diff --git a/dlls/dinput/tests/force_feedback.c b/dlls/dinput/tests/force_feedback.c index 6fdfa20c130..5ffc6a43471 100644 --- a/dlls/dinput/tests/force_feedback.c +++ b/dlls/dinput/tests/force_feedback.c @@ -5806,21 +5806,12 @@ static void test_windows_gaming_input(void) .report_len = 4, .report_buf = {9,0x01,0x18,0xfc}, }, - /* update effect (wine) */ - { - .code = IOCTL_HID_WRITE_REPORT, - .report_id = 3, - .report_len = 18, - .report_buf = {3,0x01,0x04,0x04,0x28,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0x7f,0x99,0x00,0x00,0x00}, - .wine_only = TRUE, .todo = TRUE, - }, /* update effect */ { .code = IOCTL_HID_WRITE_REPORT, .report_id = 3, .report_len = 18, .report_buf = {3,0x01,0x04,0x04,0x28,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0x7f,0x4e,0x01,0x00,0x00}, - .todo = TRUE, }, }; struct hid_expect expect_create_ramp[] = @@ -5915,21 +5906,12 @@ static void test_windows_gaming_input(void) .report_len = 6, .report_buf = {10,0x01,0x18,0xfc,0x60,0xf0}, }, - /* update effect (wine) */ - { - .code = IOCTL_HID_WRITE_REPORT, - .report_id = 3, - .report_len = 18, - .report_buf = {3,0x01,0x05,0x04,0x8f,0xe4,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x99,0x00,0x00,0x00}, - .wine_only = TRUE, .todo = TRUE, - }, /* update effect */ { .code = IOCTL_HID_WRITE_REPORT, .report_id = 3, .report_len = 18, .report_buf = {3,0x01,0x05,0x04,0xff,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x4e,0x01,0x00,0x00}, - .todo = TRUE, }, }; struct hid_expect expect_effect_start = diff --git a/dlls/windows.gaming.input/force_feedback.c b/dlls/windows.gaming.input/force_feedback.c index 20b022ff317..cff3c184bf9 100644 --- a/dlls/windows.gaming.input/force_feedback.c +++ b/dlls/windows.gaming.input/force_feedback.c @@ -117,10 +117,12 @@ static int effect_reorient_direction( const WineForceFeedbackEffectParameters *p { case WineForceFeedbackEffectType_Constant: *direction = params->constant.direction; + sign = params->constant.direction.X < 0 ? -1 : +1; break; case WineForceFeedbackEffectType_Ramp: *direction = params->ramp.start_vector; + sign = params->ramp.start_vector.X < 0 ? -1 : +1; break; case WineForceFeedbackEffectType_Periodic_SineWave: @@ -152,6 +154,7 @@ static HRESULT WINAPI effect_impl_put_Parameters( IWineForceFeedbackEffectImpl * { struct effect *impl = impl_from_IWineForceFeedbackEffectImpl( iface ); Vector3 direction = {0}; + double magnitude = 0; DWORD count = 0; HRESULT hr; int sign; @@ -161,19 +164,21 @@ static HRESULT WINAPI effect_impl_put_Parameters( IWineForceFeedbackEffectImpl * EnterCriticalSection( &impl->cs ); sign = effect_reorient_direction( ¶ms, &direction ); + /* Y and Z axes seems to be always ignored, is it really the case? */ + magnitude += direction.X * direction.X; switch (params.type) { case WineForceFeedbackEffectType_Constant: impl->repeat_count = params.constant.repeat_count; - impl->constant_force.lMagnitude = -sign * round( params.constant.gain * direction.X * 10000 ); + impl->constant_force.lMagnitude = sign * round( params.constant.gain * sqrt( magnitude ) * 10000 ); impl->params.dwDuration = min( max( params.constant.duration.Duration / 10, 0 ), INFINITE ); impl->params.dwStartDelay = min( max( params.constant.start_delay.Duration / 10, 0 ), INFINITE ); break; case WineForceFeedbackEffectType_Ramp: impl->repeat_count = params.ramp.repeat_count; - impl->ramp_force.lStart = -sign * round( params.ramp.gain * direction.X * 10000 ); + impl->ramp_force.lStart = sign * round( params.ramp.gain * sqrt( magnitude ) * 10000 ); impl->ramp_force.lEnd = round( params.ramp.gain * params.ramp.end_vector.X * 10000 ); impl->params.dwDuration = min( max( params.ramp.duration.Duration / 10, 0 ), INFINITE ); impl->params.dwStartDelay = min( max( params.ramp.start_delay.Duration / 10, 0 ), INFINITE );