pcsxr-1.9.92
[pcsx_rearmed.git] / plugins / peopsxgl / draw.c
CommitLineData
ef79bbde
P
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#include "stdafx.h"\r
20\r
21#define _IN_DRAW\r
22\r
23#include "externals.h"\r
24#include "gpu.h"\r
25#include "draw.h"\r
26#include "prim.h"\r
27#include "texture.h"\r
28#include "menu.h"\r
29\r
30////////////////////////////////////////////////////////////////////////////////////\r
31// defines\r
32\r
33#define SIGNBIT 0x800\r
34#define S_MASK 0xf000\r
35#define L_MASK 0xfffff000\r
36\r
37// ownscale: some ogl drivers have buggy texture matrix funcs, so it\r
38// is safer to calc sow/tow ourselves\r
39\r
40#ifdef OWNSCALE\r
41\r
42#define ST_FACSPRITE 255.99f\r
43#define ST_BFFACSPRITE 0.5f/256.0f\r
44#define ST_BFFACSPRITESORT 0.333f/256.0f\r
45\r
46#define ST_OFFSET 0.5f/256.0f;\r
47\r
48#define ST_FAC 255.99f\r
49#define ST_BFFAC 0.5f/256.0f\r
50#define ST_BFFACSORT 0.333f/256.0f\r
51\r
52#define ST_FACTRI 255.99f\r
53#define ST_BFFACTRI 0.5f/256.0f\r
54#define ST_BFFACTRISORT 0.333f/256.0f\r
55\r
56#define ST_FACVRAMX 255.0f\r
57#define ST_FACVRAM 256.0f\r
58\r
59///////////////////////////////////////////////////////////////\r
60\r
61#else\r
62\r
63#define ST_BFFACSPRITE 0.5f\r
64#define ST_BFFACSPRITESORT 0.333f\r
65\r
66#define ST_BFFAC 0.5f\r
67#define ST_BFFACSORT 0.333f\r
68\r
69#define ST_BFFACTRI 0.5f\r
70#define ST_BFFACTRISORT 0.333f\r
71\r
72#define ST_OFFSET 0.5f;\r
73 \r
74#endif\r
75\r
76////////////////////////////////////////////////////////////////////////////////////\r
77// draw globals; most will be initialized again later (by config or checks) \r
78\r
79BOOL bIsFirstFrame=TRUE;\r
80\r
81// resolution/ratio vars\r
82\r
83int iResX;\r
84int iResY;\r
85BOOL bKeepRatio=FALSE;\r
86RECT rRatioRect;\r
87\r
88// psx mask related vars\r
89\r
90BOOL bCheckMask=FALSE;\r
91int iUseMask=0;\r
92int iSetMask=0;\r
93unsigned short sSetMask=0;\r
94uint32_t lSetMask=0;\r
95\r
96// drawing/coord vars\r
97\r
98OGLVertex vertex[4];\r
99GLubyte gl_ux[8];\r
100GLubyte gl_vy[8];\r
101short sprtY,sprtX,sprtH,sprtW;\r
102\r
103// drawing options\r
104\r
105BOOL bOpaquePass;\r
106BOOL bAdvancedBlend;\r
107BOOL bUseLines;\r
108BOOL bUseAntiAlias;\r
109int iTexQuality;\r
110int iUsePalTextures=1;\r
111BOOL bSnapShot=FALSE;\r
112BOOL bSmallAlpha=FALSE;\r
113int iShowFPS=0;\r
114\r
115// OGL extension support\r
116\r
117int iForceVSync=-1;\r
118int iUseExts=0;\r
119BOOL bGLExt;\r
120BOOL bGLFastMovie=FALSE;\r
121BOOL bGLSoft;\r
122BOOL bGLBlend;\r
123PFNGLBLENDEQU glBlendEquationEXTEx=NULL;\r
124PFNGLCOLORTABLEEXT glColorTableEXTEx=NULL;\r
125\r
126// gfx card buffer infos\r
127\r
128int iDepthFunc=0;\r
129int iZBufferDepth=0;\r
130GLbitfield uiBufferBits=GL_COLOR_BUFFER_BIT;\r
131\r
132////////////////////////////////////////////////////////////////////////\r
133// Get extension infos (f.e. pal textures / packed pixels)\r
134////////////////////////////////////////////////////////////////////////\r
135\r
136void GetExtInfos(void) \r
137{\r
138 BOOL bPacked=FALSE; // default: no packed pixel support\r
139\r
140 bGLExt=FALSE; // default: no extensions\r
141 bGLFastMovie=FALSE;\r
142\r
143 if(strstr((char *)glGetString(GL_EXTENSIONS), // packed pixels available?\r
144 "GL_EXT_packed_pixels")) \r
145 bPacked=TRUE; // -> ok\r
146\r
147 if(bPacked && bUse15bitMdec) // packed available and 15bit mdec wanted?\r
148 bGLFastMovie=TRUE; // -> ok\r
149\r
150 if(bPacked && (iTexQuality==1 || iTexQuality==2)) // packed available and 16 bit texture format?\r
151 {\r
152 bGLFastMovie=TRUE; // -> ok\r
153 bGLExt=TRUE;\r
154 }\r
155\r
156 if(iUseExts && // extension support wanted?\r
157 (strstr((char *)glGetString(GL_EXTENSIONS),\r
158 "GL_EXT_texture_edge_clamp") ||\r
159 strstr((char *)glGetString(GL_EXTENSIONS), // -> check clamp support, if yes: use it\r
160 "GL_SGIS_texture_edge_clamp")))\r
161 iClampType=GL_TO_EDGE_CLAMP;\r
162 else iClampType=GL_CLAMP;\r
163\r
164 glColorTableEXTEx=(PFNGLCOLORTABLEEXT)NULL; // init ogl palette func pointer\r
165\r
166#ifndef __sun\r
167 if(iGPUHeight!=1024 && // no pal textures in ZN mode (height=1024)! \r
168 strstr((char *)glGetString(GL_EXTENSIONS), // otherwise: check ogl support\r
169 "GL_EXT_paletted_texture"))\r
170 {\r
171 iUsePalTextures=1; // -> wow, supported, get func pointer\r
172\r
173 glColorTableEXTEx=(PFNGLCOLORTABLEEXT)glXGetProcAddress("glColorTableEXT");\r
174\r
175 if(glColorTableEXTEx==NULL) iUsePalTextures=0; // -> ha, cheater... no func, no support\r
176 }\r
177 else iUsePalTextures=0;\r
178#else\r
179 iUsePalTextures=0;\r
180#endif\r
181}\r
182\r
183////////////////////////////////////////////////////////////////////////\r
184// Setup some stuff depending on user settings or in-game toggle\r
185////////////////////////////////////////////////////////////////////////\r
186\r
187void SetExtGLFuncs(void)\r
188{\r
189 //----------------------------------------------------//\r
190\r
191 SetFixes(); // update fix infos\r
192\r
193 //----------------------------------------------------//\r
194\r
195 if(iUseExts && !(dwActFixes&1024) && // extensions wanted? and not turned off by game fix?\r
196 strstr((char *)glGetString(GL_EXTENSIONS), // and blend_subtract available?\r
197 "GL_EXT_blend_subtract"))\r
198 { // -> get ogl blend function pointer\r
199 glBlendEquationEXTEx=(PFNGLBLENDEQU)glXGetProcAddress("glBlendEquationEXT"); \r
200 }\r
201 else // no subtract blending?\r
202 {\r
203 if(glBlendEquationEXTEx) // -> change to additive blending (if subract was active)\r
204 glBlendEquationEXTEx(FUNC_ADD_EXT);\r
205 glBlendEquationEXTEx=(PFNGLBLENDEQU)NULL; // -> no more blend function pointer\r
206 }\r
207\r
208 //----------------------------------------------------//\r
209\r
210 if(iUseExts && bAdvancedBlend && // advanced blending wanted ?\r
211 strstr((char *)glGetString(GL_EXTENSIONS), // and extension avail?\r
212 "GL_EXT_texture_env_combine"))\r
213 {\r
214 bUseMultiPass=FALSE;bGLBlend=TRUE; // -> no need for 2 passes, perfect\r
215\r
216 glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, COMBINE_EXT); \r
217 glTexEnvf(GL_TEXTURE_ENV, COMBINE_RGB_EXT, GL_MODULATE); \r
218 glTexEnvf(GL_TEXTURE_ENV, COMBINE_ALPHA_EXT, GL_MODULATE); \r
219 glTexEnvf(GL_TEXTURE_ENV, RGB_SCALE_EXT, 2.0f); \r
220 }\r
221 else // no advanced blending wanted/available:\r
222 {\r
223 if(bAdvancedBlend) bUseMultiPass=TRUE; // -> pseudo-advanced with 2 passes\r
224 else bUseMultiPass=FALSE; // -> or simple 'bright color' mode\r
225 bGLBlend=FALSE; // -> no ext blending!\r
226\r
227 glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); \r
228 }\r
229\r
230 //----------------------------------------------------//\r
231 // init standard tex quality 0-2, and big alpha mode 3\r
232\r
233 if(!(dwActFixes&0x4000) && iFilterType && iTexQuality>=3) \r
234 bSmallAlpha=TRUE; \r
235 else bSmallAlpha=FALSE;\r
236\r
237 if(bOpaquePass) // opaque mode?\r
238 {\r
239 if(dwActFixes&32) \r
240 {\r
241 TCF[0]=CP8RGBA_0;\r
242 PalTexturedColourFn=CP8RGBA; // -> init col func\r
243 }\r
244 else\r
245 {\r
246 TCF[0]=XP8RGBA_0;\r
247 PalTexturedColourFn=XP8RGBA; // -> init col func\r
248 }\r
249\r
250 TCF[1]=XP8RGBA_1;\r
251 glAlphaFunc(GL_GREATER,0.49f);\r
252 }\r
253 else // no opaque mode?\r
254 {\r
255 TCF[0]=TCF[1]=P8RGBA;\r
256 PalTexturedColourFn=P8RGBA; // -> init col func\r
257 glAlphaFunc(GL_NOTEQUAL,0); // --> set alpha func\r
258 }\r
259\r
260 //----------------------------------------------------//\r
261\r
262 LoadSubTexFn=LoadSubTexturePageSort; // init load tex ptr\r
263\r
264 giWantedFMT=GL_RGBA; // init ogl tex format\r
265\r
266 switch(iTexQuality) // -> quality:\r
267 {\r
268 //--------------------------------------------------// \r
269 case 0: // -> don't care\r
270 giWantedRGBA=4;\r
271 giWantedTYPE=GL_UNSIGNED_BYTE;\r
272 break;\r
273 //--------------------------------------------------// \r
274 case 1: // -> R4G4B4A4\r
275 if(bGLExt)\r
276 {\r
277 giWantedRGBA=GL_RGBA4;\r
278 giWantedTYPE=GL_UNSIGNED_SHORT_4_4_4_4_EXT;\r
279 LoadSubTexFn=LoadPackedSubTexturePageSort;\r
280 if(bOpaquePass) \r
281 {\r
282 if(dwActFixes&32) PTCF[0]=CP4RGBA_0;\r
283 else PTCF[0]=XP4RGBA_0;\r
284 PTCF[1]=XP4RGBA_1;\r
285 }\r
286 else \r
287 {\r
288 PTCF[0]=PTCF[1]=P4RGBA;\r
289 }\r
290 }\r
291 else\r
292 {\r
293 giWantedRGBA=GL_RGBA4;\r
294 giWantedTYPE=GL_UNSIGNED_BYTE;\r
295 }\r
296 break;\r
297 //--------------------------------------------------// \r
298 case 2: // -> R5B5G5A1\r
299 if(bGLExt)\r
300 {\r
301 giWantedRGBA=GL_RGB5_A1;\r
302 giWantedTYPE=GL_UNSIGNED_SHORT_5_5_5_1_EXT;\r
303 LoadSubTexFn=LoadPackedSubTexturePageSort;\r
304 if(bOpaquePass) \r
305 {\r
306 if(dwActFixes&32) PTCF[0]=CP5RGBA_0;\r
307 else PTCF[0]=XP5RGBA_0;\r
308 PTCF[1]=XP5RGBA_1;\r
309 }\r
310 else \r
311 {\r
312 PTCF[0]=PTCF[1]=P5RGBA;\r
313 }\r
314 }\r
315 else\r
316 {\r
317 giWantedRGBA=GL_RGB5_A1;giWantedTYPE=GL_UNSIGNED_BYTE;\r
318 }\r
319 break;\r
320 //--------------------------------------------------// \r
321 case 3: // -> R8G8B8A8\r
322 giWantedRGBA=GL_RGBA8;\r
323 giWantedTYPE=GL_UNSIGNED_BYTE;\r
324\r
325 if(bSmallAlpha)\r
326 {\r
327 if(bOpaquePass) // opaque mode?\r
328 {\r
329 if(dwActFixes&32) {TCF[0]=CP8RGBAEx_0;PalTexturedColourFn=CP8RGBAEx;}\r
330 else {TCF[0]=XP8RGBAEx_0;PalTexturedColourFn=XP8RGBAEx;}\r
331 TCF[1]=XP8RGBAEx_1;\r
332 }\r
333 }\r
334\r
335 break;\r
336 //--------------------------------------------------// \r
337 case 4: // -> R8G8B8A8\r
338 giWantedRGBA = GL_RGBA8;\r
339 giWantedTYPE = GL_UNSIGNED_BYTE;\r
340\r
341 if(strstr((char *)glGetString(GL_EXTENSIONS), // and extension avail?\r
342 "GL_EXT_bgra"))\r
343 {\r
344 giWantedFMT = GL_BGRA_EXT;\r
345\r
346 if(bOpaquePass) // opaque mode?\r
347 {\r
348 if(bSmallAlpha)\r
349 {\r
350 if(dwActFixes&32) {TCF[0]=CP8BGRAEx_0;PalTexturedColourFn=CP8RGBAEx;}\r
351 else {TCF[0]=XP8BGRAEx_0;PalTexturedColourFn=XP8RGBAEx;}\r
352 TCF[1]=XP8BGRAEx_1;\r
353 }\r
354 else\r
355 {\r
356 if(dwActFixes&32) {TCF[0]=CP8BGRA_0;PalTexturedColourFn=CP8RGBA;}\r
357 else {TCF[0]=XP8BGRA_0;PalTexturedColourFn=XP8RGBA;}\r
358 TCF[1]=XP8BGRA_1;\r
359 }\r
360 }\r
361 else // no opaque mode?\r
362 {\r
363 TCF[0]=TCF[1]=P8BGRA; // -> init col func\r
364 }\r
365 }\r
366 else\r
367 {\r
368 iTexQuality=3;\r
369 if(bSmallAlpha)\r
370 {\r
371 if(bOpaquePass) // opaque mode?\r
372 {\r
373 if(dwActFixes&32) {TCF[0]=CP8RGBAEx_0;PalTexturedColourFn=CP8RGBAEx;}\r
374 else {TCF[0]=XP8RGBAEx_0;PalTexturedColourFn=XP8RGBAEx;}\r
375 TCF[1]=XP8RGBAEx_1;\r
376 }\r
377 }\r
378 }\r
379\r
380 break;\r
381 //--------------------------------------------------// \r
382 }\r
383\r
384 bBlendEnable=FALSE; // init blending: off\r
385 glDisable(GL_BLEND);\r
386\r
387 SetScanTrans(); // init scan lines (if wanted)\r
388}\r
389\r
390////////////////////////////////////////////////////////////////////////\r
391// setup scan lines\r
392////////////////////////////////////////////////////////////////////////\r
393\r
394#define R_TSP 0x00,0x45,0x00,0xff\r
395#define G_TSP 0x00,0x00,0x45,0xff\r
396#define B_TSP 0x45,0x00,0x00,0xff\r
397#define O_TSP 0x45,0x45,0x45,0xff\r
398#define N_TSP 0x00,0x00,0x00,0xff\r
399\r
400GLuint gTexScanName=0;\r
401\r
402GLubyte texscan[4][16]= \r
403{\r
404{R_TSP, G_TSP, B_TSP, N_TSP},\r
405{O_TSP, N_TSP, O_TSP, N_TSP},\r
406{B_TSP, N_TSP, R_TSP, G_TSP},\r
407{O_TSP, N_TSP, O_TSP, N_TSP}\r
408};\r
409\r
410void CreateScanLines(void)\r
411{\r
412 if(iUseScanLines)\r
413 {\r
414 int y;\r
415 if(iScanBlend<0) // special scan mask mode\r
416 {\r
417 glGenTextures(1, &gTexScanName);\r
418 glBindTexture(GL_TEXTURE_2D, gTexScanName);\r
419\r
420 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);\r
421 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);\r
422 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);\r
423 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);\r
424 glTexImage2D(GL_TEXTURE_2D, 0, 4, 4, 4, 0,GL_RGBA, GL_UNSIGNED_BYTE, texscan);\r
425 }\r
426 else // otherwise simple lines in a display list\r
427 {\r
428 uiScanLine=glGenLists(1);\r
429 glNewList(uiScanLine,GL_COMPILE);\r
430\r
431 for(y=0;y<iResY;y+=2)\r
432 {\r
433 glBegin(GL_QUADS);\r
434 glVertex2f(0,y);\r
435 glVertex2f(iResX,y);\r
436 glVertex2f(iResX,y+1);\r
437 glVertex2f(0,y+1);\r
438 glEnd();\r
439 }\r
440 glEndList();\r
441 }\r
442 }\r
443}\r
444\r
445////////////////////////////////////////////////////////////////////////\r
446// Initialize OGL\r
447////////////////////////////////////////////////////////////////////////\r
448\r
449int GLinitialize() \r
450{\r
451 glViewport(rRatioRect.left, // init viewport by ratio rect\r
452 iResY-(rRatioRect.top+rRatioRect.bottom),\r
453 rRatioRect.right, \r
454 rRatioRect.bottom); \r
455 \r
456 glScissor(0, 0, iResX, iResY); // init clipping (fullscreen)\r
457 glEnable(GL_SCISSOR_TEST); \r
458\r
459#ifndef OWNSCALE\r
460 glMatrixMode(GL_TEXTURE); // init psx tex sow and tow if not "ownscale"\r
461 glLoadIdentity();\r
462 glScalef(1.0f/255.99f,1.0f/255.99f,1.0f); // geforce precision hack\r
463#endif \r
464\r
465 glMatrixMode(GL_PROJECTION); // init projection with psx resolution\r
466 glLoadIdentity();\r
467 glOrtho(0,PSXDisplay.DisplayMode.x,\r
468 PSXDisplay.DisplayMode.y, 0, -1, 1);\r
469\r
470 if(iZBufferDepth) // zbuffer?\r
471 {\r
472 uiBufferBits=GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT;\r
473 glEnable(GL_DEPTH_TEST); \r
474 glDepthFunc(GL_ALWAYS);\r
475 iDepthFunc=1;\r
476 }\r
477 else // no zbuffer?\r
478 {\r
479 uiBufferBits=GL_COLOR_BUFFER_BIT;\r
480 glDisable(GL_DEPTH_TEST);\r
481 }\r
482\r
483 glClearColor(0.0f, 0.0f, 0.0f, 0.0f); // first buffer clear\r
484 glClear(uiBufferBits);\r
485\r
486 if(bUseLines) // funny lines \r
487 {\r
488 glPolygonMode(GL_FRONT, GL_LINE); \r
489 glPolygonMode(GL_BACK, GL_LINE); \r
490 }\r
491 else // or the real filled thing\r
492 {\r
493 glPolygonMode(GL_FRONT, GL_FILL);\r
494 glPolygonMode(GL_BACK, GL_FILL);\r
495 }\r
496\r
497 MakeDisplayLists(); // lists for menu/opaque\r
498 GetExtInfos(); // get ext infos\r
499 SetExtGLFuncs(); // init all kind of stuff (tex function pointers)\r
500 \r
501 glEnable(GL_ALPHA_TEST); // wanna alpha test\r
502\r
503 if(!bUseAntiAlias) // no anti-alias (default)\r
504 {\r
505 glDisable(GL_LINE_SMOOTH);\r
506 glDisable(GL_POLYGON_SMOOTH);\r
507 glDisable(GL_POINT_SMOOTH);\r
508 }\r
509 else // wanna try it? glitches galore...\r
510 { \r
511 glHint(GL_PERSPECTIVE_CORRECTION_HINT,GL_NICEST);\r
512 glEnable(GL_LINE_SMOOTH);\r
513 glEnable(GL_POLYGON_SMOOTH);\r
514 glEnable(GL_POINT_SMOOTH);\r
515 glHint(GL_LINE_SMOOTH_HINT,GL_NICEST);\r
516 glHint(GL_POINT_SMOOTH_HINT,GL_NICEST);\r
517 glHint(GL_POLYGON_SMOOTH_HINT,GL_NICEST);\r
518 }\r
519\r
520 ubGloAlpha=127; // init some drawing vars\r
521 ubGloColAlpha=127;\r
522 TWin.UScaleFactor = 1;\r
523 TWin.VScaleFactor = 1;\r
524 bDrawMultiPass=FALSE;\r
525 bTexEnabled=FALSE;\r
526 bUsingTWin=FALSE;\r
527 \r
528 if(bDrawDither) glEnable(GL_DITHER); // dither mode\r
529 else glDisable(GL_DITHER); \r
530\r
531 glDisable(GL_FOG); // turn all (currently) unused modes off\r
532 glDisable(GL_LIGHTING); \r
533 glDisable(GL_LOGIC_OP);\r
534 glDisable(GL_STENCIL_TEST); \r
535 glDisable(GL_TEXTURE_1D);\r
536 glDisable(GL_TEXTURE_2D);\r
537 glDisable(GL_CULL_FACE);\r
538\r
539 glPixelTransferi(GL_RED_SCALE, 1); // to be sure:\r
540 glPixelTransferi(GL_RED_BIAS, 0); // init more OGL vals\r
541 glPixelTransferi(GL_GREEN_SCALE, 1);\r
542 glPixelTransferi(GL_GREEN_BIAS, 0);\r
543 glPixelTransferi(GL_BLUE_SCALE, 1);\r
544 glPixelTransferi(GL_BLUE_BIAS, 0);\r
545 glPixelTransferi(GL_ALPHA_SCALE, 1);\r
546 glPixelTransferi(GL_ALPHA_BIAS, 0); \r
547\r
548 printf(glGetString(GL_VENDOR)); // linux: tell user what is getting used\r
549 printf("\n");\r
550 printf(glGetString(GL_RENDERER));\r
551 printf("\n");\r
552\r
553 glFlush(); // we are done...\r
554 glFinish(); \r
555\r
556 CreateScanLines(); // setup scanline stuff (if wanted)\r
557\r
558 CheckTextureMemory(); // check available tex memory\r
559\r
560 if(bKeepRatio) SetAspectRatio(); // set ratio\r
561\r
562 if(iShowFPS) // user wants FPS display on startup?\r
563 {\r
564 ulKeybits|=KEY_SHOWFPS; // -> ok, turn display on\r
565 szDispBuf[0]=0;\r
566 BuildDispMenu(0);\r
567 }\r
568 \r
569 bIsFirstFrame = FALSE; // we have survived the first frame :)\r
570\r
571 return 0;\r
572}\r
573\r
574////////////////////////////////////////////////////////////////////////\r
575// clean up OGL stuff\r
576////////////////////////////////////////////////////////////////////////\r
577\r
578void GLcleanup() \r
579{ \r
580 KillDisplayLists(); // bye display lists\r
581\r
582 if(iUseScanLines) // scanlines used?\r
583 {\r
584 if(iScanBlend<0)\r
585 {\r
586 if(gTexScanName!=0) // some scanline tex?\r
587 glDeleteTextures(1, &gTexScanName); // -> delete it\r
588 gTexScanName=0;\r
589 }\r
590 else glDeleteLists(uiScanLine,1); // otherwise del scanline display list\r
591 }\r
592\r
593 CleanupTextureStore(); // bye textures\r
594}\r
595\r
596////////////////////////////////////////////////////////////////////////\r
597////////////////////////////////////////////////////////////////////////\r
598////////////////////////////////////////////////////////////////////////\r
599\r
600////////////////////////////////////////////////////////////////////////\r
601////////////////////////////////////////////////////////////////////////\r
602////////////////////////////////////////////////////////////////////////\r
603\r
604////////////////////////////////////////////////////////////////////////\r
605// Offset stuff\r
606////////////////////////////////////////////////////////////////////////\r
607\r
608// please note: it is hardly do-able in a hw/accel plugin to get the \r
609// real psx polygon coord mapping right... the following\r
610// works not to bad with many games, though\r
611\r
612__inline BOOL CheckCoord4()\r
613{\r
614 if(lx0<0)\r
615 {\r
616 if(((lx1-lx0)>CHKMAX_X) ||\r
617 ((lx2-lx0)>CHKMAX_X)) \r
618 {\r
619 if(lx3<0)\r
620 {\r
621 if((lx1-lx3)>CHKMAX_X) return TRUE;\r
622 if((lx2-lx3)>CHKMAX_X) return TRUE;\r
623 }\r
624 }\r
625 }\r
626 if(lx1<0)\r
627 {\r
628 if((lx0-lx1)>CHKMAX_X) return TRUE;\r
629 if((lx2-lx1)>CHKMAX_X) return TRUE;\r
630 if((lx3-lx1)>CHKMAX_X) return TRUE;\r
631 }\r
632 if(lx2<0)\r
633 {\r
634 if((lx0-lx2)>CHKMAX_X) return TRUE;\r
635 if((lx1-lx2)>CHKMAX_X) return TRUE;\r
636 if((lx3-lx2)>CHKMAX_X) return TRUE;\r
637 }\r
638 if(lx3<0)\r
639 {\r
640 if(((lx1-lx3)>CHKMAX_X) ||\r
641 ((lx2-lx3)>CHKMAX_X))\r
642 {\r
643 if(lx0<0)\r
644 {\r
645 if((lx1-lx0)>CHKMAX_X) return TRUE;\r
646 if((lx2-lx0)>CHKMAX_X) return TRUE;\r
647 }\r
648 }\r
649 }\r
650 \r
651\r
652 if(ly0<0)\r
653 {\r
654 if((ly1-ly0)>CHKMAX_Y) return TRUE;\r
655 if((ly2-ly0)>CHKMAX_Y) return TRUE;\r
656 }\r
657 if(ly1<0)\r
658 {\r
659 if((ly0-ly1)>CHKMAX_Y) return TRUE;\r
660 if((ly2-ly1)>CHKMAX_Y) return TRUE;\r
661 if((ly3-ly1)>CHKMAX_Y) return TRUE;\r
662 }\r
663 if(ly2<0)\r
664 {\r
665 if((ly0-ly2)>CHKMAX_Y) return TRUE;\r
666 if((ly1-ly2)>CHKMAX_Y) return TRUE;\r
667 if((ly3-ly2)>CHKMAX_Y) return TRUE;\r
668 }\r
669 if(ly3<0)\r
670 {\r
671 if((ly1-ly3)>CHKMAX_Y) return TRUE;\r
672 if((ly2-ly3)>CHKMAX_Y) return TRUE;\r
673 }\r
674\r
675 return FALSE;\r
676}\r
677\r
678__inline BOOL CheckCoord3()\r
679{\r
680 if(lx0<0)\r
681 {\r
682 if((lx1-lx0)>CHKMAX_X) return TRUE;\r
683 if((lx2-lx0)>CHKMAX_X) return TRUE;\r
684 }\r
685 if(lx1<0)\r
686 {\r
687 if((lx0-lx1)>CHKMAX_X) return TRUE;\r
688 if((lx2-lx1)>CHKMAX_X) return TRUE;\r
689 }\r
690 if(lx2<0)\r
691 {\r
692 if((lx0-lx2)>CHKMAX_X) return TRUE;\r
693 if((lx1-lx2)>CHKMAX_X) return TRUE;\r
694 }\r
695 if(ly0<0)\r
696 {\r
697 if((ly1-ly0)>CHKMAX_Y) return TRUE;\r
698 if((ly2-ly0)>CHKMAX_Y) return TRUE;\r
699 }\r
700 if(ly1<0)\r
701 {\r
702 if((ly0-ly1)>CHKMAX_Y) return TRUE;\r
703 if((ly2-ly1)>CHKMAX_Y) return TRUE;\r
704 }\r
705 if(ly2<0)\r
706 {\r
707 if((ly0-ly2)>CHKMAX_Y) return TRUE;\r
708 if((ly1-ly2)>CHKMAX_Y) return TRUE;\r
709 }\r
710\r
711 return FALSE;\r
712}\r
713\r
714\r
715__inline BOOL CheckCoord2()\r
716{\r
717 if(lx0<0)\r
718 {\r
719 if((lx1-lx0)>CHKMAX_X) return TRUE;\r
720 }\r
721 if(lx1<0)\r
722 {\r
723 if((lx0-lx1)>CHKMAX_X) return TRUE;\r
724 }\r
725 if(ly0<0)\r
726 {\r
727 if((ly1-ly0)>CHKMAX_Y) return TRUE;\r
728 }\r
729 if(ly1<0)\r
730 {\r
731 if((ly0-ly1)>CHKMAX_Y) return TRUE;\r
732 }\r
733\r
734 return FALSE;\r
735}\r
736\r
737/*\r
738//Lewpys "offsetline" func:\r
739\r
740void offsetline(void)\r
741{\r
742 float x0, x1, y0, y1, oolength, xl, yl;\r
743\r
744 if(bDisplayNotSet)\r
745 SetOGLDisplaySettings(1);\r
746\r
747 if(!(dwActFixes&16))\r
748 {\r
749 if((lx0 & SIGNBIT)) lx0|=S_MASK;\r
750 else lx0&=~S_MASK;\r
751 if((lx1 & SIGNBIT)) lx1|=S_MASK;\r
752 else lx1&=~S_MASK;\r
753 if((ly0 & SIGNBIT)) ly0|=S_MASK;\r
754 else ly0&=~S_MASK;\r
755 if((ly1 & SIGNBIT)) ly1|=S_MASK;\r
756 else ly1&=~S_MASK;\r
757 }\r
758\r
759 x0 = (float)(lx0 + PSXDisplay.CumulOffset.x);\r
760 x1 = (float)(lx1 + PSXDisplay.CumulOffset.x);\r
761 y0 = (float)(ly0 + PSXDisplay.CumulOffset.y);\r
762 y1 = (float)(ly1 + PSXDisplay.CumulOffset.y);\r
763\r
764 oolength = (float)1/((float)sqrt((y1 - y0)*(y1 - y0) + (x1 - x0)*(x1 - x0)) * (float)2);\r
765// oolength = (float)1/((float)sqrt(((y1 - y0)*(y1 - y0) + (x1 - x0)*(x1 - x0)) * (float)2));\r
766\r
767 xl = (x1 - x0) * oolength;\r
768 yl = (y1 - y0) * oolength;\r
769\r
770 x0 += 0.5f;\r
771 x1 += 0.5f;\r
772\r
773 x0 -= xl - yl;\r
774 x1 += xl + yl;\r
775 y0 -= yl + xl;\r
776 y1 += yl - xl;\r
777\r
778 vertex[0].x=x0;\r
779 vertex[1].x=x1;\r
780 vertex[0].y=y0;\r
781 vertex[1].y=y1;\r
782\r
783 x0 -= yl * 2;\r
784 x1 -= yl * 2;\r
785 y0 += xl * 2;\r
786 y1 += xl * 2;\r
787\r
788 vertex[2].x=x1;\r
789 vertex[3].x=x0;\r
790 vertex[2].y=y1;\r
791 vertex[3].y=y0;\r
792}\r
793*/\r
794\r
795\r
796// Pete's way: a very easy (and hopefully fast) approach for lines\r
797// without sqrt... using a small float -> short cast trick :)\r
798\r
799#define VERTEX_OFFX 0.2f\r
800#define VERTEX_OFFY 0.2f\r
801\r
802BOOL offsetline(void) \r
803{\r
804 short x0,x1,y0,y1,dx,dy;float px,py;\r
805\r
806 if(bDisplayNotSet)\r
807 SetOGLDisplaySettings(1);\r
808\r
809 if(!(dwActFixes&16))\r
810 {\r
811 lx0=(short)(((int)lx0<<SIGNSHIFT)>>SIGNSHIFT);\r
812 lx1=(short)(((int)lx1<<SIGNSHIFT)>>SIGNSHIFT);\r
813 ly0=(short)(((int)ly0<<SIGNSHIFT)>>SIGNSHIFT);\r
814 ly1=(short)(((int)ly1<<SIGNSHIFT)>>SIGNSHIFT);\r
815\r
816 if(CheckCoord2()) return TRUE;\r
817 }\r
818\r
819 x0 = (lx0 + PSXDisplay.CumulOffset.x)+1;\r
820 x1 = (lx1 + PSXDisplay.CumulOffset.x)+1;\r
821 y0 = (ly0 + PSXDisplay.CumulOffset.y)+1;\r
822 y1 = (ly1 + PSXDisplay.CumulOffset.y)+1;\r
823 \r
824 dx=x1-x0;\r
825 dy=y1-y0;\r
826 \r
827 if(dx>=0)\r
828 {\r
829 if(dy>=0)\r
830 {\r
831 px=0.5f;\r
832 if(dx>dy) py=-0.5f;\r
833 else if(dx<dy) py= 0.5f;\r
834 else py= 0.0f;\r
835 }\r
836 else\r
837 {\r
838 py=-0.5f;\r
839 dy=-dy;\r
840 if(dx>dy) px= 0.5f;\r
841 else if(dx<dy) px=-0.5f;\r
842 else px= 0.0f;\r
843 }\r
844 }\r
845 else\r
846 {\r
847 if(dy>=0)\r
848 {\r
849 py=0.5f;\r
850 dx=-dx;\r
851 if(dx>dy) px=-0.5f;\r
852 else if(dx<dy) px= 0.5f;\r
853 else px= 0.0f;\r
854 }\r
855 else\r
856 {\r
857 px=-0.5f;\r
858 if(dx>dy) py=-0.5f;\r
859 else if(dx<dy) py= 0.5f;\r
860 else py= 0.0f;\r
861 }\r
862 } \r
863 \r
864 vertex[0].x=(short)((float)x0-px);\r
865 vertex[3].x=(short)((float)x0+py);\r
866 \r
867 vertex[0].y=(short)((float)y0-py);\r
868 vertex[3].y=(short)((float)y0-px);\r
869 \r
870 vertex[1].x=(short)((float)x1-py);\r
871 vertex[2].x=(short)((float)x1+px);\r
872\r
873 vertex[1].y=(short)((float)y1+px);\r
874 vertex[2].y=(short)((float)y1+py);\r
875\r
876 if(vertex[0].x==vertex[3].x && // ortho rect? done\r
877 vertex[1].x==vertex[2].x &&\r
878 vertex[0].y==vertex[1].y &&\r
879 vertex[2].y==vertex[3].y) return FALSE;\r
880 if(vertex[0].x==vertex[1].x &&\r
881 vertex[2].x==vertex[3].x &&\r
882 vertex[0].y==vertex[3].y &&\r
883 vertex[1].y==vertex[2].y) return FALSE;\r
884\r
885 vertex[0].x-=VERTEX_OFFX; // otherwise a small offset\r
886 vertex[0].y-=VERTEX_OFFY; // to get better accuracy\r
887 vertex[1].x-=VERTEX_OFFX;\r
888 vertex[1].y-=VERTEX_OFFY;\r
889 vertex[2].x-=VERTEX_OFFX;\r
890 vertex[2].y-=VERTEX_OFFY;\r
891 vertex[3].x-=VERTEX_OFFX;\r
892 vertex[3].y-=VERTEX_OFFY;\r
893\r
894 return FALSE;\r
895}\r
896\r
897///////////////////////////////////////////////////////// \r
898\r
899BOOL offset2(void)\r
900{\r
901 if(bDisplayNotSet)\r
902 SetOGLDisplaySettings(1);\r
903\r
904 if(!(dwActFixes&16))\r
905 {\r
906 lx0=(short)(((int)lx0<<SIGNSHIFT)>>SIGNSHIFT);\r
907 lx1=(short)(((int)lx1<<SIGNSHIFT)>>SIGNSHIFT);\r
908 ly0=(short)(((int)ly0<<SIGNSHIFT)>>SIGNSHIFT);\r
909 ly1=(short)(((int)ly1<<SIGNSHIFT)>>SIGNSHIFT);\r
910\r
911 if(CheckCoord2()) return TRUE;\r
912 }\r
913\r
914 vertex[0].x=lx0+PSXDisplay.CumulOffset.x;\r
915 vertex[1].x=lx1+PSXDisplay.CumulOffset.x;\r
916 vertex[0].y=ly0+PSXDisplay.CumulOffset.y;\r
917 vertex[1].y=ly1+PSXDisplay.CumulOffset.y;\r
918\r
919 return FALSE;\r
920}\r
921\r
922///////////////////////////////////////////////////////// \r
923\r
924BOOL offset3(void)\r
925{\r
926 if(bDisplayNotSet)\r
927 SetOGLDisplaySettings(1);\r
928\r
929 if(!(dwActFixes&16))\r
930 {\r
931 lx0=(short)(((int)lx0<<SIGNSHIFT)>>SIGNSHIFT);\r
932 lx1=(short)(((int)lx1<<SIGNSHIFT)>>SIGNSHIFT);\r
933 lx2=(short)(((int)lx2<<SIGNSHIFT)>>SIGNSHIFT);\r
934 ly0=(short)(((int)ly0<<SIGNSHIFT)>>SIGNSHIFT);\r
935 ly1=(short)(((int)ly1<<SIGNSHIFT)>>SIGNSHIFT);\r
936 ly2=(short)(((int)ly2<<SIGNSHIFT)>>SIGNSHIFT);\r
937\r
938 if(CheckCoord3()) return TRUE;\r
939 }\r
940\r
941 vertex[0].x=lx0+PSXDisplay.CumulOffset.x;\r
942 vertex[1].x=lx1+PSXDisplay.CumulOffset.x;\r
943 vertex[2].x=lx2+PSXDisplay.CumulOffset.x;\r
944 vertex[0].y=ly0+PSXDisplay.CumulOffset.y;\r
945 vertex[1].y=ly1+PSXDisplay.CumulOffset.y;\r
946 vertex[2].y=ly2+PSXDisplay.CumulOffset.y;\r
947\r
948 return FALSE;\r
949}\r
950\r
951///////////////////////////////////////////////////////// \r
952\r
953BOOL offset4(void)\r
954{\r
955 if(bDisplayNotSet)\r
956 SetOGLDisplaySettings(1);\r
957\r
958 if(!(dwActFixes&16))\r
959 {\r
960 lx0=(short)(((int)lx0<<SIGNSHIFT)>>SIGNSHIFT);\r
961 lx1=(short)(((int)lx1<<SIGNSHIFT)>>SIGNSHIFT);\r
962 lx2=(short)(((int)lx2<<SIGNSHIFT)>>SIGNSHIFT);\r
963 lx3=(short)(((int)lx3<<SIGNSHIFT)>>SIGNSHIFT);\r
964 ly0=(short)(((int)ly0<<SIGNSHIFT)>>SIGNSHIFT);\r
965 ly1=(short)(((int)ly1<<SIGNSHIFT)>>SIGNSHIFT);\r
966 ly2=(short)(((int)ly2<<SIGNSHIFT)>>SIGNSHIFT);\r
967 ly3=(short)(((int)ly3<<SIGNSHIFT)>>SIGNSHIFT);\r
968\r
969 if(CheckCoord4()) return TRUE;\r
970 }\r
971\r
972 vertex[0].x=lx0+PSXDisplay.CumulOffset.x;\r
973 vertex[1].x=lx1+PSXDisplay.CumulOffset.x;\r
974 vertex[2].x=lx2+PSXDisplay.CumulOffset.x;\r
975 vertex[3].x=lx3+PSXDisplay.CumulOffset.x;\r
976 vertex[0].y=ly0+PSXDisplay.CumulOffset.y;\r
977 vertex[1].y=ly1+PSXDisplay.CumulOffset.y;\r
978 vertex[2].y=ly2+PSXDisplay.CumulOffset.y;\r
979 vertex[3].y=ly3+PSXDisplay.CumulOffset.y;\r
980\r
981 return FALSE;\r
982}\r
983\r
984///////////////////////////////////////////////////////// \r
985\r
986void offsetST(void)\r
987{\r
988 if(bDisplayNotSet)\r
989 SetOGLDisplaySettings(1);\r
990\r
991 if(!(dwActFixes&16))\r
992 {\r
993 lx0=(short)(((int)lx0<<SIGNSHIFT)>>SIGNSHIFT);\r
994 ly0=(short)(((int)ly0<<SIGNSHIFT)>>SIGNSHIFT);\r
995\r
996 if(lx0<-512 && PSXDisplay.DrawOffset.x<=-512)\r
997 lx0+=2048;\r
998\r
999 if(ly0<-512 && PSXDisplay.DrawOffset.y<=-512)\r
1000 ly0+=2048;\r
1001 }\r
1002\r
1003 ly1 = ly0;\r
1004 ly2 = ly3 = ly0+sprtH;\r
1005 lx3 = lx0;\r
1006 lx1 = lx2 = lx0+sprtW;\r
1007\r
1008 vertex[0].x=lx0+PSXDisplay.CumulOffset.x;\r
1009 vertex[1].x=lx1+PSXDisplay.CumulOffset.x;\r
1010 vertex[2].x=lx2+PSXDisplay.CumulOffset.x;\r
1011 vertex[3].x=lx3+PSXDisplay.CumulOffset.x;\r
1012 vertex[0].y=ly0+PSXDisplay.CumulOffset.y;\r
1013 vertex[1].y=ly1+PSXDisplay.CumulOffset.y;\r
1014 vertex[2].y=ly2+PSXDisplay.CumulOffset.y;\r
1015 vertex[3].y=ly3+PSXDisplay.CumulOffset.y;\r
1016}\r
1017\r
1018///////////////////////////////////////////////////////// \r
1019\r
1020void offsetScreenUpload(int Position)\r
1021{\r
1022 if(bDisplayNotSet)\r
1023 SetOGLDisplaySettings(1);\r
1024\r
1025 if(Position==-1)\r
1026 {\r
1027 int lmdx,lmdy;\r
1028\r
1029 lmdx=xrUploadArea.x0;\r
1030 lmdy=xrUploadArea.y0;\r
1031\r
1032 lx0-=lmdx;\r
1033 ly0-=lmdy;\r
1034 lx1-=lmdx;\r
1035 ly1-=lmdy;\r
1036 lx2-=lmdx;\r
1037 ly2-=lmdy;\r
1038 lx3-=lmdx;\r
1039 ly3-=lmdy;\r
1040 }\r
1041 else\r
1042 if(Position)\r
1043 {\r
1044 lx0-=PSXDisplay.DisplayPosition.x;\r
1045 ly0-=PSXDisplay.DisplayPosition.y;\r
1046 lx1-=PSXDisplay.DisplayPosition.x;\r
1047 ly1-=PSXDisplay.DisplayPosition.y;\r
1048 lx2-=PSXDisplay.DisplayPosition.x;\r
1049 ly2-=PSXDisplay.DisplayPosition.y;\r
1050 lx3-=PSXDisplay.DisplayPosition.x;\r
1051 ly3-=PSXDisplay.DisplayPosition.y;\r
1052 }\r
1053 else\r
1054 {\r
1055 lx0-=PreviousPSXDisplay.DisplayPosition.x;\r
1056 ly0-=PreviousPSXDisplay.DisplayPosition.y;\r
1057 lx1-=PreviousPSXDisplay.DisplayPosition.x;\r
1058 ly1-=PreviousPSXDisplay.DisplayPosition.y;\r
1059 lx2-=PreviousPSXDisplay.DisplayPosition.x;\r
1060 ly2-=PreviousPSXDisplay.DisplayPosition.y;\r
1061 lx3-=PreviousPSXDisplay.DisplayPosition.x;\r
1062 ly3-=PreviousPSXDisplay.DisplayPosition.y;\r
1063 }\r
1064\r
1065 vertex[0].x=lx0 + PreviousPSXDisplay.Range.x0;\r
1066 vertex[1].x=lx1 + PreviousPSXDisplay.Range.x0;\r
1067 vertex[2].x=lx2 + PreviousPSXDisplay.Range.x0;\r
1068 vertex[3].x=lx3 + PreviousPSXDisplay.Range.x0;\r
1069 vertex[0].y=ly0 + PreviousPSXDisplay.Range.y0;\r
1070 vertex[1].y=ly1 + PreviousPSXDisplay.Range.y0;\r
1071 vertex[2].y=ly2 + PreviousPSXDisplay.Range.y0;\r
1072 vertex[3].y=ly3 + PreviousPSXDisplay.Range.y0;\r
1073\r
1074 if(iUseMask)\r
1075 {\r
1076 vertex[0].z=vertex[1].z=vertex[2].z=vertex[3].z=gl_z;\r
1077 gl_z+=0.00004f;\r
1078 }\r
1079}\r
1080 \r
1081///////////////////////////////////////////////////////// \r
1082\r
1083void offsetBlk(void)\r
1084{\r
1085 if(bDisplayNotSet)\r
1086 SetOGLDisplaySettings(1);\r
1087 \r
1088 vertex[0].x=lx0-PSXDisplay.GDrawOffset.x + PreviousPSXDisplay.Range.x0;\r
1089 vertex[1].x=lx1-PSXDisplay.GDrawOffset.x + PreviousPSXDisplay.Range.x0;\r
1090 vertex[2].x=lx2-PSXDisplay.GDrawOffset.x + PreviousPSXDisplay.Range.x0;\r
1091 vertex[3].x=lx3-PSXDisplay.GDrawOffset.x + PreviousPSXDisplay.Range.x0;\r
1092 vertex[0].y=ly0-PSXDisplay.GDrawOffset.y + PreviousPSXDisplay.Range.y0;\r
1093 vertex[1].y=ly1-PSXDisplay.GDrawOffset.y + PreviousPSXDisplay.Range.y0;\r
1094 vertex[2].y=ly2-PSXDisplay.GDrawOffset.y + PreviousPSXDisplay.Range.y0;\r
1095 vertex[3].y=ly3-PSXDisplay.GDrawOffset.y + PreviousPSXDisplay.Range.y0;\r
1096\r
1097 if(iUseMask)\r
1098 {\r
1099 vertex[0].z=vertex[1].z=vertex[2].z=vertex[3].z=gl_z;\r
1100 gl_z+=0.00004f;\r
1101 }\r
1102}\r
1103\r
1104////////////////////////////////////////////////////////////////////////\r
1105// texture sow/tow calculations\r
1106////////////////////////////////////////////////////////////////////////\r
1107\r
1108void assignTextureVRAMWrite(void)\r
1109{\r
1110#ifdef OWNSCALE\r
1111\r
1112 vertex[0].sow=0.5f/ ST_FACVRAMX;\r
1113 vertex[0].tow=0.5f/ ST_FACVRAM;\r
1114\r
1115 vertex[1].sow=(float)gl_ux[1]/ ST_FACVRAMX;\r
1116 vertex[1].tow=0.5f/ ST_FACVRAM;\r
1117\r
1118 vertex[2].sow=(float)gl_ux[2]/ ST_FACVRAMX;\r
1119 vertex[2].tow=(float)gl_vy[2]/ ST_FACVRAM;\r
1120\r
1121 vertex[3].sow=0.5f/ ST_FACVRAMX;\r
1122 vertex[3].tow=(float)gl_vy[3]/ ST_FACVRAM;\r
1123\r
1124#else\r
1125\r
1126 if(gl_ux[1]==255)\r
1127 {\r
1128 vertex[0].sow=(gl_ux[0]*255.99f)/255.0f;\r
1129 vertex[1].sow=(gl_ux[1]*255.99f)/255.0f;\r
1130 vertex[2].sow=(gl_ux[2]*255.99f)/255.0f;\r
1131 vertex[3].sow=(gl_ux[3]*255.99f)/255.0f;\r
1132 }\r
1133 else\r
1134 {\r
1135 vertex[0].sow=gl_ux[0];\r
1136 vertex[1].sow=gl_ux[1];\r
1137 vertex[2].sow=gl_ux[2];\r
1138 vertex[3].sow=gl_ux[3];\r
1139 }\r
1140\r
1141 vertex[0].tow=gl_vy[0];\r
1142 vertex[1].tow=gl_vy[1];\r
1143 vertex[2].tow=gl_vy[2];\r
1144 vertex[3].tow=gl_vy[3];\r
1145\r
1146#endif\r
1147}\r
1148\r
1149GLuint gLastTex=0;\r
1150GLuint gLastFMode=(GLuint)-1;\r
1151\r
1152///////////////////////////////////////////////////////// \r
1153\r
1154void assignTextureSprite(void)\r
1155{\r
1156 if(bUsingTWin)\r
1157 {\r
1158 vertex[0].sow=vertex[3].sow=(float)gl_ux[0]/TWin.UScaleFactor;\r
1159 vertex[1].sow=vertex[2].sow=(float)sSprite_ux2/TWin.UScaleFactor;\r
1160 vertex[0].tow=vertex[1].tow=(float)gl_vy[0]/TWin.VScaleFactor;\r
1161 vertex[2].tow=vertex[3].tow=(float)sSprite_vy2/TWin.VScaleFactor;\r
1162 gLastTex=gTexName;\r
1163\r
1164 if(iFilterType>0 && iFilterType<3 && iHiResTextures!=2) \r
1165 {\r
1166 float fxmin=65536.0f,fxmax=0.0f,fymin=65536.0f,fymax=0.0f;int i;\r
1167\r
1168 for(i=0;i<4;i++)\r
1169 {\r
1170 if(vertex[i].sow<fxmin) fxmin=vertex[i].sow;\r
1171 if(vertex[i].tow<fymin) fymin=vertex[i].tow;\r
1172 if(vertex[i].sow>fxmax) fxmax=vertex[i].sow;\r
1173 if(vertex[i].tow>fymax) fymax=vertex[i].tow; \r
1174 }\r
1175\r
1176 for(i=0;i<4;i++)\r
1177 {\r
1178#ifdef OWNSCALE\r
1179 if(vertex[i].sow==fxmin) vertex[i].sow+=0.375f/(float)TWin.Position.x1;\r
1180 if(vertex[i].sow==fxmax) vertex[i].sow-=0.375f/(float)TWin.Position.x1;\r
1181 if(vertex[i].tow==fymin) vertex[i].tow+=0.375f/(float)TWin.Position.y1;\r
1182 if(vertex[i].tow==fymax) vertex[i].tow-=0.375f/(float)TWin.Position.y1;\r
1183#else\r
1184 if(vertex[i].sow==fxmin) vertex[i].sow+=96.0f/(float)TWin.Position.x1;\r
1185 if(vertex[i].sow==fxmax) vertex[i].sow-=96.0f/(float)TWin.Position.x1;\r
1186 if(vertex[i].tow==fymin) vertex[i].tow+=96.0f/(float)TWin.Position.y1;\r
1187 if(vertex[i].tow==fymax) vertex[i].tow-=96.0f/(float)TWin.Position.y1;\r
1188#endif\r
1189 }\r
1190 }\r
1191\r
1192 }\r
1193 else\r
1194 {\r
1195#ifdef OWNSCALE\r
1196\r
1197 vertex[0].sow=vertex[3].sow=(float)gl_ux[0] / ST_FACSPRITE;\r
1198 vertex[1].sow=vertex[2].sow=(float)sSprite_ux2 / ST_FACSPRITE;\r
1199 vertex[0].tow=vertex[1].tow=(float)gl_vy[0] / ST_FACSPRITE;\r
1200 vertex[2].tow=vertex[3].tow=(float)sSprite_vy2 / ST_FACSPRITE;\r
1201\r
1202#else\r
1203 \r
1204 vertex[0].sow=vertex[3].sow=gl_ux[0];\r
1205 vertex[1].sow=vertex[2].sow=sSprite_ux2;\r
1206 vertex[0].tow=vertex[1].tow=gl_vy[0];\r
1207 vertex[2].tow=vertex[3].tow=sSprite_vy2;\r
1208\r
1209#endif\r
1210\r
1211 if(iFilterType>2) \r
1212 {\r
1213 if(gLastTex!=gTexName || gLastFMode!=0)\r
1214 {\r
1215 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);\r
1216 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);\r
1217 gLastTex=gTexName;gLastFMode=0;\r
1218 }\r
1219 }\r
1220 }\r
1221\r
1222 if(usMirror & 0x1000) \r
1223 {\r
1224 vertex[0].sow=vertex[1].sow;\r
1225 vertex[1].sow=vertex[2].sow=vertex[3].sow;\r
1226 vertex[3].sow=vertex[0].sow;\r
1227 }\r
1228\r
1229 if(usMirror & 0x2000) \r
1230 {\r
1231 vertex[0].tow=vertex[3].tow;\r
1232 vertex[2].tow=vertex[3].tow=vertex[1].tow;\r
1233 vertex[1].tow=vertex[0].tow;\r
1234 }\r
1235\r
1236}\r
1237\r
1238///////////////////////////////////////////////////////// \r
1239\r
1240void assignTexture3(void)\r
1241{\r
1242 if(bUsingTWin)\r
1243 {\r
1244 vertex[0].sow=(float)gl_ux[0]/TWin.UScaleFactor;\r
1245 vertex[0].tow=(float)gl_vy[0]/TWin.VScaleFactor;\r
1246 vertex[1].sow=(float)gl_ux[1]/TWin.UScaleFactor;\r
1247 vertex[1].tow=(float)gl_vy[1]/TWin.VScaleFactor;\r
1248 vertex[2].sow=(float)gl_ux[2]/TWin.UScaleFactor;\r
1249 vertex[2].tow=(float)gl_vy[2]/TWin.VScaleFactor;\r
1250 gLastTex=gTexName;\r
1251 }\r
1252 else\r
1253 {\r
1254#ifdef OWNSCALE\r
1255 vertex[0].sow=(float)gl_ux[0] / ST_FACTRI;\r
1256 vertex[0].tow=(float)gl_vy[0] / ST_FACTRI;\r
1257 vertex[1].sow=(float)gl_ux[1] / ST_FACTRI;\r
1258\r
1259 vertex[1].tow=(float)gl_vy[1] / ST_FACTRI;\r
1260 vertex[2].sow=(float)gl_ux[2] / ST_FACTRI;\r
1261 vertex[2].tow=(float)gl_vy[2] / ST_FACTRI;\r
1262#else\r
1263 vertex[0].sow=gl_ux[0];\r
1264 vertex[0].tow=gl_vy[0];\r
1265 vertex[1].sow=gl_ux[1];\r
1266 vertex[1].tow=gl_vy[1];\r
1267 vertex[2].sow=gl_ux[2];\r
1268 vertex[2].tow=gl_vy[2];\r
1269#endif\r
1270\r
1271 if(iFilterType>2) \r
1272 {\r
1273 if(gLastTex!=gTexName || gLastFMode!=1)\r
1274 {\r
1275 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);\r
1276 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);\r
1277 gLastTex=gTexName;gLastFMode=1;\r
1278 }\r
1279 }\r
1280\r
1281 if(iFilterType) \r
1282 {\r
1283 float fxmin=256.0f,fxmax=0.0f,fymin=256.0f,fymax=0.0f;int i;\r
1284 for(i=0;i<3;i++)\r
1285 {\r
1286 if(vertex[i].sow<fxmin) fxmin=vertex[i].sow;\r
1287 if(vertex[i].tow<fymin) fymin=vertex[i].tow;\r
1288 if(vertex[i].sow>fxmax) fxmax=vertex[i].sow;\r
1289 if(vertex[i].tow>fymax) fymax=vertex[i].tow; \r
1290 }\r
1291\r
1292 for(i=0;i<3;i++)\r
1293 {\r
1294 if(vertex[i].sow==fxmin) vertex[i].sow+=ST_BFFACSORT;\r
1295 if(vertex[i].sow==fxmax) vertex[i].sow-=ST_BFFACSORT;\r
1296 if(vertex[i].tow==fymin) vertex[i].tow+=ST_BFFACSORT;\r
1297 if(vertex[i].tow==fymax) vertex[i].tow-=ST_BFFACSORT;\r
1298 }\r
1299 }\r
1300 }\r
1301}\r
1302\r
1303///////////////////////////////////////////////////////// \r
1304\r
1305void assignTexture4(void)\r
1306{\r
1307 if(bUsingTWin)\r
1308 {\r
1309 vertex[0].sow=(float)gl_ux[0]/TWin.UScaleFactor;\r
1310 vertex[0].tow=(float)gl_vy[0]/TWin.VScaleFactor;\r
1311 vertex[1].sow=(float)gl_ux[1]/TWin.UScaleFactor;\r
1312 vertex[1].tow=(float)gl_vy[1]/TWin.VScaleFactor;\r
1313 vertex[2].sow=(float)gl_ux[2]/TWin.UScaleFactor;\r
1314 vertex[2].tow=(float)gl_vy[2]/TWin.VScaleFactor;\r
1315 vertex[3].sow=(float)gl_ux[3]/TWin.UScaleFactor;\r
1316 vertex[3].tow=(float)gl_vy[3]/TWin.VScaleFactor;\r
1317 gLastTex=gTexName;\r
1318 }\r
1319 else\r
1320 {\r
1321#ifdef OWNSCALE\r
1322 vertex[0].sow=(float)gl_ux[0] / ST_FAC;\r
1323 vertex[0].tow=(float)gl_vy[0] / ST_FAC;\r
1324 vertex[1].sow=(float)gl_ux[1] / ST_FAC;\r
1325 vertex[1].tow=(float)gl_vy[1] / ST_FAC;\r
1326 vertex[2].sow=(float)gl_ux[2] / ST_FAC;\r
1327 vertex[2].tow=(float)gl_vy[2] / ST_FAC;\r
1328 vertex[3].sow=(float)gl_ux[3] / ST_FAC;\r
1329 vertex[3].tow=(float)gl_vy[3] / ST_FAC;\r
1330#else\r
1331 vertex[0].sow=gl_ux[0];\r
1332 vertex[0].tow=gl_vy[0];\r
1333 vertex[1].sow=gl_ux[1];\r
1334 vertex[1].tow=gl_vy[1];\r
1335 vertex[2].sow=gl_ux[2];\r
1336 vertex[2].tow=gl_vy[2];\r
1337 vertex[3].sow=gl_ux[3];\r
1338 vertex[3].tow=gl_vy[3];\r
1339#endif\r
1340\r
1341 if(iFilterType>2) \r
1342 {\r
1343 if(gLastTex!=gTexName || gLastFMode!=1)\r
1344 {\r
1345 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);\r
1346 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);\r
1347 gLastTex=gTexName;gLastFMode=1;\r
1348 }\r
1349 }\r
1350\r
1351 if(iFilterType) \r
1352 {\r
1353 float fxmin=256.0f,fxmax=0.0f,fymin=256.0f,fymax=0.0f;int i;\r
1354 for(i=0;i<4;i++)\r
1355 {\r
1356 if(vertex[i].sow<fxmin) fxmin=vertex[i].sow;\r
1357 if(vertex[i].tow<fymin) fymin=vertex[i].tow;\r
1358 if(vertex[i].sow>fxmax) fxmax=vertex[i].sow;\r
1359 if(vertex[i].tow>fymax) fymax=vertex[i].tow; \r
1360 }\r
1361\r
1362 for(i=0;i<4;i++)\r
1363 {\r
1364 if(vertex[i].sow==fxmin) vertex[i].sow+=ST_BFFACSORT;\r
1365 if(vertex[i].sow==fxmax) vertex[i].sow-=ST_BFFACSORT;\r
1366 if(vertex[i].tow==fymin) vertex[i].tow+=ST_BFFACSORT;\r
1367 if(vertex[i].tow==fymax) vertex[i].tow-=ST_BFFACSORT;\r
1368 }\r
1369 }\r
1370 }\r
1371}\r
1372\r
1373////////////////////////////////////////////////////////////////////////\r
1374////////////////////////////////////////////////////////////////////////\r
1375////////////////////////////////////////////////////////////////////////\r
1376\r
1377////////////////////////////////////////////////////////////////////////\r
1378// render pos / buffers\r
1379////////////////////////////////////////////////////////////////////////\r
1380\r
1381#define EqualRect(pr1,pr2) ((pr1)->left==(pr2)->left && (pr1)->top==(pr2)->top && (pr1)->right==(pr2)->right && (pr1)->bottom==(pr2)->bottom)\r
1382\r
1383////////////////////////////////////////////////////////////////////////\r
1384// SetDisplaySettings: "simply" calcs the new drawing area and updates\r
1385// the ogl clipping (scissor) \r
1386\r
1387BOOL bSetClip=FALSE;\r
1388\r
1389void SetOGLDisplaySettings(BOOL DisplaySet)\r
1390{\r
1391 static RECT rprev={0,0,0,0};\r
1392 static RECT rC ={0,0,0,0};\r
1393 static int iOldX=0;\r
1394 static int iOldY=0;\r
1395 RECT r;float XS,YS;\r
1396\r
1397 bDisplayNotSet = FALSE;\r
1398\r
1399 //----------------------------------------------------// that's a whole screen upload\r
1400 if(!DisplaySet)\r
1401 {\r
1402 RECT rX;\r
1403 PSXDisplay.GDrawOffset.x=0;\r
1404 PSXDisplay.GDrawOffset.y=0;\r
1405\r
1406 PSXDisplay.CumulOffset.x = PSXDisplay.DrawOffset.x+PreviousPSXDisplay.Range.x0;\r
1407 PSXDisplay.CumulOffset.y = PSXDisplay.DrawOffset.y+PreviousPSXDisplay.Range.y0;\r
1408\r
1409 rprev.left=rprev.left+1;\r
1410\r
1411 rX=rRatioRect;\r
1412 rX.top=iResY-(rRatioRect.top+rRatioRect.bottom);\r
1413\r
1414 if(bSetClip || !EqualRect(&rC,&rX))\r
1415 {\r
1416 rC=rX;\r
1417 glScissor(rC.left,rC.top,rC.right,rC.bottom);\r
1418 bSetClip=FALSE; \r
1419 }\r
1420 return;\r
1421 }\r
1422 //----------------------------------------------------// \r
1423\r
1424 PSXDisplay.GDrawOffset.y = PreviousPSXDisplay.DisplayPosition.y;\r
1425 PSXDisplay.GDrawOffset.x = PreviousPSXDisplay.DisplayPosition.x;\r
1426 PSXDisplay.CumulOffset.x = PSXDisplay.DrawOffset.x - PSXDisplay.GDrawOffset.x+PreviousPSXDisplay.Range.x0;\r
1427 PSXDisplay.CumulOffset.y = PSXDisplay.DrawOffset.y - PSXDisplay.GDrawOffset.y+PreviousPSXDisplay.Range.y0;\r
1428\r
1429 r.top =PSXDisplay.DrawArea.y0 - PreviousPSXDisplay.DisplayPosition.y;\r
1430 r.bottom=PSXDisplay.DrawArea.y1 - PreviousPSXDisplay.DisplayPosition.y;\r
1431\r
1432 if(r.bottom<0 || r.top>=PSXDisplay.DisplayMode.y)\r
1433 {\r
1434 r.top =PSXDisplay.DrawArea.y0 - PSXDisplay.DisplayPosition.y;\r
1435 r.bottom=PSXDisplay.DrawArea.y1 - PSXDisplay.DisplayPosition.y;\r
1436 }\r
1437\r
1438 r.left =PSXDisplay.DrawArea.x0 - PreviousPSXDisplay.DisplayPosition.x;\r
1439 r.right =PSXDisplay.DrawArea.x1 - PreviousPSXDisplay.DisplayPosition.x;\r
1440\r
1441 if(r.right<0 || r.left>=PSXDisplay.DisplayMode.x)\r
1442 {\r
1443 r.left =PSXDisplay.DrawArea.x0 - PSXDisplay.DisplayPosition.x;\r
1444 r.right =PSXDisplay.DrawArea.x1 - PSXDisplay.DisplayPosition.x;\r
1445 }\r
1446\r
1447 if(!bSetClip && EqualRect(&r,&rprev) &&\r
1448 iOldX == PSXDisplay.DisplayMode.x &&\r
1449 iOldY == PSXDisplay.DisplayMode.y)\r
1450 return;\r
1451\r
1452 rprev = r;\r
1453 iOldX = PSXDisplay.DisplayMode.x;\r
1454 iOldY = PSXDisplay.DisplayMode.y;\r
1455\r
1456 XS=(float)rRatioRect.right/(float)PSXDisplay.DisplayMode.x;\r
1457 YS=(float)rRatioRect.bottom/(float)PSXDisplay.DisplayMode.y;\r
1458\r
1459 if(PreviousPSXDisplay.Range.x0)\r
1460 {\r
1461 short s=PreviousPSXDisplay.Range.x0+PreviousPSXDisplay.Range.x1;\r
1462\r
1463 r.left+=PreviousPSXDisplay.Range.x0+1;\r
1464\r
1465 r.right+=PreviousPSXDisplay.Range.x0;\r
1466\r
1467 if(r.left>s) r.left=s;\r
1468 if(r.right>s) r.right=s;\r
1469 }\r
1470\r
1471 if(PreviousPSXDisplay.Range.y0)\r
1472 {\r
1473 short s=PreviousPSXDisplay.Range.y0+PreviousPSXDisplay.Range.y1;\r
1474\r
1475 r.top+=PreviousPSXDisplay.Range.y0+1;\r
1476 r.bottom+=PreviousPSXDisplay.Range.y0;\r
1477\r
1478 if(r.top>s) r.top=s;\r
1479 if(r.bottom>s) r.bottom=s;\r
1480 }\r
1481\r
1482 // Set the ClipArea variables to reflect the new screen,\r
1483 // offset from zero (since it is a new display buffer)\r
1484 r.left = (int)(((float)(r.left)) *XS);\r
1485 r.top = (int)(((float)(r.top)) *YS);\r
1486 r.right = (int)(((float)(r.right + 1))*XS);\r
1487 r.bottom = (int)(((float)(r.bottom + 1))*YS);\r
1488\r
1489 // Limit clip area to the screen size\r
1490 if (r.left > iResX) r.left = iResX;\r
1491 if (r.left < 0) r.left = 0;\r
1492 if (r.top > iResY) r.top = iResY;\r
1493 if (r.top < 0) r.top = 0;\r
1494 if (r.right > iResX) r.right = iResX;\r
1495 if (r.right < 0) r.right = 0;\r
1496 if (r.bottom > iResY) r.bottom = iResY;\r
1497 if (r.bottom < 0) r.bottom = 0;\r
1498\r
1499 r.right -=r.left;\r
1500 r.bottom-=r.top;\r
1501 r.top=iResY-(r.top+r.bottom);\r
1502\r
1503 r.left+=rRatioRect.left;\r
1504 r.top -=rRatioRect.top;\r
1505\r
1506 if(bSetClip || !EqualRect(&r,&rC))\r
1507 {\r
1508 glScissor(r.left,r.top,r.right,r.bottom);\r
1509 rC=r;\r
1510 bSetClip=FALSE;\r
1511 }\r
1512}\r
1513\r
1514////////////////////////////////////////////////////////////////////////\r
1515////////////////////////////////////////////////////////////////////////\r
1516////////////////////////////////////////////////////////////////////////\r
1517\r