Commit | Line | Data |
---|---|---|
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 | |
79 | BOOL bIsFirstFrame=TRUE;\r | |
80 | \r | |
81 | // resolution/ratio vars\r | |
82 | \r | |
83 | int iResX;\r | |
84 | int iResY;\r | |
85 | BOOL bKeepRatio=FALSE;\r | |
86 | RECT rRatioRect;\r | |
87 | \r | |
88 | // psx mask related vars\r | |
89 | \r | |
90 | BOOL bCheckMask=FALSE;\r | |
91 | int iUseMask=0;\r | |
92 | int iSetMask=0;\r | |
93 | unsigned short sSetMask=0;\r | |
94 | uint32_t lSetMask=0;\r | |
95 | \r | |
96 | // drawing/coord vars\r | |
97 | \r | |
98 | OGLVertex vertex[4];\r | |
99 | GLubyte gl_ux[8];\r | |
100 | GLubyte gl_vy[8];\r | |
101 | short sprtY,sprtX,sprtH,sprtW;\r | |
102 | \r | |
103 | // drawing options\r | |
104 | \r | |
105 | BOOL bOpaquePass;\r | |
106 | BOOL bAdvancedBlend;\r | |
107 | BOOL bUseLines;\r | |
108 | BOOL bUseAntiAlias;\r | |
109 | int iTexQuality;\r | |
110 | int iUsePalTextures=1;\r | |
111 | BOOL bSnapShot=FALSE;\r | |
112 | BOOL bSmallAlpha=FALSE;\r | |
113 | int iShowFPS=0;\r | |
114 | \r | |
115 | // OGL extension support\r | |
116 | \r | |
117 | int iForceVSync=-1;\r | |
118 | int iUseExts=0;\r | |
119 | BOOL bGLExt;\r | |
120 | BOOL bGLFastMovie=FALSE;\r | |
121 | BOOL bGLSoft;\r | |
122 | BOOL bGLBlend;\r | |
123 | PFNGLBLENDEQU glBlendEquationEXTEx=NULL;\r | |
124 | PFNGLCOLORTABLEEXT glColorTableEXTEx=NULL;\r | |
125 | \r | |
126 | // gfx card buffer infos\r | |
127 | \r | |
128 | int iDepthFunc=0;\r | |
129 | int iZBufferDepth=0;\r | |
130 | GLbitfield 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 | |
136 | void 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 | |
187 | void 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 | |
400 | GLuint gTexScanName=0;\r | |
401 | \r | |
402 | GLubyte 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 | |
410 | void 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 | |
449 | int 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 | |
578 | void 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 | |
740 | void 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 | |
802 | BOOL 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 | |
899 | BOOL 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 | |
924 | BOOL 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 | |
953 | BOOL 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 | |
986 | void 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 | |
1020 | void 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 | |
1083 | void 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 | |
1108 | void 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 | |
1149 | GLuint gLastTex=0;\r | |
1150 | GLuint gLastFMode=(GLuint)-1;\r | |
1151 | \r | |
1152 | ///////////////////////////////////////////////////////// \r | |
1153 | \r | |
1154 | void 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 | |
1240 | void 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 | |
1305 | void 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 | |
1387 | BOOL bSetClip=FALSE;\r | |
1388 | \r | |
1389 | void 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 |