gpu-gles: schtruck/fpse merge: gl error checks
[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
9f58cabb 178 glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); glError();\r
ce879073 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
9f58cabb 195 glAlphaFuncx(GL_GREATER,0.49f); glError();\r
196\r
ce879073 197 }\r
198 else // no opaque mode?\r
199 {\r
200 TCF[0]=TCF[1]=P8RGBA;\r
201 PalTexturedColourFn=P8RGBA; // -> init col func\r
9f58cabb 202 glAlphaFuncx(GL_NOTEQUAL,0); glError(); // --> set alpha func\r
203\r
ce879073 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
9f58cabb 211 glDisable(GL_BLEND); glError();\r
212\r
ce879073 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
227GLuint gTexScanName=0;\r
228\r
229GLubyte 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
237void CreateScanLines(void)\r
238{\r
239}\r
240\r
241////////////////////////////////////////////////////////////////////////\r
242// Initialize OGL\r
243////////////////////////////////////////////////////////////////////////\r
244\r
7eadbf88 245#define MODE_RAW 0\r
246#define MODE_X11 1\r
247#define MODE_SDL 2\r
7eadbf88 248int use_fsaa = 0;\r
249\r
250EGLDisplay display;\r
251EGLConfig config;\r
252EGLContext context;\r
253EGLSurface 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
260Window x11Window = 0;\r
261Display* x11Display = 0;\r
262long x11Screen = 0;\r
263XVisualInfo x11Visual;\r
264XVisualInfo* px11Visual = 0;\r
265Colormap x11Colormap = 0;\r
266#endif\r
267\r
268EGLint 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
278EGLint attrib_list[] =\r
279{\r
07f75e28 280// EGL_DEPTH_SIZE, 16,\r
7eadbf88 281 EGL_NONE\r
282};\r
283\r
ce879073 284bool 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
7eadbf88 295 return FALSE;\r
ce879073 296 }\r
297\r
7eadbf88 298 return TRUE;\r
ce879073 299}\r
300\r
07f75e28 301static void initEGL(void)\r
302{\r
7eadbf88 303 printf ("GL init\n");\r
ce879073 304\r
7eadbf88 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
ce879073 315 \r
7eadbf88 316 Window sRootWindow;\r
317 XSetWindowAttributes sWA;\r
318 unsigned int ui32Mask;\r
319 int i32Depth;\r
320#endif\r
ce879073 321 \r
7eadbf88 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
7eadbf88 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
ce879073 341 \r
7eadbf88 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
ce879073 350 }\r
7eadbf88 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
ce879073 357\r
7eadbf88 358 // Display capabilities list.\r
359 ui32Mask = CWBackPixel | CWBorderPixel | CWEventMask | CWColormap;\r
ce879073 360 \r
7eadbf88 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
07f75e28 388#else\r
7eadbf88 389 display = eglGetDisplay( (EGLNativeDisplayType)0 );\r
07f75e28 390#endif\r
7eadbf88 391\r
392 if( display == EGL_NO_DISPLAY )\r
ce879073 393 {\r
7eadbf88 394 printf( "GLES EGL Error: GL No Display\n" );\r
ce879073 395 }\r
7eadbf88 396\r
397 if( !eglInitialize( display, &majorVersion, &minorVersion ) )\r
ce879073 398 {\r
7eadbf88 399 printf( "GLES EGL Error: eglInitialize failed\n" );\r
ce879073 400 }\r
401\r
7eadbf88 402 if( !eglChooseConfig( display, attribList, &config, 1, &numConfigs ) )\r
ce879073 403 {\r
7eadbf88 404 printf( "GLES EGL Error: eglChooseConfig failed\n" );\r
ce879073 405 }\r
406\r
7eadbf88 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
ce879073 412\r
7eadbf88 413#if defined(USE_X11)\r
7eadbf88 414 surface = eglCreateWindowSurface( display, config, (EGLNativeDisplayType)x11Window, NULL );\r
07f75e28 415#else\r
7eadbf88 416 surface = eglCreateWindowSurface( display, config, (EGLNativeDisplayType)0, NULL );\r
07f75e28 417#endif\r
7eadbf88 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
ce879073 424}\r
ce879073 425\r
426int GLinitialize() \r
427{\r
07f75e28 428 initEGL();\r
429\r
ce879073 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
9f58cabb 435 rRatioRect.bottom); glError();\r
ce879073 436 \r
9f58cabb 437 glScissor(0, 0, iResX, iResY); glError(); // init clipping (fullscreen)\r
438 glEnable(GL_SCISSOR_TEST); glError();\r
ce879073 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
9f58cabb 446 glMatrixMode(GL_PROJECTION); glError(); // init projection with psx resolution\r
447 glLoadIdentity(); glError();\r
ce879073 448 glOrtho(0,PSXDisplay.DisplayMode.x,\r
9f58cabb 449 PSXDisplay.DisplayMode.y, 0, -1, 1); glError();\r
ce879073 450\r
451 if(iZBufferDepth) // zbuffer?\r
452 {\r
453 uiBufferBits=GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT;\r
9f58cabb 454 glEnable(GL_DEPTH_TEST); glError();\r
455 glDepthFunc(GL_ALWAYS); glError();\r
ce879073 456 iDepthFunc=1;\r
457 }\r
458 else // no zbuffer?\r
459 {\r
460 uiBufferBits=GL_COLOR_BUFFER_BIT;\r
9f58cabb 461 glDisable(GL_DEPTH_TEST); glError();\r
ce879073 462 }\r
463\r
9f58cabb 464 glClearColor(0.0f, 0.0f, 0.0f, 0.0f); glError(); // first buffer clear\r
465 glClear(uiBufferBits); glError();\r
ce879073 466\r
467 GetExtInfos(); // get ext infos\r
468 SetExtGLFuncs(); // init all kind of stuff (tex function pointers)\r
469 \r
9f58cabb 470 glEnable(GL_ALPHA_TEST); glError(); // wanna alpha test\r
ce879073 471\r
472 {\r
9f58cabb 473 glDisable(GL_LINE_SMOOTH); glError();\r
474 glDisable(GL_POINT_SMOOTH); glError();\r
ce879073 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
9f58cabb 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
ce879073 492 glDisable(GL_CULL_FACE);\r
493\r
9f58cabb 494 glFlush(); glError(); // we are done...\r
495 glFinish(); glError(); \r
ce879073 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
513void GLcleanup() \r
514{ \r
515 CleanupTextureStore(); // bye textures\r
516\r
7eadbf88 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
7eadbf88 523 if (x11Window) XDestroyWindow(x11Display, x11Window);\r
524 if (x11Colormap) XFreeColormap( x11Display, x11Colormap );\r
525 if (x11Display) XCloseDisplay(x11Display);\r
7eadbf88 526#endif\r
ce879073 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
676BOOL 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
773BOOL 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
798BOOL 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
827BOOL 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
860void 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
894void 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
957void 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
982void 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
1023GLuint gLastTex=0;\r
1024GLuint gLastFMode=(GLuint)-1;\r
1025\r
1026///////////////////////////////////////////////////////// \r
1027\r
1028void 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
9f58cabb 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
ce879073 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
1085void 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
9f58cabb 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
ce879073 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
1150void 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
9f58cabb 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
ce879073 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
ce879073 1226#define EqualRect(pr1,pr2) ((pr1)->left==(pr2)->left && (pr1)->top==(pr2)->top && (pr1)->right==(pr2)->right && (pr1)->bottom==(pr2)->bottom)\r
ce879073 1227\r
1228////////////////////////////////////////////////////////////////////////\r
1229// SetDisplaySettings: "simply" calcs the new drawing area and updates\r
1230// the ogl clipping (scissor) \r
1231\r
1232BOOL bSetClip=FALSE;\r
1233\r
1234void 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
9f58cabb 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
ce879073 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
9f58cabb 1354 glScissor(r.left,r.top,r.right,r.bottom); glError();\r
1355\r
ce879073 1356 rC=r;\r
1357 bSetClip=FALSE;\r
1358 }\r
1359}\r
1360\r
1361////////////////////////////////////////////////////////////////////////\r
1362////////////////////////////////////////////////////////////////////////\r
1363////////////////////////////////////////////////////////////////////////\r
1364\r