2eaa8254c5b31e149186850e02aedfd176f62583
[pcsx_rearmed.git] / plugins / gpu-gles / gpuDraw.c
1 /***************************************************************************\r
2                            draw.c  -  description\r
3                              -------------------\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
8 \r
9 /***************************************************************************\r
10  *                                                                         *\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
16  *                                                                         *\r
17  ***************************************************************************/\r
18 \r
19 //*************************************************************************// \r
20 // History of changes:\r
21 //\r
22 // 2009/03/08 - Pete  \r
23 // - generic cleanup for the Peops release\r
24 //\r
25 //*************************************************************************// \r
26 \r
27 \r
28 #define _IN_DRAW\r
29 \r
30 #ifdef _WINDOWS\r
31 #include "stdafx.h"\r
32 #include <stdio.h>\r
33 #include <stdlib.h>\r
34 #include <math.h>\r
35 #include "externals.h"\r
36 #include "gpu.h"\r
37 #include "draw.h"\r
38 #include "prim.h"\r
39 #include "texture.h"\r
40 #else\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
47 \r
48 #include <stdio.h>\r
49 #include <stdlib.h>\r
50 #include <math.h>\r
51 #endif\r
52 //#include "menu.h"\r
53             \r
54 ////////////////////////////////////////////////////////////////////////////////////\r
55 // defines\r
56 \r
57 #define SIGNBIT 0x800\r
58 #define S_MASK  0xf000\r
59 #define L_MASK  0xfffff000\r
60 \r
61 // ownscale: some ogl drivers have buggy texture matrix funcs, so it\r
62 //           is safer to calc sow/tow ourselves\r
63 \r
64 #ifdef OWNSCALE\r
65 \r
66 ///////////////////////////////////////////////////////////////\r
67 \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
71 \r
72 #define ST_OFFSET          0.5f/256.0f;\r
73 \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
77 \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
81 \r
82 #define ST_FACVRAMX        255.0f\r
83 #define ST_FACVRAM         256.0f\r
84 \r
85 ///////////////////////////////////////////////////////////////\r
86 \r
87 #else\r
88 \r
89 #define ST_BFFACSPRITE     0.5f\r
90 #define ST_BFFACSPRITESORT 0.333f\r
91 \r
92 #define ST_BFFAC           0.5f\r
93 #define ST_BFFACSORT       0.333f\r
94 \r
95 #define ST_BFFACTRI        0.5f\r
96 #define ST_BFFACTRISORT    0.333f\r
97 \r
98 #define ST_OFFSET          0.5f;\r
99                 \r
100 #endif\r
101 \r
102 ////////////////////////////////////////////////////////////////////////////////////\r
103 // draw globals\r
104 \r
105 #ifdef _WINDOWS\r
106 HDC            dcGlobal=NULL;\r
107 HWND           hWWindow;\r
108 #else\r
109 void  glBlendEquationEXT(GLenum mode);\r
110 void  glColorTableEXT(GLenum target, GLenum internalFormat, GLsizei width, GLenum format,GLenum type, const GLvoid *data);\r
111 #endif\r
112 \r
113 // draw globals; most will be initialized again later (by config or checks) \r
114 \r
115 BOOL           bIsFirstFrame=TRUE;\r
116 \r
117 // resolution/ratio vars\r
118 \r
119 int            iResX;\r
120 int            iResY;\r
121 BOOL           bKeepRatio=FALSE;\r
122 RECT           rRatioRect;\r
123 \r
124 // psx mask related vars\r
125 \r
126 BOOL           bCheckMask=FALSE;\r
127 int            iUseMask=0;\r
128 int            iSetMask=0;\r
129 unsigned short sSetMask=0;\r
130 unsigned long  lSetMask=0;\r
131 \r
132 // drawing/coord vars\r
133 \r
134 OGLVertex      vertex[4];\r
135 GLubyte        gl_ux[8];\r
136 GLubyte        gl_vy[8];\r
137 short          sprtY,sprtX,sprtH,sprtW;\r
138 \r
139 // drawing options\r
140 \r
141 BOOL           bOpaquePass;\r
142 BOOL           bAdvancedBlend;\r
143 \r
144 // OGL extension support\r
145 \r
146 \r
147 // gfx card buffer infos\r
148 \r
149 int            iDepthFunc=0;\r
150 int            iZBufferDepth=0;\r
151 GLbitfield     uiBufferBits=GL_COLOR_BUFFER_BIT;\r
152 \r
153 ////////////////////////////////////////////////////////////////////////\r
154 ////////////////////////////////////////////////////////////////////////\r
155 ////////////////////////////////////////////////////////////////////////\r
156 \r
157 ////////////////////////////////////////////////////////////////////////\r
158 // Set OGL pixel format\r
159 ////////////////////////////////////////////////////////////////////////\r
160  \r
161 #ifdef _WINDOWS\r
162 BOOL bSetupPixelFormat(HDC hDC)\r
163 {\r
164  int pixelformat;\r
165  static PIXELFORMATDESCRIPTOR pfd = \r
166   {\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
179     0,                               // z-buffer    \r
180     0,\r
181     0,                               // no auxiliary buffer\r
182     PFD_MAIN_PLANE,                  // main layer\r
183     0,                               // reserved\r
184     0, 0, 0                          // layer masks ignored\r
185   };\r
186  \r
187  pfd.cColorBits=iColDepth;                             // set user color depth\r
188  pfd.cDepthBits=iZBufferDepth;                         // set user zbuffer (by psx mask)\r
189 \r
190  if((pixelformat=ChoosePixelFormat(hDC,&pfd))==0)     \r
191   {\r
192    MessageBox(NULL,"ChoosePixelFormat failed","Error",MB_OK);\r
193    return FALSE;\r
194   }\r
195 \r
196  if(SetPixelFormat(hDC,pixelformat, &pfd)==FALSE)\r
197   {\r
198    MessageBox(NULL,"SetPixelFormat failed","Error",MB_OK);\r
199    return FALSE;\r
200   }\r
201 \r
202  return TRUE;\r
203 }\r
204 #endif\r
205 \r
206 ////////////////////////////////////////////////////////////////////////\r
207 // Get extension infos (f.e. pal textures / packed pixels)\r
208 ////////////////////////////////////////////////////////////////////////\r
209 \r
210 void GetExtInfos(void)                              \r
211 {\r
212  BOOL bPacked=FALSE;                                   // default: no packed pixel support\r
213 \r
214  if(strstr((char *)glGetString(GL_EXTENSIONS),         // packed pixels available?\r
215     "GL_EXT_packed_pixels"))                          \r
216   bPacked=TRUE;                                        // -> ok\r
217 \r
218  \r
219  #ifdef _WINDOWS\r
220  iClampType=GL_CLAMP;\r
221 #else\r
222  iClampType=GL_CLAMP_TO_EDGE;\r
223 #endif\r
224 }\r
225 \r
226 ////////////////////////////////////////////////////////////////////////\r
227 // Setup some stuff depending on user settings or in-game toggle\r
228 ////////////////////////////////////////////////////////////////////////\r
229 \r
230 void SetExtGLFuncs(void)\r
231 {\r
232  //----------------------------------------------------//\r
233 \r
234  SetFixes();                                           // update fix infos\r
235 \r
236  //----------------------------------------------------//\r
237 \r
238   {\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
242 \r
243    glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);    \r
244   }\r
245 \r
246  if(bOpaquePass)                                        // opaque mode?\r
247   {\r
248    if(dwActFixes&32) \r
249     {\r
250      TCF[0]=CP8RGBA_0;\r
251      PalTexturedColourFn=CP8RGBA;                      // -> init col func\r
252     }\r
253    else\r
254     {\r
255      TCF[0]=XP8RGBA_0;\r
256      PalTexturedColourFn=XP8RGBA;                      // -> init col func\r
257     }\r
258 \r
259    TCF[1]=XP8RGBA_1;\r
260    glAlphaFuncx(GL_GREATER,0.49f);\r
261   }\r
262  else                                                  // no opaque mode?\r
263   {\r
264    TCF[0]=TCF[1]=P8RGBA;\r
265    PalTexturedColourFn=P8RGBA;                         // -> init col func\r
266    glAlphaFuncx(GL_NOTEQUAL,0);                         // --> set alpha func\r
267   }\r
268 \r
269  //----------------------------------------------------//\r
270 \r
271  LoadSubTexFn=LoadSubTexturePageSort;                  // init load tex ptr\r
272 \r
273  bBlendEnable=FALSE;                                   // init blending: off\r
274  glDisable(GL_BLEND);\r
275 \r
276  SetScanTrans();                                       // init scan lines (if wanted)\r
277 }\r
278 \r
279 ////////////////////////////////////////////////////////////////////////\r
280 // setup scan lines\r
281 ////////////////////////////////////////////////////////////////////////\r
282 \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
288 \r
289 GLuint  gTexScanName=0;\r
290 \r
291 GLubyte texscan[4][16]= \r
292 {\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
297 };\r
298 \r
299 void CreateScanLines(void)\r
300 {\r
301 }\r
302 \r
303 ////////////////////////////////////////////////////////////////////////\r
304 // Initialize OGL\r
305 ////////////////////////////////////////////////////////////////////////\r
306 \r
307 #ifdef _WINDOWS    \r
308 HGLRC GLCONTEXT=NULL;\r
309 #endif\r
310 \r
311 #define MODE_RAW 0\r
312 #define MODE_X11 1\r
313 #define MODE_SDL 2\r
314 int use_fsaa = 0;\r
315 \r
316 EGLDisplay display;\r
317 EGLConfig  config;\r
318 EGLContext context;\r
319 EGLSurface surface;\r
320 \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
325 \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
332 #endif\r
333 \r
334 EGLint attrib_list_fsaa[] =\r
335 {\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
340         EGL_SAMPLES,        4,\r
341         EGL_NONE\r
342 };\r
343 \r
344 EGLint attrib_list[] =\r
345 {\r
346 //      EGL_DEPTH_SIZE,   16,\r
347         EGL_NONE\r
348 };\r
349 \r
350 bool TestEGLError(const char* pszLocation)\r
351 {\r
352         /*\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
356         */\r
357         EGLint iErr = eglGetError();\r
358         if (iErr != EGL_SUCCESS)\r
359         {\r
360                 printf("%s failed (%d).\n", pszLocation, iErr);\r
361                 return FALSE;\r
362         }\r
363 \r
364         return TRUE;\r
365 }\r
366 \r
367 static void initEGL(void)\r
368 {\r
369         printf ("GL init\n");\r
370 \r
371         EGLint numConfigs;\r
372         EGLint majorVersion;\r
373         EGLint minorVersion;\r
374 #if defined(USE_X11)\r
375         enum\r
376         {\r
377         _NET_WM_STATE_REMOVE =0,\r
378         _NET_WM_STATE_ADD = 1,\r
379         _NET_WM_STATE_TOGGLE =2\r
380         };\r
381         \r
382         Window                          sRootWindow;\r
383         XSetWindowAttributes    sWA;\r
384         unsigned int                ui32Mask;\r
385         int                                 i32Depth;\r
386 #endif\r
387         \r
388         EGLint *attribList = NULL;\r
389         if (use_fsaa)\r
390         {\r
391                 printf( "GLES: Using Full Scene Antialiasing\n" );\r
392                 attribList = attrib_list_fsaa;\r
393         }\r
394         else\r
395         {\r
396                 attribList = attrib_list;\r
397         }\r
398 \r
399 #if defined(USE_X11)\r
400             // Initializes the display and screen\r
401             x11Display = XOpenDisplay( ":0" );\r
402             if (!x11Display)\r
403             {\r
404                 printf("GLES Error: Unable to open X display\n");\r
405             }\r
406             x11Screen = XDefaultScreen( x11Display );\r
407                                 \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
413             if (!px11Visual)\r
414             {\r
415                 printf("GLES Error: Unable to acquire visual\n");\r
416                         }\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
420 \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
423 \r
424             // Display capabilities list.\r
425             ui32Mask = CWBackPixel | CWBorderPixel | CWEventMask | CWColormap;\r
426                                                            \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
430 \r
431             // Make the window viewable and flush the output buffer.\r
432             XMapWindow(x11Display, x11Window);\r
433             XFlush(x11Display);\r
434 \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
439 \r
440             XEvent xev;\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
450 \r
451             XSendEvent(x11Display, DefaultRootWindow(x11Display), False, SubstructureRedirectMask | SubstructureNotifyMask, &xev);\r
452 \r
453             display = eglGetDisplay( (EGLNativeDisplayType)x11Display );\r
454 #else\r
455             display = eglGetDisplay( (EGLNativeDisplayType)0 );\r
456 #endif\r
457 \r
458         if( display == EGL_NO_DISPLAY )\r
459         {\r
460                 printf( "GLES EGL Error: GL No Display\n" );\r
461         }\r
462 \r
463         if( !eglInitialize( display, &majorVersion, &minorVersion ) )\r
464         {\r
465                 printf( "GLES EGL Error: eglInitialize failed\n" );\r
466         }\r
467 \r
468         if( !eglChooseConfig( display, attribList, &config, 1, &numConfigs ) )\r
469         {\r
470                 printf( "GLES EGL Error: eglChooseConfig failed\n" );\r
471         }\r
472 \r
473         context = eglCreateContext( display, config, NULL, NULL );\r
474         if( context==0 )\r
475         {\r
476                 printf( "GLES EGL Error: eglCreateContext failed\n" );\r
477         }\r
478 \r
479 #if defined(USE_X11)\r
480             surface = eglCreateWindowSurface( display, config, (EGLNativeDisplayType)x11Window, NULL );\r
481 #else\r
482             surface = eglCreateWindowSurface( display, config, (EGLNativeDisplayType)0, NULL );\r
483 #endif\r
484 \r
485     eglMakeCurrent( display, surface, surface, context );\r
486     if (!TestEGLError("eglMakeCurrent"))\r
487         printf("error eglMakeCurrent");\r
488     else\r
489         printf("GLES Window Opened\n");\r
490 }\r
491 \r
492 int GLinitialize() \r
493 {\r
494  //----------------------------------------------------// \r
495 #ifdef _WINDOWS\r
496  HGLRC objectRC;\r
497  // init\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
504 #endif\r
505  initEGL();\r
506 \r
507  //----------------------------------------------------// \r
508 \r
509  glViewport(rRatioRect.left,                           // init viewport by ratio rect\r
510             iResY-(rRatioRect.top+rRatioRect.bottom),\r
511             rRatioRect.right, \r
512             rRatioRect.bottom);         \r
513                                                       \r
514  glScissor(0, 0, iResX, iResY);                        // init clipping (fullscreen)\r
515  glEnable(GL_SCISSOR_TEST);                       \r
516 \r
517 #ifndef OWNSCALE\r
518  glMatrixMode(GL_TEXTURE);                             // init psx tex sow and tow if not "ownscale"\r
519  glLoadIdentity();\r
520  glScalef(1.0f/255.99f,1.0f/255.99f,1.0f);             // geforce precision hack\r
521 #endif \r
522 \r
523  glMatrixMode(GL_PROJECTION);                          // init projection with psx resolution\r
524  glLoadIdentity();\r
525  glOrtho(0,PSXDisplay.DisplayMode.x,\r
526          PSXDisplay.DisplayMode.y, 0, -1, 1);\r
527 \r
528  if(iZBufferDepth)                                     // zbuffer?\r
529   {\r
530    uiBufferBits=GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT;\r
531    glEnable(GL_DEPTH_TEST);    \r
532    glDepthFunc(GL_ALWAYS);\r
533    iDepthFunc=1;\r
534   }\r
535  else                                                  // no zbuffer?\r
536   {\r
537    uiBufferBits=GL_COLOR_BUFFER_BIT;\r
538    glDisable(GL_DEPTH_TEST);\r
539   }\r
540 \r
541  glClearColor(0.0f, 0.0f, 0.0f, 0.0f);                 // first buffer clear\r
542  glClear(uiBufferBits);\r
543 \r
544  GetExtInfos();                                        // get ext infos\r
545  SetExtGLFuncs();                                      // init all kind of stuff (tex function pointers)\r
546  \r
547  glEnable(GL_ALPHA_TEST);                              // wanna alpha test\r
548 \r
549   {\r
550    glDisable(GL_LINE_SMOOTH);\r
551    glDisable(GL_POINT_SMOOTH);\r
552   }\r
553 \r
554  ubGloAlpha=127;                                       // init some drawing vars\r
555  ubGloColAlpha=127;\r
556  TWin.UScaleFactor = 1;\r
557  TWin.VScaleFactor = 1;\r
558  bDrawMultiPass=FALSE;\r
559  bTexEnabled=FALSE;\r
560  bUsingTWin=FALSE;\r
561       \r
562  if(bDrawDither)  glEnable(GL_DITHER);                 // dither mode\r
563  else             glDisable(GL_DITHER); \r
564 \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
570 \r
571  glFlush();                                            // we are done...\r
572  glFinish();                           \r
573 \r
574  CreateScanLines();                                    // setup scanline stuff (if wanted)\r
575 \r
576  CheckTextureMemory();                                 // check available tex memory\r
577 \r
578  if(bKeepRatio) SetAspectRatio();                      // set ratio\r
579 \r
580  \r
581  bIsFirstFrame = FALSE;                                // we have survived the first frame :)\r
582 \r
583  return 0;\r
584 }\r
585 \r
586 ////////////////////////////////////////////////////////////////////////\r
587 // clean up OGL stuff\r
588 ////////////////////////////////////////////////////////////////////////\r
589 \r
590 void GLcleanup() \r
591 {                                                     \r
592  CleanupTextureStore();                                // bye textures\r
593 \r
594 #ifdef _WINDOWS \r
595  wglMakeCurrent(NULL, NULL);                           // bye context\r
596  if(GLCONTEXT) wglDeleteContext(GLCONTEXT);\r
597  if(!bWindowMode && dcGlobal) \r
598   ReleaseDC(hWWindow,dcGlobal);\r
599 #endif\r
600 \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
605 \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
610 #endif\r
611 }\r
612 \r
613 ////////////////////////////////////////////////////////////////////////\r
614 ////////////////////////////////////////////////////////////////////////\r
615 ////////////////////////////////////////////////////////////////////////\r
616 \r
617 ////////////////////////////////////////////////////////////////////////\r
618 ////////////////////////////////////////////////////////////////////////\r
619 ////////////////////////////////////////////////////////////////////////\r
620 \r
621 ////////////////////////////////////////////////////////////////////////\r
622 // Offset stuff\r
623 ////////////////////////////////////////////////////////////////////////\r
624 \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
628 \r
629 __inline BOOL CheckCoord4()\r
630 {\r
631  if(lx0<0)\r
632   {\r
633    if(((lx1-lx0)>CHKMAX_X) ||\r
634       ((lx2-lx0)>CHKMAX_X)) \r
635     {\r
636      if(lx3<0)\r
637       {\r
638        if((lx1-lx3)>CHKMAX_X) return TRUE;\r
639        if((lx2-lx3)>CHKMAX_X) return TRUE;\r
640       }\r
641     }\r
642   }\r
643  if(lx1<0)\r
644   {\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
648   }\r
649  if(lx2<0)\r
650   {\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
654   }\r
655  if(lx3<0)\r
656   {\r
657    if(((lx1-lx3)>CHKMAX_X) ||\r
658       ((lx2-lx3)>CHKMAX_X))\r
659     {\r
660      if(lx0<0)\r
661       {\r
662        if((lx1-lx0)>CHKMAX_X) return TRUE;\r
663        if((lx2-lx0)>CHKMAX_X) return TRUE;\r
664       }\r
665     }\r
666   }\r
667  \r
668 \r
669  if(ly0<0)\r
670   {\r
671    if((ly1-ly0)>CHKMAX_Y) return TRUE;\r
672    if((ly2-ly0)>CHKMAX_Y) return TRUE;\r
673   }\r
674  if(ly1<0)\r
675   {\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
679   }\r
680  if(ly2<0)\r
681   {\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
685   }\r
686  if(ly3<0)\r
687   {\r
688    if((ly1-ly3)>CHKMAX_Y) return TRUE;\r
689    if((ly2-ly3)>CHKMAX_Y) return TRUE;\r
690   }\r
691 \r
692  return FALSE;\r
693 }\r
694 \r
695 __inline BOOL CheckCoord3()\r
696 {\r
697  if(lx0<0)\r
698   {\r
699    if((lx1-lx0)>CHKMAX_X) return TRUE;\r
700    if((lx2-lx0)>CHKMAX_X) return TRUE;\r
701   }\r
702  if(lx1<0)\r
703   {\r
704    if((lx0-lx1)>CHKMAX_X) return TRUE;\r
705    if((lx2-lx1)>CHKMAX_X) return TRUE;\r
706   }\r
707  if(lx2<0)\r
708   {\r
709    if((lx0-lx2)>CHKMAX_X) return TRUE;\r
710    if((lx1-lx2)>CHKMAX_X) return TRUE;\r
711   }\r
712  if(ly0<0)\r
713   {\r
714    if((ly1-ly0)>CHKMAX_Y) return TRUE;\r
715    if((ly2-ly0)>CHKMAX_Y) return TRUE;\r
716   }\r
717  if(ly1<0)\r
718   {\r
719    if((ly0-ly1)>CHKMAX_Y) return TRUE;\r
720    if((ly2-ly1)>CHKMAX_Y) return TRUE;\r
721   }\r
722  if(ly2<0)\r
723   {\r
724    if((ly0-ly2)>CHKMAX_Y) return TRUE;\r
725    if((ly1-ly2)>CHKMAX_Y) return TRUE;\r
726   }\r
727 \r
728  return FALSE;\r
729 }\r
730 \r
731 \r
732 __inline BOOL CheckCoord2()\r
733 {\r
734  if(lx0<0)\r
735   {\r
736    if((lx1-lx0)>CHKMAX_X) return TRUE;\r
737   }\r
738  if(lx1<0)\r
739   {\r
740    if((lx0-lx1)>CHKMAX_X) return TRUE;\r
741   }\r
742  if(ly0<0)\r
743   {\r
744    if((ly1-ly0)>CHKMAX_Y) return TRUE;\r
745   }\r
746  if(ly1<0)\r
747   {\r
748    if((ly0-ly1)>CHKMAX_Y) return TRUE;\r
749   }\r
750 \r
751  return FALSE;\r
752 }\r
753 \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
756 \r
757 #define VERTEX_OFFX 0.2f\r
758 #define VERTEX_OFFY 0.2f\r
759 \r
760 BOOL offsetline(void)           \r
761 {\r
762  short x0,x1,y0,y1,dx,dy;float px,py;\r
763 \r
764  if(bDisplayNotSet)\r
765   SetOGLDisplaySettings(1);\r
766 \r
767  if(!(dwActFixes&16))\r
768   {\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
773 \r
774    if(CheckCoord2()) return TRUE;\r
775   }\r
776 \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
781  \r
782  dx=x1-x0;\r
783  dy=y1-y0;\r
784  \r
785  if(dx>=0)\r
786   {\r
787    if(dy>=0)\r
788     {\r
789      px=0.5f;\r
790           if(dx>dy) py=-0.5f;\r
791      else if(dx<dy) py= 0.5f;\r
792      else           py= 0.0f;\r
793     }\r
794    else\r
795     {\r
796      py=-0.5f;\r
797      dy=-dy;\r
798           if(dx>dy) px= 0.5f;\r
799      else if(dx<dy) px=-0.5f;\r
800      else           px= 0.0f;\r
801     }\r
802   }\r
803  else\r
804   {\r
805    if(dy>=0)\r
806     {\r
807      py=0.5f;\r
808      dx=-dx;\r
809           if(dx>dy) px=-0.5f;\r
810      else if(dx<dy) px= 0.5f;\r
811      else           px= 0.0f;\r
812     }\r
813    else\r
814     {\r
815      px=-0.5f;\r
816           if(dx>dy) py=-0.5f;\r
817      else if(dx<dy) py= 0.5f;\r
818      else           py= 0.0f;\r
819     }\r
820   } \r
821  \r
822  vertex[0].x=(short)((float)x0-px);\r
823  vertex[3].x=(short)((float)x0+py);\r
824  \r
825  vertex[0].y=(short)((float)y0-py);\r
826  vertex[3].y=(short)((float)y0-px);\r
827  \r
828  vertex[1].x=(short)((float)x1-py);\r
829  vertex[2].x=(short)((float)x1+px);\r
830 \r
831  vertex[1].y=(short)((float)y1+px);\r
832  vertex[2].y=(short)((float)y1+py);\r
833 \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
842 \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
851 \r
852  return FALSE;\r
853 }\r
854 \r
855 ///////////////////////////////////////////////////////// \r
856 \r
857 BOOL offset2(void)\r
858 {\r
859  if(bDisplayNotSet)\r
860   SetOGLDisplaySettings(1);\r
861 \r
862  if(!(dwActFixes&16))\r
863   {\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
868 \r
869    if(CheckCoord2()) return TRUE;\r
870   }\r
871 \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
876 \r
877  return FALSE;\r
878 }\r
879 \r
880 ///////////////////////////////////////////////////////// \r
881 \r
882 BOOL offset3(void)\r
883 {\r
884  if(bDisplayNotSet)\r
885   SetOGLDisplaySettings(1);\r
886 \r
887  if(!(dwActFixes&16))\r
888   {\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
895 \r
896    if(CheckCoord3()) return TRUE;\r
897   }\r
898 \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
905 \r
906  return FALSE;\r
907 }\r
908 \r
909 ///////////////////////////////////////////////////////// \r
910 \r
911 BOOL offset4(void)\r
912 {\r
913  if(bDisplayNotSet)\r
914   SetOGLDisplaySettings(1);\r
915 \r
916  if(!(dwActFixes&16))\r
917   {\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
926 \r
927    if(CheckCoord4()) return TRUE;\r
928   }\r
929 \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
938 \r
939  return FALSE;\r
940 }\r
941 \r
942 ///////////////////////////////////////////////////////// \r
943 \r
944 void offsetST(void)\r
945 {\r
946  if(bDisplayNotSet)\r
947   SetOGLDisplaySettings(1);\r
948 \r
949  if(!(dwActFixes&16))\r
950   {\r
951    lx0=(short)(((int)lx0<<SIGNSHIFT)>>SIGNSHIFT);\r
952    ly0=(short)(((int)ly0<<SIGNSHIFT)>>SIGNSHIFT);\r
953 \r
954    if(lx0<-512 && PSXDisplay.DrawOffset.x<=-512)\r
955     lx0+=2048;\r
956 \r
957    if(ly0<-512 && PSXDisplay.DrawOffset.y<=-512)\r
958     ly0+=2048;\r
959   }\r
960 \r
961  ly1 = ly0;\r
962  ly2 = ly3 = ly0+sprtH;\r
963  lx3 = lx0;\r
964  lx1 = lx2 = lx0+sprtW;\r
965 \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
974 }\r
975 \r
976 ///////////////////////////////////////////////////////// \r
977 \r
978 void offsetScreenUpload(long Position)\r
979 {\r
980  if(bDisplayNotSet)\r
981   SetOGLDisplaySettings(1);\r
982 \r
983  if(Position==-1)\r
984   {\r
985    long lmdx,lmdy;\r
986 \r
987    lmdx=xrUploadArea.x0;\r
988    lmdy=xrUploadArea.y0;\r
989 \r
990    lx0-=lmdx;\r
991    ly0-=lmdy;\r
992    lx1-=lmdx;\r
993    ly1-=lmdy;\r
994    lx2-=lmdx;\r
995    ly2-=lmdy;\r
996    lx3-=lmdx;\r
997    ly3-=lmdy;\r
998   }\r
999  else\r
1000  if(Position)\r
1001   {\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
1010   }\r
1011  else\r
1012   {\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
1021   }\r
1022 \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
1031 \r
1032  if(iUseMask)\r
1033   {\r
1034    vertex[0].z=vertex[1].z=vertex[2].z=vertex[3].z=gl_z;\r
1035    gl_z+=0.00004f;\r
1036   }\r
1037 }\r
1038  \r
1039 ///////////////////////////////////////////////////////// \r
1040 \r
1041 void offsetBlk(void)\r
1042 {\r
1043  if(bDisplayNotSet)\r
1044   SetOGLDisplaySettings(1);\r
1045                                             \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
1054 \r
1055  if(iUseMask)\r
1056   {\r
1057    vertex[0].z=vertex[1].z=vertex[2].z=vertex[3].z=gl_z;\r
1058    gl_z+=0.00004f;\r
1059   }\r
1060 }\r
1061 \r
1062 ////////////////////////////////////////////////////////////////////////\r
1063 // texture sow/tow calculations\r
1064 ////////////////////////////////////////////////////////////////////////\r
1065 \r
1066 void assignTextureVRAMWrite(void)\r
1067 {\r
1068 #ifdef OWNSCALE\r
1069 \r
1070  vertex[0].sow=0.5f/ ST_FACVRAMX;\r
1071  vertex[0].tow=0.5f/ ST_FACVRAM;\r
1072 \r
1073  vertex[1].sow=(float)gl_ux[1]/ ST_FACVRAMX;\r
1074  vertex[1].tow=0.5f/ ST_FACVRAM;\r
1075 \r
1076  vertex[2].sow=(float)gl_ux[2]/ ST_FACVRAMX;\r
1077  vertex[2].tow=(float)gl_vy[2]/ ST_FACVRAM;\r
1078 \r
1079  vertex[3].sow=0.5f/ ST_FACVRAMX;\r
1080  vertex[3].tow=(float)gl_vy[3]/ ST_FACVRAM;\r
1081 \r
1082 #else\r
1083 \r
1084  if(gl_ux[1]==255)\r
1085   {\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
1090   }\r
1091  else\r
1092   {\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
1097   }\r
1098 \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
1103 \r
1104 #endif\r
1105 }\r
1106 \r
1107 GLuint  gLastTex=0;\r
1108 GLuint  gLastFMode=(GLuint)-1;\r
1109 \r
1110 ///////////////////////////////////////////////////////// \r
1111 \r
1112 void assignTextureSprite(void)\r
1113 {\r
1114  if(bUsingTWin)\r
1115   {\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
1121   }\r
1122  else\r
1123   {\r
1124 #ifdef OWNSCALE\r
1125 \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
1130 \r
1131 #else\r
1132  \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
1137 \r
1138 #endif\r
1139 \r
1140    if(iFilterType>2) \r
1141     {\r
1142      if(gLastTex!=gTexName || gLastFMode!=0)\r
1143       {\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
1147       }\r
1148     }\r
1149   }\r
1150 \r
1151  if(usMirror & 0x1000) \r
1152   {\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
1156   }\r
1157 \r
1158  if(usMirror & 0x2000) \r
1159   {\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
1163   }\r
1164 \r
1165 }\r
1166 \r
1167 ///////////////////////////////////////////////////////// \r
1168 \r
1169 void assignTexture3(void)\r
1170 {\r
1171  if(bUsingTWin)\r
1172   {\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
1180   }\r
1181  else\r
1182   {\r
1183 #ifdef OWNSCALE\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
1187 \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
1191 #else\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
1198 #endif\r
1199 \r
1200    if(iFilterType>2) \r
1201     {\r
1202      if(gLastTex!=gTexName || gLastFMode!=1)\r
1203       {\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
1207       }\r
1208     }\r
1209 \r
1210    if(iFilterType) \r
1211     {\r
1212      float fxmin=256.0f,fxmax=0.0f,fymin=256.0f,fymax=0.0f;int i;\r
1213      for(i=0;i<3;i++)\r
1214       {\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
1219       }\r
1220 \r
1221      for(i=0;i<3;i++)\r
1222       {\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
1227       }\r
1228     }\r
1229   }\r
1230 }\r
1231 \r
1232 ///////////////////////////////////////////////////////// \r
1233 \r
1234 void assignTexture4(void)\r
1235 {\r
1236  if(bUsingTWin)\r
1237   {\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
1247   }\r
1248  else\r
1249   {\r
1250 #ifdef OWNSCALE\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
1259 #else\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
1268 #endif\r
1269 \r
1270    if(iFilterType>2) \r
1271     {\r
1272      if(gLastTex!=gTexName || gLastFMode!=1)\r
1273       {\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
1277       }\r
1278     }\r
1279 \r
1280    if(iFilterType) \r
1281     {\r
1282      float fxmin=256.0f,fxmax=0.0f,fymin=256.0f,fymax=0.0f;int i;\r
1283      for(i=0;i<4;i++)\r
1284       {\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
1289       }\r
1290 \r
1291      for(i=0;i<4;i++)\r
1292       {\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
1297       }\r
1298     }\r
1299   }\r
1300 }\r
1301 \r
1302 ////////////////////////////////////////////////////////////////////////\r
1303 ////////////////////////////////////////////////////////////////////////\r
1304 ////////////////////////////////////////////////////////////////////////\r
1305 \r
1306 ////////////////////////////////////////////////////////////////////////\r
1307 // render pos / buffers\r
1308 ////////////////////////////////////////////////////////////////////////\r
1309 \r
1310 #ifndef _WINDOWS\r
1311 #define EqualRect(pr1,pr2) ((pr1)->left==(pr2)->left && (pr1)->top==(pr2)->top && (pr1)->right==(pr2)->right && (pr1)->bottom==(pr2)->bottom)\r
1312 #endif\r
1313 \r
1314 ////////////////////////////////////////////////////////////////////////\r
1315 // SetDisplaySettings: "simply" calcs the new drawing area and updates\r
1316 //                     the ogl clipping (scissor) \r
1317 \r
1318 BOOL bSetClip=FALSE;\r
1319 \r
1320 void SetOGLDisplaySettings(BOOL DisplaySet)\r
1321 {\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
1327 \r
1328  bDisplayNotSet = FALSE;\r
1329 \r
1330  //----------------------------------------------------// that's a whole screen upload\r
1331  if(!DisplaySet)\r
1332   {\r
1333    RECT rX;\r
1334    PSXDisplay.GDrawOffset.x=0;\r
1335    PSXDisplay.GDrawOffset.y=0;\r
1336 \r
1337    PSXDisplay.CumulOffset.x = PSXDisplay.DrawOffset.x+PreviousPSXDisplay.Range.x0;\r
1338    PSXDisplay.CumulOffset.y = PSXDisplay.DrawOffset.y+PreviousPSXDisplay.Range.y0;\r
1339 \r
1340    rprev.left=rprev.left+1;\r
1341 \r
1342    rX=rRatioRect;\r
1343    rX.top=iResY-(rRatioRect.top+rRatioRect.bottom);\r
1344 \r
1345    if(bSetClip || !EqualRect(&rC,&rX))\r
1346     {\r
1347      rC=rX;\r
1348      glScissor(rC.left,rC.top,rC.right,rC.bottom);\r
1349      bSetClip=FALSE; \r
1350     }\r
1351    return;\r
1352   }\r
1353  //----------------------------------------------------// \r
1354 \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
1359 \r
1360  r.top   =PSXDisplay.DrawArea.y0 - PreviousPSXDisplay.DisplayPosition.y;\r
1361  r.bottom=PSXDisplay.DrawArea.y1 - PreviousPSXDisplay.DisplayPosition.y;\r
1362 \r
1363  if(r.bottom<0 || r.top>=PSXDisplay.DisplayMode.y)\r
1364   {\r
1365    r.top   =PSXDisplay.DrawArea.y0 - PSXDisplay.DisplayPosition.y;\r
1366    r.bottom=PSXDisplay.DrawArea.y1 - PSXDisplay.DisplayPosition.y;\r
1367   }\r
1368 \r
1369  r.left  =PSXDisplay.DrawArea.x0 - PreviousPSXDisplay.DisplayPosition.x;\r
1370  r.right =PSXDisplay.DrawArea.x1 - PreviousPSXDisplay.DisplayPosition.x;\r
1371 \r
1372  if(r.right<0 || r.left>=PSXDisplay.DisplayMode.x)\r
1373   {\r
1374    r.left  =PSXDisplay.DrawArea.x0 - PSXDisplay.DisplayPosition.x;\r
1375    r.right =PSXDisplay.DrawArea.x1 - PSXDisplay.DisplayPosition.x;\r
1376   }\r
1377 \r
1378  if(!bSetClip && EqualRect(&r,&rprev) &&\r
1379     iOldX == PSXDisplay.DisplayMode.x &&\r
1380     iOldY == PSXDisplay.DisplayMode.y)\r
1381   return;\r
1382 \r
1383  rprev = r;\r
1384  iOldX = PSXDisplay.DisplayMode.x;\r
1385  iOldY = PSXDisplay.DisplayMode.y;\r
1386 \r
1387  XS=(float)rRatioRect.right/(float)PSXDisplay.DisplayMode.x;\r
1388  YS=(float)rRatioRect.bottom/(float)PSXDisplay.DisplayMode.y;\r
1389 \r
1390  if(PreviousPSXDisplay.Range.x0)\r
1391   {\r
1392    short s=PreviousPSXDisplay.Range.x0+PreviousPSXDisplay.Range.x1;\r
1393 \r
1394    r.left+=PreviousPSXDisplay.Range.x0+1;\r
1395 \r
1396    r.right+=PreviousPSXDisplay.Range.x0;\r
1397 \r
1398    if(r.left>s)  r.left=s;\r
1399    if(r.right>s) r.right=s;\r
1400   }\r
1401 \r
1402  if(PreviousPSXDisplay.Range.y0)\r
1403   {\r
1404    short s=PreviousPSXDisplay.Range.y0+PreviousPSXDisplay.Range.y1;\r
1405 \r
1406    r.top+=PreviousPSXDisplay.Range.y0+1;\r
1407    r.bottom+=PreviousPSXDisplay.Range.y0;\r
1408 \r
1409    if(r.top>s)    r.top=s;\r
1410    if(r.bottom>s) r.bottom=s;\r
1411   }\r
1412 \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
1419 \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
1429 \r
1430  r.right -=r.left;\r
1431  r.bottom-=r.top;\r
1432  r.top=iResY-(r.top+r.bottom);\r
1433 \r
1434  r.left+=rRatioRect.left;\r
1435  r.top -=rRatioRect.top;\r
1436 \r
1437  if(bSetClip || !EqualRect(&r,&rC))\r
1438   {\r
1439    glScissor(r.left,r.top,r.right,r.bottom);\r
1440    rC=r;\r
1441    bSetClip=FALSE;\r
1442   }\r
1443 }\r
1444 \r
1445 ////////////////////////////////////////////////////////////////////////\r
1446 ////////////////////////////////////////////////////////////////////////\r
1447 ////////////////////////////////////////////////////////////////////////\r
1448 \r