diff --git a/BizHawk.Emulation/Consoles/Nintendo/N64/N64.cs b/BizHawk.Emulation/Consoles/Nintendo/N64/N64.cs index 6bd2dfdd11..ff5ef90235 100644 --- a/BizHawk.Emulation/Consoles/Nintendo/N64/N64.cs +++ b/BizHawk.Emulation/Consoles/Nintendo/N64/N64.cs @@ -158,7 +158,8 @@ namespace BizHawk.Emulation.Consoles.Nintendo.N64 M64CMD_CORE_STATE_SET, M64CMD_READ_SCREEN, M64CMD_RESET, - M64CMD_ADVANCE_FRAME + M64CMD_ADVANCE_FRAME, + M64CMD_SET_VI_CALLBACK }; enum m64p_emu_state @@ -192,6 +193,9 @@ namespace BizHawk.Emulation.Consoles.Nintendo.N64 [UnmanagedFunctionPointer(CallingConvention.Cdecl)] delegate m64p_error CoreDoCommandFrameCallback(m64p_command Command, int ParamInt, FrameCallback ParamPtr); CoreDoCommandFrameCallback m64pCoreDoCommandFrameCallback; + [UnmanagedFunctionPointer(CallingConvention.Cdecl)] + delegate m64p_error CoreDoCommandVICallback(m64p_command Command, int ParamInt, VICallback ParamPtr); + CoreDoCommandVICallback m64pCoreDoCommandVICallback; // Graphics plugin specific [UnmanagedFunctionPointer(CallingConvention.Cdecl)] @@ -216,6 +220,13 @@ namespace BizHawk.Emulation.Consoles.Nintendo.N64 int width = 0; int height = 0; GFXReadScreen2(m64p_FrameBuffer, ref width, ref height, 0); + //m64pFrameComplete = true; + } + + public delegate void VICallback(); + VICallback m64pVICallback; + public void FrameComplete() + { m64pFrameComplete = true; } @@ -243,6 +254,7 @@ namespace BizHawk.Emulation.Consoles.Nintendo.N64 m64pCoreDoCommandPtr = (CoreDoCommandPtr)Marshal.GetDelegateForFunctionPointer(GetProcAddress(CoreDll, "CoreDoCommand"), typeof(CoreDoCommandPtr)); m64pCoreDoCommandRefInt = (CoreDoCommandRefInt)Marshal.GetDelegateForFunctionPointer(GetProcAddress(CoreDll, "CoreDoCommand"), typeof(CoreDoCommandRefInt)); m64pCoreDoCommandFrameCallback = (CoreDoCommandFrameCallback)Marshal.GetDelegateForFunctionPointer(GetProcAddress(CoreDll, "CoreDoCommand"), typeof(CoreDoCommandFrameCallback)); + m64pCoreDoCommandVICallback = (CoreDoCommandVICallback)Marshal.GetDelegateForFunctionPointer(GetProcAddress(CoreDll, "CoreDoCommand"), typeof(CoreDoCommandVICallback)); m64pCoreAttachPlugin = (CoreAttachPlugin)Marshal.GetDelegateForFunctionPointer(GetProcAddress(CoreDll, "CoreAttachPlugin"), typeof(CoreAttachPlugin)); GfxPluginStartup = (PluginStartup)Marshal.GetDelegateForFunctionPointer(GetProcAddress(GfxDll, "PluginStartup"), typeof(PluginStartup)); @@ -272,6 +284,10 @@ namespace BizHawk.Emulation.Consoles.Nintendo.N64 m64pFrameCallback = new FrameCallback(Getm64pFrameBuffer); result = m64pCoreDoCommandFrameCallback(m64p_command.M64CMD_SET_FRAME_CALLBACK, 0, m64pFrameCallback); + // Set up the vi callback function + m64pVICallback = new VICallback(FrameComplete); + result = m64pCoreDoCommandVICallback(m64p_command.M64CMD_SET_VI_CALLBACK, 0, m64pVICallback); + m64pEmulator = new Thread(ExecuteEmulator); m64pEmulator.Start(); diff --git a/BizHawk.MultiClient/output/dll/mupen64plus.dll b/BizHawk.MultiClient/output/dll/mupen64plus.dll index 8436fb01ff..ba236498d3 100644 Binary files a/BizHawk.MultiClient/output/dll/mupen64plus.dll and b/BizHawk.MultiClient/output/dll/mupen64plus.dll differ diff --git a/libmupen64plus/mupen64plus-core/src/api/frontend.c b/libmupen64plus/mupen64plus-core/src/api/frontend.c index b3fefab5e4..9a59ee1790 100644 --- a/libmupen64plus/mupen64plus-core/src/api/frontend.c +++ b/libmupen64plus/mupen64plus-core/src/api/frontend.c @@ -266,6 +266,9 @@ EXPORT m64p_error CALL CoreDoCommand(m64p_command Command, int ParamInt, void *P return M64ERR_SUCCESS; case M64CMD_SET_FRAME_CALLBACK: g_FrameCallback = (m64p_frame_callback) ParamPtr; + return M64ERR_SUCCESS; + case M64CMD_SET_VI_CALLBACK: + g_VICallback = (m64p_vi_callback) ParamPtr; return M64ERR_SUCCESS; case M64CMD_TAKE_NEXT_SCREENSHOT: if (!g_EmulatorRunning) diff --git a/libmupen64plus/mupen64plus-core/src/api/m64p_types.h b/libmupen64plus/mupen64plus-core/src/api/m64p_types.h index 07fe3b83b7..bb08162c44 100644 --- a/libmupen64plus/mupen64plus-core/src/api/m64p_types.h +++ b/libmupen64plus/mupen64plus-core/src/api/m64p_types.h @@ -151,7 +151,8 @@ typedef enum { M64CMD_CORE_STATE_SET, M64CMD_READ_SCREEN, M64CMD_RESET, - M64CMD_ADVANCE_FRAME + M64CMD_ADVANCE_FRAME, + M64CMD_SET_VI_CALLBACK } m64p_command; typedef struct { diff --git a/libmupen64plus/mupen64plus-core/src/main/main.c b/libmupen64plus/mupen64plus-core/src/main/main.c index 215519a333..449563ed13 100644 --- a/libmupen64plus/mupen64plus-core/src/main/main.c +++ b/libmupen64plus/mupen64plus-core/src/main/main.c @@ -73,6 +73,7 @@ m64p_handle g_CoreConfig = NULL; m64p_frame_callback g_FrameCallback = NULL; +m64p_vi_callback g_VICallback = NULL; int g_MemHasBeenBSwapped = 0; // store byte-swapped flag so we don't swap twice when re-playing game int g_EmulatorRunning = 0; // need separate boolean to tell if emulator is running, since --nogui doesn't use a thread @@ -652,12 +653,6 @@ void new_frame(void) /* advance the current frame */ l_CurrentFrame++; - - if (l_FrameAdvance) { - rompause = 1; - l_FrameAdvance = 0; - StateChanged(M64CORE_EMU_STATE, M64EMU_PAUSED); - } } void new_vi(void) @@ -709,6 +704,14 @@ void new_vi(void) LastFPSTime = CurrentFPSTime ; end_section(IDLE_SECTION); + if (g_VICallback != NULL) + (*g_VICallback)(); + + if (l_FrameAdvance) { + rompause = 1; + l_FrameAdvance = 0; + StateChanged(M64CORE_EMU_STATE, M64EMU_PAUSED); + } } /********************************************************************************************************* diff --git a/libmupen64plus/mupen64plus-core/src/main/main.h b/libmupen64plus/mupen64plus-core/src/main/main.h index d034c909e4..295c8e5fc4 100644 --- a/libmupen64plus/mupen64plus-core/src/main/main.h +++ b/libmupen64plus/mupen64plus-core/src/main/main.h @@ -32,6 +32,7 @@ extern int g_MemHasBeenBSwapped; extern int g_EmulatorRunning; extern m64p_frame_callback g_FrameCallback; +extern m64p_vi_callback g_VICallback; const char* get_savestatepath(void); const char* get_savesrampath(void);