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