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 | |
53636f15 |
138 | for(;ya<yb;++ya, PixelBase += FRAME_WIDTH, x3+=dx3, x4+=dx4) |
86aad47b |
139 | { |
53636f15 |
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); |
86aad47b |
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 | |
53636f15 |
313 | for(;ya<yb;++ya, PixelBase += FRAME_WIDTH, x3+=dx3, x4+=dx4, u3+=du3, v3+=dv3) |
86aad47b |
314 | { |
53636f15 |
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) |
86aad47b |
322 | { |
53636f15 |
323 | xa = xmin; |
324 | u4 = u3 + du4*temp; |
325 | v4 = v3 + dv4*temp; |
86aad47b |
326 | } |
53636f15 |
327 | else |
86aad47b |
328 | { |
53636f15 |
329 | u4 = u3; |
330 | v4 = v3; |
86aad47b |
331 | } |
53636f15 |
332 | if(xb > xmax) xb = xmax; |
333 | xb-=xa; |
334 | if(xb>0) gpuPolySpanDriver(PixelBase + xa,xb); |
86aad47b |
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 | |
53636f15 |
497 | for(;ya<yb;++ya, PixelBase += FRAME_WIDTH, x3+=dx3, x4+=dx4, r3+=dr3, g3+=dg3, b3+=db3) |
86aad47b |
498 | { |
53636f15 |
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) |
86aad47b |
506 | { |
53636f15 |
507 | xa = xmin; |
508 | r4 = r3 + dr4*temp; g4 = g3 + dg4*temp; b4 = b3 + db4*temp; |
86aad47b |
509 | } |
53636f15 |
510 | else |
86aad47b |
511 | { |
53636f15 |
512 | r4 = r3; g4 = g3; b4 = b3; |
86aad47b |
513 | } |
53636f15 |
514 | if(xb > xmax) xb = xmax; |
515 | xb-=xa; |
516 | if(xb>0) gpuPolySpanDriver(PixelBase + xa,xb); |
86aad47b |
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 | |
53636f15 |
707 | for(;ya<yb;++ya, PixelBase += FRAME_WIDTH, x3+=dx3, x4+=dx4, u3+=du3, v3+=dv3, r3+=dr3, g3+=dg3, b3+=db3) |
86aad47b |
708 | { |
53636f15 |
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) |
86aad47b |
716 | { |
53636f15 |
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; |
86aad47b |
720 | } |
53636f15 |
721 | else |
86aad47b |
722 | { |
53636f15 |
723 | u4 = u3; v4 = v3; |
724 | r4 = r3; g4 = g3; b4 = b3; |
86aad47b |
725 | } |
53636f15 |
726 | if(xb > xmax) xb = xmax; |
727 | xb-=xa; |
728 | if(xb>0) gpuPolySpanDriver(PixelBase + xa,xb); |
86aad47b |
729 | } |
730 | } |
731 | } |