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