GLES2N64: Put old Frameskip code (from mupen 1.5) instead
[mupen64plus-pandora.git] / source / gles2n64 / src / gles2N64.cpp
1
2 #include <dlfcn.h>
3 #include <string.h>
4 //#include <cpu-features.h>
5
6 #include "m64p_types.h"
7 #include "m64p_plugin.h"
8
9 #include "gles2N64.h"
10 #include "Debug.h"
11 #include "OpenGL.h"
12 #include "N64.h"
13 #include "RSP.h"
14 #include "RDP.h"
15 #include "VI.h"
16 #include "Config.h"
17 #include "Textures.h"
18 #include "ShaderCombiner.h"
19 #include "3DMath.h"
20 #include "FrameSkipper.h"
21 #include "ticks.h"
22
23 //#include "ae_bridge.h"
24
25 ptr_ConfigGetSharedDataFilepath ConfigGetSharedDataFilepath = NULL;
26
27 static FrameSkipper frameSkipper;
28
29 u32         last_good_ucode = (u32) -1;
30 void        (*CheckInterrupts)( void );
31 void        (*renderCallback)() = NULL;
32
33 extern "C" {
34
35 EXPORT m64p_error CALL PluginStartup(m64p_dynlib_handle CoreLibHandle,
36         void *Context, void (*DebugCallback)(void *, int, const char *))
37 {
38 printf("GLES2N64 Plugin StartUp\n");
39     ConfigGetSharedDataFilepath = (ptr_ConfigGetSharedDataFilepath)
40             dlsym(CoreLibHandle, "ConfigGetSharedDataFilepath");
41
42 #ifdef __NEON_OPT
43 /*    if (android_getCpuFamily() == ANDROID_CPU_FAMILY_ARM &&
44             (android_getCpuFeatures() & ANDROID_CPU_ARM_FEATURE_NEON) != 0)*/
45     {
46         MathInitNeon();
47         gSPInitNeon();
48     }
49 #endif
50     return M64ERR_SUCCESS;
51 }
52
53 EXPORT m64p_error CALL PluginShutdown(void)
54 {
55 }
56
57 EXPORT m64p_error CALL PluginGetVersion(m64p_plugin_type *PluginType,
58         int *PluginVersion, int *APIVersion, const char **PluginNamePtr,
59         int *Capabilities)
60 {
61     /* set version info */
62     if (PluginType != NULL)
63         *PluginType = M64PLUGIN_GFX;
64
65     if (PluginVersion != NULL)
66         *PluginVersion = PLUGIN_VERSION;
67
68     if (APIVersion != NULL)
69         *APIVersion = PLUGIN_API_VERSION;
70     
71     if (PluginNamePtr != NULL)
72         *PluginNamePtr = PLUGIN_NAME;
73
74     if (Capabilities != NULL)
75     {
76         *Capabilities = 0;
77     }
78                     
79     return M64ERR_SUCCESS;
80 }
81
82 EXPORT void CALL ChangeWindow (void)
83 {
84 }
85
86 EXPORT void CALL MoveScreen (int xpos, int ypos)
87 {
88 }
89
90 EXPORT int CALL InitiateGFX (GFX_INFO Gfx_Info)
91 {
92 printf("InitateGFX\n");
93     DMEM = Gfx_Info.DMEM;
94     IMEM = Gfx_Info.IMEM;
95     RDRAM = Gfx_Info.RDRAM;
96
97     REG.MI_INTR = (u32*) Gfx_Info.MI_INTR_REG;
98     REG.DPC_START = (u32*) Gfx_Info.DPC_START_REG;
99     REG.DPC_END = (u32*) Gfx_Info.DPC_END_REG;
100     REG.DPC_CURRENT = (u32*) Gfx_Info.DPC_CURRENT_REG;
101     REG.DPC_STATUS = (u32*) Gfx_Info.DPC_STATUS_REG;
102     REG.DPC_CLOCK = (u32*) Gfx_Info.DPC_CLOCK_REG;
103     REG.DPC_BUFBUSY = (u32*) Gfx_Info.DPC_BUFBUSY_REG;
104     REG.DPC_PIPEBUSY = (u32*) Gfx_Info.DPC_PIPEBUSY_REG;
105     REG.DPC_TMEM = (u32*) Gfx_Info.DPC_TMEM_REG;
106
107     REG.VI_STATUS = (u32*) Gfx_Info.VI_STATUS_REG;
108     REG.VI_ORIGIN = (u32*) Gfx_Info.VI_ORIGIN_REG;
109     REG.VI_WIDTH = (u32*) Gfx_Info.VI_WIDTH_REG;
110     REG.VI_INTR = (u32*) Gfx_Info.VI_INTR_REG;
111     REG.VI_V_CURRENT_LINE = (u32*) Gfx_Info.VI_V_CURRENT_LINE_REG;
112     REG.VI_TIMING = (u32*) Gfx_Info.VI_TIMING_REG;
113     REG.VI_V_SYNC = (u32*) Gfx_Info.VI_V_SYNC_REG;
114     REG.VI_H_SYNC = (u32*) Gfx_Info.VI_H_SYNC_REG;
115     REG.VI_LEAP = (u32*) Gfx_Info.VI_LEAP_REG;
116     REG.VI_H_START = (u32*) Gfx_Info.VI_H_START_REG;
117     REG.VI_V_START = (u32*) Gfx_Info.VI_V_START_REG;
118     REG.VI_V_BURST = (u32*) Gfx_Info.VI_V_BURST_REG;
119     REG.VI_X_SCALE = (u32*) Gfx_Info.VI_X_SCALE_REG;
120     REG.VI_Y_SCALE = (u32*) Gfx_Info.VI_Y_SCALE_REG;
121
122     CheckInterrupts = Gfx_Info.CheckInterrupts;
123
124     Config_LoadConfig();
125     Config_LoadRomConfig(Gfx_Info.HEADER);
126
127     ticksInitialize();
128     if( config.autoFrameSkip )
129         frameSkipper.setSkips( FrameSkipper::AUTO, config.maxFrameSkip );
130     else
131         frameSkipper.setSkips( FrameSkipper::MANUAL, config.maxFrameSkip );
132
133         OGL_Start();
134
135     return 1;
136 }
137
138 EXPORT void CALL ProcessDList(void)
139 {
140     OGL.frame_dl++;
141
142 #if 1
143     if (config.autoFrameSkip)
144     {
145         OGL_UpdateFrameTime();
146
147         if (OGL.consecutiveSkips < 1)
148         {
149             unsigned t = 0;
150             for(int i = 0; i < OGL_FRAMETIME_NUM; i++) t += OGL.frameTime[i];
151             t *= config.targetFPS;
152             if (config.romPAL) t = (t * 5) / 6;
153             if (t > (OGL_FRAMETIME_NUM * 1000))
154             {
155                 OGL.consecutiveSkips++;
156                 OGL.frameSkipped++;
157                 RSP.busy = FALSE;
158                 RSP.DList++;
159                                 *REG.MI_INTR |= MI_INTR_SP | MI_INTR_DP;
160                                 CheckInterrupts();
161                 return;
162             }
163         }
164     }
165     else if ((OGL.frame_vsync % config.frameRenderRate) != 0)
166     {
167         OGL.frameSkipped++;
168         RSP.busy = FALSE;
169         RSP.DList++;
170         *REG.MI_INTR |= MI_INTR_SP | MI_INTR_DP;
171         CheckInterrupts();
172         return;
173     }
174 #else
175     if (frameSkipper.willSkipNext())
176     {
177         OGL.frameSkipped++;
178         RSP.busy = FALSE;
179         RSP.DList++;
180
181         /* avoid hang on frameskip */
182 //        *REG.MI_INTR |= MI_INTR_DP;
183 //        CheckInterrupts();
184         *REG.MI_INTR |= MI_INTR_SP | MI_INTR_DP;
185         CheckInterrupts();
186         return;
187     }
188 #endif
189     OGL.consecutiveSkips = 0;
190     RSP_ProcessDList();
191     OGL.mustRenderDlist = true;
192 }
193
194 EXPORT void CALL ProcessRDPList(void)
195 {
196 }
197
198 EXPORT void CALL ResizeVideoOutput(int Width, int Height)
199 {
200 }
201
202 EXPORT void CALL RomClosed (void)
203 {
204     OGL_Stop();  // paulscode, OGL_Stop missing from Yongzh's code
205 }
206
207 EXPORT int CALL RomOpen (void)
208 {
209     RSP_Init();
210     OGL.frame_vsync = 0;
211     OGL.frame_dl = 0;
212     OGL.frame_prevdl = -1;
213     OGL.mustRenderDlist = false;
214
215     frameSkipper.setTargetFPS(config.romPAL ? 50 : 60);
216     return 1;
217 }
218
219 EXPORT void CALL RomResumed(void)
220 {
221     frameSkipper.start();
222 }
223
224 EXPORT void CALL ShowCFB (void)
225 {
226 }
227
228 EXPORT void CALL UpdateScreen (void)
229 {
230     frameSkipper.update();
231
232     //has there been any display lists since last update
233     if (OGL.frame_prevdl == OGL.frame_dl) return;
234
235     OGL.frame_prevdl = OGL.frame_dl;
236
237     if (OGL.frame_dl > 0) OGL.frame_vsync++;
238
239     if (OGL.mustRenderDlist)
240     {
241         OGL.screenUpdate=true;
242         VI_UpdateScreen();
243         OGL.mustRenderDlist = false;
244     }
245 }
246
247 EXPORT void CALL ViStatusChanged (void)
248 {
249 }
250
251 EXPORT void CALL ViWidthChanged (void)
252 {
253 }
254
255 /******************************************************************
256   Function: FrameBufferRead
257   Purpose:  This function is called to notify the dll that the
258             frame buffer memory is beening read at the given address.
259             DLL should copy content from its render buffer to the frame buffer
260             in N64 RDRAM
261             DLL is responsible to maintain its own frame buffer memory addr list
262             DLL should copy 4KB block content back to RDRAM frame buffer.
263             Emulator should not call this function again if other memory
264             is read within the same 4KB range
265
266             Since depth buffer is also being watched, the reported addr
267             may belong to depth buffer
268   input:    addr        rdram address
269             val         val
270             size        1 = uint8, 2 = uint16, 4 = uint32
271   output:   none
272 *******************************************************************/ 
273
274 EXPORT void CALL FBRead(u32 addr)
275 {
276 }
277
278 /******************************************************************
279   Function: FrameBufferWrite
280   Purpose:  This function is called to notify the dll that the
281             frame buffer has been modified by CPU at the given address.
282
283             Since depth buffer is also being watched, the reported addr
284             may belong to depth buffer
285
286   input:    addr        rdram address
287             val         val
288             size        1 = uint8, 2 = uint16, 4 = uint32
289   output:   none
290 *******************************************************************/ 
291
292 EXPORT void CALL FBWrite(u32 addr, u32 size)
293 {
294 }
295
296 /************************************************************************
297 Function: FBGetFrameBufferInfo
298 Purpose:  This function is called by the emulator core to retrieve frame
299           buffer information from the video plugin in order to be able
300           to notify the video plugin about CPU frame buffer read/write
301           operations
302
303           size:
304             = 1     byte
305             = 2     word (16 bit) <-- this is N64 default depth buffer format
306             = 4     dword (32 bit)
307
308           when frame buffer information is not available yet, set all values
309           in the FrameBufferInfo structure to 0
310
311 input:    FrameBufferInfo pinfo[6]
312           pinfo is pointed to a FrameBufferInfo structure which to be
313           filled in by this function
314 output:   Values are return in the FrameBufferInfo structure
315           Plugin can return up to 6 frame buffer info
316  ************************************************************************/
317
318 EXPORT void CALL FBGetFrameBufferInfo(void *p)
319 {
320 }
321
322 // paulscode, API changed this to "ReadScreen2" in Mupen64Plus 1.99.4
323 EXPORT void CALL ReadScreen2(void *dest, int *width, int *height, int front)
324 {
325 /* TODO: 'int front' was added in 1.99.4.  What to do with this here? */
326     OGL_ReadScreen(dest, width, height);
327 }
328
329 EXPORT void CALL SetRenderingCallback(void (*callback)())
330 {
331     renderCallback = callback;
332 }
333
334 EXPORT void CALL SetFrameSkipping(bool autoSkip, int maxSkips)
335 {
336     frameSkipper.setSkips(
337             autoSkip ? FrameSkipper::AUTO : FrameSkipper::MANUAL,
338             maxSkips);
339 }
340
341 EXPORT void CALL SetStretchVideo(bool stretch)
342 {
343     config.stretchVideo = stretch;
344 }
345
346 EXPORT void CALL StartGL()
347 {
348     OGL_Start();
349 }
350
351 EXPORT void CALL StopGL()
352 {
353     OGL_Stop();
354 }
355
356 EXPORT void CALL ResizeGL(int width, int height)
357 {
358     const float ratio = (config.romPAL ? 9.0f/11.0f : 0.75f);
359     int videoWidth = width;
360     int videoHeight = height;
361
362     if (!config.stretchVideo) {
363         videoWidth = (int) (height / ratio);
364         if (videoWidth > width) {
365             videoWidth = width;
366             videoHeight = (int) (width * ratio);
367         }
368     }
369     int x = (width - videoWidth) / 2;
370     int y = (height - videoHeight) / 2;
371
372     OGL_ResizeWindow(x, y, videoWidth, videoHeight);
373 }
374
375 } // extern "C"
376