1 /***************************************************************************
\r
4 begin : Sun Mar 08 2009
\r
5 copyright : (C) 1999-2009 by Pete Bernert
\r
6 web : www.pbernert.com
\r
7 ***************************************************************************/
\r
9 /***************************************************************************
\r
11 * This program is free software; you can redistribute it and/or modify *
\r
12 * it under the terms of the GNU General Public License as published by *
\r
13 * the Free Software Foundation; either version 2 of the License, or *
\r
14 * (at your option) any later version. See also the license.txt file for *
\r
15 * additional informations. *
\r
17 ***************************************************************************/
\r
23 #include "externals.h"
\r
27 #include "texture.h"
\r
30 ////////////////////////////////////////////////////////////////////////////////////
\r
33 #define SIGNBIT 0x800
\r
34 #define S_MASK 0xf000
\r
35 #define L_MASK 0xfffff000
\r
37 // ownscale: some ogl drivers have buggy texture matrix funcs, so it
\r
38 // is safer to calc sow/tow ourselves
\r
42 #define ST_FACSPRITE 255.99f
\r
43 #define ST_BFFACSPRITE 0.5f/256.0f
\r
44 #define ST_BFFACSPRITESORT 0.333f/256.0f
\r
46 #define ST_OFFSET 0.5f/256.0f;
\r
48 #define ST_FAC 255.99f
\r
49 #define ST_BFFAC 0.5f/256.0f
\r
50 #define ST_BFFACSORT 0.333f/256.0f
\r
52 #define ST_FACTRI 255.99f
\r
53 #define ST_BFFACTRI 0.5f/256.0f
\r
54 #define ST_BFFACTRISORT 0.333f/256.0f
\r
56 #define ST_FACVRAMX 255.0f
\r
57 #define ST_FACVRAM 256.0f
\r
59 ///////////////////////////////////////////////////////////////
\r
63 #define ST_BFFACSPRITE 0.5f
\r
64 #define ST_BFFACSPRITESORT 0.333f
\r
66 #define ST_BFFAC 0.5f
\r
67 #define ST_BFFACSORT 0.333f
\r
69 #define ST_BFFACTRI 0.5f
\r
70 #define ST_BFFACTRISORT 0.333f
\r
72 #define ST_OFFSET 0.5f;
\r
76 ////////////////////////////////////////////////////////////////////////////////////
\r
77 // draw globals; most will be initialized again later (by config or checks)
\r
79 BOOL bIsFirstFrame=TRUE;
\r
81 // resolution/ratio vars
\r
85 BOOL bKeepRatio=FALSE;
\r
88 // psx mask related vars
\r
90 BOOL bCheckMask=FALSE;
\r
93 unsigned short sSetMask=0;
\r
94 uint32_t lSetMask=0;
\r
96 // drawing/coord vars
\r
98 OGLVertex vertex[4];
\r
101 short sprtY,sprtX,sprtH,sprtW;
\r
106 BOOL bAdvancedBlend;
\r
108 BOOL bUseAntiAlias;
\r
110 int iUsePalTextures=1;
\r
111 BOOL bSnapShot=FALSE;
\r
112 BOOL bSmallAlpha=FALSE;
\r
115 // OGL extension support
\r
117 int iForceVSync=-1;
\r
120 BOOL bGLFastMovie=FALSE;
\r
123 PFNGLBLENDEQU glBlendEquationEXTEx=NULL;
\r
124 PFNGLCOLORTABLEEXT glColorTableEXTEx=NULL;
\r
126 // gfx card buffer infos
\r
129 int iZBufferDepth=0;
\r
130 GLbitfield uiBufferBits=GL_COLOR_BUFFER_BIT;
\r
132 ////////////////////////////////////////////////////////////////////////
\r
133 // Get extension infos (f.e. pal textures / packed pixels)
\r
134 ////////////////////////////////////////////////////////////////////////
\r
136 void GetExtInfos(void)
\r
138 BOOL bPacked=FALSE; // default: no packed pixel support
\r
140 bGLExt=FALSE; // default: no extensions
\r
141 bGLFastMovie=FALSE;
\r
143 if(strstr((char *)glGetString(GL_EXTENSIONS), // packed pixels available?
\r
144 "GL_EXT_packed_pixels"))
\r
145 bPacked=TRUE; // -> ok
\r
147 if(bPacked && bUse15bitMdec) // packed available and 15bit mdec wanted?
\r
148 bGLFastMovie=TRUE; // -> ok
\r
150 if(bPacked && (iTexQuality==1 || iTexQuality==2)) // packed available and 16 bit texture format?
\r
152 bGLFastMovie=TRUE; // -> ok
\r
156 if(iUseExts && // extension support wanted?
\r
157 (strstr((char *)glGetString(GL_EXTENSIONS),
\r
158 "GL_EXT_texture_edge_clamp") ||
\r
159 strstr((char *)glGetString(GL_EXTENSIONS), // -> check clamp support, if yes: use it
\r
160 "GL_SGIS_texture_edge_clamp")))
\r
161 iClampType=GL_TO_EDGE_CLAMP;
\r
162 else iClampType=GL_CLAMP;
\r
164 glColorTableEXTEx=(PFNGLCOLORTABLEEXT)NULL; // init ogl palette func pointer
\r
167 if(iGPUHeight!=1024 && // no pal textures in ZN mode (height=1024)!
\r
168 strstr((char *)glGetString(GL_EXTENSIONS), // otherwise: check ogl support
\r
169 "GL_EXT_paletted_texture"))
\r
171 iUsePalTextures=1; // -> wow, supported, get func pointer
\r
173 glColorTableEXTEx=(PFNGLCOLORTABLEEXT)glXGetProcAddress("glColorTableEXT");
\r
175 if(glColorTableEXTEx==NULL) iUsePalTextures=0; // -> ha, cheater... no func, no support
\r
177 else iUsePalTextures=0;
\r
183 ////////////////////////////////////////////////////////////////////////
\r
184 // Setup some stuff depending on user settings or in-game toggle
\r
185 ////////////////////////////////////////////////////////////////////////
\r
187 void SetExtGLFuncs(void)
\r
189 //----------------------------------------------------//
\r
191 SetFixes(); // update fix infos
\r
193 //----------------------------------------------------//
\r
195 if(iUseExts && !(dwActFixes&1024) && // extensions wanted? and not turned off by game fix?
\r
196 strstr((char *)glGetString(GL_EXTENSIONS), // and blend_subtract available?
\r
197 "GL_EXT_blend_subtract"))
\r
198 { // -> get ogl blend function pointer
\r
199 glBlendEquationEXTEx=(PFNGLBLENDEQU)glXGetProcAddress("glBlendEquationEXT");
\r
201 else // no subtract blending?
\r
203 if(glBlendEquationEXTEx) // -> change to additive blending (if subract was active)
\r
204 glBlendEquationEXTEx(FUNC_ADD_EXT);
\r
205 glBlendEquationEXTEx=(PFNGLBLENDEQU)NULL; // -> no more blend function pointer
\r
208 //----------------------------------------------------//
\r
210 if(iUseExts && bAdvancedBlend && // advanced blending wanted ?
\r
211 strstr((char *)glGetString(GL_EXTENSIONS), // and extension avail?
\r
212 "GL_EXT_texture_env_combine"))
\r
214 bUseMultiPass=FALSE;bGLBlend=TRUE; // -> no need for 2 passes, perfect
\r
216 glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, COMBINE_EXT);
\r
217 glTexEnvf(GL_TEXTURE_ENV, COMBINE_RGB_EXT, GL_MODULATE);
\r
218 glTexEnvf(GL_TEXTURE_ENV, COMBINE_ALPHA_EXT, GL_MODULATE);
\r
219 glTexEnvf(GL_TEXTURE_ENV, RGB_SCALE_EXT, 2.0f);
\r
221 else // no advanced blending wanted/available:
\r
223 if(bAdvancedBlend) bUseMultiPass=TRUE; // -> pseudo-advanced with 2 passes
\r
224 else bUseMultiPass=FALSE; // -> or simple 'bright color' mode
\r
225 bGLBlend=FALSE; // -> no ext blending!
\r
227 glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
\r
230 //----------------------------------------------------//
\r
231 // init standard tex quality 0-2, and big alpha mode 3
\r
233 if(!(dwActFixes&0x4000) && iFilterType && iTexQuality>=3)
\r
235 else bSmallAlpha=FALSE;
\r
237 if(bOpaquePass) // opaque mode?
\r
242 PalTexturedColourFn=CP8RGBA; // -> init col func
\r
247 PalTexturedColourFn=XP8RGBA; // -> init col func
\r
251 glAlphaFunc(GL_GREATER,0.49f);
\r
253 else // no opaque mode?
\r
255 TCF[0]=TCF[1]=P8RGBA;
\r
256 PalTexturedColourFn=P8RGBA; // -> init col func
\r
257 glAlphaFunc(GL_NOTEQUAL,0); // --> set alpha func
\r
260 //----------------------------------------------------//
\r
262 LoadSubTexFn=LoadSubTexturePageSort; // init load tex ptr
\r
264 giWantedFMT=GL_RGBA; // init ogl tex format
\r
266 switch(iTexQuality) // -> quality:
\r
268 //--------------------------------------------------//
\r
269 case 0: // -> don't care
\r
271 giWantedTYPE=GL_UNSIGNED_BYTE;
\r
273 //--------------------------------------------------//
\r
274 case 1: // -> R4G4B4A4
\r
277 giWantedRGBA=GL_RGBA4;
\r
278 giWantedTYPE=GL_UNSIGNED_SHORT_4_4_4_4_EXT;
\r
279 LoadSubTexFn=LoadPackedSubTexturePageSort;
\r
282 if(dwActFixes&32) PTCF[0]=CP4RGBA_0;
\r
283 else PTCF[0]=XP4RGBA_0;
\r
288 PTCF[0]=PTCF[1]=P4RGBA;
\r
293 giWantedRGBA=GL_RGBA4;
\r
294 giWantedTYPE=GL_UNSIGNED_BYTE;
\r
297 //--------------------------------------------------//
\r
298 case 2: // -> R5B5G5A1
\r
301 giWantedRGBA=GL_RGB5_A1;
\r
302 giWantedTYPE=GL_UNSIGNED_SHORT_5_5_5_1_EXT;
\r
303 LoadSubTexFn=LoadPackedSubTexturePageSort;
\r
306 if(dwActFixes&32) PTCF[0]=CP5RGBA_0;
\r
307 else PTCF[0]=XP5RGBA_0;
\r
312 PTCF[0]=PTCF[1]=P5RGBA;
\r
317 giWantedRGBA=GL_RGB5_A1;giWantedTYPE=GL_UNSIGNED_BYTE;
\r
320 //--------------------------------------------------//
\r
321 case 3: // -> R8G8B8A8
\r
322 giWantedRGBA=GL_RGBA8;
\r
323 giWantedTYPE=GL_UNSIGNED_BYTE;
\r
327 if(bOpaquePass) // opaque mode?
\r
329 if(dwActFixes&32) {TCF[0]=CP8RGBAEx_0;PalTexturedColourFn=CP8RGBAEx;}
\r
330 else {TCF[0]=XP8RGBAEx_0;PalTexturedColourFn=XP8RGBAEx;}
\r
331 TCF[1]=XP8RGBAEx_1;
\r
336 //--------------------------------------------------//
\r
337 case 4: // -> R8G8B8A8
\r
338 giWantedRGBA = GL_RGBA8;
\r
339 giWantedTYPE = GL_UNSIGNED_BYTE;
\r
341 if(strstr((char *)glGetString(GL_EXTENSIONS), // and extension avail?
\r
344 giWantedFMT = GL_BGRA_EXT;
\r
346 if(bOpaquePass) // opaque mode?
\r
350 if(dwActFixes&32) {TCF[0]=CP8BGRAEx_0;PalTexturedColourFn=CP8RGBAEx;}
\r
351 else {TCF[0]=XP8BGRAEx_0;PalTexturedColourFn=XP8RGBAEx;}
\r
352 TCF[1]=XP8BGRAEx_1;
\r
356 if(dwActFixes&32) {TCF[0]=CP8BGRA_0;PalTexturedColourFn=CP8RGBA;}
\r
357 else {TCF[0]=XP8BGRA_0;PalTexturedColourFn=XP8RGBA;}
\r
361 else // no opaque mode?
\r
363 TCF[0]=TCF[1]=P8BGRA; // -> init col func
\r
371 if(bOpaquePass) // opaque mode?
\r
373 if(dwActFixes&32) {TCF[0]=CP8RGBAEx_0;PalTexturedColourFn=CP8RGBAEx;}
\r
374 else {TCF[0]=XP8RGBAEx_0;PalTexturedColourFn=XP8RGBAEx;}
\r
375 TCF[1]=XP8RGBAEx_1;
\r
381 //--------------------------------------------------//
\r
384 bBlendEnable=FALSE; // init blending: off
\r
385 glDisable(GL_BLEND);
\r
387 SetScanTrans(); // init scan lines (if wanted)
\r
390 ////////////////////////////////////////////////////////////////////////
\r
391 // setup scan lines
\r
392 ////////////////////////////////////////////////////////////////////////
\r
394 #define R_TSP 0x00,0x45,0x00,0xff
\r
395 #define G_TSP 0x00,0x00,0x45,0xff
\r
396 #define B_TSP 0x45,0x00,0x00,0xff
\r
397 #define O_TSP 0x45,0x45,0x45,0xff
\r
398 #define N_TSP 0x00,0x00,0x00,0xff
\r
400 GLuint gTexScanName=0;
\r
402 GLubyte texscan[4][16]=
\r
404 {R_TSP, G_TSP, B_TSP, N_TSP},
\r
405 {O_TSP, N_TSP, O_TSP, N_TSP},
\r
406 {B_TSP, N_TSP, R_TSP, G_TSP},
\r
407 {O_TSP, N_TSP, O_TSP, N_TSP}
\r
410 void CreateScanLines(void)
\r
415 if(iScanBlend<0) // special scan mask mode
\r
417 glGenTextures(1, &gTexScanName);
\r
418 glBindTexture(GL_TEXTURE_2D, gTexScanName);
\r
420 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
\r
421 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
\r
422 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
\r
423 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
\r
424 glTexImage2D(GL_TEXTURE_2D, 0, 4, 4, 4, 0,GL_RGBA, GL_UNSIGNED_BYTE, texscan);
\r
426 else // otherwise simple lines in a display list
\r
428 uiScanLine=glGenLists(1);
\r
429 glNewList(uiScanLine,GL_COMPILE);
\r
431 for(y=0;y<iResY;y+=2)
\r
435 glVertex2f(iResX,y);
\r
436 glVertex2f(iResX,y+1);
\r
445 ////////////////////////////////////////////////////////////////////////
\r
447 ////////////////////////////////////////////////////////////////////////
\r
449 int GLinitialize()
\r
451 glViewport(rRatioRect.left, // init viewport by ratio rect
\r
452 iResY-(rRatioRect.top+rRatioRect.bottom),
\r
454 rRatioRect.bottom);
\r
456 glScissor(0, 0, iResX, iResY); // init clipping (fullscreen)
\r
457 glEnable(GL_SCISSOR_TEST);
\r
460 glMatrixMode(GL_TEXTURE); // init psx tex sow and tow if not "ownscale"
\r
462 glScalef(1.0f/255.99f,1.0f/255.99f,1.0f); // geforce precision hack
\r
465 glMatrixMode(GL_PROJECTION); // init projection with psx resolution
\r
467 glOrtho(0,PSXDisplay.DisplayMode.x,
\r
468 PSXDisplay.DisplayMode.y, 0, -1, 1);
\r
470 if(iZBufferDepth) // zbuffer?
\r
472 uiBufferBits=GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT;
\r
473 glEnable(GL_DEPTH_TEST);
\r
474 glDepthFunc(GL_ALWAYS);
\r
477 else // no zbuffer?
\r
479 uiBufferBits=GL_COLOR_BUFFER_BIT;
\r
480 glDisable(GL_DEPTH_TEST);
\r
483 glClearColor(0.0f, 0.0f, 0.0f, 0.0f); // first buffer clear
\r
484 glClear(uiBufferBits);
\r
486 if(bUseLines) // funny lines
\r
488 glPolygonMode(GL_FRONT, GL_LINE);
\r
489 glPolygonMode(GL_BACK, GL_LINE);
\r
491 else // or the real filled thing
\r
493 glPolygonMode(GL_FRONT, GL_FILL);
\r
494 glPolygonMode(GL_BACK, GL_FILL);
\r
497 MakeDisplayLists(); // lists for menu/opaque
\r
498 GetExtInfos(); // get ext infos
\r
499 SetExtGLFuncs(); // init all kind of stuff (tex function pointers)
\r
501 glEnable(GL_ALPHA_TEST); // wanna alpha test
\r
503 if(!bUseAntiAlias) // no anti-alias (default)
\r
505 glDisable(GL_LINE_SMOOTH);
\r
506 glDisable(GL_POLYGON_SMOOTH);
\r
507 glDisable(GL_POINT_SMOOTH);
\r
509 else // wanna try it? glitches galore...
\r
511 glHint(GL_PERSPECTIVE_CORRECTION_HINT,GL_NICEST);
\r
512 glEnable(GL_LINE_SMOOTH);
\r
513 glEnable(GL_POLYGON_SMOOTH);
\r
514 glEnable(GL_POINT_SMOOTH);
\r
515 glHint(GL_LINE_SMOOTH_HINT,GL_NICEST);
\r
516 glHint(GL_POINT_SMOOTH_HINT,GL_NICEST);
\r
517 glHint(GL_POLYGON_SMOOTH_HINT,GL_NICEST);
\r
520 ubGloAlpha=127; // init some drawing vars
\r
522 TWin.UScaleFactor = 1;
\r
523 TWin.VScaleFactor = 1;
\r
524 bDrawMultiPass=FALSE;
\r
528 if(bDrawDither) glEnable(GL_DITHER); // dither mode
\r
529 else glDisable(GL_DITHER);
\r
531 glDisable(GL_FOG); // turn all (currently) unused modes off
\r
532 glDisable(GL_LIGHTING);
\r
533 glDisable(GL_LOGIC_OP);
\r
534 glDisable(GL_STENCIL_TEST);
\r
535 glDisable(GL_TEXTURE_1D);
\r
536 glDisable(GL_TEXTURE_2D);
\r
537 glDisable(GL_CULL_FACE);
\r
539 glPixelTransferi(GL_RED_SCALE, 1); // to be sure:
\r
540 glPixelTransferi(GL_RED_BIAS, 0); // init more OGL vals
\r
541 glPixelTransferi(GL_GREEN_SCALE, 1);
\r
542 glPixelTransferi(GL_GREEN_BIAS, 0);
\r
543 glPixelTransferi(GL_BLUE_SCALE, 1);
\r
544 glPixelTransferi(GL_BLUE_BIAS, 0);
\r
545 glPixelTransferi(GL_ALPHA_SCALE, 1);
\r
546 glPixelTransferi(GL_ALPHA_BIAS, 0);
\r
548 printf(glGetString(GL_VENDOR)); // linux: tell user what is getting used
\r
550 printf(glGetString(GL_RENDERER));
\r
553 glFlush(); // we are done...
\r
556 CreateScanLines(); // setup scanline stuff (if wanted)
\r
558 CheckTextureMemory(); // check available tex memory
\r
560 if(bKeepRatio) SetAspectRatio(); // set ratio
\r
562 if(iShowFPS) // user wants FPS display on startup?
\r
564 ulKeybits|=KEY_SHOWFPS; // -> ok, turn display on
\r
569 bIsFirstFrame = FALSE; // we have survived the first frame :)
\r
574 ////////////////////////////////////////////////////////////////////////
\r
575 // clean up OGL stuff
\r
576 ////////////////////////////////////////////////////////////////////////
\r
580 KillDisplayLists(); // bye display lists
\r
582 if(iUseScanLines) // scanlines used?
\r
586 if(gTexScanName!=0) // some scanline tex?
\r
587 glDeleteTextures(1, &gTexScanName); // -> delete it
\r
590 else glDeleteLists(uiScanLine,1); // otherwise del scanline display list
\r
593 CleanupTextureStore(); // bye textures
\r
596 ////////////////////////////////////////////////////////////////////////
\r
597 ////////////////////////////////////////////////////////////////////////
\r
598 ////////////////////////////////////////////////////////////////////////
\r
600 ////////////////////////////////////////////////////////////////////////
\r
601 ////////////////////////////////////////////////////////////////////////
\r
602 ////////////////////////////////////////////////////////////////////////
\r
604 ////////////////////////////////////////////////////////////////////////
\r
606 ////////////////////////////////////////////////////////////////////////
\r
608 // please note: it is hardly do-able in a hw/accel plugin to get the
\r
609 // real psx polygon coord mapping right... the following
\r
610 // works not to bad with many games, though
\r
612 __inline BOOL CheckCoord4()
\r
616 if(((lx1-lx0)>CHKMAX_X) ||
\r
617 ((lx2-lx0)>CHKMAX_X))
\r
621 if((lx1-lx3)>CHKMAX_X) return TRUE;
\r
622 if((lx2-lx3)>CHKMAX_X) return TRUE;
\r
628 if((lx0-lx1)>CHKMAX_X) return TRUE;
\r
629 if((lx2-lx1)>CHKMAX_X) return TRUE;
\r
630 if((lx3-lx1)>CHKMAX_X) return TRUE;
\r
634 if((lx0-lx2)>CHKMAX_X) return TRUE;
\r
635 if((lx1-lx2)>CHKMAX_X) return TRUE;
\r
636 if((lx3-lx2)>CHKMAX_X) return TRUE;
\r
640 if(((lx1-lx3)>CHKMAX_X) ||
\r
641 ((lx2-lx3)>CHKMAX_X))
\r
645 if((lx1-lx0)>CHKMAX_X) return TRUE;
\r
646 if((lx2-lx0)>CHKMAX_X) return TRUE;
\r
654 if((ly1-ly0)>CHKMAX_Y) return TRUE;
\r
655 if((ly2-ly0)>CHKMAX_Y) return TRUE;
\r
659 if((ly0-ly1)>CHKMAX_Y) return TRUE;
\r
660 if((ly2-ly1)>CHKMAX_Y) return TRUE;
\r
661 if((ly3-ly1)>CHKMAX_Y) return TRUE;
\r
665 if((ly0-ly2)>CHKMAX_Y) return TRUE;
\r
666 if((ly1-ly2)>CHKMAX_Y) return TRUE;
\r
667 if((ly3-ly2)>CHKMAX_Y) return TRUE;
\r
671 if((ly1-ly3)>CHKMAX_Y) return TRUE;
\r
672 if((ly2-ly3)>CHKMAX_Y) return TRUE;
\r
678 __inline BOOL CheckCoord3()
\r
682 if((lx1-lx0)>CHKMAX_X) return TRUE;
\r
683 if((lx2-lx0)>CHKMAX_X) return TRUE;
\r
687 if((lx0-lx1)>CHKMAX_X) return TRUE;
\r
688 if((lx2-lx1)>CHKMAX_X) return TRUE;
\r
692 if((lx0-lx2)>CHKMAX_X) return TRUE;
\r
693 if((lx1-lx2)>CHKMAX_X) return TRUE;
\r
697 if((ly1-ly0)>CHKMAX_Y) return TRUE;
\r
698 if((ly2-ly0)>CHKMAX_Y) return TRUE;
\r
702 if((ly0-ly1)>CHKMAX_Y) return TRUE;
\r
703 if((ly2-ly1)>CHKMAX_Y) return TRUE;
\r
707 if((ly0-ly2)>CHKMAX_Y) return TRUE;
\r
708 if((ly1-ly2)>CHKMAX_Y) return TRUE;
\r
715 __inline BOOL CheckCoord2()
\r
719 if((lx1-lx0)>CHKMAX_X) return TRUE;
\r
723 if((lx0-lx1)>CHKMAX_X) return TRUE;
\r
727 if((ly1-ly0)>CHKMAX_Y) return TRUE;
\r
731 if((ly0-ly1)>CHKMAX_Y) return TRUE;
\r
738 //Lewpys "offsetline" func:
\r
740 void offsetline(void)
\r
742 float x0, x1, y0, y1, oolength, xl, yl;
\r
745 SetOGLDisplaySettings(1);
\r
747 if(!(dwActFixes&16))
\r
749 if((lx0 & SIGNBIT)) lx0|=S_MASK;
\r
751 if((lx1 & SIGNBIT)) lx1|=S_MASK;
\r
753 if((ly0 & SIGNBIT)) ly0|=S_MASK;
\r
755 if((ly1 & SIGNBIT)) ly1|=S_MASK;
\r
759 x0 = (float)(lx0 + PSXDisplay.CumulOffset.x);
\r
760 x1 = (float)(lx1 + PSXDisplay.CumulOffset.x);
\r
761 y0 = (float)(ly0 + PSXDisplay.CumulOffset.y);
\r
762 y1 = (float)(ly1 + PSXDisplay.CumulOffset.y);
\r
764 oolength = (float)1/((float)sqrt((y1 - y0)*(y1 - y0) + (x1 - x0)*(x1 - x0)) * (float)2);
\r
765 // oolength = (float)1/((float)sqrt(((y1 - y0)*(y1 - y0) + (x1 - x0)*(x1 - x0)) * (float)2));
\r
767 xl = (x1 - x0) * oolength;
\r
768 yl = (y1 - y0) * oolength;
\r
796 // Pete's way: a very easy (and hopefully fast) approach for lines
\r
797 // without sqrt... using a small float -> short cast trick :)
\r
799 #define VERTEX_OFFX 0.2f
\r
800 #define VERTEX_OFFY 0.2f
\r
802 BOOL offsetline(void)
\r
804 short x0,x1,y0,y1,dx,dy;float px,py;
\r
807 SetOGLDisplaySettings(1);
\r
809 if(!(dwActFixes&16))
\r
811 lx0=(short)(((int)lx0<<SIGNSHIFT)>>SIGNSHIFT);
\r
812 lx1=(short)(((int)lx1<<SIGNSHIFT)>>SIGNSHIFT);
\r
813 ly0=(short)(((int)ly0<<SIGNSHIFT)>>SIGNSHIFT);
\r
814 ly1=(short)(((int)ly1<<SIGNSHIFT)>>SIGNSHIFT);
\r
816 if(CheckCoord2()) return TRUE;
\r
819 x0 = (lx0 + PSXDisplay.CumulOffset.x)+1;
\r
820 x1 = (lx1 + PSXDisplay.CumulOffset.x)+1;
\r
821 y0 = (ly0 + PSXDisplay.CumulOffset.y)+1;
\r
822 y1 = (ly1 + PSXDisplay.CumulOffset.y)+1;
\r
832 if(dx>dy) py=-0.5f;
\r
833 else if(dx<dy) py= 0.5f;
\r
840 if(dx>dy) px= 0.5f;
\r
841 else if(dx<dy) px=-0.5f;
\r
851 if(dx>dy) px=-0.5f;
\r
852 else if(dx<dy) px= 0.5f;
\r
858 if(dx>dy) py=-0.5f;
\r
859 else if(dx<dy) py= 0.5f;
\r
864 vertex[0].x=(short)((float)x0-px);
\r
865 vertex[3].x=(short)((float)x0+py);
\r
867 vertex[0].y=(short)((float)y0-py);
\r
868 vertex[3].y=(short)((float)y0-px);
\r
870 vertex[1].x=(short)((float)x1-py);
\r
871 vertex[2].x=(short)((float)x1+px);
\r
873 vertex[1].y=(short)((float)y1+px);
\r
874 vertex[2].y=(short)((float)y1+py);
\r
876 if(vertex[0].x==vertex[3].x && // ortho rect? done
\r
877 vertex[1].x==vertex[2].x &&
\r
878 vertex[0].y==vertex[1].y &&
\r
879 vertex[2].y==vertex[3].y) return FALSE;
\r
880 if(vertex[0].x==vertex[1].x &&
\r
881 vertex[2].x==vertex[3].x &&
\r
882 vertex[0].y==vertex[3].y &&
\r
883 vertex[1].y==vertex[2].y) return FALSE;
\r
885 vertex[0].x-=VERTEX_OFFX; // otherwise a small offset
\r
886 vertex[0].y-=VERTEX_OFFY; // to get better accuracy
\r
887 vertex[1].x-=VERTEX_OFFX;
\r
888 vertex[1].y-=VERTEX_OFFY;
\r
889 vertex[2].x-=VERTEX_OFFX;
\r
890 vertex[2].y-=VERTEX_OFFY;
\r
891 vertex[3].x-=VERTEX_OFFX;
\r
892 vertex[3].y-=VERTEX_OFFY;
\r
897 /////////////////////////////////////////////////////////
\r
902 SetOGLDisplaySettings(1);
\r
904 if(!(dwActFixes&16))
\r
906 lx0=(short)(((int)lx0<<SIGNSHIFT)>>SIGNSHIFT);
\r
907 lx1=(short)(((int)lx1<<SIGNSHIFT)>>SIGNSHIFT);
\r
908 ly0=(short)(((int)ly0<<SIGNSHIFT)>>SIGNSHIFT);
\r
909 ly1=(short)(((int)ly1<<SIGNSHIFT)>>SIGNSHIFT);
\r
911 if(CheckCoord2()) return TRUE;
\r
914 vertex[0].x=lx0+PSXDisplay.CumulOffset.x;
\r
915 vertex[1].x=lx1+PSXDisplay.CumulOffset.x;
\r
916 vertex[0].y=ly0+PSXDisplay.CumulOffset.y;
\r
917 vertex[1].y=ly1+PSXDisplay.CumulOffset.y;
\r
922 /////////////////////////////////////////////////////////
\r
927 SetOGLDisplaySettings(1);
\r
929 if(!(dwActFixes&16))
\r
931 lx0=(short)(((int)lx0<<SIGNSHIFT)>>SIGNSHIFT);
\r
932 lx1=(short)(((int)lx1<<SIGNSHIFT)>>SIGNSHIFT);
\r
933 lx2=(short)(((int)lx2<<SIGNSHIFT)>>SIGNSHIFT);
\r
934 ly0=(short)(((int)ly0<<SIGNSHIFT)>>SIGNSHIFT);
\r
935 ly1=(short)(((int)ly1<<SIGNSHIFT)>>SIGNSHIFT);
\r
936 ly2=(short)(((int)ly2<<SIGNSHIFT)>>SIGNSHIFT);
\r
938 if(CheckCoord3()) return TRUE;
\r
941 vertex[0].x=lx0+PSXDisplay.CumulOffset.x;
\r
942 vertex[1].x=lx1+PSXDisplay.CumulOffset.x;
\r
943 vertex[2].x=lx2+PSXDisplay.CumulOffset.x;
\r
944 vertex[0].y=ly0+PSXDisplay.CumulOffset.y;
\r
945 vertex[1].y=ly1+PSXDisplay.CumulOffset.y;
\r
946 vertex[2].y=ly2+PSXDisplay.CumulOffset.y;
\r
951 /////////////////////////////////////////////////////////
\r
956 SetOGLDisplaySettings(1);
\r
958 if(!(dwActFixes&16))
\r
960 lx0=(short)(((int)lx0<<SIGNSHIFT)>>SIGNSHIFT);
\r
961 lx1=(short)(((int)lx1<<SIGNSHIFT)>>SIGNSHIFT);
\r
962 lx2=(short)(((int)lx2<<SIGNSHIFT)>>SIGNSHIFT);
\r
963 lx3=(short)(((int)lx3<<SIGNSHIFT)>>SIGNSHIFT);
\r
964 ly0=(short)(((int)ly0<<SIGNSHIFT)>>SIGNSHIFT);
\r
965 ly1=(short)(((int)ly1<<SIGNSHIFT)>>SIGNSHIFT);
\r
966 ly2=(short)(((int)ly2<<SIGNSHIFT)>>SIGNSHIFT);
\r
967 ly3=(short)(((int)ly3<<SIGNSHIFT)>>SIGNSHIFT);
\r
969 if(CheckCoord4()) return TRUE;
\r
972 vertex[0].x=lx0+PSXDisplay.CumulOffset.x;
\r
973 vertex[1].x=lx1+PSXDisplay.CumulOffset.x;
\r
974 vertex[2].x=lx2+PSXDisplay.CumulOffset.x;
\r
975 vertex[3].x=lx3+PSXDisplay.CumulOffset.x;
\r
976 vertex[0].y=ly0+PSXDisplay.CumulOffset.y;
\r
977 vertex[1].y=ly1+PSXDisplay.CumulOffset.y;
\r
978 vertex[2].y=ly2+PSXDisplay.CumulOffset.y;
\r
979 vertex[3].y=ly3+PSXDisplay.CumulOffset.y;
\r
984 /////////////////////////////////////////////////////////
\r
986 void offsetST(void)
\r
989 SetOGLDisplaySettings(1);
\r
991 if(!(dwActFixes&16))
\r
993 lx0=(short)(((int)lx0<<SIGNSHIFT)>>SIGNSHIFT);
\r
994 ly0=(short)(((int)ly0<<SIGNSHIFT)>>SIGNSHIFT);
\r
996 if(lx0<-512 && PSXDisplay.DrawOffset.x<=-512)
\r
999 if(ly0<-512 && PSXDisplay.DrawOffset.y<=-512)
\r
1004 ly2 = ly3 = ly0+sprtH;
\r
1006 lx1 = lx2 = lx0+sprtW;
\r
1008 vertex[0].x=lx0+PSXDisplay.CumulOffset.x;
\r
1009 vertex[1].x=lx1+PSXDisplay.CumulOffset.x;
\r
1010 vertex[2].x=lx2+PSXDisplay.CumulOffset.x;
\r
1011 vertex[3].x=lx3+PSXDisplay.CumulOffset.x;
\r
1012 vertex[0].y=ly0+PSXDisplay.CumulOffset.y;
\r
1013 vertex[1].y=ly1+PSXDisplay.CumulOffset.y;
\r
1014 vertex[2].y=ly2+PSXDisplay.CumulOffset.y;
\r
1015 vertex[3].y=ly3+PSXDisplay.CumulOffset.y;
\r
1018 /////////////////////////////////////////////////////////
\r
1020 void offsetScreenUpload(int Position)
\r
1022 if(bDisplayNotSet)
\r
1023 SetOGLDisplaySettings(1);
\r
1029 lmdx=xrUploadArea.x0;
\r
1030 lmdy=xrUploadArea.y0;
\r
1044 lx0-=PSXDisplay.DisplayPosition.x;
\r
1045 ly0-=PSXDisplay.DisplayPosition.y;
\r
1046 lx1-=PSXDisplay.DisplayPosition.x;
\r
1047 ly1-=PSXDisplay.DisplayPosition.y;
\r
1048 lx2-=PSXDisplay.DisplayPosition.x;
\r
1049 ly2-=PSXDisplay.DisplayPosition.y;
\r
1050 lx3-=PSXDisplay.DisplayPosition.x;
\r
1051 ly3-=PSXDisplay.DisplayPosition.y;
\r
1055 lx0-=PreviousPSXDisplay.DisplayPosition.x;
\r
1056 ly0-=PreviousPSXDisplay.DisplayPosition.y;
\r
1057 lx1-=PreviousPSXDisplay.DisplayPosition.x;
\r
1058 ly1-=PreviousPSXDisplay.DisplayPosition.y;
\r
1059 lx2-=PreviousPSXDisplay.DisplayPosition.x;
\r
1060 ly2-=PreviousPSXDisplay.DisplayPosition.y;
\r
1061 lx3-=PreviousPSXDisplay.DisplayPosition.x;
\r
1062 ly3-=PreviousPSXDisplay.DisplayPosition.y;
\r
1065 vertex[0].x=lx0 + PreviousPSXDisplay.Range.x0;
\r
1066 vertex[1].x=lx1 + PreviousPSXDisplay.Range.x0;
\r
1067 vertex[2].x=lx2 + PreviousPSXDisplay.Range.x0;
\r
1068 vertex[3].x=lx3 + PreviousPSXDisplay.Range.x0;
\r
1069 vertex[0].y=ly0 + PreviousPSXDisplay.Range.y0;
\r
1070 vertex[1].y=ly1 + PreviousPSXDisplay.Range.y0;
\r
1071 vertex[2].y=ly2 + PreviousPSXDisplay.Range.y0;
\r
1072 vertex[3].y=ly3 + PreviousPSXDisplay.Range.y0;
\r
1076 vertex[0].z=vertex[1].z=vertex[2].z=vertex[3].z=gl_z;
\r
1081 /////////////////////////////////////////////////////////
\r
1083 void offsetBlk(void)
\r
1085 if(bDisplayNotSet)
\r
1086 SetOGLDisplaySettings(1);
\r
1088 vertex[0].x=lx0-PSXDisplay.GDrawOffset.x + PreviousPSXDisplay.Range.x0;
\r
1089 vertex[1].x=lx1-PSXDisplay.GDrawOffset.x + PreviousPSXDisplay.Range.x0;
\r
1090 vertex[2].x=lx2-PSXDisplay.GDrawOffset.x + PreviousPSXDisplay.Range.x0;
\r
1091 vertex[3].x=lx3-PSXDisplay.GDrawOffset.x + PreviousPSXDisplay.Range.x0;
\r
1092 vertex[0].y=ly0-PSXDisplay.GDrawOffset.y + PreviousPSXDisplay.Range.y0;
\r
1093 vertex[1].y=ly1-PSXDisplay.GDrawOffset.y + PreviousPSXDisplay.Range.y0;
\r
1094 vertex[2].y=ly2-PSXDisplay.GDrawOffset.y + PreviousPSXDisplay.Range.y0;
\r
1095 vertex[3].y=ly3-PSXDisplay.GDrawOffset.y + PreviousPSXDisplay.Range.y0;
\r
1099 vertex[0].z=vertex[1].z=vertex[2].z=vertex[3].z=gl_z;
\r
1104 ////////////////////////////////////////////////////////////////////////
\r
1105 // texture sow/tow calculations
\r
1106 ////////////////////////////////////////////////////////////////////////
\r
1108 void assignTextureVRAMWrite(void)
\r
1112 vertex[0].sow=0.5f/ ST_FACVRAMX;
\r
1113 vertex[0].tow=0.5f/ ST_FACVRAM;
\r
1115 vertex[1].sow=(float)gl_ux[1]/ ST_FACVRAMX;
\r
1116 vertex[1].tow=0.5f/ ST_FACVRAM;
\r
1118 vertex[2].sow=(float)gl_ux[2]/ ST_FACVRAMX;
\r
1119 vertex[2].tow=(float)gl_vy[2]/ ST_FACVRAM;
\r
1121 vertex[3].sow=0.5f/ ST_FACVRAMX;
\r
1122 vertex[3].tow=(float)gl_vy[3]/ ST_FACVRAM;
\r
1128 vertex[0].sow=(gl_ux[0]*255.99f)/255.0f;
\r
1129 vertex[1].sow=(gl_ux[1]*255.99f)/255.0f;
\r
1130 vertex[2].sow=(gl_ux[2]*255.99f)/255.0f;
\r
1131 vertex[3].sow=(gl_ux[3]*255.99f)/255.0f;
\r
1135 vertex[0].sow=gl_ux[0];
\r
1136 vertex[1].sow=gl_ux[1];
\r
1137 vertex[2].sow=gl_ux[2];
\r
1138 vertex[3].sow=gl_ux[3];
\r
1141 vertex[0].tow=gl_vy[0];
\r
1142 vertex[1].tow=gl_vy[1];
\r
1143 vertex[2].tow=gl_vy[2];
\r
1144 vertex[3].tow=gl_vy[3];
\r
1149 GLuint gLastTex=0;
\r
1150 GLuint gLastFMode=(GLuint)-1;
\r
1152 /////////////////////////////////////////////////////////
\r
1154 void assignTextureSprite(void)
\r
1158 vertex[0].sow=vertex[3].sow=(float)gl_ux[0]/TWin.UScaleFactor;
\r
1159 vertex[1].sow=vertex[2].sow=(float)sSprite_ux2/TWin.UScaleFactor;
\r
1160 vertex[0].tow=vertex[1].tow=(float)gl_vy[0]/TWin.VScaleFactor;
\r
1161 vertex[2].tow=vertex[3].tow=(float)sSprite_vy2/TWin.VScaleFactor;
\r
1162 gLastTex=gTexName;
\r
1164 if(iFilterType>0 && iFilterType<3 && iHiResTextures!=2)
\r
1166 float fxmin=65536.0f,fxmax=0.0f,fymin=65536.0f,fymax=0.0f;int i;
\r
1170 if(vertex[i].sow<fxmin) fxmin=vertex[i].sow;
\r
1171 if(vertex[i].tow<fymin) fymin=vertex[i].tow;
\r
1172 if(vertex[i].sow>fxmax) fxmax=vertex[i].sow;
\r
1173 if(vertex[i].tow>fymax) fymax=vertex[i].tow;
\r
1179 if(vertex[i].sow==fxmin) vertex[i].sow+=0.375f/(float)TWin.Position.x1;
\r
1180 if(vertex[i].sow==fxmax) vertex[i].sow-=0.375f/(float)TWin.Position.x1;
\r
1181 if(vertex[i].tow==fymin) vertex[i].tow+=0.375f/(float)TWin.Position.y1;
\r
1182 if(vertex[i].tow==fymax) vertex[i].tow-=0.375f/(float)TWin.Position.y1;
\r
1184 if(vertex[i].sow==fxmin) vertex[i].sow+=96.0f/(float)TWin.Position.x1;
\r
1185 if(vertex[i].sow==fxmax) vertex[i].sow-=96.0f/(float)TWin.Position.x1;
\r
1186 if(vertex[i].tow==fymin) vertex[i].tow+=96.0f/(float)TWin.Position.y1;
\r
1187 if(vertex[i].tow==fymax) vertex[i].tow-=96.0f/(float)TWin.Position.y1;
\r
1197 vertex[0].sow=vertex[3].sow=(float)gl_ux[0] / ST_FACSPRITE;
\r
1198 vertex[1].sow=vertex[2].sow=(float)sSprite_ux2 / ST_FACSPRITE;
\r
1199 vertex[0].tow=vertex[1].tow=(float)gl_vy[0] / ST_FACSPRITE;
\r
1200 vertex[2].tow=vertex[3].tow=(float)sSprite_vy2 / ST_FACSPRITE;
\r
1204 vertex[0].sow=vertex[3].sow=gl_ux[0];
\r
1205 vertex[1].sow=vertex[2].sow=sSprite_ux2;
\r
1206 vertex[0].tow=vertex[1].tow=gl_vy[0];
\r
1207 vertex[2].tow=vertex[3].tow=sSprite_vy2;
\r
1211 if(iFilterType>2)
\r
1213 if(gLastTex!=gTexName || gLastFMode!=0)
\r
1215 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
\r
1216 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
\r
1217 gLastTex=gTexName;gLastFMode=0;
\r
1222 if(usMirror & 0x1000)
\r
1224 vertex[0].sow=vertex[1].sow;
\r
1225 vertex[1].sow=vertex[2].sow=vertex[3].sow;
\r
1226 vertex[3].sow=vertex[0].sow;
\r
1229 if(usMirror & 0x2000)
\r
1231 vertex[0].tow=vertex[3].tow;
\r
1232 vertex[2].tow=vertex[3].tow=vertex[1].tow;
\r
1233 vertex[1].tow=vertex[0].tow;
\r
1238 /////////////////////////////////////////////////////////
\r
1240 void assignTexture3(void)
\r
1244 vertex[0].sow=(float)gl_ux[0]/TWin.UScaleFactor;
\r
1245 vertex[0].tow=(float)gl_vy[0]/TWin.VScaleFactor;
\r
1246 vertex[1].sow=(float)gl_ux[1]/TWin.UScaleFactor;
\r
1247 vertex[1].tow=(float)gl_vy[1]/TWin.VScaleFactor;
\r
1248 vertex[2].sow=(float)gl_ux[2]/TWin.UScaleFactor;
\r
1249 vertex[2].tow=(float)gl_vy[2]/TWin.VScaleFactor;
\r
1250 gLastTex=gTexName;
\r
1255 vertex[0].sow=(float)gl_ux[0] / ST_FACTRI;
\r
1256 vertex[0].tow=(float)gl_vy[0] / ST_FACTRI;
\r
1257 vertex[1].sow=(float)gl_ux[1] / ST_FACTRI;
\r
1259 vertex[1].tow=(float)gl_vy[1] / ST_FACTRI;
\r
1260 vertex[2].sow=(float)gl_ux[2] / ST_FACTRI;
\r
1261 vertex[2].tow=(float)gl_vy[2] / ST_FACTRI;
\r
1263 vertex[0].sow=gl_ux[0];
\r
1264 vertex[0].tow=gl_vy[0];
\r
1265 vertex[1].sow=gl_ux[1];
\r
1266 vertex[1].tow=gl_vy[1];
\r
1267 vertex[2].sow=gl_ux[2];
\r
1268 vertex[2].tow=gl_vy[2];
\r
1271 if(iFilterType>2)
\r
1273 if(gLastTex!=gTexName || gLastFMode!=1)
\r
1275 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
\r
1276 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
\r
1277 gLastTex=gTexName;gLastFMode=1;
\r
1283 float fxmin=256.0f,fxmax=0.0f,fymin=256.0f,fymax=0.0f;int i;
\r
1286 if(vertex[i].sow<fxmin) fxmin=vertex[i].sow;
\r
1287 if(vertex[i].tow<fymin) fymin=vertex[i].tow;
\r
1288 if(vertex[i].sow>fxmax) fxmax=vertex[i].sow;
\r
1289 if(vertex[i].tow>fymax) fymax=vertex[i].tow;
\r
1294 if(vertex[i].sow==fxmin) vertex[i].sow+=ST_BFFACSORT;
\r
1295 if(vertex[i].sow==fxmax) vertex[i].sow-=ST_BFFACSORT;
\r
1296 if(vertex[i].tow==fymin) vertex[i].tow+=ST_BFFACSORT;
\r
1297 if(vertex[i].tow==fymax) vertex[i].tow-=ST_BFFACSORT;
\r
1303 /////////////////////////////////////////////////////////
\r
1305 void assignTexture4(void)
\r
1309 vertex[0].sow=(float)gl_ux[0]/TWin.UScaleFactor;
\r
1310 vertex[0].tow=(float)gl_vy[0]/TWin.VScaleFactor;
\r
1311 vertex[1].sow=(float)gl_ux[1]/TWin.UScaleFactor;
\r
1312 vertex[1].tow=(float)gl_vy[1]/TWin.VScaleFactor;
\r
1313 vertex[2].sow=(float)gl_ux[2]/TWin.UScaleFactor;
\r
1314 vertex[2].tow=(float)gl_vy[2]/TWin.VScaleFactor;
\r
1315 vertex[3].sow=(float)gl_ux[3]/TWin.UScaleFactor;
\r
1316 vertex[3].tow=(float)gl_vy[3]/TWin.VScaleFactor;
\r
1317 gLastTex=gTexName;
\r
1322 vertex[0].sow=(float)gl_ux[0] / ST_FAC;
\r
1323 vertex[0].tow=(float)gl_vy[0] / ST_FAC;
\r
1324 vertex[1].sow=(float)gl_ux[1] / ST_FAC;
\r
1325 vertex[1].tow=(float)gl_vy[1] / ST_FAC;
\r
1326 vertex[2].sow=(float)gl_ux[2] / ST_FAC;
\r
1327 vertex[2].tow=(float)gl_vy[2] / ST_FAC;
\r
1328 vertex[3].sow=(float)gl_ux[3] / ST_FAC;
\r
1329 vertex[3].tow=(float)gl_vy[3] / ST_FAC;
\r
1331 vertex[0].sow=gl_ux[0];
\r
1332 vertex[0].tow=gl_vy[0];
\r
1333 vertex[1].sow=gl_ux[1];
\r
1334 vertex[1].tow=gl_vy[1];
\r
1335 vertex[2].sow=gl_ux[2];
\r
1336 vertex[2].tow=gl_vy[2];
\r
1337 vertex[3].sow=gl_ux[3];
\r
1338 vertex[3].tow=gl_vy[3];
\r
1341 if(iFilterType>2)
\r
1343 if(gLastTex!=gTexName || gLastFMode!=1)
\r
1345 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
\r
1346 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
\r
1347 gLastTex=gTexName;gLastFMode=1;
\r
1353 float fxmin=256.0f,fxmax=0.0f,fymin=256.0f,fymax=0.0f;int i;
\r
1356 if(vertex[i].sow<fxmin) fxmin=vertex[i].sow;
\r
1357 if(vertex[i].tow<fymin) fymin=vertex[i].tow;
\r
1358 if(vertex[i].sow>fxmax) fxmax=vertex[i].sow;
\r
1359 if(vertex[i].tow>fymax) fymax=vertex[i].tow;
\r
1364 if(vertex[i].sow==fxmin) vertex[i].sow+=ST_BFFACSORT;
\r
1365 if(vertex[i].sow==fxmax) vertex[i].sow-=ST_BFFACSORT;
\r
1366 if(vertex[i].tow==fymin) vertex[i].tow+=ST_BFFACSORT;
\r
1367 if(vertex[i].tow==fymax) vertex[i].tow-=ST_BFFACSORT;
\r
1373 ////////////////////////////////////////////////////////////////////////
\r
1374 ////////////////////////////////////////////////////////////////////////
\r
1375 ////////////////////////////////////////////////////////////////////////
\r
1377 ////////////////////////////////////////////////////////////////////////
\r
1378 // render pos / buffers
\r
1379 ////////////////////////////////////////////////////////////////////////
\r
1381 #define EqualRect(pr1,pr2) ((pr1)->left==(pr2)->left && (pr1)->top==(pr2)->top && (pr1)->right==(pr2)->right && (pr1)->bottom==(pr2)->bottom)
\r
1383 ////////////////////////////////////////////////////////////////////////
\r
1384 // SetDisplaySettings: "simply" calcs the new drawing area and updates
\r
1385 // the ogl clipping (scissor)
\r
1387 BOOL bSetClip=FALSE;
\r
1389 void SetOGLDisplaySettings(BOOL DisplaySet)
\r
1391 static RECT rprev={0,0,0,0};
\r
1392 static RECT rC ={0,0,0,0};
\r
1393 static int iOldX=0;
\r
1394 static int iOldY=0;
\r
1395 RECT r;float XS,YS;
\r
1397 bDisplayNotSet = FALSE;
\r
1399 //----------------------------------------------------// that's a whole screen upload
\r
1403 PSXDisplay.GDrawOffset.x=0;
\r
1404 PSXDisplay.GDrawOffset.y=0;
\r
1406 PSXDisplay.CumulOffset.x = PSXDisplay.DrawOffset.x+PreviousPSXDisplay.Range.x0;
\r
1407 PSXDisplay.CumulOffset.y = PSXDisplay.DrawOffset.y+PreviousPSXDisplay.Range.y0;
\r
1409 rprev.left=rprev.left+1;
\r
1412 rX.top=iResY-(rRatioRect.top+rRatioRect.bottom);
\r
1414 if(bSetClip || !EqualRect(&rC,&rX))
\r
1417 glScissor(rC.left,rC.top,rC.right,rC.bottom);
\r
1422 //----------------------------------------------------//
\r
1424 PSXDisplay.GDrawOffset.y = PreviousPSXDisplay.DisplayPosition.y;
\r
1425 PSXDisplay.GDrawOffset.x = PreviousPSXDisplay.DisplayPosition.x;
\r
1426 PSXDisplay.CumulOffset.x = PSXDisplay.DrawOffset.x - PSXDisplay.GDrawOffset.x+PreviousPSXDisplay.Range.x0;
\r
1427 PSXDisplay.CumulOffset.y = PSXDisplay.DrawOffset.y - PSXDisplay.GDrawOffset.y+PreviousPSXDisplay.Range.y0;
\r
1429 r.top =PSXDisplay.DrawArea.y0 - PreviousPSXDisplay.DisplayPosition.y;
\r
1430 r.bottom=PSXDisplay.DrawArea.y1 - PreviousPSXDisplay.DisplayPosition.y;
\r
1432 if(r.bottom<0 || r.top>=PSXDisplay.DisplayMode.y)
\r
1434 r.top =PSXDisplay.DrawArea.y0 - PSXDisplay.DisplayPosition.y;
\r
1435 r.bottom=PSXDisplay.DrawArea.y1 - PSXDisplay.DisplayPosition.y;
\r
1438 r.left =PSXDisplay.DrawArea.x0 - PreviousPSXDisplay.DisplayPosition.x;
\r
1439 r.right =PSXDisplay.DrawArea.x1 - PreviousPSXDisplay.DisplayPosition.x;
\r
1441 if(r.right<0 || r.left>=PSXDisplay.DisplayMode.x)
\r
1443 r.left =PSXDisplay.DrawArea.x0 - PSXDisplay.DisplayPosition.x;
\r
1444 r.right =PSXDisplay.DrawArea.x1 - PSXDisplay.DisplayPosition.x;
\r
1447 if(!bSetClip && EqualRect(&r,&rprev) &&
\r
1448 iOldX == PSXDisplay.DisplayMode.x &&
\r
1449 iOldY == PSXDisplay.DisplayMode.y)
\r
1453 iOldX = PSXDisplay.DisplayMode.x;
\r
1454 iOldY = PSXDisplay.DisplayMode.y;
\r
1456 XS=(float)rRatioRect.right/(float)PSXDisplay.DisplayMode.x;
\r
1457 YS=(float)rRatioRect.bottom/(float)PSXDisplay.DisplayMode.y;
\r
1459 if(PreviousPSXDisplay.Range.x0)
\r
1461 short s=PreviousPSXDisplay.Range.x0+PreviousPSXDisplay.Range.x1;
\r
1463 r.left+=PreviousPSXDisplay.Range.x0+1;
\r
1465 r.right+=PreviousPSXDisplay.Range.x0;
\r
1467 if(r.left>s) r.left=s;
\r
1468 if(r.right>s) r.right=s;
\r
1471 if(PreviousPSXDisplay.Range.y0)
\r
1473 short s=PreviousPSXDisplay.Range.y0+PreviousPSXDisplay.Range.y1;
\r
1475 r.top+=PreviousPSXDisplay.Range.y0+1;
\r
1476 r.bottom+=PreviousPSXDisplay.Range.y0;
\r
1478 if(r.top>s) r.top=s;
\r
1479 if(r.bottom>s) r.bottom=s;
\r
1482 // Set the ClipArea variables to reflect the new screen,
\r
1483 // offset from zero (since it is a new display buffer)
\r
1484 r.left = (int)(((float)(r.left)) *XS);
\r
1485 r.top = (int)(((float)(r.top)) *YS);
\r
1486 r.right = (int)(((float)(r.right + 1))*XS);
\r
1487 r.bottom = (int)(((float)(r.bottom + 1))*YS);
\r
1489 // Limit clip area to the screen size
\r
1490 if (r.left > iResX) r.left = iResX;
\r
1491 if (r.left < 0) r.left = 0;
\r
1492 if (r.top > iResY) r.top = iResY;
\r
1493 if (r.top < 0) r.top = 0;
\r
1494 if (r.right > iResX) r.right = iResX;
\r
1495 if (r.right < 0) r.right = 0;
\r
1496 if (r.bottom > iResY) r.bottom = iResY;
\r
1497 if (r.bottom < 0) r.bottom = 0;
\r
1501 r.top=iResY-(r.top+r.bottom);
\r
1503 r.left+=rRatioRect.left;
\r
1504 r.top -=rRatioRect.top;
\r
1506 if(bSetClip || !EqualRect(&r,&rC))
\r
1508 glScissor(r.left,r.top,r.right,r.bottom);
\r
1514 ////////////////////////////////////////////////////////////////////////
\r
1515 ////////////////////////////////////////////////////////////////////////
\r
1516 ////////////////////////////////////////////////////////////////////////
\r