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