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