From 9bea299a16442e23fe2af5b00254633a37347038 Mon Sep 17 00:00:00 2001 From: Ben Vanik Date: Wed, 29 Jul 2015 21:41:09 -0700 Subject: [PATCH] Massaging xinput arguments. Fixes RCR. --- src/xenia/kernel/xam_input.cc | 57 +++++++++++++++++++++++++++++++++-- 1 file changed, 55 insertions(+), 2 deletions(-) diff --git a/src/xenia/kernel/xam_input.cc b/src/xenia/kernel/xam_input.cc index 421b6e7ec..8f1a23c38 100644 --- a/src/xenia/kernel/xam_input.cc +++ b/src/xenia/kernel/xam_input.cc @@ -21,6 +21,9 @@ namespace kernel { using namespace xe::hid; +constexpr uint32_t XINPUT_FLAG_GAMEPAD = 0x01; +constexpr uint32_t XINPUT_FLAG_ANY_USER = 1 << 30; + SHIM_CALL XamResetInactivity_shim(PPCContext* ppc_context, KernelState* kernel_state) { uint32_t unk = SHIM_GET_ARG_32(0); @@ -56,6 +59,15 @@ SHIM_CALL XamInputGetCapabilities_shim(PPCContext* ppc_context, SHIM_SET_RETURN_32(X_ERROR_BAD_ARGUMENTS); return; } + if ((flags & 0xFF) && (flags & XINPUT_FLAG_GAMEPAD) == 0) { + // Ignore any query for other types of devices. + SHIM_SET_RETURN_32(X_ERROR_DEVICE_NOT_CONNECTED); + return; + } + if ((user_index & 0xFF) == 0xFF || (flags & XINPUT_FLAG_ANY_USER)) { + // Always pin user to 0. + user_index = 0; + } InputSystem* input_system = kernel_state->emulator()->input_system(); @@ -78,6 +90,15 @@ SHIM_CALL XamInputGetCapabilitiesEx_shim(PPCContext* ppc_context, SHIM_SET_RETURN_32(X_ERROR_BAD_ARGUMENTS); return; } + if ((flags & 0xFF) && (flags & XINPUT_FLAG_GAMEPAD) == 0) { + // Ignore any query for other types of devices. + SHIM_SET_RETURN_32(X_ERROR_DEVICE_NOT_CONNECTED); + return; + } + if ((user_index & 0xFF) == 0xFF || (flags & XINPUT_FLAG_ANY_USER)) { + // Always pin user to 0. + user_index = 0; + } InputSystem* input_system = kernel_state->emulator()->input_system(); @@ -90,13 +111,23 @@ SHIM_CALL XamInputGetCapabilitiesEx_shim(PPCContext* ppc_context, SHIM_CALL XamInputGetState_shim(PPCContext* ppc_context, KernelState* kernel_state) { uint32_t user_index = SHIM_GET_ARG_32(0); - uint32_t one = SHIM_GET_ARG_32(1); + uint32_t flags = SHIM_GET_ARG_32(1); uint32_t state_ptr = SHIM_GET_ARG_32(2); - XELOGD("XamInputGetState(%d, %.8X, %.8X)", user_index, one, state_ptr); + XELOGD("XamInputGetState(%d, %.8X, %.8X)", user_index, flags, state_ptr); // Games call this with a NULL state ptr, probably as a query. + if ((flags & 0xFF) && (flags & XINPUT_FLAG_GAMEPAD) == 0) { + // Ignore any query for other types of devices. + SHIM_SET_RETURN_32(X_ERROR_DEVICE_NOT_CONNECTED); + return; + } + if ((user_index & 0xFF) == 0xFF || (flags & XINPUT_FLAG_ANY_USER)) { + // Always pin user to 0. + user_index = 0; + } + InputSystem* input_system = kernel_state->emulator()->input_system(); auto input_state = SHIM_STRUCT(X_INPUT_STATE, state_ptr); @@ -117,6 +148,10 @@ SHIM_CALL XamInputSetState_shim(PPCContext* ppc_context, SHIM_SET_RETURN_32(X_ERROR_BAD_ARGUMENTS); return; } + if ((user_index & 0xFF) == 0xFF) { + // Always pin user to 0. + user_index = 0; + } InputSystem* input_system = kernel_state->emulator()->input_system(); @@ -143,6 +178,15 @@ SHIM_CALL XamInputGetKeystroke_shim(PPCContext* ppc_context, SHIM_SET_RETURN_32(X_ERROR_BAD_ARGUMENTS); return; } + if ((flags & 0xFF) && (flags & XINPUT_FLAG_GAMEPAD) == 0) { + // Ignore any query for other types of devices. + SHIM_SET_RETURN_32(X_ERROR_DEVICE_NOT_CONNECTED); + return; + } + if ((user_index & 0xFF) == 0xFF || (flags & XINPUT_FLAG_ANY_USER)) { + // Always pin user to 0. + user_index = 0; + } InputSystem* input_system = kernel_state->emulator()->input_system(); @@ -167,6 +211,15 @@ SHIM_CALL XamInputGetKeystrokeEx_shim(PPCContext* ppc_context, SHIM_SET_RETURN_32(X_ERROR_BAD_ARGUMENTS); return; } + if ((flags & 0xFF) && (flags & XINPUT_FLAG_GAMEPAD) == 0) { + // Ignore any query for other types of devices. + SHIM_SET_RETURN_32(X_ERROR_DEVICE_NOT_CONNECTED); + return; + } + if ((user_index & 0xFF) == 0xFF || (flags & XINPUT_FLAG_ANY_USER)) { + // Always pin user to 0. + user_index = 0; + } InputSystem* input_system = kernel_state->emulator()->input_system();