[XAM/HID] Add keyboard_passthru cvar, allows XInputGetKeystroke to receive proper keyboard events
Maybe useful for debug games, or games modded to allow in-game consoles.
This commit is contained in:
parent
1b5df3ef0a
commit
79ea233a4a
|
@ -9,11 +9,18 @@
|
|||
|
||||
#include "xenia/hid/winkey/winkey_input_driver.h"
|
||||
|
||||
#include "xenia/base/cvar.h"
|
||||
#include "xenia/base/platform_win.h"
|
||||
#include "xenia/hid/hid_flags.h"
|
||||
#include "xenia/hid/input_system.h"
|
||||
#include "xenia/ui/window.h"
|
||||
|
||||
DEFINE_bool(keyboard_passthru, false,
|
||||
"Maybe useful for debug games, disables keyboard->gamepad "
|
||||
"emulation and forwards exact keyboard events to game (note that "
|
||||
"Xenia keybinds, eg. H to show FPS, will still be in effect!)",
|
||||
"HID");
|
||||
|
||||
namespace xe {
|
||||
namespace hid {
|
||||
namespace winkey {
|
||||
|
@ -103,7 +110,7 @@ X_RESULT WinKeyInputDriver::GetCapabilities(uint32_t user_index, uint32_t flags,
|
|||
|
||||
X_RESULT WinKeyInputDriver::GetState(uint32_t user_index,
|
||||
X_INPUT_STATE* out_state) {
|
||||
if (user_index != user_index_) {
|
||||
if (user_index != user_index_ || cvars::keyboard_passthru) {
|
||||
return X_ERROR_DEVICE_NOT_CONNECTED;
|
||||
}
|
||||
|
||||
|
@ -252,7 +259,7 @@ X_RESULT WinKeyInputDriver::SetState(uint32_t user_index,
|
|||
|
||||
X_RESULT WinKeyInputDriver::GetKeystroke(uint32_t user_index, uint32_t flags,
|
||||
X_INPUT_KEYSTROKE* out_keystroke) {
|
||||
if (user_index != user_index_) {
|
||||
if (!cvars::keyboard_passthru && user_index != user_index_) {
|
||||
return X_ERROR_DEVICE_NOT_CONNECTED;
|
||||
}
|
||||
|
||||
|
@ -275,118 +282,149 @@ X_RESULT WinKeyInputDriver::GetKeystroke(uint32_t user_index, uint32_t flags,
|
|||
key_events_.pop();
|
||||
}
|
||||
|
||||
// TODO(DrChat): Some other way to toggle this...
|
||||
if (IS_KEY_TOGGLED(VK_CAPITAL)) {
|
||||
// dpad toggled
|
||||
if (evt.vkey == (0x41)) {
|
||||
// A
|
||||
virtual_key = 0x5812; // VK_PAD_DPAD_LEFT
|
||||
} else if (evt.vkey == (0x44)) {
|
||||
// D
|
||||
virtual_key = 0x5813; // VK_PAD_DPAD_RIGHT
|
||||
} else if (evt.vkey == (0x53)) {
|
||||
// S
|
||||
virtual_key = 0x5811; // VK_PAD_DPAD_DOWN
|
||||
} else if (evt.vkey == (0x57)) {
|
||||
// W
|
||||
virtual_key = 0x5810; // VK_PAD_DPAD_UP
|
||||
if (cvars::keyboard_passthru) {
|
||||
virtual_key = evt.vkey;
|
||||
} else {
|
||||
// TODO(DrChat): Some other way to toggle this...
|
||||
if (IS_KEY_TOGGLED(VK_CAPITAL)) {
|
||||
// dpad toggled
|
||||
if (evt.vkey == (0x41)) {
|
||||
// A
|
||||
virtual_key = 0x5812; // VK_PAD_DPAD_LEFT
|
||||
} else if (evt.vkey == (0x44)) {
|
||||
// D
|
||||
virtual_key = 0x5813; // VK_PAD_DPAD_RIGHT
|
||||
} else if (evt.vkey == (0x53)) {
|
||||
// S
|
||||
virtual_key = 0x5811; // VK_PAD_DPAD_DOWN
|
||||
} else if (evt.vkey == (0x57)) {
|
||||
// W
|
||||
virtual_key = 0x5810; // VK_PAD_DPAD_UP
|
||||
}
|
||||
} else {
|
||||
// left stick
|
||||
if (evt.vkey == (0x57)) {
|
||||
// W
|
||||
virtual_key = 0x5820; // VK_PAD_LTHUMB_UP
|
||||
}
|
||||
if (evt.vkey == (0x53)) {
|
||||
// S
|
||||
virtual_key = 0x5821; // VK_PAD_LTHUMB_DOWN
|
||||
}
|
||||
if (evt.vkey == (0x44)) {
|
||||
// D
|
||||
virtual_key = 0x5822; // VK_PAD_LTHUMB_RIGHT
|
||||
}
|
||||
if (evt.vkey == (0x41)) {
|
||||
// A
|
||||
virtual_key = 0x5823; // VK_PAD_LTHUMB_LEFT
|
||||
}
|
||||
}
|
||||
|
||||
// Right stick
|
||||
if (evt.vkey == (0x26)) {
|
||||
// Up
|
||||
virtual_key = 0x5830;
|
||||
}
|
||||
if (evt.vkey == (0x28)) {
|
||||
// Down
|
||||
virtual_key = 0x5831;
|
||||
}
|
||||
if (evt.vkey == (0x27)) {
|
||||
// Right
|
||||
virtual_key = 0x5832;
|
||||
}
|
||||
if (evt.vkey == (0x25)) {
|
||||
// Left
|
||||
virtual_key = 0x5833;
|
||||
}
|
||||
|
||||
if (evt.vkey == (0x4C)) {
|
||||
// L
|
||||
virtual_key = 0x5802; // VK_PAD_X
|
||||
} else if (evt.vkey == (VK_OEM_7)) {
|
||||
// '
|
||||
virtual_key = 0x5801; // VK_PAD_B
|
||||
} else if (evt.vkey == (VK_OEM_1)) {
|
||||
// ;
|
||||
virtual_key = 0x5800; // VK_PAD_A
|
||||
} else if (evt.vkey == (0x50)) {
|
||||
// P
|
||||
virtual_key = 0x5803; // VK_PAD_Y
|
||||
}
|
||||
|
||||
if (evt.vkey == (0x58)) {
|
||||
// X
|
||||
virtual_key = 0x5814; // VK_PAD_START
|
||||
}
|
||||
if (evt.vkey == (0x5A)) {
|
||||
// Z
|
||||
virtual_key = 0x5815; // VK_PAD_BACK
|
||||
}
|
||||
if (evt.vkey == (0x51) || evt.vkey == (0x49)) {
|
||||
// Q / I
|
||||
virtual_key = 0x5806; // VK_PAD_LTRIGGER
|
||||
}
|
||||
if (evt.vkey == (0x45) || evt.vkey == (0x4F)) {
|
||||
// E / O
|
||||
virtual_key = 0x5807; // VK_PAD_RTRIGGER
|
||||
}
|
||||
if (evt.vkey == (0x31)) {
|
||||
// 1
|
||||
virtual_key = 0x5805; // VK_PAD_LSHOULDER
|
||||
}
|
||||
if (evt.vkey == (0x33)) {
|
||||
// 3
|
||||
virtual_key = 0x5804; // VK_PAD_RSHOULDER
|
||||
}
|
||||
}
|
||||
|
||||
if (!cvars::keyboard_passthru) {
|
||||
if (virtual_key != 0) {
|
||||
if (evt.transition == true) {
|
||||
keystroke_flags |= 0x0001; // XINPUT_KEYSTROKE_KEYDOWN
|
||||
} else if (evt.transition == false) {
|
||||
keystroke_flags |= 0x0002; // XINPUT_KEYSTROKE_KEYUP
|
||||
}
|
||||
|
||||
if (evt.prev_state == evt.transition) {
|
||||
keystroke_flags |= 0x0004; // XINPUT_KEYSTROKE_REPEAT
|
||||
}
|
||||
|
||||
result = X_ERROR_SUCCESS;
|
||||
}
|
||||
} else {
|
||||
// left stick
|
||||
if (evt.vkey == (0x57)) {
|
||||
// W
|
||||
virtual_key = 0x5820; // VK_PAD_LTHUMB_UP
|
||||
// Handle keydown/keyup for VK_SHIFT
|
||||
if (virtual_key == VK_SHIFT) {
|
||||
if (evt.transition == false) {
|
||||
keystroke_flags |= 0x0002;
|
||||
} else if (evt.transition == true) {
|
||||
keystroke_flags |= 0x0001;
|
||||
}
|
||||
}
|
||||
if (evt.vkey == (0x53)) {
|
||||
// S
|
||||
virtual_key = 0x5821; // VK_PAD_LTHUMB_DOWN
|
||||
|
||||
// Only handle keydown for other keys, since some stupid games will count
|
||||
// keyup as another keypress (seen in SR1..)
|
||||
if (virtual_key != 0 && virtual_key != 0x10) {
|
||||
if (evt.transition) {
|
||||
keystroke_flags |= 0x0001;
|
||||
}
|
||||
}
|
||||
if (evt.vkey == (0x44)) {
|
||||
// D
|
||||
virtual_key = 0x5822; // VK_PAD_LTHUMB_RIGHT
|
||||
}
|
||||
if (evt.vkey == (0x41)) {
|
||||
// A
|
||||
virtual_key = 0x5823; // VK_PAD_LTHUMB_LEFT
|
||||
|
||||
if (keystroke_flags != 0) {
|
||||
result = X_ERROR_SUCCESS;
|
||||
}
|
||||
}
|
||||
|
||||
// Right stick
|
||||
if (evt.vkey == (0x26)) {
|
||||
// Up
|
||||
virtual_key = 0x5830;
|
||||
if (!result) {
|
||||
out_keystroke->virtual_key = virtual_key;
|
||||
out_keystroke->unicode = unicode;
|
||||
out_keystroke->flags = keystroke_flags;
|
||||
out_keystroke->user_index = user_index_;
|
||||
out_keystroke->hid_code = hid_code;
|
||||
} else {
|
||||
memset(out_keystroke, 0, sizeof(X_INPUT_KEYSTROKE));
|
||||
}
|
||||
if (evt.vkey == (0x28)) {
|
||||
// Down
|
||||
virtual_key = 0x5831;
|
||||
}
|
||||
if (evt.vkey == (0x27)) {
|
||||
// Right
|
||||
virtual_key = 0x5832;
|
||||
}
|
||||
if (evt.vkey == (0x25)) {
|
||||
// Left
|
||||
virtual_key = 0x5833;
|
||||
}
|
||||
|
||||
if (evt.vkey == (0x4C)) {
|
||||
// L
|
||||
virtual_key = 0x5802; // VK_PAD_X
|
||||
} else if (evt.vkey == (VK_OEM_7)) {
|
||||
// '
|
||||
virtual_key = 0x5801; // VK_PAD_B
|
||||
} else if (evt.vkey == (VK_OEM_1)) {
|
||||
// ;
|
||||
virtual_key = 0x5800; // VK_PAD_A
|
||||
} else if (evt.vkey == (0x50)) {
|
||||
// P
|
||||
virtual_key = 0x5803; // VK_PAD_Y
|
||||
}
|
||||
|
||||
if (evt.vkey == (0x58)) {
|
||||
// X
|
||||
virtual_key = 0x5814; // VK_PAD_START
|
||||
}
|
||||
if (evt.vkey == (0x5A)) {
|
||||
// Z
|
||||
virtual_key = 0x5815; // VK_PAD_BACK
|
||||
}
|
||||
if (evt.vkey == (0x51) || evt.vkey == (0x49)) {
|
||||
// Q / I
|
||||
virtual_key = 0x5806; // VK_PAD_LTRIGGER
|
||||
}
|
||||
if (evt.vkey == (0x45) || evt.vkey == (0x4F)) {
|
||||
// E / O
|
||||
virtual_key = 0x5807; // VK_PAD_RTRIGGER
|
||||
}
|
||||
if (evt.vkey == (0x31)) {
|
||||
// 1
|
||||
virtual_key = 0x5805; // VK_PAD_LSHOULDER
|
||||
}
|
||||
if (evt.vkey == (0x33)) {
|
||||
// 3
|
||||
virtual_key = 0x5804; // VK_PAD_RSHOULDER
|
||||
}
|
||||
|
||||
if (virtual_key != 0) {
|
||||
if (evt.transition == true) {
|
||||
keystroke_flags |= 0x0001; // XINPUT_KEYSTROKE_KEYDOWN
|
||||
} else if (evt.transition == false) {
|
||||
keystroke_flags |= 0x0002; // XINPUT_KEYSTROKE_KEYUP
|
||||
}
|
||||
|
||||
if (evt.prev_state == evt.transition) {
|
||||
keystroke_flags |= 0x0004; // XINPUT_KEYSTROKE_REPEAT
|
||||
}
|
||||
|
||||
result = X_ERROR_SUCCESS;
|
||||
}
|
||||
|
||||
out_keystroke->virtual_key = virtual_key;
|
||||
out_keystroke->unicode = unicode;
|
||||
out_keystroke->flags = keystroke_flags;
|
||||
out_keystroke->user_index = user_index_;
|
||||
out_keystroke->hid_code = hid_code;
|
||||
|
||||
// X_ERROR_EMPTY if no new keys
|
||||
// X_ERROR_DEVICE_NOT_CONNECTED if no device
|
||||
|
|
|
@ -26,6 +26,7 @@ using xe::hid::X_INPUT_STATE;
|
|||
using xe::hid::X_INPUT_VIBRATION;
|
||||
|
||||
constexpr uint32_t XINPUT_FLAG_GAMEPAD = 0x01;
|
||||
constexpr uint32_t XINPUT_FLAG_KEYBOARD = 0x02;
|
||||
constexpr uint32_t XINPUT_FLAG_ANY_USER = 1 << 30;
|
||||
|
||||
void XamResetInactivity() {
|
||||
|
@ -157,7 +158,8 @@ dword_result_t XamInputGetKeystrokeEx(lpdword_t user_index_ptr, 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;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue