1 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
2 * Mupen64plus-ui-console - core_interface.c *
3 * Mupen64Plus homepage: http://code.google.com/p/mupen64plus/ *
4 * Copyright (C) 2009 Richard Goedeken *
6 * This program is free software; you can redistribute it and/or modify *
7 * it under the terms of the GNU General Public License as published by *
8 * the Free Software Foundation; either version 2 of the License, or *
9 * (at your option) any later version. *
11 * This program is distributed in the hope that it will be useful, *
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
14 * GNU General Public License for more details. *
16 * You should have received a copy of the GNU General Public License *
17 * along with this program; if not, write to the *
18 * Free Software Foundation, Inc., *
19 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. *
20 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
22 /* This file contains the routines for attaching to the Mupen64Plus core
23 * library and pointers to the core functions
28 #include "m64p_types.h"
29 #include "m64p_common.h"
30 #include "m64p_frontend.h"
31 #include "m64p_config.h"
32 #include "m64p_debugger.h"
34 #include "osal_preproc.h"
35 #include "osal_dynamiclib.h"
39 #include "core_interface.h"
41 /* global data definitions */
42 int g_CoreCapabilities;
45 /* definitions of pointers to Core common functions */
46 ptr_CoreErrorMessage CoreErrorMessage = NULL;
48 /* definitions of pointers to Core front-end functions */
49 ptr_CoreStartup CoreStartup = NULL;
50 ptr_CoreShutdown CoreShutdown = NULL;
51 ptr_CoreAttachPlugin CoreAttachPlugin = NULL;
52 ptr_CoreDetachPlugin CoreDetachPlugin = NULL;
53 ptr_CoreDoCommand CoreDoCommand = NULL;
54 ptr_CoreOverrideVidExt CoreOverrideVidExt = NULL;
55 ptr_CoreAddCheat CoreAddCheat = NULL;
56 ptr_CoreCheatEnabled CoreCheatEnabled = NULL;
58 /* definitions of pointers to Core config functions */
59 ptr_ConfigListSections ConfigListSections = NULL;
60 ptr_ConfigOpenSection ConfigOpenSection = NULL;
61 ptr_ConfigDeleteSection ConfigDeleteSection = NULL;
62 ptr_ConfigSaveSection ConfigSaveSection = NULL;
63 ptr_ConfigListParameters ConfigListParameters = NULL;
64 ptr_ConfigSaveFile ConfigSaveFile = NULL;
65 ptr_ConfigSetParameter ConfigSetParameter = NULL;
66 ptr_ConfigGetParameter ConfigGetParameter = NULL;
67 ptr_ConfigGetParameterType ConfigGetParameterType = NULL;
68 ptr_ConfigGetParameterHelp ConfigGetParameterHelp = NULL;
69 ptr_ConfigSetDefaultInt ConfigSetDefaultInt = NULL;
70 ptr_ConfigSetDefaultFloat ConfigSetDefaultFloat = NULL;
71 ptr_ConfigSetDefaultBool ConfigSetDefaultBool = NULL;
72 ptr_ConfigSetDefaultString ConfigSetDefaultString = NULL;
73 ptr_ConfigGetParamInt ConfigGetParamInt = NULL;
74 ptr_ConfigGetParamFloat ConfigGetParamFloat = NULL;
75 ptr_ConfigGetParamBool ConfigGetParamBool = NULL;
76 ptr_ConfigGetParamString ConfigGetParamString = NULL;
78 ptr_ConfigGetSharedDataFilepath ConfigGetSharedDataFilepath = NULL;
79 ptr_ConfigGetUserConfigPath ConfigGetUserConfigPath = NULL;
80 ptr_ConfigGetUserDataPath ConfigGetUserDataPath = NULL;
81 ptr_ConfigGetUserCachePath ConfigGetUserCachePath = NULL;
83 /* definitions of pointers to Core debugger functions */
84 ptr_DebugSetCallbacks DebugSetCallbacks = NULL;
85 ptr_DebugSetCoreCompare DebugSetCoreCompare = NULL;
86 ptr_DebugSetRunState DebugSetRunState = NULL;
87 ptr_DebugGetState DebugGetState = NULL;
88 ptr_DebugStep DebugStep = NULL;
89 ptr_DebugDecodeOp DebugDecodeOp = NULL;
90 ptr_DebugMemGetRecompInfo DebugMemGetRecompInfo = NULL;
91 ptr_DebugMemGetMemInfo DebugMemGetMemInfo = NULL;
92 ptr_DebugMemGetPointer DebugMemGetPointer = NULL;
94 ptr_DebugMemRead64 DebugMemRead64 = NULL;
95 ptr_DebugMemRead32 DebugMemRead32 = NULL;
96 ptr_DebugMemRead16 DebugMemRead16 = NULL;
97 ptr_DebugMemRead8 DebugMemRead8 = NULL;
99 ptr_DebugMemWrite64 DebugMemWrite64 = NULL;
100 ptr_DebugMemWrite32 DebugMemWrite32 = NULL;
101 ptr_DebugMemWrite16 DebugMemWrite16 = NULL;
102 ptr_DebugMemWrite8 DebugMemWrite8 = NULL;
104 ptr_DebugGetCPUDataPtr DebugGetCPUDataPtr = NULL;
105 ptr_DebugBreakpointLookup DebugBreakpointLookup = NULL;
106 ptr_DebugBreakpointCommand DebugBreakpointCommand = NULL;
108 /* global variables */
109 m64p_dynlib_handle CoreHandle = NULL;
112 m64p_error AttachCoreLib(const char *CoreLibFilepath)
114 /* check if Core DLL is already attached */
115 if (CoreHandle != NULL)
116 return M64ERR_INVALID_STATE;
119 m64p_error rval = M64ERR_INTERNAL;
120 /* first, try a library path+name that was given on the command-line */
121 if (CoreLibFilepath != NULL)
123 rval = osal_dynlib_open(&CoreHandle, CoreLibFilepath);
125 /* then try a library path that was given at compile time */
127 if (rval != M64ERR_SUCCESS || CoreHandle == NULL)
129 rval = osal_dynlib_open(&CoreHandle, COREDIR OSAL_DEFAULT_DYNLIB_FILENAME);
132 /* then try just the filename of the shared library, to let dlopen() look through the system lib dirs */
133 if (rval != M64ERR_SUCCESS || CoreHandle == NULL)
135 rval = osal_dynlib_open(&CoreHandle, OSAL_DEFAULT_DYNLIB_FILENAME);
137 /* as a last-ditch effort, try loading library in current directory */
138 if (rval != M64ERR_SUCCESS || CoreHandle == NULL)
140 rval = osal_dynlib_open(&CoreHandle, OSAL_CURRENT_DIR OSAL_DEFAULT_DYNLIB_FILENAME);
142 /* if we haven't found a good core library by now, then we're screwed */
143 if (rval != M64ERR_SUCCESS || CoreHandle == NULL)
145 DebugMessage(M64MSG_ERROR, "AttachCoreLib() Error: failed to find Mupen64Plus Core library");
147 return M64ERR_INPUT_NOT_FOUND;
150 /* attach and call the PluginGetVersion function, check the Core and API versions for compatibility with this front-end */
151 ptr_PluginGetVersion CoreVersionFunc;
152 CoreVersionFunc = (ptr_PluginGetVersion) osal_dynlib_getproc(CoreHandle, "PluginGetVersion");
153 if (CoreVersionFunc == NULL)
155 DebugMessage(M64MSG_ERROR, "AttachCoreLib() Error: Shared library '%s' invalid; no PluginGetVersion() function found.", CoreLibFilepath);
156 osal_dynlib_close(CoreHandle);
158 return M64ERR_INPUT_INVALID;
160 m64p_plugin_type PluginType = (m64p_plugin_type) 0;
163 const char *CoreName = NULL;
164 (*CoreVersionFunc)(&PluginType, &CoreVersion, &g_CoreAPIVersion, &CoreName, &g_CoreCapabilities);
165 if (PluginType != M64PLUGIN_CORE)
166 DebugMessage(M64MSG_ERROR, "AttachCoreLib() Error: Shared library '%s' invalid; this is not the emulator core.", CoreLibFilepath);
167 else if (CoreVersion < MINIMUM_CORE_VERSION)
168 DebugMessage(M64MSG_ERROR, "AttachCoreLib() Error: Shared library '%s' incompatible; core version %i.%i.%i is below minimum supported %i.%i.%i",
169 CoreLibFilepath, VERSION_PRINTF_SPLIT(CoreVersion), VERSION_PRINTF_SPLIT(MINIMUM_CORE_VERSION));
170 else if ((g_CoreAPIVersion & 0xffff0000) != (CORE_API_VERSION & 0xffff0000))
171 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)",
172 CoreLibFilepath, VERSION_PRINTF_SPLIT(g_CoreAPIVersion), VERSION_PRINTF_SPLIT(CORE_API_VERSION));
175 /* exit if not compatible */
178 osal_dynlib_close(CoreHandle);
180 return M64ERR_INCOMPATIBLE;
183 /* attach and call the CoreGetAPIVersion function, check Config API version for compatibility */
184 ptr_CoreGetAPIVersions CoreAPIVersionFunc;
185 CoreAPIVersionFunc = (ptr_CoreGetAPIVersions) osal_dynlib_getproc(CoreHandle, "CoreGetAPIVersions");
186 if (CoreAPIVersionFunc == NULL)
188 DebugMessage(M64MSG_ERROR, "AttachCoreLib() Error: Library '%s' broken; no CoreAPIVersionFunc() function found.", CoreLibFilepath);
189 osal_dynlib_close(CoreHandle);
191 return M64ERR_INPUT_INVALID;
193 int ConfigAPIVersion, DebugAPIVersion, VidextAPIVersion;
194 (*CoreAPIVersionFunc)(&ConfigAPIVersion, &DebugAPIVersion, &VidextAPIVersion, NULL);
195 if ((ConfigAPIVersion & 0xffff0000) != (CONFIG_API_VERSION & 0xffff0000))
197 DebugMessage(M64MSG_ERROR, "AttachCoreLib() Error: Emulator core '%s' incompatible; Config API major version %i.%i.%i doesn't match application: %i.%i.%i",
198 CoreLibFilepath, VERSION_PRINTF_SPLIT(ConfigAPIVersion), VERSION_PRINTF_SPLIT(CONFIG_API_VERSION));
199 osal_dynlib_close(CoreHandle);
201 return M64ERR_INCOMPATIBLE;
204 /* print some information about the core library */
205 DebugMessage(M64MSG_INFO, "attached to core library '%s' version %i.%i.%i", CoreName, VERSION_PRINTF_SPLIT(CoreVersion));
206 if (g_CoreCapabilities & M64CAPS_DYNAREC)
207 DebugMessage(M64MSG_INFO, " Includes support for Dynamic Recompiler.");
208 if (g_CoreCapabilities & M64CAPS_DEBUGGER)
209 DebugMessage(M64MSG_INFO, " Includes support for MIPS r4300 Debugger.");
210 if (g_CoreCapabilities & M64CAPS_CORE_COMPARE)
211 DebugMessage(M64MSG_INFO, " Includes support for r4300 Core Comparison.");
213 /* get function pointers to the common and front-end functions */
214 CoreErrorMessage = (ptr_CoreErrorMessage) osal_dynlib_getproc(CoreHandle, "CoreErrorMessage");
215 CoreStartup = (ptr_CoreStartup) osal_dynlib_getproc(CoreHandle, "CoreStartup");
216 CoreShutdown = (ptr_CoreShutdown) osal_dynlib_getproc(CoreHandle, "CoreShutdown");
217 CoreAttachPlugin = (ptr_CoreAttachPlugin) osal_dynlib_getproc(CoreHandle, "CoreAttachPlugin");
218 CoreDetachPlugin = (ptr_CoreDetachPlugin) osal_dynlib_getproc(CoreHandle, "CoreDetachPlugin");
219 CoreDoCommand = (ptr_CoreDoCommand) osal_dynlib_getproc(CoreHandle, "CoreDoCommand");
220 CoreOverrideVidExt = (ptr_CoreOverrideVidExt) osal_dynlib_getproc(CoreHandle, "CoreOverrideVidExt");
221 CoreAddCheat = (ptr_CoreAddCheat) osal_dynlib_getproc(CoreHandle, "CoreAddCheat");
222 CoreCheatEnabled = (ptr_CoreCheatEnabled) osal_dynlib_getproc(CoreHandle, "CoreCheatEnabled");
224 /* get function pointers to the configuration functions */
225 ConfigListSections = (ptr_ConfigListSections) osal_dynlib_getproc(CoreHandle, "ConfigListSections");
226 ConfigOpenSection = (ptr_ConfigOpenSection) osal_dynlib_getproc(CoreHandle, "ConfigOpenSection");
227 ConfigDeleteSection = (ptr_ConfigDeleteSection) osal_dynlib_getproc(CoreHandle, "ConfigDeleteSection");
228 ConfigSaveSection = (ptr_ConfigSaveSection) osal_dynlib_getproc(CoreHandle, "ConfigSaveSection");
229 ConfigListParameters = (ptr_ConfigListParameters) osal_dynlib_getproc(CoreHandle, "ConfigListParameters");
230 ConfigSaveFile = (ptr_ConfigSaveFile) osal_dynlib_getproc(CoreHandle, "ConfigSaveFile");
231 ConfigSetParameter = (ptr_ConfigSetParameter) osal_dynlib_getproc(CoreHandle, "ConfigSetParameter");
232 ConfigGetParameter = (ptr_ConfigGetParameter) osal_dynlib_getproc(CoreHandle, "ConfigGetParameter");
233 ConfigGetParameterType = (ptr_ConfigGetParameterType) osal_dynlib_getproc(CoreHandle, "ConfigGetParameterType");
234 ConfigGetParameterHelp = (ptr_ConfigGetParameterHelp) osal_dynlib_getproc(CoreHandle, "ConfigGetParameterHelp");
235 ConfigSetDefaultInt = (ptr_ConfigSetDefaultInt) osal_dynlib_getproc(CoreHandle, "ConfigSetDefaultInt");
236 ConfigSetDefaultFloat = (ptr_ConfigSetDefaultFloat) osal_dynlib_getproc(CoreHandle, "ConfigSetDefaultFloat");
237 ConfigSetDefaultBool = (ptr_ConfigSetDefaultBool) osal_dynlib_getproc(CoreHandle, "ConfigSetDefaultBool");
238 ConfigSetDefaultString = (ptr_ConfigSetDefaultString) osal_dynlib_getproc(CoreHandle, "ConfigSetDefaultString");
239 ConfigGetParamInt = (ptr_ConfigGetParamInt) osal_dynlib_getproc(CoreHandle, "ConfigGetParamInt");
240 ConfigGetParamFloat = (ptr_ConfigGetParamFloat) osal_dynlib_getproc(CoreHandle, "ConfigGetParamFloat");
241 ConfigGetParamBool = (ptr_ConfigGetParamBool) osal_dynlib_getproc(CoreHandle, "ConfigGetParamBool");
242 ConfigGetParamString = (ptr_ConfigGetParamString) osal_dynlib_getproc(CoreHandle, "ConfigGetParamString");
244 ConfigGetSharedDataFilepath = (ptr_ConfigGetSharedDataFilepath) osal_dynlib_getproc(CoreHandle, "ConfigGetSharedDataFilepath");
245 ConfigGetUserConfigPath = (ptr_ConfigGetUserConfigPath) osal_dynlib_getproc(CoreHandle, "ConfigGetUserConfigPath");
246 ConfigGetUserDataPath = (ptr_ConfigGetUserDataPath) osal_dynlib_getproc(CoreHandle, "ConfigGetUserDataPath");
247 ConfigGetUserCachePath = (ptr_ConfigGetUserCachePath) osal_dynlib_getproc(CoreHandle, "ConfigGetUserCachePath");
249 /* get function pointers to the debugger functions */
250 DebugSetCallbacks = (ptr_DebugSetCallbacks) osal_dynlib_getproc(CoreHandle, "DebugSetCallbacks");
251 DebugSetCoreCompare = (ptr_DebugSetCoreCompare) osal_dynlib_getproc(CoreHandle, "DebugSetCoreCompare");
252 DebugSetRunState = (ptr_DebugSetRunState) osal_dynlib_getproc(CoreHandle, "DebugSetRunState");
253 DebugGetState = (ptr_DebugGetState) osal_dynlib_getproc(CoreHandle, "DebugGetState");
254 DebugStep = (ptr_DebugStep) osal_dynlib_getproc(CoreHandle, "DebugStep");
255 DebugDecodeOp = (ptr_DebugDecodeOp) osal_dynlib_getproc(CoreHandle, "DebugDecodeOp");
256 DebugMemGetRecompInfo = (ptr_DebugMemGetRecompInfo) osal_dynlib_getproc(CoreHandle, "DebugMemGetRecompInfo");
257 DebugMemGetMemInfo = (ptr_DebugMemGetMemInfo) osal_dynlib_getproc(CoreHandle, "DebugMemGetMemInfo");
258 DebugMemGetPointer = (ptr_DebugMemGetPointer) osal_dynlib_getproc(CoreHandle, "DebugMemGetPointer");
260 DebugMemRead64 = (ptr_DebugMemRead64) osal_dynlib_getproc(CoreHandle, "DebugMemRead64");
261 DebugMemRead32 = (ptr_DebugMemRead32) osal_dynlib_getproc(CoreHandle, "DebugMemRead32");
262 DebugMemRead16 = (ptr_DebugMemRead16) osal_dynlib_getproc(CoreHandle, "DebugMemRead16");
263 DebugMemRead8 = (ptr_DebugMemRead8) osal_dynlib_getproc(CoreHandle, "DebugMemRead8");
265 DebugMemWrite64 = (ptr_DebugMemWrite64) osal_dynlib_getproc(CoreHandle, "DebugMemRead64");
266 DebugMemWrite32 = (ptr_DebugMemWrite32) osal_dynlib_getproc(CoreHandle, "DebugMemRead32");
267 DebugMemWrite16 = (ptr_DebugMemWrite16) osal_dynlib_getproc(CoreHandle, "DebugMemRead16");
268 DebugMemWrite8 = (ptr_DebugMemWrite8) osal_dynlib_getproc(CoreHandle, "DebugMemRead8");
270 DebugGetCPUDataPtr = (ptr_DebugGetCPUDataPtr) osal_dynlib_getproc(CoreHandle, "DebugGetCPUDataPtr");
271 DebugBreakpointLookup = (ptr_DebugBreakpointLookup) osal_dynlib_getproc(CoreHandle, "DebugBreakpointLookup");
272 DebugBreakpointCommand = (ptr_DebugBreakpointCommand) osal_dynlib_getproc(CoreHandle, "DebugBreakpointCommand");
274 return M64ERR_SUCCESS;
277 m64p_error DetachCoreLib(void)
279 if (CoreHandle == NULL)
280 return M64ERR_INVALID_STATE;
282 /* set the core function pointers to NULL */
283 CoreErrorMessage = NULL;
286 CoreAttachPlugin = NULL;
287 CoreDetachPlugin = NULL;
288 CoreDoCommand = NULL;
289 CoreOverrideVidExt = NULL;
291 CoreCheatEnabled = NULL;
293 ConfigListSections = NULL;
294 ConfigOpenSection = NULL;
295 ConfigDeleteSection = NULL;
296 ConfigSaveSection = NULL;
297 ConfigListParameters = NULL;
298 ConfigSetParameter = NULL;
299 ConfigGetParameter = NULL;
300 ConfigGetParameterType = NULL;
301 ConfigGetParameterHelp = NULL;
302 ConfigSetDefaultInt = NULL;
303 ConfigSetDefaultBool = NULL;
304 ConfigSetDefaultString = NULL;
305 ConfigGetParamInt = NULL;
306 ConfigGetParamBool = NULL;
307 ConfigGetParamString = NULL;
309 ConfigGetSharedDataFilepath = NULL;
310 ConfigGetUserDataPath = NULL;
311 ConfigGetUserCachePath = NULL;
313 DebugSetCallbacks = NULL;
314 DebugSetCoreCompare = NULL;
315 DebugSetRunState = NULL;
316 DebugGetState = NULL;
318 DebugDecodeOp = NULL;
319 DebugMemGetRecompInfo = NULL;
320 DebugMemGetMemInfo = NULL;
321 DebugMemGetPointer = NULL;
323 DebugMemRead64 = NULL;
324 DebugMemRead32 = NULL;
325 DebugMemRead16 = NULL;
326 DebugMemRead8 = NULL;
328 DebugMemWrite64 = NULL;
329 DebugMemWrite32 = NULL;
330 DebugMemWrite16 = NULL;
331 DebugMemWrite8 = NULL;
333 DebugGetCPUDataPtr = NULL;
334 DebugBreakpointLookup = NULL;
335 DebugBreakpointCommand = NULL;
337 /* detach the shared library */
338 osal_dynlib_close(CoreHandle);
341 return M64ERR_SUCCESS;