diff --git a/.gitignore b/.gitignore index ef982616ff..2e1d833dbd 100644 --- a/.gitignore +++ b/.gitignore @@ -18,6 +18,7 @@ *.aps *.exp *.qdact +controls.ini Debug Release Windows/x64 diff --git a/Common/KeyMap.cpp b/Common/KeyMap.cpp index f40fa81710..ff62589e60 100644 --- a/Common/KeyMap.cpp +++ b/Common/KeyMap.cpp @@ -24,213 +24,170 @@ namespace KeyMap { KeyDef AxisDef(int deviceId, int axisId, int direction); -// TODO: Make use const_map.h from native -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; -#ifdef _WIN32 - m[KeyDef(DEVICE_ID_KEYBOARD, NKCODE_V)] = CTRL_SELECT; -#else - m[KeyDef(DEVICE_ID_KEYBOARD, NKCODE_ENTER)] = CTRL_SELECT; -#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; - 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; - return m; - } - - // Not used yet, will autodetect later - static KeyMapping defaultShieldMap() - { - KeyMapping m; - m[KeyDef(DEVICE_ID_PAD_0, NKCODE_BUTTON_A)] = CTRL_CROSS; - m[KeyDef(DEVICE_ID_PAD_0, NKCODE_BUTTON_B)] = CTRL_CIRCLE; - m[KeyDef(DEVICE_ID_PAD_0, NKCODE_BUTTON_X)] = CTRL_SQUARE; - m[KeyDef(DEVICE_ID_PAD_0, NKCODE_BUTTON_Y)] = CTRL_TRIANGLE; - m[KeyDef(DEVICE_ID_PAD_0, NKCODE_BUTTON_START)] = CTRL_START; - m[KeyDef(DEVICE_ID_PAD_0, NKCODE_BUTTON_SELECT)] = CTRL_SELECT; - m[KeyDef(DEVICE_ID_PAD_0, NKCODE_BUTTON_L1)] = CTRL_LTRIGGER; - m[KeyDef(DEVICE_ID_PAD_0, NKCODE_BUTTON_R1)] = CTRL_RTRIGGER; - m[KeyDef(DEVICE_ID_PAD_0, NKCODE_BUTTON_R2)] = VIRTKEY_UNTHROTTLE; - m[KeyDef(DEVICE_ID_PAD_0, NKCODE_BUTTON_THUMBR)] = VIRTKEY_PAUSE; - m[KeyDef(DEVICE_ID_PAD_0, NKCODE_BUTTON_L2)] = VIRTKEY_SPEED_TOGGLE; - m[AxisDef(DEVICE_ID_PAD_0, JOYSTICK_AXIS_X, -1)] = VIRTKEY_AXIS_X_MIN; - m[AxisDef(DEVICE_ID_PAD_0, JOYSTICK_AXIS_X, +1)] = VIRTKEY_AXIS_X_MAX; - m[AxisDef(DEVICE_ID_PAD_0, JOYSTICK_AXIS_Y, -1)] = VIRTKEY_AXIS_Y_MIN; - m[AxisDef(DEVICE_ID_PAD_0, JOYSTICK_AXIS_Y, +1)] = VIRTKEY_AXIS_Y_MAX; - m[AxisDef(DEVICE_ID_PAD_0, JOYSTICK_AXIS_HAT_X, -1)] = CTRL_LEFT; - m[AxisDef(DEVICE_ID_PAD_0, JOYSTICK_AXIS_HAT_X, +1)] = CTRL_RIGHT; - m[AxisDef(DEVICE_ID_PAD_0, JOYSTICK_AXIS_HAT_Y, -1)] = CTRL_UP; - m[AxisDef(DEVICE_ID_PAD_0, JOYSTICK_AXIS_HAT_Y, +1)] = CTRL_DOWN; - return m; - } - - static KeyMapping defaultPadMap() - { - KeyMapping m; -#ifdef ANDROID - 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; -#else - m[KeyDef(DEVICE_ID_PAD_0, NKCODE_BUTTON_2)] = CTRL_CROSS; - m[KeyDef(DEVICE_ID_PAD_0, NKCODE_BUTTON_3)] = CTRL_CIRCLE; - m[KeyDef(DEVICE_ID_PAD_0, NKCODE_BUTTON_4)] = CTRL_SQUARE; - m[KeyDef(DEVICE_ID_PAD_0, NKCODE_BUTTON_1)] = CTRL_TRIANGLE; - m[KeyDef(DEVICE_ID_PAD_0, NKCODE_DPAD_UP)] = CTRL_UP; - m[KeyDef(DEVICE_ID_PAD_0, NKCODE_DPAD_RIGHT)] = CTRL_RIGHT; - m[KeyDef(DEVICE_ID_PAD_0, NKCODE_DPAD_DOWN)] = CTRL_DOWN; - m[KeyDef(DEVICE_ID_PAD_0, NKCODE_DPAD_LEFT)] = CTRL_LEFT; - m[KeyDef(DEVICE_ID_PAD_0, NKCODE_BUTTON_10)] = CTRL_START; - m[KeyDef(DEVICE_ID_PAD_0, NKCODE_BUTTON_9)] = CTRL_SELECT; - m[KeyDef(DEVICE_ID_PAD_0, NKCODE_BUTTON_7)] = CTRL_LTRIGGER; - m[KeyDef(DEVICE_ID_PAD_0, NKCODE_BUTTON_8)] = CTRL_RTRIGGER; - m[AxisDef(DEVICE_ID_PAD_0, JOYSTICK_AXIS_X, -1)] = VIRTKEY_AXIS_X_MIN; - m[AxisDef(DEVICE_ID_PAD_0, JOYSTICK_AXIS_X, +1)] = VIRTKEY_AXIS_X_MAX; - m[AxisDef(DEVICE_ID_PAD_0, JOYSTICK_AXIS_Y, +1)] = VIRTKEY_AXIS_Y_MIN; - m[AxisDef(DEVICE_ID_PAD_0, JOYSTICK_AXIS_Y, -1)] = VIRTKEY_AXIS_Y_MAX; -#endif - return m; - } - - static KeyMapping defaultXperiaPlay() - { - KeyMapping m; - m[KeyDef(DEVICE_ID_DEFAULT, NKCODE_BUTTON_CROSS)] = CTRL_CROSS; - m[KeyDef(DEVICE_ID_DEFAULT, NKCODE_BUTTON_CIRCLE)] = CTRL_CIRCLE; - m[KeyDef(DEVICE_ID_DEFAULT, NKCODE_BUTTON_X)] = CTRL_SQUARE; - m[KeyDef(DEVICE_ID_DEFAULT, NKCODE_BUTTON_Y)] = CTRL_TRIANGLE; - m[KeyDef(DEVICE_ID_DEFAULT, NKCODE_DPAD_UP)] = CTRL_UP; - m[KeyDef(DEVICE_ID_DEFAULT, NKCODE_DPAD_RIGHT)] = CTRL_RIGHT; - m[KeyDef(DEVICE_ID_DEFAULT, NKCODE_DPAD_DOWN)] = CTRL_DOWN; - m[KeyDef(DEVICE_ID_DEFAULT, NKCODE_DPAD_LEFT)] = CTRL_LEFT; - m[KeyDef(DEVICE_ID_DEFAULT, NKCODE_BUTTON_START)] = CTRL_START; - m[KeyDef(DEVICE_ID_DEFAULT, NKCODE_BACK)] = CTRL_SELECT; - m[KeyDef(DEVICE_ID_DEFAULT, NKCODE_BUTTON_L1)] = CTRL_LTRIGGER; - m[KeyDef(DEVICE_ID_DEFAULT, NKCODE_BUTTON_R1)] = CTRL_RTRIGGER; - m[AxisDef(DEVICE_ID_DEFAULT, JOYSTICK_AXIS_X, -1)] = VIRTKEY_AXIS_X_MIN; - m[AxisDef(DEVICE_ID_DEFAULT, JOYSTICK_AXIS_X, +1)] = VIRTKEY_AXIS_X_MAX; - m[AxisDef(DEVICE_ID_DEFAULT, JOYSTICK_AXIS_Y, -1)] = VIRTKEY_AXIS_Y_MIN; - m[AxisDef(DEVICE_ID_DEFAULT, JOYSTICK_AXIS_Y, +1)] = VIRTKEY_AXIS_Y_MAX; - return m; - } - - static std::vector init() - { - std::vector m; - -#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'?) - ControllerMap pad; - pad.keys = defaultPadMap(); - pad.name = "Pad"; - m.push_back(pad); - - ControllerMap kbd; - kbd.keys = defaultKeyboardMap(); - kbd.name = "Keyboard"; - m.push_back(kbd); - -#ifdef ANDROID - ControllerMap xperia; - xperia.keys = defaultXperiaPlay(); - xperia.name = "Xperia Play"; - xperia.active = false; - m.push_back(xperia); -#endif - -#else - ControllerMap kbd; - kbd.keys = defaultKeyboardMap(); - kbd.name = "Keyboard"; - m.push_back(kbd); - -#ifdef _WIN32 - ControllerMap x360; - x360.keys = default360Map(); - x360.name = "Xbox 360 Pad"; - m.push_back(x360); -#endif - // Keyboard and pad maps. - ControllerMap pad; - pad.keys = defaultPadMap(); - pad.name = "DirectInput Pad"; - pad.active = false; - m.push_back(pad); -#endif - return m; - } - - static std::vector KeyMap; -}; - -std::vector DefaultKeyMap::KeyMap = DefaultKeyMap::init(); - - -// Key & Button names -struct KeyMap_IntStrPair { +struct DefMappingStruct { + int pspKey; int key; - std::string name; + int direction; }; + +KeyMapping g_controllerMap; + +static const DefMappingStruct defaultKeyboardKeyMap[] = { + {CTRL_SQUARE, NKCODE_A}, + {CTRL_TRIANGLE, NKCODE_S}, + {CTRL_CIRCLE, NKCODE_X}, + {CTRL_CROSS, NKCODE_Z}, + {CTRL_LTRIGGER, NKCODE_Q}, + {CTRL_RTRIGGER, NKCODE_W}, + + {CTRL_START, NKCODE_SPACE}, +#ifdef _WIN32 + {CTRL_SELECT, NKCODE_V}, +#else + {CTRL_SELECT, NKCODE_ENTER}, +#endif + {CTRL_UP , NKCODE_DPAD_UP}, + {CTRL_DOWN , NKCODE_DPAD_DOWN}, + {CTRL_LEFT , NKCODE_DPAD_LEFT}, + {CTRL_RIGHT, NKCODE_DPAD_RIGHT}, + {VIRTKEY_AXIS_Y_MAX, NKCODE_I}, + {VIRTKEY_AXIS_Y_MIN, NKCODE_K}, + {VIRTKEY_AXIS_X_MIN, NKCODE_J}, + {VIRTKEY_AXIS_X_MAX, NKCODE_L}, + {VIRTKEY_RAPID_FIRE , NKCODE_SHIFT_LEFT}, + {VIRTKEY_UNTHROTTLE , NKCODE_TAB}, + {VIRTKEY_SPEED_TOGGLE, NKCODE_GRAVE}, + {VIRTKEY_PAUSE , NKCODE_ESCAPE}, +}; + +static const DefMappingStruct default360KeyMap[] = { + {VIRTKEY_AXIS_X_MIN, JOYSTICK_AXIS_X, -1}, + {VIRTKEY_AXIS_X_MAX, JOYSTICK_AXIS_X, +1}, + {VIRTKEY_AXIS_Y_MIN, JOYSTICK_AXIS_Y, -1}, + {VIRTKEY_AXIS_Y_MAX, JOYSTICK_AXIS_Y, +1}, + {CTRL_CROSS , NKCODE_BUTTON_A}, + {CTRL_CIRCLE , NKCODE_BUTTON_B}, + {CTRL_SQUARE , NKCODE_BUTTON_X}, + {CTRL_TRIANGLE , NKCODE_BUTTON_Y}, + {CTRL_UP , NKCODE_DPAD_UP}, + {CTRL_RIGHT , NKCODE_DPAD_RIGHT}, + {CTRL_DOWN , NKCODE_DPAD_DOWN}, + {CTRL_LEFT , NKCODE_DPAD_LEFT}, + {CTRL_START , NKCODE_BUTTON_START}, + {CTRL_SELECT , NKCODE_BUTTON_SELECT}, + {CTRL_LTRIGGER , NKCODE_BUTTON_L1}, + {CTRL_RTRIGGER , NKCODE_BUTTON_R1}, + {VIRTKEY_UNTHROTTLE , JOYSTICK_AXIS_RTRIGGER, +1}, + {VIRTKEY_PAUSE , NKCODE_BUTTON_THUMBR}, + {VIRTKEY_SPEED_TOGGLE, NKCODE_BUTTON_L2}, + {VIRTKEY_PAUSE, NKCODE_HOME}, +}; + +static const DefMappingStruct defaultShieldKeyMap[] = { + {CTRL_CROSS, NKCODE_BUTTON_A}, + {CTRL_CIRCLE ,NKCODE_BUTTON_B}, + {CTRL_SQUARE ,NKCODE_BUTTON_X}, + {CTRL_TRIANGLE ,NKCODE_BUTTON_Y}, + {CTRL_START, NKCODE_BUTTON_START}, + {CTRL_SELECT, NKCODE_BUTTON_L2}, + {CTRL_LTRIGGER, NKCODE_BUTTON_L1}, + {CTRL_RTRIGGER, NKCODE_BUTTON_R1}, + {VIRTKEY_AXIS_X_MIN, JOYSTICK_AXIS_X, -1}, + {VIRTKEY_AXIS_X_MAX, JOYSTICK_AXIS_X, +1}, + {VIRTKEY_AXIS_Y_MIN, JOYSTICK_AXIS_Y, -1}, + {VIRTKEY_AXIS_Y_MAX, JOYSTICK_AXIS_Y, +1}, + {CTRL_LEFT, JOYSTICK_AXIS_HAT_X, -1}, + {CTRL_RIGHT, JOYSTICK_AXIS_HAT_X, +1}, + {CTRL_UP, JOYSTICK_AXIS_HAT_Y, -1}, + {CTRL_DOWN, JOYSTICK_AXIS_HAT_Y, +1}, + {VIRTKEY_UNTHROTTLE, NKCODE_BUTTON_R2 }, + {VIRTKEY_PAUSE, NKCODE_BACK }, +}; + +static const DefMappingStruct defaultPadMap[] = { +#ifdef ANDROID + {CTRL_CROSS , NKCODE_BUTTON_A}, + {CTRL_CIRCLE , NKCODE_BUTTON_B}, + {CTRL_SQUARE , NKCODE_BUTTON_X}, + {CTRL_TRIANGLE , NKCODE_BUTTON_Y}, + {CTRL_UP , NKCODE_DPAD_UP}, + {CTRL_RIGHT , NKCODE_DPAD_RIGHT}, + {CTRL_DOWN , NKCODE_DPAD_DOWN}, + {CTRL_LEFT , NKCODE_DPAD_LEFT}, + {CTRL_START , NKCODE_BUTTON_START}, + {CTRL_SELECT , NKCODE_BUTTON_SELECT}, + {CTRL_LTRIGGER , NKCODE_BUTTON_L1}, + {CTRL_RTRIGGER , NKCODE_BUTTON_R1}, + {VIRTKEY_UNTHROTTLE , NKCODE_BUTTON_R2}, + {VIRTKEY_PAUSE , NKCODE_BUTTON_THUMBR}, + {VIRTKEY_SPEED_TOGGLE, NKCODE_BUTTON_L2}, + {VIRTKEY_AXIS_X_MIN, JOYSTICK_AXIS_X, -1}, + {VIRTKEY_AXIS_X_MAX, JOYSTICK_AXIS_X, +1}, + {VIRTKEY_AXIS_Y_MIN, JOYSTICK_AXIS_Y, -1}, + {VIRTKEY_AXIS_Y_MAX, JOYSTICK_AXIS_Y, +1}, +#else + {CTRL_CROSS , NKCODE_BUTTON_2}, + {CTRL_CIRCLE , NKCODE_BUTTON_3}, + {CTRL_SQUARE , NKCODE_BUTTON_4}, + {CTRL_TRIANGLE , NKCODE_BUTTON_1}, + {CTRL_UP , NKCODE_DPAD_UP}, + {CTRL_RIGHT , NKCODE_DPAD_RIGHT}, + {CTRL_DOWN , NKCODE_DPAD_DOWN}, + {CTRL_LEFT , NKCODE_DPAD_LEFT}, + {CTRL_START , NKCODE_BUTTON_10}, + {CTRL_SELECT , NKCODE_BUTTON_9}, + {CTRL_LTRIGGER , NKCODE_BUTTON_7}, + {CTRL_RTRIGGER , NKCODE_BUTTON_8}, + {VIRTKEY_AXIS_X_MIN, JOYSTICK_AXIS_X, -1}, + {VIRTKEY_AXIS_X_MAX, JOYSTICK_AXIS_X, +1}, + {VIRTKEY_AXIS_Y_MIN, JOYSTICK_AXIS_Y, +1}, + {VIRTKEY_AXIS_Y_MAX, JOYSTICK_AXIS_Y, -1}, +#endif +}; + +static const DefMappingStruct defaultXperiaPlay[] = { + {CTRL_CROSS , NKCODE_BUTTON_CROSS}, + {CTRL_CIRCLE , NKCODE_BUTTON_CIRCLE}, + {CTRL_SQUARE , NKCODE_BUTTON_X}, + {CTRL_TRIANGLE , NKCODE_BUTTON_Y}, + {CTRL_UP , NKCODE_DPAD_UP}, + {CTRL_RIGHT , NKCODE_DPAD_RIGHT}, + {CTRL_DOWN , NKCODE_DPAD_DOWN}, + {CTRL_LEFT , NKCODE_DPAD_LEFT}, + {CTRL_START , NKCODE_BUTTON_START}, + {CTRL_SELECT , NKCODE_BACK}, + {CTRL_LTRIGGER , NKCODE_BUTTON_L1}, + {CTRL_RTRIGGER , NKCODE_BUTTON_R1}, + {VIRTKEY_AXIS_X_MIN, JOYSTICK_AXIS_X, -1}, + {VIRTKEY_AXIS_X_MAX, JOYSTICK_AXIS_X, +1}, + {VIRTKEY_AXIS_Y_MIN, JOYSTICK_AXIS_Y, -1}, + {VIRTKEY_AXIS_Y_MAX, JOYSTICK_AXIS_Y, +1}, +}; + +static void SetDefaultKeyMap(int deviceId, const DefMappingStruct *array, int count, bool replace) { + for (size_t i = 0; i < count; i++) { + if (array[i].direction == 0) + SetKeyMapping(array[i].pspKey, KeyDef(deviceId, array[i].key), replace); + else + SetAxisMapping(array[i].pspKey, deviceId, array[i].key, array[i].direction, replace); + } +} + +void SetDefaultKeyMap(DefaultMaps dmap, bool replace) { + switch (dmap) { + case DEFAULT_MAPPING_KEYBOARD: + SetDefaultKeyMap(DEVICE_ID_KEYBOARD, defaultKeyboardKeyMap, ARRAY_SIZE(defaultKeyboardKeyMap), replace); + break; + case DEFAULT_MAPPING_X360: + SetDefaultKeyMap(DEVICE_ID_X360_0, default360KeyMap, ARRAY_SIZE(default360KeyMap), replace); + break; + case DEFAULT_MAPPING_SHIELD: + SetDefaultKeyMap(DEVICE_ID_X360_0, defaultShieldKeyMap, ARRAY_SIZE(defaultShieldKeyMap), replace); + break; + } +} + + const KeyMap_IntStrPair key_names[] = { {NKCODE_A, "A"}, {NKCODE_B, "B"}, @@ -433,40 +390,40 @@ const KeyMap_IntStrPair axis_names[] = { }; static std::string unknown_key_name = "??"; + const KeyMap_IntStrPair psp_button_names[] = { - {CTRL_CIRCLE, "O"}, - {CTRL_CROSS, "X"}, - {CTRL_SQUARE, "[ ]"}, - {CTRL_TRIANGLE, "/\\"}, - {CTRL_LTRIGGER, "L"}, - {CTRL_RTRIGGER, "R"}, - {CTRL_START, "Start"}, - {CTRL_SELECT, "Select"}, {CTRL_UP, "Up"}, {CTRL_DOWN, "Down"}, {CTRL_LEFT, "Left"}, {CTRL_RIGHT, "Right"}, + {CTRL_CIRCLE, "Circle"}, + {CTRL_CROSS, "Cross"}, + {CTRL_SQUARE, "Square"}, + {CTRL_TRIANGLE, "Triangle"}, + {CTRL_START, "Start"}, + {CTRL_SELECT, "Select"}, + {CTRL_LTRIGGER, "L"}, + {CTRL_RTRIGGER, "R"}, + {VIRTKEY_AXIS_Y_MAX, "An.Up"}, + {VIRTKEY_AXIS_Y_MIN, "An.Down"}, {VIRTKEY_AXIS_X_MIN, "An.Left"}, {VIRTKEY_AXIS_X_MAX, "An.Right"}, - {VIRTKEY_AXIS_Y_MIN, "An.Down"}, - {VIRTKEY_AXIS_Y_MAX, "An.Up"}, - - {VIRTKEY_AXIS_RIGHT_X_MIN, "RightAn.Left"}, - {VIRTKEY_AXIS_RIGHT_X_MAX, "RightAn.Right"}, - {VIRTKEY_AXIS_RIGHT_Y_MIN, "RightAn.Down"}, - {VIRTKEY_AXIS_RIGHT_Y_MAX, "RightAn.Up"}, {VIRTKEY_RAPID_FIRE, "RapidFire"}, {VIRTKEY_UNTHROTTLE, "Unthrottle"}, {VIRTKEY_SPEED_TOGGLE, "SpeedToggle"}, {VIRTKEY_PAUSE, "Pause"}, + + {VIRTKEY_AXIS_RIGHT_Y_MAX, "RightAn.Up"}, + {VIRTKEY_AXIS_RIGHT_Y_MIN, "RightAn.Down"}, + {VIRTKEY_AXIS_RIGHT_X_MIN, "RightAn.Left"}, + {VIRTKEY_AXIS_RIGHT_X_MAX, "RightAn.Right"}, }; 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,29 +431,51 @@ 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 GetKeyOrAxisName(int keyCode) { + if (keyCode >= AXIS_BIND_NKCODE_START) { + int direction; + int axis = TranslateKeyCodeToAxis(keyCode, direction); + std::string temp = GetAxisName(axis); + if (direction == 1) + temp += "+"; + else if (direction == -1) + temp += "-"; + return temp; + } + return FindName(keyCode, key_names, ARRAY_SIZE(key_names)); +} + +std::string GetAxisName(int axisId) { + return FindName(axisId, axis_names, ARRAY_SIZE(axis_names)); +} + +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; + int v = keyCode - AXIS_BIND_NKCODE_START; // Even/odd for direction. direction = v & 1 ? -1 : 1; 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,24 +484,20 @@ 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; - return true; +static bool FindKeyMapping(int deviceId, int key, int *psp_button) { + // Brute force, let's optimize later + for (auto iter = g_controllerMap.begin(); iter != g_controllerMap.end(); ++iter) { + for (auto iter2 = iter->second.begin(); iter2 != iter->second.end(); ++iter2) { + if (*iter2 == KeyDef(deviceId, key)) { + *psp_button = iter->first; + return true; + } } } return false; } -int KeyToPspButton(int deviceId, int key) -{ +int KeyToPspButton(int deviceId, int key) { int search_start_layer = 0; int psp_button; @@ -532,179 +507,134 @@ 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, std::vector *keys) { 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; - return true; + for (auto iter = g_controllerMap.begin(); iter != g_controllerMap.end(); ++iter) { + if (iter->first == btn) { + for (auto iter2 = iter->second.begin(); iter2 != iter->second.end(); ++iter2) { + keys->push_back(*iter2); + } } } 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); - return true; + for (auto iter = g_controllerMap.begin(); iter != g_controllerMap.end(); ++iter) { + for (auto iter2 = iter->second.begin(); iter2 != iter->second.end(); ++iter2) { + if (iter->first == btn && iter2->keyCode >= AXIS_BIND_NKCODE_START) { + *deviceId = iter2->deviceId; + *axisId = TranslateKeyCodeToAxis(iter2->keyCode, *direction); + return true; + } } } return false; } -std::string NameKeyFromPspButton(int controllerMap, int btn) { - int deviceId; - int axisId; - int direction; - int keyCode; - if (AxisFromPspButton(controllerMap, btn, &deviceId, &axisId, &direction)) { - return GetAxisName(axisId) + (direction < 0 ? "-" : "+"); - } - if (KeyFromPspButton(controllerMap, btn, &deviceId, &keyCode)) { - return GetKeyName(keyCode); - } - return "unknown"; -} - -std::string NameDeviceFromPspButton(int controllerMap, int btn) { - int deviceId; - int axisId; - int direction; - int keyCode; - if (AxisFromPspButton(controllerMap, btn, &deviceId, &axisId, &direction)) { - return GetDeviceName(deviceId); - } - if (KeyFromPspButton(controllerMap, btn, &deviceId, &keyCode)) { - return GetDeviceName(deviceId); - } - return "unknown"; -} - -bool IsMappedKey(int deviceId, int key) -{ - return KeyToPspButton(deviceId, key) != KEYMAP_ERROR_UNKNOWN_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.begin(); iter != g_controllerMap.end(); ++iter) { + if (iter->first == btn) { + g_controllerMap.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 btn, KeyDef key, bool replace) { + if (key.keyCode < 0) + return; + if (replace) { + RemoveButtonMapping(btn); + g_controllerMap[btn].clear(); + g_controllerMap[btn].push_back(key); + } else { + for (auto iter = g_controllerMap[btn].begin(); iter != g_controllerMap[btn].end(); ++iter) { + if (*iter == key) + return; + } + g_controllerMap[btn].push_back(key); + } } -std::string GetAxisName(int axisId) -{ - return FindName(axisId, axis_names, ARRAY_SIZE(axis_names)); -} - -bool IsMappedAxis(int deviceId, int axisId, int direction) -{ +void SetAxisMapping(int btn, int deviceId, int axisId, int direction, bool replace) { int key = TranslateKeyCodeFromAxis(axisId, direction); - return KeyToPspButton(deviceId, key) != KEYMAP_ERROR_UNKNOWN_KEY; -} - -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) -{ - int key = TranslateKeyCodeFromAxis(axisId, direction); - SetKeyMapping(map, deviceId, key, btn); + SetKeyMapping(btn, KeyDef(deviceId, key), replace); } +// Note that it's easy to add other defaults if desired. void RestoreDefault() { - controllerMaps = DefaultKeyMap::KeyMap; +#if defined(_WIN32) + SetDefaultKeyMap(DEFAULT_MAPPING_KEYBOARD, true); + SetDefaultKeyMap(DEFAULT_MAPPING_X360, false); +#elif defined(ANDROID) + SetDefaultKeyMap(DEFAULT_MAPPING_PAD, true); +#else + SetDefaultKeyMap(DEFAULT_MAPPING_KEYBOARD, true); + SetDefaultKeyMap(DEFAULT_MAPPING_PAD, false); +#endif } // TODO: Make the ini format nicer. void LoadFromIni(IniFile &file) { + RestoreDefault(); if (!file.HasSection("ControlMapping")) { - controllerMaps = DefaultKeyMap::KeyMap; return; } - controllerMaps.clear(); - IniFile::Section *controls = file.GetOrCreateSection("ControlMapping"); - std::vector maps; - controls->Get("ControllerMaps", maps); - if (!maps.size()) { - controllerMaps = DefaultKeyMap::KeyMap; - return; - } + for (int i = 0; i < ARRAY_SIZE(psp_button_names); i++) { + if (!controls->Exists(psp_button_names[i].name.c_str())) + continue; + std::string value; + controls->Get(psp_button_names[i].name.c_str(), &value, ""); + if (value.empty()) + continue; + // Erase default mapping + g_controllerMap.erase(psp_button_names[i].key); - for (auto x = maps.begin(); x != maps.end(); ++x) { - ControllerMap newMap; - newMap.name = *x; - IniFile::Section *map = file.GetOrCreateSection(newMap.name.c_str()); - map->Get("Active", &newMap.active, true); - std::map strmap = map->ToMap(); + std::vector mappings; + SplitString(value, ',', mappings); - for (auto x = strmap.begin(); x != strmap.end(); ++x) { - std::vector keyParts; - SplitString(x->first, '-', keyParts); - if (keyParts.size() != 2) - continue; - int deviceId = atoi(keyParts[0].c_str()); - int keyCode = atoi(keyParts[1].c_str()); - newMap.keys[KeyDef(deviceId, keyCode)] = atoi(x->second.c_str()); + for (size_t j = 0; j < mappings.size(); j++) { + std::vector parts; + SplitString(mappings[j], '-', parts); + int deviceId = atoi(parts[0].c_str()); + int keyCode = atoi(parts[1].c_str()); + + SetKeyMapping(psp_button_names[i].key, KeyDef(deviceId, keyCode), false); } - controllerMaps.push_back(newMap); } + return; } 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); - } - controls->Set("ControllerMaps", maps); - for (auto x = controllerMaps.begin(); x != controllerMaps.end(); ++x) { - IniFile::Section *map = file.GetOrCreateSection(x->name.c_str()); - map->Clear(); - map->Set("Active", x->active); - for (auto iter = x->keys.begin(); iter != x->keys.end(); ++iter) { - char key[128]; - sprintf(key, "%i-%i", iter->first.deviceId, iter->first.keyCode); - char value[128]; - sprintf(value, "%i", iter->second); - map->Set(key, value); + for (int i = 0; i < ARRAY_SIZE(psp_button_names); i++) { + std::vector keys; + KeyFromPspButton(psp_button_names[i].key, &keys); + + std::string value; + for (size_t j = 0; j < keys.size(); j++) { + char temp[128]; + sprintf(temp, "%i-%i", keys[j].deviceId, keys[j].keyCode); + value += temp; + if (j != keys.size() - 1) + value += ","; } + + controls->Set(psp_button_names[i].name.c_str(), value, ""); } } } // KeyMap - -std::vector controllerMaps = KeyMap::DefaultKeyMap::KeyMap; diff --git a/Common/KeyMap.h b/Common/KeyMap.h index 6cbc28ff61..40a7cbc3cf 100644 --- a/Common/KeyMap.h +++ b/Common/KeyMap.h @@ -44,10 +44,19 @@ enum { VIRTKEY_COUNT = VIRTKEY_LAST - VIRTKEY_FIRST }; +enum DefaultMaps { + DEFAULT_MAPPING_KEYBOARD, + DEFAULT_MAPPING_PAD, + DEFAULT_MAPPING_X360, + DEFAULT_MAPPING_SHIELD, + DEFAULT_MAPPING_OUYA, +}; + 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 +67,28 @@ 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; - - -// Multiple maps can be active at the same time. -class ControllerMap { -public: - ControllerMap() : active(true) {} - bool active; - KeyMapping keys; - AxisMapping axis; // TODO - std::string name; -}; - - -extern std::vector controllerMaps; +typedef std::map> KeyMapping; // KeyMap // A translation layer for key assignment. Provides @@ -95,10 +103,22 @@ extern std::vector controllerMaps; class IniFile; namespace KeyMap { + extern KeyMapping g_controllerMap; + + // Key & Button names + struct KeyMap_IntStrPair { + int key; + std::string name; + }; + // Use if you need to display the textual name std::string GetKeyName(int keyCode); + std::string GetKeyOrAxisName(int keyCode); + std::string GetAxisName(int axisId); std::string GetPspButtonName(int btn); + std::vector GetMappableKeys(); + // Use if to translate KeyMap Keys to PSP // buttons. You should have already translated // your platform's keys to KeyMap keys. @@ -106,33 +126,29 @@ namespace KeyMap { // Returns KEYMAP_ERROR_UNKNOWN_KEY // for any unmapped key int KeyToPspButton(int deviceId, int key); + bool KeyFromPspButton(int btn, std::vector *keys); - bool IsMappedKey(int deviceId, int key); - - // Might be useful if you want to provide hints to users - // 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); + int TranslateKeyCodeToAxis(int keyCode, int &direction); + int TranslateKeyCodeFromAxis(int axisId, int direction); // Configure the key mapping. // Any configuration will be saved to the Core config. - void SetKeyMapping(int map, 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 IsMappedAxis(int deviceId, int axisId, int direction); - std::string NamePspButtonFromAxis(int deviceId, int axisId, int direction); + void SetKeyMapping(int psp_key, KeyDef key, bool replace); // 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 btn, int deviceId, int axisId, int direction, bool replace); + + int AxisToPspButton(int deviceId, int axisId, int direction); + bool AxisFromPspButton(int btn, int *deviceId, int *axisId, int *direction); + std::string NamePspButtonFromAxis(int deviceId, int axisId, int direction); void LoadFromIni(IniFile &iniFile); void SaveToIni(IniFile &iniFile); + + void SetDefaultKeyMap(DefaultMaps dmap, bool replace); + void RestoreDefault(); + void QuickMap(int device); } diff --git a/Core/Config.cpp b/Core/Config.cpp index ae22b5463b..41bcafa96d 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; @@ -189,7 +190,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(); } @@ -307,14 +317,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 c75988f1f6..8396742313 100644 --- a/Core/Config.h +++ b/Core/Config.h @@ -163,7 +163,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 @@ -172,6 +172,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..fd853e51f7 100644 --- a/UI/ControlMappingScreen.cpp +++ b/UI/ControlMappingScreen.cpp @@ -21,6 +21,8 @@ #include "input/input_state.h" #include "ui/ui.h" #include "ui/ui_context.h" +#include "ui/view.h" +#include "ui/viewgroup.h" #include "Core/HLE/sceCtrl.h" #include "Common/KeyMap.h" @@ -31,104 +33,165 @@ extern void DrawBackground(float alpha); -void KeyMappingScreen::update(InputState &input) { - if (input.pad_buttons_down & PAD_BUTTON_BACK) { - g_Config.Save(); - screenManager()->finishDialog(this, DR_OK); +class ControlMapper : public UI::LinearLayout { +public: + ControlMapper(int pspKey, std::string keyName, ScreenManager *scrm, UI::LinearLayoutParams *layoutParams = 0); + + virtual void Update(const InputState &input); + +private: + void Refresh(); + + UI::EventReturn OnAdd(UI::EventParams ¶ms); + UI::EventReturn OnDelete(UI::EventParams ¶ms); + UI::EventReturn OnReplace(UI::EventParams ¶ms); + UI::EventReturn OnReplaceAll(UI::EventParams ¶ms); + + void MappedCallback(KeyDef key); + + enum Action { + NONE, + REPLACEONE, + REPLACEALL, + ADD, + }; + + Action action_; + int actionIndex_; + int pspKey_; + std::string keyName_; + ScreenManager *scrm_; + bool refresh_; +}; + +ControlMapper::ControlMapper(int pspKey, std::string keyName, ScreenManager *scrm, UI::LinearLayoutParams *layoutParams) + : UI::LinearLayout(UI::ORIENT_VERTICAL, layoutParams), action_(NONE), pspKey_(pspKey), keyName_(keyName), scrm_(scrm), refresh_(false) { + + Refresh(); +} + +void ControlMapper::Update(const InputState &input) { + if (refresh_) { + refresh_ = false; + Refresh(); } } -void KeyMappingScreen::render() { - UIShader_Prepare(); - UIBegin(UIShader_Get()); - DrawBackground(1.0f); +void ControlMapper::Refresh() { + Clear(); - UIContext *ctx = screenManager()->getUIContext(); - UIFlush(); + using namespace UI; - I18NCategory *keyI18N = GetI18NCategory("KeyMapping"); - I18NCategory *generalI18N = GetI18NCategory("General"); + LinearLayout *root = Add(new LinearLayout(ORIENT_HORIZONTAL, new LinearLayoutParams(FILL_PARENT, WRAP_CONTENT))); + + root->Add(new Choice(keyName_, new LinearLayoutParams(200, WRAP_CONTENT)))->OnClick.Handle(this, &ControlMapper::OnReplaceAll); + LinearLayout *rightColumn = root->Add(new LinearLayout(ORIENT_VERTICAL, new LinearLayoutParams(1.0f))); + std::vector mappings; + KeyMap::KeyFromPspButton(pspKey_, &mappings); -#define KeyBtn(x, y, symbol) \ - if (UIButton(GEN_ID, Pos(x, y), 90, 0, KeyMap::NameKeyFromPspButton(currentMap_, symbol).c_str(), \ - ALIGN_TOPLEFT)) {\ - screenManager()->push(new KeyMappingNewKeyDialog(symbol, currentMap_), 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+80), KeyMap::GetPspButtonName(symbol).c_str(), 0xFFFFFFFF, 0.5f, ALIGN_HCENTER); \ + for (size_t i = 0; i < mappings.size(); i++) { + std::string deviceName = GetDeviceName(mappings[i].deviceId); + std::string keyName = KeyMap::GetKeyOrAxisName(mappings[i].keyCode); + int image = -1; + LinearLayout *row = rightColumn->Add(new LinearLayout(ORIENT_HORIZONTAL, new LinearLayoutParams(FILL_PARENT, WRAP_CONTENT))); - // \ - // UIText(0, Pos(x, y+50), controllerMaps[currentMap_].name.c_str(), 0xFFFFFFFF, 0.5f, ALIGN_HCENTER); - - int pad = 130; - int hlfpad = pad / 2; - - int left = 30; - KeyBtn(left, 30, CTRL_LTRIGGER); - - int top = 120; - KeyBtn(left+hlfpad, top, CTRL_UP); // Up - KeyBtn(left, top+hlfpad, CTRL_LEFT);// Left - KeyBtn(left+pad, top+hlfpad, CTRL_RIGHT); // Right - KeyBtn(left+hlfpad, top+pad, CTRL_DOWN); // Down - - top = 10; - left = 250; - KeyBtn(left+hlfpad, top, VIRTKEY_AXIS_Y_MAX); // Analog Up - KeyBtn(left, top+hlfpad, VIRTKEY_AXIS_X_MIN);// Analog Left - KeyBtn(left+pad, top+hlfpad, VIRTKEY_AXIS_X_MAX); // Analog Right - KeyBtn(left+hlfpad, top+pad, VIRTKEY_AXIS_Y_MIN); // Analog Down - - top = 120; - left = 480; - KeyBtn(left+hlfpad, top, CTRL_TRIANGLE); // Triangle - KeyBtn(left, top+hlfpad, CTRL_SQUARE); // Square - KeyBtn(left+pad, top+hlfpad, CTRL_CIRCLE); // Circle - KeyBtn(left+hlfpad, top+pad, CTRL_CROSS); // Cross - - left = 610; - KeyBtn(left, 30, CTRL_RTRIGGER); - - top += pad + 50; - left = 250; - KeyBtn(left, top, CTRL_SELECT); // Select - KeyBtn(left + pad, top, CTRL_START); //Start - - top = 10; - left = 720; - KeyBtn(left, top, VIRTKEY_UNTHROTTLE); - top += 100; - KeyBtn(left, top, VIRTKEY_SPEED_TOGGLE); - top += 100; - KeyBtn(left, top, VIRTKEY_PAUSE); - top += 100; - KeyBtn(left, top, VIRTKEY_RAPID_FIRE); -#undef KeyBtn - - // TODO: Add rapid fire somewhere? - - if (UIButton(GEN_ID, Pos(dp_xres - 10, dp_yres - 10), LARGE_BUTTON_WIDTH, 0, generalI18N->T("Back"), ALIGN_RIGHT | ALIGN_BOTTOM)) { - screenManager()->finishDialog(this, DR_OK); + Choice *c = row->Add(new Choice(deviceName + "." + keyName, new LinearLayoutParams(1.0f))); + char buf[10]; + c->SetTag(itoa(i, buf, 10)); + c->OnClick.Handle(this, &ControlMapper::OnReplace); + + Choice *d = row->Add(new Choice("X")); + d->SetTag(itoa(i, buf, 10)); + d->OnClick.Handle(this, &ControlMapper::OnDelete); + + row->Add(new Choice("+"))->OnClick.Handle(this, &ControlMapper::OnAdd); } - 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 (mappings.size() == 0) { + // look like an empty line + rightColumn->Add(new Choice("", new LinearLayoutParams(WRAP_CONTENT, WRAP_CONTENT)))->OnClick.Handle(this, &ControlMapper::OnAdd); } - 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; +} + +void ControlMapper::MappedCallback(KeyDef kdf) { + switch (action_) { + case ADD: + KeyMap::SetKeyMapping(pspKey_, kdf, false); + break; + case REPLACEALL: + KeyMap::SetKeyMapping(pspKey_, kdf, true); + break; + case REPLACEONE: + KeyMap::g_controllerMap[pspKey_][actionIndex_] = kdf; + break; } - 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(); + refresh_ = true; +} + +UI::EventReturn ControlMapper::OnReplace(UI::EventParams ¶ms) { + actionIndex_ = atoi(params.v->Tag().c_str()); + action_ = REPLACEONE; + scrm_->push(new KeyMappingNewKeyDialog(pspKey_, true, std::bind(&ControlMapper::MappedCallback, this, placeholder::_1))); + return UI::EVENT_DONE; +} + +UI::EventReturn ControlMapper::OnReplaceAll(UI::EventParams ¶ms) { + action_ = REPLACEALL; + scrm_->push(new KeyMappingNewKeyDialog(pspKey_, true, std::bind(&ControlMapper::MappedCallback, this, placeholder::_1))); + return UI::EVENT_DONE; +} + +UI::EventReturn ControlMapper::OnAdd(UI::EventParams ¶ms) { + action_ = ADD; + scrm_->push(new KeyMappingNewKeyDialog(pspKey_, true, std::bind(&ControlMapper::MappedCallback, this, placeholder::_1))); + return UI::EVENT_DONE; +} + +UI::EventReturn ControlMapper::OnDelete(UI::EventParams ¶ms) { + int index = atoi(params.v->Tag().c_str()); + KeyMap::g_controllerMap[pspKey_].erase(KeyMap::g_controllerMap[pspKey_].begin() + index); + refresh_ = true; + return UI::EVENT_DONE; +} + +void ControlMappingScreen::CreateViews() { + using namespace UI; + + I18NCategory *k = GetI18NCategory("KeyMapping"); + I18NCategory *g = GetI18NCategory("General"); + + root_ = new LinearLayout(ORIENT_HORIZONTAL); + + LinearLayout *leftColumn = new LinearLayout(ORIENT_VERTICAL, new LinearLayoutParams(200, FILL_PARENT)); + leftColumn->Add(new Choice(k->T("Clear All")))->OnClick.Handle(this, &ControlMappingScreen::OnClearMapping); + leftColumn->Add(new Spacer(new LinearLayoutParams(1.0f))); + leftColumn->Add(new Choice(g->T("Back")))->OnClick.Handle(this, &UIScreen::OnBack); + + /* + ChoiceStrip *mode = leftColumn->Add(new ChoiceStrip(ORIENT_VERTICAL)); + mode->AddChoice("Replace"); + mode->AddChoice("Add"); + */ + ScrollView *rightScroll = new ScrollView(ORIENT_VERTICAL, new LinearLayoutParams(1.0f)); + LinearLayout *rightColumn = new LinearLayout(ORIENT_VERTICAL, new LinearLayoutParams(1.0f)); + rightScroll->Add(rightColumn); + + root_->Add(leftColumn); + root_->Add(rightScroll); + + std::vector mappableKeys = KeyMap::GetMappableKeys(); + for (size_t i = 0; i < mappableKeys.size(); i++) { + rightColumn->Add(new ControlMapper(mappableKeys[i].key, mappableKeys[i].name, screenManager(), new LinearLayoutParams(FILL_PARENT, WRAP_CONTENT))); + } +} + +UI::EventReturn ControlMappingScreen::OnClearMapping(UI::EventParams ¶ms) { + KeyMap::g_controllerMap.clear(); + + RecreateViews(); + return UI::EVENT_DONE; } void KeyMappingNewKeyDialog::CreatePopupContents(UI::ViewGroup *parent) { @@ -140,10 +203,6 @@ void KeyMappingNewKeyDialog::CreatePopupContents(UI::ViewGroup *parent) { std::string pspButtonName = KeyMap::GetPspButtonName(this->pspBtn_); 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_); - parent->Add(new TextView(std::string(keyI18N->T("Previous:")) + " " + buttonKey + " - " + buttonDevice)); } void KeyMappingNewKeyDialog::key(const KeyInput &key) { @@ -151,32 +210,26 @@ void KeyMappingNewKeyDialog::key(const KeyInput &key) { if (key.keyCode == NKCODE_EXT_MOUSEBUTTON_1) { return; } - - last_kb_deviceid_ = key.deviceId; - last_kb_key_ = key.keyCode; - last_axis_id_ = -1; - - KeyMap::SetKeyMapping(currentMap_, last_kb_deviceid_, last_kb_key_, pspBtn_); + + KeyDef kdf(key.deviceId, key.keyCode); screenManager()->finishDialog(this, DR_OK); + if (callback_) + callback_(kdf); } } void KeyMappingNewKeyDialog::axis(const AxisInput &axis) { if (axis.value > AXIS_BIND_THRESHOLD) { - last_axis_deviceid_ = axis.deviceId; - 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_); + KeyDef kdf(axis.deviceId, KeyMap::TranslateKeyCodeFromAxis(axis.axisId, 1)); screenManager()->finishDialog(this, DR_OK); + if (callback_) + callback_(kdf); } if (axis.value < -AXIS_BIND_THRESHOLD) { - last_axis_deviceid_ = axis.deviceId; - 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_); + KeyDef kdf(axis.deviceId, KeyMap::TranslateKeyCodeFromAxis(axis.axisId, -1)); screenManager()->finishDialog(this, DR_OK); + if (callback_) + callback_(kdf); } } diff --git a/UI/ControlMappingScreen.h b/UI/ControlMappingScreen.h index f8c3287b22..4b8f709ff0 100644 --- a/UI/ControlMappingScreen.h +++ b/UI/ControlMappingScreen.h @@ -15,28 +15,26 @@ // Official git repository and contact information can be found at // https://github.com/hrydgard/ppsspp and http://www.ppsspp.org/. +#include "base/functional.h" #include "ui/view.h" #include "ui/ui_screen.h" -class KeyMappingScreen : public Screen { +#include "UI/MiscScreens.h" + +class ControlMappingScreen : public UIDialogScreenWithBackground { public: - KeyMappingScreen() : currentMap_(0) {} - void update(InputState &input); - void render(); + ControlMappingScreen() {} +protected: + virtual void CreateViews(); + private: - int currentMap_; + UI::EventReturn OnClearMapping(UI::EventParams ¶ms); }; -// Dialog box, meant to be pushed class KeyMappingNewKeyDialog : public PopupScreen { public: - KeyMappingNewKeyDialog(int btn, int currentMap) : PopupScreen("Map Key") { + explicit KeyMappingNewKeyDialog(int btn, bool replace, std::function callback) : PopupScreen("Map Key"), callback_(callback) { 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); @@ -51,10 +49,6 @@ protected: private: int pspBtn_; - int last_kb_deviceid_; - int last_kb_key_; - int last_axis_deviceid_; - int last_axis_id_; - int last_axis_direction_; - int currentMap_; + bool replace_; + std::function callback_; }; diff --git a/UI/GameScreen.h b/UI/GameScreen.h index cd0ae57b7b..0e27495453 100644 --- a/UI/GameScreen.h +++ b/UI/GameScreen.h @@ -24,7 +24,7 @@ // set game specific settings, etc. // Uses GameInfoCache heavily to implement the functionality. -class GameScreen : public DialogScreen { +class GameScreen : public UIDialogScreen { public: GameScreen(std::string gamePath) : gamePath_(gamePath) {} diff --git a/UI/GameSettingsScreen.cpp b/UI/GameSettingsScreen.cpp index 4393ac65fd..26baeabdd4 100644 --- a/UI/GameSettingsScreen.cpp +++ b/UI/GameSettingsScreen.cpp @@ -91,8 +91,10 @@ void PopupMultiChoice::UpdateText() { } void PopupMultiChoice::ChoiceCallback(int num) { - *value_ = num + minVal_; - UpdateText(); + if (num != -1) { + *value_ = num + minVal_; + UpdateText(); + } } void PopupMultiChoice::Draw(UIContext &dc) { @@ -260,22 +262,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 +286,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); @@ -385,7 +388,7 @@ UI::EventReturn GlobalSettingsScreen::OnDeveloperTools(UI::EventParams &e) { } UI::EventReturn GameSettingsScreen::OnControlMapping(UI::EventParams &e) { - screenManager()->push(new KeyMappingScreen()); + screenManager()->push(new ControlMappingScreen()); return UI::EVENT_DONE; } diff --git a/UI/MenuScreens.cpp b/UI/MenuScreens.cpp index 2151a5ba23..77ca739101 100644 --- a/UI/MenuScreens.cpp +++ b/UI/MenuScreens.cpp @@ -712,10 +712,11 @@ void ControlsScreen::render() { g_Config.iTouchButtonOpacity = bTransparent ? 15 : 65; } y += 10; + // Button to KeyMapping screen HLinear hlinear(x, y += stride, 20); if (UIButton(GEN_ID, hlinear, 250, 0, c->T("Key Mapping"), ALIGN_LEFT)) { - screenManager()->push(new KeyMappingScreen()); + screenManager()->push(new ControlMappingScreen()); } if (UIButton(GEN_ID, hlinear, 250, 0, c->T("Default Mapping"), ALIGN_LEFT)) { KeyMap::RestoreDefault(); diff --git a/UI/MiscScreens.h b/UI/MiscScreens.h index 6d960aa247..cca70edd7c 100644 --- a/UI/MiscScreens.h +++ b/UI/MiscScreens.h @@ -34,9 +34,9 @@ protected: virtual void DrawBackground(UIContext &dc); }; -class UIDialogScreenWithBackground : public DialogScreen { +class UIDialogScreenWithBackground : public UIDialogScreen { public: - UIDialogScreenWithBackground() : DialogScreen() {} + UIDialogScreenWithBackground() : UIDialogScreen() {} protected: virtual void DrawBackground(UIContext &dc); }; diff --git a/Windows/ControlMapping.h b/Windows/ControlMapping.h index ce495c5899..933a254a07 100644 --- a/Windows/ControlMapping.h +++ b/Windows/ControlMapping.h @@ -19,6 +19,3 @@ #include "InputDevice.h" -#define XBOX_CODE_LEFTTRIGGER 0x00010000 -#define XBOX_CODE_RIGHTTRIGGER 0x00020000 - diff --git a/Windows/XinputDevice.cpp b/Windows/XinputDevice.cpp index 5ab1781eff..a92790a34a 100644 --- a/Windows/XinputDevice.cpp +++ b/Windows/XinputDevice.cpp @@ -74,8 +74,6 @@ static void UnloadXInputDLL() { // Permanent map. Actual mapping happens elsewhere. static const struct {int from, to;} xinput_ctrl_map[] = { - {XBOX_CODE_LEFTTRIGGER, NKCODE_BUTTON_L2}, - {XBOX_CODE_RIGHTTRIGGER, NKCODE_BUTTON_R2}, {XINPUT_GAMEPAD_A, NKCODE_BUTTON_A}, {XINPUT_GAMEPAD_B, NKCODE_BUTTON_B}, {XINPUT_GAMEPAD_X, NKCODE_BUTTON_X}, @@ -165,6 +163,22 @@ int XinputDevice::UpdateState(InputState &input_state) { NativeAxis(axis); } + if (prevState.Gamepad.bLeftTrigger != state.Gamepad.bLeftTrigger) { + AxisInput axis; + axis.deviceId = DEVICE_ID_X360_0; + axis.axisId = JOYSTICK_AXIS_LTRIGGER; + axis.value = (float)state.Gamepad.bLeftTrigger / 255.0f; + NativeAxis(axis); + } + + if (prevState.Gamepad.bRightTrigger != state.Gamepad.bRightTrigger) { + AxisInput axis; + axis.deviceId = DEVICE_ID_X360_0; + axis.axisId = JOYSTICK_AXIS_RTRIGGER; + axis.value = (float)state.Gamepad.bRightTrigger / 255.0f; + NativeAxis(axis); + } + this->prevState = state; this->check_delay = 0; @@ -212,11 +226,6 @@ static Stick NormalizedDeadzoneFilter(short x, short y) { void XinputDevice::ApplyButtons(XINPUT_STATE &state, InputState &input_state) { u32 buttons = state.Gamepad.wButtons; - if (state.Gamepad.bLeftTrigger > XINPUT_GAMEPAD_TRIGGER_THRESHOLD) - buttons |= XBOX_CODE_LEFTTRIGGER; - if (state.Gamepad.bRightTrigger > XINPUT_GAMEPAD_TRIGGER_THRESHOLD) - buttons |= XBOX_CODE_RIGHTTRIGGER; - u32 downMask = buttons & (~prevButtons); u32 upMask = (~buttons) & prevButtons; prevButtons = buttons; diff --git a/native b/native index 5422dead6a..17996ccd4c 160000 --- a/native +++ b/native @@ -1 +1 @@ -Subproject commit 5422dead6ab36cd450bf02c4d2ec9350a5943b8c +Subproject commit 17996ccd4c133e2f930e9b7141875a6ed5e24558