Converting HID API to use be<> auto swapping type.

This commit is contained in:
Ben Vanik 2014-08-19 22:50:21 -07:00
parent 48a0e5c601
commit fb98683ed3
24 changed files with 325 additions and 518 deletions

View File

@ -35,6 +35,8 @@ namespace poly {
#define POLY_BYTE_SWAP_64 __bswap_64 #define POLY_BYTE_SWAP_64 __bswap_64
#endif // XE_COMPILER_MSVC #endif // XE_COMPILER_MSVC
inline int8_t byte_swap(int8_t value) { return value; }
inline uint8_t byte_swap(uint8_t value) { return value; }
inline int16_t byte_swap(int16_t value) { inline int16_t byte_swap(int16_t value) {
return static_cast<int16_t>(POLY_BYTE_SWAP_16(static_cast<int16_t>(value))); return static_cast<int16_t>(POLY_BYTE_SWAP_16(static_cast<int16_t>(value)));
} }

View File

@ -245,6 +245,19 @@ inline void store_and_swap<double>(void* mem, double value) {
*reinterpret_cast<double*>(mem) = byte_swap(value); *reinterpret_cast<double*>(mem) = byte_swap(value);
} }
template <typename T>
struct be {
be() = default;
be(const T& src) : value(poly::byte_swap(src)) {}
be(const be& other) {
value = other.value;
}
operator T() const {
return poly::byte_swap(value);
}
T value;
};
} // namespace poly } // namespace poly
#endif // POLY_MEMORY_H_ #endif // POLY_MEMORY_H_

View File

@ -9,14 +9,13 @@
#include <xenia/hid/input_driver.h> #include <xenia/hid/input_driver.h>
namespace xe {
namespace hid {
using namespace xe; InputDriver::InputDriver(InputSystem* input_system)
using namespace xe::hid; : input_system_(input_system) {}
InputDriver::~InputDriver() = default;
InputDriver::InputDriver(InputSystem* input_system) : } // namespace hid
input_system_(input_system) { } // namespace xe
}
InputDriver::~InputDriver() {
}

View File

