Commit | Line | Data |
---|---|---|
86aad47b | 1 | /*************************************************************************** |
2 | * Copyright (C) 2010 PCSX4ALL Team * | |
3 | * Copyright (C) 2010 Unai * | |
030d1121 | 4 | * Copyright (C) 2016 Senquack (dansilsby <AT> gmail <DOT> com) * |
86aad47b | 5 | * * |
6 | * This program is free software; you can redistribute it and/or modify * | |
7 | * it under the terms of the GNU General Public License as published by * | |
8 | * the Free Software Foundation; either version 2 of the License, or * | |
9 | * (at your option) any later version. * | |
10 | * * | |
11 | * This program is distributed in the hope that it will be useful, * | |
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of * | |
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * | |
14 | * GNU General Public License for more details. * | |
15 | * * | |
16 | * You should have received a copy of the GNU General Public License * | |
17 | * along with this program; if not, write to the * | |
18 | * Free Software Foundation, Inc., * | |
19 | * 51 Franklin Street, Fifth Floor, Boston, MA 02111-1307 USA. * | |
20 | ***************************************************************************/ | |
21 | ||
908e426c | 22 | #ifndef __GPU_UNAI_GPU_COMMAND_H__ |
23 | #define __GPU_UNAI_GPU_COMMAND_H__ | |
24 | ||
86aad47b | 25 | /////////////////////////////////////////////////////////////////////////////// |
030d1121 | 26 | void gpuSetTexture(u16 tpage) |
86aad47b | 27 | { |
030d1121 | 28 | u32 tmode, tx, ty; |
29 | gpu_unai.GPU_GP1 = (gpu_unai.GPU_GP1 & ~0x1FF) | (tpage & 0x1FF); | |
30 | gpu_unai.TextureWindow[0]&= ~gpu_unai.TextureWindow[2]; | |
31 | gpu_unai.TextureWindow[1]&= ~gpu_unai.TextureWindow[3]; | |
86aad47b | 32 | |
030d1121 | 33 | tmode = (tpage >> 7) & 3; // 16bpp, 8bpp, or 4bpp texture colors? |
34 | // 0: 4bpp 1: 8bpp 2/3: 16bpp | |
35 | ||
36 | // Nocash PSX docs state setting of 3 is same as setting of 2 (16bpp): | |
37 | // Note: DrHell assumes 3 is same as 0.. TODO: verify which is correct? | |
38 | if (tmode == 3) tmode = 2; | |
86aad47b | 39 | |
86aad47b | 40 | tx = (tpage & 0x0F) << 6; |
41 | ty = (tpage & 0x10) << 4; | |
42 | ||
030d1121 | 43 | tx += (gpu_unai.TextureWindow[0] >> (2 - tmode)); |
44 | ty += gpu_unai.TextureWindow[1]; | |
86aad47b | 45 | |
030d1121 | 46 | gpu_unai.BLEND_MODE = ((tpage>>5) & 3) << 3; |
47 | gpu_unai.TEXT_MODE = (tmode + 1) << 5; // gpu_unai.TEXT_MODE should be values 1..3, so add one | |
4949d4ff | 48 | gpu_unai.TBA = &gpu_unai.vram[FRAME_OFFSET(tx, ty)]; |
86aad47b | 49 | } |
50 | ||
51 | /////////////////////////////////////////////////////////////////////////////// | |
52 | INLINE void gpuSetCLUT(u16 clut) | |
53 | { | |
4949d4ff | 54 | gpu_unai.CBA = &gpu_unai.vram[(clut & 0x7FFF) << 4]; |
86aad47b | 55 | } |
56 | ||
57 | #ifdef ENABLE_GPU_NULL_SUPPORT | |
58 | #define NULL_GPU() break | |
59 | #else | |
60 | #define NULL_GPU() | |
61 | #endif | |
62 | ||
63 | #ifdef ENABLE_GPU_LOG_SUPPORT | |
64 | #define DO_LOG(expr) printf expr | |
65 | #else | |
66 | #define DO_LOG(expr) {} | |
67 | #endif | |
68 | ||
030d1121 | 69 | #define Blending (((PRIM&0x2) && BlendingEnabled()) ? (PRIM&0x2) : 0) |
70 | #define Blending_Mode (((PRIM&0x2) && BlendingEnabled()) ? gpu_unai.BLEND_MODE : 0) | |
71 | #define Lighting (((~PRIM)&0x1) && LightingEnabled()) | |
72 | // Dithering applies only to Gouraud-shaded polys or texture-blended polys: | |
73 | #define Dithering (((((~PRIM)&0x1) || (PRIM&0x10)) && DitheringEnabled()) ? \ | |
74 | (ForcedDitheringEnabled() ? (1<<9) : (gpu_unai.GPU_GP1 & (1 << 9))) \ | |
75 | : 0) | |
76 | ||
77 | /////////////////////////////////////////////////////////////////////////////// | |
78 | //Now handled by Rearmed's gpulib and gpu_unai/gpulib_if.cpp: | |
79 | /////////////////////////////////////////////////////////////////////////////// | |
80 | #ifndef USE_GPULIB | |
81 | ||
82 | // Handles GP0 draw settings commands 0xE1...0xE6 | |
83 | static void gpuGP0Cmd_0xEx(gpu_unai_t &gpu_unai, u32 cmd_word) | |
84 | { | |
85 | // Assume incoming GP0 command is 0xE1..0xE6, convert to 1..6 | |
86 | u8 num = (cmd_word >> 24) & 7; | |
87 | switch (num) { | |
88 | case 1: { | |
89 | // GP0(E1h) - Draw Mode setting (aka "Texpage") | |
90 | DO_LOG(("GP0(0xE1) DrawMode TexPage(0x%x)\n", cmd_word)); | |
91 | u32 cur_texpage = gpu_unai.GPU_GP1 & 0x7FF; | |
92 | u32 new_texpage = cmd_word & 0x7FF; | |
93 | if (cur_texpage != new_texpage) { | |
94 | gpu_unai.GPU_GP1 = (gpu_unai.GPU_GP1 & ~0x7FF) | new_texpage; | |
95 | gpuSetTexture(gpu_unai.GPU_GP1); | |
96 | } | |
97 | } break; | |
98 | ||
99 | case 2: { | |
100 | // GP0(E2h) - Texture Window setting | |
101 | DO_LOG(("GP0(0xE2) TextureWindow(0x%x)\n", cmd_word)); | |
102 | if (cmd_word != gpu_unai.TextureWindowCur) { | |
103 | static const u8 TextureMask[32] = { | |
104 | 255, 7, 15, 7, 31, 7, 15, 7, 63, 7, 15, 7, 31, 7, 15, 7, | |
105 | 127, 7, 15, 7, 31, 7, 15, 7, 63, 7, 15, 7, 31, 7, 15, 7 | |
106 | }; | |
107 | gpu_unai.TextureWindowCur = cmd_word; | |
108 | gpu_unai.TextureWindow[0] = ((cmd_word >> 10) & 0x1F) << 3; | |
109 | gpu_unai.TextureWindow[1] = ((cmd_word >> 15) & 0x1F) << 3; | |
110 | gpu_unai.TextureWindow[2] = TextureMask[(cmd_word >> 0) & 0x1F]; | |
111 | gpu_unai.TextureWindow[3] = TextureMask[(cmd_word >> 5) & 0x1F]; | |
112 | gpu_unai.TextureWindow[0] &= ~gpu_unai.TextureWindow[2]; | |
113 | gpu_unai.TextureWindow[1] &= ~gpu_unai.TextureWindow[3]; | |
114 | ||
115 | // Inner loop vars must be updated whenever texture window is changed: | |
116 | const u32 fb = FIXED_BITS; // # of fractional fixed-pt bits of u4/v4 | |
117 | gpu_unai.u_msk = (((u32)gpu_unai.TextureWindow[2]) << fb) | ((1 << fb) - 1); | |
118 | gpu_unai.v_msk = (((u32)gpu_unai.TextureWindow[3]) << fb) | ((1 << fb) - 1); | |
119 | ||
120 | gpuSetTexture(gpu_unai.GPU_GP1); | |
121 | } | |
122 | } break; | |
123 | ||
124 | case 3: { | |
125 | // GP0(E3h) - Set Drawing Area top left (X1,Y1) | |
126 | DO_LOG(("GP0(0xE3) DrawingArea Pos(0x%x)\n", cmd_word)); | |
127 | gpu_unai.DrawingArea[0] = cmd_word & 0x3FF; | |
128 | gpu_unai.DrawingArea[1] = (cmd_word >> 10) & 0x3FF; | |
129 | } break; | |
130 | ||
131 | case 4: { | |
132 | // GP0(E4h) - Set Drawing Area bottom right (X2,Y2) | |
133 | DO_LOG(("GP0(0xE4) DrawingArea Size(0x%x)\n", cmd_word)); | |
134 | gpu_unai.DrawingArea[2] = (cmd_word & 0x3FF) + 1; | |
135 | gpu_unai.DrawingArea[3] = ((cmd_word >> 10) & 0x3FF) + 1; | |
136 | } break; | |
137 | ||
138 | case 5: { | |
139 | // GP0(E5h) - Set Drawing Offset (X,Y) | |
140 | DO_LOG(("GP0(0xE5) DrawingOffset(0x%x)\n", cmd_word)); | |
141 | gpu_unai.DrawingOffset[0] = ((s32)cmd_word<<(32-11))>>(32-11); | |
142 | gpu_unai.DrawingOffset[1] = ((s32)cmd_word<<(32-22))>>(32-11); | |
143 | } break; | |
144 | ||
145 | case 6: { | |
146 | // GP0(E6h) - Mask Bit Setting | |
147 | DO_LOG(("GP0(0xE6) SetMask(0x%x)\n", cmd_word)); | |
148 | gpu_unai.Masking = (cmd_word & 0x2) << 1; | |
149 | gpu_unai.PixelMSB = (cmd_word & 0x1) << 8; | |
150 | } break; | |
151 | } | |
152 | } | |
86aad47b | 153 | |
154 | void gpuSendPacketFunction(const int PRIM) | |
155 | { | |
156 | //printf("0x%x\n",PRIM); | |
157 | ||
030d1121 | 158 | //senquack - TODO: optimize this (packet pointer union as prim draw parameter |
159 | // introduced as optimization for gpulib command-list processing) | |
160 | PtrUnion packet = { .ptr = (void*)&gpu_unai.PacketBuffer }; | |
161 | ||
86aad47b | 162 | switch (PRIM) |
163 | { | |
030d1121 | 164 | case 0x02: { |
86aad47b | 165 | NULL_GPU(); |
030d1121 | 166 | gpuClearImage(packet); // prim handles updateLace && skip |
167 | gpu_unai.fb_dirty = true; | |
86aad47b | 168 | DO_LOG(("gpuClearImage(0x%x)\n",PRIM)); |
030d1121 | 169 | } break; |
170 | ||
86aad47b | 171 | case 0x20: |
172 | case 0x21: | |
173 | case 0x22: | |
030d1121 | 174 | case 0x23: { // Monochrome 3-pt poly |
175 | if (!gpu_unai.frameskip.skipGPU) | |
86aad47b | 176 | { |
177 | NULL_GPU(); | |
030d1121 | 178 | PP driver = gpuPolySpanDrivers[ |
179 | (gpu_unai.blit_mask?1024:0) | | |
180 | Blending_Mode | | |
181 | gpu_unai.Masking | Blending | gpu_unai.PixelMSB | |
182 | ]; | |
183 | gpuDrawPolyF(packet, driver, false); | |
184 | gpu_unai.fb_dirty = true; | |
185 | DO_LOG(("gpuDrawPolyF(0x%x)\n",PRIM)); | |
86aad47b | 186 | } |
030d1121 | 187 | } break; |
188 | ||
86aad47b | 189 | case 0x24: |
190 | case 0x25: | |
191 | case 0x26: | |
030d1121 | 192 | case 0x27: { // Textured 3-pt poly |
193 | if (!gpu_unai.frameskip.skipGPU) | |
86aad47b | 194 | { |
195 | NULL_GPU(); | |
4949d4ff PC |
196 | gpuSetCLUT (le32_to_u32(gpu_unai.PacketBuffer.U4[2]) >> 16); |
197 | gpuSetTexture (le32_to_u32(gpu_unai.PacketBuffer.U4[4]) >> 16); | |
030d1121 | 198 | |
199 | u32 driver_idx = | |
200 | (gpu_unai.blit_mask?1024:0) | | |
201 | Dithering | | |
202 | Blending_Mode | gpu_unai.TEXT_MODE | | |
203 | gpu_unai.Masking | Blending | gpu_unai.PixelMSB; | |
204 | ||
205 | if (!FastLightingEnabled()) { | |
206 | driver_idx |= Lighting; | |
207 | } else { | |
208 | if (!((gpu_unai.PacketBuffer.U1[0]>0x5F) && (gpu_unai.PacketBuffer.U1[1]>0x5F) && (gpu_unai.PacketBuffer.U1[2]>0x5F))) | |
209 | driver_idx |= Lighting; | |
210 | } | |
211 | ||
212 | PP driver = gpuPolySpanDrivers[driver_idx]; | |
213 | gpuDrawPolyFT(packet, driver, false); | |
214 | gpu_unai.fb_dirty = true; | |
215 | DO_LOG(("gpuDrawPolyFT(0x%x)\n",PRIM)); | |
86aad47b | 216 | } |
030d1121 | 217 | } break; |
218 | ||
86aad47b | 219 | case 0x28: |
220 | case 0x29: | |
221 | case 0x2A: | |
030d1121 | 222 | case 0x2B: { // Monochrome 4-pt poly |
223 | if (!gpu_unai.frameskip.skipGPU) | |
86aad47b | 224 | { |
225 | NULL_GPU(); | |
030d1121 | 226 | PP driver = gpuPolySpanDrivers[ |
227 | (gpu_unai.blit_mask?1024:0) | | |
228 | Blending_Mode | | |
229 | gpu_unai.Masking | Blending | gpu_unai.PixelMSB | |
230 | ]; | |
231 | gpuDrawPolyF(packet, driver, true); // is_quad = true | |
232 | gpu_unai.fb_dirty = true; | |
233 | DO_LOG(("gpuDrawPolyF(0x%x) (4-pt QUAD)\n",PRIM)); | |
86aad47b | 234 | } |
030d1121 | 235 | } break; |
236 | ||
86aad47b | 237 | case 0x2C: |
238 | case 0x2D: | |
239 | case 0x2E: | |
030d1121 | 240 | case 0x2F: { // Textured 4-pt poly |
241 | if (!gpu_unai.frameskip.skipGPU) | |
86aad47b | 242 | { |
243 | NULL_GPU(); | |
4949d4ff PC |
244 | gpuSetCLUT (le32_to_u32(gpu_unai.PacketBuffer.U4[2]) >> 16); |
245 | gpuSetTexture (le32_to_u32(gpu_unai.PacketBuffer.U4[4]) >> 16); | |
030d1121 | 246 | |
247 | u32 driver_idx = | |
248 | (gpu_unai.blit_mask?1024:0) | | |
249 | Dithering | | |
250 | Blending_Mode | gpu_unai.TEXT_MODE | | |
251 | gpu_unai.Masking | Blending | gpu_unai.PixelMSB; | |
252 | ||
253 | if (!FastLightingEnabled()) { | |
254 | driver_idx |= Lighting; | |
255 | } else { | |
256 | if (!((gpu_unai.PacketBuffer.U1[0]>0x5F) && (gpu_unai.PacketBuffer.U1[1]>0x5F) && (gpu_unai.PacketBuffer.U1[2]>0x5F))) | |
257 | driver_idx |= Lighting; | |
258 | } | |
259 | ||
260 | PP driver = gpuPolySpanDrivers[driver_idx]; | |
261 | gpuDrawPolyFT(packet, driver, true); // is_quad = true | |
262 | gpu_unai.fb_dirty = true; | |
263 | DO_LOG(("gpuDrawPolyFT(0x%x) (4-pt QUAD)\n",PRIM)); | |
86aad47b | 264 | } |
030d1121 | 265 | } break; |
266 | ||
86aad47b | 267 | case 0x30: |
268 | case 0x31: | |
269 | case 0x32: | |
030d1121 | 270 | case 0x33: { // Gouraud-shaded 3-pt poly |
271 | if (!gpu_unai.frameskip.skipGPU) | |
86aad47b | 272 | { |
273 | NULL_GPU(); | |
030d1121 | 274 | //NOTE: The '129' here is CF_GOURAUD | CF_LIGHT, however |
275 | // this is an untextured poly, so CF_LIGHT (texture blend) | |
276 | // shouldn't apply. Until the original array of template | |
277 | // instantiation ptrs is fixed, we're stuck with this. (TODO) | |
278 | PP driver = gpuPolySpanDrivers[ | |
279 | (gpu_unai.blit_mask?1024:0) | | |
280 | Dithering | | |
281 | Blending_Mode | | |
282 | gpu_unai.Masking | Blending | 129 | gpu_unai.PixelMSB | |
283 | ]; | |
284 | gpuDrawPolyG(packet, driver, false); | |
285 | gpu_unai.fb_dirty = true; | |
286 | DO_LOG(("gpuDrawPolyG(0x%x)\n",PRIM)); | |
86aad47b | 287 | } |
030d1121 | 288 | } break; |
289 | ||
86aad47b | 290 | case 0x34: |
291 | case 0x35: | |
292 | case 0x36: | |
030d1121 | 293 | case 0x37: { // Gouraud-shaded, textured 3-pt poly |
294 | if (!gpu_unai.frameskip.skipGPU) | |
86aad47b | 295 | { |
296 | NULL_GPU(); | |
4949d4ff PC |
297 | gpuSetCLUT (le32_to_u32(gpu_unai.PacketBuffer.U4[2]) >> 16); |
298 | gpuSetTexture (le32_to_u32(gpu_unai.PacketBuffer.U4[5]) >> 16); | |
030d1121 | 299 | PP driver = gpuPolySpanDrivers[ |
300 | (gpu_unai.blit_mask?1024:0) | | |
301 | Dithering | | |
302 | Blending_Mode | gpu_unai.TEXT_MODE | | |
303 | gpu_unai.Masking | Blending | ((Lighting)?129:0) | gpu_unai.PixelMSB | |
304 | ]; | |
305 | gpuDrawPolyGT(packet, driver, false); | |
306 | gpu_unai.fb_dirty = true; | |
307 | DO_LOG(("gpuDrawPolyGT(0x%x)\n",PRIM)); | |
86aad47b | 308 | } |
030d1121 | 309 | } break; |
310 | ||
86aad47b | 311 | case 0x38: |
312 | case 0x39: | |
313 | case 0x3A: | |
030d1121 | 314 | case 0x3B: { // Gouraud-shaded 4-pt poly |
315 | if (!gpu_unai.frameskip.skipGPU) | |
86aad47b | 316 | { |
317 | NULL_GPU(); | |
030d1121 | 318 | // See notes regarding '129' for 0x30..0x33 further above -senquack |
319 | PP driver = gpuPolySpanDrivers[ | |
320 | (gpu_unai.blit_mask?1024:0) | | |
321 | Dithering | | |
322 | Blending_Mode | | |
323 | gpu_unai.Masking | Blending | 129 | gpu_unai.PixelMSB | |
324 | ]; | |
325 | gpuDrawPolyG(packet, driver, true); // is_quad = true | |
326 | gpu_unai.fb_dirty = true; | |
327 | DO_LOG(("gpuDrawPolyG(0x%x) (4-pt QUAD)\n",PRIM)); | |
86aad47b | 328 | } |
030d1121 | 329 | } break; |
330 | ||
86aad47b | 331 | case 0x3C: |
332 | case 0x3D: | |
333 | case 0x3E: | |
030d1121 | 334 | case 0x3F: { // Gouraud-shaded, textured 4-pt poly |
335 | if (!gpu_unai.frameskip.skipGPU) | |
86aad47b | 336 | { |
337 | NULL_GPU(); | |
4949d4ff PC |
338 | gpuSetCLUT (le32_to_u32(gpu_unai.PacketBuffer.U4[2]) >> 16); |
339 | gpuSetTexture (le32_to_u32(gpu_unai.PacketBuffer.U4[5]) >> 16); | |
030d1121 | 340 | PP driver = gpuPolySpanDrivers[ |
341 | (gpu_unai.blit_mask?1024:0) | | |
342 | Dithering | | |
343 | Blending_Mode | gpu_unai.TEXT_MODE | | |
344 | gpu_unai.Masking | Blending | ((Lighting)?129:0) | gpu_unai.PixelMSB | |
345 | ]; | |
346 | gpuDrawPolyGT(packet, driver, true); // is_quad = true | |
347 | gpu_unai.fb_dirty = true; | |
348 | DO_LOG(("gpuDrawPolyGT(0x%x) (4-pt QUAD)\n",PRIM)); | |
86aad47b | 349 | } |
030d1121 | 350 | } break; |
351 | ||
86aad47b | 352 | case 0x40: |
353 | case 0x41: | |
354 | case 0x42: | |
030d1121 | 355 | case 0x43: { // Monochrome line |
356 | if (!gpu_unai.frameskip.skipGPU) | |
86aad47b | 357 | { |
358 | NULL_GPU(); | |
030d1121 | 359 | // Shift index right by one, as untextured prims don't use lighting |
360 | u32 driver_idx = (Blending_Mode | gpu_unai.Masking | Blending | (gpu_unai.PixelMSB>>3)) >> 1; | |
361 | PSD driver = gpuPixelSpanDrivers[driver_idx]; | |
362 | gpuDrawLineF(packet, driver); | |
363 | gpu_unai.fb_dirty = true; | |
364 | DO_LOG(("gpuDrawLineF(0x%x)\n",PRIM)); | |
86aad47b | 365 | } |
030d1121 | 366 | } break; |
367 | ||
86aad47b | 368 | case 0x48: |
369 | case 0x49: | |
370 | case 0x4A: | |
371 | case 0x4B: | |
372 | case 0x4C: | |
373 | case 0x4D: | |
374 | case 0x4E: | |
030d1121 | 375 | case 0x4F: { // Monochrome line strip |
376 | if (!gpu_unai.frameskip.skipGPU) | |
86aad47b | 377 | { |
378 | NULL_GPU(); | |
030d1121 | 379 | // Shift index right by one, as untextured prims don't use lighting |
380 | u32 driver_idx = (Blending_Mode | gpu_unai.Masking | Blending | (gpu_unai.PixelMSB>>3)) >> 1; | |
381 | PSD driver = gpuPixelSpanDrivers[driver_idx]; | |
382 | gpuDrawLineF(packet, driver); | |
383 | gpu_unai.fb_dirty = true; | |
384 | DO_LOG(("gpuDrawLineF(0x%x)\n",PRIM)); | |
86aad47b | 385 | } |
4949d4ff | 386 | if ((le32_raw(gpu_unai.PacketBuffer.U4[3]) & HTOLE32(0xF000F000)) != HTOLE32(0x50005000)) |
86aad47b | 387 | { |
030d1121 | 388 | gpu_unai.PacketBuffer.U4[1] = gpu_unai.PacketBuffer.U4[2]; |
389 | gpu_unai.PacketBuffer.U4[2] = gpu_unai.PacketBuffer.U4[3]; | |
390 | gpu_unai.PacketCount = 1; | |
391 | gpu_unai.PacketIndex = 3; | |
86aad47b | 392 | } |
030d1121 | 393 | } break; |
394 | ||
86aad47b | 395 | case 0x50: |
396 | case 0x51: | |
397 | case 0x52: | |
030d1121 | 398 | case 0x53: { // Gouraud-shaded line |
399 | if (!gpu_unai.frameskip.skipGPU) | |
86aad47b | 400 | { |
401 | NULL_GPU(); | |
030d1121 | 402 | // Shift index right by one, as untextured prims don't use lighting |
403 | u32 driver_idx = (Blending_Mode | gpu_unai.Masking | Blending | (gpu_unai.PixelMSB>>3)) >> 1; | |
404 | // Index MSB selects Gouraud-shaded PixelSpanDriver: | |
405 | driver_idx |= (1 << 5); | |
406 | PSD driver = gpuPixelSpanDrivers[driver_idx]; | |
407 | gpuDrawLineG(packet, driver); | |
408 | gpu_unai.fb_dirty = true; | |
409 | DO_LOG(("gpuDrawLineG(0x%x)\n",PRIM)); | |
86aad47b | 410 | } |
030d1121 | 411 | } break; |
412 | ||
86aad47b | 413 | case 0x58: |
414 | case 0x59: | |
415 | case 0x5A: | |
416 | case 0x5B: | |
417 | case 0x5C: | |
418 | case 0x5D: | |
419 | case 0x5E: | |
030d1121 | 420 | case 0x5F: { // Gouraud-shaded line strip |
421 | if (!gpu_unai.frameskip.skipGPU) | |
86aad47b | 422 | { |
423 | NULL_GPU(); | |
030d1121 | 424 | // Shift index right by one, as untextured prims don't use lighting |
425 | u32 driver_idx = (Blending_Mode | gpu_unai.Masking | Blending | (gpu_unai.PixelMSB>>3)) >> 1; | |
426 | // Index MSB selects Gouraud-shaded PixelSpanDriver: | |
427 | driver_idx |= (1 << 5); | |
428 | PSD driver = gpuPixelSpanDrivers[driver_idx]; | |
429 | gpuDrawLineG(packet, driver); | |
430 | gpu_unai.fb_dirty = true; | |
431 | DO_LOG(("gpuDrawLineG(0x%x)\n",PRIM)); | |
86aad47b | 432 | } |
4949d4ff | 433 | if ((le32_raw(gpu_unai.PacketBuffer.U4[4]) & HTOLE32(0xF000F000)) != HTOLE32(0x50005000)) |
86aad47b | 434 | { |
030d1121 | 435 | gpu_unai.PacketBuffer.U1[3 + (2 * 4)] = gpu_unai.PacketBuffer.U1[3 + (0 * 4)]; |
436 | gpu_unai.PacketBuffer.U4[0] = gpu_unai.PacketBuffer.U4[2]; | |
437 | gpu_unai.PacketBuffer.U4[1] = gpu_unai.PacketBuffer.U4[3]; | |
438 | gpu_unai.PacketBuffer.U4[2] = gpu_unai.PacketBuffer.U4[4]; | |
439 | gpu_unai.PacketCount = 2; | |
440 | gpu_unai.PacketIndex = 3; | |
86aad47b | 441 | } |
030d1121 | 442 | } break; |
443 | ||
86aad47b | 444 | case 0x60: |
445 | case 0x61: | |
446 | case 0x62: | |
030d1121 | 447 | case 0x63: { // Monochrome rectangle (variable size) |
448 | if (!gpu_unai.frameskip.skipGPU) | |
86aad47b | 449 | { |
450 | NULL_GPU(); | |
030d1121 | 451 | PT driver = gpuTileSpanDrivers[(Blending_Mode | gpu_unai.Masking | Blending | (gpu_unai.PixelMSB>>3)) >> 1]; |
452 | gpuDrawT(packet, driver); | |
453 | gpu_unai.fb_dirty = true; | |
86aad47b | 454 | DO_LOG(("gpuDrawT(0x%x)\n",PRIM)); |
455 | } | |
030d1121 | 456 | } break; |
457 | ||
86aad47b | 458 | case 0x64: |
459 | case 0x65: | |
460 | case 0x66: | |
030d1121 | 461 | case 0x67: { // Textured rectangle (variable size) |
462 | if (!gpu_unai.frameskip.skipGPU) | |
86aad47b | 463 | { |
464 | NULL_GPU(); | |
4949d4ff | 465 | gpuSetCLUT (le32_to_u32(gpu_unai.PacketBuffer.U4[2]) >> 16); |
030d1121 | 466 | u32 driver_idx = Blending_Mode | gpu_unai.TEXT_MODE | gpu_unai.Masking | Blending | (gpu_unai.PixelMSB>>1); |
467 | ||
468 | // This fixes Silent Hill running animation on loading screens: | |
469 | // (On PSX, color values 0x00-0x7F darken the source texture's color, | |
470 | // 0x81-FF lighten textures (ultimately clamped to 0x1F), | |
471 | // 0x80 leaves source texture color unchanged, HOWEVER, | |
472 | // gpu_unai uses a simple lighting LUT whereby only the upper | |
473 | // 5 bits of an 8-bit color are used, so 0x80-0x87 all behave as | |
474 | // 0x80. | |
475 | // | |
476 | // NOTE: I've changed all textured sprite draw commands here and | |
477 | // elsewhere to use proper behavior, but left poly commands | |
478 | // alone, I don't want to slow rendering down too much. (TODO) | |
479 | //if ((gpu_unai.PacketBuffer.U1[0]>0x5F) && (gpu_unai.PacketBuffer.U1[1]>0x5F) && (gpu_unai.PacketBuffer.U1[2]>0x5F)) | |
480 | // Strip lower 3 bits of each color and determine if lighting should be used: | |
4949d4ff | 481 | if ((le32_raw(gpu_unai.PacketBuffer.U4[0]) & HTOLE32(0xF8F8F8)) != HTOLE32(0x808080)) |
030d1121 | 482 | driver_idx |= Lighting; |
483 | PS driver = gpuSpriteSpanDrivers[driver_idx]; | |
484 | gpuDrawS(packet, driver); | |
485 | gpu_unai.fb_dirty = true; | |
86aad47b | 486 | DO_LOG(("gpuDrawS(0x%x)\n",PRIM)); |
487 | } | |
030d1121 | 488 | } break; |
489 | ||
86aad47b | 490 | case 0x68: |
491 | case 0x69: | |
492 | case 0x6A: | |
030d1121 | 493 | case 0x6B: { // Monochrome rectangle (1x1 dot) |
494 | if (!gpu_unai.frameskip.skipGPU) | |
86aad47b | 495 | { |
496 | NULL_GPU(); | |
4949d4ff | 497 | gpu_unai.PacketBuffer.U4[2] = u32_to_le32(0x00010001); |
030d1121 | 498 | PT driver = gpuTileSpanDrivers[(Blending_Mode | gpu_unai.Masking | Blending | (gpu_unai.PixelMSB>>3)) >> 1]; |
499 | gpuDrawT(packet, driver); | |
500 | gpu_unai.fb_dirty = true; | |
86aad47b | 501 | DO_LOG(("gpuDrawT(0x%x)\n",PRIM)); |
502 | } | |
030d1121 | 503 | } break; |
504 | ||
86aad47b | 505 | case 0x70: |
506 | case 0x71: | |
507 | case 0x72: | |
030d1121 | 508 | case 0x73: { // Monochrome rectangle (8x8) |
509 | if (!gpu_unai.frameskip.skipGPU) | |
86aad47b | 510 | { |
511 | NULL_GPU(); | |
4949d4ff | 512 | gpu_unai.PacketBuffer.U4[2] = u32_to_le32(0x00080008); |
030d1121 | 513 | PT driver = gpuTileSpanDrivers[(Blending_Mode | gpu_unai.Masking | Blending | (gpu_unai.PixelMSB>>3)) >> 1]; |
514 | gpuDrawT(packet, driver); | |
515 | gpu_unai.fb_dirty = true; | |
86aad47b | 516 | DO_LOG(("gpuDrawT(0x%x)\n",PRIM)); |
517 | } | |
030d1121 | 518 | } break; |
519 | ||
86aad47b | 520 | case 0x74: |
521 | case 0x75: | |
522 | case 0x76: | |
030d1121 | 523 | case 0x77: { // Textured rectangle (8x8) |
524 | if (!gpu_unai.frameskip.skipGPU) | |
86aad47b | 525 | { |
526 | NULL_GPU(); | |
4949d4ff PC |
527 | gpu_unai.PacketBuffer.U4[3] = u32_to_le32(0x00080008); |
528 | gpuSetCLUT (le32_to_u32(gpu_unai.PacketBuffer.U4[2]) >> 16); | |
030d1121 | 529 | u32 driver_idx = Blending_Mode | gpu_unai.TEXT_MODE | gpu_unai.Masking | Blending | (gpu_unai.PixelMSB>>1); |
530 | ||
531 | //senquack - Only color 808080h-878787h allows skipping lighting calculation: | |
532 | //if ((gpu_unai.PacketBuffer.U1[0]>0x5F) && (gpu_unai.PacketBuffer.U1[1]>0x5F) && (gpu_unai.PacketBuffer.U1[2]>0x5F)) | |
533 | // Strip lower 3 bits of each color and determine if lighting should be used: | |
4949d4ff | 534 | if ((le32_raw(gpu_unai.PacketBuffer.U4[0]) & HTOLE32(0xF8F8F8)) != HTOLE32(0x808080)) |
030d1121 | 535 | driver_idx |= Lighting; |
536 | PS driver = gpuSpriteSpanDrivers[driver_idx]; | |
537 | gpuDrawS(packet, driver); | |
538 | gpu_unai.fb_dirty = true; | |
86aad47b | 539 | DO_LOG(("gpuDrawS(0x%x)\n",PRIM)); |
540 | } | |
030d1121 | 541 | } break; |
542 | ||
86aad47b | 543 | case 0x78: |
544 | case 0x79: | |
545 | case 0x7A: | |
030d1121 | 546 | case 0x7B: { // Monochrome rectangle (16x16) |
547 | if (!gpu_unai.frameskip.skipGPU) | |
86aad47b | 548 | { |
549 | NULL_GPU(); | |
4949d4ff | 550 | gpu_unai.PacketBuffer.U4[2] = u32_to_le32(0x00100010); |
030d1121 | 551 | PT driver = gpuTileSpanDrivers[(Blending_Mode | gpu_unai.Masking | Blending | (gpu_unai.PixelMSB>>3)) >> 1]; |
552 | gpuDrawT(packet, driver); | |
553 | gpu_unai.fb_dirty = true; | |
86aad47b | 554 | DO_LOG(("gpuDrawT(0x%x)\n",PRIM)); |
555 | } | |
030d1121 | 556 | } break; |
557 | ||
86aad47b | 558 | case 0x7C: |
559 | case 0x7D: | |
030d1121 | 560 | #ifdef __arm__ |
561 | /* Notaz 4bit sprites optimization */ | |
562 | if ((!gpu_unai.frameskip.skipGPU) && (!(gpu_unai.GPU_GP1&0x180)) && (!(gpu_unai.Masking|gpu_unai.PixelMSB))) | |
b3db9409 | 563 | { |
4949d4ff | 564 | gpuSetCLUT (le32_to_u32(gpu_unai.PacketBuffer.U4[2]) >> 16); |
030d1121 | 565 | gpuDrawS16(packet); |
566 | gpu_unai.fb_dirty = true; | |
b3db9409 | 567 | break; |
568 | } | |
030d1121 | 569 | #endif |
86aad47b | 570 | case 0x7E: |
030d1121 | 571 | case 0x7F: { // Textured rectangle (16x16) |
572 | if (!gpu_unai.frameskip.skipGPU) | |
86aad47b | 573 | { |
574 | NULL_GPU(); | |
4949d4ff PC |
575 | gpu_unai.PacketBuffer.U4[3] = u32_to_le32(0x00100010); |
576 | gpuSetCLUT (le32_to_u32(gpu_unai.PacketBuffer.U4[2]) >> 16); | |
030d1121 | 577 | u32 driver_idx = Blending_Mode | gpu_unai.TEXT_MODE | gpu_unai.Masking | Blending | (gpu_unai.PixelMSB>>1); |
578 | ||
579 | //senquack - Only color 808080h-878787h allows skipping lighting calculation: | |
580 | //if ((gpu_unai.PacketBuffer.U1[0]>0x5F) && (gpu_unai.PacketBuffer.U1[1]>0x5F) && (gpu_unai.PacketBuffer.U1[2]>0x5F)) | |
581 | // Strip lower 3 bits of each color and determine if lighting should be used: | |
4949d4ff | 582 | if ((le32_raw(gpu_unai.PacketBuffer.U4[0]) & HTOLE32(0xF8F8F8)) != HTOLE32(0x808080)) |
030d1121 | 583 | driver_idx |= Lighting; |
584 | PS driver = gpuSpriteSpanDrivers[driver_idx]; | |
585 | gpuDrawS(packet, driver); | |
586 | gpu_unai.fb_dirty = true; | |
86aad47b | 587 | DO_LOG(("gpuDrawS(0x%x)\n",PRIM)); |
588 | } | |
030d1121 | 589 | } break; |
590 | ||
86aad47b | 591 | case 0x80: // vid -> vid |
030d1121 | 592 | gpuMoveImage(packet); // prim handles updateLace && skip |
593 | if ((!gpu_unai.frameskip.skipCount) && (gpu_unai.DisplayArea[3] == 480)) // Tekken 3 hack | |
594 | { | |
595 | if (!gpu_unai.frameskip.skipGPU) gpu_unai.fb_dirty = true; | |
596 | } | |
597 | else | |
598 | { | |
599 | gpu_unai.fb_dirty = true; | |
600 | } | |
86aad47b | 601 | DO_LOG(("gpuMoveImage(0x%x)\n",PRIM)); |
602 | break; | |
603 | case 0xA0: // sys ->vid | |
030d1121 | 604 | gpuLoadImage(packet); // prim handles updateLace && skip |
86aad47b | 605 | DO_LOG(("gpuLoadImage(0x%x)\n",PRIM)); |
606 | break; | |
607 | case 0xC0: // vid -> sys | |
030d1121 | 608 | gpuStoreImage(packet); // prim handles updateLace && skip |
86aad47b | 609 | DO_LOG(("gpuStoreImage(0x%x)\n",PRIM)); |
610 | break; | |
030d1121 | 611 | case 0xE1 ... 0xE6: { // Draw settings |
4949d4ff | 612 | gpuGP0Cmd_0xEx(gpu_unai, le32_to_u32(gpu_unai.PacketBuffer.U4[0])); |
030d1121 | 613 | } break; |
86aad47b | 614 | } |
615 | } | |
030d1121 | 616 | #endif //!USE_GPULIB |
617 | /////////////////////////////////////////////////////////////////////////////// | |
618 | // End of code specific to non-gpulib standalone version of gpu_unai | |
619 | /////////////////////////////////////////////////////////////////////////////// | |
908e426c | 620 | |
621 | #endif /* __GPU_UNAI_GPU_COMMAND_H__ */ |