4 //#include <cpu-features.h>
6 #include "m64p_types.h"
7 #include "m64p_plugin.h"
18 #include "ShaderCombiner.h"
20 #include "FrameSkipper.h"
23 //#include "ae_bridge.h"
25 ptr_ConfigGetSharedDataFilepath ConfigGetSharedDataFilepath = NULL;
27 static FrameSkipper frameSkipper;
29 u32 last_good_ucode = (u32) -1;
30 void (*CheckInterrupts)( void );
31 void (*renderCallback)() = NULL;
35 EXPORT m64p_error CALL PluginStartup(m64p_dynlib_handle CoreLibHandle,
36 void *Context, void (*DebugCallback)(void *, int, const char *))
38 printf("GLES2N64 Plugin StartUp\n");
39 ConfigGetSharedDataFilepath = (ptr_ConfigGetSharedDataFilepath)
40 dlsym(CoreLibHandle, "ConfigGetSharedDataFilepath");
43 /* if (android_getCpuFamily() == ANDROID_CPU_FAMILY_ARM &&
44 (android_getCpuFeatures() & ANDROID_CPU_ARM_FEATURE_NEON) != 0)*/
50 return M64ERR_SUCCESS;
53 EXPORT m64p_error CALL PluginShutdown(void)
57 EXPORT m64p_error CALL PluginGetVersion(m64p_plugin_type *PluginType,
58 int *PluginVersion, int *APIVersion, const char **PluginNamePtr,
61 /* set version info */
62 if (PluginType != NULL)
63 *PluginType = M64PLUGIN_GFX;
65 if (PluginVersion != NULL)
66 *PluginVersion = PLUGIN_VERSION;
68 if (APIVersion != NULL)
69 *APIVersion = PLUGIN_API_VERSION;
71 if (PluginNamePtr != NULL)
72 *PluginNamePtr = PLUGIN_NAME;
74 if (Capabilities != NULL)
79 return M64ERR_SUCCESS;
82 EXPORT void CALL ChangeWindow (void)
86 EXPORT void CALL MoveScreen (int xpos, int ypos)
90 EXPORT int CALL InitiateGFX (GFX_INFO Gfx_Info)
92 printf("InitateGFX\n");
95 RDRAM = Gfx_Info.RDRAM;
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;
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;
122 CheckInterrupts = Gfx_Info.CheckInterrupts;
125 Config_LoadRomConfig(Gfx_Info.HEADER);
128 if( config.autoFrameSkip )
129 frameSkipper.setSkips( FrameSkipper::AUTO, config.maxFrameSkip );
131 frameSkipper.setSkips( FrameSkipper::MANUAL, config.maxFrameSkip );
138 EXPORT void CALL ProcessDList(void)
143 if (config.autoFrameSkip)
145 OGL_UpdateFrameTime();
147 if (OGL.consecutiveSkips < 1)
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))
155 OGL.consecutiveSkips++;
159 *REG.MI_INTR |= MI_INTR_SP | MI_INTR_DP;
165 else if ((OGL.frame_vsync % config.frameRenderRate) != 0)
170 *REG.MI_INTR |= MI_INTR_SP | MI_INTR_DP;
175 if (frameSkipper.willSkipNext())
181 /* avoid hang on frameskip */
182 // *REG.MI_INTR |= MI_INTR_DP;
183 // CheckInterrupts();
184 *REG.MI_INTR |= MI_INTR_SP | MI_INTR_DP;
189 OGL.consecutiveSkips = 0;
191 OGL.mustRenderDlist = true;
194 EXPORT void CALL ProcessRDPList(void)
198 EXPORT void CALL ResizeVideoOutput(int Width, int Height)
202 EXPORT void CALL RomClosed (void)
204 OGL_Stop(); // paulscode, OGL_Stop missing from Yongzh's code
207 EXPORT int CALL RomOpen (void)
212 OGL.frame_prevdl = -1;
213 OGL.mustRenderDlist = false;
215 frameSkipper.setTargetFPS(config.romPAL ? 50 : 60);
219 EXPORT void CALL RomResumed(void)
221 frameSkipper.start();
224 EXPORT void CALL ShowCFB (void)
228 EXPORT void CALL UpdateScreen (void)
230 frameSkipper.update();
232 //has there been any display lists since last update
233 if (OGL.frame_prevdl == OGL.frame_dl) return;
235 OGL.frame_prevdl = OGL.frame_dl;
237 if (OGL.frame_dl > 0) OGL.frame_vsync++;
239 if (OGL.mustRenderDlist)
241 OGL.screenUpdate=true;
243 OGL.mustRenderDlist = false;
247 EXPORT void CALL ViStatusChanged (void)
251 EXPORT void CALL ViWidthChanged (void)
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
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
266 Since depth buffer is also being watched, the reported addr
267 may belong to depth buffer
268 input: addr rdram address
270 size 1 = uint8, 2 = uint16, 4 = uint32
272 *******************************************************************/
274 EXPORT void CALL FBRead(u32 addr)
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.
283 Since depth buffer is also being watched, the reported addr
284 may belong to depth buffer
286 input: addr rdram address
288 size 1 = uint8, 2 = uint16, 4 = uint32
290 *******************************************************************/
292 EXPORT void CALL FBWrite(u32 addr, u32 size)
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
305 = 2 word (16 bit) <-- this is N64 default depth buffer format
308 when frame buffer information is not available yet, set all values
309 in the FrameBufferInfo structure to 0
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 ************************************************************************/
318 EXPORT void CALL FBGetFrameBufferInfo(void *p)
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)
325 /* TODO: 'int front' was added in 1.99.4. What to do with this here? */
326 OGL_ReadScreen(dest, width, height);
329 EXPORT void CALL SetRenderingCallback(void (*callback)())
331 renderCallback = callback;
334 EXPORT void CALL SetFrameSkipping(bool autoSkip, int maxSkips)
336 frameSkipper.setSkips(
337 autoSkip ? FrameSkipper::AUTO : FrameSkipper::MANUAL,
341 EXPORT void CALL SetStretchVideo(bool stretch)
343 config.stretchVideo = stretch;
346 EXPORT void CALL StartGL()
351 EXPORT void CALL StopGL()
356 EXPORT void CALL ResizeGL(int width, int height)
358 const float ratio = (config.romPAL ? 9.0f/11.0f : 0.75f);
359 int videoWidth = width;
360 int videoHeight = height;
362 if (!config.stretchVideo) {
363 videoWidth = (int) (height / ratio);
364 if (videoWidth > width) {
366 videoHeight = (int) (width * ratio);
369 int x = (width - videoWidth) / 2;
370 int y = (height - videoHeight) / 2;
372 OGL_ResizeWindow(x, y, videoWidth, videoHeight);