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
19 //*************************************************************************//
\r
20 // History of changes:
\r
22 // 2009/03/08 - Pete
\r
23 // - generic cleanup for the Peops release
\r
25 //*************************************************************************//
\r
31 #include "gpuExternals.h"
\r
32 #include "gpuPlugin.h"
\r
33 #include "gpuDraw.h"
\r
34 #include "gpuPrim.h"
\r
35 #include "gpuTexture.h"
\r
36 #include "gpuStdafx.h"
\r
43 ////////////////////////////////////////////////////////////////////////////////////
\r
46 #define SIGNBIT 0x800
\r
47 #define S_MASK 0xf000
\r
48 #define L_MASK 0xfffff000
\r
50 // ownscale: some ogl drivers have buggy texture matrix funcs, so it
\r
51 // is safer to calc sow/tow ourselves
\r
55 ///////////////////////////////////////////////////////////////
\r
57 #define ST_FACSPRITE 255.99f
\r
58 #define ST_BFFACSPRITE 0.5f/256.0f
\r
59 #define ST_BFFACSPRITESORT 0.333f/256.0f
\r
61 #define ST_OFFSET 0.5f/256.0f;
\r
63 #define ST_FAC 255.99f
\r
64 #define ST_BFFAC 0.5f/256.0f
\r
65 #define ST_BFFACSORT 0.333f/256.0f
\r
67 #define ST_FACTRI 255.99f
\r
68 #define ST_BFFACTRI 0.5f/256.0f
\r
69 #define ST_BFFACTRISORT 0.333f/256.0f
\r
71 #define ST_FACVRAMX 255.0f
\r
72 #define ST_FACVRAM 256.0f
\r
74 ///////////////////////////////////////////////////////////////
\r
78 #define ST_BFFACSPRITE 0.5f
\r
79 #define ST_BFFACSPRITESORT 0.333f
\r
81 #define ST_BFFAC 0.5f
\r
82 #define ST_BFFACSORT 0.333f
\r
84 #define ST_BFFACTRI 0.5f
\r
85 #define ST_BFFACTRISORT 0.333f
\r
87 #define ST_OFFSET 0.5f;
\r
91 ////////////////////////////////////////////////////////////////////////////////////
\r
94 void glBlendEquationEXT(GLenum mode);
\r
95 void glColorTableEXT(GLenum target, GLenum internalFormat, GLsizei width, GLenum format,GLenum type, const GLvoid *data);
\r
97 // draw globals; most will be initialized again later (by config or checks)
\r
99 BOOL bIsFirstFrame=TRUE;
\r
101 // resolution/ratio vars
\r
105 BOOL bKeepRatio=FALSE;
\r
108 // psx mask related vars
\r
110 BOOL bCheckMask=FALSE;
\r
113 unsigned short sSetMask=0;
\r
114 unsigned long lSetMask=0;
\r
116 // drawing/coord vars
\r
118 OGLVertex vertex[4];
\r
121 short sprtY,sprtX,sprtH,sprtW;
\r
126 BOOL bAdvancedBlend;
\r
128 // OGL extension support
\r
131 // gfx card buffer infos
\r
134 int iZBufferDepth=0;
\r
135 GLbitfield uiBufferBits=GL_COLOR_BUFFER_BIT;
\r
137 ////////////////////////////////////////////////////////////////////////
\r
138 ////////////////////////////////////////////////////////////////////////
\r
139 ////////////////////////////////////////////////////////////////////////
\r
141 ////////////////////////////////////////////////////////////////////////
\r
142 // Set OGL pixel format
\r
143 ////////////////////////////////////////////////////////////////////////
\r
146 ////////////////////////////////////////////////////////////////////////
\r
147 // Get extension infos (f.e. pal textures / packed pixels)
\r
148 ////////////////////////////////////////////////////////////////////////
\r
150 void GetExtInfos(void)
\r
152 BOOL bPacked=FALSE; // default: no packed pixel support
\r
154 if(strstr((char *)glGetString(GL_EXTENSIONS), // packed pixels available?
\r
155 "GL_EXT_packed_pixels"))
\r
156 bPacked=TRUE; // -> ok
\r
159 iClampType=GL_CLAMP_TO_EDGE;
\r
162 ////////////////////////////////////////////////////////////////////////
\r
163 // Setup some stuff depending on user settings or in-game toggle
\r
164 ////////////////////////////////////////////////////////////////////////
\r
166 void SetExtGLFuncs(void)
\r
168 //----------------------------------------------------//
\r
170 SetFixes(); // update fix infos
\r
172 //----------------------------------------------------//
\r
175 if(bAdvancedBlend) bUseMultiPass=TRUE; // -> pseudo-advanced with 2 passes
\r
176 else bUseMultiPass=FALSE; // -> or simple 'bright color' mode
\r
177 // bGLBlend=FALSE; // -> no ext blending!
\r
179 glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
\r
182 if(bOpaquePass) // opaque mode?
\r
187 PalTexturedColourFn=CP8RGBA; // -> init col func
\r
192 PalTexturedColourFn=XP8RGBA; // -> init col func
\r
196 glAlphaFuncx(GL_GREATER,0.49f);
\r
198 else // no opaque mode?
\r
200 TCF[0]=TCF[1]=P8RGBA;
\r
201 PalTexturedColourFn=P8RGBA; // -> init col func
\r
202 glAlphaFuncx(GL_NOTEQUAL,0); // --> set alpha func
\r
205 //----------------------------------------------------//
\r
207 LoadSubTexFn=LoadSubTexturePageSort; // init load tex ptr
\r
209 bBlendEnable=FALSE; // init blending: off
\r
210 glDisable(GL_BLEND);
\r
212 SetScanTrans(); // init scan lines (if wanted)
\r
215 ////////////////////////////////////////////////////////////////////////
\r
216 // setup scan lines
\r
217 ////////////////////////////////////////////////////////////////////////
\r
219 #define R_TSP 0x00,0x45,0x00,0xff
\r
220 #define G_TSP 0x00,0x00,0x45,0xff
\r
221 #define B_TSP 0x45,0x00,0x00,0xff
\r
222 #define O_TSP 0x45,0x45,0x45,0xff
\r
223 #define N_TSP 0x00,0x00,0x00,0xff
\r
225 GLuint gTexScanName=0;
\r
227 GLubyte texscan[4][16]=
\r
229 {R_TSP, G_TSP, B_TSP, N_TSP},
\r
230 {O_TSP, N_TSP, O_TSP, N_TSP},
\r
231 {B_TSP, N_TSP, R_TSP, G_TSP},
\r
232 {O_TSP, N_TSP, O_TSP, N_TSP}
\r
235 void CreateScanLines(void)
\r
239 ////////////////////////////////////////////////////////////////////////
\r
241 ////////////////////////////////////////////////////////////////////////
\r
248 EGLDisplay display;
\r
250 EGLContext context;
\r
251 EGLSurface surface;
\r
253 #if defined(USE_X11)
\r
254 #include "X11/Xlib.h"
\r
255 #include "X11/Xutil.h"
\r
256 #include "X11/Xatom.h"
\r
258 Window x11Window = 0;
\r
259 Display* x11Display = 0;
\r
260 long x11Screen = 0;
\r
261 XVisualInfo x11Visual;
\r
262 XVisualInfo* px11Visual = 0;
\r
263 Colormap x11Colormap = 0;
\r
266 EGLint attrib_list_fsaa[] =
\r
268 EGL_SURFACE_TYPE, EGL_WINDOW_BIT,
\r
269 EGL_BUFFER_SIZE, 0,
\r
270 EGL_DEPTH_SIZE, 16,
\r
271 EGL_SAMPLE_BUFFERS, 1,
\r
276 EGLint attrib_list[] =
\r
278 // EGL_DEPTH_SIZE, 16,
\r
282 bool TestEGLError(const char* pszLocation)
\r
285 eglGetError returns the last error that has happened using egl,
\r
286 not the status of the last called function. The user has to
\r
287 check after every single egl call or at least once every frame.
\r
289 EGLint iErr = eglGetError();
\r
290 if (iErr != EGL_SUCCESS)
\r
292 printf("%s failed (%d).\n", pszLocation, iErr);
\r
299 static void initEGL(void)
\r
301 printf ("GL init\n");
\r
304 EGLint majorVersion;
\r
305 EGLint minorVersion;
\r
306 #if defined(USE_X11)
\r
309 _NET_WM_STATE_REMOVE =0,
\r
310 _NET_WM_STATE_ADD = 1,
\r
311 _NET_WM_STATE_TOGGLE =2
\r
314 Window sRootWindow;
\r
315 XSetWindowAttributes sWA;
\r
316 unsigned int ui32Mask;
\r
320 EGLint *attribList = NULL;
\r
323 printf( "GLES: Using Full Scene Antialiasing\n" );
\r
324 attribList = attrib_list_fsaa;
\r
328 attribList = attrib_list;
\r
331 #if defined(USE_X11)
\r
332 // Initializes the display and screen
\r
333 x11Display = XOpenDisplay( ":0" );
\r
336 printf("GLES Error: Unable to open X display\n");
\r
338 x11Screen = XDefaultScreen( x11Display );
\r
340 // Gets the display parameters so we can pass the same parameters to the window to be created.
\r
341 sRootWindow = RootWindow(x11Display, x11Screen);
\r
342 i32Depth = DefaultDepth(x11Display, x11Screen);
\r
343 px11Visual = &x11Visual;
\r
344 XMatchVisualInfo( x11Display, x11Screen, i32Depth, TrueColor, px11Visual);
\r
347 printf("GLES Error: Unable to acquire visual\n");
\r
349 // Colormap of the specified visual type for the display.
\r
350 x11Colormap = XCreateColormap( x11Display, sRootWindow, px11Visual->visual, AllocNone );
\r
351 sWA.colormap = x11Colormap;
\r
353 // List of events to be handled by the application. Add to these for handling other events.
\r
354 sWA.event_mask = StructureNotifyMask | ExposureMask | ButtonPressMask | ButtonReleaseMask | KeyPressMask | KeyReleaseMask;
\r
356 // Display capabilities list.
\r
357 ui32Mask = CWBackPixel | CWBorderPixel | CWEventMask | CWColormap;
\r
359 // Creates the X11 window
\r
360 x11Window = XCreateWindow( x11Display, RootWindow(x11Display, x11Screen), 0, 0, iResX, iResY,
\r
361 0, CopyFromParent, InputOutput, CopyFromParent, ui32Mask, &sWA);
\r
363 // Make the window viewable and flush the output buffer.
\r
364 XMapWindow(x11Display, x11Window);
\r
365 XFlush(x11Display);
\r
367 // Make the window fullscreen
\r
368 unsigned char fullScreen = 1;
\r
369 Atom wmState = XInternAtom(x11Display, "_NET_WM_STATE", False);
\r
370 Atom wmFullScreen = XInternAtom(x11Display,"_NET_WM_STATE_FULLSCREEN", False);
\r
373 xev.xclient.type = ClientMessage;
\r
374 xev.xclient.serial = 0;
\r
375 xev.xclient.send_event = True;
\r
376 xev.xclient.window = x11Window;
\r
377 xev.xclient.message_type = wmState;
\r
378 xev.xclient.format = 32;
\r
379 xev.xclient.data.l[0] = (fullScreen ? _NET_WM_STATE_ADD : _NET_WM_STATE_REMOVE);
\r
380 xev.xclient.data.l[1] = wmFullScreen;
\r
381 xev.xclient.data.l[2] = 0;
\r
383 XSendEvent(x11Display, DefaultRootWindow(x11Display), False, SubstructureRedirectMask | SubstructureNotifyMask, &xev);
\r
385 display = eglGetDisplay( (EGLNativeDisplayType)x11Display );
\r
387 display = eglGetDisplay( (EGLNativeDisplayType)0 );
\r
390 if( display == EGL_NO_DISPLAY )
\r
392 printf( "GLES EGL Error: GL No Display\n" );
\r
395 if( !eglInitialize( display, &majorVersion, &minorVersion ) )
\r
397 printf( "GLES EGL Error: eglInitialize failed\n" );
\r
400 if( !eglChooseConfig( display, attribList, &config, 1, &numConfigs ) )
\r
402 printf( "GLES EGL Error: eglChooseConfig failed\n" );
\r
405 context = eglCreateContext( display, config, NULL, NULL );
\r
408 printf( "GLES EGL Error: eglCreateContext failed\n" );
\r
411 #if defined(USE_X11)
\r
412 surface = eglCreateWindowSurface( display, config, (EGLNativeDisplayType)x11Window, NULL );
\r
414 surface = eglCreateWindowSurface( display, config, (EGLNativeDisplayType)0, NULL );
\r
417 eglMakeCurrent( display, surface, surface, context );
\r
418 if (!TestEGLError("eglMakeCurrent"))
\r
419 printf("error eglMakeCurrent");
\r
421 printf("GLES Window Opened\n");
\r
424 int GLinitialize()
\r
428 //----------------------------------------------------//
\r
430 glViewport(rRatioRect.left, // init viewport by ratio rect
\r
431 iResY-(rRatioRect.top+rRatioRect.bottom),
\r
433 rRatioRect.bottom);
\r
435 glScissor(0, 0, iResX, iResY); // init clipping (fullscreen)
\r
436 glEnable(GL_SCISSOR_TEST);
\r
439 glMatrixMode(GL_TEXTURE); // init psx tex sow and tow if not "ownscale"
\r
441 glScalef(1.0f/255.99f,1.0f/255.99f,1.0f); // geforce precision hack
\r
444 glMatrixMode(GL_PROJECTION); // init projection with psx resolution
\r
446 glOrtho(0,PSXDisplay.DisplayMode.x,
\r
447 PSXDisplay.DisplayMode.y, 0, -1, 1);
\r
449 if(iZBufferDepth) // zbuffer?
\r
451 uiBufferBits=GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT;
\r
452 glEnable(GL_DEPTH_TEST);
\r
453 glDepthFunc(GL_ALWAYS);
\r
456 else // no zbuffer?
\r
458 uiBufferBits=GL_COLOR_BUFFER_BIT;
\r
459 glDisable(GL_DEPTH_TEST);
\r
462 glClearColor(0.0f, 0.0f, 0.0f, 0.0f); // first buffer clear
\r
463 glClear(uiBufferBits);
\r
465 GetExtInfos(); // get ext infos
\r
466 SetExtGLFuncs(); // init all kind of stuff (tex function pointers)
\r
468 glEnable(GL_ALPHA_TEST); // wanna alpha test
\r
471 glDisable(GL_LINE_SMOOTH);
\r
472 glDisable(GL_POINT_SMOOTH);
\r
475 ubGloAlpha=127; // init some drawing vars
\r
477 TWin.UScaleFactor = 1;
\r
478 TWin.VScaleFactor = 1;
\r
479 bDrawMultiPass=FALSE;
\r
483 if(bDrawDither) glEnable(GL_DITHER); // dither mode
\r
484 else glDisable(GL_DITHER);
\r
486 glDisable(GL_FOG); // turn all (currently) unused modes off
\r
487 glDisable(GL_LIGHTING);
\r
488 glDisable(GL_STENCIL_TEST);
\r
489 glDisable(GL_TEXTURE_2D);
\r
490 glDisable(GL_CULL_FACE);
\r
492 glFlush(); // we are done...
\r
495 CreateScanLines(); // setup scanline stuff (if wanted)
\r
497 CheckTextureMemory(); // check available tex memory
\r
499 if(bKeepRatio) SetAspectRatio(); // set ratio
\r
502 bIsFirstFrame = FALSE; // we have survived the first frame :)
\r
507 ////////////////////////////////////////////////////////////////////////
\r
508 // clean up OGL stuff
\r
509 ////////////////////////////////////////////////////////////////////////
\r
513 CleanupTextureStore(); // bye textures
\r
515 eglMakeCurrent( display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT );
\r
516 eglDestroySurface( display, surface );
\r
517 eglDestroyContext( display, context );
\r
518 eglTerminate( display );
\r
520 #if defined(USE_X11)
\r
521 if (x11Window) XDestroyWindow(x11Display, x11Window);
\r
522 if (x11Colormap) XFreeColormap( x11Display, x11Colormap );
\r
523 if (x11Display) XCloseDisplay(x11Display);
\r
527 ////////////////////////////////////////////////////////////////////////
\r
528 ////////////////////////////////////////////////////////////////////////
\r
529 ////////////////////////////////////////////////////////////////////////
\r
531 ////////////////////////////////////////////////////////////////////////
\r
532 ////////////////////////////////////////////////////////////////////////
\r
533 ////////////////////////////////////////////////////////////////////////
\r
535 ////////////////////////////////////////////////////////////////////////
\r
537 ////////////////////////////////////////////////////////////////////////
\r
539 // please note: it is hardly do-able in a hw/accel plugin to get the
\r
540 // real psx polygon coord mapping right... the following
\r
541 // works not to bad with many games, though
\r
543 __inline BOOL CheckCoord4()
\r
547 if(((lx1-lx0)>CHKMAX_X) ||
\r
548 ((lx2-lx0)>CHKMAX_X))
\r
552 if((lx1-lx3)>CHKMAX_X) return TRUE;
\r
553 if((lx2-lx3)>CHKMAX_X) return TRUE;
\r
559 if((lx0-lx1)>CHKMAX_X) return TRUE;
\r
560 if((lx2-lx1)>CHKMAX_X) return TRUE;
\r
561 if((lx3-lx1)>CHKMAX_X) return TRUE;
\r
565 if((lx0-lx2)>CHKMAX_X) return TRUE;
\r
566 if((lx1-lx2)>CHKMAX_X) return TRUE;
\r
567 if((lx3-lx2)>CHKMAX_X) return TRUE;
\r
571 if(((lx1-lx3)>CHKMAX_X) ||
\r
572 ((lx2-lx3)>CHKMAX_X))
\r
576 if((lx1-lx0)>CHKMAX_X) return TRUE;
\r
577 if((lx2-lx0)>CHKMAX_X) return TRUE;
\r
585 if((ly1-ly0)>CHKMAX_Y) return TRUE;
\r
586 if((ly2-ly0)>CHKMAX_Y) return TRUE;
\r
590 if((ly0-ly1)>CHKMAX_Y) return TRUE;
\r
591 if((ly2-ly1)>CHKMAX_Y) return TRUE;
\r
592 if((ly3-ly1)>CHKMAX_Y) return TRUE;
\r
596 if((ly0-ly2)>CHKMAX_Y) return TRUE;
\r
597 if((ly1-ly2)>CHKMAX_Y) return TRUE;
\r
598 if((ly3-ly2)>CHKMAX_Y) return TRUE;
\r
602 if((ly1-ly3)>CHKMAX_Y) return TRUE;
\r
603 if((ly2-ly3)>CHKMAX_Y) return TRUE;
\r
609 __inline BOOL CheckCoord3()
\r
613 if((lx1-lx0)>CHKMAX_X) return TRUE;
\r
614 if((lx2-lx0)>CHKMAX_X) return TRUE;
\r
618 if((lx0-lx1)>CHKMAX_X) return TRUE;
\r
619 if((lx2-lx1)>CHKMAX_X) return TRUE;
\r
623 if((lx0-lx2)>CHKMAX_X) return TRUE;
\r
624 if((lx1-lx2)>CHKMAX_X) return TRUE;
\r
628 if((ly1-ly0)>CHKMAX_Y) return TRUE;
\r
629 if((ly2-ly0)>CHKMAX_Y) return TRUE;
\r
633 if((ly0-ly1)>CHKMAX_Y) return TRUE;
\r
634 if((ly2-ly1)>CHKMAX_Y) return TRUE;
\r
638 if((ly0-ly2)>CHKMAX_Y) return TRUE;
\r
639 if((ly1-ly2)>CHKMAX_Y) return TRUE;
\r
646 __inline BOOL CheckCoord2()
\r
650 if((lx1-lx0)>CHKMAX_X) return TRUE;
\r
654 if((lx0-lx1)>CHKMAX_X) return TRUE;
\r
658 if((ly1-ly0)>CHKMAX_Y) return TRUE;
\r
662 if((ly0-ly1)>CHKMAX_Y) return TRUE;
\r
668 // Pete's way: a very easy (and hopefully fast) approach for lines
\r
669 // without sqrt... using a small float -> short cast trick :)
\r
671 #define VERTEX_OFFX 0.2f
\r
672 #define VERTEX_OFFY 0.2f
\r
674 BOOL offsetline(void)
\r
676 short x0,x1,y0,y1,dx,dy;float px,py;
\r
679 SetOGLDisplaySettings(1);
\r
681 if(!(dwActFixes&16))
\r
683 lx0=(short)(((int)lx0<<SIGNSHIFT)>>SIGNSHIFT);
\r
684 lx1=(short)(((int)lx1<<SIGNSHIFT)>>SIGNSHIFT);
\r
685 ly0=(short)(((int)ly0<<SIGNSHIFT)>>SIGNSHIFT);
\r
686 ly1=(short)(((int)ly1<<SIGNSHIFT)>>SIGNSHIFT);
\r
688 if(CheckCoord2()) return TRUE;
\r
691 x0 = (lx0 + PSXDisplay.CumulOffset.x)+1;
\r
692 x1 = (lx1 + PSXDisplay.CumulOffset.x)+1;
\r
693 y0 = (ly0 + PSXDisplay.CumulOffset.y)+1;
\r
694 y1 = (ly1 + PSXDisplay.CumulOffset.y)+1;
\r
704 if(dx>dy) py=-0.5f;
\r
705 else if(dx<dy) py= 0.5f;
\r
712 if(dx>dy) px= 0.5f;
\r
713 else if(dx<dy) px=-0.5f;
\r
723 if(dx>dy) px=-0.5f;
\r
724 else if(dx<dy) px= 0.5f;
\r
730 if(dx>dy) py=-0.5f;
\r
731 else if(dx<dy) py= 0.5f;
\r
736 vertex[0].x=(short)((float)x0-px);
\r
737 vertex[3].x=(short)((float)x0+py);
\r
739 vertex[0].y=(short)((float)y0-py);
\r
740 vertex[3].y=(short)((float)y0-px);
\r
742 vertex[1].x=(short)((float)x1-py);
\r
743 vertex[2].x=(short)((float)x1+px);
\r
745 vertex[1].y=(short)((float)y1+px);
\r
746 vertex[2].y=(short)((float)y1+py);
\r
748 if(vertex[0].x==vertex[3].x && // ortho rect? done
\r
749 vertex[1].x==vertex[2].x &&
\r
750 vertex[0].y==vertex[1].y &&
\r
751 vertex[2].y==vertex[3].y) return FALSE;
\r
752 if(vertex[0].x==vertex[1].x &&
\r
753 vertex[2].x==vertex[3].x &&
\r
754 vertex[0].y==vertex[3].y &&
\r
755 vertex[1].y==vertex[2].y) return FALSE;
\r
757 vertex[0].x-=VERTEX_OFFX; // otherwise a small offset
\r
758 vertex[0].y-=VERTEX_OFFY; // to get better accuracy
\r
759 vertex[1].x-=VERTEX_OFFX;
\r
760 vertex[1].y-=VERTEX_OFFY;
\r
761 vertex[2].x-=VERTEX_OFFX;
\r
762 vertex[2].y-=VERTEX_OFFY;
\r
763 vertex[3].x-=VERTEX_OFFX;
\r
764 vertex[3].y-=VERTEX_OFFY;
\r
769 /////////////////////////////////////////////////////////
\r
774 SetOGLDisplaySettings(1);
\r
776 if(!(dwActFixes&16))
\r
778 lx0=(short)(((int)lx0<<SIGNSHIFT)>>SIGNSHIFT);
\r
779 lx1=(short)(((int)lx1<<SIGNSHIFT)>>SIGNSHIFT);
\r
780 ly0=(short)(((int)ly0<<SIGNSHIFT)>>SIGNSHIFT);
\r
781 ly1=(short)(((int)ly1<<SIGNSHIFT)>>SIGNSHIFT);
\r
783 if(CheckCoord2()) return TRUE;
\r
786 vertex[0].x=lx0+PSXDisplay.CumulOffset.x;
\r
787 vertex[1].x=lx1+PSXDisplay.CumulOffset.x;
\r
788 vertex[0].y=ly0+PSXDisplay.CumulOffset.y;
\r
789 vertex[1].y=ly1+PSXDisplay.CumulOffset.y;
\r
794 /////////////////////////////////////////////////////////
\r
799 SetOGLDisplaySettings(1);
\r
801 if(!(dwActFixes&16))
\r
803 lx0=(short)(((int)lx0<<SIGNSHIFT)>>SIGNSHIFT);
\r
804 lx1=(short)(((int)lx1<<SIGNSHIFT)>>SIGNSHIFT);
\r
805 lx2=(short)(((int)lx2<<SIGNSHIFT)>>SIGNSHIFT);
\r
806 ly0=(short)(((int)ly0<<SIGNSHIFT)>>SIGNSHIFT);
\r
807 ly1=(short)(((int)ly1<<SIGNSHIFT)>>SIGNSHIFT);
\r
808 ly2=(short)(((int)ly2<<SIGNSHIFT)>>SIGNSHIFT);
\r
810 if(CheckCoord3()) return TRUE;
\r
813 vertex[0].x=lx0+PSXDisplay.CumulOffset.x;
\r
814 vertex[1].x=lx1+PSXDisplay.CumulOffset.x;
\r
815 vertex[2].x=lx2+PSXDisplay.CumulOffset.x;
\r
816 vertex[0].y=ly0+PSXDisplay.CumulOffset.y;
\r
817 vertex[1].y=ly1+PSXDisplay.CumulOffset.y;
\r
818 vertex[2].y=ly2+PSXDisplay.CumulOffset.y;
\r
823 /////////////////////////////////////////////////////////
\r
828 SetOGLDisplaySettings(1);
\r
830 if(!(dwActFixes&16))
\r
832 lx0=(short)(((int)lx0<<SIGNSHIFT)>>SIGNSHIFT);
\r
833 lx1=(short)(((int)lx1<<SIGNSHIFT)>>SIGNSHIFT);
\r
834 lx2=(short)(((int)lx2<<SIGNSHIFT)>>SIGNSHIFT);
\r
835 lx3=(short)(((int)lx3<<SIGNSHIFT)>>SIGNSHIFT);
\r
836 ly0=(short)(((int)ly0<<SIGNSHIFT)>>SIGNSHIFT);
\r
837 ly1=(short)(((int)ly1<<SIGNSHIFT)>>SIGNSHIFT);
\r
838 ly2=(short)(((int)ly2<<SIGNSHIFT)>>SIGNSHIFT);
\r
839 ly3=(short)(((int)ly3<<SIGNSHIFT)>>SIGNSHIFT);
\r
841 if(CheckCoord4()) return TRUE;
\r
844 vertex[0].x=lx0+PSXDisplay.CumulOffset.x;
\r
845 vertex[1].x=lx1+PSXDisplay.CumulOffset.x;
\r
846 vertex[2].x=lx2+PSXDisplay.CumulOffset.x;
\r
847 vertex[3].x=lx3+PSXDisplay.CumulOffset.x;
\r
848 vertex[0].y=ly0+PSXDisplay.CumulOffset.y;
\r
849 vertex[1].y=ly1+PSXDisplay.CumulOffset.y;
\r
850 vertex[2].y=ly2+PSXDisplay.CumulOffset.y;
\r
851 vertex[3].y=ly3+PSXDisplay.CumulOffset.y;
\r
856 /////////////////////////////////////////////////////////
\r
858 void offsetST(void)
\r
861 SetOGLDisplaySettings(1);
\r
863 if(!(dwActFixes&16))
\r
865 lx0=(short)(((int)lx0<<SIGNSHIFT)>>SIGNSHIFT);
\r
866 ly0=(short)(((int)ly0<<SIGNSHIFT)>>SIGNSHIFT);
\r
868 if(lx0<-512 && PSXDisplay.DrawOffset.x<=-512)
\r
871 if(ly0<-512 && PSXDisplay.DrawOffset.y<=-512)
\r
876 ly2 = ly3 = ly0+sprtH;
\r
878 lx1 = lx2 = lx0+sprtW;
\r
880 vertex[0].x=lx0+PSXDisplay.CumulOffset.x;
\r
881 vertex[1].x=lx1+PSXDisplay.CumulOffset.x;
\r
882 vertex[2].x=lx2+PSXDisplay.CumulOffset.x;
\r
883 vertex[3].x=lx3+PSXDisplay.CumulOffset.x;
\r
884 vertex[0].y=ly0+PSXDisplay.CumulOffset.y;
\r
885 vertex[1].y=ly1+PSXDisplay.CumulOffset.y;
\r
886 vertex[2].y=ly2+PSXDisplay.CumulOffset.y;
\r
887 vertex[3].y=ly3+PSXDisplay.CumulOffset.y;
\r
890 /////////////////////////////////////////////////////////
\r
892 void offsetScreenUpload(long Position)
\r
895 SetOGLDisplaySettings(1);
\r
901 lmdx=xrUploadArea.x0;
\r
902 lmdy=xrUploadArea.y0;
\r
916 lx0-=PSXDisplay.DisplayPosition.x;
\r
917 ly0-=PSXDisplay.DisplayPosition.y;
\r
918 lx1-=PSXDisplay.DisplayPosition.x;
\r
919 ly1-=PSXDisplay.DisplayPosition.y;
\r
920 lx2-=PSXDisplay.DisplayPosition.x;
\r
921 ly2-=PSXDisplay.DisplayPosition.y;
\r
922 lx3-=PSXDisplay.DisplayPosition.x;
\r
923 ly3-=PSXDisplay.DisplayPosition.y;
\r
927 lx0-=PreviousPSXDisplay.DisplayPosition.x;
\r
928 ly0-=PreviousPSXDisplay.DisplayPosition.y;
\r
929 lx1-=PreviousPSXDisplay.DisplayPosition.x;
\r
930 ly1-=PreviousPSXDisplay.DisplayPosition.y;
\r
931 lx2-=PreviousPSXDisplay.DisplayPosition.x;
\r
932 ly2-=PreviousPSXDisplay.DisplayPosition.y;
\r
933 lx3-=PreviousPSXDisplay.DisplayPosition.x;
\r
934 ly3-=PreviousPSXDisplay.DisplayPosition.y;
\r
937 vertex[0].x=lx0 + PreviousPSXDisplay.Range.x0;
\r
938 vertex[1].x=lx1 + PreviousPSXDisplay.Range.x0;
\r
939 vertex[2].x=lx2 + PreviousPSXDisplay.Range.x0;
\r
940 vertex[3].x=lx3 + PreviousPSXDisplay.Range.x0;
\r
941 vertex[0].y=ly0 + PreviousPSXDisplay.Range.y0;
\r
942 vertex[1].y=ly1 + PreviousPSXDisplay.Range.y0;
\r
943 vertex[2].y=ly2 + PreviousPSXDisplay.Range.y0;
\r
944 vertex[3].y=ly3 + PreviousPSXDisplay.Range.y0;
\r
948 vertex[0].z=vertex[1].z=vertex[2].z=vertex[3].z=gl_z;
\r
953 /////////////////////////////////////////////////////////
\r
955 void offsetBlk(void)
\r
958 SetOGLDisplaySettings(1);
\r
960 vertex[0].x=lx0-PSXDisplay.GDrawOffset.x + PreviousPSXDisplay.Range.x0;
\r
961 vertex[1].x=lx1-PSXDisplay.GDrawOffset.x + PreviousPSXDisplay.Range.x0;
\r
962 vertex[2].x=lx2-PSXDisplay.GDrawOffset.x + PreviousPSXDisplay.Range.x0;
\r
963 vertex[3].x=lx3-PSXDisplay.GDrawOffset.x + PreviousPSXDisplay.Range.x0;
\r
964 vertex[0].y=ly0-PSXDisplay.GDrawOffset.y + PreviousPSXDisplay.Range.y0;
\r
965 vertex[1].y=ly1-PSXDisplay.GDrawOffset.y + PreviousPSXDisplay.Range.y0;
\r
966 vertex[2].y=ly2-PSXDisplay.GDrawOffset.y + PreviousPSXDisplay.Range.y0;
\r
967 vertex[3].y=ly3-PSXDisplay.GDrawOffset.y + PreviousPSXDisplay.Range.y0;
\r
971 vertex[0].z=vertex[1].z=vertex[2].z=vertex[3].z=gl_z;
\r
976 ////////////////////////////////////////////////////////////////////////
\r
977 // texture sow/tow calculations
\r
978 ////////////////////////////////////////////////////////////////////////
\r
980 void assignTextureVRAMWrite(void)
\r
984 vertex[0].sow=0.5f/ ST_FACVRAMX;
\r
985 vertex[0].tow=0.5f/ ST_FACVRAM;
\r
987 vertex[1].sow=(float)gl_ux[1]/ ST_FACVRAMX;
\r
988 vertex[1].tow=0.5f/ ST_FACVRAM;
\r
990 vertex[2].sow=(float)gl_ux[2]/ ST_FACVRAMX;
\r
991 vertex[2].tow=(float)gl_vy[2]/ ST_FACVRAM;
\r
993 vertex[3].sow=0.5f/ ST_FACVRAMX;
\r
994 vertex[3].tow=(float)gl_vy[3]/ ST_FACVRAM;
\r
1000 vertex[0].sow=(gl_ux[0]*255.99f)/255.0f;
\r
1001 vertex[1].sow=(gl_ux[1]*255.99f)/255.0f;
\r
1002 vertex[2].sow=(gl_ux[2]*255.99f)/255.0f;
\r
1003 vertex[3].sow=(gl_ux[3]*255.99f)/255.0f;
\r
1007 vertex[0].sow=gl_ux[0];
\r
1008 vertex[1].sow=gl_ux[1];
\r
1009 vertex[2].sow=gl_ux[2];
\r
1010 vertex[3].sow=gl_ux[3];
\r
1013 vertex[0].tow=gl_vy[0];
\r
1014 vertex[1].tow=gl_vy[1];
\r
1015 vertex[2].tow=gl_vy[2];
\r
1016 vertex[3].tow=gl_vy[3];
\r
1021 GLuint gLastTex=0;
\r
1022 GLuint gLastFMode=(GLuint)-1;
\r
1024 /////////////////////////////////////////////////////////
\r
1026 void assignTextureSprite(void)
\r
1030 vertex[0].sow=vertex[3].sow=(float)gl_ux[0]/TWin.UScaleFactor;
\r
1031 vertex[1].sow=vertex[2].sow=(float)sSprite_ux2/TWin.UScaleFactor;
\r
1032 vertex[0].tow=vertex[1].tow=(float)gl_vy[0]/TWin.VScaleFactor;
\r
1033 vertex[2].tow=vertex[3].tow=(float)sSprite_vy2/TWin.VScaleFactor;
\r
1034 gLastTex=gTexName;
\r
1040 vertex[0].sow=vertex[3].sow=(float)gl_ux[0] / ST_FACSPRITE;
\r
1041 vertex[1].sow=vertex[2].sow=(float)sSprite_ux2 / ST_FACSPRITE;
\r
1042 vertex[0].tow=vertex[1].tow=(float)gl_vy[0] / ST_FACSPRITE;
\r
1043 vertex[2].tow=vertex[3].tow=(float)sSprite_vy2 / ST_FACSPRITE;
\r
1047 vertex[0].sow=vertex[3].sow=gl_ux[0];
\r
1048 vertex[1].sow=vertex[2].sow=sSprite_ux2;
\r
1049 vertex[0].tow=vertex[1].tow=gl_vy[0];
\r
1050 vertex[2].tow=vertex[3].tow=sSprite_vy2;
\r
1054 if(iFilterType>2)
\r
1056 if(gLastTex!=gTexName || gLastFMode!=0)
\r
1058 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
\r
1059 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
\r
1060 gLastTex=gTexName;gLastFMode=0;
\r
1065 if(usMirror & 0x1000)
\r
1067 vertex[0].sow=vertex[1].sow;
\r
1068 vertex[1].sow=vertex[2].sow=vertex[3].sow;
\r
1069 vertex[3].sow=vertex[0].sow;
\r
1072 if(usMirror & 0x2000)
\r
1074 vertex[0].tow=vertex[3].tow;
\r
1075 vertex[2].tow=vertex[3].tow=vertex[1].tow;
\r
1076 vertex[1].tow=vertex[0].tow;
\r
1081 /////////////////////////////////////////////////////////
\r
1083 void assignTexture3(void)
\r
1087 vertex[0].sow=(float)gl_ux[0]/TWin.UScaleFactor;
\r
1088 vertex[0].tow=(float)gl_vy[0]/TWin.VScaleFactor;
\r
1089 vertex[1].sow=(float)gl_ux[1]/TWin.UScaleFactor;
\r
1090 vertex[1].tow=(float)gl_vy[1]/TWin.VScaleFactor;
\r
1091 vertex[2].sow=(float)gl_ux[2]/TWin.UScaleFactor;
\r
1092 vertex[2].tow=(float)gl_vy[2]/TWin.VScaleFactor;
\r
1093 gLastTex=gTexName;
\r
1098 vertex[0].sow=(float)gl_ux[0] / ST_FACTRI;
\r
1099 vertex[0].tow=(float)gl_vy[0] / ST_FACTRI;
\r
1100 vertex[1].sow=(float)gl_ux[1] / ST_FACTRI;
\r
1102 vertex[1].tow=(float)gl_vy[1] / ST_FACTRI;
\r
1103 vertex[2].sow=(float)gl_ux[2] / ST_FACTRI;
\r
1104 vertex[2].tow=(float)gl_vy[2] / ST_FACTRI;
\r
1106 vertex[0].sow=gl_ux[0];
\r
1107 vertex[0].tow=gl_vy[0];
\r
1108 vertex[1].sow=gl_ux[1];
\r
1109 vertex[1].tow=gl_vy[1];
\r
1110 vertex[2].sow=gl_ux[2];
\r
1111 vertex[2].tow=gl_vy[2];
\r
1114 if(iFilterType>2)
\r
1116 if(gLastTex!=gTexName || gLastFMode!=1)
\r
1118 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
\r
1119 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
\r
1120 gLastTex=gTexName;gLastFMode=1;
\r
1126 float fxmin=256.0f,fxmax=0.0f,fymin=256.0f,fymax=0.0f;int i;
\r
1129 if(vertex[i].sow<fxmin) fxmin=vertex[i].sow;
\r
1130 if(vertex[i].tow<fymin) fymin=vertex[i].tow;
\r
1131 if(vertex[i].sow>fxmax) fxmax=vertex[i].sow;
\r
1132 if(vertex[i].tow>fymax) fymax=vertex[i].tow;
\r
1137 if(vertex[i].sow==fxmin) vertex[i].sow+=ST_BFFACSORT;
\r
1138 if(vertex[i].sow==fxmax) vertex[i].sow-=ST_BFFACSORT;
\r
1139 if(vertex[i].tow==fymin) vertex[i].tow+=ST_BFFACSORT;
\r
1140 if(vertex[i].tow==fymax) vertex[i].tow-=ST_BFFACSORT;
\r
1146 /////////////////////////////////////////////////////////
\r
1148 void assignTexture4(void)
\r
1152 vertex[0].sow=(float)gl_ux[0]/TWin.UScaleFactor;
\r
1153 vertex[0].tow=(float)gl_vy[0]/TWin.VScaleFactor;
\r
1154 vertex[1].sow=(float)gl_ux[1]/TWin.UScaleFactor;
\r
1155 vertex[1].tow=(float)gl_vy[1]/TWin.VScaleFactor;
\r
1156 vertex[2].sow=(float)gl_ux[2]/TWin.UScaleFactor;
\r
1157 vertex[2].tow=(float)gl_vy[2]/TWin.VScaleFactor;
\r
1158 vertex[3].sow=(float)gl_ux[3]/TWin.UScaleFactor;
\r
1159 vertex[3].tow=(float)gl_vy[3]/TWin.VScaleFactor;
\r
1160 gLastTex=gTexName;
\r
1165 vertex[0].sow=(float)gl_ux[0] / ST_FAC;
\r
1166 vertex[0].tow=(float)gl_vy[0] / ST_FAC;
\r
1167 vertex[1].sow=(float)gl_ux[1] / ST_FAC;
\r
1168 vertex[1].tow=(float)gl_vy[1] / ST_FAC;
\r
1169 vertex[2].sow=(float)gl_ux[2] / ST_FAC;
\r
1170 vertex[2].tow=(float)gl_vy[2] / ST_FAC;
\r
1171 vertex[3].sow=(float)gl_ux[3] / ST_FAC;
\r
1172 vertex[3].tow=(float)gl_vy[3] / ST_FAC;
\r
1174 vertex[0].sow=gl_ux[0];
\r
1175 vertex[0].tow=gl_vy[0];
\r
1176 vertex[1].sow=gl_ux[1];
\r
1177 vertex[1].tow=gl_vy[1];
\r
1178 vertex[2].sow=gl_ux[2];
\r
1179 vertex[2].tow=gl_vy[2];
\r
1180 vertex[3].sow=gl_ux[3];
\r
1181 vertex[3].tow=gl_vy[3];
\r
1184 if(iFilterType>2)
\r
1186 if(gLastTex!=gTexName || gLastFMode!=1)
\r
1188 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
\r
1189 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
\r
1190 gLastTex=gTexName;gLastFMode=1;
\r
1196 float fxmin=256.0f,fxmax=0.0f,fymin=256.0f,fymax=0.0f;int i;
\r
1199 if(vertex[i].sow<fxmin) fxmin=vertex[i].sow;
\r
1200 if(vertex[i].tow<fymin) fymin=vertex[i].tow;
\r
1201 if(vertex[i].sow>fxmax) fxmax=vertex[i].sow;
\r
1202 if(vertex[i].tow>fymax) fymax=vertex[i].tow;
\r
1207 if(vertex[i].sow==fxmin) vertex[i].sow+=ST_BFFACSORT;
\r
1208 if(vertex[i].sow==fxmax) vertex[i].sow-=ST_BFFACSORT;
\r
1209 if(vertex[i].tow==fymin) vertex[i].tow+=ST_BFFACSORT;
\r
1210 if(vertex[i].tow==fymax) vertex[i].tow-=ST_BFFACSORT;
\r
1216 ////////////////////////////////////////////////////////////////////////
\r
1217 ////////////////////////////////////////////////////////////////////////
\r
1218 ////////////////////////////////////////////////////////////////////////
\r
1220 ////////////////////////////////////////////////////////////////////////
\r
1221 // render pos / buffers
\r
1222 ////////////////////////////////////////////////////////////////////////
\r
1224 #define EqualRect(pr1,pr2) ((pr1)->left==(pr2)->left && (pr1)->top==(pr2)->top && (pr1)->right==(pr2)->right && (pr1)->bottom==(pr2)->bottom)
\r
1226 ////////////////////////////////////////////////////////////////////////
\r
1227 // SetDisplaySettings: "simply" calcs the new drawing area and updates
\r
1228 // the ogl clipping (scissor)
\r
1230 BOOL bSetClip=FALSE;
\r
1232 void SetOGLDisplaySettings(BOOL DisplaySet)
\r
1234 static RECT rprev={0,0,0,0};
\r
1235 static RECT rC ={0,0,0,0};
\r
1236 static int iOldX=0;
\r
1237 static int iOldY=0;
\r
1238 RECT r;float XS,YS;
\r
1240 bDisplayNotSet = FALSE;
\r
1242 //----------------------------------------------------// that's a whole screen upload
\r
1246 PSXDisplay.GDrawOffset.x=0;
\r
1247 PSXDisplay.GDrawOffset.y=0;
\r
1249 PSXDisplay.CumulOffset.x = PSXDisplay.DrawOffset.x+PreviousPSXDisplay.Range.x0;
\r
1250 PSXDisplay.CumulOffset.y = PSXDisplay.DrawOffset.y+PreviousPSXDisplay.Range.y0;
\r
1252 rprev.left=rprev.left+1;
\r
1255 rX.top=iResY-(rRatioRect.top+rRatioRect.bottom);
\r
1257 if(bSetClip || !EqualRect(&rC,&rX))
\r
1260 glScissor(rC.left,rC.top,rC.right,rC.bottom);
\r
1265 //----------------------------------------------------//
\r
1267 PSXDisplay.GDrawOffset.y = PreviousPSXDisplay.DisplayPosition.y;
\r
1268 PSXDisplay.GDrawOffset.x = PreviousPSXDisplay.DisplayPosition.x;
\r
1269 PSXDisplay.CumulOffset.x = PSXDisplay.DrawOffset.x - PSXDisplay.GDrawOffset.x+PreviousPSXDisplay.Range.x0;
\r
1270 PSXDisplay.CumulOffset.y = PSXDisplay.DrawOffset.y - PSXDisplay.GDrawOffset.y+PreviousPSXDisplay.Range.y0;
\r
1272 r.top =PSXDisplay.DrawArea.y0 - PreviousPSXDisplay.DisplayPosition.y;
\r
1273 r.bottom=PSXDisplay.DrawArea.y1 - PreviousPSXDisplay.DisplayPosition.y;
\r
1275 if(r.bottom<0 || r.top>=PSXDisplay.DisplayMode.y)
\r
1277 r.top =PSXDisplay.DrawArea.y0 - PSXDisplay.DisplayPosition.y;
\r
1278 r.bottom=PSXDisplay.DrawArea.y1 - PSXDisplay.DisplayPosition.y;
\r
1281 r.left =PSXDisplay.DrawArea.x0 - PreviousPSXDisplay.DisplayPosition.x;
\r
1282 r.right =PSXDisplay.DrawArea.x1 - PreviousPSXDisplay.DisplayPosition.x;
\r
1284 if(r.right<0 || r.left>=PSXDisplay.DisplayMode.x)
\r
1286 r.left =PSXDisplay.DrawArea.x0 - PSXDisplay.DisplayPosition.x;
\r
1287 r.right =PSXDisplay.DrawArea.x1 - PSXDisplay.DisplayPosition.x;
\r
1290 if(!bSetClip && EqualRect(&r,&rprev) &&
\r
1291 iOldX == PSXDisplay.DisplayMode.x &&
\r
1292 iOldY == PSXDisplay.DisplayMode.y)
\r
1296 iOldX = PSXDisplay.DisplayMode.x;
\r
1297 iOldY = PSXDisplay.DisplayMode.y;
\r
1299 XS=(float)rRatioRect.right/(float)PSXDisplay.DisplayMode.x;
\r
1300 YS=(float)rRatioRect.bottom/(float)PSXDisplay.DisplayMode.y;
\r
1302 if(PreviousPSXDisplay.Range.x0)
\r
1304 short s=PreviousPSXDisplay.Range.x0+PreviousPSXDisplay.Range.x1;
\r
1306 r.left+=PreviousPSXDisplay.Range.x0+1;
\r
1308 r.right+=PreviousPSXDisplay.Range.x0;
\r
1310 if(r.left>s) r.left=s;
\r
1311 if(r.right>s) r.right=s;
\r
1314 if(PreviousPSXDisplay.Range.y0)
\r
1316 short s=PreviousPSXDisplay.Range.y0+PreviousPSXDisplay.Range.y1;
\r
1318 r.top+=PreviousPSXDisplay.Range.y0+1;
\r
1319 r.bottom+=PreviousPSXDisplay.Range.y0;
\r
1321 if(r.top>s) r.top=s;
\r
1322 if(r.bottom>s) r.bottom=s;
\r
1325 // Set the ClipArea variables to reflect the new screen,
\r
1326 // offset from zero (since it is a new display buffer)
\r
1327 r.left = (int)(((float)(r.left)) *XS);
\r
1328 r.top = (int)(((float)(r.top)) *YS);
\r
1329 r.right = (int)(((float)(r.right + 1))*XS);
\r
1330 r.bottom = (int)(((float)(r.bottom + 1))*YS);
\r
1332 // Limit clip area to the screen size
\r
1333 if (r.left > iResX) r.left = iResX;
\r
1334 if (r.left < 0) r.left = 0;
\r
1335 if (r.top > iResY) r.top = iResY;
\r
1336 if (r.top < 0) r.top = 0;
\r
1337 if (r.right > iResX) r.right = iResX;
\r
1338 if (r.right < 0) r.right = 0;
\r
1339 if (r.bottom > iResY) r.bottom = iResY;
\r
1340 if (r.bottom < 0) r.bottom = 0;
\r
1344 r.top=iResY-(r.top+r.bottom);
\r
1346 r.left+=rRatioRect.left;
\r
1347 r.top -=rRatioRect.top;
\r
1349 if(bSetClip || !EqualRect(&r,&rC))
\r
1351 glScissor(r.left,r.top,r.right,r.bottom);
\r
1357 ////////////////////////////////////////////////////////////////////////
\r
1358 ////////////////////////////////////////////////////////////////////////
\r
1359 ////////////////////////////////////////////////////////////////////////
\r