/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Mupen64plus-ui-console - core_interface.c * * Mupen64Plus homepage: http://code.google.com/p/mupen64plus/ * * Copyright (C) 2009 Richard Goedeken * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ /* This file contains the routines for attaching to the Mupen64Plus core * library and pointers to the core functions */ #include #include #include #include #include "core_interface.h" #include "m64p_common.h" #include "m64p_config.h" #include "m64p_debugger.h" #include "m64p_frontend.h" #include "m64p_types.h" #include "common.h" extern "C" { #include "osal_dynamiclib.h" #include "osal_preproc.h" } #include "version.h" #include "vidext.h" /* global data definitions */ int g_CoreCapabilities; int g_CoreAPIVersion; QString qtCoreDirPath; QString qtConfigDir; int coreStarted = 0; /* definitions of pointers to Core common functions */ ptr_CoreErrorMessage CoreErrorMessage = NULL; /* definitions of pointers to Core front-end functions */ ptr_CoreStartup CoreStartup = NULL; ptr_CoreShutdown CoreShutdown = NULL; ptr_CoreAttachPlugin CoreAttachPlugin = NULL; ptr_CoreDetachPlugin CoreDetachPlugin = NULL; ptr_CoreDoCommand CoreDoCommand = NULL; ptr_CoreOverrideVidExt CoreOverrideVidExt = NULL; ptr_CoreAddCheat CoreAddCheat = NULL; ptr_CoreCheatEnabled CoreCheatEnabled = NULL; /* definitions of pointers to Core config functions */ ptr_ConfigListSections ConfigListSections = NULL; ptr_ConfigOpenSection ConfigOpenSection = NULL; ptr_ConfigDeleteSection ConfigDeleteSection = NULL; ptr_ConfigSaveSection ConfigSaveSection = NULL; ptr_ConfigListParameters ConfigListParameters = NULL; ptr_ConfigSaveFile ConfigSaveFile = NULL; ptr_ConfigSetParameter ConfigSetParameter = NULL; ptr_ConfigGetParameter ConfigGetParameter = NULL; ptr_ConfigGetParameterType ConfigGetParameterType = NULL; ptr_ConfigGetParameterHelp ConfigGetParameterHelp = NULL; ptr_ConfigSetDefaultInt ConfigSetDefaultInt = NULL; ptr_ConfigSetDefaultFloat ConfigSetDefaultFloat = NULL; ptr_ConfigSetDefaultBool ConfigSetDefaultBool = NULL; ptr_ConfigSetDefaultString ConfigSetDefaultString = NULL; ptr_ConfigGetParamInt ConfigGetParamInt = NULL; ptr_ConfigGetParamFloat ConfigGetParamFloat = NULL; ptr_ConfigGetParamBool ConfigGetParamBool = NULL; ptr_ConfigGetParamString ConfigGetParamString = NULL; ptr_ConfigGetSharedDataFilepath ConfigGetSharedDataFilepath = NULL; ptr_ConfigGetUserConfigPath ConfigGetUserConfigPath = NULL; ptr_ConfigGetUserDataPath ConfigGetUserDataPath = NULL; ptr_ConfigGetUserCachePath ConfigGetUserCachePath = NULL; /* definitions of pointers to Core debugger functions */ ptr_DebugSetCallbacks DebugSetCallbacks = NULL; ptr_DebugSetCoreCompare DebugSetCoreCompare = NULL; ptr_DebugSetRunState DebugSetRunState = NULL; ptr_DebugGetState DebugGetState = NULL; ptr_DebugStep DebugStep = NULL; ptr_DebugDecodeOp DebugDecodeOp = NULL; ptr_DebugMemGetRecompInfo DebugMemGetRecompInfo = NULL; ptr_DebugMemGetMemInfo DebugMemGetMemInfo = NULL; ptr_DebugMemGetPointer DebugMemGetPointer = NULL; ptr_DebugMemRead64 DebugMemRead64 = NULL; ptr_DebugMemRead32 DebugMemRead32 = NULL; ptr_DebugMemRead16 DebugMemRead16 = NULL; ptr_DebugMemRead8 DebugMemRead8 = NULL; ptr_DebugMemWrite64 DebugMemWrite64 = NULL; ptr_DebugMemWrite32 DebugMemWrite32 = NULL; ptr_DebugMemWrite16 DebugMemWrite16 = NULL; ptr_DebugMemWrite8 DebugMemWrite8 = NULL; ptr_DebugGetCPUDataPtr DebugGetCPUDataPtr = NULL; ptr_DebugBreakpointLookup DebugBreakpointLookup = NULL; ptr_DebugBreakpointCommand DebugBreakpointCommand = NULL; /* global variables */ m64p_dynlib_handle CoreHandle = NULL; m64p_video_extension_functions vidExtFunctions = {14, qtVidExtFuncInit, qtVidExtFuncQuit, qtVidExtFuncListModes, qtVidExtFuncListRates, qtVidExtFuncSetMode, qtVidExtFuncSetModeWithRate, qtVidExtFuncGLGetProc, qtVidExtFuncGLSetAttr, qtVidExtFuncGLGetAttr, qtVidExtFuncGLSwapBuf, qtVidExtFuncSetCaption, qtVidExtFuncToggleFS, qtVidExtFuncResizeWindow, qtVidExtFuncGLGetDefaultFramebuffer}; bool QtAttachCoreLib() { if (AttachCoreLib(qtCoreDirPath.toLatin1().data()) != M64ERR_SUCCESS && CoreHandle == NULL) { QMessageBox msgBox; msgBox.setText("Couldn't load core library, please set the path in settings."); msgBox.exec(); return false; } if (!coreStarted) { /* start the Mupen64Plus core library, load the configuration file */ m64p_error rval; if (!qtConfigDir.isEmpty()) rval = (*CoreStartup)(CORE_API_VERSION, qtConfigDir.toLatin1().data() /*Config dir*/, QCoreApplication::applicationDirPath().toLatin1().data(), (char*)"Core", DebugCallback, NULL, NULL); else rval = (*CoreStartup)(CORE_API_VERSION, NULL /*Config dir*/, QCoreApplication::applicationDirPath().toLatin1().data(), (char*)"Core", DebugCallback, NULL, NULL); if (rval != M64ERR_SUCCESS) { DebugMessage(M64MSG_ERROR, "couldn't start Mupen64Plus core library."); DetachCoreLib(); return false; } rval = CoreOverrideVidExt(&vidExtFunctions); if (rval != M64ERR_SUCCESS) { DebugMessage(M64MSG_ERROR, "couldn't start VidExt library."); DetachCoreLib(); return false; } coreStarted = 1; } return true; } /* 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; if (CoreLibFilepath != NULL) { rval = osal_dynlib_open(&CoreHandle, CoreLibFilepath); } if (rval != M64ERR_SUCCESS || CoreHandle == NULL) { QString corePath = QDir(QCoreApplication::applicationDirPath()).filePath(OSAL_DEFAULT_DYNLIB_FILENAME); rval = osal_dynlib_open(&CoreHandle, corePath.toLatin1().data()); } /* 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)) { DebugMessage(M64MSG_ERROR, "AttachCoreLib() Error: Emulator core '%s' incompatible; Config API major 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"); 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; } m64p_error DetachCoreLib(void) { if (CoreHandle == NULL) return M64ERR_INVALID_STATE; (*CoreShutdown)(); /* set the core function pointers to NULL */ CoreErrorMessage = NULL; CoreStartup = NULL; CoreShutdown = NULL; CoreAttachPlugin = NULL; CoreDetachPlugin = NULL; CoreDoCommand = NULL; CoreOverrideVidExt = NULL; CoreAddCheat = NULL; CoreCheatEnabled = NULL; ConfigListSections = NULL; ConfigOpenSection = NULL; ConfigDeleteSection = NULL; ConfigSaveSection = NULL; ConfigListParameters = NULL; ConfigSetParameter = NULL; ConfigGetParameter = NULL; ConfigGetParameterType = NULL; ConfigGetParameterHelp = NULL; ConfigSetDefaultInt = NULL; ConfigSetDefaultBool = NULL; ConfigSetDefaultString = NULL; ConfigGetParamInt = NULL; ConfigGetParamBool = NULL; ConfigGetParamString = NULL; ConfigGetSharedDataFilepath = NULL; ConfigGetUserDataPath = NULL; ConfigGetUserCachePath = NULL; DebugSetCallbacks = NULL; DebugSetCoreCompare = NULL; DebugSetRunState = NULL; DebugGetState = NULL; DebugStep = NULL; DebugDecodeOp = NULL; DebugMemGetRecompInfo = NULL; DebugMemGetMemInfo = NULL; DebugMemGetPointer = NULL; DebugMemRead64 = NULL; DebugMemRead32 = NULL; DebugMemRead16 = NULL; DebugMemRead8 = NULL; DebugMemWrite64 = NULL; DebugMemWrite32 = NULL; DebugMemWrite16 = NULL; DebugMemWrite8 = NULL; DebugGetCPUDataPtr = NULL; DebugBreakpointLookup = NULL; DebugBreakpointCommand = NULL; /* detach the shared library */ osal_dynlib_close(CoreHandle); CoreHandle = NULL; coreStarted = 0; return M64ERR_SUCCESS; }