If application sends out-of-range values for FFB effects, they become -1, which is undesireable, when -1 is in the physical range of the field and being sent to the device. This patch fixes it, clamping values to the field range. Clamping was earlier implemented [here](https://gitlab.winehq.org/wine/wine/-/blob/wine-6.19/dlls/dinput/effe… in 6.19. Windows does this clamping silently, and doesn't fail `SetParameters` call when values is out of range.
Affected application is Assetto Corsa EVO, which with default settings sends out ConstantForce magnitude under/over [documented](https://learn.microsoft.com/en-us/previous-versions/ms835644(v=… \[-10000, 10000\]. [Link to the discussion with some investigation on Steam](https://steamcommunity.com/app/3058630/discussions/0/756142145462617….
In this submission scaling and clamping were moved to the separate `scale_and_clamp_value` function, which is now called every time from `set_parameter_value`. To avoid regression with sending `-1` for the infinite duration effects, separate function `set_parameter_value_no_scaling` created. Gain values in `hid_joystick_send_device_gain` are also scaled and clamped.
--
v2: dinput: Clamp FFB effect report value to the field range.
https://gitlab.winehq.org/wine/wine/-/merge_requests/7161
If application sends out-of-range values for FFB effects, they become -1, which is undesireable, when -1 is in the physical range of the field and being sent to the device. This patch fixes it, clamping values to the field range. Clamping was earlier implemented [here](https://gitlab.winehq.org/wine/wine/-/blob/wine-6.19/dlls/dinput/effe… in 6.19. Windows does this clamping silently, and doesn't fail `SetParameters` call when values is out of range.
Affected application is Assetto Corsa EVO, which with default settings sends out ConstantForce magnitude under/over [documented](https://learn.microsoft.com/en-us/previous-versions/ms835644(v=… \[-10000, 10000\]. [Link to the discussion with some investigation on Steam](https://steamcommunity.com/app/3058630/discussions/0/756142145462617….
In this submission scaling and clamping were moved to the separate `scale_and_clamp_value` function, which is now called every time from `set_parameter_value`. To avoid regression with sending `-1` for the infinite duration effects, separate function `set_parameter_value_no_scaling` created. Gain values in `hid_joystick_send_device_gain` are also scaled and clamped.
--
https://gitlab.winehq.org/wine/wine/-/merge_requests/7161
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=57665
---
The issue is that The Medium launcher uses a dialog window procedure, and implements its background by doing a StretchBlt call on WM_PAINT in the dialog procedure call, which happens before the window message loop.
It then itself calls InvalidateRect(hwnd, NULL, 0), which queues a WM_PAINT as well but with only the RDW_INVALIDATE flag.
Next, when the window message loop is executed, the WM_PAINT message is being processed as it should, but as we've invalidate the window with RDW_ERASE ourselves from the expose event, the WM_NCPAINT handler erases the entire window, clearing the pixels that the launcher has just painted.
This regressed since the window surface clipping region logic changed, as the expose event handling was previously not calling `NtUserRedrawWindow` on windows with a surface and without a clipping region. The clipping region was also previously not always set, or set later, and we're setting it more consistently since 51b16963f6e0e8df43118deac63f640aee4698b7, even when it matches the window rect, for compatibility with some old wineandroid logic (where I believe it was used to clip window surfaces to their proper sizes).
--
v2: winex11: Only erase the desktop window pixels on expose events.
https://gitlab.winehq.org/wine/wine/-/merge_requests/7157
This ensures that the induced non-client redraw are sent and executed
right away, and before the WM_PAINT messages are sent.
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=57665
---
The issue is that The Medium launcher uses a dialog window procedure, and implements its background by doing a StretchBlt call on WM_PAINT in the dialog procedure call, which happens before the window message loop.
It then itself calls InvalidateRect(hwnd, NULL, 0), which queues a WM_PAINT as well but with only the RDW_INVALIDATE flag.
Next, when the window message loop is executed, the WM_PAINT message is being processed as it should, but as we've invalidate the window with RDW_ERASE ourselves from the expose event, the WM_NCPAINT handler erases the entire window, clearing the pixels that the launcher has just painted.
Using RDW_ERASENOW we make sure that the erase happens right away on expose, and before the WM_PAINT message is being processed.
This regressed since the window surface clipping region logic changed, as the expose event handling was previously not calling `NtUserRedrawWindow` on windows with a surface and without a clipping region. The clipping region was also previously not always set, or set later, and we're setting it more consistently since 51b16963f6e0e8df43118deac63f640aee4698b7, even when it matches the window rect, for compatibility with some old wineandroid logic (where I believe it was used to clip window surfaces to their proper sizes).
--
https://gitlab.winehq.org/wine/wine/-/merge_requests/7157
Tests run via your command line fail to run for me, certainly due to lack of dependencies in my build. I'll work on addressing those, to see if I can get the tests to run.
./wine programs/winetest/x86_64-windows/winetest.exe -o - cmd.exe
0050:err:vulkan:vulkan_init_once Wine was built without Vulkan support.
00c4:err:ntoskrnl:ZwLoadDriver failed to create driver L"\\Registry\\Machine\\System\\CurrentControlSet\\Services\\winebth": c00000e5
003c:fixme:service:scmdatabase_autostart_services Auto-start service L"winebth" failed to start: 1359
wine: failed to open "programs/winetest/x86_64-windows/winetest.exe": c0000135
--
https://gitlab.winehq.org/wine/wine/-/merge_requests/7131#note_92190