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