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
35 #include "externals.h"
\r
39 #include "texture.h"
\r
41 #include "gpuExternals.h"
\r
42 #include "gpuPlugin.h"
\r
43 #include "gpuDraw.h"
\r
44 #include "gpuPrim.h"
\r
45 #include "gpuTexture.h"
\r
46 #include "gpuStdafx.h"
\r
54 ////////////////////////////////////////////////////////////////////////////////////
\r
57 #define SIGNBIT 0x800
\r
58 #define S_MASK 0xf000
\r
59 #define L_MASK 0xfffff000
\r
61 // ownscale: some ogl drivers have buggy texture matrix funcs, so it
\r
62 // is safer to calc sow/tow ourselves
\r
66 ///////////////////////////////////////////////////////////////
\r
68 #define ST_FACSPRITE 255.99f
\r
69 #define ST_BFFACSPRITE 0.5f/256.0f
\r
70 #define ST_BFFACSPRITESORT 0.333f/256.0f
\r
72 #define ST_OFFSET 0.5f/256.0f;
\r
74 #define ST_FAC 255.99f
\r
75 #define ST_BFFAC 0.5f/256.0f
\r
76 #define ST_BFFACSORT 0.333f/256.0f
\r
78 #define ST_FACTRI 255.99f
\r
79 #define ST_BFFACTRI 0.5f/256.0f
\r
80 #define ST_BFFACTRISORT 0.333f/256.0f
\r
82 #define ST_FACVRAMX 255.0f
\r
83 #define ST_FACVRAM 256.0f
\r
85 ///////////////////////////////////////////////////////////////
\r
89 #define ST_BFFACSPRITE 0.5f
\r
90 #define ST_BFFACSPRITESORT 0.333f
\r
92 #define ST_BFFAC 0.5f
\r
93 #define ST_BFFACSORT 0.333f
\r
95 #define ST_BFFACTRI 0.5f
\r
96 #define ST_BFFACTRISORT 0.333f
\r
98 #define ST_OFFSET 0.5f;
\r
102 ////////////////////////////////////////////////////////////////////////////////////
\r
109 void glBlendEquationEXT(GLenum mode);
\r
110 void glColorTableEXT(GLenum target, GLenum internalFormat, GLsizei width, GLenum format,GLenum type, const GLvoid *data);
\r
113 // draw globals; most will be initialized again later (by config or checks)
\r
115 BOOL bIsFirstFrame=TRUE;
\r
117 // resolution/ratio vars
\r
121 BOOL bKeepRatio=FALSE;
\r
124 // psx mask related vars
\r
126 BOOL bCheckMask=FALSE;
\r
129 unsigned short sSetMask=0;
\r
130 unsigned long lSetMask=0;
\r
132 // drawing/coord vars
\r
134 OGLVertex vertex[4];
\r
137 short sprtY,sprtX,sprtH,sprtW;
\r
142 BOOL bAdvancedBlend;
\r
144 // OGL extension support
\r
147 // gfx card buffer infos
\r
150 int iZBufferDepth=0;
\r
151 GLbitfield uiBufferBits=GL_COLOR_BUFFER_BIT;
\r
153 ////////////////////////////////////////////////////////////////////////
\r
154 ////////////////////////////////////////////////////////////////////////
\r
155 ////////////////////////////////////////////////////////////////////////
\r
157 ////////////////////////////////////////////////////////////////////////
\r
158 // Set OGL pixel format
\r
159 ////////////////////////////////////////////////////////////////////////
\r
162 BOOL bSetupPixelFormat(HDC hDC)
\r
165 static PIXELFORMATDESCRIPTOR pfd =
\r
167 sizeof(PIXELFORMATDESCRIPTOR), // size of this pfd
\r
168 1, // version number
\r
169 PFD_DRAW_TO_WINDOW | // support window
\r
170 PFD_SUPPORT_OPENGL | // support OpenGL
\r
171 PFD_DOUBLEBUFFER, // double buffered
\r
172 PFD_TYPE_RGBA, // RGBA type
\r
173 16, // 16-bit color depth (adjusted later)
\r
174 0, 0, 0, 0, 0, 0, // color bits ignored
\r
175 0, // no alpha buffer
\r
176 0, // shift bit ignored
\r
177 0, // no accumulation buffer
\r
178 0, 0, 0, 0, // accum bits ignored
\r
181 0, // no auxiliary buffer
\r
182 PFD_MAIN_PLANE, // main layer
\r
184 0, 0, 0 // layer masks ignored
\r
187 pfd.cColorBits=iColDepth; // set user color depth
\r
188 pfd.cDepthBits=iZBufferDepth; // set user zbuffer (by psx mask)
\r
190 if((pixelformat=ChoosePixelFormat(hDC,&pfd))==0)
\r
192 MessageBox(NULL,"ChoosePixelFormat failed","Error",MB_OK);
\r
196 if(SetPixelFormat(hDC,pixelformat, &pfd)==FALSE)
\r
198 MessageBox(NULL,"SetPixelFormat failed","Error",MB_OK);
\r
206 ////////////////////////////////////////////////////////////////////////
\r
207 // Get extension infos (f.e. pal textures / packed pixels)
\r
208 ////////////////////////////////////////////////////////////////////////
\r
210 void GetExtInfos(void)
\r
212 BOOL bPacked=FALSE; // default: no packed pixel support
\r
214 if(strstr((char *)glGetString(GL_EXTENSIONS), // packed pixels available?
\r
215 "GL_EXT_packed_pixels"))
\r
216 bPacked=TRUE; // -> ok
\r
220 iClampType=GL_CLAMP;
\r
222 iClampType=GL_CLAMP_TO_EDGE;
\r
226 ////////////////////////////////////////////////////////////////////////
\r
227 // Setup some stuff depending on user settings or in-game toggle
\r
228 ////////////////////////////////////////////////////////////////////////
\r
230 void SetExtGLFuncs(void)
\r
232 //----------------------------------------------------//
\r
234 SetFixes(); // update fix infos
\r
236 //----------------------------------------------------//
\r
239 if(bAdvancedBlend) bUseMultiPass=TRUE; // -> pseudo-advanced with 2 passes
\r
240 else bUseMultiPass=FALSE; // -> or simple 'bright color' mode
\r
241 // bGLBlend=FALSE; // -> no ext blending!
\r
243 glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
\r
246 if(bOpaquePass) // opaque mode?
\r
251 PalTexturedColourFn=CP8RGBA; // -> init col func
\r
256 PalTexturedColourFn=XP8RGBA; // -> init col func
\r
260 glAlphaFuncx(GL_GREATER,0.49f);
\r
262 else // no opaque mode?
\r
264 TCF[0]=TCF[1]=P8RGBA;
\r
265 PalTexturedColourFn=P8RGBA; // -> init col func
\r
266 glAlphaFuncx(GL_NOTEQUAL,0); // --> set alpha func
\r
269 //----------------------------------------------------//
\r
271 LoadSubTexFn=LoadSubTexturePageSort; // init load tex ptr
\r
273 bBlendEnable=FALSE; // init blending: off
\r
274 glDisable(GL_BLEND);
\r
276 SetScanTrans(); // init scan lines (if wanted)
\r
279 ////////////////////////////////////////////////////////////////////////
\r
280 // setup scan lines
\r
281 ////////////////////////////////////////////////////////////////////////
\r
283 #define R_TSP 0x00,0x45,0x00,0xff
\r
284 #define G_TSP 0x00,0x00,0x45,0xff
\r
285 #define B_TSP 0x45,0x00,0x00,0xff
\r
286 #define O_TSP 0x45,0x45,0x45,0xff
\r
287 #define N_TSP 0x00,0x00,0x00,0xff
\r
289 GLuint gTexScanName=0;
\r
291 GLubyte texscan[4][16]=
\r
293 {R_TSP, G_TSP, B_TSP, N_TSP},
\r
294 {O_TSP, N_TSP, O_TSP, N_TSP},
\r
295 {B_TSP, N_TSP, R_TSP, G_TSP},
\r
296 {O_TSP, N_TSP, O_TSP, N_TSP}
\r
299 void CreateScanLines(void)
\r
303 ////////////////////////////////////////////////////////////////////////
\r
305 ////////////////////////////////////////////////////////////////////////
\r
308 HGLRC GLCONTEXT=NULL;
\r
316 EGLDisplay display;
\r
318 EGLContext context;
\r
319 EGLSurface surface;
\r
321 #if defined(USE_X11)
\r
322 #include "X11/Xlib.h"
\r
323 #include "X11/Xutil.h"
\r
324 #include "X11/Xatom.h"
\r
326 Window x11Window = 0;
\r
327 Display* x11Display = 0;
\r
328 long x11Screen = 0;
\r
329 XVisualInfo x11Visual;
\r
330 XVisualInfo* px11Visual = 0;
\r
331 Colormap x11Colormap = 0;
\r
334 EGLint attrib_list_fsaa[] =
\r
336 EGL_SURFACE_TYPE, EGL_WINDOW_BIT,
\r
337 EGL_BUFFER_SIZE, 0,
\r
338 EGL_DEPTH_SIZE, 16,
\r
339 EGL_SAMPLE_BUFFERS, 1,
\r
344 EGLint attrib_list[] =
\r
346 // EGL_DEPTH_SIZE, 16,
\r
350 bool TestEGLError(const char* pszLocation)
\r
353 eglGetError returns the last error that has happened using egl,
\r
354 not the status of the last called function. The user has to
\r
355 check after every single egl call or at least once every frame.
\r
357 EGLint iErr = eglGetError();
\r
358 if (iErr != EGL_SUCCESS)
\r
360 printf("%s failed (%d).\n", pszLocation, iErr);
\r
367 static void initEGL(void)
\r
369 printf ("GL init\n");
\r
372 EGLint majorVersion;
\r
373 EGLint minorVersion;
\r
374 #if defined(USE_X11)
\r
377 _NET_WM_STATE_REMOVE =0,
\r
378 _NET_WM_STATE_ADD = 1,
\r
379 _NET_WM_STATE_TOGGLE =2
\r
382 Window sRootWindow;
\r
383 XSetWindowAttributes sWA;
\r
384 unsigned int ui32Mask;
\r
388 EGLint *attribList = NULL;
\r
391 printf( "GLES: Using Full Scene Antialiasing\n" );
\r
392 attribList = attrib_list_fsaa;
\r
396 attribList = attrib_list;
\r
399 #if defined(USE_X11)
\r
400 // Initializes the display and screen
\r
401 x11Display = XOpenDisplay( ":0" );
\r
404 printf("GLES Error: Unable to open X display\n");
\r
406 x11Screen = XDefaultScreen( x11Display );
\r
408 // Gets the display parameters so we can pass the same parameters to the window to be created.
\r
409 sRootWindow = RootWindow(x11Display, x11Screen);
\r
410 i32Depth = DefaultDepth(x11Display, x11Screen);
\r
411 px11Visual = &x11Visual;
\r
412 XMatchVisualInfo( x11Display, x11Screen, i32Depth, TrueColor, px11Visual);
\r
415 printf("GLES Error: Unable to acquire visual\n");
\r
417 // Colormap of the specified visual type for the display.
\r
418 x11Colormap = XCreateColormap( x11Display, sRootWindow, px11Visual->visual, AllocNone );
\r
419 sWA.colormap = x11Colormap;
\r
421 // List of events to be handled by the application. Add to these for handling other events.
\r
422 sWA.event_mask = StructureNotifyMask | ExposureMask | ButtonPressMask | ButtonReleaseMask | KeyPressMask | KeyReleaseMask;
\r
424 // Display capabilities list.
\r
425 ui32Mask = CWBackPixel | CWBorderPixel | CWEventMask | CWColormap;
\r
427 // Creates the X11 window
\r
428 x11Window = XCreateWindow( x11Display, RootWindow(x11Display, x11Screen), 0, 0, iResX, iResY,
\r
429 0, CopyFromParent, InputOutput, CopyFromParent, ui32Mask, &sWA);
\r
431 // Make the window viewable and flush the output buffer.
\r
432 XMapWindow(x11Display, x11Window);
\r
433 XFlush(x11Display);
\r
435 // Make the window fullscreen
\r
436 unsigned char fullScreen = 1;
\r
437 Atom wmState = XInternAtom(x11Display, "_NET_WM_STATE", False);
\r
438 Atom wmFullScreen = XInternAtom(x11Display,"_NET_WM_STATE_FULLSCREEN", False);
\r
441 xev.xclient.type = ClientMessage;
\r
442 xev.xclient.serial = 0;
\r
443 xev.xclient.send_event = True;
\r
444 xev.xclient.window = x11Window;
\r
445 xev.xclient.message_type = wmState;
\r
446 xev.xclient.format = 32;
\r
447 xev.xclient.data.l[0] = (fullScreen ? _NET_WM_STATE_ADD : _NET_WM_STATE_REMOVE);
\r
448 xev.xclient.data.l[1] = wmFullScreen;
\r
449 xev.xclient.data.l[2] = 0;
\r
451 XSendEvent(x11Display, DefaultRootWindow(x11Display), False, SubstructureRedirectMask | SubstructureNotifyMask, &xev);
\r
453 display = eglGetDisplay( (EGLNativeDisplayType)x11Display );
\r
455 display = eglGetDisplay( (EGLNativeDisplayType)0 );
\r
458 if( display == EGL_NO_DISPLAY )
\r
460 printf( "GLES EGL Error: GL No Display\n" );
\r
463 if( !eglInitialize( display, &majorVersion, &minorVersion ) )
\r
465 printf( "GLES EGL Error: eglInitialize failed\n" );
\r
468 if( !eglChooseConfig( display, attribList, &config, 1, &numConfigs ) )
\r
470 printf( "GLES EGL Error: eglChooseConfig failed\n" );
\r
473 context = eglCreateContext( display, config, NULL, NULL );
\r
476 printf( "GLES EGL Error: eglCreateContext failed\n" );
\r
479 #if defined(USE_X11)
\r
480 surface = eglCreateWindowSurface( display, config, (EGLNativeDisplayType)x11Window, NULL );
\r
482 surface = eglCreateWindowSurface( display, config, (EGLNativeDisplayType)0, NULL );
\r
485 eglMakeCurrent( display, surface, surface, context );
\r
486 if (!TestEGLError("eglMakeCurrent"))
\r
487 printf("error eglMakeCurrent");
\r
489 printf("GLES Window Opened\n");
\r
492 int GLinitialize()
\r
494 //----------------------------------------------------//
\r
498 dcGlobal = GetDC(hWWindow); // FIRST: dc/rc stuff
\r
499 objectRC = wglCreateContext(dcGlobal);
\r
500 GLCONTEXT=objectRC;
\r
501 wglMakeCurrent(dcGlobal, objectRC);
\r
502 // CheckWGLExtensions(dcGlobal);
\r
503 if(bWindowMode) ReleaseDC(hWWindow,dcGlobal); // win mode: release dc again
\r
507 //----------------------------------------------------//
\r
509 glViewport(rRatioRect.left, // init viewport by ratio rect
\r
510 iResY-(rRatioRect.top+rRatioRect.bottom),
\r
512 rRatioRect.bottom);
\r
514 glScissor(0, 0, iResX, iResY); // init clipping (fullscreen)
\r
515 glEnable(GL_SCISSOR_TEST);
\r
518 glMatrixMode(GL_TEXTURE); // init psx tex sow and tow if not "ownscale"
\r
520 glScalef(1.0f/255.99f,1.0f/255.99f,1.0f); // geforce precision hack
\r
523 glMatrixMode(GL_PROJECTION); // init projection with psx resolution
\r
525 glOrtho(0,PSXDisplay.DisplayMode.x,
\r
526 PSXDisplay.DisplayMode.y, 0, -1, 1);
\r
528 if(iZBufferDepth) // zbuffer?
\r
530 uiBufferBits=GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT;
\r
531 glEnable(GL_DEPTH_TEST);
\r
532 glDepthFunc(GL_ALWAYS);
\r
535 else // no zbuffer?
\r
537 uiBufferBits=GL_COLOR_BUFFER_BIT;
\r
538 glDisable(GL_DEPTH_TEST);
\r
541 glClearColor(0.0f, 0.0f, 0.0f, 0.0f); // first buffer clear
\r
542 glClear(uiBufferBits);
\r
544 GetExtInfos(); // get ext infos
\r
545 SetExtGLFuncs(); // init all kind of stuff (tex function pointers)
\r
547 glEnable(GL_ALPHA_TEST); // wanna alpha test
\r
550 glDisable(GL_LINE_SMOOTH);
\r
551 glDisable(GL_POINT_SMOOTH);
\r
554 ubGloAlpha=127; // init some drawing vars
\r
556 TWin.UScaleFactor = 1;
\r
557 TWin.VScaleFactor = 1;
\r
558 bDrawMultiPass=FALSE;
\r
562 if(bDrawDither) glEnable(GL_DITHER); // dither mode
\r
563 else glDisable(GL_DITHER);
\r
565 glDisable(GL_FOG); // turn all (currently) unused modes off
\r
566 glDisable(GL_LIGHTING);
\r
567 glDisable(GL_STENCIL_TEST);
\r
568 glDisable(GL_TEXTURE_2D);
\r
569 glDisable(GL_CULL_FACE);
\r
571 glFlush(); // we are done...
\r
574 CreateScanLines(); // setup scanline stuff (if wanted)
\r
576 CheckTextureMemory(); // check available tex memory
\r
578 if(bKeepRatio) SetAspectRatio(); // set ratio
\r
581 bIsFirstFrame = FALSE; // we have survived the first frame :)
\r
586 ////////////////////////////////////////////////////////////////////////
\r
587 // clean up OGL stuff
\r
588 ////////////////////////////////////////////////////////////////////////
\r
592 CleanupTextureStore(); // bye textures
\r
595 wglMakeCurrent(NULL, NULL); // bye context
\r
596 if(GLCONTEXT) wglDeleteContext(GLCONTEXT);
\r
597 if(!bWindowMode && dcGlobal)
\r
598 ReleaseDC(hWWindow,dcGlobal);
\r
601 eglMakeCurrent( display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT );
\r
602 eglDestroySurface( display, surface );
\r
603 eglDestroyContext( display, context );
\r
604 eglTerminate( display );
\r
606 #if defined(USE_X11)
\r
607 if (x11Window) XDestroyWindow(x11Display, x11Window);
\r
608 if (x11Colormap) XFreeColormap( x11Display, x11Colormap );
\r
609 if (x11Display) XCloseDisplay(x11Display);
\r
613 ////////////////////////////////////////////////////////////////////////
\r
614 ////////////////////////////////////////////////////////////////////////
\r
615 ////////////////////////////////////////////////////////////////////////
\r
617 ////////////////////////////////////////////////////////////////////////
\r
618 ////////////////////////////////////////////////////////////////////////
\r
619 ////////////////////////////////////////////////////////////////////////
\r
621 ////////////////////////////////////////////////////////////////////////
\r
623 ////////////////////////////////////////////////////////////////////////
\r
625 // please note: it is hardly do-able in a hw/accel plugin to get the
\r
626 // real psx polygon coord mapping right... the following
\r
627 // works not to bad with many games, though
\r
629 __inline BOOL CheckCoord4()
\r
633 if(((lx1-lx0)>CHKMAX_X) ||
\r
634 ((lx2-lx0)>CHKMAX_X))
\r
638 if((lx1-lx3)>CHKMAX_X) return TRUE;
\r
639 if((lx2-lx3)>CHKMAX_X) return TRUE;
\r
645 if((lx0-lx1)>CHKMAX_X) return TRUE;
\r
646 if((lx2-lx1)>CHKMAX_X) return TRUE;
\r
647 if((lx3-lx1)>CHKMAX_X) return TRUE;
\r
651 if((lx0-lx2)>CHKMAX_X) return TRUE;
\r
652 if((lx1-lx2)>CHKMAX_X) return TRUE;
\r
653 if((lx3-lx2)>CHKMAX_X) return TRUE;
\r
657 if(((lx1-lx3)>CHKMAX_X) ||
\r
658 ((lx2-lx3)>CHKMAX_X))
\r
662 if((lx1-lx0)>CHKMAX_X) return TRUE;
\r
663 if((lx2-lx0)>CHKMAX_X) return TRUE;
\r
671 if((ly1-ly0)>CHKMAX_Y) return TRUE;
\r
672 if((ly2-ly0)>CHKMAX_Y) return TRUE;
\r
676 if((ly0-ly1)>CHKMAX_Y) return TRUE;
\r
677 if((ly2-ly1)>CHKMAX_Y) return TRUE;
\r
678 if((ly3-ly1)>CHKMAX_Y) return TRUE;
\r
682 if((ly0-ly2)>CHKMAX_Y) return TRUE;
\r
683 if((ly1-ly2)>CHKMAX_Y) return TRUE;
\r
684 if((ly3-ly2)>CHKMAX_Y) return TRUE;
\r
688 if((ly1-ly3)>CHKMAX_Y) return TRUE;
\r
689 if((ly2-ly3)>CHKMAX_Y) return TRUE;
\r
695 __inline BOOL CheckCoord3()
\r
699 if((lx1-lx0)>CHKMAX_X) return TRUE;
\r
700 if((lx2-lx0)>CHKMAX_X) return TRUE;
\r
704 if((lx0-lx1)>CHKMAX_X) return TRUE;
\r
705 if((lx2-lx1)>CHKMAX_X) return TRUE;
\r
709 if((lx0-lx2)>CHKMAX_X) return TRUE;
\r
710 if((lx1-lx2)>CHKMAX_X) return TRUE;
\r
714 if((ly1-ly0)>CHKMAX_Y) return TRUE;
\r
715 if((ly2-ly0)>CHKMAX_Y) return TRUE;
\r
719 if((ly0-ly1)>CHKMAX_Y) return TRUE;
\r
720 if((ly2-ly1)>CHKMAX_Y) return TRUE;
\r
724 if((ly0-ly2)>CHKMAX_Y) return TRUE;
\r
725 if((ly1-ly2)>CHKMAX_Y) return TRUE;
\r
732 __inline BOOL CheckCoord2()
\r
736 if((lx1-lx0)>CHKMAX_X) return TRUE;
\r
740 if((lx0-lx1)>CHKMAX_X) return TRUE;
\r
744 if((ly1-ly0)>CHKMAX_Y) return TRUE;
\r
748 if((ly0-ly1)>CHKMAX_Y) return TRUE;
\r
754 // Pete's way: a very easy (and hopefully fast) approach for lines
\r
755 // without sqrt... using a small float -> short cast trick :)
\r
757 #define VERTEX_OFFX 0.2f
\r
758 #define VERTEX_OFFY 0.2f
\r
760 BOOL offsetline(void)
\r
762 short x0,x1,y0,y1,dx,dy;float px,py;
\r
765 SetOGLDisplaySettings(1);
\r
767 if(!(dwActFixes&16))
\r
769 lx0=(short)(((int)lx0<<SIGNSHIFT)>>SIGNSHIFT);
\r
770 lx1=(short)(((int)lx1<<SIGNSHIFT)>>SIGNSHIFT);
\r
771 ly0=(short)(((int)ly0<<SIGNSHIFT)>>SIGNSHIFT);
\r
772 ly1=(short)(((int)ly1<<SIGNSHIFT)>>SIGNSHIFT);
\r
774 if(CheckCoord2()) return TRUE;
\r
777 x0 = (lx0 + PSXDisplay.CumulOffset.x)+1;
\r
778 x1 = (lx1 + PSXDisplay.CumulOffset.x)+1;
\r
779 y0 = (ly0 + PSXDisplay.CumulOffset.y)+1;
\r
780 y1 = (ly1 + PSXDisplay.CumulOffset.y)+1;
\r
790 if(dx>dy) py=-0.5f;
\r
791 else if(dx<dy) py= 0.5f;
\r
798 if(dx>dy) px= 0.5f;
\r
799 else if(dx<dy) px=-0.5f;
\r
809 if(dx>dy) px=-0.5f;
\r
810 else if(dx<dy) px= 0.5f;
\r
816 if(dx>dy) py=-0.5f;
\r
817 else if(dx<dy) py= 0.5f;
\r
822 vertex[0].x=(short)((float)x0-px);
\r
823 vertex[3].x=(short)((float)x0+py);
\r
825 vertex[0].y=(short)((float)y0-py);
\r
826 vertex[3].y=(short)((float)y0-px);
\r
828 vertex[1].x=(short)((float)x1-py);
\r
829 vertex[2].x=(short)((float)x1+px);
\r
831 vertex[1].y=(short)((float)y1+px);
\r
832 vertex[2].y=(short)((float)y1+py);
\r
834 if(vertex[0].x==vertex[3].x && // ortho rect? done
\r
835 vertex[1].x==vertex[2].x &&
\r
836 vertex[0].y==vertex[1].y &&
\r
837 vertex[2].y==vertex[3].y) return FALSE;
\r
838 if(vertex[0].x==vertex[1].x &&
\r
839 vertex[2].x==vertex[3].x &&
\r
840 vertex[0].y==vertex[3].y &&
\r
841 vertex[1].y==vertex[2].y) return FALSE;
\r
843 vertex[0].x-=VERTEX_OFFX; // otherwise a small offset
\r
844 vertex[0].y-=VERTEX_OFFY; // to get better accuracy
\r
845 vertex[1].x-=VERTEX_OFFX;
\r
846 vertex[1].y-=VERTEX_OFFY;
\r
847 vertex[2].x-=VERTEX_OFFX;
\r
848 vertex[2].y-=VERTEX_OFFY;
\r
849 vertex[3].x-=VERTEX_OFFX;
\r
850 vertex[3].y-=VERTEX_OFFY;
\r
855 /////////////////////////////////////////////////////////
\r
860 SetOGLDisplaySettings(1);
\r
862 if(!(dwActFixes&16))
\r
864 lx0=(short)(((int)lx0<<SIGNSHIFT)>>SIGNSHIFT);
\r
865 lx1=(short)(((int)lx1<<SIGNSHIFT)>>SIGNSHIFT);
\r
866 ly0=(short)(((int)ly0<<SIGNSHIFT)>>SIGNSHIFT);
\r
867 ly1=(short)(((int)ly1<<SIGNSHIFT)>>SIGNSHIFT);
\r
869 if(CheckCoord2()) return TRUE;
\r
872 vertex[0].x=lx0+PSXDisplay.CumulOffset.x;
\r
873 vertex[1].x=lx1+PSXDisplay.CumulOffset.x;
\r
874 vertex[0].y=ly0+PSXDisplay.CumulOffset.y;
\r
875 vertex[1].y=ly1+PSXDisplay.CumulOffset.y;
\r
880 /////////////////////////////////////////////////////////
\r
885 SetOGLDisplaySettings(1);
\r
887 if(!(dwActFixes&16))
\r
889 lx0=(short)(((int)lx0<<SIGNSHIFT)>>SIGNSHIFT);
\r
890 lx1=(short)(((int)lx1<<SIGNSHIFT)>>SIGNSHIFT);
\r
891 lx2=(short)(((int)lx2<<SIGNSHIFT)>>SIGNSHIFT);
\r
892 ly0=(short)(((int)ly0<<SIGNSHIFT)>>SIGNSHIFT);
\r
893 ly1=(short)(((int)ly1<<SIGNSHIFT)>>SIGNSHIFT);
\r
894 ly2=(short)(((int)ly2<<SIGNSHIFT)>>SIGNSHIFT);
\r
896 if(CheckCoord3()) return TRUE;
\r
899 vertex[0].x=lx0+PSXDisplay.CumulOffset.x;
\r
900 vertex[1].x=lx1+PSXDisplay.CumulOffset.x;
\r
901 vertex[2].x=lx2+PSXDisplay.CumulOffset.x;
\r
902 vertex[0].y=ly0+PSXDisplay.CumulOffset.y;
\r
903 vertex[1].y=ly1+PSXDisplay.CumulOffset.y;
\r
904 vertex[2].y=ly2+PSXDisplay.CumulOffset.y;
\r
909 /////////////////////////////////////////////////////////
\r
914 SetOGLDisplaySettings(1);
\r
916 if(!(dwActFixes&16))
\r
918 lx0=(short)(((int)lx0<<SIGNSHIFT)>>SIGNSHIFT);
\r
919 lx1=(short)(((int)lx1<<SIGNSHIFT)>>SIGNSHIFT);
\r
920 lx2=(short)(((int)lx2<<SIGNSHIFT)>>SIGNSHIFT);
\r
921 lx3=(short)(((int)lx3<<SIGNSHIFT)>>SIGNSHIFT);
\r
922 ly0=(short)(((int)ly0<<SIGNSHIFT)>>SIGNSHIFT);
\r
923 ly1=(short)(((int)ly1<<SIGNSHIFT)>>SIGNSHIFT);
\r
924 ly2=(short)(((int)ly2<<SIGNSHIFT)>>SIGNSHIFT);
\r
925 ly3=(short)(((int)ly3<<SIGNSHIFT)>>SIGNSHIFT);
\r
927 if(CheckCoord4()) return TRUE;
\r
930 vertex[0].x=lx0+PSXDisplay.CumulOffset.x;
\r
931 vertex[1].x=lx1+PSXDisplay.CumulOffset.x;
\r
932 vertex[2].x=lx2+PSXDisplay.CumulOffset.x;
\r
933 vertex[3].x=lx3+PSXDisplay.CumulOffset.x;
\r
934 vertex[0].y=ly0+PSXDisplay.CumulOffset.y;
\r
935 vertex[1].y=ly1+PSXDisplay.CumulOffset.y;
\r
936 vertex[2].y=ly2+PSXDisplay.CumulOffset.y;
\r
937 vertex[3].y=ly3+PSXDisplay.CumulOffset.y;
\r
942 /////////////////////////////////////////////////////////
\r
944 void offsetST(void)
\r
947 SetOGLDisplaySettings(1);
\r
949 if(!(dwActFixes&16))
\r
951 lx0=(short)(((int)lx0<<SIGNSHIFT)>>SIGNSHIFT);
\r
952 ly0=(short)(((int)ly0<<SIGNSHIFT)>>SIGNSHIFT);
\r
954 if(lx0<-512 && PSXDisplay.DrawOffset.x<=-512)
\r
957 if(ly0<-512 && PSXDisplay.DrawOffset.y<=-512)
\r
962 ly2 = ly3 = ly0+sprtH;
\r
964 lx1 = lx2 = lx0+sprtW;
\r
966 vertex[0].x=lx0+PSXDisplay.CumulOffset.x;
\r
967 vertex[1].x=lx1+PSXDisplay.CumulOffset.x;
\r
968 vertex[2].x=lx2+PSXDisplay.CumulOffset.x;
\r
969 vertex[3].x=lx3+PSXDisplay.CumulOffset.x;
\r
970 vertex[0].y=ly0+PSXDisplay.CumulOffset.y;
\r
971 vertex[1].y=ly1+PSXDisplay.CumulOffset.y;
\r
972 vertex[2].y=ly2+PSXDisplay.CumulOffset.y;
\r
973 vertex[3].y=ly3+PSXDisplay.CumulOffset.y;
\r
976 /////////////////////////////////////////////////////////
\r
978 void offsetScreenUpload(long Position)
\r
981 SetOGLDisplaySettings(1);
\r
987 lmdx=xrUploadArea.x0;
\r
988 lmdy=xrUploadArea.y0;
\r
1002 lx0-=PSXDisplay.DisplayPosition.x;
\r
1003 ly0-=PSXDisplay.DisplayPosition.y;
\r
1004 lx1-=PSXDisplay.DisplayPosition.x;
\r
1005 ly1-=PSXDisplay.DisplayPosition.y;
\r
1006 lx2-=PSXDisplay.DisplayPosition.x;
\r
1007 ly2-=PSXDisplay.DisplayPosition.y;
\r
1008 lx3-=PSXDisplay.DisplayPosition.x;
\r
1009 ly3-=PSXDisplay.DisplayPosition.y;
\r
1013 lx0-=PreviousPSXDisplay.DisplayPosition.x;
\r
1014 ly0-=PreviousPSXDisplay.DisplayPosition.y;
\r
1015 lx1-=PreviousPSXDisplay.DisplayPosition.x;
\r
1016 ly1-=PreviousPSXDisplay.DisplayPosition.y;
\r
1017 lx2-=PreviousPSXDisplay.DisplayPosition.x;
\r
1018 ly2-=PreviousPSXDisplay.DisplayPosition.y;
\r
1019 lx3-=PreviousPSXDisplay.DisplayPosition.x;
\r
1020 ly3-=PreviousPSXDisplay.DisplayPosition.y;
\r
1023 vertex[0].x=lx0 + PreviousPSXDisplay.Range.x0;
\r
1024 vertex[1].x=lx1 + PreviousPSXDisplay.Range.x0;
\r
1025 vertex[2].x=lx2 + PreviousPSXDisplay.Range.x0;
\r
1026 vertex[3].x=lx3 + PreviousPSXDisplay.Range.x0;
\r
1027 vertex[0].y=ly0 + PreviousPSXDisplay.Range.y0;
\r
1028 vertex[1].y=ly1 + PreviousPSXDisplay.Range.y0;
\r
1029 vertex[2].y=ly2 + PreviousPSXDisplay.Range.y0;
\r
1030 vertex[3].y=ly3 + PreviousPSXDisplay.Range.y0;
\r
1034 vertex[0].z=vertex[1].z=vertex[2].z=vertex[3].z=gl_z;
\r
1039 /////////////////////////////////////////////////////////
\r
1041 void offsetBlk(void)
\r
1043 if(bDisplayNotSet)
\r
1044 SetOGLDisplaySettings(1);
\r
1046 vertex[0].x=lx0-PSXDisplay.GDrawOffset.x + PreviousPSXDisplay.Range.x0;
\r
1047 vertex[1].x=lx1-PSXDisplay.GDrawOffset.x + PreviousPSXDisplay.Range.x0;
\r
1048 vertex[2].x=lx2-PSXDisplay.GDrawOffset.x + PreviousPSXDisplay.Range.x0;
\r
1049 vertex[3].x=lx3-PSXDisplay.GDrawOffset.x + PreviousPSXDisplay.Range.x0;
\r
1050 vertex[0].y=ly0-PSXDisplay.GDrawOffset.y + PreviousPSXDisplay.Range.y0;
\r
1051 vertex[1].y=ly1-PSXDisplay.GDrawOffset.y + PreviousPSXDisplay.Range.y0;
\r
1052 vertex[2].y=ly2-PSXDisplay.GDrawOffset.y + PreviousPSXDisplay.Range.y0;
\r
1053 vertex[3].y=ly3-PSXDisplay.GDrawOffset.y + PreviousPSXDisplay.Range.y0;
\r
1057 vertex[0].z=vertex[1].z=vertex[2].z=vertex[3].z=gl_z;
\r
1062 ////////////////////////////////////////////////////////////////////////
\r
1063 // texture sow/tow calculations
\r
1064 ////////////////////////////////////////////////////////////////////////
\r
1066 void assignTextureVRAMWrite(void)
\r
1070 vertex[0].sow=0.5f/ ST_FACVRAMX;
\r
1071 vertex[0].tow=0.5f/ ST_FACVRAM;
\r
1073 vertex[1].sow=(float)gl_ux[1]/ ST_FACVRAMX;
\r
1074 vertex[1].tow=0.5f/ ST_FACVRAM;
\r
1076 vertex[2].sow=(float)gl_ux[2]/ ST_FACVRAMX;
\r
1077 vertex[2].tow=(float)gl_vy[2]/ ST_FACVRAM;
\r
1079 vertex[3].sow=0.5f/ ST_FACVRAMX;
\r
1080 vertex[3].tow=(float)gl_vy[3]/ ST_FACVRAM;
\r
1086 vertex[0].sow=(gl_ux[0]*255.99f)/255.0f;
\r
1087 vertex[1].sow=(gl_ux[1]*255.99f)/255.0f;
\r
1088 vertex[2].sow=(gl_ux[2]*255.99f)/255.0f;
\r
1089 vertex[3].sow=(gl_ux[3]*255.99f)/255.0f;
\r
1093 vertex[0].sow=gl_ux[0];
\r
1094 vertex[1].sow=gl_ux[1];
\r
1095 vertex[2].sow=gl_ux[2];
\r
1096 vertex[3].sow=gl_ux[3];
\r
1099 vertex[0].tow=gl_vy[0];
\r
1100 vertex[1].tow=gl_vy[1];
\r
1101 vertex[2].tow=gl_vy[2];
\r
1102 vertex[3].tow=gl_vy[3];
\r
1107 GLuint gLastTex=0;
\r
1108 GLuint gLastFMode=(GLuint)-1;
\r
1110 /////////////////////////////////////////////////////////
\r
1112 void assignTextureSprite(void)
\r
1116 vertex[0].sow=vertex[3].sow=(float)gl_ux[0]/TWin.UScaleFactor;
\r
1117 vertex[1].sow=vertex[2].sow=(float)sSprite_ux2/TWin.UScaleFactor;
\r
1118 vertex[0].tow=vertex[1].tow=(float)gl_vy[0]/TWin.VScaleFactor;
\r
1119 vertex[2].tow=vertex[3].tow=(float)sSprite_vy2/TWin.VScaleFactor;
\r
1120 gLastTex=gTexName;
\r
1126 vertex[0].sow=vertex[3].sow=(float)gl_ux[0] / ST_FACSPRITE;
\r
1127 vertex[1].sow=vertex[2].sow=(float)sSprite_ux2 / ST_FACSPRITE;
\r
1128 vertex[0].tow=vertex[1].tow=(float)gl_vy[0] / ST_FACSPRITE;
\r
1129 vertex[2].tow=vertex[3].tow=(float)sSprite_vy2 / ST_FACSPRITE;
\r
1133 vertex[0].sow=vertex[3].sow=gl_ux[0];
\r
1134 vertex[1].sow=vertex[2].sow=sSprite_ux2;
\r
1135 vertex[0].tow=vertex[1].tow=gl_vy[0];
\r
1136 vertex[2].tow=vertex[3].tow=sSprite_vy2;
\r
1140 if(iFilterType>2)
\r
1142 if(gLastTex!=gTexName || gLastFMode!=0)
\r
1144 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
\r
1145 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
\r
1146 gLastTex=gTexName;gLastFMode=0;
\r
1151 if(usMirror & 0x1000)
\r
1153 vertex[0].sow=vertex[1].sow;
\r
1154 vertex[1].sow=vertex[2].sow=vertex[3].sow;
\r
1155 vertex[3].sow=vertex[0].sow;
\r
1158 if(usMirror & 0x2000)
\r
1160 vertex[0].tow=vertex[3].tow;
\r
1161 vertex[2].tow=vertex[3].tow=vertex[1].tow;
\r
1162 vertex[1].tow=vertex[0].tow;
\r
1167 /////////////////////////////////////////////////////////
\r
1169 void assignTexture3(void)
\r
1173 vertex[0].sow=(float)gl_ux[0]/TWin.UScaleFactor;
\r
1174 vertex[0].tow=(float)gl_vy[0]/TWin.VScaleFactor;
\r
1175 vertex[1].sow=(float)gl_ux[1]/TWin.UScaleFactor;
\r
1176 vertex[1].tow=(float)gl_vy[1]/TWin.VScaleFactor;
\r
1177 vertex[2].sow=(float)gl_ux[2]/TWin.UScaleFactor;
\r
1178 vertex[2].tow=(float)gl_vy[2]/TWin.VScaleFactor;
\r
1179 gLastTex=gTexName;
\r
1184 vertex[0].sow=(float)gl_ux[0] / ST_FACTRI;
\r
1185 vertex[0].tow=(float)gl_vy[0] / ST_FACTRI;
\r
1186 vertex[1].sow=(float)gl_ux[1] / ST_FACTRI;
\r
1188 vertex[1].tow=(float)gl_vy[1] / ST_FACTRI;
\r
1189 vertex[2].sow=(float)gl_ux[2] / ST_FACTRI;
\r
1190 vertex[2].tow=(float)gl_vy[2] / ST_FACTRI;
\r
1192 vertex[0].sow=gl_ux[0];
\r
1193 vertex[0].tow=gl_vy[0];
\r
1194 vertex[1].sow=gl_ux[1];
\r
1195 vertex[1].tow=gl_vy[1];
\r
1196 vertex[2].sow=gl_ux[2];
\r
1197 vertex[2].tow=gl_vy[2];
\r
1200 if(iFilterType>2)
\r
1202 if(gLastTex!=gTexName || gLastFMode!=1)
\r
1204 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
\r
1205 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
\r
1206 gLastTex=gTexName;gLastFMode=1;
\r
1212 float fxmin=256.0f,fxmax=0.0f,fymin=256.0f,fymax=0.0f;int i;
\r
1215 if(vertex[i].sow<fxmin) fxmin=vertex[i].sow;
\r
1216 if(vertex[i].tow<fymin) fymin=vertex[i].tow;
\r
1217 if(vertex[i].sow>fxmax) fxmax=vertex[i].sow;
\r
1218 if(vertex[i].tow>fymax) fymax=vertex[i].tow;
\r
1223 if(vertex[i].sow==fxmin) vertex[i].sow+=ST_BFFACSORT;
\r
1224 if(vertex[i].sow==fxmax) vertex[i].sow-=ST_BFFACSORT;
\r
1225 if(vertex[i].tow==fymin) vertex[i].tow+=ST_BFFACSORT;
\r
1226 if(vertex[i].tow==fymax) vertex[i].tow-=ST_BFFACSORT;
\r
1232 /////////////////////////////////////////////////////////
\r
1234 void assignTexture4(void)
\r
1238 vertex[0].sow=(float)gl_ux[0]/TWin.UScaleFactor;
\r
1239 vertex[0].tow=(float)gl_vy[0]/TWin.VScaleFactor;
\r
1240 vertex[1].sow=(float)gl_ux[1]/TWin.UScaleFactor;
\r
1241 vertex[1].tow=(float)gl_vy[1]/TWin.VScaleFactor;
\r
1242 vertex[2].sow=(float)gl_ux[2]/TWin.UScaleFactor;
\r
1243 vertex[2].tow=(float)gl_vy[2]/TWin.VScaleFactor;
\r
1244 vertex[3].sow=(float)gl_ux[3]/TWin.UScaleFactor;
\r
1245 vertex[3].tow=(float)gl_vy[3]/TWin.VScaleFactor;
\r
1246 gLastTex=gTexName;
\r
1251 vertex[0].sow=(float)gl_ux[0] / ST_FAC;
\r
1252 vertex[0].tow=(float)gl_vy[0] / ST_FAC;
\r
1253 vertex[1].sow=(float)gl_ux[1] / ST_FAC;
\r
1254 vertex[1].tow=(float)gl_vy[1] / ST_FAC;
\r
1255 vertex[2].sow=(float)gl_ux[2] / ST_FAC;
\r
1256 vertex[2].tow=(float)gl_vy[2] / ST_FAC;
\r
1257 vertex[3].sow=(float)gl_ux[3] / ST_FAC;
\r
1258 vertex[3].tow=(float)gl_vy[3] / ST_FAC;
\r
1260 vertex[0].sow=gl_ux[0];
\r
1261 vertex[0].tow=gl_vy[0];
\r
1262 vertex[1].sow=gl_ux[1];
\r
1263 vertex[1].tow=gl_vy[1];
\r
1264 vertex[2].sow=gl_ux[2];
\r
1265 vertex[2].tow=gl_vy[2];
\r
1266 vertex[3].sow=gl_ux[3];
\r
1267 vertex[3].tow=gl_vy[3];
\r
1270 if(iFilterType>2)
\r
1272 if(gLastTex!=gTexName || gLastFMode!=1)
\r
1274 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
\r
1275 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
\r
1276 gLastTex=gTexName;gLastFMode=1;
\r
1282 float fxmin=256.0f,fxmax=0.0f,fymin=256.0f,fymax=0.0f;int i;
\r
1285 if(vertex[i].sow<fxmin) fxmin=vertex[i].sow;
\r
1286 if(vertex[i].tow<fymin) fymin=vertex[i].tow;
\r
1287 if(vertex[i].sow>fxmax) fxmax=vertex[i].sow;
\r
1288 if(vertex[i].tow>fymax) fymax=vertex[i].tow;
\r
1293 if(vertex[i].sow==fxmin) vertex[i].sow+=ST_BFFACSORT;
\r
1294 if(vertex[i].sow==fxmax) vertex[i].sow-=ST_BFFACSORT;
\r
1295 if(vertex[i].tow==fymin) vertex[i].tow+=ST_BFFACSORT;
\r
1296 if(vertex[i].tow==fymax) vertex[i].tow-=ST_BFFACSORT;
\r
1302 ////////////////////////////////////////////////////////////////////////
\r
1303 ////////////////////////////////////////////////////////////////////////
\r
1304 ////////////////////////////////////////////////////////////////////////
\r
1306 ////////////////////////////////////////////////////////////////////////
\r
1307 // render pos / buffers
\r
1308 ////////////////////////////////////////////////////////////////////////
\r
1311 #define EqualRect(pr1,pr2) ((pr1)->left==(pr2)->left && (pr1)->top==(pr2)->top && (pr1)->right==(pr2)->right && (pr1)->bottom==(pr2)->bottom)
\r
1314 ////////////////////////////////////////////////////////////////////////
\r
1315 // SetDisplaySettings: "simply" calcs the new drawing area and updates
\r
1316 // the ogl clipping (scissor)
\r
1318 BOOL bSetClip=FALSE;
\r
1320 void SetOGLDisplaySettings(BOOL DisplaySet)
\r
1322 static RECT rprev={0,0,0,0};
\r
1323 static RECT rC ={0,0,0,0};
\r
1324 static int iOldX=0;
\r
1325 static int iOldY=0;
\r
1326 RECT r;float XS,YS;
\r
1328 bDisplayNotSet = FALSE;
\r
1330 //----------------------------------------------------// that's a whole screen upload
\r
1334 PSXDisplay.GDrawOffset.x=0;
\r
1335 PSXDisplay.GDrawOffset.y=0;
\r
1337 PSXDisplay.CumulOffset.x = PSXDisplay.DrawOffset.x+PreviousPSXDisplay.Range.x0;
\r
1338 PSXDisplay.CumulOffset.y = PSXDisplay.DrawOffset.y+PreviousPSXDisplay.Range.y0;
\r
1340 rprev.left=rprev.left+1;
\r
1343 rX.top=iResY-(rRatioRect.top+rRatioRect.bottom);
\r
1345 if(bSetClip || !EqualRect(&rC,&rX))
\r
1348 glScissor(rC.left,rC.top,rC.right,rC.bottom);
\r
1353 //----------------------------------------------------//
\r
1355 PSXDisplay.GDrawOffset.y = PreviousPSXDisplay.DisplayPosition.y;
\r
1356 PSXDisplay.GDrawOffset.x = PreviousPSXDisplay.DisplayPosition.x;
\r
1357 PSXDisplay.CumulOffset.x = PSXDisplay.DrawOffset.x - PSXDisplay.GDrawOffset.x+PreviousPSXDisplay.Range.x0;
\r
1358 PSXDisplay.CumulOffset.y = PSXDisplay.DrawOffset.y - PSXDisplay.GDrawOffset.y+PreviousPSXDisplay.Range.y0;
\r
1360 r.top =PSXDisplay.DrawArea.y0 - PreviousPSXDisplay.DisplayPosition.y;
\r
1361 r.bottom=PSXDisplay.DrawArea.y1 - PreviousPSXDisplay.DisplayPosition.y;
\r
1363 if(r.bottom<0 || r.top>=PSXDisplay.DisplayMode.y)
\r
1365 r.top =PSXDisplay.DrawArea.y0 - PSXDisplay.DisplayPosition.y;
\r
1366 r.bottom=PSXDisplay.DrawArea.y1 - PSXDisplay.DisplayPosition.y;
\r
1369 r.left =PSXDisplay.DrawArea.x0 - PreviousPSXDisplay.DisplayPosition.x;
\r
1370 r.right =PSXDisplay.DrawArea.x1 - PreviousPSXDisplay.DisplayPosition.x;
\r
1372 if(r.right<0 || r.left>=PSXDisplay.DisplayMode.x)
\r
1374 r.left =PSXDisplay.DrawArea.x0 - PSXDisplay.DisplayPosition.x;
\r
1375 r.right =PSXDisplay.DrawArea.x1 - PSXDisplay.DisplayPosition.x;
\r
1378 if(!bSetClip && EqualRect(&r,&rprev) &&
\r
1379 iOldX == PSXDisplay.DisplayMode.x &&
\r
1380 iOldY == PSXDisplay.DisplayMode.y)
\r
1384 iOldX = PSXDisplay.DisplayMode.x;
\r
1385 iOldY = PSXDisplay.DisplayMode.y;
\r
1387 XS=(float)rRatioRect.right/(float)PSXDisplay.DisplayMode.x;
\r
1388 YS=(float)rRatioRect.bottom/(float)PSXDisplay.DisplayMode.y;
\r
1390 if(PreviousPSXDisplay.Range.x0)
\r
1392 short s=PreviousPSXDisplay.Range.x0+PreviousPSXDisplay.Range.x1;
\r
1394 r.left+=PreviousPSXDisplay.Range.x0+1;
\r
1396 r.right+=PreviousPSXDisplay.Range.x0;
\r
1398 if(r.left>s) r.left=s;
\r
1399 if(r.right>s) r.right=s;
\r
1402 if(PreviousPSXDisplay.Range.y0)
\r
1404 short s=PreviousPSXDisplay.Range.y0+PreviousPSXDisplay.Range.y1;
\r
1406 r.top+=PreviousPSXDisplay.Range.y0+1;
\r
1407 r.bottom+=PreviousPSXDisplay.Range.y0;
\r
1409 if(r.top>s) r.top=s;
\r
1410 if(r.bottom>s) r.bottom=s;
\r
1413 // Set the ClipArea variables to reflect the new screen,
\r
1414 // offset from zero (since it is a new display buffer)
\r
1415 r.left = (int)(((float)(r.left)) *XS);
\r
1416 r.top = (int)(((float)(r.top)) *YS);
\r
1417 r.right = (int)(((float)(r.right + 1))*XS);
\r
1418 r.bottom = (int)(((float)(r.bottom + 1))*YS);
\r
1420 // Limit clip area to the screen size
\r
1421 if (r.left > iResX) r.left = iResX;
\r
1422 if (r.left < 0) r.left = 0;
\r
1423 if (r.top > iResY) r.top = iResY;
\r
1424 if (r.top < 0) r.top = 0;
\r
1425 if (r.right > iResX) r.right = iResX;
\r
1426 if (r.right < 0) r.right = 0;
\r
1427 if (r.bottom > iResY) r.bottom = iResY;
\r
1428 if (r.bottom < 0) r.bottom = 0;
\r
1432 r.top=iResY-(r.top+r.bottom);
\r
1434 r.left+=rRatioRect.left;
\r
1435 r.top -=rRatioRect.top;
\r
1437 if(bSetClip || !EqualRect(&r,&rC))
\r
1439 glScissor(r.left,r.top,r.right,r.bottom);
\r
1445 ////////////////////////////////////////////////////////////////////////
\r
1446 ////////////////////////////////////////////////////////////////////////
\r
1447 ////////////////////////////////////////////////////////////////////////
\r