1 /***************************************************************************
2 * Copyright (C) 2010 PCSX4ALL Team *
3 * Copyright (C) 2010 Unai *
4 * Copyright (C) 2016 Senquack (dansilsby <AT> gmail <DOT> com) *
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. *
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. *
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 ***************************************************************************/
22 ///////////////////////////////////////////////////////////////////////////////
23 void gpuSetTexture(u16 tpage)
26 gpu_unai.GPU_GP1 = (gpu_unai.GPU_GP1 & ~0x1FF) | (tpage & 0x1FF);
27 gpu_unai.TextureWindow[0]&= ~gpu_unai.TextureWindow[2];
28 gpu_unai.TextureWindow[1]&= ~gpu_unai.TextureWindow[3];
30 tmode = (tpage >> 7) & 3; // 16bpp, 8bpp, or 4bpp texture colors?
31 // 0: 4bpp 1: 8bpp 2/3: 16bpp
33 // Nocash PSX docs state setting of 3 is same as setting of 2 (16bpp):
34 // Note: DrHell assumes 3 is same as 0.. TODO: verify which is correct?
35 if (tmode == 3) tmode = 2;
37 tx = (tpage & 0x0F) << 6;
38 ty = (tpage & 0x10) << 4;
40 tx += (gpu_unai.TextureWindow[0] >> (2 - tmode));
41 ty += gpu_unai.TextureWindow[1];
43 gpu_unai.BLEND_MODE = ((tpage>>5) & 3) << 3;
44 gpu_unai.TEXT_MODE = (tmode + 1) << 5; // gpu_unai.TEXT_MODE should be values 1..3, so add one
45 gpu_unai.TBA = &((u16*)gpu_unai.vram)[FRAME_OFFSET(tx, ty)];
48 ///////////////////////////////////////////////////////////////////////////////
49 INLINE void gpuSetCLUT(u16 clut)
51 gpu_unai.CBA = &((u16*)gpu_unai.vram)[(clut & 0x7FFF) << 4];
54 #ifdef ENABLE_GPU_NULL_SUPPORT
55 #define NULL_GPU() break
60 #ifdef ENABLE_GPU_LOG_SUPPORT
61 #define DO_LOG(expr) printf expr
63 #define DO_LOG(expr) {}
66 #define Blending (((PRIM&0x2) && BlendingEnabled()) ? (PRIM&0x2) : 0)
67 #define Blending_Mode (((PRIM&0x2) && BlendingEnabled()) ? gpu_unai.BLEND_MODE : 0)
68 #define Lighting (((~PRIM)&0x1) && LightingEnabled())
69 // Dithering applies only to Gouraud-shaded polys or texture-blended polys:
70 #define Dithering (((((~PRIM)&0x1) || (PRIM&0x10)) && DitheringEnabled()) ? \
71 (ForcedDitheringEnabled() ? (1<<9) : (gpu_unai.GPU_GP1 & (1 << 9))) \
74 ///////////////////////////////////////////////////////////////////////////////
75 //Now handled by Rearmed's gpulib and gpu_unai/gpulib_if.cpp:
76 ///////////////////////////////////////////////////////////////////////////////
79 // Handles GP0 draw settings commands 0xE1...0xE6
80 static void gpuGP0Cmd_0xEx(gpu_unai_t &gpu_unai, u32 cmd_word)
82 // Assume incoming GP0 command is 0xE1..0xE6, convert to 1..6
83 u8 num = (cmd_word >> 24) & 7;
86 // GP0(E1h) - Draw Mode setting (aka "Texpage")
87 DO_LOG(("GP0(0xE1) DrawMode TexPage(0x%x)\n", cmd_word));
88 u32 cur_texpage = gpu_unai.GPU_GP1 & 0x7FF;
89 u32 new_texpage = cmd_word & 0x7FF;
90 if (cur_texpage != new_texpage) {
91 gpu_unai.GPU_GP1 = (gpu_unai.GPU_GP1 & ~0x7FF) | new_texpage;
92 gpuSetTexture(gpu_unai.GPU_GP1);
97 // GP0(E2h) - Texture Window setting
98 DO_LOG(("GP0(0xE2) TextureWindow(0x%x)\n", cmd_word));
99 if (cmd_word != gpu_unai.TextureWindowCur) {
100 static const u8 TextureMask[32] = {
101 255, 7, 15, 7, 31, 7, 15, 7, 63, 7, 15, 7, 31, 7, 15, 7,
102 127, 7, 15, 7, 31, 7, 15, 7, 63, 7, 15, 7, 31, 7, 15, 7
104 gpu_unai.TextureWindowCur = cmd_word;
105 gpu_unai.TextureWindow[0] = ((cmd_word >> 10) & 0x1F) << 3;
106 gpu_unai.TextureWindow[1] = ((cmd_word >> 15) & 0x1F) << 3;
107 gpu_unai.TextureWindow[2] = TextureMask[(cmd_word >> 0) & 0x1F];
108 gpu_unai.TextureWindow[3] = TextureMask[(cmd_word >> 5) & 0x1F];
109 gpu_unai.TextureWindow[0] &= ~gpu_unai.TextureWindow[2];
110 gpu_unai.TextureWindow[1] &= ~gpu_unai.TextureWindow[3];
112 // Inner loop vars must be updated whenever texture window is changed:
113 const u32 fb = FIXED_BITS; // # of fractional fixed-pt bits of u4/v4
114 gpu_unai.u_msk = (((u32)gpu_unai.TextureWindow[2]) << fb) | ((1 << fb) - 1);
115 gpu_unai.v_msk = (((u32)gpu_unai.TextureWindow[3]) << fb) | ((1 << fb) - 1);
117 gpuSetTexture(gpu_unai.GPU_GP1);
122 // GP0(E3h) - Set Drawing Area top left (X1,Y1)
123 DO_LOG(("GP0(0xE3) DrawingArea Pos(0x%x)\n", cmd_word));
124 gpu_unai.DrawingArea[0] = cmd_word & 0x3FF;
125 gpu_unai.DrawingArea[1] = (cmd_word >> 10) & 0x3FF;
129 // GP0(E4h) - Set Drawing Area bottom right (X2,Y2)
130 DO_LOG(("GP0(0xE4) DrawingArea Size(0x%x)\n", cmd_word));
131 gpu_unai.DrawingArea[2] = (cmd_word & 0x3FF) + 1;
132 gpu_unai.DrawingArea[3] = ((cmd_word >> 10) & 0x3FF) + 1;
136 // GP0(E5h) - Set Drawing Offset (X,Y)
137 DO_LOG(("GP0(0xE5) DrawingOffset(0x%x)\n", cmd_word));
138 gpu_unai.DrawingOffset[0] = ((s32)cmd_word<<(32-11))>>(32-11);
139 gpu_unai.DrawingOffset[1] = ((s32)cmd_word<<(32-22))>>(32-11);
143 // GP0(E6h) - Mask Bit Setting
144 DO_LOG(("GP0(0xE6) SetMask(0x%x)\n", cmd_word));
145 gpu_unai.Masking = (cmd_word & 0x2) << 1;
146 gpu_unai.PixelMSB = (cmd_word & 0x1) << 8;
151 void gpuSendPacketFunction(const int PRIM)
153 //printf("0x%x\n",PRIM);
155 //senquack - TODO: optimize this (packet pointer union as prim draw parameter
156 // introduced as optimization for gpulib command-list processing)
157 PtrUnion packet = { .ptr = (void*)&gpu_unai.PacketBuffer };
163 gpuClearImage(packet); // prim handles updateLace && skip
164 gpu_unai.fb_dirty = true;
165 DO_LOG(("gpuClearImage(0x%x)\n",PRIM));
171 case 0x23: { // Monochrome 3-pt poly
172 if (!gpu_unai.frameskip.skipGPU)
175 PP driver = gpuPolySpanDrivers[
176 (gpu_unai.blit_mask?1024:0) |
178 gpu_unai.Masking | Blending | gpu_unai.PixelMSB
180 gpuDrawPolyF(packet, driver, false);
181 gpu_unai.fb_dirty = true;
182 DO_LOG(("gpuDrawPolyF(0x%x)\n",PRIM));
189 case 0x27: { // Textured 3-pt poly
190 if (!gpu_unai.frameskip.skipGPU)
193 gpuSetCLUT (gpu_unai.PacketBuffer.U4[2] >> 16);
194 gpuSetTexture (gpu_unai.PacketBuffer.U4[4] >> 16);
197 (gpu_unai.blit_mask?1024:0) |
199 Blending_Mode | gpu_unai.TEXT_MODE |
200 gpu_unai.Masking | Blending | gpu_unai.PixelMSB;
202 if (!FastLightingEnabled()) {
203 driver_idx |= Lighting;
205 if (!((gpu_unai.PacketBuffer.U1[0]>0x5F) && (gpu_unai.PacketBuffer.U1[1]>0x5F) && (gpu_unai.PacketBuffer.U1[2]>0x5F)))
206 driver_idx |= Lighting;
209 PP driver = gpuPolySpanDrivers[driver_idx];
210 gpuDrawPolyFT(packet, driver, false);
211 gpu_unai.fb_dirty = true;
212 DO_LOG(("gpuDrawPolyFT(0x%x)\n",PRIM));
219 case 0x2B: { // Monochrome 4-pt poly
220 if (!gpu_unai.frameskip.skipGPU)
223 PP driver = gpuPolySpanDrivers[
224 (gpu_unai.blit_mask?1024:0) |
226 gpu_unai.Masking | Blending | gpu_unai.PixelMSB
228 gpuDrawPolyF(packet, driver, true); // is_quad = true
229 gpu_unai.fb_dirty = true;
230 DO_LOG(("gpuDrawPolyF(0x%x) (4-pt QUAD)\n",PRIM));
237 case 0x2F: { // Textured 4-pt poly
238 if (!gpu_unai.frameskip.skipGPU)
241 gpuSetCLUT (gpu_unai.PacketBuffer.U4[2] >> 16);
242 gpuSetTexture (gpu_unai.PacketBuffer.U4[4] >> 16);
245 (gpu_unai.blit_mask?1024:0) |
247 Blending_Mode | gpu_unai.TEXT_MODE |
248 gpu_unai.Masking | Blending | gpu_unai.PixelMSB;
250 if (!FastLightingEnabled()) {
251 driver_idx |= Lighting;
253 if (!((gpu_unai.PacketBuffer.U1[0]>0x5F) && (gpu_unai.PacketBuffer.U1[1]>0x5F) && (gpu_unai.PacketBuffer.U1[2]>0x5F)))
254 driver_idx |= Lighting;
257 PP driver = gpuPolySpanDrivers[driver_idx];
258 gpuDrawPolyFT(packet, driver, true); // is_quad = true
259 gpu_unai.fb_dirty = true;
260 DO_LOG(("gpuDrawPolyFT(0x%x) (4-pt QUAD)\n",PRIM));
267 case 0x33: { // Gouraud-shaded 3-pt poly
268 if (!gpu_unai.frameskip.skipGPU)
271 //NOTE: The '129' here is CF_GOURAUD | CF_LIGHT, however
272 // this is an untextured poly, so CF_LIGHT (texture blend)
273 // shouldn't apply. Until the original array of template
274 // instantiation ptrs is fixed, we're stuck with this. (TODO)
275 PP driver = gpuPolySpanDrivers[
276 (gpu_unai.blit_mask?1024:0) |
279 gpu_unai.Masking | Blending | 129 | gpu_unai.PixelMSB
281 gpuDrawPolyG(packet, driver, false);
282 gpu_unai.fb_dirty = true;
283 DO_LOG(("gpuDrawPolyG(0x%x)\n",PRIM));
290 case 0x37: { // Gouraud-shaded, textured 3-pt poly
291 if (!gpu_unai.frameskip.skipGPU)
294 gpuSetCLUT (gpu_unai.PacketBuffer.U4[2] >> 16);
295 gpuSetTexture (gpu_unai.PacketBuffer.U4[5] >> 16);
296 PP driver = gpuPolySpanDrivers[
297 (gpu_unai.blit_mask?1024:0) |
299 Blending_Mode | gpu_unai.TEXT_MODE |
300 gpu_unai.Masking | Blending | ((Lighting)?129:0) | gpu_unai.PixelMSB
302 gpuDrawPolyGT(packet, driver, false);
303 gpu_unai.fb_dirty = true;
304 DO_LOG(("gpuDrawPolyGT(0x%x)\n",PRIM));
311 case 0x3B: { // Gouraud-shaded 4-pt poly
312 if (!gpu_unai.frameskip.skipGPU)
315 // See notes regarding '129' for 0x30..0x33 further above -senquack
316 PP driver = gpuPolySpanDrivers[
317 (gpu_unai.blit_mask?1024:0) |
320 gpu_unai.Masking | Blending | 129 | gpu_unai.PixelMSB
322 gpuDrawPolyG(packet, driver, true); // is_quad = true
323 gpu_unai.fb_dirty = true;
324 DO_LOG(("gpuDrawPolyG(0x%x) (4-pt QUAD)\n",PRIM));
331 case 0x3F: { // Gouraud-shaded, textured 4-pt poly
332 if (!gpu_unai.frameskip.skipGPU)
335 gpuSetCLUT (gpu_unai.PacketBuffer.U4[2] >> 16);
336 gpuSetTexture (gpu_unai.PacketBuffer.U4[5] >> 16);
337 PP driver = gpuPolySpanDrivers[
338 (gpu_unai.blit_mask?1024:0) |
340 Blending_Mode | gpu_unai.TEXT_MODE |
341 gpu_unai.Masking | Blending | ((Lighting)?129:0) | gpu_unai.PixelMSB
343 gpuDrawPolyGT(packet, driver, true); // is_quad = true
344 gpu_unai.fb_dirty = true;
345 DO_LOG(("gpuDrawPolyGT(0x%x) (4-pt QUAD)\n",PRIM));
352 case 0x43: { // Monochrome line
353 if (!gpu_unai.frameskip.skipGPU)
356 // Shift index right by one, as untextured prims don't use lighting
357 u32 driver_idx = (Blending_Mode | gpu_unai.Masking | Blending | (gpu_unai.PixelMSB>>3)) >> 1;
358 PSD driver = gpuPixelSpanDrivers[driver_idx];
359 gpuDrawLineF(packet, driver);
360 gpu_unai.fb_dirty = true;
361 DO_LOG(("gpuDrawLineF(0x%x)\n",PRIM));
372 case 0x4F: { // Monochrome line strip
373 if (!gpu_unai.frameskip.skipGPU)
376 // Shift index right by one, as untextured prims don't use lighting
377 u32 driver_idx = (Blending_Mode | gpu_unai.Masking | Blending | (gpu_unai.PixelMSB>>3)) >> 1;
378 PSD driver = gpuPixelSpanDrivers[driver_idx];
379 gpuDrawLineF(packet, driver);
380 gpu_unai.fb_dirty = true;
381 DO_LOG(("gpuDrawLineF(0x%x)\n",PRIM));
383 if ((gpu_unai.PacketBuffer.U4[3] & 0xF000F000) != 0x50005000)
385 gpu_unai.PacketBuffer.U4[1] = gpu_unai.PacketBuffer.U4[2];
386 gpu_unai.PacketBuffer.U4[2] = gpu_unai.PacketBuffer.U4[3];
387 gpu_unai.PacketCount = 1;
388 gpu_unai.PacketIndex = 3;
395 case 0x53: { // Gouraud-shaded line
396 if (!gpu_unai.frameskip.skipGPU)
399 // Shift index right by one, as untextured prims don't use lighting
400 u32 driver_idx = (Blending_Mode | gpu_unai.Masking | Blending | (gpu_unai.PixelMSB>>3)) >> 1;
401 // Index MSB selects Gouraud-shaded PixelSpanDriver:
402 driver_idx |= (1 << 5);
403 PSD driver = gpuPixelSpanDrivers[driver_idx];
404 gpuDrawLineG(packet, driver);
405 gpu_unai.fb_dirty = true;
406 DO_LOG(("gpuDrawLineG(0x%x)\n",PRIM));
417 case 0x5F: { // Gouraud-shaded line strip
418 if (!gpu_unai.frameskip.skipGPU)
421 // Shift index right by one, as untextured prims don't use lighting
422 u32 driver_idx = (Blending_Mode | gpu_unai.Masking | Blending | (gpu_unai.PixelMSB>>3)) >> 1;
423 // Index MSB selects Gouraud-shaded PixelSpanDriver:
424 driver_idx |= (1 << 5);
425 PSD driver = gpuPixelSpanDrivers[driver_idx];
426 gpuDrawLineG(packet, driver);
427 gpu_unai.fb_dirty = true;
428 DO_LOG(("gpuDrawLineG(0x%x)\n",PRIM));
430 if ((gpu_unai.PacketBuffer.U4[4] & 0xF000F000) != 0x50005000)
432 gpu_unai.PacketBuffer.U1[3 + (2 * 4)] = gpu_unai.PacketBuffer.U1[3 + (0 * 4)];
433 gpu_unai.PacketBuffer.U4[0] = gpu_unai.PacketBuffer.U4[2];
434 gpu_unai.PacketBuffer.U4[1] = gpu_unai.PacketBuffer.U4[3];
435 gpu_unai.PacketBuffer.U4[2] = gpu_unai.PacketBuffer.U4[4];
436 gpu_unai.PacketCount = 2;
437 gpu_unai.PacketIndex = 3;
444 case 0x63: { // Monochrome rectangle (variable size)
445 if (!gpu_unai.frameskip.skipGPU)
448 PT driver = gpuTileSpanDrivers[(Blending_Mode | gpu_unai.Masking | Blending | (gpu_unai.PixelMSB>>3)) >> 1];
449 gpuDrawT(packet, driver);
450 gpu_unai.fb_dirty = true;
451 DO_LOG(("gpuDrawT(0x%x)\n",PRIM));
458 case 0x67: { // Textured rectangle (variable size)
459 if (!gpu_unai.frameskip.skipGPU)
462 gpuSetCLUT (gpu_unai.PacketBuffer.U4[2] >> 16);
463 u32 driver_idx = Blending_Mode | gpu_unai.TEXT_MODE | gpu_unai.Masking | Blending | (gpu_unai.PixelMSB>>1);
465 // This fixes Silent Hill running animation on loading screens:
466 // (On PSX, color values 0x00-0x7F darken the source texture's color,
467 // 0x81-FF lighten textures (ultimately clamped to 0x1F),
468 // 0x80 leaves source texture color unchanged, HOWEVER,
469 // gpu_unai uses a simple lighting LUT whereby only the upper
470 // 5 bits of an 8-bit color are used, so 0x80-0x87 all behave as
473 // NOTE: I've changed all textured sprite draw commands here and
474 // elsewhere to use proper behavior, but left poly commands
475 // alone, I don't want to slow rendering down too much. (TODO)
476 //if ((gpu_unai.PacketBuffer.U1[0]>0x5F) && (gpu_unai.PacketBuffer.U1[1]>0x5F) && (gpu_unai.PacketBuffer.U1[2]>0x5F))
477 // Strip lower 3 bits of each color and determine if lighting should be used:
478 if ((gpu_unai.PacketBuffer.U4[0] & 0xF8F8F8) != 0x808080)
479 driver_idx |= Lighting;
480 PS driver = gpuSpriteSpanDrivers[driver_idx];
481 gpuDrawS(packet, driver);
482 gpu_unai.fb_dirty = true;
483 DO_LOG(("gpuDrawS(0x%x)\n",PRIM));
490 case 0x6B: { // Monochrome rectangle (1x1 dot)
491 if (!gpu_unai.frameskip.skipGPU)
494 gpu_unai.PacketBuffer.U4[2] = 0x00010001;
495 PT driver = gpuTileSpanDrivers[(Blending_Mode | gpu_unai.Masking | Blending | (gpu_unai.PixelMSB>>3)) >> 1];
496 gpuDrawT(packet, driver);
497 gpu_unai.fb_dirty = true;
498 DO_LOG(("gpuDrawT(0x%x)\n",PRIM));
505 case 0x73: { // Monochrome rectangle (8x8)
506 if (!gpu_unai.frameskip.skipGPU)
509 gpu_unai.PacketBuffer.U4[2] = 0x00080008;
510 PT driver = gpuTileSpanDrivers[(Blending_Mode | gpu_unai.Masking | Blending | (gpu_unai.PixelMSB>>3)) >> 1];
511 gpuDrawT(packet, driver);
512 gpu_unai.fb_dirty = true;
513 DO_LOG(("gpuDrawT(0x%x)\n",PRIM));
520 case 0x77: { // Textured rectangle (8x8)
521 if (!gpu_unai.frameskip.skipGPU)
524 gpu_unai.PacketBuffer.U4[3] = 0x00080008;
525 gpuSetCLUT (gpu_unai.PacketBuffer.U4[2] >> 16);
526 u32 driver_idx = Blending_Mode | gpu_unai.TEXT_MODE | gpu_unai.Masking | Blending | (gpu_unai.PixelMSB>>1);
528 //senquack - Only color 808080h-878787h allows skipping lighting calculation:
529 //if ((gpu_unai.PacketBuffer.U1[0]>0x5F) && (gpu_unai.PacketBuffer.U1[1]>0x5F) && (gpu_unai.PacketBuffer.U1[2]>0x5F))
530 // Strip lower 3 bits of each color and determine if lighting should be used:
531 if ((gpu_unai.PacketBuffer.U4[0] & 0xF8F8F8) != 0x808080)
532 driver_idx |= Lighting;
533 PS driver = gpuSpriteSpanDrivers[driver_idx];
534 gpuDrawS(packet, driver);
535 gpu_unai.fb_dirty = true;
536 DO_LOG(("gpuDrawS(0x%x)\n",PRIM));
543 case 0x7B: { // Monochrome rectangle (16x16)
544 if (!gpu_unai.frameskip.skipGPU)
547 gpu_unai.PacketBuffer.U4[2] = 0x00100010;
548 PT driver = gpuTileSpanDrivers[(Blending_Mode | gpu_unai.Masking | Blending | (gpu_unai.PixelMSB>>3)) >> 1];
549 gpuDrawT(packet, driver);
550 gpu_unai.fb_dirty = true;
551 DO_LOG(("gpuDrawT(0x%x)\n",PRIM));
558 /* Notaz 4bit sprites optimization */
559 if ((!gpu_unai.frameskip.skipGPU) && (!(gpu_unai.GPU_GP1&0x180)) && (!(gpu_unai.Masking|gpu_unai.PixelMSB)))
561 gpuSetCLUT (gpu_unai.PacketBuffer.U4[2] >> 16);
563 gpu_unai.fb_dirty = true;
568 case 0x7F: { // Textured rectangle (16x16)
569 if (!gpu_unai.frameskip.skipGPU)
572 gpu_unai.PacketBuffer.U4[3] = 0x00100010;
573 gpuSetCLUT (gpu_unai.PacketBuffer.U4[2] >> 16);
574 u32 driver_idx = Blending_Mode | gpu_unai.TEXT_MODE | gpu_unai.Masking | Blending | (gpu_unai.PixelMSB>>1);
576 //senquack - Only color 808080h-878787h allows skipping lighting calculation:
577 //if ((gpu_unai.PacketBuffer.U1[0]>0x5F) && (gpu_unai.PacketBuffer.U1[1]>0x5F) && (gpu_unai.PacketBuffer.U1[2]>0x5F))
578 // Strip lower 3 bits of each color and determine if lighting should be used:
579 if ((gpu_unai.PacketBuffer.U4[0] & 0xF8F8F8) != 0x808080)
580 driver_idx |= Lighting;
581 PS driver = gpuSpriteSpanDrivers[driver_idx];
582 gpuDrawS(packet, driver);
583 gpu_unai.fb_dirty = true;
584 DO_LOG(("gpuDrawS(0x%x)\n",PRIM));
588 case 0x80: // vid -> vid
589 gpuMoveImage(packet); // prim handles updateLace && skip
590 if ((!gpu_unai.frameskip.skipCount) && (gpu_unai.DisplayArea[3] == 480)) // Tekken 3 hack
592 if (!gpu_unai.frameskip.skipGPU) gpu_unai.fb_dirty = true;
596 gpu_unai.fb_dirty = true;
598 DO_LOG(("gpuMoveImage(0x%x)\n",PRIM));
600 case 0xA0: // sys ->vid
601 gpuLoadImage(packet); // prim handles updateLace && skip
602 DO_LOG(("gpuLoadImage(0x%x)\n",PRIM));
604 case 0xC0: // vid -> sys
605 gpuStoreImage(packet); // prim handles updateLace && skip
606 DO_LOG(("gpuStoreImage(0x%x)\n",PRIM));
608 case 0xE1 ... 0xE6: { // Draw settings
609 gpuGP0Cmd_0xEx(gpu_unai, gpu_unai.PacketBuffer.U4[0]);
614 ///////////////////////////////////////////////////////////////////////////////
615 // End of code specific to non-gpulib standalone version of gpu_unai
616 ///////////////////////////////////////////////////////////////////////////////