[PATCH 6/7] dinput: Send only the reports that have been modified.

Rémi Bernon rbernon at codeweavers.com
Mon Nov 22 04:05:48 CST 2021


Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=52061
From: Ivo Ivanov <logos128 at gmail.com>
Signed-off-by: Rémi Bernon <rbernon at codeweavers.com>
---
 dlls/dinput/joystick_hid.c | 71 +++++++++++++++++++++++---------------
 dlls/dinput8/tests/hid.c   | 32 -----------------
 2 files changed, 44 insertions(+), 59 deletions(-)

diff --git a/dlls/dinput/joystick_hid.c b/dlls/dinput/joystick_hid.c
index 5ecf54e2281..62856cefa44 100644
--- a/dlls/dinput/joystick_hid.c
+++ b/dlls/dinput/joystick_hid.c
@@ -219,7 +219,7 @@ struct hid_joystick_effect
     DIENVELOPE envelope;
     DIPERIODIC periodic;
     DIEFFECT params;
-    BOOL modified;
+    DWORD modified;
     DWORD flags;
 
     char *effect_control_buf;
@@ -2470,7 +2470,7 @@ static HRESULT WINAPI hid_joystick_effect_SetParameters( IDirectInputEffect *ifa
             if (ret != DIENUM_STOP) impl->params.rgdwAxes[i] = 0;
         }
 
-        impl->modified = TRUE;
+        impl->modified |= DIEP_AXES;
     }
 
     if (flags & DIEP_DIRECTION)
@@ -2486,7 +2486,7 @@ static HRESULT WINAPI hid_joystick_effect_SetParameters( IDirectInputEffect *ifa
         impl->params.dwFlags &= ~(DIEFF_CARTESIAN | DIEFF_POLAR | DIEFF_SPHERICAL);
         impl->params.dwFlags |= direction_flags;
         if (memcmp( impl->params.rglDirection, params->rglDirection, count * sizeof(LONG) ))
-            impl->modified = TRUE;
+            impl->modified |= DIEP_DIRECTION;
         memcpy( impl->params.rglDirection, params->rglDirection, count * sizeof(LONG) );
     }
 
