fd80270ead4d9233955d4a920e07389a9325ad8e
[pcsx_rearmed.git] / plugins / dfxvideo / soft.c
1 /***************************************************************************
2                           soft.c  -  description
3                              -------------------
4     begin                : Sun Oct 28 2001
5     copyright            : (C) 2001 by Pete Bernert
6     email                : BlackDove@addcom.de
7  ***************************************************************************/
8 /***************************************************************************
9  *                                                                         *
10  *   This program is free software; you can redistribute it and/or modify  *
11  *   it under the terms of the GNU General Public License as published by  *
12  *   the Free Software Foundation; either version 2 of the License, or     *
13  *   (at your option) any later version. See also the license.txt file for *
14  *   additional informations.                                              *
15  *                                                                         *
16  ***************************************************************************/
17
18 // switches for painting textured quads as 2 triangles (small glitches, but better shading!)
19 // can be toggled by game fix 0x200 in version 1.17 anyway, so let the defines enabled!
20 #define POLYQUAD3                 
21 #define POLYQUAD3GT                 
22
23 // fast solid loops... a bit more additional code, of course
24 #define FASTSOLID
25
26 // psx blending mode 3 with 25% incoming color (instead 50% without the define)
27 #define HALFBRIGHTMODE3
28
29 // color decode defines
30
31 #define XCOL1(x)     (x & 0x1f)
32 #define XCOL2(x)     (x & 0x3e0)
33 #define XCOL3(x)     (x & 0x7c00)
34
35 #define XCOL1D(x)     (x & 0x1f)
36 #define XCOL2D(x)     ((x>>5) & 0x1f)
37 #define XCOL3D(x)     ((x>>10) & 0x1f)
38
39 #define X32TCOL1(x)  ((x & 0x001f001f)<<7)
40 #define X32TCOL2(x)  ((x & 0x03e003e0)<<2)
41 #define X32TCOL3(x)  ((x & 0x7c007c00)>>3)
42
43 #define X32COL1(x)   (x & 0x001f001f)
44 #define X32COL2(x)   ((x>>5) & 0x001f001f)
45 #define X32COL3(x)   ((x>>10) & 0x001f001f)
46
47 #define X32ACOL1(x)  (x & 0x001e001e)
48 #define X32ACOL2(x)  ((x>>5) & 0x001e001e)
49 #define X32ACOL3(x)  ((x>>10) & 0x001e001e)
50
51 #define X32BCOL1(x)  (x & 0x001c001c)
52 #define X32BCOL2(x)  ((x>>5) & 0x001c001c)
53 #define X32BCOL3(x)  ((x>>10) & 0x001c001c)
54
55 #define X32PSXCOL(r,g,b) ((g<<10)|(b<<5)|r)
56
57 #define XPSXCOL(r,g,b) ((g&0x7c00)|(b&0x3e0)|(r&0x1f))
58
59 // soft globals
60 short g_m1=255,g_m2=255,g_m3=255;
61 short DrawSemiTrans=FALSE;
62 short Ymin;
63 short Ymax;
64 short          ly0,lx0,ly1,lx1,ly2,lx2,ly3,lx3;        // global psx vertex coords
65 int32_t           GlobalTextAddrX,GlobalTextAddrY,GlobalTextTP,GlobalTextIL;
66 int32_t           GlobalTextREST,GlobalTextABR,GlobalTextPAGE;
67
68 ////////////////////////////////////////////////////////////////////////
69 // POLYGON OFFSET FUNCS
70 ////////////////////////////////////////////////////////////////////////
71
72 static void offsetPSX2(void)
73 {
74  lx0 += PSXDisplay.DrawOffset.x;
75  ly0 += PSXDisplay.DrawOffset.y;
76  lx1 += PSXDisplay.DrawOffset.x;
77  ly1 += PSXDisplay.DrawOffset.y;
78 }
79
80 static void offsetPSX3(void)
81 {
82  lx0 += PSXDisplay.DrawOffset.x;
83  ly0 += PSXDisplay.DrawOffset.y;
84  lx1 += PSXDisplay.DrawOffset.x;
85  ly1 += PSXDisplay.DrawOffset.y;
86  lx2 += PSXDisplay.DrawOffset.x;
87  ly2 += PSXDisplay.DrawOffset.y;
88 }
89
90 static void offsetPSX4(void)
91 {
92  lx0 += PSXDisplay.DrawOffset.x;
93  ly0 += PSXDisplay.DrawOffset.y;
94  lx1 += PSXDisplay.DrawOffset.x;
95  ly1 += PSXDisplay.DrawOffset.y;
96  lx2 += PSXDisplay.DrawOffset.x;
97  ly2 += PSXDisplay.DrawOffset.y;
98  lx3 += PSXDisplay.DrawOffset.x;
99  ly3 += PSXDisplay.DrawOffset.y;
100 }
101
102 /////////////////////////////////////////////////////////////////
103 /////////////////////////////////////////////////////////////////
104 /////////////////////////////////////////////////////////////////
105 // PER PIXEL FUNCS
106 ////////////////////////////////////////////////////////////////////////
107 /////////////////////////////////////////////////////////////////
108 /////////////////////////////////////////////////////////////////
109
110
111 unsigned char dithertable[16] =
112 {
113     7, 0, 6, 1,
114     2, 5, 3, 4,
115     1, 6, 0, 7,
116     4, 3, 5, 2
117 };
118
119 static inline void Dither16(unsigned short * pdest,uint32_t r,uint32_t g,uint32_t b,unsigned short sM)
120 {
121  unsigned char coeff;
122  unsigned char rlow, glow, blow;
123  int x,y;
124                  
125  x=pdest-psxVuw;
126  y=x>>10;
127  x-=(y<<10);
128
129  coeff = dithertable[(y&3)*4+(x&3)];
130
131  rlow = r&7; glow = g&7; blow = b&7;
132
133  r>>=3; g>>=3; b>>=3;
134
135  if ((r < 0x1F) && rlow > coeff) r++;
136  if ((g < 0x1F) && glow > coeff) g++;
137  if ((b < 0x1F) && blow > coeff) b++;
138
139  PUTLE16(pdest, ((unsigned short)b<<10) |
140         ((unsigned short)g<<5) |
141         (unsigned short)r | sM);
142 }
143
144 /////////////////////////////////////////////////////////////////
145 /////////////////////////////////////////////////////////////////
146 /////////////////////////////////////////////////////////////////
147
148 static inline void GetShadeTransCol_Dither(unsigned short * pdest, int32_t m1, int32_t m2, int32_t m3)
149 {
150  int32_t r,g,b;
151
152  if(bCheckMask && (*pdest & HOST2LE16(0x8000))) return;
153
154  if(DrawSemiTrans)
155   {
156    r=((XCOL1D(GETLE16(pdest)))<<3);
157    b=((XCOL2D(GETLE16(pdest)))<<3);
158    g=((XCOL3D(GETLE16(pdest)))<<3);
159
160    if(GlobalTextABR==0)
161     {
162      r=(r>>1)+(m1>>1);
163      b=(b>>1)+(m2>>1);
164      g=(g>>1)+(m3>>1);
165     }
166    else
167    if(GlobalTextABR==1)
168     {
169      r+=m1;
170      b+=m2;
171      g+=m3;
172     }
173    else
174    if(GlobalTextABR==2)
175     {
176      r-=m1;
177      b-=m2;
178      g-=m3;
179      if(r&0x80000000) r=0;
180      if(b&0x80000000) b=0;
181      if(g&0x80000000) g=0;
182     }
183    else
184     {
185 #ifdef HALFBRIGHTMODE3
186      r+=(m1>>2);
187      b+=(m2>>2);
188      g+=(m3>>2);
189 #else
190      r+=(m1>>1);
191      b+=(m2>>1);
192      g+=(m3>>1);
193 #endif
194     }
195   }
196  else 
197   {
198    r=m1;
199    b=m2;
200    g=m3;
201   }
202
203  if(r&0x7FFFFF00) r=0xff;
204  if(b&0x7FFFFF00) b=0xff;
205  if(g&0x7FFFFF00) g=0xff;
206
207  Dither16(pdest,r,b,g,sSetMask);
208 }
209
210 ////////////////////////////////////////////////////////////////////////
211
212 static inline void GetShadeTransCol(unsigned short * pdest,unsigned short color)
213 {
214  if(bCheckMask && (*pdest & HOST2LE16(0x8000))) return;
215
216  if(DrawSemiTrans)
217   {
218    int32_t r,g,b;
219  
220    if(GlobalTextABR==0)
221     {
222      PUTLE16(pdest, (((GETLE16(pdest)&0x7bde)>>1)+(((color)&0x7bde)>>1))|sSetMask);//0x8000;
223      return;
224     }
225    else
226    if(GlobalTextABR==1)
227     {
228      r=(XCOL1(GETLE16(pdest)))+((XCOL1(color)));
229      b=(XCOL2(GETLE16(pdest)))+((XCOL2(color)));
230      g=(XCOL3(GETLE16(pdest)))+((XCOL3(color)));
231     }
232    else
233    if(GlobalTextABR==2)
234     {
235      r=(XCOL1(GETLE16(pdest)))-((XCOL1(color)));
236      b=(XCOL2(GETLE16(pdest)))-((XCOL2(color)));
237      g=(XCOL3(GETLE16(pdest)))-((XCOL3(color)));
238      if(r&0x80000000) r=0;
239      if(b&0x80000000) b=0;
240      if(g&0x80000000) g=0;
241    }
242    else
243     {
244 #ifdef HALFBRIGHTMODE3
245      r=(XCOL1(GETLE16(pdest)))+((XCOL1(color))>>2);
246      b=(XCOL2(GETLE16(pdest)))+((XCOL2(color))>>2);
247      g=(XCOL3(GETLE16(pdest)))+((XCOL3(color))>>2);
248 #else
249      r=(XCOL1(GETLE16(pdest)))+((XCOL1(color))>>1);
250      b=(XCOL2(GETLE16(pdest)))+((XCOL2(color))>>1);
251      g=(XCOL3(GETLE16(pdest)))+((XCOL3(color))>>1);
252 #endif
253     }
254
255    if(r&0x7FFFFFE0) r=0x1f;
256    if(b&0x7FFFFC00) b=0x3e0;
257    if(g&0x7FFF8000) g=0x7c00;
258
259    PUTLE16(pdest, (XPSXCOL(r,g,b))|sSetMask);//0x8000;
260   }
261  else PUTLE16(pdest, color|sSetMask);
262 }  
263
264 ////////////////////////////////////////////////////////////////////////
265
266 static inline void GetShadeTransCol32(uint32_t * pdest,uint32_t color)
267 {
268  if(DrawSemiTrans)
269   {
270    int32_t r,g,b;
271  
272    if(GlobalTextABR==0)
273     {
274      if(!bCheckMask)
275       {
276        PUTLE32(pdest, (((GETLE32(pdest)&0x7bde7bde)>>1)+(((color)&0x7bde7bde)>>1))|lSetMask);//0x80008000;
277        return;
278       }
279      r=(X32ACOL1(GETLE32(pdest))>>1)+((X32ACOL1(color))>>1);
280      b=(X32ACOL2(GETLE32(pdest))>>1)+((X32ACOL2(color))>>1);
281      g=(X32ACOL3(GETLE32(pdest))>>1)+((X32ACOL3(color))>>1);
282     }
283    else
284    if(GlobalTextABR==1)
285     {
286      r=(X32COL1(GETLE32(pdest)))+((X32COL1(color)));
287      b=(X32COL2(GETLE32(pdest)))+((X32COL2(color)));
288      g=(X32COL3(GETLE32(pdest)))+((X32COL3(color)));
289     }
290    else
291    if(GlobalTextABR==2)
292     {
293      int32_t sr,sb,sg,src,sbc,sgc,c;
294      src=XCOL1(color);sbc=XCOL2(color);sgc=XCOL3(color);
295      c=GETLE32(pdest)>>16;
296      sr=(XCOL1(c))-src;   if(sr&0x8000) sr=0;
297      sb=(XCOL2(c))-sbc;  if(sb&0x8000) sb=0;
298      sg=(XCOL3(c))-sgc; if(sg&0x8000) sg=0;
299      r=((int32_t)sr)<<16;b=((int32_t)sb)<<11;g=((int32_t)sg)<<6;
300      c=LOWORD(GETLE32(pdest));
301      sr=(XCOL1(c))-src;   if(sr&0x8000) sr=0;
302      sb=(XCOL2(c))-sbc;  if(sb&0x8000) sb=0;
303      sg=(XCOL3(c))-sgc; if(sg&0x8000) sg=0;
304      r|=sr;b|=sb>>5;g|=sg>>10;
305     }
306    else
307     {
308 #ifdef HALFBRIGHTMODE3
309      r=(X32COL1(GETLE32(pdest)))+((X32BCOL1(color))>>2);
310      b=(X32COL2(GETLE32(pdest)))+((X32BCOL2(color))>>2);
311      g=(X32COL3(GETLE32(pdest)))+((X32BCOL3(color))>>2);
312 #else
313      r=(X32COL1(GETLE32(pdest)))+((X32ACOL1(color))>>1);
314      b=(X32COL2(GETLE32(pdest)))+((X32ACOL2(color))>>1);
315      g=(X32COL3(GETLE32(pdest)))+((X32ACOL3(color))>>1);
316 #endif
317     }
318
319    if(r&0x7FE00000) r=0x1f0000|(r&0xFFFF);
320    if(r&0x7FE0)     r=0x1f    |(r&0xFFFF0000);
321    if(b&0x7FE00000) b=0x1f0000|(b&0xFFFF);
322    if(b&0x7FE0)     b=0x1f    |(b&0xFFFF0000);
323    if(g&0x7FE00000) g=0x1f0000|(g&0xFFFF);
324    if(g&0x7FE0)     g=0x1f    |(g&0xFFFF0000);
325
326    if(bCheckMask) 
327     {
328      uint32_t ma=GETLE32(pdest);
329      PUTLE32(pdest, (X32PSXCOL(r,g,b))|lSetMask);//0x80008000;
330      if(ma&0x80000000) PUTLE32(pdest, (ma&0xFFFF0000)|(*pdest&0xFFFF));
331      if(ma&0x00008000) PUTLE32(pdest, (ma&0xFFFF)    |(*pdest&0xFFFF0000));
332      return;
333     }
334    PUTLE32(pdest, (X32PSXCOL(r,g,b))|lSetMask);//0x80008000;
335   }
336  else 
337   {
338    if(bCheckMask) 
339     {
340      uint32_t ma=GETLE32(pdest);
341      PUTLE32(pdest, color|lSetMask);//0x80008000;
342      if(ma&0x80000000) PUTLE32(pdest, (ma&0xFFFF0000)|(GETLE32(pdest)&0xFFFF));
343      if(ma&0x00008000) PUTLE32(pdest, (ma&0xFFFF)    |(GETLE32(pdest)&0xFFFF0000));
344      return;
345     }
346
347    PUTLE32(pdest, color|lSetMask);//0x80008000;
348   }
349 }  
350
351 ////////////////////////////////////////////////////////////////////////
352
353 static inline void GetTextureTransColG(unsigned short * pdest,unsigned short color)
354 {
355  int32_t r,g,b;unsigned short l;
356
357  if(color==0) return;
358
359  if(bCheckMask && (*pdest & HOST2LE16(0x8000))) return;
360
361  l=sSetMask|(color&0x8000);
362
363  if(DrawSemiTrans && (color&0x8000))
364   {
365    if(GlobalTextABR==0)
366     {
367      unsigned short d;
368      d     =(GETLE16(pdest)&0x7bde)>>1;
369      color =((color) &0x7bde)>>1;
370      r=(XCOL1(d))+((((XCOL1(color)))* g_m1)>>7);
371      b=(XCOL2(d))+((((XCOL2(color)))* g_m2)>>7);
372      g=(XCOL3(d))+((((XCOL3(color)))* g_m3)>>7);
373     }
374    else
375    if(GlobalTextABR==1)
376     {
377      r=(XCOL1(GETLE16(pdest)))+((((XCOL1(color)))* g_m1)>>7);
378      b=(XCOL2(GETLE16(pdest)))+((((XCOL2(color)))* g_m2)>>7);
379      g=(XCOL3(GETLE16(pdest)))+((((XCOL3(color)))* g_m3)>>7);
380     }
381    else
382    if(GlobalTextABR==2)
383     {
384      r=(XCOL1(GETLE16(pdest)))-((((XCOL1(color)))* g_m1)>>7);
385      b=(XCOL2(GETLE16(pdest)))-((((XCOL2(color)))* g_m2)>>7);
386      g=(XCOL3(GETLE16(pdest)))-((((XCOL3(color)))* g_m3)>>7);
387      if(r&0x80000000) r=0;
388      if(b&0x80000000) b=0;
389      if(g&0x80000000) g=0;
390     }
391    else
392     {
393 #ifdef HALFBRIGHTMODE3
394      r=(XCOL1(GETLE16(pdest)))+((((XCOL1(color))>>2)* g_m1)>>7);
395      b=(XCOL2(GETLE16(pdest)))+((((XCOL2(color))>>2)* g_m2)>>7);
396      g=(XCOL3(GETLE16(pdest)))+((((XCOL3(color))>>2)* g_m3)>>7);
397 #else
398      r=(XCOL1(GETLE16(pdest)))+((((XCOL1(color))>>1)* g_m1)>>7);
399      b=(XCOL2(GETLE16(pdest)))+((((XCOL2(color))>>1)* g_m2)>>7);
400      g=(XCOL3(GETLE16(pdest)))+((((XCOL3(color))>>1)* g_m3)>>7);
401 #endif
402     }
403   }
404  else 
405   {
406    r=((XCOL1(color))* g_m1)>>7;
407    b=((XCOL2(color))* g_m2)>>7;
408    g=((XCOL3(color))* g_m3)>>7;
409   }
410
411  if(r&0x7FFFFFE0) r=0x1f;
412  if(b&0x7FFFFC00) b=0x3e0;
413  if(g&0x7FFF8000) g=0x7c00;
414
415  PUTLE16(pdest, (XPSXCOL(r,g,b))|l);
416 }
417
418 ////////////////////////////////////////////////////////////////////////
419
420 static inline void GetTextureTransColG_S(unsigned short * pdest,unsigned short color)
421 {
422  int32_t r,g,b;unsigned short l;
423
424  if(color==0) return;
425
426  l=sSetMask|(color&0x8000);
427
428  r=((XCOL1(color))* g_m1)>>7;
429  b=((XCOL2(color))* g_m2)>>7;
430  g=((XCOL3(color))* g_m3)>>7;
431
432  if(r&0x7FFFFFE0) r=0x1f;
433  if(b&0x7FFFFC00) b=0x3e0;
434  if(g&0x7FFF8000) g=0x7c00;
435
436  PUTLE16(pdest, (XPSXCOL(r,g,b))|l);
437 }
438
439 ////////////////////////////////////////////////////////////////////////
440
441 static inline void GetTextureTransColG_SPR(unsigned short * pdest,unsigned short color)
442 {
443  int32_t r,g,b;unsigned short l;
444
445  if(color==0) return;
446
447  if(bCheckMask && (GETLE16(pdest) & 0x8000)) return;
448
449  l=sSetMask|(color&0x8000);
450
451  if(DrawSemiTrans && (color&0x8000))
452   {
453    if(GlobalTextABR==0)
454     {
455      unsigned short d;
456      d     =(GETLE16(pdest)&0x7bde)>>1;
457      color =((color) &0x7bde)>>1;
458      r=(XCOL1(d))+((((XCOL1(color)))* g_m1)>>7);
459      b=(XCOL2(d))+((((XCOL2(color)))* g_m2)>>7);
460      g=(XCOL3(d))+((((XCOL3(color)))* g_m3)>>7);
461     }
462    else
463    if(GlobalTextABR==1)
464     {
465      r=(XCOL1(GETLE16(pdest)))+((((XCOL1(color)))* g_m1)>>7);
466      b=(XCOL2(GETLE16(pdest)))+((((XCOL2(color)))* g_m2)>>7);
467      g=(XCOL3(GETLE16(pdest)))+((((XCOL3(color)))* g_m3)>>7);
468     }
469    else
470    if(GlobalTextABR==2)
471     {
472      r=(XCOL1(GETLE16(pdest)))-((((XCOL1(color)))* g_m1)>>7);
473      b=(XCOL2(GETLE16(pdest)))-((((XCOL2(color)))* g_m2)>>7);
474      g=(XCOL3(GETLE16(pdest)))-((((XCOL3(color)))* g_m3)>>7);
475      if(r&0x80000000) r=0;
476      if(b&0x80000000) b=0;
477      if(g&0x80000000) g=0;
478     }
479    else
480     {
481 #ifdef HALFBRIGHTMODE3
482      r=(XCOL1(GETLE16(pdest)))+((((XCOL1(color))>>2)* g_m1)>>7);
483      b=(XCOL2(GETLE16(pdest)))+((((XCOL2(color))>>2)* g_m2)>>7);
484      g=(XCOL3(GETLE16(pdest)))+((((XCOL3(color))>>2)* g_m3)>>7);
485 #else
486      r=(XCOL1(GETLE16(pdest)))+((((XCOL1(color))>>1)* g_m1)>>7);
487      b=(XCOL2(GETLE16(pdest)))+((((XCOL2(color))>>1)* g_m2)>>7);
488      g=(XCOL3(GETLE16(pdest)))+((((XCOL3(color))>>1)* g_m3)>>7);
489 #endif
490     }
491   }
492  else 
493   {
494    r=((XCOL1(color))* g_m1)>>7;
495    b=((XCOL2(color))* g_m2)>>7;
496    g=((XCOL3(color))* g_m3)>>7;
497   }
498
499  if(r&0x7FFFFFE0) r=0x1f;
500  if(b&0x7FFFFC00) b=0x3e0;
501  if(g&0x7FFF8000) g=0x7c00;
502
503  PUTLE16(pdest, (XPSXCOL(r,g,b))|l);
504 }
505
506 ////////////////////////////////////////////////////////////////////////
507
508 static inline void GetTextureTransColG32(uint32_t * pdest,uint32_t color)
509 {
510  int32_t r,g,b,l;
511
512  if(color==0) return;
513
514  l=lSetMask|(color&0x80008000);
515
516  if(DrawSemiTrans && (color&0x80008000))
517   {
518    if(GlobalTextABR==0)
519     {                 
520      r=((((X32TCOL1(GETLE32(pdest)))+((X32COL1(color)) * g_m1))&0xFF00FF00)>>8);
521      b=((((X32TCOL2(GETLE32(pdest)))+((X32COL2(color)) * g_m2))&0xFF00FF00)>>8);
522      g=((((X32TCOL3(GETLE32(pdest)))+((X32COL3(color)) * g_m3))&0xFF00FF00)>>8);
523     }
524    else
525    if(GlobalTextABR==1)
526     {
527      r=(X32COL1(GETLE32(pdest)))+(((((X32COL1(color)))* g_m1)&0xFF80FF80)>>7);
528      b=(X32COL2(GETLE32(pdest)))+(((((X32COL2(color)))* g_m2)&0xFF80FF80)>>7);
529      g=(X32COL3(GETLE32(pdest)))+(((((X32COL3(color)))* g_m3)&0xFF80FF80)>>7);
530     }
531    else
532    if(GlobalTextABR==2)
533     {
534      int32_t t;
535      r=(((((X32COL1(color)))* g_m1)&0xFF80FF80)>>7);
536      t=(GETLE32(pdest)&0x001f0000)-(r&0x003f0000); if(t&0x80000000) t=0;
537      r=(GETLE32(pdest)&0x0000001f)-(r&0x0000003f); if(r&0x80000000) r=0;
538      r|=t;
539
540      b=(((((X32COL2(color)))* g_m2)&0xFF80FF80)>>7);
541      t=((GETLE32(pdest)>>5)&0x001f0000)-(b&0x003f0000); if(t&0x80000000) t=0;
542      b=((GETLE32(pdest)>>5)&0x0000001f)-(b&0x0000003f); if(b&0x80000000) b=0;
543      b|=t;
544
545      g=(((((X32COL3(color)))* g_m3)&0xFF80FF80)>>7);
546      t=((GETLE32(pdest)>>10)&0x001f0000)-(g&0x003f0000); if(t&0x80000000) t=0;
547      g=((GETLE32(pdest)>>10)&0x0000001f)-(g&0x0000003f); if(g&0x80000000) g=0;
548      g|=t;
549     }
550    else
551     {
552 #ifdef HALFBRIGHTMODE3
553      r=(X32COL1(GETLE32(pdest)))+(((((X32BCOL1(color))>>2)* g_m1)&0xFF80FF80)>>7);
554      b=(X32COL2(GETLE32(pdest)))+(((((X32BCOL2(color))>>2)* g_m2)&0xFF80FF80)>>7);
555      g=(X32COL3(GETLE32(pdest)))+(((((X32BCOL3(color))>>2)* g_m3)&0xFF80FF80)>>7);
556 #else
557      r=(X32COL1(GETLE32(pdest)))+(((((X32ACOL1(color))>>1)* g_m1)&0xFF80FF80)>>7);
558      b=(X32COL2(GETLE32(pdest)))+(((((X32ACOL2(color))>>1)* g_m2)&0xFF80FF80)>>7);
559      g=(X32COL3(GETLE32(pdest)))+(((((X32ACOL3(color))>>1)* g_m3)&0xFF80FF80)>>7);
560 #endif
561     }
562
563    if(!(color&0x8000))
564     {
565      r=(r&0xffff0000)|((((X32COL1(color))* g_m1)&0x0000FF80)>>7);
566      b=(b&0xffff0000)|((((X32COL2(color))* g_m2)&0x0000FF80)>>7);
567      g=(g&0xffff0000)|((((X32COL3(color))* g_m3)&0x0000FF80)>>7);
568     }
569    if(!(color&0x80000000))
570     {
571      r=(r&0xffff)|((((X32COL1(color))* g_m1)&0xFF800000)>>7);
572      b=(b&0xffff)|((((X32COL2(color))* g_m2)&0xFF800000)>>7);
573      g=(g&0xffff)|((((X32COL3(color))* g_m3)&0xFF800000)>>7);
574     }
575
576   }
577  else 
578   {
579    r=(((X32COL1(color))* g_m1)&0xFF80FF80)>>7;
580    b=(((X32COL2(color))* g_m2)&0xFF80FF80)>>7;
581    g=(((X32COL3(color))* g_m3)&0xFF80FF80)>>7;
582   }
583
584  if(r&0x7FE00000) r=0x1f0000|(r&0xFFFF);
585  if(r&0x7FE0)     r=0x1f    |(r&0xFFFF0000);
586  if(b&0x7FE00000) b=0x1f0000|(b&0xFFFF);
587  if(b&0x7FE0)     b=0x1f    |(b&0xFFFF0000);
588  if(g&0x7FE00000) g=0x1f0000|(g&0xFFFF);
589  if(g&0x7FE0)     g=0x1f    |(g&0xFFFF0000);
590          
591  if(bCheckMask) 
592   {
593    uint32_t ma=GETLE32(pdest);
594
595    PUTLE32(pdest, (X32PSXCOL(r,g,b))|l);
596    
597    if((color&0xffff)==0    ) PUTLE32(pdest, (ma&0xffff)|(GETLE32(pdest)&0xffff0000));
598    if((color&0xffff0000)==0) PUTLE32(pdest, (ma&0xffff0000)|(GETLE32(pdest)&0xffff));
599    if(ma&0x80000000) PUTLE32(pdest, (ma&0xFFFF0000)|(GETLE32(pdest)&0xFFFF));
600    if(ma&0x00008000) PUTLE32(pdest, (ma&0xFFFF)    |(GETLE32(pdest)&0xFFFF0000));
601
602    return;                            
603   }
604  if((color&0xffff)==0    ) {PUTLE32(pdest, (GETLE32(pdest)&0xffff)|(((X32PSXCOL(r,g,b))|l)&0xffff0000));return;}
605  if((color&0xffff0000)==0) {PUTLE32(pdest, (GETLE32(pdest)&0xffff0000)|(((X32PSXCOL(r,g,b))|l)&0xffff));return;}
606
607  PUTLE32(pdest, (X32PSXCOL(r,g,b))|l);
608 }
609
610 ////////////////////////////////////////////////////////////////////////
611
612 static inline void GetTextureTransColG32_S(uint32_t * pdest,uint32_t color)
613 {
614  int32_t r,g,b;
615
616  if(color==0) return;
617
618  r=(((X32COL1(color))* g_m1)&0xFF80FF80)>>7;
619  b=(((X32COL2(color))* g_m2)&0xFF80FF80)>>7;
620  g=(((X32COL3(color))* g_m3)&0xFF80FF80)>>7;
621
622  if(r&0x7FE00000) r=0x1f0000|(r&0xFFFF);
623  if(r&0x7FE0)     r=0x1f    |(r&0xFFFF0000);
624  if(b&0x7FE00000) b=0x1f0000|(b&0xFFFF);
625  if(b&0x7FE0)     b=0x1f    |(b&0xFFFF0000);
626  if(g&0x7FE00000) g=0x1f0000|(g&0xFFFF);
627  if(g&0x7FE0)     g=0x1f    |(g&0xFFFF0000);
628          
629  if((color&0xffff)==0)     {PUTLE32(pdest, (GETLE32(pdest)&0xffff)|(((X32PSXCOL(r,g,b))|lSetMask|(color&0x80008000))&0xffff0000));return;}
630  if((color&0xffff0000)==0) {PUTLE32(pdest, (GETLE32(pdest)&0xffff0000)|(((X32PSXCOL(r,g,b))|lSetMask|(color&0x80008000))&0xffff));return;}
631
632  PUTLE32(pdest, (X32PSXCOL(r,g,b))|lSetMask|(color&0x80008000));
633 }
634
635 ////////////////////////////////////////////////////////////////////////
636
637 static inline void GetTextureTransColG32_SPR(uint32_t * pdest,uint32_t color)
638 {
639  int32_t r,g,b;
640
641  if(color==0) return;
642
643  if(DrawSemiTrans && (color&0x80008000))
644   {
645    if(GlobalTextABR==0)
646     {                 
647      r=((((X32TCOL1(GETLE32(pdest)))+((X32COL1(color)) * g_m1))&0xFF00FF00)>>8);
648      b=((((X32TCOL2(GETLE32(pdest)))+((X32COL2(color)) * g_m2))&0xFF00FF00)>>8);
649      g=((((X32TCOL3(GETLE32(pdest)))+((X32COL3(color)) * g_m3))&0xFF00FF00)>>8);
650     }
651    else
652    if(GlobalTextABR==1)
653     {
654      r=(X32COL1(GETLE32(pdest)))+(((((X32COL1(color)))* g_m1)&0xFF80FF80)>>7);
655      b=(X32COL2(GETLE32(pdest)))+(((((X32COL2(color)))* g_m2)&0xFF80FF80)>>7);
656      g=(X32COL3(GETLE32(pdest)))+(((((X32COL3(color)))* g_m3)&0xFF80FF80)>>7);
657     }
658    else
659    if(GlobalTextABR==2)
660     {
661      int32_t t;
662      r=(((((X32COL1(color)))* g_m1)&0xFF80FF80)>>7);
663      t=(GETLE32(pdest)&0x001f0000)-(r&0x003f0000); if(t&0x80000000) t=0;
664      r=(GETLE32(pdest)&0x0000001f)-(r&0x0000003f); if(r&0x80000000) r=0;
665      r|=t;
666
667      b=(((((X32COL2(color)))* g_m2)&0xFF80FF80)>>7);
668      t=((GETLE32(pdest)>>5)&0x001f0000)-(b&0x003f0000); if(t&0x80000000) t=0;
669      b=((GETLE32(pdest)>>5)&0x0000001f)-(b&0x0000003f); if(b&0x80000000) b=0;
670      b|=t;
671
672      g=(((((X32COL3(color)))* g_m3)&0xFF80FF80)>>7);
673      t=((GETLE32(pdest)>>10)&0x001f0000)-(g&0x003f0000); if(t&0x80000000) t=0;
674      g=((GETLE32(pdest)>>10)&0x0000001f)-(g&0x0000003f); if(g&0x80000000) g=0;
675      g|=t;
676     }
677    else
678     {
679 #ifdef HALFBRIGHTMODE3
680      r=(X32COL1(GETLE32(pdest)))+(((((X32BCOL1(color))>>2)* g_m1)&0xFF80FF80)>>7);
681      b=(X32COL2(GETLE32(pdest)))+(((((X32BCOL2(color))>>2)* g_m2)&0xFF80FF80)>>7);
682      g=(X32COL3(GETLE32(pdest)))+(((((X32BCOL3(color))>>2)* g_m3)&0xFF80FF80)>>7);
683 #else
684      r=(X32COL1(GETLE32(pdest)))+(((((X32ACOL1(color))>>1)* g_m1)&0xFF80FF80)>>7);
685      b=(X32COL2(GETLE32(pdest)))+(((((X32ACOL2(color))>>1)* g_m2)&0xFF80FF80)>>7);
686      g=(X32COL3(GETLE32(pdest)))+(((((X32ACOL3(color))>>1)* g_m3)&0xFF80FF80)>>7);
687 #endif
688     }
689
690    if(!(color&0x8000))
691     {
692      r=(r&0xffff0000)|((((X32COL1(color))* g_m1)&0x0000FF80)>>7);
693      b=(b&0xffff0000)|((((X32COL2(color))* g_m2)&0x0000FF80)>>7);
694      g=(g&0xffff0000)|((((X32COL3(color))* g_m3)&0x0000FF80)>>7);
695     }
696    if(!(color&0x80000000))
697     {
698      r=(r&0xffff)|((((X32COL1(color))* g_m1)&0xFF800000)>>7);
699      b=(b&0xffff)|((((X32COL2(color))* g_m2)&0xFF800000)>>7);
700      g=(g&0xffff)|((((X32COL3(color))* g_m3)&0xFF800000)>>7);
701     }
702
703   }
704  else 
705   {
706    r=(((X32COL1(color))* g_m1)&0xFF80FF80)>>7;
707    b=(((X32COL2(color))* g_m2)&0xFF80FF80)>>7;
708    g=(((X32COL3(color))* g_m3)&0xFF80FF80)>>7;
709   }
710
711  if(r&0x7FE00000) r=0x1f0000|(r&0xFFFF);
712  if(r&0x7FE0)     r=0x1f    |(r&0xFFFF0000);
713  if(b&0x7FE00000) b=0x1f0000|(b&0xFFFF);
714  if(b&0x7FE0)     b=0x1f    |(b&0xFFFF0000);
715  if(g&0x7FE00000) g=0x1f0000|(g&0xFFFF);
716  if(g&0x7FE0)     g=0x1f    |(g&0xFFFF0000);
717          
718  if(bCheckMask) 
719   {
720    uint32_t ma=GETLE32(pdest);
721
722    PUTLE32(pdest, (X32PSXCOL(r,g,b))|lSetMask|(color&0x80008000));
723    
724    if((color&0xffff)==0    ) PUTLE32(pdest, (ma&0xffff)|(GETLE32(pdest)&0xffff0000));
725    if((color&0xffff0000)==0) PUTLE32(pdest, (ma&0xffff0000)|(GETLE32(pdest)&0xffff));
726    if(ma&0x80000000) PUTLE32(pdest, (ma&0xFFFF0000)|(GETLE32(pdest)&0xFFFF));
727    if(ma&0x00008000) PUTLE32(pdest, (ma&0xFFFF)    |(GETLE32(pdest)&0xFFFF0000));
728
729    return;                            
730   }
731  if((color&0xffff)==0    ) {PUTLE32(pdest, (GETLE32(pdest)&0xffff)|(((X32PSXCOL(r,g,b))|lSetMask|(color&0x80008000))&0xffff0000));return;}
732  if((color&0xffff0000)==0) {PUTLE32(pdest, (GETLE32(pdest)&0xffff0000)|(((X32PSXCOL(r,g,b))|lSetMask|(color&0x80008000))&0xffff));return;}
733
734  PUTLE32(pdest, (X32PSXCOL(r,g,b))|lSetMask|(color&0x80008000));
735 }
736
737 ////////////////////////////////////////////////////////////////////////
738
739 static inline void GetTextureTransColGX_Dither(unsigned short * pdest,unsigned short color,int32_t m1,int32_t m2,int32_t m3)
740 {
741  int32_t r,g,b;
742
743  if(color==0) return;
744  
745  if(bCheckMask && (*pdest & HOST2LE16(0x8000))) return;
746
747  m1=(((XCOL1D(color)))*m1)>>4;
748  m2=(((XCOL2D(color)))*m2)>>4;
749  m3=(((XCOL3D(color)))*m3)>>4;
750
751  if(DrawSemiTrans && (color&0x8000))
752   {
753    r=((XCOL1D(GETLE16(pdest)))<<3);
754    b=((XCOL2D(GETLE16(pdest)))<<3);
755    g=((XCOL3D(GETLE16(pdest)))<<3);
756
757    if(GlobalTextABR==0)
758     {
759      r=(r>>1)+(m1>>1);
760      b=(b>>1)+(m2>>1);
761      g=(g>>1)+(m3>>1);
762     }
763    else
764    if(GlobalTextABR==1)
765     {
766      r+=m1;
767      b+=m2;
768      g+=m3;
769     }
770    else
771    if(GlobalTextABR==2)
772     {
773      r-=m1;
774      b-=m2;
775      g-=m3;
776      if(r&0x80000000) r=0;
777      if(b&0x80000000) b=0;
778      if(g&0x80000000) g=0;
779     }
780    else
781     {
782 #ifdef HALFBRIGHTMODE3
783      r+=(m1>>2);
784      b+=(m2>>2);
785      g+=(m3>>2);
786 #else
787      r+=(m1>>1);
788      b+=(m2>>1);
789      g+=(m3>>1);
790 #endif
791     }
792   }
793  else 
794   {
795    r=m1;
796    b=m2;
797    g=m3;
798   }
799
800  if(r&0x7FFFFF00) r=0xff;
801  if(b&0x7FFFFF00) b=0xff;
802  if(g&0x7FFFFF00) g=0xff;
803
804  Dither16(pdest,r,b,g,sSetMask|(color&0x8000));
805
806 }
807
808 ////////////////////////////////////////////////////////////////////////
809
810 static inline void GetTextureTransColGX(unsigned short * pdest,unsigned short color,short m1,short m2,short m3)
811 {
812  int32_t r,g,b;unsigned short l;
813
814  if(color==0) return;
815  
816  if(bCheckMask && (*pdest & HOST2LE16(0x8000))) return;
817
818  l=sSetMask|(color&0x8000);
819
820  if(DrawSemiTrans && (color&0x8000))
821   {
822    if(GlobalTextABR==0)
823     {
824      unsigned short d;
825      d     =(GETLE16(pdest)&0x7bde)>>1;
826      color =((color) &0x7bde)>>1;
827      r=(XCOL1(d))+((((XCOL1(color)))* m1)>>7);
828      b=(XCOL2(d))+((((XCOL2(color)))* m2)>>7);
829      g=(XCOL3(d))+((((XCOL3(color)))* m3)>>7);
830     }
831    else
832    if(GlobalTextABR==1)
833     {
834      r=(XCOL1(GETLE16(pdest)))+((((XCOL1(color)))* m1)>>7);
835      b=(XCOL2(GETLE16(pdest)))+((((XCOL2(color)))* m2)>>7);
836      g=(XCOL3(GETLE16(pdest)))+((((XCOL3(color)))* m3)>>7);
837     }
838    else
839    if(GlobalTextABR==2)
840     {
841      r=(XCOL1(GETLE16(pdest)))-((((XCOL1(color)))* m1)>>7);
842      b=(XCOL2(GETLE16(pdest)))-((((XCOL2(color)))* m2)>>7);
843      g=(XCOL3(GETLE16(pdest)))-((((XCOL3(color)))* m3)>>7);
844      if(r&0x80000000) r=0;
845      if(b&0x80000000) b=0;
846      if(g&0x80000000) g=0;
847     }
848    else
849     {
850 #ifdef HALFBRIGHTMODE3
851      r=(XCOL1(GETLE16(pdest)))+((((XCOL1(color))>>2)* m1)>>7);
852      b=(XCOL2(GETLE16(pdest)))+((((XCOL2(color))>>2)* m2)>>7);
853      g=(XCOL3(GETLE16(pdest)))+((((XCOL3(color))>>2)* m3)>>7);
854 #else
855      r=(XCOL1(GETLE16(pdest)))+((((XCOL1(color))>>1)* m1)>>7);
856      b=(XCOL2(GETLE16(pdest)))+((((XCOL2(color))>>1)* m2)>>7);
857      g=(XCOL3(GETLE16(pdest)))+((((XCOL3(color))>>1)* m3)>>7);
858 #endif
859     }
860   }
861  else 
862   {
863    r=((XCOL1(color))* m1)>>7;
864    b=((XCOL2(color))* m2)>>7;
865    g=((XCOL3(color))* m3)>>7;
866   }
867
868  if(r&0x7FFFFFE0) r=0x1f;
869  if(b&0x7FFFFC00) b=0x3e0;
870  if(g&0x7FFF8000) g=0x7c00;
871
872  PUTLE16(pdest, (XPSXCOL(r,g,b))|l);
873 }
874
875 ////////////////////////////////////////////////////////////////////////
876
877 static inline void GetTextureTransColGX_S(unsigned short * pdest,unsigned short color,short m1,short m2,short m3)
878 {
879  int32_t r,g,b;
880
881  if(color==0) return;
882  
883  r=((XCOL1(color))* m1)>>7;
884  b=((XCOL2(color))* m2)>>7;
885  g=((XCOL3(color))* m3)>>7;
886
887  if(r&0x7FFFFFE0) r=0x1f;
888  if(b&0x7FFFFC00) b=0x3e0;
889  if(g&0x7FFF8000) g=0x7c00;
890
891  PUTLE16(pdest, (XPSXCOL(r,g,b))|sSetMask|(color&0x8000));
892 }
893
894 ////////////////////////////////////////////////////////////////////////
895
896 static inline void GetTextureTransColGX32_S(uint32_t * pdest,uint32_t color,short m1,short m2,short m3)
897 {
898  int32_t r,g,b;
899  
900  if(color==0) return;
901
902  r=(((X32COL1(color))* m1)&0xFF80FF80)>>7;
903  b=(((X32COL2(color))* m2)&0xFF80FF80)>>7;
904  g=(((X32COL3(color))* m3)&0xFF80FF80)>>7;
905                 
906  if(r&0x7FE00000) r=0x1f0000|(r&0xFFFF);
907  if(r&0x7FE0)     r=0x1f    |(r&0xFFFF0000);
908  if(b&0x7FE00000) b=0x1f0000|(b&0xFFFF);
909  if(b&0x7FE0)     b=0x1f    |(b&0xFFFF0000);
910  if(g&0x7FE00000) g=0x1f0000|(g&0xFFFF);
911  if(g&0x7FE0)     g=0x1f    |(g&0xFFFF0000);
912
913  if((color&0xffff)==0)     {PUTLE32(pdest, (GETLE32(pdest)&0xffff)|(((X32PSXCOL(r,g,b))|lSetMask|(color&0x80008000))&0xffff0000));return;}
914  if((color&0xffff0000)==0) {PUTLE32(pdest, (GETLE32(pdest)&0xffff0000)|(((X32PSXCOL(r,g,b))|lSetMask|(color&0x80008000))&0xffff));return;}
915
916  PUTLE32(pdest, (X32PSXCOL(r,g,b))|lSetMask|(color&0x80008000));
917 }
918
919 ////////////////////////////////////////////////////////////////////////
920 // FILL FUNCS
921 ////////////////////////////////////////////////////////////////////////
922
923 static void FillSoftwareAreaTrans(short x0,short y0,short x1, // FILL AREA TRANS
924                       short y1,unsigned short col)
925 {
926  short j,i,dx,dy;
927
928  if(y0>y1) return;
929  if(x0>x1) return;
930
931  if(x1<drawX) return;
932  if(y1<drawY) return;
933  if(x0>drawW) return;
934  if(y0>drawH) return;
935
936  x1=min(x1,drawW+1);
937  y1=min(y1,drawH+1);
938  x0=max(x0,drawX);
939  y0=max(y0,drawY);
940     
941  if(y0>=512)   return;
942  if(x0>1023)          return;
943
944  if(y1>512) y1=512;
945  if(x1>1024)       x1=1024;
946
947  dx=x1-x0;dy=y1-y0;
948
949  if(dx==1 && dy==1 && x0==1020 && y0==511)             // special fix for pinball game... emu protection???
950   {
951    static int iCheat=0;
952    col+=iCheat;
953    if(iCheat==1) iCheat=0; else iCheat=1;
954   }
955
956
957  if(dx&1)                                              // slow fill
958   {
959    unsigned short *DSTPtr;
960    unsigned short LineOffset;
961    DSTPtr = psxVuw + (1024*y0) + x0;
962    LineOffset = 1024 - dx;
963    for(i=0;i<dy;i++)
964     {
965      for(j=0;j<dx;j++)
966       GetShadeTransCol(DSTPtr++,col);
967      DSTPtr += LineOffset;
968     } 
969   }
970  else                                                  // fast fill
971   {
972    uint32_t *DSTPtr;
973    unsigned short LineOffset;
974    uint32_t lcol=lSetMask|(((uint32_t)(col))<<16)|col;
975    dx>>=1;
976    DSTPtr = (uint32_t *)(psxVuw + (1024*y0) + x0);
977    LineOffset = 512 - dx;
978
979    if(!bCheckMask && !DrawSemiTrans)
980     {
981      for(i=0;i<dy;i++)
982       {
983        for(j=0;j<dx;j++) { PUTLE32(DSTPtr, lcol); DSTPtr++; }
984        DSTPtr += LineOffset;
985       }
986     }
987    else
988     {
989      for(i=0;i<dy;i++)
990       {
991        for(j=0;j<dx;j++) 
992         GetShadeTransCol32(DSTPtr++,lcol);
993        DSTPtr += LineOffset;
994       } 
995     }
996   }
997 }
998
999 ////////////////////////////////////////////////////////////////////////
1000
1001 static void FillSoftwareArea(short x0,short y0,short x1,      // FILL AREA (BLK FILL)
1002                       short y1,unsigned short col)     // no draw area check here!
1003 {
1004  short j,i,dx,dy;
1005
1006  // ?? 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__
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_IL(short x1, short y1, short x2, short y2, short x3, short y3, short tx1, short ty1, short tx2, short ty2, short tx3, short ty3,short clX, short clY)
2655 {
2656  int i,j,xmin,xmax,ymin,ymax,n_xi,n_yi,TXV;
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<<10)+GlobalTextAddrX;
2679
2680  difX=delta_right_u;difX2=difX<<1;
2681  difY=delta_right_v;difY2=difY<<1;
2682
2683 #ifdef FASTSOLID
2684
2685  if(!bCheckMask && !DrawSemiTrans)
2686   {
2687    for (i=ymin;i<=ymax;i++)
2688     {
2689      xmin=(left_x >> 16);
2690      xmax=(right_x >> 16)-1;
2691      if(drawW<xmax) xmax=drawW;
2692
2693      if(xmax>=xmin)
2694       {
2695        posX=left_u;
2696        posY=left_v;
2697
2698        if(xmin<drawX)
2699         {j=drawX-xmin;xmin=drawX;posX+=j*difX;posY+=j*difY;}
2700
2701        for(j=xmin;j<xmax;j+=2)
2702         {
2703          XAdjust=(posX>>16);
2704
2705          TXV=posY>>16;
2706          n_xi = ( ( XAdjust >> 2 ) & ~0x3c ) + ( ( TXV << 2 ) & 0x3c );
2707          n_yi = ( TXV & ~0xf ) + ( ( XAdjust >> 4 ) & 0xf );
2708
2709          tC1= (GETLE16(&psxVuw[(n_yi<<10)+YAdjust+n_xi]) >> ((XAdjust & 0x03)<<2)) & 0x0f ;
2710
2711          XAdjust=((posX+difX)>>16);
2712
2713          TXV=(posY+difY)>>16;
2714          n_xi = ( ( XAdjust >> 2 ) & ~0x3c ) + ( ( TXV << 2 ) & 0x3c );
2715          n_yi = ( TXV & ~0xf ) + ( ( XAdjust >> 4 ) & 0xf );
2716
2717          tC2= (GETLE16(&psxVuw[(n_yi<<10)+YAdjust+n_xi]) >> ((XAdjust & 0x03)<<2)) & 0x0f ;
2718
2719          GetTextureTransColG32_S((uint32_t *)&psxVuw[(i<<10)+j],
2720              GETLE16(&psxVuw[clutP+tC1])|
2721              ((int32_t)GETLE16(&psxVuw[clutP+tC2]))<<16);
2722
2723          posX+=difX2;
2724          posY+=difY2;
2725         }
2726        if(j==xmax)
2727         {
2728          XAdjust=(posX>>16);
2729
2730          TXV=posY>>16;
2731          n_xi = ( ( XAdjust >> 2 ) & ~0x3c ) + ( ( TXV << 2 ) & 0x3c );
2732          n_yi = ( TXV & ~0xf ) + ( ( XAdjust >> 4 ) & 0xf );
2733
2734          tC1= (GETLE16(&psxVuw[(n_yi<<10)+YAdjust+n_xi]) >> ((XAdjust & 0x03)<<2)) & 0x0f ;
2735
2736          GetTextureTransColG_S(&psxVuw[(i<<10)+j],GETLE16(&psxVuw[clutP+tC1]));
2737         }
2738       }
2739      if(NextRow_FT()) 
2740       {
2741        return;
2742       }
2743     }
2744    return;
2745   }
2746
2747 #endif
2748
2749  for (i=ymin;i<=ymax;i++)
2750   {
2751    xmin=(left_x >> 16);
2752    xmax=(right_x >> 16)-1; //!!!!!!!!!!!!!!!!!!
2753    if(drawW<xmax) xmax=drawW;
2754
2755    if(xmax>=xmin)
2756     {
2757      posX=left_u;
2758      posY=left_v;
2759
2760      if(xmin<drawX)
2761       {j=drawX-xmin;xmin=drawX;posX+=j*difX;posY+=j*difY;}
2762
2763      for(j=xmin;j<xmax;j+=2)
2764       {
2765        XAdjust=(posX>>16);
2766
2767        TXV=posY>>16;
2768        n_xi = ( ( XAdjust >> 2 ) & ~0x3c ) + ( ( TXV << 2 ) & 0x3c );
2769        n_yi = ( TXV & ~0xf ) + ( ( XAdjust >> 4 ) & 0xf );
2770
2771        tC1= (GETLE16(&psxVuw[(n_yi<<10)+YAdjust+n_xi]) >> ((XAdjust & 0x03)<<2)) & 0x0f ;
2772
2773        XAdjust=((posX+difX)>>16);
2774
2775        TXV=(posY+difY)>>16;
2776        n_xi = ( ( XAdjust >> 2 ) & ~0x3c ) + ( ( TXV << 2 ) & 0x3c );
2777        n_yi = ( TXV & ~0xf ) + ( ( XAdjust >> 4 ) & 0xf );
2778
2779        tC2= (GETLE16(&psxVuw[(n_yi<<10)+YAdjust+n_xi]) >> ((XAdjust & 0x03)<<2)) & 0x0f ;
2780
2781        GetTextureTransColG32((uint32_t *)&psxVuw[(i<<10)+j],
2782            GETLE16(&psxVuw[clutP+tC1])|
2783            ((int32_t)GETLE16(&psxVuw[clutP+tC2]))<<16);
2784
2785        posX+=difX2;
2786        posY+=difY2;
2787       }
2788      if(j==xmax)
2789       {
2790        XAdjust=(posX>>16);
2791
2792        TXV=posY>>16;
2793        n_xi = ( ( XAdjust >> 2 ) & ~0x3c ) + ( ( TXV << 2 ) & 0x3c );
2794        n_yi = ( TXV & ~0xf ) + ( ( XAdjust >> 4 ) & 0xf );
2795
2796        tC1= (GETLE16(&psxVuw[(n_yi<<10)+YAdjust+n_xi]) >> ((XAdjust & 0x03)<<2)) & 0x0f ;
2797
2798        GetTextureTransColG(&psxVuw[(i<<10)+j],GETLE16(&psxVuw[clutP+tC1]));
2799       }
2800     }
2801    if(NextRow_FT()) 
2802     {
2803      return;
2804     }
2805   }
2806 }
2807
2808 ////////////////////////////////////////////////////////////////////////
2809
2810 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)
2811 {
2812  int i,j,xmin,xmax,ymin,ymax;
2813  int32_t difX, difY,difX2, difY2;
2814  int32_t posX,posY,YAdjust,XAdjust;
2815  int32_t clutP;
2816  short tC1,tC2;
2817  
2818  if(x1>drawW && x2>drawW && x3>drawW) return;
2819  if(y1>drawH && y2>drawH && y3>drawH) return;
2820  if(x1<drawX && x2<drawX && x3<drawX) return;
2821  if(y1<drawY && y2<drawY && y3<drawY) return;
2822  if(drawY>=drawH) return;
2823  if(drawX>=drawW) return; 
2824
2825  if(!SetupSections_FT(x1,y1,x2,y2,x3,y3,tx1,ty1,tx2,ty2,tx3,ty3)) return;
2826
2827  ymax=Ymax;
2828
2829  for(ymin=Ymin;ymin<drawY;ymin++)
2830   if(NextRow_FT()) return;
2831
2832  clutP=(clY<<10)+clX;
2833
2834  YAdjust=((GlobalTextAddrY)<<11)+(GlobalTextAddrX<<1);
2835  YAdjust+=(TWin.Position.y0<<11)+(TWin.Position.x0>>1);
2836
2837  difX=delta_right_u;difX2=difX<<1;
2838  difY=delta_right_v;difY2=difY<<1;
2839
2840 #ifdef FASTSOLID
2841
2842  if(!bCheckMask && !DrawSemiTrans)
2843   {
2844    for (i=ymin;i<=ymax;i++)
2845     {
2846      xmin=(left_x >> 16);
2847      xmax=(right_x >> 16);//-1; //!!!!!!!!!!!!!!!!
2848      if(xmax>xmin) xmax--;
2849
2850      if(drawW<xmax) xmax=drawW;
2851
2852      if(xmax>=xmin)
2853       {
2854        posX=left_u;
2855        posY=left_v;
2856
2857        if(xmin<drawX)
2858         {j=drawX-xmin;xmin=drawX;posX+=j*difX;posY+=j*difY;}
2859
2860        for(j=xmin;j<xmax;j+=2)
2861         {
2862          XAdjust=(posX>>16)&TWin.xmask;
2863          tC1 = psxVub[(((posY>>16)&TWin.ymask)<<11)+
2864                       YAdjust+(XAdjust>>1)];
2865          tC1=(tC1>>((XAdjust&1)<<2))&0xf;
2866          XAdjust=((posX+difX)>>16)&TWin.xmask;
2867          tC2 = psxVub[((((posY+difY)>>16)&TWin.ymask)<<11)+
2868                       YAdjust+(XAdjust>>1)];
2869          tC2=(tC2>>((XAdjust&1)<<2))&0xf;
2870
2871          GetTextureTransColG32_S((uint32_t *)&psxVuw[(i<<10)+j],
2872              GETLE16(&psxVuw[clutP+tC1])|
2873              ((int32_t)GETLE16(&psxVuw[clutP+tC2]))<<16);
2874
2875          posX+=difX2;
2876          posY+=difY2;
2877         }
2878        if(j==xmax)
2879         {
2880          XAdjust=(posX>>16)&TWin.xmask;
2881          tC1 = psxVub[(((posY>>16)&TWin.ymask)<<11)+
2882                       YAdjust+(XAdjust>>1)];
2883          tC1=(tC1>>((XAdjust&1)<<2))&0xf;
2884          GetTextureTransColG_S(&psxVuw[(i<<10)+j],GETLE16(&psxVuw[clutP+tC1]));
2885         }
2886       }
2887      if(NextRow_FT()) 
2888       {
2889        return;
2890       }
2891     }
2892    return;
2893   }
2894
2895 #endif
2896
2897  for (i=ymin;i<=ymax;i++)
2898   {
2899    xmin=(left_x >> 16);
2900    xmax=(right_x >> 16)-1; //!!!!!!!!!!!!!!!!!!
2901    if(drawW<xmax) xmax=drawW;
2902
2903    if(xmax>=xmin)
2904     {
2905      posX=left_u;
2906      posY=left_v;
2907
2908      if(xmin<drawX)
2909       {j=drawX-xmin;xmin=drawX;posX+=j*difX;posY+=j*difY;}
2910
2911      for(j=xmin;j<xmax;j+=2)
2912       {
2913        XAdjust=(posX>>16)&TWin.xmask;
2914        tC1 = psxVub[(((posY>>16)&TWin.ymask)<<11)+
2915                     YAdjust+(XAdjust>>1)];
2916        tC1=(tC1>>((XAdjust&1)<<2))&0xf;
2917        XAdjust=((posX+difX)>>16)&TWin.xmask;
2918        tC2 = psxVub[((((posY+difY)>>16)&TWin.ymask)<<11)+
2919                     YAdjust+(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
2926        posX+=difX2;
2927        posY+=difY2;
2928       }
2929      if(j==xmax)
2930       {
2931        XAdjust=(posX>>16)&TWin.xmask;
2932        tC1 = psxVub[(((posY>>16)&TWin.ymask)<<11)+
2933                     YAdjust+(XAdjust>>1)];
2934        tC1=(tC1>>((XAdjust&1)<<2))&0xf;
2935        GetTextureTransColG(&psxVuw[(i<<10)+j],GETLE16(&psxVuw[clutP+tC1]));
2936       }
2937     }
2938    if(NextRow_FT()) 
2939     {
2940      return;
2941     }
2942   }
2943 }
2944
2945 ////////////////////////////////////////////////////////////////////////
2946
2947 #ifdef POLYQUAD3
2948
2949 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)
2950 {
2951  drawPoly3TEx4(x2,y2,x3,y3,x4,y4,
2952                tx2,ty2,tx3,ty3,tx4,ty4,
2953                clX,clY);
2954  drawPoly3TEx4(x1,y1,x2,y2,x4,y4,
2955                tx1,ty1,tx2,ty2,tx4,ty4,
2956                clX,clY);
2957 }
2958
2959 #endif
2960
2961 // more exact:
2962
2963 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)
2964 {
2965  int32_t num; 
2966  int32_t i,j,xmin,xmax,ymin,ymax;
2967  int32_t difX, difY, difX2, difY2;
2968  int32_t posX,posY,YAdjust,clutP,XAdjust;
2969  short tC1,tC2;
2970
2971  if(x1>drawW && x2>drawW && x3>drawW && x4>drawW) return;
2972  if(y1>drawH && y2>drawH && y3>drawH && y4>drawH) return;
2973  if(x1<drawX && x2<drawX && x3<drawX && x4<drawX) return;
2974  if(y1<drawY && y2<drawY && y3<drawY && y4<drawY) return;
2975  if(drawY>=drawH) return;
2976  if(drawX>=drawW) return; 
2977
2978  if(!SetupSections_FT4(x1,y1,x2,y2,x3,y3,x4,y4,tx1,ty1,tx2,ty2,tx3,ty3,tx4,ty4)) return;
2979
2980  ymax=Ymax;
2981
2982  for(ymin=Ymin;ymin<drawY;ymin++)
2983   if(NextRow_FT4()) return;
2984
2985  clutP=(clY<<10)+clX;
2986
2987  YAdjust=((GlobalTextAddrY)<<11)+(GlobalTextAddrX<<1);
2988
2989 #ifdef FASTSOLID
2990
2991  if(!bCheckMask && !DrawSemiTrans)
2992   {
2993    for (i=ymin;i<=ymax;i++)
2994     {
2995      xmin=(left_x >> 16);
2996      xmax=(right_x >> 16);
2997
2998      if(xmax>=xmin)
2999       {
3000        posX=left_u;
3001        posY=left_v;
3002
3003        num=(xmax-xmin);
3004        if(num==0) num=1;
3005        difX=(right_u-posX)/num;
3006        difY=(right_v-posY)/num;
3007        difX2=difX<<1;
3008        difY2=difY<<1;
3009
3010        if(xmin<drawX)
3011         {j=drawX-xmin;xmin=drawX;posX+=j*difX;posY+=j*difY;}
3012        xmax--;if(drawW<xmax) xmax=drawW;
3013
3014        for(j=xmin;j<xmax;j+=2)
3015         {
3016          XAdjust=(posX>>16);
3017          tC1 = psxVub[((posY>>5)&(int32_t)0xFFFFF800)+YAdjust+(XAdjust>>1)];
3018          tC1=(tC1>>((XAdjust&1)<<2))&0xf;
3019          XAdjust=((posX+difX)>>16);
3020          tC2 = psxVub[(((posY+difY)>>5)&(int32_t)0xFFFFF800)+YAdjust+
3021                        (XAdjust>>1)];
3022          tC2=(tC2>>((XAdjust&1)<<2))&0xf;
3023
3024          GetTextureTransColG32_S((uint32_t *)&psxVuw[(i<<10)+j],
3025               GETLE16(&psxVuw[clutP+tC1])|
3026               ((int32_t)GETLE16(&psxVuw[clutP+tC2]))<<16);
3027          posX+=difX2;
3028          posY+=difY2;
3029         }
3030        if(j==xmax)
3031         {
3032          XAdjust=(posX>>16);
3033          tC1 = psxVub[((posY>>5)&(int32_t)0xFFFFF800)+YAdjust+
3034                       (XAdjust>>1)];
3035          tC1=(tC1>>((XAdjust&1)<<2))&0xf;
3036          GetTextureTransColG_S(&psxVuw[(i<<10)+j],GETLE16(&psxVuw[clutP+tC1]));
3037         }
3038
3039       }
3040      if(NextRow_FT4()) return;
3041     }
3042    return;
3043   }
3044
3045 #endif
3046
3047  for (i=ymin;i<=ymax;i++)
3048   {
3049    xmin=(left_x >> 16);
3050    xmax=(right_x >> 16);
3051
3052    if(xmax>=xmin)
3053     {
3054      posX=left_u;
3055      posY=left_v;
3056
3057      num=(xmax-xmin);
3058      if(num==0) num=1;
3059      difX=(right_u-posX)/num;
3060      difY=(right_v-posY)/num;
3061      difX2=difX<<1;
3062      difY2=difY<<1;
3063
3064      if(xmin<drawX)
3065       {j=drawX-xmin;xmin=drawX;posX+=j*difX;posY+=j*difY;}
3066      xmax--;if(drawW<xmax) xmax=drawW;
3067
3068      for(j=xmin;j<xmax;j+=2)
3069       {
3070        XAdjust=(posX>>16);
3071        tC1 = psxVub[((posY>>5)&(int32_t)0xFFFFF800)+YAdjust+(XAdjust>>1)];
3072        tC1=(tC1>>((XAdjust&1)<<2))&0xf;
3073        XAdjust=((posX+difX)>>16);
3074        tC2 = psxVub[(((posY+difY)>>5)&(int32_t)0xFFFFF800)+YAdjust+
3075                      (XAdjust>>1)];
3076        tC2=(tC2>>((XAdjust&1)<<2))&0xf;
3077
3078        GetTextureTransColG32((uint32_t *)&psxVuw[(i<<10)+j],
3079             GETLE16(&psxVuw[clutP+tC1])|
3080             ((int32_t)GETLE16(&psxVuw[clutP+tC2]))<<16);
3081        posX+=difX2;
3082        posY+=difY2;
3083       }
3084      if(j==xmax)
3085       {
3086        XAdjust=(posX>>16);
3087        tC1 = psxVub[((posY>>5)&(int32_t)0xFFFFF800)+YAdjust+
3088                     (XAdjust>>1)];
3089        tC1=(tC1>>((XAdjust&1)<<2))&0xf;
3090        GetTextureTransColG(&psxVuw[(i<<10)+j],GETLE16(&psxVuw[clutP+tC1]));
3091       }
3092     }
3093    if(NextRow_FT4()) return;
3094   }
3095 }
3096
3097 ////////////////////////////////////////////////////////////////////////
3098
3099 static void drawPoly4TEx4_IL(short x1, short y1, short x2, short y2, short x3, short y3, short x4, short y4, short tx1, short ty1, short tx2, short ty2, short tx3, short ty3, short tx4, short ty4,short clX, short clY)
3100 {
3101  int32_t num; 
3102  int32_t i,j=0,xmin,xmax,ymin,ymax,n_xi,n_yi,TXV;
3103  int32_t difX, difY, difX2, difY2;
3104  int32_t posX=0,posY=0,YAdjust,clutP,XAdjust;
3105  short tC1,tC2;
3106
3107  if(x1>drawW && x2>drawW && x3>drawW && x4>drawW) return;
3108  if(y1>drawH && y2>drawH && y3>drawH && y4>drawH) return;
3109  if(x1<drawX && x2<drawX && x3<drawX && x4<drawX) return;
3110  if(y1<drawY && y2<drawY && y3<drawY && y4<drawY) return;
3111  if(drawY>=drawH) return;
3112  if(drawX>=drawW) return; 
3113
3114  if(!SetupSections_FT4(x1,y1,x2,y2,x3,y3,x4,y4,tx1,ty1,tx2,ty2,tx3,ty3,tx4,ty4)) return;
3115
3116  ymax=Ymax;
3117
3118  for(ymin=Ymin;ymin<drawY;ymin++)
3119   if(NextRow_FT4()) return;
3120
3121  clutP=(clY<<10)+clX;
3122
3123  YAdjust=((GlobalTextAddrY)<<10)+GlobalTextAddrX;
3124
3125 #ifdef FASTSOLID
3126
3127  if(!bCheckMask && !DrawSemiTrans)
3128   {
3129    for (i=ymin;i<=ymax;i++)
3130     {
3131      xmin=(left_x >> 16);
3132      xmax=(right_x >> 16);
3133
3134      if(xmax>=xmin)
3135       {
3136        posX=left_u;
3137        posY=left_v;
3138
3139        num=(xmax-xmin);
3140        if(num==0) num=1;
3141        difX=(right_u-posX)/num;
3142        difY=(right_v-posY)/num;
3143        difX2=difX<<1;
3144        difY2=difY<<1;
3145
3146        if(xmin<drawX)
3147         {j=drawX-xmin;xmin=drawX;posX+=j*difX;posY+=j*difY;}
3148        xmax--;if(drawW<xmax) xmax=drawW;
3149
3150        for(j=xmin;j<xmax;j+=2)
3151         {
3152          XAdjust=(posX>>16);
3153
3154          TXV=posY>>16;
3155          n_xi = ( ( XAdjust >> 2 ) & ~0x3c ) + ( ( TXV << 2 ) & 0x3c );
3156          n_yi = ( TXV & ~0xf ) + ( ( XAdjust >> 4 ) & 0xf );
3157
3158          tC1= (GETLE16(&psxVuw[(n_yi<<10)+YAdjust+n_xi]) >> ((XAdjust & 0x03)<<2)) & 0x0f ;
3159
3160          XAdjust=((posX+difX)>>16);
3161
3162          TXV=(posY+difY)>>16;
3163          n_xi = ( ( XAdjust >> 2 ) & ~0x3c ) + ( ( TXV << 2 ) & 0x3c );
3164          n_yi = ( TXV & ~0xf ) + ( ( XAdjust >> 4 ) & 0xf );
3165
3166          tC2= (GETLE16(&psxVuw[(n_yi<<10)+YAdjust+n_xi]) >> ((XAdjust & 0x03)<<2)) & 0x0f ;
3167
3168          GetTextureTransColG32_S((uint32_t *)&psxVuw[(i<<10)+j],
3169               GETLE16(&psxVuw[clutP+tC1])|
3170               ((int32_t)GETLE16(&psxVuw[clutP+tC2]))<<16);
3171          posX+=difX2;
3172          posY+=difY2;
3173         }
3174          posX+=difX2;
3175          posY+=difY2;
3176         }
3177
3178        if(j==xmax)
3179         {
3180          XAdjust=(posX>>16);
3181          TXV=posY>>16;
3182          n_xi = ( ( XAdjust >> 2 ) & ~0x3c ) + ( ( TXV << 2 ) & 0x3c );
3183          n_yi = ( TXV & ~0xf ) + ( ( XAdjust >> 4 ) & 0xf );
3184
3185          tC1= (GETLE16(&psxVuw[(n_yi<<10)+YAdjust+n_xi]) >> ((XAdjust & 0x03)<<2)) & 0x0f ;
3186
3187          GetTextureTransColG_S(&psxVuw[(i<<10)+j],GETLE16(&psxVuw[clutP+tC1]));
3188         }
3189
3190       }
3191      if(NextRow_FT4()) return;
3192     }
3193 #endif
3194
3195  for (i=ymin;i<=ymax;i++)
3196   {
3197    xmin=(left_x >> 16);
3198    xmax=(right_x >> 16);
3199
3200    if(xmax>=xmin)
3201     {
3202      posX=left_u;
3203      posY=left_v;
3204
3205      num=(xmax-xmin);
3206      if(num==0) num=1;
3207      difX=(right_u-posX)/num;
3208      difY=(right_v-posY)/num;
3209      difX2=difX<<1;
3210      difY2=difY<<1;
3211
3212      if(xmin<drawX)
3213       {j=drawX-xmin;xmin=drawX;posX+=j*difX;posY+=j*difY;}
3214      xmax--;if(drawW<xmax) xmax=drawW;
3215
3216      for(j=xmin;j<xmax;j+=2)
3217       {
3218        XAdjust=(posX>>16);
3219
3220        TXV=posY>>16;
3221        n_xi = ( ( XAdjust >> 2 ) & ~0x3c ) + ( ( TXV << 2 ) & 0x3c );
3222        n_yi = ( TXV & ~0xf ) + ( ( XAdjust >> 4 ) & 0xf );
3223
3224        tC1= (GETLE16(&psxVuw[(n_yi<<10)+YAdjust+n_xi]) >> ((XAdjust & 0x03)<<2)) & 0x0f ;
3225
3226        XAdjust=((posX+difX)>>16);
3227
3228        TXV=(posY+difY)>>16;
3229        n_xi = ( ( XAdjust >> 2 ) & ~0x3c ) + ( ( TXV << 2 ) & 0x3c );
3230        n_yi = ( TXV & ~0xf ) + ( ( XAdjust >> 4 ) & 0xf );
3231
3232        tC2= (GETLE16(&psxVuw[(n_yi<<10)+YAdjust+n_xi]) >> ((XAdjust & 0x03)<<2)) & 0x0f ;
3233
3234        GetTextureTransColG32((uint32_t *)&psxVuw[(i<<10)+j],
3235             GETLE16(&psxVuw[clutP+tC1])|
3236             ((int32_t)GETLE16(&psxVuw[clutP+tC2]))<<16);
3237        posX+=difX2;
3238        posY+=difY2;
3239       }
3240      if(j==xmax)
3241       {
3242        XAdjust=(posX>>16);
3243        TXV=posY>>16;
3244        n_xi = ( ( XAdjust >> 2 ) & ~0x3c ) + ( ( TXV << 2 ) & 0x3c );
3245        n_yi = ( TXV & ~0xf ) + ( ( XAdjust >> 4 ) & 0xf );
3246
3247        tC1= (GETLE16(&psxVuw[(n_yi<<10)+YAdjust+n_xi]) >> ((XAdjust & 0x03)<<2)) & 0x0f ;
3248
3249        GetTextureTransColG(&psxVuw[(i<<10)+j],GETLE16(&psxVuw[clutP+tC1]));
3250       }
3251     }
3252    if(NextRow_FT4()) return;
3253   }
3254 }
3255
3256 ////////////////////////////////////////////////////////////////////////
3257
3258 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)
3259 {
3260  int32_t num; 
3261  int32_t i,j,xmin,xmax,ymin,ymax;
3262  int32_t difX, difY, difX2, difY2;
3263  int32_t posX,posY,YAdjust,clutP,XAdjust;
3264  short tC1,tC2;
3265
3266  if(x1>drawW && x2>drawW && x3>drawW && x4>drawW) return;
3267  if(y1>drawH && y2>drawH && y3>drawH && y4>drawH) return;
3268  if(x1<drawX && x2<drawX && x3<drawX && x4<drawX) return;
3269  if(y1<drawY && y2<drawY && y3<drawY && y4<drawY) return;
3270  if(drawY>=drawH) return;
3271  if(drawX>=drawW) return; 
3272
3273  if(!SetupSections_FT4(x1,y1,x2,y2,x3,y3,x4,y4,tx1,ty1,tx2,ty2,tx3,ty3,tx4,ty4)) return;
3274
3275  ymax=Ymax;
3276
3277  for(ymin=Ymin;ymin<drawY;ymin++)
3278   if(NextRow_FT4()) return;
3279
3280  clutP=(clY<<10)+clX;
3281
3282  YAdjust=((GlobalTextAddrY)<<11)+(GlobalTextAddrX<<1);
3283  YAdjust+=(TWin.Position.y0<<11)+(TWin.Position.x0>>1);
3284
3285 #ifdef FASTSOLID
3286
3287  if(!bCheckMask && !DrawSemiTrans)
3288   {
3289    for (i=ymin;i<=ymax;i++)
3290     {
3291      xmin=(left_x >> 16);
3292      xmax=(right_x >> 16);
3293
3294      if(xmax>=xmin)
3295       {
3296        posX=left_u;
3297        posY=left_v;
3298
3299        num=(xmax-xmin);
3300        if(num==0) num=1;
3301        difX=(right_u-posX)/num;
3302        difY=(right_v-posY)/num;
3303        difX2=difX<<1;
3304        difY2=difY<<1;
3305
3306        if(xmin<drawX)
3307         {j=drawX-xmin;xmin=drawX;posX+=j*difX;posY+=j*difY;}
3308        xmax--;if(drawW<xmax) xmax=drawW;
3309
3310        for(j=xmin;j<xmax;j+=2)
3311         {
3312          XAdjust=(posX>>16)&TWin.xmask;
3313          tC1 = psxVub[(((posY>>16)&TWin.ymask)<<11)+
3314                       YAdjust+(XAdjust>>1)];
3315          tC1=(tC1>>((XAdjust&1)<<2))&0xf;
3316          XAdjust=((posX+difX)>>16)&TWin.xmask;
3317          tC2 = psxVub[((((posY+difY)>>16)&TWin.ymask)<<11)+
3318                       YAdjust+(XAdjust>>1)];
3319          tC2=(tC2>>((XAdjust&1)<<2))&0xf;
3320
3321          GetTextureTransColG32_S((uint32_t *)&psxVuw[(i<<10)+j],
3322               GETLE16(&psxVuw[clutP+tC1])|
3323               ((int32_t)GETLE16(&psxVuw[clutP+tC2]))<<16);
3324          posX+=difX2;
3325          posY+=difY2;
3326         }
3327        if(j==xmax)
3328         {
3329          XAdjust=(posX>>16)&TWin.xmask;
3330          tC1 = psxVub[(((posY>>16)&TWin.ymask)<<11)+
3331                       YAdjust+(XAdjust>>1)];
3332          tC1=(tC1>>((XAdjust&1)<<2))&0xf;
3333          GetTextureTransColG_S(&psxVuw[(i<<10)+j],GETLE16(&psxVuw[clutP+tC1]));
3334         }
3335       }
3336      if(NextRow_FT4()) return;
3337     }
3338    return;
3339   }
3340
3341 #endif
3342
3343  for (i=ymin;i<=ymax;i++)
3344   {
3345    xmin=(left_x >> 16);
3346    xmax=(right_x >> 16);
3347
3348    if(xmax>=xmin)
3349     {
3350      posX=left_u;
3351      posY=left_v;
3352
3353      num=(xmax-xmin);
3354      if(num==0) num=1;
3355      difX=(right_u-posX)/num;
3356      difY=(right_v-posY)/num;
3357      difX2=difX<<1;
3358      difY2=difY<<1;
3359
3360      if(xmin<drawX)
3361       {j=drawX-xmin;xmin=drawX;posX+=j*difX;posY+=j*difY;}
3362      xmax--;if(drawW<xmax) xmax=drawW;
3363
3364      for(j=xmin;j<xmax;j+=2)
3365       {
3366        XAdjust=(posX>>16)&TWin.xmask;
3367        tC1 = psxVub[(((posY>>16)&TWin.ymask)<<11)+
3368                     YAdjust+(XAdjust>>1)];
3369        tC1=(tC1>>((XAdjust&1)<<2))&0xf;
3370        XAdjust=((posX+difX)>>16)&TWin.xmask;
3371        tC2 = psxVub[((((posY+difY)>>16)&TWin.ymask)<<11)+
3372                     YAdjust+(XAdjust>>1)];
3373        tC2=(tC2>>((XAdjust&1)<<2))&0xf;
3374
3375        GetTextureTransColG32((uint32_t *)&psxVuw[(i<<10)+j],
3376             GETLE16(&psxVuw[clutP+tC1])|
3377             ((int32_t)GETLE16(&psxVuw[clutP+tC2]))<<16);
3378        posX+=difX2;
3379        posY+=difY2;
3380       }
3381      if(j==xmax)
3382       {
3383        XAdjust=(posX>>16)&TWin.xmask;
3384        tC1 = psxVub[(((posY>>16)&TWin.ymask)<<11)+
3385                     YAdjust+(XAdjust>>1)];
3386        tC1=(tC1>>((XAdjust&1)<<2))&0xf;
3387        GetTextureTransColG(&psxVuw[(i<<10)+j],GETLE16(&psxVuw[clutP+tC1]));
3388       }
3389     }
3390    if(NextRow_FT4()) return;
3391   }
3392 }
3393
3394 ////////////////////////////////////////////////////////////////////////
3395
3396 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)
3397 {
3398  int32_t num; 
3399  int32_t i,j,xmin,xmax,ymin,ymax;
3400  int32_t difX, difY, difX2, difY2;
3401  int32_t posX,posY,YAdjust,clutP,XAdjust;
3402  short tC1,tC2;
3403
3404  if(x1>drawW && x2>drawW && x3>drawW && x4>drawW) return;
3405  if(y1>drawH && y2>drawH && y3>drawH && y4>drawH) return;
3406  if(x1<drawX && x2<drawX && x3<drawX && x4<drawX) return;
3407  if(y1<drawY && y2<drawY && y3<drawY && y4<drawY) return;
3408  if(drawY>=drawH) return;
3409  if(drawX>=drawW) return; 
3410
3411  if(!SetupSections_FT4(x1,y1,x2,y2,x3,y3,x4,y4,tx1,ty1,tx2,ty2,tx3,ty3,tx4,ty4)) return;
3412
3413  ymax=Ymax;
3414
3415  for(ymin=Ymin;ymin<drawY;ymin++)
3416   if(NextRow_FT4()) return;
3417
3418  clutP=(clY<<10)+clX;
3419
3420  YAdjust=((GlobalTextAddrY)<<11)+(GlobalTextAddrX<<1);
3421  YAdjust+=(TWin.Position.y0<<11)+(TWin.Position.x0>>1);
3422
3423 #ifdef FASTSOLID
3424
3425  if(!bCheckMask && !DrawSemiTrans)
3426   {
3427    for (i=ymin;i<=ymax;i++)
3428     {
3429      xmin=(left_x >> 16);
3430      xmax=(right_x >> 16);
3431
3432      if(xmax>=xmin)
3433       {
3434        posX=left_u;
3435        posY=left_v;
3436
3437        num=(xmax-xmin);
3438        if(num==0) num=1;
3439        difX=(right_u-posX)/num;
3440        difY=(right_v-posY)/num;
3441        difX2=difX<<1;
3442        difY2=difY<<1;
3443
3444        if(xmin<drawX)
3445         {j=drawX-xmin;xmin=drawX;posX+=j*difX;posY+=j*difY;}
3446        xmax--;if(drawW<xmax) xmax=drawW;
3447
3448        for(j=xmin;j<xmax;j+=2)
3449         {
3450          XAdjust=(posX>>16)&TWin.xmask;
3451          tC1 = psxVub[(((posY>>16)&TWin.ymask)<<11)+
3452                       YAdjust+(XAdjust>>1)];
3453          tC1=(tC1>>((XAdjust&1)<<2))&0xf;
3454          XAdjust=((posX+difX)>>16)&TWin.xmask;
3455          tC2 = psxVub[((((posY+difY)>>16)&TWin.ymask)<<11)+
3456                       YAdjust+(XAdjust>>1)];
3457          tC2=(tC2>>((XAdjust&1)<<2))&0xf;
3458
3459          GetTextureTransColG32_S((uint32_t *)&psxVuw[(i<<10)+j],
3460               GETLE16(&psxVuw[clutP+tC1])|
3461               ((int32_t)GETLE16(&psxVuw[clutP+tC2]))<<16);
3462          posX+=difX2;
3463          posY+=difY2;
3464         }
3465        if(j==xmax)
3466         {
3467          XAdjust=(posX>>16)&TWin.xmask;
3468          tC1 = psxVub[(((posY>>16)&TWin.ymask)<<11)+
3469                       YAdjust+(XAdjust>>1)];
3470          tC1=(tC1>>((XAdjust&1)<<2))&0xf;
3471          GetTextureTransColG_S(&psxVuw[(i<<10)+j],GETLE16(&psxVuw[clutP+tC1]));
3472         }
3473       }
3474      if(NextRow_FT4()) return;
3475     }
3476    return;
3477   }
3478
3479 #endif
3480
3481  for (i=ymin;i<=ymax;i++)
3482   {
3483    xmin=(left_x >> 16);
3484    xmax=(right_x >> 16);
3485
3486    if(xmax>=xmin)
3487     {
3488      posX=left_u;
3489      posY=left_v;
3490
3491      num=(xmax-xmin);
3492      if(num==0) num=1;
3493      difX=(right_u-posX)/num;
3494      difY=(right_v-posY)/num;
3495      difX2=difX<<1;
3496      difY2=difY<<1;
3497
3498      if(xmin<drawX)
3499       {j=drawX-xmin;xmin=drawX;posX+=j*difX;posY+=j*difY;}
3500      xmax--;if(drawW<xmax) xmax=drawW;
3501
3502      for(j=xmin;j<xmax;j+=2)
3503       {
3504        XAdjust=(posX>>16)&TWin.xmask;
3505        tC1 = psxVub[(((posY>>16)&TWin.ymask)<<11)+
3506                     YAdjust+(XAdjust>>1)];
3507        tC1=(tC1>>((XAdjust&1)<<2))&0xf;
3508        XAdjust=((posX+difX)>>16)&TWin.xmask;
3509        tC2 = psxVub[((((posY+difY)>>16)&TWin.ymask)<<11)+
3510                     YAdjust+(XAdjust>>1)];
3511        tC2=(tC2>>((XAdjust&1)<<2))&0xf;
3512
3513        GetTextureTransColG32_SPR((uint32_t *)&psxVuw[(i<<10)+j],
3514             GETLE16(&psxVuw[clutP+tC1])|
3515             ((int32_t)GETLE16(&psxVuw[clutP+tC2]))<<16);
3516        posX+=difX2;
3517        posY+=difY2;
3518       }
3519      if(j==xmax)
3520       {
3521        XAdjust=(posX>>16)&TWin.xmask;
3522        tC1 = psxVub[(((posY>>16)&TWin.ymask)<<11)+
3523                     YAdjust+(XAdjust>>1)];
3524        tC1=(tC1>>((XAdjust&1)<<2))&0xf;
3525        GetTextureTransColG_SPR(&psxVuw[(i<<10)+j],GETLE16(&psxVuw[clutP+tC1]));
3526       }
3527     }
3528    if(NextRow_FT4()) return;
3529   }
3530 }
3531 ////////////////////////////////////////////////////////////////////////
3532 // POLY 3 F-SHADED TEX PAL 8
3533 ////////////////////////////////////////////////////////////////////////
3534
3535 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)
3536 {
3537  int i,j,xmin,xmax,ymin,ymax;
3538  int32_t difX, difY,difX2, difY2;
3539  int32_t posX,posY,YAdjust,clutP;
3540  short tC1,tC2;
3541
3542  if(x1>drawW && x2>drawW && x3>drawW) return;
3543  if(y1>drawH && y2>drawH && y3>drawH) return;
3544  if(x1<drawX && x2<drawX && x3<drawX) return;
3545  if(y1<drawY && y2<drawY && y3<drawY) return;
3546  if(drawY>=drawH) return;
3547  if(drawX>=drawW) return; 
3548
3549  if(!SetupSections_FT(x1,y1,x2,y2,x3,y3,tx1,ty1,tx2,ty2,tx3,ty3)) return;
3550
3551  ymax=Ymax;
3552
3553  for(ymin=Ymin;ymin<drawY;ymin++)
3554   if(NextRow_FT()) return;
3555
3556  clutP=(clY<<10)+clX;
3557
3558  YAdjust=((GlobalTextAddrY)<<11)+(GlobalTextAddrX<<1);
3559
3560  difX=delta_right_u;difX2=difX<<1;
3561  difY=delta_right_v;difY2=difY<<1;
3562
3563 #ifdef FASTSOLID
3564
3565  if(!bCheckMask && !DrawSemiTrans)
3566   {
3567    for (i=ymin;i<=ymax;i++)
3568     {
3569      xmin=(left_x >> 16);
3570      xmax=(right_x >> 16)-1; //!!!!!!!!!!!!!!!
3571      if(drawW<xmax) xmax=drawW;
3572
3573      if(xmax>=xmin)
3574       {
3575        posX=left_u;
3576        posY=left_v;
3577
3578        if(xmin<drawX)
3579         {j=drawX-xmin;xmin=drawX;posX+=j*difX;posY+=j*difY;}
3580
3581        for(j=xmin;j<xmax;j+=2)
3582         {
3583          tC1 = psxVub[((posY>>5)&(int32_t)0xFFFFF800)+YAdjust+(posX>>16)];
3584          tC2 = psxVub[(((posY+difY)>>5)&(int32_t)0xFFFFF800)+YAdjust+
3585                       ((posX+difX)>>16)];
3586          GetTextureTransColG32_S((uint32_t *)&psxVuw[(i<<10)+j],
3587              GETLE16(&psxVuw[clutP+tC1])|
3588              ((int32_t)GETLE16(&psxVuw[clutP+tC2]))<<16);
3589          posX+=difX2;
3590          posY+=difY2;
3591         }
3592
3593        if(j==xmax)
3594         {
3595          tC1 = psxVub[((posY>>5)&(int32_t)0xFFFFF800)+YAdjust+(posX>>16)];
3596          GetTextureTransColG_S(&psxVuw[(i<<10)+j],GETLE16(&psxVuw[clutP+tC1]));
3597         }
3598       }
3599      if(NextRow_FT()) 
3600       {
3601        return;
3602       }
3603     }
3604    return;
3605   }
3606
3607 #endif
3608
3609  for (i=ymin;i<=ymax;i++)
3610   {
3611    xmin=(left_x >> 16);
3612    xmax=(right_x >> 16)-1; //!!!!!!!!!!!!!!!!!
3613    if(drawW<xmax) xmax=drawW;
3614
3615    if(xmax>=xmin)
3616     {
3617      posX=left_u;
3618      posY=left_v;
3619
3620      if(xmin<drawX)
3621       {j=drawX-xmin;xmin=drawX;posX+=j*difX;posY+=j*difY;}
3622
3623      for(j=xmin;j<xmax;j+=2)
3624       {
3625        tC1 = psxVub[((posY>>5)&(int32_t)0xFFFFF800)+YAdjust+(posX>>16)];
3626        tC2 = psxVub[(((posY+difY)>>5)&(int32_t)0xFFFFF800)+YAdjust+
3627                     ((posX+difX)>>16)];
3628        GetTextureTransColG32((uint32_t *)&psxVuw[(i<<10)+j],
3629            GETLE16(&psxVuw[clutP+tC1])|
3630            ((int32_t)GETLE16(&psxVuw[clutP+tC2]))<<16);
3631        posX+=difX2;
3632        posY+=difY2;
3633       }
3634
3635      if(j==xmax)
3636       {
3637        tC1 = psxVub[((posY>>5)&(int32_t)0xFFFFF800)+YAdjust+(posX>>16)];
3638        GetTextureTransColG(&psxVuw[(i<<10)+j],GETLE16(&psxVuw[clutP+tC1]));
3639       }
3640
3641     }
3642    if(NextRow_FT()) 
3643     {
3644      return;
3645     }
3646   }
3647 }
3648
3649 ////////////////////////////////////////////////////////////////////////
3650
3651 static void drawPoly3TEx8_IL(short x1, short y1, short x2, short y2, short x3, short y3, short tx1, short ty1, short tx2, short ty2, short tx3, short ty3,short clX, short clY)
3652 {
3653  int i,j,xmin,xmax,ymin,ymax,n_xi,n_yi,TXV,TXU;
3654  int32_t difX, difY,difX2, difY2;
3655  int32_t posX,posY,YAdjust,clutP;
3656  short tC1,tC2;
3657
3658  if(x1>drawW && x2>drawW && x3>drawW) return;
3659  if(y1>drawH && y2>drawH && y3>drawH) return;
3660  if(x1<drawX && x2<drawX && x3<drawX) return;
3661  if(y1<drawY && y2<drawY && y3<drawY) return;
3662  if(drawY>=drawH) return;
3663  if(drawX>=drawW) return; 
3664
3665  if(!SetupSections_FT(x1,y1,x2,y2,x3,y3,tx1,ty1,tx2,ty2,tx3,ty3)) return;
3666
3667  ymax=Ymax;
3668
3669  for(ymin=Ymin;ymin<drawY;ymin++)
3670   if(NextRow_FT()) return;
3671
3672  clutP=(clY<<10)+clX;
3673
3674  YAdjust=(GlobalTextAddrY<<10)+GlobalTextAddrX;
3675
3676  difX=delta_right_u;difX2=difX<<1;
3677  difY=delta_right_v;difY2=difY<<1;
3678
3679 #ifdef FASTSOLID
3680
3681  if(!bCheckMask && !DrawSemiTrans)
3682   {
3683    for (i=ymin;i<=ymax;i++)
3684     {
3685      xmin=(left_x >> 16);
3686      xmax=(right_x >> 16)-1; //!!!!!!!!!!!!!!!
3687      if(drawW<xmax) xmax=drawW;
3688
3689      if(xmax>=xmin)
3690       {
3691        posX=left_u;
3692        posY=left_v;
3693
3694        if(xmin<drawX)
3695         {j=drawX-xmin;xmin=drawX;posX+=j*difX;posY+=j*difY;}
3696
3697        for(j=xmin;j<xmax;j+=2)
3698         {
3699          TXU=posX>>16;
3700          TXV=posY>>16;
3701          n_xi = ( ( TXU >> 1 ) & ~0x78 ) + ( ( TXU << 2 ) & 0x40 ) + ( ( TXV << 3 ) & 0x38 );
3702          n_yi = ( TXV & ~0x7 ) + ( ( TXU >> 5 ) & 0x7 );
3703
3704          tC1= (GETLE16(&psxVuw[(n_yi<<10)+YAdjust+n_xi]) >> ((TXU & 0x01)<<3)) & 0xff;
3705
3706          TXU=(posX+difX)>>16;
3707          TXV=(posY+difY)>>16;
3708          n_xi = ( ( TXU >> 1 ) & ~0x78 ) + ( ( TXU << 2 ) & 0x40 ) + ( ( TXV << 3 ) & 0x38 );
3709          n_yi = ( TXV & ~0x7 ) + ( ( TXU >> 5 ) & 0x7 );
3710
3711          tC2= (GETLE16(&psxVuw[(n_yi<<10)+YAdjust+n_xi]) >> ((TXU & 0x01)<<3)) & 0xff;
3712
3713          GetTextureTransColG32_S((uint32_t *)&psxVuw[(i<<10)+j],
3714              GETLE16(&psxVuw[clutP+tC1])|
3715              ((int32_t)GETLE16(&psxVuw[clutP+tC2]))<<16);
3716          posX+=difX2;
3717          posY+=difY2;
3718         }
3719
3720        if(j==xmax)
3721         {
3722          TXU=posX>>16;
3723          TXV=posY>>16;
3724          n_xi = ( ( TXU >> 1 ) & ~0x78 ) + ( ( TXU << 2 ) & 0x40 ) + ( ( TXV << 3 ) & 0x38 );
3725          n_yi = ( TXV & ~0x7 ) + ( ( TXU >> 5 ) & 0x7 );
3726
3727          tC1= (GETLE16(&psxVuw[(n_yi<<10)+YAdjust+n_xi]) >> ((TXU & 0x01)<<3)) & 0xff;
3728
3729          GetTextureTransColG_S(&psxVuw[(i<<10)+j],GETLE16(&psxVuw[clutP+tC1]));
3730         }
3731       }
3732      if(NextRow_FT()) 
3733       {
3734        return;
3735       }
3736     }
3737    return;
3738   }
3739
3740 #endif
3741
3742  for (i=ymin;i<=ymax;i++)
3743   {
3744    xmin=(left_x >> 16);
3745    xmax=(right_x >> 16)-1; //!!!!!!!!!!!!!!!!!
3746    if(drawW<xmax) xmax=drawW;
3747
3748    if(xmax>=xmin)
3749     {
3750      posX=left_u;
3751      posY=left_v;
3752
3753      if(xmin<drawX)
3754       {j=drawX-xmin;xmin=drawX;posX+=j*difX;posY+=j*difY;}
3755
3756      for(j=xmin;j<xmax;j+=2)
3757       {
3758        TXU=posX>>16;
3759        TXV=posY>>16;
3760        n_xi = ( ( TXU >> 1 ) & ~0x78 ) + ( ( TXU << 2 ) & 0x40 ) + ( ( TXV << 3 ) & 0x38 );
3761        n_yi = ( TXV & ~0x7 ) + ( ( TXU >> 5 ) & 0x7 );
3762
3763        tC1= (GETLE16(&psxVuw[(n_yi<<10)+YAdjust+n_xi]) >> ((TXU & 0x01)<<3)) & 0xff;
3764
3765        TXU=(posX+difX)>>16;
3766        TXV=(posY+difY)>>16;
3767        n_xi = ( ( TXU >> 1 ) & ~0x78 ) + ( ( TXU << 2 ) & 0x40 ) + ( ( TXV << 3 ) & 0x38 );
3768        n_yi = ( TXV & ~0x7 ) + ( ( TXU >> 5 ) & 0x7 );
3769
3770        tC2= (GETLE16(&psxVuw[(n_yi<<10)+YAdjust+n_xi]) >> ((TXU & 0x01)<<3)) & 0xff;
3771
3772        GetTextureTransColG32((uint32_t *)&psxVuw[(i<<10)+j],
3773            GETLE16(&psxVuw[clutP+tC1])|
3774            ((int32_t)GETLE16(&psxVuw[clutP+tC2]))<<16);
3775        posX+=difX2;
3776        posY+=difY2;
3777       }
3778
3779      if(j==xmax)
3780       {
3781        TXU=posX>>16;
3782        TXV=posY>>16;
3783        n_xi = ( ( TXU >> 1 ) & ~0x78 ) + ( ( TXU << 2 ) & 0x40 ) + ( ( TXV << 3 ) & 0x38 );
3784        n_yi = ( TXV & ~0x7 ) + ( ( TXU >> 5 ) & 0x7 );
3785
3786        tC1= (GETLE16(&psxVuw[(n_yi<<10)+YAdjust+n_xi]) >> ((TXU & 0x01)<<3)) & 0xff;
3787
3788        GetTextureTransColG(&psxVuw[(i<<10)+j],GETLE16(&psxVuw[clutP+tC1]));
3789       }
3790
3791     }
3792    if(NextRow_FT()) 
3793     {
3794      return;
3795     }
3796   }
3797 }
3798
3799 ////////////////////////////////////////////////////////////////////////
3800
3801 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)
3802 {
3803  int i,j,xmin,xmax,ymin,ymax;
3804  int32_t difX, difY,difX2, difY2;
3805  int32_t posX,posY,YAdjust,clutP;
3806  short tC1,tC2;
3807
3808  if(x1>drawW && x2>drawW && x3>drawW) return;
3809  if(y1>drawH && y2>drawH && y3>drawH) return;
3810  if(x1<drawX && x2<drawX && x3<drawX) return;
3811  if(y1<drawY && y2<drawY && y3<drawY) return;
3812  if(drawY>=drawH) return;
3813  if(drawX>=drawW) return; 
3814
3815  if(!SetupSections_FT(x1,y1,x2,y2,x3,y3,tx1,ty1,tx2,ty2,tx3,ty3)) return;
3816
3817  ymax=Ymax;
3818
3819  for(ymin=Ymin;ymin<drawY;ymin++)
3820   if(NextRow_FT()) return;
3821
3822  clutP=(clY<<10)+clX;
3823
3824  YAdjust=((GlobalTextAddrY)<<11)+(GlobalTextAddrX<<1);
3825  YAdjust+=(TWin.Position.y0<<11)+(TWin.Position.x0);
3826
3827  difX=delta_right_u;difX2=difX<<1;
3828  difY=delta_right_v;difY2=difY<<1;
3829
3830 #ifdef FASTSOLID
3831
3832  if(!bCheckMask && !DrawSemiTrans)
3833   {
3834    for (i=ymin;i<=ymax;i++)
3835     {
3836      xmin=(left_x >> 16);
3837      xmax=(right_x >> 16);//-1; //!!!!!!!!!!!!!!!!
3838      if(xmax>xmin) xmax--;
3839
3840      if(drawW<xmax) xmax=drawW;
3841
3842      if(xmax>=xmin)
3843       {
3844        posX=left_u;
3845        posY=left_v;
3846
3847        if(xmin<drawX)
3848         {j=drawX-xmin;xmin=drawX;posX+=j*difX;posY+=j*difY;}
3849
3850        for(j=xmin;j<xmax;j+=2)
3851         {
3852          tC1 = psxVub[(((posY>>16)&TWin.ymask)<<11)+
3853                       YAdjust+((posX>>16)&TWin.xmask)];
3854          tC2 = psxVub[((((posY+difY)>>16)&TWin.ymask)<<11)+
3855                       YAdjust+(((posX+difX)>>16)&TWin.xmask)];
3856          GetTextureTransColG32_S((uint32_t *)&psxVuw[(i<<10)+j],
3857              GETLE16(&psxVuw[clutP+tC1])|
3858              ((int32_t)GETLE16(&psxVuw[clutP+tC2]))<<16);
3859          posX+=difX2;
3860          posY+=difY2;
3861         }
3862
3863        if(j==xmax)
3864         {
3865          tC1 = psxVub[(((posY>>16)&TWin.ymask)<<11)+
3866                       YAdjust+((posX>>16)&TWin.xmask)];
3867          GetTextureTransColG_S(&psxVuw[(i<<10)+j],GETLE16(&psxVuw[clutP+tC1]));
3868         }
3869       }
3870      if(NextRow_FT()) 
3871       {
3872        return;
3873       }
3874     }
3875    return;
3876   }
3877
3878 #endif
3879
3880  for (i=ymin;i<=ymax;i++)
3881   {
3882    xmin=(left_x >> 16);
3883    xmax=(right_x >> 16)-1; //!!!!!!!!!!!!!!!!!
3884    if(drawW<xmax) xmax=drawW;
3885
3886    if(xmax>=xmin)
3887     {
3888      posX=left_u;
3889      posY=left_v;
3890
3891      if(xmin<drawX)
3892       {j=drawX-xmin;xmin=drawX;posX+=j*difX;posY+=j*difY;}
3893
3894      for(j=xmin;j<xmax;j+=2)
3895       {
3896        tC1 = psxVub[(((posY>>16)&TWin.ymask)<<11)+
3897                     YAdjust+((posX>>16)&TWin.xmask)];
3898        tC2 = psxVub[((((posY+difY)>>16)&TWin.ymask)<<11)+
3899                     YAdjust+(((posX+difX)>>16)&TWin.xmask)];
3900        GetTextureTransColG32((uint32_t *)&psxVuw[(i<<10)+j],
3901            GETLE16(&psxVuw[clutP+tC1])|
3902            ((int32_t)GETLE16(&psxVuw[clutP+tC2]))<<16);
3903        posX+=difX2;
3904        posY+=difY2;
3905       }
3906
3907      if(j==xmax)
3908       {
3909        tC1 = psxVub[(((posY>>16)&TWin.ymask)<<11)+
3910                     YAdjust+((posX>>16)&TWin.xmask)];
3911        GetTextureTransColG(&psxVuw[(i<<10)+j],GETLE16(&psxVuw[clutP+tC1]));
3912       }
3913
3914     }
3915    if(NextRow_FT()) 
3916     {
3917      return;
3918     }
3919   }
3920 }
3921
3922 ////////////////////////////////////////////////////////////////////////
3923
3924 #ifdef POLYQUAD3
3925
3926 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)
3927 {
3928  drawPoly3TEx8(x2,y2,x3,y3,x4,y4,
3929                tx2,ty2,tx3,ty3,tx4,ty4,
3930                clX,clY);
3931
3932  drawPoly3TEx8(x1,y1,x2,y2,x4,y4,
3933                tx1,ty1,tx2,ty2,tx4,ty4,
3934                clX,clY);
3935 }
3936
3937 #endif
3938
3939 // more exact:
3940
3941 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)
3942 {
3943  int32_t num; 
3944  int32_t i,j,xmin,xmax,ymin,ymax;
3945  int32_t difX, difY, difX2, difY2;
3946  int32_t posX,posY,YAdjust,clutP;
3947  short tC1,tC2;
3948
3949  if(x1>drawW && x2>drawW && x3>drawW && x4>drawW) return;
3950  if(y1>drawH && y2>drawH && y3>drawH && y4>drawH) return;
3951  if(x1<drawX && x2<drawX && x3<drawX && x4<drawX) return;
3952  if(y1<drawY && y2<drawY && y3<drawY && y4<drawY) return;
3953  if(drawY>=drawH) return;
3954  if(drawX>=drawW) return; 
3955
3956  if(!SetupSections_FT4(x1,y1,x2,y2,x3,y3,x4,y4,tx1,ty1,tx2,ty2,tx3,ty3,tx4,ty4)) return;
3957
3958  ymax=Ymax;
3959
3960  for(ymin=Ymin;ymin<drawY;ymin++)
3961   if(NextRow_FT4()) return;
3962
3963  clutP=(clY<<10)+clX;
3964
3965  YAdjust=((GlobalTextAddrY)<<11)+(GlobalTextAddrX<<1);
3966
3967 #ifdef FASTSOLID
3968
3969  if(!bCheckMask && !DrawSemiTrans)
3970   {
3971    for (i=ymin;i<=ymax;i++)
3972     {
3973      xmin=(left_x >> 16);
3974      xmax=(right_x >> 16);
3975
3976      if(xmax>=xmin)
3977       {
3978        posX=left_u;
3979        posY=left_v;
3980
3981        num=(xmax-xmin);
3982        if(num==0) num=1;
3983        difX=(right_u-posX)/num;
3984        difY=(right_v-posY)/num;
3985        difX2=difX<<1;
3986        difY2=difY<<1;
3987
3988        if(xmin<drawX)
3989         {j=drawX-xmin;xmin=drawX;posX+=j*difX;posY+=j*difY;}
3990        xmax--;if(drawW<xmax) xmax=drawW;
3991
3992        for(j=xmin;j<xmax;j+=2)
3993         {
3994          tC1 = psxVub[((posY>>5)&(int32_t)0xFFFFF800)+YAdjust+(posX>>16)];
3995          tC2 = psxVub[(((posY+difY)>>5)&(int32_t)0xFFFFF800)+YAdjust+
3996                      ((posX+difX)>>16)];
3997          GetTextureTransColG32_S((uint32_t *)&psxVuw[(i<<10)+j],
3998               GETLE16(&psxVuw[clutP+tC1])|
3999               ((int32_t)GETLE16(&psxVuw[clutP+tC2]))<<16);
4000          posX+=difX2;
4001          posY+=difY2;
4002         }
4003        if(j==xmax)
4004         {
4005          tC1 = psxVub[((posY>>5)&(int32_t)0xFFFFF800)+YAdjust+(posX>>16)];
4006          GetTextureTransColG_S(&psxVuw[(i<<10)+j],GETLE16(&psxVuw[clutP+tC1]));
4007         }
4008       }
4009      if(NextRow_FT4()) return;
4010     }
4011    return;
4012   }
4013
4014 #endif
4015
4016  for (i=ymin;i<=ymax;i++)
4017   {
4018    xmin=(left_x >> 16);
4019    xmax=(right_x >> 16);
4020
4021    if(xmax>=xmin)
4022     {
4023      posX=left_u;
4024      posY=left_v;
4025
4026      num=(xmax-xmin);
4027      if(num==0) num=1;
4028      difX=(right_u-posX)/num;
4029      difY=(right_v-posY)/num;
4030      difX2=difX<<1;
4031      difY2=difY<<1;
4032
4033      if(xmin<drawX)
4034       {j=drawX-xmin;xmin=drawX;posX+=j*difX;posY+=j*difY;}
4035      xmax--;if(drawW<xmax) xmax=drawW;
4036
4037      for(j=xmin;j<xmax;j+=2)
4038       {
4039        tC1 = psxVub[((posY>>5)&(int32_t)0xFFFFF800)+YAdjust+(posX>>16)];
4040        tC2 = psxVub[(((posY+difY)>>5)&(int32_t)0xFFFFF800)+YAdjust+
4041                      ((posX+difX)>>16)];
4042        GetTextureTransColG32((uint32_t *)&psxVuw[(i<<10)+j],
4043             GETLE16(&psxVuw[clutP+tC1])|
4044             ((int32_t)GETLE16(&psxVuw[clutP+tC2]))<<16);
4045        posX+=difX2;
4046        posY+=difY2;
4047       }
4048      if(j==xmax)
4049       {
4050        tC1 = psxVub[((posY>>5)&(int32_t)0xFFFFF800)+YAdjust+(posX>>16)];
4051        GetTextureTransColG(&psxVuw[(i<<10)+j],GETLE16(&psxVuw[clutP+tC1]));
4052       }
4053     }
4054    if(NextRow_FT4()) return;
4055   }
4056 }
4057
4058 ////////////////////////////////////////////////////////////////////////
4059
4060 static void drawPoly4TEx8_IL(short x1, short y1, short x2, short y2, short x3, short y3, short x4, short y4, short tx1, short ty1, short tx2, short ty2, short tx3, short ty3, short tx4, short ty4,short clX, short clY)
4061 {
4062  int32_t num; 
4063  int32_t i,j,xmin,xmax,ymin,ymax,n_xi,n_yi,TXV,TXU;
4064  int32_t difX, difY, difX2, difY2;
4065  int32_t posX,posY,YAdjust,clutP;
4066  short tC1,tC2;
4067
4068  if(x1>drawW && x2>drawW && x3>drawW && x4>drawW) return;
4069  if(y1>drawH && y2>drawH && y3>drawH && y4>drawH) return;
4070  if(x1<drawX && x2<drawX && x3<drawX && x4<drawX) return;
4071  if(y1<drawY && y2<drawY && y3<drawY && y4<drawY) return;
4072  if(drawY>=drawH) return;
4073  if(drawX>=drawW) return; 
4074
4075  if(!SetupSections_FT4(x1,y1,x2,y2,x3,y3,x4,y4,tx1,ty1,tx2,ty2,tx3,ty3,tx4,ty4)) return;
4076
4077  ymax=Ymax;
4078
4079  for(ymin=Ymin;ymin<drawY;ymin++)
4080   if(NextRow_FT4()) return;
4081
4082  clutP=(clY<<10)+clX;
4083
4084  YAdjust=(GlobalTextAddrY<<10)+GlobalTextAddrX;
4085
4086 #ifdef FASTSOLID
4087
4088  if(!bCheckMask && !DrawSemiTrans)
4089   {
4090    for (i=ymin;i<=ymax;i++)
4091     {
4092      xmin=(left_x >> 16);
4093      xmax=(right_x >> 16);
4094
4095      if(xmax>=xmin)
4096       {
4097        posX=left_u;
4098        posY=left_v;
4099
4100        num=(xmax-xmin);
4101        if(num==0) num=1;
4102        difX=(right_u-posX)/num;
4103        difY=(right_v-posY)/num;
4104        difX2=difX<<1;
4105        difY2=difY<<1;
4106
4107        if(xmin<drawX)
4108         {j=drawX-xmin;xmin=drawX;posX+=j*difX;posY+=j*difY;}
4109        xmax--;if(drawW<xmax) xmax=drawW;
4110
4111        for(j=xmin;j<xmax;j+=2)
4112         {
4113          TXU=posX>>16;
4114          TXV=posY>>16;
4115          n_xi = ( ( TXU >> 1 ) & ~0x78 ) + ( ( TXU << 2 ) & 0x40 ) + ( ( TXV << 3 ) & 0x38 );
4116          n_yi = ( TXV & ~0x7 ) + ( ( TXU >> 5 ) & 0x7 );
4117
4118          tC1= (GETLE16(&psxVuw[(n_yi<<10)+YAdjust+n_xi]) >> ((TXU & 0x01)<<3)) & 0xff;
4119
4120          TXU=(posX+difX)>>16;
4121          TXV=(posY+difY)>>16;
4122          n_xi = ( ( TXU >> 1 ) & ~0x78 ) + ( ( TXU << 2 ) & 0x40 ) + ( ( TXV << 3 ) & 0x38 );
4123          n_yi = ( TXV & ~0x7 ) + ( ( TXU >> 5 ) & 0x7 );
4124
4125          tC2= (GETLE16(&psxVuw[(n_yi<<10)+YAdjust+n_xi]) >> ((TXU & 0x01)<<3)) & 0xff;
4126
4127          GetTextureTransColG32_S((uint32_t *)&psxVuw[(i<<10)+j],
4128               GETLE16(&psxVuw[clutP+tC1])|
4129               ((int32_t)GETLE16(&psxVuw[clutP+tC2]))<<16);
4130          posX+=difX2;
4131          posY+=difY2;
4132         }
4133        if(j==xmax)
4134         {
4135          TXU=posX>>16;
4136          TXV=posY>>16;
4137          n_xi = ( ( TXU >> 1 ) & ~0x78 ) + ( ( TXU << 2 ) & 0x40 ) + ( ( TXV << 3 ) & 0x38 );
4138          n_yi = ( TXV & ~0x7 ) + ( ( TXU >> 5 ) & 0x7 );
4139
4140          tC1= (GETLE16(&psxVuw[(n_yi<<10)+YAdjust+n_xi]) >> ((TXU & 0x01)<<3)) & 0xff;
4141
4142          GetTextureTransColG_S(&psxVuw[(i<<10)+j],GETLE16(&psxVuw[clutP+tC1]));
4143         }
4144       }
4145      if(NextRow_FT4()) return;
4146     }
4147    return;
4148   }
4149
4150 #endif
4151
4152  for (i=ymin;i<=ymax;i++)
4153   {
4154    xmin=(left_x >> 16);
4155    xmax=(right_x >> 16);
4156
4157    if(xmax>=xmin)
4158     {
4159      posX=left_u;
4160      posY=left_v;
4161
4162      num=(xmax-xmin);
4163      if(num==0) num=1;
4164      difX=(right_u-posX)/num;
4165      difY=(right_v-posY)/num;
4166      difX2=difX<<1;
4167      difY2=difY<<1;
4168
4169      if(xmin<drawX)
4170       {j=drawX-xmin;xmin=drawX;posX+=j*difX;posY+=j*difY;}
4171      xmax--;if(drawW<xmax) xmax=drawW;
4172
4173      for(j=xmin;j<xmax;j+=2)
4174       {
4175        TXU=posX>>16;
4176        TXV=posY>>16;
4177        n_xi = ( ( TXU >> 1 ) & ~0x78 ) + ( ( TXU << 2 ) & 0x40 ) + ( ( TXV << 3 ) & 0x38 );
4178        n_yi = ( TXV & ~0x7 ) + ( ( TXU >> 5 ) & 0x7 );
4179
4180        tC1= (GETLE16(&psxVuw[(n_yi<<10)+YAdjust+n_xi]) >> ((TXU & 0x01)<<3)) & 0xff;
4181
4182        TXU=(posX+difX)>>16;
4183        TXV=(posY+difY)>>16;
4184        n_xi = ( ( TXU >> 1 ) & ~0x78 ) + ( ( TXU << 2 ) & 0x40 ) + ( ( TXV << 3 ) & 0x38 );
4185        n_yi = ( TXV & ~0x7 ) + ( ( TXU >> 5 ) & 0x7 );
4186        
4187        tC2= (GETLE16(&psxVuw[(n_yi<<10)+YAdjust+n_xi]) >> ((TXU & 0x01)<<3)) & 0xff;
4188
4189        GetTextureTransColG32((uint32_t *)&psxVuw[(i<<10)+j],
4190             GETLE16(&psxVuw[clutP+tC1])|
4191             ((int32_t)GETLE16(&psxVuw[clutP+tC2]))<<16);
4192        posX+=difX2;
4193        posY+=difY2;
4194       }
4195      if(j==xmax)
4196       {
4197        TXU=posX>>16;
4198        TXV=posY>>16;
4199        n_xi = ( ( TXU >> 1 ) & ~0x78 ) + ( ( TXU << 2 ) & 0x40 ) + ( ( TXV << 3 ) & 0x38 );
4200        n_yi = ( TXV & ~0x7 ) + ( ( TXU >> 5 ) & 0x7 );
4201        tC1= (GETLE16(&psxVuw[(n_yi<<10)+YAdjust+n_xi]) >> ((TXU & 0x01)<<3)) & 0xff;
4202        GetTextureTransColG(&psxVuw[(i<<10)+j],GETLE16(&psxVuw[clutP+tC1]));
4203       }
4204     }
4205    if(NextRow_FT4()) return;
4206   }
4207 }
4208
4209 ////////////////////////////////////////////////////////////////////////
4210
4211 static void drawPoly4TEx8_TW(short x1, short y1, short x2, short y2, short x3, short y3, short x4, short y4, short tx1, short ty1, short tx2, short ty2, short tx3, short ty3, short tx4, short ty4,short clX, short clY)
4212 {
4213  int32_t num; 
4214  int32_t i,j,xmin,xmax,ymin,ymax;
4215  int32_t difX, difY, difX2, difY2;
4216  int32_t posX,posY,YAdjust,clutP;
4217  short tC1,tC2;
4218
4219  if(x1>drawW && x2>drawW && x3>drawW && x4>drawW) return;
4220  if(y1>drawH && y2>drawH && y3>drawH && y4>drawH) return;