gpu-gles: clean up headers and stuff
[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
30#ifdef _WINDOWS\r
31#include "stdafx.h"\r
32#include <stdio.h>\r
33#include <stdlib.h>\r
34#include <math.h>\r
35#include "externals.h"\r
36#include "gpu.h"\r
37#include "draw.h"\r
38#include "prim.h"\r
39#include "texture.h"\r
40#else\r
41#include "gpuExternals.h"\r
7eadbf88 42#include "gpuPlugin.h"\r
ce879073 43#include "gpuDraw.h"\r
44#include "gpuPrim.h"\r
45#include "gpuTexture.h"\r
46#include "gpuStdafx.h"\r
47\r
48#include <stdio.h>\r
49#include <stdlib.h>\r
50#include <math.h>\r
51#endif\r
52//#include "menu.h"\r
53 \r
54////////////////////////////////////////////////////////////////////////////////////\r
55// defines\r
56\r
57#define SIGNBIT 0x800\r
58#define S_MASK 0xf000\r
59#define L_MASK 0xfffff000\r
60\r
61// ownscale: some ogl drivers have buggy texture matrix funcs, so it\r
62// is safer to calc sow/tow ourselves\r
63\r
64#ifdef OWNSCALE\r
65\r
66///////////////////////////////////////////////////////////////\r
67\r
68#define ST_FACSPRITE 255.99f\r
69#define ST_BFFACSPRITE 0.5f/256.0f\r
70#define ST_BFFACSPRITESORT 0.333f/256.0f\r
71\r
72#define ST_OFFSET 0.5f/256.0f;\r
73\r
74#define ST_FAC 255.99f\r
75#define ST_BFFAC 0.5f/256.0f\r
76#define ST_BFFACSORT 0.333f/256.0f\r
77\r
78#define ST_FACTRI 255.99f\r
79#define ST_BFFACTRI 0.5f/256.0f\r
80#define ST_BFFACTRISORT 0.333f/256.0f\r
81\r
82#define ST_FACVRAMX 255.0f\r
83#define ST_FACVRAM 256.0f\r
84\r
85///////////////////////////////////////////////////////////////\r
86\r
87#else\r
88\r
89#define ST_BFFACSPRITE 0.5f\r
90#define ST_BFFACSPRITESORT 0.333f\r
91\r
92#define ST_BFFAC 0.5f\r
93#define ST_BFFACSORT 0.333f\r
94\r
95#define ST_BFFACTRI 0.5f\r
96#define ST_BFFACTRISORT 0.333f\r
97\r
98#define ST_OFFSET 0.5f;\r
99 \r
100#endif\r
101\r
102////////////////////////////////////////////////////////////////////////////////////\r
103// draw globals\r
104\r
105#ifdef _WINDOWS\r
106HDC dcGlobal=NULL;\r
107HWND hWWindow;\r
108#else\r
109void glBlendEquationEXT(GLenum mode);\r
110void glColorTableEXT(GLenum target, GLenum internalFormat, GLsizei width, GLenum format,GLenum type, const GLvoid *data);\r
111#endif\r
112\r
113// draw globals; most will be initialized again later (by config or checks) \r
114\r
115BOOL bIsFirstFrame=TRUE;\r
116\r
117// resolution/ratio vars\r
118\r
119int iResX;\r
120int iResY;\r
121BOOL bKeepRatio=FALSE;\r
122RECT rRatioRect;\r
123\r
124// psx mask related vars\r
125\r
126BOOL bCheckMask=FALSE;\r
127int iUseMask=0;\r
128int iSetMask=0;\r
129unsigned short sSetMask=0;\r
130unsigned long lSetMask=0;\r
131\r
132// drawing/coord vars\r
133\r
134OGLVertex vertex[4];\r
135GLubyte gl_ux[8];\r
136GLubyte gl_vy[8];\r
137short sprtY,sprtX,sprtH,sprtW;\r
138\r
139// drawing options\r
140\r
141BOOL bOpaquePass;\r
142BOOL bAdvancedBlend;\r
143\r
144// OGL extension support\r
145\r
146\r
147// gfx card buffer infos\r
148\r
149int iDepthFunc=0;\r
150int iZBufferDepth=0;\r
151GLbitfield uiBufferBits=GL_COLOR_BUFFER_BIT;\r
152\r
153////////////////////////////////////////////////////////////////////////\r
154////////////////////////////////////////////////////////////////////////\r
155////////////////////////////////////////////////////////////////////////\r
156\r
157////////////////////////////////////////////////////////////////////////\r
158// Set OGL pixel format\r
159////////////////////////////////////////////////////////////////////////\r
160 \r
161#ifdef _WINDOWS\r
162BOOL bSetupPixelFormat(HDC hDC)\r
163{\r
164 int pixelformat;\r
165 static PIXELFORMATDESCRIPTOR pfd = \r
166 {\r
167 sizeof(PIXELFORMATDESCRIPTOR), // size of this pfd\r
168 1, // version number\r
169 PFD_DRAW_TO_WINDOW | // support window\r
170 PFD_SUPPORT_OPENGL | // support OpenGL\r
171 PFD_DOUBLEBUFFER, // double buffered\r
172 PFD_TYPE_RGBA, // RGBA type\r
173 16, // 16-bit color depth (adjusted later)\r
174 0, 0, 0, 0, 0, 0, // color bits ignored\r
175 0, // no alpha buffer\r
176 0, // shift bit ignored\r
177 0, // no accumulation buffer\r
178 0, 0, 0, 0, // accum bits ignored\r
179 0, // z-buffer \r
180 0,\r
181 0, // no auxiliary buffer\r
182 PFD_MAIN_PLANE, // main layer\r
183 0, // reserved\r
184 0, 0, 0 // layer masks ignored\r
185 };\r
186 \r
187 pfd.cColorBits=iColDepth; // set user color depth\r
188 pfd.cDepthBits=iZBufferDepth; // set user zbuffer (by psx mask)\r
189\r
190 if((pixelformat=ChoosePixelFormat(hDC,&pfd))==0) \r
191 {\r
192 MessageBox(NULL,"ChoosePixelFormat failed","Error",MB_OK);\r
193 return FALSE;\r
194 }\r
195\r
196 if(SetPixelFormat(hDC,pixelformat, &pfd)==FALSE)\r
197 {\r
198 MessageBox(NULL,"SetPixelFormat failed","Error",MB_OK);\r
199 return FALSE;\r
200 }\r
201\r
202 return TRUE;\r
203}\r
204#endif\r
205\r
206////////////////////////////////////////////////////////////////////////\r
207// Get extension infos (f.e. pal textures / packed pixels)\r
208////////////////////////////////////////////////////////////////////////\r
209\r
210void GetExtInfos(void) \r
211{\r
212 BOOL bPacked=FALSE; // default: no packed pixel support\r
213\r
677ea103 214 if(strstr((char *)glGetString(GL_EXTENSIONS), // packed pixels available?\r
ce879073 215 "GL_EXT_packed_pixels")) \r
216 bPacked=TRUE; // -> ok\r
217\r
218 \r
219 #ifdef _WINDOWS\r
220 iClampType=GL_CLAMP;\r
221#else\r
222 iClampType=GL_CLAMP_TO_EDGE;\r
223#endif\r
224}\r
225\r
226////////////////////////////////////////////////////////////////////////\r
227// Setup some stuff depending on user settings or in-game toggle\r
228////////////////////////////////////////////////////////////////////////\r
229\r
230void SetExtGLFuncs(void)\r
231{\r
232 //----------------------------------------------------//\r
233\r
234 SetFixes(); // update fix infos\r
235\r
236 //----------------------------------------------------//\r
237\r
238 {\r
239 if(bAdvancedBlend) bUseMultiPass=TRUE; // -> pseudo-advanced with 2 passes\r
240 else bUseMultiPass=FALSE; // -> or simple 'bright color' mode\r
241// bGLBlend=FALSE; // -> no ext blending!\r
242\r
243 glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); \r
244 }\r
245\r
246 if(bOpaquePass) // opaque mode?\r
247 {\r
248 if(dwActFixes&32) \r
249 {\r
250 TCF[0]=CP8RGBA_0;\r
251 PalTexturedColourFn=CP8RGBA; // -> init col func\r
252 }\r
253 else\r
254 {\r
255 TCF[0]=XP8RGBA_0;\r
256 PalTexturedColourFn=XP8RGBA; // -> init col func\r
257 }\r
258\r
259 TCF[1]=XP8RGBA_1;\r
260 glAlphaFuncx(GL_GREATER,0.49f);\r
261 }\r
262 else // no opaque mode?\r
263 {\r
264 TCF[0]=TCF[1]=P8RGBA;\r
265 PalTexturedColourFn=P8RGBA; // -> init col func\r
266 glAlphaFuncx(GL_NOTEQUAL,0); // --> set alpha func\r
267 }\r
268\r
269 //----------------------------------------------------//\r
270\r
271 LoadSubTexFn=LoadSubTexturePageSort; // init load tex ptr\r
272\r
273 bBlendEnable=FALSE; // init blending: off\r
274 glDisable(GL_BLEND);\r
275\r
276 SetScanTrans(); // init scan lines (if wanted)\r
277}\r
278\r
279////////////////////////////////////////////////////////////////////////\r
280// setup scan lines\r
281////////////////////////////////////////////////////////////////////////\r
282\r
283#define R_TSP 0x00,0x45,0x00,0xff\r
284#define G_TSP 0x00,0x00,0x45,0xff\r
285#define B_TSP 0x45,0x00,0x00,0xff\r
286#define O_TSP 0x45,0x45,0x45,0xff\r
287#define N_TSP 0x00,0x00,0x00,0xff\r
288\r
289GLuint gTexScanName=0;\r
290\r
291GLubyte texscan[4][16]= \r
292{\r
293{R_TSP, G_TSP, B_TSP, N_TSP},\r
294{O_TSP, N_TSP, O_TSP, N_TSP},\r
295{B_TSP, N_TSP, R_TSP, G_TSP},\r
296{O_TSP, N_TSP, O_TSP, N_TSP}\r
297};\r
298\r
299void CreateScanLines(void)\r
300{\r
301}\r
302\r
303////////////////////////////////////////////////////////////////////////\r
304// Initialize OGL\r
305////////////////////////////////////////////////////////////////////////\r
306\r
307#ifdef _WINDOWS \r
308HGLRC GLCONTEXT=NULL;\r
309#endif\r
310\r
7eadbf88 311#define MODE_RAW 0\r
312#define MODE_X11 1\r
313#define MODE_SDL 2\r
7eadbf88 314int use_fsaa = 0;\r
315\r
316EGLDisplay display;\r
317EGLConfig config;\r
318EGLContext context;\r
319EGLSurface surface;\r
320\r
321#if defined(USE_X11)\r
322#include "X11/Xlib.h"\r
323#include "X11/Xutil.h"\r
324#include "X11/Xatom.h"\r
325\r
326Window x11Window = 0;\r
327Display* x11Display = 0;\r
328long x11Screen = 0;\r
329XVisualInfo x11Visual;\r
330XVisualInfo* px11Visual = 0;\r
331Colormap x11Colormap = 0;\r
332#endif\r
333\r
334EGLint attrib_list_fsaa[] =\r
335{\r
336 EGL_SURFACE_TYPE, EGL_WINDOW_BIT,\r
337 EGL_BUFFER_SIZE, 0,\r
338 EGL_DEPTH_SIZE, 16,\r
339 EGL_SAMPLE_BUFFERS, 1,\r
340 EGL_SAMPLES, 4,\r
341 EGL_NONE\r
342};\r
343\r
344EGLint attrib_list[] =\r
345{\r
07f75e28 346// EGL_DEPTH_SIZE, 16,\r
7eadbf88 347 EGL_NONE\r
348};\r
349\r
ce879073 350bool TestEGLError(const char* pszLocation)\r
351{\r
352 /*\r
353 eglGetError returns the last error that has happened using egl,\r
354 not the status of the last called function. The user has to\r
355 check after every single egl call or at least once every frame.\r
356 */\r
357 EGLint iErr = eglGetError();\r
358 if (iErr != EGL_SUCCESS)\r
359 {\r
360 printf("%s failed (%d).\n", pszLocation, iErr);\r
7eadbf88 361 return FALSE;\r
ce879073 362 }\r
363\r
7eadbf88 364 return TRUE;\r
ce879073 365}\r
366\r
07f75e28 367static void initEGL(void)\r
368{\r
7eadbf88 369 printf ("GL init\n");\r
ce879073 370\r
7eadbf88 371 EGLint numConfigs;\r
372 EGLint majorVersion;\r
373 EGLint minorVersion;\r
374#if defined(USE_X11)\r
375 enum\r
376 {\r
377 _NET_WM_STATE_REMOVE =0,\r
378 _NET_WM_STATE_ADD = 1,\r
379 _NET_WM_STATE_TOGGLE =2\r
380 };\r
ce879073 381 \r
7eadbf88 382 Window sRootWindow;\r
383 XSetWindowAttributes sWA;\r
384 unsigned int ui32Mask;\r
385 int i32Depth;\r
386#endif\r
ce879073 387 \r
7eadbf88 388 EGLint *attribList = NULL;\r
389 if (use_fsaa)\r
390 {\r
391 printf( "GLES: Using Full Scene Antialiasing\n" );\r
392 attribList = attrib_list_fsaa;\r
393 }\r
394 else\r
395 {\r
396 attribList = attrib_list;\r
397 }\r
398\r
399#if defined(USE_X11)\r
7eadbf88 400 // Initializes the display and screen\r
401 x11Display = XOpenDisplay( ":0" );\r
402 if (!x11Display)\r
403 {\r
404 printf("GLES Error: Unable to open X display\n");\r
405 }\r
406 x11Screen = XDefaultScreen( x11Display );\r
ce879073 407 \r
7eadbf88 408 // Gets the display parameters so we can pass the same parameters to the window to be created.\r
409 sRootWindow = RootWindow(x11Display, x11Screen);\r
410 i32Depth = DefaultDepth(x11Display, x11Screen);\r
411 px11Visual = &x11Visual;\r
412 XMatchVisualInfo( x11Display, x11Screen, i32Depth, TrueColor, px11Visual);\r
413 if (!px11Visual)\r
414 {\r
415 printf("GLES Error: Unable to acquire visual\n");\r
ce879073 416 }\r
7eadbf88 417 // Colormap of the specified visual type for the display.\r
418 x11Colormap = XCreateColormap( x11Display, sRootWindow, px11Visual->visual, AllocNone );\r
419 sWA.colormap = x11Colormap;\r
420\r
421 // List of events to be handled by the application. Add to these for handling other events.\r
422 sWA.event_mask = StructureNotifyMask | ExposureMask | ButtonPressMask | ButtonReleaseMask | KeyPressMask | KeyReleaseMask;\r
ce879073 423\r
7eadbf88 424 // Display capabilities list.\r
425 ui32Mask = CWBackPixel | CWBorderPixel | CWEventMask | CWColormap;\r
ce879073 426 \r
7eadbf88 427 // Creates the X11 window\r
428 x11Window = XCreateWindow( x11Display, RootWindow(x11Display, x11Screen), 0, 0, iResX, iResY,\r
429 0, CopyFromParent, InputOutput, CopyFromParent, ui32Mask, &sWA);\r
430\r
431 // Make the window viewable and flush the output buffer.\r
432 XMapWindow(x11Display, x11Window);\r
433 XFlush(x11Display);\r
434\r
435 // Make the window fullscreen\r
436 unsigned char fullScreen = 1;\r
437 Atom wmState = XInternAtom(x11Display, "_NET_WM_STATE", False);\r
438 Atom wmFullScreen = XInternAtom(x11Display,"_NET_WM_STATE_FULLSCREEN", False);\r
439\r
440 XEvent xev;\r
441 xev.xclient.type = ClientMessage;\r
442 xev.xclient.serial = 0;\r
443 xev.xclient.send_event = True;\r
444 xev.xclient.window = x11Window;\r
445 xev.xclient.message_type = wmState;\r
446 xev.xclient.format = 32;\r
447 xev.xclient.data.l[0] = (fullScreen ? _NET_WM_STATE_ADD : _NET_WM_STATE_REMOVE);\r
448 xev.xclient.data.l[1] = wmFullScreen;\r
449 xev.xclient.data.l[2] = 0;\r
450\r
451 XSendEvent(x11Display, DefaultRootWindow(x11Display), False, SubstructureRedirectMask | SubstructureNotifyMask, &xev);\r
452\r
453 display = eglGetDisplay( (EGLNativeDisplayType)x11Display );\r
07f75e28 454#else\r
7eadbf88 455 display = eglGetDisplay( (EGLNativeDisplayType)0 );\r
07f75e28 456#endif\r
7eadbf88 457\r
458 if( display == EGL_NO_DISPLAY )\r
ce879073 459 {\r
7eadbf88 460 printf( "GLES EGL Error: GL No Display\n" );\r
ce879073 461 }\r
7eadbf88 462\r
463 if( !eglInitialize( display, &majorVersion, &minorVersion ) )\r
ce879073 464 {\r
7eadbf88 465 printf( "GLES EGL Error: eglInitialize failed\n" );\r
ce879073 466 }\r
467\r
7eadbf88 468 if( !eglChooseConfig( display, attribList, &config, 1, &numConfigs ) )\r
ce879073 469 {\r
7eadbf88 470 printf( "GLES EGL Error: eglChooseConfig failed\n" );\r
ce879073 471 }\r
472\r
7eadbf88 473 context = eglCreateContext( display, config, NULL, NULL );\r
474 if( context==0 )\r
475 {\r
476 printf( "GLES EGL Error: eglCreateContext failed\n" );\r
477 }\r
ce879073 478\r
7eadbf88 479#if defined(USE_X11)\r
7eadbf88 480 surface = eglCreateWindowSurface( display, config, (EGLNativeDisplayType)x11Window, NULL );\r
07f75e28 481#else\r
7eadbf88 482 surface = eglCreateWindowSurface( display, config, (EGLNativeDisplayType)0, NULL );\r
07f75e28 483#endif\r
7eadbf88 484\r
485 eglMakeCurrent( display, surface, surface, context );\r
486 if (!TestEGLError("eglMakeCurrent"))\r
487 printf("error eglMakeCurrent");\r
488 else\r
489 printf("GLES Window Opened\n");\r
ce879073 490}\r
ce879073 491\r
492int GLinitialize() \r
493{\r
494 //----------------------------------------------------// \r
495#ifdef _WINDOWS\r
496 HGLRC objectRC;\r
497 // init\r
498 dcGlobal = GetDC(hWWindow); // FIRST: dc/rc stuff\r
499 objectRC = wglCreateContext(dcGlobal); \r
500 GLCONTEXT=objectRC;\r
501 wglMakeCurrent(dcGlobal, objectRC);\r
502 // CheckWGLExtensions(dcGlobal);\r
503 if(bWindowMode) ReleaseDC(hWWindow,dcGlobal); // win mode: release dc again\r
504#endif\r
07f75e28 505 initEGL();\r
506\r
ce879073 507 //----------------------------------------------------// \r
508\r
509 glViewport(rRatioRect.left, // init viewport by ratio rect\r
510 iResY-(rRatioRect.top+rRatioRect.bottom),\r
511 rRatioRect.right, \r
512 rRatioRect.bottom); \r
513 \r
514 glScissor(0, 0, iResX, iResY); // init clipping (fullscreen)\r
515 glEnable(GL_SCISSOR_TEST); \r
516\r
517#ifndef OWNSCALE\r
518 glMatrixMode(GL_TEXTURE); // init psx tex sow and tow if not "ownscale"\r
519 glLoadIdentity();\r
520 glScalef(1.0f/255.99f,1.0f/255.99f,1.0f); // geforce precision hack\r
521#endif \r
522\r
523 glMatrixMode(GL_PROJECTION); // init projection with psx resolution\r
524 glLoadIdentity();\r
525 glOrtho(0,PSXDisplay.DisplayMode.x,\r
526 PSXDisplay.DisplayMode.y, 0, -1, 1);\r
527\r
528 if(iZBufferDepth) // zbuffer?\r
529 {\r
530 uiBufferBits=GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT;\r
531 glEnable(GL_DEPTH_TEST); \r
532 glDepthFunc(GL_ALWAYS);\r
533 iDepthFunc=1;\r
534 }\r
535 else // no zbuffer?\r
536 {\r
537 uiBufferBits=GL_COLOR_BUFFER_BIT;\r
538 glDisable(GL_DEPTH_TEST);\r
539 }\r
540\r
541 glClearColor(0.0f, 0.0f, 0.0f, 0.0f); // first buffer clear\r
542 glClear(uiBufferBits);\r
543\r
544 GetExtInfos(); // get ext infos\r
545 SetExtGLFuncs(); // init all kind of stuff (tex function pointers)\r
546 \r
547 glEnable(GL_ALPHA_TEST); // wanna alpha test\r
548\r
549 {\r
550 glDisable(GL_LINE_SMOOTH);\r
551 glDisable(GL_POINT_SMOOTH);\r
552 }\r
553\r
554 ubGloAlpha=127; // init some drawing vars\r
555 ubGloColAlpha=127;\r
556 TWin.UScaleFactor = 1;\r
557 TWin.VScaleFactor = 1;\r
558 bDrawMultiPass=FALSE;\r
559 bTexEnabled=FALSE;\r
560 bUsingTWin=FALSE;\r
561 \r
562 if(bDrawDither) glEnable(GL_DITHER); // dither mode\r
563 else glDisable(GL_DITHER); \r
564\r
565 glDisable(GL_FOG); // turn all (currently) unused modes off\r
566 glDisable(GL_LIGHTING); \r
567 glDisable(GL_STENCIL_TEST); \r
568 glDisable(GL_TEXTURE_2D);\r
569 glDisable(GL_CULL_FACE);\r
570\r
571 glFlush(); // we are done...\r
572 glFinish(); \r
573\r
574 CreateScanLines(); // setup scanline stuff (if wanted)\r
575\r
576 CheckTextureMemory(); // check available tex memory\r
577\r
578 if(bKeepRatio) SetAspectRatio(); // set ratio\r
579\r
580 \r
581 bIsFirstFrame = FALSE; // we have survived the first frame :)\r
582\r
583 return 0;\r
584}\r
585\r
586////////////////////////////////////////////////////////////////////////\r
587// clean up OGL stuff\r
588////////////////////////////////////////////////////////////////////////\r
589\r
590void GLcleanup() \r
591{ \r
592 CleanupTextureStore(); // bye textures\r
593\r
594#ifdef _WINDOWS \r
595 wglMakeCurrent(NULL, NULL); // bye context\r
596 if(GLCONTEXT) wglDeleteContext(GLCONTEXT);\r
597 if(!bWindowMode && dcGlobal) \r
598 ReleaseDC(hWWindow,dcGlobal);\r
599#endif\r
7eadbf88 600\r
601 eglMakeCurrent( display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT );\r
602 eglDestroySurface( display, surface );\r
603 eglDestroyContext( display, context );\r
604 eglTerminate( display );\r
605\r
606#if defined(USE_X11)\r
7eadbf88 607 if (x11Window) XDestroyWindow(x11Display, x11Window);\r
608 if (x11Colormap) XFreeColormap( x11Display, x11Colormap );\r
609 if (x11Display) XCloseDisplay(x11Display);\r
7eadbf88 610#endif\r
ce879073 611}\r
612\r
613////////////////////////////////////////////////////////////////////////\r
614////////////////////////////////////////////////////////////////////////\r
615////////////////////////////////////////////////////////////////////////\r
616\r
617////////////////////////////////////////////////////////////////////////\r
618////////////////////////////////////////////////////////////////////////\r
619////////////////////////////////////////////////////////////////////////\r
620\r
621////////////////////////////////////////////////////////////////////////\r
622// Offset stuff\r
623////////////////////////////////////////////////////////////////////////\r
624\r
625// please note: it is hardly do-able in a hw/accel plugin to get the \r
626// real psx polygon coord mapping right... the following\r
627// works not to bad with many games, though\r
628\r
629__inline BOOL CheckCoord4()\r
630{\r
631 if(lx0<0)\r
632 {\r
633 if(((lx1-lx0)>CHKMAX_X) ||\r
634 ((lx2-lx0)>CHKMAX_X)) \r
635 {\r
636 if(lx3<0)\r
637 {\r
638 if((lx1-lx3)>CHKMAX_X) return TRUE;\r
639 if((lx2-lx3)>CHKMAX_X) return TRUE;\r
640 }\r
641 }\r
642 }\r
643 if(lx1<0)\r
644 {\r
645 if((lx0-lx1)>CHKMAX_X) return TRUE;\r
646 if((lx2-lx1)>CHKMAX_X) return TRUE;\r
647 if((lx3-lx1)>CHKMAX_X) return TRUE;\r
648 }\r
649 if(lx2<0)\r
650 {\r
651 if((lx0-lx2)>CHKMAX_X) return TRUE;\r
652 if((lx1-lx2)>CHKMAX_X) return TRUE;\r
653 if((lx3-lx2)>CHKMAX_X) return TRUE;\r
654 }\r
655 if(lx3<0)\r
656 {\r
657 if(((lx1-lx3)>CHKMAX_X) ||\r
658 ((lx2-lx3)>CHKMAX_X))\r
659 {\r
660 if(lx0<0)\r
661 {\r
662 if((lx1-lx0)>CHKMAX_X) return TRUE;\r
663 if((lx2-lx0)>CHKMAX_X) return TRUE;\r
664 }\r
665 }\r
666 }\r
667 \r
668\r
669 if(ly0<0)\r
670 {\r
671 if((ly1-ly0)>CHKMAX_Y) return TRUE;\r
672 if((ly2-ly0)>CHKMAX_Y) return TRUE;\r
673 }\r
674 if(ly1<0)\r
675 {\r
676 if((ly0-ly1)>CHKMAX_Y) return TRUE;\r
677 if((ly2-ly1)>CHKMAX_Y) return TRUE;\r
678 if((ly3-ly1)>CHKMAX_Y) return TRUE;\r
679 }\r
680 if(ly2<0)\r
681 {\r
682 if((ly0-ly2)>CHKMAX_Y) return TRUE;\r
683 if((ly1-ly2)>CHKMAX_Y) return TRUE;\r
684 if((ly3-ly2)>CHKMAX_Y) return TRUE;\r
685 }\r
686 if(ly3<0)\r
687 {\r
688 if((ly1-ly3)>CHKMAX_Y) return TRUE;\r
689 if((ly2-ly3)>CHKMAX_Y) return TRUE;\r
690 }\r
691\r
692 return FALSE;\r
693}\r
694\r
695__inline BOOL CheckCoord3()\r
696{\r
697 if(lx0<0)\r
698 {\r
699 if((lx1-lx0)>CHKMAX_X) return TRUE;\r
700 if((lx2-lx0)>CHKMAX_X) return TRUE;\r
701 }\r
702 if(lx1<0)\r
703 {\r
704 if((lx0-lx1)>CHKMAX_X) return TRUE;\r
705 if((lx2-lx1)>CHKMAX_X) return TRUE;\r
706 }\r
707 if(lx2<0)\r
708 {\r
709 if((lx0-lx2)>CHKMAX_X) return TRUE;\r
710 if((lx1-lx2)>CHKMAX_X) return TRUE;\r
711 }\r
712 if(ly0<0)\r
713 {\r
714 if((ly1-ly0)>CHKMAX_Y) return TRUE;\r
715 if((ly2-ly0)>CHKMAX_Y) return TRUE;\r
716 }\r
717 if(ly1<0)\r
718 {\r
719 if((ly0-ly1)>CHKMAX_Y) return TRUE;\r
720 if((ly2-ly1)>CHKMAX_Y) return TRUE;\r
721 }\r
722 if(ly2<0)\r
723 {\r
724 if((ly0-ly2)>CHKMAX_Y) return TRUE;\r
725 if((ly1-ly2)>CHKMAX_Y) return TRUE;\r
726 }\r
727\r
728 return FALSE;\r
729}\r
730\r
731\r
732__inline BOOL CheckCoord2()\r
733{\r
734 if(lx0<0)\r
735 {\r
736 if((lx1-lx0)>CHKMAX_X) return TRUE;\r
737 }\r
738 if(lx1<0)\r
739 {\r
740 if((lx0-lx1)>CHKMAX_X) return TRUE;\r
741 }\r
742 if(ly0<0)\r
743 {\r
744 if((ly1-ly0)>CHKMAX_Y) return TRUE;\r
745 }\r
746 if(ly1<0)\r
747 {\r
748 if((ly0-ly1)>CHKMAX_Y) return TRUE;\r
749 }\r
750\r
751 return FALSE;\r
752}\r
753\r
754// Pete's way: a very easy (and hopefully fast) approach for lines\r
755// without sqrt... using a small float -> short cast trick :)\r
756\r
757#define VERTEX_OFFX 0.2f\r
758#define VERTEX_OFFY 0.2f\r
759\r
760BOOL offsetline(void) \r
761{\r
762 short x0,x1,y0,y1,dx,dy;float px,py;\r
763\r
764 if(bDisplayNotSet)\r
765 SetOGLDisplaySettings(1);\r
766\r
767 if(!(dwActFixes&16))\r
768 {\r
769 lx0=(short)(((int)lx0<<SIGNSHIFT)>>SIGNSHIFT);\r
770 lx1=(short)(((int)lx1<<SIGNSHIFT)>>SIGNSHIFT);\r
771 ly0=(short)(((int)ly0<<SIGNSHIFT)>>SIGNSHIFT);\r
772 ly1=(short)(((int)ly1<<SIGNSHIFT)>>SIGNSHIFT);\r
773\r
774 if(CheckCoord2()) return TRUE;\r
775 }\r
776\r
777 x0 = (lx0 + PSXDisplay.CumulOffset.x)+1;\r
778 x1 = (lx1 + PSXDisplay.CumulOffset.x)+1;\r
779 y0 = (ly0 + PSXDisplay.CumulOffset.y)+1;\r
780 y1 = (ly1 + PSXDisplay.CumulOffset.y)+1;\r
781 \r
782 dx=x1-x0;\r
783 dy=y1-y0;\r
784 \r
785 if(dx>=0)\r
786 {\r
787 if(dy>=0)\r
788 {\r
789 px=0.5f;\r
790 if(dx>dy) py=-0.5f;\r
791 else if(dx<dy) py= 0.5f;\r
792 else py= 0.0f;\r
793 }\r
794 else\r
795 {\r
796 py=-0.5f;\r
797 dy=-dy;\r
798 if(dx>dy) px= 0.5f;\r
799 else if(dx<dy) px=-0.5f;\r
800 else px= 0.0f;\r
801 }\r
802 }\r
803 else\r
804 {\r
805 if(dy>=0)\r
806 {\r
807 py=0.5f;\r
808 dx=-dx;\r
809 if(dx>dy) px=-0.5f;\r
810 else if(dx<dy) px= 0.5f;\r
811 else px= 0.0f;\r
812 }\r
813 else\r
814 {\r
815 px=-0.5f;\r
816 if(dx>dy) py=-0.5f;\r
817 else if(dx<dy) py= 0.5f;\r
818 else py= 0.0f;\r
819 }\r
820 } \r
821 \r
822 vertex[0].x=(short)((float)x0-px);\r
823 vertex[3].x=(short)((float)x0+py);\r
824 \r
825 vertex[0].y=(short)((float)y0-py);\r
826 vertex[3].y=(short)((float)y0-px);\r
827 \r
828 vertex[1].x=(short)((float)x1-py);\r
829 vertex[2].x=(short)((float)x1+px);\r
830\r
831 vertex[1].y=(short)((float)y1+px);\r
832 vertex[2].y=(short)((float)y1+py);\r
833\r
834 if(vertex[0].x==vertex[3].x && // ortho rect? done\r
835 vertex[1].x==vertex[2].x &&\r
836 vertex[0].y==vertex[1].y &&\r
837 vertex[2].y==vertex[3].y) return FALSE;\r
838 if(vertex[0].x==vertex[1].x &&\r
839 vertex[2].x==vertex[3].x &&\r
840 vertex[0].y==vertex[3].y &&\r
841 vertex[1].y==vertex[2].y) return FALSE;\r
842\r
843 vertex[0].x-=VERTEX_OFFX; // otherwise a small offset\r
844 vertex[0].y-=VERTEX_OFFY; // to get better accuracy\r
845 vertex[1].x-=VERTEX_OFFX;\r
846 vertex[1].y-=VERTEX_OFFY;\r
847 vertex[2].x-=VERTEX_OFFX;\r
848 vertex[2].y-=VERTEX_OFFY;\r
849 vertex[3].x-=VERTEX_OFFX;\r
850 vertex[3].y-=VERTEX_OFFY;\r
851\r
852 return FALSE;\r
853}\r
854\r
855///////////////////////////////////////////////////////// \r
856\r
857BOOL offset2(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 ly0=(short)(((int)ly0<<SIGNSHIFT)>>SIGNSHIFT);\r
867 ly1=(short)(((int)ly1<<SIGNSHIFT)>>SIGNSHIFT);\r
868\r
869 if(CheckCoord2()) return TRUE;\r
870 }\r
871\r
872 vertex[0].x=lx0+PSXDisplay.CumulOffset.x;\r
873 vertex[1].x=lx1+PSXDisplay.CumulOffset.x;\r
874 vertex[0].y=ly0+PSXDisplay.CumulOffset.y;\r
875 vertex[1].y=ly1+PSXDisplay.CumulOffset.y;\r
876\r
877 return FALSE;\r
878}\r
879\r
880///////////////////////////////////////////////////////// \r
881\r
882BOOL offset3(void)\r
883{\r
884 if(bDisplayNotSet)\r
885 SetOGLDisplaySettings(1);\r
886\r
887 if(!(dwActFixes&16))\r
888 {\r
889 lx0=(short)(((int)lx0<<SIGNSHIFT)>>SIGNSHIFT);\r
890 lx1=(short)(((int)lx1<<SIGNSHIFT)>>SIGNSHIFT);\r
891 lx2=(short)(((int)lx2<<SIGNSHIFT)>>SIGNSHIFT);\r
892 ly0=(short)(((int)ly0<<SIGNSHIFT)>>SIGNSHIFT);\r
893 ly1=(short)(((int)ly1<<SIGNSHIFT)>>SIGNSHIFT);\r
894 ly2=(short)(((int)ly2<<SIGNSHIFT)>>SIGNSHIFT);\r
895\r
896 if(CheckCoord3()) return TRUE;\r
897 }\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[0].y=ly0+PSXDisplay.CumulOffset.y;\r
903 vertex[1].y=ly1+PSXDisplay.CumulOffset.y;\r
904 vertex[2].y=ly2+PSXDisplay.CumulOffset.y;\r
905\r
906 return FALSE;\r
907}\r
908\r
909///////////////////////////////////////////////////////// \r
910\r
911BOOL offset4(void)\r
912{\r
913 if(bDisplayNotSet)\r
914 SetOGLDisplaySettings(1);\r
915\r
916 if(!(dwActFixes&16))\r
917 {\r
918 lx0=(short)(((int)lx0<<SIGNSHIFT)>>SIGNSHIFT);\r
919 lx1=(short)(((int)lx1<<SIGNSHIFT)>>SIGNSHIFT);\r
920 lx2=(short)(((int)lx2<<SIGNSHIFT)>>SIGNSHIFT);\r
921 lx3=(short)(((int)lx3<<SIGNSHIFT)>>SIGNSHIFT);\r
922 ly0=(short)(((int)ly0<<SIGNSHIFT)>>SIGNSHIFT);\r
923 ly1=(short)(((int)ly1<<SIGNSHIFT)>>SIGNSHIFT);\r
924 ly2=(short)(((int)ly2<<SIGNSHIFT)>>SIGNSHIFT);\r
925 ly3=(short)(((int)ly3<<SIGNSHIFT)>>SIGNSHIFT);\r
926\r
927 if(CheckCoord4()) return TRUE;\r
928 }\r
929\r
930 vertex[0].x=lx0+PSXDisplay.CumulOffset.x;\r
931 vertex[1].x=lx1+PSXDisplay.CumulOffset.x;\r
932 vertex[2].x=lx2+PSXDisplay.CumulOffset.x;\r
933 vertex[3].x=lx3+PSXDisplay.CumulOffset.x;\r
934 vertex[0].y=ly0+PSXDisplay.CumulOffset.y;\r
935 vertex[1].y=ly1+PSXDisplay.CumulOffset.y;\r
936 vertex[2].y=ly2+PSXDisplay.CumulOffset.y;\r
937 vertex[3].y=ly3+PSXDisplay.CumulOffset.y;\r
938\r
939 return FALSE;\r
940}\r
941\r
942///////////////////////////////////////////////////////// \r
943\r
944void offsetST(void)\r
945{\r
946 if(bDisplayNotSet)\r
947 SetOGLDisplaySettings(1);\r
948\r
949 if(!(dwActFixes&16))\r
950 {\r
951 lx0=(short)(((int)lx0<<SIGNSHIFT)>>SIGNSHIFT);\r
952 ly0=(short)(((int)ly0<<SIGNSHIFT)>>SIGNSHIFT);\r
953\r
954 if(lx0<-512 && PSXDisplay.DrawOffset.x<=-512)\r
955 lx0+=2048;\r
956\r
957 if(ly0<-512 && PSXDisplay.DrawOffset.y<=-512)\r
958 ly0+=2048;\r
959 }\r
960\r
961 ly1 = ly0;\r
962 ly2 = ly3 = ly0+sprtH;\r
963 lx3 = lx0;\r
964 lx1 = lx2 = lx0+sprtW;\r
965\r
966 vertex[0].x=lx0+PSXDisplay.CumulOffset.x;\r
967 vertex[1].x=lx1+PSXDisplay.CumulOffset.x;\r
968 vertex[2].x=lx2+PSXDisplay.CumulOffset.x;\r
969 vertex[3].x=lx3+PSXDisplay.CumulOffset.x;\r
970 vertex[0].y=ly0+PSXDisplay.CumulOffset.y;\r
971 vertex[1].y=ly1+PSXDisplay.CumulOffset.y;\r
972 vertex[2].y=ly2+PSXDisplay.CumulOffset.y;\r
973 vertex[3].y=ly3+PSXDisplay.CumulOffset.y;\r
974}\r
975\r
976///////////////////////////////////////////////////////// \r
977\r
978void offsetScreenUpload(long Position)\r
979{\r
980 if(bDisplayNotSet)\r
981 SetOGLDisplaySettings(1);\r
982\r
983 if(Position==-1)\r
984 {\r
985 long lmdx,lmdy;\r
986\r
987 lmdx=xrUploadArea.x0;\r
988 lmdy=xrUploadArea.y0;\r
989\r
990 lx0-=lmdx;\r
991 ly0-=lmdy;\r
992 lx1-=lmdx;\r
993 ly1-=lmdy;\r
994 lx2-=lmdx;\r
995 ly2-=lmdy;\r
996 lx3-=lmdx;\r
997 ly3-=lmdy;\r
998 }\r
999 else\r
1000 if(Position)\r
1001 {\r
1002 lx0-=PSXDisplay.DisplayPosition.x;\r
1003 ly0-=PSXDisplay.DisplayPosition.y;\r
1004 lx1-=PSXDisplay.DisplayPosition.x;\r
1005 ly1-=PSXDisplay.DisplayPosition.y;\r
1006 lx2-=PSXDisplay.DisplayPosition.x;\r
1007 ly2-=PSXDisplay.DisplayPosition.y;\r
1008 lx3-=PSXDisplay.DisplayPosition.x;\r
1009 ly3-=PSXDisplay.DisplayPosition.y;\r
1010 }\r
1011 else\r
1012 {\r
1013 lx0-=PreviousPSXDisplay.DisplayPosition.x;\r
1014 ly0-=PreviousPSXDisplay.DisplayPosition.y;\r
1015 lx1-=PreviousPSXDisplay.DisplayPosition.x;\r
1016 ly1-=PreviousPSXDisplay.DisplayPosition.y;\r
1017 lx2-=PreviousPSXDisplay.DisplayPosition.x;\r
1018 ly2-=PreviousPSXDisplay.DisplayPosition.y;\r
1019 lx3-=PreviousPSXDisplay.DisplayPosition.x;\r
1020 ly3-=PreviousPSXDisplay.DisplayPosition.y;\r
1021 }\r
1022\r
1023 vertex[0].x=lx0 + PreviousPSXDisplay.Range.x0;\r
1024 vertex[1].x=lx1 + PreviousPSXDisplay.Range.x0;\r
1025 vertex[2].x=lx2 + PreviousPSXDisplay.Range.x0;\r
1026 vertex[3].x=lx3 + PreviousPSXDisplay.Range.x0;\r
1027 vertex[0].y=ly0 + PreviousPSXDisplay.Range.y0;\r
1028 vertex[1].y=ly1 + PreviousPSXDisplay.Range.y0;\r
1029 vertex[2].y=ly2 + PreviousPSXDisplay.Range.y0;\r
1030 vertex[3].y=ly3 + PreviousPSXDisplay.Range.y0;\r
1031\r
1032 if(iUseMask)\r
1033 {\r
1034 vertex[0].z=vertex[1].z=vertex[2].z=vertex[3].z=gl_z;\r
1035 gl_z+=0.00004f;\r
1036 }\r
1037}\r
1038 \r
1039///////////////////////////////////////////////////////// \r
1040\r
1041void offsetBlk(void)\r
1042{\r
1043 if(bDisplayNotSet)\r
1044 SetOGLDisplaySettings(1);\r
1045 \r
1046 vertex[0].x=lx0-PSXDisplay.GDrawOffset.x + PreviousPSXDisplay.Range.x0;\r
1047 vertex[1].x=lx1-PSXDisplay.GDrawOffset.x + PreviousPSXDisplay.Range.x0;\r
1048 vertex[2].x=lx2-PSXDisplay.GDrawOffset.x + PreviousPSXDisplay.Range.x0;\r
1049 vertex[3].x=lx3-PSXDisplay.GDrawOffset.x + PreviousPSXDisplay.Range.x0;\r
1050 vertex[0].y=ly0-PSXDisplay.GDrawOffset.y + PreviousPSXDisplay.Range.y0;\r
1051 vertex[1].y=ly1-PSXDisplay.GDrawOffset.y + PreviousPSXDisplay.Range.y0;\r
1052 vertex[2].y=ly2-PSXDisplay.GDrawOffset.y + PreviousPSXDisplay.Range.y0;\r
1053 vertex[3].y=ly3-PSXDisplay.GDrawOffset.y + PreviousPSXDisplay.Range.y0;\r
1054\r
1055 if(iUseMask)\r
1056 {\r
1057 vertex[0].z=vertex[1].z=vertex[2].z=vertex[3].z=gl_z;\r
1058 gl_z+=0.00004f;\r
1059 }\r
1060}\r
1061\r
1062////////////////////////////////////////////////////////////////////////\r
1063// texture sow/tow calculations\r
1064////////////////////////////////////////////////////////////////////////\r
1065\r
1066void assignTextureVRAMWrite(void)\r
1067{\r
1068#ifdef OWNSCALE\r
1069\r
1070 vertex[0].sow=0.5f/ ST_FACVRAMX;\r
1071 vertex[0].tow=0.5f/ ST_FACVRAM;\r
1072\r
1073 vertex[1].sow=(float)gl_ux[1]/ ST_FACVRAMX;\r
1074 vertex[1].tow=0.5f/ ST_FACVRAM;\r
1075\r
1076 vertex[2].sow=(float)gl_ux[2]/ ST_FACVRAMX;\r
1077 vertex[2].tow=(float)gl_vy[2]/ ST_FACVRAM;\r
1078\r
1079 vertex[3].sow=0.5f/ ST_FACVRAMX;\r
1080 vertex[3].tow=(float)gl_vy[3]/ ST_FACVRAM;\r
1081\r
1082#else\r
1083\r
1084 if(gl_ux[1]==255)\r
1085 {\r
1086 vertex[0].sow=(gl_ux[0]*255.99f)/255.0f;\r
1087 vertex[1].sow=(gl_ux[1]*255.99f)/255.0f;\r
1088 vertex[2].sow=(gl_ux[2]*255.99f)/255.0f;\r
1089 vertex[3].sow=(gl_ux[3]*255.99f)/255.0f;\r
1090 }\r
1091 else\r
1092 {\r
1093 vertex[0].sow=gl_ux[0];\r
1094 vertex[1].sow=gl_ux[1];\r
1095 vertex[2].sow=gl_ux[2];\r
1096 vertex[3].sow=gl_ux[3];\r
1097 }\r
1098\r
1099 vertex[0].tow=gl_vy[0];\r
1100 vertex[1].tow=gl_vy[1];\r
1101 vertex[2].tow=gl_vy[2];\r
1102 vertex[3].tow=gl_vy[3];\r
1103\r
1104#endif\r
1105}\r
1106\r
1107GLuint gLastTex=0;\r
1108GLuint gLastFMode=(GLuint)-1;\r
1109\r
1110///////////////////////////////////////////////////////// \r
1111\r
1112void assignTextureSprite(void)\r
1113{\r
1114 if(bUsingTWin)\r
1115 {\r
1116 vertex[0].sow=vertex[3].sow=(float)gl_ux[0]/TWin.UScaleFactor;\r
1117 vertex[1].sow=vertex[2].sow=(float)sSprite_ux2/TWin.UScaleFactor;\r
1118 vertex[0].tow=vertex[1].tow=(float)gl_vy[0]/TWin.VScaleFactor;\r
1119 vertex[2].tow=vertex[3].tow=(float)sSprite_vy2/TWin.VScaleFactor;\r
1120 gLastTex=gTexName;\r
1121 }\r
1122 else\r
1123 {\r
1124#ifdef OWNSCALE\r
1125\r
1126 vertex[0].sow=vertex[3].sow=(float)gl_ux[0] / ST_FACSPRITE;\r
1127 vertex[1].sow=vertex[2].sow=(float)sSprite_ux2 / ST_FACSPRITE;\r
1128 vertex[0].tow=vertex[1].tow=(float)gl_vy[0] / ST_FACSPRITE;\r
1129 vertex[2].tow=vertex[3].tow=(float)sSprite_vy2 / ST_FACSPRITE;\r
1130\r
1131#else\r
1132 \r
1133 vertex[0].sow=vertex[3].sow=gl_ux[0];\r
1134 vertex[1].sow=vertex[2].sow=sSprite_ux2;\r
1135 vertex[0].tow=vertex[1].tow=gl_vy[0];\r
1136 vertex[2].tow=vertex[3].tow=sSprite_vy2;\r
1137\r
1138#endif\r
1139\r
1140 if(iFilterType>2) \r
1141 {\r
1142 if(gLastTex!=gTexName || gLastFMode!=0)\r
1143 {\r
1144 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);\r
1145 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);\r
1146 gLastTex=gTexName;gLastFMode=0;\r
1147 }\r
1148 }\r
1149 }\r
1150\r
1151 if(usMirror & 0x1000) \r
1152 {\r
1153 vertex[0].sow=vertex[1].sow;\r
1154 vertex[1].sow=vertex[2].sow=vertex[3].sow;\r
1155 vertex[3].sow=vertex[0].sow;\r
1156 }\r
1157\r
1158 if(usMirror & 0x2000) \r
1159 {\r
1160 vertex[0].tow=vertex[3].tow;\r
1161 vertex[2].tow=vertex[3].tow=vertex[1].tow;\r
1162 vertex[1].tow=vertex[0].tow;\r
1163 }\r
1164\r
1165}\r
1166\r
1167///////////////////////////////////////////////////////// \r
1168\r
1169void assignTexture3(void)\r
1170{\r
1171 if(bUsingTWin)\r
1172 {\r
1173 vertex[0].sow=(float)gl_ux[0]/TWin.UScaleFactor;\r
1174 vertex[0].tow=(float)gl_vy[0]/TWin.VScaleFactor;\r
1175 vertex[1].sow=(float)gl_ux[1]/TWin.UScaleFactor;\r
1176 vertex[1].tow=(float)gl_vy[1]/TWin.VScaleFactor;\r
1177 vertex[2].sow=(float)gl_ux[2]/TWin.UScaleFactor;\r
1178 vertex[2].tow=(float)gl_vy[2]/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_FACTRI;\r
1185 vertex[0].tow=(float)gl_vy[0] / ST_FACTRI;\r
1186 vertex[1].sow=(float)gl_ux[1] / ST_FACTRI;\r
1187\r
1188 vertex[1].tow=(float)gl_vy[1] / ST_FACTRI;\r
1189 vertex[2].sow=(float)gl_ux[2] / ST_FACTRI;\r
1190 vertex[2].tow=(float)gl_vy[2] / ST_FACTRI;\r
1191#else\r
1192 vertex[0].sow=gl_ux[0];\r
1193 vertex[0].tow=gl_vy[0];\r
1194 vertex[1].sow=gl_ux[1];\r
1195 vertex[1].tow=gl_vy[1];\r
1196 vertex[2].sow=gl_ux[2];\r
1197 vertex[2].tow=gl_vy[2];\r
1198#endif\r
1199\r
1200 if(iFilterType>2) \r
1201 {\r
1202 if(gLastTex!=gTexName || gLastFMode!=1)\r
1203 {\r
1204 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);\r
1205 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);\r
1206 gLastTex=gTexName;gLastFMode=1;\r
1207 }\r
1208 }\r
1209\r
1210 if(iFilterType) \r
1211 {\r
1212 float fxmin=256.0f,fxmax=0.0f,fymin=256.0f,fymax=0.0f;int i;\r
1213 for(i=0;i<3;i++)\r
1214 {\r
1215 if(vertex[i].sow<fxmin) fxmin=vertex[i].sow;\r
1216 if(vertex[i].tow<fymin) fymin=vertex[i].tow;\r
1217 if(vertex[i].sow>fxmax) fxmax=vertex[i].sow;\r
1218 if(vertex[i].tow>fymax) fymax=vertex[i].tow; \r
1219 }\r
1220\r
1221 for(i=0;i<3;i++)\r
1222 {\r
1223 if(vertex[i].sow==fxmin) vertex[i].sow+=ST_BFFACSORT;\r
1224 if(vertex[i].sow==fxmax) vertex[i].sow-=ST_BFFACSORT;\r
1225 if(vertex[i].tow==fymin) vertex[i].tow+=ST_BFFACSORT;\r
1226 if(vertex[i].tow==fymax) vertex[i].tow-=ST_BFFACSORT;\r
1227 }\r
1228 }\r
1229 }\r
1230}\r
1231\r
1232///////////////////////////////////////////////////////// \r
1233\r
1234void assignTexture4(void)\r
1235{\r
1236 if(bUsingTWin)\r
1237 {\r
1238 vertex[0].sow=(float)gl_ux[0]/TWin.UScaleFactor;\r
1239 vertex[0].tow=(float)gl_vy[0]/TWin.VScaleFactor;\r
1240 vertex[1].sow=(float)gl_ux[1]/TWin.UScaleFactor;\r
1241 vertex[1].tow=(float)gl_vy[1]/TWin.VScaleFactor;\r
1242 vertex[2].sow=(float)gl_ux[2]/TWin.UScaleFactor;\r
1243 vertex[2].tow=(float)gl_vy[2]/TWin.VScaleFactor;\r
1244 vertex[3].sow=(float)gl_ux[3]/TWin.UScaleFactor;\r
1245 vertex[3].tow=(float)gl_vy[3]/TWin.VScaleFactor;\r
1246 gLastTex=gTexName;\r
1247 }\r
1248 else\r
1249 {\r
1250#ifdef OWNSCALE\r
1251 vertex[0].sow=(float)gl_ux[0] / ST_FAC;\r
1252 vertex[0].tow=(float)gl_vy[0] / ST_FAC;\r
1253 vertex[1].sow=(float)gl_ux[1] / ST_FAC;\r
1254 vertex[1].tow=(float)gl_vy[1] / ST_FAC;\r
1255 vertex[2].sow=(float)gl_ux[2] / ST_FAC;\r
1256 vertex[2].tow=(float)gl_vy[2] / ST_FAC;\r
1257 vertex[3].sow=(float)gl_ux[3] / ST_FAC;\r
1258 vertex[3].tow=(float)gl_vy[3] / ST_FAC;\r
1259#else\r
1260 vertex[0].sow=gl_ux[0];\r
1261 vertex[0].tow=gl_vy[0];\r
1262 vertex[1].sow=gl_ux[1];\r
1263 vertex[1].tow=gl_vy[1];\r
1264 vertex[2].sow=gl_ux[2];\r
1265 vertex[2].tow=gl_vy[2];\r
1266 vertex[3].sow=gl_ux[3];\r
1267 vertex[3].tow=gl_vy[3];\r
1268#endif\r
1269\r
1270 if(iFilterType>2) \r
1271 {\r
1272 if(gLastTex!=gTexName || gLastFMode!=1)\r
1273 {\r
1274 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);\r
1275 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);\r
1276 gLastTex=gTexName;gLastFMode=1;\r
1277 }\r
1278 }\r
1279\r
1280 if(iFilterType) \r
1281 {\r
1282 float fxmin=256.0f,fxmax=0.0f,fymin=256.0f,fymax=0.0f;int i;\r
1283 for(i=0;i<4;i++)\r
1284 {\r
1285 if(vertex[i].sow<fxmin) fxmin=vertex[i].sow;\r
1286 if(vertex[i].tow<fymin) fymin=vertex[i].tow;\r
1287 if(vertex[i].sow>fxmax) fxmax=vertex[i].sow;\r
1288 if(vertex[i].tow>fymax) fymax=vertex[i].tow; \r
1289 }\r
1290\r
1291 for(i=0;i<4;i++)\r
1292 {\r
1293 if(vertex[i].sow==fxmin) vertex[i].sow+=ST_BFFACSORT;\r
1294 if(vertex[i].sow==fxmax) vertex[i].sow-=ST_BFFACSORT;\r
1295 if(vertex[i].tow==fymin) vertex[i].tow+=ST_BFFACSORT;\r
1296 if(vertex[i].tow==fymax) vertex[i].tow-=ST_BFFACSORT;\r
1297 }\r
1298 }\r
1299 }\r
1300}\r
1301\r
1302////////////////////////////////////////////////////////////////////////\r
1303////////////////////////////////////////////////////////////////////////\r
1304////////////////////////////////////////////////////////////////////////\r
1305\r
1306////////////////////////////////////////////////////////////////////////\r
1307// render pos / buffers\r
1308////////////////////////////////////////////////////////////////////////\r
1309\r
1310#ifndef _WINDOWS\r
1311#define EqualRect(pr1,pr2) ((pr1)->left==(pr2)->left && (pr1)->top==(pr2)->top && (pr1)->right==(pr2)->right && (pr1)->bottom==(pr2)->bottom)\r
1312#endif\r
1313\r
1314////////////////////////////////////////////////////////////////////////\r
1315// SetDisplaySettings: "simply" calcs the new drawing area and updates\r
1316// the ogl clipping (scissor) \r
1317\r
1318BOOL bSetClip=FALSE;\r
1319\r
1320void SetOGLDisplaySettings(BOOL DisplaySet)\r
1321{\r
1322 static RECT rprev={0,0,0,0};\r
1323 static RECT rC ={0,0,0,0};\r
1324 static int iOldX=0;\r
1325 static int iOldY=0;\r
1326 RECT r;float XS,YS;\r
1327\r
1328 bDisplayNotSet = FALSE;\r
1329\r
1330 //----------------------------------------------------// that's a whole screen upload\r
1331 if(!DisplaySet)\r
1332 {\r
1333 RECT rX;\r
1334 PSXDisplay.GDrawOffset.x=0;\r
1335 PSXDisplay.GDrawOffset.y=0;\r
1336\r
1337 PSXDisplay.CumulOffset.x = PSXDisplay.DrawOffset.x+PreviousPSXDisplay.Range.x0;\r
1338 PSXDisplay.CumulOffset.y = PSXDisplay.DrawOffset.y+PreviousPSXDisplay.Range.y0;\r
1339\r
1340 rprev.left=rprev.left+1;\r
1341\r
1342 rX=rRatioRect;\r
1343 rX.top=iResY-(rRatioRect.top+rRatioRect.bottom);\r
1344\r
1345 if(bSetClip || !EqualRect(&rC,&rX))\r
1346 {\r
1347 rC=rX;\r
1348 glScissor(rC.left,rC.top,rC.right,rC.bottom);\r
1349 bSetClip=FALSE; \r
1350 }\r
1351 return;\r
1352 }\r
1353 //----------------------------------------------------// \r
1354\r
1355 PSXDisplay.GDrawOffset.y = PreviousPSXDisplay.DisplayPosition.y;\r
1356 PSXDisplay.GDrawOffset.x = PreviousPSXDisplay.DisplayPosition.x;\r
1357 PSXDisplay.CumulOffset.x = PSXDisplay.DrawOffset.x - PSXDisplay.GDrawOffset.x+PreviousPSXDisplay.Range.x0;\r
1358 PSXDisplay.CumulOffset.y = PSXDisplay.DrawOffset.y - PSXDisplay.GDrawOffset.y+PreviousPSXDisplay.Range.y0;\r
1359\r
1360 r.top =PSXDisplay.DrawArea.y0 - PreviousPSXDisplay.DisplayPosition.y;\r
1361 r.bottom=PSXDisplay.DrawArea.y1 - PreviousPSXDisplay.DisplayPosition.y;\r
1362\r
1363 if(r.bottom<0 || r.top>=PSXDisplay.DisplayMode.y)\r
1364 {\r
1365 r.top =PSXDisplay.DrawArea.y0 - PSXDisplay.DisplayPosition.y;\r
1366 r.bottom=PSXDisplay.DrawArea.y1 - PSXDisplay.DisplayPosition.y;\r
1367 }\r
1368\r
1369 r.left =PSXDisplay.DrawArea.x0 - PreviousPSXDisplay.DisplayPosition.x;\r
1370 r.right =PSXDisplay.DrawArea.x1 - PreviousPSXDisplay.DisplayPosition.x;\r
1371\r
1372 if(r.right<0 || r.left>=PSXDisplay.DisplayMode.x)\r
1373 {\r
1374 r.left =PSXDisplay.DrawArea.x0 - PSXDisplay.DisplayPosition.x;\r
1375 r.right =PSXDisplay.DrawArea.x1 - PSXDisplay.DisplayPosition.x;\r
1376 }\r
1377\r
1378 if(!bSetClip && EqualRect(&r,&rprev) &&\r
1379 iOldX == PSXDisplay.DisplayMode.x &&\r
1380 iOldY == PSXDisplay.DisplayMode.y)\r
1381 return;\r
1382\r
1383 rprev = r;\r
1384 iOldX = PSXDisplay.DisplayMode.x;\r
1385 iOldY = PSXDisplay.DisplayMode.y;\r
1386\r
1387 XS=(float)rRatioRect.right/(float)PSXDisplay.DisplayMode.x;\r
1388 YS=(float)rRatioRect.bottom/(float)PSXDisplay.DisplayMode.y;\r
1389\r
1390 if(PreviousPSXDisplay.Range.x0)\r
1391 {\r
1392 short s=PreviousPSXDisplay.Range.x0+PreviousPSXDisplay.Range.x1;\r
1393\r
1394 r.left+=PreviousPSXDisplay.Range.x0+1;\r
1395\r
1396 r.right+=PreviousPSXDisplay.Range.x0;\r
1397\r
1398 if(r.left>s) r.left=s;\r
1399 if(r.right>s) r.right=s;\r
1400 }\r
1401\r
1402 if(PreviousPSXDisplay.Range.y0)\r
1403 {\r
1404 short s=PreviousPSXDisplay.Range.y0+PreviousPSXDisplay.Range.y1;\r
1405\r
1406 r.top+=PreviousPSXDisplay.Range.y0+1;\r
1407 r.bottom+=PreviousPSXDisplay.Range.y0;\r
1408\r
1409 if(r.top>s) r.top=s;\r
1410 if(r.bottom>s) r.bottom=s;\r
1411 }\r
1412\r
1413 // Set the ClipArea variables to reflect the new screen,\r
1414 // offset from zero (since it is a new display buffer)\r
1415 r.left = (int)(((float)(r.left)) *XS);\r
1416 r.top = (int)(((float)(r.top)) *YS);\r
1417 r.right = (int)(((float)(r.right + 1))*XS);\r
1418 r.bottom = (int)(((float)(r.bottom + 1))*YS);\r
1419\r
1420 // Limit clip area to the screen size\r
1421 if (r.left > iResX) r.left = iResX;\r
1422 if (r.left < 0) r.left = 0;\r
1423 if (r.top > iResY) r.top = iResY;\r
1424 if (r.top < 0) r.top = 0;\r
1425 if (r.right > iResX) r.right = iResX;\r
1426 if (r.right < 0) r.right = 0;\r
1427 if (r.bottom > iResY) r.bottom = iResY;\r
1428 if (r.bottom < 0) r.bottom = 0;\r
1429\r
1430 r.right -=r.left;\r
1431 r.bottom-=r.top;\r
1432 r.top=iResY-(r.top+r.bottom);\r
1433\r
1434 r.left+=rRatioRect.left;\r
1435 r.top -=rRatioRect.top;\r
1436\r
1437 if(bSetClip || !EqualRect(&r,&rC))\r
1438 {\r
1439 glScissor(r.left,r.top,r.right,r.bottom);\r
1440 rC=r;\r
1441 bSetClip=FALSE;\r
1442 }\r
1443}\r
1444\r
1445////////////////////////////////////////////////////////////////////////\r
1446////////////////////////////////////////////////////////////////////////\r
1447////////////////////////////////////////////////////////////////////////\r
1448\r