psx_gpu: switch enhancement to 2048 width
[pcsx_rearmed.git] / plugins / gpu_unai / gpulib_if.cpp
... / ...
CommitLineData
1/***************************************************************************
2* Copyright (C) 2010 PCSX4ALL Team *
3* Copyright (C) 2010 Unai *
4* Copyright (C) 2011 notaz *
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
22#include <stdio.h>
23#include <stdlib.h>
24#include <string.h>
25#include "../gpulib/gpu.h"
26
27#define u8 uint8_t
28#define s8 int8_t
29#define u16 uint16_t
30#define s16 int16_t
31#define u32 uint32_t
32#define s32 int32_t
33#define s64 int64_t
34
35#define INLINE static
36
37#define FRAME_BUFFER_SIZE (1024*512*2)
38#define FRAME_WIDTH 1024
39#define FRAME_HEIGHT 512
40#define FRAME_OFFSET(x,y) (((y)<<10)+(x))
41
42#define isSkip 0 /* skip frame (info coming from GPU) */
43#define alt_fps 0
44static int linesInterlace; /* internal lines interlace */
45static int force_interlace;
46
47static bool light = true; /* lighting */
48static bool blend = true; /* blending */
49static bool FrameToRead = false; /* load image in progress */
50static bool FrameToWrite = false; /* store image in progress */
51
52static bool enableAbbeyHack = false; /* Abe's Odyssey hack */
53
54static u8 BLEND_MODE;
55static u8 TEXT_MODE;
56static u8 Masking;
57
58static u16 PixelMSB;
59static u16 PixelData;
60
61///////////////////////////////////////////////////////////////////////////////
62// GPU Global data
63///////////////////////////////////////////////////////////////////////////////
64
65// Dma Transfers info
66static s32 px,py;
67static s32 x_end,y_end;
68static u16* pvram;
69
70static s32 PacketCount;
71static s32 PacketIndex;
72
73// Rasterizer status
74static u32 TextureWindow [4];
75static u32 DrawingArea [4];
76static u32 DrawingOffset [2];
77
78static u16* TBA;
79static u16* CBA;
80
81// Inner Loops
82static s32 u4, du4;
83static s32 v4, dv4;
84static s32 r4, dr4;
85static s32 g4, dg4;
86static s32 b4, db4;
87static u32 lInc;
88static u32 tInc, tMsk;
89
90union GPUPacket
91{
92 u32 U4[16];
93 s32 S4[16];
94 u16 U2[32];
95 s16 S2[32];
96 u8 U1[64];
97 s8 S1[64];
98};
99
100static GPUPacket PacketBuffer;
101static u16 *GPU_FrameBuffer;
102static u32 GPU_GP1;
103
104///////////////////////////////////////////////////////////////////////////////
105
106#include "../gpu_unai/gpu_fixedpoint.h"
107
108// Inner loop driver instanciation file
109#include "../gpu_unai/gpu_inner.h"
110
111// GPU Raster Macros
112#define GPU_RGB16(rgb) ((((rgb)&0xF80000)>>9)|(((rgb)&0xF800)>>6)|(((rgb)&0xF8)>>3))
113
114#define GPU_EXPANDSIGN(x) (((s32)(x)<<21)>>21)
115
116#define CHKMAX_X 1024
117#define CHKMAX_Y 512
118
119#define GPU_SWAP(a,b,t) {(t)=(a);(a)=(b);(b)=(t);}
120
121// GPU internal image drawing functions
122#include "../gpu_unai/gpu_raster_image.h"
123
124// GPU internal line drawing functions
125#include "../gpu_unai/gpu_raster_line.h"
126
127// GPU internal polygon drawing functions
128#include "../gpu_unai/gpu_raster_polygon.h"
129
130// GPU internal sprite drawing functions
131#include "../gpu_unai/gpu_raster_sprite.h"
132
133// GPU command buffer execution/store
134#include "../gpu_unai/gpu_command.h"
135
136/////////////////////////////////////////////////////////////////////////////
137
138int renderer_init(void)
139{
140 GPU_FrameBuffer = (u16 *)gpu.vram;
141
142 // s_invTable
143 for(int i=1;i<=(1<<TABLE_BITS);++i)
144 {
145 double v = 1.0 / double(i);
146 #ifdef GPU_TABLE_10_BITS
147 v *= double(0xffffffff>>1);
148 #else
149 v *= double(0x80000000);
150 #endif
151 s_invTable[i-1]=s32(v);
152 }
153
154 return 0;
155}
156
157extern const unsigned char cmd_lengths[256];
158
159int do_cmd_list(unsigned int *list, int list_len, int *last_cmd)
160{
161 unsigned int cmd = 0, len, i;
162 unsigned int *list_start = list;
163 unsigned int *list_end = list + list_len;
164
165 linesInterlace = force_interlace;
166#ifndef __ARM_ARCH_7A__ /* XXX */
167 linesInterlace |= gpu.status.interlace;
168#endif
169
170 for (; list < list_end; list += 1 + len)
171 {
172 cmd = *list >> 24;
173 len = cmd_lengths[cmd];
174 if (list + 1 + len > list_end) {
175 cmd = -1;
176 break;
177 }
178
179 #define PRIM cmd
180 PacketBuffer.U4[0] = list[0];
181 for (i = 1; i <= len; i++)
182 PacketBuffer.U4[i] = list[i];
183
184 switch (cmd)
185 {
186 case 0x02:
187 gpuClearImage();
188 break;
189
190 case 0x20:
191 case 0x21:
192 case 0x22:
193 case 0x23:
194 gpuDrawF3(gpuPolySpanDrivers [Blending_Mode | Masking | Blending | PixelMSB]);
195 break;
196
197 case 0x24:
198 case 0x25:
199 case 0x26:
200 case 0x27:
201 gpuSetCLUT (PacketBuffer.U4[2] >> 16);
202 gpuSetTexture(PacketBuffer.U4[4] >> 16);
203 if ((PacketBuffer.U1[0]>0x5F) && (PacketBuffer.U1[1]>0x5F) && (PacketBuffer.U1[2]>0x5F))
204 gpuDrawFT3(gpuPolySpanDrivers [Blending_Mode | TEXT_MODE | Masking | Blending | PixelMSB]);
205 else
206 gpuDrawFT3(gpuPolySpanDrivers [Blending_Mode | TEXT_MODE | Masking | Blending | Lighting | PixelMSB]);
207 break;
208
209 case 0x28:
210 case 0x29:
211 case 0x2A:
212 case 0x2B: {
213 const PP gpuPolySpanDriver = gpuPolySpanDrivers [Blending_Mode | Masking | Blending | PixelMSB];
214 gpuDrawF3(gpuPolySpanDriver);
215 PacketBuffer.U4[1] = PacketBuffer.U4[4];
216 gpuDrawF3(gpuPolySpanDriver);
217 break;
218 }
219
220 case 0x2C:
221 case 0x2D:
222 case 0x2E:
223 case 0x2F: {
224 gpuSetCLUT (PacketBuffer.U4[2] >> 16);
225 gpuSetTexture(PacketBuffer.U4[4] >> 16);
226 PP gpuPolySpanDriver;
227 if ((PacketBuffer.U1[0]>0x5F) && (PacketBuffer.U1[1]>0x5F) && (PacketBuffer.U1[2]>0x5F))
228 gpuPolySpanDriver = gpuPolySpanDrivers [Blending_Mode | TEXT_MODE | Masking | Blending | PixelMSB];
229 else
230 gpuPolySpanDriver = gpuPolySpanDrivers [Blending_Mode | TEXT_MODE | Masking | Blending | Lighting | PixelMSB];
231 gpuDrawFT3(gpuPolySpanDriver);
232 PacketBuffer.U4[1] = PacketBuffer.U4[7];
233 PacketBuffer.U4[2] = PacketBuffer.U4[8];
234 gpuDrawFT3(gpuPolySpanDriver);
235 break;
236 }
237
238 case 0x30:
239 case 0x31:
240 case 0x32:
241 case 0x33:
242 gpuDrawG3(gpuPolySpanDrivers [Blending_Mode | Masking | Blending | 129 | PixelMSB]);
243 break;
244
245 case 0x34:
246 case 0x35:
247 case 0x36:
248 case 0x37:
249 gpuSetCLUT (PacketBuffer.U4[2] >> 16);
250 gpuSetTexture (PacketBuffer.U4[5] >> 16);
251 gpuDrawGT3(gpuPolySpanDrivers [Blending_Mode | TEXT_MODE | Masking | Blending | ((Lighting)?129:0) | PixelMSB]);
252 break;
253
254 case 0x38:
255 case 0x39:
256 case 0x3A:
257 case 0x3B: {
258 const PP gpuPolySpanDriver = gpuPolySpanDrivers [Blending_Mode | Masking | Blending | 129 | PixelMSB];
259 gpuDrawG3(gpuPolySpanDriver);
260 PacketBuffer.U4[0] = PacketBuffer.U4[6];
261 PacketBuffer.U4[1] = PacketBuffer.U4[7];
262 gpuDrawG3(gpuPolySpanDriver);
263 break;
264 }
265
266 case 0x3C:
267 case 0x3D:
268 case 0x3E:
269 case 0x3F: {
270 gpuSetCLUT (PacketBuffer.U4[2] >> 16);
271 gpuSetTexture (PacketBuffer.U4[5] >> 16);
272 const PP gpuPolySpanDriver = gpuPolySpanDrivers [Blending_Mode | TEXT_MODE | Masking | Blending | ((Lighting)?129:0) | PixelMSB];
273 gpuDrawGT3(gpuPolySpanDriver);
274 PacketBuffer.U4[0] = PacketBuffer.U4[9];
275 PacketBuffer.U4[1] = PacketBuffer.U4[10];
276 PacketBuffer.U4[2] = PacketBuffer.U4[11];
277 gpuDrawGT3(gpuPolySpanDriver);
278 break;
279 }
280
281 case 0x40:
282 case 0x41:
283 case 0x42:
284 case 0x43:
285 gpuDrawLF(gpuPixelDrivers [ (Blending_Mode | Masking | Blending | (PixelMSB>>3)) >> 1]);
286 break;
287
288 case 0x48 ... 0x4F:
289 {
290 u32 num_vertexes = 1;
291 u32 *list_position = &(list[2]);
292
293 gpuDrawLF(gpuPixelDrivers [ (Blending_Mode | Masking | Blending | (PixelMSB>>3)) >> 1]);
294
295 while(1)
296 {
297 PacketBuffer.U4[1] = PacketBuffer.U4[2];
298 PacketBuffer.U4[2] = *list_position++;
299 gpuDrawLF(gpuPixelDrivers [ (Blending_Mode | Masking | Blending | (PixelMSB>>3)) >> 1]);
300
301 num_vertexes++;
302 if((*list_position & 0xf000f000) == 0x50005000 || list_position >= list_end)
303 break;
304 }
305
306 len += (num_vertexes - 2);
307 break;
308 }
309
310 case 0x50:
311 case 0x51:
312 case 0x52:
313 case 0x53:
314 gpuDrawLG(gpuPixelDrivers [ (Blending_Mode | Masking | Blending | (PixelMSB>>3)) >> 1]);
315 break;
316
317 case 0x58 ... 0x5F:
318 {
319 u32 num_vertexes = 1;
320 u32 *list_position = &(list[2]);
321
322 gpuDrawLG(gpuPixelDrivers [ (Blending_Mode | Masking | Blending | (PixelMSB>>3)) >> 1]);
323
324 while(1)
325 {
326 PacketBuffer.U4[0] = PacketBuffer.U4[2];
327 PacketBuffer.U4[1] = PacketBuffer.U4[3];
328 PacketBuffer.U4[2] = *list_position++;
329 PacketBuffer.U4[3] = *list_position++;
330 gpuDrawLG(gpuPixelDrivers [ (Blending_Mode | Masking | Blending | (PixelMSB>>3)) >> 1]);
331
332 num_vertexes++;
333 if((*list_position & 0xf000f000) == 0x50005000 || list_position >= list_end)
334 break;
335 }
336
337 len += (num_vertexes - 2) * 2;
338 break;
339 }
340
341 case 0x60:
342 case 0x61:
343 case 0x62:
344 case 0x63:
345 gpuDrawT(gpuTileSpanDrivers [Blending_Mode | Masking | Blending | (PixelMSB>>3)]);
346 break;
347
348 case 0x64:
349 case 0x65:
350 case 0x66:
351 case 0x67:
352 gpuSetCLUT (PacketBuffer.U4[2] >> 16);
353 gpuSetTexture (GPU_GP1);
354 if ((PacketBuffer.U1[0]>0x5F) && (PacketBuffer.U1[1]>0x5F) && (PacketBuffer.U1[2]>0x5F))
355 gpuDrawS(gpuSpriteSpanDrivers [Blending_Mode | TEXT_MODE | Masking | Blending | (enableAbbeyHack<<7) | PixelMSB]);
356 else
357 gpuDrawS(gpuSpriteSpanDrivers [Blending_Mode | TEXT_MODE | Masking | Blending | Lighting | (enableAbbeyHack<<7) | PixelMSB]);
358 break;
359
360 case 0x68:
361 case 0x69:
362 case 0x6A:
363 case 0x6B:
364 PacketBuffer.U4[2] = 0x00010001;
365 gpuDrawT(gpuTileSpanDrivers [Blending_Mode | Masking | Blending | (PixelMSB>>3)]);
366 break;
367
368 case 0x70:
369 case 0x71:
370 case 0x72:
371 case 0x73:
372 PacketBuffer.U4[2] = 0x00080008;
373 gpuDrawT(gpuTileSpanDrivers [Blending_Mode | Masking | Blending | (PixelMSB>>3)]);
374 break;
375
376 case 0x74:
377 case 0x75:
378 case 0x76:
379 case 0x77:
380 PacketBuffer.U4[3] = 0x00080008;
381 gpuSetCLUT (PacketBuffer.U4[2] >> 16);
382 gpuSetTexture (GPU_GP1);
383 if ((PacketBuffer.U1[0]>0x5F) && (PacketBuffer.U1[1]>0x5F) && (PacketBuffer.U1[2]>0x5F))
384 gpuDrawS(gpuSpriteSpanDrivers [Blending_Mode | TEXT_MODE | Masking | Blending | (enableAbbeyHack<<7) | PixelMSB]);
385 else
386 gpuDrawS(gpuSpriteSpanDrivers [Blending_Mode | TEXT_MODE | Masking | Blending | Lighting | (enableAbbeyHack<<7) | PixelMSB]);
387 break;
388
389 case 0x78:
390 case 0x79:
391 case 0x7A:
392 case 0x7B:
393 PacketBuffer.U4[2] = 0x00100010;
394 gpuDrawT(gpuTileSpanDrivers [Blending_Mode | Masking | Blending | (PixelMSB>>3)]);
395 break;
396
397 case 0x7C:
398 case 0x7D:
399#ifdef __arm__
400 if ((GPU_GP1 & 0x180) == 0 && (Masking | PixelMSB) == 0)
401 {
402 gpuSetCLUT (PacketBuffer.U4[2] >> 16);
403 gpuSetTexture (GPU_GP1);
404 gpuDrawS16();
405 break;
406 }
407 // fallthrough
408#endif
409 case 0x7E:
410 case 0x7F:
411 PacketBuffer.U4[3] = 0x00100010;
412 gpuSetCLUT (PacketBuffer.U4[2] >> 16);
413 gpuSetTexture (GPU_GP1);
414 if ((PacketBuffer.U1[0]>0x5F) && (PacketBuffer.U1[1]>0x5F) && (PacketBuffer.U1[2]>0x5F))
415 gpuDrawS(gpuSpriteSpanDrivers [Blending_Mode | TEXT_MODE | Masking | Blending | (enableAbbeyHack<<7) | PixelMSB]);
416 else
417 gpuDrawS(gpuSpriteSpanDrivers [Blending_Mode | TEXT_MODE | Masking | Blending | Lighting | (enableAbbeyHack<<7) | PixelMSB]);
418 break;
419
420 case 0x80: // vid -> vid
421 gpuMoveImage(); // prim handles updateLace && skip
422 break;
423#ifdef TEST
424 case 0xA0: // sys -> vid
425 {
426 u32 load_width = list[2] & 0xffff;
427 u32 load_height = list[2] >> 16;
428 u32 load_size = load_width * load_height;
429
430 len += load_size / 2;
431 break;
432 }
433 case 0xC0:
434 break;
435#else
436 case 0xA0: // sys ->vid
437 case 0xC0: // vid -> sys
438 goto breakloop;
439#endif
440 case 0xE1: {
441 const u32 temp = PacketBuffer.U4[0];
442 GPU_GP1 = (GPU_GP1 & ~0x000007FF) | (temp & 0x000007FF);
443 gpuSetTexture(temp);
444 gpu.ex_regs[1] = temp;
445 break;
446 }
447 case 0xE2: {
448 static const u8 TextureMask[32] = {
449 255, 7, 15, 7, 31, 7, 15, 7, 63, 7, 15, 7, 31, 7, 15, 7,
450 127, 7, 15, 7, 31, 7, 15, 7, 63, 7, 15, 7, 31, 7, 15, 7
451 };
452 const u32 temp = PacketBuffer.U4[0];
453 TextureWindow[0] = ((temp >> 10) & 0x1F) << 3;
454 TextureWindow[1] = ((temp >> 15) & 0x1F) << 3;
455 TextureWindow[2] = TextureMask[(temp >> 0) & 0x1F];
456 TextureWindow[3] = TextureMask[(temp >> 5) & 0x1F];
457 gpuSetTexture(GPU_GP1);
458 gpu.ex_regs[2] = temp;
459 break;
460 }
461 case 0xE3: {
462 const u32 temp = PacketBuffer.U4[0];
463 DrawingArea[0] = temp & 0x3FF;
464 DrawingArea[1] = (temp >> 10) & 0x3FF;
465 gpu.ex_regs[3] = temp;
466 break;
467 }
468 case 0xE4: {
469 const u32 temp = PacketBuffer.U4[0];
470 DrawingArea[2] = (temp & 0x3FF) + 1;
471 DrawingArea[3] = ((temp >> 10) & 0x3FF) + 1;
472 gpu.ex_regs[4] = temp;
473 break;
474 }
475 case 0xE5: {
476 const u32 temp = PacketBuffer.U4[0];
477 DrawingOffset[0] = ((long)temp<<(32-11))>>(32-11);
478 DrawingOffset[1] = ((long)temp<<(32-22))>>(32-11);
479 gpu.ex_regs[5] = temp;
480 break;
481 }
482 case 0xE6: {
483 const u32 temp = PacketBuffer.U4[0];
484 Masking = (temp & 0x2) << 1;
485 PixelMSB =(temp & 0x1) << 8;
486 gpu.ex_regs[6] = temp;
487 break;
488 }
489 }
490 }
491
492breakloop:
493 gpu.ex_regs[1] &= ~0x1ff;
494 gpu.ex_regs[1] |= GPU_GP1 & 0x1ff;
495
496 *last_cmd = cmd;
497 return list - list_start;
498}
499
500void renderer_sync_ecmds(uint32_t *ecmds)
501{
502 int dummy;
503 do_cmd_list(&ecmds[1], 6, &dummy);
504}
505
506void renderer_update_caches(int x, int y, int w, int h)
507{
508}
509
510void renderer_flush_queues(void)
511{
512}
513
514void renderer_set_interlace(int enable, int is_odd)
515{
516}
517
518#ifndef TEST
519
520#include "../../frontend/plugin_lib.h"
521
522void renderer_set_config(const struct rearmed_cbs *cbs)
523{
524 force_interlace = cbs->gpu_unai.lineskip;
525 enableAbbeyHack = cbs->gpu_unai.abe_hack;
526 light = !cbs->gpu_unai.no_light;
527 blend = !cbs->gpu_unai.no_blend;
528}
529
530#endif
531
532// vim:shiftwidth=2:expandtab