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