Sacrificed ~330 LoC and mupen64plus-audio-sdl to the great gods of the trash can. No functional changes.

This commit is contained in:
null_ptr 2014-01-21 18:10:27 +00:00
parent 4012f93f31
commit f69089a617
28 changed files with 104 additions and 5391 deletions

View File

@ -51,6 +51,9 @@
<Link>
<GenerateDebugInformation>true</GenerateDebugInformation>
</Link>
<PostBuildEvent>
<Command>xcopy /y "$(OutDir)$(TargetName)$(TargetExt)" "$(TargetDir)..\..\..\..\..\output\dll\"</Command>
</PostBuildEvent>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<ClCompile>
@ -72,7 +75,7 @@
<SubSystem>Windows</SubSystem>
</Link>
<PostBuildEvent>
<Command>xcopy /y $(OutDir)$(TargetName)$(TargetExt) $(TargetDir)..\..\..\..\..\output\dll\</Command>
<Command>xcopy /y "$(OutDir)$(TargetName)$(TargetExt)" "$(TargetDir)..\..\..\..\..\output\dll\"</Command>
</PostBuildEvent>
</ItemDefinitionGroup>
<ItemGroup>
@ -81,7 +84,6 @@
</ItemGroup>
<ItemGroup>
<ClInclude Include="..\osal_dynamiclib.h" />
<ClInclude Include="..\osal_preproc.h" />
<ClInclude Include="..\plugin.h" />
<ClInclude Include="..\version.h" />
</ItemGroup>

View File

@ -1,37 +0,0 @@
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
* Mupen64plus-core - osal/dynamiclib_unix.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. *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
#include <stdlib.h>
#include <stdio.h>
#include <dlfcn.h>
#include "m64p_types.h"
#include "osal_dynamiclib.h"
void * osal_dynlib_getproc(m64p_dynlib_handle LibHandle, const char *pccProcedureName)
{
if (pccProcedureName == NULL)
return NULL;
return dlsym(LibHandle, pccProcedureName);
}

View File

@ -1,33 +0,0 @@
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
* Mupen64plus - osal_preproc.h *
* Mupen64Plus homepage: http://code.google.com/p/mupen64plus/ *
* Copyright (C) 2009 Richard Goedeken *
* Copyright (C) 2002 Hacktarux *
* *
* 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 header file is for system-dependent #defines, #includes, and typedefs */
#if !defined(OSAL_PREPROC_H)
#define OSAL_PREPROC_H
#if defined(WIN32)
#define strcasestr strstr
#define strcasecmp _stricmp
#endif // WIN32
#endif // OSAL_PREPROC_H

View File

