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((s8 *)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
311 #ifdef MAEMO_CHANGES
\r
315 int pandora_driver_mode = MODE_RAW;
\r
318 EGLDisplay display;
\r
320 EGLContext context;
\r
321 EGLSurface surface;
\r
323 #if defined(USE_X11)
\r
324 #include "X11/Xlib.h"
\r
325 #include "X11/Xutil.h"
\r
326 #include "X11/Xatom.h"
\r
328 Window x11Window = 0;
\r
329 Display* x11Display = 0;
\r
330 long x11Screen = 0;
\r
331 XVisualInfo x11Visual;
\r
332 XVisualInfo* px11Visual = 0;
\r
333 Colormap x11Colormap = 0;
\r
336 EGLint attrib_list_fsaa[] =
\r
338 EGL_SURFACE_TYPE, EGL_WINDOW_BIT,
\r
339 EGL_BUFFER_SIZE, 0,
\r
340 EGL_DEPTH_SIZE, 16,
\r
341 EGL_SAMPLE_BUFFERS, 1,
\r
346 EGLint attrib_list[] =
\r
348 EGL_SURFACE_TYPE, EGL_WINDOW_BIT,
\r
349 EGL_BUFFER_SIZE, 0,
\r
350 EGL_DEPTH_SIZE, 16,
\r
354 bool TestEGLError(const char* pszLocation)
\r
357 eglGetError returns the last error that has happened using egl,
\r
358 not the status of the last called function. The user has to
\r
359 check after every single egl call or at least once every frame.
\r
361 EGLint iErr = eglGetError();
\r
362 if (iErr != EGL_SUCCESS)
\r
364 printf("%s failed (%d).\n", pszLocation, iErr);
\r
371 void maemoGLinit(){
\r
372 printf ("GL init\n");
\r
375 EGLint majorVersion;
\r
376 EGLint minorVersion;
\r
377 #if defined(USE_X11)
\r
380 _NET_WM_STATE_REMOVE =0,
\r
381 _NET_WM_STATE_ADD = 1,
\r
382 _NET_WM_STATE_TOGGLE =2
\r
385 Window sRootWindow;
\r
386 XSetWindowAttributes sWA;
\r
387 unsigned int ui32Mask;
\r
391 EGLint *attribList = NULL;
\r
394 printf( "GLES: Using Full Scene Antialiasing\n" );
\r
395 attribList = attrib_list_fsaa;
\r
399 attribList = attrib_list;
\r
402 #if defined(USE_X11)
\r
403 pandora_driver_mode = MODE_X11; // TODO make configurable
\r
405 pandora_driver_mode = MODE_RAW; // TODO make configurable
\r
408 switch(pandora_driver_mode)
\r
410 #if defined(USE_X11)
\r
412 // Initializes the display and screen
\r
413 x11Display = XOpenDisplay( ":0" );
\r
416 printf("GLES Error: Unable to open X display\n");
\r
418 x11Screen = XDefaultScreen( x11Display );
\r
420 // Gets the display parameters so we can pass the same parameters to the window to be created.
\r
421 sRootWindow = RootWindow(x11Display, x11Screen);
\r
422 i32Depth = DefaultDepth(x11Display, x11Screen);
\r
423 px11Visual = &x11Visual;
\r
424 XMatchVisualInfo( x11Display, x11Screen, i32Depth, TrueColor, px11Visual);
\r
427 printf("GLES Error: Unable to acquire visual\n");
\r
429 // Colormap of the specified visual type for the display.
\r
430 x11Colormap = XCreateColormap( x11Display, sRootWindow, px11Visual->visual, AllocNone );
\r
431 sWA.colormap = x11Colormap;
\r
433 // List of events to be handled by the application. Add to these for handling other events.
\r
434 sWA.event_mask = StructureNotifyMask | ExposureMask | ButtonPressMask | ButtonReleaseMask | KeyPressMask | KeyReleaseMask;
\r
436 // Display capabilities list.
\r
437 ui32Mask = CWBackPixel | CWBorderPixel | CWEventMask | CWColormap;
\r
439 // Creates the X11 window
\r
440 x11Window = XCreateWindow( x11Display, RootWindow(x11Display, x11Screen), 0, 0, iResX, iResY,
\r
441 0, CopyFromParent, InputOutput, CopyFromParent, ui32Mask, &sWA);
\r
443 // Make the window viewable and flush the output buffer.
\r
444 XMapWindow(x11Display, x11Window);
\r
445 XFlush(x11Display);
\r
447 // Make the window fullscreen
\r
448 unsigned char fullScreen = 1;
\r
449 Atom wmState = XInternAtom(x11Display, "_NET_WM_STATE", False);
\r
450 Atom wmFullScreen = XInternAtom(x11Display,"_NET_WM_STATE_FULLSCREEN", False);
\r
453 xev.xclient.type = ClientMessage;
\r
454 xev.xclient.serial = 0;
\r
455 xev.xclient.send_event = True;
\r
456 xev.xclient.window = x11Window;
\r
457 xev.xclient.message_type = wmState;
\r
458 xev.xclient.format = 32;
\r
459 xev.xclient.data.l[0] = (fullScreen ? _NET_WM_STATE_ADD : _NET_WM_STATE_REMOVE);
\r
460 xev.xclient.data.l[1] = wmFullScreen;
\r
461 xev.xclient.data.l[2] = 0;
\r
463 XSendEvent(x11Display, DefaultRootWindow(x11Display), False, SubstructureRedirectMask | SubstructureNotifyMask, &xev);
\r
465 display = eglGetDisplay( (EGLNativeDisplayType)x11Display );
\r
470 display = eglGetDisplay( (EGLNativeDisplayType)0 );
\r
474 if( display == EGL_NO_DISPLAY )
\r
476 printf( "GLES EGL Error: GL No Display\n" );
\r
479 if( !eglInitialize( display, &majorVersion, &minorVersion ) )
\r
481 printf( "GLES EGL Error: eglInitialize failed\n" );
\r
484 if( !eglChooseConfig( display, attribList, &config, 1, &numConfigs ) )
\r
486 printf( "GLES EGL Error: eglChooseConfig failed\n" );
\r
489 context = eglCreateContext( display, config, NULL, NULL );
\r
492 printf( "GLES EGL Error: eglCreateContext failed\n" );
\r
495 switch(pandora_driver_mode)
\r
497 #if defined(USE_X11)
\r
499 surface = eglCreateWindowSurface( display, config, (EGLNativeDisplayType)x11Window, NULL );
\r
504 surface = eglCreateWindowSurface( display, config, (EGLNativeDisplayType)0, NULL );
\r
508 eglMakeCurrent( display, surface, surface, context );
\r
509 if (!TestEGLError("eglMakeCurrent"))
\r
510 printf("error eglMakeCurrent");
\r
512 printf("GLES Window Opened\n");
\r
516 int GLinitialize()
\r
518 //----------------------------------------------------//
\r
522 dcGlobal = GetDC(hWWindow); // FIRST: dc/rc stuff
\r
523 objectRC = wglCreateContext(dcGlobal);
\r
524 GLCONTEXT=objectRC;
\r
525 wglMakeCurrent(dcGlobal, objectRC);
\r
526 // CheckWGLExtensions(dcGlobal);
\r
527 if(bWindowMode) ReleaseDC(hWWindow,dcGlobal); // win mode: release dc again
\r
529 #ifdef MAEMO_CHANGES
\r
532 //----------------------------------------------------//
\r
534 glViewport(rRatioRect.left, // init viewport by ratio rect
\r
535 iResY-(rRatioRect.top+rRatioRect.bottom),
\r
537 rRatioRect.bottom);
\r
539 glScissor(0, 0, iResX, iResY); // init clipping (fullscreen)
\r
540 glEnable(GL_SCISSOR_TEST);
\r
543 glMatrixMode(GL_TEXTURE); // init psx tex sow and tow if not "ownscale"
\r
545 glScalef(1.0f/255.99f,1.0f/255.99f,1.0f); // geforce precision hack
\r
548 glMatrixMode(GL_PROJECTION); // init projection with psx resolution
\r
550 glOrtho(0,PSXDisplay.DisplayMode.x,
\r
551 PSXDisplay.DisplayMode.y, 0, -1, 1);
\r
553 if(iZBufferDepth) // zbuffer?
\r
555 uiBufferBits=GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT;
\r
556 glEnable(GL_DEPTH_TEST);
\r
557 glDepthFunc(GL_ALWAYS);
\r
560 else // no zbuffer?
\r
562 uiBufferBits=GL_COLOR_BUFFER_BIT;
\r
563 glDisable(GL_DEPTH_TEST);
\r
566 glClearColor(0.0f, 0.0f, 0.0f, 0.0f); // first buffer clear
\r
567 glClear(uiBufferBits);
\r
569 GetExtInfos(); // get ext infos
\r
570 SetExtGLFuncs(); // init all kind of stuff (tex function pointers)
\r
572 glEnable(GL_ALPHA_TEST); // wanna alpha test
\r
575 glDisable(GL_LINE_SMOOTH);
\r
576 glDisable(GL_POINT_SMOOTH);
\r
579 ubGloAlpha=127; // init some drawing vars
\r
581 TWin.UScaleFactor = 1;
\r
582 TWin.VScaleFactor = 1;
\r
583 bDrawMultiPass=FALSE;
\r
587 if(bDrawDither) glEnable(GL_DITHER); // dither mode
\r
588 else glDisable(GL_DITHER);
\r
590 glDisable(GL_FOG); // turn all (currently) unused modes off
\r
591 glDisable(GL_LIGHTING);
\r
592 glDisable(GL_STENCIL_TEST);
\r
593 glDisable(GL_TEXTURE_2D);
\r
594 glDisable(GL_CULL_FACE);
\r
596 glFlush(); // we are done...
\r
599 CreateScanLines(); // setup scanline stuff (if wanted)
\r
601 CheckTextureMemory(); // check available tex memory
\r
603 if(bKeepRatio) SetAspectRatio(); // set ratio
\r
606 bIsFirstFrame = FALSE; // we have survived the first frame :)
\r
611 ////////////////////////////////////////////////////////////////////////
\r
612 // clean up OGL stuff
\r
613 ////////////////////////////////////////////////////////////////////////
\r
617 CleanupTextureStore(); // bye textures
\r
620 wglMakeCurrent(NULL, NULL); // bye context
\r
621 if(GLCONTEXT) wglDeleteContext(GLCONTEXT);
\r
622 if(!bWindowMode && dcGlobal)
\r
623 ReleaseDC(hWWindow,dcGlobal);
\r
626 eglMakeCurrent( display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT );
\r
627 eglDestroySurface( display, surface );
\r
628 eglDestroyContext( display, context );
\r
629 eglTerminate( display );
\r
631 #if defined(USE_X11)
\r
632 if (pandora_driver_mode == MODE_X11)
\r
634 if (x11Window) XDestroyWindow(x11Display, x11Window);
\r
635 if (x11Colormap) XFreeColormap( x11Display, x11Colormap );
\r
636 if (x11Display) XCloseDisplay(x11Display);
\r
641 ////////////////////////////////////////////////////////////////////////
\r
642 ////////////////////////////////////////////////////////////////////////
\r
643 ////////////////////////////////////////////////////////////////////////
\r
645 ////////////////////////////////////////////////////////////////////////
\r
646 ////////////////////////////////////////////////////////////////////////
\r
647 ////////////////////////////////////////////////////////////////////////
\r
649 ////////////////////////////////////////////////////////////////////////
\r
651 ////////////////////////////////////////////////////////////////////////
\r
653 // please note: it is hardly do-able in a hw/accel plugin to get the
\r
654 // real psx polygon coord mapping right... the following
\r
655 // works not to bad with many games, though
\r
657 __inline BOOL CheckCoord4()
\r
661 if(((lx1-lx0)>CHKMAX_X) ||
\r
662 ((lx2-lx0)>CHKMAX_X))
\r
666 if((lx1-lx3)>CHKMAX_X) return TRUE;
\r
667 if((lx2-lx3)>CHKMAX_X) return TRUE;
\r
673 if((lx0-lx1)>CHKMAX_X) return TRUE;
\r
674 if((lx2-lx1)>CHKMAX_X) return TRUE;
\r
675 if((lx3-lx1)>CHKMAX_X) return TRUE;
\r
679 if((lx0-lx2)>CHKMAX_X) return TRUE;
\r
680 if((lx1-lx2)>CHKMAX_X) return TRUE;
\r
681 if((lx3-lx2)>CHKMAX_X) return TRUE;
\r
685 if(((lx1-lx3)>CHKMAX_X) ||
\r
686 ((lx2-lx3)>CHKMAX_X))
\r
690 if((lx1-lx0)>CHKMAX_X) return TRUE;
\r
691 if((lx2-lx0)>CHKMAX_X) return TRUE;
\r
699 if((ly1-ly0)>CHKMAX_Y) return TRUE;
\r
700 if((ly2-ly0)>CHKMAX_Y) return TRUE;
\r
704 if((ly0-ly1)>CHKMAX_Y) return TRUE;
\r
705 if((ly2-ly1)>CHKMAX_Y) return TRUE;
\r
706 if((ly3-ly1)>CHKMAX_Y) return TRUE;
\r
710 if((ly0-ly2)>CHKMAX_Y) return TRUE;
\r
711 if((ly1-ly2)>CHKMAX_Y) return TRUE;
\r
712 if((ly3-ly2)>CHKMAX_Y) return TRUE;
\r
716 if((ly1-ly3)>CHKMAX_Y) return TRUE;
\r
717 if((ly2-ly3)>CHKMAX_Y) return TRUE;
\r
723 __inline BOOL CheckCoord3()
\r
727 if((lx1-lx0)>CHKMAX_X) return TRUE;
\r
728 if((lx2-lx0)>CHKMAX_X) return TRUE;
\r
732 if((lx0-lx1)>CHKMAX_X) return TRUE;
\r
733 if((lx2-lx1)>CHKMAX_X) return TRUE;
\r
737 if((lx0-lx2)>CHKMAX_X) return TRUE;
\r
738 if((lx1-lx2)>CHKMAX_X) return TRUE;
\r
742 if((ly1-ly0)>CHKMAX_Y) return TRUE;
\r
743 if((ly2-ly0)>CHKMAX_Y) return TRUE;
\r
747 if((ly0-ly1)>CHKMAX_Y) return TRUE;
\r
748 if((ly2-ly1)>CHKMAX_Y) return TRUE;
\r
752 if((ly0-ly2)>CHKMAX_Y) return TRUE;
\r
753 if((ly1-ly2)>CHKMAX_Y) return TRUE;
\r
760 __inline BOOL CheckCoord2()
\r
764 if((lx1-lx0)>CHKMAX_X) return TRUE;
\r
768 if((lx0-lx1)>CHKMAX_X) return TRUE;
\r
772 if((ly1-ly0)>CHKMAX_Y) return TRUE;
\r
776 if((ly0-ly1)>CHKMAX_Y) return TRUE;
\r
782 // Pete's way: a very easy (and hopefully fast) approach for lines
\r
783 // without sqrt... using a small float -> short cast trick :)
\r
785 #define VERTEX_OFFX 0.2f
\r
786 #define VERTEX_OFFY 0.2f
\r
788 BOOL offsetline(void)
\r
790 short x0,x1,y0,y1,dx,dy;float px,py;
\r
793 SetOGLDisplaySettings(1);
\r
795 if(!(dwActFixes&16))
\r
797 lx0=(short)(((int)lx0<<SIGNSHIFT)>>SIGNSHIFT);
\r
798 lx1=(short)(((int)lx1<<SIGNSHIFT)>>SIGNSHIFT);
\r
799 ly0=(short)(((int)ly0<<SIGNSHIFT)>>SIGNSHIFT);
\r
800 ly1=(short)(((int)ly1<<SIGNSHIFT)>>SIGNSHIFT);
\r
802 if(CheckCoord2()) return TRUE;
\r
805 x0 = (lx0 + PSXDisplay.CumulOffset.x)+1;
\r
806 x1 = (lx1 + PSXDisplay.CumulOffset.x)+1;
\r
807 y0 = (ly0 + PSXDisplay.CumulOffset.y)+1;
\r
808 y1 = (ly1 + PSXDisplay.CumulOffset.y)+1;
\r
818 if(dx>dy) py=-0.5f;
\r
819 else if(dx<dy) py= 0.5f;
\r
826 if(dx>dy) px= 0.5f;
\r
827 else if(dx<dy) px=-0.5f;
\r
837 if(dx>dy) px=-0.5f;
\r
838 else if(dx<dy) px= 0.5f;
\r
844 if(dx>dy) py=-0.5f;
\r
845 else if(dx<dy) py= 0.5f;
\r
850 vertex[0].x=(short)((float)x0-px);
\r
851 vertex[3].x=(short)((float)x0+py);
\r
853 vertex[0].y=(short)((float)y0-py);
\r
854 vertex[3].y=(short)((float)y0-px);
\r
856 vertex[1].x=(short)((float)x1-py);
\r
857 vertex[2].x=(short)((float)x1+px);
\r
859 vertex[1].y=(short)((float)y1+px);
\r
860 vertex[2].y=(short)((float)y1+py);
\r
862 if(vertex[0].x==vertex[3].x && // ortho rect? done
\r
863 vertex[1].x==vertex[2].x &&
\r
864 vertex[0].y==vertex[1].y &&
\r
865 vertex[2].y==vertex[3].y) return FALSE;
\r
866 if(vertex[0].x==vertex[1].x &&
\r
867 vertex[2].x==vertex[3].x &&
\r
868 vertex[0].y==vertex[3].y &&
\r
869 vertex[1].y==vertex[2].y) return FALSE;
\r
871 vertex[0].x-=VERTEX_OFFX; // otherwise a small offset
\r
872 vertex[0].y-=VERTEX_OFFY; // to get better accuracy
\r
873 vertex[1].x-=VERTEX_OFFX;
\r
874 vertex[1].y-=VERTEX_OFFY;
\r
875 vertex[2].x-=VERTEX_OFFX;
\r
876 vertex[2].y-=VERTEX_OFFY;
\r
877 vertex[3].x-=VERTEX_OFFX;
\r
878 vertex[3].y-=VERTEX_OFFY;
\r
883 /////////////////////////////////////////////////////////
\r
888 SetOGLDisplaySettings(1);
\r
890 if(!(dwActFixes&16))
\r
892 lx0=(short)(((int)lx0<<SIGNSHIFT)>>SIGNSHIFT);
\r
893 lx1=(short)(((int)lx1<<SIGNSHIFT)>>SIGNSHIFT);
\r
894 ly0=(short)(((int)ly0<<SIGNSHIFT)>>SIGNSHIFT);
\r
895 ly1=(short)(((int)ly1<<SIGNSHIFT)>>SIGNSHIFT);
\r
897 if(CheckCoord2()) return TRUE;
\r
900 vertex[0].x=lx0+PSXDisplay.CumulOffset.x;
\r
901 vertex[1].x=lx1+PSXDisplay.CumulOffset.x;
\r
902 vertex[0].y=ly0+PSXDisplay.CumulOffset.y;
\r
903 vertex[1].y=ly1+PSXDisplay.CumulOffset.y;
\r
908 /////////////////////////////////////////////////////////
\r
913 SetOGLDisplaySettings(1);
\r
915 if(!(dwActFixes&16))
\r
917 lx0=(short)(((int)lx0<<SIGNSHIFT)>>SIGNSHIFT);
\r
918 lx1=(short)(((int)lx1<<SIGNSHIFT)>>SIGNSHIFT);
\r
919 lx2=(short)(((int)lx2<<SIGNSHIFT)>>SIGNSHIFT);
\r
920 ly0=(short)(((int)ly0<<SIGNSHIFT)>>SIGNSHIFT);
\r
921 ly1=(short)(((int)ly1<<SIGNSHIFT)>>SIGNSHIFT);
\r
922 ly2=(short)(((int)ly2<<SIGNSHIFT)>>SIGNSHIFT);
\r
924 if(CheckCoord3()) return TRUE;
\r
927 vertex[0].x=lx0+PSXDisplay.CumulOffset.x;
\r
928 vertex[1].x=lx1+PSXDisplay.CumulOffset.x;
\r
929 vertex[2].x=lx2+PSXDisplay.CumulOffset.x;
\r
930 vertex[0].y=ly0+PSXDisplay.CumulOffset.y;
\r
931 vertex[1].y=ly1+PSXDisplay.CumulOffset.y;
\r
932 vertex[2].y=ly2+PSXDisplay.CumulOffset.y;
\r
937 /////////////////////////////////////////////////////////
\r
942 SetOGLDisplaySettings(1);
\r
944 if(!(dwActFixes&16))
\r
946 lx0=(short)(((int)lx0<<SIGNSHIFT)>>SIGNSHIFT);
\r
947 lx1=(short)(((int)lx1<<SIGNSHIFT)>>SIGNSHIFT);
\r
948 lx2=(short)(((int)lx2<<SIGNSHIFT)>>SIGNSHIFT);
\r
949 lx3=(short)(((int)lx3<<SIGNSHIFT)>>SIGNSHIFT);
\r
950 ly0=(short)(((int)ly0<<SIGNSHIFT)>>SIGNSHIFT);
\r
951 ly1=(short)(((int)ly1<<SIGNSHIFT)>>SIGNSHIFT);
\r
952 ly2=(short)(((int)ly2<<SIGNSHIFT)>>SIGNSHIFT);
\r
953 ly3=(short)(((int)ly3<<SIGNSHIFT)>>SIGNSHIFT);
\r
955 if(CheckCoord4()) return TRUE;
\r
958 vertex[0].x=lx0+PSXDisplay.CumulOffset.x;
\r
959 vertex[1].x=lx1+PSXDisplay.CumulOffset.x;
\r
960 vertex[2].x=lx2+PSXDisplay.CumulOffset.x;
\r
961 vertex[3].x=lx3+PSXDisplay.CumulOffset.x;
\r
962 vertex[0].y=ly0+PSXDisplay.CumulOffset.y;
\r
963 vertex[1].y=ly1+PSXDisplay.CumulOffset.y;
\r
964 vertex[2].y=ly2+PSXDisplay.CumulOffset.y;
\r
965 vertex[3].y=ly3+PSXDisplay.CumulOffset.y;
\r
970 /////////////////////////////////////////////////////////
\r
972 void offsetST(void)
\r
975 SetOGLDisplaySettings(1);
\r
977 if(!(dwActFixes&16))
\r
979 lx0=(short)(((int)lx0<<SIGNSHIFT)>>SIGNSHIFT);
\r
980 ly0=(short)(((int)ly0<<SIGNSHIFT)>>SIGNSHIFT);
\r
982 if(lx0<-512 && PSXDisplay.DrawOffset.x<=-512)
\r
985 if(ly0<-512 && PSXDisplay.DrawOffset.y<=-512)
\r
990 ly2 = ly3 = ly0+sprtH;
\r
992 lx1 = lx2 = lx0+sprtW;
\r
994 vertex[0].x=lx0+PSXDisplay.CumulOffset.x;
\r
995 vertex[1].x=lx1+PSXDisplay.CumulOffset.x;
\r
996 vertex[2].x=lx2+PSXDisplay.CumulOffset.x;
\r
997 vertex[3].x=lx3+PSXDisplay.CumulOffset.x;
\r
998 vertex[0].y=ly0+PSXDisplay.CumulOffset.y;
\r
999 vertex[1].y=ly1+PSXDisplay.CumulOffset.y;
\r
1000 vertex[2].y=ly2+PSXDisplay.CumulOffset.y;
\r
1001 vertex[3].y=ly3+PSXDisplay.CumulOffset.y;
\r
1004 /////////////////////////////////////////////////////////
\r
1006 void offsetScreenUpload(long Position)
\r
1008 if(bDisplayNotSet)
\r
1009 SetOGLDisplaySettings(1);
\r
1015 lmdx=xrUploadArea.x0;
\r
1016 lmdy=xrUploadArea.y0;
\r
1030 lx0-=PSXDisplay.DisplayPosition.x;
\r
1031 ly0-=PSXDisplay.DisplayPosition.y;
\r
1032 lx1-=PSXDisplay.DisplayPosition.x;
\r
1033 ly1-=PSXDisplay.DisplayPosition.y;
\r
1034 lx2-=PSXDisplay.DisplayPosition.x;
\r
1035 ly2-=PSXDisplay.DisplayPosition.y;
\r
1036 lx3-=PSXDisplay.DisplayPosition.x;
\r
1037 ly3-=PSXDisplay.DisplayPosition.y;
\r
1041 lx0-=PreviousPSXDisplay.DisplayPosition.x;
\r
1042 ly0-=PreviousPSXDisplay.DisplayPosition.y;
\r
1043 lx1-=PreviousPSXDisplay.DisplayPosition.x;
\r
1044 ly1-=PreviousPSXDisplay.DisplayPosition.y;
\r
1045 lx2-=PreviousPSXDisplay.DisplayPosition.x;
\r
1046 ly2-=PreviousPSXDisplay.DisplayPosition.y;
\r
1047 lx3-=PreviousPSXDisplay.DisplayPosition.x;
\r
1048 ly3-=PreviousPSXDisplay.DisplayPosition.y;
\r
1051 vertex[0].x=lx0 + PreviousPSXDisplay.Range.x0;
\r
1052 vertex[1].x=lx1 + PreviousPSXDisplay.Range.x0;
\r
1053 vertex[2].x=lx2 + PreviousPSXDisplay.Range.x0;
\r
1054 vertex[3].x=lx3 + PreviousPSXDisplay.Range.x0;
\r
1055 vertex[0].y=ly0 + PreviousPSXDisplay.Range.y0;
\r
1056 vertex[1].y=ly1 + PreviousPSXDisplay.Range.y0;
\r
1057 vertex[2].y=ly2 + PreviousPSXDisplay.Range.y0;
\r
1058 vertex[3].y=ly3 + PreviousPSXDisplay.Range.y0;
\r
1062 vertex[0].z=vertex[1].z=vertex[2].z=vertex[3].z=gl_z;
\r
1067 /////////////////////////////////////////////////////////
\r
1069 void offsetBlk(void)
\r
1071 if(bDisplayNotSet)
\r
1072 SetOGLDisplaySettings(1);
\r
1074 vertex[0].x=lx0-PSXDisplay.GDrawOffset.x + PreviousPSXDisplay.Range.x0;
\r
1075 vertex[1].x=lx1-PSXDisplay.GDrawOffset.x + PreviousPSXDisplay.Range.x0;
\r
1076 vertex[2].x=lx2-PSXDisplay.GDrawOffset.x + PreviousPSXDisplay.Range.x0;
\r
1077 vertex[3].x=lx3-PSXDisplay.GDrawOffset.x + PreviousPSXDisplay.Range.x0;
\r
1078 vertex[0].y=ly0-PSXDisplay.GDrawOffset.y + PreviousPSXDisplay.Range.y0;
\r
1079 vertex[1].y=ly1-PSXDisplay.GDrawOffset.y + PreviousPSXDisplay.Range.y0;
\r
1080 vertex[2].y=ly2-PSXDisplay.GDrawOffset.y + PreviousPSXDisplay.Range.y0;
\r
1081 vertex[3].y=ly3-PSXDisplay.GDrawOffset.y + PreviousPSXDisplay.Range.y0;
\r
1085 vertex[0].z=vertex[1].z=vertex[2].z=vertex[3].z=gl_z;
\r
1090 ////////////////////////////////////////////////////////////////////////
\r
1091 // texture sow/tow calculations
\r
1092 ////////////////////////////////////////////////////////////////////////
\r
1094 void assignTextureVRAMWrite(void)
\r
1098 vertex[0].sow=0.5f/ ST_FACVRAMX;
\r
1099 vertex[0].tow=0.5f/ ST_FACVRAM;
\r
1101 vertex[1].sow=(float)gl_ux[1]/ ST_FACVRAMX;
\r
1102 vertex[1].tow=0.5f/ ST_FACVRAM;
\r
1104 vertex[2].sow=(float)gl_ux[2]/ ST_FACVRAMX;
\r
1105 vertex[2].tow=(float)gl_vy[2]/ ST_FACVRAM;
\r
1107 vertex[3].sow=0.5f/ ST_FACVRAMX;
\r
1108 vertex[3].tow=(float)gl_vy[3]/ ST_FACVRAM;
\r
1114 vertex[0].sow=(gl_ux[0]*255.99f)/255.0f;
\r
1115 vertex[1].sow=(gl_ux[1]*255.99f)/255.0f;
\r
1116 vertex[2].sow=(gl_ux[2]*255.99f)/255.0f;
\r
1117 vertex[3].sow=(gl_ux[3]*255.99f)/255.0f;
\r
1121 vertex[0].sow=gl_ux[0];
\r
1122 vertex[1].sow=gl_ux[1];
\r
1123 vertex[2].sow=gl_ux[2];
\r
1124 vertex[3].sow=gl_ux[3];
\r
1127 vertex[0].tow=gl_vy[0];
\r
1128 vertex[1].tow=gl_vy[1];
\r
1129 vertex[2].tow=gl_vy[2];
\r
1130 vertex[3].tow=gl_vy[3];
\r
1135 GLuint gLastTex=0;
\r
1136 GLuint gLastFMode=(GLuint)-1;
\r
1138 /////////////////////////////////////////////////////////
\r
1140 void assignTextureSprite(void)
\r
1144 vertex[0].sow=vertex[3].sow=(float)gl_ux[0]/TWin.UScaleFactor;
\r
1145 vertex[1].sow=vertex[2].sow=(float)sSprite_ux2/TWin.UScaleFactor;
\r
1146 vertex[0].tow=vertex[1].tow=(float)gl_vy[0]/TWin.VScaleFactor;
\r
1147 vertex[2].tow=vertex[3].tow=(float)sSprite_vy2/TWin.VScaleFactor;
\r
1148 gLastTex=gTexName;
\r
1154 vertex[0].sow=vertex[3].sow=(float)gl_ux[0] / ST_FACSPRITE;
\r
1155 vertex[1].sow=vertex[2].sow=(float)sSprite_ux2 / ST_FACSPRITE;
\r
1156 vertex[0].tow=vertex[1].tow=(float)gl_vy[0] / ST_FACSPRITE;
\r
1157 vertex[2].tow=vertex[3].tow=(float)sSprite_vy2 / ST_FACSPRITE;
\r
1161 vertex[0].sow=vertex[3].sow=gl_ux[0];
\r
1162 vertex[1].sow=vertex[2].sow=sSprite_ux2;
\r
1163 vertex[0].tow=vertex[1].tow=gl_vy[0];
\r
1164 vertex[2].tow=vertex[3].tow=sSprite_vy2;
\r
1168 if(iFilterType>2)
\r
1170 if(gLastTex!=gTexName || gLastFMode!=0)
\r
1172 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
\r
1173 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
\r
1174 gLastTex=gTexName;gLastFMode=0;
\r
1179 if(usMirror & 0x1000)
\r
1181 vertex[0].sow=vertex[1].sow;
\r
1182 vertex[1].sow=vertex[2].sow=vertex[3].sow;
\r
1183 vertex[3].sow=vertex[0].sow;
\r
1186 if(usMirror & 0x2000)
\r
1188 vertex[0].tow=vertex[3].tow;
\r
1189 vertex[2].tow=vertex[3].tow=vertex[1].tow;
\r
1190 vertex[1].tow=vertex[0].tow;
\r
1195 /////////////////////////////////////////////////////////
\r
1197 void assignTexture3(void)
\r
1201 vertex[0].sow=(float)gl_ux[0]/TWin.UScaleFactor;
\r
1202 vertex[0].tow=(float)gl_vy[0]/TWin.VScaleFactor;
\r
1203 vertex[1].sow=(float)gl_ux[1]/TWin.UScaleFactor;
\r
1204 vertex[1].tow=(float)gl_vy[1]/TWin.VScaleFactor;
\r
1205 vertex[2].sow=(float)gl_ux[2]/TWin.UScaleFactor;
\r
1206 vertex[2].tow=(float)gl_vy[2]/TWin.VScaleFactor;
\r
1207 gLastTex=gTexName;
\r
1212 vertex[0].sow=(float)gl_ux[0] / ST_FACTRI;
\r
1213 vertex[0].tow=(float)gl_vy[0] / ST_FACTRI;
\r
1214 vertex[1].sow=(float)gl_ux[1] / ST_FACTRI;
\r
1216 vertex[1].tow=(float)gl_vy[1] / ST_FACTRI;
\r
1217 vertex[2].sow=(float)gl_ux[2] / ST_FACTRI;
\r
1218 vertex[2].tow=(float)gl_vy[2] / ST_FACTRI;
\r
1220 vertex[0].sow=gl_ux[0];
\r
1221 vertex[0].tow=gl_vy[0];
\r
1222 vertex[1].sow=gl_ux[1];
\r
1223 vertex[1].tow=gl_vy[1];
\r
1224 vertex[2].sow=gl_ux[2];
\r
1225 vertex[2].tow=gl_vy[2];
\r
1228 if(iFilterType>2)
\r
1230 if(gLastTex!=gTexName || gLastFMode!=1)
\r
1232 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
\r
1233 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
\r
1234 gLastTex=gTexName;gLastFMode=1;
\r
1240 float fxmin=256.0f,fxmax=0.0f,fymin=256.0f,fymax=0.0f;int i;
\r
1243 if(vertex[i].sow<fxmin) fxmin=vertex[i].sow;
\r
1244 if(vertex[i].tow<fymin) fymin=vertex[i].tow;
\r
1245 if(vertex[i].sow>fxmax) fxmax=vertex[i].sow;
\r
1246 if(vertex[i].tow>fymax) fymax=vertex[i].tow;
\r
1251 if(vertex[i].sow==fxmin) vertex[i].sow+=ST_BFFACSORT;
\r
1252 if(vertex[i].sow==fxmax) vertex[i].sow-=ST_BFFACSORT;
\r
1253 if(vertex[i].tow==fymin) vertex[i].tow+=ST_BFFACSORT;
\r
1254 if(vertex[i].tow==fymax) vertex[i].tow-=ST_BFFACSORT;
\r
1260 /////////////////////////////////////////////////////////
\r
1262 void assignTexture4(void)
\r
1266 vertex[0].sow=(float)gl_ux[0]/TWin.UScaleFactor;
\r
1267 vertex[0].tow=(float)gl_vy[0]/TWin.VScaleFactor;
\r
1268 vertex[1].sow=(float)gl_ux[1]/TWin.UScaleFactor;
\r
1269 vertex[1].tow=(float)gl_vy[1]/TWin.VScaleFactor;
\r
1270 vertex[2].sow=(float)gl_ux[2]/TWin.UScaleFactor;
\r
1271 vertex[2].tow=(float)gl_vy[2]/TWin.VScaleFactor;
\r
1272 vertex[3].sow=(float)gl_ux[3]/TWin.UScaleFactor;
\r
1273 vertex[3].tow=(float)gl_vy[3]/TWin.VScaleFactor;
\r
1274 gLastTex=gTexName;
\r
1279 vertex[0].sow=(float)gl_ux[0] / ST_FAC;
\r
1280 vertex[0].tow=(float)gl_vy[0] / ST_FAC;
\r
1281 vertex[1].sow=(float)gl_ux[1] / ST_FAC;
\r
1282 vertex[1].tow=(float)gl_vy[1] / ST_FAC;
\r
1283 vertex[2].sow=(float)gl_ux[2] / ST_FAC;
\r
1284 vertex[2].tow=(float)gl_vy[2] / ST_FAC;
\r
1285 vertex[3].sow=(float)gl_ux[3] / ST_FAC;
\r
1286 vertex[3].tow=(float)gl_vy[3] / ST_FAC;
\r
1288 vertex[0].sow=gl_ux[0];
\r
1289 vertex[0].tow=gl_vy[0];
\r
1290 vertex[1].sow=gl_ux[1];
\r
1291 vertex[1].tow=gl_vy[1];
\r
1292 vertex[2].sow=gl_ux[2];
\r
1293 vertex[2].tow=gl_vy[2];
\r
1294 vertex[3].sow=gl_ux[3];
\r
1295 vertex[3].tow=gl_vy[3];
\r
1298 if(iFilterType>2)
\r
1300 if(gLastTex!=gTexName || gLastFMode!=1)
\r
1302 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
\r
1303 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
\r
1304 gLastTex=gTexName;gLastFMode=1;
\r
1310 float fxmin=256.0f,fxmax=0.0f,fymin=256.0f,fymax=0.0f;int i;
\r
1313 if(vertex[i].sow<fxmin) fxmin=vertex[i].sow;
\r
1314 if(vertex[i].tow<fymin) fymin=vertex[i].tow;
\r
1315 if(vertex[i].sow>fxmax) fxmax=vertex[i].sow;
\r
1316 if(vertex[i].tow>fymax) fymax=vertex[i].tow;
\r
1321 if(vertex[i].sow==fxmin) vertex[i].sow+=ST_BFFACSORT;
\r
1322 if(vertex[i].sow==fxmax) vertex[i].sow-=ST_BFFACSORT;
\r
1323 if(vertex[i].tow==fymin) vertex[i].tow+=ST_BFFACSORT;
\r
1324 if(vertex[i].tow==fymax) vertex[i].tow-=ST_BFFACSORT;
\r
1330 ////////////////////////////////////////////////////////////////////////
\r
1331 ////////////////////////////////////////////////////////////////////////
\r
1332 ////////////////////////////////////////////////////////////////////////
\r
1334 ////////////////////////////////////////////////////////////////////////
\r
1335 // render pos / buffers
\r
1336 ////////////////////////////////////////////////////////////////////////
\r
1339 #define EqualRect(pr1,pr2) ((pr1)->left==(pr2)->left && (pr1)->top==(pr2)->top && (pr1)->right==(pr2)->right && (pr1)->bottom==(pr2)->bottom)
\r
1342 ////////////////////////////////////////////////////////////////////////
\r
1343 // SetDisplaySettings: "simply" calcs the new drawing area and updates
\r
1344 // the ogl clipping (scissor)
\r
1346 BOOL bSetClip=FALSE;
\r
1348 void SetOGLDisplaySettings(BOOL DisplaySet)
\r
1350 static RECT rprev={0,0,0,0};
\r
1351 static RECT rC ={0,0,0,0};
\r
1352 static int iOldX=0;
\r
1353 static int iOldY=0;
\r
1354 RECT r;float XS,YS;
\r
1356 bDisplayNotSet = FALSE;
\r
1358 //----------------------------------------------------// that's a whole screen upload
\r
1362 PSXDisplay.GDrawOffset.x=0;
\r
1363 PSXDisplay.GDrawOffset.y=0;
\r
1365 PSXDisplay.CumulOffset.x = PSXDisplay.DrawOffset.x+PreviousPSXDisplay.Range.x0;
\r
1366 PSXDisplay.CumulOffset.y = PSXDisplay.DrawOffset.y+PreviousPSXDisplay.Range.y0;
\r
1368 rprev.left=rprev.left+1;
\r
1371 rX.top=iResY-(rRatioRect.top+rRatioRect.bottom);
\r
1373 if(bSetClip || !EqualRect(&rC,&rX))
\r
1376 glScissor(rC.left,rC.top,rC.right,rC.bottom);
\r
1381 //----------------------------------------------------//
\r
1383 PSXDisplay.GDrawOffset.y = PreviousPSXDisplay.DisplayPosition.y;
\r
1384 PSXDisplay.GDrawOffset.x = PreviousPSXDisplay.DisplayPosition.x;
\r
1385 PSXDisplay.CumulOffset.x = PSXDisplay.DrawOffset.x - PSXDisplay.GDrawOffset.x+PreviousPSXDisplay.Range.x0;
\r
1386 PSXDisplay.CumulOffset.y = PSXDisplay.DrawOffset.y - PSXDisplay.GDrawOffset.y+PreviousPSXDisplay.Range.y0;
\r
1388 r.top =PSXDisplay.DrawArea.y0 - PreviousPSXDisplay.DisplayPosition.y;
\r
1389 r.bottom=PSXDisplay.DrawArea.y1 - PreviousPSXDisplay.DisplayPosition.y;
\r
1391 if(r.bottom<0 || r.top>=PSXDisplay.DisplayMode.y)
\r
1393 r.top =PSXDisplay.DrawArea.y0 - PSXDisplay.DisplayPosition.y;
\r
1394 r.bottom=PSXDisplay.DrawArea.y1 - PSXDisplay.DisplayPosition.y;
\r
1397 r.left =PSXDisplay.DrawArea.x0 - PreviousPSXDisplay.DisplayPosition.x;
\r
1398 r.right =PSXDisplay.DrawArea.x1 - PreviousPSXDisplay.DisplayPosition.x;
\r
1400 if(r.right<0 || r.left>=PSXDisplay.DisplayMode.x)
\r
1402 r.left =PSXDisplay.DrawArea.x0 - PSXDisplay.DisplayPosition.x;
\r
1403 r.right =PSXDisplay.DrawArea.x1 - PSXDisplay.DisplayPosition.x;
\r
1406 if(!bSetClip && EqualRect(&r,&rprev) &&
\r
1407 iOldX == PSXDisplay.DisplayMode.x &&
\r
1408 iOldY == PSXDisplay.DisplayMode.y)
\r
1412 iOldX = PSXDisplay.DisplayMode.x;
\r
1413 iOldY = PSXDisplay.DisplayMode.y;
\r
1415 XS=(float)rRatioRect.right/(float)PSXDisplay.DisplayMode.x;
\r
1416 YS=(float)rRatioRect.bottom/(float)PSXDisplay.DisplayMode.y;
\r
1418 if(PreviousPSXDisplay.Range.x0)
\r
1420 short s=PreviousPSXDisplay.Range.x0+PreviousPSXDisplay.Range.x1;
\r
1422 r.left+=PreviousPSXDisplay.Range.x0+1;
\r
1424 r.right+=PreviousPSXDisplay.Range.x0;
\r
1426 if(r.left>s) r.left=s;
\r
1427 if(r.right>s) r.right=s;
\r
1430 if(PreviousPSXDisplay.Range.y0)
\r
1432 short s=PreviousPSXDisplay.Range.y0+PreviousPSXDisplay.Range.y1;
\r
1434 r.top+=PreviousPSXDisplay.Range.y0+1;
\r
1435 r.bottom+=PreviousPSXDisplay.Range.y0;
\r
1437 if(r.top>s) r.top=s;
\r
1438 if(r.bottom>s) r.bottom=s;
\r
1441 // Set the ClipArea variables to reflect the new screen,
\r
1442 // offset from zero (since it is a new display buffer)
\r
1443 r.left = (int)(((float)(r.left)) *XS);
\r
1444 r.top = (int)(((float)(r.top)) *YS);
\r
1445 r.right = (int)(((float)(r.right + 1))*XS);
\r
1446 r.bottom = (int)(((float)(r.bottom + 1))*YS);
\r
1448 // Limit clip area to the screen size
\r
1449 if (r.left > iResX) r.left = iResX;
\r
1450 if (r.left < 0) r.left = 0;
\r
1451 if (r.top > iResY) r.top = iResY;
\r
1452 if (r.top < 0) r.top = 0;
\r
1453 if (r.right > iResX) r.right = iResX;
\r
1454 if (r.right < 0) r.right = 0;
\r
1455 if (r.bottom > iResY) r.bottom = iResY;
\r
1456 if (r.bottom < 0) r.bottom = 0;
\r
1460 r.top=iResY-(r.top+r.bottom);
\r
1462 r.left+=rRatioRect.left;
\r
1463 r.top -=rRatioRect.top;
\r
1465 if(bSetClip || !EqualRect(&r,&rC))
\r
1467 glScissor(r.left,r.top,r.right,r.bottom);
\r
1473 ////////////////////////////////////////////////////////////////////////
\r
1474 ////////////////////////////////////////////////////////////////////////
\r
1475 ////////////////////////////////////////////////////////////////////////
\r