diff options
| author | 2016-06-10 22:28:58 -0400 | |
|---|---|---|
| committer | 2016-06-10 22:28:58 -0400 | |
| commit | f99961581ee129c44625dbd8890fab349253271a (patch) | |
| tree | 9a2610d391d795b533054a91c22763e869bdd62b /src/common/key_map.cpp | |
| parent | Merge pull request #1896 from citra-emu/revert-1893-interpreter-split (diff) | |
| parent | fixup! fixup! Refactor input system (diff) | |
| download | yuzu-f99961581ee129c44625dbd8890fab349253271a.tar.gz yuzu-f99961581ee129c44625dbd8890fab349253271a.tar.xz yuzu-f99961581ee129c44625dbd8890fab349253271a.zip | |
Merge pull request #1789 from wwylele/input-refactor
Refactor input mapping & implement circle pad modifier
Diffstat (limited to 'src/common/key_map.cpp')
| -rw-r--r-- | src/common/key_map.cpp | 126 |
1 files changed, 120 insertions, 6 deletions
diff --git a/src/common/key_map.cpp b/src/common/key_map.cpp index 844d5df68..ad311d66b 100644 --- a/src/common/key_map.cpp +++ b/src/common/key_map.cpp | |||
| @@ -2,24 +2,138 @@ | |||
| 2 | // Licensed under GPLv2 or any later version | 2 | // Licensed under GPLv2 or any later version |
| 3 | // Refer to the license.txt file included. | 3 | // Refer to the license.txt file included. |
| 4 | 4 | ||
| 5 | #include "key_map.h" | ||
| 6 | #include <map> | 5 | #include <map> |
| 7 | 6 | ||
| 7 | #include "common/emu_window.h" | ||
| 8 | #include "common/key_map.h" | ||
| 9 | |||
| 8 | namespace KeyMap { | 10 | namespace KeyMap { |
| 9 | 11 | ||
| 10 | static std::map<HostDeviceKey, Service::HID::PadState> key_map; | 12 | // TODO (wwylele): currently we treat c-stick as four direction buttons |
| 13 | // and map it directly to EmuWindow::ButtonPressed. | ||
| 14 | // It should go the analog input way like circle pad does. | ||
| 15 | const std::array<KeyTarget, Settings::NativeInput::NUM_INPUTS> mapping_targets = {{ | ||
| 16 | Service::HID::PAD_A, Service::HID::PAD_B, Service::HID::PAD_X, Service::HID::PAD_Y, | ||
| 17 | Service::HID::PAD_L, Service::HID::PAD_R, Service::HID::PAD_ZL, Service::HID::PAD_ZR, | ||
| 18 | Service::HID::PAD_START, Service::HID::PAD_SELECT, Service::HID::PAD_NONE, | ||
| 19 | Service::HID::PAD_UP, Service::HID::PAD_DOWN, Service::HID::PAD_LEFT, Service::HID::PAD_RIGHT, | ||
| 20 | Service::HID::PAD_C_UP, Service::HID::PAD_C_DOWN, Service::HID::PAD_C_LEFT, Service::HID::PAD_C_RIGHT, | ||
| 21 | |||
| 22 | IndirectTarget::CirclePadUp, | ||
| 23 | IndirectTarget::CirclePadDown, | ||
| 24 | IndirectTarget::CirclePadLeft, | ||
| 25 | IndirectTarget::CirclePadRight, | ||
| 26 | IndirectTarget::CirclePadModifier, | ||
| 27 | }}; | ||
| 28 | |||
| 29 | static std::map<HostDeviceKey, KeyTarget> key_map; | ||
| 11 | static int next_device_id = 0; | 30 | static int next_device_id = 0; |
| 12 | 31 | ||
| 32 | static bool circle_pad_up = false; | ||
| 33 | static bool circle_pad_down = false; | ||
| 34 | static bool circle_pad_left = false; | ||
| 35 | static bool circle_pad_right = false; | ||
| 36 | static bool circle_pad_modifier = false; | ||
| 37 | |||
| 38 | static void UpdateCirclePad(EmuWindow& emu_window) { | ||
| 39 | constexpr float SQRT_HALF = 0.707106781; | ||
| 40 | int x = 0, y = 0; | ||
| 41 | |||
| 42 | if (circle_pad_right) | ||
| 43 | ++x; | ||
| 44 | if (circle_pad_left) | ||
| 45 | --x; | ||
| 46 | if (circle_pad_up) | ||
| 47 | ++y; | ||
| 48 | if (circle_pad_down) | ||
| 49 | --y; | ||
| 50 | |||
| 51 | float modifier = circle_pad_modifier ? Settings::values.pad_circle_modifier_scale : 1.0; | ||
| 52 | emu_window.CirclePadUpdated(x * modifier * (y == 0 ? 1.0 : SQRT_HALF), y * modifier * (x == 0 ? 1.0 : SQRT_HALF)); | ||
| 53 | } | ||
| 54 | |||
| 13 | int NewDeviceId() { | 55 | int NewDeviceId() { |
| 14 | return next_device_id++; | 56 | return next_device_id++; |
| 15 | } | 57 | } |
| 16 | 58 | ||
| 17 | void SetKeyMapping(HostDeviceKey key, Service::HID::PadState padState) { | 59 | void SetKeyMapping(HostDeviceKey key, KeyTarget target) { |
| 18 | key_map[key].hex = padState.hex; | 60 | key_map[key] = target; |
| 61 | } | ||
| 62 | |||
| 63 | void ClearKeyMapping(int device_id) { | ||
| 64 | auto iter = key_map.begin(); | ||
| 65 | while (iter != key_map.end()) { | ||
| 66 | if (iter->first.device_id == device_id) | ||
| 67 | key_map.erase(iter++); | ||
| 68 | else | ||
| 69 | ++iter; | ||
| 70 | } | ||
| 19 | } | 71 | } |
| 20 | 72 | ||
| 21 | Service::HID::PadState GetPadKey(HostDeviceKey key) { | 73 | void PressKey(EmuWindow& emu_window, HostDeviceKey key) { |
| 22 | return key_map[key]; | 74 | auto target = key_map.find(key); |
| 75 | if (target == key_map.end()) | ||
| 76 | return; | ||
| 77 | |||
| 78 | if (target->second.direct) { | ||
| 79 | emu_window.ButtonPressed({{target->second.target.direct_target_hex}}); | ||
| 80 | } else { | ||
| 81 | switch (target->second.target.indirect_target) { | ||
| 82 | case IndirectTarget::CirclePadUp: | ||
| 83 | circle_pad_up = true; | ||
| 84 | UpdateCirclePad(emu_window); | ||
| 85 | break; | ||
| 86 | case IndirectTarget::CirclePadDown: | ||
| 87 | circle_pad_down = true; | ||
| 88 | UpdateCirclePad(emu_window); | ||
| 89 | break; | ||
| 90 | case IndirectTarget::CirclePadLeft: | ||
| 91 | circle_pad_left = true; | ||
| 92 | UpdateCirclePad(emu_window); | ||
| 93 | break; | ||
| 94 | case IndirectTarget::CirclePadRight: | ||
| 95 | circle_pad_right = true; | ||
| 96 | UpdateCirclePad(emu_window); | ||
| 97 | break; | ||
| 98 | case IndirectTarget::CirclePadModifier: | ||
| 99 | circle_pad_modifier = true; | ||
| 100 | UpdateCirclePad(emu_window); | ||
| 101 | break; | ||
| 102 | } | ||
| 103 | } | ||
| 104 | } | ||
| 105 | |||
| 106 | void ReleaseKey(EmuWindow& emu_window,HostDeviceKey key) { | ||
| 107 | auto target = key_map.find(key); | ||
| 108 | if (target == key_map.end()) | ||
| 109 | return; | ||
| 110 | |||
| 111 | if (target->second.direct) { | ||
| 112 | emu_window.ButtonReleased({{target->second.target.direct_target_hex}}); | ||
| 113 | } else { | ||
| 114 | switch (target->second.target.indirect_target) { | ||
| 115 | case IndirectTarget::CirclePadUp: | ||
| 116 | circle_pad_up = false; | ||
| 117 | UpdateCirclePad(emu_window); | ||
| 118 | break; | ||
| 119 | case IndirectTarget::CirclePadDown: | ||
| 120 | circle_pad_down = false; | ||
| 121 | UpdateCirclePad(emu_window); | ||
| 122 | break; | ||
| 123 | case IndirectTarget::CirclePadLeft: | ||
| 124 | circle_pad_left = false; | ||
| 125 | UpdateCirclePad(emu_window); | ||
| 126 | break; | ||
| 127 | case IndirectTarget::CirclePadRight: | ||
| 128 | circle_pad_right = false; | ||
| 129 | UpdateCirclePad(emu_window); | ||
| 130 | break; | ||
| 131 | case IndirectTarget::CirclePadModifier: | ||
| 132 | circle_pad_modifier = false; | ||
| 133 | UpdateCirclePad(emu_window); | ||
| 134 | break; | ||
| 135 | } | ||
| 136 | } | ||
| 23 | } | 137 | } |
| 24 | 138 | ||
| 25 | } | 139 | } |