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