psxmem: Add support for Lightrec's custom mem init sequence
[pcsx_rearmed.git] / plugins / dfxvideo / gpulib_if.c
1 /***************************************************************************
2     copyright            : (C) 2001 by Pete Bernert, 2011 notaz
3
4  ***************************************************************************/
5 /***************************************************************************
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. See also the license.txt file for *
11  *   additional informations.                                              *
12  *                                                                         *
13  ***************************************************************************/
14
15 #include <stdio.h>
16 #include <stdlib.h>
17 #include <string.h>
18 #include "../gpulib/gpu.h"
19
20 #ifdef THREAD_RENDERING
21 #include "../gpulib/gpulib_thread_if.h"
22 #define do_cmd_list real_do_cmd_list
23 #define renderer_init real_renderer_init
24 #define renderer_finish real_renderer_finish
25 #define renderer_sync_ecmds real_renderer_sync_ecmds
26 #define renderer_update_caches real_renderer_update_caches
27 #define renderer_flush_queues real_renderer_flush_queues
28 #define renderer_set_interlace real_renderer_set_interlace
29 #define renderer_set_config real_renderer_set_config
30 #define renderer_notify_res_change real_renderer_notify_res_change
31 #define renderer_notify_update_lace real_renderer_notify_update_lace
32 #define renderer_sync real_renderer_sync
33 #define ex_regs scratch_ex_regs
34 #endif
35
36 #define u32 uint32_t
37
38 #define INFO_TW        0
39 #define INFO_DRAWSTART 1
40 #define INFO_DRAWEND   2
41 #define INFO_DRAWOFF   3
42
43 #define SHADETEXBIT(x) ((x>>24) & 0x1)
44 #define SEMITRANSBIT(x) ((x>>25) & 0x1)
45 #define PSXRGB(r,g,b) ((g<<10)|(b<<5)|r)
46
47 #define DATAREGISTERMODES unsigned short
48
49 #define DR_NORMAL        0
50 #define DR_VRAMTRANSFER  1
51
52 #define GPUSTATUS_READYFORVRAM        0x08000000
53
54 // byteswappings
55
56 #define SWAP16(x) ({ uint16_t y=(x); (((y)>>8 & 0xff) | ((y)<<8 & 0xff00)); })
57 #define SWAP32(x) ({ uint32_t y=(x); (((y)>>24 & 0xfful) | ((y)>>8 & 0xff00ul) | ((y)<<8 & 0xff0000ul) | ((y)<<24 & 0xff000000ul)); })
58
59 #ifdef __BIG_ENDIAN__
60
61 // big endian config
62 #define HOST2LE32(x) SWAP32(x)
63 #define HOST2BE32(x) (x)
64 #define LE2HOST32(x) SWAP32(x)
65 #define BE2HOST32(x) (x)
66
67 #define HOST2LE16(x) SWAP16(x)
68 #define HOST2BE16(x) (x)
69 #define LE2HOST16(x) SWAP16(x)
70 #define BE2HOST16(x) (x)
71
72 #else
73
74 // little endian config
75 #define HOST2LE32(x) (x)
76 #define HOST2BE32(x) SWAP32(x)
77 #define LE2HOST32(x) (x)
78 #define BE2HOST32(x) SWAP32(x)
79
80 #define HOST2LE16(x) (x)
81 #define HOST2BE16(x) SWAP16(x)
82 #define LE2HOST16(x) (x)
83 #define BE2HOST16(x) SWAP16(x)
84
85 #endif
86
87 #define GETLEs16(X) ((int16_t)GETLE16((uint16_t *)X))
88 #define GETLEs32(X) ((int16_t)GETLE32((uint16_t *)X))
89
90 #define GETLE16(X) LE2HOST16(*(uint16_t *)X)
91 #define GETLE32_(X) LE2HOST32(*(uint32_t *)X)
92 #define GETLE16D(X) ({uint32_t val = GETLE32(X); (val<<16 | val >> 16);})
93 #define PUTLE16(X, Y) do{*((uint16_t *)X)=HOST2LE16((uint16_t)Y);}while(0)
94 #define PUTLE32_(X, Y) do{*((uint32_t *)X)=HOST2LE16((uint32_t)Y);}while(0)
95 #ifdef __arm__
96 #define GETLE32(X) (*(uint16_t *)(X)|(((uint16_t *)(X))[1]<<16))
97 #define PUTLE32(X, Y) do{uint16_t *p_=(uint16_t *)(X);uint32_t y_=Y;p_[0]=y_;p_[1]=y_>>16;}while(0)
98 #else
99 #define GETLE32 GETLE32_
100 #define PUTLE32 PUTLE32_
101 #endif
102
103 /////////////////////////////////////////////////////////////////////////////
104
105 typedef struct VRAMLOADTTAG
106 {
107  short x;
108  short y;
109  short Width;
110  short Height;
111  short RowsRemaining;
112  short ColsRemaining;
113  unsigned short *ImagePtr;
114 } VRAMLoad_t;
115
116 /////////////////////////////////////////////////////////////////////////////
117
118 typedef struct PSXPOINTTAG
119 {
120  int32_t x;
121  int32_t y;
122 } PSXPoint_t;
123
124 typedef struct PSXSPOINTTAG
125 {
126  short x;
127  short y;
128 } PSXSPoint_t;
129
130 typedef struct PSXRECTTAG
131 {
132  short x0;
133  short x1;
134  short y0;
135  short y1;
136 } PSXRect_t;
137
138 // linux defines for some windows stuff
139
140 #define FALSE 0
141 #define TRUE 1
142 #define BOOL unsigned short
143 #define LOWORD(l)           ((unsigned short)(l))
144 #define HIWORD(l)           ((unsigned short)(((uint32_t)(l) >> 16) & 0xFFFF))
145 #define max(a,b)            (((a) > (b)) ? (a) : (b))
146 #define min(a,b)            (((a) < (b)) ? (a) : (b))
147 #define DWORD uint32_t
148 #ifndef __int64
149 #define __int64 long long int
150 #endif
151
152 typedef struct RECTTAG
153 {
154  int left;
155  int top;
156  int right;
157  int bottom;
158 }RECT;
159
160 /////////////////////////////////////////////////////////////////////////////
161
162 typedef struct TWINTAG
163 {
164  PSXRect_t  Position;
165  int xmask, ymask;
166 } TWin_t;
167
168 /////////////////////////////////////////////////////////////////////////////
169
170 typedef struct PSXDISPLAYTAG
171 {
172  PSXPoint_t  DisplayModeNew;
173  PSXPoint_t  DisplayMode;
174  PSXPoint_t  DisplayPosition;
175  PSXPoint_t  DisplayEnd;
176
177  int32_t        Double;
178  int32_t        Height;
179  int32_t        PAL;
180  int32_t        InterlacedNew;
181  int32_t        Interlaced;
182  int32_t        RGB24New;
183  int32_t        RGB24;
184  PSXSPoint_t DrawOffset;
185  int32_t        Disabled;
186  PSXRect_t   Range;
187
188 } PSXDisplay_t;
189
190 /////////////////////////////////////////////////////////////////////////////
191
192 // draw.c
193
194 extern int32_t           GlobalTextAddrX,GlobalTextAddrY,GlobalTextTP;
195 extern int32_t           GlobalTextABR,GlobalTextPAGE;
196 extern short          ly0,lx0,ly1,lx1,ly2,lx2,ly3,lx3;
197 extern long           lLowerpart;
198 extern BOOL           bCheckMask;
199 extern unsigned short sSetMask;
200 extern unsigned long  lSetMask;
201 extern short          g_m1;
202 extern short          g_m2;
203 extern short          g_m3;
204 extern short          DrawSemiTrans;
205
206 // prim.c
207
208 extern BOOL           bUsingTWin;
209 extern TWin_t         TWin;
210 extern void (*primTableJ[256])(unsigned char *);
211 extern void (*primTableSkip[256])(unsigned char *);
212 extern unsigned short  usMirror;
213 extern int            iDither;
214 extern uint32_t  dwCfgFixes;
215 extern uint32_t  dwActFixes;
216 extern int            iUseFixes;
217 extern int            iUseDither;
218 extern BOOL           bDoVSyncUpdate;
219 extern int32_t           drawX;
220 extern int32_t           drawY;
221 extern int32_t           drawW;
222 extern int32_t           drawH;
223
224 // gpu.h
225
226 #define OPAQUEON   10
227 #define OPAQUEOFF  11
228
229 #define KEY_RESETTEXSTORE 1
230 #define KEY_SHOWFPS       2
231 #define KEY_RESETOPAQUE   4
232 #define KEY_RESETDITHER   8
233 #define KEY_RESETFILTER   16
234 #define KEY_RESETADVBLEND 32
235 #define KEY_BADTEXTURES   128
236 #define KEY_CHECKTHISOUT  256
237
238 #if !defined(__BIG_ENDIAN__) || defined(__x86_64__) || defined(__i386__)
239 #ifndef __LITTLE_ENDIAN__
240 #define __LITTLE_ENDIAN__
241 #endif
242 #endif
243
244 #ifdef __LITTLE_ENDIAN__
245 #define RED(x) (x & 0xff)
246 #define BLUE(x) ((x>>16) & 0xff)
247 #define GREEN(x) ((x>>8) & 0xff)
248 #define COLOR(x) (x & 0xffffff)
249 #elif defined __BIG_ENDIAN__
250 #define RED(x) ((x>>24) & 0xff)
251 #define BLUE(x) ((x>>8) & 0xff)
252 #define GREEN(x) ((x>>16) & 0xff)
253 #define COLOR(x) SWAP32(x & 0xffffff)
254 #endif
255
256 PSXDisplay_t      PSXDisplay;
257 unsigned char  *psxVub;
258 signed   char  *psxVsb;
259 unsigned short *psxVuw;
260 unsigned short *psxVuw_eom;
261 signed   short *psxVsw;
262 uint32_t *psxVul;
263 int32_t  *psxVsl;
264
265 long              lGPUstatusRet;
266 uint32_t          lGPUInfoVals[16];
267
268 VRAMLoad_t        VRAMWrite;
269 VRAMLoad_t        VRAMRead;
270
271 DATAREGISTERMODES DataWriteMode;
272 DATAREGISTERMODES DataReadMode;
273
274 BOOL           bCheckMask = FALSE;
275 unsigned short sSetMask = 0;
276 unsigned long  lSetMask = 0;
277 long           lLowerpart;
278
279 #include "soft.c"
280 #include "prim.c"
281
282 /////////////////////////////////////////////////////////////////////////////
283
284 static void set_vram(void *vram)
285 {
286  psxVub=vram;
287
288  psxVsb=(signed char *)psxVub;                         // different ways of accessing PSX VRAM
289  psxVsw=(signed short *)psxVub;
290  psxVsl=(int32_t *)psxVub;
291  psxVuw=(unsigned short *)psxVub;
292  psxVul=(uint32_t *)psxVub;
293
294  psxVuw_eom=psxVuw+1024*512;                           // pre-calc of end of vram
295 }
296
297 int renderer_init(void)
298 {
299  set_vram(gpu.vram);
300
301  PSXDisplay.RGB24        = FALSE;                      // init some stuff
302  PSXDisplay.Interlaced   = FALSE;
303  PSXDisplay.DrawOffset.x = 0;
304  PSXDisplay.DrawOffset.y = 0;
305  PSXDisplay.DisplayMode.x= 320;
306  PSXDisplay.DisplayMode.y= 240;
307  PSXDisplay.Disabled     = FALSE;
308  PSXDisplay.Range.x0=0;
309  PSXDisplay.Range.x1=0;
310  PSXDisplay.Double = 1;
311
312  DataWriteMode = DR_NORMAL;
313  lGPUstatusRet = 0x14802000;
314
315  return 0;
316 }
317
318 void renderer_finish(void)
319 {
320 }
321
322 void renderer_notify_res_change(void)
323 {
324 }
325
326 extern const unsigned char cmd_lengths[256];
327
328 int do_cmd_list(uint32_t *list, int list_len, int *last_cmd)
329 {
330   unsigned int cmd = 0, len;
331   uint32_t *list_start = list;
332   uint32_t *list_end = list + list_len;
333
334   for (; list < list_end; list += 1 + len)
335   {
336     cmd = *list >> 24;
337     len = cmd_lengths[cmd];
338     if (list + 1 + len > list_end) {
339       cmd = -1;
340       break;
341     }
342
343 #ifndef TEST
344     if (cmd == 0xa0 || cmd == 0xc0)
345       break; // image i/o, forward to upper layer
346     else if ((cmd & 0xf8) == 0xe0)
347       gpu.ex_regs[cmd & 7] = list[0];
348 #endif
349
350     primTableJ[cmd]((void *)list);
351
352     switch(cmd)
353     {
354       case 0x48 ... 0x4F:
355       {
356         u32 num_vertexes = 2;
357         u32 *list_position = &(list[3]);
358
359         while(1)
360         {
361           if(list_position >= list_end) {
362             cmd = -1;
363             goto breakloop;
364           }
365
366           if((*list_position & 0xf000f000) == 0x50005000)
367             break;
368
369           list_position++;
370           num_vertexes++;
371         }
372
373         len += (num_vertexes - 2);
374         break;
375       }
376
377       case 0x58 ... 0x5F:
378       {
379         u32 num_vertexes = 2;
380         u32 *list_position = &(list[4]);
381
382         while(1)
383         {
384           if(list_position >= list_end) {
385             cmd = -1;
386             goto breakloop;
387           }
388
389           if((*list_position & 0xf000f000) == 0x50005000)
390             break;
391
392           list_position += 2;
393           num_vertexes++;
394         }
395
396         len += (num_vertexes - 2) * 2;
397         break;
398       }
399
400 #ifdef TEST
401       case 0xA0:          //  sys -> vid
402       {
403         short *slist = (void *)list;
404         u32 load_width = slist[4];
405         u32 load_height = slist[5];
406         u32 load_size = load_width * load_height;
407
408         len += load_size / 2;
409         break;
410       }
411 #endif
412     }
413   }
414
415 breakloop:
416   gpu.ex_regs[1] &= ~0x1ff;
417   gpu.ex_regs[1] |= lGPUstatusRet & 0x1ff;
418
419   *last_cmd = cmd;
420   return list - list_start;
421 }
422
423 void renderer_sync_ecmds(uint32_t *ecmds)
424 {
425   cmdTexturePage((unsigned char *)&ecmds[1]);
426   cmdTextureWindow((unsigned char *)&ecmds[2]);
427   cmdDrawAreaStart((unsigned char *)&ecmds[3]);
428   cmdDrawAreaEnd((unsigned char *)&ecmds[4]);
429   cmdDrawOffset((unsigned char *)&ecmds[5]);
430   cmdSTP((unsigned char *)&ecmds[6]);
431 }
432
433 void renderer_update_caches(int x, int y, int w, int h)
434 {
435 }
436
437 void renderer_flush_queues(void)
438 {
439 }
440
441 void renderer_set_interlace(int enable, int is_odd)
442 {
443 }
444
445 void renderer_sync(void)
446 {
447 }
448
449 void renderer_notify_update_lace(int updated)
450 {
451 }
452
453 #include "../../frontend/plugin_lib.h"
454
455 void renderer_set_config(const struct rearmed_cbs *cbs)
456 {
457  iUseDither = cbs->gpu_peops.iUseDither;
458  dwActFixes = cbs->gpu_peops.dwActFixes;
459  if (cbs->pl_set_gpu_caps)
460   cbs->pl_set_gpu_caps(0);
461  set_vram(gpu.vram);
462 }