From 99b43306f8c650a561eaef8eb836545069fe1db6 Mon Sep 17 00:00:00 2001 From: emoose Date: Wed, 15 Jan 2020 01:52:57 +0000 Subject: [PATCH] [XAM/HID] Add more support for keyboards & fill in unicode member of keystroke CoD4 requires the unicode member to write text into the dev console, Win32's ToUnicode function seems to work fine for this. Xam functions have been updated to support keyboard devices too, which *should* let CoD4 detect the keyboard and let you use it to open console etc.. Seems the XEX still needs a 1 byte patch for it to work tho :( no idea why, does keyboard work on actual X360 without any patching? --- src/xenia/hid/winkey/winkey_input_driver.cc | 12 ++++++++++-- src/xenia/hid/winkey/winkey_input_driver.h | 3 +++ src/xenia/kernel/xam/xam_input.cc | 11 +++++++---- 3 files changed, 20 insertions(+), 6 deletions(-) diff --git a/src/xenia/hid/winkey/winkey_input_driver.cc b/src/xenia/hid/winkey/winkey_input_driver.cc index 6812e2c1b..3be9ac27b 100644 --- a/src/xenia/hid/winkey/winkey_input_driver.cc +++ b/src/xenia/hid/winkey/winkey_input_driver.cc @@ -55,6 +55,8 @@ WinKeyInputDriver::WinKeyInputDriver(xe::ui::Window* window) key.repeat_count = evt->repeat_count(); key_events_.push(key); }); + + memset(key_map_, 0, 256); } WinKeyInputDriver::~WinKeyInputDriver() = default; @@ -289,6 +291,8 @@ X_RESULT WinKeyInputDriver::GetKeystroke(uint32_t user_index, uint32_t flags, key_events_.pop(); } + key_map_[evt.vkey] = evt.transition ? 0xFF : 0; + if (cvars::keyboard_passthru) { virtual_key = evt.vkey; } else { @@ -404,9 +408,9 @@ X_RESULT WinKeyInputDriver::GetKeystroke(uint32_t user_index, uint32_t flags, // Handle keydown & keyup: if (cvars::keyboard_keyup || virtual_key == VK_SHIFT) { if (evt.transition == false) { - keystroke_flags |= 0x0002; + keystroke_flags |= 0x0002; // XINPUT_KEYSTROKE_KEYUP } else if (evt.transition == true) { - keystroke_flags |= 0x0001; + keystroke_flags |= 0x0001; // XINPUT_KEYSTROKE_KEYDOWN } } else { if (!cvars::keyboard_keyup) { @@ -421,6 +425,10 @@ X_RESULT WinKeyInputDriver::GetKeystroke(uint32_t user_index, uint32_t flags, } if (keystroke_flags != 0) { + WCHAR buf; + if (ToUnicode(virtual_key, 0, key_map_, &buf, 1, 0) == 1) { + unicode = buf; + } result = X_ERROR_SUCCESS; } } diff --git a/src/xenia/hid/winkey/winkey_input_driver.h b/src/xenia/hid/winkey/winkey_input_driver.h index 36ba37551..cc9e9369a 100644 --- a/src/xenia/hid/winkey/winkey_input_driver.h +++ b/src/xenia/hid/winkey/winkey_input_driver.h @@ -47,6 +47,9 @@ class WinKeyInputDriver : public InputDriver { xe::global_critical_region global_critical_region_; std::queue key_events_; + // map of keys pressed for ToUnicode call - not guaranteed to be up-to-date + uint8_t key_map_[256]; + uint32_t packet_number_; uint32_t user_index_ = 1; diff --git a/src/xenia/kernel/xam/xam_input.cc b/src/xenia/kernel/xam/xam_input.cc index 6983ea739..2810555cb 100644 --- a/src/xenia/kernel/xam/xam_input.cc +++ b/src/xenia/kernel/xam/xam_input.cc @@ -46,7 +46,8 @@ dword_result_t XamInputGetCapabilities(dword_t user_index, dword_t flags, return X_ERROR_BAD_ARGUMENTS; } - if ((flags & 0xFF) && (flags & XINPUT_FLAG_GAMEPAD) == 0) { + if ((flags & 0xFF) && (flags & XINPUT_FLAG_GAMEPAD) == 0 && + (flags & XINPUT_FLAG_KEYBOARD) == 0) { // Ignore any query for other types of devices. return X_ERROR_DEVICE_NOT_CONNECTED; } @@ -69,7 +70,8 @@ dword_result_t XamInputGetCapabilitiesEx(dword_t unk, dword_t user_index, return X_ERROR_BAD_ARGUMENTS; } - if ((flags & 0xFF) && (flags & XINPUT_FLAG_GAMEPAD) == 0) { + if ((flags & 0xFF) && (flags & XINPUT_FLAG_GAMEPAD) == 0 && + (flags & XINPUT_FLAG_KEYBOARD) == 0) { // Ignore any query for other types of devices. return X_ERROR_DEVICE_NOT_CONNECTED; } @@ -135,7 +137,8 @@ dword_result_t XamInputGetKeystroke(dword_t user_index, dword_t flags, return X_ERROR_BAD_ARGUMENTS; } - if ((flags & 0xFF) && (flags & XINPUT_FLAG_GAMEPAD) == 0) { + if ((flags & 0xFF) && (flags & XINPUT_FLAG_GAMEPAD) == 0 && + (flags & XINPUT_FLAG_KEYBOARD) == 0) { // Ignore any query for other types of devices. return X_ERROR_DEVICE_NOT_CONNECTED; } @@ -172,7 +175,7 @@ dword_result_t XamInputGetKeystrokeEx(lpdword_t user_index_ptr, dword_t flags, auto input_system = kernel_state()->emulator()->input_system(); auto result = input_system->GetKeystroke(user_index, flags, keystroke); - if (XSUCCEEDED(result)) { + if (!result) { *user_index_ptr = keystroke->user_index; } return result;