Signed-off-by: Brendan Shanks bshanks@codeweavers.com --- v4: Only block Acquire(), blocking Unacquire() was causing a deadlock.
dlls/dinput/dinput_main.c | 19 ++++++++++++++++--- dlls/dinput8/tests/device.c | 3 --- 2 files changed, 16 insertions(+), 6 deletions(-)
diff --git a/dlls/dinput/dinput_main.c b/dlls/dinput/dinput_main.c index 0855cb41cd..5eaa32bd0b 100644 --- a/dlls/dinput/dinput_main.c +++ b/dlls/dinput/dinput_main.c @@ -1717,10 +1717,11 @@ static DWORD WINAPI hook_thread_proc(void *param) if (msg.message == WM_USER+0x10) { IDirectInputImpl *dinput; + HANDLE finished_event = (HANDLE)msg.lParam;
- TRACE( "Processing hook change notification lp:%ld\n", msg.lParam ); + TRACE( "Processing hook change notification wp:%ld lp:%#lx\n", msg.wParam, msg.lParam );
- if (!msg.wParam && !msg.lParam) + if (!msg.wParam) { if (kbd_hook) UnhookWindowsHookEx( kbd_hook ); if (mouse_hook) UnhookWindowsHookEx( mouse_hook ); @@ -1765,6 +1766,9 @@ static DWORD WINAPI hook_thread_proc(void *param) UnhookWindowsHookEx( mouse_hook ); mouse_hook = NULL; } + + if (finished_event) + SetEvent(finished_event); } TranslateMessage(&msg); DispatchMessageW(&msg); @@ -1824,6 +1828,7 @@ void check_dinput_hooks(LPDIRECTINPUTDEVICE8W iface, BOOL acquired) static HHOOK callwndproc_hook; static ULONG foreground_cnt; IDirectInputDeviceImpl *dev = impl_from_IDirectInputDevice8W(iface); + HANDLE hook_change_finished_event = NULL;
EnterCriticalSection(&dinput_hook_crit);
@@ -1851,9 +1856,17 @@ void check_dinput_hooks(LPDIRECTINPUTDEVICE8W iface, BOOL acquired) hook_thread_event = NULL; }
- PostThreadMessageW( hook_thread_id, WM_USER+0x10, 1, 0 ); + if (acquired) + hook_change_finished_event = CreateEventW( NULL, FALSE, FALSE, NULL ); + PostThreadMessageW( hook_thread_id, WM_USER+0x10, 1, (LPARAM)hook_change_finished_event );
LeaveCriticalSection(&dinput_hook_crit); + + if (acquired) + { + WaitForSingleObject(hook_change_finished_event, INFINITE); + CloseHandle(hook_change_finished_event); + } }
void check_dinput_events(void) diff --git a/dlls/dinput8/tests/device.c b/dlls/dinput8/tests/device.c index ea5ab75109..bb82855d40 100644 --- a/dlls/dinput8/tests/device.c +++ b/dlls/dinput8/tests/device.c @@ -798,12 +798,10 @@ static void test_keyboard_events(void) data_size = ARRAY_SIZE(obj_data); hr = IDirectInputDevice8_GetDeviceData(di_keyboard, sizeof(DIDEVICEOBJECTDATA), obj_data, &data_size, 0); ok(SUCCEEDED(hr), "Failed to get data hr=%08x\n", hr); - todo_wine ok(data_size == 1, "Expected 1 element, received %d\n", data_size);
hr = IDirectInputDevice8_GetDeviceState(di_keyboard, sizeof(kbdata), kbdata); ok(SUCCEEDED(hr), "IDirectInputDevice8_GetDeviceState failed: %08x\n", hr); - todo_wine ok(kbdata[DIK_SPACE], "Expected DIK_SPACE key state down\n");
keybd_event(VK_SPACE, DIK_SPACE, KEYEVENTF_KEYUP, 0); @@ -812,7 +810,6 @@ static void test_keyboard_events(void) data_size = ARRAY_SIZE(obj_data); hr = IDirectInputDevice8_GetDeviceData(di_keyboard, sizeof(DIDEVICEOBJECTDATA), obj_data, &data_size, 0); ok(SUCCEEDED(hr), "Failed to get data hr=%08x\n", hr); - todo_wine ok(data_size == 1, "Expected 1 element, received %d\n", data_size);
/* Test injecting keyboard events with scancode=0.
Grand Theft Auto IV injects VK_F8 and scancode=0, and expects DirectInput not to report that F8 is pressed.
Signed-off-by: Brendan Shanks bshanks@codeweavers.com --- v4: Only make this behavior change for DirectInput 8. It's difficult to show because of the separation of 8 and pre-8 tests, but really does seem to depend only on the DI version used.
dlls/dinput/keyboard.c | 8 ++++---- dlls/dinput8/tests/device.c | 2 -- 2 files changed, 4 insertions(+), 6 deletions(-)
diff --git a/dlls/dinput/keyboard.c b/dlls/dinput/keyboard.c index 47f28cac52..f842f1ca42 100644 --- a/dlls/dinput/keyboard.c +++ b/dlls/dinput/keyboard.c @@ -68,9 +68,9 @@ static inline IDirectInputDevice8W *IDirectInputDevice8W_from_impl(SysKeyboardIm return &This->base.IDirectInputDevice8W_iface; }
-static BYTE map_dik_code(DWORD scanCode, DWORD vkCode, DWORD subType) +static BYTE map_dik_code(DWORD scanCode, DWORD vkCode, DWORD subType, DWORD version) { - if (!scanCode) + if (!scanCode && version < 0x0800) scanCode = MapVirtualKeyW(vkCode, MAPVK_VK_TO_VSC);
if (subType == DIDEVTYPEKEYBOARD_JAPAN106) @@ -125,7 +125,7 @@ static int KeyboardCallback( LPDIRECTINPUTDEVICE8A iface, WPARAM wparam, LPARAM case VK_NUMLOCK : dik_code = DIK_NUMLOCK; break; case VK_SUBTRACT: dik_code = DIK_SUBTRACT; break; default: - dik_code = map_dik_code(hook->scanCode & 0xff, hook->vkCode, This->subtype); + dik_code = map_dik_code(hook->scanCode & 0xff, hook->vkCode, This->subtype, This->base.dinput->dwVersion); if (hook->flags & LLKHF_EXTENDED) dik_code |= 0x80; } new_diks = hook->flags & LLKHF_UP ? 0 : 0x80; @@ -282,7 +282,7 @@ static SysKeyboardImpl *alloc_device(REFGUID rguid, IDirectInputImpl *dinput) if (!GetKeyNameTextA(((i & 0x7f) << 16) | ((i & 0x80) << 17), buf, sizeof(buf))) continue;
- dik_code = map_dik_code(i, 0, newDevice->subtype); + dik_code = map_dik_code(i, 0, newDevice->subtype, dinput->dwVersion); memcpy(&df->rgodf[idx], &c_dfDIKeyboard.rgodf[dik_code], df->dwObjSize); df->rgodf[idx++].dwType = DIDFT_MAKEINSTANCE(dik_code) | DIDFT_PSHBUTTON; } diff --git a/dlls/dinput8/tests/device.c b/dlls/dinput8/tests/device.c index bb82855d40..39c635f2fb 100644 --- a/dlls/dinput8/tests/device.c +++ b/dlls/dinput8/tests/device.c @@ -820,7 +820,6 @@ static void test_keyboard_events(void) data_size = ARRAY_SIZE(obj_data); hr = IDirectInputDevice8_GetDeviceData(di_keyboard, sizeof(DIDEVICEOBJECTDATA), obj_data, &data_size, 0); ok(SUCCEEDED(hr), "Failed to get data hr=%08x\n", hr); - todo_wine ok(data_size == 0, "Expected 0 elements, received %d\n", data_size);
hr = IDirectInputDevice8_GetDeviceState(di_keyboard, sizeof(kbdata), kbdata); @@ -834,7 +833,6 @@ static void test_keyboard_events(void) data_size = ARRAY_SIZE(obj_data); hr = IDirectInputDevice8_GetDeviceData(di_keyboard, sizeof(DIDEVICEOBJECTDATA), obj_data, &data_size, 0); ok(SUCCEEDED(hr), "Failed to get data hr=%08x\n", hr); - todo_wine ok(data_size == 0, "Expected 0 elements, received %d\n", data_size);
hr = IDirectInputDevice8_Unacquire(di_keyboard);
On 4/17/20 8:35 PM, Brendan Shanks wrote:
Grand Theft Auto IV injects VK_F8 and scancode=0, and expects DirectInput not to report that F8 is pressed.
Signed-off-by: Brendan Shanks bshanks@codeweavers.com
v4: Only make this behavior change for DirectInput 8. It's difficult to show because of the separation of 8 and pre-8 tests, but really does seem to depend only on the DI version used.
dlls/dinput/keyboard.c | 8 ++++---- dlls/dinput8/tests/device.c | 2 -- 2 files changed, 4 insertions(+), 6 deletions(-)
diff --git a/dlls/dinput/keyboard.c b/dlls/dinput/keyboard.c index 47f28cac52..f842f1ca42 100644 --- a/dlls/dinput/keyboard.c +++ b/dlls/dinput/keyboard.c @@ -68,9 +68,9 @@ static inline IDirectInputDevice8W *IDirectInputDevice8W_from_impl(SysKeyboardIm return &This->base.IDirectInputDevice8W_iface; }
-static BYTE map_dik_code(DWORD scanCode, DWORD vkCode, DWORD subType) +static BYTE map_dik_code(DWORD scanCode, DWORD vkCode, DWORD subType, DWORD version) {
- if (!scanCode)
if (!scanCode && version < 0x0800) scanCode = MapVirtualKeyW(vkCode, MAPVK_VK_TO_VSC);
if (subType == DIDEVTYPEKEYBOARD_JAPAN106)
@@ -125,7 +125,7 @@ static int KeyboardCallback( LPDIRECTINPUTDEVICE8A iface, WPARAM wparam, LPARAM case VK_NUMLOCK : dik_code = DIK_NUMLOCK; break; case VK_SUBTRACT: dik_code = DIK_SUBTRACT; break; default:
dik_code = map_dik_code(hook->scanCode & 0xff, hook->vkCode, This->subtype);
dik_code = map_dik_code(hook->scanCode & 0xff, hook->vkCode, This->subtype, This->base.dinput->dwVersion); if (hook->flags & LLKHF_EXTENDED) dik_code |= 0x80; } new_diks = hook->flags & LLKHF_UP ? 0 : 0x80;
@@ -282,7 +282,7 @@ static SysKeyboardImpl *alloc_device(REFGUID rguid, IDirectInputImpl *dinput) if (!GetKeyNameTextA(((i & 0x7f) << 16) | ((i & 0x80) << 17), buf, sizeof(buf))) continue;
dik_code = map_dik_code(i, 0, newDevice->subtype);
dik_code = map_dik_code(i, 0, newDevice->subtype, dinput->dwVersion); memcpy(&df->rgodf[idx], &c_dfDIKeyboard.rgodf[dik_code], df->dwObjSize); df->rgodf[idx++].dwType = DIDFT_MAKEINSTANCE(dik_code) | DIDFT_PSHBUTTON; }
diff --git a/dlls/dinput8/tests/device.c b/dlls/dinput8/tests/device.c index bb82855d40..39c635f2fb 100644 --- a/dlls/dinput8/tests/device.c +++ b/dlls/dinput8/tests/device.c @@ -820,7 +820,6 @@ static void test_keyboard_events(void) data_size = ARRAY_SIZE(obj_data); hr = IDirectInputDevice8_GetDeviceData(di_keyboard, sizeof(DIDEVICEOBJECTDATA), obj_data, &data_size, 0); ok(SUCCEEDED(hr), "Failed to get data hr=%08x\n", hr);
todo_wine ok(data_size == 0, "Expected 0 elements, received %d\n", data_size);
hr = IDirectInputDevice8_GetDeviceState(di_keyboard, sizeof(kbdata), kbdata);
@@ -834,7 +833,6 @@ static void test_keyboard_events(void) data_size = ARRAY_SIZE(obj_data); hr = IDirectInputDevice8_GetDeviceData(di_keyboard, sizeof(DIDEVICEOBJECTDATA), obj_data, &data_size, 0); ok(SUCCEEDED(hr), "Failed to get data hr=%08x\n", hr);
todo_wine ok(data_size == 0, "Expected 0 elements, received %d\n", data_size);
hr = IDirectInputDevice8_Unacquire(di_keyboard);
Ha that's why it installs a LL keyboard hook, I was wondering why it was doing that.
Long story short, DInput8 uses RawInput API to get input events, so I believe it should not install any LL hook in that case.
In addition, in exclusive cooperative mode it should also set the RIDEV_NOLEGACY flag which I believe prevents any input messages to be sent -even to LL hooks.
The rawinput patches that are in Staging should implement that logic, but I kept the hooks installed, specifically because of GTAV.
When no DInput hooks are there, wineserver sends the messages to GTAV and they are neve handled for some reason, which causes a wait and timeout on every keypress.
When the hooks are kept, and because the esync staging patch series also includes a hook removal on timeout -as Win >=7 is supposed to do [*]-, the first input makes GTAV hook time out, and it's then removed.
[*] I did some investigation and it looks like Windows >=7 removes hooks that time out for 32bit applications, not 64bit apps for whatever reason.
On 4/17/20 1:47 PM, Rémi Bernon wrote:
On 4/17/20 8:35 PM, Brendan Shanks wrote:
Grand Theft Auto IV injects VK_F8 and scancode=0, and expects DirectInput not to report that F8 is pressed.
Signed-off-by: Brendan Shanks bshanks@codeweavers.com
v4: Only make this behavior change for DirectInput 8. It's difficult to show because of the separation of 8 and pre-8 tests, but really does seem to depend only on the DI version used.
dlls/dinput/keyboard.c | 8 ++++---- dlls/dinput8/tests/device.c | 2 -- 2 files changed, 4 insertions(+), 6 deletions(-)
diff --git a/dlls/dinput/keyboard.c b/dlls/dinput/keyboard.c index 47f28cac52..f842f1ca42 100644 --- a/dlls/dinput/keyboard.c +++ b/dlls/dinput/keyboard.c @@ -68,9 +68,9 @@ static inline IDirectInputDevice8W *IDirectInputDevice8W_from_impl(SysKeyboardIm return &This->base.IDirectInputDevice8W_iface; } -static BYTE map_dik_code(DWORD scanCode, DWORD vkCode, DWORD subType) +static BYTE map_dik_code(DWORD scanCode, DWORD vkCode, DWORD subType, DWORD version) { - if (!scanCode) + if (!scanCode && version < 0x0800) scanCode = MapVirtualKeyW(vkCode, MAPVK_VK_TO_VSC); if (subType == DIDEVTYPEKEYBOARD_JAPAN106) @@ -125,7 +125,7 @@ static int KeyboardCallback( LPDIRECTINPUTDEVICE8A iface, WPARAM wparam, LPARAM case VK_NUMLOCK : dik_code = DIK_NUMLOCK; break; case VK_SUBTRACT: dik_code = DIK_SUBTRACT; break; default: - dik_code = map_dik_code(hook->scanCode & 0xff, hook->vkCode, This->subtype); + dik_code = map_dik_code(hook->scanCode & 0xff, hook->vkCode, This->subtype, This->base.dinput->dwVersion); if (hook->flags & LLKHF_EXTENDED) dik_code |= 0x80; } new_diks = hook->flags & LLKHF_UP ? 0 : 0x80; @@ -282,7 +282,7 @@ static SysKeyboardImpl *alloc_device(REFGUID rguid, IDirectInputImpl *dinput) if (!GetKeyNameTextA(((i & 0x7f) << 16) | ((i & 0x80) << 17), buf, sizeof(buf))) continue; - dik_code = map_dik_code(i, 0, newDevice->subtype); + dik_code = map_dik_code(i, 0, newDevice->subtype, dinput->dwVersion); memcpy(&df->rgodf[idx], &c_dfDIKeyboard.rgodf[dik_code], df->dwObjSize); df->rgodf[idx++].dwType = DIDFT_MAKEINSTANCE(dik_code) | DIDFT_PSHBUTTON; } diff --git a/dlls/dinput8/tests/device.c b/dlls/dinput8/tests/device.c index bb82855d40..39c635f2fb 100644 --- a/dlls/dinput8/tests/device.c +++ b/dlls/dinput8/tests/device.c @@ -820,7 +820,6 @@ static void test_keyboard_events(void) data_size = ARRAY_SIZE(obj_data); hr = IDirectInputDevice8_GetDeviceData(di_keyboard, sizeof(DIDEVICEOBJECTDATA), obj_data, &data_size, 0); ok(SUCCEEDED(hr), "Failed to get data hr=%08x\n", hr); - todo_wine ok(data_size == 0, "Expected 0 elements, received %d\n", data_size); hr = IDirectInputDevice8_GetDeviceState(di_keyboard, sizeof(kbdata), kbdata); @@ -834,7 +833,6 @@ static void test_keyboard_events(void) data_size = ARRAY_SIZE(obj_data); hr = IDirectInputDevice8_GetDeviceData(di_keyboard, sizeof(DIDEVICEOBJECTDATA), obj_data, &data_size, 0); ok(SUCCEEDED(hr), "Failed to get data hr=%08x\n", hr); - todo_wine ok(data_size == 0, "Expected 0 elements, received %d\n", data_size); hr = IDirectInputDevice8_Unacquire(di_keyboard);
Ha that's why it installs a LL keyboard hook, I was wondering why it was doing that.
Long story short, DInput8 uses RawInput API to get input events, so I believe it should not install any LL hook in that case.
In addition, in exclusive cooperative mode it should also set the RIDEV_NOLEGACY flag which I believe prevents any input messages to be sent -even to LL hooks.
The rawinput patches that are in Staging should implement that logic, but I kept the hooks installed, specifically because of GTAV.
When no DInput hooks are there, wineserver sends the messages to GTAV and they are neve handled for some reason, which causes a wait and timeout on every keypress.
When the hooks are kept, and because the esync staging patch series also includes a hook removal on timeout -as Win >=7 is supposed to do [*]-, the first input makes GTAV hook time out, and it's then removed.
[*] I did some investigation and it looks like Windows >=7 removes hooks that time out for 32bit applications, not 64bit apps for whatever reason.
For what it's worth, that patch could be removed; it was a workaround for an issue that I eventually had to fix another way. I figured it was correct anyway, but as this issue is showing, it may not be worth having...
On 4/17/20 8:45 PM, Zebediah Figura wrote:
For what it's worth, that patch could be removed; it was a workaround for an issue that I eventually had to fix another way. I figured it was correct anyway, but as this issue is showing, it may not be worth having...
It's actually partially fixing the issue, as without it, and because the game does not processes its hooks, every keyboard input has to wait for 2s.
The issue is that it only works on the user side, so only if called from another hook, so when no DInput hooks are used, the server directly send the message to the game and never removes the hook.
I implemented the server-side version of the removal, but as my testing didn't show that it was actually done reliably on Windows, I wasn't sure if it was correct.
In any case, the Windows timeout is 300ms rather than 2s, but that's already to long to wait for keyboard.
The actual thing to solve is probably find why the game never replies to its hook messages in the first place. Or maybe the hook messages are just queued on Windows regardless of hooks, while other subsystems process the input messages transparently. On Wine, as the input messages are sent from the winex11.drv loop, every time a hook is not responding the whole window freezes.
On Apr 17, 2020, at 11:47 AM, Rémi Bernon rbernon@codeweavers.com wrote:
On 4/17/20 8:35 PM, Brendan Shanks wrote:
Grand Theft Auto IV injects VK_F8 and scancode=0, and expects DirectInput not to report that F8 is pressed. Signed-off-by: Brendan Shanks bshanks@codeweavers.com
v4: Only make this behavior change for DirectInput 8. It's difficult to show because of the separation of 8 and pre-8 tests, but really does seem to depend only on the DI version used. dlls/dinput/keyboard.c | 8 ++++---- dlls/dinput8/tests/device.c | 2 -- 2 files changed, 4 insertions(+), 6 deletions(-) diff --git a/dlls/dinput/keyboard.c b/dlls/dinput/keyboard.c index 47f28cac52..f842f1ca42 100644 --- a/dlls/dinput/keyboard.c +++ b/dlls/dinput/keyboard.c @@ -68,9 +68,9 @@ static inline IDirectInputDevice8W *IDirectInputDevice8W_from_impl(SysKeyboardIm return &This->base.IDirectInputDevice8W_iface; } -static BYTE map_dik_code(DWORD scanCode, DWORD vkCode, DWORD subType) +static BYTE map_dik_code(DWORD scanCode, DWORD vkCode, DWORD subType, DWORD version) {
- if (!scanCode)
- if (!scanCode && version < 0x0800) scanCode = MapVirtualKeyW(vkCode, MAPVK_VK_TO_VSC); if (subType == DIDEVTYPEKEYBOARD_JAPAN106)
@@ -125,7 +125,7 @@ static int KeyboardCallback( LPDIRECTINPUTDEVICE8A iface, WPARAM wparam, LPARAM case VK_NUMLOCK : dik_code = DIK_NUMLOCK; break; case VK_SUBTRACT: dik_code = DIK_SUBTRACT; break; default:
dik_code = map_dik_code(hook->scanCode & 0xff, hook->vkCode, This->subtype);
} new_diks = hook->flags & LLKHF_UP ? 0 : 0x80;dik_code = map_dik_code(hook->scanCode & 0xff, hook->vkCode, This->subtype, This->base.dinput->dwVersion); if (hook->flags & LLKHF_EXTENDED) dik_code |= 0x80;
@@ -282,7 +282,7 @@ static SysKeyboardImpl *alloc_device(REFGUID rguid, IDirectInputImpl *dinput) if (!GetKeyNameTextA(((i & 0x7f) << 16) | ((i & 0x80) << 17), buf, sizeof(buf))) continue;
dik_code = map_dik_code(i, 0, newDevice->subtype);
}dik_code = map_dik_code(i, 0, newDevice->subtype, dinput->dwVersion); memcpy(&df->rgodf[idx], &c_dfDIKeyboard.rgodf[dik_code], df->dwObjSize); df->rgodf[idx++].dwType = DIDFT_MAKEINSTANCE(dik_code) | DIDFT_PSHBUTTON;
diff --git a/dlls/dinput8/tests/device.c b/dlls/dinput8/tests/device.c index bb82855d40..39c635f2fb 100644 --- a/dlls/dinput8/tests/device.c +++ b/dlls/dinput8/tests/device.c @@ -820,7 +820,6 @@ static void test_keyboard_events(void) data_size = ARRAY_SIZE(obj_data); hr = IDirectInputDevice8_GetDeviceData(di_keyboard, sizeof(DIDEVICEOBJECTDATA), obj_data, &data_size, 0); ok(SUCCEEDED(hr), "Failed to get data hr=%08x\n", hr);
- todo_wine ok(data_size == 0, "Expected 0 elements, received %d\n", data_size); hr = IDirectInputDevice8_GetDeviceState(di_keyboard, sizeof(kbdata), kbdata);
@@ -834,7 +833,6 @@ static void test_keyboard_events(void) data_size = ARRAY_SIZE(obj_data); hr = IDirectInputDevice8_GetDeviceData(di_keyboard, sizeof(DIDEVICEOBJECTDATA), obj_data, &data_size, 0); ok(SUCCEEDED(hr), "Failed to get data hr=%08x\n", hr);
- todo_wine ok(data_size == 0, "Expected 0 elements, received %d\n", data_size); hr = IDirectInputDevice8_Unacquire(di_keyboard);
Ha that's why it installs a LL keyboard hook, I was wondering why it was doing that.
Long story short, DInput8 uses RawInput API to get input events, so I believe it should not install any LL hook in that case.
In addition, in exclusive cooperative mode it should also set the RIDEV_NOLEGACY flag which I believe prevents any input messages to be sent -even to LL hooks.
The rawinput patches that are in Staging should implement that logic, but I kept the hooks installed, specifically because of GTAV.
When no DInput hooks are there, wineserver sends the messages to GTAV and they are neve handled for some reason, which causes a wait and timeout on every keypress.
When the hooks are kept, and because the esync staging patch series also includes a hook removal on timeout -as Win >=7 is supposed to do [*]-, the first input makes GTAV hook time out, and it's then removed.
[*] I did some investigation and it looks like Windows >=7 removes hooks that time out for 32bit applications, not 64bit apps for whatever reason.
Hmm interesting, this may be a different issue though. I’ve only seen this on GTA 4, not sure if there’s something similar in GTA 5. GTAIV does have code to install a LL keyboard hook, but on Windows 10 and Wine it doesn’t seem to actually run.
A minute or two after the game launches, it starts calling SendInput() constantly with VK_F8, scan=0 and other args=0. It’s bizarre behavior, my best theory is that F8 was a common key used by cheats to bring up their menu, so constantly sending it would make cheats go crazy and the game unplayable. But by exploiting this corner case of DirectInput8 ignoring the VK (certainly when scancode=0), the game itself isn’t affected.
Brendan
On 4/17/20 9:14 PM, Brendan Shanks wrote:
Hmm interesting, this may be a different issue though. I’ve only seen this on GTA 4, not sure if there’s something similar in GTA 5. GTAIV does have code to install a LL keyboard hook, but on Windows 10 and Wine it doesn’t seem to actually run.
A minute or two after the game launches, it starts calling SendInput() constantly with VK_F8, scan=0 and other args=0. It’s bizarre behavior, my best theory is that F8 was a common key used by cheats to bring up their menu, so constantly sending it would make cheats go crazy and the game unplayable. But by exploiting this corner case of DirectInput8 ignoring the VK (certainly when scancode=0), the game itself isn’t affected.
Brendan
Ah, my bad, I read GTAV instead of GTAIV. In any case even if the issue is different, the DInput8 is still implemented over RawInput, which explains why it doesn't report key press when messages are injected.
I believe there are already some dinput and dinput8 tests to validate that fact, but the implementation still waits in staging (and I'm not sue if extracting only the dinput code would work fine).