/* local functions */ static m64p_error PluginLoadTry(const char *filepath, int MapIndex) { /* try to open a shared library at the given filepath */ m64p_dynlib_handle handle; m64p_error rval = osal_dynlib_open(&handle, filepath); if (rval != M64ERR_SUCCESS) return rval; /* call the GetVersion function for the plugin and check compatibility */ ptr_PluginGetVersion PluginGetVersion = (ptr_PluginGetVersion) osal_dynlib_getproc(handle, "PluginGetVersion"); if (PluginGetVersion == NULL) { if (g_Verbose) fprintf(stderr, "Error: library '%s' is not a Mupen64Plus library.\n", filepath); osal_dynlib_close(handle); return M64ERR_INCOMPATIBLE; } m64p_plugin_type PluginType = (m64p_plugin_type) 0; int PluginVersion = 0; const char *PluginName = NULL; (*PluginGetVersion)(&PluginType, &PluginVersion, NULL, &PluginName, NULL); if (PluginType != g_PluginMap[MapIndex].type) { /* the type of this plugin doesn't match with the type that was requested by the caller */ osal_dynlib_close(handle); return M64ERR_INCOMPATIBLE; } /* the front-end doesn't talk to the plugins, so we don't care about the plugin version or api version */ /* call the plugin's initialization function and make sure it starts okay */ ptr_PluginStartup PluginStartup = (ptr_PluginStartup) osal_dynlib_getproc(handle, "PluginStartup"); if (PluginStartup == NULL) { fprintf(stderr, "Error: library '%s' broken. No PluginStartup() function found.\n", filepath); osal_dynlib_close(handle); return M64ERR_INCOMPATIBLE; } rval = (*PluginStartup)(CoreHandle, g_PluginMap[MapIndex].name, DebugCallback); /* DebugCallback is in main.c */ if (rval != M64ERR_SUCCESS) { fprintf(stderr, "Error: %s plugin library '%s' failed to start.\n", g_PluginMap[MapIndex].name, filepath); osal_dynlib_close(handle); return rval; } /* plugin loaded successfully, so set the plugin map's members */ g_PluginMap[MapIndex].handle = handle; strcpy(g_PluginMap[MapIndex].filename, filepath); g_PluginMap[MapIndex].libname = PluginName; g_PluginMap[MapIndex].libversion = PluginVersion; return M64ERR_SUCCESS; }
/* Mupen64Plus plugin functions */ EXPORT m64p_error CALL PluginStartup(m64p_dynlib_handle CoreLibHandle, void *Context, void (*DebugCallback)(void *, int, const char *)) { ptr_CoreGetAPIVersions CoreAPIVersionFunc; int ConfigAPIVersion, DebugAPIVersion, VidextAPIVersion; if (l_PluginInit) return M64ERR_ALREADY_INIT; /* first thing is to set the callback function for debug info */ l_DebugCallback = DebugCallback; l_DebugCallContext = Context; /* attach and call the CoreGetAPIVersions function, check Config API version for compatibility */ CoreAPIVersionFunc = (ptr_CoreGetAPIVersions) osal_dynlib_getproc(CoreLibHandle, "CoreGetAPIVersions"); if (CoreAPIVersionFunc == NULL) { DebugMessage(M64MSG_ERROR, "Core emulator broken; no CoreAPIVersionFunc() function found."); return M64ERR_INCOMPATIBLE; } (*CoreAPIVersionFunc)(&ConfigAPIVersion, &DebugAPIVersion, &VidextAPIVersion, NULL); if ((ConfigAPIVersion & 0xffff0000) != (CONFIG_API_VERSION & 0xffff0000)) { DebugMessage(M64MSG_ERROR, "Emulator core Config API (v%i.%i.%i) incompatible with plugin (v%i.%i.%i)", VERSION_PRINTF_SPLIT(ConfigAPIVersion), VERSION_PRINTF_SPLIT(CONFIG_API_VERSION)); return M64ERR_INCOMPATIBLE; } l_PluginInit = 1; return M64ERR_SUCCESS; }
m64p_error PluginUnload(void) { typedef m64p_error (*ptr_PluginShutdown)(void); ptr_PluginShutdown PluginShutdown; int i; /* shutdown each type of plugin */ for (i = 0; i < 4; i++) { if (g_PluginMap[i].handle == NULL) continue; /* call the destructor function for the plugin and release the library */ PluginShutdown = (ptr_PluginShutdown) osal_dynlib_getproc(g_PluginMap[i].handle, "PluginShutdown"); if (PluginShutdown != NULL) (*PluginShutdown)(); osal_dynlib_close(g_PluginMap[i].handle); /* clear out the plugin map's members */ g_PluginMap[i].handle = NULL; g_PluginMap[i].filename[0] = 0; g_PluginMap[i].libname = NULL; g_PluginMap[i].libversion = 0; } return M64ERR_SUCCESS; }
/* Mupen64Plus plugin functions */ EXPORT m64p_error CALL PluginStartup(m64p_dynlib_handle CoreLibHandle, void *Context, void (*DebugCallback)(void *, int, const char *)) { if (l_PluginInit) return M64ERR_ALREADY_INIT; /* first thing is to set the callback function for debug info */ l_DebugCallback = DebugCallback; l_DebugCallContext = Context; /* Get the core config function pointers from the library handle */ ConfigOpenSection = (ptr_ConfigOpenSection) osal_dynlib_getproc(CoreLibHandle, "ConfigOpenSection"); ConfigSetParameter = (ptr_ConfigSetParameter) osal_dynlib_getproc(CoreLibHandle, "ConfigSetParameter"); ConfigGetParameter = (ptr_ConfigGetParameter) osal_dynlib_getproc(CoreLibHandle, "ConfigGetParameter"); ConfigSetDefaultInt = (ptr_ConfigSetDefaultInt) osal_dynlib_getproc(CoreLibHandle, "ConfigSetDefaultInt"); ConfigSetDefaultFloat = (ptr_ConfigSetDefaultFloat) osal_dynlib_getproc(CoreLibHandle, "ConfigSetDefaultFloat"); ConfigSetDefaultBool = (ptr_ConfigSetDefaultBool) osal_dynlib_getproc(CoreLibHandle, "ConfigSetDefaultBool"); ConfigSetDefaultString = (ptr_ConfigSetDefaultString) osal_dynlib_getproc(CoreLibHandle, "ConfigSetDefaultString"); ConfigGetParamInt = (ptr_ConfigGetParamInt) osal_dynlib_getproc(CoreLibHandle, "ConfigGetParamInt"); ConfigGetParamFloat = (ptr_ConfigGetParamFloat) osal_dynlib_getproc(CoreLibHandle, "ConfigGetParamFloat"); ConfigGetParamBool = (ptr_ConfigGetParamBool) osal_dynlib_getproc(CoreLibHandle, "ConfigGetParamBool"); ConfigGetParamString = (ptr_ConfigGetParamString) osal_dynlib_getproc(CoreLibHandle, "ConfigGetParamString"); if (!ConfigOpenSection || !ConfigSetParameter || !ConfigGetParameter || !ConfigSetDefaultInt || !ConfigSetDefaultFloat || !ConfigSetDefaultBool || !ConfigSetDefaultString || !ConfigGetParamInt || !ConfigGetParamFloat || !ConfigGetParamBool || !ConfigGetParamString) return M64ERR_INCOMPATIBLE; l_PluginInit = 1; return M64ERR_SUCCESS; }
EXPORT m64p_error CALL PluginStartup(m64p_dynlib_handle CoreLibHandle, void *Context, void (*DebugCallback)(void *, int, const char *)) { ptr_CoreGetAPIVersions CoreAPIVersionFunc; int ConfigAPIVersion, DebugAPIVersion, VidextAPIVersion, bSaveConfig; float fConfigParamsVersion = 0.0f; if (l_PluginInit) return M64ERR_ALREADY_INIT; /* first thing is to set the callback function for debug info */ l_DebugCallback = DebugCallback; l_DebugCallContext = Context; /* attach and call the CoreGetAPIVersions function, check Config API version for compatibility */ CoreAPIVersionFunc = (ptr_CoreGetAPIVersions) osal_dynlib_getproc(CoreLibHandle, "CoreGetAPIVersions"); if (CoreAPIVersionFunc == NULL) { DebugMessage(M64MSG_ERROR, "Core emulator broken; no CoreAPIVersionFunc() function found."); return M64ERR_INCOMPATIBLE; } (*CoreAPIVersionFunc)(&ConfigAPIVersion, &DebugAPIVersion, &VidextAPIVersion, NULL); if ((ConfigAPIVersion & 0xffff0000) != (CONFIG_API_VERSION & 0xffff0000)) { DebugMessage(M64MSG_ERROR, "Emulator core Config API (v%i.%i.%i) incompatible with plugin (v%i.%i.%i)", VERSION_PRINTF_SPLIT(ConfigAPIVersion), VERSION_PRINTF_SPLIT(CONFIG_API_VERSION)); return M64ERR_INCOMPATIBLE; } /* Get the core config function pointers from the library handle */ ConfigOpenSection = (ptr_ConfigOpenSection) osal_dynlib_getproc(CoreLibHandle, "ConfigOpenSection"); ConfigDeleteSection = (ptr_ConfigDeleteSection) osal_dynlib_getproc(CoreLibHandle, "ConfigDeleteSection"); ConfigSaveSection = (ptr_ConfigSaveSection) osal_dynlib_getproc(CoreLibHandle, "ConfigSaveSection"); ConfigSetParameter = (ptr_ConfigSetParameter) osal_dynlib_getproc(CoreLibHandle, "ConfigSetParameter"); ConfigGetParameter = (ptr_ConfigGetParameter) osal_dynlib_getproc(CoreLibHandle, "ConfigGetParameter"); ConfigSetDefaultFloat = (ptr_ConfigSetDefaultFloat) osal_dynlib_getproc(CoreLibHandle, "ConfigSetDefaultFloat"); ConfigSetDefaultBool = (ptr_ConfigSetDefaultBool) osal_dynlib_getproc(CoreLibHandle, "ConfigSetDefaultBool"); ConfigGetParamBool = (ptr_ConfigGetParamBool) osal_dynlib_getproc(CoreLibHandle, "ConfigGetParamBool"); CoreDoCommand = (ptr_CoreDoCommand) osal_dynlib_getproc(CoreLibHandle, "CoreDoCommand"); if (!ConfigOpenSection || !ConfigDeleteSection || !ConfigSetParameter || !ConfigGetParameter || !ConfigSetDefaultBool || !ConfigGetParamBool || !ConfigSetDefaultFloat) return M64ERR_INCOMPATIBLE; /* ConfigSaveSection was added in Config API v2.1.0 */ if (ConfigAPIVersion >= 0x020100 && !ConfigSaveSection) return M64ERR_INCOMPATIBLE; /* get a configuration section handle */ if (ConfigOpenSection("rsp-cxd4", &l_ConfigRsp) != M64ERR_SUCCESS) { DebugMessage(M64MSG_ERROR, "Couldn't open config section 'rsp-cxd4'"); return M64ERR_INPUT_NOT_FOUND; } /* check the section version number */ bSaveConfig = 0; if (ConfigGetParameter(l_ConfigRsp, "Version", M64TYPE_FLOAT, &fConfigParamsVersion, sizeof(float)) != M64ERR_SUCCESS) { DebugMessage(M64MSG_WARNING, "No version number in 'rsp-cxd4' config section. Setting defaults."); ConfigDeleteSection("rsp-cxd4"); ConfigOpenSection("rsp-cxd4", &l_ConfigRsp); bSaveConfig = 1; } else if (((int) fConfigParamsVersion) != ((int) CONFIG_PARAM_VERSION)) { DebugMessage(M64MSG_WARNING, "Incompatible version %.2f in 'rsp-cxd4' config section: current is %.2f. Setting defaults.", fConfigParamsVersion, (float) CONFIG_PARAM_VERSION); ConfigDeleteSection("rsp-cxd4"); ConfigOpenSection("rsp-cxd4", &l_ConfigRsp); bSaveConfig = 1; } else if ((CONFIG_PARAM_VERSION - fConfigParamsVersion) >= 0.0001f) { /* handle upgrades */ float fVersion = CONFIG_PARAM_VERSION; ConfigSetParameter(l_ConfigRsp, "Version", M64TYPE_FLOAT, &fVersion); DebugMessage(M64MSG_INFO, "Updating parameter set version in 'rsp-cxd4' config section to %.2f", fVersion); bSaveConfig = 1; } #ifndef HLEVIDEO int hlevideo = 0; #else int hlevideo = 1; #endif /* set the default values for this plugin */ ConfigSetDefaultFloat(l_ConfigRsp, "Version", CONFIG_PARAM_VERSION, "Mupen64Plus cxd4 RSP Plugin config parameter version number"); ConfigSetDefaultBool(l_ConfigRsp, "DisplayListToGraphicsPlugin", hlevideo, "Send display lists to the graphics plugin"); ConfigSetDefaultBool(l_ConfigRsp, "AudioListToAudioPlugin", 0, "Send audio lists to the audio plugin"); ConfigSetDefaultBool(l_ConfigRsp, "WaitForCPUHost", 0, "Force CPU-RSP signals synchronization"); ConfigSetDefaultBool(l_ConfigRsp, "SupportCPUSemaphoreLock", 0, "Support CPU-RSP semaphore lock"); if (bSaveConfig && ConfigAPIVersion >= 0x020100) ConfigSaveSection("rsp-cxd4"); l_PluginInit = 1; return M64ERR_SUCCESS; }
/* functions */ m64p_error AttachCoreLib(const char *CoreLibFilepath) { /* check if Core DLL is already attached */ if (CoreHandle != NULL) return M64ERR_INVALID_STATE; /* load the DLL */ m64p_error rval = M64ERR_INTERNAL; /* first, try a library path+name that was given on the command-line */ if (CoreLibFilepath != NULL) { rval = osal_dynlib_open(&CoreHandle, CoreLibFilepath); } /* then try a library path that was given at compile time */ #if defined(COREDIR) if (rval != M64ERR_SUCCESS || CoreHandle == NULL) { rval = osal_dynlib_open(&CoreHandle, COREDIR OSAL_DEFAULT_DYNLIB_FILENAME); } #endif /* for MacOS, look for the library in the Frameworks folder of the app bundle */ #if defined(__APPLE__) CFBundleRef mainBundle = CFBundleGetMainBundle(); if (mainBundle != NULL) { CFURLRef frameworksURL = CFBundleCopyPrivateFrameworksURL(mainBundle); if (frameworksURL != NULL) { char libPath[1024 + 32]; if (CFURLGetFileSystemRepresentation(frameworksURL, TRUE, (uint8_t *) libPath, 1024)) { strcat(libPath, "/" OSAL_DEFAULT_DYNLIB_FILENAME); rval = osal_dynlib_open(&CoreHandle, libPath); } CFRelease(frameworksURL); } } #endif /* then try just the filename of the shared library, to let dlopen() look through the system lib dirs */ if (rval != M64ERR_SUCCESS || CoreHandle == NULL) { rval = osal_dynlib_open(&CoreHandle, OSAL_DEFAULT_DYNLIB_FILENAME); } /* as a last-ditch effort, try loading library in current directory */ if (rval != M64ERR_SUCCESS || CoreHandle == NULL) { rval = osal_dynlib_open(&CoreHandle, OSAL_CURRENT_DIR OSAL_DEFAULT_DYNLIB_FILENAME); } /* if we haven't found a good core library by now, then we're screwed */ if (rval != M64ERR_SUCCESS || CoreHandle == NULL) { DebugMessage(M64MSG_ERROR, "AttachCoreLib() Error: failed to find Mupen64Plus Core library"); CoreHandle = NULL; return M64ERR_INPUT_NOT_FOUND; } /* attach and call the PluginGetVersion function, check the Core and API versions for compatibility with this front-end */ ptr_PluginGetVersion CoreVersionFunc; CoreVersionFunc = (ptr_PluginGetVersion) osal_dynlib_getproc(CoreHandle, "PluginGetVersion"); if (CoreVersionFunc == NULL) { DebugMessage(M64MSG_ERROR, "AttachCoreLib() Error: Shared library '%s' invalid; no PluginGetVersion() function found.", CoreLibFilepath); osal_dynlib_close(CoreHandle); CoreHandle = NULL; return M64ERR_INPUT_INVALID; } m64p_plugin_type PluginType = (m64p_plugin_type) 0; int Compatible = 0; int CoreVersion = 0; const char *CoreName = NULL; (*CoreVersionFunc)(&PluginType, &CoreVersion, &g_CoreAPIVersion, &CoreName, &g_CoreCapabilities); if (PluginType != M64PLUGIN_CORE) DebugMessage(M64MSG_ERROR, "AttachCoreLib() Error: Shared library '%s' invalid; this is not the emulator core.", CoreLibFilepath); else if (CoreVersion < MINIMUM_CORE_VERSION) DebugMessage(M64MSG_ERROR, "AttachCoreLib() Error: Shared library '%s' incompatible; core version %i.%i.%i is below minimum supported %i.%i.%i", CoreLibFilepath, VERSION_PRINTF_SPLIT(CoreVersion), VERSION_PRINTF_SPLIT(MINIMUM_CORE_VERSION)); else if ((g_CoreAPIVersion & 0xffff0000) != (CORE_API_VERSION & 0xffff0000)) DebugMessage(M64MSG_ERROR, "AttachCoreLib() Error: Shared library '%s' incompatible; core API major version %i.%i.%i doesn't match with this application (%i.%i.%i)", CoreLibFilepath, VERSION_PRINTF_SPLIT(g_CoreAPIVersion), VERSION_PRINTF_SPLIT(CORE_API_VERSION)); else Compatible = 1; /* exit if not compatible */ if (Compatible == 0) { osal_dynlib_close(CoreHandle); CoreHandle = NULL; return M64ERR_INCOMPATIBLE; } /* attach and call the CoreGetAPIVersion function, check Config API version for compatibility */ ptr_CoreGetAPIVersions CoreAPIVersionFunc; CoreAPIVersionFunc = (ptr_CoreGetAPIVersions) osal_dynlib_getproc(CoreHandle, "CoreGetAPIVersions"); if (CoreAPIVersionFunc == NULL) { DebugMessage(M64MSG_ERROR, "AttachCoreLib() Error: Library '%s' broken; no CoreAPIVersionFunc() function found.", CoreLibFilepath); osal_dynlib_close(CoreHandle); CoreHandle = NULL; return M64ERR_INPUT_INVALID; } int ConfigAPIVersion, DebugAPIVersion, VidextAPIVersion; (*CoreAPIVersionFunc)(&ConfigAPIVersion, &DebugAPIVersion, &VidextAPIVersion, NULL); if ((ConfigAPIVersion & 0xffff0000) != (CONFIG_API_VERSION & 0xffff0000) || ConfigAPIVersion < CONFIG_API_VERSION) { DebugMessage(M64MSG_ERROR, "AttachCoreLib() Error: Emulator core '%s' incompatible; Config API version %i.%i.%i doesn't match application: %i.%i.%i", CoreLibFilepath, VERSION_PRINTF_SPLIT(ConfigAPIVersion), VERSION_PRINTF_SPLIT(CONFIG_API_VERSION)); osal_dynlib_close(CoreHandle); CoreHandle = NULL; return M64ERR_INCOMPATIBLE; } /* print some information about the core library */ DebugMessage(M64MSG_INFO, "attached to core library '%s' version %i.%i.%i", CoreName, VERSION_PRINTF_SPLIT(CoreVersion)); if (g_CoreCapabilities & M64CAPS_DYNAREC) DebugMessage(M64MSG_INFO, " Includes support for Dynamic Recompiler."); if (g_CoreCapabilities & M64CAPS_DEBUGGER) DebugMessage(M64MSG_INFO, " Includes support for MIPS r4300 Debugger."); if (g_CoreCapabilities & M64CAPS_CORE_COMPARE) DebugMessage(M64MSG_INFO, " Includes support for r4300 Core Comparison."); /* get function pointers to the common and front-end functions */ CoreErrorMessage = (ptr_CoreErrorMessage) osal_dynlib_getproc(CoreHandle, "CoreErrorMessage"); CoreStartup = (ptr_CoreStartup) osal_dynlib_getproc(CoreHandle, "CoreStartup"); CoreShutdown = (ptr_CoreShutdown) osal_dynlib_getproc(CoreHandle, "CoreShutdown"); CoreAttachPlugin = (ptr_CoreAttachPlugin) osal_dynlib_getproc(CoreHandle, "CoreAttachPlugin"); CoreDetachPlugin = (ptr_CoreDetachPlugin) osal_dynlib_getproc(CoreHandle, "CoreDetachPlugin"); CoreDoCommand = (ptr_CoreDoCommand) osal_dynlib_getproc(CoreHandle, "CoreDoCommand"); CoreOverrideVidExt = (ptr_CoreOverrideVidExt) osal_dynlib_getproc(CoreHandle, "CoreOverrideVidExt"); CoreAddCheat = (ptr_CoreAddCheat) osal_dynlib_getproc(CoreHandle, "CoreAddCheat"); CoreCheatEnabled = (ptr_CoreCheatEnabled) osal_dynlib_getproc(CoreHandle, "CoreCheatEnabled"); /* get function pointers to the configuration functions */ ConfigListSections = (ptr_ConfigListSections) osal_dynlib_getproc(CoreHandle, "ConfigListSections"); ConfigOpenSection = (ptr_ConfigOpenSection) osal_dynlib_getproc(CoreHandle, "ConfigOpenSection"); ConfigDeleteSection = (ptr_ConfigDeleteSection) osal_dynlib_getproc(CoreHandle, "ConfigDeleteSection"); ConfigSaveSection = (ptr_ConfigSaveSection) osal_dynlib_getproc(CoreHandle, "ConfigSaveSection"); ConfigListParameters = (ptr_ConfigListParameters) osal_dynlib_getproc(CoreHandle, "ConfigListParameters"); ConfigSaveFile = (ptr_ConfigSaveFile) osal_dynlib_getproc(CoreHandle, "ConfigSaveFile"); ConfigSetParameter = (ptr_ConfigSetParameter) osal_dynlib_getproc(CoreHandle, "ConfigSetParameter"); ConfigGetParameter = (ptr_ConfigGetParameter) osal_dynlib_getproc(CoreHandle, "ConfigGetParameter"); ConfigGetParameterType = (ptr_ConfigGetParameterType) osal_dynlib_getproc(CoreHandle, "ConfigGetParameterType"); ConfigGetParameterHelp = (ptr_ConfigGetParameterHelp) osal_dynlib_getproc(CoreHandle, "ConfigGetParameterHelp"); ConfigSetDefaultInt = (ptr_ConfigSetDefaultInt) osal_dynlib_getproc(CoreHandle, "ConfigSetDefaultInt"); ConfigSetDefaultFloat = (ptr_ConfigSetDefaultFloat) osal_dynlib_getproc(CoreHandle, "ConfigSetDefaultFloat"); ConfigSetDefaultBool = (ptr_ConfigSetDefaultBool) osal_dynlib_getproc(CoreHandle, "ConfigSetDefaultBool"); ConfigSetDefaultString = (ptr_ConfigSetDefaultString) osal_dynlib_getproc(CoreHandle, "ConfigSetDefaultString"); ConfigGetParamInt = (ptr_ConfigGetParamInt) osal_dynlib_getproc(CoreHandle, "ConfigGetParamInt"); ConfigGetParamFloat = (ptr_ConfigGetParamFloat) osal_dynlib_getproc(CoreHandle, "ConfigGetParamFloat"); ConfigGetParamBool = (ptr_ConfigGetParamBool) osal_dynlib_getproc(CoreHandle, "ConfigGetParamBool"); ConfigGetParamString = (ptr_ConfigGetParamString) osal_dynlib_getproc(CoreHandle, "ConfigGetParamString"); ConfigExternalOpen = (ptr_ConfigExternalOpen) osal_dynlib_getproc(CoreHandle, "ConfigExternalOpen"); ConfigExternalClose = (ptr_ConfigExternalClose) osal_dynlib_getproc(CoreHandle, "ConfigExternalClose"); ConfigExternalGetParameter = (ptr_ConfigExternalGetParameter) osal_dynlib_getproc(CoreHandle, "ConfigExternalGetParameter"); ConfigHasUnsavedChanges = (ptr_ConfigHasUnsavedChanges) osal_dynlib_getproc(CoreHandle, "ConfigHasUnsavedChanges"); ConfigGetSharedDataFilepath = (ptr_ConfigGetSharedDataFilepath) osal_dynlib_getproc(CoreHandle, "ConfigGetSharedDataFilepath"); ConfigGetUserConfigPath = (ptr_ConfigGetUserConfigPath) osal_dynlib_getproc(CoreHandle, "ConfigGetUserConfigPath"); ConfigGetUserDataPath = (ptr_ConfigGetUserDataPath) osal_dynlib_getproc(CoreHandle, "ConfigGetUserDataPath"); ConfigGetUserCachePath = (ptr_ConfigGetUserCachePath) osal_dynlib_getproc(CoreHandle, "ConfigGetUserCachePath"); /* get function pointers to the debugger functions */ DebugSetCallbacks = (ptr_DebugSetCallbacks) osal_dynlib_getproc(CoreHandle, "DebugSetCallbacks"); DebugSetCoreCompare = (ptr_DebugSetCoreCompare) osal_dynlib_getproc(CoreHandle, "DebugSetCoreCompare"); DebugSetRunState = (ptr_DebugSetRunState) osal_dynlib_getproc(CoreHandle, "DebugSetRunState"); DebugGetState = (ptr_DebugGetState) osal_dynlib_getproc(CoreHandle, "DebugGetState"); DebugStep = (ptr_DebugStep) osal_dynlib_getproc(CoreHandle, "DebugStep"); DebugDecodeOp = (ptr_DebugDecodeOp) osal_dynlib_getproc(CoreHandle, "DebugDecodeOp"); DebugMemGetRecompInfo = (ptr_DebugMemGetRecompInfo) osal_dynlib_getproc(CoreHandle, "DebugMemGetRecompInfo"); DebugMemGetMemInfo = (ptr_DebugMemGetMemInfo) osal_dynlib_getproc(CoreHandle, "DebugMemGetMemInfo"); DebugMemGetPointer = (ptr_DebugMemGetPointer) osal_dynlib_getproc(CoreHandle, "DebugMemGetPointer"); DebugMemRead64 = (ptr_DebugMemRead64) osal_dynlib_getproc(CoreHandle, "DebugMemRead64"); DebugMemRead32 = (ptr_DebugMemRead32) osal_dynlib_getproc(CoreHandle, "DebugMemRead32"); DebugMemRead16 = (ptr_DebugMemRead16) osal_dynlib_getproc(CoreHandle, "DebugMemRead16"); DebugMemRead8 = (ptr_DebugMemRead8) osal_dynlib_getproc(CoreHandle, "DebugMemRead8"); DebugMemWrite64 = (ptr_DebugMemWrite64) osal_dynlib_getproc(CoreHandle, "DebugMemWrite64"); DebugMemWrite32 = (ptr_DebugMemWrite32) osal_dynlib_getproc(CoreHandle, "DebugMemWrite32"); DebugMemWrite16 = (ptr_DebugMemWrite16) osal_dynlib_getproc(CoreHandle, "DebugMemWrite16"); DebugMemWrite8 = (ptr_DebugMemWrite8) osal_dynlib_getproc(CoreHandle, "DebugMemWrite8"); DebugGetCPUDataPtr = (ptr_DebugGetCPUDataPtr) osal_dynlib_getproc(CoreHandle, "DebugGetCPUDataPtr"); DebugBreakpointLookup = (ptr_DebugBreakpointLookup) osal_dynlib_getproc(CoreHandle, "DebugBreakpointLookup"); DebugBreakpointCommand = (ptr_DebugBreakpointCommand) osal_dynlib_getproc(CoreHandle, "DebugBreakpointCommand"); DebugBreakpointTriggeredBy = (ptr_DebugBreakpointTriggeredBy) osal_dynlib_getproc(CoreHandle, "DebugBreakpointTriggeredBy"); DebugVirtualToPhysical = (ptr_DebugVirtualToPhysical) osal_dynlib_getproc(CoreHandle, "DebugVirtualToPhysical"); return M64ERR_SUCCESS; }
EXPORT m64p_error CALL PluginStartup(m64p_dynlib_handle CoreLibHandle, void *Context, void (*DebugCallback)(void *, int, const char *)) { char logMsg[530]; Logger::getSingleton().initialize(DebugCallback, Context); Logger::getSingleton().printMsg("PluginStartup"); /* attach and call the CoreGetAPIVersions function, check Config and Video Extension API versions for compatibility */ ptr_CoreGetAPIVersions CoreAPIVersionFunc; CoreAPIVersionFunc = (ptr_CoreGetAPIVersions) osal_dynlib_getproc(CoreLibHandle, "CoreGetAPIVersions"); if (CoreAPIVersionFunc == NULL) { sprintf(logMsg, "Core emulator broken; no CoreAPIVersionFunc() function found."); Logger::getSingleton().printMsg(logMsg, M64MSG_ERROR); return M64ERR_INCOMPATIBLE; } int ConfigAPIVersion, DebugAPIVersion, VidextAPIVersion; (*CoreAPIVersionFunc)(&ConfigAPIVersion, &DebugAPIVersion, &VidextAPIVersion, NULL); if ((ConfigAPIVersion & 0xffff0000) != (CONFIG_API_VERSION & 0xffff0000)) { sprintf(logMsg, "Emulator core Config API (v%i.%i.%i) incompatible with plugin (v%i.%i.%i)", VERSION_PRINTF_SPLIT(ConfigAPIVersion), VERSION_PRINTF_SPLIT(CONFIG_API_VERSION)); Logger::getSingleton().printMsg(logMsg, M64MSG_ERROR); return M64ERR_INCOMPATIBLE; } if ((VidextAPIVersion & 0xffff0000) != (VIDEXT_API_VERSION & 0xffff0000)) { sprintf(logMsg, "Emulator core Video Extension API (v%i.%i.%i) incompatible with plugin (v%i.%i.%i)", VERSION_PRINTF_SPLIT(VidextAPIVersion), VERSION_PRINTF_SPLIT(VIDEXT_API_VERSION)); Logger::getSingleton().printMsg(logMsg, M64MSG_ERROR); return M64ERR_INCOMPATIBLE; } /* Get the core config function pointers from the library handle */ ConfigOpenSection = (ptr_ConfigOpenSection) osal_dynlib_getproc(CoreLibHandle, "ConfigOpenSection"); ConfigSetParameter = (ptr_ConfigSetParameter) osal_dynlib_getproc(CoreLibHandle, "ConfigSetParameter"); ConfigGetParameter = (ptr_ConfigGetParameter) osal_dynlib_getproc(CoreLibHandle, "ConfigGetParameter"); ConfigSetDefaultInt = (ptr_ConfigSetDefaultInt) osal_dynlib_getproc(CoreLibHandle, "ConfigSetDefaultInt"); ConfigSetDefaultFloat = (ptr_ConfigSetDefaultFloat) osal_dynlib_getproc(CoreLibHandle, "ConfigSetDefaultFloat"); ConfigSetDefaultBool = (ptr_ConfigSetDefaultBool) osal_dynlib_getproc(CoreLibHandle, "ConfigSetDefaultBool"); ConfigSetDefaultString = (ptr_ConfigSetDefaultString) osal_dynlib_getproc(CoreLibHandle, "ConfigSetDefaultString"); ConfigGetParamInt = (ptr_ConfigGetParamInt) osal_dynlib_getproc(CoreLibHandle, "ConfigGetParamInt"); ConfigGetParamFloat = (ptr_ConfigGetParamFloat) osal_dynlib_getproc(CoreLibHandle, "ConfigGetParamFloat"); ConfigGetParamBool = (ptr_ConfigGetParamBool) osal_dynlib_getproc(CoreLibHandle, "ConfigGetParamBool"); ConfigGetParamString = (ptr_ConfigGetParamString) osal_dynlib_getproc(CoreLibHandle, "ConfigGetParamString"); ConfigGetSharedDataFilepath = (ptr_ConfigGetSharedDataFilepath) osal_dynlib_getproc(CoreLibHandle, "ConfigGetSharedDataFilepath"); ConfigGetUserConfigPath = (ptr_ConfigGetUserConfigPath) osal_dynlib_getproc(CoreLibHandle, "ConfigGetUserConfigPath"); ConfigGetUserDataPath = (ptr_ConfigGetUserDataPath) osal_dynlib_getproc(CoreLibHandle, "ConfigGetUserDataPath"); ConfigGetUserCachePath = (ptr_ConfigGetUserCachePath) osal_dynlib_getproc(CoreLibHandle, "ConfigGetUserCachePath"); if (!ConfigOpenSection || !ConfigSetParameter || !ConfigGetParameter || !ConfigSetDefaultInt || !ConfigSetDefaultFloat || !ConfigSetDefaultBool || !ConfigSetDefaultString || !ConfigGetParamInt || !ConfigGetParamFloat || !ConfigGetParamBool || !ConfigGetParamString || !ConfigGetSharedDataFilepath || !ConfigGetUserConfigPath || !ConfigGetUserDataPath || !ConfigGetUserCachePath) { Logger::getSingleton().printMsg("Couldn't connect to Core configuration functions", M64MSG_ERROR); return M64ERR_INCOMPATIBLE; } /* Get the core Video Extension function pointers from the library handle */ CoreVideo_Init = (ptr_VidExt_Init) osal_dynlib_getproc(CoreLibHandle, "VidExt_Init"); CoreVideo_Quit = (ptr_VidExt_Quit) osal_dynlib_getproc(CoreLibHandle, "VidExt_Quit"); CoreVideo_ListFullscreenModes = (ptr_VidExt_ListFullscreenModes) osal_dynlib_getproc(CoreLibHandle, "VidExt_ListFullscreenModes"); CoreVideo_SetVideoMode = (ptr_VidExt_SetVideoMode) osal_dynlib_getproc(CoreLibHandle, "VidExt_SetVideoMode"); CoreVideo_SetCaption = (ptr_VidExt_SetCaption) osal_dynlib_getproc(CoreLibHandle, "VidExt_SetCaption"); CoreVideo_ToggleFullScreen = (ptr_VidExt_ToggleFullScreen) osal_dynlib_getproc(CoreLibHandle, "VidExt_ToggleFullScreen"); CoreVideo_ResizeWindow = (ptr_VidExt_ResizeWindow) osal_dynlib_getproc(CoreLibHandle, "VidExt_ResizeWindow"); CoreVideo_GL_GetProcAddress = (ptr_VidExt_GL_GetProcAddress) osal_dynlib_getproc(CoreLibHandle, "VidExt_GL_GetProcAddress"); CoreVideo_GL_SetAttribute = (ptr_VidExt_GL_SetAttribute) osal_dynlib_getproc(CoreLibHandle, "VidExt_GL_SetAttribute"); CoreVideo_GL_SwapBuffers = (ptr_VidExt_GL_SwapBuffers) osal_dynlib_getproc(CoreLibHandle, "VidExt_GL_SwapBuffers"); if (!CoreVideo_Init || !CoreVideo_Quit || !CoreVideo_ListFullscreenModes || !CoreVideo_SetVideoMode || !CoreVideo_SetCaption || !CoreVideo_ToggleFullScreen || !CoreVideo_GL_GetProcAddress || !CoreVideo_GL_SetAttribute || !CoreVideo_GL_SwapBuffers || !CoreVideo_ResizeWindow) { Logger::getSingleton().printMsg("Couldn't connect to Core video functions", M64MSG_ERROR); return M64ERR_INCOMPATIBLE; } //Read configuration if (g_config.initialize()) { g_config.load(); g_graphicsPlugin.setConfig(g_config.getConfig()); } return M64ERR_SUCCESS; }
/* functions */ m64p_error AttachCoreLib(const char *CoreLibFilepath) { /* check if Core DLL is already attached */ if (CoreHandle != NULL) return M64ERR_INVALID_STATE; /* load the DLL */ m64p_error rval = M64ERR_INTERNAL; /* first, try a library path+name that was given on the command-line */ if (CoreLibFilepath != NULL) { rval = osal_dynlib_open(&CoreHandle, CoreLibFilepath); } /* then try a library path that was given at compile time */ #if defined(COREDIR) if (rval != M64ERR_SUCCESS || CoreHandle == NULL) { rval = osal_dynlib_open(&CoreHandle, COREDIR OSAL_DEFAULT_DYNLIB_FILENAME); } #endif /* then try just the filename of the shared library, to let dlopen() look through the system lib dirs */ if (rval != M64ERR_SUCCESS || CoreHandle == NULL) { rval = osal_dynlib_open(&CoreHandle, OSAL_DEFAULT_DYNLIB_FILENAME); } /* as a last-ditch effort, try loading library in current directory */ if (rval != M64ERR_SUCCESS || CoreHandle == NULL) { rval = osal_dynlib_open(&CoreHandle, OSAL_CURRENT_DIR OSAL_DEFAULT_DYNLIB_FILENAME); } /* if we haven't found a good core library by now, then we're screwed */ if (rval != M64ERR_SUCCESS || CoreHandle == NULL) { fprintf(stderr, "AttachCoreLib() Error: failed to find Mupen64Plus Core library\n"); CoreHandle = NULL; return M64ERR_INPUT_NOT_FOUND; } printf("Core found...\n");fflush(stdout); /* attach and call the PluginGetVersion function, check the Core and API versions for compatibility with this front-end */ ptr_PluginGetVersion CoreVersionFunc; CoreVersionFunc = (ptr_PluginGetVersion) osal_dynlib_getproc(CoreHandle, "PluginGetVersion"); if (CoreVersionFunc == NULL) { fprintf(stderr, "AttachCoreLib() Error: Shared library '%s' invalid; no PluginGetVersion() function found.\n", CoreLibFilepath); osal_dynlib_close(CoreHandle); CoreHandle = NULL; return M64ERR_INPUT_INVALID; } m64p_plugin_type PluginType = (m64p_plugin_type) 0; int Compatible = 0; int CoreVersion = 0, APIVersion = 0; const char *CoreName = NULL; (*CoreVersionFunc)(&PluginType, &CoreVersion, &APIVersion, &CoreName, &g_CoreCapabilities); if (PluginType != M64PLUGIN_CORE) fprintf(stderr, "AttachCoreLib() Error: Shared library '%s' invalid; wrong plugin type %i.\n", CoreLibFilepath, (int) PluginType); else if (CoreVersion < MINIMUM_CORE_VERSION) fprintf(stderr, "AttachCoreLib() Error: Shared library '%s' invalid; core version %i.%i.%i is below minimum supported %i.%i.%i\n", CoreLibFilepath, VERSION_PRINTF_SPLIT(CoreVersion), VERSION_PRINTF_SPLIT(MINIMUM_CORE_VERSION)); else if (APIVersion < MINIMUM_API_VERSION) fprintf(stderr, "AttachCoreLib() Error: Shared library '%s' invalid; core API version %i.%i.%i is below minimum supported %i.%i.%i\n", CoreLibFilepath, VERSION_PRINTF_SPLIT(APIVersion), VERSION_PRINTF_SPLIT(MINIMUM_API_VERSION)); else Compatible = 1; /* exit if not compatible */ if (Compatible == 0) { osal_dynlib_close(CoreHandle); CoreHandle = NULL; return M64ERR_INPUT_INVALID; } /* print some information about the core library */ printf("UI-console: attached to core library '%s' version %i.%i.%i\n", CoreName, VERSION_PRINTF_SPLIT(CoreVersion)); if (g_CoreCapabilities & M64CAPS_DYNAREC) printf(" Includes support for Dynamic Recompiler.\n"); if (g_CoreCapabilities & M64CAPS_DEBUGGER) printf(" Includes support for MIPS r4300 Debugger.\n"); if (g_CoreCapabilities & M64CAPS_CORE_COMPARE) printf(" Includes support for r4300 Core Comparison.\n"); /* get function pointers to the common and front-end functions */ CoreErrorMessage = (ptr_CoreErrorMessage) osal_dynlib_getproc(CoreHandle, "CoreErrorMessage"); CoreStartup = (ptr_CoreStartup) osal_dynlib_getproc(CoreHandle, "CoreStartup"); CoreShutdown = (ptr_CoreShutdown) osal_dynlib_getproc(CoreHandle, "CoreShutdown"); CoreAttachPlugin = (ptr_CoreAttachPlugin) osal_dynlib_getproc(CoreHandle, "CoreAttachPlugin"); CoreDetachPlugin = (ptr_CoreDetachPlugin) osal_dynlib_getproc(CoreHandle, "CoreDetachPlugin"); CoreDoCommand = (ptr_CoreDoCommand) osal_dynlib_getproc(CoreHandle, "CoreDoCommand"); CoreOverrideVidExt = (ptr_CoreOverrideVidExt) osal_dynlib_getproc(CoreHandle, "CoreOverrideVidExt"); CoreAddCheat = (ptr_CoreAddCheat) osal_dynlib_getproc(CoreHandle, "CoreAddCheat"); CoreCheatEnabled = (ptr_CoreCheatEnabled) osal_dynlib_getproc(CoreHandle, "CoreCheatEnabled"); /* get function pointers to the configuration functions */ ConfigListSections = (ptr_ConfigListSections) osal_dynlib_getproc(CoreHandle, "ConfigListSections"); ConfigOpenSection = (ptr_ConfigOpenSection) osal_dynlib_getproc(CoreHandle, "ConfigOpenSection"); ConfigDeleteSection = (ptr_ConfigDeleteSection) osal_dynlib_getproc(CoreHandle, "ConfigDeleteSection"); ConfigListParameters = (ptr_ConfigListParameters) osal_dynlib_getproc(CoreHandle, "ConfigListParameters"); ConfigSaveFile = (ptr_ConfigSaveFile) osal_dynlib_getproc(CoreHandle, "ConfigSaveFile"); ConfigSetParameter = (ptr_ConfigSetParameter) osal_dynlib_getproc(CoreHandle, "ConfigSetParameter"); ConfigGetParameter = (ptr_ConfigGetParameter) osal_dynlib_getproc(CoreHandle, "ConfigGetParameter"); ConfigGetParameterType = (ptr_ConfigGetParameterType) osal_dynlib_getproc(CoreHandle, "ConfigGetParameterType"); ConfigGetParameterHelp = (ptr_ConfigGetParameterHelp) osal_dynlib_getproc(CoreHandle, "ConfigGetParameterHelp"); ConfigSetDefaultInt = (ptr_ConfigSetDefaultInt) osal_dynlib_getproc(CoreHandle, "ConfigSetDefaultInt"); ConfigSetDefaultFloat = (ptr_ConfigSetDefaultFloat) osal_dynlib_getproc(CoreHandle, "ConfigSetDefaultFloat"); ConfigSetDefaultBool = (ptr_ConfigSetDefaultBool) osal_dynlib_getproc(CoreHandle, "ConfigSetDefaultBool"); ConfigSetDefaultString = (ptr_ConfigSetDefaultString) osal_dynlib_getproc(CoreHandle, "ConfigSetDefaultString"); ConfigGetParamInt = (ptr_ConfigGetParamInt) osal_dynlib_getproc(CoreHandle, "ConfigGetParamInt"); ConfigGetParamFloat = (ptr_ConfigGetParamFloat) osal_dynlib_getproc(CoreHandle, "ConfigGetParamFloat"); ConfigGetParamBool = (ptr_ConfigGetParamBool) osal_dynlib_getproc(CoreHandle, "ConfigGetParamBool"); ConfigGetParamString = (ptr_ConfigGetParamString) osal_dynlib_getproc(CoreHandle, "ConfigGetParamString"); ConfigGetSharedDataFilepath = (ptr_ConfigGetSharedDataFilepath) osal_dynlib_getproc(CoreHandle, "ConfigGetSharedDataFilepath"); ConfigGetUserConfigPath = (ptr_ConfigGetUserConfigPath) osal_dynlib_getproc(CoreHandle, "ConfigGetUserConfigPath"); ConfigGetUserDataPath = (ptr_ConfigGetUserDataPath) osal_dynlib_getproc(CoreHandle, "ConfigGetUserDataPath"); ConfigGetUserCachePath = (ptr_ConfigGetUserCachePath) osal_dynlib_getproc(CoreHandle, "ConfigGetUserCachePath"); /* get function pointers to the debugger functions */ DebugSetCallbacks = (ptr_DebugSetCallbacks) osal_dynlib_getproc(CoreHandle, "DebugSetCallbacks"); DebugSetCoreCompare = (ptr_DebugSetCoreCompare) osal_dynlib_getproc(CoreHandle, "DebugSetCoreCompare"); DebugSetRunState = (ptr_DebugSetRunState) osal_dynlib_getproc(CoreHandle, "DebugSetRunState"); DebugGetState = (ptr_DebugGetState) osal_dynlib_getproc(CoreHandle, "DebugGetState"); DebugStep = (ptr_DebugStep) osal_dynlib_getproc(CoreHandle, "DebugStep"); DebugDecodeOp = (ptr_DebugDecodeOp) osal_dynlib_getproc(CoreHandle, "DebugDecodeOp"); DebugMemGetRecompInfo = (ptr_DebugMemGetRecompInfo) osal_dynlib_getproc(CoreHandle, "DebugMemGetRecompInfo"); DebugMemGetMemInfo = (ptr_DebugMemGetMemInfo) osal_dynlib_getproc(CoreHandle, "DebugMemGetMemInfo"); DebugMemGetPointer = (ptr_DebugMemGetPointer) osal_dynlib_getproc(CoreHandle, "DebugMemGetPointer"); DebugMemRead64 = (ptr_DebugMemRead64) osal_dynlib_getproc(CoreHandle, "DebugMemRead64"); DebugMemRead32 = (ptr_DebugMemRead32) osal_dynlib_getproc(CoreHandle, "DebugMemRead32"); DebugMemRead16 = (ptr_DebugMemRead16) osal_dynlib_getproc(CoreHandle, "DebugMemRead16"); DebugMemRead8 = (ptr_DebugMemRead8) osal_dynlib_getproc(CoreHandle, "DebugMemRead8"); DebugMemWrite64 = (ptr_DebugMemWrite64) osal_dynlib_getproc(CoreHandle, "DebugMemRead64"); DebugMemWrite32 = (ptr_DebugMemWrite32) osal_dynlib_getproc(CoreHandle, "DebugMemRead32"); DebugMemWrite16 = (ptr_DebugMemWrite16) osal_dynlib_getproc(CoreHandle, "DebugMemRead16"); DebugMemWrite8 = (ptr_DebugMemWrite8) osal_dynlib_getproc(CoreHandle, "DebugMemRead8"); DebugGetCPUDataPtr = (ptr_DebugGetCPUDataPtr) osal_dynlib_getproc(CoreHandle, "DebugGetCPUDataPtr"); DebugBreakpointLookup = (ptr_DebugBreakpointLookup) osal_dynlib_getproc(CoreHandle, "DebugBreakpointLookup"); DebugBreakpointCommand = (ptr_DebugBreakpointCommand) osal_dynlib_getproc(CoreHandle, "DebugBreakpointCommand"); return M64ERR_SUCCESS; }
static m64p_error plugin_connect_gfx(m64p_dynlib_handle plugin_handle) { /* attach the Video plugin function pointers */ if (plugin_handle != NULL) { m64p_plugin_type PluginType; int PluginVersion, APIVersion; if (l_GfxAttached) return M64ERR_INVALID_STATE; /* set function pointers for required functions */ if (!GET_FUNC(ptr_PluginGetVersion, gfx.getVersion, "PluginGetVersion") || !GET_FUNC(ptr_ChangeWindow, gfx.changeWindow, "ChangeWindow") || !GET_FUNC(ptr_InitiateGFX, gfx.initiateGFX, "InitiateGFX") || !GET_FUNC(ptr_MoveScreen, gfx.moveScreen, "MoveScreen") || !GET_FUNC(ptr_ProcessDList, gfx.processDList, "ProcessDList") || !GET_FUNC(ptr_ProcessRDPList, gfx.processRDPList, "ProcessRDPList") || !GET_FUNC(ptr_RomClosed, gfx.romClosed, "RomClosed") || !GET_FUNC(ptr_RomOpen, gfx.romOpen, "RomOpen") || !GET_FUNC(ptr_ShowCFB, gfx.showCFB, "ShowCFB") || !GET_FUNC(ptr_UpdateScreen, gfx.updateScreen, "UpdateScreen") || !GET_FUNC(ptr_ViStatusChanged, gfx.viStatusChanged, "ViStatusChanged") || !GET_FUNC(ptr_ViWidthChanged, gfx.viWidthChanged, "ViWidthChanged") || !GET_FUNC(ptr_ReadScreen2, gfx.readScreen, "ReadScreen2") || !GET_FUNC(ptr_SetRenderingCallback, gfx.setRenderingCallback, "SetRenderingCallback") || !GET_FUNC(ptr_FBRead, gfx.fBRead, "FBRead") || !GET_FUNC(ptr_FBWrite, gfx.fBWrite, "FBWrite") || !GET_FUNC(ptr_FBGetFrameBufferInfo, gfx.fBGetFrameBufferInfo, "FBGetFrameBufferInfo")) { DebugMessage(M64MSG_ERROR, "broken Video plugin; function(s) not found."); plugin_disconnect_gfx(); return M64ERR_INPUT_INVALID; } /* set function pointers for optional functions */ gfx.resizeVideoOutput = (ptr_ResizeVideoOutput) osal_dynlib_getproc(plugin_handle, "ResizeVideoOutput"); /* check the version info */ (*gfx.getVersion)(&PluginType, &PluginVersion, &APIVersion, NULL, NULL); if (PluginType != M64PLUGIN_GFX || (APIVersion & 0xffff0000) != (GFX_API_VERSION & 0xffff0000)) { DebugMessage(M64MSG_ERROR, "incompatible Video plugin"); plugin_disconnect_gfx(); return M64ERR_INCOMPATIBLE; } /* handle backwards-compatibility */ if (APIVersion < 0x020100) { DebugMessage(M64MSG_WARNING, "Fallback for Video plugin API (%02i.%02i.%02i) < 2.1.0. Screenshots may contain On Screen Display text", VERSION_PRINTF_SPLIT(APIVersion)); // tell the video plugin to make its rendering callback to me (it's old, and doesn't have the bScreenRedrawn flag) gfx.setRenderingCallback(backcompat_videoRenderCallback); l_old1SetRenderingCallback = gfx.setRenderingCallback; // save this just for future use gfx.setRenderingCallback = (ptr_SetRenderingCallback) backcompat_setRenderCallbackIntercept; } if (APIVersion < 0x20200 || gfx.resizeVideoOutput == NULL) { DebugMessage(M64MSG_WARNING, "Fallback for Video plugin API (%02i.%02i.%02i) < 2.2.0. Resizable video will not work", VERSION_PRINTF_SPLIT(APIVersion)); gfx.resizeVideoOutput = dummyvideo_ResizeVideoOutput; } l_GfxAttached = 1; } else plugin_disconnect_gfx(); return M64ERR_SUCCESS; }
EXPORT m64p_error CALL PluginStartup(m64p_dynlib_handle CoreLibHandle, void *Context, void (*DebugCallback)(void *, int, const char *)) { /* Get the core config function pointers from the library handle */ ConfigOpenSection = (ptr_ConfigOpenSection) osal_dynlib_getproc(CoreLibHandle, "ConfigOpenSection"); ConfigSetParameter = (ptr_ConfigSetParameter) osal_dynlib_getproc(CoreLibHandle, "ConfigSetParameter"); ConfigGetParameter = (ptr_ConfigGetParameter) osal_dynlib_getproc(CoreLibHandle, "ConfigGetParameter"); ConfigSetDefaultInt = (ptr_ConfigSetDefaultInt) osal_dynlib_getproc(CoreLibHandle, "ConfigSetDefaultInt"); ConfigSetDefaultFloat = (ptr_ConfigSetDefaultFloat) osal_dynlib_getproc(CoreLibHandle, "ConfigSetDefaultFloat"); ConfigSetDefaultBool = (ptr_ConfigSetDefaultBool) osal_dynlib_getproc(CoreLibHandle, "ConfigSetDefaultBool"); ConfigSetDefaultString = (ptr_ConfigSetDefaultString) osal_dynlib_getproc(CoreLibHandle, "ConfigSetDefaultString"); ConfigGetParamInt = (ptr_ConfigGetParamInt) osal_dynlib_getproc(CoreLibHandle, "ConfigGetParamInt"); ConfigGetParamFloat = (ptr_ConfigGetParamFloat) osal_dynlib_getproc(CoreLibHandle, "ConfigGetParamFloat"); ConfigGetParamBool = (ptr_ConfigGetParamBool) osal_dynlib_getproc(CoreLibHandle, "ConfigGetParamBool"); ConfigGetParamString = (ptr_ConfigGetParamString) osal_dynlib_getproc(CoreLibHandle, "ConfigGetParamString"); ConfigGetSharedDataFilepath = (ptr_ConfigGetSharedDataFilepath) osal_dynlib_getproc(CoreLibHandle, "ConfigGetSharedDataFilepath"); ConfigGetUserConfigPath = (ptr_ConfigGetUserConfigPath) osal_dynlib_getproc(CoreLibHandle, "ConfigGetUserConfigPath"); ConfigGetUserDataPath = (ptr_ConfigGetUserDataPath) osal_dynlib_getproc(CoreLibHandle, "ConfigGetUserDataPath"); ConfigGetUserCachePath = (ptr_ConfigGetUserCachePath) osal_dynlib_getproc(CoreLibHandle, "ConfigGetUserCachePath"); if (!ConfigOpenSection || !ConfigSetParameter || !ConfigGetParameter || !ConfigSetDefaultInt || !ConfigSetDefaultFloat || !ConfigSetDefaultBool || !ConfigSetDefaultString || !ConfigGetParamInt || !ConfigGetParamFloat || !ConfigGetParamBool || !ConfigGetParamString || !ConfigGetSharedDataFilepath || !ConfigGetUserConfigPath || !ConfigGetUserDataPath || !ConfigGetUserCachePath) { //DebugMessage(M64MSG_ERROR, "Couldn't connect to Core configuration functions"); return M64ERR_INCOMPATIBLE; } #ifdef __NEON_OPT //if (android_getCpuFamily() == ANDROID_CPU_FAMILY_ARM && // (android_getCpuFeatures() & ANDROID_CPU_ARM_FEATURE_NEON) != 0) { // MathInitNeon(); // gSPInitNeon(); //} #endif InitConfiguration(); return M64ERR_SUCCESS; }
EXPORT m64p_error CALL PluginStartup(m64p_dynlib_handle CoreLibHandle, void *Context, void (*DebugCallback)(void *, int, const char *)) { ///* first thing is to set the callback function for debug info */ l_DebugCallback = DebugCallback; l_DebugCallContext = Context; /* Get the core Video Extension function pointers from the library handle */ CoreVideo_Init = (ptr_VidExt_Init) osal_dynlib_getproc(CoreLibHandle, "VidExt_Init"); CoreVideo_Quit = (ptr_VidExt_Quit) osal_dynlib_getproc(CoreLibHandle, "VidExt_Quit"); CoreVideo_ListFullscreenModes = (ptr_VidExt_ListFullscreenModes) osal_dynlib_getproc(CoreLibHandle, "VidExt_ListFullscreenModes"); CoreVideo_SetVideoMode = (ptr_VidExt_SetVideoMode) osal_dynlib_getproc(CoreLibHandle, "VidExt_SetVideoMode"); CoreVideo_SetCaption = (ptr_VidExt_SetCaption) osal_dynlib_getproc(CoreLibHandle, "VidExt_SetCaption"); CoreVideo_ToggleFullScreen = (ptr_VidExt_ToggleFullScreen) osal_dynlib_getproc(CoreLibHandle, "VidExt_ToggleFullScreen"); CoreVideo_ResizeWindow = (ptr_VidExt_ResizeWindow) osal_dynlib_getproc(CoreLibHandle, "VidExt_ResizeWindow"); CoreVideo_GL_GetProcAddress = (ptr_VidExt_GL_GetProcAddress) osal_dynlib_getproc(CoreLibHandle, "VidExt_GL_GetProcAddress"); CoreVideo_GL_SetAttribute = (ptr_VidExt_GL_SetAttribute) osal_dynlib_getproc(CoreLibHandle, "VidExt_GL_SetAttribute"); CoreVideo_GL_SwapBuffers = (ptr_VidExt_GL_SwapBuffers) osal_dynlib_getproc(CoreLibHandle, "VidExt_GL_SwapBuffers"); if (!CoreVideo_Init || !CoreVideo_Quit || !CoreVideo_ListFullscreenModes || !CoreVideo_SetVideoMode || !CoreVideo_SetCaption || !CoreVideo_ToggleFullScreen || !CoreVideo_GL_GetProcAddress || !CoreVideo_GL_SetAttribute || !CoreVideo_GL_SwapBuffers || !CoreVideo_ResizeWindow) { rdp_log(M64MSG_ERROR, "Couldn't connect to Core video functions"); return M64ERR_INCOMPATIBLE; } /* attach and call the CoreGetAPIVersions function, check Config and Video Extension API versions for compatibility */ ptr_CoreGetAPIVersions CoreAPIVersionFunc; CoreAPIVersionFunc = (ptr_CoreGetAPIVersions) osal_dynlib_getproc(CoreLibHandle, "CoreGetAPIVersions"); if (CoreAPIVersionFunc == NULL) { rdp_log(M64MSG_ERROR, "Core emulator broken; no CoreAPIVersionFunc() function found."); return M64ERR_INCOMPATIBLE; } int ConfigAPIVersion, DebugAPIVersion, VidextAPIVersion; (*CoreAPIVersionFunc)(&ConfigAPIVersion, &DebugAPIVersion, &VidextAPIVersion, NULL); if ((ConfigAPIVersion & 0xffff0000) != (CONFIG_API_VERSION & 0xffff0000)) { rdp_log(M64MSG_ERROR, "Emulator core Config API (v%i.%i.%i) incompatible with plugin (v%i.%i.%i)", VERSION_PRINTF_SPLIT(ConfigAPIVersion), VERSION_PRINTF_SPLIT(CONFIG_API_VERSION)); return M64ERR_INCOMPATIBLE; } if ((VidextAPIVersion & 0xffff0000) != (VIDEXT_API_VERSION & 0xffff0000)) { rdp_log(M64MSG_ERROR, "Emulator core Video Extension API (v%i.%i.%i) incompatible with plugin (v%i.%i.%i)", VERSION_PRINTF_SPLIT(VidextAPIVersion), VERSION_PRINTF_SPLIT(VIDEXT_API_VERSION)); return M64ERR_INCOMPATIBLE; } /* Get the core config function pointers from the library handle */ ConfigOpenSection = (ptr_ConfigOpenSection) osal_dynlib_getproc(CoreLibHandle, "ConfigOpenSection"); ConfigSetParameter = (ptr_ConfigSetParameter) osal_dynlib_getproc(CoreLibHandle, "ConfigSetParameter"); ConfigGetParameter = (ptr_ConfigGetParameter) osal_dynlib_getproc(CoreLibHandle, "ConfigGetParameter"); ConfigSetDefaultInt = (ptr_ConfigSetDefaultInt) osal_dynlib_getproc(CoreLibHandle, "ConfigSetDefaultInt"); ConfigSetDefaultFloat = (ptr_ConfigSetDefaultFloat) osal_dynlib_getproc(CoreLibHandle, "ConfigSetDefaultFloat"); ConfigSetDefaultBool = (ptr_ConfigSetDefaultBool) osal_dynlib_getproc(CoreLibHandle, "ConfigSetDefaultBool"); ConfigSetDefaultString = (ptr_ConfigSetDefaultString) osal_dynlib_getproc(CoreLibHandle, "ConfigSetDefaultString"); ConfigGetParamInt = (ptr_ConfigGetParamInt) osal_dynlib_getproc(CoreLibHandle, "ConfigGetParamInt"); ConfigGetParamFloat = (ptr_ConfigGetParamFloat) osal_dynlib_getproc(CoreLibHandle, "ConfigGetParamFloat"); ConfigGetParamBool = (ptr_ConfigGetParamBool) osal_dynlib_getproc(CoreLibHandle, "ConfigGetParamBool"); ConfigGetParamString = (ptr_ConfigGetParamString) osal_dynlib_getproc(CoreLibHandle, "ConfigGetParamString"); if (!ConfigOpenSection || !ConfigSetParameter || !ConfigGetParameter || !ConfigSetDefaultInt || !ConfigSetDefaultFloat || !ConfigSetDefaultBool || !ConfigSetDefaultString || !ConfigGetParamInt || !ConfigGetParamFloat || !ConfigGetParamBool || !ConfigGetParamString) { rdp_log(M64MSG_ERROR, "Couldn't connect to Core configuration functions"); return M64ERR_INCOMPATIBLE; } rglReadSettings(); return M64ERR_SUCCESS; }
/* Mupen64Plus plugin functions */ EXPORT m64p_error CALL PluginStartup(m64p_dynlib_handle CoreLibHandle, void *Context, void (*DebugCallback)(void *, int, const char *)) { ptr_CoreGetAPIVersions CoreAPIVersionFunc; int ConfigAPIVersion, DebugAPIVersion, VidextAPIVersion, bSaveConfig; float fConfigParamsVersion = 0.0f; if (l_PluginInit) return M64ERR_ALREADY_INIT; /* first thing is to set the callback function for debug info */ l_DebugCallback = DebugCallback; l_DebugCallContext = Context; /* attach and call the CoreGetAPIVersions function, check Config API version for compatibility */ CoreAPIVersionFunc = (ptr_CoreGetAPIVersions) osal_dynlib_getproc(CoreLibHandle, "CoreGetAPIVersions"); if (CoreAPIVersionFunc == NULL) { DebugMessage(M64MSG_ERROR, "Core emulator broken; no CoreAPIVersionFunc() function found."); return M64ERR_INCOMPATIBLE; } (*CoreAPIVersionFunc)(&ConfigAPIVersion, &DebugAPIVersion, &VidextAPIVersion, NULL); if ((ConfigAPIVersion & 0xffff0000) != (CONFIG_API_VERSION & 0xffff0000)) { DebugMessage(M64MSG_ERROR, "Emulator core Config API (v%i.%i.%i) incompatible with plugin (v%i.%i.%i)", VERSION_PRINTF_SPLIT(ConfigAPIVersion), VERSION_PRINTF_SPLIT(CONFIG_API_VERSION)); return M64ERR_INCOMPATIBLE; } /* Get the core config function pointers from the library handle */ ConfigOpenSection = (ptr_ConfigOpenSection) osal_dynlib_getproc(CoreLibHandle, "ConfigOpenSection"); ConfigDeleteSection = (ptr_ConfigDeleteSection) osal_dynlib_getproc(CoreLibHandle, "ConfigDeleteSection"); ConfigSaveSection = (ptr_ConfigSaveSection) osal_dynlib_getproc(CoreLibHandle, "ConfigSaveSection"); ConfigSetParameter = (ptr_ConfigSetParameter) osal_dynlib_getproc(CoreLibHandle, "ConfigSetParameter"); ConfigGetParameter = (ptr_ConfigGetParameter) osal_dynlib_getproc(CoreLibHandle, "ConfigGetParameter"); ConfigSetDefaultInt = (ptr_ConfigSetDefaultInt) osal_dynlib_getproc(CoreLibHandle, "ConfigSetDefaultInt"); ConfigSetDefaultFloat = (ptr_ConfigSetDefaultFloat) osal_dynlib_getproc(CoreLibHandle, "ConfigSetDefaultFloat"); ConfigSetDefaultBool = (ptr_ConfigSetDefaultBool) osal_dynlib_getproc(CoreLibHandle, "ConfigSetDefaultBool"); ConfigSetDefaultString = (ptr_ConfigSetDefaultString) osal_dynlib_getproc(CoreLibHandle, "ConfigSetDefaultString"); ConfigGetParamInt = (ptr_ConfigGetParamInt) osal_dynlib_getproc(CoreLibHandle, "ConfigGetParamInt"); ConfigGetParamFloat = (ptr_ConfigGetParamFloat) osal_dynlib_getproc(CoreLibHandle, "ConfigGetParamFloat"); ConfigGetParamBool = (ptr_ConfigGetParamBool) osal_dynlib_getproc(CoreLibHandle, "ConfigGetParamBool"); ConfigGetParamString = (ptr_ConfigGetParamString) osal_dynlib_getproc(CoreLibHandle, "ConfigGetParamString"); if (!ConfigOpenSection || !ConfigDeleteSection || !ConfigSetParameter || !ConfigGetParameter || !ConfigSetDefaultInt || !ConfigSetDefaultFloat || !ConfigSetDefaultBool || !ConfigSetDefaultString || !ConfigGetParamInt || !ConfigGetParamFloat || !ConfigGetParamBool || !ConfigGetParamString) return M64ERR_INCOMPATIBLE; /* ConfigSaveSection was added in Config API v2.1.0 */ if (ConfigAPIVersion >= 0x020100 && !ConfigSaveSection) return M64ERR_INCOMPATIBLE; /* get a configuration section handle */ if (ConfigOpenSection("Audio-OMX", &l_ConfigAudio) != M64ERR_SUCCESS) { DebugMessage(M64MSG_ERROR, "Couldn't open config section 'Audio-OMX'"); return M64ERR_INPUT_NOT_FOUND; } /* check the section version number */ bSaveConfig = 0; if (ConfigGetParameter(l_ConfigAudio, "Version", M64TYPE_FLOAT, &fConfigParamsVersion, sizeof(float)) != M64ERR_SUCCESS) { DebugMessage(M64MSG_WARNING, "No version number in 'Audio-OMX' config section. Setting defaults."); ConfigDeleteSection("Audio-OMX"); ConfigOpenSection("Audio-OMX", &l_ConfigAudio); bSaveConfig = 1; } else if (((int) fConfigParamsVersion) != ((int) CONFIG_PARAM_VERSION)) { DebugMessage(M64MSG_WARNING, "Incompatible version %.2f in 'Audio-OMX' config section: current is %.2f. Setting defaults.", fConfigParamsVersion, (float) CONFIG_PARAM_VERSION); ConfigDeleteSection("Audio-OMX"); ConfigOpenSection("Audio-OMX", &l_ConfigAudio); bSaveConfig = 1; } else if ((CONFIG_PARAM_VERSION - fConfigParamsVersion) >= 0.0001f) { /* handle upgrades */ float fVersion = CONFIG_PARAM_VERSION; ConfigSetParameter(l_ConfigAudio, "Version", M64TYPE_FLOAT, &fVersion); DebugMessage(M64MSG_INFO, "Updating parameter set version in 'Audio-OMX' config section to %.2f", fVersion); bSaveConfig = 1; } /* set the default values for this plugin */ ConfigSetDefaultFloat(l_ConfigAudio,"Version", CONFIG_PARAM_VERSION, "Mupen64Plus OMX Audio Plugin config parameter version number"); ConfigSetDefaultInt(l_ConfigAudio, "DEFAULT_FREQUENCY", DEFAULT_FREQUENCY, "Frequency which is used if rom doesn't want to change it"); ConfigSetDefaultBool(l_ConfigAudio, "SWAP_CHANNELS", 0, "Swaps left and right channels"); ConfigSetDefaultInt(l_ConfigAudio, "SECONDARY_BUFFER_SIZE",SECONDARY_BUFFER_SIZE, "Number of output samples per Audio callback. This is for hardware buffers."); ConfigSetDefaultInt(l_ConfigAudio, "OUTPUT_PORT", OUTPUT_PORT, "Audio output to go to (0) Analogue jack, (1) HDMI"); ConfigSetDefaultInt(l_ConfigAudio, "DEFAULT_MODE", DEFAULT_MODE, "Audio Output Frequncy mode: 0 = Rom Frequency, 1 ROM Frequency if supported (HDMI only), 2 = Standard frequency < Rom Frequency, 3 = Standard frequency > Rom Frequency, [N] Force output frequency"); ConfigSetDefaultInt(l_ConfigAudio, "LATENCY", DEFAULT_LATENCY, "Desired Latency in ms"); ConfigSetDefaultInt(l_ConfigAudio, "VOLUME_ADJUST", 5, "Percentage change each time the volume is increased or decreased"); ConfigSetDefaultInt(l_ConfigAudio, "VOLUME_DEFAULT", 80, "Default volume when a game is started"); //ConfigSetDefaultInt(l_ConfigAudio, "DEFAULT_NUM_BUFFERS", DEFAULT_NUM_BUFFERS, "The number of Audio buffers to use"); ConfigSetDefaultInt(l_ConfigAudio, "UNDERRUN_MODE", uiUnderrunMode, "Underrun Mode, 0 = Nothing, 1 = scale frequency, 2 = repeat block" ); if (bSaveConfig && ConfigAPIVersion >= 0x020100) ConfigSaveSection("Audio-OMX"); l_PluginInit = 1; return M64ERR_SUCCESS; }