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