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