frontend: accept more bios
[pcsx_rearmed.git] / plugins / gpu_senquack / gpulib_if.cpp
CommitLineData
0bfe8d59 1/***************************************************************************
2* Copyright (C) 2010 PCSX4ALL Team *
3* Copyright (C) 2010 Unai *
4* Copyright (C) 2011 notaz *
5* Copyright (C) 2016 Senquack (dansilsby <AT> gmail <DOT> com) *
6* *
7* This program is free software; you can redistribute it and/or modify *
8* it under the terms of the GNU General Public License as published by *
9* the Free Software Foundation; either version 2 of the License, or *
10* (at your option) any later version. *
11* *
12* This program is distributed in the hope that it will be useful, *
13* but WITHOUT ANY WARRANTY; without even the implied warranty of *
14* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
15* GNU General Public License for more details. *
16* *
17* You should have received a copy of the GNU General Public License *
18* along with this program; if not, write to the *
19* Free Software Foundation, Inc., *
20* 51 Franklin Street, Fifth Floor, Boston, MA 02111-1307 USA. *
21***************************************************************************/
22
23#include <stddef.h>
24#include <stdio.h>
25#include <stdlib.h>
26#include <string.h>
27#include "../gpulib/gpu.h"
28
29//#include "port.h"
30#include "gpu_senquack.h"
31
32// GPU fixed point math
33#include "gpu_fixedpoint.h"
34
35// Inner loop driver instantiation file
36#include "gpu_inner.h"
37
38// GPU internal image drawing functions
39#include "gpu_raster_image.h"
40
41// GPU internal line drawing functions
42#include "gpu_raster_line.h"
43
44// GPU internal polygon drawing functions
45#include "gpu_raster_polygon.h"
46
47// GPU internal sprite drawing functions
48#include "gpu_raster_sprite.h"
49
50// GPU command buffer execution/store
51#include "gpu_command.h"
52
53/////////////////////////////////////////////////////////////////////////////
54
55int renderer_init(void)
56{
57 memset((void*)&gpu_senquack, 0, sizeof(gpu_senquack));
58 gpu_senquack.vram = (u16*)gpu.vram;
59
60 // Original standalone gpu_senquack initialized TextureWindow[]. I added the
61 // same behavior here, since it seems unsafe to leave [2],[3] unset when
62 // using HLE and Rearmed gpu_neon sets this similarly on init. -senquack
63 gpu_senquack.TextureWindow[0] = 0;
64 gpu_senquack.TextureWindow[1] = 0;
65 gpu_senquack.TextureWindow[2] = 255;
66 gpu_senquack.TextureWindow[3] = 255;
67 //senquack - new vars must be updated whenever texture window is changed:
68 // (used for polygon-drawing in gpu_inner.h, gpu_raster_polygon.h)
69 const u32 fb = FIXED_BITS; // # of fractional fixed-pt bits of u4/v4
70 gpu_senquack.u_msk = (((u32)gpu_senquack.TextureWindow[2]) << fb) | ((1 << fb) - 1);
71 gpu_senquack.v_msk = (((u32)gpu_senquack.TextureWindow[3]) << fb) | ((1 << fb) - 1);
72
73 // Configuration options
74 gpu_senquack.config = gpu_senquack_config_ext;
75 //senquack - disabled, not sure this is needed and would require modifying
76 // sprite-span functions, perhaps unnecessarily. No Abe Oddysey hack was
77 // present in latest PCSX4ALL sources we were using.
78 //gpu_senquack.config.enableAbbeyHack = gpu_senquack_config_ext.abe_hack;
79 gpu_senquack.ilace_mask = gpu_senquack.config.ilace_force;
80
81#ifdef GPU_UNAI_USE_INT_DIV_MULTINV
82 // s_invTable
83 for(int i=1;i<=(1<<TABLE_BITS);++i)
84 {
85 double v = 1.0 / double(i);
86#ifdef GPU_TABLE_10_BITS
87 v *= double(0xffffffff>>1);
88#else
89 v *= double(0x80000000);
90#endif
91 s_invTable[i-1]=s32(v);
92 }
93#endif
94
95 SetupLightLUT();
96 SetupDitheringConstants();
97
98 return 0;
99}
100
101void renderer_finish(void)
102{
103}
104
105void renderer_notify_res_change(void)
106{
107 if (PixelSkipEnabled()) {
108 // Set blit_mask for high horizontal resolutions. This allows skipping
109 // rendering pixels that would never get displayed on low-resolution
110 // platforms that use simple pixel-dropping scaler.
111
112 switch (gpu.screen.hres)
113 {
114 case 512: gpu_senquack.blit_mask = 0xa4; break; // GPU_BlitWWSWWSWS
115 case 640: gpu_senquack.blit_mask = 0xaa; break; // GPU_BlitWS
116 default: gpu_senquack.blit_mask = 0; break;
117 }
118 } else {
119 gpu_senquack.blit_mask = 0;
120 }
121
122 if (LineSkipEnabled()) {
123 // Set rendering line-skip (only render every other line in high-res
124 // 480 vertical mode, or, optionally, force it for all video modes)
125
126 if (gpu.screen.vres == 480) {
127 if (gpu_senquack.config.ilace_force) {
128 gpu_senquack.ilace_mask = 3; // Only need 1/4 of lines
129 } else {
130 gpu_senquack.ilace_mask = 1; // Only need 1/2 of lines
131 }
132 } else {
133 // Vert resolution changed from 480 to lower one
134 gpu_senquack.ilace_mask = gpu_senquack.config.ilace_force;
135 }
136 } else {
137 gpu_senquack.ilace_mask = 0;
138 }
139
140 /*
141 printf("res change hres: %d vres: %d depth: %d ilace_mask: %d\n",
142 gpu.screen.hres, gpu.screen.vres, gpu.status.rgb24 ? 24 : 15,
143 gpu_senquack.ilace_mask);
144 */
145}
146
147#ifdef USE_GPULIB
148// Handles GP0 draw settings commands 0xE1...0xE6
149static void gpuGP0Cmd_0xEx(gpu_senquack_t &gpu_senquack, u32 cmd_word)
150{
151 // Assume incoming GP0 command is 0xE1..0xE6, convert to 1..6
152 u8 num = (cmd_word >> 24) & 7;
153 gpu.ex_regs[num] = cmd_word; // Update gpulib register
154 switch (num) {
155 case 1: {
156 // GP0(E1h) - Draw Mode setting (aka "Texpage")
157 u32 cur_texpage = gpu_senquack.GPU_GP1 & 0x7FF;
158 u32 new_texpage = cmd_word & 0x7FF;
159 if (cur_texpage != new_texpage) {
160 gpu_senquack.GPU_GP1 = (gpu_senquack.GPU_GP1 & ~0x7FF) | new_texpage;
161 gpuSetTexture(gpu_senquack.GPU_GP1);
162 }
163 } break;
164
165 case 2: {
166 // GP0(E2h) - Texture Window setting
167 if (cmd_word != gpu_senquack.TextureWindowCur) {
168 static const u8 TextureMask[32] = {
169 255, 7, 15, 7, 31, 7, 15, 7, 63, 7, 15, 7, 31, 7, 15, 7,
170 127, 7, 15, 7, 31, 7, 15, 7, 63, 7, 15, 7, 31, 7, 15, 7
171 };
172 gpu_senquack.TextureWindowCur = cmd_word;
173 gpu_senquack.TextureWindow[0] = ((cmd_word >> 10) & 0x1F) << 3;
174 gpu_senquack.TextureWindow[1] = ((cmd_word >> 15) & 0x1F) << 3;
175 gpu_senquack.TextureWindow[2] = TextureMask[(cmd_word >> 0) & 0x1F];
176 gpu_senquack.TextureWindow[3] = TextureMask[(cmd_word >> 5) & 0x1F];
177 gpu_senquack.TextureWindow[0] &= ~gpu_senquack.TextureWindow[2];
178 gpu_senquack.TextureWindow[1] &= ~gpu_senquack.TextureWindow[3];
179
180 // Inner loop vars must be updated whenever texture window is changed:
181 const u32 fb = FIXED_BITS; // # of fractional fixed-pt bits of u4/v4
182 gpu_senquack.u_msk = (((u32)gpu_senquack.TextureWindow[2]) << fb) | ((1 << fb) - 1);
183 gpu_senquack.v_msk = (((u32)gpu_senquack.TextureWindow[3]) << fb) | ((1 << fb) - 1);
184
185 gpuSetTexture(gpu_senquack.GPU_GP1);
186 }
187 } break;
188
189 case 3: {
190 // GP0(E3h) - Set Drawing Area top left (X1,Y1)
191 gpu_senquack.DrawingArea[0] = cmd_word & 0x3FF;
192 gpu_senquack.DrawingArea[1] = (cmd_word >> 10) & 0x3FF;
193 } break;
194
195 case 4: {
196 // GP0(E4h) - Set Drawing Area bottom right (X2,Y2)
197 gpu_senquack.DrawingArea[2] = (cmd_word & 0x3FF) + 1;
198 gpu_senquack.DrawingArea[3] = ((cmd_word >> 10) & 0x3FF) + 1;
199 } break;
200
201 case 5: {
202 // GP0(E5h) - Set Drawing Offset (X,Y)
203 gpu_senquack.DrawingOffset[0] = ((s32)cmd_word<<(32-11))>>(32-11);
204 gpu_senquack.DrawingOffset[1] = ((s32)cmd_word<<(32-22))>>(32-11);
205 } break;
206
207 case 6: {
208 // GP0(E6h) - Mask Bit Setting
209 gpu_senquack.Masking = (cmd_word & 0x2) << 1;
210 gpu_senquack.PixelMSB = (cmd_word & 0x1) << 8;
211 } break;
212 }
213}
214#endif
215
216extern const unsigned char cmd_lengths[256];
217
218int do_cmd_list(u32 *list, int list_len, int *last_cmd)
219{
220 u32 cmd = 0, len, i;
221 u32 *list_start = list;
222 u32 *list_end = list + list_len;
223
224 //TODO: set ilace_mask when resolution changes instead of every time,
225 // eliminate #ifdef below.
226 gpu_senquack.ilace_mask = gpu_senquack.config.ilace_force;
227
228#ifdef HAVE_PRE_ARMV7 /* XXX */
f23b103c 229 gpu_senquack.ilace_mask |= !!(gpu.status & PSX_GPU_STATUS_INTERLACE);
0bfe8d59 230#endif
231 if (gpu_senquack.config.scale_hires) {
f23b103c 232 gpu_senquack.ilace_mask |= !!(gpu.status & PSX_GPU_STATUS_INTERLACE);
0bfe8d59 233 }
234
235 for (; list < list_end; list += 1 + len)
236 {
237 cmd = *list >> 24;
238 len = cmd_lengths[cmd];
239 if (list + 1 + len > list_end) {
240 cmd = -1;
241 break;
242 }
243
244 #define PRIM cmd
245 gpu_senquack.PacketBuffer.U4[0] = list[0];
246 for (i = 1; i <= len; i++)
247 gpu_senquack.PacketBuffer.U4[i] = list[i];
248
249 PtrUnion packet = { .ptr = (void*)&gpu_senquack.PacketBuffer };
250
251 switch (cmd)
252 {
253 case 0x02:
254 gpuClearImage(packet);
255 break;
256
257 case 0x20:
258 case 0x21:
259 case 0x22:
260 case 0x23: { // Monochrome 3-pt poly
261 PP driver = gpuPolySpanDrivers[
262 (gpu_senquack.blit_mask?1024:0) |
263 Blending_Mode |
264 gpu_senquack.Masking | Blending | gpu_senquack.PixelMSB
265 ];
266 gpuDrawPolyF(packet, driver, false);
267 } break;
268
269 case 0x24:
270 case 0x25:
271 case 0x26:
272 case 0x27: { // Textured 3-pt poly
273 gpuSetCLUT (gpu_senquack.PacketBuffer.U4[2] >> 16);
274 gpuSetTexture(gpu_senquack.PacketBuffer.U4[4] >> 16);
275
276 u32 driver_idx =
277 (gpu_senquack.blit_mask?1024:0) |
278 Dithering |
279 Blending_Mode | gpu_senquack.TEXT_MODE |
280 gpu_senquack.Masking | Blending | gpu_senquack.PixelMSB;
281
282 if (!FastLightingEnabled()) {
283 driver_idx |= Lighting;
284 } else {
285 if (!((gpu_senquack.PacketBuffer.U1[0]>0x5F) && (gpu_senquack.PacketBuffer.U1[1]>0x5F) && (gpu_senquack.PacketBuffer.U1[2]>0x5F)))
286 driver_idx |= Lighting;
287 }
288
289 PP driver = gpuPolySpanDrivers[driver_idx];
290 gpuDrawPolyFT(packet, driver, false);
291 } break;
292
293 case 0x28:
294 case 0x29:
295 case 0x2A:
296 case 0x2B: { // Monochrome 4-pt poly
297 PP driver = gpuPolySpanDrivers[
298 (gpu_senquack.blit_mask?1024:0) |
299 Blending_Mode |
300 gpu_senquack.Masking | Blending | gpu_senquack.PixelMSB
301 ];
302 gpuDrawPolyF(packet, driver, true); // is_quad = true
303 } break;
304
305 case 0x2C:
306 case 0x2D:
307 case 0x2E:
308 case 0x2F: { // Textured 4-pt poly
309 gpuSetCLUT (gpu_senquack.PacketBuffer.U4[2] >> 16);
310 gpuSetTexture(gpu_senquack.PacketBuffer.U4[4] >> 16);
311
312 u32 driver_idx =
313 (gpu_senquack.blit_mask?1024:0) |
314 Dithering |
315 Blending_Mode | gpu_senquack.TEXT_MODE |
316 gpu_senquack.Masking | Blending | gpu_senquack.PixelMSB;
317
318 if (!FastLightingEnabled()) {
319 driver_idx |= Lighting;
320 } else {
321 if (!((gpu_senquack.PacketBuffer.U1[0]>0x5F) && (gpu_senquack.PacketBuffer.U1[1]>0x5F) && (gpu_senquack.PacketBuffer.U1[2]>0x5F)))
322 driver_idx |= Lighting;
323 }
324
325 PP driver = gpuPolySpanDrivers[driver_idx];
326 gpuDrawPolyFT(packet, driver, true); // is_quad = true
327 } break;
328
329 case 0x30:
330 case 0x31:
331 case 0x32:
332 case 0x33: { // Gouraud-shaded 3-pt poly
333 //NOTE: The '129' here is CF_GOURAUD | CF_LIGHT, however
334 // this is an untextured poly, so CF_LIGHT (texture blend)
335 // shouldn't apply. Until the original array of template
336 // instantiation ptrs is fixed, we're stuck with this. (TODO)
337 PP driver = gpuPolySpanDrivers[
338 (gpu_senquack.blit_mask?1024:0) |
339 Dithering |
340 Blending_Mode |
341 gpu_senquack.Masking | Blending | 129 | gpu_senquack.PixelMSB
342 ];
343 gpuDrawPolyG(packet, driver, false);
344 } break;
345
346 case 0x34:
347 case 0x35:
348 case 0x36:
349 case 0x37: { // Gouraud-shaded, textured 3-pt poly
350 gpuSetCLUT (gpu_senquack.PacketBuffer.U4[2] >> 16);
351 gpuSetTexture (gpu_senquack.PacketBuffer.U4[5] >> 16);
352 PP driver = gpuPolySpanDrivers[
353 (gpu_senquack.blit_mask?1024:0) |
354 Dithering |
355 Blending_Mode | gpu_senquack.TEXT_MODE |
356 gpu_senquack.Masking | Blending | ((Lighting)?129:0) | gpu_senquack.PixelMSB
357 ];
358 gpuDrawPolyGT(packet, driver, false);
359 } break;
360
361 case 0x38:
362 case 0x39:
363 case 0x3A:
364 case 0x3B: { // Gouraud-shaded 4-pt poly
365 // See notes regarding '129' for 0x30..0x33 further above -senquack
366 PP driver = gpuPolySpanDrivers[
367 (gpu_senquack.blit_mask?1024:0) |
368 Dithering |
369 Blending_Mode |
370 gpu_senquack.Masking | Blending | 129 | gpu_senquack.PixelMSB
371 ];
372 gpuDrawPolyG(packet, driver, true); // is_quad = true
373 } break;
374
375 case 0x3C:
376 case 0x3D:
377 case 0x3E:
378 case 0x3F: { // Gouraud-shaded, textured 4-pt poly
379 gpuSetCLUT (gpu_senquack.PacketBuffer.U4[2] >> 16);
380 gpuSetTexture (gpu_senquack.PacketBuffer.U4[5] >> 16);
381 PP driver = gpuPolySpanDrivers[
382 (gpu_senquack.blit_mask?1024:0) |
383 Dithering |
384 Blending_Mode | gpu_senquack.TEXT_MODE |
385 gpu_senquack.Masking | Blending | ((Lighting)?129:0) | gpu_senquack.PixelMSB
386 ];
387 gpuDrawPolyGT(packet, driver, true); // is_quad = true
388 } break;
389
390 case 0x40:
391 case 0x41:
392 case 0x42:
393 case 0x43: { // Monochrome line
394 // Shift index right by one, as untextured prims don't use lighting
395 u32 driver_idx = (Blending_Mode | gpu_senquack.Masking | Blending | (gpu_senquack.PixelMSB>>3)) >> 1;
396 PSD driver = gpuPixelSpanDrivers[driver_idx];
397 gpuDrawLineF(packet, driver);
398 } break;
399
400 case 0x48 ... 0x4F: { // Monochrome line strip
401 u32 num_vertexes = 1;
402 u32 *list_position = &(list[2]);
403
404 // Shift index right by one, as untextured prims don't use lighting
405 u32 driver_idx = (Blending_Mode | gpu_senquack.Masking | Blending | (gpu_senquack.PixelMSB>>3)) >> 1;
406 PSD driver = gpuPixelSpanDrivers[driver_idx];
407 gpuDrawLineF(packet, driver);
408
409 while(1)
410 {
411 gpu_senquack.PacketBuffer.U4[1] = gpu_senquack.PacketBuffer.U4[2];
412 gpu_senquack.PacketBuffer.U4[2] = *list_position++;
413 gpuDrawLineF(packet, driver);
414
415 num_vertexes++;
416 if(list_position >= list_end) {
417 cmd = -1;
418 goto breakloop;
419 }
420 if((*list_position & 0xf000f000) == 0x50005000)
421 break;
422 }
423
424 len += (num_vertexes - 2);
425 } break;
426
427 case 0x50:
428 case 0x51:
429 case 0x52:
430 case 0x53: { // Gouraud-shaded line
431 // Shift index right by one, as untextured prims don't use lighting
432 u32 driver_idx = (Blending_Mode | gpu_senquack.Masking | Blending | (gpu_senquack.PixelMSB>>3)) >> 1;
433 // Index MSB selects Gouraud-shaded PixelSpanDriver:
434 driver_idx |= (1 << 5);
435 PSD driver = gpuPixelSpanDrivers[driver_idx];
436 gpuDrawLineG(packet, driver);
437 } break;
438
439 case 0x58 ... 0x5F: { // Gouraud-shaded line strip
440 u32 num_vertexes = 1;
441 u32 *list_position = &(list[2]);
442
443 // Shift index right by one, as untextured prims don't use lighting
444 u32 driver_idx = (Blending_Mode | gpu_senquack.Masking | Blending | (gpu_senquack.PixelMSB>>3)) >> 1;
445 // Index MSB selects Gouraud-shaded PixelSpanDriver:
446 driver_idx |= (1 << 5);
447 PSD driver = gpuPixelSpanDrivers[driver_idx];
448 gpuDrawLineG(packet, driver);
449
450 while(1)
451 {
452 gpu_senquack.PacketBuffer.U4[0] = gpu_senquack.PacketBuffer.U4[2];
453 gpu_senquack.PacketBuffer.U4[1] = gpu_senquack.PacketBuffer.U4[3];
454 gpu_senquack.PacketBuffer.U4[2] = *list_position++;
455 gpu_senquack.PacketBuffer.U4[3] = *list_position++;
456 gpuDrawLineG(packet, driver);
457
458 num_vertexes++;
459 if(list_position >= list_end) {
460 cmd = -1;
461 goto breakloop;
462 }
463 if((*list_position & 0xf000f000) == 0x50005000)
464 break;
465 }
466
467 len += (num_vertexes - 2) * 2;
468 } break;
469
470 case 0x60:
471 case 0x61:
472 case 0x62:
473 case 0x63: { // Monochrome rectangle (variable size)
474 PT driver = gpuTileSpanDrivers[(Blending_Mode | gpu_senquack.Masking | Blending | (gpu_senquack.PixelMSB>>3)) >> 1];
475 gpuDrawT(packet, driver);
476 } break;
477
478 case 0x64:
479 case 0x65:
480 case 0x66:
481 case 0x67: { // Textured rectangle (variable size)
482 gpuSetCLUT (gpu_senquack.PacketBuffer.U4[2] >> 16);
483 u32 driver_idx = Blending_Mode | gpu_senquack.TEXT_MODE | gpu_senquack.Masking | Blending | (gpu_senquack.PixelMSB>>1);
484
485 //senquack - Only color 808080h-878787h allows skipping lighting calculation:
486 // This fixes Silent Hill running animation on loading screens:
487 // (On PSX, color values 0x00-0x7F darken the source texture's color,
488 // 0x81-FF lighten textures (ultimately clamped to 0x1F),
489 // 0x80 leaves source texture color unchanged, HOWEVER,
490 // gpu_senquack uses a simple lighting LUT whereby only the upper
491 // 5 bits of an 8-bit color are used, so 0x80-0x87 all behave as
492 // 0x80.
493 //
494 // NOTE: I've changed all textured sprite draw commands here and
495 // elsewhere to use proper behavior, but left poly commands
496 // alone, I don't want to slow rendering down too much. (TODO)
497 //if ((gpu_senquack.PacketBuffer.U1[0]>0x5F) && (gpu_senquack.PacketBuffer.U1[1]>0x5F) && (gpu_senquack.PacketBuffer.U1[2]>0x5F))
498 // Strip lower 3 bits of each color and determine if lighting should be used:
499 if ((gpu_senquack.PacketBuffer.U4[0] & 0xF8F8F8) != 0x808080)
500 driver_idx |= Lighting;
501 PS driver = gpuSpriteSpanDrivers[driver_idx];
502 gpuDrawS(packet, driver);
503 } break;
504
505 case 0x68:
506 case 0x69:
507 case 0x6A:
508 case 0x6B: { // Monochrome rectangle (1x1 dot)
509 gpu_senquack.PacketBuffer.U4[2] = 0x00010001;
510 PT driver = gpuTileSpanDrivers[(Blending_Mode | gpu_senquack.Masking | Blending | (gpu_senquack.PixelMSB>>3)) >> 1];
511 gpuDrawT(packet, driver);
512 } break;
513
514 case 0x70:
515 case 0x71:
516 case 0x72:
517 case 0x73: { // Monochrome rectangle (8x8)
518 gpu_senquack.PacketBuffer.U4[2] = 0x00080008;
519 PT driver = gpuTileSpanDrivers[(Blending_Mode | gpu_senquack.Masking | Blending | (gpu_senquack.PixelMSB>>3)) >> 1];
520 gpuDrawT(packet, driver);
521 } break;
522
523 case 0x74:
524 case 0x75:
525 case 0x76:
526 case 0x77: { // Textured rectangle (8x8)
527 gpu_senquack.PacketBuffer.U4[3] = 0x00080008;
528 gpuSetCLUT (gpu_senquack.PacketBuffer.U4[2] >> 16);
529 u32 driver_idx = Blending_Mode | gpu_senquack.TEXT_MODE | gpu_senquack.Masking | Blending | (gpu_senquack.PixelMSB>>1);
530
531 //senquack - Only color 808080h-878787h allows skipping lighting calculation:
532 //if ((gpu_senquack.PacketBuffer.U1[0]>0x5F) && (gpu_senquack.PacketBuffer.U1[1]>0x5F) && (gpu_senquack.PacketBuffer.U1[2]>0x5F))
533 // Strip lower 3 bits of each color and determine if lighting should be used:
534 if ((gpu_senquack.PacketBuffer.U4[0] & 0xF8F8F8) != 0x808080)
535 driver_idx |= Lighting;
536 PS driver = gpuSpriteSpanDrivers[driver_idx];
537 gpuDrawS(packet, driver);
538 } break;
539
540 case 0x78:
541 case 0x79:
542 case 0x7A:
543 case 0x7B: { // Monochrome rectangle (16x16)
544 gpu_senquack.PacketBuffer.U4[2] = 0x00100010;
545 PT driver = gpuTileSpanDrivers[(Blending_Mode | gpu_senquack.Masking | Blending | (gpu_senquack.PixelMSB>>3)) >> 1];
546 gpuDrawT(packet, driver);
547 } break;
548
549 case 0x7C:
550 case 0x7D:
551#ifdef __arm__
552 if ((gpu_senquack.GPU_GP1 & 0x180) == 0 && (gpu_senquack.Masking | gpu_senquack.PixelMSB) == 0)
553 {
554 gpuSetCLUT (gpu_senquack.PacketBuffer.U4[2] >> 16);
555 gpuDrawS16(packet);
556 break;
557 }
558 // fallthrough
559#endif
560 case 0x7E:
561 case 0x7F: { // Textured rectangle (16x16)
562 gpu_senquack.PacketBuffer.U4[3] = 0x00100010;
563 gpuSetCLUT (gpu_senquack.PacketBuffer.U4[2] >> 16);
564 u32 driver_idx = Blending_Mode | gpu_senquack.TEXT_MODE | gpu_senquack.Masking | Blending | (gpu_senquack.PixelMSB>>1);
565 //senquack - Only color 808080h-878787h allows skipping lighting calculation:
566 //if ((gpu_senquack.PacketBuffer.U1[0]>0x5F) && (gpu_senquack.PacketBuffer.U1[1]>0x5F) && (gpu_senquack.PacketBuffer.U1[2]>0x5F))
567 // Strip lower 3 bits of each color and determine if lighting should be used:
568 if ((gpu_senquack.PacketBuffer.U4[0] & 0xF8F8F8) != 0x808080)
569 driver_idx |= Lighting;
570 PS driver = gpuSpriteSpanDrivers[driver_idx];
571 gpuDrawS(packet, driver);
572 } break;
573
574 case 0x80: // vid -> vid
575 gpuMoveImage(packet);
576 break;
577
578#ifdef TEST
579 case 0xA0: // sys -> vid
580 {
581 u32 load_width = list[2] & 0xffff;
582 u32 load_height = list[2] >> 16;
583 u32 load_size = load_width * load_height;
584
585 len += load_size / 2;
586 } break;
587
588 case 0xC0:
589 break;
590#else
591 case 0xA0: // sys ->vid
592 case 0xC0: // vid -> sys
593 // Handled by gpulib
594 goto breakloop;
595#endif
596 case 0xE1 ... 0xE6: { // Draw settings
597 gpuGP0Cmd_0xEx(gpu_senquack, gpu_senquack.PacketBuffer.U4[0]);
598 } break;
599 }
600 }
601
602breakloop:
603 gpu.ex_regs[1] &= ~0x1ff;
604 gpu.ex_regs[1] |= gpu_senquack.GPU_GP1 & 0x1ff;
605
606 *last_cmd = cmd;
607 return list - list_start;
608}
609
610void renderer_sync_ecmds(uint32_t *ecmds)
611{
612 int dummy;
613 do_cmd_list(&ecmds[1], 6, &dummy);
614}
615
616void renderer_update_caches(int x, int y, int w, int h)
617{
618}
619
620void renderer_flush_queues(void)
621{
622}
623
624void renderer_set_interlace(int enable, int is_odd)
625{
626}
627
628#include "../../frontend/plugin_lib.h"
629// Handle any gpulib settings applicable to gpu_senquack:
630void renderer_set_config(const struct rearmed_cbs *cbs)
631{
632 gpu_senquack.vram = (u16*)gpu.vram;
633 gpu_senquack.config.ilace_force = cbs->gpu_senquack.ilace_force;
634 gpu_senquack.config.pixel_skip = cbs->gpu_senquack.pixel_skip;
635 gpu_senquack.config.lighting = cbs->gpu_senquack.lighting;
636 gpu_senquack.config.fast_lighting = cbs->gpu_senquack.fast_lighting;
637 gpu_senquack.config.blending = cbs->gpu_senquack.blending;
638 gpu_senquack.config.dithering = cbs->gpu_senquack.dithering;
639 gpu_senquack.config.scale_hires = cbs->gpu_senquack.scale_hires;
640}
641
642// vim:shiftwidth=2:expandtab