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