dfxvideo: fill sanity check to prevent crashes
[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  __int64 bi=x;
1081  bi<<=10;
1082  return bi/y;
1083 }
1084
1085 ////////////////////////////////////////////////////////////////////////
1086 ////////////////////////////////////////////////////////////////////////
1087 ////////////////////////////////////////////////////////////////////////
1088                         
1089 static inline int RightSection_F(void)
1090 {
1091  soft_vertex * v1 = right_array[ right_section ];
1092  soft_vertex * v2 = right_array[ right_section-1 ];
1093
1094  int height = v2->y - v1->y;
1095  if(height == 0) return 0;
1096  delta_right_x = (v2->x - v1->x) / height;
1097  right_x = v1->x;
1098
1099  right_section_height = height;
1100  return height;
1101 }
1102
1103 ////////////////////////////////////////////////////////////////////////
1104
1105 static inline int LeftSection_F(void)
1106 {
1107  soft_vertex * v1 = left_array[ left_section ];
1108  soft_vertex * v2 = left_array[ left_section-1 ];
1109
1110  int height = v2->y - v1->y;
1111  if(height == 0) return 0;
1112  delta_left_x = (v2->x - v1->x) / height;
1113  left_x = v1->x;
1114
1115  left_section_height = height;
1116  return height;  
1117 }
1118
1119 ////////////////////////////////////////////////////////////////////////
1120
1121 static inline BOOL NextRow_F(void)
1122 {
1123  if(--left_section_height<=0) 
1124   {
1125    if(--left_section <= 0) {return TRUE;}
1126    if(LeftSection_F()  <= 0) {return TRUE;}
1127   }
1128  else
1129   {
1130    left_x += delta_left_x;
1131   }
1132
1133  if(--right_section_height<=0) 
1134   {
1135    if(--right_section<=0) {return TRUE;}
1136    if(RightSection_F() <=0) {return TRUE;}
1137   }
1138  else
1139   {
1140    right_x += delta_right_x;
1141   }
1142  return FALSE;
1143 }
1144
1145 ////////////////////////////////////////////////////////////////////////
1146
1147 static inline BOOL SetupSections_F(short x1, short y1, short x2, short y2, short x3, short y3)
1148 {
1149  soft_vertex * v1, * v2, * v3;
1150  int height,longest;
1151
1152  v1 = vtx;   v1->x=x1<<16;v1->y=y1;
1153  v2 = vtx+1; v2->x=x2<<16;v2->y=y2;
1154  v3 = vtx+2; v3->x=x3<<16;v3->y=y3;
1155
1156  if(v1->y > v2->y) { soft_vertex * v = v1; v1 = v2; v2 = v; }
1157  if(v1->y > v3->y) { soft_vertex * v = v1; v1 = v3; v3 = v; }
1158  if(v2->y > v3->y) { soft_vertex * v = v2; v2 = v3; v3 = v; }
1159
1160  height = v3->y - v1->y;
1161  if(height == 0) {return FALSE;}
1162  longest = (((v2->y - v1->y) << 16) / height) * ((v3->x - v1->x)>>16) + (v1->x - v2->x);
1163  if(longest == 0) {return FALSE;}
1164
1165  if(longest < 0)
1166   {
1167    right_array[0] = v3;
1168    right_array[1] = v2;
1169    right_array[2] = v1;
1170    right_section  = 2;
1171    left_array[0]  = v3;
1172    left_array[1]  = v1;
1173    left_section   = 1;
1174
1175    if(LeftSection_F() <= 0) return FALSE;
1176    if(RightSection_F() <= 0)
1177     {
1178      right_section--;
1179      if(RightSection_F() <= 0) return FALSE;
1180     }
1181   }
1182  else
1183   {
1184    left_array[0]  = v3;
1185    left_array[1]  = v2;
1186    left_array[2]  = v1;
1187    left_section   = 2;
1188    right_array[0] = v3;
1189    right_array[1] = v1;
1190    right_section  = 1;
1191
1192    if(RightSection_F() <= 0) return FALSE;
1193    if(LeftSection_F() <= 0)
1194     {    
1195      left_section--;
1196      if(LeftSection_F() <= 0) return FALSE;
1197     }
1198   }
1199
1200  Ymin=v1->y;
1201  Ymax=min(v3->y-1,drawH);
1202
1203  return TRUE;
1204 }
1205
1206 ////////////////////////////////////////////////////////////////////////
1207 ////////////////////////////////////////////////////////////////////////
1208
1209 static inline int RightSection_G(void)
1210 {
1211  soft_vertex * v1 = right_array[ right_section ];
1212  soft_vertex * v2 = right_array[ right_section-1 ];
1213
1214  int height = v2->y - v1->y;
1215  if(height == 0) return 0;
1216  delta_right_x = (v2->x - v1->x) / height;
1217  right_x = v1->x;
1218
1219  right_section_height = height;
1220  return height;
1221 }
1222
1223 ////////////////////////////////////////////////////////////////////////
1224
1225 static inline int LeftSection_G(void)
1226 {
1227  soft_vertex * v1 = left_array[ left_section ];
1228  soft_vertex * v2 = left_array[ left_section-1 ];
1229
1230  int height = v2->y - v1->y;
1231  if(height == 0) return 0;
1232  delta_left_x = (v2->x - v1->x) / height;
1233  left_x = v1->x;
1234
1235  delta_left_R = ((v2->R - v1->R)) / height;
1236  left_R = v1->R;
1237  delta_left_G = ((v2->G - v1->G)) / height;
1238  left_G = v1->G;
1239  delta_left_B = ((v2->B - v1->B)) / height;
1240  left_B = v1->B;
1241
1242  left_section_height = height;
1243  return height;  
1244 }
1245
1246 ////////////////////////////////////////////////////////////////////////
1247
1248 static inline BOOL NextRow_G(void)
1249 {
1250  if(--left_section_height<=0) 
1251   {
1252    if(--left_section <= 0) {return TRUE;}
1253    if(LeftSection_G()  <= 0) {return TRUE;}
1254   }
1255  else
1256   {
1257    left_x += delta_left_x;
1258    left_R += delta_left_R;
1259    left_G += delta_left_G;
1260    left_B += delta_left_B;
1261   }
1262
1263  if(--right_section_height<=0) 
1264   {
1265    if(--right_section<=0) {return TRUE;}
1266    if(RightSection_G() <=0) {return TRUE;}
1267   }
1268  else
1269   {
1270    right_x += delta_right_x;
1271   }
1272  return FALSE;
1273 }
1274
1275 ////////////////////////////////////////////////////////////////////////
1276
1277 static inline BOOL SetupSections_G(short x1,short y1,short x2,short y2,short x3,short y3,int32_t rgb1, int32_t rgb2, int32_t rgb3)
1278 {
1279  soft_vertex * v1, * v2, * v3;
1280  int height,longest,temp;
1281
1282  v1 = vtx;   v1->x=x1<<16;v1->y=y1;
1283  v1->R=(rgb1) & 0x00ff0000;
1284  v1->G=(rgb1<<8) & 0x00ff0000;
1285  v1->B=(rgb1<<16) & 0x00ff0000;
1286  v2 = vtx+1; v2->x=x2<<16;v2->y=y2;
1287  v2->R=(rgb2) & 0x00ff0000;
1288  v2->G=(rgb2<<8) & 0x00ff0000;
1289  v2->B=(rgb2<<16) & 0x00ff0000;
1290  v3 = vtx+2; v3->x=x3<<16;v3->y=y3;
1291  v3->R=(rgb3) & 0x00ff0000;
1292  v3->G=(rgb3<<8) & 0x00ff0000;
1293  v3->B=(rgb3<<16) & 0x00ff0000;
1294
1295  if(v1->y > v2->y) { soft_vertex * v = v1; v1 = v2; v2 = v; }
1296  if(v1->y > v3->y) { soft_vertex * v = v1; v1 = v3; v3 = v; }
1297  if(v2->y > v3->y) { soft_vertex * v = v2; v2 = v3; v3 = v; }
1298
1299  height = v3->y - v1->y;
1300  if(height == 0) {return FALSE;}
1301  temp=(((v2->y - v1->y) << 16) / height);
1302  longest = temp * ((v3->x - v1->x)>>16) + (v1->x - v2->x);
1303  if(longest == 0) {return FALSE;}
1304
1305  if(longest < 0)
1306   {
1307    right_array[0] = v3;
1308    right_array[1] = v2;
1309    right_array[2] = v1;
1310    right_section  = 2;
1311    left_array[0]  = v3;
1312    left_array[1]  = v1;
1313    left_section   = 1;
1314
1315    if(LeftSection_G() <= 0) return FALSE;
1316    if(RightSection_G() <= 0)
1317     {
1318      right_section--;
1319      if(RightSection_G() <= 0) return FALSE;
1320     }
1321    if(longest > -0x1000) longest = -0x1000;     
1322   }
1323  else
1324   {
1325    left_array[0]  = v3;
1326    left_array[1]  = v2;
1327    left_array[2]  = v1;
1328    left_section   = 2;
1329    right_array[0] = v3;
1330    right_array[1] = v1;
1331    right_section  = 1;
1332
1333    if(RightSection_G() <= 0) return FALSE;
1334    if(LeftSection_G() <= 0)
1335     {    
1336      left_section--;
1337      if(LeftSection_G() <= 0) return FALSE;
1338     }
1339    if(longest < 0x1000) longest = 0x1000;     
1340   }
1341
1342  Ymin=v1->y;
1343  Ymax=min(v3->y-1,drawH);    
1344
1345  delta_right_R=shl10idiv(temp*((v3->R - v1->R)>>10)+((v1->R - v2->R)<<6),longest);
1346  delta_right_G=shl10idiv(temp*((v3->G - v1->G)>>10)+((v1->G - v2->G)<<6),longest);
1347  delta_right_B=shl10idiv(temp*((v3->B - v1->B)>>10)+((v1->B - v2->B)<<6),longest);
1348
1349  return TRUE;
1350 }
1351
1352 ////////////////////////////////////////////////////////////////////////
1353 ////////////////////////////////////////////////////////////////////////
1354
1355 static inline int RightSection_FT(void)
1356 {
1357  soft_vertex * v1 = right_array[ right_section ];
1358  soft_vertex * v2 = right_array[ right_section-1 ];
1359
1360  int height = v2->y - v1->y;
1361  if(height == 0) return 0;
1362  delta_right_x = (v2->x - v1->x) / height;
1363  right_x = v1->x;
1364
1365  right_section_height = height;
1366  return height;
1367 }
1368
1369 ////////////////////////////////////////////////////////////////////////
1370
1371 static inline int LeftSection_FT(void)
1372 {
1373  soft_vertex * v1 = left_array[ left_section ];
1374  soft_vertex * v2 = left_array[ left_section-1 ];
1375
1376  int height = v2->y - v1->y;
1377  if(height == 0) return 0;
1378  delta_left_x = (v2->x - v1->x) / height;
1379  left_x = v1->x;
1380  
1381  delta_left_u = ((v2->u - v1->u)) / height;
1382  left_u = v1->u;
1383  delta_left_v = ((v2->v - v1->v)) / height;
1384  left_v = v1->v;
1385
1386  left_section_height = height;
1387  return height;  
1388 }
1389
1390 ////////////////////////////////////////////////////////////////////////
1391
1392 static inline BOOL NextRow_FT(void)
1393 {
1394  if(--left_section_height<=0) 
1395   {
1396    if(--left_section <= 0) {return TRUE;}
1397    if(LeftSection_FT()  <= 0) {return TRUE;}
1398   }
1399  else
1400   {
1401    left_x += delta_left_x;
1402    left_u += delta_left_u;
1403    left_v += delta_left_v;
1404   }
1405
1406  if(--right_section_height<=0) 
1407   {
1408    if(--right_section<=0) {return TRUE;}
1409    if(RightSection_FT() <=0) {return TRUE;}
1410   }
1411  else
1412   {
1413    right_x += delta_right_x;
1414   }
1415  return FALSE;
1416 }
1417
1418 ////////////////////////////////////////////////////////////////////////
1419
1420 static inline BOOL SetupSections_FT(short x1, short y1, short x2, short y2, short x3, short y3, short tx1, short ty1, short tx2, short ty2, short tx3, short ty3)
1421 {
1422  soft_vertex * v1, * v2, * v3;
1423  int height,longest,temp;
1424
1425  v1 = vtx;   v1->x=x1<<16;v1->y=y1;
1426  v1->u=tx1<<16;v1->v=ty1<<16;
1427  v2 = vtx+1; v2->x=x2<<16;v2->y=y2;
1428  v2->u=tx2<<16;v2->v=ty2<<16;
1429  v3 = vtx+2; v3->x=x3<<16;v3->y=y3;
1430  v3->u=tx3<<16;v3->v=ty3<<16;
1431
1432  if(v1->y > v2->y) { soft_vertex * v = v1; v1 = v2; v2 = v; }
1433  if(v1->y > v3->y) { soft_vertex * v = v1; v1 = v3; v3 = v; }
1434  if(v2->y > v3->y) { soft_vertex * v = v2; v2 = v3; v3 = v; }
1435
1436  height = v3->y - v1->y;
1437  if(height == 0) {return FALSE;}
1438
1439  temp=(((v2->y - v1->y) << 16) / height);
1440  longest = temp * ((v3->x - v1->x)>>16) + (v1->x - v2->x);
1441
1442  if(longest == 0) {return FALSE;}
1443
1444  if(longest < 0)
1445   {
1446    right_array[0] = v3;
1447    right_array[1] = v2;
1448    right_array[2] = v1;
1449    right_section  = 2;
1450    left_array[0]  = v3;
1451    left_array[1]  = v1;
1452    left_section   = 1;
1453
1454    if(LeftSection_FT() <= 0) return FALSE;
1455    if(RightSection_FT() <= 0)
1456     {
1457      right_section--;
1458      if(RightSection_FT() <= 0) return FALSE;
1459     }
1460    if(longest > -0x1000) longest = -0x1000;     
1461   }
1462  else
1463   {
1464    left_array[0]  = v3;
1465    left_array[1]  = v2;
1466    left_array[2]  = v1;
1467    left_section   = 2;
1468    right_array[0] = v3;
1469    right_array[1] = v1;
1470    right_section  = 1;
1471
1472    if(RightSection_FT() <= 0) return FALSE;
1473    if(LeftSection_FT() <= 0)
1474     {    
1475      left_section--;                
1476      if(LeftSection_FT() <= 0) return FALSE;
1477     }
1478    if(longest < 0x1000) longest = 0x1000;     
1479   }
1480
1481  Ymin=v1->y;
1482  Ymax=min(v3->y-1,drawH);
1483
1484  delta_right_u=shl10idiv(temp*((v3->u - v1->u)>>10)+((v1->u - v2->u)<<6),longest);
1485  delta_right_v=shl10idiv(temp*((v3->v - v1->v)>>10)+((v1->v - v2->v)<<6),longest);
1486
1487  return TRUE;
1488 }
1489
1490 ////////////////////////////////////////////////////////////////////////
1491 ////////////////////////////////////////////////////////////////////////
1492
1493 static inline int RightSection_GT(void)
1494 {
1495  soft_vertex * v1 = right_array[ right_section ];
1496  soft_vertex * v2 = right_array[ right_section-1 ];
1497
1498  int height = v2->y - v1->y;
1499  if(height == 0) return 0;
1500  delta_right_x = (v2->x - v1->x) / height;
1501  right_x = v1->x;
1502
1503  right_section_height = height;
1504  return height;
1505 }
1506
1507 ////////////////////////////////////////////////////////////////////////
1508
1509 static inline int LeftSection_GT(void)
1510 {
1511  soft_vertex * v1 = left_array[ left_section ];
1512  soft_vertex * v2 = left_array[ left_section-1 ];
1513
1514  int height = v2->y - v1->y;
1515  if(height == 0) return 0;
1516  delta_left_x = (v2->x - v1->x) / height;
1517  left_x = v1->x;
1518
1519  delta_left_u = ((v2->u - v1->u)) / height;
1520  left_u = v1->u;
1521  delta_left_v = ((v2->v - v1->v)) / height;
1522  left_v = v1->v;
1523
1524  delta_left_R = ((v2->R - v1->R)) / height;
1525  left_R = v1->R;
1526  delta_left_G = ((v2->G - v1->G)) / height;
1527  left_G = v1->G;
1528  delta_left_B = ((v2->B - v1->B)) / height;
1529  left_B = v1->B;
1530
1531  left_section_height = height;
1532  return height;  
1533 }
1534
1535 ////////////////////////////////////////////////////////////////////////
1536
1537 static inline BOOL NextRow_GT(void)
1538 {
1539  if(--left_section_height<=0) 
1540   {
1541    if(--left_section <= 0) {return TRUE;}
1542    if(LeftSection_GT()  <= 0) {return TRUE;}
1543   }
1544  else
1545   {
1546    left_x += delta_left_x;
1547    left_u += delta_left_u;
1548    left_v += delta_left_v;
1549    left_R += delta_left_R;
1550    left_G += delta_left_G;
1551    left_B += delta_left_B;
1552   }
1553
1554  if(--right_section_height<=0) 
1555   {
1556    if(--right_section<=0) {return TRUE;}
1557    if(RightSection_GT() <=0) {return TRUE;}
1558   }
1559  else
1560   {
1561    right_x += delta_right_x;
1562   }
1563  return FALSE;
1564 }
1565
1566 ////////////////////////////////////////////////////////////////////////
1567
1568 static inline BOOL SetupSections_GT(short x1, short y1, short x2, short y2, short x3, short y3, short tx1, short ty1, short tx2, short ty2, short tx3, short ty3, int32_t rgb1, int32_t rgb2, int32_t rgb3)
1569 {
1570  soft_vertex * v1, * v2, * v3;
1571  int height,longest,temp;
1572
1573  v1 = vtx;   v1->x=x1<<16;v1->y=y1;
1574  v1->u=tx1<<16;v1->v=ty1<<16;
1575  v1->R=(rgb1) & 0x00ff0000;
1576  v1->G=(rgb1<<8) & 0x00ff0000;
1577  v1->B=(rgb1<<16) & 0x00ff0000;
1578
1579  v2 = vtx+1; v2->x=x2<<16;v2->y=y2;
1580  v2->u=tx2<<16;v2->v=ty2<<16;
1581  v2->R=(rgb2) & 0x00ff0000;
1582  v2->G=(rgb2<<8) & 0x00ff0000;
1583  v2->B=(rgb2<<16) & 0x00ff0000;
1584              
1585  v3 = vtx+2; v3->x=x3<<16;v3->y=y3;
1586  v3->u=tx3<<16;v3->v=ty3<<16;
1587  v3->R=(rgb3) & 0x00ff0000;
1588  v3->G=(rgb3<<8) & 0x00ff0000;
1589  v3->B=(rgb3<<16) & 0x00ff0000;
1590
1591  if(v1->y > v2->y) { soft_vertex * v = v1; v1 = v2; v2 = v; }
1592  if(v1->y > v3->y) { soft_vertex * v = v1; v1 = v3; v3 = v; }
1593  if(v2->y > v3->y) { soft_vertex * v = v2; v2 = v3; v3 = v; }
1594
1595  height = v3->y - v1->y;
1596  if(height == 0) {return FALSE;}
1597
1598  temp=(((v2->y - v1->y) << 16) / height);
1599  longest = temp * ((v3->x - v1->x)>>16) + (v1->x - v2->x);
1600
1601  if(longest == 0) {return FALSE;}
1602
1603  if(longest < 0)
1604   {
1605    right_array[0] = v3;
1606    right_array[1] = v2;
1607    right_array[2] = v1;
1608    right_section  = 2;
1609    left_array[0]  = v3;
1610    left_array[1]  = v1;
1611    left_section   = 1;
1612
1613    if(LeftSection_GT() <= 0) return FALSE;
1614    if(RightSection_GT() <= 0)
1615     {
1616      right_section--;
1617      if(RightSection_GT() <= 0) return FALSE;
1618     }
1619
1620    if(longest > -0x1000) longest = -0x1000;     
1621   }
1622  else
1623   {
1624    left_array[0]  = v3;
1625    left_array[1]  = v2;
1626    left_array[2]  = v1;
1627    left_section   = 2;
1628    right_array[0] = v3;
1629    right_array[1] = v1;
1630    right_section  = 1;
1631
1632    if(RightSection_GT() <= 0) return FALSE;
1633    if(LeftSection_GT() <= 0)
1634     {    
1635      left_section--;
1636      if(LeftSection_GT() <= 0) return FALSE;
1637     }
1638    if(longest < 0x1000) longest = 0x1000;     
1639   }
1640
1641  Ymin=v1->y;
1642  Ymax=min(v3->y-1,drawH);
1643
1644  delta_right_R=shl10idiv(temp*((v3->R - v1->R)>>10)+((v1->R - v2->R)<<6),longest);
1645  delta_right_G=shl10idiv(temp*((v3->G - v1->G)>>10)+((v1->G - v2->G)<<6),longest);
1646  delta_right_B=shl10idiv(temp*((v3->B - v1->B)>>10)+((v1->B - v2->B)<<6),longest);
1647
1648  delta_right_u=shl10idiv(temp*((v3->u - v1->u)>>10)+((v1->u - v2->u)<<6),longest);
1649  delta_right_v=shl10idiv(temp*((v3->v - v1->v)>>10)+((v1->v - v2->v)<<6),longest);
1650
1651  return TRUE;
1652 }
1653
1654 ////////////////////////////////////////////////////////////////////////
1655 ////////////////////////////////////////////////////////////////////////
1656
1657 static inline int RightSection_F4(void)
1658 {
1659  soft_vertex * v1 = right_array[ right_section ];
1660  soft_vertex * v2 = right_array[ right_section-1 ];
1661
1662  int height = v2->y - v1->y;
1663  right_section_height = height;
1664  right_x = v1->x;
1665  if(height == 0) 
1666   {
1667    return 0;
1668   }
1669  delta_right_x = (v2->x - v1->x) / height;
1670
1671  return height;
1672 }
1673
1674 ////////////////////////////////////////////////////////////////////////
1675
1676 static inline int LeftSection_F4(void)
1677 {
1678  soft_vertex * v1 = left_array[ left_section ];
1679  soft_vertex * v2 = left_array[ left_section-1 ];
1680
1681  int height = v2->y - v1->y;
1682  left_section_height = height;
1683  left_x = v1->x;
1684  if(height == 0) 
1685   {
1686    return 0;
1687   }
1688  delta_left_x = (v2->x - v1->x) / height;
1689
1690  return height;  
1691 }
1692
1693 ////////////////////////////////////////////////////////////////////////
1694
1695 static inline BOOL NextRow_F4(void)
1696 {
1697  if(--left_section_height<=0) 
1698   {
1699    if(--left_section > 0) 
1700     while(LeftSection_F4()<=0) 
1701      {
1702       if(--left_section  <= 0) break;
1703      }
1704   }
1705  else
1706   {
1707    left_x += delta_left_x;
1708   }
1709
1710  if(--right_section_height<=0) 
1711   {
1712    if(--right_section > 0) 
1713     while(RightSection_F4()<=0) 
1714      {
1715       if(--right_section<=0) break;
1716      }
1717   }
1718  else
1719   {
1720    right_x += delta_right_x;
1721   }
1722  return FALSE;
1723 }
1724
1725 ////////////////////////////////////////////////////////////////////////
1726
1727 static inline BOOL SetupSections_F4(short x1, short y1, short x2, short y2, short x3, short y3, short x4, short y4)
1728 {
1729  soft_vertex * v1, * v2, * v3, * v4;
1730  int height,width,longest1,longest2;
1731
1732  v1 = vtx;   v1->x=x1<<16;v1->y=y1;
1733  v2 = vtx+1; v2->x=x2<<16;v2->y=y2;
1734  v3 = vtx+2; v3->x=x3<<16;v3->y=y3;
1735  v4 = vtx+3; v4->x=x4<<16;v4->y=y4;
1736
1737  if(v1->y > v2->y) { soft_vertex * v = v1; v1 = v2; v2 = v; }
1738  if(v1->y > v3->y) { soft_vertex * v = v1; v1 = v3; v3 = v; }
1739  if(v1->y > v4->y) { soft_vertex * v = v1; v1 = v4; v4 = v; }
1740  if(v2->y > v3->y) { soft_vertex * v = v2; v2 = v3; v3 = v; }
1741  if(v2->y > v4->y) { soft_vertex * v = v2; v2 = v4; v4 = v; }
1742  if(v3->y > v4->y) { soft_vertex * v = v3; v3 = v4; v4 = v; }
1743
1744  height = v4->y - v1->y; if(height == 0) height =1;
1745  width  = (v4->x - v1->x)>>16;
1746  longest1 = (((v2->y - v1->y) << 16) / height) * width + (v1->x - v2->x);
1747  longest2 = (((v3->y - v1->y) << 16) / height) * width + (v1->x - v3->x);
1748
1749  if(longest1 < 0)                                      // 2 is right
1750   {
1751    if(longest2 < 0)                                    // 3 is right
1752     {
1753      left_array[0]  = v4;
1754      left_array[1]  = v1;
1755      left_section   = 1;
1756
1757      height = v3->y - v1->y; if(height == 0) height=1;
1758      longest1 = (((v2->y - v1->y) << 16) / height) * ((v3->x - v1->x)>>16) + (v1->x - v2->x);
1759      if(longest1 >= 0)
1760       {
1761        right_array[0] = v4;                     //  1
1762        right_array[1] = v3;                     //     3
1763        right_array[2] = v1;                     //  4
1764        right_section  = 2;    
1765       }
1766      else
1767       {
1768        height = v4->y - v2->y; if(height == 0) height=1;
1769        longest1 = (((v3->y - v2->y) << 16) / height) * ((v4->x - v2->x)>>16) + (v2->x - v3->x);
1770        if(longest1 >= 0)
1771         {
1772          right_array[0] = v4;                    //  1
1773          right_array[1] = v2;                    //     2
1774          right_array[2] = v1;                    //  4
1775          right_section  = 2;    
1776         }
1777        else
1778         {
1779          right_array[0] = v4;                    //  1
1780          right_array[1] = v3;                    //     2
1781          right_array[2] = v2;                    //     3
1782          right_array[3] = v1;                    //  4
1783          right_section  = 3;    
1784         }
1785       }
1786     }
1787    else                                            
1788     {
1789      left_array[0]  = v4;
1790      left_array[1]  = v3;                         //    1
1791      left_array[2]  = v1;                         //      2
1792      left_section   = 2;                          //  3
1793      right_array[0] = v4;                         //    4
1794      right_array[1] = v2;
1795      right_array[2] = v1;
1796      right_section  = 2;
1797     }
1798   }
1799  else
1800   {
1801    if(longest2 < 0)             
1802     {
1803      left_array[0]  = v4;                          //    1
1804      left_array[1]  = v2;                          //  2
1805      left_array[2]  = v1;                          //      3
1806      left_section   = 2;                           //    4
1807      right_array[0] = v4;
1808      right_array[1] = v3;
1809      right_array[2] = v1;
1810      right_section  = 2;
1811     }
1812    else                         
1813     {
1814      right_array[0] = v4;
1815      right_array[1] = v1;
1816      right_section  = 1;
1817
1818      height = v3->y - v1->y; if(height == 0) height=1;
1819      longest1 = (((v2->y - v1->y) << 16) / height) * ((v3->x - v1->x)>>16) + (v1->x - v2->x);
1820      if(longest1<0)
1821       {
1822        left_array[0]  = v4;                        //    1
1823        left_array[1]  = v3;                        //  3
1824        left_array[2]  = v1;                        //    4
1825        left_section   = 2;    
1826       }
1827      else
1828       {
1829        height = v4->y - v2->y; if(height == 0) height=1;
1830        longest1 = (((v3->y - v2->y) << 16) / height) * ((v4->x - v2->x)>>16) + (v2->x - v3->x);
1831        if(longest1<0)
1832         {
1833          left_array[0]  = v4;                      //    1
1834          left_array[1]  = v2;                      //  2
1835          left_array[2]  = v1;                      //    4
1836          left_section   = 2;    
1837         }
1838        else
1839         {
1840          left_array[0]  = v4;                      //    1
1841          left_array[1]  = v3;                      //  2
1842          left_array[2]  = v2;                      //  3
1843          left_array[3]  = v1;                      //     4
1844          left_section   = 3;    
1845         }
1846       }
1847     }
1848   }
1849
1850  while(LeftSection_F4()<=0) 
1851   {
1852    if(--left_section  <= 0) break;
1853   }
1854
1855  while(RightSection_F4()<=0) 
1856   {
1857    if(--right_section <= 0) break;
1858   }
1859
1860  Ymin=v1->y;
1861  Ymax=min(v4->y-1,drawH);
1862
1863  return TRUE;
1864 }
1865
1866 ////////////////////////////////////////////////////////////////////////
1867 ////////////////////////////////////////////////////////////////////////
1868
1869 static inline int RightSection_FT4(void)
1870 {
1871  soft_vertex * v1 = right_array[ right_section ];
1872  soft_vertex * v2 = right_array[ right_section-1 ];
1873
1874  int height = v2->y - v1->y;
1875  right_section_height = height;
1876  right_x = v1->x;
1877  right_u = v1->u;
1878  right_v = v1->v;
1879  if(height == 0) 
1880   {
1881    return 0;
1882   }
1883  delta_right_x = (v2->x - v1->x) / height;
1884  delta_right_u = (v2->u - v1->u) / height;
1885  delta_right_v = (v2->v - v1->v) / height;
1886
1887  return height;
1888 }
1889
1890 ////////////////////////////////////////////////////////////////////////
1891
1892 static inline int LeftSection_FT4(void)
1893 {
1894  soft_vertex * v1 = left_array[ left_section ];
1895  soft_vertex * v2 = left_array[ left_section-1 ];
1896
1897  int height = v2->y - v1->y;
1898  left_section_height = height;
1899  left_x = v1->x;
1900  left_u = v1->u;
1901  left_v = v1->v;
1902  if(height == 0) 
1903   {
1904    return 0;
1905   }
1906  delta_left_x = (v2->x - v1->x) / height;
1907  delta_left_u = (v2->u - v1->u) / height;
1908  delta_left_v = (v2->v - v1->v) / height;
1909
1910  return height;  
1911 }
1912
1913 ////////////////////////////////////////////////////////////////////////
1914
1915 static inline BOOL NextRow_FT4(void)
1916 {
1917  if(--left_section_height<=0) 
1918   {
1919    if(--left_section > 0) 
1920     while(LeftSection_FT4()<=0) 
1921      {
1922       if(--left_section  <= 0) break;
1923      }
1924   }
1925  else
1926   {
1927    left_x += delta_left_x;
1928    left_u += delta_left_u;
1929    left_v += delta_left_v;
1930   }
1931
1932  if(--right_section_height<=0) 
1933   {
1934    if(--right_section > 0) 
1935     while(RightSection_FT4()<=0) 
1936      {
1937       if(--right_section<=0) break;
1938      }
1939   }
1940  else
1941   {
1942    right_x += delta_right_x;
1943    right_u += delta_right_u;
1944    right_v += delta_right_v;
1945   }
1946  return FALSE;
1947 }
1948
1949 ////////////////////////////////////////////////////////////////////////
1950
1951 static inline BOOL SetupSections_FT4(short x1, short y1, short x2, short y2, short x3, short y3, short x4, short y4, short tx1, short ty1, short tx2, short ty2, short tx3, short ty3, short tx4, short ty4)
1952 {
1953  soft_vertex * v1, * v2, * v3, * v4;
1954  int height,width,longest1,longest2;
1955
1956  v1 = vtx;   v1->x=x1<<16;v1->y=y1;
1957  v1->u=tx1<<16;v1->v=ty1<<16;
1958
1959  v2 = vtx+1; v2->x=x2<<16;v2->y=y2;
1960  v2->u=tx2<<16;v2->v=ty2<<16;
1961              
1962  v3 = vtx+2; v3->x=x3<<16;v3->y=y3;
1963  v3->u=tx3<<16;v3->v=ty3<<16;
1964
1965  v4 = vtx+3; v4->x=x4<<16;v4->y=y4;
1966  v4->u=tx4<<16;v4->v=ty4<<16;
1967
1968  if(v1->y > v2->y) { soft_vertex * v = v1; v1 = v2; v2 = v; }
1969  if(v1->y > v3->y) { soft_vertex * v = v1; v1 = v3; v3 = v; }
1970  if(v1->y > v4->y) { soft_vertex * v = v1; v1 = v4; v4 = v; }
1971  if(v2->y > v3->y) { soft_vertex * v = v2; v2 = v3; v3 = v; }
1972  if(v2->y > v4->y) { soft_vertex * v = v2; v2 = v4; v4 = v; }
1973  if(v3->y > v4->y) { soft_vertex * v = v3; v3 = v4; v4 = v; }
1974
1975  height = v4->y - v1->y; if(height == 0) height =1;
1976  width  = (v4->x - v1->x)>>16;
1977  longest1 = (((v2->y - v1->y) << 16) / height) * width + (v1->x - v2->x);
1978  longest2 = (((v3->y - v1->y) << 16) / height) * width + (v1->x - v3->x);
1979
1980  if(longest1 < 0)                                      // 2 is right
1981   {
1982    if(longest2 < 0)                                    // 3 is right
1983     {
1984      left_array[0]  = v4;
1985      left_array[1]  = v1;
1986      left_section   = 1;
1987
1988      height = v3->y - v1->y; if(height == 0) height=1;
1989      longest1 = (((v2->y - v1->y) << 16) / height) * ((v3->x - v1->x)>>16) + (v1->x - v2->x);
1990      if(longest1 >= 0)
1991       {
1992        right_array[0] = v4;                     //  1
1993        right_array[1] = v3;                     //     3
1994        right_array[2] = v1;                     //  4
1995        right_section  = 2;    
1996       }
1997      else
1998       {
1999        height = v4->y - v2->y; if(height == 0) height=1;
2000        longest1 = (((v3->y - v2->y) << 16) / height) * ((v4->x - v2->x)>>16) + (v2->x - v3->x);
2001        if(longest1 >= 0)
2002         {
2003          right_array[0] = v4;                    //  1
2004          right_array[1] = v2;                    //     2
2005          right_array[2] = v1;                    //  4
2006          right_section  = 2;    
2007         }
2008        else
2009         {
2010          right_array[0] = v4;                    //  1
2011          right_array[1] = v3;                    //     2
2012          right_array[2] = v2;                    //     3
2013          right_array[3] = v1;                    //  4
2014          right_section  = 3;    
2015         }
2016       }
2017     }
2018    else                                            
2019     {
2020      left_array[0]  = v4;
2021      left_array[1]  = v3;                         //    1
2022      left_array[2]  = v1;                         //      2
2023      left_section   = 2;                          //  3
2024      right_array[0] = v4;                         //    4
2025      right_array[1] = v2;
2026      right_array[2] = v1;
2027      right_section  = 2;
2028     }
2029   }
2030  else
2031   {
2032    if(longest2 < 0)             
2033     {
2034      left_array[0]  = v4;                          //    1
2035      left_array[1]  = v2;                          //  2
2036      left_array[2]  = v1;                          //      3
2037      left_section   = 2;                           //    4
2038      right_array[0] = v4;
2039      right_array[1] = v3;
2040      right_array[2] = v1;
2041      right_section  = 2;
2042     }
2043    else                         
2044     {
2045      right_array[0] = v4;
2046      right_array[1] = v1;
2047      right_section  = 1;
2048
2049      height = v3->y - v1->y; if(height == 0) height=1;
2050      longest1 = (((v2->y - v1->y) << 16) / height) * ((v3->x - v1->x)>>16) + (v1->x - v2->x);
2051      if(longest1<0)
2052       {
2053        left_array[0]  = v4;                        //    1
2054        left_array[1]  = v3;                        //  3
2055        left_array[2]  = v1;                        //    4
2056        left_section   = 2;    
2057       }
2058      else
2059       {
2060        height = v4->y - v2->y; if(height == 0) height=1;
2061        longest1 = (((v3->y - v2->y) << 16) / height) * ((v4->x - v2->x)>>16) + (v2->x - v3->x);
2062        if(longest1<0)
2063         {
2064          left_array[0]  = v4;                      //    1
2065          left_array[1]  = v2;                      //  2
2066          left_array[2]  = v1;                      //    4
2067          left_section   = 2;    
2068         }
2069        else
2070         {
2071          left_array[0]  = v4;                      //    1
2072          left_array[1]  = v3;                      //  2
2073          left_array[2]  = v2;                      //  3
2074          left_array[3]  = v1;                      //     4
2075          left_section   = 3;    
2076         }
2077       }
2078     }
2079   }
2080
2081  while(LeftSection_FT4()<=0) 
2082   {
2083    if(--left_section  <= 0) break;
2084   }
2085
2086  while(RightSection_FT4()<=0) 
2087   {
2088    if(--right_section <= 0) break;
2089   }
2090
2091  Ymin=v1->y;
2092  Ymax=min(v4->y-1,drawH);
2093
2094  return TRUE;
2095 }
2096
2097 ////////////////////////////////////////////////////////////////////////
2098 ////////////////////////////////////////////////////////////////////////
2099
2100 static inline int RightSection_GT4(void)
2101 {
2102  soft_vertex * v1 = right_array[ right_section ];
2103  soft_vertex * v2 = right_array[ right_section-1 ];
2104
2105  int height = v2->y - v1->y;
2106  right_section_height = height;
2107  right_x = v1->x;
2108  right_u = v1->u;
2109  right_v = v1->v;
2110  right_R = v1->R;
2111  right_G = v1->G;
2112  right_B = v1->B;
2113
2114  if(height == 0) 
2115   {
2116    return 0;
2117   }
2118  delta_right_x = (v2->x - v1->x) / height;
2119  delta_right_u = (v2->u - v1->u) / height;
2120  delta_right_v = (v2->v - v1->v) / height;
2121  delta_right_R = (v2->R - v1->R) / height;
2122  delta_right_G = (v2->G - v1->G) / height;
2123  delta_right_B = (v2->B - v1->B) / height;
2124
2125  return height;
2126 }
2127
2128 ////////////////////////////////////////////////////////////////////////
2129
2130 static inline int LeftSection_GT4(void)
2131 {
2132  soft_vertex * v1 = left_array[ left_section ];
2133  soft_vertex * v2 = left_array[ left_section-1 ];
2134
2135  int height = v2->y - v1->y;
2136  left_section_height = height;
2137  left_x = v1->x;
2138  left_u = v1->u;
2139  left_v = v1->v;
2140  left_R = v1->R;
2141  left_G = v1->G;
2142  left_B = v1->B;
2143
2144  if(height == 0) 
2145   {
2146    return 0;
2147   }
2148  delta_left_x = (v2->x - v1->x) / height;
2149  delta_left_u = (v2->u - v1->u) / height;
2150  delta_left_v = (v2->v - v1->v) / height;
2151  delta_left_R = (v2->R - v1->R) / height;
2152  delta_left_G = (v2->G - v1->G) / height;
2153  delta_left_B = (v2->B - v1->B) / height;
2154
2155  return height;  
2156 }
2157
2158 ////////////////////////////////////////////////////////////////////////
2159
2160 static inline BOOL NextRow_GT4(void)
2161 {
2162  if(--left_section_height<=0) 
2163   {
2164    if(--left_section > 0) 
2165     while(LeftSection_GT4()<=0) 
2166      {
2167       if(--left_section  <= 0) break;
2168      }
2169   }
2170  else
2171   {
2172    left_x += delta_left_x;
2173    left_u += delta_left_u;
2174    left_v += delta_left_v;
2175    left_R += delta_left_R;
2176    left_G += delta_left_G;
2177    left_B += delta_left_B;
2178   }
2179
2180  if(--right_section_height<=0) 
2181   {
2182    if(--right_section > 0) 
2183     while(RightSection_GT4()<=0) 
2184      {
2185       if(--right_section<=0) break;
2186      }
2187   }
2188  else
2189   {
2190    right_x += delta_right_x;
2191    right_u += delta_right_u;
2192    right_v += delta_right_v;
2193    right_R += delta_right_R;
2194    right_G += delta_right_G;
2195    right_B += delta_right_B;
2196   }
2197  return FALSE;
2198 }
2199
2200 ////////////////////////////////////////////////////////////////////////
2201
2202 static inline BOOL SetupSections_GT4(short x1, short y1, short x2, short y2, short x3, short y3, short x4, short y4, short tx1, short ty1, short tx2, short ty2, short tx3, short ty3, short tx4, short ty4,int32_t rgb1,int32_t rgb2,int32_t rgb3,int32_t rgb4)
2203 {
2204  soft_vertex * v1, * v2, * v3, * v4;
2205  int height,width,longest1,longest2;
2206
2207  v1 = vtx;   v1->x=x1<<16;v1->y=y1;
2208  v1->u=tx1<<16;v1->v=ty1<<16;
2209  v1->R=(rgb1) & 0x00ff0000;
2210  v1->G=(rgb1<<8) & 0x00ff0000;
2211  v1->B=(rgb1<<16) & 0x00ff0000;
2212
2213  v2 = vtx+1; v2->x=x2<<16;v2->y=y2;
2214  v2->u=tx2<<16;v2->v=ty2<<16;
2215  v2->R=(rgb2) & 0x00ff0000;
2216  v2->G=(rgb2<<8) & 0x00ff0000;
2217  v2->B=(rgb2<<16) & 0x00ff0000;
2218              
2219  v3 = vtx+2; v3->x=x3<<16;v3->y=y3;
2220  v3->u=tx3<<16;v3->v=ty3<<16;
2221  v3->R=(rgb3) & 0x00ff0000;
2222  v3->G=(rgb3<<8) & 0x00ff0000;
2223  v3->B=(rgb3<<16) & 0x00ff0000;
2224
2225  v4 = vtx+3; v4->x=x4<<16;v4->y=y4;
2226  v4->u=tx4<<16;v4->v=ty4<<16;
2227  v4->R=(rgb4) & 0x00ff0000;
2228  v4->G=(rgb4<<8) & 0x00ff0000;
2229  v4->B=(rgb4<<16) & 0x00ff0000;
2230
2231  if(v1->y > v2->y) { soft_vertex * v = v1; v1 = v2; v2 = v; }
2232  if(v1->y > v3->y) { soft_vertex * v = v1; v1 = v3; v3 = v; }
2233  if(v1->y > v4->y) { soft_vertex * v = v1; v1 = v4; v4 = v; }
2234  if(v2->y > v3->y) { soft_vertex * v = v2; v2 = v3; v3 = v; }
2235  if(v2->y > v4->y) { soft_vertex * v = v2; v2 = v4; v4 = v; }
2236  if(v3->y > v4->y) { soft_vertex * v = v3; v3 = v4; v4 = v; }
2237
2238  height = v4->y - v1->y; if(height == 0) height =1;
2239  width  = (v4->x - v1->x)>>16;
2240  longest1 = (((v2->y - v1->y) << 16) / height) * width + (v1->x - v2->x);
2241  longest2 = (((v3->y - v1->y) << 16) / height) * width + (v1->x - v3->x);
2242
2243  if(longest1 < 0)                                      // 2 is right
2244   {
2245    if(longest2 < 0)                                    // 3 is right
2246     {
2247      left_array[0]  = v4;
2248      left_array[1]  = v1;
2249      left_section   = 1;
2250
2251      height = v3->y - v1->y; if(height == 0) height=1;
2252      longest1 = (((v2->y - v1->y) << 16) / height) * ((v3->x - v1->x)>>16) + (v1->x - v2->x);
2253      if(longest1 >= 0)
2254       {
2255        right_array[0] = v4;                     //  1
2256        right_array[1] = v3;                     //     3
2257        right_array[2] = v1;                     //  4
2258        right_section  = 2;    
2259       }
2260      else
2261       {
2262        height = v4->y - v2->y; if(height == 0) height=1;
2263        longest1 = (((v3->y - v2->y) << 16) / height) * ((v4->x - v2->x)>>16) + (v2->x - v3->x);
2264        if(longest1 >= 0)
2265         {
2266          right_array[0] = v4;                    //  1
2267          right_array[1] = v2;                    //     2
2268          right_array[2] = v1;                    //  4
2269          right_section  = 2;    
2270         }
2271        else
2272         {
2273          right_array[0] = v4;                    //  1
2274          right_array[1] = v3;                    //     2
2275          right_array[2] = v2;                    //     3
2276          right_array[3] = v1;                    //  4
2277          right_section  = 3;    
2278         }
2279       }
2280     }
2281    else                                            
2282     {
2283      left_array[0]  = v4;
2284      left_array[1]  = v3;                         //    1
2285      left_array[2]  = v1;                         //      2
2286      left_section   = 2;                          //  3
2287      right_array[0] = v4;                         //    4
2288      right_array[1] = v2;
2289      right_array[2] = v1;
2290      right_section  = 2;
2291     }
2292   }
2293  else
2294   {
2295    if(longest2 < 0)             
2296     {
2297      left_array[0]  = v4;                          //    1
2298      left_array[1]  = v2;                          //  2
2299      left_array[2]  = v1;                          //      3
2300      left_section   = 2;                           //    4
2301      right_array[0] = v4;
2302      right_array[1] = v3;
2303      right_array[2] = v1;
2304      right_section  = 2;
2305     }
2306    else                         
2307     {
2308      right_array[0] = v4;
2309      right_array[1] = v1;
2310      right_section  = 1;
2311
2312      height = v3->y - v1->y; if(height == 0) height=1;
2313      longest1 = (((v2->y - v1->y) << 16) / height) * ((v3->x - v1->x)>>16) + (v1->x - v2->x);
2314      if(longest1<0)
2315       {
2316        left_array[0]  = v4;                        //    1
2317        left_array[1]  = v3;                        //  3
2318        left_array[2]  = v1;                        //    4
2319        left_section   = 2;    
2320       }
2321      else
2322       {
2323        height = v4->y - v2->y; if(height == 0) height=1;
2324        longest1 = (((v3->y - v2->y) << 16) / height) * ((v4->x - v2->x)>>16) + (v2->x - v3->x);
2325        if(longest1<0)
2326         {
2327          left_array[0]  = v4;                      //    1
2328          left_array[1]  = v2;                      //  2
2329          left_array[2]  = v1;                      //    4
2330          left_section   = 2;    
2331         }
2332        else
2333         {
2334          left_array[0]  = v4;                      //    1
2335          left_array[1]  = v3;                      //  2
2336          left_array[2]  = v2;                      //  3
2337          left_array[3]  = v1;                      //     4
2338          left_section   = 3;    
2339         }
2340       }
2341     }
2342   }
2343
2344  while(LeftSection_GT4()<=0) 
2345   {
2346    if(--left_section  <= 0) break;
2347   }
2348
2349  while(RightSection_GT4()<=0) 
2350   {
2351    if(--right_section <= 0) break;
2352   }
2353
2354  Ymin=v1->y;
2355  Ymax=min(v4->y-1,drawH);
2356
2357  return TRUE;
2358 }
2359
2360 ////////////////////////////////////////////////////////////////////////
2361 ////////////////////////////////////////////////////////////////////////
2362 ////////////////////////////////////////////////////////////////////////
2363 // POLY FUNCS
2364 ////////////////////////////////////////////////////////////////////////
2365 ////////////////////////////////////////////////////////////////////////
2366 ////////////////////////////////////////////////////////////////////////
2367
2368 ////////////////////////////////////////////////////////////////////////
2369 // POLY 3/4 FLAT SHADED
2370 ////////////////////////////////////////////////////////////////////////
2371
2372 static inline void drawPoly3Fi(short x1,short y1,short x2,short y2,short x3,short y3,int32_t rgb)
2373 {
2374  int i,j,xmin,xmax,ymin,ymax;
2375  unsigned short color;uint32_t lcolor;
2376
2377  if(x1>drawW && x2>drawW && x3>drawW) return;
2378  if(y1>drawH && y2>drawH && y3>drawH) return;
2379  if(x1<drawX && x2<drawX && x3<drawX) return;
2380  if(y1<drawY && y2<drawY && y3<drawY) return;
2381  if(drawY>=drawH) return;
2382  if(drawX>=drawW) return; 
2383
2384  if(!SetupSections_F(x1,y1,x2,y2,x3,y3)) return;
2385
2386  ymax=Ymax;
2387
2388  color = ((rgb & 0x00f80000)>>9) | ((rgb & 0x0000f800)>>6) | ((rgb & 0x000000f8)>>3);
2389  lcolor=lSetMask|(((uint32_t)(color))<<16)|color;
2390
2391  for(ymin=Ymin;ymin<drawY;ymin++)
2392   if(NextRow_F()) return;
2393
2394 #ifdef FASTSOLID
2395
2396  if(!bCheckMask && !DrawSemiTrans)
2397   {
2398    color |=sSetMask;
2399    for (i=ymin;i<=ymax;i++)
2400     {
2401      xmin=left_x >> 16;      if(drawX>xmin) xmin=drawX;
2402      xmax=(right_x >> 16)-1; if(drawW<xmax) xmax=drawW;
2403
2404      for(j=xmin;j<xmax;j+=2) 
2405       {
2406        PUTLE32(((uint32_t *)&psxVuw[(i<<10)+j]), lcolor);
2407       }
2408      if(j==xmax) PUTLE16(&psxVuw[(i<<10)+j], color);
2409
2410      if(NextRow_F()) return;
2411     }
2412    return;
2413   }
2414
2415 #endif
2416
2417  for (i=ymin;i<=ymax;i++)
2418   {
2419    xmin=left_x >> 16;      if(drawX>xmin) xmin=drawX;
2420    xmax=(right_x >> 16)-1; if(drawW<xmax) xmax=drawW;
2421
2422    for(j=xmin;j<xmax;j+=2) 
2423     {
2424      GetShadeTransCol32((uint32_t *)&psxVuw[(i<<10)+j],lcolor);
2425     }
2426    if(j==xmax)
2427     GetShadeTransCol(&psxVuw[(i<<10)+j],color);
2428
2429    if(NextRow_F()) return;
2430   }
2431 }
2432
2433 ////////////////////////////////////////////////////////////////////////
2434
2435 static void drawPoly3F(int32_t rgb)
2436 {
2437  drawPoly3Fi(lx0,ly0,lx1,ly1,lx2,ly2,rgb);
2438 }
2439
2440 #ifdef POLYQUAD3FS
2441
2442 static void drawPoly4F_TRI(int32_t rgb)
2443 {
2444  drawPoly3Fi(lx1,ly1,lx3,ly3,lx2,ly2,rgb);
2445  drawPoly3Fi(lx0,ly0,lx1,ly1,lx2,ly2,rgb);
2446 }
2447
2448 #endif
2449
2450 // more exact:
2451
2452 static void drawPoly4F(int32_t rgb)
2453 {
2454  int i,j,xmin,xmax,ymin,ymax;
2455  unsigned short color;uint32_t lcolor;
2456  
2457  if(lx0>drawW && lx1>drawW && lx2>drawW && lx3>drawW) return;
2458  if(ly0>drawH && ly1>drawH && ly2>drawH && ly3>drawH) return;
2459  if(lx0<drawX && lx1<drawX && lx2<drawX && lx3<drawX) return;
2460  if(ly0<drawY && ly1<drawY && ly2<drawY && ly3<drawY) return;
2461  if(drawY>=drawH) return;
2462  if(drawX>=drawW) return; 
2463
2464  if(!SetupSections_F4(lx0,ly0,lx1,ly1,lx2,ly2,lx3,ly3)) return;
2465
2466  ymax=Ymax;
2467
2468  for(ymin=Ymin;ymin<drawY;ymin++)
2469   if(NextRow_F4()) return;
2470
2471  color = ((rgb & 0x00f80000)>>9) | ((rgb & 0x0000f800)>>6) | ((rgb & 0x000000f8)>>3);
2472  lcolor= lSetMask|(((uint32_t)(color))<<16)|color;
2473
2474 #ifdef FASTSOLID
2475
2476  if(!bCheckMask && !DrawSemiTrans)
2477   {
2478    color |=sSetMask;
2479    for (i=ymin;i<=ymax;i++)
2480     {
2481      xmin=left_x >> 16;      if(drawX>xmin) xmin=drawX;
2482      xmax=(right_x >> 16)-1; if(drawW<xmax) xmax=drawW;
2483
2484      for(j=xmin;j<xmax;j+=2) 
2485       {
2486        PUTLE32(((uint32_t *)&psxVuw[(i<<10)+j]), lcolor);
2487       }
2488      if(j==xmax) PUTLE16(&psxVuw[(i<<10)+j], color);
2489
2490      if(NextRow_F4()) return;
2491     }
2492    return;
2493   }                                                        
2494
2495 #endif
2496
2497  for (i=ymin;i<=ymax;i++)
2498   {
2499    xmin=left_x >> 16;      if(drawX>xmin) xmin=drawX;
2500    xmax=(right_x >> 16)-1; if(drawW<xmax) xmax=drawW;
2501
2502    for(j=xmin;j<xmax;j+=2) 
2503     {
2504      GetShadeTransCol32((uint32_t *)&psxVuw[(i<<10)+j],lcolor);
2505     }
2506    if(j==xmax) GetShadeTransCol(&psxVuw[(i<<10)+j],color);
2507
2508    if(NextRow_F4()) return;
2509   }
2510 }
2511
2512 ////////////////////////////////////////////////////////////////////////
2513 // POLY 3/4 F-SHADED TEX PAL 4
2514 ////////////////////////////////////////////////////////////////////////
2515
2516 static void drawPoly3TEx4(short x1, short y1, short x2, short y2, short x3, short y3, short tx1, short ty1, short tx2, short ty2, short tx3, short ty3,short clX, short clY)
2517 {
2518  int i,j,xmin,xmax,ymin,ymax;
2519  int32_t difX, difY,difX2, difY2;
2520  int32_t posX,posY,YAdjust,XAdjust;
2521  int32_t clutP;
2522  short tC1,tC2;
2523  
2524  if(x1>drawW && x2>drawW && x3>drawW) return;
2525  if(y1>drawH && y2>drawH && y3>drawH) return;
2526  if(x1<drawX && x2<drawX && x3<drawX) return;
2527  if(y1<drawY && y2<drawY && y3<drawY) return;
2528  if(drawY>=drawH) return;
2529  if(drawX>=drawW) return; 
2530
2531  if(!SetupSections_FT(x1,y1,x2,y2,x3,y3,tx1,ty1,tx2,ty2,tx3,ty3)) return;
2532
2533  ymax=Ymax;
2534
2535  for(ymin=Ymin;ymin<drawY;ymin++)
2536   if(NextRow_FT()) return;
2537
2538  clutP=(clY<<10)+clX;
2539
2540  YAdjust=((GlobalTextAddrY)<<11)+(GlobalTextAddrX<<1);
2541
2542  difX=delta_right_u;difX2=difX<<1;
2543  difY=delta_right_v;difY2=difY<<1;
2544
2545 #ifdef FASTSOLID
2546
2547  if(!bCheckMask && !DrawSemiTrans)
2548   {
2549    for (i=ymin;i<=ymax;i++)
2550     {
2551      xmin=(left_x >> 16);
2552      xmax=(right_x >> 16)-1; //!!!!!!!!!!!!!!!!
2553      if(drawW<xmax) xmax=drawW;
2554
2555      if(xmax>=xmin)
2556       {
2557        posX=left_u;
2558        posY=left_v;
2559
2560        if(xmin<drawX)
2561         {j=drawX-xmin;xmin=drawX;posX+=j*difX;posY+=j*difY;}
2562
2563        for(j=xmin;j<xmax;j+=2)
2564         {
2565          XAdjust=(posX>>16);
2566          tC1 = psxVub[((posY>>5)&(int32_t)0xFFFFF800)+YAdjust+(XAdjust>>1)];
2567          tC1=(tC1>>((XAdjust&1)<<2))&0xf;
2568          XAdjust=((posX+difX)>>16);
2569          tC2 = psxVub[(((posY+difY)>>5)&(int32_t)0xFFFFF800)+YAdjust+
2570                     (XAdjust>>1)];
2571          tC2=(tC2>>((XAdjust&1)<<2))&0xf;
2572
2573          GetTextureTransColG32_S((uint32_t *)&psxVuw[(i<<10)+j],
2574              GETLE16(&psxVuw[clutP+tC1])|
2575              ((int32_t)GETLE16(&psxVuw[clutP+tC2]))<<16);
2576
2577          posX+=difX2;
2578          posY+=difY2;
2579         }
2580        if(j==xmax)
2581         {
2582          XAdjust=(posX>>16);
2583          tC1 = psxVub[((posY>>5)&(int32_t)0xFFFFF800)+YAdjust+
2584                       (XAdjust>>1)];
2585          tC1=(tC1>>((XAdjust&1)<<2))&0xf;
2586          GetTextureTransColG_S(&psxVuw[(i<<10)+j],GETLE16(&psxVuw[clutP+tC1]));
2587         }
2588       }
2589      if(NextRow_FT()) 
2590       {
2591        return;
2592       }
2593     }
2594    return;
2595   }
2596
2597 #endif
2598
2599  for (i=ymin;i<=ymax;i++)
2600   {
2601    xmin=(left_x >> 16);
2602    xmax=(right_x >> 16)-1; //!!!!!!!!!!!!!!!!!!
2603    if(drawW<xmax) xmax=drawW;
2604
2605    if(xmax>=xmin)
2606     {
2607      posX=left_u;
2608      posY=left_v;
2609
2610      if(xmin<drawX)
2611       {j=drawX-xmin;xmin=drawX;posX+=j*difX;posY+=j*difY;}
2612
2613      for(j=xmin;j<xmax;j+=2)
2614       {
2615        XAdjust=(posX>>16);
2616        tC1 = psxVub[((posY>>5)&(int32_t)0xFFFFF800)+YAdjust+(XAdjust>>1)];
2617        tC1=(tC1>>((XAdjust&1)<<2))&0xf;
2618        XAdjust=((posX+difX)>>16);
2619        tC2 = psxVub[(((posY+difY)>>5)&(int32_t)0xFFFFF800)+YAdjust+
2620                     (XAdjust>>1)];
2621        tC2=(tC2>>((XAdjust&1)<<2))&0xf;
2622
2623        GetTextureTransColG32((uint32_t *)&psxVuw[(i<<10)+j],
2624            GETLE16(&psxVuw[clutP+tC1])|
2625            ((int32_t)GETLE16(&psxVuw[clutP+tC2]))<<16);
2626
2627        posX+=difX2;
2628        posY+=difY2;
2629       }
2630      if(j==xmax)
2631       {
2632        XAdjust=(posX>>16);
2633        tC1 = psxVub[((posY>>5)&(int32_t)0xFFFFF800)+YAdjust+
2634                     (XAdjust>>1)];
2635        tC1=(tC1>>((XAdjust&1)<<2))&0xf;
2636        GetTextureTransColG(&psxVuw[(i<<10)+j],GETLE16(&psxVuw[clutP+tC1]));
2637       }
2638     }
2639    if(NextRow_FT()) 
2640     {
2641      return;
2642     }
2643   }
2644 }
2645
2646 ////////////////////////////////////////////////////////////////////////
2647
2648 static void drawPoly3TEx4_IL(short x1, short y1, short x2, short y2, short x3, short y3, short tx1, short ty1, short tx2, short ty2, short tx3, short ty3,short clX, short clY)
2649 {
2650  int i,j,xmin,xmax,ymin,ymax,n_xi,n_yi,TXV;
2651  int32_t difX, difY,difX2, difY2;
2652  int32_t posX,posY,YAdjust,XAdjust;
2653  int32_t clutP;
2654  short tC1,tC2;
2655  
2656  if(x1>drawW && x2>drawW && x3>drawW) return;
2657  if(y1>drawH && y2>drawH && y3>drawH) return;
2658  if(x1<drawX && x2<drawX && x3<drawX) return;
2659  if(y1<drawY && y2<drawY && y3<drawY) return;
2660  if(drawY>=drawH) return;
2661  if(drawX>=drawW) return; 
2662
2663  if(!SetupSections_FT(x1,y1,x2,y2,x3,y3,tx1,ty1,tx2,ty2,tx3,ty3)) return;
2664
2665  ymax=Ymax;
2666
2667  for(ymin=Ymin;ymin<drawY;ymin++)
2668   if(NextRow_FT()) return;
2669
2670  clutP=(clY<<10)+clX;
2671
2672  YAdjust=(GlobalTextAddrY<<10)+GlobalTextAddrX;
2673
2674  difX=delta_right_u;difX2=difX<<1;
2675  difY=delta_right_v;difY2=difY<<1;
2676
2677 #ifdef FASTSOLID
2678
2679  if(!bCheckMask && !DrawSemiTrans)
2680   {
2681    for (i=ymin;i<=ymax;i++)
2682     {
2683      xmin=(left_x >> 16);
2684      xmax=(right_x >> 16)-1;
2685      if(drawW<xmax) xmax=drawW;
2686
2687      if(xmax>=xmin)
2688       {
2689        posX=left_u;
2690        posY=left_v;
2691
2692        if(xmin<drawX)
2693         {j=drawX-xmin;xmin=drawX;posX+=j*difX;posY+=j*difY;}
2694
2695        for(j=xmin;j<xmax;j+=2)
2696         {
2697          XAdjust=(posX>>16);
2698
2699          TXV=posY>>16;
2700          n_xi = ( ( XAdjust >> 2 ) & ~0x3c ) + ( ( TXV << 2 ) & 0x3c );
2701          n_yi = ( TXV & ~0xf ) + ( ( XAdjust >> 4 ) & 0xf );
2702
2703          tC1= (GETLE16(&psxVuw[(n_yi<<10)+YAdjust+n_xi]) >> ((XAdjust & 0x03)<<2)) & 0x0f ;
2704
2705          XAdjust=((posX+difX)>>16);
2706
2707          TXV=(posY+difY)>>16;
2708          n_xi = ( ( XAdjust >> 2 ) & ~0x3c ) + ( ( TXV << 2 ) & 0x3c );
2709          n_yi = ( TXV & ~0xf ) + ( ( XAdjust >> 4 ) & 0xf );
2710
2711          tC2= (GETLE16(&psxVuw[(n_yi<<10)+YAdjust+n_xi]) >> ((XAdjust & 0x03)<<2)) & 0x0f ;
2712
2713          GetTextureTransColG32_S((uint32_t *)&psxVuw[(i<<10)+j],
2714              GETLE16(&psxVuw[clutP+tC1])|
2715              ((int32_t)GETLE16(&psxVuw[clutP+tC2]))<<16);
2716
2717          posX+=difX2;
2718          posY+=difY2;
2719         }
2720        if(j==xmax)
2721         {
2722          XAdjust=(posX>>16);
2723
2724          TXV=posY>>16;
2725          n_xi = ( ( XAdjust >> 2 ) & ~0x3c ) + ( ( TXV << 2 ) & 0x3c );
2726          n_yi = ( TXV & ~0xf ) + ( ( XAdjust >> 4 ) & 0xf );
2727
2728          tC1= (GETLE16(&psxVuw[(n_yi<<10)+YAdjust+n_xi]) >> ((XAdjust & 0x03)<<2)) & 0x0f ;
2729
2730          GetTextureTransColG_S(&psxVuw[(i<<10)+j],GETLE16(&psxVuw[clutP+tC1]));
2731         }
2732       }
2733      if(NextRow_FT()) 
2734       {
2735        return;
2736       }
2737     }
2738    return;
2739   }
2740
2741 #endif
2742
2743  for (i=ymin;i<=ymax;i++)
2744   {
2745    xmin=(left_x >> 16);
2746    xmax=(right_x >> 16)-1; //!!!!!!!!!!!!!!!!!!
2747    if(drawW<xmax) xmax=drawW;
2748
2749    if(xmax>=xmin)
2750     {
2751      posX=left_u;
2752      posY=left_v;
2753
2754      if(xmin<drawX)
2755       {j=drawX-xmin;xmin=drawX;posX+=j*difX;posY+=j*difY;}
2756
2757      for(j=xmin;j<xmax;j+=2)
2758       {
2759        XAdjust=(posX>>16);
2760
2761        TXV=posY>>16;
2762        n_xi = ( ( XAdjust >> 2 ) & ~0x3c ) + ( ( TXV << 2 ) & 0x3c );
2763        n_yi = ( TXV & ~0xf ) + ( ( XAdjust >> 4 ) & 0xf );
2764
2765        tC1= (GETLE16(&psxVuw[(n_yi<<10)+YAdjust+n_xi]) >> ((XAdjust & 0x03)<<2)) & 0x0f ;
2766
2767        XAdjust=((posX+difX)>>16);
2768
2769        TXV=(posY+difY)>>16;
2770        n_xi = ( ( XAdjust >> 2 ) & ~0x3c ) + ( ( TXV << 2 ) & 0x3c );
2771        n_yi = ( TXV & ~0xf ) + ( ( XAdjust >> 4 ) & 0xf );
2772
2773        tC2= (GETLE16(&psxVuw[(n_yi<<10)+YAdjust+n_xi]) >> ((XAdjust & 0x03)<<2)) & 0x0f ;
2774
2775        GetTextureTransColG32((uint32_t *)&psxVuw[(i<<10)+j],
2776            GETLE16(&psxVuw[clutP+tC1])|
2777            ((int32_t)GETLE16(&psxVuw[clutP+tC2]))<<16);
2778
2779        posX+=difX2;
2780        posY+=difY2;
2781       }
2782      if(j==xmax)
2783       {
2784        XAdjust=(posX>>16);
2785
2786        TXV=posY>>16;
2787        n_xi = ( ( XAdjust >> 2 ) & ~0x3c ) + ( ( TXV << 2 ) & 0x3c );
2788        n_yi = ( TXV & ~0xf ) + ( ( XAdjust >> 4 ) & 0xf );
2789
2790        tC1= (GETLE16(&psxVuw[(n_yi<<10)+YAdjust+n_xi]) >> ((XAdjust & 0x03)<<2)) & 0x0f ;
2791
2792        GetTextureTransColG(&psxVuw[(i<<10)+j],GETLE16(&psxVuw[clutP+tC1]));
2793       }
2794     }
2795    if(NextRow_FT()) 
2796     {
2797      return;
2798     }
2799   }
2800 }
2801
2802 ////////////////////////////////////////////////////////////////////////
2803
2804 static void drawPoly3TEx4_TW(short x1, short y1, short x2, short y2, short x3, short y3, short tx1, short ty1, short tx2, short ty2, short tx3, short ty3,short clX, short clY)
2805 {
2806  int i,j,xmin,xmax,ymin,ymax;
2807  int32_t difX, difY,difX2, difY2;
2808  int32_t posX,posY,YAdjust,XAdjust;
2809  int32_t clutP;
2810  short tC1,tC2;
2811  
2812  if(x1>drawW && x2>drawW && x3>drawW) return;
2813  if(y1>drawH && y2>drawH && y3>drawH) return;
2814  if(x1<drawX && x2<drawX && x3<drawX) return;
2815  if(y1<drawY && y2<drawY && y3<drawY) return;
2816  if(drawY>=drawH) return;
2817  if(drawX>=drawW) return; 
2818
2819  if(!SetupSections_FT(x1,y1,x2,y2,x3,y3,tx1,ty1,tx2,ty2,tx3,ty3)) return;
2820
2821  ymax=Ymax;
2822
2823  for(ymin=Ymin;ymin<drawY;ymin++)
2824   if(NextRow_FT()) return;
2825
2826  clutP=(clY<<10)+clX;
2827
2828  YAdjust=((GlobalTextAddrY)<<11)+(GlobalTextAddrX<<1);
2829  YAdjust+=(TWin.Position.y0<<11)+(TWin.Position.x0>>1);
2830
2831  difX=delta_right_u;difX2=difX<<1;
2832  difY=delta_right_v;difY2=difY<<1;
2833
2834 #ifdef FASTSOLID
2835
2836  if(!bCheckMask && !DrawSemiTrans)
2837   {
2838    for (i=ymin;i<=ymax;i++)
2839     {
2840      xmin=(left_x >> 16);
2841      xmax=(right_x >> 16);//-1; //!!!!!!!!!!!!!!!!
2842      if(xmax>xmin) xmax--;
2843
2844      if(drawW<xmax) xmax=drawW;
2845
2846      if(xmax>=xmin)
2847       {
2848        posX=left_u;
2849        posY=left_v;
2850
2851        if(xmin<drawX)
2852         {j=drawX-xmin;xmin=drawX;posX+=j*difX;posY+=j*difY;}
2853
2854        for(j=xmin;j<xmax;j+=2)
2855         {
2856          XAdjust=(posX>>16)%TWin.Position.x1;
2857          tC1 = psxVub[(((posY>>16)%TWin.Position.y1)<<11)+
2858                       YAdjust+(XAdjust>>1)];
2859          tC1=(tC1>>((XAdjust&1)<<2))&0xf;
2860          XAdjust=((posX+difX)>>16)%TWin.Position.x1;
2861          tC2 = psxVub[((((posY+difY)>>16)%TWin.Position.y1)<<11)+
2862                       YAdjust+(XAdjust>>1)];
2863          tC2=(tC2>>((XAdjust&1)<<2))&0xf;
2864
2865          GetTextureTransColG32_S((uint32_t *)&psxVuw[(i<<10)+j],
2866              GETLE16(&psxVuw[clutP+tC1])|
2867              ((int32_t)GETLE16(&psxVuw[clutP+tC2]))<<16);
2868
2869          posX+=difX2;
2870          posY+=difY2;
2871         }
2872        if(j==xmax)
2873         {
2874          XAdjust=(posX>>16)%TWin.Position.x1;
2875          tC1 = psxVub[(((posY>>16)%TWin.Position.y1)<<11)+
2876                       YAdjust+(XAdjust>>1)];
2877          tC1=(tC1>>((XAdjust&1)<<2))&0xf;
2878          GetTextureTransColG_S(&psxVuw[(i<<10)+j],GETLE16(&psxVuw[clutP+tC1]));
2879         }
2880       }
2881      if(NextRow_FT()) 
2882       {
2883        return;
2884       }
2885     }
2886    return;
2887   }
2888
2889 #endif
2890
2891  for (i=ymin;i<=ymax;i++)
2892   {
2893    xmin=(left_x >> 16);
2894    xmax=(right_x >> 16)-1; //!!!!!!!!!!!!!!!!!!
2895    if(drawW<xmax) xmax=drawW;
2896
2897    if(xmax>=xmin)
2898     {
2899      posX=left_u;
2900      posY=left_v;
2901
2902      if(xmin<drawX)
2903       {j=drawX-xmin;xmin=drawX;posX+=j*difX;posY+=j*difY;}
2904
2905      for(j=xmin;j<xmax;j+=2)
2906       {
2907        XAdjust=(posX>>16)%TWin.Position.x1;
2908        tC1 = psxVub[(((posY>>16)%TWin.Position.y1)<<11)+
2909                     YAdjust+(XAdjust>>1)];
2910        tC1=(tC1>>((XAdjust&1)<<2))&0xf;
2911        XAdjust=((posX+difX)>>16)%TWin.Position.x1;
2912        tC2 = psxVub[((((posY+difY)>>16)%TWin.Position.y1)<<11)+
2913                     YAdjust+(XAdjust>>1)];
2914        tC2=(tC2>>((XAdjust&1)<<2))&0xf;
2915
2916        GetTextureTransColG32((uint32_t *)&psxVuw[(i<<10)+j],
2917            GETLE16(&psxVuw[clutP+tC1])|
2918            ((int32_t)GETLE16(&psxVuw[clutP+tC2]))<<16);
2919
2920        posX+=difX2;
2921        posY+=difY2;
2922       }
2923      if(j==xmax)
2924       {
2925        XAdjust=(posX>>16)%TWin.Position.x1;
2926        tC1 = psxVub[(((posY>>16)%TWin.Position.y1)<<11)+
2927                     YAdjust+(XAdjust>>1)];
2928        tC1=(tC1>>((XAdjust&1)<<2))&0xf;
2929        GetTextureTransColG(&psxVuw[(i<<10)+j],GETLE16(&psxVuw[clutP+tC1]));
2930       }
2931     }
2932    if(NextRow_FT()) 
2933     {
2934      return;
2935     }
2936   }
2937 }
2938
2939 ////////////////////////////////////////////////////////////////////////
2940
2941 #ifdef POLYQUAD3
2942
2943 static void drawPoly4TEx4_TRI(short x1, short y1, short x2, short y2, short x3, short y3, short x4, short y4, short tx1, short ty1, short tx2, short ty2, short tx3, short ty3, short tx4, short ty4,short clX, short clY)
2944 {
2945  drawPoly3TEx4(x2,y2,x3,y3,x4,y4,
2946                tx2,ty2,tx3,ty3,tx4,ty4,
2947                clX,clY);
2948  drawPoly3TEx4(x1,y1,x2,y2,x4,y4,
2949                tx1,ty1,tx2,ty2,tx4,ty4,
2950                clX,clY);
2951 }
2952
2953 #endif
2954
2955 // more exact:
2956
2957 static void drawPoly4TEx4(short x1, short y1, short x2, short y2, short x3, short y3, short x4, short y4, short tx1, short ty1, short tx2, short ty2, short tx3, short ty3, short tx4, short ty4,short clX, short clY)
2958 {
2959  int32_t num; 
2960  int32_t i,j,xmin,xmax,ymin,ymax;
2961  int32_t difX, difY, difX2, difY2;
2962  int32_t posX,posY,YAdjust,clutP,XAdjust;
2963  short tC1,tC2;
2964
2965  if(x1>drawW && x2>drawW && x3>drawW && x4>drawW) return;
2966  if(y1>drawH && y2>drawH && y3>drawH && y4>drawH) return;
2967  if(x1<drawX && x2<drawX && x3<drawX && x4<drawX) return;
2968  if(y1<drawY && y2<drawY && y3<drawY && y4<drawY) return;
2969  if(drawY>=drawH) return;
2970  if(drawX>=drawW) return; 
2971
2972  if(!SetupSections_FT4(x1,y1,x2,y2,x3,y3,x4,y4,tx1,ty1,tx2,ty2,tx3,ty3,tx4,ty4)) return;
2973
2974  ymax=Ymax;
2975
2976  for(ymin=Ymin;ymin<drawY;ymin++)
2977   if(NextRow_FT4()) return;
2978
2979  clutP=(clY<<10)+clX;
2980
2981  YAdjust=((GlobalTextAddrY)<<11)+(GlobalTextAddrX<<1);
2982
2983 #ifdef FASTSOLID
2984
2985  if(!bCheckMask && !DrawSemiTrans)
2986   {
2987    for (i=ymin;i<=ymax;i++)
2988     {
2989      xmin=(left_x >> 16);
2990      xmax=(right_x >> 16);
2991
2992      if(xmax>=xmin)
2993       {
2994        posX=left_u;
2995        posY=left_v;
2996
2997        num=(xmax-xmin);
2998        if(num==0) num=1;
2999        difX=(right_u-posX)/num;
3000        difY=(right_v-posY)/num;
3001        difX2=difX<<1;
3002        difY2=difY<<1;
3003
3004        if(xmin<drawX)
3005         {j=drawX-xmin;xmin=drawX;posX+=j*difX;posY+=j*difY;}
3006        xmax--;if(drawW<xmax) xmax=drawW;
3007
3008        for(j=xmin;j<xmax;j+=2)
3009         {
3010          XAdjust=(posX>>16);
3011          tC1 = psxVub[((posY>>5)&(int32_t)0xFFFFF800)+YAdjust+(XAdjust>>1)];
3012          tC1=(tC1>>((XAdjust&1)<<2))&0xf;
3013          XAdjust=((posX+difX)>>16);
3014          tC2 = psxVub[(((posY+difY)>>5)&(int32_t)0xFFFFF800)+YAdjust+
3015                        (XAdjust>>1)];
3016          tC2=(tC2>>((XAdjust&1)<<2))&0xf;
3017
3018          GetTextureTransColG32_S((uint32_t *)&psxVuw[(i<<10)+j],
3019               GETLE16(&psxVuw[clutP+tC1])|
3020               ((int32_t)GETLE16(&psxVuw[clutP+tC2]))<<16);
3021          posX+=difX2;
3022          posY+=difY2;
3023         }
3024        if(j==xmax)
3025         {
3026          XAdjust=(posX>>16);
3027          tC1 = psxVub[((posY>>5)&(int32_t)0xFFFFF800)+YAdjust+
3028                       (XAdjust>>1)];
3029          tC1=(tC1>>((XAdjust&1)<<2))&0xf;
3030          GetTextureTransColG_S(&psxVuw[(i<<10)+j],GETLE16(&psxVuw[clutP+tC1]));
3031         }
3032
3033       }
3034      if(NextRow_FT4()) return;
3035     }
3036    return;
3037   }
3038
3039 #endif
3040
3041  for (i=ymin;i<=ymax;i++)
3042   {
3043    xmin=(left_x >> 16);
3044    xmax=(right_x >> 16);
3045
3046    if(xmax>=xmin)
3047     {
3048      posX=left_u;
3049      posY=left_v;
3050
3051      num=(xmax-xmin);
3052      if(num==0) num=1;
3053      difX=(right_u-posX)/num;
3054      difY=(right_v-posY)/num;
3055      difX2=difX<<1;
3056      difY2=difY<<1;
3057
3058      if(xmin<drawX)
3059       {j=drawX-xmin;xmin=drawX;posX+=j*difX;posY+=j*difY;}
3060      xmax--;if(drawW<xmax) xmax=drawW;
3061
3062      for(j=xmin;j<xmax;j+=2)
3063       {
3064        XAdjust=(posX>>16);
3065        tC1 = psxVub[((posY>>5)&(int32_t)0xFFFFF800)+YAdjust+(XAdjust>>1)];
3066        tC1=(tC1>>((XAdjust&1)<<2))&0xf;
3067        XAdjust=((posX+difX)>>16);
3068        tC2 = psxVub[(((posY+difY)>>5)&(int32_t)0xFFFFF800)+YAdjust+
3069                      (XAdjust>>1)];
3070        tC2=(tC2>>((XAdjust&1)<<2))&0xf;
3071
3072        GetTextureTransColG32((uint32_t *)&psxVuw[(i<<10)+j],
3073             GETLE16(&psxVuw[clutP+tC1])|
3074             ((int32_t)GETLE16(&psxVuw[clutP+tC2]))<<16);
3075        posX+=difX2;
3076        posY+=difY2;
3077       }
3078      if(j==xmax)
3079       {
3080        XAdjust=(posX>>16);
3081        tC1 = psxVub[((posY>>5)&(int32_t)0xFFFFF800)+YAdjust+
3082                     (XAdjust>>1)];
3083        tC1=(tC1>>((XAdjust&1)<<2))&0xf;
3084        GetTextureTransColG(&psxVuw[(i<<10)+j],GETLE16(&psxVuw[clutP+tC1]));
3085       }
3086     }
3087    if(NextRow_FT4()) return;
3088   }
3089 }
3090
3091 ////////////////////////////////////////////////////////////////////////
3092
3093 static void drawPoly4TEx4_IL(short x1, short y1, short x2, short y2, short x3, short y3, short x4, short y4, short tx1, short ty1, short tx2, short ty2, short tx3, short ty3, short tx4, short ty4,short clX, short clY)
3094 {
3095  int32_t num; 
3096  int32_t i,j=0,xmin,xmax,ymin,ymax,n_xi,n_yi,TXV;
3097  int32_t difX, difY, difX2, difY2;
3098  int32_t posX=0,posY=0,YAdjust,clutP,XAdjust;
3099  short tC1,tC2;
3100
3101  if(x1>drawW && x2>drawW && x3>drawW && x4>drawW) return;
3102  if(y1>drawH && y2>drawH && y3>drawH && y4>drawH) return;
3103  if(x1<drawX && x2<drawX && x3<drawX && x4<drawX) return;
3104  if(y1<drawY && y2<drawY && y3<drawY && y4<drawY) return;
3105  if(drawY>=drawH) return;
3106  if(drawX>=drawW) return; 
3107
3108  if(!SetupSections_FT4(x1,y1,x2,y2,x3,y3,x4,y4,tx1,ty1,tx2,ty2,tx3,ty3,tx4,ty4)) return;
3109
3110  ymax=Ymax;
3111
3112  for(ymin=Ymin;ymin<drawY;ymin++)
3113   if(NextRow_FT4()) return;
3114
3115  clutP=(clY<<10)+clX;
3116
3117  YAdjust=((GlobalTextAddrY)<<10)+GlobalTextAddrX;
3118
3119 #ifdef FASTSOLID
3120
3121  if(!bCheckMask && !DrawSemiTrans)
3122   {
3123    for (i=ymin;i<=ymax;i++)
3124     {
3125      xmin=(left_x >> 16);
3126      xmax=(right_x >> 16);
3127
3128      if(xmax>=xmin)
3129       {
3130        posX=left_u;
3131        posY=left_v;
3132
3133        num=(xmax-xmin);
3134        if(num==0) num=1;
3135        difX=(right_u-posX)/num;
3136        difY=(right_v-posY)/num;
3137        difX2=difX<<1;
3138        difY2=difY<<1;
3139
3140        if(xmin<drawX)
3141         {j=drawX-xmin;xmin=drawX;posX+=j*difX;posY+=j*difY;}
3142        xmax--;if(drawW<xmax) xmax=drawW;
3143
3144        for(j=xmin;j<xmax;j+=2)
3145         {
3146          XAdjust=(posX>>16);
3147
3148          TXV=posY>>16;
3149          n_xi = ( ( XAdjust >> 2 ) & ~0x3c ) + ( ( TXV << 2 ) & 0x3c );
3150          n_yi = ( TXV & ~0xf ) + ( ( XAdjust >> 4 ) & 0xf );
3151
3152          tC1= (GETLE16(&psxVuw[(n_yi<<10)+YAdjust+n_xi]) >> ((XAdjust & 0x03)<<2)) & 0x0f ;
3153
3154          XAdjust=((posX+difX)>>16);
3155
3156          TXV=(posY+difY)>>16;
3157          n_xi = ( ( XAdjust >> 2 ) & ~0x3c ) + ( ( TXV << 2 ) & 0x3c );
3158          n_yi = ( TXV & ~0xf ) + ( ( XAdjust >> 4 ) & 0xf );
3159
3160          tC2= (GETLE16(&psxVuw[(n_yi<<10)+YAdjust+n_xi]) >> ((XAdjust & 0x03)<<2)) & 0x0f ;
3161
3162          GetTextureTransColG32_S((uint32_t *)&psxVuw[(i<<10)+j],
3163               GETLE16(&psxVuw[clutP+tC1])|
3164               ((int32_t)GETLE16(&psxVuw[clutP+tC2]))<<16);
3165          posX+=difX2;
3166          posY+=difY2;
3167         }
3168          posX+=difX2;
3169          posY+=difY2;
3170         }
3171
3172        if(j==xmax)
3173         {
3174          XAdjust=(posX>>16);
3175          TXV=posY>>16;
3176          n_xi = ( ( XAdjust >> 2 ) & ~0x3c ) + ( ( TXV << 2 ) & 0x3c );
3177          n_yi = ( TXV & ~0xf ) + ( ( XAdjust >> 4 ) & 0xf );
3178
3179          tC1= (GETLE16(&psxVuw[(n_yi<<10)+YAdjust+n_xi]) >> ((XAdjust & 0x03)<<2)) & 0x0f ;
3180
3181          GetTextureTransColG_S(&psxVuw[(i<<10)+j],GETLE16(&psxVuw[clutP+tC1]));
3182         }
3183
3184       }
3185      if(NextRow_FT4()) return;
3186     }
3187 #endif
3188
3189  for (i=ymin;i<=ymax;i++)
3190   {
3191    xmin=(left_x >> 16);
3192    xmax=(right_x >> 16);
3193
3194    if(xmax>=xmin)
3195     {
3196      posX=left_u;
3197      posY=left_v;
3198
3199      num=(xmax-xmin);
3200      if(num==0) num=1;
3201      difX=(right_u-posX)/num;
3202      difY=(right_v-posY)/num;
3203      difX2=difX<<1;
3204      difY2=difY<<1;
3205
3206      if(xmin<drawX)
3207       {j=drawX-xmin;xmin=drawX;posX+=j*difX;posY+=j*difY;}
3208      xmax--;if(drawW<xmax) xmax=drawW;
3209
3210      for(j=xmin;j<xmax;j+=2)
3211       {
3212        XAdjust=(posX>>16);
3213
3214        TXV=posY>>16;
3215        n_xi = ( ( XAdjust >> 2 ) & ~0x3c ) + ( ( TXV << 2 ) & 0x3c );
3216        n_yi = ( TXV & ~0xf ) + ( ( XAdjust >> 4 ) & 0xf );
3217
3218        tC1= (GETLE16(&psxVuw[(n_yi<<10)+YAdjust+n_xi]) >> ((XAdjust & 0x03)<<2)) & 0x0f ;
3219
3220        XAdjust=((posX+difX)>>16);
3221
3222        TXV=(posY+difY)>>16;
3223        n_xi = ( ( XAdjust >> 2 ) & ~0x3c ) + ( ( TXV << 2 ) & 0x3c );
3224        n_yi = ( TXV & ~0xf ) + ( ( XAdjust >> 4 ) & 0xf );
3225
3226        tC2= (GETLE16(&psxVuw[(n_yi<<10)+YAdjust+n_xi]) >> ((XAdjust & 0x03)<<2)) & 0x0f ;
3227
3228        GetTextureTransColG32((uint32_t *)&psxVuw[(i<<10)+j],
3229             GETLE16(&psxVuw[clutP+tC1])|
3230             ((int32_t)GETLE16(&psxVuw[clutP+tC2]))<<16);
3231        posX+=difX2;
3232        posY+=difY2;
3233       }
3234      if(j==xmax)
3235       {
3236        XAdjust=(posX>>16);
3237        TXV=posY>>16;
3238        n_xi = ( ( XAdjust >> 2 ) & ~0x3c ) + ( ( TXV << 2 ) & 0x3c );
3239        n_yi = ( TXV & ~0xf ) + ( ( XAdjust >> 4 ) & 0xf );
3240
3241        tC1= (GETLE16(&psxVuw[(n_yi<<10)+YAdjust+n_xi]) >> ((XAdjust & 0x03)<<2)) & 0x0f ;
3242
3243        GetTextureTransColG(&psxVuw[(i<<10)+j],GETLE16(&psxVuw[clutP+tC1]));
3244       }
3245     }
3246    if(NextRow_FT4()) return;
3247   }
3248 }
3249
3250 ////////////////////////////////////////////////////////////////////////
3251
3252 static void drawPoly4TEx4_TW(short x1, short y1, short x2, short y2, short x3, short y3, short x4, short y4, short tx1, short ty1, short tx2, short ty2, short tx3, short ty3, short tx4, short ty4,short clX, short clY)
3253 {
3254  int32_t num; 
3255  int32_t i,j,xmin,xmax,ymin,ymax;
3256  int32_t difX, difY, difX2, difY2;
3257  int32_t posX,posY,YAdjust,clutP,XAdjust;
3258  short tC1,tC2;
3259
3260  if(x1>drawW && x2>drawW && x3>drawW && x4>drawW) return;
3261  if(y1>drawH && y2>drawH && y3>drawH && y4>drawH) return;
3262  if(x1<drawX && x2<drawX && x3<drawX && x4<drawX) return;
3263  if(y1<drawY && y2<drawY && y3<drawY && y4<drawY) return;
3264  if(drawY>=drawH) return;
3265  if(drawX>=drawW) return; 
3266
3267  if(!SetupSections_FT4(x1,y1,x2,y2,x3,y3,x4,y4,tx1,ty1,tx2,ty2,tx3,ty3,tx4,ty4)) return;
3268
3269  ymax=Ymax;
3270
3271  for(ymin=Ymin;ymin<drawY;ymin++)
3272   if(NextRow_FT4()) return;
3273
3274  clutP=(clY<<10)+clX;
3275
3276  YAdjust=((GlobalTextAddrY)<<11)+(GlobalTextAddrX<<1);
3277  YAdjust+=(TWin.Position.y0<<11)+(TWin.Position.x0>>1);
3278
3279 #ifdef FASTSOLID
3280
3281  if(!bCheckMask && !DrawSemiTrans)
3282   {
3283    for (i=ymin;i<=ymax;i++)
3284     {
3285      xmin=(left_x >> 16);
3286      xmax=(right_x >> 16);
3287
3288      if(xmax>=xmin)
3289       {
3290        posX=left_u;
3291        posY=left_v;
3292
3293        num=(xmax-xmin);
3294        if(num==0) num=1;
3295        difX=(right_u-posX)/num;
3296        difY=(right_v-posY)/num;
3297        difX2=difX<<1;
3298        difY2=difY<<1;
3299
3300        if(xmin<drawX)
3301         {j=drawX-xmin;xmin=drawX;posX+=j*difX;posY+=j*difY;}
3302        xmax--;if(drawW<xmax) xmax=drawW;
3303
3304        for(j=xmin;j<xmax;j+=2)
3305         {
3306          XAdjust=(posX>>16)%TWin.Position.x1;
3307          tC1 = psxVub[(((posY>>16)%TWin.Position.y1)<<11)+
3308                       YAdjust+(XAdjust>>1)];
3309          tC1=(tC1>>((XAdjust&1)<<2))&0xf;
3310          XAdjust=((posX+difX)>>16)%TWin.Position.x1;
3311          tC2 = psxVub[((((posY+difY)>>16)%TWin.Position.y1)<<11)+
3312                       YAdjust+(XAdjust>>1)];
3313          tC2=(tC2>>((XAdjust&1)<<2))&0xf;
3314
3315          GetTextureTransColG32_S((uint32_t *)&psxVuw[(i<<10)+j],
3316               GETLE16(&psxVuw[clutP+tC1])|
3317               ((int32_t)GETLE16(&psxVuw[clutP+tC2]))<<16);
3318          posX+=difX2;
3319          posY+=difY2;
3320         }
3321        if(j==xmax)
3322         {
3323          XAdjust=(posX>>16)%TWin.Position.x1;
3324          tC1 = psxVub[(((posY>>16)%TWin.Position.y1)<<11)+
3325                       YAdjust+(XAdjust>>1)];
3326          tC1=(tC1>>((XAdjust&1)<<2))&0xf;
3327          GetTextureTransColG_S(&psxVuw[(i<<10)+j],GETLE16(&psxVuw[clutP+tC1]));
3328         }
3329       }
3330      if(NextRow_FT4()) return;
3331     }
3332    return;
3333   }
3334
3335 #endif
3336
3337  for (i=ymin;i<=ymax;i++)
3338   {
3339    xmin=(left_x >> 16);
3340    xmax=(right_x >> 16);
3341
3342    if(xmax>=xmin)
3343     {
3344      posX=left_u;
3345      posY=left_v;
3346
3347      num=(xmax-xmin);
3348      if(num==0) num=1;
3349      difX=(right_u-posX)/num;
3350      difY=(right_v-posY)/num;
3351      difX2=difX<<1;
3352      difY2=difY<<1;
3353
3354      if(xmin<drawX)
3355       {j=drawX-xmin;xmin=drawX;posX+=j*difX;posY+=j*difY;}
3356      xmax--;if(drawW<xmax) xmax=drawW;
3357
3358      for(j=xmin;j<xmax;j+=2)
3359       {
3360        XAdjust=(posX>>16)%TWin.Position.x1;
3361        tC1 = psxVub[(((posY>>16)%TWin.Position.y1)<<11)+
3362                     YAdjust+(XAdjust>>1)];
3363        tC1=(tC1>>((XAdjust&1)<<2))&0xf;
3364        XAdjust=((posX+difX)>>16)%TWin.Position.x1;
3365        tC2 = psxVub[((((posY+difY)>>16)%TWin.Position.y1)<<11)+
3366                     YAdjust+(XAdjust>>1)];
3367        tC2=(tC2>>((XAdjust&1)<<2))&0xf;
3368
3369        GetTextureTransColG32((uint32_t *)&psxVuw[(i<<10)+j],
3370             GETLE16(&psxVuw[clutP+tC1])|
3371             ((int32_t)GETLE16(&psxVuw[clutP+tC2]))<<16);
3372        posX+=difX2;
3373        posY+=difY2;
3374       }
3375      if(j==xmax)
3376       {
3377        XAdjust=(posX>>16)%TWin.Position.x1;
3378        tC1 = psxVub[(((posY>>16)%TWin.Position.y1)<<11)+
3379                     YAdjust+(XAdjust>>1)];
3380        tC1=(tC1>>((XAdjust&1)<<2))&0xf;
3381        GetTextureTransColG(&psxVuw[(i<<10)+j],GETLE16(&psxVuw[clutP+tC1]));
3382       }
3383     }
3384    if(NextRow_FT4()) return;
3385   }
3386 }
3387
3388 ////////////////////////////////////////////////////////////////////////
3389
3390 static void drawPoly4TEx4_TW_S(short x1, short y1, short x2, short y2, short x3, short y3, short x4, short y4, short tx1, short ty1, short tx2, short ty2, short tx3, short ty3, short tx4, short ty4,short clX, short clY)
3391 {
3392  int32_t num; 
3393  int32_t i,j,xmin,xmax,ymin,ymax;
3394  int32_t difX, difY, difX2, difY2;
3395  int32_t posX,posY,YAdjust,clutP,XAdjust;
3396  short tC1,tC2;
3397
3398  if(x1>drawW && x2>drawW && x3>drawW && x4>drawW) return;
3399  if(y1>drawH && y2>drawH && y3>drawH && y4>drawH) return;
3400  if(x1<drawX && x2<drawX && x3<drawX && x4<drawX) return;
3401  if(y1<drawY && y2<drawY && y3<drawY && y4<drawY) return;
3402  if(drawY>=drawH) return;
3403  if(drawX>=drawW) return; 
3404
3405  if(!SetupSections_FT4(x1,y1,x2,y2,x3,y3,x4,y4,tx1,ty1,tx2,ty2,tx3,ty3,tx4,ty4)) return;
3406
3407  ymax=Ymax;
3408
3409  for(ymin=Ymin;ymin<drawY;ymin++)
3410   if(NextRow_FT4()) return;
3411
3412  clutP=(clY<<10)+clX;
3413
3414  YAdjust=((GlobalTextAddrY)<<11)+(GlobalTextAddrX<<1);
3415  YAdjust+=(TWin.Position.y0<<11)+(TWin.Position.x0>>1);
3416
3417 #ifdef FASTSOLID
3418
3419  if(!bCheckMask && !DrawSemiTrans)
3420   {
3421    for (i=ymin;i<=ymax;i++)
3422     {
3423      xmin=(left_x >> 16);
3424      xmax=(right_x >> 16);
3425
3426      if(xmax>=xmin)
3427       {
3428        posX=left_u;
3429        posY=left_v;
3430
3431        num=(xmax-xmin);
3432        if(num==0) num=1;
3433        difX=(right_u-posX)/num;
3434        difY=(right_v-posY)/num;
3435        difX2=difX<<1;
3436        difY2=difY<<1;
3437
3438        if(xmin<drawX)
3439         {j=drawX-xmin;xmin=drawX;posX+=j*difX;posY+=j*difY;}
3440        xmax--;if(drawW<xmax) xmax=drawW;
3441
3442        for(j=xmin;j<xmax;j+=2)
3443         {
3444          XAdjust=(posX>>16)%TWin.Position.x1;
3445          tC1 = psxVub[(((posY>>16)%TWin.Position.y1)<<11)+
3446                       YAdjust+(XAdjust>>1)];
3447          tC1=(tC1>>((XAdjust&1)<<2))&0xf;
3448          XAdjust=((posX+difX)>>16)%TWin.Position.x1;
3449          tC2 = psxVub[((((posY+difY)>>16)%TWin.Position.y1)<<11)+
3450                       YAdjust+(XAdjust>>1)];
3451          tC2=(tC2>>((XAdjust&1)<<2))&0xf;
3452
3453          GetTextureTransColG32_S((uint32_t *)&psxVuw[(i<<10)+j],
3454               GETLE16(&psxVuw[clutP+tC1])|
3455               ((int32_t)GETLE16(&psxVuw[clutP+tC2]))<<16);
3456          posX+=difX2;
3457          posY+=difY2;
3458         }
3459        if(j==xmax)
3460         {
3461          XAdjust=(posX>>16)%TWin.Position.x1;
3462          tC1 = psxVub[(((posY>>16)%TWin.Position.y1)<<11)+
3463                       YAdjust+(XAdjust>>1)];
3464          tC1=(tC1>>((XAdjust&1)<<2))&0xf;
3465          GetTextureTransColG_S(&psxVuw[(i<<10)+j],GETLE16(&psxVuw[clutP+tC1]));
3466         }
3467       }
3468      if(NextRow_FT4()) return;
3469     }
3470    return;
3471   }
3472
3473 #endif
3474
3475  for (i=ymin;i<=ymax;i++)
3476   {
3477    xmin=(left_x >> 16);
3478    xmax=(right_x >> 16);
3479
3480    if(xmax>=xmin)
3481     {
3482      posX=left_u;
3483      posY=left_v;
3484
3485      num=(xmax-xmin);
3486      if(num==0) num=1;
3487      difX=(right_u-posX)/num;
3488      difY=(right_v-posY)/num;
3489      difX2=difX<<1;
3490      difY2=difY<<1;
3491
3492      if(xmin<drawX)
3493       {j=drawX-xmin;xmin=drawX;posX+=j*difX;posY+=j*difY;}
3494      xmax--;if(drawW<xmax) xmax=drawW;
3495
3496      for(j=xmin;j<xmax;j+=2)
3497       {
3498        XAdjust=(posX>>16)%TWin.Position.x1;
3499        tC1 = psxVub[(((posY>>16)%TWin.Position.y1)<<11)+
3500                     YAdjust+(XAdjust>>1)];
3501        tC1=(tC1>>((XAdjust&1)<<2))&0xf;
3502        XAdjust=((posX+difX)>>16)%TWin.Position.x1;
3503        tC2 = psxVub[((((posY+difY)>>16)%TWin.Position.y1)<<11)+
3504                     YAdjust+(XAdjust>>1)];
3505        tC2=(tC2>>((XAdjust&1)<<2))&0xf;
3506
3507        GetTextureTransColG32_SPR((uint32_t *)&psxVuw[(i<<10)+j],
3508             GETLE16(&psxVuw[clutP+tC1])|
3509             ((int32_t)GETLE16(&psxVuw[clutP+tC2]))<<16);
3510        posX+=difX2;
3511        posY+=difY2;
3512       }
3513      if(j==xmax)
3514       {
3515        XAdjust=(posX>>16)%TWin.Position.x1;
3516        tC1 = psxVub[(((posY>>16)%TWin.Position.y1)<<11)+
3517                     YAdjust+(XAdjust>>1)];
3518        tC1=(tC1>>((XAdjust&1)<<2))&0xf;
3519        GetTextureTransColG_SPR(&psxVuw[(i<<10)+j],GETLE16(&psxVuw[clutP+tC1]));
3520       }
3521     }
3522    if(NextRow_FT4()) return;
3523   }
3524 }
3525 ////////////////////////////////////////////////////////////////////////
3526 // POLY 3 F-SHADED TEX PAL 8
3527 ////////////////////////////////////////////////////////////////////////
3528
3529 static void drawPoly3TEx8(short x1, short y1, short x2, short y2, short x3, short y3, short tx1, short ty1, short tx2, short ty2, short tx3, short ty3,short clX, short clY)
3530 {
3531  int i,j,xmin,xmax,ymin,ymax;
3532  int32_t difX, difY,difX2, difY2;
3533  int32_t posX,posY,YAdjust,clutP;
3534  short tC1,tC2;
3535
3536  if(x1>drawW && x2>drawW && x3>drawW) return;
3537  if(y1>drawH && y2>drawH && y3>drawH) return;
3538  if(x1<drawX && x2<drawX && x3<drawX) return;
3539  if(y1<drawY && y2<drawY && y3<drawY) return;
3540  if(drawY>=drawH) return;
3541  if(drawX>=drawW) return; 
3542
3543  if(!SetupSections_FT(x1,y1,x2,y2,x3,y3,tx1,ty1,tx2,ty2,tx3,ty3)) return;
3544
3545  ymax=Ymax;
3546
3547  for(ymin=Ymin;ymin<drawY;ymin++)
3548   if(NextRow_FT()) return;
3549
3550  clutP=(clY<<10)+clX;
3551
3552  YAdjust=((GlobalTextAddrY)<<11)+(GlobalTextAddrX<<1);
3553
3554  difX=delta_right_u;difX2=difX<<1;
3555  difY=delta_right_v;difY2=difY<<1;
3556
3557 #ifdef FASTSOLID
3558
3559  if(!bCheckMask && !DrawSemiTrans)
3560   {
3561    for (i=ymin;i<=ymax;i++)
3562     {
3563      xmin=(left_x >> 16);
3564      xmax=(right_x >> 16)-1; //!!!!!!!!!!!!!!!
3565      if(drawW<xmax) xmax=drawW;
3566
3567      if(xmax>=xmin)
3568       {
3569        posX=left_u;
3570        posY=left_v;
3571
3572        if(xmin<drawX)
3573         {j=drawX-xmin;xmin=drawX;posX+=j*difX;posY+=j*difY;}
3574
3575        for(j=xmin;j<xmax;j+=2)
3576         {
3577          tC1 = psxVub[((posY>>5)&(int32_t)0xFFFFF800)+YAdjust+(posX>>16)];
3578          tC2 = psxVub[(((posY+difY)>>5)&(int32_t)0xFFFFF800)+YAdjust+
3579                       ((posX+difX)>>16)];
3580          GetTextureTransColG32_S((uint32_t *)&psxVuw[(i<<10)+j],
3581              GETLE16(&psxVuw[clutP+tC1])|
3582              ((int32_t)GETLE16(&psxVuw[clutP+tC2]))<<16);
3583          posX+=difX2;
3584          posY+=difY2;
3585    &