From 450f3e8025be6e1e9c6a907337d44045dcbe6ef3 Mon Sep 17 00:00:00 2001 From: Paul Gofman Date: Fri, 9 Jul 2021 15:15:04 +0300 Subject: [PATCH] vrclient: HACK: Fixup digital action 'bChange' parameter on 32 bit. CW-Bug-Id: 19067 --- vrclient_x64/gen_wrapper.py | 6 ++ vrclient_x64/vrclient_x64/vrclient_main.c | 104 +++++++++++++++++++ vrclient_x64/vrclient_x64/vrclient_private.h | 5 + vrclient_x64/vrclient_x64/winIVRInput.c | 10 +- 4 files changed, 120 insertions(+), 5 deletions(-) diff --git a/vrclient_x64/gen_wrapper.py b/vrclient_x64/gen_wrapper.py index c97935f9..ace0ce2b 100755 --- a/vrclient_x64/gen_wrapper.py +++ b/vrclient_x64/gen_wrapper.py @@ -385,6 +385,11 @@ def ivroverlay_set_overlay_texture(cppname, method): "025" in cppname return "ivroverlay_set_overlay_texture" +def ivrinput_get_digital_action_data(cppname, method): + if "003" in cppname: + return None + return "ivrinput_get_digital_action_data" + method_overrides = [ ("IVRClientCore", "BIsHmdPresent", ivrclientcore_is_hmd_present), ("IVRClientCore", "Init", ivrclientcore_init), @@ -402,6 +407,7 @@ method_overrides = [ ("IVRRenderModels", "LoadIntoTextureD3D11_Async", ivrrendermodels_load_into_texture_d3d11_async), ("IVRMailbox", "undoc3", ivrmailbox_undoc3), ("IVROverlay", "SetOverlayTexture", ivroverlay_set_overlay_texture), + ("IVRInput", "GetDigitalActionData", ivrinput_get_digital_action_data), ] method_overrides_data = [ diff --git a/vrclient_x64/vrclient_x64/vrclient_main.c b/vrclient_x64/vrclient_x64/vrclient_main.c index 7c4b36d7..9a789fa7 100644 --- a/vrclient_x64/vrclient_x64/vrclient_main.c +++ b/vrclient_x64/vrclient_x64/vrclient_main.c @@ -59,6 +59,20 @@ static struct #endif BOOL d3d11_explicit_handoff, handoff_called; void *client_core_linux_side; + +#ifndef __x86_64__ +/* Digital action state change fixup hack. */ + struct + { + VRActionHandle_t action; + VRInputValueHandle_t origin; + LARGE_INTEGER update_qpf_time; + BOOL previous_state; + } + digital_actions_state[128]; + unsigned int digital_action_count; + LARGE_INTEGER qpf_freq; +#endif } compositor_data; @@ -1721,3 +1735,93 @@ vrmb_typeb ivrmailbox_undoc3( return r; } + +#pragma pack(push, 8) +struct winInputDigitalActionData_t { + bool bActive; + VRInputValueHandle_t activeOrigin; + bool bState; + bool bChanged; + float fUpdateTime; +} __attribute__ ((ms_struct)); +#pragma pack(pop) + +EVRInputError ivrinput_get_digital_action_data( + void *func, + void *linux_side, VRActionHandle_t action_handle, void *action_data, uint32_t action_data_size, + VRInputValueHandle_t restrict_to_device, unsigned int version) +{ + EVRInputError (*cpp_func)(void *, VRActionHandle_t, struct winInputDigitalActionData_t *, uint32_t, VRInputValueHandle_t) = func; + +#ifdef __x86_64__ + return cpp_func(linux_side, action_handle, action_data, action_data_size, restrict_to_device); +#else + /* Digital action state change fixup hack. */ + struct winInputDigitalActionData_t *data = action_data; + LARGE_INTEGER qpf; + EVRInputError ret; + unsigned int i; + + ret = cpp_func(linux_side, action_handle, action_data, action_data_size, restrict_to_device); + + TRACE("handle %s, data %p, data_size %u, restrict %s, origin %s, state %#x, changed %#x, ret %u, active %#x.\n", + wine_dbgstr_longlong(action_handle), action_data, action_data_size, + wine_dbgstr_longlong(restrict_to_device), wine_dbgstr_longlong(data->activeOrigin), + data->bState, data->bChanged, ret, data->bActive); + + if (ret) + return ret; + + if (action_data_size != sizeof(*data)) + { + WARN("Unexpected action_data_size %u.\n", action_data_size); + return 0; + } + + if (!data->bActive) + return 0; + + if (!compositor_data.qpf_freq.QuadPart) + QueryPerformanceFrequency(&compositor_data.qpf_freq); + QueryPerformanceCounter(&qpf); + + for (i = 0; i < compositor_data.digital_action_count; ++i) + { + if (compositor_data.digital_actions_state[i].action == action_handle + && compositor_data.digital_actions_state[i].origin == data->activeOrigin) + { + if ((data->bChanged = (!compositor_data.digital_actions_state[i].previous_state != !data->bState))) + { + TRACE("action %s (%s) changed to %#x, data->fUpdateTime %f.\n", wine_dbgstr_longlong(action_handle), + wine_dbgstr_longlong(restrict_to_device), data->bState, data->fUpdateTime); + + compositor_data.digital_actions_state[i].update_qpf_time = qpf; + compositor_data.digital_actions_state[i].previous_state = data->bState; + } + if (compositor_data.digital_actions_state[i].update_qpf_time.QuadPart) + data->fUpdateTime = -(float)(qpf.QuadPart + - compositor_data.digital_actions_state[i].update_qpf_time.QuadPart) + / compositor_data.qpf_freq.QuadPart; + + return 0; + } + } + + if (i == ARRAY_SIZE(compositor_data.digital_actions_state)) + { + static unsigned int once; + if (!once++) + WARN("Too many actions.\n"); + + return 0; + } + + compositor_data.digital_actions_state[i].action = action_handle; + compositor_data.digital_actions_state[i].origin = data->activeOrigin; + compositor_data.digital_actions_state[i].previous_state = data->bState; + compositor_data.digital_actions_state[i].update_qpf_time = qpf; + ++compositor_data.digital_action_count; + + return 0; +#endif +} diff --git a/vrclient_x64/vrclient_x64/vrclient_private.h b/vrclient_x64/vrclient_x64/vrclient_private.h index 53e44c03..0874e84f 100644 --- a/vrclient_x64/vrclient_x64/vrclient_private.h +++ b/vrclient_x64/vrclient_x64/vrclient_private.h @@ -172,6 +172,11 @@ EVROverlayError ivroverlay_001_set_overlay_texture( void *linux_side, VROverlayHandle_t overlayHandle, void *texture, unsigned int version); +EVRInputError ivrinput_get_digital_action_data( + void *func, + void *linux_side, VRActionHandle_t action_handle, void *action_data, uint32_t action_data_size, + VRInputValueHandle_t restrict_to_device, unsigned int version); + #endif /* __cplusplus */ #define TRACE WINE_TRACE diff --git a/vrclient_x64/vrclient_x64/winIVRInput.c b/vrclient_x64/vrclient_x64/winIVRInput.c index f21eced0..2a95b5f2 100644 --- a/vrclient_x64/vrclient_x64/winIVRInput.c +++ b/vrclient_x64/vrclient_x64/winIVRInput.c @@ -66,7 +66,7 @@ DEFINE_THISCALL_WRAPPER(winIVRInput_IVRInput_010_GetDigitalActionData, 28) EVRInputError __thiscall winIVRInput_IVRInput_010_GetDigitalActionData(winIVRInput_IVRInput_010 *_this, VRActionHandle_t action, winInputDigitalActionData_t_1168 * pActionData, uint32_t unActionDataSize, VRInputValueHandle_t ulRestrictToDevice) { TRACE("%p\n", _this); - return cppIVRInput_IVRInput_010_GetDigitalActionData(_this->linux_side, action, pActionData, unActionDataSize, ulRestrictToDevice); + return ivrinput_get_digital_action_data(cppIVRInput_IVRInput_010_GetDigitalActionData, _this->linux_side, action, pActionData, unActionDataSize, ulRestrictToDevice, 10); } DEFINE_THISCALL_WRAPPER(winIVRInput_IVRInput_010_GetAnalogActionData, 28) @@ -413,7 +413,7 @@ DEFINE_THISCALL_WRAPPER(winIVRInput_IVRInput_007_GetDigitalActionData, 28) EVRInputError __thiscall winIVRInput_IVRInput_007_GetDigitalActionData(winIVRInput_IVRInput_007 *_this, VRActionHandle_t action, winInputDigitalActionData_t_1916 * pActionData, uint32_t unActionDataSize, VRInputValueHandle_t ulRestrictToDevice) { TRACE("%p\n", _this); - return cppIVRInput_IVRInput_007_GetDigitalActionData(_this->linux_side, action, pActionData, unActionDataSize, ulRestrictToDevice); + return ivrinput_get_digital_action_data(cppIVRInput_IVRInput_007_GetDigitalActionData, _this->linux_side, action, pActionData, unActionDataSize, ulRestrictToDevice, 7); } DEFINE_THISCALL_WRAPPER(winIVRInput_IVRInput_007_GetAnalogActionData, 28) @@ -724,7 +724,7 @@ DEFINE_THISCALL_WRAPPER(winIVRInput_IVRInput_006_GetDigitalActionData, 28) EVRInputError __thiscall winIVRInput_IVRInput_006_GetDigitalActionData(winIVRInput_IVRInput_006 *_this, VRActionHandle_t action, winInputDigitalActionData_t_1418 * pActionData, uint32_t unActionDataSize, VRInputValueHandle_t ulRestrictToDevice) { TRACE("%p\n", _this); - return cppIVRInput_IVRInput_006_GetDigitalActionData(_this->linux_side, action, pActionData, unActionDataSize, ulRestrictToDevice); + return ivrinput_get_digital_action_data(cppIVRInput_IVRInput_006_GetDigitalActionData, _this->linux_side, action, pActionData, unActionDataSize, ulRestrictToDevice, 6); } DEFINE_THISCALL_WRAPPER(winIVRInput_IVRInput_006_GetAnalogActionData, 28) @@ -1017,7 +1017,7 @@ DEFINE_THISCALL_WRAPPER(winIVRInput_IVRInput_005_GetDigitalActionData, 28) EVRInputError __thiscall winIVRInput_IVRInput_005_GetDigitalActionData(winIVRInput_IVRInput_005 *_this, VRActionHandle_t action, winInputDigitalActionData_t_1322 * pActionData, uint32_t unActionDataSize, VRInputValueHandle_t ulRestrictToDevice) { TRACE("%p\n", _this); - return cppIVRInput_IVRInput_005_GetDigitalActionData(_this->linux_side, action, pActionData, unActionDataSize, ulRestrictToDevice); + return ivrinput_get_digital_action_data(cppIVRInput_IVRInput_005_GetDigitalActionData, _this->linux_side, action, pActionData, unActionDataSize, ulRestrictToDevice, 5); } DEFINE_THISCALL_WRAPPER(winIVRInput_IVRInput_005_GetAnalogActionData, 28) @@ -1301,7 +1301,7 @@ DEFINE_THISCALL_WRAPPER(winIVRInput_IVRInput_004_GetDigitalActionData, 28) EVRInputError __thiscall winIVRInput_IVRInput_004_GetDigitalActionData(winIVRInput_IVRInput_004 *_this, VRActionHandle_t action, winInputDigitalActionData_t_1017 * pActionData, uint32_t unActionDataSize, VRInputValueHandle_t ulRestrictToDevice) { TRACE("%p\n", _this); - return cppIVRInput_IVRInput_004_GetDigitalActionData(_this->linux_side, action, pActionData, unActionDataSize, ulRestrictToDevice); + return ivrinput_get_digital_action_data(cppIVRInput_IVRInput_004_GetDigitalActionData, _this->linux_side, action, pActionData, unActionDataSize, ulRestrictToDevice, 4); } DEFINE_THISCALL_WRAPPER(winIVRInput_IVRInput_004_GetAnalogActionData, 28)