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