@ -13,38 +13,32 @@
#include <xenia/core.h> #include <xenia/core.h>
#include <xenia/xbox.h> #include <xenia/xbox.h>
namespace xe { namespace xe {
namespace hid { namespace hid {
class InputSystem; class InputSystem;
class InputDriver { class InputDriver {
public: public:
virtual ~InputDriver(); virtual ~InputDriver();
virtual X_STATUS Setup() = 0; virtual X_STATUS Setup() = 0;
virtual X_RESULT GetCapabilities( virtual X_RESULT GetCapabilities(uint32_t user_index, uint32_t flags,
uint32_t user_index, uint32_t flags, X_INPUT_CAPABILITIES& out_caps) = 0; X_INPUT_CAPABILITIES* out_caps) = 0;
virtual X_RESULT GetState( virtual X_RESULT GetState(uint32_t user_index, X_INPUT_STATE* out_state) = 0;
uint32_t user_index, X_INPUT_STATE& out_state) = 0; virtual X_RESULT SetState(uint32_t user_index,
virtual X_RESULT SetState( X_INPUT_VIBRATION* vibration) = 0;
uint32_t user_index, X_INPUT_VIBRATION& vibration) = 0; virtual X_RESULT GetKeystroke(uint32_t user_index, uint32_t flags,
virtual X_RESULT GetKeystroke( X_INPUT_KEYSTROKE* out_keystroke) = 0;
uint32_t user_index, uint32_t flags,
X_INPUT_KEYSTROKE& out_keystroke) = 0;
protected: protected:
InputDriver(InputSystem* input_system); InputDriver(InputSystem* input_system);
InputSystem* input_system_; InputSystem* input_system_;
}; };
} // namespace hid } // namespace hid
} // namespace xe } // namespace xe
#endif // XENIA_HID_INPUT_DRIVER_H_ #endif // XENIA_HID_INPUT_DRIVER_H_

View File

@ -13,18 +13,14 @@
#include <xenia/cpu/processor.h> #include <xenia/cpu/processor.h>
#include <xenia/hid/input_driver.h> #include <xenia/hid/input_driver.h>
namespace xe {
namespace hid {
using namespace xe; InputSystem::InputSystem(Emulator* emulator)
using namespace xe::hid; : emulator_(emulator), memory_(emulator->memory()) {}
InputSystem::InputSystem(Emulator* emulator) :
emulator_(emulator), memory_(emulator->memory()) {
}
InputSystem::~InputSystem() { InputSystem::~InputSystem() {
for (auto it = drivers_.begin(); for (auto it = drivers_.begin(); it != drivers_.end(); ++it) {
it != drivers_.end(); ++it) {
InputDriver* driver = *it; InputDriver* driver = *it;
delete driver; delete driver;
} }
@ -36,12 +32,10 @@ X_STATUS InputSystem::Setup() {
return X_STATUS_SUCCESS; return X_STATUS_SUCCESS;
} }
void InputSystem::AddDriver(InputDriver* driver) { void InputSystem::AddDriver(InputDriver* driver) { drivers_.push_back(driver); }
drivers_.push_back(driver);
}
X_RESULT InputSystem::GetCapabilities( X_RESULT InputSystem::GetCapabilities(uint32_t user_index, uint32_t flags,
uint32_t user_index, uint32_t flags, X_INPUT_CAPABILITIES& out_caps) { X_INPUT_CAPABILITIES* out_caps) {
SCOPE_profile_cpu_f("hid"); SCOPE_profile_cpu_f("hid");
for (auto it = drivers_.begin(); it != drivers_.end(); ++it) { for (auto it = drivers_.begin(); it != drivers_.end(); ++it) {
@ -53,7 +47,7 @@ X_RESULT InputSystem::GetCapabilities(
return X_ERROR_DEVICE_NOT_CONNECTED; return X_ERROR_DEVICE_NOT_CONNECTED;
} }
X_RESULT InputSystem::GetState(uint32_t user_index, X_INPUT_STATE& out_state) { X_RESULT InputSystem::GetState(uint32_t user_index, X_INPUT_STATE* out_state) {
SCOPE_profile_cpu_f("hid"); SCOPE_profile_cpu_f("hid");
for (auto it = drivers_.begin(); it != drivers_.end(); ++it) { for (auto it = drivers_.begin(); it != drivers_.end(); ++it) {
@ -65,8 +59,8 @@ X_RESULT InputSystem::GetState(uint32_t user_index, X_INPUT_STATE& out_state) {
return X_ERROR_DEVICE_NOT_CONNECTED; return X_ERROR_DEVICE_NOT_CONNECTED;
} }
X_RESULT InputSystem::SetState( X_RESULT InputSystem::SetState(uint32_t user_index,
uint32_t user_index, X_INPUT_VIBRATION& vibration) { X_INPUT_VIBRATION* vibration) {
SCOPE_profile_cpu_f("hid"); SCOPE_profile_cpu_f("hid");
for (auto it = drivers_.begin(); it != drivers_.end(); ++it) { for (auto it = drivers_.begin(); it != drivers_.end(); ++it) {
@ -78,8 +72,8 @@ X_RESULT InputSystem::SetState(
return X_ERROR_DEVICE_NOT_CONNECTED; return X_ERROR_DEVICE_NOT_CONNECTED;
} }
X_RESULT InputSystem::GetKeystroke( X_RESULT InputSystem::GetKeystroke(uint32_t user_index, uint32_t flags,
uint32_t user_index, uint32_t flags, X_INPUT_KEYSTROKE& out_keystroke) { X_INPUT_KEYSTROKE* out_keystroke) {
SCOPE_profile_cpu_f("hid"); SCOPE_profile_cpu_f("hid");
for (auto it = drivers_.begin(); it != drivers_.end(); ++it) { for (auto it = drivers_.begin(); it != drivers_.end(); ++it) {
@ -89,4 +83,7 @@ X_RESULT InputSystem::GetKeystroke(
} }
} }
return X_ERROR_DEVICE_NOT_CONNECTED; return X_ERROR_DEVICE_NOT_CONNECTED;
} }
} // namespace hid
} // namespace xe

View File

@ -15,19 +15,16 @@
#include <xenia/core.h> #include <xenia/core.h>
#include <xenia/xbox.h> #include <xenia/xbox.h>
XEDECLARECLASS1(xe, Emulator); XEDECLARECLASS1(xe, Emulator);
XEDECLARECLASS2(xe, cpu, Processor); XEDECLARECLASS2(xe, cpu, Processor);
namespace xe { namespace xe {
namespace hid { namespace hid {
class InputDriver; class InputDriver;
class InputSystem { class InputSystem {
public: public:
InputSystem(Emulator* emulator); InputSystem(Emulator* emulator);
~InputSystem(); ~InputSystem();
@ -39,24 +36,22 @@ public:
void AddDriver(InputDriver* driver); void AddDriver(InputDriver* driver);
X_RESULT GetCapabilities( X_RESULT GetCapabilities(uint32_t user_index, uint32_t flags,
uint32_t user_index, uint32_t flags, X_INPUT_CAPABILITIES& out_caps); X_INPUT_CAPABILITIES* out_caps);
X_RESULT GetState(uint32_t user_index, X_INPUT_STATE& out_state); X_RESULT GetState(uint32_t user_index, X_INPUT_STATE* out_state);
X_RESULT SetState(uint32_t user_index, X_INPUT_VIBRATION& vibration); X_RESULT SetState(uint32_t user_index, X_INPUT_VIBRATION* vibration);
X_RESULT GetKeystroke(uint32_t user_index, uint32_t flags, X_RESULT GetKeystroke(uint32_t user_index, uint32_t flags,
X_INPUT_KEYSTROKE& out_keystroke); X_INPUT_KEYSTROKE* out_keystroke);
private: private:
Emulator* emulator_; Emulator* emulator_;
Memory* memory_; Memory* memory_;
cpu::Processor* processor_; cpu::Processor* processor_;
std::vector<InputDriver*> drivers_; std::vector<InputDriver*> drivers_;
}; };
} // namespace hid } // namespace hid
} // namespace xe } // namespace xe
#endif // XENIA_HID_INPUT_SYSTEM_H_ #endif // XENIA_HID_INPUT_SYSTEM_H_

View File

@ -11,21 +11,16 @@
#define XENIA_HID_NOP_NOP_HID_PRIVATE_H_ #define XENIA_HID_NOP_NOP_HID_PRIVATE_H_
#include <xenia/core.h> #include <xenia/core.h>
#include <xenia/hid/nop/nop_hid.h> #include <xenia/hid/nop/nop_hid.h>
namespace xe { namespace xe {
namespace hid { namespace hid {
namespace nop { namespace nop {
//
} // namespace nop } // namespace nop
} // namespace hid } // namespace hid
} // namespace xe } // namespace xe
#endif // XENIA_HID_NOP_NOP_HID_PRIVATE_H_ #endif // XENIA_HID_NOP_NOP_HID_PRIVATE_H_

View File

@ -11,34 +11,32 @@
#include <xenia/hid/nop/nop_input_driver.h> #include <xenia/hid/nop/nop_input_driver.h>
namespace xe {
namespace hid {
namespace nop {
using namespace xe; void InitializeIfNeeded();
using namespace xe::hid; void CleanupOnShutdown();
using namespace xe::hid::nop;
void InitializeIfNeeded() {
namespace { static bool has_initialized = false;
void InitializeIfNeeded(); if (has_initialized) {
void CleanupOnShutdown(); return;
void InitializeIfNeeded() {
static bool has_initialized = false;
if (has_initialized) {
return;
}
has_initialized = true;
//
atexit(CleanupOnShutdown);
} }
has_initialized = true;
void CleanupOnShutdown() { //
}
atexit(CleanupOnShutdown);
} }
void CleanupOnShutdown() {}
InputDriver* xe::hid::nop::Create(InputSystem* input_system) { InputDriver* xe::hid::nop::Create(InputSystem* input_system) {
InitializeIfNeeded(); InitializeIfNeeded();
return new NopInputDriver(input_system); return new NopInputDriver(input_system);
} }
} // namespace nop
} // namespace hid
} // namespace xe

View File

@ -12,22 +12,17 @@
#include <xenia/core.h> #include <xenia/core.h>
XEDECLARECLASS2(xe, hid, InputDriver); XEDECLARECLASS2(xe, hid, InputDriver);
XEDECLARECLASS2(xe, hid, InputSystem); XEDECLARECLASS2(xe, hid, InputSystem);
namespace xe { namespace xe {
namespace hid { namespace hid {
namespace nop { namespace nop {
InputDriver* Create(InputSystem* input_system); InputDriver* Create(InputSystem* input_system);
} // namespace nop } // namespace nop
} // namespace hid } // namespace hid
} // namespace xe } // namespace xe
#endif // XENIA_HID_NOP_NOP_HID_H_ #endif // XENIA_HID_NOP_NOP_HID_H_

View File

@ -11,42 +11,40 @@
#include <xenia/hid/hid-private.h> #include <xenia/hid/hid-private.h>
namespace xe {
namespace hid {
namespace nop {
using namespace xe; NopInputDriver::NopInputDriver(InputSystem* input_system)
using namespace xe::hid; : InputDriver(input_system) {}
using namespace xe::hid::nop;
NopInputDriver::~NopInputDriver() {}
NopInputDriver::NopInputDriver(InputSystem* input_system) : X_STATUS NopInputDriver::Setup() { return X_STATUS_SUCCESS; }
InputDriver(input_system) {
}
NopInputDriver::~NopInputDriver() {
}
X_STATUS NopInputDriver::Setup() {
return X_STATUS_SUCCESS;
}
// TODO(benvanik): spoof a device so that games don't stop waiting for // TODO(benvanik): spoof a device so that games don't stop waiting for
// a controller to be plugged in. // a controller to be plugged in.
X_RESULT NopInputDriver::GetCapabilities( X_RESULT NopInputDriver::GetCapabilities(uint32_t user_index, uint32_t flags,
uint32_t user_index, uint32_t flags, X_INPUT_CAPABILITIES& out_caps) { X_INPUT_CAPABILITIES* out_caps) {
return X_ERROR_DEVICE_NOT_CONNECTED; return X_ERROR_DEVICE_NOT_CONNECTED;
} }
X_RESULT NopInputDriver::GetState( X_RESULT NopInputDriver::GetState(uint32_t user_index,
uint32_t user_index, X_INPUT_STATE& out_state) { X_INPUT_STATE* out_state) {
return X_ERROR_DEVICE_NOT_CONNECTED; return X_ERROR_DEVICE_NOT_CONNECTED;
} }
X_RESULT NopInputDriver::SetState( X_RESULT NopInputDriver::SetState(uint32_t user_index,
uint32_t user_index, X_INPUT_VIBRATION& vibration) { X_INPUT_VIBRATION* vibration) {
return X_ERROR_DEVICE_NOT_CONNECTED; return X_ERROR_DEVICE_NOT_CONNECTED;
} }
X_RESULT NopInputDriver::GetKeystroke( X_RESULT NopInputDriver::GetKeystroke(uint32_t user_index, uint32_t flags,
uint32_t user_index, uint32_t flags, X_INPUT_KEYSTROKE& out_keystroke) { X_INPUT_KEYSTROKE* out_keystroke) {
return X_ERROR_DEVICE_NOT_CONNECTED; return X_ERROR_DEVICE_NOT_CONNECTED;
} }
} // namespace nop
} // namespace hid
} // namespace xe

View File

@ -11,39 +11,30 @@
#define XENIA_HID_NOP_NOP_INPUT_DRIVER_H_ #define XENIA_HID_NOP_NOP_INPUT_DRIVER_H_
#include <xenia/core.h> #include <xenia/core.h>
#include <xenia/hid/input_driver.h> #include <xenia/hid/input_driver.h>
#include <xenia/hid/nop/nop_hid-private.h> #include <xenia/hid/nop/nop_hid-private.h>
namespace xe { namespace xe {
namespace hid { namespace hid {
namespace nop { namespace nop {
class NopInputDriver : public InputDriver { class NopInputDriver : public InputDriver {
public: public:
NopInputDriver(InputSystem* input_system); NopInputDriver(InputSystem* input_system);
virtual ~NopInputDriver(); ~NopInputDriver() override;
virtual X_STATUS Setup(); X_STATUS Setup() override;
virtual X_RESULT GetCapabilities( X_RESULT GetCapabilities(uint32_t user_index, uint32_t flags,
uint32_t user_index, uint32_t flags, X_INPUT_CAPABILITIES& out_caps); X_INPUT_CAPABILITIES* out_caps) override;
virtual X_RESULT GetState( X_RESULT GetState(uint32_t user_index, X_INPUT_STATE* out_state) override;
uint32_t user_index, X_INPUT_STATE& out_state); X_RESULT SetState(uint32_t user_index, X_INPUT_VIBRATION* vibration) override;
virtual X_RESULT SetState( X_RESULT GetKeystroke(uint32_t user_index, uint32_t flags,
uint32_t user_index, X_INPUT_VIBRATION& vibration); X_INPUT_KEYSTROKE* out_keystroke) override;
virtual X_RESULT GetKeystroke(
uint32_t user_index, uint32_t flags, X_INPUT_KEYSTROKE& out_keystroke);
protected:
}; };
} // namespace nop } // namespace nop
} // namespace hid } // namespace hid
} // namespace xe } // namespace xe
#endif // XENIA_HID_NOP_NOP_INPUT_DRIVER_H_ #endif // XENIA_HID_NOP_NOP_INPUT_DRIVER_H_

View File

@ -11,21 +11,16 @@
#define XENIA_HID_WINKEY_WINKEY_HID_PRIVATE_H_ #define XENIA_HID_WINKEY_WINKEY_HID_PRIVATE_H_
#include <xenia/core.h> #include <xenia/core.h>
#include <xenia/hid/winkey/winkey_hid.h> #include <xenia/hid/winkey/winkey_hid.h>
namespace xe { namespace xe {
namespace hid { namespace hid {
namespace winkey { namespace winkey {
//
} // namespace winkey } // namespace winkey
} // namespace hid } // namespace hid
} // namespace xe } // namespace xe
#endif // XENIA_HID_WINKEY_WINKEY_HID_PRIVATE_H_ #endif // XENIA_HID_WINKEY_WINKEY_HID_PRIVATE_H_

View File

@ -11,34 +11,32 @@
#include <xenia/hid/winkey/winkey_input_driver.h> #include <xenia/hid/winkey/winkey_input_driver.h>
namespace xe {
namespace hid {
namespace winkey {
using namespace xe; void InitializeIfNeeded();
using namespace xe::hid; void CleanupOnShutdown();
using namespace xe::hid::winkey;
void InitializeIfNeeded() {
namespace { static bool has_initialized = false;
void InitializeIfNeeded(); if (has_initialized) {
void CleanupOnShutdown(); return;
void InitializeIfNeeded() {
static bool has_initialized = false;
if (has_initialized) {
return;
}
has_initialized = true;
//
atexit(CleanupOnShutdown);
} }
has_initialized = true;
void CleanupOnShutdown() { //
}
atexit(CleanupOnShutdown);
} }
void CleanupOnShutdown() {}
InputDriver* xe::hid::winkey::Create(InputSystem* input_system) { InputDriver* xe::hid::winkey::Create(InputSystem* input_system) {
InitializeIfNeeded(); InitializeIfNeeded();
return new WinKeyInputDriver(input_system); return new WinKeyInputDriver(input_system);
} }
} // namespace winkey
} // namespace hid
} // namespace xe

View File

@ -12,22 +12,17 @@
#include <xenia/core.h> #include <xenia/core.h>
XEDECLARECLASS2(xe, hid, InputDriver); XEDECLARECLASS2(xe, hid, InputDriver);
XEDECLARECLASS2(xe, hid, InputSystem); XEDECLARECLASS2(xe, hid, InputSystem);
namespace xe { namespace xe {
namespace hid { namespace hid {
namespace winkey { namespace winkey {
InputDriver* Create(InputSystem* input_system); InputDriver* Create(InputSystem* input_system);
} // namespace winkey } // namespace winkey
} // namespace hid } // namespace hid
} // namespace xe } // namespace xe
#endif // XENIA_HID_WINKEY_WINKEY_HID_H_ #endif // XENIA_HID_WINKEY_WINKEY_HID_H_

View File

@ -11,51 +11,44 @@
#include <xenia/hid/hid-private.h> #include <xenia/hid/hid-private.h>
namespace xe {
namespace hid {
namespace winkey {
using namespace xe; WinKeyInputDriver::WinKeyInputDriver(InputSystem* input_system)
using namespace xe::hid; : packet_number_(1), InputDriver(input_system) {}
using namespace xe::hid::winkey;
WinKeyInputDriver::~WinKeyInputDriver() {}
WinKeyInputDriver::WinKeyInputDriver(InputSystem* input_system) : X_STATUS WinKeyInputDriver::Setup() { return X_STATUS_SUCCESS; }
packet_number_(1),
InputDriver(input_system) {
}
WinKeyInputDriver::~WinKeyInputDriver() { X_RESULT WinKeyInputDriver::GetCapabilities(uint32_t user_index, uint32_t flags,
} X_INPUT_CAPABILITIES* out_caps) {
X_STATUS WinKeyInputDriver::Setup() {
return X_STATUS_SUCCESS;
}
X_RESULT WinKeyInputDriver::GetCapabilities(
uint32_t user_index, uint32_t flags, X_INPUT_CAPABILITIES& out_caps) {
if (user_index != 0) { if (user_index != 0) {
return X_ERROR_DEVICE_NOT_CONNECTED; return X_ERROR_DEVICE_NOT_CONNECTED;
} }
// TODO(benvanik): confirm with a real XInput controller. // TODO(benvanik): confirm with a real XInput controller.
out_caps.type = 0x01; // XINPUT_DEVTYPE_GAMEPAD out_caps->type = 0x01; // XINPUT_DEVTYPE_GAMEPAD
out_caps.sub_type = 0x01; // XINPUT_DEVSUBTYPE_GAMEPAD out_caps->sub_type = 0x01; // XINPUT_DEVSUBTYPE_GAMEPAD
out_caps.flags = 0; out_caps->flags = 0;
out_caps.gamepad.buttons = 0xFFFF; out_caps->gamepad.buttons = 0xFFFF;
out_caps.gamepad.left_trigger = 0xFF; out_caps->gamepad.left_trigger = 0xFF;
out_caps.gamepad.right_trigger = 0xFF; out_caps->gamepad.right_trigger = 0xFF;
out_caps.gamepad.thumb_lx = (int16_t)0xFFFF; out_caps->gamepad.thumb_lx = (int16_t)0xFFFF;
out_caps.gamepad.thumb_ly = (int16_t)0xFFFF; out_caps->gamepad.thumb_ly = (int16_t)0xFFFF;
out_caps.gamepad.thumb_rx = (int16_t)0xFFFF; out_caps->gamepad.thumb_rx = (int16_t)0xFFFF;
out_caps.gamepad.thumb_ry = (int16_t)0xFFFF; out_caps->gamepad.thumb_ry = (int16_t)0xFFFF;
out_caps.vibration.left_motor_speed = 0; out_caps->vibration.left_motor_speed = 0;
out_caps.vibration.right_motor_speed = 0; out_caps->vibration.right_motor_speed = 0;
return X_ERROR_SUCCESS; return X_ERROR_SUCCESS;
} }
#define IS_KEY_TOGGLED(key) ((GetKeyState(key) & 0x1) == 0x1) #define IS_KEY_TOGGLED(key) ((GetKeyState(key) & 0x1) == 0x1)
#define IS_KEY_DOWN(key) ((GetAsyncKeyState(key) & 0x8000) == 0x8000) #define IS_KEY_DOWN(key) ((GetAsyncKeyState(key) & 0x8000) == 0x8000)
X_RESULT WinKeyInputDriver::GetState( X_RESULT WinKeyInputDriver::GetState(uint32_t user_index,
uint32_t user_index, X_INPUT_STATE& out_state) { X_INPUT_STATE* out_state) {
if (user_index != 0) { if (user_index != 0) {
return X_ERROR_DEVICE_NOT_CONNECTED; return X_ERROR_DEVICE_NOT_CONNECTED;
} }
@ -74,19 +67,19 @@ X_RESULT WinKeyInputDriver::GetState(
// dpad toggled // dpad toggled
if (IS_KEY_DOWN(0x41)) { if (IS_KEY_DOWN(0x41)) {
// A // A
buttons |= 0x0004; // XINPUT_GAMEPAD_DPAD_LEFT buttons |= 0x0004; // XINPUT_GAMEPAD_DPAD_LEFT
} }
if (IS_KEY_DOWN(0x44)) { if (IS_KEY_DOWN(0x44)) {
// D // D
buttons |= 0x0008; // XINPUT_GAMEPAD_DPAD_RIGHT buttons |= 0x0008; // XINPUT_GAMEPAD_DPAD_RIGHT
} }
if (IS_KEY_DOWN(0x53)) { if (IS_KEY_DOWN(0x53)) {
// S // S
buttons |= 0x0002; // XINPUT_GAMEPAD_DPAD_DOWN buttons |= 0x0002; // XINPUT_GAMEPAD_DPAD_DOWN
} }
if (IS_KEY_DOWN(0x57)) { if (IS_KEY_DOWN(0x57)) {
// W // W
buttons |= 0x0001; // XINPUT_GAMEPAD_DPAD_UP buttons |= 0x0001; // XINPUT_GAMEPAD_DPAD_UP
} }
} else { } else {
// left stick // left stick
@ -110,44 +103,44 @@ X_RESULT WinKeyInputDriver::GetState(
if (IS_KEY_DOWN(0x4C)) { if (IS_KEY_DOWN(0x4C)) {
// L // L
buttons |= 0x4000; // XINPUT_GAMEPAD_X buttons |= 0x4000; // XINPUT_GAMEPAD_X
} }
if (IS_KEY_DOWN(VK_OEM_7)) { if (IS_KEY_DOWN(VK_OEM_7)) {
// ' // '
buttons |= 0x2000; // XINPUT_GAMEPAD_B buttons |= 0x2000; // XINPUT_GAMEPAD_B
} }
if (IS_KEY_DOWN(VK_OEM_1)) { if (IS_KEY_DOWN(VK_OEM_1)) {
// ; // ;
buttons |= 0x1000; // XINPUT_GAMEPAD_A buttons |= 0x1000; // XINPUT_GAMEPAD_A
} }
if (IS_KEY_DOWN(0x50)) { if (IS_KEY_DOWN(0x50)) {
// P // P
buttons |= 0x8000; // XINPUT_GAMEPAD_Y buttons |= 0x8000; // XINPUT_GAMEPAD_Y
} }
if (IS_KEY_DOWN(0x5A)) { if (IS_KEY_DOWN(0x5A)) {
// Z // Z
buttons |= 0x0020; // XINPUT_GAMEPAD_BACK buttons |= 0x0020; // XINPUT_GAMEPAD_BACK
} }
if (IS_KEY_DOWN(0x58)) { if (IS_KEY_DOWN(0x58)) {
// X // X
buttons |= 0x0010; // XINPUT_GAMEPAD_START buttons |= 0x0010; // XINPUT_GAMEPAD_START
} }
out_state.packet_number = packet_number_; out_state->packet_number = packet_number_;
out_state.gamepad.buttons = buttons; out_state->gamepad.buttons = buttons;
out_state.gamepad.left_trigger = left_trigger; out_state->gamepad.left_trigger = left_trigger;
out_state.gamepad.right_trigger = right_trigger; out_state->gamepad.right_trigger = right_trigger;
out_state.gamepad.thumb_lx = thumb_lx; out_state->gamepad.thumb_lx = thumb_lx;
out_state.gamepad.thumb_ly = thumb_ly; out_state->gamepad.thumb_ly = thumb_ly;
out_state.gamepad.thumb_rx = thumb_rx; out_state->gamepad.thumb_rx = thumb_rx;
out_state.gamepad.thumb_ry = thumb_ry; out_state->gamepad.thumb_ry = thumb_ry;
return X_ERROR_SUCCESS; return X_ERROR_SUCCESS;
} }
X_RESULT WinKeyInputDriver::SetState( X_RESULT WinKeyInputDriver::SetState(uint32_t user_index,
uint32_t user_index, X_INPUT_VIBRATION& vibration) { X_INPUT_VIBRATION* vibration) {
if (user_index != 0) { if (user_index != 0) {
return X_ERROR_DEVICE_NOT_CONNECTED; return X_ERROR_DEVICE_NOT_CONNECTED;
} }
@ -155,8 +148,8 @@ X_RESULT WinKeyInputDriver::SetState(
return X_ERROR_SUCCESS; return X_ERROR_SUCCESS;
} }
X_RESULT WinKeyInputDriver::GetKeystroke( X_RESULT WinKeyInputDriver::GetKeystroke(uint32_t user_index, uint32_t flags,
uint32_t user_index, uint32_t flags, X_INPUT_KEYSTROKE& out_keystroke) { X_INPUT_KEYSTROKE* out_keystroke) {
if (user_index != 0) { if (user_index != 0) {
return X_ERROR_DEVICE_NOT_CONNECTED; return X_ERROR_DEVICE_NOT_CONNECTED;
} }
@ -168,14 +161,18 @@ X_RESULT WinKeyInputDriver::GetKeystroke(
uint16_t keystroke_flags = 0; uint16_t keystroke_flags = 0;
uint8_t hid_code = 0; uint8_t hid_code = 0;
out_keystroke.virtual_key = virtual_key; out_keystroke->virtual_key = virtual_key;
out_keystroke.unicode = unicode; out_keystroke->unicode = unicode;
out_keystroke.flags = keystroke_flags; out_keystroke->flags = keystroke_flags;
out_keystroke.user_index = 0; out_keystroke->user_index = 0;
out_keystroke.hid_code = hid_code; out_keystroke->hid_code = hid_code;
// X_ERROR_EMPTY if no new keys // X_ERROR_EMPTY if no new keys
// X_ERROR_DEVICE_NOT_CONNECTED if no device // X_ERROR_DEVICE_NOT_CONNECTED if no device
// X_ERROR_SUCCESS if key // X_ERROR_SUCCESS if key
return result; return result;
} }
} // namespace winkey
} // namespace hid
} // namespace xe

View File

@ -11,40 +11,33 @@
#define XENIA_HID_WINKEY_WINKEY_DRIVER_H_ #define XENIA_HID_WINKEY_WINKEY_DRIVER_H_
#include <xenia/core.h> #include <xenia/core.h>
#include <xenia/hid/input_driver.h> #include <xenia/hid/input_driver.h>
#include <xenia/hid/nop/nop_hid-private.h> #include <xenia/hid/nop/nop_hid-private.h>
namespace xe { namespace xe {
namespace hid { namespace hid {
namespace winkey { namespace winkey {
class WinKeyInputDriver : public InputDriver { class WinKeyInputDriver : public InputDriver {
public: public:
WinKeyInputDriver(InputSystem* input_system); WinKeyInputDriver(InputSystem* input_system);
virtual ~WinKeyInputDriver(); ~WinKeyInputDriver() override;
virtual X_STATUS Setup(); X_STATUS Setup() override;
virtual X_RESULT GetCapabilities( X_RESULT GetCapabilities(uint32_t user_index, uint32_t flags,
uint32_t user_index, uint32_t flags, X_INPUT_CAPABILITIES& out_caps); X_INPUT_CAPABILITIES* out_caps) override;
virtual X_RESULT GetState( X_RESULT GetState(uint32_t user_index, X_INPUT_STATE* out_state) override;
uint32_t user_index, X_INPUT_STATE& out_state); X_RESULT SetState(uint32_t user_index, X_INPUT_VIBRATION* vibration) override;
virtual X_RESULT SetState( X_RESULT GetKeystroke(uint32_t user_index, uint32_t flags,
uint32_t user_index, X_INPUT_VIBRATION& vibration); X_INPUT_KEYSTROKE* out_keystroke) override;
virtual X_RESULT GetKeystroke(
uint32_t user_index, uint32_t flags, X_INPUT_KEYSTROKE& out_keystroke);
protected: protected:
uint32_t packet_number_; uint32_t packet_number_;
}; };
} // namespace winkey } // namespace winkey
} // namespace hid } // namespace hid
} // namespace xe } // namespace xe
#endif // XENIA_HID_WINKEY_WINKEY_DRIVER_H_ #endif // XENIA_HID_WINKEY_WINKEY_DRIVER_H_

View File

@ -11,21 +11,16 @@
#define XENIA_HID_XINPUT_XINPUT_HID_PRIVATE_H_ #define XENIA_HID_XINPUT_XINPUT_HID_PRIVATE_H_
#include <xenia/core.h> #include <xenia/core.h>
#include <xenia/hid/xinput/xinput_hid.h> #include <xenia/hid/xinput/xinput_hid.h>
namespace xe { namespace xe {
namespace hid { namespace hid {
namespace xinput { namespace xinput {
//
} // namespace xinput } // namespace xinput
} // namespace hid } // namespace hid
} // namespace xe } // namespace xe
#endif // XENIA_HID_XINPUT_XINPUT_HID_PRIVATE_H_ #endif // XENIA_HID_XINPUT_XINPUT_HID_PRIVATE_H_

View File

@ -11,34 +11,32 @@
#include <xenia/hid/xinput/xinput_input_driver.h> #include <xenia/hid/xinput/xinput_input_driver.h>
namespace xe {
namespace hid {
namespace xinput {
using namespace xe; void InitializeIfNeeded();
using namespace xe::hid; void CleanupOnShutdown();
using namespace xe::hid::xinput;
void InitializeIfNeeded() {
namespace { static bool has_initialized = false;
void InitializeIfNeeded(); if (has_initialized) {
void CleanupOnShutdown(); return;
void InitializeIfNeeded() {
static bool has_initialized = false;
if (has_initialized) {
return;
}
has_initialized = true;
//
atexit(CleanupOnShutdown);
} }
has_initialized = true;
void CleanupOnShutdown() { //
}
atexit(CleanupOnShutdown);
} }
void CleanupOnShutdown() {}
InputDriver* xe::hid::xinput::Create(InputSystem* input_system) { InputDriver* xe::hid::xinput::Create(InputSystem* input_system) {
InitializeIfNeeded(); InitializeIfNeeded();
return new XInputInputDriver(input_system); return new XInputInputDriver(input_system);
} }
} // namespace xinput
} // namespace hid
} // namespace xe

View File

@ -12,22 +12,17 @@
#include <xenia/core.h> #include <xenia/core.h>
XEDECLARECLASS2(xe, hid, InputDriver); XEDECLARECLASS2(xe, hid, InputDriver);
XEDECLARECLASS2(xe, hid, InputSystem); XEDECLARECLASS2(xe, hid, InputSystem);
namespace xe { namespace xe {
namespace hid { namespace hid {
namespace xinput { namespace xinput {
InputDriver* Create(InputSystem* input_system); InputDriver* Create(InputSystem* input_system);
} // namespace xinput } // namespace xinput
} // namespace hid } // namespace hid
} // namespace xe } // namespace xe
#endif // XENIA_HID_XINPUT_XINPUT_HID_H_ #endif // XENIA_HID_XINPUT_XINPUT_HID_H_

View File

@ -13,95 +13,92 @@
#include <Xinput.h> #include <Xinput.h>
namespace xe {
namespace hid {
namespace xinput {
using namespace xe; XInputInputDriver::XInputInputDriver(InputSystem* input_system)
using namespace xe::hid; : InputDriver(input_system) {
using namespace xe::hid::xinput;
XInputInputDriver::XInputInputDriver(InputSystem* input_system) :
InputDriver(input_system) {
XInputEnable(TRUE); XInputEnable(TRUE);
} }
XInputInputDriver::~XInputInputDriver() { XInputInputDriver::~XInputInputDriver() { XInputEnable(FALSE); }
XInputEnable(FALSE);
}
X_STATUS XInputInputDriver::Setup() { X_STATUS XInputInputDriver::Setup() { return X_STATUS_SUCCESS; }
return X_STATUS_SUCCESS;
}
X_RESULT XInputInputDriver::GetCapabilities( X_RESULT XInputInputDriver::GetCapabilities(uint32_t user_index, uint32_t flags,
uint32_t user_index, uint32_t flags, X_INPUT_CAPABILITIES& out_caps) { X_INPUT_CAPABILITIES* out_caps) {
XINPUT_CAPABILITIES native_caps; XINPUT_CAPABILITIES native_caps;
DWORD result = XInputGetCapabilities(user_index, flags, &native_caps); DWORD result = XInputGetCapabilities(user_index, flags, &native_caps);
if (result) { if (result) {
return result; return result;
} }
out_caps.type = native_caps.Type; out_caps->type = native_caps.Type;
out_caps.sub_type = native_caps.SubType; out_caps->sub_type = native_caps.SubType;
out_caps.flags = native_caps.Flags; out_caps->flags = native_caps.Flags;
out_caps.gamepad.buttons = native_caps.Gamepad.wButtons; out_caps->gamepad.buttons = native_caps.Gamepad.wButtons;
out_caps.gamepad.left_trigger = native_caps.Gamepad.bLeftTrigger; out_caps->gamepad.left_trigger = native_caps.Gamepad.bLeftTrigger;
out_caps.gamepad.right_trigger = native_caps.Gamepad.bRightTrigger; out_caps->gamepad.right_trigger = native_caps.Gamepad.bRightTrigger;
out_caps.gamepad.thumb_lx = native_caps.Gamepad.sThumbLX; out_caps->gamepad.thumb_lx = native_caps.Gamepad.sThumbLX;
out_caps.gamepad.thumb_ly = native_caps.Gamepad.sThumbLY; out_caps->gamepad.thumb_ly = native_caps.Gamepad.sThumbLY;
out_caps.gamepad.thumb_rx = native_caps.Gamepad.sThumbRX; out_caps->gamepad.thumb_rx = native_caps.Gamepad.sThumbRX;
out_caps.gamepad.thumb_ry = native_caps.Gamepad.sThumbRY; out_caps->gamepad.thumb_ry = native_caps.Gamepad.sThumbRY;
out_caps.vibration.left_motor_speed = out_caps->vibration.left_motor_speed = native_caps.Vibration.wLeftMotorSpeed;
native_caps.Vibration.wLeftMotorSpeed; out_caps->vibration.right_motor_speed =
out_caps.vibration.right_motor_speed =
native_caps.Vibration.wRightMotorSpeed; native_caps.Vibration.wRightMotorSpeed;
return result; return result;
} }
X_RESULT XInputInputDriver::GetState( X_RESULT XInputInputDriver::GetState(uint32_t user_index,
uint32_t user_index, X_INPUT_STATE& out_state) { X_INPUT_STATE* out_state) {
XINPUT_STATE native_state; XINPUT_STATE native_state;
DWORD result = XInputGetState(user_index, &native_state); DWORD result = XInputGetState(user_index, &native_state);
if (result) { if (result) {
return result; return result;
} }
out_state.packet_number = native_state.dwPacketNumber; out_state->packet_number = native_state.dwPacketNumber;
out_state.gamepad.buttons = native_state.Gamepad.wButtons; out_state->gamepad.buttons = native_state.Gamepad.wButtons;
out_state.gamepad.left_trigger = native_state.Gamepad.bLeftTrigger; out_state->gamepad.left_trigger = native_state.Gamepad.bLeftTrigger;
out_state.gamepad.right_trigger = native_state.Gamepad.bRightTrigger; out_state->gamepad.right_trigger = native_state.Gamepad.bRightTrigger;
out_state.gamepad.thumb_lx = native_state.Gamepad.sThumbLX; out_state->gamepad.thumb_lx = native_state.Gamepad.sThumbLX;
out_state.gamepad.thumb_ly = native_state.Gamepad.sThumbLY; out_state->gamepad.thumb_ly = native_state.Gamepad.sThumbLY;
out_state.gamepad.thumb_rx = native_state.Gamepad.sThumbRX; out_state->gamepad.thumb_rx = native_state.Gamepad.sThumbRX;
out_state.gamepad.thumb_ry = native_state.Gamepad.sThumbRY; out_state->gamepad.thumb_ry = native_state.Gamepad.sThumbRY;
return result; return result;
} }
X_RESULT XInputInputDriver::SetState( X_RESULT XInputInputDriver::SetState(uint32_t user_index,
uint32_t user_index, X_INPUT_VIBRATION& vibration) { X_INPUT_VIBRATION* vibration) {
XINPUT_VIBRATION native_vibration; XINPUT_VIBRATION native_vibration;
native_vibration.wLeftMotorSpeed = vibration.left_motor_speed; native_vibration.wLeftMotorSpeed = vibration->left_motor_speed;
native_vibration.wRightMotorSpeed= vibration.right_motor_speed; native_vibration.wRightMotorSpeed = vibration->right_motor_speed;
DWORD result = XInputSetState(user_index, &native_vibration); DWORD result = XInputSetState(user_index, &native_vibration);
return result; return result;
} }
X_RESULT XInputInputDriver::GetKeystroke( X_RESULT XInputInputDriver::GetKeystroke(uint32_t user_index, uint32_t flags,
uint32_t user_index, uint32_t flags, X_INPUT_KEYSTROKE& out_keystroke) { X_INPUT_KEYSTROKE* out_keystroke) {
// We may want to filter flags/user_index before sending to native. // We may want to filter flags/user_index before sending to native.
// flags is reserved on desktop. // flags is reserved on desktop.
XINPUT_KEYSTROKE native_keystroke; XINPUT_KEYSTROKE native_keystroke;
DWORD result = XInputGetKeystroke(user_index, flags, &native_keystroke); DWORD result = XInputGetKeystroke(user_index, flags, &native_keystroke);
if (result == ERROR_SUCCESS) { if (result == ERROR_SUCCESS) {
out_keystroke.virtual_key = native_keystroke.VirtualKey; out_keystroke->virtual_key = native_keystroke.VirtualKey;
out_keystroke.unicode = native_keystroke.Unicode; out_keystroke->unicode = native_keystroke.Unicode;
out_keystroke.flags = native_keystroke.Flags; out_keystroke->flags = native_keystroke.Flags;
out_keystroke.user_index = native_keystroke.UserIndex; out_keystroke->user_index = native_keystroke.UserIndex;
out_keystroke.hid_code = native_keystroke.HidCode; out_keystroke->hid_code = native_keystroke.HidCode;
} }
// X_ERROR_EMPTY if no new keys // X_ERROR_EMPTY if no new keys
// X_ERROR_DEVICE_NOT_CONNECTED if no device // X_ERROR_DEVICE_NOT_CONNECTED if no device
// X_ERROR_SUCCESS if key // X_ERROR_SUCCESS if key
return result; return result;
} }
} // namespace xinput
} // namespace hid
} // namespace xe

View File

@ -11,39 +11,32 @@
#define XENIA_HID_XINPUT_XINPUT_DRIVER_H_ #define XENIA_HID_XINPUT_XINPUT_DRIVER_H_
#include <xenia/core.h> #include <xenia/core.h>
#include <xenia/hid/input_driver.h> #include <xenia/hid/input_driver.h>
#include <xenia/hid/nop/nop_hid-private.h> #include <xenia/hid/nop/nop_hid-private.h>
namespace xe { namespace xe {
namespace hid { namespace hid {
namespace xinput { namespace xinput {
class XInputInputDriver : public InputDriver { class XInputInputDriver : public InputDriver {
public: public:
XInputInputDriver(InputSystem* input_system); XInputInputDriver(InputSystem* input_system);
virtual ~XInputInputDriver(); ~XInputInputDriver() override;
virtual X_STATUS Setup(); X_STATUS Setup() override;
virtual X_RESULT GetCapabilities( X_RESULT GetCapabilities(uint32_t user_index, uint32_t flags,
uint32_t user_index, uint32_t flags, X_INPUT_CAPABILITIES& out_caps); X_INPUT_CAPABILITIES* out_caps) override;
virtual X_RESULT GetState( X_RESULT GetState(uint32_t user_index, X_INPUT_STATE* out_state) override;
uint32_t user_index, X_INPUT_STATE& out_state); X_RESULT SetState(uint32_t user_index, X_INPUT_VIBRATION* vibration) override;
virtual X_RESULT SetState( X_RESULT GetKeystroke(uint32_t user_index, uint32_t flags,
uint32_t user_index, X_INPUT_VIBRATION& vibration); X_INPUT_KEYSTROKE* out_keystroke) override;
virtual X_RESULT GetKeystroke(
uint32_t user_index, uint32_t flags, X_INPUT_KEYSTROKE& out_keystroke);
protected: protected:
}; };
} // namespace xinput } // namespace xinput
} // namespace hid } // namespace hid
} // namespace xe } // namespace xe
#endif // XENIA_HID_XINPUT_XINPUT_DRIVER_H_ #endif // XENIA_HID_XINPUT_XINPUT_DRIVER_H_

View File

@ -58,6 +58,8 @@ using PPCContext = alloy::frontend::ppc::PPCContext;
#define SHIM_SET_RETURN_32(v) SHIM_SET_GPR_64(3, (uint64_t)(int32_t)v) #define SHIM_SET_RETURN_32(v) SHIM_SET_GPR_64(3, (uint64_t)(int32_t)v)
#define SHIM_SET_RETURN_64(v) SHIM_SET_GPR_64(3, v) #define SHIM_SET_RETURN_64(v) SHIM_SET_GPR_64(3, v)
#define SHIM_STRUCT(type, address) \
reinterpret_cast<type*>(SHIM_MEM_ADDR(address))
} // namespace kernel } // namespace kernel
} // namespace xe } // namespace xe

View File

@ -58,11 +58,8 @@ SHIM_CALL XamInputGetCapabilities_shim(PPCContext* ppc_state,
InputSystem* input_system = state->emulator()->input_system(); InputSystem* input_system = state->emulator()->input_system();
X_INPUT_CAPABILITIES caps; auto caps = SHIM_STRUCT(X_INPUT_CAPABILITIES, caps_ptr);
X_RESULT result = input_system->GetCapabilities(user_index, flags, caps); X_RESULT result = input_system->GetCapabilities(user_index, flags, caps);
if (XSUCCEEDED(result)) {
caps.Write(SHIM_MEM_BASE, caps_ptr);
}
SHIM_SET_RETURN_32(result); SHIM_SET_RETURN_32(result);
} }
@ -78,13 +75,8 @@ SHIM_CALL XamInputGetState_shim(PPCContext* ppc_state, KernelState* state) {
InputSystem* input_system = state->emulator()->input_system(); InputSystem* input_system = state->emulator()->input_system();
X_INPUT_STATE input_state; auto input_state = SHIM_STRUCT(X_INPUT_STATE, state_ptr);
X_RESULT result = input_system->GetState(user_index, input_state); X_RESULT 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_32(result); SHIM_SET_RETURN_32(result);
} }
@ -103,7 +95,7 @@ SHIM_CALL XamInputSetState_shim(PPCContext* ppc_state, KernelState* state) {
InputSystem* input_system = state->emulator()->input_system(); InputSystem* input_system = state->emulator()->input_system();
X_INPUT_VIBRATION vibration(SHIM_MEM_BASE, vibration_ptr); auto vibration = SHIM_STRUCT(X_INPUT_VIBRATION, vibration_ptr);
X_RESULT result = input_system->SetState(user_index, vibration); X_RESULT result = input_system->SetState(user_index, vibration);
SHIM_SET_RETURN_32(result); SHIM_SET_RETURN_32(result);
} }
@ -128,11 +120,8 @@ SHIM_CALL XamInputGetKeystroke_shim(PPCContext* ppc_state, KernelState* state) {
InputSystem* input_system = state->emulator()->input_system(); InputSystem* input_system = state->emulator()->input_system();
X_INPUT_KEYSTROKE keystroke; auto keystroke = SHIM_STRUCT(X_INPUT_KEYSTROKE, keystroke_ptr);
X_RESULT result = input_system->GetKeystroke(user_index, flags, keystroke); X_RESULT result = input_system->GetKeystroke(user_index, flags, keystroke);
if (XSUCCEEDED(result)) {
keystroke.Write(SHIM_MEM_BASE, keystroke_ptr);
}
SHIM_SET_RETURN_32(result); SHIM_SET_RETURN_32(result);
} }
@ -155,11 +144,10 @@ SHIM_CALL XamInputGetKeystrokeEx_shim(PPCContext* ppc_state,
InputSystem* input_system = state->emulator()->input_system(); InputSystem* input_system = state->emulator()->input_system();
X_INPUT_KEYSTROKE keystroke; auto keystroke = SHIM_STRUCT(X_INPUT_KEYSTROKE, keystroke_ptr);
X_RESULT result = input_system->GetKeystroke(user_index, flags, keystroke); X_RESULT result = input_system->GetKeystroke(user_index, flags, keystroke);
if (XSUCCEEDED(result)) { if (XSUCCEEDED(result)) {
SHIM_SET_MEM_32(user_index_ptr, keystroke.user_index); SHIM_SET_MEM_32(user_index_ptr, keystroke->user_index);
keystroke.Write(SHIM_MEM_BASE, keystroke_ptr);
} }
SHIM_SET_RETURN_32(result); SHIM_SET_RETURN_32(result);
} }

View File

@ -10,12 +10,16 @@
#ifndef XENIA_XBOX_H_ #ifndef XENIA_XBOX_H_
#define XENIA_XBOX_H_ #define XENIA_XBOX_H_
#include <poly/memory.h>
#include <xenia/common.h> #include <xenia/common.h>
#include <xenia/core.h> #include <xenia/core.h>
namespace xe { namespace xe {
template <typename T>
using be = poly::be<T>;
#pragma pack(push, 4) #pragma pack(push, 4)
@ -277,6 +281,7 @@ public:
return copy; return copy;
} }
}; };
//static_assert_size(X_ANSI_STRING, 8);
class X_OBJECT_ATTRIBUTES { class X_OBJECT_ATTRIBUTES {
@ -309,6 +314,7 @@ public:
attributes = 0; attributes = 0;
} }
}; };
static_assert_size(X_OBJECT_ATTRIBUTES, 12 + sizeof(X_ANSI_STRING));
// Values seem to be all over the place - GUIDs? // Values seem to be all over the place - GUIDs?
@ -330,194 +336,72 @@ struct X_VIDEO_MODE {
}; };
static_assert_size(X_VIDEO_MODE, 48); static_assert_size(X_VIDEO_MODE, 48);
typedef enum _X_INPUT_FLAG { typedef enum _X_INPUT_FLAG {
X_INPUT_FLAG_GAMEPAD = 0x00000001, X_INPUT_FLAG_GAMEPAD = 0x00000001,
} X_INPUT_FLAG; } X_INPUT_FLAG;
typedef enum _X_INPUT_GAMEPAD_BUTTON { typedef enum _X_INPUT_GAMEPAD_BUTTON {
X_INPUT_GAMEPAD_DPAD_UP = 0x0001, X_INPUT_GAMEPAD_DPAD_UP = 0x0001,
X_INPUT_GAMEPAD_DPAD_DOWN = 0x0002, X_INPUT_GAMEPAD_DPAD_DOWN = 0x0002,
X_INPUT_GAMEPAD_DPAD_LEFT = 0x0004, X_INPUT_GAMEPAD_DPAD_LEFT = 0x0004,
X_INPUT_GAMEPAD_DPAD_RIGHT = 0x0008, X_INPUT_GAMEPAD_DPAD_RIGHT = 0x0008,
X_INPUT_GAMEPAD_START = 0x0010, X_INPUT_GAMEPAD_START = 0x0010,
X_INPUT_GAMEPAD_BACK = 0x0020, X_INPUT_GAMEPAD_BACK = 0x0020,
X_INPUT_GAMEPAD_LEFT_THUMB = 0x0040, X_INPUT_GAMEPAD_LEFT_THUMB = 0x0040,
X_INPUT_GAMEPAD_RIGHT_THUMB = 0x0080, X_INPUT_GAMEPAD_RIGHT_THUMB = 0x0080,
X_INPUT_GAMEPAD_LEFT_SHOULDER = 0x0100, X_INPUT_GAMEPAD_LEFT_SHOULDER = 0x0100,
X_INPUT_GAMEPAD_RIGHT_SHOULDER = 0x0200, X_INPUT_GAMEPAD_RIGHT_SHOULDER = 0x0200,
X_INPUT_GAMEPAD_A = 0x1000, X_INPUT_GAMEPAD_A = 0x1000,
X_INPUT_GAMEPAD_B = 0x2000, X_INPUT_GAMEPAD_B = 0x2000,
X_INPUT_GAMEPAD_X = 0x4000, X_INPUT_GAMEPAD_X = 0x4000,
X_INPUT_GAMEPAD_Y = 0x8000, X_INPUT_GAMEPAD_Y = 0x8000,
} X_INPUT_GAMEPAD_BUTTON; } X_INPUT_GAMEPAD_BUTTON;
class X_INPUT_GAMEPAD { struct X_INPUT_GAMEPAD {
public: be<uint16_t> buttons;
uint16_t buttons; be<uint8_t> left_trigger;
uint8_t left_trigger; be<uint8_t> right_trigger;
uint8_t right_trigger; be<int16_t> thumb_lx;
int16_t thumb_lx; be<int16_t> thumb_ly;
int16_t thumb_ly; be<int16_t> thumb_rx;
int16_t thumb_rx; be<int16_t> thumb_ry;
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 = poly::load_and_swap<uint16_t>(base + p);
left_trigger = poly::load_and_swap<uint8_t>(base + p + 2);
right_trigger = poly::load_and_swap<uint8_t>(base + p + 3);
thumb_lx = poly::load_and_swap<int16_t>(base + p + 4);
thumb_ly = poly::load_and_swap<int16_t>(base + p + 6);
thumb_rx = poly::load_and_swap<int16_t>(base + p + 8);
thumb_ry = poly::load_and_swap<int16_t>(base + p + 10);
}
void Write(uint8_t* base, uint32_t p) {
poly::store_and_swap<uint16_t>(base + p, buttons);
poly::store_and_swap<uint8_t>(base + p + 2, left_trigger);
poly::store_and_swap<uint8_t>(base + p + 3, right_trigger);
poly::store_and_swap<int16_t>(base + p + 4, thumb_lx);
poly::store_and_swap<int16_t>(base + p + 6, thumb_ly);
poly::store_and_swap<int16_t>(base + p + 8, thumb_rx);
poly::store_and_swap<int16_t>(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 { static_assert_size(X_INPUT_GAMEPAD, 12);
public:
uint32_t packet_number;
X_INPUT_GAMEPAD gamepad;
X_INPUT_STATE() { struct X_INPUT_STATE {
Zero(); be<uint32_t> packet_number;
} X_INPUT_GAMEPAD gamepad;
X_INPUT_STATE(const uint8_t* base, uint32_t p) {
Read(base, p);
}
void Read(const uint8_t* base, uint32_t p) {
packet_number = poly::load_and_swap<uint32_t>(base + p);
gamepad.Read(base, p + 4);
}
void Write(uint8_t* base, uint32_t p) {
poly::store_and_swap<uint32_t>(base + p, packet_number);
gamepad.Write(base, p + 4);
}
void Zero() {
packet_number = 0;
gamepad.Zero();
}
}; };
class X_INPUT_VIBRATION { static_assert_size(X_INPUT_STATE, sizeof(X_INPUT_GAMEPAD) + 4);
public:
uint16_t left_motor_speed;
uint16_t right_motor_speed;
X_INPUT_VIBRATION() { struct X_INPUT_VIBRATION {
Zero(); be<uint16_t> left_motor_speed;
} be<uint16_t> right_motor_speed;
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 = poly::load_and_swap<uint16_t>(base + p);
right_motor_speed = poly::load_and_swap<uint16_t>(base + p + 2);
}
void Write(uint8_t* base, uint32_t p) {
poly::store_and_swap<uint16_t>(base + p, left_motor_speed);
poly::store_and_swap<uint16_t>(base + p + 2, right_motor_speed);
}
void Zero() {
left_motor_speed = right_motor_speed = 0;
}
}; };
class X_INPUT_CAPABILITIES { static_assert_size(X_INPUT_VIBRATION, 4);
public:
uint8_t type; struct X_INPUT_CAPABILITIES {
uint8_t sub_type; be<uint8_t> type;
uint16_t flags; be<uint8_t> sub_type;
X_INPUT_GAMEPAD gamepad; be<uint16_t> flags;
X_INPUT_GAMEPAD gamepad;
X_INPUT_VIBRATION vibration; 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 = poly::load_and_swap<uint8_t>(base + p);
sub_type = poly::load_and_swap<uint8_t>(base + p + 1);
flags = poly::load_and_swap<uint16_t>(base + p + 2);
gamepad.Read(base, p + 4);
vibration.Read(base, p + 4 + 12);
}
void Write(uint8_t* base, uint32_t p) {
poly::store_and_swap<uint8_t>(base + p, type);
poly::store_and_swap<uint8_t>(base + p + 1, sub_type);
poly::store_and_swap<uint16_t>(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();
}
}; };
static_assert_size(X_INPUT_CAPABILITIES,
sizeof(X_INPUT_GAMEPAD) + sizeof(X_INPUT_VIBRATION) + 4);
// http://msdn.microsoft.com/en-us/library/windows/desktop/microsoft.directx_sdk.reference.xinput_keystroke(v=vs.85).aspx // http://msdn.microsoft.com/en-us/library/windows/desktop/microsoft.directx_sdk.reference.xinput_keystroke(v=vs.85).aspx
class X_INPUT_KEYSTROKE { struct X_INPUT_KEYSTROKE {
public: be<uint16_t> virtual_key;
uint16_t virtual_key; be<uint16_t> unicode;
uint16_t unicode; be<uint16_t> flags;
uint16_t flags; be<uint8_t> user_index;
uint8_t user_index; be<uint8_t> hid_code;
uint8_t hid_code;
X_INPUT_KEYSTROKE() {
Zero();
}
X_INPUT_KEYSTROKE(const uint8_t* base, uint32_t p) {
Read(base, p);
}
void Read(const uint8_t* base, uint32_t p) {
virtual_key = poly::load_and_swap<uint16_t>(base + p + 0);
unicode = poly::load_and_swap<uint16_t>(base + p + 2);
flags = poly::load_and_swap<uint16_t>(base + p + 4);
user_index = poly::load_and_swap<uint8_t>(base + p + 6);
hid_code = poly::load_and_swap<uint8_t>(base + p + 7);
}
void Write(uint8_t* base, uint32_t p) {
poly::store_and_swap<uint16_t>(base + p + 0, virtual_key);
poly::store_and_swap<uint16_t>(base + p + 2, unicode);
poly::store_and_swap<uint16_t>(base + p + 4, flags);
poly::store_and_swap<uint8_t>(base + p + 6, user_index);
poly::store_and_swap<uint8_t>(base + p + 7, hid_code);
}
void Zero() {
virtual_key = 0;
unicode = 0;
flags = 0;
user_index = 0;
hid_code = 0;
}
}; };
static_assert_size(X_INPUT_KEYSTROKE, 8);
#pragma pack(pop) #pragma pack(pop)
} // namespace xe } // namespace xe
#endif // XENIA_XBOX_H_ #endif // XENIA_XBOX_H_