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