gpulib: clear fb when display is blanked
[pcsx_rearmed.git] / plugins / gpu_unai / gpu_raster_polygon.h
1 /***************************************************************************
2 *   Copyright (C) 2010 PCSX4ALL Team                                      *
3 *   Copyright (C) 2010 Unai                                               *
4 *                                                                         *
5 *   This program is free software; you can redistribute it and/or modify  *
6 *   it under the terms of the GNU General Public License as published by  *
7 *   the Free Software Foundation; either version 2 of the License, or     *
8 *   (at your option) any later version.                                   *
9 *                                                                         *
10 *   This program is distributed in the hope that it will be useful,       *
11 *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
12 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
13 *   GNU General Public License for more details.                          *
14 *                                                                         *
15 *   You should have received a copy of the GNU General Public License     *
16 *   along with this program; if not, write to the                         *
17 *   Free Software Foundation, Inc.,                                       *
18 *   51 Franklin Street, Fifth Floor, Boston, MA 02111-1307 USA.           *
19 ***************************************************************************/
20
21 ///////////////////////////////////////////////////////////////////////////////
22 //  GPU internal polygon drawing functions
23
24 ///////////////////////////////////////////////////////////////////////////////
25 void gpuDrawF3(const PP gpuPolySpanDriver)
26 {
27         const int li=linesInterlace;
28         s32 temp;
29         s32 xa, xb, xmin, xmax;
30         s32 ya, yb, ymin, ymax;
31         s32 x0, x1, x2, x3, dx3=0, x4, dx4=0, dx;
32         s32 y0, y1, y2;
33
34         x0 = GPU_EXPANDSIGN_POLY(PacketBuffer.S2[2]);  GPU_TESTRANGE(x0);
35         y0 = GPU_EXPANDSIGN_POLY(PacketBuffer.S2[3]);  GPU_TESTRANGE(y0);
36         x1 = GPU_EXPANDSIGN_POLY(PacketBuffer.S2[4]);  GPU_TESTRANGE(x1);
37         y1 = GPU_EXPANDSIGN_POLY(PacketBuffer.S2[5]);  GPU_TESTRANGE(y1);
38         x2 = GPU_EXPANDSIGN_POLY(PacketBuffer.S2[6]);  GPU_TESTRANGE(x2);
39         y2 = GPU_EXPANDSIGN_POLY(PacketBuffer.S2[7]);  GPU_TESTRANGE(y2);
40
41         x0 += DrawingOffset[0];   x1 += DrawingOffset[0];   x2 += DrawingOffset[0];
42         y0 += DrawingOffset[1];   y1 += DrawingOffset[1];   y2 += DrawingOffset[1];
43
44         xmin = DrawingArea[0];  xmax = DrawingArea[2];
45         ymin = DrawingArea[1];  ymax = DrawingArea[3];
46
47         {
48                 int rx0 = Max2(xmin,Min3(x0,x1,x2));
49                 int ry0 = Max2(ymin,Min3(y0,y1,y2));
50                 int rx1 = Min2(xmax,Max3(x0,x1,x2));
51                 int ry1 = Min2(ymax,Max3(y0,y1,y2));
52                 if( rx0>=rx1 || ry0>=ry1) return;
53         }
54         
55         PixelData = GPU_RGB16(PacketBuffer.U4[0]);
56
57         if (y0 >= y1)
58         {
59                 if( y0!=y1 || x0>x1 )
60                 {
61                         GPU_SWAP(x0, x1, temp);
62                         GPU_SWAP(y0, y1, temp);
63                 }
64         }
65         if (y1 >= y2)
66         {
67                 if( y1!=y2 || x1>x2 )
68                 {
69                         GPU_SWAP(x1, x2, temp);
70                         GPU_SWAP(y1, y2, temp);
71                 }
72         }
73         if (y0 >= y1)
74         {
75                 if( y0!=y1 || x0>x1 )
76                 {
77                         GPU_SWAP(x0, x1, temp);
78                         GPU_SWAP(y0, y1, temp);
79                 }
80         }
81
82         ya = y2 - y0;
83         yb = y2 - y1;
84         dx =(x2 - x1) * ya - (x2 - x0) * yb;
85
86         for (s32 loop0 = 2; loop0; --loop0)
87         {
88                 if (loop0 == 2)
89                 {
90                         ya = y0;
91                         yb = y1;
92                         x3 = i2x(x0);
93                         x4 = y0!=y1 ? x3 : i2x(x1);
94                         if (dx < 0)
95                         {
96                                 dx3 = xLoDivx((x2 - x0), (y2 - y0));
97                                 dx4 = xLoDivx((x1 - x0), (y1 - y0));
98                         }
99                         else
100                         {
101                                 dx3 = xLoDivx((x1 - x0), (y1 - y0));
102                                 dx4 = xLoDivx((x2 - x0), (y2 - y0));
103                         }
104                 }
105                 else
106                 {
107                         ya = y1;
108                         yb = y2;
109                         if (dx < 0)
110                         {
111                                 x4  = i2x(x1);
112                                 x3  = i2x(x0) + (dx3 * (y1 - y0));
113                                 dx4 = xLoDivx((x2 - x1), (y2 - y1));
114                         }
115                         else
116                         {
117                                 x3  = i2x(x1);
118                                 x4  = i2x(x0) + (dx4 * (y1 - y0));
119                                 dx3 = xLoDivx((x2 - x1), (y2 - y1));
120                         }
121                 }
122
123                 temp = ymin - ya;
124                 if (temp > 0)
125                 {
126                         ya  = ymin;
127                         x3 += dx3*temp;
128                         x4 += dx4*temp;
129                 }
130                 if (yb > ymax) yb = ymax;
131                 if (ya>=yb) continue;
132
133                 x3+= fixed_HALF;
134                 x4+= fixed_HALF;
135
136                 u16* PixelBase  = &((u16*)GPU_FrameBuffer)[FRAME_OFFSET(0, ya)];
137                 
138                 for(;ya<yb;++ya, PixelBase += FRAME_WIDTH, x3+=dx3, x4+=dx4)
139                 {
140                         if (ya&li) continue;
141                         xa = x2i(x3);
142                         xb = x2i(x4);
143                         if( (xa>xmax) || (xb<xmin) ) continue;
144                         if(xa < xmin) xa = xmin;
145                         if(xb > xmax) xb = xmax;
146                         xb-=xa;
147                         if(xb>0) gpuPolySpanDriver(PixelBase + xa,xb);
148                 }
149         }
150 }
151
152 /*----------------------------------------------------------------------
153 FT3
154 ----------------------------------------------------------------------*/
155
156 void gpuDrawFT3(const PP gpuPolySpanDriver)
157 {
158         const int li=linesInterlace;
159         s32 temp;
160         s32 xa, xb, xmin, xmax;
161         s32 ya, yb, ymin, ymax;
162         s32 x0, x1, x2, x3, dx3=0, x4, dx4=0, dx;
163         s32 y0, y1, y2;
164         s32 u0, u1, u2, u3, du3=0;
165         s32 v0, v1, v2, v3, dv3=0;
166
167         x0 = GPU_EXPANDSIGN_POLY(PacketBuffer.S2[2] );   GPU_TESTRANGE(x0);
168         y0 = GPU_EXPANDSIGN_POLY(PacketBuffer.S2[3] );   GPU_TESTRANGE(y0);
169         x1 = GPU_EXPANDSIGN_POLY(PacketBuffer.S2[6] );   GPU_TESTRANGE(x1);
170         y1 = GPU_EXPANDSIGN_POLY(PacketBuffer.S2[7] );   GPU_TESTRANGE(y1);
171         x2 = GPU_EXPANDSIGN_POLY(PacketBuffer.S2[10]);   GPU_TESTRANGE(x2);
172         y2 = GPU_EXPANDSIGN_POLY(PacketBuffer.S2[11]);   GPU_TESTRANGE(y2);
173
174         x0 += DrawingOffset[0];   x1 += DrawingOffset[0];   x2 += DrawingOffset[0];
175         y0 += DrawingOffset[1];   y1 += DrawingOffset[1];   y2 += DrawingOffset[1];
176
177         xmin = DrawingArea[0];  xmax = DrawingArea[2];
178         ymin = DrawingArea[1];  ymax = DrawingArea[3];
179
180         {
181                 int rx0 = Max2(xmin,Min3(x0,x1,x2));
182                 int ry0 = Max2(ymin,Min3(y0,y1,y2));
183                 int rx1 = Min2(xmax,Max3(x0,x1,x2));
184                 int ry1 = Min2(ymax,Max3(y0,y1,y2));
185                 if( rx0>=rx1 || ry0>=ry1) return;
186         }
187         
188         u0 = PacketBuffer.U1[8];  v0 = PacketBuffer.U1[9];
189         u1 = PacketBuffer.U1[16]; v1 = PacketBuffer.U1[17];
190         u2 = PacketBuffer.U1[24]; v2 = PacketBuffer.U1[25];
191
192         r4 = s32(PacketBuffer.U1[0]);
193         g4 = s32(PacketBuffer.U1[1]);
194         b4 = s32(PacketBuffer.U1[2]);
195         dr4 = dg4 = db4 = 0;
196
197         if (y0 >= y1)
198         {
199                 if( y0!=y1 || x0>x1 )
200                 {
201                         GPU_SWAP(x0, x1, temp);
202                         GPU_SWAP(y0, y1, temp);
203                         GPU_SWAP(u0, u1, temp);
204                         GPU_SWAP(v0, v1, temp);
205                 }
206         }
207         if (y1 >= y2)
208         {
209                 if( y1!=y2 || x1>x2 )
210                 {
211                         GPU_SWAP(x1, x2, temp);
212                         GPU_SWAP(y1, y2, temp);
213                         GPU_SWAP(u1, u2, temp);
214                         GPU_SWAP(v1, v2, temp);
215                 }
216         }
217         if (y0 >= y1)
218         {
219                 if( y0!=y1 || x0>x1 )
220                 {
221                         GPU_SWAP(x0, x1, temp);
222                         GPU_SWAP(y0, y1, temp);
223                         GPU_SWAP(u0, u1, temp);
224                         GPU_SWAP(v0, v1, temp);
225                 }
226         }
227
228         ya  = y2 - y0;
229         yb  = y2 - y1;
230         dx  = (x2 - x1) * ya - (x2 - x0) * yb;
231         du4 = (u2 - u1) * ya - (u2 - u0) * yb;
232         dv4 = (v2 - v1) * ya - (v2 - v0) * yb;
233
234         s32 iF,iS;
235         xInv( dx, iF, iS);
236         du4 = xInvMulx( du4, iF, iS);
237         dv4 = xInvMulx( dv4, iF, iS);
238         tInc = ((u32)(du4<<7)&0x7fff0000) | ((u32)(dv4>>9)&0x00007fff);
239         tMsk = (TextureWindow[2]<<23) | (TextureWindow[3]<<7) | 0x00ff00ff;
240
241         for (s32 loop0 = 2; loop0; --loop0)
242         {
243                 if (loop0 == 2)
244                 {
245                         ya = y0;
246                         yb = y1;
247                         u3 = i2x(u0);
248                         v3 = i2x(v0);
249                         x3 = i2x(x0);
250                         x4 = y0!=y1 ? x3 : i2x(x1);
251                         if (dx < 0)
252                         {
253                                 xInv( (y2 - y0), iF, iS);
254                                 dx3 = xInvMulx( (x2 - x0), iF, iS);
255                                 du3 = xInvMulx( (u2 - u0), iF, iS);
256                                 dv3 = xInvMulx( (v2 - v0), iF, iS);
257                                 dx4 = xLoDivx ( (x1 - x0), (y1 - y0));
258                         }
259                         else
260                         {
261                                 xInv( (y1 - y0), iF, iS);
262                                 dx3 = xInvMulx( (x1 - x0), iF, iS);
263                                 du3 = xInvMulx( (u1 - u0), iF, iS);
264                                 dv3 = xInvMulx( (v1 - v0), iF, iS);
265                                 dx4 = xLoDivx ( (x2 - x0), (y2 - y0));
266                         }
267                 }
268                 else
269                 {
270                         ya = y1;
271                         yb = y2;
272                         if (dx < 0)
273                         {
274                                 temp = y1 - y0;
275                                 u3 = i2x(u0) + (du3 * temp);
276                                 v3 = i2x(v0) + (dv3 * temp);
277                                 x3 = i2x(x0) + (dx3 * temp);
278                                 x4 = i2x(x1);
279                                 dx4 = xLoDivx((x2 - x1), (y2 - y1));
280                         }
281                         else
282                         {
283                                 u3 = i2x(u1);
284                                 v3 = i2x(v1);
285                                 x3 = i2x(x1);
286                                 x4 = i2x(x0) + (dx4 * (y1 - y0));
287                                 xInv( (y2 - y1), iF, iS);
288                                 dx3 = xInvMulx( (x2 - x1), iF, iS);
289                                 du3 = xInvMulx( (u2 - u1), iF, iS);
290                                 dv3 = xInvMulx( (v2 - v1), iF, iS);
291                         }
292                 }
293
294                 temp = ymin - ya;
295                 if (temp > 0)
296                 {
297                         ya  = ymin;
298                         x3 += dx3*temp;
299                         x4 += dx4*temp;
300                         u3 += du3*temp;
301                         v3 += dv3*temp;
302                 }
303                 if (yb > ymax) yb = ymax;
304                 if (ya>=yb) continue;
305
306                 x3+= fixed_HALF;
307                 x4+= fixed_HALF;
308                 u3+= fixed_HALF;
309                 v4+= fixed_HALF;
310
311                 u16* PixelBase  = &((u16*)GPU_FrameBuffer)[FRAME_OFFSET(0, ya)];
312
313                 for(;ya<yb;++ya, PixelBase += FRAME_WIDTH, x3+=dx3, x4+=dx4, u3+=du3, v3+=dv3)
314                 {
315                         if (ya&li) continue;
316                         xa = x2i(x3);
317                         xb = x2i(x4);
318                         if( (xa>xmax) || (xb<xmin) ) continue;
319
320                         temp = xmin - xa;
321                         if(temp > 0)
322                         {
323                                 xa  = xmin;
324                                 u4 = u3 + du4*temp;
325                                 v4 = v3 + dv4*temp;
326                         }
327                         else
328                         {
329                                 u4 = u3;
330                                 v4 = v3;
331                         }
332                         if(xb > xmax) xb = xmax;
333                         xb-=xa;
334                         if(xb>0) gpuPolySpanDriver(PixelBase + xa,xb);
335                 }
336         }
337 }
338
339 /*----------------------------------------------------------------------
340 G3
341 ----------------------------------------------------------------------*/
342
343 void gpuDrawG3(const PP gpuPolySpanDriver)
344 {
345         const int li=linesInterlace;
346         s32 temp;
347         s32 xa, xb, xmin, xmax;
348         s32 ya, yb, ymin, ymax;
349         s32 x0, x1, x2, x3, dx3=0, x4, dx4=0, dx;
350         s32 y0, y1, y2;
351         s32 r0, r1, r2, r3, dr3=0;
352         s32 g0, g1, g2, g3, dg3=0;
353         s32 b0, b1, b2, b3, db3=0;
354
355         x0 = GPU_EXPANDSIGN_POLY(PacketBuffer.S2[2] );    GPU_TESTRANGE(x0);
356         y0 = GPU_EXPANDSIGN_POLY(PacketBuffer.S2[3] );    GPU_TESTRANGE(y0);
357         x1 = GPU_EXPANDSIGN_POLY(PacketBuffer.S2[6] );    GPU_TESTRANGE(x1);
358         y1 = GPU_EXPANDSIGN_POLY(PacketBuffer.S2[7] );    GPU_TESTRANGE(y1);
359         x2 = GPU_EXPANDSIGN_POLY(PacketBuffer.S2[10]);    GPU_TESTRANGE(x2);
360         y2 = GPU_EXPANDSIGN_POLY(PacketBuffer.S2[11]);    GPU_TESTRANGE(y2);
361
362         x0 += DrawingOffset[0];   x1 += DrawingOffset[0];   x2 += DrawingOffset[0];
363         y0 += DrawingOffset[1];   y1 += DrawingOffset[1];   y2 += DrawingOffset[1];
364
365         xmin = DrawingArea[0];  xmax = DrawingArea[2];
366         ymin = DrawingArea[1];  ymax = DrawingArea[3];
367
368         {
369                 int rx0 = Max2(xmin,Min3(x0,x1,x2));
370                 int ry0 = Max2(ymin,Min3(y0,y1,y2));
371                 int rx1 = Min2(xmax,Max3(x0,x1,x2));
372                 int ry1 = Min2(ymax,Max3(y0,y1,y2));
373                 if( rx0>=rx1 || ry0>=ry1) return;
374         }
375         
376         r0 = PacketBuffer.U1[0];        g0 = PacketBuffer.U1[1];        b0 = PacketBuffer.U1[2];
377         r1 = PacketBuffer.U1[8];        g1 = PacketBuffer.U1[9];        b1 = PacketBuffer.U1[10];
378         r2 = PacketBuffer.U1[16];       g2 = PacketBuffer.U1[17];       b2 = PacketBuffer.U1[18];
379
380         if (y0 >= y1)
381         {
382                 if( y0!=y1 || x0>x1 )
383                 {
384                         GPU_SWAP(x0, x1, temp);         GPU_SWAP(y0, y1, temp);
385                         GPU_SWAP(r0, r1, temp);         GPU_SWAP(g0, g1, temp);         GPU_SWAP(b0, b1, temp);
386                 }
387         }
388         if (y1 >= y2)
389         {
390                 if( y1!=y2 || x1>x2 )
391                 {
392                         GPU_SWAP(x1, x2, temp);         GPU_SWAP(y1, y2, temp);
393                         GPU_SWAP(r1, r2, temp);         GPU_SWAP(g1, g2, temp);   GPU_SWAP(b1, b2, temp);
394                 }
395         }
396         if (y0 >= y1)
397         {
398                 if( y0!=y1 || x0>x1 )
399                 {
400                         GPU_SWAP(x0, x1, temp);         GPU_SWAP(y0, y1, temp);
401                         GPU_SWAP(r0, r1, temp);   GPU_SWAP(g0, g1, temp);               GPU_SWAP(b0, b1, temp);
402                 }
403         }
404
405         ya  = y2 - y0;
406         yb  = y2 - y1;
407         dx  = (x2 - x1) * ya - (x2 - x0) * yb;
408         dr4 = (r2 - r1) * ya - (r2 - r0) * yb;
409         dg4 = (g2 - g1) * ya - (g2 - g0) * yb;
410         db4 = (b2 - b1) * ya - (b2 - b0) * yb;
411
412         s32 iF,iS;
413         xInv(            dx, iF, iS);
414         dr4 = xInvMulx( dr4, iF, iS);
415         dg4 = xInvMulx( dg4, iF, iS);
416         db4 = xInvMulx( db4, iF, iS);
417         u32 dr = (u32)(dr4<< 8)&(0xffffffff<<21);   if(dr4<0) dr+= 1<<21;
418         u32 dg = (u32)(dg4>> 3)&(0xffffffff<<10);   if(dg4<0) dg+= 1<<10;
419         u32 db = (u32)(db4>>14)&(0xffffffff    );   if(db4<0) db+= 1<< 0;
420         lInc = db + dg + dr;
421
422         for (s32 loop0 = 2; loop0; --loop0)
423         {
424                 if (loop0 == 2)
425                 {
426                         ya = y0;
427                         yb = y1;
428                         r3 = i2x(r0);
429                         g3 = i2x(g0);
430                         b3 = i2x(b0);
431                         x3 = i2x(x0);
432                         x4 = y0!=y1 ? x3 : i2x(x1);
433                         if (dx < 0)
434                         {
435                                 xInv(           (y2 - y0), iF, iS);
436                                 dx3 = xInvMulx( (x2 - x0), iF, iS);
437                                 dr3 = xInvMulx( (r2 - r0), iF, iS);
438                                 dg3 = xInvMulx( (g2 - g0), iF, iS);
439                                 db3 = xInvMulx( (b2 - b0), iF, iS);
440                                 dx4 = xLoDivx ( (x1 - x0), (y1 - y0));
441                         }
442                         else
443                         {
444                                 xInv(           (y1 - y0), iF, iS);
445                                 dx3 = xInvMulx( (x1 - x0), iF, iS);
446                                 dr3 = xInvMulx( (r1 - r0), iF, iS);
447                                 dg3 = xInvMulx( (g1 - g0), iF, iS);
448                                 db3 = xInvMulx( (b1 - b0), iF, iS);
449                                 dx4 = xLoDivx ( (x2 - x0), (y2 - y0));
450                         }
451                 }
452                 else
453                 {
454                         ya = y1;
455                         yb = y2;
456                         if (dx < 0)
457                         {
458                                 temp = y1 - y0;
459                                 r3  = i2x(r0) + (dr3 * temp);
460                                 g3  = i2x(g0) + (dg3 * temp);
461                                 b3  = i2x(b0) + (db3 * temp);
462                                 x3  = i2x(x0) + (dx3 * temp);
463                                 x4  = i2x(x1);
464                                 dx4 = xLoDivx((x2 - x1), (y2 - y1));
465                         }
466                         else
467                         {
468                                 r3 = i2x(r1);
469                                 g3 = i2x(g1);
470                                 b3 = i2x(b1);
471                                 x3 = i2x(x1);
472                                 x4 = i2x(x0) + (dx4 * (y1 - y0));
473
474                                 xInv(           (y2 - y1), iF, iS);
475                                 dx3 = xInvMulx( (x2 - x1), iF, iS);
476                                 dr3 = xInvMulx( (r2 - r1), iF, iS);
477                                 dg3 = xInvMulx( (g2 - g1), iF, iS);
478                                 db3 = xInvMulx( (b2 - b1), iF, iS);
479                         }
480                 }
481
482                 temp = ymin - ya;
483                 if (temp > 0)
484                 {
485                         ya  = ymin;
486                         x3 += dx3*temp;   x4 += dx4*temp;
487                         r3 += dr3*temp;   g3 += dg3*temp;   b3 += db3*temp;
488                 }
489                 if (yb > ymax) yb = ymax;
490                 if (ya>=yb) continue;
491
492                 x3+= fixed_HALF;  x4+= fixed_HALF;
493                 r3+= fixed_HALF;  g3+= fixed_HALF;  b3+= fixed_HALF;
494
495                 u16* PixelBase  = &((u16*)GPU_FrameBuffer)[FRAME_OFFSET(0, ya)];
496                 
497                 for(;ya<yb;++ya, PixelBase += FRAME_WIDTH, x3+=dx3, x4+=dx4, r3+=dr3, g3+=dg3, b3+=db3)
498                 {
499                         if (ya&li) continue;
500                         xa = x2i(x3);
501                         xb = x2i(x4);
502                         if( (xa>xmax) || (xb<xmin) ) continue;
503
504                         temp = xmin - xa;
505                         if(temp > 0)
506                         {
507                                 xa  = xmin;
508                                 r4 = r3 + dr4*temp;   g4 = g3 + dg4*temp;   b4 = b3 + db4*temp;
509                         }
510                         else
511                         {
512                                 r4 = r3;  g4 = g3;  b4 = b3;
513                         }
514                         if(xb > xmax) xb = xmax;
515                         xb-=xa;
516                         if(xb>0) gpuPolySpanDriver(PixelBase + xa,xb);
517                 }
518         }
519 }
520
521 /*----------------------------------------------------------------------
522 GT3
523 ----------------------------------------------------------------------*/
524
525 void gpuDrawGT3(const PP gpuPolySpanDriver)
526 {
527         const int li=linesInterlace;
528         s32 temp;
529         s32 xa, xb, xmin, xmax;
530         s32 ya, yb, ymin, ymax;
531         s32 x0, x1, x2, x3, dx3=0, x4, dx4=0, dx;
532         s32 y0, y1, y2;
533         s32 u0, u1, u2, u3, du3=0;
534         s32 v0, v1, v2, v3, dv3=0;
535         s32 r0, r1, r2, r3, dr3=0;
536         s32 g0, g1, g2, g3, dg3=0;
537         s32 b0, b1, b2, b3, db3=0;
538
539         x0 = GPU_EXPANDSIGN_POLY(PacketBuffer.S2[2] );   GPU_TESTRANGE(x0);
540         y0 = GPU_EXPANDSIGN_POLY(PacketBuffer.S2[3] );   GPU_TESTRANGE(y0);
541         x1 = GPU_EXPANDSIGN_POLY(PacketBuffer.S2[8] );   GPU_TESTRANGE(x1);
542         y1 = GPU_EXPANDSIGN_POLY(PacketBuffer.S2[9] );   GPU_TESTRANGE(y1);
543         x2 = GPU_EXPANDSIGN_POLY(PacketBuffer.S2[14]);   GPU_TESTRANGE(x2);
544         y2 = GPU_EXPANDSIGN_POLY(PacketBuffer.S2[15]);   GPU_TESTRANGE(y2);
545
546         x0 += DrawingOffset[0];   x1 += DrawingOffset[0];   x2 += DrawingOffset[0];
547         y0 += DrawingOffset[1];   y1 += DrawingOffset[1];   y2 += DrawingOffset[1];
548
549         xmin = DrawingArea[0];  xmax = DrawingArea[2];
550         ymin = DrawingArea[1];  ymax = DrawingArea[3];
551
552         {
553                 int rx0 = Max2(xmin,Min3(x0,x1,x2));
554                 int ry0 = Max2(ymin,Min3(y0,y1,y2));
555                 int rx1 = Min2(xmax,Max3(x0,x1,x2));
556                 int ry1 = Min2(ymax,Max3(y0,y1,y2));
557                 if( rx0>=rx1 || ry0>=ry1) return;
558         }
559
560         r0 = PacketBuffer.U1[0];        g0 = PacketBuffer.U1[1];        b0 = PacketBuffer.U1[2];
561         u0 = PacketBuffer.U1[8];        v0 = PacketBuffer.U1[9];
562         r1 = PacketBuffer.U1[12];       g1 = PacketBuffer.U1[13];       b1 = PacketBuffer.U1[14];
563         u1 = PacketBuffer.U1[20];       v1 = PacketBuffer.U1[21];
564         r2 = PacketBuffer.U1[24];       g2 = PacketBuffer.U1[25];       b2 = PacketBuffer.U1[26];
565         u2 = PacketBuffer.U1[32];       v2 = PacketBuffer.U1[33];
566
567         if (y0 >= y1)
568         {
569                 if( y0!=y1 || x0>x1 )
570                 {
571                         GPU_SWAP(x0, x1, temp);         GPU_SWAP(y0, y1, temp);
572                         GPU_SWAP(u0, u1, temp);         GPU_SWAP(v0, v1, temp);
573                         GPU_SWAP(r0, r1, temp);         GPU_SWAP(g0, g1, temp);   GPU_SWAP(b0, b1, temp);
574                 }
575         }
576         if (y1 >= y2)
577         {
578                 if( y1!=y2 || x1>x2 )
579                 {
580                         GPU_SWAP(x1, x2, temp);         GPU_SWAP(y1, y2, temp);
581                         GPU_SWAP(u1, u2, temp);         GPU_SWAP(v1, v2, temp);
582                         GPU_SWAP(r1, r2, temp);   GPU_SWAP(g1, g2, temp);               GPU_SWAP(b1, b2, temp);
583                 }
584         }
585         if (y0 >= y1)
586         {
587                 if( y0!=y1 || x0>x1 )
588                 {
589                         GPU_SWAP(x0, x1, temp);         GPU_SWAP(y0, y1, temp);
590                         GPU_SWAP(u0, u1, temp);         GPU_SWAP(v0, v1, temp);
591                         GPU_SWAP(r0, r1, temp);         GPU_SWAP(g0, g1, temp);         GPU_SWAP(b0, b1, temp);
592                 }
593         }
594
595         ya  = y2 - y0;
596         yb  = y2 - y1;
597         dx  = (x2 - x1) * ya - (x2 - x0) * yb;
598         du4 = (u2 - u1) * ya - (u2 - u0) * yb;
599         dv4 = (v2 - v1) * ya - (v2 - v0) * yb;
600         dr4 = (r2 - r1) * ya - (r2 - r0) * yb;
601         dg4 = (g2 - g1) * ya - (g2 - g0) * yb;
602         db4 = (b2 - b1) * ya - (b2 - b0) * yb;
603
604         s32 iF,iS;
605
606         xInv(            dx, iF, iS);
607         du4 = xInvMulx( du4, iF, iS);
608         dv4 = xInvMulx( dv4, iF, iS);
609         dr4 = xInvMulx( dr4, iF, iS);
610         dg4 = xInvMulx( dg4, iF, iS);
611         db4 = xInvMulx( db4, iF, iS);
612         u32 dr = (u32)(dr4<< 8)&(0xffffffff<<21);   if(dr4<0) dr+= 1<<21;
613         u32 dg = (u32)(dg4>> 3)&(0xffffffff<<10);   if(dg4<0) dg+= 1<<10;
614         u32 db = (u32)(db4>>14)&(0xffffffff    );   if(db4<0) db+= 1<< 0;
615         lInc = db + dg + dr;
616         tInc = ((u32)(du4<<7)&0x7fff0000) | ((u32)(dv4>>9)&0x00007fff);
617         tMsk = (TextureWindow[2]<<23) | (TextureWindow[3]<<7) | 0x00ff00ff;
618
619         for (s32 loop0 = 2; loop0; --loop0)
620         {
621                 if (loop0 == 2)
622                 {
623                         ya = y0;
624                         yb = y1;
625                         u3 = i2x(u0);
626                         v3 = i2x(v0);
627                         r3 = i2x(r0);
628                         g3 = i2x(g0);
629                         b3 = i2x(b0);
630                         x3 = i2x(x0);
631                         x4 = y0!=y1 ? x3 : i2x(x1);
632                         if (dx < 0)
633                         {
634                                 xInv(           (y2 - y0), iF, iS);
635                                 dx3 = xInvMulx( (x2 - x0), iF, iS);
636                                 du3 = xInvMulx( (u2 - u0), iF, iS);
637                                 dv3 = xInvMulx( (v2 - v0), iF, iS);
638                                 dr3 = xInvMulx( (r2 - r0), iF, iS);
639                                 dg3 = xInvMulx( (g2 - g0), iF, iS);
640                                 db3 = xInvMulx( (b2 - b0), iF, iS);
641                                 dx4 = xLoDivx ( (x1 - x0), (y1 - y0));
642                         }
643                         else
644                         {
645                                 xInv(           (y1 - y0), iF, iS);
646                                 dx3 = xInvMulx( (x1 - x0), iF, iS);
647                                 du3 = xInvMulx( (u1 - u0), iF, iS);
648                                 dv3 = xInvMulx( (v1 - v0), iF, iS);
649                                 dr3 = xInvMulx( (r1 - r0), iF, iS);
650                                 dg3 = xInvMulx( (g1 - g0), iF, iS);
651                                 db3 = xInvMulx( (b1 - b0), iF, iS);
652                                 dx4 = xLoDivx ( (x2 - x0), (y2 - y0));
653                         }
654                 }
655                 else
656                 {
657                         ya = y1;
658                         yb = y2;
659                         if (dx < 0)
660                         {
661                                 temp = y1 - y0;
662                                 u3  = i2x(u0) + (du3 * temp);
663                                 v3  = i2x(v0) + (dv3 * temp);
664                                 r3  = i2x(r0) + (dr3 * temp);
665                                 g3  = i2x(g0) + (dg3 * temp);
666                                 b3  = i2x(b0) + (db3 * temp);
667                                 x3  = i2x(x0) + (dx3 * temp);
668                                 x4  = i2x(x1);
669                                 dx4 = xLoDivx((x2 - x1), (y2 - y1));
670                         }
671                         else
672                         {
673                                 u3 = i2x(u1);
674                                 v3 = i2x(v1);
675                                 r3 = i2x(r1);
676                                 g3 = i2x(g1);
677                                 b3 = i2x(b1);
678                                 x3 = i2x(x1);
679                                 x4 = i2x(x0) + (dx4 * (y1 - y0));
680
681                                 xInv(           (y2 - y1), iF, iS);
682                                 dx3 = xInvMulx( (x2 - x1), iF, iS);
683                                 du3 = xInvMulx( (u2 - u1), iF, iS);
684                                 dv3 = xInvMulx( (v2 - v1), iF, iS);
685                                 dr3 = xInvMulx( (r2 - r1), iF, iS);
686                                 dg3 = xInvMulx( (g2 - g1), iF, iS);
687                                 db3 = xInvMulx( (b2 - b1), iF, iS);
688                         }
689                 }
690
691                 temp = ymin - ya;
692                 if (temp > 0)
693                 {
694                         ya  = ymin;
695                         x3 += dx3*temp;   x4 += dx4*temp;
696                         u3 += du3*temp;   v3 += dv3*temp;
697                         r3 += dr3*temp;   g3 += dg3*temp;   b3 += db3*temp;
698                 }
699                 if (yb > ymax) yb = ymax;
700                 if (ya>=yb) continue;
701
702                 x3+= fixed_HALF;  x4+= fixed_HALF;
703                 u3+= fixed_HALF;  v4+= fixed_HALF;
704                 r3+= fixed_HALF;  g3+= fixed_HALF;  b3+= fixed_HALF;
705                 u16* PixelBase  = &((u16*)GPU_FrameBuffer)[FRAME_OFFSET(0, ya)];
706                 
707                 for(;ya<yb;++ya, PixelBase += FRAME_WIDTH, x3+=dx3, x4+=dx4, u3+=du3, v3+=dv3, r3+=dr3, g3+=dg3,        b3+=db3)
708                 {
709                         if (ya&li) continue;
710                         xa = x2i(x3);
711                         xb = x2i(x4);
712                         if( (xa>xmax) || (xb<xmin))     continue;
713
714                         temp = xmin - xa;
715                         if(temp > 0)
716                         {
717                                 xa  = xmin;
718                                 u4 = u3 + du4*temp;   v4 = v3 + dv4*temp;
719                                 r4 = r3 + dr4*temp;   g4 = g3 + dg4*temp;   b4 = b3 + db4*temp;
720                         }
721                         else
722                         {
723                                 u4 = u3;  v4 = v3;
724                                 r4 = r3;  g4 = g3;  b4 = b3;
725                         }
726                         if(xb > xmax) xb = xmax;
727                         xb-=xa;
728                         if(xb>0) gpuPolySpanDriver(PixelBase + xa,xb);
729                 }
730         }
731 }