add automatic mapping of joysticks
This commit is contained in:
@@ -48,6 +48,9 @@ NEW FEATURE: New parameters for background changes: rate, fade old, loop,
|
||||
rewind.
|
||||
CHANGE: Background playback speed scaled by song rate, so movies stay in
|
||||
sync (although syncing isn't very accurate at some song rates).
|
||||
NEW FEATURE: Automatic mapping of joysticks.
|
||||
NEW FEATURE: Automatically adujst graphic detail on first run.
|
||||
NEW FEATURE: #DISPLAYBPM tag for SM and DWI files.
|
||||
|
||||
----------------------- Version 3.01 ---------------------------
|
||||
CHANGE: Simplified NoteSkin tap graphic format. Old NoteSkins will need to
|
||||
|
||||
@@ -1787,6 +1787,7 @@ AttackDurationSeconds=0
|
||||
|
||||
[ScreenInputOptions]
|
||||
HelpText=&UP; &DOWN; to change line &LEFT; &RIGHT; to select between options::START to accept changes BACK to discard changes
|
||||
AutoMapJoysticks=&oq;ON&cq; will cause StepMania automatically create::mappings for the joysticks attached to your computer::at the time the program starts. This will::override any manually defined mappings.
|
||||
IgnoreJoyAxes=&oq;ON&cq; will cause StepMania to ignore all input from::joystick directional pads. This is useful for the DirectPad Pro driver::and some brands of USB convertors.
|
||||
MenuButtons=The default setting allows the dance pad's panels to navigate::the menus. Changing this to &oq;dedicated only&cq; will restrict::menu navigation to only the Menu* set of buttons. Be sure to map::the Menu* set of buttons before setting this to &oq;dedicated&cq;!
|
||||
AutoPlay=This option is useful for those who would like to play::without using a pad. However, you will not be able to set::high scores or earn extra stages while this options is ON.
|
||||
|
||||
@@ -17,6 +17,8 @@
|
||||
#include "RageLog.h"
|
||||
#include "InputFilter.h"
|
||||
#include "RageUtil.h"
|
||||
#include "PrefsManager.h"
|
||||
#include "RageInput.h"
|
||||
|
||||
|
||||
InputMapper* INPUTMAPPER = NULL; // global and accessable from anywhere in our program
|
||||
@@ -63,6 +65,113 @@ void InputMapper::AddDefaultMappingsForCurrentGameIfUnmapped()
|
||||
}
|
||||
}
|
||||
|
||||
struct AutoJoyMapping
|
||||
{
|
||||
Game game;
|
||||
char sDeviceDescription[64];
|
||||
bool bIgnoreAxes;
|
||||
int numMappings;
|
||||
struct {
|
||||
int deviceButton;
|
||||
GameButton gb;
|
||||
} mapping[32];
|
||||
};
|
||||
const AutoJoyMapping g_AutoJoyMappings[] =
|
||||
{
|
||||
{
|
||||
GAME_DANCE,
|
||||
"GIC USB Joystick",
|
||||
false,
|
||||
4,
|
||||
{
|
||||
{ JOY_16, DANCE_BUTTON_LEFT },
|
||||
{ JOY_14, DANCE_BUTTON_RIGHT },
|
||||
{ JOY_13, DANCE_BUTTON_UP },
|
||||
{ JOY_15, DANCE_BUTTON_DOWN },
|
||||
}
|
||||
},
|
||||
{
|
||||
GAME_DANCE,
|
||||
"4 axis 16 button joystick", // likely a PC Magic Box
|
||||
false,
|
||||
4,
|
||||
{
|
||||
{ JOY_16, DANCE_BUTTON_LEFT },
|
||||
{ JOY_14, DANCE_BUTTON_RIGHT },
|
||||
{ JOY_13, DANCE_BUTTON_UP },
|
||||
{ JOY_15, DANCE_BUTTON_DOWN },
|
||||
}
|
||||
},
|
||||
{
|
||||
GAME_DANCE,
|
||||
"GamePad Pro USB ", // yes, there is a space at the end
|
||||
false,
|
||||
12,
|
||||
{
|
||||
{ JOY_LEFT, DANCE_BUTTON_LEFT },
|
||||
{ JOY_RIGHT, DANCE_BUTTON_RIGHT },
|
||||
{ JOY_UP, DANCE_BUTTON_UP },
|
||||
{ JOY_DOWN, DANCE_BUTTON_DOWN },
|
||||
{ JOY_1, DANCE_BUTTON_LEFT },
|
||||
{ JOY_3, DANCE_BUTTON_RIGHT },
|
||||
{ JOY_4, DANCE_BUTTON_UP },
|
||||
{ JOY_2, DANCE_BUTTON_DOWN },
|
||||
{ JOY_5, DANCE_BUTTON_UPLEFT },
|
||||
{ JOY_6, DANCE_BUTTON_UPRIGHT },
|
||||
{ JOY_9, DANCE_BUTTON_BACK },
|
||||
{ JOY_10, DANCE_BUTTON_START },
|
||||
}
|
||||
},
|
||||
};
|
||||
const int NUM_AUTO_JOY_MAPPINGS = sizeof(g_AutoJoyMappings) / sizeof(g_AutoJoyMappings[0]);
|
||||
|
||||
void InputMapper::AutoMapJoysticksForCurrentGame()
|
||||
{
|
||||
vector<InputDevice> vDevices;
|
||||
vector<CString> vDescriptions;
|
||||
PREFSMAN->m_bIgnoreJoyAxes = false;
|
||||
INPUTMAN->GetDevicesAndDescriptions(vDevices,vDescriptions);
|
||||
for( unsigned i=0; i<vDevices.size(); i++ )
|
||||
{
|
||||
InputDevice device = vDevices[i];
|
||||
CString sDescription = vDescriptions[i];
|
||||
for( unsigned j=0; j<NUM_AUTO_JOY_MAPPINGS; j++ )
|
||||
{
|
||||
const AutoJoyMapping& mapping = g_AutoJoyMappings[j];
|
||||
|
||||
if( sDescription == mapping.sDeviceDescription )
|
||||
{
|
||||
PREFSMAN->m_bIgnoreJoyAxes |= mapping.bIgnoreAxes;
|
||||
|
||||
GameController gc = GAME_CONTROLLER_INVALID;
|
||||
switch( device )
|
||||
{
|
||||
case DEVICE_JOY1:
|
||||
case DEVICE_JOY3:
|
||||
case DEVICE_PUMP1:
|
||||
gc = GAME_CONTROLLER_1;
|
||||
break;
|
||||
case DEVICE_JOY2:
|
||||
case DEVICE_JOY4:
|
||||
case DEVICE_PUMP2:
|
||||
gc = GAME_CONTROLLER_2;
|
||||
break;
|
||||
}
|
||||
if( gc == GAME_CONTROLLER_INVALID )
|
||||
continue;
|
||||
|
||||
for( unsigned k=0; k<mapping.numMappings; k++ )
|
||||
{
|
||||
DeviceInput di( device, mapping.mapping[k].deviceButton );
|
||||
GameInput gi( gc, mapping.mapping[k].gb );
|
||||
SetInputMap( di, gi, 1 );
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void InputMapper::ReadMappingsFromDisk()
|
||||
{
|
||||
ASSERT( GAMEMAN != NULL );
|
||||
|
||||
@@ -40,6 +40,7 @@ public:
|
||||
void ClearFromInputMap( GameInput GameI, int iSlotIndex );
|
||||
|
||||
void AddDefaultMappingsForCurrentGameIfUnmapped();
|
||||
void AutoMapJoysticksForCurrentGame();
|
||||
|
||||
bool IsMapped( DeviceInput DeviceI );
|
||||
bool IsMapped( GameInput GameI );
|
||||
|
||||
@@ -96,6 +96,7 @@ PrefsManager::PrefsManager()
|
||||
m_fDancePointsAccumulated = 0;
|
||||
m_bUseUnlockSystem = false;
|
||||
m_bFirstRun = true;
|
||||
m_bAutoMapJoysticks = true;
|
||||
|
||||
/* DDR Extreme-style extra stage support.
|
||||
* Default off so people used to the current behavior (or those with extra
|
||||
@@ -205,6 +206,7 @@ void PrefsManager::ReadGlobalPrefsFromDisk( bool bSwitchToLastPlayedGame )
|
||||
ini.GetValueF( "Options", "DancePointsAccumulated", m_fDancePointsAccumulated );
|
||||
ini.GetValueB( "Options", "UseUnlockSystem", m_bUseUnlockSystem );
|
||||
ini.GetValueB( "Options", "FirstRun", m_bFirstRun );
|
||||
ini.GetValueB( "Options", "AutoMapJoysticks", m_bAutoMapJoysticks );
|
||||
|
||||
m_asAdditionalSongFolders.clear();
|
||||
CString sAdditionalSongFolders;
|
||||
@@ -291,6 +293,7 @@ void PrefsManager::SaveGlobalPrefsToDisk()
|
||||
ini.SetValueF( "Options", "DancePointsAccumulated", m_fDancePointsAccumulated );
|
||||
ini.SetValueB( "Options", "UseUnlockSystem", m_bUseUnlockSystem );
|
||||
ini.SetValueB( "Options", "FirstRun", m_bFirstRun );
|
||||
ini.SetValueB( "Options", "AutoMapJoysticks", m_bAutoMapJoysticks );
|
||||
|
||||
|
||||
/* Only write these if they aren't the default. This ensures that we can change
|
||||
|
||||
@@ -79,6 +79,7 @@ public:
|
||||
float m_fDancePointsAccumulated;
|
||||
bool m_bUseUnlockSystem;
|
||||
bool m_bFirstRun;
|
||||
bool m_bAutoMapJoysticks;
|
||||
|
||||
/* 0 = no; 1 = yes; -1 = auto (do whatever is appropriate for the arch). */
|
||||
int m_iBoostAppPriority;
|
||||
|
||||
@@ -44,3 +44,8 @@ void RageInput::Update( float fDeltaTime )
|
||||
Devices[i]->Update(fDeltaTime);
|
||||
}
|
||||
|
||||
void RageInput::GetDevicesAndDescriptions(vector<InputDevice>& vDevicesOut, vector<CString>& vDescriptionsOut)
|
||||
{
|
||||
for(unsigned i = 0; i < Devices.size(); ++i)
|
||||
Devices[i]->GetDevicesAndDescriptions( vDevicesOut, vDescriptionsOut );
|
||||
}
|
||||
|
||||
@@ -21,6 +21,7 @@ public:
|
||||
~RageInput();
|
||||
|
||||
void Update( float fDeltaTime );
|
||||
void GetDevicesAndDescriptions(vector<InputDevice>& vDevicesOut, vector<CString>& vDescriptionsOut);
|
||||
};
|
||||
|
||||
extern RageInput* INPUTMAN; // global and accessable from anywhere in our program
|
||||
|
||||
@@ -24,7 +24,8 @@
|
||||
|
||||
|
||||
enum {
|
||||
IO_IGNORE_AXES = 0,
|
||||
IO_AUTO_MAP_JOYSTICKS = 0,
|
||||
IO_IGNORE_AXES,
|
||||
IO_DEDICATED_MENU_BUTTONS,
|
||||
IO_AUTOPLAY,
|
||||
IO_DELAYED_ESCAPE,
|
||||
@@ -36,6 +37,7 @@ enum {
|
||||
/* Hmm. Ignore JoyAxes and Back Delayed probably belong in "key/joy config",
|
||||
* preferably alongside button configuration. */
|
||||
OptionRow g_InputOptionsLines[NUM_INPUT_OPTIONS_LINES] = {
|
||||
OptionRow( "Auto Map\nJoysticks", "OFF","ON (recommended)" ),
|
||||
OptionRow( "Ignore\nJoy Axes", "OFF","ON (for NTPad or DirectPad)" ),
|
||||
OptionRow( "Menu\nButtons", "USE GAMEPLAY BUTTONS","ONLY DEDICATED BUTTONS" ),
|
||||
OptionRow( "AutoPlay", "OFF","ON" ),
|
||||
@@ -61,6 +63,7 @@ ScreenInputOptions::ScreenInputOptions() :
|
||||
|
||||
void ScreenInputOptions::ImportOptions()
|
||||
{
|
||||
m_iSelectedOption[0][IO_AUTO_MAP_JOYSTICKS] = PREFSMAN->m_bAutoMapJoysticks ? 1:0;
|
||||
m_iSelectedOption[0][IO_IGNORE_AXES] = PREFSMAN->m_bIgnoreJoyAxes ? 1:0;
|
||||
m_iSelectedOption[0][IO_DEDICATED_MENU_BUTTONS] = PREFSMAN->m_bOnlyDedicatedMenuButtons ? 1:0;
|
||||
m_iSelectedOption[0][IO_AUTOPLAY] = PREFSMAN->m_bAutoPlay;
|
||||
@@ -74,6 +77,7 @@ void ScreenInputOptions::ImportOptions()
|
||||
|
||||
void ScreenInputOptions::ExportOptions()
|
||||
{
|
||||
PREFSMAN->m_bAutoMapJoysticks = m_iSelectedOption[0][IO_AUTO_MAP_JOYSTICKS] == 1;
|
||||
PREFSMAN->m_bIgnoreJoyAxes = m_iSelectedOption[0][IO_IGNORE_AXES] == 1;
|
||||
PREFSMAN->m_bOnlyDedicatedMenuButtons= m_iSelectedOption[0][IO_DEDICATED_MENU_BUTTONS] == 1;
|
||||
PREFSMAN->m_bDelayedEscape = m_iSelectedOption[0][IO_DELAYED_ESCAPE] == 1;
|
||||
|
||||
@@ -153,6 +153,9 @@ void ResetGame()
|
||||
else
|
||||
SCREENMAN->SetNewScreen( THEME->GetMetric("Common","InitialScreen") );
|
||||
PREFSMAN->m_bFirstRun = false;
|
||||
|
||||
if( PREFSMAN->m_bAutoMapJoysticks )
|
||||
INPUTMAPPER->AutoMapJoysticksForCurrentGame();
|
||||
}
|
||||
|
||||
static void GameLoop();
|
||||
@@ -402,7 +405,6 @@ int main(int argc, char* argv[])
|
||||
SONGINDEX = new SongCacheIndex;
|
||||
/* depends on SONGINDEX: */
|
||||
SONGMAN = new SongManager( loading_window ); // this takes a long time to load
|
||||
|
||||
delete loading_window; // destroy this before init'ing Display
|
||||
|
||||
PREFSMAN->ReadGlobalPrefsFromDisk( true );
|
||||
|
||||
@@ -64,7 +64,7 @@ IntDir=.\../Debug6
|
||||
TargetDir=\stepmania\stepmania
|
||||
TargetName=StepMania-debug
|
||||
SOURCE="$(InputPath)"
|
||||
PreLink_Cmds=disasm\verinc cl /Zl /nologo /c verstub.cpp /Fo$(IntDir)\
|
||||
PreLink_Cmds=disasm\verinc cl /Zl /nologo /c verstub.cpp /Fo$(IntDir)\
|
||||
PostBuild_Cmds=disasm\mapconv $(IntDir)\$(TargetName).map $(TargetDir)\StepMania.vdi ia32.vdi
|
||||
# End Special Build Tool
|
||||
|
||||
@@ -104,7 +104,7 @@ IntDir=.\StepMania___Xbox_Debug___VC6
|
||||
TargetDir=.\StepMania___Xbox_Debug___VC6
|
||||
TargetName=StepMania
|
||||
SOURCE="$(InputPath)"
|
||||
PreLink_Cmds=disasm\verinc cl /Zl /nologo /c verstub.cpp /Fo$(IntDir)\
|
||||
PreLink_Cmds=disasm\verinc cl /Zl /nologo /c verstub.cpp /Fo$(IntDir)\
|
||||
PostBuild_Cmds=disasm\mapconv $(IntDir)\$(TargetName).map $(TargetDir)\StepMania.vdi ia32.vdi
|
||||
# End Special Build Tool
|
||||
|
||||
@@ -144,7 +144,7 @@ IntDir=.\../Release6
|
||||
TargetDir=\stepmania\stepmania
|
||||
TargetName=StepMania
|
||||
SOURCE="$(InputPath)"
|
||||
PreLink_Cmds=disasm\verinc cl /Zl /nologo /c verstub.cpp /Fo$(IntDir)\
|
||||
PreLink_Cmds=disasm\verinc cl /Zl /nologo /c verstub.cpp /Fo$(IntDir)\
|
||||
PostBuild_Cmds=disasm\mapconv $(IntDir)\$(TargetName).map $(TargetDir)\StepMania.vdi ia32.vdi
|
||||
# End Special Build Tool
|
||||
|
||||
@@ -336,6 +336,10 @@ SOURCE=.\RageInput.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\RageInput.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\RageInputDevice.cpp
|
||||
|
||||
!IF "$(CFG)" == "StepMania - Win32 Debug"
|
||||
|
||||
@@ -31,9 +31,9 @@
|
||||
RuntimeLibrary="2"
|
||||
UsePrecompiledHeader="2"
|
||||
PrecompiledHeaderFile="$(IntDir)/StepMania.pch"
|
||||
AssemblerListingLocation=".\../Debug_OGL/"
|
||||
ObjectFile=".\../Debug_OGL/"
|
||||
ProgramDataBaseFileName=".\../Debug_OGL/"
|
||||
AssemblerListingLocation=".\../Debug/"
|
||||
ObjectFile=".\../Debug/"
|
||||
ProgramDataBaseFileName=".\../Debug/"
|
||||
BrowseInformation="0"
|
||||
WarningLevel="4"
|
||||
SuppressStartupBanner="TRUE"
|
||||
@@ -110,9 +110,9 @@ cl /Zl /nologo /c verstub.cpp /Fo"$(IntDir)"\
|
||||
UsePrecompiledHeader="2"
|
||||
PrecompiledHeaderThrough="global.h"
|
||||
PrecompiledHeaderFile="$(IntDir)/StepMania.pch"
|
||||
AssemblerListingLocation=".\../Release_OGL/"
|
||||
ObjectFile=".\../Release_OGL/"
|
||||
ProgramDataBaseFileName=".\../Release_OGL/"
|
||||
AssemblerListingLocation=".\../Release/"
|
||||
ObjectFile=".\../Release/"
|
||||
ProgramDataBaseFileName=".\../Release/"
|
||||
BrowseInformation="1"
|
||||
WarningLevel="4"
|
||||
SuppressStartupBanner="TRUE"
|
||||
|
||||
@@ -22,12 +22,14 @@
|
||||
* input for the same device; we have no method to allocate device numbers.
|
||||
* We don't need this now; I'll write it if it becomes needed.)
|
||||
*/
|
||||
#include "RageInputDevice.h" // for InputDevice
|
||||
|
||||
class InputHandler
|
||||
{
|
||||
public:
|
||||
virtual void Update(float fDeltaTime) { }
|
||||
virtual ~InputHandler() { }
|
||||
virtual void GetDevicesAndDescriptions(vector<InputDevice>& vDevicesOut, vector<CString>& vDescriptionsOut) = 0;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
@@ -132,6 +132,22 @@ void InputHandler_SDL::Update(float fDeltaTime)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void InputHandler_SDL::GetDevicesAndDescriptions(vector<InputDevice>& vDevicesOut, vector<CString>& vDescriptionsOut)
|
||||
{
|
||||
vDevicesOut.push_back( DEVICE_KEYBOARD );
|
||||
vDescriptionsOut.push_back( "Keyboard" );
|
||||
|
||||
for( int i=0; i<SDL_NumJoysticks(); i++ )
|
||||
{
|
||||
if( SDL_JoystickOpened(i) )
|
||||
{
|
||||
vDevicesOut.push_back( InputDevice(DEVICE_JOY1+i) );
|
||||
vDescriptionsOut.push_back( SDL_JoystickName(i) );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
-----------------------------------------------------------------------------
|
||||
Copyright (c) 2001-2003 by the person(s) listed below. All rights reserved.
|
||||
|
||||
@@ -14,6 +14,7 @@ public:
|
||||
void Update(float fDeltaTime);
|
||||
InputHandler_SDL();
|
||||
~InputHandler_SDL();
|
||||
void GetDevicesAndDescriptions(vector<InputDevice>& vDevicesOut, vector<CString>& vDescriptionsOut);
|
||||
};
|
||||
|
||||
|
||||
|
||||
@@ -46,6 +46,18 @@ void InputHandler_Win32_Pump::Update(float fDeltaTime)
|
||||
}
|
||||
}
|
||||
|
||||
void InputHandler_Win32_Pump::GetDevicesAndDescriptions(vector<InputDevice>& vDevicesOut, vector<CString>& vDescriptionsOut)
|
||||
{
|
||||
for(int i = 0; i < NUM_PUMPS; ++i)
|
||||
{
|
||||
if( dev[i].IsOpen() )
|
||||
{
|
||||
vDevicesOut.push_back( InputDevice(DEVICE_PUMP1+i) );
|
||||
vDescriptionsOut.push_back( "Pump USB" );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
-----------------------------------------------------------------------------
|
||||
Copyright (c) 2002-2003 by the person(s) listed below. All rights reserved.
|
||||
|
||||
@@ -12,6 +12,7 @@ public:
|
||||
void Update(float fDeltaTime);
|
||||
InputHandler_Win32_Pump();
|
||||
~InputHandler_Win32_Pump();
|
||||
void GetDevicesAndDescriptions(vector<InputDevice>& vDevicesOut, vector<CString>& vDescriptionsOut);
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
@@ -108,6 +108,11 @@ bool USBDevice::Open(int VID, int PID, int num)
|
||||
return h != INVALID_HANDLE_VALUE;
|
||||
}
|
||||
|
||||
bool USBDevice::IsOpen()
|
||||
{
|
||||
return h != INVALID_HANDLE_VALUE;
|
||||
}
|
||||
|
||||
int USBDevice::GetPadEvent()
|
||||
{
|
||||
if(h == INVALID_HANDLE_VALUE)
|
||||
|
||||
@@ -8,6 +8,7 @@ public:
|
||||
~USBDevice();
|
||||
int GetPadEvent();
|
||||
bool Open(int VID, int PID, int num);
|
||||
bool IsOpen();
|
||||
|
||||
private:
|
||||
HANDLE h;
|
||||
|
||||
Reference in New Issue
Block a user