gpu-gles: schtruck/fpse merge: don't delay gl init
[pcsx_rearmed.git] / plugins / gpu-gles / gpuPrim.c
1 /***************************************************************************\r
2                           prim.c  -  description\r
3                              -------------------\r
4     begin                : Sun Mar 08 2009\r
5     copyright            : (C) 1999-2009 by Pete Bernert\r
6     web                  : www.pbernert.com   \r
7  ***************************************************************************/\r
8 \r
9 /***************************************************************************\r
10  *                                                                         *\r
11  *   This program is free software; you can redistribute it and/or modify  *\r
12  *   it under the terms of the GNU General Public License as published by  *\r
13  *   the Free Software Foundation; either version 2 of the License, or     *\r
14  *   (at your option) any later version. See also the license.txt file for *\r
15  *   additional informations.                                              *\r
16  *                                                                         *\r
17  ***************************************************************************/\r
18 \r
19 //*************************************************************************// \r
20 // History of changes:\r
21 //\r
22 // 2009/03/08 - Pete  \r
23 // - generic cleanup for the Peops release\r
24 //\r
25 //*************************************************************************// \r
26 \r
27 #define _IN_PRIMDRAW\r
28 \r
29 #include "gpuStdafx.h"\r
30 #include "gpuExternals.h"\r
31 #include "gpuPlugin.h"\r
32 #include "gpuDraw.h"\r
33 #include "gpuTexture.h"\r
34 #include "gpuPrim.h"\r
35 \r
36 ////////////////////////////////////////////////////////////////////////                                          \r
37 // defines\r
38 ////////////////////////////////////////////////////////////////////////\r
39 \r
40 #define DEFOPAQUEON  glAlphaFunc(GL_EQUAL,0.0f);bBlendEnable=FALSE;glDisable(GL_BLEND);                                \r
41 #define DEFOPAQUEOFF glAlphaFunc(GL_GREATER,0.49f);\r
42 #define fpoint(x) x\r
43 ////////////////////////////////////////////////////////////////////////                                          \r
44 // globals\r
45 ////////////////////////////////////////////////////////////////////////\r
46 \r
47 EGLSurface surface;\r
48 EGLDisplay display;\r
49 \r
50 \r
51 BOOL           bDrawTextured;                          // current active drawing states\r
52 BOOL           bDrawSmoothShaded;\r
53 BOOL           bOldSmoothShaded;\r
54 BOOL           bDrawNonShaded;\r
55 BOOL           bDrawMultiPass;\r
56 int            iOffscreenDrawing;\r
57 int            iDrawnSomething=0;\r
58 \r
59 BOOL           bRenderFrontBuffer=FALSE;               // flag for front buffer rendering\r
60 \r
61 GLubyte        ubGloAlpha;                             // texture alpha\r
62 GLubyte        ubGloColAlpha;                          // color alpha\r
63 int            iFilterType;                            // type of filter\r
64 BOOL           bFullVRam=FALSE;                        // sign for tex win\r
65 BOOL           bDrawDither;                            // sign for dither\r
66 BOOL           bUseMultiPass;                          // sign for multi pass\r
67 GLuint         gTexName;                               // binded texture\r
68 BOOL           bTexEnabled;                            // texture enable flag\r
69 BOOL           bBlendEnable;                           // blend enable flag\r
70 PSXRect_t      xrUploadArea;                           // rect to upload\r
71 PSXRect_t      xrUploadAreaIL;                         // rect to upload\r
72 PSXRect_t      xrUploadAreaRGB24;                      // rect to upload rgb24\r
73 int            iSpriteTex=0;                           // flag for "hey, it's a sprite"\r
74 unsigned short usMirror;                               // mirror, mirror on the wall\r
75 \r
76 BOOL           bNeedUploadAfter=FALSE;                 // sign for uploading in next frame\r
77 BOOL           bNeedUploadTest=FALSE;                  // sign for upload test\r
78 BOOL           bUsingTWin=FALSE;                       // tex win active flag\r
79 BOOL           bUsingMovie=FALSE;                      // movie active flag\r
80 PSXRect_t      xrMovieArea;                            // rect for movie upload\r
81 short          sSprite_ux2;                            // needed for sprire adjust\r
82 short          sSprite_vy2;                            // \r
83 unsigned long  ulOLDCOL=0;                             // active color\r
84 unsigned long  ulClutID;                               // clut\r
85 \r
86 unsigned long dwCfgFixes;                              // game fixes\r
87 unsigned long dwActFixes=0;\r
88 unsigned long dwEmuFixes=0;\r
89 BOOL          bUseFixes;\r
90 \r
91 long          drawX,drawY,drawW,drawH;                 // offscreen drawing checkers\r
92 short         sxmin,sxmax,symin,symax;\r
93 \r
94 ////////////////////////////////////////////////////////////////////////                                          \r
95 // Update global TP infos\r
96 ////////////////////////////////////////////////////////////////////////\r
97 \r
98 void UpdateGlobalTP(unsigned short gdata)\r
99 {\r
100  GlobalTextAddrX = (gdata << 6) & 0x3c0;\r
101 \r
102  if(iGPUHeight==1024)                                  // ZN mode\r
103   {\r
104    if(dwGPUVersion==2)                                 // very special zn gpu\r
105     {\r
106      GlobalTextAddrY =((gdata & 0x60 ) << 3);\r
107      GlobalTextIL    =(gdata & 0x2000) >> 13;\r
108      GlobalTextABR = (unsigned short)((gdata >> 7) & 0x3);\r
109      GlobalTextTP = (gdata >> 9) & 0x3;\r
110      if(GlobalTextTP==3) GlobalTextTP=2;             \r
111      GlobalTexturePage = (GlobalTextAddrX>>6)+(GlobalTextAddrY>>4);\r
112      usMirror =0;\r
113      STATUSREG = (STATUSREG & 0xffffe000 ) | (gdata & 0x1fff );\r
114      return;\r
115     }\r
116    else                                                // "enhanced" psx gpu\r
117     {\r
118      GlobalTextAddrY = (unsigned short)(((gdata << 4) & 0x100) | ((gdata >> 2) & 0x200));\r
119     }\r
120   }\r
121  else GlobalTextAddrY = (gdata << 4) & 0x100;          // "normal" psx gpu\r
122 \r
123  usMirror=gdata&0x3000;\r
124  \r
125  GlobalTextTP = (gdata >> 7) & 0x3;                    // tex mode (4,8,15)\r
126  if(GlobalTextTP==3) GlobalTextTP=2;                   // seen in Wild9 :(\r
127  GlobalTextABR = (gdata >> 5) & 0x3;                   // blend mode\r
128 \r
129  GlobalTexturePage = (GlobalTextAddrX>>6)+(GlobalTextAddrY>>4);\r
130 \r
131  STATUSREG&=~0x07ff;                                   // Clear the necessary bits\r
132  STATUSREG|=(gdata & 0x07ff);                          // set the necessary bits\r
133 }\r
134 \r
135 ////////////////////////////////////////////////////////////////////////                                          \r
136 // Some ASM color convertion... Lewpy's special...\r
137 ////////////////////////////////////////////////////////////////////////\r
138 \r
139 \r
140 unsigned long DoubleBGR2RGB (unsigned long BGR)\r
141 {\r
142  unsigned long ebx,eax,edx;\r
143 \r
144  ebx=(BGR&0x000000ff)<<1;\r
145  if(ebx&0x00000100) ebx=0x000000ff;\r
146 \r
147  eax=(BGR&0x0000ff00)<<1;\r
148  if(eax&0x00010000) eax=0x0000ff00;\r
149 \r
150  edx=(BGR&0x00ff0000)<<1;\r
151  if(edx&0x01000000) edx=0x00ff0000;\r
152 \r
153  return (ebx|eax|edx);\r
154 }\r
155 \r
156 unsigned short BGR24to16 (unsigned long BGR)\r
157 {\r
158  return ((BGR>>3)&0x1f)|((BGR&0xf80000)>>9)|((BGR&0xf800)>>6);\r
159 }\r
160 \r
161 \r
162 ////////////////////////////////////////////////////////////////////////\r
163 // OpenGL primitive drawing commands\r
164 ////////////////////////////////////////////////////////////////////////\r
165 \r
166 void PRIMdrawTexturedQuad(OGLVertex* vertex1, OGLVertex* vertex2,\r
167                                    OGLVertex* vertex3, OGLVertex* vertex4) \r
168 {\r
169 \r
170 \r
171 Vertex v[4];\r
172 \r
173 v[0].xyz.x = fpoint(vertex1->x);\r
174 v[0].xyz.y = fpoint(vertex1->y);\r
175 v[0].xyz.z = fpoint(vertex1->z);\r
176 v[0].st.x = fpoint(vertex1->sow);\r
177 v[0].st.y = fpoint(vertex1->tow);\r
178 \r
179 v[1].xyz.x = fpoint(vertex2->x);\r
180 v[1].xyz.y = fpoint(vertex2->y);\r
181 v[1].xyz.z = fpoint(vertex2->z);\r
182 v[1].st.x = fpoint(vertex2->sow);\r
183 v[1].st.y = fpoint(vertex2->tow);\r
184 \r
185 v[2].xyz.x = fpoint(vertex4->x);\r
186 v[2].xyz.y = fpoint(vertex4->y);\r
187 v[2].xyz.z = fpoint(vertex4->z);\r
188 v[2].st.x = fpoint(vertex4->sow);\r
189 v[2].st.y = fpoint(vertex4->tow);\r
190 \r
191 v[3].xyz.x = fpoint(vertex3->x);\r
192 v[3].xyz.y = fpoint(vertex3->y);\r
193 v[3].xyz.z = fpoint(vertex3->z);\r
194 v[3].st.x = fpoint(vertex3->sow);\r
195 v[3].st.y = fpoint(vertex3->tow);\r
196 \r
197 glEnableClientState(GL_TEXTURE_COORD_ARRAY);\r
198 glEnableClientState(GL_VERTEX_ARRAY);\r
199 glTexCoordPointer(2, GL_FLOAT, sizeof(v[0]), &v[0].st);\r
200 glVertexPointer(3, GL_FLOAT, sizeof(v[0]), &v[0].xyz);\r
201 glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);\r
202 glDisableClientState(GL_TEXTURE_COORD_ARRAY);\r
203 glDisableClientState(GL_VERTEX_ARRAY); \r
204 }\r
205 \r
206 ///////////////////////////////////////////////////////// \r
207 \r
208 __inline void PRIMdrawTexturedTri(OGLVertex* vertex1, OGLVertex* vertex2, \r
209                                   OGLVertex* vertex3) \r
210 {\r
211 Vertex v[3];\r
212 \r
213 v[0].xyz.x = fpoint(vertex1->x);\r
214 v[0].xyz.y = fpoint(vertex1->y);\r
215 v[0].xyz.z = fpoint(vertex1->z);\r
216 v[0].st.x = fpoint(vertex1->sow);\r
217 v[0].st.y = fpoint(vertex1->tow);\r
218 \r
219 v[1].xyz.x = fpoint(vertex2->x);\r
220 v[1].xyz.y = fpoint(vertex2->y);\r
221 v[1].xyz.z = fpoint(vertex2->z);\r
222 v[1].st.x = fpoint(vertex2->sow);\r
223 v[1].st.y = fpoint(vertex2->tow);\r
224 \r
225 v[2].xyz.x = fpoint(vertex3->x);\r
226 v[2].xyz.y = fpoint(vertex3->y);\r
227 v[2].xyz.z = fpoint(vertex3->z);\r
228 v[2].st.x = fpoint(vertex3->sow);\r
229 v[2].st.y = fpoint(vertex3->tow);\r
230 \r
231 glEnableClientState(GL_TEXTURE_COORD_ARRAY);\r
232 glEnableClientState(GL_VERTEX_ARRAY);\r
233 glTexCoordPointer(2, GL_FLOAT, sizeof(v[0]), &v[0].st);\r
234 glVertexPointer(3, GL_FLOAT, sizeof(v[0]), &v[0].xyz);\r
235 glDrawArrays(GL_TRIANGLES, 0, 3);\r
236 glDisableClientState(GL_TEXTURE_COORD_ARRAY);\r
237 glDisableClientState(GL_VERTEX_ARRAY);\r
238 \r
239 }\r
240 \r
241 ///////////////////////////////////////////////////////// \r
242 \r
243 __inline void PRIMdrawTexGouraudTriColor(OGLVertex* vertex1, OGLVertex* vertex2, \r
244                                          OGLVertex* vertex3) \r
245 {\r
246 \r
247 Vertex2 v[3];\r
248 \r
249 v[0].xyz.x = fpoint(vertex1->x);\r
250 v[0].xyz.y = fpoint(vertex1->y);\r
251 v[0].xyz.z = fpoint(vertex1->z);\r
252 v[0].st.x = fpoint(vertex1->sow);\r
253 v[0].st.y = fpoint(vertex1->tow);\r
254 v[0].rgba.r = vertex1->c.col[0];\r
255 v[0].rgba.g = vertex1->c.col[1];\r
256 v[0].rgba.b = vertex1->c.col[2];\r
257 v[0].rgba.a = vertex1->c.col[3];\r
258 \r
259 v[1].xyz.x = fpoint(vertex2->x);\r
260 v[1].xyz.y = fpoint(vertex2->y);\r
261 v[1].xyz.z = fpoint(vertex2->z);\r
262 v[1].st.x = fpoint(vertex2->sow);\r
263 v[1].st.y = fpoint(vertex2->tow);\r
264 v[1].rgba.r = vertex2->c.col[0];\r
265 v[1].rgba.g = vertex2->c.col[1];\r
266 v[1].rgba.b = vertex2->c.col[2];\r
267 v[1].rgba.a = vertex2->c.col[3];\r
268 \r
269 v[2].xyz.x = fpoint(vertex3->x);\r
270 v[2].xyz.y = fpoint(vertex3->y);\r
271 v[2].xyz.z = fpoint(vertex3->z);\r
272 v[2].st.x = fpoint(vertex3->sow);\r
273 v[2].st.y = fpoint(vertex3->tow);\r
274 v[2].rgba.r = vertex3->c.col[0];\r
275 v[2].rgba.g = vertex3->c.col[1];\r
276 v[2].rgba.b = vertex3->c.col[2];\r
277 v[2].rgba.a = vertex3->c.col[3];\r
278 \r
279 glEnableClientState(GL_TEXTURE_COORD_ARRAY);\r
280 glEnableClientState(GL_VERTEX_ARRAY);\r
281 glEnableClientState(GL_COLOR_ARRAY);\r
282 \r
283 glTexCoordPointer(2, GL_FLOAT, sizeof(v[0]), &v[0].st);\r
284 glVertexPointer(3, GL_FLOAT, sizeof(v[0]), &v[0].xyz);\r
285 glColorPointer(4, GL_UNSIGNED_BYTE, sizeof(v[0]), &v[0].rgba);\r
286 \r
287 glDrawArrays(GL_TRIANGLES, 0, 3);\r
288 glDisableClientState(GL_TEXTURE_COORD_ARRAY);\r
289 glDisableClientState(GL_VERTEX_ARRAY);\r
290 glDisableClientState(GL_COLOR_ARRAY);\r
291 }\r
292 \r
293 ///////////////////////////////////////////////////////// \r
294 \r
295 __inline void PRIMdrawTexGouraudTriColorQuad(OGLVertex* vertex1, OGLVertex* vertex2, \r
296                                              OGLVertex* vertex3, OGLVertex* vertex4) \r
297 {\r
298 Vertex2 v[4];\r
299 \r
300 v[0].xyz.x = fpoint(vertex1->x);\r
301 v[0].xyz.y = fpoint(vertex1->y);\r
302 v[0].xyz.z = fpoint(vertex1->z);\r
303 v[0].st.x = fpoint(vertex1->sow);\r
304 v[0].st.y = fpoint(vertex1->tow);\r
305 v[0].rgba.r = vertex1->c.col[0];\r
306 v[0].rgba.g = vertex1->c.col[1];\r
307 v[0].rgba.b = vertex1->c.col[2];\r
308 v[0].rgba.a = vertex1->c.col[3];\r
309 \r
310 v[1].xyz.x = fpoint(vertex2->x);\r
311 v[1].xyz.y = fpoint(vertex2->y);\r
312 v[1].xyz.z = fpoint(vertex2->z);\r
313 v[1].st.x = fpoint(vertex2->sow);\r
314 v[1].st.y = fpoint(vertex2->tow);\r
315 v[1].rgba.r = vertex2->c.col[0];\r
316 v[1].rgba.g = vertex2->c.col[1];\r
317 v[1].rgba.b = vertex2->c.col[2];\r
318 v[1].rgba.a = vertex2->c.col[3];\r
319 \r
320 v[2].xyz.x = fpoint(vertex4->x);\r
321 v[2].xyz.y = fpoint(vertex4->y);\r
322 v[2].xyz.z = fpoint(vertex4->z);\r
323 v[2].st.x = fpoint(vertex4->sow);\r
324 v[2].st.y = fpoint(vertex4->tow);\r
325 v[2].rgba.r = vertex4->c.col[0];\r
326 v[2].rgba.g = vertex4->c.col[1];\r
327 v[2].rgba.b = vertex4->c.col[2];\r
328 v[2].rgba.a = vertex4->c.col[3];\r
329 \r
330 v[3].xyz.x = fpoint(vertex3->x);\r
331 v[3].xyz.y = fpoint(vertex3->y);\r
332 v[3].xyz.z = fpoint(vertex3->z);\r
333 v[3].st.x = fpoint(vertex3->sow);\r
334 v[3].st.y = fpoint(vertex3->tow);\r
335 v[3].rgba.r = vertex3->c.col[0];\r
336 v[3].rgba.g = vertex3->c.col[1];\r
337 v[3].rgba.b = vertex3->c.col[2];\r
338 v[3].rgba.a = vertex3->c.col[3];\r
339 \r
340 glEnableClientState(GL_TEXTURE_COORD_ARRAY);\r
341 glEnableClientState(GL_VERTEX_ARRAY);\r
342 glEnableClientState(GL_COLOR_ARRAY);\r
343 \r
344 glTexCoordPointer(2, GL_FLOAT, sizeof(v[0]), &v[0].st);\r
345 glVertexPointer(3, GL_FLOAT, sizeof(v[0]), &v[0].xyz);\r
346 glColorPointer(4, GL_UNSIGNED_BYTE, sizeof(v[0]), &v[0].rgba);\r
347 \r
348 glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);\r
349 glDisableClientState(GL_TEXTURE_COORD_ARRAY);\r
350 glDisableClientState(GL_VERTEX_ARRAY);\r
351 glDisableClientState(GL_COLOR_ARRAY);\r
352 }\r
353 \r
354 ///////////////////////////////////////////////////////// \r
355 \r
356 __inline void PRIMdrawTri(OGLVertex* vertex1, OGLVertex* vertex2, OGLVertex* vertex3) \r
357 {\r
358 Vec3f v[3];\r
359 \r
360 v[0].x = fpoint(vertex1->x);\r
361 v[0].y = fpoint(vertex1->y);\r
362 v[0].z = fpoint(vertex1->z);\r
363 \r
364 v[1].x = fpoint(vertex2->x);\r
365 v[1].y = fpoint(vertex2->y);\r
366 v[1].z = fpoint(vertex2->z);\r
367 \r
368 v[2].x = fpoint(vertex3->x);\r
369 v[2].y = fpoint(vertex3->y);\r
370 v[2].z = fpoint(vertex3->z);\r
371 \r
372 glEnableClientState(GL_VERTEX_ARRAY);\r
373 glVertexPointer(3, GL_FLOAT, sizeof(v[0]), &v[0]);\r
374 glDrawArrays(GL_TRIANGLES, 0, 3);\r
375 glDisableClientState(GL_VERTEX_ARRAY);\r
376 }\r
377 \r
378 ///////////////////////////////////////////////////////// \r
379 \r
380 __inline void PRIMdrawTri2(OGLVertex* vertex1, OGLVertex* vertex2, \r
381                            OGLVertex* vertex3, OGLVertex* vertex4) \r
382 {\r
383 Vec3f v[4];\r
384 \r
385 v[0].x = fpoint(vertex1->x);\r
386 v[0].y = fpoint(vertex1->y);\r
387 v[0].z = fpoint(vertex1->z);\r
388 \r
389 v[1].x = fpoint(vertex3->x);\r
390 v[1].y = fpoint(vertex3->y);\r
391 v[1].z = fpoint(vertex3->z);\r
392 \r
393 v[2].x = fpoint(vertex2->x);\r
394 v[2].y = fpoint(vertex2->y);\r
395 v[2].z = fpoint(vertex2->z);\r
396 \r
397 v[3].x = fpoint(vertex4->x);\r
398 v[3].y = fpoint(vertex4->y);\r
399 v[3].z = fpoint(vertex4->z);\r
400 \r
401 glEnableClientState(GL_VERTEX_ARRAY);\r
402 glVertexPointer(3, GL_FLOAT, sizeof(v[0]), &v[0]);\r
403 glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);\r
404 glDisableClientState(GL_VERTEX_ARRAY);\r
405 }\r
406 \r
407 ///////////////////////////////////////////////////////// \r
408 \r
409 __inline void PRIMdrawGouraudTriColor(OGLVertex* vertex1, OGLVertex* vertex2, \r
410                                       OGLVertex* vertex3) \r
411 {\r
412 Vertex2 v[3];\r
413 \r
414 v[0].xyz.x = fpoint(vertex1->x);\r
415 v[0].xyz.y = fpoint(vertex1->y);\r
416 v[0].xyz.z = fpoint(vertex1->z);\r
417 v[0].rgba.r = vertex1->c.col[0];\r
418 v[0].rgba.g = vertex1->c.col[1];\r
419 v[0].rgba.b = vertex1->c.col[2];\r
420 v[0].rgba.a = vertex1->c.col[3];\r
421 \r
422 v[1].xyz.x = fpoint(vertex2->x);\r
423 v[1].xyz.y = fpoint(vertex2->y);\r
424 v[1].xyz.z = fpoint(vertex2->z);\r
425 v[1].rgba.r = vertex2->c.col[0];\r
426 v[1].rgba.g = vertex2->c.col[1];\r
427 v[1].rgba.b = vertex2->c.col[2];\r
428 v[1].rgba.a = vertex2->c.col[3];\r
429 \r
430 v[2].xyz.x = fpoint(vertex3->x);\r
431 v[2].xyz.y = fpoint(vertex3->y);\r
432 v[2].xyz.z = fpoint(vertex3->z);\r
433 v[2].rgba.r = vertex3->c.col[0];\r
434 v[2].rgba.g = vertex3->c.col[1];\r
435 v[2].rgba.b = vertex3->c.col[2];\r
436 v[2].rgba.a = vertex3->c.col[3];\r
437 \r
438 glEnableClientState(GL_VERTEX_ARRAY);\r
439 glEnableClientState(GL_COLOR_ARRAY);\r
440 \r
441 glVertexPointer(3, GL_FLOAT, sizeof(v[0]), &v[0].xyz);\r
442 glColorPointer(4, GL_UNSIGNED_BYTE, sizeof(v[0]), &v[0].rgba);\r
443 \r
444 glDrawArrays(GL_TRIANGLES, 0, 3);\r
445 glDisableClientState(GL_VERTEX_ARRAY);\r
446 glDisableClientState(GL_COLOR_ARRAY);\r
447 }\r
448 \r
449 ///////////////////////////////////////////////////////// \r
450 \r
451 __inline void PRIMdrawGouraudTri2Color(OGLVertex* vertex1, OGLVertex* vertex2, \r
452                                        OGLVertex* vertex3, OGLVertex* vertex4) \r
453 {\r
454 Vertex2 v[4];\r
455 \r
456 v[0].xyz.x = fpoint(vertex1->x);\r
457 v[0].xyz.y = fpoint(vertex1->y);\r
458 v[0].xyz.z = fpoint(vertex1->z);\r
459 v[0].rgba.r = vertex1->c.col[0];\r
460 v[0].rgba.g = vertex1->c.col[1];\r
461 v[0].rgba.b = vertex1->c.col[2];\r
462 v[0].rgba.a = vertex1->c.col[3];\r
463 \r
464 v[1].xyz.x = fpoint(vertex2->x);\r
465 v[1].xyz.y = fpoint(vertex2->y);\r
466 v[1].xyz.z = fpoint(vertex2->z);\r
467 v[1].rgba.r = vertex2->c.col[0];\r
468 v[1].rgba.g = vertex2->c.col[1];\r
469 v[1].rgba.b = vertex2->c.col[2];\r
470 v[1].rgba.a = vertex2->c.col[3];\r
471 \r
472 v[2].xyz.x = fpoint(vertex3->x);\r
473 v[2].xyz.y = fpoint(vertex3->y);\r
474 v[2].xyz.z = fpoint(vertex3->z);\r
475 v[2].rgba.r = vertex3->c.col[0];\r
476 v[2].rgba.g = vertex3->c.col[1];\r
477 v[2].rgba.b = vertex3->c.col[2];\r
478 v[2].rgba.a = vertex3->c.col[3];\r
479 \r
480 v[3].xyz.x = fpoint(vertex4->x);\r
481 v[3].xyz.y = fpoint(vertex4->y);\r
482 v[3].xyz.z = fpoint(vertex4->z);\r
483 v[3].rgba.r = vertex4->c.col[0];\r
484 v[3].rgba.g = vertex4->c.col[1];\r
485 v[3].rgba.b = vertex4->c.col[2];\r
486 v[3].rgba.a = vertex4->c.col[3];\r
487 \r
488 glEnableClientState(GL_VERTEX_ARRAY);\r
489 glEnableClientState(GL_COLOR_ARRAY);\r
490 \r
491 glVertexPointer(3, GL_FLOAT, sizeof(v[0]), &v[0].xyz);\r
492 glColorPointer(4, GL_UNSIGNED_BYTE, sizeof(v[0]), &v[0].rgba);\r
493 \r
494 glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);\r
495 glDisableClientState(GL_VERTEX_ARRAY);\r
496 glDisableClientState(GL_COLOR_ARRAY);\r
497 }\r
498 \r
499 ///////////////////////////////////////////////////////// \r
500 \r
501 __inline void PRIMdrawFlatLine(OGLVertex* vertex1, OGLVertex* vertex2,OGLVertex* vertex3, OGLVertex* vertex4)\r
502 {\r
503 Vertex2 v[4];\r
504 \r
505 v[0].xyz.x = fpoint(vertex1->x);\r
506 v[0].xyz.y = fpoint(vertex1->y);\r
507 v[0].xyz.z = fpoint(vertex1->z);\r
508 v[0].rgba.r = vertex1->c.col[0];\r
509 v[0].rgba.g = vertex1->c.col[1];\r
510 v[0].rgba.b = vertex1->c.col[2];\r
511 v[0].rgba.a = vertex1->c.col[3];\r
512 \r
513 v[1].xyz.x = fpoint(vertex2->x);\r
514 v[1].xyz.y = fpoint(vertex2->y);\r
515 v[1].xyz.z = fpoint(vertex2->z);\r
516 v[1].rgba.r = vertex1->c.col[0];\r
517 v[1].rgba.g = vertex1->c.col[1];\r
518 v[1].rgba.b = vertex1->c.col[2];\r
519 v[1].rgba.a = vertex1->c.col[3];\r
520 \r
521 v[2].xyz.x = fpoint(vertex4->x);\r
522 v[2].xyz.y = fpoint(vertex4->y);\r
523 v[2].xyz.z = fpoint(vertex4->z);\r
524 v[2].rgba.r = vertex1->c.col[0];\r
525 v[2].rgba.g = vertex1->c.col[1];\r
526 v[2].rgba.b = vertex1->c.col[2];\r
527 v[2].rgba.a = vertex1->c.col[3];\r
528 \r
529 v[3].xyz.x = fpoint(vertex3->x);\r
530 v[3].xyz.y = fpoint(vertex3->y);\r
531 v[3].xyz.z = fpoint(vertex3->z);\r
532 v[3].rgba.r = vertex1->c.col[0];\r
533 v[3].rgba.g = vertex1->c.col[1];\r
534 v[3].rgba.b = vertex1->c.col[2];\r
535 v[3].rgba.a = vertex1->c.col[3];\r
536 \r
537 glEnableClientState(GL_VERTEX_ARRAY);\r
538 glEnableClientState(GL_COLOR_ARRAY);\r
539 \r
540 glVertexPointer(3, GL_FLOAT, sizeof(v[0]), &v[0].xyz);\r
541 glColorPointer(4, GL_UNSIGNED_BYTE, sizeof(v[0]), &v[0].rgba);\r
542 \r
543 glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);\r
544 glDisableClientState(GL_VERTEX_ARRAY);\r
545 glDisableClientState(GL_COLOR_ARRAY);\r
546 \r
547 \r
548 }\r
549 \r
550 ///////////////////////////////////////////////////////// \r
551      \r
552 __inline void PRIMdrawGouraudLine(OGLVertex* vertex1, OGLVertex* vertex2,OGLVertex* vertex3, OGLVertex* vertex4)\r
553 {\r
554         Vertex2 v[4];\r
555 \r
556 v[0].xyz.x = fpoint(vertex1->x);\r
557 v[0].xyz.y = fpoint(vertex1->y);\r
558 v[0].xyz.z = fpoint(vertex1->z);\r
559 v[0].rgba.r = vertex1->c.col[0];\r
560 v[0].rgba.g = vertex1->c.col[1];\r
561 v[0].rgba.b = vertex1->c.col[2];\r
562 v[0].rgba.a = vertex1->c.col[3];\r
563 \r
564 v[1].xyz.x = fpoint(vertex2->x);\r
565 v[1].xyz.y = fpoint(vertex2->y);\r
566 v[1].xyz.z = fpoint(vertex2->z);\r
567 v[1].rgba.r = vertex2->c.col[0];\r
568 v[1].rgba.g = vertex2->c.col[1];\r
569 v[1].rgba.b = vertex2->c.col[2];\r
570 v[1].rgba.a = vertex2->c.col[3];\r
571 \r
572 v[3].xyz.x = fpoint(vertex3->x);\r
573 v[3].xyz.y = fpoint(vertex3->y);\r
574 v[3].xyz.z = fpoint(vertex3->z);\r
575 v[3].rgba.r = vertex3->c.col[0];\r
576 v[3].rgba.g = vertex3->c.col[1];\r
577 v[3].rgba.b = vertex3->c.col[2];\r
578 v[3].rgba.a = vertex3->c.col[3];\r
579 \r
580 v[2].xyz.x = fpoint(vertex4->x);\r
581 v[2].xyz.y = fpoint(vertex4->y);\r
582 v[2].xyz.z = fpoint(vertex4->z);\r
583 v[2].rgba.r = vertex4->c.col[0];\r
584 v[2].rgba.g = vertex4->c.col[1];\r
585 v[2].rgba.b = vertex4->c.col[2];\r
586 v[2].rgba.a = vertex4->c.col[3];\r
587 \r
588 glEnableClientState(GL_VERTEX_ARRAY);\r
589 glEnableClientState(GL_COLOR_ARRAY);\r
590 \r
591 glVertexPointer(3, GL_FLOAT, sizeof(v[0]), &v[0].xyz);\r
592 glColorPointer(4, GL_UNSIGNED_BYTE, sizeof(v[0]), &v[0].rgba);\r
593 \r
594 glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);\r
595 glDisableClientState(GL_VERTEX_ARRAY);\r
596 glDisableClientState(GL_COLOR_ARRAY);\r
597 }\r
598 \r
599 ///////////////////////////////////////////////////////// \r
600              \r
601 __inline void PRIMdrawQuad(OGLVertex* vertex1, OGLVertex* vertex2, \r
602                            OGLVertex* vertex3, OGLVertex* vertex4) \r
603 {\r
604 Vec3f v[4];\r
605 \r
606 v[0].x = fpoint(vertex1->x);\r
607 v[0].y = fpoint(vertex1->y);\r
608 v[0].z = fpoint(vertex1->z);\r
609 \r
610 v[1].x = fpoint(vertex2->x);\r
611 v[1].y = fpoint(vertex2->y);\r
612 v[1].z = fpoint(vertex2->z);\r
613 \r
614 v[2].x = fpoint(vertex4->x);\r
615 v[2].y = fpoint(vertex4->y);\r
616 v[2].z = fpoint(vertex4->z);\r
617 \r
618 v[3].x = fpoint(vertex3->x);\r
619 v[3].y = fpoint(vertex3->y);\r
620 v[3].z = fpoint(vertex3->z);\r
621 \r
622 glEnableClientState(GL_VERTEX_ARRAY);\r
623 glVertexPointer(3, GL_FLOAT, sizeof(v[0]), &v[0]);\r
624 glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);\r
625 glDisableClientState(GL_VERTEX_ARRAY);\r
626 }\r
627 \r
628 ////////////////////////////////////////////////////////////////////////                                          \r
629 // Transparent blending settings\r
630 ////////////////////////////////////////////////////////////////////////\r
631 \r
632 static GLenum obm1=GL_ZERO;\r
633 static GLenum obm2=GL_ZERO;\r
634 \r
635 typedef struct SEMITRANSTAG\r
636 {\r
637  GLenum  srcFac;\r
638  GLenum  dstFac;\r
639  GLubyte alpha;\r
640 } SemiTransParams;\r
641 \r
642 SemiTransParams TransSets[4]=\r
643 {\r
644  {GL_SRC_ALPHA,GL_SRC_ALPHA,          127},\r
645  {GL_ONE,      GL_ONE,                255},\r
646  {GL_ZERO,     GL_ONE_MINUS_SRC_COLOR,255},\r
647  {GL_ONE_MINUS_SRC_ALPHA,GL_ONE,      192}\r
648 }; \r
649 \r
650 ////////////////////////////////////////////////////////////////////////\r
651 \r
652 void SetSemiTrans(void)\r
653 {\r
654 /*\r
655 * 0.5 x B + 0.5 x F\r
656 * 1.0 x B + 1.0 x F\r
657 * 1.0 x B - 1.0 x F\r
658 * 1.0 x B +0.25 x F\r
659 */\r
660 \r
661  if(!DrawSemiTrans)                                    // no semi trans at all?\r
662   {\r
663    if(bBlendEnable)\r
664     {glDisable(GL_BLEND);bBlendEnable=FALSE;}          // -> don't wanna blend\r
665    ubGloAlpha=ubGloColAlpha=255;                       // -> full alpha\r
666    return;                                             // -> and bye\r
667   }\r
668 \r
669  ubGloAlpha=ubGloColAlpha=TransSets[GlobalTextABR].alpha;\r
670 \r
671  if(!bBlendEnable)\r
672   {glEnable(GL_BLEND);bBlendEnable=TRUE;}              // wanna blend\r
673 \r
674  if(TransSets[GlobalTextABR].srcFac!=obm1 || \r
675     TransSets[GlobalTextABR].dstFac!=obm2)\r
676   {\r
677    //if(glBlendEquationEXTEx==NULL)\r
678     {\r
679      obm1=TransSets[GlobalTextABR].srcFac;\r
680      obm2=TransSets[GlobalTextABR].dstFac;\r
681      glBlendFunc(obm1,obm2);                           // set blend func\r
682     }\r
683    /*else\r
684    if(TransSets[GlobalTextABR].dstFac !=GL_ONE_MINUS_SRC_COLOR)\r
685     {\r
686      if(obm2==GL_ONE_MINUS_SRC_COLOR)\r
687       glBlendEquationEXTEx(FUNC_ADD_EXT);\r
688      obm1=TransSets[GlobalTextABR].srcFac;\r
689      obm2=TransSets[GlobalTextABR].dstFac;\r
690      glBlendFunc(obm1,obm2);                           // set blend func\r
691     }\r
692    else\r
693     {\r
694      glBlendEquationEXTEx(FUNC_REVERSESUBTRACT_EXT);\r
695      obm1=TransSets[GlobalTextABR].srcFac;\r
696      obm2=TransSets[GlobalTextABR].dstFac;\r
697      glBlendFunc(GL_ONE,GL_ONE);                       // set blend func\r
698     }*/\r
699   }\r
700 }\r
701 \r
702 void SetScanTrans(void)                                // blending for scan lines\r
703 {\r
704 /* if(glBlendEquationEXTEx!=NULL)\r
705   {\r
706    if(obm2==GL_ONE_MINUS_SRC_COLOR)\r
707     glBlendEquationEXTEx(FUNC_ADD_EXT);\r
708   }\r
709 */\r
710  obm1=TransSets[0].srcFac;\r
711  obm2=TransSets[0].dstFac;\r
712  glBlendFunc(obm1,obm2);                               // set blend func\r
713 }\r
714 \r
715 void SetScanTexTrans(void)                             // blending for scan mask texture\r
716 {\r
717 /* if(glBlendEquationEXTEx!=NULL)\r
718   {\r
719    if(obm2==GL_ONE_MINUS_SRC_COLOR)\r
720     glBlendEquationEXTEx(FUNC_ADD_EXT);\r
721   }\r
722 */\r
723  obm1=TransSets[2].srcFac;\r
724  obm2=TransSets[2].dstFac;\r
725  glBlendFunc(obm1,obm2);                               // set blend func\r
726 }\r
727 \r
728 ////////////////////////////////////////////////////////////////////////                                          \r
729 // multi pass in old 'Advanced blending' mode... got it from Lewpy :)\r
730 ////////////////////////////////////////////////////////////////////////                                          \r
731 \r
732 SemiTransParams MultiTexTransSets[4][2]=\r
733 {\r
734  {\r
735  {GL_ONE      ,GL_SRC_ALPHA,          127},\r
736  {GL_SRC_ALPHA,GL_ONE,                127}\r
737  },\r
738  {\r
739  {GL_ONE,      GL_SRC_ALPHA,          255},\r
740  {GL_SRC_ALPHA,GL_ONE,                255}\r
741  },\r
742  {\r
743  {GL_ZERO,     GL_ONE_MINUS_SRC_COLOR,255},\r
744  {GL_ZERO,     GL_ONE_MINUS_SRC_COLOR,255}\r
745  },\r
746  {\r
747  {GL_SRC_ALPHA,GL_ONE,                127},\r
748  {GL_ONE_MINUS_SRC_ALPHA,GL_ONE,      255}\r
749  }\r
750 }; \r
751 \r
752 ////////////////////////////////////////////////////////////////////////                                          \r
753 \r
754 SemiTransParams MultiColTransSets[4]=\r
755 {\r
756  {GL_ONE_MINUS_SRC_ALPHA,GL_SRC_ALPHA,127},\r
757  {GL_ONE,      GL_ONE,                255},\r
758  {GL_ZERO,     GL_ONE_MINUS_SRC_COLOR,255},\r
759  {GL_SRC_ALPHA,GL_ONE,                127}\r
760 }; \r
761 \r
762 ////////////////////////////////////////////////////////////////////////                                          \r
763 \r
764 void SetSemiTransMulti(int Pass)\r
765 {\r
766  static GLenum bm1=GL_ZERO;\r
767  static GLenum bm2=GL_ONE;\r
768 \r
769  ubGloAlpha=255;\r
770  ubGloColAlpha=255;\r
771  \r
772  // are we enabling SemiTransparent mode?\r
773  if(DrawSemiTrans)\r
774   {\r
775    if(bDrawTextured)\r
776     {\r
777      bm1=MultiTexTransSets[GlobalTextABR][Pass].srcFac;\r
778      bm2=MultiTexTransSets[GlobalTextABR][Pass].dstFac;\r
779      ubGloAlpha=MultiTexTransSets[GlobalTextABR][Pass].alpha;\r
780     }\r
781    // no texture\r
782    else\r
783     {\r
784      bm1=MultiColTransSets[GlobalTextABR].srcFac;\r
785      bm2=MultiColTransSets[GlobalTextABR].dstFac;\r
786      ubGloColAlpha=MultiColTransSets[GlobalTextABR].alpha;\r
787     }\r
788   }\r
789  // no shading\r
790  else\r
791   {\r
792    if(Pass==0)\r
793     {\r
794      // disable blending\r
795      bm1=GL_ONE;bm2=GL_ZERO;\r
796     }\r
797    else\r
798     {\r
799      // disable blending, but add src col a second time\r
800      bm1=GL_ONE;bm2=GL_ONE;\r
801     }\r
802   }\r
803 \r
804  if(!bBlendEnable)\r
805   {glEnable(GL_BLEND);bBlendEnable=TRUE;}              // wanna blend\r
806 \r
807  if(bm1!=obm1 || bm2!=obm2)\r
808   {\r
809    glBlendFunc(bm1,bm2);                               // set blend func\r
810    obm1=bm1;obm2=bm2;\r
811   }\r
812 }\r
813 \r
814 ////////////////////////////////////////////////////////////////////////                                          \r
815 // Set several rendering stuff including blending \r
816 ////////////////////////////////////////////////////////////////////////\r
817 \r
818 __inline void SetZMask3O(void)\r
819 {\r
820  if(iUseMask && DrawSemiTrans && !iSetMask)\r
821   {\r
822    vertex[0].z=vertex[1].z=vertex[2].z=gl_z;\r
823    gl_z+=0.00004f;\r
824   }\r
825 }\r
826 \r
827 __inline void SetZMask3(void)\r
828 {\r
829  if(iUseMask)\r
830   {\r
831    if(iSetMask || DrawSemiTrans)\r
832     {vertex[0].z=vertex[1].z=vertex[2].z=0.95f;}\r
833    else\r
834     {\r
835      vertex[0].z=vertex[1].z=vertex[2].z=gl_z;\r
836      gl_z+=0.00004f;\r
837     }\r
838   }\r
839 }\r
840 \r
841 __inline void SetZMask3NT(void)\r
842 {\r
843  if(iUseMask)\r
844   {\r
845    if(iSetMask)\r
846     {vertex[0].z=vertex[1].z=vertex[2].z=0.95f;}\r
847    else\r
848     {\r
849      vertex[0].z=vertex[1].z=vertex[2].z=gl_z;\r
850      gl_z+=0.00004f;\r
851     }\r
852   }\r
853 }\r
854 \r
855 ////////////////////////////////////////////////////////////////////////\r
856 \r
857 __inline void SetZMask4O(void)\r
858 {\r
859  if(iUseMask && DrawSemiTrans && !iSetMask)\r
860   {\r
861    vertex[0].z=vertex[1].z=vertex[2].z=vertex[3].z=gl_z;\r
862    gl_z+=0.00004f;\r
863   }\r
864 }\r
865 \r
866 __inline void SetZMask4(void)\r
867 {\r
868  if(iUseMask)\r
869   {\r
870    if(iSetMask || DrawSemiTrans)\r
871     {vertex[0].z=vertex[1].z=vertex[2].z=vertex[3].z=0.95f;}\r
872    else\r
873     {\r
874      vertex[0].z=vertex[1].z=vertex[2].z=vertex[3].z=gl_z;\r
875      gl_z+=0.00004f;\r
876     }\r
877   }\r
878 }\r
879 \r
880 __inline void SetZMask4NT(void)\r
881 {\r
882  if(iUseMask)\r
883   {\r
884    if(iSetMask==1)\r
885     {vertex[0].z=vertex[1].z=vertex[2].z=vertex[3].z=0.95f;}\r
886    else\r
887     {\r
888      vertex[0].z=vertex[1].z=vertex[2].z=vertex[3].z=gl_z;\r
889      gl_z+=0.00004f;\r
890     }\r
891   }\r
892 }\r
893 \r
894 __inline void SetZMask4SP(void)\r
895 {\r
896  if(iUseMask)\r
897   {\r
898    if(iSetMask==1)\r
899     {vertex[0].z=vertex[1].z=vertex[2].z=vertex[3].z=0.95f;}\r
900    else\r
901     {\r
902      if(bCheckMask)\r
903       {\r
904        vertex[0].z=vertex[1].z=vertex[2].z=vertex[3].z=gl_z;\r
905        gl_z+=0.00004f;\r
906       }\r
907      else\r
908       {vertex[0].z=vertex[1].z=vertex[2].z=vertex[3].z=0.95f;}\r
909     }\r
910   }\r
911 }\r
912 \r
913 ////////////////////////////////////////////////////////////////////////\r
914 \r
915 __inline void SetRenderState(unsigned long DrawAttributes)\r
916 {\r
917  bDrawNonShaded = (SHADETEXBIT(DrawAttributes)) ? TRUE : FALSE;\r
918  DrawSemiTrans = (SEMITRANSBIT(DrawAttributes)) ? TRUE : FALSE;\r
919 }                         \r
920 \r
921 ////////////////////////////////////////////////////////////////////////                                          \r
922 \r
923 __inline void SetRenderColor(unsigned long DrawAttributes)\r
924 {\r
925  if(bDrawNonShaded) {g_m1=g_m2=g_m3=128;}\r
926  else\r
927   {\r
928    g_m1=DrawAttributes&0xff;\r
929    g_m2=(DrawAttributes>>8)&0xff;\r
930    g_m3=(DrawAttributes>>16)&0xff;\r
931   }\r
932 }\r
933 \r
934 ////////////////////////////////////////////////////////////////////////                                          \r
935                                \r
936 void SetRenderMode(unsigned long DrawAttributes,BOOL bSCol)\r
937 {\r
938  if((bUseMultiPass) && (bDrawTextured) && !(bDrawNonShaded))\r
939       {bDrawMultiPass = TRUE; SetSemiTransMulti(0);}\r
940  else {bDrawMultiPass = FALSE;SetSemiTrans();}\r
941 \r
942  if(bDrawTextured)                                     // texture ? build it/get it from cache\r
943   {\r
944    GLuint currTex;\r
945    if(bUsingTWin)       currTex=LoadTextureWnd(GlobalTexturePage,GlobalTextTP, ulClutID);\r
946    else if(bUsingMovie) currTex=LoadTextureMovie();\r
947    else                 currTex=SelectSubTextureS(GlobalTextTP,ulClutID);\r
948 \r
949    if(gTexName!=currTex)\r
950     {gTexName=currTex;glBindTexture(GL_TEXTURE_2D,currTex);}\r
951 \r
952    if(!bTexEnabled)                                    // -> turn texturing on\r
953     {bTexEnabled=TRUE;glEnable(GL_TEXTURE_2D);}\r
954   }\r
955  else                                                  // no texture ?\r
956  if(bTexEnabled) \r
957   {bTexEnabled=FALSE;glDisable(GL_TEXTURE_2D);}        // -> turn texturing off\r
958 \r
959  if(bSCol)                                             // also set color ?\r
960   {\r
961    if((dwActFixes&4) && ((DrawAttributes&0x00ffffff)==0))\r
962      DrawAttributes|=0x007f7f7f;\r
963 \r
964    if(bDrawNonShaded)                                  // -> non shaded?\r
965     {\r
966 /*     if(bGLBlend)  vertex[0].c.lcol=0x7f7f7f;          // --> solid color...\r
967      else          */vertex[0].c.lcol=0xffffff;\r
968     }\r
969    else                                                // -> shaded?\r
970     {\r
971 //     if(!bUseMultiPass && !bGLBlend)                   // --> given color...\r
972           vertex[0].c.lcol=DoubleBGR2RGB(DrawAttributes);\r
973 //     else vertex[0].c.lcol=DrawAttributes;\r
974     }\r
975    vertex[0].c.col[3]=ubGloAlpha;                      // -> set color with\r
976    SETCOL(vertex[0]);                                  //    texture alpha\r
977   }\r
978  \r
979  if(bDrawSmoothShaded!=bOldSmoothShaded)               // shading changed?\r
980   {\r
981    if(bDrawSmoothShaded) glShadeModel(GL_SMOOTH);      // -> set actual shading\r
982    else                  glShadeModel(GL_FLAT);\r
983    bOldSmoothShaded=bDrawSmoothShaded;\r
984   }\r
985 }\r
986 \r
987 ////////////////////////////////////////////////////////////////////////                                          \r
988 // Set Opaque multipass color\r
989 ////////////////////////////////////////////////////////////////////////\r
990 \r
991 void SetOpaqueColor(unsigned long DrawAttributes)\r
992 {\r
993  if(bDrawNonShaded) return;                            // no shading? bye\r
994   \r
995  DrawAttributes=DoubleBGR2RGB(DrawAttributes);         // multipass is just half color, so double it on opaque pass\r
996  vertex[0].c.lcol=DrawAttributes|0xff000000;\r
997  SETCOL(vertex[0]);                                    // set color\r
998 }\r
999 \r
1000 ////////////////////////////////////////////////////////////////////////                                          \r
1001 // Fucking stupid screen coord checking\r
1002 ////////////////////////////////////////////////////////////////////////\r
1003 \r
1004 BOOL ClipVertexListScreen(void)\r
1005 {\r
1006  if (lx0 >= PSXDisplay.DisplayEnd.x)      goto NEXTSCRTEST;\r
1007  if (ly0 >= PSXDisplay.DisplayEnd.y)      goto NEXTSCRTEST;\r
1008  if (lx2 <  PSXDisplay.DisplayPosition.x) goto NEXTSCRTEST;\r
1009  if (ly2 <  PSXDisplay.DisplayPosition.y) goto NEXTSCRTEST;\r
1010 \r
1011  return TRUE;\r
1012 \r
1013 NEXTSCRTEST:\r
1014  if(PSXDisplay.InterlacedTest) return FALSE;\r
1015 \r
1016  if (lx0 >= PreviousPSXDisplay.DisplayEnd.x)      return FALSE;\r
1017  if (ly0 >= PreviousPSXDisplay.DisplayEnd.y)      return FALSE;\r
1018  if (lx2 <  PreviousPSXDisplay.DisplayPosition.x) return FALSE;\r
1019  if (ly2 <  PreviousPSXDisplay.DisplayPosition.y) return FALSE;\r
1020 \r
1021  return TRUE;\r
1022 }\r
1023 \r
1024 ////////////////////////////////////////////////////////////////////////\r
1025 \r
1026 BOOL bDrawOffscreenFront(void)\r
1027 {\r
1028  if(sxmin < PSXDisplay.DisplayPosition.x) return FALSE;   // must be complete in front\r
1029  if(symin < PSXDisplay.DisplayPosition.y) return FALSE;\r
1030  if(sxmax > PSXDisplay.DisplayEnd.x)      return FALSE;\r
1031  if(symax > PSXDisplay.DisplayEnd.y)      return FALSE;\r
1032  return TRUE;\r
1033 }\r
1034 \r
1035 BOOL bOnePointInFront(void)\r
1036 {\r
1037  if(sxmax< PSXDisplay.DisplayPosition.x)\r
1038   return FALSE;\r
1039 \r
1040  if(symax< PSXDisplay.DisplayPosition.y)\r
1041   return FALSE;\r
1042 \r
1043  if(sxmin>=PSXDisplay.DisplayEnd.x)\r
1044   return FALSE;\r
1045 \r
1046  if(symin>=PSXDisplay.DisplayEnd.y)\r
1047   return FALSE;\r
1048 \r
1049  return TRUE;\r
1050 }\r
1051  \r
1052 \r
1053 BOOL bOnePointInBack(void)\r
1054 {\r
1055  if(sxmax< PreviousPSXDisplay.DisplayPosition.x)\r
1056   return FALSE;\r
1057 \r
1058  if(symax< PreviousPSXDisplay.DisplayPosition.y)\r
1059   return FALSE;\r
1060 \r
1061  if(sxmin>=PreviousPSXDisplay.DisplayEnd.x)\r
1062   return FALSE;\r
1063 \r
1064  if(symin>=PreviousPSXDisplay.DisplayEnd.y)\r
1065   return FALSE;\r
1066 \r
1067  return TRUE;\r
1068 }\r
1069  \r
1070 BOOL bDrawOffscreen4(void)\r
1071 {\r
1072  BOOL bFront;short sW,sH;\r
1073 \r
1074  sxmax=max(lx0,max(lx1,max(lx2,lx3)));\r
1075  if(sxmax<drawX) return FALSE;\r
1076  sxmin=min(lx0,min(lx1,min(lx2,lx3)));\r
1077  if(sxmin>drawW) return FALSE;\r
1078  symax=max(ly0,max(ly1,max(ly2,ly3)));\r
1079  if(symax<drawY) return FALSE;\r
1080  symin=min(ly0,min(ly1,min(ly2,ly3)));\r
1081  if(symin>drawH) return FALSE;\r
1082 \r
1083  if(PSXDisplay.Disabled) return TRUE;                  // disabled? ever\r
1084 \r
1085  if(iOffscreenDrawing==1) return bFullVRam;\r
1086 \r
1087  if(dwActFixes&1 && iOffscreenDrawing==4)\r
1088   {\r
1089    if(PreviousPSXDisplay.DisplayPosition.x==PSXDisplay.DisplayPosition.x &&\r
1090       PreviousPSXDisplay.DisplayPosition.y==PSXDisplay.DisplayPosition.y &&\r
1091       PreviousPSXDisplay.DisplayEnd.x==PSXDisplay.DisplayEnd.x &&\r
1092       PreviousPSXDisplay.DisplayEnd.y==PSXDisplay.DisplayEnd.y)\r
1093     {\r
1094      bRenderFrontBuffer=TRUE;\r
1095      return FALSE;\r
1096     }\r
1097   }\r
1098 \r
1099  sW=drawW-1;sH=drawH-1;\r
1100  \r
1101  sxmin=min(sW,max(sxmin,drawX));\r
1102  sxmax=max(drawX,min(sxmax,sW));\r
1103  symin=min(sH,max(symin,drawY));\r
1104  symax=max(drawY,min(symax,sH));\r
1105 \r
1106  if(bOnePointInBack()) return bFullVRam;\r
1107 \r
1108  if(iOffscreenDrawing==2) \r
1109       bFront=bDrawOffscreenFront();\r
1110  else bFront=bOnePointInFront();\r
1111 \r
1112  if(bFront)\r
1113   {\r
1114    if(PSXDisplay.InterlacedTest) return bFullVRam;      // -> ok, no need for adjust\r
1115                                \r
1116    vertex[0].x=lx0 - PSXDisplay.DisplayPosition.x+PreviousPSXDisplay.Range.x0;\r
1117    vertex[1].x=lx1 - PSXDisplay.DisplayPosition.x+PreviousPSXDisplay.Range.x0;\r
1118    vertex[2].x=lx2 - PSXDisplay.DisplayPosition.x+PreviousPSXDisplay.Range.x0;\r
1119    vertex[3].x=lx3 - PSXDisplay.DisplayPosition.x+PreviousPSXDisplay.Range.x0;\r
1120    vertex[0].y=ly0 - PSXDisplay.DisplayPosition.y+PreviousPSXDisplay.Range.y0;\r
1121    vertex[1].y=ly1 - PSXDisplay.DisplayPosition.y+PreviousPSXDisplay.Range.y0;\r
1122    vertex[2].y=ly2 - PSXDisplay.DisplayPosition.y+PreviousPSXDisplay.Range.y0;\r
1123    vertex[3].y=ly3 - PSXDisplay.DisplayPosition.y+PreviousPSXDisplay.Range.y0;\r
1124 \r
1125    if(iOffscreenDrawing==4 && !(dwActFixes&1))         // -> frontbuffer wanted\r
1126     {\r
1127      bRenderFrontBuffer=TRUE;\r
1128      //return TRUE;\r
1129     }\r
1130    return bFullVRam;                                   // -> but no od\r
1131   }\r
1132 \r
1133  return TRUE;\r
1134 }\r
1135 \r
1136 ////////////////////////////////////////////////////////////////////////\r
1137  \r
1138 BOOL bDrawOffscreen3(void)\r
1139 {\r
1140  BOOL bFront;short sW,sH;\r
1141 \r
1142  sxmax=max(lx0,max(lx1,lx2));\r
1143  if(sxmax<drawX) return FALSE;\r
1144  sxmin=min(lx0,min(lx1,lx2));\r
1145  if(sxmin>drawW) return FALSE;\r
1146  symax=max(ly0,max(ly1,ly2));\r
1147  if(symax<drawY) return FALSE;\r
1148  symin=min(ly0,min(ly1,ly2));\r
1149  if(symin>drawH) return FALSE;\r
1150 \r
1151  if(PSXDisplay.Disabled) return TRUE;                  // disabled? ever\r
1152 \r
1153  if(iOffscreenDrawing==1) return bFullVRam;\r
1154 \r
1155  sW=drawW-1;sH=drawH-1;\r
1156  sxmin=min(sW,max(sxmin,drawX));\r
1157  sxmax=max(drawX,min(sxmax,sW));\r
1158  symin=min(sH,max(symin,drawY));\r
1159  symax=max(drawY,min(symax,sH));\r
1160 \r
1161  if(bOnePointInBack()) return bFullVRam;\r
1162 \r
1163  if(iOffscreenDrawing==2) \r
1164       bFront=bDrawOffscreenFront();\r
1165  else bFront=bOnePointInFront();\r
1166 \r
1167  if(bFront)\r
1168   {\r
1169    if(PSXDisplay.InterlacedTest) return bFullVRam;     // -> ok, no need for adjust\r
1170 \r
1171    vertex[0].x=lx0 - PSXDisplay.DisplayPosition.x+PreviousPSXDisplay.Range.x0;\r
1172    vertex[1].x=lx1 - PSXDisplay.DisplayPosition.x+PreviousPSXDisplay.Range.x0;\r
1173    vertex[2].x=lx2 - PSXDisplay.DisplayPosition.x+PreviousPSXDisplay.Range.x0;\r
1174    vertex[0].y=ly0 - PSXDisplay.DisplayPosition.y+PreviousPSXDisplay.Range.y0;\r
1175    vertex[1].y=ly1 - PSXDisplay.DisplayPosition.y+PreviousPSXDisplay.Range.y0;\r
1176    vertex[2].y=ly2 - PSXDisplay.DisplayPosition.y+PreviousPSXDisplay.Range.y0;\r
1177 \r
1178    if(iOffscreenDrawing==4)                            // -> frontbuffer wanted\r
1179     {\r
1180      bRenderFrontBuffer=TRUE;\r
1181    //  return TRUE;\r
1182     }\r
1183 \r
1184    return bFullVRam;                                   // -> but no od\r
1185   }\r
1186 \r
1187  return TRUE;\r
1188 }\r
1189 \r
1190 ////////////////////////////////////////////////////////////////////////\r
1191 \r
1192 BOOL FastCheckAgainstScreen(short imageX0,short imageY0,short imageX1,short imageY1)\r
1193 {\r
1194  PSXRect_t xUploadArea;\r
1195 \r
1196  imageX1 += imageX0;\r
1197  imageY1 += imageY0;\r
1198 \r
1199  if (imageX0 < PreviousPSXDisplay.DisplayPosition.x)\r
1200    xUploadArea.x0 = PreviousPSXDisplay.DisplayPosition.x;\r
1201  else\r
1202  if (imageX0 > PreviousPSXDisplay.DisplayEnd.x)\r
1203    xUploadArea.x0 = PreviousPSXDisplay.DisplayEnd.x;\r
1204  else\r
1205    xUploadArea.x0 = imageX0;\r
1206 \r
1207  if(imageX1 < PreviousPSXDisplay.DisplayPosition.x)\r
1208    xUploadArea.x1 = PreviousPSXDisplay.DisplayPosition.x;\r
1209  else\r
1210  if (imageX1 > PreviousPSXDisplay.DisplayEnd.x)\r
1211    xUploadArea.x1 = PreviousPSXDisplay.DisplayEnd.x;\r
1212  else\r
1213    xUploadArea.x1 = imageX1;\r
1214 \r
1215  if (imageY0 < PreviousPSXDisplay.DisplayPosition.y)\r
1216    xUploadArea.y0 = PreviousPSXDisplay.DisplayPosition.y;\r
1217  else\r
1218  if (imageY0 > PreviousPSXDisplay.DisplayEnd.y)\r
1219    xUploadArea.y0 = PreviousPSXDisplay.DisplayEnd.y;\r
1220  else\r
1221    xUploadArea.y0 = imageY0;\r
1222 \r
1223  if (imageY1 < PreviousPSXDisplay.DisplayPosition.y)\r
1224    xUploadArea.y1 = PreviousPSXDisplay.DisplayPosition.y;\r
1225  else\r
1226  if (imageY1 > PreviousPSXDisplay.DisplayEnd.y)\r
1227    xUploadArea.y1 = PreviousPSXDisplay.DisplayEnd.y;\r
1228  else\r
1229    xUploadArea.y1 = imageY1;\r
1230 \r
1231  if ((xUploadArea.x0 != xUploadArea.x1) && (xUploadArea.y0 != xUploadArea.y1))\r
1232       return TRUE;\r
1233  else return FALSE;\r
1234 }\r
1235 \r
1236 BOOL CheckAgainstScreen(short imageX0,short imageY0,short imageX1,short imageY1)\r
1237 {\r
1238  imageX1 += imageX0;\r
1239  imageY1 += imageY0;\r
1240 \r
1241  if (imageX0 < PreviousPSXDisplay.DisplayPosition.x)\r
1242    xrUploadArea.x0 = PreviousPSXDisplay.DisplayPosition.x;\r
1243  else\r
1244  if (imageX0 > PreviousPSXDisplay.DisplayEnd.x)\r
1245    xrUploadArea.x0 = PreviousPSXDisplay.DisplayEnd.x;\r
1246  else\r
1247    xrUploadArea.x0 = imageX0;\r
1248 \r
1249  if(imageX1 < PreviousPSXDisplay.DisplayPosition.x)\r
1250    xrUploadArea.x1 = PreviousPSXDisplay.DisplayPosition.x;\r
1251  else\r
1252  if (imageX1 > PreviousPSXDisplay.DisplayEnd.x)\r
1253    xrUploadArea.x1 = PreviousPSXDisplay.DisplayEnd.x;\r
1254  else\r
1255    xrUploadArea.x1 = imageX1;\r
1256 \r
1257  if (imageY0 < PreviousPSXDisplay.DisplayPosition.y)\r
1258    xrUploadArea.y0 = PreviousPSXDisplay.DisplayPosition.y;\r
1259  else\r
1260  if (imageY0 > PreviousPSXDisplay.DisplayEnd.y)\r
1261    xrUploadArea.y0 = PreviousPSXDisplay.DisplayEnd.y;\r
1262  else\r
1263    xrUploadArea.y0 = imageY0;\r
1264 \r
1265  if (imageY1 < PreviousPSXDisplay.DisplayPosition.y)\r
1266    xrUploadArea.y1 = PreviousPSXDisplay.DisplayPosition.y;\r
1267  else\r
1268  if (imageY1 > PreviousPSXDisplay.DisplayEnd.y)\r
1269    xrUploadArea.y1 = PreviousPSXDisplay.DisplayEnd.y;\r
1270  else\r
1271    xrUploadArea.y1 = imageY1;\r
1272 \r
1273  if ((xrUploadArea.x0 != xrUploadArea.x1) && (xrUploadArea.y0 != xrUploadArea.y1))\r
1274       return TRUE;\r
1275  else return FALSE;\r
1276 }\r
1277 \r
1278 BOOL FastCheckAgainstFrontScreen(short imageX0,short imageY0,short imageX1,short imageY1)\r
1279 {\r
1280  PSXRect_t xUploadArea;\r
1281 \r
1282  imageX1 += imageX0;\r
1283  imageY1 += imageY0;\r
1284 \r
1285  if (imageX0 < PSXDisplay.DisplayPosition.x)\r
1286    xUploadArea.x0 = PSXDisplay.DisplayPosition.x;\r
1287  else\r
1288  if (imageX0 > PSXDisplay.DisplayEnd.x)\r
1289    xUploadArea.x0 = PSXDisplay.DisplayEnd.x;\r
1290  else\r
1291    xUploadArea.x0 = imageX0;\r
1292 \r
1293  if(imageX1 < PSXDisplay.DisplayPosition.x)\r
1294    xUploadArea.x1 = PSXDisplay.DisplayPosition.x;\r
1295  else\r
1296  if (imageX1 > PSXDisplay.DisplayEnd.x)\r
1297    xUploadArea.x1 = PSXDisplay.DisplayEnd.x;\r
1298  else\r
1299    xUploadArea.x1 = imageX1;\r
1300 \r
1301  if (imageY0 < PSXDisplay.DisplayPosition.y)\r
1302    xUploadArea.y0 = PSXDisplay.DisplayPosition.y;\r
1303  else\r
1304  if (imageY0 > PSXDisplay.DisplayEnd.y)\r
1305    xUploadArea.y0 = PSXDisplay.DisplayEnd.y;\r
1306  else\r
1307    xUploadArea.y0 = imageY0;\r
1308 \r
1309  if (imageY1 < PSXDisplay.DisplayPosition.y)\r
1310    xUploadArea.y1 = PSXDisplay.DisplayPosition.y;\r
1311  else\r
1312  if (imageY1 > PSXDisplay.DisplayEnd.y)\r
1313    xUploadArea.y1 = PSXDisplay.DisplayEnd.y;\r
1314  else\r
1315    xUploadArea.y1 = imageY1;\r
1316 \r
1317  if ((xUploadArea.x0 != xUploadArea.x1) && (xUploadArea.y0 != xUploadArea.y1))\r
1318       return TRUE; \r
1319  else return FALSE;\r
1320 }\r
1321 \r
1322 BOOL CheckAgainstFrontScreen(short imageX0,short imageY0,short imageX1,short imageY1)\r
1323 {\r
1324  imageX1 += imageX0;\r
1325  imageY1 += imageY0;\r
1326 \r
1327  if (imageX0 < PSXDisplay.DisplayPosition.x)\r
1328    xrUploadArea.x0 = PSXDisplay.DisplayPosition.x;\r
1329  else\r
1330  if (imageX0 > PSXDisplay.DisplayEnd.x)\r
1331    xrUploadArea.x0 = PSXDisplay.DisplayEnd.x;\r
1332  else\r
1333    xrUploadArea.x0 = imageX0;\r
1334 \r
1335  if(imageX1 < PSXDisplay.DisplayPosition.x)\r
1336    xrUploadArea.x1 = PSXDisplay.DisplayPosition.x;\r
1337  else\r
1338  if (imageX1 > PSXDisplay.DisplayEnd.x)\r
1339    xrUploadArea.x1 = PSXDisplay.DisplayEnd.x;\r
1340  else\r
1341    xrUploadArea.x1 = imageX1;\r
1342 \r
1343  if (imageY0 < PSXDisplay.DisplayPosition.y)\r
1344    xrUploadArea.y0 = PSXDisplay.DisplayPosition.y;\r
1345  else\r
1346  if (imageY0 > PSXDisplay.DisplayEnd.y)\r
1347    xrUploadArea.y0 = PSXDisplay.DisplayEnd.y;\r
1348  else\r
1349    xrUploadArea.y0 = imageY0;\r
1350 \r
1351  if (imageY1 < PSXDisplay.DisplayPosition.y)\r
1352    xrUploadArea.y1 = PSXDisplay.DisplayPosition.y;\r
1353  else\r
1354  if (imageY1 > PSXDisplay.DisplayEnd.y)\r
1355    xrUploadArea.y1 = PSXDisplay.DisplayEnd.y;\r
1356  else\r
1357    xrUploadArea.y1 = imageY1;\r
1358 \r
1359  if ((xrUploadArea.x0 != xrUploadArea.x1) && (xrUploadArea.y0 != xrUploadArea.y1))\r
1360       return TRUE; \r
1361  else return FALSE;\r
1362 }\r
1363 \r
1364 ////////////////////////////////////////////////////////////////////////\r
1365 \r
1366 void PrepareFullScreenUpload (long Position)\r
1367 {\r
1368  if (Position==-1)                                     // rgb24\r
1369   {\r
1370    if(PSXDisplay.Interlaced)\r
1371     {\r
1372      xrUploadArea.x0 = PSXDisplay.DisplayPosition.x;\r
1373      xrUploadArea.x1 = PSXDisplay.DisplayEnd.x;\r
1374      xrUploadArea.y0 = PSXDisplay.DisplayPosition.y;\r
1375      xrUploadArea.y1 = PSXDisplay.DisplayEnd.y;\r
1376     }\r
1377    else\r
1378     {\r
1379      xrUploadArea.x0 = PreviousPSXDisplay.DisplayPosition.x;\r
1380      xrUploadArea.x1 = PreviousPSXDisplay.DisplayEnd.x;\r
1381      xrUploadArea.y0 = PreviousPSXDisplay.DisplayPosition.y;\r
1382      xrUploadArea.y1 = PreviousPSXDisplay.DisplayEnd.y;\r
1383     }\r
1384 \r
1385    if(bNeedRGB24Update)\r
1386     {\r
1387      if(lClearOnSwap) \r
1388       {\r
1389 //       lClearOnSwap=0;\r
1390       }\r
1391      else    \r
1392      if(PSXDisplay.Interlaced && PreviousPSXDisplay.RGB24<2) // in interlaced mode we upload at least two full frames (GT1 menu)\r
1393       {\r
1394        PreviousPSXDisplay.RGB24++;\r
1395       }\r
1396      else\r
1397       {\r
1398        xrUploadArea.y1 = min(xrUploadArea.y0+xrUploadAreaRGB24.y1,xrUploadArea.y1);\r
1399        xrUploadArea.y0+=xrUploadAreaRGB24.y0;\r
1400       }\r
1401     }\r
1402   }\r
1403  else\r
1404  if (Position)\r
1405   {\r
1406    xrUploadArea.x0 = PSXDisplay.DisplayPosition.x;\r
1407    xrUploadArea.x1 = PSXDisplay.DisplayEnd.x;\r
1408    xrUploadArea.y0 = PSXDisplay.DisplayPosition.y;\r
1409    xrUploadArea.y1 = PSXDisplay.DisplayEnd.y;\r
1410   }\r
1411  else\r
1412   {\r
1413    xrUploadArea.x0 = PreviousPSXDisplay.DisplayPosition.x;\r
1414    xrUploadArea.x1 = PreviousPSXDisplay.DisplayEnd.x;\r
1415    xrUploadArea.y0 = PreviousPSXDisplay.DisplayPosition.y;\r
1416    xrUploadArea.y1 = PreviousPSXDisplay.DisplayEnd.y;\r
1417   }\r
1418 \r
1419  if (xrUploadArea.x0 < 0)               xrUploadArea.x0 = 0;\r
1420  else\r
1421  if (xrUploadArea.x0 > 1023)            xrUploadArea.x0 = 1023;\r
1422 \r
1423  if (xrUploadArea.x1 < 0)               xrUploadArea.x1 = 0;\r
1424  else\r
1425  if (xrUploadArea.x1 > 1024)            xrUploadArea.x1 = 1024;\r
1426 \r
1427  if (xrUploadArea.y0 < 0)               xrUploadArea.y0 = 0;\r
1428  else\r
1429  if (xrUploadArea.y0 > iGPUHeightMask)  xrUploadArea.y0 = iGPUHeightMask;\r
1430 \r
1431  if (xrUploadArea.y1 < 0)               xrUploadArea.y1 = 0;\r
1432  else\r
1433  if (xrUploadArea.y1 > iGPUHeight)      xrUploadArea.y1 = iGPUHeight;\r
1434 \r
1435  if (PSXDisplay.RGB24)\r
1436   {\r
1437    InvalidateTextureArea(xrUploadArea.x0,xrUploadArea.y0,xrUploadArea.x1-xrUploadArea.x0,xrUploadArea.y1-xrUploadArea.y0);\r
1438   }\r
1439 }\r
1440 \r
1441 ////////////////////////////////////////////////////////////////////////\r
1442 // Upload screen (MDEC and such)\r
1443 ////////////////////////////////////////////////////////////////////////\r
1444 ////////////////////////////////////////////////////////////////////////\r
1445 \r
1446 unsigned char * LoadDirectMovieFast(void);\r
1447 \r
1448 void UploadScreenEx(long Position)\r
1449 {\r
1450  short ya,yb,xa,xb,x, y, YStep, XStep, U, UStep,ux[4],vy[4];\r
1451 \r
1452  if(!PSXDisplay.DisplayMode.x) return;\r
1453  if(!PSXDisplay.DisplayMode.y) return;\r
1454 \r
1455  glDisable(GL_SCISSOR_TEST);\r
1456  glShadeModel(GL_FLAT);\r
1457  bOldSmoothShaded=FALSE;\r
1458  glDisable(GL_BLEND);\r
1459  bBlendEnable=FALSE;\r
1460  glDisable(GL_TEXTURE_2D);\r
1461  bTexEnabled=FALSE;\r
1462  glDisable(GL_ALPHA_TEST);\r
1463 \r
1464  //glPixelZoom(((float)rRatioRect.right)/((float)PSXDisplay.DisplayMode.x),\r
1465  //            -1.0f*(((float)rRatioRect.bottom)/((float)PSXDisplay.DisplayMode.y)));\r
1466                                                       \r
1467  //----------------------------------------------------//\r
1468 \r
1469  YStep = 256;                                          // max texture size\r
1470  XStep = 256;\r
1471  UStep = (PSXDisplay.RGB24 ? 128 : 0);\r
1472  ya    = xrUploadArea.y0;\r
1473  yb    = xrUploadArea.y1;\r
1474  xa    = xrUploadArea.x0;\r
1475  xb    = xrUploadArea.x1;\r
1476  \r
1477  for(y=ya;y<=yb;y+=YStep)                              // loop y\r
1478   {\r
1479    U = 0;\r
1480    for(x=xa;x<=xb;x+=XStep)                            // loop x\r
1481     {\r
1482      ly0 = ly1 = y;                                    // -> get y coords\r
1483      ly2 = y + YStep;\r
1484      if (ly2 > yb) ly2 = yb;\r
1485      ly3 = ly2;\r
1486 \r
1487      lx0 = lx3 = x;                                    // -> get x coords\r
1488      lx1 = x + XStep;\r
1489      if (lx1 > xb) lx1 = xb;\r
1490 \r
1491      lx2 = lx1;\r
1492 \r
1493      ux[0]=ux[3]=(xa - x);                             // -> set tex x coords\r
1494      if (ux[0] < 0) ux[0]=ux[3]=0;\r
1495      ux[2]=ux[1]=(xb - x);\r
1496      if (ux[2] > 256) ux[2]=ux[1]=256;\r
1497 \r
1498      vy[0]=vy[1]=(ya - y);                             // -> set tex y coords\r
1499      if (vy[0] < 0) vy[0]=vy[1]=0;\r
1500      vy[2]=vy[3]=(yb - y);\r
1501      if (vy[2] > 256) vy[2]=vy[3]=256;\r
1502 \r
1503      if ((ux[0] >= ux[2]) ||                           // -> cheaters never win...\r
1504          (vy[0] >= vy[2])) continue;                   //    (but winners always cheat...)\r
1505                 \r
1506      xrMovieArea.x0=lx0+U; xrMovieArea.y0=ly0;\r
1507      xrMovieArea.x1=lx2+U; xrMovieArea.y1=ly2;\r
1508      \r
1509      offsetScreenUpload(Position);\r
1510 \r
1511      //glRasterPos2f(vertex[0].x,vertex[0].y);\r
1512 \r
1513      //glDrawPixels(xrMovieArea.x1-xrMovieArea.x0,\r
1514      //             xrMovieArea.y1-xrMovieArea.y0,\r
1515      //             GL_RGBA,GL_UNSIGNED_BYTE,\r
1516                   LoadDirectMovieFast();//);\r
1517 \r
1518      U+=UStep;\r
1519     }\r
1520   }\r
1521 \r
1522  //----------------------------------------------------//\r
1523 \r
1524 // glPixelZoom(1.0F,1.0F);\r
1525 \r
1526  glEnable(GL_ALPHA_TEST);\r
1527  glEnable(GL_SCISSOR_TEST);\r
1528 }\r
1529 \r
1530 ////////////////////////////////////////////////////////////////////////\r
1531 \r
1532 void UploadScreen(long Position)\r
1533 {\r
1534  short x, y, YStep, XStep, U, s, UStep,ux[4],vy[4];\r
1535  short xa,xb,ya,yb;\r
1536 \r
1537  if(xrUploadArea.x0>1023) xrUploadArea.x0=1023;\r
1538  if(xrUploadArea.x1>1024) xrUploadArea.x1=1024;\r
1539  if(xrUploadArea.y0>iGPUHeightMask)  xrUploadArea.y0=iGPUHeightMask;\r
1540  if(xrUploadArea.y1>iGPUHeight)      xrUploadArea.y1=iGPUHeight;\r
1541 \r
1542  if(xrUploadArea.x0==xrUploadArea.x1) return;\r
1543  if(xrUploadArea.y0==xrUploadArea.y1) return;\r
1544 \r
1545  if(PSXDisplay.Disabled && iOffscreenDrawing<4) return;\r
1546 \r
1547  iDrawnSomething   = 2;\r
1548  iLastRGB24=PSXDisplay.RGB24+1;\r
1549 \r
1550  if(bSkipNextFrame) return;\r
1551 \r
1552  if(dwActFixes & 2) {UploadScreenEx(Position);return;}\r
1553 \r
1554  bUsingMovie       = TRUE;\r
1555  bDrawTextured     = TRUE;                             // just doing textures\r
1556  bDrawSmoothShaded = FALSE;\r
1557 \r
1558 /* if(bGLBlend) vertex[0].c.lcol=0xff7f7f7f;             // set solid col\r
1559  else          */vertex[0].c.lcol=0xffffffff;\r
1560  SETCOL(vertex[0]); \r
1561 \r
1562  SetOGLDisplaySettings(0);\r
1563 \r
1564  YStep = 256;                                          // max texture size\r
1565  XStep = 256;\r
1566 \r
1567  UStep = (PSXDisplay.RGB24 ? 128 : 0);\r
1568  \r
1569  ya=xrUploadArea.y0;\r
1570  yb=xrUploadArea.y1;\r
1571  xa=xrUploadArea.x0;\r
1572  xb=xrUploadArea.x1;\r
1573 \r
1574  for(y=ya;y<=yb;y+=YStep)                              // loop y\r
1575   {\r
1576    U = 0;\r
1577    for(x=xa;x<=xb;x+=XStep)                            // loop x\r
1578     {\r
1579      ly0 = ly1 = y;                                    // -> get y coords\r
1580      ly2 = y + YStep;\r
1581      if (ly2 > yb) ly2 = yb;\r
1582      ly3 = ly2;\r
1583 \r
1584      lx0 = lx3 = x;                                    // -> get x coords\r
1585      lx1 = x + XStep;\r
1586      if (lx1 > xb) lx1 = xb;\r
1587 \r
1588      lx2 = lx1;\r
1589 \r
1590      ux[0]=ux[3]=(xa - x);                             // -> set tex x coords\r
1591      if (ux[0] < 0) ux[0]=ux[3]=0;\r
1592      ux[2]=ux[1]=(xb - x);\r
1593      if (ux[2] > 256) ux[2]=ux[1]=256;\r
1594 \r
1595      vy[0]=vy[1]=(ya - y);                             // -> set tex y coords\r
1596      if (vy[0] < 0) vy[0]=vy[1]=0;\r
1597      vy[2]=vy[3]=(yb - y);\r
1598      if (vy[2] > 256) vy[2]=vy[3]=256;\r
1599 \r
1600      if ((ux[0] >= ux[2]) ||                           // -> cheaters never win...\r
1601          (vy[0] >= vy[2])) continue;                   //    (but winners always cheat...)\r
1602                 \r
1603      xrMovieArea.x0=lx0+U; xrMovieArea.y0=ly0;\r
1604      xrMovieArea.x1=lx2+U; xrMovieArea.y1=ly2;\r
1605 \r
1606      s=ux[2] - ux[0]; if(s>255) s=255;\r
1607 \r
1608      gl_ux[2] = gl_ux[1] = s;\r
1609      s=vy[2] - vy[0]; if(s>255) s=255;\r
1610      gl_vy[2] = gl_vy[3] = s;\r
1611      gl_ux[0] = gl_ux[3] = gl_vy[0] = gl_vy[1] = 0;\r
1612 \r
1613      SetRenderState((unsigned long)0x01000000);\r
1614      SetRenderMode((unsigned long)0x01000000, FALSE);  // upload texture data\r
1615      offsetScreenUpload(Position);\r
1616      assignTextureVRAMWrite();\r
1617 \r
1618      PRIMdrawTexturedQuad(&vertex[0], &vertex[1], &vertex[2], &vertex[3]);\r
1619 \r
1620      U+=UStep;\r
1621     }\r
1622   }\r
1623 \r
1624  bUsingMovie=FALSE;                                    // done...\r
1625  bDisplayNotSet = TRUE;\r
1626 }\r
1627 \r
1628 ////////////////////////////////////////////////////////////////////////\r
1629 // Detect next screen\r
1630 ////////////////////////////////////////////////////////////////////////\r
1631 \r
1632 BOOL IsCompleteInsideNextScreen(short x, short y, short xoff, short yoff)\r
1633 {        \r
1634  if (x > PSXDisplay.DisplayPosition.x+1)     return FALSE;\r
1635  if ((x + xoff) < PSXDisplay.DisplayEnd.x-1) return FALSE;\r
1636  yoff+=y;\r
1637  if (y >= PSXDisplay.DisplayPosition.y &&\r
1638      y <= PSXDisplay.DisplayEnd.y )\r
1639   {\r
1640    if ((yoff) >= PSXDisplay.DisplayPosition.y &&\r
1641        (yoff) <= PSXDisplay.DisplayEnd.y ) return TRUE;\r
1642   }   \r
1643  if (y > PSXDisplay.DisplayPosition.y+1) return FALSE;\r
1644  if (yoff < PSXDisplay.DisplayEnd.y-1)   return FALSE;\r
1645  return TRUE;\r
1646 }\r
1647 \r
1648 BOOL IsPrimCompleteInsideNextScreen(short x, short y, short xoff, short yoff)\r
1649 {\r
1650  x+=PSXDisplay.DrawOffset.x;\r
1651  if (x > PSXDisplay.DisplayPosition.x+1) return FALSE;\r
1652  y+=PSXDisplay.DrawOffset.y;\r
1653  if (y > PSXDisplay.DisplayPosition.y+1) return FALSE;\r
1654  xoff+=PSXDisplay.DrawOffset.x;\r
1655  if (xoff < PSXDisplay.DisplayEnd.x-1)   return FALSE;\r
1656  yoff+=PSXDisplay.DrawOffset.y;\r
1657  if (yoff < PSXDisplay.DisplayEnd.y-1)   return FALSE;\r
1658  return TRUE;\r
1659 }\r
1660 \r
1661 BOOL IsInsideNextScreen(short x, short y, short xoff, short yoff)\r
1662 {                    \r
1663  if (x > PSXDisplay.DisplayEnd.x) return FALSE;\r
1664  if (y > PSXDisplay.DisplayEnd.y) return FALSE;\r
1665  if ((x + xoff) < PSXDisplay.DisplayPosition.x) return FALSE;\r
1666  if ((y + yoff) < PSXDisplay.DisplayPosition.y) return FALSE;\r
1667  return TRUE;\r
1668 }\r
1669 \r
1670 ////////////////////////////////////////////////////////////////////////\r
1671 // mask stuff...\r
1672 ////////////////////////////////////////////////////////////////////////\r
1673 \r
1674 //Mask1    Set mask bit while drawing. 1 = on\r
1675 //Mask2    Do not draw to mask areas. 1= on\r
1676 \r
1677 void cmdSTP(unsigned char * baseAddr)\r
1678 {\r
1679  unsigned long gdata = ((unsigned long*)baseAddr)[0];\r
1680 \r
1681  STATUSREG&=~0x1800;                                   // clear the necessary bits\r
1682  STATUSREG|=((gdata & 0x03) << 11);                    // set the current bits\r
1683 \r
1684  if(!iUseMask) return;\r
1685 \r
1686  if(gdata&1) {sSetMask=0x8000;lSetMask=0x80008000;iSetMask=1;}\r
1687  else        {sSetMask=0;     lSetMask=0;         iSetMask=0;}\r
1688 \r
1689  if(gdata&2) \r
1690   {\r
1691    if(!(gdata&1)) iSetMask=2;\r
1692    bCheckMask=TRUE;\r
1693    if(iDepthFunc==0) return;\r
1694    iDepthFunc=0;\r
1695    glDepthFunc(GL_LESS);\r
1696   }\r
1697  else\r
1698   {\r
1699    bCheckMask=FALSE;\r
1700    if(iDepthFunc==1) return;\r
1701    glDepthFunc(GL_ALWAYS);\r
1702    iDepthFunc=1;\r
1703   }\r
1704 }\r
1705 \r
1706 ////////////////////////////////////////////////////////////////////////\r
1707 // cmd: Set texture page infos\r
1708 ////////////////////////////////////////////////////////////////////////\r
1709 \r
1710 void cmdTexturePage(unsigned char * baseAddr)\r
1711 {\r
1712  unsigned long gdata = ((unsigned long*)baseAddr)[0];\r
1713  UpdateGlobalTP((unsigned short)gdata);\r
1714  GlobalTextREST = (gdata&0x00ffffff)>>9;\r
1715 }\r
1716 \r
1717 ////////////////////////////////////////////////////////////////////////\r
1718 // cmd: turn on/off texture window\r
1719 ////////////////////////////////////////////////////////////////////////\r
1720 \r
1721 void cmdTextureWindow(unsigned char *baseAddr)\r
1722 {\r
1723  unsigned long gdata = ((unsigned long*)baseAddr)[0];\r
1724 \r
1725  unsigned long YAlign,XAlign;\r
1726 \r
1727  ulGPUInfoVals[INFO_TW]=gdata&0xFFFFF;\r
1728 \r
1729  if(gdata & 0x020)\r
1730   TWin.Position.y1 = 8;    // xxxx1\r
1731  else if (gdata & 0x040)\r
1732   TWin.Position.y1 = 16;   // xxx10\r
1733  else if (gdata & 0x080)\r
1734   TWin.Position.y1 = 32;   // xx100\r
1735  else if (gdata & 0x100)\r
1736   TWin.Position.y1 = 64;   // x1000\r
1737  else if (gdata & 0x200)\r
1738   TWin.Position.y1 = 128;  // 10000\r
1739  else\r
1740   TWin.Position.y1 = 256;  // 00000\r
1741 \r
1742   // Texture window size is determined by the least bit set of the relevant 5 bits\r
1743 \r
1744  if (gdata & 0x001)\r
1745   TWin.Position.x1 = 8;    // xxxx1\r
1746  else if (gdata & 0x002)\r
1747   TWin.Position.x1 = 16;   // xxx10\r
1748  else if (gdata & 0x004)\r
1749   TWin.Position.x1 = 32;   // xx100\r
1750  else if (gdata & 0x008)\r
1751   TWin.Position.x1 = 64;   // x1000\r
1752  else if (gdata & 0x010)\r
1753   TWin.Position.x1 = 128;  // 10000\r
1754  else\r
1755   TWin.Position.x1 = 256;  // 00000\r
1756 \r
1757  // Re-calculate the bit field, because we can't trust what is passed in the data\r
1758 \r
1759  YAlign = (unsigned long)(32 - (TWin.Position.y1 >> 3));\r
1760  XAlign = (unsigned long)(32 - (TWin.Position.x1 >> 3));\r
1761 \r
1762  // Absolute position of the start of the texture window\r
1763 \r
1764  TWin.Position.y0 = (short)(((gdata >> 15) & YAlign) << 3);\r
1765  TWin.Position.x0 = (short)(((gdata >> 10) & XAlign) << 3);\r
1766 \r
1767  if((TWin.Position.x0 == 0 &&                          // tw turned off\r
1768      TWin.Position.y0 == 0 &&\r
1769      TWin.Position.x1 == 0 &&\r
1770      TWin.Position.y1 == 0) ||\r
1771      (TWin.Position.x1 == 256 &&\r
1772       TWin.Position.y1 == 256))\r
1773   {\r
1774    bUsingTWin = FALSE;                                 // -> just do it\r
1775 \r
1776 #ifdef OWNSCALE\r
1777    TWin.UScaleFactor = 1.0f;\r
1778    TWin.VScaleFactor = 1.0f;\r
1779 #else\r
1780    TWin.UScaleFactor = \r
1781    TWin.VScaleFactor = 1.0f/256.0f;\r
1782 #endif\r
1783   }\r
1784  else                                                  // tw turned on\r
1785   {\r
1786    bUsingTWin = TRUE;\r
1787 \r
1788    TWin.OPosition.y1 = TWin.Position.y1;               // -> get psx sizes\r
1789    TWin.OPosition.x1 = TWin.Position.x1;              \r
1790 \r
1791    if(TWin.Position.x1<=2)   TWin.Position.x1=2;       // -> set OGL sizes\r
1792    else\r
1793    if(TWin.Position.x1<=4)   TWin.Position.x1=4;\r
1794    else\r
1795    if(TWin.Position.x1<=8)   TWin.Position.x1=8;\r
1796    else\r
1797    if(TWin.Position.x1<=16)  TWin.Position.x1=16;\r
1798    else\r
1799    if(TWin.Position.x1<=32)  TWin.Position.x1=32;\r
1800    else\r
1801    if(TWin.Position.x1<=64)  TWin.Position.x1=64;\r
1802    else\r
1803    if(TWin.Position.x1<=128) TWin.Position.x1=128;\r
1804    else\r
1805    if(TWin.Position.x1<=256) TWin.Position.x1=256;\r
1806    \r
1807    if(TWin.Position.y1<=2)   TWin.Position.y1=2;\r
1808    else\r
1809    if(TWin.Position.y1<=4)   TWin.Position.y1=4;\r
1810    else\r
1811    if(TWin.Position.y1<=8)   TWin.Position.y1=8;\r
1812    else\r
1813    if(TWin.Position.y1<=16)  TWin.Position.y1=16;\r
1814    else\r
1815    if(TWin.Position.y1<=32)  TWin.Position.y1=32;\r
1816    else\r
1817    if(TWin.Position.y1<=64)  TWin.Position.y1=64;\r
1818    else\r
1819    if(TWin.Position.y1<=128) TWin.Position.y1=128;\r
1820    else\r
1821    if(TWin.Position.y1<=256) TWin.Position.y1=256;\r
1822 \r
1823 #ifdef OWNSCALE\r
1824    TWin.UScaleFactor = (float)TWin.Position.x1;\r
1825    TWin.VScaleFactor = (float)TWin.Position.y1;\r
1826 #else\r
1827    TWin.UScaleFactor = ((float)TWin.Position.x1)/256.0f; // -> set scale factor\r
1828    TWin.VScaleFactor = ((float)TWin.Position.y1)/256.0f;\r
1829 #endif\r
1830   }\r
1831 }\r
1832 \r
1833 ////////////////////////////////////////////////////////////////////////\r
1834 // mmm, Lewpy uses that in TileS ... I don't ;)\r
1835 ////////////////////////////////////////////////////////////////////////\r
1836 \r
1837 /*\r
1838 void ClampToPSXDrawAreaOffset(short *x0, short *y0, short *x1, short *y1)\r
1839 {\r
1840  if (*x0 < PSXDisplay.DrawArea.x0)\r
1841   {\r
1842    *x1 -= (PSXDisplay.DrawArea.x0 - *x0);\r
1843    *x0 = PSXDisplay.DrawArea.x0;\r
1844   }\r
1845  else\r
1846  if (*x0 > PSXDisplay.DrawArea.x1)\r
1847   {\r
1848    *x0 = PSXDisplay.DrawArea.x1;\r
1849    *x1 = 0;\r
1850   }\r
1851 \r
1852  if (*y0 < PSXDisplay.DrawArea.y0)\r
1853   {\r
1854    *y1 -= (PSXDisplay.DrawArea.y0 - *y0);\r
1855    *y0 = PSXDisplay.DrawArea.y0;\r
1856   }\r
1857  else\r
1858  if (*y0 > PSXDisplay.DrawArea.y1)\r
1859   {\r
1860    *y0 = PSXDisplay.DrawArea.y1;\r
1861    *y1 = 0;\r
1862   }\r
1863 \r
1864  if (*x1 < 0) *x1 = 0;\r
1865 \r
1866  if ((*x1 + *x0) > PSXDisplay.DrawArea.x1)\r
1867   *x1 = (PSXDisplay.DrawArea.x1 -  *x0 + 1);\r
1868 \r
1869  if (*y1 < 0) *y1 = 0;\r
1870 \r
1871  if ((*y1 + *y0) > PSXDisplay.DrawArea.y1)\r
1872   *y1 = (PSXDisplay.DrawArea.y1 -  *y0 + 1);\r
1873 }\r
1874 */\r
1875 \r
1876 ////////////////////////////////////////////////////////////////////////\r
1877 // Check draw area dimensions\r
1878 ////////////////////////////////////////////////////////////////////////\r
1879 \r
1880 void ClampToPSXScreen(short *x0, short *y0, short *x1, short *y1)\r
1881 {\r
1882  if (*x0 < 0)               *x0 = 0;\r
1883  else\r
1884  if (*x0 > 1023)            *x0 = 1023;\r
1885             \r
1886  if (*x1 < 0)               *x1 = 0;\r
1887  else\r
1888  if (*x1 > 1023)            *x1 = 1023;\r
1889 \r
1890  if (*y0 < 0)               *y0 = 0;\r
1891  else\r
1892  if (*y0 > iGPUHeightMask)  *y0 = iGPUHeightMask;\r
1893             \r
1894  if (*y1 < 0)               *y1 = 0;\r
1895  else\r
1896  if (*y1 > iGPUHeightMask)  *y1 = iGPUHeightMask;\r
1897 }\r
1898 \r
1899 ////////////////////////////////////////////////////////////////////////\r
1900 // Used in Load Image and Blk Fill\r
1901 ////////////////////////////////////////////////////////////////////////\r
1902 \r
1903 void ClampToPSXScreenOffset(short *x0, short *y0, short *x1, short *y1)\r
1904 {\r
1905  if (*x0 < 0)\r
1906   { *x1 += *x0;  *x0 = 0; }\r
1907  else\r
1908  if (*x0 > 1023)\r
1909   { *x0 = 1023;  *x1 = 0; }\r
1910 \r
1911  if (*y0 < 0)\r
1912   { *y1 += *y0;  *y0 = 0; }\r
1913  else\r
1914  if (*y0 > iGPUHeightMask)\r
1915   { *y0 = iGPUHeightMask;   *y1 = 0; }\r
1916 \r
1917  if (*x1 < 0) *x1 = 0;\r
1918 \r
1919  if ((*x1 + *x0) > 1024) *x1 = (1024 -  *x0);\r
1920 \r
1921  if (*y1 < 0) *y1 = 0;\r
1922 \r
1923  if ((*y1 + *y0) > iGPUHeight)  *y1 = (iGPUHeight -  *y0);\r
1924 }\r
1925 \r
1926 ////////////////////////////////////////////////////////////////////////\r
1927 // cmd: start of drawing area... primitives will be clipped inside\r
1928 ////////////////////////////////////////////////////////////////////////\r
1929 \r
1930 void cmdDrawAreaStart(unsigned char * baseAddr)\r
1931 {\r
1932  unsigned long gdata = ((unsigned long*)baseAddr)[0];\r
1933 \r
1934  drawX = gdata & 0x3ff;                                // for soft drawing\r
1935  if(drawX>=1024) drawX=1023;\r
1936 \r
1937  if(dwGPUVersion==2)\r
1938   {\r
1939    ulGPUInfoVals[INFO_DRAWSTART]=gdata&0x3FFFFF;\r
1940    drawY  = (gdata>>12)&0x3ff;\r
1941   }\r
1942  else\r
1943   {\r
1944    ulGPUInfoVals[INFO_DRAWSTART]=gdata&0xFFFFF;\r
1945    drawY  = (gdata>>10)&0x3ff;\r
1946   }\r
1947 \r
1948  if(drawY>=iGPUHeight) drawY=iGPUHeightMask;\r
1949 \r
1950  PreviousPSXDisplay.DrawArea.y0=PSXDisplay.DrawArea.y0;\r
1951  PreviousPSXDisplay.DrawArea.x0=PSXDisplay.DrawArea.x0;\r
1952 \r
1953  PSXDisplay.DrawArea.y0 = (short)drawY;                // for OGL drawing\r
1954  PSXDisplay.DrawArea.x0 = (short)drawX;\r
1955 }\r
1956 \r
1957 ////////////////////////////////////////////////////////////////////////\r
1958 // cmd: end of drawing area... primitives will be clipped inside\r
1959 ////////////////////////////////////////////////////////////////////////\r
1960 \r
1961 void cmdDrawAreaEnd(unsigned char * baseAddr)\r
1962 {\r
1963  unsigned long gdata = ((unsigned long*)baseAddr)[0];\r
1964 \r
1965  drawW = gdata & 0x3ff;                                // for soft drawing\r
1966  if(drawW>=1024) drawW=1023;\r
1967 \r
1968  if(dwGPUVersion==2)\r
1969   {\r
1970    ulGPUInfoVals[INFO_DRAWEND]=gdata&0x3FFFFF;\r
1971    drawH  = (gdata>>12)&0x3ff;\r
1972   }\r
1973  else\r
1974   {\r
1975    ulGPUInfoVals[INFO_DRAWEND]=gdata&0xFFFFF;\r
1976    drawH  = (gdata>>10)&0x3ff;\r
1977   }\r
1978  \r
1979  if(drawH>=iGPUHeight) drawH=iGPUHeightMask;\r
1980 \r
1981  PSXDisplay.DrawArea.y1 = (short)drawH;                // for OGL drawing\r
1982  PSXDisplay.DrawArea.x1 = (short)drawW;\r
1983 \r
1984  ClampToPSXScreen(&PSXDisplay.DrawArea.x0,             // clamp\r
1985                   &PSXDisplay.DrawArea.y0,\r
1986                   &PSXDisplay.DrawArea.x1,\r
1987                   &PSXDisplay.DrawArea.y1);\r
1988 \r
1989  bDisplayNotSet = TRUE;\r
1990 }\r
1991 \r
1992 ////////////////////////////////////////////////////////////////////////\r
1993 // cmd: draw offset... will be added to prim coords\r
1994 ////////////////////////////////////////////////////////////////////////\r
1995 \r
1996 void cmdDrawOffset(unsigned char * baseAddr)\r
1997 {\r
1998  unsigned long gdata = ((unsigned long*)baseAddr)[0];\r
1999 \r
2000  PreviousPSXDisplay.DrawOffset.x = \r
2001   PSXDisplay.DrawOffset.x = (short)(gdata & 0x7ff);\r
2002 \r
2003  if(dwGPUVersion==2)\r
2004   {\r
2005    ulGPUInfoVals[INFO_DRAWOFF]=gdata&0x7FFFFF;\r
2006    PSXDisplay.DrawOffset.y = (short)((gdata>>12) & 0x7ff);\r
2007   }\r
2008  else\r
2009   {\r
2010    ulGPUInfoVals[INFO_DRAWOFF]=gdata&0x3FFFFF;\r
2011    PSXDisplay.DrawOffset.y = (short)((gdata>>11) & 0x7ff);\r
2012   }\r
2013  \r
2014  PSXDisplay.DrawOffset.x=(short)(((int)PSXDisplay.DrawOffset.x<<21)>>21);\r
2015  PSXDisplay.DrawOffset.y=(short)(((int)PSXDisplay.DrawOffset.y<<21)>>21);\r
2016 \r
2017  PSXDisplay.CumulOffset.x =                            // new OGL prim offsets\r
2018   PSXDisplay.DrawOffset.x - PSXDisplay.GDrawOffset.x + PreviousPSXDisplay.Range.x0;\r
2019  PSXDisplay.CumulOffset.y = \r
2020   PSXDisplay.DrawOffset.y - PSXDisplay.GDrawOffset.y + PreviousPSXDisplay.Range.y0;\r
2021 }\r
2022 \r
2023 ////////////////////////////////////////////////////////////////////////\r
2024 // cmd: load image to vram\r
2025 ////////////////////////////////////////////////////////////////////////\r
2026 \r
2027 void primLoadImage(unsigned char * baseAddr)\r
2028 {\r
2029  unsigned short *sgpuData = ((unsigned short *) baseAddr);\r
2030 \r
2031  VRAMWrite.x      = sgpuData[2]&0x03ff;\r
2032  VRAMWrite.y      = sgpuData[3]&iGPUHeightMask;\r
2033  VRAMWrite.Width  = sgpuData[4];\r
2034  VRAMWrite.Height = sgpuData[5];\r
2035 \r
2036  iDataWriteMode = DR_VRAMTRANSFER;\r
2037  VRAMWrite.ImagePtr = psxVuw + (VRAMWrite.y<<10) + VRAMWrite.x;\r
2038  VRAMWrite.RowsRemaining = VRAMWrite.Width;\r
2039  VRAMWrite.ColsRemaining = VRAMWrite.Height;\r
2040 \r
2041  bNeedWriteUpload=TRUE;\r
2042 }\r
2043 \r
2044 ////////////////////////////////////////////////////////////////////////\r
2045 \r
2046 void PrepareRGB24Upload(void)\r
2047 {\r
2048  VRAMWrite.x=(VRAMWrite.x*2)/3;\r
2049  VRAMWrite.Width=(VRAMWrite.Width*2)/3;\r
2050 \r
2051  if(!PSXDisplay.InterlacedTest && // NEW\r
2052     CheckAgainstScreen(VRAMWrite.x, VRAMWrite.y, VRAMWrite.Width, VRAMWrite.Height))\r
2053   {\r
2054    xrUploadArea.x0-=PreviousPSXDisplay.DisplayPosition.x;\r
2055    xrUploadArea.x1-=PreviousPSXDisplay.DisplayPosition.x;\r
2056    xrUploadArea.y0-=PreviousPSXDisplay.DisplayPosition.y;\r
2057    xrUploadArea.y1-=PreviousPSXDisplay.DisplayPosition.y;\r
2058   }  \r
2059  else\r
2060  if(CheckAgainstFrontScreen(VRAMWrite.x, VRAMWrite.y, VRAMWrite.Width, VRAMWrite.Height))\r
2061   {\r
2062    xrUploadArea.x0-=PSXDisplay.DisplayPosition.x;\r
2063    xrUploadArea.x1-=PSXDisplay.DisplayPosition.x;\r
2064    xrUploadArea.y0-=PSXDisplay.DisplayPosition.y;\r
2065    xrUploadArea.y1-=PSXDisplay.DisplayPosition.y;\r
2066   }  \r
2067  else return;\r
2068 \r
2069  if(bRenderFrontBuffer) \r
2070   {\r
2071    updateFrontDisplay();\r
2072   }\r
2073 \r
2074  if(bNeedRGB24Update==FALSE)\r
2075   {\r
2076    xrUploadAreaRGB24=xrUploadArea;\r
2077    bNeedRGB24Update=TRUE;\r
2078   }\r
2079  else\r
2080   {\r
2081    xrUploadAreaRGB24.x0=min(xrUploadAreaRGB24.x0,xrUploadArea.x0);\r
2082    xrUploadAreaRGB24.x1=max(xrUploadAreaRGB24.x1,xrUploadArea.x1);\r
2083    xrUploadAreaRGB24.y0=min(xrUploadAreaRGB24.y0,xrUploadArea.y0);\r
2084    xrUploadAreaRGB24.y1=max(xrUploadAreaRGB24.y1,xrUploadArea.y1);\r
2085   }\r
2086 }\r
2087 \r
2088 ////////////////////////////////////////////////////////////////////////\r
2089 \r
2090 void CheckWriteUpdate()\r
2091 {\r
2092  int iX=0,iY=0;\r
2093 \r
2094  if(VRAMWrite.Width)   iX=1;\r
2095  if(VRAMWrite.Height)  iY=1;\r
2096 \r
2097  InvalidateTextureArea(VRAMWrite.x, VRAMWrite.y, VRAMWrite.Width-iX, VRAMWrite.Height-iY);\r
2098 \r
2099  if(PSXDisplay.Interlaced && !iOffscreenDrawing) return;\r
2100 \r
2101  if(PSXDisplay.RGB24) {PrepareRGB24Upload();return;}\r
2102 \r
2103  if(!PSXDisplay.InterlacedTest &&\r
2104     CheckAgainstScreen(VRAMWrite.x, VRAMWrite.y, VRAMWrite.Width, VRAMWrite.Height)) \r
2105   {\r
2106    if(dwActFixes&0x800) return;\r
2107 \r
2108    if(bRenderFrontBuffer) \r
2109     {\r
2110      updateFrontDisplay();\r
2111     }\r
2112 \r
2113    UploadScreen(FALSE);\r
2114 \r
2115    bNeedUploadTest=TRUE;\r
2116   }\r
2117  else \r
2118  if(iOffscreenDrawing)\r
2119   {\r
2120    if (CheckAgainstFrontScreen(VRAMWrite.x, VRAMWrite.y, VRAMWrite.Width, VRAMWrite.Height)) \r
2121     {\r
2122      if(PSXDisplay.InterlacedTest)\r
2123       {\r
2124        if(PreviousPSXDisplay.InterlacedNew) \r
2125         {\r
2126          PreviousPSXDisplay.InterlacedNew=FALSE;\r
2127          bNeedInterlaceUpdate=TRUE;\r
2128          xrUploadAreaIL.x0=PSXDisplay.DisplayPosition.x;\r
2129          xrUploadAreaIL.y0=PSXDisplay.DisplayPosition.y;\r
2130          xrUploadAreaIL.x1=PSXDisplay.DisplayPosition.x+PSXDisplay.DisplayModeNew.x;\r
2131          xrUploadAreaIL.y1=PSXDisplay.DisplayPosition.y+PSXDisplay.DisplayModeNew.y;\r
2132          if(xrUploadAreaIL.x1>1023) xrUploadAreaIL.x1=1023;\r
2133          if(xrUploadAreaIL.y1>511)  xrUploadAreaIL.y1=511;\r
2134         }\r
2135 \r
2136        if(bNeedInterlaceUpdate==FALSE)\r
2137         {\r
2138          xrUploadAreaIL=xrUploadArea;\r
2139          bNeedInterlaceUpdate=TRUE;\r
2140         }\r
2141        else\r
2142         {\r
2143          xrUploadAreaIL.x0=min(xrUploadAreaIL.x0,xrUploadArea.x0);\r
2144          xrUploadAreaIL.x1=max(xrUploadAreaIL.x1,xrUploadArea.x1);\r
2145          xrUploadAreaIL.y0=min(xrUploadAreaIL.y0,xrUploadArea.y0);\r
2146          xrUploadAreaIL.y1=max(xrUploadAreaIL.y1,xrUploadArea.y1);\r
2147         }\r
2148        return;\r
2149       }\r
2150 \r
2151      if(!bNeedUploadAfter)\r
2152       {\r
2153        bNeedUploadAfter = TRUE;\r
2154        xrUploadArea.x0=VRAMWrite.x;\r
2155        xrUploadArea.x1=VRAMWrite.x+VRAMWrite.Width;\r
2156        xrUploadArea.y0=VRAMWrite.y;\r
2157        xrUploadArea.y1=VRAMWrite.y+VRAMWrite.Height;\r
2158       }\r
2159      else\r
2160       {\r
2161        xrUploadArea.x0=min(xrUploadArea.x0,VRAMWrite.x);\r
2162        xrUploadArea.x1=max(xrUploadArea.x1,VRAMWrite.x+VRAMWrite.Width);\r
2163        xrUploadArea.y0=min(xrUploadArea.y0,VRAMWrite.y);\r
2164        xrUploadArea.y1=max(xrUploadArea.y1,VRAMWrite.y+VRAMWrite.Height);\r
2165       }\r
2166 \r
2167      if(dwActFixes&0x8000)\r
2168       {\r
2169        if((xrUploadArea.x1-xrUploadArea.x0)>=(PSXDisplay.DisplayMode.x-32) &&\r
2170           (xrUploadArea.y1-xrUploadArea.y0)>=(PSXDisplay.DisplayMode.y-32))\r
2171         {\r
2172          UploadScreen(-1);\r
2173          updateFrontDisplay();\r
2174         }\r
2175       }\r
2176     }\r
2177   }\r
2178 }\r
2179 \r
2180 ////////////////////////////////////////////////////////////////////////\r
2181 // cmd: vram -> psx mem\r
2182 ////////////////////////////////////////////////////////////////////////\r
2183 \r
2184 void primStoreImage(unsigned char * baseAddr)\r
2185 {\r
2186  unsigned short *sgpuData = ((unsigned short *) baseAddr);\r
2187 \r
2188  VRAMRead.x      = sgpuData[2]&0x03ff;\r
2189  VRAMRead.y      = sgpuData[3]&iGPUHeightMask;\r
2190  VRAMRead.Width  = sgpuData[4];\r
2191  VRAMRead.Height = sgpuData[5];\r
2192 \r
2193  VRAMRead.ImagePtr = psxVuw + (VRAMRead.y<<10) + VRAMRead.x;\r
2194  VRAMRead.RowsRemaining = VRAMRead.Width;\r
2195  VRAMRead.ColsRemaining = VRAMRead.Height;\r
2196 \r
2197  iDataReadMode = DR_VRAMTRANSFER;\r
2198 \r
2199  STATUSREG |= GPUSTATUS_READYFORVRAM;\r
2200 }\r
2201 \r
2202 ////////////////////////////////////////////////////////////////////////\r
2203 // cmd: blkfill - NO primitive! Doesn't care about draw areas...\r
2204 ////////////////////////////////////////////////////////////////////////\r
2205 \r
2206 void primBlkFill(unsigned char * baseAddr)\r
2207 {\r
2208  unsigned long *gpuData = ((unsigned long *) baseAddr);\r
2209  short *sgpuData = ((short *) baseAddr);\r
2210 \r
2211  iDrawnSomething=1;\r
2212 \r
2213  sprtX = sgpuData[2];\r
2214  sprtY = sgpuData[3];\r
2215  sprtW = sgpuData[4] & 0x3ff;\r
2216  sprtH = sgpuData[5] & iGPUHeightMask;\r
2217 \r
2218  sprtW = (sprtW+15) & ~15;\r
2219 \r
2220  // Increase H & W if they are one short of full values, because they never can be full values\r
2221  if (sprtH == iGPUHeightMask)  sprtH=iGPUHeight;\r
2222  if (sprtW == 1023)            sprtW=1024; \r
2223         \r
2224  // x and y of start\r
2225  ly0 = ly1 = sprtY;\r
2226  ly2 = ly3 = (sprtY+sprtH);\r
2227  lx0 = lx3 = sprtX;\r
2228  lx1 = lx2 = (sprtX+sprtW);\r
2229 \r
2230  offsetBlk();\r
2231 \r
2232  if(ClipVertexListScreen())                           \r
2233   {\r
2234    PSXDisplay_t * pd;\r
2235    if(PSXDisplay.InterlacedTest) pd=&PSXDisplay;\r
2236    else                          pd=&PreviousPSXDisplay;\r
2237 \r
2238    if ((lx0 <= pd->DisplayPosition.x+16) &&\r
2239        (ly0 <= pd->DisplayPosition.y+16) &&\r
2240        (lx2 >= pd->DisplayEnd.x-16) &&\r
2241        (ly2 >= pd->DisplayEnd.y-16))\r
2242     {\r
2243      GLclampf g,b,r;\r
2244      g=((GLclampf)GREEN(gpuData[0]))/255.0f;\r
2245      b=((GLclampf)BLUE(gpuData[0]))/255.0f;\r
2246      r=((GLclampf)RED(gpuData[0]))/255.0f;\r
2247      \r
2248      glDisable(GL_SCISSOR_TEST);                       \r
2249      glClearColor(r,g,b,1.0f);\r
2250      glClear(uiBufferBits); \r
2251      gl_z=0.0f;\r
2252 \r
2253      if(gpuData[0]!=0x02000000 &&\r
2254         (ly0>pd->DisplayPosition.y ||\r
2255          ly2<pd->DisplayEnd.y))\r
2256       {\r
2257        bDrawTextured     = FALSE;\r
2258        bDrawSmoothShaded = FALSE;\r
2259        SetRenderState((unsigned long)0x01000000);\r
2260        SetRenderMode((unsigned long)0x01000000, FALSE);\r
2261        vertex[0].c.lcol=0xff000000;\r
2262        SETCOL(vertex[0]); \r
2263        if(ly0>pd->DisplayPosition.y)\r
2264         {\r
2265          vertex[0].x=0;vertex[0].y=0;\r
2266          vertex[1].x=pd->DisplayEnd.x-pd->DisplayPosition.x;vertex[1].y=0;\r
2267          vertex[2].x=vertex[1].x;vertex[2].y=ly0-pd->DisplayPosition.y;\r
2268          vertex[3].x=0;vertex[3].y=vertex[2].y;\r
2269          PRIMdrawQuad(&vertex[0], &vertex[1], &vertex[2], &vertex[3]);\r
2270         }\r
2271        if(ly2<pd->DisplayEnd.y)\r
2272         {\r
2273          vertex[0].x=0;vertex[0].y=(pd->DisplayEnd.y-pd->DisplayPosition.y)-(pd->DisplayEnd.y-ly2);\r
2274          vertex[1].x=pd->DisplayEnd.x-pd->DisplayPosition.x;vertex[1].y=vertex[0].y;\r
2275          vertex[2].x=vertex[1].x;vertex[2].y=pd->DisplayEnd.y;\r
2276          vertex[3].x=0;vertex[3].y=vertex[2].y;\r
2277          PRIMdrawQuad(&vertex[0], &vertex[1], &vertex[2], &vertex[3]);\r
2278         }\r
2279       }\r
2280 \r
2281      glEnable(GL_SCISSOR_TEST);                       \r
2282     }\r
2283    else\r
2284     {\r
2285      bDrawTextured     = FALSE;\r
2286      bDrawSmoothShaded = FALSE;\r
2287      SetRenderState((unsigned long)0x01000000);\r
2288      SetRenderMode((unsigned long)0x01000000, FALSE);\r
2289      vertex[0].c.lcol=gpuData[0]|0xff000000;\r
2290      SETCOL(vertex[0]); \r
2291      glDisable(GL_SCISSOR_TEST);                       \r
2292      PRIMdrawQuad(&vertex[0], &vertex[1], &vertex[2], &vertex[3]);\r
2293      glEnable(GL_SCISSOR_TEST);                       \r
2294     }\r
2295   }\r
2296 \r
2297  //mmm... will clean all stuff, also if not all _should_ be cleaned...\r
2298  //if (IsInsideNextScreen(sprtX, sprtY, sprtW, sprtH))\r
2299  // try this:\r
2300  if (IsCompleteInsideNextScreen(sprtX, sprtY, sprtW, sprtH))\r
2301   {\r
2302    lClearOnSwapColor = COLOR(gpuData[0]);\r
2303    lClearOnSwap = 1;\r
2304   }\r
2305 \r
2306 /* if(iOffscreenDrawing)\r
2307   {\r
2308    ClampToPSXScreenOffset( &sprtX, &sprtY, &sprtW, &sprtH);\r
2309    if ((sprtW == 0) || (sprtH == 0)) return;\r
2310    InvalidateTextureArea(sprtX, sprtY, sprtW-1, sprtH-1);   \r
2311 \r
2312    sprtW+=sprtX;\r
2313    sprtH+=sprtY;\r
2314 \r
2315    FillSoftwareArea(sprtX, sprtY, sprtW, sprtH, BGR24to16(gpuData[0]));\r
2316   }*/\r
2317 }\r
2318   \r
2319 ////////////////////////////////////////////////////////////////////////\r
2320 // cmd: move image vram -> vram\r
2321 ////////////////////////////////////////////////////////////////////////\r
2322 \r
2323 void MoveImageWrapped(short imageX0,short imageY0,\r
2324                       short imageX1,short imageY1,\r
2325                       short imageSX,short imageSY)\r
2326 {\r
2327  int i,j,imageXE,imageYE;\r
2328 \r
2329  if(iFrameReadType&2)\r
2330   {\r
2331    imageXE=imageX0+imageSX;\r
2332    imageYE=imageY0+imageSY;\r
2333 \r
2334    if(imageYE>iGPUHeight && imageXE>1024) \r
2335     {\r
2336      CheckVRamRead(0,0,\r
2337                    (imageXE&0x3ff),\r
2338                    (imageY0&iGPUHeightMask),\r
2339                    FALSE);\r
2340     }\r
2341 \r
2342    if(imageXE>1024) \r
2343     {\r
2344      CheckVRamRead(0,imageY0, \r
2345                    (imageXE&0x3ff),\r
2346                    (imageYE>iGPUHeight)?iGPUHeight:imageYE,\r
2347                    FALSE);\r
2348     }\r
2349 \r
2350    if(imageYE>iGPUHeight) \r
2351     {\r
2352      CheckVRamRead(imageX0,0, \r
2353                    (imageXE>1024)?1024:imageXE,\r
2354                    imageYE&iGPUHeightMask,\r
2355                    FALSE);\r
2356     }\r
2357 \r
2358    CheckVRamRead(imageX0,imageY0, \r
2359                  (imageXE>1024)?1024:imageXE,\r
2360                  (imageYE>iGPUHeight)?iGPUHeight:imageYE,\r
2361                  FALSE);\r
2362   }\r
2363 \r
2364  for(j=0;j<imageSY;j++)\r
2365   for(i=0;i<imageSX;i++)\r
2366    psxVuw [(1024*((imageY1+j)&iGPUHeightMask))+((imageX1+i)&0x3ff)]=\r
2367     psxVuw[(1024*((imageY0+j)&iGPUHeightMask))+((imageX0+i)&0x3ff)];\r
2368 \r
2369  if(!PSXDisplay.RGB24)\r
2370   {\r
2371    imageXE=imageX1+imageSX;\r
2372    imageYE=imageY1+imageSY;\r
2373 \r
2374    if(imageYE>iGPUHeight && imageXE>1024) \r
2375     {\r
2376      InvalidateTextureArea(0,0,\r
2377                            (imageXE&0x3ff)-1,\r
2378                            (imageYE&iGPUHeightMask)-1);\r
2379     }\r
2380 \r
2381    if(imageXE>1024) \r
2382     {\r
2383      InvalidateTextureArea(0,imageY1,\r
2384                            (imageXE&0x3ff)-1,\r
2385                            ((imageYE>iGPUHeight)?iGPUHeight:imageYE)-imageY1-1);\r
2386     }\r
2387 \r
2388    if(imageYE>iGPUHeight) \r
2389     {\r
2390      InvalidateTextureArea(imageX1,0,\r
2391                            ((imageXE>1024)?1024:imageXE)-imageX1-1,\r
2392                            (imageYE&iGPUHeightMask)-1);\r
2393     }\r
2394 \r
2395    InvalidateTextureArea(imageX1,imageY1,\r
2396                          ((imageXE>1024)?1024:imageXE)-imageX1-1,\r
2397                          ((imageYE>iGPUHeight)?iGPUHeight:imageYE)-imageY1-1);\r
2398   }\r
2399 }\r
2400 \r
2401 ////////////////////////////////////////////////////////////////////////\r
2402 \r
2403 void primMoveImage(unsigned char * baseAddr)\r
2404 {\r
2405  short *sgpuData = ((short *) baseAddr);\r
2406  short imageY0,imageX0,imageY1,imageX1,imageSX,imageSY,i,j;\r
2407 \r
2408  imageX0 = sgpuData[2]&0x03ff;\r
2409  imageY0 = sgpuData[3]&iGPUHeightMask;\r
2410  imageX1 = sgpuData[4]&0x03ff;\r
2411  imageY1 = sgpuData[5]&iGPUHeightMask;\r
2412  imageSX = sgpuData[6];\r
2413  imageSY = sgpuData[7];\r
2414 \r
2415  if((imageX0 == imageX1) && (imageY0 == imageY1)) return;  \r
2416  if(imageSX<=0) return;\r
2417  if(imageSY<=0) return;\r
2418 \r
2419  if(iGPUHeight==1024 && sgpuData[7]>1024) return;\r
2420 \r
2421  if((imageY0+imageSY)>iGPUHeight ||\r
2422     (imageX0+imageSX)>1024       ||\r
2423     (imageY1+imageSY)>iGPUHeight ||\r
2424     (imageX1+imageSX)>1024)\r
2425   {\r
2426    MoveImageWrapped(imageX0,imageY0,imageX1,imageY1,imageSX,imageSY);\r
2427    if((imageY0+imageSY)>iGPUHeight) imageSY=iGPUHeight-imageY0;\r
2428    if((imageX0+imageSX)>1024)       imageSX=1024-imageX0;\r
2429    if((imageY1+imageSY)>iGPUHeight) imageSY=iGPUHeight-imageY1;\r
2430    if((imageX1+imageSX)>1024)       imageSX=1024-imageX1;\r
2431   }\r
2432 \r
2433  if(iFrameReadType&2)\r
2434   CheckVRamRead(imageX0,imageY0, \r
2435                 imageX0+imageSX,\r
2436                 imageY0+imageSY,\r
2437                 FALSE);\r
2438 \r
2439  if(imageSX&1)\r
2440   {\r
2441    unsigned short *SRCPtr, *DSTPtr;\r
2442    unsigned short LineOffset;\r
2443 \r
2444    SRCPtr = psxVuw + (1024*imageY0) + imageX0;\r
2445    DSTPtr = psxVuw + (1024*imageY1) + imageX1;\r
2446 \r
2447    LineOffset = 1024 - imageSX;\r
2448 \r
2449    for(j=0;j<imageSY;j++)\r
2450     {\r
2451      for(i=0;i<imageSX;i++) *DSTPtr++ = *SRCPtr++;\r
2452      SRCPtr += LineOffset;\r
2453      DSTPtr += LineOffset;\r
2454     }\r
2455   }\r
2456  else\r
2457   {\r
2458    unsigned long *SRCPtr, *DSTPtr;\r
2459    unsigned short LineOffset;\r
2460    int dx=imageSX>>1;\r
2461 \r
2462    SRCPtr = (unsigned long *)(psxVuw + (1024*imageY0) + imageX0);\r
2463    DSTPtr = (unsigned long *)(psxVuw + (1024*imageY1) + imageX1);\r
2464 \r
2465    LineOffset = 512 - dx;\r
2466 \r
2467    for(j=0;j<imageSY;j++)\r
2468     {\r
2469      for(i=0;i<dx;i++) *DSTPtr++ = *SRCPtr++;\r
2470      SRCPtr += LineOffset;\r
2471      DSTPtr += LineOffset;\r
2472     }\r
2473   }\r
2474 \r
2475  if (!PSXDisplay.RGB24)\r
2476   {\r
2477    InvalidateTextureArea(imageX1,imageY1,imageSX-1,imageSY-1);\r
2478 \r
2479    if (CheckAgainstScreen(imageX1,imageY1,imageSX,imageSY)) \r
2480     {\r
2481      if(imageX1>=PreviousPSXDisplay.DisplayPosition.x &&\r
2482         imageX1<PreviousPSXDisplay.DisplayEnd.x &&\r
2483         imageY1>=PreviousPSXDisplay.DisplayPosition.y &&\r
2484         imageY1<PreviousPSXDisplay.DisplayEnd.y)\r
2485       {\r
2486        imageX1 += imageSX;\r
2487        imageY1 += imageSY;\r
2488 \r
2489        if(imageX1>=PreviousPSXDisplay.DisplayPosition.x &&\r
2490           imageX1<=PreviousPSXDisplay.DisplayEnd.x &&\r
2491           imageY1>=PreviousPSXDisplay.DisplayPosition.y &&\r
2492           imageY1<=PreviousPSXDisplay.DisplayEnd.y)\r
2493         {\r
2494          if(!(\r
2495                imageX0>=PSXDisplay.DisplayPosition.x &&\r
2496                imageX0<PSXDisplay.DisplayEnd.x &&\r
2497                imageY0>=PSXDisplay.DisplayPosition.y &&\r
2498                imageY0<PSXDisplay.DisplayEnd.y \r
2499               ))\r
2500           {\r
2501            if(bRenderFrontBuffer) \r
2502             {\r
2503              updateFrontDisplay();\r
2504             }\r
2505  \r
2506            UploadScreen(FALSE);\r
2507           }\r
2508          else bFakeFrontBuffer=TRUE;\r
2509         }\r
2510       }\r
2511 \r
2512      bNeedUploadTest=TRUE;\r
2513     }\r
2514    else\r
2515    if(iOffscreenDrawing)\r
2516     {\r
2517      if (CheckAgainstFrontScreen(imageX1,imageY1,imageSX,imageSY)) \r
2518       {\r
2519        if(!PSXDisplay.InterlacedTest &&\r
2520 //          !bFullVRam &&\r
2521           ((\r
2522             imageX0>=PreviousPSXDisplay.DisplayPosition.x &&\r
2523             imageX0<PreviousPSXDisplay.DisplayEnd.x &&\r
2524             imageY0>=PreviousPSXDisplay.DisplayPosition.y &&\r
2525             imageY0<PreviousPSXDisplay.DisplayEnd.y\r
2526            ) ||\r
2527            (\r
2528             imageX0>=PSXDisplay.DisplayPosition.x &&\r
2529             imageX0<PSXDisplay.DisplayEnd.x &&\r
2530             imageY0>=PSXDisplay.DisplayPosition.y &&\r
2531             imageY0<PSXDisplay.DisplayEnd.y\r
2532            )))\r
2533         return;\r
2534 \r
2535        bNeedUploadTest=TRUE;\r
2536 \r
2537        if(!bNeedUploadAfter)\r
2538         {\r
2539          bNeedUploadAfter = TRUE;\r
2540          xrUploadArea.x0=imageX0;\r
2541          xrUploadArea.x1=imageX0+imageSX;\r
2542          xrUploadArea.y0=imageY0;\r
2543          xrUploadArea.y1=imageY0+imageSY;\r
2544         }\r
2545        else\r
2546         {\r
2547          xrUploadArea.x0=min(xrUploadArea.x0,imageX0);\r
2548          xrUploadArea.x1=max(xrUploadArea.x1,imageX0+imageSX);\r
2549          xrUploadArea.y0=min(xrUploadArea.y0,imageY0);\r
2550          xrUploadArea.y1=max(xrUploadArea.y1,imageY0+imageSY);\r
2551         }\r
2552       }\r
2553     }\r
2554   }\r
2555 }\r
2556 \r
2557 \r
2558 ////////////////////////////////////////////////////////////////////////\r
2559 // cmd: draw free-size Tile \r
2560 ////////////////////////////////////////////////////////////////////////\r
2561 \r
2562 void primTileS(unsigned char * baseAddr)\r
2563 {\r
2564  unsigned long *gpuData = ((unsigned long*)baseAddr);\r
2565  short *sgpuData = ((short *) baseAddr);\r
2566 \r
2567  sprtX = sgpuData[2];\r
2568  sprtY = sgpuData[3];\r
2569  sprtW = sgpuData[4] & 0x3ff;\r
2570  sprtH = sgpuData[5] & iGPUHeightMask;\r
2571 \r
2572  // x and y of start\r
2573 \r
2574  lx0 = sprtX;\r
2575  ly0 = sprtY;\r
2576 \r
2577  offsetST();\r
2578 \r
2579  if((dwActFixes&1) &&                                  // FF7 special game gix (battle cursor)\r
2580     sprtX==0 && sprtY==0 && sprtW==24 && sprtH==16) \r
2581   return;\r
2582 \r
2583  bDrawTextured = FALSE;\r
2584  bDrawSmoothShaded = FALSE;\r
2585 \r
2586  SetRenderState(gpuData[0]);\r
2587 \r
2588 /* if(iOffscreenDrawing)\r
2589   {\r
2590    if(IsPrimCompleteInsideNextScreen(lx0,ly0,lx2,ly2) ||\r
2591       (ly0==-6 && ly2==10))                            // OH MY GOD... I DIDN'T WANT TO DO IT... BUT I'VE FOUND NO OTHER WAY... HACK FOR GRADIUS SHOOTER :(\r
2592     {\r
2593      lClearOnSwapColor = COLOR(gpuData[0]);\r
2594      lClearOnSwap = 1;\r
2595     }\r
2596 \r
2597    offsetPSX4();\r
2598    if(bDrawOffscreen4())\r
2599     {\r
2600      if(!(iTileCheat && sprtH==32 && gpuData[0]==0x60ffffff)) // special cheat for certain ZiNc games\r
2601       {\r
2602        InvalidateTextureAreaEx();   \r
2603        FillSoftwareAreaTrans(lx0,ly0,lx2,ly2,\r
2604                              BGR24to16(gpuData[0]));  \r
2605       }\r
2606     }\r
2607   }*/\r
2608 \r
2609  SetRenderMode(gpuData[0], FALSE);\r
2610  SetZMask4NT();\r
2611 \r
2612  if(bIgnoreNextTile) {bIgnoreNextTile=FALSE;return;}\r
2613 \r
2614  vertex[0].c.lcol=gpuData[0];\r
2615  vertex[0].c.col[3]=ubGloColAlpha;\r
2616  SETCOL(vertex[0]); \r
2617  \r
2618  PRIMdrawQuad(&vertex[0], &vertex[1], &vertex[2], &vertex[3]);\r
2619 \r
2620  iDrawnSomething=1;\r
2621 }\r
2622 \r
2623 ////////////////////////////////////////////////////////////////////////\r
2624 // cmd: draw 1 dot Tile (point)\r
2625 ////////////////////////////////////////////////////////////////////////\r
2626 \r
2627 void primTile1(unsigned char * baseAddr)\r
2628 {\r
2629  unsigned long *gpuData = ((unsigned long*)baseAddr);\r
2630  short *sgpuData = ((short *) baseAddr);\r
2631 \r
2632  sprtX = sgpuData[2];\r
2633  sprtY = sgpuData[3];\r
2634  sprtW = 1;\r
2635  sprtH = 1;\r
2636 \r
2637  lx0 = sprtX;\r
2638  ly0 = sprtY;\r
2639 \r
2640  offsetST();\r
2641 \r
2642  bDrawTextured = FALSE;\r
2643  bDrawSmoothShaded = FALSE;\r
2644 \r
2645  SetRenderState(gpuData[0]);\r
2646 \r
2647 /* if(iOffscreenDrawing)\r
2648   {\r
2649    offsetPSX4();\r
2650 \r
2651    if(bDrawOffscreen4())\r
2652     {\r
2653      InvalidateTextureAreaEx();   \r
2654      FillSoftwareAreaTrans(lx0,ly0,lx2,ly2,\r
2655                            BGR24to16(gpuData[0]));          \r
2656     }\r
2657   }\r
2658 */\r
2659  SetRenderMode(gpuData[0], FALSE);\r
2660  SetZMask4NT();\r
2661 \r
2662  vertex[0].c.lcol=gpuData[0];vertex[0].c.col[3]=ubGloColAlpha;\r
2663  SETCOL(vertex[0]); \r
2664 \r
2665  PRIMdrawQuad(&vertex[0], &vertex[1], &vertex[2], &vertex[3]);\r
2666 \r
2667  iDrawnSomething=1;\r
2668 }\r
2669 \r
2670 ////////////////////////////////////////////////////////////////////////\r
2671 // cmd: draw 8 dot Tile (small rect)\r
2672 ////////////////////////////////////////////////////////////////////////\r
2673 \r
2674 void primTile8(unsigned char * baseAddr)\r
2675 {\r
2676  unsigned long *gpuData = ((unsigned long*)baseAddr);\r
2677  short *sgpuData = ((short *) baseAddr);\r
2678 \r
2679  sprtX = sgpuData[2];\r
2680  sprtY = sgpuData[3];\r
2681  sprtW = 8;\r
2682  sprtH = 8;\r
2683 \r
2684  lx0 = sprtX;\r
2685  ly0 = sprtY;\r
2686 \r
2687  offsetST();\r
2688 \r
2689  bDrawTextured = FALSE;\r
2690  bDrawSmoothShaded = FALSE;\r
2691  SetRenderState(gpuData[0]);\r
2692 \r
2693 /* if(iOffscreenDrawing)\r
2694   {\r
2695    offsetPSX4();\r
2696 \r
2697    if(bDrawOffscreen4())\r
2698     {\r
2699      InvalidateTextureAreaEx();   \r
2700      FillSoftwareAreaTrans(lx0,ly0,lx2,ly2,\r
2701                            BGR24to16(gpuData[0]));    \r
2702     }\r
2703   }\r
2704 */\r
2705  SetRenderMode(gpuData[0], FALSE);\r
2706  SetZMask4NT();\r
2707 \r
2708  vertex[0].c.lcol=gpuData[0];\r
2709  vertex[0].c.col[3]=ubGloColAlpha;\r
2710  SETCOL(vertex[0]); \r
2711 \r
2712  PRIMdrawQuad(&vertex[0], &vertex[1], &vertex[2], &vertex[3]);\r
2713 \r
2714  iDrawnSomething=1;\r
2715 }\r
2716 \r
2717 ////////////////////////////////////////////////////////////////////////\r
2718 // cmd: draw 16 dot Tile (medium rect)\r
2719 ////////////////////////////////////////////////////////////////////////\r
2720 \r
2721 void primTile16(unsigned char * baseAddr)\r
2722 {\r
2723  unsigned long *gpuData = ((unsigned long*)baseAddr);\r
2724  short *sgpuData = ((short *) baseAddr);\r
2725 \r
2726  sprtX = sgpuData[2];\r
2727  sprtY = sgpuData[3];\r
2728  sprtW = 16;\r
2729  sprtH = 16;\r
2730  // x and y of start\r
2731  lx0 = sprtX;\r
2732  ly0 = sprtY;\r
2733 \r
2734  offsetST();\r
2735 \r
2736  bDrawTextured = FALSE;\r
2737  bDrawSmoothShaded = FALSE;\r
2738  SetRenderState(gpuData[0]);\r
2739 \r
2740 /* if(iOffscreenDrawing)\r
2741   {\r
2742    offsetPSX4();\r
2743 \r
2744    if(bDrawOffscreen4())\r
2745     {\r
2746      InvalidateTextureAreaEx();   \r
2747      FillSoftwareAreaTrans(lx0,ly0,lx2,ly2,\r
2748                            BGR24to16(gpuData[0]));    \r
2749     }\r
2750   }\r
2751 */\r
2752  SetRenderMode(gpuData[0], FALSE);\r
2753  SetZMask4NT();\r
2754 \r
2755  vertex[0].c.lcol=gpuData[0];\r
2756  vertex[0].c.col[3]=ubGloColAlpha;\r
2757  SETCOL(vertex[0]); \r
2758 \r
2759  PRIMdrawQuad(&vertex[0], &vertex[1], &vertex[2], &vertex[3]);\r
2760 \r
2761  iDrawnSomething=1;\r
2762 }\r
2763 \r
2764 ////////////////////////////////////////////////////////////////////////\r
2765 // helper: filter effect by multipass rendering\r
2766 ////////////////////////////////////////////////////////////////////////\r
2767 \r
2768 /*void DrawMultiBlur(void)\r
2769 {\r
2770  long lABR,lDST;float fx,fy;\r
2771 \r
2772  lABR=GlobalTextABR;\r
2773  lDST=DrawSemiTrans;\r
2774 \r
2775  fx=(float)PSXDisplay.DisplayMode.x/(float)(iResX); \r
2776  fy=(float)PSXDisplay.DisplayMode.y/(float)(iResY);\r
2777 \r
2778  vertex[0].x+=fx;vertex[1].x+=fx;\r
2779  vertex[2].x+=fx;vertex[3].x+=fx;\r
2780 \r
2781  GlobalTextABR=0;\r
2782  DrawSemiTrans=1;\r
2783  SetSemiTrans();\r
2784 \r
2785  PRIMdrawTexturedQuad(&vertex[0], &vertex[1], &vertex[2], &vertex[3]);\r
2786 \r
2787  vertex[0].y+=fy;vertex[1].y+=fy;\r
2788  vertex[2].y+=fy;vertex[3].y+=fy;\r
2789  PRIMdrawTexturedQuad(&vertex[0], &vertex[1], &vertex[2], &vertex[3]);\r
2790 \r
2791  if(bDrawMultiPass) {obm1=obm2=GL_SRC_ALPHA;}\r
2792 \r
2793  GlobalTextABR=lABR;\r
2794  DrawSemiTrans=lDST;\r
2795 }\r
2796 */\r
2797 ////////////////////////////////////////////////////////////////////////\r
2798 \r
2799 #define   POFF 0.375f\r
2800 \r
2801 void DrawMultiFilterSprite(void)\r
2802 {\r
2803  long lABR,lDST;\r
2804 \r
2805  if(bUseMultiPass || DrawSemiTrans || ubOpaqueDraw) \r
2806   {\r
2807    PRIMdrawTexturedQuad(&vertex[0], &vertex[1], &vertex[2], &vertex[3]);\r
2808    return;\r
2809   }\r
2810 \r
2811  lABR=GlobalTextABR;\r
2812  lDST=DrawSemiTrans;\r
2813  vertex[0].c.col[3]=ubGloAlpha/2;                      // -> set color with\r
2814  SETCOL(vertex[0]);                                    //    texture alpha\r
2815  PRIMdrawTexturedQuad(&vertex[0], &vertex[1], &vertex[2], &vertex[3]);\r
2816  vertex[0].x+=POFF;vertex[1].x+=POFF;\r
2817  vertex[2].x+=POFF;vertex[3].x+=POFF;\r
2818  vertex[0].y+=POFF;vertex[1].y+=POFF;\r
2819  vertex[2].y+=POFF;vertex[3].y+=POFF;\r
2820  GlobalTextABR=0;\r
2821  DrawSemiTrans=1;\r
2822  SetSemiTrans();\r
2823  PRIMdrawTexturedQuad(&vertex[0], &vertex[1], &vertex[2], &vertex[3]);\r
2824  GlobalTextABR=lABR;\r
2825  DrawSemiTrans=lDST;\r
2826 }\r
2827 \r
2828 ////////////////////////////////////////////////////////////////////////\r
2829 // cmd: small sprite (textured rect)\r
2830 ////////////////////////////////////////////////////////////////////////\r
2831 \r
2832 void primSprt8(unsigned char * baseAddr)\r
2833 {\r
2834  unsigned long *gpuData = ((unsigned long *) baseAddr);\r
2835  short *sgpuData = ((short *) baseAddr);\r
2836  short s;\r
2837 \r
2838  iSpriteTex=1;\r
2839 \r
2840  sprtX = sgpuData[2];\r
2841  sprtY = sgpuData[3];\r
2842  sprtW = 8;\r
2843  sprtH = 8;\r
2844 \r
2845  lx0 = sprtX;\r
2846  ly0 = sprtY;\r
2847 \r
2848  offsetST();\r
2849 \r
2850  // do texture stuff\r
2851  gl_ux[0]=gl_ux[3]=baseAddr[8];//gpuData[2]&0xff;\r
2852 \r
2853  if(usMirror & 0x1000) \r
2854   {\r
2855    s=gl_ux[0];\r
2856    s-=sprtW-1;\r
2857    if(s<0) {s=0;}\r
2858    gl_ux[0]=gl_ux[3]=s;\r
2859   }\r
2860 \r
2861  sSprite_ux2=s=gl_ux[0]+sprtW; \r
2862  if(s)     s--;\r
2863  if(s>255) s=255;\r
2864  gl_ux[1]=gl_ux[2]=s;\r
2865  // Y coords\r
2866  gl_vy[0]=gl_vy[1]=baseAddr[9];//(gpuData[2]>>8)&0xff;\r
2867 \r
2868  if(usMirror & 0x2000) \r
2869   {\r
2870    s=gl_vy[0];\r
2871    s-=sprtH-1;\r
2872    if(s<0) {s=0;}\r
2873    gl_vy[0]=gl_vy[1]=s;\r
2874   }\r
2875 \r
2876  sSprite_vy2=s=gl_vy[0]+sprtH; \r
2877  if(s)     s--;\r
2878  if(s>255) s=255;\r
2879  gl_vy[2]=gl_vy[3]=s;\r
2880 \r
2881  ulClutID=(gpuData[2]>>16);\r
2882 \r
2883  bDrawTextured = TRUE;\r
2884  bDrawSmoothShaded = FALSE;\r
2885  SetRenderState(gpuData[0]);\r
2886 \r
2887 /* if(iOffscreenDrawing)      \r
2888   {\r
2889    offsetPSX4();\r
2890 \r
2891    if(bDrawOffscreen4())\r
2892     {\r
2893      InvalidateTextureAreaEx();   \r
2894      SetRenderColor(gpuData[0]);\r
2895      lx0-=PSXDisplay.DrawOffset.x;\r
2896      ly0-=PSXDisplay.DrawOffset.y;\r
2897 \r
2898      if(bUsingTWin) DrawSoftwareSpriteTWin(baseAddr,8,8);\r
2899      else\r
2900      if(usMirror)   DrawSoftwareSpriteMirror(baseAddr,8,8);\r
2901      else\r
2902      DrawSoftwareSprite(baseAddr,8,8,baseAddr[8],baseAddr[9]);\r
2903     }\r
2904   }\r
2905 */\r
2906  SetRenderMode(gpuData[0], TRUE);\r
2907  SetZMask4SP();\r
2908 \r
2909  sSprite_ux2=gl_ux[0]+sprtW;\r
2910  sSprite_vy2=gl_vy[0]+sprtH;\r
2911 \r
2912  assignTextureSprite();\r
2913 \r
2914  if(iFilterType>4) \r
2915   DrawMultiFilterSprite();\r
2916  else\r
2917   PRIMdrawTexturedQuad(&vertex[0], &vertex[1], &vertex[2], &vertex[3]);\r
2918 \r
2919  if(bDrawMultiPass)\r
2920   {\r
2921    SetSemiTransMulti(1);\r
2922    PRIMdrawTexturedQuad(&vertex[0], &vertex[1], &vertex[2], &vertex[3]);\r
2923   }\r
2924 \r
2925  if(ubOpaqueDraw)\r
2926   {\r
2927    SetZMask4O();\r
2928    if(bUseMultiPass) SetOpaqueColor(gpuData[0]);\r
2929    DEFOPAQUEON\r
2930 \r
2931 /*   if(bSmallAlpha && iFilterType<=2)\r
2932     {\r
2933      glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);\r
2934      glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);\r
2935      PRIMdrawTexturedQuad(&vertex[0], &vertex[1], &vertex[2], &vertex[3]);\r
2936      glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);\r
2937      glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);\r
2938      SetZMask4O();\r
2939     }\r
2940 */\r
2941    PRIMdrawTexturedQuad(&vertex[0], &vertex[1], &vertex[2], &vertex[3]);\r
2942    DEFOPAQUEOFF\r
2943   }\r
2944 \r
2945  iSpriteTex=0;\r
2946  iDrawnSomething=1;\r
2947 }\r
2948 \r
2949 ////////////////////////////////////////////////////////////////////////\r
2950 // cmd: medium sprite (textured rect)\r
2951 ////////////////////////////////////////////////////////////////////////\r
2952 \r
2953 void primSprt16(unsigned char * baseAddr)\r
2954 {\r
2955  unsigned long *gpuData = ((unsigned long *) baseAddr);\r
2956  short *sgpuData = ((short *) baseAddr);\r
2957  short s;\r
2958 \r
2959  iSpriteTex=1;\r
2960 \r
2961  sprtX = sgpuData[2];\r
2962  sprtY = sgpuData[3];\r
2963  sprtW = 16;\r
2964  sprtH = 16;\r
2965 \r
2966  lx0 = sprtX;\r
2967  ly0 = sprtY;\r
2968 \r
2969  offsetST();\r
2970 \r
2971  // do texture stuff\r
2972  gl_ux[0]=gl_ux[3]=baseAddr[8];//gpuData[2]&0xff;\r
2973 \r
2974  if(usMirror & 0x1000) \r
2975   {\r
2976    s=gl_ux[0];\r
2977    s-=sprtW-1;\r
2978    if(s<0) {s=0;}\r
2979    gl_ux[0]=gl_ux[3]=s;\r
2980   }\r
2981 \r
2982  sSprite_ux2=s=gl_ux[0]+sprtW; \r
2983  if(s)     s--;\r
2984  if(s>255) s=255;\r
2985  gl_ux[1]=gl_ux[2]=s; \r
2986  // Y coords\r
2987  gl_vy[0]=gl_vy[1]=baseAddr[9];//(gpuData[2]>>8)&0xff;\r
2988 \r
2989  if(usMirror & 0x2000) \r
2990   {\r
2991    s=gl_vy[0];\r
2992    s-=sprtH-1;\r
2993    if(s<0) {s=0;}\r
2994    gl_vy[0]=gl_vy[1]=s;\r
2995   }\r
2996 \r
2997  sSprite_vy2=s=gl_vy[0]+sprtH; \r
2998  if(s)     s--;\r
2999  if(s>255) s=255;\r
3000  gl_vy[2]=gl_vy[3]=s;\r
3001 \r
3002  ulClutID=(gpuData[2]>>16);\r
3003 \r
3004  bDrawTextured = TRUE;\r
3005  bDrawSmoothShaded = FALSE;\r
3006  SetRenderState(gpuData[0]);\r
3007 \r
3008 /* if(iOffscreenDrawing)  \r
3009   {\r
3010    offsetPSX4();\r
3011 \r
3012    if(bDrawOffscreen4())\r
3013     {\r
3014      InvalidateTextureAreaEx();   \r
3015      SetRenderColor(gpuData[0]);\r
3016      lx0-=PSXDisplay.DrawOffset.x;\r
3017      ly0-=PSXDisplay.DrawOffset.y;\r
3018      if(bUsingTWin) DrawSoftwareSpriteTWin(baseAddr,16,16);\r
3019      else\r
3020      if(usMirror)   DrawSoftwareSpriteMirror(baseAddr,16,16);\r
3021      else\r
3022      DrawSoftwareSprite(baseAddr,16,16,baseAddr[8],baseAddr[9]);\r
3023     }\r
3024   }\r
3025 */\r
3026  SetRenderMode(gpuData[0], TRUE);\r
3027  SetZMask4SP();\r
3028 \r
3029  sSprite_ux2=gl_ux[0]+sprtW;\r
3030  sSprite_vy2=gl_vy[0]+sprtH;\r
3031 \r
3032  assignTextureSprite();\r
3033 \r
3034  if(iFilterType>4) \r
3035   DrawMultiFilterSprite();\r
3036  else\r
3037   PRIMdrawTexturedQuad(&vertex[0], &vertex[1], &vertex[2], &vertex[3]);\r
3038 \r
3039  if(bDrawMultiPass)\r
3040   {\r
3041    SetSemiTransMulti(1);\r
3042    PRIMdrawTexturedQuad(&vertex[0], &vertex[1], &vertex[2], &vertex[3]);\r
3043   }\r
3044 \r
3045  if(ubOpaqueDraw)\r
3046   {\r
3047    SetZMask4O();\r
3048    if(bUseMultiPass) SetOpaqueColor(gpuData[0]);\r
3049    DEFOPAQUEON\r
3050 \r
3051 /*   if(bSmallAlpha && iFilterType<=2)\r
3052     {\r
3053      glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);\r
3054      glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);\r
3055      PRIMdrawTexturedQuad(&vertex[0], &vertex[1], &vertex[2], &vertex[3]);\r
3056      glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);\r
3057      glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);\r
3058      SetZMask4O();\r
3059     }\r
3060 */\r
3061    PRIMdrawTexturedQuad(&vertex[0], &vertex[1], &vertex[2], &vertex[3]);\r
3062    DEFOPAQUEOFF\r
3063   }\r
3064 \r
3065  iSpriteTex=0;\r
3066  iDrawnSomething=1;\r
3067 }\r
3068 \r
3069 ////////////////////////////////////////////////////////////////////////\r
3070 // cmd: free-size sprite (textured rect)\r
3071 ////////////////////////////////////////////////////////////////////////\r
3072  \r
3073 void primSprtSRest(unsigned char * baseAddr,unsigned short type)\r
3074 {\r
3075  unsigned long *gpuData = ((unsigned long *) baseAddr);\r
3076  short *sgpuData = ((short *) baseAddr);\r
3077  short s;unsigned short sTypeRest=0;\r
3078 \r
3079  sprtX = sgpuData[2];\r
3080  sprtY = sgpuData[3];\r
3081  sprtW = sgpuData[6] & 0x3ff;\r
3082  sprtH = sgpuData[7] & 0x1ff;\r
3083 \r
3084 \r
3085  // do texture stuff\r
3086  switch(type)\r
3087   {\r
3088    case 1:\r
3089     gl_vy[0]=gl_vy[1]=baseAddr[9];\r
3090     s=256-baseAddr[8];\r
3091     sprtW-=s;\r
3092     sprtX+=s;\r
3093     gl_ux[0]=gl_ux[3]=0;\r
3094     break;\r
3095    case 2:\r
3096     gl_ux[0]=gl_ux[3]=baseAddr[8];\r
3097     s=256-baseAddr[9];\r
3098     sprtH-=s;\r
3099     sprtY+=s;\r
3100     gl_vy[0]=gl_vy[1]=0;\r
3101     break;\r
3102    case 3:\r
3103     s=256-baseAddr[8];\r
3104     sprtW-=s;\r
3105     sprtX+=s;\r
3106     gl_ux[0]=gl_ux[3]=0;\r
3107     s=256-baseAddr[9];\r
3108     sprtH-=s;\r
3109     sprtY+=s;\r
3110     gl_vy[0]=gl_vy[1]=0;\r
3111     break;\r
3112 \r
3113    case 4:\r
3114     gl_vy[0]=gl_vy[1]=baseAddr[9];\r
3115     s=512-baseAddr[8];\r
3116     sprtW-=s;\r
3117     sprtX+=s;\r
3118     gl_ux[0]=gl_ux[3]=0;\r
3119     break;\r
3120    case 5:\r
3121     gl_ux[0]=gl_ux[3]=baseAddr[8];\r
3122     s=512-baseAddr[9];\r
3123     sprtH-=s;\r
3124     sprtY+=s;\r
3125     gl_vy[0]=gl_vy[1]=0;\r
3126     break;\r
3127    case 6:\r
3128     s=512-baseAddr[8];\r
3129     sprtW-=s;\r
3130     sprtX+=s;\r
3131     gl_ux[0]=gl_ux[3]=0;\r
3132     s=512-baseAddr[9];\r
3133     sprtH-=s;\r
3134     sprtY+=s;\r
3135     gl_vy[0]=gl_vy[1]=0;\r
3136     break;\r
3137 \r
3138   }\r
3139 \r
3140  if(usMirror & 0x1000) \r
3141   {\r
3142    s=gl_ux[0];\r
3143    s-=sprtW-1;if(s<0) s=0;\r
3144    gl_ux[0]=gl_ux[3]=s;\r
3145   }\r
3146  if(usMirror & 0x2000) \r
3147   {\r
3148    s=gl_vy[0];\r
3149    s-=sprtH-1;if(s<0) {s=0;}\r
3150    gl_vy[0]=gl_vy[1]=s;\r
3151   }\r
3152 \r
3153  sSprite_ux2=s=gl_ux[0]+sprtW; \r
3154  if(s>255) s=255;\r
3155  gl_ux[1]=gl_ux[2]=s;\r
3156  sSprite_vy2=s=gl_vy[0]+sprtH; \r
3157  if(s>255) s=255;\r
3158  gl_vy[2]=gl_vy[3]=s;\r
3159 \r
3160  if(!bUsingTWin)\r
3161   {\r
3162    if(sSprite_ux2>256) \r
3163     {sprtW=256-gl_ux[0];sSprite_ux2=256;sTypeRest+=1;}\r
3164    if(sSprite_vy2>256) \r
3165     {sprtH=256-gl_vy[0];sSprite_vy2=256;sTypeRest+=2;}\r
3166   }\r
3167  \r
3168  lx0 = sprtX;\r
3169  ly0 = sprtY;\r
3170 \r
3171  offsetST();\r
3172 \r
3173  ulClutID=(gpuData[2]>>16);\r
3174 \r
3175  bDrawTextured = TRUE;\r
3176  bDrawSmoothShaded = FALSE;\r
3177  SetRenderState(gpuData[0]);\r
3178 \r
3179 /* if(iOffscreenDrawing)\r
3180   {\r
3181    offsetPSX4();\r
3182 \r
3183    if(bDrawOffscreen4())\r
3184     {\r
3185      InvalidateTextureAreaEx();   \r
3186      SetRenderColor(gpuData[0]);\r
3187      lx0-=PSXDisplay.DrawOffset.x;\r
3188      ly0-=PSXDisplay.DrawOffset.y;\r
3189      if(bUsingTWin) DrawSoftwareSpriteTWin(baseAddr,sprtW,sprtH);\r
3190      else\r
3191      if(usMirror)   DrawSoftwareSpriteMirror(baseAddr,sprtW,sprtH);\r
3192      else\r
3193      DrawSoftwareSprite(baseAddr,sprtW,sprtH,baseAddr[8],baseAddr[9]);\r
3194     }\r
3195   }\r
3196 */\r
3197  SetRenderMode(gpuData[0], TRUE);\r
3198  SetZMask4SP();\r
3199 \r
3200  sSprite_ux2=gl_ux[0]+sprtW;\r
3201  sSprite_vy2=gl_vy[0]+sprtH;\r
3202 \r
3203  assignTextureSprite();\r
3204 \r
3205  if(iFilterType>4) \r
3206   DrawMultiFilterSprite();\r
3207  else\r
3208   PRIMdrawTexturedQuad(&vertex[0], &vertex[1], &vertex[2], &vertex[3]);\r
3209  \r
3210  if(bDrawMultiPass)\r
3211   {\r
3212    SetSemiTransMulti(1);\r
3213    PRIMdrawTexturedQuad(&vertex[0], &vertex[1], &vertex[2], &vertex[3]);\r
3214   }\r
3215 \r
3216  if(ubOpaqueDraw)\r
3217   {\r
3218    SetZMask4O();\r
3219    if(bUseMultiPass) SetOpaqueColor(gpuData[0]);\r
3220    DEFOPAQUEON\r
3221 \r
3222 /*   if(bSmallAlpha && iFilterType<=2)\r
3223     {\r
3224      glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);\r
3225      glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);\r
3226      PRIMdrawTexturedQuad(&vertex[0], &vertex[1], &vertex[2], &vertex[3]);\r
3227      glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);\r
3228      glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);\r
3229      SetZMask4O();\r
3230     }\r
3231 */\r
3232    PRIMdrawTexturedQuad(&vertex[0], &vertex[1], &vertex[2], &vertex[3]);\r
3233    DEFOPAQUEOFF\r
3234   }\r
3235 \r
3236  if(sTypeRest && type<4) \r
3237   {\r
3238    if(sTypeRest&1  && type==1) primSprtSRest(baseAddr,4);\r
3239    if(sTypeRest&2  && type==2) primSprtSRest(baseAddr,5);\r
3240    if(sTypeRest==3 && type==3) primSprtSRest(baseAddr,6);\r
3241   }\r
3242 }\r
3243 \r
3244 void primSprtS(unsigned char * baseAddr)\r
3245 {\r
3246  unsigned long *gpuData = ((unsigned long *) baseAddr);\r
3247  short *sgpuData = ((short *) baseAddr);\r
3248 \r
3249  short s;unsigned short sTypeRest=0;\r
3250 \r
3251  sprtX = sgpuData[2];\r
3252  sprtY = sgpuData[3];\r
3253  sprtW = sgpuData[6] & 0x3ff;\r
3254  sprtH = sgpuData[7] & 0x1ff;\r
3255 \r
3256  if(!sprtH) return;\r
3257  if(!sprtW) return;\r
3258 \r
3259  iSpriteTex=1;\r
3260 \r
3261  // do texture stuff\r
3262  gl_ux[0]=gl_ux[3]=baseAddr[8];//gpuData[2]&0xff;\r
3263  gl_vy[0]=gl_vy[1]=baseAddr[9];//(gpuData[2]>>8)&0xff;\r
3264 \r
3265  if(usMirror & 0x1000) \r
3266   {\r
3267    s=gl_ux[0];\r
3268    s-=sprtW-1;\r
3269    if(s<0) {s=0;}\r
3270    gl_ux[0]=gl_ux[3]=s;\r
3271   }\r
3272  if(usMirror & 0x2000) \r
3273   {\r
3274    s=gl_vy[0];\r
3275    s-=sprtH-1;\r
3276    if(s<0) {s=0;}\r
3277    gl_vy[0]=gl_vy[1]=s;\r
3278   }\r
3279 \r
3280  sSprite_ux2=s=gl_ux[0]+sprtW; \r
3281  if(s)     s--;\r
3282  if(s>255) s=255;\r
3283  gl_ux[1]=gl_ux[2]=s;\r
3284  sSprite_vy2=s=gl_vy[0]+sprtH; \r