minimal working gtk-less build
[pcsx_rearmed.git] / plugins / peopsxgl / prim.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 #include "stdafx.h"
20
21 #define _IN_PRIMDRAW
22
23 #include "externals.h"
24 #include "gpu.h"
25 #include "draw.h"
26 #include "soft.h"
27 #include "texture.h"
28
29 ////////////////////////////////////////////////////////////////////////                                          
30 // defines
31 ////////////////////////////////////////////////////////////////////////
32
33 #define DEFOPAQUEON  glAlphaFunc(GL_EQUAL,0.0f);bBlendEnable=FALSE;glDisable(GL_BLEND);                                
34 #define DEFOPAQUEOFF glAlphaFunc(GL_GREATER,0.49f);
35
36 ////////////////////////////////////////////////////////////////////////                                          
37 // globals
38 ////////////////////////////////////////////////////////////////////////
39
40 BOOL           bDrawTextured;                          // current active drawing states\r
41 BOOL           bDrawSmoothShaded;
42 BOOL           bOldSmoothShaded;
43 BOOL           bDrawNonShaded;
44 BOOL           bDrawMultiPass;
45 int            iOffscreenDrawing;
46 int            iDrawnSomething=0;
47 \r
48 BOOL           bRenderFrontBuffer=FALSE;               // flag for front buffer rendering\r
49
50 GLubyte        ubGloAlpha;                             // texture alpha\r
51 GLubyte        ubGloColAlpha;                          // color alpha\r
52 int            iFilterType;                            // type of filter\r
53 BOOL           bFullVRam=FALSE;                        // sign for tex win\r
54 BOOL           bDrawDither;                            // sign for dither\r
55 BOOL           bUseMultiPass;                          // sign for multi pass\r
56 GLuint         gTexName;                               // binded texture\r
57 BOOL           bTexEnabled;                            // texture enable flag\r
58 BOOL           bBlendEnable;                           // blend enable flag\r
59 PSXRect_t      xrUploadArea;                           // rect to upload\r
60 PSXRect_t      xrUploadAreaIL;                         // rect to upload\r
61 PSXRect_t      xrUploadAreaRGB24;                      // rect to upload rgb24\r
62 int            iSpriteTex=0;                           // flag for "hey, it's a sprite"\r
63 unsigned short usMirror;                               // mirror, mirror on the wall\r
64
65 BOOL           bNeedUploadAfter=FALSE;                 // sign for uploading in next frame\r
66 BOOL           bNeedUploadTest=FALSE;                  // sign for upload test\r
67 BOOL           bUsingTWin=FALSE;                       // tex win active flag\r
68 BOOL           bUsingMovie=FALSE;                      // movie active flag\r
69 PSXRect_t      xrMovieArea;                            // rect for movie upload\r
70 short          sSprite_ux2;                            // needed for sprire adjust\r
71 short          sSprite_vy2;                            // \r
72 uint32_t       ulOLDCOL=0;                             // active color\r
73 uint32_t       ulClutID;                               // clut\r
74
75 uint32_t      dwCfgFixes;                              // game fixes\r
76 uint32_t      dwActFixes=0;\r
77 uint32_t      dwEmuFixes=0;
78 BOOL          bUseFixes;\r
79
80 int           drawX,drawY,drawW,drawH;                 // offscreen drawing checkers\r
81 short         sxmin,sxmax,symin,symax;
82
83 ////////////////////////////////////////////////////////////////////////                                          
84 // Update global TP infos
85 ////////////////////////////////////////////////////////////////////////
86
87 void UpdateGlobalTP(unsigned short gdata)
88 {
89  GlobalTextAddrX = (gdata << 6) & 0x3c0;
90
91  if(iGPUHeight==1024)                                  // ZN mode\r
92   {\r
93    if(dwGPUVersion==2)                                 // very special zn gpu\r
94     {\r
95      GlobalTextAddrY =((gdata & 0x60 ) << 3);\r
96      GlobalTextIL    =(gdata & 0x2000) >> 13;\r
97      GlobalTextABR = (unsigned short)((gdata >> 7) & 0x3);\r
98      GlobalTextTP = (gdata >> 9) & 0x3;\r
99      if(GlobalTextTP==3) GlobalTextTP=2;             \r
100      GlobalTexturePage = (GlobalTextAddrX>>6)+(GlobalTextAddrY>>4);\r
101      usMirror =0;\r
102      STATUSREG = (STATUSREG & 0xffffe000 ) | (gdata & 0x1fff );\r
103      return;\r
104     }\r
105    else                                                // "enhanced" psx gpu\r
106     {\r
107      GlobalTextAddrY = (unsigned short)(((gdata << 4) & 0x100) | ((gdata >> 2) & 0x200));\r
108     }\r
109   }\r
110  else GlobalTextAddrY = (gdata << 4) & 0x100;          // "normal" psx gpu\r
111
112  usMirror=gdata&0x3000;
113  
114  GlobalTextTP = (gdata >> 7) & 0x3;                    // tex mode (4,8,15)
115  if(GlobalTextTP==3) GlobalTextTP=2;                   // seen in Wild9 :(
116  GlobalTextABR = (gdata >> 5) & 0x3;                   // blend mode
117
118  GlobalTexturePage = (GlobalTextAddrX>>6)+(GlobalTextAddrY>>4);
119
120  STATUSREG&=~0x07ff;                                   // Clear the necessary bits
121  STATUSREG|=(gdata & 0x07ff);                          // set the necessary bits
122 }
123
124 unsigned int DoubleBGR2RGB (unsigned int BGR)
125 {
126  unsigned int ebx,eax,edx;
127
128  ebx=(BGR&0x000000ff)<<1;
129  if(ebx&0x00000100) ebx=0x000000ff;
130
131  eax=(BGR&0x0000ff00)<<1;
132  if(eax&0x00010000) eax=0x0000ff00;
133
134  edx=(BGR&0x00ff0000)<<1;
135  if(edx&0x01000000) edx=0x00ff0000;
136
137  return (ebx|eax|edx);
138 }
139
140 unsigned short BGR24to16 (uint32_t BGR)
141 {
142  return ((BGR>>3)&0x1f)|((BGR&0xf80000)>>9)|((BGR&0xf800)>>6);
143 }
144
145 ////////////////////////////////////////////////////////////////////////
146 // OpenGL primitive drawing commands
147 ////////////////////////////////////////////////////////////////////////
148
149 __inline void PRIMdrawTexturedQuad(OGLVertex* vertex1, OGLVertex* vertex2, 
150                                    OGLVertex* vertex3, OGLVertex* vertex4) 
151 {
152  glBegin(GL_TRIANGLE_STRIP);
153   glTexCoord2fv(&vertex1->sow);
154   glVertex3fv(&vertex1->x);
155   
156   glTexCoord2fv(&vertex2->sow);
157   glVertex3fv(&vertex2->x);
158   
159   glTexCoord2fv(&vertex4->sow);
160   glVertex3fv(&vertex4->x);
161   
162   glTexCoord2fv(&vertex3->sow);
163   glVertex3fv(&vertex3->x);
164  glEnd();
165 }
166
167 ///////////////////////////////////////////////////////// 
168
169 __inline void PRIMdrawTexturedTri(OGLVertex* vertex1, OGLVertex* vertex2, 
170                                   OGLVertex* vertex3) 
171 {
172  glBegin(GL_TRIANGLES);
173   glTexCoord2fv(&vertex1->sow);
174   glVertex3fv(&vertex1->x);
175
176   glTexCoord2fv(&vertex2->sow);
177   glVertex3fv(&vertex2->x);
178
179   glTexCoord2fv(&vertex3->sow);
180   glVertex3fv(&vertex3->x);
181  glEnd();
182 }
183
184 ///////////////////////////////////////////////////////// 
185
186 __inline void PRIMdrawTexGouraudTriColor(OGLVertex* vertex1, OGLVertex* vertex2, 
187                                          OGLVertex* vertex3) 
188 {
189  glBegin(GL_TRIANGLES);
190
191   SETPCOL(vertex1); 
192   glTexCoord2fv(&vertex1->sow);
193   glVertex3fv(&vertex1->x);
194
195   SETPCOL(vertex2); 
196   glTexCoord2fv(&vertex2->sow);
197   glVertex3fv(&vertex2->x);
198
199   SETPCOL(vertex3); 
200   glTexCoord2fv(&vertex3->sow);
201   glVertex3fv(&vertex3->x);
202  glEnd();
203 }
204
205 ///////////////////////////////////////////////////////// 
206
207 __inline void PRIMdrawTexGouraudTriColorQuad(OGLVertex* vertex1, OGLVertex* vertex2, 
208                                              OGLVertex* vertex3, OGLVertex* vertex4) 
209 {
210  glBegin(GL_TRIANGLE_STRIP);
211   SETPCOL(vertex1); 
212   glTexCoord2fv(&vertex1->sow);
213   glVertex3fv(&vertex1->x);
214
215   SETPCOL(vertex2); 
216   glTexCoord2fv(&vertex2->sow);
217   glVertex3fv(&vertex2->x);
218
219   SETPCOL(vertex4); 
220   glTexCoord2fv(&vertex4->sow);
221   glVertex3fv(&vertex4->x);
222
223   SETPCOL(vertex3); 
224   glTexCoord2fv(&vertex3->sow);
225   glVertex3fv(&vertex3->x);
226  glEnd();
227 }
228
229 ///////////////////////////////////////////////////////// 
230
231 __inline void PRIMdrawTri(OGLVertex* vertex1, OGLVertex* vertex2, OGLVertex* vertex3) 
232 {
233  glBegin(GL_TRIANGLES);
234   glVertex3fv(&vertex1->x);
235   glVertex3fv(&vertex2->x);
236   glVertex3fv(&vertex3->x);
237  glEnd();
238 }
239
240 ///////////////////////////////////////////////////////// 
241
242 __inline void PRIMdrawTri2(OGLVertex* vertex1, OGLVertex* vertex2, 
243                            OGLVertex* vertex3, OGLVertex* vertex4) 
244 {
245  glBegin(GL_TRIANGLE_STRIP);                           
246   glVertex3fv(&vertex1->x);
247   glVertex3fv(&vertex3->x);
248   glVertex3fv(&vertex2->x);
249   glVertex3fv(&vertex4->x);
250  glEnd();
251 }
252
253 ///////////////////////////////////////////////////////// 
254
255 __inline void PRIMdrawGouraudTriColor(OGLVertex* vertex1, OGLVertex* vertex2, 
256                                       OGLVertex* vertex3) 
257 {
258  glBegin(GL_TRIANGLES);                           
259   SETPCOL(vertex1); 
260   glVertex3fv(&vertex1->x);
261        
262   SETPCOL(vertex2); 
263   glVertex3fv(&vertex2->x);
264
265   SETPCOL(vertex3); 
266   glVertex3fv(&vertex3->x);
267  glEnd();
268 }
269
270 ///////////////////////////////////////////////////////// 
271
272 __inline void PRIMdrawGouraudTri2Color(OGLVertex* vertex1, OGLVertex* vertex2, 
273                                        OGLVertex* vertex3, OGLVertex* vertex4) 
274 {
275  glBegin(GL_TRIANGLE_STRIP);                           
276   SETPCOL(vertex1); 
277   glVertex3fv(&vertex1->x);
278        
279   SETPCOL(vertex3); 
280   glVertex3fv(&vertex3->x);
281
282   SETPCOL(vertex2); 
283   glVertex3fv(&vertex2->x);
284
285   SETPCOL(vertex4); 
286   glVertex3fv(&vertex4->x);
287  glEnd();
288 }
289
290 ///////////////////////////////////////////////////////// 
291
292 __inline void PRIMdrawFlatLine(OGLVertex* vertex1, OGLVertex* vertex2,OGLVertex* vertex3, OGLVertex* vertex4)
293 {
294  glBegin(GL_QUADS);
295
296   SETPCOL(vertex1); 
297
298   glVertex3fv(&vertex1->x);
299   glVertex3fv(&vertex2->x);
300   glVertex3fv(&vertex3->x);
301   glVertex3fv(&vertex4->x);
302  glEnd();
303 }
304
305 ///////////////////////////////////////////////////////// 
306      
307 __inline void PRIMdrawGouraudLine(OGLVertex* vertex1, OGLVertex* vertex2,OGLVertex* vertex3, OGLVertex* vertex4)
308 {
309  glBegin(GL_QUADS);
310
311   SETPCOL(vertex1); 
312   glVertex3fv(&vertex1->x);
313
314   SETPCOL(vertex2); 
315   glVertex3fv(&vertex2->x);
316
317   SETPCOL(vertex3); 
318   glVertex3fv(&vertex3->x);
319
320   SETPCOL(vertex4); 
321   glVertex3fv(&vertex4->x);
322  glEnd();
323 }
324
325 ///////////////////////////////////////////////////////// 
326              
327 __inline void PRIMdrawQuad(OGLVertex* vertex1, OGLVertex* vertex2, 
328                            OGLVertex* vertex3, OGLVertex* vertex4) 
329 {
330  glBegin(GL_QUADS);
331   glVertex3fv(&vertex1->x);
332   glVertex3fv(&vertex2->x);
333   glVertex3fv(&vertex3->x);
334   glVertex3fv(&vertex4->x);
335  glEnd();
336 }
337
338 ////////////////////////////////////////////////////////////////////////                                          
339 // Transparent blending settings
340 ////////////////////////////////////////////////////////////////////////
341
342 static GLenum obm1=GL_ZERO;
343 static GLenum obm2=GL_ZERO;
344
345 typedef struct SEMITRANSTAG
346 {
347  GLenum  srcFac;
348  GLenum  dstFac;
349  GLubyte alpha;
350 } SemiTransParams;
351
352 SemiTransParams TransSets[4]=
353 {
354  {GL_SRC_ALPHA,GL_SRC_ALPHA,          127},
355  {GL_ONE,      GL_ONE,                255},
356  {GL_ZERO,     GL_ONE_MINUS_SRC_COLOR,255},
357  {GL_ONE_MINUS_SRC_ALPHA,GL_ONE,      192}\r
358 }; 
359
360 ////////////////////////////////////////////////////////////////////////
361
362 void SetSemiTrans(void)
363 {
364 /*
365 * 0.5 x B + 0.5 x F
366 * 1.0 x B + 1.0 x F
367 * 1.0 x B - 1.0 x F
368 * 1.0 x B +0.25 x F
369 */
370
371  if(!DrawSemiTrans)                                    // no semi trans at all?
372   {
373    if(bBlendEnable)
374     {glDisable(GL_BLEND);bBlendEnable=FALSE;}          // -> don't wanna blend
375    ubGloAlpha=ubGloColAlpha=255;                       // -> full alpha\r
376    return;                                             // -> and bye
377   }
378
379  ubGloAlpha=ubGloColAlpha=TransSets[GlobalTextABR].alpha;
380
381  if(!bBlendEnable)
382   {glEnable(GL_BLEND);bBlendEnable=TRUE;}              // wanna blend
383
384  if(TransSets[GlobalTextABR].srcFac!=obm1 || 
385     TransSets[GlobalTextABR].dstFac!=obm2)
386   {
387    if(glBlendEquationEXTEx==NULL)
388     {
389      obm1=TransSets[GlobalTextABR].srcFac;
390      obm2=TransSets[GlobalTextABR].dstFac;
391      glBlendFunc(obm1,obm2);                           // set blend func\r
392     }
393    else
394    if(TransSets[GlobalTextABR].dstFac !=GL_ONE_MINUS_SRC_COLOR)
395     {
396      if(obm2==GL_ONE_MINUS_SRC_COLOR)
397       glBlendEquationEXTEx(FUNC_ADD_EXT);
398      obm1=TransSets[GlobalTextABR].srcFac;
399      obm2=TransSets[GlobalTextABR].dstFac;
400      glBlendFunc(obm1,obm2);                           // set blend func\r
401     }
402    else
403     {
404      glBlendEquationEXTEx(FUNC_REVERSESUBTRACT_EXT);
405      obm1=TransSets[GlobalTextABR].srcFac;
406      obm2=TransSets[GlobalTextABR].dstFac;
407      glBlendFunc(GL_ONE,GL_ONE);                       // set blend func\r
408     }
409   }
410 }
411
412 void SetScanTrans(void)                                // blending for scan lines\r
413 {
414  if(glBlendEquationEXTEx!=NULL)
415   {
416    if(obm2==GL_ONE_MINUS_SRC_COLOR)
417     glBlendEquationEXTEx(FUNC_ADD_EXT);
418   }
419
420  obm1=TransSets[0].srcFac;
421  obm2=TransSets[0].dstFac;
422  glBlendFunc(obm1,obm2);                               // set blend func\r
423 }
424
425 void SetScanTexTrans(void)                             // blending for scan mask texture\r
426 {
427  if(glBlendEquationEXTEx!=NULL)
428   {
429    if(obm2==GL_ONE_MINUS_SRC_COLOR)
430     glBlendEquationEXTEx(FUNC_ADD_EXT);
431   }
432
433  obm1=TransSets[2].srcFac;
434  obm2=TransSets[2].dstFac;
435  glBlendFunc(obm1,obm2);                               // set blend func\r
436 }
437
438 ////////////////////////////////////////////////////////////////////////                                          
439 // multi pass in old 'Advanced blending' mode... got it from Lewpy :)
440 ////////////////////////////////////////////////////////////////////////                                          
441
442 SemiTransParams MultiTexTransSets[4][2]=
443 {
444  {
445  {GL_ONE      ,GL_SRC_ALPHA,          127},
446  {GL_SRC_ALPHA,GL_ONE,                127}
447  },
448  {
449  {GL_ONE,      GL_SRC_ALPHA,          255},
450  {GL_SRC_ALPHA,GL_ONE,                255}
451  },
452  {
453  {GL_ZERO,     GL_ONE_MINUS_SRC_COLOR,255},
454  {GL_ZERO,     GL_ONE_MINUS_SRC_COLOR,255}
455  },
456  {
457  {GL_SRC_ALPHA,GL_ONE,                127},
458  {GL_ONE_MINUS_SRC_ALPHA,GL_ONE,      255}
459  }
460 }; 
461
462 ////////////////////////////////////////////////////////////////////////                                          
463
464 SemiTransParams MultiColTransSets[4]=
465 {
466  {GL_ONE_MINUS_SRC_ALPHA,GL_SRC_ALPHA,127},
467  {GL_ONE,      GL_ONE,                255},
468  {GL_ZERO,     GL_ONE_MINUS_SRC_COLOR,255},
469  {GL_SRC_ALPHA,GL_ONE,                127}
470 }; 
471
472 ////////////////////////////////////////////////////////////////////////                                          
473
474 void SetSemiTransMulti(int Pass)
475 {
476  static GLenum bm1=GL_ZERO;
477  static GLenum bm2=GL_ONE;
478
479  ubGloAlpha=255;
480  ubGloColAlpha=255;
481  
482  // are we enabling SemiTransparent mode?
483  if(DrawSemiTrans)
484   {
485    if(bDrawTextured)
486     {
487      bm1=MultiTexTransSets[GlobalTextABR][Pass].srcFac;
488      bm2=MultiTexTransSets[GlobalTextABR][Pass].dstFac;
489      ubGloAlpha=MultiTexTransSets[GlobalTextABR][Pass].alpha;
490     }
491    // no texture
492    else
493     {
494      bm1=MultiColTransSets[GlobalTextABR].srcFac;
495      bm2=MultiColTransSets[GlobalTextABR].dstFac;
496      ubGloColAlpha=MultiColTransSets[GlobalTextABR].alpha;
497     }
498   }
499  // no shading
500  else
501   {
502    if(Pass==0)
503     {
504      // disable blending
505      bm1=GL_ONE;bm2=GL_ZERO;
506     }
507    else
508     {
509      // disable blending, but add src col a second time
510      bm1=GL_ONE;bm2=GL_ONE;
511     }
512   }
513
514  if(!bBlendEnable)
515   {glEnable(GL_BLEND);bBlendEnable=TRUE;}              // wanna blend\r
516
517  if(bm1!=obm1 || bm2!=obm2)
518   {
519    glBlendFunc(bm1,bm2);                               // set blend func\r
520    obm1=bm1;obm2=bm2;
521   }
522 }
523
524 ////////////////////////////////////////////////////////////////////////                                          
525 // Set several rendering stuff including blending 
526 ////////////////////////////////////////////////////////////////////////
527
528 __inline void SetZMask3O(void)
529 {
530  if(iUseMask && DrawSemiTrans && !iSetMask)
531   {
532    vertex[0].z=vertex[1].z=vertex[2].z=gl_z;
533    gl_z+=0.00004f;
534   }
535 }
536
537 __inline void SetZMask3(void)
538 {
539  if(iUseMask)
540   {
541    if(iSetMask || DrawSemiTrans)
542     {vertex[0].z=vertex[1].z=vertex[2].z=0.95f;}
543    else
544     {
545      vertex[0].z=vertex[1].z=vertex[2].z=gl_z;
546      gl_z+=0.00004f;
547     }
548   }
549 }
550
551 __inline void SetZMask3NT(void)
552 {
553  if(iUseMask)
554   {
555    if(iSetMask)
556     {vertex[0].z=vertex[1].z=vertex[2].z=0.95f;}
557    else
558     {
559      vertex[0].z=vertex[1].z=vertex[2].z=gl_z;
560      gl_z+=0.00004f;
561     }
562   }
563 }
564
565 ////////////////////////////////////////////////////////////////////////
566
567 __inline void SetZMask4O(void)
568 {
569  if(iUseMask && DrawSemiTrans && !iSetMask)
570   {
571    vertex[0].z=vertex[1].z=vertex[2].z=vertex[3].z=gl_z;
572    gl_z+=0.00004f;
573   }
574 }
575
576 __inline void SetZMask4(void)
577 {
578  if(iUseMask)
579   {
580    if(iSetMask || DrawSemiTrans)
581     {vertex[0].z=vertex[1].z=vertex[2].z=vertex[3].z=0.95f;}
582    else
583     {
584      vertex[0].z=vertex[1].z=vertex[2].z=vertex[3].z=gl_z;
585      gl_z+=0.00004f;
586     }
587   }
588 }
589
590 __inline void SetZMask4NT(void)
591 {
592  if(iUseMask)
593   {
594    if(iSetMask==1)
595     {vertex[0].z=vertex[1].z=vertex[2].z=vertex[3].z=0.95f;}
596    else
597     {
598      vertex[0].z=vertex[1].z=vertex[2].z=vertex[3].z=gl_z;
599      gl_z+=0.00004f;
600     }
601   }
602 }
603 \r
604 __inline void SetZMask4SP(void)\r
605 {\r
606  if(iUseMask)\r
607   {\r
608    if(iSetMask==1)\r
609     {vertex[0].z=vertex[1].z=vertex[2].z=vertex[3].z=0.95f;}\r
610    else\r
611     {\r
612      if(bCheckMask)\r
613       {\r
614        vertex[0].z=vertex[1].z=vertex[2].z=vertex[3].z=gl_z;\r
615        gl_z+=0.00004f;\r
616       }\r
617      else\r
618       {vertex[0].z=vertex[1].z=vertex[2].z=vertex[3].z=0.95f;}\r
619     }\r
620   }\r
621 }\r
622 \r
623 ////////////////////////////////////////////////////////////////////////
624
625 __inline void SetRenderState(uint32_t DrawAttributes)
626 {
627  bDrawNonShaded = (SHADETEXBIT(DrawAttributes)) ? TRUE : FALSE;
628  DrawSemiTrans = (SEMITRANSBIT(DrawAttributes)) ? TRUE : FALSE;
629 }                         
630
631 ////////////////////////////////////////////////////////////////////////                                          
632
633 __inline void SetRenderColor(uint32_t DrawAttributes)
634 {
635  if(bDrawNonShaded) {g_m1=g_m2=g_m3=128;}
636  else
637   {
638    g_m1=DrawAttributes&0xff;
639    g_m2=(DrawAttributes>>8)&0xff;
640    g_m3=(DrawAttributes>>16)&0xff;
641   }
642 }
643
644 ////////////////////////////////////////////////////////////////////////                                          
645                                
646 void SetRenderMode(uint32_t DrawAttributes, BOOL bSCol)
647 {
648  if((bUseMultiPass) && (bDrawTextured) && !(bDrawNonShaded))
649       {bDrawMultiPass = TRUE; SetSemiTransMulti(0);}
650  else {bDrawMultiPass = FALSE;SetSemiTrans();}
651
652  if(bDrawTextured)                                     // texture ? build it/get it from cache
653   {
654    GLuint currTex;
655    if(bUsingTWin)       currTex=LoadTextureWnd(GlobalTexturePage,GlobalTextTP, ulClutID);
656    else if(bUsingMovie) currTex=LoadTextureMovie();
657    else                 currTex=SelectSubTextureS(GlobalTextTP,ulClutID);
658
659    if(gTexName!=currTex)
660     {gTexName=currTex;glBindTexture(GL_TEXTURE_2D,currTex);}
661
662    if(!bTexEnabled)                                    // -> turn texturing on
663     {bTexEnabled=TRUE;glEnable(GL_TEXTURE_2D);}
664   }
665  else                                                  // no texture ?
666  if(bTexEnabled) 
667   {bTexEnabled=FALSE;glDisable(GL_TEXTURE_2D);}        // -> turn texturing off
668
669  if(bSCol)                                             // also set color ?
670   {
671    if((dwActFixes&4) && ((DrawAttributes&0x00ffffff)==0))
672      DrawAttributes|=0x007f7f7f;
673
674    if(bDrawNonShaded)                                  // -> non shaded?\r
675     {
676      if(bGLBlend)  vertex[0].c.lcol=0x7f7f7f;          // --> solid color...\r
677      else          vertex[0].c.lcol=0xffffff;
678     }
679    else                                                // -> shaded?
680     {
681      if(!bUseMultiPass && !bGLBlend)                   // --> given color...\r
682           vertex[0].c.lcol=DoubleBGR2RGB(DrawAttributes);
683      else vertex[0].c.lcol=DrawAttributes;
684     }
685    vertex[0].c.col[3]=ubGloAlpha;                      // -> set color with\r
686    SETCOL(vertex[0]);                                  //    texture alpha
687   }
688  
689  if(bDrawSmoothShaded!=bOldSmoothShaded)               // shading changed?\r
690   {
691    if(bDrawSmoothShaded) glShadeModel(GL_SMOOTH);      // -> set actual shading\r
692    else                  glShadeModel(GL_FLAT);
693    bOldSmoothShaded=bDrawSmoothShaded;
694   }
695 }
696
697 ////////////////////////////////////////////////////////////////////////                                          
698 // Set Opaque multipass color
699 ////////////////////////////////////////////////////////////////////////
700
701 void SetOpaqueColor(uint32_t DrawAttributes)
702 {
703  if(bDrawNonShaded) return;                            // no shading? bye\r
704   
705  DrawAttributes=DoubleBGR2RGB(DrawAttributes);         // multipass is just half color, so double it on opaque pass
706  vertex[0].c.lcol=DrawAttributes|0xff000000;
707  SETCOL(vertex[0]);                                    // set color
708 }
709
710 ////////////////////////////////////////////////////////////////////////                                          
711 // Fucking stupid screen coord checking
712 ////////////////////////////////////////////////////////////////////////
713
714 BOOL ClipVertexListScreen(void)
715 {
716  if (lx0 >= PSXDisplay.DisplayEnd.x)      goto NEXTSCRTEST;
717  if (ly0 >= PSXDisplay.DisplayEnd.y)      goto NEXTSCRTEST;
718  if (lx2 <  PSXDisplay.DisplayPosition.x) goto NEXTSCRTEST;
719  if (ly2 <  PSXDisplay.DisplayPosition.y) goto NEXTSCRTEST;
720
721  return TRUE;
722
723 NEXTSCRTEST:
724  if(PSXDisplay.InterlacedTest) return FALSE;
725
726  if (lx0 >= PreviousPSXDisplay.DisplayEnd.x)      return FALSE;
727  if (ly0 >= PreviousPSXDisplay.DisplayEnd.y)      return FALSE;
728  if (lx2 <  PreviousPSXDisplay.DisplayPosition.x) return FALSE;
729  if (ly2 <  PreviousPSXDisplay.DisplayPosition.y) return FALSE;
730
731  return TRUE;
732 }
733
734 ////////////////////////////////////////////////////////////////////////
735
736 BOOL bDrawOffscreenFront(void)
737 {
738  if(sxmin < PSXDisplay.DisplayPosition.x) return FALSE;   // must be complete in front
739  if(symin < PSXDisplay.DisplayPosition.y) return FALSE;
740  if(sxmax > PSXDisplay.DisplayEnd.x)      return FALSE;
741  if(symax > PSXDisplay.DisplayEnd.y)      return FALSE;
742  return TRUE;
743 }
744
745 BOOL bOnePointInFront(void)
746 {
747  if(sxmax< PSXDisplay.DisplayPosition.x)
748   return FALSE;
749
750  if(symax< PSXDisplay.DisplayPosition.y)
751   return FALSE;
752
753  if(sxmin>=PSXDisplay.DisplayEnd.x)
754   return FALSE;
755
756  if(symin>=PSXDisplay.DisplayEnd.y)
757   return FALSE;
758
759  return TRUE;
760 }
761  
762
763 BOOL bOnePointInBack(void)
764 {
765  if(sxmax< PreviousPSXDisplay.DisplayPosition.x)
766   return FALSE;
767
768  if(symax< PreviousPSXDisplay.DisplayPosition.y)
769   return FALSE;
770
771  if(sxmin>=PreviousPSXDisplay.DisplayEnd.x)
772   return FALSE;
773
774  if(symin>=PreviousPSXDisplay.DisplayEnd.y)
775   return FALSE;
776
777  return TRUE;
778 }
779  
780 BOOL bDrawOffscreen4(void)
781 {
782  BOOL bFront;short sW,sH;
783
784  sxmax=max(lx0,max(lx1,max(lx2,lx3)));
785  if(sxmax<drawX) return FALSE;
786  sxmin=min(lx0,min(lx1,min(lx2,lx3)));
787  if(sxmin>drawW) return FALSE;
788  symax=max(ly0,max(ly1,max(ly2,ly3)));
789  if(symax<drawY) return FALSE;
790  symin=min(ly0,min(ly1,min(ly2,ly3)));
791  if(symin>drawH) return FALSE;
792
793  if(PSXDisplay.Disabled) return TRUE;                  // disabled? ever
794
795  if(iOffscreenDrawing==1) return bFullVRam;
796
797  if(dwActFixes&1 && iOffscreenDrawing==4)
798   {
799    if(PreviousPSXDisplay.DisplayPosition.x==PSXDisplay.DisplayPosition.x &&
800       PreviousPSXDisplay.DisplayPosition.y==PSXDisplay.DisplayPosition.y &&
801       PreviousPSXDisplay.DisplayEnd.x==PSXDisplay.DisplayEnd.x &&
802       PreviousPSXDisplay.DisplayEnd.y==PSXDisplay.DisplayEnd.y)
803     {
804      bRenderFrontBuffer=TRUE;
805      return FALSE;
806     }
807   }
808
809  sW=drawW-1;sH=drawH-1;
810  
811  sxmin=min(sW,max(sxmin,drawX));
812  sxmax=max(drawX,min(sxmax,sW));
813  symin=min(sH,max(symin,drawY));
814  symax=max(drawY,min(symax,sH));
815
816  if(bOnePointInBack()) return bFullVRam;
817
818  if(iOffscreenDrawing==2) 
819       bFront=bDrawOffscreenFront();
820  else bFront=bOnePointInFront();
821
822  if(bFront)
823   {
824    if(PSXDisplay.InterlacedTest) return bFullVRam;      // -> ok, no need for adjust
825                                
826    vertex[0].x=lx0 - PSXDisplay.DisplayPosition.x+PreviousPSXDisplay.Range.x0;
827    vertex[1].x=lx1 - PSXDisplay.DisplayPosition.x+PreviousPSXDisplay.Range.x0;
828    vertex[2].x=lx2 - PSXDisplay.DisplayPosition.x+PreviousPSXDisplay.Range.x0;
829    vertex[3].x=lx3 - PSXDisplay.DisplayPosition.x+PreviousPSXDisplay.Range.x0;
830    vertex[0].y=ly0 - PSXDisplay.DisplayPosition.y+PreviousPSXDisplay.Range.y0;
831    vertex[1].y=ly1 - PSXDisplay.DisplayPosition.y+PreviousPSXDisplay.Range.y0;
832    vertex[2].y=ly2 - PSXDisplay.DisplayPosition.y+PreviousPSXDisplay.Range.y0;
833    vertex[3].y=ly3 - PSXDisplay.DisplayPosition.y+PreviousPSXDisplay.Range.y0;
834
835    if(iOffscreenDrawing==4 && !(dwActFixes&1))         // -> frontbuffer wanted\r
836     {
837      bRenderFrontBuffer=TRUE;
838      //return TRUE;
839     }
840    return bFullVRam;                                   // -> but no od\r
841   }
842
843  return TRUE;
844 }
845
846 ////////////////////////////////////////////////////////////////////////
847  
848 BOOL bDrawOffscreen3(void)
849 {
850  BOOL bFront;short sW,sH;
851
852  sxmax=max(lx0,max(lx1,lx2));
853  if(sxmax<drawX) return FALSE;
854  sxmin=min(lx0,min(lx1,lx2));
855  if(sxmin>drawW) return FALSE;
856  symax=max(ly0,max(ly1,ly2));
857  if(symax<drawY) return FALSE;
858  symin=min(ly0,min(ly1,ly2));
859  if(symin>drawH) return FALSE;
860
861  if(PSXDisplay.Disabled) return TRUE;                  // disabled? ever\r
862
863  if(iOffscreenDrawing==1) return bFullVRam;
864
865  sW=drawW-1;sH=drawH-1;
866  sxmin=min(sW,max(sxmin,drawX));
867  sxmax=max(drawX,min(sxmax,sW));
868  symin=min(sH,max(symin,drawY));
869  symax=max(drawY,min(symax,sH));
870
871  if(bOnePointInBack()) return bFullVRam;
872
873  if(iOffscreenDrawing==2) 
874       bFront=bDrawOffscreenFront();
875  else bFront=bOnePointInFront();
876
877  if(bFront)
878   {
879    if(PSXDisplay.InterlacedTest) return bFullVRam;     // -> ok, no need for adjust\r
880
881    vertex[0].x=lx0 - PSXDisplay.DisplayPosition.x+PreviousPSXDisplay.Range.x0;
882    vertex[1].x=lx1 - PSXDisplay.DisplayPosition.x+PreviousPSXDisplay.Range.x0;
883    vertex[2].x=lx2 - PSXDisplay.DisplayPosition.x+PreviousPSXDisplay.Range.x0;
884    vertex[0].y=ly0 - PSXDisplay.DisplayPosition.y+PreviousPSXDisplay.Range.y0;
885    vertex[1].y=ly1 - PSXDisplay.DisplayPosition.y+PreviousPSXDisplay.Range.y0;
886    vertex[2].y=ly2 - PSXDisplay.DisplayPosition.y+PreviousPSXDisplay.Range.y0;
887
888    if(iOffscreenDrawing==4)                            // -> frontbuffer wanted\r
889     {
890      bRenderFrontBuffer=TRUE;
891    //  return TRUE;
892     }
893
894    return bFullVRam;                                   // -> but no od\r
895   }
896
897  return TRUE;
898 }
899
900 ////////////////////////////////////////////////////////////////////////
901
902 BOOL FastCheckAgainstScreen(short imageX0,short imageY0,short imageX1,short imageY1)
903 {
904  PSXRect_t xUploadArea;
905
906  imageX1 += imageX0;
907  imageY1 += imageY0;
908
909  if (imageX0 < PreviousPSXDisplay.DisplayPosition.x)
910    xUploadArea.x0 = PreviousPSXDisplay.DisplayPosition.x;
911  else
912  if (imageX0 > PreviousPSXDisplay.DisplayEnd.x)
913    xUploadArea.x0 = PreviousPSXDisplay.DisplayEnd.x;
914  else
915    xUploadArea.x0 = imageX0;
916
917  if(imageX1 < PreviousPSXDisplay.DisplayPosition.x)
918    xUploadArea.x1 = PreviousPSXDisplay.DisplayPosition.x;
919  else
920  if (imageX1 > PreviousPSXDisplay.DisplayEnd.x)
921    xUploadArea.x1 = PreviousPSXDisplay.DisplayEnd.x;
922  else
923    xUploadArea.x1 = imageX1;
924
925  if (imageY0 < PreviousPSXDisplay.DisplayPosition.y)
926    xUploadArea.y0 = PreviousPSXDisplay.DisplayPosition.y;
927  else
928  if (imageY0 > PreviousPSXDisplay.DisplayEnd.y)
929    xUploadArea.y0 = PreviousPSXDisplay.DisplayEnd.y;
930  else
931    xUploadArea.y0 = imageY0;
932
933  if (imageY1 < PreviousPSXDisplay.DisplayPosition.y)
934    xUploadArea.y1 = PreviousPSXDisplay.DisplayPosition.y;
935  else
936  if (imageY1 > PreviousPSXDisplay.DisplayEnd.y)
937    xUploadArea.y1 = PreviousPSXDisplay.DisplayEnd.y;
938  else
939    xUploadArea.y1 = imageY1;
940
941  if ((xUploadArea.x0 != xUploadArea.x1) && (xUploadArea.y0 != xUploadArea.y1))
942       return TRUE;
943  else return FALSE;
944 }
945
946 BOOL CheckAgainstScreen(short imageX0,short imageY0,short imageX1,short imageY1)
947 {
948  imageX1 += imageX0;
949  imageY1 += imageY0;
950 \r
951  if (imageX0 < PreviousPSXDisplay.DisplayPosition.x)
952    xrUploadArea.x0 = PreviousPSXDisplay.DisplayPosition.x;
953  else
954  if (imageX0 > PreviousPSXDisplay.DisplayEnd.x)
955    xrUploadArea.x0 = PreviousPSXDisplay.DisplayEnd.x;
956  else
957    xrUploadArea.x0 = imageX0;
958
959  if(imageX1 < PreviousPSXDisplay.DisplayPosition.x)
960    xrUploadArea.x1 = PreviousPSXDisplay.DisplayPosition.x;
961  else
962  if (imageX1 > PreviousPSXDisplay.DisplayEnd.x)
963    xrUploadArea.x1 = PreviousPSXDisplay.DisplayEnd.x;
964  else
965    xrUploadArea.x1 = imageX1;
966
967  if (imageY0 < PreviousPSXDisplay.DisplayPosition.y)
968    xrUploadArea.y0 = PreviousPSXDisplay.DisplayPosition.y;
969  else
970  if (imageY0 > PreviousPSXDisplay.DisplayEnd.y)
971    xrUploadArea.y0 = PreviousPSXDisplay.DisplayEnd.y;
972  else
973    xrUploadArea.y0 = imageY0;
974
975  if (imageY1 < PreviousPSXDisplay.DisplayPosition.y)
976    xrUploadArea.y1 = PreviousPSXDisplay.DisplayPosition.y;
977  else
978  if (imageY1 > PreviousPSXDisplay.DisplayEnd.y)
979    xrUploadArea.y1 = PreviousPSXDisplay.DisplayEnd.y;
980  else
981    xrUploadArea.y1 = imageY1;
982
983  if ((xrUploadArea.x0 != xrUploadArea.x1) && (xrUploadArea.y0 != xrUploadArea.y1))
984       return TRUE;
985  else return FALSE;
986 }
987
988 BOOL FastCheckAgainstFrontScreen(short imageX0,short imageY0,short imageX1,short imageY1)
989 {
990  PSXRect_t xUploadArea;
991
992  imageX1 += imageX0;
993  imageY1 += imageY0;
994
995  if (imageX0 < PSXDisplay.DisplayPosition.x)
996    xUploadArea.x0 = PSXDisplay.DisplayPosition.x;
997  else
998  if (imageX0 > PSXDisplay.DisplayEnd.x)
999    xUploadArea.x0 = PSXDisplay.DisplayEnd.x;
1000  else
1001    xUploadArea.x0 = imageX0;
1002
1003  if(imageX1 < PSXDisplay.DisplayPosition.x)
1004    xUploadArea.x1 = PSXDisplay.DisplayPosition.x;
1005  else
1006  if (imageX1 > PSXDisplay.DisplayEnd.x)
1007    xUploadArea.x1 = PSXDisplay.DisplayEnd.x;
1008  else
1009    xUploadArea.x1 = imageX1;
1010
1011  if (imageY0 < PSXDisplay.DisplayPosition.y)
1012    xUploadArea.y0 = PSXDisplay.DisplayPosition.y;
1013  else
1014  if (imageY0 > PSXDisplay.DisplayEnd.y)
1015    xUploadArea.y0 = PSXDisplay.DisplayEnd.y;
1016  else
1017    xUploadArea.y0 = imageY0;
1018
1019  if (imageY1 < PSXDisplay.DisplayPosition.y)
1020    xUploadArea.y1 = PSXDisplay.DisplayPosition.y;
1021  else
1022  if (imageY1 > PSXDisplay.DisplayEnd.y)
1023    xUploadArea.y1 = PSXDisplay.DisplayEnd.y;
1024  else
1025    xUploadArea.y1 = imageY1;
1026
1027  if ((xUploadArea.x0 != xUploadArea.x1) && (xUploadArea.y0 != xUploadArea.y1))
1028       return TRUE; 
1029  else return FALSE;
1030 }
1031
1032 BOOL CheckAgainstFrontScreen(short imageX0,short imageY0,short imageX1,short imageY1)
1033 {
1034  imageX1 += imageX0;
1035  imageY1 += imageY0;
1036
1037  if (imageX0 < PSXDisplay.DisplayPosition.x)
1038    xrUploadArea.x0 = PSXDisplay.DisplayPosition.x;
1039  else
1040  if (imageX0 > PSXDisplay.DisplayEnd.x)
1041    xrUploadArea.x0 = PSXDisplay.DisplayEnd.x;
1042  else
1043    xrUploadArea.x0 = imageX0;
1044
1045  if(imageX1 < PSXDisplay.DisplayPosition.x)
1046    xrUploadArea.x1 = PSXDisplay.DisplayPosition.x;
1047  else
1048  if (imageX1 > PSXDisplay.DisplayEnd.x)
1049    xrUploadArea.x1 = PSXDisplay.DisplayEnd.x;
1050  else
1051    xrUploadArea.x1 = imageX1;
1052
1053  if (imageY0 < PSXDisplay.DisplayPosition.y)
1054    xrUploadArea.y0 = PSXDisplay.DisplayPosition.y;
1055  else
1056  if (imageY0 > PSXDisplay.DisplayEnd.y)
1057    xrUploadArea.y0 = PSXDisplay.DisplayEnd.y;
1058  else
1059    xrUploadArea.y0 = imageY0;
1060
1061  if (imageY1 < PSXDisplay.DisplayPosition.y)
1062    xrUploadArea.y1 = PSXDisplay.DisplayPosition.y;
1063  else
1064  if (imageY1 > PSXDisplay.DisplayEnd.y)
1065    xrUploadArea.y1 = PSXDisplay.DisplayEnd.y;
1066  else
1067    xrUploadArea.y1 = imageY1;
1068
1069  if ((xrUploadArea.x0 != xrUploadArea.x1) && (xrUploadArea.y0 != xrUploadArea.y1))
1070       return TRUE; 
1071  else return FALSE;
1072 }
1073
1074 ////////////////////////////////////////////////////////////////////////
1075
1076 void PrepareFullScreenUpload (int Position)
1077 {
1078  if (Position==-1)                                     // rgb24
1079   {
1080    if(PSXDisplay.Interlaced)
1081     {
1082      xrUploadArea.x0 = PSXDisplay.DisplayPosition.x;
1083      xrUploadArea.x1 = PSXDisplay.DisplayEnd.x;
1084      xrUploadArea.y0 = PSXDisplay.DisplayPosition.y;
1085      xrUploadArea.y1 = PSXDisplay.DisplayEnd.y;
1086     }
1087    else
1088     {
1089      xrUploadArea.x0 = PreviousPSXDisplay.DisplayPosition.x;
1090      xrUploadArea.x1 = PreviousPSXDisplay.DisplayEnd.x;
1091      xrUploadArea.y0 = PreviousPSXDisplay.DisplayPosition.y;
1092      xrUploadArea.y1 = PreviousPSXDisplay.DisplayEnd.y;
1093     }
1094
1095    if(bNeedRGB24Update)
1096     {
1097      if(lClearOnSwap) 
1098       {
1099 //       lClearOnSwap=0;
1100       }
1101      else    
1102      if(PSXDisplay.Interlaced && PreviousPSXDisplay.RGB24<2) // in interlaced mode we upload at least two full frames (GT1 menu)\r
1103       {
1104        PreviousPSXDisplay.RGB24++;
1105       }
1106      else
1107       {
1108        xrUploadArea.y1 = min(xrUploadArea.y0+xrUploadAreaRGB24.y1,xrUploadArea.y1);
1109        xrUploadArea.y0+=xrUploadAreaRGB24.y0;
1110       }
1111     }
1112   }
1113  else
1114  if (Position)
1115   {
1116    xrUploadArea.x0 = PSXDisplay.DisplayPosition.x;
1117    xrUploadArea.x1 = PSXDisplay.DisplayEnd.x;
1118    xrUploadArea.y0 = PSXDisplay.DisplayPosition.y;
1119    xrUploadArea.y1 = PSXDisplay.DisplayEnd.y;
1120   }
1121  else
1122   {
1123    xrUploadArea.x0 = PreviousPSXDisplay.DisplayPosition.x;
1124    xrUploadArea.x1 = PreviousPSXDisplay.DisplayEnd.x;
1125    xrUploadArea.y0 = PreviousPSXDisplay.DisplayPosition.y;
1126    xrUploadArea.y1 = PreviousPSXDisplay.DisplayEnd.y;
1127   }
1128
1129  if (xrUploadArea.x0 < 0)               xrUploadArea.x0 = 0;
1130  else
1131  if (xrUploadArea.x0 > 1023)            xrUploadArea.x0 = 1023;
1132
1133  if (xrUploadArea.x1 < 0)               xrUploadArea.x1 = 0;
1134  else
1135  if (xrUploadArea.x1 > 1024)            xrUploadArea.x1 = 1024;
1136
1137  if (xrUploadArea.y0 < 0)               xrUploadArea.y0 = 0;
1138  else
1139  if (xrUploadArea.y0 > iGPUHeightMask)  xrUploadArea.y0 = iGPUHeightMask;
1140
1141  if (xrUploadArea.y1 < 0)               xrUploadArea.y1 = 0;
1142  else
1143  if (xrUploadArea.y1 > iGPUHeight)      xrUploadArea.y1 = iGPUHeight;
1144
1145  if (PSXDisplay.RGB24)
1146   {
1147    InvalidateTextureArea(xrUploadArea.x0,xrUploadArea.y0,xrUploadArea.x1-xrUploadArea.x0,xrUploadArea.y1-xrUploadArea.y0);
1148   }
1149 }
1150
1151 ////////////////////////////////////////////////////////////////////////
1152 // Upload screen (MDEC and such)
1153 ////////////////////////////////////////////////////////////////////////
1154 ////////////////////////////////////////////////////////////////////////
1155 \r
1156 unsigned char * LoadDirectMovieFast(void);\r
1157 \r
1158 void UploadScreenEx(int Position)\r
1159 {\r
1160  short ya,yb,xa,xb,x, y, YStep, XStep, U, UStep,ux[4],vy[4];\r
1161 \r
1162  if(!PSXDisplay.DisplayMode.x) return;\r
1163  if(!PSXDisplay.DisplayMode.y) return;\r
1164 \r
1165  glDisable(GL_SCISSOR_TEST);\r
1166  glShadeModel(GL_FLAT);\r
1167  bOldSmoothShaded=FALSE;\r
1168  glDisable(GL_BLEND);\r
1169  bBlendEnable=FALSE;\r
1170  glDisable(GL_TEXTURE_2D);\r
1171  bTexEnabled=FALSE;\r
1172  glDisable(GL_ALPHA_TEST);\r
1173 \r
1174  glPixelZoom(((float)rRatioRect.right)/((float)PSXDisplay.DisplayMode.x),\r
1175              -1.0f*(((float)rRatioRect.bottom)/((float)PSXDisplay.DisplayMode.y)));\r
1176                                                       \r
1177  //----------------------------------------------------//\r
1178 \r
1179  YStep = 256;                                          // max texture size\r
1180  XStep = 256;\r
1181  UStep = (PSXDisplay.RGB24 ? 128 : 0);\r
1182  ya    = xrUploadArea.y0;\r
1183  yb    = xrUploadArea.y1;\r
1184  xa    = xrUploadArea.x0;\r
1185  xb    = xrUploadArea.x1;\r
1186  \r
1187  for(y=ya;y<=yb;y+=YStep)                              // loop y\r
1188   {\r
1189    U = 0;\r
1190    for(x=xa;x<=xb;x+=XStep)                            // loop x\r
1191     {\r
1192      ly0 = ly1 = y;                                    // -> get y coords\r
1193      ly2 = y + YStep;\r
1194      if (ly2 > yb) ly2 = yb;\r
1195      ly3 = ly2;\r
1196 \r
1197      lx0 = lx3 = x;                                    // -> get x coords\r
1198      lx1 = x + XStep;\r
1199      if (lx1 > xb) lx1 = xb;\r
1200 \r
1201      lx2 = lx1;\r
1202 \r
1203      ux[0]=ux[3]=(xa - x);                             // -> set tex x coords\r
1204      if (ux[0] < 0) ux[0]=ux[3]=0;\r
1205      ux[2]=ux[1]=(xb - x);\r
1206      if (ux[2] > 256) ux[2]=ux[1]=256;\r
1207 \r
1208      vy[0]=vy[1]=(ya - y);                             // -> set tex y coords\r
1209      if (vy[0] < 0) vy[0]=vy[1]=0;\r
1210      vy[2]=vy[3]=(yb - y);\r
1211      if (vy[2] > 256) vy[2]=vy[3]=256;\r
1212 \r
1213      if ((ux[0] >= ux[2]) ||                           // -> cheaters never win...\r
1214          (vy[0] >= vy[2])) continue;                   //    (but winners always cheat...)\r
1215                 \r
1216      xrMovieArea.x0=lx0+U; xrMovieArea.y0=ly0;\r
1217      xrMovieArea.x1=lx2+U; xrMovieArea.y1=ly2;\r
1218      \r
1219      offsetScreenUpload(Position);\r
1220 \r
1221      glRasterPos2f(vertex[0].x,vertex[0].y);\r
1222 \r
1223      glDrawPixels(xrMovieArea.x1-xrMovieArea.x0,\r
1224                   xrMovieArea.y1-xrMovieArea.y0,\r
1225                   GL_RGBA,GL_UNSIGNED_BYTE,\r
1226                   LoadDirectMovieFast());\r
1227 \r
1228      U+=UStep;\r
1229     }\r
1230   }\r
1231 \r
1232  //----------------------------------------------------//\r
1233 \r
1234  glPixelZoom(1.0F,1.0F);\r
1235 \r
1236  glEnable(GL_ALPHA_TEST);\r
1237  glEnable(GL_SCISSOR_TEST);\r
1238 }\r
1239 \r
1240 ////////////////////////////////////////////////////////////////////////\r
1241
1242 void UploadScreen(int Position)
1243 {
1244  short x, y, YStep, XStep, U, s, UStep,ux[4],vy[4];
1245  short xa,xb,ya,yb;
1246
1247  if(xrUploadArea.x0>1023) xrUploadArea.x0=1023;
1248  if(xrUploadArea.x1>1024) xrUploadArea.x1=1024;
1249  if(xrUploadArea.y0>iGPUHeightMask)  xrUploadArea.y0=iGPUHeightMask;\r
1250  if(xrUploadArea.y1>iGPUHeight)      xrUploadArea.y1=iGPUHeight;\r
1251
1252  if(xrUploadArea.x0==xrUploadArea.x1) return;
1253  if(xrUploadArea.y0==xrUploadArea.y1) return;
1254
1255  if(PSXDisplay.Disabled && iOffscreenDrawing<4) return;
1256 \r
1257  iDrawnSomething   = 2;\r
1258  iLastRGB24=PSXDisplay.RGB24+1;\r
1259 \r
1260  if(bSkipNextFrame) return;\r
1261 \r
1262  if(dwActFixes & 2) {UploadScreenEx(Position);return;}\r
1263
1264  bUsingMovie       = TRUE;
1265  bDrawTextured     = TRUE;                             // just doing textures\r
1266  bDrawSmoothShaded = FALSE;
1267
1268  if(bGLBlend) vertex[0].c.lcol=0xff7f7f7f;             // set solid col\r
1269  else          vertex[0].c.lcol=0xffffffff;
1270  SETCOL(vertex[0]); 
1271
1272  SetOGLDisplaySettings(0);
1273
1274  YStep = 256;                                          // max texture size
1275  XStep = 256;
1276
1277  UStep = (PSXDisplay.RGB24 ? 128 : 0);
1278  
1279  ya=xrUploadArea.y0;
1280  yb=xrUploadArea.y1;
1281  xa=xrUploadArea.x0;
1282  xb=xrUploadArea.x1;
1283
1284  for(y=ya;y<=yb;y+=YStep)                              // loop y\r
1285   {
1286    U = 0;
1287    for(x=xa;x<=xb;x+=XStep)                            // loop x\r
1288     {
1289      ly0 = ly1 = y;                                    // -> get y coords
1290      ly2 = y + YStep;
1291      if (ly2 > yb) ly2 = yb;
1292      ly3 = ly2;
1293
1294      lx0 = lx3 = x;                                    // -> get x coords
1295      lx1 = x + XStep;
1296      if (lx1 > xb) lx1 = xb;
1297
1298      lx2 = lx1;
1299
1300      ux[0]=ux[3]=(xa - x);                             // -> set tex x coords\r
1301      if (ux[0] < 0) ux[0]=ux[3]=0;
1302      ux[2]=ux[1]=(xb - x);
1303      if (ux[2] > 256) ux[2]=ux[1]=256;
1304
1305      vy[0]=vy[1]=(ya - y);                             // -> set tex y coords\r
1306      if (vy[0] < 0) vy[0]=vy[1]=0;
1307      vy[2]=vy[3]=(yb - y);
1308      if (vy[2] > 256) vy[2]=vy[3]=256;
1309
1310      if ((ux[0] >= ux[2]) ||                           // -> cheaters never win...\r
1311          (vy[0] >= vy[2])) continue;                   //    (but winners always cheat...)
1312                 
1313      xrMovieArea.x0=lx0+U; xrMovieArea.y0=ly0;
1314      xrMovieArea.x1=lx2+U; xrMovieArea.y1=ly2;
1315
1316      s=ux[2] - ux[0]; if(s>255) s=255;
1317
1318      gl_ux[2] = gl_ux[1] = s;
1319      s=vy[2] - vy[0]; if(s>255) s=255;
1320      gl_vy[2] = gl_vy[3] = s;
1321      gl_ux[0] = gl_ux[3] = gl_vy[0] = gl_vy[1] = 0;
1322
1323      SetRenderState((uint32_t)0x01000000);
1324      SetRenderMode((uint32_t)0x01000000, FALSE);  // upload texture data
1325      offsetScreenUpload(Position);
1326      assignTextureVRAMWrite();
1327
1328      PRIMdrawTexturedQuad(&vertex[0], &vertex[1], &vertex[2], &vertex[3]);
1329
1330      U+=UStep;
1331     }
1332   }
1333
1334  bUsingMovie=FALSE;                                    // done...\r
1335  bDisplayNotSet = TRUE;
1336 }
1337
1338 ////////////////////////////////////////////////////////////////////////
1339 // Detect next screen
1340 ////////////////////////////////////////////////////////////////////////
1341
1342 BOOL IsCompleteInsideNextScreen(short x, short y, short xoff, short yoff)
1343 {        
1344  if (x > PSXDisplay.DisplayPosition.x+1)     return FALSE;
1345  if ((x + xoff) < PSXDisplay.DisplayEnd.x-1) return FALSE;
1346  yoff+=y;
1347  if (y >= PSXDisplay.DisplayPosition.y &&
1348      y <= PSXDisplay.DisplayEnd.y )
1349   {
1350    if ((yoff) >= PSXDisplay.DisplayPosition.y &&
1351        (yoff) <= PSXDisplay.DisplayEnd.y ) return TRUE;
1352   }   
1353  if (y > PSXDisplay.DisplayPosition.y+1) return FALSE;
1354  if (yoff < PSXDisplay.DisplayEnd.y-1)   return FALSE;
1355  return TRUE;
1356 }
1357
1358 BOOL IsPrimCompleteInsideNextScreen(short x, short y, short xoff, short yoff)
1359 {
1360  x+=PSXDisplay.DrawOffset.x;
1361  if (x > PSXDisplay.DisplayPosition.x+1) return FALSE;
1362  y+=PSXDisplay.DrawOffset.y;
1363  if (y > PSXDisplay.DisplayPosition.y+1) return FALSE;
1364  xoff+=PSXDisplay.DrawOffset.x;
1365  if (xoff < PSXDisplay.DisplayEnd.x-1)   return FALSE;
1366  yoff+=PSXDisplay.DrawOffset.y;
1367  if (yoff < PSXDisplay.DisplayEnd.y-1)   return FALSE;
1368  return TRUE;
1369 }
1370
1371 BOOL IsInsideNextScreen(short x, short y, short xoff, short yoff)
1372 {                    
1373  if (x > PSXDisplay.DisplayEnd.x) return FALSE;
1374  if (y > PSXDisplay.DisplayEnd.y) return FALSE;
1375  if ((x + xoff) < PSXDisplay.DisplayPosition.x) return FALSE;
1376  if ((y + yoff) < PSXDisplay.DisplayPosition.y) return FALSE;
1377  return TRUE;
1378 }
1379
1380 ////////////////////////////////////////////////////////////////////////
1381 // mask stuff...
1382 ////////////////////////////////////////////////////////////////////////
1383
1384 //Mask1    Set mask bit while drawing. 1 = on
1385 //Mask2    Do not draw to mask areas. 1= on
1386
1387 void cmdSTP(unsigned char * baseAddr)
1388 {
1389  uint32_t gdata = ((uint32_t*)baseAddr)[0];
1390
1391  STATUSREG&=~0x1800;                                   // clear the necessary bits
1392  STATUSREG|=((gdata & 0x03) << 11);                    // set the current bits
1393
1394  if(!iUseMask) return;
1395 \r
1396  if(gdata&1) {sSetMask=0x8000;lSetMask=0x80008000;iSetMask=1;}\r
1397  else        {sSetMask=0;     lSetMask=0;         iSetMask=0;}\r
1398 \r
1399  if(gdata&2) \r
1400   {\r
1401    if(!(gdata&1)) iSetMask=2;\r
1402    bCheckMask=TRUE;\r
1403    if(iDepthFunc==0) return;\r
1404    iDepthFunc=0;\r
1405    glDepthFunc(GL_LESS);\r
1406   }\r
1407  else\r
1408   {\r
1409    bCheckMask=FALSE;\r
1410    if(iDepthFunc==1) return;\r
1411    glDepthFunc(GL_ALWAYS);\r
1412    iDepthFunc=1;\r
1413   }\r
1414 }
1415
1416 ////////////////////////////////////////////////////////////////////////
1417 // cmd: Set texture page infos
1418 ////////////////////////////////////////////////////////////////////////
1419
1420 void cmdTexturePage(unsigned char * baseAddr)
1421 {
1422  uint32_t gdata = ((uint32_t *)baseAddr)[0];
1423  UpdateGlobalTP((unsigned short)gdata);
1424  GlobalTextREST = (gdata&0x00ffffff)>>9;
1425 }
1426
1427 ////////////////////////////////////////////////////////////////////////
1428 // cmd: turn on/off texture window
1429 ////////////////////////////////////////////////////////////////////////
1430
1431 void cmdTextureWindow(unsigned char *baseAddr)
1432 {
1433  uint32_t gdata = ((uint32_t *)baseAddr)[0];\r
1434  uint32_t YAlign,XAlign;\r
1435 \r
1436  ulGPUInfoVals[INFO_TW]=gdata&0xFFFFF;\r
1437 \r
1438  if(gdata & 0x020)\r
1439   TWin.Position.y1 = 8;    // xxxx1\r
1440  else if (gdata & 0x040)\r
1441   TWin.Position.y1 = 16;   // xxx10\r
1442  else if (gdata & 0x080)\r
1443   TWin.Position.y1 = 32;   // xx100\r
1444  else if (gdata & 0x100)\r
1445   TWin.Position.y1 = 64;   // x1000\r
1446  else if (gdata & 0x200)\r
1447   TWin.Position.y1 = 128;  // 10000\r
1448  else\r
1449   TWin.Position.y1 = 256;  // 00000\r
1450 \r
1451   // Texture window size is determined by the least bit set of the relevant 5 bits\r
1452 \r
1453  if (gdata & 0x001)\r
1454   TWin.Position.x1 = 8;    // xxxx1\r
1455  else if (gdata & 0x002)\r
1456   TWin.Position.x1 = 16;   // xxx10\r
1457  else if (gdata & 0x004)\r
1458   TWin.Position.x1 = 32;   // xx100\r
1459  else if (gdata & 0x008)\r
1460   TWin.Position.x1 = 64;   // x1000\r
1461  else if (gdata & 0x010)\r
1462   TWin.Position.x1 = 128;  // 10000\r
1463  else\r
1464   TWin.Position.x1 = 256;  // 00000\r
1465 \r
1466  // Re-calculate the bit field, because we can't trust what is passed in the data\r
1467 \r
1468  YAlign = (uint32_t)(32 - (TWin.Position.y1 >> 3));\r
1469  XAlign = (uint32_t)(32 - (TWin.Position.x1 >> 3));\r
1470 \r
1471  // Absolute position of the start of the texture window\r
1472 \r
1473  TWin.Position.y0 = (short)(((gdata >> 15) & YAlign) << 3);\r
1474  TWin.Position.x0 = (short)(((gdata >> 10) & XAlign) << 3);\r
1475
1476  if((TWin.Position.x0 == 0 &&                          // tw turned off\r
1477      TWin.Position.y0 == 0 &&
1478      TWin.Position.x1 == 0 &&
1479      TWin.Position.y1 == 0) ||
1480      (TWin.Position.x1 == 256 &&
1481       TWin.Position.y1 == 256))
1482   {
1483    bUsingTWin = FALSE;                                 // -> just do it\r
1484
1485 #ifdef OWNSCALE
1486    TWin.UScaleFactor = 1.0f;
1487    TWin.VScaleFactor = 1.0f;
1488 #else
1489    TWin.UScaleFactor = 
1490    TWin.VScaleFactor = 1.0f/256.0f;
1491 #endif
1492   }
1493  else                                                  // tw turned on
1494   {
1495    bUsingTWin = TRUE;
1496
1497    TWin.OPosition.y1 = TWin.Position.y1;               // -> get psx sizes
1498    TWin.OPosition.x1 = TWin.Position.x1;              
1499
1500    if(TWin.Position.x1<=2)   TWin.Position.x1=2;       // -> set OGL sizes
1501    else
1502    if(TWin.Position.x1<=4)   TWin.Position.x1=4;
1503    else
1504    if(TWin.Position.x1<=8)   TWin.Position.x1=8;
1505    else
1506    if(TWin.Position.x1<=16)  TWin.Position.x1=16;
1507    else
1508    if(TWin.Position.x1<=32)  TWin.Position.x1=32;
1509    else
1510    if(TWin.Position.x1<=64)  TWin.Position.x1=64;
1511    else
1512    if(TWin.Position.x1<=128) TWin.Position.x1=128;
1513    else
1514    if(TWin.Position.x1<=256) TWin.Position.x1=256;
1515    
1516    if(TWin.Position.y1<=2)   TWin.Position.y1=2;
1517    else
1518    if(TWin.Position.y1<=4)   TWin.Position.y1=4;
1519    else
1520    if(TWin.Position.y1<=8)   TWin.Position.y1=8;
1521    else
1522    if(TWin.Position.y1<=16)  TWin.Position.y1=16;
1523    else
1524    if(TWin.Position.y1<=32)  TWin.Position.y1=32;
1525    else
1526    if(TWin.Position.y1<=64)  TWin.Position.y1=64;
1527    else
1528    if(TWin.Position.y1<=128) TWin.Position.y1=128;
1529    else
1530    if(TWin.Position.y1<=256) TWin.Position.y1=256;
1531
1532 #ifdef OWNSCALE
1533    TWin.UScaleFactor = (float)TWin.Position.x1;
1534    TWin.VScaleFactor = (float)TWin.Position.y1;
1535 #else
1536    TWin.UScaleFactor = ((float)TWin.Position.x1)/256.0f; // -> set scale factor\r
1537    TWin.VScaleFactor = ((float)TWin.Position.y1)/256.0f;
1538 #endif
1539   }
1540 }
1541
1542 ////////////////////////////////////////////////////////////////////////
1543 // mmm, Lewpy uses that in TileS ... I don't ;)
1544 ////////////////////////////////////////////////////////////////////////
1545 \r
1546 /*
1547 void ClampToPSXDrawAreaOffset(short *x0, short *y0, short *x1, short *y1)
1548 {
1549  if (*x0 < PSXDisplay.DrawArea.x0)
1550   {
1551    *x1 -= (PSXDisplay.DrawArea.x0 - *x0);
1552    *x0 = PSXDisplay.DrawArea.x0;
1553   }
1554  else
1555  if (*x0 > PSXDisplay.DrawArea.x1)
1556   {
1557    *x0 = PSXDisplay.DrawArea.x1;
1558    *x1 = 0;
1559   }
1560
1561  if (*y0 < PSXDisplay.DrawArea.y0)
1562   {
1563    *y1 -= (PSXDisplay.DrawArea.y0 - *y0);
1564    *y0 = PSXDisplay.DrawArea.y0;
1565   }
1566  else
1567  if (*y0 > PSXDisplay.DrawArea.y1)
1568   {
1569    *y0 = PSXDisplay.DrawArea.y1;
1570    *y1 = 0;
1571   }
1572
1573  if (*x1 < 0) *x1 = 0;
1574
1575  if ((*x1 + *x0) > PSXDisplay.DrawArea.x1)
1576   *x1 = (PSXDisplay.DrawArea.x1 -  *x0 + 1);
1577
1578  if (*y1 < 0) *y1 = 0;
1579
1580  if ((*y1 + *y0) > PSXDisplay.DrawArea.y1)
1581   *y1 = (PSXDisplay.DrawArea.y1 -  *y0 + 1);
1582 }
1583 */\r
1584
1585 ////////////////////////////////////////////////////////////////////////
1586 // Check draw area dimensions
1587 ////////////////////////////////////////////////////////////////////////
1588
1589 void ClampToPSXScreen(short *x0, short *y0, short *x1, short *y1)
1590 {
1591  if (*x0 < 0)               *x0 = 0;
1592  else
1593  if (*x0 > 1023)            *x0 = 1023;
1594             
1595  if (*x1 < 0)               *x1 = 0;
1596  else
1597  if (*x1 > 1023)            *x1 = 1023;
1598
1599  if (*y0 < 0)               *y0 = 0;
1600  else
1601  if (*y0 > iGPUHeightMask)  *y0 = iGPUHeightMask;\r
1602             
1603  if (*y1 < 0)               *y1 = 0;
1604  else
1605  if (*y1 > iGPUHeightMask)  *y1 = iGPUHeightMask;\r
1606 }
1607
1608 ////////////////////////////////////////////////////////////////////////
1609 // Used in Load Image and Blk Fill
1610 ////////////////////////////////////////////////////////////////////////
1611
1612 void ClampToPSXScreenOffset(short *x0, short *y0, short *x1, short *y1)
1613 {
1614  if (*x0 < 0)
1615   { *x1 += *x0;  *x0 = 0; }
1616  else
1617  if (*x0 > 1023)
1618   { *x0 = 1023;  *x1 = 0; }
1619
1620  if (*y0 < 0)
1621   { *y1 += *y0;  *y0 = 0; }
1622  else
1623  if (*y0 > iGPUHeightMask)\r
1624   { *y0 = iGPUHeightMask;   *y1 = 0; }\r
1625
1626  if (*x1 < 0) *x1 = 0;
1627
1628  if ((*x1 + *x0) > 1024) *x1 = (1024 -  *x0);
1629
1630  if (*y1 < 0) *y1 = 0;
1631
1632  if ((*y1 + *y0) > iGPUHeight)  *y1 = (iGPUHeight -  *y0);\r
1633 }
1634
1635 ////////////////////////////////////////////////////////////////////////
1636 // cmd: start of drawing area... primitives will be clipped inside
1637 ////////////////////////////////////////////////////////////////////////
1638
1639 void cmdDrawAreaStart(unsigned char * baseAddr)
1640 {
1641  uint32_t gdata = ((uint32_t *)baseAddr)[0];
1642 \r
1643  drawX = gdata & 0x3ff;                                // for soft drawing\r
1644  if(drawX>=1024) drawX=1023;\r
1645
1646  if(dwGPUVersion==2)\r
1647   {\r
1648    ulGPUInfoVals[INFO_DRAWSTART]=gdata&0x3FFFFF;\r
1649    drawY  = (gdata>>12)&0x3ff;\r
1650   }\r
1651  else\r
1652   {\r
1653    ulGPUInfoVals[INFO_DRAWSTART]=gdata&0xFFFFF;\r
1654    drawY  = (gdata>>10)&0x3ff;\r
1655   }\r
1656 \r
1657  if(drawY>=iGPUHeight) drawY=iGPUHeightMask;\r
1658
1659  PreviousPSXDisplay.DrawArea.y0=PSXDisplay.DrawArea.y0;
1660  PreviousPSXDisplay.DrawArea.x0=PSXDisplay.DrawArea.x0;
1661
1662  PSXDisplay.DrawArea.y0 = (short)drawY;                // for OGL drawing\r
1663  PSXDisplay.DrawArea.x0 = (short)drawX;
1664 }
1665
1666 ////////////////////////////////////////////////////////////////////////
1667 // cmd: end of drawing area... primitives will be clipped inside
1668 ////////////////////////////////////////////////////////////////////////
1669
1670 void cmdDrawAreaEnd(unsigned char * baseAddr)
1671 {
1672  uint32_t gdata = ((uint32_t *)baseAddr)[0];
1673 \r
1674  drawW = gdata & 0x3ff;                                // for soft drawing
1675  if(drawW>=1024) drawW=1023;
1676 \r
1677  if(dwGPUVersion==2)\r
1678   {\r
1679    ulGPUInfoVals[INFO_DRAWEND]=gdata&0x3FFFFF;\r
1680    drawH  = (gdata>>12)&0x3ff;\r
1681   }\r
1682  else\r
1683   {\r
1684    ulGPUInfoVals[INFO_DRAWEND]=gdata&0xFFFFF;\r
1685    drawH  = (gdata>>10)&0x3ff;\r
1686   }\r
1687  \r
1688  if(drawH>=iGPUHeight) drawH=iGPUHeightMask;\r
1689
1690  PSXDisplay.DrawArea.y1 = (short)drawH;                // for OGL drawing\r
1691  PSXDisplay.DrawArea.x1 = (short)drawW;
1692
1693  ClampToPSXScreen(&PSXDisplay.DrawArea.x0,             // clamp
1694                   &PSXDisplay.DrawArea.y0,
1695                   &PSXDisplay.DrawArea.x1,
1696                   &PSXDisplay.DrawArea.y1);
1697
1698  bDisplayNotSet = TRUE;
1699 }
1700
1701 ////////////////////////////////////////////////////////////////////////
1702 // cmd: draw offset... will be added to prim coords
1703 ////////////////////////////////////////////////////////////////////////
1704
1705 void cmdDrawOffset(unsigned char * baseAddr)
1706 {
1707  uint32_t gdata = ((uint32_t *)baseAddr)[0];
1708 \r
1709  PreviousPSXDisplay.DrawOffset.x = 
1710   PSXDisplay.DrawOffset.x = (short)(gdata & 0x7ff);\r
1711 \r
1712  if (dwGPUVersion == 2)\r
1713   {\r
1714    ulGPUInfoVals[INFO_DRAWOFF] = gdata&0x7FFFFF;\r
1715    PSXDisplay.DrawOffset.y = (short)((gdata>>12) & 0x7ff);\r
1716   }\r
1717  else\r
1718   {\r
1719    ulGPUInfoVals[INFO_DRAWOFF]=gdata&0x3FFFFF;\r
1720    PSXDisplay.DrawOffset.y = (short)((gdata>>11) & 0x7ff);\r
1721   }\r
1722  
1723  PSXDisplay.DrawOffset.x=(short)(((int)PSXDisplay.DrawOffset.x<<21)>>21);
1724  PSXDisplay.DrawOffset.y=(short)(((int)PSXDisplay.DrawOffset.y<<21)>>21);
1725
1726  PSXDisplay.CumulOffset.x =                            // new OGL prim offsets\r
1727   PSXDisplay.DrawOffset.x - PSXDisplay.GDrawOffset.x + PreviousPSXDisplay.Range.x0;
1728  PSXDisplay.CumulOffset.y = 
1729   PSXDisplay.DrawOffset.y - PSXDisplay.GDrawOffset.y + PreviousPSXDisplay.Range.y0;
1730 }
1731
1732 ////////////////////////////////////////////////////////////////////////
1733 // cmd: load image to vram
1734 ////////////////////////////////////////////////////////////////////////
1735
1736 void primLoadImage(unsigned char * baseAddr)
1737 {
1738  unsigned short *sgpuData = ((unsigned short *) baseAddr);
1739
1740  VRAMWrite.x      = sgpuData[2]&0x03ff;
1741  VRAMWrite.y      = sgpuData[3]&iGPUHeightMask;
1742  VRAMWrite.Width  = sgpuData[4];
1743  VRAMWrite.Height = sgpuData[5];
1744
1745  iDataWriteMode = DR_VRAMTRANSFER;
1746  VRAMWrite.ImagePtr = psxVuw + (VRAMWrite.y<<10) + VRAMWrite.x;
1747  VRAMWrite.RowsRemaining = VRAMWrite.Width;
1748  VRAMWrite.ColsRemaining = VRAMWrite.Height;
1749
1750  bNeedWriteUpload=TRUE;
1751 }
1752
1753 ////////////////////////////////////////////////////////////////////////
1754
1755 void PrepareRGB24Upload(void)
1756 {
1757  VRAMWrite.x=(VRAMWrite.x*2)/3;
1758  VRAMWrite.Width=(VRAMWrite.Width*2)/3;
1759
1760  if(!PSXDisplay.InterlacedTest && // NEW
1761     CheckAgainstScreen(VRAMWrite.x, VRAMWrite.y, VRAMWrite.Width, VRAMWrite.Height))
1762   {
1763    xrUploadArea.x0-=PreviousPSXDisplay.DisplayPosition.x;
1764    xrUploadArea.x1-=PreviousPSXDisplay.DisplayPosition.x;
1765    xrUploadArea.y0-=PreviousPSXDisplay.DisplayPosition.y;
1766    xrUploadArea.y1-=PreviousPSXDisplay.DisplayPosition.y;
1767   }  
1768  else
1769  if(CheckAgainstFrontScreen(VRAMWrite.x, VRAMWrite.y, VRAMWrite.Width, VRAMWrite.Height))
1770   {
1771    xrUploadArea.x0-=PSXDisplay.DisplayPosition.x;
1772    xrUploadArea.x1-=PSXDisplay.DisplayPosition.x;
1773    xrUploadArea.y0-=PSXDisplay.DisplayPosition.y;
1774    xrUploadArea.y1-=PSXDisplay.DisplayPosition.y;
1775   }  
1776  else return;
1777
1778  if(bRenderFrontBuffer) 
1779   {
1780    updateFrontDisplay();
1781   }
1782
1783  if(bNeedRGB24Update==FALSE)
1784   {
1785    xrUploadAreaRGB24=xrUploadArea;
1786    bNeedRGB24Update=TRUE;
1787   }
1788  else
1789   {
1790    xrUploadAreaRGB24.x0=min(xrUploadAreaRGB24.x0,xrUploadArea.x0);
1791    xrUploadAreaRGB24.x1=max(xrUploadAreaRGB24.x1,xrUploadArea.x1);
1792    xrUploadAreaRGB24.y0=min(xrUploadAreaRGB24.y0,xrUploadArea.y0);
1793    xrUploadAreaRGB24.y1=max(xrUploadAreaRGB24.y1,xrUploadArea.y1);
1794   }
1795 }
1796
1797 ////////////////////////////////////////////////////////////////////////
1798
1799 void CheckWriteUpdate()
1800 {
1801  int iX=0,iY=0;
1802
1803  if(VRAMWrite.Width)   iX=1;
1804  if(VRAMWrite.Height)  iY=1;
1805
1806  InvalidateTextureArea(VRAMWrite.x, VRAMWrite.y, VRAMWrite.Width-iX, VRAMWrite.Height-iY);
1807
1808  if(PSXDisplay.Interlaced && !iOffscreenDrawing) return;
1809
1810  if(PSXDisplay.RGB24) {PrepareRGB24Upload();return;}
1811
1812  if(!PSXDisplay.InterlacedTest &&
1813     CheckAgainstScreen(VRAMWrite.x, VRAMWrite.y, VRAMWrite.Width, VRAMWrite.Height)) 
1814   {
1815    if(dwActFixes&0x800) return;
1816
1817    if(bRenderFrontBuffer) 
1818     {
1819      updateFrontDisplay();
1820     }
1821
1822    UploadScreen(FALSE);
1823
1824    bNeedUploadTest=TRUE;
1825   }
1826  else 
1827  if(iOffscreenDrawing)
1828   {
1829    if (CheckAgainstFrontScreen(VRAMWrite.x, VRAMWrite.y, VRAMWrite.Width, VRAMWrite.Height)) 
1830     {
1831      if(PSXDisplay.InterlacedTest)
1832       {
1833        if(PreviousPSXDisplay.InterlacedNew) 
1834         {
1835          PreviousPSXDisplay.InterlacedNew=FALSE;
1836          bNeedInterlaceUpdate=TRUE;
1837          xrUploadAreaIL.x0=PSXDisplay.DisplayPosition.x;
1838          xrUploadAreaIL.y0=PSXDisplay.DisplayPosition.y;
1839          xrUploadAreaIL.x1=PSXDisplay.DisplayPosition.x+PSXDisplay.DisplayModeNew.x;
1840          xrUploadAreaIL.y1=PSXDisplay.DisplayPosition.y+PSXDisplay.DisplayModeNew.y;
1841          if(xrUploadAreaIL.x1>1023) xrUploadAreaIL.x1=1023;
1842          if(xrUploadAreaIL.y1>511)  xrUploadAreaIL.y1=511;
1843         }
1844
1845        if(bNeedInterlaceUpdate==FALSE)
1846         {
1847          xrUploadAreaIL=xrUploadArea;
1848          bNeedInterlaceUpdate=TRUE;
1849         }
1850        else
1851         {
1852          xrUploadAreaIL.x0=min(xrUploadAreaIL.x0,xrUploadArea.x0);
1853          xrUploadAreaIL.x1=max(xrUploadAreaIL.x1,xrUploadArea.x1);
1854          xrUploadAreaIL.y0=min(xrUploadAreaIL.y0,xrUploadArea.y0);
1855          xrUploadAreaIL.y1=max(xrUploadAreaIL.y1,xrUploadArea.y1);
1856         }
1857        return;
1858       }
1859 \r
1860      if(!bNeedUploadAfter)
1861       {
1862        bNeedUploadAfter = TRUE;
1863        xrUploadArea.x0=VRAMWrite.x;
1864        xrUploadArea.x1=VRAMWrite.x+VRAMWrite.Width;
1865        xrUploadArea.y0=VRAMWrite.y;
1866        xrUploadArea.y1=VRAMWrite.y+VRAMWrite.Height;
1867       }
1868      else
1869       {
1870        xrUploadArea.x0=min(xrUploadArea.x0,VRAMWrite.x);
1871        xrUploadArea.x1=max(xrUploadArea.x1,VRAMWrite.x+VRAMWrite.Width);
1872        xrUploadArea.y0=min(xrUploadArea.y0,VRAMWrite.y);
1873        xrUploadArea.y1=max(xrUploadArea.y1,VRAMWrite.y+VRAMWrite.Height);
1874       }
1875 \r
1876      if(dwActFixes&0x8000)\r
1877       {\r
1878        if((xrUploadArea.x1-xrUploadArea.x0)>=(PSXDisplay.DisplayMode.x-32) &&\r
1879           (xrUploadArea.y1-xrUploadArea.y0)>=(PSXDisplay.DisplayMode.y-32))\r
1880         {\r
1881          UploadScreen(-1);\r
1882          updateFrontDisplay();\r
1883         }\r
1884       }\r
1885     }
1886   }
1887 }
1888
1889 ////////////////////////////////////////////////////////////////////////
1890 // cmd: vram -> psx mem
1891 ////////////////////////////////////////////////////////////////////////
1892
1893 void primStoreImage(unsigned char * baseAddr)
1894 {
1895  unsigned short *sgpuData = ((unsigned short *) baseAddr);
1896
1897  VRAMRead.x      = sgpuData[2]&0x03ff;
1898  VRAMRead.y      = sgpuData[3]&iGPUHeightMask;
1899  VRAMRead.Width  = sgpuData[4];
1900  VRAMRead.Height = sgpuData[5];
1901
1902  VRAMRead.ImagePtr = psxVuw + (VRAMRead.y<<10) + VRAMRead.x;
1903  VRAMRead.RowsRemaining = VRAMRead.Width;
1904  VRAMRead.ColsRemaining = VRAMRead.Height;
1905 \r
1906  iDataReadMode = DR_VRAMTRANSFER;
1907
1908  STATUSREG |= GPUSTATUS_READYFORVRAM;
1909 }
1910
1911 ////////////////////////////////////////////////////////////////////////
1912 // cmd: blkfill - NO primitive! Doesn't care about draw areas...
1913 ////////////////////////////////////////////////////////////////////////
1914
1915 void primBlkFill(unsigned char * baseAddr)
1916 {
1917  uint32_t *gpuData = ((uint32_t *) baseAddr);
1918  short *sgpuData = ((short *) baseAddr);
1919
1920  iDrawnSomething = 1;
1921
1922  sprtX = sgpuData[2];
1923  sprtY = sgpuData[3];
1924  sprtW = sgpuData[4] & 0x3ff;
1925  sprtH = sgpuData[5] & iGPUHeightMask;\r
1926 \r
1927  sprtW = (sprtW + 15) & ~15;\r
1928
1929  // Increase H & W if they are one short of full values, because they never can be full values
1930  if (sprtH == iGPUHeightMask)  sprtH=iGPUHeight;
1931  if (sprtW == 1023)            sprtW=1024; 
1932         
1933  // x and y of start
1934  ly0 = ly1 = sprtY;
1935  ly2 = ly3 = (sprtY+sprtH);
1936  lx0 = lx3 = sprtX;
1937  lx1 = lx2 = (sprtX+sprtW);
1938
1939  offsetBlk();
1940
1941  if(ClipVertexListScreen())                           \r
1942   {
1943    PSXDisplay_t * pd;
1944    if(PSXDisplay.InterlacedTest) pd=&PSXDisplay;
1945    else                          pd=&PreviousPSXDisplay;
1946
1947    if ((lx0 <= pd->DisplayPosition.x+16) &&
1948        (ly0 <= pd->DisplayPosition.y+16) &&
1949        (lx2 >= pd->DisplayEnd.x-16) &&
1950        (ly2 >= pd->DisplayEnd.y-16))
1951     {
1952      GLclampf g,b,r;
1953      g=((GLclampf)GREEN(gpuData[0]))/255.0f;
1954      b=((GLclampf)BLUE(gpuData[0]))/255.0f;
1955      r=((GLclampf)RED(gpuData[0]))/255.0f;
1956      
1957      glDisable(GL_SCISSOR_TEST);                       
1958      glClearColor(r,g,b,1.0f);
1959      glClear(uiBufferBits); 
1960      gl_z=0.0f;
1961
1962      if(gpuData[0]!=0x02000000 &&
1963         (ly0>pd->DisplayPosition.y ||
1964          ly2<pd->DisplayEnd.y))
1965       {
1966        bDrawTextured     = FALSE;
1967        bDrawSmoothShaded = FALSE;
1968        SetRenderState((uint32_t)0x01000000);
1969        SetRenderMode((uint32_t)0x01000000, FALSE);
1970        vertex[0].c.lcol=0xff000000;
1971        SETCOL(vertex[0]); 
1972        if(ly0>pd->DisplayPosition.y)
1973         {
1974          vertex[0].x=0;vertex[0].y=0;
1975          vertex[1].x=pd->DisplayEnd.x-pd->DisplayPosition.x;vertex[1].y=0;
1976          vertex[2].x=vertex[1].x;vertex[2].y=ly0-pd->DisplayPosition.y;
1977          vertex[3].x=0;vertex[3].y=vertex[2].y;
1978          PRIMdrawQuad(&vertex[0], &vertex[1], &vertex[2], &vertex[3]);
1979         }
1980        if(ly2<pd->DisplayEnd.y)
1981         {
1982          vertex[0].x=0;vertex[0].y=(pd->DisplayEnd.y-pd->DisplayPosition.y)-(pd->DisplayEnd.y-ly2);\r
1983          vertex[1].x=pd->DisplayEnd.x-pd->DisplayPosition.x;vertex[1].y=vertex[0].y;
1984          vertex[2].x=vertex[1].x;vertex[2].y=pd->DisplayEnd.y;
1985          vertex[3].x=0;vertex[3].y=vertex[2].y;
1986          PRIMdrawQuad(&vertex[0], &vertex[1], &vertex[2], &vertex[3]);
1987         }
1988       }
1989
1990      glEnable(GL_SCISSOR_TEST);                       
1991     }
1992    else
1993     {
1994      bDrawTextured     = FALSE;
1995      bDrawSmoothShaded = FALSE;
1996      SetRenderState((uint32_t)0x01000000);
1997      SetRenderMode((uint32_t)0x01000000, FALSE);
1998      vertex[0].c.lcol=gpuData[0]|0xff000000;
1999      SETCOL(vertex[0]); 
2000      glDisable(GL_SCISSOR_TEST);                       
2001      PRIMdrawQuad(&vertex[0], &vertex[1], &vertex[2], &vertex[3]);
2002      glEnable(GL_SCISSOR_TEST);                       
2003     }
2004   }
2005
2006  //mmm... will clean all stuff, also if not all _should_ be cleaned...
2007  //if (IsInsideNextScreen(sprtX, sprtY, sprtW, sprtH))
2008  // try this:
2009  if (IsCompleteInsideNextScreen(sprtX, sprtY, sprtW, sprtH))
2010   {
2011    lClearOnSwapColor = COLOR(gpuData[0]);
2012    lClearOnSwap = 1;
2013   }
2014
2015  if(iOffscreenDrawing)
2016   {
2017    ClampToPSXScreenOffset( &sprtX, &sprtY, &sprtW, &sprtH);
2018    if ((sprtW == 0) || (sprtH == 0)) return;
2019    InvalidateTextureArea(sprtX, sprtY, sprtW-1, sprtH-1);   
2020
2021    sprtW+=sprtX;
2022    sprtH+=sprtY;
2023
2024    FillSoftwareArea(sprtX, sprtY, sprtW, sprtH, BGR24to16(gpuData[0]));
2025   }
2026 }
2027   
2028 ////////////////////////////////////////////////////////////////////////
2029 // cmd: move image vram -> vram
2030 ////////////////////////////////////////////////////////////////////////
2031
2032 void MoveImageWrapped(short imageX0,short imageY0,
2033                       short imageX1,short imageY1,
2034                       short imageSX,short imageSY)
2035 {
2036  int i,j,imageXE,imageYE;
2037
2038  if(iFrameReadType&2)
2039   {
2040    imageXE=imageX0+imageSX;
2041    imageYE=imageY0+imageSY;
2042
2043    if(imageYE>iGPUHeight && imageXE>1024) 
2044     {
2045      CheckVRamRead(0,0,
2046                    (imageXE&0x3ff),
2047                    (imageY0&iGPUHeightMask),
2048                    FALSE);
2049     }
2050
2051    if(imageXE>1024) 
2052     {
2053      CheckVRamRead(0,imageY0, 
2054                    (imageXE&0x3ff),
2055                    (imageYE>iGPUHeight)?iGPUHeight:imageYE,
2056                    FALSE);
2057     }
2058
2059    if(imageYE>iGPUHeight) 
2060     {
2061      CheckVRamRead(imageX0,0, 
2062                    (imageXE>1024)?1024:imageXE,
2063                    imageYE&iGPUHeightMask,
2064                    FALSE);
2065     }
2066
2067    CheckVRamRead(imageX0,imageY0, 
2068                  (imageXE>1024)?1024:imageXE,
2069                  (imageYE>iGPUHeight)?iGPUHeight:imageYE,
2070                  FALSE);
2071   }
2072
2073  for(j=0;j<imageSY;j++)
2074   for(i=0;i<imageSX;i++)
2075    psxVuw [(1024*((imageY1+j)&iGPUHeightMask))+((imageX1+i)&0x3ff)]=
2076     psxVuw[(1024*((imageY0+j)&iGPUHeightMask))+((imageX0+i)&0x3ff)];
2077
2078  if(!PSXDisplay.RGB24)
2079   {
2080    imageXE=imageX1+imageSX;
2081    imageYE=imageY1+imageSY;
2082
2083    if(imageYE>iGPUHeight && imageXE>1024) 
2084     {
2085      InvalidateTextureArea(0,0,
2086                            (imageXE&0x3ff)-1,
2087                            (imageYE&iGPUHeightMask)-1);
2088     }
2089
2090    if(imageXE>1024) 
2091     {
2092      InvalidateTextureArea(0,imageY1,
2093                            (imageXE&0x3ff)-1,
2094                            ((imageYE>iGPUHeight)?iGPUHeight:imageYE)-imageY1-1);
2095     }
2096
2097    if(imageYE>iGPUHeight) 
2098     {
2099      InvalidateTextureArea(imageX1,0,
2100                            ((imageXE>1024)?1024:imageXE)-imageX1-1,
2101                            (imageYE&iGPUHeightMask)-1);
2102     }
2103
2104    InvalidateTextureArea(imageX1,imageY1,
2105                          ((imageXE>1024)?1024:imageXE)-imageX1-1,
2106                          ((imageYE>iGPUHeight)?iGPUHeight:imageYE)-imageY1-1);
2107   }
2108 }
2109
2110 ////////////////////////////////////////////////////////////////////////
2111
2112 void primMoveImage(unsigned char * baseAddr)
2113 {
2114  short *sgpuData = ((short *) baseAddr);
2115  short imageY0,imageX0,imageY1,imageX1,imageSX,imageSY,i,j;
2116
2117  imageX0 = sgpuData[2]&0x03ff;
2118  imageY0 = sgpuData[3]&iGPUHeightMask;
2119  imageX1 = sgpuData[4]&0x03ff;
2120  imageY1 = sgpuData[5]&iGPUHeightMask;
2121  imageSX = sgpuData[6];
2122  imageSY = sgpuData[7];
2123
2124  if((imageX0 == imageX1) && (imageY0 == imageY1)) return;  
2125  if(imageSX<=0) return;
2126  if(imageSY<=0) return;
2127 \r
2128  if(iGPUHeight==1024 && sgpuData[7]>1024) return;\r
2129
2130  if((imageY0+imageSY)>iGPUHeight ||
2131     (imageX0+imageSX)>1024       ||
2132     (imageY1+imageSY)>iGPUHeight ||
2133     (imageX1+imageSX)>1024)
2134   {
2135    MoveImageWrapped(imageX0,imageY0,imageX1,imageY1,imageSX,imageSY);
2136    if((imageY0+imageSY)>iGPUHeight) imageSY=iGPUHeight-imageY0;
2137    if((imageX0+imageSX)>1024)       imageSX=1024-imageX0;
2138    if((imageY1+imageSY)>iGPUHeight) imageSY=iGPUHeight-imageY1;
2139    if((imageX1+imageSX)>1024)       imageSX=1024-imageX1;
2140   }
2141
2142  if(iFrameReadType&2)
2143   CheckVRamRead(imageX0,imageY0, 
2144                 imageX0+imageSX,
2145                 imageY0+imageSY,
2146                 FALSE);
2147
2148  if(imageSX&1)
2149   {
2150    unsigned short *SRCPtr, *DSTPtr;
2151    unsigned short LineOffset;
2152
2153    SRCPtr = psxVuw + (1024*imageY0) + imageX0;
2154    DSTPtr = psxVuw + (1024*imageY1) + imageX1;
2155
2156    LineOffset = 1024 - imageSX;
2157
2158    for(j=0;j<imageSY;j++)
2159     {
2160      for(i=0;i<imageSX;i++) *DSTPtr++ = *SRCPtr++;
2161      SRCPtr += LineOffset;
2162      DSTPtr += LineOffset;
2163     }
2164   }
2165  else
2166   {
2167    uint32_t *SRCPtr, *DSTPtr;
2168    unsigned short LineOffset;
2169    int dx=imageSX>>1;
2170
2171    SRCPtr = (uint32_t *)(psxVuw + (1024*imageY0) + imageX0);
2172    DSTPtr = (uint32_t *)(psxVuw + (1024*imageY1) + imageX1);
2173
2174    LineOffset = 512 - dx;
2175
2176    for(j=0;j<imageSY;j++)
2177     {
2178      for(i=0;i<dx;i++) *DSTPtr++ = *SRCPtr++;
2179      SRCPtr += LineOffset;
2180      DSTPtr += LineOffset;
2181     }
2182   }
2183
2184  if (!PSXDisplay.RGB24)
2185   {
2186    InvalidateTextureArea(imageX1,imageY1,imageSX-1,imageSY-1);
2187
2188    if (CheckAgainstScreen(imageX1,imageY1,imageSX,imageSY)) 
2189     {
2190      if(imageX1>=PreviousPSXDisplay.DisplayPosition.x &&
2191         imageX1<PreviousPSXDisplay.DisplayEnd.x &&
2192         imageY1>=PreviousPSXDisplay.DisplayPosition.y &&
2193         imageY1<PreviousPSXDisplay.DisplayEnd.y)
2194       {
2195        imageX1 += imageSX;
2196        imageY1 += imageSY;
2197
2198        if(imageX1>=PreviousPSXDisplay.DisplayPosition.x &&
2199           imageX1<=PreviousPSXDisplay.DisplayEnd.x &&
2200           imageY1>=PreviousPSXDisplay.DisplayPosition.y &&
2201           imageY1<=PreviousPSXDisplay.DisplayEnd.y)
2202         {
2203          if(!(
2204                imageX0>=PSXDisplay.DisplayPosition.x &&
2205                imageX0<PSXDisplay.DisplayEnd.x &&
2206                imageY0>=PSXDisplay.DisplayPosition.y &&
2207                imageY0<PSXDisplay.DisplayEnd.y 
2208               ))
2209           {
2210            if(bRenderFrontBuffer) 
2211             {
2212              updateFrontDisplay();
2213             }
2214  
2215            UploadScreen(FALSE);
2216           }
2217          else bFakeFrontBuffer=TRUE;
2218         }
2219       }
2220
2221      bNeedUploadTest=TRUE;
2222     }
2223    else
2224    if(iOffscreenDrawing)
2225     {
2226      if (CheckAgainstFrontScreen(imageX1,imageY1,imageSX,imageSY)) 
2227       {
2228        if(!PSXDisplay.InterlacedTest &&
2229 //          !bFullVRam &&
2230           ((
2231             imageX0>=PreviousPSXDisplay.DisplayPosition.x &&
2232             imageX0<PreviousPSXDisplay.DisplayEnd.x &&
2233             imageY0>=PreviousPSXDisplay.DisplayPosition.y &&
2234             imageY0<PreviousPSXDisplay.DisplayEnd.y
2235            ) ||
2236            (
2237             imageX0>=PSXDisplay.DisplayPosition.x &&
2238             imageX0<PSXDisplay.DisplayEnd.x &&
2239             imageY0>=PSXDisplay.DisplayPosition.y &&
2240             imageY0<PSXDisplay.DisplayEnd.y
2241            )))
2242         return;
2243
2244        bNeedUploadTest=TRUE;
2245
2246        if(!bNeedUploadAfter)
2247         {
2248          bNeedUploadAfter = TRUE;
2249          xrUploadArea.x0=imageX0;
2250          xrUploadArea.x1=imageX0+imageSX;
2251          xrUploadArea.y0=imageY0;
2252          xrUploadArea.y1=imageY0+imageSY;
2253         }
2254        else
2255         {
2256          xrUploadArea.x0=min(xrUploadArea.x0,imageX0);
2257          xrUploadArea.x1=max(xrUploadArea.x1,imageX0+imageSX);
2258          xrUploadArea.y0=min(xrUploadArea.y0,imageY0);
2259          xrUploadArea.y1=max(xrUploadArea.y1,imageY0+imageSY);
2260         }
2261       }
2262     }
2263   }
2264 }
2265
2266
2267 ////////////////////////////////////////////////////////////////////////
2268 // cmd: draw free-size Tile 
2269 ////////////////////////////////////////////////////////////////////////
2270
2271 void primTileS(unsigned char * baseAddr)
2272 {
2273  uint32_t *gpuData = ((uint32_t *)baseAddr);
2274  short *sgpuData = ((short *) baseAddr);
2275
2276  sprtX = sgpuData[2];
2277  sprtY = sgpuData[3];
2278  sprtW = sgpuData[4] & 0x3ff;
2279  sprtH = sgpuData[5] & iGPUHeightMask;
2280
2281  // x and y of start
2282
2283  lx0 = sprtX;
2284  ly0 = sprtY;
2285
2286  offsetST();
2287
2288  if((dwActFixes&1) &&                                  // FF7 special game gix (battle cursor)\r
2289     sprtX==0 && sprtY==0 && sprtW==24 && sprtH==16) \r
2290   return;
2291
2292  bDrawTextured = FALSE;
2293  bDrawSmoothShaded = FALSE;
2294
2295  SetRenderState(gpuData[0]);
2296
2297  if(iOffscreenDrawing)
2298   {
2299    if(IsPrimCompleteInsideNextScreen(lx0,ly0,lx2,ly2) ||
2300       (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
2301     {
2302      lClearOnSwapColor = COLOR(gpuData[0]);
2303      lClearOnSwap = 1;
2304     }
2305
2306    offsetPSX4();
2307    if(bDrawOffscreen4())
2308     {\r
2309      if(!(iTileCheat && sprtH==32 && gpuData[0]==0x60ffffff)) // special cheat for certain ZiNc games\r
2310       {
2311        InvalidateTextureAreaEx();   
2312        FillSoftwareAreaTrans(lx0,ly0,lx2,ly2,
2313                              BGR24to16(gpuData[0]));  \r
2314       }
2315     }
2316   }
2317
2318  SetRenderMode(gpuData[0], FALSE);
2319  SetZMask4NT();
2320
2321  if(bIgnoreNextTile) {bIgnoreNextTile=FALSE;return;}
2322
2323  vertex[0].c.lcol=gpuData[0];
2324  vertex[0].c.col[3]=ubGloColAlpha;
2325  SETCOL(vertex[0]); 
2326  
2327  PRIMdrawQuad(&vertex[0], &vertex[1], &vertex[2], &vertex[3]);
2328
2329  iDrawnSomething=1;
2330 }
2331
2332 ////////////////////////////////////////////////////////////////////////
2333 // cmd: draw 1 dot Tile (point)
2334 ////////////////////////////////////////////////////////////////////////
2335
2336 void primTile1(unsigned char * baseAddr)
2337 {
2338  uint32_t *gpuData = ((uint32_t *)baseAddr);
2339  short *sgpuData = ((short *)baseAddr);
2340
2341  sprtX = sgpuData[2];
2342  sprtY = sgpuData[3];
2343  sprtW = 1;
2344  sprtH = 1;
2345
2346  lx0 = sprtX;
2347  ly0 = sprtY;
2348
2349  offsetST();
2350
2351  bDrawTextured = FALSE;
2352  bDrawSmoothShaded = FALSE;
2353
2354  SetRenderState(gpuData[0]);
2355
2356  if(iOffscreenDrawing)
2357   {
2358    offsetPSX4();
2359
2360    if(bDrawOffscreen4())
2361     {
2362      InvalidateTextureAreaEx();   
2363      FillSoftwareAreaTrans(lx0,ly0,lx2,ly2,
2364                            BGR24to16(gpuData[0]));          
2365     }
2366   }
2367
2368  SetRenderMode(gpuData[0], FALSE);
2369  SetZMask4NT();
2370
2371  vertex[0].c.lcol=gpuData[0];vertex[0].c.col[3]=ubGloColAlpha;
2372  SETCOL(vertex[0]); 
2373
2374  PRIMdrawQuad(&vertex[0], &vertex[1], &vertex[2], &vertex[3]);
2375
2376  iDrawnSomething=1;
2377 }
2378
2379 ////////////////////////////////////////////////////////////////////////
2380 // cmd: draw 8 dot Tile (small rect)
2381 ////////////////////////////////////////////////////////////////////////
2382
2383 void primTile8(unsigned char * baseAddr)
2384 {
2385  uint32_t *gpuData = ((uint32_t *)baseAddr);
2386  short *sgpuData = ((short *) baseAddr);
2387
2388  sprtX = sgpuData[2];
2389  sprtY = sgpuData[3];
2390  sprtW = 8;
2391  sprtH = 8;
2392
2393  lx0 = sprtX;
2394  ly0 = sprtY;
2395
2396  offsetST();
2397
2398  bDrawTextured = FALSE;
2399  bDrawSmoothShaded = FALSE;
2400  SetRenderState(gpuData[0]);
2401
2402  if(iOffscreenDrawing)
2403   {
2404    offsetPSX4();
2405
2406    if(bDrawOffscreen4())
2407     {
2408      InvalidateTextureAreaEx();   
2409      FillSoftwareAreaTrans(lx0,ly0,lx2,ly2,
2410                            BGR24to16(gpuData[0]));    
2411     }
2412   }
2413
2414  SetRenderMode(gpuData[0], FALSE);
2415  SetZMask4NT();
2416
2417  vertex[0].c.lcol=gpuData[0];
2418  vertex[0].c.col[3]=ubGloColAlpha;
2419  SETCOL(vertex[0]); 
2420
2421  PRIMdrawQuad(&vertex[0], &vertex[1], &vertex[2], &vertex[3]);
2422
2423  iDrawnSomething=1;
2424 }
2425
2426 ////////////////////////////////////////////////////////////////////////
2427 // cmd: draw 16 dot Tile (medium rect)
2428 ////////////////////////////////////////////////////////////////////////
2429
2430 void primTile16(unsigned char * baseAddr)
2431 {
2432  uint32_t *gpuData = ((uint32_t *)baseAddr);
2433  short *sgpuData = ((short *)baseAddr);
2434
2435  sprtX = sgpuData[2];
2436  sprtY = sgpuData[3];
2437  sprtW = 16;
2438  sprtH = 16;
2439  // x and y of start
2440  lx0 = sprtX;
2441  ly0 = sprtY;
2442
2443  offsetST();
2444
2445  bDrawTextured = FALSE;
2446  bDrawSmoothShaded = FALSE;
2447  SetRenderState(gpuData[0]);
2448
2449  if(iOffscreenDrawing)
2450   {
2451    offsetPSX4();
2452
2453    if(bDrawOffscreen4())
2454     {
2455      InvalidateTextureAreaEx();   
2456      FillSoftwareAreaTrans(lx0,ly0,lx2,ly2,
2457                            BGR24to16(gpuData[0]));    
2458     }
2459   }
2460
2461  SetRenderMode(gpuData[0], FALSE);
2462  SetZMask4NT();
2463
2464  vertex[0].c.lcol=gpuData[0];
2465  vertex[0].c.col[3]=ubGloColAlpha;
2466  SETCOL(vertex[0]); 
2467
2468  PRIMdrawQuad(&vertex[0], &vertex[1], &vertex[2], &vertex[3]);
2469
2470  iDrawnSomething=1;
2471 }
2472
2473 ////////////////////////////////////////////////////////////////////////
2474 // helper: filter effect by multipass rendering
2475 ////////////////////////////////////////////////////////////////////////
2476
2477 void DrawMultiBlur(void)
2478 {
2479  int lABR,lDST;
2480  float fx,fy;
2481
2482  lABR=GlobalTextABR;
2483  lDST=DrawSemiTrans;
2484
2485  fx=(float)PSXDisplay.DisplayMode.x/(float)(iResX); 
2486  fy=(float)PSXDisplay.DisplayMode.y/(float)(iResY);
2487
2488  vertex[0].x+=fx;vertex[1].x+=fx;
2489  vertex[2].x+=fx;vertex[3].x+=fx;
2490
2491  GlobalTextABR=0;
2492  DrawSemiTrans=1;
2493  SetSemiTrans();
2494
2495  PRIMdrawTexturedQuad(&vertex[0], &vertex[1], &vertex[2], &vertex[3]);
2496
2497  vertex[0].y+=fy;vertex[1].y+=fy;
2498  vertex[2].y+=fy;vertex[3].y+=fy;
2499  PRIMdrawTexturedQuad(&vertex[0], &vertex[1], &vertex[2], &vertex[3]);
2500
2501  if(bDrawMultiPass) {obm1=obm2=GL_SRC_ALPHA;}
2502
2503  GlobalTextABR=lABR;
2504  DrawSemiTrans=lDST;
2505 }
2506
2507 ////////////////////////////////////////////////////////////////////////
2508
2509 #define   POFF 0.375f
2510
2511 void DrawMultiFilterSprite(void)
2512 {
2513  int lABR,lDST;
2514
2515  if(bUseMultiPass || DrawSemiTrans || ubOpaqueDraw) 
2516   {
2517    PRIMdrawTexturedQuad(&vertex[0], &vertex[1], &vertex[2], &vertex[3]);
2518    return;
2519   }
2520
2521  lABR=GlobalTextABR;
2522  lDST=DrawSemiTrans;
2523  vertex[0].c.col[3]=ubGloAlpha/2;                      // -> set color with\r
2524  SETCOL(vertex[0]);                                    //    texture alpha\r
2525  PRIMdrawTexturedQuad(&vertex[0], &vertex[1], &vertex[2], &vertex[3]);
2526  vertex[0].x+=POFF;vertex[1].x+=POFF;
2527  vertex[2].x+=POFF;vertex[3].x+=POFF;
2528  vertex[0].y+=POFF;vertex[1].y+=POFF;
2529  vertex[2].y+=POFF;vertex[3].y+=POFF;
2530  GlobalTextABR=0;
2531  DrawSemiTrans=1;
2532  SetSemiTrans();
2533  PRIMdrawTexturedQuad(&vertex[0], &vertex[1], &vertex[2], &vertex[3]);
2534  GlobalTextABR=lABR;
2535  DrawSemiTrans=lDST;
2536 }
2537
2538 ////////////////////////////////////////////////////////////////////////
2539 // cmd: small sprite (textured rect)
2540 ////////////////////////////////////////////////////////////////////////
2541
2542 void primSprt8(unsigned char * baseAddr)
2543 {
2544  uint32_t *gpuData = ((uint32_t *) baseAddr);
2545  short *sgpuData = ((short *) baseAddr);
2546  short s;
2547
2548  iSpriteTex=1;
2549
2550  sprtX = sgpuData[2];
2551  sprtY = sgpuData[3];
2552  sprtW = 8;
2553  sprtH = 8;
2554
2555  lx0 = sprtX;
2556  ly0 = sprtY;
2557
2558  offsetST();
2559
2560  // do texture stuff
2561  gl_ux[0]=gl_ux[3]=baseAddr[8];//gpuData[2]&0xff;\r
2562 \r
2563  if(usMirror & 0x1000) \r
2564   {\r
2565    s=gl_ux[0];\r
2566    s-=sprtW-1;\r
2567    if(s<0) {s=0;}\r
2568    gl_ux[0]=gl_ux[3]=s;\r
2569   }\r
2570
2571  sSprite_ux2=s=gl_ux[0]+sprtW; 
2572  if(s)     s--;
2573  if(s>255) s=255;
2574  gl_ux[1]=gl_ux[2]=s;
2575  // Y coords
2576  gl_vy[0]=gl_vy[1]=baseAddr[9];//(gpuData[2]>>8)&0xff;\r
2577 \r
2578  if(usMirror & 0x2000) \r
2579   {\r
2580    s=gl_vy[0];\r
2581    s-=sprtH-1;\r
2582    if(s<0) {s=0;}\r
2583    gl_vy[0]=gl_vy[1]=s;\r
2584   }\r
2585
2586  sSprite_vy2=s=gl_vy[0]+sprtH; 
2587  if(s)     s--;
2588  if(s>255) s=255;
2589  gl_vy[2]=gl_vy[3]=s;
2590
2591  ulClutID=(gpuData[2]>>16);
2592
2593  bDrawTextured = TRUE;
2594  bDrawSmoothShaded = FALSE;
2595  SetRenderState(gpuData[0]);
2596
2597  if(iOffscreenDrawing)      
2598   {
2599    offsetPSX4();
2600
2601    if(bDrawOffscreen4())
2602     {
2603      InvalidateTextureAreaEx();   
2604      SetRenderColor(gpuData[0]);
2605      lx0-=PSXDisplay.DrawOffset.x;
2606      ly0-=PSXDisplay.DrawOffset.y;
2607 \r
2608      if(bUsingTWin) DrawSoftwareSpriteTWin(baseAddr,8,8);
2609      else
2610      if(usMirror)   DrawSoftwareSpriteMirror(baseAddr,8,8);
2611      else
2612      DrawSoftwareSprite(baseAddr,8,8,baseAddr[8],baseAddr[9]);\r
2613     }
2614   }
2615
2616  SetRenderMode(gpuData[0], TRUE);
2617  SetZMask4SP();
2618
2619  sSprite_ux2=gl_ux[0]+sprtW;
2620  sSprite_vy2=gl_vy[0]+sprtH;
2621
2622  assignTextureSprite();
2623
2624  if(iFilterType>4) 
2625   DrawMultiFilterSprite();
2626  else
2627   PRIMdrawTexturedQuad(&vertex[0], &vertex[1], &vertex[2], &vertex[3]);
2628
2629  if(bDrawMultiPass)
2630   {
2631    SetSemiTransMulti(1);
2632    PRIMdrawTexturedQuad(&vertex[0], &vertex[1], &vertex[2], &vertex[3]);
2633   }
2634
2635  if(ubOpaqueDraw)
2636   {
2637    SetZMask4O();
2638    if(bUseMultiPass) SetOpaqueColor(gpuData[0]);
2639    DEFOPAQUEON\r
2640 \r
2641    if(bSmallAlpha && iFilterType<=2)\r
2642     {\r
2643      glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);\r
2644      glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);\r
2645      PRIMdrawTexturedQuad(&vertex[0], &vertex[1], &vertex[2], &vertex[3]);\r
2646      glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);\r
2647      glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);\r
2648      SetZMask4O();\r
2649     }\r
2650
2651    PRIMdrawTexturedQuad(&vertex[0], &vertex[1], &vertex[2], &vertex[3]);
2652    DEFOPAQUEOFF
2653   }
2654
2655  iSpriteTex=0;
2656  iDrawnSomething=1;
2657 }
2658
2659 ////////////////////////////////////////////////////////////////////////
2660 // cmd: medium sprite (textured rect)
2661 ////////////////////////////////////////////////////////////////////////
2662
2663 void primSprt16(unsigned char * baseAddr)
2664 {
2665  uint32_t *gpuData = ((uint32_t *) baseAddr);
2666  short *sgpuData = ((short *) baseAddr);
2667  short s;
2668
2669  iSpriteTex=1;
2670
2671  sprtX = sgpuData[2];
2672  sprtY = sgpuData[3];
2673  sprtW = 16;
2674  sprtH = 16;
2675
2676  lx0 = sprtX;
2677  ly0 = sprtY;
2678
2679  offsetST();
2680
2681  // do texture stuff
2682  gl_ux[0]=gl_ux[3]=baseAddr[8];//gpuData[2]&0xff;\r
2683 \r
2684  if(usMirror & 0x1000) \r
2685   {\r
2686    s=gl_ux[0];\r
2687    s-=sprtW-1;\r
2688    if(s<0) {s=0;}\r
2689    gl_ux[0]=gl_ux[3]=s;\r
2690   }\r
2691
2692  sSprite_ux2=s=gl_ux[0]+sprtW; 
2693  if(s)     s--;
2694  if(s>255) s=255;
2695  gl_ux[1]=gl_ux[2]=s; 
2696  // Y coords
2697  gl_vy[0]=gl_vy[1]=baseAddr[9];//(gpuData[2]>>8)&0xff;\r
2698 \r
2699  if(usMirror & 0x2000) \r
2700   {\r
2701    s=gl_vy[0];\r
2702    s-=sprtH-1;\r
2703    if(s<0) {s=0;}\r
2704    gl_vy[0]=gl_vy[1]=s;\r
2705   }\r
2706
2707  sSprite_vy2=s=gl_vy[0]+sprtH; 
2708  if(s)     s--;
2709  if(s>255) s=255;
2710  gl_vy[2]=gl_vy[3]=s;
2711
2712  ulClutID=(gpuData[2]>>16);
2713
2714  bDrawTextured = TRUE;
2715  bDrawSmoothShaded = FALSE;
2716  SetRenderState(gpuData[0]);
2717
2718  if(iOffscreenDrawing)  
2719   {
2720    offsetPSX4();
2721
2722    if(bDrawOffscreen4())
2723     {
2724      InvalidateTextureAreaEx();   
2725      SetRenderColor(gpuData[0]);
2726      lx0-=PSXDisplay.DrawOffset.x;
2727      ly0-=PSXDisplay.DrawOffset.y;
2728      if(bUsingTWin) DrawSoftwareSpriteTWin(baseAddr,16,16);
2729      else
2730      if(usMirror)   DrawSoftwareSpriteMirror(baseAddr,16,16);
2731      else
2732      DrawSoftwareSprite(baseAddr,16,16,baseAddr[8],baseAddr[9]);\r
2733     }
2734   }
2735
2736  SetRenderMode(gpuData[0], TRUE);
2737  SetZMask4SP();
2738
2739  sSprite_ux2=gl_ux[0]+sprtW;
2740  sSprite_vy2=gl_vy[0]+sprtH;
2741
2742  assignTextureSprite();
2743
2744  if(iFilterType>4) 
2745   DrawMultiFilterSprite();
2746  else
2747   PRIMdrawTexturedQuad(&vertex[0], &vertex[1], &vertex[2], &vertex[3]);
2748
2749  if(bDrawMultiPass)
2750   {
2751    SetSemiTransMulti(1);
2752    PRIMdrawTexturedQuad(&vertex[0], &vertex[1], &vertex[2], &vertex[3]);
2753   }
2754
2755  if(ubOpaqueDraw)
2756   {
2757    SetZMask4O();
2758    if(bUseMultiPass) SetOpaqueColor(gpuData[0]);
2759    DEFOPAQUEON
2760 \r
2761    if(bSmallAlpha && iFilterType<=2)\r
2762     {\r
2763      glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);\r
2764      glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);\r
2765      PRIMdrawTexturedQuad(&vertex[0], &vertex[1], &vertex[2], &vertex[3]);\r
2766      glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);\r
2767      glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);\r
2768      SetZMask4O();\r
2769     }\r
2770
2771    PRIMdrawTexturedQuad(&vertex[0], &vertex[1], &vertex[2], &vertex[3]);
2772    DEFOPAQUEOFF
2773   }
2774
2775  iSpriteTex=0;
2776  iDrawnSomething=1;
2777 }
2778
2779 ////////////////////////////////////////////////////////////////////////
2780 // cmd: free-size sprite (textured rect)
2781 ////////////////////////////////////////////////////////////////////////
2782  
2783 void primSprtSRest(unsigned char * baseAddr,unsigned short type)
2784 {
2785  uint32_t *gpuData = ((uint32_t *)baseAddr);
2786  short *sgpuData = ((short *) baseAddr);
2787  short s;
2788  unsigned short sTypeRest=0;
2789
2790  sprtX = sgpuData[2];
2791  sprtY = sgpuData[3];
2792  sprtW = sgpuData[6] & 0x3ff;
2793  sprtH = sgpuData[7] & 0x1ff;
2794
2795  // do texture stuff
2796  switch(type)
2797   {
2798    case 1:
2799     gl_vy[0]=gl_vy[1]=baseAddr[9];
2800     s=256-baseAddr[8];
2801     sprtW-=s;
2802     sprtX+=s;
2803     gl_ux[0]=gl_ux[3]=0;
2804     break;
2805    case 2:
2806     gl_ux[0]=gl_ux[3]=baseAddr[8];
2807     s=256-baseAddr[9];
2808     sprtH-=s;
2809     sprtY+=s;
2810     gl_vy[0]=gl_vy[1]=0;
2811     break;
2812    case 3:
2813     s=256-baseAddr[8];
2814     sprtW-=s;
2815     sprtX+=s;
2816     gl_ux[0]=gl_ux[3]=0;
2817     s=256-baseAddr[9];
2818     sprtH-=s;
2819     sprtY+=s;
2820     gl_vy[0]=gl_vy[1]=0;
2821     break;
2822
2823    case 4:
2824     gl_vy[0]=gl_vy[1]=baseAddr[9];
2825     s=512-baseAddr[8];
2826     sprtW-=s;
2827     sprtX+=s;
2828     gl_ux[0]=gl_ux[3]=0;
2829     break;
2830    case 5:
2831     gl_ux[0]=gl_ux[3]=baseAddr[8];
2832     s=512-baseAddr[9];
2833     sprtH-=s;
2834     sprtY+=s;
2835     gl_vy[0]=gl_vy[1]=0;
2836     break;
2837    case 6:
2838     s=512-baseAddr[8];
2839     sprtW-=s;
2840     sprtX+=s;
2841     gl_ux[0]=gl_ux[3]=0;
2842     s=512-baseAddr[9];
2843     sprtH-=s;
2844     sprtY+=s;
2845     gl_vy[0]=gl_vy[1]=0;
2846     break;
2847
2848   }
2849
2850  if(usMirror & 0x1000) 
2851   {
2852    s=gl_ux[0];
2853    s-=sprtW-1;if(s<0) s=0;
2854    gl_ux[0]=gl_ux[3]=s;
2855   }
2856  if(usMirror & 0x2000) \r
2857   {\r
2858    s=gl_vy[0];\r
2859    s-=sprtH-1;if(s<0) {s=0;}\r
2860    gl_vy[0]=gl_vy[1]=s;\r
2861   }\r
2862
2863  sSprite_ux2=s=gl_ux[0]+sprtW; 
2864  if(s>255) s=255;
2865  gl_ux[1]=gl_ux[2]=s;
2866  sSprite_vy2=s=gl_vy[0]+sprtH; 
2867  if(s>255) s=255;
2868  gl_vy[2]=gl_vy[3]=s;
2869
2870  if(!bUsingTWin)
2871   {
2872    if(sSprite_ux2>256) 
2873     {sprtW=256-gl_ux[0];sSprite_ux2=256;sTypeRest+=1;}
2874    if(sSprite_vy2>256) 
2875     {sprtH=256-gl_vy[0];sSprite_vy2=256;sTypeRest+=2;}
2876   }
2877  
2878  lx0 = sprtX;
2879  ly0 = sprtY;
2880
2881  offsetST();
2882
2883  ulClutID=(gpuData[2]>>16);
2884
2885  bDrawTextured = TRUE;
2886  bDrawSmoothShaded = FALSE;
2887  SetRenderState(gpuData[0]);
2888
2889  if(iOffscreenDrawing)
2890   {
2891    offsetPSX4();
2892
2893    if(bDrawOffscreen4())
2894     {
2895      InvalidateTextureAreaEx();   
2896      SetRenderColor(gpuData[0]);
2897      lx0-=PSXDisplay.DrawOffset.x;
2898      ly0-=PSXDisplay.DrawOffset.y;
2899      if(bUsingTWin) DrawSoftwareSpriteTWin(baseAddr,sprtW,sprtH);
2900      else
2901      if(usMirror)   DrawSoftwareSpriteMirror(baseAddr,sprtW,sprtH);
2902      else
2903      DrawSoftwareSprite(baseAddr,sprtW,sprtH,baseAddr[8],baseAddr[9]);\r
2904     }
2905   }
2906
2907  SetRenderMode(gpuData[0], TRUE);
2908  SetZMask4SP();
2909
2910  sSprite_ux2=gl_ux[0]+sprtW;
2911  sSprite_vy2=gl_vy[0]+sprtH;
2912
2913  assignTextureSprite();
2914
2915  if(iFilterType>4) 
2916   DrawMultiFilterSprite();
2917  else
2918   PRIMdrawTexturedQuad(&vertex[0], &vertex[1], &vertex[2], &vertex[3]);
2919  
2920  if(bDrawMultiPass)
2921   {
2922    SetSemiTransMulti(1);
2923    PRIMdrawTexturedQuad(&vertex[0], &vertex[1], &vertex[2], &vertex[3]);
2924   }
2925
2926  if(ubOpaqueDraw)
2927   {
2928    SetZMask4O();
2929    if(bUseMultiPass) SetOpaqueColor(gpuData[0]);
2930    DEFOPAQUEON\r
2931 \r
2932    if(bSmallAlpha && iFilterType<=2)\r
2933     {\r
2934      glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);\r
2935      glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);\r
2936      PRIMdrawTexturedQuad(&vertex[0], &vertex[1], &vertex[2], &vertex[3]);\r
2937      glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);\r
2938      glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);\r
2939      SetZMask4O();\r
2940     }\r
2941
2942    PRIMdrawTexturedQuad(&vertex[0], &vertex[1], &vertex[2], &vertex[3]);
2943    DEFOPAQUEOFF
2944   }
2945
2946  if(sTypeRest && type<4) 
2947   {
2948    if(sTypeRest&1  && type==1) primSprtSRest(baseAddr,4);
2949    if(sTypeRest&2  && type==2) primSprtSRest(baseAddr,5);
2950    if(sTypeRest==3 && type==3) primSprtSRest(baseAddr,6);
2951   }
2952 }
2953
2954 void primSprtS(unsigned char * baseAddr)
2955 {
2956  uint32_t *gpuData = ((uint32_t *) baseAddr);
2957  short *sgpuData = ((short *) baseAddr);
2958
2959  short s;
2960  unsigned short sTypeRest=0;
2961
2962  sprtX = sgpuData[2];
2963  sprtY = sgpuData[3];
2964  sprtW = sgpuData[6] & 0x3ff;
2965  sprtH = sgpuData[7] & 0x1ff;
2966
2967  if(!sprtH) return;
2968  if(!sprtW) return;
2969
2970  iSpriteTex=1;
2971
2972  // do texture stuff
2973  gl_ux[0]=gl_ux[3]=baseAddr[8];//gpuData[2]&0xff;
2974  gl_vy[0]=gl_vy[1]=baseAddr[9];//(gpuData[2]>>8)&0xff;
2975
2976  if(usMirror & 0x1000) 
2977   {
2978    s=gl_ux[0];
2979    s-=sprtW-1;
2980    if(s<0) {s=0;}
2981    gl_ux[0]=gl_ux[3]=s;
2982   }
2983  if(usMirror & 0x2000) \r
2984   {\r
2985    s=gl_vy[0];\r
2986    s-=sprtH-1;\r
2987    if(s<0) {s=0;}\r
2988    gl_vy[0]=gl_vy[1]=s;\r
2989   }\r
2990
2991  sSprite_ux2=s=gl_ux[0]+sprtW; 
2992  if(s)     s--;
2993  if(s>255) s=255;
2994  gl_ux[1]=gl_ux[2]=s;
2995  sSprite_vy2=s=gl_vy[0]+sprtH; 
2996  if(s)     s--;
2997  if(s>255) s=255;
2998  gl_vy[2]=gl_vy[3]=s;
2999
3000  if(!bUsingTWin)
3001   {
3002    if(sSprite_ux2>256) 
3003     {sprtW=256-gl_ux[0];sSprite_ux2=256;sTypeRest+=1;}
3004    if(sSprite_vy2>256) 
3005     {sprtH=256-gl_vy[0];sSprite_vy2=256;sTypeRest+=2;}
3006   }
3007
3008  lx0 = sprtX;
3009  ly0 = sprtY;
3010
3011  offsetST();
3012
3013  ulClutID=(gpuData[2]>>16);
3014
3015  bDrawTextured = TRUE;
3016  bDrawSmoothShaded = FALSE;
3017  SetRenderState(gpuData[0]);
3018
3019  if(iOffscreenDrawing)
3020   {
3021    offsetPSX4();
3022
3023    if(bDrawOffscreen4())
3024     {
3025      InvalidateTextureAreaEx();   
3026      SetRenderColor(gpuData[0]);
3027      lx0-=PSXDisplay.DrawOffset.x;
3028      ly0-=PSXDisplay.DrawOffset.y;
3029      if(bUsingTWin) DrawSoftwareSpriteTWin(baseAddr,sprtW,sprtH);
3030      else
3031      if(usMirror)   DrawSoftwareSpriteMirror(baseAddr,sprtW,sprtH);
3032      else
3033      DrawSoftwareSprite(baseAddr,sprtW,sprtH,baseAddr[8],baseAddr[9]);\r
3034     }
3035   }
3036
3037  SetRenderMode(gpuData[0], TRUE);
3038  SetZMask4SP();
3039
3040  if((dwActFixes&1) && gTexFrameName && gTexName==gTexFrameName) 
3041   {iSpriteTex=0;return;}
3042
3043  sSprite_ux2=gl_ux[0]+sprtW;
3044  sSprite_vy2=gl_vy[0]+sprtH;
3045
3046  assignTextureSprite();
3047
3048  if(iFilterType>4) 
3049   DrawMultiFilterSprite();
3050  else
3051   PRIMdrawTexturedQuad(&vertex[0], &vertex[1], &vertex[2], &vertex[3]);
3052  
3053  if(bDrawMultiPass)
3054   {
3055    SetSemiTransMulti(1);
3056    PRIMdrawTexturedQuad(&vertex[0], &vertex[1], &vertex[2], &vertex[3]);
3057   }
3058
3059  if(ubOpaqueDraw)
3060   {
3061    SetZMask4O();
3062    if(bUseMultiPass) SetOpaqueColor(gpuData[0]);
3063    DEFOPAQUEON\r
3064 \r
3065    if(bSmallAlpha && iFilterType<=2)\r
3066     {\r
3067      glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);\r
3068      glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);\r
3069      PRIMdrawTexturedQuad(&vertex[0], &vertex[1], &vertex[2], &vertex[3]);\r
3070      glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);\r
3071      glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);\r
3072      SetZMask4O();\r
3073     }\r
3074
3075    PRIMdrawTexturedQuad(&vertex[0], &vertex[1], &vertex[2], &vertex[3]);
3076    DEFOPAQUEOFF
3077   }
3078
3079  if(sTypeRest) 
3080   {
3081    if(sTypeRest&1)  primSprtSRest(baseAddr,1);
3082    if(sTypeRest&2)  primSprtSRest(baseAddr,2);
3083    if(sTypeRest==3) primSprtSRest(baseAddr,3);
3084   }
3085
3086  iSpriteTex=0;
3087  iDrawnSomething=1;
3088 }
3089
3090 ////////////////////////////////////////////////////////////////////////
3091 // cmd: flat shaded Poly4
3092 ////////////////////////////////////////////////////////////////////////
3093
3094 void primPolyF4(unsigned char *baseAddr)
3095 {
3096  uint32_t *gpuData = ((uint32_t *) baseAddr);
3097  short *sgpuData = ((short *) baseAddr);
3098
3099  lx0 = sgpuData[2];
3100  ly0 = sgpuData[3];
3101  lx1 = sgpuData[4];
3102  ly1 = sgpuData[5];
3103  lx2 = sgpuData[6];
3104  ly2 = sgpuData[7];
3105  lx3 = sgpuData[8];
3106  ly3 = sgpuData[9];
3107
3108  if(offset4()) return;
3109
3110  bDrawTextured = FALSE;
3111  bDrawSmoothShaded = FALSE;
3112  SetRenderState(gpuData[0]);
3113
3114  if(iOffscreenDrawing)
3115   {
3116    offsetPSX4();
3117    if(bDrawOffscreen4())
3118     {
3119      InvalidateTextureAreaEx();   
3120      drawPoly4F(gpuData[0]);
3121     }
3122   }
3123
3124  SetRenderMode(gpuData[0], FALSE);
3125  SetZMask4NT();
3126
3127  vertex[0].c.lcol=gpuData[0];vertex[0].c.col[3]=ubGloColAlpha;
3128  SETCOL(vertex[0]); 
3129
3130  PRIMdrawTri2(&vertex[0], &vertex[1], &vertex[2],&vertex[3]);
3131
3132  iDrawnSomething=1;
3133 }
3134
3135 ////////////////////////////////////////////////////////////////////////
3136 // cmd: smooth shaded Poly4
3137 ////////////////////////////////////////////////////////////////////////
3138
3139 void primPolyG4(unsigned char * baseAddr);
3140
3141 BOOL bDrawOffscreenFrontFF9G4(void)
3142 {
3143  if(lx0< PSXDisplay.DisplayPosition.x) return FALSE;   // must be complete in front
3144  if(lx0> PSXDisplay.DisplayEnd.x)      return FALSE;
3145  if(ly0< PSXDisplay.DisplayPosition.y) return FALSE;
3146  if(ly0> PSXDisplay.DisplayEnd.y)      return FALSE;
3147  if(lx1< PSXDisplay.DisplayPosition.x) return FALSE;
3148  if(lx1> PSXDisplay.DisplayEnd.x)      return FALSE;
3149  if(ly1< PSXDisplay.DisplayPosition.y) return FALSE;
3150  if(ly1> PSXDisplay.DisplayEnd.y)      return FALSE;
3151  if(lx2< PSXDisplay.DisplayPosition.x) return FALSE;
3152  if(lx2> PSXDisplay.DisplayEnd.x)      return FALSE;
3153  if(ly2< PSXDisplay.DisplayPosition.y) return FALSE;
3154  if(ly2> PSXDisplay.DisplayEnd.y)      return FALSE;
3155  if(lx3< PSXDisplay.DisplayPosition.x) return FALSE;
3156  if(lx3> PSXDisplay.DisplayEnd.x)      return FALSE;
3157  if(ly3< PSXDisplay.DisplayPosition.y) return FALSE;
3158  if(ly3> PSXDisplay.DisplayEnd.y)      return FALSE;
3159  return TRUE;
3160 }
3161
3162 BOOL bCheckFF9G4(unsigned char * baseAddr)
3163 {
3164  static unsigned char pFF9G4Cache[32];
3165  static int iFF9Fix=0;
3166
3167  if(baseAddr)
3168   {
3169    if(iFF9Fix==0)
3170     {
3171      if(bDrawOffscreenFrontFF9G4())
3172       {\r
3173        short *sgpuData = ((short *) pFF9G4Cache);\r
3174        iFF9Fix=2;\r
3175        memcpy(pFF9G4Cache,baseAddr,32);\r
3176 \r
3177        if(sgpuData[2]==142)\r
3178         {\r
3179          sgpuData[2] +=65;\r
3180          sgpuData[10]+=65;\r
3181         }\r
3182        return TRUE;
3183       }
3184      else iFF9Fix=1;
3185     }
3186    return FALSE;
3187   }
3188
3189  if(iFF9Fix==2)
3190   {
3191    int labr=GlobalTextABR;
3192    GlobalTextABR = 1;
3193    primPolyG4(pFF9G4Cache);
3194    GlobalTextABR = labr;
3195   }
3196  iFF9Fix = 0;
3197
3198  return FALSE;
3199 }
3200
3201 ////////////////////////////////////////////////////////////////////////
3202
3203 void primPolyG4(unsigned char * baseAddr)
3204 {
3205  uint32_t *gpuData = (uint32_t *)baseAddr;
3206  short *sgpuData = ((short *)baseAddr);
3207
3208  lx0 = sgpuData[2];
3209  ly0 = sgpuData[3];
3210  lx1 = sgpuData[6];
3211  ly1 = sgpuData[7];
3212  lx2 = sgpuData[10];
3213  ly2 = sgpuData[11];
3214  lx3 = sgpuData[14];
3215  ly3 = sgpuData[15];
3216
3217  if(offset4()) return;
3218
3219  bDrawTextured = FALSE;
3220  bDrawSmoothShaded = TRUE;
3221  SetRenderState(gpuData[0]);
3222
3223  if(iOffscreenDrawing)
3224   {
3225    offsetPSX4();
3226
3227    if((dwActFixes&512) && bCheckFF9G4(baseAddr)) return;
3228
3229    if(bDrawOffscreen4())
3230     {
3231      InvalidateTextureAreaEx();   
3232      drawPoly4G(gpuData[0], gpuData[2], gpuData[4], gpuData[6]);
3233     }     
3234   }
3235
3236  SetRenderMode(gpuData[0], FALSE);
3237  SetZMask4NT();
3238
3239  vertex[0].c.lcol=gpuData[0];
3240  vertex[1].c.lcol=gpuData[2];
3241  vertex[2].c.lcol=gpuData[4];
3242  vertex[3].c.lcol=gpuData[6];
3243
3244  vertex[0].c.col[3]=vertex[1].c.col[3]=vertex[2].c.col[3]=vertex[3].c.col[3]=ubGloAlpha;
3245
3246
3247  PRIMdrawGouraudTri2Color(&vertex[0],&vertex[1], &vertex[2], &vertex[3]);
3248
3249  iDrawnSomething=1;
3250 }
3251
3252 ////////////////////////////////////////////////////////////////////////
3253 // cmd: flat shaded Texture3
3254 ////////////////////////////////////////////////////////////////////////
3255
3256 BOOL DoLineCheck(uint32_t *gpuData)
3257 {
3258  BOOL bQuad=FALSE;short dx,dy;
3259
3260  if(lx0==lx1)
3261   {
3262    dx=lx0-lx2;if(dx<0) dx=-dx;
3263
3264    if(ly1==ly2) 
3265     {
3266      dy=ly1-ly0;if(dy<0) dy=-dy;
3267      if(dx<=1)
3268       {
3269        vertex[3]=vertex[2];
3270        vertex[2]=vertex[0];
3271        vertex[2].x=vertex[3].x;
3272       }
3273      else
3274      if(dy<=1)
3275       {
3276        vertex[3]=vertex[2];
3277        vertex[2].y=vertex[0].y;
3278       }
3279      else return FALSE;
3280
3281      bQuad=TRUE;
3282     }
3283    else
3284    if(ly0==ly2) 
3285     {
3286      dy=ly0-ly1;if(dy<0) dy=-dy;
3287      if(dx<=1)
3288       {
3289        vertex[3]=vertex[1];
3290        vertex[3].x=vertex[2].x;
3291       }
3292      else
3293      if(dy<=1)
3294       {
3295        vertex[3]=vertex[2];
3296        vertex[3].y=vertex[1].y;
3297       }
3298      else return FALSE;
3299
3300      bQuad=TRUE;
3301     }
3302   }
3303
3304  if(lx0==lx2)
3305   {
3306    dx=lx0-lx1;if(dx<0) dx=-dx;
3307
3308    if(ly2==ly1) 
3309     {
3310      dy=ly2-ly0;if(dy<0) dy=-dy;
3311      if(dx<=1)
3312       {
3313        vertex[3]=vertex[1];
3314        vertex[1]=vertex[0];
3315        vertex[1].x=vertex[3].x;
3316       }
3317      else
3318      if(dy<=1)
3319       {
3320        vertex[3]=vertex[1];
3321        vertex[1].y=vertex[0].y;
3322       }
3323      else return FALSE;
3324
3325      bQuad=TRUE;
3326     }
3327    else
3328    if(ly0==ly1)
3329     {
3330      dy=ly2-ly0;if(dy<0) dy=-dy;
3331      if(dx<=1)
3332       {
3333        vertex[3]=vertex[2];
3334        vertex[3].x=vertex[1].x;
3335       }
3336      else
3337      if(dy<=1)
3338       {
3339        vertex[3]=vertex[1];
3340        vertex[3].y=vertex[2].y;
3341       }
3342      else return FALSE;
3343
3344      bQuad=TRUE;
3345     }
3346   }
3347
3348  if(lx1==lx2)
3349   {
3350    dx=lx1-lx0;if(dx<0) dx=-dx;
3351
3352    if(ly1==ly0)
3353     {
3354      dy=ly1-ly2;if(dy<0) dy=-dy;
3355
3356      if(dx<=1)
3357       {
3358        vertex[3]=vertex[2];
3359        vertex[2].x=vertex[0].x;
3360       }
3361      else
3362      if(dy<=1)
3363       {
3364        vertex[3]=vertex[2];
3365        vertex[2]=vertex[0];
3366        vertex[2].y=vertex[3].y;
3367       }
3368      else return FALSE;
3369
3370      bQuad=TRUE;
3371     }
3372    else
3373    if(ly2==ly0)
3374     {
3375      dy=ly2-ly1;if(dy<0) dy=-dy;
3376
3377      if(dx<=1)
3378       {
3379        vertex[3]=vertex[1];
3380        vertex[1].x=vertex[0].x;
3381       }
3382      else
3383      if(dy<=1)
3384       {
3385        vertex[3]=vertex[1];
3386        vertex[1]=vertex[0];
3387        vertex[1].y=vertex[3].y;
3388       }
3389      else return FALSE;
3390
3391      bQuad=TRUE;
3392     }
3393   }
3394
3395  if(!bQuad) return FALSE;
3396
3397  PRIMdrawTexturedQuad(&vertex[0], &vertex[1], &vertex[3], &vertex[2]);
3398
3399  if(bDrawMultiPass)
3400   {
3401    SetSemiTransMulti(1);
3402    PRIMdrawTexturedQuad(&vertex[0], &vertex[1], &vertex[3], &vertex[2]);
3403   }
3404
3405  if(ubOpaqueDraw)
3406   {
3407    SetZMask4O();
3408    if(bUseMultiPass) SetOpaqueColor(gpuData[0]);
3409    DEFOPAQUEON
3410    PRIMdrawTexturedQuad(&vertex[0], &vertex[1], &vertex[3], &vertex[2]);
3411    DEFOPAQUEOFF
3412   }
3413
3414  iDrawnSomething=1;
3415
3416  return TRUE;
3417 }
3418
3419 ////////////////////////////////////////////////////////////////////////
3420
3421 void primPolyFT3(unsigned char * baseAddr)
3422 {
3423  uint32_t *gpuData = ((uint32_t *) baseAddr);
3424  short *sgpuData = ((short *) baseAddr);
3425
3426  lx0 = sgpuData[2];
3427  ly0 = sgpuData[3];
3428  lx1 = sgpuData[6];
3429  ly1 = sgpuData[7];
3430  lx2 = sgpuData[10];
3431  ly2 = sgpuData[11];
3432
3433  if(offset3()) return;
3434     
3435  // do texture UV coordinates stuff
3436  gl_ux[0]=gl_ux[3]=baseAddr[8];//gpuData[2]&0xff;
3437  gl_vy[0]=gl_vy[3]=baseAddr[9];//(gpuData[2]>>8)&0xff;
3438  gl_ux[1]=baseAddr[16];//gpuData[4]&0xff;
3439  gl_vy[1]=baseAddr[17];//(gpuData[4]>>8)&0xff;
3440  gl_ux[2]=baseAddr[24];//gpuData[6]&0xff;
3441  gl_vy[2]=baseAddr[25];//(gpuData[6]>>8)&0xff;
3442
3443  UpdateGlobalTP((unsigned short)(gpuData[4]>>16));
3444  ulClutID=gpuData[2]>>16;
3445
3446  bDrawTextured = TRUE;
3447  bDrawSmoothShaded = FALSE;
3448  SetRenderState(gpuData[0]);
3449
3450  if(iOffscreenDrawing)
3451   {
3452    offsetPSX3();
3453    if(bDrawOffscreen3())
3454     {
3455      InvalidateTextureAreaEx();   
3456      SetRenderColor(gpuData[0]);
3457      drawPoly3FT(baseAddr);
3458     }
3459   }
3460
3461  SetRenderMode(gpuData[0], TRUE);
3462  SetZMask3();
3463
3464  assignTexture3();
3465
3466  if(!(dwActFixes&0x10))
3467   {
3468    if(DoLineCheck(gpuData)) return;
3469   }
3470
3471  PRIMdrawTexturedTri(&vertex[0], &vertex[1], &vertex[2]);
3472
3473  if(bDrawMultiPass)
3474   {
3475    SetSemiTransMulti(1);
3476    PRIMdrawTexturedTri(&vertex[0], &vertex[1], &vertex[2]);
3477   }
3478
3479  if(ubOpaqueDraw)
3480   {
3481    SetZMask3O();
3482    if(bUseMultiPass) SetOpaqueColor(gpuData[0]);
3483    DEFOPAQUEON
3484    PRIMdrawTexturedTri(&vertex[0], &vertex[1], &vertex[2]);
3485    DEFOPAQUEOFF
3486   }
3487
3488  iDrawnSomething=1;
3489 }
3490
3491 ////////////////////////////////////////////////////////////////////////
3492 // cmd: flat shaded Texture4
3493 ////////////////////////////////////////////////////////////////////////
3494 \r
3495 #define ST_FAC             255.99f\r
3496 \r
3497 void RectTexAlign(void)\r
3498 {\r
3499  int UFlipped = FALSE;\r
3500  int VFlipped = FALSE;\r
3501 \r
3502  if(gTexName==gTexFrameName) return;\r
3503 \r
3504  if(ly0==ly1)\r
3505   {\r
3506    if(!((lx1==lx3 && ly3==ly2 && lx2==lx0) ||\r
3507         (lx1==lx2 && ly2==ly3 && lx3==lx0)))\r
3508     return;\r
3509 \r
3510    if(ly0<ly2) \r
3511     {\r
3512      if (vertex[0].tow > vertex[2].tow)\r
3513       VFlipped = 1;\r
3514     }\r
3515    else\r
3516     {\r
3517      if (vertex[0].tow < vertex[2].tow)\r
3518       VFlipped = 2;\r
3519     }\r
3520   }\r
3521  else\r
3522  if(ly0==ly2)\r
3523   {\r
3524    if(!((lx2==lx3 && ly3==ly1 && lx1==lx0) ||\r
3525         (lx2==lx1 && ly1==ly3 && lx3==lx0)))\r
3526     return;\r
3527 \r
3528    if(ly0<ly1) \r
3529     {\r
3530      if (vertex[0].tow > vertex[1].tow)\r
3531       VFlipped = 3;\r
3532     }\r
3533    else\r
3534     {\r
3535      if (vertex[0].tow < vertex[1].tow)\r
3536       VFlipped = 4;\r
3537     }\r
3538   }\r
3539  else\r
3540  if(ly0==ly3)\r
3541   {\r
3542    if(!((lx3==lx2 && ly2==ly1 && lx1==lx0) ||\r
3543         (lx3==lx1 && ly1==ly2 && lx2==lx0)))\r
3544     return;\r
3545 \r
3546    if(ly0<ly1) \r
3547     {\r
3548      if (vertex[0].tow > vertex[1].tow)\r
3549       VFlipped = 5;\r
3550     }\r
3551    else\r
3552     {\r
3553      if (vertex[0].tow < vertex[1].tow)\r
3554       VFlipped = 6;\r
3555     }\r
3556   }\r
3557  else return;\r
3558 \r
3559  if(lx0==lx1)\r
3560   {\r
3561    if(lx0<lx2) \r
3562     {\r
3563      if (vertex[0].sow > vertex[2].sow)\r
3564       UFlipped = 1;\r
3565     }\r
3566    else\r
3567     {\r
3568      if (vertex[0].sow < vertex[2].sow)\r
3569       UFlipped = 2;\r
3570     }\r
3571   }\r
3572  else\r
3573  if(lx0==lx2)\r
3574   {\r
3575    if(lx0<lx1) \r
3576     {\r
3577      if (vertex[0].sow > vertex[1].sow)\r
3578       UFlipped = 3;\r
3579     }\r
3580    else\r
3581     {\r
3582      if (vertex[0].sow < vertex[1].sow)\r
3583       UFlipped = 4;\r
3584     }\r
3585   }\r
3586  else\r
3587  if(lx0==lx3)\r
3588   {\r
3589    if(lx0<lx1) \r
3590     {\r
3591      if (vertex[0].sow > vertex[1].sow)\r
3592       UFlipped = 5;\r
3593     }\r
3594    else\r
3595     {\r
3596      if (vertex[0].sow < vertex[1].sow)\r
3597       UFlipped = 6;\r
3598     }\r
3599   }\r
3600 \r
3601  if (UFlipped)\r
3602   {\r
3603 #ifdef OWNSCALE\r
3604    if(bUsingTWin)\r
3605     {\r
3606      switch(UFlipped)\r
3607       {\r
3608        case 1:\r
3609         vertex[2].sow+=0.95f/TWin.UScaleFactor; \r
3610         vertex[3].sow+=0.95f/TWin.UScaleFactor;\r
3611         break;\r
3612        case 2:\r
3613         vertex[0].sow+=0.95f/TWin.UScaleFactor; \r
3614         vertex[1].sow+=0.95f/TWin.UScaleFactor;\r
3615         break;\r
3616        case 3:\r
3617         vertex[1].sow+=0.95f/TWin.UScaleFactor; \r
3618         vertex[3].sow+=0.95f/TWin.UScaleFactor;\r
3619         break;\r
3620        case 4:\r
3621         vertex[0].sow+=0.95f/TWin.UScaleFactor; \r
3622         vertex[2].sow+=0.95f/TWin.UScaleFactor;\r
3623         break;\r
3624        case 5:\r
3625         vertex[1].sow+=0.95f/TWin.UScaleFactor; \r
3626         vertex[2].sow+=0.95f/TWin.UScaleFactor;\r
3627         break;\r
3628        case 6:\r
3629         vertex[0].sow+=0.95f/TWin.UScaleFactor; \r
3630         vertex[3].sow+=0.95f/TWin.UScaleFactor;\r
3631         break;\r
3632       }\r
3633     }\r
3634    else\r
3635     {\r
3636      switch(UFlipped)\r
3637       {\r
3638        case 1:\r
3639         vertex[2].sow+=1.0f/ST_FAC; \r
3640         vertex[3].sow+=1.0f/ST_FAC;\r
3641         break;\r
3642        case 2:\r
3643         vertex[0].sow+=1.0f/ST_FAC; \r
3644         vertex[1].sow+=1.0f/ST_FAC;\r
3645         break;\r
3646        case 3:\r
3647         vertex[1].sow+=1.0f/ST_FAC; \r
3648         vertex[3].sow+=1.0f/ST_FAC;\r
3649         break;\r
3650        case 4:\r
3651         vertex[0].sow+=1.0f/ST_FAC; \r
3652         vertex[2].sow+=1.0f/ST_FAC;\r
3653         break;\r
3654        case 5:\r
3655         vertex[1].sow+=1.0f/ST_FAC; \r
3656         vertex[2].sow+=1.0f/ST_FAC;\r
3657         break;\r
3658        case 6:\r
3659         vertex[0].sow+=1.0f/ST_FAC; \r
3660         vertex[3].sow+=1.0f/ST_FAC;\r
3661         break;\r
3662       }\r
3663     }\r
3664 #else\r
3665    if(bUsingTWin)\r
3666     {\r
3667      switch(UFlipped)\r
3668       {\r
3669        case 1:\r
3670         vertex[2].sow+=1.0f/TWin.UScaleFactor; \r
3671         vertex[3].sow+=1.0f/TWin.UScaleFactor;\r
3672         break;\r
3673        case 2:\r
3674         vertex[0].sow+=1.0f/TWin.UScaleFactor; \r
3675         vertex[1].sow+=1.0f/TWin.UScaleFactor;\r
3676         break;\r
3677        case 3:\r
3678         vertex[1].sow+=1.0f/TWin.UScaleFactor; \r
3679         vertex[3].sow+=1.0f/TWin.UScaleFactor;\r
3680         break;\r
3681        case 4:\r
3682         vertex[0].sow+=1.0f/TWin.UScaleFactor; \r
3683         vertex[2].sow+=1.0f/TWin.UScaleFactor;\r
3684         break;\r
3685        case 5:\r
3686         vertex[1].sow+=1.0f/TWin.UScaleFactor; \r
3687         vertex[2].sow+=1.0f/TWin.UScaleFactor;\r
3688         break;\r
3689        case 6:\r
3690         vertex[0].sow+=1.0f/TWin.UScaleFactor; \r
3691         vertex[3].sow+=1.0f/TWin.UScaleFactor;\r
3692         break;\r
3693       }\r
3694     }\r
3695    else\r
3696     {\r
3697      switch(UFlipped)\r
3698       {\r
3699        case 1:\r
3700         vertex[2].sow+=1.0f; \r
3701         vertex[3].sow+=1.0f;\r
3702         break;\r
3703        case 2:\r
3704         vertex[0].sow+=1.0f; \r
3705         vertex[1].sow+=1.0f;\r
3706         break;\r
3707        case 3:\r
3708         vertex[1].sow+=1.0f; \r
3709         vertex[3].sow+=1.0f;\r
3710         break;\r
3711        case 4:\r
3712         vertex[0].sow+=1.0f; \r
3713         vertex[2].sow+=1.0f;\r
3714         break;\r
3715        case 5:\r
3716         vertex[1].sow+=1.0f; \r
3717         vertex[2].sow+=1.0f;\r
3718         break;\r
3719        case 6:\r
3720         vertex[0].sow+=1.0f; \r
3721         vertex[3].sow+=1.0f;\r
3722         break;\r
3723       }\r
3724     }\r
3725 #endif\r
3726   }\r
3727 \r
3728  if (VFlipped)\r
3729   {\r
3730 #ifdef OWNSCALE\r
3731    if(bUsingTWin)\r
3732     {\r
3733      switch(VFlipped)\r
3734       {\r
3735        case 1:\r
3736         vertex[2].tow+=0.95f/TWin.VScaleFactor; \r
3737         vertex[3].tow+=0.95f/TWin.VScaleFactor;\r
3738         break;\r
3739        case 2:\r
3740         vertex[0].tow+=0.95f/TWin.VScaleFactor; \r
3741         vertex[1].tow+=0.95f/TWin.VScaleFactor;\r
3742         break;\r
3743        case 3:\r
3744         vertex[1].tow+=0.95f/TWin.VScaleFactor; \r
3745         vertex[3].tow+=0.95f/TWin.VScaleFactor;\r
3746         break;\r
3747        case 4:\r
3748         vertex[0].tow+=0.95f/TWin.VScaleFactor; \r
3749         vertex[2].tow+=0.95f/TWin.VScaleFactor;\r
3750         break;\r
3751        case 5:\r
3752         vertex[1].tow+=0.95f/TWin.VScaleFactor; \r
3753         vertex[2].tow+=0.95f/TWin.VScaleFactor;\r
3754         break;\r
3755        case 6:\r
3756         vertex[0].tow+=0.95f/TWin.VScaleFactor; \r
3757         vertex[3].tow+=0.95f/TWin.VScaleFactor;\r
3758         break;\r
3759       }\r
3760     }\r
3761    else\r
3762     {\r
3763      switch(VFlipped)\r
3764       {\r
3765        case 1:\r
3766         vertex[2].tow+=1.0f/ST_FAC; \r
3767         vertex[3].tow+=1.0f/ST_FAC;\r
3768         break;\r
3769        case 2:\r
3770         vertex[0].tow+=1.0f/ST_FAC; \r
3771         vertex[1].tow+=1.0f/ST_FAC;\r
3772         break;\r
3773        case 3:\r
3774         vertex[1].tow+=1.0f/ST_FAC;\r
3775         vertex[3].tow+=1.0f/ST_FAC;\r
3776         break;\r
3777        case 4:\r
3778         vertex[0].tow+=1.0f/ST_FAC; \r
3779         vertex[2].tow+=1.0f/ST_FAC;\r
3780         break;\r
3781        case 5:\r
3782         vertex[1].tow+=1.0f/ST_FAC;\r
3783         vertex[2].tow+=1.0f/ST_FAC;\r
3784         break;\r
3785        case 6:\r
3786         vertex[0].tow+=1.0f/ST_FAC;\r
3787         vertex[3].tow+=1.0f/ST_FAC;\r
3788         break;\r
3789       }\r
3790     }\r
3791 #else\r
3792    if(bUsingTWin)\r
3793     {\r
3794      switch(VFlipped)\r
3795       {\r
3796        case 1:\r
3797         vertex[2].tow+=1.0f/TWin.VScaleFactor; \r
3798         vertex[3].tow+=1.0f/TWin.VScaleFactor;\r
3799         break;\r
3800        case 2:\r
3801         vertex[0].tow+=1.0f/TWin.VScaleFactor; \r
3802         vertex[1].tow+=1.0f/TWin.VScaleFactor;\r
3803         break;\r
3804        case 3:\r
3805         vertex[1].tow+=1.0f/TWin.VScaleFactor; \r
3806         vertex[3].tow+=1.0f/TWin.VScaleFactor;\r
3807         break;\r
3808        case 4:\r
3809         vertex[0].tow+=1.0f/TWin.VScaleFactor; \r
3810         vertex[2].tow+=1.0f/TWin.VScaleFactor;\r
3811         break;\r
3812        case 5:\r
3813         vertex[1].tow+=1.0f/TWin.VScaleFactor; \r
3814         vertex[2].tow+=1.0f/TWin.VScaleFactor;\r
3815         break;\r
3816        case 6:\r
3817         vertex[0].tow+=1.0f/TWin.VScaleFactor; \r
3818         vertex[3].tow+=1.0f/TWin.VScaleFactor;\r
3819         break;\r
3820       }\r
3821     }\r
3822    else\r
3823     {\r
3824      switch(VFlipped)\r
3825       {\r
3826        case 1:\r
3827         vertex[2].tow+=1.0f; \r
3828         vertex[3].tow+=1.0f;\r
3829         break;\r
3830        case 2:\r
3831         vertex[0].tow+=1.0f; \r
3832         vertex[1].tow+=1.0f;\r
3833         break;\r
3834        case 3:\r
3835         vertex[1].tow+=1.0f; \r
3836         vertex[3].tow+=1.0f;\r
3837         break;\r
3838        case 4:\r
3839         vertex[0].tow+=1.0f; \r
3840         vertex[2].tow+=1.0f;\r
3841         break;\r
3842        case 5:\r
3843         vertex[1].tow+=1.0f; \r
3844         vertex[2].tow+=1.0f;\r
3845         break;\r
3846        case 6:\r
3847         vertex[0].tow+=1.0f; \r
3848         vertex[3].tow+=1.0f;\r
3849         break;\r
3850       }\r
3851     }\r
3852 #endif\r
3853   }\r
3854 \r
3855 }\r
3856
3857 void primPolyFT4(unsigned char * baseAddr)
3858 {
3859  uint32_t *gpuData = ((uint32_t *)baseAddr);
3860  short *sgpuData = ((short *) baseAddr);
3861
3862  lx0 = sgpuData[2];
3863  ly0 = sgpuData[3];
3864  lx1 = sgpuData[6];
3865  ly1 = sgpuData[7];
3866  lx2 = sgpuData[10];
3867  ly2 = sgpuData[11];
3868  lx3 = sgpuData[14];
3869  ly3 = sgpuData[15];
3870
3871  if(offset4()) return;
3872
3873  gl_vy[0]=baseAddr[9];//((gpuData[2]>>8)&0xff);
3874  gl_vy[1]=baseAddr[17];//((gpuData[4]>>8)&0xff);
3875  gl_vy[2]=baseAddr[25];//((gpuData[6]>>8)&0xff);
3876  gl_vy[3]=baseAddr[33];//((gpuData[8]>>8)&0xff);
3877  
3878  gl_ux[0]=baseAddr[8];//(gpuData[2]&0xff);
3879  gl_ux[1]=baseAddr[16];//(gpuData[4]&0xff);
3880  gl_ux[2]=baseAddr[24];//(gpuData[6]&0xff);
3881  gl_ux[3]=baseAddr[32];//(gpuData[8]&0xff);
3882
3883  UpdateGlobalTP((unsigned short)(gpuData[4]>>16));
3884  ulClutID=(gpuData[2]>>16);
3885
3886  bDrawTextured = TRUE;
3887  bDrawSmoothShaded = FALSE;
3888  SetRenderState(gpuData[0]);
3889
3890  if(iOffscreenDrawing)
3891   {
3892    offsetPSX4();
3893    if(bDrawOffscreen4())
3894     {
3895      InvalidateTextureAreaEx();   
3896      SetRenderColor(gpuData[0]);
3897      drawPoly4FT(baseAddr);
3898     }
3899   }
3900
3901  SetRenderMode(gpuData[0], TRUE);
3902
3903  SetZMask4();
3904
3905  assignTexture4();
3906
3907  RectTexAlign();
3908
3909  PRIMdrawTexturedQuad(&vertex[0], &vertex[1], &vertex[3], &vertex[2]);
3910
3911  if(bDrawMultiPass)
3912   {
3913    SetSemiTransMulti(1);
3914    PRIMdrawTexturedQuad(&vertex[0], &vertex[1], &vertex[3], &vertex[2]);
3915   }
3916
3917  if(ubOpaqueDraw)
3918   {
3919    SetZMask4O();
3920    if(bUseMultiPass) SetOpaqueColor(gpuData[0]);
3921    DEFOPAQUEON\r
3922 \r
3923    if(bSmallAlpha && iFilterType<=2)\r
3924     {\r
3925      glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);\r
3926      glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);\r
3927      PRIMdrawTexturedQuad(&vertex[0], &vertex[1], &vertex[3], &vertex[2]);\r
3928      glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);\r
3929      glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);\r
3930      SetZMask4O();\r
3931     }\r
3932
3933    PRIMdrawTexturedQuad(&vertex[0], &vertex[1], &vertex[3], &vertex[2]);
3934    DEFOPAQUEOFF
3935   }
3936
3937  iDrawnSomething=1;
3938 }
3939
3940 ////////////////////////////////////////////////////////////////////////
3941 // cmd: smooth shaded Texture3
3942 ////////////////////////////////////////////////////////////////////////
3943
3944 void primPolyGT3(unsigned char *baseAddr)
3945 {    
3946  uint32_t *gpuData = ((uint32_t *) baseAddr);
3947  short *sgpuData = ((short *) baseAddr);
3948
3949  lx0 = sgpuData[2];
3950  ly0 = sgpuData[3];
3951  lx1 = sgpuData[8];
3952  ly1 = sgpuData[9];
3953  lx2 = sgpuData[14];
3954  ly2 = sgpuData[15];
3955
3956  if(offset3()) return;
3957
3958  // do texture stuff
3959  gl_ux[0]=gl_ux[3]=baseAddr[8];//gpuData[2]&0xff;
3960  gl_vy[0]=gl_vy[3]=baseAddr[9];//(gpuData[2]>>8)&0xff;
3961  gl_ux[1]=baseAddr[20];//gpuData[5]&0xff;
3962  gl_vy[1]=baseAddr[21];//(gpuData[5]>>8)&0xff;
3963  gl_ux[2]=baseAddr[32];//gpuData[8]&0xff;
3964  gl_vy[2]=baseAddr[33];//(gpuData[8]>>8)&0xff;
3965
3966  UpdateGlobalTP((unsigned short)(gpuData[5]>>16));
3967  ulClutID=(gpuData[2]>>16);
3968            
3969  bDrawTextured = TRUE;
3970  bDrawSmoothShaded = TRUE;
3971  SetRenderState(gpuData[0]);
3972
3973  if(iOffscreenDrawing)
3974   {
3975    offsetPSX3();
3976    if(bDrawOffscreen3())
3977     {
3978      InvalidateTextureAreaEx();   
3979      drawPoly3GT(baseAddr);
3980     }
3981   }
3982
3983  SetRenderMode(gpuData[0], FALSE);
3984  SetZMask3();
3985
3986  assignTexture3();
3987
3988  if(bDrawNonShaded)
3989   {
3990    //if(!bUseMultiPass) vertex[0].lcol=DoubleBGR2RGB(gpuData[0]); else vertex[0].lcol=gpuData[0];
3991    // eat this...
3992    if(bGLBlend) vertex[0].c.lcol=0x7f7f7f;
3993    else         vertex[0].c.lcol=0xffffff;
3994    vertex[0].c.col[3]=ubGloAlpha;
3995    SETCOL(vertex[0]); 
3996
3997    PRIMdrawTexturedTri(&vertex[0], &vertex[1], &vertex[2]);
3998
3999    if(ubOpaqueDraw)
4000     {
4001      SetZMask3O();
4002      DEFOPAQUEON
4003      PRIMdrawTexturedTri(&vertex[0], &vertex[1], &vertex[2]);
4004      DEFOPAQUEOFF
4005     }
4006    return; 
4007   }
4008
4009  if(!bUseMultiPass  && !bGLBlend)
4010   {
4011    vertex[0].c.lcol=DoubleBGR2RGB(gpuData[0]); 
4012    vertex[1].c.lcol=DoubleBGR2RGB(gpuData[3]); 
4013    vertex[2].c.lcol=DoubleBGR2RGB(gpuData[6]);
4014   }
4015  else
4016   {
4017    vertex[0].c.lcol=gpuData[0];
4018    vertex[1].c.lcol=gpuData[3];
4019    vertex[2].c.lcol=gpuData[6];
4020   }
4021  vertex[0].c.col[3]=vertex[1].c.col[3]=vertex[2].c.col[3]=ubGloAlpha;
4022
4023  PRIMdrawTexGouraudTriColor(&vertex[0], &vertex[1], &vertex[2]);
4024
4025  if(bDrawMultiPass)
4026   {
4027    SetSemiTransMulti(1);
4028    PRIMdrawTexGouraudTriColor(&vertex[0], &vertex[1], &vertex[2]);
4029   }
4030
4031  if(ubOpaqueDraw)
4032   {
4033    SetZMask3O();
4034    if(bUseMultiPass) 
4035     {
4036      vertex[0].c.lcol=DoubleBGR2RGB(gpuData[0]);
4037      vertex[1].c.lcol=DoubleBGR2RGB(gpuData[3]);
4038      vertex[2].c.lcol=DoubleBGR2RGB(gpuData[6]);
4039      vertex[0].c.col[3]=vertex[1].c.col[3]=vertex[2].c.col[3]=ubGloAlpha;
4040     }
4041    DEFOPAQUEON
4042    PRIMdrawTexGouraudTriColor(&vertex[0], &vertex[1], &vertex[2]);
4043    DEFOPAQUEOFF
4044   }
4045
4046  iDrawnSomething=1;
4047 }
4048
4049 ////////////////////////////////////////////////////////////////////////
4050 // cmd: smooth shaded Poly3
4051 ////////////////////////////////////////////////////////////////////////
4052
4053 void primPolyG3(unsigned char *baseAddr)
4054 {    
4055  uint32_t *gpuData = ((uint32_t *)baseAddr);
4056  short *sgpuData = ((short *) baseAddr);
4057
4058  lx0 = sgpuData[2];
4059  ly0 = sgpuData[3];
4060  lx1 = sgpuData[6];
4061  ly1 = sgpuData[7];
4062  lx2 = sgpuData[10];
4063  ly2 = sgpuData[11];
4064
4065  if(offset3()) return;
4066
4067  bDrawTextured = FALSE;
4068  bDrawSmoothShaded = TRUE;
4069  SetRenderState(gpuData[0]);
4070
4071  if(iOffscreenDrawing) 
4072   {
4073    offsetPSX3();
4074    if(bDrawOffscreen3())
4075     {
4076      InvalidateTextureAreaEx();   
4077      drawPoly3G(gpuData[0], gpuData[2], gpuData[4]);
4078     }
4079   }
4080
4081  SetRenderMode(gpuData[0], FALSE);
4082  SetZMask3NT();
4083
4084  vertex[0].c.lcol=gpuData[0];
4085  vertex[1].c.lcol=gpuData[2];
4086  vertex[2].c.lcol=gpuData[4];
4087  vertex[0].c.col[3]=vertex[1].c.col[3]=vertex[2].c.col[3]=ubGloColAlpha; 
4088
4089  PRIMdrawGouraudTriColor(&vertex[0], &vertex[1], &vertex[2]);
4090
4091  iDrawnSomething=1;
4092 }
4093
4094 ////////////////////////////////////////////////////////////////////////
4095 // cmd: smooth shaded Texture4
4096 ////////////////////////////////////////////////////////////////////////
4097
4098 void primPolyGT4(unsigned char *baseAddr)
4099
4100  uint32_t *gpuData = ((uint32_t *)baseAddr);
4101  short *sgpuData = ((short *)baseAddr);
4102
4103  lx0 = sgpuData[2];
4104  ly0 = sgpuData[3];
4105  lx1 = sgpuData[8];
4106  ly1 = sgpuData[9];
4107  lx2 = sgpuData[14];
4108  ly2 = sgpuData[15];
4109  lx3 = sgpuData[20];
4110  ly3 = sgpuData[21];
4111
4112  if(offset4()) return;
4113
4114  // do texture stuff
4115  gl_ux[0]=baseAddr[8];//gpuData[2]&0xff;
4116  gl_vy[0]=baseAddr[9];//(gpuData[2]>>8)&0xff;
4117  gl_ux[1]=baseAddr[20];//gpuData[5]&0xff;
4118  gl_vy[1]=baseAddr[21];//(gpuData[5]>>8)&0xff;
4119  gl_ux[2]=baseAddr[32];//gpuData[8]&0xff;
4120  gl_vy[2]=baseAddr[33];//(gpuData[8]>>8)&0xff;
4121  gl_ux[3]=baseAddr[44];//gpuData[11]&0xff;
4122  gl_vy[3]=baseAddr[45];//(gpuData[11]>>8)&0xff;
4123
4124  UpdateGlobalTP((unsigned short)(gpuData[5]>>16));
4125  ulClutID=(gpuData[2]>>16);
4126
4127  bDrawTextured     = TRUE;
4128  bDrawSmoothShaded = TRUE;
4129  SetRenderState(gpuData[0]);
4130
4131  if(iOffscreenDrawing)
4132   {
4133    offsetPSX4();
4134    if(bDrawOffscreen4())
4135     {
4136      InvalidateTextureAreaEx();   
4137      drawPoly4GT(baseAddr);
4138     }     
4139   }
4140
4141  SetRenderMode(gpuData[0], FALSE);
4142  SetZMask4();
4143
4144  assignTexture4();
4145
4146  RectTexAlign();
4147
4148  if(bDrawNonShaded)
4149   {
4150    //if(!bUseMultiPass) vertex[0].lcol=DoubleBGR2RGB(gpuData[0]); else vertex[0].lcol=gpuData[0];
4151    if(bGLBlend) vertex[0].c.lcol=0x7f7f7f;
4152    else          vertex[0].c.lcol=0xffffff;
4153    vertex[0].c.col[3]=ubGloAlpha;
4154    SETCOL(vertex[0]); 
4155
4156    PRIMdrawTexturedQuad(&vertex[0], &vertex[1], &vertex[3], &vertex[2]);
4157   
4158    if(ubOpaqueDraw)
4159     {
4160      SetZMask4O();
4161      ubGloAlpha=ubGloColAlpha=0xff;   
4162      DEFOPAQUEON
4163      PRIMdrawTexturedQuad(&vertex[0], &vertex[1], &vertex[3], &vertex[2]);
4164      DEFOPAQUEOFF
4165     }
4166    return;
4167   }
4168
4169  if(!bUseMultiPass  && !bGLBlend) 
4170   {
4171    vertex[0].c.lcol=DoubleBGR2RGB(gpuData[0]);
4172    vertex[1].c.lcol=DoubleBGR2RGB(gpuData[3]);
4173    vertex[2].c.lcol=DoubleBGR2RGB(gpuData[6]);
4174    vertex[3].c.lcol=DoubleBGR2RGB(gpuData[9]);
4175   }
4176  else
4177   {
4178    vertex[0].c.lcol=gpuData[0];
4179    vertex[1].c.lcol=gpuData[3];
4180    vertex[2].c.lcol=gpuData[6];
4181    vertex[3].c.lcol=gpuData[9];
4182   }
4183
4184  vertex[0].c.col[3]=vertex[1].c.col[3]=vertex[2].c.col[3]=vertex[3].c.col[3]=ubGloAlpha; 
4185
4186  PRIMdrawTexGouraudTriColorQuad(&vertex[0], &vertex[1], &vertex[3],&vertex[2]);
4187  
4188  if(bDrawMultiPass)
4189   {
4190    SetSemiTransMulti(1);
4191    PRIMdrawTexGouraudTriColorQuad(&vertex[0], &vertex[1], &vertex[3],&vertex[2]);
4192   }
4193
4194  if(ubOpaqueDraw)
4195   {
4196    SetZMask4O();
4197    if(bUseMultiPass) 
4198     {
4199      vertex[0].c.lcol=DoubleBGR2RGB(gpuData[0]);
4200      vertex[1].c.lcol=DoubleBGR2RGB(gpuData[3]);
4201      vertex[2].c.lcol=DoubleBGR2RGB(gpuData[6]);
4202      vertex[3].c.lcol=DoubleBGR2RGB(gpuData[9]);
4203      vertex[0].c.col[3]=vertex[1].c.col[3]=vertex[2].c.col[3]=vertex[3].c.col[3]=ubGloAlpha; 
4204     }
4205    ubGloAlpha=ubGloColAlpha=0xff;   
4206    DEFOPAQUEON
4207    PRIMdrawTexGouraudTriColorQuad(&vertex[0], &vertex[1], &vertex[3],&vertex[2]);
4208    DEFOPAQUEOFF
4209   }
4210
4211  iDrawnSomething=1;
4212 }
4213
4214 ////////////////////////////////////////////////////////////////////////
4215 // cmd: smooth shaded Poly3
4216 ////////////////////////////////////////////////////////////////////////
4217
4218 void primPolyF3(unsigned char *baseAddr)
4219 {    
4220  uint32_t *gpuData = ((uint32_t *) baseAddr);
4221  short *sgpuData = ((short *) baseAddr);
4222
4223  lx0 = sgpuData[2];
4224  ly0 = sgpuData[3];
4225  lx1 = sgpuData[4];
4226  ly1 = sgpuData[5];
4227  lx2 = sgpuData[6];
4228  ly2 = sgpuData[7];
4229
4230  if(offset3()) return;
4231
4232  bDrawTextured     = FALSE;
4233  bDrawSmoothShaded = FALSE;
4234  SetRenderState(gpuData[0]);
4235
4236  if(iOffscreenDrawing)
4237   {
4238    offsetPSX3();
4239    if(bDrawOffscreen3())
4240     {
4241      InvalidateTextureAreaEx();   
4242      drawPoly3F(gpuData[0]);
4243     }
4244   }
4245
4246  SetRenderMode(gpuData[0], FALSE);
4247  SetZMask3NT();
4248
4249  vertex[0].c.lcol=gpuData[0];
4250  vertex[0].c.col[3]=ubGloColAlpha;
4251  SETCOL(vertex[0]); 
4252
4253  PRIMdrawTri(&vertex[0], &vertex[1], &vertex[2]);
4254
4255  iDrawnSomething=1;
4256 }
4257
4258 ////////////////////////////////////////////////////////////////////////
4259 // cmd: skipping shaded polylines
4260 ////////////////////////////////////////////////////////////////////////
4261
4262 void primLineGSkip(unsigned char *baseAddr)
4263 {    
4264  uint32_t *gpuData = ((uint32_t *) baseAddr);
4265  short *sgpuData = ((short *) baseAddr);
4266  int iMax=255;
4267  int i=2;
4268
4269  lx1 = sgpuData[2];
4270  ly1 = sgpuData[3];
4271 \r
4272  while(!(((gpuData[i] & 0xF000F000) == 0x50005000) && i>=4))\r
4273   {
4274    i++;
4275
4276    ly1 = (short)((gpuData[i]>>16) & 0xffff);
4277    lx1 = (short)(gpuData[i] & 0xffff);
4278
4279    i++;if(i>iMax) break;
4280   }
4281 }
4282
4283 ////////////////////////////////////////////////////////////////////////
4284 // cmd: shaded polylines
4285 ////////////////////////////////////////////////////////////////////////
4286
4287 void primLineGEx(unsigned char *baseAddr)
4288 {    
4289  uint32_t *gpuData = ((uint32_t *) baseAddr);
4290  int iMax=255;
4291  short cx0,cx1,cy0,cy1;int i;BOOL bDraw=TRUE;
4292
4293  bDrawTextured = FALSE;
4294  bDrawSmoothShaded = TRUE;
4295  SetRenderState(gpuData[0]);
4296  SetRenderMode(gpuData[0], FALSE);
4297  SetZMask4NT();
4298
4299  vertex[0].c.lcol=vertex[3].c.lcol=gpuData[0];
4300  vertex[0].c.col[3]=vertex[3].c.col[3]=ubGloColAlpha; 
4301  ly1 = (short)((gpuData[1]>>16) & 0xffff);
4302  lx1 = (short)(gpuData[1] & 0xffff);
4303
4304  i=2;
4305 \r
4306  //while((gpuData[i]>>24)!=0x55)
4307  //while((gpuData[i]&0x50000000)!=0x50000000) \r
4308  // currently best way to check for poly line end:\r
4309  while(!(((gpuData[i] & 0xF000F000) == 0x50005000) && i>=4))\r
4310   {
4311    ly0 = ly1;lx0=lx1;
4312    vertex[1].c.lcol=vertex[2].c.lcol=vertex[0].c.lcol;
4313    vertex[0].c.lcol=vertex[3].c.lcol=gpuData[i];
4314    vertex[0].c.col[3]=vertex[3].c.col[3]=ubGloColAlpha; 
4315
4316    i++;
4317
4318    ly1 = (short)((gpuData[i]>>16) & 0xffff);
4319    lx1 = (short)(gpuData[i] & 0xffff);
4320 \r
4321    if(offsetline()) bDraw=FALSE; else bDraw=TRUE;\r
4322   
4323    if (bDraw && ((lx0 != lx1) || (ly0 != ly1)))
4324     {
4325      if(iOffscreenDrawing)
4326       {
4327        cx0=lx0;cx1=lx1;cy0=ly0;cy1=ly1;
4328        offsetPSXLine();
4329        if(bDrawOffscreen4())
4330         {
4331          InvalidateTextureAreaEx();   
4332          drawPoly4G(gpuData[i-3],gpuData[i-1],gpuData[i-3],gpuData[i-1]);
4333         }
4334        lx0=cx0;lx1=cx1;ly0=cy0;ly1=cy1;
4335       }
4336
4337      PRIMdrawGouraudLine(&vertex[0], &vertex[1], &vertex[2], &vertex[3]);
4338     }
4339    i++;  
4340
4341    if(i>iMax) break;
4342   }
4343
4344  iDrawnSomething=1;
4345 }
4346
4347 ////////////////////////////////////////////////////////////////////////
4348 // cmd: shaded polyline2
4349 ////////////////////////////////////////////////////////////////////////
4350
4351 void primLineG2(unsigned char *baseAddr)
4352 {    
4353  uint32_t *gpuData = ((uint32_t *) baseAddr);
4354  short *sgpuData = ((short *) baseAddr);
4355
4356  lx0 = sgpuData[2];
4357  ly0 = sgpuData[3];
4358  lx1 = sgpuData[6];
4359  ly1 = sgpuData[7];
4360
4361  vertex[0].c.lcol=vertex[3].c.lcol=gpuData[0];
4362  vertex[1].c.lcol=vertex[2].c.lcol=gpuData[2];
4363  vertex[0].c.col[3]=vertex[1].c.col[3]=vertex[2].c.col[3]=vertex[3].c.col[3]=ubGloColAlpha; 
4364
4365  bDrawTextured = FALSE;
4366  bDrawSmoothShaded = TRUE;
4367
4368  if((lx0 == lx1) && (ly0 == ly1)) return;
4369     
4370  if(offsetline()) return;
4371     
4372  SetRenderState(gpuData[0]);
4373  SetRenderMode(gpuData[0], FALSE);
4374  SetZMask4NT();
4375
4376  if(iOffscreenDrawing)
4377   {
4378    offsetPSXLine();
4379    if(bDrawOffscreen4())
4380     {
4381      InvalidateTextureAreaEx();   
4382      drawPoly4G(gpuData[0],gpuData[2],gpuData[0],gpuData[2]);
4383     }
4384   }
4385
4386  //if(ClipVertexList4())
4387  PRIMdrawGouraudLine(&vertex[0], &vertex[1], &vertex[2], &vertex[3]);
4388
4389  iDrawnSomething=1;
4390 }
4391
4392 ////////////////////////////////////////////////////////////////////////
4393 // cmd: skipping flat polylines
4394 ////////////////////////////////////////////////////////////////////////
4395
4396 void primLineFSkip(unsigned char *baseAddr)
4397 {
4398  uint32_t *gpuData = ((uint32_t *) baseAddr);
4399  int i=2,iMax=255;
4400
4401  ly1 = (short)((gpuData[1]>>16) & 0xffff);
4402  lx1 = (short)(gpuData[1] & 0xffff);
4403
4404  while(!(((gpuData[i] & 0xF000F000) == 0x50005000) && i>=3))\r
4405   {
4406    ly1 = (short)((gpuData[i]>>16) & 0xffff);
4407    lx1 = (short)(gpuData[i] & 0xffff);
4408    i++;if(i>iMax) break;
4409   }             
4410 }
4411
4412 ////////////////////////////////////////////////////////////////////////
4413 // cmd: drawing flat polylines
4414 ////////////////////////////////////////////////////////////////////////
4415
4416 void primLineFEx(unsigned char *baseAddr)
4417 {
4418  uint32_t *gpuData = ((uint32_t *) baseAddr);
4419  int iMax;
4420  short cx0,cx1,cy0,cy1;int i;
4421
4422  iMax=255;
4423
4424  bDrawTextured = FALSE;
4425  bDrawSmoothShaded = FALSE;
4426  SetRenderState(gpuData[0]);
4427  SetRenderMode(gpuData[0], FALSE);
4428  SetZMask4NT();
4429
4430  vertex[0].c.lcol=gpuData[0];
4431  vertex[0].c.col[3]=ubGloColAlpha; 
4432
4433  ly1 = (short)((gpuData[1]>>16) & 0xffff);
4434  lx1 = (short)(gpuData[1] & 0xffff);
4435
4436  i=2;
4437
4438 // while(!(gpuData[i]&0x40000000)) 
4439 // while((gpuData[i]>>24)!=0x55)
4440 // while((gpuData[i]&0x50000000)!=0x50000000) 
4441 // currently best way to check for poly line end:
4442  while(!(((gpuData[i] & 0xF000F000) == 0x50005000) && i>=3))\r
4443   {
4444    ly0 = ly1;lx0=lx1;
4445    ly1 = (short)((gpuData[i]>>16) & 0xffff);
4446    lx1 = (short)(gpuData[i] & 0xffff);
4447 \r
4448    if(!offsetline())\r
4449     {
4450      if(iOffscreenDrawing)
4451       {
4452        cx0=lx0;cx1=lx1;cy0=ly0;cy1=ly1;
4453        offsetPSXLine();
4454        if(bDrawOffscreen4())
4455         {
4456          InvalidateTextureAreaEx();   
4457          drawPoly4F(gpuData[0]);
4458         }
4459        lx0=cx0;lx1=cx1;ly0=cy0;ly1=cy1;
4460       }
4461      PRIMdrawFlatLine(&vertex[0], &vertex[1], &vertex[2], &vertex[3]);
4462     }\r
4463                   
4464    i++;if(i>iMax) break;
4465   }
4466
4467  iDrawnSomething=1;
4468 }
4469
4470 ////////////////////////////////////////////////////////////////////////
4471 // cmd: drawing flat polyline2
4472 ////////////////////////////////////////////////////////////////////////
4473
4474 void primLineF2(unsigned char *baseAddr)
4475 {
4476  uint32_t *gpuData = ((uint32_t *) baseAddr);
4477  short *sgpuData = ((short *) baseAddr);
4478
4479  lx0 = sgpuData[2];
4480  ly0 = sgpuData[3];
4481  lx1 = sgpuData[4];
4482  ly1 = sgpuData[5];
4483
4484  if(offsetline()) return;
4485
4486  bDrawTextured = FALSE;
4487  bDrawSmoothShaded = FALSE;
4488  SetRenderState(gpuData[0]);
4489  SetRenderMode(gpuData[0], FALSE);
4490  SetZMask4NT();
4491
4492  vertex[0].c.lcol=gpuData[0];
4493  vertex[0].c.col[3]=ubGloColAlpha; 
4494
4495  if(iOffscreenDrawing)
4496   {
4497    offsetPSXLine();
4498    if(bDrawOffscreen4())
4499     {
4500      InvalidateTextureAreaEx();   
4501      drawPoly4F(gpuData[0]);
4502     }
4503   }
4504
4505  //if(ClipVertexList4()) 
4506  PRIMdrawFlatLine(&vertex[0], &vertex[1], &vertex[2], &vertex[3]);
4507
4508  iDrawnSomething=1;
4509 }
4510
4511 ////////////////////////////////////////////////////////////////////////
4512 // cmd: well, easiest command... not implemented
4513 ////////////////////////////////////////////////////////////////////////
4514
4515 void primNI(unsigned char *bA)
4516 {
4517 }
4518
4519 ////////////////////////////////////////////////////////////////////////
4520 // cmd func ptr table
4521 ////////////////////////////////////////////////////////////////////////
4522
4523 void (*primTableJ[256])(unsigned char *) = 
4524 {
4525     // 00
4526     primNI,primNI,primBlkFill,primNI,primNI,primNI,primNI,primNI,
4527     // 08
4528     primNI,primNI,primNI,primNI,primNI,primNI,primNI,primNI,
4529     // 10
4530     primNI,primNI,primNI,primNI,primNI,primNI,primNI,primNI,
4531     // 18
4532     primNI,primNI,primNI,primNI,primNI,primNI,primNI,primNI,
4533     // 20
4534     primPolyF3,primPolyF3,primPolyF3,primPolyF3,primPolyFT3,primPolyFT3,primPolyFT3,primPolyFT3,
4535     // 28
4536     primPolyF4,primPolyF4,primPolyF4,primPolyF4,primPolyFT4,primPolyFT4,primPolyFT4,primPolyFT4,
4537     // 30
4538     primPolyG3,primPolyG3,primPolyG3,primPolyG3,primPolyGT3,primPolyGT3,primPolyGT3,primPolyGT3,
4539     // 38
4540     primPolyG4,primPolyG4,primPolyG4,primPolyG4,primPolyGT4,primPolyGT4,primPolyGT4,primPolyGT4,
4541     // 40
4542     primLineF2,primLineF2,primLineF2,primLineF2,primNI,primNI,primNI,primNI,
4543     // 48
4544     primLineFEx,primLineFEx,primLineFEx,primLineFEx,primLineFEx,primLineFEx,primLineFEx,primLineFEx,
4545     // 50
4546     primLineG2,primLineG2,primLineG2,primLineG2,primNI,primNI,primNI,primNI,
4547     // 58
4548     primLineGEx,primLineGEx,primLineGEx,primLineGEx,primLineGEx,primLineGEx,primLineGEx,primLineGEx,
4549     // 60
4550     primTileS,primTileS,primTileS,primTileS,primSprtS,primSprtS,primSprtS,primSprtS,
4551     // 68
4552     primTile1,primTile1,primTile1,primTile1,primNI,primNI,primNI,primNI,
4553     // 70
4554     primTile8,primTile8,primTile8,primTile8,primSprt8,primSprt8,primSprt8,primSprt8,
4555     // 78
4556     primTile16,primTile16,primTile16,primTile16,primSprt16,primSprt16,primSprt16,primSprt16,
4557     // 80
4558     primMoveImage,primNI,primNI,primNI,primNI,primNI,primNI,primNI,
4559     // 88
4560     primNI,primNI,primNI,primNI,primNI,primNI,primNI,primNI,
4561     // 90
4562     primNI,primNI,primNI,primNI,primNI,primNI,primNI,primNI,
4563     // 98
4564     primNI,primNI,primNI,primNI,primNI,primNI,primNI,primNI,
4565     // a0
4566     primLoadImage,primNI,primNI,primNI,primNI,primNI,primNI,primNI,
4567     // a8
4568     primNI,primNI,primNI,primNI,primNI,primNI,primNI,primNI,
4569     // b0
4570     primNI,primNI,primNI,primNI,primNI,primNI,primNI,primNI,
4571     // b8
4572     primNI,primNI,primNI,primNI,primNI,primNI,primNI,primNI,
4573     // c0
4574     primStoreImage,primNI,primNI,primNI,primNI,primNI,primNI,primNI,
4575     // c8
4576     primNI,primNI,primNI,primNI,primNI,primNI,primNI,primNI,
4577     // d0
4578     primNI,primNI,primNI,primNI,primNI,primNI,primNI,primNI,
4579     // d8
4580     primNI,primNI,primNI,primNI,primNI,primNI,primNI,primNI,
4581     // e0
4582     primNI,cmdTexturePage,cmdTextureWindow,cmdDrawAreaStart,cmdDrawAreaEnd,cmdDrawOffset,cmdSTP,primNI,
4583     // e8
4584     primNI,primNI,primNI,primNI,primNI,primNI,primNI,primNI,
4585     // f0
4586     primNI,primNI,primNI,primNI,primNI,primNI,primNI,primNI,
4587     // f8
4588     primNI,primNI,primNI,primNI,primNI,primNI,primNI,primNI
4589 };
4590
4591 ////////////////////////////////////////////////////////////////////////
4592 // cmd func ptr table for skipping
4593 ////////////////////////////////////////////////////////////////////////
4594
4595 void (*primTableSkip[256])(unsigned char *) = 
4596 {
4597     // 00
4598     primNI,primNI,primBlkFill,primNI,primNI,primNI,primNI,primNI,
4599     // 08
4600     primNI,primNI,primNI,primNI,primNI,primNI,primNI,primNI,
4601     // 10
4602     primNI,primNI,primNI,primNI,primNI,primNI,primNI,primNI,
4603     // 18
4604     primNI,primNI,primNI,primNI,primNI,primNI,primNI,primNI,
4605     // 20
4606     primNI,primNI,primNI,primNI,primNI,primNI,primNI,primNI,
4607     // 28
4608     primNI,primNI,primNI,primNI,primNI,primNI,primNI,primNI,
4609     // 30
4610     primNI,primNI,primNI,primNI,primNI,primNI,primNI,primNI,
4611     // 38
4612     primNI,primNI,primNI,primNI,primNI,primNI,primNI,primNI,
4613     // 40
4614     primNI,primNI,primNI,primNI,primNI,primNI,primNI,primNI,
4615     // 48
4616     primLineFSkip,primLineFSkip,primLineFSkip,primLineFSkip,primLineFSkip,primLineFSkip,primLineFSkip,primLineFSkip,
4617     // 50
4618     primNI,primNI,primNI,primNI,primNI,primNI,primNI,primNI,
4619     // 58
4620     primLineGSkip,primLineGSkip,primLineGSkip,primLineGSkip,primLineGSkip,primLineGSkip,primLineGSkip,primLineGSkip,
4621     // 60
4622     primNI,primNI,primNI,primNI,primNI,primNI,primNI,primNI,
4623     // 68
4624     primNI,primNI,primNI,primNI,primNI,primNI,primNI,primNI,
4625     // 70
4626     primNI,primNI,primNI,primNI,primNI,primNI,primNI,primNI,
4627     // 78
4628     primNI,primNI,primNI,primNI,primNI,primNI,primNI,primNI,
4629     // 80
4630     primMoveImage,primNI,primNI,primNI,primNI,primNI,primNI,primNI,
4631     // 88
4632     primNI,primNI,primNI,primNI,primNI,primNI,primNI,primNI,
4633     // 90
4634     primNI,primNI,primNI,primNI,primNI,primNI,primNI,primNI,
4635     // 98
4636     primNI,primNI,primNI,primNI,primNI,primNI,primNI,primNI,
4637     // a0
4638     primLoadImage,primNI,primNI,primNI,primNI,primNI,primNI,primNI,
4639     // a8
4640     primNI,primNI,primNI,primNI,primNI,primNI,primNI,primNI,
4641     // b0
4642     primNI,primNI,primNI,primNI,primNI,primNI,primNI,primNI,
4643     // b8
4644     primNI,primNI,primNI,primNI,primNI,primNI,primNI,primNI,
4645     // c0
4646     primStoreImage,primNI,primNI,primNI,primNI,primNI,primNI,primNI,
4647     // c8
4648     primNI,primNI,primNI,primNI,primNI,primNI,primNI,primNI,
4649     // d0
4650     primNI,primNI,primNI,primNI,primNI,primNI,primNI,primNI,
4651     // d8
4652     primNI,primNI,primNI,primNI,primNI,primNI,primNI,primNI,
4653     // e0
4654     primNI,cmdTexturePage,cmdTextureWindow,cmdDrawAreaStart,cmdDrawAreaEnd,cmdDrawOffset,cmdSTP,primNI,
4655     // e8
4656     primNI,primNI,primNI,primNI,primNI,primNI,primNI,primNI,
4657     // f0
4658     primNI,primNI,primNI,primNI,primNI,primNI,primNI,primNI,
4659     // f8
4660     primNI,primNI,primNI,primNI,primNI,primNI,primNI,primNI
4661 };