From c4fe2e692643b101ac7481bc9be68324ef7f51dd Mon Sep 17 00:00:00 2001 From: Ben Vanik Date: Wed, 23 Oct 2013 22:13:05 -0700 Subject: [PATCH] Input bouncing through to input system. --- src/xenia/hid/input_system.cc | 15 ++++ src/xenia/hid/input_system.h | 5 ++ src/xenia/kernel/xam/xam_input.cc | 34 +++++++- src/xenia/kernel/xam/xam_state.h | 1 + src/xenia/xbox.h | 135 +++++++++++++++++++++++++++++- 5 files changed, 183 insertions(+), 7 deletions(-) diff --git a/src/xenia/hid/input_system.cc b/src/xenia/hid/input_system.cc index 50c9afed8..72de3454f 100644 --- a/src/xenia/hid/input_system.cc +++ b/src/xenia/hid/input_system.cc @@ -41,3 +41,18 @@ X_STATUS InputSystem::Setup() { void InputSystem::AddDriver(InputDriver* driver) { drivers_.push_back(driver); } + +XRESULT InputSystem::GetCapabilities( + uint32_t user_index, uint32_t flags, X_INPUT_CAPABILITIES& out_caps) { + return X_ERROR_DEVICE_NOT_CONNECTED; +} + +XRESULT InputSystem::GetState(uint32_t user_index, X_INPUT_STATE& out_state) { + return X_ERROR_DEVICE_NOT_CONNECTED; +} + +XRESULT InputSystem::SetState( + uint32_t user_index, X_INPUT_VIBRATION& vibration) { + // or X_ERROR_BUSY + return X_ERROR_DEVICE_NOT_CONNECTED; +} diff --git a/src/xenia/hid/input_system.h b/src/xenia/hid/input_system.h index 179f51949..12a3ec586 100644 --- a/src/xenia/hid/input_system.h +++ b/src/xenia/hid/input_system.h @@ -37,6 +37,11 @@ public: void AddDriver(InputDriver* driver); + XRESULT GetCapabilities( + uint32_t user_index, uint32_t flags, X_INPUT_CAPABILITIES& out_caps); + XRESULT GetState(uint32_t user_index, X_INPUT_STATE& out_state); + XRESULT SetState(uint32_t user_index, X_INPUT_VIBRATION& vibration); + private: Emulator* emulator_; xe_memory_ref memory_; diff --git a/src/xenia/kernel/xam/xam_input.cc b/src/xenia/kernel/xam/xam_input.cc index 046440a6e..35a0d64ca 100644 --- a/src/xenia/kernel/xam/xam_input.cc +++ b/src/xenia/kernel/xam/xam_input.cc @@ -9,12 +9,15 @@ #include +#include +#include #include #include #include using namespace xe; +using namespace xe::hid; using namespace xe::kernel; using namespace xe::kernel::xam; @@ -37,7 +40,16 @@ SHIM_CALL XamInputGetCapabilities_shim( flags, caps_ptr); - SHIM_SET_RETURN(X_ERROR_DEVICE_NOT_CONNECTED); + InputSystem* input_system = state->emulator()->input_system(); + + X_INPUT_CAPABILITIES caps; + XRESULT result = input_system->GetCapabilities(user_index, flags, caps); + if (XSUCCEEDED(result)) { + if (caps_ptr) { + caps.Write(SHIM_MEM_BASE, caps_ptr); + } + } + SHIM_SET_RETURN(result); } @@ -52,7 +64,16 @@ SHIM_CALL XamInputGetState_shim( user_index, state_ptr); - SHIM_SET_RETURN(X_ERROR_DEVICE_NOT_CONNECTED); + InputSystem* input_system = state->emulator()->input_system(); + + X_INPUT_STATE input_state; + XRESULT result = input_system->GetState(user_index, input_state); + if (XSUCCEEDED(result)) { + if (state_ptr) { + input_state.Write(SHIM_MEM_BASE, state_ptr); + } + } + SHIM_SET_RETURN(result); } @@ -67,9 +88,14 @@ SHIM_CALL XamInputSetState_shim( user_index, vibration_ptr); - // or X_ERROR_BUSY + InputSystem* input_system = state->emulator()->input_system(); - SHIM_SET_RETURN(X_ERROR_DEVICE_NOT_CONNECTED); + X_INPUT_VIBRATION vibration; + if (vibration_ptr) { + vibration.Read(SHIM_MEM_BASE, vibration_ptr); + } + XRESULT result = input_system->SetState(user_index, vibration); + SHIM_SET_RETURN(result); } diff --git a/src/xenia/kernel/xam/xam_state.h b/src/xenia/kernel/xam/xam_state.h index e5dc4cb7e..d422a2b3d 100644 --- a/src/xenia/kernel/xam/xam_state.h +++ b/src/xenia/kernel/xam/xam_state.h @@ -27,6 +27,7 @@ public: XamState(Emulator* emulator); ~XamState(); + Emulator* emulator() const { return emulator_; } xe_memory_ref memory() const { return memory_; } private: diff --git a/src/xenia/xbox.h b/src/xenia/xbox.h index 51a53efee..b75e694cb 100644 --- a/src/xenia/xbox.h +++ b/src/xenia/xbox.h @@ -25,8 +25,8 @@ typedef uint32_t X_HANDLE; // http://msdn.microsoft.com/en-us/library/cc704588.aspx // Adding as needed. typedef uint32_t X_STATUS; -#define XFAILED(s) (s & X_STATUS_UNSUCCESSFUL) -#define XSUCCEEDED(s) !XFAILED(s) +#define XFAILED(s) ((s) < 0) +#define XSUCCEEDED(s) ((s) >= 0) #define X_STATUS_SUCCESS ((uint32_t)0x00000000L) #define X_STATUS_ABANDONED_WAIT_0 ((uint32_t)0x00000080L) #define X_STATUS_USER_APC ((uint32_t)0x000000C0L) @@ -52,7 +52,7 @@ typedef uint32_t X_STATUS; // HRESULT (ERROR_*) // Adding as needed. -typedef uint32_t X_RESULT; +typedef uint32_t XRESULT; #define X_ERROR_SUCCESS ((uint32_t)0x00000000L) #define X_ERROR_ACCESS_DENIED ((uint32_t)0x80070005L) #define X_ERROR_BUSY ((uint32_t)0x800700AAL) @@ -251,6 +251,135 @@ public: }; +typedef enum _X_INPUT_FLAG { + X_INPUT_FLAG_GAMEPAD = 0x00000001, +} X_INPUT_FLAG; + +class X_INPUT_GAMEPAD { +public: + uint16_t buttons; + uint8_t left_trigger; + uint8_t right_trigger; + int16_t thumb_lx; + int16_t thumb_ly; + int16_t thumb_rx; + int16_t thumb_ry; + + X_INPUT_GAMEPAD() { + Zero(); + } + X_INPUT_GAMEPAD(const uint8_t* base, uint32_t p) { + Read(base, p); + } + void Read(const uint8_t* base, uint32_t p) { + buttons = XEGETUINT16BE(base + p); + left_trigger = XEGETUINT8BE(base + p + 2); + right_trigger = XEGETUINT8BE(base + p + 3); + thumb_lx = XEGETINT16BE(base + p + 4); + thumb_ly = XEGETINT16BE(base + p + 6); + thumb_rx = XEGETINT16BE(base + p + 8); + thumb_ry = XEGETINT16BE(base + p + 10); + } + void Write(uint8_t* base, uint32_t p) { + XESETUINT16BE(base + p, buttons); + XESETUINT8BE(base + p + 2, left_trigger); + XESETUINT8BE(base + p + 3, right_trigger); + XESETINT16BE(base + p + 4, thumb_lx); + XESETINT16BE(base + p + 6, thumb_ly); + XESETINT16BE(base + p + 8, thumb_rx); + XESETINT16BE(base + p + 10, thumb_ry); + } + void Zero() { + buttons = 0; + left_trigger = right_trigger = 0; + thumb_lx = thumb_ly = thumb_rx = thumb_ry = 0; + } +}; +class X_INPUT_STATE { +public: + uint32_t packet_number; + X_INPUT_GAMEPAD gamepad; + + X_INPUT_STATE() { + Zero(); + } + X_INPUT_STATE(const uint8_t* base, uint32_t p) { + Read(base, p); + } + void Read(const uint8_t* base, uint32_t p) { + packet_number = XEGETUINT32BE(base + p); + gamepad.Read(base, p + 4); + } + void Write(uint8_t* base, uint32_t p) { + XESETUINT32BE(base + p, packet_number); + gamepad.Write(base, p + 4); + } + void Zero() { + packet_number = 0; + gamepad.Zero(); + } +}; +class X_INPUT_VIBRATION { +public: + uint16_t left_motor_speed; + uint16_t right_motor_speed; + + X_INPUT_VIBRATION() { + Zero(); + } + X_INPUT_VIBRATION(const uint8_t* base, uint32_t p) { + Read(base, p); + } + void Read(const uint8_t* base, uint32_t p) { + left_motor_speed = XEGETUINT16BE(base + p); + right_motor_speed = XEGETUINT16BE(base + p + 2); + } + void Write(uint8_t* base, uint32_t p) { + XESETUINT16BE(base + p, left_motor_speed); + XESETUINT16BE(base + p + 2, right_motor_speed); + } + void Zero() { + left_motor_speed = right_motor_speed = 0; + } +}; +class X_INPUT_CAPABILITIES { +public: + uint8_t type; + uint8_t sub_type; + uint16_t flags; + X_INPUT_GAMEPAD gamepad; + X_INPUT_VIBRATION vibration; + + X_INPUT_CAPABILITIES() { + Zero(); + } + X_INPUT_CAPABILITIES(const uint8_t* base, uint32_t p) { + Read(base, p); + } + void Read(const uint8_t* base, uint32_t p) { + type = XEGETUINT8BE(base + p); + sub_type = XEGETUINT8BE(base + p + 1); + flags = XEGETUINT16BE(base + p + 2); + gamepad.Read(base, p + 4); + vibration.Read(base, p + 4 + 12); + } + void Write(uint8_t* base, uint32_t p) { + XESETUINT8BE(base + p, type); + XESETUINT8BE(base + p + 1, sub_type); + XESETUINT16BE(base + p + 2, flags); + gamepad.Write(base, p + 4); + vibration.Write(base, p + 4 + 12); + } + void Zero() { + type = 0; + sub_type = 0; + flags = 0; + gamepad.Zero(); + vibration.Zero(); + } +}; + + } // namespace xe