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 | INLINE void gpuSetTexture(u16 tpage) |
23 | { |
24 | long tp; |
25 | long tx, ty; |
26 | GPU_GP1 = (GPU_GP1 & ~0x7FF) | (tpage & 0x7FF); |
27 | |
28 | TextureWindow[0]&= ~TextureWindow[2]; |
29 | TextureWindow[1]&= ~TextureWindow[3]; |
30 | |
31 | tp = (tpage >> 7) & 3; |
32 | tx = (tpage & 0x0F) << 6; |
33 | ty = (tpage & 0x10) << 4; |
34 | |
35 | tx += (TextureWindow[0] >> (2 - tp)); |
36 | ty += TextureWindow[1]; |
37 | |
38 | BLEND_MODE = (((tpage>>5)&0x3) ) << 3; |
39 | TEXT_MODE = (((tpage>>7)&0x3) + 1 ) << 5; // +1 el cero no lo usamos |
40 | |
41 | TBA = &((u16*)GPU_FrameBuffer)[FRAME_OFFSET(tx, ty)]; |
42 | |
43 | } |
44 | |
45 | /////////////////////////////////////////////////////////////////////////////// |
46 | INLINE void gpuSetCLUT(u16 clut) |
47 | { |
48 | CBA = &((u16*)GPU_FrameBuffer)[(clut & 0x7FFF) << 4]; |
49 | } |
50 | |
51 | #ifdef ENABLE_GPU_NULL_SUPPORT |
52 | #define NULL_GPU() break |
53 | #else |
54 | #define NULL_GPU() |
55 | #endif |
56 | |
57 | #ifdef ENABLE_GPU_LOG_SUPPORT |
58 | #define DO_LOG(expr) printf expr |
59 | #else |
60 | #define DO_LOG(expr) {} |
61 | #endif |
62 | |
63 | #define Blending (((PRIM&0x2)&&(blend))?(PRIM&0x2):0) |
64 | #define Blending_Mode (((PRIM&0x2)&&(blend))?BLEND_MODE:0) |
65 | #define Lighting (((~PRIM)&0x1)&&(light)) |
66 | |
67 | void gpuSendPacketFunction(const int PRIM) |
68 | { |
69 | //printf("0x%x\n",PRIM); |
70 | |
71 | switch (PRIM) |
72 | { |
73 | case 0x02: |
74 | NULL_GPU(); |
75 | gpuClearImage(); // prim handles updateLace && skip |
76 | DO_LOG(("gpuClearImage(0x%x)\n",PRIM)); |
77 | break; |
78 | case 0x20: |
79 | case 0x21: |
80 | case 0x22: |
81 | case 0x23: |
82 | if (!isSkip) |
83 | { |
84 | NULL_GPU(); |
85 | gpuDrawF3(gpuPolySpanDrivers [Blending_Mode | Masking | Blending | PixelMSB]); |
86 | DO_LOG(("gpuDrawF3(0x%x)\n",PRIM)); |
87 | } |
88 | break; |
89 | case 0x24: |
90 | case 0x25: |
91 | case 0x26: |
92 | case 0x27: |
93 | if (!isSkip) |
94 | { |
95 | NULL_GPU(); |
96 | gpuSetCLUT (PacketBuffer.U4[2] >> 16); |
97 | gpuSetTexture (PacketBuffer.U4[4] >> 16); |
98 | if ((PacketBuffer.U1[0]>0x5F) && (PacketBuffer.U1[1]>0x5F) && (PacketBuffer.U1[2]>0x5F)) |
99 | gpuDrawFT3(gpuPolySpanDrivers [Blending_Mode | TEXT_MODE | Masking | Blending | PixelMSB]); |
100 | else |
101 | gpuDrawFT3(gpuPolySpanDrivers [Blending_Mode | TEXT_MODE | Masking | Blending | Lighting | PixelMSB]); |
102 | DO_LOG(("gpuDrawFT3(0x%x)\n",PRIM)); |
103 | } |
104 | break; |
105 | case 0x28: |
106 | case 0x29: |
107 | case 0x2A: |
108 | case 0x2B: |
109 | if (!isSkip) |
110 | { |
111 | NULL_GPU(); |
112 | const PP gpuPolySpanDriver = gpuPolySpanDrivers [Blending_Mode | Masking | Blending | PixelMSB]; |
113 | //--PacketBuffer.S2[6]; |
114 | gpuDrawF3(gpuPolySpanDriver); |
115 | PacketBuffer.U4[1] = PacketBuffer.U4[4]; |
116 | //--PacketBuffer.S2[2]; |
117 | gpuDrawF3(gpuPolySpanDriver); |
118 | DO_LOG(("gpuDrawF4(0x%x)\n",PRIM)); |
119 | } |
120 | break; |
121 | case 0x2C: |
122 | case 0x2D: |
123 | case 0x2E: |
124 | case 0x2F: |
125 | if (!isSkip) |
126 | { |
127 | NULL_GPU(); |
128 | gpuSetCLUT (PacketBuffer.U4[2] >> 16); |
129 | gpuSetTexture (PacketBuffer.U4[4] >> 16); |
130 | PP gpuPolySpanDriver; |
131 | if ((PacketBuffer.U1[0]>0x5F) && (PacketBuffer.U1[1]>0x5F) && (PacketBuffer.U1[2]>0x5F)) |
132 | gpuPolySpanDriver = gpuPolySpanDrivers [Blending_Mode | TEXT_MODE | Masking | Blending | PixelMSB]; |
133 | else |
134 | gpuPolySpanDriver = gpuPolySpanDrivers [Blending_Mode | TEXT_MODE | Masking | Blending | Lighting | PixelMSB]; |
135 | //--PacketBuffer.S2[6]; |
136 | gpuDrawFT3(gpuPolySpanDriver); |
137 | PacketBuffer.U4[1] = PacketBuffer.U4[7]; |
138 | PacketBuffer.U4[2] = PacketBuffer.U4[8]; |
139 | //--PacketBuffer.S2[2]; |
140 | gpuDrawFT3(gpuPolySpanDriver); |
141 | DO_LOG(("gpuDrawFT4(0x%x)\n",PRIM)); |
142 | } |
143 | break; |
144 | case 0x30: |
145 | case 0x31: |
146 | case 0x32: |
147 | case 0x33: |
148 | if (!isSkip) |
149 | { |
150 | NULL_GPU(); |
151 | gpuDrawG3(gpuPolySpanDrivers [Blending_Mode | Masking | Blending | 129 | PixelMSB]); |
152 | DO_LOG(("gpuDrawG3(0x%x)\n",PRIM)); |
153 | } |
154 | break; |
155 | case 0x34: |
156 | case 0x35: |
157 | case 0x36: |
158 | case 0x37: |
159 | if (!isSkip) |
160 | { |
161 | NULL_GPU(); |
162 | gpuSetCLUT (PacketBuffer.U4[2] >> 16); |
163 | gpuSetTexture (PacketBuffer.U4[5] >> 16); |
164 | gpuDrawGT3(gpuPolySpanDrivers [Blending_Mode | TEXT_MODE | Masking | Blending | ((Lighting)?129:0) | PixelMSB]); |
165 | DO_LOG(("gpuDrawGT3(0x%x)\n",PRIM)); |
166 | } |
167 | break; |
168 | case 0x38: |
169 | case 0x39: |
170 | case 0x3A: |
171 | case 0x3B: |
172 | if (!isSkip) |
173 | { |
174 | NULL_GPU(); |
175 | const PP gpuPolySpanDriver = gpuPolySpanDrivers [Blending_Mode | Masking | Blending | 129 | PixelMSB]; |
176 | //--PacketBuffer.S2[6]; |
177 | gpuDrawG3(gpuPolySpanDriver); |
178 | PacketBuffer.U4[0] = PacketBuffer.U4[6]; |
179 | PacketBuffer.U4[1] = PacketBuffer.U4[7]; |
180 | //--PacketBuffer.S2[2]; |
181 | gpuDrawG3(gpuPolySpanDriver); |
182 | DO_LOG(("gpuDrawG4(0x%x)\n",PRIM)); |
183 | } |
184 | break; |
185 | case 0x3C: |
186 | case 0x3D: |
187 | case 0x3E: |
188 | case 0x3F: |
189 | if (!isSkip) |
190 | { |
191 | NULL_GPU(); |
192 | gpuSetCLUT (PacketBuffer.U4[2] >> 16); |
193 | gpuSetTexture (PacketBuffer.U4[5] >> 16); |
194 | const PP gpuPolySpanDriver = gpuPolySpanDrivers [Blending_Mode | TEXT_MODE | Masking | Blending | ((Lighting)?129:0) | PixelMSB]; |
195 | //--PacketBuffer.S2[6]; |
196 | gpuDrawGT3(gpuPolySpanDriver); |
197 | PacketBuffer.U4[0] = PacketBuffer.U4[9]; |
198 | PacketBuffer.U4[1] = PacketBuffer.U4[10]; |
199 | PacketBuffer.U4[2] = PacketBuffer.U4[11]; |
200 | //--PacketBuffer.S2[2]; |
201 | gpuDrawGT3(gpuPolySpanDriver); |
202 | DO_LOG(("gpuDrawGT4(0x%x)\n",PRIM)); |
203 | } |
204 | break; |
205 | case 0x40: |
206 | case 0x41: |
207 | case 0x42: |
208 | case 0x43: |
209 | if (!isSkip) |
210 | { |
211 | NULL_GPU(); |
212 | gpuDrawLF(gpuPixelDrivers [ (Blending_Mode | Masking | Blending | (PixelMSB>>3)) >> 1]); |
213 | DO_LOG(("gpuDrawLF(0x%x)\n",PRIM)); |
214 | } |
215 | break; |
216 | case 0x48: |
217 | case 0x49: |
218 | case 0x4A: |
219 | case 0x4B: |
220 | case 0x4C: |
221 | case 0x4D: |
222 | case 0x4E: |
223 | case 0x4F: |
224 | if (!isSkip) |
225 | { |
226 | NULL_GPU(); |
227 | gpuDrawLF(gpuPixelDrivers [ (Blending_Mode | Masking | Blending | (PixelMSB>>3)) >> 1]); |
228 | DO_LOG(("gpuDrawLF(0x%x)\n",PRIM)); |
229 | } |
230 | if ((PacketBuffer.U4[3] & 0xF000F000) != 0x50005000) |
231 | { |
232 | PacketBuffer.U4[1] = PacketBuffer.U4[2]; |
233 | PacketBuffer.U4[2] = PacketBuffer.U4[3]; |
234 | PacketCount = 1; |
235 | PacketIndex = 3; |
236 | } |
237 | break; |
238 | case 0x50: |
239 | case 0x51: |
240 | case 0x52: |
241 | case 0x53: |
242 | if (!isSkip) |
243 | { |
244 | NULL_GPU(); |
245 | gpuDrawLG(gpuPixelDrivers [ (Blending_Mode | Masking | Blending | (PixelMSB>>3)) >> 1]); |
246 | DO_LOG(("gpuDrawLG(0x%x)\n",PRIM)); |
247 | } |
248 | break; |
249 | case 0x58: |
250 | case 0x59: |
251 | case 0x5A: |
252 | case 0x5B: |
253 | case 0x5C: |
254 | case 0x5D: |
255 | case 0x5E: |
256 | case 0x5F: |
257 | if (!isSkip) |
258 | { |
259 | NULL_GPU(); |
260 | gpuDrawLG(gpuPixelDrivers [ (Blending_Mode | Masking | Blending | (PixelMSB>>3)) >> 1]); |
261 | DO_LOG(("gpuDrawLG(0x%x)\n",PRIM)); |
262 | } |
263 | if ((PacketBuffer.U4[4] & 0xF000F000) != 0x50005000) |
264 | { |
265 | PacketBuffer.U1[3 + (2 * 4)] = PacketBuffer.U1[3 + (0 * 4)]; |
266 | PacketBuffer.U4[0] = PacketBuffer.U4[2]; |
267 | PacketBuffer.U4[1] = PacketBuffer.U4[3]; |
268 | PacketBuffer.U4[2] = PacketBuffer.U4[4]; |
269 | PacketCount = 2; |
270 | PacketIndex = 3; |
271 | } |
272 | break; |
273 | case 0x60: |
274 | case 0x61: |
275 | case 0x62: |
276 | case 0x63: |
277 | if (!isSkip) |
278 | { |
279 | NULL_GPU(); |
280 | gpuDrawT(gpuTileSpanDrivers [Blending_Mode | Masking | Blending | (PixelMSB>>3)]); |
281 | DO_LOG(("gpuDrawT(0x%x)\n",PRIM)); |
282 | } |
283 | break; |
284 | case 0x64: |
285 | case 0x65: |
286 | case 0x66: |
287 | case 0x67: |
288 | if (!isSkip) |
289 | { |
290 | NULL_GPU(); |
291 | gpuSetCLUT (PacketBuffer.U4[2] >> 16); |
292 | gpuSetTexture (GPU_GP1); |
293 | if ((PacketBuffer.U1[0]>0x5F) && (PacketBuffer.U1[1]>0x5F) && (PacketBuffer.U1[2]>0x5F)) |
294 | gpuDrawS(gpuSpriteSpanDrivers [Blending_Mode | TEXT_MODE | Masking | Blending | (enableAbbeyHack<<7) | PixelMSB]); |
295 | else |
296 | gpuDrawS(gpuSpriteSpanDrivers [Blending_Mode | TEXT_MODE | Masking | Blending | Lighting | (enableAbbeyHack<<7) | PixelMSB]); |
297 | DO_LOG(("gpuDrawS(0x%x)\n",PRIM)); |
298 | } |
299 | break; |
300 | case 0x68: |
301 | case 0x69: |
302 | case 0x6A: |
303 | case 0x6B: |
304 | if (!isSkip) |
305 | { |
306 | NULL_GPU(); |
307 | PacketBuffer.U4[2] = 0x00010001; |
308 | gpuDrawT(gpuTileSpanDrivers [Blending_Mode | Masking | Blending | (PixelMSB>>3)]); |
309 | DO_LOG(("gpuDrawT(0x%x)\n",PRIM)); |
310 | } |
311 | break; |
312 | case 0x70: |
313 | case 0x71: |
314 | case 0x72: |
315 | case 0x73: |
316 | if (!isSkip) |
317 | { |
318 | NULL_GPU(); |
319 | PacketBuffer.U4[2] = 0x00080008; |
320 | gpuDrawT(gpuTileSpanDrivers [Blending_Mode | Masking | Blending | (PixelMSB>>3)]); |
321 | DO_LOG(("gpuDrawT(0x%x)\n",PRIM)); |
322 | } |
323 | break; |
324 | case 0x74: |
325 | case 0x75: |
326 | case 0x76: |
327 | case 0x77: |
328 | if (!isSkip) |
329 | { |
330 | NULL_GPU(); |
331 | PacketBuffer.U4[3] = 0x00080008; |
332 | gpuSetCLUT (PacketBuffer.U4[2] >> 16); |
333 | gpuSetTexture (GPU_GP1); |
334 | if ((PacketBuffer.U1[0]>0x5F) && (PacketBuffer.U1[1]>0x5F) && (PacketBuffer.U1[2]>0x5F)) |
335 | gpuDrawS(gpuSpriteSpanDrivers [Blending_Mode | TEXT_MODE | Masking | Blending | (enableAbbeyHack<<7) | PixelMSB]); |
336 | else |
337 | gpuDrawS(gpuSpriteSpanDrivers [Blending_Mode | TEXT_MODE | Masking | Blending | Lighting | (enableAbbeyHack<<7) | PixelMSB]); |
338 | DO_LOG(("gpuDrawS(0x%x)\n",PRIM)); |
339 | } |
340 | break; |
341 | case 0x78: |
342 | case 0x79: |
343 | case 0x7A: |
344 | case 0x7B: |
345 | if (!isSkip) |
346 | { |
347 | NULL_GPU(); |
348 | PacketBuffer.U4[2] = 0x00100010; |
349 | gpuDrawT(gpuTileSpanDrivers [Blending_Mode | Masking | Blending | (PixelMSB>>3)]); |
350 | DO_LOG(("gpuDrawT(0x%x)\n",PRIM)); |
351 | } |
352 | break; |
353 | case 0x7C: |
354 | case 0x7D: |
b3db9409 |
355 | #ifdef __arm__ |
356 | if ((GPU_GP1 & 0x180) == 0 && (Masking | PixelMSB) == 0) |
357 | { |
358 | gpuSetCLUT (PacketBuffer.U4[2] >> 16); |
359 | gpuSetTexture (GPU_GP1); |
360 | gpuDrawS16(); |
361 | break; |
362 | } |
363 | // fallthrough |
364 | #endif |
86aad47b |
365 | case 0x7E: |
366 | case 0x7F: |
367 | if (!isSkip) |
368 | { |
369 | NULL_GPU(); |
370 | PacketBuffer.U4[3] = 0x00100010; |
371 | gpuSetCLUT (PacketBuffer.U4[2] >> 16); |
372 | gpuSetTexture (GPU_GP1); |
373 | if ((PacketBuffer.U1[0]>0x5F) && (PacketBuffer.U1[1]>0x5F) && (PacketBuffer.U1[2]>0x5F)) |
374 | gpuDrawS(gpuSpriteSpanDrivers [Blending_Mode | TEXT_MODE | Masking | Blending | (enableAbbeyHack<<7) | PixelMSB]); |
375 | else |
376 | gpuDrawS(gpuSpriteSpanDrivers [Blending_Mode | TEXT_MODE | Masking | Blending | Lighting | (enableAbbeyHack<<7) | PixelMSB]); |
377 | DO_LOG(("gpuDrawS(0x%x)\n",PRIM)); |
378 | } |
379 | break; |
380 | case 0x80: // vid -> vid |
381 | gpuMoveImage(); // prim handles updateLace && skip |
382 | DO_LOG(("gpuMoveImage(0x%x)\n",PRIM)); |
383 | break; |
384 | case 0xA0: // sys ->vid |
385 | gpuLoadImage(); // prim handles updateLace && skip |
89c0de42 |
386 | #ifndef isSkip // not a define |
86aad47b |
387 | if (alt_fps) isSkip=false; |
89c0de42 |
388 | #endif |
86aad47b |
389 | DO_LOG(("gpuLoadImage(0x%x)\n",PRIM)); |
390 | break; |
391 | case 0xC0: // vid -> sys |
392 | gpuStoreImage(); // prim handles updateLace && skip |
393 | DO_LOG(("gpuStoreImage(0x%x)\n",PRIM)); |
394 | break; |
395 | case 0xE1: |
396 | { |
397 | const u32 temp = PacketBuffer.U4[0]; |
398 | GPU_GP1 = (GPU_GP1 & ~0x000007FF) | (temp & 0x000007FF); |
399 | gpuSetTexture(temp); |
400 | DO_LOG(("gpuSetTexture(0x%x)\n",PRIM)); |
401 | } |
402 | break; |
403 | case 0xE2: |
404 | { |
405 | static const u8 TextureMask[32] = { |
406 | 255, 7, 15, 7, 31, 7, 15, 7, 63, 7, 15, 7, 31, 7, 15, 7, // |
407 | 127, 7, 15, 7, 31, 7, 15, 7, 63, 7, 15, 7, 31, 7, 15, 7 // |
408 | }; |
409 | const u32 temp = PacketBuffer.U4[0]; |
410 | TextureWindow[0] = ((temp >> 10) & 0x1F) << 3; |
411 | TextureWindow[1] = ((temp >> 15) & 0x1F) << 3; |
412 | TextureWindow[2] = TextureMask[(temp >> 0) & 0x1F]; |
413 | TextureWindow[3] = TextureMask[(temp >> 5) & 0x1F]; |
414 | gpuSetTexture(GPU_GP1); |
c006d9e3 |
415 | //isSkip = false; |
86aad47b |
416 | DO_LOG(("TextureWindow(0x%x)\n",PRIM)); |
417 | } |
418 | break; |
419 | case 0xE3: |
420 | { |
421 | const u32 temp = PacketBuffer.U4[0]; |
422 | DrawingArea[0] = temp & 0x3FF; |
423 | DrawingArea[1] = (temp >> 10) & 0x3FF; |
c006d9e3 |
424 | //isSkip = false; |
86aad47b |
425 | DO_LOG(("DrawingArea_Pos(0x%x)\n",PRIM)); |
426 | } |
427 | break; |
428 | case 0xE4: |
429 | { |
430 | const u32 temp = PacketBuffer.U4[0]; |
431 | DrawingArea[2] = (temp & 0x3FF) + 1; |
432 | DrawingArea[3] = ((temp >> 10) & 0x3FF) + 1; |
c006d9e3 |
433 | //isSkip = false; |
86aad47b |
434 | DO_LOG(("DrawingArea_Size(0x%x)\n",PRIM)); |
435 | } |
436 | break; |
437 | case 0xE5: |
438 | { |
439 | const u32 temp = PacketBuffer.U4[0]; |
440 | DrawingOffset[0] = ((long)temp<<(32-11))>>(32-11); |
441 | DrawingOffset[1] = ((long)temp<<(32-22))>>(32-11); |
c006d9e3 |
442 | //isSkip = false; |
86aad47b |
443 | DO_LOG(("DrawingOffset(0x%x)\n",PRIM)); |
444 | } |
445 | break; |
446 | case 0xE6: |
447 | { |
448 | const u32 temp = PacketBuffer.U4[0]; |
449 | //GPU_GP1 = (GPU_GP1 & ~0x00001800) | ((temp&3) << 11); |
450 | Masking = (temp & 0x2) << 1; |
451 | PixelMSB =(temp & 0x1) << 8; |
452 | DO_LOG(("SetMask(0x%x)\n",PRIM)); |
453 | } |
454 | break; |
455 | } |
456 | } |