XInputGetKeystroke/Ex.

This commit is contained in:
Ben Vanik 2014-01-04 22:38:56 -08:00
parent 4d92720109
commit 9b02cfb560
9 changed files with 153 additions and 7 deletions

View File

@ -32,6 +32,9 @@ public:
uint32_t user_index, X_INPUT_STATE& out_state) = 0;
virtual X_RESULT SetState(
uint32_t user_index, X_INPUT_VIBRATION& vibration) = 0;
virtual X_RESULT GetKeystroke(
uint32_t user_index, uint32_t flags,
X_INPUT_KEYSTROKE& out_keystroke) = 0;
protected:
InputDriver(InputSystem* input_system);

View File

@ -23,7 +23,7 @@ InputSystem::InputSystem(Emulator* emulator) :
}
InputSystem::~InputSystem() {
for (std::vector<InputDriver*>::iterator it = drivers_.begin();
for (auto it = drivers_.begin();
it != drivers_.end(); ++it) {
InputDriver* driver = *it;
delete driver;
@ -42,8 +42,7 @@ void InputSystem::AddDriver(InputDriver* driver) {
X_RESULT InputSystem::GetCapabilities(
uint32_t user_index, uint32_t flags, X_INPUT_CAPABILITIES& out_caps) {
for (std::vector<InputDriver*>::iterator it = drivers_.begin();
it != drivers_.end(); ++it) {
for (auto it = drivers_.begin(); it != drivers_.end(); ++it) {
InputDriver* driver = *it;
if (XSUCCEEDED(driver->GetCapabilities(user_index, flags, out_caps))) {
return X_ERROR_SUCCESS;
@ -53,8 +52,7 @@ X_RESULT InputSystem::GetCapabilities(
}
X_RESULT InputSystem::GetState(uint32_t user_index, X_INPUT_STATE& out_state) {
for (std::vector<InputDriver*>::iterator it = drivers_.begin();
it != drivers_.end(); ++it) {
for (auto it = drivers_.begin(); it != drivers_.end(); ++it) {
InputDriver* driver = *it;
if (driver->GetState(user_index, out_state) == X_ERROR_SUCCESS) {
return X_ERROR_SUCCESS;
@ -65,8 +63,7 @@ X_RESULT InputSystem::GetState(uint32_t user_index, X_INPUT_STATE& out_state) {
X_RESULT InputSystem::SetState(
uint32_t user_index, X_INPUT_VIBRATION& vibration) {
for (std::vector<InputDriver*>::iterator it = drivers_.begin();
it != drivers_.end(); ++it) {
for (auto it = drivers_.begin(); it != drivers_.end(); ++it) {
InputDriver* driver = *it;
if (XSUCCEEDED(driver->SetState(user_index, vibration))) {
return X_ERROR_SUCCESS;
@ -74,3 +71,14 @@ X_RESULT InputSystem::SetState(
}
return X_ERROR_DEVICE_NOT_CONNECTED;
}
X_RESULT InputSystem::GetKeystroke(
uint32_t user_index, uint32_t flags, X_INPUT_KEYSTROKE& out_keystroke) {
for (auto it = drivers_.begin(); it != drivers_.end(); ++it) {
InputDriver* driver = *it;
if (XSUCCEEDED(driver->GetKeystroke(user_index, flags, out_keystroke))) {
return X_ERROR_SUCCESS;
}
}
return X_ERROR_DEVICE_NOT_CONNECTED;
}

View File

@ -41,6 +41,8 @@ public:
uint32_t user_index, uint32_t flags, X_INPUT_CAPABILITIES& out_caps);
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 GetKeystroke(uint32_t user_index, uint32_t flags,
X_INPUT_KEYSTROKE& out_keystroke);
private:
Emulator* emulator_;

View File

@ -45,3 +45,8 @@ X_RESULT NopInputDriver::SetState(
uint32_t user_index, X_INPUT_VIBRATION& vibration) {
return X_ERROR_DEVICE_NOT_CONNECTED;
}
X_RESULT NopInputDriver::GetKeystroke(
uint32_t user_index, uint32_t flags, X_INPUT_KEYSTROKE& out_keystroke) {
return X_ERROR_DEVICE_NOT_CONNECTED;
}

View File

@ -34,6 +34,8 @@ public:
uint32_t user_index, X_INPUT_STATE& out_state);
virtual X_RESULT SetState(
uint32_t user_index, X_INPUT_VIBRATION& vibration);
virtual X_RESULT GetKeystroke(
uint32_t user_index, uint32_t flags, X_INPUT_KEYSTROKE& out_keystroke);
protected:
};

View File

@ -86,3 +86,22 @@ X_RESULT XInputInputDriver::SetState(
DWORD result = XInputSetState(user_index, &native_vibration);
return result;
}
X_RESULT XInputInputDriver::GetKeystroke(
uint32_t user_index, uint32_t flags, X_INPUT_KEYSTROKE& out_keystroke) {
// We may want to filter flags/user_index before sending to native.
// flags is reserved on desktop.
XINPUT_KEYSTROKE native_keystroke;
DWORD result = XInputGetKeystroke(user_index, flags, &native_keystroke);
if (result == ERROR_SUCCESS) {
out_keystroke.virtual_key = native_keystroke.VirtualKey;
out_keystroke.unicode = native_keystroke.Unicode;
out_keystroke.flags = native_keystroke.Flags;
out_keystroke.user_index = native_keystroke.UserIndex;
out_keystroke.hid_code = native_keystroke.HidCode;
}
// X_ERROR_EMPTY if no new keys
// X_ERROR_DEVICE_NOT_CONNECTED if no device
// X_ERROR_SUCCESS if key
return result;
}

View File

@ -34,6 +34,8 @@ public:
uint32_t user_index, X_INPUT_STATE& out_state);
virtual X_RESULT SetState(
uint32_t user_index, X_INPUT_VIBRATION& vibration);
virtual X_RESULT GetKeystroke(
uint32_t user_index, uint32_t flags, X_INPUT_KEYSTROKE& out_keystroke);
protected:
};

View File

@ -106,6 +106,71 @@ SHIM_CALL XamInputSetState_shim(
}
// http://msdn.microsoft.com/en-us/library/windows/desktop/microsoft.directx_sdk.reference.xinputgetkeystroke(v=vs.85).aspx
SHIM_CALL XamInputGetKeystroke_shim(
PPCContext* ppc_state, KernelState* state) {
uint32_t user_index = SHIM_GET_ARG_32(0);
uint32_t flags = SHIM_GET_ARG_32(1);
uint32_t keystroke_ptr = SHIM_GET_ARG_32(2);
// http://ffplay360.googlecode.com/svn/Test/Common/AtgXime.cpp
// user index = index or XUSER_INDEX_ANY
// flags = XINPUT_FLAG_GAMEPAD (| _ANYUSER | _ANYDEVICE)
XELOGD(
"XamInputGetKeystroke(%d, %.8X, %.8X)",
user_index,
flags,
keystroke_ptr);
if (!keystroke_ptr) {
SHIM_SET_RETURN(X_ERROR_BAD_ARGUMENTS);
return;
}
InputSystem* input_system = state->emulator()->input_system();
X_INPUT_KEYSTROKE keystroke;
X_RESULT result = input_system->GetKeystroke(user_index, flags, keystroke);
if (XSUCCEEDED(result)) {
keystroke.Write(SHIM_MEM_BASE, keystroke_ptr);
}
SHIM_SET_RETURN(result);
}
// Same as non-ex, just takes a pointer to user index.
SHIM_CALL XamInputGetKeystrokeEx_shim(
PPCContext* ppc_state, KernelState* state) {
uint32_t user_index_ptr = SHIM_GET_ARG_32(0);
uint32_t flags = SHIM_GET_ARG_32(1);
uint32_t keystroke_ptr = SHIM_GET_ARG_32(2);
uint32_t user_index = SHIM_MEM_32(user_index_ptr);
XELOGD(
"XamInputGetKeystroke(%.8X(%.d), %.8X, %.8X)",
user_index_ptr, user_index,
flags,
keystroke_ptr);
if (!keystroke_ptr) {
SHIM_SET_RETURN(X_ERROR_BAD_ARGUMENTS);
return;
}
InputSystem* input_system = state->emulator()->input_system();
X_INPUT_KEYSTROKE keystroke;
X_RESULT result = input_system->GetKeystroke(user_index, flags, keystroke);
if (XSUCCEEDED(result)) {
SHIM_SET_MEM_32(user_index_ptr, keystroke.user_index);
keystroke.Write(SHIM_MEM_BASE, keystroke_ptr);
}
SHIM_SET_RETURN(result);
}
} // namespace kernel
} // namespace xe
@ -115,4 +180,6 @@ void xe::kernel::xam::RegisterInputExports(
SHIM_SET_MAPPING("xam.xex", XamInputGetCapabilities, state);
SHIM_SET_MAPPING("xam.xex", XamInputGetState, state);
SHIM_SET_MAPPING("xam.xex", XamInputSetState, state);
SHIM_SET_MAPPING("xam.xex", XamInputGetKeystroke, state);
SHIM_SET_MAPPING("xam.xex", XamInputGetKeystrokeEx, state);
}

View File

@ -59,6 +59,7 @@ typedef uint32_t X_RESULT;
#define X_ERROR_BUSY ((uint32_t)0x800700AAL)
#define X_ERROR_DEVICE_NOT_CONNECTED ((uint32_t)0x8007048FL)
#define X_ERROR_CANCELLED ((uint32_t)0x800704C7L)
#define X_ERROR_EMPTY ((uint32_t)0x000010D2L)
// MEM_*, used by NtAllocateVirtualMemory
#define X_MEM_COMMIT 0x00001000
@ -396,6 +397,43 @@ public:
vibration.Zero();
}
};
// http://msdn.microsoft.com/en-us/library/windows/desktop/microsoft.directx_sdk.reference.xinput_keystroke(v=vs.85).aspx
class X_INPUT_KEYSTROKE {
public:
uint16_t virtual_key;
uint16_t unicode;
uint16_t flags;
uint8_t user_index;
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 = XEGETUINT16BE(base + p + 0);
unicode = XEGETUINT16BE(base + p + 2);
flags = XEGETUINT16BE(base + p + 4);
user_index = XEGETUINT8BE(base + p + 6);
hid_code = XEGETUINT8BE(base + p + 7);
}
void Write(uint8_t* base, uint32_t p) {
XESETUINT16BE(base + p + 0, virtual_key);
XESETUINT16BE(base + p + 2, unicode);
XESETUINT16BE(base + p + 4, flags);
XESETUINT8BE(base + p + 6, user_index);
XESETUINT8BE(base + p + 7, hid_code);
}
void Zero() {
virtual_key = 0;
unicode = 0;
flags = 0;
user_index = 0;
hid_code = 0;
}
};
} // namespace xe