--- /dev/null
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ * 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 <stdio.h>
+
+#include "m64p_types.h"
+#include "m64p_common.h"
+#include "m64p_frontend.h"
+#include "m64p_config.h"
+#include "m64p_debugger.h"
+
+#include "osal_preproc.h"
+#include "osal_dynamiclib.h"
+
+#include "main.h"
+#include "version.h"
+#include "core_interface.h"
+
+/* global data definitions */
+int g_CoreCapabilities;
+int g_CoreAPIVersion;
+
+/* 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;
+
+/* 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)
+ {
+ 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;
+
+ /* 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;
+
+ return M64ERR_SUCCESS;
+}
+
+