prepare for external gpu plugins
[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
4246  ymax=Ymax;
4247
4248  for(ymin=Ymin;ymin<drawY;ymin++)
4249   if(NextRow_FT4()) return;
4250
4251  clutP=(clY<<10)+clX;
4252
4253  YAdjust=(GlobalTextAddrY<<10)+GlobalTextAddrX;
4254
4255 #ifdef FASTSOLID
4256
4257  if(!bCheckMask && !DrawSemiTrans)
4258   {
4259    for (i=ymin;i<=ymax;i++)
4260     {
4261      xmin=(left_x >> 16);
4262      xmax=(right_x >> 16);
4263
4264      if(xmax>=xmin)
4265       {
4266        posX=left_u;
4267        posY=left_v;
4268
4269        num=(xmax-xmin);
4270        if(num==0) num=1;
4271        difX=(right_u-posX)/num;
4272        difY=(right_v-posY)/num;
4273        difX2=difX<<1;
4274        difY2=difY<<1;
4275
4276        if(xmin<drawX)
4277         {j=drawX-xmin;xmin=drawX;posX+=j*difX;posY+=j*difY;}
4278        xmax--;if(drawW<xmax) xmax=drawW;
4279
4280        for(j=xmin;j<xmax;j+=2)
4281         {
4282          TXU=posX>>16;
4283          TXV=posY>>16;
4284          n_xi = ( ( TXU >> 1 ) & ~0x78 ) + ( ( TXU << 2 ) & 0x40 ) + ( ( TXV << 3 ) & 0x38 );
4285          n_yi = ( TXV & ~0x7 ) + ( ( TXU >> 5 ) & 0x7 );
4286
4287          tC1= (GETLE16(&psxVuw[(n_yi<<10)+YAdjust+n_xi]) >> ((TXU & 0x01)<<3)) & 0xff;
4288
4289          TXU=(posX+difX)>>16;
4290          TXV=(posY+difY)>>16;
4291          n_xi = ( ( TXU >> 1 ) & ~0x78 ) + ( ( TXU << 2 ) & 0x40 ) + ( ( TXV << 3 ) & 0x38 );
4292          n_yi = ( TXV & ~0x7 ) + ( ( TXU >> 5 ) & 0x7 );
4293
4294          tC2= (GETLE16(&psxVuw[(n_yi<<10)+YAdjust+n_xi]) >> ((TXU & 0x01)<<3)) & 0xff;
4295
4296          GetTextureTransColG32_S((uint32_t *)&psxVuw[(i<<10)+j],
4297               GETLE16(&psxVuw[clutP+tC1])|
4298               ((int32_t)GETLE16(&psxVuw[clutP+tC2]))<<16);
4299          posX+=difX2;
4300          posY+=difY2;
4301         }
4302        if(j==xmax)
4303         {
4304          TXU=posX>>16;
4305          TXV=posY>>16;
4306          n_xi = ( ( TXU >> 1 ) & ~0x78 ) + ( ( TXU << 2 ) & 0x40 ) + ( ( TXV << 3 ) & 0x38 );
4307          n_yi = ( TXV & ~0x7 ) + ( ( TXU >> 5 ) & 0x7 );
4308
4309          tC1= (GETLE16(&psxVuw[(n_yi<<10)+YAdjust+n_xi]) >> ((TXU & 0x01)<<3)) & 0xff;
4310
4311          GetTextureTransColG_S(&psxVuw[(i<<10)+j],GETLE16(&psxVuw[clutP+tC1]));
4312         }
4313       }
4314      if(NextRow_FT4()) return;
4315     }
4316    return;
4317   }
4318
4319 #endif
4320
4321  for (i=ymin;i<=ymax;i++)
4322   {
4323    xmin=(left_x >> 16);
4324    xmax=(right_x >> 16);
4325
4326    if(xmax>=xmin)
4327     {
4328      posX=left_u;
4329      posY=left_v;
4330
4331      num=(xmax-xmin);
4332      if(num==0) num=1;
4333      difX=(right_u-posX)/num;
4334      difY=(right_v-posY)/num;
4335      difX2=difX<<1;
4336      difY2=difY<<1;
4337
4338      if(xmin<drawX)
4339       {j=drawX-xmin;xmin=drawX;posX+=j*difX;posY+=j*difY;}
4340      xmax--;if(drawW<xmax) xmax=drawW;
4341
4342      for(j=xmin;j<xmax;j+=2)
4343       {
4344        TXU=posX>>16;
4345        TXV=posY>>16;
4346        n_xi = ( ( TXU >> 1 ) & ~0x78 ) + ( ( TXU << 2 ) & 0x40 ) + ( ( TXV << 3 ) & 0x38 );
4347        n_yi = ( TXV & ~0x7 ) + ( ( TXU >> 5 ) & 0x7 );
4348
4349        tC1= (GETLE16(&psxVuw[(n_yi<<10)+YAdjust+n_xi]) >> ((TXU & 0x01)<<3)) & 0xff;
4350
4351        TXU=(posX+difX)>>16;
4352        TXV=(posY+difY)>>16;
4353        n_xi = ( ( TXU >> 1 ) & ~0x78 ) + ( ( TXU << 2 ) & 0x40 ) + ( ( TXV << 3 ) & 0x38 );
4354        n_yi = ( TXV & ~0x7 ) + ( ( TXU >> 5 ) & 0x7 );
4355        
4356        tC2= (GETLE16(&psxVuw[(n_yi<<10)+YAdjust+n_xi]) >> ((TXU & 0x01)<<3)) & 0xff;
4357
4358        GetTextureTransColG32((uint32_t *)&psxVuw[(i<<10)+j],
4359             GETLE16(&psxVuw[clutP+tC1])|
4360             ((int32_t)GETLE16(&psxVuw[clutP+tC2]))<<16);
4361        posX+=difX2;
4362        posY+=difY2;
4363       }
4364      if(j==xmax)
4365       {
4366        TXU=posX>>16;
4367        TXV=posY>>16;
4368        n_xi = ( ( TXU >> 1 ) & ~0x78 ) + ( ( TXU << 2 ) & 0x40 ) + ( ( TXV << 3 ) & 0x38 );
4369        n_yi = ( TXV & ~0x7 ) + ( ( TXU >> 5 ) & 0x7 );
4370        tC1= (GETLE16(&psxVuw[(n_yi<<10)+YAdjust+n_xi]) >> ((TXU & 0x01)<<3)) & 0xff;
4371        GetTextureTransColG(&psxVuw[(i<<10)+j],GETLE16(&psxVuw[clutP+tC1]));
4372       }
4373     }
4374    if(NextRow_FT4()) return;
4375   }
4376 }
4377
4378 ////////////////////////////////////////////////////////////////////////
4379
4380 void drawPoly4TEx8_TW(short x1, short y1, short x2, short y2, short x3, short y3, short x4, short y4, short tx1, short ty1, short tx2, short ty2, short tx3, short ty3, short tx4, short ty4,short clX, short clY)
4381 {
4382  int32_t num; 
4383  int32_t i,j,xmin,xmax,ymin,ymax;
4384  int32_t difX, difY, difX2, difY2;
4385  int32_t posX,posY,YAdjust,clutP;
4386  short tC1,tC2;
4387
4388  if(x1>drawW && x2>drawW && x3>drawW && x4>drawW) return;
4389  if(y1>drawH && y2>drawH && y3>drawH && y4>drawH) return;
4390  if(x1<drawX && x2<drawX && x3<drawX && x4<drawX) return;
4391  if(y1<drawY && y2<drawY && y3<drawY && y4<drawY) return;
4392  if(drawY>=drawH) return;
4393  if(drawX>=drawW) return; 
4394
4395  if(!SetupSections_FT4(x1,y1,x2,y2,x3,y3,x4,y4,tx1,ty1,tx2,ty2,tx3,ty3,tx4,ty4)) return;
4396
4397  ymax=Ymax;
4398
4399  for(ymin=Ymin;ymin<drawY;ymin++)
4400   if(NextRow_FT4()) return;
4401
4402  clutP=(clY<<10)+clX;
4403
4404  YAdjust=((GlobalTextAddrY)<<11)+(GlobalTextAddrX<<1);
4405  YAdjust+=(TWin.Position.y0<<11)+(TWin.Position.x0);
4406
4407 #ifdef FASTSOLID
4408
4409  if(!bCheckMask && !DrawSemiTrans)
4410   {
4411    for (i=ymin;i<=ymax;i++)
4412     {
4413      xmin=(left_x >> 16);
4414      xmax=(right_x >> 16);
4415
4416      if(xmax>=xmin)
4417       {
4418        posX=left_u;
4419        posY=left_v;
4420
4421        num=(xmax-xmin);
4422        if(num==0) num=1;
4423        difX=(right_u-posX)/num;
4424        difY=(right_v-posY)/num;
4425        difX2=difX<<1;
4426        difY2=difY<<1;
4427
4428        if(xmin<drawX)
4429         {j=drawX-xmin;xmin=drawX;posX+=j*difX;posY+=j*difY;}
4430        xmax--;if(drawW<xmax) xmax=drawW;
4431
4432        for(j=xmin;j<xmax;j+=2)
4433         {
4434          tC1 = psxVub[(((posY>>16)%TWin.Position.y1)<<11)+
4435                       YAdjust+((posX>>16)%TWin.Position.x1)];
4436          tC2 = psxVub[((((posY+difY)>>16)%TWin.Position.y1)<<11)+
4437                       YAdjust+(((posX+difX)>>16)%TWin.Position.x1)];
4438          GetTextureTransColG32_S((uint32_t *)&psxVuw[(i<<10)+j],
4439               GETLE16(&psxVuw[clutP+tC1])|
4440               ((int32_t)GETLE16(&psxVuw[clutP+tC2]))<<16);
4441          posX+=difX2;
4442          posY+=difY2;
4443         }
4444        if(j==xmax)
4445         {
4446          tC1 = psxVub[((((posY+difY)>>16)%TWin.Position.y1)<<11)+
4447                       YAdjust+((posX>>16)%TWin.Position.x1)];
4448          GetTextureTransColG_S(&psxVuw[(i<<10)+j],GETLE16(&psxVuw[clutP+tC1]));
4449         }
4450       }
4451      if(NextRow_FT4()) return;
4452     }
4453    return;
4454   }
4455
4456 #endif
4457
4458
4459  for (i=ymin;i<=ymax;i++)
4460   {
4461    xmin=(left_x >> 16);
4462    xmax=(right_x >> 16);
4463
4464    if(xmax>=xmin)
4465     {
4466      posX=left_u;
4467      posY=left_v;
4468
4469      num=(xmax-xmin);
4470      if(num==0) num=1;
4471      difX=(right_u-posX)/num;
4472      difY=(right_v-posY)/num;
4473      difX2=difX<<1;
4474      difY2=difY<<1;
4475
4476      if(xmin<drawX)
4477       {j=drawX-xmin;xmin=drawX;posX+=j*difX;posY+=j*difY;}
4478      xmax--;if(drawW<xmax) xmax=drawW;
4479
4480      for(j=xmin;j<xmax;j+=2)
4481       {
4482        tC1 = psxVub[(((posY>>16)%TWin.Position.y1)<<11)+
4483                     YAdjust+((posX>>16)%TWin.Position.x1)];
4484        tC2 = psxVub[((((posY+difY)>>16)%TWin.Position.y1)<<11)+
4485                      YAdjust+(((posX+difX)>>16)%TWin.Position.x1)];
4486        GetTextureTransColG32((uint32_t *)&psxVuw[(i<<10)+j],
4487             GETLE16(&psxVuw[clutP+tC1])|
4488             ((int32_t)GETLE16(&psxVuw[clutP+tC2]))<<16);
4489        posX+=difX2;
4490        posY+=difY2;
4491       }
4492      if(j==xmax)
4493       {
4494        tC1 = psxVub[((((posY+difY)>>16)%TWin.Position.y1)<<11)+
4495                     YAdjust+((posX>>16)%TWin.Position.x1)];
4496        GetTextureTransColG(&psxVuw[(i<<10)+j],GETLE16(&psxVuw[clutP+tC1]));
4497       }
4498     }
4499    if(NextRow_FT4()) return;
4500   }
4501 }
4502
4503 ////////////////////////////////////////////////////////////////////////
4504
4505 void drawPoly4TEx8_TW_S(short x1, short y1, short x2, short y2, short x3, short y3, short x4, short y4, short tx1, short ty1, short tx2, short ty2, short tx3, short ty3, short tx4, short ty4,short clX, short clY)
4506 {
4507  int32_t num; 
4508  int32_t i,j,xmin,xmax,ymin,ymax;
4509  int32_t difX, difY, difX2, difY2;
4510  int32_t posX,posY,YAdjust,clutP;
4511  short tC1,tC2;
4512
4513  if(x1>drawW && x2>drawW && x3>drawW && x4>drawW) return;
4514  if(y1>drawH && y2>drawH && y3>drawH && y4>drawH) return;
4515  if(x1<drawX && x2<drawX && x3<drawX && x4<drawX) return;
4516  if(y1<drawY && y2<drawY && y3<drawY && y4<drawY) return;
4517  if(drawY>=drawH) return;
4518  if(drawX>=drawW) return; 
4519
4520  if(!SetupSections_FT4(x1,y1,x2,y2,x3,y3,x4,y4,tx1,ty1,tx2,ty2,tx3,ty3,tx4,ty4)) return;
4521
4522  ymax=Ymax;
4523
4524  for(ymin=Ymin;ymin<drawY;ymin++)
4525   if(NextRow_FT4()) return;
4526
4527  clutP=(clY<<10)+clX;
4528
4529  YAdjust=((GlobalTextAddrY)<<11)+(GlobalTextAddrX<<1);
4530  YAdjust+=(TWin.Position.y0<<11)+(TWin.Position.x0);
4531
4532 #ifdef FASTSOLID
4533
4534  if(!bCheckMask && !DrawSemiTrans)
4535   {
4536    for (i=ymin;i<=ymax;i++)
4537     {
4538      xmin=(left_x >> 16);
4539      xmax=(right_x >> 16);
4540
4541      if(xmax>=xmin)
4542       {
4543        posX=left_u;
4544        posY=left_v;
4545
4546        num=(xmax-xmin);
4547        if(num==0) num=1;
4548        difX=(right_u-posX)/num;
4549        difY=(right_v-posY)/num;
4550        difX2=difX<<1;
4551        difY2=difY<<1;
4552
4553        if(xmin<drawX)
4554         {j=drawX-xmin;xmin=drawX;posX+=j*difX;posY+=j*difY;}
4555        xmax--;if(drawW<xmax) xmax=drawW;
4556
4557        for(j=xmin;j<xmax;j+=2)
4558         {
4559          tC1 = psxVub[(((posY>>16)%TWin.Position.y1)<<11)+
4560                       YAdjust+((posX>>16)%TWin.Position.x1)];
4561          tC2 = psxVub[((((posY+difY)>>16)%TWin.Position.y1)<<11)+
4562                       YAdjust+(((posX+difX)>>16)%TWin.Position.x1)];
4563          GetTextureTransColG32_S((uint32_t *)&psxVuw[(i<<10)+j],
4564               GETLE16(&psxVuw[clutP+tC1])|
4565               ((int32_t)GETLE16(&psxVuw[clutP+tC2]))<<16);
4566          posX+=difX2;
4567          posY+=difY2;
4568         }
4569        if(j==xmax)
4570         {
4571          tC1 = psxVub[((((posY+difY)>>16)%TWin.Position.y1)<<11)+
4572                       YAdjust+((posX>>16)%TWin.Position.x1)];
4573          GetTextureTransColG_S(&psxVuw[(i<<10)+j],GETLE16(&psxVuw[clutP+tC1]));
4574         }
4575       }
4576      if(NextRow_FT4()) return;
4577     }
4578    return;
4579   }
4580
4581 #endif
4582
4583
4584  for (i=ymin;i<=ymax;i++)
4585   {
4586    xmin=(left_x >> 16);
4587    xmax=(right_x >> 16);
4588
4589    if(xmax>=xmin)
4590     {
4591      posX=left_u;
4592      posY=left_v;
4593
4594      num=(xmax-xmin);
4595      if(num==0) num=1;
4596      difX=(right_u-posX)/num;
4597      difY=(right_v-posY)/num;
4598      difX2=difX<<1;
4599      difY2=difY<<1;
4600
4601      if(xmin<drawX)
4602       {j=drawX-xmin;xmin=drawX;posX+=j*difX;posY+=j*difY;}
4603      xmax--;if(drawW<xmax) xmax=drawW;
4604
4605      for(j=xmin;j<xmax;j+=2)
4606       {
4607        tC1 = psxVub[(((posY>>16)%TWin.Position.y1)<<11)+
4608                     YAdjust+((posX>>16)%TWin.Position.x1)];
4609        tC2 = psxVub[((((posY+difY)>>16)%TWin.Position.y1)<<11)+
4610                      YAdjust+(((posX+difX)>>16)%TWin.Position.x1)];
4611        GetTextureTransColG32_SPR((uint32_t *)&psxVuw[(i<<10)+j],
4612             GETLE16(&psxVuw[clutP+tC1])|
4613             ((int32_t)GETLE16(&psxVuw[clutP+tC2]))<<16);
4614        posX+=difX2;
4615        posY+=difY2;
4616       }
4617      if(j==xmax)
4618       {
4619        tC1 = psxVub[((((posY+difY)>>16)%TWin.Position.y1)<<11)+
4620                     YAdjust+((posX>>16)%TWin.Position.x1)];
4621        GetTextureTransColG_SPR(&psxVuw[(i<<10)+j],GETLE16(&psxVuw[clutP+tC1]));
4622       }
4623     }
4624    if(NextRow_FT4()) return;
4625   }
4626 }
4627
4628 ////////////////////////////////////////////////////////////////////////
4629 // POLY 3 F-SHADED TEX 15 BIT
4630 ////////////////////////////////////////////////////////////////////////
4631
4632 void drawPoly3TD(short x1, short y1, short x2, short y2, short x3, short y3, short tx1, short ty1, short tx2, short ty2, short tx3, short ty3)
4633 {
4634  int i,j,xmin,xmax,ymin,ymax;
4635  int32_t difX, difY,difX2, difY2;
4636  int32_t posX,posY;
4637
4638  if(x1>drawW && x2>drawW && x3>drawW) return;
4639  if(y1>drawH && y2>drawH && y3>drawH) return;
4640  if(x1<drawX && x2<drawX && x3<drawX) return;
4641  if(y1<drawY && y2<drawY && y3<drawY) return;
4642  if(drawY>=drawH) return;
4643  if(drawX>=drawW) return; 
4644                      
4645  if(!SetupSections_FT(x1,y1,x2,y2,x3,y3,tx1,ty1,tx2,ty2,tx3,ty3)) return;
4646
4647  ymax=Ymax;
4648
4649  for(ymin=Ymin;ymin<drawY;ymin++)
4650   if(NextRow_FT()) return;
4651
4652  difX=delta_right_u;difX2=difX<<1;
4653  difY=delta_right_v;difY2=difY<<1;
4654
4655 #ifdef FASTSOLID
4656
4657  if(!bCheckMask && !DrawSemiTrans)
4658   {
4659    for (i=ymin;i<=ymax;i++)
4660     {
4661      xmin=(left_x >> 16);
4662      xmax=(right_x >> 16)-1; //!!!!!!!!!!!!!
4663      if(drawW<xmax) xmax=drawW;
4664
4665      if(xmax>=xmin)
4666       {
4667        posX=left_u;
4668        posY=left_v;
4669
4670        if(xmin<drawX)
4671         {j=drawX-xmin;xmin=drawX;posX+=j*difX;posY+=j*difY;}
4672
4673        for(j=xmin;j<xmax;j+=2)
4674         {
4675          GetTextureTransColG32_S((uint32_t *)&psxVuw[(i<<10)+j],
4676               (((int32_t)GETLE16(&psxVuw[((((posY+difY)>>16)+GlobalTextAddrY)<<10)+((posX+difX)>>16)+GlobalTextAddrX]))<<16)|
4677               GETLE16(&psxVuw[(((posY>>16)+GlobalTextAddrY)<<10)+((posX)>>16)+GlobalTextAddrX]));
4678
4679          posX+=difX2;
4680          posY+=difY2;
4681         }
4682        if(j==xmax)
4683          GetTextureTransColG_S(&psxVuw[(i<<10)+j],
4684              GETLE16(&psxVuw[(((posY>>16)+GlobalTextAddrY)<<10)+(posX>>16)+GlobalTextAddrX]));
4685       }
4686      if(NextRow_FT()) 
4687       {
4688        return;
4689       }
4690     }
4691    return;
4692   }
4693
4694 #endif
4695
4696  for (i=ymin;i<=ymax;i++)
4697   {
4698    xmin=(left_x >> 16);
4699    xmax=(right_x >> 16)-1; //!!!!!!!!!!!!!!
4700    if(drawW<xmax) xmax=drawW;
4701
4702    if(xmax>=xmin)
4703     {
4704      posX=left_u;
4705      posY=left_v;
4706
4707      if(xmin<drawX)
4708       {j=drawX-xmin;xmin=drawX;posX+=j*difX;posY+=j*difY;}
4709
4710      for(j=xmin;j<xmax;j+=2)
4711       {
4712        GetTextureTransColG32((uint32_t *)&psxVuw[(i<<10)+j],
4713             (((int32_t)GETLE16(&psxVuw[((((posY+difY)>>16)+GlobalTextAddrY)<<10)+((posX+difX)>>16)+GlobalTextAddrX]))<<16)|
4714             GETLE16(&psxVuw[(((posY>>16)+GlobalTextAddrY)<<10)+((posX)>>16)+GlobalTextAddrX]));
4715
4716        posX+=difX2;
4717        posY+=difY2;
4718       }
4719      if(j==xmax)
4720        GetTextureTransColG(&psxVuw[(i<<10)+j],
4721            GETLE16(&psxVuw[(((posY>>16)+GlobalTextAddrY)<<10)+(posX>>16)+GlobalTextAddrX]));
4722     }
4723    if(NextRow_FT()) 
4724     {
4725      return;
4726     }
4727   }
4728 }
4729
4730 ////////////////////////////////////////////////////////////////////////
4731
4732 void drawPoly3TD_TW(short x1, short y1, short x2, short y2, short x3, short y3, short tx1, short ty1, short tx2, short ty2, short tx3, short ty3)
4733 {
4734  int i,j,xmin,xmax,ymin,ymax;
4735  int32_t difX, difY,difX2, difY2;
4736  int32_t posX,posY;
4737
4738  if(x1>drawW && x2>drawW && x3>drawW) return;
4739  if(y1>drawH && y2>drawH && y3>drawH) return;
4740  if(x1<drawX && x2<drawX && x3<drawX) return;
4741  if(y1<drawY && y2<drawY && y3<drawY) return;
4742  if(drawY>=drawH) return;
4743  if(drawX>=drawW) return; 
4744                      
4745  if(!SetupSections_FT(x1,y1,x2,y2,x3,y3,tx1,ty1,tx2,ty2,tx3,ty3)) return;
4746
4747  ymax=Ymax;
4748
4749  for(ymin=Ymin;ymin<drawY;ymin++)
4750   if(NextRow_FT()) return;
4751
4752  difX=delta_right_u;difX2=difX<<1;
4753  difY=delta_right_v;difY2=difY<<1;
4754
4755 #ifdef FASTSOLID
4756
4757  if(!bCheckMask && !DrawSemiTrans)
4758   {
4759    for (i=ymin;i<=ymax;i++)
4760     {
4761      xmin=(left_x >> 16);
4762      xmax=(right_x >> 16)-1; //!!!!!!!!!!!!!
4763      if(drawW<xmax) xmax=drawW;
4764
4765      if(xmax>=xmin)
4766       {
4767        posX=left_u;
4768        posY=left_v;
4769
4770        if(xmin<drawX)
4771         {j=drawX-xmin;xmin=drawX;posX+=j*difX;posY+=j*difY;}
4772
4773        for(j=xmin;j<xmax;j+=2)
4774         {
4775          GetTextureTransColG32_S((uint32_t *)&psxVuw[(i<<10)+j],
4776               (((int32_t)GETLE16(&psxVuw[(((((posY+difY)>>16)%TWin.Position.y1)+GlobalTextAddrY+TWin.Position.y0)<<10)+
4777               (((posX+difX)>>16)%TWin.Position.x1)+GlobalTextAddrX+TWin.Position.x0]))<<16)|
4778               GETLE16(&psxVuw[((((posY>>16)%TWin.Position.y1)+GlobalTextAddrY+TWin.Position.y0)<<10)+
4779                      (((posX)>>16)%TWin.Position.x1)+GlobalTextAddrX+TWin.Position.x0]));
4780
4781          posX+=difX2;
4782          posY+=difY2;
4783         }
4784        if(j==xmax)
4785          GetTextureTransColG_S(&psxVuw[(i<<10)+j],
4786              GETLE16(&psxVuw[((((posY>>16)%TWin.Position.y1)+GlobalTextAddrY+TWin.Position.y0)<<10)+
4787                     ((posX>>16)%TWin.Position.x1)+GlobalTextAddrX+TWin.Position.x0]));
4788       }
4789      if(NextRow_FT()) 
4790       {
4791        return;
4792       }
4793     }
4794    return;
4795   }
4796
4797 #endif
4798
4799  for (i=ymin;i<=ymax;i++)
4800   {
4801    xmin=(left_x >> 16);
4802    xmax=(right_x >> 16)-1; //!!!!!!!!!!!!!!
4803    if(drawW<xmax) xmax=drawW;
4804
4805    if(xmax>=xmin)
4806     {
4807      posX=left_u;
4808      posY=left_v;
4809
4810      if(xmin<drawX)
4811       {j=drawX-xmin;xmin=drawX;posX+=j*difX;posY+=j*difY;}
4812
4813      for(j=xmin;j<xmax;j+=2)
4814       {
4815        GetTextureTransColG32((uint32_t *)&psxVuw[(i<<10)+j],
4816             (((int32_t)GETLE16(&psxVuw[(((((posY+difY)>>16)%TWin.Position.y1)+GlobalTextAddrY+TWin.Position.y0)<<10)+
4817             (((posX+difX)>>16)%TWin.Position.x1)+GlobalTextAddrX+TWin.Position.x0]))<<16)|
4818             GETLE16(&psxVuw[((((posY>>16)%TWin.Position.y1)+GlobalTextAddrY+TWin.Position.y0)<<10)+
4819                    (((posX)>>16)%TWin.Position.x1)+GlobalTextAddrX+TWin.Position.x0]));
4820
4821        posX+=difX2;
4822        posY+=difY2;
4823       }
4824      if(j==xmax)
4825        GetTextureTransColG(&psxVuw[(i<<10)+j],
4826            GETLE16(&psxVuw[((((posY>>16)%TWin.Position.y1)+GlobalTextAddrY+TWin.Position.y0)<<10)+
4827                   ((posX>>16)%TWin.Position.x1)+GlobalTextAddrX+TWin.Position.x0]));
4828     }
4829    if(NextRow_FT()) 
4830     {
4831      return;
4832     }
4833   }
4834 }
4835
4836
4837 ////////////////////////////////////////////////////////////////////////
4838
4839 #ifdef POLYQUAD3
4840
4841 void drawPoly4TD_TRI(short x1, short y1, short x2, short y2, short x3, short y3, short x4, short y4, short tx1, short ty1, short tx2, short ty2, short tx3, short ty3, short tx4, short ty4)
4842 {
4843  drawPoly3TD(x2,y2,x3,y3,x4,y4,
4844             tx2,ty2,tx3,ty3,tx4,ty4);
4845  drawPoly3TD(x1,y1,x2,y2,x4,y4,
4846             tx1,ty1,tx2,ty2,tx4,ty4);
4847 }
4848
4849 #endif
4850
4851 // more exact:
4852
4853 void drawPoly4TD(short x1, short y1, short x2, short y2, short x3, short y3, short x4, short y4, short tx1, short ty1, short tx2, short ty2, short tx3, short ty3, short tx4, short ty4)
4854 {
4855  int32_t num; 
4856  int32_t i,j,xmin,xmax,ymin,ymax;
4857  int32_t difX, difY, difX2, difY2;
4858  int32_t posX,posY;
4859
4860  if(x1>drawW && x2>drawW && x3>drawW && x4>drawW) return;
4861  if(y1>drawH && y2>drawH && y3>drawH && y4>drawH) return;
4862  if(x1<drawX && x2<drawX && x3<drawX && x4<drawX) return;
4863  if(y1<drawY && y2<drawY && y3<drawY && y4<drawY) return;
4864  if(drawY>=drawH) return;
4865  if(drawX>=drawW) return; 
4866
4867  if(!SetupSections_FT4(x1,y1,x2,y2,x3,y3,x4,y4,tx1,ty1,tx2,ty2,tx3,ty3,tx4,ty4)) return;
4868
4869  ymax=Ymax;
4870
4871  for(ymin=Ymin;ymin<drawY;ymin++)
4872   if(NextRow_FT4()) return;
4873
4874 #ifdef FASTSOLID
4875
4876  if(!bCheckMask && !DrawSemiTrans)
4877   {
4878    for (i=ymin;i<=ymax;i++)
4879     {
4880      xmin=(left_x >> 16);
4881      xmax=(right_x >> 16);
4882
4883      if(xmax>=xmin)
4884       {
4885        posX=left_u;
4886        posY=left_v;
4887
4888        num=(xmax-xmin);
4889        if(num==0) num=1;
4890        difX=(right_u-posX)/num;
4891        difY=(right_v-posY)/num;
4892        difX2=difX<<1;
4893        difY2=difY<<1;
4894
4895        if(xmin<drawX)
4896         {j=drawX-xmin;xmin=drawX;posX+=j*difX;posY+=j*difY;}
4897        xmax--;if(drawW<xmax) xmax=drawW;
4898
4899        for(j=xmin;j<xmax;j+=2)
4900         {
4901          GetTextureTransColG32_S((uint32_t *)&psxVuw[(i<<10)+j],
4902               (((int32_t)GETLE16(&psxVuw[((((posY+difY)>>16)+GlobalTextAddrY)<<10)+((posX+difX)>>16)+GlobalTextAddrX]))<<16)|
4903               GETLE16(&psxVuw[(((posY>>16)+GlobalTextAddrY)<<10)+((posX)>>16)+GlobalTextAddrX]));
4904
4905          posX+=difX2;
4906          posY+=difY2;
4907         }
4908        if(j==xmax)
4909         GetTextureTransColG_S(&psxVuw[(i<<10)+j],
4910            GETLE16(&psxVuw[(((posY>>16)+GlobalTextAddrY)<<10)+(posX>>16)+GlobalTextAddrX]));
4911       }
4912      if(NextRow_FT4()) return;
4913     }
4914    return;
4915   }
4916
4917 #endif
4918
4919  for (i=ymin;i<=ymax;i++)
4920   {
4921    xmin=(left_x >> 16);
4922    xmax=(right_x >> 16);
4923
4924    if(xmax>=xmin)
4925     {
4926      posX=left_u;
4927      posY=left_v;
4928
4929      num=(xmax-xmin);
4930      if(num==0) num=1;
4931      difX=(right_u-posX)/num;
4932      difY=(right_v-posY)/num;
4933      difX2=difX<<1;
4934      difY2=difY<<1;
4935
4936      if(xmin<drawX)
4937       {j=drawX-xmin;xmin=drawX;posX+=j*difX;posY+=j*difY;}
4938      xmax--;if(drawW<xmax) xmax=drawW;
4939
4940      for(j=xmin;j<xmax;j+=2)
4941       {
4942        GetTextureTransColG32((uint32_t *)&psxVuw[(i<<10)+j],
4943             (((int32_t)GETLE16(&psxVuw[((((posY+difY)>>16)+GlobalTextAddrY)<<10)+((posX+difX)>>16)+GlobalTextAddrX]))<<16)|
4944             GETLE16(&psxVuw[(((posY>>16)+GlobalTextAddrY)<<10)+((posX)>>16)+GlobalTextAddrX]));
4945
4946        posX+=difX2;
4947        posY+=difY2;
4948       }
4949      if(j==xmax)
4950       GetTextureTransColG(&psxVuw[(i<<10)+j],
4951          GETLE16(&psxVuw[(((posY>>16)+GlobalTextAddrY)<<10)+(posX>>16)+GlobalTextAddrX]));
4952     }
4953    if(NextRow_FT4()) return;
4954   }
4955 }
4956
4957 ////////////////////////////////////////////////////////////////////////
4958
4959 void drawPoly4TD_TW(short x1, short y1, short x2, short y2, short x3, short y3, short x4, short y4, short tx1, short ty1, short tx2, short ty2, short tx3, short ty3, short tx4, short ty4)
4960 {
4961  int32_t num; 
4962  int32_t i,j,xmin,xmax,ymin,ymax;
4963  int32_t difX, difY, difX2, difY2;
4964  int32_t posX,posY;
4965
4966  if(x1>drawW && x2>drawW && x3>drawW && x4>drawW) return;
4967  if(y1>drawH && y2>drawH && y3>drawH && y4>drawH) return;
4968  if(x1<drawX && x2<drawX && x3<drawX && x4<drawX) return;
4969  if(y1<drawY && y2<drawY && y3<drawY && y4<drawY) return;
4970  if(drawY>=drawH) return;
4971  if(drawX>=drawW) return; 
4972
4973  if(!SetupSections_FT4(x1,y1,x2,y2,x3,y3,x4,y4,tx1,ty1,tx2,ty2,tx3,ty3,tx4,ty4)) return;
4974
4975  ymax=Ymax;
4976
4977  for(ymin=Ymin;ymin<drawY;ymin++)
4978   if(NextRow_FT4()) return;
4979
4980 #ifdef FASTSOLID
4981
4982  if(!bCheckMask && !DrawSemiTrans)
4983   {
4984    for (i=ymin;i<=ymax;i++)
4985     {
4986      xmin=(left_x >> 16);
4987      xmax=(right_x >> 16);
4988
4989      if(xmax>=xmin)
4990       {
4991        posX=left_u;
4992        posY=left_v;
4993
4994        num=(xmax-xmin);
4995        if(num==0) num=1;
4996        difX=(right_u-posX)/num;
4997        difY=(right_v-posY)/num;
4998        difX2=difX<<1;
4999        difY2=difY<<1;
5000
5001        if(xmin<drawX)
5002         {j=drawX-xmin;xmin=drawX;posX+=j*difX;posY+=j*difY;}
5003        xmax--;if(drawW<xmax) xmax=drawW;
5004
5005        for(j=xmin;j<xmax;j+=2)
5006         {
5007          GetTextureTransColG32_S((uint32_t *)&psxVuw[(i<<10)+j],
5008               (((int32_t)GETLE16(&psxVuw[(((((posY+difY)>>16)%TWin.Position.y1)+GlobalTextAddrY+TWin.Position.y0)<<10)+
5009                              (((posX+difX)>>16)%TWin.Position.x1)+GlobalTextAddrX+TWin.Position.x0]))<<16)|
5010               GETLE16(&psxVuw[((((posY>>16)%TWin.Position.y1)+GlobalTextAddrY)<<10)+TWin.Position.y0+
5011                      ((posX>>16)%TWin.Position.x1)+GlobalTextAddrX+TWin.Position.x0]));
5012
5013          posX+=difX2;
5014          posY+=difY2;
5015         }
5016        if(j==xmax)
5017         GetTextureTransColG_S(&psxVuw[(i<<10)+j],
5018            GETLE16(&psxVuw[((((posY>>16)%TWin.Position.y1)+GlobalTextAddrY+TWin.Position.y0)<<10)+
5019                   ((posX>>16)%TWin.Position.x1)+GlobalTextAddrX+TWin.Position.x0]));
5020       }
5021      if(NextRow_FT4()) return;
5022     }
5023    return;
5024   }
5025
5026 #endif
5027
5028  for (i=ymin;i<=ymax;i++)
5029   {
5030    xmin=(left_x >> 16);
5031    xmax=(right_x >> 16);
5032
5033    if(xmax>=xmin)
5034     {
5035      posX=left_u;
5036      posY=left_v;
5037
5038      num=(xmax-xmin);
5039      if(num==0) num=1;
5040      difX=(right_u-posX)/num;
5041      difY=(right_v-posY)/num;
5042      difX2=difX<<1;
5043      difY2=difY<<1;
5044
5045      if(xmin<drawX)
5046       {j=drawX-xmin;xmin=drawX;posX+=j*difX;posY+=j*difY;}
5047      xmax--;if(drawW<xmax) xmax=drawW;
5048
5049      for(j=xmin;j<xmax;j+=2)
5050       {
5051        GetTextureTransColG32((uint32_t *)&psxVuw[(i<<10)+j],
5052             (((int32_t)GETLE16(&psxVuw[(((((posY+difY)>>16)%TWin.Position.y1)+GlobalTextAddrY+TWin.Position.y0)<<10)+
5053                            (((posX+difX)>>16)%TWin.Position.x1)+GlobalTextAddrX+TWin.Position.x0]))<<16)|
5054             GETLE16(&psxVuw[((((posY>>16)%TWin.Position.y1)+GlobalTextAddrY+TWin.Position.y0)<<10)+
5055                    ((posX>>16)%TWin.Position.x1)+GlobalTextAddrX+TWin.Position.x0]));
5056
5057        posX+=difX2;
5058        posY+=difY2;
5059       }
5060      if(j==xmax)
5061       GetTextureTransColG(&psxVuw[(i<<10)+j],
5062          GETLE16(&psxVuw[((((posY>>16)%TWin.Position.y1)+GlobalTextAddrY+TWin.Position.y0)<<10)+
5063                 ((posX>>16)%TWin.Position.x1)+GlobalTextAddrX+TWin.Position.x0]));
5064     }
5065    if(NextRow_FT4()) return;
5066   }
5067 }
5068
5069 ////////////////////////////////////////////////////////////////////////
5070
5071 void drawPoly4TD_TW_S(short x1, short y1, short x2, short y2, short x3, short y3, short x4, short y4, short tx1, short ty1, short tx2, short ty2, short tx3, short ty3, short tx4, short ty4)
5072 {
5073  int32_t num; 
5074  int32_t i,j,xmin,xmax,ymin,ymax;
5075  int32_t difX, difY, difX2, difY2;
5076  int32_t posX,posY;
5077
5078  if(x1>drawW && x2>drawW && x3>drawW && x4>drawW) return;
5079  if(y1>drawH && y2>drawH && y3>drawH && y4>drawH) return;
5080  if(x1<drawX && x2<drawX && x3<drawX && x4<drawX) return;
5081  if(y1<drawY && y2<drawY && y3<drawY && y4<drawY) return;
5082  if(drawY>=drawH) return;
5083  if(drawX>=drawW) return; 
5084
5085  if(!SetupSections_FT4(x1,y1,x2,y2,x3,y3,x4,y4,tx1,ty1,tx2,ty2,tx3,ty3,tx4,ty4)) return;
5086
5087  ymax=Ymax;
5088
5089  for(ymin=Ymin;ymin<drawY;ymin++)
5090   if(NextRow_FT4()) return;
5091
5092 #ifdef FASTSOLID
5093
5094  if(!bCheckMask && !DrawSemiTrans)
5095   {
5096    for (i=ymin;i<=ymax;i++)
5097     {
5098      xmin=(left_x >> 16);
5099      xmax=(right_x >> 16);
5100
5101      if(xmax>=xmin)
5102       {
5103        posX=left_u;
5104        posY=left_v;
5105
5106        num=(xmax-xmin);
5107        if(num==0) num=1;
5108        difX=(right_u-posX)/num;
5109        difY=(right_v-posY)/num;
5110        difX2=difX<<1;
5111        difY2=difY<<1;
5112
5113        if(xmin<drawX)
5114         {j=drawX-xmin;xmin=drawX;posX+=j*difX;posY+=j*difY;}
5115        xmax--;if(drawW<xmax) xmax=drawW;
5116
5117        for(j=xmin;j<xmax;j+=2)
5118         {
5119          GetTextureTransColG32_S((uint32_t *)&psxVuw[(i<<10)+j],
5120               (((int32_t)GETLE16(&psxVuw[(((((posY+difY)>>16)%TWin.Position.y1)+GlobalTextAddrY+TWin.Position.y0)<<10)+
5121                              (((posX+difX)>>16)%TWin.Position.x1)+GlobalTextAddrX+TWin.Position.x0]))<<16)|
5122               GETLE16(&psxVuw[((((posY>>16)%TWin.Position.y1)+GlobalTextAddrY)<<10)+TWin.Position.y0+
5123                      ((posX>>16)%TWin.Position.x1)+GlobalTextAddrX+TWin.Position.x0]));
5124
5125          posX+=difX2;
5126          posY+=difY2;
5127         }
5128        if(j==xmax)
5129         GetTextureTransColG_S(&psxVuw[(i<<10)+j],
5130            GETLE16(&psxVuw[((((posY>>16)%TWin.Position.y1)+GlobalTextAddrY+TWin.Position.y0)<<10)+
5131                   ((posX>>16)%TWin.Position.x1)+GlobalTextAddrX+TWin.Position.x0]));
5132       }
5133      if(NextRow_FT4()) return;
5134     }
5135    return;
5136   }
5137
5138 #endif
5139
5140  for (i=ymin;i<=ymax;i++)
5141   {
5142    xmin=(left_x >> 16);
5143    xmax=(right_x >> 16);
5144
5145    if(xmax>=xmin)
5146     {
5147      posX=left_u;
5148      posY=left_v;
5149
5150      num=(xmax-xmin);
5151      if(num==0) num=1;
5152      difX=(right_u-posX)/num;
5153      difY=(right_v-posY)/num;
5154      difX2=difX<<1;
5155      difY2=difY<<1;
5156
5157      if(xmin<drawX)
5158       {j=drawX-xmin;xmin=drawX;posX+=j*difX;posY+=j*difY;}
5159      xmax--;if(drawW<xmax) xmax=drawW;
5160
5161      for(j=xmin;j<xmax;j+=2)
5162       {
5163        GetTextureTransColG32_SPR((uint32_t *)&psxVuw[(i<<10)+j],
5164             (((int32_t)GETLE16(&psxVuw[(((((posY+difY)>>16)%TWin.Position.y1)+GlobalTextAddrY+TWin.Position.y0)<<10)+
5165                            (((posX+difX)>>16)%TWin.Position.x1)+GlobalTextAddrX+TWin.Position.x0]))<<16)|
5166             GETLE16(&psxVuw[((((posY>>16)%TWin.Position.y1)+GlobalTextAddrY+TWin.Position.y0)<<10)+
5167                    ((posX>>16)%TWin.Position.x1)+GlobalTextAddrX+TWin.Position.x0]));
5168
5169        posX+=difX2;
5170        posY+=difY2;
5171       }
5172      if(j==xmax)
5173       GetTextureTransColG_SPR(&psxVuw[(i<<10)+j],
5174          GETLE16(&psxVuw[((((posY>>16)%TWin.Position.y1)+GlobalTextAddrY+TWin.Position.y0)<<10)+
5175                 ((posX>>16)%TWin.Position.x1)+GlobalTextAddrX+TWin.Position.x0]));
5176     }
5177    if(NextRow_FT4()) return;
5178   }
5179 }
5180
5181 ////////////////////////////////////////////////////////////////////////
5182 // POLY 3/4 G-SHADED
5183 ////////////////////////////////////////////////////////////////////////
5184  
5185 __inline void drawPoly3Gi(short x1,short y1,short x2,short y2,short x3,short y3,int32_t rgb1, int32_t rgb2, int32_t rgb3)
5186 {
5187  int i,j,xmin,xmax,ymin,ymax;
5188  int32_t cR1,cG1,cB1;
5189  int32_t difR,difB,difG,difR2,difB2,difG2;
5190
5191  if(x1>drawW && x2>drawW && x3>drawW) return;
5192  if(y1>drawH && y2>drawH && y3>drawH) return;
5193  if(x1<drawX && x2<drawX && x3<drawX) return;
5194  if(y1<drawY && y2<drawY && y3<drawY) return;
5195  if(drawY>=drawH) return;
5196  if(drawX>=drawW) return; 
5197
5198  if(!SetupSections_G(x1,y1,x2,y2,x3,y3,rgb1,rgb2,rgb3)) return;
5199
5200  ymax=Ymax;
5201
5202  for(ymin=Ymin;ymin<drawY;ymin++)
5203   if(NextRow_G()) return;
5204
5205  difR=delta_right_R;
5206  difG=delta_right_G;
5207  difB=delta_right_B;
5208  difR2=difR<<1;
5209  difG2=difG<<1;
5210  difB2=difB<<1;
5211
5212 #ifdef FASTSOLID
5213
5214  if(!bCheckMask && !DrawSemiTrans && iDither!=2)
5215   {
5216    for (i=ymin;i<=ymax;i++)
5217     {
5218      xmin=(left_x >> 16);
5219      xmax=(right_x >> 16)-1;if(drawW<xmax) xmax=drawW;
5220
5221      if(xmax>=xmin)
5222       {
5223        cR1=left_R;
5224        cG1=left_G;
5225        cB1=left_B;
5226
5227        if(xmin<drawX)
5228         {j=drawX-xmin;xmin=drawX;cR1+=j*difR;cG1+=j*difG;cB1+=j*difB;}
5229
5230        for(j=xmin;j<xmax;j+=2) 
5231         {
5232          PUTLE32(((uint32_t *)&psxVuw[(i<<10)+j]), 
5233             ((((cR1+difR) <<7)&0x7c000000)|(((cG1+difG) << 2)&0x03e00000)|(((cB1+difB)>>3)&0x001f0000)|
5234              (((cR1) >> 9)&0x7c00)|(((cG1) >> 14)&0x03e0)|(((cB1) >> 19)&0x001f))|lSetMask);
5235    
5236          cR1+=difR2;
5237          cG1+=difG2;
5238          cB1+=difB2;
5239         }
5240        if(j==xmax)
5241         PUTLE16(&psxVuw[(i<<10)+j], (((cR1 >> 9)&0x7c00)|((cG1 >> 14)&0x03e0)|((cB1 >> 19)&0x001f))|sSetMask);
5242       }
5243      if(NextRow_G()) return;
5244     }
5245    return;
5246   }
5247
5248 #endif
5249
5250  if(iDither==2)
5251  for (i=ymin;i<=ymax;i++)
5252   {
5253    xmin=(left_x >> 16);
5254    xmax=(right_x >> 16)-1;if(drawW<xmax) xmax=drawW;
5255
5256    if(xmax>=xmin)
5257     {
5258      cR1=left_R;
5259      cG1=left_G;
5260      cB1=left_B;
5261
5262      if(xmin<drawX)
5263       {j=drawX-xmin;xmin=drawX;cR1+=j*difR;cG1+=j*difG;cB1+=j*difB;}
5264
5265      for(j=xmin;j<=xmax;j++) 
5266       {
5267        GetShadeTransCol_Dither(&psxVuw[(i<<10)+j],(cB1>>16),(cG1>>16),(cR1>>16));
5268
5269        cR1+=difR;
5270        cG1+=difG;
5271        cB1+=difB;
5272       }
5273     }
5274    if(NextRow_G()) return;
5275   }
5276  else
5277  for (i=ymin;i<=ymax;i++)
5278   {
5279    xmin=(left_x >> 16);
5280    xmax=(right_x >> 16)-1;if(drawW<xmax) xmax=drawW;
5281
5282    if(xmax>=xmin)
5283     {
5284      cR1=left_R;
5285      cG1=left_G;
5286      cB1=left_B;
5287
5288      if(xmin<drawX)
5289       {j=drawX-xmin;xmin=drawX;cR1+=j*difR;cG1+=j*difG;cB1+=j*difB;}
5290
5291      for(j=xmin;j<=xmax;j++) 
5292       {
5293        GetShadeTransCol(&psxVuw[(i<<10)+j],((cR1 >> 9)&0x7c00)|((cG1 >> 14)&0x03e0)|((cB1 >> 19)&0x001f));
5294
5295        cR1+=difR;
5296        cG1+=difG;
5297        cB1+=difB;
5298       }
5299     }
5300    if(NextRow_G()) return;
5301   }
5302
5303 }
5304
5305 ////////////////////////////////////////////////////////////////////////
5306
5307 void drawPoly3G(int32_t rgb1, int32_t rgb2, int32_t rgb3)
5308 {
5309  drawPoly3Gi(lx0,ly0,lx1,ly1,lx2,ly2,rgb1,rgb2,rgb3);
5310 }
5311
5312 // draw two g-shaded tris for right psx shading emulation
5313
5314 void drawPoly4G(int32_t rgb1, int32_t rgb2, int32_t rgb3, int32_t rgb4)
5315 {
5316  drawPoly3Gi(lx1,ly1,lx3,ly3,lx2,ly2,
5317              rgb2,rgb4,rgb3);
5318  drawPoly3Gi(lx0,ly0,lx1,ly1,lx2,ly2,
5319              rgb1,rgb2,rgb3);
5320 }
5321
5322 ////////////////////////////////////////////////////////////////////////
5323 // POLY 3/4 G-SHADED TEX PAL4
5324 ////////////////////////////////////////////////////////////////////////
5325
5326 void drawPoly3TGEx4(short x1, short y1, short x2, short y2, short x3, short y3, short tx1, short ty1, short tx2, short ty2, short tx3, short ty3, short clX, short clY,int32_t col1, int32_t col2, int32_t col3)
5327 {
5328  int i,j,xmin,xmax,ymin,ymax;
5329  int32_t cR1,cG1,cB1;
5330  int32_t difR,difB,difG,difR2,difB2,difG2;
5331  int32_t difX, difY,difX2, difY2;
5332  int32_t posX,posY,YAdjust,clutP,XAdjust;
5333  short tC1,tC2;
5334
5335  if(x1>drawW && x2>drawW && x3>drawW) return;
5336  if(y1>drawH && y2>drawH && y3>drawH) return;
5337  if(x1<drawX && x2<drawX && x3<drawX) return;
5338  if(y1<drawY && y2<drawY && y3<drawY) return;
5339  if(drawY>=drawH) return;
5340  if(drawX>=drawW) return; 
5341
5342  if(!SetupSections_GT(x1,y1,x2,y2,x3,y3,tx1,ty1,tx2,ty2,tx3,ty3,col1,col2,col3)) return;
5343
5344  ymax=Ymax;
5345
5346  for(ymin=Ymin;ymin<drawY;ymin++)
5347   if(NextRow_GT()) return;
5348
5349  clutP=(clY<<10)+clX;
5350
5351  YAdjust=((GlobalTextAddrY)<<11)+(GlobalTextAddrX<<1);
5352
5353  difR=delta_right_R;
5354  difG=delta_right_G;
5355  difB=delta_right_B;
5356  difR2=difR<<1;
5357  difG2=difG<<1;
5358  difB2=difB<<1;
5359
5360  difX=delta_right_u;difX2=difX<<1;
5361  difY=delta_right_v;difY2=difY<<1;
5362
5363 #ifdef FASTSOLID
5364
5365  if(!bCheckMask && !DrawSemiTrans && !iDither)
5366   {
5367    for (i=ymin;i<=ymax;i++)
5368     {
5369      xmin=((left_x) >> 16);
5370      xmax=((right_x) >> 16)-1; //!!!!!!!!!!!!!
5371      if(drawW<xmax) xmax=drawW;
5372
5373      if(xmax>=xmin)
5374       {
5375        posX=left_u;
5376        posY=left_v;
5377        cR1=left_R;
5378        cG1=left_G;
5379        cB1=left_B;
5380
5381        if(xmin<drawX)
5382         {j=drawX-xmin;xmin=drawX;posX+=j*difX;posY+=j*difY;cR1+=j*difR;cG1+=j*difG;cB1+=j*difB;}
5383
5384        for(j=xmin;j<xmax;j+=2) 
5385         {
5386          XAdjust=(posX>>16);
5387          tC1 = psxVub[((posY>>5)&0xFFFFF800)+YAdjust+(XAdjust>>1)];
5388          tC1=(tC1>>((XAdjust&1)<<2))&0xf;
5389          XAdjust=((posX+difX)>>16);
5390          tC2 = psxVub[(((posY+difY)>>5)&(int32_t)0xFFFFF800)+YAdjust+
5391                       (XAdjust>>1)];
5392          tC2=(tC2>>((XAdjust&1)<<2))&0xf;
5393
5394          GetTextureTransColGX32_S((uint32_t *)&psxVuw[(i<<10)+j],
5395                GETLE16(&psxVuw[clutP+tC1])|
5396                ((int32_t)GETLE16(&psxVuw[clutP+tC2]))<<16,
5397                (cB1>>16)|((cB1+difB)&0xff0000),
5398                (cG1>>16)|((cG1+difG)&0xff0000),
5399                (cR1>>16)|((cR1+difR)&0xff0000));
5400          posX+=difX2;
5401          posY+=difY2;
5402          cR1+=difR2;
5403          cG1+=difG2;
5404          cB1+=difB2;
5405         }
5406        if(j==xmax)
5407         {
5408          XAdjust=(posX>>16);
5409          tC1 = psxVub[((posY>>5)&(int32_t)0xFFFFF800)+YAdjust+(XAdjust>>1)];
5410          tC1=(tC1>>((XAdjust&1)<<2))&0xf;
5411          GetTextureTransColGX_S(&psxVuw[(i<<10)+j], 
5412               GETLE16(&psxVuw[clutP+tC1]),
5413               (cB1>>16),(cG1>>16),(cR1>>16));
5414         }
5415       }
5416      if(NextRow_GT()) 
5417       {
5418        return;
5419       }
5420     }
5421    return;
5422   }
5423
5424 #endif
5425
5426  for (i=ymin;i<=ymax;i++)
5427   {
5428    xmin=(left_x >> 16);
5429    xmax=(right_x >> 16)-1; //!!!!!!!!!!!!!!!!
5430    if(drawW<xmax) xmax=drawW;
5431
5432    if(xmax>=xmin)
5433     {
5434      posX=left_u;
5435      posY=left_v;
5436      cR1=left_R;
5437      cG1=left_G;
5438      cB1=left_B;
5439
5440      if(xmin<drawX)
5441       {j=drawX-xmin;xmin=drawX;posX+=j*difX;posY+=j*difY;cR1+=j*difR;cG1+=j*difG;cB1+=j*difB;}
5442
5443      for(j=xmin;j<=xmax;j++) 
5444       {
5445        XAdjust=(posX>>16);
5446        tC1 = psxVub[((posY>>5)&(int32_t)0xFFFFF800)+YAdjust+(XAdjust>>1)];
5447        tC1=(tC1>>((XAdjust&1)<<2))&0xf;
5448        if(iDither)
5449         GetTextureTransColGX_Dither(&psxVuw[(i<<10)+j], 
5450             GETLE16(&psxVuw[clutP+tC1]),
5451             (cB1>>16),(cG1>>16),(cR1>>16));
5452        else
5453         GetTextureTransColGX(&psxVuw[(i<<10)+j], 
5454             GETLE16(&psxVuw[clutP+tC1]),
5455             (cB1>>16),(cG1>>16),(cR1>>16));
5456        posX+=difX;
5457        posY+=difY;
5458        cR1+=difR;
5459        cG1+=difG;
5460        cB1+=difB;
5461       }
5462     }
5463    if(NextRow_GT()) 
5464     {
5465      return;
5466     }
5467   }
5468 }
5469
5470 ////////////////////////////////////////////////////////////////////////
5471
5472 void drawPoly3TGEx4_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,int32_t col1, int32_t col2, int32_t col3)
5473 {
5474  int i,j,xmin,xmax,ymin,ymax,n_xi,n_yi,TXV;
5475  int32_t cR1,cG1,cB1;
5476  int32_t difR,difB,difG,difR2,difB2,difG2;
5477  int32_t difX, difY,difX2, difY2;
5478  int32_t posX,posY,YAdjust,clutP,XAdjust;
5479  short tC1,tC2;
5480
5481  if(x1>drawW && x2>drawW && x3>drawW) return;
5482  if(y1>drawH && y2>drawH && y3>drawH) return;
5483  if(x1<drawX && x2<drawX && x3<drawX) return;
5484  if(y1<drawY && y2<drawY && y3<drawY) return;
5485  if(drawY>=drawH) return;
5486  if(drawX>=drawW) return; 
5487
5488  if(!SetupSections_GT(x1,y1,x2,y2,x3,y3,tx1,ty1,tx2,ty2,tx3,ty3,col1,col2,col3)) return;
5489
5490  ymax=Ymax;
5491
5492  for(ymin=Ymin;ymin<drawY;ymin++)
5493   if(NextRow_GT()) return;
5494
5495  clutP=(clY<<10)+clX;
5496
5497  YAdjust=(GlobalTextAddrY<<10)+GlobalTextAddrX;
5498
5499  difR=delta_right_R;
5500  difG=delta_right_G;
5501  difB=delta_right_B;
5502  difR2=difR<<1;
5503  difG2=difG<<1;
5504  difB2=difB<<1;
5505
5506  difX=delta_right_u;difX2=difX<<1;
5507  difY=delta_right_v;difY2=difY<<1;
5508
5509 #ifdef FASTSOLID
5510
5511  if(!bCheckMask && !DrawSemiTrans && !iDither)
5512   {
5513    for (i=ymin;i<=ymax;i++)
5514     {
5515      xmin=((left_x) >> 16);
5516      xmax=((right_x) >> 16)-1; //!!!!!!!!!!!!!
5517      if(drawW<xmax) xmax=drawW;
5518
5519      if(xmax>=xmin)
5520       {
5521        posX=left_u;
5522        posY=left_v;
5523        cR1=left_R;
5524        cG1=left_G;
5525        cB1=left_B;
5526
5527        if(xmin<drawX)
5528         {j=drawX-xmin;xmin=drawX;posX+=j*difX;posY+=j*difY;cR1+=j*difR;cG1+=j*difG;cB1+=j*difB;}
5529
5530        for(j=xmin;j<xmax;j+=2) 
5531         {
5532          XAdjust=(posX>>16);
5533
5534          TXV=posY>>16;
5535          n_xi = ( ( XAdjust >> 2 ) & ~0x3c ) + ( ( TXV << 2 ) & 0x3c );
5536          n_yi = ( TXV & ~0xf ) + ( ( XAdjust >> 4 ) & 0xf );
5537  
5538          tC1= (GETLE16(&psxVuw[(n_yi<<10)+YAdjust+n_xi]) >> ((XAdjust & 0x03)<<2)) & 0x0f ;
5539
5540          XAdjust=((posX+difX)>>16);
5541
5542          TXV=(posY+difY)>>16;
5543          n_xi = ( ( XAdjust >> 2 ) & ~0x3c ) + ( ( TXV << 2 ) & 0x3c );
5544          n_yi = ( TXV & ~0xf ) + ( ( XAdjust >> 4 ) & 0xf );
5545
5546          tC2= (GETLE16(&psxVuw[(n_yi<<10)+YAdjust+n_xi]) >> ((XAdjust & 0x03)<<2)) & 0x0f ;
5547
5548          GetTextureTransColGX32_S((uint32_t *)&psxVuw[(i<<10)+j],
5549                GETLE16(&psxVuw[clutP+tC1])|
5550                ((int32_t)GETLE16(&psxVuw[clutP+tC2]))<<16,
5551                (cB1>>16)|((cB1+difB)&0xff0000),
5552                (cG1>>16)|((cG1+difG)&0xff0000),
5553                (cR1>>16)|((cR1+difR)&0xff0000));
5554          posX+=difX2;
5555          posY+=difY2;
5556          cR1+=difR2;
5557          cG1+=difG2;
5558          cB1+=difB2;
5559         }
5560        if(j==xmax)
5561         {
5562          XAdjust=(posX>>16);
5563
5564          TXV=posY>>16;
5565          n_xi = ( ( XAdjust >> 2 ) & ~0x3c ) + ( ( TXV << 2 ) & 0x3c );
5566          n_yi = ( TXV & ~0xf ) + ( ( XAdjust >> 4 ) & 0xf );
5567
5568          tC1= (GETLE16(&psxVuw[(n_yi<<10)+YAdjust+n_xi]) >> ((XAdjust & 0x03)<<2)) & 0x0f ;
5569
5570          GetTextureTransColGX_S(&psxVuw[(i<<10)+j], 
5571               GETLE16(&psxVuw[clutP+tC1]),
5572               (cB1>>16),(cG1>>16),(cR1>>16));
5573         }
5574       }
5575      if(NextRow_GT()) 
5576       {
5577        return;
5578       }
5579     }
5580    return;
5581   }
5582
5583 #endif
5584
5585  for (i=ymin;i<=ymax;i++)
5586   {
5587    xmin=(left_x >> 16);
5588    xmax=(right_x >> 16)-1; //!!!!!!!!!!!!!!!!
5589    if(drawW<xmax) xmax=drawW;
5590
5591    if(xmax>=xmin)
5592     {
5593      posX=left_u;
5594      posY=left_v;
5595      cR1=left_R;
5596      cG1=left_G;
5597      cB1=left_B;
5598
5599      if(xmin<drawX)
5600       {j=drawX-xmin;xmin=drawX;posX+=j*difX;posY+=j*difY;cR1+=j*difR;cG1+=j*difG;cB1+=j*difB;}
5601
5602      for(j=xmin;j<=xmax;j++) 
5603       {
5604        XAdjust=(posX>>16);
5605
5606        TXV=posY>>16;
5607        n_xi = ( ( XAdjust >> 2 ) & ~0x3c ) + ( ( TXV << 2 ) & 0x3c );
5608        n_yi = ( TXV & ~0xf ) + ( ( XAdjust >> 4 ) & 0xf );
5609
5610        tC1= (GETLE16(&psxVuw[(n_yi<<10)+YAdjust+n_xi]) >> ((XAdjust & 0x03)<<2)) & 0x0f ;
5611
5612        if(iDither)
5613         GetTextureTransColGX_Dither(&psxVuw[(i<<10)+j], 
5614             GETLE16(&psxVuw[clutP+tC1]),
5615             (cB1>>16),(cG1>>16),(cR1>>16));
5616        else
5617         GetTextureTransColGX(&psxVuw[(i<<10)+j], 
5618             GETLE16(&psxVuw[clutP+tC1]),
5619             (cB1>>16),(cG1>>16),(cR1>>16));
5620        posX+=difX;
5621        posY+=difY;
5622        cR1+=difR;
5623        cG1+=difG;
5624        cB1+=difB;
5625       }
5626     }
5627    if(NextRow_GT()) 
5628     {
5629      return;
5630     }
5631   }
5632 }
5633
5634 ////////////////////////////////////////////////////////////////////////
5635
5636 void drawPoly3TGEx4_TW(short x1, short y1, short x2, short y2, short x3, short y3, short tx1, short ty1, short tx2, short ty2, short tx3, short ty3, short clX, short clY,int32_t col1, int32_t col2, int32_t col3)
5637 {
5638  int i,j,xmin,xmax,ymin,ymax;
5639  int32_t cR1,cG1,cB1;
5640  int32_t difR,difB,difG,difR2,difB2,difG2;
5641  int32_t difX, difY,difX2, difY2;
5642  int32_t posX,posY,YAdjust,clutP,XAdjust;
5643  short tC1,tC2;
5644
5645  if(x1>drawW && x2>drawW && x3>drawW) return;
5646  if(y1>drawH && y2>drawH && y3>drawH) return;
5647  if(x1<drawX && x2<drawX && x3<drawX) return;
5648  if(y1<drawY && y2<drawY && y3<drawY) return;
5649  if(drawY>=drawH) return;
5650  if(drawX>=drawW) return; 
5651
5652  if(!SetupSections_GT(x1,y1,x2,y2,x3,y3,tx1,ty1,tx2,ty2,tx3,ty3,col1,col2,col3)) return;
5653
5654  ymax=Ymax;
5655
5656  for(ymin=Ymin;ymin<drawY;ymin++)
5657   if(NextRow_GT()) return;
5658
5659  clutP=(clY<<10)+clX;
5660
5661  YAdjust=((GlobalTextAddrY)<<11)+(GlobalTextAddrX<<1);
5662  YAdjust+=(TWin.Position.y0<<11)+(TWin.Position.x0>>1);
5663
5664  difR=delta_right_R;
5665  difG=delta_right_G;
5666  difB=delta_right_B;
5667  difR2=difR<<1;
5668  difG2=difG<<1;
5669  difB2=difB<<1;
5670
5671  difX=delta_right_u;difX2=difX<<1;
5672  difY=delta_right_v;difY2=difY<<1;
5673
5674 #ifdef FASTSOLID
5675
5676  if(!bCheckMask && !DrawSemiTrans && !iDither)
5677   {
5678    for (i=ymin;i<=ymax;i++)
5679     {
5680      xmin=((left_x) >> 16);
5681      xmax=((right_x) >> 16)-1; //!!!!!!!!!!!!!
5682      if(drawW<xmax) xmax=drawW;
5683
5684      if(xmax>=xmin)
5685       {
5686        posX=left_u;
5687        posY=left_v;
5688        cR1=left_R;
5689        cG1=left_G;
5690        cB1=left_B;
5691
5692        if(xmin<drawX)
5693         {j=drawX-xmin;xmin=drawX;posX+=j*difX;posY+=j*difY;cR1+=j*difR;cG1+=j*difG;cB1+=j*difB;}
5694
5695        for(j=xmin;j<xmax;j+=2) 
5696         {
5697          XAdjust=(posX>>16)%TWin.Position.x1;
5698          tC1 = psxVub[(((posY>>16)%TWin.Position.y1)<<11)+
5699                       YAdjust+(XAdjust>>1)];
5700          tC1=(tC1>>((XAdjust&1)<<2))&0xf;
5701          XAdjust=((posX+difX)>>16)%TWin.Position.x1;
5702          tC2 = psxVub[((((posY+difY)>>16)%TWin.Position.y1)<<11)+
5703                       YAdjust+(XAdjust>>1)];
5704          tC2=(tC2>>((XAdjust&1)<<2))&0xf;
5705          GetTextureTransColGX32_S((uint32_t *)&psxVuw[(i<<10)+j],
5706               GETLE16(&psxVuw[clutP+tC1])|
5707               ((int32_t)GETLE16(&psxVuw[clutP+tC2]))<<16,
5708               (cB1>>16)|((cB1+difB)&0xff0000),
5709               (cG1>>16)|((cG1+difG)&0xff0000),
5710               (cR1>>16)|((cR1+difR)&0xff0000));
5711          posX+=difX2;
5712          posY+=difY2;
5713          cR1+=difR2;
5714          cG1+=difG2;
5715          cB1+=difB2;
5716         }
5717        if(j==xmax)
5718         {
5719          XAdjust=(posX>>16)%TWin.Position.x1;
5720          tC1 = psxVub[(((posY>>16)%TWin.Position.y1)<<11)+
5721                        YAdjust+(XAdjust>>1)];
5722          tC1=(tC1>>((XAdjust&1)<<2))&0xf;
5723          GetTextureTransColGX_S(&psxVuw[(i<<10)+j], 
5724              GETLE16(&psxVuw[clutP+tC1]),
5725              (cB1>>16),(cG1>>16),(cR1>>16));
5726         }
5727       }
5728      if(NextRow_GT()) 
5729       {
5730        return;
5731       }
5732     }
5733    return;
5734   }
5735
5736 #endif
5737
5738  for (i=ymin;i<=ymax;i++)
5739   {
5740    xmin=(left_x >> 16);
5741    xmax=(right_x >> 16)-1; //!!!!!!!!!!!!!!!!
5742    if(drawW<xmax) xmax=drawW;
5743
5744    if(xmax>=xmin)
5745     {
5746      posX=left_u;
5747      posY=left_v;
5748      cR1=left_R;
5749      cG1=left_G;
5750      cB1=left_B;
5751
5752      if(xmin<drawX)
5753       {j=drawX-xmin;xmin=drawX;posX+=j*difX;posY+=j*difY;cR1+=j*difR;cG1+=j*difG;cB1+=j*difB;}
5754
5755      for(j=xmin;j<=xmax;j++) 
5756       {
5757        XAdjust=(posX>>16)%TWin.Position.x1;
5758        tC1 = psxVub[(((posY>>16)%TWin.Position.y1)<<11)+
5759                     YAdjust+(XAdjust>>1)];
5760        tC1=(tC1>>((XAdjust&1)<<2))&0xf;
5761        if(iDither)
5762         GetTextureTransColGX_Dither(&psxVuw[(i<<10)+j], 
5763             GETLE16(&psxVuw[clutP+tC1]),
5764             (cB1>>16),(cG1>>16),(cR1>>16));
5765        else
5766         GetTextureTransColGX(&psxVuw[(i<<10)+j], 
5767             GETLE16(&psxVuw[clutP+tC1]),
5768             (cB1>>16),(cG1>>16),(cR1>>16));
5769        posX+=difX;
5770        posY+=difY;
5771        cR1+=difR;
5772        cG1+=difG;
5773        cB1+=difB;
5774       }
5775     }
5776    if(NextRow_GT()) 
5777     {
5778      return;
5779     }
5780   }
5781 }
5782
5783 ////////////////////////////////////////////////////////////////////////
5784
5785 // note: the psx is doing g-shaded quads as two g-shaded tris,
5786 // like the following func... sadly texturing is not 100%
5787 // correct that way, so small texture distortions can 
5788 // happen... 
5789
5790 void drawPoly4TGEx4_TRI_IL(short x1, short y1, short x2, short y2, short x3, short y3, short x4, short y4,
5791                     short tx1, short ty1, short tx2, short ty2, short tx3, short ty3, short tx4, short ty4,
5792                     short clX, short clY,
5793                     int32_t col1, int32_t col2, int32_t col3, int32_t col4)
5794 {
5795  drawPoly3TGEx4_IL(x2,y2,x3,y3,x4,y4,
5796                    tx2,ty2,tx3,ty3,tx4,ty4,
5797                    clX,clY,
5798                    col2,col4,col3);
5799  drawPoly3TGEx4_IL(x1,y1,x2,y2,x4,y4,
5800                    tx1,ty1,tx2,ty2,tx4,ty4,
5801                    clX,clY,
5802                    col1,col2,col3);
5803 }
5804
5805 #ifdef POLYQUAD3GT
5806
5807 void drawPoly4TGEx4_TRI(short x1, short y1, short x2, short y2, short x3, short y3, short x4, short y4, 
5808                     short tx1, short ty1, short tx2, short ty2, short tx3, short ty3, short tx4, short ty4, 
5809                     short clX, short clY,
5810                     int32_t col1, int32_t col2, int32_t col3, int32_t col4)
5811 {
5812  drawPoly3TGEx4(x2,y2,x3,y3,x4,y4,
5813                 tx2,ty2,tx3,ty3,tx4,ty4,
5814                 clX,clY,
5815                 col2,col4,col3);
5816  drawPoly3TGEx4(x1,y1,x2,y2,x4,y4,
5817                 tx1,ty1,tx2,ty2,tx4,ty4,
5818                 clX,clY,
5819                 col1,col2,col3);
5820 }
5821
5822 #endif
5823                
5824 ////////////////////////////////////////////////////////////////////////
5825
5826 void drawPoly4TGEx4(short x1, short y1, short x2, short y2, short x3, short y3, short x4, short y4, 
5827                     short tx1, short ty1, short tx2, short ty2, short tx3, short ty3, short tx4, short ty4, 
5828                     short clX, short clY,
5829                     int32_t col1, int32_t col2, int32_t col4, int32_t col3)
5830 {
5831  int32_t num; 
5832  int32_t i,j,xmin,xmax,ymin,ymax;
5833  int32_t cR1,cG1,cB1;
5834  int32_t difR,difB,difG,difR2,difB2,difG2;
5835  int32_t difX, difY, difX2, difY2;
5836  int32_t posX,posY,YAdjust,clutP,XAdjust;
5837  short tC1,tC2;
5838
5839  if(x1>drawW && x2>drawW && x3>drawW && x4>drawW) return;
5840  if(y1>drawH && y2>drawH && y3>drawH && y4>drawH) return;
5841  if(x1<drawX && x2<drawX && x3<drawX && x4<drawX) return;
5842  if(y1<drawY && y2<drawY && y3<drawY && y4<drawY) return;
5843  if(drawY>=drawH) return;
5844  if(drawX>=drawW) return; 
5845
5846  if(!SetupSections_GT4(x1,y1,x2,y2,x3,y3,x4,y4,tx1,ty1,tx2,ty2,tx3,ty3,tx4,ty4,col1,col2,col3,col4)) return;
5847
5848  ymax=Ymax;
5849
5850  for(ymin=Ymin;ymin<drawY;ymin++)
5851   if(NextRow_GT4()) return;
5852
5853  clutP=(clY<<10)+clX;
5854
5855  YAdjust=((GlobalTextAddrY)<<11)+(GlobalTextAddrX<<1);
5856
5857
5858 #ifdef FASTSOLID
5859
5860  if(!bCheckMask && !DrawSemiTrans && !iDither)
5861   {
5862    for (i=ymin;i<=ymax;i++)
5863     {
5864      xmin=(left_x >> 16);
5865      xmax=(right_x >> 16);
5866
5867      if(xmax>=xmin)
5868       {
5869        posX=left_u;
5870        posY=left_v;
5871
5872        num=(xmax-xmin);
5873        if(num==0) num=1;
5874        difX=(right_u-posX)/num;
5875        difY=(right_v-posY)/num;
5876        difX2=difX<<1;
5877        difY2=difY<<1;
5878
5879        cR1=left_R;
5880        cG1=left_G;
5881        cB1=left_B;
5882        difR=(right_R-cR1)/num;
5883        difG=(right_G-cG1)/num;
5884        difB=(right_B-cB1)/num;
5885        difR2=difR<<1;
5886        difG2=difG<<1;
5887        difB2=difB<<1;
5888
5889        if(xmin<drawX)
5890         {j=drawX-xmin;xmin=drawX;posX+=j*difX;posY+=j*difY;cR1+=j*difR;cG1+=j*difG;cB1+=j*difB;}
5891        xmax--;if(drawW<xmax) xmax=drawW;
5892
5893        for(j=xmin;j<xmax;j+=2)
5894         {
5895          XAdjust=(posX>>16);
5896          tC1 = psxVub[((posY>>5)&(int32_t)0xFFFFF800)+YAdjust+(XAdjust>>1)];
5897          tC1=(tC1>>((XAdjust&1)<<2))&0xf;
5898          XAdjust=((posX+difX)>>16);
5899          tC2 = psxVub[(((posY+difY)>>5)&(int32_t)0xFFFFF800)+YAdjust+
5900                        (XAdjust>>1)];
5901          tC2=(tC2>>((XAdjust&1)<<2))&0xf;
5902
5903          GetTextureTransColGX32_S((uint32_t *)&psxVuw[(i<<10)+j],
5904               GETLE16(&psxVuw[clutP+tC1])|
5905               ((int32_t)GETLE16(&psxVuw[clutP+tC2]))<<16,
5906               (cB1>>16)|((cB1+difB)&0xff0000),
5907               (cG1>>16)|((cG1+difG)&0xff0000),
5908               (cR1>>16)|((cR1+difR)&0xff0000));
5909          posX+=difX2;
5910          posY+=difY2;
5911          cR1+=difR2;
5912          cG1+=difG2;
5913          cB1+=difB2;
5914         }
5915        if(j==xmax)
5916         {
5917          XAdjust=(posX>>16);
5918          tC1 = psxVub[((posY>>5)&(int32_t)0xFFFFF800)+YAdjust+
5919                       (XAdjust>>1)];
5920          tC1=(tC1>>((XAdjust&1)<<2))&0xf;
5921
5922          GetTextureTransColGX_S(&psxVuw[(i<<10)+j], 
5923              GETLE16(&psxVuw[clutP+tC1]),
5924              (cB1>>16),(cG1>>16),(cR1>>16));
5925         }
5926       }
5927      if(NextRow_GT4()) return;
5928     }
5929    return;
5930   }
5931
5932 #endif
5933
5934  for (i=ymin;i<=ymax;i++)
5935   {
5936    xmin=(left_x >> 16);
5937    xmax=(right_x >> 16);
5938
5939    if(xmax>=xmin)
5940     {
5941      posX=left_u;
5942      posY=left_v;
5943
5944      num=(xmax-xmin);
5945      if(num==0) num=1;
5946      difX=(right_u-posX)/num;
5947      difY=(right_v-posY)/num;
5948      difX2=difX<<1;
5949      difY2=difY<<1;
5950
5951      cR1=left_R;
5952      cG1=left_G;
5953      cB1=left_B;
5954      difR=(right_R-cR1)/num;
5955      difG=(right_G-cG1)/num;
5956      difB=(right_B-cB1)/num;
5957      difR2=difR<<1;
5958      difG2=difG<<1;
5959      difB2=difB<<1;
5960
5961      if(xmin<drawX)
5962       {j=drawX-xmin;xmin=drawX;posX+=j*difX;posY+=j*difY;cR1+=j*difR;cG1+=j*difG;cB1+=j*difB;}
5963      xmax--;if(drawW<xmax) xmax=drawW;
5964
5965      for(j=xmin;j<=xmax;j++)
5966       {
5967        XAdjust=(posX>>16);
5968        tC1 = psxVub[((posY>>5)&(int32_t)0xFFFFF800)+YAdjust+
5969                     (XAdjust>>1)];
5970        tC1=(tC1>>((XAdjust&1)<<2))&0xf;
5971        if(iDither)
5972         GetTextureTransColGX_Dither(&psxVuw[(i<<10)+j], 
5973            GETLE16(&psxVuw[clutP+tC1]),
5974            (cB1>>16),(cG1>>16),(cR1>>16));
5975        else
5976         GetTextureTransColGX(&psxVuw[(i<<10)+j], 
5977            GETLE16(&psxVuw[clutP+tC1]),
5978            (cB1>>16),(cG1>>16),(cR1>>16));
5979        posX+=difX;
5980        posY+=difY;
5981        cR1+=difR;
5982        cG1+=difG;
5983        cB1+=difB;
5984       }
5985     }
5986    if(NextRow_GT4()) return;
5987   }
5988 }
5989
5990 ////////////////////////////////////////////////////////////////////////
5991
5992 void drawPoly4TGEx4_TW(short x1, short y1, short x2, short y2, short x3, short y3, short x4, short y4, 
5993                     short tx1, short ty1, short tx2, short ty2, short tx3, short ty3, short tx4, short ty4, 
5994                     short clX, short clY,
5995                     int32_t col1, int32_t col2, int32_t col3, int32_t col4)
5996 {
5997  drawPoly3TGEx4_TW(x2,y2,x3,y3,x4,y4,
5998                    tx2,ty2,tx3,ty3,tx4,ty4,
5999                    clX,clY,
6000                    col2,col4,col3);
6001
6002  drawPoly3TGEx4_TW(x1,y1,x2,y2,x4,y4,
6003                    tx1,ty1,tx2,ty2,tx4,ty4,
6004                    clX,clY,
6005                    col1,col2,col3);
6006 }
6007
6008 ////////////////////////////////////////////////////////////////////////
6009 // POLY 3/4 G-SHADED TEX PAL8
6010 ////////////////////////////////////////////////////////////////////////
6011
6012 void drawPoly3TGEx8(short x1, short y1, short x2, short y2, short x3, short y3, short tx1, short ty1, short tx2, short ty2, short tx3, short ty3, short clX, short clY,int32_t col1, int32_t col2, int32_t col3)
6013 {
6014  int i,j,xmin,xmax,ymin,ymax;
6015  int32_t cR1,cG1,cB1;
6016  int32_t difR,difB,difG,difR2,difB2,difG2;
6017  int32_t difX, difY,difX2, difY2;
6018  int32_t posX,posY,YAdjust,clutP;
6019  short tC1,tC2;
6020
6021  if(x1>drawW && x2>drawW && x3>drawW) return;
6022  if(y1>drawH && y2>drawH && y3>drawH) return;
6023  if(x1<drawX && x2<drawX && x3<drawX) return;
6024  if(y1<drawY && y2<drawY && y3<drawY) return;
6025  if(drawY>=drawH) return;
6026  if(drawX>=drawW) return; 
6027
6028  if(!SetupSections_GT(x1,y1,x2,y2,x3,y3,tx1,ty1,tx2,ty2,tx3,ty3,col1,col2,col3)) return;
6029
6030  ymax=Ymax;
6031
6032  for(ymin=Ymin;ymin<drawY;ymin++)
6033   if(NextRow_GT()) return;
6034
6035  clutP=(clY<<10)+clX;
6036
6037  YAdjust=((GlobalTextAddrY)<<11)+(GlobalTextAddrX<<1);
6038
6039  difR=delta_right_R;
6040  difG=delta_right_G;
6041  difB=delta_right_B;
6042  difR2=difR<<1;
6043  difG2=difG<<1;
6044  difB2=difB<<1;
6045  difX=delta_right_u;difX2=difX<<1;
6046  difY=delta_right_v;difY2=difY<<1;
6047
6048 #ifdef FASTSOLID
6049
6050  if(!bCheckMask && !DrawSemiTrans && !iDither)
6051   {
6052    for (i=ymin;i<=ymax;i++)
6053     {
6054      xmin=(left_x >> 16);
6055      xmax=(right_x >> 16)-1; // !!!!!!!!!!!!!
6056      if(drawW<xmax) xmax=drawW;
6057
6058      if(xmax>=xmin)
6059       {
6060        posX=left_u;
6061        posY=left_v;
6062        cR1=left_R;
6063        cG1=left_G;
6064        cB1=left_B;
6065
6066        if(xmin<drawX)
6067         {j=drawX-xmin;xmin=drawX;posX+=j*difX;posY+=j*difY;cR1+=j*difR;cG1+=j*difG;cB1+=j*difB;}
6068
6069        for(j=xmin;j<xmax;j+=2)
6070         {
6071          tC1 = psxVub[((posY>>5)&(int32_t)0xFFFFF800)+YAdjust+((posX>>16))];
6072          tC2 = psxVub[(((posY+difY)>>5)&(int32_t)0xFFFFF800)+YAdjust+
6073                       (((posX+difX)>>16))];
6074          GetTextureTransColGX32_S((uint32_t *)&psxVuw[(i<<10)+j],
6075               GETLE16(&psxVuw[clutP+tC1])|
6076               ((int32_t)GETLE16(&psxVuw[clutP+tC2]))<<16,
6077               (cB1>>16)|((cB1+difB)&0xff0000),
6078               (cG1>>16)|((cG1+difG)&0xff0000),
6079               (cR1>>16)|((cR1+difR)&0xff0000));
6080          posX+=difX2;
6081          posY+=difY2;
6082          cR1+=difR2;
6083          cG1+=difG2;
6084          cB1+=difB2;
6085         }
6086        if(j==xmax)
6087         {
6088          tC1 = psxVub[((posY>>5)&(int32_t)0xFFFFF800)+YAdjust+((posX>>16))];
6089          GetTextureTransColGX_S(&psxVuw[(i<<10)+j], 
6090               GETLE16(&psxVuw[clutP+tC1]),
6091               (cB1>>16),(cG1>>16),(cR1>>16));
6092         }
6093       }
6094      if(NextRow_GT()) 
6095       {
6096        return;
6097       }
6098     }
6099    return;
6100   }
6101
6102 #endif
6103
6104  for (i=ymin;i<=ymax;i++)
6105   {
6106    xmin=(left_x >> 16);
6107    xmax=(right_x >> 16)-1; //!!!!!!!!!!!!!!!!!!!!!!!
6108    if(drawW<xmax) xmax=drawW;
6109
6110    if(xmax>=xmin)
6111     {
6112      posX=left_u;
6113      posY=left_v;
6114      cR1=left_R;
6115      cG1=left_G;
6116      cB1=left_B;
6117
6118      if(xmin<drawX)
6119       {j=drawX-xmin;xmin=drawX;posX+=j*difX;posY+=j*difY;cR1+=j*difR;cG1+=j*difG;cB1+=j*difB;}
6120
6121      for(j=xmin;j<=xmax;j++)
6122       {
6123        tC1 = psxVub[((posY>>5)&(int32_t)0xFFFFF800)+YAdjust+((posX>>16))];
6124        if(iDither)
6125         GetTextureTransColGX_Dither(&psxVuw[(i<<10)+j], 
6126             GETLE16(&psxVuw[clutP+tC1]),
6127             (cB1>>16),(cG1>>16),(cR1>>16));
6128        else
6129         GetTextureTransColGX(&psxVuw[(i<<10)+j], 
6130             GETLE16(&psxVuw[clutP+tC1]),
6131             (cB1>>16),(cG1>>16),(cR1>>16));
6132        posX+=difX;
6133        posY+=difY;
6134        cR1+=difR;
6135        cG1+=difG;
6136        cB1+=difB;
6137       }
6138     }
6139    if(NextRow_GT()) 
6140     {
6141      return;
6142     }
6143   }
6144 }
6145
6146 ////////////////////////////////////////////////////////////////////////
6147
6148 void drawPoly3TGEx8_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,int32_t col1, int32_t col2, int32_t col3)
6149 {
6150  int i,j,xmin,xmax,ymin,ymax,n_xi,n_yi,TXV,TXU;
6151  int32_t cR1,cG1,cB1;
6152  int32_t difR,difB,difG,difR2,difB2,difG2;
6153  int32_t difX, difY,difX2, difY2;
6154  int32_t posX,posY,YAdjust,clutP;
6155  short tC1,tC2;
6156
6157  if(x1>drawW && x2>drawW && x3>drawW) return;
6158  if(y1>drawH && y2>drawH && y3>drawH) return;
6159  if(x1<drawX && x2<drawX && x3<drawX) return;
6160  if(y1<drawY && y2<drawY && y3<drawY) return;
6161  if(drawY>=drawH) return;
6162  if(drawX>=drawW) return; 
6163
6164  if(!SetupSections_GT(x1,y1,x2,y2,x3,y3,tx1,ty1,tx2,ty2,tx3,ty3,col1,col2,col3)) return;
6165
6166  ymax=Ymax;
6167
6168  for(ymin=Ymin;ymin<drawY;ymin++)
6169   if(NextRow_GT()) return;
6170
6171  clutP=(clY<<10)+clX;
6172
6173  YAdjust=(GlobalTextAddrY<<10)+GlobalTextAddrX;
6174
6175  difR=delta_right_R;
6176  difG=delta_right_G;
6177  difB=delta_right_B;
6178  difR2=difR<<1;
6179  difG2=difG<<1;
6180  difB2=difB<<1;
6181  difX=delta_right_u;difX2=difX<<1;
6182  difY=delta_right_v;difY2=difY<<1;
6183
6184 #ifdef FASTSOLID
6185
6186  if(!bCheckMask && !DrawSemiTrans && !iDither)
6187   {
6188    for (i=ymin;i<=ymax;i++)
6189     {
6190      xmin=(left_x >> 16);
6191      xmax=(right_x >> 16)-1; // !!!!!!!!!!!!!
6192      if(drawW<xmax) xmax=drawW;
6193
6194      if(xmax>=xmin)
6195       {
6196        posX=left_u;
6197        posY=left_v;
6198        cR1=left_R;
6199        cG1=left_G;
6200        cB1=left_B;
6201
6202        if(xmin<drawX)
6203         {j=drawX-xmin;xmin=drawX;posX+=j*difX;posY+=j*difY;cR1+=j*difR;cG1+=j*difG;cB1+=j*difB;}
6204
6205        for(j=xmin;j<xmax;j+=2)
6206         {
6207          TXU=posX>>16;
6208          TXV=posY>>16;
6209          n_xi = ( ( TXU >> 1 ) & ~0x78 ) + ( ( TXU << 2 ) & 0x40 ) + ( ( TXV << 3 ) & 0x38 );
6210          n_yi = ( TXV & ~0x7 ) + ( ( TXU >> 5 ) & 0x7 );
6211
6212          tC1= (GETLE16(&psxVuw[(n_yi<<10)+YAdjust+n_xi]) >> ((TXU & 0x01)<<3)) & 0xff;
6213
6214          TXU=(posX+difX)>>16;
6215          TXV=(posY+difY)>>16;
6216          n_xi = ( ( TXU >> 1 ) & ~0x78 ) + ( ( TXU << 2 ) & 0x40 ) + ( ( TXV << 3 ) & 0x38 );
6217          n_yi = ( TXV & ~0x7 ) + ( ( TXU >> 5 ) & 0x7 );
6218
6219          tC2= (GETLE16(&psxVuw[(n_yi<<10)+YAdjust+n_xi]) >> ((TXU & 0x01)<<3)) & 0xff;
6220
6221          GetTextureTransColGX32_S((uint32_t *)&psxVuw[(i<<10)+j],
6222               GETLE16(&psxVuw[clutP+tC1])|
6223               ((int32_t)GETLE16(&psxVuw[clutP+tC2]))<<16,
6224               (cB1>>16)|((cB1+difB)&0xff0000),
6225               (cG1>>16)|((cG1+difG)&0xff0000),
6226               (cR1>>16)|((cR1+difR)&0xff0000));
6227          posX+=difX2;
6228          posY+=difY2;
6229          cR1+=difR2;
6230          cG1+=difG2;
6231          cB1+=difB2;
6232         }
6233        if(j==xmax)
6234         {
6235          TXU=posX>>16;
6236          TXV=posY>>16;
6237          n_xi = ( ( TXU >> 1 ) & ~0x78 ) + ( ( TXU << 2 ) & 0x40 ) + ( ( TXV << 3 ) & 0x38 );
6238          n_yi = ( TXV & ~0x7 ) + ( ( TXU >> 5 ) & 0x7 );
6239
6240          tC1= (GETLE16(&psxVuw[(n_yi<<10)+YAdjust+n_xi]) >> ((TXU & 0x01)<<3)) & 0xff;
6241
6242          GetTextureTransColGX_S(&psxVuw[(i<<10)+j], 
6243               GETLE16(&psxVuw[clutP+tC1]),
6244               (cB1>>16),(cG1>>16),(cR1>>16));
6245         }
6246       }
6247      if(NextRow_GT()) 
6248       {
6249        return;
6250       }
6251     }
6252    return;
6253   }
6254
6255 #endif
6256
6257  for (i=ymin;i<=ymax;i++)
6258   {
6259    xmin=(left_x >> 16);
6260    xmax=(right_x >> 16)-1; //!!!!!!!!!!!!!!!!!!!!!!!
6261    if(drawW<xmax) xmax=drawW;
6262
6263    if(xmax>=xmin)
6264     {
6265      posX=left_u;
6266      posY=left_v;
6267      cR1=left_R;
6268      cG1=left_G;
6269      cB1=left_B;
6270
6271      if(xmin<drawX)
6272       {j=drawX-xmin;xmin=drawX;posX+=j*difX;posY+=j*difY;cR1+=j*difR;cG1+=j*difG;cB1+=j*difB;}
6273
6274      for(j=xmin;j<=xmax;j++)
6275       {
6276        TXU=posX>>16;
6277        TXV=posY>>16;
6278        n_xi = ( ( TXU >> 1 ) & ~0x78 ) + ( ( TXU << 2 ) & 0x40 ) + ( ( TXV << 3 ) & 0x38 );
6279        n_yi = ( TXV & ~0x7 ) + ( ( TXU >> 5 ) & 0x7 );
6280
6281        tC1= (GETLE16(&psxVuw[(n_yi<<10)+YAdjust+n_xi]) >> ((TXU & 0x01)<<3)) & 0xff;
6282
6283        if(iDither)
6284         GetTextureTransColGX_Dither(&psxVuw[(i<<10)+j], 
6285             GETLE16(&psxVuw[clutP+tC1]),
6286             (cB1>>16),(cG1>>16),(cR1>>16));
6287        else
6288         GetTextureTransColGX(&psxVuw[(i<<10)+j], 
6289             GETLE16(&psxVuw[clutP+tC1]),
6290             (cB1>>16),(cG1>>16),(cR1>>16));
6291        posX+=difX;
6292        posY+=difY;
6293        cR1+=difR;
6294        cG1+=difG;
6295        cB1+=difB;
6296       }
6297     }
6298    if(NextRow_GT()) 
6299     {
6300      return;
6301     }
6302   }
6303 }
6304
6305 ////////////////////////////////////////////////////////////////////////
6306
6307 void drawPoly3TGEx8_TW(short x1, short y1, short x2, short y2, short x3, short y3, short tx1, short ty1, short tx2, short ty2, short tx3, short ty3, short clX, short clY,int32_t col1, int32_t col2, int32_t col3)
6308 {
6309  int i,j,xmin,xmax,ymin,ymax;
6310  int32_t cR1,cG1,cB1;
6311  int32_t difR,difB,difG,difR2,difB2,difG2;
6312  int32_t difX, difY,difX2, difY2;
6313  int32_t posX,posY,YAdjust,clutP;
6314  short tC1,tC2;
6315
6316  if(x1>drawW && x2>drawW && x3>drawW) return;
6317  if(y1>drawH && y2>drawH && y3>drawH) return;
6318  if(x1<drawX && x2<drawX && x3<drawX) return;
6319  if(y1<drawY && y2<drawY && y3<drawY) return;
6320  if(drawY>=drawH) return;
6321  if(drawX>=drawW) return; 
6322
6323  if(!SetupSections_GT(x1,y1,x2,y2,x3,y3,tx1,ty1,tx2,ty2,tx3,ty3,col1,col2,col3)) return;
6324
6325  ymax=Ymax;
6326
6327  for(ymin=Ymin;ymin<drawY;ymin++)
6328   if(NextRow_GT()) return;
6329
6330  clutP=(clY<<10)+clX;
6331
6332  YAdjust=((GlobalTextAddrY)<<11)+(GlobalTextAddrX<<1);
6333  YAdjust+=(TWin.Position.y0<<11)+(TWin.Position.x0);
6334
6335  difR=delta_right_R;
6336  difG=delta_right_G;
6337  difB=delta_right_B;
6338  difR2=difR<<1;
6339  difG2=difG<<1;
6340  difB2=difB<<1;
6341  difX=delta_right_u;difX2=difX<<1;
6342  difY=delta_right_v;difY2=difY<<1;
6343
6344 #ifdef FASTSOLID
6345
6346  if(!bCheckMask && !DrawSemiTrans && !iDither)
6347   {
6348    for (i=ymin;i<=ymax;i++)
6349     {
6350      xmin=(left_x >> 16);
6351      xmax=(right_x >> 16)-1; // !!!!!!!!!!!!!
6352      if(drawW<xmax) xmax=drawW;
6353
6354      if(xmax>=xmin)
6355       {
6356        posX=left_u;
6357        posY=left_v;
6358        cR1=left_R;
6359        cG1=left_G;
6360        cB1=left_B;
6361
6362        if(xmin<drawX)
6363         {j=drawX-xmin;xmin=drawX;posX+=j*difX;posY+=j*difY;cR1+=j*difR;cG1+=j*difG;cB1+=j*difB;}
6364
6365        for(j=xmin;j<xmax;j+=2)
6366         {
6367          tC1 = psxVub[(((posY>>16)%TWin.Position.y1)<<11)+
6368                       YAdjust+((posX>>16)%TWin.Position.x1)];
6369          tC2 = psxVub[((((posY+difY)>>16)%TWin.Position.y1)<<11)+
6370                       YAdjust+(((posX+difX)>>16)%TWin.Position.x1)];
6371                       
6372          GetTextureTransColGX32_S((uint32_t *)&psxVuw[(i<<10)+j],
6373               GETLE16(&psxVuw[clutP+tC1])|
6374               ((int32_t)GETLE16(&psxVuw[clutP+tC2]))<<16,
6375               (cB1>>16)|((cB1+difB)&0xff0000),
6376               (cG1>>16)|((cG1+difG)&0xff0000),
6377               (cR1>>16)|((cR1+difR)&0xff0000));
6378          posX+=difX2;
6379          posY+=difY2;
6380          cR1+=difR2;
6381          cG1+=difG2;
6382          cB1+=difB2;
6383         }
6384        if(j==xmax)
6385         {
6386          tC1 = psxVub[(((posY>>16)%TWin.Position.y1)<<11)+
6387                       YAdjust+((posX>>16)%TWin.Position.x1)];
6388          GetTextureTransColGX_S(&psxVuw[(i<<10)+j], 
6389               GETLE16(&psxVuw[clutP+tC1]),
6390               (cB1>>16),(cG1>>16),(cR1>>16));
6391         }
6392       }
6393      if(NextRow_GT()) 
6394       {
6395        return;
6396       }
6397     }
6398    return;
6399   }
6400
6401 #endif
6402
6403  for (i=ymin;i<=ymax;i++)
6404   {
6405    xmin=(left_x >> 16);
6406    xmax=(right_x >> 16)-1; //!!!!!!!!!!!!!!!!!!!!!!!
6407    if(drawW<xmax) xmax=drawW;
6408
6409    if(xmax>=xmin)
6410     {
6411      posX=left_u;
6412      posY=left_v;
6413      cR1=left_R;
6414      cG1=left_G;
6415      cB1=left_B;
6416
6417      if(xmin<drawX)
6418       {j=drawX-xmin;xmin=drawX;posX+=j*difX;posY+=j*difY;cR1+=j*difR;cG1+=j*difG;cB1+=j*difB;}
6419
6420      for(j=xmin;j<=xmax;j++)
6421       {
6422        tC1 = psxVub[(((posY>>16)%TWin.Position.y1)<<11)+
6423                     YAdjust+((posX>>16)%TWin.Position.x1)];
6424        if(iDither)
6425         GetTextureTransColGX_Dither(&psxVuw[(i<<10)+j], 
6426             GETLE16(&psxVuw[clutP+tC1]),
6427             (cB1>>16),(cG1>>16),(cR1>>16));
6428        else
6429         GetTextureTransColGX(&psxVuw[(i<<10)+j], 
6430             GETLE16(&psxVuw[clutP+tC1]),
6431             (cB1>>16),(cG1>>16),(cR1>>16));
6432        posX+=difX;
6433        posY+=difY;
6434        cR1+=difR;
6435        cG1+=difG;
6436        cB1+=difB;
6437       }
6438     }
6439    if(NextRow_GT()) 
6440     {
6441      return;
6442     }
6443   }
6444 }
6445
6446 ////////////////////////////////////////////////////////////////////////
6447
6448 // note: two g-shaded tris: small texture distortions can happen
6449
6450 void drawPoly4TGEx8_TRI_IL(short x1, short y1, short x2, short y2, short x3, short y3, short x4, short y4, 
6451                            short tx1, short ty1, short tx2, short ty2, short tx3, short ty3, short tx4, short ty4, 
6452                            short clX, short clY,
6453                            int32_t col1, int32_t col2, int32_t col3, int32_t col4)
6454 {
6455  drawPoly3TGEx8_IL(x2,y2,x3,y3,x4,y4,
6456                    tx2,ty2,tx3,ty3,tx4,ty4,
6457                    clX,clY,
6458                    col2,col4,col3);
6459  drawPoly3TGEx8_IL(x1,y1,x2,y2,x4,y4,
6460                    tx1,ty1,tx2,ty2,tx4,ty4,
6461                    clX,clY,
6462                    col1,col2,col3);
6463 }
6464
6465 #ifdef POLYQUAD3GT
6466                       
6467 void drawPoly4TGEx8_TRI(short x1, short y1, short x2, short y2, short x3, short y3, short x4, short y4, 
6468                    short tx1, short ty1, short tx2, short ty2, short tx3, short ty3, short tx4, short ty4, 
6469                    short clX, short clY,
6470                    int32_t col1, int32_t col2, int32_t col3, int32_t col4)
6471 {
6472  drawPoly3TGEx8(x2,y2,x3,y3,x4,y4,
6473                 tx2,ty2,tx3,ty3,tx4,ty4,
6474                 clX,clY,
6475                 col2,col4,col3);
6476  drawPoly3TGEx8(x1,y1,x2,y2,x4,y4,
6477                 tx1,ty1,tx2,ty2,tx4,ty4,
6478                 clX,clY,
6479                 col1,col2,col3);
6480 }
6481
6482 #endif
6483
6484 void drawPoly4TGEx8(short x1, short y1, short x2, short y2, short x3, short y3, short x4, short y4, 
6485                    short tx1, short ty1, short tx2, short ty2, short tx3, short ty3, short tx4, short ty4, 
6486                    short clX, short clY,
6487                    int32_t col1, int32_t col2, int32_t col4, int32_t col3)
6488 {
6489  int32_t num; 
6490  int32_t i,j,xmin,xmax,ymin,ymax;
6491  int32_t cR1,cG1,cB1;
6492  int32_t difR,difB,difG,difR2,difB2,difG2;
6493  int32_t difX, difY, difX2, difY2;
6494  int32_t posX,posY,YAdjust,clutP;
6495  short tC1,tC2;
6496
6497  if(x1>drawW && x2>drawW && x3>drawW && x4>drawW) return;
6498  if(y1>drawH && y2>drawH && y3>drawH && y4>drawH) return;
6499  if(x1<drawX && x2<drawX && x3<drawX && x4<drawX) return;
6500  if(y1<drawY && y2<drawY && y3<drawY && y4<drawY) return;
6501  if(drawY>=drawH) return;
6502  if(drawX>=drawW) return; 
6503
6504  if(!SetupSections_GT4(x1,y1,x2,y2,x3,y3,x4,y4,tx1,ty1,tx2,ty2,tx3,ty3,tx4,ty4,col1,col2,col3,col4)) return;
6505
6506  ymax=Ymax;
6507
6508  for(ymin=Ymin;ymin<drawY;ymin++)
6509   if(NextRow_GT4()) return;
6510
6511  clutP=(clY<<10)+clX;
6512
6513  YAdjust=((GlobalTextAddrY)<<11)+(GlobalTextAddrX<<1);
6514
6515 #ifdef FASTSOLID
6516
6517  if(!bCheckMask && !DrawSemiTrans && !iDither)
6518   {
6519    for (i=ymin;i<=ymax;i++)
6520     {
6521      xmin=(left_x >> 16);
6522      xmax=(right_x >> 16);
6523
6524      if(xmax>=xmin)
6525       {
6526        posX=left_u;
6527        posY=left_v;
6528
6529        num=(xmax-xmin);
6530        if(num==0) num=1;
6531        difX=(right_u-posX)/num;
6532        difY=(right_v-posY)/num;
6533        difX2=difX<<1;
6534        difY2=difY<<1;
6535
6536        cR1=left_R;
6537        cG1=left_G;
6538        cB1=left_B;
6539        difR=(right_R-cR1)/num;
6540        difG=(right_G-cG1)/num;
6541        difB=(right_B-cB1)/num;
6542        difR2=difR<<1;
6543        difG2=difG<<1;
6544        difB2=difB<<1;
6545
6546        if(xmin<drawX)
6547         {j=drawX-xmin;xmin=drawX;posX+=j*difX;posY+=j*difY;cR1+=j*difR;cG1+=j*difG;cB1+=j*difB;}
6548        xmax--;if(drawW<xmax) xmax=drawW;
6549
6550        for(j=xmin;j<xmax;j+=2)
6551         {
6552          tC1 = psxVub[((posY>>5)&(int32_t)0xFFFFF800)+YAdjust+(posX>>16)];
6553          tC2 = psxVub[(((posY+difY)>>5)&(int32_t)0xFFFFF800)+YAdjust+
6554                      ((posX+difX)>>16)];
6555
6556          GetTextureTransColGX32_S((uint32_t *)&psxVuw[(i<<10)+j],
6557               GETLE16(&psxVuw[clutP+tC1])|
6558               ((int32_t)GETLE16(&psxVuw[clutP+tC2]))<<16,
6559               (cB1>>16)|((cB1+difB)&0xff0000),
6560               (cG1>>16)|((cG1+difG)&0xff0000),
6561               (cR1>>16)|((cR1+difR)&0xff0000));
6562          posX+=difX2;
6563          posY+=difY2;
6564          cR1+=difR2;
6565          cG1+=difG2;
6566          cB1+=difB2;
6567         }
6568        if(j==xmax)
6569         {
6570          tC1 = psxVub[((posY>>5)&(int32_t)0xFFFFF800)+YAdjust+(posX>>16)];
6571          GetTextureTransColGX_S(&psxVuw[(i<<10)+j], 
6572               GETLE16(&psxVuw[clutP+tC1]),
6573              (cB1>>16),(cG1>>16),(cR1>>16));
6574         }
6575       }
6576      if(NextRow_GT4()) return;
6577     }
6578    return;
6579   }
6580
6581 #endif
6582
6583  for (i=ymin;i<=ymax;i++)
6584   {
6585    xmin=(left_x >> 16);
6586    xmax=(right_x >> 16);
6587
6588    if(xmax>=xmin)
6589     {
6590      posX=left_u;
6591      posY=left_v;
6592
6593      num=(xmax-xmin);
6594      if(num==0) num=1;
6595      difX=(right_u-posX)/num;
6596      difY=(right_v-posY)/num;
6597      difX2=difX<<1;
6598      difY2=difY<<1;
6599
6600      cR1=left_R;
6601      cG1=left_G;
6602      cB1=left_B;
6603      difR=(right_R-cR1)/num;
6604      difG=(right_G-cG1)/num;
6605      difB=(right_B-cB1)/num;
6606      difR2=difR<<1;
6607      difG2=difG<<1;
6608      difB2=difB<<1;
6609
6610      if(xmin<drawX)
6611       {j=drawX-xmin;xmin=drawX;posX+=j*difX;posY+=j*difY;cR1+=j*difR;cG1+=j*difG;cB1+=j*difB;}
6612      xmax--;if(drawW<xmax) xmax=drawW;
6613
6614      for(j=xmin;j<=xmax;j++)
6615       {
6616        tC1 = psxVub[((posY>>5)&(int32_t)0xFFFFF800)+YAdjust+(posX>>16)];
6617        if(iDither)
6618         GetTextureTransColGX_Dither(&psxVuw[(i<<10)+j], 
6619             GETLE16(&psxVuw[clutP+tC1]),
6620            (cB1>>16),(cG1>>16),(cR1>>16));
6621        else
6622         GetTextureTransColGX(&psxVuw[(i<<10)+j], 
6623             GETLE16(&psxVuw[clutP+tC1]),
6624            (cB1>>16),(cG1>>16),(cR1>>16));
6625        posX+=difX;
6626        posY+=difY;
6627        cR1+=difR;
6628        cG1+=difG;
6629        cB1+=difB;
6630       }
6631     }
6632    if(NextRow_GT4()) return;
6633   }
6634 }
6635
6636 ////////////////////////////////////////////////////////////////////////
6637
6638 void drawPoly4TGEx8_TW(short x1, short y1, short x2, short y2, short x3, short y3, short x4, short y4, 
6639                    short tx1, short ty1, short tx2, short ty2, short tx3, short ty3, short tx4, short ty4, 
6640                    short clX, short clY,
6641                    int32_t col1, int32_t col2, int32_t col3, int32_t col4)
6642 {
6643  drawPoly3TGEx8_TW(x2,y2,x3,y3,x4,y4,
6644                 tx2,ty2,tx3,ty3,tx4,ty4,
6645                 clX,clY,
6646                 col2,col4,col3);
6647  drawPoly3TGEx8_TW(x1,y1,x2,y2,x4,y4,
6648                 tx1,ty1,tx2,ty2,tx4,ty4,
6649                 clX,clY,
6650                 col1,col2,col3);
6651 }
6652
6653 ////////////////////////////////////////////////////////////////////////
6654 // POLY 3 G-SHADED TEX 15 BIT
6655 ////////////////////////////////////////////////////////////////////////
6656
6657 void drawPoly3TGD(short x1, short y1, short x2, short y2, short x3, short y3, short tx1, short ty1, short tx2, short ty2, short tx3, short ty3,int32_t col1, int32_t col2, int32_t col3)
6658 {
6659  int i,j,xmin,xmax,ymin,ymax;
6660  int32_t cR1,cG1,cB1;
6661  int32_t difR,difB,difG,difR2,difB2,difG2;
6662  int32_t difX, difY,difX2, difY2;
6663  int32_t posX,posY;
6664
6665  if(x1>drawW && x2>drawW && x3>drawW) return;
6666  if(y1>drawH && y2>drawH && y3>drawH) return;
6667  if(x1<drawX && x2<drawX && x3<drawX) return;
6668  if(y1<drawY && y2<drawY && y3<drawY) return;
6669  if(drawY>=drawH) return;
6670  if(drawX>=drawW) return; 
6671
6672  if(!SetupSections_GT(x1,y1,x2,y2,x3,y3,tx1,ty1,tx2,ty2,tx3,ty3,col1,col2,col3)) return;
6673
6674  ymax=Ymax;
6675
6676  for(ymin=Ymin;ymin<drawY;ymin++)
6677   if(NextRow_GT()) return;
6678
6679  difR=delta_right_R;
6680  difG=delta_right_G;
6681  difB=delta_right_B;
6682  difR2=difR<<1;
6683  difG2=difG<<1;
6684  difB2=difB<<1;
6685  difX=delta_right_u;difX2=difX<<1;
6686  difY=delta_right_v;difY2=difY<<1;
6687
6688 #ifdef FASTSOLID
6689
6690  if(!bCheckMask && !DrawSemiTrans && !iDither)
6691   {       
6692    for (i=ymin;i<=ymax;i++)
6693     {
6694      xmin=(left_x >> 16);
6695      xmax=(right_x >> 16)-1; //!!!!!!!!!!!!!!!!!!!!
6696      if(drawW<xmax) xmax=drawW;
6697
6698      if(xmax>=xmin)
6699       {
6700        posX=left_u;
6701        posY=left_v;
6702        cR1=left_R;
6703        cG1=left_G;
6704        cB1=left_B;
6705
6706        if(xmin<drawX)
6707         {j=drawX-xmin;xmin=drawX;posX+=j*difX;posY+=j*difY;cR1+=j*difR;cG1+=j*difG;cB1+=j*difB;}
6708
6709        for(j=xmin;j<xmax;j+=2)
6710         {
6711          GetTextureTransColGX32_S((uint32_t *)&psxVuw[(i<<10)+j],
6712               (((int32_t)GETLE16(&psxVuw[((((posY+difY)>>16)+GlobalTextAddrY)<<10)+((posX+difX)>>16)+GlobalTextAddrX]))<<16)|
6713               GETLE16(&psxVuw[(((posY>>16)+GlobalTextAddrY)<<10)+((posX)>>16)+GlobalTextAddrX]),
6714               (cB1>>16)|((cB1+difB)&0xff0000),
6715               (cG1>>16)|((cG1+difG)&0xff0000),
6716               (cR1>>16)|((cR1+difR)&0xff0000));
6717          posX+=difX2;
6718          posY+=difY2;
6719          cR1+=difR2;
6720          cG1+=difG2;
6721          cB1+=difB2;
6722         }
6723        if(j==xmax)
6724         GetTextureTransColGX_S(&psxVuw[(i<<10)+j],
6725             GETLE16(&psxVuw[(((posY>>16)+GlobalTextAddrY)<<10)+(posX>>16)+GlobalTextAddrX]),
6726             (cB1>>16),(cG1>>16),(cR1>>16));
6727       }
6728      if(NextRow_GT()) 
6729       {
6730        return;
6731       }
6732     }
6733    return;
6734   }
6735
6736 #endif
6737
6738  for (i=ymin;i<=ymax;i++)
6739   {
6740    xmin=(left_x >> 16);
6741    xmax=(right_x >> 16)-1; //!!!!!!!!!!!!!!!!!!
6742    if(drawW<xmax) xmax=drawW;
6743
6744    if(xmax>=xmin)
6745     {
6746      posX=left_u;
6747      posY=left_v;
6748      cR1=left_R;
6749      cG1=left_G;
6750      cB1=left_B;
6751
6752      if(xmin<drawX)
6753       {j=drawX-xmin;xmin=drawX;posX+=j*difX;posY+=j*difY;cR1+=j*difR;cG1+=j*difG;cB1+=j*difB;}
6754
6755      for(j=xmin;j<=xmax;j++)
6756       {
6757        if(iDither)
6758         GetTextureTransColGX_Dither(&psxVuw[(i<<10)+j],
6759           GETLE16(&psxVuw[(((posY>>16)+GlobalTextAddrY)<<10)+(posX>>16)+GlobalTextAddrX]),
6760           (cB1>>16),(cG1>>16),(cR1>>16));
6761        else
6762         GetTextureTransColGX(&psxVuw[(i<<10)+j],
6763           GETLE16(&psxVuw[(((posY>>16)+GlobalTextAddrY)<<10)+(posX>>16)+GlobalTextAddrX]),
6764           (cB1>>16),(cG1>>16),(cR1>>16));
6765        posX+=difX;
6766        posY+=difY;
6767        cR1+=difR;
6768        cG1+=difG;
6769        cB1+=difB;
6770       }
6771     }
6772    if(NextRow_GT()) 
6773     {
6774      return;
6775     }
6776   }
6777 }
6778
6779 ////////////////////////////////////////////////////////////////////////
6780
6781 void drawPoly3TGD_TW(short x1, short y1, short x2, short y2, short x3, short y3, short tx1, short ty1, short tx2, short ty2, short tx3, short ty3,int32_t col1, int32_t col2, int32_t col3)
6782 {
6783  int i,j,xmin,xmax,ymin,ymax;
6784  int32_t cR1,cG1,cB1;
6785  int32_t difR,difB,difG,difR2,difB2,difG2;
6786  int32_t difX, difY,difX2, difY2;
6787  int32_t posX,posY;
6788
6789  if(x1>drawW && x2>drawW && x3>drawW) return;
6790  if(y1>drawH && y2>drawH && y3>drawH) return;
6791  if(x1<drawX && x2<drawX && x3<drawX) return;
6792  if(y1<drawY && y2<drawY && y3<drawY) return;
6793  if(drawY>=drawH) return;
6794  if(drawX>=drawW) return; 
6795
6796  if(!SetupSections_GT(x1,y1,x2,y2,x3,y3,tx1,ty1,tx2,ty2,tx3,ty3,col1,col2,col3)) return;
6797
6798  ymax=Ymax;
6799
6800  for(ymin=Ymin;ymin<drawY;ymin++)
6801   if(NextRow_GT()) return;
6802
6803  difR=delta_right_R;
6804  difG=delta_right_G;
6805  difB=delta_right_B;
6806  difR2=difR<<1;
6807  difG2=difG<<1;
6808  difB2=difB<<1;
6809  difX=delta_right_u;difX2=difX<<1;
6810  difY=delta_right_v;difY2=difY<<1;
6811
6812 #ifdef FASTSOLID
6813
6814  if(!bCheckMask && !DrawSemiTrans && !iDither)
6815   {       
6816    for (i=ymin;i<=ymax;i++)
6817     {
6818      xmin=(left_x >> 16);
6819      xmax=(right_x >> 16)-1; //!!!!!!!!!!!!!!!!!!!!
6820      if(drawW<xmax) xmax=drawW;
6821
6822      if(xmax>=xmin)
6823       {
6824        posX=left_u;
6825        posY=left_v;
6826        cR1=left_R;
6827        cG1=left_G;
6828        cB1=left_B;
6829
6830        if(xmin<drawX)
6831         {j=drawX-xmin;xmin=drawX;posX+=j*difX;posY+=j*difY;cR1+=j*difR;cG1+=j*difG;cB1+=j*difB;}
6832
6833        for(j=xmin;j<xmax;j+=2)
6834         {
6835          GetTextureTransColGX32_S((uint32_t *)&psxVuw[(i<<10)+j],
6836               (((int32_t)GETLE16(&psxVuw[(((((posY+difY)>>16)%TWin.Position.y1)+GlobalTextAddrY+TWin.Position.y0)<<10)+
6837                              (((posX+difX)>>16)%TWin.Position.x1)+GlobalTextAddrX+TWin.Position.x0]))<<16)|
6838               GETLE16(&psxVuw[((((posY>>16)%TWin.Position.y1)+GlobalTextAddrY+TWin.Position.y0)<<10)+
6839                      (((posX)>>16)%TWin.Position.x1)+GlobalTextAddrX+TWin.Position.x0]),
6840               (cB1>>16)|((cB1+difB)&0xff0000),
6841               (cG1>>16)|((cG1+difG)&0xff0000),
6842               (cR1>>16)|((cR1+difR)&0xff0000));
6843          posX+=difX2;
6844          posY+=difY2;
6845          cR1+=difR2;
6846          cG1+=difG2;
6847          cB1+=difB2;
6848         }
6849        if(j==xmax)
6850         GetTextureTransColGX_S(&psxVuw[(i<<10)+j],
6851             GETLE16(&psxVuw[((((posY>>16)%TWin.Position.y1)+GlobalTextAddrY+TWin.Position.y0)<<10)+
6852                    ((posX>>16)%TWin.Position.x1)+GlobalTextAddrX+TWin.Position.x0]),
6853             (cB1>>16),(cG1>>16),(cR1>>16));
6854       }
6855      if(NextRow_GT()) 
6856       {
6857        return;
6858       }
6859     }
6860    return;
6861   }
6862
6863 #endif
6864
6865  for (i=ymin;i<=ymax;i++)
6866   {
6867    xmin=(left_x >> 16);
6868    xmax=(right_x >> 16)-1; //!!!!!!!!!!!!!!!!!!
6869    if(drawW<xmax) xmax=drawW;
6870
6871    if(xmax>=xmin)
6872     {
6873      posX=left_u;
6874      posY=left_v;
6875      cR1=left_R;
6876      cG1=left_G;
6877      cB1=left_B;
6878
6879      if(xmin<drawX)
6880       {j=drawX-xmin;xmin=drawX;posX+=j*difX;posY+=j*difY;cR1+=j*difR;cG1+=j*difG;cB1+=j*difB;}
6881
6882      for(j=xmin;j<=xmax;j++)
6883       {
6884        if(iDither)
6885         GetTextureTransColGX_Dither(&psxVuw[(i<<10)+j],
6886           GETLE16(&psxVuw[((((posY>>16)%TWin.Position.y1)+GlobalTextAddrY+TWin.Position.y0)<<10)+
6887                  ((posX>>16)%TWin.Position.x1)+GlobalTextAddrX+TWin.Position.x0]),
6888           (cB1>>16),(cG1>>16),(cR1>>16));
6889        else
6890         GetTextureTransColGX(&psxVuw[(i<<10)+j],
6891           GETLE16(&psxVuw[((((posY>>16)%TWin.Position.y1)+GlobalTextAddrY+TWin.Position.y0)<<10)+
6892                  ((posX>>16)%TWin.Position.x1)+GlobalTextAddrX+TWin.Position.x0]),
6893           (cB1>>16),(cG1>>16),(cR1>>16));
6894        posX+=difX;
6895        posY+=difY;
6896        cR1+=difR;
6897        cG1+=difG;
6898        cB1+=difB;
6899       }
6900     }
6901    if(NextRow_GT()) 
6902     {
6903      return;
6904     }
6905   }
6906 }
6907
6908 ////////////////////////////////////////////////////////////////////////
6909
6910 // note: two g-shaded tris: small texture distortions can happen
6911
6912 #ifdef POLYQUAD3GT
6913
6914 void drawPoly4TGD_TRI(short x1, short y1, short x2, short y2, short x3, short y3, short x4, short y4, short tx1, short ty1, short tx2, short ty2, short tx3, short ty3, short tx4, short ty4, int32_t col1, int32_t col2, int32_t col3, int32_t col4)
6915 {
6916  drawPoly3TGD(x2,y2,x3,y3,x4,y4,
6917               tx2,ty2,tx3,ty3,tx4,ty4,
6918               col2,col4,col3);
6919  drawPoly3TGD(x1,y1,x2,y2,x4,y4,
6920               tx1,ty1,tx2,ty2,tx4,ty4,
6921               col1,col2,col3);
6922 }
6923
6924 #endif
6925
6926 void drawPoly4TGD(short x1, short y1, short x2, short y2, short x3, short y3, short x4, short y4, short tx1, short ty1, short tx2, short ty2, short tx3, short ty3, short tx4, short ty4, int32_t col1, int32_t col2, int32_t col4, int32_t col3)
6927 {
6928  int32_t num; 
6929  int32_t i,j,xmin,xmax,ymin,ymax;
6930  int32_t cR1,cG1,cB1;
6931  int32_t difR,difB,difG,difR2,difB2,difG2;
6932  int32_t difX, difY, difX2, difY2;
6933  int32_t posX,posY;
6934
6935  if(x1>drawW && x2>drawW && x3>drawW && x4>drawW) return;
6936  if(y1>drawH && y2>drawH && y3>drawH && y4>drawH) return;
6937  if(x1<drawX && x2<drawX && x3<drawX && x4<drawX) return;
6938  if(y1<drawY && y2<drawY && y3<drawY && y4<drawY) return;
6939  if(drawY>=drawH) return;
6940  if(drawX>=drawW) return; 
6941
6942  if(!SetupSections_GT4(x1,y1,x2,y2,x3,y3,x4,y4,tx1,ty1,tx2,ty2,tx3,ty3,tx4,ty4,col1,col2,col3,col4)) return;
6943
6944  ymax=Ymax;
6945
6946  for(ymin=Ymin;ymin<drawY;ymin++)
6947   if(NextRow_GT4()) return;
6948
6949 #ifdef FASTSOLID
6950
6951  if(!bCheckMask && !DrawSemiTrans && !iDither)
6952   {
6953    for (i=ymin;i<=ymax;i++)
6954     {
6955      xmin=(left_x >> 16);
6956      xmax=(right_x >> 16);
6957
6958      if(xmax>=xmin)
6959       {
6960        posX=left_u;
6961        posY=left_v;
6962
6963        num=(xmax-xmin);
6964        if(num==0) num=1;
6965        difX=(right_u-posX)/num;
6966        difY=(right_v-posY)/num;
6967        difX2=difX<<1;
6968        difY2=difY<<1;
6969
6970        cR1=left_R;
6971        cG1=left_G;
6972        cB1=left_B;
6973        difR=(right_R-cR1)/num;
6974        difG=(right_G-cG1)/num;
6975        difB=(right_B-cB1)/num;
6976        difR2=difR<<1;
6977        difG2=difG<<1;
6978        difB2=difB<<1;
6979
6980        if(xmin<drawX)
6981         {j=drawX-xmin;xmin=drawX;posX+=j*difX;posY+=j*difY;cR1+=j*difR;cG1+=j*difG;cB1+=j*difB;}
6982        xmax--;if(drawW<xmax) xmax=drawW;
6983
6984        for(j=xmin;j<xmax;j+=2)
6985         {
6986          GetTextureTransColGX32_S((uint32_t *)&psxVuw[(i<<10)+j],
6987               (((int32_t)GETLE16(&psxVuw[((((posY+difY)>>16)+GlobalTextAddrY)<<10)+((posX+difX)>>16)+GlobalTextAddrX]))<<16)|
6988               GETLE16(&psxVuw[(((posY>>16)+GlobalTextAddrY)<<10)+((posX)>>16)+GlobalTextAddrX]),
6989               (cB1>>16)|((cB1+difB)&0xff0000),
6990               (cG1>>16)|((cG1+difG)&0xff0000),
6991               (cR1>>16)|((cR1+difR)&0xff0000));
6992          posX+=difX2;
6993          posY+=difY2;
6994          cR1+=difR2;
6995          cG1+=difG2;
6996          cB1+=difB2;
6997         }
6998        if(j==xmax)
6999         GetTextureTransColGX_S(&psxVuw[(i<<10)+j],
7000             GETLE16(&psxVuw[(((posY>>16)+GlobalTextAddrY)<<10)+(posX>>16)+GlobalTextAddrX]),
7001             (cB1>>16),(cG1>>16),(cR1>>16));
7002       }
7003      if(NextRow_GT4()) return;
7004     }
7005    return;
7006   }
7007
7008 #endif
7009
7010  for (i=ymin;i<=ymax;i++)
7011   {
7012    xmin=(left_x >> 16);
7013    xmax=(right_x >> 16);
7014
7015    if(xmax>=xmin)
7016     {
7017      posX=left_u;
7018      posY=left_v;
7019
7020      num=(xmax-xmin);
7021      if(num==0) num=1;
7022      difX=(right_u-posX)/num;
7023      difY=(right_v-posY)/num;
7024      difX2=difX<<1;
7025      difY2=difY<<1;
7026
7027      cR1=left_R;
7028      cG1=left_G;
7029      cB1=left_B;
7030      difR=(right_R-cR1)/num;
7031      difG=(right_G-cG1)/num;
7032      difB=(right_B-cB1)/num;
7033      difR2=difR<<1;
7034      difG2=difG<<1;
7035      difB2=difB<<1;
7036
7037      if(xmin<drawX)
7038       {j=drawX-xmin;xmin=drawX;posX+=j*difX;posY+=j*difY;cR1+=j*difR;cG1+=j*difG;cB1+=j*difB;}
7039      xmax--;if(drawW<xmax) xmax=drawW;
7040
7041      for(j=xmin;j<=xmax;j++)
7042       {
7043        if(iDither)
7044         GetTextureTransColGX(&psxVuw[(i<<10)+j],
7045           GETLE16(&psxVuw[(((posY>>16)+GlobalTextAddrY)<<10)+(posX>>16)+GlobalTextAddrX]),
7046           (cB1>>16),(cG1>>16),(cR1>>16));
7047        else
7048         GetTextureTransColGX(&psxVuw[(i<<10)+j],
7049           GETLE16(&psxVuw[(((posY>>16)+GlobalTextAddrY)<<10)+(posX>>16)+GlobalTextAddrX]),
7050           (cB1>>16),(cG1>>16),(cR1>>16));
7051        posX+=difX;
7052        posY+=difY;
7053        cR1+=difR;
7054        cG1+=difG;
7055        cB1+=difB;
7056       }
7057     }
7058    if(NextRow_GT4()) return;
7059   }
7060 }
7061
7062 ////////////////////////////////////////////////////////////////////////
7063
7064 void drawPoly4TGD_TW(short x1, short y1, short x2, short y2, short x3, short y3, short x4, short y4, short tx1, short ty1, short tx2, short ty2, short tx3, short ty3, short tx4, short ty4, int32_t col1, int32_t col2, int32_t col3, int32_t col4)
7065 {
7066  drawPoly3TGD_TW(x2,y2,x3,y3,x4,y4,
7067               tx2,ty2,tx3,ty3,tx4,ty4,
7068               col2,col4,col3);
7069  drawPoly3TGD_TW(x1,y1,x2,y2,x4,y4,
7070               tx1,ty1,tx2,ty2,tx4,ty4,
7071               col1,col2,col3);
7072 }
7073
7074 ////////////////////////////////////////////////////////////////////////
7075 ////////////////////////////////////////////////////////////////////////
7076 ////////////////////////////////////////////////////////////////////////
7077 ////////////////////////////////////////////////////////////////////////
7078 ////////////////////////////////////////////////////////////////////////
7079 ////////////////////////////////////////////////////////////////////////
7080
7081
7082 /*
7083 // no real rect test, but it does its job the way I need it
7084 __inline BOOL IsNoRect(void)
7085 {
7086  if(lx0==lx1 && lx2==lx3) return FALSE;
7087  if(lx0==lx2 && lx1==lx3) return FALSE;
7088  if(lx0==lx3 && lx1==lx2) return FALSE;
7089  return TRUE;                      
7090 }
7091 */
7092
7093 // real rect test
7094 __inline BOOL IsNoRect(void)
7095 {
7096  if(!(dwActFixes&0x200)) return FALSE;
7097
7098  if(ly0==ly1)
7099   {
7100    if(lx1==lx3 && ly3==ly2 && lx2==lx0) return FALSE;
7101    if(lx1==lx2 && ly2==ly3 && lx3==lx0) return FALSE;
7102    return TRUE;
7103   }
7104  
7105  if(ly0==ly2)
7106   {
7107    if(lx2==lx3 && ly3==ly1 && lx1==lx0) return FALSE;
7108    if(lx2==lx1 && ly1==ly3 && lx3==lx0) return FALSE;
7109    return TRUE;
7110   }
7111  
7112  if(ly0==ly3)
7113   {
7114    if(lx3==lx2 && ly2==ly1 && lx1==lx0) return FALSE;
7115    if(lx3==lx1 && ly1==ly2 && lx2==lx0) return FALSE;
7116    return TRUE;
7117   }
7118  return TRUE;
7119 }
7120
7121 ////////////////////////////////////////////////////////////////////////
7122
7123 void drawPoly3FT(unsigned char * baseAddr)
7124 {
7125  uint32_t *gpuData = ((uint32_t *) baseAddr);
7126
7127  if(GlobalTextIL && GlobalTextTP<2)
7128   {
7129    if(GlobalTextTP==0)
7130     drawPoly3TEx4_IL(lx0,ly0,lx1,ly1,lx2,ly2,
7131                      (GETLE32(&gpuData[2]) & 0x000000ff), ((GETLE32(&gpuData[2])>>8) & 0x000000ff), (GETLE32(&gpuData[4]) & 0x000000ff), ((GETLE32(&gpuData[4])>>8) & 0x000000ff),(GETLE32(&gpuData[6]) & 0x000000ff), ((GETLE32(&gpuData[6])>>8) & 0x000000ff), 
7132                      ((GETLE32(&gpuData[2])>>12) & 0x3f0), ((GETLE32(&gpuData[2])>>22) & iGPUHeightMask));
7133    else
7134     drawPoly3TEx8_IL(lx0,ly0,lx1,ly1,lx2,ly2,
7135                      (GETLE32(&gpuData[2]) & 0x000000ff), ((GETLE32(&gpuData[2])>>8) & 0x000000ff), (GETLE32(&gpuData[4]) & 0x000000ff), ((GETLE32(&gpuData[4])>>8) & 0x000000ff),(GETLE32(&gpuData[6]) & 0x000000ff), ((GETLE32(&gpuData[6])>>8) & 0x000000ff), 
7136                      ((GETLE32(&gpuData[2])>>12) & 0x3f0), ((GETLE32(&gpuData[2])>>22) & iGPUHeightMask));
7137    return;
7138   }
7139
7140  if(!bUsingTWin && !(dwActFixes&0x100))
7141   {
7142    switch(GlobalTextTP)   // depending on texture mode
7143     {
7144      case 0:
7145       drawPoly3TEx4(lx0,ly0,lx1,ly1,lx2,ly2,
7146                     (GETLE32(&gpuData[2]) & 0x000000ff), ((GETLE32(&gpuData[2])>>8) & 0x000000ff), (GETLE32(&gpuData[4]) & 0x000000ff), ((GETLE32(&gpuData[4])>>8) & 0x000000ff),(GETLE32(&gpuData[6]) & 0x000000ff), ((GETLE32(&gpuData[6])>>8) & 0x000000ff), 
7147                     ((GETLE32(&gpuData[2])>>12) & 0x3f0), ((GETLE32(&gpuData[2])>>22) & iGPUHeightMask));
7148       return;
7149      case 1:
7150       drawPoly3TEx8(lx0,ly0,lx1,ly1,lx2,ly2,
7151                     (GETLE32(&gpuData[2]) & 0x000000ff), ((GETLE32(&gpuData[2])>>8) & 0x000000ff), (GETLE32(&gpuData[4]) & 0x000000ff), ((GETLE32(&gpuData[4])>>8) & 0x000000ff),(GETLE32(&gpuData[6]) & 0x000000ff), ((GETLE32(&gpuData[6])>>8) & 0x000000ff), 
7152                     ((GETLE32(&gpuData[2])>>12) & 0x3f0), ((GETLE32(&gpuData[2])>>22) & iGPUHeightMask));
7153       return;
7154      case 2:
7155       drawPoly3TD(lx0,ly0,lx1,ly1,lx2,ly2,(GETLE32(&gpuData[2]) & 0x000000ff), ((GETLE32(&gpuData[2])>>8) & 0x000000ff), (GETLE32(&gpuData[4]) & 0x000000ff), ((GETLE32(&gpuData[4])>>8) & 0x000000ff),(GETLE32(&gpuData[6]) & 0x000000ff), ((GETLE32(&gpuData[6])>>8) & 0x000000ff));
7156       return;
7157     }
7158    return;
7159   }
7160
7161  switch(GlobalTextTP)   // depending on texture mode
7162   {
7163    case 0:
7164     drawPoly3TEx4_TW(lx0,ly0,lx1,ly1,lx2,ly2,
7165                      (GETLE32(&gpuData[2]) & 0x000000ff), ((GETLE32(&gpuData[2])>>8) & 0x000000ff), (GETLE32(&gpuData[4]) & 0x000000ff), ((GETLE32(&gpuData[4])>>8) & 0x000000ff),(GETLE32(&gpuData[6]) & 0x000000ff), ((GETLE32(&gpuData[6])>>8) & 0x000000ff), 
7166                      ((GETLE32(&gpuData[2])>>12) & 0x3f0), ((GETLE32(&gpuData[2])>>22) & iGPUHeightMask));
7167     return;
7168    case 1:
7169     drawPoly3TEx8_TW(lx0,ly0,lx1,ly1,lx2,ly2,
7170                      (GETLE32(&gpuData[2]) & 0x000000ff), ((GETLE32(&gpuData[2])>>8) & 0x000000ff), (GETLE32(&gpuData[4]) & 0x000000ff), ((GETLE32(&gpuData[4])>>8) & 0x000000ff),(GETLE32(&gpuData[6]) & 0x000000ff), ((GETLE32(&gpuData[6])>>8) & 0x000000ff), 
7171                      ((GETLE32(&gpuData[2])>>12) & 0x3f0), ((GETLE32(&gpuData[2])>>22) & iGPUHeightMask));
7172     return;
7173    case 2:
7174     drawPoly3TD_TW(lx0,ly0,lx1,ly1,lx2,ly2,(GETLE32(&gpuData[2]) & 0x000000ff), ((GETLE32(&gpuData[2])>>8) & 0x000000ff), (GETLE32(&gpuData[4]) & 0x000000ff), ((GETLE32(&gpuData[4])>>8) & 0x000000ff),(GETLE32(&gpuData[6]) & 0x000000ff), ((GETLE32(&gpuData[6])>>8) & 0x000000ff));
7175     return;
7176   }
7177 }
7178
7179 ////////////////////////////////////////////////////////////////////////
7180
7181 void drawPoly4FT(unsigned char * baseAddr)
7182 {
7183  uint32_t *gpuData = ((uint32_t *) baseAddr);
7184
7185  if(GlobalTextIL && GlobalTextTP<2)
7186   {
7187    if(GlobalTextTP==0)
7188     drawPoly4TEx4_IL(lx0,ly0,lx1,ly1,lx3,ly3,lx2,ly2,
7189                      (GETLE32(&gpuData[2]) & 0x000000ff), ((GETLE32(&gpuData[2])>>8) & 0x000000ff), (GETLE32(&gpuData[4]) & 0x000000ff), ((GETLE32(&gpuData[4])>>8) & 0x000000ff),(GETLE32(&gpuData[8]) & 0x000000ff), ((GETLE32(&gpuData[8])>>8) & 0x000000ff),(GETLE32(&gpuData[6]) & 0x000000ff), ((GETLE32(&gpuData[6])>>8) & 0x000000ff), ((GETLE32(&gpuData[2])>>12) & 0x3f0), ((GETLE32(&gpuData[2])>>22) & iGPUHeightMask));
7190    else
7191     drawPoly4TEx8_IL(lx0,ly0,lx1,ly1,lx3,ly3,lx2,ly2,
7192                   (GETLE32(&gpuData[2]) & 0x000000ff), ((GETLE32(&gpuData[2])>>8) & 0x000000ff), (GETLE32(&gpuData[4]) & 0x000000ff), ((GETLE32(&gpuData[4])>>8) & 0x000000ff),(GETLE32(&gpuData[8]) & 0x000000ff), ((GETLE32(&gpuData[8])>>8) & 0x000000ff),(GETLE32(&gpuData[6]) & 0x000000ff), ((GETLE32(&gpuData[6])>>8) & 0x000000ff), ((GETLE32(&gpuData[2])>>12) & 0x3f0), ((GETLE32(&gpuData[2])>>22) & iGPUHeightMask));
7193    return;
7194   }
7195
7196  if(!bUsingTWin)
7197   {
7198 #ifdef POLYQUAD3GT
7199    if(IsNoRect())
7200     {
7201      switch (GlobalTextTP)
7202       {
7203        case 0:
7204         drawPoly4TEx4_TRI(lx0,ly0,lx1,ly1,lx3,ly3,lx2,ly2,
7205                       (GETLE32(&gpuData[2]) & 0x000000ff), ((GETLE32(&gpuData[2])>>8) & 0x000000ff), (GETLE32(&gpuData[4]) & 0x000000ff), ((GETLE32(&gpuData[4])>>8) & 0x000000ff),(GETLE32(&gpuData[8]) & 0x000000ff), ((GETLE32(&gpuData[8])>>8) & 0x000000ff),(GETLE32(&gpuData[6]) & 0x000000ff), ((GETLE32(&gpuData[6])>>8) & 0x000000ff), ((GETLE32(&gpuData[2])>>12) & 0x3f0), ((GETLE32(&gpuData[2])>>22) & iGPUHeightMask));
7206         return;
7207        case 1:
7208         drawPoly4TEx8_TRI(lx0,ly0,lx1,ly1,lx3,ly3,lx2,ly2,
7209                       (GETLE32(&gpuData[2]) & 0x000000ff), ((GETLE32(&gpuData[2])>>8) & 0x000000ff), (GETLE32(&gpuData[4]) & 0x000000ff), ((GETLE32(&gpuData[4])>>8) & 0x000000ff),(GETLE32(&gpuData[8]) & 0x000000ff), ((GETLE32(&gpuData[8])>>8) & 0x000000ff),(GETLE32(&gpuData[6]) & 0x000000ff), ((GETLE32(&gpuData[6])>>8) & 0x000000ff), ((GETLE32(&gpuData[2])>>12) & 0x3f0), ((GETLE32(&gpuData[2])>>22) & iGPUHeightMask));
7210         return;
7211        case 2:
7212         drawPoly4TD_TRI(lx0,ly0,lx1,ly1,lx3,ly3,lx2,ly2,(GETLE32(&gpuData[2]) & 0x000000ff), ((GETLE32(&gpuData[2])>>8) & 0x000000ff), (GETLE32(&gpuData[4]) & 0x000000ff), ((GETLE32(&gpuData[4])>>8) & 0x000000ff),(GETLE32(&gpuData[8]) & 0x000000ff), ((GETLE32(&gpuData[8])>>8) & 0x000000ff),(GETLE32(&gpuData[6]) & 0x000000ff), ((GETLE32(&gpuData[6])>>8) & 0x000000ff));
7213         return;
7214       }
7215      return;
7216     }
7217 #endif
7218           
7219    switch (GlobalTextTP)
7220     {
7221      case 0: // grandia investigations needed
7222       drawPoly4TEx4(lx0,ly0,lx1,ly1,lx3,ly3,lx2,ly2,
7223                     (GETLE32(&gpuData[2]) & 0x000000ff), ((GETLE32(&gpuData[2])>>8) & 0x000000ff), (GETLE32(&gpuData[4]) & 0x000000ff), ((GETLE32(&gpuData[4])>>8) & 0x000000ff),(GETLE32(&gpuData[8]) & 0x000000ff), ((GETLE32(&gpuData[8])>>8) & 0x000000ff),(GETLE32(&gpuData[6]) & 0x000000ff), ((GETLE32(&gpuData[6])>>8) & 0x000000ff), ((GETLE32(&gpuData[2])>>12) & 0x3f0), ((GETLE32(&gpuData[2])>>22) & iGPUHeightMask));
7224       return;
7225      case 1:
7226       drawPoly4TEx8(lx0,ly0,lx1,ly1,lx3,ly3,lx2,ly2,
7227                   (GETLE32(&gpuData[2]) & 0x000000ff), ((GETLE32(&gpuData[2])>>8) & 0x000000ff), (GETLE32(&gpuData[4]) & 0x000000ff), ((GETLE32(&gpuData[4])>>8) & 0x000000ff),(GETLE32(&gpuData[8]) & 0x000000ff), ((GETLE32(&gpuData[8])>>8) & 0x000000ff),(GETLE32(&gpuData[6]) & 0x000000ff), ((GETLE32(&gpuData[6])>>8) & 0x000000ff), ((GETLE32(&gpuData[2])>>12) & 0x3f0), ((GETLE32(&gpuData[2])>>22) & iGPUHeightMask));
7228       return;
7229      case 2:
7230       drawPoly4TD(lx0,ly0,lx1,ly1,lx3,ly3,lx2,ly2,(GETLE32(&gpuData[2]) & 0x000000ff), ((GETLE32(&gpuData[2])>>8) & 0x000000ff), (GETLE32(&gpuData[4]) & 0x000000ff), ((GETLE32(&gpuData[4])>>8) & 0x000000ff),(GETLE32(&gpuData[8]) & 0x000000ff), ((GETLE32(&gpuData[8])>>8) & 0x000000ff),(GETLE32(&gpuData[6]) & 0x000000ff), ((GETLE32(&gpuData[6])>>8) & 0x000000ff));
7231       return;
7232     }
7233    return;
7234   }
7235
7236  switch (GlobalTextTP)
7237   {
7238    case 0:
7239     drawPoly4TEx4_TW(lx0,ly0,lx1,ly1,lx3,ly3,lx2,ly2,
7240                      (GETLE32(&gpuData[2]) & 0x000000ff), ((GETLE32(&gpuData[2])>>8) & 0x000000ff), (GETLE32(&gpuData[4]) & 0x000000ff), ((GETLE32(&gpuData[4])>>8) & 0x000000ff),(GETLE32(&gpuData[8]) & 0x000000ff), ((GETLE32(&gpuData[8])>>8) & 0x000000ff),(GETLE32(&gpuData[6]) & 0x000000ff), ((GETLE32(&gpuData[6])>>8) & 0x000000ff), ((GETLE32(&gpuData[2])>>12) & 0x3f0), ((GETLE32(&gpuData[2])>>22) & iGPUHeightMask));
7241     return;
7242    case 1:
7243     drawPoly4TEx8_TW(lx0,ly0,lx1,ly1,lx3,ly3,lx2,ly2,
7244                      (GETLE32(&gpuData[2]) & 0x000000ff), ((GETLE32(&gpuData[2])>>8) & 0x000000ff), (GETLE32(&gpuData[4]) & 0x000000ff), ((GETLE32(&gpuData[4])>>8) & 0x000000ff),(GETLE32(&gpuData[8]) & 0x000000ff), ((GETLE32(&gpuData[8])>>8) & 0x000000ff),(GETLE32(&gpuData[6]) & 0x000000ff), ((GETLE32(&gpuData[6])>>8) & 0x000000ff), ((GETLE32(&gpuData[2])>>12) & 0x3f0), ((GETLE32(&gpuData[2])>>22) & iGPUHeightMask));
7245     return;
7246    case 2:
7247     drawPoly4TD_TW(lx0,ly0,lx1,ly1,lx3,ly3,lx2,ly2,(GETLE32(&gpuData[2]) & 0x000000ff), ((GETLE32(&gpuData[2])>>8) & 0x000000ff), (GETLE32(&gpuData[4]) & 0x000000ff), ((GETLE32(&gpuData[4])>>8) & 0x000000ff),(GETLE32(&gpuData[8]) & 0x000000ff), ((GETLE32(&gpuData[8])>>8) & 0x000000ff),(GETLE32(&gpuData[6]) & 0x000000ff), ((GETLE32(&gpuData[6])>>8) & 0x000000ff));
7248     return;
7249   }
7250 }
7251
7252 ////////////////////////////////////////////////////////////////////////
7253
7254 void drawPoly3GT(unsigned char * baseAddr)
7255 {
7256  uint32_t *gpuData = ((uint32_t *) baseAddr);
7257
7258  if(GlobalTextIL && GlobalTextTP<2)
7259   {
7260    if(GlobalTextTP==0)
7261     drawPoly3TGEx4_IL(lx0,ly0,lx1,ly1,lx2,ly2,
7262                       (GETLE32(&gpuData[2]) & 0x000000ff), ((GETLE32(&gpuData[2])>>8) & 0x000000ff), (GETLE32(&gpuData[5]) & 0x000000ff), ((GETLE32(&gpuData[5])>>8) & 0x000000ff),(GETLE32(&gpuData[8]) & 0x000000ff), ((GETLE32(&gpuData[8])>>8) & 0x000000ff), 
7263                       ((GETLE32(&gpuData[2])>>12) & 0x3f0), ((GETLE32(&gpuData[2])>>22) & iGPUHeightMask),
7264                       GETLE32(&gpuData[0]),GETLE32(&gpuData[3]),GETLE32(&gpuData[6]));
7265    else
7266     drawPoly3TGEx8_IL(lx0,ly0,lx1,ly1,lx2,ly2,
7267                       (GETLE32(&gpuData[2]) & 0x000000ff), ((GETLE32(&gpuData[2])>>8) & 0x000000ff), (GETLE32(&gpuData[5]) & 0x000000ff), ((GETLE32(&gpuData[5])>>8) & 0x000000ff),(GETLE32(&gpuData[8]) & 0x000000ff), ((GETLE32(&gpuData[8])>>8) & 0x000000ff), 
7268                       ((GETLE32(&gpuData[2])>>12) & 0x3f0), ((GETLE32(&gpuData[2])>>22) & iGPUHeightMask),
7269                       GETLE32(&gpuData[0]),GETLE32(&gpuData[3]),GETLE32(&gpuData[6]));
7270    return;
7271   }
7272
7273  if(!bUsingTWin)
7274   {
7275    switch (GlobalTextTP)
7276     {
7277      case 0:
7278       drawPoly3TGEx4(lx0,ly0,lx1,ly1,lx2,ly2,
7279                      (GETLE32(&gpuData[2]) & 0x000000ff), ((GETLE32(&gpuData[2])>>8) & 0x000000ff), (GETLE32(&gpuData[5]) & 0x000000ff), ((GETLE32(&gpuData[5])>>8) & 0x000000ff),(GETLE32(&gpuData[8]) & 0x000000ff), ((GETLE32(&gpuData[8])>>8) & 0x000000ff), 
7280                      ((GETLE32(&gpuData[2])>>12) & 0x3f0), ((GETLE32(&gpuData[2])>>22) & iGPUHeightMask),
7281                      GETLE32(&gpuData[0]),GETLE32(&gpuData[3]),GETLE32(&gpuData[6]));
7282       return;
7283      case 1:
7284       drawPoly3TGEx8(lx0,ly0,lx1,ly1,lx2,ly2,
7285                      (GETLE32(&gpuData[2]) & 0x000000ff), ((GETLE32(&gpuData[2])>>8) & 0x000000ff), (GETLE32(&gpuData[5]) & 0x000000ff), ((GETLE32(&gpuData[5])>>8) & 0x000000ff),(GETLE32(&gpuData[8]) & 0x000000ff), ((GETLE32(&gpuData[8])>>8) & 0x000000ff), 
7286                      ((GETLE32(&gpuData[2])>>12) & 0x3f0), ((GETLE32(&gpuData[2])>>22) & iGPUHeightMask),
7287                      GETLE32(&gpuData[0]),GETLE32(&gpuData[3]),GETLE32(&gpuData[6]));
7288       return;
7289      case 2:
7290       drawPoly3TGD(lx0,ly0,lx1,ly1,lx2,ly2,(GETLE32(&gpuData[2]) & 0x000000ff), ((GETLE32(&gpuData[2])>>8) & 0x000000ff), (GETLE32(&gpuData[5]) & 0x000000ff), ((GETLE32(&gpuData[5])>>8) & 0x000000ff),(GETLE32(&gpuData[8]) & 0x000000ff), ((GETLE32(&gpuData[8])>>8) & 0x000000ff),GETLE32(&gpuData[0]),GETLE32(&gpuData[3]),GETLE32(&gpuData[6]));
7291       return;
7292     }
7293    return;
7294   }
7295
7296  switch(GlobalTextTP)
7297   {
7298    case 0:
7299     drawPoly3TGEx4_TW(lx0,ly0,lx1,ly1,lx2,ly2,
7300                       (GETLE32(&gpuData[2]) & 0x000000ff), ((GETLE32(&gpuData[2])>>8) & 0x000000ff), (GETLE32(&gpuData[5]) & 0x000000ff), ((GETLE32(&gpuData[5])>>8) & 0x000000ff),(GETLE32(&gpuData[8]) & 0x000000ff), ((GETLE32(&gpuData[8])>>8) & 0x000000ff), 
7301                       ((GETLE32(&gpuData[2])>>12) & 0x3f0), ((GETLE32(&gpuData[2])>>22) & iGPUHeightMask),
7302                       GETLE32(&gpuData[0]),GETLE32(&gpuData[3]),GETLE32(&gpuData[6]));
7303     return;
7304    case 1:
7305     drawPoly3TGEx8_TW(lx0,ly0,lx1,ly1,lx2,ly2,
7306                       (GETLE32(&gpuData[2]) & 0x000000ff), ((GETLE32(&gpuData[2])>>8) & 0x000000ff), (GETLE32(&gpuData[5]) & 0x000000ff), ((GETLE32(&gpuData[5])>>8) & 0x000000ff),(GETLE32(&gpuData[8]) & 0x000000ff), ((GETLE32(&gpuData[8])>>8) & 0x000000ff), 
7307                       ((GETLE32(&gpuData[2])>>12) & 0x3f0), ((GETLE32(&gpuData[2])>>22) & iGPUHeightMask),
7308                       GETLE32(&gpuData[0]),GETLE32(&gpuData[3]),GETLE32(&gpuData[6]));
7309     return;
7310    case 2:
7311     drawPoly3TGD_TW(lx0,ly0,lx1,ly1,lx2,ly2,(GETLE32(&gpuData[2]) & 0x000000ff), ((GETLE32(&gpuData[2])>>8) & 0x000000ff), (GETLE32(&gpuData[5]) & 0x000000ff), ((GETLE32(&gpuData[5])>>8) & 0x000000ff),(GETLE32(&gpuData[8]) & 0x000000ff), ((GETLE32(&gpuData[8])>>8) & 0x000000ff),GETLE32(&gpuData[0]),GETLE32(&gpuData[3]),GETLE32(&gpuData[6]));
7312     return;
7313   }
7314 }              
7315
7316 ////////////////////////////////////////////////////////////////////////
7317
7318 void drawPoly4GT(unsigned char *baseAddr)
7319 {
7320  uint32_t *gpuData = ((uint32_t *) baseAddr);
7321
7322  if(GlobalTextIL && GlobalTextTP<2)
7323   {
7324    if(GlobalTextTP==0)
7325     drawPoly4TGEx4_TRI_IL(lx0,ly0,lx1,ly1,lx3,ly3,lx2,ly2,
7326                           (GETLE32(&gpuData[2]) & 0x000000ff), ((GETLE32(&gpuData[2])>>8) & 0x000000ff), (GETLE32(&gpuData[5]) & 0x000000ff), ((GETLE32(&gpuData[5])>>8) & 0x000000ff),(GETLE32(&gpuData[11]) & 0x000000ff), ((GETLE32(&gpuData[11])>>8) & 0x000000ff),(GETLE32(&gpuData[8]) & 0x000000ff), ((GETLE32(&gpuData[8])>>8) & 0x000000ff),
7327                           ((GETLE32(&gpuData[2])>>12) & 0x3f0),((GETLE32(&gpuData[2])>>22) & iGPUHeightMask),
7328                           GETLE32(&gpuData[0]),GETLE32(&gpuData[3]),GETLE32(&gpuData[6]),GETLE32(&gpuData[9]));
7329    else
7330     drawPoly4TGEx8_TRI_IL(lx0,ly0,lx1,ly1,lx3,ly3,lx2,ly2,
7331                           (GETLE32(&gpuData[2]) & 0x000000ff), ((GETLE32(&gpuData[2])>>8) & 0x000000ff), (GETLE32(&gpuData[5]) & 0x000000ff), ((GETLE32(&gpuData[5])>>8) & 0x000000ff),(GETLE32(&gpuData[11]) & 0x000000ff), ((GETLE32(&gpuData[11])>>8) & 0x000000ff),(GETLE32(&gpuData[8]) & 0x000000ff), ((GETLE32(&gpuData[8])>>8) & 0x000000ff),
7332                           ((GETLE32(&gpuData[2])>>12) & 0x3f0),((GETLE32(&gpuData[2])>>22) & iGPUHeightMask),
7333                           GETLE32(&gpuData[0]),GETLE32(&gpuData[3]),GETLE32(&gpuData[6]),GETLE32(&gpuData[9]));
7334    return;
7335   }
7336
7337  if(!bUsingTWin)
7338   {
7339 #ifdef POLYQUAD3GT
7340    if(IsNoRect())
7341     {
7342      switch (GlobalTextTP)
7343       {
7344        case 0:
7345         drawPoly4TGEx4_TRI(lx0,ly0,lx1,ly1,lx3,ly3,lx2,ly2,
7346                       (GETLE32(&gpuData[2]) & 0x000000ff), ((GETLE32(&gpuData[2])>>8) & 0x000000ff), (GETLE32(&gpuData[5]) & 0x000000ff), ((GETLE32(&gpuData[5])>>8) & 0x000000ff),(GETLE32(&gpuData[11]) & 0x000000ff), ((GETLE32(&gpuData[11])>>8) & 0x000000ff),(GETLE32(&gpuData[8]) & 0x000000ff), ((GETLE32(&gpuData[8])>>8) & 0x000000ff),
7347                       ((GETLE32(&gpuData[2])>>12) & 0x3f0),((GETLE32(&gpuData[2])>>22) & iGPUHeightMask),
7348                        GETLE32(&gpuData[0]),GETLE32(&gpuData[3]),GETLE32(&gpuData[6]),GETLE32(&gpuData[9]));
7349
7350         return;
7351        case 1:
7352         drawPoly4TGEx8_TRI(lx0,ly0,lx1,ly1,lx3,ly3,lx2,ly2,
7353                       (GETLE32(&gpuData[2]) & 0x000000ff), ((GETLE32(&gpuData[2])>>8) & 0x000000ff), (GETLE32(&gpuData[5]) & 0x000000ff), ((GETLE32(&gpuData[5])>>8) & 0x000000ff),(GETLE32(&gpuData[11]) & 0x000000ff), ((GETLE32(&gpuData[11])>>8) & 0x000000ff),(GETLE32(&gpuData[8]) & 0x000000ff), ((GETLE32(&gpuData[8])>>8) & 0x000000ff),
7354                       ((GETLE32(&gpuData[2])>>12) & 0x3f0),((GETLE32(&gpuData[2])>>22) & iGPUHeightMask),
7355                       GETLE32(&gpuData[0]),GETLE32(&gpuData[3]),GETLE32(&gpuData[6]),GETLE32(&gpuData[9]));
7356         return;
7357        case 2:
7358         drawPoly4TGD_TRI(lx0,ly0,lx1,ly1,lx3,ly3,lx2,ly2,(GETLE32(&gpuData[2]) & 0x000000ff),((GETLE32(&gpuData[2])>>8) & 0x000000ff), (GETLE32(&gpuData[5]) & 0x000000ff), ((GETLE32(&gpuData[5])>>8) & 0x000000ff),(GETLE32(&gpuData[11]) & 0x000000ff), ((GETLE32(&gpuData[11])>>8) & 0x000000ff),(GETLE32(&gpuData[8]) & 0x000000ff), ((GETLE32(&gpuData[8])>>8) & 0x000000ff),GETLE32(&gpuData[0]),GETLE32(&gpuData[3]),GETLE32(&gpuData[6]),GETLE32(&gpuData[9]));
7359         return;
7360       }
7361      return;
7362     }
7363 #endif
7364
7365    switch (GlobalTextTP)
7366     {
7367      case 0:
7368       drawPoly4TGEx4(lx0,ly0,lx1,ly1,lx3,ly3,lx2,ly2,
7369                     (GETLE32(&gpuData[2]) & 0x000000ff), ((GETLE32(&gpuData[2])>>8) & 0x000000ff), (GETLE32(&gpuData[5]) & 0x000000ff), ((GETLE32(&gpuData[5])>>8) & 0x000000ff),(GETLE32(&gpuData[11]) & 0x000000ff), ((GETLE32(&gpuData[11])>>8) & 0x000000ff),(GETLE32(&gpuData[8]) & 0x000000ff), ((GETLE32(&gpuData[8])>>8) & 0x000000ff),
7370                     ((GETLE32(&gpuData[2])>>12) & 0x3f0),((GETLE32(&gpuData[2])>>22) & iGPUHeightMask),
7371                      GETLE32(&gpuData[0]),GETLE32(&gpuData[3]),GETLE32(&gpuData[6]),GETLE32(&gpuData[9]));
7372
7373       return;
7374      case 1:
7375       drawPoly4TGEx8(lx0,ly0,lx1,ly1,lx3,ly3,lx2,ly2,
7376                     (GETLE32(&gpuData[2]) & 0x000000ff), ((GETLE32(&gpuData[2])>>8) & 0x000000ff), (GETLE32(&gpuData[5]) & 0x000000ff), ((GETLE32(&gpuData[5])>>8) & 0x000000ff),(GETLE32(&gpuData[11]) & 0x000000ff), ((GETLE32(&gpuData[11])>>8) & 0x000000ff),(GETLE32(&gpuData[8]) & 0x000000ff), ((GETLE32(&gpuData[8])>>8) & 0x000000ff),
7377                     ((GETLE32(&gpuData[2])>>12) & 0x3f0),((GETLE32(&gpuData[2])>>22) & iGPUHeightMask),
7378                     GETLE32(&gpuData[0]),GETLE32(&gpuData[3]),GETLE32(&gpuData[6]),GETLE32(&gpuData[9]));
7379       return;
7380      case 2:
7381       drawPoly4TGD(lx0,ly0,lx1,ly1,lx3,ly3,lx2,ly2,(GETLE32(&gpuData[2]) & 0x000000ff),((GETLE32(&gpuData[2])>>8) & 0x000000ff), (GETLE32(&gpuData[5]) & 0x000000ff), ((GETLE32(&gpuData[5])>>8) & 0x000000ff),(GETLE32(&gpuData[11]) & 0x000000ff), ((GETLE32(&gpuData[11])>>8) & 0x000000ff),(GETLE32(&gpuData[8]) & 0x000000ff), ((GETLE32(&gpuData[8])>>8) & 0x000000ff),GETLE32(&gpuData[0]),GETLE32(&gpuData[3]),GETLE32(&gpuData[6]),GETLE32(&gpuData[9]));
7382       return;
7383     }
7384    return;
7385   }
7386
7387  switch (GlobalTextTP)
7388   {
7389    case 0:
7390     drawPoly4TGEx4_TW(lx0,ly0,lx1,ly1,lx3,ly3,lx2,ly2,
7391                       (GETLE32(&gpuData[2]) & 0x000000ff), ((GETLE32(&gpuData[2])>>8) & 0x000000ff), (GETLE32(&gpuData[5]) & 0x000000ff), ((GETLE32(&gpuData[5])>>8) & 0x000000ff),(GETLE32(&gpuData[11]) & 0x000000ff), ((GETLE32(&gpuData[11])>>8) & 0x000000ff),(GETLE32(&gpuData[8]) & 0x000000ff), ((GETLE32(&gpuData[8])>>8) & 0x000000ff),
7392                       ((GETLE32(&gpuData[2])>>12) & 0x3f0),((GETLE32(&gpuData[2])>>22) & iGPUHeightMask),
7393                       GETLE32(&gpuData[0]),GETLE32(&gpuData[3]),GETLE32(&gpuData[6]),GETLE32(&gpuData[9]));
7394     return;
7395    case 1:
7396     drawPoly4TGEx8_TW(lx0,ly0,lx1,ly1,lx3,ly3,lx2,ly2,
7397                       (GETLE32(&gpuData[2]) & 0x000000ff), ((GETLE32(&gpuData[2])>>8) & 0x000000ff), (GETLE32(&gpuData[5]) & 0x000000ff), ((GETLE32(&gpuData[5])>>8) & 0x000000ff),(GETLE32(&gpuData[11]) & 0x000000ff), ((GETLE32(&gpuData[11])>>8) & 0x000000ff),(GETLE32(&gpuData[8]) & 0x000000ff), ((GETLE32(&gpuData[8])>>8) & 0x000000ff),
7398                       ((GETLE32(&gpuData[2])>>12) & 0x3f0),((GETLE32(&gpuData[2])>>22) & iGPUHeightMask),
7399                       GETLE32(&gpuData[0]),GETLE32(&gpuData[3]),GETLE32(&gpuData[6]),GETLE32(&gpuData[9]));
7400     return;
7401    case 2:
7402     drawPoly4TGD_TW(lx0,ly0,lx1,ly1,lx3,ly3,lx2,ly2,(GETLE32(&gpuData[2]) & 0x000000ff),((GETLE32(&gpuData[2])>>8) & 0x000000ff), (GETLE32(&gpuData[5]) & 0x000000ff), ((GETLE32(&gpuData[5])>>8) & 0x000000ff),(GETLE32(&gpuData[11]) & 0x000000ff), ((GETLE32(&gpuData[11])>>8) & 0x000000ff),(GETLE32(&gpuData[8]) & 0x000000ff), ((GETLE32(&gpuData[8])>>8) & 0x000000ff),GETLE32(&gpuData[0]),GETLE32(&gpuData[3]),GETLE32(&gpuData[6]),GETLE32(&gpuData[9]));
7403     return;
7404   }
7405 }
7406                 
7407 ////////////////////////////////////////////////////////////////////////
7408 // SPRITE FUNCS
7409 ////////////////////////////////////////////////////////////////////////
7410
7411 void DrawSoftwareSpriteTWin(unsigned char * baseAddr,int32_t w,int32_t h)
7412
7413  uint32_t *gpuData = (uint32_t *)baseAddr;
7414  short sx0,sy0,sx1,sy1,sx2,sy2,sx3,sy3;
7415  short tx0,ty0,tx1,ty1,tx2,ty2,tx3,ty3;
7416
7417  sx0=lx0;
7418  sy0=ly0;
7419
7420  sx0=sx3=sx0+PSXDisplay.DrawOffset.x;
7421  sx1=sx2=sx0+w;
7422  sy0=sy1=sy0+PSXDisplay.DrawOffset.y;
7423  sy2=sy3=sy0+h;
7424  
7425  tx0=tx3=GETLE32(&gpuData[2])&0xff;
7426  tx1=tx2=tx0+w;
7427  ty0=ty1=(GETLE32(&gpuData[2])>>8)&0xff;
7428  ty2=ty3=ty0+h;
7429
7430  switch (GlobalTextTP)
7431   {
7432    case 0:
7433     drawPoly4TEx4_TW_S(sx0,sy0,sx1,sy1,sx2,sy2,sx3,sy3,
7434                      tx0,ty0,tx1,ty1,tx2,ty2,tx3,ty3, 
7435                      ((GETLE32(&gpuData[2])>>12) & 0x3f0), ((GETLE32(&gpuData[2])>>22) & iGPUHeightMask));
7436     return;
7437    case 1:
7438     drawPoly4TEx8_TW_S(sx0,sy0,sx1,sy1,sx2,sy2,sx3,sy3,
7439                        tx0,ty0,tx1,ty1,tx2,ty2,tx3,ty3, 
7440                        ((GETLE32(&gpuData[2])>>12) & 0x3f0), ((GETLE32(&gpuData[2])>>22) & iGPUHeightMask));
7441     return;
7442    case 2:
7443     drawPoly4TD_TW_S(sx0,sy0,sx1,sy1,sx2,sy2,sx3,sy3,
7444                      tx0,ty0,tx1,ty1,tx2,ty2,tx3,ty3);
7445     return;
7446   }
7447 }                                                   
7448
7449 ////////////////////////////////////////////////////////////////////////
7450
7451 void DrawSoftwareSpriteMirror(unsigned char * baseAddr,int32_t w,int32_t h)
7452 {
7453  int32_t sprtY,sprtX,sprtW,sprtH,lXDir,lYDir;
7454  int32_t clutY0,clutX0,clutP,textX0,textY0,sprtYa,sprCY,sprCX,sprA;
7455  short tC;
7456  uint32_t *gpuData = (uint32_t *)baseAddr;
7457  sprtY = ly0;
7458  sprtX = lx0;
7459  sprtH = h;
7460  sprtW = w;
7461  clutY0 = (GETLE32(&gpuData[2])>>22) & iGPUHeightMask;
7462  clutX0 = (GETLE32(&gpuData[2])>>12) & 0x3f0;
7463  clutP  = (clutY0<<11) + (clutX0<<1);
7464  textY0 = ((GETLE32(&gpuData[2])>>8) & 0x000000ff) + GlobalTextAddrY;
7465  textX0 = (GETLE32(&gpuData[2]) & 0x000000ff);
7466
7467  sprtX+=PSXDisplay.DrawOffset.x;
7468  sprtY+=PSXDisplay.DrawOffset.y;
7469
7470 // while (sprtX>1023)             sprtX-=1024;
7471 // while (sprtY>MAXYLINESMIN1)    sprtY-=MAXYLINES;
7472
7473  if(sprtX>drawW)
7474   {
7475 //   if((sprtX+sprtW)>1023) sprtX-=1024;
7476 //   else return;
7477    return;
7478   }
7479
7480  if(sprtY>drawH)
7481   {
7482 //   if ((sprtY+sprtH)>MAXYLINESMIN1) sprtY-=MAXYLINES;
7483 //   else return;
7484    return;
7485   }
7486
7487  if(sprtY<drawY)
7488   {
7489    if((sprtY+sprtH)<drawY) return;
7490    sprtH-=(drawY-sprtY);
7491    textY0+=(drawY-sprtY);
7492    sprtY=drawY;
7493   }
7494
7495  if(sprtX<drawX)
7496   {
7497    if((sprtX+sprtW)<drawX) return;
7498    sprtW-=(drawX-sprtX);
7499    textX0+=(drawX-sprtX);
7500    sprtX=drawX;
7501   }
7502
7503  if((sprtY+sprtH)>drawH) sprtH=drawH-sprtY+1;
7504  if((sprtX+sprtW)>drawW) sprtW=drawW-sprtX+1;
7505
7506  if(usMirror&0x1000) lXDir=-1; else lXDir=1;
7507  if(usMirror&0x2000) lYDir=-1; else lYDir=1;
7508
7509  switch (GlobalTextTP)
7510   {
7511    case 0: // texture is 4-bit
7512
7513     sprtW=sprtW/2;
7514     textX0=(GlobalTextAddrX<<1)+(textX0>>1);
7515     sprtYa=(sprtY<<10);
7516     clutP=(clutY0<<10)+clutX0;
7517     for (sprCY=0;sprCY<sprtH;sprCY++)
7518      for (sprCX=0;sprCX<sprtW;sprCX++)
7519       {
7520        tC= psxVub[((textY0+(sprCY*lYDir))<<11) + textX0 +(sprCX*lXDir)];
7521        sprA=sprtYa+(sprCY<<10)+sprtX + (sprCX<<1);
7522        GetTextureTransColG_SPR(&psxVuw[sprA],GETLE16(&psxVuw[clutP+((tC>>4)&0xf)]));
7523        GetTextureTransColG_SPR(&psxVuw[sprA+1],GETLE16(&psxVuw[clutP+(tC&0xf)]));
7524       }
7525     return;
7526
7527    case 1: 
7528
7529     clutP>>=1;
7530     for(sprCY=0;sprCY<sprtH;sprCY++)
7531      for(sprCX=0;sprCX<sprtW;sprCX++)
7532       { 
7533        tC = psxVub[((textY0+(sprCY*lYDir))<<11)+(GlobalTextAddrX<<1) + textX0 + (sprCX*lXDir)] & 0xff;
7534        GetTextureTransColG_SPR(&psxVuw[((sprtY+sprCY)<<10)+sprtX + sprCX],psxVuw[clutP+tC]);
7535       }
7536      return;
7537
7538    case 2:
7539
7540     for (sprCY=0;sprCY<sprtH;sprCY++)
7541      for (sprCX=0;sprCX<sprtW;sprCX++)
7542       { 
7543        GetTextureTransColG_SPR(&psxVuw[((sprtY+sprCY)<<10)+sprtX+sprCX],
7544            GETLE16(&psxVuw[((textY0+(sprCY*lYDir))<<10)+GlobalTextAddrX + textX0 +(sprCX*lXDir)]));
7545       }
7546      return;
7547   }
7548 }
7549
7550 ////////////////////////////////////////////////////////////////////////
7551
7552 void DrawSoftwareSprite_IL(unsigned char * baseAddr,short w,short h,int32_t tx,int32_t ty)
7553 {
7554  int32_t sprtY,sprtX,sprtW,sprtH,tdx,tdy;
7555  uint32_t *gpuData = (uint32_t *)baseAddr;
7556
7557  sprtY = ly0;
7558  sprtX = lx0;
7559  sprtH = h;
7560  sprtW = w;
7561
7562  sprtX+=PSXDisplay.DrawOffset.x;
7563  sprtY+=PSXDisplay.DrawOffset.y;
7564
7565  if(sprtX>drawW) return;
7566  if(sprtY>drawH) return;
7567
7568  tdx=tx+sprtW;
7569  tdy=ty+sprtH;
7570
7571  sprtW+=sprtX;
7572  sprtH+=sprtY;
7573
7574  // Pete is too lazy to make a faster version ;)
7575
7576  if(GlobalTextTP==0)
7577   drawPoly4TEx4_IL(sprtX,sprtY,sprtX,sprtH,sprtW,sprtH,sprtW,sprtY,
7578                    tx,ty,      tx,tdy,     tdx,tdy,    tdx,ty,     
7579                    (GETLE32(&gpuData[2])>>12) & 0x3f0, ((GETLE32(&gpuData[2])>>22) & iGPUHeightMask));
7580
7581
7582  else
7583   drawPoly4TEx8_IL(sprtX,sprtY,sprtX,sprtH,sprtW,sprtH,sprtW,sprtY,
7584                    tx,ty,      tx,tdy,     tdx,tdy,    tdx,ty,     
7585                    (GETLE32(&gpuData[2])>>12) & 0x3f0, ((GETLE32(&gpuData[2])>>22) & iGPUHeightMask));
7586 }
7587
7588 ////////////////////////////////////////////////////////////////////////
7589
7590 void DrawSoftwareSprite(unsigned char * baseAddr,short w,short h,int32_t tx,int32_t ty)
7591 {
7592  int32_t sprtY,sprtX,sprtW,sprtH;
7593  int32_t clutY0,clutX0,clutP,textX0,textY0,sprtYa,sprCY,sprCX,sprA;
7594  short tC,tC2;
7595  uint32_t *gpuData = (uint32_t *)baseAddr;
7596  unsigned char * pV;
7597  BOOL bWT,bWS;
7598
7599  if(GlobalTextIL && GlobalTextTP<2)
7600   {DrawSoftwareSprite_IL(baseAddr,w,h,tx,ty);return;}
7601
7602  sprtY = ly0;
7603  sprtX = lx0;
7604  sprtH = h;
7605  sprtW = w;
7606  clutY0 = (GETLE32(&gpuData[2])>>22) & iGPUHeightMask;
7607  clutX0 = (GETLE32(&gpuData[2])>>12) & 0x3f0;
7608
7609  clutP  = (clutY0<<11) + (clutX0<<1);
7610
7611  textY0 =ty+ GlobalTextAddrY;
7612  textX0 =tx;
7613
7614  sprtX+=PSXDisplay.DrawOffset.x;
7615  sprtY+=PSXDisplay.DrawOffset.y;
7616
7617  //while (sprtX>1023)             sprtX-=1024;
7618  //while (sprtY>MAXYLINESMIN1)    sprtY-=MAXYLINES;
7619
7620  if(sprtX>drawW)
7621   {
7622 //   if((sprtX+sprtW)>1023) sprtX-=1024;
7623 //   else return;
7624    return;
7625   }
7626
7627  if(sprtY>drawH)
7628   {
7629 //   if ((sprtY+sprtH)>MAXYLINESMIN1) sprtY-=MAXYLINES;
7630 //   else return;
7631    return;
7632   }
7633
7634  if(sprtY<drawY)
7635   {
7636    if((sprtY+sprtH)<drawY) return;
7637    sprtH-=(drawY-sprtY);
7638    textY0+=(drawY-sprtY);
7639    sprtY=drawY;
7640   }
7641
7642  if(sprtX<drawX)
7643   {
7644    if((sprtX+sprtW)<drawX) return;
7645
7646    sprtW-=(drawX-sprtX);
7647    textX0+=(drawX-sprtX);
7648    sprtX=drawX;
7649   }
7650
7651  if((sprtY+sprtH)>drawH) sprtH=drawH-sprtY+1;
7652  if((sprtX+sprtW)>drawW) sprtW=drawW-sprtX+1;
7653
7654
7655  bWT=FALSE;
7656  bWS=FALSE;
7657
7658  switch (GlobalTextTP)
7659   {
7660    case 0:
7661
7662     if(textX0&1) {bWS=TRUE;sprtW--;}
7663     if(sprtW&1)  bWT=TRUE;
7664     
7665     sprtW=sprtW>>1;
7666     textX0=(GlobalTextAddrX<<1)+(textX0>>1)+(textY0<<11);
7667     sprtYa=(sprtY<<10)+sprtX;
7668     clutP=(clutY0<<10)+clutX0;
7669
7670 #ifdef FASTSOLID
7671  
7672     if(!bCheckMask && !DrawSemiTrans)
7673      {
7674       for (sprCY=0;sprCY<sprtH;sprCY++)
7675        {
7676         sprA=sprtYa+(sprCY<<10);
7677         pV=&psxVub[(sprCY<<11)+textX0];
7678
7679         if(bWS)
7680          {
7681           tC=*pV++;
7682           GetTextureTransColG_S(&psxVuw[sprA++],GETLE16(&psxVuw[clutP+((tC>>4)&0xf)]));
7683          }
7684
7685         for (sprCX=0;sprCX<sprtW;sprCX++,sprA+=2)
7686          { 
7687           tC=*pV++;
7688
7689           GetTextureTransColG32_S((uint32_t *)&psxVuw[sprA],
7690               (((int32_t)GETLE16(&psxVuw[clutP+((tC>>4)&0xf)]))<<16)|
7691               GETLE16(&psxVuw[clutP+(tC&0x0f)]));
7692          }
7693
7694         if(bWT)
7695          {
7696           tC=*pV;
7697           GetTextureTransColG_S(&psxVuw[sprA],GETLE16(&psxVuw[clutP+(tC&0x0f)]));
7698          }
7699        }
7700       return;
7701      }
7702
7703 #endif
7704
7705     for (sprCY=0;sprCY<sprtH;sprCY++)
7706      {
7707       sprA=sprtYa+(sprCY<<10);
7708       pV=&psxVub[(sprCY<<11)+textX0];
7709
7710       if(bWS)
7711        {
7712         tC=*pV++;
7713         GetTextureTransColG_SPR(&psxVuw[sprA++],GETLE16(&psxVuw[clutP+((tC>>4)&0xf)]));
7714        }
7715
7716       for (sprCX=0;sprCX<sprtW;sprCX++,sprA+=2)
7717        { 
7718         tC=*pV++;
7719
7720         GetTextureTransColG32_SPR((uint32_t *)&psxVuw[sprA],
7721             (((int32_t)GETLE16(&psxVuw[clutP+((tC>>4)&0xf)])<<16))|
7722             GETLE16(&psxVuw[clutP+(tC&0x0f)]));
7723        }
7724
7725       if(bWT)
7726        {
7727         tC=*pV;
7728         GetTextureTransColG_SPR(&psxVuw[sprA],GETLE16(&psxVuw[clutP+(tC&0x0f)]));
7729        }
7730      }
7731     return;
7732
7733    case 1:
7734     clutP>>=1;sprtW--;
7735     textX0+=(GlobalTextAddrX<<1) + (textY0<<11);
7736
7737 #ifdef FASTSOLID
7738
7739     if(!bCheckMask && !DrawSemiTrans)
7740      {
7741       for(sprCY=0;sprCY<sprtH;sprCY++)
7742        {
7743         sprA=((sprtY+sprCY)<<10)+sprtX;
7744         pV=&psxVub[(sprCY<<11)+textX0];
7745         for(sprCX=0;sprCX<sprtW;sprCX+=2,sprA+=2)
7746          { 
7747           tC = *pV++;tC2 = *pV++;
7748           GetTextureTransColG32_S((uint32_t *)&psxVuw[sprA],
7749               (((int32_t)GETLE16(&psxVuw[clutP+tC2]))<<16)|
7750               GETLE16(&psxVuw[clutP+tC]));
7751          }
7752         if(sprCX==sprtW)
7753          GetTextureTransColG_S(&psxVuw[sprA],GETLE16(&psxVuw[clutP+(*pV)]));
7754        }
7755       return;
7756      }
7757
7758 #endif
7759
7760     for(sprCY=0;sprCY<sprtH;sprCY++)
7761      {
7762       sprA=((sprtY+sprCY)<<10)+sprtX;
7763       pV=&psxVub[(sprCY<<11)+textX0];
7764       for(sprCX=0;sprCX<sprtW;sprCX+=2,sprA+=2)
7765        { 
7766         tC = *pV++;tC2 = *pV++;
7767         GetTextureTransColG32_SPR((uint32_t *)&psxVuw[sprA],
7768             (((int32_t)GETLE16(&psxVuw[clutP+tC2]))<<16)|
7769             GETLE16(&psxVuw[clutP+tC]));
7770        }
7771       if(sprCX==sprtW)
7772        GetTextureTransColG_SPR(&psxVuw[sprA],GETLE16(&psxVuw[clutP+(*pV)]));
7773      }
7774     return;
7775
7776    case 2:
7777
7778     textX0+=(GlobalTextAddrX) + (textY0<<10);
7779     sprtW--;
7780
7781 #ifdef FASTSOLID
7782
7783     if(!bCheckMask && !DrawSemiTrans)
7784      {
7785       for (sprCY=0;sprCY<sprtH;sprCY++)
7786        {
7787         sprA=((sprtY+sprCY)<<10)+sprtX;
7788
7789         for (sprCX=0;sprCX<sprtW;sprCX+=2,sprA+=2)
7790          { 
7791           GetTextureTransColG32_S((uint32_t *)&psxVuw[sprA],
7792               (((int32_t)GETLE16(&psxVuw[(sprCY<<10) + textX0 + sprCX +1]))<<16)|
7793               GETLE16(&psxVuw[(sprCY<<10) + textX0 + sprCX]));
7794          }
7795         if(sprCX==sprtW)
7796          GetTextureTransColG_S(&psxVuw[sprA],
7797               GETLE16(&psxVuw[(sprCY<<10) + textX0 + sprCX]));
7798
7799        }
7800       return;
7801      }
7802
7803 #endif
7804
7805     for (sprCY=0;sprCY<sprtH;sprCY++)
7806      {
7807       sprA=((sprtY+sprCY)<<10)+sprtX;
7808
7809       for (sprCX=0;sprCX<sprtW;sprCX+=2,sprA+=2)
7810        { 
7811         GetTextureTransColG32_SPR((uint32_t *)&psxVuw[sprA],
7812             (((int32_t)GETLE16(&psxVuw[(sprCY<<10) + textX0 + sprCX +1]))<<16)|
7813             GETLE16(&psxVuw[(sprCY<<10) + textX0 + sprCX]));
7814        }
7815       if(sprCX==sprtW)
7816        GetTextureTransColG_SPR(&psxVuw[sprA],
7817             GETLE16(&psxVuw[(sprCY<<10) + textX0 + sprCX]));
7818
7819      }
7820     return;
7821    }                
7822 }
7823  
7824 ///////////////////////////////////////////////////////////////////////
7825
7826 /////////////////////////////////////////////////////////////////
7827 /////////////////////////////////////////////////////////////////
7828 /////////////////////////////////////////////////////////////////
7829 // LINE FUNCS
7830 ////////////////////////////////////////////////////////////////////////
7831 /////////////////////////////////////////////////////////////////
7832 /////////////////////////////////////////////////////////////////
7833
7834
7835 ///////////////////////////////////////////////////////////////////////
7836
7837 void Line_E_SE_Shade(int x0, int y0, int x1, int y1, uint32_t rgb0, uint32_t rgb1)
7838 {
7839     int dx, dy, incrE, incrSE, d;
7840                 uint32_t r0, g0, b0, r1, g1, b1;
7841                 int32_t dr, dg, db;
7842
7843                 r0 = (rgb0 & 0x00ff0000);
7844                 g0 = (rgb0 & 0x0000ff00) << 8;
7845                 b0 = (rgb0 & 0x000000ff) << 16;
7846                 r1 = (rgb1 & 0x00ff0000);
7847                 g1 = (rgb1 & 0x0000ff00) << 8;
7848                 b1 = (rgb1 & 0x000000ff) << 16;
7849
7850     dx = x1 - x0;
7851     dy = y1 - y0;
7852
7853                 if (dx > 0)
7854                 {
7855                         dr = ((int32_t)r1 - (int32_t)r0) / dx;
7856                         dg = ((int32_t)g1 - (int32_t)g0) / dx;
7857                         db = ((int32_t)b1 - (int32_t)b0) / dx;
7858                 }
7859                 else
7860                 {
7861                         dr = ((int32_t)r1 - (int32_t)r0);
7862                         dg = ((int32_t)g1 - (int32_t)g0);
7863                         db = ((int32_t)b1 - (int32_t)b0);
7864                 }
7865
7866     d = 2*dy - dx;              /* Initial value of d */
7867     incrE = 2*dy;               /* incr. used for move to E */
7868     incrSE = 2*(dy - dx);       /* incr. used for move to SE */
7869
7870                 if ((x0>=drawX)&&(x0<drawW)&&(y0>=drawY)&&(y0<drawH))
7871                         GetShadeTransCol(&psxVuw[(y0<<10)+x0],(unsigned short)(((r0 >> 9)&0x7c00)|((g0 >> 14)&0x03e0)|((b0 >> 19)&0x001f)));
7872     while(x0 < x1)
7873     {
7874         if (d <= 0)
7875         {
7876             d = d + incrE;              /* Choose E */
7877         }
7878         else
7879         {
7880             d = d + incrSE;             /* Choose SE */
7881             y0++;
7882         }
7883         x0++;
7884
7885                                 r0+=dr;
7886                                 g0+=dg;
7887                                 b0+=db;
7888
7889                                 if ((x0>=drawX)&&(x0<drawW)&&(y0>=drawY)&&(y0<drawH))
7890                                         GetShadeTransCol(&psxVuw[(y0<<10)+x0],(unsigned short)(((r0 >> 9)&0x7c00)|((g0 >> 14)&0x03e0)|((b0 >> 19)&0x001f)));
7891     }
7892 }
7893
7894 ///////////////////////////////////////////////////////////////////////
7895
7896 void Line_S_SE_Shade(int x0, int y0, int x1, int y1, uint32_t rgb0, uint32_t rgb1)
7897 {
7898     int dx, dy, incrS, incrSE, d;
7899                 uint32_t r0, g0, b0, r1, g1, b1;
7900                 int32_t dr, dg, db;
7901
7902                 r0 = (rgb0 & 0x00ff0000);
7903                 g0 = (rgb0 & 0x0000ff00) << 8;
7904                 b0 = (rgb0 & 0x000000ff) << 16;
7905                 r1 = (rgb1 & 0x00ff0000);
7906                 g1 = (rgb1 & 0x0000ff00) << 8;
7907                 b1 = (rgb1 & 0x000000ff) << 16;
7908
7909     dx = x1 - x0;
7910     dy = y1 - y0;
7911
7912                 if (dy > 0)
7913                 {
7914                         dr = ((int32_t)r1 - (int32_t)r0) / dy;
7915                         dg = ((int32_t)g1 - (int32_t)g0) / dy;
7916                         db = ((int32_t)b1 - (int32_t)b0) / dy;
7917                 }
7918                 else
7919                 {
7920                         dr = ((int32_t)r1 - (int32_t)r0);
7921                         dg = ((int32_t)g1 - (int32_t)g0);
7922                         db = ((int32_t)b1 - (int32_t)b0);
7923                 }
7924
7925     d = 2*dx - dy;              /* Initial value of d */
7926     incrS = 2*dx;               /* incr. used for move to S */
7927     incrSE = 2*(dx - dy);       /* incr. used for move to SE */
7928
7929                 if ((x0>=drawX)&&(x0<drawW)&&(y0>=drawY)&&(y0<drawH))
7930                         GetShadeTransCol(&psxVuw[(y0<<10)+x0],(unsigned short)(((r0 >> 9)&0x7c00)|((g0 >> 14)&0x03e0)|((b0 >> 19)&0x001f)));
7931     while(y0 < y1)
7932     {
7933         if (d <= 0)
7934         {
7935             d = d + incrS;              /* Choose S */
7936         }
7937         else
7938         {
7939             d = d + incrSE;             /* Choose SE */
7940             x0++;
7941         }
7942         y0++;
7943
7944                                 r0+=dr;
7945                                 g0+=dg;
7946                                 b0+=db;
7947
7948                                 if ((x0>=drawX)&&(x0<drawW)&&(y0>=drawY)&&(y0<drawH))
7949                                         GetShadeTransCol(&psxVuw[(y0<<10)+x0],(unsigned short)(((r0 >> 9)&0x7c00)|((g0 >> 14)&0x03e0)|((b0 >> 19)&0x001f)));
7950     }
7951 }
7952
7953 ///////////////////////////////////////////////////////////////////////
7954
7955 void Line_N_NE_Shade(int x0, int y0, int x1, int y1, uint32_t rgb0, uint32_t rgb1)
7956 {
7957     int dx, dy, incrN, incrNE, d;
7958                 uint32_t r0, g0, b0, r1, g1, b1;
7959                 int32_t dr, dg, db;
7960
7961                 r0 = (rgb0 & 0x00ff0000);
7962                 g0 = (rgb0 & 0x0000ff00) << 8;
7963                 b0 = (rgb0 & 0x000000ff) << 16;
7964                 r1 = (rgb1 & 0x00ff0000);
7965                 g1 = (rgb1 & 0x0000ff00) << 8;
7966                 b1 = (rgb1 & 0x000000ff) << 16;
7967
7968     dx = x1 - x0;
7969     dy = -(y1 - y0);
7970
7971                 if (dy > 0)
7972                 {
7973                         dr = ((int32_t)r1 - (int32_t)r0) / dy;
7974                         dg = ((int32_t)g1 - (int32_t)g0) / dy;
7975                         db = ((int32_t)b1 - (int32_t)b0) / dy;
7976                 }
7977                 else
7978                 {
7979                         dr = ((int32_t)r1 - (int32_t)r0);
7980                         dg = ((int32_t)g1 - (int32_t)g0);
7981                         db = ((int32_t)b1 - (int32_t)b0);
7982                 }
7983
7984     d = 2*dx - dy;              /* Initial value of d */
7985     incrN = 2*dx;               /* incr. used for move to N */
7986     incrNE = 2*(dx - dy);       /* incr. used for move to NE */
7987
7988                 if ((x0>=drawX)&&(x0<drawW)&&(y0>=drawY)&&(y0<drawH))
7989                         GetShadeTransCol(&psxVuw[(y0<<10)+x0],(unsigned short)(((r0 >> 9)&0x7c00)|((g0 >> 14)&0x03e0)|((b0 >> 19)&0x001f)));
7990     while(y0 > y1)
7991     {
7992         if (d <= 0)
7993         {
7994             d = d + incrN;              /* Choose N */
7995         }
7996         else
7997         {
7998             d = d + incrNE;             /* Choose NE */
7999             x0++;
8000         }
8001         y0--;
8002
8003                                 r0+=dr;
8004                                 g0+=dg;
8005                                 b0+=db;
8006
8007                                 if ((x0>=drawX)&&(x0<drawW)&&(y0>=drawY)&&(y0<drawH))
8008                                         GetShadeTransCol(&psxVuw[(y0<<10)+x0],(unsigned short)(((r0 >> 9)&0x7c00)|((g0 >> 14)&0x03e0)|((b0 >> 19)&0x001f)));
8009     }
8010 }
8011
8012 ///////////////////////////////////////////////////////////////////////
8013
8014 void Line_E_NE_Shade(int x0, int y0, int x1, int y1, uint32_t rgb0, uint32_t rgb1)
8015 {
8016     int dx, dy, incrE, incrNE, d;
8017                 uint32_t r0, g0, b0, r1, g1, b1;
8018                 int32_t dr, dg, db;
8019
8020                 r0 = (rgb0 & 0x00ff0000);
8021                 g0 = (rgb0 & 0x0000ff00) << 8;
8022                 b0 = (rgb0 & 0x000000ff) << 16;
8023                 r1 = (rgb1 & 0x00ff0000);
8024                 g1 = (rgb1 & 0x0000ff00) << 8;
8025                 b1 = (rgb1 & 0x000000ff) << 16;
8026
8027     dx = x1 - x0;
8028     dy = -(y1 - y0);
8029
8030                 if (dx > 0)
8031                 {
8032                         dr = ((int32_t)r1 - (int32_t)r0) / dx;
8033                         dg = ((int32_t)g1 - (int32_t)g0) / dx;
8034                         db = ((int32_t)b1 - (int32_t)b0) / dx;
8035                 }
8036                 else
8037                 {
8038                         dr = ((int32_t)r1 - (int32_t)r0);
8039                         dg = ((int32_t)g1 - (int32_t)g0);
8040                         db = ((int32_t)b1 - (int32_t)b0);
8041                 }
8042
8043     d = 2*dy - dx;              /* Initial value of d */
8044     incrE = 2*dy;               /* incr. used for move to E */
8045     incrNE = 2*(dy - dx);       /* incr. used for move to NE */
8046
8047                 if ((x0>=drawX)&&(x0<drawW)&&(y0>=drawY)&&(y0<drawH))
8048                         GetShadeTransCol(&psxVuw[(y0<<10)+x0],(unsigned short)(((r0 >> 9)&0x7c00)|((g0 >> 14)&0x03e0)|((b0 >> 19)&0x001f)));
8049     while(x0 < x1)
8050     {
8051         if (d <= 0)
8052         {
8053             d = d + incrE;              /* Choose E */
8054         }
8055         else
8056         {
8057             d = d + incrNE;             /* Choose NE */
8058             y0--;
8059         }
8060         x0++;
8061
8062                                 r0+=dr;
8063                                 g0+=dg;
8064                                 b0+=db;
8065
8066                                 if ((x0>=drawX)&&(x0<drawW)&&(y0>=drawY)&&(y0<drawH))
8067                                         GetShadeTransCol(&psxVuw[(y0<<10)+x0],(unsigned short)(((r0 >> 9)&0x7c00)|((g0 >> 14)&0x03e0)|((b0 >> 19)&0x001f)));
8068     }
8069 }
8070
8071 ///////////////////////////////////////////////////////////////////////
8072
8073 void VertLineShade(int x, int y0, int y1, uint32_t rgb0, uint32_t rgb1)
8074 {
8075   int y, dy;
8076         uint32_t r0, g0, b0, r1, g1, b1;
8077         int32_t dr, dg, db;
8078
8079         r0 = (rgb0 & 0x00ff0000);
8080         g0 = (rgb0 & 0x0000ff00) << 8;
8081         b0 = (rgb0 & 0x000000ff) << 16;
8082         r1 = (rgb1 & 0x00ff0000);
8083         g1 = (rgb1 & 0x0000ff00) << 8;
8084         b1 = (rgb1 & 0x000000ff) << 16;
8085
8086         dy = (y1 - y0);
8087
8088         if (dy > 0)
8089         {
8090                 dr = ((int32_t)r1 - (int32_t)r0) / dy;
8091                 dg = ((int32_t)g1 - (int32_t)g0) / dy;
8092                 db = ((int32_t)b1 - (int32_t)b0) / dy;
8093         }
8094         else
8095         {
8096                 dr = ((int32_t)r1 - (int32_t)r0);
8097                 dg = ((int32_t)g1 - (int32_t)g0);
8098                 db = ((int32_t)b1 - (int32_t)b0);
8099         }
8100
8101         if (y0 < drawY)
8102         {
8103                 r0+=dr*(drawY - y0);
8104                 g0+=dg*(drawY - y0);
8105                 b0+=db*(drawY - y0);
8106                 y0 = drawY;
8107         }
8108
8109         if (y1 > drawH)
8110                 y1 = drawH;
8111
8112   for (y = y0; y <= y1; y++)
8113         {
8114                 GetShadeTransCol(&psxVuw[(y<<10)+x],(unsigned short)(((r0 >> 9)&0x7c00)|((g0 >> 14)&0x03e0)|((b0 >> 19)&0x001f)));
8115                 r0+=dr;
8116                 g0+=dg;
8117                 b0+=db;
8118         }
8119 }
8120
8121 ///////////////////////////////////////////////////////////////////////
8122
8123 void HorzLineShade(int y, int x0, int x1, uint32_t rgb0, uint32_t rgb1)
8124 {
8125   int x, dx;
8126         uint32_t r0, g0, b0, r1, g1, b1;
8127         int32_t dr, dg, db;
8128
8129         r0 = (rgb0 & 0x00ff0000);
8130         g0 = (rgb0 & 0x0000ff00) << 8;
8131         b0 = (rgb0 & 0x000000ff) << 16;
8132         r1 = (rgb1 & 0x00ff0000);
8133         g1 = (rgb1 & 0x0000ff00) << 8;
8134         b1 = (rgb1 & 0x000000ff) << 16;
8135
8136         dx = (x1 - x0);
8137
8138         if (dx > 0)
8139         {
8140                 dr = ((int32_t)r1 - (int32_t)r0) / dx;
8141                 dg = ((int32_t)g1 - (int32_t)g0) / dx;
8142                 db = ((int32_t)b1 - (int32_t)b0) / dx;
8143         }
8144         else
8145         {
8146                 dr = ((int32_t)r1 - (int32_t)r0);
8147                 dg = ((int32_t)g1 - (int32_t)g0);
8148                 db = ((int32_t)b1 - (int32_t)b0);
8149         }
8150
8151         if (x0 < drawX)
8152         {
8153                 r0+=dr*(drawX - x0);
8154                 g0+=dg*(drawX - x0);
8155                 b0+=db*(drawX - x0);
8156                 x0 = drawX;
8157         }
8158
8159         if (x1 > drawW)
8160                 x1 = drawW;
8161
8162   for (x = x0; x <= x1; x++)
8163         {
8164                 GetShadeTransCol(&psxVuw[(y<<10)+x],(unsigned short)(((r0 >> 9)&0x7c00)|((g0 >> 14)&0x03e0)|((b0 >> 19)&0x001f)));
8165                 r0+=dr;
8166                 g0+=dg;
8167                 b0+=db;
8168         }
8169 }
8170
8171 ///////////////////////////////////////////////////////////////////////
8172
8173 void Line_E_SE_Flat(int x0, int y0, int x1, int y1, unsigned short colour)
8174 {
8175     int dx, dy, incrE, incrSE, d, x, y;
8176
8177     dx = x1 - x0;
8178     dy = y1 - y0;
8179     d = 2*dy - dx;              /* Initial value of d */
8180     incrE = 2*dy;               /* incr. used for move to E */
8181     incrSE = 2*(dy - dx);       /* incr. used for move to SE */
8182     x = x0;
8183     y = y0;
8184                 if ((x>=drawX)&&(x<drawW)&&(y>=drawY)&&(y<drawH))
8185                         GetShadeTransCol(&psxVuw[(y<<10)+x], colour);
8186     while(x < x1)
8187     {
8188         if (d <= 0)
8189         {
8190             d = d + incrE;              /* Choose E */
8191             x++;
8192         }
8193         else
8194         {
8195             d = d + incrSE;             /* Choose SE */
8196             x++;
8197             y++;
8198         }
8199                                 if ((x>=drawX)&&(x<drawW)&&(y>=drawY)&&(y<drawH))
8200                                         GetShadeTransCol(&psxVuw[(y<<10)+x], colour);
8201     }
8202 }
8203
8204 ///////////////////////////////////////////////////////////////////////
8205
8206 void Line_S_SE_Flat(int x0, int y0, int x1, int y1, unsigned short colour)
8207 {
8208     int dx, dy, incrS, incrSE, d, x, y;
8209
8210     dx = x1 - x0;
8211     dy = y1 - y0;
8212     d = 2*dx - dy;              /* Initial value of d */
8213     incrS = 2*dx;               /* incr. used for move to S */
8214     incrSE = 2*(dx - dy);       /* incr. used for move to SE */
8215     x = x0;
8216     y = y0;
8217                 if ((x>=drawX)&&(x<drawW)&&(y>=drawY)&&(y<drawH))
8218                         GetShadeTransCol(&psxVuw[(y<<10)+x], colour);
8219     while(y < y1)
8220     {
8221         if (d <= 0)
8222         {
8223             d = d + incrS;              /* Choose S */
8224             y++;
8225         }
8226         else
8227         {
8228             d = d + incrSE;             /* Choose SE */
8229             x++;
8230             y++;
8231         }
8232                                 if ((x>=drawX)&&(x<drawW)&&(y>=drawY)&&(y<drawH))
8233                                         GetShadeTransCol(&psxVuw[(y<<10)+x], colour);
8234     }
8235 }
8236
8237 ///////////////////////////////////////////////////////////////////////
8238
8239 void Line_N_NE_Flat(int x0, int y0, int x1, int y1, unsigned short colour)
8240 {
8241     int dx, dy, incrN, incrNE, d, x, y;
8242
8243     dx = x1 - x0;
8244     dy = -(y1 - y0);
8245     d = 2*dx - dy;              /* Initial value of d */
8246     incrN = 2*dx;               /* incr. used for move to N */
8247     incrNE = 2*(dx - dy);       /* incr. used for move to NE */
8248     x = x0;
8249     y = y0;
8250                 if ((x>=drawX)&&(x<drawW)&&(y>=drawY)&&(y<drawH))
8251                         GetShadeTransCol(&psxVuw[(y<<10)+x], colour);
8252     while(y > y1)
8253     {
8254         if (d <= 0)
8255         {
8256             d = d + incrN;              /* Choose N */
8257             y--;
8258         }
8259         else
8260         {
8261             d = d + incrNE;             /* Choose NE */
8262             x++;
8263             y--;
8264         }
8265                                 if ((x>=drawX)&&(x<drawW)&&(y>=drawY)&&(y<drawH))
8266                                         GetShadeTransCol(&psxVuw[(y<<10)+x], colour);
8267     }
8268 }
8269
8270 ///////////////////////////////////////////////////////////////////////
8271
8272 void Line_E_NE_Flat(int x0, int y0, int x1, int y1, unsigned short colour)
8273 {
8274     int dx, dy, incrE, incrNE, d, x, y;
8275
8276     dx = x1 - x0;
8277     dy = -(y1 - y0);
8278     d = 2*dy - dx;              /* Initial value of d */
8279     incrE = 2*dy;               /* incr. used for move to E */
8280     incrNE = 2*(dy - dx);       /* incr. used for move to NE */
8281     x = x0;
8282     y = y0;
8283                 if ((x>=drawX)&&(x<drawW)&&(y>=drawY)&&(y<drawH))
8284                         GetShadeTransCol(&psxVuw[(y<<10)+x], colour);
8285     while(x < x1)
8286     {
8287         if (d <= 0)
8288         {
8289             d = d + incrE;              /* Choose E */
8290             x++;
8291         }
8292         else
8293         {
8294             d = d + incrNE;             /* Choose NE */
8295             x++;
8296             y--;
8297         }
8298                                 if ((x>=drawX)&&(x<drawW)&&(y>=drawY)&&(y<drawH))
8299                                         GetShadeTransCol(&psxVuw[(y<<10)+x], colour);
8300     }
8301 }
8302
8303 ///////////////////////////////////////////////////////////////////////
8304
8305 void VertLineFlat(int x, int y0, int y1, unsigned short colour)
8306 {
8307         int y;
8308
8309         if (y0 < drawY)
8310                 y0 = drawY;
8311
8312         if (y1 > drawH)
8313                 y1 = drawH;
8314
8315   for (y = y0; y <= y1; y++)
8316                 GetShadeTransCol(&psxVuw[(y<<10)+x], colour);
8317 }
8318
8319 ///////////////////////////////////////////////////////////////////////
8320
8321 void HorzLineFlat(int y, int x0, int x1, unsigned short colour)
8322 {
8323         int x;
8324
8325         if (x0 < drawX)
8326                 x0 = drawX;
8327
8328         if (x1 > drawW)
8329                 x1 = drawW;
8330
8331         for (x = x0; x <= x1; x++)
8332                 GetShadeTransCol(&psxVuw[(y << 10) + x], colour);
8333 }
8334
8335 ///////////////////////////////////////////////////////////////////////
8336
8337 /* Bresenham Line drawing function */
8338 void DrawSoftwareLineShade(int32_t rgb0, int32_t rgb1)
8339 {
8340         short x0, y0, x1, y1, xt, yt;
8341         int32_t rgbt;
8342         double m, dy, dx;
8343
8344         if (lx0 > drawW && lx1 > drawW) return;
8345         if (ly0 > drawH && ly1 > drawH) return;
8346         if (lx0 < drawX && lx1 < drawX) return;
8347         if (ly0 < drawY && ly1 < drawY) return;
8348         if (drawY >= drawH) return;
8349         if (drawX >= drawW) return; 
8350
8351         x0 = lx0;
8352         y0 = ly0;
8353         x1 = lx1;
8354         y1 = ly1;
8355
8356         dx = x1 - x0;
8357         dy = y1 - y0;
8358
8359         if (dx == 0)
8360         {
8361                 if (dy > 0)
8362                         VertLineShade(x0, y0, y1, rgb0, rgb1);
8363                 else
8364                         VertLineShade(x0, y1, y0, rgb1, rgb0);
8365         }
8366         else
8367                 if (dy == 0)
8368                 {
8369                         if (dx > 0)
8370                                 HorzLineShade(y0, x0, x1, rgb0, rgb1);
8371                         else
8372                                 HorzLineShade(y0, x1, x0, rgb1, rgb0);
8373                 }
8374                 else
8375                 {
8376                         if (dx < 0)
8377                         {
8378                                 xt = x0;
8379                                 yt = y0;
8380                                 rgbt = rgb0;
8381                                 x0 = x1;
8382                                 y0 = y1;
8383                                 rgb0 = rgb1;
8384                                 x1 = xt;
8385                                 y1 = yt;
8386                                 rgb1 = rgbt;
8387
8388                                 dx = x1 - x0;
8389                                 dy = y1 - y0;
8390                         }
8391
8392                         m = dy / dx;
8393
8394                         if (m >= 0)
8395                         {
8396                                 if (m > 1)
8397                                         Line_S_SE_Shade(x0, y0, x1, y1, rgb0, rgb1);
8398                                 else
8399                                         Line_E_SE_Shade(x0, y0, x1, y1, rgb0, rgb1);
8400                         }
8401                         else
8402                                 if (m < -1)
8403                                         Line_N_NE_Shade(x0, y0, x1, y1, rgb0, rgb1);
8404                                 else
8405                                         Line_E_NE_Shade(x0, y0, x1, y1, rgb0, rgb1);
8406                 }
8407 }
8408
8409 ///////////////////////////////////////////////////////////////////////
8410
8411 void DrawSoftwareLineFlat(int32_t rgb)
8412 {
8413         short x0, y0, x1, y1, xt, yt;
8414         double m, dy, dx;
8415         unsigned short colour = 0;
8416  
8417         if (lx0 > drawW && lx1 > drawW) return;
8418         if (ly0 > drawH && ly1 > drawH) return;
8419         if (lx0 < drawX && lx1 < drawX) return;
8420         if (ly0 < drawY && ly1 < drawY) return;
8421         if (drawY >= drawH) return;
8422         if (drawX >= drawW) return; 
8423
8424         colour = ((rgb & 0x00f80000) >> 9) | ((rgb & 0x0000f800) >> 6) | ((rgb & 0x000000f8) >> 3);
8425
8426         x0 = lx0;
8427         y0 = ly0;
8428         x1 = lx1;
8429         y1 = ly1;
8430
8431         dx = x1 - x0;
8432         dy = y1 - y0;
8433
8434         if (dx == 0)
8435         {
8436                 if (dy == 0)
8437                         return; // Nothing to draw
8438                 else if (dy > 0)
8439                         VertLineFlat(x0, y0, y1, colour);
8440                 else
8441                         VertLineFlat(x0, y1, y0, colour);
8442         }
8443         else
8444                 if (dy == 0)
8445                 {
8446                         if (dx > 0)
8447                                 HorzLineFlat(y0, x0, x1, colour);
8448                         else
8449                                 HorzLineFlat(y0, x1, x0, colour);
8450                 }
8451                 else
8452                 {
8453                         if (dx < 0)
8454                         {
8455                                 xt = x0;
8456                                 yt = y0;
8457                                 x0 = x1;
8458                                 y0 = y1;
8459                                 x1 = xt;
8460                                 y1 = yt;
8461
8462                                 dx = x1 - x0;
8463                                 dy = y1 - y0;
8464                         }
8465
8466                         m = dy/dx;
8467
8468                         if (m >= 0)
8469                         {
8470                                 if (m > 1)
8471                                         Line_S_SE_Flat(x0, y0, x1, y1, colour);
8472                                 else
8473                                         Line_E_SE_Flat(x0, y0, x1, y1, colour);
8474                         }
8475                         else
8476                                 if (m < -1)
8477                                         Line_N_NE_Flat(x0, y0, x1, y1, colour);
8478                                 else
8479                                         Line_E_NE_Flat(x0, y0, x1, y1, colour);
8480                 }
8481 }
8482
8483 ///////////////////////////////////////////////////////////////////////