Files
simple64/mupen64plus-gui/interface/core_interface.cpp
T
2020-09-02 16:28:30 -07:00

389 lines
19 KiB
C++

/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
* 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 <QMessageBox>
#include <QCoreApplication>
#include <QDir>
#include <stdio.h>
#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;
}