/* 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; }
/* Mupen64Plus plugin functions */ EXPORT m64p_error CALL PluginStartup(m64p_dynlib_handle CoreLibHandle, void *Context, void (*DebugCallback)(void *, int, const char *)) { LOG("API WRAPPER:\t PluginStartup") setup_jabo_functions(); 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) GetProcAddress(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; } ConfigOpenSection = (ptr_ConfigOpenSection) GetProcAddress(CoreLibHandle, "ConfigOpenSection"); ConfigSetParameter = (ptr_ConfigSetParameter) GetProcAddress(CoreLibHandle, "ConfigSetParameter"); ConfigGetParameter = (ptr_ConfigGetParameter) GetProcAddress(CoreLibHandle, "ConfigGetParameter"); ConfigSetDefaultInt = (ptr_ConfigSetDefaultInt) GetProcAddress(CoreLibHandle, "ConfigSetDefaultInt"); ConfigSetDefaultFloat = (ptr_ConfigSetDefaultFloat) GetProcAddress(CoreLibHandle, "ConfigSetDefaultFloat"); ConfigSetDefaultBool = (ptr_ConfigSetDefaultBool) GetProcAddress(CoreLibHandle, "ConfigSetDefaultBool"); ConfigSetDefaultString = (ptr_ConfigSetDefaultString) GetProcAddress(CoreLibHandle, "ConfigSetDefaultString"); ConfigGetParamInt = (ptr_ConfigGetParamInt) GetProcAddress(CoreLibHandle, "ConfigGetParamInt"); ConfigGetParamFloat = (ptr_ConfigGetParamFloat) GetProcAddress(CoreLibHandle, "ConfigGetParamFloat"); ConfigGetParamBool = (ptr_ConfigGetParamBool) GetProcAddress(CoreLibHandle, "ConfigGetParamBool"); ConfigGetParamString = (ptr_ConfigGetParamString) GetProcAddress(CoreLibHandle, "ConfigGetParamString"); l_PluginInit = 1; return M64ERR_SUCCESS; }
/* functions exported outside of libmupen64plus to front-end application */ EXPORT m64p_error CALL CoreStartup(int APIVersion, const char *ConfigPath, const char *DataPath, void *Context, void (*DebugCallback)(void *, int, const char *), void *Context2, void (*StateCallback)(void *, m64p_core_param, int)) { if (l_CoreInit) return M64ERR_ALREADY_INIT; /* very first thing is to set the callback functions for debug info and state changing*/ SetDebugCallback(DebugCallback, Context); SetStateCallback(StateCallback, Context2); /* check front-end's API version */ if ((APIVersion & 0xffff0000) != (FRONTEND_API_VERSION & 0xffff0000)) { DebugMessage(M64MSG_ERROR, "CoreStartup(): Front-end (API version %i.%i.%i) is incompatible with this core (API %i.%i.%i)", VERSION_PRINTF_SPLIT(APIVersion), VERSION_PRINTF_SPLIT(FRONTEND_API_VERSION)); return M64ERR_INCOMPATIBLE; } /* next, start up the configuration handling code by loading and parsing the config file */ if (ConfigInit(ConfigPath, DataPath) != M64ERR_SUCCESS) return M64ERR_INTERNAL; /* set default configuration parameter values for Core */ if (ConfigOpenSection("Core", &g_CoreConfig) != M64ERR_SUCCESS || g_CoreConfig == NULL) return M64ERR_INTERNAL; if (!main_set_core_defaults()) return M64ERR_INTERNAL; /* The ROM database contains MD5 hashes, goodnames, and some game-specific parameters */ romdatabase_open(); l_CoreInit = 1; return M64ERR_SUCCESS; }
int main(int argc, char *argv[]) { int i; printf(" __ __ __ _ _ ____ _ \n"); printf("| \\/ |_ _ _ __ ___ _ __ / /_ | || | | _ \\| |_ _ ___ \n"); printf("| |\\/| | | | | '_ \\ / _ \\ '_ \\| '_ \\| || |_| |_) | | | | / __| \n"); printf("| | | | |_| | |_) | __/ | | | (_) |__ _| __/| | |_| \\__ \\ \n"); printf("|_| |_|\\__,_| .__/ \\___|_| |_|\\___/ |_| |_| |_|\\__,_|___/ \n"); printf(" |_| http://code.google.com/p/mupen64plus/ \n"); printf("%s Version %i.%i.%i\n\n", CONSOLE_UI_NAME, VERSION_PRINTF_SPLIT(CONSOLE_UI_VERSION)); /* bootstrap some special parameters from the command line */ if (ParseCommandLineInitial(argc, (const char **) argv) != 0) return 1; /* load the Mupen64Plus core library */ if (AttachCoreLib(l_CoreLibPath) != M64ERR_SUCCESS) return 2; /* start the Mupen64Plus core library, load the configuration file */ m64p_error rval = (*CoreStartup)(CORE_API_VERSION, l_ConfigDirPath, l_DataDirPath, "Core", DebugCallback, NULL, CALLBACK_FUNC); if (rval != M64ERR_SUCCESS) { DebugMessage(M64MSG_ERROR, "couldn't start Mupen64Plus core library."); DetachCoreLib(); return 3; } /* Open configuration sections */ rval = OpenConfigurationHandles(); if (rval != M64ERR_SUCCESS) { (*CoreShutdown)(); DetachCoreLib(); return 4; } /* parse command-line options */ rval = ParseCommandLineFinal(argc, (const char **) argv); if (rval != M64ERR_SUCCESS) { (*CoreShutdown)(); DetachCoreLib(); return 5; } /* Handle the core comparison feature */ if (l_CoreCompareMode != 0 && !(g_CoreCapabilities & M64CAPS_CORE_COMPARE)) { DebugMessage(M64MSG_ERROR, "can't use --core-compare feature with this Mupen64Plus core library."); DetachCoreLib(); return 6; } compare_core_init(l_CoreCompareMode); /* save the given command-line options in configuration file if requested */ if (l_SaveOptions) SaveConfigurationOptions(); /* load ROM image */ FILE *fPtr = fopen(l_ROMFilepath, "rb"); if (fPtr == NULL) { DebugMessage(M64MSG_ERROR, "couldn't open ROM file '%s' for reading.", l_ROMFilepath); (*CoreShutdown)(); DetachCoreLib(); return 7; } /* get the length of the ROM, allocate memory buffer, load it from disk */ long romlength = 0; fseek(fPtr, 0L, SEEK_END); romlength = ftell(fPtr); fseek(fPtr, 0L, SEEK_SET); unsigned char *ROM_buffer = (unsigned char *) malloc(romlength); if (ROM_buffer == NULL) { DebugMessage(M64MSG_ERROR, "couldn't allocate %li-byte buffer for ROM image file '%s'.", romlength, l_ROMFilepath); fclose(fPtr); (*CoreShutdown)(); DetachCoreLib(); return 8; } else if (fread(ROM_buffer, 1, romlength, fPtr) != romlength) { DebugMessage(M64MSG_ERROR, "couldn't read %li bytes from ROM image file '%s'.", romlength, l_ROMFilepath); free(ROM_buffer); fclose(fPtr); (*CoreShutdown)(); DetachCoreLib(); return 9; } fclose(fPtr); /* Try to load the ROM image into the core */ if ((*CoreDoCommand)(M64CMD_ROM_OPEN, (int) romlength, ROM_buffer) != M64ERR_SUCCESS) { DebugMessage(M64MSG_ERROR, "core failed to open ROM image file '%s'.", l_ROMFilepath); free(ROM_buffer); (*CoreShutdown)(); DetachCoreLib(); return 10; } free(ROM_buffer); /* the core copies the ROM image, so we can release this buffer immediately */ /* handle the cheat codes */ CheatStart(l_CheatMode, l_CheatNumList); if (l_CheatMode == CHEAT_SHOW_LIST) { (*CoreDoCommand)(M64CMD_ROM_CLOSE, 0, NULL); (*CoreShutdown)(); DetachCoreLib(); return 11; } /* search for and load plugins */ rval = PluginSearchLoad(l_ConfigUI); if (rval != M64ERR_SUCCESS) { (*CoreDoCommand)(M64CMD_ROM_CLOSE, 0, NULL); (*CoreShutdown)(); DetachCoreLib(); return 12; } /* attach plugins to core */ for (i = 0; i < 4; i++) { if ((*CoreAttachPlugin)(g_PluginMap[i].type, g_PluginMap[i].handle) != M64ERR_SUCCESS) { DebugMessage(M64MSG_ERROR, "core error while attaching %s plugin.", g_PluginMap[i].name); (*CoreDoCommand)(M64CMD_ROM_CLOSE, 0, NULL); (*CoreShutdown)(); DetachCoreLib(); return 13; } } /* set up Frame Callback if --testshots or --savestate is enabled */ if (l_TestShotList != NULL || l_SaveStatePath != NULL) { if ((*CoreDoCommand)(M64CMD_SET_FRAME_CALLBACK, 0, FrameCallback) != M64ERR_SUCCESS) { DebugMessage(M64MSG_WARNING, "couldn't set frame callback, --testshots and/or --savestate will not work."); } } /* run the game */ (*CoreDoCommand)(M64CMD_EXECUTE, 0, NULL); /* detach plugins from core and unload them */ for (i = 0; i < 4; i++) (*CoreDetachPlugin)(g_PluginMap[i].type); PluginUnload(); /* close the ROM image */ (*CoreDoCommand)(M64CMD_ROM_CLOSE, 0, NULL); /* save the configuration file again if --nosaveoptions was not specified, to keep any updated parameters from the core/plugins */ if (l_SaveOptions) SaveConfigurationOptions(); /* Shut down and release the Core library */ (*CoreShutdown)(); DetachCoreLib(); /* free allocated memory */ if (l_TestShotList != NULL) free(l_TestShotList); return 0; }
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; }
bool COGLGraphicsContext::Initialize(uint32 dwWidth, uint32 dwHeight, BOOL bWindowed ) { DebugMessage(M64MSG_INFO, "Initializing OpenGL Device Context."); Lock(); CGraphicsContext::Initialize(dwWidth, dwHeight, bWindowed ); if( bWindowed ) { windowSetting.statusBarHeightToUse = windowSetting.statusBarHeight; windowSetting.toolbarHeightToUse = windowSetting.toolbarHeight; } else { windowSetting.statusBarHeightToUse = 0; windowSetting.toolbarHeightToUse = 0; } int depthBufferDepth = options.OpenglDepthBufferSetting; int colorBufferDepth = 32; int bVerticalSync = windowSetting.bVerticalSync; if( options.colorQuality == TEXTURE_FMT_A4R4G4B4 ) colorBufferDepth = 16; // init sdl & gl DebugMessage(M64MSG_VERBOSE, "Initializing video subsystem..."); if (CoreVideo_Init() != M64ERR_SUCCESS) return false; /* hard-coded attribute values */ const int iDOUBLEBUFFER = 1; // OpenEmu #if 0 /* set opengl attributes */ CoreVideo_GL_SetAttribute(M64P_GL_DOUBLEBUFFER, iDOUBLEBUFFER); CoreVideo_GL_SetAttribute(M64P_GL_SWAP_CONTROL, bVerticalSync); CoreVideo_GL_SetAttribute(M64P_GL_BUFFER_SIZE, colorBufferDepth); CoreVideo_GL_SetAttribute(M64P_GL_DEPTH_SIZE, depthBufferDepth); #endif /* set multisampling */ if (options.multiSampling > 0) { CoreVideo_GL_SetAttribute(M64P_GL_MULTISAMPLEBUFFERS, 1); if (options.multiSampling <= 2) CoreVideo_GL_SetAttribute(M64P_GL_MULTISAMPLESAMPLES, 2); else if (options.multiSampling <= 4) CoreVideo_GL_SetAttribute(M64P_GL_MULTISAMPLESAMPLES, 4); else if (options.multiSampling <= 8) CoreVideo_GL_SetAttribute(M64P_GL_MULTISAMPLESAMPLES, 8); else CoreVideo_GL_SetAttribute(M64P_GL_MULTISAMPLESAMPLES, 16); } /* Set the video mode */ m64p_video_mode ScreenMode = bWindowed ? M64VIDEO_WINDOWED : M64VIDEO_FULLSCREEN; m64p_video_flags flags = M64VIDEOFLAG_SUPPORT_RESIZING; if (CoreVideo_SetVideoMode(windowSetting.uDisplayWidth, windowSetting.uDisplayHeight, colorBufferDepth, ScreenMode, flags) != M64ERR_SUCCESS) { DebugMessage(M64MSG_ERROR, "Failed to set %i-bit video mode: %ix%i", colorBufferDepth, (int)windowSetting.uDisplayWidth, (int)windowSetting.uDisplayHeight); CoreVideo_Quit(); return false; } // OpenEmu #if 0 /* check that our opengl attributes were properly set */ int iActual; if (CoreVideo_GL_GetAttribute(M64P_GL_DOUBLEBUFFER, &iActual) == M64ERR_SUCCESS) if (iActual != iDOUBLEBUFFER) DebugMessage(M64MSG_WARNING, "Failed to set GL_DOUBLEBUFFER to %i. (it's %i)", iDOUBLEBUFFER, iActual); if (CoreVideo_GL_GetAttribute(M64P_GL_SWAP_CONTROL, &iActual) == M64ERR_SUCCESS) if (iActual != bVerticalSync) DebugMessage(M64MSG_WARNING, "Failed to set GL_SWAP_CONTROL to %i. (it's %i)", bVerticalSync, iActual); if (CoreVideo_GL_GetAttribute(M64P_GL_BUFFER_SIZE, &iActual) == M64ERR_SUCCESS) if (iActual != colorBufferDepth) DebugMessage(M64MSG_WARNING, "Failed to set GL_BUFFER_SIZE to %i. (it's %i)", colorBufferDepth, iActual); if (CoreVideo_GL_GetAttribute(M64P_GL_DEPTH_SIZE, &iActual) == M64ERR_SUCCESS) if (iActual != depthBufferDepth) DebugMessage(M64MSG_WARNING, "Failed to set GL_DEPTH_SIZE to %i. (it's %i)", depthBufferDepth, iActual); #endif #ifndef USE_GLES /* Get function pointers to OpenGL extensions (blame Microsoft Windows for this) */ OGLExtensions_Init(); #endif char caption[500]; sprintf(caption, "%s v%i.%i.%i", PLUGIN_NAME, VERSION_PRINTF_SPLIT(PLUGIN_VERSION)); CoreVideo_SetCaption(caption); SetWindowMode(); InitState(); InitOGLExtension(); sprintf(m_strDeviceStats, "%.60s - %.128s : %.60s", m_pVendorStr, m_pRenderStr, m_pVersionStr); TRACE0(m_strDeviceStats); DebugMessage(M64MSG_INFO, "Using OpenGL: %s", m_strDeviceStats); Unlock(); Clear(CLEAR_COLOR_AND_DEPTH_BUFFER); // Clear buffers UpdateFrame(); Clear(CLEAR_COLOR_AND_DEPTH_BUFFER); UpdateFrame(); m_bReady = true; 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; /* 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 *)) { ///* 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; }
bool COGLGraphicsContext::Initialize(uint32 dwWidth, uint32 dwHeight, BOOL bWindowed ) { DebugMessage(M64MSG_INFO, "Initializing OpenGL Device Context."); Lock(); CGraphicsContext::Get()->m_supportTextureMirror = false; CGraphicsContext::Initialize(dwWidth, dwHeight, bWindowed ); if( bWindowed ) { windowSetting.statusBarHeightToUse = windowSetting.statusBarHeight; windowSetting.toolbarHeightToUse = windowSetting.toolbarHeight; } else { windowSetting.statusBarHeightToUse = 0; windowSetting.toolbarHeightToUse = 0; } int depthBufferDepth = options.OpenglDepthBufferSetting; int colorBufferDepth = 32; if( options.colorQuality == TEXTURE_FMT_A4R4G4B4 ) colorBufferDepth = 16; // init sdl & gl DebugMessage(M64MSG_VERBOSE, "Initializing video subsystem..."); if (CoreVideo_Init() != M64ERR_SUCCESS) return false; /* set opengl attributes */ CoreVideo_GL_SetAttribute(M64P_GL_DOUBLEBUFFER, 1); CoreVideo_GL_SetAttribute(M64P_GL_BUFFER_SIZE, colorBufferDepth); CoreVideo_GL_SetAttribute(M64P_GL_DEPTH_SIZE, depthBufferDepth); /* Set the video mode */ m64p_video_mode ScreenMode = bWindowed ? M64VIDEO_WINDOWED : M64VIDEO_FULLSCREEN; if (CoreVideo_SetVideoMode(windowSetting.uDisplayWidth, windowSetting.uDisplayHeight, colorBufferDepth, ScreenMode) != M64ERR_SUCCESS) { DebugMessage(M64MSG_ERROR, "Failed to set %i-bit video mode: %ix%i", colorBufferDepth, (int)windowSetting.uDisplayWidth, (int)windowSetting.uDisplayHeight); CoreVideo_Quit(); return false; } char caption[500]; sprintf(caption, "%s v%i.%i.%i", PLUGIN_NAME, VERSION_PRINTF_SPLIT(PLUGIN_VERSION)); CoreVideo_SetCaption(caption); SetWindowMode(); InitState(); InitOGLExtension(); sprintf(m_strDeviceStats, "%s - %s : %s", m_pVendorStr, m_pRenderStr, m_pVersionStr); TRACE0(m_strDeviceStats); DebugMessage(M64MSG_INFO, "Using OpenGL: %s", m_strDeviceStats); Unlock(); Clear(CLEAR_COLOR_AND_DEPTH_BUFFER); // Clear buffers UpdateFrame(); Clear(CLEAR_COLOR_AND_DEPTH_BUFFER); UpdateFrame(); m_bReady = true; status.isVertexShaderEnabled = false; return true; }
/* global functions */ m64p_error PluginSearchLoad() { m64p_handle ConfigUI; if (ConfigGetSectionHandle(CONFIG_SECTION_UI, &ConfigUI) != M64ERR_SUCCESS) { return M64ERR_PLUGIN_FAIL; } osal_lib_search *lib_filelist = NULL; int i; /* start by checking the directory given on the command line */ if (g_PluginDir != NULL) { lib_filelist = osal_library_search(g_PluginDir); if (lib_filelist == NULL) { fprintf(stderr, "Error: No plugins found in --plugindir path: %s\n", g_PluginDir); return M64ERR_INPUT_NOT_FOUND; } } /* if no plugins found, search the PluginDir in the UI-console section of the config file */ if (lib_filelist == NULL) { const char *plugindir = (*ConfigGetParamString)(ConfigUI, "PluginDir"); lib_filelist = osal_library_search(plugindir); } /* if still no plugins found, search some common system folders */ if (lib_filelist == NULL) { for (i = 0; i < osal_libsearchdirs; i++) { lib_filelist = osal_library_search(osal_libsearchpath[i]); if (lib_filelist != NULL) break; } } /* try to load one of each type of plugin */ for (i = 0; i < 4; i++) { m64p_plugin_type type = g_PluginMap[i].type; const char *cmdline_path = NULL; const char *config_var = NULL; int use_dummy = 0; switch (type) { case M64PLUGIN_RSP: cmdline_path = g_RspPlugin; config_var = "RspPlugin"; break; case M64PLUGIN_GFX: cmdline_path = g_GfxPlugin; config_var = "VideoPlugin"; break; case M64PLUGIN_AUDIO: cmdline_path = g_AudioPlugin; config_var = "AudioPlugin"; break; case M64PLUGIN_INPUT: cmdline_path = g_InputPlugin; config_var = "InputPlugin"; break; default: cmdline_path = NULL; config_var = ""; } /* first search for a plugin matching what was given on the command line */ if (cmdline_path != NULL) { /* if full path was given, try loading exactly this file */ if (strchr(cmdline_path, OSAL_DIR_SEPARATOR) != NULL) { PluginLoadTry(cmdline_path, i); } else if (strcmp(cmdline_path, "dummy") == 0) { use_dummy = 1; } else /* otherwise search through the plugin directory to find a match with this name */ { osal_lib_search *curr = lib_filelist; while (curr != NULL && g_PluginMap[i].handle == NULL) { if (strncmp(curr->filename, cmdline_path, strlen(cmdline_path)) == 0) PluginLoadTry(curr->filepath, i); curr = curr->next; } } /* exit with error if we couldn't find the specified plugin */ if (!use_dummy && g_PluginMap[i].handle == NULL) { fprintf(stderr, "Error: Specified %s plugin not found: %s\n", g_PluginMap[i].name, cmdline_path); osal_free_lib_list(lib_filelist); return M64ERR_INPUT_NOT_FOUND; } } else /* otherwise search for a plugin specified in the config file */ { const char *config_path = (*ConfigGetParamString)(ConfigUI, config_var); if (config_path != NULL && strlen(config_path) > 0) { /* if full path was given, try loading exactly this file */ if (strchr(config_path, OSAL_DIR_SEPARATOR) != NULL) { PluginLoadTry(config_path, i); } else if (strcmp(config_path, "dummy") == 0) { use_dummy = 1; } else /* otherwise search through the plugin directory to find a match with this name */ { osal_lib_search *curr = lib_filelist; while (curr != NULL && g_PluginMap[i].handle == NULL) { if (strncmp(curr->filename, config_path, strlen(config_path)) == 0) PluginLoadTry(curr->filepath, i); curr = curr->next; } } } } /* As a last resort, search for any appropriate plugin in search directory */ if (!use_dummy && g_PluginMap[i].handle == NULL) { osal_lib_search *curr = lib_filelist; while (curr != NULL && g_PluginMap[i].handle == NULL) { PluginLoadTry(curr->filepath, i); curr = curr->next; } } /* print out the particular plugin used */ if (g_PluginMap[i].handle == NULL) { printf("UI-console: using %s plugin: <dummy>\n", g_PluginMap[i].name); } else { printf("UI-console: using %s plugin: '%s' v%i.%i.%i\n", g_PluginMap[i].name, g_PluginMap[i].libname, VERSION_PRINTF_SPLIT(g_PluginMap[i].libversion)); if (g_Verbose) printf("UI-console: %s plugin library: %s\n", g_PluginMap[i].name, g_PluginMap[i].filename); } } /* free up the list of library files in the plugin search directory */ osal_free_lib_list(lib_filelist); 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; }
int main(int argc, char *argv[]) { int i; printf(" __ __ __ _ _ ____ _ \n"); printf("| \\/ |_ _ _ __ ___ _ __ / /_ | || | | _ \\| |_ _ ___ \n"); printf("| |\\/| | | | | '_ \\ / _ \\ '_ \\| '_ \\| || |_| |_) | | | | / __| \n"); printf("| | | | |_| | |_) | __/ | | | (_) |__ _| __/| | |_| \\__ \\ \n"); printf("|_| |_|\\__,_| .__/ \\___|_| |_|\\___/ |_| |_| |_|\\__,_|___/ \n"); printf(" |_| https://mupen64plus.org/ \n"); printf("%s Version %i.%i.%i\n\n", CONSOLE_UI_NAME, VERSION_PRINTF_SPLIT(CONSOLE_UI_VERSION)); /* bootstrap some special parameters from the command line */ if (ParseCommandLineInitial(argc, (const char **) argv) != 0) return 1; /* load the Mupen64Plus core library */ if (AttachCoreLib(l_CoreLibPath) != M64ERR_SUCCESS) return 2; /* start the Mupen64Plus core library, load the configuration file */ m64p_error rval = (*CoreStartup)(CORE_API_VERSION, l_ConfigDirPath, l_DataDirPath, "Core", DebugCallback, NULL, CALLBACK_FUNC); if (rval != M64ERR_SUCCESS) { DebugMessage(M64MSG_ERROR, "couldn't start Mupen64Plus core library."); DetachCoreLib(); return 3; } #ifdef VIDEXT_HEADER rval = CoreOverrideVidExt(&vidExtFunctions); if (rval != M64ERR_SUCCESS) { DebugMessage(M64MSG_ERROR, "couldn't start VidExt library."); DetachCoreLib(); return 14; } #endif /* Open configuration sections */ rval = OpenConfigurationHandles(); if (rval != M64ERR_SUCCESS) { (*CoreShutdown)(); DetachCoreLib(); return 4; } /* parse command-line options */ rval = ParseCommandLineFinal(argc, (const char **) argv); if (rval != M64ERR_SUCCESS) { (*CoreShutdown)(); DetachCoreLib(); return 5; } /* Ensure that the core supports comparison feature if necessary */ if (l_CoreCompareMode != 0 && !(g_CoreCapabilities & M64CAPS_CORE_COMPARE)) { DebugMessage(M64MSG_ERROR, "can't use --core-compare feature with this Mupen64Plus core library."); DetachCoreLib(); return 6; } compare_core_init(l_CoreCompareMode); /* Ensure that the core supports the debugger if necessary */ if (l_LaunchDebugger && !(g_CoreCapabilities & M64CAPS_DEBUGGER)) { DebugMessage(M64MSG_ERROR, "can't use --debug feature with this Mupen64Plus core library."); DetachCoreLib(); return 6; } /* save the given command-line options in configuration file if requested */ if (l_SaveOptions) SaveConfigurationOptions(); /* load ROM image */ FILE *fPtr = fopen(l_ROMFilepath, "rb"); if (fPtr == NULL) { DebugMessage(M64MSG_ERROR, "couldn't open ROM file '%s' for reading.", l_ROMFilepath); (*CoreShutdown)(); DetachCoreLib(); return 7; } /* get the length of the ROM, allocate memory buffer, load it from disk */ long romlength = 0; fseek(fPtr, 0L, SEEK_END); romlength = ftell(fPtr); fseek(fPtr, 0L, SEEK_SET); unsigned char *ROM_buffer = (unsigned char *) malloc(romlength); if (ROM_buffer == NULL) { DebugMessage(M64MSG_ERROR, "couldn't allocate %li-byte buffer for ROM image file '%s'.", romlength, l_ROMFilepath); fclose(fPtr); (*CoreShutdown)(); DetachCoreLib(); return 8; } else if (fread(ROM_buffer, 1, romlength, fPtr) != romlength) { DebugMessage(M64MSG_ERROR, "couldn't read %li bytes from ROM image file '%s'.", romlength, l_ROMFilepath); free(ROM_buffer); fclose(fPtr); (*CoreShutdown)(); DetachCoreLib(); return 9; } fclose(fPtr); /* Try to load the ROM image into the core */ if ((*CoreDoCommand)(M64CMD_ROM_OPEN, (int) romlength, ROM_buffer) != M64ERR_SUCCESS) { DebugMessage(M64MSG_ERROR, "core failed to open ROM image file '%s'.", l_ROMFilepath); free(ROM_buffer); (*CoreShutdown)(); DetachCoreLib(); return 10; } free(ROM_buffer); /* the core copies the ROM image, so we can release this buffer immediately */ /* handle the cheat codes */ CheatStart(l_CheatMode, l_CheatNumList); if (l_CheatMode == CHEAT_SHOW_LIST) { (*CoreDoCommand)(M64CMD_ROM_CLOSE, 0, NULL); (*CoreShutdown)(); DetachCoreLib(); return 11; } /* search for and load plugins */ rval = PluginSearchLoad(l_ConfigUI); if (rval != M64ERR_SUCCESS) { (*CoreDoCommand)(M64CMD_ROM_CLOSE, 0, NULL); (*CoreShutdown)(); DetachCoreLib(); return 12; } /* attach plugins to core */ for (i = 0; i < 4; i++) { if ((*CoreAttachPlugin)(g_PluginMap[i].type, g_PluginMap[i].handle) != M64ERR_SUCCESS) { DebugMessage(M64MSG_ERROR, "core error while attaching %s plugin.", g_PluginMap[i].name); (*CoreDoCommand)(M64CMD_ROM_CLOSE, 0, NULL); (*CoreShutdown)(); DetachCoreLib(); return 13; } } /* set up Frame Callback if --testshots is enabled */ if (l_TestShotList != NULL) { if ((*CoreDoCommand)(M64CMD_SET_FRAME_CALLBACK, 0, FrameCallback) != M64ERR_SUCCESS) { DebugMessage(M64MSG_WARNING, "couldn't set frame callback, --testshots will not work."); } } /* set gb cart loader */ if ((*CoreDoCommand)(M64CMD_SET_MEDIA_LOADER, sizeof(l_media_loader), &l_media_loader) != M64ERR_SUCCESS) { DebugMessage(M64MSG_WARNING, "Couldn't set media loader, transferpak and GB carts will not work."); } /* load savestate at startup */ if (l_SaveStatePath != NULL) { if ((*CoreDoCommand)(M64CMD_STATE_LOAD, 0, (void *) l_SaveStatePath) != M64ERR_SUCCESS) { DebugMessage(M64MSG_WARNING, "couldn't load state, rom will run normally."); } } /* Setup debugger */ if (l_LaunchDebugger) { if (debugger_setup_callbacks()) { DebugMessage(M64MSG_ERROR, "couldn't setup debugger callbacks."); (*CoreDoCommand)(M64CMD_ROM_CLOSE, 0, NULL); (*CoreShutdown)(); DetachCoreLib(); return 14; } /* Set Core config parameter to enable debugger */ int bEnableDebugger = 1; (*ConfigSetParameter)(l_ConfigCore, "EnableDebugger", M64TYPE_BOOL, &bEnableDebugger); /* Fork the debugger input thread. */ #if SDL_VERSION_ATLEAST(2,0,0) SDL_CreateThread(debugger_loop, "DebugLoop", NULL); #else SDL_CreateThread(debugger_loop, NULL); #endif } /* run the game */ (*CoreDoCommand)(M64CMD_EXECUTE, 0, NULL); /* detach plugins from core and unload them */ for (i = 0; i < 4; i++) (*CoreDetachPlugin)(g_PluginMap[i].type); PluginUnload(); /* close the ROM image */ (*CoreDoCommand)(M64CMD_ROM_CLOSE, 0, NULL); /* save the configuration file again if --nosaveoptions was not specified, to keep any updated parameters from the core/plugins */ if (l_SaveOptions) SaveConfigurationOptions(); /* Shut down and release the Core library */ (*CoreShutdown)(); DetachCoreLib(); /* free allocated memory */ if (l_TestShotList != NULL) free(l_TestShotList); return 0; }