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
178 glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); glError();
\r
181 if(bOpaquePass) // opaque mode?
\r
186 PalTexturedColourFn=CP8RGBA; // -> init col func
\r
191 PalTexturedColourFn=XP8RGBA; // -> init col func
\r
195 glAlphaFuncx(GL_GREATER,0.49f); glError();
\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); glError(); // --> set alpha func
\r
206 //----------------------------------------------------//
\r
208 LoadSubTexFn=LoadSubTexturePageSort; // init load tex ptr
\r
210 bBlendEnable=FALSE; // init blending: off
\r
211 glDisable(GL_BLEND); glError();
\r
214 SetScanTrans(); // init scan lines (if wanted)
\r
217 ////////////////////////////////////////////////////////////////////////
\r
218 // setup scan lines
\r
219 ////////////////////////////////////////////////////////////////////////
\r
221 #define R_TSP 0x00,0x45,0x00,0xff
\r
222 #define G_TSP 0x00,0x00,0x45,0xff
\r
223 #define B_TSP 0x45,0x00,0x00,0xff
\r
224 #define O_TSP 0x45,0x45,0x45,0xff
\r
225 #define N_TSP 0x00,0x00,0x00,0xff
\r
227 GLuint gTexScanName=0;
\r
229 GLubyte texscan[4][16]=
\r
231 {R_TSP, G_TSP, B_TSP, N_TSP},
\r
232 {O_TSP, N_TSP, O_TSP, N_TSP},
\r
233 {B_TSP, N_TSP, R_TSP, G_TSP},
\r
234 {O_TSP, N_TSP, O_TSP, N_TSP}
\r
237 void CreateScanLines(void)
\r
241 ////////////////////////////////////////////////////////////////////////
\r
243 ////////////////////////////////////////////////////////////////////////
\r
250 EGLDisplay display;
\r
252 EGLContext context;
\r
253 EGLSurface surface;
\r
255 #if defined(USE_X11)
\r
256 #include "X11/Xlib.h"
\r
257 #include "X11/Xutil.h"
\r
258 #include "X11/Xatom.h"
\r
260 Window x11Window = 0;
\r
261 Display* x11Display = 0;
\r
262 long x11Screen = 0;
\r
263 XVisualInfo x11Visual;
\r
264 XVisualInfo* px11Visual = 0;
\r
265 Colormap x11Colormap = 0;
\r
268 EGLint attrib_list_fsaa[] =
\r
270 EGL_SURFACE_TYPE, EGL_WINDOW_BIT,
\r
271 EGL_BUFFER_SIZE, 0,
\r
272 EGL_DEPTH_SIZE, 16,
\r
273 EGL_SAMPLE_BUFFERS, 1,
\r
278 EGLint attrib_list[] =
\r
280 // EGL_DEPTH_SIZE, 16,
\r
284 bool TestEGLError(const char* pszLocation)
\r
287 eglGetError returns the last error that has happened using egl,
\r
288 not the status of the last called function. The user has to
\r
289 check after every single egl call or at least once every frame.
\r
291 EGLint iErr = eglGetError();
\r
292 if (iErr != EGL_SUCCESS)
\r
294 printf("%s failed (%d).\n", pszLocation, iErr);
\r
301 static void initEGL(void)
\r
303 printf ("GL init\n");
\r
306 EGLint majorVersion;
\r
307 EGLint minorVersion;
\r
308 #if defined(USE_X11)
\r
311 _NET_WM_STATE_REMOVE =0,
\r
312 _NET_WM_STATE_ADD = 1,
\r
313 _NET_WM_STATE_TOGGLE =2
\r
316 Window sRootWindow;
\r
317 XSetWindowAttributes sWA;
\r
318 unsigned int ui32Mask;
\r
322 EGLint *attribList = NULL;
\r
325 printf( "GLES: Using Full Scene Antialiasing\n" );
\r
326 attribList = attrib_list_fsaa;
\r
330 attribList = attrib_list;
\r
333 #if defined(USE_X11)
\r
334 // Initializes the display and screen
\r
335 x11Display = XOpenDisplay( ":0" );
\r
338 printf("GLES Error: Unable to open X display\n");
\r
340 x11Screen = XDefaultScreen( x11Display );
\r
342 // Gets the display parameters so we can pass the same parameters to the window to be created.
\r
343 sRootWindow = RootWindow(x11Display, x11Screen);
\r
344 i32Depth = DefaultDepth(x11Display, x11Screen);
\r
345 px11Visual = &x11Visual;
\r
346 XMatchVisualInfo( x11Display, x11Screen, i32Depth, TrueColor, px11Visual);
\r
349 printf("GLES Error: Unable to acquire visual\n");
\r
351 // Colormap of the specified visual type for the display.
\r
352 x11Colormap = XCreateColormap( x11Display, sRootWindow, px11Visual->visual, AllocNone );
\r
353 sWA.colormap = x11Colormap;
\r
355 // List of events to be handled by the application. Add to these for handling other events.
\r
356 sWA.event_mask = StructureNotifyMask | ExposureMask | ButtonPressMask | ButtonReleaseMask | KeyPressMask | KeyReleaseMask;
\r
358 // Display capabilities list.
\r
359 ui32Mask = CWBackPixel | CWBorderPixel | CWEventMask | CWColormap;
\r
361 // Creates the X11 window
\r
362 x11Window = XCreateWindow( x11Display, RootWindow(x11Display, x11Screen), 0, 0, iResX, iResY,
\r
363 0, CopyFromParent, InputOutput, CopyFromParent, ui32Mask, &sWA);
\r
365 // Make the window viewable and flush the output buffer.
\r
366 XMapWindow(x11Display, x11Window);
\r
367 XFlush(x11Display);
\r
369 // Make the window fullscreen
\r
370 unsigned char fullScreen = 1;
\r
371 Atom wmState = XInternAtom(x11Display, "_NET_WM_STATE", False);
\r
372 Atom wmFullScreen = XInternAtom(x11Display,"_NET_WM_STATE_FULLSCREEN", False);
\r
375 xev.xclient.type = ClientMessage;
\r
376 xev.xclient.serial = 0;
\r
377 xev.xclient.send_event = True;
\r
378 xev.xclient.window = x11Window;
\r
379 xev.xclient.message_type = wmState;
\r
380 xev.xclient.format = 32;
\r
381 xev.xclient.data.l[0] = (fullScreen ? _NET_WM_STATE_ADD : _NET_WM_STATE_REMOVE);
\r
382 xev.xclient.data.l[1] = wmFullScreen;
\r
383 xev.xclient.data.l[2] = 0;
\r
385 XSendEvent(x11Display, DefaultRootWindow(x11Display), False, SubstructureRedirectMask | SubstructureNotifyMask, &xev);
\r
387 display = eglGetDisplay( (EGLNativeDisplayType)x11Display );
\r
389 display = eglGetDisplay( (EGLNativeDisplayType)0 );
\r
392 if( display == EGL_NO_DISPLAY )
\r
394 printf( "GLES EGL Error: GL No Display\n" );
\r
397 if( !eglInitialize( display, &majorVersion, &minorVersion ) )
\r
399 printf( "GLES EGL Error: eglInitialize failed\n" );
\r
402 if( !eglChooseConfig( display, attribList, &config, 1, &numConfigs ) )
\r
404 printf( "GLES EGL Error: eglChooseConfig failed\n" );
\r
407 context = eglCreateContext( display, config, NULL, NULL );
\r
410 printf( "GLES EGL Error: eglCreateContext failed\n" );
\r
413 #if defined(USE_X11)
\r
414 surface = eglCreateWindowSurface( display, config, (EGLNativeDisplayType)x11Window, NULL );
\r
416 surface = eglCreateWindowSurface( display, config, (EGLNativeDisplayType)0, NULL );
\r
419 eglMakeCurrent( display, surface, surface, context );
\r
420 if (!TestEGLError("eglMakeCurrent"))
\r
421 printf("error eglMakeCurrent");
\r
423 printf("GLES Window Opened\n");
\r
426 int GLinitialize()
\r
430 //----------------------------------------------------//
\r
432 glViewport(rRatioRect.left, // init viewport by ratio rect
\r
433 iResY-(rRatioRect.top+rRatioRect.bottom),
\r
435 rRatioRect.bottom); glError();
\r
437 glScissor(0, 0, iResX, iResY); glError(); // init clipping (fullscreen)
\r
438 glEnable(GL_SCISSOR_TEST); glError();
\r
441 glMatrixMode(GL_TEXTURE); // init psx tex sow and tow if not "ownscale"
\r
443 glScalef(1.0f/255.99f,1.0f/255.99f,1.0f); // geforce precision hack
\r
445 glDepthRangef(0.0f, 1.0f);glError();
\r
447 glPolygonOffset( -0.2f, -0.2f );glError();
\r
449 glMatrixMode(GL_PROJECTION); glError(); // init projection with psx resolution
\r
450 glLoadIdentity(); glError();
\r
452 glOrtho(0,PSXDisplay.DisplayMode.x,
\r
453 PSXDisplay.DisplayMode.y, 0, -1, 1); glError();
\r
455 if(iZBufferDepth) // zbuffer?
\r
457 uiBufferBits=GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT;
\r
458 glEnable(GL_DEPTH_TEST); glError();
\r
459 glDepthFunc(GL_ALWAYS); glError();
\r
462 else // no zbuffer?
\r
464 uiBufferBits=GL_COLOR_BUFFER_BIT;
\r
465 glDisable(GL_DEPTH_TEST); glError();
\r
468 glClearColor(0.0f, 0.0f, 0.0f, 0.0f); glError(); // first buffer clear
\r
469 glClear(uiBufferBits); glError();
\r
471 GetExtInfos(); // get ext infos
\r
472 SetExtGLFuncs(); // init all kind of stuff (tex function pointers)
\r
474 glEnable(GL_ALPHA_TEST); glError(); // wanna alpha test
\r
477 glDisable(GL_LINE_SMOOTH); glError();
\r
478 glDisable(GL_POINT_SMOOTH); glError();
\r
481 ubGloAlpha=127; // init some drawing vars
\r
483 TWin.UScaleFactor = 1;
\r
484 TWin.VScaleFactor = 1;
\r
485 bDrawMultiPass=FALSE;
\r
489 if(bDrawDither) glEnable(GL_DITHER); // dither mode
\r
490 else glDisable(GL_DITHER);
\r
492 glDisable(GL_FOG); glError(); // turn all (currently) unused modes off
\r
493 glDisable(GL_LIGHTING); glError();
\r
494 glDisable(GL_STENCIL_TEST); glError();
\r
495 glDisable(GL_TEXTURE_2D); glError();
\r
496 glDisable(GL_CULL_FACE);
\r
498 glFlush(); glError(); // we are done...
\r
499 glFinish(); glError();
\r
501 CreateScanLines(); // setup scanline stuff (if wanted)
\r
503 CheckTextureMemory(); // check available tex memory
\r
505 if(bKeepRatio) SetAspectRatio(); // set ratio
\r
508 bIsFirstFrame = FALSE; // we have survived the first frame :)
\r
513 ////////////////////////////////////////////////////////////////////////
\r
514 // clean up OGL stuff
\r
515 ////////////////////////////////////////////////////////////////////////
\r
519 CleanupTextureStore(); // bye textures
\r
521 eglMakeCurrent( display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT );
\r
522 eglDestroySurface( display, surface );
\r
523 eglDestroyContext( display, context );
\r
524 eglTerminate( display );
\r
526 #if defined(USE_X11)
\r
527 if (x11Window) XDestroyWindow(x11Display, x11Window);
\r
528 if (x11Colormap) XFreeColormap( x11Display, x11Colormap );
\r
529 if (x11Display) XCloseDisplay(x11Display);
\r
533 ////////////////////////////////////////////////////////////////////////
\r
534 ////////////////////////////////////////////////////////////////////////
\r
535 ////////////////////////////////////////////////////////////////////////
\r
537 ////////////////////////////////////////////////////////////////////////
\r
538 ////////////////////////////////////////////////////////////////////////
\r
539 ////////////////////////////////////////////////////////////////////////
\r
541 ////////////////////////////////////////////////////////////////////////
\r
543 ////////////////////////////////////////////////////////////////////////
\r
545 // please note: it is hardly do-able in a hw/accel plugin to get the
\r
546 // real psx polygon coord mapping right... the following
\r
547 // works not to bad with many games, though
\r
549 __inline BOOL CheckCoord4()
\r
553 if(((lx1-lx0)>CHKMAX_X) ||
\r
554 ((lx2-lx0)>CHKMAX_X))
\r
558 if((lx1-lx3)>CHKMAX_X) return TRUE;
\r
559 if((lx2-lx3)>CHKMAX_X) return TRUE;
\r
565 if((lx0-lx1)>CHKMAX_X) return TRUE;
\r
566 if((lx2-lx1)>CHKMAX_X) return TRUE;
\r
567 if((lx3-lx1)>CHKMAX_X) return TRUE;
\r
571 if((lx0-lx2)>CHKMAX_X) return TRUE;
\r
572 if((lx1-lx2)>CHKMAX_X) return TRUE;
\r
573 if((lx3-lx2)>CHKMAX_X) return TRUE;
\r
577 if(((lx1-lx3)>CHKMAX_X) ||
\r
578 ((lx2-lx3)>CHKMAX_X))
\r
582 if((lx1-lx0)>CHKMAX_X) return TRUE;
\r
583 if((lx2-lx0)>CHKMAX_X) return TRUE;
\r
591 if((ly1-ly0)>CHKMAX_Y) return TRUE;
\r
592 if((ly2-ly0)>CHKMAX_Y) return TRUE;
\r
596 if((ly0-ly1)>CHKMAX_Y) return TRUE;
\r
597 if((ly2-ly1)>CHKMAX_Y) return TRUE;
\r
598 if((ly3-ly1)>CHKMAX_Y) return TRUE;
\r
602 if((ly0-ly2)>CHKMAX_Y) return TRUE;
\r
603 if((ly1-ly2)>CHKMAX_Y) return TRUE;
\r
604 if((ly3-ly2)>CHKMAX_Y) return TRUE;
\r
608 if((ly1-ly3)>CHKMAX_Y) return TRUE;
\r
609 if((ly2-ly3)>CHKMAX_Y) return TRUE;
\r
615 __inline BOOL CheckCoord3()
\r
619 if((lx1-lx0)>CHKMAX_X) return TRUE;
\r
620 if((lx2-lx0)>CHKMAX_X) return TRUE;
\r
624 if((lx0-lx1)>CHKMAX_X) return TRUE;
\r
625 if((lx2-lx1)>CHKMAX_X) return TRUE;
\r
629 if((lx0-lx2)>CHKMAX_X) return TRUE;
\r
630 if((lx1-lx2)>CHKMAX_X) return TRUE;
\r
634 if((ly1-ly0)>CHKMAX_Y) return TRUE;
\r
635 if((ly2-ly0)>CHKMAX_Y) return TRUE;
\r
639 if((ly0-ly1)>CHKMAX_Y) return TRUE;
\r
640 if((ly2-ly1)>CHKMAX_Y) return TRUE;
\r
644 if((ly0-ly2)>CHKMAX_Y) return TRUE;
\r
645 if((ly1-ly2)>CHKMAX_Y) return TRUE;
\r
652 __inline BOOL CheckCoord2()
\r
656 if((lx1-lx0)>CHKMAX_X) return TRUE;
\r
660 if((lx0-lx1)>CHKMAX_X) return TRUE;
\r
664 if((ly1-ly0)>CHKMAX_Y) return TRUE;
\r
668 if((ly0-ly1)>CHKMAX_Y) return TRUE;
\r
674 // Pete's way: a very easy (and hopefully fast) approach for lines
\r
675 // without sqrt... using a small float -> short cast trick :)
\r
677 #define VERTEX_OFFX 0.2f
\r
678 #define VERTEX_OFFY 0.2f
\r
680 BOOL offsetline(void)
\r
682 short x0,x1,y0,y1,dx,dy;float px,py;
\r
685 SetOGLDisplaySettings(1);
\r
687 if(!(dwActFixes&16))
\r
689 lx0=(short)(((int)lx0<<SIGNSHIFT)>>SIGNSHIFT);
\r
690 lx1=(short)(((int)lx1<<SIGNSHIFT)>>SIGNSHIFT);
\r
691 ly0=(short)(((int)ly0<<SIGNSHIFT)>>SIGNSHIFT);
\r
692 ly1=(short)(((int)ly1<<SIGNSHIFT)>>SIGNSHIFT);
\r
694 if(CheckCoord2()) return TRUE;
\r
697 x0 = (lx0 + PSXDisplay.CumulOffset.x)+1;
\r
698 x1 = (lx1 + PSXDisplay.CumulOffset.x)+1;
\r
699 y0 = (ly0 + PSXDisplay.CumulOffset.y)+1;
\r
700 y1 = (ly1 + PSXDisplay.CumulOffset.y)+1;
\r
710 if(dx>dy) py=-0.5f;
\r
711 else if(dx<dy) py= 0.5f;
\r
718 if(dx>dy) px= 0.5f;
\r
719 else if(dx<dy) px=-0.5f;
\r
729 if(dx>dy) px=-0.5f;
\r
730 else if(dx<dy) px= 0.5f;
\r
736 if(dx>dy) py=-0.5f;
\r
737 else if(dx<dy) py= 0.5f;
\r
742 vertex[0].x=(short)((float)x0-px);
\r
743 vertex[3].x=(short)((float)x0+py);
\r
745 vertex[0].y=(short)((float)y0-py);
\r
746 vertex[3].y=(short)((float)y0-px);
\r
748 vertex[1].x=(short)((float)x1-py);
\r
749 vertex[2].x=(short)((float)x1+px);
\r
751 vertex[1].y=(short)((float)y1+px);
\r
752 vertex[2].y=(short)((float)y1+py);
\r
754 if(vertex[0].x==vertex[3].x && // ortho rect? done
\r
755 vertex[1].x==vertex[2].x &&
\r
756 vertex[0].y==vertex[1].y &&
\r
757 vertex[2].y==vertex[3].y) return FALSE;
\r
758 if(vertex[0].x==vertex[1].x &&
\r
759 vertex[2].x==vertex[3].x &&
\r
760 vertex[0].y==vertex[3].y &&
\r
761 vertex[1].y==vertex[2].y) return FALSE;
\r
763 vertex[0].x-=VERTEX_OFFX; // otherwise a small offset
\r
764 vertex[0].y-=VERTEX_OFFY; // to get better accuracy
\r
765 vertex[1].x-=VERTEX_OFFX;
\r
766 vertex[1].y-=VERTEX_OFFY;
\r
767 vertex[2].x-=VERTEX_OFFX;
\r
768 vertex[2].y-=VERTEX_OFFY;
\r
769 vertex[3].x-=VERTEX_OFFX;
\r
770 vertex[3].y-=VERTEX_OFFY;
\r
775 /////////////////////////////////////////////////////////
\r
780 SetOGLDisplaySettings(1);
\r
782 if(!(dwActFixes&16))
\r
784 lx0=(short)(((int)lx0<<SIGNSHIFT)>>SIGNSHIFT);
\r
785 lx1=(short)(((int)lx1<<SIGNSHIFT)>>SIGNSHIFT);
\r
786 ly0=(short)(((int)ly0<<SIGNSHIFT)>>SIGNSHIFT);
\r
787 ly1=(short)(((int)ly1<<SIGNSHIFT)>>SIGNSHIFT);
\r
789 if(CheckCoord2()) return TRUE;
\r
792 vertex[0].x=lx0+PSXDisplay.CumulOffset.x;
\r
793 vertex[1].x=lx1+PSXDisplay.CumulOffset.x;
\r
794 vertex[0].y=ly0+PSXDisplay.CumulOffset.y;
\r
795 vertex[1].y=ly1+PSXDisplay.CumulOffset.y;
\r
800 /////////////////////////////////////////////////////////
\r
805 SetOGLDisplaySettings(1);
\r
807 if(!(dwActFixes&16))
\r
809 lx0=(short)(((int)lx0<<SIGNSHIFT)>>SIGNSHIFT);
\r
810 lx1=(short)(((int)lx1<<SIGNSHIFT)>>SIGNSHIFT);
\r
811 lx2=(short)(((int)lx2<<SIGNSHIFT)>>SIGNSHIFT);
\r
812 ly0=(short)(((int)ly0<<SIGNSHIFT)>>SIGNSHIFT);
\r
813 ly1=(short)(((int)ly1<<SIGNSHIFT)>>SIGNSHIFT);
\r
814 ly2=(short)(((int)ly2<<SIGNSHIFT)>>SIGNSHIFT);
\r
816 if(CheckCoord3()) return TRUE;
\r
819 vertex[0].x=lx0+PSXDisplay.CumulOffset.x;
\r
820 vertex[1].x=lx1+PSXDisplay.CumulOffset.x;
\r
821 vertex[2].x=lx2+PSXDisplay.CumulOffset.x;
\r
822 vertex[0].y=ly0+PSXDisplay.CumulOffset.y;
\r
823 vertex[1].y=ly1+PSXDisplay.CumulOffset.y;
\r
824 vertex[2].y=ly2+PSXDisplay.CumulOffset.y;
\r
829 /////////////////////////////////////////////////////////
\r
834 SetOGLDisplaySettings(1);
\r
836 if(!(dwActFixes&16))
\r
838 lx0=(short)(((int)lx0<<SIGNSHIFT)>>SIGNSHIFT);
\r
839 lx1=(short)(((int)lx1<<SIGNSHIFT)>>SIGNSHIFT);
\r
840 lx2=(short)(((int)lx2<<SIGNSHIFT)>>SIGNSHIFT);
\r
841 lx3=(short)(((int)lx3<<SIGNSHIFT)>>SIGNSHIFT);
\r
842 ly0=(short)(((int)ly0<<SIGNSHIFT)>>SIGNSHIFT);
\r
843 ly1=(short)(((int)ly1<<SIGNSHIFT)>>SIGNSHIFT);
\r
844 ly2=(short)(((int)ly2<<SIGNSHIFT)>>SIGNSHIFT);
\r
845 ly3=(short)(((int)ly3<<SIGNSHIFT)>>SIGNSHIFT);
\r
847 if(CheckCoord4()) return TRUE;
\r
850 vertex[0].x=lx0+PSXDisplay.CumulOffset.x;
\r
851 vertex[1].x=lx1+PSXDisplay.CumulOffset.x;
\r
852 vertex[2].x=lx2+PSXDisplay.CumulOffset.x;
\r
853 vertex[3].x=lx3+PSXDisplay.CumulOffset.x;
\r
854 vertex[0].y=ly0+PSXDisplay.CumulOffset.y;
\r
855 vertex[1].y=ly1+PSXDisplay.CumulOffset.y;
\r
856 vertex[2].y=ly2+PSXDisplay.CumulOffset.y;
\r
857 vertex[3].y=ly3+PSXDisplay.CumulOffset.y;
\r
862 /////////////////////////////////////////////////////////
\r
864 void offsetST(void)
\r
867 SetOGLDisplaySettings(1);
\r
869 if(!(dwActFixes&16))
\r
871 lx0=(short)(((int)lx0<<SIGNSHIFT)>>SIGNSHIFT);
\r
872 ly0=(short)(((int)ly0<<SIGNSHIFT)>>SIGNSHIFT);
\r
874 if(lx0<-512 && PSXDisplay.DrawOffset.x<=-512)
\r
877 if(ly0<-512 && PSXDisplay.DrawOffset.y<=-512)
\r
882 ly2 = ly3 = ly0+sprtH;
\r
884 lx1 = lx2 = lx0+sprtW;
\r
886 vertex[0].x=lx0+PSXDisplay.CumulOffset.x;
\r
887 vertex[1].x=lx1+PSXDisplay.CumulOffset.x;
\r
888 vertex[2].x=lx2+PSXDisplay.CumulOffset.x;
\r
889 vertex[3].x=lx3+PSXDisplay.CumulOffset.x;
\r
890 vertex[0].y=ly0+PSXDisplay.CumulOffset.y;
\r
891 vertex[1].y=ly1+PSXDisplay.CumulOffset.y;
\r
892 vertex[2].y=ly2+PSXDisplay.CumulOffset.y;
\r
893 vertex[3].y=ly3+PSXDisplay.CumulOffset.y;
\r
896 /////////////////////////////////////////////////////////
\r
898 void offsetScreenUpload(long Position)
\r
901 SetOGLDisplaySettings(1);
\r
907 lmdx=xrUploadArea.x0;
\r
908 lmdy=xrUploadArea.y0;
\r
922 lx0-=PSXDisplay.DisplayPosition.x;
\r
923 ly0-=PSXDisplay.DisplayPosition.y;
\r
924 lx1-=PSXDisplay.DisplayPosition.x;
\r
925 ly1-=PSXDisplay.DisplayPosition.y;
\r
926 lx2-=PSXDisplay.DisplayPosition.x;
\r
927 ly2-=PSXDisplay.DisplayPosition.y;
\r
928 lx3-=PSXDisplay.DisplayPosition.x;
\r
929 ly3-=PSXDisplay.DisplayPosition.y;
\r
933 lx0-=PreviousPSXDisplay.DisplayPosition.x;
\r
934 ly0-=PreviousPSXDisplay.DisplayPosition.y;
\r
935 lx1-=PreviousPSXDisplay.DisplayPosition.x;
\r
936 ly1-=PreviousPSXDisplay.DisplayPosition.y;
\r
937 lx2-=PreviousPSXDisplay.DisplayPosition.x;
\r
938 ly2-=PreviousPSXDisplay.DisplayPosition.y;
\r
939 lx3-=PreviousPSXDisplay.DisplayPosition.x;
\r
940 ly3-=PreviousPSXDisplay.DisplayPosition.y;
\r
943 vertex[0].x=lx0 + PreviousPSXDisplay.Range.x0;
\r
944 vertex[1].x=lx1 + PreviousPSXDisplay.Range.x0;
\r
945 vertex[2].x=lx2 + PreviousPSXDisplay.Range.x0;
\r
946 vertex[3].x=lx3 + PreviousPSXDisplay.Range.x0;
\r
947 vertex[0].y=ly0 + PreviousPSXDisplay.Range.y0;
\r
948 vertex[1].y=ly1 + PreviousPSXDisplay.Range.y0;
\r
949 vertex[2].y=ly2 + PreviousPSXDisplay.Range.y0;
\r
950 vertex[3].y=ly3 + PreviousPSXDisplay.Range.y0;
\r
954 vertex[0].z=vertex[1].z=vertex[2].z=vertex[3].z=gl_z;
\r
959 /////////////////////////////////////////////////////////
\r
961 void offsetBlk(void)
\r
964 SetOGLDisplaySettings(1);
\r
966 vertex[0].x=lx0-PSXDisplay.GDrawOffset.x + PreviousPSXDisplay.Range.x0;
\r
967 vertex[1].x=lx1-PSXDisplay.GDrawOffset.x + PreviousPSXDisplay.Range.x0;
\r
968 vertex[2].x=lx2-PSXDisplay.GDrawOffset.x + PreviousPSXDisplay.Range.x0;
\r
969 vertex[3].x=lx3-PSXDisplay.GDrawOffset.x + PreviousPSXDisplay.Range.x0;
\r
970 vertex[0].y=ly0-PSXDisplay.GDrawOffset.y + PreviousPSXDisplay.Range.y0;
\r
971 vertex[1].y=ly1-PSXDisplay.GDrawOffset.y + PreviousPSXDisplay.Range.y0;
\r
972 vertex[2].y=ly2-PSXDisplay.GDrawOffset.y + PreviousPSXDisplay.Range.y0;
\r
973 vertex[3].y=ly3-PSXDisplay.GDrawOffset.y + PreviousPSXDisplay.Range.y0;
\r
977 vertex[0].z=vertex[1].z=vertex[2].z=vertex[3].z=gl_z;
\r
982 ////////////////////////////////////////////////////////////////////////
\r
983 // texture sow/tow calculations
\r
984 ////////////////////////////////////////////////////////////////////////
\r
986 void assignTextureVRAMWrite(void)
\r
990 vertex[0].sow=0.5f/ ST_FACVRAMX;
\r
991 vertex[0].tow=0.5f/ ST_FACVRAM;
\r
993 vertex[1].sow=(float)gl_ux[1]/ ST_FACVRAMX;
\r
994 vertex[1].tow=0.5f/ ST_FACVRAM;
\r
996 vertex[2].sow=(float)gl_ux[2]/ ST_FACVRAMX;
\r
997 vertex[2].tow=(float)gl_vy[2]/ ST_FACVRAM;
\r
999 vertex[3].sow=0.5f/ ST_FACVRAMX;
\r
1000 vertex[3].tow=(float)gl_vy[3]/ ST_FACVRAM;
\r
1006 vertex[0].sow=(gl_ux[0]*255.99f)/255.0f;
\r
1007 vertex[1].sow=(gl_ux[1]*255.99f)/255.0f;
\r
1008 vertex[2].sow=(gl_ux[2]*255.99f)/255.0f;
\r
1009 vertex[3].sow=(gl_ux[3]*255.99f)/255.0f;
\r
1013 vertex[0].sow=gl_ux[0];
\r
1014 vertex[1].sow=gl_ux[1];
\r
1015 vertex[2].sow=gl_ux[2];
\r
1016 vertex[3].sow=gl_ux[3];
\r
1019 vertex[0].tow=gl_vy[0];
\r
1020 vertex[1].tow=gl_vy[1];
\r
1021 vertex[2].tow=gl_vy[2];
\r
1022 vertex[3].tow=gl_vy[3];
\r
1027 GLuint gLastTex=0;
\r
1028 GLuint gLastFMode=(GLuint)-1;
\r
1030 /////////////////////////////////////////////////////////
\r
1032 void assignTextureSprite(void)
\r
1036 vertex[0].sow=vertex[3].sow=(float)gl_ux[0]/TWin.UScaleFactor;
\r
1037 vertex[1].sow=vertex[2].sow=(float)sSprite_ux2/TWin.UScaleFactor;
\r
1038 vertex[0].tow=vertex[1].tow=(float)gl_vy[0]/TWin.VScaleFactor;
\r
1039 vertex[2].tow=vertex[3].tow=(float)sSprite_vy2/TWin.VScaleFactor;
\r
1040 gLastTex=gTexName;
\r
1046 vertex[0].sow=vertex[3].sow=(float)gl_ux[0] / ST_FACSPRITE;
\r
1047 vertex[1].sow=vertex[2].sow=(float)sSprite_ux2 / ST_FACSPRITE;
\r
1048 vertex[0].tow=vertex[1].tow=(float)gl_vy[0] / ST_FACSPRITE;
\r
1049 vertex[2].tow=vertex[3].tow=(float)sSprite_vy2 / ST_FACSPRITE;
\r
1053 vertex[0].sow=vertex[3].sow=gl_ux[0];
\r
1054 vertex[1].sow=vertex[2].sow=sSprite_ux2;
\r
1055 vertex[0].tow=vertex[1].tow=gl_vy[0];
\r
1056 vertex[2].tow=vertex[3].tow=sSprite_vy2;
\r
1060 if(iFilterType>2)
\r
1062 if(gLastTex!=gTexName || gLastFMode!=0)
\r
1064 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glError();
\r
1065 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glError();
\r
1066 gLastTex=gTexName;gLastFMode=0;
\r
1071 if(usMirror & 0x1000)
\r
1073 vertex[0].sow=vertex[1].sow;
\r
1074 vertex[1].sow=vertex[2].sow=vertex[3].sow;
\r
1075 vertex[3].sow=vertex[0].sow;
\r
1078 if(usMirror & 0x2000)
\r
1080 vertex[0].tow=vertex[3].tow;
\r
1081 vertex[2].tow=vertex[3].tow=vertex[1].tow;
\r
1082 vertex[1].tow=vertex[0].tow;
\r
1087 /////////////////////////////////////////////////////////
\r
1089 void assignTexture3(void)
\r
1093 vertex[0].sow=(float)gl_ux[0]/TWin.UScaleFactor;
\r
1094 vertex[0].tow=(float)gl_vy[0]/TWin.VScaleFactor;
\r
1095 vertex[1].sow=(float)gl_ux[1]/TWin.UScaleFactor;
\r
1096 vertex[1].tow=(float)gl_vy[1]/TWin.VScaleFactor;
\r
1097 vertex[2].sow=(float)gl_ux[2]/TWin.UScaleFactor;
\r
1098 vertex[2].tow=(float)gl_vy[2]/TWin.VScaleFactor;
\r
1099 gLastTex=gTexName;
\r
1104 vertex[0].sow=(float)gl_ux[0] / ST_FACTRI;
\r
1105 vertex[0].tow=(float)gl_vy[0] / ST_FACTRI;
\r
1106 vertex[1].sow=(float)gl_ux[1] / ST_FACTRI;
\r
1108 vertex[1].tow=(float)gl_vy[1] / ST_FACTRI;
\r
1109 vertex[2].sow=(float)gl_ux[2] / ST_FACTRI;
\r
1110 vertex[2].tow=(float)gl_vy[2] / ST_FACTRI;
\r
1112 vertex[0].sow=gl_ux[0];
\r
1113 vertex[0].tow=gl_vy[0];
\r
1114 vertex[1].sow=gl_ux[1];
\r
1115 vertex[1].tow=gl_vy[1];
\r
1116 vertex[2].sow=gl_ux[2];
\r
1117 vertex[2].tow=gl_vy[2];
\r
1120 if(iFilterType>2)
\r
1122 if(gLastTex!=gTexName || gLastFMode!=1)
\r
1124 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glError();
\r
1125 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glError();
\r
1126 gLastTex=gTexName;gLastFMode=1;
\r
1132 float fxmin=256.0f,fxmax=0.0f,fymin=256.0f,fymax=0.0f;int i;
\r
1135 if(vertex[i].sow<fxmin) fxmin=vertex[i].sow;
\r
1136 if(vertex[i].tow<fymin) fymin=vertex[i].tow;
\r
1137 if(vertex[i].sow>fxmax) fxmax=vertex[i].sow;
\r
1138 if(vertex[i].tow>fymax) fymax=vertex[i].tow;
\r
1143 if(vertex[i].sow==fxmin) vertex[i].sow+=ST_BFFACSORT;
\r
1144 if(vertex[i].sow==fxmax) vertex[i].sow-=ST_BFFACSORT;
\r
1145 if(vertex[i].tow==fymin) vertex[i].tow+=ST_BFFACSORT;
\r
1146 if(vertex[i].tow==fymax) vertex[i].tow-=ST_BFFACSORT;
\r
1152 /////////////////////////////////////////////////////////
\r
1154 void assignTexture4(void)
\r
1158 vertex[0].sow=(float)gl_ux[0]/TWin.UScaleFactor;
\r
1159 vertex[0].tow=(float)gl_vy[0]/TWin.VScaleFactor;
\r
1160 vertex[1].sow=(float)gl_ux[1]/TWin.UScaleFactor;
\r
1161 vertex[1].tow=(float)gl_vy[1]/TWin.VScaleFactor;
\r
1162 vertex[2].sow=(float)gl_ux[2]/TWin.UScaleFactor;
\r
1163 vertex[2].tow=(float)gl_vy[2]/TWin.VScaleFactor;
\r
1164 vertex[3].sow=(float)gl_ux[3]/TWin.UScaleFactor;
\r
1165 vertex[3].tow=(float)gl_vy[3]/TWin.VScaleFactor;
\r
1166 gLastTex=gTexName;
\r
1171 vertex[0].sow=(float)gl_ux[0] / ST_FAC;
\r
1172 vertex[0].tow=(float)gl_vy[0] / ST_FAC;
\r
1173 vertex[1].sow=(float)gl_ux[1] / ST_FAC;
\r
1174 vertex[1].tow=(float)gl_vy[1] / ST_FAC;
\r
1175 vertex[2].sow=(float)gl_ux[2] / ST_FAC;
\r
1176 vertex[2].tow=(float)gl_vy[2] / ST_FAC;
\r
1177 vertex[3].sow=(float)gl_ux[3] / ST_FAC;
\r
1178 vertex[3].tow=(float)gl_vy[3] / ST_FAC;
\r
1180 vertex[0].sow=gl_ux[0];
\r
1181 vertex[0].tow=gl_vy[0];
\r
1182 vertex[1].sow=gl_ux[1];
\r
1183 vertex[1].tow=gl_vy[1];
\r
1184 vertex[2].sow=gl_ux[2];
\r
1185 vertex[2].tow=gl_vy[2];
\r
1186 vertex[3].sow=gl_ux[3];
\r
1187 vertex[3].tow=gl_vy[3];
\r
1190 if(iFilterType>2)
\r
1192 if(gLastTex!=gTexName || gLastFMode!=1)
\r
1194 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glError();
\r
1195 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glError();
\r
1196 gLastTex=gTexName;gLastFMode=1;
\r
1202 float fxmin=256.0f,fxmax=0.0f,fymin=256.0f,fymax=0.0f;int i;
\r
1205 if(vertex[i].sow<fxmin) fxmin=vertex[i].sow;
\r
1206 if(vertex[i].tow<fymin) fymin=vertex[i].tow;
\r
1207 if(vertex[i].sow>fxmax) fxmax=vertex[i].sow;
\r
1208 if(vertex[i].tow>fymax) fymax=vertex[i].tow;
\r
1213 if(vertex[i].sow==fxmin) vertex[i].sow+=ST_BFFACSORT;
\r
1214 if(vertex[i].sow==fxmax) vertex[i].sow-=ST_BFFACSORT;
\r
1215 if(vertex[i].tow==fymin) vertex[i].tow+=ST_BFFACSORT;
\r
1216 if(vertex[i].tow==fymax) vertex[i].tow-=ST_BFFACSORT;
\r
1222 ////////////////////////////////////////////////////////////////////////
\r
1223 ////////////////////////////////////////////////////////////////////////
\r
1224 ////////////////////////////////////////////////////////////////////////
\r
1226 ////////////////////////////////////////////////////////////////////////
\r
1227 // render pos / buffers
\r
1228 ////////////////////////////////////////////////////////////////////////
\r
1230 #define EqualRect(pr1,pr2) ((pr1)->left==(pr2)->left && (pr1)->top==(pr2)->top && (pr1)->right==(pr2)->right && (pr1)->bottom==(pr2)->bottom)
\r
1232 ////////////////////////////////////////////////////////////////////////
\r
1233 // SetDisplaySettings: "simply" calcs the new drawing area and updates
\r
1234 // the ogl clipping (scissor)
\r
1236 BOOL bSetClip=FALSE;
\r
1238 void SetOGLDisplaySettings(BOOL DisplaySet)
\r
1240 static RECT rprev={0,0,0,0};
\r
1241 static RECT rC ={0,0,0,0};
\r
1242 static int iOldX=0;
\r
1243 static int iOldY=0;
\r
1244 RECT r;float XS,YS;
\r
1246 bDisplayNotSet = FALSE;
\r
1248 //----------------------------------------------------// that's a whole screen upload
\r
1252 PSXDisplay.GDrawOffset.x=0;
\r
1253 PSXDisplay.GDrawOffset.y=0;
\r
1255 PSXDisplay.CumulOffset.x = PSXDisplay.DrawOffset.x+PreviousPSXDisplay.Range.x0;
\r
1256 PSXDisplay.CumulOffset.y = PSXDisplay.DrawOffset.y+PreviousPSXDisplay.Range.y0;
\r
1258 rprev.left=rprev.left+1;
\r
1261 rX.top=iResY-(rRatioRect.top+rRatioRect.bottom);
\r
1263 if(bSetClip || !EqualRect(&rC,&rX))
\r
1266 glScissor(rC.left,rC.top,rC.right,rC.bottom); glError();
\r
1267 //LOGE("glscissor:%d %d %d %d",rC.left,rC.top,rC.right,rC.bottom);
\r
1272 //----------------------------------------------------//
\r
1274 PSXDisplay.GDrawOffset.y = PreviousPSXDisplay.DisplayPosition.y;
\r
1275 PSXDisplay.GDrawOffset.x = PreviousPSXDisplay.DisplayPosition.x;
\r
1276 PSXDisplay.CumulOffset.x = PSXDisplay.DrawOffset.x - PSXDisplay.GDrawOffset.x+PreviousPSXDisplay.Range.x0;
\r
1277 PSXDisplay.CumulOffset.y = PSXDisplay.DrawOffset.y - PSXDisplay.GDrawOffset.y+PreviousPSXDisplay.Range.y0;
\r
1279 r.top =PSXDisplay.DrawArea.y0 - PreviousPSXDisplay.DisplayPosition.y;
\r
1280 r.bottom=PSXDisplay.DrawArea.y1 - PreviousPSXDisplay.DisplayPosition.y;
\r
1282 if(r.bottom<0 || r.top>=PSXDisplay.DisplayMode.y)
\r
1284 r.top =PSXDisplay.DrawArea.y0 - PSXDisplay.DisplayPosition.y;
\r
1285 r.bottom=PSXDisplay.DrawArea.y1 - PSXDisplay.DisplayPosition.y;
\r
1288 r.left =PSXDisplay.DrawArea.x0 - PreviousPSXDisplay.DisplayPosition.x;
\r
1289 r.right =PSXDisplay.DrawArea.x1 - PreviousPSXDisplay.DisplayPosition.x;
\r
1291 if(r.right<0 || r.left>=PSXDisplay.DisplayMode.x)
\r
1293 r.left =PSXDisplay.DrawArea.x0 - PSXDisplay.DisplayPosition.x;
\r
1294 r.right =PSXDisplay.DrawArea.x1 - PSXDisplay.DisplayPosition.x;
\r
1297 if(!bSetClip && EqualRect(&r,&rprev) &&
\r
1298 iOldX == PSXDisplay.DisplayMode.x &&
\r
1299 iOldY == PSXDisplay.DisplayMode.y)
\r
1303 iOldX = PSXDisplay.DisplayMode.x;
\r
1304 iOldY = PSXDisplay.DisplayMode.y;
\r
1306 XS=(float)rRatioRect.right/(float)PSXDisplay.DisplayMode.x;
\r
1307 YS=(float)rRatioRect.bottom/(float)PSXDisplay.DisplayMode.y;
\r
1309 if(PreviousPSXDisplay.Range.x0)
\r
1311 short s=PreviousPSXDisplay.Range.x0+PreviousPSXDisplay.Range.x1;
\r
1313 r.left+=PreviousPSXDisplay.Range.x0+1;
\r
1315 r.right+=PreviousPSXDisplay.Range.x0;
\r
1317 if(r.left>s) r.left=s;
\r
1318 if(r.right>s) r.right=s;
\r
1321 if(PreviousPSXDisplay.Range.y0)
\r
1323 short s=PreviousPSXDisplay.Range.y0+PreviousPSXDisplay.Range.y1;
\r
1325 r.top+=PreviousPSXDisplay.Range.y0+1;
\r
1326 r.bottom+=PreviousPSXDisplay.Range.y0;
\r
1328 if(r.top>s) r.top=s;
\r
1329 if(r.bottom>s) r.bottom=s;
\r
1332 // Set the ClipArea variables to reflect the new screen,
\r
1333 // offset from zero (since it is a new display buffer)
\r
1334 r.left = (int)(((float)(r.left)) *XS);
\r
1335 r.top = (int)(((float)(r.top)) *YS);
\r
1336 r.right = (int)(((float)(r.right + 1))*XS);
\r
1337 r.bottom = (int)(((float)(r.bottom + 1))*YS);
\r
1339 // Limit clip area to the screen size
\r
1340 if (r.left > iResX) r.left = iResX;
\r
1341 if (r.left < 0) r.left = 0;
\r
1342 if (r.top > iResY) r.top = iResY;
\r
1343 if (r.top < 0) r.top = 0;
\r
1344 if (r.right > iResX) r.right = iResX;
\r
1345 if (r.right < 0) r.right = 0;
\r
1346 if (r.bottom > iResY) r.bottom = iResY;
\r
1347 if (r.bottom < 0) r.bottom = 0;
\r
1351 r.top=iResY-(r.top+r.bottom);
\r
1353 r.left+=rRatioRect.left;
\r
1354 r.top -=rRatioRect.top;
\r
1356 if(bSetClip || !EqualRect(&r,&rC))
\r
1358 glScissor(r.left,r.top,r.right,r.bottom); glError();
\r
1365 ////////////////////////////////////////////////////////////////////////
\r
1366 ////////////////////////////////////////////////////////////////////////
\r
1367 ////////////////////////////////////////////////////////////////////////
\r