gpu-gles: schtruck/fpse merge: gl error checks
[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 \r
31 #include "gpuExternals.h"\r
32 #include "gpuPlugin.h"\r
33 #include "gpuDraw.h"\r
34 #include "gpuPrim.h"\r
35 #include "gpuTexture.h"\r
36 #include "gpuStdafx.h"\r
37 \r
38 #include <stdio.h>\r
39 #include <stdlib.h>\r
40 #include <math.h>\r
41 //#include "menu.h"\r
42             \r
43 ////////////////////////////////////////////////////////////////////////////////////\r
44 // defines\r
45 \r
46 #define SIGNBIT 0x800\r
47 #define S_MASK  0xf000\r
48 #define L_MASK  0xfffff000\r
49 \r
50 // ownscale: some ogl drivers have buggy texture matrix funcs, so it\r
51 //           is safer to calc sow/tow ourselves\r
52 \r
53 #ifdef OWNSCALE\r
54 \r
55 ///////////////////////////////////////////////////////////////\r
56 \r
57 #define ST_FACSPRITE       255.99f\r
58 #define ST_BFFACSPRITE     0.5f/256.0f\r
59 #define ST_BFFACSPRITESORT 0.333f/256.0f\r
60 \r
61 #define ST_OFFSET          0.5f/256.0f;\r
62 \r
63 #define ST_FAC             255.99f\r
64 #define ST_BFFAC           0.5f/256.0f\r
65 #define ST_BFFACSORT       0.333f/256.0f\r
66 \r
67 #define ST_FACTRI          255.99f\r
68 #define ST_BFFACTRI        0.5f/256.0f\r
69 #define ST_BFFACTRISORT    0.333f/256.0f\r
70 \r
71 #define ST_FACVRAMX        255.0f\r
72 #define ST_FACVRAM         256.0f\r
73 \r
74 ///////////////////////////////////////////////////////////////\r
75 \r
76 #else\r
77 \r
78 #define ST_BFFACSPRITE     0.5f\r
79 #define ST_BFFACSPRITESORT 0.333f\r
80 \r
81 #define ST_BFFAC           0.5f\r
82 #define ST_BFFACSORT       0.333f\r
83 \r
84 #define ST_BFFACTRI        0.5f\r
85 #define ST_BFFACTRISORT    0.333f\r
86 \r
87 #define ST_OFFSET          0.5f;\r
88                 \r
89 #endif\r
90 \r
91 ////////////////////////////////////////////////////////////////////////////////////\r
92 // draw globals\r
93 \r
94 void  glBlendEquationEXT(GLenum mode);\r
95 void  glColorTableEXT(GLenum target, GLenum internalFormat, GLsizei width, GLenum format,GLenum type, const GLvoid *data);\r
96 \r
97 // draw globals; most will be initialized again later (by config or checks) \r
98 \r
99 BOOL           bIsFirstFrame=TRUE;\r
100 \r
101 // resolution/ratio vars\r
102 \r
103 int            iResX;\r
104 int            iResY;\r
105 BOOL           bKeepRatio=FALSE;\r
106 RECT           rRatioRect;\r
107 \r
108 // psx mask related vars\r
109 \r
110 BOOL           bCheckMask=FALSE;\r
111 int            iUseMask=0;\r
112 int            iSetMask=0;\r
113 unsigned short sSetMask=0;\r
114 unsigned long  lSetMask=0;\r
115 \r
116 // drawing/coord vars\r
117 \r
118 OGLVertex      vertex[4];\r
119 GLubyte        gl_ux[8];\r
120 GLubyte        gl_vy[8];\r
121 short          sprtY,sprtX,sprtH,sprtW;\r
122 \r
123 // drawing options\r
124 \r
125 BOOL           bOpaquePass;\r
126 BOOL           bAdvancedBlend;\r
127 \r
128 // OGL extension support\r
129 \r
130 \r
131 // gfx card buffer infos\r
132 \r
133 int            iDepthFunc=0;\r
134 int            iZBufferDepth=0;\r
135 GLbitfield     uiBufferBits=GL_COLOR_BUFFER_BIT;\r
136 \r
137 ////////////////////////////////////////////////////////////////////////\r
138 ////////////////////////////////////////////////////////////////////////\r
139 ////////////////////////////////////////////////////////////////////////\r
140 \r
141 ////////////////////////////////////////////////////////////////////////\r
142 // Set OGL pixel format\r
143 ////////////////////////////////////////////////////////////////////////\r
144  \r
145 \r
146 ////////////////////////////////////////////////////////////////////////\r
147 // Get extension infos (f.e. pal textures / packed pixels)\r
148 ////////////////////////////////////////////////////////////////////////\r
149 \r
150 void GetExtInfos(void)                              \r
151 {\r
152  BOOL bPacked=FALSE;                                   // default: no packed pixel support\r
153 \r
154  if(strstr((char *)glGetString(GL_EXTENSIONS),         // packed pixels available?\r
155     "GL_EXT_packed_pixels"))                          \r
156   bPacked=TRUE;                                        // -> ok\r
157 \r
158  \r
159  iClampType=GL_CLAMP_TO_EDGE;\r
160 }\r
161 \r
162 ////////////////////////////////////////////////////////////////////////\r
163 // Setup some stuff depending on user settings or in-game toggle\r
164 ////////////////////////////////////////////////////////////////////////\r
165 \r
166 void SetExtGLFuncs(void)\r
167 {\r
168  //----------------------------------------------------//\r
169 \r
170  SetFixes();                                           // update fix infos\r
171 \r
172  //----------------------------------------------------//\r
173 \r
174   {\r
175    if(bAdvancedBlend) bUseMultiPass=TRUE;              // -> pseudo-advanced with 2 passes\r
176    else               bUseMultiPass=FALSE;             // -> or simple 'bright color' mode\r
177 //   bGLBlend=FALSE;                                     // -> no ext blending!\r
178    glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); glError();\r
179   }\r
180 \r
181  if(bOpaquePass)                                        // opaque mode?\r
182   {\r
183    if(dwActFixes&32) \r
184     {\r
185      TCF[0]=CP8RGBA_0;\r
186      PalTexturedColourFn=CP8RGBA;                      // -> init col func\r
187     }\r
188    else\r
189     {\r
190      TCF[0]=XP8RGBA_0;\r
191      PalTexturedColourFn=XP8RGBA;                      // -> init col func\r
192     }\r
193 \r
194    TCF[1]=XP8RGBA_1;\r
195    glAlphaFuncx(GL_GREATER,0.49f); glError();\r
196 \r
197   }\r
198  else                                                  // no opaque mode?\r
199   {\r
200    TCF[0]=TCF[1]=P8RGBA;\r
201    PalTexturedColourFn=P8RGBA;                         // -> init col func\r
202    glAlphaFuncx(GL_NOTEQUAL,0); glError();             // --> set alpha func\r
203 \r
204   }\r
205 \r
206  //----------------------------------------------------//\r
207 \r
208  LoadSubTexFn=LoadSubTexturePageSort;                  // init load tex ptr\r
209 \r
210  bBlendEnable=FALSE;                                   // init blending: off\r
211  glDisable(GL_BLEND); glError();\r
212 \r
213 \r
214  SetScanTrans();                                       // init scan lines (if wanted)\r
215 }\r
216 \r
217 ////////////////////////////////////////////////////////////////////////\r
218 // setup scan lines\r
219 ////////////////////////////////////////////////////////////////////////\r
220 \r
221 #define R_TSP 0x00,0x45,0x00,0xff\r
222 #define G_TSP 0x00,0x00,0x45,0xff\r
223 #define B_TSP 0x45,0x00,0x00,0xff\r
224 #define O_TSP 0x45,0x45,0x45,0xff\r
225 #define N_TSP 0x00,0x00,0x00,0xff\r
226 \r
227 GLuint  gTexScanName=0;\r
228 \r
229 GLubyte texscan[4][16]= \r
230 {\r
231 {R_TSP, G_TSP, B_TSP, N_TSP},\r
232 {O_TSP, N_TSP, O_TSP, N_TSP},\r
233 {B_TSP, N_TSP, R_TSP, G_TSP},\r
234 {O_TSP, N_TSP, O_TSP, N_TSP}\r
235 };\r
236 \r
237 void CreateScanLines(void)\r
238 {\r
239 }\r
240 \r
241 ////////////////////////////////////////////////////////////////////////\r
242 // Initialize OGL\r
243 ////////////////////////////////////////////////////////////////////////\r
244 \r
245 #define MODE_RAW 0\r
246 #define MODE_X11 1\r
247 #define MODE_SDL 2\r
248 int use_fsaa = 0;\r
249 \r
250 EGLDisplay display;\r
251 EGLConfig  config;\r
252 EGLContext context;\r
253 EGLSurface surface;\r
254 \r
255 #if defined(USE_X11)\r
256 #include "X11/Xlib.h"\r
257 #include "X11/Xutil.h"\r
258 #include "X11/Xatom.h"\r
259 \r
260 Window                  x11Window       = 0;\r
261 Display*                x11Display      = 0;\r
262 long                    x11Screen       = 0;\r
263 XVisualInfo             x11Visual;\r
264 XVisualInfo*    px11Visual      = 0;\r
265 Colormap        x11Colormap     = 0;\r
266 #endif\r
267 \r
268 EGLint attrib_list_fsaa[] =\r
269 {\r
270         EGL_SURFACE_TYPE, EGL_WINDOW_BIT,\r
271         EGL_BUFFER_SIZE,    0,\r
272         EGL_DEPTH_SIZE,     16,\r
273         EGL_SAMPLE_BUFFERS, 1,\r
274         EGL_SAMPLES,        4,\r
275         EGL_NONE\r
276 };\r
277 \r
278 EGLint attrib_list[] =\r
279 {\r
280 //      EGL_DEPTH_SIZE,   16,\r
281         EGL_NONE\r
282 };\r
283 \r
284 bool TestEGLError(const char* pszLocation)\r
285 {\r
286         /*\r
287                 eglGetError returns the last error that has happened using egl,\r
288                 not the status of the last called function. The user has to\r
289                 check after every single egl call or at least once every frame.\r
290         */\r
291         EGLint iErr = eglGetError();\r
292         if (iErr != EGL_SUCCESS)\r
293         {\r
294                 printf("%s failed (%d).\n", pszLocation, iErr);\r
295                 return FALSE;\r
296         }\r
297 \r
298         return TRUE;\r
299 }\r
300 \r
301 static void initEGL(void)\r
302 {\r
303         printf ("GL init\n");\r
304 \r
305         EGLint numConfigs;\r
306         EGLint majorVersion;\r
307         EGLint minorVersion;\r
308 #if defined(USE_X11)\r
309         enum\r
310         {\r
311         _NET_WM_STATE_REMOVE =0,\r
312         _NET_WM_STATE_ADD = 1,\r
313         _NET_WM_STATE_TOGGLE =2\r
314         };\r
315         \r
316         Window                          sRootWindow;\r
317         XSetWindowAttributes    sWA;\r
318         unsigned int                ui32Mask;\r
319         int                                 i32Depth;\r
320 #endif\r
321         \r
322         EGLint *attribList = NULL;\r
323         if (use_fsaa)\r
324         {\r
325                 printf( "GLES: Using Full Scene Antialiasing\n" );\r
326                 attribList = attrib_list_fsaa;\r
327         }\r
328         else\r
329         {\r
330                 attribList = attrib_list;\r
331         }\r
332 \r
333 #if defined(USE_X11)\r
334             // Initializes the display and screen\r
335             x11Display = XOpenDisplay( ":0" );\r
336             if (!x11Display)\r
337             {\r
338                 printf("GLES Error: Unable to open X display\n");\r
339             }\r
340             x11Screen = XDefaultScreen( x11Display );\r
341                                 \r
342             // Gets the display parameters so we can pass the same parameters to the window to be created.\r
343             sRootWindow = RootWindow(x11Display, x11Screen);\r
344             i32Depth    = DefaultDepth(x11Display, x11Screen);\r
345             px11Visual  = &x11Visual;\r
346             XMatchVisualInfo( x11Display, x11Screen, i32Depth, TrueColor, px11Visual);\r
347             if (!px11Visual)\r
348             {\r
349                 printf("GLES Error: Unable to acquire visual\n");\r
350                         }\r
351             // Colormap of the specified visual type for the display.\r
352             x11Colormap = XCreateColormap( x11Display, sRootWindow, px11Visual->visual, AllocNone );\r
353             sWA.colormap = x11Colormap;\r
354 \r
355             // List of events to be handled by the application. Add to these for handling other events.\r
356             sWA.event_mask = StructureNotifyMask | ExposureMask | ButtonPressMask | ButtonReleaseMask | KeyPressMask | KeyReleaseMask;\r
357 \r
358             // Display capabilities list.\r
359             ui32Mask = CWBackPixel | CWBorderPixel | CWEventMask | CWColormap;\r
360                                                            \r
361             // Creates the X11 window\r
362             x11Window = XCreateWindow( x11Display, RootWindow(x11Display, x11Screen), 0, 0, iResX, iResY,\r
363                                         0, CopyFromParent, InputOutput, CopyFromParent, ui32Mask, &sWA);\r
364 \r
365             // Make the window viewable and flush the output buffer.\r
366             XMapWindow(x11Display, x11Window);\r
367             XFlush(x11Display);\r
368 \r
369             // Make the window fullscreen\r
370             unsigned char fullScreen = 1;\r
371             Atom wmState = XInternAtom(x11Display, "_NET_WM_STATE", False);\r
372             Atom wmFullScreen = XInternAtom(x11Display,"_NET_WM_STATE_FULLSCREEN", False);\r
373 \r
374             XEvent xev;\r
375             xev.xclient.type                = ClientMessage;\r
376             xev.xclient.serial              = 0;\r
377             xev.xclient.send_event      = True;\r
378             xev.xclient.window              = x11Window;\r
379             xev.xclient.message_type    = wmState;\r
380             xev.xclient.format              = 32;\r
381             xev.xclient.data.l[0]               = (fullScreen ? _NET_WM_STATE_ADD : _NET_WM_STATE_REMOVE);\r
382             xev.xclient.data.l[1]               = wmFullScreen;\r
383             xev.xclient.data.l[2]               = 0;\r
384 \r
385             XSendEvent(x11Display, DefaultRootWindow(x11Display), False, SubstructureRedirectMask | SubstructureNotifyMask, &xev);\r
386 \r
387             display = eglGetDisplay( (EGLNativeDisplayType)x11Display );\r
388 #else\r
389             display = eglGetDisplay( (EGLNativeDisplayType)0 );\r
390 #endif\r
391 \r
392         if( display == EGL_NO_DISPLAY )\r
393         {\r
394                 printf( "GLES EGL Error: GL No Display\n" );\r
395         }\r
396 \r
397         if( !eglInitialize( display, &majorVersion, &minorVersion ) )\r
398         {\r
399                 printf( "GLES EGL Error: eglInitialize failed\n" );\r
400         }\r
401 \r
402         if( !eglChooseConfig( display, attribList, &config, 1, &numConfigs ) )\r
403         {\r
404                 printf( "GLES EGL Error: eglChooseConfig failed\n" );\r
405         }\r
406 \r
407         context = eglCreateContext( display, config, NULL, NULL );\r
408         if( context==0 )\r
409         {\r
410                 printf( "GLES EGL Error: eglCreateContext failed\n" );\r
411         }\r
412 \r
413 #if defined(USE_X11)\r
414             surface = eglCreateWindowSurface( display, config, (EGLNativeDisplayType)x11Window, NULL );\r
415 #else\r
416             surface = eglCreateWindowSurface( display, config, (EGLNativeDisplayType)0, NULL );\r
417 #endif\r
418 \r
419     eglMakeCurrent( display, surface, surface, context );\r
420     if (!TestEGLError("eglMakeCurrent"))\r
421         printf("error eglMakeCurrent");\r
422     else\r
423         printf("GLES Window Opened\n");\r
424 }\r
425 \r
426 int GLinitialize() \r
427 {\r
428  initEGL();\r
429 \r
430  //----------------------------------------------------// \r
431 \r
432  glViewport(rRatioRect.left,                           // init viewport by ratio rect\r
433             iResY-(rRatioRect.top+rRatioRect.bottom),\r
434             rRatioRect.right, \r
435             rRatioRect.bottom); glError();\r
436                                                       \r
437  glScissor(0, 0, iResX, iResY); glError();             // init clipping (fullscreen)\r
438  glEnable(GL_SCISSOR_TEST); glError();\r
439 \r
440 #ifndef OWNSCALE\r
441  glMatrixMode(GL_TEXTURE);                             // init psx tex sow and tow if not "ownscale"\r
442  glLoadIdentity();\r
443  glScalef(1.0f/255.99f,1.0f/255.99f,1.0f);             // geforce precision hack\r
444 #endif \r
445 \r
446  glMatrixMode(GL_PROJECTION); glError();               // init projection with psx resolution\r
447  glLoadIdentity(); glError();\r
448  glOrtho(0,PSXDisplay.DisplayMode.x,\r
449          PSXDisplay.DisplayMode.y, 0, -1, 1); glError();\r
450 \r
451  if(iZBufferDepth)                                     // zbuffer?\r
452   {\r
453    uiBufferBits=GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT;\r
454    glEnable(GL_DEPTH_TEST); glError();\r
455    glDepthFunc(GL_ALWAYS); glError();\r
456    iDepthFunc=1;\r
457   }\r
458  else                                                  // no zbuffer?\r
459   {\r
460    uiBufferBits=GL_COLOR_BUFFER_BIT;\r
461    glDisable(GL_DEPTH_TEST); glError();\r
462   }\r
463 \r
464  glClearColor(0.0f, 0.0f, 0.0f, 0.0f); glError();      // first buffer clear\r
465  glClear(uiBufferBits); glError();\r
466 \r
467  GetExtInfos();                                        // get ext infos\r
468  SetExtGLFuncs();                                      // init all kind of stuff (tex function pointers)\r
469  \r
470  glEnable(GL_ALPHA_TEST); glError();                   // wanna alpha test\r
471 \r
472   {\r
473    glDisable(GL_LINE_SMOOTH); glError();\r
474    glDisable(GL_POINT_SMOOTH); glError();\r
475   }\r
476 \r
477  ubGloAlpha=127;                                       // init some drawing vars\r
478  ubGloColAlpha=127;\r
479  TWin.UScaleFactor = 1;\r
480  TWin.VScaleFactor = 1;\r
481  bDrawMultiPass=FALSE;\r
482  bTexEnabled=FALSE;\r
483  bUsingTWin=FALSE;\r
484       \r
485  if(bDrawDither)  glEnable(GL_DITHER);                 // dither mode\r
486  else             glDisable(GL_DITHER); \r
487  glError(); \r
488  glDisable(GL_FOG); glError();                          // turn all (currently) unused modes off\r
489  glDisable(GL_LIGHTING); glError();  \r
490  glDisable(GL_STENCIL_TEST); glError();  \r
491  glDisable(GL_TEXTURE_2D); glError();\r
492  glDisable(GL_CULL_FACE);\r
493 \r
494  glFlush(); glError();                                 // we are done...\r
495  glFinish(); glError();                           \r
496 \r
497  CreateScanLines();                                    // setup scanline stuff (if wanted)\r
498 \r
499  CheckTextureMemory();                                 // check available tex memory\r
500 \r
501  if(bKeepRatio) SetAspectRatio();                      // set ratio\r
502 \r
503  \r
504  bIsFirstFrame = FALSE;                                // we have survived the first frame :)\r
505 \r
506  return 0;\r
507 }\r
508 \r
509 ////////////////////////////////////////////////////////////////////////\r
510 // clean up OGL stuff\r
511 ////////////////////////////////////////////////////////////////////////\r
512 \r
513 void GLcleanup() \r
514 {                                                     \r
515  CleanupTextureStore();                                // bye textures\r
516 \r
517         eglMakeCurrent( display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT );\r
518         eglDestroySurface( display, surface );\r
519         eglDestroyContext( display, context );\r
520         eglTerminate( display );\r
521 \r
522 #if defined(USE_X11)\r
523                 if (x11Window) XDestroyWindow(x11Display, x11Window);\r
524                 if (x11Colormap) XFreeColormap( x11Display, x11Colormap );\r
525                 if (x11Display) XCloseDisplay(x11Display);\r
526 #endif\r
527 }\r
528 \r
529 ////////////////////////////////////////////////////////////////////////\r
530 ////////////////////////////////////////////////////////////////////////\r
531 ////////////////////////////////////////////////////////////////////////\r
532 \r
533 ////////////////////////////////////////////////////////////////////////\r
534 ////////////////////////////////////////////////////////////////////////\r
535 ////////////////////////////////////////////////////////////////////////\r
536 \r
537 ////////////////////////////////////////////////////////////////////////\r
538 // Offset stuff\r
539 ////////////////////////////////////////////////////////////////////////\r
540 \r
541 // please note: it is hardly do-able in a hw/accel plugin to get the \r
542 //              real psx polygon coord mapping right... the following\r
543 //              works not to bad with many games, though\r
544 \r
545 __inline BOOL CheckCoord4()\r
546 {\r
547  if(lx0<0)\r
548   {\r
549    if(((lx1-lx0)>CHKMAX_X) ||\r
550       ((lx2-lx0)>CHKMAX_X)) \r
551     {\r
552      if(lx3<0)\r
553       {\r
554        if((lx1-lx3)>CHKMAX_X) return TRUE;\r
555        if((lx2-lx3)>CHKMAX_X) return TRUE;\r
556       }\r
557     }\r
558   }\r
559  if(lx1<0)\r
560   {\r
561    if((lx0-lx1)>CHKMAX_X) return TRUE;\r
562    if((lx2-lx1)>CHKMAX_X) return TRUE;\r
563    if((lx3-lx1)>CHKMAX_X) return TRUE;\r
564   }\r
565  if(lx2<0)\r
566   {\r
567    if((lx0-lx2)>CHKMAX_X) return TRUE;\r
568    if((lx1-lx2)>CHKMAX_X) return TRUE;\r
569    if((lx3-lx2)>CHKMAX_X) return TRUE;\r
570   }\r
571  if(lx3<0)\r
572   {\r
573    if(((lx1-lx3)>CHKMAX_X) ||\r
574       ((lx2-lx3)>CHKMAX_X))\r
575     {\r
576      if(lx0<0)\r
577       {\r
578        if((lx1-lx0)>CHKMAX_X) return TRUE;\r
579        if((lx2-lx0)>CHKMAX_X) return TRUE;\r
580       }\r
581     }\r
582   }\r
583  \r
584 \r
585  if(ly0<0)\r
586   {\r
587    if((ly1-ly0)>CHKMAX_Y) return TRUE;\r
588    if((ly2-ly0)>CHKMAX_Y) return TRUE;\r
589   }\r
590  if(ly1<0)\r
591   {\r
592    if((ly0-ly1)>CHKMAX_Y) return TRUE;\r
593    if((ly2-ly1)>CHKMAX_Y) return TRUE;\r
594    if((ly3-ly1)>CHKMAX_Y) return TRUE;\r
595   }\r
596  if(ly2<0)\r
597   {\r
598    if((ly0-ly2)>CHKMAX_Y) return TRUE;\r
599    if((ly1-ly2)>CHKMAX_Y) return TRUE;\r
600    if((ly3-ly2)>CHKMAX_Y) return TRUE;\r
601   }\r
602  if(ly3<0)\r
603   {\r
604    if((ly1-ly3)>CHKMAX_Y) return TRUE;\r
605    if((ly2-ly3)>CHKMAX_Y) return TRUE;\r
606   }\r
607 \r
608  return FALSE;\r
609 }\r
610 \r
611 __inline BOOL CheckCoord3()\r
612 {\r
613  if(lx0<0)\r
614   {\r
615    if((lx1-lx0)>CHKMAX_X) return TRUE;\r
616    if((lx2-lx0)>CHKMAX_X) return TRUE;\r
617   }\r
618  if(lx1<0)\r
619   {\r
620    if((lx0-lx1)>CHKMAX_X) return TRUE;\r
621    if((lx2-lx1)>CHKMAX_X) return TRUE;\r
622   }\r
623  if(lx2<0)\r
624   {\r
625    if((lx0-lx2)>CHKMAX_X) return TRUE;\r
626    if((lx1-lx2)>CHKMAX_X) return TRUE;\r
627   }\r
628  if(ly0<0)\r
629   {\r
630    if((ly1-ly0)>CHKMAX_Y) return TRUE;\r
631    if((ly2-ly0)>CHKMAX_Y) return TRUE;\r
632   }\r
633  if(ly1<0)\r
634   {\r
635    if((ly0-ly1)>CHKMAX_Y) return TRUE;\r
636    if((ly2-ly1)>CHKMAX_Y) return TRUE;\r
637   }\r
638  if(ly2<0)\r
639   {\r
640    if((ly0-ly2)>CHKMAX_Y) return TRUE;\r
641    if((ly1-ly2)>CHKMAX_Y) return TRUE;\r
642   }\r
643 \r
644  return FALSE;\r
645 }\r
646 \r
647 \r
648 __inline BOOL CheckCoord2()\r
649 {\r
650  if(lx0<0)\r
651   {\r
652    if((lx1-lx0)>CHKMAX_X) return TRUE;\r
653   }\r
654  if(lx1<0)\r
655   {\r
656    if((lx0-lx1)>CHKMAX_X) return TRUE;\r
657   }\r
658  if(ly0<0)\r
659   {\r
660    if((ly1-ly0)>CHKMAX_Y) return TRUE;\r
661   }\r
662  if(ly1<0)\r
663   {\r
664    if((ly0-ly1)>CHKMAX_Y) return TRUE;\r
665   }\r
666 \r
667  return FALSE;\r
668 }\r
669 \r
670 // Pete's way: a very easy (and hopefully fast) approach for lines\r
671 // without sqrt... using a small float -> short cast trick :)\r
672 \r
673 #define VERTEX_OFFX 0.2f\r
674 #define VERTEX_OFFY 0.2f\r
675 \r
676 BOOL offsetline(void)           \r
677 {\r
678  short x0,x1,y0,y1,dx,dy;float px,py;\r
679 \r
680  if(bDisplayNotSet)\r
681   SetOGLDisplaySettings(1);\r
682 \r
683  if(!(dwActFixes&16))\r
684   {\r
685    lx0=(short)(((int)lx0<<SIGNSHIFT)>>SIGNSHIFT);\r
686    lx1=(short)(((int)lx1<<SIGNSHIFT)>>SIGNSHIFT);\r
687    ly0=(short)(((int)ly0<<SIGNSHIFT)>>SIGNSHIFT);\r
688    ly1=(short)(((int)ly1<<SIGNSHIFT)>>SIGNSHIFT);\r
689 \r
690    if(CheckCoord2()) return TRUE;\r
691   }\r
692 \r
693  x0 = (lx0 + PSXDisplay.CumulOffset.x)+1;\r
694  x1 = (lx1 + PSXDisplay.CumulOffset.x)+1;\r
695  y0 = (ly0 + PSXDisplay.CumulOffset.y)+1;\r
696  y1 = (ly1 + PSXDisplay.CumulOffset.y)+1;\r
697  \r
698  dx=x1-x0;\r
699  dy=y1-y0;\r
700  \r
701  if(dx>=0)\r
702   {\r
703    if(dy>=0)\r
704     {\r
705      px=0.5f;\r
706           if(dx>dy) py=-0.5f;\r
707      else if(dx<dy) py= 0.5f;\r
708      else           py= 0.0f;\r
709     }\r
710    else\r
711     {\r
712      py=-0.5f;\r
713      dy=-dy;\r
714           if(dx>dy) px= 0.5f;\r
715      else if(dx<dy) px=-0.5f;\r
716      else           px= 0.0f;\r
717     }\r
718   }\r
719  else\r
720   {\r
721    if(dy>=0)\r
722     {\r
723      py=0.5f;\r
724      dx=-dx;\r
725           if(dx>dy) px=-0.5f;\r
726      else if(dx<dy) px= 0.5f;\r
727      else           px= 0.0f;\r
728     }\r
729    else\r
730     {\r
731      px=-0.5f;\r
732           if(dx>dy) py=-0.5f;\r
733      else if(dx<dy) py= 0.5f;\r
734      else           py= 0.0f;\r
735     }\r
736   } \r
737  \r
738  vertex[0].x=(short)((float)x0-px);\r
739  vertex[3].x=(short)((float)x0+py);\r
740  \r
741  vertex[0].y=(short)((float)y0-py);\r
742  vertex[3].y=(short)((float)y0-px);\r
743  \r
744  vertex[1].x=(short)((float)x1-py);\r
745  vertex[2].x=(short)((float)x1+px);\r
746 \r
747  vertex[1].y=(short)((float)y1+px);\r
748  vertex[2].y=(short)((float)y1+py);\r
749 \r
750  if(vertex[0].x==vertex[3].x &&                        // ortho rect? done\r
751     vertex[1].x==vertex[2].x &&\r
752     vertex[0].y==vertex[1].y &&\r
753     vertex[2].y==vertex[3].y) return FALSE;\r
754  if(vertex[0].x==vertex[1].x &&\r
755     vertex[2].x==vertex[3].x &&\r
756     vertex[0].y==vertex[3].y &&\r
757     vertex[1].y==vertex[2].y) return FALSE;\r
758 \r
759  vertex[0].x-=VERTEX_OFFX;                             // otherwise a small offset\r
760  vertex[0].y-=VERTEX_OFFY;                             // to get better accuracy\r
761  vertex[1].x-=VERTEX_OFFX;\r
762  vertex[1].y-=VERTEX_OFFY;\r
763  vertex[2].x-=VERTEX_OFFX;\r
764  vertex[2].y-=VERTEX_OFFY;\r
765  vertex[3].x-=VERTEX_OFFX;\r
766  vertex[3].y-=VERTEX_OFFY;\r
767 \r
768  return FALSE;\r
769 }\r
770 \r
771 ///////////////////////////////////////////////////////// \r
772 \r
773 BOOL offset2(void)\r
774 {\r
775  if(bDisplayNotSet)\r
776   SetOGLDisplaySettings(1);\r
777 \r
778  if(!(dwActFixes&16))\r
779   {\r
780    lx0=(short)(((int)lx0<<SIGNSHIFT)>>SIGNSHIFT);\r
781    lx1=(short)(((int)lx1<<SIGNSHIFT)>>SIGNSHIFT);\r
782    ly0=(short)(((int)ly0<<SIGNSHIFT)>>SIGNSHIFT);\r
783    ly1=(short)(((int)ly1<<SIGNSHIFT)>>SIGNSHIFT);\r
784 \r
785    if(CheckCoord2()) return TRUE;\r
786   }\r
787 \r
788  vertex[0].x=lx0+PSXDisplay.CumulOffset.x;\r
789  vertex[1].x=lx1+PSXDisplay.CumulOffset.x;\r
790  vertex[0].y=ly0+PSXDisplay.CumulOffset.y;\r
791  vertex[1].y=ly1+PSXDisplay.CumulOffset.y;\r
792 \r
793  return FALSE;\r
794 }\r
795 \r
796 ///////////////////////////////////////////////////////// \r
797 \r
798 BOOL offset3(void)\r
799 {\r
800  if(bDisplayNotSet)\r
801   SetOGLDisplaySettings(1);\r
802 \r
803  if(!(dwActFixes&16))\r
804   {\r
805    lx0=(short)(((int)lx0<<SIGNSHIFT)>>SIGNSHIFT);\r
806    lx1=(short)(((int)lx1<<SIGNSHIFT)>>SIGNSHIFT);\r
807    lx2=(short)(((int)lx2<<SIGNSHIFT)>>SIGNSHIFT);\r
808    ly0=(short)(((int)ly0<<SIGNSHIFT)>>SIGNSHIFT);\r
809    ly1=(short)(((int)ly1<<SIGNSHIFT)>>SIGNSHIFT);\r
810    ly2=(short)(((int)ly2<<SIGNSHIFT)>>SIGNSHIFT);\r
811 \r
812    if(CheckCoord3()) return TRUE;\r
813   }\r
814 \r
815  vertex[0].x=lx0+PSXDisplay.CumulOffset.x;\r
816  vertex[1].x=lx1+PSXDisplay.CumulOffset.x;\r
817  vertex[2].x=lx2+PSXDisplay.CumulOffset.x;\r
818  vertex[0].y=ly0+PSXDisplay.CumulOffset.y;\r
819  vertex[1].y=ly1+PSXDisplay.CumulOffset.y;\r
820  vertex[2].y=ly2+PSXDisplay.CumulOffset.y;\r
821 \r
822  return FALSE;\r
823 }\r
824 \r
825 ///////////////////////////////////////////////////////// \r
826 \r
827 BOOL offset4(void)\r
828 {\r
829  if(bDisplayNotSet)\r
830   SetOGLDisplaySettings(1);\r
831 \r
832  if(!(dwActFixes&16))\r
833   {\r
834    lx0=(short)(((int)lx0<<SIGNSHIFT)>>SIGNSHIFT);\r
835    lx1=(short)(((int)lx1<<SIGNSHIFT)>>SIGNSHIFT);\r
836    lx2=(short)(((int)lx2<<SIGNSHIFT)>>SIGNSHIFT);\r
837    lx3=(short)(((int)lx3<<SIGNSHIFT)>>SIGNSHIFT);\r
838    ly0=(short)(((int)ly0<<SIGNSHIFT)>>SIGNSHIFT);\r
839    ly1=(short)(((int)ly1<<SIGNSHIFT)>>SIGNSHIFT);\r
840    ly2=(short)(((int)ly2<<SIGNSHIFT)>>SIGNSHIFT);\r
841    ly3=(short)(((int)ly3<<SIGNSHIFT)>>SIGNSHIFT);\r
842 \r
843    if(CheckCoord4()) return TRUE;\r
844   }\r
845 \r
846  vertex[0].x=lx0+PSXDisplay.CumulOffset.x;\r
847  vertex[1].x=lx1+PSXDisplay.CumulOffset.x;\r
848  vertex[2].x=lx2+PSXDisplay.CumulOffset.x;\r
849  vertex[3].x=lx3+PSXDisplay.CumulOffset.x;\r
850  vertex[0].y=ly0+PSXDisplay.CumulOffset.y;\r
851  vertex[1].y=ly1+PSXDisplay.CumulOffset.y;\r
852  vertex[2].y=ly2+PSXDisplay.CumulOffset.y;\r
853  vertex[3].y=ly3+PSXDisplay.CumulOffset.y;\r
854 \r
855  return FALSE;\r
856 }\r
857 \r
858 ///////////////////////////////////////////////////////// \r
859 \r
860 void offsetST(void)\r
861 {\r
862  if(bDisplayNotSet)\r
863   SetOGLDisplaySettings(1);\r
864 \r
865  if(!(dwActFixes&16))\r
866   {\r
867    lx0=(short)(((int)lx0<<SIGNSHIFT)>>SIGNSHIFT);\r
868    ly0=(short)(((int)ly0<<SIGNSHIFT)>>SIGNSHIFT);\r
869 \r
870    if(lx0<-512 && PSXDisplay.DrawOffset.x<=-512)\r
871     lx0+=2048;\r
872 \r
873    if(ly0<-512 && PSXDisplay.DrawOffset.y<=-512)\r
874     ly0+=2048;\r
875   }\r
876 \r
877  ly1 = ly0;\r
878  ly2 = ly3 = ly0+sprtH;\r
879  lx3 = lx0;\r
880  lx1 = lx2 = lx0+sprtW;\r
881 \r
882  vertex[0].x=lx0+PSXDisplay.CumulOffset.x;\r
883  vertex[1].x=lx1+PSXDisplay.CumulOffset.x;\r
884  vertex[2].x=lx2+PSXDisplay.CumulOffset.x;\r
885  vertex[3].x=lx3+PSXDisplay.CumulOffset.x;\r
886  vertex[0].y=ly0+PSXDisplay.CumulOffset.y;\r
887  vertex[1].y=ly1+PSXDisplay.CumulOffset.y;\r
888  vertex[2].y=ly2+PSXDisplay.CumulOffset.y;\r
889  vertex[3].y=ly3+PSXDisplay.CumulOffset.y;\r
890 }\r
891 \r
892 ///////////////////////////////////////////////////////// \r
893 \r
894 void offsetScreenUpload(long Position)\r
895 {\r
896  if(bDisplayNotSet)\r
897   SetOGLDisplaySettings(1);\r
898 \r
899  if(Position==-1)\r
900   {\r
901    long lmdx,lmdy;\r
902 \r
903    lmdx=xrUploadArea.x0;\r
904    lmdy=xrUploadArea.y0;\r
905 \r
906    lx0-=lmdx;\r
907    ly0-=lmdy;\r
908    lx1-=lmdx;\r
909    ly1-=lmdy;\r
910    lx2-=lmdx;\r
911    ly2-=lmdy;\r
912    lx3-=lmdx;\r
913    ly3-=lmdy;\r
914   }\r
915  else\r
916  if(Position)\r
917   {\r
918    lx0-=PSXDisplay.DisplayPosition.x;\r
919    ly0-=PSXDisplay.DisplayPosition.y;\r
920    lx1-=PSXDisplay.DisplayPosition.x;\r
921    ly1-=PSXDisplay.DisplayPosition.y;\r
922    lx2-=PSXDisplay.DisplayPosition.x;\r
923    ly2-=PSXDisplay.DisplayPosition.y;\r
924    lx3-=PSXDisplay.DisplayPosition.x;\r
925    ly3-=PSXDisplay.DisplayPosition.y;\r
926   }\r
927  else\r
928   {\r
929    lx0-=PreviousPSXDisplay.DisplayPosition.x;\r
930    ly0-=PreviousPSXDisplay.DisplayPosition.y;\r
931    lx1-=PreviousPSXDisplay.DisplayPosition.x;\r
932    ly1-=PreviousPSXDisplay.DisplayPosition.y;\r
933    lx2-=PreviousPSXDisplay.DisplayPosition.x;\r
934    ly2-=PreviousPSXDisplay.DisplayPosition.y;\r
935    lx3-=PreviousPSXDisplay.DisplayPosition.x;\r
936    ly3-=PreviousPSXDisplay.DisplayPosition.y;\r
937   }\r
938 \r
939  vertex[0].x=lx0 + PreviousPSXDisplay.Range.x0;\r
940  vertex[1].x=lx1 + PreviousPSXDisplay.Range.x0;\r
941  vertex[2].x=lx2 + PreviousPSXDisplay.Range.x0;\r
942  vertex[3].x=lx3 + PreviousPSXDisplay.Range.x0;\r
943  vertex[0].y=ly0 + PreviousPSXDisplay.Range.y0;\r
944  vertex[1].y=ly1 + PreviousPSXDisplay.Range.y0;\r
945  vertex[2].y=ly2 + PreviousPSXDisplay.Range.y0;\r
946  vertex[3].y=ly3 + PreviousPSXDisplay.Range.y0;\r
947 \r
948  if(iUseMask)\r
949   {\r
950    vertex[0].z=vertex[1].z=vertex[2].z=vertex[3].z=gl_z;\r
951    gl_z+=0.00004f;\r
952   }\r
953 }\r
954  \r
955 ///////////////////////////////////////////////////////// \r
956 \r
957 void offsetBlk(void)\r
958 {\r
959  if(bDisplayNotSet)\r
960   SetOGLDisplaySettings(1);\r
961                                             \r
962  vertex[0].x=lx0-PSXDisplay.GDrawOffset.x + PreviousPSXDisplay.Range.x0;\r
963  vertex[1].x=lx1-PSXDisplay.GDrawOffset.x + PreviousPSXDisplay.Range.x0;\r
964  vertex[2].x=lx2-PSXDisplay.GDrawOffset.x + PreviousPSXDisplay.Range.x0;\r
965  vertex[3].x=lx3-PSXDisplay.GDrawOffset.x + PreviousPSXDisplay.Range.x0;\r
966  vertex[0].y=ly0-PSXDisplay.GDrawOffset.y + PreviousPSXDisplay.Range.y0;\r
967  vertex[1].y=ly1-PSXDisplay.GDrawOffset.y + PreviousPSXDisplay.Range.y0;\r
968  vertex[2].y=ly2-PSXDisplay.GDrawOffset.y + PreviousPSXDisplay.Range.y0;\r
969  vertex[3].y=ly3-PSXDisplay.GDrawOffset.y + PreviousPSXDisplay.Range.y0;\r
970 \r
971  if(iUseMask)\r
972   {\r
973    vertex[0].z=vertex[1].z=vertex[2].z=vertex[3].z=gl_z;\r
974    gl_z+=0.00004f;\r
975   }\r
976 }\r
977 \r
978 ////////////////////////////////////////////////////////////////////////\r
979 // texture sow/tow calculations\r
980 ////////////////////////////////////////////////////////////////////////\r
981 \r
982 void assignTextureVRAMWrite(void)\r
983 {\r
984 #ifdef OWNSCALE\r
985 \r
986  vertex[0].sow=0.5f/ ST_FACVRAMX;\r
987  vertex[0].tow=0.5f/ ST_FACVRAM;\r
988 \r
989  vertex[1].sow=(float)gl_ux[1]/ ST_FACVRAMX;\r
990  vertex[1].tow=0.5f/ ST_FACVRAM;\r
991 \r
992  vertex[2].sow=(float)gl_ux[2]/ ST_FACVRAMX;\r
993  vertex[2].tow=(float)gl_vy[2]/ ST_FACVRAM;\r
994 \r
995  vertex[3].sow=0.5f/ ST_FACVRAMX;\r
996  vertex[3].tow=(float)gl_vy[3]/ ST_FACVRAM;\r
997 \r
998 #else\r
999 \r
1000  if(gl_ux[1]==255)\r
1001   {\r
1002    vertex[0].sow=(gl_ux[0]*255.99f)/255.0f;\r
1003    vertex[1].sow=(gl_ux[1]*255.99f)/255.0f;\r
1004    vertex[2].sow=(gl_ux[2]*255.99f)/255.0f;\r
1005    vertex[3].sow=(gl_ux[3]*255.99f)/255.0f;\r
1006   }\r
1007  else\r
1008   {\r
1009    vertex[0].sow=gl_ux[0];\r
1010    vertex[1].sow=gl_ux[1];\r
1011    vertex[2].sow=gl_ux[2];\r
1012    vertex[3].sow=gl_ux[3];\r
1013   }\r
1014 \r
1015  vertex[0].tow=gl_vy[0];\r
1016  vertex[1].tow=gl_vy[1];\r
1017  vertex[2].tow=gl_vy[2];\r
1018  vertex[3].tow=gl_vy[3];\r
1019 \r
1020 #endif\r
1021 }\r
1022 \r
1023 GLuint  gLastTex=0;\r
1024 GLuint  gLastFMode=(GLuint)-1;\r
1025 \r
1026 ///////////////////////////////////////////////////////// \r
1027 \r
1028 void assignTextureSprite(void)\r
1029 {\r
1030  if(bUsingTWin)\r
1031   {\r
1032    vertex[0].sow=vertex[3].sow=(float)gl_ux[0]/TWin.UScaleFactor;\r
1033    vertex[1].sow=vertex[2].sow=(float)sSprite_ux2/TWin.UScaleFactor;\r
1034    vertex[0].tow=vertex[1].tow=(float)gl_vy[0]/TWin.VScaleFactor;\r
1035    vertex[2].tow=vertex[3].tow=(float)sSprite_vy2/TWin.VScaleFactor;\r
1036    gLastTex=gTexName;\r
1037   }\r
1038  else\r
1039   {\r
1040 #ifdef OWNSCALE\r
1041 \r
1042    vertex[0].sow=vertex[3].sow=(float)gl_ux[0]     / ST_FACSPRITE;\r
1043    vertex[1].sow=vertex[2].sow=(float)sSprite_ux2  / ST_FACSPRITE;\r
1044    vertex[0].tow=vertex[1].tow=(float)gl_vy[0]     / ST_FACSPRITE;\r
1045    vertex[2].tow=vertex[3].tow=(float)sSprite_vy2  / ST_FACSPRITE;\r
1046 \r
1047 #else\r
1048  \r
1049    vertex[0].sow=vertex[3].sow=gl_ux[0];\r
1050    vertex[1].sow=vertex[2].sow=sSprite_ux2;\r
1051    vertex[0].tow=vertex[1].tow=gl_vy[0];\r
1052    vertex[2].tow=vertex[3].tow=sSprite_vy2;\r
1053 \r
1054 #endif\r
1055 \r
1056    if(iFilterType>2) \r
1057     {\r
1058      if(gLastTex!=gTexName || gLastFMode!=0)\r
1059       {\r
1060        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glError();\r
1061        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glError();\r
1062        gLastTex=gTexName;gLastFMode=0;\r
1063       }\r
1064     }\r
1065   }\r
1066 \r
1067  if(usMirror & 0x1000) \r
1068   {\r
1069    vertex[0].sow=vertex[1].sow;\r
1070    vertex[1].sow=vertex[2].sow=vertex[3].sow;\r
1071    vertex[3].sow=vertex[0].sow;\r
1072   }\r
1073 \r
1074  if(usMirror & 0x2000) \r
1075   {\r
1076    vertex[0].tow=vertex[3].tow;\r
1077    vertex[2].tow=vertex[3].tow=vertex[1].tow;\r
1078    vertex[1].tow=vertex[0].tow;\r
1079   }\r
1080 \r
1081 }\r
1082 \r
1083 ///////////////////////////////////////////////////////// \r
1084 \r
1085 void assignTexture3(void)\r
1086 {\r
1087  if(bUsingTWin)\r
1088   {\r
1089    vertex[0].sow=(float)gl_ux[0]/TWin.UScaleFactor;\r
1090    vertex[0].tow=(float)gl_vy[0]/TWin.VScaleFactor;\r
1091    vertex[1].sow=(float)gl_ux[1]/TWin.UScaleFactor;\r
1092    vertex[1].tow=(float)gl_vy[1]/TWin.VScaleFactor;\r
1093    vertex[2].sow=(float)gl_ux[2]/TWin.UScaleFactor;\r
1094    vertex[2].tow=(float)gl_vy[2]/TWin.VScaleFactor;\r
1095    gLastTex=gTexName;\r
1096   }\r
1097  else\r
1098   {\r
1099 #ifdef OWNSCALE\r
1100    vertex[0].sow=(float)gl_ux[0] / ST_FACTRI;\r
1101    vertex[0].tow=(float)gl_vy[0] / ST_FACTRI;\r
1102    vertex[1].sow=(float)gl_ux[1] / ST_FACTRI;\r
1103 \r
1104    vertex[1].tow=(float)gl_vy[1] / ST_FACTRI;\r
1105    vertex[2].sow=(float)gl_ux[2] / ST_FACTRI;\r
1106    vertex[2].tow=(float)gl_vy[2] / ST_FACTRI;\r
1107 #else\r
1108    vertex[0].sow=gl_ux[0];\r
1109    vertex[0].tow=gl_vy[0];\r
1110    vertex[1].sow=gl_ux[1];\r
1111    vertex[1].tow=gl_vy[1];\r
1112    vertex[2].sow=gl_ux[2];\r
1113    vertex[2].tow=gl_vy[2];\r
1114 #endif\r
1115 \r
1116    if(iFilterType>2) \r
1117     {\r
1118      if(gLastTex!=gTexName || gLastFMode!=1)\r
1119       {\r
1120        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glError();\r
1121        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glError();\r
1122        gLastTex=gTexName;gLastFMode=1;\r
1123       }\r
1124     }\r
1125 \r
1126    if(iFilterType) \r
1127     {\r
1128      float fxmin=256.0f,fxmax=0.0f,fymin=256.0f,fymax=0.0f;int i;\r
1129      for(i=0;i<3;i++)\r
1130       {\r
1131        if(vertex[i].sow<fxmin) fxmin=vertex[i].sow;\r
1132        if(vertex[i].tow<fymin) fymin=vertex[i].tow;\r
1133        if(vertex[i].sow>fxmax) fxmax=vertex[i].sow;\r
1134        if(vertex[i].tow>fymax) fymax=vertex[i].tow; \r
1135       }\r
1136 \r
1137      for(i=0;i<3;i++)\r
1138       {\r
1139        if(vertex[i].sow==fxmin) vertex[i].sow+=ST_BFFACSORT;\r
1140        if(vertex[i].sow==fxmax) vertex[i].sow-=ST_BFFACSORT;\r
1141        if(vertex[i].tow==fymin) vertex[i].tow+=ST_BFFACSORT;\r
1142        if(vertex[i].tow==fymax) vertex[i].tow-=ST_BFFACSORT;\r
1143       }\r
1144     }\r
1145   }\r
1146 }\r
1147 \r
1148 ///////////////////////////////////////////////////////// \r
1149 \r
1150 void assignTexture4(void)\r
1151 {\r
1152  if(bUsingTWin)\r
1153   {\r
1154    vertex[0].sow=(float)gl_ux[0]/TWin.UScaleFactor;\r
1155    vertex[0].tow=(float)gl_vy[0]/TWin.VScaleFactor;\r
1156    vertex[1].sow=(float)gl_ux[1]/TWin.UScaleFactor;\r
1157    vertex[1].tow=(float)gl_vy[1]/TWin.VScaleFactor;\r
1158    vertex[2].sow=(float)gl_ux[2]/TWin.UScaleFactor;\r
1159    vertex[2].tow=(float)gl_vy[2]/TWin.VScaleFactor;\r
1160    vertex[3].sow=(float)gl_ux[3]/TWin.UScaleFactor;\r
1161    vertex[3].tow=(float)gl_vy[3]/TWin.VScaleFactor;\r
1162    gLastTex=gTexName;\r
1163   }\r
1164  else\r
1165   {\r
1166 #ifdef OWNSCALE\r
1167    vertex[0].sow=(float)gl_ux[0] / ST_FAC;\r
1168    vertex[0].tow=(float)gl_vy[0] / ST_FAC;\r
1169    vertex[1].sow=(float)gl_ux[1] / ST_FAC;\r
1170    vertex[1].tow=(float)gl_vy[1] / ST_FAC;\r
1171    vertex[2].sow=(float)gl_ux[2] / ST_FAC;\r
1172    vertex[2].tow=(float)gl_vy[2] / ST_FAC;\r
1173    vertex[3].sow=(float)gl_ux[3] / ST_FAC;\r
1174    vertex[3].tow=(float)gl_vy[3] / ST_FAC;\r
1175 #else\r
1176    vertex[0].sow=gl_ux[0];\r
1177    vertex[0].tow=gl_vy[0];\r
1178    vertex[1].sow=gl_ux[1];\r
1179    vertex[1].tow=gl_vy[1];\r
1180    vertex[2].sow=gl_ux[2];\r
1181    vertex[2].tow=gl_vy[2];\r
1182    vertex[3].sow=gl_ux[3];\r
1183    vertex[3].tow=gl_vy[3];\r
1184 #endif\r
1185 \r
1186    if(iFilterType>2) \r
1187     {\r
1188      if(gLastTex!=gTexName || gLastFMode!=1)\r
1189       {\r
1190        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glError();\r
1191        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glError();\r
1192        gLastTex=gTexName;gLastFMode=1;\r
1193       }\r
1194     }\r
1195 \r
1196    if(iFilterType) \r
1197     {\r
1198      float fxmin=256.0f,fxmax=0.0f,fymin=256.0f,fymax=0.0f;int i;\r
1199      for(i=0;i<4;i++)\r
1200       {\r
1201        if(vertex[i].sow<fxmin) fxmin=vertex[i].sow;\r
1202        if(vertex[i].tow<fymin) fymin=vertex[i].tow;\r
1203        if(vertex[i].sow>fxmax) fxmax=vertex[i].sow;\r
1204        if(vertex[i].tow>fymax) fymax=vertex[i].tow; \r
1205       }\r
1206 \r
1207      for(i=0;i<4;i++)\r
1208       {\r
1209        if(vertex[i].sow==fxmin) vertex[i].sow+=ST_BFFACSORT;\r
1210        if(vertex[i].sow==fxmax) vertex[i].sow-=ST_BFFACSORT;\r
1211        if(vertex[i].tow==fymin) vertex[i].tow+=ST_BFFACSORT;\r
1212        if(vertex[i].tow==fymax) vertex[i].tow-=ST_BFFACSORT;\r
1213       }\r
1214     }\r
1215   }\r
1216 }\r
1217 \r
1218 ////////////////////////////////////////////////////////////////////////\r
1219 ////////////////////////////////////////////////////////////////////////\r
1220 ////////////////////////////////////////////////////////////////////////\r
1221 \r
1222 ////////////////////////////////////////////////////////////////////////\r
1223 // render pos / buffers\r
1224 ////////////////////////////////////////////////////////////////////////\r
1225 \r
1226 #define EqualRect(pr1,pr2) ((pr1)->left==(pr2)->left && (pr1)->top==(pr2)->top && (pr1)->right==(pr2)->right && (pr1)->bottom==(pr2)->bottom)\r
1227 \r
1228 ////////////////////////////////////////////////////////////////////////\r
1229 // SetDisplaySettings: "simply" calcs the new drawing area and updates\r
1230 //                     the ogl clipping (scissor) \r
1231 \r
1232 BOOL bSetClip=FALSE;\r
1233 \r
1234 void SetOGLDisplaySettings(BOOL DisplaySet)\r
1235 {\r
1236  static RECT rprev={0,0,0,0};\r
1237  static RECT rC   ={0,0,0,0};\r
1238  static int iOldX=0;\r
1239  static int iOldY=0;\r
1240  RECT r;float XS,YS;\r
1241 \r
1242  bDisplayNotSet = FALSE;\r
1243 \r
1244  //----------------------------------------------------// that's a whole screen upload\r
1245  if(!DisplaySet)\r
1246   {\r
1247    RECT rX;\r
1248    PSXDisplay.GDrawOffset.x=0;\r
1249    PSXDisplay.GDrawOffset.y=0;\r
1250 \r
1251    PSXDisplay.CumulOffset.x = PSXDisplay.DrawOffset.x+PreviousPSXDisplay.Range.x0;\r
1252    PSXDisplay.CumulOffset.y = PSXDisplay.DrawOffset.y+PreviousPSXDisplay.Range.y0;\r
1253 \r
1254    rprev.left=rprev.left+1;\r
1255 \r
1256    rX=rRatioRect;\r
1257    rX.top=iResY-(rRatioRect.top+rRatioRect.bottom);\r
1258 \r
1259    if(bSetClip || !EqualRect(&rC,&rX))\r
1260     {\r
1261      rC=rX;\r
1262      glScissor(rC.left,rC.top,rC.right,rC.bottom); glError();\r
1263      //LOGE("glscissor:%d %d %d %d",rC.left,rC.top,rC.right,rC.bottom);\r
1264      bSetClip=FALSE; \r
1265     }\r
1266    return;\r
1267   }\r
1268  //----------------------------------------------------// \r
1269 \r
1270  PSXDisplay.GDrawOffset.y = PreviousPSXDisplay.DisplayPosition.y;\r
1271  PSXDisplay.GDrawOffset.x = PreviousPSXDisplay.DisplayPosition.x;\r
1272  PSXDisplay.CumulOffset.x = PSXDisplay.DrawOffset.x - PSXDisplay.GDrawOffset.x+PreviousPSXDisplay.Range.x0;\r
1273  PSXDisplay.CumulOffset.y = PSXDisplay.DrawOffset.y - PSXDisplay.GDrawOffset.y+PreviousPSXDisplay.Range.y0;\r
1274 \r
1275  r.top   =PSXDisplay.DrawArea.y0 - PreviousPSXDisplay.DisplayPosition.y;\r
1276  r.bottom=PSXDisplay.DrawArea.y1 - PreviousPSXDisplay.DisplayPosition.y;\r
1277 \r
1278  if(r.bottom<0 || r.top>=PSXDisplay.DisplayMode.y)\r
1279   {\r
1280    r.top   =PSXDisplay.DrawArea.y0 - PSXDisplay.DisplayPosition.y;\r
1281    r.bottom=PSXDisplay.DrawArea.y1 - PSXDisplay.DisplayPosition.y;\r
1282   }\r
1283 \r
1284  r.left  =PSXDisplay.DrawArea.x0 - PreviousPSXDisplay.DisplayPosition.x;\r
1285  r.right =PSXDisplay.DrawArea.x1 - PreviousPSXDisplay.DisplayPosition.x;\r
1286 \r
1287  if(r.right<0 || r.left>=PSXDisplay.DisplayMode.x)\r
1288   {\r
1289    r.left  =PSXDisplay.DrawArea.x0 - PSXDisplay.DisplayPosition.x;\r
1290    r.right =PSXDisplay.DrawArea.x1 - PSXDisplay.DisplayPosition.x;\r
1291   }\r
1292 \r
1293  if(!bSetClip && EqualRect(&r,&rprev) &&\r
1294     iOldX == PSXDisplay.DisplayMode.x &&\r
1295     iOldY == PSXDisplay.DisplayMode.y)\r
1296   return;\r
1297 \r
1298  rprev = r;\r
1299  iOldX = PSXDisplay.DisplayMode.x;\r
1300  iOldY = PSXDisplay.DisplayMode.y;\r
1301 \r
1302  XS=(float)rRatioRect.right/(float)PSXDisplay.DisplayMode.x;\r
1303  YS=(float)rRatioRect.bottom/(float)PSXDisplay.DisplayMode.y;\r
1304 \r
1305  if(PreviousPSXDisplay.Range.x0)\r
1306   {\r
1307    short s=PreviousPSXDisplay.Range.x0+PreviousPSXDisplay.Range.x1;\r
1308 \r
1309    r.left+=PreviousPSXDisplay.Range.x0+1;\r
1310 \r
1311    r.right+=PreviousPSXDisplay.Range.x0;\r
1312 \r
1313    if(r.left>s)  r.left=s;\r
1314    if(r.right>s) r.right=s;\r
1315   }\r
1316 \r
1317  if(PreviousPSXDisplay.Range.y0)\r
1318   {\r
1319    short s=PreviousPSXDisplay.Range.y0+PreviousPSXDisplay.Range.y1;\r
1320 \r
1321    r.top+=PreviousPSXDisplay.Range.y0+1;\r
1322    r.bottom+=PreviousPSXDisplay.Range.y0;\r
1323 \r
1324    if(r.top>s)    r.top=s;\r
1325    if(r.bottom>s) r.bottom=s;\r
1326   }\r
1327 \r
1328  // Set the ClipArea variables to reflect the new screen,\r
1329  // offset from zero (since it is a new display buffer)\r
1330  r.left   = (int)(((float)(r.left))      *XS);\r
1331  r.top    = (int)(((float)(r.top))       *YS);\r
1332  r.right  = (int)(((float)(r.right  + 1))*XS);\r
1333  r.bottom = (int)(((float)(r.bottom + 1))*YS);\r
1334 \r
1335  // Limit clip area to the screen size\r
1336  if (r.left   > iResX)   r.left   = iResX;\r
1337  if (r.left   < 0)       r.left   = 0;\r
1338  if (r.top    > iResY)   r.top    = iResY;\r
1339  if (r.top    < 0)       r.top    = 0;\r
1340  if (r.right  > iResX)   r.right  = iResX;\r
1341  if (r.right  < 0)       r.right  = 0;\r
1342  if (r.bottom > iResY)   r.bottom = iResY;\r
1343  if (r.bottom < 0)       r.bottom = 0;\r
1344 \r
1345  r.right -=r.left;\r
1346  r.bottom-=r.top;\r
1347  r.top=iResY-(r.top+r.bottom);\r
1348 \r
1349  r.left+=rRatioRect.left;\r
1350  r.top -=rRatioRect.top;\r
1351 \r
1352  if(bSetClip || !EqualRect(&r,&rC))\r
1353   {\r
1354    glScissor(r.left,r.top,r.right,r.bottom); glError();\r
1355 \r
1356    rC=r;\r
1357    bSetClip=FALSE;\r
1358   }\r
1359 }\r
1360 \r
1361 ////////////////////////////////////////////////////////////////////////\r
1362 ////////////////////////////////////////////////////////////////////////\r
1363 ////////////////////////////////////////////////////////////////////////\r
1364 \r