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