dfxvideo: make fskip update on vsync too
[pcsx_rearmed.git] / plugins / dfxvideo / soft.c
1 /***************************************************************************
2                           soft.c  -  description
3                              -------------------
4     begin                : Sun Oct 28 2001
5     copyright            : (C) 2001 by Pete Bernert
6     email                : BlackDove@addcom.de
7  ***************************************************************************/
8 /***************************************************************************
9  *                                                                         *
10  *   This program is free software; you can redistribute it and/or modify  *
11  *   it under the terms of the GNU General Public License as published by  *
12  *   the Free Software Foundation; either version 2 of the License, or     *
13  *   (at your option) any later version. See also the license.txt file for *
14  *   additional informations.                                              *
15  *                                                                         *
16  ***************************************************************************/
17
18 // switches for painting textured quads as 2 triangles (small glitches, but better shading!)
19 // can be toggled by game fix 0x200 in version 1.17 anyway, so let the defines enabled!
20 #define POLYQUAD3                 
21 #define POLYQUAD3GT                 
22
23 // fast solid loops... a bit more additional code, of course
24 #define FASTSOLID
25
26 // psx blending mode 3 with 25% incoming color (instead 50% without the define)
27 #define HALFBRIGHTMODE3
28
29 // color decode defines
30
31 #define XCOL1(x)     (x & 0x1f)
32 #define XCOL2(x)     (x & 0x3e0)
33 #define XCOL3(x)     (x & 0x7c00)
34
35 #define XCOL1D(x)     (x & 0x1f)
36 #define XCOL2D(x)     ((x>>5) & 0x1f)
37 #define XCOL3D(x)     ((x>>10) & 0x1f)
38
39 #define X32TCOL1(x)  ((x & 0x001f001f)<<7)
40 #define X32TCOL2(x)  ((x & 0x03e003e0)<<2)
41 #define X32TCOL3(x)  ((x & 0x7c007c00)>>3)
42
43 #define X32COL1(x)   (x & 0x001f001f)
44 #define X32COL2(x)   ((x>>5) & 0x001f001f)
45 #define X32COL3(x)   ((x>>10) & 0x001f001f)
46
47 #define X32ACOL1(x)  (x & 0x001e001e)
48 #define X32ACOL2(x)  ((x>>5) & 0x001e001e)
49 #define X32ACOL3(x)  ((x>>10) & 0x001e001e)
50
51 #define X32BCOL1(x)  (x & 0x001c001c)
52 #define X32BCOL2(x)  ((x>>5) & 0x001c001c)
53 #define X32BCOL3(x)  ((x>>10) & 0x001c001c)
54
55 #define X32PSXCOL(r,g,b) ((g<<10)|(b<<5)|r)
56
57 #define XPSXCOL(r,g,b) ((g&0x7c00)|(b&0x3e0)|(r&0x1f))
58
59 // soft globals
60 short g_m1=255,g_m2=255,g_m3=255;
61 short DrawSemiTrans=FALSE;
62 short Ymin;
63 short Ymax;
64 short          ly0,lx0,ly1,lx1,ly2,lx2,ly3,lx3;        // global psx vertex coords
65 int32_t           GlobalTextAddrX,GlobalTextAddrY,GlobalTextTP,GlobalTextIL;
66 int32_t           GlobalTextREST,GlobalTextABR,GlobalTextPAGE;
67
68 ////////////////////////////////////////////////////////////////////////
69 // POLYGON OFFSET FUNCS
70 ////////////////////////////////////////////////////////////////////////
71
72 static void offsetPSX2(void)
73 {
74  lx0 += PSXDisplay.DrawOffset.x;
75  ly0 += PSXDisplay.DrawOffset.y;
76  lx1 += PSXDisplay.DrawOffset.x;
77  ly1 += PSXDisplay.DrawOffset.y;
78 }
79
80 static void offsetPSX3(void)
81 {
82  lx0 += PSXDisplay.DrawOffset.x;
83  ly0 += PSXDisplay.DrawOffset.y;
84  lx1 += PSXDisplay.DrawOffset.x;
85  ly1 += PSXDisplay.DrawOffset.y;
86  lx2 += PSXDisplay.DrawOffset.x;
87  ly2 += PSXDisplay.DrawOffset.y;
88 }
89
90 static void offsetPSX4(void)
91 {
92  lx0 += PSXDisplay.DrawOffset.x;
93  ly0 += PSXDisplay.DrawOffset.y;
94  lx1 += PSXDisplay.DrawOffset.x;
95  ly1 += PSXDisplay.DrawOffset.y;
96  lx2 += PSXDisplay.DrawOffset.x;
97  ly2 += PSXDisplay.DrawOffset.y;
98  lx3 += PSXDisplay.DrawOffset.x;
99  ly3 += PSXDisplay.DrawOffset.y;
100 }
101
102 /////////////////////////////////////////////////////////////////
103 /////////////////////////////////////////////////////////////////
104 /////////////////////////////////////////////////////////////////
105 // PER PIXEL FUNCS
106 ////////////////////////////////////////////////////////////////////////
107 /////////////////////////////////////////////////////////////////
108 /////////////////////////////////////////////////////////////////
109
110
111 unsigned char dithertable[16] =
112 {
113     7, 0, 6, 1,
114     2, 5, 3, 4,
115     1, 6, 0, 7,
116     4, 3, 5, 2
117 };
118
119 static inline void Dither16(unsigned short * pdest,uint32_t r,uint32_t g,uint32_t b,unsigned short sM)
120 {
121  unsigned char coeff;
122  unsigned char rlow, glow, blow;
123  int x,y;
124                  
125  x=pdest-psxVuw;
126  y=x>>10;
127  x-=(y<<10);
128
129  coeff = dithertable[(y&3)*4+(x&3)];
130
131  rlow = r&7; glow = g&7; blow = b&7;
132
133  r>>=3; g>>=3; b>>=3;
134
135  if ((r < 0x1F) && rlow > coeff) r++;
136  if ((g < 0x1F) && glow > coeff) g++;
137  if ((b < 0x1F) && blow > coeff) b++;
138
139  PUTLE16(pdest, ((unsigned short)b<<10) |
140         ((unsigned short)g<<5) |
141         (unsigned short)r | sM);
142 }
143
144 /////////////////////////////////////////////////////////////////
145 /////////////////////////////////////////////////////////////////
146 /////////////////////////////////////////////////////////////////
147
148 static inline void GetShadeTransCol_Dither(unsigned short * pdest, int32_t m1, int32_t m2, int32_t m3)
149 {
150  int32_t r,g,b;
151
152  if(bCheckMask && (*pdest & HOST2LE16(0x8000))) return;
153
154  if(DrawSemiTrans)
155   {
156    r=((XCOL1D(GETLE16(pdest)))<<3);
157    b=((XCOL2D(GETLE16(pdest)))<<3);
158    g=((XCOL3D(GETLE16(pdest)))<<3);
159
160    if(GlobalTextABR==0)
161     {
162      r=(r>>1)+(m1>>1);
163      b=(b>>1)+(m2>>1);
164      g=(g>>1)+(m3>>1);
165     }
166    else
167    if(GlobalTextABR==1)
168     {
169      r+=m1;
170      b+=m2;
171      g+=m3;
172     }
173    else
174    if(GlobalTextABR==2)
175     {
176      r-=m1;
177      b-=m2;
178      g-=m3;
179      if(r&0x80000000) r=0;
180      if(b&0x80000000) b=0;
181      if(g&0x80000000) g=0;
182     }
183    else
184     {
185 #ifdef HALFBRIGHTMODE3
186      r+=(m1>>2);
187      b+=(m2>>2);
188      g+=(m3>>2);
189 #else
190      r+=(m1>>1);
191      b+=(m2>>1);
192      g+=(m3>>1);
193 #endif
194     }
195   }
196  else 
197   {
198    r=m1;
199    b=m2;
200    g=m3;
201   }
202
203  if(r&0x7FFFFF00) r=0xff;
204  if(b&0x7FFFFF00) b=0xff;
205  if(g&0x7FFFFF00) g=0xff;
206
207  Dither16(pdest,r,b,g,sSetMask);
208 }
209
210 ////////////////////////////////////////////////////////////////////////
211
212 static inline void GetShadeTransCol(unsigned short * pdest,unsigned short color)
213 {
214  if(bCheckMask && (*pdest & HOST2LE16(0x8000))) return;
215
216  if(DrawSemiTrans)
217   {
218    int32_t r,g,b;
219  
220    if(GlobalTextABR==0)
221     {
222      PUTLE16(pdest, (((GETLE16(pdest)&0x7bde)>>1)+(((color)&0x7bde)>>1))|sSetMask);//0x8000;
223      return;
224     }
225    else
226    if(GlobalTextABR==1)
227     {
228      r=(XCOL1(GETLE16(pdest)))+((XCOL1(color)));
229      b=(XCOL2(GETLE16(pdest)))+((XCOL2(color)));
230      g=(XCOL3(GETLE16(pdest)))+((XCOL3(color)));
231     }
232    else
233    if(GlobalTextABR==2)
234     {
235      r=(XCOL1(GETLE16(pdest)))-((XCOL1(color)));
236      b=(XCOL2(GETLE16(pdest)))-((XCOL2(color)));
237      g=(XCOL3(GETLE16(pdest)))-((XCOL3(color)));
238      if(r&0x80000000) r=0;
239      if(b&0x80000000) b=0;
240      if(g&0x80000000) g=0;
241    }
242    else
243     {
244 #ifdef HALFBRIGHTMODE3
245      r=(XCOL1(GETLE16(pdest)))+((XCOL1(color))>>2);
246      b=(XCOL2(GETLE16(pdest)))+((XCOL2(color))>>2);
247      g=(XCOL3(GETLE16(pdest)))+((XCOL3(color))>>2);
248 #else
249      r=(XCOL1(GETLE16(pdest)))+((XCOL1(color))>>1);
250      b=(XCOL2(GETLE16(pdest)))+((XCOL2(color))>>1);
251      g=(XCOL3(GETLE16(pdest)))+((XCOL3(color))>>1);
252 #endif
253     }
254
255    if(r&0x7FFFFFE0) r=0x1f;
256    if(b&0x7FFFFC00) b=0x3e0;
257    if(g&0x7FFF8000) g=0x7c00;
258
259    PUTLE16(pdest, (XPSXCOL(r,g,b))|sSetMask);//0x8000;
260   }
261  else PUTLE16(pdest, color|sSetMask);
262 }  
263
264 ////////////////////////////////////////////////////////////////////////
265
266 static inline void GetShadeTransCol32(uint32_t * pdest,uint32_t color)
267 {
268  if(DrawSemiTrans)
269   {
270    int32_t r,g,b;
271  
272    if(GlobalTextABR==0)
273     {
274      if(!bCheckMask)
275       {
276        PUTLE32(pdest, (((GETLE32(pdest)&0x7bde7bde)>>1)+(((color)&0x7bde7bde)>>1))|lSetMask);//0x80008000;
277        return;
278       }
279      r=(X32ACOL1(GETLE32(pdest))>>1)+((X32ACOL1(color))>>1);
280      b=(X32ACOL2(GETLE32(pdest))>>1)+((X32ACOL2(color))>>1);
281      g=(X32ACOL3(GETLE32(pdest))>>1)+((X32ACOL3(color))>>1);
282     }
283    else
284    if(GlobalTextABR==1)
285     {
286      r=(X32COL1(GETLE32(pdest)))+((X32COL1(color)));
287      b=(X32COL2(GETLE32(pdest)))+((X32COL2(color)));
288      g=(X32COL3(GETLE32(pdest)))+((X32COL3(color)));
289     }
290    else
291    if(GlobalTextABR==2)
292     {
293      int32_t sr,sb,sg,src,sbc,sgc,c;
294      src=XCOL1(color);sbc=XCOL2(color);sgc=XCOL3(color);
295      c=GETLE32(pdest)>>16;
296      sr=(XCOL1(c))-src;   if(sr&0x8000) sr=0;
297      sb=(XCOL2(c))-sbc;  if(sb&0x8000) sb=0;
298      sg=(XCOL3(c))-sgc; if(sg&0x8000) sg=0;
299      r=((int32_t)sr)<<16;b=((int32_t)sb)<<11;g=((int32_t)sg)<<6;
300      c=LOWORD(GETLE32(pdest));
301      sr=(XCOL1(c))-src;   if(sr&0x8000) sr=0;
302      sb=(XCOL2(c))-sbc;  if(sb&0x8000) sb=0;
303      sg=(XCOL3(c))-sgc; if(sg&0x8000) sg=0;
304      r|=sr;b|=sb>>5;g|=sg>>10;
305     }
306    else
307     {
308 #ifdef HALFBRIGHTMODE3
309      r=(X32COL1(GETLE32(pdest)))+((X32BCOL1(color))>>2);
310      b=(X32COL2(GETLE32(pdest)))+((X32BCOL2(color))>>2);
311      g=(X32COL3(GETLE32(pdest)))+((X32BCOL3(color))>>2);
312 #else
313      r=(X32COL1(GETLE32(pdest)))+((X32ACOL1(color))>>1);
314      b=(X32COL2(GETLE32(pdest)))+((X32ACOL2(color))>>1);
315      g=(X32COL3(GETLE32(pdest)))+((X32ACOL3(color))>>1);
316 #endif
317     }
318
319    if(r&0x7FE00000) r=0x1f0000|(r&0xFFFF);
320    if(r&0x7FE0)     r=0x1f    |(r&0xFFFF0000);
321    if(b&0x7FE00000) b=0x1f0000|(b&0xFFFF);
322    if(b&0x7FE0)     b=0x1f    |(b&0xFFFF0000);
323    if(g&0x7FE00000) g=0x1f0000|(g&0xFFFF);
324    if(g&0x7FE0)     g=0x1f    |(g&0xFFFF0000);
325
326    if(bCheckMask) 
327     {
328      uint32_t ma=GETLE32(pdest);
329      PUTLE32(pdest, (X32PSXCOL(r,g,b))|lSetMask);//0x80008000;
330      if(ma&0x80000000) PUTLE32(pdest, (ma&0xFFFF0000)|(*pdest&0xFFFF));
331      if(ma&0x00008000) PUTLE32(pdest, (ma&0xFFFF)    |(*pdest&0xFFFF0000));
332      return;
333     }
334    PUTLE32(pdest, (X32PSXCOL(r,g,b))|lSetMask);//0x80008000;
335   }
336  else 
337   {
338    if(bCheckMask) 
339     {
340      uint32_t ma=GETLE32(pdest);
341      PUTLE32(pdest, color|lSetMask);//0x80008000;
342      if(ma&0x80000000) PUTLE32(pdest, (ma&0xFFFF0000)|(GETLE32(pdest)&0xFFFF));
343      if(ma&0x00008000) PUTLE32(pdest, (ma&0xFFFF)    |(GETLE32(pdest)&0xFFFF0000));
344      return;
345     }
346
347    PUTLE32(pdest, color|lSetMask);//0x80008000;
348   }
349 }  
350
351 ////////////////////////////////////////////////////////////////////////
352
353 static inline void GetTextureTransColG(unsigned short * pdest,unsigned short color)
354 {
355  int32_t r,g,b;unsigned short l;
356
357  if(color==0) return;
358
359  if(bCheckMask && (*pdest & HOST2LE16(0x8000))) return;
360
361  l=sSetMask|(color&0x8000);
362
363  if(DrawSemiTrans && (color&0x8000))
364   {
365    if(GlobalTextABR==0)
366     {
367      unsigned short d;
368      d     =(GETLE16(pdest)&0x7bde)>>1;
369      color =((color) &0x7bde)>>1;
370      r=(XCOL1(d))+((((XCOL1(color)))* g_m1)>>7);
371      b=(XCOL2(d))+((((XCOL2(color)))* g_m2)>>7);
372      g=(XCOL3(d))+((((XCOL3(color)))* g_m3)>>7);
373     }
374    else
375    if(GlobalTextABR==1)
376     {
377      r=(XCOL1(GETLE16(pdest)))+((((XCOL1(color)))* g_m1)>>7);
378      b=(XCOL2(GETLE16(pdest)))+((((XCOL2(color)))* g_m2)>>7);
379      g=(XCOL3(GETLE16(pdest)))+((((XCOL3(color)))* g_m3)>>7);
380     }
381    else
382    if(GlobalTextABR==2)
383     {
384      r=(XCOL1(GETLE16(pdest)))-((((XCOL1(color)))* g_m1)>>7);
385      b=(XCOL2(GETLE16(pdest)))-((((XCOL2(color)))* g_m2)>>7);
386      g=(XCOL3(GETLE16(pdest)))-((((XCOL3(color)))* g_m3)>>7);
387      if(r&0x80000000) r=0;
388      if(b&0x80000000) b=0;
389      if(g&0x80000000) g=0;
390     }
391    else
392     {
393 #ifdef HALFBRIGHTMODE3
394      r=(XCOL1(GETLE16(pdest)))+((((XCOL1(color))>>2)* g_m1)>>7);
395      b=(XCOL2(GETLE16(pdest)))+((((XCOL2(color))>>2)* g_m2)>>7);
396      g=(XCOL3(GETLE16(pdest)))+((((XCOL3(color))>>2)* g_m3)>>7);
397 #else
398      r=(XCOL1(GETLE16(pdest)))+((((XCOL1(color))>>1)* g_m1)>>7);
399      b=(XCOL2(GETLE16(pdest)))+((((XCOL2(color))>>1)* g_m2)>>7);
400      g=(XCOL3(GETLE16(pdest)))+((((XCOL3(color))>>1)* g_m3)>>7);
401 #endif
402     }
403   }
404  else 
405   {
406    r=((XCOL1(color))* g_m1)>>7;
407    b=((XCOL2(color))* g_m2)>>7;
408    g=((XCOL3(color))* g_m3)>>7;
409   }
410
411  if(r&0x7FFFFFE0) r=0x1f;
412  if(b&0x7FFFFC00) b=0x3e0;
413  if(g&0x7FFF8000) g=0x7c00;
414
415  PUTLE16(pdest, (XPSXCOL(r,g,b))|l);
416 }
417
418 ////////////////////////////////////////////////////////////////////////
419
420 static inline void GetTextureTransColG_S(unsigned short * pdest,unsigned short color)
421 {
422  int32_t r,g,b;unsigned short l;
423
424  if(color==0) return;
425
426  l=sSetMask|(color&0x8000);
427
428  r=((XCOL1(color))* g_m1)>>7;
429  b=((XCOL2(color))* g_m2)>>7;
430  g=((XCOL3(color))* g_m3)>>7;
431
432  if(r&0x7FFFFFE0) r=0x1f;
433  if(b&0x7FFFFC00) b=0x3e0;
434  if(g&0x7FFF8000) g=0x7c00;
435
436  PUTLE16(pdest, (XPSXCOL(r,g,b))|l);
437 }
438
439 ////////////////////////////////////////////////////////////////////////
440
441 static inline void GetTextureTransColG_SPR(unsigned short * pdest,unsigned short color)
442 {
443  int32_t r,g,b;unsigned short l;
444
445  if(color==0) return;
446
447  if(bCheckMask && (GETLE16(pdest) & 0x8000)) return;
448
449  l=sSetMask|(color&0x8000);
450
451  if(DrawSemiTrans && (color&0x8000))
452   {
453    if(GlobalTextABR==0)
454     {
455      unsigned short d;
456      d     =(GETLE16(pdest)&0x7bde)>>1;
457      color =((color) &0x7bde)>>1;
458      r=(XCOL1(d))+((((XCOL1(color)))* g_m1)>>7);
459      b=(XCOL2(d))+((((XCOL2(color)))* g_m2)>>7);
460      g=(XCOL3(d))+((((XCOL3(color)))* g_m3)>>7);
461     }
462    else
463    if(GlobalTextABR==1)
464     {
465      r=(XCOL1(GETLE16(pdest)))+((((XCOL1(color)))* g_m1)>>7);
466      b=(XCOL2(GETLE16(pdest)))+((((XCOL2(color)))* g_m2)>>7);
467      g=(XCOL3(GETLE16(pdest)))+((((XCOL3(color)))* g_m3)>>7);
468     }
469    else
470    if(GlobalTextABR==2)
471     {
472      r=(XCOL1(GETLE16(pdest)))-((((XCOL1(color)))* g_m1)>>7);
473      b=(XCOL2(GETLE16(pdest)))-((((XCOL2(color)))* g_m2)>>7);
474      g=(XCOL3(GETLE16(pdest)))-((((XCOL3(color)))* g_m3)>>7);
475      if(r&0x80000000) r=0;
476      if(b&0x80000000) b=0;
477      if(g&0x80000000) g=0;
478     }
479    else
480     {
481 #ifdef HALFBRIGHTMODE3
482      r=(XCOL1(GETLE16(pdest)))+((((XCOL1(color))>>2)* g_m1)>>7);
483      b=(XCOL2(GETLE16(pdest)))+((((XCOL2(color))>>2)* g_m2)>>7);
484      g=(XCOL3(GETLE16(pdest)))+((((XCOL3(color))>>2)* g_m3)>>7);
485 #else
486      r=(XCOL1(GETLE16(pdest)))+((((XCOL1(color))>>1)* g_m1)>>7);
487      b=(XCOL2(GETLE16(pdest)))+((((XCOL2(color))>>1)* g_m2)>>7);
488      g=(XCOL3(GETLE16(pdest)))+((((XCOL3(color))>>1)* g_m3)>>7);
489 #endif
490     }
491   }
492  else 
493   {
494    r=((XCOL1(color))* g_m1)>>7;
495    b=((XCOL2(color))* g_m2)>>7;
496    g=((XCOL3(color))* g_m3)>>7;
497   }
498
499  if(r&0x7FFFFFE0) r=0x1f;
500  if(b&0x7FFFFC00) b=0x3e0;
501  if(g&0x7FFF8000) g=0x7c00;
502
503  PUTLE16(pdest, (XPSXCOL(r,g,b))|l);
504 }
505
506 ////////////////////////////////////////////////////////////////////////
507
508 static inline void GetTextureTransColG32(uint32_t * pdest,uint32_t color)
509 {
510  int32_t r,g,b,l;
511
512  if(color==0) return;
513
514  l=lSetMask|(color&0x80008000);
515
516  if(DrawSemiTrans && (color&0x80008000))
517   {
518    if(GlobalTextABR==0)
519     {                 
520      r=((((X32TCOL1(GETLE32(pdest)))+((X32COL1(color)) * g_m1))&0xFF00FF00)>>8);
521      b=((((X32TCOL2(GETLE32(pdest)))+((X32COL2(color)) * g_m2))&0xFF00FF00)>>8);
522      g=((((X32TCOL3(GETLE32(pdest)))+((X32COL3(color)) * g_m3))&0xFF00FF00)>>8);
523     }
524    else
525    if(GlobalTextABR==1)
526     {
527      r=(X32COL1(GETLE32(pdest)))+(((((X32COL1(color)))* g_m1)&0xFF80FF80)>>7);
528      b=(X32COL2(GETLE32(pdest)))+(((((X32COL2(color)))* g_m2)&0xFF80FF80)>>7);
529      g=(X32COL3(GETLE32(pdest)))+(((((X32COL3(color)))* g_m3)&0xFF80FF80)>>7);
530     }
531    else
532    if(GlobalTextABR==2)
533     {
534      int32_t t;
535      r=(((((X32COL1(color)))* g_m1)&0xFF80FF80)>>7);
536      t=(GETLE32(pdest)&0x001f0000)-(r&0x003f0000); if(t&0x80000000) t=0;
537      r=(GETLE32(pdest)&0x0000001f)-(r&0x0000003f); if(r&0x80000000) r=0;
538      r|=t;
539
540      b=(((((X32COL2(color)))* g_m2)&0xFF80FF80)>>7);
541      t=((GETLE32(pdest)>>5)&0x001f0000)-(b&0x003f0000); if(t&0x80000000) t=0;
542      b=((GETLE32(pdest)>>5)&0x0000001f)-(b&0x0000003f); if(b&0x80000000) b=0;
543      b|=t;
544
545      g=(((((X32COL3(color)))* g_m3)&0xFF80FF80)>>7);
546      t=((GETLE32(pdest)>>10)&0x001f0000)-(g&0x003f0000); if(t&0x80000000) t=0;
547      g=((GETLE32(pdest)>>10)&0x0000001f)-(g&0x0000003f); if(g&0x80000000) g=0;
548      g|=t;
549     }
550    else
551     {
552 #ifdef HALFBRIGHTMODE3
553      r=(X32COL1(GETLE32(pdest)))+(((((X32BCOL1(color))>>2)* g_m1)&0xFF80FF80)>>7);
554      b=(X32COL2(GETLE32(pdest)))+(((((X32BCOL2(color))>>2)* g_m2)&0xFF80FF80)>>7);
555      g=(X32COL3(GETLE32(pdest)))+(((((X32BCOL3(color))>>2)* g_m3)&0xFF80FF80)>>7);
556 #else
557      r=(X32COL1(GETLE32(pdest)))+(((((X32ACOL1(color))>>1)* g_m1)&0xFF80FF80)>>7);
558      b=(X32COL2(GETLE32(pdest)))+(((((X32ACOL2(color))>>1)* g_m2)&0xFF80FF80)>>7);
559      g=(X32COL3(GETLE32(pdest)))+(((((X32ACOL3(color))>>1)* g_m3)&0xFF80FF80)>>7);
560 #endif
561     }
562
563    if(!(color&0x8000))
564     {
565      r=(r&0xffff0000)|((((X32COL1(color))* g_m1)&0x0000FF80)>>7);
566      b=(b&0xffff0000)|((((X32COL2(color))* g_m2)&0x0000FF80)>>7);
567      g=(g&0xffff0000)|((((X32COL3(color))* g_m3)&0x0000FF80)>>7);
568     }
569    if(!(color&0x80000000))
570     {
571      r=(r&0xffff)|((((X32COL1(color))* g_m1)&0xFF800000)>>7);
572      b=(b&0xffff)|((((X32COL2(color))* g_m2)&0xFF800000)>>7);
573      g=(g&0xffff)|((((X32COL3(color))* g_m3)&0xFF800000)>>7);
574     }
575
576   }
577  else 
578   {
579    r=(((X32COL1(color))* g_m1)&0xFF80FF80)>>7;
580    b=(((X32COL2(color))* g_m2)&0xFF80FF80)>>7;
581    g=(((X32COL3(color))* g_m3)&0xFF80FF80)>>7;
582   }
583
584  if(r&0x7FE00000) r=0x1f0000|(r&0xFFFF);
585  if(r&0x7FE0)     r=0x1f    |(r&0xFFFF0000);
586  if(b&0x7FE00000) b=0x1f0000|(b&0xFFFF);
587  if(b&0x7FE0)     b=0x1f    |(b&0xFFFF0000);
588  if(g&0x7FE00000) g=0x1f0000|(g&0xFFFF);
589  if(g&0x7FE0)     g=0x1f    |(g&0xFFFF0000);
590          
591  if(bCheckMask) 
592   {
593    uint32_t ma=GETLE32(pdest);
594
595    PUTLE32(pdest, (X32PSXCOL(r,g,b))|l);
596    
597    if((color&0xffff)==0    ) PUTLE32(pdest, (ma&0xffff)|(GETLE32(pdest)&0xffff0000));
598    if((color&0xffff0000)==0) PUTLE32(pdest, (ma&0xffff0000)|(GETLE32(pdest)&0xffff));
599    if(ma&0x80000000) PUTLE32(pdest, (ma&0xFFFF0000)|(GETLE32(pdest)&0xFFFF));
600    if(ma&0x00008000) PUTLE32(pdest, (ma&0xFFFF)    |(GETLE32(pdest)&0xFFFF0000));
601
602    return;                            
603   }
604  if((color&0xffff)==0    ) {PUTLE32(pdest, (GETLE32(pdest)&0xffff)|(((X32PSXCOL(r,g,b))|l)&0xffff0000));return;}
605  if((color&0xffff0000)==0) {PUTLE32(pdest, (GETLE32(pdest)&0xffff0000)|(((X32PSXCOL(r,g,b))|l)&0xffff));return;}
606
607  PUTLE32(pdest, (X32PSXCOL(r,g,b))|l);
608 }
609
610 ////////////////////////////////////////////////////////////////////////
611
612 static inline void GetTextureTransColG32_S(uint32_t * pdest,uint32_t color)
613 {
614  int32_t r,g,b;
615
616  if(color==0) return;
617
618  r=(((X32COL1(color))* g_m1)&0xFF80FF80)>>7;
619  b=(((X32COL2(color))* g_m2)&0xFF80FF80)>>7;
620  g=(((X32COL3(color))* g_m3)&0xFF80FF80)>>7;
621
622  if(r&0x7FE00000) r=0x1f0000|(r&0xFFFF);
623  if(r&0x7FE0)     r=0x1f    |(r&0xFFFF0000);
624  if(b&0x7FE00000) b=0x1f0000|(b&0xFFFF);
625  if(b&0x7FE0)     b=0x1f    |(b&0xFFFF0000);
626  if(g&0x7FE00000) g=0x1f0000|(g&0xFFFF);
627  if(g&0x7FE0)     g=0x1f    |(g&0xFFFF0000);
628          
629  if((color&0xffff)==0)     {PUTLE32(pdest, (GETLE32(pdest)&0xffff)|(((X32PSXCOL(r,g,b))|lSetMask|(color&0x80008000))&0xffff0000));return;}
630  if((color&0xffff0000)==0) {PUTLE32(pdest, (GETLE32(pdest)&0xffff0000)|(((X32PSXCOL(r,g,b))|lSetMask|(color&0x80008000))&0xffff));return;}
631
632  PUTLE32(pdest, (X32PSXCOL(r,g,b))|lSetMask|(color&0x80008000));
633 }
634
635 ////////////////////////////////////////////////////////////////////////
636
637 static inline void GetTextureTransColG32_SPR(uint32_t * pdest,uint32_t color)
638 {
639  int32_t r,g,b;
640
641  if(color==0) return;
642
643  if(DrawSemiTrans && (color&0x80008000))
644   {
645    if(GlobalTextABR==0)
646     {                 
647      r=((((X32TCOL1(GETLE32(pdest)))+((X32COL1(color)) * g_m1))&0xFF00FF00)>>8);
648      b=((((X32TCOL2(GETLE32(pdest)))+((X32COL2(color)) * g_m2))&0xFF00FF00)>>8);
649      g=((((X32TCOL3(GETLE32(pdest)))+((X32COL3(color)) * g_m3))&0xFF00FF00)>>8);
650     }
651    else
652    if(GlobalTextABR==1)
653     {
654      r=(X32COL1(GETLE32(pdest)))+(((((X32COL1(color)))* g_m1)&0xFF80FF80)>>7);
655      b=(X32COL2(GETLE32(pdest)))+(((((X32COL2(color)))* g_m2)&0xFF80FF80)>>7);
656      g=(X32COL3(GETLE32(pdest)))+(((((X32COL3(color)))* g_m3)&0xFF80FF80)>>7);
657     }
658    else
659    if(GlobalTextABR==2)
660     {
661      int32_t t;
662      r=(((((X32COL1(color)))* g_m1)&0xFF80FF80)>>7);
663      t=(GETLE32(pdest)&0x001f0000)-(r&0x003f0000); if(t&0x80000000) t=0;
664      r=(GETLE32(pdest)&0x0000001f)-(r&0x0000003f); if(r&0x80000000) r=0;
665      r|=t;
666
667      b=(((((X32COL2(color)))* g_m2)&0xFF80FF80)>>7);
668      t=((GETLE32(pdest)>>5)&0x001f0000)-(b&0x003f0000); if(t&0x80000000) t=0;
669      b=((GETLE32(pdest)>>5)&0x0000001f)-(b&0x0000003f); if(b&0x80000000) b=0;
670      b|=t;
671
672      g=(((((X32COL3(color)))* g_m3)&0xFF80FF80)>>7);
673      t=((GETLE32(pdest)>>10)&0x001f0000)-(g&0x003f0000); if(t&0x80000000) t=0;
674      g=((GETLE32(pdest)>>10)&0x0000001f)-(g&0x0000003f); if(g&0x80000000) g=0;
675      g|=t;
676     }
677    else
678     {
679 #ifdef HALFBRIGHTMODE3
680      r=(X32COL1(GETLE32(pdest)))+(((((X32BCOL1(color))>>2)* g_m1)&0xFF80FF80)>>7);
681      b=(X32COL2(GETLE32(pdest)))+(((((X32BCOL2(color))>>2)* g_m2)&0xFF80FF80)>>7);
682      g=(X32COL3(GETLE32(pdest)))+(((((X32BCOL3(color))>>2)* g_m3)&0xFF80FF80)>>7);
683 #else
684      r=(X32COL1(GETLE32(pdest)))+(((((X32ACOL1(color))>>1)* g_m1)&0xFF80FF80)>>7);
685      b=(X32COL2(GETLE32(pdest)))+(((((X32ACOL2(color))>>1)* g_m2)&0xFF80FF80)>>7);
686      g=(X32COL3(GETLE32(pdest)))+(((((X32ACOL3(color))>>1)* g_m3)&0xFF80FF80)>>7);
687 #endif
688     }
689
690    if(!(color&0x8000))
691     {
692      r=(r&0xffff0000)|((((X32COL1(color))* g_m1)&0x0000FF80)>>7);
693      b=(b&0xffff0000)|((((X32COL2(color))* g_m2)&0x0000FF80)>>7);
694      g=(g&0xffff0000)|((((X32COL3(color))* g_m3)&0x0000FF80)>>7);
695     }
696    if(!(color&0x80000000))
697     {
698      r=(r&0xffff)|((((X32COL1(color))* g_m1)&0xFF800000)>>7);
699      b=(b&0xffff)|((((X32COL2(color))* g_m2)&0xFF800000)>>7);
700      g=(g&0xffff)|((((X32COL3(color))* g_m3)&0xFF800000)>>7);
701     }
702
703   }
704  else 
705   {
706    r=(((X32COL1(color))* g_m1)&0xFF80FF80)>>7;
707    b=(((X32COL2(color))* g_m2)&0xFF80FF80)>>7;
708    g=(((X32COL3(color))* g_m3)&0xFF80FF80)>>7;
709   }
710
711  if(r&0x7FE00000) r=0x1f0000|(r&0xFFFF);
712  if(r&0x7FE0)     r=0x1f    |(r&0xFFFF0000);
713  if(b&0x7FE00000) b=0x1f0000|(b&0xFFFF);
714  if(b&0x7FE0)     b=0x1f    |(b&0xFFFF0000);
715  if(g&0x7FE00000) g=0x1f0000|(g&0xFFFF);
716  if(g&0x7FE0)     g=0x1f    |(g&0xFFFF0000);
717          
718  if(bCheckMask) 
719   {
720    uint32_t ma=GETLE32(pdest);
721
722    PUTLE32(pdest, (X32PSXCOL(r,g,b))|lSetMask|(color&0x80008000));
723    
724    if((color&0xffff)==0    ) PUTLE32(pdest, (ma&0xffff)|(GETLE32(pdest)&0xffff0000));
725    if((color&0xffff0000)==0) PUTLE32(pdest, (ma&0xffff0000)|(GETLE32(pdest)&0xffff));
726    if(ma&0x80000000) PUTLE32(pdest, (ma&0xFFFF0000)|(GETLE32(pdest)&0xFFFF));
727    if(ma&0x00008000) PUTLE32(pdest, (ma&0xFFFF)    |(GETLE32(pdest)&0xFFFF0000));
728
729    return;                            
730   }
731  if((color&0xffff)==0    ) {PUTLE32(pdest, (GETLE32(pdest)&0xffff)|(((X32PSXCOL(r,g,b))|lSetMask|(color&0x80008000))&0xffff0000));return;}
732  if((color&0xffff0000)==0) {PUTLE32(pdest, (GETLE32(pdest)&0xffff0000)|(((X32PSXCOL(r,g,b))|lSetMask|(color&0x80008000))&0xffff));return;}
733
734  PUTLE32(pdest, (X32PSXCOL(r,g,b))|lSetMask|(color&0x80008000));
735 }
736
737 ////////////////////////////////////////////////////////////////////////
738
739 static inline void GetTextureTransColGX_Dither(unsigned short * pdest,unsigned short color,int32_t m1,int32_t m2,int32_t m3)
740 {
741  int32_t r,g,b;
742
743  if(color==0) return;
744  
745  if(bCheckMask && (*pdest & HOST2LE16(0x8000))) return;
746
747  m1=(((XCOL1D(color)))*m1)>>4;
748  m2=(((XCOL2D(color)))*m2)>>4;
749  m3=(((XCOL3D(color)))*m3)>>4;
750
751  if(DrawSemiTrans && (color&0x8000))
752   {
753    r=((XCOL1D(GETLE16(pdest)))<<3);
754    b=((XCOL2D(GETLE16(pdest)))<<3);
755    g=((XCOL3D(GETLE16(pdest)))<<3);
756
757    if(GlobalTextABR==0)
758     {
759      r=(r>>1)+(m1>>1);
760      b=(b>>1)+(m2>>1);
761      g=(g>>1)+(m3>>1);
762     }
763    else
764    if(GlobalTextABR==1)
765     {
766      r+=m1;
767      b+=m2;
768      g+=m3;
769     }
770    else
771    if(GlobalTextABR==2)
772     {
773      r-=m1;
774      b-=m2;
775      g-=m3;
776      if(r&0x80000000) r=0;
777      if(b&0x80000000) b=0;
778      if(g&0x80000000) g=0;
779     }
780    else
781     {
782 #ifdef HALFBRIGHTMODE3
783      r+=(m1>>2);
784      b+=(m2>>2);
785      g+=(m3>>2);
786 #else
787      r+=(m1>>1);
788      b+=(m2>>1);
789      g+=(m3>>1);
790 #endif
791     }
792   }
793  else 
794   {
795    r=m1;
796    b=m2;
797    g=m3;
798   }
799
800  if(r&0x7FFFFF00) r=0xff;
801  if(b&0x7FFFFF00) b=0xff;
802  if(g&0x7FFFFF00) g=0xff;
803
804  Dither16(pdest,r,b,g,sSetMask|(color&0x8000));
805
806 }
807
808 ////////////////////////////////////////////////////////////////////////
809
810 static inline void GetTextureTransColGX(unsigned short * pdest,unsigned short color,short m1,short m2,short m3)
811 {
812  int32_t r,g,b;unsigned short l;
813
814  if(color==0) return;
815  
816  if(bCheckMask && (*pdest & HOST2LE16(0x8000))) return;
817
818  l=sSetMask|(color&0x8000);
819
820  if(DrawSemiTrans && (color&0x8000))
821   {
822    if(GlobalTextABR==0)
823     {
824      unsigned short d;
825      d     =(GETLE16(pdest)&0x7bde)>>1;
826      color =((color) &0x7bde)>>1;
827      r=(XCOL1(d))+((((XCOL1(color)))* m1)>>7);
828      b=(XCOL2(d))+((((XCOL2(color)))* m2)>>7);
829      g=(XCOL3(d))+((((XCOL3(color)))* m3)>>7);
830     }
831    else
832    if(GlobalTextABR==1)
833     {
834      r=(XCOL1(GETLE16(pdest)))+((((XCOL1(color)))* m1)>>7);
835      b=(XCOL2(GETLE16(pdest)))+((((XCOL2(color)))* m2)>>7);
836      g=(XCOL3(GETLE16(pdest)))+((((XCOL3(color)))* m3)>>7);
837     }
838    else
839    if(GlobalTextABR==2)
840     {
841      r=(XCOL1(GETLE16(pdest)))-((((XCOL1(color)))* m1)>>7);
842      b=(XCOL2(GETLE16(pdest)))-((((XCOL2(color)))* m2)>>7);
843      g=(XCOL3(GETLE16(pdest)))-((((XCOL3(color)))* m3)>>7);
844      if(r&0x80000000) r=0;
845      if(b&0x80000000) b=0;
846      if(g&0x80000000) g=0;
847     }
848    else
849     {
850 #ifdef HALFBRIGHTMODE3
851      r=(XCOL1(GETLE16(pdest)))+((((XCOL1(color))>>2)* m1)>>7);
852      b=(XCOL2(GETLE16(pdest)))+((((XCOL2(color))>>2)* m2)>>7);
853      g=(XCOL3(GETLE16(pdest)))+((((XCOL3(color))>>2)* m3)>>7);
854 #else
855      r=(XCOL1(GETLE16(pdest)))+((((XCOL1(color))>>1)* m1)>>7);
856      b=(XCOL2(GETLE16(pdest)))+((((XCOL2(color))>>1)* m2)>>7);
857      g=(XCOL3(GETLE16(pdest)))+((((XCOL3(color))>>1)* m3)>>7);
858 #endif
859     }
860   }
861  else 
862   {
863    r=((XCOL1(color))* m1)>>7;
864    b=((XCOL2(color))* m2)>>7;
865    g=((XCOL3(color))* m3)>>7;
866   }
867
868  if(r&0x7FFFFFE0) r=0x1f;
869  if(b&0x7FFFFC00) b=0x3e0;
870  if(g&0x7FFF8000) g=0x7c00;
871
872  PUTLE16(pdest, (XPSXCOL(r,g,b))|l);
873 }
874
875 ////////////////////////////////////////////////////////////////////////
876
877 static inline void GetTextureTransColGX_S(unsigned short * pdest,unsigned short color,short m1,short m2,short m3)
878 {
879  int32_t r,g,b;
880
881  if(color==0) return;
882  
883  r=((XCOL1(color))* m1)>>7;
884  b=((XCOL2(color))* m2)>>7;
885  g=((XCOL3(color))* m3)>>7;
886
887  if(r&0x7FFFFFE0) r=0x1f;
888  if(b&0x7FFFFC00) b=0x3e0;
889  if(g&0x7FFF8000) g=0x7c00;
890
891  PUTLE16(pdest, (XPSXCOL(r,g,b))|sSetMask|(color&0x8000));
892 }
893
894 ////////////////////////////////////////////////////////////////////////
895
896 static inline void GetTextureTransColGX32_S(uint32_t * pdest,uint32_t color,short m1,short m2,short m3)
897 {
898  int32_t r,g,b;
899  
900  if(color==0) return;
901
902  r=(((X32COL1(color))* m1)&0xFF80FF80)>>7;
903  b=(((X32COL2(color))* m2)&0xFF80FF80)>>7;
904  g=(((X32COL3(color))* m3)&0xFF80FF80)>>7;
905                 
906  if(r&0x7FE00000) r=0x1f0000|(r&0xFFFF);
907  if(r&0x7FE0)     r=0x1f    |(r&0xFFFF0000);
908  if(b&0x7FE00000) b=0x1f0000|(b&0xFFFF);
909  if(b&0x7FE0)     b=0x1f    |(b&0xFFFF0000);
910  if(g&0x7FE00000) g=0x1f0000|(g&0xFFFF);
911  if(g&0x7FE0)     g=0x1f    |(g&0xFFFF0000);
912
913  if((color&0xffff)==0)     {PUTLE32(pdest, (GETLE32(pdest)&0xffff)|(((X32PSXCOL(r,g,b))|lSetMask|(color&0x80008000))&0xffff0000));return;}
914  if((color&0xffff0000)==0) {PUTLE32(pdest, (GETLE32(pdest)&0xffff0000)|(((X32PSXCOL(r,g,b))|lSetMask|(color&0x80008000))&0xffff));return;}
915
916  PUTLE32(pdest, (X32PSXCOL(r,g,b))|lSetMask|(color&0x80008000));
917 }
918
919 ////////////////////////////////////////////////////////////////////////
920 // FILL FUNCS
921 ////////////////////////////////////////////////////////////////////////
922
923 static void FillSoftwareAreaTrans(short x0,short y0,short x1, // FILL AREA TRANS
924                       short y1,unsigned short col)
925 {
926  short j,i,dx,dy;
927
928  if(y0>y1) return;
929  if(x0>x1) return;
930
931  if(x1<drawX) return;
932  if(y1<drawY) return;
933  if(x0>drawW) return;
934  if(y0>drawH) return;
935
936  x1=min(x1,drawW+1);
937  y1=min(y1,drawH+1);
938  x0=max(x0,drawX);
939  y0=max(y0,drawY);
940     
941  if(y0>=512)   return;
942  if(x0>1023)          return;
943
944  if(y1>512) y1=512;
945  if(x1>1024)       x1=1024;
946
947  dx=x1-x0;dy=y1-y0;
948
949  if(dx==1 && dy==1 && x0==1020 && y0==511)             // special fix for pinball game... emu protection???
950   {
951    static int iCheat=0;
952    col+=iCheat;
953    if(iCheat==1) iCheat=0; else iCheat=1;
954   }
955
956
957  if(dx&1)                                              // slow fill
958   {
959    unsigned short *DSTPtr;
960    unsigned short LineOffset;
961    DSTPtr = psxVuw + (1024*y0) + x0;
962    LineOffset = 1024 - dx;
963    for(i=0;i<dy;i++)
964     {
965      for(j=0;j<dx;j++)
966       GetShadeTransCol(DSTPtr++,col);
967      DSTPtr += LineOffset;
968     } 
969   }
970  else                                                  // fast fill
971   {
972    uint32_t *DSTPtr;
973    unsigned short LineOffset;
974    uint32_t lcol=lSetMask|(((uint32_t)(col))<<16)|col;
975    dx>>=1;
976    DSTPtr = (uint32_t *)(psxVuw + (1024*y0) + x0);
977    LineOffset = 512 - dx;
978
979    if(!bCheckMask && !DrawSemiTrans)
980     {
981      for(i=0;i<dy;i++)
982       {
983        for(j=0;j<dx;j++) { PUTLE32(DSTPtr, lcol); DSTPtr++; }
984        DSTPtr += LineOffset;
985       }
986     }
987    else
988     {
989      for(i=0;i<dy;i++)
990       {
991        for(j=0;j<dx;j++) 
992         GetShadeTransCol32(DSTPtr++,lcol);
993        DSTPtr += LineOffset;
994       } 
995     }
996   }
997 }
998
999 ////////////////////////////////////////////////////////////////////////
1000
1001 static void FillSoftwareArea(short x0,short y0,short x1,      // FILL AREA (BLK FILL)
1002                       short y1,unsigned short col)     // no draw area check here!
1003 {
1004  short j,i,dx,dy;
1005
1006  // ?? ff9 pal hooligan crack sets nonsense x0
1007  if(x0<0) x0=0;
1008  if(y0<0) y0=0;
1009
1010  if(y0>y1) return;
1011  if(x0>x1) return;
1012     
1013  if(y0>=512)   return;
1014  if(x0>1023)          return;
1015
1016  if(y1>512) y1=512;
1017  if(x1>1024)       x1=1024;
1018
1019  dx=x1-x0;dy=y1-y0;
1020  if(dx&1)
1021   {
1022    unsigned short *DSTPtr;
1023    unsigned short LineOffset;
1024
1025    DSTPtr = psxVuw + (1024*y0) + x0;
1026    LineOffset = 1024 - dx;
1027
1028    for(i=0;i<dy;i++)
1029     {
1030      for(j=0;j<dx;j++) { PUTLE16(DSTPtr, col); DSTPtr++; }
1031      DSTPtr += LineOffset;
1032     } 
1033   }
1034  else
1035   {
1036    uint32_t *DSTPtr;
1037    unsigned short LineOffset;
1038    uint32_t lcol=(((int32_t)col)<<16)|col;
1039    dx>>=1;
1040    DSTPtr = (uint32_t *)(psxVuw + (1024*y0) + x0);
1041    LineOffset = 512 - dx;
1042
1043    for(i=0;i<dy;i++)
1044     {
1045      for(j=0;j<dx;j++) { PUTLE32(DSTPtr, lcol); DSTPtr++; }
1046      DSTPtr += LineOffset;
1047     } 
1048   }
1049 }
1050
1051 ////////////////////////////////////////////////////////////////////////
1052 ////////////////////////////////////////////////////////////////////////
1053 ////////////////////////////////////////////////////////////////////////
1054 // EDGE INTERPOLATION
1055 ////////////////////////////////////////////////////////////////////////
1056 ////////////////////////////////////////////////////////////////////////
1057 ////////////////////////////////////////////////////////////////////////
1058
1059 typedef struct SOFTVTAG
1060 {
1061  int x,y;   
1062  int u,v;
1063  int32_t R,G,B;
1064 } soft_vertex;
1065
1066 static soft_vertex vtx[4];
1067 static soft_vertex * left_array[4], * right_array[4];
1068 static int left_section, right_section;
1069 static int left_section_height, right_section_height;
1070 static int left_x, delta_left_x, right_x, delta_right_x;
1071 static int left_u, delta_left_u, left_v, delta_left_v;
1072 static int right_u, delta_right_u, right_v, delta_right_v;
1073 static int left_R, delta_left_R, right_R, delta_right_R;
1074 static int left_G, delta_left_G, right_G, delta_right_G;
1075 static int left_B, delta_left_B, right_B, delta_right_B;
1076
1077 // USE_NASM
1078 static inline int shl10idiv(int x, int y)
1079 {
1080 #ifdef __arm__
1081  // rearmed: let's use VFP divider instead
1082  float r = 1024.0f * (float)x / (float)y;
1083  return (int)r;
1084 #else
1085  __int64 bi=x;
1086  bi<<=10;
1087  return bi/y;
1088 #endif
1089 }
1090
1091 ////////////////////////////////////////////////////////////////////////
1092 ////////////////////////////////////////////////////////////////////////
1093 ////////////////////////////////////////////////////////////////////////
1094                         
1095 static inline int RightSection_F(void)
1096 {
1097  soft_vertex * v1 = right_array[ right_section ];
1098  soft_vertex * v2 = right_array[ right_section-1 ];
1099
1100  int height = v2->y - v1->y;
1101  if(height == 0) return 0;
1102  delta_right_x = (v2->x - v1->x) / height;
1103  right_x = v1->x;
1104
1105  right_section_height = height;
1106  return height;
1107 }
1108
1109 ////////////////////////////////////////////////////////////////////////
1110
1111 static inline int LeftSection_F(void)
1112 {
1113  soft_vertex * v1 = left_array[ left_section ];
1114  soft_vertex * v2 = left_array[ left_section-1 ];
1115
1116  int height = v2->y - v1->y;
1117  if(height == 0) return 0;
1118  delta_left_x = (v2->x - v1->x) / height;
1119  left_x = v1->x;
1120
1121  left_section_height = height;
1122  return height;  
1123 }
1124
1125 ////////////////////////////////////////////////////////////////////////
1126
1127 static inline BOOL NextRow_F(void)
1128 {
1129  if(--left_section_height<=0) 
1130   {
1131    if(--left_section <= 0) {return TRUE;}
1132    if(LeftSection_F()  <= 0) {return TRUE;}
1133   }
1134  else
1135   {
1136    left_x += delta_left_x;
1137   }
1138
1139  if(--right_section_height<=0) 
1140   {
1141    if(--right_section<=0) {return TRUE;}
1142    if(RightSection_F() <=0) {return TRUE;}
1143   }
1144  else
1145   {
1146    right_x += delta_right_x;
1147   }
1148  return FALSE;
1149 }
1150
1151 ////////////////////////////////////////////////////////////////////////
1152
1153 static inline BOOL SetupSections_F(short x1, short y1, short x2, short y2, short x3, short y3)
1154 {
1155  soft_vertex * v1, * v2, * v3;
1156  int height,longest;
1157
1158  v1 = vtx;   v1->x=x1<<16;v1->y=y1;
1159  v2 = vtx+1; v2->x=x2<<16;v2->y=y2;
1160  v3 = vtx+2; v3->x=x3<<16;v3->y=y3;
1161
1162  if(v1->y > v2->y) { soft_vertex * v = v1; v1 = v2; v2 = v; }
1163  if(v1->y > v3->y) { soft_vertex * v = v1; v1 = v3; v3 = v; }
1164  if(v2->y > v3->y) { soft_vertex * v = v2; v2 = v3; v3 = v; }
1165
1166  height = v3->y - v1->y;
1167  if(height == 0) {return FALSE;}
1168  longest = (((v2->y - v1->y) << 16) / height) * ((v3->x - v1->x)>>16) + (v1->x - v2->x);
1169  if(longest == 0) {return FALSE;}
1170
1171  if(longest < 0)
1172   {
1173    right_array[0] = v3;
1174    right_array[1] = v2;
1175    right_array[2] = v1;
1176    right_section  = 2;
1177    left_array[0]  = v3;
1178    left_array[1]  = v1;
1179    left_section   = 1;
1180
1181    if(LeftSection_F() <= 0) return FALSE;
1182    if(RightSection_F() <= 0)
1183     {
1184      right_section--;
1185      if(RightSection_F() <= 0) return FALSE;
1186     }
1187   }
1188  else
1189   {
1190    left_array[0]  = v3;
1191    left_array[1]  = v2;
1192    left_array[2]  = v1;
1193    left_section   = 2;
1194    right_array[0] = v3;
1195    right_array[1] = v1;
1196    right_section  = 1;
1197
1198    if(RightSection_F() <= 0) return FALSE;
1199    if(LeftSection_F() <= 0)
1200     {    
1201      left_section--;
1202      if(LeftSection_F() <= 0) return FALSE;
1203     }
1204   }
1205
1206  Ymin=v1->y;
1207  Ymax=min(v3->y-1,drawH);
1208
1209  return TRUE;
1210 }
1211
1212 ////////////////////////////////////////////////////////////////////////
1213 ////////////////////////////////////////////////////////////////////////
1214
1215 static inline int RightSection_G(void)
1216 {
1217  soft_vertex * v1 = right_array[ right_section ];
1218  soft_vertex * v2 = right_array[ right_section-1 ];
1219
1220  int height = v2->y - v1->y;
1221  if(height == 0) return 0;
1222  delta_right_x = (v2->x - v1->x) / height;
1223  right_x = v1->x;
1224
1225  right_section_height = height;
1226  return height;
1227 }
1228
1229 ////////////////////////////////////////////////////////////////////////
1230
1231 static inline int LeftSection_G(void)
1232 {
1233  soft_vertex * v1 = left_array[ left_section ];
1234  soft_vertex * v2 = left_array[ left_section-1 ];
1235
1236  int height = v2->y - v1->y;
1237  if(height == 0) return 0;
1238  delta_left_x = (v2->x - v1->x) / height;
1239  left_x = v1->x;
1240
1241  delta_left_R = ((v2->R - v1->R)) / height;
1242  left_R = v1->R;
1243  delta_left_G = ((v2->G - v1->G)) / height;
1244  left_G = v1->G;
1245  delta_left_B = ((v2->B - v1->B)) / height;
1246  left_B = v1->B;
1247
1248  left_section_height = height;
1249  return height;  
1250 }
1251
1252 ////////////////////////////////////////////////////////////////////////
1253
1254 static inline BOOL NextRow_G(void)
1255 {
1256  if(--left_section_height<=0) 
1257   {
1258    if(--left_section <= 0) {return TRUE;}
1259    if(LeftSection_G()  <= 0) {return TRUE;}
1260   }
1261  else
1262   {
1263    left_x += delta_left_x;
1264    left_R += delta_left_R;
1265    left_G += delta_left_G;
1266    left_B += delta_left_B;
1267   }
1268
1269  if(--right_section_height<=0) 
1270   {
1271    if(--right_section<=0) {return TRUE;}
1272    if(RightSection_G() <=0) {return TRUE;}
1273   }
1274  else
1275   {
1276    right_x += delta_right_x;
1277   }
1278  return FALSE;
1279 }
1280
1281 ////////////////////////////////////////////////////////////////////////
1282
1283 static inline BOOL SetupSections_G(short x1,short y1,short x2,short y2,short x3,short y3,int32_t rgb1, int32_t rgb2, int32_t rgb3)
1284 {
1285  soft_vertex * v1, * v2, * v3;
1286  int height,longest,temp;
1287
1288  v1 = vtx;   v1->x=x1<<16;v1->y=y1;
1289  v1->R=(rgb1) & 0x00ff0000;
1290  v1->G=(rgb1<<8) & 0x00ff0000;
1291  v1->B=(rgb1<<16) & 0x00ff0000;
1292  v2 = vtx+1; v2->x=x2<<16;v2->y=y2;
1293  v2->R=(rgb2) & 0x00ff0000;
1294  v2->G=(rgb2<<8) & 0x00ff0000;
1295  v2->B=(rgb2<<16) & 0x00ff0000;
1296  v3 = vtx+2; v3->x=x3<<16;v3->y=y3;
1297  v3->R=(rgb3) & 0x00ff0000;
1298  v3->G=(rgb3<<8) & 0x00ff0000;
1299  v3->B=(rgb3<<16) & 0x00ff0000;
1300
1301  if(v1->y > v2->y) { soft_vertex * v = v1; v1 = v2; v2 = v; }
1302  if(v1->y > v3->y) { soft_vertex * v = v1; v1 = v3; v3 = v; }
1303  if(v2->y > v3->y) { soft_vertex * v = v2; v2 = v3; v3 = v; }
1304
1305  height = v3->y - v1->y;
1306  if(height == 0) {return FALSE;}
1307  temp=(((v2->y - v1->y) << 16) / height);
1308  longest = temp * ((v3->x - v1->x)>>16) + (v1->x - v2->x);
1309  if(longest == 0) {return FALSE;}
1310
1311  if(longest < 0)
1312   {
1313    right_array[0] = v3;
1314    right_array[1] = v2;
1315    right_array[2] = v1;
1316    right_section  = 2;
1317    left_array[0]  = v3;
1318    left_array[1]  = v1;
1319    left_section   = 1;
1320
1321    if(LeftSection_G() <= 0) return FALSE;
1322    if(RightSection_G() <= 0)
1323     {
1324      right_section--;
1325      if(RightSection_G() <= 0) return FALSE;
1326     }
1327    if(longest > -0x1000) longest = -0x1000;     
1328   }
1329  else
1330   {
1331    left_array[0]  = v3;
1332    left_array[1]  = v2;
1333    left_array[2]  = v1;
1334    left_section   = 2;
1335    right_array[0] = v3;
1336    right_array[1] = v1;
1337    right_section  = 1;
1338
1339    if(RightSection_G() <= 0) return FALSE;
1340    if(LeftSection_G() <= 0)
1341     {    
1342      left_section--;
1343      if(LeftSection_G() <= 0) return FALSE;
1344     }
1345    if(longest < 0x1000) longest = 0x1000;     
1346   }
1347
1348  Ymin=v1->y;
1349  Ymax=min(v3->y-1,drawH);    
1350
1351  delta_right_R=shl10idiv(temp*((v3->R - v1->R)>>10)+((v1->R - v2->R)<<6),longest);
1352  delta_right_G=shl10idiv(temp*((v3->G - v1->G)>>10)+((v1->G - v2->G)<<6),longest);
1353  delta_right_B=shl10idiv(temp*((v3->B - v1->B)>>10)+((v1->B - v2->B)<<6),longest);
1354
1355  return TRUE;
1356 }
1357
1358 ////////////////////////////////////////////////////////////////////////
1359 ////////////////////////////////////////////////////////////////////////
1360
1361 static inline int RightSection_FT(void)
1362 {
1363  soft_vertex * v1 = right_array[ right_section ];
1364  soft_vertex * v2 = right_array[ right_section-1 ];
1365
1366  int height = v2->y - v1->y;
1367  if(height == 0) return 0;
1368  delta_right_x = (v2->x - v1->x) / height;
1369  right_x = v1->x;
1370
1371  right_section_height = height;
1372  return height;
1373 }
1374
1375 ////////////////////////////////////////////////////////////////////////
1376
1377 static inline int LeftSection_FT(void)
1378 {
1379  soft_vertex * v1 = left_array[ left_section ];
1380  soft_vertex * v2 = left_array[ left_section-1 ];
1381
1382  int height = v2->y - v1->y;
1383  if(height == 0) return 0;
1384  delta_left_x = (v2->x - v1->x) / height;
1385  left_x = v1->x;
1386  
1387  delta_left_u = ((v2->u - v1->u)) / height;
1388  left_u = v1->u;
1389  delta_left_v = ((v2->v - v1->v)) / height;
1390  left_v = v1->v;
1391
1392  left_section_height = height;
1393  return height;  
1394 }
1395
1396 ////////////////////////////////////////////////////////////////////////
1397
1398 static inline BOOL NextRow_FT(void)
1399 {
1400  if(--left_section_height<=0) 
1401   {
1402    if(--left_section <= 0) {return TRUE;}
1403    if(LeftSection_FT()  <= 0) {return TRUE;}
1404   }
1405  else
1406   {
1407    left_x += delta_left_x;
1408    left_u += delta_left_u;
1409    left_v += delta_left_v;
1410   }
1411
1412  if(--right_section_height<=0) 
1413   {
1414    if(--right_section<=0) {return TRUE;}
1415    if(RightSection_FT() <=0) {return TRUE;}
1416   }
1417  else
1418   {
1419    right_x += delta_right_x;
1420   }
1421  return FALSE;
1422 }
1423
1424 ////////////////////////////////////////////////////////////////////////
1425
1426 static inline BOOL SetupSections_FT(short x1, short y1, short x2, short y2, short x3, short y3, short tx1, short ty1, short tx2, short ty2, short tx3, short ty3)
1427 {
1428  soft_vertex * v1, * v2, * v3;
1429  int height,longest,temp;
1430
1431  v1 = vtx;   v1->x=x1<<16;v1->y=y1;
1432  v1->u=tx1<<16;v1->v=ty1<<16;
1433  v2 = vtx+1; v2->x=x2<<16;v2->y=y2;
1434  v2->u=tx2<<16;v2->v=ty2<<16;
1435  v3 = vtx+2; v3->x=x3<<16;v3->y=y3;
1436  v3->u=tx3<<16;v3->v=ty3<<16;
1437
1438  if(v1->y > v2->y) { soft_vertex * v = v1; v1 = v2; v2 = v; }
1439  if(v1->y > v3->y) { soft_vertex * v = v1; v1 = v3; v3 = v; }
1440  if(v2->y > v3->y) { soft_vertex * v = v2; v2 = v3; v3 = v; }
1441
1442  height = v3->y - v1->y;
1443  if(height == 0) {return FALSE;}
1444
1445  temp=(((v2->y - v1->y) << 16) / height);
1446  longest = temp * ((v3->x - v1->x)>>16) + (v1->x - v2->x);
1447
1448  if(longest == 0) {return FALSE;}
1449
1450  if(longest < 0)
1451   {
1452    right_array[0] = v3;
1453    right_array[1] = v2;
1454    right_array[2] = v1;
1455    right_section  = 2;
1456    left_array[0]  = v3;
1457    left_array[1]  = v1;
1458    left_section   = 1;
1459
1460    if(LeftSection_FT() <= 0) return FALSE;
1461    if(RightSection_FT() <= 0)
1462     {
1463      right_section--;
1464      if(RightSection_FT() <= 0) return FALSE;
1465     }
1466    if(longest > -0x1000) longest = -0x1000;     
1467   }
1468  else
1469   {
1470    left_array[0]  = v3;
1471    left_array[1]  = v2;
1472    left_array[2]  = v1;
1473    left_section   = 2;
1474    right_array[0] = v3;
1475    right_array[1] = v1;
1476    right_section  = 1;
1477
1478    if(RightSection_FT() <= 0) return FALSE;
1479    if(LeftSection_FT() <= 0)
1480     {    
1481      left_section--;                
1482      if(LeftSection_FT() <= 0) return FALSE;
1483     }
1484    if(longest < 0x1000) longest = 0x1000;     
1485   }
1486
1487  Ymin=v1->y;
1488  Ymax=min(v3->y-1,drawH);
1489
1490  delta_right_u=shl10idiv(temp*((v3->u - v1->u)>>10)+((v1->u - v2->u)<<6),longest);
1491  delta_right_v=shl10idiv(temp*((v3->v - v1->v)>>10)+((v1->v - v2->v)<<6),longest);
1492
1493  return TRUE;
1494 }
1495
1496 ////////////////////////////////////////////////////////////////////////
1497 ////////////////////////////////////////////////////////////////////////
1498
1499 static inline int RightSection_GT(void)
1500 {
1501  soft_vertex * v1 = right_array[ right_section ];
1502  soft_vertex * v2 = right_array[ right_section-1 ];
1503
1504  int height = v2->y - v1->y;
1505  if(height == 0) return 0;
1506  delta_right_x = (v2->x - v1->x) / height;
1507  right_x = v1->x;
1508
1509  right_section_height = height;
1510  return height;
1511 }
1512
1513 ////////////////////////////////////////////////////////////////////////
1514
1515 static inline int LeftSection_GT(void)
1516 {
1517  soft_vertex * v1 = left_array[ left_section ];
1518  soft_vertex * v2 = left_array[ left_section-1 ];
1519
1520  int height = v2->y - v1->y;
1521  if(height == 0) return 0;
1522  delta_left_x = (v2->x - v1->x) / height;
1523  left_x = v1->x;
1524
1525  delta_left_u = ((v2->u - v1->u)) / height;
1526  left_u = v1->u;
1527  delta_left_v = ((v2->v - v1->v)) / height;
1528  left_v = v1->v;
1529
1530  delta_left_R = ((v2->R - v1->R)) / height;
1531  left_R = v1->R;
1532  delta_left_G = ((v2->G - v1->G)) / height;
1533  left_G = v1->G;
1534  delta_left_B = ((v2->B - v1->B)) / height;
1535  left_B = v1->B;
1536
1537  left_section_height = height;
1538  return height;  
1539 }
1540
1541 ////////////////////////////////////////////////////////////////////////
1542
1543 static inline BOOL NextRow_GT(void)
1544 {
1545  if(--left_section_height<=0) 
1546   {
1547    if(--left_section <= 0) {return TRUE;}
1548    if(LeftSection_GT()  <= 0) {return TRUE;}
1549   }
1550  else
1551   {
1552    left_x += delta_left_x;
1553    left_u += delta_left_u;
1554    left_v += delta_left_v;
1555    left_R += delta_left_R;
1556    left_G += delta_left_G;
1557    left_B += delta_left_B;
1558   }
1559
1560  if(--right_section_height<=0) 
1561   {
1562    if(--right_section<=0) {return TRUE;}
1563    if(RightSection_GT() <=0) {return TRUE;}
1564   }
1565  else
1566   {
1567    right_x += delta_right_x;
1568   }
1569  return FALSE;
1570 }
1571
1572 ////////////////////////////////////////////////////////////////////////
1573
1574 static inline BOOL SetupSections_GT(short x1, short y1, short x2, short y2, short x3, short y3, short tx1, short ty1, short tx2, short ty2, short tx3, short ty3, int32_t rgb1, int32_t rgb2, int32_t rgb3)
1575 {
1576  soft_vertex * v1, * v2, * v3;
1577  int height,longest,temp;
1578
1579  v1 = vtx;   v1->x=x1<<16;v1->y=y1;
1580  v1->u=tx1<<16;v1->v=ty1<<16;
1581  v1->R=(rgb1) & 0x00ff0000;
1582  v1->G=(rgb1<<8) & 0x00ff0000;
1583  v1->B=(rgb1<<16) & 0x00ff0000;
1584
1585  v2 = vtx+1; v2->x=x2<<16;v2->y=y2;
1586  v2->u=tx2<<16;v2->v=ty2<<16;
1587  v2->R=(rgb2) & 0x00ff0000;
1588  v2->G=(rgb2<<8) & 0x00ff0000;
1589  v2->B=(rgb2<<16) & 0x00ff0000;
1590              
1591  v3 = vtx+2; v3->x=x3<<16;v3->y=y3;
1592  v3->u=tx3<<16;v3->v=ty3<<16;
1593  v3->R=(rgb3) & 0x00ff0000;
1594  v3->G=(rgb3<<8) & 0x00ff0000;
1595  v3->B=(rgb3<<16) & 0x00ff0000;
1596
1597  if(v1->y > v2->y) { soft_vertex * v = v1; v1 = v2; v2 = v; }
1598  if(v1->y > v3->y) { soft_vertex * v = v1; v1 = v3; v3 = v; }
1599  if(v2->y > v3->y) { soft_vertex * v = v2; v2 = v3; v3 = v; }
1600
1601  height = v3->y - v1->y;
1602  if(height == 0) {return FALSE;}
1603
1604  temp=(((v2->y - v1->y) << 16) / height);
1605  longest = temp * ((v3->x - v1->x)>>16) + (v1->x - v2->x);
1606
1607  if(longest == 0) {return FALSE;}
1608
1609  if(longest < 0)
1610   {
1611    right_array[0] = v3;
1612    right_array[1] = v2;
1613    right_array[2] = v1;
1614    right_section  = 2;
1615    left_array[0]  = v3;
1616    left_array[1]  = v1;
1617    left_section   = 1;
1618
1619    if(LeftSection_GT() <= 0) return FALSE;
1620    if(RightSection_GT() <= 0)
1621     {
1622      right_section--;
1623      if(RightSection_GT() <= 0) return FALSE;
1624     }
1625
1626    if(longest > -0x1000) longest = -0x1000;     
1627   }
1628  else
1629   {
1630    left_array[0]  = v3;
1631    left_array[1]  = v2;
1632    left_array[2]  = v1;
1633    left_section   = 2;
1634    right_array[0] = v3;
1635    right_array[1] = v1;
1636    right_section  = 1;
1637
1638    if(RightSection_GT() <= 0) return FALSE;
1639    if(LeftSection_GT() <= 0)
1640     {    
1641      left_section--;
1642      if(LeftSection_GT() <= 0) return FALSE;
1643     }
1644    if(longest < 0x1000) longest = 0x1000;     
1645   }
1646
1647  Ymin=v1->y;
1648  Ymax=min(v3->y-1,drawH);
1649
1650  delta_right_R=shl10idiv(temp*((v3->R - v1->R)>>10)+((v1->R - v2->R)<<6),longest);
1651  delta_right_G=shl10idiv(temp*((v3->G - v1->G)>>10)+((v1->G - v2->G)<<6),longest);
1652  delta_right_B=shl10idiv(temp*((v3->B - v1->B)>>10)+((v1->B - v2->B)<<6),longest);
1653
1654  delta_right_u=shl10idiv(temp*((v3->u - v1->u)>>10)+((v1->u - v2->u)<<6),longest);
1655  delta_right_v=shl10idiv(temp*((v3->v - v1->v)>>10)+((v1->v - v2->v)<<6),longest);
1656
1657  return TRUE;
1658 }
1659
1660 ////////////////////////////////////////////////////////////////////////
1661 ////////////////////////////////////////////////////////////////////////
1662
1663 static inline int RightSection_F4(void)
1664 {
1665  soft_vertex * v1 = right_array[ right_section ];
1666  soft_vertex * v2 = right_array[ right_section-1 ];
1667
1668  int height = v2->y - v1->y;
1669  right_section_height = height;
1670  right_x = v1->x;
1671  if(height == 0) 
1672   {
1673    return 0;
1674   }
1675  delta_right_x = (v2->x - v1->x) / height;
1676
1677  return height;
1678 }
1679
1680 ////////////////////////////////////////////////////////////////////////
1681
1682 static inline int LeftSection_F4(void)
1683 {
1684  soft_vertex * v1 = left_array[ left_section ];
1685  soft_vertex * v2 = left_array[ left_section-1 ];
1686
1687  int height = v2->y - v1->y;
1688  left_section_height = height;
1689  left_x = v1->x;
1690  if(height == 0) 
1691   {
1692    return 0;
1693   }
1694  delta_left_x = (v2->x - v1->x) / height;
1695
1696  return height;  
1697 }
1698
1699 ////////////////////////////////////////////////////////////////////////
1700
1701 static inline BOOL NextRow_F4(void)
1702 {
1703  if(--left_section_height<=0) 
1704   {
1705    if(--left_section > 0) 
1706     while(LeftSection_F4()<=0) 
1707      {
1708       if(--left_section  <= 0) break;
1709      }
1710   }
1711  else
1712   {
1713    left_x += delta_left_x;
1714   }
1715
1716  if(--right_section_height<=0) 
1717   {
1718    if(--right_section > 0) 
1719     while(RightSection_F4()<=0) 
1720      {
1721       if(--right_section<=0) break;
1722      }
1723   }
1724  else
1725   {
1726    right_x += delta_right_x;
1727   }
1728  return FALSE;
1729 }
1730
1731 ////////////////////////////////////////////////////////////////////////
1732
1733 static inline BOOL SetupSections_F4(short x1, short y1, short x2, short y2, short x3, short y3, short x4, short y4)
1734 {
1735  soft_vertex * v1, * v2, * v3, * v4;
1736  int height,width,longest1,longest2;
1737
1738  v1 = vtx;   v1->x=x1<<16;v1->y=y1;
1739  v2 = vtx+1; v2->x=x2<<16;v2->y=y2;
1740  v3 = vtx+2; v3->x=x3<<16;v3->y=y3;
1741  v4 = vtx+3; v4->x=x4<<16;v4->y=y4;
1742
1743  if(v1->y > v2->y) { soft_vertex * v = v1; v1 = v2; v2 = v; }
1744  if(v1->y > v3->y) { soft_vertex * v = v1; v1 = v3; v3 = v; }
1745  if(v1->y > v4->y) { soft_vertex * v = v1; v1 = v4; v4 = v; }
1746  if(v2->y > v3->y) { soft_vertex * v = v2; v2 = v3; v3 = v; }
1747  if(v2->y > v4->y) { soft_vertex * v = v2; v2 = v4; v4 = v; }
1748  if(v3->y > v4->y) { soft_vertex * v = v3; v3 = v4; v4 = v; }
1749
1750  height = v4->y - v1->y; if(height == 0) height =1;
1751  width  = (v4->x - v1->x)>>16;
1752  longest1 = (((v2->y - v1->y) << 16) / height) * width + (v1->x - v2->x);
1753  longest2 = (((v3->y - v1->y) << 16) / height) * width + (v1->x - v3->x);
1754
1755  if(longest1 < 0)                                      // 2 is right
1756   {
1757    if(longest2 < 0)                                    // 3 is right
1758     {
1759      left_array[0]  = v4;
1760      left_array[1]  = v1;
1761      left_section   = 1;
1762
1763      height = v3->y - v1->y; if(height == 0) height=1;
1764      longest1 = (((v2->y - v1->y) << 16) / height) * ((v3->x - v1->x)>>16) + (v1->x - v2->x);
1765      if(longest1 >= 0)
1766       {
1767        right_array[0] = v4;                     //  1
1768        right_array[1] = v3;                     //     3
1769        right_array[2] = v1;                     //  4
1770        right_section  = 2;    
1771       }
1772      else
1773       {
1774        height = v4->y - v2->y; if(height == 0) height=1;
1775        longest1 = (((v3->y - v2->y) << 16) / height) * ((v4->x - v2->x)>>16) + (v2->x - v3->x);
1776        if(longest1 >= 0)
1777         {
1778          right_array[0] = v4;                    //  1
1779          right_array[1] = v2;                    //     2
1780          right_array[2] = v1;                    //  4
1781          right_section  = 2;    
1782         }
1783        else
1784         {
1785          right_array[0] = v4;                    //  1
1786          right_array[1] = v3;                    //     2
1787          right_array[2] = v2;                    //     3
1788          right_array[3] = v1;                    //  4
1789          right_section  = 3;    
1790         }
1791       }
1792     }
1793    else                                            
1794     {
1795      left_array[0]  = v4;
1796      left_array[1]  = v3;                         //    1
1797      left_array[2]  = v1;                         //      2
1798      left_section   = 2;                          //  3
1799      right_array[0] = v4;                         //    4
1800      right_array[1] = v2;
1801      right_array[2] = v1;
1802      right_section  = 2;
1803     }
1804   }
1805  else
1806   {
1807    if(longest2 < 0)             
1808     {
1809      left_array[0]  = v4;                          //    1
1810      left_array[1]  = v2;                          //  2
1811      left_array[2]  = v1;                          //      3
1812      left_section   = 2;                           //    4
1813      right_array[0] = v4;
1814      right_array[1] = v3;
1815      right_array[2] = v1;
1816      right_section  = 2;
1817     }
1818    else                         
1819     {
1820      right_array[0] = v4;
1821      right_array[1] = v1;
1822      right_section  = 1;
1823
1824      height = v3->y - v1->y; if(height == 0) height=1;
1825      longest1 = (((v2->y - v1->y) << 16) / height) * ((v3->x - v1->x)>>16) + (v1->x - v2->x);
1826      if(longest1<0)
1827       {
1828        left_array[0]  = v4;                        //    1
1829        left_array[1]  = v3;                        //  3
1830        left_array[2]  = v1;                        //    4
1831        left_section   = 2;    
1832       }
1833      else
1834       {
1835        height = v4->y - v2->y; if(height == 0) height=1;
1836        longest1 = (((v3->y - v2->y) << 16) / height) * ((v4->x - v2->x)>>16) + (v2->x - v3->x);
1837        if(longest1<0)
1838         {
1839          left_array[0]  = v4;                      //    1
1840          left_array[1]  = v2;                      //  2
1841          left_array[2]  = v1;                      //    4
1842          left_section   = 2;    
1843         }
1844        else
1845         {
1846          left_array[0]  = v4;                      //    1
1847          left_array[1]  = v3;                      //  2
1848          left_array[2]  = v2;                      //  3
1849          left_array[3]  = v1;                      //     4
1850          left_section   = 3;    
1851         }
1852       }
1853     }
1854   }
1855
1856  while(LeftSection_F4()<=0) 
1857   {
1858    if(--left_section  <= 0) break;
1859   }
1860
1861  while(RightSection_F4()<=0) 
1862   {
1863    if(--right_section <= 0) break;
1864   }
1865
1866  Ymin=v1->y;
1867  Ymax=min(v4->y-1,drawH);
1868
1869  return TRUE;
1870 }
1871
1872 ////////////////////////////////////////////////////////////////////////
1873 ////////////////////////////////////////////////////////////////////////
1874
1875 static inline int RightSection_FT4(void)
1876 {
1877  soft_vertex * v1 = right_array[ right_section ];
1878  soft_vertex * v2 = right_array[ right_section-1 ];
1879
1880  int height = v2->y - v1->y;
1881  right_section_height = height;
1882  right_x = v1->x;
1883  right_u = v1->u;
1884  right_v = v1->v;
1885  if(height == 0) 
1886   {
1887    return 0;
1888   }
1889  delta_right_x = (v2->x - v1->x) / height;
1890  delta_right_u = (v2->u - v1->u) / height;
1891  delta_right_v = (v2->v - v1->v) / height;
1892
1893  return height;
1894 }
1895
1896 ////////////////////////////////////////////////////////////////////////
1897
1898 static inline int LeftSection_FT4(void)
1899 {
1900  soft_vertex * v1 = left_array[ left_section ];
1901  soft_vertex * v2 = left_array[ left_section-1 ];
1902
1903  int height = v2->y - v1->y;
1904  left_section_height = height;
1905  left_x = v1->x;
1906  left_u = v1->u;
1907  left_v = v1->v;
1908  if(height == 0) 
1909   {
1910    return 0;
1911   }
1912  delta_left_x = (v2->x - v1->x) / height;
1913  delta_left_u = (v2->u - v1->u) / height;
1914  delta_left_v = (v2->v - v1->v) / height;
1915
1916  return height;  
1917 }
1918
1919 ////////////////////////////////////////////////////////////////////////
1920
1921 static inline BOOL NextRow_FT4(void)
1922 {
1923  if(--left_section_height<=0) 
1924   {
1925    if(--left_section > 0) 
1926     while(LeftSection_FT4()<=0) 
1927      {
1928       if(--left_section  <= 0) break;
1929      }
1930   }
1931  else
1932   {
1933    left_x += delta_left_x;
1934    left_u += delta_left_u;
1935    left_v += delta_left_v;
1936   }
1937
1938  if(--right_section_height<=0) 
1939   {
1940    if(--right_section > 0) 
1941     while(RightSection_FT4()<=0) 
1942      {
1943       if(--right_section<=0) break;
1944      }
1945   }
1946  else
1947   {
1948    right_x += delta_right_x;
1949    right_u += delta_right_u;
1950    right_v += delta_right_v;
1951   }
1952  return FALSE;
1953 }
1954
1955 ////////////////////////////////////////////////////////////////////////
1956
1957 static inline BOOL SetupSections_FT4(short x1, short y1, short x2, short y2, short x3, short y3, short x4, short y4, short tx1, short ty1, short tx2, short ty2, short tx3, short ty3, short tx4, short ty4)
1958 {
1959  soft_vertex * v1, * v2, * v3, * v4;
1960  int height,width,longest1,longest2;
1961
1962  v1 = vtx;   v1->x=x1<<16;v1->y=y1;
1963  v1->u=tx1<<16;v1->v=ty1<<16;
1964
1965  v2 = vtx+1; v2->x=x2<<16;v2->y=y2;
1966  v2->u=tx2<<16;v2->v=ty2<<16;
1967              
1968  v3 = vtx+2; v3->x=x3<<16;v3->y=y3;
1969  v3->u=tx3<<16;v3->v=ty3<<16;
1970
1971  v4 = vtx+3; v4->x=x4<<16;v4->y=y4;
1972  v4->u=tx4<<16;v4->v=ty4<<16;
1973
1974  if(v1->y > v2->y) { soft_vertex * v = v1; v1 = v2; v2 = v; }
1975  if(v1->y > v3->y) { soft_vertex * v = v1; v1 = v3; v3 = v; }
1976  if(v1->y > v4->y) { soft_vertex * v = v1; v1 = v4; v4 = v; }
1977  if(v2->y > v3->y) { soft_vertex * v = v2; v2 = v3; v3 = v; }
1978  if(v2->y > v4->y) { soft_vertex * v = v2; v2 = v4; v4 = v; }
1979  if(v3->y > v4->y) { soft_vertex * v = v3; v3 = v4; v4 = v; }
1980
1981  height = v4->y - v1->y; if(height == 0) height =1;
1982  width  = (v4->x - v1->x)>>16;
1983  longest1 = (((v2->y - v1->y) << 16) / height) * width + (v1->x - v2->x);
1984  longest2 = (((v3->y - v1->y) << 16) / height) * width + (v1->x - v3->x);
1985
1986  if(longest1 < 0)                                      // 2 is right
1987   {
1988    if(longest2 < 0)                                    // 3 is right
1989     {
1990      left_array[0]  = v4;
1991      left_array[1]  = v1;
1992      left_section   = 1;
1993
1994      height = v3->y - v1->y; if(height == 0) height=1;
1995      longest1 = (((v2->y - v1->y) << 16) / height) * ((v3->x - v1->x)>>16) + (v1->x - v2->x);
1996      if(longest1 >= 0)
1997       {
1998        right_array[0] = v4;                     //  1
1999        right_array[1] = v3;                     //     3
2000        right_array[2] = v1;                     //  4
2001        right_section  = 2;    
2002       }
2003      else
2004       {
2005        height = v4->y - v2->y; if(height == 0) height=1;
2006        longest1 = (((v3->y - v2->y) << 16) / height) * ((v4->x - v2->x)>>16) + (v2->x - v3->x);
2007        if(longest1 >= 0)
2008         {
2009          right_array[0] = v4;                    //  1
2010          right_array[1] = v2;                    //     2
2011          right_array[2] = v1;                    //  4
2012          right_section  = 2;    
2013         }
2014        else
2015         {
2016          right_array[0] = v4;                    //  1
2017          right_array[1] = v3;                    //     2
2018          right_array[2] = v2;                    //     3
2019          right_array[3] = v1;                    //  4
2020          right_section  = 3;    
2021         }
2022       }
2023     }
2024    else                                            
2025     {
2026      left_array[0]  = v4;
2027      left_array[1]  = v3;                         //    1
2028      left_array[2]  = v1;                         //      2
2029      left_section   = 2;                          //  3
2030      right_array[0] = v4;                         //    4
2031      right_array[1] = v2;
2032      right_array[2] = v1;
2033      right_section  = 2;
2034     }
2035   }
2036  else
2037   {
2038    if(longest2 < 0)             
2039     {
2040      left_array[0]  = v4;                          //    1
2041      left_array[1]  = v2;                          //  2
2042      left_array[2]  = v1;                          //      3
2043      left_section   = 2;                           //    4
2044      right_array[0] = v4;
2045      right_array[1] = v3;
2046      right_array[2] = v1;
2047      right_section  = 2;
2048     }
2049    else                         
2050     {
2051      right_array[0] = v4;
2052      right_array[1] = v1;
2053      right_section  = 1;
2054
2055      height = v3->y - v1->y; if(height == 0) height=1;
2056      longest1 = (((v2->y - v1->y) << 16) / height) * ((v3->x - v1->x)>>16) + (v1->x - v2->x);
2057      if(longest1<0)
2058       {
2059        left_array[0]  = v4;                        //    1
2060        left_array[1]  = v3;                        //  3
2061        left_array[2]  = v1;                        //    4
2062        left_section   = 2;    
2063       }
2064      else
2065       {
2066        height = v4->y - v2->y; if(height == 0) height=1;
2067        longest1 = (((v3->y - v2->y) << 16) / height) * ((v4->x - v2->x)>>16) + (v2->x - v3->x);
2068        if(longest1<0)
2069         {
2070          left_array[0]  = v4;                      //    1
2071          left_array[1]  = v2;                      //  2
2072          left_array[2]  = v1;                      //    4
2073          left_section   = 2;    
2074         }
2075        else
2076         {
2077          left_array[0]  = v4;                      //    1
2078          left_array[1]  = v3;                      //  2
2079          left_array[2]  = v2;                      //  3
2080          left_array[3]  = v1;                      //     4
2081          left_section   = 3;    
2082         }
2083       }
2084     }
2085   }
2086
2087  while(LeftSection_FT4()<=0) 
2088   {
2089    if(--left_section  <= 0) break;
2090   }
2091
2092  while(RightSection_FT4()<=0) 
2093   {
2094    if(--right_section <= 0) break;
2095   }
2096
2097  Ymin=v1->y;
2098  Ymax=min(v4->y-1,drawH);
2099
2100  return TRUE;
2101 }
2102
2103 ////////////////////////////////////////////////////////////////////////
2104 ////////////////////////////////////////////////////////////////////////
2105
2106 static inline int RightSection_GT4(void)
2107 {
2108  soft_vertex * v1 = right_array[ right_section ];
2109  soft_vertex * v2 = right_array[ right_section-1 ];
2110
2111  int height = v2->y - v1->y;
2112  right_section_height = height;
2113  right_x = v1->x;
2114  right_u = v1->u;
2115  right_v = v1->v;
2116  right_R = v1->R;
2117  right_G = v1->G;
2118  right_B = v1->B;
2119
2120  if(height == 0) 
2121   {
2122    return 0;
2123   }
2124  delta_right_x = (v2->x - v1->x) / height;
2125  delta_right_u = (v2->u - v1->u) / height;
2126  delta_right_v = (v2->v - v1->v) / height;
2127  delta_right_R = (v2->R - v1->R) / height;
2128  delta_right_G = (v2->G - v1->G) / height;
2129  delta_right_B = (v2->B - v1->B) / height;
2130
2131  return height;
2132 }
2133
2134 ////////////////////////////////////////////////////////////////////////
2135
2136 static inline int LeftSection_GT4(void)
2137 {
2138  soft_vertex * v1 = left_array[ left_section ];
2139  soft_vertex * v2 = left_array[ left_section-1 ];
2140
2141  int height = v2->y - v1->y;
2142  left_section_height = height;
2143  left_x = v1->x;
2144  left_u = v1->u;
2145  left_v = v1->v;
2146  left_R = v1->R;
2147  left_G = v1->G;
2148  left_B = v1->B;
2149
2150  if(height == 0) 
2151   {
2152    return 0;
2153   }
2154  delta_left_x = (v2->x - v1->x) / height;
2155  delta_left_u = (v2->u - v1->u) / height;
2156  delta_left_v = (v2->v - v1->v) / height;
2157  delta_left_R = (v2->R - v1->R) / height;
2158  delta_left_G = (v2->G - v1->G) / height;
2159  delta_left_B = (v2->B - v1->B) / height;
2160
2161  return height;  
2162 }
2163
2164 ////////////////////////////////////////////////////////////////////////
2165
2166 static inline BOOL NextRow_GT4(void)
2167 {
2168  if(--left_section_height<=0) 
2169   {
2170    if(--left_section > 0) 
2171     while(LeftSection_GT4()<=0) 
2172      {
2173       if(--left_section  <= 0) break;
2174      }
2175   }
2176  else
2177   {
2178    left_x += delta_left_x;
2179    left_u += delta_left_u;
2180    left_v += delta_left_v;
2181    left_R += delta_left_R;
2182    left_G += delta_left_G;
2183    left_B += delta_left_B;
2184   }
2185
2186  if(--right_section_height<=0) 
2187   {
2188    if(--right_section > 0) 
2189     while(RightSection_GT4()<=0) 
2190      {
2191       if(--right_section<=0) break;
2192      }
2193   }
2194  else
2195   {
2196    right_x += delta_right_x;
2197    right_u += delta_right_u;
2198    right_v += delta_right_v;
2199    right_R += delta_right_R;
2200    right_G += delta_right_G;
2201    right_B += delta_right_B;
2202   }
2203  return FALSE;
2204 }
2205
2206 ////////////////////////////////////////////////////////////////////////
2207
2208 static inline BOOL SetupSections_GT4(short x1, short y1, short x2, short y2, short x3, short y3, short x4, short y4, short tx1, short ty1, short tx2, short ty2, short tx3, short ty3, short tx4, short ty4,int32_t rgb1,int32_t rgb2,int32_t rgb3,int32_t rgb4)
2209 {
2210  soft_vertex * v1, * v2, * v3, * v4;
2211  int height,width,longest1,longest2;
2212
2213  v1 = vtx;   v1->x=x1<<16;v1->y=y1;
2214  v1->u=tx1<<16;v1->v=ty1<<16;
2215  v1->R=(rgb1) & 0x00ff0000;
2216  v1->G=(rgb1<<8) & 0x00ff0000;
2217  v1->B=(rgb1<<16) & 0x00ff0000;
2218
2219  v2 = vtx+1; v2->x=x2<<16;v2->y=y2;
2220  v2->u=tx2<<16;v2->v=ty2<<16;
2221  v2->R=(rgb2) & 0x00ff0000;
2222  v2->G=(rgb2<<8) & 0x00ff0000;
2223  v2->B=(rgb2<<16) & 0x00ff0000;
2224              
2225  v3 = vtx+2; v3->x=x3<<16;v3->y=y3;
2226  v3->u=tx3<<16;v3->v=ty3<<16;
2227  v3->R=(rgb3) & 0x00ff0000;
2228  v3->G=(rgb3<<8) & 0x00ff0000;
2229  v3->B=(rgb3<<16) & 0x00ff0000;
2230
2231  v4 = vtx+3; v4->x=x4<<16;v4->y=y4;
2232  v4->u=tx4<<16;v4->v=ty4<<16;
2233  v4->R=(rgb4) & 0x00ff0000;
2234  v4->G=(rgb4<<8) & 0x00ff0000;
2235  v4->B=(rgb4<<16) & 0x00ff0000;
2236
2237  if(v1->y > v2->y) { soft_vertex * v = v1; v1 = v2; v2 = v; }
2238  if(v1->y > v3->y) { soft_vertex * v = v1; v1 = v3; v3 = v; }
2239  if(v1->y > v4->y) { soft_vertex * v = v1; v1 = v4; v4 = v; }
2240  if(v2->y > v3->y) { soft_vertex * v = v2; v2 = v3; v3 = v; }
2241  if(v2->y > v4->y) { soft_vertex * v = v2; v2 = v4; v4 = v; }
2242  if(v3->y > v4->y) { soft_vertex * v = v3; v3 = v4; v4 = v; }
2243
2244  height = v4->y - v1->y; if(height == 0) height =1;
2245  width  = (v4->x - v1->x)>>16;
2246  longest1 = (((v2->y - v1->y) << 16) / height) * width + (v1->x - v2->x);
2247  longest2 = (((v3->y - v1->y) << 16) / height) * width + (v1->x - v3->x);
2248
2249  if(longest1 < 0)                                      // 2 is right
2250   {
2251    if(longest2 < 0)                                    // 3 is right
2252     {
2253      left_array[0]  = v4;
2254      left_array[1]  = v1;
2255      left_section   = 1;
2256
2257      height = v3->y - v1->y; if(height == 0) height=1;
2258      longest1 = (((v2->y - v1->y) << 16) / height) * ((v3->x - v1->x)>>16) + (v1->x - v2->x);
2259      if(longest1 >= 0)
2260       {
2261        right_array[0] = v4;                     //  1
2262        right_array[1] = v3;                     //     3
2263        right_array[2] = v1;                     //  4
2264        right_section  = 2;    
2265       }
2266      else
2267       {
2268        height = v4->y - v2->y; if(height == 0) height=1;
2269        longest1 = (((v3->y - v2->y) << 16) / height) * ((v4->x - v2->x)>>16) + (v2->x - v3->x);
2270        if(longest1 >= 0)
2271         {
2272          right_array[0] = v4;                    //  1
2273          right_array[1] = v2;                    //     2
2274          right_array[2] = v1;                    //  4
2275          right_section  = 2;    
2276         }
2277        else
2278         {
2279          right_array[0] = v4;                    //  1
2280          right_array[1] = v3;                    //     2
2281          right_array[2] = v2;                    //     3
2282          right_array[3] = v1;                    //  4
2283          right_section  = 3;    
2284         }
2285       }
2286     }
2287    else                                            
2288     {
2289      left_array[0]  = v4;
2290      left_array[1]  = v3;                         //    1
2291      left_array[2]  = v1;                         //      2
2292      left_section   = 2;                          //  3
2293      right_array[0] = v4;                         //    4
2294      right_array[1] = v2;
2295      right_array[2] = v1;
2296      right_section  = 2;
2297     }
2298   }
2299  else
2300   {
2301    if(longest2 < 0)             
2302     {
2303      left_array[0]  = v4;                          //    1
2304      left_array[1]  = v2;                          //  2
2305      left_array[2]  = v1;                          //      3
2306      left_section   = 2;                           //    4
2307      right_array[0] = v4;
2308      right_array[1] = v3;
2309      right_array[2] = v1;
2310      right_section  = 2;
2311     }
2312    else                         
2313     {
2314      right_array[0] = v4;
2315      right_array[1] = v1;
2316      right_section  = 1;
2317
2318      height = v3->y - v1->y; if(height == 0) height=1;
2319      longest1 = (((v2->y - v1->y) << 16) / height) * ((v3->x - v1->x)>>16) + (v1->x - v2->x);
2320      if(longest1<0)
2321       {
2322        left_array[0]  = v4;                        //    1
2323        left_array[1]  = v3;                        //  3
2324        left_array[2]  = v1;                        //    4
2325        left_section   = 2;    
2326       }
2327      else
2328       {
2329        height = v4->y - v2->y; if(height == 0) height=1;
2330        longest1 = (((v3->y - v2->y) << 16) / height) * ((v4->x - v2->x)>>16) + (v2->x - v3->x);
2331        if(longest1<0)
2332         {
2333          left_array[0]  = v4;                      //    1
2334          left_array[1]  = v2;                      //  2
2335          left_array[2]  = v1;                      //    4
2336          left_section   = 2;    
2337         }
2338        else
2339         {
2340          left_array[0]  = v4;                      //    1
2341          left_array[1]  = v3;                      //  2
2342          left_array[2]  = v2;                      //  3
2343          left_array[3]  = v1;                      //     4
2344          left_section   = 3;    
2345         }
2346       }
2347     }
2348   }
2349
2350  while(LeftSection_GT4()<=0) 
2351   {
2352    if(--left_section  <= 0) break;
2353   }
2354
2355  while(RightSection_GT4()<=0) 
2356   {
2357    if(--right_section <= 0) break;
2358   }
2359
2360  Ymin=v1->y;
2361  Ymax=min(v4->y-1,drawH);
2362
2363  return TRUE;
2364 }
2365
2366 ////////////////////////////////////////////////////////////////////////
2367 ////////////////////////////////////////////////////////////////////////
2368 ////////////////////////////////////////////////////////////////////////
2369 // POLY FUNCS
2370 ////////////////////////////////////////////////////////////////////////
2371 ////////////////////////////////////////////////////////////////////////
2372 ////////////////////////////////////////////////////////////////////////
2373
2374 ////////////////////////////////////////////////////////////////////////
2375 // POLY 3/4 FLAT SHADED
2376 ////////////////////////////////////////////////////////////////////////
2377
2378 static inline void drawPoly3Fi(short x1,short y1,short x2,short y2,short x3,short y3,int32_t rgb)
2379 {
2380  int i,j,xmin,xmax,ymin,ymax;
2381  unsigned short color;uint32_t lcolor;
2382
2383  if(x1>drawW && x2>drawW && x3>drawW) return;
2384  if(y1>drawH && y2>drawH && y3>drawH) return;
2385  if(x1<drawX && x2<drawX && x3<drawX) return;
2386  if(y1<drawY && y2<drawY && y3<drawY) return;
2387  if(drawY>=drawH) return;
2388  if(drawX>=drawW) return; 
2389
2390  if(!SetupSections_F(x1,y1,x2,y2,x3,y3)) return;
2391
2392  ymax=Ymax;
2393
2394  color = ((rgb & 0x00f80000)>>9) | ((rgb & 0x0000f800)>>6) | ((rgb & 0x000000f8)>>3);
2395  lcolor=lSetMask|(((uint32_t)(color))<<16)|color;
2396
2397  for(ymin=Ymin;ymin<drawY;ymin++)
2398   if(NextRow_F()) return;
2399
2400 #ifdef FASTSOLID
2401
2402  if(!bCheckMask && !DrawSemiTrans)
2403   {
2404    color |=sSetMask;
2405    for (i=ymin;i<=ymax;i++)
2406     {
2407      xmin=left_x >> 16;      if(drawX>xmin) xmin=drawX;
2408      xmax=(right_x >> 16)-1; if(drawW<xmax) xmax=drawW;
2409
2410      for(j=xmin;j<xmax;j+=2) 
2411       {
2412        PUTLE32(((uint32_t *)&psxVuw[(i<<10)+j]), lcolor);
2413       }
2414      if(j==xmax) PUTLE16(&psxVuw[(i<<10)+j], color);
2415
2416      if(NextRow_F()) return;
2417     }
2418    return;
2419   }
2420
2421 #endif
2422
2423  for (i=ymin;i<=ymax;i++)
2424   {
2425    xmin=left_x >> 16;      if(drawX>xmin) xmin=drawX;
2426    xmax=(right_x >> 16)-1; if(drawW<xmax) xmax=drawW;
2427
2428    for(j=xmin;j<xmax;j+=2) 
2429     {
2430      GetShadeTransCol32((uint32_t *)&psxVuw[(i<<10)+j],lcolor);
2431     }
2432    if(j==xmax)
2433     GetShadeTransCol(&psxVuw[(i<<10)+j],color);
2434
2435    if(NextRow_F()) return;
2436   }
2437 }
2438
2439 ////////////////////////////////////////////////////////////////////////
2440
2441 static void drawPoly3F(int32_t rgb)
2442 {
2443  drawPoly3Fi(lx0,ly0,lx1,ly1,lx2,ly2,rgb);
2444 }
2445
2446 #ifdef POLYQUAD3FS
2447
2448 static void drawPoly4F_TRI(int32_t rgb)
2449 {
2450  drawPoly3Fi(lx1,ly1,lx3,ly3,lx2,ly2,rgb);
2451  drawPoly3Fi(lx0,ly0,lx1,ly1,lx2,ly2,rgb);
2452 }
2453
2454 #endif
2455
2456 // more exact:
2457
2458 static void drawPoly4F(int32_t rgb)
2459 {
2460  int i,j,xmin,xmax,ymin,ymax;
2461  unsigned short color;uint32_t lcolor;
2462  
2463  if(lx0>drawW && lx1>drawW && lx2>drawW && lx3>drawW) return;
2464  if(ly0>drawH && ly1>drawH && ly2>drawH && ly3>drawH) return;
2465  if(lx0<drawX && lx1<drawX && lx2<drawX && lx3<drawX) return;
2466  if(ly0<drawY && ly1<drawY && ly2<drawY && ly3<drawY) return;
2467  if(drawY>=drawH) return;
2468  if(drawX>=drawW) return; 
2469
2470  if(!SetupSections_F4(lx0,ly0,lx1,ly1,lx2,ly2,lx3,ly3)) return;
2471
2472  ymax=Ymax;
2473
2474  for(ymin=Ymin;ymin<drawY;ymin++)
2475   if(NextRow_F4()) return;
2476
2477  color = ((rgb & 0x00f80000)>>9) | ((rgb & 0x0000f800)>>6) | ((rgb & 0x000000f8)>>3);
2478  lcolor= lSetMask|(((uint32_t)(color))<<16)|color;
2479
2480 #ifdef FASTSOLID
2481
2482  if(!bCheckMask && !DrawSemiTrans)
2483   {
2484    color |=sSetMask;
2485    for (i=ymin;i<=ymax;i++)
2486     {
2487      xmin=left_x >> 16;      if(drawX>xmin) xmin=drawX;
2488      xmax=(right_x >> 16)-1; if(drawW<xmax) xmax=drawW;
2489
2490      for(j=xmin;j<xmax;j+=2) 
2491       {
2492        PUTLE32(((uint32_t *)&psxVuw[(i<<10)+j]), lcolor);
2493       }
2494      if(j==xmax) PUTLE16(&psxVuw[(i<<10)+j], color);
2495
2496      if(NextRow_F4()) return;
2497     }
2498    return;
2499   }                                                        
2500
2501 #endif
2502
2503  for (i=ymin;i<=ymax;i++)
2504   {
2505    xmin=left_x >> 16;      if(drawX>xmin) xmin=drawX;
2506    xmax=(right_x >> 16)-1; if(drawW<xmax) xmax=drawW;
2507
2508    for(j=xmin;j<xmax;j+=2) 
2509     {
2510      GetShadeTransCol32((uint32_t *)&psxVuw[(i<<10)+j],lcolor);
2511     }
2512    if(j==xmax) GetShadeTransCol(&psxVuw[(i<<10)+j],color);
2513
2514    if(NextRow_F4()) return;
2515   }
2516 }
2517
2518 ////////////////////////////////////////////////////////////////////////
2519 // POLY 3/4 F-SHADED TEX PAL 4
2520 ////////////////////////////////////////////////////////////////////////
2521
2522 static void drawPoly3TEx4(short x1, short y1, short x2, short y2, short x3, short y3, short tx1, short ty1, short tx2, short ty2, short tx3, short ty3,short clX, short clY)
2523 {
2524  int i,j,xmin,xmax,ymin,ymax;
2525  int32_t difX, difY,difX2, difY2;
2526  int32_t posX,posY,YAdjust,XAdjust;
2527  int32_t clutP;
2528  short tC1,tC2;
2529  
2530  if(x1>drawW && x2>drawW && x3>drawW) return;
2531  if(y1>drawH && y2>drawH && y3>drawH) return;
2532  if(x1<drawX && x2<drawX && x3<drawX) return;
2533  if(y1<drawY && y2<drawY && y3<drawY) return;
2534  if(drawY>=drawH) return;
2535  if(drawX>=drawW) return; 
2536
2537  if(!SetupSections_FT(x1,y1,x2,y2,x3,y3,tx1,ty1,tx2,ty2,tx3,ty3)) return;
2538
2539  ymax=Ymax;
2540
2541  for(ymin=Ymin;ymin<drawY;ymin++)
2542   if(NextRow_FT()) return;
2543
2544  clutP=(clY<<10)+clX;
2545
2546  YAdjust=((GlobalTextAddrY)<<11)+(GlobalTextAddrX<<1);
2547
2548  difX=delta_right_u;difX2=difX<<1;
2549  difY=delta_right_v;difY2=difY<<1;
2550
2551 #ifdef FASTSOLID
2552
2553  if(!bCheckMask && !DrawSemiTrans)
2554   {
2555    for (i=ymin;i<=ymax;i++)
2556     {
2557      xmin=(left_x >> 16);
2558      xmax=(right_x >> 16)-1; //!!!!!!!!!!!!!!!!
2559      if(drawW<xmax) xmax=drawW;
2560
2561      if(xmax>=xmin)
2562       {
2563        posX=left_u;
2564        posY=left_v;
2565
2566        if(xmin<drawX)
2567         {j=drawX-xmin;xmin=drawX;posX+=j*difX;posY+=j*difY;}
2568
2569        for(j=xmin;j<xmax;j+=2)
2570         {
2571          XAdjust=(posX>>16);
2572          tC1 = psxVub[((posY>>5)&(int32_t)0xFFFFF800)+YAdjust+(XAdjust>>1)];
2573          tC1=(tC1>>((XAdjust&1)<<2))&0xf;
2574          XAdjust=((posX+difX)>>16);
2575          tC2 = psxVub[(((posY+difY)>>5)&(int32_t)0xFFFFF800)+YAdjust+
2576                     (XAdjust>>1)];
2577          tC2=(tC2>>((XAdjust&1)<<2))&0xf;
2578
2579          GetTextureTransColG32_S((uint32_t *)&psxVuw[(i<<10)+j],
2580              GETLE16(&psxVuw[clutP+tC1])|
2581              ((int32_t)GETLE16(&psxVuw[clutP+tC2]))<<16);
2582
2583          posX+=difX2;
2584          posY+=difY2;
2585         }
2586        if(j==xmax)
2587         {
2588          XAdjust=(posX>>16);
2589          tC1 = psxVub[((posY>>5)&(int32_t)0xFFFFF800)+YAdjust+
2590                       (XAdjust>>1)];
2591          tC1=(tC1>>((XAdjust&1)<<2))&0xf;
2592          GetTextureTransColG_S(&psxVuw[(i<<10)+j],GETLE16(&psxVuw[clutP+tC1]));
2593         }
2594       }
2595      if(NextRow_FT()) 
2596       {
2597        return;
2598       }
2599     }
2600    return;
2601   }
2602
2603 #endif
2604
2605  for (i=ymin;i<=ymax;i++)
2606   {
2607    xmin=(left_x >> 16);
2608    xmax=(right_x >> 16)-1; //!!!!!!!!!!!!!!!!!!
2609    if(drawW<xmax) xmax=drawW;
2610
2611    if(xmax>=xmin)
2612     {
2613      posX=left_u;
2614      posY=left_v;
2615
2616      if(xmin<drawX)
2617       {j=drawX-xmin;xmin=drawX;posX+=j*difX;posY+=j*difY;}
2618
2619      for(j=xmin;j<xmax;j+=2)
2620       {
2621        XAdjust=(posX>>16);
2622        tC1 = psxVub[((posY>>5)&(int32_t)0xFFFFF800)+YAdjust+(XAdjust>>1)];
2623        tC1=(tC1>>((XAdjust&1)<<2))&0xf;
2624        XAdjust=((posX+difX)>>16);
2625        tC2 = psxVub[(((posY+difY)>>5)&(int32_t)0xFFFFF800)+YAdjust+
2626                     (XAdjust>>1)];
2627        tC2=(tC2>>((XAdjust&1)<<2))&0xf;
2628
2629        GetTextureTransColG32((uint32_t *)&psxVuw[(i<<10)+j],
2630            GETLE16(&psxVuw[clutP+tC1])|
2631            ((int32_t)GETLE16(&psxVuw[clutP+tC2]))<<16);
2632
2633        posX+=difX2;
2634        posY+=difY2;
2635       }
2636      if(j==xmax)
2637       {
2638        XAdjust=(posX>>16);
2639        tC1 = psxVub[((posY>>5)&(int32_t)0xFFFFF800)+YAdjust+
2640                     (XAdjust>>1)];
2641        tC1=(tC1>>((XAdjust&1)<<2))&0xf;
2642        GetTextureTransColG(&psxVuw[(i<<10)+j],GETLE16(&psxVuw[clutP+tC1]));
2643       }
2644     }
2645    if(NextRow_FT()) 
2646     {
2647      return;
2648     }
2649   }
2650 }
2651
2652 ////////////////////////////////////////////////////////////////////////
2653
2654 static void drawPoly3TEx4_IL(short x1, short y1, short x2, short y2, short x3, short y3, short tx1, short ty1, short tx2, short ty2, short tx3, short ty3,short clX, short clY)
2655 {
2656  int i,j,xmin,xmax,ymin,ymax,n_xi,n_yi,TXV;
2657  int32_t difX, difY,difX2, difY2;
2658  int32_t posX,posY,YAdjust,XAdjust;
2659  int32_t clutP;
2660  short tC1,tC2;
2661  
2662  if(x1>drawW && x2>drawW && x3>drawW) return;
2663  if(y1>drawH && y2>drawH && y3>drawH) return;
2664  if(x1<drawX && x2<drawX && x3<drawX) return;
2665  if(y1<drawY && y2<drawY && y3<drawY) return;
2666  if(drawY>=drawH) return;
2667  if(drawX>=drawW) return; 
2668
2669  if(!SetupSections_FT(x1,y1,x2,y2,x3,y3,tx1,ty1,tx2,ty2,tx3,ty3)) return;
2670
2671  ymax=Ymax;
2672
2673  for(ymin=Ymin;ymin<drawY;ymin++)
2674   if(NextRow_FT()) return;
2675
2676  clutP=(clY<<10)+clX;
2677
2678  YAdjust=(GlobalTextAddrY<<10)+GlobalTextAddrX;
2679
2680  difX=delta_right_u;difX2=difX<<1;
2681  difY=delta_right_v;difY2=difY<<1;
2682
2683 #ifdef FASTSOLID
2684
2685  if(!bCheckMask && !DrawSemiTrans)
2686   {
2687    for (i=ymin;i<=ymax;i++)
2688     {
2689      xmin=(left_x >> 16);
2690      xmax=(right_x >> 16)-1;
2691      if(drawW<xmax) xmax=drawW;
2692
2693      if(xmax>=xmin)
2694       {
2695        posX=left_u;
2696        posY=left_v;
2697
2698        if(xmin<drawX)
2699         {j=drawX-xmin;xmin=drawX;posX+=j*difX;posY+=j*difY;}
2700
2701        for(j=xmin;j<xmax;j+=2)
2702         {
2703          XAdjust=(posX>>16);
2704
2705          TXV=posY>>16;
2706          n_xi = ( ( XAdjust >> 2 ) & ~0x3c ) + ( ( TXV << 2 ) & 0x3c );
2707          n_yi = ( TXV & ~0xf ) + ( ( XAdjust >> 4 ) & 0xf );
2708
2709          tC1= (GETLE16(&psxVuw[(n_yi<<10)+YAdjust+n_xi]) >> ((XAdjust & 0x03)<<2)) & 0x0f ;
2710
2711          XAdjust=((posX+difX)>>16);
2712
2713          TXV=(posY+difY)>>16;
2714          n_xi = ( ( XAdjust >> 2 ) & ~0x3c ) + ( ( TXV << 2 ) & 0x3c );
2715          n_yi = ( TXV & ~0xf ) + ( ( XAdjust >> 4 ) & 0xf );
2716
2717          tC2= (GETLE16(&psxVuw[(n_yi<<10)+YAdjust+n_xi]) >> ((XAdjust & 0x03)<<2)) & 0x0f ;
2718
2719          GetTextureTransColG32_S((uint32_t *)&psxVuw[(i<<10)+j],
2720              GETLE16(&psxVuw[clutP+tC1])|
2721              ((int32_t)GETLE16(&psxVuw[clutP+tC2]))<<16);
2722
2723          posX+=difX2;
2724          posY+=difY2;
2725         }
2726        if(j==xmax)
2727         {
2728          XAdjust=(posX>>16);
2729
2730          TXV=posY>>16;
2731          n_xi = ( ( XAdjust >> 2 ) & ~0x3c ) + ( ( TXV << 2 ) & 0x3c );
2732          n_yi = ( TXV & ~0xf ) + ( ( XAdjust >> 4 ) & 0xf );
2733
2734          tC1= (GETLE16(&psxVuw[(n_yi<<10)+YAdjust+n_xi]) >> ((XAdjust & 0x03)<<2)) & 0x0f ;
2735
2736          GetTextureTransColG_S(&psxVuw[(i<<10)+j],GETLE16(&psxVuw[clutP+tC1]));
2737         }
2738       }
2739      if(NextRow_FT()) 
2740       {
2741        return;
2742       }
2743     }
2744    return;
2745   }
2746
2747 #endif
2748
2749  for (i=ymin;i<=ymax;i++)
2750   {
2751    xmin=(left_x >> 16);
2752    xmax=(right_x >> 16)-1; //!!!!!!!!!!!!!!!!!!
2753    if(drawW<xmax) xmax=drawW;
2754
2755    if(xmax>=xmin)
2756     {
2757      posX=left_u;
2758      posY=left_v;
2759
2760      if(xmin<drawX)
2761       {j=drawX-xmin;xmin=drawX;posX+=j*difX;posY+=j*difY;}
2762
2763      for(j=xmin;j<xmax;j+=2)
2764       {
2765        XAdjust=(posX>>16);
2766
2767        TXV=posY>>16;
2768        n_xi = ( ( XAdjust >> 2 ) & ~0x3c ) + ( ( TXV << 2 ) & 0x3c );
2769        n_yi = ( TXV & ~0xf ) + ( ( XAdjust >> 4 ) & 0xf );
2770
2771        tC1= (GETLE16(&psxVuw[(n_yi<<10)+YAdjust+n_xi]) >> ((XAdjust & 0x03)<<2)) & 0x0f ;
2772
2773        XAdjust=((posX+difX)>>16);
2774
2775        TXV=(posY+difY)>>16;
2776        n_xi = ( ( XAdjust >> 2 ) & ~0x3c ) + ( ( TXV << 2 ) & 0x3c );
2777        n_yi = ( TXV & ~0xf ) + ( ( XAdjust >> 4 ) & 0xf );
2778
2779        tC2= (GETLE16(&psxVuw[(n_yi<<10)+YAdjust+n_xi]) >> ((XAdjust & 0x03)<<2)) & 0x0f ;
2780
2781        GetTextureTransColG32((uint32_t *)&psxVuw[(i<<10)+j],
2782            GETLE16(&psxVuw[clutP+tC1])|
2783            ((int32_t)GETLE16(&psxVuw[clutP+tC2]))<<16);
2784
2785        posX+=difX2;
2786        posY+=difY2;
2787       }
2788      if(j==xmax)
2789       {
2790        XAdjust=(posX>>16);
2791
2792        TXV=posY>>16;
2793        n_xi = ( ( XAdjust >> 2 ) & ~0x3c ) + ( ( TXV << 2 ) & 0x3c );
2794        n_yi = ( TXV & ~0xf ) + ( ( XAdjust >> 4 ) & 0xf );
2795
2796        tC1= (GETLE16(&psxVuw[(n_yi<<10)+YAdjust+n_xi]) >> ((XAdjust & 0x03)<<2)) & 0x0f ;
2797
2798        GetTextureTransColG(&psxVuw[(i<<10)+j],GETLE16(&psxVuw[clutP+tC1]));
2799       }
2800     }
2801    if(NextRow_FT()) 
2802     {
2803      return;
2804     }
2805   }
2806 }
2807
2808 ////////////////////////////////////////////////////////////////////////
2809
2810 static void drawPoly3TEx4_TW(short x1, short y1, short x2, short y2, short x3, short y3, short tx1, short ty1, short tx2, short ty2, short tx3, short ty3,short clX, short clY)
2811 {
2812  int i,j,xmin,xmax,ymin,ymax;
2813  int32_t difX, difY,difX2, difY2;
2814  int32_t posX,posY,YAdjust,XAdjust;
2815  int32_t clutP;
2816  short tC1,tC2;
2817  
2818  if(x1>drawW && x2>drawW && x3>drawW) return;
2819  if(y1>drawH && y2>drawH && y3>drawH) return;
2820  if(x1<drawX && x2<drawX && x3<drawX) return;
2821  if(y1<drawY && y2<drawY && y3<drawY) return;
2822  if(drawY>=drawH) return;
2823  if(drawX>=drawW) return; 
2824
2825  if(!SetupSections_FT(x1,y1,x2,y2,x3,y3,tx1,ty1,tx2,ty2,tx3,ty3)) return;
2826
2827  ymax=Ymax;
2828
2829  for(ymin=Ymin;ymin<drawY;ymin++)
2830   if(NextRow_FT()) return;
2831
2832  clutP=(clY<<10)+clX;
2833
2834  YAdjust=((GlobalTextAddrY)<<11)+(GlobalTextAddrX<<1);
2835  YAdjust+=(TWin.Position.y0<<11)+(TWin.Position.x0>>1);
2836
2837  difX=delta_right_u;difX2=difX<<1;
2838  difY=delta_right_v;difY2=difY<<1;
2839
2840 #ifdef FASTSOLID
2841
2842  if(!bCheckMask && !DrawSemiTrans)
2843   {
2844    for (i=ymin;i<=ymax;i++)
2845     {
2846      xmin=(left_x >> 16);
2847      xmax=(right_x >> 16);//-1; //!!!!!!!!!!!!!!!!
2848      if(xmax>xmin) xmax--;
2849
2850      if(drawW<xmax) xmax=drawW;
2851
2852      if(xmax>=xmin)
2853       {
2854        posX=left_u;
2855        posY=left_v;
2856
2857        if(xmin<drawX)
2858         {j=drawX-xmin;xmin=drawX;posX+=j*difX;posY+=j*difY;}
2859
2860        for(j=xmin;j<xmax;j+=2)
2861         {
2862          XAdjust=(posX>>16)&TWin.xmask;
2863          tC1 = psxVub[(((posY>>16)&TWin.ymask)<<11)+
2864                       YAdjust+(XAdjust>>1)];
2865          tC1=(tC1>>((XAdjust&1)<<2))&0xf;
2866          XAdjust=((posX+difX)>>16)&TWin.xmask;
2867          tC2 = psxVub[((((posY+difY)>>16)&TWin.ymask)<<11)+
2868                       YAdjust+(XAdjust>>1)];
2869          tC2=(tC2>>((XAdjust&1)<<2))&0xf;
2870
2871          GetTextureTransColG32_S((uint32_t *)&psxVuw[(i<<10)+j],
2872              GETLE16(&psxVuw[clutP+tC1])|
2873              ((int32_t)GETLE16(&psxVuw[clutP+tC2]))<<16);
2874
2875          posX+=difX2;
2876          posY+=difY2;
2877         }
2878        if(j==xmax)
2879         {
2880          XAdjust=(posX>>16)&TWin.xmask;
2881          tC1 = psxVub[(((posY>>16)&TWin.ymask)<<11)+
2882                       YAdjust+(XAdjust>>1)];
2883          tC1=(tC1>>((XAdjust&1)<<2))&0xf;
2884          GetTextureTransColG_S(&psxVuw[(i<<10)+j],GETLE16(&psxVuw[clutP+tC1]));
2885         }
2886       }
2887      if(NextRow_FT()) 
2888       {
2889        return;
2890       }
2891     }
2892    return;
2893   }
2894
2895 #endif
2896
2897  for (i=ymin;i<=ymax;i++)
2898   {
2899    xmin=(left_x >> 16);
2900    xmax=(right_x >> 16)-1; //!!!!!!!!!!!!!!!!!!
2901    if(drawW<xmax) xmax=drawW;
2902
2903    if(xmax>=xmin)
2904     {
2905      posX=left_u;
2906      posY=left_v;
2907
2908      if(xmin<drawX)
2909       {j=drawX-xmin;xmin=drawX;posX+=j*difX;posY+=j*difY;}
2910
2911      for(j=xmin;j<xmax;j+=2)
2912       {
2913        XAdjust=(posX>>16)&TWin.xmask;
2914        tC1 = psxVub[(((posY>>16)&TWin.ymask)<<11)+
2915                     YAdjust+(XAdjust>>1)];
2916        tC1=(tC1>>((XAdjust&1)<<2))&0xf;
2917        XAdjust=((posX+difX)>>16)&TWin.xmask;
2918        tC2 = psxVub[((((posY+difY)>>16)&TWin.ymask)<<11)+
2919                     YAdjust+(XAdjust>>1)];
2920        tC2=(tC2>>((XAdjust&1)<<2))&0xf;
2921
2922        GetTextureTransColG32((uint32_t *)&psxVuw[(i<<10)+j],
2923            GETLE16(&psxVuw[clutP+tC1])|
2924            ((int32_t)GETLE16(&psxVuw[clutP+tC2]))<<16);
2925
2926        posX+=difX2;
2927        posY+=difY2;
2928       }
2929      if(j==xmax)
2930       {
2931        XAdjust=(posX>>16)&TWin.xmask;
2932        tC1 = psxVub[(((posY>>16)&TWin.ymask)<<11)+
2933                     YAdjust+(XAdjust>>1)];
2934        tC1=(tC1>>((XAdjust&1)<<2))&0xf;
2935        GetTextureTransColG(&psxVuw[(i<<10)+j],GETLE16(&psxVuw[clutP+tC1]));
2936       }
2937     }
2938    if(NextRow_FT()) 
2939     {
2940      return;
2941     }
2942   }
2943 }
2944
2945 ////////////////////////////////////////////////////////////////////////
2946
2947 #ifdef POLYQUAD3
2948
2949 static void drawPoly4TEx4_TRI(short x1, short y1, short x2, short y2, short x3, short y3, short x4, short y4, short tx1, short ty1, short tx2, short ty2, short tx3, short ty3, short tx4, short ty4,short clX, short clY)
2950 {
2951  drawPoly3TEx4(x2,y2,x3,y3,x4,y4,
2952                tx2,ty2,tx3,ty3,tx4,ty4,
2953                clX,clY);
2954  drawPoly3TEx4(x1,y1,x2,y2,x4,y4,
2955                tx1,ty1,tx2,ty2,tx4,ty4,
2956                clX,clY);
2957 }
2958
2959 #endif
2960
2961 // more exact:
2962
2963 static void drawPoly4TEx4(short x1, short y1, short x2, short y2, short x3, short y3, short x4, short y4, short tx1, short ty1, short tx2, short ty2, short tx3, short ty3, short tx4, short ty4,short clX, short clY)
2964 {
2965  int32_t num; 
2966  int32_t i,j,xmin,xmax,ymin,ymax;
2967  int32_t difX, difY, difX2, difY2;
2968  int32_t posX,posY,YAdjust,clutP,XAdjust;
2969  short tC1,tC2;
2970
2971  if(x1>drawW && x2>drawW && x3>drawW && x4>drawW) return;
2972  if(y1>drawH && y2>drawH && y3>drawH && y4>drawH) return;
2973  if(x1<drawX && x2<drawX && x3<drawX && x4<drawX) return;
2974  if(y1<drawY && y2<drawY && y3<drawY && y4<drawY) return;
2975  if(drawY>=drawH) return;
2976  if(drawX>=drawW) return; 
2977
2978  if(!SetupSections_FT4(x1,y1,x2,y2,x3,y3,x4,y4,tx1,ty1,tx2,ty2,tx3,ty3,tx4,ty4)) return;
2979
2980  ymax=Ymax;
2981
2982  for(ymin=Ymin;ymin<drawY;ymin++)
2983   if(NextRow_FT4()) return;
2984
2985  clutP=(clY<<10)+clX;
2986
2987  YAdjust=((GlobalTextAddrY)<<11)+(GlobalTextAddrX<<1);
2988
2989 #ifdef FASTSOLID
2990
2991  if(!bCheckMask && !DrawSemiTrans)
2992   {
2993    for (i=ymin;i<=ymax;i++)
2994     {
2995      xmin=(left_x >> 16);
2996      xmax=(right_x >> 16);
2997
2998      if(xmax>=xmin)
2999       {
3000        posX=left_u;
3001        posY=left_v;
3002
3003        num=(xmax-xmin);
3004        if(num==0) num=1;
3005        difX=(right_u-posX)/num;
3006        difY=(right_v-posY)/num;
3007        difX2=difX<<1;
3008        difY2=difY<<1;
3009
3010        if(xmin<drawX)
3011         {j=drawX-xmin;xmin=drawX;posX+=j*difX;posY+=j*difY;}
3012        xmax--;if(drawW<xmax) xmax=drawW;
3013
3014        for(j=xmin;j<xmax;j+=2)
3015         {
3016          XAdjust=(posX>>16);
3017          tC1 = psxVub[((posY>>5)&(int32_t)0xFFFFF800)+YAdjust+(XAdjust>>1)];
3018          tC1=(tC1>>((XAdjust&1)<<2))&0xf;
3019          XAdjust=((posX+difX)>>16);
3020          tC2 = psxVub[(((posY+difY)>>5)&(int32_t)0xFFFFF800)+YAdjust+
3021                        (XAdjust>>1)];
3022          tC2=(tC2>>((XAdjust&1)<<2))&0xf;
3023
3024          GetTextureTransColG32_S((uint32_t *)&psxVuw[(i<<10)+j],
3025               GETLE16(&psxVuw[clutP+tC1])|
3026               ((int32_t)GETLE16(&psxVuw[clutP+tC2]))<<16);
3027          posX+=difX2;
3028          posY+=difY2;
3029         }
3030        if(j==xmax)
3031         {
3032          XAdjust=(posX>>16);
3033          tC1 = psxVub[((posY>>5)&(int32_t)0xFFFFF800)+YAdjust+
3034                       (XAdjust>>1)];
3035          tC1=(tC1>>((XAdjust&1)<<2))&0xf;
3036          GetTextureTransColG_S(&psxVuw[(i<<10)+j],GETLE16(&psxVuw[clutP+tC1]));
3037         }
3038
3039       }
3040      if(NextRow_FT4()) return;
3041     }
3042    return;
3043   }
3044
3045 #endif
3046
3047  for (i=ymin;i<=ymax;i++)
3048   {
3049    xmin=(left_x >> 16);
3050    xmax=(right_x >> 16);
3051
3052    if(xmax>=xmin)
3053     {
3054      posX=left_u;
3055      posY=left_v;
3056
3057      num=(xmax-xmin);
3058      if(num==0) num=1;
3059      difX=(right_u-posX)/num;
3060      difY=(right_v-posY)/num;
3061      difX2=difX<<1;
3062      difY2=difY<<1;
3063
3064      if(xmin<drawX)
3065       {j=drawX-xmin;xmin=drawX;posX+=j*difX;posY+=j*difY;}
3066      xmax--;if(drawW<xmax) xmax=drawW;
3067
3068      for(j=xmin;j<xmax;j+=2)
3069       {
3070        XAdjust=(posX>>16);
3071        tC1 = psxVub[((posY>>5)&(int32_t)0xFFFFF800)+YAdjust+(XAdjust>>1)];
3072        tC1=(tC1>>((XAdjust&1)<<2))&0xf;
3073        XAdjust=((posX+difX)>>16);
3074        tC2 = psxVub[(((posY+difY)>>5)&(int32_t)0xFFFFF800)+YAdjust+
3075                      (XAdjust>>1)];
3076        tC2=(tC2>>((XAdjust&1)<<2))&0xf;
3077
3078        GetTextureTransColG32((uint32_t *)&psxVuw[(i<<10)+j],
3079             GETLE16(&psxVuw[clutP+tC1])|
3080             ((int32_t)GETLE16(&psxVuw[clutP+tC2]))<<16);
3081        posX+=difX2;
3082        posY+=difY2;
3083       }
3084      if(j==xmax)
3085       {
3086        XAdjust=(posX>>16);
3087        tC1 = psxVub[((posY>>5)&(int32_t)0xFFFFF800)+YAdjust+
3088                     (XAdjust>>1)];
3089        tC1=(tC1>>((XAdjust&1)<<2))&0xf;
3090        GetTextureTransColG(&psxVuw[(i<<10)+j],GETLE16(&psxVuw[clutP+tC1]));
3091       }
3092     }
3093    if(NextRow_FT4()) return;
3094   }
3095 }
3096
3097 ////////////////////////////////////////////////////////////////////////
3098
3099 static void drawPoly4TEx4_IL(short x1, short y1, short x2, short y2, short x3, short y3, short x4, short y4, short tx1, short ty1, short tx2, short ty2, short tx3, short ty3, short tx4, short ty4,short clX, short clY)
3100 {
3101  int32_t num; 
3102  int32_t i,j=0,xmin,xmax,ymin,ymax,n_xi,n_yi,TXV;
3103  int32_t difX, difY, difX2, difY2;
3104  int32_t posX=0,posY=0,YAdjust,clutP,XAdjust;
3105  short tC1,tC2;
3106
3107  if(x1>drawW && x2>drawW && x3>drawW && x4>drawW) return;
3108  if(y1>drawH && y2>drawH && y3>drawH && y4>drawH) return;
3109  if(x1<drawX && x2<drawX && x3<drawX && x4<drawX) return;
3110  if(y1<drawY && y2<drawY && y3<drawY && y4<drawY) return;
3111  if(drawY>=drawH) return;
3112  if(drawX>=drawW) return; 
3113
3114  if(!SetupSections_FT4(x1,y1,x2,y2,x3,y3,x4,y4,tx1,ty1,tx2,ty2,tx3,ty3,tx4,ty4)) return;
3115
3116  ymax=Ymax;
3117
3118  for(ymin=Ymin;ymin<drawY;ymin++)
3119   if(NextRow_FT4()) return;
3120
3121  clutP=(clY<<10)+clX;
3122
3123  YAdjust=((GlobalTextAddrY)<<10)+GlobalTextAddrX;
3124
3125 #ifdef FASTSOLID
3126
3127  if(!bCheckMask && !DrawSemiTrans)
3128   {
3129    for (i=ymin;i<=ymax;i++)
3130     {
3131      xmin=(left_x >> 16);
3132      xmax=(right_x >> 16);
3133
3134      if(xmax>=xmin)
3135       {
3136        posX=left_u;
3137        posY=left_v;
3138
3139        num=(xmax-xmin);
3140        if(num==0) num=1;
3141        difX=(right_u-posX)/num;
3142        difY=(right_v-posY)/num;
3143        difX2=difX<<1;
3144        difY2=difY<<1;
3145
3146        if(xmin<drawX)
3147         {j=drawX-xmin;xmin=drawX;posX+=j*difX;posY+=j*difY;}
3148        xmax--;if(drawW<xmax) xmax=drawW;
3149
3150        for(j=xmin;j<xmax;j+=2)
3151         {
3152          XAdjust=(posX>>16);
3153
3154          TXV=posY>>16;
3155          n_xi = ( ( XAdjust >> 2 ) & ~0x3c ) + ( ( TXV << 2 ) & 0x3c );
3156          n_yi = ( TXV & ~0xf ) + ( ( XAdjust >> 4 ) & 0xf );
3157
3158          tC1= (GETLE16(&psxVuw[(n_yi<<10)+YAdjust+n_xi]) >> ((XAdjust & 0x03)<<2)) & 0x0f ;
3159
3160          XAdjust=((posX+difX)>>16);
3161
3162          TXV=(posY+difY)>>16;
3163          n_xi = ( ( XAdjust >> 2 ) & ~0x3c ) + ( ( TXV << 2 ) & 0x3c );
3164          n_yi = ( TXV & ~0xf ) + ( ( XAdjust >> 4 ) & 0xf );
3165
3166          tC2= (GETLE16(&psxVuw[(n_yi<<10)+YAdjust+n_xi]) >> ((XAdjust & 0x03)<<2)) & 0x0f ;
3167
3168          GetTextureTransColG32_S((uint32_t *)&psxVuw[(i<<10)+j],
3169               GETLE16(&psxVuw[clutP+tC1])|
3170               ((int32_t)GETLE16(&psxVuw[clutP+tC2]))<<16);
3171          posX+=difX2;
3172          posY+=difY2;
3173         }
3174          posX+=difX2;
3175          posY+=difY2;
3176         }
3177
3178        if(j==xmax)
3179         {
3180          XAdjust=(posX>>16);
3181          TXV=posY>>16;
3182          n_xi = ( ( XAdjust >> 2 ) & ~0x3c ) + ( ( TXV << 2 ) & 0x3c );
3183          n_yi = ( TXV & ~0xf ) + ( ( XAdjust >> 4 ) & 0xf );
3184
3185          tC1= (GETLE16(&psxVuw[(n_yi<<10)+YAdjust+n_xi]) >> ((XAdjust & 0x03)<<2)) & 0x0f ;
3186
3187          GetTextureTransColG_S(&psxVuw[(i<<10)+j],GETLE16(&psxVuw[clutP+tC1]));
3188         }
3189
3190       }
3191      if(NextRow_FT4()) return;
3192     }
3193 #endif
3194
3195  for (i=ymin;i<=ymax;i++)
3196   {
3197    xmin=(left_x >> 16);
3198    xmax=(right_x >> 16);
3199
3200    if(xmax>=xmin)
3201     {
3202      posX=left_u;
3203      posY=left_v;
3204
3205      num=(xmax-xmin);
3206      if(num==0) num=1;
3207      difX=(right_u-posX)/num;
3208      difY=(right_v-posY)/num;
3209      difX2=difX<<1;
3210      difY2=difY<<1;
3211
3212      if(xmin<drawX)
3213       {j=drawX-xmin;xmin=drawX;posX+=j*difX;posY+=j*difY;}
3214      xmax--;if(drawW<xmax) xmax=drawW;
3215
3216      for(j=xmin;j<xmax;j+=2)
3217       {
3218        XAdjust=(posX>>16);
3219
3220        TXV=posY>>16;
3221        n_xi = ( ( XAdjust >> 2 ) & ~0x3c ) + ( ( TXV << 2 ) & 0x3c );
3222        n_yi = ( TXV & ~0xf ) + ( ( XAdjust >> 4 ) & 0xf );
3223
3224        tC1= (GETLE16(&psxVuw[(n_yi<<10)+YAdjust+n_xi]) >> ((XAdjust & 0x03)<<2)) & 0x0f ;
3225
3226        XAdjust=((posX+difX)>>16);
3227
3228        TXV=(posY+difY)>>16;
3229        n_xi = ( ( XAdjust >> 2 ) & ~0x3c ) + ( ( TXV << 2 ) & 0x3c );
3230        n_yi = ( TXV & ~0xf ) + ( ( XAdjust >> 4 ) & 0xf );
3231
3232        tC2= (GETLE16(&psxVuw[(n_yi<<10)+YAdjust+n_xi]) >> ((XAdjust & 0x03)<<2)) & 0x0f ;
3233
3234        GetTextureTransColG32((uint32_t *)&psxVuw[(i<<10)+j],
3235             GETLE16(&psxVuw[clutP+tC1])|
3236             ((int32_t)GETLE16(&psxVuw[clutP+tC2]))<<16);
3237        posX+=difX2;
3238        posY+=difY2;
3239       }
3240      if(j==xmax)
3241       {
3242        XAdjust=(posX>>16);
3243        TXV=posY>>16;
3244        n_xi = ( ( XAdjust >> 2 ) & ~0x3c ) + ( ( TXV << 2 ) & 0x3c );
3245        n_yi = ( TXV & ~0xf ) + ( ( XAdjust >> 4 ) & 0xf );
3246
3247        tC1= (GETLE16(&psxVuw[(n_yi<<10)+YAdjust+n_xi]) >> ((XAdjust & 0x03)<<2)) & 0x0f ;
3248
3249        GetTextureTransColG(&psxVuw[(i<<10)+j],GETLE16(&psxVuw[clutP+tC1]));
3250       }
3251     }
3252    if(NextRow_FT4()) return;
3253   }
3254 }
3255
3256 ////////////////////////////////////////////////////////////////////////
3257
3258 static void drawPoly4TEx4_TW(short x1, short y1, short x2, short y2, short x3, short y3, short x4, short y4, short tx1, short ty1, short tx2, short ty2, short tx3, short ty3, short tx4, short ty4,short clX, short clY)
3259 {
3260  int32_t num; 
3261  int32_t i,j,xmin,xmax,ymin,ymax;
3262  int32_t difX, difY, difX2, difY2;
3263  int32_t posX,posY,YAdjust,clutP,XAdjust;
3264  short tC1,tC2;
3265
3266  if(x1>drawW && x2>drawW && x3>drawW && x4>drawW) return;
3267  if(y1>drawH && y2>drawH && y3>drawH && y4>drawH) return;
3268  if(x1<drawX && x2<drawX && x3<drawX && x4<drawX) return;
3269  if(y1<drawY && y2<drawY && y3<drawY && y4<drawY) return;
3270  if(drawY>=drawH) return;
3271  if(drawX>=drawW) return; 
3272
3273  if(!SetupSections_FT4(x1,y1,x2,y2,x3,y3,x4,y4,tx1,ty1,tx2,ty2,tx3,ty3,tx4,ty4)) return;
3274
3275  ymax=Ymax;
3276
3277  for(ymin=Ymin;ymin<drawY;ymin++)
3278   if(NextRow_FT4()) return;
3279
3280  clutP=(clY<<10)+clX;
3281
3282  YAdjust=((GlobalTextAddrY)<<11)+(GlobalTextAddrX<<1);
3283  YAdjust+=(TWin.Position.y0<<11)+(TWin.Position.x0>>1);
3284
3285 #ifdef FASTSOLID
3286
3287  if(!bCheckMask && !DrawSemiTrans)
3288   {
3289    for (i=ymin;i<=ymax;i++)
3290     {
3291      xmin=(left_x >> 16);
3292      xmax=(right_x >> 16);
3293
3294      if(xmax>=xmin)
3295       {
3296        posX=left_u;
3297        posY=left_v;
3298
3299        num=(xmax-xmin);
3300        if(num==0) num=1;
3301        difX=(right_u-posX)/num;
3302        difY=(right_v-posY)/num;
3303        difX2=difX<<1;
3304        difY2=difY<<1;
3305
3306        if(xmin<drawX)
3307         {j=drawX-xmin;xmin=drawX;posX+=j*difX;posY+=j*difY;}
3308        xmax--;if(drawW<xmax) xmax=drawW;
3309
3310        for(j=xmin;j<xmax;j+=2)
3311         {
3312          XAdjust=(posX>>16)&TWin.xmask;
3313          tC1 = psxVub[(((posY>>16)&TWin.ymask)<<11)+
3314                       YAdjust+(XAdjust>>1)];
3315          tC1=(tC1>>((XAdjust&1)<<2))&0xf;
3316          XAdjust=((posX+difX)>>16)&TWin.xmask;
3317          tC2 = psxVub[((((posY+difY)>>16)&TWin.ymask)<<11)+
3318                       YAdjust+(XAdjust>>1)];
3319          tC2=(tC2>>((XAdjust&1)<<2))&0xf;
3320
3321          GetTextureTransColG32_S((uint32_t *)&psxVuw[(i<<10)+j],
3322               GETLE16(&psxVuw[clutP+tC1])|
3323               ((int32_t)GETLE16(&psxVuw[clutP+tC2]))<<16);
3324          posX+=difX2;
3325          posY+=difY2;
3326         }
3327        if(j==xmax)
3328         {
3329          XAdjust=(posX>>16)&TWin.xmask;
3330          tC1 = psxVub[(((posY>>16)&TWin.ymask)<<11)+
3331                       YAdjust+(XAdjust>>1)];
3332          tC1=(tC1>>((XAdjust&1)<<2))&0xf;
3333          GetTextureTransColG_S(&psxVuw[(i<<10)+j],GETLE16(&psxVuw[clutP+tC1]));
3334         }
3335       }
3336      if(NextRow_FT4()) return;
3337     }
3338    return;
3339   }
3340
3341 #endif
3342
3343  for (i=ymin;i<=ymax;i++)
3344   {
3345    xmin=(left_x >> 16);
3346    xmax=(right_x >> 16);
3347
3348    if(xmax>=xmin)
3349     {
3350      posX=left_u;
3351      posY=left_v;
3352
3353      num=(xmax-xmin);
3354      if(num==0) num=1;
3355      difX=(right_u-posX)/num;
3356      difY=(right_v-posY)/num;
3357      difX2=difX<<1;
3358      difY2=difY<<1;
3359
3360      if(xmin<drawX)
3361       {j=drawX-xmin;xmin=drawX;posX+=j*difX;posY+=j*difY;}
3362      xmax--;if(drawW<xmax) xmax=drawW;
3363
3364      for(j=xmin;j<xmax;j+=2)
3365       {
3366        XAdjust=(posX>>16)&TWin.xmask;
3367        tC1 = psxVub[(((posY>>16)&TWin.ymask)<<11)+
3368                     YAdjust+(XAdjust>>1)];
3369        tC1=(tC1>>((XAdjust&1)<<2))&0xf;
3370        XAdjust=((posX+difX)>>16)&TWin.xmask;
3371        tC2 = psxVub[((((posY+difY)>>16)&TWin.ymask)<<11)+
3372                     YAdjust+(XAdjust>>1)];
3373        tC2=(tC2>>((XAdjust&1)<<2))&0xf;
3374
3375        GetTextureTransColG32((uint32_t *)&psxVuw[(i<<10)+j],
3376             GETLE16(&psxVuw[clutP+tC1])|
3377             ((int32_t)GETLE16(&psxVuw[clutP+tC2]))<<16);
3378        posX+=difX2;
3379        posY+=difY2;
3380       }
3381      if(j==xmax)
3382       {
3383        XAdjust=(posX>>16)&TWin.xmask;
3384        tC1 = psxVub[(((posY>>16)&TWin.ymask)<<11)+
3385                     YAdjust+(XAdjust>>1)];
3386        tC1=(tC1>>((XAdjust&1)<<2))&0xf;
3387        GetTextureTransColG(&psxVuw[(i<<10)+j],GETLE16(&psxVuw[clutP+tC1]));
3388       }
3389     }
3390    if(NextRow_FT4()) return;
3391   }
3392 }
3393
3394 ////////////////////////////////////////////////////////////////////////
3395
3396 static void drawPoly4TEx4_TW_S(short x1, short y1, short x2, short y2, short x3, short y3, short x4, short y4, short tx1, short ty1, short tx2, short ty2, short tx3, short ty3, short tx4, short ty4,short clX, short clY)
3397 {
3398  int32_t num; 
3399  int32_t i,j,xmin,xmax,ymin,ymax;
3400  int32_t difX, difY, difX2, difY2;
3401  int32_t posX,posY,YAdjust,clutP,XAdjust;
3402  short tC1,tC2;
3403
3404  if(x1>drawW && x2>drawW && x3>drawW && x4>drawW) return;
3405  if(y1>drawH && y2>drawH && y3>drawH && y4>drawH) return;
3406  if(x1<drawX && x2<drawX && x3<drawX && x4<drawX) return;
3407  if(y1<drawY && y2<drawY && y3<drawY && y4<drawY) return;
3408  if(drawY>=drawH) return;
3409  if(drawX>=drawW) return; 
3410
3411  if(!SetupSections_FT4(x1,y1,x2,y2,x3,y3,x4,y4,tx1,ty1,tx2,ty2,tx3,ty3,tx4,ty4)) return;
3412
3413  ymax=Ymax;
3414
3415  for(ymin=Ymin;ymin<drawY;ymin++)
3416   if(NextRow_FT4()) return;
3417
3418  clutP=(clY<<10)+clX;
3419
3420  YAdjust=((GlobalTextAddrY)<<11)+(GlobalTextAddrX<<1);
3421  YAdjust+=(TWin.Position.y0<<11)+(TWin.Position.x0>>1);
3422
3423 #ifdef FASTSOLID
3424
3425  if(!bCheckMask && !DrawSemiTrans)
3426   {
3427    for (i=ymin;i<=ymax;i++)
3428     {
3429      xmin=(left_x >> 16);
3430      xmax=(right_x >> 16);
3431
3432      if(xmax>=xmin)
3433       {
3434        posX=left_u;
3435        posY=left_v;
3436
3437        num=(xmax-xmin);
3438        if(num==0) num=1;
3439        difX=(right_u-posX)/num;
3440        difY=(right_v-posY)/num;
3441        difX2=difX<<1;
3442        difY2=difY<<1;
3443
3444        if(xmin<drawX)
3445         {j=drawX-xmin;xmin=drawX;posX+=j*difX;posY+=j*difY;}
3446        xmax--;if(drawW<xmax) xmax=drawW;
3447
3448        for(j=xmin;j<xmax;j+=2)
3449         {
3450          XAdjust=(posX>>16)&TWin.xmask;
3451          tC1 = psxVub[(((posY>>16)&TWin.ymask)<<11)+
3452                       YAdjust+(XAdjust>>1)];
3453          tC1=(tC1>>((XAdjust&1)<<2))&0xf;
3454          XAdjust=((posX+difX)>>16)&TWin.xmask;
3455          tC2 = psxVub[((((posY+difY)>>16)&TWin.ymask)<<11)+
3456                       YAdjust+(XAdjust>>1)];
3457          tC2=(tC2>>((XAdjust&1)<<2))&0xf;
3458
3459          GetTextureTransColG32_S((uint32_t *)&psxVuw[(i<<10)+j],
3460               GETLE16(&psxVuw[clutP+tC1])|
3461               ((int32_t)GETLE16(&psxVuw[clutP+tC2]))<<16);
3462          posX+=difX2;
3463          posY+=difY2;
3464         }
3465        if(j==xmax)
3466         {
3467          XAdjust=(posX>>16)&TWin.xmask;
3468          tC1 = psxVub[(((posY>>16)&TWin.ymask)<<11)+
3469                       YAdjust+(XAdjust>>1)];
3470          tC1=(tC1>>((XAdjust&1)<<2))&0xf;
3471          GetTextureTransColG_S(&psxVuw[(i<<10)+j],GETLE16(&psxVuw[clutP+tC1]));
3472         }
3473       }
3474      if(NextRow_FT4()) return;
3475     }
3476    return;
3477   }
3478
3479 #endif
3480
3481  for (i=ymin;i<=ymax;i++)
3482   {
3483    xmin=(left_x >> 16);
3484    xmax=(right_x >> 16);
3485
3486    if(xmax>=xmin)
3487     {
3488      posX=left_u;
3489      posY=left_v;
3490
3491      num=(xmax-xmin);
3492      if(num==0) num=1;
3493      difX=(right_u-posX)/num;
3494      difY=(right_v-posY)/num;
3495      difX2=difX<<1;
3496      difY2=difY<<1;
3497
3498      if(xmin<drawX)
3499       {j=drawX-xmin;xmin=drawX;posX+=j*difX;posY+=j*difY;}
3500      xmax--;if(drawW<xmax) xmax=drawW;
3501
3502      for(j=xmin;j<xmax;j+=2)
3503       {
3504        XAdjust=(posX>>16)&TWin.xmask;
3505        tC1 = psxVub[(((posY>>16)&TWin.ymask)<<11)+
3506                     YAdjust+(XAdjust>>1)];
3507        tC1=(tC1>>((XAdjust&1)<<2))&0xf;
3508        XAdjust=((posX+difX)>>16)&TWin.xmask;
3509        tC2 = psxVub[((((posY+difY)>>16)&TWin.ymask)<<11)+
3510                     YAdjust+(XAdjust>>1)];
3511        tC2=(tC2>>((XAdjust&1)<<2))&0xf;
3512
3513        GetTextureTransColG32_SPR((uint32_t *)&psxVuw[(i<<10)+j],
3514             GETLE16(&psxVuw[clutP+tC1])|
3515             ((int32_t)GETLE16(&psxVuw[clutP+tC2]))<<16);
3516        posX+=difX2;
3517        posY+=difY2;
3518       }
3519      if(j==xmax)
3520       {
3521        XAdjust=(posX>>16)&TWin.xmask;
3522        tC1 = psxVub[(((posY>>16)&TWin.ymask)<<11)+
3523                     YAdjust+(XAdjust>>1)];
3524        tC1=(tC1>>((XAdjust&1)<<2))&0xf;
3525        GetTextureTransColG_SPR(&psxVuw[(i<<10)+j],GETLE16(&psxVuw[clutP+tC1]));
3526       }
3527     }
3528    if(NextRow_FT4()) return;
3529   }
3530 }
3531 ////////////////////////////////////////////////////////////////////////
3532 // POLY 3 F-SHADED TEX PAL 8
3533 ////////////////////////////////////////////////////////////////////////
3534
3535 static void drawPoly3TEx8(short x1, short y1, short x2, short y2, short x3, short y3, short tx1, short ty1, short tx2, short ty2, short tx3, short ty3,short clX, short clY)
3536 {
3537  int i,j,xmin,xmax,ymin,ymax;
3538  int32_t difX, difY,difX2, difY2;
3539  int32_t posX,posY,YAdjust,clutP;
3540  short tC1,tC2;
3541
3542  if(x1>drawW && x2>drawW && x3>drawW) return;
3543  if(y1>drawH && y2>drawH && y3>drawH) return;
3544  if(x1<drawX && x2<drawX && x3<drawX) return;
3545  if(y1<drawY && y2<drawY && y3<drawY) return;
3546  if(drawY>=drawH) return;
3547  if(drawX>=drawW) return; 
3548
3549  if(!SetupSections_FT(x1,y1,x2,y2,x3,y3,tx1,ty1,tx2,ty2,tx3,ty3)) return;
3550
3551  ymax=Ymax;
3552
3553  for(ymin=Ymin;ymin<drawY;ymin++)
3554   if(NextRow_FT()) return;
3555
3556  clutP=(clY<<10)+clX;
3557
3558  YAdjust=((GlobalTextAddrY)<<11)+(GlobalTextAddrX<<1);
3559
3560  difX=delta_right_u;difX2=difX<<1;
3561  difY=delta_right_v;difY2=difY<<1;
3562
3563 #ifdef FASTSOLID
3564
3565  if(!bCheckMask && !DrawSemiTrans)
3566   {
3567    for (i=ymin;i<=ymax;i++)
3568     {
3569      xmin=(left_x >> 16);
3570      xmax=(right_x >> 16)-1; //!!!!!!!!!!!!!!!
3571      if(drawW<xmax) xmax=drawW;
3572
3573      if(xmax>=xmin)
3574       {
3575        posX=left_u;
3576        posY=left_v;
3577
3578        if(xmin<drawX)
3579         {j=drawX-xmin;xmin=drawX;posX+=j*difX;posY+=j*difY;}
3580
3581        for(j=xmin;j<xmax;j+=2)
3582         {
3583          tC1 = psxVub[((posY>>5)&(int32_t)0xFFFFF800)+YAdjust+(posX>>16)];
3584          tC2 = psxVub[(((posY+difY)>>5)&(int32_t)0xFFFFF800)+YAdjust+
3585                       ((posX+difX)>>16)];
3586          GetTextureTransColG32_S((uint32_t *)&psxVuw[(i<<10)+j],
3587              GETLE16(&psxVuw[clutP+tC1])|
3588              ((int32_t)GETLE16(&psxVuw[clutP+tC2]))<<16);
3589          posX+=difX2;
3590          posY+=difY2;
3591         }
3592
3593        if(j==xmax)
3594         {
3595          tC1 = psxVub[((posY>>5)&(int32_t)0xFFFFF800)+YAdjust+(posX>>16)];
3596          GetTextureTransColG_S(&psxVuw[(i<<10)+j],GETLE16(&psxVuw[clutP+tC1]));
3597         }
3598       }
3599      if(NextRow_FT()) 
3600       {
3601        return;
3602       }
3603     }
3604    return;
3605   }
3606
3607 #endif
3608
3609  for (i=ymin;i<=ymax;i++)
3610   {
3611    xmin=(left_x >> 16);
3612    xmax=(right_x >> 16)-1; //!!!!!!!!!!!!!!!!!
3613    if(drawW<xmax) xmax=drawW;
3614
3615    if(xmax>=xmin)
3616     {
3617      posX=left_u;
3618      posY=left_v;
3619
3620      if(xmin<drawX)
3621       {j=drawX-xmin;xmin=drawX;posX+=j*difX;posY+=j*difY;}
3622
3623      for(j=xmin;j<xmax;j+=2)
3624       {
3625        tC1 = psxVub[((posY>>5)&(int32_t)0xFFFFF800)+YAdjust+(posX>>16)];
3626        tC2 = psxVub[(((posY+difY)>>5)&(int32_t)0xFFFFF800)+YAdjust+
3627                     ((posX+difX)>>16)];
3628        GetTextureTransColG32((uint32_t *)&psxVuw[(i<<10)+j],
3629            GETLE16(&psxVuw[clutP+tC1])|
3630            ((int32_t)GETLE16(&psxVuw[clutP+tC2]))<<16);
3631        posX+=difX2;
3632        posY+=difY2;
3633       }
3634
3635      if(j==xmax)
3636       {
3637        tC1 = psxVub[((posY>>5)&(int32_t)0xFFFFF800)+YAdjust+(posX>>16)];
3638        GetTextureTransColG(&psxVuw[(i<<10)+j],GETLE16(&psxVuw[clutP+tC1]));
3639       }
3640
3641     }
3642    if(NextRow_FT()) 
3643     {
3644      return;
3645     }
3646   }
3647 }
3648
3649 ////////////////////////////////////////////////////////////////////////
3650
3651 static void drawPoly3TEx8_IL(short x1, short y1, short x2, short y2, short x3, short y3, short tx1, short ty1, short tx2, short ty2, short tx3, short ty3,short clX, short clY)
3652 {
3653  int i,j,xmin,xmax,ymin,ymax,n_xi,n_yi,TXV,TXU;
3654  int32_t difX, difY,difX2, difY2;
3655  int32_t posX,posY,YAdjust,clutP;
3656  short tC1,tC2;
3657
3658  if(x1>drawW && x2>drawW && x3>drawW) return;
3659  if(y1>drawH && y2>drawH && y3>drawH) return;
3660  if(x1<drawX && x2<drawX && x3<drawX) return;
3661  if(y1<drawY && y2<drawY && y3<drawY) return;
3662  if(drawY>=drawH) return;
3663  if(drawX>=drawW) return; 
3664
3665  if(!SetupSections_FT(x1,y1,x2,y2,x3,y3,tx1,ty1,tx2,ty2,tx3,ty3)) return;
3666
3667  ymax=Ymax;
3668
3669  for(ymin=Ymin;ymin<drawY;ymin++)
3670   if(NextRow_FT()) return;
3671
3672  clutP=(clY<<10)+clX;
3673
3674  YAdjust=(GlobalTextAddrY<<10)+GlobalTextAddrX;
3675
3676  difX=delta_right_u;difX2=difX<<1;
3677  difY=delta_right_v;difY2=difY<<1;
3678
3679 #ifdef FASTSOLID
3680
3681  if(!bCheckMask && !DrawSemiTrans)
3682   {
3683    for (i=ymin;i<=ymax;i++)
3684     {
3685      xmin=(left_x >> 16);
3686      xmax=(right_x >> 16)-1; //!!!!!!!!!!!!!!!
3687      if(drawW<xmax) xmax=drawW;
3688
3689      if(xmax>=xmin)
3690       {
3691        posX=left_u;
3692        posY=left_v;
3693
3694        if(xmin<drawX)
3695         {j=drawX-xmin;xmin=drawX;posX+=j*difX;posY+=j*difY;}
3696
3697        for(j=xmin;j<xmax;j+=2)
3698         {
3699          TXU=posX>>16;
3700          TXV=posY>>16;
3701          n_xi = ( ( TXU >> 1 ) & ~0x78 ) + ( ( TXU << 2 ) & 0x40 ) + ( ( TXV << 3 ) & 0x38 );
3702          n_yi = ( TXV & ~0x7 ) + ( ( TXU >> 5 ) & 0x7 );
3703
3704          tC1= (GETLE16(&psxVuw[(n_yi<<10)+YAdjust+n_xi]) >> ((TXU & 0x01)<<3)) & 0xff;
3705
3706          TXU=(posX+difX)>>16;
3707          TXV=(posY+difY)>>16;
3708          n_xi = ( ( TXU >> 1 ) & ~0x78 ) + ( ( TXU << 2 ) & 0x40 ) + ( ( TXV << 3 ) & 0x38 );
3709          n_yi = ( TXV & ~0x7 ) + ( ( TXU >> 5 ) & 0x7 );
3710
3711          tC2= (GETLE16(&psxVuw[(n_yi<<10)+YAdjust+n_xi]) >> ((TXU & 0x01)<<3)) & 0xff;
3712
3713          GetTextureTransColG32_S((uint32_t *)&psxVuw[(i<<10)+j],
3714              GETLE16(&psxVuw[clutP+tC1])|
3715              ((int32_t)GETLE16(&psxVuw[clutP+tC2]))<<16);
3716          posX+=difX2;
3717          posY+=difY2;
3718         }
3719
3720        if(j==xmax)
3721         {
3722          TXU=posX>>16;
3723          TXV=posY>>16;
3724          n_xi = ( ( TXU >> 1 ) & ~0x78 ) + ( ( TXU << 2 ) & 0x40 ) + ( ( TXV << 3 ) & 0x38 );
3725          n_yi = ( TXV & ~0x7 ) + ( ( TXU >> 5 ) & 0x7 );
3726
3727          tC1= (GETLE16(&psxVuw[(n_yi<<10)+YAdjust+n_xi]) >> ((TXU & 0x01)<<3)) & 0xff;
3728
3729          GetTextureTransColG_S(&psxVuw[(i<<10)+j],GETLE16(&psxVuw[clutP+tC1]));
3730         }
3731       }
3732      if(NextRow_FT()) 
3733       {
3734        return;
3735       }
3736     }
3737    return;
3738   }
3739
3740 #endif
3741
3742  for (i=ymin;i<=ymax;i++)
3743   {
3744    xmin=(left_x >> 16);
3745    xmax=(right_x >> 16)-1; //!!!!!!!!!!!!!!!!!
3746    if(drawW<xmax) xmax=drawW;
3747
3748    if(xmax>=xmin)
3749     {
3750      posX=left_u;
3751      posY=left_v;
3752
3753      if(xmin<drawX)
3754       {j=drawX-xmin;xmin=drawX;posX+=j*difX;posY+=j*difY;}
3755
3756      for(j=xmin;j<xmax;j+=2)
3757       {
3758        TXU=posX>>16;
3759        TXV=posY>>16;
3760        n_xi = ( ( TXU >> 1 ) & ~0x78 ) + ( ( TXU << 2 ) & 0x40 ) + ( ( TXV << 3 ) & 0x38 );
3761        n_yi = ( TXV & ~0x7 ) + ( ( TXU >> 5 ) & 0x7 );
3762
3763        tC1= (GETLE16(&psxVuw[(n_yi<<10)+YAdjust+n_xi]) >> ((TXU & 0x01)<<3)) & 0xff;
3764
3765        TXU=(posX+difX)>>16;
3766        TXV=(posY+difY)>>16;
3767        n_xi = ( ( TXU >> 1 ) & ~0x78 ) + ( ( TXU << 2 ) & 0x40 ) + ( ( TXV << 3 ) & 0x38 );
3768        n_yi = ( TXV & ~0x7 ) + ( ( TXU >> 5 ) & 0x7 );
3769
3770        tC2= (GETLE16(&psxVuw[(n_yi<<10)+YAdjust+n_xi]) >> ((TXU & 0x01)<<3)) & 0xff;
3771
3772        GetTextureTransColG32((uint32_t *)&psxVuw[(i<<10)+j],
3773            GETLE16(&psxVuw[clutP+tC1])|
3774            ((int32_t)GETLE16(&psxVuw[clutP+tC2]))<<16);
3775        posX+=difX2;
3776        posY+=difY2;
3777       }
3778
3779      if(j==xmax)
3780       {
3781        TXU=posX>>16;
3782        TXV=posY>>16;
3783        n_xi = ( ( TXU >> 1 ) & ~0x78 ) + ( ( TXU << 2 ) & 0x40 ) + ( ( TXV << 3 ) & 0x38 );
3784        n_yi = ( TXV & ~0x7 ) + ( ( TXU >> 5 ) & 0x7 );
3785
3786        tC1= (GETLE16(&psxVuw[(n_yi<<10)+YAdjust+n_xi]) >> ((TXU & 0x01)<<3)) & 0xff;
3787
3788        GetTextureTransColG(&psxVuw[(i<<10)+j],GETLE16(&psxVuw[clutP+tC1]));
3789       }
3790
3791     }
3792    if(NextRow_FT()) 
3793     {
3794      return;
3795     }
3796   }
3797 }
3798
3799 ////////////////////////////////////////////////////////////////////////
3800
3801 static void drawPoly3TEx8_TW(short x1, short y1, short x2, short y2, short x3, short y3, short tx1, short ty1, short tx2, short ty2, short tx3, short ty3,short clX, short clY)
3802 {
3803  int i,j,xmin,xmax,ymin,ymax;
3804  int32_t difX, difY,difX2, difY2;
3805  int32_t posX,posY,YAdjust,clutP;
3806  short tC1,tC2;
3807
3808  if(x1>drawW && x2>drawW && x3>drawW) return;
3809  if(y1>drawH && y2>drawH && y3>drawH) return;
3810  if(x1<drawX && x2<drawX && x3<drawX) return;
3811  if(y1<drawY && y2<drawY && y3<drawY) return;
3812  if(drawY>=drawH) return;
3813  if(drawX>=drawW) return; 
3814
3815  if(!SetupSections_FT(x1,y1,x2,y2,x3,y3,tx1,ty1,tx2,ty2,tx3,ty3)) return;
3816
3817  ymax=Ymax;
3818
3819  for(ymin=Ymin;ymin<drawY;ymin++)
3820   if(NextRow_FT()) return;
3821
3822  clutP=(clY<<10)+clX;
3823
3824  YAdjust=((GlobalTextAddrY)<<11)+(GlobalTextAddrX<<1);
3825  YAdjust+=(TWin.Position.y0<<11)+(TWin.Position.x0);
3826
3827  difX=delta_right_u;difX2=difX<<1;
3828  difY=delta_right_v;difY2=difY<<1;
3829
3830 #ifdef FASTSOLID
3831
3832  if(!bCheckMask && !DrawSemiTrans)
3833   {
3834    for (i=ymin;i<=ymax;i++)
3835     {
3836      xmin=(left_x >> 16);
3837      xmax=(right_x >> 16);//-1; //!!!!!!!!!!!!!!!!
3838      if(xmax>xmin) xmax--;
3839
3840      if(drawW<xmax) xmax=drawW;
3841
3842      if(xmax>=xmin)
3843       {
3844        posX=left_u;
3845        posY=left_v;
3846
3847        if(xmin<drawX)
3848         {j=drawX-xmin;xmin=drawX;posX+=j*difX;posY+=j*difY;}
3849
3850        for(j=xmin;j<xmax;j+=2)
3851         {
3852          tC1 = psxVub[(((posY>>16)&TWin.ymask)<<11)+
3853                       YAdjust+((posX>>16)&TWin.xmask)];
3854          tC2 = psxVub[((((posY+difY)>>16)&TWin.ymask)<<11)+
3855                       YAdjust+(((posX+difX)>>16)&TWin.xmask)];
3856          GetTextureTransColG32_S((uint32_t *)&psxVuw[(i<<10)+j],
3857              GETLE16(&psxVuw[clutP+tC1])|
3858              ((int32_t)GETLE16(&psxVuw[clutP+tC2]))<<16);
3859          posX+=difX2;
3860          posY+=difY2;
3861         }
3862
3863        if(j==xmax)
3864         {
3865          tC1 = psxVub[(((posY>>16)&TWin.ymask)<<11)+
3866                       YAdjust+((posX>>16)&TWin.xmask)];
3867          GetTextureTransColG_S(&psxVuw[(i<<10)+j],GETLE16(&psxVuw[clutP+tC1]));
3868         }
3869       }
3870      if(NextRow_FT()) 
3871       {
3872        return;
3873       }
3874     }
3875    return;
3876   }
3877
3878 #endif
3879
3880  for (i=ymin;i<=ymax;i++)
3881   {
3882    xmin=(left_x >> 16);
3883    xmax=(right_x >> 16)-1; //!!!!!!!!!!!!!!!!!
3884    if(drawW<xmax) xmax=drawW;
3885
3886    if(xmax>=xmin)
3887     {
3888      posX=left_u;
3889      posY=left_v;
3890
3891      if(xmin<drawX)
3892       {j=drawX-xmin;xmin=drawX;posX+=j*difX;posY+=j*difY;}
3893
3894      for(j=xmin;j<xmax;j+=2)
3895       {
3896        tC1 = psxVub[(((posY>>16)&TWin.ymask)<<11)+
3897                     YAdjust+((posX>>16)&TWin.xmask)];
3898        tC2 = psxVub[((((posY+difY)>>16)&TWin.ymask)<<11)+
3899                     YAdjust+(((posX+difX)>>16)&TWin.xmask)];
3900        GetTextureTransColG32((uint32_t *)&psxVuw[(i<<10)+j],
3901            GETLE16(&psxVuw[clutP+tC1])|
3902            ((int32_t)GETLE16(&psxVuw[clutP+tC2]))<<16);
3903        posX+=difX2;
3904        posY+=difY2;
3905       }
3906
3907      if(j==xmax)
3908       {
3909        tC1 = psxVub[(((posY>>16)&TWin.ymask)<<11)+
3910                     YAdjust+((posX>>16)&TWin.xmask)];
3911        GetTextureTransColG(&psxVuw[(i<<10)+j],GETLE16(&psxVuw[clutP+tC1]));
3912       }
3913
3914     }
3915    if(NextRow_FT()) 
3916     {
3917      return;
3918     }
3919   }
3920 }
3921
3922 ////////////////////////////////////////////////////////////////////////
3923
3924 #ifdef POLYQUAD3
3925
3926 static void drawPoly4TEx8_TRI(short x1, short y1, short x2, short y2, short x3, short y3, short x4, short y4, short tx1, short ty1, short tx2, short ty2, short tx3, short ty3, short tx4, short ty4,short clX, short clY)
3927 {
3928  drawPoly3TEx8(x2,y2,x3,y3,x4,y4,
3929                tx2,ty2,tx3,ty3,tx4,ty4,
3930                clX,clY);
3931
3932  drawPoly3TEx8(x1,y1,x2,y2,x4,y4,
3933                tx1,ty1,tx2,ty2,tx4,ty4,
3934                clX,clY);
3935 }
3936
3937 #endif
3938
3939 // more exact:
3940
3941 static void drawPoly4TEx8(short x1, short y1, short x2, short y2, short x3, short y3, short x4, short y4, short tx1, short ty1, short tx2, short ty2, short tx3, short ty3, short tx4, short ty4,short clX, short clY)
3942 {
3943  int32_t num; 
3944  int32_t i,j,xmin,xmax,ymin,ymax;
3945  int32_t difX, difY, difX2, difY2;
3946  int32_t posX,posY,YAdjust,clutP;
3947  short tC1,tC2;
3948
3949  if(x1>drawW && x2>drawW && x3>drawW && x4>drawW) return;
3950  if(y1>drawH && y2>drawH && y3>drawH && y4>drawH) return;
3951  if(x1<drawX && x2<drawX && x3<drawX && x4<drawX) return;
3952  if(y1<drawY && y2<drawY && y3<drawY && y4<drawY) return;
3953  if(drawY>=drawH) return;
3954  if(drawX>=drawW) return; 
3955
3956  if(!SetupSections_FT4(x1,y1,x2,y2,x3,y3,x4,y4,tx1,ty1,tx2,ty2,tx3,ty3,tx4,ty4)) return;
3957
3958  ymax=Ymax;
3959
3960  for(ymin=Ymin;ymin<drawY;ymin++)
3961   if(NextRow_FT4()) return;
3962
3963  clutP=(clY<<10)+clX;
3964
3965  YAdjust=((GlobalTextAddrY)<<11)+(GlobalTextAddrX<<1);
3966
3967 #ifdef FASTSOLID
3968
3969  if(!bCheckMask && !DrawSemiTrans)
3970   {
3971    for (i=ymin;i<=ymax;i++)
3972     {
3973      xmin=(left_x >> 16);
3974      xmax=(right_x >> 16);
3975
3976      if(xmax>=xmin)
3977       {
3978        posX=left_u;
3979        posY=left_v;
3980
3981        num=(xmax-xmin);
3982        if(num==0) num=1;
3983        difX=(right_u-posX)/num;
3984        difY=(right_v-posY)/num;
3985        difX2=difX<<1;
3986        difY2=difY<<1;
3987
3988        if(xmin<drawX)
3989         {j=drawX-xmin;xmin=drawX;posX+=j*difX;posY+=j*difY;}
3990        xmax--;if(drawW<xmax) xmax=drawW;
3991
3992        for(j=xmin;j<xmax;j+=2)
3993         {
3994          tC1 = psxVub[((posY>>5)&(int32_t)0xFFFFF800)+YAdjust+(posX>>16)];
3995          tC2 = psxVub[(((posY+difY)>>5)&(int32_t)0xFFFFF800)+YAdjust+
3996                      ((posX+difX)>>16)];
3997          GetTextureTransColG32_S((uint32_t *)&psxVuw[(i<<10)+j],
3998               GETLE16(&psxVuw[clutP+tC1])|
3999               ((int32_t)GETLE16(&psxVuw[clutP+tC2]))<<16);
4000          posX+=difX2;
4001          posY+=difY2;
4002         }
4003        if(j==xmax)
4004         {
4005          tC1 = psxVub[((posY>>5)&(int32_t)0xFFFFF800)+YAdjust+(posX>>16)];
4006          GetTextureTransColG_S(&psxVuw[(i<<10)+j],GETLE16(&psxVuw[clutP+tC1]));
4007         }
4008       }
4009      if(NextRow_FT4()) return;
4010     }
4011    return;
4012   }
4013
4014 #endif
4015
4016  for (i=ymin;i<=ymax;i++)
4017   {
4018    xmin=(left_x >> 16);
4019    xmax=(right_x >> 16);
4020
4021    if(xmax>=xmin)
4022     {
4023      posX=left_u;
4024      posY=left_v;
4025
4026      num=(xmax-xmin);
4027      if(num==0) num=1;
4028      difX=(right_u-posX)/num;
4029      difY=(right_v-posY)/num;
4030      difX2=difX<<1;
4031      difY2=difY<<1;
4032
4033      if(xmin<drawX)
4034       {j=drawX-xmin;xmin=drawX;posX+=j*difX;posY+=j*difY;}
4035      xmax--;if(drawW<xmax) xmax=drawW;
4036
4037      for(j=xmin;j<xmax;j+=2)
4038       {
4039        tC1 = psxVub[((posY>>5)&(int32_t)0xFFFFF800)+YAdjust+(posX>>16)];
4040        tC2 = psxVub[(((posY+difY)>>5)&(int32_t)0xFFFFF800)+YAdjust+
4041                      ((posX+difX)>>16)];
4042        GetTextureTransColG32((uint32_t *)&psxVuw[(i<<10)+j],
4043             GETLE16(&psxVuw[clutP+tC1])|
4044             ((int32_t)GETLE16(&psxVuw[clutP+tC2]))<<16);
4045        posX+=difX2;
4046        posY+=difY2;
4047       }
4048      if(j==xmax)
4049       {
4050        tC1 = psxVub[((posY>>5)&(int32_t)0xFFFFF800)+YAdjust+(posX>>16)];
4051        GetTextureTransColG(&psxVuw[(i<<10)+j],GETLE16(&psxVuw[clutP+tC1]));
4052       }
4053     }
4054    if(NextRow_FT4()) return;
4055   }
4056 }
4057
4058 ////////////////////////////////////////////////////////////////////////
4059
4060 static void drawPoly4TEx8_IL(short x1, short y1, short x2, short y2, short x3, short y3, short x4, short y4, short tx1, short ty1, short tx2, short ty2, short tx3, short ty3, short tx4, short ty4,short clX, short clY)
4061 {
4062  int32_t num; 
4063  int32_t i,j,xmin,xmax,ymin,ymax,n_xi,n_yi,TXV,TXU;
4064  int32_t difX, difY, difX2, difY2;
4065  int32_t posX,posY,YAdjust,clutP;
4066  short tC1,tC2;
4067
4068  if(x1>drawW && x2>drawW && x3>drawW && x4>drawW) return;
4069  if(y1>drawH && y2>drawH && y3>drawH && y4>drawH) return;
4070  if(x1<drawX && x2<drawX && x3<drawX && x4<drawX) return;
4071  if(y1<drawY && y2<drawY && y3<drawY && y4<drawY) return;
4072  if(drawY>=drawH) return;
4073  if(drawX>=drawW) return; 
4074
4075  if(!SetupSections_FT4(x1,y1,x2,y2,x3,y3,x4,y4,tx1,ty1,tx2,ty2,tx3,ty3,tx4,ty4)) return;
4076
4077  ymax=Ymax;
4078
4079  for(ymin=Ymin;ymin<drawY;ymin++)
4080   if(NextRow_FT4()) return;
4081
4082  clutP=(clY<<10)+clX;
4083
4084  YAdjust=(GlobalTextAddrY<<10)+GlobalTextAddrX;
4085
4086 #ifdef FASTSOLID
4087
4088  if(!bCheckMask && !DrawSemiTrans)
4089   {
4090    for (i=ymin;i<=ymax;i++)
4091     {
4092      xmin=(left_x >> 16);
4093      xmax=(right_x >> 16);
4094
4095      if(xmax>=xmin)
4096       {
4097        posX=left_u;
4098        posY=left_v;
4099
4100        num=(xmax-xmin);
4101        if(num==0) num=1;
4102        difX=(right_u-posX)/num;
4103        difY=(right_v-posY)/num;
4104        difX2=difX<<1;
4105        difY2=difY<<1;
4106
4107        if(xmin<drawX)
4108         {j=drawX-xmin;xmin=drawX;posX+=j*difX;posY+=j*difY;}
4109        xmax--;if(drawW<xmax) xmax=drawW;
4110
4111        for(j=xmin;j<xmax;j+=2)
4112         {
4113          TXU=posX>>16;
4114          TXV=posY>>16;
4115          n_xi = ( ( TXU >> 1 ) & ~0x78 ) + ( ( TXU << 2 ) & 0x40 ) + ( ( TXV << 3 ) & 0x38 );
4116          n_yi = ( TXV & ~0x7 ) + ( ( TXU >> 5 ) & 0x7 );
4117
4118          tC1= (GETLE16(&psxVuw[(n_yi<<10)+YAdjust+n_xi]) >> ((TXU & 0x01)<<3)) & 0xff;
4119
4120          TXU=(posX+difX)>>16;
4121          TXV=(posY+difY)>>16;
4122          n_xi = ( ( TXU >> 1 ) & ~0x78 ) + ( ( TXU << 2 ) & 0x40 ) + ( ( TXV << 3 ) & 0x38 );
4123          n_yi = ( TXV & ~0x7 ) + ( ( TXU >> 5 ) & 0x7 );
4124
4125          tC2= (GETLE16(&psxVuw[(n_yi<<10)+YAdjust+n_xi]) >> ((TXU & 0x01)<<3)) & 0xff;
4126
4127          GetTextureTransColG32_S((uint32_t *)&psxVuw[(i<<10)+j],
4128               GETLE16(&psxVuw[clutP+tC1])|
4129               ((int32_t)GETLE16(&psxVuw[clutP+tC2]))<<16);
4130          posX+=difX2;
4131          posY+=difY2;
4132         }
4133        if(j==xmax)
4134         {
4135          TXU=posX>>16;
4136          TXV=posY>>16;
4137          n_xi = ( ( TXU >> 1 ) & ~0x78 ) + ( ( TXU << 2 ) & 0x40 ) + ( ( TXV << 3 ) & 0x38 );
4138          n_yi = ( TXV & ~0x7 ) + ( ( TXU >> 5 ) & 0x7 );
4139
4140          tC1= (GETLE16(&psxVuw[(n_yi<<10)+YAdjust+n_xi]) >> ((TXU & 0x01)<<3)) & 0xff;
4141
4142          GetTextureTransColG_S(&psxVuw[(i<<10)+j],GETLE16(&psxVuw[clutP+tC1]));
4143         }
4144       }
4145      if(NextRow_FT4()) return;
4146     }
4147    return;
4148   }
4149
4150 #endif
4151
4152  for (i=ymin;i<=ymax;i++)
4153   {
4154    xmin=(left_x >> 16);
4155    xmax=(right_x >> 16);
4156
4157    if(xmax>=xmin)
4158     {
4159      posX=left_u;
4160      posY=left_v;
4161
4162      num=(xmax-xmin);
4163      if(num==0) num=1;
4164      difX=(right_u-posX)/num;
4165      difY=(right_v-posY)/num;
4166      difX2=difX<<1;
4167      difY2=difY<<1;
4168
4169      if(xmin<drawX)
4170       {j=drawX-xmin;xmin=drawX;posX+=j*difX;posY+=j*difY;}
4171      xmax--;if(drawW<xmax) xmax=drawW;
4172
4173      for(j=xmin;j<xmax;j+=2)
4174       {
4175        TXU=posX>>16;
4176        TXV=posY>>16;
4177        n_xi = ( ( TXU >> 1 ) & ~0x78 ) + ( ( TXU << 2 ) & 0x40 ) + ( ( TXV << 3 ) & 0x38 );
4178        n_yi = ( TXV & ~0x7 ) + ( ( TXU >> 5 ) & 0x7 );
4179
4180        tC1= (GETLE16(&psxVuw[(n_yi<<10)+YAdjust+n_xi]) >> ((TXU & 0x01)<<3)) & 0xff;
4181
4182        TXU=(posX+difX)>>16;
4183        TXV=(posY+difY)>>16;
4184        n_xi = ( ( TXU >> 1 ) & ~0x78 ) + ( ( TXU << 2 ) & 0x40 ) + ( ( TXV << 3 ) & 0x38 );
4185        n_yi = ( TXV & ~0x7 ) + ( ( TXU >> 5 ) & 0x7 );
4186        
4187        tC2= (GETLE16(&psxVuw[(n_yi<<10)+YAdjust+n_xi]) >> ((TXU & 0x01)<<3)) & 0xff;
4188
4189        GetTextureTransColG32((uint32_t *)&psxVuw[(i<<10)+j],
4190             GETLE16(&psxVuw[clutP+tC1])|
4191             ((int32_t)GETLE16(&psxVuw[clutP+tC2]))<<16);
4192        posX+=difX2;
4193        posY+=difY2;
4194       }
4195      if(j==xmax)
4196       {
4197        TXU=posX>>16;
4198        TXV=posY>>16;
4199        n_xi = ( ( TXU >> 1 ) & ~0x78 ) + ( ( TXU << 2 ) & 0x40 ) + ( ( TXV << 3 ) & 0x38 );
4200        n_yi = ( TXV & ~0x7 ) + ( ( TXU >> 5 ) & 0x7 );
4201        tC1= (GETLE16(&psxVuw[(n_yi<<10)+YAdjust+n_xi]) >> ((TXU & 0x01)<<3)) & 0xff;
4202        GetTextureTransColG(&psxVuw[(i<<10)+j],GETLE16(&psxVuw[clutP+tC1]));
4203       }
4204     }
4205    if(NextRow_FT4()) return;
4206   }
4207 }
4208
4209 ////////////////////////////////////////////////////////////////////////
4210
4211 static void drawPoly4TEx8_TW(short x1, short y1, short x2, short y2, short x3, short y3, short x4, short y4, short tx1, short ty1, short tx2, short ty2, short tx3, short ty3, short tx4, short ty4,short clX, short clY)
4212 {
4213  int32_t num; 
4214  int32_t i,j,xmin,xmax,ymin,ymax;
4215  int32_t difX, difY, difX2, difY2;
4216  int32_t posX,posY,YAdjust,clutP;
4217  short tC1,tC2;
4218
4219  if(x1>drawW && x2>drawW && x3>drawW && x4>drawW) return;
4220  if(y1>drawH && y2>drawH && y3>drawH && y4>drawH) return;
4221  if(x1<drawX && x2<drawX && x3<drawX && x4<drawX) return;
4222  if(y1<drawY && y2<drawY && y3<drawY && y4<drawY) return;
4223  if(drawY>=drawH) return;
4224  if(drawX>=drawW) return; 
4225
4226  if(!SetupSections_FT4(x1,y1,x2,y2,x3,y3,x4,y4,tx1,ty1,tx2,ty2,tx3,ty3,tx4,ty4)) return;
4227
4228  ymax=Ymax;
4229
4230  for(ymin=Ymin;ymin<drawY;ymin++)
4231   if(NextRow_FT4()) return;
4232
4233  clutP=(clY<<10)+clX;
4234
4235  YAdjust=((GlobalTextAddrY)<<11)+(GlobalTextAddrX<<1);
4236  YAdjust+=(TWin.Position.y0<<11)+(TWin.Position.x0);
4237
4238 #ifdef FASTSOLID
4239
4240  if(!bCheckMask && !DrawSemiTrans)
4241   {
4242    for (i=ymin;i<=ymax;i++)
4243     {
4244      xmin=(left_x >> 16);
4245      xmax=(right_x >> 16);
4246
4247      if(xmax>=xmin)
4248       {
4249        posX=left_u;
4250        posY=left_v;
4251
4252        num=(xmax-xmin);
4253        if(num==0) num=1;
4254        difX=(right_u-posX)/num;
4255        difY=(right_v-posY)/num;
4256        difX2=difX<<1;
4257        difY2=difY<<1;
4258
4259        if(xmin<drawX)
4260         {j=drawX-xmin;xmin=drawX;posX+=j*difX;posY+=j*difY;}
4261        xmax--;if(drawW<xmax) xmax=drawW;
4262
4263        for(j=xmin;j<xmax;j+=2)
4264         {
4265          tC1 = psxVub[(((posY>>16)&TWin.ymask)<<11)+
4266                       YAdjust+((posX>>16)&TWin.xmask)];
4267          tC2 = psxVub[((((posY+difY)>>16)&TWin.ymask)<<11)+
4268                       YAdjust+(((posX+difX)>>16)&TWin.xmask)];
4269          GetTextureTransColG32_S((uint32_t *)&psxVuw[(i<<10)+j],
4270               GETLE16(&psxVuw[clutP+tC1])|
4271               ((int32_t)GETLE16(&psxVuw[clutP+tC2]))<<16);
4272          posX+=difX2;
4273          posY+=difY2;
4274         }
4275        if(j==xmax)
4276         {
4277          tC1 = psxVub[((((posY+difY)>>16)&TWin.ymask)<<11)+
4278                       YAdjust+((posX>>16)&TWin.xmask)];
4279          GetTextureTransColG_S(&psxVuw[(i<<10)+j],GETLE16(&psxVuw[clutP+tC1]));
4280         }
4281       }
4282      if(NextRow_FT4()) return;
4283     }
4284    return;
4285   }
4286
4287 #endif
4288
4289
4290  for (i=ymin;i<=ymax;i++)
4291   {
4292    xmin=(left_x >> 16);
4293    xmax=(right_x >> 16);
4294
4295    if(xmax>=xmin)
4296     {
4297      posX=left_u;
4298      posY=left_v;
4299
4300      num=(xmax-xmin);
4301      if(num==0) num=1;
4302      difX=(right_u-posX)/num;
4303      difY=(right_v-posY)/num;
4304      difX2=difX<<1;
4305      difY2=difY<<1;
4306
4307      if(xmin<drawX)
4308       {j=drawX-xmin;xmin=drawX;posX+=j*difX;posY+=j*difY;}
4309      xmax--;if(drawW<xmax) xmax=drawW;
4310
4311      for(j=xmin;j<xmax;j+=2)
4312       {
4313        tC1 = psxVub[(((posY>>16)&TWin.ymask)<<11)+
4314                     YAdjust+((posX>>16)&TWin.xmask)];
4315        tC2 = psxVub[((((posY+difY)>>16)&TWin.ymask)<<11)+
4316                      YAdjust+(((posX+difX)>>16)&TWin.xmask)];
4317        GetTextureTransColG32((uint32_t *)&psxVuw[(i<<10)+j],
4318             GETLE16(&psxVuw[clutP+tC1])|
4319             ((int32_t)GETLE16(&psxVuw[clutP+tC2]))<<16);
4320        posX+=difX2;
4321        posY+=difY2;
4322       }
4323      if(j==xmax)
4324       {
4325        tC1 = psxVub[((((posY+difY)>>16)&TWin.ymask)<<11)+
4326                     YAdjust+((posX>>16)&TWin.xmask)];
4327        GetTextureTransColG(&psxVuw[(i<<10)+j],GETLE16(&psxVuw[clutP+tC1]));
4328       }
4329     }
4330    if(NextRow_FT4()) return;
4331   }
4332 }
4333
4334 ////////////////////////////////////////////////////////////////////////
4335
4336 static void drawPoly4TEx8_TW_S(short x1, short y1, short x2, short y2, short x3, short y3, short x4, short y4, short tx1, short ty1, short tx2, short ty2, short tx3, short ty3, short tx4, short ty4,short clX, short clY)
4337 {
4338  int32_t num; 
4339  int32_t i,j,xmin,xmax,ymin,ymax;
4340  int32_t difX, difY, difX2, difY2;
4341  int32_t posX,posY,YAdjust,clutP;
4342  short tC1,tC2;
4343
4344  if(x1>drawW && x2>drawW && x3>drawW && x4>drawW) return;
4345  if(y1>drawH && y2>drawH && y3>drawH && y4>drawH) return;
4346  if(x1<drawX && x2<drawX && x3<drawX && x4<drawX) return;
4347  if(y1<drawY && y2<drawY && y3<drawY && y4<drawY) return;
4348  if(drawY>=drawH) return;
4349  if(drawX>=drawW) return; 
4350
4351  if(!SetupSections_FT4(x1,y1,x2,y2,x3,y3,x4,y4,tx1,ty1,tx2,ty2,tx3,ty3,tx4,ty4)) return;
4352
4353  ymax=Ymax;
4354
4355  for(ymin=Ymin;ymin<drawY;ymin++)
4356   if(NextRow_FT4()) return;
4357
4358  clutP=(clY<<10)+clX;
4359
4360  YAdjust=((GlobalTextAddrY)<<11)+(GlobalTextAddrX<<1);
4361  YAdjust+=(TWin.Position.y0<<11)+(TWin.Position.x0);
4362
4363 #ifdef FASTSOLID
4364
4365  if(!bCheckMask && !DrawSemiTrans)
4366   {
4367    for (i=ymin;i<=ymax;i++)
4368     {
4369      xmin=(left_x >> 16);
4370      xmax=(right_x >> 16);
4371
4372      if(xmax>=xmin)
4373       {
4374        posX=left_u;
4375        posY=left_v;
4376
4377        num=(xmax-xmin);
4378        if(num==0) num=1;
4379        difX=(right_u-posX)/num;
4380        difY=(right_v-posY)/num;
4381        difX2=difX<<1;
4382        difY2=difY<<1;
4383
4384        if(xmin<drawX)
4385         {j=drawX-xmin;xmin=drawX;posX+=j*difX;posY+=j*difY;}
4386        xmax--;if(drawW<xmax) xmax=drawW;
4387
4388        for(j=xmin;j<xmax;j+=2)
4389         {
4390          tC1 = psxVub[(((posY>>16)&TWin.ymask)<<11)+
4391                       YAdjust+((posX>>16)&TWin.xmask)];
4392          tC2 = psxVub[((((posY+difY)>>16)&TWin.ymask)<<11)+
4393                       YAdjust+(((posX+difX)>>16)&TWin.xmask)];
4394          GetTextureTransColG32_S((uint32_t *)&psxVuw[(i<<10)+j],
4395               GETLE16(&psxVuw[clutP+tC1])|
4396               ((int32_t)GETLE16(&psxVuw[clutP+tC2]))<<16);
4397          posX+=difX2;
4398          posY+=difY2;
4399         }
4400        if(j==xmax)
4401         {
4402          tC1 = psxVub[((((posY+difY)>>16)&TWin.ymask)<<11)+
4403                       YAdjust+((posX>>16)&TWin.xmask)];
4404          GetTextureTransColG_S(&psxVuw[(i<<10)+j],GETLE16(&psxVuw[clutP+tC1]));
4405         }
4406       }
4407      if(NextRow_FT4()) return;
4408     }
4409    return;
4410   }
4411
4412 #endif
4413
4414
4415  for (i=ymin;i<=ymax;i++)
4416   {
4417    xmin=(left_x >> 16);
4418    xmax=(right_x >> 16);
4419
4420    if(xmax>=xmin)
4421     {
4422      posX=left_u;
4423      posY=left_v;
4424
4425      num=(xmax-xmin);
4426      if(num==0) num=1;
4427      difX=(right_u-posX)/num;
4428      difY=(right_v-posY)/num;
4429      difX2=difX<<1;
4430      difY2=difY<<1;
4431
4432      if(xmin<drawX)
4433       {j=drawX-xmin;xmin=drawX;posX+=j*difX;posY+=j*difY;}
4434      xmax--;if(drawW<xmax) xmax=drawW;
4435
4436      for(j=xmin;j<xmax;j+=2)
4437       {
4438        tC1 = psxVub[(((posY>>16)&TWin.ymask)<<11)+
4439                     YAdjust+((posX>>16)&TWin.xmask)];
4440        tC2 = psxVub[((((posY+difY)>>16)&TWin.ymask)<<11)+
4441                      YAdjust+(((posX+difX)>>16)&TWin.xmask)];
4442        GetTextureTransColG32_SPR((uint32_t *)&psxVuw[(i<<10)+j],
4443             GETLE16(&psxVuw[clutP+tC1])|
4444             ((int32_t)GETLE16(&psxVuw[clutP+tC2]))<<16);
4445        posX+=difX2;
4446        posY+=difY2;
4447       }
4448      if(j==xmax)
4449       {
4450        tC1 = psxVub[((((posY+difY)>>16)&TWin.ymask)<<11)+
4451                     YAdjust+((posX>>16)&TWin.xmask)];
4452        GetTextureTransColG_SPR(&psxVuw[(i<<10)+j],GETLE16(&psxVuw[clutP+tC1]));
4453       }
4454     }
4455    if(NextRow_FT4()) return;
4456   }
4457 }
4458
4459 ////////////////////////////////////////////////////////////////////////
4460 // POLY 3 F-SHADED TEX 15 BIT
4461 ////////////////////////////////////////////////////////////////////////
4462
4463 static void drawPoly3TD(short x1, short y1, short x2, short y2, short x3, short y3, short tx1, short ty1, short tx2, short ty2, short tx3, short ty3)
4464 {
4465  int i,j,xmin,xmax,ymin,ymax;
4466  int32_t difX, difY,difX2, difY2;
4467  int32_t posX,posY;
4468
4469  if(x1>drawW && x2>drawW && x3>drawW) return;
4470  if(y1>drawH && y2>drawH && y3>drawH) return;
4471  if(x1<drawX && x2<drawX && x3<drawX) return;
4472  if(y1<drawY && y2<drawY && y3<drawY) return;
4473  if(drawY>=drawH) return;
4474  if(drawX>=drawW) return; 
4475                      
4476  if(!SetupSections_FT(x1,y1,x2,y2,x3,y3,tx1,ty1,tx2,ty2,tx3,ty3)) return;
4477
4478  ymax=Ymax;
4479
4480  for(ymin=Ymin;ymin<drawY;ymin++)
4481   if(NextRow_FT()) return;
4482
4483  difX=delta_right_u;difX2=difX<<1;
4484  difY=delta_right_v;difY2=difY<<1;
4485
4486 #ifdef FASTSOLID
4487
4488  if(!bCheckMask && !DrawSemiTrans)
4489   {
4490    for (i=ymin;i<=ymax;i++)
4491     {
4492      xmin=(left_x >> 16);
4493      xmax=(right_x >> 16)-1; //!!!!!!!!!!!!!
4494      if(drawW<xmax) xmax=drawW;
4495
4496      if(xmax>=xmin)
4497       {
4498        posX=left_u;
4499        posY=left_v;
4500
4501        if(xmin<drawX)
4502         {j=drawX-xmin;xmin=drawX;posX+=j*difX;posY+=j*difY;}
4503
4504        for(j=xmin;j<xmax;j+=2)
4505         {
4506          GetTextureTransColG32_S((uint32_t *)&psxVuw[(i<<10)+j],
4507               (((int32_t)GETLE16(&psxVuw[((((posY+difY)>>16)+GlobalTextAddrY)<<10)+((posX+difX)>>16)+GlobalTextAddrX]))<<16)|
4508               GETLE16(&psxVuw[(((posY>>16)+GlobalTextAddrY)<<10)+((posX)>>16)+GlobalTextAddrX]));
4509
4510          posX+=difX2;
4511          posY+=difY2;
4512         }
4513        if(j==xmax)
4514          GetTextureTransColG_S(&psxVuw[(i<<10)+j],
4515              GETLE16(&psxVuw[(((posY>>16)+GlobalTextAddrY)<<10)+(posX>>16)+GlobalTextAddrX]));
4516       }
4517      if(NextRow_FT()) 
4518       {
4519        return;
4520       }
4521     }
4522    return;
4523   }
4524
4525 #endif
4526
4527  for (i=ymin;i<=ymax;i++)
4528   {
4529    xmin=(left_x >> 16);
4530    xmax=(right_x >> 16)-1; //!!!!!!!!!!!!!!
4531    if(drawW<xmax) xmax=drawW;
4532
4533    if(xmax>=xmin)
4534     {
4535      posX=left_u;
4536      posY=left_v;
4537
4538      if(xmin<drawX)
4539       {j=drawX-xmin;xmin=drawX;posX+=j*difX;posY+=j*difY;}
4540
4541      for(j=xmin;j<xmax;j+=2)
4542       {
4543        GetTextureTransColG32((uint32_t *)&psxVuw[(i<<10)+j],
4544             (((int32_t)GETLE16(&psxVuw[((((posY+difY)>>16)+GlobalTextAddrY)<<10)+((posX+difX)>>16)+GlobalTextAddrX]))<<16)|
4545             GETLE16(&psxVuw[(((posY>>16)+GlobalTextAddrY)<<10)+((posX)>>16)+GlobalTextAddrX]));
4546
4547        posX+=difX2;
4548        posY+=difY2;
4549       }
4550      if(j==xmax)
4551        GetTextureTransColG(&psxVuw[(i<<10)+j],
4552            GETLE16(&psxVuw[(((posY>>16)+GlobalTextAddrY)<<10)+(posX>>16)+GlobalTextAddrX]));
4553     }
4554    if(NextRow_FT()) 
4555     {
4556      return;
4557     }
4558   }
4559 }
4560
4561 ////////////////////////////////////////////////////////////////////////
4562
4563 static void drawPoly3TD_TW(short x1, short y1, short x2, short y2, short x3, short y3, short tx1, short ty1, short tx2, short ty2, short tx3, short ty3)
4564 {
4565  int i,j,xmin,xmax,ymin,ymax;
4566  int32_t difX, difY,difX2, difY2;
4567  int32_t posX,posY;
4568
4569  if(x1>drawW && x2>drawW && x3>drawW) return;
4570  if(y1>drawH && y2>drawH && y3>drawH) return;
4571  if(x1<drawX && x2<drawX && x3<drawX) return;
4572  if(y1<drawY && y2<drawY && y3<drawY) return;
4573  if(drawY>=drawH) return;
4574  if(drawX>=drawW) return; 
4575                      
4576  if(!SetupSections_FT(x1,y1,x2,y2,x3,y3,tx1,ty1,tx2,ty2,tx3,ty3)) return;
4577
4578  ymax=Ymax;
4579
4580  for(ymin=Ymin;ymin<drawY;ymin++)
4581   if(NextRow_FT()) return;
4582
4583  difX=delta_right_u;difX2=difX<<1;
4584  difY=delta_right_v;difY2=difY<<1;
4585
4586 #ifdef FASTSOLID
4587
4588  if(!bCheckMask && !DrawSemiTrans)
4589   {
4590    for (i=ymin;i<=ymax;i++)
4591     {
4592      xmin=(left_x >> 16);
4593      xmax=(right_x >> 16)-1; //!!!!!!!!!!!!!
4594      if(drawW<xmax) xmax=drawW;
4595
4596      if(xmax>=xmin)
4597       {
4598        posX=left_u;
4599        posY=left_v;
4600
4601        if(xmin<drawX)
4602         {j=drawX-xmin;xmin=drawX;posX+=j*difX;posY+=j*difY;}
4603
4604        for(j=xmin;j<xmax;j+=2)
4605         {
4606          GetTextureTransColG32_S((uint32_t *)&psxVuw[(i<<10)+j],
4607               (((int32_t)GETLE16(&psxVuw[(((((posY+difY)>>16)&TWin.ymask)+GlobalTextAddrY+TWin.Position.y0)<<10)+
4608               (((posX+difX)>>16)&TWin.xmask)+GlobalTextAddrX+TWin.Position.x0]))<<16)|
4609               GETLE16(&psxVuw[((((posY>>16)&TWin.ymask)+GlobalTextAddrY+TWin.Position.y0)<<10)+
4610                      (((posX)>>16)&TWin.xmask)+GlobalTextAddrX+TWin.Position.x0]));
4611
4612          posX+=difX2;
4613          posY+=difY2;
4614         }
4615        if(j==xmax)
4616          GetTextureTransColG_S(&psxVuw[(i<<10)+j],
4617              GETLE16(&psxVuw[((((posY>>16)&TWin.ymask)+GlobalTextAddrY+TWin.Position.y0)<<10)+
4618                     ((posX>>16)&TWin.xmask)+GlobalTextAddrX+TWin.Position.x0]));
4619       }
4620      if(NextRow_FT()) 
4621       {
4622        return;
4623       }
4624     }
4625    return;
4626   }
4627
4628 #endif
4629
4630  for (i=ymin;i<=ymax;i++)
4631   {
4632    xmin=(left_x >> 16);
4633    xmax=(right_x >> 16)-1; //!!!!!!!!!!!!!!
4634    if(drawW<xmax) xmax=drawW;
4635
4636    if(xmax>=xmin)
4637     {
4638      posX=left_u;
4639      posY=left_v;
4640
4641      if(xmin<drawX)
4642       {j=drawX-xmin;xmin=drawX;posX+=j*difX;posY+=j*difY;}
4643
4644      for(j=xmin;j<xmax;j+=2)
4645       {
4646        GetTextureTransColG32((uint32_t *)&psxVuw[(i<<10)+j],
4647             (((int32_t)GETLE16(&psxVuw[(((((posY+difY)>>16)&TWin.ymask)+GlobalTextAddrY+TWin.Position.y0)<<10)+
4648             (((posX+difX)>>16)&TWin.xmask)+GlobalTextAddrX+TWin.Position.x0]))<<16)|
4649             GETLE16(&psxVuw[((((posY>>16)&TWin.ymask)+GlobalTextAddrY+TWin.Position.y0)<<10)+
4650                    (((posX)>>16)&TWin.xmask)+GlobalTextAddrX+TWin.Position.x0]));
4651
4652        posX+=difX2;
4653        posY+=difY2;
4654       }
4655      if(j==xmax)
4656        GetTextureTransColG(&psxVuw[(i<<10)+j],
4657            GETLE16(&psxVuw[((((posY>>16)&TWin.ymask)+GlobalTextAddrY+TWin.Position.y0)<<10)+
4658                   ((posX>>16)&TWin.xmask)+GlobalTextAddrX+TWin.Position.x0]));
4659     }
4660    if(NextRow_FT()) 
4661     {
4662      return;
4663     }
4664   }
4665 }
4666
4667
4668 ////////////////////////////////////////////////////////////////////////
4669
4670 #ifdef POLYQUAD3
4671
4672 static void drawPoly4TD_TRI(short x1, short y1, short x2, short y2, short x3, short y3, short x4, short y4, short tx1, short ty1, short tx2, short ty2, short tx3, short ty3, short tx4, short ty4)
4673 {
4674  drawPoly3TD(x2,y2,x3,y3,x4,y4,
4675             tx2,ty2,tx3,ty3,tx4,ty4);
4676  drawPoly3TD(x1,y1,x2,y2,x4,y4,
4677             tx1,ty1,tx2,ty2,tx4,ty4);
4678 }
4679
4680 #endif
4681
4682 // more exact:
4683
4684 static void drawPoly4TD(short x1, short y1, short x2, short y2, short x3, short y3, short x4, short y4, short tx1, short ty1, short tx2, short ty2, short tx3, short ty3, short tx4, short ty4)
4685 {
4686  int32_t num; 
4687  int32_t i,j,xmin,xmax,ymin,ymax;
4688  int32_t difX, difY, difX2, difY2;
4689  int32_t posX,posY;
4690
4691  if(x1>drawW && x2>drawW && x3>drawW && x4>drawW) return;
4692  if(y1>drawH && y2>drawH && y3>drawH && y4>drawH) return;
4693  if(x1<drawX && x2<drawX && x3<drawX && x4<drawX) return;
4694  if(y1<drawY && y2<drawY && y3<drawY && y4<drawY) return;
4695  if(drawY>=drawH) return;
4696  if(drawX>=drawW) return; 
4697
4698  if(!SetupSections_FT4(x1,y1,x2,y2,x3,y3,x4,y4,tx1,ty1,tx2,ty2,tx3,ty3,tx4,ty4)) return;
4699
4700  ymax=Ymax;
4701
4702  for(ymin=Ymin;ymin<drawY;ymin++)
4703   if(NextRow_FT4()) return;
4704
4705 #ifdef FASTSOLID
4706
4707  if(!bCheckMask && !DrawSemiTrans)
4708   {
4709    for (i=ymin;i<=ymax;i++)
4710     {
4711      xmin=(left_x >> 16);
4712      xmax=(right_x >> 16);
4713
4714      if(xmax>=xmin)
4715       {
4716        posX=left_u;
4717        posY=left_v;
4718
4719        num=(xmax-xmin);
4720        if(num==0) num=1;
4721        difX=(right_u-posX)/num;
4722        difY=(right_v-posY)/num;
4723        difX2=difX<<1;
4724        difY2=difY<<1;
4725
4726        if(xmin<drawX)
4727         {j=drawX-xmin;xmin=drawX;posX+=j*difX;posY+=j*difY;}
4728        xmax--;if(drawW<xmax) xmax=drawW;
4729
4730        for(j=xmin;j<xmax;j+=2)
4731         {
4732          GetTextureTransColG32_S((uint32_t *)&psxVuw[(i<<10)+j],
4733               (((int32_t)GETLE16(&psxVuw[((((posY+difY)>>16)+GlobalTextAddrY)<<10)+((posX+difX)>>16)+GlobalTextAddrX]))<<16)|
4734               GETLE16(&psxVuw[(((posY>>16)+GlobalTextAddrY)<<10)+((posX)>>16)+GlobalTextAddrX]));
4735
4736          posX+=difX2;
4737          posY+=difY2;
4738         }
4739        if(j==xmax)
4740         GetTextureTransColG_S(&psxVuw[(i<<10)+j],
4741            GETLE16(&psxVuw[(((posY>>16)+GlobalTextAddrY)<<10)+(posX>>16)+GlobalTextAddrX]));
4742       }
4743      if(NextRow_FT4()) return;
4744     }
4745    return;
4746   }
4747
4748 #endif
4749
4750  for (i=ymin;i<=ymax;i++)
4751   {
4752    xmin=(left_x >> 16);
4753    xmax=(right_x >> 16);
4754
4755    if(xmax>=xmin)
4756     {
4757      posX=left_u;
4758      posY=left_v;
4759
4760      num=(xmax-xmin);
4761      if(num==0) num=1;
4762      difX=(right_u-posX)/num;
4763      difY=(right_v-posY)/num;
4764      difX2=difX<<1;
4765      difY2=difY<<1;
4766
4767      if(xmin<drawX)
4768       {j=drawX-xmin;xmin=drawX;posX+=j*difX;posY+=j*difY;}
4769      xmax--;if(drawW<xmax) xmax=drawW;
4770
4771      for(j=xmin;j<xmax;j+=2)
4772       {
4773        GetTextureTransColG32((uint32_t *)&psxVuw[(i<<10)+j],
4774             (((int32_t)GETLE16(&psxVuw[((((posY+difY)>>16)+GlobalTextAddrY)<<10)+((posX+difX)>>16)+GlobalTextAddrX]))<<16)|
4775             GETLE16(&psxVuw[(((posY>>16)+GlobalTextAddrY)<<10)+((posX)>>16)+GlobalTextAddrX]));
4776
4777        posX+=difX2;
4778        posY+=difY2;
4779       }
4780      if(j==xmax)
4781       GetTextureTransColG(&psxVuw[(i<<10)+j],
4782          GETLE16(&psxVuw[(((posY>>16)+GlobalTextAddrY)<<10)+(posX>>16)+GlobalTextAddrX]));
4783     }
4784    if(NextRow_FT4()) return;
4785   }
4786 }
4787
4788 ////////////////////////////////////////////////////////////////////////
4789
4790 static void drawPoly4TD_TW(short x1, short y1, short x2, short y2, short x3, short y3, short x4, short y4, short tx1, short ty1, short tx2, short ty2, short tx3, short ty3, short tx4, short ty4)
4791 {
4792  int32_t num; 
4793  int32_t i,j,xmin,xmax,ymin,ymax;
4794  int32_t difX, difY, difX2, difY2;
4795  int32_t posX,posY;
4796
4797  if(x1>drawW && x2>drawW && x3>drawW && x4>drawW) return;
4798  if(y1>drawH && y2>drawH && y3>drawH && y4>drawH) return;
4799  if(x1<drawX && x2<drawX && x3<drawX && x4<drawX) return;
4800  if(y1<drawY && y2<drawY && y3<drawY && y4<drawY) return;
4801  if(drawY>=drawH) return;
4802  if(drawX>=drawW) return; 
4803
4804  if(!SetupSections_FT4(x1,y1,x2,y2,x3,y3,x4,y4,tx1,ty1,tx2,ty2,tx3,ty3,tx4,ty4)) return;
4805
4806  ymax=Ymax;
4807
4808  for(ymin=Ymin;ymin<drawY;ymin++)
4809   if(NextRow_FT4()) return;
4810
4811 #ifdef FASTSOLID
4812
4813  if(!bCheckMask && !DrawSemiTrans)
4814   {
4815    for (i=ymin;i<=ymax;i++)
4816     {
4817      xmin=(left_x >> 16);
4818      xmax=(right_x >> 16);
4819
4820      if(xmax>=xmin)
4821       {
4822        posX=left_u;
4823        posY=left_v;
4824
4825        num=(xmax-xmin);
4826        if(num==0) num=1;
4827        difX=(right_u-posX)/num;
4828        difY=(right_v-posY)/num;
4829        difX2=difX<<1;
4830        difY2=difY<<1;
4831
4832        if(xmin<drawX)
4833         {j=drawX-xmin;xmin=drawX;posX+=j*difX;posY+=j*difY;}
4834        xmax--;if(drawW<xmax) xmax=drawW;
4835
4836        for(j=xmin;j<xmax;j+=2)
4837         {
4838          GetTextureTransColG32_S((uint32_t *)&psxVuw[(i<<10)+j],
4839               (((int32_t)GETLE16(&psxVuw[(((((posY+difY)>>16)&TWin.ymask)+GlobalTextAddrY+TWin.Position.y0)<<10)+
4840                              (((posX+difX)>>16)&TWin.xmask)+GlobalTextAddrX+TWin.Position.x0]))<<16)|
4841               GETLE16(&psxVuw[((((posY>>16)&TWin.ymask)+GlobalTextAddrY)<<10)+TWin.Position.y0+
4842                     ((posX>>16)&TWin.xmask)+GlobalTextAddrX+TWin.Position.x0]));
4843
4844          posX+=difX2;
4845          posY+=difY2;
4846         }
4847        if(j==xmax)
4848         GetTextureTransColG_S(&psxVuw[(i<<10)+j],
4849            GETLE16(&psxVuw[((((posY>>16)&TWin.ymask)+GlobalTextAddrY+TWin.Position.y0)<<10)+
4850                   ((posX>>16)&TWin.xmask)+GlobalTextAddrX+TWin.Position.x0]));
4851       }
4852      if(NextRow_FT4()) return;
4853     }
4854    return;
4855   }
4856
4857 #endif
4858
4859  for (i=ymin;i<=ymax;i++)
4860   {
4861    xmin=(left_x >> 16);
4862    xmax=(right_x >> 16);
4863
4864    if(xmax>=xmin)
4865     {
4866      posX=left_u;
4867      posY=left_v;
4868
4869      num=(xmax-xmin);
4870      if(num==0) num=1;
4871      difX=(right_u-posX)/num;
4872      difY=(right_v-posY)/num;
4873      difX2=difX<<1;
4874      difY2=difY<<1;
4875
4876      if(xmin<drawX)
4877       {j=drawX-xmin;xmin=drawX;posX+=j*difX;posY+=j*difY;}
4878      xmax--;if(drawW<xmax) xmax=drawW;
4879
4880      for(j=xmin;j<xmax;j+=2)
4881       {
4882        GetTextureTransColG32((uint32_t *)&psxVuw[(i<<10)+j],
4883             (((int32_t)GETLE16(&psxVuw[(((((posY+difY)>>16)&TWin.ymask)+GlobalTextAddrY+TWin.Position.y0)<<10)+
4884                            (((posX+difX)>>16)&TWin.xmask)+GlobalTextAddrX+TWin.Position.x0]))<<16)|
4885             GETLE16(&psxVuw[((((posY>>16)&TWin.ymask)+GlobalTextAddrY+TWin.Position.y0)<<10)+
4886                    ((posX>>16)&TWin.xmask)+GlobalTextAddrX+TWin.Position.x0]));
4887
4888        posX+=difX2;
4889        posY+=difY2;
4890       }
4891      if(j==xmax)
4892       GetTextureTransColG(&psxVuw[(i<<10)+j],
4893          GETLE16(&psxVuw[((((posY>>16)&TWin.ymask)+GlobalTextAddrY+TWin.Position.y0)<<10)+
4894                 ((posX>>16)&TWin.xmask)+GlobalTextAddrX+TWin.Position.x0]));
4895     }
4896    if(NextRow_FT4()) return;
4897   }
4898 }
4899
4900 ////////////////////////////////////////////////////////////////////////
4901
4902 static void drawPoly4TD_TW_S(short x1, short y1, short x2, short y2, short x3, short y3, short x4, short y4, short tx1, short ty1, short tx2, short ty2, short tx3, short ty3, short tx4, short ty4)
4903 {
4904  int32_t num; 
4905  int32_t i,j,xmin,xmax,ymin,ymax;
4906  int32_t difX, difY, difX2, difY2;
4907  int32_t posX,posY;
4908
4909  if(x1>drawW && x2>drawW && x3>drawW && x4>drawW) return;
4910  if(y1>drawH && y2>drawH && y3>drawH && y4>drawH) return;
4911  if(x1<drawX && x2<drawX && x3<drawX && x4<drawX) return;
4912  if(y1<drawY && y2<drawY && y3<drawY && y4<drawY) return;
4913  if(drawY>=drawH) return;
4914  if(drawX>=drawW) return; 
4915
4916  if(!SetupSections_FT4(x1,y1,x2,y2,x3,y3,x4,y4,tx1,ty1,tx2,ty2,tx3,ty3,tx4,ty4)) return;
4917
4918  ymax=Ymax;
4919
4920  for(ymin=Ymin;ymin<drawY;ymin++)
4921   if(NextRow_FT4()) return;
4922
4923 #ifdef FASTSOLID
4924
4925  if(!bCheckMask && !DrawSemiTrans)
4926   {
4927    for (i=ymin;i<=ymax;i++)
4928     {
4929      xmin=(left_x >> 16);
4930      xmax=(right_x >> 16);
4931
4932      if(xmax>=xmin)
4933       {
4934        posX=left_u;
4935        posY=left_v;
4936
4937        num=(xmax-xmin);
4938        if(num==0) num=1;
4939        difX=(right_u-posX)/num;
4940        difY=(right_v-posY)/num;
4941        difX2=difX<<1;
4942        difY2=difY<<1;
4943
4944        if(xmin<drawX)
4945         {j=drawX-xmin;xmin=drawX;posX+=j*difX;posY+=j*difY;}
4946        xmax--;if(drawW<xmax) xmax=drawW;
4947
4948        for(j=xmin;j<xmax;j+=2)
4949         {
4950          GetTextureTransColG32_S((uint32_t *)&psxVuw[(i<<10)+j],
4951               (((int32_t)GETLE16(&psxVuw[(((((posY+difY)>>16)&TWin.ymask)+GlobalTextAddrY+TWin.Position.y0)<<10)+
4952                              (((posX+difX)>>16)&TWin.xmask)+GlobalTextAddrX+TWin.Position.x0]))<<16)|
4953               GETLE16(&psxVuw[((((posY>>16)&TWin.ymask)+GlobalTextAddrY)<<10)+TWin.Position.y0+
4954                      ((posX>>16)&TWin.xmask)+GlobalTextAddrX+TWin.Position.x0]));
4955
4956          posX+=difX2;
4957          posY+=difY2;
4958         }
4959        if(j==xmax)
4960         GetTextureTransColG_S(&psxVuw[(i<<10)+j],
4961            GETLE16(&psxVuw[((((posY>>16)&TWin.ymask)+GlobalTextAddrY+TWin.Position.y0)<<10)+
4962                   ((posX>>16)&TWin.xmask)+GlobalTextAddrX+TWin.Position.x0]));
4963       }
4964      if(NextRow_FT4()) return;
4965     }
4966    return;
4967   }
4968
4969 #endif
4970
4971  for (i=ymin;i<=ymax;i++)
4972   {
4973    xmin=(left_x >> 16);
4974    xmax=(right_x >> 16);
4975
4976    if(xmax>=xmin)
4977     {
4978      posX=left_u;
4979      posY=left_v;
4980
4981      num=(xmax-xmin);
4982      if(num==0) num=1;
4983      difX=(right_u-posX)/num;
4984      difY=(right_v-posY)/num;
4985      difX2=difX<<1;
4986      difY2=difY<<1;
4987
4988      if(xmin<drawX)
4989       {j=drawX-xmin;xmin=drawX;posX+=j*difX;posY+=j*difY;}
4990      xmax--;if(drawW<xmax) xmax=drawW;
4991
4992      for(j=xmin;j<xmax;j+=2)
4993       {
4994        GetTextureTransColG32_SPR((uint32_t *)&psxVuw[(i<<10)+j],
4995             (((int32_t)GETLE16(&psxVuw[(((((posY+difY)>>16)&TWin.ymask)+GlobalTextAddrY+TWin.Position.y0)<<10)+
4996                            (((posX+difX)>>16)&TWin.xmask)+GlobalTextAddrX+TWin.Position.x0]))<<16)|
4997             GETLE16(&psxVuw[((((posY>>16)&TWin.ymask)+GlobalTextAddrY+TWin.Position.y0)<<10)+
4998                    ((posX>>16)&TWin.xmask)+GlobalTextAddrX+TWin.Position.x0]));
4999
5000        posX+=difX2;
5001        posY+=difY2;
5002       }
5003      if(j==xmax)
5004       GetTextureTransColG_SPR(&psxVuw[(i<<10)+j],
5005          GETLE16(&psxVuw[((((posY>>16)&TWin.ymask)+GlobalTextAddrY+TWin.Position.y0)<<10)+
5006                 ((posX>>16)&TWin.xmask)+GlobalTextAddrX+TWin.Position.x0]));
5007     }
5008    if(NextRow_FT4()) return;
5009   }
5010 }
5011
5012 ////////////////////////////////////////////////////////////////////////
5013 // POLY 3/4 G-SHADED
5014 ////////////////////////////////////////////////////////////////////////
5015  
5016 static inline void drawPoly3Gi(short x1,short y1,short x2,short y2,short x3,short y3,int32_t rgb1, int32_t rgb2, int32_t rgb3)
5017 {
5018  int i,j,xmin,xmax,ymin,ymax;
5019  int32_t cR1,cG1,cB1;
5020  int32_t difR,difB,difG,difR2,difB2,difG2;
5021
5022  if(x1>drawW && x2>drawW && x3>drawW) return;
5023  if(y1>drawH && y2>drawH && y3>drawH) return;
5024  if(x1<drawX && x2<drawX && x3<drawX) return;
5025  if(y1<drawY && y2<drawY && y3<drawY) return;
5026  if(drawY>=drawH) return;
5027  if(drawX>=drawW) return; 
5028
5029  if(!SetupSections_G(x1,y1,x2,y2,x3,y3,rgb1,rgb2,rgb3)) return;
5030
5031  ymax=Ymax;
5032
5033  for(ymin=Ymin;ymin<drawY;ymin++)
5034   if(NextRow_G()) return;
5035
5036  difR=delta_right_R;
5037  difG=delta_right_G;
5038  difB=delta_right_B;
5039  difR2=difR<<1;
5040  difG2=difG<<1;
5041  difB2=difB<<1;
5042
5043 #ifdef FASTSOLID
5044
5045  if(!bCheckMask && !DrawSemiTrans && iDither!=2)
5046   {
5047    for (i=ymin;i<=ymax;i++)
5048     {
5049      xmin=(left_x >> 16);
5050      xmax=(right_x >> 16)-1;if(drawW<xmax) xmax=drawW;
5051
5052      if(xmax>=xmin)
5053       {
5054        cR1=left_R;
5055        cG1=left_G;
5056        cB1=left_B;
5057
5058        if(xmin<drawX)
5059         {j=drawX-xmin;xmin=drawX;cR1+=j*difR;cG1+=j*difG;cB1+=j*difB;}
5060
5061        for(j=xmin;j<xmax;j+=2) 
5062         {
5063          PUTLE32(((uint32_t *)&psxVuw[(i<<10)+j]), 
5064             ((((cR1+difR) <<7)&0x7c000000)|(((cG1+difG) << 2)&0x03e00000)|(((cB1+difB)>>3)&0x001f0000)|
5065              (((cR1) >> 9)&0x7c00)|(((cG1) >> 14)&0x03e0)|(((cB1) >> 19)&0x001f))|lSetMask);
5066    
5067          cR1+=difR2;
5068          cG1+=difG2;
5069          cB1+=difB2;
5070         }
5071        if(j==xmax)
5072         PUTLE16(&psxVuw[(i<<10)+j], (((cR1 >> 9)&0x7c00)|((cG1 >> 14)&0x03e0)|((cB1 >> 19)&0x001f))|sSetMask);
5073       }
5074      if(NextRow_G()) return;
5075     }
5076    return;
5077   }
5078
5079 #endif
5080
5081  if(iDither==2)
5082  for (i=ymin;i<=ymax;i++)
5083   {
5084    xmin=(left_x >> 16);
5085    xmax=(right_x >> 16)-1;if(drawW<xmax) xmax=drawW;
5086
5087    if(xmax>=xmin)
5088     {
5089      cR1=left_R;
5090      cG1=left_G;
5091      cB1=left_B;
5092
5093      if(xmin<drawX)
5094       {j=drawX-xmin;xmin=drawX;cR1+=j*difR;cG1+=j*difG;cB1+=j*difB;}
5095
5096      for(j=xmin;j<=xmax;j++) 
5097       {
5098        GetShadeTransCol_Dither(&psxVuw[(i<<10)+j],(cB1>>16),(cG1>>16),(cR1>>16));
5099
5100        cR1+=difR;
5101        cG1+=difG;
5102        cB1+=difB;
5103       }
5104     }
5105    if(NextRow_G()) return;
5106   }
5107  else
5108  for (i=ymin;i<=ymax;i++)
5109   {
5110    xmin=(left_x >> 16);
5111    xmax=(right_x >> 16)-1;if(drawW<xmax) xmax=drawW;
5112
5113    if(xmax>=xmin)
5114     {
5115      cR1=left_R;
5116      cG1=left_G;
5117      cB1=left_B;
5118
5119      if(xmin<drawX)
5120       {j=drawX-xmin;xmin=drawX;cR1+=j*difR;cG1+=j*difG;cB1+=j*difB;}
5121
5122      for(j=xmin;j<=xmax;j++) 
5123       {
5124        GetShadeTransCol(&psxVuw[(i<<10)+j],((cR1 >> 9)&0x7c00)|((cG1 >> 14)&0x03e0)|((cB1 >> 19)&0x001f));
5125
5126        cR1+=difR;
5127        cG1+=difG;
5128        cB1+=difB;
5129       }
5130     }
5131    if(NextRow_G()) return;
5132   }
5133
5134 }
5135
5136 ////////////////////////////////////////////////////////////////////////
5137
5138 static void drawPoly3G(int32_t rgb1, int32_t rgb2, int32_t rgb3)
5139 {
5140  drawPoly3Gi(lx0,ly0,lx1,ly1,lx2,ly2,rgb1,rgb2,rgb3);
5141 }
5142
5143 // draw two g-shaded tris for right psx shading emulation
5144
5145 static void drawPoly4G(int32_t rgb1, int32_t rgb2, int32_t rgb3, int32_t rgb4)
5146 {
5147  drawPoly3Gi(lx1,ly1,lx3,ly3,lx2,ly2,
5148              rgb2,rgb4,rgb3);
5149  drawPoly3Gi(lx0,ly0,lx1,ly1,lx2,ly2,
5150              rgb1,rgb2,rgb3);
5151 }
5152
5153 ////////////////////////////////////////////////////////////////////////
5154 // POLY 3/4 G-SHADED TEX PAL4
5155 ////////////////////////////////////////////////////////////////////////
5156
5157 static void drawPoly3TGEx4(short x1, short y1, short x2, short y2, short x3, short y3, short tx1, short ty1, short tx2, short ty2, short tx3, short ty3, short clX, short clY,int32_t col1, int32_t col2, int32_t col3)
5158 {
5159  int i,j,xmin,xmax,ymin,ymax;
5160  int32_t cR1,cG1,cB1;
5161  int32_t difR,difB,difG,difR2,difB2,difG2;
5162  int32_t difX, difY,difX2, difY2;
5163  int32_t posX,posY,YAdjust,clutP,XAdjust;
5164  short tC1,tC2;
5165
5166  if(x1>drawW && x2>drawW && x3>drawW) return;
5167  if(y1>drawH && y2>drawH && y3>drawH) return;
5168  if(x1<drawX && x2<drawX && x3<drawX) return;
5169  if(y1<drawY && y2<drawY && y3<drawY) return;
5170  if(drawY>=drawH) return;
5171  if(drawX>=drawW) return; 
5172
5173  if(!SetupSections_GT(x1,y1,x2,y2,x3,y3,tx1,ty1,tx2,ty2,tx3,ty3,col1,col2,col3)) return;
5174
5175  ymax=Ymax;
5176
5177  for(ymin=Ymin;ymin<drawY;ymin++)
5178   if(NextRow_GT()) return;
5179
5180  clutP=(clY<<10)+clX;
5181
5182  YAdjust=((GlobalTextAddrY)<<11)+(GlobalTextAddrX<<1);
5183
5184  difR=delta_right_R;
5185  difG=delta_right_G;
5186  difB=delta_right_B;
5187  difR2=difR<<1;
5188  difG2=difG<<1;
5189  difB2=difB<<1;
5190
5191  difX=delta_right_u;difX2=difX<<1;
5192  difY=delta_right_v;difY2=difY<<1;
5193
5194 #ifdef FASTSOLID
5195
5196  if(!bCheckMask && !DrawSemiTrans && !iDither)
5197   {
5198    for (i=ymin;i<=ymax;i++)
5199     {
5200      xmin=((left_x) >> 16);
5201      xmax=((right_x) >> 16)-1; //!!!!!!!!!!!!!
5202      if(drawW<xmax) xmax=drawW;
5203
5204      if(xmax>=xmin)
5205       {
5206        posX=left_u;
5207        posY=left_v;
5208        cR1=left_R;
5209        cG1=left_G;
5210        cB1=left_B;
5211
5212        if(xmin<drawX)
5213         {j=drawX-xmin;xmin=drawX;posX+=j*difX;posY+=j*difY;cR1+=j*difR;cG1+=j*difG;cB1+=j*difB;}
5214
5215        for(j=xmin;j<xmax;j+=2) 
5216         {
5217          XAdjust=(posX>>16);
5218          tC1 = psxVub[((posY>>5)&0xFFFFF800)+YAdjust+(XAdjust>>1)];
5219          tC1=(tC1>>((XAdjust&1)<<2))&0xf;
5220          XAdjust=((posX+difX)>>16);
5221          tC2 = psxVub[(((posY+difY)>>5)&(int32_t)0xFFFFF800)+YAdjust+
5222                       (XAdjust>>1)];
5223          tC2=(tC2>>((XAdjust&1)<<2))&0xf;
5224
5225          GetTextureTransColGX32_S((uint32_t *)&psxVuw[(i<<10)+j],
5226                GETLE16(&psxVuw[clutP+tC1])|
5227                ((int32_t)GETLE16(&psxVuw[clutP+tC2]))<<16,
5228                (cB1>>16)|((cB1+difB)&0xff0000),
5229                (cG1>>16)|((cG1+difG)&0xff0000),
5230                (cR1>>16)|((cR1+difR)&0xff0000));
5231          posX+=difX2;
5232          posY+=difY2;
5233          cR1+=difR2;
5234          cG1+=difG2;
5235          cB1+=difB2;
5236         }
5237        if(j==xmax)
5238         {
5239          XAdjust=(posX>>16);
5240          tC1 = psxVub[((posY>>5)&(int32_t)0xFFFFF800)+YAdjust+(XAdjust>>1)];
5241          tC1=(tC1>>((XAdjust&1)<<2))&0xf;
5242          GetTextureTransColGX_S(&psxVuw[(i<<10)+j], 
5243               GETLE16(&psxVuw[clutP+tC1]),
5244               (cB1>>16),(cG1>>16),(cR1>>16));
5245         }
5246       }
5247      if(NextRow_GT()) 
5248       {
5249        return;
5250       }
5251     }
5252    return;
5253   }
5254
5255 #endif
5256
5257  for (i=ymin;i<=ymax;i++)
5258   {
5259    xmin=(left_x >> 16);
5260    xmax=(right_x >> 16)-1; //!!!!!!!!!!!!!!!!
5261    if(drawW<xmax) xmax=drawW;
5262
5263    if(xmax>=xmin)
5264     {
5265      posX=left_u;
5266      posY=left_v;
5267      cR1=left_R;
5268      cG1=left_G;
5269      cB1=left_B;
5270
5271      if(xmin<drawX)
5272       {j=drawX-xmin;xmin=drawX;posX+=j*difX;posY+=j*difY;cR1+=j*difR;cG1+=j*difG;cB1+=j*difB;}
5273
5274      for(j=xmin;j<=xmax;j++) 
5275       {
5276        XAdjust=(posX>>16);
5277        tC1 = psxVub[((posY>>5)&(int32_t)0xFFFFF800)+YAdjust+(XAdjust>>1)];
5278        tC1=(tC1>>((XAdjust&1)<<2))&0xf;
5279        if(iDither)
5280         GetTextureTransColGX_Dither(&psxVuw[(i<<10)+j], 
5281             GETLE16(&psxVuw[clutP+tC1]),
5282             (cB1>>16),(cG1>>16),(cR1>>16));
5283        else
5284         GetTextureTransColGX(&psxVuw[(i<<10)+j], 
5285             GETLE16(&psxVuw[clutP+tC1]),
5286             (cB1>>16),(cG1>>16),(cR1>>16));
5287        posX+=difX;
5288        posY+=difY;
5289        cR1+=difR;
5290        cG1+=difG;
5291        cB1+=difB;
5292       }
5293     }
5294    if(NextRow_GT()) 
5295     {
5296      return;
5297     }
5298   }
5299 }
5300
5301 ////////////////////////////////////////////////////////////////////////
5302
5303 static void drawPoly3TGEx4_IL(short x1, short y1, short x2, short y2, short x3, short y3, short tx1, short ty1, short tx2, short ty2, short tx3, short ty3, short clX, short clY,int32_t col1, int32_t col2, int32_t col3)
5304 {
5305  int i,j,xmin,xmax,ymin,ymax,n_xi,n_yi,TXV;
5306  int32_t cR1,cG1,cB1;
5307  int32_t difR,difB,difG,difR2,difB2,difG2;
5308  int32_t difX, difY,difX2, difY2;
5309  int32_t posX,posY,YAdjust,clutP,XAdjust;
5310  short tC1,tC2;
5311
5312  if(x1>drawW && x2>drawW && x3>drawW) return;
5313  if(y1>drawH && y2>drawH && y3>drawH) return;
5314  if(x1<drawX && x2<drawX && x3<drawX) return;
5315  if(y1<drawY && y2<drawY && y3<drawY) return;
5316  if(drawY>=drawH) return;
5317  if(drawX>=drawW) return; 
5318
5319  if(!SetupSections_GT(x1,y1,x2,y2,x3,y3,tx1,ty1,tx2,ty2,tx3,ty3,col1,col2,col3)) return;
5320
5321  ymax=Ymax;
5322
5323  for(ymin=Ymin;ymin<drawY;ymin++)
5324   if(NextRow_GT()) return;
5325
5326  clutP=(clY<<10)+clX;
5327
5328  YAdjust=(GlobalTextAddrY<<10)+GlobalTextAddrX;
5329
5330  difR=delta_right_R;
5331  difG=delta_right_G;
5332  difB=delta_right_B;
5333  difR2=difR<<1;
5334  difG2=difG<<1;
5335  difB2=difB<<1;
5336
5337  difX=delta_right_u;difX2=difX<<1;
5338  difY=delta_right_v;difY2=difY<<1;
5339
5340 #ifdef FASTSOLID
5341
5342  if(!bCheckMask && !DrawSemiTrans && !iDither)
5343   {
5344    for (i=ymin;i<=ymax;i++)
5345     {
5346      xmin=((left_x) >> 16);
5347      xmax=((right_x) >> 16)-1; //!!!!!!!!!!!!!
5348      if(drawW<xmax) xmax=drawW;
5349
5350      if(xmax>=xmin)
5351       {
5352        posX=left_u;
5353        posY=left_v;
5354        cR1=left_R;
5355        cG1=left_G;
5356        cB1=left_B;
5357
5358        if(xmin<drawX)
5359         {j=drawX-xmin;xmin=drawX;posX+=j*difX;posY+=j*difY;cR1+=j*difR;cG1+=j*difG;cB1+=j*difB;}
5360
5361        for(j=xmin;j<xmax;j+=2) 
5362         {
5363          XAdjust=(posX>>16);
5364
5365          TXV=posY>>16;
5366          n_xi = ( ( XAdjust >> 2 ) & ~0x3c ) + ( ( TXV << 2 ) & 0x3c );
5367          n_yi = ( TXV & ~0xf ) + ( ( XAdjust >> 4 ) & 0xf );
5368  
5369          tC1= (GETLE16(&psxVuw[(n_yi<<10)+YAdjust+n_xi]) >> ((XAdjust & 0x03)<<2)) & 0x0f ;
5370
5371          XAdjust=((posX+difX)>>16);
5372
5373          TXV=(posY+difY)>>16;
5374          n_xi = ( ( XAdjust >> 2 ) & ~0x3c ) + ( ( TXV << 2 ) & 0x3c );
5375          n_yi = ( TXV & ~0xf ) + ( ( XAdjust >> 4 ) & 0xf );
5376
5377          tC2= (GETLE16(&psxVuw[(n_yi<<10)+YAdjust+n_xi]) >> ((XAdjust & 0x03)<<2)) & 0x0f ;
5378
5379          GetTextureTransColGX32_S((uint32_t *)&psxVuw[(i<<10)+j],
5380                GETLE16(&psxVuw[clutP+tC1])|
5381                ((int32_t)GETLE16(&psxVuw[clutP+tC2]))<<16,
5382                (cB1>>16)|((cB1+difB)&0xff0000),
5383                (cG1>>16)|((cG1+difG)&0xff0000),
5384                (cR1>>16)|((cR1+difR)&0xff0000));
5385          posX+=difX2;
5386          posY+=difY2;
5387          cR1+=difR2;
5388          cG1+=difG2;
5389          cB1+=difB2;
5390         }
5391        if(j==xmax)
5392         {
5393          XAdjust=(posX>>16);
5394
5395          TXV=posY>>16;
5396          n_xi = ( ( XAdjust >> 2 ) & ~0x3c ) + ( ( TXV << 2 ) & 0x3c );
5397          n_yi = ( TXV & ~0xf ) + ( ( XAdjust >> 4 ) & 0xf );
5398
5399          tC1= (GETLE16(&psxVuw[(n_yi<<10)+YAdjust+n_xi]) >> ((XAdjust & 0x03)<<2)) & 0x0f ;
5400
5401          GetTextureTransColGX_S(&psxVuw[(i<<10)+j], 
5402               GETLE16(&psxVuw[clutP+tC1]),
5403               (cB1>>16),(cG1>>16),(cR1>>16));
5404         }
5405       }
5406      if(NextRow_GT()) 
5407       {
5408        return;
5409       }
5410     }
5411    return;
5412   }
5413
5414 #endif
5415
5416  for (i=ymin;i<=ymax;i++)
5417   {
5418    xmin=(left_x >> 16);
5419    xmax=(right_x >> 16)-1; //!!!!!!!!!!!!!!!!
5420    if(drawW<xmax) xmax=drawW;
5421
5422    if(xmax>=xmin)
5423     {
5424      posX=left_u;
5425      posY=left_v;
5426      cR1=left_R;
5427      cG1=left_G;
5428      cB1=left_B;
5429
5430      if(xmin<drawX)
5431       {j=drawX-xmin;xmin=drawX;posX+=j*difX;posY+=j*difY;cR1+=j*difR;cG1+=j*difG;cB1+=j*difB;}
5432
5433      for(j=xmin;j<=xmax;j++) 
5434       {
5435        XAdjust=(posX>>16);
5436
5437        TXV=posY>>16;
5438        n_xi = ( ( XAdjust >> 2 ) & ~0x3c ) + ( ( TXV << 2 ) & 0x3c );
5439        n_yi = ( TXV & ~0xf ) + ( ( XAdjust >> 4 ) & 0xf );
5440
5441        tC1= (GETLE16(&psxVuw[(n_yi<<10)+YAdjust+n_xi]) >> ((XAdjust & 0x03)<<2)) & 0x0f ;
5442
5443        if(iDither)
5444         GetTextureTransColGX_Dither(&psxVuw[(i<<10)+j], 
5445             GETLE16(&psxVuw[clutP+tC1]),
5446             (cB1>>16),(cG1>>16),(cR1>>16));
5447        else
5448         GetTextureTransColGX(&psxVuw[(i<<10)+j], 
5449             GETLE16(&psxVuw[clutP+tC1]),
5450             (cB1>>16),(cG1>>16),(cR1>>16));
5451        posX+=difX;
5452        posY+=difY;
5453        cR1+=difR;
5454        cG1+=difG;
5455        cB1+=difB;
5456       }
5457     }
5458    if(NextRow_GT()) 
5459     {
5460      return;
5461     }
5462   }
5463 }
5464
5465 ////////////////////////////////////////////////////////////////////////
5466
5467 static void drawPoly3TGEx4_TW(short x1, short y1, short x2, short y2, short x3, short y3, short tx1, short ty1, short tx2, short ty2, short tx3, short ty3, short clX, short clY,int32_t col1, int32_t col2, int32_t col3)
5468 {
5469  int i,j,xmin,xmax,ymin,ymax;
5470  int32_t cR1,cG1,cB1;
5471  int32_t difR,difB,difG,difR2,difB2,difG2;
5472  int32_t difX, difY,difX2, difY2;
5473  int32_t posX,posY,YAdjust,clutP,XAdjust;
5474  short tC1,tC2;
5475
5476  if(x1>drawW && x2>drawW && x3>drawW) return;
5477  if(y1>drawH && y2>drawH && y3>drawH) return;
5478  if(x1<drawX && x2<drawX && x3<drawX) return;
5479  if(y1<drawY && y2<drawY && y3<drawY) return;
5480  if(drawY>=drawH) return;
5481  if(drawX>=drawW) return; 
5482
5483  if(!SetupSections_GT(x1,y1,x2,y2,x3,y3,tx1,ty1,tx2,ty2,tx3,ty3,col1,col2,col3)) return;
5484
5485  ymax=Ymax;
5486
5487  for(ymin=Ymin;ymin<drawY;ymin++)
5488   if(NextRow_GT()) return;
5489
5490  clutP=(clY<<10)+clX;
5491
5492  YAdjust=((GlobalTextAddrY)<<11)+(GlobalTextAddrX<<1);
5493  YAdjust+=(TWin.Position.y0<<11)+(TWin.Position.x0>>1);
5494
5495  difR=delta_right_R;
5496  difG=delta_right_G;
5497  difB=delta_right_B;
5498  difR2=difR<<1;
5499  difG2=difG<<1;
5500  difB2=difB<<1;
5501
5502  difX=delta_right_u;difX2=difX<<1;
5503  difY=delta_right_v;difY2=difY<<1;
5504
5505 #ifdef FASTSOLID
5506
5507  if(!bCheckMask && !DrawSemiTrans && !iDither)
5508   {
5509    for (i=ymin;i<=ymax;i++)
5510     {
5511      xmin=((left_x) >> 16);
5512      xmax=((right_x) >> 16)-1; //!!!!!!!!!!!!!
5513      if(drawW<xmax) xmax=drawW;
5514
5515      if(xmax>=xmin)
5516       {
5517        posX=left_u;
5518        posY=left_v;
5519        cR1=left_R;
5520        cG1=left_G;
5521        cB1=left_B;
5522
5523        if(xmin<drawX)
5524         {j=drawX-xmin;xmin=drawX;posX+=j*difX;posY+=j*difY;cR1+=j*difR;cG1+=j*difG;cB1+=j*difB;}
5525
5526        for(j=xmin;j<xmax;j+=2) 
5527         {
5528          XAdjust=(posX>>16)&TWin.xmask;
5529          tC1 = psxVub[(((posY>>16)&TWin.ymask)<<11)+
5530                       YAdjust+(XAdjust>>1)];
5531          tC1=(tC1>>((XAdjust&1)<<2))&0xf;
5532          XAdjust=((posX+difX)>>16)&TWin.xmask;
5533          tC2 = psxVub[((((posY+difY)>>16)&TWin.ymask)<<11)+
5534                       YAdjust+(XAdjust>>1)];
5535          tC2=(tC2>>((XAdjust&1)<<2))&0xf;
5536          GetTextureTransColGX32_S((uint32_t *)&psxVuw[(i<<10)+j],
5537               GETLE16(&psxVuw[clutP+tC1])|
5538               ((int32_t)GETLE16(&psxVuw[clutP+tC2]))<<16,
5539               (cB1>>16)|((cB1+difB)&0xff0000),
5540               (cG1>>16)|((cG1+difG)&0xff0000),
5541               (cR1>>16)|((cR1+difR)&0xff0000));
5542          posX+=difX2;
5543          posY+=difY2;
5544          cR1+=difR2;
5545          cG1+=difG2;
5546          cB1+=difB2;
5547         }
5548        if(j==xmax)
5549         {
5550          XAdjust=(posX>>16)&TWin.xmask;
5551          tC1 = psxVub[(((posY>>16)&TWin.ymask)<<11)+
5552                        YAdjust+(XAdjust>>1)];
5553          tC1=(tC1>>((XAdjust&1)<<2))&0xf;
5554          GetTextureTransColGX_S(&psxVuw[(i<<10)+j], 
5555              GETLE16(&psxVuw[clutP+tC1]),
5556              (cB1>>16),(cG1>>16),(cR1>>16));
5557         }
5558       }
5559      if(NextRow_GT()) 
5560       {
5561        return;
5562       }
5563     }
5564    return;
5565   }
5566
5567 #endif
5568
5569  for (i=ymin;i<=ymax;i++)
5570   {
5571    xmin=(left_x >> 16);
5572    xmax=(right_x >> 16)-1; //!!!!!!!!!!!!!!!!
5573    if(drawW<xmax) xmax=drawW;
5574
5575    if(xmax>=xmin)
5576     {
5577      posX=left_u;
5578      posY=left_v;
5579      cR1=left_R;
5580      cG1=left_G;
5581      cB1=left_B;
5582
5583      if(xmin<drawX)
5584       {j=drawX-xmin;xmin=drawX;posX+=j*difX;posY+=j*difY;cR1+=j*difR;cG1+=j*difG;cB1+=j*difB;}
5585
5586      for(j=xmin;j<=xmax;j++) 
5587       {
5588        XAdjust=(posX>>16)&TWin.xmask;
5589        tC1 = psxVub[(((posY>>16)&TWin.ymask)<<11)+
5590                     YAdjust+(XAdjust>>1)];
5591        tC1=(tC1>>((XAdjust&1)<<2))&0xf;
5592        if(iDither)
5593         GetTextureTransColGX_Dither(&psxVuw[(i<<10)+j], 
5594             GETLE16(&psxVuw[clutP+tC1]),
5595             (cB1>>16),(cG1>>16),(cR1>>16));
5596        else
5597         GetTextureTransColGX(&psxVuw[(i<<10)+j], 
5598             GETLE16(&psxVuw[clutP+tC1]),
5599             (cB1>>16),(cG1>>16),(cR1>>16));
5600        posX+=difX;
5601        posY+=difY;
5602        cR1+=difR;
5603        cG1+=difG;
5604        cB1+=difB;
5605       }
5606     }
5607    if(NextRow_GT()) 
5608     {
5609      return;
5610     }
5611   }
5612 }
5613
5614 ////////////////////////////////////////////////////////////////////////
5615
5616 // note: the psx is doing g-shaded quads as two g-shaded tris,
5617 // like the following func... sadly texturing is not 100%
5618 // correct that way, so small texture distortions can 
5619 // happen... 
5620
5621 static void drawPoly4TGEx4_TRI_IL(short x1, short y1, short x2, short y2, short x3, short y3, short x4, short y4,
5622                     short tx1, short ty1, short tx2, short ty2, short tx3, short ty3, short tx4, short ty4,
5623                     short clX, short clY,
5624                     int32_t col1, int32_t col2, int32_t col3, int32_t col4)
5625 {
5626  drawPoly3TGEx4_IL(x2,y2,x3,y3,x4,y4,
5627                    tx2,ty2,tx3,ty3,tx4,ty4,
5628                    clX,clY,
5629                    col2,col4,col3);
5630  drawPoly3TGEx4_IL(x1,y1,x2,y2,x4,y4,
5631                    tx1,ty1,tx2,ty2,tx4,ty4,
5632                    clX,clY,
5633                    col1,col2,col3);
5634 }
5635
5636 #ifdef POLYQUAD3GT
5637
5638 static void drawPoly4TGEx4_TRI(short x1, short y1, short x2, short y2, short x3, short y3, short x4, short y4, 
5639                     short tx1, short ty1, short tx2, short ty2, short tx3, short ty3, short tx4, short ty4, 
5640                     short clX, short clY,
5641                     int32_t col1, int32_t col2, int32_t col3, int32_t col4)
5642 {
5643  drawPoly3TGEx4(x2,y2,x3,y3,x4,y4,
5644                 tx2,ty2,tx3,ty3,tx4,ty4,
5645                 clX,clY,
5646                 col2,col4,col3);
5647  drawPoly3TGEx4(x1,y1,x2,y2,x4,y4,
5648                 tx1,ty1,tx2,ty2,tx4,ty4,
5649                 clX,clY,
5650                 col1,col2,col3);
5651 }
5652
5653 #endif
5654                
5655 ////////////////////////////////////////////////////////////////////////
5656
5657 static void drawPoly4TGEx4(short x1, short y1, short x2, short y2, short x3, short y3, short x4, short y4, 
5658                     short tx1, short ty1, short tx2, short ty2, short tx3, short ty3, short tx4, short ty4, 
5659                     short clX, short clY,
5660                     int32_t col1, int32_t col2, int32_t col4, int32_t col3)
5661 {
5662  int32_t num; 
5663  int32_t i,j,xmin,xmax,ymin,ymax;
5664  int32_t cR1,cG1,cB1;
5665  int32_t difR,difB,difG,difR2,difB2,difG2;
5666  int32_t difX, difY, difX2, difY2;
5667  int32_t posX,posY,YAdjust,clutP,XAdjust;
5668  short tC1,tC2;
5669
5670  if(x1>drawW && x2>drawW && x3>drawW && x4>drawW) return;
5671  if(y1>drawH && y2>drawH && y3>drawH && y4>drawH) return;
5672  if(x1<drawX && x2<drawX && x3<drawX && x4<drawX) return;
5673  if(y1<drawY && y2<drawY && y3<drawY && y4<drawY) return;
5674  if(drawY>=drawH) return;
5675  if(drawX>=drawW) return; 
5676
5677  if(!SetupSections_GT4(x1,y1,x2,y2,x3,y3,x4,y4,tx1,ty1,tx2,ty2,tx3,ty3,tx4,ty4,col1,col2,col3,col4)) return;
5678
5679  ymax=Ymax;
5680
5681  for(ymin=Ymin;ymin<drawY;ymin++)
5682   if(NextRow_GT4()) return;
5683
5684  clutP=(clY<<10)+clX;
5685
5686  YAdjust=((GlobalTextAddrY)<<11)+(GlobalTextAddrX<<1);
5687
5688
5689 #ifdef FASTSOLID
5690
5691  if(!bCheckMask && !DrawSemiTrans && !iDither)
5692   {
5693    for (i=ymin;i<=ymax;i++)
5694     {
5695      xmin=(left_x >> 16);
5696      xmax=(right_x >> 16);
5697
5698      if(xmax>=xmin)
5699       {
5700        posX=left_u;
5701        posY=left_v;
5702
5703        num=(xmax-xmin);
5704        if(num==0) num=1;
5705        difX=(right_u-posX)/num;
5706        difY=(right_v-posY)/num;
5707        difX2=difX<<1;
5708        difY2=difY<<1;
5709
5710        cR1=left_R;
5711        cG1=left_G;
5712        cB1=left_B;
5713        difR=(right_R-cR1)/num;
5714        difG=(right_G-cG1)/num;
5715        difB=(right_B-cB1)/num;
5716        difR2=difR<<1;
5717        difG2=difG<<1;
5718        difB2=difB<<1;
5719
5720        if(xmin<drawX)
5721         {j=drawX-xmin;xmin=drawX;posX+=j*difX;posY+=j*difY;cR1+=j*difR;cG1+=j*difG;cB1+=j*difB;}
5722        xmax--;if(drawW<xmax) xmax=drawW;
5723
5724        for(j=xmin;j<xmax;j+=2)
5725         {
5726          XAdjust=(posX>>16);
5727          tC1 = psxVub[((posY>>5)&(int32_t)0xFFFFF800)+YAdjust+(XAdjust>>1)];
5728          tC1=(tC1>>((XAdjust&1)<<2))&0xf;
5729          XAdjust=((posX+difX)>>16);
5730          tC2 = psxVub[(((posY+difY)>>5)&(int32_t)0xFFFFF800)+YAdjust+
5731                        (XAdjust>>1)];
5732          tC2=(tC2>>((XAdjust&1)<<2))&0xf;
5733
5734          GetTextureTransColGX32_S((uint32_t *)&psxVuw[(i<<10)+j],
5735               GETLE16(&psxVuw[clutP+tC1])|
5736               ((int32_t)GETLE16(&psxVuw[clutP+tC2]))<<16,
5737               (cB1>>16)|((cB1+difB)&0xff0000),
5738               (cG1>>16)|((cG1+difG)&0xff0000),
5739               (cR1>>16)|((cR1+difR)&0xff0000));
5740          posX+=difX2;
5741          posY+=difY2;
5742          cR1+=difR2;
5743          cG1+=difG2;
5744          cB1+=difB2;
5745         }
5746        if(j==xmax)
5747         {
5748          XAdjust=(posX>>16);
5749          tC1 = psxVub[((posY>>5)&(int32_t)0xFFFFF800)+YAdjust+
5750                       (XAdjust>>1)];
5751          tC1=(tC1>>((XAdjust&1)<<2))&0xf;
5752
5753          GetTextureTransColGX_S(&psxVuw[(i<<10)+j], 
5754              GETLE16(&psxVuw[clutP+tC1]),
5755              (cB1>>16),(cG1>>16),(cR1>>16));
5756         }
5757       }
5758      if(NextRow_GT4()) return;
5759     }
5760    return;
5761   }
5762
5763 #endif
5764
5765  for (i=ymin;i<=ymax;i++)
5766   {
5767    xmin=(left_x >> 16);
5768    xmax=(right_x >> 16);
5769
5770    if(xmax>=xmin)
5771     {
5772      posX=left_u;
5773      posY=left_v;
5774
5775      num=(xmax-xmin);
5776      if(num==0) num=1;
5777      difX=(right_u-posX)/num;
5778      difY=(right_v-posY)/num;
5779      difX2=difX<<1;
5780      difY2=difY<<1;
5781
5782      cR1=left_R;
5783      cG1=left_G;
5784      cB1=left_B;
5785      difR=(right_R-cR1)/num;
5786      difG=(right_G-cG1)/num;
5787      difB=(right_B-cB1)/num;
5788      difR2=difR<<1;
5789      difG2=difG<<1;
5790      difB2=difB<<1;
5791
5792      if(xmin<drawX)
5793       {j=drawX-xmin;xmin=drawX;posX+=j*difX;posY+=j*difY;cR1+=j*difR;cG1+=j*difG;cB1+=j*difB;}
5794      xmax--;if(drawW<xmax) xmax=drawW;
5795
5796      for(j=xmin;j<=xmax;j++)
5797       {
5798        XAdjust=(posX>>16);
5799        tC1 = psxVub[((posY>>5)&(int32_t)0xFFFFF800)+YAdjust+
5800                     (XAdjust>>1)];
5801        tC1=(tC1>>((XAdjust&1)<<2))&0xf;
5802        if(iDither)
5803         GetTextureTransColGX_Dither(&psxVuw[(i<<10)+j], 
5804            GETLE16(&psxVuw[clutP+tC1]),
5805            (cB1>>16),(cG1>>16),(cR1>>16));
5806        else
5807         GetTextureTransColGX(&psxVuw[(i<<10)+j], 
5808            GETLE16(&psxVuw[clutP+tC1]),
5809            (cB1>>16),(cG1>>16),(cR1>>16));
5810        posX+=difX;
5811        posY+=difY;
5812        cR1+=difR;
5813        cG1+=difG;
5814        cB1+=difB;
5815       }
5816     }
5817    if(NextRow_GT4()) return;
5818   }
5819 }
5820
5821 ////////////////////////////////////////////////////////////////////////
5822
5823 static void drawPoly4TGEx4_TW(short x1, short y1, short x2, short y2, short x3, short y3, short x4, short y4, 
5824                     short tx1, short ty1, short tx2, short ty2, short tx3, short ty3, short tx4, short ty4, 
5825                     short clX, short clY,
5826                     int32_t col1, int32_t col2, int32_t col3, int32_t col4)
5827 {
5828  drawPoly3TGEx4_TW(x2,y2,x3,y3,x4,y4,
5829                    tx2,ty2,tx3,ty3,tx4,ty4,
5830                    clX,clY,
5831                    col2,col4,col3);
5832
5833  drawPoly3TGEx4_TW(x1,y1,x2,y2,x4,y4,
5834                    tx1,ty1,tx2,ty2,tx4,ty4,
5835                    clX,clY,
5836                    col1,col2,col3);
5837 }
5838
5839 ////////////////////////////////////////////////////////////////////////
5840 // POLY 3/4 G-SHADED TEX PAL8
5841 ////////////////////////////////////////////////////////////////////////
5842
5843 static void drawPoly3TGEx8(short x1, short y1, short x2, short y2, short x3, short y3, short tx1, short ty1, short tx2, short ty2, short tx3, short ty3, short clX, short clY,int32_t col1, int32_t col2, int32_t col3)
5844 {
5845  int i,j,xmin,xmax,ymin,ymax;
5846  int32_t cR1,cG1,cB1;
5847  int32_t difR,difB,difG,difR2,difB2,difG2;
5848  int32_t difX, difY,difX2, difY2;
5849  int32_t posX,posY,YAdjust,clutP;
5850  short tC1,tC2;
5851
5852  if(x1>drawW && x2>drawW && x3>drawW) return;
5853  if(y1>drawH && y2>drawH && y3>drawH) return;
5854  if(x1<drawX && x2<drawX && x3<drawX) return;
5855  if(y1<drawY && y2<drawY && y3<drawY) return;
5856  if(drawY>=drawH) return;
5857  if(drawX>=drawW) return; 
5858
5859  if(!SetupSections_GT(x1,y1,x2,y2,x3,y3,tx1,ty1,tx2,ty2,tx3,ty3,col1,col2,col3)) return;
5860
5861  ymax=Ymax;
5862
5863  for(ymin=Ymin;ymin<drawY;ymin++)
5864   if(NextRow_GT()) return;
5865
5866  clutP=(clY<<10)+clX;
5867
5868  YAdjust=((GlobalTextAddrY)<<11)+(GlobalTextAddrX<<1);
5869
5870  difR=delta_right_R;
5871  difG=delta_right_G;
5872  difB=delta_right_B;
5873  difR2=difR<<1;
5874  difG2=difG<<1;
5875  difB2=difB<<1;
5876  difX=delta_right_u;difX2=difX<<1;
5877  difY=delta_right_v;difY2=difY<<1;
5878
5879 #ifdef FASTSOLID
5880
5881  if(!bCheckMask && !DrawSemiTrans && !iDither)
5882   {
5883    for (i=ymin;i<=ymax;i++)
5884     {
5885      xmin=(left_x >> 16);
5886      xmax=(right_x >> 16)-1; // !!!!!!!!!!!!!
5887      if(drawW<xmax) xmax=drawW;
5888
5889      if(xmax>=xmin)
5890       {
5891        posX=left_u;
5892        posY=left_v;
5893        cR1=left_R;
5894        cG1=left_G;
5895        cB1=left_B;
5896
5897        if(xmin<drawX)
5898         {j=drawX-xmin;xmin=drawX;posX+=j*difX;posY+=j*difY;cR1+=j*difR;cG1+=j*difG;cB1+=j*difB;}
5899
5900        for(j=xmin;j<xmax;j+=2)
5901         {
5902          tC1 = psxVub[((posY>>5)&(int32_t)0xFFFFF800)+YAdjust+((posX>>16))];
5903          tC2 = psxVub[(((posY+difY)>>5)&(int32_t)0xFFFFF800)+YAdjust+
5904                       (((posX+difX)>>16))];
5905          GetTextureTransColGX32_S((uint32_t *)&psxVuw[(i<<10)+j],
5906               GETLE16(&psxVuw[clutP+tC1])|
5907               ((int32_t)GETLE16(&psxVuw[clutP+tC2]))<<16,
5908               (cB1>>16)|((cB1+difB)&0xff0000),
5909               (cG1>>16)|((cG1+difG)&0xff0000),
5910               (cR1>>16)|((cR1+difR)&0xff0000));
5911          posX+=difX2;
5912          posY+=difY2;
5913          cR1+=difR2;
5914          cG1+=difG2;
5915          cB1+=difB2;
5916         }
5917        if(j==xmax)
5918         {
5919          tC1 = psxVub[((posY>>5)&(int32_t)0xFFFFF800)+YAdjust+((posX>>16))];
5920          GetTextureTransColGX_S(&psxVuw[(i<<10)+j], 
5921               GETLE16(&psxVuw[clutP+tC1]),
5922               (cB1>>16),(cG1>>16),(cR1>>16));
5923         }
5924       }
5925      if(NextRow_GT()) 
5926       {
5927        return;
5928       }
5929     }
5930    return;
5931   }
5932
5933 #endif
5934
5935  for (i=ymin;i<=ymax;i++)
5936   {
5937    xmin=(left_x >> 16);
5938    xmax=(right_x >> 16)-1; //!!!!!!!!!!!!!!!!!!!!!!!
5939    if(drawW<xmax) xmax=drawW;
5940
5941    if(xmax>=xmin)
5942     {
5943      posX=left_u;
5944      posY=left_v;
5945      cR1=left_R;
5946      cG1=left_G;
5947      cB1=left_B;
5948
5949      if(xmin<drawX)
5950       {j=drawX-xmin;xmin=drawX;posX+=j*difX;posY+=j*difY;cR1+=j*difR;cG1+=j*difG;cB1+=j*difB;}
5951
5952      for(j=xmin;j<=xmax;j++)
5953       {
5954        tC1 = psxVub[((posY>>5)&(int32_t)0xFFFFF800)+YAdjust+((posX>>16))];
5955        if(iDither)
5956         GetTextureTransColGX_Dither(&psxVuw[(i<<10)+j], 
5957             GETLE16(&psxVuw[clutP+tC1]),
5958             (cB1>>16),(cG1>>16),(cR1>>16));
5959        else
5960         GetTextureTransColGX(&psxVuw[(i<<10)+j], 
5961             GETLE16(&psxVuw[clutP+tC1]),
5962             (cB1>>16),(cG1>>16),(cR1>>16));
5963        posX+=difX;
5964        posY+=difY;
5965        cR1+=difR;
5966        cG1+=difG;
5967        cB1+=difB;
5968       }
5969     }
5970    if(NextRow_GT()) 
5971     {
5972      return;
5973     }
5974   }
5975 }
5976
5977 ////////////////////////////////////////////////////////////////////////
5978
5979 static void drawPoly3TGEx8_IL(short x1, short y1, short x2, short y2, short x3, short y3, short tx1, short ty1, short tx2, short ty2, short tx3, short ty3, short clX, short clY,int32_t col1, int32_t col2, int32_t col3)
5980 {
5981  int i,j,xmin,xmax,ymin,ymax,n_xi,n_yi,TXV,TXU;
5982  int32_t cR1,cG1,cB1;
5983  int32_t difR,difB,difG,difR2,difB2,difG2;
5984  int32_t difX, difY,difX2, difY2;
5985  int32_t posX,posY,YAdjust,clutP;
5986  short tC1,tC2;
5987
5988  if(x1>drawW && x2>drawW && x3>drawW) return;
5989  if(y1>drawH && y2>drawH && y3>drawH) return;
5990  if(x1<drawX && x2<drawX && x3<drawX) return;
5991  if(y1<drawY && y2<drawY && y3<drawY) return;
5992  if(drawY>=drawH) return;
5993  if(drawX>=drawW) return; 
5994
5995  if(!SetupSections_GT(x1,y1,x2,y2,x3,y3,tx1,ty1,tx2,ty2,tx3,ty3,col1,col2,col3)) return;
5996
5997  ymax=Ymax;
5998
5999  for(ymin=Ymin;ymin<drawY;ymin++)
6000   if(NextRow_GT()) return;
6001
6002  clutP=(clY<<10)+clX;
6003
6004  YAdjust=(GlobalTextAddrY<<10)+GlobalTextAddrX;
6005
6006  difR=delta_right_R;
6007  difG=delta_right_G;
6008  difB=delta_right_B;
6009  difR2=difR<<1;
6010  difG2=difG<<1;
6011  difB2=difB<<1;
6012  difX=delta_right_u;difX2=difX<<1;
6013  difY=delta_right_v;difY2=difY<<1;
6014
6015 #ifdef FASTSOLID
6016
6017  if(!bCheckMask && !DrawSemiTrans && !iDither)
6018   {
6019    for (i=ymin;i<=ymax;i++)
6020     {
6021      xmin=(left_x >> 16);
6022      xmax=(right_x >> 16)-1; // !!!!!!!!!!!!!
6023      if(drawW<xmax) xmax=drawW;
6024
6025      if(xmax>=xmin)
6026       {
6027        posX=left_u;
6028        posY=left_v;
6029        cR1=left_R;
6030        cG1=left_G;
6031        cB1=left_B;
6032
6033        if(xmin<drawX)
6034         {j=drawX-xmin;xmin=drawX;posX+=j*difX;posY+=j*difY;cR1+=j*difR;cG1+=j*difG;cB1+=j*difB;}
6035
6036        for(j=xmin;j<xmax;j+=2)
6037         {
6038          TXU=posX>>16;
6039          TXV=posY>>16;
6040          n_xi = ( ( TXU >> 1 ) & ~0x78 ) + ( ( TXU << 2 ) & 0x40 ) + ( ( TXV << 3 ) & 0x38 );
6041          n_yi = ( TXV & ~0x7 ) + ( ( TXU >> 5 ) & 0x7 );
6042
6043          tC1= (GETLE16(&psxVuw[(n_yi<<10)+YAdjust+n_xi]) >> ((TXU & 0x01)<<3)) & 0xff;
6044
6045          TXU=(posX+difX)>>16;
6046          TXV=(posY+difY)>>16;
6047          n_xi = ( ( TXU >> 1 ) & ~0x78 ) + ( ( TXU << 2 ) & 0x40 ) + ( ( TXV << 3 ) & 0x38 );
6048          n_yi = ( TXV & ~0x7 ) + ( ( TXU >> 5 ) & 0x7 );
6049
6050          tC2= (GETLE16(&psxVuw[(n_yi<<10)+YAdjust+n_xi]) >> ((TXU & 0x01)<<3)) & 0xff;
6051
6052          GetTextureTransColGX32_S((uint32_t *)&psxVuw[(i<<10)+j],
6053               GETLE16(&psxVuw[clutP+tC1])|
6054               ((int32_t)GETLE16(&psxVuw[clutP+tC2]))<<16,
6055               (cB1>>16)|((cB1+difB)&0xff0000),
6056               (cG1>>16)|((cG1+difG)&0xff0000),
6057               (cR1>>16)|((cR1+difR)&0xff0000));
6058          posX+=difX2;
6059          posY+=difY2;
6060          cR1+=difR2;
6061          cG1+=difG2;
6062          cB1+=difB2;
6063         }
6064        if(j==xmax)
6065         {
6066          TXU=posX>>16;
6067          TXV=posY>>16;
6068          n_xi = ( ( TXU >> 1 ) & ~0x78 ) + ( ( TXU << 2 ) & 0x40 ) + ( ( TXV << 3 ) & 0x38 );
6069          n_yi = ( TXV & ~0x7 ) + ( ( TXU >> 5 ) & 0x7 );
6070
6071          tC1= (GETLE16(&psxVuw[(n_yi<<10)+YAdjust+n_xi]) >> ((TXU & 0x01)<<3)) & 0xff;
6072
6073          GetTextureTransColGX_S(&psxVuw[(i<<10)+j], 
6074               GETLE16(&psxVuw[clutP+tC1]),
6075               (cB1>>16),(cG1>>16),(cR1>>16));
6076         }
6077       }
6078      if(NextRow_GT()) 
6079       {
6080        return;
6081       }
6082     }
6083    return;
6084   }
6085
6086 #endif
6087
6088  for (i=ymin;i<=ymax;i++)
6089   {
6090    xmin=(left_x >> 16);
6091    xmax=(right_x >> 16)-1; //!!!!!!!!!!!!!!!!!!!!!!!
6092    if(drawW<xmax) xmax=drawW;
6093
6094    if(xmax>=xmin)
6095     {
6096      posX=left_u;
6097      posY=left_v;
6098      cR1=left_R;
6099      cG1=left_G;
6100      cB1=left_B;
6101
6102      if(xmin<drawX)
6103       {j=drawX-xmin;xmin=drawX;posX+=j*difX;posY+=j*difY;cR1+=j*difR;cG1+=j*difG;cB1+=j*difB;}
6104
6105      for(j=xmin;j<=xmax;j++)
6106       {
6107        TXU=posX>>16;
6108        TXV=posY>>16;
6109        n_xi = ( ( TXU >> 1 ) & ~0x78 ) + ( ( TXU << 2 ) & 0x40 ) + ( ( TXV << 3 ) & 0x38 );
6110        n_yi = ( TXV & ~0x7 ) + ( ( TXU >> 5 ) & 0x7 );
6111
6112        tC1= (GETLE16(&psxVuw[(n_yi<<10)+YAdjust+n_xi]) >> ((TXU & 0x01)<<3)) & 0xff;
6113
6114        if(iDither)
6115         GetTextureTransColGX_Dither(&psxVuw[(i<<10)+j], 
6116             GETLE16(&psxVuw[clutP+tC1]),
6117             (cB1>>16),(cG1>>16),(cR1>>16));
6118        else
6119         GetTextureTransColGX(&psxVuw[(i<<10)+j], 
6120             GETLE16(&psxVuw[clutP+tC1]),
6121             (cB1>>16),(cG1>>16),(cR1>>16));
6122        posX+=difX;
6123        posY+=difY;
6124        cR1+=difR;
6125        cG1+=difG;
6126        cB1+=difB;
6127       }
6128     }
6129    if(NextRow_GT()) 
6130     {
6131      return;
6132     }
6133   }
6134 }
6135
6136 ////////////////////////////////////////////////////////////////////////
6137
6138 static void drawPoly3TGEx8_TW(short x1, short y1, short x2, short y2, short x3, short y3, short tx1, short ty1, short tx2, short ty2, short tx3, short ty3, short clX, short clY,int32_t col1, int32_t col2, int32_t col3)
6139 {
6140  int i,j,xmin,xmax,ymin,ymax;
6141  int32_t cR1,cG1,cB1;
6142  int32_t difR,difB,difG,difR2,difB2,difG2;
6143  int32_t difX, difY,difX2, difY2;
6144  int32_t posX,posY,YAdjust,clutP;
6145  short tC1,tC2;
6146
6147  if(x1>drawW && x2>drawW && x3>drawW) return;
6148  if(y1>drawH && y2>drawH && y3>drawH) return;
6149  if(x1<drawX && x2<drawX && x3<drawX) return;
6150  if(y1<drawY && y2<drawY && y3<drawY) return;
6151  if(drawY>=drawH) return;
6152  if(drawX>=drawW) return; 
6153
6154  if(!SetupSections_GT(x1,y1,x2,y2,x3,y3,tx1,ty1,tx2,ty2,tx3,ty3,col1,col2,col3)) return;
6155
6156  ymax=Ymax;
6157
6158  for(ymin=Ymin;ymin<drawY;ymin++)
6159   if(NextRow_GT()) return;
6160
6161  clutP=(clY<<10)+clX;
6162
6163  YAdjust=((GlobalTextAddrY)<<11)+(GlobalTextAddrX<<1);
6164  YAdjust+=(TWin.Position.y0<<11)+(TWin.Position.x0);
6165
6166  difR=delta_right_R;
6167  difG=delta_right_G;
6168  difB=delta_right_B;
6169  difR2=difR<<1;
6170  difG2=difG<<1;
6171  difB2=difB<<1;
6172  difX=delta_right_u;difX2=difX<<1;
6173  difY=delta_right_v;difY2=difY<<1;
6174
6175 #ifdef FASTSOLID
6176
6177  if(!bCheckMask && !DrawSemiTrans && !iDither)
6178   {
6179    for (i=ymin;i<=ymax;i++)
6180     {
6181      xmin=(left_x >> 16);
6182      xmax=(right_x >> 16)-1; // !!!!!!!!!!!!!
6183      if(drawW<xmax) xmax=drawW;
6184
6185      if(xmax>=xmin)
6186       {
6187        posX=left_u;
6188        posY=left_v;
6189        cR1=left_R;
6190        cG1=left_G;
6191        cB1=left_B;
6192
6193        if(xmin<drawX)
6194         {j=drawX-xmin;xmin=drawX;posX+=j*difX;posY+=j*difY;cR1+=j*difR;cG1+=j*difG;cB1+=j*difB;}
6195
6196        for(j=xmin;j<xmax;j+=2)
6197         {
6198          tC1 = psxVub[(((posY>>16)&TWin.ymask)<<11)+
6199                       YAdjust+((posX>>16)&TWin.xmask)];
6200          tC2 = psxVub[((((posY+difY)>>16)&TWin.ymask)<<11)+
6201                       YAdjust+(((posX+difX)>>16)&TWin.xmask)];
6202                       
6203          GetTextureTransColGX32_S((uint32_t *)&psxVuw[(i<<10)+j],
6204               GETLE16(&psxVuw[clutP+tC1])|
6205               ((int32_t)GETLE16(&psxVuw[clutP+tC2]))<<16,
6206               (cB1>>16)|((cB1+difB)&0xff0000),
6207               (cG1>>16)|((cG1+difG)&0xff0000),
6208               (cR1>>16)|((cR1+difR)&0xff0000));
6209          posX+=difX2;
6210          posY+=difY2;
6211          cR1+=difR2;
6212          cG1+=difG2;
6213          cB1+=difB2;
6214         }
6215        if(j==xmax)
6216         {
6217          tC1 = psxVub[(((posY>>16)&TWin.ymask)<<11)+
6218                       YAdjust+((posX>>16)&TWin.xmask)];
6219          GetTextureTransColGX_S(&psxVuw[(i<<10)+j], 
6220               GETLE16(&psxVuw[clutP+tC1]),
6221               (cB1>>16),(cG1>>16),(cR1>>16));
6222         }
6223       }
6224      if(NextRow_GT()) 
6225       {
6226        return;
6227       }
6228     }
6229    return;
6230   }
6231
6232 #endif
6233
6234  for (i=ymin;i<=ymax;i++)
6235   {
6236    xmin=(left_x >> 16);
6237    xmax=(right_x >> 16)-1; //!!!!!!!!!!!!!!!!!!!!!!!
6238    if(drawW<xmax) xmax=drawW;
6239
6240    if(xmax>=xmin)
6241     {
6242      posX=left_u;
6243      posY=left_v;
6244      cR1=left_R;
6245      cG1=left_G;
6246      cB1=left_B;
6247
6248      if(xmin<drawX)
6249       {j=drawX-xmin;xmin=drawX;posX+=j*difX;posY+=j*difY;cR1+=j*difR;cG1+=j*difG;cB1+=j*difB;}
6250
6251      for(j=xmin;j<=xmax;j++)
6252       {
6253        tC1 = psxVub[(((posY>>16)&TWin.ymask)<<11)+
6254                     YAdjust+((posX>>16)&TWin.xmask)];
6255        if(iDither)
6256         GetTextureTransColGX_Dither(&psxVuw[(i<<10)+j], 
6257             GETLE16(&psxVuw[clutP+tC1]),
6258             (cB1>>16),(cG1>>16),(cR1>>16));
6259        else
6260         GetTextureTransColGX(&psxVuw[(i<<10)+j], 
6261             GETLE16(&psxVuw[clutP+tC1]),
6262             (cB1>>16),(cG1>>16),(cR1>>16));
6263        posX+=difX;
6264        posY+=difY;
6265        cR1+=difR;
6266        cG1+=difG;
6267        cB1+=difB;
6268       }
6269     }
6270    if(NextRow_GT()) 
6271     {
6272      return;
6273     }
6274   }
6275 }
6276
6277 ////////////////////////////////////////////////////////////////////////
6278
6279 // note: two g-shaded tris: small texture distortions can happen
6280
6281 static void drawPoly4TGEx8_TRI_IL(short x1, short y1, short x2, short y2, short x3, short y3, short x4, short y4, 
6282                            short tx1, short ty1, short tx2, short ty2, short tx3, short ty3, short tx4, short ty4, 
6283                            short clX, short clY,
6284                            int32_t col1, int32_t col2, int32_t col3, int32_t col4)
6285 {
6286  drawPoly3TGEx8_IL(x2,y2,x3,y3,x4,y4,
6287                    tx2,ty2,tx3,ty3,tx4,ty4,
6288                    clX,clY,
6289                    col2,col4,col3);
6290  drawPoly3TGEx8_IL(x1,y1,x2,y2,x4,y4,
6291                    tx1,ty1,tx2,ty2,tx4,ty4,
6292                    clX,clY,
6293                    col1,col2,col3);
6294 }
6295
6296 #ifdef POLYQUAD3GT
6297                       
6298 static void drawPoly4TGEx8_TRI(short x1, short y1, short x2, short y2, short x3, short y3, short x4, short y4, 
6299                    short tx1, short ty1, short tx2, short ty2, short tx3, short ty3, short tx4, short ty4, 
6300                    short clX, short clY,
6301                    int32_t col1, int32_t col2, int32_t col3, int32_t col4)
6302 {
6303  drawPoly3TGEx8(x2,y2,x3,y3,x4,y4,
6304                 tx2,ty2,tx3,ty3,tx4,ty4,
6305                 clX,clY,
6306                 col2,col4,col3);
6307  drawPoly3TGEx8(x1,y1,x2,y2,x4,y4,
6308                 tx1,ty1,tx2,ty2,tx4,ty4,
6309                 clX,clY,
6310                 col1,col2,col3);
6311 }
6312
6313 #endif
6314
6315 static void drawPoly4TGEx8(short x1, short y1, short x2, short y2, short x3, short y3, short x4, short y4, 
6316                    short tx1, short ty1, short tx2, short ty2, short tx3, short ty3, short tx4, short ty4, 
6317                    short clX, short clY,
6318                    int32_t col1, int32_t col2, int32_t col4, int32_t col3)
6319 {
6320  int32_t num; 
6321  int32_t i,j,xmin,xmax,ymin,ymax;
6322  int32_t cR1,cG1,cB1;
6323  int32_t difR,difB,difG,difR2,difB2,difG2;
6324  int32_t difX, difY, difX2, difY2;
6325  int32_t posX,posY,YAdjust,clutP;
6326  short tC1,tC2;
6327
6328  if(x1>drawW && x2>drawW && x3>drawW && x4>drawW) return;
6329  if(y1>drawH && y2>drawH && y3>drawH && y4>drawH) return;
6330  if(x1<drawX && x2<drawX && x3<drawX && x4<drawX) return;
6331  if(y1<drawY && y2<drawY && y3<drawY && y4<drawY) return;
6332  if(drawY>=drawH) return;
6333  if(drawX>=drawW) return; 
6334
6335  if(!SetupSections_GT4(x1,y1,x2,y2,x3,y3,x4,y4,tx1,ty1,tx2,ty2,tx3,ty3,tx4,ty4,col1,col2,col3,col4)) return;
6336
6337  ymax=Ymax;
6338
6339  for(ymin=Ymin;ymin<drawY;ymin++)
6340   if(NextRow_GT4()) return;
6341
6342  clutP=(clY<<10)+clX;
6343
6344  YAdjust=((GlobalTextAddrY)<<11)+(GlobalTextAddrX<<1);
6345
6346 #ifdef FASTSOLID
6347
6348  if(!bCheckMask && !DrawSemiTrans && !iDither)
6349   {
6350    for (i=ymin;i<=ymax;i++)
6351     {
6352      xmin=(left_x >> 16);
6353      xmax=(right_x >> 16);
6354
6355      if(xmax>=xmin)
6356       {
6357        posX=left_u;
6358        posY=left_v;
6359
6360        num=(xmax-xmin);
6361        if(num==0) num=1;
6362        difX=(right_u-posX)/num;
6363        difY=(right_v-posY)/num;
6364        difX2=difX<<1;
6365        difY2=difY<<1;
6366
6367        cR1=left_R;
6368        cG1=left_G;
6369        cB1=left_B;
6370        difR=(right_R-cR1)/num;
6371        difG=(right_G-cG1)/num;
6372        difB=(right_B-cB1)/num;
6373        difR2=difR<<1;
6374        difG2=difG<<1;
6375        difB2=difB<<1;
6376
6377        if(xmin<drawX)
6378         {j=drawX-xmin;xmin=drawX;posX+=j*difX;posY+=j*difY;cR1+=j*difR;cG1+=j*difG;cB1+=j*difB;}
6379        xmax--;if(drawW<xmax) xmax=drawW;
6380
6381        for(j=xmin;j<xmax;j+=2)
6382         {
6383          tC1 = psxVub[((posY>>5)&(int32_t)0xFFFFF800)+YAdjust+(posX>>16)];
6384          tC2 = psxVub[(((posY+difY)>>5)&(int32_t)0xFFFFF800)+YAdjust+
6385                      ((posX+difX)>>16)];
6386
6387          GetTextureTransColGX32_S((uint32_t *)&psxVuw[(i<<10)+j],
6388               GETLE16(&psxVuw[clutP+tC1])|
6389               ((int32_t)GETLE16(&psxVuw[clutP+tC2]))<<16,
6390               (cB1>>16)|((cB1+difB)&0xff0000),
6391               (cG1>>16)|((cG1+difG)&0xff0000),
6392               (cR1>>16)|((cR1+difR)&0xff0000));
6393          posX+=difX2;
6394          posY+=difY2;
6395          cR1+=difR2;
6396          cG1+=difG2;
6397          cB1+=difB2;
6398         }
6399        if(j==xmax)
6400         {
6401          tC1 = psxVub[((posY>>5)&(int32_t)0xFFFFF800)+YAdjust+(posX>>16)];
6402          GetTextureTransColGX_S(&psxVuw[(i<<10)+j], 
6403               GETLE16(&psxVuw[clutP+tC1]),
6404              (cB1>>16),(cG1>>16),(cR1>>16));
6405         }
6406       }
6407      if(NextRow_GT4()) return;
6408     }
6409    return;
6410   }
6411
6412 #endif
6413
6414  for (i=ymin;i<=ymax;i++)
6415   {
6416    xmin=(left_x >> 16);
6417    xmax=(right_x >> 16);
6418
6419    if(xmax>=xmin)
6420     {
6421      posX=left_u;
6422      posY=left_v;
6423
6424      num=(xmax-xmin);
6425      if(num==0) num=1;
6426      difX=(right_u-posX)/num;
6427      difY=(right_v-posY)/num;
6428      difX2=difX<<1;
6429      difY2=difY<<1;
6430
6431      cR1=left_R;
6432      cG1=left_G;
6433      cB1=left_B;
6434      difR=(right_R-cR1)/num;
6435      difG=(right_G-cG1)/num;
6436      difB=(right_B-cB1)/num;
6437      difR2=difR<<1;
6438      difG2=difG<<1;
6439      difB2=difB<<1;
6440
6441      if(xmin<drawX)
6442       {j=drawX-xmin;xmin=drawX;posX+=j*difX;posY+=j*difY;cR1+=j*difR;cG1+=j*difG;cB1+=j*difB;}
6443      xmax--;if(drawW<xmax) xmax=drawW;
6444
6445      for(j=xmin;j<=xmax;j++)
6446       {
6447        tC1 = psxVub[((posY>>5)&(int32_t)0xFFFFF800)+YAdjust+(posX>>16)];
6448        if(iDither)
6449         GetTextureTransColGX_Dither(&psxVuw[(i<<10)+j], 
6450             GETLE16(&psxVuw[clutP+tC1]),
6451            (cB1>>16),(cG1>>16),(cR1>>16));
6452        else
6453         GetTextureTransColGX(&psxVuw[(i<<10)+j], 
6454             GETLE16(&psxVuw[clutP+tC1]),
6455            (cB1>>16),(cG1>>16),(cR1>>16));
6456        posX+=difX;
6457        posY+=difY;
6458        cR1+=difR;
6459        cG1+=difG;
6460        cB1+=difB;
6461       }
6462     }
6463    if(NextRow_GT4()) return;
6464   }
6465 }
6466
6467 ////////////////////////////////////////////////////////////////////////
6468
6469 static void drawPoly4TGEx8_TW(short x1, short y1, short x2, short y2, short x3, short y3, short x4, short y4, 
6470                    short tx1, short ty1, short tx2, short ty2, short tx3, short ty3, short tx4, short ty4, 
6471                    short clX, short clY,
6472                    int32_t col1, int32_t col2, int32_t col3, int32_t col4)
6473 {
6474  drawPoly3TGEx8_TW(x2,y2,x3,y3,x4,y4,
6475                 tx2,ty2,tx3,ty3,tx4,ty4,
6476                 clX,clY,
6477                 col2,col4,col3);
6478  drawPoly3TGEx8_TW(x1,y1,x2,y2,x4,y4,
6479                 tx1,ty1,tx2,ty2,tx4,ty4,
6480                 clX,clY,
6481                 col1,col2,col3);
6482 }
6483
6484 ////////////////////////////////////////////////////////////////////////
6485 // POLY 3 G-SHADED TEX 15 BIT
6486 ////////////////////////////////////////////////////////////////////////
6487
6488 static void drawPoly3TGD(short x1, short y1, short x2, short y2, short x3, short y3, short tx1, short ty1, short tx2, short ty2, short tx3, short ty3,int32_t col1, int32_t col2, int32_t col3)
6489 {
6490  int i,j,xmin,xmax,ymin,ymax;
6491  int32_t cR1,cG1,cB1;
6492  int32_t difR,difB,difG,difR2,difB2,difG2;
6493  int32_t difX, difY,difX2, difY2;
6494  int32_t posX,posY;
6495
6496  if(x1>drawW && x2>drawW && x3>drawW) return;
6497  if(y1>drawH && y2>drawH && y3>drawH) return;
6498  if(x1<drawX && x2<drawX && x3<drawX) return;
6499  if(y1<drawY && y2<drawY && y3<drawY) return;
6500  if(drawY>=drawH) return;
6501  if(drawX>=drawW) return; 
6502
6503  if(!SetupSections_GT(x1,y1,x2,y2,x3,y3,tx1,ty1,tx2,ty2,tx3,ty3,col1,col2,col3)) return;
6504
6505  ymax=Ymax;
6506
6507  for(ymin=Ymin;ymin<drawY;ymin++)
6508   if(NextRow_GT()) return;
6509
6510  difR=delta_right_R;
6511  difG=delta_right_G;
6512  difB=delta_right_B;
6513  difR2=difR<<1;
6514  difG2=difG<<1;
6515  difB2=difB<<1;
6516  difX=delta_right_u;difX2=difX<<1;
6517  difY=delta_right_v;difY2=difY<<1;
6518
6519 #ifdef FASTSOLID
6520
6521  if(!bCheckMask && !DrawSemiTrans && !iDither)
6522   {       
6523    for (i=ymin;i<=ymax;i++)
6524     {
6525      xmin=(left_x >> 16);
6526      xmax=(right_x >> 16)-1; //!!!!!!!!!!!!!!!!!!!!
6527      if(drawW<xmax) xmax=drawW;
6528
6529      if(xmax>=xmin)
6530       {
6531        posX=left_u;
6532        posY=left_v;
6533        cR1=left_R;
6534        cG1=left_G;
6535        cB1=left_B;
6536
6537        if(xmin<drawX)
6538         {j=drawX-xmin;xmin=drawX;posX+=j*difX;posY+=j*difY;cR1+=j*difR;cG1+=j*difG;cB1+=j*difB;}
6539
6540        for(j=xmin;j<xmax;j+=2)
6541         {
6542          GetTextureTransColGX32_S((uint32_t *)&psxVuw[(i<<10)+j],
6543               (((int32_t)GETLE16(&psxVuw[((((posY+difY)>>16)+GlobalTextAddrY)<<10)+((posX+difX)>>16)+GlobalTextAddrX]))<<16)|
6544               GETLE16(&psxVuw[(((posY>>16)+GlobalTextAddrY)<<10)+((posX)>>16)+GlobalTextAddrX]),
6545               (cB1>>16)|((cB1+difB)&0xff0000),
6546               (cG1>>16)|((cG1+difG)&0xff0000),
6547               (cR1>>16)|((cR1+difR)&0xff0000));
6548          posX+=difX2;
6549          posY+=difY2;
6550          cR1+=difR2;
6551          cG1+=difG2;
6552          cB1+=difB2;
6553         }
6554        if(j==xmax)
6555         GetTextureTransColGX_S(&psxVuw[(i<<10)+j],
6556             GETLE16(&psxVuw[(((posY>>16)+GlobalTextAddrY)<<10)+(posX>>16)+GlobalTextAddrX]),
6557             (cB1>>16),(cG1>>16),(cR1>>16));
6558       }
6559      if(NextRow_GT()) 
6560       {
6561        return;
6562       }
6563     }
6564    return;
6565   }
6566
6567 #endif
6568
6569  for (i=ymin;i<=ymax;i++)
6570   {
6571    xmin=(left_x >> 16);
6572    xmax=(right_x >> 16)-1; //!!!!!!!!!!!!!!!!!!
6573    if(drawW<xmax) xmax=drawW;
6574
6575    if(xmax>=xmin)
6576     {
6577      posX=left_u;
6578      posY=left_v;
6579      cR1=left_R;
6580      cG1=left_G;
6581      cB1=left_B;
6582
6583      if(xmin<drawX)
6584       {j=drawX-xmin;xmin=drawX;posX+=j*difX;posY+=j*difY;cR1+=j*difR;cG1+=j*difG;cB1+=j*difB;}
6585
6586      for(j=xmin;j<=xmax;j++)
6587       {
6588        if(iDither)
6589         GetTextureTransColGX_Dither(&psxVuw[(i<<10)+j],
6590           GETLE16(&psxVuw[(((posY>>16)+GlobalTextAddrY)<<10)+(posX>>16)+GlobalTextAddrX]),
6591           (cB1>>16),(cG1>>16),(cR1>>16));
6592        else
6593         GetTextureTransColGX(&psxVuw[(i<<10)+j],
6594           GETLE16(&psxVuw[(((posY>>16)+GlobalTextAddrY)<<10)+(posX>>16)+GlobalTextAddrX]),
6595           (cB1>>16),(cG1>>16),(cR1>>16));
6596        posX+=difX;
6597        posY+=difY;
6598        cR1+=difR;
6599        cG1+=difG;
6600        cB1+=difB;
6601       }
6602     }
6603    if(NextRow_GT()) 
6604     {
6605      return;
6606     }
6607   }
6608 }
6609
6610 ////////////////////////////////////////////////////////////////////////
6611
6612 static void drawPoly3TGD_TW(short x1, short y1, short x2, short y2, short x3, short y3, short tx1, short ty1, short tx2, short ty2, short tx3, short ty3,int32_t col1, int32_t col2, int32_t col3)
6613 {
6614  int i,j,xmin,xmax,ymin,ymax;
6615  int32_t cR1,cG1,cB1;
6616  int32_t difR,difB,difG,difR2,difB2,difG2;
6617  int32_t difX, difY,difX2, difY2;
6618  int32_t posX,posY;
6619
6620  if(x1>drawW && x2>drawW && x3>drawW) return;
6621  if(y1>drawH && y2>drawH && y3>drawH) return;
6622  if(x1<drawX && x2<drawX && x3<drawX) return;
6623  if(y1<drawY && y2<drawY && y3<drawY) return;
6624  if(drawY>=drawH) return;
6625  if(drawX>=drawW) return; 
6626
6627  if(!SetupSections_GT(x1,y1,x2,y2,x3,y3,tx1,ty1,tx2,ty2,tx3,ty3,col1,col2,col3)) return;
6628
6629  ymax=Ymax;
6630
6631  for(ymin=Ymin;ymin<drawY;ymin++)
6632   if(NextRow_GT()) return;
6633
6634  difR=delta_right_R;
6635  difG=delta_right_G;
6636  difB=delta_right_B;
6637  difR2=difR<<1;
6638  difG2=difG<<1;
6639  difB2=difB<<1;
6640  difX=delta_right_u;difX2=difX<<1;
6641  difY=delta_right_v;difY2=difY<<1;
6642
6643 #ifdef FASTSOLID
6644
6645  if(!bCheckMask && !DrawSemiTrans && !iDither)
6646   {       
6647    for (i=ymin;i<=ymax;i++)
6648     {
6649      xmin=(left_x >> 16);
6650      xmax=(right_x >> 16)-1; //!!!!!!!!!!!!!!!!!!!!
6651      if(drawW<xmax) xmax=drawW;
6652
6653      if(xmax>=xmin)
6654       {
6655        posX=left_u;
6656        posY=left_v;
6657        cR1=left_R;
6658        cG1=left_G;
6659        cB1=left_B;
6660
6661        if(xmin<drawX)
6662         {j=drawX-xmin;xmin=drawX;posX+=j*difX;posY+=j*difY;cR1+=j*difR;cG1+=j*difG;cB1+=j*difB;}
6663
6664        for(j=xmin;j<xmax;j+=2)
6665         {
6666          GetTextureTransColGX32_S((uint32_t *)&psxVuw[(i<<10)+j],
6667               (((int32_t)GETLE16(&psxVuw[(((((posY+difY)>>16)&TWin.ymask)+GlobalTextAddrY+TWin.Position.y0)<<10)+
6668                              (((posX+difX)>>16)&TWin.xmask)+GlobalTextAddrX+TWin.Position.x0]))<<16)|
6669               GETLE16(&psxVuw[((((posY>>16)&TWin.ymask)+GlobalTextAddrY+TWin.Position.y0)<<10)+
6670                      (((posX)>>16)&TWin.xmask)+GlobalTextAddrX+TWin.Position.x0]),
6671               (cB1>>16)|((cB1+difB)&0xff0000),
6672               (cG1>>16)|((cG1+difG)&0xff0000),
6673               (cR1>>16)|((cR1+difR)&0xff0000));
6674          posX+=difX2;
6675          posY+=difY2;
6676          cR1+=difR2;
6677          cG1+=difG2;
6678          cB1+=difB2;
6679         }
6680        if(j==xmax)
6681         GetTextureTransColGX_S(&psxVuw[(i<<10)+j],
6682             GETLE16(&psxVuw[((((posY>>16)&TWin.ymask)+GlobalTextAddrY+TWin.Position.y0)<<10)+
6683                    ((posX>>16)&TWin.xmask)+GlobalTextAddrX+TWin.Position.x0]),
6684             (cB1>>16),(cG1>>16),(cR1>>16));
6685       }
6686      if(NextRow_GT()) 
6687       {
6688        return;
6689       }
6690     }
6691    return;
6692   }
6693
6694 #endif
6695
6696  for (i=ymin;i<=ymax;i++)
6697   {
6698    xmin=(left_x >> 16);
6699    xmax=(right_x >> 16)-1; //!!!!!!!!!!!!!!!!!!
6700    if(drawW<xmax) xmax=drawW;
6701
6702    if(xmax>=xmin)
6703     {
6704      posX=left_u;
6705      posY=left_v;
6706      cR1=left_R;
6707      cG1=left_G;
6708      cB1=left_B;
6709
6710      if(xmin<drawX)
6711       {j=drawX-xmin;xmin=drawX;posX+=j*difX;posY+=j*difY;cR1+=j*difR;cG1+=j*difG;cB1+=j*difB;}
6712
6713      for(j=xmin;j<=xmax;j++)
6714       {
6715        if(iDither)
6716         GetTextureTransColGX_Dither(&psxVuw[(i<<10)+j],
6717           GETLE16(&psxVuw[((((posY>>16)&TWin.ymask)+GlobalTextAddrY+TWin.Position.y0)<<10)+
6718                  ((posX>>16)&TWin.xmask)+GlobalTextAddrX+TWin.Position.x0]),
6719           (cB1>>16),(cG1>>16),(cR1>>16));
6720        else
6721         GetTextureTransColGX(&psxVuw[(i<<10)+j],
6722           GETLE16(&psxVuw[((((posY>>16)&TWin.ymask)+GlobalTextAddrY+TWin.Position.y0)<<10)+
6723                  ((posX>>16)&TWin.xmask)+GlobalTextAddrX+TWin.Position.x0]),
6724           (cB1>>16),(cG1>>16),(cR1>>16));
6725        posX+=difX;
6726        posY+=difY;
6727        cR1+=difR;
6728        cG1+=difG;
6729        cB1+=difB;
6730       }
6731     }
6732    if(NextRow_GT()) 
6733     {
6734      return;
6735     }
6736   }
6737 }
6738
6739 ////////////////////////////////////////////////////////////////////////
6740
6741 // note: two g-shaded tris: small texture distortions can happen
6742
6743 #ifdef POLYQUAD3GT
6744
6745 static void drawPoly4TGD_TRI(short x1, short y1, short x2, short y2, short x3, short y3, short x4, short y4, short tx1, short ty1, short tx2, short ty2, short tx3, short ty3, short tx4, short ty4, int32_t col1, int32_t col2, int32_t col3, int32_t col4)
6746 {
6747  drawPoly3TGD(x2,y2,x3,y3,x4,y4,
6748               tx2,ty2,tx3,ty3,tx4,ty4,
6749               col2,col4,col3);
6750  drawPoly3TGD(x1,y1,x2,y2,x4,y4,
6751               tx1,ty1,tx2,ty2,tx4,ty4,
6752               col1,col2,col3);
6753 }
6754
6755 #endif
6756
6757 static void drawPoly4TGD(short x1, short y1, short x2, short y2, short x3, short y3, short x4, short y4, short tx1, short ty1, short tx2, short ty2, short tx3, short ty3, short tx4, short ty4, int32_t col1, int32_t col2, int32_t col4, int32_t col3)
6758 {
6759  int32_t num; 
6760  int32_t i,j,xmin,xmax,ymin,ymax;
6761  int32_t cR1,cG1,cB1;
6762  int32_t difR,difB,difG,difR2,difB2,difG2;
6763  int32_t difX, difY, difX2, difY2;
6764  int32_t posX,posY;
6765
6766  if(x1>drawW && x2>drawW && x3>drawW && x4>drawW) return;
6767  if(y1>drawH && y2>drawH && y3>drawH && y4>drawH) return;
6768  if(x1<drawX && x2<drawX && x3<drawX && x4<drawX) return;
6769  if(y1<drawY && y2<drawY && y3<drawY && y4<drawY) return;
6770  if(drawY>=drawH) return;
6771  if(drawX>=drawW) return; 
6772
6773  if(!SetupSections_GT4(x1,y1,x2,y2,x3,y3,x4,y4,tx1,ty1,tx2,ty2,tx3,ty3,tx4,ty4,col1,col2,col3,col4)) return;
6774
6775  ymax=Ymax;
6776
6777  for(ymin=Ymin;ymin<drawY;ymin++)
6778   if(NextRow_GT4()) return;
6779
6780 #ifdef FASTSOLID
6781
6782  if(!bCheckMask && !DrawSemiTrans && !iDither)
6783   {
6784    for (i=ymin;i<=ymax;i++)
6785     {
6786      xmin=(left_x >> 16);
6787      xmax=(right_x >> 16);
6788
6789      if(xmax>=xmin)
6790       {
6791        posX=left_u;
6792        posY=left_v;
6793
6794        num=(xmax-xmin);
6795        if(num==0) num=1;
6796        difX=(right_u-posX)/num;
6797        difY=(right_v-posY)/num;
6798        difX2=difX<<1;
6799        difY2=difY<<1;
6800
6801        cR1=left_R;
6802        cG1=left_G;
6803        cB1=left_B;
6804        difR=(right_R-cR1)/num;
6805        difG=(right_G-cG1)/num;
6806        difB=(right_B-cB1)/num;
6807        difR2=difR<<1;
6808        difG2=difG<<1;
6809        difB2=difB<<1;
6810
6811        if(xmin<drawX)
6812         {j=drawX-xmin;xmin=drawX;posX+=j*difX;posY+=j*difY;cR1+=j*difR;cG1+=j*difG;cB1+=j*difB;}
6813        xmax--;if(drawW<xmax) xmax=drawW;
6814
6815        for(j=xmin;j<xmax;j+=2)
6816         {
6817          GetTextureTransColGX32_S((uint32_t *)&psxVuw[(i<<10)+j],
6818               (((int32_t)GETLE16(&psxVuw[((((posY+difY)>>16)+GlobalTextAddrY)<<10)+((posX+difX)>>16)+GlobalTextAddrX]))<<16)|
6819               GETLE16(&psxVuw[(((posY>>16)+GlobalTextAddrY)<<10)+((posX)>>16)+GlobalTextAddrX]),
6820               (cB1>>16)|((cB1+difB)&0xff0000),
6821               (cG1>>16)|((cG1+difG)&0xff0000),
6822               (cR1>>16)|((cR1+difR)&0xff0000));
6823          posX+=difX2;
6824          posY+=difY2;
6825          cR1+=difR2;
6826          cG1+=difG2;
6827          cB1+=difB2;
6828         }
6829        if(j==xmax)
6830         GetTextureTransColGX_S(&psxVuw[(i<<10)+j],
6831             GETLE16(&psxVuw[(((posY>>16)+GlobalTextAddrY)<<10)+(posX>>16)+GlobalTextAddrX]),
6832             (cB1>>16),(cG1>>16),(cR1>>16));
6833       }
6834      if(NextRow_GT4()) return;
6835     }
6836    return;
6837   }
6838
6839 #endif
6840
6841  for (i=ymin;i<=ymax;i++)
6842   {
6843    xmin=(left_x >> 16);
6844    xmax=(right_x >> 16);
6845
6846    if(xmax>=xmin)
6847     {
6848      posX=left_u;
6849      posY=left_v;
6850
6851      num=(xmax-xmin);
6852      if(num==0) num=1;
6853      difX=(right_u-posX)/num;
6854      difY=(right_v-posY)/num;
6855      difX2=difX<<1;
6856      difY2=difY<<1;
6857
6858      cR1=left_R;
6859      cG1=left_G;
6860      cB1=left_B;
6861      difR=(right_R-cR1)/num;
6862      difG=(right_G-cG1)/num;
6863      difB=(right_B-cB1)/num;
6864      difR2=difR<<1;
6865      difG2=difG<<1;
6866      difB2=difB<<1;
6867
6868      if(xmin<drawX)
6869       {j=drawX-xmin;xmin=drawX;posX+=j*difX;posY+=j*difY;cR1+=j*difR;cG1+=j*difG;cB1+=j*difB;}
6870      xmax--;if(drawW<xmax) xmax=drawW;
6871
6872      for(j=xmin;j<=xmax;j++)
6873       {
6874        if(iDither)
6875         GetTextureTransColGX(&psxVuw[(i<<10)+j],
6876           GETLE16(&psxVuw[(((posY>>16)+GlobalTextAddrY)<<10)+(posX>>16)+GlobalTextAddrX]),
6877           (cB1>>16),(cG1>>16),(cR1>>16));
6878        else
6879         GetTextureTransColGX(&psxVuw[(i<<10)+j],
6880           GETLE16(&psxVuw[(((posY>>16)+GlobalTextAddrY)<<10)+(posX>>16)+GlobalTextAddrX]),
6881           (cB1>>16),(cG1>>16),(cR1>>16));
6882        posX+=difX;
6883        posY+=difY;
6884        cR1+=difR;
6885        cG1+=difG;
6886        cB1+=difB;
6887       }
6888     }
6889    if(NextRow_GT4()) return;
6890   }
6891 }
6892
6893 ////////////////////////////////////////////////////////////////////////
6894
6895 static void drawPoly4TGD_TW(short x1, short y1, short x2, short y2, short x3, short y3, short x4, short y4, short tx1, short ty1, short tx2, short ty2, short tx3, short ty3, short tx4, short ty4, int32_t col1, int32_t col2, int32_t col3, int32_t col4)
6896 {
6897  drawPoly3TGD_TW(x2,y2,x3,y3,x4,y4,
6898               tx2,ty2,tx3,ty3,tx4,ty4,
6899               col2,col4,col3);
6900  drawPoly3TGD_TW(x1,y1,x2,y2,x4,y4,
6901               tx1,ty1,tx2,ty2,tx4,ty4,
6902               col1,col2,col3);
6903 }
6904
6905 ////////////////////////////////////////////////////////////////////////
6906 ////////////////////////////////////////////////////////////////////////
6907 ////////////////////////////////////////////////////////////////////////
6908 ////////////////////////////////////////////////////////////////////////
6909 ////////////////////////////////////////////////////////////////////////
6910 ////////////////////////////////////////////////////////////////////////
6911
6912
6913 /*
6914 // no real rect test, but it does its job the way I need it
6915 static inline BOOL IsNoRect(void)
6916 {
6917  if(lx0==lx1 && lx2==lx3) return FALSE;
6918  if(lx0==lx2 && lx1==lx3) return FALSE;
6919  if(lx0==lx3 && lx1==lx2) return FALSE;
6920  return TRUE;                      
6921 }
6922 */
6923
6924 // real rect test
6925 static inline BOOL IsNoRect(void)
6926 {
6927  if(!(dwActFixes&0x200)) return FALSE;
6928
6929  if(ly0==ly1)
6930   {
6931    if(lx1==lx3 && ly3==ly2 && lx2==lx0) return FALSE;
6932    if(lx1==lx2 && ly2==ly3 && lx3==lx0) return FALSE;
6933    return TRUE;
6934   }
6935  
6936  if(ly0==ly2)
6937   {
6938    if(lx2==lx3 && ly3==ly1 && lx1==lx0) return FALSE;
6939    if(lx2==lx1 && ly1==ly3 && lx3==lx0) return FALSE;
6940    return TRUE;
6941   }
6942  
6943  if(ly0==ly3)
6944   {
6945    if(lx3==lx2 && ly2==ly1 && lx1==lx0) return FALSE;
6946    if(lx3==lx1 && ly1==ly2 && lx2==lx0) return FALSE;
6947    return TRUE;
6948   }
6949  return TRUE;
6950 }
6951
6952 ////////////////////////////////////////////////////////////////////////
6953
6954 static void drawPoly3FT(unsigned char * baseAddr)
6955 {
6956  uint32_t *gpuData = ((uint32_t *) baseAddr);
6957
6958  if(GlobalTextIL && GlobalTextTP<2)
6959   {
6960    if(GlobalTextTP==0)
6961     drawPoly3TEx4_IL(lx0,ly0,lx1,ly1,lx2,ly2,
6962                      (GETLE32(&gpuData[2]) & 0x000000ff), ((GETLE32(&gpuData[2])>>8) & 0x000000ff), (GETLE32(&gpuData[4]) & 0x000000ff), ((GETLE32(&gpuData[4])>>8) & 0x000000ff),(GETLE32(&gpuData[6]) & 0x000000ff), ((GETLE32(&gpuData[6])>>8) & 0x000000ff), 
6963                      ((GETLE32(&gpuData[2])>>12) & 0x3f0), ((GETLE32(&gpuData[2])>>22) & 511));
6964    else
6965     drawPoly3TEx8_IL(lx0,ly0,lx1,ly1,lx2,ly2,
6966                      (GETLE32(&gpuData[2]) & 0x000000ff), ((GETLE32(&gpuData[2])>>8) & 0x000000ff), (GETLE32(&gpuData[4]) & 0x000000ff), ((GETLE32(&gpuData[4])>>8) & 0x000000ff),(GETLE32(&gpuData[6]) & 0x000000ff), ((GETLE32(&gpuData[6])>>8) & 0x000000ff), 
6967                      ((GETLE32(&gpuData[2])>>12) & 0x3f0), ((GETLE32(&gpuData[2])>>22) & 511));
6968    return;
6969   }
6970
6971  if(!bUsingTWin && !(dwActFixes&0x100))
6972   {
6973    switch(GlobalTextTP)   // depending on texture mode
6974     {
6975      case 0:
6976       drawPoly3TEx4(lx0,ly0,lx1,ly1,lx2,ly2,
6977                     (GETLE32(&gpuData[2]) & 0x000000ff), ((GETLE32(&gpuData[2])>>8) & 0x000000ff), (GETLE32(&gpuData[4]) & 0x000000ff), ((GETLE32(&gpuData[4])>>8) & 0x000000ff),(GETLE32(&gpuData[6]) & 0x000000ff), ((GETLE32(&gpuData[6])>>8) & 0x000000ff), 
6978                     ((GETLE32(&gpuData[2])>>12) & 0x3f0), ((GETLE32(&gpuData[2])>>22) & 511));
6979       return;
6980      case 1:
6981       drawPoly3TEx8(lx0,ly0,lx1,ly1,lx2,ly2,
6982                     (GETLE32(&gpuData[2]) & 0x000000ff), ((GETLE32(&gpuData[2])>>8) & 0x000000ff), (GETLE32(&gpuData[4]) & 0x000000ff), ((GETLE32(&gpuData[4])>>8) & 0x000000ff),(GETLE32(&gpuData[6]) & 0x000000ff), ((GETLE32(&gpuData[6])>>8) & 0x000000ff), 
6983                     ((GETLE32(&gpuData[2])>>12) & 0x3f0), ((GETLE32(&gpuData[2])>>22) & 511));
6984       return;
6985      case 2:
6986       drawPoly3TD(lx0,ly0,lx1,ly1,lx2,ly2,(GETLE32(&gpuData[2]) & 0x000000ff), ((GETLE32(&gpuData[2])>>8) & 0x000000ff), (GETLE32(&gpuData[4]) & 0x000000ff), ((GETLE32(&gpuData[4])>>8) & 0x000000ff),(GETLE32(&gpuData[6]) & 0x000000ff), ((GETLE32(&gpuData[6])>>8) & 0x000000ff));
6987       return;
6988     }
6989    return;
6990   }
6991
6992  switch(GlobalTextTP)   // depending on texture mode
6993   {
6994    case 0:
6995     drawPoly3TEx4_TW(lx0,ly0,lx1,ly1,lx2,ly2,
6996                      (GETLE32(&gpuData[2]) & 0x000000ff), ((GETLE32(&gpuData[2])>>8) & 0x000000ff), (GETLE32(&gpuData[4]) & 0x000000ff), ((GETLE32(&gpuData[4])>>8) & 0x000000ff),(GETLE32(&gpuData[6]) & 0x000000ff), ((GETLE32(&gpuData[6])>>8) & 0x000000ff), 
6997                      ((GETLE32(&gpuData[2])>>12) & 0x3f0), ((GETLE32(&gpuData[2])>>22) & 511));
6998     return;
6999    case 1:
7000     drawPoly3TEx8_TW(lx0,ly0,lx1,ly1,lx2,ly2,
7001                      (GETLE32(&gpuData[2]) & 0x000000ff), ((GETLE32(&gpuData[2])>>8) & 0x000000ff), (GETLE32(&gpuData[4]) & 0x000000ff), ((GETLE32(&gpuData[4])>>8) & 0x000000ff),(GETLE32(&gpuData[6]) & 0x000000ff), ((GETLE32(&gpuData[6])>>8) & 0x000000ff), 
7002                      ((GETLE32(&gpuData[2])>>12) & 0x3f0), ((GETLE32(&gpuData[2])>>22) & 511));
7003     return;
7004    case 2:
7005     drawPoly3TD_TW(lx0,ly0,lx1,ly1,lx2,ly2,(GETLE32(&gpuData[2]) & 0x000000ff), ((GETLE32(&gpuData[2])>>8) & 0x000000ff), (GETLE32(&gpuData[4]) & 0x000000ff), ((GETLE32(&gpuData[4])>>8) & 0x000000ff),(GETLE32(&gpuData[6]) & 0x000000ff), ((GETLE32(&gpuData[6])>>8) & 0x000000ff));
7006     return;
7007   }
7008 }
7009
7010 ////////////////////////////////////////////////////////////////////////
7011
7012 static void drawPoly4FT(unsigned char * baseAddr)
7013 {
7014  uint32_t *gpuData = ((uint32_t *) baseAddr);
7015
7016  if(GlobalTextIL && GlobalTextTP<2)
7017   {
7018    if(GlobalTextTP==0)
7019     drawPoly4TEx4_IL(lx0,ly0,lx1,ly1,lx3,ly3,lx2,ly2,
7020                      (GETLE32(&gpuData[2]) & 0x000000ff), ((GETLE32(&gpuData[2])>>8) & 0x000000ff), (GETLE32(&gpuData[4]) & 0x000000ff), ((GETLE32(&gpuData[4])>>8) & 0x000000ff),(GETLE32(&gpuData[8]) & 0x000000ff), ((GETLE32(&gpuData[8])>>8) & 0x000000ff),(GETLE32(&gpuData[6]) & 0x000000ff), ((GETLE32(&gpuData[6])>>8) & 0x000000ff), ((GETLE32(&gpuData[2])>>12) & 0x3f0), ((GETLE32(&gpuData[2])>>22) & 511));
7021    else
7022     drawPoly4TEx8_IL(lx0,ly0,lx1,ly1,lx3,ly3,lx2,ly2,
7023                   (GETLE32(&gpuData[2]) & 0x000000ff), ((GETLE32(&gpuData[2])>>8) & 0x000000ff), (GETLE32(&gpuData[4]) & 0x000000ff), ((GETLE32(&gpuData[4])>>8) & 0x000000ff),(GETLE32(&gpuData[8]) & 0x000000ff), ((GETLE32(&gpuData[8])>>8) & 0x000000ff),(GETLE32(&gpuData[6]) & 0x000000ff), ((GETLE32(&gpuData[6])>>8) & 0x000000ff), ((GETLE32(&gpuData[2])>>12) & 0x3f0), ((GETLE32(&gpuData[2])>>22) & 511));
7024    return;
7025   }
7026
7027  if(!bUsingTWin)
7028   {
7029 #ifdef POLYQUAD3GT
7030    if(IsNoRect())
7031     {
7032      switch (GlobalTextTP)
7033       {
7034        case 0:
7035         drawPoly4TEx4_TRI(lx0,ly0,lx1,ly1,lx3,ly3,lx2,ly2,
7036                       (GETLE32(&gpuData[2]) & 0x000000ff), ((GETLE32(&gpuData[2])>>8) & 0x000000ff), (GETLE32(&gpuData[4]) & 0x000000ff), ((GETLE32(&gpuData[4])>>8) & 0x000000ff),(GETLE32(&gpuData[8]) & 0x000000ff), ((GETLE32(&gpuData[8])>>8) & 0x000000ff),(GETLE32(&gpuData[6]) & 0x000000ff), ((GETLE32(&gpuData[6])>>8) & 0x000000ff), ((GETLE32(&gpuData[2])>>12) & 0x3f0), ((GETLE32(&gpuData[2])>>22) & 511));
7037         return;
7038        case 1:
7039         drawPoly4TEx8_TRI(lx0,ly0,lx1,ly1,lx3,ly3,lx2,ly2,
7040                       (GETLE32(&gpuData[2]) & 0x000000ff), ((GETLE32(&gpuData[2])>>8) & 0x000000ff), (GETLE32(&gpuData[4]) & 0x000000ff), ((GETLE32(&gpuData[4])>>8) & 0x000000ff),(GETLE32(&gpuData[8]) & 0x000000ff), ((GETLE32(&gpuData[8])>>8) & 0x000000ff),(GETLE32(&gpuData[6]) & 0x000000ff), ((GETLE32(&gpuData[6])>>8) & 0x000000ff), ((GETLE32(&gpuData[2])>>12) & 0x3f0), ((GETLE32(&gpuData[2])>>22) & 511));
7041         return;
7042        case 2:
7043         drawPoly4TD_TRI(lx0,ly0,lx1,ly1,lx3,ly3,lx2,ly2,(GETLE32(&gpuData[2]) & 0x000000ff), ((GETLE32(&gpuData[2])>>8) & 0x000000ff), (GETLE32(&gpuData[4]) & 0x000000ff), ((GETLE32(&gpuData[4])>>8) & 0x000000ff),(GETLE32(&gpuData[8]) & 0x000000ff), ((GETLE32(&gpuData[8])>>8) & 0x000000ff),(GETLE32(&gpuData[6]) & 0x000000ff), ((GETLE32(&gpuData[6])>>8) & 0x000000ff));
7044         return;
7045       }
7046      return;
7047     }
7048 #endif
7049           
7050    switch (GlobalTextTP)
7051     {
7052      case 0: // grandia investigations needed
7053       drawPoly4TEx4(lx0,ly0,lx1,ly1,lx3,ly3,lx2,ly2,
7054                     (GETLE32(&gpuData[2]) & 0x000000ff), ((GETLE32(&gpuData[2])>>8) & 0x000000ff), (GETLE32(&gpuData[4]) & 0x000000ff), ((GETLE32(&gpuData[4])>>8) & 0x000000ff),(GETLE32(&gpuData[8]) & 0x000000ff), ((GETLE32(&gpuData[8])>>8) & 0x000000ff),(GETLE32(&gpuData[6]) & 0x000000ff), ((GETLE32(&gpuData[6])>>8) & 0x000000ff), ((GETLE32(&gpuData[2])>>12) & 0x3f0), ((GETLE32(&gpuData[2])>>22) & 511));
7055       return;
7056      case 1:
7057       drawPoly4TEx8(lx0,ly0,lx1,ly1,lx3,ly3,lx2,ly2,
7058                   (GETLE32(&gpuData[2]) & 0x000000ff), ((GETLE32(&gpuData[2])>>8) & 0x000000ff), (GETLE32(&gpuData[4]) & 0x000000ff), ((GETLE32(&gpuData[4])>>8) & 0x000000ff),(GETLE32(&gpuData[8]) & 0x000000ff), ((GETLE32(&gpuData[8])>>8) & 0x000000ff),(GETLE32(&gpuData[6]) & 0x000000ff), ((GETLE32(&gpuData[6])>>8) & 0x000000ff), ((GETLE32(&gpuData[2])>>12) & 0x3f0), ((GETLE32(&gpuData[2])>>22) & 511));
7059       return;
7060      case 2:
7061       drawPoly4TD(lx0,ly0,lx1,ly1,lx3,ly3,lx2,ly2,(GETLE32(&gpuData[2]) & 0x000000ff), ((GETLE32(&gpuData[2])>>8) & 0x000000ff), (GETLE32(&gpuData[4]) & 0x000000ff), ((GETLE32(&gpuData[4])>>8) & 0x000000ff),(GETLE32(&gpuData[8]) & 0x000000ff), ((GETLE32(&gpuData[8])>>8) & 0x000000ff),(GETLE32(&gpuData[6]) & 0x000000ff), ((GETLE32(&gpuData[6])>>8) & 0x000000ff));
7062       return;
7063     }
7064    return;
7065   }
7066
7067  switch (GlobalTextTP)
7068   {
7069    case 0:
7070     drawPoly4TEx4_TW(lx0,ly0,lx1,ly1,lx3,ly3,lx2,ly2,
7071                      (GETLE32(&gpuData[2]) & 0x000000ff), ((GETLE32(&gpuData[2])>>8) & 0x000000ff), (GETLE32(&gpuData[4]) & 0x000000ff), ((GETLE32(&gpuData[4])>>8) & 0x000000ff),(GETLE32(&gpuData[8]) & 0x000000ff), ((GETLE32(&gpuData[8])>>8) & 0x000000ff),(GETLE32(&gpuData[6]) & 0x000000ff), ((GETLE32(&gpuData[6])>>8) & 0x000000ff), ((GETLE32(&gpuData[2])>>12) & 0x3f0), ((GETLE32(&gpuData[2])>>22) & 511));
7072     return;
7073    case 1:
7074     drawPoly4TEx8_TW(lx0,ly0,lx1,ly1,lx3,ly3,lx2,ly2,
7075                      (GETLE32(&gpuData[2]) & 0x000000ff), ((GETLE32(&gpuData[2])>>8) & 0x000000ff), (GETLE32(&gpuData[4]) & 0x000000ff), ((GETLE32(&gpuData[4])>>8) & 0x000000ff),(GETLE32(&gpuData[8]) & 0x000000ff), ((GETLE32(&gpuData[8])>>8) & 0x000000ff),(GETLE32(&gpuData[6]) & 0x000000ff), ((GETLE32(&gpuData[6])>>8) & 0x000000ff), ((GETLE32(&gpuData[2])>>12) & 0x3f0), ((GETLE32(&gpuData[2])>>22) & 511));
7076     return;
7077    case 2:
7078     drawPoly4TD_TW(lx0,ly0,lx1,ly1,lx3,ly3,lx2,ly2,(GETLE32(&gpuData[2]) & 0x000000ff), ((GETLE32(&gpuData[2])>>8) & 0x000000ff), (GETLE32(&gpuData[4]) & 0x000000ff), ((GETLE32(&gpuData[4])>>8) & 0x000000ff),(GETLE32(&gpuData[8]) & 0x000000ff), ((GETLE32(&gpuData[8])>>8) & 0x000000ff),(GETLE32(&gpuData[6]) & 0x000000ff), ((GETLE32(&gpuData[6])>>8) & 0x000000ff));
7079     return;
7080   }
7081 }
7082
7083 ////////////////////////////////////////////////////////////////////////
7084
7085 static void drawPoly3GT(unsigned char * baseAddr)
7086 {
7087  uint32_t *gpuData = ((uint32_t *) baseAddr);
7088
7089  if(GlobalTextIL && GlobalTextTP<2)
7090   {
7091    if(GlobalTextTP==0)
7092     drawPoly3TGEx4_IL(lx0,ly0,lx1,ly1,lx2,ly2,
7093                       (GETLE32(&gpuData[2]) & 0x000000ff), ((GETLE32(&gpuData[2])>>8) & 0x000000ff), (GETLE32(&gpuData[5]) & 0x000000ff), ((GETLE32(&gpuData[5])>>8) & 0x000000ff),(GETLE32(&gpuData[8]) & 0x000000ff), ((GETLE32(&gpuData[8])>>8) & 0x000000ff), 
7094                       ((GETLE32(&gpuData[2])>>12) & 0x3f0), ((GETLE32(&gpuData[2])>>22) & 511),
7095                       GETLE32(&gpuData[0]),GETLE32(&gpuData[3]),GETLE32(&gpuData[6]));
7096    else
7097     drawPoly3TGEx8_IL(lx0,ly0,lx1,ly1,lx2,ly2,
7098                       (GETLE32(&gpuData[2]) & 0x000000ff), ((GETLE32(&gpuData[2])>>8) & 0x000000ff), (GETLE32(&gpuData[5]) & 0x000000ff), ((GETLE32(&gpuData[5])>>8) & 0x000000ff),(GETLE32(&gpuData[8]) & 0x000000ff), ((GETLE32(&gpuData[8])>>8) & 0x000000ff), 
7099                       ((GETLE32(&gpuData[2])>>12) & 0x3f0), ((GETLE32(&gpuData[2])>>22) & 511),
7100                       GETLE32(&gpuData[0]),GETLE32(&gpuData[3]),GETLE32(&gpuData[6]));
7101    return;
7102   }
7103
7104  if(!bUsingTWin)
7105   {
7106    switch (GlobalTextTP)
7107     {
7108      case 0:
7109       drawPoly3TGEx4(lx0,ly0,lx1,ly1,lx2,ly2,
7110                      (GETLE32(&gpuData[2]) & 0x000000ff), ((GETLE32(&gpuData[2])>>8) & 0x000000ff), (GETLE32(&gpuData[5]) & 0x000000ff), ((GETLE32(&gpuData[5])>>8) & 0x000000ff),(GETLE32(&gpuData[8]) & 0x000000ff), ((GETLE32(&gpuData[8])>>8) & 0x000000ff), 
7111                      ((GETLE32(&gpuData[2])>>12) & 0x3f0), ((GETLE32(&gpuData[2])>>22) & 511),
7112                      GETLE32(&gpuData[0]),GETLE32(&gpuData[3]),GETLE32(&gpuData[6]));
7113       return;
7114      case 1:
7115       drawPoly3TGEx8(lx0,ly0,lx1,ly1,lx2,ly2,
7116                      (GETLE32(&gpuData[2]) & 0x000000ff), ((GETLE32(&gpuData[2])>>8) & 0x000000ff), (GETLE32(&gpuData[5]) & 0x000000ff), ((GETLE32(&gpuData[5])>>8) & 0x000000ff),(GETLE32(&gpuData[8]) & 0x000000ff), ((GETLE32(&gpuData[8])>>8) & 0x000000ff), 
7117                      ((GETLE32(&gpuData[2])>>12) & 0x3f0), ((GETLE32(&gpuData[2])>>22) & 511),
7118                      GETLE32(&gpuData[0]),GETLE32(&gpuData[3]),GETLE32(&gpuData[6]));
7119       return;
7120      case 2:
7121       drawPoly3TGD(lx0,ly0,lx1,ly1,lx2,ly2,(GETLE32(&gpuData[2]) & 0x000000ff), ((GETLE32(&gpuData[2])>>8) & 0x000000ff), (GETLE32(&gpuData[5]) & 0x000000ff), ((GETLE32(&gpuData[5])>>8) & 0x000000ff),(GETLE32(&gpuData[8]) & 0x000000ff), ((GETLE32(&gpuData[8])>>8) & 0x000000ff),GETLE32(&gpuData[0]),GETLE32(&gpuData[3]),GETLE32(&gpuData[6]));
7122       return;
7123     }
7124    return;
7125   }
7126
7127  switch(GlobalTextTP)
7128   {
7129    case 0:
7130     drawPoly3TGEx4_TW(lx0,ly0,lx1,ly1,lx2,ly2,
7131                       (GETLE32(&gpuData[2]) & 0x000000ff), ((GETLE32(&gpuData[2])>>8) & 0x000000ff), (GETLE32(&gpuData[5]) & 0x000000ff), ((GETLE32(&gpuData[5])>>8) & 0x000000ff),(GETLE32(&gpuData[8]) & 0x000000ff), ((GETLE32(&gpuData[8])>>8) & 0x000000ff), 
7132                       ((GETLE32(&gpuData[2])>>12) & 0x3f0), ((GETLE32(&gpuData[2])>>22) & 511),
7133                       GETLE32(&gpuData[0]),GETLE32(&gpuData[3]),GETLE32(&gpuData[6]));
7134     return;
7135    case 1:
7136     drawPoly3TGEx8_TW(lx0,ly0,lx1,ly1,lx2,ly2,
7137                       (GETLE32(&gpuData[2]) & 0x000000ff), ((GETLE32(&gpuData[2])>>8) & 0x000000ff), (GETLE32(&gpuData[5]) & 0x000000ff), ((GETLE32(&gpuData[5])>>8) & 0x000000ff),(GETLE32(&gpuData[8]) & 0x000000ff), ((GETLE32(&gpuData[8])>>8) & 0x000000ff), 
7138                       ((GETLE32(&gpuData[2])>>12) & 0x3f0), ((GETLE32(&gpuData[2])>>22) & 511),
7139                       GETLE32(&gpuData[0]),GETLE32(&gpuData[3]),GETLE32(&gpuData[6]));
7140     return;
7141    case 2:
7142     drawPoly3TGD_TW(lx0,ly0,lx1,ly1,lx2,ly2,(GETLE32(&gpuData[2]) & 0x000000ff), ((GETLE32(&gpuData[2])>>8) & 0x000000ff), (GETLE32(&gpuData[5]) & 0x000000ff), ((GETLE32(&gpuData[5])>>8) & 0x000000ff),(GETLE32(&gpuData[8]) & 0x000000ff), ((GETLE32(&gpuData[8])>>8) & 0x000000ff),GETLE32(&gpuData[0]),GETLE32(&gpuData[3]),GETLE32(&gpuData[6]));
7143     return;
7144   }
7145 }              
7146
7147 ////////////////////////////////////////////////////////////////////////
7148
7149 static void drawPoly4GT(unsigned char *baseAddr)
7150 {
7151  uint32_t *gpuData = ((uint32_t *) baseAddr);
7152
7153  if(GlobalTextIL && GlobalTextTP<2)
7154   {
7155    if(GlobalTextTP==0)
7156     drawPoly4TGEx4_TRI_IL(lx0,ly0,lx1,ly1,lx3,ly3,lx2,ly2,
7157                           (GETLE32(&gpuData[2]) & 0x000000ff), ((GETLE32(&gpuData[2])>>8) & 0x000000ff), (GETLE32(&gpuData[5]) & 0x000000ff), ((GETLE32(&gpuData[5])>>8) & 0x000000ff),(GETLE32(&gpuData[11]) & 0x000000ff), ((GETLE32(&gpuData[11])>>8) & 0x000000ff),(GETLE32(&gpuData[8]) & 0x000000ff), ((GETLE32(&gpuData[8])>>8) & 0x000000ff),
7158                           ((GETLE32(&gpuData[2])>>12) & 0x3f0),((GETLE32(&gpuData[2])>>22) & 511),
7159                           GETLE32(&gpuData[0]),GETLE32(&gpuData[3]),GETLE32(&gpuData[6]),GETLE32(&gpuData[9]));
7160    else
7161     drawPoly4TGEx8_TRI_IL(lx0,ly0,lx1,ly1,lx3,ly3,lx2,ly2,
7162                           (GETLE32(&gpuData[2]) & 0x000000ff), ((GETLE32(&gpuData[2])>>8) & 0x000000ff), (GETLE32(&gpuData[5]) & 0x000000ff), ((GETLE32(&gpuData[5])>>8) & 0x000000ff),(GETLE32(&gpuData[11]) & 0x000000ff), ((GETLE32(&gpuData[11])>>8) & 0x000000ff),(GETLE32(&gpuData[8]) & 0x000000ff), ((GETLE32(&gpuData[8])>>8) & 0x000000ff),
7163                           ((GETLE32(&gpuData[2])>>12) & 0x3f0),((GETLE32(&gpuData[2])>>22) & 511),
7164                           GETLE32(&gpuData[0]),GETLE32(&gpuData[3]),GETLE32(&gpuData[6]),GETLE32(&gpuData[9]));
7165    return;
7166   }
7167
7168  if(!bUsingTWin)
7169   {
7170 #ifdef POLYQUAD3GT
7171    if(IsNoRect())
7172     {
7173      switch (GlobalTextTP)
7174       {
7175        case 0:
7176         drawPoly4TGEx4_TRI(lx0,ly0,lx1,ly1,lx3,ly3,lx2,ly2,
7177                       (GETLE32(&gpuData[2]) & 0x000000ff), ((GETLE32(&gpuData[2])>>8) & 0x000000ff), (GETLE32(&gpuData[5]) & 0x000000ff), ((GETLE32(&gpuData[5])>>8) & 0x000000ff),(GETLE32(&gpuData[11]) & 0x000000ff), ((GETLE32(&gpuData[11])>>8) & 0x000000ff),(GETLE32(&gpuData[8]) & 0x000000ff), ((GETLE32(&gpuData[8])>>8) & 0x000000ff),
7178                       ((GETLE32(&gpuData[2])>>12) & 0x3f0),((GETLE32(&gpuData[2])>>22) & 511),
7179                        GETLE32(&gpuData[0]),GETLE32(&gpuData[3]),GETLE32(&gpuData[6]),GETLE32(&gpuData[9]));
7180
7181         return;
7182        case 1:
7183         drawPoly4TGEx8_TRI(lx0,ly0,lx1,ly1,lx3,ly3,lx2,ly2,
7184                       (GETLE32(&gpuData[2]) & 0x000000ff), ((GETLE32(&gpuData[2])>>8) & 0x000000ff), (GETLE32(&gpuData[5]) & 0x000000ff), ((GETLE32(&gpuData[5])>>8) & 0x000000ff),(GETLE32(&gpuData[11]) & 0x000000ff), ((GETLE32(&gpuData[11])>>8) & 0x000000ff),(GETLE32(&gpuData[8]) & 0x000000ff), ((GETLE32(&gpuData[8])>>8) & 0x000000ff),
7185                       ((GETLE32(&gpuData[2])>>12) & 0x3f0),((GETLE32(&gpuData[2])>>22) & 511),
7186                       GETLE32(&gpuData[0]),GETLE32(&gpuData[3]),GETLE32(&gpuData[6]),GETLE32(&gpuData[9]));
7187         return;
7188        case 2:
7189         drawPoly4TGD_TRI(lx0,ly0,lx1,ly1,lx3,ly3,lx2,ly2,(GETLE32(&gpuData[2]) & 0x000000ff),((GETLE32(&gpuData[2])>>8) & 0x000000ff), (GETLE32(&gpuData[5]) & 0x000000ff), ((GETLE32(&gpuData[5])>>8) & 0x000000ff),(GETLE32(&gpuData[11]) & 0x000000ff), ((GETLE32(&gpuData[11])>>8) & 0x000000ff),(GETLE32(&gpuData[8]) & 0x000000ff), ((GETLE32(&gpuData[8])>>8) & 0x000000ff),GETLE32(&gpuData[0]),GETLE32(&gpuData[3]),GETLE32(&gpuData[6]),GETLE32(&gpuData[9]));
7190         return;
7191       }
7192      return;
7193     }
7194 #endif
7195
7196    switch (GlobalTextTP)
7197     {
7198      case 0:
7199       drawPoly4TGEx4(lx0,ly0,lx1,ly1,lx3,ly3,lx2,ly2,
7200                     (GETLE32(&gpuData[2]) & 0x000000ff), ((GETLE32(&gpuData[2])>>8) & 0x000000ff), (GETLE32(&gpuData[5]) & 0x000000ff), ((GETLE32(&gpuData[5])>>8) & 0x000000ff),(GETLE32(&gpuData[11]) & 0x000000ff), ((GETLE32(&gpuData[11])>>8) & 0x000000ff),(GETLE32(&gpuData[8]) & 0x000000ff), ((GETLE32(&gpuData[8])>>8) & 0x000000ff),
7201                     ((GETLE32(&gpuData[2])>>12) & 0x3f0),((GETLE32(&gpuData[2])>>22) & 511),
7202                      GETLE32(&gpuData[0]),GETLE32(&gpuData[3]),GETLE32(&gpuData[6]),GETLE32(&gpuData[9]));
7203
7204       return;
7205      case 1:
7206       drawPoly4TGEx8(lx0,ly0,lx1,ly1,lx3,ly3,lx2,ly2,
7207                     (GETLE32(&gpuData[2]) & 0x000000ff), ((GETLE32(&gpuData[2])>>8) & 0x000000ff), (GETLE32(&gpuData[5]) & 0x000000ff), ((GETLE32(&gpuData[5])>>8) & 0x000000ff),(GETLE32(&gpuData[11]) & 0x000000ff), ((GETLE32(&gpuData[11])>>8) & 0x000000ff),(GETLE32(&gpuData[8]) & 0x000000ff), ((GETLE32(&gpuData[8])>>8) & 0x000000ff),
7208                     ((GETLE32(&gpuData[2])>>12) & 0x3f0),((GETLE32(&gpuData[2])>>22) & 511),
7209                     GETLE32(&gpuData[0]),GETLE32(&gpuData[3]),GETLE32(&gpuData[6]),GETLE32(&gpuData[9]));
7210       return;
7211      case 2:
7212       drawPoly4TGD(lx0,ly0,lx1,ly1,lx3,ly3,lx2,ly2,(GETLE32(&gpuData[2]) & 0x000000ff),((GETLE32(&gpuData[2])>>8) & 0x000000ff), (GETLE32(&gpuData[5]) & 0x000000ff), ((GETLE32(&gpuData[5])>>8) & 0x000000ff),(GETLE32(&gpuData[11]) & 0x000000ff), ((GETLE32(&gpuData[11])>>8) & 0x000000ff),(GETLE32(&gpuData[8]) & 0x000000ff), ((GETLE32(&gpuData[8])>>8) & 0x000000ff),GETLE32(&gpuData[0]),GETLE32(&gpuData[3]),GETLE32(&gpuData[6]),GETLE32(&gpuData[9]));
7213       return;
7214     }
7215    return;
7216   }
7217
7218  switch (GlobalTextTP)
7219   {
7220    case 0:
7221     drawPoly4TGEx4_TW(lx0,ly0,lx1,ly1,lx3,ly3,lx2,ly2,
7222                       (GETLE32(&gpuData[2]) & 0x000000ff), ((GETLE32(&gpuData[2])>>8) & 0x000000ff), (GETLE32(&gpuData[5]) & 0x000000ff), ((GETLE32(&gpuData[5])>>8) & 0x000000ff),(GETLE32(&gpuData[11]) & 0x000000ff), ((GETLE32(&gpuData[11])>>8) & 0x000000ff),(GETLE32(&gpuData[8]) & 0x000000ff), ((GETLE32(&gpuData[8])>>8) & 0x000000ff),
7223                       ((GETLE32(&gpuData[2])>>12) & 0x3f0),((GETLE32(&gpuData[2])>>22) & 511),
7224                       GETLE32(&gpuData[0]),GETLE32(&gpuData[3]),GETLE32(&gpuData[6]),GETLE32(&gpuData[9]));
7225     return;
7226    case 1:
7227     drawPoly4TGEx8_TW(lx0,ly0,lx1,ly1,lx3,ly3,lx2,ly2,
7228                       (GETLE32(&gpuData[2]) & 0x000000ff), ((GETLE32(&gpuData[2])>>8) & 0x000000ff), (GETLE32(&gpuData[5]) & 0x000000ff), ((GETLE32(&gpuData[5])>>8) & 0x000000ff),(GETLE32(&gpuData[11]) & 0x000000ff), ((GETLE32(&gpuData[11])>>8) & 0x000000ff),(GETLE32(&gpuData[8]) & 0x000000ff), ((GETLE32(&gpuData[8])>>8) & 0x000000ff),
7229                       ((GETLE32(&gpuData[2])>>12) & 0x3f0),((GETLE32(&gpuData[2])>>22) & 511),
7230                       GETLE32(&gpuData[0]),GETLE32(&gpuData[3]),GETLE32(&gpuData[6]),GETLE32(&gpuData[9]));
7231     return;
7232    case 2:
7233     drawPoly4TGD_TW(lx0,ly0,lx1,ly1,lx3,ly3,lx2,ly2,(GETLE32(&gpuData[2]) & 0x000000ff),((GETLE32(&gpuData[2])>>8) & 0x000000ff), (GETLE32(&gpuData[5]) & 0x000000ff), ((GETLE32(&gpuData[5])>>8) & 0x000000ff),(GETLE32(&gpuData[11]) & 0x000000ff), ((GETLE32(&gpuData[11])>>8) & 0x000000ff),(GETLE32(&gpuData[8]) & 0x000000ff), ((GETLE32(&gpuData[8])>>8) & 0x000000ff),GETLE32(&gpuData[0]),GETLE32(&gpuData[3]),GETLE32(&gpuData[6]),GETLE32(&gpuData[9]));
7234     return;
7235   }
7236 }
7237                 
7238 ////////////////////////////////////////////////////////////////////////
7239 // SPRITE FUNCS
7240 ////////////////////////////////////////////////////////////////////////
7241
7242 static void DrawSoftwareSpriteTWin(unsigned char * baseAddr,int32_t w,int32_t h)
7243
7244  uint32_t *gpuData = (uint32_t *)baseAddr;
7245  short sx0,sy0,sx1,sy1,sx2,sy2,sx3,sy3;
7246  short tx0,ty0,tx1,ty1,tx2,ty2,tx3,ty3;
7247
7248  sx0=lx0;
7249  sy0=ly0;
7250
7251  sx0=sx3=sx0+PSXDisplay.DrawOffset.x;
7252  sx1=sx2=sx0+w;
7253  sy0=sy1=sy0+PSXDisplay.DrawOffset.y;
7254  sy2=sy3=sy0+h;
7255  
7256  tx0=tx3=GETLE32(&gpuData[2])&0xff;
7257  tx1=tx2=tx0+w;
7258  ty0=ty1=(GETLE32(&gpuData[2])>>8)&0xff;
7259  ty2=ty3=ty0+h;
7260
7261  switch (GlobalTextTP)
7262   {
7263    case 0:
7264     drawPoly4TEx4_TW_S(sx0,sy0,sx1,sy1,sx2,sy2,sx3,sy3,
7265                      tx0,ty0,tx1,ty1,tx2,ty2,tx3,ty3, 
7266                      ((GETLE32(&gpuData[2])>>12) & 0x3f0), ((GETLE32(&gpuData[2])>>22) & 511));
7267     return;
7268    case 1:
7269     drawPoly4TEx8_TW_S(sx0,sy0,sx1,sy1,sx2,sy2,sx3,sy3,
7270                        tx0,ty0,tx1,ty1,tx2,ty2,tx3,ty3, 
7271                        ((GETLE32(&gpuData[2])>>12) & 0x3f0), ((GETLE32(&gpuData[2])>>22) & 511));
7272     return;
7273    case 2:
7274     drawPoly4TD_TW_S(sx0,sy0,sx1,sy1,sx2,sy2,sx3,sy3,
7275                      tx0,ty0,tx1,ty1,tx2,ty2,tx3,ty3);
7276     return;
7277   }
7278 }                                                   
7279
7280 ////////////////////////////////////////////////////////////////////////
7281
7282 static void DrawSoftwareSpriteMirror(unsigned char * baseAddr,int32_t w,int32_t h)
7283 {
7284  int32_t sprtY,sprtX,sprtW,sprtH,lXDir,lYDir;
7285  int32_t clutY0,clutX0,clutP,textX0,textY0,sprtYa,sprCY,sprCX,sprA;
7286  short tC;
7287  uint32_t *gpuData = (uint32_t *)baseAddr;
7288  sprtY = ly0;
7289  sprtX = lx0;
7290  sprtH = h;
7291  sprtW = w;
7292  clutY0 = (GETLE32(&gpuData[2])>>22) & 511;
7293  clutX0 = (GETLE32(&gpuData[2])>>12) & 0x3f0;
7294  clutP  = (clutY0<<11) + (clutX0<<1);
7295  textY0 = ((GETLE32(&gpuData[2])>>8) & 0x000000ff) + GlobalTextAddrY;
7296  textX0 = (GETLE32(&gpuData[2]) & 0x000000ff);
7297
7298  sprtX+=PSXDisplay.DrawOffset.x;
7299  sprtY+=PSXDisplay.DrawOffset.y;
7300
7301  if(sprtX>drawW)
7302   {
7303    return;
7304   }
7305
7306  if(sprtY>drawH)
7307   {
7308    return;
7309   }
7310
7311  if(sprtY<drawY)
7312   {
7313    if((sprtY+sprtH)<drawY) return;
7314    sprtH-=(drawY-sprtY);
7315    textY0+=(drawY-sprtY);
7316    sprtY=drawY;
7317   }
7318
7319  if(sprtX<drawX)
7320   {
7321    if((sprtX+sprtW)<drawX) return;
7322    sprtW-=(drawX-sprtX);
7323    textX0+=(drawX-sprtX);
7324    sprtX=drawX;
7325   }
7326
7327  if((sprtY+sprtH)>drawH) sprtH=drawH-sprtY+1;
7328  if((sprtX+sprtW)>drawW) sprtW=drawW-sprtX+1;
7329
7330  if(usMirror&0x1000) lXDir=-1; else lXDir=1;
7331  if(usMirror&0x2000) lYDir=-1; else lYDir=1;
7332
7333  switch (GlobalTextTP)
7334   {
7335    case 0: // texture is 4-bit
7336
7337     sprtW=sprtW/2;
7338     textX0=(GlobalTextAddrX<<1)+(textX0>>1);
7339     sprtYa=(sprtY<<10);
7340     clutP=(clutY0<<10)+clutX0;
7341     for (sprCY=0;sprCY<sprtH;sprCY++)
7342      for (sprCX=0;sprCX<sprtW;sprCX++)
7343       {
7344        tC= psxVub[((textY0+(sprCY*lYDir))<<11) + textX0 +(sprCX*lXDir)];
7345        sprA=sprtYa+(sprCY<<10)+sprtX + (sprCX<<1);
7346        GetTextureTransColG_SPR(&psxVuw[sprA],GETLE16(&psxVuw[clutP+((tC>>4)&0xf)]));
7347        GetTextureTransColG_SPR(&psxVuw[sprA+1],GETLE16(&psxVuw[clutP+(tC&0xf)]));
7348       }
7349     return;
7350
7351    case 1: 
7352
7353     clutP>>=1;
7354     for(sprCY=0;sprCY<sprtH;sprCY++)
7355      for(sprCX=0;sprCX<sprtW;sprCX++)
7356       { 
7357        tC = psxVub[((textY0+(sprCY*lYDir))<<11)+(GlobalTextAddrX<<1) + textX0 + (sprCX*lXDir)] & 0xff;
7358        GetTextureTransColG_SPR(&psxVuw[((sprtY+sprCY)<<10)+sprtX + sprCX],psxVuw[clutP+tC]);
7359       }
7360      return;
7361
7362    case 2:
7363
7364     for (sprCY=0;sprCY<sprtH;sprCY++)
7365      for (sprCX=0;sprCX<sprtW;sprCX++)
7366       { 
7367        GetTextureTransColG_SPR(&psxVuw[((sprtY+sprCY)<<10)+sprtX+sprCX],
7368            GETLE16(&psxVuw[((textY0+(sprCY*lYDir))<<10)+GlobalTextAddrX + textX0 +(sprCX*lXDir)]));
7369       }
7370      return;
7371   }
7372 }
7373
7374 ////////////////////////////////////////////////////////////////////////
7375
7376 void DrawSoftwareSprite_IL(unsigned char * baseAddr,short w,short h,int32_t tx,int32_t ty)
7377 {
7378  int32_t sprtY,sprtX,sprtW,sprtH,tdx,tdy;
7379  uint32_t *gpuData = (uint32_t *)baseAddr;
7380
7381  sprtY = ly0;
7382  sprtX = lx0;
7383  sprtH = h;
7384  sprtW = w;
7385
7386  sprtX+=PSXDisplay.DrawOffset.x;
7387  sprtY+=PSXDisplay.DrawOffset.y;
7388
7389  if(sprtX>drawW) return;
7390  if(sprtY>drawH) return;
7391
7392  tdx=tx+sprtW;
7393  tdy=ty+sprtH;
7394
7395  sprtW+=sprtX;
7396  sprtH+=sprtY;
7397
7398  // Pete is too lazy to make a faster version ;)
7399
7400  if(GlobalTextTP==0)
7401   drawPoly4TEx4_IL(sprtX,sprtY,sprtX,sprtH,sprtW,sprtH,sprtW,sprtY,
7402                    tx,ty,      tx,tdy,     tdx,tdy,    tdx,ty,     
7403                    (GETLE32(&gpuData[2])>>12) & 0x3f0, ((GETLE32(&gpuData[2])>>22) & 511));
7404
7405
7406  else
7407   drawPoly4TEx8_IL(sprtX,sprtY,sprtX,sprtH,sprtW,sprtH,sprtW,sprtY,
7408                    tx,ty,      tx,tdy,     tdx,tdy,    tdx,ty,     
7409                    (GETLE32(&gpuData[2])>>12) & 0x3f0, ((GETLE32(&gpuData[2])>>22) & 511));
7410 }
7411
7412 ////////////////////////////////////////////////////////////////////////
7413
7414 static void DrawSoftwareSprite(unsigned char * baseAddr,short w,short h,int32_t tx,int32_t ty)
7415 {
7416  int32_t sprtY,sprtX,sprtW,sprtH;
7417  int32_t clutY0,clutX0,clutP,textX0,textY0,sprtYa,sprCY,sprCX,sprA;
7418  short tC,tC2;
7419  uint32_t *gpuData = (uint32_t *)baseAddr;
7420  unsigned char * pV;
7421  BOOL bWT,bWS;
7422
7423  if(GlobalTextIL && GlobalTextTP<2)
7424   {DrawSoftwareSprite_IL(baseAddr,w,h,tx,ty);return;}
7425
7426  sprtY = ly0;
7427  sprtX = lx0;
7428  sprtH = h;
7429  sprtW = w;
7430  clutY0 = (GETLE32(&gpuData[2])>>22) & 511;
7431  clutX0 = (GETLE32(&gpuData[2])>>12) & 0x3f0;
7432
7433  clutP  = (clutY0<<11) + (clutX0<<1);
7434
7435  textY0 =ty+ GlobalTextAddrY;
7436  textX0 =tx;
7437
7438  sprtX+=PSXDisplay.DrawOffset.x;
7439  sprtY+=PSXDisplay.DrawOffset.y;
7440
7441  if(sprtX>drawW)
7442   {
7443    return;
7444   }
7445
7446  if(sprtY>drawH)
7447   {
7448    return;
7449   }
7450
7451  if(sprtY<drawY)
7452   {
7453    if((sprtY+sprtH)<drawY) return;
7454    sprtH-=(drawY-sprtY);
7455    textY0+=(drawY-sprtY);
7456    sprtY=drawY;
7457   }
7458
7459  if(sprtX<drawX)
7460   {
7461    if((sprtX+sprtW)<drawX) return;
7462
7463    sprtW-=(drawX-sprtX);
7464    textX0+=(drawX-sprtX);
7465    sprtX=drawX;
7466   }
7467
7468  if((sprtY+sprtH)>drawH) sprtH=drawH-sprtY+1;
7469  if((sprtX+sprtW)>drawW) sprtW=drawW-sprtX+1;
7470
7471
7472  bWT=FALSE;
7473  bWS=FALSE;
7474
7475  switch (GlobalTextTP)
7476   {
7477    case 0:
7478
7479     if(textX0&1) {bWS=TRUE;sprtW--;}
7480     if(sprtW&1)  bWT=TRUE;
7481     
7482     sprtW=sprtW>>1;
7483     textX0=(GlobalTextAddrX<<1)+(textX0>>1)+(textY0<<11);
7484     sprtYa=(sprtY<<10)+sprtX;
7485     clutP=(clutY0<<10)+clutX0;
7486
7487 #ifdef FASTSOLID
7488  
7489     if(!bCheckMask && !DrawSemiTrans)
7490      {
7491       for (sprCY=0;sprCY<sprtH;sprCY++)
7492        {
7493         sprA=sprtYa+(sprCY<<10);
7494         pV=&psxVub[(sprCY<<11)+textX0];
7495
7496         if(bWS)
7497          {
7498           tC=*pV++;
7499           GetTextureTransColG_S(&psxVuw[sprA++],GETLE16(&psxVuw[clutP+((tC>>4)&0xf)]));
7500          }
7501
7502         for (sprCX=0;sprCX<sprtW;sprCX++,sprA+=2)
7503          { 
7504           tC=*pV++;
7505
7506           GetTextureTransColG32_S((uint32_t *)&psxVuw[sprA],
7507               (((int32_t)GETLE16(&psxVuw[clutP+((tC>>4)&0xf)]))<<16)|
7508               GETLE16(&psxVuw[clutP+(tC&0x0f)]));
7509          }
7510
7511         if(bWT)
7512          {
7513           tC=*pV;
7514           GetTextureTransColG_S(&psxVuw[sprA],GETLE16(&psxVuw[clutP+(tC&0x0f)]));
7515          }
7516        }
7517       return;
7518      }
7519
7520 #endif
7521
7522     for (sprCY=0;sprCY<sprtH;sprCY++)
7523      {
7524       sprA=sprtYa+(sprCY<<10);
7525       pV=&psxVub[(sprCY<<11)+textX0];
7526
7527       if(bWS)
7528        {
7529         tC=*pV++;
7530         GetTextureTransColG_SPR(&psxVuw[sprA++],GETLE16(&psxVuw[clutP+((tC>>4)&0xf)]));
7531        }
7532
7533       for (sprCX=0;sprCX<sprtW;sprCX++,sprA+=2)
7534        { 
7535         tC=*pV++;
7536
7537         GetTextureTransColG32_SPR((uint32_t *)&psxVuw[sprA],
7538             (((int32_t)GETLE16(&psxVuw[clutP+((tC>>4)&0xf)])<<16))|
7539             GETLE16(&psxVuw[clutP+(tC&0x0f)]));
7540        }
7541
7542       if(bWT)
7543        {
7544         tC=*pV;
7545         GetTextureTransColG_SPR(&psxVuw[sprA],GETLE16(&psxVuw[clutP+(tC&0x0f)]));
7546        }
7547      }
7548     return;
7549
7550    case 1:
7551     clutP>>=1;sprtW--;
7552     textX0+=(GlobalTextAddrX<<1) + (textY0<<11);
7553
7554 #ifdef FASTSOLID
7555
7556     if(!bCheckMask && !DrawSemiTrans)
7557      {
7558       for(sprCY=0;sprCY<sprtH;sprCY++)
7559        {
7560         sprA=((sprtY+sprCY)<<10)+sprtX;
7561         pV=&psxVub[(sprCY<<11)+textX0];
7562         for(sprCX=0;sprCX<sprtW;sprCX+=2,sprA+=2)
7563          { 
7564           tC = *pV++;tC2 = *pV++;
7565           GetTextureTransColG32_S((uint32_t *)&psxVuw[sprA],
7566               (((int32_t)GETLE16(&psxVuw[clutP+tC2]))<<16)|
7567               GETLE16(&psxVuw[clutP+tC]));
7568          }
7569         if(sprCX==sprtW)
7570          GetTextureTransColG_S(&psxVuw[sprA],GETLE16(&psxVuw[clutP+(*pV)]));
7571        }
7572       return;
7573      }
7574
7575 #endif
7576
7577     for(sprCY=0;sprCY<sprtH;sprCY++)
7578      {
7579       sprA=((sprtY+sprCY)<<10)+sprtX;
7580       pV=&psxVub[(sprCY<<11)+textX0];
7581       for(sprCX=0;sprCX<sprtW;sprCX+=2,sprA+=2)
7582        { 
7583         tC = *pV++;tC2 = *pV++;
7584         GetTextureTransColG32_SPR((uint32_t *)&psxVuw[sprA],
7585             (((int32_t)GETLE16(&psxVuw[clutP+tC2]))<<16)|
7586             GETLE16(&psxVuw[clutP+tC]));
7587        }
7588       if(sprCX==sprtW)
7589        GetTextureTransColG_SPR(&psxVuw[sprA],GETLE16(&psxVuw[clutP+(*pV)]));
7590      }
7591     return;
7592
7593    case 2:
7594
7595     textX0+=(GlobalTextAddrX) + (textY0<<10);
7596     sprtW--;
7597
7598 #ifdef FASTSOLID
7599
7600     if(!bCheckMask && !DrawSemiTrans)
7601      {
7602       for (sprCY=0;sprCY<sprtH;sprCY++)
7603        {
7604         sprA=((sprtY+sprCY)<<10)+sprtX;
7605
7606         for (sprCX=0;sprCX<sprtW;sprCX+=2,sprA+=2)
7607          { 
7608           GetTextureTransColG32_S((uint32_t *)&psxVuw[sprA],
7609               (((int32_t)GETLE16(&psxVuw[(sprCY<<10) + textX0 + sprCX +1]))<<16)|
7610               GETLE16(&psxVuw[(sprCY<<10) + textX0 + sprCX]));
7611          }
7612         if(sprCX==sprtW)
7613          GetTextureTransColG_S(&psxVuw[sprA],
7614               GETLE16(&psxVuw[(sprCY<<10) + textX0 + sprCX]));
7615
7616        }
7617       return;
7618      }
7619
7620 #endif
7621
7622     for (sprCY=0;sprCY<sprtH;sprCY++)
7623      {
7624       sprA=((sprtY+sprCY)<<10)+sprtX;
7625
7626       for (sprCX=0;sprCX<sprtW;sprCX+=2,sprA+=2)
7627        { 
7628         GetTextureTransColG32_SPR((uint32_t *)&psxVuw[sprA],
7629             (((int32_t)GETLE16(&psxVuw[(sprCY<<10) + textX0 + sprCX +1]))<<16)|
7630             GETLE16(&psxVuw[(sprCY<<10) + textX0 + sprCX]));
7631        }
7632       if(sprCX==sprtW)
7633        GetTextureTransColG_SPR(&psxVuw[sprA],
7634             GETLE16(&psxVuw[(sprCY<<10) + textX0 + sprCX]));
7635
7636      }
7637     return;
7638    }                
7639 }
7640  
7641 ///////////////////////////////////////////////////////////////////////
7642
7643 /////////////////////////////////////////////////////////////////
7644 /////////////////////////////////////////////////////////////////
7645 /////////////////////////////////////////////////////////////////
7646 // LINE FUNCS
7647 ////////////////////////////////////////////////////////////////////////
7648 /////////////////////////////////////////////////////////////////
7649 /////////////////////////////////////////////////////////////////
7650
7651
7652 ///////////////////////////////////////////////////////////////////////
7653
7654 static void Line_E_SE_Shade(int x0, int y0, int x1, int y1, uint32_t rgb0, uint32_t rgb1)
7655 {
7656     int dx, dy, incrE, incrSE, d;
7657                 uint32_t r0, g0, b0, r1, g1, b1;
7658                 int32_t dr, dg, db;
7659
7660                 r0 = (rgb0 & 0x00ff0000);
7661                 g0 = (rgb0 & 0x0000ff00) << 8;
7662                 b0 = (rgb0 & 0x000000ff) << 16;
7663                 r1 = (rgb1 & 0x00ff0000);
7664                 g1 = (rgb1 & 0x0000ff00) << 8;
7665                 b1 = (rgb1 & 0x000000ff) << 16;
7666
7667     dx = x1 - x0;
7668     dy = y1 - y0;
7669
7670                 if (dx > 0)
7671                 {
7672                         dr = ((int32_t)r1 - (int32_t)r0) / dx;
7673                         dg = ((int32_t)g1 - (int32_t)g0) / dx;
7674                         db = ((int32_t)b1 - (int32_t)b0) / dx;
7675                 }
7676                 else
7677                 {
7678                         dr = ((int32_t)r1 - (int32_t)r0);
7679                         dg = ((int32_t)g1 - (int32_t)g0);
7680                         db = ((int32_t)b1 - (int32_t)b0);
7681                 }
7682
7683     d = 2*dy - dx;              /* Initial value of d */
7684     incrE = 2*dy;               /* incr. used for move to E */
7685     incrSE = 2*(dy - dx);       /* incr. used for move to SE */
7686
7687                 if ((x0>=drawX)&&(x0<drawW)&&(y0>=drawY)&&(y0<drawH))
7688                         GetShadeTransCol(&psxVuw[(y0<<10)+x0],(unsigned short)(((r0 >> 9)&0x7c00)|((g0 >> 14)&0x03e0)|((b0 >> 19)&0x001f)));
7689     while(x0 < x1)
7690     {
7691         if (d <= 0)
7692         {
7693             d = d + incrE;              /* Choose E */
7694         }
7695         else
7696         {
7697             d = d + incrSE;             /* Choose SE */
7698             y0++;
7699         }
7700         x0++;
7701
7702                                 r0+=dr;
7703                                 g0+=dg;
7704                                 b0+=db;
7705
7706                                 if ((x0>=drawX)&&(x0<drawW)&&(y0>=drawY)&&(y0<drawH))
7707                                         GetShadeTransCol(&psxVuw[(y0<<10)+x0],(unsigned short)(((r0 >> 9)&0x7c00)|((g0 >> 14)&0x03e0)|((b0 >> 19)&0x001f)));
7708     }
7709 }
7710
7711 ///////////////////////////////////////////////////////////////////////
7712
7713 static void Line_S_SE_Shade(int x0, int y0, int x1, int y1, uint32_t rgb0, uint32_t rgb1)
7714 {
7715     int dx, dy, incrS, incrSE, d;
7716                 uint32_t r0, g0, b0, r1, g1, b1;
7717                 int32_t dr, dg, db;
7718
7719                 r0 = (rgb0 & 0x00ff0000);
7720                 g0 = (rgb0 & 0x0000ff00) << 8;
7721                 b0 = (rgb0 & 0x000000ff) << 16;
7722                 r1 = (rgb1 & 0x00ff0000);
7723                 g1 = (rgb1 & 0x0000ff00) << 8;
7724                 b1 = (rgb1 & 0x000000ff) << 16;
7725
7726     dx = x1 - x0;
7727     dy = y1 - y0;
7728
7729                 if (dy > 0)
7730                 {
7731                         dr = ((int32_t)r1 - (int32_t)r0) / dy;
7732                         dg = ((int32_t)g1 - (int32_t)g0) / dy;
7733                         db = ((int32_t)b1 - (int32_t)b0) / dy;
7734                 }
7735                 else
7736                 {
7737                         dr = ((int32_t)r1 - (int32_t)r0);
7738                         dg = ((int32_t)g1 - (int32_t)g0);
7739                         db = ((int32_t)b1 - (int32_t)b0);
7740                 }
7741
7742     d = 2*dx - dy;              /* Initial value of d */
7743     incrS = 2*dx;               /* incr. used for move to S */
7744     incrSE = 2*(dx - dy);       /* incr. used for move to SE */
7745
7746                 if ((x0>=drawX)&&(x0<drawW)&&(y0>=drawY)&&(y0<drawH))
7747                         GetShadeTransCol(&psxVuw[(y0<<10)+x0],(unsigned short)(((r0 >> 9)&0x7c00)|((g0 >> 14)&0x03e0)|((b0 >> 19)&0x001f)));
7748     while(y0 < y1)
7749     {
7750         if (d <= 0)
7751         {
7752             d = d + incrS;              /* Choose S */
7753         }
7754         else
7755         {
7756             d = d + incrSE;             /* Choose SE */
7757             x0++;
7758         }
7759         y0++;
7760
7761                                 r0+=dr;
7762                                 g0+=dg;
7763                                 b0+=db;
7764
7765                                 if ((x0>=drawX)&&(x0<drawW)&&(y0>=drawY)&&(y0<drawH))
7766                                         GetShadeTransCol(&psxVuw[(y0<<10)+x0],(unsigned short)(((r0 >> 9)&0x7c00)|((g0 >> 14)&0x03e0)|((b0 >> 19)&0x001f)));
7767     }
7768 }
7769
7770 ///////////////////////////////////////////////////////////////////////
7771
7772 static void Line_N_NE_Shade(int x0, int y0, int x1, int y1, uint32_t rgb0, uint32_t rgb1)
7773 {
7774     int dx, dy, incrN, incrNE, d;
7775                 uint32_t r0, g0, b0, r1, g1, b1;
7776                 int32_t dr, dg, db;
7777
7778                 r0 = (rgb0 & 0x00ff0000);
7779                 g0 = (rgb0 & 0x0000ff00) << 8;
7780                 b0 = (rgb0 & 0x000000ff) << 16;
7781                 r1 = (rgb1 & 0x00ff0000);
7782                 g1 = (rgb1 & 0x0000ff00) << 8;
7783                 b1 = (rgb1 & 0x000000ff) << 16;
7784
7785     dx = x1 - x0;
7786     dy = -(y1 - y0);
7787
7788                 if (dy > 0)
7789                 {
7790                         dr = ((int32_t)r1 - (int32_t)r0) / dy;
7791                         dg = ((int32_t)g1 - (int32_t)g0) / dy;
7792                         db = ((int32_t)b1 - (int32_t)b0) / dy;
7793                 }
7794                 else
7795                 {
7796                         dr = ((int32_t)r1 - (int32_t)r0);
7797                         dg = ((int32_t)g1 - (int32_t)g0);
7798                         db = ((int32_t)b1 - (int32_t)b0);
7799                 }
7800
7801     d = 2*dx - dy;              /* Initial value of d */
7802     incrN = 2*dx;               /* incr. used for move to N */
7803     incrNE = 2*(dx - dy);       /* incr. used for move to NE */
7804
7805                 if ((x0>=drawX)&&(x0<drawW)&&(y0>=drawY)&&(y0<drawH))
7806                         GetShadeTransCol(&psxVuw[(y0<<10)+x0],(unsigned short)(((r0 >> 9)&0x7c00)|((g0 >> 14)&0x03e0)|((b0 >> 19)&0x001f)));
7807     while(y0 > y1)
7808     {
7809         if (d <= 0)
7810         {
7811             d = d + incrN;              /* Choose N */
7812         }
7813         else
7814         {
7815             d = d + incrNE;             /* Choose NE */
7816             x0++;
7817         }
7818         y0--;
7819
7820                                 r0+=dr;
7821                                 g0+=dg;
7822                                 b0+=db;
7823
7824                                 if ((x0>=drawX)&&(x0<drawW)&&(y0>=drawY)&&(y0<drawH))
7825                                         GetShadeTransCol(&psxVuw[(y0<<10)+x0],(unsigned short)(((r0 >> 9)&0x7c00)|((g0 >> 14)&0x03e0)|((b0 >> 19)&0x001f)));
7826     }
7827 }
7828
7829 ///////////////////////////////////////////////////////////////////////
7830
7831 static void Line_E_NE_Shade(int x0, int y0, int x1, int y1, uint32_t rgb0, uint32_t rgb1)
7832 {
7833     int dx, dy, incrE, incrNE, d;
7834                 uint32_t r0, g0, b0, r1, g1, b1;
7835                 int32_t dr, dg, db;
7836
7837                 r0 = (rgb0 & 0x00ff0000);
7838                 g0 = (rgb0 & 0x0000ff00) << 8;
7839                 b0 = (rgb0 & 0x000000ff) << 16;
7840                 r1 = (rgb1 & 0x00ff0000);
7841                 g1 = (rgb1 & 0x0000ff00) << 8;
7842                 b1 = (rgb1 & 0x000000ff) << 16;
7843
7844     dx = x1 - x0;
7845     dy = -(y1 - y0);
7846
7847                 if (dx > 0)
7848                 {
7849                         dr = ((int32_t)r1 - (int32_t)r0) / dx;
7850                         dg = ((int32_t)g1 - (int32_t)g0) / dx;
7851                         db = ((int32_t)b1 - (int32_t)b0) / dx;
7852                 }
7853                 else
7854                 {
7855                         dr = ((int32_t)r1 - (int32_t)r0);
7856                         dg = ((int32_t)g1 - (int32_t)g0);
7857                         db = ((int32_t)b1 - (int32_t)b0);
7858                 }
7859
7860     d = 2*dy - dx;              /* Initial value of d */
7861     incrE = 2*dy;               /* incr. used for move to E */
7862     incrNE = 2*(dy - dx);       /* incr. used for move to NE */
7863
7864                 if ((x0>=drawX)&&(x0<drawW)&&(y0>=drawY)&&(y0<drawH))
7865                         GetShadeTransCol(&psxVuw[(y0<<10)+x0],(unsigned short)(((r0 >> 9)&0x7c00)|((g0 >> 14)&0x03e0)|((b0 >> 19)&0x001f)));
7866     while(x0 < x1)
7867     {
7868         if (d <= 0)
7869         {
7870             d = d + incrE;              /* Choose E */
7871         }
7872         else
7873         {
7874             d = d + incrNE;             /* Choose NE */
7875             y0--;
7876         }
7877         x0++;
7878
7879                                 r0+=dr;
7880                                 g0+=dg;
7881                                 b0+=db;
7882
7883                                 if ((x0>=drawX)&&(x0<drawW)&&(y0>=drawY)&&(y0<drawH))
7884                                         GetShadeTransCol(&psxVuw[(y0<<10)+x0],(unsigned short)(((r0 >> 9)&0x7c00)|((g0 >> 14)&0x03e0)|((b0 >> 19)&0x001f)));
7885     }
7886 }
7887
7888 ///////////////////////////////////////////////////////////////////////
7889
7890 static void VertLineShade(int x, int y0, int y1, uint32_t rgb0, uint32_t rgb1)
7891 {
7892   int y, dy;
7893         uint32_t r0, g0, b0, r1, g1, b1;
7894         int32_t dr, dg, db;
7895
7896         r0 = (rgb0 & 0x00ff0000);
7897         g0 = (rgb0 & 0x0000ff00) << 8;
7898         b0 = (rgb0 & 0x000000ff) << 16;
7899         r1 = (rgb1 & 0x00ff0000);
7900         g1 = (rgb1 & 0x0000ff00) << 8;
7901         b1 = (rgb1 & 0x000000ff) << 16;
7902
7903         dy = (y1 - y0);
7904
7905         if (dy > 0)
7906         {
7907                 dr = ((int32_t)r1 - (int32_t)r0) / dy;
7908                 dg = ((int32_t)g1 - (int32_t)g0) / dy;
7909                 db = ((int32_t)b1 - (int32_t)b0) / dy;
7910         }
7911         else
7912         {
7913                 dr = ((int32_t)r1 - (int32_t)r0);
7914                 dg = ((int32_t)g1 - (int32_t)g0);
7915                 db = ((int32_t)b1 - (int32_t)b0);
7916         }
7917
7918         if (y0 < drawY)
7919         {
7920                 r0+=dr*(drawY - y0);
7921                 g0+=dg*(drawY - y0);
7922                 b0+=db*(drawY - y0);
7923                 y0 = drawY;
7924         }
7925
7926         if (y1 > drawH)
7927                 y1 = drawH;
7928
7929   for (y = y0; y <= y1; y++)
7930         {
7931                 GetShadeTransCol(&psxVuw[(y<<10)+x],(unsigned short)(((r0 >> 9)&0x7c00)|((g0 >> 14)&0x03e0)|((b0 >> 19)&0x001f)));
7932                 r0+=dr;
7933                 g0+=dg;
7934                 b0+=db;
7935         }
7936 }
7937
7938 ///////////////////////////////////////////////////////////////////////
7939
7940 static void HorzLineShade(int y, int x0, int x1, uint32_t rgb0, uint32_t rgb1)
7941 {
7942   int x, dx;
7943         uint32_t r0, g0, b0, r1, g1, b1;
7944         int32_t dr, dg, db;
7945
7946         r0 = (rgb0 & 0x00ff0000);
7947         g0 = (rgb0 & 0x0000ff00) << 8;
7948         b0 = (rgb0 & 0x000000ff) << 16;
7949         r1 = (rgb1 & 0x00ff0000);
7950         g1 = (rgb1 & 0x0000ff00) << 8;
7951         b1 = (rgb1 & 0x000000ff) << 16;
7952
7953         dx = (x1 - x0);
7954
7955         if (dx > 0)
7956         {
7957                 dr = ((int32_t)r1 - (int32_t)r0) / dx;
7958                 dg = ((int32_t)g1 - (int32_t)g0) / dx;
7959                 db = ((int32_t)b1 - (int32_t)b0) / dx;
7960         }
7961         else
7962         {
7963                 dr = ((int32_t)r1 - (int32_t)r0);
7964                 dg = ((int32_t)g1 - (int32_t)g0);
7965                 db = ((int32_t)b1 - (int32_t)b0);
7966         }
7967
7968         if (x0 < drawX)
7969         {
7970                 r0+=dr*(drawX - x0);
7971                 g0+=dg*(drawX - x0);
7972                 b0+=db*(drawX - x0);
7973                 x0 = drawX;
7974         }
7975
7976         if (x1 > drawW)
7977                 x1 = drawW;
7978
7979   for (x = x0; x <= x1; x++)
7980         {
7981                 GetShadeTransCol(&psxVuw[(y<<10)+x],(unsigned short)(((r0 >> 9)&0x7c00)|((g0 >> 14)&0x03e0)|((b0 >> 19)&0x001f)));
7982                 r0+=dr;
7983                 g0+=dg;
7984                 b0+=db;
7985         }
7986 }
7987
7988 ///////////////////////////////////////////////////////////////////////
7989
7990 static void Line_E_SE_Flat(int x0, int y0, int x1, int y1, unsigned short colour)
7991 {
7992     int dx, dy, incrE, incrSE, d, x, y;
7993
7994     dx = x1 - x0;
7995     dy = y1 - y0;
7996     d = 2*dy - dx;              /* Initial value of d */
7997     incrE = 2*dy;               /* incr. used for move to E */
7998     incrSE = 2*(dy - dx);       /* incr. used for move to SE */
7999     x = x0;
8000     y = y0;
8001                 if ((x>=drawX)&&(x<drawW)&&(y>=drawY)&&(y<drawH))
8002                         GetShadeTransCol(&psxVuw[(y<<10)+x], colour);
8003     while(x < x1)
8004     {
8005         if (d <= 0)
8006         {
8007             d = d + incrE;              /* Choose E */
8008             x++;
8009         }
8010         else
8011         {
8012             d = d + incrSE;             /* Choose SE */
8013             x++;
8014             y++;
8015         }
8016                                 if ((x>=drawX)&&(x<drawW)&&(y>=drawY)&&(y<drawH))
8017                                         GetShadeTransCol(&psxVuw[(y<<10)+x], colour);
8018     }
8019 }
8020
8021 ///////////////////////////////////////////////////////////////////////
8022
8023 static void Line_S_SE_Flat(int x0, int y0, int x1, int y1, unsigned short colour)
8024 {
8025     int dx, dy, incrS, incrSE, d, x, y;
8026
8027     dx = x1 - x0;
8028     dy = y1 - y0;
8029     d = 2*dx - dy;              /* Initial value of d */
8030     incrS = 2*dx;               /* incr. used for move to S */
8031     incrSE = 2*(dx - dy);       /* incr. used for move to SE */
8032     x = x0;
8033     y = y0;
8034                 if ((x>=drawX)&&(x<drawW)&&(y>=drawY)&&(y<drawH))
8035                         GetShadeTransCol(&psxVuw[(y<<10)+x], colour);
8036     while(y < y1)
8037     {
8038         if (d <= 0)
8039         {
8040             d = d + incrS;              /* Choose S */
8041             y++;
8042         }
8043         else
8044         {
8045             d = d + incrSE;             /* Choose SE */
8046             x++;
8047             y++;
8048         }
8049                                 if ((x>=drawX)&&(x<drawW)&&(y>=drawY)&&(y<drawH))
8050                                         GetShadeTransCol(&psxVuw[(y<<10)+x], colour);
8051     }
8052 }
8053
8054 ///////////////////////////////////////////////////////////////////////
8055
8056 static void Line_N_NE_Flat(int x0, int y0, int x1, int y1, unsigned short colour)
8057 {
8058     int dx, dy, incrN, incrNE, d, x, y;
8059
8060     dx = x1 - x0;
8061     dy = -(y1 - y0);
8062     d = 2*dx - dy;              /* Initial value of d */
8063     incrN = 2*dx;               /* incr. used for move to N */
8064     incrNE = 2*(dx - dy);       /* incr. used for move to NE */
8065     x = x0;
8066     y = y0;
8067                 if ((x>=drawX)&&(x<drawW)&&(y>=drawY)&&(y<drawH))
8068                         GetShadeTransCol(&psxVuw[(y<<10)+x], colour);
8069     while(y > y1)
8070     {
8071         if (d <= 0)
8072         {
8073             d = d + incrN;              /* Choose N */
8074             y--;
8075         }
8076         else
8077         {
8078             d = d + incrNE;             /* Choose NE */
8079             x++;
8080             y--;
8081         }
8082                                 if ((x>=drawX)&&(x<drawW)&&(y>=drawY)&&(y<drawH))
8083                                         GetShadeTransCol(&psxVuw[(y<<10)+x], colour);
8084     }
8085 }
8086
8087 ///////////////////////////////////////////////////////////////////////
8088
8089 static void Line_E_NE_Flat(int x0, int y0, int x1, int y1, unsigned short colour)
8090 {
8091     int dx, dy, incrE, incrNE, d, x, y;
8092
8093     dx = x1 - x0;
8094     dy = -(y1 - y0);
8095     d = 2*dy - dx;              /* Initial value of d */
8096     incrE = 2*dy;               /* incr. used for move to E */
8097     incrNE = 2*(dy - dx);       /* incr. used for move to NE */
8098     x = x0;
8099     y = y0;
8100                 if ((x>=drawX)&&(x<drawW)&&(y>=drawY)&&(y<drawH))
8101                         GetShadeTransCol(&psxVuw[(y<<10)+x], colour);
8102     while(x < x1)
8103     {
8104         if (d <= 0)
8105         {
8106             d = d + incrE;              /* Choose E */
8107             x++;
8108         }
8109         else
8110         {
8111             d = d + incrNE;             /* Choose NE */
8112             x++;
8113             y--;
8114         }
8115                                 if ((x>=drawX)&&(x<drawW)&&(y>=drawY)&&(y<drawH))
8116                                         GetShadeTransCol(&psxVuw[(y<<10)+x], colour);
8117     }
8118 }
8119
8120 ///////////////////////////////////////////////////////////////////////
8121
8122 static void VertLineFlat(int x, int y0, int y1, unsigned short colour)
8123 {
8124         int y;
8125
8126         if (y0 < drawY)
8127                 y0 = drawY;
8128
8129         if (y1 > drawH)
8130                 y1 = drawH;
8131
8132   for (y = y0; y <= y1; y++)
8133                 GetShadeTransCol(&psxVuw[(y<<10)+x], colour);
8134 }
8135
8136 ///////////////////////////////////////////////////////////////////////
8137
8138 static void HorzLineFlat(int y, int x0, int x1, unsigned short colour)
8139 {
8140         int x;
8141
8142         if (x0 < drawX)
8143                 x0 = drawX;
8144
8145         if (x1 > drawW)
8146                 x1 = drawW;
8147
8148         for (x = x0; x <= x1; x++)
8149                 GetShadeTransCol(&psxVuw[(y << 10) + x], colour);
8150 }
8151
8152 ///////////////////////////////////////////////////////////////////////
8153
8154 /* Bresenham Line drawing function */
8155 static void DrawSoftwareLineShade(int32_t rgb0, int32_t rgb1)
8156 {
8157         short x0, y0, x1, y1, xt, yt;
8158         int32_t rgbt;
8159         double m, dy, dx;
8160
8161         if (lx0 > drawW && lx1 > drawW) return;
8162         if (ly0 > drawH && ly1 > drawH) return;
8163         if (lx0 < drawX && lx1 < drawX) return;
8164         if (ly0 < drawY && ly1 < drawY) return;
8165         if (drawY >= drawH) return;
8166         if (drawX >= drawW) return; 
8167
8168         x0 = lx0;
8169         y0 = ly0;
8170         x1 = lx1;
8171         y1 = ly1;
8172
8173         dx = x1 - x0;
8174         dy = y1 - y0;
8175
8176         if (dx == 0)
8177         {
8178                 if (dy > 0)
8179                         VertLineShade(x0, y0, y1, rgb0, rgb1);
8180                 else
8181                         VertLineShade(x0, y1, y0, rgb1, rgb0);
8182         }
8183         else
8184                 if (dy == 0)
8185                 {
8186                         if (dx > 0)
8187                                 HorzLineShade(y0, x0, x1, rgb0, rgb1);
8188                         else
8189                                 HorzLineShade(y0, x1, x0, rgb1, rgb0);
8190                 }
8191                 else
8192                 {
8193                         if (dx < 0)
8194                         {
8195                                 xt = x0;
8196                                 yt = y0;
8197                                 rgbt = rgb0;
8198                                 x0 = x1;
8199                                 y0 = y1;
8200                                 rgb0 = rgb1;
8201                                 x1 = xt;
8202                                 y1 = yt;
8203                                 rgb1 = rgbt;
8204
8205                                 dx = x1 - x0;
8206                                 dy = y1 - y0;
8207                         }
8208
8209                         m = dy / dx;
8210
8211                         if (m >= 0)
8212                         {
8213                                 if (m > 1)
8214                                         Line_S_SE_Shade(x0, y0, x1, y1, rgb0, rgb1);
8215                                 else
8216                                         Line_E_SE_Shade(x0, y0, x1, y1, rgb0, rgb1);
8217                         }
8218                         else
8219                                 if (m < -1)
8220                                         Line_N_NE_Shade(x0, y0, x1, y1, rgb0, rgb1);
8221                                 else
8222                                         Line_E_NE_Shade(x0, y0, x1, y1, rgb0, rgb1);
8223                 }
8224 }
8225
8226 ///////////////////////////////////////////////////////////////////////
8227
8228 static void DrawSoftwareLineFlat(int32_t rgb)
8229 {
8230         short x0, y0, x1, y1, xt, yt;
8231         double m, dy, dx;
8232         unsigned short colour = 0;
8233  
8234         if (lx0 > drawW && lx1 > drawW) return;
8235         if (ly0 > drawH && ly1 > drawH) return;
8236         if (lx0 < drawX && lx1 < drawX) return;
8237         if (ly0 < drawY && ly1 < drawY) return;
8238         if (drawY >= drawH) return;
8239         if (drawX >= drawW) return; 
8240
8241         colour = ((rgb & 0x00f80000) >> 9) | ((rgb & 0x0000f800) >> 6) | ((rgb & 0x000000f8) >> 3);
8242
8243         x0 = lx0;
8244         y0 = ly0;
8245         x1 = lx1;
8246         y1 = ly1;
8247
8248         dx = x1 - x0;
8249         dy = y1 - y0;
8250
8251         if (dx == 0)
8252         {
8253                 if (dy == 0)
8254                         return; // Nothing to draw
8255                 else if (dy > 0)
8256                         VertLineFlat(x0, y0, y1, colour);
8257                 else
8258                         VertLineFlat(x0, y1, y0, colour);
8259         }
8260         else
8261                 if (dy == 0)
8262                 {
8263                         if (dx > 0)
8264                                 HorzLineFlat(y0, x0, x1, colour);
8265                         else
8266                                 HorzLineFlat(y0, x1, x0, colour);
8267                 }
8268                 else
8269                 {
8270                         if (dx < 0)
8271                         {
8272                                 xt = x0;
8273                                 yt = y0;
8274                                 x0 = x1;
8275                                 y0 = y1;
8276                                 x1 = xt;
8277                                 y1 = yt;
8278
8279                                 dx = x1 - x0;
8280                                 dy = y1 - y0;
8281                         }
8282
8283                         m = dy/dx;
8284
8285                         if (m >= 0)
8286                         {
8287                                 if (m > 1)
8288                                         Line_S_SE_Flat(x0, y0, x1, y1, colour);
8289                                 else
8290                                         Line_E_SE_Flat(x0, y0, x1, y1, colour);
8291                         }
8292                         else
8293                                 if (m < -1)
8294                                         Line_N_NE_Flat(x0, y0, x1, y1, colour);
8295                                 else
8296                                         Line_E_NE_Flat(x0, y0, x1, y1, colour);
8297                 }
8298 }
8299
8300 ///////////////////////////////////////////////////////////////////////