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