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