rename gpu_senquack to gpu_unai
[pcsx_rearmed.git] / plugins / gpu_unai / 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
2da2fc76 147void renderer_notify_scanout_change(int x, int y)
0b4038f8 148{
149}
150
0bfe8d59 151#ifdef USE_GPULIB
152// Handles GP0 draw settings commands 0xE1...0xE6
153static void gpuGP0Cmd_0xEx(gpu_senquack_t &gpu_senquack, u32 cmd_word)
154{
155 // Assume incoming GP0 command is 0xE1..0xE6, convert to 1..6
156 u8 num = (cmd_word >> 24) & 7;
157 gpu.ex_regs[num] = cmd_word; // Update gpulib register
158 switch (num) {
159 case 1: {
160 // GP0(E1h) - Draw Mode setting (aka "Texpage")
161 u32 cur_texpage = gpu_senquack.GPU_GP1 & 0x7FF;
162 u32 new_texpage = cmd_word & 0x7FF;
163 if (cur_texpage != new_texpage) {
164 gpu_senquack.GPU_GP1 = (gpu_senquack.GPU_GP1 & ~0x7FF) | new_texpage;
165 gpuSetTexture(gpu_senquack.GPU_GP1);
166 }
167 } break;
168
169 case 2: {
170 // GP0(E2h) - Texture Window setting
171 if (cmd_word != gpu_senquack.TextureWindowCur) {
172 static const u8 TextureMask[32] = {
173 255, 7, 15, 7, 31, 7, 15, 7, 63, 7, 15, 7, 31, 7, 15, 7,
174 127, 7, 15, 7, 31, 7, 15, 7, 63, 7, 15, 7, 31, 7, 15, 7
175 };
176 gpu_senquack.TextureWindowCur = cmd_word;
177 gpu_senquack.TextureWindow[0] = ((cmd_word >> 10) & 0x1F) << 3;
178 gpu_senquack.TextureWindow[1] = ((cmd_word >> 15) & 0x1F) << 3;
179 gpu_senquack.TextureWindow[2] = TextureMask[(cmd_word >> 0) & 0x1F];
180 gpu_senquack.TextureWindow[3] = TextureMask[(cmd_word >> 5) & 0x1F];
181 gpu_senquack.TextureWindow[0] &= ~gpu_senquack.TextureWindow[2];
182 gpu_senquack.TextureWindow[1] &= ~gpu_senquack.TextureWindow[3];
183
184 // Inner loop vars must be updated whenever texture window is changed:
185 const u32 fb = FIXED_BITS; // # of fractional fixed-pt bits of u4/v4
186 gpu_senquack.u_msk = (((u32)gpu_senquack.TextureWindow[2]) << fb) | ((1 << fb) - 1);
187 gpu_senquack.v_msk = (((u32)gpu_senquack.TextureWindow[3]) << fb) | ((1 << fb) - 1);
188
189 gpuSetTexture(gpu_senquack.GPU_GP1);
190 }
191 } break;
192
193 case 3: {
194 // GP0(E3h) - Set Drawing Area top left (X1,Y1)
195 gpu_senquack.DrawingArea[0] = cmd_word & 0x3FF;
196 gpu_senquack.DrawingArea[1] = (cmd_word >> 10) & 0x3FF;
197 } break;
198
199 case 4: {
200 // GP0(E4h) - Set Drawing Area bottom right (X2,Y2)
201 gpu_senquack.DrawingArea[2] = (cmd_word & 0x3FF) + 1;
202 gpu_senquack.DrawingArea[3] = ((cmd_word >> 10) & 0x3FF) + 1;
203 } break;
204
205 case 5: {
206 // GP0(E5h) - Set Drawing Offset (X,Y)
207 gpu_senquack.DrawingOffset[0] = ((s32)cmd_word<<(32-11))>>(32-11);
208 gpu_senquack.DrawingOffset[1] = ((s32)cmd_word<<(32-22))>>(32-11);
209 } break;
210
211 case 6: {
212 // GP0(E6h) - Mask Bit Setting
213 gpu_senquack.Masking = (cmd_word & 0x2) << 1;
214 gpu_senquack.PixelMSB = (cmd_word & 0x1) << 8;
215 } break;
216 }
217}
218#endif
219
220extern const unsigned char cmd_lengths[256];
221
222int do_cmd_list(u32 *list, int list_len, int *last_cmd)
223{
224 u32 cmd = 0, len, i;
225 u32 *list_start = list;
226 u32 *list_end = list + list_len;
227
228 //TODO: set ilace_mask when resolution changes instead of every time,
229 // eliminate #ifdef below.
230 gpu_senquack.ilace_mask = gpu_senquack.config.ilace_force;
231
232#ifdef HAVE_PRE_ARMV7 /* XXX */
f23b103c 233 gpu_senquack.ilace_mask |= !!(gpu.status & PSX_GPU_STATUS_INTERLACE);
0bfe8d59 234#endif
235 if (gpu_senquack.config.scale_hires) {
f23b103c 236 gpu_senquack.ilace_mask |= !!(gpu.status & PSX_GPU_STATUS_INTERLACE);
0bfe8d59 237 }
238
239 for (; list < list_end; list += 1 + len)
240 {
241 cmd = *list >> 24;
242 len = cmd_lengths[cmd];
243 if (list + 1 + len > list_end) {
244 cmd = -1;
245 break;
246 }
247
248 #define PRIM cmd
249 gpu_senquack.PacketBuffer.U4[0] = list[0];
250 for (i = 1; i <= len; i++)
251 gpu_senquack.PacketBuffer.U4[i] = list[i];
252
253 PtrUnion packet = { .ptr = (void*)&gpu_senquack.PacketBuffer };
254
255 switch (cmd)
256 {
257 case 0x02:
258 gpuClearImage(packet);
259 break;
260
261 case 0x20:
262 case 0x21:
263 case 0x22:
264 case 0x23: { // Monochrome 3-pt poly
265 PP driver = gpuPolySpanDrivers[
266 (gpu_senquack.blit_mask?1024:0) |
267 Blending_Mode |
268 gpu_senquack.Masking | Blending | gpu_senquack.PixelMSB
269 ];
270 gpuDrawPolyF(packet, driver, false);
271 } break;
272
273 case 0x24:
274 case 0x25:
275 case 0x26:
276 case 0x27: { // Textured 3-pt poly
277 gpuSetCLUT (gpu_senquack.PacketBuffer.U4[2] >> 16);
278 gpuSetTexture(gpu_senquack.PacketBuffer.U4[4] >> 16);
279
280 u32 driver_idx =
281 (gpu_senquack.blit_mask?1024:0) |
282 Dithering |
283 Blending_Mode | gpu_senquack.TEXT_MODE |
284 gpu_senquack.Masking | Blending | gpu_senquack.PixelMSB;
285
286 if (!FastLightingEnabled()) {
287 driver_idx |= Lighting;
288 } else {
289 if (!((gpu_senquack.PacketBuffer.U1[0]>0x5F) && (gpu_senquack.PacketBuffer.U1[1]>0x5F) && (gpu_senquack.PacketBuffer.U1[2]>0x5F)))
290 driver_idx |= Lighting;
291 }
292
293 PP driver = gpuPolySpanDrivers[driver_idx];
294 gpuDrawPolyFT(packet, driver, false);
295 } break;
296
297 case 0x28:
298 case 0x29:
299 case 0x2A:
300 case 0x2B: { // Monochrome 4-pt poly
301 PP driver = gpuPolySpanDrivers[
302 (gpu_senquack.blit_mask?1024:0) |
303 Blending_Mode |
304 gpu_senquack.Masking | Blending | gpu_senquack.PixelMSB
305 ];
306 gpuDrawPolyF(packet, driver, true); // is_quad = true
307 } break;
308
309 case 0x2C:
310 case 0x2D:
311 case 0x2E:
312 case 0x2F: { // Textured 4-pt poly
313 gpuSetCLUT (gpu_senquack.PacketBuffer.U4[2] >> 16);
314 gpuSetTexture(gpu_senquack.PacketBuffer.U4[4] >> 16);
315
316 u32 driver_idx =
317 (gpu_senquack.blit_mask?1024:0) |
318 Dithering |
319 Blending_Mode | gpu_senquack.TEXT_MODE |
320 gpu_senquack.Masking | Blending | gpu_senquack.PixelMSB;
321
322 if (!FastLightingEnabled()) {
323 driver_idx |= Lighting;
324 } else {
325 if (!((gpu_senquack.PacketBuffer.U1[0]>0x5F) && (gpu_senquack.PacketBuffer.U1[1]>0x5F) && (gpu_senquack.PacketBuffer.U1[2]>0x5F)))
326 driver_idx |= Lighting;
327 }
328
329 PP driver = gpuPolySpanDrivers[driver_idx];
330 gpuDrawPolyFT(packet, driver, true); // is_quad = true
331 } break;
332
333 case 0x30:
334 case 0x31:
335 case 0x32:
336 case 0x33: { // Gouraud-shaded 3-pt poly
337 //NOTE: The '129' here is CF_GOURAUD | CF_LIGHT, however
338 // this is an untextured poly, so CF_LIGHT (texture blend)
339 // shouldn't apply. Until the original array of template
340 // instantiation ptrs is fixed, we're stuck with this. (TODO)
341 PP driver = gpuPolySpanDrivers[
342 (gpu_senquack.blit_mask?1024:0) |
343 Dithering |
344 Blending_Mode |
345 gpu_senquack.Masking | Blending | 129 | gpu_senquack.PixelMSB
346 ];
347 gpuDrawPolyG(packet, driver, false);
348 } break;
349
350 case 0x34:
351 case 0x35:
352 case 0x36:
353 case 0x37: { // Gouraud-shaded, textured 3-pt poly
354 gpuSetCLUT (gpu_senquack.PacketBuffer.U4[2] >> 16);
355 gpuSetTexture (gpu_senquack.PacketBuffer.U4[5] >> 16);
356 PP driver = gpuPolySpanDrivers[
357 (gpu_senquack.blit_mask?1024:0) |
358 Dithering |
359 Blending_Mode | gpu_senquack.TEXT_MODE |
360 gpu_senquack.Masking | Blending | ((Lighting)?129:0) | gpu_senquack.PixelMSB
361 ];
362 gpuDrawPolyGT(packet, driver, false);
363 } break;
364
365 case 0x38:
366 case 0x39:
367 case 0x3A:
368 case 0x3B: { // Gouraud-shaded 4-pt poly
369 // See notes regarding '129' for 0x30..0x33 further above -senquack
370 PP driver = gpuPolySpanDrivers[
371 (gpu_senquack.blit_mask?1024:0) |
372 Dithering |
373 Blending_Mode |
374 gpu_senquack.Masking | Blending | 129 | gpu_senquack.PixelMSB
375 ];
376 gpuDrawPolyG(packet, driver, true); // is_quad = true
377 } break;
378
379 case 0x3C:
380 case 0x3D:
381 case 0x3E:
382 case 0x3F: { // Gouraud-shaded, textured 4-pt poly
383 gpuSetCLUT (gpu_senquack.PacketBuffer.U4[2] >> 16);
384 gpuSetTexture (gpu_senquack.PacketBuffer.U4[5] >> 16);
385 PP driver = gpuPolySpanDrivers[
386 (gpu_senquack.blit_mask?1024:0) |
387 Dithering |
388 Blending_Mode | gpu_senquack.TEXT_MODE |
389 gpu_senquack.Masking | Blending | ((Lighting)?129:0) | gpu_senquack.PixelMSB
390 ];
391 gpuDrawPolyGT(packet, driver, true); // is_quad = true
392 } break;
393
394 case 0x40:
395 case 0x41:
396 case 0x42:
397 case 0x43: { // Monochrome line
398 // Shift index right by one, as untextured prims don't use lighting
399 u32 driver_idx = (Blending_Mode | gpu_senquack.Masking | Blending | (gpu_senquack.PixelMSB>>3)) >> 1;
400 PSD driver = gpuPixelSpanDrivers[driver_idx];
401 gpuDrawLineF(packet, driver);
402 } break;
403
404 case 0x48 ... 0x4F: { // Monochrome line strip
405 u32 num_vertexes = 1;
406 u32 *list_position = &(list[2]);
407
408 // Shift index right by one, as untextured prims don't use lighting
409 u32 driver_idx = (Blending_Mode | gpu_senquack.Masking | Blending | (gpu_senquack.PixelMSB>>3)) >> 1;
410 PSD driver = gpuPixelSpanDrivers[driver_idx];
411 gpuDrawLineF(packet, driver);
412
413 while(1)
414 {
415 gpu_senquack.PacketBuffer.U4[1] = gpu_senquack.PacketBuffer.U4[2];
416 gpu_senquack.PacketBuffer.U4[2] = *list_position++;
417 gpuDrawLineF(packet, driver);
418
419 num_vertexes++;
420 if(list_position >= list_end) {
421 cmd = -1;
422 goto breakloop;
423 }
424 if((*list_position & 0xf000f000) == 0x50005000)
425 break;
426 }
427
428 len += (num_vertexes - 2);
429 } break;
430
431 case 0x50:
432 case 0x51:
433 case 0x52:
434 case 0x53: { // Gouraud-shaded line
435 // Shift index right by one, as untextured prims don't use lighting
436 u32 driver_idx = (Blending_Mode | gpu_senquack.Masking | Blending | (gpu_senquack.PixelMSB>>3)) >> 1;
437 // Index MSB selects Gouraud-shaded PixelSpanDriver:
438 driver_idx |= (1 << 5);
439 PSD driver = gpuPixelSpanDrivers[driver_idx];
440 gpuDrawLineG(packet, driver);
441 } break;
442
443 case 0x58 ... 0x5F: { // Gouraud-shaded line strip
444 u32 num_vertexes = 1;
445 u32 *list_position = &(list[2]);
446
447 // Shift index right by one, as untextured prims don't use lighting
448 u32 driver_idx = (Blending_Mode | gpu_senquack.Masking | Blending | (gpu_senquack.PixelMSB>>3)) >> 1;
449 // Index MSB selects Gouraud-shaded PixelSpanDriver:
450 driver_idx |= (1 << 5);
451 PSD driver = gpuPixelSpanDrivers[driver_idx];
452 gpuDrawLineG(packet, driver);
453
454 while(1)
455 {
456 gpu_senquack.PacketBuffer.U4[0] = gpu_senquack.PacketBuffer.U4[2];
457 gpu_senquack.PacketBuffer.U4[1] = gpu_senquack.PacketBuffer.U4[3];
458 gpu_senquack.PacketBuffer.U4[2] = *list_position++;
459 gpu_senquack.PacketBuffer.U4[3] = *list_position++;
460 gpuDrawLineG(packet, driver);
461
462 num_vertexes++;
463 if(list_position >= list_end) {
464 cmd = -1;
465 goto breakloop;
466 }
467 if((*list_position & 0xf000f000) == 0x50005000)
468 break;
469 }
470
471 len += (num_vertexes - 2) * 2;
472 } break;
473
474 case 0x60:
475 case 0x61:
476 case 0x62:
477 case 0x63: { // Monochrome rectangle (variable size)
478 PT driver = gpuTileSpanDrivers[(Blending_Mode | gpu_senquack.Masking | Blending | (gpu_senquack.PixelMSB>>3)) >> 1];
479 gpuDrawT(packet, driver);
480 } break;
481
482 case 0x64:
483 case 0x65:
484 case 0x66:
485 case 0x67: { // Textured rectangle (variable size)
486 gpuSetCLUT (gpu_senquack.PacketBuffer.U4[2] >> 16);
487 u32 driver_idx = Blending_Mode | gpu_senquack.TEXT_MODE | gpu_senquack.Masking | Blending | (gpu_senquack.PixelMSB>>1);
488
489 //senquack - Only color 808080h-878787h allows skipping lighting calculation:
490 // This fixes Silent Hill running animation on loading screens:
491 // (On PSX, color values 0x00-0x7F darken the source texture's color,
492 // 0x81-FF lighten textures (ultimately clamped to 0x1F),
493 // 0x80 leaves source texture color unchanged, HOWEVER,
494 // gpu_senquack uses a simple lighting LUT whereby only the upper
495 // 5 bits of an 8-bit color are used, so 0x80-0x87 all behave as
496 // 0x80.
497 //
498 // NOTE: I've changed all textured sprite draw commands here and
499 // elsewhere to use proper behavior, but left poly commands
500 // alone, I don't want to slow rendering down too much. (TODO)
501 //if ((gpu_senquack.PacketBuffer.U1[0]>0x5F) && (gpu_senquack.PacketBuffer.U1[1]>0x5F) && (gpu_senquack.PacketBuffer.U1[2]>0x5F))
502 // Strip lower 3 bits of each color and determine if lighting should be used:
503 if ((gpu_senquack.PacketBuffer.U4[0] & 0xF8F8F8) != 0x808080)
504 driver_idx |= Lighting;
505 PS driver = gpuSpriteSpanDrivers[driver_idx];
506 gpuDrawS(packet, driver);
507 } break;
508
509 case 0x68:
510 case 0x69:
511 case 0x6A:
512 case 0x6B: { // Monochrome rectangle (1x1 dot)
513 gpu_senquack.PacketBuffer.U4[2] = 0x00010001;
514 PT driver = gpuTileSpanDrivers[(Blending_Mode | gpu_senquack.Masking | Blending | (gpu_senquack.PixelMSB>>3)) >> 1];
515 gpuDrawT(packet, driver);
516 } break;
517
518 case 0x70:
519 case 0x71:
520 case 0x72:
521 case 0x73: { // Monochrome rectangle (8x8)
522 gpu_senquack.PacketBuffer.U4[2] = 0x00080008;
523 PT driver = gpuTileSpanDrivers[(Blending_Mode | gpu_senquack.Masking | Blending | (gpu_senquack.PixelMSB>>3)) >> 1];
524 gpuDrawT(packet, driver);
525 } break;
526
527 case 0x74:
528 case 0x75:
529 case 0x76:
530 case 0x77: { // Textured rectangle (8x8)
531 gpu_senquack.PacketBuffer.U4[3] = 0x00080008;
532 gpuSetCLUT (gpu_senquack.PacketBuffer.U4[2] >> 16);
533 u32 driver_idx = Blending_Mode | gpu_senquack.TEXT_MODE | gpu_senquack.Masking | Blending | (gpu_senquack.PixelMSB>>1);
534
535 //senquack - Only color 808080h-878787h allows skipping lighting calculation:
536 //if ((gpu_senquack.PacketBuffer.U1[0]>0x5F) && (gpu_senquack.PacketBuffer.U1[1]>0x5F) && (gpu_senquack.PacketBuffer.U1[2]>0x5F))
537 // Strip lower 3 bits of each color and determine if lighting should be used:
538 if ((gpu_senquack.PacketBuffer.U4[0] & 0xF8F8F8) != 0x808080)
539 driver_idx |= Lighting;
540 PS driver = gpuSpriteSpanDrivers[driver_idx];
541 gpuDrawS(packet, driver);
542 } break;
543
544 case 0x78:
545 case 0x79:
546 case 0x7A:
547 case 0x7B: { // Monochrome rectangle (16x16)
548 gpu_senquack.PacketBuffer.U4[2] = 0x00100010;
549 PT driver = gpuTileSpanDrivers[(Blending_Mode | gpu_senquack.Masking | Blending | (gpu_senquack.PixelMSB>>3)) >> 1];
550 gpuDrawT(packet, driver);
551 } break;
552
553 case 0x7C:
554 case 0x7D:
555#ifdef __arm__
556 if ((gpu_senquack.GPU_GP1 & 0x180) == 0 && (gpu_senquack.Masking | gpu_senquack.PixelMSB) == 0)
557 {
558 gpuSetCLUT (gpu_senquack.PacketBuffer.U4[2] >> 16);
559 gpuDrawS16(packet);
560 break;
561 }
562 // fallthrough
563#endif
564 case 0x7E:
565 case 0x7F: { // Textured rectangle (16x16)
566 gpu_senquack.PacketBuffer.U4[3] = 0x00100010;
567 gpuSetCLUT (gpu_senquack.PacketBuffer.U4[2] >> 16);
568 u32 driver_idx = Blending_Mode | gpu_senquack.TEXT_MODE | gpu_senquack.Masking | Blending | (gpu_senquack.PixelMSB>>1);
569 //senquack - Only color 808080h-878787h allows skipping lighting calculation:
570 //if ((gpu_senquack.PacketBuffer.U1[0]>0x5F) && (gpu_senquack.PacketBuffer.U1[1]>0x5F) && (gpu_senquack.PacketBuffer.U1[2]>0x5F))
571 // Strip lower 3 bits of each color and determine if lighting should be used:
572 if ((gpu_senquack.PacketBuffer.U4[0] & 0xF8F8F8) != 0x808080)
573 driver_idx |= Lighting;
574 PS driver = gpuSpriteSpanDrivers[driver_idx];
575 gpuDrawS(packet, driver);
576 } break;
577
72583812 578#ifdef TEST
0bfe8d59 579 case 0x80: // vid -> vid
580 gpuMoveImage(packet);
581 break;
582
0bfe8d59 583 case 0xA0: // sys -> vid
584 {
585 u32 load_width = list[2] & 0xffff;
586 u32 load_height = list[2] >> 16;
587 u32 load_size = load_width * load_height;
588
589 len += load_size / 2;
590 } break;
591
592 case 0xC0:
593 break;
594#else
72583812 595 case 0x80 ... 0x9F: // vid -> vid
596 case 0xA0 ... 0xBF: // sys -> vid
597 case 0xC0 ... 0xDF: // vid -> sys
0bfe8d59 598 // Handled by gpulib
599 goto breakloop;
600#endif
601 case 0xE1 ... 0xE6: { // Draw settings
602 gpuGP0Cmd_0xEx(gpu_senquack, gpu_senquack.PacketBuffer.U4[0]);
603 } break;
604 }
605 }
606
607breakloop:
608 gpu.ex_regs[1] &= ~0x1ff;
609 gpu.ex_regs[1] |= gpu_senquack.GPU_GP1 & 0x1ff;
610
611 *last_cmd = cmd;
612 return list - list_start;
613}
614
615void renderer_sync_ecmds(uint32_t *ecmds)
616{
617 int dummy;
618 do_cmd_list(&ecmds[1], 6, &dummy);
619}
620
0b4038f8 621void renderer_update_caches(int x, int y, int w, int h, int state_changed)
0bfe8d59 622{
623}
624
625void renderer_flush_queues(void)
626{
627}
628
629void renderer_set_interlace(int enable, int is_odd)
630{
631}
632
633#include "../../frontend/plugin_lib.h"
634// Handle any gpulib settings applicable to gpu_senquack:
635void renderer_set_config(const struct rearmed_cbs *cbs)
636{
637 gpu_senquack.vram = (u16*)gpu.vram;
4cfc568d 638 gpu_senquack.config.ilace_force = cbs->gpu_unai.ilace_force;
639 gpu_senquack.config.pixel_skip = cbs->gpu_unai.pixel_skip;
640 gpu_senquack.config.lighting = cbs->gpu_unai.lighting;
641 gpu_senquack.config.fast_lighting = cbs->gpu_unai.fast_lighting;
642 gpu_senquack.config.blending = cbs->gpu_unai.blending;
643 gpu_senquack.config.dithering = cbs->gpu_unai.dithering;
644 gpu_senquack.config.scale_hires = cbs->gpu_unai.scale_hires;
0bfe8d59 645}
646
647// vim:shiftwidth=2:expandtab