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