windows.gaming.input: Fix magnitude sign for constant and ramp effects.

The magnitude already carries the sign of X direction. Having a signed
direction will inverse the effective direction. The Y and Z direction
sign and magnitude seem to be ignored.
This commit is contained in:
Rémi Bernon 2023-01-02 13:48:20 +01:00 committed by Alexandre Julliard
parent 9d06d700e8
commit 4466e2c24c
2 changed files with 7 additions and 20 deletions

View file

@ -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 =

View file

@ -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( &params, &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 );