dfxvideo: massive cleanup
[pcsx_rearmed.git] / plugins / dfxvideo / soft.c
1 /***************************************************************************
2                           soft.c  -  description
3                              -------------------
4     begin                : Sun Oct 28 2001
5     copyright            : (C) 2001 by Pete Bernert
6     email                : BlackDove@addcom.de
7  ***************************************************************************/
8 /***************************************************************************
9  *                                                                         *
10  *   This program is free software; you can redistribute it and/or modify  *
11  *   it under the terms of the GNU General Public License as published by  *
12  *   the Free Software Foundation; either version 2 of the License, or     *
13  *   (at your option) any later version. See also the license.txt file for *
14  *   additional informations.                                              *
15  *                                                                         *
16  ***************************************************************************/
17
18 // switches for painting textured quads as 2 triangles (small glitches, but better shading!)
19 // can be toggled by game fix 0x200 in version 1.17 anyway, so let the defines enabled!
20 #define POLYQUAD3                 
21 #define POLYQUAD3GT                 
22
23 // fast solid loops... a bit more additional code, of course
24 #define FASTSOLID
25
26 // psx blending mode 3 with 25% incoming color (instead 50% without the define)
27 #define HALFBRIGHTMODE3
28
29 // color decode defines
30
31 #define XCOL1(x)     (x & 0x1f)
32 #define XCOL2(x)     (x & 0x3e0)
33 #define XCOL3(x)     (x & 0x7c00)
34
35 #define XCOL1D(x)     (x & 0x1f)
36 #define XCOL2D(x)     ((x>>5) & 0x1f)
37 #define XCOL3D(x)     ((x>>10) & 0x1f)
38
39 #define X32TCOL1(x)  ((x & 0x001f001f)<<7)
40 #define X32TCOL2(x)  ((x & 0x03e003e0)<<2)
41 #define X32TCOL3(x)  ((x & 0x7c007c00)>>3)
42
43 #define X32COL1(x)   (x & 0x001f001f)
44 #define X32COL2(x)   ((x>>5) & 0x001f001f)
45 #define X32COL3(x)   ((x>>10) & 0x001f001f)
46
47 #define X32ACOL1(x)  (x & 0x001e001e)
48 #define X32ACOL2(x)  ((x>>5) & 0x001e001e)
49 #define X32ACOL3(x)  ((x>>10) & 0x001e001e)
50
51 #define X32BCOL1(x)  (x & 0x001c001c)
52 #define X32BCOL2(x)  ((x>>5) & 0x001c001c)
53 #define X32BCOL3(x)  ((x>>10) & 0x001c001c)
54
55 #define X32PSXCOL(r,g,b) ((g<<10)|(b<<5)|r)
56
57 #define XPSXCOL(r,g,b) ((g&0x7c00)|(b&0x3e0)|(r&0x1f))
58
59 // soft globals
60 short g_m1=255,g_m2=255,g_m3=255;
61 short DrawSemiTrans=FALSE;
62 short Ymin;
63 short Ymax;
64 short          ly0,lx0,ly1,lx1,ly2,lx2,ly3,lx3;        // global psx vertex coords
65 int32_t           GlobalTextAddrX,GlobalTextAddrY,GlobalTextTP,GlobalTextIL;
66 int32_t           GlobalTextREST,GlobalTextABR,GlobalTextPAGE;
67
68 ////////////////////////////////////////////////////////////////////////
69 // POLYGON OFFSET FUNCS
70 ////////////////////////////////////////////////////////////////////////
71
72 static void offsetPSX2(void)
73 {
74  lx0 += PSXDisplay.DrawOffset.x;
75  ly0 += PSXDisplay.DrawOffset.y;
76  lx1 += PSXDisplay.DrawOffset.x;
77  ly1 += PSXDisplay.DrawOffset.y;
78 }
79
80 static void offsetPSX3(void)
81 {
82  lx0 += PSXDisplay.DrawOffset.x;
83  ly0 += PSXDisplay.DrawOffset.y;
84  lx1 += PSXDisplay.DrawOffset.x;
85  ly1 += PSXDisplay.DrawOffset.y;
86  lx2 += PSXDisplay.DrawOffset.x;
87  ly2 += PSXDisplay.DrawOffset.y;
88 }
89
90 static void offsetPSX4(void)
91 {
92  lx0 += PSXDisplay.DrawOffset.x;
93  ly0 += PSXDisplay.DrawOffset.y;
94  lx1 += PSXDisplay.DrawOffset.x;
95  ly1 += PSXDisplay.DrawOffset.y;
96  lx2 += PSXDisplay.DrawOffset.x;
97  ly2 += PSXDisplay.DrawOffset.y;
98  lx3 += PSXDisplay.DrawOffset.x;
99  ly3 += PSXDisplay.DrawOffset.y;
100 }
101
102 /////////////////////////////////////////////////////////////////
103 /////////////////////////////////////////////////////////////////
104 /////////////////////////////////////////////////////////////////
105 // PER PIXEL FUNCS
106 ////////////////////////////////////////////////////////////////////////
107 /////////////////////////////////////////////////////////////////
108 /////////////////////////////////////////////////////////////////
109
110
111 unsigned char dithertable[16] =
112 {
113     7, 0, 6, 1,
114     2, 5, 3, 4,
115     1, 6, 0, 7,
116     4, 3, 5, 2
117 };
118
119 static inline void Dither16(unsigned short * pdest,uint32_t r,uint32_t g,uint32_t b,unsigned short sM)
120 {
121  unsigned char coeff;
122  unsigned char rlow, glow, blow;
123  int x,y;
124                  
125  x=pdest-psxVuw;
126  y=x>>10;
127  x-=(y<<10);
128
129  coeff = dithertable[(y&3)*4+(x&3)];
130
131  rlow = r&7; glow = g&7; blow = b&7;
132
133  r>>=3; g>>=3; b>>=3;
134
135  if ((r < 0x1F) && rlow > coeff) r++;
136  if ((g < 0x1F) && glow > coeff) g++;
137  if ((b < 0x1F) && blow > coeff) b++;
138
139  PUTLE16(pdest, ((unsigned short)b<<10) |
140         ((unsigned short)g<<5) |
141         (unsigned short)r | sM);
142 }
143
144 /////////////////////////////////////////////////////////////////
145 /////////////////////////////////////////////////////////////////
146 /////////////////////////////////////////////////////////////////
147
148 static inline void GetShadeTransCol_Dither(unsigned short * pdest, int32_t m1, int32_t m2, int32_t m3)
149 {
150  int32_t r,g,b;
151
152  if(bCheckMask && (*pdest & HOST2LE16(0x8000))) return;
153
154  if(DrawSemiTrans)
155   {
156    r=((XCOL1D(GETLE16(pdest)))<<3);
157    b=((XCOL2D(GETLE16(pdest)))<<3);
158    g=((XCOL3D(GETLE16(pdest)))<<3);
159
160    if(GlobalTextABR==0)
161     {
162      r=(r>>1)+(m1>>1);
163      b=(b>>1)+(m2>>1);
164      g=(g>>1)+(m3>>1);
165     }
166    else
167    if(GlobalTextABR==1)
168     {
169      r+=m1;
170      b+=m2;
171      g+=m3;
172     }
173    else
174    if(GlobalTextABR==2)
175     {
176      r-=m1;
177      b-=m2;
178      g-=m3;
179      if(r&0x80000000) r=0;
180      if(b&0x80000000) b=0;
181      if(g&0x80000000) g=0;
182     }
183    else
184     {
185 #ifdef HALFBRIGHTMODE3
186      r+=(m1>>2);
187      b+=(m2>>2);
188      g+=(m3>>2);
189 #else
190      r+=(m1>>1);
191      b+=(m2>>1);
192      g+=(m3>>1);
193 #endif
194     }
195   }
196  else 
197   {
198    r=m1;
199    b=m2;
200    g=m3;
201   }
202
203  if(r&0x7FFFFF00) r=0xff;
204  if(b&0x7FFFFF00) b=0xff;
205  if(g&0x7FFFFF00) g=0xff;
206
207  Dither16(pdest,r,b,g,sSetMask);
208 }
209
210 ////////////////////////////////////////////////////////////////////////
211
212 static inline void GetShadeTransCol(unsigned short * pdest,unsigned short color)
213 {
214  if(bCheckMask && (*pdest & HOST2LE16(0x8000))) return;
215
216  if(DrawSemiTrans)
217   {
218    int32_t r,g,b;
219  
220    if(GlobalTextABR==0)
221     {
222      PUTLE16(pdest, (((GETLE16(pdest)&0x7bde)>>1)+(((color)&0x7bde)>>1))|sSetMask);//0x8000;
223      return;
224     }
225    else
226    if(GlobalTextABR==1)
227     {
228      r=(XCOL1(GETLE16(pdest)))+((XCOL1(color)));
229      b=(XCOL2(GETLE16(pdest)))+((XCOL2(color)));
230      g=(XCOL3(GETLE16(pdest)))+((XCOL3(color)));
231     }
232    else
233    if(GlobalTextABR==2)
234     {
235      r=(XCOL1(GETLE16(pdest)))-((XCOL1(color)));
236      b=(XCOL2(GETLE16(pdest)))-((XCOL2(color)));
237      g=(XCOL3(GETLE16(pdest)))-((XCOL3(color)));
238      if(r&0x80000000) r=0;
239      if(b&0x80000000) b=0;
240      if(g&0x80000000) g=0;
241    }
242    else
243     {
244 #ifdef HALFBRIGHTMODE3
245      r=(XCOL1(GETLE16(pdest)))+((XCOL1(color))>>2);
246      b=(XCOL2(GETLE16(pdest)))+((XCOL2(color))>>2);
247      g=(XCOL3(GETLE16(pdest)))+((XCOL3(color))>>2);
248 #else
249      r=(XCOL1(GETLE16(pdest)))+((XCOL1(color))>>1);
250      b=(XCOL2(GETLE16(pdest)))+((XCOL2(color))>>1);
251      g=(XCOL3(GETLE16(pdest)))+((XCOL3(color))>>1);
252 #endif
253     }
254
255    if(r&0x7FFFFFE0) r=0x1f;
256    if(b&0x7FFFFC00) b=0x3e0;
257    if(g&0x7FFF8000) g=0x7c00;
258
259    PUTLE16(pdest, (XPSXCOL(r,g,b))|sSetMask);//0x8000;
260   }
261  else PUTLE16(pdest, color|sSetMask);
262 }  
263
264 ////////////////////////////////////////////////////////////////////////
265
266 static inline void GetShadeTransCol32(uint32_t * pdest,uint32_t color)
267 {
268  if(DrawSemiTrans)
269   {
270    int32_t r,g,b;
271  
272    if(GlobalTextABR==0)
273     {
274      if(!bCheckMask)
275       {
276        PUTLE32(pdest, (((GETLE32(pdest)&0x7bde7bde)>>1)+(((color)&0x7bde7bde)>>1))|lSetMask);//0x80008000;
277        return;
278       }
279      r=(X32ACOL1(GETLE32(pdest))>>1)+((X32ACOL1(color))>>1);
280      b=(X32ACOL2(GETLE32(pdest))>>1)+((X32ACOL2(color))>>1);
281      g=(X32ACOL3(GETLE32(pdest))>>1)+((X32ACOL3(color))>>1);
282     }
283    else
284    if(GlobalTextABR==1)
285     {
286      r=(X32COL1(GETLE32(pdest)))+((X32COL1(color)));
287      b=(X32COL2(GETLE32(pdest)))+((X32COL2(color)));
288      g=(X32COL3(GETLE32(pdest)))+((X32COL3(color)));
289     }
290    else
291    if(GlobalTextABR==2)
292     {
293      int32_t sr,sb,sg,src,sbc,sgc,c;
294      src=XCOL1(color);sbc=XCOL2(color);sgc=XCOL3(color);
295      c=GETLE32(pdest)>>16;
296      sr=(XCOL1(c))-src;   if(sr&0x8000) sr=0;
297      sb=(XCOL2(c))-sbc;  if(sb&0x8000) sb=0;
298      sg=(XCOL3(c))-sgc; if(sg&0x8000) sg=0;
299      r=((int32_t)sr)<<16;b=((int32_t)sb)<<11;g=((int32_t)sg)<<6;
300      c=LOWORD(GETLE32(pdest));
301      sr=(XCOL1(c))-src;   if(sr&0x8000) sr=0;
302      sb=(XCOL2(c))-sbc;  if(sb&0x8000) sb=0;
303      sg=(XCOL3(c))-sgc; if(sg&0x8000) sg=0;
304      r|=sr;b|=sb>>5;g|=sg>>10;
305     }
306    else
307     {
308 #ifdef HALFBRIGHTMODE3
309      r=(X32COL1(GETLE32(pdest)))+((X32BCOL1(color))>>2);
310      b=(X32COL2(GETLE32(pdest)))+((X32BCOL2(color))>>2);
311      g=(X32COL3(GETLE32(pdest)))+((X32BCOL3(color))>>2);
312 #else
313      r=(X32COL1(GETLE32(pdest)))+((X32ACOL1(color))>>1);
314      b=(X32COL2(GETLE32(pdest)))+((X32ACOL2(color))>>1);
315      g=(X32COL3(GETLE32(pdest)))+((X32ACOL3(color))>>1);
316 #endif
317     }
318
319    if(r&0x7FE00000) r=0x1f0000|(r&0xFFFF);
320    if(r&0x7FE0)     r=0x1f    |(r&0xFFFF0000);
321    if(b&0x7FE00000) b=0x1f0000|(b&0xFFFF);
322    if(b&0x7FE0)     b=0x1f    |(b&0xFFFF0000);
323    if(g&0x7FE00000) g=0x1f0000|(g&0xFFFF);
324    if(g&0x7FE0)     g=0x1f    |(g&0xFFFF0000);
325
326    if(bCheckMask) 
327     {
328      uint32_t ma=GETLE32(pdest);
329      PUTLE32(pdest, (X32PSXCOL(r,g,b))|lSetMask);//0x80008000;
330      if(ma&0x80000000) PUTLE32(pdest, (ma&0xFFFF0000)|(*pdest&0xFFFF));
331      if(ma&0x00008000) PUTLE32(pdest, (ma&0xFFFF)    |(*pdest&0xFFFF0000));
332      return;
333     }
334    PUTLE32(pdest, (X32PSXCOL(r,g,b))|lSetMask);//0x80008000;
335   }
336  else 
337   {
338    if(bCheckMask) 
339     {
340      uint32_t ma=GETLE32(pdest);
341      PUTLE32(pdest, color|lSetMask);//0x80008000;
342      if(ma&0x80000000) PUTLE32(pdest, (ma&0xFFFF0000)|(GETLE32(pdest)&0xFFFF));
343      if(ma&0x00008000) PUTLE32(pdest, (ma&0xFFFF)    |(GETLE32(pdest)&0xFFFF0000));
344      return;
345     }
346
347    PUTLE32(pdest, color|lSetMask);//0x80008000;
348   }
349 }  
350
351 ////////////////////////////////////////////////////////////////////////
352
353 static inline void GetTextureTransColG(unsigned short * pdest,unsigned short color)
354 {
355  int32_t r,g,b;unsigned short l;
356
357  if(color==0) return;
358
359  if(bCheckMask && (*pdest & HOST2LE16(0x8000))) return;
360
361  l=sSetMask|(color&0x8000);
362
363  if(DrawSemiTrans && (color&0x8000))
364   {
365    if(GlobalTextABR==0)
366     {
367      unsigned short d;
368      d     =(GETLE16(pdest)&0x7bde)>>1;
369      color =((color) &0x7bde)>>1;
370      r=(XCOL1(d))+((((XCOL1(color)))* g_m1)>>7);
371      b=(XCOL2(d))+((((XCOL2(color)))* g_m2)>>7);
372      g=(XCOL3(d))+((((XCOL3(color)))* g_m3)>>7);
373     }
374    else
375    if(GlobalTextABR==1)
376     {
377      r=(XCOL1(GETLE16(pdest)))+((((XCOL1(color)))* g_m1)>>7);
378      b=(XCOL2(GETLE16(pdest)))+((((XCOL2(color)))* g_m2)>>7);
379      g=(XCOL3(GETLE16(pdest)))+((((XCOL3(color)))* g_m3)>>7);
380     }
381    else
382    if(GlobalTextABR==2)
383     {
384      r=(XCOL1(GETLE16(pdest)))-((((XCOL1(color)))* g_m1)>>7);
385      b=(XCOL2(GETLE16(pdest)))-((((XCOL2(color)))* g_m2)>>7);
386      g=(XCOL3(GETLE16(pdest)))-((((XCOL3(color)))* g_m3)>>7);
387      if(r&0x80000000) r=0;
388      if(b&0x80000000) b=0;
389      if(g&0x80000000) g=0;
390     }
391    else
392     {
393 #ifdef HALFBRIGHTMODE3
394      r=(XCOL1(GETLE16(pdest)))+((((XCOL1(color))>>2)* g_m1)>>7);
395      b=(XCOL2(GETLE16(pdest)))+((((XCOL2(color))>>2)* g_m2)>>7);
396      g=(XCOL3(GETLE16(pdest)))+((((XCOL3(color))>>2)* g_m3)>>7);
397 #else
398      r=(XCOL1(GETLE16(pdest)))+((((XCOL1(color))>>1)* g_m1)>>7);
399      b=(XCOL2(GETLE16(pdest)))+((((XCOL2(color))>>1)* g_m2)>>7);
400      g=(XCOL3(GETLE16(pdest)))+((((XCOL3(color))>>1)* g_m3)>>7);
401 #endif
402     }
403   }
404  else 
405   {
406    r=((XCOL1(color))* g_m1)>>7;
407    b=((XCOL2(color))* g_m2)>>7;
408    g=((XCOL3(color))* g_m3)>>7;
409   }
410
411  if(r&0x7FFFFFE0) r=0x1f;
412  if(b&0x7FFFFC00) b=0x3e0;
413  if(g&0x7FFF8000) g=0x7c00;
414
415  PUTLE16(pdest, (XPSXCOL(r,g,b))|l);
416 }
417
418 ////////////////////////////////////////////////////////////////////////
419
420 static inline void GetTextureTransColG_S(unsigned short * pdest,unsigned short color)
421 {
422  int32_t r,g,b;unsigned short l;
423
424  if(color==0) return;
425
426  l=sSetMask|(color&0x8000);
427
428  r=((XCOL1(color))* g_m1)>>7;
429  b=((XCOL2(color))* g_m2)>>7;
430  g=((XCOL3(color))* g_m3)>>7;
431
432  if(r&0x7FFFFFE0) r=0x1f;
433  if(b&0x7FFFFC00) b=0x3e0;
434  if(g&0x7FFF8000) g=0x7c00;
435
436  PUTLE16(pdest, (XPSXCOL(r,g,b))|l);
437 }
438
439 ////////////////////////////////////////////////////////////////////////
440
441 static inline void GetTextureTransColG_SPR(unsigned short * pdest,unsigned short color)
442 {
443  int32_t r,g,b;unsigned short l;
444
445  if(color==0) return;
446
447  if(bCheckMask && (GETLE16(pdest) & 0x8000)) return;
448
449  l=sSetMask|(color&0x8000);
450
451  if(DrawSemiTrans && (color&0x8000))
452   {
453    if(GlobalTextABR==0)
454     {
455      unsigned short d;
456      d     =(GETLE16(pdest)&0x7bde)>>1;
457      color =((color) &0x7bde)>>1;
458      r=(XCOL1(d))+((((XCOL1(color)))* g_m1)>>7);
459      b=(XCOL2(d))+((((XCOL2(color)))* g_m2)>>7);
460      g=(XCOL3(d))+((((XCOL3(color)))* g_m3)>>7);
461     }
462    else
463    if(GlobalTextABR==1)
464     {
465      r=(XCOL1(GETLE16(pdest)))+((((XCOL1(color)))* g_m1)>>7);
466      b=(XCOL2(GETLE16(pdest)))+((((XCOL2(color)))* g_m2)>>7);
467      g=(XCOL3(GETLE16(pdest)))+((((XCOL3(color)))* g_m3)>>7);
468     }
469    else
470    if(GlobalTextABR==2)
471     {
472      r=(XCOL1(GETLE16(pdest)))-((((XCOL1(color)))* g_m1)>>7);
473      b=(XCOL2(GETLE16(pdest)))-((((XCOL2(color)))* g_m2)>>7);
474      g=(XCOL3(GETLE16(pdest)))-((((XCOL3(color)))* g_m3)>>7);
475      if(r&0x80000000) r=0;
476      if(b&0x80000000) b=0;
477      if(g&0x80000000) g=0;
478     }
479    else
480     {
481 #ifdef HALFBRIGHTMODE3
482      r=(XCOL1(GETLE16(pdest)))+((((XCOL1(color))>>2)* g_m1)>>7);
483      b=(XCOL2(GETLE16(pdest)))+((((XCOL2(color))>>2)* g_m2)>>7);
484      g=(XCOL3(GETLE16(pdest)))+((((XCOL3(color))>>2)* g_m3)>>7);
485 #else
486      r=(XCOL1(GETLE16(pdest)))+((((XCOL1(color))>>1)* g_m1)>>7);
487      b=(XCOL2(GETLE16(pdest)))+((((XCOL2(color))>>1)* g_m2)>>7);
488      g=(XCOL3(GETLE16(pdest)))+((((XCOL3(color))>>1)* g_m3)>>7);
489 #endif
490     }
491   }
492  else 
493   {
494    r=((XCOL1(color))* g_m1)>>7;
495    b=((XCOL2(color))* g_m2)>>7;
496    g=((XCOL3(color))* g_m3)>>7;
497   }
498
499  if(r&0x7FFFFFE0) r=0x1f;
500  if(b&0x7FFFFC00) b=0x3e0;
501  if(g&0x7FFF8000) g=0x7c00;
502
503  PUTLE16(pdest, (XPSXCOL(r,g,b))|l);
504 }
505
506 ////////////////////////////////////////////////////////////////////////
507
508 static inline void GetTextureTransColG32(uint32_t * pdest,uint32_t color)
509 {
510  int32_t r,g,b,l;
511
512  if(color==0) return;
513
514  l=lSetMask|(color&0x80008000);
515
516  if(DrawSemiTrans && (color&0x80008000))
517   {
518    if(GlobalTextABR==0)
519     {                 
520      r=((((X32TCOL1(GETLE32(pdest)))+((X32COL1(color)) * g_m1))&0xFF00FF00)>>8);
521      b=((((X32TCOL2(GETLE32(pdest)))+((X32COL2(color)) * g_m2))&0xFF00FF00)>>8);
522      g=((((X32TCOL3(GETLE32(pdest)))+((X32COL3(color)) * g_m3))&0xFF00FF00)>>8);
523     }
524    else
525    if(GlobalTextABR==1)
526     {
527      r=(X32COL1(GETLE32(pdest)))+(((((X32COL1(color)))* g_m1)&0xFF80FF80)>>7);
528      b=(X32COL2(GETLE32(pdest)))+(((((X32COL2(color)))* g_m2)&0xFF80FF80)>>7);
529      g=(X32COL3(GETLE32(pdest)))+(((((X32COL3(color)))* g_m3)&0xFF80FF80)>>7);
530     }
531    else
532    if(GlobalTextABR==2)
533     {
534      int32_t t;
535      r=(((((X32COL1(color)))* g_m1)&0xFF80FF80)>>7);
536      t=(GETLE32(pdest)&0x001f0000)-(r&0x003f0000); if(t&0x80000000) t=0;
537      r=(GETLE32(pdest)&0x0000001f)-(r&0x0000003f); if(r&0x80000000) r=0;
538      r|=t;
539
540      b=(((((X32COL2(color)))* g_m2)&0xFF80FF80)>>7);
541      t=((GETLE32(pdest)>>5)&0x001f0000)-(b&0x003f0000); if(t&0x80000000) t=0;
542      b=((GETLE32(pdest)>>5)&0x0000001f)-(b&0x0000003f); if(b&0x80000000) b=0;
543      b|=t;
544
545      g=(((((X32COL3(color)))* g_m3)&0xFF80FF80)>>7);
546      t=((GETLE32(pdest)>>10)&0x001f0000)-(g&0x003f0000); if(t&0x80000000) t=0;
547      g=((GETLE32(pdest)>>10)&0x0000001f)-(g&0x0000003f); if(g&0x80000000) g=0;
548      g|=t;
549     }
550    else
551     {
552 #ifdef HALFBRIGHTMODE3
553      r=(X32COL1(GETLE32(pdest)))+(((((X32BCOL1(color))>>2)* g_m1)&0xFF80FF80)>>7);
554      b=(X32COL2(GETLE32(pdest)))+(((((X32BCOL2(color))>>2)* g_m2)&0xFF80FF80)>>7);
555      g=(X32COL3(GETLE32(pdest)))+(((((X32BCOL3(color))>>2)* g_m3)&0xFF80FF80)>>7);
556 #else
557      r=(X32COL1(GETLE32(pdest)))+(((((X32ACOL1(color))>>1)* g_m1)&0xFF80FF80)>>7);
558      b=(X32COL2(GETLE32(pdest)))+(((((X32ACOL2(color))>>1)* g_m2)&0xFF80FF80)>>7);
559      g=(X32COL3(GETLE32(pdest)))+(((((X32ACOL3(color))>>1)* g_m3)&0xFF80FF80)>>7);
560 #endif
561     }
562
563    if(!(color&0x8000))
564     {
565      r=(r&0xffff0000)|((((X32COL1(color))* g_m1)&0x0000FF80)>>7);
566      b=(b&0xffff0000)|((((X32COL2(color))* g_m2)&0x0000FF80)>>7);
567      g=(g&0xffff0000)|((((X32COL3(color))* g_m3)&0x0000FF80)>>7);
568     }
569    if(!(color&0x80000000))
570     {
571      r=(r&0xffff)|((((X32COL1(color))* g_m1)&0xFF800000)>>7);
572      b=(b&0xffff)|((((X32COL2(color))* g_m2)&0xFF800000)>>7);
573      g=(g&0xffff)|((((X32COL3(color))* g_m3)&0xFF800000)>>7);
574     }
575
576   }
577  else 
578   {
579    r=(((X32COL1(color))* g_m1)&0xFF80FF80)>>7;
580    b=(((X32COL2(color))* g_m2)&0xFF80FF80)>>7;
581    g=(((X32COL3(color))* g_m3)&0xFF80FF80)>>7;
582   }
583
584  if(r&0x7FE00000) r=0x1f0000|(r&0xFFFF);
585  if(r&0x7FE0)     r=0x1f    |(r&0xFFFF0000);
586  if(b&0x7FE00000) b=0x1f0000|(b&0xFFFF);
587  if(b&0x7FE0)     b=0x1f    |(b&0xFFFF0000);
588  if(g&0x7FE00000) g=0x1f0000|(g&0xFFFF);
589  if(g&0x7FE0)     g=0x1f    |(g&0xFFFF0000);
590          
591  if(bCheckMask) 
592   {
593    uint32_t ma=GETLE32(pdest);
594
595    PUTLE32(pdest, (X32PSXCOL(r,g,b))|l);
596    
597    if((color&0xffff)==0    ) PUTLE32(pdest, (ma&0xffff)|(GETLE32(pdest)&0xffff0000));
598    if((color&0xffff0000)==0) PUTLE32(pdest, (ma&0xffff0000)|(GETLE32(pdest)&0xffff));
599    if(ma&0x80000000) PUTLE32(pdest, (ma&0xFFFF0000)|(GETLE32(pdest)&0xFFFF));
600    if(ma&0x00008000) PUTLE32(pdest, (ma&0xFFFF)    |(GETLE32(pdest)&0xFFFF0000));
601
602    return;                            
603   }
604  if((color&0xffff)==0    ) {PUTLE32(pdest, (GETLE32(pdest)&0xffff)|(((X32PSXCOL(r,g,b))|l)&0xffff0000));return;}
605  if((color&0xffff0000)==0) {PUTLE32(pdest, (GETLE32(pdest)&0xffff0000)|(((X32PSXCOL(r,g,b))|l)&0xffff));return;}
606
607  PUTLE32(pdest, (X32PSXCOL(r,g,b))|l);
608 }
609
610 ////////////////////////////////////////////////////////////////////////
611
612 static inline void GetTextureTransColG32_S(uint32_t * pdest,uint32_t color)
613 {
614  int32_t r,g,b;
615
616  if(color==0) return;
617
618  r=(((X32COL1(color))* g_m1)&0xFF80FF80)>>7;
619  b=(((X32COL2(color))* g_m2)&0xFF80FF80)>>7;
620  g=(((X32COL3(color))* g_m3)&0xFF80FF80)>>7;
621
622  if(r&0x7FE00000) r=0x1f0000|(r&0xFFFF);
623  if(r&0x7FE0)     r=0x1f    |(r&0xFFFF0000);
624  if(b&0x7FE00000) b=0x1f0000|(b&0xFFFF);
625  if(b&0x7FE0)     b=0x1f    |(b&0xFFFF0000);
626  if(g&0x7FE00000) g=0x1f0000|(g&0xFFFF);
627  if(g&0x7FE0)     g=0x1f    |(g&0xFFFF0000);
628          
629  if((color&0xffff)==0)     {PUTLE32(pdest, (GETLE32(pdest)&0xffff)|(((X32PSXCOL(r,g,b))|lSetMask|(color&0x80008000))&0xffff0000));return;}
630  if((color&0xffff0000)==0) {PUTLE32(pdest, (GETLE32(pdest)&0xffff0000)|(((X32PSXCOL(r,g,b))|lSetMask|(color&0x80008000))&0xffff));return;}
631
632  PUTLE32(pdest, (X32PSXCOL(r,g,b))|lSetMask|(color&0x80008000));
633 }
634
635 ////////////////////////////////////////////////////////////////////////
636
637 static inline void GetTextureTransColG32_SPR(uint32_t * pdest,uint32_t color)
638 {
639  int32_t r,g,b;
640
641  if(color==0) return;
642
643  if(DrawSemiTrans && (color&0x80008000))
644   {
645    if(GlobalTextABR==0)
646     {                 
647      r=((((X32TCOL1(GETLE32(pdest)))+((X32COL1(color)) * g_m1))&0xFF00FF00)>>8);
648      b=((((X32TCOL2(GETLE32(pdest)))+((X32COL2(color)) * g_m2))&0xFF00FF00)>>8);
649      g=((((X32TCOL3(GETLE32(pdest)))+((X32COL3(color)) * g_m3))&0xFF00FF00)>>8);
650     }
651    else
652    if(GlobalTextABR==1)
653     {
654      r=(X32COL1(GETLE32(pdest)))+(((((X32COL1(color)))* g_m1)&0xFF80FF80)>>7);
655      b=(X32COL2(GETLE32(pdest)))+(((((X32COL2(color)))* g_m2)&0xFF80FF80)>>7);
656      g=(X32COL3(GETLE32(pdest)))+(((((X32COL3(color)))* g_m3)&0xFF80FF80)>>7);
657     }
658    else
659    if(GlobalTextABR==2)
660     {
661      int32_t t;
662      r=(((((X32COL1(color)))* g_m1)&0xFF80FF80)>>7);
663      t=(GETLE32(pdest)&0x001f0000)-(r&0x003f0000); if(t&0x80000000) t=0;
664      r=(GETLE32(pdest)&0x0000001f)-(r&0x0000003f); if(r&0x80000000) r=0;
665      r|=t;
666
667      b=(((((X32COL2(color)))* g_m2)&0xFF80FF80)>>7);
668      t=((GETLE32(pdest)>>5)&0x001f0000)-(b&0x003f0000); if(t&0x80000000) t=0;
669      b=((GETLE32(pdest)>>5)&0x0000001f)-(b&0x0000003f); if(b&0x80000000) b=0;
670      b|=t;
671
672      g=(((((X32COL3(color)))* g_m3)&0xFF80FF80)>>7);
673      t=((GETLE32(pdest)>>10)&0x001f0000)-(g&0x003f0000); if(t&0x80000000) t=0;
674      g=((GETLE32(pdest)>>10)&0x0000001f)-(g&0x0000003f); if(g&0x80000000) g=0;
675      g|=t;
676     }
677    else
678     {
679 #ifdef HALFBRIGHTMODE3
680      r=(X32COL1(GETLE32(pdest)))+(((((X32BCOL1(color))>>2)* g_m1)&0xFF80FF80)>>7);
681      b=(X32COL2(GETLE32(pdest)))+(((((X32BCOL2(color))>>2)* g_m2)&0xFF80FF80)>>7);
682      g=(X32COL3(GETLE32(pdest)))+(((((X32BCOL3(color))>>2)* g_m3)&0xFF80FF80)>>7);
683 #else
684      r=(X32COL1(GETLE32(pdest)))+(((((X32ACOL1(color))>>1)* g_m1)&0xFF80FF80)>>7);
685      b=(X32COL2(GETLE32(pdest)))+(((((X32ACOL2(color))>>1)* g_m2)&0xFF80FF80)>>7);
686      g=(X32COL3(GETLE32(pdest)))+(((((X32ACOL3(color))>>1)* g_m3)&0xFF80FF80)>>7);
687 #endif
688     }
689
690    if(!(color&0x8000))
691     {
692      r=(r&0xffff0000)|((((X32COL1(color))* g_m1)&0x0000FF80)>>7);
693      b=(b&0xffff0000)|((((X32COL2(color))* g_m2)&0x0000FF80)>>7);
694      g=(g&0xffff0000)|((((X32COL3(color))* g_m3)&0x0000FF80)>>7);
695     }
696    if(!(color&0x80000000))
697     {
698      r=(r&0xffff)|((((X32COL1(color))* g_m1)&0xFF800000)>>7);
699      b=(b&0xffff)|((((X32COL2(color))* g_m2)&0xFF800000)>>7);
700      g=(g&0xffff)|((((X32COL3(color))* g_m3)&0xFF800000)>>7);
701     }
702
703   }
704  else 
705   {
706    r=(((X32COL1(color))* g_m1)&0xFF80FF80)>>7;
707    b=(((X32COL2(color))* g_m2)&0xFF80FF80)>>7;
708    g=(((X32COL3(color))* g_m3)&0xFF80FF80)>>7;
709   }
710
711  if(r&0x7FE00000) r=0x1f0000|(r&0xFFFF);
712  if(r&0x7FE0)     r=0x1f    |(r&0xFFFF0000);
713  if(b&0x7FE00000) b=0x1f0000|(b&0xFFFF);
714  if(b&0x7FE0)     b=0x1f    |(b&0xFFFF0000);
715  if(g&0x7FE00000) g=0x1f0000|(g&0xFFFF);
716  if(g&0x7FE0)     g=0x1f    |(g&0xFFFF0000);
717          
718  if(bCheckMask) 
719   {
720    uint32_t ma=GETLE32(pdest);
721
722    PUTLE32(pdest, (X32PSXCOL(r,g,b))|lSetMask|(color&0x80008000));
723    
724    if((color&0xffff)==0    ) PUTLE32(pdest, (ma&0xffff)|(GETLE32(pdest)&0xffff0000));
725    if((color&0xffff0000)==0) PUTLE32(pdest, (ma&0xffff0000)|(GETLE32(pdest)&0xffff));
726    if(ma&0x80000000) PUTLE32(pdest, (ma&0xFFFF0000)|(GETLE32(pdest)&0xFFFF));
727    if(ma&0x00008000) PUTLE32(pdest, (ma&0xFFFF)    |(GETLE32(pdest)&0xFFFF0000));
728
729    return;                            
730   }
731  if((color&0xffff)==0    ) {PUTLE32(pdest, (GETLE32(pdest)&0xffff)|(((X32PSXCOL(r,g,b))|lSetMask|(color&0x80008000))&0xffff0000));return;}
732  if((color&0xffff0000)==0) {PUTLE32(pdest, (GETLE32(pdest)&0xffff0000)|(((X32PSXCOL(r,g,b))|lSetMask|(color&0x80008000))&0xffff));return;}
733
734  PUTLE32(pdest, (X32PSXCOL(r,g,b))|lSetMask|(color&0x80008000));
735 }
736
737 ////////////////////////////////////////////////////////////////////////
738
739 static inline void GetTextureTransColGX_Dither(unsigned short * pdest,unsigned short color,int32_t m1,int32_t m2,int32_t m3)
740 {
741  int32_t r,g,b;
742
743  if(color==0) return;
744  
745  if(bCheckMask && (*pdest & HOST2LE16(0x8000))) return;
746
747  m1=(((XCOL1D(color)))*m1)>>4;
748  m2=(((XCOL2D(color)))*m2)>>4;
749  m3=(((XCOL3D(color)))*m3)>>4;
750
751  if(DrawSemiTrans && (color&0x8000))
752   {
753    r=((XCOL1D(GETLE16(pdest)))<<3);
754    b=((XCOL2D(GETLE16(pdest)))<<3);
755    g=((XCOL3D(GETLE16(pdest)))<<3);
756
757    if(GlobalTextABR==0)
758     {
759      r=(r>>1)+(m1>>1);
760      b=(b>>1)+(m2>>1);
761      g=(g>>1)+(m3>>1);
762     }
763    else
764    if(GlobalTextABR==1)
765     {
766      r+=m1;
767      b+=m2;
768      g+=m3;
769     }
770    else
771    if(GlobalTextABR==2)
772     {
773      r-=m1;
774      b-=m2;
775      g-=m3;
776      if(r&0x80000000) r=0;
777      if(b&0x80000000) b=0;
778      if(g&0x80000000) g=0;
779     }
780    else
781     {
782 #ifdef HALFBRIGHTMODE3
783      r+=(m1>>2);
784      b+=(m2>>2);
785      g+=(m3>>2);
786 #else
787      r+=(m1>>1);
788      b+=(m2>>1);
789      g+=(m3>>1);
790 #endif
791     }
792   }
793  else 
794   {
795    r=m1;
796    b=m2;
797    g=m3;
798   }
799
800  if(r&0x7FFFFF00) r=0xff;
801  if(b&0x7FFFFF00) b=0xff;
802  if(g&0x7FFFFF00) g=0xff;
803
804  Dither16(pdest,r,b,g,sSetMask|(color&0x8000));
805
806 }
807
808 ////////////////////////////////////////////////////////////////////////
809
810 static inline void GetTextureTransColGX(unsigned short * pdest,unsigned short color,short m1,short m2,short m3)
811 {
812  int32_t r,g,b;unsigned short l;
813
814  if(color==0) return;
815  
816  if(bCheckMask && (*pdest & HOST2LE16(0x8000))) return;
817
818  l=sSetMask|(color&0x8000);
819
820  if(DrawSemiTrans && (color&0x8000))
821   {
822    if(GlobalTextABR==0)
823     {
824      unsigned short d;
825      d     =(GETLE16(pdest)&0x7bde)>>1;
826      color =((color) &0x7bde)>>1;
827      r=(XCOL1(d))+((((XCOL1(color)))* m1)>>7);
828      b=(XCOL2(d))+((((XCOL2(color)))* m2)>>7);
829      g=(XCOL3(d))+((((XCOL3(color)))* m3)>>7);
830     }
831    else
832    if(GlobalTextABR==1)
833     {
834      r=(XCOL1(GETLE16(pdest)))+((((XCOL1(color)))* m1)>>7);
835      b=(XCOL2(GETLE16(pdest)))+((((XCOL2(color)))* m2)>>7);
836      g=(XCOL3(GETLE16(pdest)))+((((XCOL3(color)))* m3)>>7);
837     }
838    else
839    if(GlobalTextABR==2)
840     {
841      r=(XCOL1(GETLE16(pdest)))-((((XCOL1(color)))* m1)>>7);
842      b=(XCOL2(GETLE16(pdest)))-((((XCOL2(color)))* m2)>>7);
843      g=(XCOL3(GETLE16(pdest)))-((((XCOL3(color)))* m3)>>7);
844      if(r&0x80000000) r=0;
845      if(b&0x80000000) b=0;
846      if(g&0x80000000) g=0;
847     }
848    else
849     {
850 #ifdef HALFBRIGHTMODE3
851      r=(XCOL1(GETLE16(pdest)))+((((XCOL1(color))>>2)* m1)>>7);
852      b=(XCOL2(GETLE16(pdest)))+((((XCOL2(color))>>2)* m2)>>7);
853      g=(XCOL3(GETLE16(pdest)))+((((XCOL3(color))>>2)* m3)>>7);
854 #else
855      r=(XCOL1(GETLE16(pdest)))+((((XCOL1(color))>>1)* m1)>>7);
856      b=(XCOL2(GETLE16(pdest)))+((((XCOL2(color))>>1)* m2)>>7);
857      g=(XCOL3(GETLE16(pdest)))+((((XCOL3(color))>>1)* m3)>>7);
858 #endif
859     }
860   }
861  else 
862   {
863    r=((XCOL1(color))* m1)>>7;
864    b=((XCOL2(color))* m2)>>7;
865    g=((XCOL3(color))* m3)>>7;
866   }
867
868  if(r&0x7FFFFFE0) r=0x1f;
869  if(b&0x7FFFFC00) b=0x3e0;
870  if(g&0x7FFF8000) g=0x7c00;
871
872  PUTLE16(pdest, (XPSXCOL(r,g,b))|l);
873 }
874
875 ////////////////////////////////////////////////////////////////////////
876
877 static inline void GetTextureTransColGX_S(unsigned short * pdest,unsigned short color,short m1,short m2,short m3)
878 {
879  int32_t r,g,b;
880
881  if(color==0) return;
882  
883  r=((XCOL1(color))* m1)>>7;
884  b=((XCOL2(color))* m2)>>7;
885  g=((XCOL3(color))* m3)>>7;
886
887  if(r&0x7FFFFFE0) r=0x1f;
888  if(b&0x7FFFFC00) b=0x3e0;
889  if(g&0x7FFF8000) g=0x7c00;
890
891  PUTLE16(pdest, (XPSXCOL(r,g,b))|sSetMask|(color&0x8000));
892 }
893
894 ////////////////////////////////////////////////////////////////////////
895
896 static inline void GetTextureTransColGX32_S(uint32_t * pdest,uint32_t color,short m1,short m2,short m3)
897 {
898  int32_t r,g,b;
899  
900  if(color==0) return;
901
902  r=(((X32COL1(color))* m1)&0xFF80FF80)>>7;
903  b=(((X32COL2(color))* m2)&0xFF80FF80)>>7;
904  g=(((X32COL3(color))* m3)&0xFF80FF80)>>7;
905                 
906  if(r&0x7FE00000) r=0x1f0000|(r&0xFFFF);
907  if(r&0x7FE0)     r=0x1f    |(r&0xFFFF0000);
908  if(b&0x7FE00000) b=0x1f0000|(b&0xFFFF);
909  if(b&0x7FE0)     b=0x1f    |(b&0xFFFF0000);
910  if(g&0x7FE00000) g=0x1f0000|(g&0xFFFF);
911  if(g&0x7FE0)     g=0x1f    |(g&0xFFFF0000);
912
913  if((color&0xffff)==0)     {PUTLE32(pdest, (GETLE32(pdest)&0xffff)|(((X32PSXCOL(r,g,b))|lSetMask|(color&0x80008000))&0xffff0000));return;}
914  if((color&0xffff0000)==0) {PUTLE32(pdest, (GETLE32(pdest)&0xffff0000)|(((X32PSXCOL(r,g,b))|lSetMask|(color&0x80008000))&0xffff));return;}
915
916  PUTLE32(pdest, (X32PSXCOL(r,g,b))|lSetMask|(color&0x80008000));
917 }
918
919 ////////////////////////////////////////////////////////////////////////
920 // FILL FUNCS
921 ////////////////////////////////////////////////////////////////////////
922
923 static void FillSoftwareAreaTrans(short x0,short y0,short x1, // FILL AREA TRANS
924                       short y1,unsigned short col)
925 {
926  short j,i,dx,dy;
927
928  if(y0>y1) return;
929  if(x0>x1) return;
930
931  if(x1<drawX) return;
932  if(y1<drawY) return;
933  if(x0>drawW) return;
934  if(y0>drawH) return;
935
936  x1=min(x1,drawW+1);
937  y1=min(y1,drawH+1);
938  x0=max(x0,drawX);
939  y0=max(y0,drawY);
940     
941  if(y0>=512)   return;
942  if(x0>1023)          return;
943
944  if(y1>512) y1=512;
945  if(x1>1024)       x1=1024;
946
947  dx=x1-x0;dy=y1-y0;
948
949  if(dx==1 && dy==1 && x0==1020 && y0==511)             // special fix for pinball game... emu protection???
950   {
951    static int iCheat=0;
952    col+=iCheat;
953    if(iCheat==1) iCheat=0; else iCheat=1;
954   }
955
956
957  if(dx&1)                                              // slow fill
958   {
959    unsigned short *DSTPtr;
960    unsigned short LineOffset;
961    DSTPtr = psxVuw + (1024*y0) + x0;
962    LineOffset = 1024 - dx;
963    for(i=0;i<dy;i++)
964     {
965      for(j=0;j<dx;j++)
966       GetShadeTransCol(DSTPtr++,col);
967      DSTPtr += LineOffset;
968     } 
969   }
970  else                                                  // fast fill
971   {
972    uint32_t *DSTPtr;
973    unsigned short LineOffset;
974    uint32_t lcol=lSetMask|(((uint32_t)(col))<<16)|col;
975    dx>>=1;
976    DSTPtr = (uint32_t *)(psxVuw + (1024*y0) + x0);
977    LineOffset = 512 - dx;
978
979    if(!bCheckMask && !DrawSemiTrans)
980     {
981      for(i=0;i<dy;i++)
982       {
983        for(j=0;j<dx;j++) { PUTLE32(DSTPtr, lcol); DSTPtr++; }
984        DSTPtr += LineOffset;
985       }
986     }
987    else
988     {
989      for(i=0;i<dy;i++)
990       {
991        for(j=0;j<dx;j++) 
992         GetShadeTransCol32(DSTPtr++,lcol);
993        DSTPtr += LineOffset;
994       } 
995     }
996   }
997 }
998
999 ////////////////////////////////////////////////////////////////////////
1000
1001 static void FillSoftwareArea(short x0,short y0,short x1,      // FILL AREA (BLK FILL)
1002                       short y1,unsigned short col)     // no draw area check here!
1003 {
1004  short j,i,dx,dy;
1005
1006  if(y0>y1) return;
1007  if(x0>x1) return;
1008     
1009  if(y0>=512)   return;
1010  if(x0>1023)          return;
1011
1012  if(y1>512) y1=512;
1013  if(x1>1024)       x1=1024;
1014
1015  dx=x1-x0;dy=y1-y0;
1016  if(dx&1)
1017   {
1018    unsigned short *DSTPtr;
1019    unsigned short LineOffset;
1020
1021    DSTPtr = psxVuw + (1024*y0) + x0;
1022    LineOffset = 1024 - dx;
1023
1024    for(i=0;i<dy;i++)
1025     {
1026      for(j=0;j<dx;j++) { PUTLE16(DSTPtr, col); DSTPtr++; }
1027      DSTPtr += LineOffset;
1028     } 
1029   }
1030  else
1031   {
1032    uint32_t *DSTPtr;
1033    unsigned short LineOffset;
1034    uint32_t lcol=(((int32_t)col)<<16)|col;
1035    dx>>=1;
1036    DSTPtr = (uint32_t *)(psxVuw + (1024*y0) + x0);
1037    LineOffset = 512 - dx;
1038
1039    for(i=0;i<dy;i++)
1040     {
1041      for(j=0;j<dx;j++) { PUTLE32(DSTPtr, lcol); DSTPtr++; }
1042      DSTPtr += LineOffset;
1043     } 
1044   }
1045 }
1046
1047 ////////////////////////////////////////////////////////////////////////
1048 ////////////////////////////////////////////////////////////////////////
1049 ////////////////////////////////////////////////////////////////////////
1050 // EDGE INTERPOLATION
1051 ////////////////////////////////////////////////////////////////////////
1052 ////////////////////////////////////////////////////////////////////////
1053 ////////////////////////////////////////////////////////////////////////
1054
1055 typedef struct SOFTVTAG
1056 {
1057  int x,y;   
1058  int u,v;
1059  int32_t R,G,B;
1060 } soft_vertex;
1061
1062 static soft_vertex vtx[4];
1063 static soft_vertex * left_array[4], * right_array[4];
1064 static int left_section, right_section;
1065 static int left_section_height, right_section_height;
1066 static int left_x, delta_left_x, right_x, delta_right_x;
1067 static int left_u, delta_left_u, left_v, delta_left_v;
1068 static int right_u, delta_right_u, right_v, delta_right_v;
1069 static int left_R, delta_left_R, right_R, delta_right_R;
1070 static int left_G, delta_left_G, right_G, delta_right_G;
1071 static int left_B, delta_left_B, right_B, delta_right_B;
1072
1073 // USE_NASM
1074 static inline int shl10idiv(int x, int y)
1075 {
1076  __int64 bi=x;
1077  bi<<=10;
1078  return bi/y;
1079 }
1080
1081 ////////////////////////////////////////////////////////////////////////
1082 ////////////////////////////////////////////////////////////////////////
1083 ////////////////////////////////////////////////////////////////////////
1084                         
1085 static inline int RightSection_F(void)
1086 {
1087  soft_vertex * v1 = right_array[ right_section ];
1088  soft_vertex * v2 = right_array[ right_section-1 ];
1089
1090  int height = v2->y - v1->y;
1091  if(height == 0) return 0;
1092  delta_right_x = (v2->x - v1->x) / height;
1093  right_x = v1->x;
1094
1095  right_section_height = height;
1096  return height;
1097 }
1098
1099 ////////////////////////////////////////////////////////////////////////
1100
1101 static inline int LeftSection_F(void)
1102 {
1103  soft_vertex * v1 = left_array[ left_section ];
1104  soft_vertex * v2 = left_array[ left_section-1 ];
1105
1106  int height = v2->y - v1->y;
1107  if(height == 0) return 0;
1108  delta_left_x = (v2->x - v1->x) / height;
1109  left_x = v1->x;
1110
1111  left_section_height = height;
1112  return height;  
1113 }
1114
1115 ////////////////////////////////////////////////////////////////////////
1116
1117 static inline BOOL NextRow_F(void)
1118 {
1119  if(--left_section_height<=0) 
1120   {
1121    if(--left_section <= 0) {return TRUE;}
1122    if(LeftSection_F()  <= 0) {return TRUE;}
1123   }
1124  else
1125   {
1126    left_x += delta_left_x;
1127   }
1128
1129  if(--right_section_height<=0) 
1130   {
1131    if(--right_section<=0) {return TRUE;}
1132    if(RightSection_F() <=0) {return TRUE;}
1133   }
1134  else
1135   {
1136    right_x += delta_right_x;
1137   }
1138  return FALSE;
1139 }
1140
1141 ////////////////////////////////////////////////////////////////////////
1142
1143 static inline BOOL SetupSections_F(short x1, short y1, short x2, short y2, short x3, short y3)
1144 {
1145  soft_vertex * v1, * v2, * v3;
1146  int height,longest;
1147
1148  v1 = vtx;   v1->x=x1<<16;v1->y=y1;
1149  v2 = vtx+1; v2->x=x2<<16;v2->y=y2;
1150  v3 = vtx+2; v3->x=x3<<16;v3->y=y3;
1151
1152  if(v1->y > v2->y) { soft_vertex * v = v1; v1 = v2; v2 = v; }
1153  if(v1->y > v3->y) { soft_vertex * v = v1; v1 = v3; v3 = v; }
1154  if(v2->y > v3->y) { soft_vertex * v = v2; v2 = v3; v3 = v; }
1155
1156  height = v3->y - v1->y;
1157  if(height == 0) {return FALSE;}
1158  longest = (((v2->y - v1->y) << 16) / height) * ((v3->x - v1->x)>>16) + (v1->x - v2->x);
1159  if(longest == 0) {return FALSE;}
1160
1161  if(longest < 0)
1162   {
1163    right_array[0] = v3;
1164    right_array[1] = v2;
1165    right_array[2] = v1;
1166    right_section  = 2;
1167    left_array[0]  = v3;
1168    left_array[1]  = v1;
1169    left_section   = 1;
1170
1171    if(LeftSection_F() <= 0) return FALSE;
1172    if(RightSection_F() <= 0)
1173     {
1174      right_section--;
1175      if(RightSection_F() <= 0) return FALSE;
1176     }
1177   }
1178  else
1179   {
1180    left_array[0]  = v3;
1181    left_array[1]  = v2;
1182    left_array[2]  = v1;
1183    left_section   = 2;
1184    right_array[0] = v3;
1185    right_array[1] = v1;
1186    right_section  = 1;
1187
1188    if(RightSection_F() <= 0) return FALSE;
1189    if(LeftSection_F() <= 0)
1190     {    
1191      left_section--;
1192      if(LeftSection_F() <= 0) return FALSE;
1193     }
1194   }
1195
1196  Ymin=v1->y;
1197  Ymax=min(v3->y-1,drawH);
1198
1199  return TRUE;
1200 }
1201
1202 ////////////////////////////////////////////////////////////////////////
1203 ////////////////////////////////////////////////////////////////////////
1204
1205 static inline int RightSection_G(void)
1206 {
1207  soft_vertex * v1 = right_array[ right_section ];
1208  soft_vertex * v2 = right_array[ right_section-1 ];
1209
1210  int height = v2->y - v1->y;
1211  if(height == 0) return 0;
1212  delta_right_x = (v2->x - v1->x) / height;
1213  right_x = v1->x;
1214
1215  right_section_height = height;
1216  return height;
1217 }
1218
1219 ////////////////////////////////////////////////////////////////////////
1220
1221 static inline int LeftSection_G(void)
1222 {
1223  soft_vertex * v1 = left_array[ left_section ];
1224  soft_vertex * v2 = left_array[ left_section-1 ];
1225
1226  int height = v2->y - v1->y;
1227  if(height == 0) return 0;
1228  delta_left_x = (v2->x - v1->x) / height;
1229  left_x = v1->x;
1230
1231  delta_left_R = ((v2->R - v1->R)) / height;
1232  left_R = v1->R;
1233  delta_left_G = ((v2->G - v1->G)) / height;
1234  left_G = v1->G;
1235  delta_left_B = ((v2->B - v1->B)) / height;
1236  left_B = v1->B;
1237
1238  left_section_height = height;
1239  return height;  
1240 }
1241
1242 ////////////////////////////////////////////////////////////////////////
1243
1244 static inline BOOL NextRow_G(void)
1245 {
1246  if(--left_section_height<=0) 
1247   {
1248    if(--left_section <= 0) {return TRUE;}
1249    if(LeftSection_G()  <= 0) {return TRUE;}
1250   }
1251  else
1252   {
1253    left_x += delta_left_x;
1254    left_R += delta_left_R;
1255    left_G += delta_left_G;
1256    left_B += delta_left_B;
1257   }
1258
1259  if(--right_section_height<=0) 
1260   {
1261    if(--right_section<=0) {return TRUE;}
1262    if(RightSection_G() <=0) {return TRUE;}
1263   }
1264  else
1265   {
1266    right_x += delta_right_x;
1267   }
1268  return FALSE;
1269 }
1270
1271 ////////////////////////////////////////////////////////////////////////
1272
1273 static inline BOOL SetupSections_G(short x1,short y1,short x2,short y2,short x3,short y3,int32_t rgb1, int32_t rgb2, int32_t rgb3)
1274 {
1275  soft_vertex * v1, * v2, * v3;
1276  int height,longest,temp;
1277
1278  v1 = vtx;   v1->x=x1<<16;v1->y=y1;
1279  v1->R=(rgb1) & 0x00ff0000;
1280  v1->G=(rgb1<<8) & 0x00ff0000;
1281  v1->B=(rgb1<<16) & 0x00ff0000;
1282  v2 = vtx+1; v2->x=x2<<16;v2->y=y2;
1283  v2->R=(rgb2) & 0x00ff0000;
1284  v2->G=(rgb2<<8) & 0x00ff0000;
1285  v2->B=(rgb2<<16) & 0x00ff0000;
1286  v3 = vtx+2; v3->x=x3<<16;v3->y=y3;
1287  v3->R=(rgb3) & 0x00ff0000;
1288  v3->G=(rgb3<<8) & 0x00ff0000;
1289  v3->B=(rgb3<<16) & 0x00ff0000;
1290
1291  if(v1->y > v2->y) { soft_vertex * v = v1; v1 = v2; v2 = v; }
1292  if(v1->y > v3->y) { soft_vertex * v = v1; v1 = v3; v3 = v; }
1293  if(v2->y > v3->y) { soft_vertex * v = v2; v2 = v3; v3 = v; }
1294
1295  height = v3->y - v1->y;
1296  if(height == 0) {return FALSE;}
1297  temp=(((v2->y - v1->y) << 16) / height);
1298  longest = temp * ((v3->x - v1->x)>>16) + (v1->x - v2->x);
1299  if(longest == 0) {return FALSE;}
1300
1301  if(longest < 0)
1302   {
1303    right_array[0] = v3;
1304    right_array[1] = v2;
1305    right_array[2] = v1;
1306    right_section  = 2;
1307    left_array[0]  = v3;
1308    left_array[1]  = v1;
1309    left_section   = 1;
1310
1311    if(LeftSection_G() <= 0) return FALSE;
1312    if(RightSection_G() <= 0)
1313     {
1314      right_section--;
1315      if(RightSection_G() <= 0) return FALSE;
1316     }
1317    if(longest > -0x1000) longest = -0x1000;     
1318   }
1319  else
1320   {
1321    left_array[0]  = v3;
1322    left_array[1]  = v2;
1323    left_array[2]  = v1;
1324    left_section   = 2;
1325    right_array[0] = v3;
1326    right_array[1] = v1;
1327    right_section  = 1;
1328
1329    if(RightSection_G() <= 0) return FALSE;
1330    if(LeftSection_G() <= 0)
1331     {    
1332      left_section--;
1333      if(LeftSection_G() <= 0) return FALSE;
1334     }
1335    if(longest < 0x1000) longest = 0x1000;     
1336   }
1337
1338  Ymin=v1->y;
1339  Ymax=min(v3->y-1,drawH);    
1340
1341  delta_right_R=shl10idiv(temp*((v3->R - v1->R)>>10)+((v1->R - v2->R)<<6),longest);
1342  delta_right_G=shl10idiv(temp*((v3->G - v1->G)>>10)+((v1->G - v2->G)<<6),longest);
1343  delta_right_B=shl10idiv(temp*((v3->B - v1->B)>>10)+((v1->B - v2->B)<<6),longest);
1344
1345  return TRUE;
1346 }
1347
1348 ////////////////////////////////////////////////////////////////////////
1349 ////////////////////////////////////////////////////////////////////////
1350
1351 static inline int RightSection_FT(void)
1352 {
1353  soft_vertex * v1 = right_array[ right_section ];
1354  soft_vertex * v2 = right_array[ right_section-1 ];
1355
1356  int height = v2->y - v1->y;
1357  if(height == 0) return 0;
1358  delta_right_x = (v2->x - v1->x) / height;
1359  right_x = v1->x;
1360
1361  right_section_height = height;
1362  return height;
1363 }
1364
1365 ////////////////////////////////////////////////////////////////////////
1366
1367 static inline int LeftSection_FT(void)
1368 {
1369  soft_vertex * v1 = left_array[ left_section ];
1370  soft_vertex * v2 = left_array[ left_section-1 ];
1371
1372  int height = v2->y - v1->y;
1373  if(height == 0) return 0;
1374  delta_left_x = (v2->x - v1->x) / height;
1375  left_x = v1->x;
1376  
1377  delta_left_u = ((v2->u - v1->u)) / height;
1378  left_u = v1->u;
1379  delta_left_v = ((v2->v - v1->v)) / height;
1380  left_v = v1->v;
1381
1382  left_section_height = height;
1383  return height;  
1384 }
1385
1386 ////////////////////////////////////////////////////////////////////////
1387
1388 static inline BOOL NextRow_FT(void)
1389 {
1390  if(--left_section_height<=0) 
1391   {
1392    if(--left_section <= 0) {return TRUE;}
1393    if(LeftSection_FT()  <= 0) {return TRUE;}
1394   }
1395  else
1396   {
1397    left_x += delta_left_x;
1398    left_u += delta_left_u;
1399    left_v += delta_left_v;
1400   }
1401
1402  if(--right_section_height<=0) 
1403   {
1404    if(--right_section<=0) {return TRUE;}
1405    if(RightSection_FT() <=0) {return TRUE;}
1406   }
1407  else
1408   {
1409    right_x += delta_right_x;
1410   }
1411  return FALSE;
1412 }
1413
1414 ////////////////////////////////////////////////////////////////////////
1415
1416 static inline BOOL SetupSections_FT(short x1, short y1, short x2, short y2, short x3, short y3, short tx1, short ty1, short tx2, short ty2, short tx3, short ty3)
1417 {
1418  soft_vertex * v1, * v2, * v3;
1419  int height,longest,temp;
1420
1421  v1 = vtx;   v1->x=x1<<16;v1->y=y1;
1422  v1->u=tx1<<16;v1->v=ty1<<16;
1423  v2 = vtx+1; v2->x=x2<<16;v2->y=y2;
1424  v2->u=tx2<<16;v2->v=ty2<<16;
1425  v3 = vtx+2; v3->x=x3<<16;v3->y=y3;
1426  v3->u=tx3<<16;v3->v=ty3<<16;
1427
1428  if(v1->y > v2->y) { soft_vertex * v = v1; v1 = v2; v2 = v; }
1429  if(v1->y > v3->y) { soft_vertex * v = v1; v1 = v3; v3 = v; }
1430  if(v2->y > v3->y) { soft_vertex * v = v2; v2 = v3; v3 = v; }
1431
1432  height = v3->y - v1->y;
1433  if(height == 0) {return FALSE;}
1434
1435  temp=(((v2->y - v1->y) << 16) / height);
1436  longest = temp * ((v3->x - v1->x)>>16) + (v1->x - v2->x);
1437
1438  if(longest == 0) {return FALSE;}
1439
1440  if(longest < 0)
1441   {
1442    right_array[0] = v3;
1443    right_array[1] = v2;
1444    right_array[2] = v1;
1445    right_section  = 2;
1446    left_array[0]  = v3;
1447    left_array[1]  = v1;
1448    left_section   = 1;
1449
1450    if(LeftSection_FT() <= 0) return FALSE;
1451    if(RightSection_FT() <= 0)
1452     {
1453      right_section--;
1454      if(RightSection_FT() <= 0) return FALSE;
1455     }
1456    if(longest > -0x1000) longest = -0x1000;     
1457   }
1458  else
1459   {
1460    left_array[0]  = v3;
1461    left_array[1]  = v2;
1462    left_array[2]  = v1;
1463    left_section   = 2;
1464    right_array[0] = v3;
1465    right_array[1] = v1;
1466    right_section  = 1;
1467
1468    if(RightSection_FT() <= 0) return FALSE;
1469    if(LeftSection_FT() <= 0)
1470     {    
1471      left_section--;                
1472      if(LeftSection_FT() <= 0) return FALSE;
1473     }
1474    if(longest < 0x1000) longest = 0x1000;     
1475   }
1476
1477  Ymin=v1->y;
1478  Ymax=min(v3->y-1,drawH);
1479
1480  delta_right_u=shl10idiv(temp*((v3->u - v1->u)>>10)+((v1->u - v2->u)<<6),longest);
1481  delta_right_v=shl10idiv(temp*((v3->v - v1->v)>>10)+((v1->v - v2->v)<<6),longest);
1482
1483  return TRUE;
1484 }
1485
1486 ////////////////////////////////////////////////////////////////////////
1487 ////////////////////////////////////////////////////////////////////////
1488
1489 static inline int RightSection_GT(void)
1490 {
1491  soft_vertex * v1 = right_array[ right_section ];
1492  soft_vertex * v2 = right_array[ right_section-1 ];
1493
1494  int height = v2->y - v1->y;
1495  if(height == 0) return 0;
1496  delta_right_x = (v2->x - v1->x) / height;
1497  right_x = v1->x;
1498
1499  right_section_height = height;
1500  return height;
1501 }
1502
1503 ////////////////////////////////////////////////////////////////////////
1504
1505 static inline int LeftSection_GT(void)
1506 {
1507  soft_vertex * v1 = left_array[ left_section ];
1508  soft_vertex * v2 = left_array[ left_section-1 ];
1509
1510  int height = v2->y - v1->y;
1511  if(height == 0) return 0;
1512  delta_left_x = (v2->x - v1->x) / height;
1513  left_x = v1->x;
1514
1515  delta_left_u = ((v2->u - v1->u)) / height;
1516  left_u = v1->u;
1517  delta_left_v = ((v2->v - v1->v)) / height;
1518  left_v = v1->v;
1519
1520  delta_left_R = ((v2->R - v1->R)) / height;
1521  left_R = v1->R;
1522  delta_left_G = ((v2->G - v1->G)) / height;
1523  left_G = v1->G;
1524  delta_left_B = ((v2->B - v1->B)) / height;
1525  left_B = v1->B;
1526
1527  left_section_height = height;
1528  return height;  
1529 }
1530
1531 ////////////////////////////////////////////////////////////////////////
1532
1533 static inline BOOL NextRow_GT(void)
1534 {
1535  if(--left_section_height<=0) 
1536   {
1537    if(--left_section <= 0) {return TRUE;}
1538    if(LeftSection_GT()  <= 0) {return TRUE;}
1539   }
1540  else
1541   {
1542    left_x += delta_left_x;
1543    left_u += delta_left_u;
1544    left_v += delta_left_v;
1545    left_R += delta_left_R;
1546    left_G += delta_left_G;
1547    left_B += delta_left_B;
1548   }
1549
1550  if(--right_section_height<=0) 
1551   {
1552    if(--right_section<=0) {return TRUE;}
1553    if(RightSection_GT() <=0) {return TRUE;}
1554   }
1555  else
1556   {
1557    right_x += delta_right_x;
1558   }
1559  return FALSE;
1560 }
1561
1562 ////////////////////////////////////////////////////////////////////////
1563
1564 static inline BOOL SetupSections_GT(short x1, short y1, short x2, short y2, short x3, short y3, short tx1, short ty1, short tx2, short ty2, short tx3, short ty3, int32_t rgb1, int32_t rgb2, int32_t rgb3)
1565 {
1566  soft_vertex * v1, * v2, * v3;
1567  int height,longest,temp;
1568
1569  v1 = vtx;   v1->x=x1<<16;v1->y=y1;
1570  v1->u=tx1<<16;v1->v=ty1<<16;
1571  v1->R=(rgb1) & 0x00ff0000;
1572  v1->G=(rgb1<<8) & 0x00ff0000;
1573  v1->B=(rgb1<<16) & 0x00ff0000;
1574
1575  v2 = vtx+1; v2->x=x2<<16;v2->y=y2;
1576  v2->u=tx2<<16;v2->v=ty2<<16;
1577  v2->R=(rgb2) & 0x00ff0000;
1578  v2->G=(rgb2<<8) & 0x00ff0000;
1579  v2->B=(rgb2<<16) & 0x00ff0000;
1580              
1581  v3 = vtx+2; v3->x=x3<<16;v3->y=y3;
1582  v3->u=tx3<<16;v3->v=ty3<<16;
1583  v3->R=(rgb3) & 0x00ff0000;
1584  v3->G=(rgb3<<8) & 0x00ff0000;
1585  v3->B=(rgb3<<16) & 0x00ff0000;
1586
1587  if(v1->y > v2->y) { soft_vertex * v = v1; v1 = v2; v2 = v; }
1588  if(v1->y > v3->y) { soft_vertex * v = v1; v1 = v3; v3 = v; }
1589  if(v2->y > v3->y) { soft_vertex * v = v2; v2 = v3; v3 = v; }
1590
1591  height = v3->y - v1->y;
1592  if(height == 0) {return FALSE;}
1593
1594  temp=(((v2->y - v1->y) << 16) / height);
1595  longest = temp * ((v3->x - v1->x)>>16) + (v1->x - v2->x);
1596
1597  if(longest == 0) {return FALSE;}
1598
1599  if(longest < 0)
1600   {
1601    right_array[0] = v3;
1602    right_array[1] = v2;
1603    right_array[2] = v1;
1604    right_section  = 2;
1605    left_array[0]  = v3;
1606    left_array[1]  = v1;
1607    left_section   = 1;
1608
1609    if(LeftSection_GT() <= 0) return FALSE;
1610    if(RightSection_GT() <= 0)
1611     {
1612      right_section--;
1613      if(RightSection_GT() <= 0) return FALSE;
1614     }
1615
1616    if(longest > -0x1000) longest = -0x1000;     
1617   }
1618  else
1619   {
1620    left_array[0]  = v3;
1621    left_array[1]  = v2;
1622    left_array[2]  = v1;
1623    left_section   = 2;
1624    right_array[0] = v3;
1625    right_array[1] = v1;
1626    right_section  = 1;
1627
1628    if(RightSection_GT() <= 0) return FALSE;
1629    if(LeftSection_GT() <= 0)
1630     {    
1631      left_section--;
1632      if(LeftSection_GT() <= 0) return FALSE;
1633     }
1634    if(longest < 0x1000) longest = 0x1000;     
1635   }
1636
1637  Ymin=v1->y;
1638  Ymax=min(v3->y-1,drawH);
1639
1640  delta_right_R=shl10idiv(temp*((v3->R - v1->R)>>10)+((v1->R - v2->R)<<6),longest);
1641  delta_right_G=shl10idiv(temp*((v3->G - v1->G)>>10)+((v1->G - v2->G)<<6),longest);
1642  delta_right_B=shl10idiv(temp*((v3->B - v1->B)>>10)+((v1->B - v2->B)<<6),longest);
1643
1644  delta_right_u=shl10idiv(temp*((v3->u - v1->u)>>10)+((v1->u - v2->u)<<6),longest);
1645  delta_right_v=shl10idiv(temp*((v3->v - v1->v)>>10)+((v1->v - v2->v)<<6),longest);
1646
1647  return TRUE;
1648 }
1649
1650 ////////////////////////////////////////////////////////////////////////
1651 ////////////////////////////////////////////////////////////////////////
1652
1653 static inline int RightSection_F4(void)
1654 {
1655  soft_vertex * v1 = right_array[ right_section ];
1656  soft_vertex * v2 = right_array[ right_section-1 ];
1657
1658  int height = v2->y - v1->y;
1659  right_section_height = height;
1660  right_x = v1->x;
1661  if(height == 0) 
1662   {
1663    return 0;
1664   }
1665  delta_right_x = (v2->x - v1->x) / height;
1666
1667  return height;
1668 }
1669
1670 ////////////////////////////////////////////////////////////////////////
1671
1672 static inline int LeftSection_F4(void)
1673 {
1674  soft_vertex * v1 = left_array[ left_section ];
1675  soft_vertex * v2 = left_array[ left_section-1 ];
1676
1677  int height = v2->y - v1->y;
1678  left_section_height = height;
1679  left_x = v1->x;
1680  if(height == 0) 
1681   {
1682    return 0;
1683   }
1684  delta_left_x = (v2->x - v1->x) / height;
1685
1686  return height;  
1687 }
1688
1689 ////////////////////////////////////////////////////////////////////////
1690
1691 static inline BOOL NextRow_F4(void)
1692 {
1693  if(--left_section_height<=0) 
1694   {
1695    if(--left_section > 0) 
1696     while(LeftSection_F4()<=0) 
1697      {
1698       if(--left_section  <= 0) break;
1699      }
1700   }
1701  else
1702   {
1703    left_x += delta_left_x;
1704   }
1705
1706  if(--right_section_height<=0) 
1707   {
1708    if(--right_section > 0) 
1709     while(RightSection_F4()<=0) 
1710      {
1711       if(--right_section<=0) break;
1712      }
1713   }
1714  else
1715   {
1716    right_x += delta_right_x;
1717   }
1718  return FALSE;
1719 }
1720
1721 ////////////////////////////////////////////////////////////////////////
1722
1723 static inline BOOL SetupSections_F4(short x1, short y1, short x2, short y2, short x3, short y3, short x4, short y4)
1724 {
1725  soft_vertex * v1, * v2, * v3, * v4;
1726  int height,width,longest1,longest2;
1727
1728  v1 = vtx;   v1->x=x1<<16;v1->y=y1;
1729  v2 = vtx+1; v2->x=x2<<16;v2->y=y2;
1730  v3 = vtx+2; v3->x=x3<<16;v3->y=y3;
1731  v4 = vtx+3; v4->x=x4<<16;v4->y=y4;
1732
1733  if(v1->y > v2->y) { soft_vertex * v = v1; v1 = v2; v2 = v; }
1734  if(v1->y > v3->y) { soft_vertex * v = v1; v1 = v3; v3 = v; }
1735  if(v1->y > v4->y) { soft_vertex * v = v1; v1 = v4; v4 = v; }
1736  if(v2->y > v3->y) { soft_vertex * v = v2; v2 = v3; v3 = v; }
1737  if(v2->y > v4->y) { soft_vertex * v = v2; v2 = v4; v4 = v; }
1738  if(v3->y > v4->y) { soft_vertex * v = v3; v3 = v4; v4 = v; }
1739
1740  height = v4->y - v1->y; if(height == 0) height =1;
1741  width  = (v4->x - v1->x)>>16;
1742  longest1 = (((v2->y - v1->y) << 16) / height) * width + (v1->x - v2->x);
1743  longest2 = (((v3->y - v1->y) << 16) / height) * width + (v1->x - v3->x);
1744
1745  if(longest1 < 0)                                      // 2 is right
1746   {
1747    if(longest2 < 0)                                    // 3 is right
1748     {
1749      left_array[0]  = v4;
1750      left_array[1]  = v1;
1751      left_section   = 1;
1752
1753      height = v3->y - v1->y; if(height == 0) height=1;
1754      longest1 = (((v2->y - v1->y) << 16) / height) * ((v3->x - v1->x)>>16) + (v1->x - v2->x);
1755      if(longest1 >= 0)
1756       {
1757        right_array[0] = v4;                     //  1
1758        right_array[1] = v3;                     //     3
1759        right_array[2] = v1;                     //  4
1760        right_section  = 2;    
1761       }
1762      else
1763       {
1764        height = v4->y - v2->y; if(height == 0) height=1;
1765        longest1 = (((v3->y - v2->y) << 16) / height) * ((v4->x - v2->x)>>16) + (v2->x - v3->x);
1766        if(longest1 >= 0)
1767         {
1768          right_array[0] = v4;                    //  1
1769          right_array[1] = v2;                    //     2
1770          right_array[2] = v1;                    //  4
1771          right_section  = 2;    
1772         }
1773        else
1774         {
1775          right_array[0] = v4;                    //  1
1776          right_array[1] = v3;                    //     2
1777          right_array[2] = v2;                    //     3
1778          right_array[3] = v1;                    //  4
1779          right_section  = 3;    
1780         }
1781       }
1782     }
1783    else                                            
1784     {
1785      left_array[0]  = v4;
1786      left_array[1]  = v3;                         //    1
1787      left_array[2]  = v1;                         //      2
1788      left_section   = 2;                          //  3
1789      right_array[0] = v4;                         //    4
1790      right_array[1] = v2;
1791      right_array[2] = v1;
1792      right_section  = 2;
1793     }
1794   }
1795  else
1796   {
1797    if(longest2 < 0)             
1798     {
1799      left_array[0]  = v4;                          //    1
1800      left_array[1]  = v2;                          //  2
1801      left_array[2]  = v1;                          //      3
1802      left_section   = 2;                           //    4
1803      right_array[0] = v4;
1804      right_array[1] = v3;
1805      right_array[2] = v1;
1806      right_section  = 2;
1807     }
1808    else                         
1809     {
1810      right_array[0] = v4;
1811      right_array[1] = v1;
1812      right_section  = 1;
1813
1814      height = v3->y - v1->y; if(height == 0) height=1;
1815      longest1 = (((v2->y - v1->y) << 16) / height) * ((v3->x - v1->x)>>16) + (v1->x - v2->x);
1816      if(longest1<0)
1817       {
1818        left_array[0]  = v4;                        //    1
1819        left_array[1]  = v3;                        //  3
1820        left_array[2]  = v1;                        //    4
1821        left_section   = 2;    
1822       }
1823      else
1824       {
1825        height = v4->y - v2->y; if(height == 0) height=1;
1826        longest1 = (((v3->y - v2->y) << 16) / height) * ((v4->x - v2->x)>>16) + (v2->x - v3->x);
1827        if(longest1<0)
1828         {
1829          left_array[0]  = v4;                      //    1
1830          left_array[1]  = v2;                      //  2
1831          left_array[2]  = v1;                      //    4
1832          left_section   = 2;    
1833         }
1834        else
1835         {
1836          left_array[0]  = v4;                      //    1
1837          left_array[1]  = v3;                      //  2
1838          left_array[2]  = v2;                      //  3
1839          left_array[3]  = v1;                      //     4
1840          left_section   = 3;    
1841         }
1842       }
1843     }
1844   }
1845
1846  while(LeftSection_F4()<=0) 
1847   {
1848    if(--left_section  <= 0) break;
1849   }
1850
1851  while(RightSection_F4()<=0) 
1852   {
1853    if(--right_section <= 0) break;
1854   }
1855
1856  Ymin=v1->y;
1857  Ymax=min(v4->y-1,drawH);
1858
1859  return TRUE;
1860 }
1861
1862 ////////////////////////////////////////////////////////////////////////
1863 ////////////////////////////////////////////////////////////////////////
1864
1865 static inline int RightSection_FT4(void)
1866 {
1867  soft_vertex * v1 = right_array[ right_section ];
1868  soft_vertex * v2 = right_array[ right_section-1 ];
1869
1870  int height = v2->y - v1->y;
1871  right_section_height = height;
1872  right_x = v1->x;
1873  right_u = v1->u;
1874  right_v = v1->v;
1875  if(height == 0) 
1876   {
1877    return 0;
1878   }
1879  delta_right_x = (v2->x - v1->x) / height;
1880  delta_right_u = (v2->u - v1->u) / height;
1881  delta_right_v = (v2->v - v1->v) / height;
1882
1883  return height;
1884 }
1885
1886 ////////////////////////////////////////////////////////////////////////
1887
1888 static inline int LeftSection_FT4(void)
1889 {
1890  soft_vertex * v1 = left_array[ left_section ];
1891  soft_vertex * v2 = left_array[ left_section-1 ];
1892
1893  int height = v2->y - v1->y;
1894  left_section_height = height;
1895  left_x = v1->x;
1896  left_u = v1->u;
1897  left_v = v1->v;
1898  if(height == 0) 
1899   {
1900    return 0;
1901   }
1902  delta_left_x = (v2->x - v1->x) / height;
1903  delta_left_u = (v2->u - v1->u) / height;
1904  delta_left_v = (v2->v - v1->v) / height;
1905
1906  return height;  
1907 }
1908
1909 ////////////////////////////////////////////////////////////////////////
1910
1911 static inline BOOL NextRow_FT4(void)
1912 {
1913  if(--left_section_height<=0) 
1914   {
1915    if(--left_section > 0) 
1916     while(LeftSection_FT4()<=0) 
1917      {
1918       if(--left_section  <= 0) break;
1919      }
1920   }
1921  else
1922   {
1923    left_x += delta_left_x;
1924    left_u += delta_left_u;
1925    left_v += delta_left_v;
1926   }
1927
1928  if(--right_section_height<=0) 
1929   {
1930    if(--right_section > 0) 
1931     while(RightSection_FT4()<=0) 
1932      {
1933       if(--right_section<=0) break;
1934      }
1935   }
1936  else
1937   {
1938    right_x += delta_right_x;
1939    right_u += delta_right_u;
1940    right_v += delta_right_v;
1941   }
1942  return FALSE;
1943 }
1944
1945 ////////////////////////////////////////////////////////////////////////
1946
1947 static inline BOOL SetupSections_FT4(short x1, short y1, short x2, short y2, short x3, short y3, short x4, short y4, short tx1, short ty1, short tx2, short ty2, short tx3, short ty3, short tx4, short ty4)
1948 {
1949  soft_vertex * v1, * v2, * v3, * v4;
1950  int height,width,longest1,longest2;
1951
1952  v1 = vtx;   v1->x=x1<<16;v1->y=y1;
1953  v1->u=tx1<<16;v1->v=ty1<<16;
1954
1955  v2 = vtx+1; v2->x=x2<<16;v2->y=y2;
1956  v2->u=tx2<<16;v2->v=ty2<<16;
1957              
1958  v3 = vtx+2; v3->x=x3<<16;v3->y=y3;
1959  v3->u=tx3<<16;v3->v=ty3<<16;
1960
1961  v4 = vtx+3; v4->x=x4<<16;v4->y=y4;
1962  v4->u=tx4<<16;v4->v=ty4<<16;
1963
1964  if(v1->y > v2->y) { soft_vertex * v = v1; v1 = v2; v2 = v; }
1965  if(v1->y > v3->y) { soft_vertex * v = v1; v1 = v3; v3 = v; }
1966  if(v1->y > v4->y) { soft_vertex * v = v1; v1 = v4; v4 = v; }
1967  if(v2->y > v3->y) { soft_vertex * v = v2; v2 = v3; v3 = v; }
1968  if(v2->y > v4->y) { soft_vertex * v = v2; v2 = v4; v4 = v; }
1969  if(v3->y > v4->y) { soft_vertex * v = v3; v3 = v4; v4 = v; }
1970
1971  height = v4->y - v1->y; if(height == 0) height =1;
1972  width  = (v4->x - v1->x)>>16;
1973  longest1 = (((v2->y - v1->y) << 16) / height) * width + (v1->x - v2->x);
1974  longest2 = (((v3->y - v1->y) << 16) / height) * width + (v1->x - v3->x);
1975
1976  if(longest1 < 0)                                      // 2 is right
1977   {
1978    if(longest2 < 0)                                    // 3 is right
1979     {
1980      left_array[0]  = v4;
1981      left_array[1]  = v1;
1982      left_section   = 1;
1983
1984      height = v3->y - v1->y; if(height == 0) height=1;
1985      longest1 = (((v2->y - v1->y) << 16) / height) * ((v3->x - v1->x)>>16) + (v1->x - v2->x);
1986      if(longest1 >= 0)
1987       {
1988        right_array[0] = v4;                     //  1
1989        right_array[1] = v3;                     //     3
1990        right_array[2] = v1;                     //  4
1991        right_section  = 2;    
1992       }
1993      else
1994       {
1995        height = v4->y - v2->y; if(height == 0) height=1;
1996        longest1 = (((v3->y - v2->y) << 16) / height) * ((v4->x - v2->x)>>16) + (v2->x - v3->x);
1997        if(longest1 >= 0)
1998         {
1999          right_array[0] = v4;                    //  1
2000          right_array[1] = v2;                    //     2
2001          right_array[2] = v1;                    //  4
2002          right_section  = 2;    
2003         }
2004        else
2005         {
2006          right_array[0] = v4;                    //  1
2007          right_array[1] = v3;                    //     2
2008          right_array[2] = v2;                    //     3
2009          right_array[3] = v1;                    //  4
2010          right_section  = 3;    
2011         }
2012       }
2013     }
2014    else                                            
2015     {
2016      left_array[0]  = v4;
2017      left_array[1]  = v3;                         //    1
2018      left_array[2]  = v1;                         //      2
2019      left_section   = 2;                          //  3
2020      right_array[0] = v4;                         //    4
2021      right_array[1] = v2;
2022      right_array[2] = v1;
2023      right_section  = 2;
2024     }
2025   }
2026  else
2027   {
2028    if(longest2 < 0)             
2029     {
2030      left_array[0]  = v4;                          //    1
2031      left_array[1]  = v2;                          //  2
2032      left_array[2]  = v1;                          //      3
2033      left_section   = 2;                           //    4
2034      right_array[0] = v4;
2035      right_array[1] = v3;
2036      right_array[2] = v1;
2037      right_section  = 2;
2038     }
2039    else                         
2040     {
2041      right_array[0] = v4;
2042      right_array[1] = v1;
2043      right_section  = 1;
2044
2045      height = v3->y - v1->y; if(height == 0) height=1;
2046      longest1 = (((v2->y - v1->y) << 16) / height) * ((v3->x - v1->x)>>16) + (v1->x - v2->x);
2047      if(longest1<0)
2048       {
2049        left_array[0]  = v4;                        //    1
2050        left_array[1]  = v3;                        //  3
2051        left_array[2]  = v1;                        //    4
2052        left_section   = 2;    
2053       }
2054      else
2055       {
2056        height = v4->y - v2->y; if(height == 0) height=1;
2057        longest1 = (((v3->y - v2->y) << 16) / height) * ((v4->x - v2->x)>>16) + (v2->x - v3->x);
2058        if(longest1<0)
2059         {
2060          left_array[0]  = v4;                      //    1
2061          left_array[1]  = v2;                      //  2
2062          left_array[2]  = v1;                      //    4
2063          left_section   = 2;    
2064         }
2065        else
2066         {
2067          left_array[0]  = v4;                      //    1
2068          left_array[1]  = v3;                      //  2
2069          left_array[2]  = v2;                      //  3
2070          left_array[3]  = v1;                      //     4
2071          left_section   = 3;    
2072         }
2073       }
2074     }
2075   }
2076
2077  while(LeftSection_FT4()<=0) 
2078   {
2079    if(--left_section  <= 0) break;
2080   }
2081
2082  while(RightSection_FT4()<=0) 
2083   {
2084    if(--right_section <= 0) break;
2085   }
2086
2087  Ymin=v1->y;
2088  Ymax=min(v4->y-1,drawH);
2089
2090  return TRUE;
2091 }
2092
2093 ////////////////////////////////////////////////////////////////////////
2094 ////////////////////////////////////////////////////////////////////////
2095
2096 static inline int RightSection_GT4(void)
2097 {
2098  soft_vertex * v1 = right_array[ right_section ];
2099  soft_vertex * v2 = right_array[ right_section-1 ];
2100
2101  int height = v2->y - v1->y;
2102  right_section_height = height;
2103  right_x = v1->x;
2104  right_u = v1->u;
2105  right_v = v1->v;
2106  right_R = v1->R;
2107  right_G = v1->G;
2108  right_B = v1->B;
2109
2110  if(height == 0) 
2111   {
2112    return 0;
2113   }
2114  delta_right_x = (v2->x - v1->x) / height;
2115  delta_right_u = (v2->u - v1->u) / height;
2116  delta_right_v = (v2->v - v1->v) / height;
2117  delta_right_R = (v2->R - v1->R) / height;
2118  delta_right_G = (v2->G - v1->G) / height;
2119  delta_right_B = (v2->B - v1->B) / height;
2120
2121  return height;
2122 }
2123
2124 ////////////////////////////////////////////////////////////////////////
2125
2126 static inline int LeftSection_GT4(void)
2127 {
2128  soft_vertex * v1 = left_array[ left_section ];
2129  soft_vertex * v2 = left_array[ left_section-1 ];
2130
2131  int height = v2->y - v1->y;
2132  left_section_height = height;
2133  left_x = v1->x;
2134  left_u = v1->u;
2135  left_v = v1->v;
2136  left_R = v1->R;
2137  left_G = v1->G;
2138  left_B = v1->B;
2139
2140  if(height == 0) 
2141   {
2142    return 0;
2143   }
2144  delta_left_x = (v2->x - v1->x) / height;
2145  delta_left_u = (v2->u - v1->u) / height;
2146  delta_left_v = (v2->v - v1->v) / height;
2147  delta_left_R = (v2->R - v1->R) / height;
2148  delta_left_G = (v2->G - v1->G) / height;
2149  delta_left_B = (v2->B - v1->B) / height;
2150
2151  return height;  
2152 }
2153
2154 ////////////////////////////////////////////////////////////////////////
2155
2156 static inline BOOL NextRow_GT4(void)
2157 {
2158  if(--left_section_height<=0) 
2159   {
2160    if(--left_section > 0) 
2161     while(LeftSection_GT4()<=0) 
2162      {
2163       if(--left_section  <= 0) break;
2164      }
2165   }
2166  else
2167   {
2168    left_x += delta_left_x;
2169    left_u += delta_left_u;
2170    left_v += delta_left_v;
2171    left_R += delta_left_R;
2172    left_G += delta_left_G;
2173    left_B += delta_left_B;
2174   }
2175
2176  if(--right_section_height<=0) 
2177   {
2178    if(--right_section > 0) 
2179     while(RightSection_GT4()<=0) 
2180      {
2181       if(--right_section<=0) break;
2182      }
2183   }
2184  else
2185   {
2186    right_x += delta_right_x;
2187    right_u += delta_right_u;
2188    right_v += delta_right_v;
2189    right_R += delta_right_R;
2190    right_G += delta_right_G;
2191    right_B += delta_right_B;
2192   }
2193  return FALSE;
2194 }
2195
2196 ////////////////////////////////////////////////////////////////////////
2197
2198 static inline BOOL SetupSections_GT4(short x1, short y1, short x2, short y2, short x3, short y3, short x4, short y4, short tx1, short ty1, short tx2, short ty2, short tx3, short ty3, short tx4, short ty4,int32_t rgb1,int32_t rgb2,int32_t rgb3,int32_t rgb4)
2199 {
2200  soft_vertex * v1, * v2, * v3, * v4;
2201  int height,width,longest1,longest2;
2202
2203  v1 = vtx;   v1->x=x1<<16;v1->y=y1;
2204  v1->u=tx1<<16;v1->v=ty1<<16;
2205  v1->R=(rgb1) & 0x00ff0000;
2206  v1->G=(rgb1<<8) & 0x00ff0000;
2207  v1->B=(rgb1<<16) & 0x00ff0000;
2208
2209  v2 = vtx+1; v2->x=x2<<16;v2->y=y2;
2210  v2->u=tx2<<16;v2->v=ty2<<16;
2211  v2->R=(rgb2) & 0x00ff0000;
2212  v2->G=(rgb2<<8) & 0x00ff0000;
2213  v2->B=(rgb2<<16) & 0x00ff0000;
2214              
2215  v3 = vtx+2; v3->x=x3<<16;v3->y=y3;
2216  v3->u=tx3<<16;v3->v=ty3<<16;
2217  v3->R=(rgb3) & 0x00ff0000;
2218  v3->G=(rgb3<<8) & 0x00ff0000;
2219  v3->B=(rgb3<<16) & 0x00ff0000;
2220
2221  v4 = vtx+3; v4->x=x4<<16;v4->y=y4;
2222  v4->u=tx4<<16;v4->v=ty4<<16;
2223  v4->R=(rgb4) & 0x00ff0000;
2224  v4->G=(rgb4<<8) & 0x00ff0000;
2225  v4->B=(rgb4<<16) & 0x00ff0000;
2226
2227  if(v1->y > v2->y) { soft_vertex * v = v1; v1 = v2; v2 = v; }
2228  if(v1->y > v3->y) { soft_vertex * v = v1; v1 = v3; v3 = v; }
2229  if(v1->y > v4->y) { soft_vertex * v = v1; v1 = v4; v4 = v; }
2230  if(v2->y > v3->y) { soft_vertex * v = v2; v2 = v3; v3 = v; }
2231  if(v2->y > v4->y) { soft_vertex * v = v2; v2 = v4; v4 = v; }
2232  if(v3->y > v4->y) { soft_vertex * v = v3; v3 = v4; v4 = v; }
2233
2234  height = v4->y - v1->y; if(height == 0) height =1;
2235  width  = (v4->x - v1->x)>>16;
2236  longest1 = (((v2->y - v1->y) << 16) / height) * width + (v1->x - v2->x);
2237  longest2 = (((v3->y - v1->y) << 16) / height) * width + (v1->x - v3->x);
2238
2239  if(longest1 < 0)                                      // 2 is right
2240   {
2241    if(longest2 < 0)                                    // 3 is right
2242     {
2243      left_array[0]  = v4;
2244      left_array[1]  = v1;
2245      left_section   = 1;
2246
2247      height = v3->y - v1->y; if(height == 0) height=1;
2248      longest1 = (((v2->y - v1->y) << 16) / height) * ((v3->x - v1->x)>>16) + (v1->x - v2->x);
2249      if(longest1 >= 0)
2250       {
2251        right_array[0] = v4;                     //  1
2252        right_array[1] = v3;                     //     3
2253        right_array[2] = v1;                     //  4
2254        right_section  = 2;    
2255       }
2256      else
2257       {
2258        height = v4->y - v2->y; if(height == 0) height=1;
2259        longest1 = (((v3->y - v2->y) << 16) / height) * ((v4->x - v2->x)>>16) + (v2->x - v3->x);
2260        if(longest1 >= 0)
2261         {
2262          right_array[0] = v4;                    //  1
2263          right_array[1] = v2;                    //     2
2264          right_array[2] = v1;                    //  4
2265          right_section  = 2;    
2266         }
2267        else
2268         {
2269          right_array[0] = v4;                    //  1
2270          right_array[1] = v3;                    //     2
2271          right_array[2] = v2;                    //     3
2272          right_array[3] = v1;                    //  4
2273          right_section  = 3;    
2274         }
2275       }
2276     }
2277    else                                            
2278     {
2279      left_array[0]  = v4;
2280      left_array[1]  = v3;                         //    1
2281      left_array[2]  = v1;                         //      2
2282      left_section   = 2;                          //  3
2283      right_array[0] = v4;                         //    4
2284      right_array[1] = v2;
2285      right_array[2] = v1;
2286      right_section  = 2;
2287     }
2288   }
2289  else
2290   {
2291    if(longest2 < 0)             
2292     {
2293      left_array[0]  = v4;                          //    1
2294      left_array[1]  = v2;                          //  2
2295      left_array[2]  = v1;                          //      3
2296      left_section   = 2;                           //    4
2297      right_array[0] = v4;
2298      right_array[1] = v3;
2299      right_array[2] = v1;
2300      right_section  = 2;
2301     }
2302    else                         
2303     {
2304      right_array[0] = v4;
2305      right_array[1] = v1;
2306      right_section  = 1;
2307
2308      height = v3->y - v1->y; if(height == 0) height=1;
2309      longest1 = (((v2->y - v1->y) << 16) / height) * ((v3->x - v1->x)>>16) + (v1->x - v2->x);
2310      if(longest1<0)
2311       {
2312        left_array[0]  = v4;                        //    1
2313        left_array[1]  = v3;                        //  3
2314        left_array[2]  = v1;                        //    4
2315        left_section   = 2;    
2316       }
2317      else
2318       {
2319        height = v4->y - v2->y; if(height == 0) height=1;
2320        longest1 = (((v3->y - v2->y) << 16) / height) * ((v4->x - v2->x)>>16) + (v2->x - v3->x);
2321        if(longest1<0)
2322         {
2323          left_array[0]  = v4;                      //    1
2324          left_array[1]  = v2;                      //  2
2325          left_array[2]  = v1;                      //    4
2326          left_section   = 2;    
2327         }
2328        else
2329         {
2330          left_array[0]  = v4;                      //    1
2331          left_array[1]  = v3;                      //  2
2332          left_array[2]  = v2;                      //  3
2333          left_array[3]  = v1;                      //     4
2334          left_section   = 3;    
2335         }
2336       }
2337     }
2338   }
2339
2340  while(LeftSection_GT4()<=0) 
2341   {
2342    if(--left_section  <= 0) break;
2343   }
2344
2345  while(RightSection_GT4()<=0) 
2346   {
2347    if(--right_section <= 0) break;
2348   }
2349
2350  Ymin=v1->y;
2351  Ymax=min(v4->y-1,drawH);
2352
2353  return TRUE;
2354 }
2355
2356 ////////////////////////////////////////////////////////////////////////
2357 ////////////////////////////////////////////////////////////////////////
2358 ////////////////////////////////////////////////////////////////////////
2359 // POLY FUNCS
2360 ////////////////////////////////////////////////////////////////////////
2361 ////////////////////////////////////////////////////////////////////////
2362 ////////////////////////////////////////////////////////////////////////
2363
2364 ////////////////////////////////////////////////////////////////////////
2365 // POLY 3/4 FLAT SHADED
2366 ////////////////////////////////////////////////////////////////////////
2367
2368 static inline void drawPoly3Fi(short x1,short y1,short x2,short y2,short x3,short y3,int32_t rgb)
2369 {
2370  int i,j,xmin,xmax,ymin,ymax;
2371  unsigned short color;uint32_t lcolor;
2372
2373  if(x1>drawW && x2>drawW && x3>drawW) return;
2374  if(y1>drawH && y2>drawH && y3>drawH) return;
2375  if(x1<drawX && x2<drawX && x3<drawX) return;
2376  if(y1<drawY && y2<drawY && y3<drawY) return;
2377  if(drawY>=drawH) return;
2378  if(drawX>=drawW) return; 
2379
2380  if(!SetupSections_F(x1,y1,x2,y2,x3,y3)) return;
2381
2382  ymax=Ymax;
2383
2384  color = ((rgb & 0x00f80000)>>9) | ((rgb & 0x0000f800)>>6) | ((rgb & 0x000000f8)>>3);
2385  lcolor=lSetMask|(((uint32_t)(color))<<16)|color;
2386
2387  for(ymin=Ymin;ymin<drawY;ymin++)
2388   if(NextRow_F()) return;
2389
2390 #ifdef FASTSOLID
2391
2392  if(!bCheckMask && !DrawSemiTrans)
2393   {
2394    color |=sSetMask;
2395    for (i=ymin;i<=ymax;i++)
2396     {
2397      xmin=left_x >> 16;      if(drawX>xmin) xmin=drawX;
2398      xmax=(right_x >> 16)-1; if(drawW<xmax) xmax=drawW;
2399
2400      for(j=xmin;j<xmax;j+=2) 
2401       {
2402        PUTLE32(((uint32_t *)&psxVuw[(i<<10)+j]), lcolor);
2403       }
2404      if(j==xmax) PUTLE16(&psxVuw[(i<<10)+j], color);
2405
2406      if(NextRow_F()) return;
2407     }
2408    return;
2409   }
2410
2411 #endif
2412
2413  for (i=ymin;i<=ymax;i++)
2414   {
2415    xmin=left_x >> 16;      if(drawX>xmin) xmin=drawX;
2416    xmax=(right_x >> 16)-1; if(drawW<xmax) xmax=drawW;
2417
2418    for(j=xmin;j<xmax;j+=2) 
2419     {
2420      GetShadeTransCol32((uint32_t *)&psxVuw[(i<<10)+j],lcolor);
2421     }
2422    if(j==xmax)
2423     GetShadeTransCol(&psxVuw[(i<<10)+j],color);
2424
2425    if(NextRow_F()) return;
2426   }
2427 }
2428
2429 ////////////////////////////////////////////////////////////////////////
2430
2431 static void drawPoly3F(int32_t rgb)
2432 {
2433  drawPoly3Fi(lx0,ly0,lx1,ly1,lx2,ly2,rgb);
2434 }
2435
2436 #ifdef POLYQUAD3FS
2437
2438 static void drawPoly4F_TRI(int32_t rgb)
2439 {
2440  drawPoly3Fi(lx1,ly1,lx3,ly3,lx2,ly2,rgb);
2441  drawPoly3Fi(lx0,ly0,lx1,ly1,lx2,ly2,rgb);
2442 }
2443
2444 #endif
2445
2446 // more exact:
2447
2448 static void drawPoly4F(int32_t rgb)
2449 {
2450  int i,j,xmin,xmax,ymin,ymax;
2451  unsigned short color;uint32_t lcolor;
2452  
2453  if(lx0>drawW && lx1>drawW && lx2>drawW && lx3>drawW) return;
2454  if(ly0>drawH && ly1>drawH && ly2>drawH && ly3>drawH) return;
2455  if(lx0<drawX && lx1<drawX && lx2<drawX && lx3<drawX) return;
2456  if(ly0<drawY && ly1<drawY && ly2<drawY && ly3<drawY) return;
2457  if(drawY>=drawH) return;
2458  if(drawX>=drawW) return; 
2459
2460  if(!SetupSections_F4(lx0,ly0,lx1,ly1,lx2,ly2,lx3,ly3)) return;
2461
2462  ymax=Ymax;
2463
2464  for(ymin=Ymin;ymin<drawY;ymin++)
2465   if(NextRow_F4()) return;
2466
2467  color = ((rgb & 0x00f80000)>>9) | ((rgb & 0x0000f800)>>6) | ((rgb & 0x000000f8)>>3);
2468  lcolor= lSetMask|(((uint32_t)(color))<<16)|color;
2469
2470 #ifdef FASTSOLID
2471
2472  if(!bCheckMask && !DrawSemiTrans)
2473   {
2474    color |=sSetMask;
2475    for (i=ymin;i<=ymax;i++)
2476     {
2477      xmin=left_x >> 16;      if(drawX>xmin) xmin=drawX;
2478      xmax=(right_x >> 16)-1; if(drawW<xmax) xmax=drawW;
2479
2480      for(j=xmin;j<xmax;j+=2) 
2481       {
2482        PUTLE32(((uint32_t *)&psxVuw[(i<<10)+j]), lcolor);
2483       }
2484      if(j==xmax) PUTLE16(&psxVuw[(i<<10)+j], color);
2485
2486      if(NextRow_F4()) return;
2487     }
2488    return;
2489   }                                                        
2490
2491 #endif
2492
2493  for (i=ymin;i<=ymax;i++)
2494   {
2495    xmin=left_x >> 16;      if(drawX>xmin) xmin=drawX;
2496    xmax=(right_x >> 16)-1; if(drawW<xmax) xmax=drawW;
2497
2498    for(j=xmin;j<xmax;j+=2) 
2499     {
2500      GetShadeTransCol32((uint32_t *)&psxVuw[(i<<10)+j],lcolor);
2501     }
2502    if(j==xmax) GetShadeTransCol(&psxVuw[(i<<10)+j],color);
2503
2504    if(NextRow_F4()) return;
2505   }
2506 }
2507
2508 ////////////////////////////////////////////////////////////////////////
2509 // POLY 3/4 F-SHADED TEX PAL 4
2510 ////////////////////////////////////////////////////////////////////////
2511
2512 static void drawPoly3TEx4(short x1, short y1, short x2, short y2, short x3, short y3, short tx1, short ty1, short tx2, short ty2, short tx3, short ty3,short clX, short clY)
2513 {
2514  int i,j,xmin,xmax,ymin,ymax;
2515  int32_t difX, difY,difX2, difY2;
2516  int32_t posX,posY,YAdjust,XAdjust;
2517  int32_t clutP;
2518  short tC1,tC2;
2519  
2520  if(x1>drawW && x2>drawW && x3>drawW) return;
2521  if(y1>drawH && y2>drawH && y3>drawH) return;
2522  if(x1<drawX && x2<drawX && x3<drawX) return;
2523  if(y1<drawY && y2<drawY && y3<drawY) return;
2524  if(drawY>=drawH) return;
2525  if(drawX>=drawW) return; 
2526
2527  if(!SetupSections_FT(x1,y1,x2,y2,x3,y3,tx1,ty1,tx2,ty2,tx3,ty3)) return;
2528
2529  ymax=Ymax;
2530
2531  for(ymin=Ymin;ymin<drawY;ymin++)
2532   if(NextRow_FT()) return;
2533
2534  clutP=(clY<<10)+clX;
2535
2536  YAdjust=((GlobalTextAddrY)<<11)+(GlobalTextAddrX<<1);
2537
2538  difX=delta_right_u;difX2=difX<<1;
2539  difY=delta_right_v;difY2=difY<<1;
2540
2541 #ifdef FASTSOLID
2542
2543  if(!bCheckMask && !DrawSemiTrans)
2544   {
2545    for (i=ymin;i<=ymax;i++)
2546     {
2547      xmin=(left_x >> 16);
2548      xmax=(right_x >> 16)-1; //!!!!!!!!!!!!!!!!
2549      if(drawW<xmax) xmax=drawW;
2550
2551      if(xmax>=xmin)
2552       {
2553        posX=left_u;
2554        posY=left_v;
2555
2556        if(xmin<drawX)
2557         {j=drawX-xmin;xmin=drawX;posX+=j*difX;posY+=j*difY;}
2558
2559        for(j=xmin;j<xmax;j+=2)
2560         {
2561          XAdjust=(posX>>16);
2562          tC1 = psxVub[((posY>>5)&(int32_t)0xFFFFF800)+YAdjust+(XAdjust>>1)];
2563          tC1=(tC1>>((XAdjust&1)<<2))&0xf;
2564          XAdjust=((posX+difX)>>16);
2565          tC2 = psxVub[(((posY+difY)>>5)&(int32_t)0xFFFFF800)+YAdjust+
2566                     (XAdjust>>1)];
2567          tC2=(tC2>>((XAdjust&1)<<2))&0xf;
2568
2569          GetTextureTransColG32_S((uint32_t *)&psxVuw[(i<<10)+j],
2570              GETLE16(&psxVuw[clutP+tC1])|
2571              ((int32_t)GETLE16(&psxVuw[clutP+tC2]))<<16);
2572
2573          posX+=difX2;
2574          posY+=difY2;
2575         }
2576        if(j==xmax)
2577         {
2578          XAdjust=(posX>>16);
2579          tC1 = psxVub[((posY>>5)&(int32_t)0xFFFFF800)+YAdjust+
2580                       (XAdjust>>1)];
2581          tC1=(tC1>>((XAdjust&1)<<2))&0xf;
2582          GetTextureTransColG_S(&psxVuw[(i<<10)+j],GETLE16(&psxVuw[clutP+tC1]));
2583         }
2584       }
2585      if(NextRow_FT()) 
2586       {
2587        return;
2588       }
2589     }
2590    return;
2591   }
2592
2593 #endif
2594
2595  for (i=ymin;i<=ymax;i++)
2596   {
2597    xmin=(left_x >> 16);
2598    xmax=(right_x >> 16)-1; //!!!!!!!!!!!!!!!!!!
2599    if(drawW<xmax) xmax=drawW;
2600
2601    if(xmax>=xmin)
2602     {
2603      posX=left_u;
2604      posY=left_v;
2605
2606      if(xmin<drawX)
2607       {j=drawX-xmin;xmin=drawX;posX+=j*difX;posY+=j*difY;}
2608
2609      for(j=xmin;j<xmax;j+=2)
2610       {
2611        XAdjust=(posX>>16);
2612        tC1 = psxVub[((posY>>5)&(int32_t)0xFFFFF800)+YAdjust+(XAdjust>>1)];
2613        tC1=(tC1>>((XAdjust&1)<<2))&0xf;
2614        XAdjust=((posX+difX)>>16);
2615        tC2 = psxVub[(((posY+difY)>>5)&(int32_t)0xFFFFF800)+YAdjust+
2616                     (XAdjust>>1)];
2617        tC2=(tC2>>((XAdjust&1)<<2))&0xf;
2618
2619        GetTextureTransColG32((uint32_t *)&psxVuw[(i<<10)+j],
2620            GETLE16(&psxVuw[clutP+tC1])|
2621            ((int32_t)GETLE16(&psxVuw[clutP+tC2]))<<16);
2622
2623        posX+=difX2;
2624        posY+=difY2;
2625       }
2626      if(j==xmax)
2627       {
2628        XAdjust=(posX>>16);
2629        tC1 = psxVub[((posY>>5)&(int32_t)0xFFFFF800)+YAdjust+
2630                     (XAdjust>>1)];
2631        tC1=(tC1>>((XAdjust&1)<<2))&0xf;
2632        GetTextureTransColG(&psxVuw[(i<<10)+j],GETLE16(&psxVuw[clutP+tC1]));
2633       }
2634     }
2635    if(NextRow_FT()) 
2636     {
2637      return;
2638     }
2639   }
2640 }
2641
2642 ////////////////////////////////////////////////////////////////////////
2643
2644 static void drawPoly3TEx4_IL(short x1, short y1, short x2, short y2, short x3, short y3, short tx1, short ty1, short tx2, short ty2, short tx3, short ty3,short clX, short clY)
2645 {
2646  int i,j,xmin,xmax,ymin,ymax,n_xi,n_yi,TXV;
2647  int32_t difX, difY,difX2, difY2;
2648  int32_t posX,posY,YAdjust,XAdjust;
2649  int32_t clutP;
2650  short tC1,tC2;
2651  
2652  if(x1>drawW && x2>drawW && x3>drawW) return;
2653  if(y1>drawH && y2>drawH && y3>drawH) return;
2654  if(x1<drawX && x2<drawX && x3<drawX) return;
2655  if(y1<drawY && y2<drawY && y3<drawY) return;
2656  if(drawY>=drawH) return;
2657  if(drawX>=drawW) return; 
2658
2659  if(!SetupSections_FT(x1,y1,x2,y2,x3,y3,tx1,ty1,tx2,ty2,tx3,ty3)) return;
2660
2661  ymax=Ymax;
2662
2663  for(ymin=Ymin;ymin<drawY;ymin++)
2664   if(NextRow_FT()) return;
2665
2666  clutP=(clY<<10)+clX;
2667
2668  YAdjust=(GlobalTextAddrY<<10)+GlobalTextAddrX;
2669
2670  difX=delta_right_u;difX2=difX<<1;
2671  difY=delta_right_v;difY2=difY<<1;
2672
2673 #ifdef FASTSOLID
2674
2675  if(!bCheckMask && !DrawSemiTrans)
2676   {
2677    for (i=ymin;i<=ymax;i++)
2678     {
2679      xmin=(left_x >> 16);
2680      xmax=(right_x >> 16)-1;
2681      if(drawW<xmax) xmax=drawW;
2682
2683      if(xmax>=xmin)
2684       {
2685        posX=left_u;
2686        posY=left_v;
2687
2688        if(xmin<drawX)
2689         {j=drawX-xmin;xmin=drawX;posX+=j*difX;posY+=j*difY;}
2690
2691        for(j=xmin;j<xmax;j+=2)
2692         {
2693          XAdjust=(posX>>16);
2694
2695          TXV=posY>>16;
2696          n_xi = ( ( XAdjust >> 2 ) & ~0x3c ) + ( ( TXV << 2 ) & 0x3c );
2697          n_yi = ( TXV & ~0xf ) + ( ( XAdjust >> 4 ) & 0xf );
2698
2699          tC1= (GETLE16(&psxVuw[(n_yi<<10)+YAdjust+n_xi]) >> ((XAdjust & 0x03)<<2)) & 0x0f ;
2700
2701          XAdjust=((posX+difX)>>16);
2702
2703          TXV=(posY+difY)>>16;
2704          n_xi = ( ( XAdjust >> 2 ) & ~0x3c ) + ( ( TXV << 2 ) & 0x3c );
2705          n_yi = ( TXV & ~0xf ) + ( ( XAdjust >> 4 ) & 0xf );
2706
2707          tC2= (GETLE16(&psxVuw[(n_yi<<10)+YAdjust+n_xi]) >> ((XAdjust & 0x03)<<2)) & 0x0f ;
2708
2709          GetTextureTransColG32_S((uint32_t *)&psxVuw[(i<<10)+j],
2710              GETLE16(&psxVuw[clutP+tC1])|
2711              ((int32_t)GETLE16(&psxVuw[clutP+tC2]))<<16);
2712
2713          posX+=difX2;
2714          posY+=difY2;
2715         }
2716        if(j==xmax)
2717         {
2718          XAdjust=(posX>>16);
2719
2720          TXV=posY>>16;
2721          n_xi = ( ( XAdjust >> 2 ) & ~0x3c ) + ( ( TXV << 2 ) & 0x3c );
2722          n_yi = ( TXV & ~0xf ) + ( ( XAdjust >> 4 ) & 0xf );
2723
2724          tC1= (GETLE16(&psxVuw[(n_yi<<10)+YAdjust+n_xi]) >> ((XAdjust & 0x03)<<2)) & 0x0f ;
2725
2726          GetTextureTransColG_S(&psxVuw[(i<<10)+j],GETLE16(&psxVuw[clutP+tC1]));
2727         }
2728       }
2729      if(NextRow_FT()) 
2730       {
2731        return;
2732       }
2733     }
2734    return;
2735   }
2736
2737 #endif
2738
2739  for (i=ymin;i<=ymax;i++)
2740   {
2741    xmin=(left_x >> 16);
2742    xmax=(right_x >> 16)-1; //!!!!!!!!!!!!!!!!!!
2743    if(drawW<xmax) xmax=drawW;
2744
2745    if(xmax>=xmin)
2746     {
2747      posX=left_u;
2748      posY=left_v;
2749
2750      if(xmin<drawX)
2751       {j=drawX-xmin;xmin=drawX;posX+=j*difX;posY+=j*difY;}
2752
2753      for(j=xmin;j<xmax;j+=2)
2754       {
2755        XAdjust=(posX>>16);
2756
2757        TXV=posY>>16;
2758        n_xi = ( ( XAdjust >> 2 ) & ~0x3c ) + ( ( TXV << 2 ) & 0x3c );
2759        n_yi = ( TXV & ~0xf ) + ( ( XAdjust >> 4 ) & 0xf );
2760
2761        tC1= (GETLE16(&psxVuw[(n_yi<<10)+YAdjust+n_xi]) >> ((XAdjust & 0x03)<<2)) & 0x0f ;
2762
2763        XAdjust=((posX+difX)>>16);
2764
2765        TXV=(posY+difY)>>16;
2766        n_xi = ( ( XAdjust >> 2 ) & ~0x3c ) + ( ( TXV << 2 ) & 0x3c );
2767        n_yi = ( TXV & ~0xf ) + ( ( XAdjust >> 4 ) & 0xf );
2768
2769        tC2= (GETLE16(&psxVuw[(n_yi<<10)+YAdjust+n_xi]) >> ((XAdjust & 0x03)<<2)) & 0x0f ;
2770
2771        GetTextureTransColG32((uint32_t *)&psxVuw[(i<<10)+j],
2772            GETLE16(&psxVuw[clutP+tC1])|
2773            ((int32_t)GETLE16(&psxVuw[clutP+tC2]))<<16);
2774
2775        posX+=difX2;
2776        posY+=difY2;
2777       }
2778      if(j==xmax)
2779       {
2780        XAdjust=(posX>>16);
2781
2782        TXV=posY>>16;
2783        n_xi = ( ( XAdjust >> 2 ) & ~0x3c ) + ( ( TXV << 2 ) & 0x3c );
2784        n_yi = ( TXV & ~0xf ) + ( ( XAdjust >> 4 ) & 0xf );
2785
2786        tC1= (GETLE16(&psxVuw[(n_yi<<10)+YAdjust+n_xi]) >> ((XAdjust & 0x03)<<2)) & 0x0f ;
2787
2788        GetTextureTransColG(&psxVuw[(i<<10)+j],GETLE16(&psxVuw[clutP+tC1]));
2789       }
2790     }
2791    if(NextRow_FT()) 
2792     {
2793      return;
2794     }
2795   }
2796 }
2797
2798 ////////////////////////////////////////////////////////////////////////
2799
2800 static void drawPoly3TEx4_TW(short x1, short y1, short x2, short y2, short x3, short y3, short tx1, short ty1, short tx2, short ty2, short tx3, short ty3,short clX, short clY)
2801 {
2802  int i,j,xmin,xmax,ymin,ymax;
2803  int32_t difX, difY,difX2, difY2;
2804  int32_t posX,posY,YAdjust,XAdjust;
2805  int32_t clutP;
2806  short tC1,tC2;
2807  
2808  if(x1>drawW && x2>drawW && x3>drawW) return;
2809  if(y1>drawH && y2>drawH && y3>drawH) return;
2810  if(x1<drawX && x2<drawX && x3<drawX) return;
2811  if(y1<drawY && y2<drawY && y3<drawY) return;
2812  if(drawY>=drawH) return;
2813  if(drawX>=drawW) return; 
2814
2815  if(!SetupSections_FT(x1,y1,x2,y2,x3,y3,tx1,ty1,tx2,ty2,tx3,ty3)) return;
2816
2817  ymax=Ymax;
2818
2819  for(ymin=Ymin;ymin<drawY;ymin++)
2820   if(NextRow_FT()) return;
2821
2822  clutP=(clY<<10)+clX;
2823
2824  YAdjust=((GlobalTextAddrY)<<11)+(GlobalTextAddrX<<1);
2825  YAdjust+=(TWin.Position.y0<<11)+(TWin.Position.x0>>1);
2826
2827  difX=delta_right_u;difX2=difX<<1;
2828  difY=delta_right_v;difY2=difY<<1;
2829
2830 #ifdef FASTSOLID
2831
2832  if(!bCheckMask && !DrawSemiTrans)
2833   {
2834    for (i=ymin;i<=ymax;i++)
2835     {
2836      xmin=(left_x >> 16);
2837      xmax=(right_x >> 16);//-1; //!!!!!!!!!!!!!!!!
2838      if(xmax>xmin) xmax--;
2839
2840      if(drawW<xmax) xmax=drawW;
2841
2842      if(xmax>=xmin)
2843       {
2844        posX=left_u;
2845        posY=left_v;
2846
2847        if(xmin<drawX)
2848         {j=drawX-xmin;xmin=drawX;posX+=j*difX;posY+=j*difY;}
2849
2850        for(j=xmin;j<xmax;j+=2)
2851         {
2852          XAdjust=(posX>>16)%TWin.Position.x1;
2853          tC1 = psxVub[(((posY>>16)%TWin.Position.y1)<<11)+
2854                       YAdjust+(XAdjust>>1)];
2855          tC1=(tC1>>((XAdjust&1)<<2))&0xf;
2856          XAdjust=((posX+difX)>>16)%TWin.Position.x1;
2857          tC2 = psxVub[((((posY+difY)>>16)%TWin.Position.y1)<<11)+
2858                       YAdjust+(XAdjust>>1)];
2859          tC2=(tC2>>((XAdjust&1)<<2))&0xf;
2860
2861          GetTextureTransColG32_S((uint32_t *)&psxVuw[(i<<10)+j],
2862              GETLE16(&psxVuw[clutP+tC1])|
2863              ((int32_t)GETLE16(&psxVuw[clutP+tC2]))<<16);
2864
2865          posX+=difX2;
2866          posY+=difY2;
2867         }
2868        if(j==xmax)
2869         {
2870          XAdjust=(posX>>16)%TWin.Position.x1;
2871          tC1 = psxVub[(((posY>>16)%TWin.Position.y1)<<11)+
2872                       YAdjust+(XAdjust>>1)];
2873          tC1=(tC1>>((XAdjust&1)<<2))&0xf;
2874          GetTextureTransColG_S(&psxVuw[(i<<10)+j],GETLE16(&psxVuw[clutP+tC1]));
2875         }
2876       }
2877      if(NextRow_FT()) 
2878       {
2879        return;
2880       }
2881     }
2882    return;
2883   }
2884
2885 #endif
2886
2887  for (i=ymin;i<=ymax;i++)
2888   {
2889    xmin=(left_x >> 16);
2890    xmax=(right_x >> 16)-1; //!!!!!!!!!!!!!!!!!!
2891    if(drawW<xmax) xmax=drawW;
2892
2893    if(xmax>=xmin)
2894     {
2895      posX=left_u;
2896      posY=left_v;
2897
2898      if(xmin<drawX)
2899       {j=drawX-xmin;xmin=drawX;posX+=j*difX;posY+=j*difY;}
2900
2901      for(j=xmin;j<xmax;j+=2)
2902       {
2903        XAdjust=(posX>>16)%TWin.Position.x1;
2904        tC1 = psxVub[(((posY>>16)%TWin.Position.y1)<<11)+
2905                     YAdjust+(XAdjust>>1)];
2906        tC1=(tC1>>((XAdjust&1)<<2))&0xf;
2907        XAdjust=((posX+difX)>>16)%TWin.Position.x1;
2908        tC2 = psxVub[((((posY+difY)>>16)%TWin.Position.y1)<<11)+
2909                     YAdjust+(XAdjust>>1)];
2910        tC2=(tC2>>((XAdjust&1)<<2))&0xf;
2911
2912        GetTextureTransColG32((uint32_t *)&psxVuw[(i<<10)+j],
2913            GETLE16(&psxVuw[clutP+tC1])|
2914            ((int32_t)GETLE16(&psxVuw[clutP+tC2]))<<16);
2915
2916        posX+=difX2;
2917        posY+=difY2;
2918       }
2919      if(j==xmax)
2920       {
2921        XAdjust=(posX>>16)%TWin.Position.x1;
2922        tC1 = psxVub[(((posY>>16)%TWin.Position.y1)<<11)+
2923                     YAdjust+(XAdjust>>1)];
2924        tC1=(tC1>>((XAdjust&1)<<2))&0xf;
2925        GetTextureTransColG(&psxVuw[(i<<10)+j],GETLE16(&psxVuw[clutP+tC1]));
2926       }
2927     }
2928    if(NextRow_FT()) 
2929     {
2930      return;
2931     }
2932   }
2933 }
2934
2935 ////////////////////////////////////////////////////////////////////////
2936
2937 #ifdef POLYQUAD3
2938
2939 static void drawPoly4TEx4_TRI(short x1, short y1, short x2, short y2, short x3, short y3, short x4, short y4, short tx1, short ty1, short tx2, short ty2, short tx3, short ty3, short tx4, short ty4,short clX, short clY)
2940 {
2941  drawPoly3TEx4(x2,y2,x3,y3,x4,y4,
2942                tx2,ty2,tx3,ty3,tx4,ty4,
2943                clX,clY);
2944  drawPoly3TEx4(x1,y1,x2,y2,x4,y4,
2945                tx1,ty1,tx2,ty2,tx4,ty4,
2946                clX,clY);
2947 }
2948
2949 #endif
2950
2951 // more exact:
2952
2953 static void drawPoly4TEx4(short x1, short y1, short x2, short y2, short x3, short y3, short x4, short y4, short tx1, short ty1, short tx2, short ty2, short tx3, short ty3, short tx4, short ty4,short clX, short clY)
2954 {
2955  int32_t num; 
2956  int32_t i,j,xmin,xmax,ymin,ymax;
2957  int32_t difX, difY, difX2, difY2;
2958  int32_t posX,posY,YAdjust,clutP,XAdjust;
2959  short tC1,tC2;
2960
2961  if(x1>drawW && x2>drawW && x3>drawW && x4>drawW) return;
2962  if(y1>drawH && y2>drawH && y3>drawH && y4>drawH) return;
2963  if(x1<drawX && x2<drawX && x3<drawX && x4<drawX) return;
2964  if(y1<drawY && y2<drawY && y3<drawY && y4<drawY) return;
2965  if(drawY>=drawH) return;
2966  if(drawX>=drawW) return; 
2967
2968  if(!SetupSections_FT4(x1,y1,x2,y2,x3,y3,x4,y4,tx1,ty1,tx2,ty2,tx3,ty3,tx4,ty4)) return;
2969
2970  ymax=Ymax;
2971
2972  for(ymin=Ymin;ymin<drawY;ymin++)
2973   if(NextRow_FT4()) return;
2974
2975  clutP=(clY<<10)+clX;
2976
2977  YAdjust=((GlobalTextAddrY)<<11)+(GlobalTextAddrX<<1);
2978
2979 #ifdef FASTSOLID
2980
2981  if(!bCheckMask && !DrawSemiTrans)
2982   {
2983    for (i=ymin;i<=ymax;i++)
2984     {
2985      xmin=(left_x >> 16);
2986      xmax=(right_x >> 16);
2987
2988      if(xmax>=xmin)
2989       {
2990        posX=left_u;
2991        posY=left_v;
2992
2993        num=(xmax-xmin);
2994        if(num==0) num=1;
2995        difX=(right_u-posX)/num;
2996        difY=(right_v-posY)/num;
2997        difX2=difX<<1;
2998        difY2=difY<<1;
2999
3000        if(xmin<drawX)
3001         {j=drawX-xmin;xmin=drawX;posX+=j*difX;posY+=j*difY;}
3002        xmax--;if(drawW<xmax) xmax=drawW;
3003
3004        for(j=xmin;j<xmax;j+=2)
3005         {
3006          XAdjust=(posX>>16);
3007          tC1 = psxVub[((posY>>5)&(int32_t)0xFFFFF800)+YAdjust+(XAdjust>>1)];
3008          tC1=(tC1>>((XAdjust&1)<<2))&0xf;
3009          XAdjust=((posX+difX)>>16);
3010          tC2 = psxVub[(((posY+difY)>>5)&(int32_t)0xFFFFF800)+YAdjust+
3011                        (XAdjust>>1)];
3012          tC2=(tC2>>((XAdjust&1)<<2))&0xf;
3013
3014          GetTextureTransColG32_S((uint32_t *)&psxVuw[(i<<10)+j],
3015               GETLE16(&psxVuw[clutP+tC1])|
3016               ((int32_t)GETLE16(&psxVuw[clutP+tC2]))<<16);
3017          posX+=difX2;
3018          posY+=difY2;
3019         }
3020        if(j==xmax)
3021         {
3022          XAdjust=(posX>>16);
3023          tC1 = psxVub[((posY>>5)&(int32_t)0xFFFFF800)+YAdjust+
3024                       (XAdjust>>1)];
3025          tC1=(tC1>>((XAdjust&1)<<2))&0xf;
3026          GetTextureTransColG_S(&psxVuw[(i<<10)+j],GETLE16(&psxVuw[clutP+tC1]));
3027         }
3028
3029       }
3030      if(NextRow_FT4()) return;
3031     }
3032    return;
3033   }
3034
3035 #endif
3036
3037  for (i=ymin;i<=ymax;i++)
3038   {
3039    xmin=(left_x >> 16);
3040    xmax=(right_x >> 16);
3041
3042    if(xmax>=xmin)
3043     {
3044      posX=left_u;
3045      posY=left_v;
3046
3047      num=(xmax-xmin);
3048      if(num==0) num=1;
3049      difX=(right_u-posX)/num;
3050      difY=(right_v-posY)/num;
3051      difX2=difX<<1;
3052      difY2=difY<<1;
3053
3054      if(xmin<drawX)
3055       {j=drawX-xmin;xmin=drawX;posX+=j*difX;posY+=j*difY;}
3056      xmax--;if(drawW<xmax) xmax=drawW;
3057
3058      for(j=xmin;j<xmax;j+=2)
3059       {
3060        XAdjust=(posX>>16);
3061        tC1 = psxVub[((posY>>5)&(int32_t)0xFFFFF800)+YAdjust+(XAdjust>>1)];
3062        tC1=(tC1>>((XAdjust&1)<<2))&0xf;
3063        XAdjust=((posX+difX)>>16);
3064        tC2 = psxVub[(((posY+difY)>>5)&(int32_t)0xFFFFF800)+YAdjust+
3065                      (XAdjust>>1)];
3066        tC2=(tC2>>((XAdjust&1)<<2))&0xf;
3067
3068        GetTextureTransColG32((uint32_t *)&psxVuw[(i<<10)+j],
3069             GETLE16(&psxVuw[clutP+tC1])|
3070             ((int32_t)GETLE16(&psxVuw[clutP+tC2]))<<16);
3071        posX+=difX2;
3072        posY+=difY2;
3073       }
3074      if(j==xmax)
3075       {
3076        XAdjust=(posX>>16);
3077        tC1 = psxVub[((posY>>5)&(int32_t)0xFFFFF800)+YAdjust+
3078                     (XAdjust>>1)];
3079        tC1=(tC1>>((XAdjust&1)<<2))&0xf;
3080        GetTextureTransColG(&psxVuw[(i<<10)+j],GETLE16(&psxVuw[clutP+tC1]));
3081       }
3082     }
3083    if(NextRow_FT4()) return;
3084   }
3085 }
3086
3087 ////////////////////////////////////////////////////////////////////////
3088
3089 static void drawPoly4TEx4_IL(short x1, short y1, short x2, short y2, short x3, short y3, short x4, short y4, short tx1, short ty1, short tx2, short ty2, short tx3, short ty3, short tx4, short ty4,short clX, short clY)
3090 {
3091  int32_t num; 
3092  int32_t i,j=0,xmin,xmax,ymin,ymax,n_xi,n_yi,TXV;
3093  int32_t difX, difY, difX2, difY2;
3094  int32_t posX=0,posY=0,YAdjust,clutP,XAdjust;
3095  short tC1,tC2;
3096
3097  if(x1>drawW && x2>drawW && x3>drawW && x4>drawW) return;
3098  if(y1>drawH && y2>drawH && y3>drawH && y4>drawH) return;
3099  if(x1<drawX && x2<drawX && x3<drawX && x4<drawX) return;
3100  if(y1<drawY && y2<drawY && y3<drawY && y4<drawY) return;
3101  if(drawY>=drawH) return;
3102  if(drawX>=drawW) return; 
3103
3104  if(!SetupSections_FT4(x1,y1,x2,y2,x3,y3,x4,y4,tx1,ty1,tx2,ty2,tx3,ty3,tx4,ty4)) return;
3105
3106  ymax=Ymax;
3107
3108  for(ymin=Ymin;ymin<drawY;ymin++)
3109   if(NextRow_FT4()) return;
3110
3111  clutP=(clY<<10)+clX;
3112
3113  YAdjust=((GlobalTextAddrY)<<10)+GlobalTextAddrX;
3114
3115 #ifdef FASTSOLID
3116
3117  if(!bCheckMask && !DrawSemiTrans)
3118   {
3119    for (i=ymin;i<=ymax;i++)
3120     {
3121      xmin=(left_x >> 16);
3122      xmax=(right_x >> 16);
3123
3124      if(xmax>=xmin)
3125       {
3126        posX=left_u;
3127        posY=left_v;
3128
3129        num=(xmax-xmin);
3130        if(num==0) num=1;
3131        difX=(right_u-posX)/num;
3132        difY=(right_v-posY)/num;
3133        difX2=difX<<1;
3134        difY2=difY<<1;
3135
3136        if(xmin<drawX)
3137         {j=drawX-xmin;xmin=drawX;posX+=j*difX;posY+=j*difY;}
3138        xmax--;if(drawW<xmax) xmax=drawW;
3139
3140        for(j=xmin;j<xmax;j+=2)
3141         {
3142          XAdjust=(posX>>16);
3143
3144          TXV=posY>>16;
3145          n_xi = ( ( XAdjust >> 2 ) & ~0x3c ) + ( ( TXV << 2 ) & 0x3c );
3146          n_yi = ( TXV & ~0xf ) + ( ( XAdjust >> 4 ) & 0xf );
3147
3148          tC1= (GETLE16(&psxVuw[(n_yi<<10)+YAdjust+n_xi]) >> ((XAdjust & 0x03)<<2)) & 0x0f ;
3149
3150          XAdjust=((posX+difX)>>16);
3151
3152          TXV=(posY+difY)>>16;
3153          n_xi = ( ( XAdjust >> 2 ) & ~0x3c ) + ( ( TXV << 2 ) & 0x3c );
3154          n_yi = ( TXV & ~0xf ) + ( ( XAdjust >> 4 ) & 0xf );
3155
3156          tC2= (GETLE16(&psxVuw[(n_yi<<10)+YAdjust+n_xi]) >> ((XAdjust & 0x03)<<2)) & 0x0f ;
3157
3158          GetTextureTransColG32_S((uint32_t *)&psxVuw[(i<<10)+j],
3159               GETLE16(&psxVuw[clutP+tC1])|
3160               ((int32_t)GETLE16(&psxVuw[clutP+tC2]))<<16);
3161          posX+=difX2;
3162          posY+=difY2;
3163         }
3164          posX+=difX2;
3165          posY+=difY2;
3166         }
3167
3168        if(j==xmax)
3169         {
3170          XAdjust=(posX>>16);
3171          TXV=posY>>16;
3172          n_xi = ( ( XAdjust >> 2 ) & ~0x3c ) + ( ( TXV << 2 ) & 0x3c );
3173          n_yi = ( TXV & ~0xf ) + ( ( XAdjust >> 4 ) & 0xf );
3174
3175          tC1= (GETLE16(&psxVuw[(n_yi<<10)+YAdjust+n_xi]) >> ((XAdjust & 0x03)<<2)) & 0x0f ;
3176
3177          GetTextureTransColG_S(&psxVuw[(i<<10)+j],GETLE16(&psxVuw[clutP+tC1]));
3178         }
3179
3180       }
3181      if(NextRow_FT4()) return;
3182     }
3183 #endif
3184
3185  for (i=ymin;i<=ymax;i++)
3186   {
3187    xmin=(left_x >> 16);
3188    xmax=(right_x >> 16);
3189
3190    if(xmax>=xmin)
3191     {
3192      posX=left_u;
3193      posY=left_v;
3194
3195      num=(xmax-xmin);
3196      if(num==0) num=1;
3197      difX=(right_u-posX)/num;
3198      difY=(right_v-posY)/num;
3199      difX2=difX<<1;
3200      difY2=difY<<1;
3201
3202      if(xmin<drawX)
3203       {j=drawX-xmin;xmin=drawX;posX+=j*difX;posY+=j*difY;}
3204      xmax--;if(drawW<xmax) xmax=drawW;
3205
3206      for(j=xmin;j<xmax;j+=2)
3207       {
3208        XAdjust=(posX>>16);
3209
3210        TXV=posY>>16;
3211        n_xi = ( ( XAdjust >> 2 ) & ~0x3c ) + ( ( TXV << 2 ) & 0x3c );
3212        n_yi = ( TXV & ~0xf ) + ( ( XAdjust >> 4 ) & 0xf );
3213
3214        tC1= (GETLE16(&psxVuw[(n_yi<<10)+YAdjust+n_xi]) >> ((XAdjust & 0x03)<<2)) & 0x0f ;
3215
3216        XAdjust=((posX+difX)>>16);
3217
3218        TXV=(posY+difY)>>16;
3219        n_xi = ( ( XAdjust >> 2 ) & ~0x3c ) + ( ( TXV << 2 ) & 0x3c );
3220        n_yi = ( TXV & ~0xf ) + ( ( XAdjust >> 4 ) & 0xf );
3221
3222        tC2= (GETLE16(&psxVuw[(n_yi<<10)+YAdjust+n_xi]) >> ((XAdjust & 0x03)<<2)) & 0x0f ;
3223
3224        GetTextureTransColG32((uint32_t *)&psxVuw[(i<<10)+j],
3225             GETLE16(&psxVuw[clutP+tC1])|
3226             ((int32_t)GETLE16(&psxVuw[clutP+tC2]))<<16);
3227        posX+=difX2;
3228        posY+=difY2;
3229       }
3230      if(j==xmax)
3231       {
3232        XAdjust=(posX>>16);
3233        TXV=posY>>16;
3234        n_xi = ( ( XAdjust >> 2 ) & ~0x3c ) + ( ( TXV << 2 ) & 0x3c );
3235        n_yi = ( TXV & ~0xf ) + ( ( XAdjust >> 4 ) & 0xf );
3236
3237        tC1= (GETLE16(&psxVuw[(n_yi<<10)+YAdjust+n_xi]) >> ((XAdjust & 0x03)<<2)) & 0x0f ;
3238
3239        GetTextureTransColG(&psxVuw[(i<<10)+j],GETLE16(&psxVuw[clutP+tC1]));
3240       }
3241     }
3242    if(NextRow_FT4()) return;
3243   }
3244 }
3245
3246 ////////////////////////////////////////////////////////////////////////
3247
3248 static void drawPoly4TEx4_TW(short x1, short y1, short x2, short y2, short x3, short y3, short x4, short y4, short tx1, short ty1, short tx2, short ty2, short tx3, short ty3, short tx4, short ty4,short clX, short clY)
3249 {
3250  int32_t num; 
3251  int32_t i,j,xmin,xmax,ymin,ymax;
3252  int32_t difX, difY, difX2, difY2;
3253  int32_t posX,posY,YAdjust,clutP,XAdjust;
3254  short tC1,tC2;
3255
3256  if(x1>drawW && x2>drawW && x3>drawW && x4>drawW) return;
3257  if(y1>drawH && y2>drawH && y3>drawH && y4>drawH) return;
3258  if(x1<drawX && x2<drawX && x3<drawX && x4<drawX) return;
3259  if(y1<drawY && y2<drawY && y3<drawY && y4<drawY) return;
3260  if(drawY>=drawH) return;
3261  if(drawX>=drawW) return; 
3262
3263  if(!SetupSections_FT4(x1,y1,x2,y2,x3,y3,x4,y4,tx1,ty1,tx2,ty2,tx3,ty3,tx4,ty4)) return;
3264
3265  ymax=Ymax;
3266
3267  for(ymin=Ymin;ymin<drawY;ymin++)
3268   if(NextRow_FT4()) return;
3269
3270  clutP=(clY<<10)+clX;
3271
3272  YAdjust=((GlobalTextAddrY)<<11)+(GlobalTextAddrX<<1);
3273  YAdjust+=(TWin.Position.y0<<11)+(TWin.Position.x0>>1);
3274
3275 #ifdef FASTSOLID
3276
3277  if(!bCheckMask && !DrawSemiTrans)
3278   {
3279    for (i=ymin;i<=ymax;i++)
3280     {
3281      xmin=(left_x >> 16);
3282      xmax=(right_x >> 16);
3283
3284      if(xmax>=xmin)
3285       {
3286        posX=left_u;
3287        posY=left_v;
3288
3289        num=(xmax-xmin);
3290        if(num==0) num=1;
3291        difX=(right_u-posX)/num;
3292        difY=(right_v-posY)/num;
3293        difX2=difX<<1;
3294        difY2=difY<<1;
3295
3296        if(xmin<drawX)
3297         {j=drawX-xmin;xmin=drawX;posX+=j*difX;posY+=j*difY;}
3298        xmax--;if(drawW<xmax) xmax=drawW;
3299
3300        for(j=xmin;j<xmax;j+=2)
3301         {
3302          XAdjust=(posX>>16)%TWin.Position.x1;
3303          tC1 = psxVub[(((posY>>16)%TWin.Position.y1)<<11)+
3304                       YAdjust+(XAdjust>>1)];
3305          tC1=(tC1>>((XAdjust&1)<<2))&0xf;
3306          XAdjust=((posX+difX)>>16)%TWin.Position.x1;
3307          tC2 = psxVub[((((posY+difY)>>16)%TWin.Position.y1)<<11)+
3308                       YAdjust+(XAdjust>>1)];
3309          tC2=(tC2>>((XAdjust&1)<<2))&0xf;
3310
3311          GetTextureTransColG32_S((uint32_t *)&psxVuw[(i<<10)+j],
3312               GETLE16(&psxVuw[clutP+tC1])|
3313               ((int32_t)GETLE16(&psxVuw[clutP+tC2]))<<16);
3314          posX+=difX2;
3315          posY+=difY2;
3316         }
3317        if(j==xmax)
3318         {
3319          XAdjust=(posX>>16)%TWin.Position.x1;
3320          tC1 = psxVub[(((posY>>16)%TWin.Position.y1)<<11)+
3321                       YAdjust+(XAdjust>>1)];
3322          tC1=(tC1>>((XAdjust&1)<<2))&0xf;
3323          GetTextureTransColG_S(&psxVuw[(i<<10)+j],GETLE16(&psxVuw[clutP+tC1]));
3324         }
3325       }
3326      if(NextRow_FT4()) return;
3327     }
3328    return;
3329   }
3330
3331 #endif
3332
3333  for (i=ymin;i<=ymax;i++)
3334   {
3335    xmin=(left_x >> 16);
3336    xmax=(right_x >> 16);
3337
3338    if(xmax>=xmin)
3339     {
3340      posX=left_u;
3341      posY=left_v;
3342
3343      num=(xmax-xmin);
3344      if(num==0) num=1;
3345      difX=(right_u-posX)/num;
3346      difY=(right_v-posY)/num;
3347      difX2=difX<<1;
3348      difY2=difY<<1;
3349
3350      if(xmin<drawX)
3351       {j=drawX-xmin;xmin=drawX;posX+=j*difX;posY+=j*difY;}
3352      xmax--;if(drawW<xmax) xmax=drawW;
3353
3354      for(j=xmin;j<xmax;j+=2)
3355       {
3356        XAdjust=(posX>>16)%TWin.Position.x1;
3357        tC1 = psxVub[(((posY>>16)%TWin.Position.y1)<<11)+
3358                     YAdjust+(XAdjust>>1)];
3359        tC1=(tC1>>((XAdjust&1)<<2))&0xf;
3360        XAdjust=((posX+difX)>>16)%TWin.Position.x1;
3361        tC2 = psxVub[((((posY+difY)>>16)%TWin.Position.y1)<<11)+
3362                     YAdjust+(XAdjust>>1)];
3363        tC2=(tC2>>((XAdjust&1)<<2))&0xf;
3364
3365        GetTextureTransColG32((uint32_t *)&psxVuw[(i<<10)+j],
3366             GETLE16(&psxVuw[clutP+tC1])|
3367             ((int32_t)GETLE16(&psxVuw[clutP+tC2]))<<16);
3368        posX+=difX2;
3369        posY+=difY2;
3370       }
3371      if(j==xmax)
3372       {
3373        XAdjust=(posX>>16)%TWin.Position.x1;
3374        tC1 = psxVub[(((posY>>16)%TWin.Position.y1)<<11)+
3375                     YAdjust+(XAdjust>>1)];
3376        tC1=(tC1>>((XAdjust&1)<<2))&0xf;
3377        GetTextureTransColG(&psxVuw[(i<<10)+j],GETLE16(&psxVuw[clutP+tC1]));
3378       }
3379     }
3380    if(NextRow_FT4()) return;
3381   }
3382 }
3383
3384 ////////////////////////////////////////////////////////////////////////
3385
3386 static void drawPoly4TEx4_TW_S(short x1, short y1, short x2, short y2, short x3, short y3, short x4, short y4, short tx1, short ty1, short tx2, short ty2, short tx3, short ty3, short tx4, short ty4,short clX, short clY)
3387 {
3388  int32_t num; 
3389  int32_t i,j,xmin,xmax,ymin,ymax;
3390  int32_t difX, difY, difX2, difY2;
3391  int32_t posX,posY,YAdjust,clutP,XAdjust;
3392  short tC1,tC2;
3393
3394  if(x1>drawW && x2>drawW && x3>drawW && x4>drawW) return;
3395  if(y1>drawH && y2>drawH && y3>drawH && y4>drawH) return;
3396  if(x1<drawX && x2<drawX && x3<drawX && x4<drawX) return;
3397  if(y1<drawY && y2<drawY && y3<drawY && y4<drawY) return;
3398  if(drawY>=drawH) return;
3399  if(drawX>=drawW) return; 
3400
3401  if(!SetupSections_FT4(x1,y1,x2,y2,x3,y3,x4,y4,tx1,ty1,tx2,ty2,tx3,ty3,tx4,ty4)) return;
3402
3403  ymax=Ymax;
3404
3405  for(ymin=Ymin;ymin<drawY;ymin++)
3406   if(NextRow_FT4()) return;
3407
3408  clutP=(clY<<10)+clX;
3409
3410  YAdjust=((GlobalTextAddrY)<<11)+(GlobalTextAddrX<<1);
3411  YAdjust+=(TWin.Position.y0<<11)+(TWin.Position.x0>>1);
3412
3413 #ifdef FASTSOLID
3414
3415  if(!bCheckMask && !DrawSemiTrans)
3416   {
3417    for (i=ymin;i<=ymax;i++)
3418     {
3419      xmin=(left_x >> 16);
3420      xmax=(right_x >> 16);
3421
3422      if(xmax>=xmin)
3423       {
3424        posX=left_u;
3425        posY=left_v;
3426
3427        num=(xmax-xmin);
3428        if(num==0) num=1;
3429        difX=(right_u-posX)/num;
3430        difY=(right_v-posY)/num;
3431        difX2=difX<<1;
3432        difY2=difY<<1;
3433
3434        if(xmin<drawX)
3435         {j=drawX-xmin;xmin=drawX;posX+=j*difX;posY+=j*difY;}
3436        xmax--;if(drawW<xmax) xmax=drawW;
3437
3438        for(j=xmin;j<xmax;j+=2)
3439         {
3440          XAdjust=(posX>>16)%TWin.Position.x1;
3441          tC1 = psxVub[(((posY>>16)%TWin.Position.y1)<<11)+
3442                       YAdjust+(XAdjust>>1)];
3443          tC1=(tC1>>((XAdjust&1)<<2))&0xf;
3444          XAdjust=((posX+difX)>>16)%TWin.Position.x1;
3445          tC2 = psxVub[((((posY+difY)>>16)%TWin.Position.y1)<<11)+
3446                       YAdjust+(XAdjust>>1)];
3447          tC2=(tC2>>((XAdjust&1)<<2))&0xf;
3448
3449          GetTextureTransColG32_S((uint32_t *)&psxVuw[(i<<10)+j],
3450               GETLE16(&psxVuw[clutP+tC1])|
3451               ((int32_t)GETLE16(&psxVuw[clutP+tC2]))<<16);
3452          posX+=difX2;
3453          posY+=difY2;
3454         }
3455        if(j==xmax)
3456         {
3457          XAdjust=(posX>>16)%TWin.Position.x1;
3458          tC1 = psxVub[(((posY>>16)%TWin.Position.y1)<<11)+
3459                       YAdjust+(XAdjust>>1)];
3460          tC1=(tC1>>((XAdjust&1)<<2))&0xf;
3461          GetTextureTransColG_S(&psxVuw[(i<<10)+j],GETLE16(&psxVuw[clutP+tC1]));
3462         }
3463       }
3464      if(NextRow_FT4()) return;
3465     }
3466    return;
3467   }
3468
3469 #endif
3470
3471  for (i=ymin;i<=ymax;i++)
3472   {
3473    xmin=(left_x >> 16);
3474    xmax=(right_x >> 16);
3475
3476    if(xmax>=xmin)
3477     {
3478      posX=left_u;
3479      posY=left_v;
3480
3481      num=(xmax-xmin);
3482      if(num==0) num=1;
3483      difX=(right_u-posX)/num;
3484      difY=(right_v-posY)/num;
3485      difX2=difX<<1;
3486      difY2=difY<<1;
3487
3488      if(xmin<drawX)
3489       {j=drawX-xmin;xmin=drawX;posX+=j*difX;posY+=j*difY;}
3490      xmax--;if(drawW<xmax) xmax=drawW;
3491
3492      for(j=xmin;j<xmax;j+=2)
3493       {
3494        XAdjust=(posX>>16)%TWin.Position.x1;
3495        tC1 = psxVub[(((posY>>16)%TWin.Position.y1)<<11)+
3496                     YAdjust+(XAdjust>>1)];
3497        tC1=(tC1>>((XAdjust&1)<<2))&0xf;
3498        XAdjust=((posX+difX)>>16)%TWin.Position.x1;
3499        tC2 = psxVub[((((posY+difY)>>16)%TWin.Position.y1)<<11)+
3500                     YAdjust+(XAdjust>>1)];
3501        tC2=(tC2>>((XAdjust&1)<<2))&0xf;
3502
3503        GetTextureTransColG32_SPR((uint32_t *)&psxVuw[(i<<10)+j],
3504             GETLE16(&psxVuw[clutP+tC1])|
3505             ((int32_t)GETLE16(&psxVuw[clutP+tC2]))<<16);
3506        posX+=difX2;
3507        posY+=difY2;
3508       }
3509      if(j==xmax)
3510       {
3511        XAdjust=(posX>>16)%TWin.Position.x1;
3512        tC1 = psxVub[(((posY>>16)%TWin.Position.y1)<<11)+
3513                     YAdjust+(XAdjust>>1)];
3514        tC1=(tC1>>((XAdjust&1)<<2))&0xf;
3515        GetTextureTransColG_SPR(&psxVuw[(i<<10)+j],GETLE16(&psxVuw[clutP+tC1]));
3516       }
3517     }
3518    if(NextRow_FT4()) return;
3519   }
3520 }
3521 ////////////////////////////////////////////////////////////////////////
3522 // POLY 3 F-SHADED TEX PAL 8
3523 ////////////////////////////////////////////////////////////////////////
3524
3525 static void drawPoly3TEx8(short x1, short y1, short x2, short y2, short x3, short y3, short tx1, short ty1, short tx2, short ty2, short tx3, short ty3,short clX, short clY)
3526 {
3527  int i,j,xmin,xmax,ymin,ymax;
3528  int32_t difX, difY,difX2, difY2;
3529  int32_t posX,posY,YAdjust,clutP;
3530  short tC1,tC2;
3531
3532  if(x1>drawW && x2>drawW && x3>drawW) return;
3533  if(y1>drawH && y2>drawH && y3>drawH) return;
3534  if(x1<drawX && x2<drawX && x3<drawX) return;
3535  if(y1<drawY && y2<drawY && y3<drawY) return;
3536  if(drawY>=drawH) return;
3537  if(drawX>=drawW) return; 
3538
3539  if(!SetupSections_FT(x1,y1,x2,y2,x3,y3,tx1,ty1,tx2,ty2,tx3,ty3)) return;
3540
3541  ymax=Ymax;
3542
3543  for(ymin=Ymin;ymin<drawY;ymin++)
3544   if(NextRow_FT()) return;
3545
3546  clutP=(clY<<10)+clX;
3547
3548  YAdjust=((GlobalTextAddrY)<<11)+(GlobalTextAddrX<<1);
3549
3550  difX=delta_right_u;difX2=difX<<1;
3551  difY=delta_right_v;difY2=difY<<1;
3552
3553 #ifdef FASTSOLID
3554
3555  if(!bCheckMask && !DrawSemiTrans)
3556   {
3557    for (i=ymin;i<=ymax;i++)
3558     {
3559      xmin=(left_x >> 16);
3560      xmax=(right_x >> 16)-1; //!!!!!!!!!!!!!!!
3561      if(drawW<xmax) xmax=drawW;
3562
3563      if(xmax>=xmin)
3564       {
3565        posX=left_u;
3566        posY=left_v;
3567
3568        if(xmin<drawX)
3569         {j=drawX-xmin;xmin=drawX;posX+=j*difX;posY+=j*difY;}
3570
3571        for(j=xmin;j<xmax;j+=2)
3572         {
3573          tC1 = psxVub[((posY>>5)&(int32_t)0xFFFFF800)+YAdjust+(posX>>16)];
3574          tC2 = psxVub[(((posY+difY)>>5)&(int32_t)0xFFFFF800)+YAdjust+
3575                       ((posX+difX)>>16)];
3576          GetTextureTransColG32_S((uint32_t *)&psxVuw[(i<<10)+j],
3577              GETLE16(&psxVuw[clutP+tC1])|
3578              ((int32_t)GETLE16(&psxVuw[clutP+tC2]))<<16);
3579          posX+=difX2;
3580          posY+=difY2;
3581         }
3582
3583        if(j==xmax)
3584         {
3585