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