0497ddaf5b697558b3d7ce5102de59e548567666
[pcsx_rearmed.git] / plugins / gpu_neon / unai_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 "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
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 VIDEO_WIDTH 320
43
44 static bool isSkip = false; /* skip frame (info coming from GPU) */
45 static int linesInterlace = 0;  /* internal lines interlace */
46
47 #define alt_fps 0
48
49 static bool light = true; /* lighting */
50 static bool blend = true; /* blending */
51 static bool FrameToRead = false; /* load image in progress */
52 static bool FrameToWrite = false; /* store image in progress */
53
54 static bool enableAbbeyHack = false; /* Abe's Odyssey hack */
55
56 static u8 BLEND_MODE;
57 static u8 TEXT_MODE;
58 static u8 Masking;
59
60 static u16 PixelMSB;
61 static u16 PixelData;
62
63 ///////////////////////////////////////////////////////////////////////////////
64 //  GPU Global data
65 ///////////////////////////////////////////////////////////////////////////////
66
67 //  Dma Transfers info
68 static s32              px,py;
69 static s32              x_end,y_end;
70 static u16*  pvram;
71
72 static s32 PacketCount;
73 static s32 PacketIndex;
74
75 //  Rasterizer status
76 static u32 TextureWindow [4];
77 static u32 DrawingArea   [4];
78 static u32 DrawingOffset [2];
79
80 static u16* TBA;
81 static u16* CBA;
82
83 //  Inner Loops
84 static s32   u4, du4;
85 static s32   v4, dv4;
86 static s32   r4, dr4;
87 static s32   g4, dg4;
88 static s32   b4, db4;
89 static u32   lInc;
90 static u32   tInc, tMsk;
91
92 union GPUPacket
93 {
94         u32 *U4;
95         s32 *S4;
96         u16 *U2;
97         s16 *S2;
98         u8  *U1;
99         s8  *S1;
100 };
101
102 static GPUPacket PacketBuffer;
103 static u16  *GPU_FrameBuffer;
104 static u32   GPU_GP1;
105
106 ///////////////////////////////////////////////////////////////////////////////
107
108 #include "../gpu_unai/gpu_fixedpoint.h"
109
110 //  Inner loop driver instanciation file
111 #include "../gpu_unai/gpu_inner.h"
112
113 //  GPU Raster Macros
114 #define GPU_RGB16(rgb)        ((((rgb)&0xF80000)>>9)|(((rgb)&0xF800)>>6)|(((rgb)&0xF8)>>3))
115
116 #define GPU_EXPANDSIGN_POLY(x)  (((s32)(x)<<20)>>20)
117 //#define GPU_EXPANDSIGN_POLY(x)  (((s32)(x)<<21)>>21)
118 #define GPU_EXPANDSIGN_SPRT(x)  (((s32)(x)<<21)>>21)
119
120 //#define       GPU_TESTRANGE(x)      { if((u32)(x+1024) > 2047) return; }
121 #define GPU_TESTRANGE(x)      { if ((x<-1023) || (x>1023)) return; }
122
123 #define GPU_SWAP(a,b,t) {(t)=(a);(a)=(b);(b)=(t);}
124
125 // GPU internal image drawing functions
126 #include "../gpu_unai/gpu_raster_image.h"
127
128 // GPU internal line drawing functions
129 #include "../gpu_unai/gpu_raster_line.h"
130
131 // GPU internal polygon drawing functions
132 #include "../gpu_unai/gpu_raster_polygon.h"
133
134 // GPU internal sprite drawing functions
135 #include "../gpu_unai/gpu_raster_sprite.h"
136
137 // GPU command buffer execution/store
138 #include "../gpu_unai/gpu_command.h"
139
140 #define unai_do_prim(cmd, list) \
141   PacketBuffer.U4 = list; \
142   gpuSendPacketFunction(cmd)
143
144 /////////////////////////////////////////////////////////////////////////////
145
146 int renderer_init(void)
147 {
148         GPU_FrameBuffer = (u16 *)gpu.vram;
149
150         // s_invTable
151         for(int i=1;i<=(1<<TABLE_BITS);++i)
152         {
153                 double v = 1.0 / double(i);
154                 #ifdef GPU_TABLE_10_BITS
155                 v *= double(0xffffffff>>1);
156                 #else
157                 v *= double(0x80000000);
158                 #endif
159                 s_invTable[i-1]=s32(v);
160         }
161
162         return 0;
163 }
164
165 extern const unsigned char cmd_lengths[256];
166
167 void do_cmd_list(unsigned int *list, int list_len)
168 {
169   unsigned int cmd, len;
170
171   unsigned int *list_end = list + list_len;
172
173   for (; list < list_end; list += 1 + len)
174   {
175     short *slist = (short *)list;
176     cmd = *list >> 24;
177     len = cmd_lengths[cmd];
178
179     unai_do_prim(cmd, list);
180
181     switch(cmd)
182     {
183       case 0x48 ... 0x4F:
184       {
185         u32 num_vertexes = 1;
186         u32 *list_position = &(list[2]);
187
188         while(1)
189         {
190           if((*list_position & 0xf000f000) == 0x50005000 || list_position >= list_end)
191             break;
192
193           list_position++;
194           num_vertexes++;
195         }
196
197         if(num_vertexes > 2)
198           len += (num_vertexes - 2);
199
200         break;
201       }
202
203       case 0x58 ... 0x5F:
204       {
205         u32 num_vertexes = 1;
206         u32 *list_position = &(list[2]);
207
208         while(1)
209         {
210           if((*list_position & 0xf000f000) == 0x50005000 || list_position >= list_end)
211             break;
212
213           list_position += 2;
214           num_vertexes++;
215         }
216
217         if(num_vertexes > 2)
218           len += ((num_vertexes * 2) - 2);
219
220         break;
221       }
222
223       case 0xA0:          //  sys -> vid
224       {
225         u32 load_width = slist[4];
226         u32 load_height = slist[5];
227         u32 load_size = load_width * load_height;
228
229         len += load_size / 2;
230         break;
231       }
232     }
233   }
234 }
235
236 void renderer_sync_ecmds(uint32_t *ecmds)
237 {
238   unai_do_prim(0xe1, &ecmds[1]);
239   unai_do_prim(0xe2, &ecmds[2]);
240   unai_do_prim(0xe3, &ecmds[3]);
241   unai_do_prim(0xe4, &ecmds[4]);
242   unai_do_prim(0xe5, &ecmds[5]);
243   unai_do_prim(0xe6, &ecmds[6]);
244 }
245
246 void renderer_invalidate_caches(int x, int y, int w, int h)
247 {
248 }
249
250 void renderer_flush_queues(void)
251 {
252 }
253
254 #include "../../frontend/plugin_lib.h"
255
256 void renderer_set_config(const struct rearmed_cbs *cbs)
257 {
258   enableAbbeyHack = cbs->gpu_unai.abe_hack;
259   light = !cbs->gpu_unai.no_light;
260   blend = !cbs->gpu_unai.no_blend;
261 }