XInputGetKeystroke/Ex.
This commit is contained in:
parent
4d92720109
commit
9b02cfb560
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
}
|
|
@ -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_;
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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:
|
||||
};
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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:
|
||||
};
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue