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
446 glMatrixMode(GL_PROJECTION); glError(); // init projection with psx resolution
\r
447 glLoadIdentity(); glError();
\r
448 glOrtho(0,PSXDisplay.DisplayMode.x,
\r
449 PSXDisplay.DisplayMode.y, 0, -1, 1); glError();
\r
451 if(iZBufferDepth) // zbuffer?
\r
453 uiBufferBits=GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT;
\r
454 glEnable(GL_DEPTH_TEST); glError();
\r
455 glDepthFunc(GL_ALWAYS); glError();
\r
458 else // no zbuffer?
\r
460 uiBufferBits=GL_COLOR_BUFFER_BIT;
\r
461 glDisable(GL_DEPTH_TEST); glError();
\r
464 glClearColor(0.0f, 0.0f, 0.0f, 0.0f); glError(); // first buffer clear
\r
465 glClear(uiBufferBits); glError();
\r
467 GetExtInfos(); // get ext infos
\r
468 SetExtGLFuncs(); // init all kind of stuff (tex function pointers)
\r
470 glEnable(GL_ALPHA_TEST); glError(); // wanna alpha test
\r
473 glDisable(GL_LINE_SMOOTH); glError();
\r
474 glDisable(GL_POINT_SMOOTH); glError();
\r
477 ubGloAlpha=127; // init some drawing vars
\r
479 TWin.UScaleFactor = 1;
\r
480 TWin.VScaleFactor = 1;
\r
481 bDrawMultiPass=FALSE;
\r
485 if(bDrawDither) glEnable(GL_DITHER); // dither mode
\r
486 else glDisable(GL_DITHER);
\r
488 glDisable(GL_FOG); glError(); // turn all (currently) unused modes off
\r
489 glDisable(GL_LIGHTING); glError();
\r
490 glDisable(GL_STENCIL_TEST); glError();
\r
491 glDisable(GL_TEXTURE_2D); glError();
\r
492 glDisable(GL_CULL_FACE);
\r
494 glFlush(); glError(); // we are done...
\r
495 glFinish(); glError();
\r
497 CreateScanLines(); // setup scanline stuff (if wanted)
\r
499 CheckTextureMemory(); // check available tex memory
\r
501 if(bKeepRatio) SetAspectRatio(); // set ratio
\r
504 bIsFirstFrame = FALSE; // we have survived the first frame :)
\r
509 ////////////////////////////////////////////////////////////////////////
\r
510 // clean up OGL stuff
\r
511 ////////////////////////////////////////////////////////////////////////
\r
515 CleanupTextureStore(); // bye textures
\r
517 eglMakeCurrent( display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT );
\r
518 eglDestroySurface( display, surface );
\r
519 eglDestroyContext( display, context );
\r
520 eglTerminate( display );
\r
522 #if defined(USE_X11)
\r
523 if (x11Window) XDestroyWindow(x11Display, x11Window);
\r
524 if (x11Colormap) XFreeColormap( x11Display, x11Colormap );
\r
525 if (x11Display) XCloseDisplay(x11Display);
\r
529 ////////////////////////////////////////////////////////////////////////
\r
530 ////////////////////////////////////////////////////////////////////////
\r
531 ////////////////////////////////////////////////////////////////////////
\r
533 ////////////////////////////////////////////////////////////////////////
\r
534 ////////////////////////////////////////////////////////////////////////
\r
535 ////////////////////////////////////////////////////////////////////////
\r
537 ////////////////////////////////////////////////////////////////////////
\r
539 ////////////////////////////////////////////////////////////////////////
\r
541 // please note: it is hardly do-able in a hw/accel plugin to get the
\r
542 // real psx polygon coord mapping right... the following
\r
543 // works not to bad with many games, though
\r
545 __inline BOOL CheckCoord4()
\r
549 if(((lx1-lx0)>CHKMAX_X) ||
\r
550 ((lx2-lx0)>CHKMAX_X))
\r
554 if((lx1-lx3)>CHKMAX_X) return TRUE;
\r
555 if((lx2-lx3)>CHKMAX_X) return TRUE;
\r
561 if((lx0-lx1)>CHKMAX_X) return TRUE;
\r
562 if((lx2-lx1)>CHKMAX_X) return TRUE;
\r
563 if((lx3-lx1)>CHKMAX_X) return TRUE;
\r
567 if((lx0-lx2)>CHKMAX_X) return TRUE;
\r
568 if((lx1-lx2)>CHKMAX_X) return TRUE;
\r
569 if((lx3-lx2)>CHKMAX_X) return TRUE;
\r
573 if(((lx1-lx3)>CHKMAX_X) ||
\r
574 ((lx2-lx3)>CHKMAX_X))
\r
578 if((lx1-lx0)>CHKMAX_X) return TRUE;
\r
579 if((lx2-lx0)>CHKMAX_X) return TRUE;
\r
587 if((ly1-ly0)>CHKMAX_Y) return TRUE;
\r
588 if((ly2-ly0)>CHKMAX_Y) return TRUE;
\r
592 if((ly0-ly1)>CHKMAX_Y) return TRUE;
\r
593 if((ly2-ly1)>CHKMAX_Y) return TRUE;
\r
594 if((ly3-ly1)>CHKMAX_Y) return TRUE;
\r
598 if((ly0-ly2)>CHKMAX_Y) return TRUE;
\r
599 if((ly1-ly2)>CHKMAX_Y) return TRUE;
\r
600 if((ly3-ly2)>CHKMAX_Y) return TRUE;
\r
604 if((ly1-ly3)>CHKMAX_Y) return TRUE;
\r
605 if((ly2-ly3)>CHKMAX_Y) return TRUE;
\r
611 __inline BOOL CheckCoord3()
\r
615 if((lx1-lx0)>CHKMAX_X) return TRUE;
\r
616 if((lx2-lx0)>CHKMAX_X) return TRUE;
\r
620 if((lx0-lx1)>CHKMAX_X) return TRUE;
\r
621 if((lx2-lx1)>CHKMAX_X) return TRUE;
\r
625 if((lx0-lx2)>CHKMAX_X) return TRUE;
\r
626 if((lx1-lx2)>CHKMAX_X) return TRUE;
\r
630 if((ly1-ly0)>CHKMAX_Y) return TRUE;
\r
631 if((ly2-ly0)>CHKMAX_Y) return TRUE;
\r
635 if((ly0-ly1)>CHKMAX_Y) return TRUE;
\r
636 if((ly2-ly1)>CHKMAX_Y) return TRUE;
\r
640 if((ly0-ly2)>CHKMAX_Y) return TRUE;
\r
641 if((ly1-ly2)>CHKMAX_Y) return TRUE;
\r
648 __inline BOOL CheckCoord2()
\r
652 if((lx1-lx0)>CHKMAX_X) return TRUE;
\r
656 if((lx0-lx1)>CHKMAX_X) return TRUE;
\r
660 if((ly1-ly0)>CHKMAX_Y) return TRUE;
\r
664 if((ly0-ly1)>CHKMAX_Y) return TRUE;
\r
670 // Pete's way: a very easy (and hopefully fast) approach for lines
\r
671 // without sqrt... using a small float -> short cast trick :)
\r
673 #define VERTEX_OFFX 0.2f
\r
674 #define VERTEX_OFFY 0.2f
\r
676 BOOL offsetline(void)
\r
678 short x0,x1,y0,y1,dx,dy;float px,py;
\r
681 SetOGLDisplaySettings(1);
\r
683 if(!(dwActFixes&16))
\r
685 lx0=(short)(((int)lx0<<SIGNSHIFT)>>SIGNSHIFT);
\r
686 lx1=(short)(((int)lx1<<SIGNSHIFT)>>SIGNSHIFT);
\r
687 ly0=(short)(((int)ly0<<SIGNSHIFT)>>SIGNSHIFT);
\r
688 ly1=(short)(((int)ly1<<SIGNSHIFT)>>SIGNSHIFT);
\r
690 if(CheckCoord2()) return TRUE;
\r
693 x0 = (lx0 + PSXDisplay.CumulOffset.x)+1;
\r
694 x1 = (lx1 + PSXDisplay.CumulOffset.x)+1;
\r
695 y0 = (ly0 + PSXDisplay.CumulOffset.y)+1;
\r
696 y1 = (ly1 + PSXDisplay.CumulOffset.y)+1;
\r
706 if(dx>dy) py=-0.5f;
\r
707 else if(dx<dy) py= 0.5f;
\r
714 if(dx>dy) px= 0.5f;
\r
715 else if(dx<dy) px=-0.5f;
\r
725 if(dx>dy) px=-0.5f;
\r
726 else if(dx<dy) px= 0.5f;
\r
732 if(dx>dy) py=-0.5f;
\r
733 else if(dx<dy) py= 0.5f;
\r
738 vertex[0].x=(short)((float)x0-px);
\r
739 vertex[3].x=(short)((float)x0+py);
\r
741 vertex[0].y=(short)((float)y0-py);
\r
742 vertex[3].y=(short)((float)y0-px);
\r
744 vertex[1].x=(short)((float)x1-py);
\r
745 vertex[2].x=(short)((float)x1+px);
\r
747 vertex[1].y=(short)((float)y1+px);
\r
748 vertex[2].y=(short)((float)y1+py);
\r
750 if(vertex[0].x==vertex[3].x && // ortho rect? done
\r
751 vertex[1].x==vertex[2].x &&
\r
752 vertex[0].y==vertex[1].y &&
\r
753 vertex[2].y==vertex[3].y) return FALSE;
\r
754 if(vertex[0].x==vertex[1].x &&
\r
755 vertex[2].x==vertex[3].x &&
\r
756 vertex[0].y==vertex[3].y &&
\r
757 vertex[1].y==vertex[2].y) return FALSE;
\r
759 vertex[0].x-=VERTEX_OFFX; // otherwise a small offset
\r
760 vertex[0].y-=VERTEX_OFFY; // to get better accuracy
\r
761 vertex[1].x-=VERTEX_OFFX;
\r
762 vertex[1].y-=VERTEX_OFFY;
\r
763 vertex[2].x-=VERTEX_OFFX;
\r
764 vertex[2].y-=VERTEX_OFFY;
\r
765 vertex[3].x-=VERTEX_OFFX;
\r
766 vertex[3].y-=VERTEX_OFFY;
\r
771 /////////////////////////////////////////////////////////
\r
776 SetOGLDisplaySettings(1);
\r
778 if(!(dwActFixes&16))
\r
780 lx0=(short)(((int)lx0<<SIGNSHIFT)>>SIGNSHIFT);
\r
781 lx1=(short)(((int)lx1<<SIGNSHIFT)>>SIGNSHIFT);
\r
782 ly0=(short)(((int)ly0<<SIGNSHIFT)>>SIGNSHIFT);
\r
783 ly1=(short)(((int)ly1<<SIGNSHIFT)>>SIGNSHIFT);
\r
785 if(CheckCoord2()) return TRUE;
\r
788 vertex[0].x=lx0+PSXDisplay.CumulOffset.x;
\r
789 vertex[1].x=lx1+PSXDisplay.CumulOffset.x;
\r
790 vertex[0].y=ly0+PSXDisplay.CumulOffset.y;
\r
791 vertex[1].y=ly1+PSXDisplay.CumulOffset.y;
\r
796 /////////////////////////////////////////////////////////
\r
801 SetOGLDisplaySettings(1);
\r
803 if(!(dwActFixes&16))
\r
805 lx0=(short)(((int)lx0<<SIGNSHIFT)>>SIGNSHIFT);
\r
806 lx1=(short)(((int)lx1<<SIGNSHIFT)>>SIGNSHIFT);
\r
807 lx2=(short)(((int)lx2<<SIGNSHIFT)>>SIGNSHIFT);
\r
808 ly0=(short)(((int)ly0<<SIGNSHIFT)>>SIGNSHIFT);
\r
809 ly1=(short)(((int)ly1<<SIGNSHIFT)>>SIGNSHIFT);
\r
810 ly2=(short)(((int)ly2<<SIGNSHIFT)>>SIGNSHIFT);
\r
812 if(CheckCoord3()) return TRUE;
\r
815 vertex[0].x=lx0+PSXDisplay.CumulOffset.x;
\r
816 vertex[1].x=lx1+PSXDisplay.CumulOffset.x;
\r
817 vertex[2].x=lx2+PSXDisplay.CumulOffset.x;
\r
818 vertex[0].y=ly0+PSXDisplay.CumulOffset.y;
\r
819 vertex[1].y=ly1+PSXDisplay.CumulOffset.y;
\r
820 vertex[2].y=ly2+PSXDisplay.CumulOffset.y;
\r
825 /////////////////////////////////////////////////////////
\r
830 SetOGLDisplaySettings(1);
\r
832 if(!(dwActFixes&16))
\r
834 lx0=(short)(((int)lx0<<SIGNSHIFT)>>SIGNSHIFT);
\r
835 lx1=(short)(((int)lx1<<SIGNSHIFT)>>SIGNSHIFT);
\r
836 lx2=(short)(((int)lx2<<SIGNSHIFT)>>SIGNSHIFT);
\r
837 lx3=(short)(((int)lx3<<SIGNSHIFT)>>SIGNSHIFT);
\r
838 ly0=(short)(((int)ly0<<SIGNSHIFT)>>SIGNSHIFT);
\r
839 ly1=(short)(((int)ly1<<SIGNSHIFT)>>SIGNSHIFT);
\r
840 ly2=(short)(((int)ly2<<SIGNSHIFT)>>SIGNSHIFT);
\r
841 ly3=(short)(((int)ly3<<SIGNSHIFT)>>SIGNSHIFT);
\r
843 if(CheckCoord4()) return TRUE;
\r
846 vertex[0].x=lx0+PSXDisplay.CumulOffset.x;
\r
847 vertex[1].x=lx1+PSXDisplay.CumulOffset.x;
\r
848 vertex[2].x=lx2+PSXDisplay.CumulOffset.x;
\r
849 vertex[3].x=lx3+PSXDisplay.CumulOffset.x;
\r
850 vertex[0].y=ly0+PSXDisplay.CumulOffset.y;
\r
851 vertex[1].y=ly1+PSXDisplay.CumulOffset.y;
\r
852 vertex[2].y=ly2+PSXDisplay.CumulOffset.y;
\r
853 vertex[3].y=ly3+PSXDisplay.CumulOffset.y;
\r
858 /////////////////////////////////////////////////////////
\r
860 void offsetST(void)
\r
863 SetOGLDisplaySettings(1);
\r
865 if(!(dwActFixes&16))
\r
867 lx0=(short)(((int)lx0<<SIGNSHIFT)>>SIGNSHIFT);
\r
868 ly0=(short)(((int)ly0<<SIGNSHIFT)>>SIGNSHIFT);
\r
870 if(lx0<-512 && PSXDisplay.DrawOffset.x<=-512)
\r
873 if(ly0<-512 && PSXDisplay.DrawOffset.y<=-512)
\r
878 ly2 = ly3 = ly0+sprtH;
\r
880 lx1 = lx2 = lx0+sprtW;
\r
882 vertex[0].x=lx0+PSXDisplay.CumulOffset.x;
\r
883 vertex[1].x=lx1+PSXDisplay.CumulOffset.x;
\r
884 vertex[2].x=lx2+PSXDisplay.CumulOffset.x;
\r
885 vertex[3].x=lx3+PSXDisplay.CumulOffset.x;
\r
886 vertex[0].y=ly0+PSXDisplay.CumulOffset.y;
\r
887 vertex[1].y=ly1+PSXDisplay.CumulOffset.y;
\r
888 vertex[2].y=ly2+PSXDisplay.CumulOffset.y;
\r
889 vertex[3].y=ly3+PSXDisplay.CumulOffset.y;
\r
892 /////////////////////////////////////////////////////////
\r
894 void offsetScreenUpload(long Position)
\r
897 SetOGLDisplaySettings(1);
\r
903 lmdx=xrUploadArea.x0;
\r
904 lmdy=xrUploadArea.y0;
\r
918 lx0-=PSXDisplay.DisplayPosition.x;
\r
919 ly0-=PSXDisplay.DisplayPosition.y;
\r
920 lx1-=PSXDisplay.DisplayPosition.x;
\r
921 ly1-=PSXDisplay.DisplayPosition.y;
\r
922 lx2-=PSXDisplay.DisplayPosition.x;
\r
923 ly2-=PSXDisplay.DisplayPosition.y;
\r
924 lx3-=PSXDisplay.DisplayPosition.x;
\r
925 ly3-=PSXDisplay.DisplayPosition.y;
\r
929 lx0-=PreviousPSXDisplay.DisplayPosition.x;
\r
930 ly0-=PreviousPSXDisplay.DisplayPosition.y;
\r
931 lx1-=PreviousPSXDisplay.DisplayPosition.x;
\r
932 ly1-=PreviousPSXDisplay.DisplayPosition.y;
\r
933 lx2-=PreviousPSXDisplay.DisplayPosition.x;
\r
934 ly2-=PreviousPSXDisplay.DisplayPosition.y;
\r
935 lx3-=PreviousPSXDisplay.DisplayPosition.x;
\r
936 ly3-=PreviousPSXDisplay.DisplayPosition.y;
\r
939 vertex[0].x=lx0 + PreviousPSXDisplay.Range.x0;
\r
940 vertex[1].x=lx1 + PreviousPSXDisplay.Range.x0;
\r
941 vertex[2].x=lx2 + PreviousPSXDisplay.Range.x0;
\r
942 vertex[3].x=lx3 + PreviousPSXDisplay.Range.x0;
\r
943 vertex[0].y=ly0 + PreviousPSXDisplay.Range.y0;
\r
944 vertex[1].y=ly1 + PreviousPSXDisplay.Range.y0;
\r
945 vertex[2].y=ly2 + PreviousPSXDisplay.Range.y0;
\r
946 vertex[3].y=ly3 + PreviousPSXDisplay.Range.y0;
\r
950 vertex[0].z=vertex[1].z=vertex[2].z=vertex[3].z=gl_z;
\r
955 /////////////////////////////////////////////////////////
\r
957 void offsetBlk(void)
\r
960 SetOGLDisplaySettings(1);
\r
962 vertex[0].x=lx0-PSXDisplay.GDrawOffset.x + PreviousPSXDisplay.Range.x0;
\r
963 vertex[1].x=lx1-PSXDisplay.GDrawOffset.x + PreviousPSXDisplay.Range.x0;
\r
964 vertex[2].x=lx2-PSXDisplay.GDrawOffset.x + PreviousPSXDisplay.Range.x0;
\r
965 vertex[3].x=lx3-PSXDisplay.GDrawOffset.x + PreviousPSXDisplay.Range.x0;
\r
966 vertex[0].y=ly0-PSXDisplay.GDrawOffset.y + PreviousPSXDisplay.Range.y0;
\r
967 vertex[1].y=ly1-PSXDisplay.GDrawOffset.y + PreviousPSXDisplay.Range.y0;
\r
968 vertex[2].y=ly2-PSXDisplay.GDrawOffset.y + PreviousPSXDisplay.Range.y0;
\r
969 vertex[3].y=ly3-PSXDisplay.GDrawOffset.y + PreviousPSXDisplay.Range.y0;
\r
973 vertex[0].z=vertex[1].z=vertex[2].z=vertex[3].z=gl_z;
\r
978 ////////////////////////////////////////////////////////////////////////
\r
979 // texture sow/tow calculations
\r
980 ////////////////////////////////////////////////////////////////////////
\r
982 void assignTextureVRAMWrite(void)
\r
986 vertex[0].sow=0.5f/ ST_FACVRAMX;
\r
987 vertex[0].tow=0.5f/ ST_FACVRAM;
\r
989 vertex[1].sow=(float)gl_ux[1]/ ST_FACVRAMX;
\r
990 vertex[1].tow=0.5f/ ST_FACVRAM;
\r
992 vertex[2].sow=(float)gl_ux[2]/ ST_FACVRAMX;
\r
993 vertex[2].tow=(float)gl_vy[2]/ ST_FACVRAM;
\r
995 vertex[3].sow=0.5f/ ST_FACVRAMX;
\r
996 vertex[3].tow=(float)gl_vy[3]/ ST_FACVRAM;
\r
1002 vertex[0].sow=(gl_ux[0]*255.99f)/255.0f;
\r
1003 vertex[1].sow=(gl_ux[1]*255.99f)/255.0f;
\r
1004 vertex[2].sow=(gl_ux[2]*255.99f)/255.0f;
\r
1005 vertex[3].sow=(gl_ux[3]*255.99f)/255.0f;
\r
1009 vertex[0].sow=gl_ux[0];
\r
1010 vertex[1].sow=gl_ux[1];
\r
1011 vertex[2].sow=gl_ux[2];
\r
1012 vertex[3].sow=gl_ux[3];
\r
1015 vertex[0].tow=gl_vy[0];
\r
1016 vertex[1].tow=gl_vy[1];
\r
1017 vertex[2].tow=gl_vy[2];
\r
1018 vertex[3].tow=gl_vy[3];
\r
1023 GLuint gLastTex=0;
\r
1024 GLuint gLastFMode=(GLuint)-1;
\r
1026 /////////////////////////////////////////////////////////
\r
1028 void assignTextureSprite(void)
\r
1032 vertex[0].sow=vertex[3].sow=(float)gl_ux[0]/TWin.UScaleFactor;
\r
1033 vertex[1].sow=vertex[2].sow=(float)sSprite_ux2/TWin.UScaleFactor;
\r
1034 vertex[0].tow=vertex[1].tow=(float)gl_vy[0]/TWin.VScaleFactor;
\r
1035 vertex[2].tow=vertex[3].tow=(float)sSprite_vy2/TWin.VScaleFactor;
\r
1036 gLastTex=gTexName;
\r
1042 vertex[0].sow=vertex[3].sow=(float)gl_ux[0] / ST_FACSPRITE;
\r
1043 vertex[1].sow=vertex[2].sow=(float)sSprite_ux2 / ST_FACSPRITE;
\r
1044 vertex[0].tow=vertex[1].tow=(float)gl_vy[0] / ST_FACSPRITE;
\r
1045 vertex[2].tow=vertex[3].tow=(float)sSprite_vy2 / ST_FACSPRITE;
\r
1049 vertex[0].sow=vertex[3].sow=gl_ux[0];
\r
1050 vertex[1].sow=vertex[2].sow=sSprite_ux2;
\r
1051 vertex[0].tow=vertex[1].tow=gl_vy[0];
\r
1052 vertex[2].tow=vertex[3].tow=sSprite_vy2;
\r
1056 if(iFilterType>2)
\r
1058 if(gLastTex!=gTexName || gLastFMode!=0)
\r
1060 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glError();
\r
1061 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glError();
\r
1062 gLastTex=gTexName;gLastFMode=0;
\r
1067 if(usMirror & 0x1000)
\r
1069 vertex[0].sow=vertex[1].sow;
\r
1070 vertex[1].sow=vertex[2].sow=vertex[3].sow;
\r
1071 vertex[3].sow=vertex[0].sow;
\r
1074 if(usMirror & 0x2000)
\r
1076 vertex[0].tow=vertex[3].tow;
\r
1077 vertex[2].tow=vertex[3].tow=vertex[1].tow;
\r
1078 vertex[1].tow=vertex[0].tow;
\r
1083 /////////////////////////////////////////////////////////
\r
1085 void assignTexture3(void)
\r
1089 vertex[0].sow=(float)gl_ux[0]/TWin.UScaleFactor;
\r
1090 vertex[0].tow=(float)gl_vy[0]/TWin.VScaleFactor;
\r
1091 vertex[1].sow=(float)gl_ux[1]/TWin.UScaleFactor;
\r
1092 vertex[1].tow=(float)gl_vy[1]/TWin.VScaleFactor;
\r
1093 vertex[2].sow=(float)gl_ux[2]/TWin.UScaleFactor;
\r
1094 vertex[2].tow=(float)gl_vy[2]/TWin.VScaleFactor;
\r
1095 gLastTex=gTexName;
\r
1100 vertex[0].sow=(float)gl_ux[0] / ST_FACTRI;
\r
1101 vertex[0].tow=(float)gl_vy[0] / ST_FACTRI;
\r
1102 vertex[1].sow=(float)gl_ux[1] / ST_FACTRI;
\r
1104 vertex[1].tow=(float)gl_vy[1] / ST_FACTRI;
\r
1105 vertex[2].sow=(float)gl_ux[2] / ST_FACTRI;
\r
1106 vertex[2].tow=(float)gl_vy[2] / ST_FACTRI;
\r
1108 vertex[0].sow=gl_ux[0];
\r
1109 vertex[0].tow=gl_vy[0];
\r
1110 vertex[1].sow=gl_ux[1];
\r
1111 vertex[1].tow=gl_vy[1];
\r
1112 vertex[2].sow=gl_ux[2];
\r
1113 vertex[2].tow=gl_vy[2];
\r
1116 if(iFilterType>2)
\r
1118 if(gLastTex!=gTexName || gLastFMode!=1)
\r
1120 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glError();
\r
1121 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glError();
\r
1122 gLastTex=gTexName;gLastFMode=1;
\r
1128 float fxmin=256.0f,fxmax=0.0f,fymin=256.0f,fymax=0.0f;int i;
\r
1131 if(vertex[i].sow<fxmin) fxmin=vertex[i].sow;
\r
1132 if(vertex[i].tow<fymin) fymin=vertex[i].tow;
\r
1133 if(vertex[i].sow>fxmax) fxmax=vertex[i].sow;
\r
1134 if(vertex[i].tow>fymax) fymax=vertex[i].tow;
\r
1139 if(vertex[i].sow==fxmin) vertex[i].sow+=ST_BFFACSORT;
\r
1140 if(vertex[i].sow==fxmax) vertex[i].sow-=ST_BFFACSORT;
\r
1141 if(vertex[i].tow==fymin) vertex[i].tow+=ST_BFFACSORT;
\r
1142 if(vertex[i].tow==fymax) vertex[i].tow-=ST_BFFACSORT;
\r
1148 /////////////////////////////////////////////////////////
\r
1150 void assignTexture4(void)
\r
1154 vertex[0].sow=(float)gl_ux[0]/TWin.UScaleFactor;
\r
1155 vertex[0].tow=(float)gl_vy[0]/TWin.VScaleFactor;
\r
1156 vertex[1].sow=(float)gl_ux[1]/TWin.UScaleFactor;
\r
1157 vertex[1].tow=(float)gl_vy[1]/TWin.VScaleFactor;
\r
1158 vertex[2].sow=(float)gl_ux[2]/TWin.UScaleFactor;
\r
1159 vertex[2].tow=(float)gl_vy[2]/TWin.VScaleFactor;
\r
1160 vertex[3].sow=(float)gl_ux[3]/TWin.UScaleFactor;
\r
1161 vertex[3].tow=(float)gl_vy[3]/TWin.VScaleFactor;
\r
1162 gLastTex=gTexName;
\r
1167 vertex[0].sow=(float)gl_ux[0] / ST_FAC;
\r
1168 vertex[0].tow=(float)gl_vy[0] / ST_FAC;
\r
1169 vertex[1].sow=(float)gl_ux[1] / ST_FAC;
\r
1170 vertex[1].tow=(float)gl_vy[1] / ST_FAC;
\r
1171 vertex[2].sow=(float)gl_ux[2] / ST_FAC;
\r
1172 vertex[2].tow=(float)gl_vy[2] / ST_FAC;
\r
1173 vertex[3].sow=(float)gl_ux[3] / ST_FAC;
\r
1174 vertex[3].tow=(float)gl_vy[3] / ST_FAC;
\r
1176 vertex[0].sow=gl_ux[0];
\r
1177 vertex[0].tow=gl_vy[0];
\r
1178 vertex[1].sow=gl_ux[1];
\r
1179 vertex[1].tow=gl_vy[1];
\r
1180 vertex[2].sow=gl_ux[2];
\r
1181 vertex[2].tow=gl_vy[2];
\r
1182 vertex[3].sow=gl_ux[3];
\r
1183 vertex[3].tow=gl_vy[3];
\r
1186 if(iFilterType>2)
\r
1188 if(gLastTex!=gTexName || gLastFMode!=1)
\r
1190 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glError();
\r
1191 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glError();
\r
1192 gLastTex=gTexName;gLastFMode=1;
\r
1198 float fxmin=256.0f,fxmax=0.0f,fymin=256.0f,fymax=0.0f;int i;
\r
1201 if(vertex[i].sow<fxmin) fxmin=vertex[i].sow;
\r
1202 if(vertex[i].tow<fymin) fymin=vertex[i].tow;
\r
1203 if(vertex[i].sow>fxmax) fxmax=vertex[i].sow;
\r
1204 if(vertex[i].tow>fymax) fymax=vertex[i].tow;
\r
1209 if(vertex[i].sow==fxmin) vertex[i].sow+=ST_BFFACSORT;
\r
1210 if(vertex[i].sow==fxmax) vertex[i].sow-=ST_BFFACSORT;
\r
1211 if(vertex[i].tow==fymin) vertex[i].tow+=ST_BFFACSORT;
\r
1212 if(vertex[i].tow==fymax) vertex[i].tow-=ST_BFFACSORT;
\r
1218 ////////////////////////////////////////////////////////////////////////
\r
1219 ////////////////////////////////////////////////////////////////////////
\r
1220 ////////////////////////////////////////////////////////////////////////
\r
1222 ////////////////////////////////////////////////////////////////////////
\r
1223 // render pos / buffers
\r
1224 ////////////////////////////////////////////////////////////////////////
\r
1226 #define EqualRect(pr1,pr2) ((pr1)->left==(pr2)->left && (pr1)->top==(pr2)->top && (pr1)->right==(pr2)->right && (pr1)->bottom==(pr2)->bottom)
\r
1228 ////////////////////////////////////////////////////////////////////////
\r
1229 // SetDisplaySettings: "simply" calcs the new drawing area and updates
\r
1230 // the ogl clipping (scissor)
\r
1232 BOOL bSetClip=FALSE;
\r
1234 void SetOGLDisplaySettings(BOOL DisplaySet)
\r
1236 static RECT rprev={0,0,0,0};
\r
1237 static RECT rC ={0,0,0,0};
\r
1238 static int iOldX=0;
\r
1239 static int iOldY=0;
\r
1240 RECT r;float XS,YS;
\r
1242 bDisplayNotSet = FALSE;
\r
1244 //----------------------------------------------------// that's a whole screen upload
\r
1248 PSXDisplay.GDrawOffset.x=0;
\r
1249 PSXDisplay.GDrawOffset.y=0;
\r
1251 PSXDisplay.CumulOffset.x = PSXDisplay.DrawOffset.x+PreviousPSXDisplay.Range.x0;
\r
1252 PSXDisplay.CumulOffset.y = PSXDisplay.DrawOffset.y+PreviousPSXDisplay.Range.y0;
\r
1254 rprev.left=rprev.left+1;
\r
1257 rX.top=iResY-(rRatioRect.top+rRatioRect.bottom);
\r
1259 if(bSetClip || !EqualRect(&rC,&rX))
\r
1262 glScissor(rC.left,rC.top,rC.right,rC.bottom); glError();
\r
1263 //LOGE("glscissor:%d %d %d %d",rC.left,rC.top,rC.right,rC.bottom);
\r
1268 //----------------------------------------------------//
\r
1270 PSXDisplay.GDrawOffset.y = PreviousPSXDisplay.DisplayPosition.y;
\r
1271 PSXDisplay.GDrawOffset.x = PreviousPSXDisplay.DisplayPosition.x;
\r
1272 PSXDisplay.CumulOffset.x = PSXDisplay.DrawOffset.x - PSXDisplay.GDrawOffset.x+PreviousPSXDisplay.Range.x0;
\r
1273 PSXDisplay.CumulOffset.y = PSXDisplay.DrawOffset.y - PSXDisplay.GDrawOffset.y+PreviousPSXDisplay.Range.y0;
\r
1275 r.top =PSXDisplay.DrawArea.y0 - PreviousPSXDisplay.DisplayPosition.y;
\r
1276 r.bottom=PSXDisplay.DrawArea.y1 - PreviousPSXDisplay.DisplayPosition.y;
\r
1278 if(r.bottom<0 || r.top>=PSXDisplay.DisplayMode.y)
\r
1280 r.top =PSXDisplay.DrawArea.y0 - PSXDisplay.DisplayPosition.y;
\r
1281 r.bottom=PSXDisplay.DrawArea.y1 - PSXDisplay.DisplayPosition.y;
\r
1284 r.left =PSXDisplay.DrawArea.x0 - PreviousPSXDisplay.DisplayPosition.x;
\r
1285 r.right =PSXDisplay.DrawArea.x1 - PreviousPSXDisplay.DisplayPosition.x;
\r
1287 if(r.right<0 || r.left>=PSXDisplay.DisplayMode.x)
\r
1289 r.left =PSXDisplay.DrawArea.x0 - PSXDisplay.DisplayPosition.x;
\r
1290 r.right =PSXDisplay.DrawArea.x1 - PSXDisplay.DisplayPosition.x;
\r
1293 if(!bSetClip && EqualRect(&r,&rprev) &&
\r
1294 iOldX == PSXDisplay.DisplayMode.x &&
\r
1295 iOldY == PSXDisplay.DisplayMode.y)
\r
1299 iOldX = PSXDisplay.DisplayMode.x;
\r
1300 iOldY = PSXDisplay.DisplayMode.y;
\r
1302 XS=(float)rRatioRect.right/(float)PSXDisplay.DisplayMode.x;
\r
1303 YS=(float)rRatioRect.bottom/(float)PSXDisplay.DisplayMode.y;
\r
1305 if(PreviousPSXDisplay.Range.x0)
\r
1307 short s=PreviousPSXDisplay.Range.x0+PreviousPSXDisplay.Range.x1;
\r
1309 r.left+=PreviousPSXDisplay.Range.x0+1;
\r
1311 r.right+=PreviousPSXDisplay.Range.x0;
\r
1313 if(r.left>s) r.left=s;
\r
1314 if(r.right>s) r.right=s;
\r
1317 if(PreviousPSXDisplay.Range.y0)
\r
1319 short s=PreviousPSXDisplay.Range.y0+PreviousPSXDisplay.Range.y1;
\r
1321 r.top+=PreviousPSXDisplay.Range.y0+1;
\r
1322 r.bottom+=PreviousPSXDisplay.Range.y0;
\r
1324 if(r.top>s) r.top=s;
\r
1325 if(r.bottom>s) r.bottom=s;
\r
1328 // Set the ClipArea variables to reflect the new screen,
\r
1329 // offset from zero (since it is a new display buffer)
\r
1330 r.left = (int)(((float)(r.left)) *XS);
\r
1331 r.top = (int)(((float)(r.top)) *YS);
\r
1332 r.right = (int)(((float)(r.right + 1))*XS);
\r
1333 r.bottom = (int)(((float)(r.bottom + 1))*YS);
\r
1335 // Limit clip area to the screen size
\r
1336 if (r.left > iResX) r.left = iResX;
\r
1337 if (r.left < 0) r.left = 0;
\r
1338 if (r.top > iResY) r.top = iResY;
\r
1339 if (r.top < 0) r.top = 0;
\r
1340 if (r.right > iResX) r.right = iResX;
\r
1341 if (r.right < 0) r.right = 0;
\r
1342 if (r.bottom > iResY) r.bottom = iResY;
\r
1343 if (r.bottom < 0) r.bottom = 0;
\r
1347 r.top=iResY-(r.top+r.bottom);
\r
1349 r.left+=rRatioRect.left;
\r
1350 r.top -=rRatioRect.top;
\r
1352 if(bSetClip || !EqualRect(&r,&rC))
\r
1354 glScissor(r.left,r.top,r.right,r.bottom); glError();
\r
1361 ////////////////////////////////////////////////////////////////////////
\r
1362 ////////////////////////////////////////////////////////////////////////
\r
1363 ////////////////////////////////////////////////////////////////////////
\r