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 | /////////////////////////////////////////////////////////////////////////////// |
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 | 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 | /*---------------------------------------------------------------------- |
171 | FT3 |
172 | ----------------------------------------------------------------------*/ |
173 | |
174 | void 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 | /*---------------------------------------------------------------------- |
388 | G3 |
389 | ----------------------------------------------------------------------*/ |
390 | |
391 | void 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 | /*---------------------------------------------------------------------- |
598 | GT3 |
599 | ----------------------------------------------------------------------*/ |
600 | |
601 | void 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 | } |