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