gpu: improve timings of clipped sprites
[pcsx_rearmed.git] / plugins / gpu_unai / gpu_command.h
CommitLineData
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 26void 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///////////////////////////////////////////////////////////////////////////////
52INLINE 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
83static 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
154void 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__ */