allow some build customization
[pcsx_rearmed.git] / plugins / gpu_unai / gpu_raster_polygon.h
CommitLineData
86aad47b 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///////////////////////////////////////////////////////////////////////////////
25void 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 if (!progressInterlace)
139 {
140 for(;ya<yb;++ya, PixelBase += FRAME_WIDTH, x3+=dx3, x4+=dx4)
141 {
142 if (ya&li) continue;
143 xa = x2i(x3);
144 xb = x2i(x4);
145 if( (xa>xmax) || (xb<xmin) ) continue;
146 if(xa < xmin) xa = xmin;
147 if(xb > xmax) xb = xmax;
148 xb-=xa;
149 if(xb>0) gpuPolySpanDriver(PixelBase + xa,xb);
150 }
151 }
152 else
153 {
154 bool flag=progressInterlace_flag;
155 for(;ya<yb;++ya, PixelBase += FRAME_WIDTH, x3+=dx3, x4+=dx4)
156 {
157 if ((ya&li) && (flag=!flag)) continue;
158 xa = x2i(x3);
159 xb = x2i(x4);
160 if( (xa>xmax) || (xb<xmin) ) continue;
161 if(xa < xmin) xa = xmin;
162 if(xb > xmax) xb = xmax;
163 xb-=xa;
164 if(xb>0) gpuPolySpanDriver(PixelBase + xa,xb);
165 }
166 }
167 }
168}
169
170/*----------------------------------------------------------------------
171FT3
172----------------------------------------------------------------------*/
173
174void gpuDrawFT3(const PP gpuPolySpanDriver)
175{
176 const int li=linesInterlace;
177 s32 temp;
178 s32 xa, xb, xmin, xmax;
179 s32 ya, yb, ymin, ymax;
180 s32 x0, x1, x2, x3, dx3=0, x4, dx4=0, dx;
181 s32 y0, y1, y2;
182 s32 u0, u1, u2, u3, du3=0;
183 s32 v0, v1, v2, v3, dv3=0;
184
185 x0 = GPU_EXPANDSIGN_POLY(PacketBuffer.S2[2] ); GPU_TESTRANGE(x0);
186 y0 = GPU_EXPANDSIGN_POLY(PacketBuffer.S2[3] ); GPU_TESTRANGE(y0);
187 x1 = GPU_EXPANDSIGN_POLY(PacketBuffer.S2[6] ); GPU_TESTRANGE(x1);
188 y1 = GPU_EXPANDSIGN_POLY(PacketBuffer.S2[7] ); GPU_TESTRANGE(y1);
189 x2 = GPU_EXPANDSIGN_POLY(PacketBuffer.S2[10]); GPU_TESTRANGE(x2);
190 y2 = GPU_EXPANDSIGN_POLY(PacketBuffer.S2[11]); GPU_TESTRANGE(y2);
191
192 x0 += DrawingOffset[0]; x1 += DrawingOffset[0]; x2 += DrawingOffset[0];
193 y0 += DrawingOffset[1]; y1 += DrawingOffset[1]; y2 += DrawingOffset[1];
194
195 xmin = DrawingArea[0]; xmax = DrawingArea[2];
196 ymin = DrawingArea[1]; ymax = DrawingArea[3];
197
198 {
199 int rx0 = Max2(xmin,Min3(x0,x1,x2));
200 int ry0 = Max2(ymin,Min3(y0,y1,y2));
201 int rx1 = Min2(xmax,Max3(x0,x1,x2));
202 int ry1 = Min2(ymax,Max3(y0,y1,y2));
203 if( rx0>=rx1 || ry0>=ry1) return;
204 }
205
206 u0 = PacketBuffer.U1[8]; v0 = PacketBuffer.U1[9];
207 u1 = PacketBuffer.U1[16]; v1 = PacketBuffer.U1[17];
208 u2 = PacketBuffer.U1[24]; v2 = PacketBuffer.U1[25];
209
210 r4 = s32(PacketBuffer.U1[0]);
211 g4 = s32(PacketBuffer.U1[1]);
212 b4 = s32(PacketBuffer.U1[2]);
213 dr4 = dg4 = db4 = 0;
214
215 if (y0 >= y1)
216 {
217 if( y0!=y1 || x0>x1 )
218 {
219 GPU_SWAP(x0, x1, temp);
220 GPU_SWAP(y0, y1, temp);
221 GPU_SWAP(u0, u1, temp);
222 GPU_SWAP(v0, v1, temp);
223 }
224 }
225 if (y1 >= y2)
226 {
227 if( y1!=y2 || x1>x2 )
228 {
229 GPU_SWAP(x1, x2, temp);
230 GPU_SWAP(y1, y2, temp);
231 GPU_SWAP(u1, u2, temp);
232 GPU_SWAP(v1, v2, temp);
233 }
234 }
235 if (y0 >= y1)
236 {
237 if( y0!=y1 || x0>x1 )
238 {
239 GPU_SWAP(x0, x1, temp);
240 GPU_SWAP(y0, y1, temp);
241 GPU_SWAP(u0, u1, temp);
242 GPU_SWAP(v0, v1, temp);
243 }
244 }
245
246 ya = y2 - y0;
247 yb = y2 - y1;
248 dx = (x2 - x1) * ya - (x2 - x0) * yb;
249 du4 = (u2 - u1) * ya - (u2 - u0) * yb;
250 dv4 = (v2 - v1) * ya - (v2 - v0) * yb;
251
252 s32 iF,iS;
253 xInv( dx, iF, iS);
254 du4 = xInvMulx( du4, iF, iS);
255 dv4 = xInvMulx( dv4, iF, iS);
256 tInc = ((u32)(du4<<7)&0x7fff0000) | ((u32)(dv4>>9)&0x00007fff);
257 tMsk = (TextureWindow[2]<<23) | (TextureWindow[3]<<7) | 0x00ff00ff;
258
259 for (s32 loop0 = 2; loop0; --loop0)
260 {
261 if (loop0 == 2)
262 {
263 ya = y0;
264 yb = y1;
265 u3 = i2x(u0);
266 v3 = i2x(v0);
267 x3 = i2x(x0);
268 x4 = y0!=y1 ? x3 : i2x(x1);
269 if (dx < 0)
270 {
271 xInv( (y2 - y0), iF, iS);
272 dx3 = xInvMulx( (x2 - x0), iF, iS);
273 du3 = xInvMulx( (u2 - u0), iF, iS);
274 dv3 = xInvMulx( (v2 - v0), iF, iS);
275 dx4 = xLoDivx ( (x1 - x0), (y1 - y0));
276 }
277 else
278 {
279 xInv( (y1 - y0), iF, iS);
280 dx3 = xInvMulx( (x1 - x0), iF, iS);
281 du3 = xInvMulx( (u1 - u0), iF, iS);
282 dv3 = xInvMulx( (v1 - v0), iF, iS);
283 dx4 = xLoDivx ( (x2 - x0), (y2 - y0));
284 }
285 }
286 else
287 {
288 ya = y1;
289 yb = y2;
290 if (dx < 0)
291 {
292 temp = y1 - y0;
293 u3 = i2x(u0) + (du3 * temp);
294 v3 = i2x(v0) + (dv3 * temp);
295 x3 = i2x(x0) + (dx3 * temp);
296 x4 = i2x(x1);
297 dx4 = xLoDivx((x2 - x1), (y2 - y1));
298 }
299 else
300 {
301 u3 = i2x(u1);
302 v3 = i2x(v1);
303 x3 = i2x(x1);
304 x4 = i2x(x0) + (dx4 * (y1 - y0));
305 xInv( (y2 - y1), iF, iS);
306 dx3 = xInvMulx( (x2 - x1), iF, iS);
307 du3 = xInvMulx( (u2 - u1), iF, iS);
308 dv3 = xInvMulx( (v2 - v1), iF, iS);
309 }
310 }
311
312 temp = ymin - ya;
313 if (temp > 0)
314 {
315 ya = ymin;
316 x3 += dx3*temp;
317 x4 += dx4*temp;
318 u3 += du3*temp;
319 v3 += dv3*temp;
320 }
321 if (yb > ymax) yb = ymax;
322 if (ya>=yb) continue;
323
324 x3+= fixed_HALF;
325 x4+= fixed_HALF;
326 u3+= fixed_HALF;
327 v4+= fixed_HALF;
328
329 u16* PixelBase = &((u16*)GPU_FrameBuffer)[FRAME_OFFSET(0, ya)];
330
331 if (!progressInterlace)
332 {
333 for(;ya<yb;++ya, PixelBase += FRAME_WIDTH, x3+=dx3, x4+=dx4, u3+=du3, v3+=dv3)
334 {
335 if (ya&li) continue;
336 xa = x2i(x3);
337 xb = x2i(x4);
338 if( (xa>xmax) || (xb<xmin) ) continue;
339
340 temp = xmin - xa;
341 if(temp > 0)
342 {
343 xa = xmin;
344 u4 = u3 + du4*temp;
345 v4 = v3 + dv4*temp;
346 }
347 else
348 {
349 u4 = u3;
350 v4 = v3;
351 }
352 if(xb > xmax) xb = xmax;
353 xb-=xa;
354 if(xb>0) gpuPolySpanDriver(PixelBase + xa,xb);
355 }
356 }
357 else
358 {
359 bool flag=progressInterlace_flag;
360 for(;ya<yb;++ya, PixelBase += FRAME_WIDTH, x3+=dx3, x4+=dx4, u3+=du3, v3+=dv3)
361 {
362 if ((ya&li) && (flag=!flag)) continue;
363 xa = x2i(x3);
364 xb = x2i(x4);
365 if( (xa>xmax) || (xb<xmin) ) continue;
366
367 temp = xmin - xa;
368 if(temp > 0)
369 {
370 xa = xmin;
371 u4 = u3 + du4*temp;
372 v4 = v3 + dv4*temp;
373 }
374 else
375 {
376 u4 = u3;
377 v4 = v3;
378 }
379 if(xb > xmax) xb = xmax;
380 xb-=xa;
381 if(xb>0) gpuPolySpanDriver(PixelBase + xa,xb);
382 }
383 }
384 }
385}
386
387/*----------------------------------------------------------------------
388G3
389----------------------------------------------------------------------*/
390
391void gpuDrawG3(const PP gpuPolySpanDriver)
392{
393 const int li=linesInterlace;
394 s32 temp;
395 s32 xa, xb, xmin, xmax;
396 s32 ya, yb, ymin, ymax;
397 s32 x0, x1, x2, x3, dx3=0, x4, dx4=0, dx;
398 s32 y0, y1, y2;
399 s32 r0, r1, r2, r3, dr3=0;
400 s32 g0, g1, g2, g3, dg3=0;
401 s32 b0, b1, b2, b3, db3=0;
402
403 x0 = GPU_EXPANDSIGN_POLY(PacketBuffer.S2[2] ); GPU_TESTRANGE(x0);
404 y0 = GPU_EXPANDSIGN_POLY(PacketBuffer.S2[3] ); GPU_TESTRANGE(y0);
405 x1 = GPU_EXPANDSIGN_POLY(PacketBuffer.S2[6] ); GPU_TESTRANGE(x1);
406 y1 = GPU_EXPANDSIGN_POLY(PacketBuffer.S2[7] ); GPU_TESTRANGE(y1);
407 x2 = GPU_EXPANDSIGN_POLY(PacketBuffer.S2[10]); GPU_TESTRANGE(x2);
408 y2 = GPU_EXPANDSIGN_POLY(PacketBuffer.S2[11]); GPU_TESTRANGE(y2);
409
410 x0 += DrawingOffset[0]; x1 += DrawingOffset[0]; x2 += DrawingOffset[0];
411 y0 += DrawingOffset[1]; y1 += DrawingOffset[1]; y2 += DrawingOffset[1];
412
413 xmin = DrawingArea[0]; xmax = DrawingArea[2];
414 ymin = DrawingArea[1]; ymax = DrawingArea[3];
415
416 {
417 int rx0 = Max2(xmin,Min3(x0,x1,x2));
418 int ry0 = Max2(ymin,Min3(y0,y1,y2));
419 int rx1 = Min2(xmax,Max3(x0,x1,x2));
420 int ry1 = Min2(ymax,Max3(y0,y1,y2));
421 if( rx0>=rx1 || ry0>=ry1) return;
422 }
423
424 r0 = PacketBuffer.U1[0]; g0 = PacketBuffer.U1[1]; b0 = PacketBuffer.U1[2];
425 r1 = PacketBuffer.U1[8]; g1 = PacketBuffer.U1[9]; b1 = PacketBuffer.U1[10];
426 r2 = PacketBuffer.U1[16]; g2 = PacketBuffer.U1[17]; b2 = PacketBuffer.U1[18];
427
428 if (y0 >= y1)
429 {
430 if( y0!=y1 || x0>x1 )
431 {
432 GPU_SWAP(x0, x1, temp); GPU_SWAP(y0, y1, temp);
433 GPU_SWAP(r0, r1, temp); GPU_SWAP(g0, g1, temp); GPU_SWAP(b0, b1, temp);
434 }
435 }
436 if (y1 >= y2)
437 {
438 if( y1!=y2 || x1>x2 )
439 {
440 GPU_SWAP(x1, x2, temp); GPU_SWAP(y1, y2, temp);
441 GPU_SWAP(r1, r2, temp); GPU_SWAP(g1, g2, temp); GPU_SWAP(b1, b2, temp);
442 }
443 }
444 if (y0 >= y1)
445 {
446 if( y0!=y1 || x0>x1 )
447 {
448 GPU_SWAP(x0, x1, temp); GPU_SWAP(y0, y1, temp);
449 GPU_SWAP(r0, r1, temp); GPU_SWAP(g0, g1, temp); GPU_SWAP(b0, b1, temp);
450 }
451 }
452
453 ya = y2 - y0;
454 yb = y2 - y1;
455 dx = (x2 - x1) * ya - (x2 - x0) * yb;
456 dr4 = (r2 - r1) * ya - (r2 - r0) * yb;
457 dg4 = (g2 - g1) * ya - (g2 - g0) * yb;
458 db4 = (b2 - b1) * ya - (b2 - b0) * yb;
459
460 s32 iF,iS;
461 xInv( dx, iF, iS);
462 dr4 = xInvMulx( dr4, iF, iS);
463 dg4 = xInvMulx( dg4, iF, iS);
464 db4 = xInvMulx( db4, iF, iS);
465 u32 dr = (u32)(dr4<< 8)&(0xffffffff<<21); if(dr4<0) dr+= 1<<21;
466 u32 dg = (u32)(dg4>> 3)&(0xffffffff<<10); if(dg4<0) dg+= 1<<10;
467 u32 db = (u32)(db4>>14)&(0xffffffff ); if(db4<0) db+= 1<< 0;
468 lInc = db + dg + dr;
469
470 for (s32 loop0 = 2; loop0; --loop0)
471 {
472 if (loop0 == 2)
473 {
474 ya = y0;
475 yb = y1;
476 r3 = i2x(r0);
477 g3 = i2x(g0);
478 b3 = i2x(b0);
479 x3 = i2x(x0);
480 x4 = y0!=y1 ? x3 : i2x(x1);
481 if (dx < 0)
482 {
483 xInv( (y2 - y0), iF, iS);
484 dx3 = xInvMulx( (x2 - x0), iF, iS);
485 dr3 = xInvMulx( (r2 - r0), iF, iS);
486 dg3 = xInvMulx( (g2 - g0), iF, iS);
487 db3 = xInvMulx( (b2 - b0), iF, iS);
488 dx4 = xLoDivx ( (x1 - x0), (y1 - y0));
489 }
490 else
491 {
492 xInv( (y1 - y0), iF, iS);
493 dx3 = xInvMulx( (x1 - x0), iF, iS);
494 dr3 = xInvMulx( (r1 - r0), iF, iS);
495 dg3 = xInvMulx( (g1 - g0), iF, iS);
496 db3 = xInvMulx( (b1 - b0), iF, iS);
497 dx4 = xLoDivx ( (x2 - x0), (y2 - y0));
498 }
499 }
500 else
501 {
502 ya = y1;
503 yb = y2;
504 if (dx < 0)
505 {
506 temp = y1 - y0;
507 r3 = i2x(r0) + (dr3 * temp);
508 g3 = i2x(g0) + (dg3 * temp);
509 b3 = i2x(b0) + (db3 * temp);
510 x3 = i2x(x0) + (dx3 * temp);
511 x4 = i2x(x1);
512 dx4 = xLoDivx((x2 - x1), (y2 - y1));
513 }
514 else
515 {
516 r3 = i2x(r1);
517 g3 = i2x(g1);
518 b3 = i2x(b1);
519 x3 = i2x(x1);
520 x4 = i2x(x0) + (dx4 * (y1 - y0));
521
522 xInv( (y2 - y1), iF, iS);
523 dx3 = xInvMulx( (x2 - x1), iF, iS);
524 dr3 = xInvMulx( (r2 - r1), iF, iS);
525 dg3 = xInvMulx( (g2 - g1), iF, iS);
526 db3 = xInvMulx( (b2 - b1), iF, iS);
527 }
528 }
529
530 temp = ymin - ya;
531 if (temp > 0)
532 {
533 ya = ymin;
534 x3 += dx3*temp; x4 += dx4*temp;
535 r3 += dr3*temp; g3 += dg3*temp; b3 += db3*temp;
536 }
537 if (yb > ymax) yb = ymax;
538 if (ya>=yb) continue;
539
540 x3+= fixed_HALF; x4+= fixed_HALF;
541 r3+= fixed_HALF; g3+= fixed_HALF; b3+= fixed_HALF;
542
543 u16* PixelBase = &((u16*)GPU_FrameBuffer)[FRAME_OFFSET(0, ya)];
544
545 if (!progressInterlace)
546 {
547 for(;ya<yb;++ya, PixelBase += FRAME_WIDTH, x3+=dx3, x4+=dx4, r3+=dr3, g3+=dg3, b3+=db3)
548 {
549 if (ya&li) continue;
550 xa = x2i(x3);
551 xb = x2i(x4);
552 if( (xa>xmax) || (xb<xmin) ) continue;
553
554 temp = xmin - xa;
555 if(temp > 0)
556 {
557 xa = xmin;
558 r4 = r3 + dr4*temp; g4 = g3 + dg4*temp; b4 = b3 + db4*temp;
559 }
560 else
561 {
562 r4 = r3; g4 = g3; b4 = b3;
563 }
564 if(xb > xmax) xb = xmax;
565 xb-=xa;
566 if(xb>0) gpuPolySpanDriver(PixelBase + xa,xb);
567 }
568 }
569 else
570 {
571 bool flag=progressInterlace_flag;
572 for(;ya<yb;++ya, PixelBase += FRAME_WIDTH, x3+=dx3, x4+=dx4, r3+=dr3, g3+=dg3, b3+=db3)
573 {
574 if ((ya&li) && (flag=!flag)) continue;
575 xa = x2i(x3);
576 xb = x2i(x4);
577 if( (xa>xmax) || (xb<xmin) ) continue;
578
579 temp = xmin - xa;
580 if(temp > 0)
581 {
582 xa = xmin;
583 r4 = r3 + dr4*temp; g4 = g3 + dg4*temp; b4 = b3 + db4*temp;
584 }
585 else
586 {
587 r4 = r3; g4 = g3; b4 = b3;
588 }
589 if(xb > xmax) xb = xmax;
590 xb-=xa;
591 if(xb>0) gpuPolySpanDriver(PixelBase + xa,xb);
592 }
593 }
594 }
595}
596
597/*----------------------------------------------------------------------
598GT3
599----------------------------------------------------------------------*/
600
601void gpuDrawGT3(const PP gpuPolySpanDriver)
602{
603 const int li=linesInterlace;
604 s32 temp;
605 s32 xa, xb, xmin, xmax;
606 s32 ya, yb, ymin, ymax;
607 s32 x0, x1, x2, x3, dx3=0, x4, dx4=0, dx;
608 s32 y0, y1, y2;
609 s32 u0, u1, u2, u3, du3=0;
610 s32 v0, v1, v2, v3, dv3=0;
611 s32 r0, r1, r2, r3, dr3=0;
612 s32 g0, g1, g2, g3, dg3=0;
613 s32 b0, b1, b2, b3, db3=0;
614
615 x0 = GPU_EXPANDSIGN_POLY(PacketBuffer.S2[2] ); GPU_TESTRANGE(x0);
616 y0 = GPU_EXPANDSIGN_POLY(PacketBuffer.S2[3] ); GPU_TESTRANGE(y0);
617 x1 = GPU_EXPANDSIGN_POLY(PacketBuffer.S2[8] ); GPU_TESTRANGE(x1);
618 y1 = GPU_EXPANDSIGN_POLY(PacketBuffer.S2[9] ); GPU_TESTRANGE(y1);
619 x2 = GPU_EXPANDSIGN_POLY(PacketBuffer.S2[14]); GPU_TESTRANGE(x2);
620 y2 = GPU_EXPANDSIGN_POLY(PacketBuffer.S2[15]); GPU_TESTRANGE(y2);
621
622 x0 += DrawingOffset[0]; x1 += DrawingOffset[0]; x2 += DrawingOffset[0];
623 y0 += DrawingOffset[1]; y1 += DrawingOffset[1]; y2 += DrawingOffset[1];
624
625 xmin = DrawingArea[0]; xmax = DrawingArea[2];
626 ymin = DrawingArea[1]; ymax = DrawingArea[3];
627
628 {
629 int rx0 = Max2(xmin,Min3(x0,x1,x2));
630 int ry0 = Max2(ymin,Min3(y0,y1,y2));
631 int rx1 = Min2(xmax,Max3(x0,x1,x2));
632 int ry1 = Min2(ymax,Max3(y0,y1,y2));
633 if( rx0>=rx1 || ry0>=ry1) return;
634 }
635
636 r0 = PacketBuffer.U1[0]; g0 = PacketBuffer.U1[1]; b0 = PacketBuffer.U1[2];
637 u0 = PacketBuffer.U1[8]; v0 = PacketBuffer.U1[9];
638 r1 = PacketBuffer.U1[12]; g1 = PacketBuffer.U1[13]; b1 = PacketBuffer.U1[14];
639 u1 = PacketBuffer.U1[20]; v1 = PacketBuffer.U1[21];
640 r2 = PacketBuffer.U1[24]; g2 = PacketBuffer.U1[25]; b2 = PacketBuffer.U1[26];
641 u2 = PacketBuffer.U1[32]; v2 = PacketBuffer.U1[33];
642
643 if (y0 >= y1)
644 {
645 if( y0!=y1 || x0>x1 )
646 {
647 GPU_SWAP(x0, x1, temp); GPU_SWAP(y0, y1, temp);
648 GPU_SWAP(u0, u1, temp); GPU_SWAP(v0, v1, temp);
649 GPU_SWAP(r0, r1, temp); GPU_SWAP(g0, g1, temp); GPU_SWAP(b0, b1, temp);
650 }
651 }
652 if (y1 >= y2)
653 {
654 if( y1!=y2 || x1>x2 )
655 {
656 GPU_SWAP(x1, x2, temp); GPU_SWAP(y1, y2, temp);
657 GPU_SWAP(u1, u2, temp); GPU_SWAP(v1, v2, temp);
658 GPU_SWAP(r1, r2, temp); GPU_SWAP(g1, g2, temp); GPU_SWAP(b1, b2, temp);
659 }
660 }
661 if (y0 >= y1)
662 {
663 if( y0!=y1 || x0>x1 )
664 {
665 GPU_SWAP(x0, x1, temp); GPU_SWAP(y0, y1, temp);
666 GPU_SWAP(u0, u1, temp); GPU_SWAP(v0, v1, temp);
667 GPU_SWAP(r0, r1, temp); GPU_SWAP(g0, g1, temp); GPU_SWAP(b0, b1, temp);
668 }
669 }
670
671 ya = y2 - y0;
672 yb = y2 - y1;
673 dx = (x2 - x1) * ya - (x2 - x0) * yb;
674 du4 = (u2 - u1) * ya - (u2 - u0) * yb;
675 dv4 = (v2 - v1) * ya - (v2 - v0) * yb;
676 dr4 = (r2 - r1) * ya - (r2 - r0) * yb;
677 dg4 = (g2 - g1) * ya - (g2 - g0) * yb;
678 db4 = (b2 - b1) * ya - (b2 - b0) * yb;
679
680 s32 iF,iS;
681
682 xInv( dx, iF, iS);
683 du4 = xInvMulx( du4, iF, iS);
684 dv4 = xInvMulx( dv4, iF, iS);
685 dr4 = xInvMulx( dr4, iF, iS);
686 dg4 = xInvMulx( dg4, iF, iS);
687 db4 = xInvMulx( db4, iF, iS);
688 u32 dr = (u32)(dr4<< 8)&(0xffffffff<<21); if(dr4<0) dr+= 1<<21;
689 u32 dg = (u32)(dg4>> 3)&(0xffffffff<<10); if(dg4<0) dg+= 1<<10;
690 u32 db = (u32)(db4>>14)&(0xffffffff ); if(db4<0) db+= 1<< 0;
691 lInc = db + dg + dr;
692 tInc = ((u32)(du4<<7)&0x7fff0000) | ((u32)(dv4>>9)&0x00007fff);
693 tMsk = (TextureWindow[2]<<23) | (TextureWindow[3]<<7) | 0x00ff00ff;
694
695 for (s32 loop0 = 2; loop0; --loop0)
696 {
697 if (loop0 == 2)
698 {
699 ya = y0;
700 yb = y1;
701 u3 = i2x(u0);
702 v3 = i2x(v0);
703 r3 = i2x(r0);
704 g3 = i2x(g0);
705 b3 = i2x(b0);
706 x3 = i2x(x0);
707 x4 = y0!=y1 ? x3 : i2x(x1);
708 if (dx < 0)
709 {
710 xInv( (y2 - y0), iF, iS);
711 dx3 = xInvMulx( (x2 - x0), iF, iS);
712 du3 = xInvMulx( (u2 - u0), iF, iS);
713 dv3 = xInvMulx( (v2 - v0), iF, iS);
714 dr3 = xInvMulx( (r2 - r0), iF, iS);
715 dg3 = xInvMulx( (g2 - g0), iF, iS);
716 db3 = xInvMulx( (b2 - b0), iF, iS);
717 dx4 = xLoDivx ( (x1 - x0), (y1 - y0));
718 }
719 else
720 {
721 xInv( (y1 - y0), iF, iS);
722 dx3 = xInvMulx( (x1 - x0), iF, iS);
723 du3 = xInvMulx( (u1 - u0), iF, iS);
724 dv3 = xInvMulx( (v1 - v0), iF, iS);
725 dr3 = xInvMulx( (r1 - r0), iF, iS);
726 dg3 = xInvMulx( (g1 - g0), iF, iS);
727 db3 = xInvMulx( (b1 - b0), iF, iS);
728 dx4 = xLoDivx ( (x2 - x0), (y2 - y0));
729 }
730 }
731 else
732 {
733 ya = y1;
734 yb = y2;
735 if (dx < 0)
736 {
737 temp = y1 - y0;
738 u3 = i2x(u0) + (du3 * temp);
739 v3 = i2x(v0) + (dv3 * temp);
740 r3 = i2x(r0) + (dr3 * temp);
741 g3 = i2x(g0) + (dg3 * temp);
742 b3 = i2x(b0) + (db3 * temp);
743 x3 = i2x(x0) + (dx3 * temp);
744 x4 = i2x(x1);
745 dx4 = xLoDivx((x2 - x1), (y2 - y1));
746 }
747 else
748 {
749 u3 = i2x(u1);
750 v3 = i2x(v1);
751 r3 = i2x(r1);
752 g3 = i2x(g1);
753 b3 = i2x(b1);
754 x3 = i2x(x1);
755 x4 = i2x(x0) + (dx4 * (y1 - y0));
756
757 xInv( (y2 - y1), iF, iS);
758 dx3 = xInvMulx( (x2 - x1), iF, iS);
759 du3 = xInvMulx( (u2 - u1), iF, iS);
760 dv3 = xInvMulx( (v2 - v1), iF, iS);
761 dr3 = xInvMulx( (r2 - r1), iF, iS);
762 dg3 = xInvMulx( (g2 - g1), iF, iS);
763 db3 = xInvMulx( (b2 - b1), iF, iS);
764 }
765 }
766
767 temp = ymin - ya;
768 if (temp > 0)
769 {
770 ya = ymin;
771 x3 += dx3*temp; x4 += dx4*temp;
772 u3 += du3*temp; v3 += dv3*temp;
773 r3 += dr3*temp; g3 += dg3*temp; b3 += db3*temp;
774 }
775 if (yb > ymax) yb = ymax;
776 if (ya>=yb) continue;
777
778 x3+= fixed_HALF; x4+= fixed_HALF;
779 u3+= fixed_HALF; v4+= fixed_HALF;
780 r3+= fixed_HALF; g3+= fixed_HALF; b3+= fixed_HALF;
781 u16* PixelBase = &((u16*)GPU_FrameBuffer)[FRAME_OFFSET(0, ya)];
782
783 if (!progressInterlace)
784 {
785 for(;ya<yb;++ya, PixelBase += FRAME_WIDTH, x3+=dx3, x4+=dx4, u3+=du3, v3+=dv3, r3+=dr3, g3+=dg3, b3+=db3)
786 {
787 if (ya&li) continue;
788 xa = x2i(x3);
789 xb = x2i(x4);
790 if( (xa>xmax) || (xb<xmin)) continue;
791
792 temp = xmin - xa;
793 if(temp > 0)
794 {
795 xa = xmin;
796 u4 = u3 + du4*temp; v4 = v3 + dv4*temp;
797 r4 = r3 + dr4*temp; g4 = g3 + dg4*temp; b4 = b3 + db4*temp;
798 }
799 else
800 {
801 u4 = u3; v4 = v3;
802 r4 = r3; g4 = g3; b4 = b3;
803 }
804 if(xb > xmax) xb = xmax;
805 xb-=xa;
806 if(xb>0) gpuPolySpanDriver(PixelBase + xa,xb);
807 }
808 }
809 else
810 {
811 bool flag=progressInterlace_flag;
812 for(;ya<yb;++ya, PixelBase += FRAME_WIDTH, x3+=dx3, x4+=dx4, u3+=du3, v3+=dv3, r3+=dr3, g3+=dg3, b3+=db3)
813 {
814 if ((ya&li) && (flag=!flag)) continue;
815 xa = x2i(x3);
816 xb = x2i(x4);
817 if ((xa>xmax) || (xb<xmin)) continue;
818
819 temp = xmin - xa;
820 if(temp > 0)
821 {
822 xa = xmin;
823 u4 = u3 + du4*temp; v4 = v3 + dv4*temp;
824 r4 = r3 + dr4*temp; g4 = g3 + dg4*temp; b4 = b3 + db4*temp;
825 }
826 else
827 {
828 u4 = u3; v4 = v3;
829 r4 = r3; g4 = g3; b4 = b3;
830 }
831 if(xb > xmax) xb = xmax;
832 xb-=xa;
833 if(xb>0) gpuPolySpanDriver(PixelBase + xa,xb);
834 }
835 }
836 }
837}