2 * $Logfile: /Freespace2/code/Graphics/2d.cpp $
7 * Main file for 2d primitives.
10 * Revision 1.1 2002/05/03 03:28:09 root
14 * 25 8/20/99 2:09p Dave
17 * 24 8/16/99 9:45a Jefff
18 * changes to cursor management to allow a 2nd temporary cursor
20 * 23 7/27/99 3:52p Dave
21 * Make star drawing a bit more robust to help lame D3D cards.
23 * 22 7/18/99 12:32p Dave
24 * Randomly oriented shockwaves.
26 * 21 7/15/99 3:07p Dave
27 * 32 bit detection support. Mouse coord commandline.
29 * 20 7/14/99 9:42a Dave
30 * Put in clear_color debug function. Put in base for 3dnow stuff / P3
33 * 19 7/13/99 1:15p Dave
34 * 32 bit support. Whee!
36 * 18 7/12/99 11:42a Jefff
37 * Made rectangle drawing smarter in D3D. Made plines draw properly on Ati
40 * 17 7/09/99 9:51a Dave
41 * Added thick polyline code.
43 * 16 7/02/99 3:05p Anoop
44 * Oops. Fixed g3_draw_2d_poly() so that it properly handles poly bitmap
45 * and LFB bitmap calls.
47 * 15 6/29/99 10:35a Dave
48 * Interface polygon bitmaps! Whee!
50 * 14 4/09/99 2:21p Dave
51 * Multiplayer beta stuff. CD checking.
53 * 13 2/03/99 11:44a Dave
54 * Fixed d3d transparent textures.
56 * 12 1/29/99 12:47a Dave
57 * Put in sounds for beam weapon. A bunch of interface screens (tech
60 * 11 1/15/99 11:29a Neilk
61 * Fixed D3D screen/texture pixel formatting problem.
63 * 10 1/08/99 2:08p Dave
64 * Fixed software rendering for pofview. Super early support for AWACS and
67 * 9 1/06/99 2:24p Dave
68 * Stubs and release build fixes.
70 * 8 12/18/98 1:49a Dave
71 * Fixed Fred initialization problem resulting from hi-res mode changes.
73 * 7 12/18/98 1:13a Dave
74 * Rough 1024x768 support for Direct3D. Proper detection and usage through
77 * 6 12/01/98 10:32a Johnson
78 * Fixed direct3d font problems. Fixed sun bitmap problem. Fixed direct3d
81 * 5 11/30/98 5:31p Dave
82 * Fixed up Fred support for software mode.
84 * 4 11/30/98 1:07p Dave
85 * 16 bit conversion, first run.
87 * 3 11/11/98 5:37p Dave
88 * Checkin for multiplayer testing.
90 * 2 10/07/98 10:52a Dave
93 * 1 10/07/98 10:48a Dave
95 * 122 6/13/98 3:18p Hoffoss
96 * NOX()ed out a bunch of strings that shouldn't be translated.
98 * 121 5/23/98 11:26a Hoffoss
99 * Fixed bug where optimized code used EDX and my code trashed it.
101 * 120 5/22/98 11:09p John
102 * put in code to hopefull not crash cyrix cpus
104 * 119 5/20/98 9:45p John
105 * added code so the places in code that change half the palette don't
106 * have to clear the screen.
108 * 118 5/20/98 12:59p Hoffoss
109 * Changed temporary crossfade code to just pop the image again.
111 * 117 5/16/98 1:18p John
112 * Made softtware DirectDraw reset palette after Alt+TAB.
114 * 116 5/14/98 5:42p John
115 * Revamped the whole window position/mouse code for the graphics windows.
117 * 115 5/08/98 10:49a John
118 * Made 'gr d' go into direct3d mode.
120 * 114 5/06/98 11:21p John
121 * Fixed a bitmap bug with Direct3D. Started adding new caching code into
124 * 113 4/21/98 9:28a John
125 * Added stub for cross-fade.
127 * 112 4/10/98 5:20p John
128 * Changed RGB in lighting structure to be ubytes. Removed old
129 * not-necessary 24 bpp software stuff.
131 * 111 4/06/98 12:55p John
132 * Upped the gamma for Fred.
134 * 110 3/25/98 8:07p John
135 * Restructured software rendering into two modules; One for windowed
136 * debug mode and one for DirectX fullscreen.
138 * 109 3/24/98 3:58p John
139 * Put in (hopefully) final gamma setting code.
141 * 108 3/10/98 4:18p John
142 * Cleaned up graphics lib. Took out most unused gr functions. Made D3D
143 * & Glide have popups and print screen. Took out all >8bpp software
144 * support. Made Fred zbuffer. Made zbuffer allocate dynamically to
145 * support Fred. Made zbuffering key off of functions rather than one
148 * 107 2/25/98 2:37p John
149 * Made afterburner shake 2x less noticable. Made 'gr a' leave Glide mode
150 * properly. Made model_caching never work in hardware mode.
152 * 106 2/23/98 2:27p John
153 * Made int3,asserts, etc pass video through.
155 * 105 2/20/98 3:13p John
156 * Made popup save code print an error an exit out if 3d accelerated.
158 * 104 2/19/98 6:13p John
159 * Made Glide do texturing & zbuffering.
161 * 103 1/26/98 5:12p John
162 * Added in code for Pentium Pro specific optimizations. Speed up
163 * zbuffered correct tmapper about 35%. Speed up non-zbuffered scalers
166 * 102 1/14/98 11:39a Dave
167 * Polished up a bunch of popup support items.
169 * 101 1/10/98 1:14p John
170 * Added explanation to debug console commands
172 * 100 12/21/97 4:33p John
173 * Made debug console functions a class that registers itself
174 * automatically, so you don't need to add the function to
175 * debugfunctions.cpp.
177 * 99 12/04/97 12:09p John
178 * Made glows use scaler instead of tmapper so they don't rotate. Had to
179 * add a zbuffered scaler.
181 * 98 12/03/97 10:47a John
182 * added functions to save/restore entire screens.
184 * 97 12/02/97 3:59p John
185 * Added first rev of thruster glow, along with variable levels of
186 * translucency, which retquired some restructing of palman.
188 * 96 11/30/97 12:18p John
189 * added more 24 & 32-bpp primitives
191 * 95 11/24/97 11:20a John
194 * 94 11/14/97 3:54p John
195 * Added triple buffering.
197 * 93 11/14/97 12:30p John
198 * Fixed some DirectX bugs. Moved the 8-16 xlat tables into Graphics
199 * libs. Made 16-bpp DirectX modes know what bitmap format they're in.
201 * 92 10/09/97 5:23p John
202 * Added support for more 16-bpp functions
204 * 91 9/20/97 8:16a John
205 * Made .clr files go into the Cache directory. Replaced cfopen(name,NULL)
206 * to delete a file with cf_delete.
208 * 90 9/09/97 11:01a Sandeep
209 * fixed warning level 4 bugs
211 * 89 9/07/97 10:01p Lawrance
212 * add in support for animating mouse pointer
214 * 88 9/03/97 4:32p John
215 * changed bmpman to only accept ani and pcx's. made passing .pcx or .ani
216 * to bm_load functions not needed. Made bmpman keep track of palettes
217 * for bitmaps not mapped into game palettes.
219 * 87 8/20/97 4:19p John
220 * added delay to hopefully fix mike's problems when getting int3's in
223 * 86 7/16/97 3:07p John
225 * 85 6/18/97 12:07p John
226 * fixed some color bugs
228 * 84 6/17/97 7:04p John
229 * added d3d support for gradients.
230 * fixed some color bugs by adding screen signatures instead of watching
231 * flags and palette changes.
233 * 83 6/17/97 12:03p John
234 * Moved color/alphacolor functions into their own module. Made all color
235 * functions be part of the low-level graphics drivers, not just the
238 * 82 6/12/97 5:04p John
239 * Initial rev of Glide support
241 * 81 6/11/97 5:49p John
242 * Changed palette code to only recalculate alphacolors when needed, not
243 * when palette changes.
245 * 80 6/11/97 1:12p John
246 * Started fixing all the text colors in the game.
248 * 79 6/06/97 5:03p John
249 * fixed bug withalpha colors failing after gr_init
251 * 78 6/06/97 4:53p John
252 * made gr_init not bash current color
254 * 77 6/05/97 4:53p John
255 * First rev of new antialiased font stuff.
257 * 76 5/20/97 10:36a John
258 * Fixed problem with user bitmaps and direct3d caching.
260 * 75 5/16/97 9:11a John
261 * fixed bug that made Ctrl+Break in fullscreen hang
263 * 74 5/14/97 4:38p John
264 * Fixed print_screen bug.
266 * 73 5/14/97 2:10p John
267 * added rudimentary support for windowed direct3d.
269 * 72 5/14/97 10:53a John
270 * fixed some discrepencies between d3d and software palette setting.
272 * 71 5/13/97 4:39p John
273 * Added console function to set graphics modes.
275 * 70 5/13/97 12:39p John
276 * Got fullscreen mode working.
278 * 69 5/12/97 12:27p John
279 * Restructured Graphics Library to add support for multiple renderers.
281 * 68 5/07/97 2:59p John
282 * Initial rev of D3D texturing.
284 * 67 5/01/97 3:32p John
285 * oops... forced 2d to always be in 8bpp,
287 * 66 5/01/97 3:23p John
288 * first hooks for some direct 3d setup stuff.
290 * 65 4/28/97 5:33p John
291 * fixed a newly introduced bug with fullscreen toggle.
293 * 64 4/28/97 4:46p John
295 * 63 4/22/97 12:20p John
296 * fixed more resource leaks
298 * 62 4/22/97 10:33a John
299 * fixed the 2d resource leaks that Alan found.
301 * 61 3/31/97 9:45a Allender
302 * start of new font stuff
304 * 60 3/26/97 10:52a Lawrance
305 * mouse always on in menus, disappears in gameplay after 1 second
307 * 59 3/14/97 3:55p John
308 * Made tiled tmapper not always be zbuffered.
310 * 58 3/13/97 9:09a Allender
311 * variable to allow trashing of the palette. kind of temporary code
312 * right now...checking needed for undefined references
314 * 57 3/12/97 2:51p John
315 * Added some test code for tmapper.
317 * 56 3/12/97 9:25a John
318 * fixed a bug with zbuffering. Reenabled it by default.
320 * 55 3/11/97 5:13p John
321 * made top up bitmaps work.
323 * 54 2/26/97 11:59a Allender
324 * comment out warning about display settings not being optimal
326 * 53 1/09/97 2:16p John
327 * took out the "Bing!" message
329 * 52 1/09/97 11:35a John
330 * Added some 2d functions to get/put screen images.
332 * 51 1/07/97 2:01p John
333 * Fairly fast zbuffering for object sorting.
335 * 50 1/06/97 2:44p John
336 * Added in slow (but correct) zbuffering
338 * 49 12/11/96 12:41p John
339 * Added new code to draw 3d laser using 2d ellipses.
341 * 48 12/03/96 5:42p John
342 * took out debug code.
344 * 47 12/03/96 5:42p John
345 * made gr_bitmap clip properly.
347 * 46 12/03/96 5:06p John
348 * Added code to draw our own cursor.
350 * 45 11/26/96 6:50p John
351 * Added some more hicolor primitives. Made windowed mode run as current
352 * bpp, if bpp is 8,16,or 32.
354 * 44 11/21/96 11:23a John
355 * fixed bug with previous.
357 * 43 11/21/96 11:21a John
358 * Made gr_get_string_size handle multi line text.
359 * Took out gr_get_multiline_string_size
361 * 42 11/21/96 11:06a John
364 * 41 11/20/96 10:01a Hoffoss
365 * A few minor improvements.
367 * 40 11/19/96 2:47p Allender
368 * add support for xparent bitmaps in 32bpp
370 * 39 11/18/96 4:46p Allender
371 * changed warning message about bit depth to appear when requested
372 * doesn't equal actual
374 * 38 11/18/96 4:35p Allender
375 * new 16bpp gradient functions
377 * 37 11/18/96 3:09p John
378 * made gr_clear always clear to black.
380 * 36 11/18/96 1:48p Allender
381 * added 16 bit version of shader
383 * 35 11/18/96 12:36p John
384 * Added code to dump screen to a PCX file.
386 * 34 11/18/96 11:40a John
387 * Added faster gr_set_color method.
389 * 33 11/15/96 11:26a John
390 * Added code to clip text to clipping region.
392 * 32 11/15/96 11:26a Allender
393 * fixed up 16 bbp version of gr_bitmap
395 * 31 11/14/96 9:11a John
396 * Fixed bug that didn't offset the gr_string text by the current clip
399 * 30 11/13/96 6:47p John
400 * Added gr_flip function.
402 * 29 11/13/96 10:10a John
403 * Increases MAX_WIDTH & HEIGHT for Jasen's massive 1600x1200 display.
405 * 28 11/07/96 6:19p John
406 * Added a bunch of 16bpp primitives so the game sort of runs in 16bpp
409 * 27 10/30/96 10:36a Lawrance
410 * added gr_diamond function
412 * 26 10/26/96 1:40p John
413 * Added some now primitives to the 2d library and
414 * cleaned up some old ones.
421 #include <windowsx.h>
430 #include "grinternal.h"
431 #include "systemvars.h"
435 // #include "amd3d.h"
437 // Includes for different rendering systems
441 #include "gropengl.h"
442 #include "grdirectdraw.h"
446 color_gun Gr_red, Gr_green, Gr_blue, Gr_alpha;
447 color_gun Gr_t_red, Gr_t_green, Gr_t_blue, Gr_t_alpha;
448 color_gun Gr_ta_red, Gr_ta_green, Gr_ta_blue, Gr_ta_alpha;
449 color_gun *Gr_current_red, *Gr_current_green, *Gr_current_blue, *Gr_current_alpha;
452 ubyte Gr_original_palette[768]; // The palette
453 ubyte Gr_current_palette[768];
454 char Gr_current_palette_name[128] = NOX("none");
458 int Web_cursor_bitmap = -1;
468 uint Gr_signature = 0;
470 float Gr_gamma = 1.8f;
471 int Gr_gamma_int = 180;
472 int Gr_gamma_lookup[256];
476 if ( !Gr_inited ) return;
480 switch( gr_screen.mode ) {
486 gr_directdraw_cleanup();
499 Int3(); // Invalid graphics mode
508 DCF(gr,"Changes graphics mode")
510 #ifndef HARDWARE_ONLY
511 int mode = gr_screen.mode;
514 dc_get_arg(ARG_STRING);
516 if ( !strcmp( Dc_arg, "a")) {
519 } else if ( !strcmp( Dc_arg, "b")) {
521 mode = GR_DIRECTDRAW;
522 } else if ( !strcmp( Dc_arg, "d")) {
524 } else if ( !strcmp( Dc_arg, "g")) {
526 } else if ( !strcmp( Dc_arg, "o")) {
530 // print usage, not stats
535 if ( mode != gr_screen.mode ) {
536 dc_printf( "Setting new video mode...\n" );
537 int errcode = gr_init( gr_screen.max_w, gr_screen.max_h, mode );
539 dc_printf( "Error %d. Graphics unchanged.\n", errcode );
546 dc_printf( "Usage: gr mode\n" );
547 dc_printf( "The options can be:\n" );
548 dc_printf( "Macros: A=software win32 window (obsolete)\n" );
549 dc_printf( " B=software directdraw fullscreen (obsolete)\n" );
550 dc_printf( " D=Direct3d\n" );
551 dc_printf( " G=Glide\n" );
552 dc_printf( " O=OpenGl (obsolete)\n" );
553 Dc_status = 0; // don't print status if help is printed. Too messy.
557 switch( gr_screen.mode ) {
560 dc_printf( "Win32 software windowed\n" );
564 dc_printf( "DirectDraw software windowed\n" );
567 dc_printf( "Direct3D\n" );
570 dc_printf( "3Dfx Glide\n" );
574 dc_printf( "OpenGl\n" );
577 Int3(); // Invalid graphics mode
584 // set screen clear color
585 DCF(clear_color, "set clear color r, g, b")
597 gr_set_clear_color(r, g, b);
600 void gr_set_palette_internal( char *name, ubyte * palette, int restrict_font_to_128 )
602 if ( palette == NULL ) {
603 // Create a default palette
609 for (b=0; b<6; b++ ) {
610 Gr_current_palette[i*3+0] = (unsigned char)(r*51);
611 Gr_current_palette[i*3+1] = (unsigned char)(g*51);
612 Gr_current_palette[i*3+2] = (unsigned char)(b*51);
615 for ( i=216;i<256; i++ ) {
616 Gr_current_palette[i*3+0] = (unsigned char)((i-216)*6);
617 Gr_current_palette[i*3+1] = (unsigned char)((i-216)*6);
618 Gr_current_palette[i*3+2] = (unsigned char)((i-216)*6);
620 memmove( Gr_original_palette, Gr_current_palette, 768 );
622 memmove( Gr_original_palette, palette, 768 );
623 memmove( Gr_current_palette, palette, 768 );
626 // mprintf(("Setting new palette\n" ));
629 if (gr_screen.gf_set_palette) {
630 (*gr_screen.gf_set_palette)(Gr_current_palette, restrict_font_to_128 );
632 // Since the palette set code might shuffle the palette,
633 // reload it into the source palette
635 memmove( palette, Gr_current_palette, 768 );
638 // Update Palette Manager tables
639 memmove( gr_palette, Gr_current_palette, 768 );
640 palette_update(name, restrict_font_to_128);
645 void gr_set_palette( char *name, ubyte * palette, int restrict_font_to_128 )
649 strcpy( Gr_current_palette_name, name );
650 p = strchr( Gr_current_palette_name, '.' );
652 gr_screen.signature = Gr_signature++;
653 gr_set_palette_internal( name, palette, restrict_font_to_128 );
659 #define CPUID _asm _emit 0fh _asm _emit 0a2h
661 // -----------------------------------------------------------------------
663 void gr_detect_cpu(int *cpu, int *mmx, int *amd3d, int *katmai )
678 memset( cpu_vender, 0, sizeof(cpu_vender) );
682 // Check for prescence of
688 pushfd // get extended flags
690 mov ebx, eax // save current flags
691 xor eax, 200000h // toggle bit 21
692 push eax // push new flags on stack
693 popfd // flags updated now in flags
694 pushfd // get extended flags
695 pop eax // store extended flags in eax
696 xor eax, ebx // if bit 21 r/w then eax <> 0
699 mov eax, 0 // setup CPUID to return vender id
700 CPUID // code bytes = 0fh, 0a2h
701 mov DWORD PTR cpu_vender[0], ebx
702 mov DWORD PTR cpu_vender[4], edx
703 mov DWORD PTR cpu_vender[8], ecx
705 mov eax, 1 // setup CPUID to return features
707 CPUID // code bytes = 0fh, 0a2h
709 mov RegEAX, eax // family, etc returned in eax
710 mov RegEDX, edx // features returned in edx
711 jmp done_checking_cpuid
715 mov RegEAX, 4<<8 // family, etc returned in eax
716 mov RegEDX, 0 // features returned in edx
728 //RegEAX . Bits 11:8 is family
729 *cpu = (RegEAX >>8) & 0xF;
732 *cpu = 4; // processor does not support CPUID
736 //RegEAX . Bits 11:8 is family
737 *cpu = (RegEAX >>8) & 0xF;
741 if (RegEDX & 0x800000) // bit 23 is set for MMX technology
744 __try { _asm emms } // try executing an MMX instruction "emms"
746 __except(EXCEPTION_EXECUTE_HANDLER) { retval = FALSE; }
752 *mmx = 1; // processor supports CPUID but does not support MMX technology
756 if (RegEDX & (1<<25) ) // bit 25 is set for Katmai technology
761 // Check for Amd 3dnow
763 if ( !stricmp( cpu_vender, NOX("AuthenticAMD")) ) {
766 mov eax, 0x80000000 // setup CPUID to return extended number of functions
768 CPUID // code bytes = 0fh, 0a2h
770 mov RegEAX, eax // highest extended function value
773 if ( RegEAX > 0x80000000 ) {
776 mov eax, 0x80000001 // setup CPUID to return extended flags
778 CPUID // code bytes = 0fh, 0a2h
780 mov RegEAX, eax // family, etc returned in eax
781 mov RegEDX, edx // flags in edx
784 if (RegEDX & 0x80000000) // bit 31 is set for AMD-3D technology
786 // try executing some 3Dnow instructions
789 float x = (float)1.25;
790 float y = (float)1.25;
796 PFMUL(AMD_M1, AMD_M2);
802 int should_be_156 = int(z*100);
804 if ( should_be_156 == 156 ) {
810 __except(EXCEPTION_EXECUTE_HANDLER) { }
819 // --------------------------------------------------------------------------
821 int gr_init(int res, int mode, int depth, int fred_x, int fred_y)
826 gr_detect_cpu(&Gr_cpu, &Gr_mmx, &Gr_amd3d, &Gr_katmai );
828 mprintf(( "GR_CPU: Family %d, MMX=%s\n", Gr_cpu, (Gr_mmx?"Yes":"No") ));
835 // If already inited, shutdown the previous graphics
837 switch( gr_screen.mode ) {
843 gr_directdraw_cleanup();
856 Int3(); // Invalid graphics mode
862 #if defined(HARDWARE_ONLY)
863 if(!Fred_running && !Pofview_running && !Nebedit_running && !Is_standalone){
864 if((mode != GR_GLIDE) && (mode != GR_DIRECT3D)){
865 mprintf(("Forcing glide startup!\n"));
876 if(!Fred_running && !Pofview_running){
877 // set resolution based on the res type
897 // Make w a multiple of 8
898 max_w = ( max_w / 8 )*8;
899 if ( max_w < 8 ) max_w = 8;
900 if ( max_h < 8 ) max_h = 8;
902 memset( &gr_screen, 0, sizeof(screen) );
904 gr_screen.signature = Gr_signature++;
905 gr_screen.mode = mode;
907 gr_screen.max_w = max_w;
908 gr_screen.max_h = max_h;
909 gr_screen.aspect = 1.0f; // Normal PC screen
910 gr_screen.offset_x = 0;
911 gr_screen.offset_y = 0;
912 gr_screen.clip_left = 0;
913 gr_screen.clip_top = 0;
914 gr_screen.clip_right = gr_screen.max_w - 1;
915 gr_screen.clip_bottom = gr_screen.max_h - 1;
916 gr_screen.clip_width = gr_screen.max_w;
917 gr_screen.clip_height = gr_screen.max_h;
919 switch( gr_screen.mode ) {
921 Assert(Fred_running || Pofview_running || Is_standalone || Nebedit_running);
926 gr_directdraw_init();
929 // we only care about possible 32 bit stuff here
930 Cmdline_force_32bit = 0;
932 Cmdline_force_32bit = 1;
937 // bad startup - stupid D3D
938 extern int D3D_inited;
946 // if we're in high-res. force polygon interface
947 if(gr_screen.res == GR_1024){
957 Int3(); // Invalid graphics mode
960 memmove( Gr_current_palette, Gr_original_palette, 768 );
961 gr_set_palette_internal(Gr_current_palette_name, Gr_current_palette,0);
963 gr_set_gamma(Gr_gamma);
965 if ( Gr_cursor == -1 ){
966 Gr_cursor = bm_load( "cursor" );
969 // load the web pointer cursor bitmap
970 if (Web_cursor_bitmap < 0) {
971 int nframes; // used to pass, not really needed (should be 1)
972 Web_cursor_bitmap = bm_load_animation("cursorweb", &nframes);
973 Assert(Web_cursor_bitmap >= 0); // if bitmap didnt load, thats not good (this is protected for in release tho)
978 gr_set_clear_color(0, 0, 0);
980 // Call some initialization functions
986 void gr_force_windowed()
988 if ( !Gr_inited ) return;
990 switch( gr_screen.mode ) {
993 extern void gr_soft_force_windowed();
994 gr_soft_force_windowed();
1000 extern void gr_directdraw_force_windowed();
1001 gr_directdraw_force_windowed();
1008 extern void gr_glide_force_windowed();
1009 gr_glide_force_windowed();
1017 Int3(); // Invalid graphics mode
1020 if ( Os_debugger_running )
1029 void gr_activate(int active)
1031 if ( !Gr_inited ) return;
1033 switch( gr_screen.mode ) {
1036 extern void gr_soft_activate(int active);
1037 gr_soft_activate(active);
1044 extern void gr_dd_activate(int active);
1045 gr_dd_activate(active);
1051 extern void gr_d3d_activate(int active);
1052 gr_d3d_activate(active);
1058 extern void gr_glide_activate(int active);
1059 gr_glide_activate(active);
1067 Int3(); // Invalid graphics mode
1072 // -----------------------------------------------------------------------
1073 // gr_set_cursor_bitmap()
1075 // Set the bitmap for the mouse pointer. This is called by the animating mouse
1078 // The lock parameter just locks basically disables the next call of this function that doesnt
1079 // have an unlock feature. If adding in more cursor-changing situations, be aware of
1080 // unexpected results. You have been warned.
1082 // TODO: investigate memory leak of original Gr_cursor bitmap when this is called
1083 void gr_set_cursor_bitmap(int n, int lock)
1085 static int locked = 0;
1088 if (!locked || (lock == GR_CURSOR_UNLOCK)) {
1094 if (lock == GR_CURSOR_LOCK) {
1099 // retrieves the current bitmap
1100 // used in UI_GADGET to save/restore current cursor state
1101 int gr_get_cursor_bitmap()
1107 int Gr_bitmap_poly = 0;
1110 Gr_bitmap_poly = !Gr_bitmap_poly;
1113 dc_printf("Using poly bitmaps\n");
1115 dc_printf("Using LFB bitmaps\n");
1119 // new bitmap functions
1120 void gr_bitmap(int x, int y)
1122 int section_x, section_y;
1126 // d3d and glide support texture poly shiz
1127 if(((gr_screen.mode == GR_DIRECT3D) || (gr_screen.mode == GR_GLIDE)) && Gr_bitmap_poly){
1129 // float u_scale, v_scale;
1130 bitmap_section_info *sections;
1132 // render all sections
1133 bm_get_info(gr_screen.current_bitmap, &w, &h, NULL, NULL, NULL, §ions);
1136 for(idx=0; idx<sections->num_y; idx++){
1138 for(s_idx=0; s_idx<sections->num_x; s_idx++){
1139 // get the section as a texture in vram
1140 gr_set_bitmap(gr_screen.current_bitmap, gr_screen.current_alphablend_mode, gr_screen.current_bitblt_mode, gr_screen.current_alpha, s_idx, idx);
1142 // determine the width and height of this section
1143 bm_get_section_size(gr_screen.current_bitmap, s_idx, idx, §ion_x, §ion_y);
1146 g3_draw_2d_poly_bitmap(x + x_line, y + y_line, section_x, section_y, TMAP_FLAG_BITMAP_SECTION);
1147 x_line += section_x;
1149 y_line += section_y;
1156 // old school bitmaps
1157 switch(gr_screen.mode){
1164 gr_d3d_bitmap(x, y);
1168 gr_glide_bitmap(x, y);
1172 gr_opengl_bitmap(x, y);
1177 void gr_bitmap_ex(int x, int y, int w, int h, int sx, int sy)
1179 switch(gr_screen.mode){
1182 grx_bitmap_ex(x, y, w, h, sx, sy);
1186 gr_d3d_bitmap_ex(x, y, w, h, sx, sy);
1190 gr_glide_bitmap_ex(x, y, w, h, sx, sy);
1194 gr_opengl_bitmap_ex(x, y, w, h, sx, sy);
1198 // given endpoints, and thickness, calculate coords of the endpoint
1199 void gr_pline_helper(vector *out, vector *in1, vector *in2, int thickness)
1203 // slope of the line
1204 if(vm_vec_same(in1, in2)){
1205 slope = vmd_zero_vector;
1207 vm_vec_sub(&slope, in2, in1);
1208 float temp = -slope.x;
1211 vm_vec_normalize(&slope);
1215 vm_vec_scale_add(out, in1, &slope, (float)thickness);
1218 // special function for drawing polylines. this function is specifically intended for
1219 // polylines where each section is no more than 90 degrees away from a previous section.
1220 // Moreover, it is _really_ intended for use with 45 degree angles.
1221 void gr_pline_special(vector **pts, int num_pts, int thickness)
1223 vector s1, s2, e1, e2, dir;
1224 vector last_e1, last_e2;
1226 vertex *verts[4] = {&v[0], &v[1], &v[2], &v[3]};
1227 int saved_zbuffer_mode, idx;
1228 int started_frame = 0;
1232 // if we have less than 2 pts, bail
1237 extern int G3_count;
1243 // turn off zbuffering
1244 saved_zbuffer_mode = gr_zbuffer_get();
1245 gr_zbuffer_set(GR_ZBUFF_NONE);
1250 // draw each section
1251 last_e1 = vmd_zero_vector;
1252 last_e2 = vmd_zero_vector;
1253 for(idx=0; idx<num_pts-1; idx++){
1254 // get the start and endpoints
1255 s1 = *pts[idx]; // start 1 (on the line)
1256 gr_pline_helper(&s2, pts[idx], pts[idx+1], thickness); // start 2
1257 e1 = *pts[idx+1]; // end 1 (on the line)
1258 vm_vec_sub(&dir, pts[idx+1], pts[idx]);
1259 vm_vec_add(&e2, &s2, &dir); // end 2
1262 v[0].sx = (float)ceil(s1.x);
1263 v[0].sy = (float)ceil(s1.y);
1267 v[0].flags = PF_PROJECTED;
1269 v[0].r = gr_screen.current_color.red;
1270 v[0].g = gr_screen.current_color.green;
1271 v[0].b = gr_screen.current_color.blue;
1273 v[1].sx = (float)ceil(s2.x);
1274 v[1].sy = (float)ceil(s2.y);
1278 v[1].flags = PF_PROJECTED;
1280 v[1].r = gr_screen.current_color.red;
1281 v[1].g = gr_screen.current_color.green;
1282 v[1].b = gr_screen.current_color.blue;
1284 v[2].sx = (float)ceil(e2.x);
1285 v[2].sy = (float)ceil(e2.y);
1289 v[2].flags = PF_PROJECTED;
1291 v[2].r = gr_screen.current_color.red;
1292 v[2].g = gr_screen.current_color.green;
1293 v[2].b = gr_screen.current_color.blue;
1295 v[3].sx = (float)ceil(e1.x);
1296 v[3].sy = (float)ceil(e1.y);
1300 v[3].flags = PF_PROJECTED;
1302 v[3].r = gr_screen.current_color.red;
1303 v[3].g = gr_screen.current_color.green;
1304 v[3].b = gr_screen.current_color.blue;
1307 g3_draw_poly_constant_sw(4, verts, TMAP_FLAG_GOURAUD | TMAP_FLAG_RGB, 0.1f);
1309 // if we're past the first section, draw a "patch" triangle to fill any gaps
1312 v[0].sx = (float)ceil(s1.x);
1313 v[0].sy = (float)ceil(s1.y);
1317 v[0].flags = PF_PROJECTED;
1319 v[0].r = gr_screen.current_color.red;
1320 v[0].g = gr_screen.current_color.green;
1321 v[0].b = gr_screen.current_color.blue;
1323 v[1].sx = (float)ceil(s2.x);
1324 v[1].sy = (float)ceil(s2.y);
1328 v[1].flags = PF_PROJECTED;
1330 v[1].r = gr_screen.current_color.red;
1331 v[1].g = gr_screen.current_color.green;
1332 v[1].b = gr_screen.current_color.blue;
1335 v[2].sx = (float)ceil(last_e2.x);
1336 v[2].sy = (float)ceil(last_e2.y);
1340 v[2].flags = PF_PROJECTED;
1342 v[2].r = gr_screen.current_color.red;
1343 v[2].g = gr_screen.current_color.green;
1344 v[2].b = gr_screen.current_color.blue;
1346 g3_draw_poly_constant_sw(3, verts, TMAP_FLAG_GOURAUD | TMAP_FLAG_RGB, 0.1f);
1349 // store our endpoints
1358 // restore zbuffer mode
1359 gr_zbuffer_set(saved_zbuffer_mode);