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