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