diff --git a/Docs/Changelog_sm5.txt b/Docs/Changelog_sm5.txt index ba856b65f0..0a05fc5040 100644 --- a/Docs/Changelog_sm5.txt +++ b/Docs/Changelog_sm5.txt @@ -8,6 +8,11 @@ ________________________________________________________________________________ StepMania 5.0 ???? ?? | 20120??? -------------------------------------------------------------------------------- +2012/07/09 +---------- +* [InputMapper] Use "|" for separating entries instead of ",", since some + companies have names like "x Ltd., something". [Mordae, AJ] + 2012/07/06 ---------- * [ScoreDisplayRave] Add FrameBase and FrameOver to the metrics. [AJ] diff --git a/src/InputMapper.cpp b/src/InputMapper.cpp index 1b0a71e77c..1d80e36669 100644 --- a/src/InputMapper.cpp +++ b/src/InputMapper.cpp @@ -1,1213 +1,1216 @@ -#include "global.h" -#include "InputMapper.h" -#include "IniFile.h" -#include "MessageManager.h" -#include "RageLog.h" -#include "InputFilter.h" -#include "RageUtil.h" -#include "PrefsManager.h" -#include "RageInput.h" -#include "SpecialFiles.h" -#include "LocalizedString.h" -#include "Foreach.h" -#include "arch/Dialog/Dialog.h" - -#define AUTOMAPPINGS_DIR "/Data/AutoMappings/" - -static Preference g_sLastSeenInputDevices( "LastSeenInputDevices", "" ); -static Preference g_bAutoMapOnJoyChange( "AutoMapOnJoyChange", true ); - -namespace -{ - // lookup for efficiency from a DeviceInput to a GameInput - // This is repopulated every time m_PItoDI changes by calling UpdateTempDItoPI(). - map g_tempDItoGI; - - PlayerNumber g_JoinControllers; -}; - -InputMapper* INPUTMAPPER = NULL; // global and accessable from anywhere in our program - -InputMapper::InputMapper() -{ - g_JoinControllers = PLAYER_INVALID; - m_pInputScheme = NULL; -} - -InputMapper::~InputMapper() -{ - SaveMappingsToDisk(); - g_tempDItoGI.clear(); -} - -void InputMapper::ClearAllMappings() -{ - m_mappings.Clear(); - - UpdateTempDItoGI(); -} - -static const AutoMappings g_DefaultKeyMappings = AutoMappings( - "", - "", - "", - AutoMappingEntry( 0, KEY_LEFT, GAME_BUTTON_MENULEFT, false ), - AutoMappingEntry( 0, KEY_RIGHT, GAME_BUTTON_MENURIGHT, false ), - AutoMappingEntry( 0, KEY_UP, GAME_BUTTON_MENUUP, false ), - AutoMappingEntry( 0, KEY_DOWN, GAME_BUTTON_MENUDOWN, false ), - AutoMappingEntry( 0, KEY_ENTER, GAME_BUTTON_START, false ), - AutoMappingEntry( 0, KEY_SLASH, GAME_BUTTON_SELECT, false ), - AutoMappingEntry( 0, KEY_ESC, GAME_BUTTON_BACK, false ), - AutoMappingEntry( 0, KEY_KP_C4, GAME_BUTTON_MENULEFT, true ), - AutoMappingEntry( 0, KEY_KP_C6, GAME_BUTTON_MENURIGHT, true ), - AutoMappingEntry( 0, KEY_KP_C8, GAME_BUTTON_MENUUP, true ), - AutoMappingEntry( 0, KEY_KP_C2, GAME_BUTTON_MENUDOWN, true ), - AutoMappingEntry( 0, KEY_KP_ENTER, GAME_BUTTON_START, true ), - AutoMappingEntry( 0, KEY_KP_C0, GAME_BUTTON_SELECT, true ), - AutoMappingEntry( 0, KEY_HYPHEN, GAME_BUTTON_BACK, true ), // laptop keyboards. - AutoMappingEntry( 0, KEY_F1, GAME_BUTTON_COIN, false ), - AutoMappingEntry( 0, KEY_SCRLLOCK, GAME_BUTTON_OPERATOR, false ) -); - -void InputMapper::AddDefaultMappingsForCurrentGameIfUnmapped() -{ - // Clear default mappings. Default mappings are in the third slot. - FOREACH_ENUM( GameController, i ) - FOREACH_ENUM( GameButton, j) - ClearFromInputMap( GameInput(i, j), 2 ); - - vector aMaps; - aMaps.reserve( 32 ); - - FOREACH_CONST( AutoMappingEntry, g_DefaultKeyMappings.m_vMaps, iter ) - aMaps.push_back( *iter ); - FOREACH_CONST( AutoMappingEntry, m_pInputScheme->m_pAutoMappings->m_vMaps, iter ) - aMaps.push_back( *iter ); - - /* There may be duplicate GAME_BUTTON maps. Process the list backwards, - * so game-specific mappings override g_DefaultKeyMappings. */ - std::reverse( aMaps.begin(), aMaps.end() ); - - FOREACH( AutoMappingEntry, aMaps, m ) - { - DeviceButton key = m->m_deviceButton; - DeviceInput DeviceI( DEVICE_KEYBOARD, key ); - GameInput GameI( m->m_bSecondController ? GameController_2 : GameController_1, m->m_gb ); - if( !IsMapped(DeviceI) ) // if this key isn't already being used by another user-made mapping - { - if( !GameI.IsValid() ) - ClearFromInputMap( DeviceI ); - else - SetInputMap( DeviceI, GameI, 2 ); - } - } -} - -static const AutoMappings g_AutoMappings[] = -{ - AutoMappings( - "dance", - "GIC USB Joystick", - "Boom USB convertor (black/gray)", - AutoMappingEntry( 0, JOY_BUTTON_16, DANCE_BUTTON_LEFT, false ), - AutoMappingEntry( 0, JOY_BUTTON_14, DANCE_BUTTON_RIGHT, false ), - AutoMappingEntry( 0, JOY_BUTTON_13, DANCE_BUTTON_UP, false ), - AutoMappingEntry( 0, JOY_BUTTON_15, DANCE_BUTTON_DOWN, false ), - AutoMappingEntry( 1, JOY_BUTTON_4, DANCE_BUTTON_LEFT, false ), - AutoMappingEntry( 1, JOY_BUTTON_2, DANCE_BUTTON_RIGHT, false ), - AutoMappingEntry( 1, JOY_BUTTON_1, DANCE_BUTTON_UP, false ), - AutoMappingEntry( 1, JOY_BUTTON_3, DANCE_BUTTON_DOWN, false ), - AutoMappingEntry( 0, JOY_BUTTON_7, DANCE_BUTTON_UPLEFT, false ), - AutoMappingEntry( 0, JOY_BUTTON_8, DANCE_BUTTON_UPRIGHT, false ), - AutoMappingEntry( 0, JOY_BUTTON_9, GAME_BUTTON_BACK, false ), - AutoMappingEntry( 0, JOY_BUTTON_12, GAME_BUTTON_START, false ) - ), - AutoMappings( - "dance", - "4 axis 16 button joystick", - "EMS USB2", - AutoMappingEntry( 0, JOY_BUTTON_16, DANCE_BUTTON_LEFT, false ), - AutoMappingEntry( 0, JOY_BUTTON_14, DANCE_BUTTON_RIGHT, false ), - AutoMappingEntry( 0, JOY_BUTTON_13, DANCE_BUTTON_UP, false ), - AutoMappingEntry( 0, JOY_BUTTON_15, DANCE_BUTTON_DOWN, false ), - AutoMappingEntry( 1, JOY_BUTTON_4, DANCE_BUTTON_LEFT, false ), - AutoMappingEntry( 1, JOY_BUTTON_2, DANCE_BUTTON_RIGHT, false ), - AutoMappingEntry( 1, JOY_BUTTON_1, DANCE_BUTTON_UP, false ), - AutoMappingEntry( 1, JOY_BUTTON_3, DANCE_BUTTON_DOWN, false ), - AutoMappingEntry( 0, JOY_BUTTON_7, DANCE_BUTTON_UPLEFT, false ), - AutoMappingEntry( 0, JOY_BUTTON_8, DANCE_BUTTON_UPRIGHT, false ), - AutoMappingEntry( 0, JOY_BUTTON_9, GAME_BUTTON_BACK, false ), - AutoMappingEntry( 0, JOY_BUTTON_10, GAME_BUTTON_START, false ) - ), - AutoMappings( - "dance", - "GamePad Pro USB ", // yes, there is a space at the end - "GamePad Pro USB", - AutoMappingEntry( 0, JOY_LEFT, DANCE_BUTTON_LEFT, false ), - AutoMappingEntry( 0, JOY_RIGHT, DANCE_BUTTON_RIGHT, false ), - AutoMappingEntry( 0, JOY_UP, DANCE_BUTTON_UP, false ), - AutoMappingEntry( 0, JOY_DOWN, DANCE_BUTTON_DOWN, false ), - AutoMappingEntry( 1, JOY_BUTTON_1, DANCE_BUTTON_LEFT, false ), - AutoMappingEntry( 1, JOY_BUTTON_3, DANCE_BUTTON_RIGHT, false ), - AutoMappingEntry( 1, JOY_BUTTON_4, DANCE_BUTTON_UP, false ), - AutoMappingEntry( 1, JOY_BUTTON_2, DANCE_BUTTON_DOWN, false ), - AutoMappingEntry( 0, JOY_BUTTON_5, DANCE_BUTTON_UPLEFT, false ), - AutoMappingEntry( 0, JOY_BUTTON_6, DANCE_BUTTON_UPRIGHT, false ), - AutoMappingEntry( 0, JOY_BUTTON_9, GAME_BUTTON_BACK, false ), - AutoMappingEntry( 0, JOY_BUTTON_10, GAME_BUTTON_START, false ) - ), - AutoMappings( - "dance", - "SideWinder Game Pad USB version 1.0", - "SideWinder Game Pad USB", - AutoMappingEntry( 0, JOY_LEFT, DANCE_BUTTON_LEFT, false ), - AutoMappingEntry( 0, JOY_RIGHT, DANCE_BUTTON_RIGHT, false ), - AutoMappingEntry( 0, JOY_UP, DANCE_BUTTON_UP, false ), - AutoMappingEntry( 0, JOY_DOWN, DANCE_BUTTON_DOWN, false ), - AutoMappingEntry( 1, JOY_BUTTON_4, DANCE_BUTTON_LEFT, false ), - AutoMappingEntry( 1, JOY_BUTTON_2, DANCE_BUTTON_RIGHT, false ), - AutoMappingEntry( 1, JOY_BUTTON_5, DANCE_BUTTON_UP, false ), - AutoMappingEntry( 1, JOY_BUTTON_1, DANCE_BUTTON_DOWN, false ), - AutoMappingEntry( 0, JOY_BUTTON_7, DANCE_BUTTON_UPLEFT, false ), - AutoMappingEntry( 0, JOY_BUTTON_8, DANCE_BUTTON_UPRIGHT, false ), - AutoMappingEntry( 0, JOY_BUTTON_9, GAME_BUTTON_BACK, false ), - AutoMappingEntry( 0, JOY_BUTTON_10, GAME_BUTTON_START, false ) - ), - AutoMappings( - "dance", - "4 axis 12 button joystick with hat switch", - "Super Joy Box 5", - AutoMappingEntry( 0, JOY_LEFT, DANCE_BUTTON_LEFT, false ), - AutoMappingEntry( 0, JOY_RIGHT, DANCE_BUTTON_RIGHT, false ), - AutoMappingEntry( 0, JOY_UP, DANCE_BUTTON_UP, false ), - AutoMappingEntry( 0, JOY_DOWN, DANCE_BUTTON_DOWN, false ), - AutoMappingEntry( 1, JOY_BUTTON_4, DANCE_BUTTON_LEFT, false ), - AutoMappingEntry( 1, JOY_BUTTON_2, DANCE_BUTTON_RIGHT, false ), - AutoMappingEntry( 1, JOY_BUTTON_1, DANCE_BUTTON_UP, false ), - AutoMappingEntry( 1, JOY_BUTTON_3, DANCE_BUTTON_DOWN, false ), - AutoMappingEntry( 0, JOY_BUTTON_7, DANCE_BUTTON_UPLEFT, false ), - AutoMappingEntry( 0, JOY_BUTTON_8, DANCE_BUTTON_UPRIGHT, false ), - AutoMappingEntry( 0, JOY_BUTTON_10, GAME_BUTTON_BACK, false ), - AutoMappingEntry( 0, JOY_BUTTON_9, GAME_BUTTON_START, false ) - ), -/* AutoMappings( - - "dance", - "MP-8866 Dual USB Joypad", - "Super Dual Box (from Lik-Sang, 2004)", - //NEEDS_DANCE_PAD_MAPPING_CODE, - AutoMappingEntry( 0, JOY_LEFT, DANCE_BUTTON_LEFT, false ), - AutoMappingEntry( 0, JOY_RIGHT, DANCE_BUTTON_RIGHT, false ), - AutoMappingEntry( 0, JOY_UP, DANCE_BUTTON_UP, false ), - AutoMappingEntry( 0, JOY_DOWN, DANCE_BUTTON_DOWN, false ), - AutoMappingEntry( 1, JOY_BUTTON_4, DANCE_BUTTON_LEFT, false ), - AutoMappingEntry( 1, JOY_BUTTON_2, DANCE_BUTTON_RIGHT, false ), - AutoMappingEntry( 1, JOY_BUTTON_1, DANCE_BUTTON_UP, false ), - AutoMappingEntry( 1, JOY_BUTTON_3, DANCE_BUTTON_DOWN, false ), - AutoMappingEntry( 0, JOY_BUTTON_5, DANCE_BUTTON_UPLEFT, false ), - AutoMappingEntry( 0, JOY_BUTTON_6, DANCE_BUTTON_UPRIGHT, false ), - AutoMappingEntry( 1, JOY_BUTTON_7, DANCE_BUTTON_UPLEFT, false ), - AutoMappingEntry( 1, JOY_BUTTON_8, DANCE_BUTTON_UPRIGHT, false ), - AutoMappingEntry( 0, JOY_BUTTON_10, GAME_BUTTON_BACK, false ), - AutoMappingEntry( 0, JOY_BUTTON_9, GAME_BUTTON_START, false ), - ), -*/ - AutoMappings( - "dance", - "MP-8866 Dual USB Joypad", - "Super Dual Box (from DDRGame.com, Feb 2008)", - //NEEDS_DANCE_PAD_MAPPING_CODE, - AutoMappingEntry( 0, JOY_BUTTON_3, DANCE_BUTTON_UP, false ), - AutoMappingEntry( 0, JOY_BUTTON_2, DANCE_BUTTON_DOWN, false ), - AutoMappingEntry( 0, JOY_BUTTON_1, DANCE_BUTTON_LEFT, false ), - AutoMappingEntry( 0, JOY_BUTTON_4, DANCE_BUTTON_RIGHT, false ), - AutoMappingEntry( 0, JOY_BUTTON_7, DANCE_BUTTON_UPLEFT, false ), - AutoMappingEntry( 0, JOY_BUTTON_8, DANCE_BUTTON_UPRIGHT, false ), - //AutoMappingEntry{ 0, JOY_BUTTON_5, DANCE_BUTTON_DOWNLEFT, false ), - //AutoMappingEntry{ 0, JOY_BUTTON_6, DANCE_BUTTON_DOWNRIGHT, false ), - AutoMappingEntry( 0, JOY_BUTTON_10, GAME_BUTTON_BACK, false ), - AutoMappingEntry( 0, JOY_BUTTON_9, GAME_BUTTON_START, false ) - ), - AutoMappings( - "dance", - "NTPAD", - "NTPAD", - AutoMappingEntry( 0, JOY_BUTTON_13, DANCE_BUTTON_LEFT, false ), - AutoMappingEntry( 0, JOY_BUTTON_15, DANCE_BUTTON_RIGHT, false ), - AutoMappingEntry( 0, JOY_BUTTON_16, DANCE_BUTTON_UP, false ), - AutoMappingEntry( 0, JOY_BUTTON_14, DANCE_BUTTON_DOWN, false ), - AutoMappingEntry( 1, JOY_BUTTON_1, DANCE_BUTTON_LEFT, false ), - AutoMappingEntry( 1, JOY_BUTTON_3, DANCE_BUTTON_RIGHT, false ), - AutoMappingEntry( 1, JOY_BUTTON_4, DANCE_BUTTON_UP, false ), - AutoMappingEntry( 1, JOY_BUTTON_2, DANCE_BUTTON_DOWN, false ), - AutoMappingEntry( 0, JOY_BUTTON_5, DANCE_BUTTON_UPLEFT, false ), - AutoMappingEntry( 0, JOY_BUTTON_6, DANCE_BUTTON_UPRIGHT, false ), - AutoMappingEntry( 1, JOY_BUTTON_7, DANCE_BUTTON_UPLEFT, false ), - AutoMappingEntry( 1, JOY_BUTTON_8, DANCE_BUTTON_UPRIGHT, false ), - AutoMappingEntry( 0, JOY_BUTTON_9, GAME_BUTTON_BACK, false ), - AutoMappingEntry( 0, JOY_BUTTON_10, GAME_BUTTON_START, false ) - ), - AutoMappings( - "dance", - "Psx Gamepad", - "PSXPAD", - AutoMappingEntry( 0, JOY_LEFT, DANCE_BUTTON_LEFT, false ), - AutoMappingEntry( 0, JOY_RIGHT, DANCE_BUTTON_RIGHT, false ), - AutoMappingEntry( 0, JOY_UP, DANCE_BUTTON_UP, false ), - AutoMappingEntry( 0, JOY_DOWN, DANCE_BUTTON_DOWN, false ), - AutoMappingEntry( 1, JOY_BUTTON_2, DANCE_BUTTON_LEFT, false ), - AutoMappingEntry( 1, JOY_BUTTON_1, DANCE_BUTTON_RIGHT, false ), - AutoMappingEntry( 1, JOY_BUTTON_4, DANCE_BUTTON_UP, false ), - AutoMappingEntry( 1, JOY_BUTTON_3, DANCE_BUTTON_DOWN, false ), - AutoMappingEntry( 0, JOY_BUTTON_7, DANCE_BUTTON_UPLEFT, false ), - AutoMappingEntry( 0, JOY_BUTTON_5, DANCE_BUTTON_UPRIGHT, false ), - AutoMappingEntry( 1, JOY_BUTTON_8, DANCE_BUTTON_UPLEFT, false ), - AutoMappingEntry( 1, JOY_BUTTON_6, DANCE_BUTTON_UPRIGHT, false ), - AutoMappingEntry( 0, JOY_BUTTON_10, GAME_BUTTON_BACK, false ), - AutoMappingEntry( 0, JOY_BUTTON_9, GAME_BUTTON_START, false ) - ), - AutoMappings( - "dance", - "XBOX Gamepad Plugin V0.01", - "X-Box gamepad", - AutoMappingEntry( 0, JOY_LEFT, DANCE_BUTTON_LEFT, false ), - AutoMappingEntry( 0, JOY_RIGHT, DANCE_BUTTON_RIGHT, false ), - AutoMappingEntry( 0, JOY_UP, DANCE_BUTTON_UP, false ), - AutoMappingEntry( 0, JOY_DOWN, DANCE_BUTTON_DOWN, false ), - AutoMappingEntry( 1, JOY_BUTTON_1, DANCE_BUTTON_DOWN, false ), // A - AutoMappingEntry( 1, JOY_BUTTON_2, DANCE_BUTTON_RIGHT, false ), // B - AutoMappingEntry( 1, JOY_BUTTON_3, DANCE_BUTTON_LEFT, false ), // X - AutoMappingEntry( 1, JOY_BUTTON_4, DANCE_BUTTON_UP, false ), // Y - AutoMappingEntry( 0, JOY_BUTTON_7, DANCE_BUTTON_UPLEFT, false ), // L shoulder - AutoMappingEntry( 0, JOY_BUTTON_8, DANCE_BUTTON_UPRIGHT, false ), // R shoulder - AutoMappingEntry( 0, JOY_BUTTON_9, GAME_BUTTON_START, false ), - AutoMappingEntry( 0, JOY_BUTTON_10, GAME_BUTTON_BACK, false ) - ), - AutoMappings( - "dance", - "0b43:0003", // The EMS USB2 doesn't provide a model string, so Linux - // just gives us the VendorID and ModelID in hex. - "EMS USB2", - // Player 1. - AutoMappingEntry( 0, JOY_BUTTON_16, DANCE_BUTTON_LEFT, false ), - AutoMappingEntry( 0, JOY_BUTTON_14, DANCE_BUTTON_RIGHT, false ), - AutoMappingEntry( 0, JOY_BUTTON_13, DANCE_BUTTON_UP, false ), - AutoMappingEntry( 0, JOY_BUTTON_15, DANCE_BUTTON_DOWN, false ), - AutoMappingEntry( 1, JOY_BUTTON_4, DANCE_BUTTON_LEFT, false ), - AutoMappingEntry( 1, JOY_BUTTON_2, DANCE_BUTTON_RIGHT, false ), - AutoMappingEntry( 1, JOY_BUTTON_1, DANCE_BUTTON_UP, false ), - AutoMappingEntry( 1, JOY_BUTTON_3, DANCE_BUTTON_DOWN, false ), - AutoMappingEntry( 0, JOY_BUTTON_7, DANCE_BUTTON_UPLEFT, false ), - AutoMappingEntry( 0, JOY_BUTTON_8, DANCE_BUTTON_UPRIGHT, false ), - AutoMappingEntry( 0, JOY_BUTTON_9, GAME_BUTTON_SELECT, false ), - AutoMappingEntry( 0, JOY_BUTTON_10, GAME_BUTTON_START, false ), - AutoMappingEntry( 0, JOY_BUTTON_5, GAME_BUTTON_BACK, false ), - AutoMappingEntry( 0, JOY_BUTTON_6, GAME_BUTTON_COIN, false ), - // Player 2. - AutoMappingEntry( 0, JOY_BUTTON_32, DANCE_BUTTON_LEFT, true ), - AutoMappingEntry( 0, JOY_BUTTON_30, DANCE_BUTTON_RIGHT, true ), - AutoMappingEntry( 0, JOY_BUTTON_29, DANCE_BUTTON_UP, true ), - AutoMappingEntry( 0, JOY_BUTTON_31, DANCE_BUTTON_DOWN, true ), - AutoMappingEntry( 1, JOY_BUTTON_20, DANCE_BUTTON_LEFT, true ), - AutoMappingEntry( 1, JOY_BUTTON_18, DANCE_BUTTON_RIGHT, true ), - AutoMappingEntry( 1, JOY_BUTTON_17, DANCE_BUTTON_UP, true ), - AutoMappingEntry( 1, JOY_BUTTON_19, DANCE_BUTTON_DOWN, true ), - AutoMappingEntry( 0, JOY_BUTTON_23, DANCE_BUTTON_UPRIGHT, true ), - AutoMappingEntry( 0, JOY_BUTTON_24, DANCE_BUTTON_UPLEFT, true ), - AutoMappingEntry( 0, JOY_BUTTON_25, GAME_BUTTON_SELECT, true ), - AutoMappingEntry( 0, JOY_BUTTON_26, GAME_BUTTON_START, true ), - AutoMappingEntry( 0, JOY_BUTTON_21, GAME_BUTTON_BACK, true ), - AutoMappingEntry( 0, JOY_BUTTON_22, GAME_BUTTON_COIN, true ) - ), - AutoMappings( - "dance", - "Dance ", //Notice extra space at end - "LevelSix USB Pad (DDR638)", // "DDR638" is the model number of the pad - AutoMappingEntry( 0, JOY_BUTTON_1, DANCE_BUTTON_UP, false ), - AutoMappingEntry( 0, JOY_BUTTON_2, DANCE_BUTTON_DOWN, false ), - AutoMappingEntry( 0, JOY_BUTTON_3, DANCE_BUTTON_LEFT, false ), - AutoMappingEntry( 0, JOY_BUTTON_4, DANCE_BUTTON_RIGHT, false ), - AutoMappingEntry( 0, JOY_BUTTON_7, DANCE_BUTTON_UPRIGHT, false ), - AutoMappingEntry( 0, JOY_BUTTON_8, DANCE_BUTTON_UPLEFT, false ), - AutoMappingEntry( 0, JOY_BUTTON_9, GAME_BUTTON_BACK, false ), - AutoMappingEntry( 0, JOY_BUTTON_10, GAME_BUTTON_START, false ) - ), - AutoMappings( - "dance", - "SmartJoy PLUS Adapter", - "SmartJoy PLUS Adapter", - AutoMappingEntry( 0, JOY_LEFT, /* dpad L */ DANCE_BUTTON_LEFT, false ), - AutoMappingEntry( 0, JOY_RIGHT, /* dpad R */ DANCE_BUTTON_RIGHT, false ), - AutoMappingEntry( 0, JOY_UP, /* dpad U */ DANCE_BUTTON_UP, false ), - AutoMappingEntry( 0, JOY_DOWN, /* dpad D */ DANCE_BUTTON_DOWN, false ), - AutoMappingEntry( 1, JOY_BUTTON_4, /* Square */ DANCE_BUTTON_LEFT, false ), - AutoMappingEntry( 1, JOY_BUTTON_2, /* Circle */ DANCE_BUTTON_RIGHT, false ), - AutoMappingEntry( 1, JOY_BUTTON_1, /* Tri */ DANCE_BUTTON_UP, false ), - AutoMappingEntry( 1, JOY_BUTTON_3, /* X */ DANCE_BUTTON_DOWN, false ), - AutoMappingEntry( 0, JOY_BUTTON_7, /* L1 */ DANCE_BUTTON_UPLEFT, false ), - AutoMappingEntry( 0, JOY_BUTTON_8, /* R1 */ DANCE_BUTTON_UPRIGHT, false ), - AutoMappingEntry( 0, JOY_BUTTON_10, /* Select */ GAME_BUTTON_BACK, false ), - AutoMappingEntry( 0, JOY_BUTTON_9, /* Start */ GAME_BUTTON_START, false ), - AutoMappingEntry( 0, JOY_BUTTON_5, /* R1 */ GAME_BUTTON_SELECT, false ), - AutoMappingEntry( 0, JOY_BUTTON_6, /* R2 */ GAME_BUTTON_COIN, false ) - ), - AutoMappings( - "dance", - "RedOctane USB Pad|XBOX DDR", // "RedOctane USB Pad" is Ignition 3s and newer Afterburners. "XBOX DDR" is older Afterburners. - "RedOctane Ignition 3 or Afterburner", - AutoMappingEntry( 0, JOY_BUTTON_1, /* dpad L */ DANCE_BUTTON_LEFT, false ), - AutoMappingEntry( 0, JOY_BUTTON_4, /* dpad R */ DANCE_BUTTON_RIGHT, false ), - AutoMappingEntry( 0, JOY_BUTTON_3, /* dpad U */ DANCE_BUTTON_UP, false ), - AutoMappingEntry( 0, JOY_BUTTON_2, /* dpad D */ DANCE_BUTTON_DOWN, false ), - //AutoMappingEntry{ 0, JOY_BUTTON_5, /* Tri */ GAME_BUTTON_BACK, false ), - //AutoMappingEntry{ 0, JOY_BUTTON_6, /* Square */ GAME_BUTTON_BACK, false ), - //AutoMappingEntry{ 1, JOY_BUTTON_7, /* X */ GAME_BUTTON_START, false ), - AutoMappingEntry( 0, JOY_BUTTON_8, /* O */ GAME_BUTTON_START, false ), - AutoMappingEntry( 1, JOY_BUTTON_9, /* Start */ GAME_BUTTON_START, false ), - AutoMappingEntry( 0, JOY_BUTTON_10, /* Sel */ GAME_BUTTON_BACK, false ) - ), - AutoMappings( - "dance", - "Joypad to USB converter", - "EMS Trio Linker", - AutoMappingEntry( 0, JOY_BUTTON_16, /* dpad L */ DANCE_BUTTON_LEFT, false ), - AutoMappingEntry( 0, JOY_BUTTON_14, /* dpad R */ DANCE_BUTTON_RIGHT, false ), - AutoMappingEntry( 0, JOY_BUTTON_13, /* dpad U */ DANCE_BUTTON_UP, false ), - AutoMappingEntry( 0, JOY_BUTTON_15, /* dpad D */ DANCE_BUTTON_DOWN, false ), - //AutoMappingEntry{ 0, JOY_BUTTON_5, /* Tri */ GAME_BUTTON_BACK, false ), - //AutoMappingEntry{ 0, JOY_BUTTON_6, /* Square */ GAME_BUTTON_BACK, false ), - //AutoMappingEntry{ 1, JOY_BUTTON_7, /* X */ GAME_BUTTON_START, false ), - AutoMappingEntry( 0, JOY_BUTTON_2, /* O */ GAME_BUTTON_START, false ), - AutoMappingEntry( 1, JOY_BUTTON_10, /* Start */ GAME_BUTTON_START, false ), - AutoMappingEntry( 0, JOY_BUTTON_9, /* Sel */ GAME_BUTTON_BACK, false ) - ), - AutoMappings( - "dance", - "Positive Gaming Impact USB pad", - "Positive Gaming Impact USB pad", - AutoMappingEntry( 0, JOY_BUTTON_1, /* dpad L */ DANCE_BUTTON_LEFT, false ), - AutoMappingEntry( 0, JOY_BUTTON_4, /* dpad R */ DANCE_BUTTON_RIGHT, false ), - AutoMappingEntry( 0, JOY_BUTTON_3, /* dpad U */ DANCE_BUTTON_UP, false ), - AutoMappingEntry( 0, JOY_BUTTON_2, /* dpad D */ DANCE_BUTTON_DOWN, false ), - //AutoMappingEntry{ 0, JOY_BUTTON_5, /* Tri */ GAME_BUTTON_BACK, false ), - //AutoMappingEntry{ 0, JOY_BUTTON_6, /* Square */ GAME_BUTTON_BACK, false ), - AutoMappingEntry( 0, JOY_BUTTON_7, /* X */ DANCE_BUTTON_UPLEFT, false ), - AutoMappingEntry( 0, JOY_BUTTON_8, /* O */ DANCE_BUTTON_UPRIGHT, false ), - AutoMappingEntry( 1, JOY_BUTTON_9, /* Start */ GAME_BUTTON_START, false ), - AutoMappingEntry( 0, JOY_BUTTON_10, /* Sel */ GAME_BUTTON_BACK, false ) - ), - AutoMappings( - "dance", - "USB Dance Pad", - "DDRGame Energy Dance Pad", - AutoMappingEntry( 0, JOY_BUTTON_13, DANCE_BUTTON_UP, false ), - AutoMappingEntry( 0, JOY_BUTTON_15, DANCE_BUTTON_DOWN, false ), - AutoMappingEntry( 0, JOY_BUTTON_16, DANCE_BUTTON_LEFT, false ), - AutoMappingEntry( 0, JOY_BUTTON_14, DANCE_BUTTON_RIGHT, false ), - AutoMappingEntry( 0, JOY_BUTTON_3, DANCE_BUTTON_UPLEFT, false ), - AutoMappingEntry( 0, JOY_BUTTON_2, DANCE_BUTTON_UPRIGHT, false ), - //AutoMappingEntry{ 0, JOY_BUTTON_1, DANCE_BUTTON_DOWNLEFT, false ), - //AutoMappingEntry{ 0, JOY_BUTTON_4, DANCE_BUTTON_DOWNRIGHT, false ), - AutoMappingEntry( 0, JOY_BUTTON_9, GAME_BUTTON_BACK, false ), - AutoMappingEntry( 0, JOY_BUTTON_10, GAME_BUTTON_START, false ) - ), - AutoMappings( - "dance", - "Dual USB Vibration Joystick", - "PC Multi Hub Double Power Box 4", - AutoMappingEntry( 0, JOY_BUTTON_13, DANCE_BUTTON_UP, false ), - AutoMappingEntry( 0, JOY_BUTTON_15, DANCE_BUTTON_DOWN, false ), - AutoMappingEntry( 0, JOY_BUTTON_16, DANCE_BUTTON_LEFT, false ), - AutoMappingEntry( 0, JOY_BUTTON_14, DANCE_BUTTON_RIGHT, false ), - AutoMappingEntry( 0, JOY_BUTTON_3, DANCE_BUTTON_UPLEFT, false ), - AutoMappingEntry( 0, JOY_BUTTON_2, DANCE_BUTTON_UPRIGHT, false ), - //AutoMappingEntry{ 0, JOY_BUTTON_1, DANCE_BUTTON_DOWNLEFT, false ), - //AutoMappingEntry{ 0, JOY_BUTTON_4, DANCE_BUTTON_DOWNRIGHT, false ), - AutoMappingEntry( 0, JOY_BUTTON_9, GAME_BUTTON_BACK, false ), - AutoMappingEntry( 0, JOY_BUTTON_10, GAME_BUTTON_START, false ) - ), - AutoMappings( - "dance", - "Controller \\(Harmonix Drum Kit for Xbox 360\\)", - "Rock Band drum controller (Xbox 360, Windows driver)", - AutoMappingEntry( 0, JOY_BUTTON_3, DANCE_BUTTON_UP, false ), // blue drum - AutoMappingEntry( 0, JOY_BUTTON_4, DANCE_BUTTON_DOWN, false ), // yellow drum - AutoMappingEntry( 0, JOY_BUTTON_2, DANCE_BUTTON_LEFT, false ), // red drum - AutoMappingEntry( 0, JOY_BUTTON_1, DANCE_BUTTON_RIGHT, false ), // green drum - AutoMappingEntry( 0, JOY_HAT_LEFT, GAME_BUTTON_MENULEFT, false ), // d-pad left - AutoMappingEntry( 0, JOY_HAT_RIGHT, GAME_BUTTON_MENURIGHT, false ), // d-pad right - AutoMappingEntry( 0, JOY_HAT_UP, GAME_BUTTON_MENUUP, false ), // d-pad up - AutoMappingEntry( 0, JOY_HAT_DOWN, GAME_BUTTON_MENUDOWN, false ), // d-pad down - AutoMappingEntry( 0, JOY_BUTTON_8, GAME_BUTTON_START, false ), // start button - AutoMappingEntry( 0, JOY_BUTTON_7, GAME_BUTTON_BACK, false ) // back button - ), - AutoMappings( - "pump", - "Pump USB", - "Pump USB pad", - AutoMappingEntry( 0, JOY_BUTTON_1, PUMP_BUTTON_UPLEFT, false ), - AutoMappingEntry( 0, JOY_BUTTON_2, PUMP_BUTTON_UPRIGHT, false ), - AutoMappingEntry( 0, JOY_BUTTON_3, PUMP_BUTTON_CENTER, false ), - AutoMappingEntry( 0, JOY_BUTTON_4, PUMP_BUTTON_DOWNLEFT, false ), - AutoMappingEntry( 0, JOY_BUTTON_5, PUMP_BUTTON_DOWNRIGHT, false ), - AutoMappingEntry( 0, JOY_BUTTON_6, GAME_BUTTON_BACK, false ), - AutoMappingEntry( 0, JOY_BUTTON_7, PUMP_BUTTON_UPLEFT, true ), - AutoMappingEntry( 0, JOY_BUTTON_8, PUMP_BUTTON_UPRIGHT, true ), - AutoMappingEntry( 0, JOY_BUTTON_9, PUMP_BUTTON_CENTER, true ), - AutoMappingEntry( 0, JOY_BUTTON_10, PUMP_BUTTON_DOWNLEFT, true ), - AutoMappingEntry( 0, JOY_BUTTON_11, PUMP_BUTTON_DOWNRIGHT, true ) - ), - AutoMappings( - "pump", - "GamePad Pro USB ", // yes, there is a space at the end - "GamePad Pro USB", - AutoMappingEntry( 0, JOY_BUTTON_5, PUMP_BUTTON_UPLEFT, false ), - AutoMappingEntry( 0, JOY_BUTTON_6, PUMP_BUTTON_UPRIGHT, false ), - AutoMappingEntry( 0, JOY_BUTTON_7, PUMP_BUTTON_DOWNLEFT, false ), - AutoMappingEntry( 0, JOY_BUTTON_8, PUMP_BUTTON_DOWNRIGHT, false ), - AutoMappingEntry( 0, JOY_LEFT, GAME_BUTTON_MENULEFT, false ), - AutoMappingEntry( 0, JOY_RIGHT, GAME_BUTTON_MENURIGHT, false ), - AutoMappingEntry( 0, JOY_UP, GAME_BUTTON_MENUUP, false ), - AutoMappingEntry( 0, JOY_DOWN, GAME_BUTTON_MENUDOWN, false ), - AutoMappingEntry( 1, JOY_BUTTON_1, PUMP_BUTTON_CENTER, false ), - AutoMappingEntry( 0, JOY_BUTTON_9, GAME_BUTTON_BACK, false ), - AutoMappingEntry( 0, JOY_BUTTON_10, GAME_BUTTON_START, false ) - ), - AutoMappings( - "pump", - "Controller \\(Harmonix Drum Kit for Xbox 360\\)", - "Rock Band drum controller (Xbox 360, Windows driver)", - AutoMappingEntry( 0, JOY_BUTTON_5, PUMP_BUTTON_CENTER, false ), // bass pedal - AutoMappingEntry( 0, JOY_BUTTON_3, PUMP_BUTTON_UPRIGHT, false ), // blue drum - AutoMappingEntry( 0, JOY_BUTTON_4, PUMP_BUTTON_UPLEFT, false ), // yellow drum - AutoMappingEntry( 0, JOY_BUTTON_2, PUMP_BUTTON_DOWNLEFT, false ), // red drum - AutoMappingEntry( 0, JOY_BUTTON_1, PUMP_BUTTON_DOWNRIGHT, false ), // green drum - AutoMappingEntry( 0, JOY_HAT_LEFT, GAME_BUTTON_MENULEFT, false ), // d-pad left - AutoMappingEntry( 0, JOY_HAT_RIGHT, GAME_BUTTON_MENURIGHT, false ), // d-pad right - AutoMappingEntry( 0, JOY_HAT_UP, GAME_BUTTON_MENUUP, false ), // d-pad up - AutoMappingEntry( 0, JOY_HAT_DOWN, GAME_BUTTON_MENUDOWN, false ), // d-pad down - AutoMappingEntry( 0, JOY_BUTTON_8, GAME_BUTTON_START, false ), // start button - AutoMappingEntry( 0, JOY_BUTTON_7, GAME_BUTTON_BACK, false ) // back button - ), - AutoMappings( - "para", - "ParaParaParadise Controller", - "ParaParaParadise Controller", - AutoMappingEntry( 0, JOY_BUTTON_5, PARA_BUTTON_LEFT, false ), - AutoMappingEntry( 0, JOY_BUTTON_4, PARA_BUTTON_UPLEFT, false ), - AutoMappingEntry( 0, JOY_BUTTON_3, PARA_BUTTON_UP, false ), - AutoMappingEntry( 0, JOY_BUTTON_2, PARA_BUTTON_UPRIGHT, false ), - AutoMappingEntry( 0, JOY_BUTTON_1, PARA_BUTTON_RIGHT, false ), - AutoMappingEntry( 0, JOY_BUTTON_10, GAME_BUTTON_START, false ), - AutoMappingEntry( 0, JOY_BUTTON_11, GAME_BUTTON_BACK, false ), - AutoMappingEntry( 0, JOY_BUTTON_12, GAME_BUTTON_MENULEFT, false ), - AutoMappingEntry( 0, JOY_BUTTON_9, GAME_BUTTON_MENURIGHT, false ) - ), - AutoMappings( - "techno", - "Dance ", //Notice the extra space at end - "LevelSix USB Pad (DDR638)", // "DDR638" is the model number of the pad - AutoMappingEntry( 0, JOY_BUTTON_1, TECHNO_BUTTON_UP, false ), - AutoMappingEntry( 0, JOY_BUTTON_2, TECHNO_BUTTON_DOWN, false ), - AutoMappingEntry( 0, JOY_BUTTON_3, TECHNO_BUTTON_LEFT, false ), - AutoMappingEntry( 0, JOY_BUTTON_4, TECHNO_BUTTON_RIGHT, false ), - AutoMappingEntry( 0, JOY_BUTTON_5, TECHNO_BUTTON_DOWNRIGHT,false ), - AutoMappingEntry( 0, JOY_BUTTON_6, TECHNO_BUTTON_DOWNLEFT, false ), - AutoMappingEntry( 0, JOY_BUTTON_7, TECHNO_BUTTON_UPRIGHT, false ), - AutoMappingEntry( 0, JOY_BUTTON_8, TECHNO_BUTTON_UPLEFT, false ), - AutoMappingEntry( 0, JOY_BUTTON_9, GAME_BUTTON_BACK, false ), - AutoMappingEntry( 0, JOY_BUTTON_10, GAME_BUTTON_START, false ) - ), -}; - -void InputMapper::Unmap( InputDevice id ) -{ - m_mappings.Unmap( id ); - - UpdateTempDItoGI(); -} - -void InputMapper::ApplyMapping( const vector &vMmaps, GameController gc, InputDevice id ) -{ - map MappedButtons; - FOREACH_CONST( AutoMappingEntry, vMmaps, iter ) - { - GameController map_gc = gc; - if( iter->m_bSecondController ) - { - map_gc = (GameController)(map_gc+1); - - /* If that pushed it over, then it's a second controller for a joystick - * that's already a second controller, so we'll just ignore it. (This - * can happen if eg. two primary Pump pads are connected.) */ - if( map_gc >= NUM_GameController ) - continue; - } - - DeviceInput di( id, iter->m_deviceButton ); - GameInput gi( map_gc, iter->m_gb ); - int iSlot = MappedButtons[gi]; - ++MappedButtons[gi]; - SetInputMap( di, gi, iSlot );//maps[k].iSlotIndex ); - } -} - -void InputMapper::AutoMapJoysticksForCurrentGame() -{ - vector vDevices; - INPUTMAN->GetDevicesAndDescriptions(vDevices); - - // fill vector with all auto mappings - vector vAutoMappings; - { - // file automaps - Add these first so that they can match before the hard-coded mappings - vector vs; - GetDirListing( AUTOMAPPINGS_DIR "*.ini", vs, false, true ); - FOREACH_CONST( RString, vs, sFilePath ) - { - InputMappings km; - km.ReadMappings( m_pInputScheme, *sFilePath, true ); - - AutoMappings mapping( m_pInputScheme->m_szName, km.m_sDeviceRegex, km.m_sDescription ); - - FOREACH_ENUM( GameController, c ) - { - FOREACH_ENUM( GameButton, b ) - { - for( int s=0; s GameController_1 ); - mapping.m_vMaps.push_back( im ); - } - } - } - - vAutoMappings.push_back( mapping ); - } - - // hard-coded automaps - for( unsigned j=0; jm_szName) ) - vAutoMappings.push_back( mapping ); - } - } - - - // apply auto mappings - int iNumJoysticksMapped = 0; - FOREACH_CONST( InputDeviceInfo, vDevices, device ) - { - InputDevice id = device->id; - const RString &sDescription = device->sDesc; - FOREACH_CONST( AutoMappings, vAutoMappings, mapping ) - { - Regex regex( mapping->m_sDriverRegex ); - if( !regex.Compare(sDescription) ) - continue; // driver names don't match - - // We have a mapping for this joystick - GameController gc = (GameController)iNumJoysticksMapped; - if( gc >= NUM_GameController ) - break; // stop mapping. We already mapped one device for each game controller. - - LOG->Info( "Applying default joystick mapping #%d for device '%s' (%s)", - iNumJoysticksMapped+1, mapping->m_sDriverRegex.c_str(), mapping->m_sControllerName.c_str() ); - - Unmap( id ); - ApplyMapping( mapping->m_vMaps, gc, id ); - - iNumJoysticksMapped++; - } - } -} - -void InputMapper::SetInputScheme( const InputScheme *pInputScheme ) -{ - m_pInputScheme = pInputScheme; - - ReadMappingsFromDisk(); -} - -const InputScheme *InputMapper::GetInputScheme() const -{ - return m_pInputScheme; -} - -static const RString DEVICE_INPUT_SEPARATOR = ":"; // this isn't used in any key names - -void InputMapper::ReadMappingsFromDisk() -{ - m_mappings.ReadMappings( m_pInputScheme, SpecialFiles::KEYMAPS_PATH, false ); - UpdateTempDItoGI(); - - AddDefaultMappingsForCurrentGameIfUnmapped(); -} - -void InputMapper::SaveMappingsToDisk() -{ - m_mappings.WriteMappings( m_pInputScheme, SpecialFiles::KEYMAPS_PATH ); -} - -static LocalizedString CONNECTED ( "InputMapper", "Connected" ); -static LocalizedString DISCONNECTED ( "InputMapper", "Disconnected" ); -static LocalizedString AUTOMAPPING_ALL_JOYSTICKS ( "InputMapper", "Auto-mapping all joysticks." ); -bool InputMapper::CheckForChangedInputDevicesAndRemap( RString &sMessageOut ) -{ - // Only check for changes in joysticks since that's all we know how to remap. - - // update last seen joysticks - vector vDevices; - INPUTMAN->GetDevicesAndDescriptions( vDevices ); - - // Strip non-joysticks. - vector vsLastSeenJoysticks; - split( g_sLastSeenInputDevices, ",", vsLastSeenJoysticks ); - - vector vsCurrent; - vector vsCurrentJoysticks; - for( int i=vDevices.size()-1; i>=0; i-- ) - { - vsCurrent.push_back( vDevices[i].sDesc ); - if( IsJoystick(vDevices[i].id) ) - { - vsCurrentJoysticks.push_back( vDevices[i].sDesc ); - } - else - { - vector::iterator iter = find( vsLastSeenJoysticks.begin(), vsLastSeenJoysticks.end(), vDevices[i].sDesc ); - if( iter != vsLastSeenJoysticks.end() ) - vsLastSeenJoysticks.erase( iter ); - } - } - - bool bJoysticksChanged = vsCurrentJoysticks != vsLastSeenJoysticks; - if( !bJoysticksChanged ) - return false; - - vector vsConnects, vsDisconnects; - GetConnectsDisconnects( vsLastSeenJoysticks, vsCurrentJoysticks, vsDisconnects, vsConnects ); - - sMessageOut = RString(); - if( !vsConnects.empty() ) - sMessageOut += CONNECTED.GetValue()+": " + join( "\n", vsConnects ) + "\n"; - if( !vsDisconnects.empty() ) - sMessageOut += DISCONNECTED.GetValue()+": " + join( "\n", vsDisconnects ) + "\n"; - - if( g_bAutoMapOnJoyChange ) - { - sMessageOut += AUTOMAPPING_ALL_JOYSTICKS.GetValue(); - AutoMapJoysticksForCurrentGame(); - SaveMappingsToDisk(); - MESSAGEMAN->Broadcast( Message_AutoJoyMappingApplied ); - } - - LOG->Info( "%s", sMessageOut.c_str() ); - - g_sLastSeenInputDevices.Set( join(",",vsCurrent) ); - PREFSMAN->SavePrefsToDisk(); - - return true; -} - -void InputMapper::SetInputMap( const DeviceInput &DeviceI, const GameInput &GameI, int iSlotIndex ) -{ - m_mappings.SetInputMap( DeviceI, GameI, iSlotIndex ); - - UpdateTempDItoGI(); -} - -void InputMapper::ClearFromInputMap( const DeviceInput &DeviceI ) -{ - m_mappings.ClearFromInputMap( DeviceI ); - - UpdateTempDItoGI(); -} - -bool InputMapper::ClearFromInputMap( const GameInput &GameI, int iSlotIndex ) -{ - if( !m_mappings.ClearFromInputMap(GameI, iSlotIndex) ) - return false; - - UpdateTempDItoGI(); - return true; -} - -bool InputMapper::IsMapped( const DeviceInput &DeviceI ) const -{ - return g_tempDItoGI.find(DeviceI) != g_tempDItoGI.end(); -} - -void InputMapper::UpdateTempDItoGI() -{ - // repopulate g_tempDItoGI - g_tempDItoGI.clear(); - FOREACH_ENUM( GameController, n ) - { - FOREACH_ENUM( GameButton, b ) - { - for( int s=0; sGameButtonToMenuButton( gb ); -} - -/* If set (not PLAYER_INVALID), inputs from both GameControllers will be mapped - * to the specified player. If PLAYER_INVALID, GameControllers will be mapped - * individually. */ -void InputMapper::SetJoinControllers( PlayerNumber pn ) -{ - g_JoinControllers = pn; -} - - -void InputMapper::MenuToGame( GameButton MenuI, PlayerNumber pn, vector &GameIout ) const -{ - if( g_JoinControllers != PLAYER_INVALID ) - pn = PLAYER_INVALID; - - m_pInputScheme->MenuButtonToGameInputs( MenuI, pn, GameIout ); -} - - -bool InputMapper::IsBeingPressed( const GameInput &GameI, MultiPlayer mp, const DeviceInputList *pButtonState ) const -{ - for( int i=0; iIsBeingPressed(DeviceI, pButtonState) ) - return true; - } - } - - return false; -} - -bool InputMapper::IsBeingPressed( GameButton MenuI, PlayerNumber pn ) const -{ - vector GameI; - MenuToGame( MenuI, pn, GameI ); - for( size_t i=0; iRepeatStopKey( DeviceI ); - } -} - -void InputMapper::RepeatStopKey( GameButton MenuI, PlayerNumber pn ) -{ - vector GameI; - MenuToGame( MenuI, pn, GameI ); - for( size_t i=0; iGetSecsHeld(DeviceI) ); - } - } - - return fMaxSecsHeld; -} - -float InputMapper::GetSecsHeld( GameButton MenuI, PlayerNumber pn ) const -{ - float fMaxSecsHeld = 0; - - vector GameI; - MenuToGame( MenuI, pn, GameI ); - for( size_t i=0; iResetKeyRepeat( DeviceI ); - } -} - -void InputMapper::ResetKeyRepeat( GameButton MenuI, PlayerNumber pn ) -{ - vector GameI; - MenuToGame( MenuI, pn, GameI ); - for( size_t i=0; iGetLevel(DeviceI) ); - } - return fLevel; -} - -float InputMapper::GetLevel( GameButton MenuI, PlayerNumber pn ) const -{ - vector GameI; - MenuToGame( MenuI, pn, GameI ); - - float fLevel = 0; - for( size_t i=0; i &GameIout ) const -{ - ASSERT( MenuI != GameButton_Invalid ); - - vector aGameButtons; - MenuButtonToGameButtons( MenuI, aGameButtons ); - FOREACH( GameButton, aGameButtons, gb ) - { - if( pn == PLAYER_INVALID ) - { - GameIout.push_back( GameInput(GameController_1, *gb) ); - GameIout.push_back( GameInput(GameController_2, *gb) ); - } - else - { - GameIout.push_back( GameInput((GameController)pn, *gb) ); - } - } -} - -void InputScheme::MenuButtonToGameButtons( GameButton MenuI, vector &aGameButtons ) const -{ - ASSERT( MenuI != GameButton_Invalid ); - - if( MenuI == GameButton_Invalid ) - return; - - FOREACH_ENUM( GameButton, gb) - { - if( PREFSMAN->m_bOnlyDedicatedMenuButtons && gb >= GAME_BUTTON_NEXT ) - break; - - const GameButtonInfo *pGameButtonInfo = GetGameButtonInfo( gb ); - if( pGameButtonInfo->m_SecondaryMenuButton != MenuI ) - continue; - aGameButtons.push_back( gb ); - } -} - -GameButton InputScheme::GameButtonToMenuButton( GameButton gb ) const -{ - if( gb == GameButton_Invalid ) - return GameButton_Invalid; - if( gb >= GAME_BUTTON_NEXT && PREFSMAN->m_bOnlyDedicatedMenuButtons ) - return GameButton_Invalid; - return GetGameButtonInfo(gb)->m_SecondaryMenuButton; -} - -static const InputScheme::GameButtonInfo g_CommonGameButtonInfo[] = -{ - { "MenuLeft", GAME_BUTTON_MENULEFT }, - { "MenuRight", GAME_BUTTON_MENURIGHT }, - { "MenuUp", GAME_BUTTON_MENUUP }, - { "MenuDown", GAME_BUTTON_MENUDOWN }, - { "Start", GAME_BUTTON_START }, - { "Select", GAME_BUTTON_SELECT }, - { "Back", GAME_BUTTON_BACK }, - { "Coin", GAME_BUTTON_COIN }, - { "Operator", GAME_BUTTON_OPERATOR }, - { "EffectUp", GAME_BUTTON_EFFECT_UP }, - { "EffectDown", GAME_BUTTON_EFFECT_DOWN }, -}; - -const InputScheme::GameButtonInfo *InputScheme::GetGameButtonInfo( GameButton gb ) const -{ - COMPILE_ASSERT( GAME_BUTTON_NEXT == ARRAYLEN(g_CommonGameButtonInfo) ); - if( gb < GAME_BUTTON_NEXT ) - return &g_CommonGameButtonInfo[gb]; - else - return &m_GameButtonInfo[gb-GAME_BUTTON_NEXT]; -} - -const char *InputScheme::GetGameButtonName( GameButton gb ) const -{ - if( gb == GameButton_Invalid ) - return ""; - return GetGameButtonInfo(gb)->m_szName; -} - -void InputMappings::Clear() -{ - FOREACH_ENUM( GameController, i ) - FOREACH_ENUM( GameButton, j) - for( int k=0; kTrace( "Couldn't open mapping file \"%s\": %s.", - SpecialFiles::KEYMAPS_PATH.c_str(), ini.GetError().c_str() ); - - if( bIsAutoMapping ) - { - if( !ini.GetValue( "AutoMapping", "DeviceRegex", m_sDeviceRegex ) ) - Dialog::OK( "Missing AutoMapping::DeviceRegex in '%s'", sFilePath.c_str() ); - - if( !ini.GetValue( "AutoMapping", "Description", m_sDescription ) ) - Dialog::OK( "Missing AutoMapping::Description in '%s'", sFilePath.c_str() ); - } - - const XNode *Key = ini.GetChild( pInputScheme->m_szName ); - - if( Key ) - { - FOREACH_CONST_Attr( Key, i ) - { - const RString &name = i->first; - RString value; - i->second->GetValue( value ); - - GameInput GameI; - GameI.FromString( pInputScheme, name ); - if( !GameI.IsValid() ) - continue; - - vector sDeviceInputStrings; - split( value, DEVICE_INPUT_SEPARATOR, sDeviceInputStrings, false ); - - for( unsigned j=0; jm_szName ); - - XNode *pKey = ini.GetChild( pInputScheme->m_szName ); - if( pKey != NULL ) - ini.RemoveChild( pKey ); - pKey = ini.AppendChild( pInputScheme->m_szName ); - - // iterate over our input map and write all mappings to the ini file - FOREACH_ENUM( GameController, i ) - { - FOREACH_GameButtonInScheme( pInputScheme, j ) - { - GameInput GameI( i, j ); - RString sNameString = GameI.ToString( pInputScheme ); - - vector asValues; - for( int slot = 0; slot < NUM_USER_GAME_TO_DEVICE_SLOTS; ++slot ) // don't save data from the last (keyboard automap) slot - asValues.push_back( m_GItoDI[i][j][slot].ToString() ); - - while( asValues.size() && asValues.back() == "" ) - asValues.erase( asValues.begin()+asValues.size()-1 ); - - RString sValueString = join( DEVICE_INPUT_SEPARATOR, asValues ); - - pKey->AppendAttr( sNameString, sValueString ); - } - } - - ini.WriteFile( sFilePath ); -} - -void InputMappings::SetInputMap( const DeviceInput &DeviceI, const GameInput &GameI, int iSlotIndex ) -{ - // remove the old input - ClearFromInputMap( DeviceI ); - ClearFromInputMap( GameI, iSlotIndex ); - - ASSERT_M( GameI.controller < NUM_GameController, - ssprintf("controller: %u >= %u", GameI.controller, NUM_GameController) ); - ASSERT_M( GameI.button < NUM_GameButton, - ssprintf("button: %u >= %u", GameI.button, NUM_GameButton) ); - ASSERT_M( iSlotIndex < NUM_GAME_TO_DEVICE_SLOTS, - ssprintf("slot: %u >= %u", iSlotIndex, NUM_GAME_TO_DEVICE_SLOTS) ); - m_GItoDI[GameI.controller][GameI.button][iSlotIndex] = DeviceI; -} - -void InputMappings::ClearFromInputMap( const DeviceInput &DeviceI ) -{ - // search for where this DeviceI maps to - - FOREACH_ENUM( GameController, p ) - { - FOREACH_ENUM( GameButton, b) - { - for( int s=0; s g_sLastSeenInputDevices( "LastSeenInputDevices", "" ); +static Preference g_bAutoMapOnJoyChange( "AutoMapOnJoyChange", true ); + +namespace +{ + // lookup for efficiency from a DeviceInput to a GameInput + // This is repopulated every time m_PItoDI changes by calling UpdateTempDItoPI(). + map g_tempDItoGI; + + PlayerNumber g_JoinControllers; +}; + +InputMapper* INPUTMAPPER = NULL; // global and accessable from anywhere in our program + +InputMapper::InputMapper() +{ + g_JoinControllers = PLAYER_INVALID; + m_pInputScheme = NULL; +} + +InputMapper::~InputMapper() +{ + SaveMappingsToDisk(); + g_tempDItoGI.clear(); +} + +void InputMapper::ClearAllMappings() +{ + m_mappings.Clear(); + + UpdateTempDItoGI(); +} + +static const AutoMappings g_DefaultKeyMappings = AutoMappings( + "", + "", + "", + AutoMappingEntry( 0, KEY_LEFT, GAME_BUTTON_MENULEFT, false ), + AutoMappingEntry( 0, KEY_RIGHT, GAME_BUTTON_MENURIGHT, false ), + AutoMappingEntry( 0, KEY_UP, GAME_BUTTON_MENUUP, false ), + AutoMappingEntry( 0, KEY_DOWN, GAME_BUTTON_MENUDOWN, false ), + AutoMappingEntry( 0, KEY_ENTER, GAME_BUTTON_START, false ), + AutoMappingEntry( 0, KEY_SLASH, GAME_BUTTON_SELECT, false ), + AutoMappingEntry( 0, KEY_ESC, GAME_BUTTON_BACK, false ), + AutoMappingEntry( 0, KEY_KP_C4, GAME_BUTTON_MENULEFT, true ), + AutoMappingEntry( 0, KEY_KP_C6, GAME_BUTTON_MENURIGHT, true ), + AutoMappingEntry( 0, KEY_KP_C8, GAME_BUTTON_MENUUP, true ), + AutoMappingEntry( 0, KEY_KP_C2, GAME_BUTTON_MENUDOWN, true ), + AutoMappingEntry( 0, KEY_KP_ENTER, GAME_BUTTON_START, true ), + AutoMappingEntry( 0, KEY_KP_C0, GAME_BUTTON_SELECT, true ), + AutoMappingEntry( 0, KEY_HYPHEN, GAME_BUTTON_BACK, true ), // laptop keyboards. + AutoMappingEntry( 0, KEY_F1, GAME_BUTTON_COIN, false ), + AutoMappingEntry( 0, KEY_SCRLLOCK, GAME_BUTTON_OPERATOR, false ) +); + +void InputMapper::AddDefaultMappingsForCurrentGameIfUnmapped() +{ + // Clear default mappings. Default mappings are in the third slot. + FOREACH_ENUM( GameController, i ) + FOREACH_ENUM( GameButton, j) + ClearFromInputMap( GameInput(i, j), 2 ); + + vector aMaps; + aMaps.reserve( 32 ); + + FOREACH_CONST( AutoMappingEntry, g_DefaultKeyMappings.m_vMaps, iter ) + aMaps.push_back( *iter ); + FOREACH_CONST( AutoMappingEntry, m_pInputScheme->m_pAutoMappings->m_vMaps, iter ) + aMaps.push_back( *iter ); + + /* There may be duplicate GAME_BUTTON maps. Process the list backwards, + * so game-specific mappings override g_DefaultKeyMappings. */ + std::reverse( aMaps.begin(), aMaps.end() ); + + FOREACH( AutoMappingEntry, aMaps, m ) + { + DeviceButton key = m->m_deviceButton; + DeviceInput DeviceI( DEVICE_KEYBOARD, key ); + GameInput GameI( m->m_bSecondController ? GameController_2 : GameController_1, m->m_gb ); + if( !IsMapped(DeviceI) ) // if this key isn't already being used by another user-made mapping + { + if( !GameI.IsValid() ) + ClearFromInputMap( DeviceI ); + else + SetInputMap( DeviceI, GameI, 2 ); + } + } +} + +static const AutoMappings g_AutoMappings[] = +{ + AutoMappings( + "dance", + "GIC USB Joystick", + "Boom USB convertor (black/gray)", + AutoMappingEntry( 0, JOY_BUTTON_16, DANCE_BUTTON_LEFT, false ), + AutoMappingEntry( 0, JOY_BUTTON_14, DANCE_BUTTON_RIGHT, false ), + AutoMappingEntry( 0, JOY_BUTTON_13, DANCE_BUTTON_UP, false ), + AutoMappingEntry( 0, JOY_BUTTON_15, DANCE_BUTTON_DOWN, false ), + AutoMappingEntry( 1, JOY_BUTTON_4, DANCE_BUTTON_LEFT, false ), + AutoMappingEntry( 1, JOY_BUTTON_2, DANCE_BUTTON_RIGHT, false ), + AutoMappingEntry( 1, JOY_BUTTON_1, DANCE_BUTTON_UP, false ), + AutoMappingEntry( 1, JOY_BUTTON_3, DANCE_BUTTON_DOWN, false ), + AutoMappingEntry( 0, JOY_BUTTON_7, DANCE_BUTTON_UPLEFT, false ), + AutoMappingEntry( 0, JOY_BUTTON_8, DANCE_BUTTON_UPRIGHT, false ), + AutoMappingEntry( 0, JOY_BUTTON_9, GAME_BUTTON_BACK, false ), + AutoMappingEntry( 0, JOY_BUTTON_12, GAME_BUTTON_START, false ) + ), + AutoMappings( + "dance", + "4 axis 16 button joystick", + "EMS USB2", + AutoMappingEntry( 0, JOY_BUTTON_16, DANCE_BUTTON_LEFT, false ), + AutoMappingEntry( 0, JOY_BUTTON_14, DANCE_BUTTON_RIGHT, false ), + AutoMappingEntry( 0, JOY_BUTTON_13, DANCE_BUTTON_UP, false ), + AutoMappingEntry( 0, JOY_BUTTON_15, DANCE_BUTTON_DOWN, false ), + AutoMappingEntry( 1, JOY_BUTTON_4, DANCE_BUTTON_LEFT, false ), + AutoMappingEntry( 1, JOY_BUTTON_2, DANCE_BUTTON_RIGHT, false ), + AutoMappingEntry( 1, JOY_BUTTON_1, DANCE_BUTTON_UP, false ), + AutoMappingEntry( 1, JOY_BUTTON_3, DANCE_BUTTON_DOWN, false ), + AutoMappingEntry( 0, JOY_BUTTON_7, DANCE_BUTTON_UPLEFT, false ), + AutoMappingEntry( 0, JOY_BUTTON_8, DANCE_BUTTON_UPRIGHT, false ), + AutoMappingEntry( 0, JOY_BUTTON_9, GAME_BUTTON_BACK, false ), + AutoMappingEntry( 0, JOY_BUTTON_10, GAME_BUTTON_START, false ) + ), + AutoMappings( + "dance", + "GamePad Pro USB ", // yes, there is a space at the end + "GamePad Pro USB", + AutoMappingEntry( 0, JOY_LEFT, DANCE_BUTTON_LEFT, false ), + AutoMappingEntry( 0, JOY_RIGHT, DANCE_BUTTON_RIGHT, false ), + AutoMappingEntry( 0, JOY_UP, DANCE_BUTTON_UP, false ), + AutoMappingEntry( 0, JOY_DOWN, DANCE_BUTTON_DOWN, false ), + AutoMappingEntry( 1, JOY_BUTTON_1, DANCE_BUTTON_LEFT, false ), + AutoMappingEntry( 1, JOY_BUTTON_3, DANCE_BUTTON_RIGHT, false ), + AutoMappingEntry( 1, JOY_BUTTON_4, DANCE_BUTTON_UP, false ), + AutoMappingEntry( 1, JOY_BUTTON_2, DANCE_BUTTON_DOWN, false ), + AutoMappingEntry( 0, JOY_BUTTON_5, DANCE_BUTTON_UPLEFT, false ), + AutoMappingEntry( 0, JOY_BUTTON_6, DANCE_BUTTON_UPRIGHT, false ), + AutoMappingEntry( 0, JOY_BUTTON_9, GAME_BUTTON_BACK, false ), + AutoMappingEntry( 0, JOY_BUTTON_10, GAME_BUTTON_START, false ) + ), + AutoMappings( + "dance", + "SideWinder Game Pad USB version 1.0", + "SideWinder Game Pad USB", + AutoMappingEntry( 0, JOY_LEFT, DANCE_BUTTON_LEFT, false ), + AutoMappingEntry( 0, JOY_RIGHT, DANCE_BUTTON_RIGHT, false ), + AutoMappingEntry( 0, JOY_UP, DANCE_BUTTON_UP, false ), + AutoMappingEntry( 0, JOY_DOWN, DANCE_BUTTON_DOWN, false ), + AutoMappingEntry( 1, JOY_BUTTON_4, DANCE_BUTTON_LEFT, false ), + AutoMappingEntry( 1, JOY_BUTTON_2, DANCE_BUTTON_RIGHT, false ), + AutoMappingEntry( 1, JOY_BUTTON_5, DANCE_BUTTON_UP, false ), + AutoMappingEntry( 1, JOY_BUTTON_1, DANCE_BUTTON_DOWN, false ), + AutoMappingEntry( 0, JOY_BUTTON_7, DANCE_BUTTON_UPLEFT, false ), + AutoMappingEntry( 0, JOY_BUTTON_8, DANCE_BUTTON_UPRIGHT, false ), + AutoMappingEntry( 0, JOY_BUTTON_9, GAME_BUTTON_BACK, false ), + AutoMappingEntry( 0, JOY_BUTTON_10, GAME_BUTTON_START, false ) + ), + AutoMappings( + "dance", + "4 axis 12 button joystick with hat switch", + "Super Joy Box 5", + AutoMappingEntry( 0, JOY_LEFT, DANCE_BUTTON_LEFT, false ), + AutoMappingEntry( 0, JOY_RIGHT, DANCE_BUTTON_RIGHT, false ), + AutoMappingEntry( 0, JOY_UP, DANCE_BUTTON_UP, false ), + AutoMappingEntry( 0, JOY_DOWN, DANCE_BUTTON_DOWN, false ), + AutoMappingEntry( 1, JOY_BUTTON_4, DANCE_BUTTON_LEFT, false ), + AutoMappingEntry( 1, JOY_BUTTON_2, DANCE_BUTTON_RIGHT, false ), + AutoMappingEntry( 1, JOY_BUTTON_1, DANCE_BUTTON_UP, false ), + AutoMappingEntry( 1, JOY_BUTTON_3, DANCE_BUTTON_DOWN, false ), + AutoMappingEntry( 0, JOY_BUTTON_7, DANCE_BUTTON_UPLEFT, false ), + AutoMappingEntry( 0, JOY_BUTTON_8, DANCE_BUTTON_UPRIGHT, false ), + AutoMappingEntry( 0, JOY_BUTTON_10, GAME_BUTTON_BACK, false ), + AutoMappingEntry( 0, JOY_BUTTON_9, GAME_BUTTON_START, false ) + ), +/* AutoMappings( + + "dance", + "MP-8866 Dual USB Joypad", + "Super Dual Box (from Lik-Sang, 2004)", + //NEEDS_DANCE_PAD_MAPPING_CODE, + AutoMappingEntry( 0, JOY_LEFT, DANCE_BUTTON_LEFT, false ), + AutoMappingEntry( 0, JOY_RIGHT, DANCE_BUTTON_RIGHT, false ), + AutoMappingEntry( 0, JOY_UP, DANCE_BUTTON_UP, false ), + AutoMappingEntry( 0, JOY_DOWN, DANCE_BUTTON_DOWN, false ), + AutoMappingEntry( 1, JOY_BUTTON_4, DANCE_BUTTON_LEFT, false ), + AutoMappingEntry( 1, JOY_BUTTON_2, DANCE_BUTTON_RIGHT, false ), + AutoMappingEntry( 1, JOY_BUTTON_1, DANCE_BUTTON_UP, false ), + AutoMappingEntry( 1, JOY_BUTTON_3, DANCE_BUTTON_DOWN, false ), + AutoMappingEntry( 0, JOY_BUTTON_5, DANCE_BUTTON_UPLEFT, false ), + AutoMappingEntry( 0, JOY_BUTTON_6, DANCE_BUTTON_UPRIGHT, false ), + AutoMappingEntry( 1, JOY_BUTTON_7, DANCE_BUTTON_UPLEFT, false ), + AutoMappingEntry( 1, JOY_BUTTON_8, DANCE_BUTTON_UPRIGHT, false ), + AutoMappingEntry( 0, JOY_BUTTON_10, GAME_BUTTON_BACK, false ), + AutoMappingEntry( 0, JOY_BUTTON_9, GAME_BUTTON_START, false ), + ), +*/ + AutoMappings( + "dance", + "MP-8866 Dual USB Joypad", + "Super Dual Box (from DDRGame.com, Feb 2008)", + //NEEDS_DANCE_PAD_MAPPING_CODE, + AutoMappingEntry( 0, JOY_BUTTON_3, DANCE_BUTTON_UP, false ), + AutoMappingEntry( 0, JOY_BUTTON_2, DANCE_BUTTON_DOWN, false ), + AutoMappingEntry( 0, JOY_BUTTON_1, DANCE_BUTTON_LEFT, false ), + AutoMappingEntry( 0, JOY_BUTTON_4, DANCE_BUTTON_RIGHT, false ), + AutoMappingEntry( 0, JOY_BUTTON_7, DANCE_BUTTON_UPLEFT, false ), + AutoMappingEntry( 0, JOY_BUTTON_8, DANCE_BUTTON_UPRIGHT, false ), + //AutoMappingEntry{ 0, JOY_BUTTON_5, DANCE_BUTTON_DOWNLEFT, false ), + //AutoMappingEntry{ 0, JOY_BUTTON_6, DANCE_BUTTON_DOWNRIGHT, false ), + AutoMappingEntry( 0, JOY_BUTTON_10, GAME_BUTTON_BACK, false ), + AutoMappingEntry( 0, JOY_BUTTON_9, GAME_BUTTON_START, false ) + ), + AutoMappings( + "dance", + "NTPAD", + "NTPAD", + AutoMappingEntry( 0, JOY_BUTTON_13, DANCE_BUTTON_LEFT, false ), + AutoMappingEntry( 0, JOY_BUTTON_15, DANCE_BUTTON_RIGHT, false ), + AutoMappingEntry( 0, JOY_BUTTON_16, DANCE_BUTTON_UP, false ), + AutoMappingEntry( 0, JOY_BUTTON_14, DANCE_BUTTON_DOWN, false ), + AutoMappingEntry( 1, JOY_BUTTON_1, DANCE_BUTTON_LEFT, false ), + AutoMappingEntry( 1, JOY_BUTTON_3, DANCE_BUTTON_RIGHT, false ), + AutoMappingEntry( 1, JOY_BUTTON_4, DANCE_BUTTON_UP, false ), + AutoMappingEntry( 1, JOY_BUTTON_2, DANCE_BUTTON_DOWN, false ), + AutoMappingEntry( 0, JOY_BUTTON_5, DANCE_BUTTON_UPLEFT, false ), + AutoMappingEntry( 0, JOY_BUTTON_6, DANCE_BUTTON_UPRIGHT, false ), + AutoMappingEntry( 1, JOY_BUTTON_7, DANCE_BUTTON_UPLEFT, false ), + AutoMappingEntry( 1, JOY_BUTTON_8, DANCE_BUTTON_UPRIGHT, false ), + AutoMappingEntry( 0, JOY_BUTTON_9, GAME_BUTTON_BACK, false ), + AutoMappingEntry( 0, JOY_BUTTON_10, GAME_BUTTON_START, false ) + ), + AutoMappings( + "dance", + "Psx Gamepad", + "PSXPAD", + AutoMappingEntry( 0, JOY_LEFT, DANCE_BUTTON_LEFT, false ), + AutoMappingEntry( 0, JOY_RIGHT, DANCE_BUTTON_RIGHT, false ), + AutoMappingEntry( 0, JOY_UP, DANCE_BUTTON_UP, false ), + AutoMappingEntry( 0, JOY_DOWN, DANCE_BUTTON_DOWN, false ), + AutoMappingEntry( 1, JOY_BUTTON_2, DANCE_BUTTON_LEFT, false ), + AutoMappingEntry( 1, JOY_BUTTON_1, DANCE_BUTTON_RIGHT, false ), + AutoMappingEntry( 1, JOY_BUTTON_4, DANCE_BUTTON_UP, false ), + AutoMappingEntry( 1, JOY_BUTTON_3, DANCE_BUTTON_DOWN, false ), + AutoMappingEntry( 0, JOY_BUTTON_7, DANCE_BUTTON_UPLEFT, false ), + AutoMappingEntry( 0, JOY_BUTTON_5, DANCE_BUTTON_UPRIGHT, false ), + AutoMappingEntry( 1, JOY_BUTTON_8, DANCE_BUTTON_UPLEFT, false ), + AutoMappingEntry( 1, JOY_BUTTON_6, DANCE_BUTTON_UPRIGHT, false ), + AutoMappingEntry( 0, JOY_BUTTON_10, GAME_BUTTON_BACK, false ), + AutoMappingEntry( 0, JOY_BUTTON_9, GAME_BUTTON_START, false ) + ), + AutoMappings( + "dance", + "XBOX Gamepad Plugin V0.01", + "X-Box gamepad", + AutoMappingEntry( 0, JOY_LEFT, DANCE_BUTTON_LEFT, false ), + AutoMappingEntry( 0, JOY_RIGHT, DANCE_BUTTON_RIGHT, false ), + AutoMappingEntry( 0, JOY_UP, DANCE_BUTTON_UP, false ), + AutoMappingEntry( 0, JOY_DOWN, DANCE_BUTTON_DOWN, false ), + AutoMappingEntry( 1, JOY_BUTTON_1, DANCE_BUTTON_DOWN, false ), // A + AutoMappingEntry( 1, JOY_BUTTON_2, DANCE_BUTTON_RIGHT, false ), // B + AutoMappingEntry( 1, JOY_BUTTON_3, DANCE_BUTTON_LEFT, false ), // X + AutoMappingEntry( 1, JOY_BUTTON_4, DANCE_BUTTON_UP, false ), // Y + AutoMappingEntry( 0, JOY_BUTTON_7, DANCE_BUTTON_UPLEFT, false ), // L shoulder + AutoMappingEntry( 0, JOY_BUTTON_8, DANCE_BUTTON_UPRIGHT, false ), // R shoulder + AutoMappingEntry( 0, JOY_BUTTON_9, GAME_BUTTON_START, false ), + AutoMappingEntry( 0, JOY_BUTTON_10, GAME_BUTTON_BACK, false ) + ), + AutoMappings( + "dance", + "0b43:0003", // The EMS USB2 doesn't provide a model string, so Linux + // just gives us the VendorID and ModelID in hex. + "EMS USB2", + // Player 1. + AutoMappingEntry( 0, JOY_BUTTON_16, DANCE_BUTTON_LEFT, false ), + AutoMappingEntry( 0, JOY_BUTTON_14, DANCE_BUTTON_RIGHT, false ), + AutoMappingEntry( 0, JOY_BUTTON_13, DANCE_BUTTON_UP, false ), + AutoMappingEntry( 0, JOY_BUTTON_15, DANCE_BUTTON_DOWN, false ), + AutoMappingEntry( 1, JOY_BUTTON_4, DANCE_BUTTON_LEFT, false ), + AutoMappingEntry( 1, JOY_BUTTON_2, DANCE_BUTTON_RIGHT, false ), + AutoMappingEntry( 1, JOY_BUTTON_1, DANCE_BUTTON_UP, false ), + AutoMappingEntry( 1, JOY_BUTTON_3, DANCE_BUTTON_DOWN, false ), + AutoMappingEntry( 0, JOY_BUTTON_7, DANCE_BUTTON_UPLEFT, false ), + AutoMappingEntry( 0, JOY_BUTTON_8, DANCE_BUTTON_UPRIGHT, false ), + AutoMappingEntry( 0, JOY_BUTTON_9, GAME_BUTTON_SELECT, false ), + AutoMappingEntry( 0, JOY_BUTTON_10, GAME_BUTTON_START, false ), + AutoMappingEntry( 0, JOY_BUTTON_5, GAME_BUTTON_BACK, false ), + AutoMappingEntry( 0, JOY_BUTTON_6, GAME_BUTTON_COIN, false ), + // Player 2. + AutoMappingEntry( 0, JOY_BUTTON_32, DANCE_BUTTON_LEFT, true ), + AutoMappingEntry( 0, JOY_BUTTON_30, DANCE_BUTTON_RIGHT, true ), + AutoMappingEntry( 0, JOY_BUTTON_29, DANCE_BUTTON_UP, true ), + AutoMappingEntry( 0, JOY_BUTTON_31, DANCE_BUTTON_DOWN, true ), + AutoMappingEntry( 1, JOY_BUTTON_20, DANCE_BUTTON_LEFT, true ), + AutoMappingEntry( 1, JOY_BUTTON_18, DANCE_BUTTON_RIGHT, true ), + AutoMappingEntry( 1, JOY_BUTTON_17, DANCE_BUTTON_UP, true ), + AutoMappingEntry( 1, JOY_BUTTON_19, DANCE_BUTTON_DOWN, true ), + AutoMappingEntry( 0, JOY_BUTTON_23, DANCE_BUTTON_UPRIGHT, true ), + AutoMappingEntry( 0, JOY_BUTTON_24, DANCE_BUTTON_UPLEFT, true ), + AutoMappingEntry( 0, JOY_BUTTON_25, GAME_BUTTON_SELECT, true ), + AutoMappingEntry( 0, JOY_BUTTON_26, GAME_BUTTON_START, true ), + AutoMappingEntry( 0, JOY_BUTTON_21, GAME_BUTTON_BACK, true ), + AutoMappingEntry( 0, JOY_BUTTON_22, GAME_BUTTON_COIN, true ) + ), + AutoMappings( + "dance", + "Dance ", //Notice extra space at end + "LevelSix USB Pad (DDR638)", // "DDR638" is the model number of the pad + AutoMappingEntry( 0, JOY_BUTTON_1, DANCE_BUTTON_UP, false ), + AutoMappingEntry( 0, JOY_BUTTON_2, DANCE_BUTTON_DOWN, false ), + AutoMappingEntry( 0, JOY_BUTTON_3, DANCE_BUTTON_LEFT, false ), + AutoMappingEntry( 0, JOY_BUTTON_4, DANCE_BUTTON_RIGHT, false ), + AutoMappingEntry( 0, JOY_BUTTON_7, DANCE_BUTTON_UPRIGHT, false ), + AutoMappingEntry( 0, JOY_BUTTON_8, DANCE_BUTTON_UPLEFT, false ), + AutoMappingEntry( 0, JOY_BUTTON_9, GAME_BUTTON_BACK, false ), + AutoMappingEntry( 0, JOY_BUTTON_10, GAME_BUTTON_START, false ) + ), + AutoMappings( + "dance", + "SmartJoy PLUS Adapter", + "SmartJoy PLUS Adapter", + AutoMappingEntry( 0, JOY_LEFT, /* dpad L */ DANCE_BUTTON_LEFT, false ), + AutoMappingEntry( 0, JOY_RIGHT, /* dpad R */ DANCE_BUTTON_RIGHT, false ), + AutoMappingEntry( 0, JOY_UP, /* dpad U */ DANCE_BUTTON_UP, false ), + AutoMappingEntry( 0, JOY_DOWN, /* dpad D */ DANCE_BUTTON_DOWN, false ), + AutoMappingEntry( 1, JOY_BUTTON_4, /* Square */ DANCE_BUTTON_LEFT, false ), + AutoMappingEntry( 1, JOY_BUTTON_2, /* Circle */ DANCE_BUTTON_RIGHT, false ), + AutoMappingEntry( 1, JOY_BUTTON_1, /* Tri */ DANCE_BUTTON_UP, false ), + AutoMappingEntry( 1, JOY_BUTTON_3, /* X */ DANCE_BUTTON_DOWN, false ), + AutoMappingEntry( 0, JOY_BUTTON_7, /* L1 */ DANCE_BUTTON_UPLEFT, false ), + AutoMappingEntry( 0, JOY_BUTTON_8, /* R1 */ DANCE_BUTTON_UPRIGHT, false ), + AutoMappingEntry( 0, JOY_BUTTON_10, /* Select */ GAME_BUTTON_BACK, false ), + AutoMappingEntry( 0, JOY_BUTTON_9, /* Start */ GAME_BUTTON_START, false ), + AutoMappingEntry( 0, JOY_BUTTON_5, /* R1 */ GAME_BUTTON_SELECT, false ), + AutoMappingEntry( 0, JOY_BUTTON_6, /* R2 */ GAME_BUTTON_COIN, false ) + ), + AutoMappings( + "dance", + "RedOctane USB Pad|XBOX DDR", // "RedOctane USB Pad" is Ignition 3s and newer Afterburners. "XBOX DDR" is older Afterburners. + "RedOctane Ignition 3 or Afterburner", + AutoMappingEntry( 0, JOY_BUTTON_1, /* dpad L */ DANCE_BUTTON_LEFT, false ), + AutoMappingEntry( 0, JOY_BUTTON_4, /* dpad R */ DANCE_BUTTON_RIGHT, false ), + AutoMappingEntry( 0, JOY_BUTTON_3, /* dpad U */ DANCE_BUTTON_UP, false ), + AutoMappingEntry( 0, JOY_BUTTON_2, /* dpad D */ DANCE_BUTTON_DOWN, false ), + //AutoMappingEntry{ 0, JOY_BUTTON_5, /* Tri */ GAME_BUTTON_BACK, false ), + //AutoMappingEntry{ 0, JOY_BUTTON_6, /* Square */ GAME_BUTTON_BACK, false ), + //AutoMappingEntry{ 1, JOY_BUTTON_7, /* X */ GAME_BUTTON_START, false ), + AutoMappingEntry( 0, JOY_BUTTON_8, /* O */ GAME_BUTTON_START, false ), + AutoMappingEntry( 1, JOY_BUTTON_9, /* Start */ GAME_BUTTON_START, false ), + AutoMappingEntry( 0, JOY_BUTTON_10, /* Sel */ GAME_BUTTON_BACK, false ) + ), + AutoMappings( + "dance", + "Joypad to USB converter", + "EMS Trio Linker", + AutoMappingEntry( 0, JOY_BUTTON_16, /* dpad L */ DANCE_BUTTON_LEFT, false ), + AutoMappingEntry( 0, JOY_BUTTON_14, /* dpad R */ DANCE_BUTTON_RIGHT, false ), + AutoMappingEntry( 0, JOY_BUTTON_13, /* dpad U */ DANCE_BUTTON_UP, false ), + AutoMappingEntry( 0, JOY_BUTTON_15, /* dpad D */ DANCE_BUTTON_DOWN, false ), + //AutoMappingEntry{ 0, JOY_BUTTON_5, /* Tri */ GAME_BUTTON_BACK, false ), + //AutoMappingEntry{ 0, JOY_BUTTON_6, /* Square */ GAME_BUTTON_BACK, false ), + //AutoMappingEntry{ 1, JOY_BUTTON_7, /* X */ GAME_BUTTON_START, false ), + AutoMappingEntry( 0, JOY_BUTTON_2, /* O */ GAME_BUTTON_START, false ), + AutoMappingEntry( 1, JOY_BUTTON_10, /* Start */ GAME_BUTTON_START, false ), + AutoMappingEntry( 0, JOY_BUTTON_9, /* Sel */ GAME_BUTTON_BACK, false ) + ), + AutoMappings( + "dance", + "Positive Gaming Impact USB pad", + "Positive Gaming Impact USB pad", + AutoMappingEntry( 0, JOY_BUTTON_1, /* dpad L */ DANCE_BUTTON_LEFT, false ), + AutoMappingEntry( 0, JOY_BUTTON_4, /* dpad R */ DANCE_BUTTON_RIGHT, false ), + AutoMappingEntry( 0, JOY_BUTTON_3, /* dpad U */ DANCE_BUTTON_UP, false ), + AutoMappingEntry( 0, JOY_BUTTON_2, /* dpad D */ DANCE_BUTTON_DOWN, false ), + //AutoMappingEntry{ 0, JOY_BUTTON_5, /* Tri */ GAME_BUTTON_BACK, false ), + //AutoMappingEntry{ 0, JOY_BUTTON_6, /* Square */ GAME_BUTTON_BACK, false ), + AutoMappingEntry( 0, JOY_BUTTON_7, /* X */ DANCE_BUTTON_UPLEFT, false ), + AutoMappingEntry( 0, JOY_BUTTON_8, /* O */ DANCE_BUTTON_UPRIGHT, false ), + AutoMappingEntry( 1, JOY_BUTTON_9, /* Start */ GAME_BUTTON_START, false ), + AutoMappingEntry( 0, JOY_BUTTON_10, /* Sel */ GAME_BUTTON_BACK, false ) + ), + AutoMappings( + "dance", + "USB Dance Pad", + "DDRGame Energy Dance Pad", + AutoMappingEntry( 0, JOY_BUTTON_13, DANCE_BUTTON_UP, false ), + AutoMappingEntry( 0, JOY_BUTTON_15, DANCE_BUTTON_DOWN, false ), + AutoMappingEntry( 0, JOY_BUTTON_16, DANCE_BUTTON_LEFT, false ), + AutoMappingEntry( 0, JOY_BUTTON_14, DANCE_BUTTON_RIGHT, false ), + AutoMappingEntry( 0, JOY_BUTTON_3, DANCE_BUTTON_UPLEFT, false ), + AutoMappingEntry( 0, JOY_BUTTON_2, DANCE_BUTTON_UPRIGHT, false ), + //AutoMappingEntry{ 0, JOY_BUTTON_1, DANCE_BUTTON_DOWNLEFT, false ), + //AutoMappingEntry{ 0, JOY_BUTTON_4, DANCE_BUTTON_DOWNRIGHT, false ), + AutoMappingEntry( 0, JOY_BUTTON_9, GAME_BUTTON_BACK, false ), + AutoMappingEntry( 0, JOY_BUTTON_10, GAME_BUTTON_START, false ) + ), + AutoMappings( + "dance", + "Dual USB Vibration Joystick", + "PC Multi Hub Double Power Box 4", + AutoMappingEntry( 0, JOY_BUTTON_13, DANCE_BUTTON_UP, false ), + AutoMappingEntry( 0, JOY_BUTTON_15, DANCE_BUTTON_DOWN, false ), + AutoMappingEntry( 0, JOY_BUTTON_16, DANCE_BUTTON_LEFT, false ), + AutoMappingEntry( 0, JOY_BUTTON_14, DANCE_BUTTON_RIGHT, false ), + AutoMappingEntry( 0, JOY_BUTTON_3, DANCE_BUTTON_UPLEFT, false ), + AutoMappingEntry( 0, JOY_BUTTON_2, DANCE_BUTTON_UPRIGHT, false ), + //AutoMappingEntry{ 0, JOY_BUTTON_1, DANCE_BUTTON_DOWNLEFT, false ), + //AutoMappingEntry{ 0, JOY_BUTTON_4, DANCE_BUTTON_DOWNRIGHT, false ), + AutoMappingEntry( 0, JOY_BUTTON_9, GAME_BUTTON_BACK, false ), + AutoMappingEntry( 0, JOY_BUTTON_10, GAME_BUTTON_START, false ) + ), + AutoMappings( + "dance", + "Controller \\(Harmonix Drum Kit for Xbox 360\\)", + "Rock Band drum controller (Xbox 360, Windows driver)", + AutoMappingEntry( 0, JOY_BUTTON_3, DANCE_BUTTON_UP, false ), // blue drum + AutoMappingEntry( 0, JOY_BUTTON_4, DANCE_BUTTON_DOWN, false ), // yellow drum + AutoMappingEntry( 0, JOY_BUTTON_2, DANCE_BUTTON_LEFT, false ), // red drum + AutoMappingEntry( 0, JOY_BUTTON_1, DANCE_BUTTON_RIGHT, false ), // green drum + AutoMappingEntry( 0, JOY_HAT_LEFT, GAME_BUTTON_MENULEFT, false ), // d-pad left + AutoMappingEntry( 0, JOY_HAT_RIGHT, GAME_BUTTON_MENURIGHT, false ), // d-pad right + AutoMappingEntry( 0, JOY_HAT_UP, GAME_BUTTON_MENUUP, false ), // d-pad up + AutoMappingEntry( 0, JOY_HAT_DOWN, GAME_BUTTON_MENUDOWN, false ), // d-pad down + AutoMappingEntry( 0, JOY_BUTTON_8, GAME_BUTTON_START, false ), // start button + AutoMappingEntry( 0, JOY_BUTTON_7, GAME_BUTTON_BACK, false ) // back button + ), + AutoMappings( + "pump", + "Pump USB", + "Pump USB pad", + AutoMappingEntry( 0, JOY_BUTTON_1, PUMP_BUTTON_UPLEFT, false ), + AutoMappingEntry( 0, JOY_BUTTON_2, PUMP_BUTTON_UPRIGHT, false ), + AutoMappingEntry( 0, JOY_BUTTON_3, PUMP_BUTTON_CENTER, false ), + AutoMappingEntry( 0, JOY_BUTTON_4, PUMP_BUTTON_DOWNLEFT, false ), + AutoMappingEntry( 0, JOY_BUTTON_5, PUMP_BUTTON_DOWNRIGHT, false ), + AutoMappingEntry( 0, JOY_BUTTON_6, GAME_BUTTON_BACK, false ), + AutoMappingEntry( 0, JOY_BUTTON_7, PUMP_BUTTON_UPLEFT, true ), + AutoMappingEntry( 0, JOY_BUTTON_8, PUMP_BUTTON_UPRIGHT, true ), + AutoMappingEntry( 0, JOY_BUTTON_9, PUMP_BUTTON_CENTER, true ), + AutoMappingEntry( 0, JOY_BUTTON_10, PUMP_BUTTON_DOWNLEFT, true ), + AutoMappingEntry( 0, JOY_BUTTON_11, PUMP_BUTTON_DOWNRIGHT, true ) + ), + AutoMappings( + "pump", + "GamePad Pro USB ", // yes, there is a space at the end + "GamePad Pro USB", + AutoMappingEntry( 0, JOY_BUTTON_5, PUMP_BUTTON_UPLEFT, false ), + AutoMappingEntry( 0, JOY_BUTTON_6, PUMP_BUTTON_UPRIGHT, false ), + AutoMappingEntry( 0, JOY_BUTTON_7, PUMP_BUTTON_DOWNLEFT, false ), + AutoMappingEntry( 0, JOY_BUTTON_8, PUMP_BUTTON_DOWNRIGHT, false ), + AutoMappingEntry( 0, JOY_LEFT, GAME_BUTTON_MENULEFT, false ), + AutoMappingEntry( 0, JOY_RIGHT, GAME_BUTTON_MENURIGHT, false ), + AutoMappingEntry( 0, JOY_UP, GAME_BUTTON_MENUUP, false ), + AutoMappingEntry( 0, JOY_DOWN, GAME_BUTTON_MENUDOWN, false ), + AutoMappingEntry( 1, JOY_BUTTON_1, PUMP_BUTTON_CENTER, false ), + AutoMappingEntry( 0, JOY_BUTTON_9, GAME_BUTTON_BACK, false ), + AutoMappingEntry( 0, JOY_BUTTON_10, GAME_BUTTON_START, false ) + ), + AutoMappings( + "pump", + "Controller \\(Harmonix Drum Kit for Xbox 360\\)", + "Rock Band drum controller (Xbox 360, Windows driver)", + AutoMappingEntry( 0, JOY_BUTTON_5, PUMP_BUTTON_CENTER, false ), // bass pedal + AutoMappingEntry( 0, JOY_BUTTON_3, PUMP_BUTTON_UPRIGHT, false ), // blue drum + AutoMappingEntry( 0, JOY_BUTTON_4, PUMP_BUTTON_UPLEFT, false ), // yellow drum + AutoMappingEntry( 0, JOY_BUTTON_2, PUMP_BUTTON_DOWNLEFT, false ), // red drum + AutoMappingEntry( 0, JOY_BUTTON_1, PUMP_BUTTON_DOWNRIGHT, false ), // green drum + AutoMappingEntry( 0, JOY_HAT_LEFT, GAME_BUTTON_MENULEFT, false ), // d-pad left + AutoMappingEntry( 0, JOY_HAT_RIGHT, GAME_BUTTON_MENURIGHT, false ), // d-pad right + AutoMappingEntry( 0, JOY_HAT_UP, GAME_BUTTON_MENUUP, false ), // d-pad up + AutoMappingEntry( 0, JOY_HAT_DOWN, GAME_BUTTON_MENUDOWN, false ), // d-pad down + AutoMappingEntry( 0, JOY_BUTTON_8, GAME_BUTTON_START, false ), // start button + AutoMappingEntry( 0, JOY_BUTTON_7, GAME_BUTTON_BACK, false ) // back button + ), + AutoMappings( + "para", + "ParaParaParadise Controller", + "ParaParaParadise Controller", + AutoMappingEntry( 0, JOY_BUTTON_5, PARA_BUTTON_LEFT, false ), + AutoMappingEntry( 0, JOY_BUTTON_4, PARA_BUTTON_UPLEFT, false ), + AutoMappingEntry( 0, JOY_BUTTON_3, PARA_BUTTON_UP, false ), + AutoMappingEntry( 0, JOY_BUTTON_2, PARA_BUTTON_UPRIGHT, false ), + AutoMappingEntry( 0, JOY_BUTTON_1, PARA_BUTTON_RIGHT, false ), + AutoMappingEntry( 0, JOY_BUTTON_10, GAME_BUTTON_START, false ), + AutoMappingEntry( 0, JOY_BUTTON_11, GAME_BUTTON_BACK, false ), + AutoMappingEntry( 0, JOY_BUTTON_12, GAME_BUTTON_MENULEFT, false ), + AutoMappingEntry( 0, JOY_BUTTON_9, GAME_BUTTON_MENURIGHT, false ) + ), + AutoMappings( + "techno", + "Dance ", //Notice the extra space at end + "LevelSix USB Pad (DDR638)", // "DDR638" is the model number of the pad + AutoMappingEntry( 0, JOY_BUTTON_1, TECHNO_BUTTON_UP, false ), + AutoMappingEntry( 0, JOY_BUTTON_2, TECHNO_BUTTON_DOWN, false ), + AutoMappingEntry( 0, JOY_BUTTON_3, TECHNO_BUTTON_LEFT, false ), + AutoMappingEntry( 0, JOY_BUTTON_4, TECHNO_BUTTON_RIGHT, false ), + AutoMappingEntry( 0, JOY_BUTTON_5, TECHNO_BUTTON_DOWNRIGHT,false ), + AutoMappingEntry( 0, JOY_BUTTON_6, TECHNO_BUTTON_DOWNLEFT, false ), + AutoMappingEntry( 0, JOY_BUTTON_7, TECHNO_BUTTON_UPRIGHT, false ), + AutoMappingEntry( 0, JOY_BUTTON_8, TECHNO_BUTTON_UPLEFT, false ), + AutoMappingEntry( 0, JOY_BUTTON_9, GAME_BUTTON_BACK, false ), + AutoMappingEntry( 0, JOY_BUTTON_10, GAME_BUTTON_START, false ) + ), +}; + +void InputMapper::Unmap( InputDevice id ) +{ + m_mappings.Unmap( id ); + + UpdateTempDItoGI(); +} + +void InputMapper::ApplyMapping( const vector &vMmaps, GameController gc, InputDevice id ) +{ + map MappedButtons; + FOREACH_CONST( AutoMappingEntry, vMmaps, iter ) + { + GameController map_gc = gc; + if( iter->m_bSecondController ) + { + map_gc = (GameController)(map_gc+1); + + /* If that pushed it over, then it's a second controller for a joystick + * that's already a second controller, so we'll just ignore it. (This + * can happen if eg. two primary Pump pads are connected.) */ + if( map_gc >= NUM_GameController ) + continue; + } + + DeviceInput di( id, iter->m_deviceButton ); + GameInput gi( map_gc, iter->m_gb ); + int iSlot = MappedButtons[gi]; + ++MappedButtons[gi]; + SetInputMap( di, gi, iSlot );//maps[k].iSlotIndex ); + } +} + +void InputMapper::AutoMapJoysticksForCurrentGame() +{ + vector vDevices; + INPUTMAN->GetDevicesAndDescriptions(vDevices); + + // fill vector with all auto mappings + vector vAutoMappings; + { + // file automaps - Add these first so that they can match before the hard-coded mappings + vector vs; + GetDirListing( AUTOMAPPINGS_DIR "*.ini", vs, false, true ); + FOREACH_CONST( RString, vs, sFilePath ) + { + InputMappings km; + km.ReadMappings( m_pInputScheme, *sFilePath, true ); + + AutoMappings mapping( m_pInputScheme->m_szName, km.m_sDeviceRegex, km.m_sDescription ); + + FOREACH_ENUM( GameController, c ) + { + FOREACH_ENUM( GameButton, b ) + { + for( int s=0; s GameController_1 ); + mapping.m_vMaps.push_back( im ); + } + } + } + + vAutoMappings.push_back( mapping ); + } + + // hard-coded automaps + for( unsigned j=0; jm_szName) ) + vAutoMappings.push_back( mapping ); + } + } + + + // apply auto mappings + int iNumJoysticksMapped = 0; + FOREACH_CONST( InputDeviceInfo, vDevices, device ) + { + InputDevice id = device->id; + const RString &sDescription = device->sDesc; + FOREACH_CONST( AutoMappings, vAutoMappings, mapping ) + { + Regex regex( mapping->m_sDriverRegex ); + if( !regex.Compare(sDescription) ) + continue; // driver names don't match + + // We have a mapping for this joystick + GameController gc = (GameController)iNumJoysticksMapped; + if( gc >= NUM_GameController ) + break; // stop mapping. We already mapped one device for each game controller. + + LOG->Info( "Applying default joystick mapping #%d for device '%s' (%s)", + iNumJoysticksMapped+1, mapping->m_sDriverRegex.c_str(), mapping->m_sControllerName.c_str() ); + + Unmap( id ); + ApplyMapping( mapping->m_vMaps, gc, id ); + + iNumJoysticksMapped++; + } + } +} + +void InputMapper::SetInputScheme( const InputScheme *pInputScheme ) +{ + m_pInputScheme = pInputScheme; + + ReadMappingsFromDisk(); +} + +const InputScheme *InputMapper::GetInputScheme() const +{ + return m_pInputScheme; +} + +static const RString DEVICE_INPUT_SEPARATOR = ":"; // this isn't used in any key names + +void InputMapper::ReadMappingsFromDisk() +{ + m_mappings.ReadMappings( m_pInputScheme, SpecialFiles::KEYMAPS_PATH, false ); + UpdateTempDItoGI(); + + AddDefaultMappingsForCurrentGameIfUnmapped(); +} + +void InputMapper::SaveMappingsToDisk() +{ + m_mappings.WriteMappings( m_pInputScheme, SpecialFiles::KEYMAPS_PATH ); +} + +static LocalizedString CONNECTED ( "InputMapper", "Connected" ); +static LocalizedString DISCONNECTED ( "InputMapper", "Disconnected" ); +static LocalizedString AUTOMAPPING_ALL_JOYSTICKS ( "InputMapper", "Auto-mapping all joysticks." ); +bool InputMapper::CheckForChangedInputDevicesAndRemap( RString &sMessageOut ) +{ + // Only check for changes in joysticks since that's all we know how to remap. + + // update last seen joysticks + vector vDevices; + INPUTMAN->GetDevicesAndDescriptions( vDevices ); + + // Strip non-joysticks. + vector vsLastSeenJoysticks; + // Don't use "," since some vendors have a name like "company Ltd., etc". + // For now, use a pipe character. -aj, fix from Mordae. + split( g_sLastSeenInputDevices, "|", vsLastSeenJoysticks ); + + vector vsCurrent; + vector vsCurrentJoysticks; + for( int i=vDevices.size()-1; i>=0; i-- ) + { + vsCurrent.push_back( vDevices[i].sDesc ); + if( IsJoystick(vDevices[i].id) ) + { + vsCurrentJoysticks.push_back( vDevices[i].sDesc ); + } + else + { + vector::iterator iter = find( vsLastSeenJoysticks.begin(), vsLastSeenJoysticks.end(), vDevices[i].sDesc ); + if( iter != vsLastSeenJoysticks.end() ) + vsLastSeenJoysticks.erase( iter ); + } + } + + bool bJoysticksChanged = vsCurrentJoysticks != vsLastSeenJoysticks; + if( !bJoysticksChanged ) + return false; + + vector vsConnects, vsDisconnects; + GetConnectsDisconnects( vsLastSeenJoysticks, vsCurrentJoysticks, vsDisconnects, vsConnects ); + + sMessageOut = RString(); + if( !vsConnects.empty() ) + sMessageOut += CONNECTED.GetValue()+": " + join( "\n", vsConnects ) + "\n"; + if( !vsDisconnects.empty() ) + sMessageOut += DISCONNECTED.GetValue()+": " + join( "\n", vsDisconnects ) + "\n"; + + if( g_bAutoMapOnJoyChange ) + { + sMessageOut += AUTOMAPPING_ALL_JOYSTICKS.GetValue(); + AutoMapJoysticksForCurrentGame(); + SaveMappingsToDisk(); + MESSAGEMAN->Broadcast( Message_AutoJoyMappingApplied ); + } + + LOG->Info( "%s", sMessageOut.c_str() ); + + // see above comment about not using ",". -aj + g_sLastSeenInputDevices.Set( join("|",vsCurrent) ); + PREFSMAN->SavePrefsToDisk(); + + return true; +} + +void InputMapper::SetInputMap( const DeviceInput &DeviceI, const GameInput &GameI, int iSlotIndex ) +{ + m_mappings.SetInputMap( DeviceI, GameI, iSlotIndex ); + + UpdateTempDItoGI(); +} + +void InputMapper::ClearFromInputMap( const DeviceInput &DeviceI ) +{ + m_mappings.ClearFromInputMap( DeviceI ); + + UpdateTempDItoGI(); +} + +bool InputMapper::ClearFromInputMap( const GameInput &GameI, int iSlotIndex ) +{ + if( !m_mappings.ClearFromInputMap(GameI, iSlotIndex) ) + return false; + + UpdateTempDItoGI(); + return true; +} + +bool InputMapper::IsMapped( const DeviceInput &DeviceI ) const +{ + return g_tempDItoGI.find(DeviceI) != g_tempDItoGI.end(); +} + +void InputMapper::UpdateTempDItoGI() +{ + // repopulate g_tempDItoGI + g_tempDItoGI.clear(); + FOREACH_ENUM( GameController, n ) + { + FOREACH_ENUM( GameButton, b ) + { + for( int s=0; sGameButtonToMenuButton( gb ); +} + +/* If set (not PLAYER_INVALID), inputs from both GameControllers will be mapped + * to the specified player. If PLAYER_INVALID, GameControllers will be mapped + * individually. */ +void InputMapper::SetJoinControllers( PlayerNumber pn ) +{ + g_JoinControllers = pn; +} + + +void InputMapper::MenuToGame( GameButton MenuI, PlayerNumber pn, vector &GameIout ) const +{ + if( g_JoinControllers != PLAYER_INVALID ) + pn = PLAYER_INVALID; + + m_pInputScheme->MenuButtonToGameInputs( MenuI, pn, GameIout ); +} + + +bool InputMapper::IsBeingPressed( const GameInput &GameI, MultiPlayer mp, const DeviceInputList *pButtonState ) const +{ + for( int i=0; iIsBeingPressed(DeviceI, pButtonState) ) + return true; + } + } + + return false; +} + +bool InputMapper::IsBeingPressed( GameButton MenuI, PlayerNumber pn ) const +{ + vector GameI; + MenuToGame( MenuI, pn, GameI ); + for( size_t i=0; iRepeatStopKey( DeviceI ); + } +} + +void InputMapper::RepeatStopKey( GameButton MenuI, PlayerNumber pn ) +{ + vector GameI; + MenuToGame( MenuI, pn, GameI ); + for( size_t i=0; iGetSecsHeld(DeviceI) ); + } + } + + return fMaxSecsHeld; +} + +float InputMapper::GetSecsHeld( GameButton MenuI, PlayerNumber pn ) const +{ + float fMaxSecsHeld = 0; + + vector GameI; + MenuToGame( MenuI, pn, GameI ); + for( size_t i=0; iResetKeyRepeat( DeviceI ); + } +} + +void InputMapper::ResetKeyRepeat( GameButton MenuI, PlayerNumber pn ) +{ + vector GameI; + MenuToGame( MenuI, pn, GameI ); + for( size_t i=0; iGetLevel(DeviceI) ); + } + return fLevel; +} + +float InputMapper::GetLevel( GameButton MenuI, PlayerNumber pn ) const +{ + vector GameI; + MenuToGame( MenuI, pn, GameI ); + + float fLevel = 0; + for( size_t i=0; i &GameIout ) const +{ + ASSERT( MenuI != GameButton_Invalid ); + + vector aGameButtons; + MenuButtonToGameButtons( MenuI, aGameButtons ); + FOREACH( GameButton, aGameButtons, gb ) + { + if( pn == PLAYER_INVALID ) + { + GameIout.push_back( GameInput(GameController_1, *gb) ); + GameIout.push_back( GameInput(GameController_2, *gb) ); + } + else + { + GameIout.push_back( GameInput((GameController)pn, *gb) ); + } + } +} + +void InputScheme::MenuButtonToGameButtons( GameButton MenuI, vector &aGameButtons ) const +{ + ASSERT( MenuI != GameButton_Invalid ); + + if( MenuI == GameButton_Invalid ) + return; + + FOREACH_ENUM( GameButton, gb) + { + if( PREFSMAN->m_bOnlyDedicatedMenuButtons && gb >= GAME_BUTTON_NEXT ) + break; + + const GameButtonInfo *pGameButtonInfo = GetGameButtonInfo( gb ); + if( pGameButtonInfo->m_SecondaryMenuButton != MenuI ) + continue; + aGameButtons.push_back( gb ); + } +} + +GameButton InputScheme::GameButtonToMenuButton( GameButton gb ) const +{ + if( gb == GameButton_Invalid ) + return GameButton_Invalid; + if( gb >= GAME_BUTTON_NEXT && PREFSMAN->m_bOnlyDedicatedMenuButtons ) + return GameButton_Invalid; + return GetGameButtonInfo(gb)->m_SecondaryMenuButton; +} + +static const InputScheme::GameButtonInfo g_CommonGameButtonInfo[] = +{ + { "MenuLeft", GAME_BUTTON_MENULEFT }, + { "MenuRight", GAME_BUTTON_MENURIGHT }, + { "MenuUp", GAME_BUTTON_MENUUP }, + { "MenuDown", GAME_BUTTON_MENUDOWN }, + { "Start", GAME_BUTTON_START }, + { "Select", GAME_BUTTON_SELECT }, + { "Back", GAME_BUTTON_BACK }, + { "Coin", GAME_BUTTON_COIN }, + { "Operator", GAME_BUTTON_OPERATOR }, + { "EffectUp", GAME_BUTTON_EFFECT_UP }, + { "EffectDown", GAME_BUTTON_EFFECT_DOWN }, +}; + +const InputScheme::GameButtonInfo *InputScheme::GetGameButtonInfo( GameButton gb ) const +{ + COMPILE_ASSERT( GAME_BUTTON_NEXT == ARRAYLEN(g_CommonGameButtonInfo) ); + if( gb < GAME_BUTTON_NEXT ) + return &g_CommonGameButtonInfo[gb]; + else + return &m_GameButtonInfo[gb-GAME_BUTTON_NEXT]; +} + +const char *InputScheme::GetGameButtonName( GameButton gb ) const +{ + if( gb == GameButton_Invalid ) + return ""; + return GetGameButtonInfo(gb)->m_szName; +} + +void InputMappings::Clear() +{ + FOREACH_ENUM( GameController, i ) + FOREACH_ENUM( GameButton, j) + for( int k=0; kTrace( "Couldn't open mapping file \"%s\": %s.", + SpecialFiles::KEYMAPS_PATH.c_str(), ini.GetError().c_str() ); + + if( bIsAutoMapping ) + { + if( !ini.GetValue( "AutoMapping", "DeviceRegex", m_sDeviceRegex ) ) + Dialog::OK( "Missing AutoMapping::DeviceRegex in '%s'", sFilePath.c_str() ); + + if( !ini.GetValue( "AutoMapping", "Description", m_sDescription ) ) + Dialog::OK( "Missing AutoMapping::Description in '%s'", sFilePath.c_str() ); + } + + const XNode *Key = ini.GetChild( pInputScheme->m_szName ); + + if( Key ) + { + FOREACH_CONST_Attr( Key, i ) + { + const RString &name = i->first; + RString value; + i->second->GetValue( value ); + + GameInput GameI; + GameI.FromString( pInputScheme, name ); + if( !GameI.IsValid() ) + continue; + + vector sDeviceInputStrings; + split( value, DEVICE_INPUT_SEPARATOR, sDeviceInputStrings, false ); + + for( unsigned j=0; jm_szName ); + + XNode *pKey = ini.GetChild( pInputScheme->m_szName ); + if( pKey != NULL ) + ini.RemoveChild( pKey ); + pKey = ini.AppendChild( pInputScheme->m_szName ); + + // iterate over our input map and write all mappings to the ini file + FOREACH_ENUM( GameController, i ) + { + FOREACH_GameButtonInScheme( pInputScheme, j ) + { + GameInput GameI( i, j ); + RString sNameString = GameI.ToString( pInputScheme ); + + vector asValues; + for( int slot = 0; slot < NUM_USER_GAME_TO_DEVICE_SLOTS; ++slot ) // don't save data from the last (keyboard automap) slot + asValues.push_back( m_GItoDI[i][j][slot].ToString() ); + + while( asValues.size() && asValues.back() == "" ) + asValues.erase( asValues.begin()+asValues.size()-1 ); + + RString sValueString = join( DEVICE_INPUT_SEPARATOR, asValues ); + + pKey->AppendAttr( sNameString, sValueString ); + } + } + + ini.WriteFile( sFilePath ); +} + +void InputMappings::SetInputMap( const DeviceInput &DeviceI, const GameInput &GameI, int iSlotIndex ) +{ + // remove the old input + ClearFromInputMap( DeviceI ); + ClearFromInputMap( GameI, iSlotIndex ); + + ASSERT_M( GameI.controller < NUM_GameController, + ssprintf("controller: %u >= %u", GameI.controller, NUM_GameController) ); + ASSERT_M( GameI.button < NUM_GameButton, + ssprintf("button: %u >= %u", GameI.button, NUM_GameButton) ); + ASSERT_M( iSlotIndex < NUM_GAME_TO_DEVICE_SLOTS, + ssprintf("slot: %u >= %u", iSlotIndex, NUM_GAME_TO_DEVICE_SLOTS) ); + m_GItoDI[GameI.controller][GameI.button][iSlotIndex] = DeviceI; +} + +void InputMappings::ClearFromInputMap( const DeviceInput &DeviceI ) +{ + // search for where this DeviceI maps to + + FOREACH_ENUM( GameController, p ) + { + FOREACH_ENUM( GameButton, b) + { + for( int s=0; s