From 081a2891267aa65b4e8e5eb50d8d6b663a701b46 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A9mi=20Bernon?= Date: Thu, 12 May 2022 16:00:55 +0200 Subject: [PATCH] windows.gaming.input: Implement IRampForceEffect_SetParameters(WithEnvelope). MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: RĂ©mi Bernon Signed-off-by: Alexandre Julliard --- dlls/dinput/tests/force_feedback.c | 6 +-- dlls/windows.gaming.input/force_feedback.c | 9 ++++- dlls/windows.gaming.input/provider.idl | 13 ++++++ dlls/windows.gaming.input/ramp_effect.c | 47 +++++++++++++++++++--- 4 files changed, 64 insertions(+), 11 deletions(-) diff --git a/dlls/dinput/tests/force_feedback.c b/dlls/dinput/tests/force_feedback.c index 8d06cdda3d8..acd12f22401 100644 --- a/dlls/dinput/tests/force_feedback.c +++ b/dlls/dinput/tests/force_feedback.c @@ -5604,7 +5604,6 @@ static void test_windows_gaming_input(void) .report_id = 10, .report_len = 6, .report_buf = {10,0x01,0xc8,0x00,0x20,0x03}, - .todo = TRUE, }, /* set envelope */ { @@ -5612,14 +5611,13 @@ static void test_windows_gaming_input(void) .report_id = 8, .report_len = 8, .report_buf = {8,0x01,0x19,0x4c,0x14,0x00,0x3c,0x00}, - .todo = TRUE, }, /* update effect */ { .code = IOCTL_HID_WRITE_REPORT, .report_id = 3, .report_len = 18, - .report_buf = {3,0x01,0x05,0x08,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x5a,0x00,0x00,0x00}, + .report_buf = {3,0x01,0x05,0x08,0x5a,0x00,0x00,0x00,0x00,0x00,0x0a,0x00,0xff,0xff,0xce,0x00,0x00,0x00}, .wine_only = TRUE, .todo = TRUE, }, @@ -6399,11 +6397,9 @@ static void test_windows_gaming_input(void) ok( hr == S_OK, "QueryInterface returned %#lx\n", hr ); hr = IRampForceEffect_SetParameters( ramp_effect, direction, end_direction, duration ); - todo_wine ok( hr == S_OK, "SetParameters returned %#lx\n", hr ); hr = IRampForceEffect_SetParametersWithEnvelope( ramp_effect, direction, end_direction, 0.1, 0.2, 0.3, delay, attack_duration, duration, release_duration, 1 ); - todo_wine ok( hr == S_OK, "SetParametersWithEnvelope returned %#lx\n", hr ); IRampForceEffect_Release( ramp_effect ); diff --git a/dlls/windows.gaming.input/force_feedback.c b/dlls/windows.gaming.input/force_feedback.c index ce30db14cd9..2ed272916c9 100644 --- a/dlls/windows.gaming.input/force_feedback.c +++ b/dlls/windows.gaming.input/force_feedback.c @@ -131,7 +131,14 @@ static HRESULT WINAPI effect_impl_put_Parameters( IWineForceFeedbackEffectImpl * break; case WineForceFeedbackEffectType_Ramp: - FIXME("stub!\n"); + impl->repeat_count = params.ramp.repeat_count; + impl->ramp_force.lStart = round( params.ramp.gain * params.ramp.start_vector.X * 10000 ); + impl->ramp_force.lEnd = round( params.ramp.gain * params.ramp.end_vector.X * 10000 ); + impl->params.dwDuration = params.ramp.duration.Duration / 10; + impl->params.dwStartDelay = params.ramp.start_delay.Duration / 10; + impl->directions[0] = round( -params.ramp.start_vector.X * 10000 ); + impl->directions[1] = round( -params.ramp.start_vector.Y * 10000 ); + impl->directions[2] = round( -params.ramp.start_vector.Z * 10000 ); break; case WineForceFeedbackEffectType_Periodic_SineWave: diff --git a/dlls/windows.gaming.input/provider.idl b/dlls/windows.gaming.input/provider.idl index 16d394e7afa..3baac4fe77d 100644 --- a/dlls/windows.gaming.input/provider.idl +++ b/dlls/windows.gaming.input/provider.idl @@ -38,6 +38,7 @@ namespace Windows.Gaming.Input.Custom { typedef struct WineGameControllerState WineGameControllerState; typedef struct WineGameControllerVibration WineGameControllerVibration; typedef struct WineConstantEffectParameters WineConstantEffectParameters; + typedef struct WineRampEffectParameters WineRampEffectParameters; typedef struct WineForceFeedbackEffectEnvelope WineForceFeedbackEffectEnvelope; typedef union WineForceFeedbackEffectParameters WineForceFeedbackEffectParameters; interface IWineGameControllerProvider; @@ -100,6 +101,17 @@ namespace Windows.Gaming.Input.Custom { FLOAT gain; }; + struct WineRampEffectParameters + { + WineForceFeedbackEffectType type; + Windows.Foundation.Numerics.Vector3 start_vector; + Windows.Foundation.Numerics.Vector3 end_vector; + Windows.Foundation.TimeSpan duration; + Windows.Foundation.TimeSpan start_delay; + UINT32 repeat_count; + FLOAT gain; + }; + struct WineForceFeedbackEffectEnvelope { FLOAT attack_gain; @@ -112,6 +124,7 @@ namespace Windows.Gaming.Input.Custom { { WineForceFeedbackEffectType type; WineConstantEffectParameters constant; + WineRampEffectParameters ramp; }; [ diff --git a/dlls/windows.gaming.input/ramp_effect.c b/dlls/windows.gaming.input/ramp_effect.c index 0a719b3e2a6..a498942cabe 100644 --- a/dlls/windows.gaming.input/ramp_effect.c +++ b/dlls/windows.gaming.input/ramp_effect.c @@ -99,9 +99,23 @@ static HRESULT WINAPI effect_GetTrustLevel( IRampForceEffect *iface, TrustLevel static HRESULT WINAPI effect_SetParameters( IRampForceEffect *iface, Vector3 start_vector, Vector3 end_vector, TimeSpan duration ) { - FIXME( "iface %p, start_vector %s, end_vector %s, duration %I64u stub!\n", iface, + WineForceFeedbackEffectParameters params = + { + .ramp = + { + .type = WineForceFeedbackEffectType_Ramp, + .start_vector = start_vector, + .end_vector = end_vector, + .duration = duration, + .repeat_count = 1, + }, + }; + struct ramp_effect *impl = impl_from_IRampForceEffect( iface ); + + TRACE( "iface %p, start_vector %s, end_vector %s, duration %I64u.\n", iface, debugstr_vector3( &start_vector ), debugstr_vector3( &end_vector ), duration.Duration ); - return E_NOTIMPL; + + return IWineForceFeedbackEffectImpl_put_Parameters( impl->IWineForceFeedbackEffectImpl_inner, params, NULL ); } static HRESULT WINAPI effect_SetParametersWithEnvelope( IRampForceEffect *iface, Vector3 start_vector, Vector3 end_vector, FLOAT attack_gain, @@ -109,11 +123,34 @@ static HRESULT WINAPI effect_SetParametersWithEnvelope( IRampForceEffect *iface, TimeSpan attack_duration, TimeSpan sustain_duration, TimeSpan release_duration, UINT32 repeat_count ) { - FIXME( "iface %p, start_vector %s, end_vector %s, attack_gain %f, sustain_gain %f, release_gain %f, start_delay %I64u, attack_duration %I64u, " - "sustain_duration %I64u, release_duration %I64u, repeat_count %u stub!\n", iface, debugstr_vector3( &start_vector ), debugstr_vector3( &end_vector ), + WineForceFeedbackEffectParameters params = + { + .ramp = + { + .type = WineForceFeedbackEffectType_Ramp, + .start_vector = start_vector, + .end_vector = end_vector, + .duration = {attack_duration.Duration + sustain_duration.Duration + release_duration.Duration}, + .start_delay = start_delay, + .repeat_count = repeat_count, + .gain = sustain_gain, + }, + }; + WineForceFeedbackEffectEnvelope envelope = + { + .attack_gain = attack_gain, + .release_gain = release_gain, + .attack_duration = attack_duration, + .release_duration = release_duration, + }; + struct ramp_effect *impl = impl_from_IRampForceEffect( iface ); + + TRACE( "iface %p, start_vector %s, end_vector %s, attack_gain %f, sustain_gain %f, release_gain %f, start_delay %I64u, attack_duration %I64u, " + "sustain_duration %I64u, release_duration %I64u, repeat_count %u.\n", iface, debugstr_vector3( &start_vector ), debugstr_vector3( &end_vector ), attack_gain, sustain_gain, release_gain, start_delay.Duration, attack_duration.Duration, sustain_duration.Duration, release_duration.Duration, repeat_count ); - return E_NOTIMPL; + + return IWineForceFeedbackEffectImpl_put_Parameters( impl->IWineForceFeedbackEffectImpl_inner, params, &envelope ); } static const struct IRampForceEffectVtbl effect_vtbl =