diff --git a/Common/KeyMap.cpp b/Common/KeyMap.cpp index f40fa81710..ceca63ba12 100644 --- a/Common/KeyMap.cpp +++ b/Common/KeyMap.cpp @@ -29,58 +29,60 @@ struct DefaultKeyMap { static KeyMapping defaultKeyboardMap() { KeyMapping m; - m[KeyDef(DEVICE_ID_KEYBOARD, NKCODE_A)] = CTRL_SQUARE; - m[KeyDef(DEVICE_ID_KEYBOARD, NKCODE_S)] = CTRL_TRIANGLE; - m[KeyDef(DEVICE_ID_KEYBOARD, NKCODE_X)] = CTRL_CIRCLE; - m[KeyDef(DEVICE_ID_KEYBOARD, NKCODE_Z)] = CTRL_CROSS; - m[KeyDef(DEVICE_ID_KEYBOARD, NKCODE_Q)] = CTRL_LTRIGGER; - m[KeyDef(DEVICE_ID_KEYBOARD, NKCODE_W)] = CTRL_RTRIGGER; - m[KeyDef(DEVICE_ID_KEYBOARD, NKCODE_SPACE)] = CTRL_START; + m[CTRL_SQUARE] = KeyDef(DEVICE_ID_KEYBOARD, NKCODE_A); + m[CTRL_TRIANGLE] = KeyDef(DEVICE_ID_KEYBOARD, NKCODE_S); + m[CTRL_CIRCLE] = KeyDef(DEVICE_ID_KEYBOARD, NKCODE_X); + m[CTRL_CROSS] = KeyDef(DEVICE_ID_KEYBOARD, NKCODE_Z); + m[CTRL_LTRIGGER] = KeyDef(DEVICE_ID_KEYBOARD, NKCODE_Q); + m[CTRL_RTRIGGER] = KeyDef(DEVICE_ID_KEYBOARD, NKCODE_W); + + m[CTRL_START] = KeyDef(DEVICE_ID_KEYBOARD, NKCODE_SPACE); #ifdef _WIN32 - m[KeyDef(DEVICE_ID_KEYBOARD, NKCODE_V)] = CTRL_SELECT; + m[CTRL_SELECT] = KeyDef(DEVICE_ID_KEYBOARD, NKCODE_V); #else - m[KeyDef(DEVICE_ID_KEYBOARD, NKCODE_ENTER)] = CTRL_SELECT; + m[CTRL_SELECT]; = KeyDef(DEVICE_ID_KEYBOARD, NKCODE_ENTER); #endif - m[KeyDef(DEVICE_ID_KEYBOARD, NKCODE_DPAD_UP)] = CTRL_UP; - m[KeyDef(DEVICE_ID_KEYBOARD, NKCODE_DPAD_DOWN)] = CTRL_DOWN; - m[KeyDef(DEVICE_ID_KEYBOARD, NKCODE_DPAD_LEFT)] = CTRL_LEFT; - m[KeyDef(DEVICE_ID_KEYBOARD, NKCODE_DPAD_RIGHT)] = CTRL_RIGHT; - m[KeyDef(DEVICE_ID_KEYBOARD, NKCODE_I)] = VIRTKEY_AXIS_Y_MAX; - m[KeyDef(DEVICE_ID_KEYBOARD, NKCODE_K)] = VIRTKEY_AXIS_Y_MIN; - m[KeyDef(DEVICE_ID_KEYBOARD, NKCODE_J)] = VIRTKEY_AXIS_X_MIN; - m[KeyDef(DEVICE_ID_KEYBOARD, NKCODE_L)] = VIRTKEY_AXIS_X_MAX; - m[KeyDef(DEVICE_ID_KEYBOARD, NKCODE_SHIFT_LEFT)] = VIRTKEY_RAPID_FIRE; - m[KeyDef(DEVICE_ID_KEYBOARD, NKCODE_TAB)] = VIRTKEY_UNTHROTTLE; - m[KeyDef(DEVICE_ID_KEYBOARD, NKCODE_GRAVE)] = VIRTKEY_SPEED_TOGGLE; - m[KeyDef(DEVICE_ID_KEYBOARD, NKCODE_ESCAPE)] = VIRTKEY_PAUSE; + m[CTRL_UP ] = KeyDef(DEVICE_ID_KEYBOARD, NKCODE_DPAD_UP) ; + m[CTRL_DOWN ] = KeyDef(DEVICE_ID_KEYBOARD, NKCODE_DPAD_DOWN) ; + m[CTRL_LEFT ] = KeyDef(DEVICE_ID_KEYBOARD, NKCODE_DPAD_LEFT) ; + m[CTRL_RIGHT] = KeyDef(DEVICE_ID_KEYBOARD, NKCODE_DPAD_RIGHT); + m[VIRTKEY_AXIS_Y_MAX] = KeyDef(DEVICE_ID_KEYBOARD, NKCODE_I); + m[VIRTKEY_AXIS_Y_MIN] = KeyDef(DEVICE_ID_KEYBOARD, NKCODE_K); + m[VIRTKEY_AXIS_X_MIN] = KeyDef(DEVICE_ID_KEYBOARD, NKCODE_J); + m[VIRTKEY_AXIS_X_MAX] = KeyDef(DEVICE_ID_KEYBOARD, NKCODE_L); + m[VIRTKEY_RAPID_FIRE ] = KeyDef(DEVICE_ID_KEYBOARD, NKCODE_SHIFT_LEFT); + m[VIRTKEY_UNTHROTTLE ] = KeyDef(DEVICE_ID_KEYBOARD, NKCODE_TAB) ; + m[VIRTKEY_SPEED_TOGGLE] = KeyDef(DEVICE_ID_KEYBOARD, NKCODE_GRAVE) ; + m[VIRTKEY_PAUSE ] = KeyDef(DEVICE_ID_KEYBOARD, NKCODE_ESCAPE) ; return m; } static KeyMapping default360Map() { KeyMapping m; - m[KeyDef(DEVICE_ID_X360_0, NKCODE_BUTTON_A)] = CTRL_CROSS; - m[KeyDef(DEVICE_ID_X360_0, NKCODE_BUTTON_B)] = CTRL_CIRCLE; - m[KeyDef(DEVICE_ID_X360_0, NKCODE_BUTTON_X)] = CTRL_SQUARE; - m[KeyDef(DEVICE_ID_X360_0, NKCODE_BUTTON_Y)] = CTRL_TRIANGLE; - m[KeyDef(DEVICE_ID_X360_0, NKCODE_DPAD_UP)] = CTRL_UP; - m[KeyDef(DEVICE_ID_X360_0, NKCODE_DPAD_RIGHT)] = CTRL_RIGHT; - m[KeyDef(DEVICE_ID_X360_0, NKCODE_DPAD_DOWN)] = CTRL_DOWN; - m[KeyDef(DEVICE_ID_X360_0, NKCODE_DPAD_LEFT)] = CTRL_LEFT; - m[KeyDef(DEVICE_ID_X360_0, NKCODE_BUTTON_START)] = CTRL_START; - m[KeyDef(DEVICE_ID_X360_0, NKCODE_BUTTON_SELECT)] = CTRL_SELECT; - m[KeyDef(DEVICE_ID_X360_0, NKCODE_BUTTON_L1)] = CTRL_LTRIGGER; - m[KeyDef(DEVICE_ID_X360_0, NKCODE_BUTTON_R1)] = CTRL_RTRIGGER; - m[KeyDef(DEVICE_ID_X360_0, NKCODE_BUTTON_R2)] = VIRTKEY_UNTHROTTLE; - m[KeyDef(DEVICE_ID_X360_0, NKCODE_BUTTON_THUMBR)] = VIRTKEY_PAUSE; - m[KeyDef(DEVICE_ID_X360_0, NKCODE_BUTTON_L2)] = VIRTKEY_SPEED_TOGGLE; - m[AxisDef(DEVICE_ID_X360_0, JOYSTICK_AXIS_X, -1)] = VIRTKEY_AXIS_X_MIN; - m[AxisDef(DEVICE_ID_X360_0, JOYSTICK_AXIS_X, +1)] = VIRTKEY_AXIS_X_MAX; - m[AxisDef(DEVICE_ID_X360_0, JOYSTICK_AXIS_Y, -1)] = VIRTKEY_AXIS_Y_MIN; - m[AxisDef(DEVICE_ID_X360_0, JOYSTICK_AXIS_Y, +1)] = VIRTKEY_AXIS_Y_MAX; + m[CTRL_CROSS ] = KeyDef(DEVICE_ID_X360_0, NKCODE_BUTTON_A) ; + m[CTRL_CIRCLE ] = KeyDef(DEVICE_ID_X360_0, NKCODE_BUTTON_B) ; + m[CTRL_SQUARE ] = KeyDef(DEVICE_ID_X360_0, NKCODE_BUTTON_X) ; + m[CTRL_TRIANGLE ] = KeyDef(DEVICE_ID_X360_0, NKCODE_BUTTON_Y) ; + m[CTRL_UP ] = KeyDef(DEVICE_ID_X360_0, NKCODE_DPAD_UP) ; + m[CTRL_RIGHT ] = KeyDef(DEVICE_ID_X360_0, NKCODE_DPAD_RIGHT) ; + m[CTRL_DOWN ] = KeyDef(DEVICE_ID_X360_0, NKCODE_DPAD_DOWN) ; + m[CTRL_LEFT ] = KeyDef(DEVICE_ID_X360_0, NKCODE_DPAD_LEFT) ; + m[CTRL_START ] = KeyDef(DEVICE_ID_X360_0, NKCODE_BUTTON_START) ; + m[CTRL_SELECT ] = KeyDef(DEVICE_ID_X360_0, NKCODE_BUTTON_SELECT); + m[CTRL_LTRIGGER ] = KeyDef(DEVICE_ID_X360_0, NKCODE_BUTTON_L1) ; + m[CTRL_RTRIGGER ] = KeyDef(DEVICE_ID_X360_0, NKCODE_BUTTON_R1) ; + m[VIRTKEY_UNTHROTTLE ] = KeyDef(DEVICE_ID_X360_0, NKCODE_BUTTON_R2) ; + m[VIRTKEY_PAUSE ] = KeyDef(DEVICE_ID_X360_0, NKCODE_BUTTON_THUMBR); + m[VIRTKEY_SPEED_TOGGLE] = KeyDef(DEVICE_ID_X360_0, NKCODE_BUTTON_L2) ; + m[VIRTKEY_AXIS_X_MIN ] = AxisDef(DEVICE_ID_X360_0, JOYSTICK_AXIS_X, -1); + m[VIRTKEY_AXIS_X_MAX ] = AxisDef(DEVICE_ID_X360_0, JOYSTICK_AXIS_X, +1); + m[VIRTKEY_AXIS_Y_MIN ] = AxisDef(DEVICE_ID_X360_0, JOYSTICK_AXIS_Y, -1); + m[VIRTKEY_AXIS_Y_MAX ] = AxisDef(DEVICE_ID_X360_0, JOYSTICK_AXIS_Y, +1); return m; } + /* // Not used yet, will autodetect later static KeyMapping defaultShieldMap() { @@ -172,11 +174,15 @@ struct DefaultKeyMap { m[AxisDef(DEVICE_ID_DEFAULT, JOYSTICK_AXIS_Y, +1)] = VIRTKEY_AXIS_Y_MAX; return m; } + */ - static std::vector init() + + static ControllerMap init() { - std::vector m; + ControllerMap m; + m.keys = defaultKeyboardMap(); + /* #if defined(USING_GLES2) // Mobile! Only a pad map required, some can use a keyboard map though. // Currently no way to distinguish between external keyboard and qwerty keyboard ('pad'?) @@ -217,13 +223,17 @@ struct DefaultKeyMap { pad.active = false; m.push_back(pad); #endif + */ + return m; } - static std::vector KeyMap; + static ControllerMap KeyMap; }; -std::vector DefaultKeyMap::KeyMap = DefaultKeyMap::init(); +ControllerMap DefaultKeyMap::KeyMap = DefaultKeyMap::init(); + +ControllerMap g_controllerMap; // Key & Button names @@ -231,6 +241,7 @@ struct KeyMap_IntStrPair { int key; std::string name; }; + const KeyMap_IntStrPair key_names[] = { {NKCODE_A, "A"}, {NKCODE_B, "B"}, @@ -433,6 +444,7 @@ const KeyMap_IntStrPair axis_names[] = { }; static std::string unknown_key_name = "??"; + const KeyMap_IntStrPair psp_button_names[] = { {CTRL_CIRCLE, "O"}, {CTRL_CROSS, "X"}, @@ -465,8 +477,7 @@ const KeyMap_IntStrPair psp_button_names[] = { const int AXIS_BIND_NKCODE_START = 4000; -static std::string FindName(int key, const KeyMap_IntStrPair list[], size_t size) -{ +static std::string FindName(int key, const KeyMap_IntStrPair list[], size_t size) { for (size_t i = 0; i < size; i++) if (list[i].key == key) return list[i].name; @@ -474,18 +485,23 @@ static std::string FindName(int key, const KeyMap_IntStrPair list[], size_t size return unknown_key_name; } -std::string GetKeyName(int keyCode) -{ +std::string GetKeyName(int keyCode) { return FindName(keyCode, key_names, ARRAY_SIZE(key_names)); } -std::string GetPspButtonName(int btn) -{ +std::string GetPspButtonName(int btn) { return FindName(btn, psp_button_names, ARRAY_SIZE(psp_button_names)); } -int TranslateKeyCodeToAxis(int keyCode, int &direction) -{ +std::vector GetMappableKeys() { + std::vector temp; + for (size_t i = 0; i < ARRAY_SIZE(psp_button_names); i++) { + temp.push_back(psp_button_names[i]); + } + return temp; +} + +int TranslateKeyCodeToAxis(int keyCode, int &direction) { if (keyCode < AXIS_BIND_NKCODE_START) return 0; int v = keyCode - AXIS_BIND_NKCODE_START; @@ -495,8 +511,7 @@ int TranslateKeyCodeToAxis(int keyCode, int &direction) return v / 2; } -int TranslateKeyCodeFromAxis(int axisId, int direction) -{ +int TranslateKeyCodeFromAxis(int axisId, int direction) { direction = direction < 0 ? 1 : 0; return AXIS_BIND_NKCODE_START + axisId * 2 + direction; } @@ -505,16 +520,11 @@ KeyDef AxisDef(int deviceId, int axisId, int direction) { return KeyDef(deviceId, TranslateKeyCodeFromAxis(axisId, direction)); } - -static bool FindKeyMapping(int deviceId, int key, int *psp_button) -{ - for (size_t i = 0; i < controllerMaps.size(); i++) { - if (!controllerMaps[i].active) - continue; - - auto iter = controllerMaps[i].keys.find(KeyDef(deviceId, key)); - if (iter != controllerMaps[i].keys.end()) { - *psp_button = iter->second; +static bool FindKeyMapping(int deviceId, int key, int *psp_button) { + // Brute force, let's optimize later + for (auto iter = g_controllerMap.keys.begin(); iter != g_controllerMap.keys.end(); ++iter) { + if (iter->second == KeyDef(deviceId, key)) { + *psp_button = iter->first; return true; } } @@ -532,130 +542,126 @@ int KeyToPspButton(int deviceId, int key) return KEYMAP_ERROR_UNKNOWN_KEY; } -bool KeyFromPspButton(int controllerMap, int btn, int *deviceId, int *keyCode) +// TODO: vector output +bool KeyFromPspButton(int btn, int *deviceId, int *keyCode) { int search_start_layer = 0; - for (auto iter = controllerMaps[controllerMap].keys.begin(); iter != controllerMaps[controllerMap].keys.end(); ++iter) { - if (iter->second == btn) { - *deviceId = iter->first.deviceId; - *keyCode = iter->first.keyCode; + for (auto iter = g_controllerMap.keys.begin(); iter != g_controllerMap.keys.end(); ++iter) { + if (iter->first == btn) { + *deviceId = iter->second.deviceId; + *keyCode = iter->second.keyCode; return true; } } return false; } -int AxisToPspButton(int deviceId, int axisId, int direction) -{ +int AxisToPspButton(int deviceId, int axisId, int direction) { int key = TranslateKeyCodeFromAxis(axisId, direction); return KeyToPspButton(deviceId, key); } -bool AxisFromPspButton(int controllerMap, int btn, int *deviceId, int *axisId, int *direction) -{ +bool AxisFromPspButton(int btn, int *deviceId, int *axisId, int *direction) { int search_start_layer = 0; - for (auto iter = controllerMaps[controllerMap].keys.begin(); iter != controllerMaps[controllerMap].keys.end(); ++iter) { - if (iter->second == btn && iter->first.keyCode >= AXIS_BIND_NKCODE_START) { - *deviceId = iter->first.deviceId; - *axisId = TranslateKeyCodeToAxis(iter->first.keyCode, *direction); + for (auto iter = g_controllerMap.keys.begin(); iter != g_controllerMap.keys.end(); ++iter) { + if (iter->first == btn && iter->second.keyCode >= AXIS_BIND_NKCODE_START) { + *deviceId = iter->second.deviceId; + *axisId = TranslateKeyCodeToAxis(iter->second.keyCode, *direction); return true; } } return false; } -std::string NameKeyFromPspButton(int controllerMap, int btn) { +std::string NameKeyFromPspButton(int btn) { int deviceId; int axisId; int direction; int keyCode; - if (AxisFromPspButton(controllerMap, btn, &deviceId, &axisId, &direction)) { + if (AxisFromPspButton(btn, &deviceId, &axisId, &direction)) { return GetAxisName(axisId) + (direction < 0 ? "-" : "+"); } - if (KeyFromPspButton(controllerMap, btn, &deviceId, &keyCode)) { + if (KeyFromPspButton(btn, &deviceId, &keyCode)) { return GetKeyName(keyCode); } return "unknown"; } -std::string NameDeviceFromPspButton(int controllerMap, int btn) { +std::string NameDeviceFromPspButton(int btn) { int deviceId; int axisId; int direction; int keyCode; - if (AxisFromPspButton(controllerMap, btn, &deviceId, &axisId, &direction)) { + if (AxisFromPspButton(btn, &deviceId, &axisId, &direction)) { return GetDeviceName(deviceId); } - if (KeyFromPspButton(controllerMap, btn, &deviceId, &keyCode)) { + if (KeyFromPspButton(btn, &deviceId, &keyCode)) { return GetDeviceName(deviceId); } return "unknown"; } -bool IsMappedKey(int deviceId, int key) -{ +bool IsMappedKey(int deviceId, int key) { return KeyToPspButton(deviceId, key) != KEYMAP_ERROR_UNKNOWN_KEY; } -std::string NamePspButtonFromKey(int deviceId, int key) -{ +std::string NamePspButtonFromKey(int deviceId, int key) { return GetPspButtonName(KeyToPspButton(deviceId, key)); } -void RemoveButtonMapping(int map, int btn) { - for (auto iter = controllerMaps[map].keys.begin(); iter != controllerMaps[map].keys.end(); ++iter) { - if (iter->second == btn) { - controllerMaps[map].keys.erase(iter); +void RemoveButtonMapping(int btn) { + for (auto iter = g_controllerMap.keys.begin(); iter != g_controllerMap.keys.end(); ++iter) { + if (iter->first == btn) { + g_controllerMap.keys.erase(iter); return; } } } -void SetKeyMapping(int map, int deviceId, int key, int btn) -{ - RemoveButtonMapping(map, btn); - controllerMaps[map].keys[KeyDef(deviceId, key)] = btn; +void SetKeyMapping(int deviceId, int key, int btn) { + RemoveButtonMapping(btn); + g_controllerMap.keys[btn] = KeyDef(deviceId, key); } -std::string GetAxisName(int axisId) -{ +std::string GetAxisName(int axisId) { return FindName(axisId, axis_names, ARRAY_SIZE(axis_names)); } -bool IsMappedAxis(int deviceId, int axisId, int direction) -{ +bool IsMappedAxis(int deviceId, int axisId, int direction) { int key = TranslateKeyCodeFromAxis(axisId, direction); return KeyToPspButton(deviceId, key) != KEYMAP_ERROR_UNKNOWN_KEY; } -std::string NamePspButtonFromAxis(int deviceId, int axisId, int direction) -{ +std::string NamePspButtonFromAxis(int deviceId, int axisId, int direction) { int key = TranslateKeyCodeFromAxis(axisId, direction); return GetPspButtonName(KeyToPspButton(deviceId, key)); } -void SetAxisMapping(int map, int deviceId, int axisId, int direction, int btn) -{ +void SetAxisMapping(int deviceId, int axisId, int direction, int btn) { int key = TranslateKeyCodeFromAxis(axisId, direction); - SetKeyMapping(map, deviceId, key, btn); + SetKeyMapping(deviceId, key, btn); } void RestoreDefault() { - controllerMaps = DefaultKeyMap::KeyMap; + g_controllerMap = DefaultKeyMap::KeyMap; } // TODO: Make the ini format nicer. void LoadFromIni(IniFile &file) { if (!file.HasSection("ControlMapping")) { - controllerMaps = DefaultKeyMap::KeyMap; + g_controllerMap = DefaultKeyMap::KeyMap; return; } - controllerMaps.clear(); + g_controllerMap.keys.clear(); IniFile::Section *controls = file.GetOrCreateSection("ControlMapping"); + + /* + + std::vector maps; controls->Get("ControllerMaps", maps); if (!maps.size()) { @@ -680,11 +686,13 @@ void LoadFromIni(IniFile &file) { newMap.keys[KeyDef(deviceId, keyCode)] = atoi(x->second.c_str()); } controllerMaps.push_back(newMap); - } + }*/ + } void SaveToIni(IniFile &file) { IniFile::Section *controls = file.GetOrCreateSection("ControlMapping"); + /* std::vector maps; for (auto x = controllerMaps.begin(); x != controllerMaps.end(); ++x) { maps.push_back(x->name); @@ -702,9 +710,7 @@ void SaveToIni(IniFile &file) { sprintf(value, "%i", iter->second); map->Set(key, value); } - } + }*/ } } // KeyMap - -std::vector controllerMaps = KeyMap::DefaultKeyMap::KeyMap; diff --git a/Common/KeyMap.h b/Common/KeyMap.h index 6cbc28ff61..21c025033b 100644 --- a/Common/KeyMap.h +++ b/Common/KeyMap.h @@ -48,6 +48,7 @@ const float AXIS_BIND_THRESHOLD = 0.75f; class KeyDef { public: + KeyDef() : deviceId(0), keyCode(0) {} KeyDef(int devId, int k) : deviceId(devId), keyCode(k) {} int deviceId; int keyCode; @@ -58,29 +59,40 @@ public: if (keyCode < other.keyCode) return true; return false; } + bool operator == (const KeyDef &other) const { + if (deviceId != other.deviceId) return false; + if (keyCode != other.keyCode) return false; + return true; + } }; struct AxisPos { int axis; float position; + + bool operator < (const AxisPos &other) const { + if (axis < other.axis) return true; + if (axis > other.axis) return false; + return position < other.position; + } + bool operator == (const AxisPos &other) const { + return axis == other.axis && position == other.position; + } }; -typedef std::map KeyMapping; -typedef std::map AxisMapping; +typedef std::map KeyMapping; + + +// These are for speed only, built from the regular ones. For the future. +// typedef std::map KeyMapping; // Multiple maps can be active at the same time. -class ControllerMap { -public: - ControllerMap() : active(true) {} - bool active; +struct ControllerMap { KeyMapping keys; - AxisMapping axis; // TODO - std::string name; }; - -extern std::vector controllerMaps; +extern ControllerMap g_controllerMap; // KeyMap // A translation layer for key assignment. Provides @@ -113,26 +125,28 @@ namespace KeyMap { // about mapping conflicts std::string NamePspButtonFromKey(int deviceId, int key); - bool KeyFromPspButton(int controllerMap, int btn, int *deviceId, int *keyCode); - std::string NameKeyFromPspButton(int controllerMap, int btn); - std::string NameDeviceFromPspButton(int controllerMap, int btn); + bool KeyFromPspButton(int btn, int *deviceId, int *keyCode); + std::string NameKeyFromPspButton(int btn); + std::string NameDeviceFromPspButton(int btn); // Configure the key mapping. // Any configuration will be saved to the Core config. - void SetKeyMapping(int map, int deviceId, int keyCode, int psp_key); + void SetKeyMapping(int deviceId, int keyCode, int psp_key); std::string GetAxisName(int axisId); int AxisToPspButton(int deviceId, int axisId, int direction); - bool AxisFromPspButton(int controllerMap, int btn, int *deviceId, int *axisId, int *direction); + bool AxisFromPspButton(int btn, int *deviceId, int *axisId, int *direction); bool IsMappedAxis(int deviceId, int axisId, int direction); std::string NamePspButtonFromAxis(int deviceId, int axisId, int direction); // Configure an axis mapping, saves the configuration. // Direction is negative or positive. - void SetAxisMapping(int map, int deviceId, int axisId, int direction, int btn); + void SetAxisMapping(int deviceId, int axisId, int direction, int btn); void LoadFromIni(IniFile &iniFile); void SaveToIni(IniFile &iniFile); + void RestoreDefault(); + void QuickMap(int device); } diff --git a/Core/Config.cpp b/Core/Config.cpp index 15b2b37558..015584edfd 100644 --- a/Core/Config.cpp +++ b/Core/Config.cpp @@ -33,9 +33,10 @@ extern bool isJailed; Config::Config() { } Config::~Config() { } -void Config::Load(const char *iniFileName) +void Config::Load(const char *iniFileName, const char *controllerIniFilename) { iniFilename_ = iniFileName; + controllerIniFilename_ = controllerIniFilename; INFO_LOG(LOADER, "Loading config: %s", iniFileName); bSaveSettings = true; @@ -188,7 +189,16 @@ void Config::Load(const char *iniFileName) IniFile::Section *gleshacks = iniFile.GetOrCreateSection("GLESHacks"); gleshacks->Get("PrescaleUV", &bPrescaleUV, false); - KeyMap::LoadFromIni(iniFile); + INFO_LOG(LOADER, "Loading controller config: %s", controllerIniFilename); + bSaveSettings = true; + + IniFile controllerIniFile; + if (!controllerIniFile.Load(controllerIniFilename)) { + ERROR_LOG(LOADER, "Failed to read %s. Setting controller config to default.", controllerIniFilename); + } + + // Continue anyway to initialize the config. It will just restore the defaults. + KeyMap::LoadFromIni(controllerIniFile); CleanRecent(); } @@ -305,14 +315,26 @@ void Config::Save() debugConfig->Set("FontWidth", iFontWidth); debugConfig->Set("FontHeight", iFontHeight); debugConfig->Set("DisplayStatusBar", bDisplayStatusBar); - - KeyMap::SaveToIni(iniFile); - if (!iniFile.Save(iniFilename_.c_str())) { ERROR_LOG(LOADER, "Error saving config - can't write ini %s", iniFilename_.c_str()); return; } INFO_LOG(LOADER, "Config saved: %s", iniFilename_.c_str()); + + + IniFile controllerIniFile; + if (!controllerIniFile.Load(controllerIniFilename_.c_str())) { + ERROR_LOG(LOADER, "Error saving config - can't read ini %s", controllerIniFilename_.c_str()); + } else { + KeyMap::SaveToIni(controllerIniFile); + } + + if (!controllerIniFile.Save(controllerIniFilename_.c_str())) { + ERROR_LOG(LOADER, "Error saving config - can't write ini %s", controllerIniFilename_.c_str()); + return; + } + INFO_LOG(LOADER, "Controller config saved: %s", controllerIniFilename_.c_str()); + } else { INFO_LOG(LOADER, "Not saving config"); } diff --git a/Core/Config.h b/Core/Config.h index bf8d893670..303ab63852 100644 --- a/Core/Config.h +++ b/Core/Config.h @@ -162,7 +162,7 @@ public: std::string flashDirectory; std::string internalDataDirectory; - void Load(const char *iniFileName = "ppsspp.ini"); + void Load(const char *iniFileName = "ppsspp.ini", const char *controllerIniFilename = "controls.ini"); void Save(); // Utility functions for "recent" management @@ -171,6 +171,7 @@ public: private: std::string iniFilename_; + std::string controllerIniFilename_; }; extern Config g_Config; diff --git a/UI/ControlMappingScreen.cpp b/UI/ControlMappingScreen.cpp index f3251e3b79..af04b133eb 100644 --- a/UI/ControlMappingScreen.cpp +++ b/UI/ControlMappingScreen.cpp @@ -51,18 +51,14 @@ void KeyMappingScreen::render() { #define KeyBtn(x, y, symbol) \ - if (UIButton(GEN_ID, Pos(x, y), 90, 0, KeyMap::NameKeyFromPspButton(currentMap_, symbol).c_str(), \ + if (UIButton(GEN_ID, Pos(x, y), 90, 0, KeyMap::NameKeyFromPspButton(symbol).c_str(), \ ALIGN_TOPLEFT)) {\ - screenManager()->push(new KeyMappingNewKeyDialog(symbol, currentMap_), 0); \ + screenManager()->push(new KeyMappingNewKeyDialog(symbol), 0); \ UIReset(); \ } \ - UIText(0, Pos(x+30, y+50), KeyMap::NameDeviceFromPspButton(currentMap_, symbol).c_str(), 0xFFFFFFFF, 0.7f, ALIGN_HCENTER); \ + UIText(0, Pos(x+30, y+50), KeyMap::NameDeviceFromPspButton(symbol).c_str(), 0xFFFFFFFF, 0.7f, ALIGN_HCENTER); \ UIText(0, Pos(x+30, y+80), KeyMap::GetPspButtonName(symbol).c_str(), 0xFFFFFFFF, 0.5f, ALIGN_HCENTER); \ - - // \ - // UIText(0, Pos(x, y+50), controllerMaps[currentMap_].name.c_str(), 0xFFFFFFFF, 0.5f, ALIGN_HCENTER); - int pad = 130; int hlfpad = pad / 2; @@ -114,20 +110,6 @@ void KeyMappingScreen::render() { screenManager()->finishDialog(this, DR_OK); } - if (UIButton(GEN_ID, Pos(10, dp_yres-10), LARGE_BUTTON_WIDTH, 0, generalI18N->T("Prev"), ALIGN_BOTTOMLEFT)) { - currentMap_--; - if (currentMap_ < 0) - currentMap_ = (int)controllerMaps.size() - 1; - } - if (UIButton(GEN_ID, Pos(10 + 10 + LARGE_BUTTON_WIDTH, dp_yres-10), LARGE_BUTTON_WIDTH, 0, generalI18N->T("Next"), ALIGN_BOTTOMLEFT)) { - currentMap_++; - if (currentMap_ >= (int)controllerMaps.size()) - currentMap_ = 0; - } - char temp[256]; - sprintf(temp, "%s (%i/%i)", controllerMaps[currentMap_].name.c_str(), currentMap_ + 1, (int)controllerMaps.size()); - UIText(0, Pos(10, dp_yres-170), temp, 0xFFFFFFFF, 1.0f, ALIGN_BOTTOMLEFT); - UICheckBox(GEN_ID,10, dp_yres - 80, keyI18N->T("Mapping Active"), ALIGN_BOTTOMLEFT, &controllerMaps[currentMap_].active); UIEnd(); } @@ -141,8 +123,8 @@ void KeyMappingNewKeyDialog::CreatePopupContents(UI::ViewGroup *parent) { parent->Add(new TextView(std::string(keyI18N->T("Map a new key for ")) + pspButtonName)); - std::string buttonKey = KeyMap::NameKeyFromPspButton(currentMap_, this->pspBtn_); - std::string buttonDevice = KeyMap::NameDeviceFromPspButton(currentMap_, this->pspBtn_); + std::string buttonKey = KeyMap::NameKeyFromPspButton(this->pspBtn_); + std::string buttonDevice = KeyMap::NameDeviceFromPspButton(this->pspBtn_); parent->Add(new TextView(std::string(keyI18N->T("Previous:")) + " " + buttonKey + " - " + buttonDevice)); } @@ -156,7 +138,7 @@ void KeyMappingNewKeyDialog::key(const KeyInput &key) { last_kb_key_ = key.keyCode; last_axis_id_ = -1; - KeyMap::SetKeyMapping(currentMap_, last_kb_deviceid_, last_kb_key_, pspBtn_); + KeyMap::SetKeyMapping(last_kb_deviceid_, last_kb_key_, pspBtn_); screenManager()->finishDialog(this, DR_OK); } } @@ -167,7 +149,7 @@ void KeyMappingNewKeyDialog::axis(const AxisInput &axis) { last_axis_id_ = axis.axisId; last_axis_direction_ = 1; last_kb_key_ = 0; - KeyMap::SetAxisMapping(currentMap_, last_axis_deviceid_, last_axis_id_, last_axis_direction_, pspBtn_); + KeyMap::SetAxisMapping(last_axis_deviceid_, last_axis_id_, last_axis_direction_, pspBtn_); screenManager()->finishDialog(this, DR_OK); } @@ -176,7 +158,7 @@ void KeyMappingNewKeyDialog::axis(const AxisInput &axis) { last_axis_id_ = axis.axisId; last_axis_direction_ = -1; last_kb_key_ = 0; - KeyMap::SetAxisMapping(currentMap_, last_axis_deviceid_, last_axis_id_, last_axis_direction_, pspBtn_); + KeyMap::SetAxisMapping(last_axis_deviceid_, last_axis_id_, last_axis_direction_, pspBtn_); screenManager()->finishDialog(this, DR_OK); } } diff --git a/UI/ControlMappingScreen.h b/UI/ControlMappingScreen.h index f8c3287b22..4b7e57cb85 100644 --- a/UI/ControlMappingScreen.h +++ b/UI/ControlMappingScreen.h @@ -20,23 +20,20 @@ class KeyMappingScreen : public Screen { public: - KeyMappingScreen() : currentMap_(0) {} + KeyMappingScreen() : Screen() {} void update(InputState &input); void render(); -private: - int currentMap_; }; // Dialog box, meant to be pushed class KeyMappingNewKeyDialog : public PopupScreen { public: - KeyMappingNewKeyDialog(int btn, int currentMap) : PopupScreen("Map Key") { + explicit KeyMappingNewKeyDialog(int btn) : PopupScreen("Map Key") { pspBtn_ = btn; last_kb_deviceid_ = 0; last_kb_key_ = 0; last_axis_deviceid_ = 0; last_axis_id_ = -1; - currentMap_ = currentMap; } void key(const KeyInput &key); @@ -56,5 +53,4 @@ private: int last_axis_deviceid_; int last_axis_id_; int last_axis_direction_; - int currentMap_; }; diff --git a/UI/GameSettingsScreen.cpp b/UI/GameSettingsScreen.cpp index 4393ac65fd..7ca1dfdac8 100644 --- a/UI/GameSettingsScreen.cpp +++ b/UI/GameSettingsScreen.cpp @@ -260,22 +260,23 @@ void GameSettingsScreen::CreateViews() { atracString.assign(Atrac3plus_Decoder::IsInstalled() ? "Redownload Atrac3+ plugin" : "Download Atrac3+ plugin"); audioSettings->Add(new Choice(a->T(atracString.c_str())))->OnClick.Handle(this, &GameSettingsScreen::OnDownloadPlugin); - audioSettings->Add(new CheckBox(&g_Config.bEnableSound, a->T("Enable Sound"))); - audioSettings->Add(new CheckBox(&g_Config.bEnableAtrac3plus, a->T("Enable Atrac3+"))); audioSettings->Add(new PopupSliderChoice(&g_Config.iSFXVolume, 0, 8, a->T("SFX volume"), screenManager())); audioSettings->Add(new PopupSliderChoice(&g_Config.iBGMVolume, 0, 8, a->T("BGM volume"), screenManager())); + audioSettings->Add(new CheckBox(&g_Config.bEnableSound, a->T("Enable Sound"))); + audioSettings->Add(new CheckBox(&g_Config.bEnableAtrac3plus, a->T("Enable Atrac3+"))); + // Control ViewGroup *controlsSettingsScroll = new ScrollView(ORIENT_VERTICAL, new LinearLayoutParams(FILL_PARENT, FILL_PARENT)); ViewGroup *controlsSettings = new LinearLayout(ORIENT_VERTICAL); controlsSettingsScroll->Add(controlsSettings); tabHolder->AddTab(ms->T("Controls"), controlsSettingsScroll); - controlsSettings->Add(new CheckBox(&g_Config.bShowTouchControls, c->T("OnScreen", "On-Screen Touch Controls"))); - controlsSettings->Add(new CheckBox(&g_Config.bShowAnalogStick, c->T("Show Left Analog Stick"))); - controlsSettings->Add(new CheckBox(&g_Config.bAccelerometerToAnalogHoriz, c->T("Tilt", "Tilt to Analog (horizontal)"))); controlsSettings->Add(new Choice(gs->T("Control Mapping")))->OnClick.Handle(this, &GameSettingsScreen::OnControlMapping); + controlsSettings->Add(new CheckBox(&g_Config.bShowTouchControls, c->T("OnScreen", "On-Screen Touch Controls"))); controlsSettings->Add(new PopupSliderChoice(&g_Config.iTouchButtonOpacity, 0, 85, c->T("Button Opacity"), screenManager())); controlsSettings->Add(new PopupSliderChoiceFloat(&g_Config.fButtonScale, 1.15, 2.05, c->T("Button Scaling"), screenManager())); + controlsSettings->Add(new CheckBox(&g_Config.bShowAnalogStick, c->T("Show Left Analog Stick"))); + controlsSettings->Add(new CheckBox(&g_Config.bAccelerometerToAnalogHoriz, c->T("Tilt", "Tilt to Analog (horizontal)"))); // System ViewGroup *systemSettingsScroll = new ScrollView(ORIENT_VERTICAL, new LinearLayoutParams(FILL_PARENT, FILL_PARENT)); @@ -283,16 +284,16 @@ void GameSettingsScreen::CreateViews() { systemSettingsScroll->Add(systemSettings); tabHolder->AddTab(ms->T("System"), systemSettingsScroll); systemSettings->Add(new CheckBox(&g_Config.bJit, s->T("Dynarec", "Dynarec (JIT)"))); - systemSettings->Add(new CheckBox(&g_Config.bSeparateCPUThread, s->T("Multithreaded (experimental)"))); systemSettings->Add(new CheckBox(&g_Config.bFastMemory, s->T("Fast Memory", "Fast Memory (Unstable)"))); - systemSettings->Add(new PopupSliderChoice(&g_Config.iLockedCPUSpeed, 0, 1000, gs->T("Unlock CPU Clock"), screenManager())); + systemSettings->Add(new CheckBox(&g_Config.bSeparateCPUThread, s->T("Multithreaded (experimental)"))); + systemSettings->Add(new PopupSliderChoice(&g_Config.iLockedCPUSpeed, 0, 1000, gs->T("Change CPU Clock", "Change CPU Clock (0 = default)"), screenManager())); systemSettings->Add(new CheckBox(&g_Config.bDayLightSavings, s->T("Day Light Saving"))); static const char *dateFormat[] = { "YYYYMMDD", "MMDDYYYY", "DDMMYYYY"}; systemSettings->Add(new PopupMultiChoice(&g_Config.iDateFormat, gs->T("Date Format"), dateFormat, 1, 3, s, screenManager())); static const char *timeFormat[] = { "12HR", "24HR"}; systemSettings->Add(new PopupMultiChoice(&g_Config.iTimeFormat, gs->T("Time Format"), timeFormat, 1, 2, s, screenManager())); static const char *buttonPref[] = { "Use X to confirm", "Use O to confirm"}; - systemSettings->Add(new PopupMultiChoice(&g_Config.iButtonPreference, gs->T("Button Preference"), buttonPref, 1, 2, s, screenManager())); + systemSettings->Add(new PopupMultiChoice(&g_Config.iButtonPreference, gs->T("Confirmation Button"), buttonPref, 1, 2, s, screenManager())); } void DrawBackground(float alpha);