[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
51ba83d315
commit
bf6d4dcda0
|
@ -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,6 +282,9 @@ X_RESULT WinKeyInputDriver::GetKeystroke(uint32_t user_index, uint32_t flags,
|
|||
key_events_.pop();
|
||||
}
|
||||
|
||||
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
|
||||
|
@ -367,7 +377,9 @@ X_RESULT WinKeyInputDriver::GetKeystroke(uint32_t user_index, uint32_t flags,
|
|||
// 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
|
||||
|
@ -381,12 +393,38 @@ X_RESULT WinKeyInputDriver::GetKeystroke(uint32_t user_index, uint32_t flags,
|
|||
|
||||
result = X_ERROR_SUCCESS;
|
||||
}
|
||||
} else {
|
||||
// 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;
|
||||
}
|
||||
}
|
||||
|
||||
// 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 (keystroke_flags != 0) {
|
||||
result = X_ERROR_SUCCESS;
|
||||
}
|
||||
}
|
||||
|
||||
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));
|
||||
}
|
||||
|
||||
// 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