3d09c333eef91b8571fc9699547ea6aef0cab3f6
[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((s8 *)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 #ifdef MAEMO_CHANGES\r
312 bool TestEGLError(const char* pszLocation)\r
313 {\r
314         /*\r
315                 eglGetError returns the last error that has happened using egl,\r
316                 not the status of the last called function. The user has to\r
317                 check after every single egl call or at least once every frame.\r
318         */\r
319         EGLint iErr = eglGetError();\r
320         if (iErr != EGL_SUCCESS)\r
321         {\r
322                 printf("%s failed (%d).\n", pszLocation, iErr);\r
323                 return false;\r
324         }\r
325 \r
326         return true;\r
327 }\r
328 \r
329 void maemoGLinit(){\r
330         iResX= 800;\r
331     iResY =480;\r
332 \r
333         \r
334         printf ("maemo GL init\n");\r
335         long int winxid=GDK_WINDOW_XID(GTK_WIDGET(windowG)->window);\r
336         printf ("%d\n",winxid);\r
337         \r
338         EGLContext                      context = 0;\r
339         EGLConfig                       eglConfig       = 0;\r
340         EGLContext                      eglContext      = 0;\r
341         display = eglGetDisplay( EGL_DEFAULT_DISPLAY );\r
342         \r
343         if( eglInitialize( display, NULL, NULL ) == EGL_FALSE )\r
344             {            \r
345                 printf( "EGL Initialize failed!\n" );\r
346                                 \r
347                         }\r
348 \r
349 const EGLint attributeList[] = { \r
350                                      EGL_SURFACE_TYPE, EGL_WINDOW_BIT, \r
351                                      /*EGL_BUFFER_SIZE, 32, */\r
352                                      EGL_NONE \r
353                                    };\r
354                                                            \r
355         EGLint pi32ConfigAttribs[5];\r
356         pi32ConfigAttribs[0] = EGL_SURFACE_TYPE;\r
357         pi32ConfigAttribs[1] = EGL_WINDOW_BIT;\r
358         pi32ConfigAttribs[2] = EGL_RENDERABLE_TYPE;\r
359         pi32ConfigAttribs[3] = EGL_OPENGL_ES2_BIT;      \r
360         pi32ConfigAttribs[4] = EGL_NONE;\r
361 \r
362         EGLint pi32ContextAttribs[3];\r
363         pi32ContextAttribs[0] = EGL_CONTEXT_CLIENT_VERSION;\r
364         pi32ContextAttribs[1] = 2;\r
365         pi32ContextAttribs[2] = EGL_NONE;\r
366 \r
367         int iConfigs;\r
368         if (!eglChooseConfig(display, attributeList, &eglConfig, 1, &iConfigs) || (iConfigs != 1))\r
369         {\r
370                 printf("Error: eglChooseConfig() failed.\n");\r
371         }\r
372         printf ("%d\n",iConfigs);\r
373         surface = eglCreateWindowSurface(display, eglConfig, (void*)winxid, NULL);\r
374         printf ("%d\n",surface);\r
375     if (!TestEGLError("eglCreateWindowSurface"))\r
376         {\r
377                 printf ("eglCreateWindowSurface fail");\r
378         }\r
379 \r
380         //context = eglCreateContext(display, eglConfig, NULL, pi32ContextAttribs);\r
381         context =eglCreateContext( display, eglConfig,\r
382                                     EGL_NO_CONTEXT, NULL \r
383                                   );\r
384 printf ("%d\n",context);\r
385         if (!TestEGLError("eglCreateContext"))\r
386         {\r
387                 printf("error eglCreateContext");\r
388         }\r
389 \r
390         eglMakeCurrent(display, surface, surface, context);\r
391 \r
392         if (!TestEGLError("eglMakeCurrent"))\r
393         {\r
394                 printf("error eglMakeCurrent");\r
395         }\r
396 }\r
397 #endif\r
398 \r
399 int GLinitialize() \r
400 {\r
401  //----------------------------------------------------// \r
402 #ifdef _WINDOWS\r
403  HGLRC objectRC;\r
404  // init\r
405  dcGlobal = GetDC(hWWindow);                           // FIRST: dc/rc stuff\r
406  objectRC = wglCreateContext(dcGlobal); \r
407  GLCONTEXT=objectRC;\r
408  wglMakeCurrent(dcGlobal, objectRC);\r
409  // CheckWGLExtensions(dcGlobal);\r
410  if(bWindowMode) ReleaseDC(hWWindow,dcGlobal);         // win mode: release dc again\r
411 #endif\r
412 #ifdef MAEMO_CHANGES\r
413          maemoGLinit();\r
414 #endif\r
415  //----------------------------------------------------// \r
416 \r
417  glViewport(rRatioRect.left,                           // init viewport by ratio rect\r
418             iResY-(rRatioRect.top+rRatioRect.bottom),\r
419             rRatioRect.right, \r
420             rRatioRect.bottom);         \r
421                                                       \r
422  glScissor(0, 0, iResX, iResY);                        // init clipping (fullscreen)\r
423  glEnable(GL_SCISSOR_TEST);                       \r
424 \r
425 #ifndef OWNSCALE\r
426  glMatrixMode(GL_TEXTURE);                             // init psx tex sow and tow if not "ownscale"\r
427  glLoadIdentity();\r
428  glScalef(1.0f/255.99f,1.0f/255.99f,1.0f);             // geforce precision hack\r
429 #endif \r
430 \r
431  glMatrixMode(GL_PROJECTION);                          // init projection with psx resolution\r
432  glLoadIdentity();\r
433  glOrtho(0,PSXDisplay.DisplayMode.x,\r
434          PSXDisplay.DisplayMode.y, 0, -1, 1);\r
435 \r
436  if(iZBufferDepth)                                     // zbuffer?\r
437   {\r
438    uiBufferBits=GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT;\r
439    glEnable(GL_DEPTH_TEST);    \r
440    glDepthFunc(GL_ALWAYS);\r
441    iDepthFunc=1;\r
442   }\r
443  else                                                  // no zbuffer?\r
444   {\r
445    uiBufferBits=GL_COLOR_BUFFER_BIT;\r
446    glDisable(GL_DEPTH_TEST);\r
447   }\r
448 \r
449  glClearColor(0.0f, 0.0f, 0.0f, 0.0f);                 // first buffer clear\r
450  glClear(uiBufferBits);\r
451 \r
452  GetExtInfos();                                        // get ext infos\r
453  SetExtGLFuncs();                                      // init all kind of stuff (tex function pointers)\r
454  \r
455  glEnable(GL_ALPHA_TEST);                              // wanna alpha test\r
456 \r
457   {\r
458    glDisable(GL_LINE_SMOOTH);\r
459    glDisable(GL_POINT_SMOOTH);\r
460   }\r
461 \r
462  ubGloAlpha=127;                                       // init some drawing vars\r
463  ubGloColAlpha=127;\r
464  TWin.UScaleFactor = 1;\r
465  TWin.VScaleFactor = 1;\r
466  bDrawMultiPass=FALSE;\r
467  bTexEnabled=FALSE;\r
468  bUsingTWin=FALSE;\r
469       \r
470  if(bDrawDither)  glEnable(GL_DITHER);                 // dither mode\r
471  else             glDisable(GL_DITHER); \r
472 \r
473  glDisable(GL_FOG);                                    // turn all (currently) unused modes off\r
474  glDisable(GL_LIGHTING);  \r
475  glDisable(GL_STENCIL_TEST);  \r
476  glDisable(GL_TEXTURE_2D);\r
477  glDisable(GL_CULL_FACE);\r
478 \r
479  glFlush();                                            // we are done...\r
480  glFinish();                           \r
481 \r
482  CreateScanLines();                                    // setup scanline stuff (if wanted)\r
483 \r
484  CheckTextureMemory();                                 // check available tex memory\r
485 \r
486  if(bKeepRatio) SetAspectRatio();                      // set ratio\r
487 \r
488  \r
489  bIsFirstFrame = FALSE;                                // we have survived the first frame :)\r
490 \r
491  return 0;\r
492 }\r
493 \r
494 ////////////////////////////////////////////////////////////////////////\r
495 // clean up OGL stuff\r
496 ////////////////////////////////////////////////////////////////////////\r
497 \r
498 void GLcleanup() \r
499 {                                                     \r
500  CleanupTextureStore();                                // bye textures\r
501 \r
502 #ifdef _WINDOWS \r
503  wglMakeCurrent(NULL, NULL);                           // bye context\r
504  if(GLCONTEXT) wglDeleteContext(GLCONTEXT);\r
505  if(!bWindowMode && dcGlobal) \r
506   ReleaseDC(hWWindow,dcGlobal);\r
507 #endif\r
508 }\r
509 \r
510 ////////////////////////////////////////////////////////////////////////\r
511 ////////////////////////////////////////////////////////////////////////\r
512 ////////////////////////////////////////////////////////////////////////\r
513 \r
514 ////////////////////////////////////////////////////////////////////////\r
515 ////////////////////////////////////////////////////////////////////////\r
516 ////////////////////////////////////////////////////////////////////////\r
517 \r
518 ////////////////////////////////////////////////////////////////////////\r
519 // Offset stuff\r
520 ////////////////////////////////////////////////////////////////////////\r
521 \r
522 // please note: it is hardly do-able in a hw/accel plugin to get the \r
523 //              real psx polygon coord mapping right... the following\r
524 //              works not to bad with many games, though\r
525 \r
526 __inline BOOL CheckCoord4()\r
527 {\r
528  if(lx0<0)\r
529   {\r
530    if(((lx1-lx0)>CHKMAX_X) ||\r
531       ((lx2-lx0)>CHKMAX_X)) \r
532     {\r
533      if(lx3<0)\r
534       {\r
535        if((lx1-lx3)>CHKMAX_X) return TRUE;\r
536        if((lx2-lx3)>CHKMAX_X) return TRUE;\r
537       }\r
538     }\r
539   }\r
540  if(lx1<0)\r
541   {\r
542    if((lx0-lx1)>CHKMAX_X) return TRUE;\r
543    if((lx2-lx1)>CHKMAX_X) return TRUE;\r
544    if((lx3-lx1)>CHKMAX_X) return TRUE;\r
545   }\r
546  if(lx2<0)\r
547   {\r
548    if((lx0-lx2)>CHKMAX_X) return TRUE;\r
549    if((lx1-lx2)>CHKMAX_X) return TRUE;\r
550    if((lx3-lx2)>CHKMAX_X) return TRUE;\r
551   }\r
552  if(lx3<0)\r
553   {\r
554    if(((lx1-lx3)>CHKMAX_X) ||\r
555       ((lx2-lx3)>CHKMAX_X))\r
556     {\r
557      if(lx0<0)\r
558       {\r
559        if((lx1-lx0)>CHKMAX_X) return TRUE;\r
560        if((lx2-lx0)>CHKMAX_X) return TRUE;\r
561       }\r
562     }\r
563   }\r
564  \r
565 \r
566  if(ly0<0)\r
567   {\r
568    if((ly1-ly0)>CHKMAX_Y) return TRUE;\r
569    if((ly2-ly0)>CHKMAX_Y) return TRUE;\r
570   }\r
571  if(ly1<0)\r
572   {\r
573    if((ly0-ly1)>CHKMAX_Y) return TRUE;\r
574    if((ly2-ly1)>CHKMAX_Y) return TRUE;\r
575    if((ly3-ly1)>CHKMAX_Y) return TRUE;\r
576   }\r
577  if(ly2<0)\r
578   {\r
579    if((ly0-ly2)>CHKMAX_Y) return TRUE;\r
580    if((ly1-ly2)>CHKMAX_Y) return TRUE;\r
581    if((ly3-ly2)>CHKMAX_Y) return TRUE;\r
582   }\r
583  if(ly3<0)\r
584   {\r
585    if((ly1-ly3)>CHKMAX_Y) return TRUE;\r
586    if((ly2-ly3)>CHKMAX_Y) return TRUE;\r
587   }\r
588 \r
589  return FALSE;\r
590 }\r
591 \r
592 __inline BOOL CheckCoord3()\r
593 {\r
594  if(lx0<0)\r
595   {\r
596    if((lx1-lx0)>CHKMAX_X) return TRUE;\r
597    if((lx2-lx0)>CHKMAX_X) return TRUE;\r
598   }\r
599  if(lx1<0)\r
600   {\r
601    if((lx0-lx1)>CHKMAX_X) return TRUE;\r
602    if((lx2-lx1)>CHKMAX_X) return TRUE;\r
603   }\r
604  if(lx2<0)\r
605   {\r
606    if((lx0-lx2)>CHKMAX_X) return TRUE;\r
607    if((lx1-lx2)>CHKMAX_X) return TRUE;\r
608   }\r
609  if(ly0<0)\r
610   {\r
611    if((ly1-ly0)>CHKMAX_Y) return TRUE;\r
612    if((ly2-ly0)>CHKMAX_Y) return TRUE;\r
613   }\r
614  if(ly1<0)\r
615   {\r
616    if((ly0-ly1)>CHKMAX_Y) return TRUE;\r
617    if((ly2-ly1)>CHKMAX_Y) return TRUE;\r
618   }\r
619  if(ly2<0)\r
620   {\r
621    if((ly0-ly2)>CHKMAX_Y) return TRUE;\r
622    if((ly1-ly2)>CHKMAX_Y) return TRUE;\r
623   }\r
624 \r
625  return FALSE;\r
626 }\r
627 \r
628 \r
629 __inline BOOL CheckCoord2()\r
630 {\r
631  if(lx0<0)\r
632   {\r
633    if((lx1-lx0)>CHKMAX_X) return TRUE;\r
634   }\r
635  if(lx1<0)\r
636   {\r
637    if((lx0-lx1)>CHKMAX_X) return TRUE;\r
638   }\r
639  if(ly0<0)\r
640   {\r
641    if((ly1-ly0)>CHKMAX_Y) return TRUE;\r
642   }\r
643  if(ly1<0)\r
644   {\r
645    if((ly0-ly1)>CHKMAX_Y) return TRUE;\r
646   }\r
647 \r
648  return FALSE;\r
649 }\r
650 \r
651 // Pete's way: a very easy (and hopefully fast) approach for lines\r
652 // without sqrt... using a small float -> short cast trick :)\r
653 \r
654 #define VERTEX_OFFX 0.2f\r
655 #define VERTEX_OFFY 0.2f\r
656 \r
657 BOOL offsetline(void)           \r
658 {\r
659  short x0,x1,y0,y1,dx,dy;float px,py;\r
660 \r
661  if(bDisplayNotSet)\r
662   SetOGLDisplaySettings(1);\r
663 \r
664  if(!(dwActFixes&16))\r
665   {\r
666    lx0=(short)(((int)lx0<<SIGNSHIFT)>>SIGNSHIFT);\r
667    lx1=(short)(((int)lx1<<SIGNSHIFT)>>SIGNSHIFT);\r
668    ly0=(short)(((int)ly0<<SIGNSHIFT)>>SIGNSHIFT);\r
669    ly1=(short)(((int)ly1<<SIGNSHIFT)>>SIGNSHIFT);\r
670 \r
671    if(CheckCoord2()) return TRUE;\r
672   }\r
673 \r
674  x0 = (lx0 + PSXDisplay.CumulOffset.x)+1;\r
675  x1 = (lx1 + PSXDisplay.CumulOffset.x)+1;\r
676  y0 = (ly0 + PSXDisplay.CumulOffset.y)+1;\r
677  y1 = (ly1 + PSXDisplay.CumulOffset.y)+1;\r
678  \r
679  dx=x1-x0;\r
680  dy=y1-y0;\r
681  \r
682  if(dx>=0)\r
683   {\r
684    if(dy>=0)\r
685     {\r
686      px=0.5f;\r
687           if(dx>dy) py=-0.5f;\r
688      else if(dx<dy) py= 0.5f;\r
689      else           py= 0.0f;\r
690     }\r
691    else\r
692     {\r
693      py=-0.5f;\r
694      dy=-dy;\r
695           if(dx>dy) px= 0.5f;\r
696      else if(dx<dy) px=-0.5f;\r
697      else           px= 0.0f;\r
698     }\r
699   }\r
700  else\r
701   {\r
702    if(dy>=0)\r
703     {\r
704      py=0.5f;\r
705      dx=-dx;\r
706           if(dx>dy) px=-0.5f;\r
707      else if(dx<dy) px= 0.5f;\r
708      else           px= 0.0f;\r
709     }\r
710    else\r
711     {\r
712      px=-0.5f;\r
713           if(dx>dy) py=-0.5f;\r
714      else if(dx<dy) py= 0.5f;\r
715      else           py= 0.0f;\r
716     }\r
717   } \r
718  \r
719  vertex[0].x=(short)((float)x0-px);\r
720  vertex[3].x=(short)((float)x0+py);\r
721  \r
722  vertex[0].y=(short)((float)y0-py);\r
723  vertex[3].y=(short)((float)y0-px);\r
724  \r
725  vertex[1].x=(short)((float)x1-py);\r
726  vertex[2].x=(short)((float)x1+px);\r
727 \r
728  vertex[1].y=(short)((float)y1+px);\r
729  vertex[2].y=(short)((float)y1+py);\r
730 \r
731  if(vertex[0].x==vertex[3].x &&                        // ortho rect? done\r
732     vertex[1].x==vertex[2].x &&\r
733     vertex[0].y==vertex[1].y &&\r
734     vertex[2].y==vertex[3].y) return FALSE;\r
735  if(vertex[0].x==vertex[1].x &&\r
736     vertex[2].x==vertex[3].x &&\r
737     vertex[0].y==vertex[3].y &&\r
738     vertex[1].y==vertex[2].y) return FALSE;\r
739 \r
740  vertex[0].x-=VERTEX_OFFX;                             // otherwise a small offset\r
741  vertex[0].y-=VERTEX_OFFY;                             // to get better accuracy\r
742  vertex[1].x-=VERTEX_OFFX;\r
743  vertex[1].y-=VERTEX_OFFY;\r
744  vertex[2].x-=VERTEX_OFFX;\r
745  vertex[2].y-=VERTEX_OFFY;\r
746  vertex[3].x-=VERTEX_OFFX;\r
747  vertex[3].y-=VERTEX_OFFY;\r
748 \r
749  return FALSE;\r
750 }\r
751 \r
752 ///////////////////////////////////////////////////////// \r
753 \r
754 BOOL offset2(void)\r
755 {\r
756  if(bDisplayNotSet)\r
757   SetOGLDisplaySettings(1);\r
758 \r
759  if(!(dwActFixes&16))\r
760   {\r
761    lx0=(short)(((int)lx0<<SIGNSHIFT)>>SIGNSHIFT);\r
762    lx1=(short)(((int)lx1<<SIGNSHIFT)>>SIGNSHIFT);\r
763    ly0=(short)(((int)ly0<<SIGNSHIFT)>>SIGNSHIFT);\r
764    ly1=(short)(((int)ly1<<SIGNSHIFT)>>SIGNSHIFT);\r
765 \r
766    if(CheckCoord2()) return TRUE;\r
767   }\r
768 \r
769  vertex[0].x=lx0+PSXDisplay.CumulOffset.x;\r
770  vertex[1].x=lx1+PSXDisplay.CumulOffset.x;\r
771  vertex[0].y=ly0+PSXDisplay.CumulOffset.y;\r
772  vertex[1].y=ly1+PSXDisplay.CumulOffset.y;\r
773 \r
774  return FALSE;\r
775 }\r
776 \r
777 ///////////////////////////////////////////////////////// \r
778 \r
779 BOOL offset3(void)\r
780 {\r
781  if(bDisplayNotSet)\r
782   SetOGLDisplaySettings(1);\r
783 \r
784  if(!(dwActFixes&16))\r
785   {\r
786    lx0=(short)(((int)lx0<<SIGNSHIFT)>>SIGNSHIFT);\r
787    lx1=(short)(((int)lx1<<SIGNSHIFT)>>SIGNSHIFT);\r
788    lx2=(short)(((int)lx2<<SIGNSHIFT)>>SIGNSHIFT);\r
789    ly0=(short)(((int)ly0<<SIGNSHIFT)>>SIGNSHIFT);\r
790    ly1=(short)(((int)ly1<<SIGNSHIFT)>>SIGNSHIFT);\r
791    ly2=(short)(((int)ly2<<SIGNSHIFT)>>SIGNSHIFT);\r
792 \r
793    if(CheckCoord3()) return TRUE;\r
794   }\r
795 \r
796  vertex[0].x=lx0+PSXDisplay.CumulOffset.x;\r
797  vertex[1].x=lx1+PSXDisplay.CumulOffset.x;\r
798  vertex[2].x=lx2+PSXDisplay.CumulOffset.x;\r
799  vertex[0].y=ly0+PSXDisplay.CumulOffset.y;\r
800  vertex[1].y=ly1+PSXDisplay.CumulOffset.y;\r
801  vertex[2].y=ly2+PSXDisplay.CumulOffset.y;\r
802 \r
803  return FALSE;\r
804 }\r
805 \r
806 ///////////////////////////////////////////////////////// \r
807 \r
808 BOOL offset4(void)\r
809 {\r
810  if(bDisplayNotSet)\r
811   SetOGLDisplaySettings(1);\r
812 \r
813  if(!(dwActFixes&16))\r
814   {\r
815    lx0=(short)(((int)lx0<<SIGNSHIFT)>>SIGNSHIFT);\r
816    lx1=(short)(((int)lx1<<SIGNSHIFT)>>SIGNSHIFT);\r
817    lx2=(short)(((int)lx2<<SIGNSHIFT)>>SIGNSHIFT);\r
818    lx3=(short)(((int)lx3<<SIGNSHIFT)>>SIGNSHIFT);\r
819    ly0=(short)(((int)ly0<<SIGNSHIFT)>>SIGNSHIFT);\r
820    ly1=(short)(((int)ly1<<SIGNSHIFT)>>SIGNSHIFT);\r
821    ly2=(short)(((int)ly2<<SIGNSHIFT)>>SIGNSHIFT);\r
822    ly3=(short)(((int)ly3<<SIGNSHIFT)>>SIGNSHIFT);\r
823 \r
824    if(CheckCoord4()) return TRUE;\r
825   }\r
826 \r
827  vertex[0].x=lx0+PSXDisplay.CumulOffset.x;\r
828  vertex[1].x=lx1+PSXDisplay.CumulOffset.x;\r
829  vertex[2].x=lx2+PSXDisplay.CumulOffset.x;\r
830  vertex[3].x=lx3+PSXDisplay.CumulOffset.x;\r
831  vertex[0].y=ly0+PSXDisplay.CumulOffset.y;\r
832  vertex[1].y=ly1+PSXDisplay.CumulOffset.y;\r
833  vertex[2].y=ly2+PSXDisplay.CumulOffset.y;\r
834  vertex[3].y=ly3+PSXDisplay.CumulOffset.y;\r
835 \r
836  return FALSE;\r
837 }\r
838 \r
839 ///////////////////////////////////////////////////////// \r
840 \r
841 void offsetST(void)\r
842 {\r
843  if(bDisplayNotSet)\r
844   SetOGLDisplaySettings(1);\r
845 \r
846  if(!(dwActFixes&16))\r
847   {\r
848    lx0=(short)(((int)lx0<<SIGNSHIFT)>>SIGNSHIFT);\r
849    ly0=(short)(((int)ly0<<SIGNSHIFT)>>SIGNSHIFT);\r
850 \r
851    if(lx0<-512 && PSXDisplay.DrawOffset.x<=-512)\r
852     lx0+=2048;\r
853 \r
854    if(ly0<-512 && PSXDisplay.DrawOffset.y<=-512)\r
855     ly0+=2048;\r
856   }\r
857 \r
858  ly1 = ly0;\r
859  ly2 = ly3 = ly0+sprtH;\r
860  lx3 = lx0;\r
861  lx1 = lx2 = lx0+sprtW;\r
862 \r
863  vertex[0].x=lx0+PSXDisplay.CumulOffset.x;\r
864  vertex[1].x=lx1+PSXDisplay.CumulOffset.x;\r
865  vertex[2].x=lx2+PSXDisplay.CumulOffset.x;\r
866  vertex[3].x=lx3+PSXDisplay.CumulOffset.x;\r
867  vertex[0].y=ly0+PSXDisplay.CumulOffset.y;\r
868  vertex[1].y=ly1+PSXDisplay.CumulOffset.y;\r
869  vertex[2].y=ly2+PSXDisplay.CumulOffset.y;\r
870  vertex[3].y=ly3+PSXDisplay.CumulOffset.y;\r
871 }\r
872 \r
873 ///////////////////////////////////////////////////////// \r
874 \r
875 void offsetScreenUpload(long Position)\r
876 {\r
877  if(bDisplayNotSet)\r
878   SetOGLDisplaySettings(1);\r
879 \r
880  if(Position==-1)\r
881   {\r
882    long lmdx,lmdy;\r
883 \r
884    lmdx=xrUploadArea.x0;\r
885    lmdy=xrUploadArea.y0;\r
886 \r
887    lx0-=lmdx;\r
888    ly0-=lmdy;\r
889    lx1-=lmdx;\r
890    ly1-=lmdy;\r
891    lx2-=lmdx;\r
892    ly2-=lmdy;\r
893    lx3-=lmdx;\r
894    ly3-=lmdy;\r
895   }\r
896  else\r
897  if(Position)\r
898   {\r
899    lx0-=PSXDisplay.DisplayPosition.x;\r
900    ly0-=PSXDisplay.DisplayPosition.y;\r
901    lx1-=PSXDisplay.DisplayPosition.x;\r
902    ly1-=PSXDisplay.DisplayPosition.y;\r
903    lx2-=PSXDisplay.DisplayPosition.x;\r
904    ly2-=PSXDisplay.DisplayPosition.y;\r
905    lx3-=PSXDisplay.DisplayPosition.x;\r
906    ly3-=PSXDisplay.DisplayPosition.y;\r
907   }\r
908  else\r
909   {\r
910    lx0-=PreviousPSXDisplay.DisplayPosition.x;\r
911    ly0-=PreviousPSXDisplay.DisplayPosition.y;\r
912    lx1-=PreviousPSXDisplay.DisplayPosition.x;\r
913    ly1-=PreviousPSXDisplay.DisplayPosition.y;\r
914    lx2-=PreviousPSXDisplay.DisplayPosition.x;\r
915    ly2-=PreviousPSXDisplay.DisplayPosition.y;\r
916    lx3-=PreviousPSXDisplay.DisplayPosition.x;\r
917    ly3-=PreviousPSXDisplay.DisplayPosition.y;\r
918   }\r
919 \r
920  vertex[0].x=lx0 + PreviousPSXDisplay.Range.x0;\r
921  vertex[1].x=lx1 + PreviousPSXDisplay.Range.x0;\r
922  vertex[2].x=lx2 + PreviousPSXDisplay.Range.x0;\r
923  vertex[3].x=lx3 + PreviousPSXDisplay.Range.x0;\r
924  vertex[0].y=ly0 + PreviousPSXDisplay.Range.y0;\r
925  vertex[1].y=ly1 + PreviousPSXDisplay.Range.y0;\r
926  vertex[2].y=ly2 + PreviousPSXDisplay.Range.y0;\r
927  vertex[3].y=ly3 + PreviousPSXDisplay.Range.y0;\r
928 \r
929  if(iUseMask)\r
930   {\r
931    vertex[0].z=vertex[1].z=vertex[2].z=vertex[3].z=gl_z;\r
932    gl_z+=0.00004f;\r
933   }\r
934 }\r
935  \r
936 ///////////////////////////////////////////////////////// \r
937 \r
938 void offsetBlk(void)\r
939 {\r
940  if(bDisplayNotSet)\r
941   SetOGLDisplaySettings(1);\r
942                                             \r
943  vertex[0].x=lx0-PSXDisplay.GDrawOffset.x + PreviousPSXDisplay.Range.x0;\r
944  vertex[1].x=lx1-PSXDisplay.GDrawOffset.x + PreviousPSXDisplay.Range.x0;\r
945  vertex[2].x=lx2-PSXDisplay.GDrawOffset.x + PreviousPSXDisplay.Range.x0;\r
946  vertex[3].x=lx3-PSXDisplay.GDrawOffset.x + PreviousPSXDisplay.Range.x0;\r
947  vertex[0].y=ly0-PSXDisplay.GDrawOffset.y + PreviousPSXDisplay.Range.y0;\r
948  vertex[1].y=ly1-PSXDisplay.GDrawOffset.y + PreviousPSXDisplay.Range.y0;\r
949  vertex[2].y=ly2-PSXDisplay.GDrawOffset.y + PreviousPSXDisplay.Range.y0;\r
950  vertex[3].y=ly3-PSXDisplay.GDrawOffset.y + PreviousPSXDisplay.Range.y0;\r
951 \r
952  if(iUseMask)\r
953   {\r
954    vertex[0].z=vertex[1].z=vertex[2].z=vertex[3].z=gl_z;\r
955    gl_z+=0.00004f;\r
956   }\r
957 }\r
958 \r
959 ////////////////////////////////////////////////////////////////////////\r
960 // texture sow/tow calculations\r
961 ////////////////////////////////////////////////////////////////////////\r
962 \r
963 void assignTextureVRAMWrite(void)\r
964 {\r
965 #ifdef OWNSCALE\r
966 \r
967  vertex[0].sow=0.5f/ ST_FACVRAMX;\r
968  vertex[0].tow=0.5f/ ST_FACVRAM;\r
969 \r
970  vertex[1].sow=(float)gl_ux[1]/ ST_FACVRAMX;\r
971  vertex[1].tow=0.5f/ ST_FACVRAM;\r
972 \r
973  vertex[2].sow=(float)gl_ux[2]/ ST_FACVRAMX;\r
974  vertex[2].tow=(float)gl_vy[2]/ ST_FACVRAM;\r
975 \r
976  vertex[3].sow=0.5f/ ST_FACVRAMX;\r
977  vertex[3].tow=(float)gl_vy[3]/ ST_FACVRAM;\r
978 \r
979 #else\r
980 \r
981  if(gl_ux[1]==255)\r
982   {\r
983    vertex[0].sow=(gl_ux[0]*255.99f)/255.0f;\r
984    vertex[1].sow=(gl_ux[1]*255.99f)/255.0f;\r
985    vertex[2].sow=(gl_ux[2]*255.99f)/255.0f;\r
986    vertex[3].sow=(gl_ux[3]*255.99f)/255.0f;\r
987   }\r
988  else\r
989   {\r
990    vertex[0].sow=gl_ux[0];\r
991    vertex[1].sow=gl_ux[1];\r
992    vertex[2].sow=gl_ux[2];\r
993    vertex[3].sow=gl_ux[3];\r
994   }\r
995 \r
996  vertex[0].tow=gl_vy[0];\r
997  vertex[1].tow=gl_vy[1];\r
998  vertex[2].tow=gl_vy[2];\r
999  vertex[3].tow=gl_vy[3];\r
1000 \r
1001 #endif\r
1002 }\r
1003 \r
1004 GLuint  gLastTex=0;\r
1005 GLuint  gLastFMode=(GLuint)-1;\r
1006 \r
1007 ///////////////////////////////////////////////////////// \r
1008 \r
1009 void assignTextureSprite(void)\r
1010 {\r
1011  if(bUsingTWin)\r
1012   {\r
1013    vertex[0].sow=vertex[3].sow=(float)gl_ux[0]/TWin.UScaleFactor;\r
1014    vertex[1].sow=vertex[2].sow=(float)sSprite_ux2/TWin.UScaleFactor;\r
1015    vertex[0].tow=vertex[1].tow=(float)gl_vy[0]/TWin.VScaleFactor;\r
1016    vertex[2].tow=vertex[3].tow=(float)sSprite_vy2/TWin.VScaleFactor;\r
1017    gLastTex=gTexName;\r
1018   }\r
1019  else\r
1020   {\r
1021 #ifdef OWNSCALE\r
1022 \r
1023    vertex[0].sow=vertex[3].sow=(float)gl_ux[0]     / ST_FACSPRITE;\r
1024    vertex[1].sow=vertex[2].sow=(float)sSprite_ux2  / ST_FACSPRITE;\r
1025    vertex[0].tow=vertex[1].tow=(float)gl_vy[0]     / ST_FACSPRITE;\r
1026    vertex[2].tow=vertex[3].tow=(float)sSprite_vy2  / ST_FACSPRITE;\r
1027 \r
1028 #else\r
1029  \r
1030    vertex[0].sow=vertex[3].sow=gl_ux[0];\r
1031    vertex[1].sow=vertex[2].sow=sSprite_ux2;\r
1032    vertex[0].tow=vertex[1].tow=gl_vy[0];\r
1033    vertex[2].tow=vertex[3].tow=sSprite_vy2;\r
1034 \r
1035 #endif\r
1036 \r
1037    if(iFilterType>2) \r
1038     {\r
1039      if(gLastTex!=gTexName || gLastFMode!=0)\r
1040       {\r
1041        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);\r
1042        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);\r
1043        gLastTex=gTexName;gLastFMode=0;\r
1044       }\r
1045     }\r
1046   }\r
1047 \r
1048  if(usMirror & 0x1000) \r
1049   {\r
1050    vertex[0].sow=vertex[1].sow;\r
1051    vertex[1].sow=vertex[2].sow=vertex[3].sow;\r
1052    vertex[3].sow=vertex[0].sow;\r
1053   }\r
1054 \r
1055  if(usMirror & 0x2000) \r
1056   {\r
1057    vertex[0].tow=vertex[3].tow;\r
1058    vertex[2].tow=vertex[3].tow=vertex[1].tow;\r
1059    vertex[1].tow=vertex[0].tow;\r
1060   }\r
1061 \r
1062 }\r
1063 \r
1064 ///////////////////////////////////////////////////////// \r
1065 \r
1066 void assignTexture3(void)\r
1067 {\r
1068  if(bUsingTWin)\r
1069   {\r
1070    vertex[0].sow=(float)gl_ux[0]/TWin.UScaleFactor;\r
1071    vertex[0].tow=(float)gl_vy[0]/TWin.VScaleFactor;\r
1072    vertex[1].sow=(float)gl_ux[1]/TWin.UScaleFactor;\r
1073    vertex[1].tow=(float)gl_vy[1]/TWin.VScaleFactor;\r
1074    vertex[2].sow=(float)gl_ux[2]/TWin.UScaleFactor;\r
1075    vertex[2].tow=(float)gl_vy[2]/TWin.VScaleFactor;\r
1076    gLastTex=gTexName;\r
1077   }\r
1078  else\r
1079   {\r
1080 #ifdef OWNSCALE\r
1081    vertex[0].sow=(float)gl_ux[0] / ST_FACTRI;\r
1082    vertex[0].tow=(float)gl_vy[0] / ST_FACTRI;\r
1083    vertex[1].sow=(float)gl_ux[1] / ST_FACTRI;\r
1084 \r
1085    vertex[1].tow=(float)gl_vy[1] / ST_FACTRI;\r
1086    vertex[2].sow=(float)gl_ux[2] / ST_FACTRI;\r
1087    vertex[2].tow=(float)gl_vy[2] / ST_FACTRI;\r
1088 #else\r
1089    vertex[0].sow=gl_ux[0];\r
1090    vertex[0].tow=gl_vy[0];\r
1091    vertex[1].sow=gl_ux[1];\r
1092    vertex[1].tow=gl_vy[1];\r
1093    vertex[2].sow=gl_ux[2];\r
1094    vertex[2].tow=gl_vy[2];\r
1095 #endif\r
1096 \r
1097    if(iFilterType>2) \r
1098     {\r
1099      if(gLastTex!=gTexName || gLastFMode!=1)\r
1100       {\r
1101        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);\r
1102        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);\r
1103        gLastTex=gTexName;gLastFMode=1;\r
1104       }\r
1105     }\r
1106 \r
1107    if(iFilterType) \r
1108     {\r
1109      float fxmin=256.0f,fxmax=0.0f,fymin=256.0f,fymax=0.0f;int i;\r
1110      for(i=0;i<3;i++)\r
1111       {\r
1112        if(vertex[i].sow<fxmin) fxmin=vertex[i].sow;\r
1113        if(vertex[i].tow<fymin) fymin=vertex[i].tow;\r
1114        if(vertex[i].sow>fxmax) fxmax=vertex[i].sow;\r
1115        if(vertex[i].tow>fymax) fymax=vertex[i].tow; \r
1116       }\r
1117 \r
1118      for(i=0;i<3;i++)\r
1119       {\r
1120        if(vertex[i].sow==fxmin) vertex[i].sow+=ST_BFFACSORT;\r
1121        if(vertex[i].sow==fxmax) vertex[i].sow-=ST_BFFACSORT;\r
1122        if(vertex[i].tow==fymin) vertex[i].tow+=ST_BFFACSORT;\r
1123        if(vertex[i].tow==fymax) vertex[i].tow-=ST_BFFACSORT;\r
1124       }\r
1125     }\r
1126   }\r
1127 }\r
1128 \r
1129 ///////////////////////////////////////////////////////// \r
1130 \r
1131 void assignTexture4(void)\r
1132 {\r
1133  if(bUsingTWin)\r
1134   {\r
1135    vertex[0].sow=(float)gl_ux[0]/TWin.UScaleFactor;\r
1136    vertex[0].tow=(float)gl_vy[0]/TWin.VScaleFactor;\r
1137    vertex[1].sow=(float)gl_ux[1]/TWin.UScaleFactor;\r
1138    vertex[1].tow=(float)gl_vy[1]/TWin.VScaleFactor;\r
1139    vertex[2].sow=(float)gl_ux[2]/TWin.UScaleFactor;\r
1140    vertex[2].tow=(float)gl_vy[2]/TWin.VScaleFactor;\r
1141    vertex[3].sow=(float)gl_ux[3]/TWin.UScaleFactor;\r
1142    vertex[3].tow=(float)gl_vy[3]/TWin.VScaleFactor;\r
1143    gLastTex=gTexName;\r
1144   }\r
1145  else\r
1146   {\r
1147 #ifdef OWNSCALE\r
1148    vertex[0].sow=(float)gl_ux[0] / ST_FAC;\r
1149    vertex[0].tow=(float)gl_vy[0] / ST_FAC;\r
1150    vertex[1].sow=(float)gl_ux[1] / ST_FAC;\r
1151    vertex[1].tow=(float)gl_vy[1] / ST_FAC;\r
1152    vertex[2].sow=(float)gl_ux[2] / ST_FAC;\r
1153    vertex[2].tow=(float)gl_vy[2] / ST_FAC;\r
1154    vertex[3].sow=(float)gl_ux[3] / ST_FAC;\r
1155    vertex[3].tow=(float)gl_vy[3] / ST_FAC;\r
1156 #else\r
1157    vertex[0].sow=gl_ux[0];\r
1158    vertex[0].tow=gl_vy[0];\r
1159    vertex[1].sow=gl_ux[1];\r
1160    vertex[1].tow=gl_vy[1];\r
1161    vertex[2].sow=gl_ux[2];\r
1162    vertex[2].tow=gl_vy[2];\r
1163    vertex[3].sow=gl_ux[3];\r
1164    vertex[3].tow=gl_vy[3];\r
1165 #endif\r
1166 \r
1167    if(iFilterType>2) \r
1168     {\r
1169      if(gLastTex!=gTexName || gLastFMode!=1)\r
1170       {\r
1171        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);\r
1172        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);\r
1173        gLastTex=gTexName;gLastFMode=1;\r
1174       }\r
1175     }\r
1176 \r
1177    if(iFilterType) \r
1178     {\r
1179      float fxmin=256.0f,fxmax=0.0f,fymin=256.0f,fymax=0.0f;int i;\r
1180      for(i=0;i<4;i++)\r
1181       {\r
1182        if(vertex[i].sow<fxmin) fxmin=vertex[i].sow;\r
1183        if(vertex[i].tow<fymin) fymin=vertex[i].tow;\r
1184        if(vertex[i].sow>fxmax) fxmax=vertex[i].sow;\r
1185        if(vertex[i].tow>fymax) fymax=vertex[i].tow; \r
1186       }\r
1187 \r
1188      for(i=0;i<4;i++)\r
1189       {\r
1190        if(vertex[i].sow==fxmin) vertex[i].sow+=ST_BFFACSORT;\r
1191        if(vertex[i].sow==fxmax) vertex[i].sow-=ST_BFFACSORT;\r
1192        if(vertex[i].tow==fymin) vertex[i].tow+=ST_BFFACSORT;\r
1193        if(vertex[i].tow==fymax) vertex[i].tow-=ST_BFFACSORT;\r
1194       }\r
1195     }\r
1196   }\r
1197 }\r
1198 \r
1199 ////////////////////////////////////////////////////////////////////////\r
1200 ////////////////////////////////////////////////////////////////////////\r
1201 ////////////////////////////////////////////////////////////////////////\r
1202 \r
1203 ////////////////////////////////////////////////////////////////////////\r
1204 // render pos / buffers\r
1205 ////////////////////////////////////////////////////////////////////////\r
1206 \r
1207 #ifndef _WINDOWS\r
1208 #define EqualRect(pr1,pr2) ((pr1)->left==(pr2)->left && (pr1)->top==(pr2)->top && (pr1)->right==(pr2)->right && (pr1)->bottom==(pr2)->bottom)\r
1209 #endif\r
1210 \r
1211 ////////////////////////////////////////////////////////////////////////\r
1212 // SetDisplaySettings: "simply" calcs the new drawing area and updates\r
1213 //                     the ogl clipping (scissor) \r
1214 \r
1215 BOOL bSetClip=FALSE;\r
1216 \r
1217 void SetOGLDisplaySettings(BOOL DisplaySet)\r
1218 {\r
1219  static RECT rprev={0,0,0,0};\r
1220  static RECT rC   ={0,0,0,0};\r
1221  static int iOldX=0;\r
1222  static int iOldY=0;\r
1223  RECT r;float XS,YS;\r
1224 \r
1225  bDisplayNotSet = FALSE;\r
1226 \r
1227  //----------------------------------------------------// that's a whole screen upload\r
1228  if(!DisplaySet)\r
1229   {\r
1230    RECT rX;\r
1231    PSXDisplay.GDrawOffset.x=0;\r
1232    PSXDisplay.GDrawOffset.y=0;\r
1233 \r
1234    PSXDisplay.CumulOffset.x = PSXDisplay.DrawOffset.x+PreviousPSXDisplay.Range.x0;\r
1235    PSXDisplay.CumulOffset.y = PSXDisplay.DrawOffset.y+PreviousPSXDisplay.Range.y0;\r
1236 \r
1237    rprev.left=rprev.left+1;\r
1238 \r
1239    rX=rRatioRect;\r
1240    rX.top=iResY-(rRatioRect.top+rRatioRect.bottom);\r
1241 \r
1242    if(bSetClip || !EqualRect(&rC,&rX))\r
1243     {\r
1244      rC=rX;\r
1245      glScissor(rC.left,rC.top,rC.right,rC.bottom);\r
1246      bSetClip=FALSE; \r
1247     }\r
1248    return;\r
1249   }\r
1250  //----------------------------------------------------// \r
1251 \r
1252  PSXDisplay.GDrawOffset.y = PreviousPSXDisplay.DisplayPosition.y;\r
1253  PSXDisplay.GDrawOffset.x = PreviousPSXDisplay.DisplayPosition.x;\r
1254  PSXDisplay.CumulOffset.x = PSXDisplay.DrawOffset.x - PSXDisplay.GDrawOffset.x+PreviousPSXDisplay.Range.x0;\r
1255  PSXDisplay.CumulOffset.y = PSXDisplay.DrawOffset.y - PSXDisplay.GDrawOffset.y+PreviousPSXDisplay.Range.y0;\r
1256 \r
1257  r.top   =PSXDisplay.DrawArea.y0 - PreviousPSXDisplay.DisplayPosition.y;\r
1258  r.bottom=PSXDisplay.DrawArea.y1 - PreviousPSXDisplay.DisplayPosition.y;\r
1259 \r
1260  if(r.bottom<0 || r.top>=PSXDisplay.DisplayMode.y)\r
1261   {\r
1262    r.top   =PSXDisplay.DrawArea.y0 - PSXDisplay.DisplayPosition.y;\r
1263    r.bottom=PSXDisplay.DrawArea.y1 - PSXDisplay.DisplayPosition.y;\r
1264   }\r
1265 \r
1266  r.left  =PSXDisplay.DrawArea.x0 - PreviousPSXDisplay.DisplayPosition.x;\r
1267  r.right =PSXDisplay.DrawArea.x1 - PreviousPSXDisplay.DisplayPosition.x;\r
1268 \r
1269  if(r.right<0 || r.left>=PSXDisplay.DisplayMode.x)\r
1270   {\r
1271    r.left  =PSXDisplay.DrawArea.x0 - PSXDisplay.DisplayPosition.x;\r
1272    r.right =PSXDisplay.DrawArea.x1 - PSXDisplay.DisplayPosition.x;\r
1273   }\r
1274 \r
1275  if(!bSetClip && EqualRect(&r,&rprev) &&\r
1276     iOldX == PSXDisplay.DisplayMode.x &&\r
1277     iOldY == PSXDisplay.DisplayMode.y)\r
1278   return;\r
1279 \r
1280  rprev = r;\r
1281  iOldX = PSXDisplay.DisplayMode.x;\r
1282  iOldY = PSXDisplay.DisplayMode.y;\r
1283 \r
1284  XS=(float)rRatioRect.right/(float)PSXDisplay.DisplayMode.x;\r
1285  YS=(float)rRatioRect.bottom/(float)PSXDisplay.DisplayMode.y;\r
1286 \r
1287  if(PreviousPSXDisplay.Range.x0)\r
1288   {\r
1289    short s=PreviousPSXDisplay.Range.x0+PreviousPSXDisplay.Range.x1;\r
1290 \r
1291    r.left+=PreviousPSXDisplay.Range.x0+1;\r
1292 \r
1293    r.right+=PreviousPSXDisplay.Range.x0;\r
1294 \r
1295    if(r.left>s)  r.left=s;\r
1296    if(r.right>s) r.right=s;\r
1297   }\r
1298 \r
1299  if(PreviousPSXDisplay.Range.y0)\r
1300   {\r
1301    short s=PreviousPSXDisplay.Range.y0+PreviousPSXDisplay.Range.y1;\r
1302 \r
1303    r.top+=PreviousPSXDisplay.Range.y0+1;\r
1304    r.bottom+=PreviousPSXDisplay.Range.y0;\r
1305 \r
1306    if(r.top>s)    r.top=s;\r
1307    if(r.bottom>s) r.bottom=s;\r
1308   }\r
1309 \r
1310  // Set the ClipArea variables to reflect the new screen,\r
1311  // offset from zero (since it is a new display buffer)\r
1312  r.left   = (int)(((float)(r.left))      *XS);\r
1313  r.top    = (int)(((float)(r.top))       *YS);\r
1314  r.right  = (int)(((float)(r.right  + 1))*XS);\r
1315  r.bottom = (int)(((float)(r.bottom + 1))*YS);\r
1316 \r
1317  // Limit clip area to the screen size\r
1318  if (r.left   > iResX)   r.left   = iResX;\r
1319  if (r.left   < 0)       r.left   = 0;\r
1320  if (r.top    > iResY)   r.top    = iResY;\r
1321  if (r.top    < 0)       r.top    = 0;\r
1322  if (r.right  > iResX)   r.right  = iResX;\r
1323  if (r.right  < 0)       r.right  = 0;\r
1324  if (r.bottom > iResY)   r.bottom = iResY;\r
1325  if (r.bottom < 0)       r.bottom = 0;\r
1326 \r
1327  r.right -=r.left;\r
1328  r.bottom-=r.top;\r
1329  r.top=iResY-(r.top+r.bottom);\r
1330 \r
1331  r.left+=rRatioRect.left;\r
1332  r.top -=rRatioRect.top;\r
1333 \r
1334  if(bSetClip || !EqualRect(&r,&rC))\r
1335   {\r
1336    glScissor(r.left,r.top,r.right,r.bottom);\r
1337    rC=r;\r
1338    bSetClip=FALSE;\r
1339   }\r
1340 }\r
1341 \r
1342 ////////////////////////////////////////////////////////////////////////\r
1343 ////////////////////////////////////////////////////////////////////////\r
1344 ////////////////////////////////////////////////////////////////////////\r
1345 \r