2 * $Logfile: /Freespace2/code/Graphics/GrGlide.cpp $
7 * Code that uses 3DFX's Glide graphics library
10 * Revision 1.1 2002/05/03 03:28:09 root
14 * 39 9/14/99 5:14a Dave
15 * Fixed credits drawing in Glide.
17 * 38 9/08/99 11:38p Dave
18 * Make V2 minimize/maximize the old way.
20 * 37 9/04/99 8:00p Dave
21 * Fixed up 1024 and 32 bit movie support.
23 * 36 9/01/99 10:49p Dave
24 * Added nice SquadWar checkbox to the client join wait screen.
26 * 35 8/30/99 5:01p Dave
27 * Made d3d do less state changing in the nebula. Use new chat server for
30 * 34 8/06/99 12:29a Dave
33 * 33 8/04/99 5:36p Dave
34 * Make glide and D3D switch out properly.
36 * 32 7/19/99 3:29p Dave
37 * Fixed gamma bitmap in the options screen.
39 * 31 7/14/99 9:42a Dave
40 * Put in clear_color debug function. Put in base for 3dnow stuff / P3
43 * 30 7/13/99 1:15p Dave
44 * 32 bit support. Whee!
46 * 29 6/29/99 10:35a Dave
47 * Interface polygon bitmaps! Whee!
49 * 28 5/05/99 9:02p Dave
50 * Fixed D3D aabitmap rendering. Spiffed up nebula effect a bit (added
51 * rotations, tweaked values, made bitmap selection more random). Fixed
52 * D3D beam weapon clipping problem. Added D3d frame dumping.
54 * 27 2/21/99 1:48p Dave
55 * Some code for monitoring datarate for multiplayer in detail.
57 * 26 2/11/99 3:08p Dave
58 * PXO refresh button. Very preliminary squad war support.
60 * 25 2/05/99 12:52p Dave
61 * Fixed Glide nondarkening textures.
63 * 24 2/04/99 6:29p Dave
64 * First full working rev of FS2 PXO support. Fixed Glide lighting
67 * 23 2/03/99 11:44a Dave
68 * Fixed d3d transparent textures.
70 * 22 1/30/99 1:29a Dave
71 * Fixed nebula thumbnail problem. Full support for 1024x768 choose pilot
72 * screen. Fixed beam weapon death messages.
74 * 21 1/24/99 11:37p Dave
75 * First full rev of beam weapons. Very customizable. Removed some bogus
76 * Int3()'s in low level net code.
78 * 20 1/23/99 5:33p Dave
79 * Put in support for 1024x768 Glide.
81 * 19 1/15/99 11:29a Neilk
82 * Fixed D3D screen/texture pixel formatting problem.
84 * 18 12/18/98 1:13a Dave
85 * Rough 1024x768 support for Direct3D. Proper detection and usage through
88 * 17 12/14/98 12:13p Dave
89 * Spiffed up xfer system a bit. Put in support for squad logo file xfer.
92 * 16 12/09/98 7:34p Dave
93 * Cleanup up nebula effect. Tweaked many values.
95 * 15 12/06/98 2:36p Dave
96 * Drastically improved nebula fogging.
98 * 14 12/04/98 10:20a Dave
99 * Fixed up gr_glide_get_pixel(...)
101 * 13 12/02/98 9:58a Dave
102 * Got fonttool working under Glide/Direct3d.
104 * 12 12/01/98 5:54p Dave
105 * Simplified the way pixel data is swizzled. Fixed tga bitmaps to work
106 * properly in D3D and Glide.
108 * 11 12/01/98 10:32a Johnson
109 * Fixed direct3d font problems. Fixed sun bitmap problem. Fixed direct3d
112 * 10 12/01/98 8:06a Dave
113 * Temporary checkin to fix some texture transparency problems in d3d.
115 * 9 11/30/98 1:07p Dave
116 * 16 bit conversion, first run.
118 * 8 11/24/98 4:43p Dave
119 * Make sure glide starts up in 640x480
121 * 7 11/20/98 11:16a Dave
122 * Fixed up IPX support a bit. Making sure that switching modes and
123 * loading/saving pilot files maintains proper state.
125 * 6 11/14/98 5:32p Dave
126 * Lots of nebula work. Put in ship contrails.
128 * 5 11/12/98 12:19a Dave
129 * Removed compiler warning.
131 * 4 11/11/98 5:37p Dave
132 * Checkin for multiplayer testing.
134 * 3 11/09/98 2:11p Dave
135 * Nebula optimizations.
137 * 2 10/07/98 10:52a Dave
140 * 1 10/07/98 10:49a Dave
142 * 116 9/14/98 1:59p Allender
143 * allow for interlaced movies
145 * 115 5/25/98 10:32a John
146 * Took out redundant code for font bitmap offsets that converted to a
147 * float, then later on converted back to an integer. Quite unnecessary.
149 * 114 5/22/98 9:09a John
150 * fixed type in previous
152 * 113 5/22/98 9:07a John
153 * added in code that fixed Rush Glide startup problemmo.
155 * 112 5/20/98 9:46p John
156 * added code so the places in code that change half the palette don't
157 * have to clear the screen.
159 * 111 5/17/98 5:03p John
160 * Fixed some bugs that make the taskbar interfere with the DEBUG-only
163 * 110 5/17/98 3:23p John
164 * Took out capibility check for additive blending. Made gr_bitmap_ex
165 * clip properly in glide and direct3d.
167 * 109 5/15/98 9:34p John
168 * Removed the initial ugly little cursor part that drew right at program
171 * 108 5/15/98 8:48a John
172 * Fixed bug where one-pixel line was getting left on right and bottom.
174 * 107 5/14/98 5:42p John
175 * Revamped the whole window position/mouse code for the graphics windows.
177 * 106 5/08/98 5:38p John
178 * Made Glide wait for retrace.
180 * 105 5/08/98 5:37p John
182 * 104 5/07/98 6:58p Hoffoss
183 * Made changes to mouse code to fix a number of problems.
185 * 103 5/07/98 8:43a John
186 * Turned off 3dfx gamma correction.
188 * 102 5/07/98 8:36a John
189 * Fixed Glide gradients
191 * 101 5/06/98 8:41p John
192 * Fixed some font clipping bugs. Moved texture handle set code for d3d
193 * into the texture module.
195 * 100 5/06/98 5:30p John
196 * Removed unused cfilearchiver. Removed/replaced some unused/little used
197 * graphics functions, namely gradient_h and _v and pixel_sp. Put in new
198 * DirectX header files and libs that fixed the Direct3D alpha blending
203 //#define USE_8BPP_TEXTURES
206 #include <windowsx.h>
208 #include "glideutl.h"
213 #include "floating.h"
215 #include "grinternal.h"
221 #include "systemvars.h"
222 #include "grglideinternal.h"
225 // #include "movie.h"
228 #define NEBULA_COLORS 20
230 GrFog_t Glide_linear_fogtable[GR_FOG_TABLE_SIZE];
232 int Glide_textures_in = 0;
234 int Glide_voodoo3 = 0;
236 static int Inited = 0;
238 // voodoo3 is a little sensitive to getting deactivated
239 #define VOODOO3_DEACTIVATED -1
240 #define VOODOO3_INACTIVE() ( (Glide_voodoo3 == 1) && (Glide_deactivate == VOODOO3_DEACTIVATED) )
242 float Gr_gamma_lookup_float[256];
244 volatile int Glide_running = 0;
245 volatile int Glide_activate = 0;
246 volatile int Glide_deactivate = 0;
248 typedef enum gr_texture_source {
250 TEXTURE_SOURCE_DECAL,
253 typedef enum gr_color_source {
255 COLOR_SOURCE_TEXTURE,
256 COLOR_SOURCE_VERTEX_TIMES_TEXTURE,
259 typedef enum gr_alpha_source {
261 ALPHA_SOURCE_VERTEX_NONDARKENING,
262 ALPHA_SOURCE_TEXTURE,
263 ALPHA_SOURCE_VERTEX_TIMES_TEXTURE,
266 typedef enum gr_alpha_blend {
267 ALPHA_BLEND_NONE, // 1*SrcPixel + 0*DestPixel
268 ALPHA_BLEND_ADDITIVE, // 1*SrcPixel + 1*DestPixel
269 ALPHA_BLEND_ALPHA_ADDITIVE, // Alpha*SrcPixel + 1*DestPixel
270 ALPHA_BLEND_ALPHA_BLEND_ALPHA, // Alpha*SrcPixel + (1-Alpha)*DestPixel
271 ALPHA_BLEND_ALPHA_BLEND_SRC_COLOR, // Alpha*SrcPixel + (1-SrcPixel)*DestPixel
274 typedef enum gr_zbuffer_type {
281 int Glide_last_state = -1;
283 void gr_glide_set_state( gr_texture_source ts, gr_color_source cs, gr_alpha_source as, gr_alpha_blend ab, gr_zbuffer_type zt )
285 int current_state = 0;
287 if(VOODOO3_INACTIVE()){
291 current_state = current_state | (ts<<0);
292 current_state = current_state | (cs<<5);
293 current_state = current_state | (as<<10);
294 current_state = current_state | (ab<<15);
295 current_state = current_state | (zt<<20);
297 if ( current_state == Glide_last_state ) {
300 Glide_last_state = current_state;
303 case TEXTURE_SOURCE_NONE:
304 grTexCombineFunction( GR_TMU0, GR_TEXTURECOMBINE_ONE );
306 case TEXTURE_SOURCE_DECAL:
307 grTexCombineFunction( GR_TMU0, GR_TEXTURECOMBINE_DECAL );
314 case COLOR_SOURCE_VERTEX:
315 grColorCombine( GR_COMBINE_FUNCTION_LOCAL, GR_COMBINE_FACTOR_NONE, GR_COMBINE_LOCAL_ITERATED, GR_COMBINE_OTHER_NONE, FXFALSE );
318 case COLOR_SOURCE_TEXTURE:
319 grColorCombine( GR_COMBINE_FUNCTION_SCALE_OTHER, GR_COMBINE_FACTOR_ONE, GR_COMBINE_LOCAL_NONE, GR_COMBINE_OTHER_TEXTURE, FXFALSE);
322 case COLOR_SOURCE_VERTEX_TIMES_TEXTURE:
323 grColorCombine( GR_COMBINE_FUNCTION_SCALE_OTHER, GR_COMBINE_FACTOR_LOCAL, GR_COMBINE_LOCAL_ITERATED, GR_COMBINE_OTHER_TEXTURE, FXFALSE);
331 case ALPHA_SOURCE_VERTEX:
332 grAlphaCombine( GR_COMBINE_FUNCTION_LOCAL, GR_COMBINE_FACTOR_NONE, GR_COMBINE_LOCAL_ITERATED, GR_COMBINE_OTHER_NONE, FXFALSE );
333 grAlphaControlsITRGBLighting(FXFALSE);
336 case ALPHA_SOURCE_VERTEX_NONDARKENING:
337 grAlphaCombine( GR_COMBINE_FUNCTION_LOCAL, GR_COMBINE_FACTOR_NONE, GR_COMBINE_LOCAL_ITERATED, GR_COMBINE_OTHER_NONE, FXFALSE );
338 grAlphaControlsITRGBLighting(FXTRUE);
339 grConstantColorValue(0xFFFFFFFF); // Non-darkening colors will use this
342 case ALPHA_SOURCE_TEXTURE:
343 grAlphaCombine( GR_COMBINE_FUNCTION_SCALE_OTHER, GR_COMBINE_FACTOR_ONE, GR_COMBINE_LOCAL_NONE, GR_COMBINE_OTHER_TEXTURE, FXFALSE);
344 grAlphaControlsITRGBLighting(FXFALSE);
347 case ALPHA_SOURCE_VERTEX_TIMES_TEXTURE:
348 grAlphaCombine( GR_COMBINE_FUNCTION_SCALE_OTHER, GR_COMBINE_FACTOR_LOCAL, GR_COMBINE_LOCAL_ITERATED, GR_COMBINE_OTHER_TEXTURE, FXFALSE );
349 grAlphaControlsITRGBLighting(FXFALSE);
358 case ALPHA_BLEND_NONE: // 1*SrcPixel + 0*DestPixel
359 grAlphaBlendFunction( GR_BLEND_ONE, GR_BLEND_ZERO, GR_BLEND_ZERO, GR_BLEND_ZERO );
362 case ALPHA_BLEND_ADDITIVE: // 1*SrcPixel + 1*DestPixel
363 grAlphaBlendFunction( GR_BLEND_ONE, GR_BLEND_ONE, GR_BLEND_ZERO, GR_BLEND_ZERO );
366 case ALPHA_BLEND_ALPHA_ADDITIVE: // Alpha*SrcPixel + 1*DestPixel
367 grAlphaBlendFunction( GR_BLEND_SRC_ALPHA, GR_BLEND_ONE, GR_BLEND_ZERO, GR_BLEND_ZERO);
370 case ALPHA_BLEND_ALPHA_BLEND_ALPHA: // Alpha*SrcPixel + (1-Alpha)*DestPixel
371 grAlphaBlendFunction( GR_BLEND_SRC_ALPHA, GR_BLEND_ONE_MINUS_SRC_ALPHA, GR_BLEND_ZERO, GR_BLEND_ZERO );
374 case ALPHA_BLEND_ALPHA_BLEND_SRC_COLOR: // Alpha*SrcPixel + (1-SrcPixel)*DestPixel
375 grAlphaBlendFunction( GR_BLEND_SRC_ALPHA, GR_BLEND_ONE_MINUS_SRC_COLOR, GR_BLEND_ZERO, GR_BLEND_ZERO );
384 case ZBUFFER_TYPE_NONE:
385 grDepthBufferMode(GR_DEPTHBUFFER_DISABLE);
386 grDepthMask( FXFALSE );
389 case ZBUFFER_TYPE_READ:
390 grDepthBufferMode(GR_DEPTHBUFFER_WBUFFER);
391 grDepthBufferFunction(GR_CMP_LEQUAL);
392 grDepthMask( FXFALSE );
395 case ZBUFFER_TYPE_WRITE:
396 grDepthBufferMode(GR_DEPTHBUFFER_WBUFFER);
397 grDepthBufferFunction(GR_CMP_ALWAYS);
398 grDepthMask( FXTRUE );
401 case ZBUFFER_TYPE_FULL:
402 grDepthBufferMode(GR_DEPTHBUFFER_WBUFFER);
403 grDepthBufferFunction(GR_CMP_LEQUAL);
404 grDepthMask( FXTRUE );
415 TEXTURE_SOURCE_NONE, TEXTURE_SOURCE_DECAL,
417 COLOR_SOURCE_VERTEX, COLOR_SOURCE_TEXTURE, COLOR_SOURCE_VERTEX_TIMES_TEXTURE,
419 ALPHA_SOURCE_VERTEX, ALPHA_SOURCE_TEXTURE, ALPHA_SOURCE_VERTEX_TIMES_TEXTURE,
421 ALPHA_BLEND_NONE, ALPHA_BLEND_ADDITIVE, ALPHA_BLEND_ALPHA_ADDITIVE, ALPHA_BLEND_ALPHA_BLEND_ALPHA, ALPHA_BLEND_ALPHA_BLEND_SRC_COLOR,
423 ZBUFFER_TYPE_NONE, ZBUFFER_TYPE_READ, ZBUFFER_TYPE_WRITE, ZBUFFER_TYPE_FULL,
430 // If mode is FALSE, turn zbuffer off the entire frame,
431 // no matter what people pass to gr_zbuffer_set.
432 void gr_glide_zbuffer_clear(int mode)
434 if(VOODOO3_INACTIVE()){
440 gr_zbuffering_mode = GR_ZBUFF_FULL;
441 gr_global_zbuffering = 1;
443 // Make sure zbuffering is on
444 gr_glide_set_state( TEXTURE_SOURCE_NONE, COLOR_SOURCE_VERTEX, ALPHA_SOURCE_VERTEX, ALPHA_BLEND_NONE, ZBUFFER_TYPE_FULL );
446 // Disable writes to color and alpha buffers
447 grColorMask( FXFALSE, FXFALSE );
449 grBufferClear( 0x0, 0, GR_WDEPTHVALUE_FARTHEST );
450 // Re-enable writes to the color buffer
451 grColorMask( FXTRUE, FXFALSE );
454 gr_zbuffering_mode = GR_ZBUFF_NONE;
455 gr_global_zbuffering = 0;
459 int gr_glide_zbuffer_get()
461 if ( !gr_global_zbuffering ) {
462 return GR_ZBUFF_NONE;
464 return gr_zbuffering_mode;
467 int gr_glide_zbuffer_set(int mode)
469 if ( !gr_global_zbuffering ) {
471 return GR_ZBUFF_NONE;
474 int tmp = gr_zbuffering_mode;
476 gr_zbuffering_mode = mode;
478 if ( gr_zbuffering_mode == GR_ZBUFF_NONE ) {
487 void gr_glide_pixel(int x, int y)
489 if(VOODOO3_INACTIVE()){
495 if ( x < gr_screen.clip_left ) return;
496 if ( x > gr_screen.clip_right ) return;
497 if ( y < gr_screen.clip_top ) return;
498 if ( y > gr_screen.clip_bottom ) return;
500 // Set up Render State - flat shading - alpha blending
501 gr_glide_set_state( TEXTURE_SOURCE_NONE, COLOR_SOURCE_VERTEX, ALPHA_SOURCE_VERTEX, ALPHA_BLEND_ALPHA_BLEND_ALPHA, ZBUFFER_TYPE_NONE );
504 p.x = 0.5f + i2fl(x + gr_screen.offset_x);
505 p.y = 0.5f + i2fl(y + gr_screen.offset_y);
507 p.r = i2fl(gr_screen.current_color.red);
508 p.g = i2fl(gr_screen.current_color.green);
509 p.b = i2fl(gr_screen.current_color.blue);
517 int xi = fl2i(x*16.0f);
518 return i2fl(xi)/16.0f;
521 void gr_glide_clear()
523 GrColor_t clear_color;
525 if(VOODOO3_INACTIVE()){
529 // Turn off zbuffering so this doesn't clear the zbuffer
530 gr_glide_set_state( TEXTURE_SOURCE_NONE, COLOR_SOURCE_VERTEX, ALPHA_SOURCE_VERTEX, ALPHA_BLEND_NONE, ZBUFFER_TYPE_NONE );
534 clear_color |= ((ubyte)gr_screen.current_clear_color.red);
535 clear_color |= ((ubyte)gr_screen.current_clear_color.green << 8);
536 clear_color |= ((ubyte)gr_screen.current_clear_color.blue << 16);
537 grBufferClear( clear_color, 0, GR_WDEPTHVALUE_FARTHEST );
540 static RECT Glide_cursor_clip_rect;
542 void gr_glide_clip_cursor(int active)
545 ClipCursor(&Glide_cursor_clip_rect);
552 int Gr_glide_mouse_saved = 0;
553 int Gr_glide_mouse_saved_x1 = 0;
554 int Gr_glide_mouse_saved_y1 = 0;
555 int Gr_glide_mouse_saved_x2 = 0;
556 int Gr_glide_mouse_saved_y2 = 0;
557 int Gr_glide_mouse_saved_w = 0;
558 int Gr_glide_mouse_saved_h = 0;
559 #define MAX_SAVE_SIZE (32*32)
560 ushort Gr_glide_mouse_saved_data[MAX_SAVE_SIZE];
562 // Clamps X between R1 and R2
563 #define CLAMP(x,r1,r2) do { if ( (x) < (r1) ) (x) = (r1); else if ((x) > (r2)) (x) = (r2); } while(0)
565 void gr_glide_save_mouse_area(int x, int y, int w, int h )
567 if(VOODOO3_INACTIVE()){
571 Gr_glide_mouse_saved_x1 = x;
572 Gr_glide_mouse_saved_y1 = y;
573 Gr_glide_mouse_saved_x2 = x+w-1;
574 Gr_glide_mouse_saved_y2 = y+h-1;
576 CLAMP(Gr_glide_mouse_saved_x1, gr_screen.clip_left, gr_screen.clip_right );
577 CLAMP(Gr_glide_mouse_saved_x2, gr_screen.clip_left, gr_screen.clip_right );
578 CLAMP(Gr_glide_mouse_saved_y1, gr_screen.clip_top, gr_screen.clip_bottom );
579 CLAMP(Gr_glide_mouse_saved_y2, gr_screen.clip_top, gr_screen.clip_bottom );
581 Gr_glide_mouse_saved_w = Gr_glide_mouse_saved_x2 - Gr_glide_mouse_saved_x1 + 1;
582 Gr_glide_mouse_saved_h = Gr_glide_mouse_saved_y2 - Gr_glide_mouse_saved_y1 + 1;
584 if ( Gr_glide_mouse_saved_w < 1 ) return;
585 if ( Gr_glide_mouse_saved_h < 1 ) return;
587 // Make sure we're not saving too much!
588 Assert( (Gr_glide_mouse_saved_w*Gr_glide_mouse_saved_h) <= MAX_SAVE_SIZE );
592 info.size=sizeof(GrLfbInfo_t);
594 // get a read pointer
595 if ( grLfbLock( GR_LFB_READ_ONLY, GR_BUFFER_BACKBUFFER, GR_LFBWRITEMODE_565,
596 GR_ORIGIN_UPPER_LEFT, FXFALSE, &info)) {
599 int short_per_row=info.strideInBytes/2;
601 rptr = (ushort *)info.lfbPtr;
605 dptr = Gr_glide_mouse_saved_data;
607 for (int i=0; i<Gr_glide_mouse_saved_h; i++ ) {
608 sptr = &rptr[(Gr_glide_mouse_saved_y1+i)*short_per_row+Gr_glide_mouse_saved_x1];
610 for(int j=0; j<Gr_glide_mouse_saved_w; j++ ) {
617 grLfbUnlock( GR_LFB_READ_ONLY, GR_BUFFER_BACKBUFFER );
619 Gr_glide_mouse_saved = 1;
622 mprintf(( "Couldn't get read-only lock to backbuffer for glide mouse save\n" ));
627 // lock the backbuffer and return a pointer
632 if(VOODOO3_INACTIVE()){
636 info.size=sizeof(GrLfbInfo_t);
637 if(grLfbLock(GR_LFB_READ_ONLY, GR_BUFFER_BACKBUFFER, GR_LFBWRITEMODE_1555, GR_ORIGIN_UPPER_LEFT, FXFALSE, &info)){
638 return (uint)info.lfbPtr;
645 // unlock the backbuffer
646 void gr_glide_unlock()
648 if(VOODOO3_INACTIVE()){
653 grLfbUnlock( GR_LFB_READ_ONLY, GR_BUFFER_BACKBUFFER );
656 static int gr_palette_faded_out = 0;
662 if(VOODOO3_INACTIVE()){
668 cnt = Glide_activate;
670 Glide_activate -= cnt;
672 gr_glide_clip_cursor(1);
673 grSstControl(GR_CONTROL_ACTIVATE);
676 cnt = Glide_deactivate;
678 Glide_deactivate -= cnt;
680 gr_glide_clip_cursor(0);
681 grSstControl(GR_CONTROL_DEACTIVATE);
687 if ( gr_palette_faded_out ) {
693 Gr_glide_mouse_saved = 0; // assume not saved
696 if ( mouse_is_visible() ) {
698 mouse_get_pos( &mx, &my );
699 gr_glide_save_mouse_area(mx,my,32,32);
700 if ( Gr_cursor == -1 ) {
701 gr_set_color(255,255,255);
702 gr_line( mx, my, mx+7, my + 7 );
703 gr_line( mx, my, mx+5, my );
704 gr_line( mx, my, mx, my+5 );
706 gr_set_bitmap(Gr_cursor);
712 if(Interface_framerate){
713 if(Interface_last_tick > 0){
714 int diff = timer_get_milliseconds() - Interface_last_tick;
715 gr_printf(10, 10, "%f", 1000.0f / (float)diff);
717 Interface_last_tick = timer_get_milliseconds();
728 glide_tcache_frame();
731 void gr_glide_flip_window(uint _hdc, int x, int y, int w, int h )
735 void gr_glide_set_clip(int x,int y,int w,int h)
737 gr_screen.offset_x = x;
738 gr_screen.offset_y = y;
740 gr_screen.clip_left = 0;
741 gr_screen.clip_right = w-1;
743 gr_screen.clip_top = 0;
744 gr_screen.clip_bottom = h-1;
746 if(VOODOO3_INACTIVE()){
750 // check for sanity of parameters
751 if ( gr_screen.clip_left+x < 0 ) {
752 gr_screen.clip_left = -x;
753 } else if ( gr_screen.clip_left+x > gr_screen.max_w-1 ) {
754 gr_screen.clip_left = gr_screen.max_w-1-x;
756 if ( gr_screen.clip_right+x < 0 ) {
757 gr_screen.clip_right = -x;
758 } else if ( gr_screen.clip_right+x >= gr_screen.max_w-1 ) {
759 gr_screen.clip_right = gr_screen.max_w-1-x;
762 if ( gr_screen.clip_top+y < 0 ) {
763 gr_screen.clip_top = -y;
764 } else if ( gr_screen.clip_top+y > gr_screen.max_h-1 ) {
765 gr_screen.clip_top = gr_screen.max_h-1-y;
768 if ( gr_screen.clip_bottom+y < 0 ) {
769 gr_screen.clip_bottom = -y;
770 } else if ( gr_screen.clip_bottom+y > gr_screen.max_h-1 ) {
771 gr_screen.clip_bottom = gr_screen.max_h-1-y;
774 gr_screen.clip_width = gr_screen.clip_right - gr_screen.clip_left + 1;
775 gr_screen.clip_height = gr_screen.clip_bottom - gr_screen.clip_top + 1;
777 grClipWindow( gr_screen.clip_left+x, gr_screen.clip_top+y, gr_screen.clip_right+1+x, gr_screen.clip_bottom+1+y );
780 void gr_glide_reset_clip()
782 if(VOODOO3_INACTIVE()){
786 gr_screen.offset_x = 0;
787 gr_screen.offset_y = 0;
788 gr_screen.clip_left = 0;
789 gr_screen.clip_top = 0;
790 gr_screen.clip_right = gr_screen.max_w - 1;
791 gr_screen.clip_bottom = gr_screen.max_h - 1;
792 gr_screen.clip_width = gr_screen.max_w;
793 gr_screen.clip_height = gr_screen.max_h;
795 grClipWindow( gr_screen.clip_left, gr_screen.clip_top, gr_screen.clip_right+1, gr_screen.clip_bottom+1 );
799 void gr_glide_set_bitmap( int bitmap_num, int alphablend_mode, int bitblt_mode, float alpha, int sx, int sy )
801 if(VOODOO3_INACTIVE()){
805 gr_screen.current_alpha = alpha;
806 gr_screen.current_alphablend_mode = alphablend_mode;
807 gr_screen.current_bitblt_mode = bitblt_mode;
808 gr_screen.current_bitmap = bitmap_num;
810 gr_screen.current_bitmap_sx = sx;
811 gr_screen.current_bitmap_sy = sy;
814 void gr_glide_create_shader(shader * shade, float r, float g, float b, float c )
816 shade->screen_sig = gr_screen.signature;
824 void gr_glide_set_shader( shader * shade )
827 if (shade->screen_sig != gr_screen.signature) {
828 gr_create_shader( shade, shade->r, shade->g, shade->b, shade->c );
830 gr_screen.current_shader = *shade;
832 gr_create_shader( &gr_screen.current_shader, 0.0f, 0.0f, 0.0f, 0.0f );
836 void gr_glide_bitmap_ex_internal(int x,int y,int w,int h,int sx,int sy)
842 if(VOODOO3_INACTIVE()){
846 bmp = bm_lock( gr_screen.current_bitmap, 16, 0 );
847 sptr = (ushort *)( bmp->data + (sy*bmp->w*2) + (sx*2) );
849 if ( x < gr_screen.clip_left ) return;
850 if ( x > gr_screen.clip_right ) return;
851 if ( y < gr_screen.clip_top ) return;
852 if ( y > gr_screen.clip_bottom ) return;
854 gr_glide_set_state( TEXTURE_SOURCE_NONE, COLOR_SOURCE_VERTEX, ALPHA_SOURCE_VERTEX, ALPHA_BLEND_ALPHA_BLEND_ALPHA, ZBUFFER_TYPE_NONE );
858 if ( grLfbLock( GR_LFB_WRITE_ONLY, GR_BUFFER_BACKBUFFER, GR_LFBWRITEMODE_1555, GR_ORIGIN_UPPER_LEFT, FXFALSE, &info) ) {
860 ushort *vram = (ushort *)info.lfbPtr;
861 int stride = info.strideInBytes / sizeof(ushort);
863 for (i=0; i<h; i++ ) {
865 ushort *dptr = &vram[stride*(gr_screen.offset_y+i+y)+(gr_screen.offset_x+x)];
867 for ( j=0; j<w; j++ ) {
868 if(sptr[j] & 0x8000){
877 grLfbUnlock(GR_LFB_WRITE_ONLY, GR_BUFFER_BACKBUFFER);
880 bm_unlock(gr_screen.current_bitmap);
884 void gr_glide_bitmap_ex(int x,int y,int w,int h,int sx,int sy)
891 int dx1=x, dx2=x+w-1;
892 int dy1=y, dy2=y+h-1;
895 bm_get_info( gr_screen.current_bitmap, &bw, &bh, NULL );
900 if ( count > 1 ) Int3();
904 if ((dx1 > gr_screen.clip_right ) || (dx2 < gr_screen.clip_left)) return;
905 if ((dy1 > gr_screen.clip_bottom ) || (dy2 < gr_screen.clip_top)) return;
906 if ( dx1 < gr_screen.clip_left ) { sx += gr_screen.clip_left-dx1; dx1 = gr_screen.clip_left; }
907 if ( dy1 < gr_screen.clip_top ) { sy += gr_screen.clip_top-dy1; dy1 = gr_screen.clip_top; }
908 if ( dx2 > gr_screen.clip_right ) { dx2 = gr_screen.clip_right; }
909 if ( dy2 > gr_screen.clip_bottom ) { dy2 = gr_screen.clip_bottom; }
936 if ( w < 1 ) return; // clipped away!
937 if ( h < 1 ) return; // clipped away!
941 // Make sure clipping algorithm works
945 Assert( w == (dx2-dx1+1) );
946 Assert( h == (dy2-dy1+1) );
949 Assert( sx+w <= bw );
950 Assert( sy+h <= bh );
951 Assert( dx2 >= dx1 );
952 Assert( dy2 >= dy1 );
953 Assert( (dx1 >= gr_screen.clip_left ) && (dx1 <= gr_screen.clip_right) );
954 Assert( (dx2 >= gr_screen.clip_left ) && (dx2 <= gr_screen.clip_right) );
955 Assert( (dy1 >= gr_screen.clip_top ) && (dy1 <= gr_screen.clip_bottom) );
956 Assert( (dy2 >= gr_screen.clip_top ) && (dy2 <= gr_screen.clip_bottom) );
959 // We now have dx1,dy1 and dx2,dy2 and sx, sy all set validly within clip regions.
960 // Draw bitmap bm[sx,sy] into (dx1,dy1)-(dx2,dy2)
962 gr_glide_bitmap_ex_internal(dx1,dy1,dx2-dx1+1,dy2-dy1+1,sx,sy);
966 void gr_glide_bitmap(int x, int y)
970 bm_get_info( gr_screen.current_bitmap, &w, &h, NULL );
971 int dx1=x, dx2=x+w-1;
972 int dy1=y, dy2=y+h-1;
975 if ((dx1 > gr_screen.clip_right ) || (dx2 < gr_screen.clip_left)) return;
976 if ((dy1 > gr_screen.clip_bottom ) || (dy2 < gr_screen.clip_top)) return;
977 if ( dx1 < gr_screen.clip_left ) { sx = gr_screen.clip_left-dx1; dx1 = gr_screen.clip_left; }
978 if ( dy1 < gr_screen.clip_top ) { sy = gr_screen.clip_top-dy1; dy1 = gr_screen.clip_top; }
979 if ( dx2 > gr_screen.clip_right ) { dx2 = gr_screen.clip_right; }
980 if ( dy2 > gr_screen.clip_bottom ) { dy2 = gr_screen.clip_bottom; }
982 if ( sx < 0 ) return;
983 if ( sy < 0 ) return;
984 if ( sx >= w ) return;
985 if ( sy >= h ) return;
987 // Draw bitmap bm[sx,sy] into (dx1,dy1)-(dx2,dy2)
989 gr_glide_bitmap_ex_internal(dx1,dy1,dx2-dx1+1,dy2-dy1+1,sx,sy);
993 static void glide_scanline( int x1, int x2, int y )
997 if(VOODOO3_INACTIVE()){
1007 if ( y < gr_screen.clip_top ) return;
1008 if ( y > gr_screen.clip_bottom ) return;
1010 if ( x1 < gr_screen.clip_left ) x1 = gr_screen.clip_left;
1011 if ( x2 > gr_screen.clip_right ) x2 = gr_screen.clip_right;
1015 if ( w < 1 ) return;
1017 // for (i=0; i<w; i++)
1018 // gr_pixel(x1+i,y);
1021 // Set up Render State - flat shading - alpha blending
1022 gr_glide_set_state( TEXTURE_SOURCE_NONE, COLOR_SOURCE_VERTEX, ALPHA_SOURCE_VERTEX, ALPHA_BLEND_ALPHA_BLEND_ALPHA, ZBUFFER_TYPE_NONE );
1026 a.x = i2fl(x1 + gr_screen.offset_x);
1027 a.y = i2fl(y + gr_screen.offset_y);
1028 a.r = i2fl(gr_screen.current_color.red);
1029 a.g = i2fl(gr_screen.current_color.green);
1030 a.b = i2fl(gr_screen.current_color.blue);
1031 a.a = i2fl(gr_screen.current_color.alpha);
1033 b.x = i2fl(x2 + gr_screen.offset_x);
1034 b.y = i2fl(y + gr_screen.offset_y);
1035 b.r = i2fl(gr_screen.current_color.red);
1036 b.g = i2fl(gr_screen.current_color.green);
1037 b.b = i2fl(gr_screen.current_color.blue);
1038 b.a = i2fl(gr_screen.current_color.alpha);
1060 void gr_glide_rect(int x,int y,int w,int h)
1094 for (int i=0; i<h; i++ )
1095 glide_scanline( x1, x2, y1+i );
1099 static void glide_shade_scanline( int x1, int x2, int y, int r, int g, int b, int a )
1103 if(VOODOO3_INACTIVE()){
1113 if ( y < gr_screen.clip_top ) return;
1114 if ( y > gr_screen.clip_bottom ) return;
1116 if ( x1 < gr_screen.clip_left ) x1 = gr_screen.clip_left;
1117 if ( x2 > gr_screen.clip_right ) x2 = gr_screen.clip_right;
1121 if ( w < 1 ) return;
1124 // Set up Render State - flat shading - alpha blending
1125 gr_glide_set_state( TEXTURE_SOURCE_NONE, COLOR_SOURCE_VERTEX, ALPHA_SOURCE_VERTEX, ALPHA_BLEND_ALPHA_BLEND_ALPHA, ZBUFFER_TYPE_NONE );
1129 v1.x = i2fl(x1 + gr_screen.offset_x);
1130 v1.y = i2fl(y + gr_screen.offset_y);
1136 v2.x = i2fl(x2 + gr_screen.offset_x);
1137 v2.y = i2fl(y + gr_screen.offset_y);
1159 grDrawLine(&v1, &v2);
1163 float shade1 = 1.0f;
1164 float shade2 = 6.0f;
1166 DCF(shade1,"Set shade1")
1169 dc_get_arg(ARG_FLOAT|ARG_NONE);
1170 if ( Dc_arg_type & ARG_FLOAT ) {
1171 shade1 = Dc_arg_float;
1176 DCF(shade2,"Set shade2")
1179 dc_get_arg(ARG_FLOAT|ARG_NONE);
1180 if ( Dc_arg_type & ARG_FLOAT ) {
1181 shade2 = Dc_arg_float;
1187 void gr_glide_shade(int x,int y,int w,int h)
1222 r = fl2i(gr_screen.current_shader.r*255.0f*shade1);
1223 if ( r < 0 ) r = 0; else if ( r > 255 ) r = 255;
1224 g = fl2i(gr_screen.current_shader.g*255.0f*shade1);
1225 if ( g < 0 ) g = 0; else if ( g > 255 ) g = 255;
1226 b = fl2i(gr_screen.current_shader.b*255.0f*shade1);
1227 if ( b < 0 ) b = 0; else if ( b > 255 ) b = 255;
1228 a = fl2i(gr_screen.current_shader.c*255.0f*shade2);
1229 if ( a < 0 ) a = 0; else if ( a > 255 ) a = 255;
1231 for (int i=0; i<h; i++ ) {
1232 glide_shade_scanline( x1, x2, y1+i, r, g, b, a );
1237 void gr_glide_aabitmap_ex_new(int x,int y,int w,int h,int sx,int sy);
1239 void gr_glide_char(int x,int y,int letter)
1243 ch = &Current_font->char_data[letter];
1245 int sx = Current_font->bm_u[letter];
1246 int sy = Current_font->bm_v[letter];
1248 gr_glide_aabitmap_ex_new( x, y, ch->byte_width, Current_font->h, sx, sy );
1250 // mprintf(( "String = %s\n", text ));
1254 void gr_glide_string( int sx, int sy, char *s )
1256 int width, spacing, letter;
1259 if ( !Current_font ) {
1263 gr_set_bitmap(Current_font->bitmap_id);
1268 if (sx==0x8000) { //centered
1269 x = get_centered_x(s);
1280 while (*s== '\n' ) {
1282 y += Current_font->h;
1283 if (sx==0x8000) { //centered
1284 x = get_centered_x(s);
1289 if (*s == 0 ) break;
1291 letter = get_char_width(s[0],s[1],&width,&spacing);
1294 if (letter<0) { //not in font, draw as space
1298 gr_glide_char( x, y, letter );
1302 void gr_glide_circle( int xc, int yc, int d )
1313 if ( (xc+r) < gr_screen.clip_left ) return;
1314 if ( (xc-r) > gr_screen.clip_right ) return;
1315 if ( (yc+r) < gr_screen.clip_top ) return;
1316 if ( (yc-r) > gr_screen.clip_bottom ) return;
1319 // Draw the first octant
1320 glide_scanline( xc-y, xc+y, yc-x );
1321 glide_scanline( xc-y, xc+y, yc+x );
1326 // Draw the second octant
1327 glide_scanline( xc-x, xc+x, yc-y );
1328 glide_scanline( xc-x, xc+x, yc+y );
1335 glide_scanline( xc-x, xc+x, yc-y );
1336 glide_scanline( xc-x, xc+x, yc+y );
1341 void gr_glide_line(int x1,int y1,int x2,int y2)
1343 int clipped = 0, swapped=0;
1345 if(VOODOO3_INACTIVE()){
1349 INT_CLIPLINE(x1,y1,x2,y2,gr_screen.clip_left,gr_screen.clip_top,gr_screen.clip_right,gr_screen.clip_bottom,return,clipped=1,swapped=1);
1351 // Set up Render State - flat shading - alpha blending
1352 gr_glide_set_state( TEXTURE_SOURCE_NONE, COLOR_SOURCE_VERTEX, ALPHA_SOURCE_VERTEX, ALPHA_BLEND_ALPHA_BLEND_ALPHA, ZBUFFER_TYPE_NONE );
1356 a.x = i2fl(x1 + gr_screen.offset_x);
1357 a.y = i2fl(y1 + gr_screen.offset_y);
1358 a.r = i2fl(gr_screen.current_color.red);
1359 a.g = i2fl(gr_screen.current_color.green);
1360 a.b = i2fl(gr_screen.current_color.blue);
1361 a.a = i2fl(gr_screen.current_color.alpha);
1363 b.x = i2fl(x2 + gr_screen.offset_x);
1364 b.y = i2fl(y2 + gr_screen.offset_y);
1365 b.r = i2fl(gr_screen.current_color.red);
1366 b.g = i2fl(gr_screen.current_color.green);
1367 b.b = i2fl(gr_screen.current_color.blue);
1368 b.a = i2fl(gr_screen.current_color.alpha);
1390 void gr_glide_aaline( vertex *v1, vertex *v2 )
1392 float x1, y1, x2, y2;
1393 int clipped = 0, swapped = 0;
1394 float a1, b1, a2, b2;
1396 if(VOODOO3_INACTIVE()){
1406 a1 = (float)gr_screen.clip_left;
1407 b1 = (float)gr_screen.clip_top;
1408 a2 = (float)gr_screen.clip_right;
1409 b2 = (float)gr_screen.clip_bottom;
1411 FL_CLIPLINE(x1,y1,x2,y2,a1,b1,a2,b2,return,clipped=1,swapped=1);
1413 gr_glide_set_state( TEXTURE_SOURCE_NONE, COLOR_SOURCE_VERTEX, ALPHA_SOURCE_VERTEX, ALPHA_BLEND_ALPHA_BLEND_ALPHA, ZBUFFER_TYPE_NONE );
1417 a.x = i2fl(fl2i(x1)) + gr_screen.offset_x;
1418 a.y = i2fl(fl2i(y1)) + gr_screen.offset_y;
1419 a.r = i2fl(gr_screen.current_color.red);
1420 a.g = i2fl(gr_screen.current_color.green);
1421 a.b = i2fl(gr_screen.current_color.blue);
1422 a.a = i2fl(gr_screen.current_color.alpha);
1424 b.x = i2fl(fl2i(x2)) + gr_screen.offset_x;
1425 b.y = i2fl(fl2i(y2)) + gr_screen.offset_y;
1426 b.r = i2fl(gr_screen.current_color.red);
1427 b.g = i2fl(gr_screen.current_color.green);
1428 b.b = i2fl(gr_screen.current_color.blue);
1429 b.a = i2fl(gr_screen.current_color.alpha);
1447 grAADrawLine(&a, &b);
1450 void gr_glide_tmapper_internal( int nv, vertex * verts[], uint flags, int is_scaler )
1452 GrVertex GrVerts[25];
1454 float Glide_u_ratio = 0.0f;
1455 float Glide_v_ratio = 0.0f;
1457 if(VOODOO3_INACTIVE()){
1461 // Make nebula use the texture mapper... this blends the colors better.
1462 if ( flags & TMAP_FLAG_NEBULA ) {
1465 flags |= TMAP_FLAG_TEXTURED;
1467 static int test_bmp = -1;
1468 static ushort data[16];
1469 if ( test_bmp == -1 ){
1474 // stuff the fake bitmap
1475 a = 1; r = 255; g = 255; b = 255;
1477 bm_set_components((ubyte*)&pix, &r, &g, &b, &a);
1478 for(idx=0; idx<16; idx++){
1481 test_bmp = bm_create( 16, 4, 4, data );
1483 gr_set_bitmap( test_bmp );
1485 for (i=0; i<nv; i++ ) {
1486 verts[i]->u = verts[i]->v = 0.5f;
1491 gr_texture_source texture_source = (gr_texture_source)-1;
1492 gr_color_source color_source = (gr_color_source)-1;
1493 gr_alpha_source alpha_source = (gr_alpha_source)-1;
1494 gr_alpha_blend alpha_blend = (gr_alpha_blend)-1;
1495 gr_zbuffer_type zbuffer_type = (gr_zbuffer_type)-1;
1497 if ( gr_zbuffering ) {
1498 if ( is_scaler || (gr_screen.current_alphablend_mode == GR_ALPHABLEND_FILTER) ) {
1499 zbuffer_type = ZBUFFER_TYPE_READ;
1501 zbuffer_type = ZBUFFER_TYPE_FULL;
1504 zbuffer_type = ZBUFFER_TYPE_NONE;
1509 alpha_source = ALPHA_SOURCE_VERTEX;
1511 switch(gr_screen.current_alphablend_mode){
1512 case GR_ALPHABLEND_FILTER:
1513 // Blend with screen pixel using src*alpha+dst
1514 if ( gr_screen.current_alpha > 1.0f ) {
1515 alpha_blend = ALPHA_BLEND_ALPHA_BLEND_SRC_COLOR;
1518 alpha_blend = ALPHA_BLEND_ALPHA_ADDITIVE;
1519 alpha = gr_screen.current_alpha*255.0f;
1524 alpha_blend = ALPHA_BLEND_ALPHA_BLEND_ALPHA;
1529 if ( flags & TMAP_FLAG_TEXTURED ) {
1530 int texture_type = TCACHE_TYPE_NORMAL;
1532 if ( flags & TMAP_FLAG_NONDARKENING ) {
1533 alpha_source = ALPHA_SOURCE_VERTEX_NONDARKENING;
1534 //alpha_source = ALPHA_SOURCE_VERTEX_TIMES_TEXTURE;
1535 texture_type = TCACHE_TYPE_NONDARKENING;
1537 alpha_source = ALPHA_SOURCE_VERTEX_TIMES_TEXTURE;
1538 texture_type = TCACHE_TYPE_XPARENT;
1542 color_source = COLOR_SOURCE_VERTEX_TIMES_TEXTURE;
1543 texture_source = TEXTURE_SOURCE_DECAL;
1545 // force texture type
1546 if(flags & TMAP_FLAG_BITMAP_SECTION){
1547 texture_type = TCACHE_TYPE_BITMAP_SECTION;
1550 if ( !gr_tcache_set( gr_screen.current_bitmap, texture_type, &Glide_u_ratio, &Glide_v_ratio, 0, gr_screen.current_bitmap_sx, gr_screen.current_bitmap_sy )) {
1551 // Error setting texture!
1552 mprintf(( "GLIDE: Error setting texture!\n" ));
1553 // Mark as no texturing
1554 color_source = COLOR_SOURCE_VERTEX;
1555 texture_source = TEXTURE_SOURCE_NONE;
1558 color_source = COLOR_SOURCE_VERTEX;
1559 texture_source = TEXTURE_SOURCE_NONE;
1560 if(flags & TMAP_FLAG_ALPHA){
1561 alpha_source = ALPHA_SOURCE_VERTEX;
1565 // zbuffer_type = ZBUFFER_TYPE_NONE;
1566 // alpha_source = ALPHA_SOURCE_VERTEX;
1567 // alpha_blend = ALPHA_BLEND_NONE;
1569 // color_source = COLOR_SOURCE_VERTEX;
1570 // texture_source = TEXTURE_SOURCE_NONE;
1571 gr_glide_set_state( texture_source, color_source, alpha_source, alpha_blend, zbuffer_type );
1574 x1 = gr_screen.clip_left*16;
1575 x2 = gr_screen.clip_right*16+15;
1576 y1 = gr_screen.clip_top*16;
1577 y2 = gr_screen.clip_bottom*16+15;
1579 // memset( GrVerts, 0, sizeof(GrVertex) * 25 );
1581 for (i=0; i<nv; i++ ) {
1582 if ( flags & TMAP_FLAG_ALPHA ) {
1583 GrVerts[i].a = i2fl(verts[i]->a);
1585 GrVerts[i].a = alpha;
1588 if ( flags & TMAP_FLAG_NEBULA ) {
1589 int pal = (verts[i]->b*(NEBULA_COLORS-1))/255;
1590 GrVerts[i].r = i2fl(gr_palette[pal*3+0]);
1591 GrVerts[i].g = i2fl(gr_palette[pal*3+1]);
1592 GrVerts[i].b = i2fl(gr_palette[pal*3+2]);
1593 } else if ( (flags & TMAP_FLAG_RAMP) && (flags & TMAP_FLAG_GOURAUD) ) {
1594 GrVerts[i].r = Gr_gamma_lookup_float[verts[i]->b];
1595 GrVerts[i].g = Gr_gamma_lookup_float[verts[i]->b];
1596 GrVerts[i].b = Gr_gamma_lookup_float[verts[i]->b];
1597 } else if ( (flags & TMAP_FLAG_RGB) && (flags & TMAP_FLAG_GOURAUD) ) {
1598 // Make 0.75 be 256.0f
1599 GrVerts[i].r = Gr_gamma_lookup_float[verts[i]->r];
1600 GrVerts[i].g = Gr_gamma_lookup_float[verts[i]->g];
1601 GrVerts[i].b = Gr_gamma_lookup_float[verts[i]->b];
1603 if ( flags & TMAP_FLAG_TEXTURED ) {
1604 GrVerts[i].r = 255.0f;
1605 GrVerts[i].g = 255.0f;
1606 GrVerts[i].b = 255.0f;
1608 GrVerts[i].r = i2fl(gr_screen.current_color.red);
1609 GrVerts[i].g = i2fl(gr_screen.current_color.green);
1610 GrVerts[i].b = i2fl(gr_screen.current_color.blue);
1615 x = fl2i(verts[i]->sx*16.0f);
1616 y = fl2i(verts[i]->sy*16.0f);
1618 if ( flags & TMAP_FLAG_CORRECT ) {
1622 } else if ( x > x2 ) {
1627 } else if ( y > y2 ) {
1632 x += gr_screen.offset_x*16;
1633 y += gr_screen.offset_y*16;
1635 GrVerts[i].x = i2fl(x) / 16.0f;
1636 GrVerts[i].y = i2fl(y) / 16.0f;
1638 //verts[i]->sw = 1.0f;
1640 GrVerts[i].oow=verts[i]->sw;
1642 if ( flags & TMAP_FLAG_TEXTURED ) {
1643 GrVerts[i].tmuvtx[GR_TMU0].oow=verts[i]->sw;
1644 GrVerts[i].tmuvtx[GR_TMU0].sow=verts[i]->u * verts[i]->sw * Glide_u_ratio;
1645 GrVerts[i].tmuvtx[GR_TMU0].tow=verts[i]->v * verts[i]->sw * Glide_v_ratio;
1649 // if we're rendering against a fullneb background
1650 if(flags & TMAP_FLAG_PIXEL_FOG){
1655 // get the average pixel color behind the vertices
1656 for(i=0; i<nv; i++){
1657 neb2_get_pixel((int)GrVerts[i].x, (int)GrVerts[i].y, &r, &g, &b);
1668 gr_fog_set(GR_FOGMODE_FOG, ra, ga, ba);
1671 if ( flags & TMAP_FLAG_CORRECT ) {
1672 grDrawPolygonVertexList( nv, GrVerts );
1674 for (i=1; i<nv-1; i++ ) {
1675 guDrawTriangleWithClip(&GrVerts[0],&GrVerts[i],&GrVerts[i+1]);
1680 // if(flags & TMAP_FLAG_PIXEL_FOG){
1681 // gr_fog_set(GR_FOGMODE_NONE, 0, 0, 0);
1685 void gr_glide_tmapper( int nv, vertex * verts[], uint flags )
1687 gr_glide_tmapper_internal( nv, verts, flags, 0 );
1690 #define FIND_SCALED_NUM(x,x0,x1,y0,y1) (((((x)-(x0))*((y1)-(y0)))/((x1)-(x0)))+(y0))
1692 void gr_glide_aascaler(vertex *va, vertex *vb )
1697 void gr_glide_scaler(vertex *va, vertex *vb )
1699 float x0, y0, x1, y1;
1700 float u0, v0, u1, v1;
1701 float clipped_x0, clipped_y0, clipped_x1, clipped_y1;
1702 float clipped_u0, clipped_v0, clipped_u1, clipped_v1;
1703 float xmin, xmax, ymin, ymax;
1704 int dx0, dy0, dx1, dy1;
1706 if(VOODOO3_INACTIVE()){
1710 //============= CLIP IT =====================
1712 x0 = va->sx; y0 = va->sy;
1713 x1 = vb->sx; y1 = vb->sy;
1715 xmin = i2fl(gr_screen.clip_left); ymin = i2fl(gr_screen.clip_top);
1716 xmax = i2fl(gr_screen.clip_right); ymax = i2fl(gr_screen.clip_bottom);
1718 u0 = va->u; v0 = va->v;
1719 u1 = vb->u; v1 = vb->v;
1721 // Check for obviously offscreen bitmaps...
1722 if ( (y1<=y0) || (x1<=x0) ) return;
1723 if ( (x1<xmin ) || (x0>xmax) ) return;
1724 if ( (y1<ymin ) || (y0>ymax) ) return;
1726 clipped_u0 = u0; clipped_v0 = v0;
1727 clipped_u1 = u1; clipped_v1 = v1;
1729 clipped_x0 = x0; clipped_y0 = y0;
1730 clipped_x1 = x1; clipped_y1 = y1;
1732 // Clip the left, moving u0 right as necessary
1734 clipped_u0 = FIND_SCALED_NUM(xmin,x0,x1,u0,u1);
1738 // Clip the right, moving u1 left as necessary
1740 clipped_u1 = FIND_SCALED_NUM(xmax,x0,x1,u0,u1);
1744 // Clip the top, moving v0 down as necessary
1746 clipped_v0 = FIND_SCALED_NUM(ymin,y0,y1,v0,v1);
1750 // Clip the bottom, moving v1 up as necessary
1752 clipped_v1 = FIND_SCALED_NUM(ymax,y0,y1,v0,v1);
1756 dx0 = fl2i(clipped_x0); dx1 = fl2i(clipped_x1);
1757 dy0 = fl2i(clipped_y0); dy1 = fl2i(clipped_y1);
1759 if (dx1<=dx0) return;
1760 if (dy1<=dy0) return;
1762 //============= DRAW IT =====================
1776 v[1].sx = clipped_x1;
1777 v[1].sy = clipped_y0;
1780 v[1].u = clipped_u1;
1781 v[1].v = clipped_v0;
1784 v[2].sx = clipped_x1;
1785 v[2].sy = clipped_y1;
1788 v[2].u = clipped_u1;
1789 v[2].v = clipped_v1;
1792 v[3].sx = clipped_x0;
1793 v[3].sy = clipped_y1;
1796 v[3].u = clipped_u0;
1797 v[3].v = clipped_v1;
1799 //glide_zbuffering(0);
1800 gr_glide_tmapper_internal( 4, vl, TMAP_FLAG_TEXTURED, 1 );
1804 void gr_glide_aabitmap_ex_new(int x,int y,int w,int h,int sx,int sy)
1806 if ( w < 1 ) return;
1807 if ( h < 1 ) return;
1809 if ( !gr_screen.current_color.is_alphacolor ) return;
1811 if(VOODOO3_INACTIVE()){
1815 // mprintf(( "x=%d, y=%d, w=%d, h=%d\n", x, y, w, h ));
1816 // mprintf(( "sx=%d, sy=%d, bw=%d, bh=%d\n", sx, sy, bmp->w, bmp->h ));
1818 float Glide_u_ratio;
1819 float Glide_v_ratio;
1821 // Set up Render State - flat shading - alpha blending
1822 gr_glide_set_state( TEXTURE_SOURCE_DECAL, COLOR_SOURCE_VERTEX, ALPHA_SOURCE_VERTEX_TIMES_TEXTURE, ALPHA_BLEND_ALPHA_BLEND_ALPHA, ZBUFFER_TYPE_NONE );
1824 if ( !gr_tcache_set( gr_screen.current_bitmap, TCACHE_TYPE_AABITMAP, &Glide_u_ratio, &Glide_v_ratio ) ) {
1825 // Couldn't set texture
1826 mprintf(( "GLIDE: Error setting aabitmap texture!\n" ));
1830 GrVertex GrVerts[4];
1832 float u0, u1, v0, v1;
1835 r = i2fl(gr_screen.current_color.red);
1836 g = i2fl(gr_screen.current_color.green);
1837 b = i2fl(gr_screen.current_color.blue);
1838 a = i2fl(gr_screen.current_color.alpha);
1842 bm_get_info( gr_screen.current_bitmap, &bw, &bh );
1844 u0 = Glide_u_ratio*i2fl(sx)/i2fl(bw);
1845 v0 = Glide_v_ratio*i2fl(sy)/i2fl(bh);
1847 u1 = Glide_u_ratio*i2fl(sx+w)/i2fl(bw);
1848 v1 = Glide_v_ratio*i2fl(sy+h)/i2fl(bh);
1850 float x1, x2, y1, y2;
1851 x1 = i2fl(x+gr_screen.offset_x);
1852 y1 = i2fl(y+gr_screen.offset_y);
1853 x2 = i2fl(x+w+gr_screen.offset_x);
1854 y2 = i2fl(y+h+gr_screen.offset_y);
1861 GrVerts[i].oow = 1.0f;
1866 GrVerts[i].tmuvtx[GR_TMU0].sow=u0;
1867 GrVerts[i].tmuvtx[GR_TMU0].tow=v0;
1872 GrVerts[i].oow = 1.0f;
1877 GrVerts[i].tmuvtx[GR_TMU0].sow=u1;
1878 GrVerts[i].tmuvtx[GR_TMU0].tow=v0;
1883 GrVerts[i].oow = 1.0f;
1888 GrVerts[i].tmuvtx[GR_TMU0].sow=u1;
1889 GrVerts[i].tmuvtx[GR_TMU0].tow=v1;
1894 GrVerts[i].oow = 1.0f;
1899 GrVerts[i].tmuvtx[GR_TMU0].sow=u0;
1900 GrVerts[i].tmuvtx[GR_TMU0].tow=v1;
1902 grDrawPolygonVertexList( 4, GrVerts );
1907 void gr_glide_aabitmap_ex(int x,int y,int w,int h,int sx,int sy)
1914 int dx1=x, dx2=x+w-1;
1915 int dy1=y, dy2=y+h-1;
1918 bm_get_info( gr_screen.current_bitmap, &bw, &bh, NULL );
1923 if ( count > 1 ) Int3();
1927 if ((dx1 > gr_screen.clip_right ) || (dx2 < gr_screen.clip_left)) return;
1928 if ((dy1 > gr_screen.clip_bottom ) || (dy2 < gr_screen.clip_top)) return;
1929 if ( dx1 < gr_screen.clip_left ) { sx += gr_screen.clip_left-dx1; dx1 = gr_screen.clip_left; }
1930 if ( dy1 < gr_screen.clip_top ) { sy += gr_screen.clip_top-dy1; dy1 = gr_screen.clip_top; }
1931 if ( dx2 > gr_screen.clip_right ) { dx2 = gr_screen.clip_right; }
1932 if ( dy2 > gr_screen.clip_bottom ) { dy2 = gr_screen.clip_bottom; }
1949 if ( sx + w > bw ) {
1954 if ( sy + h > bh ) {
1959 if ( w < 1 ) return; // clipped away!
1960 if ( h < 1 ) return; // clipped away!
1964 // Make sure clipping algorithm works
1968 Assert( w == (dx2-dx1+1) );
1969 Assert( h == (dy2-dy1+1) );
1972 Assert( sx+w <= bw );
1973 Assert( sy+h <= bh );
1974 Assert( dx2 >= dx1 );
1975 Assert( dy2 >= dy1 );
1976 Assert( (dx1 >= gr_screen.clip_left ) && (dx1 <= gr_screen.clip_right) );
1977 Assert( (dx2 >= gr_screen.clip_left ) && (dx2 <= gr_screen.clip_right) );
1978 Assert( (dy1 >= gr_screen.clip_top ) && (dy1 <= gr_screen.clip_bottom) );
1979 Assert( (dy2 >= gr_screen.clip_top ) && (dy2 <= gr_screen.clip_bottom) );
1982 // We now have dx1,dy1 and dx2,dy2 and sx, sy all set validly within clip regions.
1984 // Draw bitmap bm[sx,sy] into (dx1,dy1)-(dx2,dy2)
1985 gr_glide_aabitmap_ex_new(dx1,dy1,dx2-dx1+1,dy2-dy1+1,sx,sy);
1988 void gr_glide_string_hack( int sx, int sy, char *s )
1990 int width, spacing, letter;
1993 if ( !Current_font ) {
1997 gr_set_bitmap(Current_font->bitmap_id);
2002 if (sx==0x8000) { //centered
2003 x = get_centered_x(s);
2014 while (*s== '\n' ) {
2016 y += Current_font->h;
2017 if (sx==0x8000) { //centered
2018 x = get_centered_x(s);
2023 if (*s == 0 ) break;
2025 letter = get_char_width(s[0],s[1],&width,&spacing);
2028 if (letter<0) { //not in font, draw as space
2032 // formerly a call to gr_glide_char(...)
2036 ch = &Current_font->char_data[letter];
2038 int _sx = Current_font->bm_u[letter];
2039 int _sy = Current_font->bm_v[letter];
2041 gr_glide_aabitmap_ex( x, y, ch->byte_width, Current_font->h, _sx, _sy );
2046 void gr_glide_aabitmap(int x, int y)
2050 bm_get_info( gr_screen.current_bitmap, &w, &h, NULL );
2051 int dx1=x, dx2=x+w-1;
2052 int dy1=y, dy2=y+h-1;
2055 if ((dx1 > gr_screen.clip_right ) || (dx2 < gr_screen.clip_left)) return;
2056 if ((dy1 > gr_screen.clip_bottom ) || (dy2 < gr_screen.clip_top)) return;
2057 if ( dx1 < gr_screen.clip_left ) { sx = gr_screen.clip_left-dx1; dx1 = gr_screen.clip_left; }
2058 if ( dy1 < gr_screen.clip_top ) { sy = gr_screen.clip_top-dy1; dy1 = gr_screen.clip_top; }
2059 if ( dx2 > gr_screen.clip_right ) { dx2 = gr_screen.clip_right; }
2060 if ( dy2 > gr_screen.clip_bottom ) { dy2 = gr_screen.clip_bottom; }
2062 if ( sx < 0 ) return;
2063 if ( sy < 0 ) return;
2064 if ( sx >= w ) return;
2065 if ( sy >= h ) return;
2067 // Draw bitmap bm[sx,sy] into (dx1,dy1)-(dx2,dy2)
2068 gr_aabitmap_ex(dx1,dy1,dx2-dx1+1,dy2-dy1+1,sx,sy);
2072 void gr_glide_gradient(int x1,int y1,int x2,int y2)
2074 int clipped = 0, swapped=0;
2076 if(VOODOO3_INACTIVE()){
2080 if ( !gr_screen.current_color.is_alphacolor ) {
2081 gr_line( x1, y1, x2, y2 );
2085 INT_CLIPLINE(x1,y1,x2,y2,gr_screen.clip_left,gr_screen.clip_top,gr_screen.clip_right,gr_screen.clip_bottom,return,clipped=1,swapped=1);
2087 // Set up Render State - flat shading - alpha blending
2088 gr_glide_set_state( TEXTURE_SOURCE_NONE, COLOR_SOURCE_VERTEX, ALPHA_SOURCE_VERTEX, ALPHA_BLEND_ALPHA_BLEND_ALPHA, ZBUFFER_TYPE_NONE );
2092 a.x = i2fl(x1 + gr_screen.offset_x);
2093 a.y = i2fl(y1 + gr_screen.offset_y);
2094 a.r = i2fl(gr_screen.current_color.red);
2095 a.g = i2fl(gr_screen.current_color.green);
2096 a.b = i2fl(gr_screen.current_color.blue);
2098 b.x = i2fl(x2 + gr_screen.offset_x);
2099 b.y = i2fl(y2 + gr_screen.offset_y);
2100 b.r = i2fl(gr_screen.current_color.red);
2101 b.g = i2fl(gr_screen.current_color.green);
2102 b.b = i2fl(gr_screen.current_color.blue);
2106 b.a = i2fl(gr_screen.current_color.alpha);
2109 a.a = i2fl(gr_screen.current_color.alpha);
2131 void gr_glide_set_palette(ubyte *new_palette, int force_flag )
2133 gr_palette_faded_out = 0;
2135 if(VOODOO3_INACTIVE()){
2139 #ifdef USE_8BPP_TEXTURES
2140 GuTexPalette palette;
2142 glide_free_textures();
2146 for (i=0;i<256; i++ ) {
2147 palette.data[i] = 0xFF000000;
2148 palette.data[i] |= new_palette[i*3+2];
2149 palette.data[i] |= new_palette[i*3+1]<<8;
2150 palette.data[i] |= new_palette[i*3+0]<<16;
2153 grTexDownloadTable( GR_TMU0, GR_TEXTABLE_PALETTE, &palette );
2158 void gr_glide_init_color(color *c, int r, int g, int b)
2160 c->screen_sig = gr_screen.signature;
2161 c->red = unsigned char(r);
2162 c->green = unsigned char(g);
2163 c->blue = unsigned char(b);
2165 c->ac_type = AC_TYPE_NONE;
2167 c->is_alphacolor = 0;
2171 void gr_glide_init_alphacolor( color *clr, int r, int g, int b, int alpha, int type )
2173 if ( r < 0 ) r = 0; else if ( r > 255 ) r = 255;
2174 if ( g < 0 ) g = 0; else if ( g > 255 ) g = 255;
2175 if ( b < 0 ) b = 0; else if ( b > 255 ) b = 255;
2176 if ( alpha < 0 ) alpha = 0; else if ( alpha > 255 ) alpha = 255;
2178 gr_glide_init_color( clr, r, g, b );
2180 clr->alpha = unsigned char(alpha);
2181 clr->ac_type = (ubyte)type;
2182 clr->alphacolor = -1;
2183 clr->is_alphacolor = 1;
2186 void gr_glide_set_color( int r, int g, int b )
2188 Assert((r >= 0) && (r < 256));
2189 Assert((g >= 0) && (g < 256));
2190 Assert((b >= 0) && (b < 256));
2192 gr_glide_init_color( &gr_screen.current_color, r, g, b );
2195 void gr_glide_get_color( int * r, int * g, int * b )
2197 if (r) *r = gr_screen.current_color.red;
2198 if (g) *g = gr_screen.current_color.green;
2199 if (b) *b = gr_screen.current_color.blue;
2202 void gr_glide_set_color_fast(color *dst)
2204 if ( dst->screen_sig != gr_screen.signature ) {
2205 if ( dst->is_alphacolor ) {
2206 gr_glide_init_alphacolor( dst, dst->red, dst->green, dst->blue, dst->alpha, dst->ac_type );
2208 gr_glide_init_color( dst, dst->red, dst->green, dst->blue );
2211 gr_screen.current_color = *dst;
2216 void gr_glide_flash(int r, int g, int b)
2222 if(VOODOO3_INACTIVE()){
2230 if ( Flash_r || Flash_g || Flash_b ) {
2231 gr_glide_set_state( TEXTURE_SOURCE_NONE, COLOR_SOURCE_VERTEX, ALPHA_SOURCE_VERTEX, ALPHA_BLEND_ALPHA_ADDITIVE, ZBUFFER_TYPE_NONE );
2233 GrVertex GrVerts[4];
2242 float x1, x2, y1, y2;
2243 x1 = i2fl(gr_screen.clip_left+gr_screen.offset_x);
2244 y1 = i2fl(gr_screen.clip_top+gr_screen.offset_y);
2245 x2 = i2fl(gr_screen.clip_right+gr_screen.offset_x);
2246 y2 = i2fl(gr_screen.clip_bottom+gr_screen.offset_y);
2282 grDrawPolygonVertexList( 4, GrVerts );
2289 void gr_glide_activate(int active)
2291 if (!Glide_running) {
2295 mprintf(( "Glide activate: %d\n", active ));
2299 // choose resolution
2300 GrScreenResolution_t res_mode;
2301 if((gr_screen.max_w == 1024) && (gr_screen.max_h == 768)){
2302 res_mode = GR_RESOLUTION_1024x768;
2304 res_mode = GR_RESOLUTION_640x480;
2307 HWND hwnd = (HWND)os_get_window();
2311 if(Glide_deactivate == 0){
2315 Glide_deactivate = 0;
2318 SetActiveWindow(hwnd);
2319 SetForegroundWindow(hwnd);
2320 grSstWinOpen( (DWORD)hwnd, res_mode, GR_REFRESH_60Hz, GR_COLORFORMAT_ABGR, GR_ORIGIN_UPPER_LEFT, 2, 1 );
2321 ShowWindow(hwnd,SW_MAXIMIZE);
2322 gr_glide_clip_cursor(1);
2323 glide_tcache_init();
2324 grGammaCorrectionValue(1.0f);
2327 // already deactivated
2328 if(Glide_deactivate == VOODOO3_DEACTIVATED){
2332 Glide_deactivate = VOODOO3_DEACTIVATED;
2335 gr_glide_clip_cursor(0);
2336 ShowWindow(hwnd,SW_MINIMIZE);
2341 HWND hwnd = (HWND)os_get_window();
2347 // SetActiveWindow(hwnd);
2348 // SetForegroundWindow(hwnd);
2349 ShowWindow(hwnd,SW_RESTORE);
2350 // gr_glide_clip_cursor(1);
2351 // grSstControl(GR_CONTROL_ACTIVATE);
2357 // grSstControl(GR_CONTROL_DEACTIVATE);
2359 ShowWindow(hwnd,SW_MINIMIZE);
2366 // copy from one pixel buffer to another
2368 // from pointer to source buffer
2369 // to pointer to dest. buffet
2370 // pixels number of pixels to copy
2371 // fromsize source pixel size
2372 // tosize dest. pixel size
2374 static int tga_copy_data(char *to, char *from, int pixels, int fromsize, int tosize)
2386 if ( (fromsize == 2) && (tosize == 3) ) {
2387 ushort *src = (ushort *)from;
2388 ubyte *dst = (ubyte *)to;
2391 for (i=0; i<pixels; i++ ) {
2392 ushort pixel = *src++;
2395 b = ((pixel & bmask)>>bshift)*bscale;
2396 g = ((pixel & gmask)>>gshift)*gscale;
2397 r = ((pixel & rmask)>>rshift)*rscale;
2399 // Adjust for gamma and output it
2404 return tosize*pixels;
2407 return tosize*pixels;
2414 // tga_pixels_equal -- Test if two pixels are identical
2420 static int tga_pixels_equal(char *pix1, char *pix2, int pixbytes)
2423 if ( *pix1++ != *pix2++ ) {
2426 } while ( --pixbytes > 0 );
2432 // tga_compress - Do the Run Length Compression
2435 // out Buffer to write it out to
2436 // in Buffer to compress
2437 // bytecount Number of bytes input
2438 // pixsize Number of bytes in input pixel
2439 // outsize Number of bytes in output buffer
2441 int tga_compress(char *out, char *in, int bytecount )
2445 int pixcount; // number of pixels in the current packet
2446 char *inputpixel=NULL; // current input pixel position
2447 char *matchpixel=NULL; // pixel value to match for a run
2448 char *flagbyte=NULL; // location of last flag byte to set
2449 int rlcount; // current count in r.l. string
2450 int rlthresh; // minimum valid run length
2451 char *copyloc; // location to begin copying at
2453 // set the threshold -- the minimum valid run length
2456 rlthresh = 2; // for 8bpp, require a 2 pixel span before rle'ing
2461 // set the first pixel up
2463 flagbyte = out; // place to put next flag if run
2467 copyloc = (char *)0;
2469 // loop till data processing complete
2472 // if we have accumulated a 128-byte packet, process it
2473 if ( pixcount == 129 ) {
2476 // set the run flag if this is a run
2478 if ( rlcount >= rlthresh ) {
2483 // copy the data into place
2485 flagbyte += tga_copy_data(flagbyte, copyloc, pixcount-1, pixsize, outsize);
2488 // set up for next packet
2492 // if zeroth byte, handle as special case
2493 if ( pixcount == 1 ) {
2495 copyloc = inputpixel; /* point to 1st guy in packet */
2496 matchpixel = inputpixel; /* set pointer to pix to match */
2498 inputpixel += pixsize;
2502 // assembling a packet -- look at next pixel
2504 // current pixel == match pixel?
2505 if ( tga_pixels_equal(inputpixel, matchpixel, outsize) ) {
2507 // establishing a run of enough length to
2508 // save space by doing it
2509 // -- write the non-run length packet
2510 // -- start run-length packet
2512 if ( ++rlcount == rlthresh ) {
2514 // close a non-run packet
2516 if ( pixcount > (rlcount+1) ) {
2517 // write out length and do not set run flag
2519 *flagbyte++ = (char)(pixcount - 2 - rlthresh);
2521 flagbyte += tga_copy_data(flagbyte, copyloc, (pixcount-1-rlcount), pixsize, outsize);
2523 copyloc = inputpixel;
2524 pixcount = rlcount + 1;
2529 // no match -- either break a run or continue without one
2530 // if a run exists break it:
2531 // write the bytes in the string (outsize+1)
2532 // start the next string
2534 if ( rlcount >= rlthresh ) {
2536 *flagbyte++ = (char)(0x80 | rlcount);
2537 flagbyte += tga_copy_data(flagbyte, copyloc, 1, pixsize, outsize);
2542 // not a match and currently not a run
2543 // - save the current pixel
2544 // - reset the run-length flag
2546 matchpixel = inputpixel;
2550 inputpixel += pixsize;
2551 } while ( inputpixel < (in + bytecount));
2553 // quit this buffer without loosing any data
2555 if ( --pixcount >= 1 ) {
2556 *flagbyte = (char)(pixcount - 1);
2557 if ( rlcount >= rlthresh ) {
2562 // copy the data into place
2564 flagbyte += tga_copy_data(flagbyte, copyloc, pixcount, pixsize, outsize);
2566 return(flagbyte-out);
2571 void gr_glide_print_screen(char *filename)
2575 ubyte outrow[1024*3*4];
2577 if(VOODOO3_INACTIVE()){
2581 if ( gr_screen.max_w > 1024 ) {
2582 mprintf(( "Screen too wide for print_screen\n" ));
2586 info.size=sizeof(GrLfbInfo_t);
2588 // get a read pointer
2589 if ( grLfbLock( GR_LFB_READ_ONLY, GR_BUFFER_BACKBUFFER, GR_LFBWRITEMODE_565,
2590 GR_ORIGIN_UPPER_LEFT, FXFALSE, &info)) {
2591 int w=gr_screen.max_w,h=gr_screen.max_h;
2593 int short_per_row=info.strideInBytes/2;
2595 rptr = (ushort *)info.lfbPtr;
2600 strcpy( tmp, NOX(".\\")); // specify a path mean files goes in root
2601 strcat( tmp, filename );
2602 strcat( tmp, NOX(".tga"));
2604 CFILE *f = cfopen(tmp, "wb");
2606 // Write the TGA header
2607 cfwrite_ubyte( 0, f ); // IDLength;
2608 cfwrite_ubyte( 0, f ); // ColorMapType;
2609 cfwrite_ubyte( 10, f ); // ImageType; // 2 = 24bpp, uncompressed, 10=24bpp rle compressed
2610 cfwrite_ushort( 0, f ); // CMapStart;
2611 cfwrite_ushort( 0, f ); // CMapLength;
2612 cfwrite_ubyte( 0, f ); // CMapDepth;
2613 cfwrite_ushort( 0, f ); // XOffset;
2614 cfwrite_ushort( 0, f ); // YOffset;
2615 cfwrite_ushort( (ushort)w, f ); // Width;
2616 cfwrite_ushort( (ushort)h, f ); // Height;
2617 cfwrite_ubyte( 24, f ); //PixelDepth;
2618 cfwrite_ubyte( 0, f ); //ImageDesc;
2620 // Go through and read our pixels
2622 int len = tga_compress( (char *)outrow, (char *)&rptr[(h-i-1)*short_per_row], w*sizeof(short) );
2624 cfwrite(outrow,len,1,f);
2630 grLfbUnlock( GR_LFB_READ_ONLY, GR_BUFFER_BACKBUFFER );
2632 mprintf(( "Couldn't get a lock to glide's back buffer!\n" ));
2638 int gr_glide_save_screen_internal(ushort *src_data)
2643 if(VOODOO3_INACTIVE()){
2647 info.size=sizeof(GrLfbInfo_t);
2649 // get a read pointer
2650 if ( grLfbLock( GR_LFB_READ_ONLY, GR_BUFFER_FRONTBUFFER, GR_LFBWRITEMODE_565,
2651 GR_ORIGIN_UPPER_LEFT, FXFALSE, &info)) {
2652 int w=gr_screen.max_w,h=gr_screen.max_h;
2654 int short_per_row=info.strideInBytes/2;
2656 rptr = (ushort *)info.lfbPtr;
2658 // Go through and read our pixels
2660 memcpy( &src_data[gr_screen.max_w*i], &rptr[i*short_per_row], w*sizeof(short) );
2664 grLfbUnlock( GR_LFB_READ_ONLY, GR_BUFFER_FRONTBUFFER );
2666 mprintf(( "Couldn't get a read lock to glide's back buffer!\n" ));
2673 static ushort *Gr_saved_screen = NULL;
2675 int gr_glide_save_screen()
2677 if(VOODOO3_INACTIVE()){
2681 if ( Gr_saved_screen ) {
2682 mprintf(( "Screen alread saved!\n" ));
2688 Gr_saved_screen = (ushort *)malloc( gr_screen.max_w*gr_screen.max_h*sizeof(ushort) );
2689 if (!Gr_saved_screen) {
2690 mprintf(( "Couldn't get memory for saved screen!\n" ));
2694 if ( !gr_glide_save_screen_internal(Gr_saved_screen) ) {
2695 free(Gr_saved_screen);
2696 Gr_saved_screen = NULL;
2700 if ( Gr_glide_mouse_saved ) {
2701 ushort *sptr, *dptr;
2703 sptr = Gr_glide_mouse_saved_data;
2705 for (int i=0; i<Gr_glide_mouse_saved_h; i++ ) {
2706 dptr = &Gr_saved_screen[(Gr_glide_mouse_saved_y1+i)*gr_screen.max_w+Gr_glide_mouse_saved_x1];
2708 for(int j=0; j<Gr_glide_mouse_saved_w; j++ ) {
2717 void gr_glide_restore_screen_internal(ushort *src_data)
2722 if(VOODOO3_INACTIVE()){
2726 info.size=sizeof(GrLfbInfo_t);
2728 // get a read pointer
2729 if ( grLfbLock( GR_LFB_WRITE_ONLY, GR_BUFFER_BACKBUFFER, GR_LFBWRITEMODE_565,
2730 GR_ORIGIN_UPPER_LEFT, FXFALSE, &info)) {
2731 int w=gr_screen.max_w,h=gr_screen.max_h;
2733 int short_per_row=info.strideInBytes/2;
2735 rptr = (ushort *)info.lfbPtr;
2737 // Go through and read our pixels
2739 memcpy( &rptr[i*short_per_row], &src_data[gr_screen.max_w*i], w*sizeof(short) );
2743 grLfbUnlock( GR_LFB_WRITE_ONLY, GR_BUFFER_BACKBUFFER );
2745 mprintf(( "Couldn't get a write lock to glide's back buffer!\n" ));
2750 void gr_glide_restore_screen(int id)
2752 if(VOODOO3_INACTIVE()){
2758 if ( !Gr_saved_screen ) {
2763 gr_glide_restore_screen_internal(Gr_saved_screen);
2766 void gr_glide_free_screen(int id)
2768 if(VOODOO3_INACTIVE()){
2772 if ( Gr_saved_screen ) {
2773 free( Gr_saved_screen );
2774 Gr_saved_screen = NULL;
2779 void gr_glide_force_windowed()
2781 if(VOODOO3_INACTIVE()){
2785 gr_glide_clip_cursor(0);
2786 grSstControl(GR_CONTROL_DEACTIVATE);
2791 static int Glide_dump_frames = 0;
2792 static ubyte *Glide_dump_buffer = NULL;
2793 static int Glide_dump_frame_number = 0;
2794 static int Glide_dump_frame_count = 0;
2795 static int Glide_dump_frame_count_max = 0;
2796 static int Glide_dump_frame_size = 0;
2798 void gr_glide_dump_frame_start(int first_frame, int frames_between_dumps)
2800 if(VOODOO3_INACTIVE()){
2804 if ( Glide_dump_frames ) {
2805 Int3(); // We're already dumping frames. See John.
2808 Glide_dump_frames = 1;
2809 Glide_dump_frame_number = first_frame;
2810 Glide_dump_frame_count = 0;
2811 Glide_dump_frame_count_max = frames_between_dumps;
2812 Glide_dump_frame_size = gr_screen.max_w * gr_screen.max_h * 2;
2814 if ( !Glide_dump_buffer ) {
2815 int size = Glide_dump_frame_count_max * Glide_dump_frame_size;
2816 Glide_dump_buffer = (ubyte *)malloc(size);
2817 if ( !Glide_dump_buffer ) {
2818 Error(LOCATION, "Unable to malloc %d bytes for dump buffer", size );
2824 // A hacked function to dump the frame buffer contents
2825 void gr_glide_dump_screen_hack( ushort * dst )
2830 if(VOODOO3_INACTIVE()){
2834 info.size=sizeof(GrLfbInfo_t);
2836 // get a read pointer
2837 if ( grLfbLock(GR_LFB_READ_ONLY, GR_BUFFER_BACKBUFFER, GR_LFBWRITEMODE_565, GR_ORIGIN_UPPER_LEFT, FXFALSE, &info)) {
2838 int w=gr_screen.max_w,h=gr_screen.max_h;
2840 int short_per_row=info.strideInBytes/2;
2842 rptr = (ushort *)info.lfbPtr;
2844 // Go through and read our pixels
2846 memcpy( &dst[gr_screen.max_w*i], &rptr[(h-i-1)*short_per_row], w*sizeof(short) );
2850 grLfbUnlock( GR_LFB_READ_ONLY, GR_BUFFER_BACKBUFFER );
2852 mprintf(( "Couldn't get a read lock to glide's back buffer for frame dump!\n" ));
2856 void gr_glide_get_region(int front, int w, int h, ubyte *data)
2863 if(VOODOO3_INACTIVE()){
2867 info.size=sizeof(GrLfbInfo_t);
2868 // get a read pointer
2869 if ( grLfbLock(GR_LFB_READ_ONLY, front ? GR_BUFFER_FRONTBUFFER : GR_BUFFER_BACKBUFFER, GR_LFBWRITEMODE_1555, GR_ORIGIN_UPPER_LEFT, FXFALSE, &info)){
2871 int short_per_row=info.strideInBytes/2;
2873 rptr = (ushort *)info.lfbPtr;
2875 ushort *sptr, *dptr;
2877 dptr = (ushort*)data;
2879 for (int i=0; i<h; i++ ) {
2880 sptr = &rptr[i*short_per_row];
2882 // 565 data is what we always get, so we need to swizzle
2883 for(int j=0; j<w; j++ ) {
2886 r = (ubyte)((bit_16 & 0xf800) >> 8);
2887 g = (ubyte)((bit_16 & 0x07e0) >> 3);
2888 b = (ubyte)((bit_16 & 0x001f) << 3);
2890 // swizzle the data to 1555 (BM_PIXEL_FORMAT_ARGB)
2892 bm_set_components((ubyte*)dptr++, &r, &g, &b, &a);
2897 grLfbUnlock(GR_LFB_READ_ONLY, front ? GR_BUFFER_FRONTBUFFER : GR_BUFFER_BACKBUFFER);
2901 void gr_glide_flush_frame_dump()
2904 char filename[MAX_PATH_LEN], *movie_path = ".\\";
2905 ubyte outrow[1024*3*4];
2907 if(VOODOO3_INACTIVE()){
2911 if ( gr_screen.max_w > 1024) {
2912 mprintf(( "Screen too wide for frame_dump\n" ));
2916 for (i = 0; i < Glide_dump_frame_count; i++) {
2918 int w = gr_screen.max_w;
2919 int h = gr_screen.max_h;
2921 sprintf(filename, NOX("%sfrm%04d.tga"), movie_path, Glide_dump_frame_number );
2922 Glide_dump_frame_number++;
2924 CFILE *f = cfopen(filename, "wb");
2926 // Write the TGA header
2927 cfwrite_ubyte( 0, f ); // IDLength;
2928 cfwrite_ubyte( 0, f ); // ColorMapType;
2929 cfwrite_ubyte( 10, f ); // ImageType; // 2 = 24bpp, uncompressed, 10=24bpp rle compressed
2930 cfwrite_ushort( 0, f ); // CMapStart;
2931 cfwrite_ushort( 0, f ); // CMapLength;
2932 cfwrite_ubyte( 0, f ); // CMapDepth;
2933 cfwrite_ushort( 0, f ); // XOffset;
2934 cfwrite_ushort( 0, f ); // YOffset;
2935 cfwrite_ushort( (ushort)w, f ); // Width;
2936 cfwrite_ushort( (ushort)h, f ); // Height;
2937 cfwrite_ubyte( 24, f ); //PixelDepth;
2938 cfwrite_ubyte( 0, f ); //ImageDesc;
2940 // Go through and write our pixels
2942 ubyte *src_ptr = Glide_dump_buffer+(i*Glide_dump_frame_size)+(j*w*2);
2944 int len = tga_compress( (char *)outrow, (char *)src_ptr, w*sizeof(short) );
2946 cfwrite(outrow,len,1,f);
2953 Glide_dump_frame_count = 0;
2956 void gr_glide_dump_frame()
2958 if(VOODOO3_INACTIVE()){
2962 // A hacked function to dump the frame buffer contents
2963 gr_glide_dump_screen_hack( (ushort *)(Glide_dump_buffer+(Glide_dump_frame_count*Glide_dump_frame_size)) );
2965 Glide_dump_frame_count++;
2967 if ( Glide_dump_frame_count == Glide_dump_frame_count_max ) {
2968 gr_glide_flush_frame_dump();
2972 void gr_glide_dump_frame_stop()
2974 if(VOODOO3_INACTIVE()){
2978 if ( !Glide_dump_frames ) {
2979 Int3(); // We're not dumping frames. See John.
2983 // dump any remaining frames
2984 gr_glide_flush_frame_dump();
2986 Glide_dump_frames = 0;
2987 if ( Glide_dump_buffer ) {
2988 free(Glide_dump_buffer);
2989 Glide_dump_buffer = NULL;
2993 #define FADE_TIME (F1_0/4) // How long to fade out
2995 void gr_glide_fade_out(int instantaneous)
2999 if(VOODOO3_INACTIVE()){
3006 tmp_data = (ushort *)malloc( gr_screen.max_w*gr_screen.max_h*sizeof(ushort) );
3009 gr_glide_save_screen_internal(tmp_data);
3012 if (!gr_palette_faded_out) {
3014 if ( !instantaneous ) {
3018 fix start_time, stop_time, t1;
3021 start_time = timer_get_fixed_seconds();
3025 //int c = (255*(FADE_TIME-t1))/FADE_TIME;
3026 int c = (255*t1)/FADE_TIME;
3029 } else if ( c > 255 ) {
3033 gr_glide_restore_screen_internal(tmp_data);
3035 for (int i=0; i<gr_screen.max_h; i++ ) {
3036 glide_shade_scanline( 0, gr_screen.max_w-1, i, 0, 0, 0, c );
3042 t1 = timer_get_fixed_seconds() - start_time;
3044 } while ( (t1 < FADE_TIME) && (t1>=0) ); // Loop as long as time not up and timer hasn't rolled
3046 stop_time = timer_get_fixed_seconds();
3048 mprintf(( "Took %d frames (and %.1f secs) to fade out\n", count, f2fl(stop_time-start_time) ));
3056 gr_palette_faded_out = 1;
3064 void gr_glide_fade_in(int instantaneous)
3068 if(VOODOO3_INACTIVE()){
3075 tmp_data = (ushort *)malloc( gr_screen.max_w*gr_screen.max_h*sizeof(ushort) );
3078 gr_glide_save_screen_internal(tmp_data);
3081 if (gr_palette_faded_out) {
3083 gr_palette_faded_out = 0;
3085 if ( !instantaneous ) {
3089 fix start_time, stop_time, t1;
3092 start_time = timer_get_fixed_seconds();
3096 int c = (255*(FADE_TIME-t1))/FADE_TIME;
3099 } else if ( c > 255 ) {
3103 gr_glide_restore_screen_internal(tmp_data);
3105 for (int i=0; i<gr_screen.max_h; i++ ) {
3106 glide_shade_scanline( 0, gr_screen.max_w-1, i, 0, 0, 0, c );
3112 t1 = timer_get_fixed_seconds() - start_time;
3114 } while ( (t1 < FADE_TIME) && (t1>=0) ); // Loop as long as time not up and timer hasn't rolled
3116 stop_time = timer_get_fixed_seconds();
3118 mprintf(( "Took %d frames (and %.1f secs) to fade out\n", count, f2fl(stop_time-start_time) ));
3126 gr_glide_restore_screen_internal(tmp_data);
3136 void gr_glide_cleanup()
3138 if ( !Inited ) return;
3145 gr_glide_clip_cursor(0);
3147 glide_tcache_cleanup();
3152 void gr_glide_set_gamma(float gamma)
3155 Gr_gamma_int = int(Gr_gamma*100);
3157 // Create the Gamma lookup table
3159 for (i=0; i<256; i++ ) {
3160 int v = fl2i(pow(i2fl(i)/255.0f, 1.0f/Gr_gamma)*255.0f);
3163 } else if ( v < 0 ) {
3166 Gr_gamma_lookup[i] = v;
3169 for (i=0; i<256; i++ ) {
3170 float v = (float)pow(i2fl(i)/255.0f, 1.0f/Gr_gamma)*255.0f;
3173 } else if ( v < 0.0f ) {
3176 Gr_gamma_lookup_float[i] = v;
3179 // Flush any existing textures
3180 glide_tcache_flush();
3184 void gr_glide_fog_set(int fog_mode, int r, int g, int b, float fog_near, float fog_far)
3186 GrColor_t color = 0;
3188 if(VOODOO3_INACTIVE()){
3192 Assert((r >= 0) && (r < 256));
3193 Assert((g >= 0) && (g < 256));
3194 Assert((b >= 0) && (b < 256));
3197 gr_glide_init_color( &gr_screen.current_fog_color, r, g, b );
3198 if(fog_near >= 0.0f){
3199 gr_screen.fog_near = fog_near;
3201 if(fog_far >= 0.0f){
3202 gr_screen.fog_far = fog_far;
3204 gr_screen.current_fog_mode = fog_mode;
3206 // enable/disable fog
3207 if(fog_mode == GR_FOGMODE_NONE){
3208 grFogMode(GR_FOG_DISABLE);
3210 // always unset the global for value if we're disabling fog
3211 gr_screen.fog_near = -1.0f;
3212 gr_screen.fog_far = -1.0f;
3216 grFogMode(GR_FOG_WITH_TABLE);
3218 // set the fog color
3219 color |= ((ubyte)r);
3220 color |= ((ubyte)g << 8);
3221 color |= ((ubyte)b << 16);
3222 grFogColorValue(color);
3224 // only generate a new fog table if we have to
3225 if((fog_near >= 0.0f) && (fog_far > fog_near)){
3226 guFogGenerateLinear(Glide_linear_fogtable, fog_near, fog_far);
3229 // set the fog table
3230 grFogTable(Glide_linear_fogtable);
3233 void gr_glide_get_pixel(int x, int y, int *r, int *g, int *b)
3240 if(VOODOO3_INACTIVE()){
3244 // returns data in 565 format
3245 grLfbReadRegion(GR_BUFFER_BACKBUFFER, (FxU32)x, (FxU32)y, 1, 1, 2, &pixel);
3247 // unpack pixel color
3248 *r = (0xf800 & pixel) >> 8;
3249 *g = (0x07e0 & pixel) >> 3;
3250 *b = (0x001f & pixel) << 3;
3253 // resolution checking
3254 int gr_glide_supports_res_ingame(int res)
3259 int gr_glide_supports_res_interface(int res)
3264 void gr_glide_set_cull(int cull)
3268 void gr_glide_filter_set(int filter)
3270 if(VOODOO3_INACTIVE()){
3275 grTexFilterMode(GR_TMU0, GR_TEXTUREFILTER_BILINEAR, GR_TEXTUREFILTER_BILINEAR);
3277 grTexFilterMode(GR_TMU0, GR_TEXTUREFILTER_POINT_SAMPLED, GR_TEXTUREFILTER_POINT_SAMPLED);
3282 void gr_glide_set_clear_color(int r, int g, int b)
3284 gr_init_color(&gr_screen.current_clear_color, r, g, b);
3287 extern int movie_rendered_flag;
3288 extern int movie_frame_count;
3290 void __cdecl grglide_MovieShowFrame(void *buf,uint bufw,uint bufh, uint sx,uint sy,uint w,uint h,uint dstx,uint dsty, uint hi_color)
3297 if(VOODOO3_INACTIVE()){
3304 ushort *src_data = (ushort *)buf;
3306 movie_rendered_flag = 1;
3315 SetRect(&srect, sx, sy, sx+w-1, sy+h-1);
3316 //SetRect(&drect, dstx, dsty, dstx+w-1, dsty+h-1);
3317 dstx = (gr_screen.max_w - w)/2;
3318 dsty = (gr_screen.max_h - h)/2;
3319 SetRect(&drect, dstx, dsty, dstx+w-1, dsty+h-1);
3324 info.size=sizeof(GrLfbInfo_t);
3326 // get a read pointer
3327 if ( grLfbLock( GR_LFB_WRITE_ONLY, GR_BUFFER_BACKBUFFER, GR_LFBWRITEMODE_1555,
3328 GR_ORIGIN_UPPER_LEFT, FXFALSE, &info)) {
3330 int short_per_row=info.strideInBytes/2;
3332 rptr = (ushort *)info.lfbPtr;
3334 // if doing interlaced mode, then go through every other scanline
3335 if ( Interlace_movies ) {
3336 static int start_at = 0;
3338 for ( i = start_at; i < (int)h; i += 2 ) {
3339 memcpy( &rptr[(dsty+i)*short_per_row+dstx], &src_data[bufw*i], w*sizeof(short) );
3341 //start_at = (start_at + 1) % 2;
3343 // Go through and read our pixels
3344 for (i=0;i<(int)h;i++) {
3345 memcpy( &rptr[(dsty+i)*short_per_row+dstx], &src_data[bufw*i], w*sizeof(short) );
3350 grLfbUnlock( GR_LFB_WRITE_ONLY, GR_BUFFER_BACKBUFFER );
3352 mprintf(( "Couldn't get a write lock to glide's back buffer!\n" ));
3362 #define FETCH_A(i, j) { \
3364 code |= ((i+min_x<x1) << 0); \
3365 code |= ((j+min_y<y1) << 1); \
3366 code |= ((i+min_x<x1+bmp1->w) << 2); \
3367 code |= ((j+min_y<y1+bmp1->h) << 3); \
3368 if(code && (code < 4)){ \
3369 pixel_a = sptr1[i - (x1 - min_x)]; \
3371 pixel_a = pixel_black; \
3374 #define FETCH_B(i, j) { \
3376 code |= ((i+min_x<x2) << 0); \
3377 code |= ((j+min_y<y2) << 1); \
3378 code |= ((i+min_x<x2+bmp2->w) << 2); \
3379 code |= ((j+min_y<y2+bmp2->h) << 3); \
3380 if(code && (code < 4)){ \
3381 pixel_b = sptr2[i - (x2 - min_x)]; \
3383 pixel_b = pixel_black; \
3386 #define MIX(pout, p1, p2) { pout = p1; }
3387 void gr_glide_cross_fade(int bmap1, int bmap2, int x1, int y1, int x2, int y2, float pct)
3390 gr_set_bitmap(bmap1);
3393 gr_set_bitmap(bmap2);
3397 int min_x = x1 < x2 ? x1 : x2;
3398 int min_y = y1 < y2 ? y1 : y2;
3399 int max_x = x2 > x1 ? x2 : x1;
3400 int max_y = y2 > y1 ? y2 : y1;
3405 bitmap *bmp1, *bmp2;
3406 ushort pixel_a, pixel_b;
3411 // stuff the black pixel
3412 r = 0; g = 0; b = 0; a = 255;
3414 bm_set_components(&pixel_black, &r, &g, &b, &a);
3416 // lock the first bitmap
3417 bmp1 = bm_lock( bmap1, 16, 0 );
3418 sptr1 = (ushort *)( bmp1->data );
3420 // lock the second bitmap
3421 bmp2 = bm_lock( bmap2, 16, 0 );
3422 sptr2 = (ushort *)( bmp2->data );
3438 if(bmp1->w > bmp2->w){
3443 if(bmp1->h > bmp2->h){
3451 // lock the framebuffer
3452 if ( grLfbLock( GR_LFB_WRITE_ONLY, GR_BUFFER_BACKBUFFER, GR_LFBWRITEMODE_1555, GR_ORIGIN_UPPER_LEFT, FXFALSE, &info) ) {
3454 // pointer into vram
3455 ushort *vram = (ushort *)info.lfbPtr;
3456 int stride = info.strideInBytes / sizeof(ushort);
3458 // for all scanlines
3459 for (i=0; i<max_h; i++ ){
3460 // this scanline in vram
3461 ushort *dptr = &vram[stride*(gr_screen.offset_y+i+min_y)+(gr_screen.offset_x+min_x)];
3463 // for this scanline
3464 for ( j=0; j<max_w; j++ ){
3465 // fetch the A and B pixels
3470 code |= ((i+min_x>=x1) << 0);
3471 code |= ((j+min_y>=y1) << 1);
3472 code |= ((i+min_x>x1+bmp1->w) << 2);
3473 code |= ((j+min_y>y1+bmp1->h) << 3);
3474 if(code && (code < 4)){
3475 pixel_a = sptr1[i - (x1 - min_x)];
3477 pixel_a = pixel_black;
3482 code |= ((i+min_x>=x2) << 0);
3483 code |= ((j+min_y>=y2) << 1);
3484 code |= ((i+min_x>x2+bmp2->w) << 2);
3485 code |= ((j+min_y>y2+bmp2->h) << 3);
3486 if(code && (code < 4)){
3487 pixel_b = sptr2[i - (x2 - min_x)];
3489 pixel_b = pixel_black;
3494 // mix them - for now just always pick pixel A
3495 MIX(pixel_out, pixel_a, pixel_b);
3500 // next pixel in vram
3504 // increment if we need to
3505 if((j+min_y >= y1) && (j+min_y < y1+bmp1->h)){
3508 // increment if we need to
3509 if((j+min_y >= y2) && (j+min_y < y2+bmp2->h)){
3514 grLfbUnlock(GR_LFB_WRITE_ONLY, GR_BUFFER_BACKBUFFER);
3522 GrHwConfiguration hwconfig;
3524 void gr_glide_init()
3535 // Turn off the 3Dfx splash screen
3536 SetEnvironmentVariable("FX_GLIDE_NO_SPLASH","1");
3538 // Turn off the 3Dfx gamma correction
3539 SetEnvironmentVariable("SST_RGAMMA","1.0");
3540 SetEnvironmentVariable("SST_GGAMMA","1.0");
3541 SetEnvironmentVariable("SST_BGAMMA","1.0");
3543 mprintf(( "Initializing glide graphics device...\n" ));
3546 if ( !vglide_init() ) {
3547 mprintf(( "Glide DLL not found!\n" ));
3553 // Find the extents of the window
3554 HWND hwnd = (HWND)os_get_window();
3556 // Prepare the window to go full screen
3558 mprintf(( "Window in debugging mode... mouse clicking may cause problems!\n" ));
3559 SetWindowLong( hwnd, GWL_EXSTYLE, WS_EX_TRANSPARENT );
3560 SetWindowLong( hwnd, GWL_STYLE, WS_POPUP );
3561 ShowWindow(hwnd, SW_SHOWNORMAL );
3563 SystemParametersInfo( SPI_GETWORKAREA, 0, &work_rect, 0 );
3564 SetWindowPos( hwnd, HWND_NOTOPMOST, work_rect.left, work_rect.top, gr_screen.max_w, gr_screen.max_h, 0 );
3565 SetActiveWindow(hwnd);
3566 SetForegroundWindow(hwnd);
3567 Glide_cursor_clip_rect.left = work_rect.left;
3568 Glide_cursor_clip_rect.top = work_rect.top;
3569 Glide_cursor_clip_rect.right = work_rect.left + gr_screen.max_w - 1;
3570 Glide_cursor_clip_rect.bottom = work_rect.top + gr_screen.max_h - 1;
3572 SetWindowLong( hwnd, GWL_EXSTYLE, 0 );
3573 SetWindowLong( hwnd, GWL_STYLE, WS_POPUP );
3574 ShowWindow(hwnd, SW_SHOWNORMAL );
3575 SetWindowPos( hwnd, HWND_TOPMOST, 0, 0, GetSystemMetrics( SM_CXSCREEN ), GetSystemMetrics( SM_CYSCREEN ), 0 );
3576 SetActiveWindow(hwnd);
3577 SetForegroundWindow(hwnd);
3578 Glide_cursor_clip_rect.left = 0;
3579 Glide_cursor_clip_rect.top = 0;
3580 Glide_cursor_clip_rect.right = gr_screen.max_w;
3581 Glide_cursor_clip_rect.bottom = gr_screen.max_h;
3584 // Let things catch up....
3589 gr_screen.bytes_per_pixel = 2;
3590 gr_screen.bits_per_pixel = 16;
3593 grGlideGetVersion(version);
3594 mprintf(( "Glide version: %s\n", version ));
3596 if ( !grSstQueryHardware( &hwconfig )) {
3597 mprintf(( "Glide: Query hardaware failed!\n" ));
3606 if(hwconfig.SSTs[0].sstBoard.Voodoo2Config.fbRam >= 12){
3610 // choose resolution
3611 if((gr_screen.max_w == 1024) && (gr_screen.max_h == 768)){
3612 res_mode = GR_RESOLUTION_1024x768;
3614 res_mode = GR_RESOLUTION_640x480;
3617 int retval = grSstWinOpen( (DWORD)hwnd, res_mode, GR_REFRESH_60Hz, GR_COLORFORMAT_ABGR, GR_ORIGIN_UPPER_LEFT, 2, 1 );
3619 mprintf(( "Glide: grSstOpen failed!\n" ));
3625 Bm_pixel_format = BM_PIXEL_FORMAT_ARGB;
3627 // grChromakeyMode( GR_CHROMAKEY_ENABLE );
3628 // grChromakeyValue( 0x00FF00 );
3632 // Setup the surface format
3635 Gr_red.scale = 256/32;
3636 Gr_red.mask = 0x7C00;
3638 Gr_current_red = &Gr_red;
3642 Gr_green.scale = 256/32;
3643 Gr_green.mask = 0x03e0;
3644 Gr_t_green = Gr_green;
3645 Gr_current_green = &Gr_green;
3649 Gr_blue.scale = 256/32;
3650 Gr_blue.mask = 0x1F;
3651 Gr_t_blue = Gr_blue;
3652 Gr_current_blue = &Gr_blue;
3654 Gr_current_alpha = &Gr_alpha;
3656 glide_tcache_init();
3658 gr_glide_clip_cursor(1);
3660 grGammaCorrectionValue(1.0f);
3662 gr_screen.gf_flip = gr_glide_flip;
3663 gr_screen.gf_flip_window = gr_glide_flip_window;
3664 gr_screen.gf_set_clip = gr_glide_set_clip;
3665 gr_screen.gf_reset_clip = gr_glide_reset_clip;
3666 gr_screen.gf_set_font = grx_set_font;
3667 gr_screen.gf_set_color = gr_glide_set_color;
3668 gr_screen.gf_set_bitmap = gr_glide_set_bitmap;
3669 gr_screen.gf_create_shader = gr_glide_create_shader;
3670 gr_screen.gf_set_shader = gr_glide_set_shader;
3671 gr_screen.gf_clear = gr_glide_clear;
3673 // gr_screen.gf_bitmap = gr_glide_bitmap;
3674 // gr_screen.gf_bitmap_ex = gr_glide_bitmap_ex;
3676 gr_screen.gf_rect = gr_glide_rect;
3677 gr_screen.gf_shade = gr_glide_shade;
3678 gr_screen.gf_string = gr_glide_string;
3679 gr_screen.gf_circle = gr_glide_circle;
3681 gr_screen.gf_line = gr_glide_line;
3682 gr_screen.gf_aaline = gr_glide_aaline;
3683 gr_screen.gf_pixel = gr_glide_pixel;
3684 gr_screen.gf_scaler = gr_glide_scaler;
3685 gr_screen.gf_aascaler = gr_glide_aascaler;
3686 gr_screen.gf_tmapper = gr_glide_tmapper;
3688 gr_screen.gf_gradient = gr_glide_gradient;
3690 gr_screen.gf_set_palette = gr_glide_set_palette;
3691 gr_screen.gf_get_color = gr_glide_get_color;
3692 gr_screen.gf_init_color = gr_glide_init_color;
3693 gr_screen.gf_init_alphacolor = gr_glide_init_alphacolor;
3694 gr_screen.gf_set_color_fast = gr_glide_set_color_fast;
3695 gr_screen.gf_print_screen = gr_glide_print_screen;
3697 gr_screen.gf_aabitmap = gr_glide_aabitmap;
3698 gr_screen.gf_aabitmap_ex = gr_glide_aabitmap_ex;
3700 gr_screen.gf_fade_in = gr_glide_fade_in;
3701 gr_screen.gf_fade_out = gr_glide_fade_out;
3702 gr_screen.gf_flash = gr_glide_flash;
3704 gr_screen.gf_zbuffer_get = gr_glide_zbuffer_get;
3705 gr_screen.gf_zbuffer_set = gr_glide_zbuffer_set;
3706 gr_screen.gf_zbuffer_clear = gr_glide_zbuffer_clear;
3708 gr_screen.gf_save_screen = gr_glide_save_screen;
3709 gr_screen.gf_restore_screen = gr_glide_restore_screen;
3710 gr_screen.gf_free_screen = gr_glide_free_screen;
3712 // Screen dumping stuff
3713 gr_screen.gf_dump_frame_start = gr_glide_dump_frame_start;
3714 gr_screen.gf_dump_frame_stop = gr_glide_dump_frame_stop;
3715 gr_screen.gf_dump_frame = gr_glide_dump_frame;
3717 gr_screen.gf_set_gamma = gr_glide_set_gamma;
3719 // Lock/unlock stuff
3720 gr_screen.gf_lock = gr_glide_lock;
3721 gr_screen.gf_unlock = gr_glide_unlock;
3724 gr_screen.gf_get_region = gr_glide_get_region;
3727 gr_screen.gf_fog_set = gr_glide_fog_set;
3730 gr_screen.gf_get_pixel = gr_glide_get_pixel;
3733 gr_screen.gf_set_cull = gr_glide_set_cull;
3736 gr_screen.gf_cross_fade = gr_glide_cross_fade;
3739 gr_screen.gf_filter_set = gr_glide_filter_set;
3741 // texture cache set
3742 gr_screen.gf_tcache_set = glide_tcache_set;
3745 gr_screen.gf_set_clear_color = gr_glide_set_clear_color;
3749 // default linear fog table
3750 guFogGenerateLinear(Glide_linear_fogtable, 1.0f, 1000.0f);