/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Mupen64plus-input-bkm - plugin.c * * Mupen64Plus homepage: http://code.google.com/p/mupen64plus/ * * Edited 2014 null_ptr * * Copyright (C) 2008-2011 Richard Goedeken * * Copyright (C) 2008 Tillin9 * * Copyright (C) 2002 Blight * * * * 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. * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ #include #include #include #define M64P_PLUGIN_PROTOTYPES 1 #include "m64p_types.h" #include "m64p_plugin.h" #include "m64p_common.h" #include "m64p_config.h" #include "plugin.h" #include "config.h" #include "version.h" #include "osal_dynamiclib.h" #include /* global data definitions */ SController controller[4]; // 4 controllers /* static data definitions */ static void (*l_DebugCallback)(void *, int, const char *) = NULL; static void *l_DebugCallContext = NULL; static int l_PluginInit = 0; static int (*l_inputCallback)(int i) = NULL; static int romopen = 0; // is a rom opened /* Global functions */ void DebugMessage(int level, const char *message, ...) { char msgbuf[1024]; va_list args; if (l_DebugCallback == NULL) return; va_start(args, message); vsprintf(msgbuf, message, args); (*l_DebugCallback)(l_DebugCallContext, level, msgbuf); va_end(args); } #pragma region (De-)Initialization /* 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; } /* reset controllers */ memset(controller, 0, sizeof(controller)); l_PluginInit = 1; return M64ERR_SUCCESS; } EXPORT m64p_error CALL PluginShutdown(void) { if (!l_PluginInit) return M64ERR_NOT_INIT; /* reset some local variables */ l_DebugCallback = NULL; l_DebugCallContext = NULL; l_PluginInit = 0; memset(controller, 0, sizeof(controller)); return M64ERR_SUCCESS; } /****************************************************************** Function: InitiateControllers Purpose: This function initialises how each of the controllers should be handled. input: - The handle to the main window. - A controller structure that needs to be filled for the emulator to know how to handle each controller. output: none *******************************************************************/ EXPORT void CALL InitiateControllers(CONTROL_INFO ControlInfo) { int i; memset( controller, 0, sizeof(controller) ); for( i = 0; i < 4; i++ ) { controller[i].control = ControlInfo.Controls + i; controller[i].control->Plugin = PLUGIN_MEMPAK; controller[i].control->Present = 1; } DebugMessage(M64MSG_INFO, "%s version %i.%i.%i initialized.", PLUGIN_NAME, VERSION_PRINTF_SPLIT(PLUGIN_VERSION)); } /****************************************************************** Function: RomClosed Purpose: This function is called when a rom is closed. input: none output: none *******************************************************************/ EXPORT void CALL RomClosed(void) { romopen = 0; } /****************************************************************** Function: RomOpen Purpose: This function is called when a rom is open. (from the emulation thread) input: none output: none *******************************************************************/ EXPORT int CALL RomOpen(void) { romopen = 1; return 1; } #pragma endregion EXPORT m64p_error CALL PluginGetVersion(m64p_plugin_type *PluginType, int *PluginVersion, int *APIVersion, const char **PluginNamePtr, int *Capabilities) { /* set version info */ if (PluginType != NULL) *PluginType = M64PLUGIN_INPUT; if (PluginVersion != NULL) *PluginVersion = PLUGIN_VERSION; if (APIVersion != NULL) *APIVersion = INPUT_PLUGIN_API_VERSION; if (PluginNamePtr != NULL) *PluginNamePtr = PLUGIN_NAME; if (Capabilities != NULL) { *Capabilities = 0; } return M64ERR_SUCCESS; } #pragma region Useless stubs /* ---------------------------------------------------------------------- -------------------- This functions are not used -------------------- -------------------- Plugin api just expects them -------------------- -------------------- to exist -------------------- ---------------------------------------------------------------------- */ /****************************************************************** Function: ControllerCommand Purpose: To process the raw data that has just been sent to a specific controller. input: - Controller Number (0 to 3) and -1 signalling end of processing the pif ram. - Pointer of data to be processed. output: none note: This function is only needed if the DLL is allowing raw data, or the plugin is set to raw the data that is being processed looks like this: initilize controller: 01 03 00 FF FF FF read controller: 01 04 01 FF FF FF FF *******************************************************************/ EXPORT void CALL ControllerCommand(int Control, unsigned char *Command) { } /****************************************************************** Function: ReadController Purpose: To process the raw data in the pif ram that is about to be read. input: - Controller Number (0 to 3) and -1 signalling end of processing the pif ram. - Pointer of data to be processed. output: none note: This function is only needed if the DLL is allowing raw data. *******************************************************************/ EXPORT void CALL ReadController(int Control, unsigned char *Command) { } /****************************************************************** Function: SDL_KeyDown Purpose: To pass the SDL_KeyDown message from the emulator to the plugin. input: keymod and keysym of the SDL_KEYDOWN message. output: none *******************************************************************/ EXPORT void CALL SDL_KeyDown(int keymod, int keysym) { } /****************************************************************** Function: SDL_KeyUp Purpose: To pass the SDL_KeyUp message from the emulator to the plugin. input: keymod and keysym of the SDL_KEYUP message. output: none *******************************************************************/ EXPORT void CALL SDL_KeyUp(int keymod, int keysym) { } #pragma endregion /****************************************************************** Function: GetKeys Purpose: To get the current state of the controllers buttons. input: - Controller Number (0 to 3) - A pointer to a BUTTONS structure to be filled with the controller state. output: none *******************************************************************/ EXPORT void CALL GetKeys( int Control, BUTTONS *Keys ) { Keys->Value = (*l_inputCallback)(Control); } EXPORT void CALL SetInputCallback(int (*inputCallback)(int i)) { l_inputCallback = inputCallback; }