2 * Copyright (C) Volition, Inc. 1999. All rights reserved.
4 * All source code herein is the property of Volition, Inc. You may not sell
5 * or otherwise commercially exploit the source or things you created based on
10 * $Logfile: /Freespace2/code/Graphics/GrGlide.cpp $
15 * Code that uses 3DFX's Glide graphics library
18 * Revision 1.2 2002/06/09 04:41:17 relnev
19 * added copyright header
21 * Revision 1.1.1.1 2002/05/03 03:28:09 root
25 * 39 9/14/99 5:14a Dave
26 * Fixed credits drawing in Glide.
28 * 38 9/08/99 11:38p Dave
29 * Make V2 minimize/maximize the old way.
31 * 37 9/04/99 8:00p Dave
32 * Fixed up 1024 and 32 bit movie support.
34 * 36 9/01/99 10:49p Dave
35 * Added nice SquadWar checkbox to the client join wait screen.
37 * 35 8/30/99 5:01p Dave
38 * Made d3d do less state changing in the nebula. Use new chat server for
41 * 34 8/06/99 12:29a Dave
44 * 33 8/04/99 5:36p Dave
45 * Make glide and D3D switch out properly.
47 * 32 7/19/99 3:29p Dave
48 * Fixed gamma bitmap in the options screen.
50 * 31 7/14/99 9:42a Dave
51 * Put in clear_color debug function. Put in base for 3dnow stuff / P3
54 * 30 7/13/99 1:15p Dave
55 * 32 bit support. Whee!
57 * 29 6/29/99 10:35a Dave
58 * Interface polygon bitmaps! Whee!
60 * 28 5/05/99 9:02p Dave
61 * Fixed D3D aabitmap rendering. Spiffed up nebula effect a bit (added
62 * rotations, tweaked values, made bitmap selection more random). Fixed
63 * D3D beam weapon clipping problem. Added D3d frame dumping.
65 * 27 2/21/99 1:48p Dave
66 * Some code for monitoring datarate for multiplayer in detail.
68 * 26 2/11/99 3:08p Dave
69 * PXO refresh button. Very preliminary squad war support.
71 * 25 2/05/99 12:52p Dave
72 * Fixed Glide nondarkening textures.
74 * 24 2/04/99 6:29p Dave
75 * First full working rev of FS2 PXO support. Fixed Glide lighting
78 * 23 2/03/99 11:44a Dave
79 * Fixed d3d transparent textures.
81 * 22 1/30/99 1:29a Dave
82 * Fixed nebula thumbnail problem. Full support for 1024x768 choose pilot
83 * screen. Fixed beam weapon death messages.
85 * 21 1/24/99 11:37p Dave
86 * First full rev of beam weapons. Very customizable. Removed some bogus
87 * Int3()'s in low level net code.
89 * 20 1/23/99 5:33p Dave
90 * Put in support for 1024x768 Glide.
92 * 19 1/15/99 11:29a Neilk
93 * Fixed D3D screen/texture pixel formatting problem.
95 * 18 12/18/98 1:13a Dave
96 * Rough 1024x768 support for Direct3D. Proper detection and usage through
99 * 17 12/14/98 12:13p Dave
100 * Spiffed up xfer system a bit. Put in support for squad logo file xfer.
103 * 16 12/09/98 7:34p Dave
104 * Cleanup up nebula effect. Tweaked many values.
106 * 15 12/06/98 2:36p Dave
107 * Drastically improved nebula fogging.
109 * 14 12/04/98 10:20a Dave
110 * Fixed up gr_glide_get_pixel(...)
112 * 13 12/02/98 9:58a Dave
113 * Got fonttool working under Glide/Direct3d.
115 * 12 12/01/98 5:54p Dave
116 * Simplified the way pixel data is swizzled. Fixed tga bitmaps to work
117 * properly in D3D and Glide.
119 * 11 12/01/98 10:32a Johnson
120 * Fixed direct3d font problems. Fixed sun bitmap problem. Fixed direct3d
123 * 10 12/01/98 8:06a Dave
124 * Temporary checkin to fix some texture transparency problems in d3d.
126 * 9 11/30/98 1:07p Dave
127 * 16 bit conversion, first run.
129 * 8 11/24/98 4:43p Dave
130 * Make sure glide starts up in 640x480
132 * 7 11/20/98 11:16a Dave
133 * Fixed up IPX support a bit. Making sure that switching modes and
134 * loading/saving pilot files maintains proper state.
136 * 6 11/14/98 5:32p Dave
137 * Lots of nebula work. Put in ship contrails.
139 * 5 11/12/98 12:19a Dave
140 * Removed compiler warning.
142 * 4 11/11/98 5:37p Dave
143 * Checkin for multiplayer testing.
145 * 3 11/09/98 2:11p Dave
146 * Nebula optimizations.
148 * 2 10/07/98 10:52a Dave
151 * 1 10/07/98 10:49a Dave
153 * 116 9/14/98 1:59p Allender
154 * allow for interlaced movies
156 * 115 5/25/98 10:32a John
157 * Took out redundant code for font bitmap offsets that converted to a
158 * float, then later on converted back to an integer. Quite unnecessary.
160 * 114 5/22/98 9:09a John
161 * fixed type in previous
163 * 113 5/22/98 9:07a John
164 * added in code that fixed Rush Glide startup problemmo.
166 * 112 5/20/98 9:46p John
167 * added code so the places in code that change half the palette don't
168 * have to clear the screen.
170 * 111 5/17/98 5:03p John
171 * Fixed some bugs that make the taskbar interfere with the DEBUG-only
174 * 110 5/17/98 3:23p John
175 * Took out capibility check for additive blending. Made gr_bitmap_ex
176 * clip properly in glide and direct3d.
178 * 109 5/15/98 9:34p John
179 * Removed the initial ugly little cursor part that drew right at program
182 * 108 5/15/98 8:48a John
183 * Fixed bug where one-pixel line was getting left on right and bottom.
185 * 107 5/14/98 5:42p John
186 * Revamped the whole window position/mouse code for the graphics windows.
188 * 106 5/08/98 5:38p John
189 * Made Glide wait for retrace.
191 * 105 5/08/98 5:37p John
193 * 104 5/07/98 6:58p Hoffoss
194 * Made changes to mouse code to fix a number of problems.
196 * 103 5/07/98 8:43a John
197 * Turned off 3dfx gamma correction.
199 * 102 5/07/98 8:36a John
200 * Fixed Glide gradients
202 * 101 5/06/98 8:41p John
203 * Fixed some font clipping bugs. Moved texture handle set code for d3d
204 * into the texture module.
206 * 100 5/06/98 5:30p John
207 * Removed unused cfilearchiver. Removed/replaced some unused/little used
208 * graphics functions, namely gradient_h and _v and pixel_sp. Put in new
209 * DirectX header files and libs that fixed the Direct3D alpha blending
214 //#define USE_8BPP_TEXTURES
217 #include <windowsx.h>
219 #include "glideutl.h"
224 #include "floating.h"
226 #include "grinternal.h"
232 #include "systemvars.h"
233 #include "grglideinternal.h"
236 // #include "movie.h"
239 #define NEBULA_COLORS 20
241 GrFog_t Glide_linear_fogtable[GR_FOG_TABLE_SIZE];
243 int Glide_textures_in = 0;
245 int Glide_voodoo3 = 0;
247 static int Inited = 0;
249 // voodoo3 is a little sensitive to getting deactivated
250 #define VOODOO3_DEACTIVATED -1
251 #define VOODOO3_INACTIVE() ( (Glide_voodoo3 == 1) && (Glide_deactivate == VOODOO3_DEACTIVATED) )
253 float Gr_gamma_lookup_float[256];
255 volatile int Glide_running = 0;
256 volatile int Glide_activate = 0;
257 volatile int Glide_deactivate = 0;
259 typedef enum gr_texture_source {
261 TEXTURE_SOURCE_DECAL,
264 typedef enum gr_color_source {
266 COLOR_SOURCE_TEXTURE,
267 COLOR_SOURCE_VERTEX_TIMES_TEXTURE,
270 typedef enum gr_alpha_source {
272 ALPHA_SOURCE_VERTEX_NONDARKENING,
273 ALPHA_SOURCE_TEXTURE,
274 ALPHA_SOURCE_VERTEX_TIMES_TEXTURE,
277 typedef enum gr_alpha_blend {
278 ALPHA_BLEND_NONE, // 1*SrcPixel + 0*DestPixel
279 ALPHA_BLEND_ADDITIVE, // 1*SrcPixel + 1*DestPixel
280 ALPHA_BLEND_ALPHA_ADDITIVE, // Alpha*SrcPixel + 1*DestPixel
281 ALPHA_BLEND_ALPHA_BLEND_ALPHA, // Alpha*SrcPixel + (1-Alpha)*DestPixel
282 ALPHA_BLEND_ALPHA_BLEND_SRC_COLOR, // Alpha*SrcPixel + (1-SrcPixel)*DestPixel
285 typedef enum gr_zbuffer_type {
292 int Glide_last_state = -1;
294 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 )
296 int current_state = 0;
298 if(VOODOO3_INACTIVE()){
302 current_state = current_state | (ts<<0);
303 current_state = current_state | (cs<<5);
304 current_state = current_state | (as<<10);
305 current_state = current_state | (ab<<15);
306 current_state = current_state | (zt<<20);
308 if ( current_state == Glide_last_state ) {
311 Glide_last_state = current_state;
314 case TEXTURE_SOURCE_NONE:
315 grTexCombineFunction( GR_TMU0, GR_TEXTURECOMBINE_ONE );
317 case TEXTURE_SOURCE_DECAL:
318 grTexCombineFunction( GR_TMU0, GR_TEXTURECOMBINE_DECAL );
325 case COLOR_SOURCE_VERTEX:
326 grColorCombine( GR_COMBINE_FUNCTION_LOCAL, GR_COMBINE_FACTOR_NONE, GR_COMBINE_LOCAL_ITERATED, GR_COMBINE_OTHER_NONE, FXFALSE );
329 case COLOR_SOURCE_TEXTURE:
330 grColorCombine( GR_COMBINE_FUNCTION_SCALE_OTHER, GR_COMBINE_FACTOR_ONE, GR_COMBINE_LOCAL_NONE, GR_COMBINE_OTHER_TEXTURE, FXFALSE);
333 case COLOR_SOURCE_VERTEX_TIMES_TEXTURE:
334 grColorCombine( GR_COMBINE_FUNCTION_SCALE_OTHER, GR_COMBINE_FACTOR_LOCAL, GR_COMBINE_LOCAL_ITERATED, GR_COMBINE_OTHER_TEXTURE, FXFALSE);
342 case ALPHA_SOURCE_VERTEX:
343 grAlphaCombine( GR_COMBINE_FUNCTION_LOCAL, GR_COMBINE_FACTOR_NONE, GR_COMBINE_LOCAL_ITERATED, GR_COMBINE_OTHER_NONE, FXFALSE );
344 grAlphaControlsITRGBLighting(FXFALSE);
347 case ALPHA_SOURCE_VERTEX_NONDARKENING:
348 grAlphaCombine( GR_COMBINE_FUNCTION_LOCAL, GR_COMBINE_FACTOR_NONE, GR_COMBINE_LOCAL_ITERATED, GR_COMBINE_OTHER_NONE, FXFALSE );
349 grAlphaControlsITRGBLighting(FXTRUE);
350 grConstantColorValue(0xFFFFFFFF); // Non-darkening colors will use this
353 case ALPHA_SOURCE_TEXTURE:
354 grAlphaCombine( GR_COMBINE_FUNCTION_SCALE_OTHER, GR_COMBINE_FACTOR_ONE, GR_COMBINE_LOCAL_NONE, GR_COMBINE_OTHER_TEXTURE, FXFALSE);
355 grAlphaControlsITRGBLighting(FXFALSE);
358 case ALPHA_SOURCE_VERTEX_TIMES_TEXTURE:
359 grAlphaCombine( GR_COMBINE_FUNCTION_SCALE_OTHER, GR_COMBINE_FACTOR_LOCAL, GR_COMBINE_LOCAL_ITERATED, GR_COMBINE_OTHER_TEXTURE, FXFALSE );
360 grAlphaControlsITRGBLighting(FXFALSE);
369 case ALPHA_BLEND_NONE: // 1*SrcPixel + 0*DestPixel
370 grAlphaBlendFunction( GR_BLEND_ONE, GR_BLEND_ZERO, GR_BLEND_ZERO, GR_BLEND_ZERO );
373 case ALPHA_BLEND_ADDITIVE: // 1*SrcPixel + 1*DestPixel
374 grAlphaBlendFunction( GR_BLEND_ONE, GR_BLEND_ONE, GR_BLEND_ZERO, GR_BLEND_ZERO );
377 case ALPHA_BLEND_ALPHA_ADDITIVE: // Alpha*SrcPixel + 1*DestPixel
378 grAlphaBlendFunction( GR_BLEND_SRC_ALPHA, GR_BLEND_ONE, GR_BLEND_ZERO, GR_BLEND_ZERO);
381 case ALPHA_BLEND_ALPHA_BLEND_ALPHA: // Alpha*SrcPixel + (1-Alpha)*DestPixel
382 grAlphaBlendFunction( GR_BLEND_SRC_ALPHA, GR_BLEND_ONE_MINUS_SRC_ALPHA, GR_BLEND_ZERO, GR_BLEND_ZERO );
385 case ALPHA_BLEND_ALPHA_BLEND_SRC_COLOR: // Alpha*SrcPixel + (1-SrcPixel)*DestPixel
386 grAlphaBlendFunction( GR_BLEND_SRC_ALPHA, GR_BLEND_ONE_MINUS_SRC_COLOR, GR_BLEND_ZERO, GR_BLEND_ZERO );
395 case ZBUFFER_TYPE_NONE:
396 grDepthBufferMode(GR_DEPTHBUFFER_DISABLE);
397 grDepthMask( FXFALSE );
400 case ZBUFFER_TYPE_READ:
401 grDepthBufferMode(GR_DEPTHBUFFER_WBUFFER);
402 grDepthBufferFunction(GR_CMP_LEQUAL);
403 grDepthMask( FXFALSE );
406 case ZBUFFER_TYPE_WRITE:
407 grDepthBufferMode(GR_DEPTHBUFFER_WBUFFER);
408 grDepthBufferFunction(GR_CMP_ALWAYS);
409 grDepthMask( FXTRUE );
412 case ZBUFFER_TYPE_FULL:
413 grDepthBufferMode(GR_DEPTHBUFFER_WBUFFER);
414 grDepthBufferFunction(GR_CMP_LEQUAL);
415 grDepthMask( FXTRUE );
426 TEXTURE_SOURCE_NONE, TEXTURE_SOURCE_DECAL,
428 COLOR_SOURCE_VERTEX, COLOR_SOURCE_TEXTURE, COLOR_SOURCE_VERTEX_TIMES_TEXTURE,
430 ALPHA_SOURCE_VERTEX, ALPHA_SOURCE_TEXTURE, ALPHA_SOURCE_VERTEX_TIMES_TEXTURE,
432 ALPHA_BLEND_NONE, ALPHA_BLEND_ADDITIVE, ALPHA_BLEND_ALPHA_ADDITIVE, ALPHA_BLEND_ALPHA_BLEND_ALPHA, ALPHA_BLEND_ALPHA_BLEND_SRC_COLOR,
434 ZBUFFER_TYPE_NONE, ZBUFFER_TYPE_READ, ZBUFFER_TYPE_WRITE, ZBUFFER_TYPE_FULL,
441 // If mode is FALSE, turn zbuffer off the entire frame,
442 // no matter what people pass to gr_zbuffer_set.
443 void gr_glide_zbuffer_clear(int mode)
445 if(VOODOO3_INACTIVE()){
451 gr_zbuffering_mode = GR_ZBUFF_FULL;
452 gr_global_zbuffering = 1;
454 // Make sure zbuffering is on
455 gr_glide_set_state( TEXTURE_SOURCE_NONE, COLOR_SOURCE_VERTEX, ALPHA_SOURCE_VERTEX, ALPHA_BLEND_NONE, ZBUFFER_TYPE_FULL );
457 // Disable writes to color and alpha buffers
458 grColorMask( FXFALSE, FXFALSE );
460 grBufferClear( 0x0, 0, GR_WDEPTHVALUE_FARTHEST );
461 // Re-enable writes to the color buffer
462 grColorMask( FXTRUE, FXFALSE );
465 gr_zbuffering_mode = GR_ZBUFF_NONE;
466 gr_global_zbuffering = 0;
470 int gr_glide_zbuffer_get()
472 if ( !gr_global_zbuffering ) {
473 return GR_ZBUFF_NONE;
475 return gr_zbuffering_mode;
478 int gr_glide_zbuffer_set(int mode)
480 if ( !gr_global_zbuffering ) {
482 return GR_ZBUFF_NONE;
485 int tmp = gr_zbuffering_mode;
487 gr_zbuffering_mode = mode;
489 if ( gr_zbuffering_mode == GR_ZBUFF_NONE ) {
498 void gr_glide_pixel(int x, int y)
500 if(VOODOO3_INACTIVE()){
506 if ( x < gr_screen.clip_left ) return;
507 if ( x > gr_screen.clip_right ) return;
508 if ( y < gr_screen.clip_top ) return;
509 if ( y > gr_screen.clip_bottom ) return;
511 // Set up Render State - flat shading - alpha blending
512 gr_glide_set_state( TEXTURE_SOURCE_NONE, COLOR_SOURCE_VERTEX, ALPHA_SOURCE_VERTEX, ALPHA_BLEND_ALPHA_BLEND_ALPHA, ZBUFFER_TYPE_NONE );
515 p.x = 0.5f + i2fl(x + gr_screen.offset_x);
516 p.y = 0.5f + i2fl(y + gr_screen.offset_y);
518 p.r = i2fl(gr_screen.current_color.red);
519 p.g = i2fl(gr_screen.current_color.green);
520 p.b = i2fl(gr_screen.current_color.blue);
528 int xi = fl2i(x*16.0f);
529 return i2fl(xi)/16.0f;
532 void gr_glide_clear()
534 GrColor_t clear_color;
536 if(VOODOO3_INACTIVE()){
540 // Turn off zbuffering so this doesn't clear the zbuffer
541 gr_glide_set_state( TEXTURE_SOURCE_NONE, COLOR_SOURCE_VERTEX, ALPHA_SOURCE_VERTEX, ALPHA_BLEND_NONE, ZBUFFER_TYPE_NONE );
545 clear_color |= ((ubyte)gr_screen.current_clear_color.red);
546 clear_color |= ((ubyte)gr_screen.current_clear_color.green << 8);
547 clear_color |= ((ubyte)gr_screen.current_clear_color.blue << 16);
548 grBufferClear( clear_color, 0, GR_WDEPTHVALUE_FARTHEST );
551 static RECT Glide_cursor_clip_rect;
553 void gr_glide_clip_cursor(int active)
556 ClipCursor(&Glide_cursor_clip_rect);
563 int Gr_glide_mouse_saved = 0;
564 int Gr_glide_mouse_saved_x1 = 0;
565 int Gr_glide_mouse_saved_y1 = 0;
566 int Gr_glide_mouse_saved_x2 = 0;
567 int Gr_glide_mouse_saved_y2 = 0;
568 int Gr_glide_mouse_saved_w = 0;
569 int Gr_glide_mouse_saved_h = 0;
570 #define MAX_SAVE_SIZE (32*32)
571 ushort Gr_glide_mouse_saved_data[MAX_SAVE_SIZE];
573 // Clamps X between R1 and R2
574 #define CLAMP(x,r1,r2) do { if ( (x) < (r1) ) (x) = (r1); else if ((x) > (r2)) (x) = (r2); } while(0)
576 void gr_glide_save_mouse_area(int x, int y, int w, int h )
578 if(VOODOO3_INACTIVE()){
582 Gr_glide_mouse_saved_x1 = x;
583 Gr_glide_mouse_saved_y1 = y;
584 Gr_glide_mouse_saved_x2 = x+w-1;
585 Gr_glide_mouse_saved_y2 = y+h-1;
587 CLAMP(Gr_glide_mouse_saved_x1, gr_screen.clip_left, gr_screen.clip_right );
588 CLAMP(Gr_glide_mouse_saved_x2, gr_screen.clip_left, gr_screen.clip_right );
589 CLAMP(Gr_glide_mouse_saved_y1, gr_screen.clip_top, gr_screen.clip_bottom );
590 CLAMP(Gr_glide_mouse_saved_y2, gr_screen.clip_top, gr_screen.clip_bottom );
592 Gr_glide_mouse_saved_w = Gr_glide_mouse_saved_x2 - Gr_glide_mouse_saved_x1 + 1;
593 Gr_glide_mouse_saved_h = Gr_glide_mouse_saved_y2 - Gr_glide_mouse_saved_y1 + 1;
595 if ( Gr_glide_mouse_saved_w < 1 ) return;
596 if ( Gr_glide_mouse_saved_h < 1 ) return;
598 // Make sure we're not saving too much!
599 Assert( (Gr_glide_mouse_saved_w*Gr_glide_mouse_saved_h) <= MAX_SAVE_SIZE );
603 info.size=sizeof(GrLfbInfo_t);
605 // get a read pointer
606 if ( grLfbLock( GR_LFB_READ_ONLY, GR_BUFFER_BACKBUFFER, GR_LFBWRITEMODE_565,
607 GR_ORIGIN_UPPER_LEFT, FXFALSE, &info)) {
610 int short_per_row=info.strideInBytes/2;
612 rptr = (ushort *)info.lfbPtr;
616 dptr = Gr_glide_mouse_saved_data;
618 for (int i=0; i<Gr_glide_mouse_saved_h; i++ ) {
619 sptr = &rptr[(Gr_glide_mouse_saved_y1+i)*short_per_row+Gr_glide_mouse_saved_x1];
621 for(int j=0; j<Gr_glide_mouse_saved_w; j++ ) {
628 grLfbUnlock( GR_LFB_READ_ONLY, GR_BUFFER_BACKBUFFER );
630 Gr_glide_mouse_saved = 1;
633 mprintf(( "Couldn't get read-only lock to backbuffer for glide mouse save\n" ));
638 // lock the backbuffer and return a pointer
643 if(VOODOO3_INACTIVE()){
647 info.size=sizeof(GrLfbInfo_t);
648 if(grLfbLock(GR_LFB_READ_ONLY, GR_BUFFER_BACKBUFFER, GR_LFBWRITEMODE_1555, GR_ORIGIN_UPPER_LEFT, FXFALSE, &info)){
649 return (uint)info.lfbPtr;
656 // unlock the backbuffer
657 void gr_glide_unlock()
659 if(VOODOO3_INACTIVE()){
664 grLfbUnlock( GR_LFB_READ_ONLY, GR_BUFFER_BACKBUFFER );
667 static int gr_palette_faded_out = 0;
673 if(VOODOO3_INACTIVE()){
679 cnt = Glide_activate;
681 Glide_activate -= cnt;
683 gr_glide_clip_cursor(1);
684 grSstControl(GR_CONTROL_ACTIVATE);
687 cnt = Glide_deactivate;
689 Glide_deactivate -= cnt;
691 gr_glide_clip_cursor(0);
692 grSstControl(GR_CONTROL_DEACTIVATE);
698 if ( gr_palette_faded_out ) {
704 Gr_glide_mouse_saved = 0; // assume not saved
707 if ( mouse_is_visible() ) {
709 mouse_get_pos( &mx, &my );
710 gr_glide_save_mouse_area(mx,my,32,32);
711 if ( Gr_cursor == -1 ) {
712 gr_set_color(255,255,255);
713 gr_line( mx, my, mx+7, my + 7 );
714 gr_line( mx, my, mx+5, my );
715 gr_line( mx, my, mx, my+5 );
717 gr_set_bitmap(Gr_cursor);
723 if(Interface_framerate){
724 if(Interface_last_tick > 0){
725 int diff = timer_get_milliseconds() - Interface_last_tick;
726 gr_printf(10, 10, "%f", 1000.0f / (float)diff);
728 Interface_last_tick = timer_get_milliseconds();
739 glide_tcache_frame();
742 void gr_glide_flip_window(uint _hdc, int x, int y, int w, int h )
746 void gr_glide_set_clip(int x,int y,int w,int h)
748 gr_screen.offset_x = x;
749 gr_screen.offset_y = y;
751 gr_screen.clip_left = 0;
752 gr_screen.clip_right = w-1;
754 gr_screen.clip_top = 0;
755 gr_screen.clip_bottom = h-1;
757 if(VOODOO3_INACTIVE()){
761 // check for sanity of parameters
762 if ( gr_screen.clip_left+x < 0 ) {
763 gr_screen.clip_left = -x;
764 } else if ( gr_screen.clip_left+x > gr_screen.max_w-1 ) {
765 gr_screen.clip_left = gr_screen.max_w-1-x;
767 if ( gr_screen.clip_right+x < 0 ) {
768 gr_screen.clip_right = -x;
769 } else if ( gr_screen.clip_right+x >= gr_screen.max_w-1 ) {
770 gr_screen.clip_right = gr_screen.max_w-1-x;
773 if ( gr_screen.clip_top+y < 0 ) {
774 gr_screen.clip_top = -y;
775 } else if ( gr_screen.clip_top+y > gr_screen.max_h-1 ) {
776 gr_screen.clip_top = gr_screen.max_h-1-y;
779 if ( gr_screen.clip_bottom+y < 0 ) {
780 gr_screen.clip_bottom = -y;
781 } else if ( gr_screen.clip_bottom+y > gr_screen.max_h-1 ) {
782 gr_screen.clip_bottom = gr_screen.max_h-1-y;
785 gr_screen.clip_width = gr_screen.clip_right - gr_screen.clip_left + 1;
786 gr_screen.clip_height = gr_screen.clip_bottom - gr_screen.clip_top + 1;
788 grClipWindow( gr_screen.clip_left+x, gr_screen.clip_top+y, gr_screen.clip_right+1+x, gr_screen.clip_bottom+1+y );
791 void gr_glide_reset_clip()
793 if(VOODOO3_INACTIVE()){
797 gr_screen.offset_x = 0;
798 gr_screen.offset_y = 0;
799 gr_screen.clip_left = 0;
800 gr_screen.clip_top = 0;
801 gr_screen.clip_right = gr_screen.max_w - 1;
802 gr_screen.clip_bottom = gr_screen.max_h - 1;
803 gr_screen.clip_width = gr_screen.max_w;
804 gr_screen.clip_height = gr_screen.max_h;
806 grClipWindow( gr_screen.clip_left, gr_screen.clip_top, gr_screen.clip_right+1, gr_screen.clip_bottom+1 );
810 void gr_glide_set_bitmap( int bitmap_num, int alphablend_mode, int bitblt_mode, float alpha, int sx, int sy )
812 if(VOODOO3_INACTIVE()){
816 gr_screen.current_alpha = alpha;
817 gr_screen.current_alphablend_mode = alphablend_mode;
818 gr_screen.current_bitblt_mode = bitblt_mode;
819 gr_screen.current_bitmap = bitmap_num;
821 gr_screen.current_bitmap_sx = sx;
822 gr_screen.current_bitmap_sy = sy;
825 void gr_glide_create_shader(shader * shade, float r, float g, float b, float c )
827 shade->screen_sig = gr_screen.signature;
835 void gr_glide_set_shader( shader * shade )
838 if (shade->screen_sig != gr_screen.signature) {
839 gr_create_shader( shade, shade->r, shade->g, shade->b, shade->c );
841 gr_screen.current_shader = *shade;
843 gr_create_shader( &gr_screen.current_shader, 0.0f, 0.0f, 0.0f, 0.0f );
847 void gr_glide_bitmap_ex_internal(int x,int y,int w,int h,int sx,int sy)
853 if(VOODOO3_INACTIVE()){
857 bmp = bm_lock( gr_screen.current_bitmap, 16, 0 );
858 sptr = (ushort *)( bmp->data + (sy*bmp->w*2) + (sx*2) );
860 if ( x < gr_screen.clip_left ) return;
861 if ( x > gr_screen.clip_right ) return;
862 if ( y < gr_screen.clip_top ) return;
863 if ( y > gr_screen.clip_bottom ) return;
865 gr_glide_set_state( TEXTURE_SOURCE_NONE, COLOR_SOURCE_VERTEX, ALPHA_SOURCE_VERTEX, ALPHA_BLEND_ALPHA_BLEND_ALPHA, ZBUFFER_TYPE_NONE );
869 if ( grLfbLock( GR_LFB_WRITE_ONLY, GR_BUFFER_BACKBUFFER, GR_LFBWRITEMODE_1555, GR_ORIGIN_UPPER_LEFT, FXFALSE, &info) ) {
871 ushort *vram = (ushort *)info.lfbPtr;
872 int stride = info.strideInBytes / sizeof(ushort);
874 for (i=0; i<h; i++ ) {
876 ushort *dptr = &vram[stride*(gr_screen.offset_y+i+y)+(gr_screen.offset_x+x)];
878 for ( j=0; j<w; j++ ) {
879 if(sptr[j] & 0x8000){
888 grLfbUnlock(GR_LFB_WRITE_ONLY, GR_BUFFER_BACKBUFFER);
891 bm_unlock(gr_screen.current_bitmap);
895 void gr_glide_bitmap_ex(int x,int y,int w,int h,int sx,int sy)
902 int dx1=x, dx2=x+w-1;
903 int dy1=y, dy2=y+h-1;
906 bm_get_info( gr_screen.current_bitmap, &bw, &bh, NULL );
911 if ( count > 1 ) Int3();
915 if ((dx1 > gr_screen.clip_right ) || (dx2 < gr_screen.clip_left)) return;
916 if ((dy1 > gr_screen.clip_bottom ) || (dy2 < gr_screen.clip_top)) return;
917 if ( dx1 < gr_screen.clip_left ) { sx += gr_screen.clip_left-dx1; dx1 = gr_screen.clip_left; }
918 if ( dy1 < gr_screen.clip_top ) { sy += gr_screen.clip_top-dy1; dy1 = gr_screen.clip_top; }
919 if ( dx2 > gr_screen.clip_right ) { dx2 = gr_screen.clip_right; }
920 if ( dy2 > gr_screen.clip_bottom ) { dy2 = gr_screen.clip_bottom; }
947 if ( w < 1 ) return; // clipped away!
948 if ( h < 1 ) return; // clipped away!
952 // Make sure clipping algorithm works
956 Assert( w == (dx2-dx1+1) );
957 Assert( h == (dy2-dy1+1) );
960 Assert( sx+w <= bw );
961 Assert( sy+h <= bh );
962 Assert( dx2 >= dx1 );
963 Assert( dy2 >= dy1 );
964 Assert( (dx1 >= gr_screen.clip_left ) && (dx1 <= gr_screen.clip_right) );
965 Assert( (dx2 >= gr_screen.clip_left ) && (dx2 <= gr_screen.clip_right) );
966 Assert( (dy1 >= gr_screen.clip_top ) && (dy1 <= gr_screen.clip_bottom) );
967 Assert( (dy2 >= gr_screen.clip_top ) && (dy2 <= gr_screen.clip_bottom) );
970 // We now have dx1,dy1 and dx2,dy2 and sx, sy all set validly within clip regions.
971 // Draw bitmap bm[sx,sy] into (dx1,dy1)-(dx2,dy2)
973 gr_glide_bitmap_ex_internal(dx1,dy1,dx2-dx1+1,dy2-dy1+1,sx,sy);
977 void gr_glide_bitmap(int x, int y)
981 bm_get_info( gr_screen.current_bitmap, &w, &h, NULL );
982 int dx1=x, dx2=x+w-1;
983 int dy1=y, dy2=y+h-1;
986 if ((dx1 > gr_screen.clip_right ) || (dx2 < gr_screen.clip_left)) return;
987 if ((dy1 > gr_screen.clip_bottom ) || (dy2 < gr_screen.clip_top)) return;
988 if ( dx1 < gr_screen.clip_left ) { sx = gr_screen.clip_left-dx1; dx1 = gr_screen.clip_left; }
989 if ( dy1 < gr_screen.clip_top ) { sy = gr_screen.clip_top-dy1; dy1 = gr_screen.clip_top; }
990 if ( dx2 > gr_screen.clip_right ) { dx2 = gr_screen.clip_right; }
991 if ( dy2 > gr_screen.clip_bottom ) { dy2 = gr_screen.clip_bottom; }
993 if ( sx < 0 ) return;
994 if ( sy < 0 ) return;
995 if ( sx >= w ) return;
996 if ( sy >= h ) return;
998 // Draw bitmap bm[sx,sy] into (dx1,dy1)-(dx2,dy2)
1000 gr_glide_bitmap_ex_internal(dx1,dy1,dx2-dx1+1,dy2-dy1+1,sx,sy);
1004 static void glide_scanline( int x1, int x2, int y )
1008 if(VOODOO3_INACTIVE()){
1018 if ( y < gr_screen.clip_top ) return;
1019 if ( y > gr_screen.clip_bottom ) return;
1021 if ( x1 < gr_screen.clip_left ) x1 = gr_screen.clip_left;
1022 if ( x2 > gr_screen.clip_right ) x2 = gr_screen.clip_right;
1026 if ( w < 1 ) return;
1028 // for (i=0; i<w; i++)
1029 // gr_pixel(x1+i,y);
1032 // Set up Render State - flat shading - alpha blending
1033 gr_glide_set_state( TEXTURE_SOURCE_NONE, COLOR_SOURCE_VERTEX, ALPHA_SOURCE_VERTEX, ALPHA_BLEND_ALPHA_BLEND_ALPHA, ZBUFFER_TYPE_NONE );
1037 a.x = i2fl(x1 + gr_screen.offset_x);
1038 a.y = i2fl(y + gr_screen.offset_y);
1039 a.r = i2fl(gr_screen.current_color.red);
1040 a.g = i2fl(gr_screen.current_color.green);
1041 a.b = i2fl(gr_screen.current_color.blue);
1042 a.a = i2fl(gr_screen.current_color.alpha);
1044 b.x = i2fl(x2 + gr_screen.offset_x);
1045 b.y = i2fl(y + gr_screen.offset_y);
1046 b.r = i2fl(gr_screen.current_color.red);
1047 b.g = i2fl(gr_screen.current_color.green);
1048 b.b = i2fl(gr_screen.current_color.blue);
1049 b.a = i2fl(gr_screen.current_color.alpha);
1071 void gr_glide_rect(int x,int y,int w,int h)
1105 for (int i=0; i<h; i++ )
1106 glide_scanline( x1, x2, y1+i );
1110 static void glide_shade_scanline( int x1, int x2, int y, int r, int g, int b, int a )
1114 if(VOODOO3_INACTIVE()){
1124 if ( y < gr_screen.clip_top ) return;
1125 if ( y > gr_screen.clip_bottom ) return;
1127 if ( x1 < gr_screen.clip_left ) x1 = gr_screen.clip_left;
1128 if ( x2 > gr_screen.clip_right ) x2 = gr_screen.clip_right;
1132 if ( w < 1 ) return;
1135 // Set up Render State - flat shading - alpha blending
1136 gr_glide_set_state( TEXTURE_SOURCE_NONE, COLOR_SOURCE_VERTEX, ALPHA_SOURCE_VERTEX, ALPHA_BLEND_ALPHA_BLEND_ALPHA, ZBUFFER_TYPE_NONE );
1140 v1.x = i2fl(x1 + gr_screen.offset_x);
1141 v1.y = i2fl(y + gr_screen.offset_y);
1147 v2.x = i2fl(x2 + gr_screen.offset_x);
1148 v2.y = i2fl(y + gr_screen.offset_y);
1170 grDrawLine(&v1, &v2);
1174 float shade1 = 1.0f;
1175 float shade2 = 6.0f;
1177 DCF(shade1,"Set shade1")
1180 dc_get_arg(ARG_FLOAT|ARG_NONE);
1181 if ( Dc_arg_type & ARG_FLOAT ) {
1182 shade1 = Dc_arg_float;
1187 DCF(shade2,"Set shade2")
1190 dc_get_arg(ARG_FLOAT|ARG_NONE);
1191 if ( Dc_arg_type & ARG_FLOAT ) {
1192 shade2 = Dc_arg_float;
1198 void gr_glide_shade(int x,int y,int w,int h)
1233 r = fl2i(gr_screen.current_shader.r*255.0f*shade1);
1234 if ( r < 0 ) r = 0; else if ( r > 255 ) r = 255;
1235 g = fl2i(gr_screen.current_shader.g*255.0f*shade1);
1236 if ( g < 0 ) g = 0; else if ( g > 255 ) g = 255;
1237 b = fl2i(gr_screen.current_shader.b*255.0f*shade1);
1238 if ( b < 0 ) b = 0; else if ( b > 255 ) b = 255;
1239 a = fl2i(gr_screen.current_shader.c*255.0f*shade2);
1240 if ( a < 0 ) a = 0; else if ( a > 255 ) a = 255;
1242 for (int i=0; i<h; i++ ) {
1243 glide_shade_scanline( x1, x2, y1+i, r, g, b, a );
1248 void gr_glide_aabitmap_ex_new(int x,int y,int w,int h,int sx,int sy);
1250 void gr_glide_char(int x,int y,int letter)
1254 ch = &Current_font->char_data[letter];
1256 int sx = Current_font->bm_u[letter];
1257 int sy = Current_font->bm_v[letter];
1259 gr_glide_aabitmap_ex_new( x, y, ch->byte_width, Current_font->h, sx, sy );
1261 // mprintf(( "String = %s\n", text ));
1265 void gr_glide_string( int sx, int sy, char *s )
1267 int width, spacing, letter;
1270 if ( !Current_font ) {
1274 gr_set_bitmap(Current_font->bitmap_id);
1279 if (sx==0x8000) { //centered
1280 x = get_centered_x(s);
1291 while (*s== '\n' ) {
1293 y += Current_font->h;
1294 if (sx==0x8000) { //centered
1295 x = get_centered_x(s);
1300 if (*s == 0 ) break;
1302 letter = get_char_width(s[0],s[1],&width,&spacing);
1305 if (letter<0) { //not in font, draw as space
1309 gr_glide_char( x, y, letter );
1313 void gr_glide_circle( int xc, int yc, int d )
1324 if ( (xc+r) < gr_screen.clip_left ) return;
1325 if ( (xc-r) > gr_screen.clip_right ) return;
1326 if ( (yc+r) < gr_screen.clip_top ) return;
1327 if ( (yc-r) > gr_screen.clip_bottom ) return;
1330 // Draw the first octant
1331 glide_scanline( xc-y, xc+y, yc-x );
1332 glide_scanline( xc-y, xc+y, yc+x );
1337 // Draw the second octant
1338 glide_scanline( xc-x, xc+x, yc-y );
1339 glide_scanline( xc-x, xc+x, yc+y );
1346 glide_scanline( xc-x, xc+x, yc-y );
1347 glide_scanline( xc-x, xc+x, yc+y );
1352 void gr_glide_line(int x1,int y1,int x2,int y2)
1354 int clipped = 0, swapped=0;
1356 if(VOODOO3_INACTIVE()){
1360 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);
1362 // Set up Render State - flat shading - alpha blending
1363 gr_glide_set_state( TEXTURE_SOURCE_NONE, COLOR_SOURCE_VERTEX, ALPHA_SOURCE_VERTEX, ALPHA_BLEND_ALPHA_BLEND_ALPHA, ZBUFFER_TYPE_NONE );
1367 a.x = i2fl(x1 + gr_screen.offset_x);
1368 a.y = i2fl(y1 + gr_screen.offset_y);
1369 a.r = i2fl(gr_screen.current_color.red);
1370 a.g = i2fl(gr_screen.current_color.green);
1371 a.b = i2fl(gr_screen.current_color.blue);
1372 a.a = i2fl(gr_screen.current_color.alpha);
1374 b.x = i2fl(x2 + gr_screen.offset_x);
1375 b.y = i2fl(y2 + gr_screen.offset_y);
1376 b.r = i2fl(gr_screen.current_color.red);
1377 b.g = i2fl(gr_screen.current_color.green);
1378 b.b = i2fl(gr_screen.current_color.blue);
1379 b.a = i2fl(gr_screen.current_color.alpha);
1401 void gr_glide_aaline( vertex *v1, vertex *v2 )
1403 float x1, y1, x2, y2;
1404 int clipped = 0, swapped = 0;
1405 float a1, b1, a2, b2;
1407 if(VOODOO3_INACTIVE()){
1417 a1 = (float)gr_screen.clip_left;
1418 b1 = (float)gr_screen.clip_top;
1419 a2 = (float)gr_screen.clip_right;
1420 b2 = (float)gr_screen.clip_bottom;
1422 FL_CLIPLINE(x1,y1,x2,y2,a1,b1,a2,b2,return,clipped=1,swapped=1);
1424 gr_glide_set_state( TEXTURE_SOURCE_NONE, COLOR_SOURCE_VERTEX, ALPHA_SOURCE_VERTEX, ALPHA_BLEND_ALPHA_BLEND_ALPHA, ZBUFFER_TYPE_NONE );
1428 a.x = i2fl(fl2i(x1)) + gr_screen.offset_x;
1429 a.y = i2fl(fl2i(y1)) + gr_screen.offset_y;
1430 a.r = i2fl(gr_screen.current_color.red);
1431 a.g = i2fl(gr_screen.current_color.green);
1432 a.b = i2fl(gr_screen.current_color.blue);
1433 a.a = i2fl(gr_screen.current_color.alpha);
1435 b.x = i2fl(fl2i(x2)) + gr_screen.offset_x;
1436 b.y = i2fl(fl2i(y2)) + gr_screen.offset_y;
1437 b.r = i2fl(gr_screen.current_color.red);
1438 b.g = i2fl(gr_screen.current_color.green);
1439 b.b = i2fl(gr_screen.current_color.blue);
1440 b.a = i2fl(gr_screen.current_color.alpha);
1458 grAADrawLine(&a, &b);
1461 void gr_glide_tmapper_internal( int nv, vertex * verts[], uint flags, int is_scaler )
1463 GrVertex GrVerts[25];
1465 float Glide_u_ratio = 0.0f;
1466 float Glide_v_ratio = 0.0f;
1468 if(VOODOO3_INACTIVE()){
1472 // Make nebula use the texture mapper... this blends the colors better.
1473 if ( flags & TMAP_FLAG_NEBULA ) {
1476 flags |= TMAP_FLAG_TEXTURED;
1478 static int test_bmp = -1;
1479 static ushort data[16];
1480 if ( test_bmp == -1 ){
1485 // stuff the fake bitmap
1486 a = 1; r = 255; g = 255; b = 255;
1488 bm_set_components((ubyte*)&pix, &r, &g, &b, &a);
1489 for(idx=0; idx<16; idx++){
1492 test_bmp = bm_create( 16, 4, 4, data );
1494 gr_set_bitmap( test_bmp );
1496 for (i=0; i<nv; i++ ) {
1497 verts[i]->u = verts[i]->v = 0.5f;
1502 gr_texture_source texture_source = (gr_texture_source)-1;
1503 gr_color_source color_source = (gr_color_source)-1;
1504 gr_alpha_source alpha_source = (gr_alpha_source)-1;
1505 gr_alpha_blend alpha_blend = (gr_alpha_blend)-1;
1506 gr_zbuffer_type zbuffer_type = (gr_zbuffer_type)-1;
1508 if ( gr_zbuffering ) {
1509 if ( is_scaler || (gr_screen.current_alphablend_mode == GR_ALPHABLEND_FILTER) ) {
1510 zbuffer_type = ZBUFFER_TYPE_READ;
1512 zbuffer_type = ZBUFFER_TYPE_FULL;
1515 zbuffer_type = ZBUFFER_TYPE_NONE;
1520 alpha_source = ALPHA_SOURCE_VERTEX;
1522 switch(gr_screen.current_alphablend_mode){
1523 case GR_ALPHABLEND_FILTER:
1524 // Blend with screen pixel using src*alpha+dst
1525 if ( gr_screen.current_alpha > 1.0f ) {
1526 alpha_blend = ALPHA_BLEND_ALPHA_BLEND_SRC_COLOR;
1529 alpha_blend = ALPHA_BLEND_ALPHA_ADDITIVE;
1530 alpha = gr_screen.current_alpha*255.0f;
1535 alpha_blend = ALPHA_BLEND_ALPHA_BLEND_ALPHA;
1540 if ( flags & TMAP_FLAG_TEXTURED ) {
1541 int texture_type = TCACHE_TYPE_NORMAL;
1543 if ( flags & TMAP_FLAG_NONDARKENING ) {
1544 alpha_source = ALPHA_SOURCE_VERTEX_NONDARKENING;
1545 //alpha_source = ALPHA_SOURCE_VERTEX_TIMES_TEXTURE;
1546 texture_type = TCACHE_TYPE_NONDARKENING;
1548 alpha_source = ALPHA_SOURCE_VERTEX_TIMES_TEXTURE;
1549 texture_type = TCACHE_TYPE_XPARENT;
1553 color_source = COLOR_SOURCE_VERTEX_TIMES_TEXTURE;
1554 texture_source = TEXTURE_SOURCE_DECAL;
1556 // force texture type
1557 if(flags & TMAP_FLAG_BITMAP_SECTION){
1558 texture_type = TCACHE_TYPE_BITMAP_SECTION;
1561 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 )) {
1562 // Error setting texture!
1563 mprintf(( "GLIDE: Error setting texture!\n" ));
1564 // Mark as no texturing
1565 color_source = COLOR_SOURCE_VERTEX;
1566 texture_source = TEXTURE_SOURCE_NONE;
1569 color_source = COLOR_SOURCE_VERTEX;
1570 texture_source = TEXTURE_SOURCE_NONE;
1571 if(flags & TMAP_FLAG_ALPHA){
1572 alpha_source = ALPHA_SOURCE_VERTEX;
1576 // zbuffer_type = ZBUFFER_TYPE_NONE;
1577 // alpha_source = ALPHA_SOURCE_VERTEX;
1578 // alpha_blend = ALPHA_BLEND_NONE;
1580 // color_source = COLOR_SOURCE_VERTEX;
1581 // texture_source = TEXTURE_SOURCE_NONE;
1582 gr_glide_set_state( texture_source, color_source, alpha_source, alpha_blend, zbuffer_type );
1585 x1 = gr_screen.clip_left*16;
1586 x2 = gr_screen.clip_right*16+15;
1587 y1 = gr_screen.clip_top*16;
1588 y2 = gr_screen.clip_bottom*16+15;
1590 // memset( GrVerts, 0, sizeof(GrVertex) * 25 );
1592 for (i=0; i<nv; i++ ) {
1593 if ( flags & TMAP_FLAG_ALPHA ) {
1594 GrVerts[i].a = i2fl(verts[i]->a);
1596 GrVerts[i].a = alpha;
1599 if ( flags & TMAP_FLAG_NEBULA ) {
1600 int pal = (verts[i]->b*(NEBULA_COLORS-1))/255;
1601 GrVerts[i].r = i2fl(gr_palette[pal*3+0]);
1602 GrVerts[i].g = i2fl(gr_palette[pal*3+1]);
1603 GrVerts[i].b = i2fl(gr_palette[pal*3+2]);
1604 } else if ( (flags & TMAP_FLAG_RAMP) && (flags & TMAP_FLAG_GOURAUD) ) {
1605 GrVerts[i].r = Gr_gamma_lookup_float[verts[i]->b];
1606 GrVerts[i].g = Gr_gamma_lookup_float[verts[i]->b];
1607 GrVerts[i].b = Gr_gamma_lookup_float[verts[i]->b];
1608 } else if ( (flags & TMAP_FLAG_RGB) && (flags & TMAP_FLAG_GOURAUD) ) {
1609 // Make 0.75 be 256.0f
1610 GrVerts[i].r = Gr_gamma_lookup_float[verts[i]->r];
1611 GrVerts[i].g = Gr_gamma_lookup_float[verts[i]->g];
1612 GrVerts[i].b = Gr_gamma_lookup_float[verts[i]->b];
1614 if ( flags & TMAP_FLAG_TEXTURED ) {
1615 GrVerts[i].r = 255.0f;
1616 GrVerts[i].g = 255.0f;
1617 GrVerts[i].b = 255.0f;
1619 GrVerts[i].r = i2fl(gr_screen.current_color.red);
1620 GrVerts[i].g = i2fl(gr_screen.current_color.green);
1621 GrVerts[i].b = i2fl(gr_screen.current_color.blue);
1626 x = fl2i(verts[i]->sx*16.0f);
1627 y = fl2i(verts[i]->sy*16.0f);
1629 if ( flags & TMAP_FLAG_CORRECT ) {
1633 } else if ( x > x2 ) {
1638 } else if ( y > y2 ) {
1643 x += gr_screen.offset_x*16;
1644 y += gr_screen.offset_y*16;
1646 GrVerts[i].x = i2fl(x) / 16.0f;
1647 GrVerts[i].y = i2fl(y) / 16.0f;
1649 //verts[i]->sw = 1.0f;
1651 GrVerts[i].oow=verts[i]->sw;
1653 if ( flags & TMAP_FLAG_TEXTURED ) {
1654 GrVerts[i].tmuvtx[GR_TMU0].oow=verts[i]->sw;
1655 GrVerts[i].tmuvtx[GR_TMU0].sow=verts[i]->u * verts[i]->sw * Glide_u_ratio;
1656 GrVerts[i].tmuvtx[GR_TMU0].tow=verts[i]->v * verts[i]->sw * Glide_v_ratio;
1660 // if we're rendering against a fullneb background
1661 if(flags & TMAP_FLAG_PIXEL_FOG){
1666 // get the average pixel color behind the vertices
1667 for(i=0; i<nv; i++){
1668 neb2_get_pixel((int)GrVerts[i].x, (int)GrVerts[i].y, &r, &g, &b);
1679 gr_fog_set(GR_FOGMODE_FOG, ra, ga, ba);
1682 if ( flags & TMAP_FLAG_CORRECT ) {
1683 grDrawPolygonVertexList( nv, GrVerts );
1685 for (i=1; i<nv-1; i++ ) {
1686 guDrawTriangleWithClip(&GrVerts[0],&GrVerts[i],&GrVerts[i+1]);
1691 // if(flags & TMAP_FLAG_PIXEL_FOG){
1692 // gr_fog_set(GR_FOGMODE_NONE, 0, 0, 0);
1696 void gr_glide_tmapper( int nv, vertex * verts[], uint flags )
1698 gr_glide_tmapper_internal( nv, verts, flags, 0 );
1701 #define FIND_SCALED_NUM(x,x0,x1,y0,y1) (((((x)-(x0))*((y1)-(y0)))/((x1)-(x0)))+(y0))
1703 void gr_glide_aascaler(vertex *va, vertex *vb )
1708 void gr_glide_scaler(vertex *va, vertex *vb )
1710 float x0, y0, x1, y1;
1711 float u0, v0, u1, v1;
1712 float clipped_x0, clipped_y0, clipped_x1, clipped_y1;
1713 float clipped_u0, clipped_v0, clipped_u1, clipped_v1;
1714 float xmin, xmax, ymin, ymax;
1715 int dx0, dy0, dx1, dy1;
1717 if(VOODOO3_INACTIVE()){
1721 //============= CLIP IT =====================
1723 x0 = va->sx; y0 = va->sy;
1724 x1 = vb->sx; y1 = vb->sy;
1726 xmin = i2fl(gr_screen.clip_left); ymin = i2fl(gr_screen.clip_top);
1727 xmax = i2fl(gr_screen.clip_right); ymax = i2fl(gr_screen.clip_bottom);
1729 u0 = va->u; v0 = va->v;
1730 u1 = vb->u; v1 = vb->v;
1732 // Check for obviously offscreen bitmaps...
1733 if ( (y1<=y0) || (x1<=x0) ) return;
1734 if ( (x1<xmin ) || (x0>xmax) ) return;
1735 if ( (y1<ymin ) || (y0>ymax) ) return;
1737 clipped_u0 = u0; clipped_v0 = v0;
1738 clipped_u1 = u1; clipped_v1 = v1;
1740 clipped_x0 = x0; clipped_y0 = y0;
1741 clipped_x1 = x1; clipped_y1 = y1;
1743 // Clip the left, moving u0 right as necessary
1745 clipped_u0 = FIND_SCALED_NUM(xmin,x0,x1,u0,u1);
1749 // Clip the right, moving u1 left as necessary
1751 clipped_u1 = FIND_SCALED_NUM(xmax,x0,x1,u0,u1);
1755 // Clip the top, moving v0 down as necessary
1757 clipped_v0 = FIND_SCALED_NUM(ymin,y0,y1,v0,v1);
1761 // Clip the bottom, moving v1 up as necessary
1763 clipped_v1 = FIND_SCALED_NUM(ymax,y0,y1,v0,v1);
1767 dx0 = fl2i(clipped_x0); dx1 = fl2i(clipped_x1);
1768 dy0 = fl2i(clipped_y0); dy1 = fl2i(clipped_y1);
1770 if (dx1<=dx0) return;
1771 if (dy1<=dy0) return;
1773 //============= DRAW IT =====================
1787 v[1].sx = clipped_x1;
1788 v[1].sy = clipped_y0;
1791 v[1].u = clipped_u1;
1792 v[1].v = clipped_v0;
1795 v[2].sx = clipped_x1;
1796 v[2].sy = clipped_y1;
1799 v[2].u = clipped_u1;
1800 v[2].v = clipped_v1;
1803 v[3].sx = clipped_x0;
1804 v[3].sy = clipped_y1;
1807 v[3].u = clipped_u0;
1808 v[3].v = clipped_v1;
1810 //glide_zbuffering(0);
1811 gr_glide_tmapper_internal( 4, vl, TMAP_FLAG_TEXTURED, 1 );
1815 void gr_glide_aabitmap_ex_new(int x,int y,int w,int h,int sx,int sy)
1817 if ( w < 1 ) return;
1818 if ( h < 1 ) return;
1820 if ( !gr_screen.current_color.is_alphacolor ) return;
1822 if(VOODOO3_INACTIVE()){
1826 // mprintf(( "x=%d, y=%d, w=%d, h=%d\n", x, y, w, h ));
1827 // mprintf(( "sx=%d, sy=%d, bw=%d, bh=%d\n", sx, sy, bmp->w, bmp->h ));
1829 float Glide_u_ratio;
1830 float Glide_v_ratio;
1832 // Set up Render State - flat shading - alpha blending
1833 gr_glide_set_state( TEXTURE_SOURCE_DECAL, COLOR_SOURCE_VERTEX, ALPHA_SOURCE_VERTEX_TIMES_TEXTURE, ALPHA_BLEND_ALPHA_BLEND_ALPHA, ZBUFFER_TYPE_NONE );
1835 if ( !gr_tcache_set( gr_screen.current_bitmap, TCACHE_TYPE_AABITMAP, &Glide_u_ratio, &Glide_v_ratio ) ) {
1836 // Couldn't set texture
1837 mprintf(( "GLIDE: Error setting aabitmap texture!\n" ));
1841 GrVertex GrVerts[4];
1843 float u0, u1, v0, v1;
1846 r = i2fl(gr_screen.current_color.red);
1847 g = i2fl(gr_screen.current_color.green);
1848 b = i2fl(gr_screen.current_color.blue);
1849 a = i2fl(gr_screen.current_color.alpha);
1853 bm_get_info( gr_screen.current_bitmap, &bw, &bh );
1855 u0 = Glide_u_ratio*i2fl(sx)/i2fl(bw);
1856 v0 = Glide_v_ratio*i2fl(sy)/i2fl(bh);
1858 u1 = Glide_u_ratio*i2fl(sx+w)/i2fl(bw);
1859 v1 = Glide_v_ratio*i2fl(sy+h)/i2fl(bh);
1861 float x1, x2, y1, y2;
1862 x1 = i2fl(x+gr_screen.offset_x);
1863 y1 = i2fl(y+gr_screen.offset_y);
1864 x2 = i2fl(x+w+gr_screen.offset_x);
1865 y2 = i2fl(y+h+gr_screen.offset_y);
1872 GrVerts[i].oow = 1.0f;
1877 GrVerts[i].tmuvtx[GR_TMU0].sow=u0;
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=v0;
1894 GrVerts[i].oow = 1.0f;
1899 GrVerts[i].tmuvtx[GR_TMU0].sow=u1;
1900 GrVerts[i].tmuvtx[GR_TMU0].tow=v1;
1905 GrVerts[i].oow = 1.0f;
1910 GrVerts[i].tmuvtx[GR_TMU0].sow=u0;
1911 GrVerts[i].tmuvtx[GR_TMU0].tow=v1;
1913 grDrawPolygonVertexList( 4, GrVerts );
1918 void gr_glide_aabitmap_ex(int x,int y,int w,int h,int sx,int sy)
1925 int dx1=x, dx2=x+w-1;
1926 int dy1=y, dy2=y+h-1;
1929 bm_get_info( gr_screen.current_bitmap, &bw, &bh, NULL );
1934 if ( count > 1 ) Int3();
1938 if ((dx1 > gr_screen.clip_right ) || (dx2 < gr_screen.clip_left)) return;
1939 if ((dy1 > gr_screen.clip_bottom ) || (dy2 < gr_screen.clip_top)) return;
1940 if ( dx1 < gr_screen.clip_left ) { sx += gr_screen.clip_left-dx1; dx1 = gr_screen.clip_left; }
1941 if ( dy1 < gr_screen.clip_top ) { sy += gr_screen.clip_top-dy1; dy1 = gr_screen.clip_top; }
1942 if ( dx2 > gr_screen.clip_right ) { dx2 = gr_screen.clip_right; }
1943 if ( dy2 > gr_screen.clip_bottom ) { dy2 = gr_screen.clip_bottom; }
1960 if ( sx + w > bw ) {
1965 if ( sy + h > bh ) {
1970 if ( w < 1 ) return; // clipped away!
1971 if ( h < 1 ) return; // clipped away!
1975 // Make sure clipping algorithm works
1979 Assert( w == (dx2-dx1+1) );
1980 Assert( h == (dy2-dy1+1) );
1983 Assert( sx+w <= bw );
1984 Assert( sy+h <= bh );
1985 Assert( dx2 >= dx1 );
1986 Assert( dy2 >= dy1 );
1987 Assert( (dx1 >= gr_screen.clip_left ) && (dx1 <= gr_screen.clip_right) );
1988 Assert( (dx2 >= gr_screen.clip_left ) && (dx2 <= gr_screen.clip_right) );
1989 Assert( (dy1 >= gr_screen.clip_top ) && (dy1 <= gr_screen.clip_bottom) );
1990 Assert( (dy2 >= gr_screen.clip_top ) && (dy2 <= gr_screen.clip_bottom) );
1993 // We now have dx1,dy1 and dx2,dy2 and sx, sy all set validly within clip regions.
1995 // Draw bitmap bm[sx,sy] into (dx1,dy1)-(dx2,dy2)
1996 gr_glide_aabitmap_ex_new(dx1,dy1,dx2-dx1+1,dy2-dy1+1,sx,sy);
1999 void gr_glide_string_hack( int sx, int sy, char *s )
2001 int width, spacing, letter;
2004 if ( !Current_font ) {
2008 gr_set_bitmap(Current_font->bitmap_id);
2013 if (sx==0x8000) { //centered
2014 x = get_centered_x(s);
2025 while (*s== '\n' ) {
2027 y += Current_font->h;
2028 if (sx==0x8000) { //centered
2029 x = get_centered_x(s);
2034 if (*s == 0 ) break;
2036 letter = get_char_width(s[0],s[1],&width,&spacing);
2039 if (letter<0) { //not in font, draw as space
2043 // formerly a call to gr_glide_char(...)
2047 ch = &Current_font->char_data[letter];
2049 int _sx = Current_font->bm_u[letter];
2050 int _sy = Current_font->bm_v[letter];
2052 gr_glide_aabitmap_ex( x, y, ch->byte_width, Current_font->h, _sx, _sy );
2057 void gr_glide_aabitmap(int x, int y)
2061 bm_get_info( gr_screen.current_bitmap, &w, &h, NULL );
2062 int dx1=x, dx2=x+w-1;
2063 int dy1=y, dy2=y+h-1;
2066 if ((dx1 > gr_screen.clip_right ) || (dx2 < gr_screen.clip_left)) return;
2067 if ((dy1 > gr_screen.clip_bottom ) || (dy2 < gr_screen.clip_top)) return;
2068 if ( dx1 < gr_screen.clip_left ) { sx = gr_screen.clip_left-dx1; dx1 = gr_screen.clip_left; }
2069 if ( dy1 < gr_screen.clip_top ) { sy = gr_screen.clip_top-dy1; dy1 = gr_screen.clip_top; }
2070 if ( dx2 > gr_screen.clip_right ) { dx2 = gr_screen.clip_right; }
2071 if ( dy2 > gr_screen.clip_bottom ) { dy2 = gr_screen.clip_bottom; }
2073 if ( sx < 0 ) return;
2074 if ( sy < 0 ) return;
2075 if ( sx >= w ) return;
2076 if ( sy >= h ) return;
2078 // Draw bitmap bm[sx,sy] into (dx1,dy1)-(dx2,dy2)
2079 gr_aabitmap_ex(dx1,dy1,dx2-dx1+1,dy2-dy1+1,sx,sy);
2083 void gr_glide_gradient(int x1,int y1,int x2,int y2)
2085 int clipped = 0, swapped=0;
2087 if(VOODOO3_INACTIVE()){
2091 if ( !gr_screen.current_color.is_alphacolor ) {
2092 gr_line( x1, y1, x2, y2 );
2096 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);
2098 // Set up Render State - flat shading - alpha blending
2099 gr_glide_set_state( TEXTURE_SOURCE_NONE, COLOR_SOURCE_VERTEX, ALPHA_SOURCE_VERTEX, ALPHA_BLEND_ALPHA_BLEND_ALPHA, ZBUFFER_TYPE_NONE );
2103 a.x = i2fl(x1 + gr_screen.offset_x);
2104 a.y = i2fl(y1 + gr_screen.offset_y);
2105 a.r = i2fl(gr_screen.current_color.red);
2106 a.g = i2fl(gr_screen.current_color.green);
2107 a.b = i2fl(gr_screen.current_color.blue);
2109 b.x = i2fl(x2 + gr_screen.offset_x);
2110 b.y = i2fl(y2 + gr_screen.offset_y);
2111 b.r = i2fl(gr_screen.current_color.red);
2112 b.g = i2fl(gr_screen.current_color.green);
2113 b.b = i2fl(gr_screen.current_color.blue);
2117 b.a = i2fl(gr_screen.current_color.alpha);
2120 a.a = i2fl(gr_screen.current_color.alpha);
2142 void gr_glide_set_palette(ubyte *new_palette, int force_flag )
2144 gr_palette_faded_out = 0;
2146 if(VOODOO3_INACTIVE()){
2150 #ifdef USE_8BPP_TEXTURES
2151 GuTexPalette palette;
2153 glide_free_textures();
2157 for (i=0;i<256; i++ ) {
2158 palette.data[i] = 0xFF000000;
2159 palette.data[i] |= new_palette[i*3+2];
2160 palette.data[i] |= new_palette[i*3+1]<<8;
2161 palette.data[i] |= new_palette[i*3+0]<<16;
2164 grTexDownloadTable( GR_TMU0, GR_TEXTABLE_PALETTE, &palette );
2169 void gr_glide_init_color(color *c, int r, int g, int b)
2171 c->screen_sig = gr_screen.signature;
2172 c->red = unsigned char(r);
2173 c->green = unsigned char(g);
2174 c->blue = unsigned char(b);
2176 c->ac_type = AC_TYPE_NONE;
2178 c->is_alphacolor = 0;
2182 void gr_glide_init_alphacolor( color *clr, int r, int g, int b, int alpha, int type )
2184 if ( r < 0 ) r = 0; else if ( r > 255 ) r = 255;
2185 if ( g < 0 ) g = 0; else if ( g > 255 ) g = 255;
2186 if ( b < 0 ) b = 0; else if ( b > 255 ) b = 255;
2187 if ( alpha < 0 ) alpha = 0; else if ( alpha > 255 ) alpha = 255;
2189 gr_glide_init_color( clr, r, g, b );
2191 clr->alpha = unsigned char(alpha);
2192 clr->ac_type = (ubyte)type;
2193 clr->alphacolor = -1;
2194 clr->is_alphacolor = 1;
2197 void gr_glide_set_color( int r, int g, int b )
2199 Assert((r >= 0) && (r < 256));
2200 Assert((g >= 0) && (g < 256));
2201 Assert((b >= 0) && (b < 256));
2203 gr_glide_init_color( &gr_screen.current_color, r, g, b );
2206 void gr_glide_get_color( int * r, int * g, int * b )
2208 if (r) *r = gr_screen.current_color.red;
2209 if (g) *g = gr_screen.current_color.green;
2210 if (b) *b = gr_screen.current_color.blue;
2213 void gr_glide_set_color_fast(color *dst)
2215 if ( dst->screen_sig != gr_screen.signature ) {
2216 if ( dst->is_alphacolor ) {
2217 gr_glide_init_alphacolor( dst, dst->red, dst->green, dst->blue, dst->alpha, dst->ac_type );
2219 gr_glide_init_color( dst, dst->red, dst->green, dst->blue );
2222 gr_screen.current_color = *dst;
2227 void gr_glide_flash(int r, int g, int b)
2233 if(VOODOO3_INACTIVE()){
2241 if ( Flash_r || Flash_g || Flash_b ) {
2242 gr_glide_set_state( TEXTURE_SOURCE_NONE, COLOR_SOURCE_VERTEX, ALPHA_SOURCE_VERTEX, ALPHA_BLEND_ALPHA_ADDITIVE, ZBUFFER_TYPE_NONE );
2244 GrVertex GrVerts[4];
2253 float x1, x2, y1, y2;
2254 x1 = i2fl(gr_screen.clip_left+gr_screen.offset_x);
2255 y1 = i2fl(gr_screen.clip_top+gr_screen.offset_y);
2256 x2 = i2fl(gr_screen.clip_right+gr_screen.offset_x);
2257 y2 = i2fl(gr_screen.clip_bottom+gr_screen.offset_y);
2293 grDrawPolygonVertexList( 4, GrVerts );
2300 void gr_glide_activate(int active)
2302 if (!Glide_running) {
2306 mprintf(( "Glide activate: %d\n", active ));
2310 // choose resolution
2311 GrScreenResolution_t res_mode;
2312 if((gr_screen.max_w == 1024) && (gr_screen.max_h == 768)){
2313 res_mode = GR_RESOLUTION_1024x768;
2315 res_mode = GR_RESOLUTION_640x480;
2318 HWND hwnd = (HWND)os_get_window();
2322 if(Glide_deactivate == 0){
2326 Glide_deactivate = 0;
2329 SetActiveWindow(hwnd);
2330 SetForegroundWindow(hwnd);
2331 grSstWinOpen( (DWORD)hwnd, res_mode, GR_REFRESH_60Hz, GR_COLORFORMAT_ABGR, GR_ORIGIN_UPPER_LEFT, 2, 1 );
2332 ShowWindow(hwnd,SW_MAXIMIZE);
2333 gr_glide_clip_cursor(1);
2334 glide_tcache_init();
2335 grGammaCorrectionValue(1.0f);
2338 // already deactivated
2339 if(Glide_deactivate == VOODOO3_DEACTIVATED){
2343 Glide_deactivate = VOODOO3_DEACTIVATED;
2346 gr_glide_clip_cursor(0);
2347 ShowWindow(hwnd,SW_MINIMIZE);
2352 HWND hwnd = (HWND)os_get_window();
2358 // SetActiveWindow(hwnd);
2359 // SetForegroundWindow(hwnd);
2360 ShowWindow(hwnd,SW_RESTORE);
2361 // gr_glide_clip_cursor(1);
2362 // grSstControl(GR_CONTROL_ACTIVATE);
2368 // grSstControl(GR_CONTROL_DEACTIVATE);
2370 ShowWindow(hwnd,SW_MINIMIZE);
2377 // copy from one pixel buffer to another
2379 // from pointer to source buffer
2380 // to pointer to dest. buffet
2381 // pixels number of pixels to copy
2382 // fromsize source pixel size
2383 // tosize dest. pixel size
2385 static int tga_copy_data(char *to, char *from, int pixels, int fromsize, int tosize)
2397 if ( (fromsize == 2) && (tosize == 3) ) {
2398 ushort *src = (ushort *)from;
2399 ubyte *dst = (ubyte *)to;
2402 for (i=0; i<pixels; i++ ) {
2403 ushort pixel = *src++;
2406 b = ((pixel & bmask)>>bshift)*bscale;
2407 g = ((pixel & gmask)>>gshift)*gscale;
2408 r = ((pixel & rmask)>>rshift)*rscale;
2410 // Adjust for gamma and output it
2415 return tosize*pixels;
2418 return tosize*pixels;
2425 // tga_pixels_equal -- Test if two pixels are identical
2431 static int tga_pixels_equal(char *pix1, char *pix2, int pixbytes)
2434 if ( *pix1++ != *pix2++ ) {
2437 } while ( --pixbytes > 0 );
2443 // tga_compress - Do the Run Length Compression
2446 // out Buffer to write it out to
2447 // in Buffer to compress
2448 // bytecount Number of bytes input
2449 // pixsize Number of bytes in input pixel
2450 // outsize Number of bytes in output buffer
2452 int tga_compress(char *out, char *in, int bytecount )
2456 int pixcount; // number of pixels in the current packet
2457 char *inputpixel=NULL; // current input pixel position
2458 char *matchpixel=NULL; // pixel value to match for a run
2459 char *flagbyte=NULL; // location of last flag byte to set
2460 int rlcount; // current count in r.l. string
2461 int rlthresh; // minimum valid run length
2462 char *copyloc; // location to begin copying at
2464 // set the threshold -- the minimum valid run length
2467 rlthresh = 2; // for 8bpp, require a 2 pixel span before rle'ing
2472 // set the first pixel up
2474 flagbyte = out; // place to put next flag if run
2478 copyloc = (char *)0;
2480 // loop till data processing complete
2483 // if we have accumulated a 128-byte packet, process it
2484 if ( pixcount == 129 ) {
2487 // set the run flag if this is a run
2489 if ( rlcount >= rlthresh ) {
2494 // copy the data into place
2496 flagbyte += tga_copy_data(flagbyte, copyloc, pixcount-1, pixsize, outsize);
2499 // set up for next packet
2503 // if zeroth byte, handle as special case
2504 if ( pixcount == 1 ) {
2506 copyloc = inputpixel; /* point to 1st guy in packet */
2507 matchpixel = inputpixel; /* set pointer to pix to match */
2509 inputpixel += pixsize;
2513 // assembling a packet -- look at next pixel
2515 // current pixel == match pixel?
2516 if ( tga_pixels_equal(inputpixel, matchpixel, outsize) ) {
2518 // establishing a run of enough length to
2519 // save space by doing it
2520 // -- write the non-run length packet
2521 // -- start run-length packet
2523 if ( ++rlcount == rlthresh ) {
2525 // close a non-run packet
2527 if ( pixcount > (rlcount+1) ) {
2528 // write out length and do not set run flag
2530 *flagbyte++ = (char)(pixcount - 2 - rlthresh);
2532 flagbyte += tga_copy_data(flagbyte, copyloc, (pixcount-1-rlcount), pixsize, outsize);
2534 copyloc = inputpixel;
2535 pixcount = rlcount + 1;
2540 // no match -- either break a run or continue without one
2541 // if a run exists break it:
2542 // write the bytes in the string (outsize+1)
2543 // start the next string
2545 if ( rlcount >= rlthresh ) {
2547 *flagbyte++ = (char)(0x80 | rlcount);
2548 flagbyte += tga_copy_data(flagbyte, copyloc, 1, pixsize, outsize);
2553 // not a match and currently not a run
2554 // - save the current pixel
2555 // - reset the run-length flag
2557 matchpixel = inputpixel;
2561 inputpixel += pixsize;
2562 } while ( inputpixel < (in + bytecount));
2564 // quit this buffer without loosing any data
2566 if ( --pixcount >= 1 ) {
2567 *flagbyte = (char)(pixcount - 1);
2568 if ( rlcount >= rlthresh ) {
2573 // copy the data into place
2575 flagbyte += tga_copy_data(flagbyte, copyloc, pixcount, pixsize, outsize);
2577 return(flagbyte-out);
2582 void gr_glide_print_screen(char *filename)
2586 ubyte outrow[1024*3*4];
2588 if(VOODOO3_INACTIVE()){
2592 if ( gr_screen.max_w > 1024 ) {
2593 mprintf(( "Screen too wide for print_screen\n" ));
2597 info.size=sizeof(GrLfbInfo_t);
2599 // get a read pointer
2600 if ( grLfbLock( GR_LFB_READ_ONLY, GR_BUFFER_BACKBUFFER, GR_LFBWRITEMODE_565,
2601 GR_ORIGIN_UPPER_LEFT, FXFALSE, &info)) {
2602 int w=gr_screen.max_w,h=gr_screen.max_h;
2604 int short_per_row=info.strideInBytes/2;
2606 rptr = (ushort *)info.lfbPtr;
2611 strcpy( tmp, NOX(".\\")); // specify a path mean files goes in root
2612 strcat( tmp, filename );
2613 strcat( tmp, NOX(".tga"));
2615 CFILE *f = cfopen(tmp, "wb");
2617 // Write the TGA header
2618 cfwrite_ubyte( 0, f ); // IDLength;
2619 cfwrite_ubyte( 0, f ); // ColorMapType;
2620 cfwrite_ubyte( 10, f ); // ImageType; // 2 = 24bpp, uncompressed, 10=24bpp rle compressed
2621 cfwrite_ushort( 0, f ); // CMapStart;
2622 cfwrite_ushort( 0, f ); // CMapLength;
2623 cfwrite_ubyte( 0, f ); // CMapDepth;
2624 cfwrite_ushort( 0, f ); // XOffset;
2625 cfwrite_ushort( 0, f ); // YOffset;
2626 cfwrite_ushort( (ushort)w, f ); // Width;
2627 cfwrite_ushort( (ushort)h, f ); // Height;
2628 cfwrite_ubyte( 24, f ); //PixelDepth;
2629 cfwrite_ubyte( 0, f ); //ImageDesc;
2631 // Go through and read our pixels
2633 int len = tga_compress( (char *)outrow, (char *)&rptr[(h-i-1)*short_per_row], w*sizeof(short) );
2635 cfwrite(outrow,len,1,f);
2641 grLfbUnlock( GR_LFB_READ_ONLY, GR_BUFFER_BACKBUFFER );
2643 mprintf(( "Couldn't get a lock to glide's back buffer!\n" ));
2649 int gr_glide_save_screen_internal(ushort *src_data)
2654 if(VOODOO3_INACTIVE()){
2658 info.size=sizeof(GrLfbInfo_t);
2660 // get a read pointer
2661 if ( grLfbLock( GR_LFB_READ_ONLY, GR_BUFFER_FRONTBUFFER, GR_LFBWRITEMODE_565,
2662 GR_ORIGIN_UPPER_LEFT, FXFALSE, &info)) {
2663 int w=gr_screen.max_w,h=gr_screen.max_h;
2665 int short_per_row=info.strideInBytes/2;
2667 rptr = (ushort *)info.lfbPtr;
2669 // Go through and read our pixels
2671 memcpy( &src_data[gr_screen.max_w*i], &rptr[i*short_per_row], w*sizeof(short) );
2675 grLfbUnlock( GR_LFB_READ_ONLY, GR_BUFFER_FRONTBUFFER );
2677 mprintf(( "Couldn't get a read lock to glide's back buffer!\n" ));
2684 static ushort *Gr_saved_screen = NULL;
2686 int gr_glide_save_screen()
2688 if(VOODOO3_INACTIVE()){
2692 if ( Gr_saved_screen ) {
2693 mprintf(( "Screen alread saved!\n" ));
2699 Gr_saved_screen = (ushort *)malloc( gr_screen.max_w*gr_screen.max_h*sizeof(ushort) );
2700 if (!Gr_saved_screen) {
2701 mprintf(( "Couldn't get memory for saved screen!\n" ));
2705 if ( !gr_glide_save_screen_internal(Gr_saved_screen) ) {
2706 free(Gr_saved_screen);
2707 Gr_saved_screen = NULL;
2711 if ( Gr_glide_mouse_saved ) {
2712 ushort *sptr, *dptr;
2714 sptr = Gr_glide_mouse_saved_data;
2716 for (int i=0; i<Gr_glide_mouse_saved_h; i++ ) {
2717 dptr = &Gr_saved_screen[(Gr_glide_mouse_saved_y1+i)*gr_screen.max_w+Gr_glide_mouse_saved_x1];
2719 for(int j=0; j<Gr_glide_mouse_saved_w; j++ ) {
2728 void gr_glide_restore_screen_internal(ushort *src_data)
2733 if(VOODOO3_INACTIVE()){
2737 info.size=sizeof(GrLfbInfo_t);
2739 // get a read pointer
2740 if ( grLfbLock( GR_LFB_WRITE_ONLY, GR_BUFFER_BACKBUFFER, GR_LFBWRITEMODE_565,
2741 GR_ORIGIN_UPPER_LEFT, FXFALSE, &info)) {
2742 int w=gr_screen.max_w,h=gr_screen.max_h;
2744 int short_per_row=info.strideInBytes/2;
2746 rptr = (ushort *)info.lfbPtr;
2748 // Go through and read our pixels
2750 memcpy( &rptr[i*short_per_row], &src_data[gr_screen.max_w*i], w*sizeof(short) );
2754 grLfbUnlock( GR_LFB_WRITE_ONLY, GR_BUFFER_BACKBUFFER );
2756 mprintf(( "Couldn't get a write lock to glide's back buffer!\n" ));
2761 void gr_glide_restore_screen(int id)
2763 if(VOODOO3_INACTIVE()){
2769 if ( !Gr_saved_screen ) {
2774 gr_glide_restore_screen_internal(Gr_saved_screen);
2777 void gr_glide_free_screen(int id)
2779 if(VOODOO3_INACTIVE()){
2783 if ( Gr_saved_screen ) {
2784 free( Gr_saved_screen );
2785 Gr_saved_screen = NULL;
2790 void gr_glide_force_windowed()
2792 if(VOODOO3_INACTIVE()){
2796 gr_glide_clip_cursor(0);
2797 grSstControl(GR_CONTROL_DEACTIVATE);
2802 static int Glide_dump_frames = 0;
2803 static ubyte *Glide_dump_buffer = NULL;
2804 static int Glide_dump_frame_number = 0;
2805 static int Glide_dump_frame_count = 0;
2806 static int Glide_dump_frame_count_max = 0;
2807 static int Glide_dump_frame_size = 0;
2809 void gr_glide_dump_frame_start(int first_frame, int frames_between_dumps)
2811 if(VOODOO3_INACTIVE()){
2815 if ( Glide_dump_frames ) {
2816 Int3(); // We're already dumping frames. See John.
2819 Glide_dump_frames = 1;
2820 Glide_dump_frame_number = first_frame;
2821 Glide_dump_frame_count = 0;
2822 Glide_dump_frame_count_max = frames_between_dumps;
2823 Glide_dump_frame_size = gr_screen.max_w * gr_screen.max_h * 2;
2825 if ( !Glide_dump_buffer ) {
2826 int size = Glide_dump_frame_count_max * Glide_dump_frame_size;
2827 Glide_dump_buffer = (ubyte *)malloc(size);
2828 if ( !Glide_dump_buffer ) {
2829 Error(LOCATION, "Unable to malloc %d bytes for dump buffer", size );
2835 // A hacked function to dump the frame buffer contents
2836 void gr_glide_dump_screen_hack( ushort * dst )
2841 if(VOODOO3_INACTIVE()){
2845 info.size=sizeof(GrLfbInfo_t);
2847 // get a read pointer
2848 if ( grLfbLock(GR_LFB_READ_ONLY, GR_BUFFER_BACKBUFFER, GR_LFBWRITEMODE_565, GR_ORIGIN_UPPER_LEFT, FXFALSE, &info)) {
2849 int w=gr_screen.max_w,h=gr_screen.max_h;
2851 int short_per_row=info.strideInBytes/2;
2853 rptr = (ushort *)info.lfbPtr;
2855 // Go through and read our pixels
2857 memcpy( &dst[gr_screen.max_w*i], &rptr[(h-i-1)*short_per_row], w*sizeof(short) );
2861 grLfbUnlock( GR_LFB_READ_ONLY, GR_BUFFER_BACKBUFFER );
2863 mprintf(( "Couldn't get a read lock to glide's back buffer for frame dump!\n" ));
2867 void gr_glide_get_region(int front, int w, int h, ubyte *data)
2874 if(VOODOO3_INACTIVE()){
2878 info.size=sizeof(GrLfbInfo_t);
2879 // get a read pointer
2880 if ( grLfbLock(GR_LFB_READ_ONLY, front ? GR_BUFFER_FRONTBUFFER : GR_BUFFER_BACKBUFFER, GR_LFBWRITEMODE_1555, GR_ORIGIN_UPPER_LEFT, FXFALSE, &info)){
2882 int short_per_row=info.strideInBytes/2;
2884 rptr = (ushort *)info.lfbPtr;
2886 ushort *sptr, *dptr;
2888 dptr = (ushort*)data;
2890 for (int i=0; i<h; i++ ) {
2891 sptr = &rptr[i*short_per_row];
2893 // 565 data is what we always get, so we need to swizzle
2894 for(int j=0; j<w; j++ ) {
2897 r = (ubyte)((bit_16 & 0xf800) >> 8);
2898 g = (ubyte)((bit_16 & 0x07e0) >> 3);
2899 b = (ubyte)((bit_16 & 0x001f) << 3);
2901 // swizzle the data to 1555 (BM_PIXEL_FORMAT_ARGB)
2903 bm_set_components((ubyte*)dptr++, &r, &g, &b, &a);
2908 grLfbUnlock(GR_LFB_READ_ONLY, front ? GR_BUFFER_FRONTBUFFER : GR_BUFFER_BACKBUFFER);
2912 void gr_glide_flush_frame_dump()
2915 char filename[MAX_PATH_LEN], *movie_path = ".\\";
2916 ubyte outrow[1024*3*4];
2918 if(VOODOO3_INACTIVE()){
2922 if ( gr_screen.max_w > 1024) {
2923 mprintf(( "Screen too wide for frame_dump\n" ));
2927 for (i = 0; i < Glide_dump_frame_count; i++) {
2929 int w = gr_screen.max_w;
2930 int h = gr_screen.max_h;
2932 sprintf(filename, NOX("%sfrm%04d.tga"), movie_path, Glide_dump_frame_number );
2933 Glide_dump_frame_number++;
2935 CFILE *f = cfopen(filename, "wb");
2937 // Write the TGA header
2938 cfwrite_ubyte( 0, f ); // IDLength;
2939 cfwrite_ubyte( 0, f ); // ColorMapType;
2940 cfwrite_ubyte( 10, f ); // ImageType; // 2 = 24bpp, uncompressed, 10=24bpp rle compressed
2941 cfwrite_ushort( 0, f ); // CMapStart;
2942 cfwrite_ushort( 0, f ); // CMapLength;
2943 cfwrite_ubyte( 0, f ); // CMapDepth;
2944 cfwrite_ushort( 0, f ); // XOffset;
2945 cfwrite_ushort( 0, f ); // YOffset;
2946 cfwrite_ushort( (ushort)w, f ); // Width;
2947 cfwrite_ushort( (ushort)h, f ); // Height;
2948 cfwrite_ubyte( 24, f ); //PixelDepth;
2949 cfwrite_ubyte( 0, f ); //ImageDesc;
2951 // Go through and write our pixels
2953 ubyte *src_ptr = Glide_dump_buffer+(i*Glide_dump_frame_size)+(j*w*2);
2955 int len = tga_compress( (char *)outrow, (char *)src_ptr, w*sizeof(short) );
2957 cfwrite(outrow,len,1,f);
2964 Glide_dump_frame_count = 0;
2967 void gr_glide_dump_frame()
2969 if(VOODOO3_INACTIVE()){
2973 // A hacked function to dump the frame buffer contents
2974 gr_glide_dump_screen_hack( (ushort *)(Glide_dump_buffer+(Glide_dump_frame_count*Glide_dump_frame_size)) );
2976 Glide_dump_frame_count++;
2978 if ( Glide_dump_frame_count == Glide_dump_frame_count_max ) {
2979 gr_glide_flush_frame_dump();
2983 void gr_glide_dump_frame_stop()
2985 if(VOODOO3_INACTIVE()){
2989 if ( !Glide_dump_frames ) {
2990 Int3(); // We're not dumping frames. See John.
2994 // dump any remaining frames
2995 gr_glide_flush_frame_dump();
2997 Glide_dump_frames = 0;
2998 if ( Glide_dump_buffer ) {
2999 free(Glide_dump_buffer);
3000 Glide_dump_buffer = NULL;
3004 #define FADE_TIME (F1_0/4) // How long to fade out
3006 void gr_glide_fade_out(int instantaneous)
3010 if(VOODOO3_INACTIVE()){
3017 tmp_data = (ushort *)malloc( gr_screen.max_w*gr_screen.max_h*sizeof(ushort) );
3020 gr_glide_save_screen_internal(tmp_data);
3023 if (!gr_palette_faded_out) {
3025 if ( !instantaneous ) {
3029 fix start_time, stop_time, t1;
3032 start_time = timer_get_fixed_seconds();
3036 //int c = (255*(FADE_TIME-t1))/FADE_TIME;
3037 int c = (255*t1)/FADE_TIME;
3040 } else if ( c > 255 ) {
3044 gr_glide_restore_screen_internal(tmp_data);
3046 for (int i=0; i<gr_screen.max_h; i++ ) {
3047 glide_shade_scanline( 0, gr_screen.max_w-1, i, 0, 0, 0, c );
3053 t1 = timer_get_fixed_seconds() - start_time;
3055 } while ( (t1 < FADE_TIME) && (t1>=0) ); // Loop as long as time not up and timer hasn't rolled
3057 stop_time = timer_get_fixed_seconds();
3059 mprintf(( "Took %d frames (and %.1f secs) to fade out\n", count, f2fl(stop_time-start_time) ));
3067 gr_palette_faded_out = 1;
3075 void gr_glide_fade_in(int instantaneous)
3079 if(VOODOO3_INACTIVE()){
3086 tmp_data = (ushort *)malloc( gr_screen.max_w*gr_screen.max_h*sizeof(ushort) );
3089 gr_glide_save_screen_internal(tmp_data);
3092 if (gr_palette_faded_out) {
3094 gr_palette_faded_out = 0;
3096 if ( !instantaneous ) {
3100 fix start_time, stop_time, t1;
3103 start_time = timer_get_fixed_seconds();
3107 int c = (255*(FADE_TIME-t1))/FADE_TIME;
3110 } else if ( c > 255 ) {
3114 gr_glide_restore_screen_internal(tmp_data);
3116 for (int i=0; i<gr_screen.max_h; i++ ) {
3117 glide_shade_scanline( 0, gr_screen.max_w-1, i, 0, 0, 0, c );
3123 t1 = timer_get_fixed_seconds() - start_time;
3125 } while ( (t1 < FADE_TIME) && (t1>=0) ); // Loop as long as time not up and timer hasn't rolled
3127 stop_time = timer_get_fixed_seconds();
3129 mprintf(( "Took %d frames (and %.1f secs) to fade out\n", count, f2fl(stop_time-start_time) ));
3137 gr_glide_restore_screen_internal(tmp_data);
3147 void gr_glide_cleanup()
3149 if ( !Inited ) return;
3156 gr_glide_clip_cursor(0);
3158 glide_tcache_cleanup();
3163 void gr_glide_set_gamma(float gamma)
3166 Gr_gamma_int = int(Gr_gamma*100);
3168 // Create the Gamma lookup table
3170 for (i=0; i<256; i++ ) {
3171 int v = fl2i(pow(i2fl(i)/255.0f, 1.0f/Gr_gamma)*255.0f);
3174 } else if ( v < 0 ) {
3177 Gr_gamma_lookup[i] = v;
3180 for (i=0; i<256; i++ ) {
3181 float v = (float)pow(i2fl(i)/255.0f, 1.0f/Gr_gamma)*255.0f;
3184 } else if ( v < 0.0f ) {
3187 Gr_gamma_lookup_float[i] = v;
3190 // Flush any existing textures
3191 glide_tcache_flush();
3195 void gr_glide_fog_set(int fog_mode, int r, int g, int b, float fog_near, float fog_far)
3197 GrColor_t color = 0;
3199 if(VOODOO3_INACTIVE()){
3203 Assert((r >= 0) && (r < 256));
3204 Assert((g >= 0) && (g < 256));
3205 Assert((b >= 0) && (b < 256));
3208 gr_glide_init_color( &gr_screen.current_fog_color, r, g, b );
3209 if(fog_near >= 0.0f){
3210 gr_screen.fog_near = fog_near;
3212 if(fog_far >= 0.0f){
3213 gr_screen.fog_far = fog_far;
3215 gr_screen.current_fog_mode = fog_mode;
3217 // enable/disable fog
3218 if(fog_mode == GR_FOGMODE_NONE){
3219 grFogMode(GR_FOG_DISABLE);
3221 // always unset the global for value if we're disabling fog
3222 gr_screen.fog_near = -1.0f;
3223 gr_screen.fog_far = -1.0f;
3227 grFogMode(GR_FOG_WITH_TABLE);
3229 // set the fog color
3230 color |= ((ubyte)r);
3231 color |= ((ubyte)g << 8);
3232 color |= ((ubyte)b << 16);
3233 grFogColorValue(color);
3235 // only generate a new fog table if we have to
3236 if((fog_near >= 0.0f) && (fog_far > fog_near)){
3237 guFogGenerateLinear(Glide_linear_fogtable, fog_near, fog_far);
3240 // set the fog table
3241 grFogTable(Glide_linear_fogtable);
3244 void gr_glide_get_pixel(int x, int y, int *r, int *g, int *b)
3251 if(VOODOO3_INACTIVE()){
3255 // returns data in 565 format
3256 grLfbReadRegion(GR_BUFFER_BACKBUFFER, (FxU32)x, (FxU32)y, 1, 1, 2, &pixel);
3258 // unpack pixel color
3259 *r = (0xf800 & pixel) >> 8;
3260 *g = (0x07e0 & pixel) >> 3;
3261 *b = (0x001f & pixel) << 3;
3264 // resolution checking
3265 int gr_glide_supports_res_ingame(int res)
3270 int gr_glide_supports_res_interface(int res)
3275 void gr_glide_set_cull(int cull)
3279 void gr_glide_filter_set(int filter)
3281 if(VOODOO3_INACTIVE()){
3286 grTexFilterMode(GR_TMU0, GR_TEXTUREFILTER_BILINEAR, GR_TEXTUREFILTER_BILINEAR);
3288 grTexFilterMode(GR_TMU0, GR_TEXTUREFILTER_POINT_SAMPLED, GR_TEXTUREFILTER_POINT_SAMPLED);
3293 void gr_glide_set_clear_color(int r, int g, int b)
3295 gr_init_color(&gr_screen.current_clear_color, r, g, b);
3298 extern int movie_rendered_flag;
3299 extern int movie_frame_count;
3301 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)
3308 if(VOODOO3_INACTIVE()){
3315 ushort *src_data = (ushort *)buf;
3317 movie_rendered_flag = 1;
3326 SetRect(&srect, sx, sy, sx+w-1, sy+h-1);
3327 //SetRect(&drect, dstx, dsty, dstx+w-1, dsty+h-1);
3328 dstx = (gr_screen.max_w - w)/2;
3329 dsty = (gr_screen.max_h - h)/2;
3330 SetRect(&drect, dstx, dsty, dstx+w-1, dsty+h-1);
3335 info.size=sizeof(GrLfbInfo_t);
3337 // get a read pointer
3338 if ( grLfbLock( GR_LFB_WRITE_ONLY, GR_BUFFER_BACKBUFFER, GR_LFBWRITEMODE_1555,
3339 GR_ORIGIN_UPPER_LEFT, FXFALSE, &info)) {
3341 int short_per_row=info.strideInBytes/2;
3343 rptr = (ushort *)info.lfbPtr;
3345 // if doing interlaced mode, then go through every other scanline
3346 if ( Interlace_movies ) {
3347 static int start_at = 0;
3349 for ( i = start_at; i < (int)h; i += 2 ) {
3350 memcpy( &rptr[(dsty+i)*short_per_row+dstx], &src_data[bufw*i], w*sizeof(short) );
3352 //start_at = (start_at + 1) % 2;
3354 // Go through and read our pixels
3355 for (i=0;i<(int)h;i++) {
3356 memcpy( &rptr[(dsty+i)*short_per_row+dstx], &src_data[bufw*i], w*sizeof(short) );
3361 grLfbUnlock( GR_LFB_WRITE_ONLY, GR_BUFFER_BACKBUFFER );
3363 mprintf(( "Couldn't get a write lock to glide's back buffer!\n" ));
3373 #define FETCH_A(i, j) { \
3375 code |= ((i+min_x<x1) << 0); \
3376 code |= ((j+min_y<y1) << 1); \
3377 code |= ((i+min_x<x1+bmp1->w) << 2); \
3378 code |= ((j+min_y<y1+bmp1->h) << 3); \
3379 if(code && (code < 4)){ \
3380 pixel_a = sptr1[i - (x1 - min_x)]; \
3382 pixel_a = pixel_black; \
3385 #define FETCH_B(i, j) { \
3387 code |= ((i+min_x<x2) << 0); \
3388 code |= ((j+min_y<y2) << 1); \
3389 code |= ((i+min_x<x2+bmp2->w) << 2); \
3390 code |= ((j+min_y<y2+bmp2->h) << 3); \
3391 if(code && (code < 4)){ \
3392 pixel_b = sptr2[i - (x2 - min_x)]; \
3394 pixel_b = pixel_black; \
3397 #define MIX(pout, p1, p2) { pout = p1; }
3398 void gr_glide_cross_fade(int bmap1, int bmap2, int x1, int y1, int x2, int y2, float pct)
3401 gr_set_bitmap(bmap1);
3404 gr_set_bitmap(bmap2);
3408 int min_x = x1 < x2 ? x1 : x2;
3409 int min_y = y1 < y2 ? y1 : y2;
3410 int max_x = x2 > x1 ? x2 : x1;
3411 int max_y = y2 > y1 ? y2 : y1;
3416 bitmap *bmp1, *bmp2;
3417 ushort pixel_a, pixel_b;
3422 // stuff the black pixel
3423 r = 0; g = 0; b = 0; a = 255;
3425 bm_set_components(&pixel_black, &r, &g, &b, &a);
3427 // lock the first bitmap
3428 bmp1 = bm_lock( bmap1, 16, 0 );
3429 sptr1 = (ushort *)( bmp1->data );
3431 // lock the second bitmap
3432 bmp2 = bm_lock( bmap2, 16, 0 );
3433 sptr2 = (ushort *)( bmp2->data );
3449 if(bmp1->w > bmp2->w){
3454 if(bmp1->h > bmp2->h){
3462 // lock the framebuffer
3463 if ( grLfbLock( GR_LFB_WRITE_ONLY, GR_BUFFER_BACKBUFFER, GR_LFBWRITEMODE_1555, GR_ORIGIN_UPPER_LEFT, FXFALSE, &info) ) {
3465 // pointer into vram
3466 ushort *vram = (ushort *)info.lfbPtr;
3467 int stride = info.strideInBytes / sizeof(ushort);
3469 // for all scanlines
3470 for (i=0; i<max_h; i++ ){
3471 // this scanline in vram
3472 ushort *dptr = &vram[stride*(gr_screen.offset_y+i+min_y)+(gr_screen.offset_x+min_x)];
3474 // for this scanline
3475 for ( j=0; j<max_w; j++ ){
3476 // fetch the A and B pixels
3481 code |= ((i+min_x>=x1) << 0);
3482 code |= ((j+min_y>=y1) << 1);
3483 code |= ((i+min_x>x1+bmp1->w) << 2);
3484 code |= ((j+min_y>y1+bmp1->h) << 3);
3485 if(code && (code < 4)){
3486 pixel_a = sptr1[i - (x1 - min_x)];
3488 pixel_a = pixel_black;
3493 code |= ((i+min_x>=x2) << 0);
3494 code |= ((j+min_y>=y2) << 1);
3495 code |= ((i+min_x>x2+bmp2->w) << 2);
3496 code |= ((j+min_y>y2+bmp2->h) << 3);
3497 if(code && (code < 4)){
3498 pixel_b = sptr2[i - (x2 - min_x)];
3500 pixel_b = pixel_black;
3505 // mix them - for now just always pick pixel A
3506 MIX(pixel_out, pixel_a, pixel_b);
3511 // next pixel in vram
3515 // increment if we need to
3516 if((j+min_y >= y1) && (j+min_y < y1+bmp1->h)){
3519 // increment if we need to
3520 if((j+min_y >= y2) && (j+min_y < y2+bmp2->h)){
3525 grLfbUnlock(GR_LFB_WRITE_ONLY, GR_BUFFER_BACKBUFFER);
3533 GrHwConfiguration hwconfig;
3535 void gr_glide_init()
3546 // Turn off the 3Dfx splash screen
3547 SetEnvironmentVariable("FX_GLIDE_NO_SPLASH","1");
3549 // Turn off the 3Dfx gamma correction
3550 SetEnvironmentVariable("SST_RGAMMA","1.0");
3551 SetEnvironmentVariable("SST_GGAMMA","1.0");
3552 SetEnvironmentVariable("SST_BGAMMA","1.0");
3554 mprintf(( "Initializing glide graphics device...\n" ));
3557 if ( !vglide_init() ) {
3558 mprintf(( "Glide DLL not found!\n" ));
3564 // Find the extents of the window
3565 HWND hwnd = (HWND)os_get_window();
3567 // Prepare the window to go full screen
3569 mprintf(( "Window in debugging mode... mouse clicking may cause problems!\n" ));
3570 SetWindowLong( hwnd, GWL_EXSTYLE, WS_EX_TRANSPARENT );
3571 SetWindowLong( hwnd, GWL_STYLE, WS_POPUP );
3572 ShowWindow(hwnd, SW_SHOWNORMAL );
3574 SystemParametersInfo( SPI_GETWORKAREA, 0, &work_rect, 0 );
3575 SetWindowPos( hwnd, HWND_NOTOPMOST, work_rect.left, work_rect.top, gr_screen.max_w, gr_screen.max_h, 0 );
3576 SetActiveWindow(hwnd);
3577 SetForegroundWindow(hwnd);
3578 Glide_cursor_clip_rect.left = work_rect.left;
3579 Glide_cursor_clip_rect.top = work_rect.top;
3580 Glide_cursor_clip_rect.right = work_rect.left + gr_screen.max_w - 1;
3581 Glide_cursor_clip_rect.bottom = work_rect.top + gr_screen.max_h - 1;
3583 SetWindowLong( hwnd, GWL_EXSTYLE, 0 );
3584 SetWindowLong( hwnd, GWL_STYLE, WS_POPUP );
3585 ShowWindow(hwnd, SW_SHOWNORMAL );
3586 SetWindowPos( hwnd, HWND_TOPMOST, 0, 0, GetSystemMetrics( SM_CXSCREEN ), GetSystemMetrics( SM_CYSCREEN ), 0 );
3587 SetActiveWindow(hwnd);
3588 SetForegroundWindow(hwnd);
3589 Glide_cursor_clip_rect.left = 0;
3590 Glide_cursor_clip_rect.top = 0;
3591 Glide_cursor_clip_rect.right = gr_screen.max_w;
3592 Glide_cursor_clip_rect.bottom = gr_screen.max_h;
3595 // Let things catch up....
3600 gr_screen.bytes_per_pixel = 2;
3601 gr_screen.bits_per_pixel = 16;
3604 grGlideGetVersion(version);
3605 mprintf(( "Glide version: %s\n", version ));
3607 if ( !grSstQueryHardware( &hwconfig )) {
3608 mprintf(( "Glide: Query hardaware failed!\n" ));
3617 if(hwconfig.SSTs[0].sstBoard.Voodoo2Config.fbRam >= 12){
3621 // choose resolution
3622 if((gr_screen.max_w == 1024) && (gr_screen.max_h == 768)){
3623 res_mode = GR_RESOLUTION_1024x768;
3625 res_mode = GR_RESOLUTION_640x480;
3628 int retval = grSstWinOpen( (DWORD)hwnd, res_mode, GR_REFRESH_60Hz, GR_COLORFORMAT_ABGR, GR_ORIGIN_UPPER_LEFT, 2, 1 );
3630 mprintf(( "Glide: grSstOpen failed!\n" ));
3636 Bm_pixel_format = BM_PIXEL_FORMAT_ARGB;
3638 // grChromakeyMode( GR_CHROMAKEY_ENABLE );
3639 // grChromakeyValue( 0x00FF00 );
3643 // Setup the surface format
3646 Gr_red.scale = 256/32;
3647 Gr_red.mask = 0x7C00;
3649 Gr_current_red = &Gr_red;
3653 Gr_green.scale = 256/32;
3654 Gr_green.mask = 0x03e0;
3655 Gr_t_green = Gr_green;
3656 Gr_current_green = &Gr_green;
3660 Gr_blue.scale = 256/32;
3661 Gr_blue.mask = 0x1F;
3662 Gr_t_blue = Gr_blue;
3663 Gr_current_blue = &Gr_blue;
3665 Gr_current_alpha = &Gr_alpha;
3667 glide_tcache_init();
3669 gr_glide_clip_cursor(1);
3671 grGammaCorrectionValue(1.0f);
3673 gr_screen.gf_flip = gr_glide_flip;
3674 gr_screen.gf_flip_window = gr_glide_flip_window;
3675 gr_screen.gf_set_clip = gr_glide_set_clip;
3676 gr_screen.gf_reset_clip = gr_glide_reset_clip;
3677 gr_screen.gf_set_font = grx_set_font;
3678 gr_screen.gf_set_color = gr_glide_set_color;
3679 gr_screen.gf_set_bitmap = gr_glide_set_bitmap;
3680 gr_screen.gf_create_shader = gr_glide_create_shader;
3681 gr_screen.gf_set_shader = gr_glide_set_shader;
3682 gr_screen.gf_clear = gr_glide_clear;
3684 // gr_screen.gf_bitmap = gr_glide_bitmap;
3685 // gr_screen.gf_bitmap_ex = gr_glide_bitmap_ex;
3687 gr_screen.gf_rect = gr_glide_rect;
3688 gr_screen.gf_shade = gr_glide_shade;
3689 gr_screen.gf_string = gr_glide_string;
3690 gr_screen.gf_circle = gr_glide_circle;
3692 gr_screen.gf_line = gr_glide_line;
3693 gr_screen.gf_aaline = gr_glide_aaline;
3694 gr_screen.gf_pixel = gr_glide_pixel;
3695 gr_screen.gf_scaler = gr_glide_scaler;
3696 gr_screen.gf_aascaler = gr_glide_aascaler;
3697 gr_screen.gf_tmapper = gr_glide_tmapper;
3699 gr_screen.gf_gradient = gr_glide_gradient;
3701 gr_screen.gf_set_palette = gr_glide_set_palette;
3702 gr_screen.gf_get_color = gr_glide_get_color;
3703 gr_screen.gf_init_color = gr_glide_init_color;
3704 gr_screen.gf_init_alphacolor = gr_glide_init_alphacolor;
3705 gr_screen.gf_set_color_fast = gr_glide_set_color_fast;
3706 gr_screen.gf_print_screen = gr_glide_print_screen;
3708 gr_screen.gf_aabitmap = gr_glide_aabitmap;
3709 gr_screen.gf_aabitmap_ex = gr_glide_aabitmap_ex;
3711 gr_screen.gf_fade_in = gr_glide_fade_in;
3712 gr_screen.gf_fade_out = gr_glide_fade_out;
3713 gr_screen.gf_flash = gr_glide_flash;
3715 gr_screen.gf_zbuffer_get = gr_glide_zbuffer_get;
3716 gr_screen.gf_zbuffer_set = gr_glide_zbuffer_set;
3717 gr_screen.gf_zbuffer_clear = gr_glide_zbuffer_clear;
3719 gr_screen.gf_save_screen = gr_glide_save_screen;
3720 gr_screen.gf_restore_screen = gr_glide_restore_screen;
3721 gr_screen.gf_free_screen = gr_glide_free_screen;
3723 // Screen dumping stuff
3724 gr_screen.gf_dump_frame_start = gr_glide_dump_frame_start;
3725 gr_screen.gf_dump_frame_stop = gr_glide_dump_frame_stop;
3726 gr_screen.gf_dump_frame = gr_glide_dump_frame;
3728 gr_screen.gf_set_gamma = gr_glide_set_gamma;
3730 // Lock/unlock stuff
3731 gr_screen.gf_lock = gr_glide_lock;
3732 gr_screen.gf_unlock = gr_glide_unlock;
3735 gr_screen.gf_get_region = gr_glide_get_region;
3738 gr_screen.gf_fog_set = gr_glide_fog_set;
3741 gr_screen.gf_get_pixel = gr_glide_get_pixel;
3744 gr_screen.gf_set_cull = gr_glide_set_cull;
3747 gr_screen.gf_cross_fade = gr_glide_cross_fade;
3750 gr_screen.gf_filter_set = gr_glide_filter_set;
3752 // texture cache set
3753 gr_screen.gf_tcache_set = glide_tcache_set;
3756 gr_screen.gf_set_clear_color = gr_glide_set_clear_color;
3760 // default linear fog table
3761 guFogGenerateLinear(Glide_linear_fogtable, 1.0f, 1000.0f);