gpu-gles: schtruck/fpse merge: additional calls
[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);glError();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);glError();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); glError();                // 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); glError();                    // 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); glError();                    // 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);glError();bBlendEnable=TRUE;}    // wanna blend\r
806 \r
807  if(bm1!=obm1 || bm2!=obm2)\r
808   {\r
809    glBlendFunc(bm1,bm2); glError();                    // 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); glError();}\r
951 \r
952    if(!bTexEnabled)                                    // -> turn texturing on\r
953     {bTexEnabled=TRUE;glEnable(GL_TEXTURE_2D); glError();}\r
954   }\r
955  else                                                  // no texture ?\r
956  if(bTexEnabled) \r
957   {bTexEnabled=FALSE;glDisable(GL_TEXTURE_2D); glError();} // -> 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    glError();\r
984    bOldSmoothShaded=bDrawSmoothShaded;\r
985   }\r
986 }\r
987 \r
988 ////////////////////////////////////////////////////////////////////////                                          \r
989 // Set Opaque multipass color\r
990 ////////////////////////////////////////////////////////////////////////\r
991 \r
992 void SetOpaqueColor(unsigned long DrawAttributes)\r
993 {\r
994  if(bDrawNonShaded) return;                            // no shading? bye\r
995   \r
996  DrawAttributes=DoubleBGR2RGB(DrawAttributes);         // multipass is just half color, so double it on opaque pass\r
997  vertex[0].c.lcol=DrawAttributes|0xff000000;\r
998  SETCOL(vertex[0]);                                    // set color\r
999 }\r
1000 \r
1001 ////////////////////////////////////////////////////////////////////////                                          \r
1002 // Fucking stupid screen coord checking\r
1003 ////////////////////////////////////////////////////////////////////////\r
1004 \r
1005 BOOL ClipVertexListScreen(void)\r
1006 {\r
1007  if (lx0 >= PSXDisplay.DisplayEnd.x)      goto NEXTSCRTEST;\r
1008  if (ly0 >= PSXDisplay.DisplayEnd.y)      goto NEXTSCRTEST;\r
1009  if (lx2 <  PSXDisplay.DisplayPosition.x) goto NEXTSCRTEST;\r
1010  if (ly2 <  PSXDisplay.DisplayPosition.y) goto NEXTSCRTEST;\r
1011 \r
1012  return TRUE;\r
1013 \r
1014 NEXTSCRTEST:\r
1015  if(PSXDisplay.InterlacedTest) return FALSE;\r
1016 \r
1017  if (lx0 >= PreviousPSXDisplay.DisplayEnd.x)      return FALSE;\r
1018  if (ly0 >= PreviousPSXDisplay.DisplayEnd.y)      return FALSE;\r
1019  if (lx2 <  PreviousPSXDisplay.DisplayPosition.x) return FALSE;\r
1020  if (ly2 <  PreviousPSXDisplay.DisplayPosition.y) return FALSE;\r
1021 \r
1022  return TRUE;\r
1023 }\r
1024 \r
1025 ////////////////////////////////////////////////////////////////////////\r
1026 \r
1027 BOOL bDrawOffscreenFront(void)\r
1028 {\r
1029  if(sxmin < PSXDisplay.DisplayPosition.x) return FALSE;   // must be complete in front\r
1030  if(symin < PSXDisplay.DisplayPosition.y) return FALSE;\r
1031  if(sxmax > PSXDisplay.DisplayEnd.x)      return FALSE;\r
1032  if(symax > PSXDisplay.DisplayEnd.y)      return FALSE;\r
1033  return TRUE;\r
1034 }\r
1035 \r
1036 BOOL bOnePointInFront(void)\r
1037 {\r
1038  if(sxmax< PSXDisplay.DisplayPosition.x)\r
1039   return FALSE;\r
1040 \r
1041  if(symax< PSXDisplay.DisplayPosition.y)\r
1042   return FALSE;\r
1043 \r
1044  if(sxmin>=PSXDisplay.DisplayEnd.x)\r
1045   return FALSE;\r
1046 \r
1047  if(symin>=PSXDisplay.DisplayEnd.y)\r
1048   return FALSE;\r
1049 \r
1050  return TRUE;\r
1051 }\r
1052  \r
1053 \r
1054 BOOL bOnePointInBack(void)\r
1055 {\r
1056  if(sxmax< PreviousPSXDisplay.DisplayPosition.x)\r
1057   return FALSE;\r
1058 \r
1059  if(symax< PreviousPSXDisplay.DisplayPosition.y)\r
1060   return FALSE;\r
1061 \r
1062  if(sxmin>=PreviousPSXDisplay.DisplayEnd.x)\r
1063   return FALSE;\r
1064 \r
1065  if(symin>=PreviousPSXDisplay.DisplayEnd.y)\r
1066   return FALSE;\r
1067 \r
1068  return TRUE;\r
1069 }\r
1070  \r
1071 BOOL bDrawOffscreen4(void)\r
1072 {\r
1073  BOOL bFront;short sW,sH;\r
1074 \r
1075  sxmax=max(lx0,max(lx1,max(lx2,lx3)));\r
1076  if(sxmax<drawX) return FALSE;\r
1077  sxmin=min(lx0,min(lx1,min(lx2,lx3)));\r
1078  if(sxmin>drawW) return FALSE;\r
1079  symax=max(ly0,max(ly1,max(ly2,ly3)));\r
1080  if(symax<drawY) return FALSE;\r
1081  symin=min(ly0,min(ly1,min(ly2,ly3)));\r
1082  if(symin>drawH) return FALSE;\r
1083 \r
1084  if(PSXDisplay.Disabled) return TRUE;                  // disabled? ever\r
1085 \r
1086  if(iOffscreenDrawing==1) return bFullVRam;\r
1087 \r
1088  if(dwActFixes&1 && iOffscreenDrawing==4)\r
1089   {\r
1090    if(PreviousPSXDisplay.DisplayPosition.x==PSXDisplay.DisplayPosition.x &&\r
1091       PreviousPSXDisplay.DisplayPosition.y==PSXDisplay.DisplayPosition.y &&\r
1092       PreviousPSXDisplay.DisplayEnd.x==PSXDisplay.DisplayEnd.x &&\r
1093       PreviousPSXDisplay.DisplayEnd.y==PSXDisplay.DisplayEnd.y)\r
1094     {\r
1095      bRenderFrontBuffer=TRUE;\r
1096      return FALSE;\r
1097     }\r
1098   }\r
1099 \r
1100  sW=drawW-1;sH=drawH-1;\r
1101  \r
1102  sxmin=min(sW,max(sxmin,drawX));\r
1103  sxmax=max(drawX,min(sxmax,sW));\r
1104  symin=min(sH,max(symin,drawY));\r
1105  symax=max(drawY,min(symax,sH));\r
1106 \r
1107  if(bOnePointInBack()) return bFullVRam;\r
1108 \r
1109  if(iOffscreenDrawing==2) \r
1110       bFront=bDrawOffscreenFront();\r
1111  else bFront=bOnePointInFront();\r
1112 \r
1113  if(bFront)\r
1114   {\r
1115    if(PSXDisplay.InterlacedTest) return bFullVRam;      // -> ok, no need for adjust\r
1116                                \r
1117    vertex[0].x=lx0 - PSXDisplay.DisplayPosition.x+PreviousPSXDisplay.Range.x0;\r
1118    vertex[1].x=lx1 - PSXDisplay.DisplayPosition.x+PreviousPSXDisplay.Range.x0;\r
1119    vertex[2].x=lx2 - PSXDisplay.DisplayPosition.x+PreviousPSXDisplay.Range.x0;\r
1120    vertex[3].x=lx3 - PSXDisplay.DisplayPosition.x+PreviousPSXDisplay.Range.x0;\r
1121    vertex[0].y=ly0 - PSXDisplay.DisplayPosition.y+PreviousPSXDisplay.Range.y0;\r
1122    vertex[1].y=ly1 - PSXDisplay.DisplayPosition.y+PreviousPSXDisplay.Range.y0;\r
1123    vertex[2].y=ly2 - PSXDisplay.DisplayPosition.y+PreviousPSXDisplay.Range.y0;\r
1124    vertex[3].y=ly3 - PSXDisplay.DisplayPosition.y+PreviousPSXDisplay.Range.y0;\r
1125 \r
1126    if(iOffscreenDrawing==4 && !(dwActFixes&1))         // -> frontbuffer wanted\r
1127     {\r
1128      bRenderFrontBuffer=TRUE;\r
1129      //return TRUE;\r
1130     }\r
1131    return bFullVRam;                                   // -> but no od\r
1132   }\r
1133 \r
1134  return TRUE;\r
1135 }\r
1136 \r
1137 ////////////////////////////////////////////////////////////////////////\r
1138  \r
1139 BOOL bDrawOffscreen3(void)\r
1140 {\r
1141  BOOL bFront;short sW,sH;\r
1142 \r
1143  sxmax=max(lx0,max(lx1,lx2));\r
1144  if(sxmax<drawX) return FALSE;\r
1145  sxmin=min(lx0,min(lx1,lx2));\r
1146  if(sxmin>drawW) return FALSE;\r
1147  symax=max(ly0,max(ly1,ly2));\r
1148  if(symax<drawY) return FALSE;\r
1149  symin=min(ly0,min(ly1,ly2));\r
1150  if(symin>drawH) return FALSE;\r
1151 \r
1152  if(PSXDisplay.Disabled) return TRUE;                  // disabled? ever\r
1153 \r
1154  if(iOffscreenDrawing==1) return bFullVRam;\r
1155 \r
1156  sW=drawW-1;sH=drawH-1;\r
1157  sxmin=min(sW,max(sxmin,drawX));\r
1158  sxmax=max(drawX,min(sxmax,sW));\r
1159  symin=min(sH,max(symin,drawY));\r
1160  symax=max(drawY,min(symax,sH));\r
1161 \r
1162  if(bOnePointInBack()) return bFullVRam;\r
1163 \r
1164  if(iOffscreenDrawing==2) \r
1165       bFront=bDrawOffscreenFront();\r
1166  else bFront=bOnePointInFront();\r
1167 \r
1168  if(bFront)\r
1169   {\r
1170    if(PSXDisplay.InterlacedTest) return bFullVRam;     // -> ok, no need for adjust\r
1171 \r
1172    vertex[0].x=lx0 - PSXDisplay.DisplayPosition.x+PreviousPSXDisplay.Range.x0;\r
1173    vertex[1].x=lx1 - PSXDisplay.DisplayPosition.x+PreviousPSXDisplay.Range.x0;\r
1174    vertex[2].x=lx2 - PSXDisplay.DisplayPosition.x+PreviousPSXDisplay.Range.x0;\r
1175    vertex[0].y=ly0 - PSXDisplay.DisplayPosition.y+PreviousPSXDisplay.Range.y0;\r
1176    vertex[1].y=ly1 - PSXDisplay.DisplayPosition.y+PreviousPSXDisplay.Range.y0;\r
1177    vertex[2].y=ly2 - PSXDisplay.DisplayPosition.y+PreviousPSXDisplay.Range.y0;\r
1178 \r
1179    if(iOffscreenDrawing==4)                            // -> frontbuffer wanted\r
1180     {\r
1181      bRenderFrontBuffer=TRUE;\r
1182    //  return TRUE;\r
1183     }\r
1184 \r
1185    return bFullVRam;                                   // -> but no od\r
1186   }\r
1187 \r
1188  return TRUE;\r
1189 }\r
1190 \r
1191 ////////////////////////////////////////////////////////////////////////\r
1192 \r
1193 BOOL FastCheckAgainstScreen(short imageX0,short imageY0,short imageX1,short imageY1)\r
1194 {\r
1195  PSXRect_t xUploadArea;\r
1196 \r
1197  imageX1 += imageX0;\r
1198  imageY1 += imageY0;\r
1199 \r
1200  if (imageX0 < PreviousPSXDisplay.DisplayPosition.x)\r
1201    xUploadArea.x0 = PreviousPSXDisplay.DisplayPosition.x;\r
1202  else\r
1203  if (imageX0 > PreviousPSXDisplay.DisplayEnd.x)\r
1204    xUploadArea.x0 = PreviousPSXDisplay.DisplayEnd.x;\r
1205  else\r
1206    xUploadArea.x0 = imageX0;\r
1207 \r
1208  if(imageX1 < PreviousPSXDisplay.DisplayPosition.x)\r
1209    xUploadArea.x1 = PreviousPSXDisplay.DisplayPosition.x;\r
1210  else\r
1211  if (imageX1 > PreviousPSXDisplay.DisplayEnd.x)\r
1212    xUploadArea.x1 = PreviousPSXDisplay.DisplayEnd.x;\r
1213  else\r
1214    xUploadArea.x1 = imageX1;\r
1215 \r
1216  if (imageY0 < PreviousPSXDisplay.DisplayPosition.y)\r
1217    xUploadArea.y0 = PreviousPSXDisplay.DisplayPosition.y;\r
1218  else\r
1219  if (imageY0 > PreviousPSXDisplay.DisplayEnd.y)\r
1220    xUploadArea.y0 = PreviousPSXDisplay.DisplayEnd.y;\r
1221  else\r
1222    xUploadArea.y0 = imageY0;\r
1223 \r
1224  if (imageY1 < PreviousPSXDisplay.DisplayPosition.y)\r
1225    xUploadArea.y1 = PreviousPSXDisplay.DisplayPosition.y;\r
1226  else\r
1227  if (imageY1 > PreviousPSXDisplay.DisplayEnd.y)\r
1228    xUploadArea.y1 = PreviousPSXDisplay.DisplayEnd.y;\r
1229  else\r
1230    xUploadArea.y1 = imageY1;\r
1231 \r
1232  if ((xUploadArea.x0 != xUploadArea.x1) && (xUploadArea.y0 != xUploadArea.y1))\r
1233       return TRUE;\r
1234  else return FALSE;\r
1235 }\r
1236 \r
1237 BOOL CheckAgainstScreen(short imageX0,short imageY0,short imageX1,short imageY1)\r
1238 {\r
1239  imageX1 += imageX0;\r
1240  imageY1 += imageY0;\r
1241 \r
1242  if (imageX0 < PreviousPSXDisplay.DisplayPosition.x)\r
1243    xrUploadArea.x0 = PreviousPSXDisplay.DisplayPosition.x;\r
1244  else\r
1245  if (imageX0 > PreviousPSXDisplay.DisplayEnd.x)\r
1246    xrUploadArea.x0 = PreviousPSXDisplay.DisplayEnd.x;\r
1247  else\r
1248    xrUploadArea.x0 = imageX0;\r
1249 \r
1250  if(imageX1 < PreviousPSXDisplay.DisplayPosition.x)\r
1251    xrUploadArea.x1 = PreviousPSXDisplay.DisplayPosition.x;\r
1252  else\r
1253  if (imageX1 > PreviousPSXDisplay.DisplayEnd.x)\r
1254    xrUploadArea.x1 = PreviousPSXDisplay.DisplayEnd.x;\r
1255  else\r
1256    xrUploadArea.x1 = imageX1;\r
1257 \r
1258  if (imageY0 < PreviousPSXDisplay.DisplayPosition.y)\r
1259    xrUploadArea.y0 = PreviousPSXDisplay.DisplayPosition.y;\r
1260  else\r
1261  if (imageY0 > PreviousPSXDisplay.DisplayEnd.y)\r
1262    xrUploadArea.y0 = PreviousPSXDisplay.DisplayEnd.y;\r
1263  else\r
1264    xrUploadArea.y0 = imageY0;\r
1265 \r
1266  if (imageY1 < PreviousPSXDisplay.DisplayPosition.y)\r
1267    xrUploadArea.y1 = PreviousPSXDisplay.DisplayPosition.y;\r
1268  else\r
1269  if (imageY1 > PreviousPSXDisplay.DisplayEnd.y)\r
1270    xrUploadArea.y1 = PreviousPSXDisplay.DisplayEnd.y;\r
1271  else\r
1272    xrUploadArea.y1 = imageY1;\r
1273 \r
1274  if ((xrUploadArea.x0 != xrUploadArea.x1) && (xrUploadArea.y0 != xrUploadArea.y1))\r
1275       return TRUE;\r
1276  else return FALSE;\r
1277 }\r
1278 \r
1279 BOOL FastCheckAgainstFrontScreen(short imageX0,short imageY0,short imageX1,short imageY1)\r
1280 {\r
1281  PSXRect_t xUploadArea;\r
1282 \r
1283  imageX1 += imageX0;\r
1284  imageY1 += imageY0;\r
1285 \r
1286  if (imageX0 < PSXDisplay.DisplayPosition.x)\r
1287    xUploadArea.x0 = PSXDisplay.DisplayPosition.x;\r
1288  else\r
1289  if (imageX0 > PSXDisplay.DisplayEnd.x)\r
1290    xUploadArea.x0 = PSXDisplay.DisplayEnd.x;\r
1291  else\r
1292    xUploadArea.x0 = imageX0;\r
1293 \r
1294  if(imageX1 < PSXDisplay.DisplayPosition.x)\r
1295    xUploadArea.x1 = PSXDisplay.DisplayPosition.x;\r
1296  else\r
1297  if (imageX1 > PSXDisplay.DisplayEnd.x)\r
1298    xUploadArea.x1 = PSXDisplay.DisplayEnd.x;\r
1299  else\r
1300    xUploadArea.x1 = imageX1;\r
1301 \r
1302  if (imageY0 < PSXDisplay.DisplayPosition.y)\r
1303    xUploadArea.y0 = PSXDisplay.DisplayPosition.y;\r
1304  else\r
1305  if (imageY0 > PSXDisplay.DisplayEnd.y)\r
1306    xUploadArea.y0 = PSXDisplay.DisplayEnd.y;\r
1307  else\r
1308    xUploadArea.y0 = imageY0;\r
1309 \r
1310  if (imageY1 < PSXDisplay.DisplayPosition.y)\r
1311    xUploadArea.y1 = PSXDisplay.DisplayPosition.y;\r
1312  else\r
1313  if (imageY1 > PSXDisplay.DisplayEnd.y)\r
1314    xUploadArea.y1 = PSXDisplay.DisplayEnd.y;\r
1315  else\r
1316    xUploadArea.y1 = imageY1;\r
1317 \r
1318  if ((xUploadArea.x0 != xUploadArea.x1) && (xUploadArea.y0 != xUploadArea.y1))\r
1319       return TRUE; \r
1320  else return FALSE;\r
1321 }\r
1322 \r
1323 BOOL CheckAgainstFrontScreen(short imageX0,short imageY0,short imageX1,short imageY1)\r
1324 {\r
1325  imageX1 += imageX0;\r
1326  imageY1 += imageY0;\r
1327 \r
1328  if (imageX0 < PSXDisplay.DisplayPosition.x)\r
1329    xrUploadArea.x0 = PSXDisplay.DisplayPosition.x;\r
1330  else\r
1331  if (imageX0 > PSXDisplay.DisplayEnd.x)\r
1332    xrUploadArea.x0 = PSXDisplay.DisplayEnd.x;\r
1333  else\r
1334    xrUploadArea.x0 = imageX0;\r
1335 \r
1336  if(imageX1 < PSXDisplay.DisplayPosition.x)\r
1337    xrUploadArea.x1 = PSXDisplay.DisplayPosition.x;\r
1338  else\r
1339  if (imageX1 > PSXDisplay.DisplayEnd.x)\r
1340    xrUploadArea.x1 = PSXDisplay.DisplayEnd.x;\r
1341  else\r
1342    xrUploadArea.x1 = imageX1;\r
1343 \r
1344  if (imageY0 < PSXDisplay.DisplayPosition.y)\r
1345    xrUploadArea.y0 = PSXDisplay.DisplayPosition.y;\r
1346  else\r
1347  if (imageY0 > PSXDisplay.DisplayEnd.y)\r
1348    xrUploadArea.y0 = PSXDisplay.DisplayEnd.y;\r
1349  else\r
1350    xrUploadArea.y0 = imageY0;\r
1351 \r
1352  if (imageY1 < PSXDisplay.DisplayPosition.y)\r
1353    xrUploadArea.y1 = PSXDisplay.DisplayPosition.y;\r
1354  else\r
1355  if (imageY1 > PSXDisplay.DisplayEnd.y)\r
1356    xrUploadArea.y1 = PSXDisplay.DisplayEnd.y;\r
1357  else\r
1358    xrUploadArea.y1 = imageY1;\r
1359 \r
1360  if ((xrUploadArea.x0 != xrUploadArea.x1) && (xrUploadArea.y0 != xrUploadArea.y1))\r
1361       return TRUE; \r
1362  else return FALSE;\r
1363 }\r
1364 \r
1365 ////////////////////////////////////////////////////////////////////////\r
1366 \r
1367 void PrepareFullScreenUpload (long Position)\r
1368 {\r
1369  if (Position==-1)                                     // rgb24\r
1370   {\r
1371    if(PSXDisplay.Interlaced)\r
1372     {\r
1373      xrUploadArea.x0 = PSXDisplay.DisplayPosition.x;\r
1374      xrUploadArea.x1 = PSXDisplay.DisplayEnd.x;\r
1375      xrUploadArea.y0 = PSXDisplay.DisplayPosition.y;\r
1376      xrUploadArea.y1 = PSXDisplay.DisplayEnd.y;\r
1377     }\r
1378    else\r
1379     {\r
1380      xrUploadArea.x0 = PreviousPSXDisplay.DisplayPosition.x;\r
1381      xrUploadArea.x1 = PreviousPSXDisplay.DisplayEnd.x;\r
1382      xrUploadArea.y0 = PreviousPSXDisplay.DisplayPosition.y;\r
1383      xrUploadArea.y1 = PreviousPSXDisplay.DisplayEnd.y;\r
1384     }\r
1385 \r
1386    if(bNeedRGB24Update)\r
1387     {\r
1388      if(lClearOnSwap) \r
1389       {\r
1390 //       lClearOnSwap=0;\r
1391       }\r
1392      else    \r
1393      if(PSXDisplay.Interlaced && PreviousPSXDisplay.RGB24<2) // in interlaced mode we upload at least two full frames (GT1 menu)\r
1394       {\r
1395        PreviousPSXDisplay.RGB24++;\r
1396       }\r
1397      else\r
1398       {\r
1399        xrUploadArea.y1 = min(xrUploadArea.y0+xrUploadAreaRGB24.y1,xrUploadArea.y1);\r
1400        xrUploadArea.y0+=xrUploadAreaRGB24.y0;\r
1401       }\r
1402     }\r
1403   }\r
1404  else\r
1405  if (Position)\r
1406   {\r
1407    xrUploadArea.x0 = PSXDisplay.DisplayPosition.x;\r
1408    xrUploadArea.x1 = PSXDisplay.DisplayEnd.x;\r
1409    xrUploadArea.y0 = PSXDisplay.DisplayPosition.y;\r
1410    xrUploadArea.y1 = PSXDisplay.DisplayEnd.y;\r
1411   }\r
1412  else\r
1413   {\r
1414    xrUploadArea.x0 = PreviousPSXDisplay.DisplayPosition.x;\r
1415    xrUploadArea.x1 = PreviousPSXDisplay.DisplayEnd.x;\r
1416    xrUploadArea.y0 = PreviousPSXDisplay.DisplayPosition.y;\r
1417    xrUploadArea.y1 = PreviousPSXDisplay.DisplayEnd.y;\r
1418   }\r
1419 \r
1420  if (xrUploadArea.x0 < 0)               xrUploadArea.x0 = 0;\r
1421  else\r
1422  if (xrUploadArea.x0 > 1023)            xrUploadArea.x0 = 1023;\r
1423 \r
1424  if (xrUploadArea.x1 < 0)               xrUploadArea.x1 = 0;\r
1425  else\r
1426  if (xrUploadArea.x1 > 1024)            xrUploadArea.x1 = 1024;\r
1427 \r
1428  if (xrUploadArea.y0 < 0)               xrUploadArea.y0 = 0;\r
1429  else\r
1430  if (xrUploadArea.y0 > iGPUHeightMask)  xrUploadArea.y0 = iGPUHeightMask;\r
1431 \r
1432  if (xrUploadArea.y1 < 0)               xrUploadArea.y1 = 0;\r
1433  else\r
1434  if (xrUploadArea.y1 > iGPUHeight)      xrUploadArea.y1 = iGPUHeight;\r
1435 \r
1436  if (PSXDisplay.RGB24)\r
1437   {\r
1438    InvalidateTextureArea(xrUploadArea.x0,xrUploadArea.y0,xrUploadArea.x1-xrUploadArea.x0,xrUploadArea.y1-xrUploadArea.y0);\r
1439   }\r
1440 }\r
1441 \r
1442 ////////////////////////////////////////////////////////////////////////\r
1443 // Upload screen (MDEC and such)\r
1444 ////////////////////////////////////////////////////////////////////////\r
1445 ////////////////////////////////////////////////////////////////////////\r
1446 \r
1447 unsigned char * LoadDirectMovieFast(void);\r
1448 \r
1449 void UploadScreenEx(long Position)\r
1450 {\r
1451  short ya,yb,xa,xb,x, y, YStep, XStep, U, UStep,ux[4],vy[4];\r
1452 \r
1453  if(!PSXDisplay.DisplayMode.x) return;\r
1454  if(!PSXDisplay.DisplayMode.y) return;\r
1455 \r
1456  glDisable(GL_SCISSOR_TEST); glError();\r
1457  glShadeModel(GL_FLAT); glError();\r
1458  bOldSmoothShaded=FALSE;\r
1459  glDisable(GL_BLEND); glError();\r
1460  bBlendEnable=FALSE;\r
1461  glDisable(GL_TEXTURE_2D); glError();\r
1462  bTexEnabled=FALSE;\r
1463  glDisable(GL_ALPHA_TEST); glError();\r
1464 \r
1465  //glPixelZoom(((float)rRatioRect.right)/((float)PSXDisplay.DisplayMode.x),\r
1466  //            -1.0f*(((float)rRatioRect.bottom)/((float)PSXDisplay.DisplayMode.y)));\r
1467                                                       \r
1468  //----------------------------------------------------//\r
1469 \r
1470  YStep = 256;                                          // max texture size\r
1471  XStep = 256;\r
1472  UStep = (PSXDisplay.RGB24 ? 128 : 0);\r
1473  ya    = xrUploadArea.y0;\r
1474  yb    = xrUploadArea.y1;\r
1475  xa    = xrUploadArea.x0;\r
1476  xb    = xrUploadArea.x1;\r
1477  \r
1478  for(y=ya;y<=yb;y+=YStep)                              // loop y\r
1479   {\r
1480    U = 0;\r
1481    for(x=xa;x<=xb;x+=XStep)                            // loop x\r
1482     {\r
1483      ly0 = ly1 = y;                                    // -> get y coords\r
1484      ly2 = y + YStep;\r
1485      if (ly2 > yb) ly2 = yb;\r
1486      ly3 = ly2;\r
1487 \r
1488      lx0 = lx3 = x;                                    // -> get x coords\r
1489      lx1 = x + XStep;\r
1490      if (lx1 > xb) lx1 = xb;\r
1491 \r
1492      lx2 = lx1;\r
1493 \r
1494      ux[0]=ux[3]=(xa - x);                             // -> set tex x coords\r
1495      if (ux[0] < 0) ux[0]=ux[3]=0;\r
1496      ux[2]=ux[1]=(xb - x);\r
1497      if (ux[2] > 256) ux[2]=ux[1]=256;\r
1498 \r
1499      vy[0]=vy[1]=(ya - y);                             // -> set tex y coords\r
1500      if (vy[0] < 0) vy[0]=vy[1]=0;\r
1501      vy[2]=vy[3]=(yb - y);\r
1502      if (vy[2] > 256) vy[2]=vy[3]=256;\r
1503 \r
1504      if ((ux[0] >= ux[2]) ||                           // -> cheaters never win...\r
1505          (vy[0] >= vy[2])) continue;                   //    (but winners always cheat...)\r
1506                 \r
1507      xrMovieArea.x0=lx0+U; xrMovieArea.y0=ly0;\r
1508      xrMovieArea.x1=lx2+U; xrMovieArea.y1=ly2;\r
1509      \r
1510      offsetScreenUpload(Position);\r
1511 \r
1512      //glRasterPos2f(vertex[0].x,vertex[0].y);\r
1513 \r
1514      //glDrawPixels(xrMovieArea.x1-xrMovieArea.x0,\r
1515      //             xrMovieArea.y1-xrMovieArea.y0,\r
1516      //             GL_RGBA,GL_UNSIGNED_BYTE,\r
1517                   LoadDirectMovieFast();//);\r
1518 \r
1519      U+=UStep;\r
1520     }\r
1521   }\r
1522 \r
1523  //----------------------------------------------------//\r
1524 \r
1525 // glPixelZoom(1.0F,1.0F);\r
1526 \r
1527  glEnable(GL_ALPHA_TEST); glError();\r
1528  glEnable(GL_SCISSOR_TEST); glError();\r
1529 }\r
1530 \r
1531 ////////////////////////////////////////////////////////////////////////\r
1532 \r
1533 void UploadScreen(long Position)\r
1534 {\r
1535  short x, y, YStep, XStep, U, s, UStep,ux[4],vy[4];\r
1536  short xa,xb,ya,yb;\r
1537 \r
1538  if(xrUploadArea.x0>1023) xrUploadArea.x0=1023;\r
1539  if(xrUploadArea.x1>1024) xrUploadArea.x1=1024;\r
1540  if(xrUploadArea.y0>iGPUHeightMask)  xrUploadArea.y0=iGPUHeightMask;\r
1541  if(xrUploadArea.y1>iGPUHeight)      xrUploadArea.y1=iGPUHeight;\r
1542 \r
1543  if(xrUploadArea.x0==xrUploadArea.x1) return;\r
1544  if(xrUploadArea.y0==xrUploadArea.y1) return;\r
1545 \r
1546  if(PSXDisplay.Disabled && iOffscreenDrawing<4) return;\r
1547 \r
1548  iDrawnSomething   = 2;\r
1549  iLastRGB24=PSXDisplay.RGB24+1;\r
1550 \r
1551  if(bSkipNextFrame) return;\r
1552 \r
1553  if(dwActFixes & 2) {UploadScreenEx(Position);return;}\r
1554 \r
1555  bUsingMovie       = TRUE;\r
1556  bDrawTextured     = TRUE;                             // just doing textures\r
1557  bDrawSmoothShaded = FALSE;\r
1558 \r
1559 /* if(bGLBlend) vertex[0].c.lcol=0xff7f7f7f;             // set solid col\r
1560  else          */vertex[0].c.lcol=0xffffffff;\r
1561  SETCOL(vertex[0]); \r
1562 \r
1563  SetOGLDisplaySettings(0);\r
1564 \r
1565  YStep = 256;                                          // max texture size\r
1566  XStep = 256;\r
1567 \r
1568  UStep = (PSXDisplay.RGB24 ? 128 : 0);\r
1569  \r
1570  ya=xrUploadArea.y0;\r
1571  yb=xrUploadArea.y1;\r
1572  xa=xrUploadArea.x0;\r
1573  xb=xrUploadArea.x1;\r
1574 \r
1575  for(y=ya;y<=yb;y+=YStep)                              // loop y\r
1576   {\r
1577    U = 0;\r
1578    for(x=xa;x<=xb;x+=XStep)                            // loop x\r
1579     {\r
1580      ly0 = ly1 = y;                                    // -> get y coords\r
1581      ly2 = y + YStep;\r
1582      if (ly2 > yb) ly2 = yb;\r
1583      ly3 = ly2;\r
1584 \r
1585      lx0 = lx3 = x;                                    // -> get x coords\r
1586      lx1 = x + XStep;\r
1587      if (lx1 > xb) lx1 = xb;\r
1588 \r
1589      lx2 = lx1;\r
1590 \r
1591      ux[0]=ux[3]=(xa - x);                             // -> set tex x coords\r
1592      if (ux[0] < 0) ux[0]=ux[3]=0;\r
1593      ux[2]=ux[1]=(xb - x);\r
1594      if (ux[2] > 256) ux[2]=ux[1]=256;\r
1595 \r
1596      vy[0]=vy[1]=(ya - y);                             // -> set tex y coords\r
1597      if (vy[0] < 0) vy[0]=vy[1]=0;\r
1598      vy[2]=vy[3]=(yb - y);\r
1599      if (vy[2] > 256) vy[2]=vy[3]=256;\r
1600 \r
1601      if ((ux[0] >= ux[2]) ||                           // -> cheaters never win...\r
1602          (vy[0] >= vy[2])) continue;                   //    (but winners always cheat...)\r
1603                 \r
1604      xrMovieArea.x0=lx0+U; xrMovieArea.y0=ly0;\r
1605      xrMovieArea.x1=lx2+U; xrMovieArea.y1=ly2;\r
1606 \r
1607      s=ux[2] - ux[0]; if(s>255) s=255;\r
1608 \r
1609      gl_ux[2] = gl_ux[1] = s;\r
1610      s=vy[2] - vy[0]; if(s>255) s=255;\r
1611      gl_vy[2] = gl_vy[3] = s;\r
1612      gl_ux[0] = gl_ux[3] = gl_vy[0] = gl_vy[1] = 0;\r
1613 \r
1614      SetRenderState((unsigned long)0x01000000);\r
1615      SetRenderMode((unsigned long)0x01000000, FALSE);  // upload texture data\r
1616      offsetScreenUpload(Position);\r
1617      assignTextureVRAMWrite();\r
1618 \r
1619      PRIMdrawTexturedQuad(&vertex[0], &vertex[1], &vertex[2], &vertex[3]);\r
1620 \r
1621      U+=UStep;\r
1622     }\r
1623   }\r
1624 \r
1625  bUsingMovie=FALSE;                                    // done...\r
1626  bDisplayNotSet = TRUE;\r
1627 }\r
1628 \r
1629 ////////////////////////////////////////////////////////////////////////\r
1630 // Detect next screen\r
1631 ////////////////////////////////////////////////////////////////////////\r
1632 \r
1633 BOOL IsCompleteInsideNextScreen(short x, short y, short xoff, short yoff)\r
1634 {        \r
1635  if (x > PSXDisplay.DisplayPosition.x+1)     return FALSE;\r
1636  if ((x + xoff) < PSXDisplay.DisplayEnd.x-1) return FALSE;\r
1637  yoff+=y;\r
1638  if (y >= PSXDisplay.DisplayPosition.y &&\r
1639      y <= PSXDisplay.DisplayEnd.y )\r
1640   {\r
1641    if ((yoff) >= PSXDisplay.DisplayPosition.y &&\r
1642        (yoff) <= PSXDisplay.DisplayEnd.y ) return TRUE;\r
1643   }   \r
1644  if (y > PSXDisplay.DisplayPosition.y+1) return FALSE;\r
1645  if (yoff < PSXDisplay.DisplayEnd.y-1)   return FALSE;\r
1646  return TRUE;\r
1647 }\r
1648 \r
1649 BOOL IsPrimCompleteInsideNextScreen(short x, short y, short xoff, short yoff)\r
1650 {\r
1651  x+=PSXDisplay.DrawOffset.x;\r
1652  if (x > PSXDisplay.DisplayPosition.x+1) return FALSE;\r
1653  y+=PSXDisplay.DrawOffset.y;\r
1654  if (y > PSXDisplay.DisplayPosition.y+1) return FALSE;\r
1655  xoff+=PSXDisplay.DrawOffset.x;\r
1656  if (xoff < PSXDisplay.DisplayEnd.x-1)   return FALSE;\r
1657  yoff+=PSXDisplay.DrawOffset.y;\r
1658  if (yoff < PSXDisplay.DisplayEnd.y-1)   return FALSE;\r
1659  return TRUE;\r
1660 }\r
1661 \r
1662 BOOL IsInsideNextScreen(short x, short y, short xoff, short yoff)\r
1663 {                    \r
1664  if (x > PSXDisplay.DisplayEnd.x) return FALSE;\r
1665  if (y > PSXDisplay.DisplayEnd.y) return FALSE;\r
1666  if ((x + xoff) < PSXDisplay.DisplayPosition.x) return FALSE;\r
1667  if ((y + yoff) < PSXDisplay.DisplayPosition.y) return FALSE;\r
1668  return TRUE;\r
1669 }\r
1670 \r
1671 ////////////////////////////////////////////////////////////////////////\r
1672 // mask stuff...\r
1673 ////////////////////////////////////////////////////////////////////////\r
1674 \r
1675 //Mask1    Set mask bit while drawing. 1 = on\r
1676 //Mask2    Do not draw to mask areas. 1= on\r
1677 \r
1678 void cmdSTP(unsigned char * baseAddr)\r
1679 {\r
1680  unsigned long gdata = ((unsigned long*)baseAddr)[0];\r
1681 \r
1682  STATUSREG&=~0x1800;                                   // clear the necessary bits\r
1683  STATUSREG|=((gdata & 0x03) << 11);                    // set the current bits\r
1684 \r
1685  if(!iUseMask) return;\r
1686 \r
1687  if(gdata&1) {sSetMask=0x8000;lSetMask=0x80008000;iSetMask=1;}\r
1688  else        {sSetMask=0;     lSetMask=0;         iSetMask=0;}\r
1689 \r
1690  if(gdata&2) \r
1691   {\r
1692    if(!(gdata&1)) iSetMask=2;\r
1693    bCheckMask=TRUE;\r
1694    if(iDepthFunc==0) return;\r
1695    iDepthFunc=0;\r
1696    glDepthFunc(GL_LESS); glError();\r
1697   }\r
1698  else\r
1699   {\r
1700    bCheckMask=FALSE;\r
1701    if(iDepthFunc==1) return;\r
1702    glDepthFunc(GL_ALWAYS); glError();\r
1703    iDepthFunc=1;\r
1704   }\r
1705 }\r
1706 \r
1707 ////////////////////////////////////////////////////////////////////////\r
1708 // cmd: Set texture page infos\r
1709 ////////////////////////////////////////////////////////////////////////\r
1710 \r
1711 void cmdTexturePage(unsigned char * baseAddr)\r
1712 {\r
1713  unsigned long gdata = ((unsigned long*)baseAddr)[0];\r
1714  UpdateGlobalTP((unsigned short)gdata);\r
1715  GlobalTextREST = (gdata&0x00ffffff)>>9;\r
1716 }\r
1717 \r
1718 ////////////////////////////////////////////////////////////////////////\r
1719 // cmd: turn on/off texture window\r
1720 ////////////////////////////////////////////////////////////////////////\r
1721 \r
1722 void cmdTextureWindow(unsigned char *baseAddr)\r
1723 {\r
1724  unsigned long gdata = ((unsigned long*)baseAddr)[0];\r
1725 \r
1726  unsigned long YAlign,XAlign;\r
1727 \r
1728  ulGPUInfoVals[INFO_TW]=gdata&0xFFFFF;\r
1729 \r
1730  if(gdata & 0x020)\r
1731   TWin.Position.y1 = 8;    // xxxx1\r
1732  else if (gdata & 0x040)\r
1733   TWin.Position.y1 = 16;   // xxx10\r
1734  else if (gdata & 0x080)\r
1735   TWin.Position.y1 = 32;   // xx100\r
1736  else if (gdata & 0x100)\r
1737   TWin.Position.y1 = 64;   // x1000\r
1738  else if (gdata & 0x200)\r
1739   TWin.Position.y1 = 128;  // 10000\r
1740  else\r
1741   TWin.Position.y1 = 256;  // 00000\r
1742 \r
1743   // Texture window size is determined by the least bit set of the relevant 5 bits\r
1744 \r
1745  if (gdata & 0x001)\r
1746   TWin.Position.x1 = 8;    // xxxx1\r
1747  else if (gdata & 0x002)\r
1748   TWin.Position.x1 = 16;   // xxx10\r
1749  else if (gdata & 0x004)\r
1750   TWin.Position.x1 = 32;   // xx100\r
1751  else if (gdata & 0x008)\r
1752   TWin.Position.x1 = 64;   // x1000\r
1753  else if (gdata & 0x010)\r
1754   TWin.Position.x1 = 128;  // 10000\r
1755  else\r
1756   TWin.Position.x1 = 256;  // 00000\r
1757 \r
1758  // Re-calculate the bit field, because we can't trust what is passed in the data\r
1759 \r
1760  YAlign = (unsigned long)(32 - (TWin.Position.y1 >> 3));\r
1761  XAlign = (unsigned long)(32 - (TWin.Position.x1 >> 3));\r
1762 \r
1763  // Absolute position of the start of the texture window\r
1764 \r
1765  TWin.Position.y0 = (short)(((gdata >> 15) & YAlign) << 3);\r
1766  TWin.Position.x0 = (short)(((gdata >> 10) & XAlign) << 3);\r
1767 \r
1768  if((TWin.Position.x0 == 0 &&                          // tw turned off\r
1769      TWin.Position.y0 == 0 &&\r
1770      TWin.Position.x1 == 0 &&\r
1771      TWin.Position.y1 == 0) ||\r
1772      (TWin.Position.x1 == 256 &&\r
1773       TWin.Position.y1 == 256))\r
1774   {\r
1775    bUsingTWin = FALSE;                                 // -> just do it\r
1776 \r
1777 #ifdef OWNSCALE\r
1778    TWin.UScaleFactor = 1.0f;\r
1779    TWin.VScaleFactor = 1.0f;\r
1780 #else\r
1781    TWin.UScaleFactor = \r
1782    TWin.VScaleFactor = 1.0f/256.0f;\r
1783 #endif\r
1784   }\r
1785  else                                                  // tw turned on\r
1786   {\r
1787    bUsingTWin = TRUE;\r
1788 \r
1789    TWin.OPosition.y1 = TWin.Position.y1;               // -> get psx sizes\r
1790    TWin.OPosition.x1 = TWin.Position.x1;              \r
1791 \r
1792    if(TWin.Position.x1<=2)   TWin.Position.x1=2;       // -> set OGL sizes\r
1793    else\r
1794    if(TWin.Position.x1<=4)   TWin.Position.x1=4;\r
1795    else\r
1796    if(TWin.Position.x1<=8)   TWin.Position.x1=8;\r
1797    else\r
1798    if(TWin.Position.x1<=16)  TWin.Position.x1=16;\r
1799    else\r
1800    if(TWin.Position.x1<=32)  TWin.Position.x1=32;\r
1801    else\r
1802    if(TWin.Position.x1<=64)  TWin.Position.x1=64;\r
1803    else\r
1804    if(TWin.Position.x1<=128) TWin.Position.x1=128;\r
1805    else\r
1806    if(TWin.Position.x1<=256) TWin.Position.x1=256;\r
1807    \r
1808    if(TWin.Position.y1<=2)   TWin.Position.y1=2;\r
1809    else\r
1810    if(TWin.Position.y1<=4)   TWin.Position.y1=4;\r
1811    else\r
1812    if(TWin.Position.y1<=8)   TWin.Position.y1=8;\r
1813    else\r
1814    if(TWin.Position.y1<=16)  TWin.Position.y1=16;\r
1815    else\r
1816    if(TWin.Position.y1<=32)  TWin.Position.y1=32;\r
1817    else\r
1818    if(TWin.Position.y1<=64)  TWin.Position.y1=64;\r
1819    else\r
1820    if(TWin.Position.y1<=128) TWin.Position.y1=128;\r
1821    else\r
1822    if(TWin.Position.y1<=256) TWin.Position.y1=256;\r
1823 \r
1824 #ifdef OWNSCALE\r
1825    TWin.UScaleFactor = (float)TWin.Position.x1;\r
1826    TWin.VScaleFactor = (float)TWin.Position.y1;\r
1827 #else\r
1828    TWin.UScaleFactor = ((float)TWin.Position.x1)/256.0f; // -> set scale factor\r
1829    TWin.VScaleFactor = ((float)TWin.Position.y1)/256.0f;\r
1830 #endif\r
1831   }\r
1832 }\r
1833 \r
1834 ////////////////////////////////////////////////////////////////////////\r
1835 // mmm, Lewpy uses that in TileS ... I don't ;)\r
1836 ////////////////////////////////////////////////////////////////////////\r
1837 \r
1838 /*\r
1839 void ClampToPSXDrawAreaOffset(short *x0, short *y0, short *x1, short *y1)\r
1840 {\r
1841  if (*x0 < PSXDisplay.DrawArea.x0)\r
1842   {\r
1843    *x1 -= (PSXDisplay.DrawArea.x0 - *x0);\r
1844    *x0 = PSXDisplay.DrawArea.x0;\r
1845   }\r
1846  else\r
1847  if (*x0 > PSXDisplay.DrawArea.x1)\r
1848   {\r
1849    *x0 = PSXDisplay.DrawArea.x1;\r
1850    *x1 = 0;\r
1851   }\r
1852 \r
1853  if (*y0 < PSXDisplay.DrawArea.y0)\r
1854   {\r
1855    *y1 -= (PSXDisplay.DrawArea.y0 - *y0);\r
1856    *y0 = PSXDisplay.DrawArea.y0;\r
1857   }\r
1858  else\r
1859  if (*y0 > PSXDisplay.DrawArea.y1)\r
1860   {\r
1861    *y0 = PSXDisplay.DrawArea.y1;\r
1862    *y1 = 0;\r
1863   }\r
1864 \r
1865  if (*x1 < 0) *x1 = 0;\r
1866 \r
1867  if ((*x1 + *x0) > PSXDisplay.DrawArea.x1)\r
1868   *x1 = (PSXDisplay.DrawArea.x1 -  *x0 + 1);\r
1869 \r
1870  if (*y1 < 0) *y1 = 0;\r
1871 \r
1872  if ((*y1 + *y0) > PSXDisplay.DrawArea.y1)\r
1873   *y1 = (PSXDisplay.DrawArea.y1 -  *y0 + 1);\r
1874 }\r
1875 */\r
1876 \r
1877 ////////////////////////////////////////////////////////////////////////\r
1878 // Check draw area dimensions\r
1879 ////////////////////////////////////////////////////////////////////////\r
1880 \r
1881 void ClampToPSXScreen(short *x0, short *y0, short *x1, short *y1)\r
1882 {\r
1883  if (*x0 < 0)               *x0 = 0;\r
1884  else\r
1885  if (*x0 > 1023)            *x0 = 1023;\r
1886             \r
1887  if (*x1 < 0)               *x1 = 0;\r
1888  else\r
1889  if (*x1 > 1023)            *x1 = 1023;\r
1890 \r
1891  if (*y0 < 0)               *y0 = 0;\r
1892  else\r
1893  if (*y0 > iGPUHeightMask)  *y0 = iGPUHeightMask;\r
1894             \r
1895  if (*y1 < 0)               *y1 = 0;\r
1896  else\r
1897  if (*y1 > iGPUHeightMask)  *y1 = iGPUHeightMask;\r
1898 }\r
1899 \r
1900 ////////////////////////////////////////////////////////////////////////\r
1901 // Used in Load Image and Blk Fill\r
1902 ////////////////////////////////////////////////////////////////////////\r
1903 \r
1904 void ClampToPSXScreenOffset(short *x0, short *y0, short *x1, short *y1)\r
1905 {\r
1906  if (*x0 < 0)\r
1907   { *x1 += *x0;  *x0 = 0; }\r
1908  else\r
1909  if (*x0 > 1023)\r
1910   { *x0 = 1023;  *x1 = 0; }\r
1911 \r
1912  if (*y0 < 0)\r
1913   { *y1 += *y0;  *y0 = 0; }\r
1914  else\r
1915  if (*y0 > iGPUHeightMask)\r
1916   { *y0 = iGPUHeightMask;   *y1 = 0; }\r
1917 \r
1918  if (*x1 < 0) *x1 = 0;\r
1919 \r
1920  if ((*x1 + *x0) > 1024) *x1 = (1024 -  *x0);\r
1921 \r
1922  if (*y1 < 0) *y1 = 0;\r
1923 \r
1924  if ((*y1 + *y0) > iGPUHeight)  *y1 = (iGPUHeight -  *y0);\r
1925 }\r
1926 \r
1927 ////////////////////////////////////////////////////////////////////////\r
1928 // cmd: start of drawing area... primitives will be clipped inside\r
1929 ////////////////////////////////////////////////////////////////////////\r
1930 \r
1931 void cmdDrawAreaStart(unsigned char * baseAddr)\r
1932 {\r
1933  unsigned long gdata = ((unsigned long*)baseAddr)[0];\r
1934 \r
1935  drawX = gdata & 0x3ff;                                // for soft drawing\r
1936  if(drawX>=1024) drawX=1023;\r
1937 \r
1938  if(dwGPUVersion==2)\r
1939   {\r
1940    ulGPUInfoVals[INFO_DRAWSTART]=gdata&0x3FFFFF;\r
1941    drawY  = (gdata>>12)&0x3ff;\r
1942   }\r
1943  else\r
1944   {\r
1945    ulGPUInfoVals[INFO_DRAWSTART]=gdata&0xFFFFF;\r
1946    drawY  = (gdata>>10)&0x3ff;\r
1947   }\r
1948 \r
1949  if(drawY>=iGPUHeight) drawY=iGPUHeightMask;\r
1950 \r
1951  PreviousPSXDisplay.DrawArea.y0=PSXDisplay.DrawArea.y0;\r
1952  PreviousPSXDisplay.DrawArea.x0=PSXDisplay.DrawArea.x0;\r
1953 \r
1954  PSXDisplay.DrawArea.y0 = (short)drawY;                // for OGL drawing\r
1955  PSXDisplay.DrawArea.x0 = (short)drawX;\r
1956 }\r
1957 \r
1958 ////////////////////////////////////////////////////////////////////////\r
1959 // cmd: end of drawing area... primitives will be clipped inside\r
1960 ////////////////////////////////////////////////////////////////////////\r
1961 \r
1962 void cmdDrawAreaEnd(unsigned char * baseAddr)\r
1963 {\r
1964  unsigned long gdata = ((unsigned long*)baseAddr)[0];\r
1965 \r
1966  drawW = gdata & 0x3ff;                                // for soft drawing\r
1967  if(drawW>=1024) drawW=1023;\r
1968 \r
1969  if(dwGPUVersion==2)\r
1970   {\r
1971    ulGPUInfoVals[INFO_DRAWEND]=gdata&0x3FFFFF;\r
1972    drawH  = (gdata>>12)&0x3ff;\r
1973   }\r
1974  else\r
1975   {\r
1976    ulGPUInfoVals[INFO_DRAWEND]=gdata&0xFFFFF;\r
1977    drawH  = (gdata>>10)&0x3ff;\r
1978   }\r
1979  \r
1980  if(drawH>=iGPUHeight) drawH=iGPUHeightMask;\r
1981 \r
1982  PSXDisplay.DrawArea.y1 = (short)drawH;                // for OGL drawing\r
1983  PSXDisplay.DrawArea.x1 = (short)drawW;\r
1984 \r
1985  ClampToPSXScreen(&PSXDisplay.DrawArea.x0,             // clamp\r
1986                   &PSXDisplay.DrawArea.y0,\r
1987                   &PSXDisplay.DrawArea.x1,\r
1988                   &PSXDisplay.DrawArea.y1);\r
1989 \r
1990  bDisplayNotSet = TRUE;\r
1991 }\r
1992 \r
1993 ////////////////////////////////////////////////////////////////////////\r
1994 // cmd: draw offset... will be added to prim coords\r
1995 ////////////////////////////////////////////////////////////////////////\r
1996 \r
1997 void cmdDrawOffset(unsigned char * baseAddr)\r
1998 {\r
1999  unsigned long gdata = ((unsigned long*)baseAddr)[0];\r
2000 \r
2001  PreviousPSXDisplay.DrawOffset.x = \r
2002   PSXDisplay.DrawOffset.x = (short)(gdata & 0x7ff);\r
2003 \r
2004  if(dwGPUVersion==2)\r
2005   {\r
2006    ulGPUInfoVals[INFO_DRAWOFF]=gdata&0x7FFFFF;\r
2007    PSXDisplay.DrawOffset.y = (short)((gdata>>12) & 0x7ff);\r
2008   }\r
2009  else\r
2010   {\r
2011    ulGPUInfoVals[INFO_DRAWOFF]=gdata&0x3FFFFF;\r
2012    PSXDisplay.DrawOffset.y = (short)((gdata>>11) & 0x7ff);\r
2013   }\r
2014  \r
2015  PSXDisplay.DrawOffset.x=(short)(((int)PSXDisplay.DrawOffset.x<<21)>>21);\r
2016  PSXDisplay.DrawOffset.y=(short)(((int)PSXDisplay.DrawOffset.y<<21)>>21);\r
2017 \r
2018  PSXDisplay.CumulOffset.x =                            // new OGL prim offsets\r
2019   PSXDisplay.DrawOffset.x - PSXDisplay.GDrawOffset.x + PreviousPSXDisplay.Range.x0;\r
2020  PSXDisplay.CumulOffset.y = \r
2021   PSXDisplay.DrawOffset.y - PSXDisplay.GDrawOffset.y + PreviousPSXDisplay.Range.y0;\r
2022 }\r
2023 \r
2024 ////////////////////////////////////////////////////////////////////////\r
2025 // cmd: load image to vram\r
2026 ////////////////////////////////////////////////////////////////////////\r
2027 \r
2028 void primLoadImage(unsigned char * baseAddr)\r
2029 {\r
2030  unsigned short *sgpuData = ((unsigned short *) baseAddr);\r
2031 \r
2032  VRAMWrite.x      = sgpuData[2]&0x03ff;\r
2033  VRAMWrite.y      = sgpuData[3]&iGPUHeightMask;\r
2034  VRAMWrite.Width  = sgpuData[4];\r
2035  VRAMWrite.Height = sgpuData[5];\r
2036 \r
2037  iDataWriteMode = DR_VRAMTRANSFER;\r
2038  VRAMWrite.ImagePtr = psxVuw + (VRAMWrite.y<<10) + VRAMWrite.x;\r
2039  VRAMWrite.RowsRemaining = VRAMWrite.Width;\r
2040  VRAMWrite.ColsRemaining = VRAMWrite.Height;\r
2041 \r
2042  bNeedWriteUpload=TRUE;\r
2043 }\r
2044 \r
2045 ////////////////////////////////////////////////////////////////////////\r
2046 \r
2047 void PrepareRGB24Upload(void)\r
2048 {\r
2049  VRAMWrite.x=(VRAMWrite.x*2)/3;\r
2050  VRAMWrite.Width=(VRAMWrite.Width*2)/3;\r
2051 \r
2052  if(!PSXDisplay.InterlacedTest && // NEW\r
2053     CheckAgainstScreen(VRAMWrite.x, VRAMWrite.y, VRAMWrite.Width, VRAMWrite.Height))\r
2054   {\r
2055    xrUploadArea.x0-=PreviousPSXDisplay.DisplayPosition.x;\r
2056    xrUploadArea.x1-=PreviousPSXDisplay.DisplayPosition.x;\r
2057    xrUploadArea.y0-=PreviousPSXDisplay.DisplayPosition.y;\r
2058    xrUploadArea.y1-=PreviousPSXDisplay.DisplayPosition.y;\r
2059   }  \r
2060  else\r
2061  if(CheckAgainstFrontScreen(VRAMWrite.x, VRAMWrite.y, VRAMWrite.Width, VRAMWrite.Height))\r
2062   {\r
2063    xrUploadArea.x0-=PSXDisplay.DisplayPosition.x;\r
2064    xrUploadArea.x1-=PSXDisplay.DisplayPosition.x;\r
2065    xrUploadArea.y0-=PSXDisplay.DisplayPosition.y;\r
2066    xrUploadArea.y1-=PSXDisplay.DisplayPosition.y;\r
2067   }  \r
2068  else return;\r
2069 \r
2070  if(bRenderFrontBuffer) \r
2071   {\r
2072    updateFrontDisplay();\r
2073   }\r
2074 \r
2075  if(bNeedRGB24Update==FALSE)\r
2076   {\r
2077    xrUploadAreaRGB24=xrUploadArea;\r
2078    bNeedRGB24Update=TRUE;\r
2079   }\r
2080  else\r
2081   {\r
2082    xrUploadAreaRGB24.x0=min(xrUploadAreaRGB24.x0,xrUploadArea.x0);\r
2083    xrUploadAreaRGB24.x1=max(xrUploadAreaRGB24.x1,xrUploadArea.x1);\r
2084    xrUploadAreaRGB24.y0=min(xrUploadAreaRGB24.y0,xrUploadArea.y0);\r
2085    xrUploadAreaRGB24.y1=max(xrUploadAreaRGB24.y1,xrUploadArea.y1);\r
2086   }\r
2087 }\r
2088 \r
2089 ////////////////////////////////////////////////////////////////////////\r
2090 \r
2091 void CheckWriteUpdate()\r
2092 {\r
2093  int iX=0,iY=0;\r
2094 \r
2095  if(VRAMWrite.Width)   iX=1;\r
2096  if(VRAMWrite.Height)  iY=1;\r
2097 \r
2098  InvalidateTextureArea(VRAMWrite.x, VRAMWrite.y, VRAMWrite.Width-iX, VRAMWrite.Height-iY);\r
2099 \r
2100  if(PSXDisplay.Interlaced && !iOffscreenDrawing) return;\r
2101 \r
2102  if(PSXDisplay.RGB24) {PrepareRGB24Upload();return;}\r
2103 \r
2104  if(!PSXDisplay.InterlacedTest &&\r
2105     CheckAgainstScreen(VRAMWrite.x, VRAMWrite.y, VRAMWrite.Width, VRAMWrite.Height)) \r
2106   {\r
2107    if(dwActFixes&0x800) return;\r
2108 \r
2109    if(bRenderFrontBuffer) \r
2110     {\r
2111      updateFrontDisplay();\r
2112     }\r
2113 \r
2114    UploadScreen(FALSE);\r
2115 \r
2116    bNeedUploadTest=TRUE;\r
2117   }\r
2118  else \r
2119  if(iOffscreenDrawing)\r
2120   {\r
2121    if (CheckAgainstFrontScreen(VRAMWrite.x, VRAMWrite.y, VRAMWrite.Width, VRAMWrite.Height)) \r
2122     {\r
2123      if(PSXDisplay.InterlacedTest)\r
2124       {\r
2125        if(PreviousPSXDisplay.InterlacedNew) \r
2126         {\r
2127          PreviousPSXDisplay.InterlacedNew=FALSE;\r
2128          bNeedInterlaceUpdate=TRUE;\r
2129          xrUploadAreaIL.x0=PSXDisplay.DisplayPosition.x;\r
2130          xrUploadAreaIL.y0=PSXDisplay.DisplayPosition.y;\r
2131          xrUploadAreaIL.x1=PSXDisplay.DisplayPosition.x+PSXDisplay.DisplayModeNew.x;\r
2132          xrUploadAreaIL.y1=PSXDisplay.DisplayPosition.y+PSXDisplay.DisplayModeNew.y;\r
2133          if(xrUploadAreaIL.x1>1023) xrUploadAreaIL.x1=1023;\r
2134          if(xrUploadAreaIL.y1>511)  xrUploadAreaIL.y1=511;\r
2135         }\r
2136 \r
2137        if(bNeedInterlaceUpdate==FALSE)\r
2138         {\r
2139          xrUploadAreaIL=xrUploadArea;\r
2140          bNeedInterlaceUpdate=TRUE;\r
2141         }\r
2142        else\r
2143         {\r
2144          xrUploadAreaIL.x0=min(xrUploadAreaIL.x0,xrUploadArea.x0);\r
2145          xrUploadAreaIL.x1=max(xrUploadAreaIL.x1,xrUploadArea.x1);\r
2146          xrUploadAreaIL.y0=min(xrUploadAreaIL.y0,xrUploadArea.y0);\r
2147          xrUploadAreaIL.y1=max(xrUploadAreaIL.y1,xrUploadArea.y1);\r
2148         }\r
2149        return;\r
2150       }\r
2151 \r
2152      if(!bNeedUploadAfter)\r
2153       {\r
2154        bNeedUploadAfter = TRUE;\r
2155        xrUploadArea.x0=VRAMWrite.x;\r
2156        xrUploadArea.x1=VRAMWrite.x+VRAMWrite.Width;\r
2157        xrUploadArea.y0=VRAMWrite.y;\r
2158        xrUploadArea.y1=VRAMWrite.y+VRAMWrite.Height;\r
2159       }\r
2160      else\r
2161       {\r
2162        xrUploadArea.x0=min(xrUploadArea.x0,VRAMWrite.x);\r
2163        xrUploadArea.x1=max(xrUploadArea.x1,VRAMWrite.x+VRAMWrite.Width);\r
2164        xrUploadArea.y0=min(xrUploadArea.y0,VRAMWrite.y);\r
2165        xrUploadArea.y1=max(xrUploadArea.y1,VRAMWrite.y+VRAMWrite.Height);\r
2166       }\r
2167 \r
2168      if(dwActFixes&0x8000)\r
2169       {\r
2170        if((xrUploadArea.x1-xrUploadArea.x0)>=(PSXDisplay.DisplayMode.x-32) &&\r
2171           (xrUploadArea.y1-xrUploadArea.y0)>=(PSXDisplay.DisplayMode.y-32))\r
2172         {\r
2173          UploadScreen(-1);\r
2174          updateFrontDisplay();\r
2175         }\r
2176       }\r
2177     }\r
2178   }\r
2179 }\r
2180 \r
2181 ////////////////////////////////////////////////////////////////////////\r
2182 // cmd: vram -> psx mem\r
2183 ////////////////////////////////////////////////////////////////////////\r
2184 \r
2185 void primStoreImage(unsigned char * baseAddr)\r
2186 {\r
2187  unsigned short *sgpuData = ((unsigned short *) baseAddr);\r
2188 \r
2189  VRAMRead.x      = sgpuData[2]&0x03ff;\r
2190  VRAMRead.y      = sgpuData[3]&iGPUHeightMask;\r
2191  VRAMRead.Width  = sgpuData[4];\r
2192  VRAMRead.Height = sgpuData[5];\r
2193 \r
2194  VRAMRead.ImagePtr = psxVuw + (VRAMRead.y<<10) + VRAMRead.x;\r
2195  VRAMRead.RowsRemaining = VRAMRead.Width;\r
2196  VRAMRead.ColsRemaining = VRAMRead.Height;\r
2197 \r
2198  iDataReadMode = DR_VRAMTRANSFER;\r
2199 \r
2200  STATUSREG |= GPUSTATUS_READYFORVRAM;\r
2201 }\r
2202 \r
2203 ////////////////////////////////////////////////////////////////////////\r
2204 // cmd: blkfill - NO primitive! Doesn't care about draw areas...\r
2205 ////////////////////////////////////////////////////////////////////////\r
2206 \r
2207 void primBlkFill(unsigned char * baseAddr)\r
2208 {\r
2209  unsigned long *gpuData = ((unsigned long *) baseAddr);\r
2210  short *sgpuData = ((short *) baseAddr);\r
2211 \r
2212  iDrawnSomething=1;\r
2213 \r
2214  sprtX = sgpuData[2];\r
2215  sprtY = sgpuData[3];\r
2216  sprtW = sgpuData[4] & 0x3ff;\r
2217  sprtH = sgpuData[5] & iGPUHeightMask;\r
2218 \r
2219  sprtW = (sprtW+15) & ~15;\r
2220 \r
2221  // Increase H & W if they are one short of full values, because they never can be full values\r
2222  if (sprtH == iGPUHeightMask)  sprtH=iGPUHeight;\r
2223  if (sprtW == 1023)            sprtW=1024; \r
2224         \r
2225  // x and y of start\r
2226  ly0 = ly1 = sprtY;\r
2227  ly2 = ly3 = (sprtY+sprtH);\r
2228  lx0 = lx3 = sprtX;\r
2229  lx1 = lx2 = (sprtX+sprtW);\r
2230 \r
2231  offsetBlk();\r
2232 \r
2233  if(ClipVertexListScreen())                           \r
2234   {\r
2235    PSXDisplay_t * pd;\r
2236    if(PSXDisplay.InterlacedTest) pd=&PSXDisplay;\r
2237    else                          pd=&PreviousPSXDisplay;\r
2238 \r
2239    if ((lx0 <= pd->DisplayPosition.x+16) &&\r
2240        (ly0 <= pd->DisplayPosition.y+16) &&\r
2241        (lx2 >= pd->DisplayEnd.x-16) &&\r
2242        (ly2 >= pd->DisplayEnd.y-16))\r
2243     {\r
2244      GLclampf g,b,r;\r
2245      g=((GLclampf)GREEN(gpuData[0]))/255.0f;\r
2246      b=((GLclampf)BLUE(gpuData[0]))/255.0f;\r
2247      r=((GLclampf)RED(gpuData[0]))/255.0f;\r
2248      \r
2249      glDisable(GL_SCISSOR_TEST); glError();\r
2250      glClearColor(r,g,b,1.0f); glError();\r
2251      glClear(uiBufferBits); glError();\r
2252      gl_z=0.0f;\r
2253 \r
2254      if(gpuData[0]!=0x02000000 &&\r
2255         (ly0>pd->DisplayPosition.y ||\r
2256          ly2<pd->DisplayEnd.y))\r
2257       {\r
2258        bDrawTextured     = FALSE;\r
2259        bDrawSmoothShaded = FALSE;\r
2260        SetRenderState((unsigned long)0x01000000);\r
2261        SetRenderMode((unsigned long)0x01000000, FALSE);\r
2262        vertex[0].c.lcol=0xff000000;\r
2263        SETCOL(vertex[0]); \r
2264        if(ly0>pd->DisplayPosition.y)\r
2265         {\r
2266          vertex[0].x=0;vertex[0].y=0;\r
2267          vertex[1].x=pd->DisplayEnd.x-pd->DisplayPosition.x;vertex[1].y=0;\r
2268          vertex[2].x=vertex[1].x;vertex[2].y=ly0-pd->DisplayPosition.y;\r
2269          vertex[3].x=0;vertex[3].y=vertex[2].y;\r
2270          PRIMdrawQuad(&vertex[0], &vertex[1], &vertex[2], &vertex[3]);\r
2271         }\r
2272        if(ly2<pd->DisplayEnd.y)\r
2273         {\r
2274          vertex[0].x=0;vertex[0].y=(pd->DisplayEnd.y-pd->DisplayPosition.y)-(pd->DisplayEnd.y-ly2);\r
2275          vertex[1].x=pd->DisplayEnd.x-pd->DisplayPosition.x;vertex[1].y=vertex[0].y;\r
2276          vertex[2].x=vertex[1].x;vertex[2].y=pd->DisplayEnd.y;\r
2277          vertex[3].x=0;vertex[3].y=vertex[2].y;\r
2278          PRIMdrawQuad(&vertex[0], &vertex[1], &vertex[2], &vertex[3]);\r
2279         }\r
2280       }\r
2281 \r
2282      glEnable(GL_SCISSOR_TEST); glError();\r
2283     }\r
2284    else\r
2285     {\r
2286      bDrawTextured     = FALSE;\r
2287      bDrawSmoothShaded = FALSE;\r
2288      SetRenderState((unsigned long)0x01000000);\r
2289      SetRenderMode((unsigned long)0x01000000, FALSE);\r
2290      vertex[0].c.lcol=gpuData[0]|0xff000000;\r
2291      SETCOL(vertex[0]); \r
2292      glDisable(GL_SCISSOR_TEST); glError();\r
2293      PRIMdrawQuad(&vertex[0], &vertex[1], &vertex[2], &vertex[3]);\r
2294      glEnable(GL_SCISSOR_TEST); glError();\r
2295     }\r
2296   }\r
2297 \r
2298  //mmm... will clean all stuff, also if not all _should_ be cleaned...\r
2299  //if (IsInsideNextScreen(sprtX, sprtY, sprtW, sprtH))\r
2300  // try this:\r
2301  if (IsCompleteInsideNextScreen(sprtX, sprtY, sprtW, sprtH))\r
2302   {\r
2303    lClearOnSwapColor = COLOR(gpuData[0]);\r
2304    lClearOnSwap = 1;\r
2305   }\r
2306 \r
2307 /* if(iOffscreenDrawing)\r
2308   {\r
2309    ClampToPSXScreenOffset( &sprtX, &sprtY, &sprtW, &sprtH);\r
2310    if ((sprtW == 0) || (sprtH == 0)) return;\r
2311    InvalidateTextureArea(sprtX, sprtY, sprtW-1, sprtH-1);   \r
2312 \r
2313    sprtW+=sprtX;\r
2314    sprtH+=sprtY;\r
2315 \r
2316    FillSoftwareArea(sprtX, sprtY, sprtW, sprtH, BGR24to16(gpuData[0]));\r
2317   }*/\r
2318 }\r
2319   \r
2320 ////////////////////////////////////////////////////////////////////////\r
2321 // cmd: move image vram -> vram\r
2322 ////////////////////////////////////////////////////////////////////////\r
2323 \r
2324 void MoveImageWrapped(short imageX0,short imageY0,\r
2325                       short imageX1,short imageY1,\r
2326                       short imageSX,short imageSY)\r
2327 {\r
2328  int i,j,imageXE,imageYE;\r
2329 \r
2330  if(iFrameReadType&2)\r
2331   {\r
2332    imageXE=imageX0+imageSX;\r
2333    imageYE=imageY0+imageSY;\r
2334 \r
2335    if(imageYE>iGPUHeight && imageXE>1024) \r
2336     {\r
2337      CheckVRamRead(0,0,\r
2338                    (imageXE&0x3ff),\r
2339                    (imageY0&iGPUHeightMask),\r
2340                    FALSE);\r
2341     }\r
2342 \r
2343    if(imageXE>1024) \r
2344     {\r
2345      CheckVRamRead(0,imageY0, \r
2346                    (imageXE&0x3ff),\r
2347                    (imageYE>iGPUHeight)?iGPUHeight:imageYE,\r
2348                    FALSE);\r
2349     }\r
2350 \r
2351    if(imageYE>iGPUHeight) \r
2352     {\r
2353      CheckVRamRead(imageX0,0, \r
2354                    (imageXE>1024)?1024:imageXE,\r
2355                    imageYE&iGPUHeightMask,\r
2356                    FALSE);\r
2357     }\r
2358 \r
2359    CheckVRamRead(imageX0,imageY0, \r
2360                  (imageXE>1024)?1024:imageXE,\r
2361                  (imageYE>iGPUHeight)?iGPUHeight:imageYE,\r
2362                  FALSE);\r
2363   }\r
2364 \r
2365  for(j=0;j<imageSY;j++)\r
2366   for(i=0;i<imageSX;i++)\r
2367    psxVuw [(1024*((imageY1+j)&iGPUHeightMask))+((imageX1+i)&0x3ff)]=\r
2368     psxVuw[(1024*((imageY0+j)&iGPUHeightMask))+((imageX0+i)&0x3ff)];\r
2369 \r
2370  if(!PSXDisplay.RGB24)\r
2371   {\r
2372    imageXE=imageX1+imageSX;\r
2373    imageYE=imageY1+imageSY;\r
2374 \r
2375    if(imageYE>iGPUHeight && imageXE>1024) \r
2376     {\r
2377      InvalidateTextureArea(0,0,\r
2378                            (imageXE&0x3ff)-1,\r
2379                            (imageYE&iGPUHeightMask)-1);\r
2380     }\r
2381 \r
2382    if(imageXE>1024) \r
2383     {\r
2384      InvalidateTextureArea(0,imageY1,\r
2385                            (imageXE&0x3ff)-1,\r
2386                            ((imageYE>iGPUHeight)?iGPUHeight:imageYE)-imageY1-1);\r
2387     }\r
2388 \r
2389    if(imageYE>iGPUHeight) \r
2390     {\r
2391      InvalidateTextureArea(imageX1,0,\r
2392                            ((imageXE>1024)?1024:imageXE)-imageX1-1,\r
2393                            (imageYE&iGPUHeightMask)-1);\r
2394     }\r
2395 \r
2396    InvalidateTextureArea(imageX1,imageY1,\r
2397                          ((imageXE>1024)?1024:imageXE)-imageX1-1,\r
2398                          ((imageYE>iGPUHeight)?iGPUHeight:imageYE)-imageY1-1);\r
2399   }\r
2400 }\r
2401 \r
2402 ////////////////////////////////////////////////////////////////////////\r
2403 \r
2404 void primMoveImage(unsigned char * baseAddr)\r
2405 {\r
2406  short *sgpuData = ((short *) baseAddr);\r
2407  short imageY0,imageX0,imageY1,imageX1,imageSX,imageSY,i,j;\r
2408 \r
2409  imageX0 = sgpuData[2]&0x03ff;\r
2410  imageY0 = sgpuData[3]&iGPUHeightMask;\r
2411  imageX1 = sgpuData[4]&0x03ff;\r
2412  imageY1 = sgpuData[5]&iGPUHeightMask;\r
2413  imageSX = sgpuData[6];\r
2414  imageSY = sgpuData[7];\r
2415 \r
2416  if((imageX0 == imageX1) && (imageY0 == imageY1)) return;  \r
2417  if(imageSX<=0) return;\r
2418  if(imageSY<=0) return;\r
2419 \r
2420  if(iGPUHeight==1024 && sgpuData[7]>1024) return;\r
2421 \r
2422  if((imageY0+imageSY)>iGPUHeight ||\r
2423     (imageX0+imageSX)>1024       ||\r
2424     (imageY1+imageSY)>iGPUHeight ||\r
2425     (imageX1+imageSX)>1024)\r
2426   {\r
2427    MoveImageWrapped(imageX0,imageY0,imageX1,imageY1,imageSX,imageSY);\r
2428    if((imageY0+imageSY)>iGPUHeight) imageSY=iGPUHeight-imageY0;\r
2429    if((imageX0+imageSX)>1024)       imageSX=1024-imageX0;\r
2430    if((imageY1+imageSY)>iGPUHeight) imageSY=iGPUHeight-imageY1;\r
2431    if((imageX1+imageSX)>1024)       imageSX=1024-imageX1;\r
2432   }\r
2433 \r
2434  if(iFrameReadType&2)\r
2435   CheckVRamRead(imageX0,imageY0, \r
2436                 imageX0+imageSX,\r
2437                 imageY0+imageSY,\r
2438                 FALSE);\r
2439 \r
2440  if(imageSX&1)\r
2441   {\r
2442    unsigned short *SRCPtr, *DSTPtr;\r
2443    unsigned short LineOffset;\r
2444 \r
2445    SRCPtr = psxVuw + (1024*imageY0) + imageX0;\r
2446    DSTPtr = psxVuw + (1024*imageY1) + imageX1;\r
2447 \r
2448    LineOffset = 1024 - imageSX;\r
2449 \r
2450    for(j=0;j<imageSY;j++)\r
2451     {\r
2452      for(i=0;i<imageSX;i++) *DSTPtr++ = *SRCPtr++;\r
2453      SRCPtr += LineOffset;\r
2454      DSTPtr += LineOffset;\r
2455     }\r
2456   }\r
2457  else\r
2458   {\r
2459    unsigned long *SRCPtr, *DSTPtr;\r
2460    unsigned short LineOffset;\r
2461    int dx=imageSX>>1;\r
2462 \r
2463    SRCPtr = (unsigned long *)(psxVuw + (1024*imageY0) + imageX0);\r
2464    DSTPtr = (unsigned long *)(psxVuw + (1024*imageY1) + imageX1);\r
2465 \r
2466    LineOffset = 512 - dx;\r
2467 \r
2468    for(j=0;j<imageSY;j++)\r
2469     {\r
2470      for(i=0;i<dx;i++) *DSTPtr++ = *SRCPtr++;\r
2471      SRCPtr += LineOffset;\r
2472      DSTPtr += LineOffset;\r
2473     }\r
2474   }\r
2475 \r
2476  if (!PSXDisplay.RGB24)\r
2477   {\r
2478    InvalidateTextureArea(imageX1,imageY1,imageSX-1,imageSY-1);\r
2479 \r
2480    if (CheckAgainstScreen(imageX1,imageY1,imageSX,imageSY)) \r
2481     {\r
2482      if(imageX1>=PreviousPSXDisplay.DisplayPosition.x &&\r
2483         imageX1<PreviousPSXDisplay.DisplayEnd.x &&\r
2484         imageY1>=PreviousPSXDisplay.DisplayPosition.y &&\r
2485         imageY1<PreviousPSXDisplay.DisplayEnd.y)\r
2486       {\r
2487        imageX1 += imageSX;\r
2488        imageY1 += imageSY;\r
2489 \r
2490        if(imageX1>=PreviousPSXDisplay.DisplayPosition.x &&\r
2491           imageX1<=PreviousPSXDisplay.DisplayEnd.x &&\r
2492           imageY1>=PreviousPSXDisplay.DisplayPosition.y &&\r
2493           imageY1<=PreviousPSXDisplay.DisplayEnd.y)\r
2494         {\r
2495          if(!(\r
2496                imageX0>=PSXDisplay.DisplayPosition.x &&\r
2497                imageX0<PSXDisplay.DisplayEnd.x &&\r
2498                imageY0>=PSXDisplay.DisplayPosition.y &&\r
2499                imageY0<PSXDisplay.DisplayEnd.y \r
2500               ))\r
2501           {\r
2502            if(bRenderFrontBuffer) \r
2503             {\r
2504              updateFrontDisplay();\r
2505             }\r
2506  \r
2507            UploadScreen(FALSE);\r
2508           }\r
2509          else bFakeFrontBuffer=TRUE;\r
2510         }\r
2511       }\r
2512 \r
2513      bNeedUploadTest=TRUE;\r
2514     }\r
2515    else\r
2516    if(iOffscreenDrawing)\r
2517     {\r
2518      if (CheckAgainstFrontScreen(imageX1,imageY1,imageSX,imageSY)) \r
2519       {\r
2520        if(!PSXDisplay.InterlacedTest &&\r
2521 //          !bFullVRam &&\r
2522           ((\r
2523             imageX0>=PreviousPSXDisplay.DisplayPosition.x &&\r
2524             imageX0<PreviousPSXDisplay.DisplayEnd.x &&\r
2525             imageY0>=PreviousPSXDisplay.DisplayPosition.y &&\r
2526             imageY0<PreviousPSXDisplay.DisplayEnd.y\r
2527            ) ||\r
2528            (\r
2529             imageX0>=PSXDisplay.DisplayPosition.x &&\r
2530             imageX0<PSXDisplay.DisplayEnd.x &&\r
2531             imageY0>=PSXDisplay.DisplayPosition.y &&\r
2532             imageY0<PSXDisplay.DisplayEnd.y\r
2533            )))\r
2534         return;\r
2535 \r
2536        bNeedUploadTest=TRUE;\r
2537 \r
2538        if(!bNeedUploadAfter)\r
2539         {\r
2540          bNeedUploadAfter = TRUE;\r
2541          xrUploadArea.x0=imageX0;\r
2542          xrUploadArea.x1=imageX0+imageSX;\r
2543          xrUploadArea.y0=imageY0;\r
2544          xrUploadArea.y1=imageY0+imageSY;\r
2545         }\r
2546        else\r
2547         {\r
2548          xrUploadArea.x0=min(xrUploadArea.x0,imageX0);\r
2549          xrUploadArea.x1=max(xrUploadArea.x1,imageX0+imageSX);\r
2550          xrUploadArea.y0=min(xrUploadArea.y0,imageY0);\r
2551          xrUploadArea.y1=max(xrUploadArea.y1,imageY0+imageSY);\r
2552         }\r
2553       }\r
2554     }\r
2555   }\r
2556 }\r
2557 \r
2558 \r
2559 ////////////////////////////////////////////////////////////////////////\r
2560 // cmd: draw free-size Tile \r
2561 ////////////////////////////////////////////////////////////////////////\r
2562 \r
2563 void primTileS(unsigned char * baseAddr)\r
2564 {\r
2565  unsigned long *gpuData = ((unsigned long*)baseAddr);\r
2566  short *sgpuData = ((short *) baseAddr);\r
2567 \r
2568  sprtX = sgpuData[2];\r
2569  sprtY = sgpuData[3];\r
2570  sprtW = sgpuData[4] & 0x3ff;\r
2571  sprtH = sgpuData[5] & iGPUHeightMask;\r
2572 \r
2573  // x and y of start\r
2574 \r
2575  lx0 = sprtX;\r
2576  ly0 = sprtY;\r
2577 \r
2578  offsetST();\r
2579 \r
2580  if((dwActFixes&1) &&                                  // FF7 special game gix (battle cursor)\r
2581     sprtX==0 && sprtY==0 && sprtW==24 && sprtH==16) \r
2582   return;\r
2583 \r
2584  bDrawTextured = FALSE;\r
2585  bDrawSmoothShaded = FALSE;\r
2586 \r
2587  SetRenderState(gpuData[0]);\r
2588 \r
2589 /* if(iOffscreenDrawing)\r
2590   {\r
2591    if(IsPrimCompleteInsideNextScreen(lx0,ly0,lx2,ly2) ||\r
2592       (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
2593     {\r
2594      lClearOnSwapColor = COLOR(gpuData[0]);\r
2595      lClearOnSwap = 1;\r
2596     }\r
2597 \r
2598    offsetPSX4();\r
2599    if(bDrawOffscreen4())\r
2600     {\r
2601      if(!(iTileCheat && sprtH==32 && gpuData[0]==0x60ffffff)) // special cheat for certain ZiNc games\r
2602       {\r
2603        InvalidateTextureAreaEx();   \r
2604        FillSoftwareAreaTrans(lx0,ly0,lx2,ly2,\r
2605                              BGR24to16(gpuData[0]));  \r
2606       }\r
2607     }\r
2608   }*/\r
2609 \r
2610  SetRenderMode(gpuData[0], FALSE);\r
2611  SetZMask4NT();\r
2612 \r
2613  if(bIgnoreNextTile) {bIgnoreNextTile=FALSE;return;}\r
2614 \r
2615  vertex[0].c.lcol=gpuData[0];\r
2616  vertex[0].c.col[3]=ubGloColAlpha;\r
2617  SETCOL(vertex[0]); \r
2618  \r
2619  PRIMdrawQuad(&vertex[0], &vertex[1], &vertex[2], &vertex[3]);\r
2620 \r
2621  iDrawnSomething=1;\r
2622 }\r
2623 \r
2624 ////////////////////////////////////////////////////////////////////////\r
2625 // cmd: draw 1 dot Tile (point)\r
2626 ////////////////////////////////////////////////////////////////////////\r
2627 \r
2628 void primTile1(unsigned char * baseAddr)\r
2629 {\r
2630  unsigned long *gpuData = ((unsigned long*)baseAddr);\r
2631  short *sgpuData = ((short *) baseAddr);\r
2632 \r
2633  sprtX = sgpuData[2];\r
2634  sprtY = sgpuData[3];\r
2635  sprtW = 1;\r
2636  sprtH = 1;\r
2637 \r
2638  lx0 = sprtX;\r
2639  ly0 = sprtY;\r
2640 \r
2641  offsetST();\r
2642 \r
2643  bDrawTextured = FALSE;\r
2644  bDrawSmoothShaded = FALSE;\r
2645 \r
2646  SetRenderState(gpuData[0]);\r
2647 \r
2648 /* if(iOffscreenDrawing)\r
2649   {\r
2650    offsetPSX4();\r
2651 \r
2652    if(bDrawOffscreen4())\r
2653     {\r
2654      InvalidateTextureAreaEx();   \r
2655      FillSoftwareAreaTrans(lx0,ly0,lx2,ly2,\r
2656                            BGR24to16(gpuData[0]));          \r
2657     }\r
2658   }\r
2659 */\r
2660  SetRenderMode(gpuData[0], FALSE);\r
2661  SetZMask4NT();\r
2662 \r
2663  vertex[0].c.lcol=gpuData[0];vertex[0].c.col[3]=ubGloColAlpha;\r
2664  SETCOL(vertex[0]); \r
2665 \r
2666  PRIMdrawQuad(&vertex[0], &vertex[1], &vertex[2], &vertex[3]);\r
2667 \r
2668  iDrawnSomething=1;\r
2669 }\r
2670 \r
2671 ////////////////////////////////////////////////////////////////////////\r
2672 // cmd: draw 8 dot Tile (small rect)\r
2673 ////////////////////////////////////////////////////////////////////////\r
2674 \r
2675 void primTile8(unsigned char * baseAddr)\r
2676 {\r
2677  unsigned long *gpuData = ((unsigned long*)baseAddr);\r
2678  short *sgpuData = ((short *) baseAddr);\r
2679 \r
2680  sprtX = sgpuData[2];\r
2681  sprtY = sgpuData[3];\r
2682  sprtW = 8;\r
2683  sprtH = 8;\r
2684 \r
2685  lx0 = sprtX;\r
2686  ly0 = sprtY;\r
2687 \r
2688  offsetST();\r
2689 \r
2690  bDrawTextured = FALSE;\r
2691  bDrawSmoothShaded = FALSE;\r
2692  SetRenderState(gpuData[0]);\r
2693 \r
2694 /* if(iOffscreenDrawing)\r
2695   {\r
2696    offsetPSX4();\r
2697 \r
2698    if(bDrawOffscreen4())\r
2699     {\r
2700      InvalidateTextureAreaEx();   \r
2701      FillSoftwareAreaTrans(lx0,ly0,lx2,ly2,\r
2702                            BGR24to16(gpuData[0]));    \r
2703     }\r
2704   }\r
2705 */\r
2706  SetRenderMode(gpuData[0], FALSE);\r
2707  SetZMask4NT();\r
2708 \r
2709  vertex[0].c.lcol=gpuData[0];\r
2710  vertex[0].c.col[3]=ubGloColAlpha;\r
2711  SETCOL(vertex[0]); \r
2712 \r
2713  PRIMdrawQuad(&vertex[0], &vertex[1], &vertex[2], &vertex[3]);\r
2714 \r
2715  iDrawnSomething=1;\r
2716 }\r
2717 \r
2718 ////////////////////////////////////////////////////////////////////////\r
2719 // cmd: draw 16 dot Tile (medium rect)\r
2720 ////////////////////////////////////////////////////////////////////////\r
2721 \r
2722 void primTile16(unsigned char * baseAddr)\r
2723 {\r
2724  unsigned long *gpuData = ((unsigned long*)baseAddr);\r
2725  short *sgpuData = ((short *) baseAddr);\r
2726 \r
2727  sprtX = sgpuData[2];\r
2728  sprtY = sgpuData[3];\r
2729  sprtW = 16;\r
2730  sprtH = 16;\r
2731  // x and y of start\r
2732  lx0 = sprtX;\r
2733  ly0 = sprtY;\r
2734 \r
2735  offsetST();\r
2736 \r
2737  bDrawTextured = FALSE;\r
2738  bDrawSmoothShaded = FALSE;\r
2739  SetRenderState(gpuData[0]);\r
2740 \r
2741 /* if(iOffscreenDrawing)\r
2742   {\r
2743    offsetPSX4();\r
2744 \r
2745    if(bDrawOffscreen4())\r
2746     {\r
2747      InvalidateTextureAreaEx();   \r
2748      FillSoftwareAreaTrans(lx0,ly0,lx2,ly2,\r
2749                            BGR24to16(gpuData[0]));    \r
2750     }\r
2751   }\r
2752 */\r
2753  SetRenderMode(gpuData[0], FALSE);\r
2754  SetZMask4NT();\r
2755 \r
2756  vertex[0].c.lcol=gpuData[0];\r
2757  vertex[0].c.col[3]=ubGloColAlpha;\r
2758  SETCOL(vertex[0]); \r
2759 \r
2760  PRIMdrawQuad(&vertex[0], &vertex[1], &vertex[2], &vertex[3]);\r
2761 \r
2762  iDrawnSomething=1;\r
2763 }\r
2764 \r
2765 ////////////////////////////////////////////////////////////////////////\r
2766 // helper: filter effect by multipass rendering\r
2767 ////////////////////////////////////////////////////////////////////////\r
2768 \r
2769 /*void DrawMultiBlur(void)\r
2770 {\r
2771  long lABR,lDST;float fx,fy;\r
2772 \r
2773  lABR=GlobalTextABR;\r
2774  lDST=DrawSemiTrans;\r
2775 \r
2776  fx=(float)PSXDisplay.DisplayMode.x/(float)(iResX); \r
2777  fy=(float)PSXDisplay.DisplayMode.y/(float)(iResY);\r
2778 \r
2779  vertex[0].x+=fx;vertex[1].x+=fx;\r
2780  vertex[2].x+=fx;vertex[3].x+=fx;\r
2781 \r
2782  GlobalTextABR=0;\r
2783  DrawSemiTrans=1;\r
2784  SetSemiTrans();\r
2785 \r
2786  PRIMdrawTexturedQuad(&vertex[0], &vertex[1], &vertex[2], &vertex[3]);\r
2787 \r
2788  vertex[0].y+=fy;vertex[1].y+=fy;\r
2789  vertex[2].y+=fy;vertex[3].y+=fy;\r
2790  PRIMdrawTexturedQuad(&vertex[0], &vertex[1], &vertex[2], &vertex[3]);\r
2791 \r
2792  if(bDrawMultiPass) {obm1=obm2=GL_SRC_ALPHA;}\r
2793 \r
2794  GlobalTextABR=lABR;\r
2795  DrawSemiTrans=lDST;\r
2796 }\r
2797 */\r
2798 ////////////////////////////////////////////////////////////////////////\r
2799 \r
2800 #define   POFF 0.375f\r
2801 \r
2802 void DrawMultiFilterSprite(void)\r
2803 {\r
2804  long lABR,lDST;\r
2805 \r
2806  if(bUseMultiPass || DrawSemiTrans || ubOpaqueDraw) \r
2807   {\r
2808    PRIMdrawTexturedQuad(&vertex[0], &vertex[1], &vertex[2], &vertex[3]);\r
2809    return;\r
2810   }\r
2811 \r
2812  lABR=GlobalTextABR;\r
2813  lDST=DrawSemiTrans;\r
2814  vertex[0].c.col[3]=ubGloAlpha/2;                      // -> set color with\r
2815  SETCOL(vertex[0]);                                    //    texture alpha\r
2816  PRIMdrawTexturedQuad(&vertex[0], &vertex[1], &vertex[2], &vertex[3]);\r
2817  vertex[0].x+=POFF;vertex[1].x+=POFF;\r
2818  vertex[2].x+=POFF;vertex[3].x+=POFF;\r
2819  vertex[0].y+=POFF;vertex[1].y+=POFF;\r
2820  vertex[2].y+=POFF;vertex[3].y+=POFF;\r
2821  GlobalTextABR=0;\r
2822  DrawSemiTrans=1;\r
2823  SetSemiTrans();\r
2824  PRIMdrawTexturedQuad(&vertex[0], &vertex[1], &vertex[2], &vertex[3]);\r
2825  GlobalTextABR=lABR;\r
2826  DrawSemiTrans=lDST;\r
2827 }\r
2828 \r
2829 ////////////////////////////////////////////////////////////////////////\r
2830 // cmd: small sprite (textured rect)\r
2831 ////////////////////////////////////////////////////////////////////////\r
2832 \r
2833 void primSprt8(unsigned char * baseAddr)\r
2834 {\r
2835  unsigned long *gpuData = ((unsigned long *) baseAddr);\r
2836  short *sgpuData = ((short *) baseAddr);\r
2837  short s;\r
2838 \r
2839  iSpriteTex=1;\r
2840 \r
2841  sprtX = sgpuData[2];\r
2842  sprtY = sgpuData[3];\r
2843  sprtW = 8;\r
2844  sprtH = 8;\r
2845 \r
2846  lx0 = sprtX;\r
2847  ly0 = sprtY;\r
2848 \r
2849  offsetST();\r
2850 \r
2851  // do texture stuff\r
2852  gl_ux[0]=gl_ux[3]=baseAddr[8];//gpuData[2]&0xff;\r
2853 \r
2854  if(usMirror & 0x1000) \r
2855   {\r
2856    s=gl_ux[0];\r
2857    s-=sprtW-1;\r
2858    if(s<0) {s=0;}\r
2859    gl_ux[0]=gl_ux[3]=s;\r
2860   }\r
2861 \r
2862  sSprite_ux2=s=gl_ux[0]+sprtW; \r
2863  if(s)     s--;\r
2864  if(s>255) s=255;\r
2865  gl_ux[1]=gl_ux[2]=s;\r
2866  // Y coords\r
2867  gl_vy[0]=gl_vy[1]=baseAddr[9];//(gpuData[2]>>8)&0xff;\r
2868 \r
2869  if(usMirror & 0x2000) \r
2870   {\r
2871    s=gl_vy[0];\r
2872    s-=sprtH-1;\r
2873    if(s<0) {s=0;}\r
2874    gl_vy[0]=gl_vy[1]=s;\r
2875   }\r
2876 \r
2877  sSprite_vy2=s=gl_vy[0]+sprtH; \r
2878  if(s)     s--;\r
2879  if(s>255) s=255;\r
2880  gl_vy[2]=gl_vy[3]=s;\r
2881 \r
2882  ulClutID=(gpuData[2]>>16);\r
2883 \r
2884  bDrawTextured = TRUE;\r
2885  bDrawSmoothShaded = FALSE;\r
2886  SetRenderState(gpuData[0]);\r
2887 \r
2888 /* if(iOffscreenDrawing)      \r
2889   {\r
2890    offsetPSX4();\r
2891 \r
2892    if(bDrawOffscreen4())\r
2893     {\r
2894      InvalidateTextureAreaEx();   \r
2895      SetRenderColor(gpuData[0]);\r
2896      lx0-=PSXDisplay.DrawOffset.x;\r
2897      ly0-=PSXDisplay.DrawOffset.y;\r
2898 \r
2899      if(bUsingTWin) DrawSoftwareSpriteTWin(baseAddr,8,8);\r
2900      else\r
2901      if(usMirror)   DrawSoftwareSpriteMirror(baseAddr,8,8);\r
2902      else\r
2903      DrawSoftwareSprite(baseAddr,8,8,baseAddr[8],baseAddr[9]);\r
2904     }\r
2905   }\r
2906 */\r
2907  SetRenderMode(gpuData[0], TRUE);\r
2908  SetZMask4SP();\r
2909 \r
2910  sSprite_ux2=gl_ux[0]+sprtW;\r
2911  sSprite_vy2=gl_vy[0]+sprtH;\r
2912 \r
2913  assignTextureSprite();\r
2914 \r
2915  if(iFilterType>4) \r
2916   DrawMultiFilterSprite();\r
2917  else\r
2918   PRIMdrawTexturedQuad(&vertex[0], &vertex[1], &vertex[2], &vertex[3]);\r
2919 \r
2920  if(bDrawMultiPass)\r
2921   {\r
2922    SetSemiTransMulti(1);\r
2923    PRIMdrawTexturedQuad(&vertex[0], &vertex[1], &vertex[2], &vertex[3]);\r
2924   }\r
2925 \r
2926  if(ubOpaqueDraw)\r
2927   {\r
2928    SetZMask4O();\r
2929    if(bUseMultiPass) SetOpaqueColor(gpuData[0]);\r
2930    DEFOPAQUEON\r
2931 \r
2932 /*   if(bSmallAlpha && iFilterType<=2)\r
2933     {\r
2934      glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);\r
2935      glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);\r
2936      PRIMdrawTexturedQuad(&vertex[0], &vertex[1], &vertex[2], &vertex[3]);\r
2937      glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);\r
2938      glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);\r
2939      SetZMask4O();\r
2940     }\r
2941 */\r
2942    PRIMdrawTexturedQuad(&vertex[0], &vertex[1], &vertex[2], &vertex[3]);\r
2943    DEFOPAQUEOFF\r
2944   }\r
2945 \r
2946  iSpriteTex=0;\r
2947  iDrawnSomething=1;\r
2948 }\r
2949 \r
2950 ////////////////////////////////////////////////////////////////////////\r
2951 // cmd: medium sprite (textured rect)\r
2952 ////////////////////////////////////////////////////////////////////////\r
2953 \r
2954 void primSprt16(unsigned char * baseAddr)\r
2955 {\r
2956  unsigned long *gpuData = ((unsigned long *) baseAddr);\r
2957  short *sgpuData = ((short *) baseAddr);\r
2958  short s;\r
2959 \r
2960  iSpriteTex=1;\r
2961 \r
2962  sprtX = sgpuData[2];\r
2963  sprtY = sgpuData[3];\r
2964  sprtW = 16;\r
2965  sprtH = 16;\r
2966 \r
2967  lx0 = sprtX;\r
2968  ly0 = sprtY;\r
2969 \r
2970  offsetST();\r
2971 \r
2972  // do texture stuff\r
2973  gl_ux[0]=gl_ux[3]=baseAddr[8];//gpuData[2]&0xff;\r
2974 \r
2975  if(usMirror & 0x1000) \r
2976   {\r
2977    s=gl_ux[0];\r
2978    s-=sprtW-1;\r
2979    if(s<0) {s=0;}\r
2980    gl_ux[0]=gl_ux[3]=s;\r
2981   }\r
2982 \r
2983  sSprite_ux2=s=gl_ux[0]+sprtW; \r
2984  if(s)     s--;\r
2985  if(s>255) s=255;\r
2986  gl_ux[1]=gl_ux[2]=s; \r
2987  // Y coords\r
2988  gl_vy[0]=gl_vy[1]=baseAddr[9];//(gpuData[2]>>8)&0xff;\r
2989 \r
2990  if(usMirror & 0x2000) \r
2991   {\r
2992    s=gl_vy[0];\r
2993    s-=sprtH-1;\r
2994    if(s<0) {s=0;}\r
2995    gl_vy[0]=gl_vy[1]=s;\r
2996   }\r
2997 \r
2998  sSprite_vy2=s=gl_vy[0]+sprtH; \r
2999  if(s)     s--;\r
3000  if(s>255) s=255;\r
3001  gl_vy[2]=gl_vy[3]=s;\r
3002 \r
3003  ulClutID=(gpuData[2]>>16);\r
3004 \r
3005  bDrawTextured = TRUE;\r
3006  bDrawSmoothShaded = FALSE;\r
3007  SetRenderState(gpuData[0]);\r
3008 \r
3009 /* if(iOffscreenDrawing)  \r
3010   {\r
3011    offsetPSX4();\r
3012 \r
3013    if(bDrawOffscreen4())\r
3014     {\r
3015      InvalidateTextureAreaEx();   \r
3016      SetRenderColor(gpuData[0]);\r
3017      lx0-=PSXDisplay.DrawOffset.x;\r
3018      ly0-=PSXDisplay.DrawOffset.y;\r
3019      if(bUsingTWin) DrawSoftwareSpriteTWin(baseAddr,16,16);\r
3020      else\r
3021      if(usMirror)   DrawSoftwareSpriteMirror(baseAddr,16,16);\r
3022      else\r
3023      DrawSoftwareSprite(baseAddr,16,16,baseAddr[8],baseAddr[9]);\r
3024     }\r
3025   }\r
3026 */\r
3027  SetRenderMode(gpuData[0], TRUE);\r
3028  SetZMask4SP();\r
3029 \r
3030  sSprite_ux2=gl_ux[0]+sprtW;\r
3031  sSprite_vy2=gl_vy[0]+sprtH;\r
3032 \r
3033  assignTextureSprite();\r
3034 \r
3035  if(iFilterType>4) \r
3036   DrawMultiFilterSprite();\r
3037  else\r
3038   PRIMdrawTexturedQuad(&vertex[0], &vertex[1], &vertex[2], &vertex[3]);\r
3039 \r
3040  if(bDrawMultiPass)\r
3041   {\r
3042    SetSemiTransMulti(1);\r
3043    PRIMdrawTexturedQuad(&vertex[0], &vertex[1], &vertex[2], &vertex[3]);\r
3044   }\r
3045 \r
3046  if(ubOpaqueDraw)\r
3047   {\r
3048    SetZMask4O();\r
3049    if(bUseMultiPass) SetOpaqueColor(gpuData[0]);\r
3050    DEFOPAQUEON\r
3051 \r
3052 /*   if(bSmallAlpha && iFilterType<=2)\r
3053     {\r
3054      glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);\r
3055      glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);\r
3056      PRIMdrawTexturedQuad(&vertex[0], &vertex[1], &vertex[2], &vertex[3]);\r
3057      glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);\r
3058      glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);\r
3059      SetZMask4O();\r
3060     }\r
3061 */\r
3062    PRIMdrawTexturedQuad(&vertex[0], &vertex[1], &vertex[2], &vertex[3]);\r
3063    DEFOPAQUEOFF\r
3064   }\r
3065 \r
3066  iSpriteTex=0;\r
3067  iDrawnSomething=1;\r
3068 }\r
3069 \r
3070 ////////////////////////////////////////////////////////////////////////\r
3071 // cmd: free-size sprite (textured rect)\r
3072 ////////////////////////////////////////////////////////////////////////\r
3073  \r
3074 void primSprtSRest(unsigned char * baseAddr,unsigned short type)\r
3075 {\r
3076  unsigned long *gpuData = ((unsigned long *) baseAddr);\r
3077  short *sgpuData = ((short *) baseAddr);\r
3078  short s;unsigned short sTypeRest=0;\r
3079 \r
3080  sprtX = sgpuData[2];\r
3081  sprtY = sgpuData[3];\r
3082  sprtW = sgpuData[6] & 0x3ff;\r
3083  sprtH = sgpuData[7] & 0x1ff;\r
3084 \r
3085 \r
3086  // do texture stuff\r
3087  switch(type)\r
3088   {\r
3089    case 1:\r
3090     gl_vy[0]=gl_vy[1]=baseAddr[9];\r
3091     s=256-baseAddr[8];\r
3092     sprtW-=s;\r
3093     sprtX+=s;\r
3094     gl_ux[0]=gl_ux[3]=0;\r
3095     break;\r
3096    case 2:\r
3097     gl_ux[0]=gl_ux[3]=baseAddr[8];\r
3098     s=256-baseAddr[9];\r
3099     sprtH-=s;\r
3100     sprtY+=s;\r
3101     gl_vy[0]=gl_vy[1]=0;\r
3102     break;\r
3103    case 3:\r
3104     s=256-baseAddr[8];\r
3105     sprtW-=s;\r
3106     sprtX+=s;\r
3107     gl_ux[0]=gl_ux[3]=0;\r
3108     s=256-baseAddr[9];\r
3109     sprtH-=s;\r
3110     sprtY+=s;\r
3111     gl_vy[0]=gl_vy[1]=0;\r
3112     break;\r
3113 \r
3114    case 4:\r
3115     gl_vy[0]=gl_vy[1]=baseAddr[9];\r
3116     s=512-baseAddr[8];\r
3117     sprtW-=s;\r
3118     sprtX+=s;\r
3119     gl_ux[0]=gl_ux[3]=0;\r
3120     break;\r
3121    case 5:\r
3122     gl_ux[0]=gl_ux[3]=baseAddr[8];\r
3123     s=512-baseAddr[9];\r
3124     sprtH-=s;\r
3125     sprtY+=s;\r
3126     gl_vy[0]=gl_vy[1]=0;\r
3127     break;\r
3128    case 6:\r
3129     s=512-baseAddr[8];\r
3130     sprtW-=s;\r
3131     sprtX+=s;\r
3132     gl_ux[0]=gl_ux[3]=0;\r
3133     s=512-baseAddr[9];\r
3134     sprtH-=s;\r
3135     sprtY+=s;\r
3136     gl_vy[0]=gl_vy[1]=0;\r
3137     break;\r
3138 \r
3139   }\r
3140 \r
3141  if(usMirror & 0x1000) \r
3142   {\r
3143    s=gl_ux[0];\r
3144    s-=sprtW-1;if(s<0) s=0;\r
3145    gl_ux[0]=gl_ux[3]=s;\r
3146   }\r
3147  if(usMirror & 0x2000) \r
3148   {\r
3149    s=gl_vy[0];\r
3150    s-=sprtH-1;if(s<0) {s=0;}\r
3151    gl_vy[0]=gl_vy[1]=s;\r
3152   }\r
3153 \r
3154  sSprite_ux2=s=gl_ux[0]+sprtW; \r
3155  if(s>255) s=255;\r
3156  gl_ux[1]=gl_ux[2]=s;\r
3157  sSprite_vy2=s=gl_vy[0]+sprtH; \r
3158  if(s>255) s=255;\r
3159  gl_vy[2]=gl_vy[3]=s;\r
3160 \r
3161  if(!bUsingTWin)\r
3162   {\r
3163    if(sSprite_ux2>256) \r
3164     {sprtW=256-gl_ux[0];sSprite_ux2=256;sTypeRest+=1;}\r
3165    if(sSprite_vy2>256) \r
3166     {sprtH=256-gl_vy[0];sSprite_vy2=256;sTypeRest+=2;}\r
3167   }\r
3168  \r
3169  lx0 = sprtX;\r
3170  ly0 = sprtY;\r
3171 \r
3172  offsetST();\r
3173 \r
3174  ulClutID=(gpuData[2]>>16);\r
3175 \r
3176  bDrawTextured = TRUE;\r
3177  bDrawSmoothShaded = FALSE;\r
3178  SetRenderState(gpuData[0]);\r
3179 \r
3180 /* if(iOffscreenDrawing)\r
3181   {\r
3182    offsetPSX4();\r
3183 \r
3184    if(bDrawOffscreen4())\r
3185     {\r
3186      InvalidateTextureAreaEx();   \r
3187      SetRenderColor(gpuData[0]);\r
3188      lx0-=PSXDisplay.DrawOffset.x;\r
3189      ly0-=PSXDisplay.DrawOffset.y;\r
3190      if(bUsingTWin) DrawSoftwareSpriteTWin(baseAddr,sprtW,sprtH);\r
3191      else\r
3192      if(usMirror)   DrawSoftwareSpriteMirror(baseAddr,sprtW,sprtH);\r
3193      else\r
3194      DrawSoftwareSprite(baseAddr,sprtW,sprtH,baseAddr[8],baseAddr[9]);\r
3195     }\r
3196   }\r
3197 */\r
3198  SetRenderMode(gpuData[0], TRUE);\r
3199  SetZMask4SP();\r
3200 \r
3201  sSprite_ux2=gl_ux[0]+sprtW;\r
3202  sSprite_vy2=gl_vy[0]+sprtH;\r
3203 \r
3204  assignTextureSprite();\r
3205 \r
3206  if(iFilterType>4) \r
3207   DrawMultiFilterSprite();\r
3208  else\r
3209   PRIMdrawTexturedQuad(&vertex[0], &vertex[1], &vertex[2], &vertex[3]);\r
3210  \r
3211  if(bDrawMultiPass)\r
3212   {\r
3213    SetSemiTransMulti(1);\r
3214    PRIMdrawTexturedQuad(&vertex[0], &vertex[1], &vertex[2], &vertex[3]);\r
3215   }\r
3216 \r
3217  if(ubOpaqueDraw)\r
3218   {\r
3219    SetZMask4O();\r
3220    if(bUseMultiPass) SetOpaqueColor(gpuData[0]);\r
3221    DEFOPAQUEON\r
3222 \r
3223 /*   if(bSmallAlpha && iFilterType<=2)\r
3224     {\r
3225      glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);\r
3226      glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);\r
3227      PRIMdrawTexturedQuad(&vertex[0], &vertex[1], &vertex[2], &vertex[3]);\r
3228      glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);\r
3229      glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);\r
3230      SetZMask4O();\r
3231     }\r
3232 */\r
3233    PRIMdrawTexturedQuad(&vertex[0], &vertex[1], &vertex[2], &vertex[3]);\r
3234    DEFOPAQUEOFF\r
3235   }\r
3236 \r
3237  if(sTypeRest && type<4) \r
3238   {\r
3239    if(sTypeRest&1  && type==1) primSprtSRest(baseAddr,4);\r
3240    if(sTypeRest&2  && type==2) primSprtSRest(baseAddr,5);\r
3241    if(sTypeRest==3 && type==3) primSprtSRest(baseAddr,6);\r
3242   }\r
3243 }\r
3244 \r
3245 void primSprtS(unsigned char * baseAddr)\r
3246 {\r
3247  unsigned long *gpuData = ((unsigned long *) baseAddr);\r
3248  short *sgpuData = ((short *) baseAddr);\r
3249 \r
3250  short s;unsigned short sTypeRest=0;\r
3251 \r
3252  sprtX = sgpuData[2];\r
3253  sprtY = sgpuData[3];\r
3254  sprtW = sgpuData[6] & 0x3ff;\r
3255  sprtH = sgpuData[7] & 0x1ff;\r
3256 \r
3257  if(!sprtH) return;\r
3258  if(!sprtW) return;\r
3259 \r
3260  iSpriteTex=1;\r
3261 \r
3262  // do texture stuff\r
3263  gl_ux[0]=gl_ux[3]=baseAddr[8];//gpuData[2]&0xff;\r
3264  gl_vy[0]=gl_vy[1]=baseAddr[9];//(gpuData[2]>>8)&0xff;\r
3265 \r
3266  if(usMirror & 0x1000) \r
3267   {\r
3268    s=gl_ux[0];\r
3269    s-=sprtW-1;\r
3270    if(s<0) {s=0;}\r
3271    gl_ux[0]=gl_ux[3]=s;\r
3272   }\r
3273  if(usMirror & 0x2000) \r
3274   {\r
3275    s=gl_vy[0];\r
3276    s-=sprtH-1;\r
3277    if(s<0) {s=0;}\r
3278    gl_vy[0]=gl_vy[1]=s;\r
3279   }\r
3280 \r
3281  sSprite_ux2=s=gl_ux[0]+sprtW; \r
3282  if(s)     s--;\r
3283  if(s>255) s=255;\r
3284  gl_ux[1]=gl_ux[2]=s;\r
3285  sSprite_vy2=s=gl_vy[0]+sprtH; \r
3286  if(s)     s--;\r