From c8da7fbfe4672ce6531b9914653aebf42fb8ee69 Mon Sep 17 00:00:00 2001 From: Joel Linn Date: Mon, 20 Apr 2020 15:03:37 +0200 Subject: [PATCH] [HID] Optional guide button support. Maybe this is interesting to some games. --- src/xenia/hid/hid_demo.cc | 32 ++++++++++++--------- src/xenia/hid/hid_flags.cc | 3 ++ src/xenia/hid/hid_flags.h | 4 +++ src/xenia/hid/input.h | 1 + src/xenia/hid/sdl/sdl_input_driver.cc | 9 ++++-- src/xenia/hid/xinput/xinput_input_driver.cc | 7 +++++ 6 files changed, 41 insertions(+), 15 deletions(-) diff --git a/src/xenia/hid/hid_demo.cc b/src/xenia/hid/hid_demo.cc index c2cb46ef2..1829d2b47 100644 --- a/src/xenia/hid/hid_demo.cc +++ b/src/xenia/hid/hid_demo.cc @@ -20,6 +20,7 @@ #include "xenia/base/logging.h" #include "xenia/base/main.h" #include "xenia/base/threading.h" +#include "xenia/hid/hid_flags.h" #include "xenia/hid/input_system.h" #include "xenia/ui/imgui_drawer.h" #include "xenia/ui/vulkan/vulkan_provider.h" @@ -155,6 +156,8 @@ int hid_demo_main(const std::vector& args) { static bool enable_GetState = false; ImGui::Checkbox("Active", &enable_GetState); + ImGui::SameLine(); + ImGui::Checkbox("Guide Button", &cvars::guide_button); if (enable_GetState) { ImGui::Spacing(); DrawInputGetState(); @@ -203,35 +206,38 @@ void DrawUserInputGetState(uint32_t user_index) { return; } - ImGui::Text(" Packet Number: %u", static_cast(state.packet_number)); + ImGui::Text(" Packet Number: %u", + static_cast(state.packet_number)); auto& gamepad = state.gamepad; - ImGui::Text(" Buttons: [%c][%c][%c][%c] [%s][%s]", + ImGui::Text(" Right Buttons: [%c][%c][%c][%c]", gamepad.buttons & X_INPUT_GAMEPAD_A ? 'A' : ' ', gamepad.buttons & X_INPUT_GAMEPAD_B ? 'B' : ' ', gamepad.buttons & X_INPUT_GAMEPAD_X ? 'X' : ' ', - gamepad.buttons & X_INPUT_GAMEPAD_Y ? 'Y' : ' ', - gamepad.buttons & X_INPUT_GAMEPAD_START ? "start" : " ", - gamepad.buttons & X_INPUT_GAMEPAD_BACK ? "back" : " "); - ImGui::Text(" D-pad: [%c][%c][%c][%c]", + gamepad.buttons & X_INPUT_GAMEPAD_Y ? 'Y' : ' '); + ImGui::Text("Special Buttons: [%s][%s][%s]", + gamepad.buttons & X_INPUT_GAMEPAD_BACK ? "back" : " ", + gamepad.buttons & X_INPUT_GAMEPAD_GUIDE ? "guide" : " ", + gamepad.buttons & X_INPUT_GAMEPAD_START ? "start" : " "); + ImGui::Text(" D-pad: [%c][%c][%c][%c]", gamepad.buttons & X_INPUT_GAMEPAD_DPAD_UP ? 'U' : ' ', gamepad.buttons & X_INPUT_GAMEPAD_DPAD_DOWN ? 'D' : ' ', gamepad.buttons & X_INPUT_GAMEPAD_DPAD_LEFT ? 'L' : ' ', gamepad.buttons & X_INPUT_GAMEPAD_DPAD_RIGHT ? 'R' : ' '); - ImGui::Text(" Thumbs: [%c][%c]", + ImGui::Text(" Thumbs: [%c][%c]", gamepad.buttons & X_INPUT_GAMEPAD_LEFT_THUMB ? 'L' : ' ', gamepad.buttons & X_INPUT_GAMEPAD_RIGHT_THUMB ? 'R' : ' '); - ImGui::Text(" Shoulders: [%c][%c]", + ImGui::Text(" Shoulders: [%c][%c]", gamepad.buttons & X_INPUT_GAMEPAD_LEFT_SHOULDER ? 'L' : ' ', gamepad.buttons & X_INPUT_GAMEPAD_RIGHT_SHOULDER ? 'R' : ' '); - ImGui::Text(" Left Trigger: %3u", + ImGui::Text(" Left Trigger: %3u", static_cast(gamepad.left_trigger)); - ImGui::Text(" Right Trigger: %3u", + ImGui::Text(" Right Trigger: %3u", static_cast(gamepad.right_trigger)); - ImGui::Text(" Left Thumb: %6d, %6d", + ImGui::Text(" Left Thumb: %6d, %6d", static_cast(gamepad.thumb_lx), static_cast(gamepad.thumb_ly)); - ImGui::Text(" Right Thumb: %6d, %6d", + ImGui::Text(" Right Thumb: %6d, %6d", static_cast(gamepad.thumb_rx), static_cast(gamepad.thumb_ry)); @@ -243,7 +249,7 @@ void DrawUserInputGetState(uint32_t user_index) { UINT16_MAX); input_system_->SetState(user_index, &vibration); - ImGui::Text(" Motor Speeds: L %5u, R %5u", + ImGui::Text(" Motor Speeds: L %5u, R %5u", static_cast(vibration.left_motor_speed), static_cast(vibration.right_motor_speed)); diff --git a/src/xenia/hid/hid_flags.cc b/src/xenia/hid/hid_flags.cc index 784b32f42..19a2b867f 100644 --- a/src/xenia/hid/hid_flags.cc +++ b/src/xenia/hid/hid_flags.cc @@ -8,3 +8,6 @@ */ #include "xenia/hid/hid_flags.h" + +DEFINE_bool(guide_button, false, "Forward guide button presses to guest.", + "HID"); diff --git a/src/xenia/hid/hid_flags.h b/src/xenia/hid/hid_flags.h index f7321aec3..37b45a0f2 100644 --- a/src/xenia/hid/hid_flags.h +++ b/src/xenia/hid/hid_flags.h @@ -10,4 +10,8 @@ #ifndef XENIA_HID_HID_FLAGS_H_ #define XENIA_HID_HID_FLAGS_H_ +#include "xenia/base/cvar.h" + +DECLARE_bool(guide_button); + #endif // XENIA_HID_HID_FLAGS_H_ diff --git a/src/xenia/hid/input.h b/src/xenia/hid/input.h index 8aec0a443..71ed28b22 100644 --- a/src/xenia/hid/input.h +++ b/src/xenia/hid/input.h @@ -31,6 +31,7 @@ enum X_INPUT_GAMEPAD_BUTTON { X_INPUT_GAMEPAD_RIGHT_THUMB = 0x0080, X_INPUT_GAMEPAD_LEFT_SHOULDER = 0x0100, X_INPUT_GAMEPAD_RIGHT_SHOULDER = 0x0200, + X_INPUT_GAMEPAD_GUIDE = 0x0400, X_INPUT_GAMEPAD_A = 0x1000, X_INPUT_GAMEPAD_B = 0x2000, X_INPUT_GAMEPAD_X = 0x4000, diff --git a/src/xenia/hid/sdl/sdl_input_driver.cc b/src/xenia/hid/sdl/sdl_input_driver.cc index 712a0e8e6..762caf7bb 100644 --- a/src/xenia/hid/sdl/sdl_input_driver.cc +++ b/src/xenia/hid/sdl/sdl_input_driver.cc @@ -15,6 +15,7 @@ #include "xenia/base/cvar.h" #include "xenia/base/logging.h" +#include "xenia/hid/hid_flags.h" #include "xenia/ui/window.h" // TODO(joellinn) make this path relative to the config folder. @@ -162,7 +163,8 @@ X_RESULT SDLInputDriver::GetCapabilities(uint32_t user_index, uint32_t flags, out_caps->type = 0x01; // XINPUT_DEVTYPE_GAMEPAD out_caps->sub_type = 0x01; // XINPUT_DEVSUBTYPE_GAMEPAD out_caps->flags = 0; - out_caps->gamepad.buttons = 0xF3FF; + out_caps->gamepad.buttons = + 0xF3FF | (cvars::guide_button ? X_INPUT_GAMEPAD_GUIDE : 0x0); out_caps->gamepad.left_trigger = 0xFF; out_caps->gamepad.right_trigger = 0xFF; out_caps->gamepad.thumb_lx = static_cast(0xFFFFu); @@ -323,7 +325,7 @@ void SDLInputDriver::OnControllerDeviceButtonChanged(SDL_Event* event) { X_INPUT_GAMEPAD_X, X_INPUT_GAMEPAD_Y, X_INPUT_GAMEPAD_BACK, - 0 /* Guide button */, + X_INPUT_GAMEPAD_GUIDE, X_INPUT_GAMEPAD_START, X_INPUT_GAMEPAD_LEFT_THUMB, X_INPUT_GAMEPAD_RIGHT_THUMB, @@ -343,6 +345,9 @@ void SDLInputDriver::OnControllerDeviceButtonChanged(SDL_Event* event) { auto xbutton = xbutton_lookup.at(event->cbutton.button); // Pressed or released? if (event->cbutton.state == SDL_PRESSED) { + if (xbutton == X_INPUT_GAMEPAD_GUIDE && !cvars::guide_button) { + return; + } xbuttons |= xbutton; } else { xbuttons &= ~xbutton; diff --git a/src/xenia/hid/xinput/xinput_input_driver.cc b/src/xenia/hid/xinput/xinput_input_driver.cc index 9e6d2f90c..02c35ad14 100644 --- a/src/xenia/hid/xinput/xinput_input_driver.cc +++ b/src/xenia/hid/xinput/xinput_input_driver.cc @@ -14,6 +14,7 @@ #include // NOLINT(build/include_order) +#include "xenia/base/logging.h" #include "xenia/hid/hid_flags.h" namespace xe { @@ -71,6 +72,12 @@ X_STATUS XInputInputDriver::Setup() { XInputGetKeystroke_ = xigk; XInputSetState_ = xiss; XInputEnable_ = xie; + + if (cvars::guide_button) { + // Theoretically there is XInputGetStateEx + // but thats undocumented and milage varies. + XELOGW("XInput: Guide button support is not implemented."); + } return X_STATUS_SUCCESS; }