gpu-gles: schtruck/fpse merge: don't delay gl init
[pcsx_rearmed.git] / plugins / gpu-gles / gpuDraw.c
CommitLineData
ce879073 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
13326d3e 30\r
ce879073 31#include "gpuExternals.h"\r
7eadbf88 32#include "gpuPlugin.h"\r
ce879073 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
ce879073 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
ce879073 94void glBlendEquationEXT(GLenum mode);\r
95void glColorTableEXT(GLenum target, GLenum internalFormat, GLsizei width, GLenum format,GLenum type, const GLvoid *data);\r
ce879073 96\r
97// draw globals; most will be initialized again later (by config or checks) \r
98\r
99BOOL bIsFirstFrame=TRUE;\r
100\r
101// resolution/ratio vars\r
102\r
103int iResX;\r
104int iResY;\r
105BOOL bKeepRatio=FALSE;\r
106RECT rRatioRect;\r
107\r
108// psx mask related vars\r
109\r
110BOOL bCheckMask=FALSE;\r
111int iUseMask=0;\r
112int iSetMask=0;\r
113unsigned short sSetMask=0;\r
114unsigned long lSetMask=0;\r
115\r
116// drawing/coord vars\r
117\r
118OGLVertex vertex[4];\r
119GLubyte gl_ux[8];\r
120GLubyte gl_vy[8];\r
121short sprtY,sprtX,sprtH,sprtW;\r
122\r
123// drawing options\r
124\r
125BOOL bOpaquePass;\r
126BOOL bAdvancedBlend;\r
127\r
128// OGL extension support\r
129\r
130\r
131// gfx card buffer infos\r
132\r
133int iDepthFunc=0;\r
134int iZBufferDepth=0;\r
135GLbitfield 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
ce879073 145\r
146////////////////////////////////////////////////////////////////////////\r
147// Get extension infos (f.e. pal textures / packed pixels)\r
148////////////////////////////////////////////////////////////////////////\r
149\r
150void GetExtInfos(void) \r
151{\r
152 BOOL bPacked=FALSE; // default: no packed pixel support\r
153\r
677ea103 154 if(strstr((char *)glGetString(GL_EXTENSIONS), // packed pixels available?\r
ce879073 155 "GL_EXT_packed_pixels")) \r
156 bPacked=TRUE; // -> ok\r
157\r
158 \r
ce879073 159 iClampType=GL_CLAMP_TO_EDGE;\r
ce879073 160}\r
161\r
162////////////////////////////////////////////////////////////////////////\r
163// Setup some stuff depending on user settings or in-game toggle\r
164////////////////////////////////////////////////////////////////////////\r
165\r
166void 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
225GLuint gTexScanName=0;\r
226\r
227GLubyte 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
235void CreateScanLines(void)\r
236{\r
237}\r
238\r
239////////////////////////////////////////////////////////////////////////\r
240// Initialize OGL\r
241////////////////////////////////////////////////////////////////////////\r
242\r
7eadbf88 243#define MODE_RAW 0\r
244#define MODE_X11 1\r
245#define MODE_SDL 2\r
7eadbf88 246int use_fsaa = 0;\r
247\r
248EGLDisplay display;\r
249EGLConfig config;\r
250EGLContext context;\r
251EGLSurface 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
258Window x11Window = 0;\r
259Display* x11Display = 0;\r
260long x11Screen = 0;\r
261XVisualInfo x11Visual;\r
262XVisualInfo* px11Visual = 0;\r
263Colormap x11Colormap = 0;\r
264#endif\r
265\r
266EGLint 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
276EGLint attrib_list[] =\r
277{\r
07f75e28 278// EGL_DEPTH_SIZE, 16,\r
7eadbf88 279 EGL_NONE\r
280};\r
281\r
ce879073 282bool 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
7eadbf88 293 return FALSE;\r
ce879073 294 }\r
295\r
7eadbf88 296 return TRUE;\r
ce879073 297}\r
298\r
07f75e28 299static void initEGL(void)\r
300{\r
7eadbf88 301 printf ("GL init\n");\r
ce879073 302\r
7eadbf88 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
ce879073 313 \r
7eadbf88 314 Window sRootWindow;\r
315 XSetWindowAttributes sWA;\r
316 unsigned int ui32Mask;\r
317 int i32Depth;\r
318#endif\r
ce879073 319 \r
7eadbf88 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
7eadbf88 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
ce879073 339 \r
7eadbf88 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
ce879073 348 }\r
7eadbf88 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
ce879073 355\r
7eadbf88 356 // Display capabilities list.\r
357 ui32Mask = CWBackPixel | CWBorderPixel | CWEventMask | CWColormap;\r
ce879073 358 \r
7eadbf88 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
07f75e28 386#else\r
7eadbf88 387 display = eglGetDisplay( (EGLNativeDisplayType)0 );\r
07f75e28 388#endif\r
7eadbf88 389\r
390 if( display == EGL_NO_DISPLAY )\r
ce879073 391 {\r
7eadbf88 392 printf( "GLES EGL Error: GL No Display\n" );\r
ce879073 393 }\r
7eadbf88 394\r
395 if( !eglInitialize( display, &majorVersion, &minorVersion ) )\r
ce879073 396 {\r
7eadbf88 397 printf( "GLES EGL Error: eglInitialize failed\n" );\r
ce879073 398 }\r
399\r
7eadbf88 400 if( !eglChooseConfig( display, attribList, &config, 1, &numConfigs ) )\r
ce879073 401 {\r
7eadbf88 402 printf( "GLES EGL Error: eglChooseConfig failed\n" );\r
ce879073 403 }\r
404\r
7eadbf88 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
ce879073 410\r
7eadbf88 411#if defined(USE_X11)\r
7eadbf88 412 surface = eglCreateWindowSurface( display, config, (EGLNativeDisplayType)x11Window, NULL );\r
07f75e28 413#else\r
7eadbf88 414 surface = eglCreateWindowSurface( display, config, (EGLNativeDisplayType)0, NULL );\r
07f75e28 415#endif\r
7eadbf88 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
ce879073 422}\r
ce879073 423\r
424int GLinitialize() \r
425{\r
07f75e28 426 initEGL();\r
427\r
ce879073 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
511void GLcleanup() \r
512{ \r
513 CleanupTextureStore(); // bye textures\r
514\r
7eadbf88 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
7eadbf88 521 if (x11Window) XDestroyWindow(x11Display, x11Window);\r
522 if (x11Colormap) XFreeColormap( x11Display, x11Colormap );\r
523 if (x11Display) XCloseDisplay(x11Display);\r
7eadbf88 524#endif\r
ce879073 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
674BOOL 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
771BOOL 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
796BOOL 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
825BOOL 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
858void 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
892void 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
955void 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
980void 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
1021GLuint gLastTex=0;\r
1022GLuint gLastFMode=(GLuint)-1;\r
1023\r
1024///////////////////////////////////////////////////////// \r
1025\r
1026void 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
1083void 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
1148void 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
ce879073 1224#define EqualRect(pr1,pr2) ((pr1)->left==(pr2)->left && (pr1)->top==(pr2)->top && (pr1)->right==(pr2)->right && (pr1)->bottom==(pr2)->bottom)\r
ce879073 1225\r
1226////////////////////////////////////////////////////////////////////////\r
1227// SetDisplaySettings: "simply" calcs the new drawing area and updates\r
1228// the ogl clipping (scissor) \r
1229\r
1230BOOL bSetClip=FALSE;\r
1231\r
1232void 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