@ -1,6 +1,7 @@
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
* Mupen64plus-input-sdl - plugin.c *
* 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 *
@ -38,26 +39,6 @@
#include <errno.h>
/* definitions of pointers to Core config functions */
ptr_ConfigOpenSection ConfigOpenSection = NULL;
ptr_ConfigDeleteSection ConfigDeleteSection = NULL;
ptr_ConfigSetParameter ConfigSetParameter = NULL;
ptr_ConfigGetParameter ConfigGetParameter = 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;
/* global data definitions */
SController controller[4]; // 4 controllers
@ -68,37 +49,8 @@ static int l_PluginInit = 0;
static void (*l_inputCallback)() = NULL;
static unsigned short button_bits[] = {
0x0001, // R_DPAD
0x0002, // L_DPAD
0x0004, // D_DPAD
0x0008, // U_DPAD
0x0010, // START_BUTTON
0x0020, // Z_TRIG
0x0040, // B_BUTTON
0x0080, // A_BUTTON
0x0100, // R_CBUTTON
0x0200, // L_CBUTTON
0x0400, // D_CBUTTON
0x0800, // U_CBUTTON
0x1000, // R_TRIG
0x2000, // L_TRIG
0x4000, // Mempak switch
0x8000 // Rumblepak switch
};
static int romopen = 0; // is a rom opened
static unsigned char myKeyState[SDL_NUM_SCANCODES];
BUTTONS controllers[4];
#ifdef __linux__
static struct ff_effect ffeffect[3];
static struct ff_effect ffstrong[3];
static struct ff_effect ffweak[3];
#endif //__linux__
/* Global functions */
void DebugMessage(int level, const char *message, ...)
{
@ -116,7 +68,7 @@ void DebugMessage(int level, const char *message, ...)
va_end(args);
}
static CONTROL temp_core_controlinfo[4];
#pragma region (De-)Initialization
/* Mupen64Plus plugin functions */
EXPORT m64p_error CALL PluginStartup(m64p_dynlib_handle CoreLibHandle, void *Context,
@ -124,7 +76,7 @@ EXPORT m64p_error CALL PluginStartup(m64p_dynlib_handle CoreLibHandle, void *Con
{
ptr_CoreGetAPIVersions CoreAPIVersionFunc;
int i, ConfigAPIVersion, DebugAPIVersion, VidextAPIVersion;
int ConfigAPIVersion, DebugAPIVersion, VidextAPIVersion;
if (l_PluginInit)
return M64ERR_ALREADY_INIT;
@ -140,7 +92,7 @@ EXPORT m64p_error CALL PluginStartup(m64p_dynlib_handle CoreLibHandle, void *Con
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))
{
@ -149,45 +101,8 @@ EXPORT m64p_error CALL PluginStartup(m64p_dynlib_handle CoreLibHandle, void *Con
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");
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 || !ConfigDeleteSection || !ConfigSetParameter || !ConfigGetParameter ||
!ConfigSetDefaultInt || !ConfigSetDefaultFloat || !ConfigSetDefaultBool || !ConfigSetDefaultString ||
!ConfigGetParamInt || !ConfigGetParamFloat || !ConfigGetParamBool || !ConfigGetParamString ||
!ConfigGetSharedDataFilepath || !ConfigGetUserConfigPath || !ConfigGetUserDataPath || !ConfigGetUserCachePath)
{
DebugMessage(M64MSG_ERROR, "Couldn't connect to Core configuration functions");
return M64ERR_INCOMPATIBLE;
}
/* reset controllers */
memset(controller, 0, sizeof(SController) * 4);
for (i = 0; i < SDL_NUM_SCANCODES; i++)
{
myKeyState[i] = 0;
}
/* set CONTROL struct pointers to the temporary static array */
/* this small struct is used to tell the core whether each controller is plugged in, and what type of pak is connected */
/* we only need it so that we can call load_configuration below, to auto-config for a GUI front-end */
for (i = 0; i < 4; i++)
controller[i].control = temp_core_controlinfo + i;
memset(controller, 0, sizeof(controller));
l_PluginInit = 1;
return M64ERR_SUCCESS;
@ -203,177 +118,10 @@ EXPORT m64p_error CALL PluginShutdown(void)
l_DebugCallContext = NULL;
l_PluginInit = 0;
memset(controller, 0, sizeof(controller));
return M64ERR_SUCCESS;
}
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;
}
static unsigned char DataCRC( unsigned char *Data, int iLenght )
{
unsigned char Remainder = Data[0];
int iByte = 1;
unsigned char bBit = 0;
while( iByte <= iLenght )
{
int HighBit = ((Remainder & 0x80) != 0);
Remainder = Remainder << 1;
Remainder += ( iByte < iLenght && Data[iByte] & (0x80 >> bBit )) ? 1 : 0;
Remainder ^= (HighBit) ? 0x85 : 0;
bBit++;
iByte += bBit/8;
bBit %= 8;
}
return Remainder;
}
/******************************************************************
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)
{
unsigned char *Data = &Command[5];
if (Control == -1)
return;
switch (Command[2])
{
case RD_GETSTATUS:
#ifdef _DEBUG
DebugMessage(M64MSG_INFO, "Get status");
#endif
break;
case RD_READKEYS:
#ifdef _DEBUG
DebugMessage(M64MSG_INFO, "Read keys");
#endif
break;
case RD_READPAK:
#ifdef _DEBUG
DebugMessage(M64MSG_INFO, "Read pak");
#endif
if (controller[Control].control->Plugin == PLUGIN_RAW)
{
unsigned int dwAddress = (Command[3] << 8) + (Command[4] & 0xE0);
if(( dwAddress >= 0x8000 ) && ( dwAddress < 0x9000 ) )
memset( Data, 0x80, 32 );
else
memset( Data, 0x00, 32 );
Data[32] = DataCRC( Data, 32 );
}
break;
case RD_WRITEPAK:
#ifdef _DEBUG
DebugMessage(M64MSG_INFO, "Write pak");
#endif
if (controller[Control].control->Plugin == PLUGIN_RAW)
{
unsigned int dwAddress = (Command[3] << 8) + (Command[4] & 0xE0);
if (dwAddress == PAK_IO_RUMBLE && *Data)
DebugMessage(M64MSG_VERBOSE, "Triggering rumble pack.");
#ifdef __linux__
struct input_event play;
if( dwAddress == PAK_IO_RUMBLE && controller[Control].event_joystick != 0)
{
if( *Data )
{
play.type = EV_FF;
play.code = ffeffect[Control].id;
play.value = 1;
if (write(controller[Control].event_joystick, (const void*) &play, sizeof(play)) == -1)
perror("Error starting rumble effect");
}
else
{
play.type = EV_FF;
play.code = ffeffect[Control].id;
play.value = 0;
if (write(controller[Control].event_joystick, (const void*) &play, sizeof(play)) == -1)
perror("Error stopping rumble effect");
}
}
#endif //__linux__
Data[32] = DataCRC( Data, 32 );
}
break;
case RD_RESETCONTROLLER:
#ifdef _DEBUG
DebugMessage(M64MSG_INFO, "Reset controller");
#endif
break;
case RD_READEEPROM:
#ifdef _DEBUG
DebugMessage(M64MSG_INFO, "Read eeprom");
#endif
break;
case RD_WRITEEPROM:
#ifdef _DEBUG
DebugMessage(M64MSG_INFO, "Write eeprom");
#endif
break;
}
}
/******************************************************************
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 )
{
(*l_inputCallback)();
(*Keys).Value = controllers[Control].Value;
}
/******************************************************************
Function: InitiateControllers
Purpose: This function initialises how each of the controllers
@ -386,7 +134,7 @@ EXPORT void CALL GetKeys( int Control, BUTTONS *Keys )
EXPORT void CALL InitiateControllers(CONTROL_INFO ControlInfo)
{
int i;
memset( controller, 0, sizeof( SController ) * 4 );
memset( controller, 0, sizeof(controller) );
for( i = 0; i < 4; i++ )
{
@ -398,26 +146,6 @@ EXPORT void CALL InitiateControllers(CONTROL_INFO ControlInfo)
DebugMessage(M64MSG_INFO, "%s version %i.%i.%i initialized.", PLUGIN_NAME, VERSION_PRINTF_SPLIT(PLUGIN_VERSION));
}
/******************************************************************
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)
{
#ifdef _DEBUG
if (Command != NULL)
DebugMessage(M64MSG_INFO, "Raw Read (cont=%d): %02X %02X %02X %02X %02X %02X", Control,
Command[0], Command[1], Command[2], Command[3], Command[4], Command[5]);
#endif
}
/******************************************************************
Function: RomClosed
Purpose: This function is called when a rom is closed.
@ -442,6 +170,74 @@ EXPORT int CALL RomOpen(void)
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
@ -464,25 +260,31 @@ 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 )
{
(*l_inputCallback)();
Keys->Value = controller[Control].buttons.Value;
}
/* ----------------------------------------------------------------------
----------- Sets the internal buttons delegated to mupen64 -----------
---------------------------------------------------------------------- */
EXPORT void CALL SetKeys(int num, int keys, char X, char Y)
{
controllers[num].R_DPAD = (keys >> 0) & 0x01;
controllers[num].L_DPAD = (keys >> 1) & 0x01;
controllers[num].D_DPAD = (keys >> 2) & 0x01;
controllers[num].U_DPAD = (keys >> 3) & 0x01;
controllers[num].START_BUTTON = (keys >> 4) & 0x01;
controllers[num].Z_TRIG = (keys >> 5) & 0x01;
controllers[num].B_BUTTON = (keys >> 6) & 0x01;
controllers[num].A_BUTTON = (keys >> 7) & 0x01;
controllers[num].R_CBUTTON = (keys >> 8) & 0x01;
controllers[num].L_CBUTTON = (keys >> 9) & 0x01;
controllers[num].D_CBUTTON = (keys >> 10) & 0x01;
controllers[num].U_CBUTTON = (keys >> 11) & 0x01;
controllers[num].R_TRIG = (keys >> 12) & 0x01;
controllers[num].L_TRIG = (keys >> 13) & 0x01;
controller[num].buttons.Value = keys;
controllers[num].X_AXIS = X;
controllers[num].Y_AXIS = Y;
controller[num].buttons.X_AXIS = X;
controller[num].buttons.Y_AXIS = Y;
}
EXPORT void CALL SetInputCallback(void (*inputCallback)())

View File

@ -24,122 +24,14 @@
#ifndef __PLUGIN_H__
#define __PLUGIN_H__
#include <SDL.h>
#if ! SDL_VERSION_ATLEAST(1,3,0)
#define SDL_GetKeyboardState SDL_GetKeyState
#define SDL_SCANCODE_UNKNOWN SDLK_UNKNOWN
#define SDL_NUM_SCANCODES SDLK_LAST
#define SDL_SCANCODE_RCTRL SDLK_RCTRL
#define SDL_SCANCODE_RSHIFT SDLK_RSHIFT
#define SDL_SCANCODE_LCTRL SDLK_LCTRL
#define SDL_SCANCODE_LALT SDLK_LALT
#define SDL_Scancode SDLKey
#endif
#if SDL_VERSION_ATLEAST(2,0,0)
static inline const char* _SDL_JoystickName(int device_index)
{
SDL_Joystick *joystick;
const char *name;
static char JoyName[256];
joystick = SDL_JoystickOpen(device_index);
if (!joystick)
return NULL;
name = SDL_JoystickName(joystick);
if (name)
{
strncpy(JoyName, name, 255);
JoyName[255] = 0;
}
SDL_JoystickClose(joystick);
return JoyName;
}
#define SDL_JoystickName(device_index) _SDL_JoystickName(device_index)
#endif
#define M64P_PLUGIN_PROTOTYPES 1
#include "m64p_plugin.h"
#include "m64p_config.h"
#define DEVICE_AUTO (-1)
#define DEVICE_NOT_JOYSTICK (-2)
// Some stuff from n-rage plugin
#define RD_GETSTATUS 0x00 // get status
#define RD_READKEYS 0x01 // read button values
#define RD_READPAK 0x02 // read from controllerpack
#define RD_WRITEPAK 0x03 // write to controllerpack
#define RD_RESETCONTROLLER 0xff // reset controller
#define RD_READEEPROM 0x04 // read eeprom
#define RD_WRITEEPROM 0x05 // write eeprom
#define PAK_IO_RUMBLE 0xC000 // the address where rumble-commands are sent to
enum EButton
{
R_DPAD = 0,
L_DPAD,
D_DPAD,
U_DPAD,
START_BUTTON,
Z_TRIG,
B_BUTTON,
A_BUTTON,
R_CBUTTON,
L_CBUTTON,
D_CBUTTON,
U_CBUTTON,
R_TRIG,
L_TRIG,
MEMPAK,
RUMBLEPAK,
X_AXIS,
Y_AXIS,
NUM_BUTTONS
};
typedef struct
{
int button; // button index; -1 if notassigned
SDL_Scancode key; // sdl keysym; SDL_SCANCODE_UNKNOWN if not assigned
int axis, axis_dir; // aixs + direction (i.e. 0, 1 = X Axis +; 0, -1 = X Axis -); -1 if notassigned
int axis_deadzone; // -1 for default, or >= 0 for custom value
int hat, hat_pos; // hat + hat position; -1 if not assigned
int mouse; // mouse button
} SButtonMap;
typedef struct
{
int button_a, button_b; // up/down or left/right; -1 if not assigned
SDL_Scancode key_a, key_b; // up/down or left/right; SDL_SCANCODE_UNKNOWN if not assigned
int axis_a, axis_b; // axis index; -1 if not assigned
int axis_dir_a, axis_dir_b; // direction (1 = X+, 0, -1 = X-)
int hat, hat_pos_a, hat_pos_b; // hat + hat position up/down and left/right; -1 if not assigned
} SAxisMap;
typedef struct
{
CONTROL *control; // pointer to CONTROL struct in Core library
BUTTONS buttons;
// mappings
SButtonMap button[16]; // 14 buttons; in the order of EButton + mempak/rumblepak switches
SAxisMap axis[2]; // 2 axis
int device; // joystick device; -1 = keyboard; -2 = none
int mouse; // mouse enabled: 0 = no; 1 = yes
SDL_Joystick *joystick; // SDL joystick device
int event_joystick; // the /dev/input/eventX device for force feeback
int axis_deadzone[2]; // minimum absolute value before analog movement is recognized
int axis_peak[2]; // highest analog value returned by SDL, used for scaling
float mouse_sens[2]; // mouse sensitivity
} SController;
/* global data definitions */
@ -148,28 +40,4 @@ extern SController controller[4]; // 4 controllers
/* global function definitions */
extern void DebugMessage(int level, const char *message, ...);
/* declarations of pointers to Core config functions */
extern ptr_ConfigListSections ConfigListSections;
extern ptr_ConfigOpenSection ConfigOpenSection;
extern ptr_ConfigDeleteSection ConfigDeleteSection;
extern ptr_ConfigListParameters ConfigListParameters;
extern ptr_ConfigSaveFile ConfigSaveFile;
extern ptr_ConfigSetParameter ConfigSetParameter;
extern ptr_ConfigGetParameter ConfigGetParameter;
extern ptr_ConfigGetParameterHelp ConfigGetParameterHelp;
extern ptr_ConfigSetDefaultInt ConfigSetDefaultInt;
extern ptr_ConfigSetDefaultFloat ConfigSetDefaultFloat;
extern ptr_ConfigSetDefaultBool ConfigSetDefaultBool;
extern ptr_ConfigSetDefaultString ConfigSetDefaultString;
extern ptr_ConfigGetParamInt ConfigGetParamInt;
extern ptr_ConfigGetParamFloat ConfigGetParamFloat;
extern ptr_ConfigGetParamBool ConfigGetParamBool;
extern ptr_ConfigGetParamString ConfigGetParamString;
extern ptr_ConfigGetSharedDataFilepath ConfigGetSharedDataFilepath;
extern ptr_ConfigGetUserConfigPath ConfigGetUserConfigPath;
extern ptr_ConfigGetUserDataPath ConfigGetUserDataPath;
extern ptr_ConfigGetUserCachePath ConfigGetUserCachePath;
#endif // __PLUGIN_H__

View File

@ -1,6 +1,6 @@
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
* Mupen64plus-input-sdl - version.h *
* Mupen64Plus homepage: http://code.google.com/p/mupen64plus/ *
* Mupen64plus-input-bkm - version.h *
* Edited 2014 null_ptr *
* Copyright (C) 2009-2012 Richard Goedeken *
* *
* This program is free software; you can redistribute it and/or modify *

View File

@ -1,4 +0,0 @@
Original author: Gregor Anich <blight>
Subsequent authors: many people from the Mupen64Plus team have worked on this code.

View File

@ -1,340 +0,0 @@
GNU GENERAL PUBLIC LICENSE
Version 2, June 1991
Copyright (C) 1989, 1991 Free Software Foundation, Inc.
59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
Preamble
The licenses for most software are designed to take away your
freedom to share and change it. By contrast, the GNU General Public
License is intended to guarantee your freedom to share and change free
software--to make sure the software is free for all its users. This
General Public License applies to most of the Free Software
Foundation's software and to any other program whose authors commit to
using it. (Some other Free Software Foundation software is covered by
the GNU Library General Public License instead.) You can apply it to
your programs, too.
When we speak of free software, we are referring to freedom, not
price. Our General Public Licenses are designed to make sure that you
have the freedom to distribute copies of free software (and charge for
this service if you wish), that you receive source code or can get it
if you want it, that you can change the software or use pieces of it
in new free programs; and that you know you can do these things.
To protect your rights, we need to make restrictions that forbid
anyone to deny you these rights or to ask you to surrender the rights.
These restrictions translate to certain responsibilities for you if you
distribute copies of the software, or if you modify it.
For example, if you distribute copies of such a program, whether
gratis or for a fee, you must give the recipients all the rights that
you have. You must make sure that they, too, receive or can get the
source code. And you must show them these terms so they know their
rights.
We protect your rights with two steps: (1) copyright the software, and
(2) offer you this license which gives you legal permission to copy,
distribute and/or modify the software.
Also, for each author's protection and ours, we want to make certain
that everyone understands that there is no warranty for this free
software. If the software is modified by someone else and passed on, we
want its recipients to know that what they have is not the original, so
that any problems introduced by others will not reflect on the original
authors' reputations.
Finally, any free program is threatened constantly by software
patents. We wish to avoid the danger that redistributors of a free
program will individually obtain patent licenses, in effect making the
program proprietary. To prevent this, we have made it clear that any
patent must be licensed for everyone's free use or not licensed at all.
The precise terms and conditions for copying, distribution and
modification follow.
GNU GENERAL PUBLIC LICENSE
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
0. This License applies to any program or other work which contains
a notice placed by the copyright holder saying it may be distributed
under the terms of this General Public License. The "Program", below,
refers to any such program or work, and a "work based on the Program"
means either the Program or any derivative work under copyright law:
that is to say, a work containing the Program or a portion of it,
either verbatim or with modifications and/or translated into another
language. (Hereinafter, translation is included without limitation in
the term "modification".) Each licensee is addressed as "you".
Activities other than copying, distribution and modification are not
covered by this License; they are outside its scope. The act of
running the Program is not restricted, and the output from the Program
is covered only if its contents constitute a work based on the
Program (independent of having been made by running the Program).
Whether that is true depends on what the Program does.
1. You may copy and distribute verbatim copies of the Program's
source code as you receive it, in any medium, provided that you
conspicuously and appropriately publish on each copy an appropriate
copyright notice and disclaimer of warranty; keep intact all the
notices that refer to this License and to the absence of any warranty;
and give any other recipients of the Program a copy of this License
along with the Program.
You may charge a fee for the physical act of transferring a copy, and
you may at your option offer warranty protection in exchange for a fee.
2. You may modify your copy or copies of the Program or any portion
of it, thus forming a work based on the Program, and copy and
distribute such modifications or work under the terms of Section 1
above, provided that you also meet all of these conditions:
a) You must cause the modified files to carry prominent notices
stating that you changed the files and the date of any change.
b) You must cause any work that you distribute or publish, that in
whole or in part contains or is derived from the Program or any
part thereof, to be licensed as a whole at no charge to all third
parties under the terms of this License.
c) If the modified program normally reads commands interactively
when run, you must cause it, when started running for such
interactive use in the most ordinary way, to print or display an
announcement including an appropriate copyright notice and a
notice that there is no warranty (or else, saying that you provide
a warranty) and that users may redistribute the program under
these conditions, and telling the user how to view a copy of this
License. (Exception: if the Program itself is interactive but
does not normally print such an announcement, your work based on
the Program is not required to print an announcement.)
These requirements apply to the modified work as a whole. If
identifiable sections of that work are not derived from the Program,
and can be reasonably considered independent and separate works in
themselves, then this License, and its terms, do not apply to those
sections when you distribute them as separate works. But when you
distribute the same sections as part of a whole which is a work based
on the Program, the distribution of the whole must be on the terms of
this License, whose permissions for other licensees extend to the
entire whole, and thus to each and every part regardless of who wrote it.
Thus, it is not the intent of this section to claim rights or contest
your rights to work written entirely by you; rather, the intent is to
exercise the right to control the distribution of derivative or
collective works based on the Program.
In addition, mere aggregation of another work not based on the Program
with the Program (or with a work based on the Program) on a volume of
a storage or distribution medium does not bring the other work under
the scope of this License.
3. You may copy and distribute the Program (or a work based on it,
under Section 2) in object code or executable form under the terms of
Sections 1 and 2 above provided that you also do one of the following:
a) Accompany it with the complete corresponding machine-readable
source code, which must be distributed under the terms of Sections
1 and 2 above on a medium customarily used for software interchange; or,
b) Accompany it with a written offer, valid for at least three
years, to give any third party, for a charge no more than your
cost of physically performing source distribution, a complete
machine-readable copy of the corresponding source code, to be
distributed under the terms of Sections 1 and 2 above on a medium
customarily used for software interchange; or,
c) Accompany it with the information you received as to the offer
to distribute corresponding source code. (This alternative is
allowed only for noncommercial distribution and only if you
received the program in object code or executable form with such
an offer, in accord with Subsection b above.)
The source code for a work means the preferred form of the work for
making modifications to it. For an executable work, complete source
code means all the source code for all modules it contains, plus any
associated interface definition files, plus the scripts used to
control compilation and installation of the executable. However, as a
special exception, the source code distributed need not include
anything that is normally distributed (in either source or binary
form) with the major components (compiler, kernel, and so on) of the
operating system on which the executable runs, unless that component
itself accompanies the executable.
If distribution of executable or object code is made by offering
access to copy from a designated place, then offering equivalent
access to copy the source code from the same place counts as
distribution of the source code, even though third parties are not
compelled to copy the source along with the object code.
4. You may not copy, modify, sublicense, or distribute the Program
except as expressly provided under this License. Any attempt
otherwise to copy, modify, sublicense or distribute the Program is
void, and will automatically terminate your rights under this License.
However, parties who have received copies, or rights, from you under
this License will not have their licenses terminated so long as such
parties remain in full compliance.
5. You are not required to accept this License, since you have not
signed it. However, nothing else grants you permission to modify or
distribute the Program or its derivative works. These actions are
prohibited by law if you do not accept this License. Therefore, by
modifying or distributing the Program (or any work based on the
Program), you indicate your acceptance of this License to do so, and
all its terms and conditions for copying, distributing or modifying
the Program or works based on it.
6. Each time you redistribute the Program (or any work based on the
Program), the recipient automatically receives a license from the
original licensor to copy, distribute or modify the Program subject to
these terms and conditions. You may not impose any further
restrictions on the recipients' exercise of the rights granted herein.
You are not responsible for enforcing compliance by third parties to
this License.
7. If, as a consequence of a court judgment or allegation of patent
infringement or for any other reason (not limited to patent issues),
conditions are imposed on you (whether by court order, agreement or
otherwise) that contradict the conditions of this License, they do not
excuse you from the conditions of this License. If you cannot
distribute so as to satisfy simultaneously your obligations under this
License and any other pertinent obligations, then as a consequence you
may not distribute the Program at all. For example, if a patent
license would not permit royalty-free redistribution of the Program by
all those who receive copies directly or indirectly through you, then
the only way you could satisfy both it and this License would be to
refrain entirely from distribution of the Program.
If any portion of this section is held invalid or unenforceable under
any particular circumstance, the balance of the section is intended to
apply and the section as a whole is intended to apply in other
circumstances.
It is not the purpose of this section to induce you to infringe any
patents or other property right claims or to contest validity of any
such claims; this section has the sole purpose of protecting the
integrity of the free software distribution system, which is
implemented by public license practices. Many people have made
generous contributions to the wide range of software distributed
through that system in reliance on consistent application of that
system; it is up to the author/donor to decide if he or she is willing
to distribute software through any other system and a licensee cannot
impose that choice.
This section is intended to make thoroughly clear what is believed to
be a consequence of the rest of this License.
8. If the distribution and/or use of the Program is restricted in
certain countries either by patents or by copyrighted interfaces, the
original copyright holder who places the Program under this License
may add an explicit geographical distribution limitation excluding
those countries, so that distribution is permitted only in or among
countries not thus excluded. In such case, this License incorporates
the limitation as if written in the body of this License.
9. The Free Software Foundation may publish revised and/or new versions
of the General Public License from time to time. Such new versions will
be similar in spirit to the present version, but may differ in detail to
address new problems or concerns.
Each version is given a distinguishing version number. If the Program
specifies a version number of this License which applies to it and "any
later version", you have the option of following the terms and conditions
either of that version or of any later version published by the Free
Software Foundation. If the Program does not specify a version number of
this License, you may choose any version ever published by the Free Software
Foundation.
10. If you wish to incorporate parts of the Program into other free
programs whose distribution conditions are different, write to the author
to ask for permission. For software which is copyrighted by the Free
Software Foundation, write to the Free Software Foundation; we sometimes
make exceptions for this. Our decision will be guided by the two goals
of preserving the free status of all derivatives of our free software and
of promoting the sharing and reuse of software generally.
NO WARRANTY
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
REPAIR OR CORRECTION.
12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
POSSIBILITY OF SUCH DAMAGES.
END OF TERMS AND CONDITIONS
How to Apply These Terms to Your New Programs
If you develop a new program, and you want it to be of the greatest
possible use to the public, the best way to achieve this is to make it
free software which everyone can redistribute and change under these terms.
To do so, attach the following notices to the program. It is safest
to attach them to the start of each source file to most effectively
convey the exclusion of warranty; and each file should have at least
the "copyright" line and a pointer to where the full notice is found.
<one line to give the program's name and a brief idea of what it does.>
Copyright (C) 19yy <name of author>
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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
Also add information on how to contact you by electronic and paper mail.
If the program is interactive, make it output a short notice like this
when it starts in an interactive mode:
Gnomovision version 69, Copyright (C) 19yy name of author
Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
This is free software, and you are welcome to redistribute it
under certain conditions; type `show c' for details.
The hypothetical commands `show w' and `show c' should show the appropriate
parts of the General Public License. Of course, the commands you use may
be called something other than `show w' and `show c'; they could even be
mouse-clicks or menu items--whatever suits your program.
You should also get your employer (if you work as a programmer) or your
school, if any, to sign a "copyright disclaimer" for the program, if
necessary. Here is a sample; alter the names:
Yoyodyne, Inc., hereby disclaims all copyright interest in the program
`Gnomovision' (which makes passes at compilers) written by James Hacker.
<signature of Ty Coon>, 1 April 1989
Ty Coon, President of Vice
This General Public License does not permit incorporating your program into
proprietary programs. If your program is a subroutine library, you may
consider it more useful to permit linking proprietary applications with the
library. If this is what you want to do, use the GNU Library General
Public License instead of this License.

View File

@ -1,26 +0,0 @@
Mupen64Plus-Input-SDL INSTALL
-----------------------------
This text file was written to explain the installation process of the
Mupen64Plus-Input-SDL module.
If this module is part of a Mupen64Plus source code bundle, the user should run
the "m64p_install.sh" script in the root of the unzipped bundle to install all
of the included modules in the bundle.
If this module is a standalone source code release, you should build the library
from source code and install it via the makefile, like this:
$ cd projects/unix
$ make all
$ sudo make install
If you want to build the Mupen64Plus-Input-SDL module for installation in a
home folder for a single user, you may build it like this (replacing
<my-folder> with your desired local installation path):
$ cd projects/unix
$ make all
$ make install LIBDIR=<my-folder>

View File

@ -1,368 +0,0 @@
Mupen64Plus-input-sdl LICENSE
-----------------------------
Mupen64Plus-input-sdl is licensed under the GNU General Public License version 2.
The authors of Mupen64Plus are:
* Richard Goedeken (Richard42)
* John Chadwick (NMN)
* James Hood (Ebenblues)
* Scott Gorman (okaygo)
* Scott Knauert (Tillin9)
* Jesse Dean (DarkJezter)
* Louai Al-Khanji (slougi)
* Bob Forder (orbitaldecay)
* Jason Espinosa (hasone)
* HyperHacker
* and others.
Mupen64Plus is based on GPL-licensed source code from Mupen64 v0.5, originally written by:
* Hacktarux
* Dave2001
* Zilmar
* Gregor Anich (Blight)
* Juha Luotio (JttL)
* and others.
GNU GENERAL PUBLIC LICENSE
Version 2, June 1991
Copyright (C) 1989, 1991 Free Software Foundation, Inc.
675 Mass Ave, Cambridge, MA 02139, USA
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
Preamble
The licenses for most software are designed to take away your
freedom to share and change it. By contrast, the GNU General Public
License is intended to guarantee your freedom to share and change free
software--to make sure the software is free for all its users. This
General Public License applies to most of the Free Software
Foundation's software and to any other program whose authors commit to
using it. (Some other Free Software Foundation software is covered by
the GNU Library General Public License instead.) You can apply it to
your programs, too.
When we speak of free software, we are referring to freedom, not
price. Our General Public Licenses are designed to make sure that you
have the freedom to distribute copies of free software (and charge for
this service if you wish), that you receive source code or can get it
if you want it, that you can change the software or use pieces of it
in new free programs; and that you know you can do these things.
To protect your rights, we need to make restrictions that forbid
anyone to deny you these rights or to ask you to surrender the rights.
These restrictions translate to certain responsibilities for you if you
distribute copies of the software, or if you modify it.
For example, if you distribute copies of such a program, whether
gratis or for a fee, you must give the recipients all the rights that
you have. You must make sure that they, too, receive or can get the
source code. And you must show them these terms so they know their
rights.
We protect your rights with two steps: (1) copyright the software, and
(2) offer you this license which gives you legal permission to copy,
distribute and/or modify the software.
Also, for each author's protection and ours, we want to make certain
that everyone understands that there is no warranty for this free
software. If the software is modified by someone else and passed on, we
want its recipients to know that what they have is not the original, so
that any problems introduced by others will not reflect on the original
authors' reputations.
Finally, any free program is threatened constantly by software
patents. We wish to avoid the danger that redistributors of a free
program will individually obtain patent licenses, in effect making the
program proprietary. To prevent this, we have made it clear that any
patent must be licensed for everyone's free use or not licensed at all.
The precise terms and conditions for copying, distribution and
modification follow.
GNU GENERAL PUBLIC LICENSE
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
0. This License applies to any program or other work which contains
a notice placed by the copyright holder saying it may be distributed
under the terms of this General Public License. The "Program", below,
refers to any such program or work, and a "work based on the Program"
means either the Program or any derivative work under copyright law:
that is to say, a work containing the Program or a portion of it,
either verbatim or with modifications and/or translated into another
language. (Hereinafter, translation is included without limitation in
the term "modification".) Each licensee is addressed as "you".
Activities other than copying, distribution and modification are not
covered by this License; they are outside its scope. The act of
running the Program is not restricted, and the output from the Program
is covered only if its contents constitute a work based on the
Program (independent of having been made by running the Program).
Whether that is true depends on what the Program does.
1. You may copy and distribute verbatim copies of the Program's
source code as you receive it, in any medium, provided that you
conspicuously and appropriately publish on each copy an appropriate
copyright notice and disclaimer of warranty; keep intact all the
notices that refer to this License and to the absence of any warranty;
and give any other recipients of the Program a copy of this License
along with the Program.
You may charge a fee for the physical act of transferring a copy, and
you may at your option offer warranty protection in exchange for a fee.
2. You may modify your copy or copies of the Program or any portion
of it, thus forming a work based on the Program, and copy and
distribute such modifications or work under the terms of Section 1
above, provided that you also meet all of these conditions:
a) You must cause the modified files to carry prominent notices
stating that you changed the files and the date of any change.
b) You must cause any work that you distribute or publish, that in
whole or in part contains or is derived from the Program or any
part thereof, to be licensed as a whole at no charge to all third
parties under the terms of this License.
c) If the modified program normally reads commands interactively
when run, you must cause it, when started running for such
interactive use in the most ordinary way, to print or display an
announcement including an appropriate copyright notice and a
notice that there is no warranty (or else, saying that you provide
a warranty) and that users may redistribute the program under
these conditions, and telling the user how to view a copy of this
License. (Exception: if the Program itself is interactive but
does not normally print such an announcement, your work based on
the Program is not required to print an announcement.)
These requirements apply to the modified work as a whole. If
identifiable sections of that work are not derived from the Program,
and can be reasonably considered independent and separate works in
themselves, then this License, and its terms, do not apply to those
sections when you distribute them as separate works. But when you
distribute the same sections as part of a whole which is a work based
on the Program, the distribution of the whole must be on the terms of
this License, whose permissions for other licensees extend to the
entire whole, and thus to each and every part regardless of who wrote it.
Thus, it is not the intent of this section to claim rights or contest
your rights to work written entirely by you; rather, the intent is to
exercise the right to control the distribution of derivative or
collective works based on the Program.
In addition, mere aggregation of another work not based on the Program
with the Program (or with a work based on the Program) on a volume of
a storage or distribution medium does not bring the other work under
the scope of this License.
3. You may copy and distribute the Program (or a work based on it,
under Section 2) in object code or executable form under the terms of
Sections 1 and 2 above provided that you also do one of the following:
a) Accompany it with the complete corresponding machine-readable
source code, which must be distributed under the terms of Sections
1 and 2 above on a medium customarily used for software interchange; or,
b) Accompany it with a written offer, valid for at least three
years, to give any third party, for a charge no more than your
cost of physically performing source distribution, a complete
machine-readable copy of the corresponding source code, to be
distributed under the terms of Sections 1 and 2 above on a medium
customarily used for software interchange; or,
c) Accompany it with the information you received as to the offer
to distribute corresponding source code. (This alternative is
allowed only for noncommercial distribution and only if you
received the program in object code or executable form with such
an offer, in accord with Subsection b above.)
The source code for a work means the preferred form of the work for
making modifications to it. For an executable work, complete source
code means all the source code for all modules it contains, plus any
associated interface definition files, plus the scripts used to
control compilation and installation of the executable. However, as a
special exception, the source code distributed need not include
anything that is normally distributed (in either source or binary
form) with the major components (compiler, kernel, and so on) of the
operating system on which the executable runs, unless that component
itself accompanies the executable.
If distribution of executable or object code is made by offering
access to copy from a designated place, then offering equivalent
access to copy the source code from the same place counts as
distribution of the source code, even though third parties are not
compelled to copy the source along with the object code.
4. You may not copy, modify, sublicense, or distribute the Program
except as expressly provided under this License. Any attempt
otherwise to copy, modify, sublicense or distribute the Program is
void, and will automatically terminate your rights under this License.
However, parties who have received copies, or rights, from you under
this License will not have their licenses terminated so long as such
parties remain in full compliance.
5. You are not required to accept this License, since you have not
signed it. However, nothing else grants you permission to modify or
distribute the Program or its derivative works. These actions are
prohibited by law if you do not accept this License. Therefore, by
modifying or distributing the Program (or any work based on the
Program), you indicate your acceptance of this License to do so, and
all its terms and conditions for copying, distributing or modifying
the Program or works based on it.
6. Each time you redistribute the Program (or any work based on the
Program), the recipient automatically receives a license from the
original licensor to copy, distribute or modify the Program subject to
these terms and conditions. You may not impose any further
restrictions on the recipients' exercise of the rights granted herein.
You are not responsible for enforcing compliance by third parties to
this License.
7. If, as a consequence of a court judgment or allegation of patent
infringement or for any other reason (not limited to patent issues),
conditions are imposed on you (whether by court order, agreement or
otherwise) that contradict the conditions of this License, they do not
excuse you from the conditions of this License. If you cannot
distribute so as to satisfy simultaneously your obligations under this
License and any other pertinent obligations, then as a consequence you
may not distribute the Program at all. For example, if a patent
license would not permit royalty-free redistribution of the Program by
all those who receive copies directly or indirectly through you, then
the only way you could satisfy both it and this License would be to
refrain entirely from distribution of the Program.
If any portion of this section is held invalid or unenforceable under
any particular circumstance, the balance of the section is intended to
apply and the section as a whole is intended to apply in other
circumstances.
It is not the purpose of this section to induce you to infringe any
patents or other property right claims or to contest validity of any
such claims; this section has the sole purpose of protecting the
integrity of the free software distribution system, which is
implemented by public license practices. Many people have made
generous contributions to the wide range of software distributed
through that system in reliance on consistent application of that
system; it is up to the author/donor to decide if he or she is willing
to distribute software through any other system and a licensee cannot
impose that choice.
This section is intended to make thoroughly clear what is believed to
be a consequence of the rest of this License.
8. If the distribution and/or use of the Program is restricted in
certain countries either by patents or by copyrighted interfaces, the
original copyright holder who places the Program under this License
may add an explicit geographical distribution limitation excluding
those countries, so that distribution is permitted only in or among
countries not thus excluded. In such case, this License incorporates
the limitation as if written in the body of this License.
9. The Free Software Foundation may publish revised and/or new versions
of the General Public License from time to time. Such new versions will
be similar in spirit to the present version, but may differ in detail to
address new problems or concerns.
Each version is given a distinguishing version number. If the Program
specifies a version number of this License which applies to it and "any
later version", you have the option of following the terms and conditions
either of that version or of any later version published by the Free
Software Foundation. If the Program does not specify a version number of
this License, you may choose any version ever published by the Free Software
Foundation.
10. If you wish to incorporate parts of the Program into other free
programs whose distribution conditions are different, write to the author
to ask for permission. For software which is copyrighted by the Free
Software Foundation, write to the Free Software Foundation; we sometimes
make exceptions for this. Our decision will be guided by the two goals
of preserving the free status of all derivatives of our free software and
of promoting the sharing and reuse of software generally.
NO WARRANTY
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
REPAIR OR CORRECTION.
12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
POSSIBILITY OF SUCH DAMAGES.
END OF TERMS AND CONDITIONS
Appendix: How to Apply These Terms to Your New Programs
If you develop a new program, and you want it to be of the greatest
possible use to the public, the best way to achieve this is to make it
free software which everyone can redistribute and change under these terms.
To do so, attach the following notices to the program. It is safest
to attach them to the start of each source file to most effectively
convey the exclusion of warranty; and each file should have at least
the "copyright" line and a pointer to where the full notice is found.
<one line to give the program's name and a brief idea of what it does.>
Copyright (C) 19yy <name of author>
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., 675 Mass Ave, Cambridge, MA 02139, USA.
Also add information on how to contact you by electronic and paper mail.
If the program is interactive, make it output a short notice like this
when it starts in an interactive mode:
Gnomovision version 69, Copyright (C) 19yy name of author
Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
This is free software, and you are welcome to redistribute it
under certain conditions; type `show c' for details.
The hypothetical commands `show w' and `show c' should show the appropriate
parts of the General Public License. Of course, the commands you use may
be called something other than `show w' and `show c'; they could even be
mouse-clicks or menu items--whatever suits your program.
You should also get your employer (if you work as a programmer) or your
school, if any, to sign a "copyright disclaimer" for the program, if
necessary. Here is a sample; alter the names:
Yoyodyne, Inc., hereby disclaims all copyright interest in the program
`Gnomovision' (which makes passes at compilers) written by James Hacker.
<signature of Ty Coon>, 1 April 1989
Ty Coon, President of Vice
This General Public License does not permit incorporating your program into
proprietary programs. If your program is a subroutine library, you may
consider it more useful to permit linking proprietary applications with the
library. If this is what you want to do, use the GNU Library General
Public License instead of this License.

View File

@ -1,125 +0,0 @@
********Notes about usage of SDL input plugin:
- If one of the enabled controllers has the "mouse" general-purpose config parameters set
to True, the plugin will hide the mouse cursor and 'grab' the mouse pointer. The user
may press the Left Control and Alt keys together to toggle the mouse cursor on and off.
- If X/Y analog axes are mapped to keys, a plain keypress will simulate the joystick
being pressed all the way to the edge. To decrease the amount of simulated joystick
deflection, the user may press Right Control, Right Shift, or Right Ctrl+Right Shift.
********Notes for supported joysticks for auto-configuration:
1. Jess Tech Rumble Pad (Saitek Rumble)
The left D-pad is mapped to the D-pad; The joystick is mapped to the left joystick of the gamepad; the C buttons are mapped to the gampad's right joystick. Start button is mapped to start; the A-button is mapped to the lowest button on the gamepad's right front; the B-button to the left button (buttons marked 3 and 1 on my gamepad). The L and R buttons are mapped to the lower left and right rear triggers; the Z button is mapped to the left upper rear trigger. All other buttons are unused.
2. Logitech Dual Action gamepad, Logitech Cordless Rumblepad 2:
The digital pad maps to the N64 d-pad. The left analog stick maps to the N64 analog stick.
The right analog stick maps to the C-buttons, and the buttons 2 and 1 map to A and B.
Button 4 is the Z trigger, and the top shoulder buttons map to the left and right N64 triggers.
Button 10 is the start button.
The bottom shoulder buttons select the memory pack or rumble pak.
3. Logitech Logitech(R) Precision(TM) Gamepad, Gravis GamePad Pro USB
I came up with what I see as one of the few decent configurations (SSB aside) since it allows access to everything but the dpad.
A is L1, B is R1, Z is L2, R is R2, L is select. C buttons are the four buttons, and the dpad acts as the joystick. Not the most orthodox, but it works well.
4. Microsoft X-Box 360 pad:
C button U (up) and C button R (right) are assigned to the Y and B buttons.
All 4 C buttons are assigned to the U and V axis (including the already configured up and right C buttons).
The Z button has been assigned to the left trigger and switching the rumble on and off can be done with the right trigger.
Because there are no other buttons left I decided to use the button click behavior of the left joystick to switch Mempak on and off.
5. MP-8866 Dual USB Joypad:
This is a USB adapter for PlayStation controllers (2).
D-Pad: hat(0)
L-Stick: x:0, y:1
R-Stick: x:2, y:3
Triangle: button(0)
Circle: button(1)
Cross: button(2)
Square: button(3)
L2: button(4)
R2: button(5)
L1: button(6)
R1: button(7)
Start: button(8)
Select: button(9)
L3: button(10)
R3: button(11)
Note: This is when analog mode is selected. If analog is off then D-Pad becomes axes 0/1 and both sticks are disabled (including L3/R3).
6. N64 controller:
All controls are mapped to their proper place on the N64 controller with an Adaptoid or custom hardware with Gamecon driver.
Rumble and Memory packs can be selected with the 'r' and 'm' keys, respectively.
7. Playstation 3 Controller:
Left analog stick - analog stick
Right analog stick - C-pad
D-Pad - D-Pad
Cross - A
Square - B
L1 / R1 - L / R
L2 - Z
Start - Start
8. SAITEK P880:
The gamepad doesnt have enough keys to real assign all buttons. The second
analog stick can be used as button by pushing him insight.
General Configuration:
Digital Pad was used as N64 digital pad, First analog stick was used as N64
Analog stick. The red button was used as N64 Start button. L and R was used
for N64 L and R. Second analog stick axes was used for N64 C buttons and
second "analog stick button" was used for C-down. The first column of keys was
used for A and B and the second and third row was used for C-Buttons - except
for the Button next to the A button which would be C-Down but got the Z
button.
9. Xbox Gamepad (userspace driver)
I created an Input Config for a Xbox 360 controller running with
xboxdrv on a Linux system (http://pingus.seul.org/~grumbel/xboxdrv/).
Z = Left shoulder button
L = Left shoulder trigger
A = A Button
B = X Button
everything else should be obvious.
Unfortunately, you will also have to make some configuration to
xboxdrv to make this work properly. xboxdrv has to be started with the
following config file. The "-as-button" options make sure that the D-
Pad and Trigger are emulated as buttons and the deadzone options make
the C buttons work much better.
The guide=KEY_ESC allows you to quit the emulator by pressing the
guide key on the controller. This is obviously just nice-to-have and
not actually neccessary for the config to work.
[xboxdrv]
silent=true
trigger-as-button=true
dpad-as-button=true
[ui-buttonmap]
guide=KEY_ESC
[axismap]
x2^deadzone:27000
y2^deadzone:27000
10. Saitek Cyborg V.3 Rumble Pad (aka Saitek PS2700)
Honestly, it's one of the best pads that I've used in a long time, so thought I'd contribute this quick config. Basically, Dpad and Analog sticks are unchanged, C-buttons are mapped to the right analog stick, L-R triggers are L1 and R1, Z is mapped to R2, A + B are mapped to X and Square, respectively, start is mapped to the Home button, and Triangle, Square, L2, Start, Select, and the Analog triggers are unused, since it's not intuitive to use them for what's left.
11. Default Keyboard interface:
Analog Pad is "Arrow Keys"
C Up/Left/Down/Right are "I", "J", "K", "L"
DPad Up/Left/Down/Right are "W", "A", "S", "D"
Z trig is "z" key
L and R trigs are "x" and "c"
Start is "Enter" ("Return")
A is "left shift"
B is "left control"
Select Mempack = ","
Select Rumblepack = "."

View File

@ -1,146 +0,0 @@
SDL Input plugin for Mupen64Plus
--------------------------------
Mupen64Plus-input-sdl v1.99.5 - March 10, 2012
-------------------------------------------------
- Improved input setup behavior (auto-config) to make some use cases more friendly
- Updated input plugin for new Mupen64plus 2.0 API versioning scheme
- Added version number to SDL Input plugin parameters
- Add new parameter for mouse sensitivity, handle mouse movement differently so mouse is easier to use as controller
- New auto-configuration for controllers:
- raphnet technologies GC/N64 usb converter
- Logitech Chillstream Controller
- Jess Tech Colour Rumble
- Xbox 360 linux userspace driver
- Generic X-Box pad
- Saitek P2900 Wireless Pad
- Jess Tech USB 4-Axis 12-Button Gamepad
- bugfix: #392 - when switching between rumble pak and memory pak, simulate removing the pack, waiting 1 second, then inserting the new one
- bugfix: #424 - problem with USB devices supporting multiple controllers per device
- bugfix: #409 - PS3 controller not auto-detected in Gentoo when connected via bluetooth
- bugfix: correctly handle USB devices with multiple game pads, from Peter Helbing
- makefile fixes and improvements
Mupen64Plus-input-sdl v1.99.4 - November 22, 2010
-------------------------------------------------
- Bugfix: Do configuration during PluginStart(), so GUI will see defaults (auto-configured) the first time it is run
- Move axis value reducers to right shift and right ctrl, to avoid conflict with A/B buttons
- New feature: extra deadzone parameter in axis() config parameter clause when mapping an analog joystick axis to an N64 button
- many new joystick auto-configurations
- makefile fixes and improvements
Mupen64Plus-input-sdl v1.99.3 - February 13, 2010
-------------------------------------------------
- New feature: auto-configuration uses an .ini file instead of hard-coding the controllers in the source code
- New controller auto-configurations:
- Original X-Box (and compatible clones)
- HuiJia USB GamePad
- USB Human(2p) Interface Device
- sync with core<-->plugin API change for RomOpen()
- Bugfix: controller pak was fixed at startup, switching b/w mempak and rumblepak did not work
- Bugfix: Xbox 360 and PS3 controllers need slightly different names under OSX
- Makefile improvements:
- plugin must be linked with CC instead of LD because 'sdl-config --libs' can give "-Wl,-rpath"
- added OS type GNU/kFreeBSD
Mupen64Plus-input-sdl v1.99.2 - January 6, 2010
-------------------------------------------------
- new feature: added MSVC8 project file, minor code refactoring for VC compatibility
- added auto-configuration for:
- Xbox 360 Wireless Receiver
- PS3 controller
- Jess Tech Dual Analog Pad
- Makefile improvements:
- throw error if OS/CPU not supported
- use DESTDIR in install/uninstall paths
- Allow user-specified CC/CXX/LD paths
Mupen64Plus-input-sdl v1.99.1 - December 14, 2009
-------------------------------------------------
- New feature: Joystick/Keyboard auto-configuration
- New feature: deadzone and peak analog joystick values are now configurable
- Converted to new Mupen64Plus 2.0 API
- Refactored build system to separate source and object files
- Major code cleanup: mouse movement and analog axis code was terrible, removed non-standard data types
- Improved debug messages
- bugfix: mapping the X/Y analog sticks to keypresses didnt work
- bugfix: LeftCtrl-LeftAlt key command when mouse is enabled to now toggles between grabbing and releasing the mouse pointer
Mupen64Plus Pre-2.0
-------------------
- numerous fixes and enhancements were made to this code during the mupen64plus project before v2.0
Original Blight Changelog
-------------------------
0.0.10:
- when the keyboard is used to control an axis left shift and left control can be
pressed to change the axis movement. shift reduces the movement by 25%, control
reduces it by 50%, control and shift together reduce the movement by 75%
- when the mouse is used left ctrl + left alt can be used to release the mouse,
clicking into the window will grab the mouse again.
0.0.9:
- import new version of SDL_tff (2.0.7)
- when the keyboard is used to control an axis left shift can be pressed to change
the axis movement to 25% of the original value
0.0.8-b:
- fixed bug which didn't put analog axis back into default position when a key
which was assigned to it was pressed and released again
0.0.8:
- fixed a stupid bug which disabled analog axis
0.0.7-b:
- sdl config dialog: input event queue is flushed before a
button/whatever is assigned
0.0.7: mouse support!
- mouse support (x and y axis automatically mapped to analog stick,
mouse buttons mapable onto n64 buttons)
0.0.6:
- keyboard and gamepad can be used at the same time (the keyboard will work always,
even if you choose another device. if you want to use only the keyboard select
keyboard as device
0.0.5:
- sdl about dialog
- fixed config routine (incorrectly read X- axis)
- fixed small sdl config dialog drawing bug
- corrected config dialog c button labels
0.0.4: joystick hat support
- fixed a segfault when the rom was closed
- less axis sensibility when assigning a new mapping (changed from 10 to 50 percent)
- less sensibility for axis mapped to buttons (changed from 10 to 20 percent)
- it's possible to clear assignments and cancel an assignment
- joystick hat support (mapable to axis and buttons)
- fixed some bugs in the input reading function
- fixed all compiler warnings
0.0.3:
- no more need for the SDL_image library
- no longer link against gtk library
0.0.2-2:
- fixed a bug which didn't allow to assign anything to a pad button
0.0.2-1: *BROKEN*
- help for the SDL gui
0.0.2: new SDL config dialog! *BROKEN*
- fixed a bug where it wouldn't open the joystick device if you change the controller
- sdl config dialog
- some other lil' fixes
0.0.1: made some small fixes
- now it's possible to map an axis (i.e. X Axis +) to a button (i.e. DPAD_UP)
- configuration is saved and displayed for all devices
- changed the config dialog a bit (bigger text entries, bigger device combo)
- new config file format
0.0.1b: initial version
- should work :-)

View File

@ -1,969 +0,0 @@
; InputAutoCfg.ini for Mupen64Plus SDL Input plugin
[Keyboard]
plugged = True
plugin = 2
mouse = False
DPad R = key(100)
DPad L = key(97)
DPad D = key(115)
DPad U = key(119)
Start = key(13)
Z Trig = key(122)
B Button = key(306)
A Button = key(304)
C Button R = key(108)
C Button L = key(106)
C Button D = key(107)
C Button U = key(105)
R Trig = key(99)
L Trig = key(120)
Mempak switch = key(44)
Rumblepak switch = key(46)
X Axis = key(276,275)
Y Axis = key(273,274)
; Boom Smart Joy Converter
[HID 6666:0667]
plugged = True
plugin = 2
mouse = False
AnalogDeadzone = 4096,4096
AnalogPeak = 32768,32768
DPad R = button(13)
DPad L = button(15)
DPad D = button(14)
DPad U = button(12)
Start = button(11)
Z Trig = button(10)
B Button = button(4)
A Button = button(5)
C Button R = button(1)
C Button L = button(3)
C Button D = button(2)
C Button U = button(0)
R Trig = button(7)
L Trig = button(6)
Mempak switch = key(109)
Rumblepak switch = key(114)
X Axis = axis(0-,0+)
Y Axis = axis(1-,1+)
[Cyborg V.3 Rumble Pad]
plugged = True
plugin = 2
mouse = False
AnalogDeadzone = 4096,4096
AnalogPeak = 32768,32768
DPad R = axis(4+)
DPad L = axis(4-)
DPad D = axis(5+)
DPad U = axis(5-)
Start = button(12)
Z Trig = button(7)
B Button = button(0)
A Button = button(1)
C Button R = button(8) axis(2+)
C Button L = button(3) axis(2-)
C Button D = button(2) axis(3+)
C Button U = button(9) axis(3-)
R Trig = button(5)
L Trig = button(4)
Mempak switch =
Rumblepak switch =
X Axis = axis(0-,0+)
Y Axis = axis(1-,1+)
[DragonRise Inc. Generic USB Joystick]
plugged = True
plugin = 2
mouse = False
AnalogDeadzone = 4096,4096
AnalogPeak = 32768,32768
DPad R = key(275) axis(0+)
DPad L = key(276) axis(0-)
DPad D = key(274) axis(1+)
DPad U = key(273) axis(1-)
Start = button(9)
Z Trig = button(4)
B Button = button(3)
A Button = button(2)
C Button R = button(7) axis(3+)
C Button L = button(6) axis(3-)
C Button D = button(1) axis(4+)
C Button U = button(0) axis(4-)
R Trig = button(5)
L Trig = button(4)
Mempak switch =
Rumblepak switch =
X Axis = axis(0-,0+)
Y Axis = axis(1-,1+)
; FuSa is a homebrew program which allows a PSP to be used as a gamepad
[FuSa FuSa GamePad]
plugged = True
plugin = 2
mouse = False
AnalogDeadzone = 4096,4096
AnalogPeak = 32768,32768
DPad R =
DPad L =
DPad D =
DPad U =
Start = button(7)
Z Trig = button(4)
B Button = button(2)
A Button = button(0)
C Button R = hat(0 Right)
C Button L = hat(0 Left)
C Button D = hat(0 Down)
C Button U = hat(0 Up)
R Trig = button(5)
L Trig = button(3)
Mempak switch =
Rumblepak switch =
X Axis = axis(0-,0+)
Y Axis = axis(1-,1+)
[Gasia Co.,Ltd PS(R) Gamepad]
plugged = True
plugin = 2
mouse = False
AnalogDeadzone = 4096,4096
AnalogPeak = 32768,32768
DPad R = key(275) axis(0+) hat(0 Right)
DPad L = key(276) axis(0-)
DPad D = key(274) axis(1+) hat(0 Down)
DPad U = key(273) axis(1-)
Start = button(9)
Z Trig = button(6)
B Button = button(3)
A Button = button(2)
C Button R = axis(2+)
C Button L = axis(2-)
C Button D = axis(3+)
C Button U = axis(3-)
R Trig = button(5)
L Trig = button(4)
Mempak switch = button(1)
Rumblepak switch = button(0)
X Axis = axis(0-,0+)
Y Axis = axis(1-,1+)
; raphnet technologies USB converter (http://www.raphnet-tech.com/)
[GC/N64_USB]
plugged = True
plugin = 2
mouse = False
AnalogDeadzone = 4096,4096
AnalogPeak = 32768,32768
DPad R = button(13)
DPad L = button(12)
DPad D = button(11)
DPad U = button(10)
Start = button(3)
Z Trig = button(2)
B Button = button(1)
A Button = button(0)
C Button R = button(7)
C Button L = button(6)
C Button D = button(5)
C Button U = button(4)
R Trig = button(9)
L Trig = button(8)
Mempak switch =
Rumblepak switch =
X Axis = axis(0-,0+)
Y Axis = axis(1-,1+)
[GreenAsia Inc. USB Joystick]
plugged = True
plugin = 2
mouse = False
AnalogDeadzone = 4096,4096
AnalogPeak = 32768,32768
DPad R = hat(0 Right)
DPad L = hat(0 Left)
DPad D = hat(0 Down)
DPad U = hat(0 Up)
Start = button(9)
Z Trig = button(1)
B Button = button(3)
A Button = button(2)
C Button R = axis(3+)
C Button L = axis(3-)
C Button D = axis(2+)
C Button U = axis(2-)
R Trig = button(7)
L Trig = button(6)
Mempak switch =
Rumblepak switch =
X Axis = axis(0-,0+)
Y Axis = axis(1-,1+)
[Jess Tech Dual Analog Pad]
plugged = True
plugin = 2
mouse = False
AnalogDeadzone = 4096,4096
AnalogPeak = 32768,32768
DPad R = hat(0 Right)
DPad L = hat(0 Left)
DPad D = hat(0 Down)
DPad U = hat(0 Up)
Start = button(9)
Z Trig = button(7)
B Button = button(0)
A Button = button(2)
C Button R = axis(3+)
C Button L = axis(3-)
C Button D = axis(2+)
C Button U = axis(2-)
R Trig = button(6)
L Trig = button(4)
Mempak switch =
Rumblepak switch =
X Axis = axis(0-,0+)
Y Axis = axis(1-,1+)
[Jess Tech Colour Rumble Pad]
plugged = True
plugin = 1
mouse = False
AnalogDeadzone = 4096,4096
AnalogPeak = 32768,32768
DPad R = hat(0 Right)
DPad L = hat(0 Left)
DPad D = hat(0 Down)
DPad U = hat(0 Up)
Start = button(9)
Z Trig = button(4)
B Button = button(0)
A Button = button(2)
C Button R = axis(3+)
C Button L = axis(3-)
C Button D = axis(2+)
C Button U = axis(2-)
R Trig = button(7)
L Trig = button(5)
Mempak switch =
Rumblepak switch =
X Axis = axis(0-,0+)
Y Axis = axis(1-,1+)
[Jess Tech USB 4-Axis 12-Button Gamepad]
plugged = True
plugin = 2
mouse = False
AnalogDeadzone = 4096,4096
AnalogPeak = 32768,32768
DPad R = hat(0 Right)
DPad L = hat(0 Left)
DPad D = hat(0 Down)
DPad U = hat(0 Up)
Start = button(4)
Z Trig = button(5)
B Button = button(8)
A Button = button(9)
C Button R = button(1)
C Button L = button(3)
C Button D = button(2)
C Button U = button(0)
R Trig = button(7)
L Trig = button(6)
Mempak switch =
Rumblepak switch =
X Axis = axis(0-,0+)
Y Axis = axis(1-,1+)
; X-box controllers and compatible clones
[Logitech Chillstream Controller]
plugged = True
plugin = 2
mouse = False
AnalogDeadzone = 4096,4096
AnalogPeak = 32768,32768
DPad R = hat(0 Right)
DPad L = hat(0 Left)
DPad D = hat(0 Down)
DPad U = hat(0 Up)
Start = button(7)
Z Trig = axis(2+)
B Button = button(2)
A Button = button(0)
C Button R = axis(3+)
C Button L = axis(3-)
C Button D = axis(4+)
C Button U = axis(4-)
R Trig = button(5)
L Trig = button(4)
Mempak switch = button(6)
Rumblepak switch = button(8)
X Axis = axis(0-,0+)
Y Axis = axis(1-,1+)
[Logitech Cordless Rumblepad 2]
[Logitech Cordless RumblePad 2]
[Logitech RumblePad 2 USB]
[Logitech Dual Action]
plugged = True
plugin = 2
mouse = False
AnalogDeadzone = 4096,4096
AnalogPeak = 32768,32768
DPad R = axis(4+) hat(0 Right)
DPad L = axis(4-) hat(0 Left)
DPad D = axis(5+) hat(0 Down)
DPad U = axis(5-) hat(0 Up)
Start = button(9)
Z Trig = button(6)
B Button = button(0)
A Button = button(1)
C Button R = axis(2+)
C Button L = axis(2-)
C Button D = axis(3+)
C Button U = axis(3-)
R Trig = button(5)
L Trig = button(4)
Mempak switch = button(8)
Rumblepak switch = button(7)
X Axis = axis(0-,0+)
Y Axis = axis(1-,1+)
[Logitech Logitech(R) Precision(TM) Gamepad]
[Gravis GamePad Pro USB]
plugged = True
plugin = 2
mouse = False
AnalogDeadzone = 100,100
AnalogPeak = 32768,32768
DPad R = axis(0+)
DPad L = axis(0-)
DPad D = axis(1+)
Dpad U = axis(1-)
Start = button(9)
Z Trig = button(6)
B Button = button(5)
A Button = button(4)
C Button R = button(2)
C Button L = button(0)
C Button D = button(1)
C Button U = button(3)
R Trig = button(7)
L Trig = button(8)
Mempack switch =
Rumblepak Switch =
X Axis = axis(0-,0+)
Y Axis = axis(1-,1+)
[Logitech WingMan Action Pad]
plugged = True
plugin = 2
mouse = False
AnalogDeadzone = 4096,4096
AnalogPeak = 32768,32768
DPad R = button(13)
DPad L = button(15)
DPad D = button(14)
DPad U = button(12)
Start = button(8)
Z Trig = button(6)
B Button = button(3)
A Button = button(0)
C Button R = button(2)
C Button L = button(4)
C Button D = button(1)
C Button U = button(5)
R Trig = button(7)
L Trig =
Mempak switch =
Rumblepak switch =
X Axis = axis(0-,0+)
Y Axis = axis(1-,1+)
[Mega World USB Game Controllers]
plugged = True
plugin = 2
mouse = False
AnalogDeadzone = 4096,4096
AnalogPeak = 32768,32768
DPad R = hat(0 Right)
DPad L = hat(0 Left)
DPad D = hat(0 Down)
DPad U = hat(0 Up)
Start = button(9)
Z Trig = button(7)
B Button = button(0)
A Button = button(2)
C Button R = axis(3+)
C Button L = axis(3-)
C Button D = axis(2+)
C Button U = axis(2-)
R Trig = button(6)
L Trig = button(4)
Mempak switch =
Rumblepak switch =
X Axis = axis(0-,0+)
Y Axis = axis(1-,1+)
[MP-8866 Dual USB Joypad]
plugged = True
plugin = 2
mouse = False
AnalogDeadzone = 4096,4096
AnalogPeak = 32768,32768
DPad R = hat(0 Right)
DPad L = hat(0 Left)
DPad D = hat(0 Down)
DPad U = hat(0 Up)
Start = button(8)
Z Trig = button(6)
B Button = button(3)
A Button = button(2)
C Button R = axis(2+)
C Button L = axis(2-)
C Button D = axis(3+)
C Button U = axis(3-)
R Trig = button(7)
L Trig = button(4)
Mempak switch = button(10)
Rumblepak switch = button(11)
Y Axis = axis(1-,1+)
X Axis = axis(0-,0+)
[Microsoft X-Box 360 pad]
[Win32: Controller (XBOX 360 For Windows)]
[Win32: XBOX 360 For Windows (Controller)]
[Win32: XBOX 360 For Windows]
[Xbox 360 Wireless Receiver]
[OSX: Wireless 360 Controller]
[OSX: Controller]
[Linux: Xbox Gamepad (userspace driver)]
plugged = True
plugin = 2
mouse = False
AnalogDeadzone = 4096,4096
AnalogPeak = 32768,32768
DPad R = hat(0 Right)
DPad L = hat(0 Left)
DPad D = hat(0 Down)
DPad U = hat(0 Up)
Start = button(7)
Z Trig = axis(2+)
B Button = button(2)
A Button = button(0)
C Button R = axis(4+)
C Button L = axis(4-) button(3)
C Button D = axis(3+) button(1)
C Button U = axis(3-)
R Trig = button(5) axis(2-)
L Trig = button(4)
Mempak switch =
Rumblepak switch =
X Axis = axis(0-,0+)
Y Axis = axis(1-,1+)
[N64 controller]
plugged = True
plugin = 2
mouse = False
AnalogDeadzone = 4096,4096
AnalogPeak = 32768,32768
DPad R = hat(0 Right)
DPad L = hat(0 Left)
DPad D = hat(0 Down)
DPad U = hat(0 Up)
Start = button(9)
Z Trig = button(0)
B Button = button(2)
A Button = button(1)
C Button R = button(4)
C Button L = button(5)
C Button D = button(3)
C Button U = button(6)
R Trig = button(8)
L Trig = button(7)
Mempak switch = key(109)
Rumblepak switch = key(114)
X Axis = axis(0-,0+)
Y Axis = axis(1-,1+)
[PC Game Controller]
plugged = True
plugin = 2
mouse = False
AnalogDeadzone = 4096,4096
AnalogPeak = 32768,32768
DPad R = hat(0 Right)
DPad L = hat(0 Left)
DPad D = hat(0 Down)
DPad U = hat(0 Up)
Start = button(9)
Z Trig = button(8)
B Button = button(4)
A Button = button(5)
C Button R = button(1)
C Button L = button(3)
C Button D = button(2)
C Button U = button(0)
R Trig = button(7)
L Trig = button(6)
Mempak switch = key(109)
Rumblepak switch = key(114)
X Axis = axis(0-,0+)
Y Axis = axis(1-,1+)
[SAITEK P880]
plugged = True
plugin = 2
mouse = False
AnalogDeadzone = 4096,4096
AnalogPeak = 32768,32768
DPad R = hat(0 Right)
DPad L = hat(0 Left)
DPad D = hat(0 Down)
DPad U = hat(0 Up)
Start = button(10)
Z Trig = button(3)
B Button = button(0)
A Button = button(2)
C Button R = button(5) axis(3+)
C Button L = button(1) axis(3-)
C Button D = button(9) axis(2+)
C Button U = button(4) axis(2-)
R Trig = button(7)
L Trig = button(6)
Mempak switch =
Rumblepak switch =
X Axis = axis(0-,0+)
Y Axis = axis(1-,1+)
[Saitek P990 Dual Analog Pad]
plugged = True
plugin = 2
mouse = False
AnalogDeadzone = 4096,4096
AnalogPeak = 32768,32768
DPad R = hat(0 Right)
DPad L = hat(0 Left)
DPad D = hat(0 Down)
DPad U = hat(0 Up)
Start = button(5)
Z Trig = button(4)
B Button = button(0)
A Button = button(1)
C Button R = button(8) axis(3+)
C Button L = button(3) axis(3-)
C Button D = button(2) axis(2+)
C Button U = button(9) axis(2-)
R Trig = button(7)
L Trig = button(6)
Mempak switch = button(11)
Rumblepak switch = axis(10+)
X Axis = axis(0-,0+)
Y Axis = axis(1-,1+)
[Saitek P2900 Wireless Pad]
plugged = True
plugin = 2
mouse = False
AnalogDeadzone = 4096,4096
AnalogPeak = 32768,32768
DPad R = axis(4+)
DPad L = axis(4-)
DPad D = axis(5+)
DPad U = axis(5-)
Start = button(6)
Z Trig = button(7)
B Button = button(0)
A Button = button(1)
C Button R = button(8) axis(3+)
C Button L = button(3) axis(3-)
C Button D = button(2) axis(2+)
C Button U = button(9) axis(2-)
R Trig = button(5)
L Trig = button(4)
Mempak switch = button(11)
Rumblepak switch = axis(10+)
X Axis = axis(0-,0+)
Y Axis = axis(1-,1+)
[Thrustmaster Dual Trigger 3-in-1]
plugged = True
plugin = 2
mouse = False
AnalogDeadzone = 4096,4096
AnalogPeak = 32768,32768
DPad R = hat(0 Right)
DPad L = hat(0 Left)
DPad D = hat(0 Down)
DPad U = hat(0 Up)
Start = button(9)
Z Trig = button(3)
B Button = button(0)
A Button = button(1)
C Button R = axis(2+)
C Button L = axis(2-)
C Button D = axis(5+)
C Button U = axis(5-)
R Trig = button(5)
L Trig = button(4)
Mempak switch = button(6)
Rumblepak switch = button(7)
X Axis = axis(0-,0+)
Y Axis = axis(1-,1+)
[THRUSTMASTER Firestorm Dual Power 2]
plugged = True
plugin = 2
mouse = False
AnalogDeadzone = 4096,4096
AnalogPeak = 32768,32768
DPad R = hat(0 Right)
DPad L = hat(0 Left)
DPad D = hat(0 Down)
DPad U = hat(0 Up)
Start = button(5)
Z Trig = button(8)
B Button = button(1)
A Button = button(0)
C Button R = axis(2+)
C Button L = axis(2-)
C Button D = axis(3+)
C Button U = axis(3-)
R Trig = button(6)
L Trig = button(4)
Mempak switch =
Rumblepak switch =
X Axis = axis(0-,0+)
Y Axis = axis(1-,1+)
[Twin USB Joystick]
plugged = True
plugin = 2
mouse = False
AnalogDeadzone = 4096,4096
AnalogPeak = 32768,32768
DPad R = hat(0 Right)
DPad L = hat(0 Left)
DPad D = hat(0 Down)
DPad U = hat(0 Up)
Start = button(9)
Z Trig = button(4)
B Button = button(6)
A Button = button(7)
C Button R = button(1)
C Button L = button(3)
C Button D = button(2)
C Button U = button(0)
R Trig = button(5)
L Trig = button(11)
Mempak switch =
Rumblepak switch =
Y Axis = axis(1-,1+)
X Axis = axis(0-,0+)
[PLAYSTATION(R)3 Controller]
plugged = True
plugin = 2
mouse = False
AnalogDeadzone = 4096,4096
AnalogPeak = 32768,32768
DPad R = button(5)
DPad L = button(7)
DPad D = button(6)
DPad U = button(4)
Start = button(3)
Z Trig = button(8)
B Button = button(15)
A Button = button(14)
C Button R = axis(2+)
C Button L = axis(2-)
C Button D = axis(3+)
C Button U = axis(3-)
R Trig = button(11)
L Trig = button(10)
Mempak switch =
Rumblepak switch =
X Axis = axis(0-,0+)
Y Axis = axis(1-,1+)
[WiseGroup.,Ltd TigerGame XBOX+PS2+GC Game Controller Adapter]
plugged = True
plugin = 2
mouse = False
AnalogDeadzone = 4096,4096
AnalogPeak = 32768,32768
DPad R = button(9)
DPad L = button(8)
DPad D = button(10)
DPad U = button(11)
Start = button(7)
Z Trig = button(6)
B Button = button(1)
A Button = button(0)
C Button R = axis(2+)
C Button L = axis(2-)
C Button D = axis(3+)
C Button U = axis(3-)
R Trig = axis(4+)
L Trig = axis(5+)
Mempak switch =
Rumblepak switch =
X Axis = axis(0-,0+)
Y Axis = axis(1-,1+)
[Wish Technologies Adaptoid]
plugged = True
plugin = 2
mouse = False
AnalogDeadzone = 4096,4096
AnalogPeak = 32768,32768
DPad R = button(13)
DPad L = button(12)
DPad D = button(11)
DPad U = button(10)
Start = button(8)
Z Trig = button(9)
B Button = button(3)
A Button = button(0)
C Button R = button(2)
C Button L = button(4)
C Button D = button(1)
C Button U = button(5)
R Trig = button(7)
L Trig = button(6)
Mempak switch =
Rumblepak switch =
X Axis = axis(0-,0+)
Y Axis = axis(1-,1+)
; X-box controllers and compatible clones
[Microsoft X-Box pad v1 (US)]
[Microsoft X-Box pad v2 (US)]
[Microsoft X-Box pad (Japan)]
[Microsoft Xbox Controller S]
[Thrustmaster, Inc. Controller]
[Logitech Xbox Cordless Controller]
[Logitech Compact Controller for Xbox]
[Mad Catz Controller (unverified)]
[InterAct 'PowerPad Pro' X-Box pad (Germany)]
[Mad Catz Control Pad]
[Mad Catz LumiCON]
[Mad Catz Control Pad Pro]
[Mad Catz MicroCON]
[Mad Catz Lynx Wireless Controller]
[Zeroplus Xbox Controller]
[Pelican Eclipse PL-2023]
[Zeroplus Xbox Controller]
[Radica Gamester Controller]
[Radica Games Jtech Controller]
[Logic3 Freebird wireless Controller]
[Eclipse wireless Controller]
[Edge wireless Controller]
[SmartJoy Frag Xpad/PS2 adaptor]
[Joytech Advanced Controller]
[BigBen XBMiniPad Controller]
[Joytech Wireless Advanced Controller]
[Chinese-made Xbox Controller]
[Generic X-Box pad]
plugged = True
plugin = 2
mouse = False
AnalogDeadzone = 4096,4096
AnalogPeak = 32768,32768
DPad R = hat(0 Right)
DPad L = hat(0 Left)
DPad D = hat(0 Down)
DPad U = hat(0 Up)
Start = button(6)
Z Trig = button(7)
B Button = button(1)
A Button = button(0)
C Button R = axis(3+)
C Button L = axis(3-)
C Button D = axis(4+)
C Button U = axis(4-)
R Trig = axis(5+)
L Trig = axis(2+)
Mempak switch = button(5)
Rumblepak switch = button(2)
X Axis = axis(0-,0+)
Y Axis = axis(1-,1+)
[OSX: USB GamePad]
; this is a 2-port USB device. The Right port is controller #1, the Left port is #2
; this is the "MayFlash" adapter, aka HuiJia. The OSX driver seems to have a
; different button mapping
plugged = True
plugin = 2
mouse = False
AnalogDeadzone = 2500,2500
AnalogPeak = 20000,20000
DPad R = button(13)
DPad L = button(15)
DPad D = button(14)
DPad U = button(12)
Start = button(9)
Z Trig = button(8)
B Button = button(2)
A Button = button(1)
C Button R = axis(1-)
C Button L = axis(1+)
C Button D = axis(0+)
C Button U = axis(0-)
R Trig = button(7)
L Trig = button(6)
Mempak switch = key(109)
Rumblepak switch = key(114)
X Axis = axis(2-,2+)
Y Axis = axis(3-,3+)
__NextController:
plugged = True
plugin = 2
mouse = False
AnalogDeadzone = 2500,2500
AnalogPeak = 20000,20000
DPad R = button(29)
DPad L = button(31)
DPad D = button(30)
DPad U = button(28)
Start = button(25)
Z Trig = button(24)
B Button = button(18)
A Button = button(17)
C Button R = axis(5-)
C Button L = axis(5+)
C Button D = axis(4+)
C Button U = axis(4-)
R Trig = button(23)
L Trig = button(22)
Mempak switch = key(109)
Rumblepak switch = key(114)
X Axis = axis(6-,6+)
Y Axis = axis(7-,7+)
[Linux: HuiJia USB GamePad]
plugged = True
plugin = 2
mouse = False
AnalogDeadzone = 100,100
AnalogPeak = 20000,20000
DPad R = button(13)
DPad L = button(15)
DPad D = button(14)
DPad U = button(12)
Start = button(9)
Z Trig = button(8)
B Button = button(2)
A Button = button(1)
C Button R = axis(3-)
C Button L = axis(3+)
C Button D = axis(2+)
C Button U = axis(2-)
R Trig = button(7)
L Trig = button(6)
Mempak switch = key(109)
Rumblepak switch = key(114)
X Axis = axis(0-,0+)
Y Axis = axis(1-,1+)
__NextController:
plugged = True
plugin = 2
mouse = False
AnalogDeadzone = 100,100
AnalogPeak = 20000,20000
DPad R = button(29)
DPad L = button(31)
DPad D = button(30)
DPad U = button(28)
Start = button(25)
Z Trig = button(24)
B Button = button(18)
A Button = button(17)
C Button R = axis(7-)
C Button L = axis(7+)
C Button D = axis(6+)
C Button U = axis(6-)
R Trig = button(23)
L Trig = button(22)
Mempak switch = key(109)
Rumblepak switch = key(114)
X Axis = axis(4-,4+)
Y Axis = axis(5-,5+)
; Mayflah N64 Controller Adapter (for PC USB) - With two N64 gamepads connected
; this is a 2-port USB device. The Right port is controller #1, the Left port is #2
[Win32: USB GamePad]
plugged = True
plugin = 2
mouse = False
AnalogDeadzone = 4096,4096
AnalogPeak = 32768,32768
DPad R = hat(0 Right)
DPad L = hat(0 Left)
DPad D = hat(0 Down)
DPad U = hat(0 Up)
Start = button(9)
Z Trig = button(8)
B Button = button(2)
A Button = button(1)
C Button R = axis(3-)
C Button L = axis(3+)
C Button D = axis(2+)
C Button U = axis(2-)
R Trig = button(7)
L Trig = button(6)
Mempak switch = key(109)
Rumblepak switch = key(114)
Y Axis = axis(1-,1+)
X Axis = axis(0-,0+)
; Asikgame - Super Dual Box (with two PS2 gamepads connected)
; this is a 2-port USB device. The Right port is controller #1, the Left port is #2
[USB Human(2p) Interface Device]
plugged = True
plugin = 2
mouse = False
DPad R= axis(2+)
DPad L= axis(2-)
DPad D= axis(5+)
DPad U= axis(5-)
Start= button(0)
Z Trig= button(1)
B Button= button(3)
A Button= button(2)
C Button R= hat(0 Right)
C Button L= hat(0 Left)
C Button D= hat(0 Down)
C Button U= hat(0 Up)
R Trig= button(5)
L Trig= button(4)
Mempak switch= button(9)
Rumblepak switch= button(8)
Y Axis= axis(1-,1+)
X Axis= axis(0-,0+)
__NextController:
plugged = True
plugin = 2
mouse = False
DPad R= axis(6+)
DPad L= axis(6-)
DPad D= axis(7+)
DPad U= axis(7-)
Start= button(12)
Z Trig= button(13)
B Button= button(15)
A Button= button(14)
C Button R= hat(1 Right)
C Button L= hat(1 Left)
C Button D= hat(1 Down)
C Button U= hat(1 Up)
R Trig= button(17)
L Trig= button(16)
Mempak switch= button(21)
Rumblepak switch= button(20)
Y Axis= axis(4-,4+)
X Axis= axis(3-,3+)

View File

@ -1,118 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|Win32">
<Configuration>Debug</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|Win32">
<Configuration>Release</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
</ItemGroup>
<PropertyGroup Label="Globals">
<ProjectGuid>{7F3178D0-0E2E-471B-9160-69F0354F9DE9}</ProjectGuid>
<RootNamespace>mupen64plusinputsdl</RootNamespace>
<Keyword>Win32Proj</Keyword>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<CharacterSet>MultiByte</CharacterSet>
<WholeProgramOptimization>true</WholeProgramOptimization>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<CharacterSet>MultiByte</CharacterSet>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<PropertyGroup>
<_ProjectFileVersion>10.0.40219.1</_ProjectFileVersion>
<OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(SolutionDir)$(Configuration)\</OutDir>
<IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(Configuration)\</IntDir>
<LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</LinkIncremental>
<OutDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(SolutionDir)$(Configuration)\</OutDir>
<IntDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(Configuration)\</IntDir>
<LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">false</LinkIncremental>
<CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">AllRules.ruleset</CodeAnalysisRuleSet>
<CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" />
<CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" />
<CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">AllRules.ruleset</CodeAnalysisRuleSet>
<CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" />
<CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" />
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<ClCompile>
<Optimization>Disabled</Optimization>
<AdditionalIncludeDirectories>..\..\..\mupen64plus-core\src\api;..\..\..\mupen64plus-win32-deps\SDL-1.2.14\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;_USRDLL;_CRT_SECURE_NO_DEPRECATE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<MinimalRebuild>false</MinimalRebuild>
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
<RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
<PrecompiledHeader>
</PrecompiledHeader>
<WarningLevel>Level3</WarningLevel>
<DebugInformationFormat>EditAndContinue</DebugInformationFormat>
<MultiProcessorCompilation>true</MultiProcessorCompilation>
</ClCompile>
<Link>
<AdditionalDependencies>..\..\..\mupen64plus-win32-deps\SDL-1.2.14\lib\SDL.lib;%(AdditionalDependencies)</AdditionalDependencies>
<GenerateDebugInformation>true</GenerateDebugInformation>
<SubSystem>Windows</SubSystem>
<TargetMachine>MachineX86</TargetMachine>
</Link>
<PostBuildEvent>
<Command>xcopy /y "$(OutDir)$(TargetName)$(TargetExt)" "$(TargetDir)..\..\..\..\..\BizHawk.MultiClient\output\dll\"</Command>
</PostBuildEvent>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<ClCompile>
<AdditionalIncludeDirectories>..\..\..\mupen64plus-core\src\api;..\..\..\mupen64plus-win32-deps\SDL-1.2.14\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_USRDLL;_CRT_SECURE_NO_DEPRECATE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
<PrecompiledHeader>
</PrecompiledHeader>
<WarningLevel>Level3</WarningLevel>
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
<CompileAs>Default</CompileAs>
<MultiProcessorCompilation>true</MultiProcessorCompilation>
</ClCompile>
<Link>
<AdditionalDependencies>..\..\..\mupen64plus-win32-deps\SDL-1.2.14\lib\SDL.lib;%(AdditionalDependencies)</AdditionalDependencies>
<GenerateDebugInformation>true</GenerateDebugInformation>
<SubSystem>Windows</SubSystem>
<OptimizeReferences>true</OptimizeReferences>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<TargetMachine>MachineX86</TargetMachine>
</Link>
<PostBuildEvent>
<Command>xcopy /y $(OutDir)$(TargetName)$(TargetExt) $(TargetDir)..\..\..\..\..\BizHawk.MultiClient\output\dll\</Command>
</PostBuildEvent>
</ItemDefinitionGroup>
<ItemGroup>
<ClCompile Include="..\..\src\autoconfig.c" />
<ClCompile Include="..\..\src\config.c" />
<ClCompile Include="..\..\src\osal_dynamiclib_win32.c" />
<ClCompile Include="..\..\src\plugin.c" />
</ItemGroup>
<ItemGroup>
<ClInclude Include="..\..\src\autoconfig.h" />
<ClInclude Include="..\..\src\config.h" />
<ClInclude Include="..\..\src\osal_dynamiclib.h" />
<ClInclude Include="..\..\src\osal_preproc.h" />
<ClInclude Include="..\..\src\plugin.h" />
<ClInclude Include="..\..\src\version.h" />
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
</Project>

View File

@ -1,232 +0,0 @@
<?xml version="1.0" encoding="Windows-1252"?>
<VisualStudioProject
ProjectType="Visual C++"
Version="8.00"
Name="mupen64plus-input-sdl"
ProjectGUID="{7F3178D0-0E2E-471B-9160-69F0354F9DE9}"
RootNamespace="mupen64plusinputsdl"
Keyword="Win32Proj"
>
<Platforms>
<Platform
Name="Win32"
/>
</Platforms>
<ToolFiles>
</ToolFiles>
<Configurations>
<Configuration
Name="Debug|Win32"
OutputDirectory="$(SolutionDir)$(ConfigurationName)"
IntermediateDirectory="$(ConfigurationName)"
ConfigurationType="2"
CharacterSet="2"
>
<Tool
Name="VCPreBuildEventTool"
/>
<Tool
Name="VCCustomBuildTool"
/>
<Tool
Name="VCXMLDataGeneratorTool"
/>
<Tool
Name="VCWebServiceProxyGeneratorTool"
/>
<Tool
Name="VCMIDLTool"
/>
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories="..\..\..\mupen64plus-core\src\api;..\..\..\mupen64plus-win32-deps\SDL-1.2.14\include"
PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;_USRDLL;_CRT_SECURE_NO_DEPRECATE"
MinimalRebuild="true"
BasicRuntimeChecks="3"
RuntimeLibrary="3"
UsePrecompiledHeader="0"
WarningLevel="3"
Detect64BitPortabilityProblems="false"
DebugInformationFormat="4"
/>
<Tool
Name="VCManagedResourceCompilerTool"
/>
<Tool
Name="VCResourceCompilerTool"
/>
<Tool
Name="VCPreLinkEventTool"
/>
<Tool
Name="VCLinkerTool"
AdditionalDependencies="..\..\..\mupen64plus-win32-deps\SDL-1.2.14\lib\SDL.lib"
LinkIncremental="2"
GenerateDebugInformation="true"
SubSystem="2"
TargetMachine="1"
/>
<Tool
Name="VCALinkTool"
/>
<Tool
Name="VCManifestTool"
/>
<Tool
Name="VCXDCMakeTool"
/>
<Tool
Name="VCBscMakeTool"
/>
<Tool
Name="VCFxCopTool"
/>
<Tool
Name="VCAppVerifierTool"
/>
<Tool
Name="VCWebDeploymentTool"
/>
<Tool
Name="VCPostBuildEventTool"
/>
</Configuration>
<Configuration
Name="Release|Win32"
OutputDirectory="$(SolutionDir)$(ConfigurationName)"
IntermediateDirectory="$(ConfigurationName)"
ConfigurationType="2"
CharacterSet="2"
WholeProgramOptimization="1"
>
<Tool
Name="VCPreBuildEventTool"
/>
<Tool
Name="VCCustomBuildTool"
/>
<Tool
Name="VCXMLDataGeneratorTool"
/>
<Tool
Name="VCWebServiceProxyGeneratorTool"
/>
<Tool
Name="VCMIDLTool"
/>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories="..\..\..\mupen64plus-core\src\api;..\..\..\mupen64plus-win32-deps\SDL-1.2.14\include"
PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;_USRDLL;_CRT_SECURE_NO_DEPRECATE"
RuntimeLibrary="2"
UsePrecompiledHeader="0"
WarningLevel="3"
Detect64BitPortabilityProblems="false"
DebugInformationFormat="3"
CompileAs="0"
/>
<Tool
Name="VCManagedResourceCompilerTool"
/>
<Tool
Name="VCResourceCompilerTool"
/>
<Tool
Name="VCPreLinkEventTool"
/>
<Tool
Name="VCLinkerTool"
AdditionalDependencies="..\..\..\mupen64plus-win32-deps\SDL-1.2.14\lib\SDL.lib"
LinkIncremental="1"
GenerateDebugInformation="true"
SubSystem="2"
OptimizeReferences="2"
EnableCOMDATFolding="2"
TargetMachine="1"
/>
<Tool
Name="VCALinkTool"
/>
<Tool
Name="VCManifestTool"
/>
<Tool
Name="VCXDCMakeTool"
/>
<Tool
Name="VCBscMakeTool"
/>
<Tool
Name="VCFxCopTool"
/>
<Tool
Name="VCAppVerifierTool"
/>
<Tool
Name="VCWebDeploymentTool"
/>
<Tool
Name="VCPostBuildEventTool"
/>
</Configuration>
</Configurations>
<References>
</References>
<Files>
<Filter
Name="Source Files"
Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx"
UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"
>
<File
RelativePath="..\..\src\autoconfig.c"
>
</File>
<File
RelativePath="..\..\src\config.c"
>
</File>
<File
RelativePath="..\..\src\osal_dynamiclib_win32.c"
>
</File>
<File
RelativePath="..\..\src\plugin.c"
>
</File>
</Filter>
<Filter
Name="Header Files"
Filter="h;hpp;hxx;hm;inl;inc;xsd"
UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"
>
<File
RelativePath="..\..\src\autoconfig.h"
>
</File>
<File
RelativePath="..\..\src\config.h"
>
</File>
<File
RelativePath="..\..\src\osal_dynamiclib.h"
>
</File>
<File
RelativePath="..\..\src\osal_preproc.h"
>
</File>
<File
RelativePath="..\..\src\plugin.h"
>
</File>
<File
RelativePath="..\..\src\version.h"
>
</File>
</Filter>
</Files>
<Globals>
</Globals>
</VisualStudioProject>

View File

@ -1,336 +0,0 @@
#/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
# * Mupen64plus-input-sdl - Makefile *
# * Mupen64Plus homepage: http://code.google.com/p/mupen64plus/ *
# * Copyright (C) 2007-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. *
# * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
# Makefile for SDL Input plugin in Mupen64plus
# detect operating system
UNAME ?= $(shell uname -s)
OS := NONE
ifeq ("$(UNAME)","Linux")
OS = LINUX
SO_EXTENSION = so
SHARED = -shared
endif
ifeq ("$(UNAME)","linux")
OS = LINUX
SO_EXTENSION = so
SHARED = -shared
endif
ifneq ("$(filter GNU hurd,$(UNAME))","")
OS = LINUX
SO_EXTENSION = so
SHARED = -shared
endif
ifeq ("$(UNAME)","Darwin")
OS = OSX
SO_EXTENSION = dylib
SHARED = -bundle
endif
ifeq ("$(UNAME)","FreeBSD")
OS = FREEBSD
SO_EXTENSION = so
SHARED = -shared
endif
ifeq ("$(UNAME)","OpenBSD")
OS = FREEBSD
SO_EXTENSION = so
SHARED = -shared
$(warning OS type "$(UNAME)" not officially supported.')
endif
ifneq ("$(filter GNU/kFreeBSD kfreebsd,$(UNAME))","")
OS = LINUX
SO_EXTENSION = so
SHARED = -shared
endif
ifeq ("$(patsubst MINGW%,MINGW,$(UNAME))","MINGW")
OS = MINGW
SO_EXTENSION = dll
SHARED = -shared
PIC = 0
endif
ifeq ("$(OS)","NONE")
$(error OS type "$(UNAME)" not supported. Please file bug report at 'http://code.google.com/p/mupen64plus/issues')
endif
# detect system architecture
HOST_CPU ?= $(shell uname -m)
NO_ASM ?= 1
CPU := NONE
ifneq ("$(filter x86_64 amd64,$(HOST_CPU))","")
CPU := X86
ifeq ("$(BITS)", "32")
ARCH_DETECTED := 64BITS_32
PIC ?= 0
else
ARCH_DETECTED := 64BITS
PIC ?= 1
endif
endif
ifneq ("$(filter pentium i%86,$(HOST_CPU))","")
CPU := X86
ARCH_DETECTED := 32BITS
PIC ?= 0
endif
ifneq ("$(filter ppc macppc socppc powerpc,$(HOST_CPU))","")
CPU := PPC
ARCH_DETECTED := 32BITS
BIG_ENDIAN := 1
PIC ?= 1
$(warning Architecture "$(HOST_CPU)" not officially supported.')
endif
ifneq ("$(filter ppc64 powerpc64,$(HOST_CPU))","")
CPU := PPC
ARCH_DETECTED := 64BITS
BIG_ENDIAN := 1
PIC ?= 1
$(warning Architecture "$(HOST_CPU)" not officially supported.')
endif
ifneq ("$(filter arm%,$(HOST_CPU))","")
ifeq ("$(filter arm%b,$(HOST_CPU))","")
CPU := ARM
ARCH_DETECTED := 32BITS
PIC ?= 1
$(warning Architecture "$(HOST_CPU)" not officially supported.')
endif
endif
ifeq ("$(CPU)","NONE")
$(error CPU type "$(HOST_CPU)" not supported. Please file bug report at 'http://code.google.com/p/mupen64plus/issues')
endif
# base CFLAGS, LDLIBS, and LDFLAGS
OPTFLAGS ?= -O3
WARNFLAGS ?= -Wall
CFLAGS += $(OPTFLAGS) $(WARNFLAGS) -ffast-math -fno-strict-aliasing -fvisibility=hidden -I../../src
LDFLAGS += $(SHARED)
# default configuration programs
SDL_CONFIG = $(CROSS_COMPILE)sdl-config
# Since we are building a shared library, we must compile with -fPIC on some architectures
# On 32-bit x86 systems we do not want to use -fPIC because we don't have to and it has a big performance penalty on this arch
ifeq ($(PIC), 1)
CFLAGS += -fPIC
LDFLAGS += -fPIC
else
CFLAGS += -fno-PIC
LDFLAGS += -fno-PIC
endif
ifeq ($(BIG_ENDIAN), 1)
CFLAGS += -DM64P_BIG_ENDIAN
endif
# tweak flags for 32-bit build on 64-bit system
ifeq ($(ARCH_DETECTED), 64BITS_32)
CFLAGS += -m32
LDFLAGS += -m32 -Wl,-m,elf_i386
endif
# set special flags per-system
ifeq ($(OS), FREEBSD)
ifeq ($(ARCH_DETECTED), 64BITS_32)
$(error Do not use the BITS=32 option with FreeBSD, use -m32 and -m elf_i386)
endif
endif
ifeq ($(OS), LINUX)
LDLIBS += -ldl
endif
ifeq ($(OS), OSX)
# Select the proper SDK
# Also, SDKs are stored in a different location since XCode 4.3
OSX_SDK ?= $(shell sw_vers -productVersion | cut -f1 -f2 -d .)
OSX_XCODEMAJ = $(shell xcodebuild -version | grep '[0-9]*\.[0-9]*' | cut -f2 -d ' ' | cut -f1 -d .)
OSX_XCODEMIN = $(shell xcodebuild -version | grep '[0-9]*\.[0-9]*' | cut -f2 -d ' ' | cut -f2 -d .)
OSX_XCODEGE43 = $(shell echo "`expr $(OSX_XCODEMAJ) \>= 4``expr $(OSX_XCODEMIN) \>= 3`")
ifeq ($(OSX_XCODEGE43), 11)
OSX_SYSROOT := /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs
else
OSX_SYSROOT := /Developer/SDKs
endif
ifeq ($(CPU), X86)
ifeq ($(ARCH_DETECTED), 64BITS)
CFLAGS += -arch x86_64 -mmacosx-version-min=$(OSX_SDK) -isysroot $(OSX_SYSROOT)/MacOSX$(OSX_SDK).sdk
LDLIBS += -ldl
else
CFLAGS += -mmmx -msse -fomit-frame-pointer -arch i686 -mmacosx-version-min=$(OSX_SDK) -isysroot $(OSX_SYSROOT)/MacOSX$(OSX_SDK).sdk
LDFLAGS += -arch i686
LDLIBS += -ldl -read_only_relocs suppress
endif
endif
endif
# test for presence of SDL
ifeq ($(shell which $(SDL_CONFIG) 2>/dev/null),)
$(error No SDL development libraries found!)
endif
CFLAGS += $(shell $(SDL_CONFIG) --cflags)
LDLIBS += $(shell $(SDL_CONFIG) --libs)
# set mupen64plus core API header path
ifneq ("$(APIDIR)","")
CFLAGS += "-I$(APIDIR)"
else
TRYDIR = ../../../mupen64plus-core/src/api
ifneq ("$(wildcard $(TRYDIR)/m64p_types.h)","")
CFLAGS += -I$(TRYDIR)
else
TRYDIR = /usr/local/include/mupen64plus
ifneq ("$(wildcard $(TRYDIR)/m64p_types.h)","")
CFLAGS += -I$(TRYDIR)
else
TRYDIR = /usr/include/mupen64plus
ifneq ("$(wildcard $(TRYDIR)/m64p_types.h)","")
CFLAGS += -I$(TRYDIR)
else
$(error Mupen64Plus API header files not found! Use makefile parameter APIDIR to force a location.)
endif
endif
endif
endif
# reduced compile output when running make without V=1
ifneq ($(findstring $(MAKEFLAGS),s),s)
ifndef V
Q_CC = @echo ' CC '$@;
Q_LD = @echo ' LD '$@;
endif
endif
# set base program pointers and flags
CC = $(CROSS_COMPILE)gcc
CXX = $(CROSS_COMPILE)g++
RM ?= rm -f
INSTALL ?= install
MKDIR ?= mkdir -p
COMPILE.c = $(Q_CC)$(CC) $(CFLAGS) $(CPPFLAGS) $(TARGET_ARCH) -c
LINK.o = $(Q_LD)$(CC) $(LDFLAGS) $(TARGET_ARCH)
# set special flags for given Makefile parameters
ifeq ($(DEBUG),1)
CFLAGS += -g
INSTALL_STRIP_FLAG ?=
else
ifneq ($(OS),OSX)
INSTALL_STRIP_FLAG ?= -s
endif
endif
ifeq ($(PLUGINDBG), 1)
CFLAGS += -D_DEBUG
endif
# set installation options
ifeq ($(PREFIX),)
PREFIX := /usr/local
endif
ifeq ($(SHAREDIR),)
SHAREDIR := $(PREFIX)/share/mupen64plus
endif
ifeq ($(LIBDIR),)
LIBDIR := $(PREFIX)/lib
endif
ifeq ($(PLUGINDIR),)
PLUGINDIR := $(LIBDIR)/mupen64plus
endif
SRCDIR = ../../src
OBJDIR = _obj$(POSTFIX)
# list of source files to compile
SOURCE = \
$(SRCDIR)/plugin.c \
$(SRCDIR)/autoconfig.c \
$(SRCDIR)/config.c
ifeq ($(OS),MINGW)
SOURCE += $(SRCDIR)/osal_dynamiclib_win32.c
else
SOURCE += $(SRCDIR)/osal_dynamiclib_unix.c
endif
# generate a list of object files build, make a temporary directory for them
OBJECTS := $(patsubst $(SRCDIR)/%.c, $(OBJDIR)/%.o, $(filter %.c, $(SOURCE)))
OBJDIRS = $(dir $(OBJECTS))
$(shell $(MKDIR) $(OBJDIRS))
# build targets
TARGET = mupen64plus-input-sdl$(POSTFIX).$(SO_EXTENSION)
targets:
@echo "Mupen64Plus-input-sdl makefile. "
@echo " Targets:"
@echo " all == Build Mupen64Plus SDL input plugin"
@echo " clean == remove object files"
@echo " rebuild == clean and re-build all"
@echo " install == Install Mupen64Plus SDL input plugin"
@echo " uninstall == Uninstall Mupen64Plus SDL input plugin"
@echo " Options:"
@echo " BITS=32 == build 32-bit binaries on 64-bit machine"
@echo " APIDIR=path == path to find Mupen64Plus Core headers"
@echo " OPTFLAGS=flag == compiler optimization (default: -O3)"
@echo " WARNFLAGS=flag == compiler warning levels (default: -Wall)"
@echo " PIC=(1|0) == Force enable/disable of position independent code"
@echo " POSTFIX=name == String added to the name of the the build (default: '')"
@echo " Install Options:"
@echo " PREFIX=path == install/uninstall prefix (default: /usr/local)"
@echo " SHAREDIR=path == path to install shared data files (default: PREFIX/share/mupen64plus)"
@echo " LIBDIR=path == library prefix (default: PREFIX/lib)"
@echo " PLUGINDIR=path == path to install plugin libraries (default: LIBDIR/mupen64plus)"
@echo " DESTDIR=path == path to prepend to all installation paths (only for packagers)"
@echo " Debugging Options:"
@echo " DEBUG=1 == add debugging symbols"
@echo " PLUGINDBG=1 == print extra debugging information while running"
@echo " LTO=1 == enable experimental build with link-time optimization"
@echo " V=1 == show verbose compiler output"
all: $(TARGET)
install: $(TARGET)
$(INSTALL) -d "$(DESTDIR)$(PLUGINDIR)"
$(INSTALL) -m 0644 $(INSTALL_STRIP_FLAG) $(TARGET) "$(DESTDIR)$(PLUGINDIR)"
$(INSTALL) -d "$(DESTDIR)$(SHAREDIR)"
$(INSTALL) -m 0644 "../../data/InputAutoCfg.ini" "$(DESTDIR)$(SHAREDIR)"
uninstall:
$(RM) "$(DESTDIR)$(PLUGINDIR)/$(TARGET)"
$(RM) "$(DESTDIR)$(SHAREDIR)/InputAutoCfg.ini"
clean:
$(RM) -r $(OBJDIR) $(TARGET)
rebuild: clean all
# build dependency files
CFLAGS += -MD
-include $(OBJECTS:.o=.d)
ifeq ($(LTO), 1)
CFLAGS += -flto
LDFLAGS += -fuse-linker-plugin $(CFLAGS)
endif
# standard build rules
$(OBJDIR)/%.o: $(SRCDIR)/%.c
$(COMPILE.c) -o $@ $<
$(TARGET): $(OBJECTS)
$(LINK.o) $^ $(LOADLIBES) $(LDLIBS) -o $@
.PHONY: all clean install uninstall targets

View File

@ -1,270 +0,0 @@
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
* Mupen64plus-input-sdl - autoconfig.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. *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
#include <string.h>
#include "m64p_types.h"
#include "m64p_config.h"
#include "osal_preproc.h"
#include "autoconfig.h"
#include "plugin.h"
/* local definitions */
#define INI_FILE_NAME "InputAutoCfg.ini"
/* local functions */
static char *StripSpace(char *pIn)
{
char *pEnd = pIn + strlen(pIn) - 1;
while (*pIn == ' ' || *pIn == '\t' || *pIn == '\r' || *pIn == '\n')
pIn++;
while (pIn <= pEnd && (*pEnd == ' ' || *pEnd == '\t' || *pEnd == '\r' || *pEnd == '\n'))
*pEnd-- = 0;
return pIn;
}
/* global functions */
int auto_set_defaults(int iDeviceIdx, const char *joySDLName)
{
FILE *pfIn;
m64p_handle pConfig = NULL;
const char *CfgFilePath = ConfigGetSharedDataFilepath(INI_FILE_NAME);
enum { E_NAME_SEARCH, E_NAME_FOUND, E_PARAM_READ } eParseState;
char *pchIni, *pchNextLine, *pchCurLine;
long iniLength;
int ControllersFound = 0;
/* if we couldn't get a name (no joystick plugged in to given port), then return with a failure */
if (joySDLName == NULL)
return 0;
/* if we couldn't find the shared data file, dump an error and return */
if (CfgFilePath == NULL || strlen(CfgFilePath) < 1)
{
DebugMessage(M64MSG_ERROR, "Couldn't find config file '%s'", INI_FILE_NAME);
return 0;
}
/* read the input auto-config .ini file */
pfIn = fopen(CfgFilePath, "rb");
if (pfIn == NULL)
{
DebugMessage(M64MSG_ERROR, "Couldn't open config file '%s'", CfgFilePath);
return 0;
}
fseek(pfIn, 0L, SEEK_END);
iniLength = ftell(pfIn);
fseek(pfIn, 0L, SEEK_SET);
pchIni = (char *) malloc(iniLength + 1);
if (pchIni == NULL)
{
DebugMessage(M64MSG_ERROR, "Couldn't allocate %li bytes for config file '%s'", iniLength, CfgFilePath);
fclose(pfIn);
return 0;
}
if (fread(pchIni, 1, iniLength, pfIn) != iniLength)
{
DebugMessage(M64MSG_ERROR, "File read failed for %li bytes of config file '%s'", iniLength, CfgFilePath);
free(pchIni);
fclose(pfIn);
return 0;
}
fclose(pfIn);
pchIni[iniLength] = 0;
/* parse the INI file, line by line */
pchNextLine = pchIni;
eParseState = E_NAME_SEARCH;
while (pchNextLine != NULL && *pchNextLine != 0)
{
char *pivot = NULL;
/* set up character pointers */
pchCurLine = pchNextLine;
pchNextLine = strchr(pchNextLine, '\n');
if (pchNextLine != NULL)
*pchNextLine++ = 0;
pchCurLine = StripSpace(pchCurLine);
/* handle blank/comment lines */
if (strlen(pchCurLine) < 1 || *pchCurLine == ';' || *pchCurLine == '#')
continue;
/* handle section (joystick name in ini file) */
if (*pchCurLine == '[' && pchCurLine[strlen(pchCurLine)-1] == ']')
{
char Word[64];
char *wordPtr;
int joyFound = 1;
if (eParseState == E_PARAM_READ)
{
/* we've finished parsing all parameters for the discovered input device */
free(pchIni);
return ControllersFound;
}
else if (eParseState == E_NAME_FOUND)
{
/* this is an equivalent device name to the one we're looking for (and found); keep looking for parameters */
continue;
}
/* we need to look through the device name word by word to see if it matches the joySDLName that we're looking for */
pchCurLine[strlen(pchCurLine)-1] = 0;
wordPtr = StripSpace(pchCurLine + 1);
/* first, if there is a preceding system name in this .ini device name, and the system matches, then strip out */
#if defined(__unix__)
if (strncmp(wordPtr, "Unix:", 5) == 0)
wordPtr = StripSpace(wordPtr + 5);
#endif
#if defined(__linux__)
if (strncmp(wordPtr, "Linux:", 6) == 0)
wordPtr = StripSpace(wordPtr + 6);
#endif
#if defined(__APPLE__)
if (strncmp(wordPtr, "OSX:", 4) == 0)
wordPtr = StripSpace(wordPtr + 4);
#endif
#if defined(WIN32)
if (strncmp(wordPtr, "Win32:", 6) == 0)
wordPtr = StripSpace(wordPtr + 6);
#endif
/* search in the .ini device name for all the words in the joystick name. If any are missing, then this is not the right joystick model */
while (wordPtr != NULL && strlen(wordPtr) > 0)
{
char *nextSpace = strchr(wordPtr, ' ');
if (nextSpace == NULL)
{
strncpy(Word, wordPtr, 63);
Word[63] = 0;
wordPtr = NULL;
}
else
{
int length = (int) (nextSpace - wordPtr);
if (length > 63) length = 63;
strncpy(Word, wordPtr, length);
Word[length] = 0;
wordPtr = nextSpace + 1;
}
if (strcasestr(joySDLName, Word) == NULL)
joyFound = 0;
}
/* if we found the right joystick, then open up the core config section to store parameters and set the 'device' param */
if (joyFound)
{
char SectionName[32];
sprintf(SectionName, "AutoConfig%i", ControllersFound);
if (ConfigOpenSection(SectionName, &pConfig) != M64ERR_SUCCESS)
{
DebugMessage(M64MSG_ERROR, "auto_set_defaults(): Couldn't open config section '%s'", SectionName);
free(pchIni);
return 0;
}
eParseState = E_NAME_FOUND;
ControllersFound++;
DebugMessage(M64MSG_INFO, "Using auto-configuration for device '%s'", joySDLName);
ConfigSetParameter(pConfig, "device", M64TYPE_INT, &iDeviceIdx);
}
continue;
}
/* handle parameters */
pivot = strchr(pchCurLine, '=');
if (pivot != NULL)
{
/* if we haven't found the correct section yet, just skip this */
if (eParseState == E_NAME_SEARCH)
continue;
eParseState = E_PARAM_READ;
/* otherwise, store this parameter in the current active joystick config */
*pivot++ = 0;
pchCurLine = StripSpace(pchCurLine);
pivot = StripSpace(pivot);
if (strcasecmp(pchCurLine, "plugin") == 0 || strcasecmp(pchCurLine, "device") == 0)
{
int iVal = atoi(pivot);
ConfigSetParameter(pConfig, pchCurLine, M64TYPE_INT, &iVal);
}
else if (strcasecmp(pchCurLine, "plugged") == 0 || strcasecmp(pchCurLine, "mouse") == 0)
{
int bVal = (strcasecmp(pivot, "true") == 0);
ConfigSetParameter(pConfig, pchCurLine, M64TYPE_BOOL, &bVal);
}
else
{
ConfigSetParameter(pConfig, pchCurLine, M64TYPE_STRING, pivot);
}
continue;
}
/* handle keywords */
if (pchCurLine[strlen(pchCurLine)-1] == ':')
{
/* if we haven't found the correct section yet, just skip this */
if (eParseState == E_NAME_SEARCH)
continue;
/* otherwise parse the keyword */
if (strcmp(pchCurLine, "__NextController:") == 0)
{
char SectionName[32];
/* if there are no more N64 controller spaces left, then exit */
if (ControllersFound == 4)
{
free(pchIni);
return ControllersFound;
}
/* otherwise go to the next N64 controller */
sprintf(SectionName, "AutoConfig%i", ControllersFound);
if (ConfigOpenSection(SectionName, &pConfig) != M64ERR_SUCCESS)
{
DebugMessage(M64MSG_ERROR, "auto_set_defaults(): Couldn't open config section '%s'", SectionName);
free(pchIni);
return ControllersFound;
}
ControllersFound++;
DebugMessage(M64MSG_INFO, "Using auto-configuration for device '%s': %i controllers for this device", joySDLName, ControllersFound);
ConfigSetParameter(pConfig, "device", M64TYPE_INT, &iDeviceIdx);
}
else
{
DebugMessage(M64MSG_ERROR, "Unknown keyword '%s' in %s", pchCurLine, INI_FILE_NAME);
}
continue;
}
/* unhandled line in .ini file */
DebugMessage(M64MSG_ERROR, "Invalid line in %s: '%s'", INI_FILE_NAME, pchCurLine);
}
if (eParseState == E_PARAM_READ)
{
/* we've finished parsing all parameters for the discovered input device, which is the last in the .ini file */
free(pchIni);
return ControllersFound;
}
DebugMessage(M64MSG_INFO, "No auto-configuration found for device '%s'", joySDLName);
free(pchIni);
return 0;
}

View File

@ -1,28 +0,0 @@
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
* Mupen64plus-input-sdl - autoconfig.h *
* 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. *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
#ifndef __AUTOCONFIG_H__
#define __AUTOCONFIG_H__
extern int auto_set_defaults(int iDeviceIdx, const char *joySDLName);
#endif /* __AUTOCONFIG_H__ */

View File

@ -1,592 +0,0 @@
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
* Mupen64plus-input-sdl - config.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. *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
#include <SDL.h>
#define M64P_PLUGIN_PROTOTYPES 1
#include "m64p_types.h"
#include "m64p_plugin.h"
#include "m64p_config.h"
#include "osal_preproc.h"
#include "autoconfig.h"
#include "plugin.h"
#include "config.h"
#define HAT_POS_NAME( hat ) \
((hat == SDL_HAT_UP) ? "Up" : \
((hat == SDL_HAT_DOWN) ? "Down" : \
((hat == SDL_HAT_LEFT) ? "Left" : \
((hat == SDL_HAT_RIGHT) ? "Right" : \
"None"))))
static const char *button_names[] = {
"DPad R", // R_DPAD
"DPad L", // L_DPAD
"DPad D", // D_DPAD
"DPad U", // U_DPAD
"Start", // START_BUTTON
"Z Trig", // Z_TRIG
"B Button", // B_BUTTON
"A Button", // A_BUTTON
"C Button R", // R_CBUTTON
"C Button L", // L_CBUTTON
"C Button D", // D_CBUTTON
"C Button U", // U_CBUTTON
"R Trig", // R_TRIG
"L Trig", // L_TRIG
"Mempak switch",
"Rumblepak switch",
"X Axis", // X_AXIS
"Y Axis" // Y_AXIS
};
/* static functions */
static int get_hat_pos_by_name( const char *name )
{
if( !strcasecmp( name, "up" ) )
return SDL_HAT_UP;
if( !strcasecmp( name, "down" ) )
return SDL_HAT_DOWN;
if( !strcasecmp( name, "left" ) )
return SDL_HAT_LEFT;
if( !strcasecmp( name, "right" ) )
return SDL_HAT_RIGHT;
DebugMessage(M64MSG_WARNING, "get_hat_pos_by_name(): direction '%s' unknown", name);
return -1;
}
static void clear_controller(int iCtrlIdx)
{
int b;
controller[iCtrlIdx].device = DEVICE_AUTO;
controller[iCtrlIdx].control->Present = 0;
controller[iCtrlIdx].control->RawData = 0;
controller[iCtrlIdx].control->Plugin = PLUGIN_NONE;
for( b = 0; b < 16; b++ )
{
controller[iCtrlIdx].button[b].button = -1;
controller[iCtrlIdx].button[b].key = SDL_SCANCODE_UNKNOWN;
controller[iCtrlIdx].button[b].axis = -1;
controller[iCtrlIdx].button[b].axis_deadzone = -1;
controller[iCtrlIdx].button[b].hat = -1;
controller[iCtrlIdx].button[b].hat_pos = -1;
controller[iCtrlIdx].button[b].mouse = -1;
}
for( b = 0; b < 2; b++ )
{
controller[iCtrlIdx].mouse_sens[b] = 2.0;
controller[iCtrlIdx].axis_deadzone[b] = 4096;
controller[iCtrlIdx].axis_peak[b] = 32768;
controller[iCtrlIdx].axis[b].button_a = controller[iCtrlIdx].axis[b].button_b = -1;
controller[iCtrlIdx].axis[b].key_a = controller[iCtrlIdx].axis[b].key_b = SDL_SCANCODE_UNKNOWN;
controller[iCtrlIdx].axis[b].axis_a = -1;
controller[iCtrlIdx].axis[b].axis_dir_a = 1;
controller[iCtrlIdx].axis[b].axis_b = -1;
controller[iCtrlIdx].axis[b].axis_dir_b = 1;
controller[iCtrlIdx].axis[b].hat = -1;
controller[iCtrlIdx].axis[b].hat_pos_a = -1;
controller[iCtrlIdx].axis[b].hat_pos_b = -1;
}
}
static const char * get_sdl_joystick_name(int iCtrlIdx)
{
static char JoyName[256];
const char *joySDLName;
int joyWasInit = SDL_WasInit(SDL_INIT_JOYSTICK);
/* initialize the joystick subsystem if necessary */
if (!joyWasInit)
if (SDL_InitSubSystem(SDL_INIT_JOYSTICK) == -1)
{
DebugMessage(M64MSG_ERROR, "Couldn't init SDL joystick subsystem: %s", SDL_GetError() );
return NULL;
}
/* get the name of the corresponding joystick */
joySDLName = SDL_JoystickName(iCtrlIdx);
/* copy the name to our local string */
if (joySDLName != NULL)
{
strncpy(JoyName, joySDLName, 255);
JoyName[255] = 0;
}
/* quit the joystick subsystem if necessary */
if (!joyWasInit)
SDL_QuitSubSystem(SDL_INIT_JOYSTICK);
/* if the SDL function had an error, then return NULL, otherwise return local copy of joystick name */
if (joySDLName == NULL)
return NULL;
else
return JoyName;
}
/////////////////////////////////////
// load_controller_config()
// return value: 1 = OK
// 0 = fail: couldn't open config section
// -1 = fail: stored configuration incomplete - missing parameters
// -2 = fail: AutoKeyboard stored in mupen64plus.cfg file
// -3 = fail: joystick name stored in mupen64plus.cfg doesn't match SDL joystick name for given SDL joystick #
static int load_controller_config(const char *SectionName, int i, int bIsAutoconfig)
{
m64p_handle pConfig;
char input_str[256], value1_str[16], value2_str[16];
const char *config_ptr;
int j;
/* Open the configuration section for this controller */
if (ConfigOpenSection(SectionName, &pConfig) != M64ERR_SUCCESS)
{
DebugMessage(M64MSG_ERROR, "Couldn't open config section '%s'", SectionName);
return 0;
}
/* Check version number, and if it doesn't match: delete the config section and return with error */
if (!bIsAutoconfig)
{
float fVersion = 0.0f;
if (ConfigGetParameter(pConfig, "version", M64TYPE_FLOAT, &fVersion, sizeof(float)) != M64ERR_SUCCESS)
{
ConfigDeleteSection(SectionName);
return -1;
}
if (((int) fVersion) != ((int) CONFIG_VERSION))
{
DebugMessage(M64MSG_WARNING, "Incompatible version %.2f in config section '%s': current is %.2f. Clearing.", fVersion, SectionName, (float) CONFIG_VERSION);
ConfigDeleteSection(SectionName);
return -1;
}
}
/* check for the required parameters */
if (ConfigGetParameter(pConfig, "plugged", M64TYPE_BOOL, &controller[i].control->Present, sizeof(int)) != M64ERR_SUCCESS)
return -1;
if (ConfigGetParameter(pConfig, "plugin", M64TYPE_INT, &controller[i].control->Plugin, sizeof(int)) != M64ERR_SUCCESS)
return -1;
if (ConfigGetParameter(pConfig, "device", M64TYPE_INT, &controller[i].device, sizeof(int)) != M64ERR_SUCCESS)
return -1;
/* Name validation only applies to stored configurations (not auto-configs) */
if (!bIsAutoconfig)
{
char device_name[256];
if (ConfigGetParameter(pConfig, "name", M64TYPE_STRING, device_name, 256) != M64ERR_SUCCESS)
device_name[0] = 0;
if (controller[i].device == DEVICE_NOT_JOYSTICK)
{
/* do not load automatically generated keyboard config that was stored to disk (prefer any joysticks attached) */
if (strcmp(device_name, "AutoKeyboard") == 0)
return -2;
}
else if (controller[i].device >= 0 && device_name[0] != 0)
{
/* check that the SDL device name matches the name stored in the config section */
const char *sdl_name = get_sdl_joystick_name(controller[i].device);
if (sdl_name == NULL || strncmp(device_name, sdl_name, 255) != 0)
{
DebugMessage(M64MSG_WARNING, "N64 Controller #%i: SDL joystick name '%s' doesn't match stored configuration name '%s'", i + 1, sdl_name, device_name);
return -3;
}
}
}
/* then do the optional parameters */
ConfigGetParameter(pConfig, "mouse", M64TYPE_BOOL, &controller[i].mouse, sizeof(int));
if (ConfigGetParameter(pConfig, "MouseSensitivity", M64TYPE_STRING, input_str, 256) == M64ERR_SUCCESS)
{
if (sscanf(input_str, "%f,%f", &controller[i].mouse_sens[0], &controller[i].mouse_sens[1]) != 2)
DebugMessage(M64MSG_WARNING, "parsing error in MouseSensitivity parameter for controller %i", i + 1);
}
if (ConfigGetParameter(pConfig, "AnalogDeadzone", M64TYPE_STRING, input_str, 256) == M64ERR_SUCCESS)
{
if (sscanf(input_str, "%i,%i", &controller[i].axis_deadzone[0], &controller[i].axis_deadzone[1]) != 2)
DebugMessage(M64MSG_WARNING, "parsing error in AnalogDeadzone parameter for controller %i", i + 1);
}
if (ConfigGetParameter(pConfig, "AnalogPeak", M64TYPE_STRING, input_str, 256) == M64ERR_SUCCESS)
{
if (sscanf(input_str, "%i,%i", &controller[i].axis_peak[0], &controller[i].axis_peak[1]) != 2)
DebugMessage(M64MSG_WARNING, "parsing error in AnalogPeak parameter for controller %i", i + 1);
}
/* load configuration for all the digital buttons */
for (j = 0; j < X_AXIS; j++)
{
if (ConfigGetParameter(pConfig, button_names[j], M64TYPE_STRING, input_str, 256) != M64ERR_SUCCESS)
{
DebugMessage(M64MSG_WARNING, "missing config key '%s' for controller %i button %i", button_names[j], i+1, j);
continue;
}
if ((config_ptr = strstr(input_str, "key")) != NULL)
if (sscanf(config_ptr, "key(%i)", (int *) &controller[i].button[j].key) != 1)
DebugMessage(M64MSG_WARNING, "parsing error in key() parameter of button '%s' for controller %i", button_names[j], i + 1);
if ((config_ptr = strstr(input_str, "button")) != NULL)
if (sscanf(config_ptr, "button(%i)", &controller[i].button[j].button) != 1)
DebugMessage(M64MSG_WARNING, "parsing error in button() parameter of button '%s' for controller %i", button_names[j], i + 1);
if ((config_ptr = strstr(input_str, "axis")) != NULL)
{
char chAxisDir;
if (sscanf(config_ptr, "axis(%d%c,%d", &controller[i].button[j].axis, &chAxisDir, &controller[i].button[j].axis_deadzone) != 3 &&
sscanf(config_ptr, "axis(%i%c", &controller[i].button[j].axis, &chAxisDir) != 2)
DebugMessage(M64MSG_WARNING, "parsing error in axis() parameter of button '%s' for controller %i", button_names[j], i + 1);
controller[i].button[j].axis_dir = (chAxisDir == '+' ? 1 : (chAxisDir == '-' ? -1 : 0));
}
if ((config_ptr = strstr(input_str, "hat")) != NULL)
{
char *lastchar = NULL;
if (sscanf(config_ptr, "hat(%i %15s", &controller[i].button[j].hat, value1_str) != 2)
DebugMessage(M64MSG_WARNING, "parsing error in hat() parameter of button '%s' for controller %i", button_names[j], i + 1);
value1_str[15] = 0;
/* chop off the last character of value1_str if it is the closing parenthesis */
lastchar = &value1_str[strlen(value1_str) - 1];
if (lastchar > value1_str && *lastchar == ')') *lastchar = 0;
controller[i].button[j].hat_pos = get_hat_pos_by_name(value1_str);
}
if ((config_ptr = strstr(input_str, "mouse")) != NULL)
if (sscanf(config_ptr, "mouse(%i)", &controller[i].button[j].mouse) != 1)
DebugMessage(M64MSG_WARNING, "parsing error in mouse() parameter of button '%s' for controller %i", button_names[j], i + 1);
}
/* load configuration for the 2 analog joystick axes */
for (j = X_AXIS; j <= Y_AXIS; j++)
{
int axis_idx = j - X_AXIS;
if (ConfigGetParameter(pConfig, button_names[j], M64TYPE_STRING, input_str, 256) != M64ERR_SUCCESS)
{
DebugMessage(M64MSG_WARNING, "missing config key '%s' for controller %i axis %i", button_names[j], i+1, axis_idx);
continue;
}
if ((config_ptr = strstr(input_str, "key")) != NULL)
if (sscanf(config_ptr, "key(%i,%i)", (int *) &controller[i].axis[axis_idx].key_a, (int *) &controller[i].axis[axis_idx].key_b) != 2)
DebugMessage(M64MSG_WARNING, "parsing error in key() parameter of axis '%s' for controller %i", button_names[j], i + 1);
if ((config_ptr = strstr(input_str, "button")) != NULL)
if (sscanf(config_ptr, "button(%i,%i)", &controller[i].axis[axis_idx].button_a, &controller[i].axis[axis_idx].button_b) != 2)
DebugMessage(M64MSG_WARNING, "parsing error in button() parameter of axis '%s' for controller %i", button_names[j], i + 1);
if ((config_ptr = strstr(input_str, "axis")) != NULL)
{
char chAxisDir1, chAxisDir2;
if (sscanf(config_ptr, "axis(%i%c,%i%c)", &controller[i].axis[axis_idx].axis_a, &chAxisDir1,
&controller[i].axis[axis_idx].axis_b, &chAxisDir2) != 4)
DebugMessage(M64MSG_WARNING, "parsing error in axis() parameter of axis '%s' for controller %i", button_names[j], i + 1);
controller[i].axis[axis_idx].axis_dir_a = (chAxisDir1 == '+' ? 1 : (chAxisDir1 == '-' ? -1 : 0));
controller[i].axis[axis_idx].axis_dir_b = (chAxisDir2 == '+' ? 1 : (chAxisDir2 == '-' ? -1 : 0));
}
if ((config_ptr = strstr(input_str, "hat")) != NULL)
{
char *lastchar = NULL;
if (sscanf(config_ptr, "hat(%i %15s %15s", &controller[i].axis[axis_idx].hat, value1_str, value2_str) != 3)
DebugMessage(M64MSG_WARNING, "parsing error in hat() parameter of axis '%s' for controller %i", button_names[j], i + 1);
value1_str[15] = value2_str[15] = 0;
/* chop off the last character of value2_str if it is the closing parenthesis */
lastchar = &value2_str[strlen(value2_str) - 1];
if (lastchar > value2_str && *lastchar == ')') *lastchar = 0;
controller[i].axis[axis_idx].hat_pos_a = get_hat_pos_by_name(value1_str);
controller[i].axis[axis_idx].hat_pos_b = get_hat_pos_by_name(value2_str);
}
}
return 1;
}
static void save_controller_config(int iCtrlIdx, const char *pccDeviceName)
{
m64p_handle pConfig;
char SectionName[32], Param[32], ParamString[128];
int j;
/* Delete the configuration section for this controller, so we can use SetDefaults and save the help comments also */
sprintf(SectionName, "Input-SDL-Control%i", iCtrlIdx + 1);
ConfigDeleteSection(SectionName);
/* Open the configuration section for this controller (create a new one) */
if (ConfigOpenSection(SectionName, &pConfig) != M64ERR_SUCCESS)
{
DebugMessage(M64MSG_ERROR, "Couldn't open config section '%s'", SectionName);
return;
}
/* save the general controller parameters */
ConfigSetDefaultFloat(pConfig, "version", CONFIG_VERSION, "Mupen64Plus SDL Input Plugin config parameter version number. Please don't change this version number.");
ConfigSetDefaultBool(pConfig, "plugged", controller[iCtrlIdx].control->Present, "Specifies whether this controller is 'plugged in' to the simulated N64");
ConfigSetDefaultInt(pConfig, "plugin", controller[iCtrlIdx].control->Plugin, "Specifies which type of expansion pak is in the controller: 1=None, 2=Mem pak, 5=Rumble pak");
ConfigSetDefaultBool(pConfig, "mouse", controller[iCtrlIdx].mouse, "If True, then mouse buttons may be used with this controller");
ConfigSetDefaultInt(pConfig, "device", controller[iCtrlIdx].device, "Specifies which joystick is bound to this controller: -2=Keyboard/mouse, -1=Auto config, 0 or more= SDL Joystick number");
ConfigSetDefaultString(pConfig, "name", pccDeviceName, "SDL joystick name (name check disabled if this is empty string)");
sprintf(Param, "%.2f,%.2f", controller[iCtrlIdx].mouse_sens[0], controller[iCtrlIdx].mouse_sens[1]);
ConfigSetDefaultString(pConfig, "MouseSensitivity", Param, "Scaling factor for mouse movements. For X, Y axes.");
sprintf(Param, "%i,%i", controller[iCtrlIdx].axis_deadzone[0], controller[iCtrlIdx].axis_deadzone[1]);
ConfigSetDefaultString(pConfig, "AnalogDeadzone", Param, "The minimum absolute value of the SDL analog joystick axis to move the N64 controller axis value from 0. For X, Y axes.");
sprintf(Param, "%i,%i", controller[iCtrlIdx].axis_peak[0], controller[iCtrlIdx].axis_peak[1]);
ConfigSetDefaultString(pConfig, "AnalogPeak", Param, "An absolute value of the SDL joystick axis >= AnalogPeak will saturate the N64 controller axis value (at 80). For X, Y axes. For each axis, this must be greater than the corresponding AnalogDeadzone value");
/* save configuration for all the digital buttons */
for (j = 0; j < X_AXIS; j++ )
{
const char *Help;
int len = 0;
ParamString[0] = 0;
if (controller[iCtrlIdx].button[j].key > 0)
{
sprintf(Param, "key(%i) ", controller[iCtrlIdx].button[j].key);
strcat(ParamString, Param);
}
if (controller[iCtrlIdx].button[j].button >= 0)
{
sprintf(Param, "button(%i) ", controller[iCtrlIdx].button[j].button);
strcat(ParamString, Param);
}
if (controller[iCtrlIdx].button[j].axis >= 0)
{
if (controller[iCtrlIdx].button[j].axis_deadzone >= 0)
sprintf(Param, "axis(%i%c,%i) ", controller[iCtrlIdx].button[j].axis, (controller[iCtrlIdx].button[j].axis_dir == -1) ? '-' : '+',
controller[iCtrlIdx].button[j].axis_deadzone);
else
sprintf(Param, "axis(%i%c) ", controller[iCtrlIdx].button[j].axis, (controller[iCtrlIdx].button[j].axis_dir == -1) ? '-' : '+');
strcat(ParamString, Param);
}
if (controller[iCtrlIdx].button[j].hat >= 0)
{
sprintf(Param, "hat(%i %s) ", controller[iCtrlIdx].button[j].hat, HAT_POS_NAME(controller[iCtrlIdx].button[j].hat_pos));
strcat(ParamString, Param);
}
if (controller[iCtrlIdx].button[j].mouse >= 0)
{
sprintf(Param, "mouse(%i) ", controller[iCtrlIdx].button[j].mouse);
strcat(ParamString, Param);
}
if (j == 0)
Help = "Digital button configuration mappings";
else
Help = NULL;
/* if last character is a space, chop it off */
len = strlen(ParamString);
if (len > 0 && ParamString[len-1] == ' ')
ParamString[len-1] = 0;
ConfigSetDefaultString(pConfig, button_names[j], ParamString, Help);
}
/* save configuration for the 2 analog axes */
for (j = 0; j < 2; j++ )
{
const char *Help;
int len = 0;
ParamString[0] = 0;
if (controller[iCtrlIdx].axis[j].key_a > 0 && controller[iCtrlIdx].axis[j].key_b > 0)
{
sprintf(Param, "key(%i,%i) ", controller[iCtrlIdx].axis[j].key_a, controller[iCtrlIdx].axis[j].key_b);
strcat(ParamString, Param);
}
if (controller[iCtrlIdx].axis[j].button_a >= 0 && controller[iCtrlIdx].axis[j].button_b >= 0)
{
sprintf(Param, "button(%i,%i) ", controller[iCtrlIdx].axis[j].button_a, controller[iCtrlIdx].axis[j].button_b);
strcat(ParamString, Param);
}
if (controller[iCtrlIdx].axis[j].axis_a >= 0 && controller[iCtrlIdx].axis[j].axis_b >= 0)
{
sprintf(Param, "axis(%i%c,%i%c) ", controller[iCtrlIdx].axis[j].axis_a, (controller[iCtrlIdx].axis[j].axis_dir_a <= 0) ? '-' : '+',
controller[iCtrlIdx].axis[j].axis_b, (controller[iCtrlIdx].axis[j].axis_dir_b <= 0) ? '-' : '+' );
strcat(ParamString, Param);
}
if (controller[iCtrlIdx].axis[j].hat >= 0)
{
sprintf(Param, "hat(%i %s %s) ", controller[iCtrlIdx].axis[j].hat,
HAT_POS_NAME(controller[iCtrlIdx].axis[j].hat_pos_a),
HAT_POS_NAME(controller[iCtrlIdx].axis[j].hat_pos_b));
strcat(ParamString, Param);
}
if (j == 0)
Help = "Analog axis configuration mappings";
else
Help = NULL;
/* if last character is a space, chop it off */
len = strlen(ParamString);
if (len > 0 && ParamString[len-1] == ' ')
ParamString[len-1] = 0;
ConfigSetDefaultString(pConfig, button_names[X_AXIS + j], ParamString, Help);
}
}
static void force_controller_keyboard(int n64CtrlIdx)
{
if (n64CtrlIdx < 0 || n64CtrlIdx > 3)
{
DebugMessage(M64MSG_ERROR, "internal assert in ForceControllerKeyboard. n64CtrlIdx=%i", n64CtrlIdx);
return;
}
DebugMessage(M64MSG_INFO, "N64 Controller #%i: Forcing default keyboard configuration", n64CtrlIdx+1);
auto_set_defaults(DEVICE_NOT_JOYSTICK, "Keyboard");
if (load_controller_config("AutoConfig0", n64CtrlIdx, 1) > 0)
{
/* use ConfigSetDefault*() to save this auto-config if config section was empty */
save_controller_config(n64CtrlIdx, "AutoKeyboard");
}
else
{
DebugMessage(M64MSG_ERROR, "Autoconfig keyboard setup invalid");
}
ConfigDeleteSection("AutoConfig0");
}
/* global functions */
/* The reason why the architecture of this config-handling code is so wacky is that it tries to balance
* several different user scenarios. From a high-level perspective, it works like this:
* 1. If there is a valid configuration setup already in the config file, it should not be changed
* - if a user sets up a joystick in a GUI dialog, this code should not cause the setup to magically change under any circumstances
* - if the config setup references an SDL joystick, and that device is not connected, then the controller is disabled
* 2. If there is no valid setup for an N64 controller in the config file, or the device is set to AUTO, then we will try to auto-configure it
* - there must be a joystick connected which SDL recognizes
* - the auto-configuration is based on the joystick's name (usually USB device name)
* - if the auto-configuration is successful, then the input plugin's internal data structures are configured for use but the config file parameters are not overwritten
* - However, if the config data section (Input-SDL-Control*) was previously empty, then the auto-configured parameters *will* be written to the config file
* - this allows a user to run the emulator once and save the auto-configured parameters, then later tweak the settings from a GUI
* 3. If for any reason there are no joysticks enabled after trying to set up all 4 controllers, then Controller #1 will be auto-configured for Keyboard usage
* - the keyboard config parameters will never be written to the config file, even if the Input-SDL-Control1 section was previously empty
*/
void load_configuration(int bPrintSummary)
{
char SectionName[32];
const char *JoyName;
int joy_found = 0, joy_plugged = 0;
int readOK;
int n64CtrlIdx, sdlCtrlIdx, j;
/* loop through all 4 simulated N64 controllers */
for (n64CtrlIdx=0,sdlCtrlIdx=0; n64CtrlIdx < 4; n64CtrlIdx++)
{
/* reset the controller configuration */
clear_controller(n64CtrlIdx);
/* try to load the config from the core's configuration api */
sprintf(SectionName, "Input-SDL-Control%i", n64CtrlIdx + 1);
readOK = load_controller_config(SectionName, n64CtrlIdx, 0);
if (readOK <= 0 || controller[n64CtrlIdx].device == DEVICE_AUTO)
{
int ControllersFound = 0;
/* make sure that SDL device number hasn't already been used for a different N64 controller */
for (j = 0; j < n64CtrlIdx; j++)
{
if (controller[j].device == sdlCtrlIdx)
{
sdlCtrlIdx++;
j = -1;
}
}
/* if auto / bad config, get joystick name based on SDL order */
JoyName = get_sdl_joystick_name(sdlCtrlIdx);
/* reset the controller configuration again and try to auto-configure */
ControllersFound = auto_set_defaults(sdlCtrlIdx, JoyName);
sdlCtrlIdx++;
if (ControllersFound == 0)
{
controller[n64CtrlIdx].device = DEVICE_AUTO;
controller[n64CtrlIdx].control->Present = 0;
DebugMessage(M64MSG_VERBOSE, "N64 Controller #%i: Disabled, SDL joystick %i is not available", n64CtrlIdx+1, sdlCtrlIdx-1);
}
else
{
for (j = 0; j < ControllersFound; j++) /* a USB device may have > 1 controller */
{
sprintf(SectionName, "AutoConfig%i", j);
if (n64CtrlIdx + j > 3)
{
ConfigDeleteSection(SectionName);
continue;
}
clear_controller(n64CtrlIdx + j);
if (load_controller_config(SectionName, n64CtrlIdx + j, 1) > 0)
{
/* use ConfigSetDefault*() to save this auto-config if config section was empty */
save_controller_config(n64CtrlIdx + j, JoyName);
DebugMessage(M64MSG_INFO, "N64 Controller #%i: Using auto-config for SDL joystick %i ('%s')", n64CtrlIdx+1, controller[n64CtrlIdx].device, JoyName);
}
else
{
DebugMessage(M64MSG_ERROR, "Autoconfig data invalid for controller #%i in device '%s'", j + 1, JoyName);
}
ConfigDeleteSection(SectionName);
}
n64CtrlIdx += ControllersFound - 1;
continue;
}
}
else if (controller[n64CtrlIdx].device >= 0)
{
/* if joystick found in cfg, take its SDL number from there */
JoyName = get_sdl_joystick_name(controller[n64CtrlIdx].device);
/* valid joystick configuration was read; check if the specified joystick is available in SDL */
if (JoyName == NULL)
{
controller[n64CtrlIdx].device = DEVICE_AUTO;
controller[n64CtrlIdx].control->Present = 0;
DebugMessage(M64MSG_WARNING, "N64 Controller #%i: Disabled, SDL joystick %i is not available", n64CtrlIdx+1, controller[n64CtrlIdx].device);
}
else
DebugMessage(M64MSG_INFO, "N64 Controller #%i: Using stored config for SDL joystick %i ('%s')", n64CtrlIdx+1, controller[n64CtrlIdx].device, JoyName);
}
else /* controller is configured for keyboard/mouse */
{
DebugMessage(M64MSG_INFO, "N64 Controller #%i: Using keyboard/mouse", n64CtrlIdx+1);
}
}
/* see how many joysticks were found */
joy_found = 0, joy_plugged = 0;
for (j = 0; j < 4; j++)
{
if (controller[j].device >= 0 || controller[j].device == DEVICE_NOT_JOYSTICK)
{
joy_found++;
if (controller[j].control->Present)
joy_plugged++;
}
}
/* fallback to keyboard if no joysticks are available and 'plugged in' */
if (joy_found == 0 || joy_plugged == 0)
{
force_controller_keyboard(0);
}
if (bPrintSummary)
{
if (joy_found > 0 && joy_plugged > 0)
{
DebugMessage(M64MSG_INFO, "%i controller(s) found, %i plugged in and usable in the emulator", joy_found, joy_plugged);
}
else
{
if (joy_found == 0)
DebugMessage(M64MSG_WARNING, "No joysticks/controllers found");
else if (joy_plugged == 0)
DebugMessage(M64MSG_WARNING, "%i controllers found, but none were 'plugged in'", joy_found);
}
}
}

View File

@ -1,30 +0,0 @@
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
* Mupen64plus-input-sdl - config.h *
* 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. *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
#ifndef __CONFIG_H__
#define __CONFIG_H__
#define CONFIG_VERSION 1.00
extern void load_configuration(int bPrintSummary);
#endif /* __CONFIG_H__ */

View File

@ -1,30 +0,0 @@
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
* Mupen64plus-core - osal/dynamiclib.h *
* 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. *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
#if !defined(OSAL_DYNAMICLIB_H)
#define OSAL_DYNAMICLIB_H
#include "m64p_types.h"
void * osal_dynlib_getproc(m64p_dynlib_handle LibHandle, const char *pccProcedureName);
#endif /* #define OSAL_DYNAMICLIB_H */

View File

@ -1,37 +0,0 @@
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
* Mupen64plus-core - osal/dynamiclib_unix.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. *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
#include <stdlib.h>
#include <stdio.h>
#include <dlfcn.h>
#include "m64p_types.h"
#include "osal_dynamiclib.h"
void * osal_dynlib_getproc(m64p_dynlib_handle LibHandle, const char *pccProcedureName)
{
if (pccProcedureName == NULL)
return NULL;
return dlsym(LibHandle, pccProcedureName);
}

View File

@ -1,74 +0,0 @@
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
* Mupen64plus-ui-console - osal_dynamiclib_win32.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. *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
#include <windows.h>
#include <stdlib.h>
#include <stdio.h>
#include "m64p_types.h"
#include "osal_dynamiclib.h"
m64p_error osal_dynlib_open(m64p_dynlib_handle *pLibHandle, const char *pccLibraryPath)
{
if (pLibHandle == NULL || pccLibraryPath == NULL)
return M64ERR_INPUT_ASSERT;
*pLibHandle = LoadLibrary(pccLibraryPath);
if (*pLibHandle == NULL)
{
char *pchErrMsg;
DWORD dwErr = GetLastError();
FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM, NULL, dwErr,
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPTSTR) &pchErrMsg, 0, NULL);
fprintf(stderr, "LoadLibrary('%s') error: %s\n", pccLibraryPath, pchErrMsg);
LocalFree(pchErrMsg);
return M64ERR_INPUT_NOT_FOUND;
}
return M64ERR_SUCCESS;
}
void * osal_dynlib_getproc(m64p_dynlib_handle LibHandle, const char *pccProcedureName)
{
if (pccProcedureName == NULL)
return NULL;
return GetProcAddress(LibHandle, pccProcedureName);
}
m64p_error osal_dynlib_close(m64p_dynlib_handle LibHandle)
{
int rval = FreeLibrary(LibHandle);
if (rval == 0)
{
char *pchErrMsg;
DWORD dwErr = GetLastError();
FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM, NULL, dwErr,
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPTSTR) &pchErrMsg, 0, NULL);
fprintf(stderr, "FreeLibrary() error: %s\n", pchErrMsg);
LocalFree(pchErrMsg);
return M64ERR_INTERNAL;
}
return M64ERR_SUCCESS;
}

View File

@ -1,33 +0,0 @@
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
* Mupen64plus - osal_preproc.h *
* Mupen64Plus homepage: http://code.google.com/p/mupen64plus/ *
* Copyright (C) 2009 Richard Goedeken *
* Copyright (C) 2002 Hacktarux *
* *
* 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 header file is for system-dependent #defines, #includes, and typedefs */
#if !defined(OSAL_PREPROC_H)
#define OSAL_PREPROC_H
#if defined(WIN32)
#define strcasestr strstr
#define strcasecmp _stricmp
#endif // WIN32
#endif // OSAL_PREPROC_H

View File

@ -1,919 +0,0 @@
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
* Mupen64plus-input-sdl - plugin.c *
* Mupen64Plus homepage: http://code.google.com/p/mupen64plus/ *
* 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 <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <SDL.h>
#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"
#ifdef __linux__
#include <unistd.h>
#include <dirent.h>
#include <fcntl.h>
#include <sys/types.h>
#include <linux/input.h>
#endif /* __linux__ */
#include <errno.h>
/* defines for the force feedback rumble support */
#ifdef __linux__
#define BITS_PER_LONG (sizeof(long) * 8)
#define OFF(x) ((x)%BITS_PER_LONG)
#define BIT(x) (1UL<<OFF(x))
#define LONG(x) ((x)/BITS_PER_LONG)
#define test_bit(bit, array) ((array[LONG(bit)] >> OFF(bit)) & 1)
#endif //__linux__
/* definitions of pointers to Core config functions */
ptr_ConfigOpenSection ConfigOpenSection = NULL;
ptr_ConfigDeleteSection ConfigDeleteSection = NULL;
ptr_ConfigSetParameter ConfigSetParameter = NULL;
ptr_ConfigGetParameter ConfigGetParameter = 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;
/* 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 unsigned short button_bits[] = {
0x0001, // R_DPAD
0x0002, // L_DPAD
0x0004, // D_DPAD
0x0008, // U_DPAD
0x0010, // START_BUTTON
0x0020, // Z_TRIG
0x0040, // B_BUTTON
0x0080, // A_BUTTON
0x0100, // R_CBUTTON
0x0200, // L_CBUTTON
0x0400, // D_CBUTTON
0x0800, // U_CBUTTON
0x1000, // R_TRIG
0x2000, // L_TRIG
0x4000, // Mempak switch
0x8000 // Rumblepak switch
};
static int romopen = 0; // is a rom opened
static unsigned char myKeyState[SDL_NUM_SCANCODES];
#ifdef __linux__
static struct ff_effect ffeffect[3];
static struct ff_effect ffstrong[3];
static struct ff_effect ffweak[3];
#endif //__linux__
/* 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);
}
static CONTROL temp_core_controlinfo[4];
/* Mupen64Plus plugin functions */
EXPORT m64p_error CALL PluginStartup(m64p_dynlib_handle CoreLibHandle, void *Context,
void (*DebugCallback)(void *, int, const char *))
{
ptr_CoreGetAPIVersions CoreAPIVersionFunc;
int i, 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;
}
/* 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");
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 || !ConfigDeleteSection || !ConfigSetParameter || !ConfigGetParameter ||
!ConfigSetDefaultInt || !ConfigSetDefaultFloat || !ConfigSetDefaultBool || !ConfigSetDefaultString ||
!ConfigGetParamInt || !ConfigGetParamFloat || !ConfigGetParamBool || !ConfigGetParamString ||
!ConfigGetSharedDataFilepath || !ConfigGetUserConfigPath || !ConfigGetUserDataPath || !ConfigGetUserCachePath)
{
DebugMessage(M64MSG_ERROR, "Couldn't connect to Core configuration functions");
return M64ERR_INCOMPATIBLE;
}
/* reset controllers */
memset(controller, 0, sizeof(SController) * 4);
for (i = 0; i < SDL_NUM_SCANCODES; i++)
{
myKeyState[i] = 0;
}
/* set CONTROL struct pointers to the temporary static array */
/* this small struct is used to tell the core whether each controller is plugged in, and what type of pak is connected */
/* we only need it so that we can call load_configuration below, to auto-config for a GUI front-end */
for (i = 0; i < 4; i++)
controller[i].control = temp_core_controlinfo + i;
/* read plugin config from core config database, auto-config if necessary and update core database */
load_configuration(0);
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;
return M64ERR_SUCCESS;
}
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;
}
/* Helper function to handle the SDL keys */
static void
doSdlKeys(unsigned char* keystate)
{
int c, b, axis_val, axis_max_val;
static int grabmouse = 1, grabtoggled = 0;
axis_max_val = 80;
if (keystate[SDL_SCANCODE_RCTRL])
axis_max_val -= 40;
if (keystate[SDL_SCANCODE_RSHIFT])
axis_max_val -= 20;
for( c = 0; c < 4; c++ )
{
for( b = 0; b < 16; b++ )
{
if( controller[c].button[b].key == SDL_SCANCODE_UNKNOWN || ((int) controller[c].button[b].key) < 0)
continue;
if( keystate[controller[c].button[b].key] )
controller[c].buttons.Value |= button_bits[b];
}
for( b = 0; b < 2; b++ )
{
// from the N64 func ref: The 3D Stick data is of type signed char and in
// the range between 80 and -80. (32768 / 409 = ~80.1)
if( b == 0 )
axis_val = controller[c].buttons.X_AXIS;
else
axis_val = -controller[c].buttons.Y_AXIS;
if( controller[c].axis[b].key_a != SDL_SCANCODE_UNKNOWN && ((int) controller[c].axis[b].key_a) > 0)
if( keystate[controller[c].axis[b].key_a] )
axis_val = -axis_max_val;
if( controller[c].axis[b].key_b != SDL_SCANCODE_UNKNOWN && ((int) controller[c].axis[b].key_b) > 0)
if( keystate[controller[c].axis[b].key_b] )
axis_val = axis_max_val;
if( b == 0 )
controller[c].buttons.X_AXIS = axis_val;
else
controller[c].buttons.Y_AXIS = -axis_val;
}
if (controller[c].mouse)
{
if (keystate[SDL_SCANCODE_LCTRL] && keystate[SDL_SCANCODE_LALT])
{
if (!grabtoggled)
{
grabtoggled = 1;
grabmouse = !grabmouse;
// grab/ungrab mouse
#if SDL_VERSION_ATLEAST(2,0,0)
#warning SDL mouse grabbing not yet supported with SDL 2.0
#else
SDL_WM_GrabInput( grabmouse ? SDL_GRAB_ON : SDL_GRAB_OFF );
#endif
SDL_ShowCursor( grabmouse ? 0 : 1 );
}
}
else grabtoggled = 0;
}
}
}
static unsigned char DataCRC( unsigned char *Data, int iLenght )
{
unsigned char Remainder = Data[0];
int iByte = 1;
unsigned char bBit = 0;
while( iByte <= iLenght )
{
int HighBit = ((Remainder & 0x80) != 0);
Remainder = Remainder << 1;
Remainder += ( iByte < iLenght && Data[iByte] & (0x80 >> bBit )) ? 1 : 0;
Remainder ^= (HighBit) ? 0x85 : 0;
bBit++;
iByte += bBit/8;
bBit %= 8;
}
return Remainder;
}
/******************************************************************
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)
{
unsigned char *Data = &Command[5];
if (Control == -1)
return;
switch (Command[2])
{
case RD_GETSTATUS:
#ifdef _DEBUG
DebugMessage(M64MSG_INFO, "Get status");
#endif
break;
case RD_READKEYS:
#ifdef _DEBUG
DebugMessage(M64MSG_INFO, "Read keys");
#endif
break;
case RD_READPAK:
#ifdef _DEBUG
DebugMessage(M64MSG_INFO, "Read pak");
#endif
if (controller[Control].control->Plugin == PLUGIN_RAW)
{
unsigned int dwAddress = (Command[3] << 8) + (Command[4] & 0xE0);
if(( dwAddress >= 0x8000 ) && ( dwAddress < 0x9000 ) )
memset( Data, 0x80, 32 );
else
memset( Data, 0x00, 32 );
Data[32] = DataCRC( Data, 32 );
}
break;
case RD_WRITEPAK:
#ifdef _DEBUG
DebugMessage(M64MSG_INFO, "Write pak");
#endif
if (controller[Control].control->Plugin == PLUGIN_RAW)
{
unsigned int dwAddress = (Command[3] << 8) + (Command[4] & 0xE0);
if (dwAddress == PAK_IO_RUMBLE && *Data)
DebugMessage(M64MSG_VERBOSE, "Triggering rumble pack.");
#ifdef __linux__
struct input_event play;
if( dwAddress == PAK_IO_RUMBLE && controller[Control].event_joystick != 0)
{
if( *Data )
{
play.type = EV_FF;
play.code = ffeffect[Control].id;
play.value = 1;
if (write(controller[Control].event_joystick, (const void*) &play, sizeof(play)) == -1)
perror("Error starting rumble effect");
}
else
{
play.type = EV_FF;
play.code = ffeffect[Control].id;
play.value = 0;
if (write(controller[Control].event_joystick, (const void*) &play, sizeof(play)) == -1)
perror("Error stopping rumble effect");
}
}
#endif //__linux__
Data[32] = DataCRC( Data, 32 );
}
break;
case RD_RESETCONTROLLER:
#ifdef _DEBUG
DebugMessage(M64MSG_INFO, "Reset controller");
#endif
break;
case RD_READEEPROM:
#ifdef _DEBUG
DebugMessage(M64MSG_INFO, "Read eeprom");
#endif
break;
case RD_WRITEEPROM:
#ifdef _DEBUG
DebugMessage(M64MSG_INFO, "Write eeprom");
#endif
break;
}
}
/******************************************************************
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 )
{
static int mousex_residual = 0;
static int mousey_residual = 0;
int b, axis_val;
SDL_Event event;
unsigned char mstate;
// Handle keyboard input first
doSdlKeys(SDL_GetKeyboardState(NULL));
doSdlKeys(myKeyState);
// read joystick state
SDL_JoystickUpdate();
if( controller[Control].device >= 0 )
{
for( b = 0; b < 16; b++ )
{
if( controller[Control].button[b].button >= 0 )
if( SDL_JoystickGetButton( controller[Control].joystick, controller[Control].button[b].button ) )
controller[Control].buttons.Value |= button_bits[b];
if( controller[Control].button[b].axis >= 0 )
{
int deadzone = controller[Control].button[b].axis_deadzone;
axis_val = SDL_JoystickGetAxis( controller[Control].joystick, controller[Control].button[b].axis );
if (deadzone < 0)
deadzone = 6000; /* default */
if( (controller[Control].button[b].axis_dir < 0) && (axis_val <= -deadzone) )
controller[Control].buttons.Value |= button_bits[b];
else if( (controller[Control].button[b].axis_dir > 0) && (axis_val >= deadzone) )
controller[Control].buttons.Value |= button_bits[b];
}
if( controller[Control].button[b].hat >= 0 )
{
if( controller[Control].button[b].hat_pos > 0 )
if( SDL_JoystickGetHat( controller[Control].joystick, controller[Control].button[b].hat ) & controller[Control].button[b].hat_pos )
controller[Control].buttons.Value |= button_bits[b];
}
}
for( b = 0; b < 2; b++ )
{
/* from the N64 func ref: The 3D Stick data is of type signed char and in the range between -80 and +80 */
int deadzone = controller[Control].axis_deadzone[b];
int range = controller[Control].axis_peak[b] - controller[Control].axis_deadzone[b];
/* skip this axis if the deadzone/peak values are invalid */
if (deadzone < 0 || range < 1)
continue;
if( b == 0 )
axis_val = controller[Control].buttons.X_AXIS;
else
axis_val = -controller[Control].buttons.Y_AXIS;
if( controller[Control].axis[b].axis_a >= 0 ) /* up and left for N64 */
{
int joy_val = SDL_JoystickGetAxis(controller[Control].joystick, controller[Control].axis[b].axis_a);
int axis_dir = controller[Control].axis[b].axis_dir_a;
if (joy_val * axis_dir > deadzone)
axis_val = -((abs(joy_val) - deadzone) * 80 / range);
if (axis_val < -80)
axis_val = -80;
}
if( controller[Control].axis[b].axis_b >= 0 ) /* down and right for N64 */
{
int joy_val = SDL_JoystickGetAxis(controller[Control].joystick, controller[Control].axis[b].axis_b);
int axis_dir = controller[Control].axis[b].axis_dir_b;
if (joy_val * axis_dir > deadzone)
axis_val = ((abs(joy_val) - deadzone) * 80 / range);
if (axis_val > 80)
axis_val = 80;
}
if( controller[Control].axis[b].hat >= 0 )
{
if( controller[Control].axis[b].hat_pos_a >= 0 )
if( SDL_JoystickGetHat( controller[Control].joystick, controller[Control].axis[b].hat ) & controller[Control].axis[b].hat_pos_a )
axis_val = -80;
if( controller[Control].axis[b].hat_pos_b >= 0 )
if( SDL_JoystickGetHat( controller[Control].joystick, controller[Control].axis[b].hat ) & controller[Control].axis[b].hat_pos_b )
axis_val = 80;
}
if( controller[Control].axis[b].button_a >= 0 )
if( SDL_JoystickGetButton( controller[Control].joystick, controller[Control].axis[b].button_a ) )
axis_val = -80;
if( controller[Control].axis[b].button_b >= 0 )
if( SDL_JoystickGetButton( controller[Control].joystick, controller[Control].axis[b].button_b ) )
axis_val = 80;
if( b == 0 )
controller[Control].buttons.X_AXIS = axis_val;
else
controller[Control].buttons.Y_AXIS = -axis_val;
}
}
// process mouse events
mstate = SDL_GetMouseState( NULL, NULL );
for( b = 0; b < 16; b++ )
{
if( controller[Control].button[b].mouse < 1 )
continue;
if( mstate & SDL_BUTTON(controller[Control].button[b].mouse) )
controller[Control].buttons.Value |= button_bits[b];
}
if (controller[Control].mouse)
{
#if SDL_VERSION_ATLEAST(2,0,0)
#warning SDL mouse grabbing not yet supported with SDL 2.0
#else
if (SDL_WM_GrabInput(SDL_GRAB_QUERY) == SDL_GRAB_ON)
{
SDL_PumpEvents();
#if SDL_VERSION_ATLEAST(1,3,0)
while (SDL_PeepEvents(&event, 1, SDL_GETEVENT, SDL_MOUSEMOTION, SDL_MOUSEMOTION) == 1)
#else
while (SDL_PeepEvents(&event, 1, SDL_GETEVENT, SDL_EVENTMASK(SDL_MOUSEMOTION)) == 1)
#endif
{
if (event.motion.xrel)
{
mousex_residual += (int) (event.motion.xrel * controller[Control].mouse_sens[0]);
}
if (event.motion.yrel)
{
mousey_residual += (int) (event.motion.yrel * controller[Control].mouse_sens[1]);
}
}
}
else
#endif
{
mousex_residual = 0;
mousey_residual = 0;
}
axis_val = mousex_residual;
if (axis_val < -80)
axis_val = -80;
else if (axis_val > 80)
axis_val = 80;
controller[Control].buttons.X_AXIS = axis_val;
axis_val = mousey_residual;
if (axis_val < -80)
axis_val = -80;
else if (axis_val > 80)
axis_val = 80;
controller[Control].buttons.Y_AXIS = -axis_val;
/* the mouse x/y values decay exponentially */
mousex_residual = (mousex_residual * 224) / 256;
mousey_residual = (mousey_residual * 224) / 256;
}
#ifdef _DEBUG
DebugMessage(M64MSG_VERBOSE, "Controller #%d value: 0x%8.8X", Control, *(int *)&controller[Control].buttons );
#endif
*Keys = controller[Control].buttons;
/* handle mempack / rumblepak switching (only if rumble is active on joystick) */
#ifdef __linux__
if (controller[Control].event_joystick != 0)
{
struct input_event play;
static unsigned int SwitchPackTime[4] = {0, 0, 0, 0}, SwitchPackType[4] = {0, 0, 0, 0};
// when the user switches packs, we should mimick the act of removing 1 pack, and then inserting another 1 second later
if (controller[Control].buttons.Value & button_bits[14])
{
SwitchPackTime[Control] = SDL_GetTicks(); // time at which the 'switch pack' command was given
SwitchPackType[Control] = PLUGIN_MEMPAK; // type of new pack to insert
controller[Control].control->Plugin = PLUGIN_NONE;// remove old pack
play.type = EV_FF;
play.code = ffweak[Control].id;
play.value = 1;
if (write(controller[Control].event_joystick, (const void*) &play, sizeof(play)) == -1)
perror("Error starting rumble effect");
}
if (controller[Control].buttons.Value & button_bits[15])
{
SwitchPackTime[Control] = SDL_GetTicks(); // time at which the 'switch pack' command was given
SwitchPackType[Control] = PLUGIN_RAW; // type of new pack to insert
controller[Control].control->Plugin = PLUGIN_NONE;// remove old pack
play.type = EV_FF;
play.code = ffstrong[Control].id;
play.value = 1;
if (write(controller[Control].event_joystick, (const void*) &play, sizeof(play)) == -1)
perror("Error starting rumble effect");
}
// handle inserting new pack if the time has arrived
if (SwitchPackTime[Control] != 0 && (SDL_GetTicks() - SwitchPackTime[Control]) >= 1000)
{
controller[Control].control->Plugin = SwitchPackType[Control];
SwitchPackTime[Control] = 0;
}
}
#endif /* __linux__ */
controller[Control].buttons.Value = 0;
}
static void InitiateRumble(int cntrl)
{
#ifdef __linux__
DIR* dp;
struct dirent* ep;
unsigned long features[4];
char temp[128];
char temp2[128];
int iFound = 0;
controller[cntrl].event_joystick = 0;
sprintf(temp,"/sys/class/input/js%d/device", controller[cntrl].device);
dp = opendir(temp);
if(dp==NULL)
return;
while ((ep=readdir(dp)))
{
if (strncmp(ep->d_name, "event",5)==0)
{
sprintf(temp, "/dev/input/%s", ep->d_name);
iFound = 1;
break;
}
else if(strncmp(ep->d_name,"input:event", 11)==0)
{
sscanf(ep->d_name, "input:%s", temp2);
sprintf(temp, "/dev/input/%s", temp2);
iFound = 1;
break;
}
else if(strncmp(ep->d_name,"input:input", 11)==0)
{
strcat(temp, "/");
strcat(temp, ep->d_name);
closedir (dp);
dp = opendir(temp);
if(dp==NULL)
return;
}
}
closedir(dp);
if (!iFound)
{
DebugMessage(M64MSG_WARNING, "Couldn't find input event for rumble support.");
return;
}
controller[cntrl].event_joystick = open(temp, O_RDWR);
if(controller[cntrl].event_joystick==-1)
{
DebugMessage(M64MSG_WARNING, "Couldn't open device file '%s' for rumble support.", temp);
controller[cntrl].event_joystick = 0;
return;
}
if(ioctl(controller[cntrl].event_joystick, EVIOCGBIT(EV_FF, sizeof(unsigned long) * 4), features)==-1)
{
DebugMessage(M64MSG_WARNING, "Linux kernel communication failed for force feedback (rumble).\n");
controller[cntrl].event_joystick = 0;
return;
}
if(!test_bit(FF_RUMBLE, features))
{
DebugMessage(M64MSG_WARNING, "No rumble supported on N64 joystick #%i", cntrl + 1);
controller[cntrl].event_joystick = 0;
return;
}
ffeffect[cntrl].type = FF_RUMBLE;
ffeffect[cntrl].id = -1;
ffeffect[cntrl].u.rumble.strong_magnitude = 0xFFFF;
ffeffect[cntrl].u.rumble.weak_magnitude = 0xFFFF;
ioctl(controller[cntrl].event_joystick, EVIOCSFF, &ffeffect[cntrl]);
ffstrong[cntrl].type = FF_RUMBLE;
ffstrong[cntrl].id = -1;
ffstrong[cntrl].u.rumble.strong_magnitude = 0xFFFF;
ffstrong[cntrl].u.rumble.weak_magnitude = 0x0000;
ffstrong[cntrl].replay.length = 500;
ffstrong[cntrl].replay.delay = 0;
ioctl(controller[cntrl].event_joystick, EVIOCSFF, &ffstrong[cntrl]);
ffweak[cntrl].type = FF_RUMBLE;
ffweak[cntrl].id = -1;
ffweak[cntrl].u.rumble.strong_magnitude = 0x0000;
ffweak[cntrl].u.rumble.weak_magnitude = 0xFFFF;
ffweak[cntrl].replay.length = 500;
ffweak[cntrl].replay.delay = 0;
ioctl(controller[cntrl].event_joystick, EVIOCSFF, &ffweak[cntrl]);
DebugMessage(M64MSG_INFO, "Rumble activated on N64 joystick #%i", cntrl + 1);
#endif /* __linux__ */
}
/******************************************************************
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;
// reset controllers
memset( controller, 0, sizeof( SController ) * 4 );
for ( i = 0; i < SDL_NUM_SCANCODES; i++)
{
myKeyState[i] = 0;
}
// set our CONTROL struct pointers to the array that was passed in to this function from the core
// this small struct tells the core whether each controller is plugged in, and what type of pak is connected
for (i = 0; i < 4; i++)
controller[i].control = ControlInfo.Controls + i;
// read configuration
load_configuration(1);
for( i = 0; i < 4; i++ )
{
// test for rumble support for this joystick
InitiateRumble(i);
// if rumble not supported, switch to mempack
if (controller[i].control->Plugin == PLUGIN_RAW && controller[i].event_joystick == 0)
controller[i].control->Plugin = PLUGIN_MEMPAK;
}
DebugMessage(M64MSG_INFO, "%s version %i.%i.%i initialized.", PLUGIN_NAME, VERSION_PRINTF_SPLIT(PLUGIN_VERSION));
}
/******************************************************************
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)
{
#ifdef _DEBUG
if (Command != NULL)
DebugMessage(M64MSG_INFO, "Raw Read (cont=%d): %02X %02X %02X %02X %02X %02X", Control,
Command[0], Command[1], Command[2], Command[3], Command[4], Command[5]);
#endif
}
/******************************************************************
Function: RomClosed
Purpose: This function is called when a rom is closed.
input: none
output: none
*******************************************************************/
EXPORT void CALL RomClosed(void)
{
int i;
// close joysticks
for( i = 0; i < 4; i++ )
if( controller[i].joystick )
{
SDL_JoystickClose( controller[i].joystick );
controller[i].joystick = NULL;
}
// quit SDL joystick subsystem
SDL_QuitSubSystem( SDL_INIT_JOYSTICK );
// release/ungrab mouse
#if SDL_VERSION_ATLEAST(2,0,0)
#warning SDL mouse grabbing not yet supported with SDL 2.0
#else
SDL_WM_GrabInput( SDL_GRAB_OFF );
#endif
SDL_ShowCursor( 1 );
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)
{
int i;
// init SDL joystick subsystem
if( !SDL_WasInit( SDL_INIT_JOYSTICK ) )
if( SDL_InitSubSystem( SDL_INIT_JOYSTICK ) == -1 )
{
DebugMessage(M64MSG_ERROR, "Couldn't init SDL joystick subsystem: %s", SDL_GetError() );
return 0;
}
// open joysticks
for( i = 0; i < 4; i++ )
if( controller[i].device >= 0 )
{
controller[i].joystick = SDL_JoystickOpen( controller[i].device );
if( controller[i].joystick == NULL )
DebugMessage(M64MSG_WARNING, "Couldn't open joystick for controller #%d: %s", i + 1, SDL_GetError() );
}
else
controller[i].joystick = NULL;
// grab mouse
if (controller[0].mouse || controller[1].mouse || controller[2].mouse || controller[3].mouse)
{
#if SDL_VERSION_ATLEAST(2,0,0)
#warning SDL mouse grabbing not yet supported with SDL 2.0
#else
SDL_ShowCursor( 0 );
if (SDL_WM_GrabInput( SDL_GRAB_ON ) != SDL_GRAB_ON)
{
DebugMessage(M64MSG_WARNING, "Couldn't grab input! Mouse support won't work!");
}
#endif
}
romopen = 1;
return 1;
}
/******************************************************************
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)
{
myKeyState[keysym] = 1;
}
/******************************************************************
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)
{
myKeyState[keysym] = 0;
}

View File

@ -1,175 +0,0 @@
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
* Mupen64plus-input-sdl - plugin.h *
* Mupen64Plus homepage: http://code.google.com/p/mupen64plus/ *
* Copyright (C) 2008-2009 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. *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
#ifndef __PLUGIN_H__
#define __PLUGIN_H__
#include <SDL.h>
#if ! SDL_VERSION_ATLEAST(1,3,0)
#define SDL_GetKeyboardState SDL_GetKeyState
#define SDL_SCANCODE_UNKNOWN SDLK_UNKNOWN
#define SDL_NUM_SCANCODES SDLK_LAST
#define SDL_SCANCODE_RCTRL SDLK_RCTRL
#define SDL_SCANCODE_RSHIFT SDLK_RSHIFT
#define SDL_SCANCODE_LCTRL SDLK_LCTRL
#define SDL_SCANCODE_LALT SDLK_LALT
#define SDL_Scancode SDLKey
#endif
#if SDL_VERSION_ATLEAST(2,0,0)
static inline const char* _SDL_JoystickName(int device_index)
{
SDL_Joystick *joystick;
const char *name;
static char JoyName[256];
joystick = SDL_JoystickOpen(device_index);
if (!joystick)
return NULL;
name = SDL_JoystickName(joystick);
if (name)
{
strncpy(JoyName, name, 255);
JoyName[255] = 0;
}
SDL_JoystickClose(joystick);
return JoyName;
}
#define SDL_JoystickName(device_index) _SDL_JoystickName(device_index)
#endif
#define M64P_PLUGIN_PROTOTYPES 1
#include "m64p_plugin.h"
#include "m64p_config.h"
#define DEVICE_AUTO (-1)
#define DEVICE_NOT_JOYSTICK (-2)
// Some stuff from n-rage plugin
#define RD_GETSTATUS 0x00 // get status
#define RD_READKEYS 0x01 // read button values
#define RD_READPAK 0x02 // read from controllerpack
#define RD_WRITEPAK 0x03 // write to controllerpack
#define RD_RESETCONTROLLER 0xff // reset controller
#define RD_READEEPROM 0x04 // read eeprom
#define RD_WRITEEPROM 0x05 // write eeprom
#define PAK_IO_RUMBLE 0xC000 // the address where rumble-commands are sent to
enum EButton
{
R_DPAD = 0,
L_DPAD,
D_DPAD,
U_DPAD,
START_BUTTON,
Z_TRIG,
B_BUTTON,
A_BUTTON,
R_CBUTTON,
L_CBUTTON,
D_CBUTTON,
U_CBUTTON,
R_TRIG,
L_TRIG,
MEMPAK,
RUMBLEPAK,
X_AXIS,
Y_AXIS,
NUM_BUTTONS
};
typedef struct
{
int button; // button index; -1 if notassigned
SDL_Scancode key; // sdl keysym; SDL_SCANCODE_UNKNOWN if not assigned
int axis, axis_dir; // aixs + direction (i.e. 0, 1 = X Axis +; 0, -1 = X Axis -); -1 if notassigned
int axis_deadzone; // -1 for default, or >= 0 for custom value
int hat, hat_pos; // hat + hat position; -1 if not assigned
int mouse; // mouse button
} SButtonMap;
typedef struct
{
int button_a, button_b; // up/down or left/right; -1 if not assigned
SDL_Scancode key_a, key_b; // up/down or left/right; SDL_SCANCODE_UNKNOWN if not assigned
int axis_a, axis_b; // axis index; -1 if not assigned
int axis_dir_a, axis_dir_b; // direction (1 = X+, 0, -1 = X-)
int hat, hat_pos_a, hat_pos_b; // hat + hat position up/down and left/right; -1 if not assigned
} SAxisMap;
typedef struct
{
CONTROL *control; // pointer to CONTROL struct in Core library
BUTTONS buttons;
// mappings
SButtonMap button[16]; // 14 buttons; in the order of EButton + mempak/rumblepak switches
SAxisMap axis[2]; // 2 axis
int device; // joystick device; -1 = keyboard; -2 = none
int mouse; // mouse enabled: 0 = no; 1 = yes
SDL_Joystick *joystick; // SDL joystick device
int event_joystick; // the /dev/input/eventX device for force feeback
int axis_deadzone[2]; // minimum absolute value before analog movement is recognized
int axis_peak[2]; // highest analog value returned by SDL, used for scaling
float mouse_sens[2]; // mouse sensitivity
} SController;
/* global data definitions */
extern SController controller[4]; // 4 controllers
/* global function definitions */
extern void DebugMessage(int level, const char *message, ...);
/* declarations of pointers to Core config functions */
extern ptr_ConfigListSections ConfigListSections;
extern ptr_ConfigOpenSection ConfigOpenSection;
extern ptr_ConfigDeleteSection ConfigDeleteSection;
extern ptr_ConfigListParameters ConfigListParameters;
extern ptr_ConfigSaveFile ConfigSaveFile;
extern ptr_ConfigSetParameter ConfigSetParameter;
extern ptr_ConfigGetParameter ConfigGetParameter;
extern ptr_ConfigGetParameterHelp ConfigGetParameterHelp;
extern ptr_ConfigSetDefaultInt ConfigSetDefaultInt;
extern ptr_ConfigSetDefaultFloat ConfigSetDefaultFloat;
extern ptr_ConfigSetDefaultBool ConfigSetDefaultBool;
extern ptr_ConfigSetDefaultString ConfigSetDefaultString;
extern ptr_ConfigGetParamInt ConfigGetParamInt;
extern ptr_ConfigGetParamFloat ConfigGetParamFloat;
extern ptr_ConfigGetParamBool ConfigGetParamBool;
extern ptr_ConfigGetParamString ConfigGetParamString;
extern ptr_ConfigGetSharedDataFilepath ConfigGetSharedDataFilepath;
extern ptr_ConfigGetUserConfigPath ConfigGetUserConfigPath;
extern ptr_ConfigGetUserDataPath ConfigGetUserDataPath;
extern ptr_ConfigGetUserCachePath ConfigGetUserCachePath;
#endif // __PLUGIN_H__

View File

@ -1,37 +0,0 @@
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
* Mupen64plus-input-sdl - version.h *
* Mupen64Plus homepage: http://code.google.com/p/mupen64plus/ *
* Copyright (C) 2009-2012 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 header file is for versioning information
*
*/
#if !defined(VERSION_H)
#define VERSION_H
#define PLUGIN_NAME "Mupen64Plus SDL Input Plugin"
#define PLUGIN_VERSION 0x016305
#define INPUT_PLUGIN_API_VERSION 0x020000
#define CONFIG_API_VERSION 0x020000
#define VERSION_PRINTF_SPLIT(x) (((x) >> 16) & 0xffff), (((x) >> 8) & 0xff), ((x) & 0xff)
#endif /* #define VERSION_H */

Binary file not shown.