2 * Copyright (C) Volition, Inc. 1999. All rights reserved.
4 * All source code herein is the property of Volition, Inc. You may not sell
5 * or otherwise commercially exploit the source or things you created based on
10 * $Logfile: /Freespace2/code/Graphics/2d.cpp $
15 * Main file for 2d primitives.
18 * Revision 1.12 2004/07/04 11:31:43 taylor
19 * amd64 support, compiler warning fixes, don't use software rendering
21 * Revision 1.11 2002/08/31 01:39:13 theoddone33
22 * Speed up the renderer a tad
24 * Revision 1.10 2002/06/17 06:33:09 relnev
25 * ryan's struct patch for gcc 2.95
27 * Revision 1.9 2002/06/09 04:41:17 relnev
28 * added copyright header
30 * Revision 1.8 2002/06/05 04:03:32 relnev
31 * finished cfilesystem.
33 * removed some old code.
35 * fixed mouse save off-by-one.
39 * Revision 1.7 2002/05/30 21:44:48 relnev
40 * implemented some missing texture stuff.
42 * enable bitmap polys for opengl.
44 * work around greenness in bitmaps.
46 * Revision 1.6 2002/05/28 21:36:10 relnev
47 * some more timer junk.
49 * tried to fix software mode.
51 * Revision 1.5 2002/05/28 04:18:08 theoddone33
52 * Fix some stuff and add -DFS2_DEMO
54 * Revision 1.4 2002/05/27 22:43:02 theoddone33
55 * Fix more glide symbols
57 * Revision 1.3 2002/05/27 22:39:21 theoddone33
58 * Remove glide symbols
60 * Revision 1.2 2002/05/07 03:16:45 theoddone33
61 * The Great Newline Fix
63 * Revision 1.1.1.1 2002/05/03 03:28:09 root
67 * 25 8/20/99 2:09p Dave
70 * 24 8/16/99 9:45a Jefff
71 * changes to cursor management to allow a 2nd temporary cursor
73 * 23 7/27/99 3:52p Dave
74 * Make star drawing a bit more robust to help lame D3D cards.
76 * 22 7/18/99 12:32p Dave
77 * Randomly oriented shockwaves.
79 * 21 7/15/99 3:07p Dave
80 * 32 bit detection support. Mouse coord commandline.
82 * 20 7/14/99 9:42a Dave
83 * Put in clear_color debug function. Put in base for 3dnow stuff / P3
86 * 19 7/13/99 1:15p Dave
87 * 32 bit support. Whee!
89 * 18 7/12/99 11:42a Jefff
90 * Made rectangle drawing smarter in D3D. Made plines draw properly on Ati
93 * 17 7/09/99 9:51a Dave
94 * Added thick polyline code.
96 * 16 7/02/99 3:05p Anoop
97 * Oops. Fixed g3_draw_2d_poly() so that it properly handles poly bitmap
98 * and LFB bitmap calls.
100 * 15 6/29/99 10:35a Dave
101 * Interface polygon bitmaps! Whee!
103 * 14 4/09/99 2:21p Dave
104 * Multiplayer beta stuff. CD checking.
106 * 13 2/03/99 11:44a Dave
107 * Fixed d3d transparent textures.
109 * 12 1/29/99 12:47a Dave
110 * Put in sounds for beam weapon. A bunch of interface screens (tech
113 * 11 1/15/99 11:29a Neilk
114 * Fixed D3D screen/texture pixel formatting problem.
116 * 10 1/08/99 2:08p Dave
117 * Fixed software rendering for pofview. Super early support for AWACS and
120 * 9 1/06/99 2:24p Dave
121 * Stubs and release build fixes.
123 * 8 12/18/98 1:49a Dave
124 * Fixed Fred initialization problem resulting from hi-res mode changes.
126 * 7 12/18/98 1:13a Dave
127 * Rough 1024x768 support for Direct3D. Proper detection and usage through
130 * 6 12/01/98 10:32a Johnson
131 * Fixed direct3d font problems. Fixed sun bitmap problem. Fixed direct3d
134 * 5 11/30/98 5:31p Dave
135 * Fixed up Fred support for software mode.
137 * 4 11/30/98 1:07p Dave
138 * 16 bit conversion, first run.
140 * 3 11/11/98 5:37p Dave
141 * Checkin for multiplayer testing.
143 * 2 10/07/98 10:52a Dave
146 * 1 10/07/98 10:48a Dave
148 * 122 6/13/98 3:18p Hoffoss
149 * NOX()ed out a bunch of strings that shouldn't be translated.
151 * 121 5/23/98 11:26a Hoffoss
152 * Fixed bug where optimized code used EDX and my code trashed it.
154 * 120 5/22/98 11:09p John
155 * put in code to hopefull not crash cyrix cpus
157 * 119 5/20/98 9:45p John
158 * added code so the places in code that change half the palette don't
159 * have to clear the screen.
161 * 118 5/20/98 12:59p Hoffoss
162 * Changed temporary crossfade code to just pop the image again.
164 * 117 5/16/98 1:18p John
165 * Made softtware DirectDraw reset palette after Alt+TAB.
167 * 116 5/14/98 5:42p John
168 * Revamped the whole window position/mouse code for the graphics windows.
170 * 115 5/08/98 10:49a John
171 * Made 'gr d' go into direct3d mode.
173 * 114 5/06/98 11:21p John
174 * Fixed a bitmap bug with Direct3D. Started adding new caching code into
177 * 113 4/21/98 9:28a John
178 * Added stub for cross-fade.
180 * 112 4/10/98 5:20p John
181 * Changed RGB in lighting structure to be ubytes. Removed old
182 * not-necessary 24 bpp software stuff.
184 * 111 4/06/98 12:55p John
185 * Upped the gamma for Fred.
187 * 110 3/25/98 8:07p John
188 * Restructured software rendering into two modules; One for windowed
189 * debug mode and one for DirectX fullscreen.
191 * 109 3/24/98 3:58p John
192 * Put in (hopefully) final gamma setting code.
194 * 108 3/10/98 4:18p John
195 * Cleaned up graphics lib. Took out most unused gr functions. Made D3D
196 * & Glide have popups and print screen. Took out all >8bpp software
197 * support. Made Fred zbuffer. Made zbuffer allocate dynamically to
198 * support Fred. Made zbuffering key off of functions rather than one
201 * 107 2/25/98 2:37p John
202 * Made afterburner shake 2x less noticable. Made 'gr a' leave Glide mode
203 * properly. Made model_caching never work in hardware mode.
205 * 106 2/23/98 2:27p John
206 * Made int3,asserts, etc pass video through.
208 * 105 2/20/98 3:13p John
209 * Made popup save code print an error an exit out if 3d accelerated.
211 * 104 2/19/98 6:13p John
212 * Made Glide do texturing & zbuffering.
214 * 103 1/26/98 5:12p John
215 * Added in code for Pentium Pro specific optimizations. Speed up
216 * zbuffered correct tmapper about 35%. Speed up non-zbuffered scalers
219 * 102 1/14/98 11:39a Dave
220 * Polished up a bunch of popup support items.
222 * 101 1/10/98 1:14p John
223 * Added explanation to debug console commands
225 * 100 12/21/97 4:33p John
226 * Made debug console functions a class that registers itself
227 * automatically, so you don't need to add the function to
228 * debugfunctions.cpp.
230 * 99 12/04/97 12:09p John
231 * Made glows use scaler instead of tmapper so they don't rotate. Had to
232 * add a zbuffered scaler.
234 * 98 12/03/97 10:47a John
235 * added functions to save/restore entire screens.
237 * 97 12/02/97 3:59p John
238 * Added first rev of thruster glow, along with variable levels of
239 * translucency, which retquired some restructing of palman.
241 * 96 11/30/97 12:18p John
242 * added more 24 & 32-bpp primitives
244 * 95 11/24/97 11:20a John
247 * 94 11/14/97 3:54p John
248 * Added triple buffering.
250 * 93 11/14/97 12:30p John
251 * Fixed some DirectX bugs. Moved the 8-16 xlat tables into Graphics
252 * libs. Made 16-bpp DirectX modes know what bitmap format they're in.
254 * 92 10/09/97 5:23p John
255 * Added support for more 16-bpp functions
257 * 91 9/20/97 8:16a John
258 * Made .clr files go into the Cache directory. Replaced cfopen(name,NULL)
259 * to delete a file with cf_delete.
261 * 90 9/09/97 11:01a Sandeep
262 * fixed warning level 4 bugs
264 * 89 9/07/97 10:01p Lawrance
265 * add in support for animating mouse pointer
267 * 88 9/03/97 4:32p John
268 * changed bmpman to only accept ani and pcx's. made passing .pcx or .ani
269 * to bm_load functions not needed. Made bmpman keep track of palettes
270 * for bitmaps not mapped into game palettes.
272 * 87 8/20/97 4:19p John
273 * added delay to hopefully fix mike's problems when getting int3's in
276 * 86 7/16/97 3:07p John
278 * 85 6/18/97 12:07p John
279 * fixed some color bugs
281 * 84 6/17/97 7:04p John
282 * added d3d support for gradients.
283 * fixed some color bugs by adding screen signatures instead of watching
284 * flags and palette changes.
286 * 83 6/17/97 12:03p John
287 * Moved color/alphacolor functions into their own module. Made all color
288 * functions be part of the low-level graphics drivers, not just the
291 * 82 6/12/97 5:04p John
292 * Initial rev of Glide support
294 * 81 6/11/97 5:49p John
295 * Changed palette code to only recalculate alphacolors when needed, not
296 * when palette changes.
298 * 80 6/11/97 1:12p John
299 * Started fixing all the text colors in the game.
301 * 79 6/06/97 5:03p John
302 * fixed bug withalpha colors failing after gr_init
304 * 78 6/06/97 4:53p John
305 * made gr_init not bash current color
307 * 77 6/05/97 4:53p John
308 * First rev of new antialiased font stuff.
310 * 76 5/20/97 10:36a John
311 * Fixed problem with user bitmaps and direct3d caching.
313 * 75 5/16/97 9:11a John
314 * fixed bug that made Ctrl+Break in fullscreen hang
316 * 74 5/14/97 4:38p John
317 * Fixed print_screen bug.
319 * 73 5/14/97 2:10p John
320 * added rudimentary support for windowed direct3d.
322 * 72 5/14/97 10:53a John
323 * fixed some discrepencies between d3d and software palette setting.
325 * 71 5/13/97 4:39p John
326 * Added console function to set graphics modes.
328 * 70 5/13/97 12:39p John
329 * Got fullscreen mode working.
331 * 69 5/12/97 12:27p John
332 * Restructured Graphics Library to add support for multiple renderers.
334 * 68 5/07/97 2:59p John
335 * Initial rev of D3D texturing.
337 * 67 5/01/97 3:32p John
338 * oops... forced 2d to always be in 8bpp,
340 * 66 5/01/97 3:23p John
341 * first hooks for some direct 3d setup stuff.
343 * 65 4/28/97 5:33p John
344 * fixed a newly introduced bug with fullscreen toggle.
346 * 64 4/28/97 4:46p John
348 * 63 4/22/97 12:20p John
349 * fixed more resource leaks
351 * 62 4/22/97 10:33a John
352 * fixed the 2d resource leaks that Alan found.
354 * 61 3/31/97 9:45a Allender
355 * start of new font stuff
357 * 60 3/26/97 10:52a Lawrance
358 * mouse always on in menus, disappears in gameplay after 1 second
360 * 59 3/14/97 3:55p John
361 * Made tiled tmapper not always be zbuffered.
363 * 58 3/13/97 9:09a Allender
364 * variable to allow trashing of the palette. kind of temporary code
365 * right now...checking needed for undefined references
367 * 57 3/12/97 2:51p John
368 * Added some test code for tmapper.
370 * 56 3/12/97 9:25a John
371 * fixed a bug with zbuffering. Reenabled it by default.
373 * 55 3/11/97 5:13p John
374 * made top up bitmaps work.
376 * 54 2/26/97 11:59a Allender
377 * comment out warning about display settings not being optimal
379 * 53 1/09/97 2:16p John
380 * took out the "Bing!" message
382 * 52 1/09/97 11:35a John
383 * Added some 2d functions to get/put screen images.
385 * 51 1/07/97 2:01p John
386 * Fairly fast zbuffering for object sorting.
388 * 50 1/06/97 2:44p John
389 * Added in slow (but correct) zbuffering
391 * 49 12/11/96 12:41p John
392 * Added new code to draw 3d laser using 2d ellipses.
394 * 48 12/03/96 5:42p John
395 * took out debug code.
397 * 47 12/03/96 5:42p John
398 * made gr_bitmap clip properly.
400 * 46 12/03/96 5:06p John
401 * Added code to draw our own cursor.
403 * 45 11/26/96 6:50p John
404 * Added some more hicolor primitives. Made windowed mode run as current
405 * bpp, if bpp is 8,16,or 32.
407 * 44 11/21/96 11:23a John
408 * fixed bug with previous.
410 * 43 11/21/96 11:21a John
411 * Made gr_get_string_size handle multi line text.
412 * Took out gr_get_multiline_string_size
414 * 42 11/21/96 11:06a John
417 * 41 11/20/96 10:01a Hoffoss
418 * A few minor improvements.
420 * 40 11/19/96 2:47p Allender
421 * add support for xparent bitmaps in 32bpp
423 * 39 11/18/96 4:46p Allender
424 * changed warning message about bit depth to appear when requested
425 * doesn't equal actual
427 * 38 11/18/96 4:35p Allender
428 * new 16bpp gradient functions
430 * 37 11/18/96 3:09p John
431 * made gr_clear always clear to black.
433 * 36 11/18/96 1:48p Allender
434 * added 16 bit version of shader
436 * 35 11/18/96 12:36p John
437 * Added code to dump screen to a PCX file.
439 * 34 11/18/96 11:40a John
440 * Added faster gr_set_color method.
442 * 33 11/15/96 11:26a John
443 * Added code to clip text to clipping region.
445 * 32 11/15/96 11:26a Allender
446 * fixed up 16 bbp version of gr_bitmap
448 * 31 11/14/96 9:11a John
449 * Fixed bug that didn't offset the gr_string text by the current clip
452 * 30 11/13/96 6:47p John
453 * Added gr_flip function.
455 * 29 11/13/96 10:10a John
456 * Increases MAX_WIDTH & HEIGHT for Jasen's massive 1600x1200 display.
458 * 28 11/07/96 6:19p John
459 * Added a bunch of 16bpp primitives so the game sort of runs in 16bpp
462 * 27 10/30/96 10:36a Lawrance
463 * added gr_diamond function
465 * 26 10/26/96 1:40p John
466 * Added some now primitives to the 2d library and
467 * cleaned up some old ones.
478 #include "grinternal.h"
479 #include "systemvars.h"
481 #include "osregistry.h"
483 #include "cfilesystem.h"
486 // Includes for different rendering systems
487 #include "gropengl.h"
494 color_gun Gr_red, Gr_green, Gr_blue, Gr_alpha;
495 color_gun Gr_t_red, Gr_t_green, Gr_t_blue, Gr_t_alpha;
496 color_gun Gr_ta_red, Gr_ta_green, Gr_ta_blue, Gr_ta_alpha;
497 color_gun *Gr_current_red, *Gr_current_green, *Gr_current_blue, *Gr_current_alpha;
500 ubyte Gr_original_palette[768]; // The palette
501 ubyte Gr_current_palette[768];
502 char Gr_current_palette_name[128] = NOX("none");
504 int Gr_zbuffering = 0;
505 int Gr_zbuffering_mode = 0;
506 int Gr_global_zbuffering = 0;
510 int Web_cursor_bitmap = -1;
514 uint Gr_signature = 0;
516 float Gr_gamma = 1.8f;
517 int Gr_gamma_int = 180;
518 int Gr_gamma_lookup[256];
520 int Gr_textures_in = 0;
525 if ( !Gr_inited ) return;
529 switch (gr_screen.mode) {
542 Int3(); // Invalid graphics mode
553 // set screen clear color
554 DCF(clear_color, "set clear color r, g, b")
566 gr_set_clear_color(r, g, b);
569 void gr_set_palette_internal( const char *name, ubyte * palette, int restrict_font_to_128 )
571 if ( palette == NULL ) {
572 // Create a default palette
578 for (b=0; b<6; b++ ) {
579 Gr_current_palette[i*3+0] = (unsigned char)(r*51);
580 Gr_current_palette[i*3+1] = (unsigned char)(g*51);
581 Gr_current_palette[i*3+2] = (unsigned char)(b*51);
584 for ( i=216;i<256; i++ ) {
585 Gr_current_palette[i*3+0] = (unsigned char)((i-216)*6);
586 Gr_current_palette[i*3+1] = (unsigned char)((i-216)*6);
587 Gr_current_palette[i*3+2] = (unsigned char)((i-216)*6);
589 memmove( Gr_original_palette, Gr_current_palette, 768 );
591 memmove( Gr_original_palette, palette, 768 );
592 memmove( Gr_current_palette, palette, 768 );
595 // mprintf(("Setting new palette\n" ));
598 // Update Palette Manager tables
599 memmove( gr_palette, Gr_current_palette, 768 );
600 palette_update(name, restrict_font_to_128);
605 void gr_set_palette( const char *name, ubyte * palette, int restrict_font_to_128 )
609 SDL_strlcpy( Gr_current_palette_name, name, SDL_arraysize(Gr_current_palette_name) );
610 p = SDL_strchr( Gr_current_palette_name, '.' );
612 gr_screen.signature = Gr_signature++;
613 gr_set_palette_internal( name, palette, restrict_font_to_128 );
616 void gr_set_gamma(float gamma)
624 CAP(gamma, 0.1f, 5.0f);
627 Gr_gamma_int = fl2i(gamma * 100.0f);
629 // create the gamma lookup table
630 float gamma_1f = 1.0f / gamma;
632 for (i = 0; i < 256; i++) {
633 int v = fl2i(pow(i2fl(i)/255.0f, gamma_1f)*255.0f);
635 Gr_gamma_lookup[i] = v;
638 // save new value to cfg file
639 char tmp_gamma_string[10];
640 SDL_snprintf( tmp_gamma_string, SDL_arraysize(tmp_gamma_string), "%.2f", gamma);
641 os_config_write_string("Video", "Gamma", tmp_gamma_string);
643 // call renderer specific functionality, if needed
644 if (gr_screen.gf_set_gamma) {
645 (*gr_screen.gf_set_gamma)(gamma);
649 static int gr_get_best_res(int *max_w, int *max_h)
651 if (Fred_running || Pofview_running || Nebedit_running || Fonttool_running) {
670 // quickly bail if we are forcing low-res mode
671 if ( os_config_read_uint("Video", "LowRes", 0) ) {
676 // check to see if we have hi-res art
677 if ( cf_has_packfile("sparky_hi_fs2") ) {
678 // check desktop res to make sure we should use it
679 if ( !SDL_InitSubSystem(SDL_INIT_VIDEO) ) {
680 SDL_DisplayMode desk_mode;
682 if ( !SDL_GetDesktopDisplayMode(0, &desk_mode) ) {
683 if ( (desk_mode.w >= 1024) && (desk_mode.h >= 768) ) {
690 SDL_QuitSubSystem(SDL_INIT_VIDEO);
701 // --------------------------------------------------------------------------
705 const char *ptr = NULL;
706 int mode = GR_OPENGL;
714 // If already inited, shutdown the previous graphics
716 switch (gr_screen.mode) {
728 Int3(); // Invalid graphics mode
735 if (Fred_running || Pofview_running) {
737 } else if (Is_standalone) {
740 ptr = os_config_read_string("Video", "Renderer", "OpenGL");
742 if ( !SDL_strcasecmp("OpenGL", ptr) ) {
752 // get best available resolution
753 res = gr_get_best_res(&max_w, &max_h);
755 mprintf(("Using %s-res graphics\n", (res == GR_1024) ? "high" : "low" ));
758 memset( &gr_screen, 0, sizeof(screen) );
760 gr_screen.signature = Gr_signature++;
761 gr_screen.mode = mode;
763 gr_screen.max_w = max_w;
764 gr_screen.max_h = max_h;
765 gr_screen.use_sections = 1;
766 gr_screen.aspect = 1.0f; // Normal PC screen
767 gr_screen.offset_x = 0;
768 gr_screen.offset_y = 0;
769 gr_screen.clip_left = 0;
770 gr_screen.clip_top = 0;
771 gr_screen.clip_right = gr_screen.max_w - 1;
772 gr_screen.clip_bottom = gr_screen.max_h - 1;
773 gr_screen.clip_width = gr_screen.max_w;
774 gr_screen.clip_height = gr_screen.max_h;
775 gr_screen.viewport_offset_x = 0;
776 gr_screen.viewport_offset_y = 0;
777 gr_screen.viewport_scale_factor_x = 1.0f;
778 gr_screen.viewport_scale_factor_y = 1.0f;
782 switch( gr_screen.mode ) {
788 SDL_assert( Pofview_running || Fred_running );
793 SDL_assert(Is_standalone);
797 Int3(); // Invalid graphics mode
801 memmove( Gr_current_palette, Gr_original_palette, 768 );
802 gr_set_palette_internal(Gr_current_palette_name, Gr_current_palette,0);
805 extern float Freespace_gamma;
807 ptr = os_config_read_string("Video", "Gamma", "1.8");
809 Freespace_gamma = (float)SDL_atof(ptr);
810 CAP(Freespace_gamma, 0.1f, 5.0f);
812 gr_set_gamma(Freespace_gamma);
815 if ( Gr_cursor == -1 ){
816 Gr_cursor = bm_load( "cursor" );
820 // load the web pointer cursor bitmap
821 if (Web_cursor_bitmap < 0) {
822 int nframes; // used to pass, not really needed (should be 1)
823 Web_cursor_bitmap = bm_load_animation("cursorweb", &nframes);
824 SDL_assert(Web_cursor_bitmap >= 0); // if bitmap didnt load, thats not good (this is protected for in release tho)
830 gr_set_clear_color(0, 0, 0);
832 // Call some initialization functions
838 void gr_force_windowed()
845 int rc = SDL_SetWindowFullscreen(os_get_window(), 0);
848 gr_screen.fullscreen = 0;
849 mouse_grab(0); // will be grabbed if needed
852 if (Os_debugger_running) {
857 void gr_force_fullscreen()
863 int rc = SDL_SetWindowFullscreen(os_get_window(), SDL_WINDOW_FULLSCREEN_DESKTOP);
866 gr_screen.fullscreen = 1;
867 mouse_grab(0); // will be grabbed if needed
870 if (Os_debugger_running) {
875 void gr_toggle_fullscreen()
881 // skip if a tool is running (except fonttool)
882 if (Fred_running || Pofview_running || Nebedit_running) {
886 Uint32 flags = SDL_GetWindowFlags( os_get_window() );
888 if (flags & SDL_WINDOW_FULLSCREEN_DESKTOP) {
891 gr_force_fullscreen();
894 if (Os_debugger_running) {
899 void gr_activate(int active)
905 if (gr_screen.gf_activate) {
906 (*gr_screen.gf_activate)(active);
910 // -----------------------------------------------------------------------
911 // gr_set_cursor_bitmap()
913 // Set the bitmap for the mouse pointer. This is called by the animating mouse
916 // The lock parameter just locks basically disables the next call of this function that doesnt
917 // have an unlock feature. If adding in more cursor-changing situations, be aware of
918 // unexpected results. You have been warned.
920 // TODO: investigate memory leak of original Gr_cursor bitmap when this is called
921 void gr_set_cursor_bitmap(int n, int lock)
923 static int locked = 0;
926 if (!locked || (lock == GR_CURSOR_UNLOCK)) {
932 if (lock == GR_CURSOR_LOCK) {
937 // retrieves the current bitmap
938 // used in UI_GADGET to save/restore current cursor state
939 int gr_get_cursor_bitmap()
944 // new bitmap functions
945 void gr_bitmap(int x, int y)
947 int section_x, section_y;
951 // float u_scale, v_scale;
952 bitmap_section_info *sections;
954 // render all sections
955 bm_get_info(gr_screen.current_bitmap, &w, &h, NULL, NULL, NULL, §ions);
959 if (gr_screen.use_sections) {
960 for(idx=0; idx<sections->num_y; idx++){
962 for(s_idx=0; s_idx<sections->num_x; s_idx++){
963 // get the section as a texture in vram
964 gr_set_bitmap(gr_screen.current_bitmap, gr_screen.current_alphablend_mode, gr_screen.current_bitblt_mode, gr_screen.current_alpha, s_idx, idx);
966 // determine the width and height of this section
967 bm_get_section_size(gr_screen.current_bitmap, s_idx, idx, §ion_x, §ion_y);
970 g3_draw_2d_poly_bitmap(x + x_line, y + y_line, section_x, section_y, TMAP_FLAG_BITMAP_SECTION);
976 gr_set_bitmap(gr_screen.current_bitmap, gr_screen.current_alphablend_mode,
977 gr_screen.current_bitblt_mode, gr_screen.current_alpha);
978 g3_draw_2d_poly_bitmap(x, y, w, h, TMAP_FLAG_BITMAP_INTERFACE);
983 // given endpoints, and thickness, calculate coords of the endpoint
984 void gr_pline_helper(vector *out, vector *in1, vector *in2, int thickness)
989 if(vm_vec_same(in1, in2)){
990 slope = vmd_zero_vector;
992 vm_vec_sub(&slope, in2, in1);
993 float temp = -slope.xyz.x;
994 slope.xyz.x = slope.xyz.y;
996 vm_vec_normalize(&slope);
1000 vm_vec_scale_add(out, in1, &slope, (float)thickness);
1003 // special function for drawing polylines. this function is specifically intended for
1004 // polylines where each section is no more than 90 degrees away from a previous section.
1005 // Moreover, it is _really_ intended for use with 45 degree angles.
1006 void gr_pline_special(vector **pts, int num_pts, int thickness)
1008 vector s1, s2, e1, e2, dir;
1009 vector last_e1, last_e2;
1011 vertex *verts[4] = {&v[0], &v[1], &v[2], &v[3]};
1012 int saved_zbuffer_mode, idx;
1013 int started_frame = 0;
1017 // if we have less than 2 pts, bail
1022 extern int G3_count;
1028 // turn off zbuffering
1029 saved_zbuffer_mode = gr_zbuffer_get();
1030 gr_zbuffer_set(GR_ZBUFF_NONE);
1035 // draw each section
1036 last_e1 = vmd_zero_vector;
1037 last_e2 = vmd_zero_vector;
1038 for(idx=0; idx<num_pts-1; idx++){
1039 // get the start and endpoints
1040 s1 = *pts[idx]; // start 1 (on the line)
1041 gr_pline_helper(&s2, pts[idx], pts[idx+1], thickness); // start 2
1042 e1 = *pts[idx+1]; // end 1 (on the line)
1043 vm_vec_sub(&dir, pts[idx+1], pts[idx]);
1044 vm_vec_add(&e2, &s2, &dir); // end 2
1047 v[0].sx = (float)ceil(s1.xyz.x);
1048 v[0].sy = (float)ceil(s1.xyz.y);
1052 v[0].flags = PF_PROJECTED;
1054 v[0].r = gr_screen.current_color.red;
1055 v[0].g = gr_screen.current_color.green;
1056 v[0].b = gr_screen.current_color.blue;
1058 v[1].sx = (float)ceil(s2.xyz.x);
1059 v[1].sy = (float)ceil(s2.xyz.y);
1063 v[1].flags = PF_PROJECTED;
1065 v[1].r = gr_screen.current_color.red;
1066 v[1].g = gr_screen.current_color.green;
1067 v[1].b = gr_screen.current_color.blue;
1069 v[2].sx = (float)ceil(e2.xyz.x);
1070 v[2].sy = (float)ceil(e2.xyz.y);
1074 v[2].flags = PF_PROJECTED;
1076 v[2].r = gr_screen.current_color.red;
1077 v[2].g = gr_screen.current_color.green;
1078 v[2].b = gr_screen.current_color.blue;
1080 v[3].sx = (float)ceil(e1.xyz.x);
1081 v[3].sy = (float)ceil(e1.xyz.y);
1085 v[3].flags = PF_PROJECTED;
1087 v[3].r = gr_screen.current_color.red;
1088 v[3].g = gr_screen.current_color.green;
1089 v[3].b = gr_screen.current_color.blue;
1092 g3_draw_poly_constant_sw(4, verts, TMAP_FLAG_GOURAUD | TMAP_FLAG_RGB, 0.1f);
1094 // if we're past the first section, draw a "patch" triangle to fill any gaps
1097 v[0].sx = (float)ceil(s1.xyz.x);
1098 v[0].sy = (float)ceil(s1.xyz.y);
1102 v[0].flags = PF_PROJECTED;
1104 v[0].r = gr_screen.current_color.red;
1105 v[0].g = gr_screen.current_color.green;
1106 v[0].b = gr_screen.current_color.blue;
1108 v[1].sx = (float)ceil(s2.xyz.x);
1109 v[1].sy = (float)ceil(s2.xyz.y);
1113 v[1].flags = PF_PROJECTED;
1115 v[1].r = gr_screen.current_color.red;
1116 v[1].g = gr_screen.current_color.green;
1117 v[1].b = gr_screen.current_color.blue;
1120 v[2].sx = (float)ceil(last_e2.xyz.x);
1121 v[2].sy = (float)ceil(last_e2.xyz.y);
1125 v[2].flags = PF_PROJECTED;
1127 v[2].r = gr_screen.current_color.red;
1128 v[2].g = gr_screen.current_color.green;
1129 v[2].b = gr_screen.current_color.blue;
1131 g3_draw_poly_constant_sw(3, verts, TMAP_FLAG_GOURAUD | TMAP_FLAG_RGB, 0.1f);
1134 // store our endpoints
1143 // restore zbuffer mode
1144 gr_zbuffer_set(saved_zbuffer_mode);
1150 void gr_set_color_fast(color *dst)
1152 if (dst->screen_sig != gr_screen.signature) {
1153 if (dst->is_alphacolor) {
1154 gr_init_alphacolor(dst, dst->red, dst->green, dst->blue, dst->alpha, dst->ac_type);
1156 gr_init_color(dst, dst->red, dst->green, dst->blue);
1160 gr_screen.current_color = *dst;
1163 void gr_get_color(int *r, int *g, int *b)
1165 if (r) *r = gr_screen.current_color.red;
1166 if (g) *g = gr_screen.current_color.green;
1167 if (b) *b = gr_screen.current_color.blue;
1170 void gr_get_colorf(float *r, float *g, float *b, float *a)
1172 if (r) *r = gr_screen.current_color.red / 255.0f;
1173 if (g) *g = gr_screen.current_color.green / 255.0f;
1174 if (b) *b = gr_screen.current_color.blue / 255.0f;
1175 if (a) *a = gr_screen.current_color.alpha / 255.0f;
1178 void gr_init_color(color *c, int r, int g, int b)
1180 c->screen_sig = gr_screen.signature;
1181 c->red = (unsigned char)r;
1182 c->green = (unsigned char)g;
1183 c->blue = (unsigned char)b;
1185 c->ac_type = AC_TYPE_NONE;
1187 c->is_alphacolor = 0;
1191 void gr_init_alphacolor(color *clr, int r, int g, int b, int alpha, int type)
1198 gr_init_color(clr, r, g, b);
1200 clr->alpha = (unsigned char)alpha;
1201 clr->ac_type = (ubyte)type;
1202 clr->alphacolor = -1;
1203 clr->is_alphacolor = 1;
1206 void gr_set_color(int r, int g, int b)
1208 SDL_assert((r >= 0) && (r < 256));
1209 SDL_assert((g >= 0) && (g < 256));
1210 SDL_assert((b >= 0) && (b < 256));
1212 gr_init_color(&gr_screen.current_color, r, g, b);
1215 void gr_set_clear_color(int r, int g, int b)
1217 gr_init_color(&gr_screen.current_clear_color, r, g, b);
1220 void gr_set_bitmap(int bitmap_num, int alphablend_mode, int bitblt_mode, float alpha, int sx, int sy)
1222 gr_screen.current_alpha = alpha;
1223 gr_screen.current_alphablend_mode = alphablend_mode;
1224 gr_screen.current_bitblt_mode = bitblt_mode;
1225 gr_screen.current_bitmap = bitmap_num;
1227 gr_screen.current_bitmap_sx = sx;
1228 gr_screen.current_bitmap_sy = sy;
1231 void gr_create_shader(shader *shade, float r, float g, float b, float c)
1233 shade->screen_sig = gr_screen.signature;
1240 void gr_set_shader(shader *shade)
1243 if (shade->screen_sig != gr_screen.signature) {
1244 gr_create_shader(shade, shade->r, shade->g, shade->b, shade->c);
1247 gr_screen.current_shader = *shade;
1249 gr_create_shader(&gr_screen.current_shader, 0.0f, 0.0f, 0.0f, 0.0f);
1253 int gr_zbuffer_get()
1255 if ( !Gr_global_zbuffering ) {
1256 return GR_ZBUFF_NONE;
1259 return Gr_zbuffering_mode;
1262 int gr_zbuffer_set(int mode)
1264 int tmp = Gr_zbuffering_mode;
1266 Gr_zbuffering_mode = mode;
1268 if (Gr_zbuffering_mode == GR_ZBUFF_NONE) {