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;
|
uint32_t user_index, X_INPUT_STATE& out_state) = 0;
|
||||||
virtual X_RESULT SetState(
|
virtual X_RESULT SetState(
|
||||||
uint32_t user_index, 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,
|
||||||
|
X_INPUT_KEYSTROKE& out_keystroke) = 0;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
InputDriver(InputSystem* input_system);
|
InputDriver(InputSystem* input_system);
|
||||||
|
|
|
@ -23,7 +23,7 @@ InputSystem::InputSystem(Emulator* emulator) :
|
||||||
}
|
}
|
||||||
|
|
||||||
InputSystem::~InputSystem() {
|
InputSystem::~InputSystem() {
|
||||||
for (std::vector<InputDriver*>::iterator 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;
|
||||||
|
@ -42,8 +42,7 @@ void InputSystem::AddDriver(InputDriver* driver) {
|
||||||
|
|
||||||
X_RESULT InputSystem::GetCapabilities(
|
X_RESULT InputSystem::GetCapabilities(
|
||||||
uint32_t user_index, uint32_t flags, X_INPUT_CAPABILITIES& out_caps) {
|
uint32_t user_index, uint32_t flags, X_INPUT_CAPABILITIES& out_caps) {
|
||||||
for (std::vector<InputDriver*>::iterator it = drivers_.begin();
|
for (auto it = drivers_.begin(); it != drivers_.end(); ++it) {
|
||||||
it != drivers_.end(); ++it) {
|
|
||||||
InputDriver* driver = *it;
|
InputDriver* driver = *it;
|
||||||
if (XSUCCEEDED(driver->GetCapabilities(user_index, flags, out_caps))) {
|
if (XSUCCEEDED(driver->GetCapabilities(user_index, flags, out_caps))) {
|
||||||
return X_ERROR_SUCCESS;
|
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) {
|
X_RESULT InputSystem::GetState(uint32_t user_index, X_INPUT_STATE& out_state) {
|
||||||
for (std::vector<InputDriver*>::iterator it = drivers_.begin();
|
for (auto it = drivers_.begin(); it != drivers_.end(); ++it) {
|
||||||
it != drivers_.end(); ++it) {
|
|
||||||
InputDriver* driver = *it;
|
InputDriver* driver = *it;
|
||||||
if (driver->GetState(user_index, out_state) == X_ERROR_SUCCESS) {
|
if (driver->GetState(user_index, out_state) == X_ERROR_SUCCESS) {
|
||||||
return 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(
|
X_RESULT InputSystem::SetState(
|
||||||
uint32_t user_index, X_INPUT_VIBRATION& vibration) {
|
uint32_t user_index, X_INPUT_VIBRATION& vibration) {
|
||||||
for (std::vector<InputDriver*>::iterator it = drivers_.begin();
|
for (auto it = drivers_.begin(); it != drivers_.end(); ++it) {
|
||||||
it != drivers_.end(); ++it) {
|
|
||||||
InputDriver* driver = *it;
|
InputDriver* driver = *it;
|
||||||
if (XSUCCEEDED(driver->SetState(user_index, vibration))) {
|
if (XSUCCEEDED(driver->SetState(user_index, vibration))) {
|
||||||
return X_ERROR_SUCCESS;
|
return X_ERROR_SUCCESS;
|
||||||
|
@ -74,3 +71,14 @@ X_RESULT InputSystem::SetState(
|
||||||
}
|
}
|
||||||
return X_ERROR_DEVICE_NOT_CONNECTED;
|
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);
|
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 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_INPUT_KEYSTROKE& out_keystroke);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Emulator* emulator_;
|
Emulator* emulator_;
|
||||||
|
|
|
@ -45,3 +45,8 @@ X_RESULT NopInputDriver::SetState(
|
||||||
uint32_t user_index, X_INPUT_VIBRATION& vibration) {
|
uint32_t user_index, X_INPUT_VIBRATION& vibration) {
|
||||||
return X_ERROR_DEVICE_NOT_CONNECTED;
|
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);
|
uint32_t user_index, X_INPUT_STATE& out_state);
|
||||||
virtual X_RESULT SetState(
|
virtual X_RESULT SetState(
|
||||||
uint32_t user_index, X_INPUT_VIBRATION& vibration);
|
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:
|
protected:
|
||||||
};
|
};
|
||||||
|
|
|
@ -86,3 +86,22 @@ X_RESULT XInputInputDriver::SetState(
|
||||||
DWORD result = XInputSetState(user_index, &native_vibration);
|
DWORD result = XInputSetState(user_index, &native_vibration);
|
||||||
return result;
|
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);
|
uint32_t user_index, X_INPUT_STATE& out_state);
|
||||||
virtual X_RESULT SetState(
|
virtual X_RESULT SetState(
|
||||||
uint32_t user_index, X_INPUT_VIBRATION& vibration);
|
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:
|
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 kernel
|
||||||
} // namespace xe
|
} // namespace xe
|
||||||
|
|
||||||
|
@ -115,4 +180,6 @@ void xe::kernel::xam::RegisterInputExports(
|
||||||
SHIM_SET_MAPPING("xam.xex", XamInputGetCapabilities, state);
|
SHIM_SET_MAPPING("xam.xex", XamInputGetCapabilities, state);
|
||||||
SHIM_SET_MAPPING("xam.xex", XamInputGetState, state);
|
SHIM_SET_MAPPING("xam.xex", XamInputGetState, state);
|
||||||
SHIM_SET_MAPPING("xam.xex", XamInputSetState, 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_BUSY ((uint32_t)0x800700AAL)
|
||||||
#define X_ERROR_DEVICE_NOT_CONNECTED ((uint32_t)0x8007048FL)
|
#define X_ERROR_DEVICE_NOT_CONNECTED ((uint32_t)0x8007048FL)
|
||||||
#define X_ERROR_CANCELLED ((uint32_t)0x800704C7L)
|
#define X_ERROR_CANCELLED ((uint32_t)0x800704C7L)
|
||||||
|
#define X_ERROR_EMPTY ((uint32_t)0x000010D2L)
|
||||||
|
|
||||||
// MEM_*, used by NtAllocateVirtualMemory
|
// MEM_*, used by NtAllocateVirtualMemory
|
||||||
#define X_MEM_COMMIT 0x00001000
|
#define X_MEM_COMMIT 0x00001000
|
||||||
|
@ -396,6 +397,43 @@ public:
|
||||||
vibration.Zero();
|
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
|
} // namespace xe
|
||||||
|
|
Loading…
Reference in New Issue