summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorgerman77 <juangerman-13@hotmail.com>2021-11-14 06:25:45 +0100
committerNarr the Reg <juangerman-13@hotmail.com>2021-11-25 03:30:28 +0100
commitb673857d7dfc72f38d9242b315cd590b859795ff (patch)
tree8dbb0823ddfdb827eec99f9f05c678a9d15d6631
parentcore/hid: Fix keyboard alignment (diff)
downloadyuzu-b673857d7dfc72f38d9242b315cd590b859795ff.tar
yuzu-b673857d7dfc72f38d9242b315cd590b859795ff.tar.gz
yuzu-b673857d7dfc72f38d9242b315cd590b859795ff.tar.bz2
yuzu-b673857d7dfc72f38d9242b315cd590b859795ff.tar.lz
yuzu-b673857d7dfc72f38d9242b315cd590b859795ff.tar.xz
yuzu-b673857d7dfc72f38d9242b315cd590b859795ff.tar.zst
yuzu-b673857d7dfc72f38d9242b315cd590b859795ff.zip
Diffstat (limited to '')
-rw-r--r--src/common/settings_input.h35
-rw-r--r--src/core/hid/emulated_devices.cpp3
-rw-r--r--src/core/hid/hid_types.h398
-rw-r--r--src/core/hle/service/hid/controllers/keyboard.cpp1
-rw-r--r--src/core/hle/service/hid/hid.cpp35
-rw-r--r--src/core/hle/service/hid/hid.h2
-rw-r--r--src/input_common/drivers/keyboard.cpp53
-rw-r--r--src/input_common/drivers/keyboard.h7
-rw-r--r--src/input_common/main.cpp9
-rw-r--r--src/input_common/main.h3
-rw-r--r--src/yuzu/bootmanager.cpp276
-rw-r--r--src/yuzu/bootmanager.h6
-rw-r--r--src/yuzu/configuration/config.cpp167
13 files changed, 682 insertions, 313 deletions
diff --git a/src/common/settings_input.h b/src/common/settings_input.h
index 2c0eb31d3..a2982fca4 100644
--- a/src/common/settings_input.h
+++ b/src/common/settings_input.h
@@ -129,7 +129,6 @@ extern const std::array<const char*, NumMouseButtons> mapping;
namespace NativeKeyboard {
enum Keys {
None,
- Error,
A = 4,
B,
@@ -167,22 +166,22 @@ enum Keys {
N8,
N9,
N0,
- Enter,
+ Return,
Escape,
Backspace,
Tab,
Space,
Minus,
- Equal,
- LeftBrace,
- RightBrace,
- Backslash,
+ Plus,
+ OpenBracket,
+ CloseBracket,
+ Pipe,
Tilde,
Semicolon,
- Apostrophe,
- Grave,
+ Quote,
+ Backquote,
Comma,
- Dot,
+ Period,
Slash,
CapsLockKey,
@@ -199,7 +198,7 @@ enum Keys {
F11,
F12,
- SystemRequest,
+ PrintScreen,
ScrollLockKey,
Pause,
Insert,
@@ -268,8 +267,18 @@ enum Keys {
ScrollLockActive,
KPComma,
- KPLeftParenthesis,
- KPRightParenthesis,
+ Ro = 0x87,
+ KatakanaHiragana,
+ Yen,
+ Henkan,
+ Muhenkan,
+ NumPadCommaPc98,
+
+ HangulEnglish = 0x90,
+ Hanja,
+ KatakanaKey,
+ HiraganaKey,
+ ZenkakuHankaku,
LeftControlKey = 0xE0,
LeftShiftKey,
@@ -318,6 +327,8 @@ enum Modifiers {
CapsLock,
ScrollLock,
NumLock,
+ Katakana,
+ Hiragana,
NumKeyboardMods,
};
diff --git a/src/core/hid/emulated_devices.cpp b/src/core/hid/emulated_devices.cpp
index e97470240..0d840a003 100644
--- a/src/core/hid/emulated_devices.cpp
+++ b/src/core/hid/emulated_devices.cpp
@@ -170,13 +170,14 @@ void EmulatedDevices::SetKeyboardButton(Common::Input::CallbackStatus callback,
return;
}
+ // Index should be converted from NativeKeyboard to KeyboardKeyIndex
UpdateKey(index, current_status.value);
TriggerOnChange(DeviceTriggerType::Keyboard);
}
void EmulatedDevices::UpdateKey(std::size_t key_index, bool status) {
- constexpr u8 KEYS_PER_BYTE = 8;
+ constexpr std::size_t KEYS_PER_BYTE = 8;
auto& entry = device_status.keyboard_state.key[key_index / KEYS_PER_BYTE];
const u8 mask = static_cast<u8>(1 << (key_index % KEYS_PER_BYTE));
if (status) {
diff --git a/src/core/hid/hid_types.h b/src/core/hid/hid_types.h
index 41bc65ce2..af95f3aff 100644
--- a/src/core/hid/hid_types.h
+++ b/src/core/hid/hid_types.h
@@ -12,6 +12,195 @@
namespace Core::HID {
+enum class DeviceIndex : u8 {
+ Left = 0,
+ Right = 1,
+ None = 2,
+ MaxDeviceIndex = 3,
+};
+
+// This is nn::hid::NpadButton
+enum class NpadButton : u64 {
+ None = 0,
+ A = 1U << 0,
+ B = 1U << 1,
+ X = 1U << 2,
+ Y = 1U << 3,
+ StickL = 1U << 4,
+ StickR = 1U << 5,
+ L = 1U << 6,
+ R = 1U << 7,
+ ZL = 1U << 8,
+ ZR = 1U << 9,
+ Plus = 1U << 10,
+ Minus = 1U << 11,
+
+ Left = 1U << 12,
+ Up = 1U << 13,
+ Right = 1U << 14,
+ Down = 1U << 15,
+
+ StickLLeft = 1U << 16,
+ StickLUp = 1U << 17,
+ StickLRight = 1U << 18,
+ StickLDown = 1U << 19,
+
+ StickRLeft = 1U << 20,
+ StickRUp = 1U << 21,
+ StickRRight = 1U << 22,
+ StickRDown = 1U << 23,
+
+ LeftSL = 1U << 24,
+ LeftSR = 1U << 25,
+
+ RightSL = 1U << 26,
+ RightSR = 1U << 27,
+
+ Palma = 1U << 28,
+ Verification = 1U << 29,
+ HandheldLeftB = 1U << 30,
+ LagonCLeft = 1U << 31,
+ LagonCUp = 1ULL << 32,
+ LagonCRight = 1ULL << 33,
+ LagonCDown = 1ULL << 34,
+};
+DECLARE_ENUM_FLAG_OPERATORS(NpadButton);
+
+enum class KeyboardKeyIndex : u32 {
+ A = 4,
+ B = 5,
+ C = 6,
+ D = 7,
+ E = 8,
+ F = 9,
+ G = 10,
+ H = 11,
+ I = 12,
+ J = 13,
+ K = 14,
+ L = 15,
+ M = 16,
+ N = 17,
+ O = 18,
+ P = 19,
+ Q = 20,
+ R = 21,
+ S = 22,
+ T = 23,
+ U = 24,
+ V = 25,
+ W = 26,
+ X = 27,
+ Y = 28,
+ Z = 29,
+ D1 = 30,
+ D2 = 31,
+ D3 = 32,
+ D4 = 33,
+ D5 = 34,
+ D6 = 35,
+ D7 = 36,
+ D8 = 37,
+ D9 = 38,
+ D0 = 39,
+ Return = 40,
+ Escape = 41,
+ Backspace = 42,
+ Tab = 43,
+ Space = 44,
+ Minus = 45,
+ Plus = 46,
+ OpenBracket = 47,
+ CloseBracket = 48,
+ Pipe = 49,
+ Tilde = 50,
+ Semicolon = 51,
+ Quote = 52,
+ Backquote = 53,
+ Comma = 54,
+ Period = 55,
+ Slash = 56,
+ CapsLock = 57,
+ F1 = 58,
+ F2 = 59,
+ F3 = 60,
+ F4 = 61,
+ F5 = 62,
+ F6 = 63,
+ F7 = 64,
+ F8 = 65,
+ F9 = 66,
+ F10 = 67,
+ F11 = 68,
+ F12 = 69,
+ PrintScreen = 70,
+ ScrollLock = 71,
+ Pause = 72,
+ Insert = 73,
+ Home = 74,
+ PageUp = 75,
+ Delete = 76,
+ End = 77,
+ PageDown = 78,
+ RightArrow = 79,
+ LeftArrow = 80,
+ DownArrow = 81,
+ UpArrow = 82,
+ NumLock = 83,
+ NumPadDivide = 84,
+ NumPadMultiply = 85,
+ NumPadSubtract = 86,
+ NumPadAdd = 87,
+ NumPadEnter = 88,
+ NumPad1 = 89,
+ NumPad2 = 90,
+ NumPad3 = 91,
+ NumPad4 = 92,
+ NumPad5 = 93,
+ NumPad6 = 94,
+ NumPad7 = 95,
+ NumPad8 = 96,
+ NumPad9 = 97,
+ NumPad0 = 98,
+ NumPadDot = 99,
+ Backslash = 100,
+ Application = 101,
+ Power = 102,
+ NumPadEquals = 103,
+ F13 = 104,
+ F14 = 105,
+ F15 = 106,
+ F16 = 107,
+ F17 = 108,
+ F18 = 109,
+ F19 = 110,
+ F20 = 111,
+ F21 = 112,
+ F22 = 113,
+ F23 = 114,
+ F24 = 115,
+ NumPadComma = 133,
+ Ro = 135,
+ KatakanaHiragana = 136,
+ Yen = 137,
+ Henkan = 138,
+ Muhenkan = 139,
+ NumPadCommaPc98 = 140,
+ HangulEnglish = 144,
+ Hanja = 145,
+ Katakana = 146,
+ Hiragana = 147,
+ ZenkakuHankaku = 148,
+ LeftControl = 224,
+ LeftShift = 225,
+ LeftAlt = 226,
+ LeftGui = 227,
+ RightControl = 228,
+ RightShift = 229,
+ RightAlt = 230,
+ RightGui = 231,
+};
+
// This is nn::hid::NpadIdType
enum class NpadIdType : u32 {
Player1 = 0x0,
@@ -28,62 +217,6 @@ enum class NpadIdType : u32 {
Invalid = 0xFFFFFFFF,
};
-/// Converts a NpadIdType to an array index.
-constexpr size_t NpadIdTypeToIndex(NpadIdType npad_id_type) {
- switch (npad_id_type) {
- case NpadIdType::Player1:
- return 0;
- case NpadIdType::Player2:
- return 1;
- case NpadIdType::Player3:
- return 2;
- case NpadIdType::Player4:
- return 3;
- case NpadIdType::Player5:
- return 4;
- case NpadIdType::Player6:
- return 5;
- case NpadIdType::Player7:
- return 6;
- case NpadIdType::Player8:
- return 7;
- case NpadIdType::Handheld:
- return 8;
- case NpadIdType::Other:
- return 9;
- default:
- return 0;
- }
-}
-
-/// Converts an array index to a NpadIdType
-constexpr NpadIdType IndexToNpadIdType(size_t index) {
- switch (index) {
- case 0:
- return NpadIdType::Player1;
- case 1:
- return NpadIdType::Player2;
- case 2:
- return NpadIdType::Player3;
- case 3:
- return NpadIdType::Player4;
- case 4:
- return NpadIdType::Player5;
- case 5:
- return NpadIdType::Player6;
- case 6:
- return NpadIdType::Player7;
- case 7:
- return NpadIdType::Player8;
- case 8:
- return NpadIdType::Handheld;
- case 9:
- return NpadIdType::Other;
- default:
- return NpadIdType::Invalid;
- }
-}
-
// This is nn::hid::NpadStyleIndex
enum class NpadStyleIndex : u8 {
None = 0,
@@ -124,6 +257,27 @@ enum class NpadStyleSet : u32 {
};
static_assert(sizeof(NpadStyleSet) == 4, "NpadStyleSet is an invalid size");
+// This is nn::hid::VibrationDevicePosition
+enum class VibrationDevicePosition : u32 {
+ None = 0,
+ Left = 1,
+ Right = 2,
+};
+
+// This is nn::hid::VibrationDeviceType
+enum class VibrationDeviceType : u32 {
+ Unknown = 0,
+ LinearResonantActuator = 1,
+ GcErm = 2,
+};
+
+// This is nn::hid::VibrationGcErmCommand
+enum class VibrationGcErmCommand : u64 {
+ Stop = 0,
+ Start = 1,
+ StopHard = 2,
+};
+
// This is nn::hid::NpadStyleTag
struct NpadStyleTag {
union {
@@ -220,53 +374,6 @@ struct LedPattern {
};
};
-// This is nn::hid::NpadButton
-enum class NpadButton : u64 {
- None = 0,
- A = 1U << 0,
- B = 1U << 1,
- X = 1U << 2,
- Y = 1U << 3,
- StickL = 1U << 4,
- StickR = 1U << 5,
- L = 1U << 6,
- R = 1U << 7,
- ZL = 1U << 8,
- ZR = 1U << 9,
- Plus = 1U << 10,
- Minus = 1U << 11,
-
- Left = 1U << 12,
- Up = 1U << 13,
- Right = 1U << 14,
- Down = 1U << 15,
-
- StickLLeft = 1U << 16,
- StickLUp = 1U << 17,
- StickLRight = 1U << 18,
- StickLDown = 1U << 19,
-
- StickRLeft = 1U << 20,
- StickRUp = 1U << 21,
- StickRRight = 1U << 22,
- StickRDown = 1U << 23,
-
- LeftSL = 1U << 24,
- LeftSR = 1U << 25,
-
- RightSL = 1U << 26,
- RightSR = 1U << 27,
-
- Palma = 1U << 28,
- Verification = 1U << 29,
- HandheldLeftB = 1U << 30,
- LagonCLeft = 1U << 31,
- LagonCUp = 1ULL << 32,
- LagonCRight = 1ULL << 33,
- LagonCDown = 1ULL << 34,
-};
-DECLARE_ENUM_FLAG_OPERATORS(NpadButton);
-
struct NpadButtonState {
union {
NpadButton raw{};
@@ -342,13 +449,6 @@ struct DebugPadButton {
};
static_assert(sizeof(DebugPadButton) == 0x4, "DebugPadButton is an invalid size");
-enum class DeviceIndex : u8 {
- Left = 0,
- Right = 1,
- None = 2,
- MaxDeviceIndex = 3,
-};
-
// This is nn::hid::ConsoleSixAxisSensorHandle
struct ConsoleSixAxisSensorHandle {
u8 unknown_1;
@@ -383,20 +483,6 @@ struct VibrationDeviceHandle {
};
static_assert(sizeof(VibrationDeviceHandle) == 4, "SixAxisSensorHandle is an invalid size");
-// This is nn::hid::VibrationDeviceType
-enum class VibrationDeviceType : u32 {
- Unknown = 0,
- LinearResonantActuator = 1,
- GcErm = 2,
-};
-
-// This is nn::hid::VibrationDevicePosition
-enum class VibrationDevicePosition : u32 {
- None = 0,
- Left = 1,
- Right = 2,
-};
-
// This is nn::hid::VibrationValue
struct VibrationValue {
f32 low_amplitude;
@@ -406,13 +492,6 @@ struct VibrationValue {
};
static_assert(sizeof(VibrationValue) == 0x10, "VibrationValue has incorrect size.");
-// This is nn::hid::VibrationGcErmCommand
-enum class VibrationGcErmCommand : u64 {
- Stop = 0,
- Start = 1,
- StopHard = 2,
-};
-
// This is nn::hid::VibrationDeviceInfo
struct VibrationDeviceInfo {
VibrationDeviceType type{};
@@ -482,4 +561,61 @@ struct MouseState {
MouseAttribute attribute;
};
static_assert(sizeof(MouseState) == 0x28, "MouseState is an invalid size");
+
+/// Converts a NpadIdType to an array index.
+constexpr size_t NpadIdTypeToIndex(NpadIdType npad_id_type) {
+ switch (npad_id_type) {
+ case NpadIdType::Player1:
+ return 0;
+ case NpadIdType::Player2:
+ return 1;
+ case NpadIdType::Player3:
+ return 2;
+ case NpadIdType::Player4:
+ return 3;
+ case NpadIdType::Player5:
+ return 4;
+ case NpadIdType::Player6:
+ return 5;
+ case NpadIdType::Player7:
+ return 6;
+ case NpadIdType::Player8:
+ return 7;
+ case NpadIdType::Handheld:
+ return 8;
+ case NpadIdType::Other:
+ return 9;
+ default:
+ return 0;
+ }
+}
+
+/// Converts an array index to a NpadIdType
+constexpr NpadIdType IndexToNpadIdType(size_t index) {
+ switch (index) {
+ case 0:
+ return NpadIdType::Player1;
+ case 1:
+ return NpadIdType::Player2;
+ case 2:
+ return NpadIdType::Player3;
+ case 3:
+ return NpadIdType::Player4;
+ case 4:
+ return NpadIdType::Player5;
+ case 5:
+ return NpadIdType::Player6;
+ case 6:
+ return NpadIdType::Player7;
+ case 7:
+ return NpadIdType::Player8;
+ case 8:
+ return NpadIdType::Handheld;
+ case 9:
+ return NpadIdType::Other;
+ default:
+ return NpadIdType::Invalid;
+ }
+}
+
} // namespace Core::HID
diff --git a/src/core/hle/service/hid/controllers/keyboard.cpp b/src/core/hle/service/hid/controllers/keyboard.cpp
index d6505dbc5..0ef8af0e6 100644
--- a/src/core/hle/service/hid/controllers/keyboard.cpp
+++ b/src/core/hle/service/hid/controllers/keyboard.cpp
@@ -42,6 +42,7 @@ void Controller_Keyboard::OnUpdate(const Core::Timing::CoreTiming& core_timing,
next_state.key = keyboard_state;
next_state.modifier = keyboard_modifier_state;
+ // This is always enabled on HW. Check what it actually does
next_state.modifier.unknown.Assign(1);
}
diff --git a/src/core/hle/service/hid/hid.cpp b/src/core/hle/service/hid/hid.cpp
index 496b55d0e..e740b4331 100644
--- a/src/core/hle/service/hid/hid.cpp
+++ b/src/core/hle/service/hid/hid.cpp
@@ -35,8 +35,9 @@ namespace Service::HID {
// Updating period for each HID device.
// Period time is obtained by measuring the number of samples in a second on HW using a homebrew
-constexpr auto pad_update_ns = std::chrono::nanoseconds{4 * 1000 * 1000}; // (4ms, 250Hz)
-constexpr auto motion_update_ns = std::chrono::nanoseconds{5 * 1000 * 1000}; // (5ms, 200Hz)
+constexpr auto pad_update_ns = std::chrono::nanoseconds{4 * 1000 * 1000}; // (4ms, 250Hz)
+constexpr auto keyboard_update_ns = std::chrono::nanoseconds{8 * 1000 * 1000}; // (8ms, 125Hz)
+constexpr auto motion_update_ns = std::chrono::nanoseconds{5 * 1000 * 1000}; // (5ms, 200Hz)
constexpr std::size_t SHARED_MEMORY_SIZE = 0x40000;
IAppletResource::IAppletResource(Core::System& system_,
@@ -78,14 +79,21 @@ IAppletResource::IAppletResource(Core::System& system_,
const auto guard = LockService();
UpdateControllers(user_data, ns_late);
});
+ keyboard_update_event = Core::Timing::CreateEvent(
+ "HID::UpdatekeyboardCallback",
+ [this](std::uintptr_t user_data, std::chrono::nanoseconds ns_late) {
+ const auto guard = LockService();
+ UpdateKeyboard(user_data, ns_late);
+ });
motion_update_event = Core::Timing::CreateEvent(
- "HID::MotionPadCallback",
+ "HID::UpdateMotionCallback",
[this](std::uintptr_t user_data, std::chrono::nanoseconds ns_late) {
const auto guard = LockService();
UpdateMotion(user_data, ns_late);
});
system.CoreTiming().ScheduleEvent(pad_update_ns, pad_update_event);
+ system.CoreTiming().ScheduleEvent(keyboard_update_ns, keyboard_update_event);
system.CoreTiming().ScheduleEvent(motion_update_ns, motion_update_event);
system.HIDCore().ReloadInputDevices();
@@ -101,6 +109,7 @@ void IAppletResource::DeactivateController(HidController controller) {
IAppletResource::~IAppletResource() {
system.CoreTiming().UnscheduleEvent(pad_update_event, 0);
+ system.CoreTiming().UnscheduleEvent(keyboard_update_event, 0);
system.CoreTiming().UnscheduleEvent(motion_update_event, 0);
}
@@ -117,18 +126,36 @@ void IAppletResource::UpdateControllers(std::uintptr_t user_data,
auto& core_timing = system.CoreTiming();
for (const auto& controller : controllers) {
+ // Keyboard has it's own update event
+ if (controller == controllers[static_cast<size_t>(HidController::Keyboard)]) {
+ continue;
+ }
controller->OnUpdate(core_timing, system.Kernel().GetHidSharedMem().GetPointer(),
SHARED_MEMORY_SIZE);
}
// If ns_late is higher than the update rate ignore the delay
- if (ns_late > motion_update_ns) {
+ if (ns_late > pad_update_ns) {
ns_late = {};
}
core_timing.ScheduleEvent(pad_update_ns - ns_late, pad_update_event);
}
+void IAppletResource::UpdateKeyboard(std::uintptr_t user_data, std::chrono::nanoseconds ns_late) {
+ auto& core_timing = system.CoreTiming();
+
+ controllers[static_cast<size_t>(HidController::Keyboard)]->OnUpdate(
+ core_timing, system.Kernel().GetHidSharedMem().GetPointer(), SHARED_MEMORY_SIZE);
+
+ // If ns_late is higher than the update rate ignore the delay
+ if (ns_late > keyboard_update_ns) {
+ ns_late = {};
+ }
+
+ core_timing.ScheduleEvent(keyboard_update_ns - ns_late, keyboard_update_event);
+}
+
void IAppletResource::UpdateMotion(std::uintptr_t user_data, std::chrono::nanoseconds ns_late) {
auto& core_timing = system.CoreTiming();
diff --git a/src/core/hle/service/hid/hid.h b/src/core/hle/service/hid/hid.h
index 973e6a8ac..bbad165f8 100644
--- a/src/core/hle/service/hid/hid.h
+++ b/src/core/hle/service/hid/hid.h
@@ -70,11 +70,13 @@ private:
void GetSharedMemoryHandle(Kernel::HLERequestContext& ctx);
void UpdateControllers(std::uintptr_t user_data, std::chrono::nanoseconds ns_late);
+ void UpdateKeyboard(std::uintptr_t user_data, std::chrono::nanoseconds ns_late);
void UpdateMotion(std::uintptr_t user_data, std::chrono::nanoseconds ns_late);
KernelHelpers::ServiceContext& service_context;
std::shared_ptr<Core::Timing::EventType> pad_update_event;
+ std::shared_ptr<Core::Timing::EventType> keyboard_update_event;
std::shared_ptr<Core::Timing::EventType> motion_update_event;
std::array<std::unique_ptr<ControllerBase>, static_cast<size_t>(HidController::MaxControllers)>
diff --git a/src/input_common/drivers/keyboard.cpp b/src/input_common/drivers/keyboard.cpp
index 549704e89..328fe1ac1 100644
--- a/src/input_common/drivers/keyboard.cpp
+++ b/src/input_common/drivers/keyboard.cpp
@@ -3,26 +3,71 @@
// Refer to the license.txt file included
#include "common/param_package.h"
+#include "common/settings_input.h"
#include "input_common/drivers/keyboard.h"
namespace InputCommon {
-constexpr PadIdentifier identifier = {
+constexpr PadIdentifier key_identifier = {
.guid = Common::UUID{Common::INVALID_UUID},
.port = 0,
.pad = 0,
};
+constexpr PadIdentifier modifier_identifier = {
+ .guid = Common::UUID{Common::INVALID_UUID},
+ .port = 0,
+ .pad = 1,
+};
Keyboard::Keyboard(const std::string& input_engine_) : InputEngine(input_engine_) {
- PreSetController(identifier);
+ PreSetController(key_identifier);
+ PreSetController(modifier_identifier);
}
void Keyboard::PressKey(int key_code) {
- SetButton(identifier, key_code, true);
+ SetButton(key_identifier, key_code, true);
}
void Keyboard::ReleaseKey(int key_code) {
- SetButton(identifier, key_code, false);
+ SetButton(key_identifier, key_code, false);
+}
+
+void Keyboard::SetModifiers(int key_modifiers) {
+ for (int i = 0; i < 32; ++i) {
+ bool key_value = ((key_modifiers >> i) & 0x1) != 0;
+ SetButton(modifier_identifier, i, key_value);
+ // Use the modifier to press the key button equivalent
+ switch (i) {
+ case Settings::NativeKeyboard::LeftControl:
+ SetButton(key_identifier, Settings::NativeKeyboard::LeftControlKey, key_value);
+ break;
+ case Settings::NativeKeyboard::LeftShift:
+ SetButton(key_identifier, Settings::NativeKeyboard::LeftShiftKey, key_value);
+ break;
+ case Settings::NativeKeyboard::LeftAlt:
+ SetButton(key_identifier, Settings::NativeKeyboard::LeftAltKey, key_value);
+ break;
+ case Settings::NativeKeyboard::LeftMeta:
+ SetButton(key_identifier, Settings::NativeKeyboard::LeftMetaKey, key_value);
+ break;
+ case Settings::NativeKeyboard::RightControl:
+ SetButton(key_identifier, Settings::NativeKeyboard::RightControlKey, key_value);
+ break;
+ case Settings::NativeKeyboard::RightShift:
+ SetButton(key_identifier, Settings::NativeKeyboard::RightShiftKey, key_value);
+ break;
+ case Settings::NativeKeyboard::RightAlt:
+ SetButton(key_identifier, Settings::NativeKeyboard::RightAltKey, key_value);
+ break;
+ case Settings::NativeKeyboard::RightMeta:
+ SetButton(key_identifier, Settings::NativeKeyboard::RightMetaKey, key_value);
+ break;
+ default:
+ // Other modifier keys should be pressed with PressKey since they stay enabled until
+ // next press
+ break;
+ }
+ }
}
void Keyboard::ReleaseAllKeys() {
diff --git a/src/input_common/drivers/keyboard.h b/src/input_common/drivers/keyboard.h
index 46fe78576..2ab92fd6c 100644
--- a/src/input_common/drivers/keyboard.h
+++ b/src/input_common/drivers/keyboard.h
@@ -28,6 +28,13 @@ public:
*/
void ReleaseKey(int key_code);
+ /**
+ * Sets the status of all keyboard modifier keys
+ * @param key_modifiers the code of the key to release
+ */
+ void SetModifiers(int key_modifiers);
+
+ /// Sets all keys to the non pressed state
void ReleaseAllKeys();
/// Used for automapping features
diff --git a/src/input_common/main.cpp b/src/input_common/main.cpp
index df36a337c..ae2518f53 100644
--- a/src/input_common/main.cpp
+++ b/src/input_common/main.cpp
@@ -402,6 +402,15 @@ std::string GenerateKeyboardParam(int key_code) {
return param.Serialize();
}
+std::string GenerateModdifierKeyboardParam(int key_code) {
+ Common::ParamPackage param;
+ param.Set("engine", "keyboard");
+ param.Set("code", key_code);
+ param.Set("toggle", false);
+ param.Set("pad", 1);
+ return param.Serialize();
+}
+
std::string GenerateAnalogParamFromKeys(int key_up, int key_down, int key_left, int key_right,
int key_modifier, float modifier_scale) {
Common::ParamPackage circle_pad_param{
diff --git a/src/input_common/main.h b/src/input_common/main.h
index a4a24d076..9ea395465 100644
--- a/src/input_common/main.h
+++ b/src/input_common/main.h
@@ -134,6 +134,9 @@ private:
/// Generates a serialized param package for creating a keyboard button device.
std::string GenerateKeyboardParam(int key_code);
+/// Generates a serialized param package for creating a moddifier keyboard button device.
+std::string GenerateModdifierKeyboardParam(int key_code);
+
/// Generates a serialized param package for creating an analog device taking input from keyboard.
std::string GenerateAnalogParamFromKeys(int key_up, int key_down, int key_left, int key_right,
int key_modifier, float modifier_scale);
diff --git a/src/yuzu/bootmanager.cpp b/src/yuzu/bootmanager.cpp
index 3c5590a01..61513a5b4 100644
--- a/src/yuzu/bootmanager.cpp
+++ b/src/yuzu/bootmanager.cpp
@@ -392,15 +392,287 @@ void GRenderWindow::closeEvent(QCloseEvent* event) {
QWidget::closeEvent(event);
}
+int GRenderWindow::QtKeyToSwitchKey(Qt::Key qt_key) {
+ switch (qt_key) {
+ case Qt::Key_A:
+ return Settings::NativeKeyboard::A;
+ case Qt::Key_B:
+ return Settings::NativeKeyboard::B;
+ case Qt::Key_C:
+ return Settings::NativeKeyboard::C;
+ case Qt::Key_D:
+ return Settings::NativeKeyboard::D;
+ case Qt::Key_E:
+ return Settings::NativeKeyboard::E;
+ case Qt::Key_F:
+ return Settings::NativeKeyboard::F;
+ case Qt::Key_G:
+ return Settings::NativeKeyboard::G;
+ case Qt::Key_H:
+ return Settings::NativeKeyboard::H;
+ case Qt::Key_I:
+ return Settings::NativeKeyboard::I;
+ case Qt::Key_J:
+ return Settings::NativeKeyboard::J;
+ case Qt::Key_K:
+ return Settings::NativeKeyboard::K;
+ case Qt::Key_L:
+ return Settings::NativeKeyboard::L;
+ case Qt::Key_M:
+ return Settings::NativeKeyboard::M;
+ case Qt::Key_N:
+ return Settings::NativeKeyboard::N;
+ case Qt::Key_O:
+ return Settings::NativeKeyboard::O;
+ case Qt::Key_P:
+ return Settings::NativeKeyboard::P;
+ case Qt::Key_Q:
+ return Settings::NativeKeyboard::Q;
+ case Qt::Key_R:
+ return Settings::NativeKeyboard::R;
+ case Qt::Key_S:
+ return Settings::NativeKeyboard::S;
+ case Qt::Key_T:
+ return Settings::NativeKeyboard::T;
+ case Qt::Key_U:
+ return Settings::NativeKeyboard::U;
+ case Qt::Key_V:
+ return Settings::NativeKeyboard::V;
+ case Qt::Key_W:
+ return Settings::NativeKeyboard::W;
+ case Qt::Key_X:
+ return Settings::NativeKeyboard::X;
+ case Qt::Key_Y:
+ return Settings::NativeKeyboard::Y;
+ case Qt::Key_Z:
+ return Settings::NativeKeyboard::Z;
+ case Qt::Key_1:
+ return Settings::NativeKeyboard::N1;
+ case Qt::Key_2:
+ return Settings::NativeKeyboard::N2;
+ case Qt::Key_3:
+ return Settings::NativeKeyboard::N3;
+ case Qt::Key_4:
+ return Settings::NativeKeyboard::N4;
+ case Qt::Key_5:
+ return Settings::NativeKeyboard::N5;
+ case Qt::Key_6:
+ return Settings::NativeKeyboard::N6;
+ case Qt::Key_7:
+ return Settings::NativeKeyboard::N7;
+ case Qt::Key_8:
+ return Settings::NativeKeyboard::N8;
+ case Qt::Key_9:
+ return Settings::NativeKeyboard::N9;
+ case Qt::Key_0:
+ return Settings::NativeKeyboard::N0;
+ case Qt::Key_Return:
+ return Settings::NativeKeyboard::Return;
+ case Qt::Key_Escape:
+ return Settings::NativeKeyboard::Escape;
+ case Qt::Key_Backspace:
+ return Settings::NativeKeyboard::Backspace;
+ case Qt::Key_Tab:
+ return Settings::NativeKeyboard::Tab;
+ case Qt::Key_Space:
+ return Settings::NativeKeyboard::Space;
+ case Qt::Key_Minus:
+ return Settings::NativeKeyboard::Minus;
+ case Qt::Key_Plus:
+ case Qt::Key_questiondown:
+ return Settings::NativeKeyboard::Plus;
+ case Qt::Key_BracketLeft:
+ case Qt::Key_BraceLeft:
+ return Settings::NativeKeyboard::OpenBracket;
+ case Qt::Key_BracketRight:
+ case Qt::Key_BraceRight:
+ return Settings::NativeKeyboard::CloseBracket;
+ case Qt::Key_Bar:
+ return Settings::NativeKeyboard::Pipe;
+ case Qt::Key_Dead_Tilde:
+ return Settings::NativeKeyboard::Tilde;
+ case Qt::Key_Ntilde:
+ case Qt::Key_Semicolon:
+ return Settings::NativeKeyboard::Semicolon;
+ case Qt::Key_Apostrophe:
+ return Settings::NativeKeyboard::Quote;
+ case Qt::Key_Dead_Grave:
+ return Settings::NativeKeyboard::Backquote;
+ case Qt::Key_Comma:
+ return Settings::NativeKeyboard::Comma;
+ case Qt::Key_Period:
+ return Settings::NativeKeyboard::Period;
+ case Qt::Key_Slash:
+ return Settings::NativeKeyboard::Slash;
+ case Qt::Key_CapsLock:
+ return Settings::NativeKeyboard::CapsLock;
+ case Qt::Key_F1:
+ return Settings::NativeKeyboard::F1;
+ case Qt::Key_F2:
+ return Settings::NativeKeyboard::F2;
+ case Qt::Key_F3:
+ return Settings::NativeKeyboard::F3;
+ case Qt::Key_F4:
+ return Settings::NativeKeyboard::F4;
+ case Qt::Key_F5:
+ return Settings::NativeKeyboard::F5;
+ case Qt::Key_F6:
+ return Settings::NativeKeyboard::F6;
+ case Qt::Key_F7:
+ return Settings::NativeKeyboard::F7;
+ case Qt::Key_F8:
+ return Settings::NativeKeyboard::F8;
+ case Qt::Key_F9:
+ return Settings::NativeKeyboard::F9;
+ case Qt::Key_F10:
+ return Settings::NativeKeyboard::F10;
+ case Qt::Key_F11:
+ return Settings::NativeKeyboard::F11;
+ case Qt::Key_F12:
+ return Settings::NativeKeyboard::F12;
+ case Qt::Key_Print:
+ return Settings::NativeKeyboard::PrintScreen;
+ case Qt::Key_ScrollLock:
+ return Settings::NativeKeyboard::ScrollLock;
+ case Qt::Key_Pause:
+ return Settings::NativeKeyboard::Pause;
+ case Qt::Key_Insert:
+ return Settings::NativeKeyboard::Insert;
+ case Qt::Key_Home:
+ return Settings::NativeKeyboard::Home;
+ case Qt::Key_PageUp:
+ return Settings::NativeKeyboard::PageUp;
+ case Qt::Key_Delete:
+ return Settings::NativeKeyboard::Delete;
+ case Qt::Key_End:
+ return Settings::NativeKeyboard::End;
+ case Qt::Key_PageDown:
+ return Settings::NativeKeyboard::PageDown;
+ case Qt::Key_Right:
+ return Settings::NativeKeyboard::Right;
+ case Qt::Key_Left:
+ return Settings::NativeKeyboard::Left;
+ case Qt::Key_Down:
+ return Settings::NativeKeyboard::Down;
+ case Qt::Key_Up:
+ return Settings::NativeKeyboard::Up;
+ case Qt::Key_NumLock:
+ return Settings::NativeKeyboard::NumLock;
+ // Numpad keys are missing here
+ case Qt::Key_F13:
+ return Settings::NativeKeyboard::F13;
+ case Qt::Key_F14:
+ return Settings::NativeKeyboard::F14;
+ case Qt::Key_F15:
+ return Settings::NativeKeyboard::F15;
+ case Qt::Key_F16:
+ return Settings::NativeKeyboard::F16;
+ case Qt::Key_F17:
+ return Settings::NativeKeyboard::F17;
+ case Qt::Key_F18:
+ return Settings::NativeKeyboard::F18;
+ case Qt::Key_F19:
+ return Settings::NativeKeyboard::F19;
+ case Qt::Key_F20:
+ return Settings::NativeKeyboard::F20;
+ case Qt::Key_F21:
+ return Settings::NativeKeyboard::F21;
+ case Qt::Key_F22:
+ return Settings::NativeKeyboard::F22;
+ case Qt::Key_F23:
+ return Settings::NativeKeyboard::F23;
+ case Qt::Key_F24:
+ return Settings::NativeKeyboard::F24;
+ // case Qt:::
+ // return Settings::NativeKeyboard::KPComma;
+ // case Qt:::
+ // return Settings::NativeKeyboard::Ro;
+ case Qt::Key_Hiragana_Katakana:
+ return Settings::NativeKeyboard::KatakanaHiragana;
+ case Qt::Key_yen:
+ return Settings::NativeKeyboard::Yen;
+ case Qt::Key_Henkan:
+ return Settings::NativeKeyboard::Henkan;
+ case Qt::Key_Muhenkan:
+ return Settings::NativeKeyboard::Muhenkan;
+ // case Qt:::
+ // return Settings::NativeKeyboard::NumPadCommaPc98;
+ case Qt::Key_Hangul:
+ return Settings::NativeKeyboard::HangulEnglish;
+ case Qt::Key_Hangul_Hanja:
+ return Settings::NativeKeyboard::Hanja;
+ case Qt::Key_Katakana:
+ return Settings::NativeKeyboard::KatakanaKey;
+ case Qt::Key_Hiragana:
+ return Settings::NativeKeyboard::HiraganaKey;
+ case Qt::Key_Zenkaku_Hankaku:
+ return Settings::NativeKeyboard::ZenkakuHankaku;
+ // Modifier keys are handled by the modifier property
+ default:
+ return 0;
+ }
+}
+
+int GRenderWindow::QtModifierToSwitchModdifier(quint32 qt_moddifiers) {
+ int moddifier = 0;
+ // The values are obtained through testing, Qt doesn't seem to provide a proper enum
+ if ((qt_moddifiers & 0x1) != 0) {
+ moddifier |= 1 << Settings::NativeKeyboard::LeftShift;
+ }
+ if ((qt_moddifiers & 0x2) != 0) {
+ moddifier |= 1 << Settings::NativeKeyboard::LeftControl;
+ }
+ if ((qt_moddifiers & 0x4) != 0) {
+ moddifier |= 1 << Settings::NativeKeyboard::LeftAlt;
+ }
+ if ((qt_moddifiers & 0x08) != 0) {
+ moddifier |= 1 << Settings::NativeKeyboard::LeftMeta;
+ }
+ if ((qt_moddifiers & 0x10) != 0) {
+ moddifier |= 1 << Settings::NativeKeyboard::RightShift;
+ }
+ if ((qt_moddifiers & 0x20) != 0) {
+ moddifier |= 1 << Settings::NativeKeyboard::RightControl;
+ }
+ if ((qt_moddifiers & 0x40) != 0) {
+ moddifier |= 1 << Settings::NativeKeyboard::RightAlt;
+ }
+ if ((qt_moddifiers & 0x80) != 0) {
+ moddifier |= 1 << Settings::NativeKeyboard::RightMeta;
+ }
+ if ((qt_moddifiers & 0x100) != 0) {
+ moddifier |= 1 << Settings::NativeKeyboard::CapsLock;
+ }
+ if ((qt_moddifiers & 0x200) != 0) {
+ moddifier |= 1 << Settings::NativeKeyboard::NumLock;
+ }
+ // Verify the last two keys
+ if ((qt_moddifiers & 0x400) != 0) {
+ moddifier |= 1 << Settings::NativeKeyboard::Katakana;
+ }
+ if ((qt_moddifiers & 0x800) != 0) {
+ moddifier |= 1 << Settings::NativeKeyboard::Hiragana;
+ }
+ return moddifier;
+}
+
void GRenderWindow::keyPressEvent(QKeyEvent* event) {
if (!event->isAutoRepeat()) {
- input_subsystem->GetKeyboard()->PressKey(event->key());
+ const auto moddifier = QtModifierToSwitchModdifier(event->nativeModifiers());
+ // Replace event->key() with event->nativeVirtualKey() since the second one provides raw key
+ // buttons
+ const auto key = QtKeyToSwitchKey(Qt::Key(event->key()));
+ input_subsystem->GetKeyboard()->SetModifiers(moddifier);
+ input_subsystem->GetKeyboard()->PressKey(key);
}
}
void GRenderWindow::keyReleaseEvent(QKeyEvent* event) {
if (!event->isAutoRepeat()) {
- input_subsystem->GetKeyboard()->ReleaseKey(event->key());
+ const auto moddifier = QtModifierToSwitchModdifier(event->nativeModifiers());
+ const auto key = QtKeyToSwitchKey(Qt::Key(event->key()));
+ input_subsystem->GetKeyboard()->SetModifiers(moddifier);
+ input_subsystem->GetKeyboard()->ReleaseKey(key);
}
}
diff --git a/src/yuzu/bootmanager.h b/src/yuzu/bootmanager.h
index 95594f81c..c42d139be 100644
--- a/src/yuzu/bootmanager.h
+++ b/src/yuzu/bootmanager.h
@@ -158,6 +158,12 @@ public:
void resizeEvent(QResizeEvent* event) override;
+ /// Converts a Qt keybard key into NativeKeyboard key
+ static int QtKeyToSwitchKey(Qt::Key qt_keys);
+
+ /// Converts a Qt modifier keys into NativeKeyboard modifier keys
+ static int QtModifierToSwitchModdifier(quint32 qt_moddifiers);
+
void keyPressEvent(QKeyEvent* event) override;
void keyReleaseEvent(QKeyEvent* event) override;
diff --git a/src/yuzu/configuration/config.cpp b/src/yuzu/configuration/config.cpp
index 7669fe474..ccf274895 100644
--- a/src/yuzu/configuration/config.cpp
+++ b/src/yuzu/configuration/config.cpp
@@ -65,157 +65,6 @@ const std::array<int, Settings::NativeMouseButton::NumMouseButtons> Config::defa
Qt::Key_BracketLeft, Qt::Key_BracketRight, Qt::Key_Apostrophe, Qt::Key_Minus, Qt::Key_Equal,
};
-const std::array<int, Settings::NativeKeyboard::NumKeyboardKeys> Config::default_keyboard_keys = {
- 0,
- 0,
- 0,
- 0,
- Qt::Key_A,
- Qt::Key_B,
- Qt::Key_C,
- Qt::Key_D,
- Qt::Key_E,
- Qt::Key_F,
- Qt::Key_G,
- Qt::Key_H,
- Qt::Key_I,
- Qt::Key_J,
- Qt::Key_K,
- Qt::Key_L,
- Qt::Key_M,
- Qt::Key_N,
- Qt::Key_O,
- Qt::Key_P,
- Qt::Key_Q,
- Qt::Key_R,
- Qt::Key_S,
- Qt::Key_T,
- Qt::Key_U,
- Qt::Key_V,
- Qt::Key_W,
- Qt::Key_X,
- Qt::Key_Y,
- Qt::Key_Z,
- Qt::Key_1,
- Qt::Key_2,
- Qt::Key_3,
- Qt::Key_4,
- Qt::Key_5,
- Qt::Key_6,
- Qt::Key_7,
- Qt::Key_8,
- Qt::Key_9,
- Qt::Key_0,
- Qt::Key_Enter,
- Qt::Key_Escape,
- Qt::Key_Backspace,
- Qt::Key_Tab,
- Qt::Key_Space,
- Qt::Key_Minus,
- Qt::Key_Equal,
- Qt::Key_BracketLeft,
- Qt::Key_BracketRight,
- Qt::Key_Backslash,
- Qt::Key_Dead_Tilde,
- Qt::Key_Semicolon,
- Qt::Key_Apostrophe,
- Qt::Key_Dead_Grave,
- Qt::Key_Comma,
- Qt::Key_Period,
- Qt::Key_Slash,
- Qt::Key_CapsLock,
-
- Qt::Key_F1,
- Qt::Key_F2,
- Qt::Key_F3,
- Qt::Key_F4,
- Qt::Key_F5,
- Qt::Key_F6,
- Qt::Key_F7,
- Qt::Key_F8,
- Qt::Key_F9,
- Qt::Key_F10,
- Qt::Key_F11,
- Qt::Key_F12,
-
- Qt::Key_SysReq,
- Qt::Key_ScrollLock,
- Qt::Key_Pause,
- Qt::Key_Insert,
- Qt::Key_Home,
- Qt::Key_PageUp,
- Qt::Key_Delete,
- Qt::Key_End,
- Qt::Key_PageDown,
- Qt::Key_Right,
- Qt::Key_Left,
- Qt::Key_Down,
- Qt::Key_Up,
-
- Qt::Key_NumLock,
- Qt::Key_Slash,
- Qt::Key_Asterisk,
- Qt::Key_Minus,
- Qt::Key_Plus,
- Qt::Key_Enter,
- Qt::Key_1,
- Qt::Key_2,
- Qt::Key_3,
- Qt::Key_4,
- Qt::Key_5,
- Qt::Key_6,
- Qt::Key_7,
- Qt::Key_8,
- Qt::Key_9,
- Qt::Key_0,
- Qt::Key_Period,
-
- 0,
- 0,
- Qt::Key_PowerOff,
- Qt::Key_Equal,
-
- Qt::Key_F13,
- Qt::Key_F14,
- Qt::Key_F15,
- Qt::Key_F16,
- Qt::Key_F17,
- Qt::Key_F18,
- Qt::Key_F19,
- Qt::Key_F20,
- Qt::Key_F21,
- Qt::Key_F22,
- Qt::Key_F23,
- Qt::Key_F24,
-
- Qt::Key_Open,
- Qt::Key_Help,
- Qt::Key_Menu,
- 0,
- Qt::Key_Stop,
- Qt::Key_AudioRepeat,
- Qt::Key_Undo,
- Qt::Key_Cut,
- Qt::Key_Copy,
- Qt::Key_Paste,
- Qt::Key_Find,
- Qt::Key_VolumeMute,
- Qt::Key_VolumeUp,
- Qt::Key_VolumeDown,
- Qt::Key_CapsLock,
- Qt::Key_NumLock,
- Qt::Key_ScrollLock,
- Qt::Key_Comma,
-
- Qt::Key_ParenLeft,
- Qt::Key_ParenRight,
-};
-
-const std::array<int, Settings::NativeKeyboard::NumKeyboardMods> Config::default_keyboard_mods = {
- Qt::Key_Control, Qt::Key_Shift, Qt::Key_Alt, Qt::Key_ApplicationLeft,
- Qt::Key_Control, Qt::Key_Shift, Qt::Key_AltGr, Qt::Key_ApplicationRight,
-};
-
// This shouldn't have anything except static initializers (no functions). So
// QKeySequence(...).toString() is NOT ALLOWED HERE.
// This must be in alphabetical order according to action name as it must have the same order as
@@ -496,14 +345,14 @@ void Config::ReadDebugValues() {
void Config::ReadKeyboardValues() {
ReadBasicSetting(Settings::values.keyboard_enabled);
- std::transform(default_keyboard_keys.begin(), default_keyboard_keys.end(),
- Settings::values.keyboard_keys.begin(), InputCommon::GenerateKeyboardParam);
- std::transform(default_keyboard_mods.begin(), default_keyboard_mods.end(),
- Settings::values.keyboard_keys.begin() +
- Settings::NativeKeyboard::LeftControlKey,
- InputCommon::GenerateKeyboardParam);
- std::transform(default_keyboard_mods.begin(), default_keyboard_mods.end(),
- Settings::values.keyboard_mods.begin(), InputCommon::GenerateKeyboardParam);
+ for (std::size_t i = 0; i < Settings::values.keyboard_keys.size(); ++i) {
+ Settings::values.keyboard_keys[i] = InputCommon::GenerateKeyboardParam(static_cast<int>(i));
+ }
+
+ for (std::size_t i = 0; i < Settings::values.keyboard_mods.size(); ++i) {
+ Settings::values.keyboard_mods[i] =
+ InputCommon::GenerateModdifierKeyboardParam(static_cast<int>(i));
+ }
}
void Config::ReadMouseValues() {