@@ -2502,7 +2502,7 @@ static HRESULT WINAPI hid_joystick_effect_SetParameters( IDirectInputEffect *ifa
             if (!params->lpvTypeSpecificParams) return E_POINTER;
             if (params->cbTypeSpecificParams != sizeof(DIPERIODIC)) return DIERR_INVALIDPARAM;
             if (memcmp( &impl->periodic, params->lpvTypeSpecificParams, sizeof(DIPERIODIC) ))
-                impl->modified = TRUE;
+                impl->modified |= DIEP_TYPESPECIFICPARAMS;
             memcpy( &impl->periodic, params->lpvTypeSpecificParams, sizeof(DIPERIODIC) );
             impl->params.cbTypeSpecificParams = sizeof(DIPERIODIC);
             break;
@@ -2516,6 +2516,8 @@ static HRESULT WINAPI hid_joystick_effect_SetParameters( IDirectInputEffect *ifa
                 if (params->cbTypeSpecificParams != count * sizeof(DICONDITION) &&
                     params->cbTypeSpecificParams != sizeof(DICONDITION))
                     return DIERR_INVALIDPARAM;
+                if (memcmp( impl->condition, params->lpvTypeSpecificParams, params->cbTypeSpecificParams ))
+                    impl->modified |= DIEP_TYPESPECIFICPARAMS;
                 memcpy( impl->condition, params->lpvTypeSpecificParams, params->cbTypeSpecificParams );
                 impl->params.cbTypeSpecificParams = params->cbTypeSpecificParams;
             }
@@ -2524,7 +2526,7 @@ static HRESULT WINAPI hid_joystick_effect_SetParameters( IDirectInputEffect *ifa
             if (!params->lpvTypeSpecificParams) return E_POINTER;
             if (params->cbTypeSpecificParams != sizeof(DICONSTANTFORCE)) return DIERR_INVALIDPARAM;
             if (memcmp( &impl->constant_force, params->lpvTypeSpecificParams, sizeof(DICONSTANTFORCE) ))
-                impl->modified = TRUE;
+                impl->modified |= DIEP_TYPESPECIFICPARAMS;
             memcpy( &impl->constant_force, params->lpvTypeSpecificParams, sizeof(DICONSTANTFORCE) );
             impl->params.cbTypeSpecificParams = sizeof(DICONSTANTFORCE);
             break;
@@ -2532,7 +2534,7 @@ static HRESULT WINAPI hid_joystick_effect_SetParameters( IDirectInputEffect *ifa
             if (!params->lpvTypeSpecificParams) return E_POINTER;
             if (params->cbTypeSpecificParams != sizeof(DIRAMPFORCE)) return DIERR_INVALIDPARAM;
             if (memcmp( &impl->constant_force, params->lpvTypeSpecificParams, sizeof(DIRAMPFORCE) ))
-                impl->modified = TRUE;
+                impl->modified |= DIEP_TYPESPECIFICPARAMS;
             memcpy( &impl->constant_force, params->lpvTypeSpecificParams, sizeof(DIRAMPFORCE) );
             impl->params.cbTypeSpecificParams = sizeof(DIRAMPFORCE);
             break;
@@ -2546,35 +2548,35 @@ static HRESULT WINAPI hid_joystick_effect_SetParameters( IDirectInputEffect *ifa
     {
         if (params->lpEnvelope->dwSize != sizeof(DIENVELOPE)) return DIERR_INVALIDPARAM;
         if (memcmp( &impl->envelope, params->lpEnvelope, sizeof(DIENVELOPE) ))
-            impl->modified = TRUE;
+            impl->modified |= DIEP_ENVELOPE;
         memcpy( &impl->envelope, params->lpEnvelope, sizeof(DIENVELOPE) );
     }
 
     if (flags & DIEP_DURATION)
     {
-        if (impl->params.dwDuration != params->dwDuration) impl->modified = TRUE;
+        if (impl->params.dwDuration != params->dwDuration) impl->modified |= DIEP_DURATION;
         impl->params.dwDuration = params->dwDuration;
     }
     if (flags & DIEP_GAIN)
     {
-        if (impl->params.dwGain != params->dwGain) impl->modified = TRUE;
+        if (impl->params.dwGain != params->dwGain) impl->modified |= DIEP_GAIN;
         impl->params.dwGain = params->dwGain;
     }
     if (flags & DIEP_SAMPLEPERIOD)
     {
-        if (impl->params.dwSamplePeriod != params->dwSamplePeriod) impl->modified = TRUE;
+        if (impl->params.dwSamplePeriod != params->dwSamplePeriod) impl->modified |= DIEP_SAMPLEPERIOD;
         impl->params.dwSamplePeriod = params->dwSamplePeriod;
     }
     if (flags & DIEP_STARTDELAY)
     {
         if (params->dwSize != sizeof(DIEFFECT_DX6)) return DIERR_INVALIDPARAM;
-        if (impl->params.dwStartDelay != params->dwStartDelay) impl->modified = TRUE;
+        if (impl->params.dwStartDelay != params->dwStartDelay) impl->modified |= DIEP_STARTDELAY;
         impl->params.dwStartDelay = params->dwStartDelay;
     }
     if (flags & DIEP_TRIGGERREPEATINTERVAL)
     {
         if (impl->params.dwTriggerRepeatInterval != params->dwTriggerRepeatInterval)
-            impl->modified = TRUE;
+            impl->modified |= DIEP_TRIGGERREPEATINTERVAL;
         impl->params.dwTriggerRepeatInterval = params->dwTriggerRepeatInterval;
     }
 
@@ -2587,7 +2589,7 @@ static HRESULT WINAPI hid_joystick_effect_SetParameters( IDirectInputEffect *ifa
         ret = enum_objects( impl->joystick, &filter, DIDFT_BUTTON, set_parameters_object,
                             &impl->params.dwTriggerButton );
         if (ret != DIENUM_STOP) impl->params.dwTriggerButton = -1;
-        if (impl->params.dwTriggerButton != old_value) impl->modified = TRUE;
+        if (impl->params.dwTriggerButton != old_value) impl->modified |= DIEP_TRIGGERBUTTON;
     }
 
     impl->flags |= flags;
@@ -2792,6 +2794,8 @@ static HRESULT WINAPI hid_joystick_effect_Download( IDirectInputEffect *iface )
         case PID_USAGE_ET_TRIANGLE:
         case PID_USAGE_ET_SAWTOOTH_UP:
         case PID_USAGE_ET_SAWTOOTH_DOWN:
+            if (!(impl->modified & DIEP_TYPESPECIFICPARAMS)) break;
+
             set_parameter_value( impl, impl->type_specific_buf, set_periodic->magnitude_caps,
                                  impl->periodic.dwMagnitude );
             set_parameter_value_us( impl, impl->type_specific_buf, set_periodic->period_caps,
@@ -2801,13 +2805,15 @@ static HRESULT WINAPI hid_joystick_effect_Download( IDirectInputEffect *iface )
             set_parameter_value( impl, impl->type_specific_buf, set_periodic->offset_caps,
                                  impl->periodic.lOffset );
 
-            if (WriteFile( device, impl->type_specific_buf, report_len, NULL, NULL )) hr = DI_OK;
-            else hr = DIERR_INPUTLOST;
+            if (!WriteFile( device, impl->type_specific_buf, report_len, NULL, NULL )) hr = DIERR_INPUTLOST;
+            else impl->modified &= ~DIEP_TYPESPECIFICPARAMS;
             break;
         case PID_USAGE_ET_SPRING:
         case PID_USAGE_ET_DAMPER:
         case PID_USAGE_ET_INERTIA:
         case PID_USAGE_ET_FRICTION:
+            if (!(impl->modified & DIEP_TYPESPECIFICPARAMS)) break;
+
             for (i = 0; i < impl->params.cbTypeSpecificParams / sizeof(DICONDITION); ++i)
             {
                 status = HidP_SetUsageValue( HidP_Output, HID_USAGE_PAGE_PID, 0, PID_USAGE_PARAMETER_BLOCK_OFFSET,
@@ -2827,28 +2833,35 @@ static HRESULT WINAPI hid_joystick_effect_Download( IDirectInputEffect *iface )
                 set_parameter_value( impl, impl->type_specific_buf, set_condition->dead_band_caps,
                                      impl->condition[i].lDeadBand );
 
-                if (WriteFile( device, impl->type_specific_buf, report_len, NULL, NULL )) hr = DI_OK;
-                else hr = DIERR_INPUTLOST;
+                if (!WriteFile( device, impl->type_specific_buf, report_len, NULL, NULL )) hr = DIERR_INPUTLOST;
+                else impl->modified &= ~DIEP_TYPESPECIFICPARAMS;
             }
             break;
         case PID_USAGE_ET_CONSTANT_FORCE:
+            if (!(impl->modified & DIEP_TYPESPECIFICPARAMS)) break;
+
             set_parameter_value( impl, impl->type_specific_buf, set_constant_force->magnitude_caps,
                                  impl->constant_force.lMagnitude );
 
-            if (WriteFile( device, impl->type_specific_buf, report_len, NULL, NULL )) hr = DI_OK;
-            else hr = DIERR_INPUTLOST;
+            if (!WriteFile( device, impl->type_specific_buf, report_len, NULL, NULL )) hr = DIERR_INPUTLOST;
+            else impl->modified &= ~DIEP_TYPESPECIFICPARAMS;
             break;
         case PID_USAGE_ET_RAMP:
+            if (!(impl->modified & DIEP_TYPESPECIFICPARAMS)) break;
+
             set_parameter_value( impl, impl->type_specific_buf, set_ramp_force->start_caps,
                                  impl->ramp_force.lStart );
             set_parameter_value( impl, impl->type_specific_buf, set_ramp_force->end_caps,
                                  impl->ramp_force.lEnd );
 
-            if (WriteFile( device, impl->type_specific_buf, report_len, NULL, NULL )) hr = DI_OK;
-            else hr = DIERR_INPUTLOST;
+            if (!WriteFile( device, impl->type_specific_buf, report_len, NULL, NULL )) hr = DIERR_INPUTLOST;
+            else impl->modified &= ~DIEP_TYPESPECIFICPARAMS;
             break;
         }
+    }
 
+    if (hr == DI_OK)
+    {
         switch (impl->type)
         {
         case PID_USAGE_ET_SQUARE:
@@ -2858,6 +2871,8 @@ static HRESULT WINAPI hid_joystick_effect_Download( IDirectInputEffect *iface )
         case PID_USAGE_ET_SAWTOOTH_DOWN:
         case PID_USAGE_ET_CONSTANT_FORCE:
         case PID_USAGE_ET_RAMP:
+            if (!(impl->modified & DIEP_ENVELOPE)) break;
+
             set_parameter_value( impl, impl->set_envelope_buf, set_envelope->attack_level_caps,
                                  impl->envelope.dwAttackLevel );
             set_parameter_value_us( impl, impl->set_envelope_buf, set_envelope->attack_time_caps,
@@ -2867,11 +2882,14 @@ static HRESULT WINAPI hid_joystick_effect_Download( IDirectInputEffect *iface )
             set_parameter_value_us( impl, impl->set_envelope_buf, set_envelope->fade_time_caps,
                                     impl->envelope.dwFadeTime );
 
-            if (WriteFile( device, impl->set_envelope_buf, report_len, NULL, NULL )) hr = DI_OK;
-            else hr = DIERR_INPUTLOST;
+            if (!WriteFile( device, impl->set_envelope_buf, report_len, NULL, NULL )) hr = DIERR_INPUTLOST;
+            else impl->modified &= ~DIEP_ENVELOPE;
             break;
         }
+    }
 
+    if (hr == DI_OK && impl->modified)
+    {
         set_parameter_value_us( impl, impl->effect_update_buf, effect_update->duration_caps,
                                 impl->params.dwDuration );
         set_parameter_value( impl, impl->effect_update_buf, effect_update->gain_caps,
@@ -2904,10 +2922,8 @@ static HRESULT WINAPI hid_joystick_effect_Download( IDirectInputEffect *iface )
                                      impl->effect_update_buf, report_len );
         if (status != HIDP_STATUS_SUCCESS) WARN( "HidP_SetUsageValue returned %#x\n", status );
 
-        if (WriteFile( device, impl->effect_update_buf, report_len, NULL, NULL )) hr = DI_OK;
-        else hr = DIERR_INPUTLOST;
-
-        impl->modified = FALSE;
+        if (!WriteFile( device, impl->effect_update_buf, report_len, NULL, NULL )) hr = DIERR_INPUTLOST;
+        else impl->modified = 0;
     }
     LeaveCriticalSection( &impl->joystick->base.crit );
 
@@ -2947,6 +2963,7 @@ static HRESULT WINAPI hid_joystick_effect_Unload( IDirectInputEffect *iface )
             else hr = DIERR_INPUTLOST;
         }
 
+        impl->modified = impl->flags;
         impl->index = 0;
     }
     LeaveCriticalSection( &joystick->base.crit );
diff --git a/dlls/dinput8/tests/hid.c b/dlls/dinput8/tests/hid.c
index 26a5406fa57..4159c3edd90 100644
--- a/dlls/dinput8/tests/hid.c
+++ b/dlls/dinput8/tests/hid.c
@@ -5628,22 +5628,6 @@ static void test_periodic_effect( IDirectInputDevice8W *device, HANDLE file, DWO
     };
     struct hid_expect expect_update[] =
     {
-        /* set periodic */
-        {
-            .code = IOCTL_HID_WRITE_REPORT,
-            .report_id = 5,
-            .report_len = 2,
-            .report_buf = {0x05,0x19},
-            .wine_only = TRUE, .todo = TRUE,
-        },
-        /* set envelope */
-        {
-            .code = IOCTL_HID_WRITE_REPORT,
-            .report_id = 6,
-            .report_len = 7,
-            .report_buf = {0x06,0x19,0x4c,0x02,0x00,0x04,0x00},
-            .wine_only = TRUE, .todo = TRUE,
-        },
         /* update effect */
         {
             .code = IOCTL_HID_WRITE_REPORT,
@@ -5654,14 +5638,6 @@ static void test_periodic_effect( IDirectInputDevice8W *device, HANDLE file, DWO
     };
     struct hid_expect expect_set_envelope[] =
     {
-        /* set periodic */
-        {
-            .code = IOCTL_HID_WRITE_REPORT,
-            .report_id = 5,
-            .report_len = 2,
-            .report_buf = {0x05,0x19},
-            .wine_only = TRUE, .todo = TRUE,
-        },
         /* set envelope */
         {
             .code = IOCTL_HID_WRITE_REPORT,
@@ -5669,14 +5645,6 @@ static void test_periodic_effect( IDirectInputDevice8W *device, HANDLE file, DWO
             .report_len = 7,
             .report_buf = {0x06,0x19,0x4c,0x01,0x00,0x04,0x00},
         },
-        /* update effect */
-        {
-            .code = IOCTL_HID_WRITE_REPORT,
-            .report_id = 3,
-            .report_len = 11,
-            .report_buf = {0x03,0x01,0x02,0x08,0xff,0xff,version >= 0x700 ? 0x06 : 0x00,0x00,0x01,0x55,0xd5},
-            .wine_only = TRUE, .todo = TRUE,
-        },
     };
     struct hid_expect expect_start =
     {
-- 
2.33.1




More information about the wine-devel mailing list