Commit 9d4a9e16 authored by Rémi Bernon's avatar Rémi Bernon Committed by Alexandre Julliard

joy.cpl: Use a struct list to keep created device effects.

parent 1c94551e
...@@ -33,6 +33,7 @@ ...@@ -33,6 +33,7 @@
#include "ole2.h" #include "ole2.h"
#include "wine/debug.h" #include "wine/debug.h"
#include "wine/list.h"
#include "resource.h" #include "resource.h"
...@@ -68,8 +69,9 @@ WINE_DEFAULT_DEBUG_CHANNEL(joycpl); ...@@ -68,8 +69,9 @@ WINE_DEFAULT_DEBUG_CHANNEL(joycpl);
#define NUM_PROPERTY_PAGES 3 #define NUM_PROPERTY_PAGES 3
struct Effect struct effect
{ {
struct list entry;
IDirectInputEffect *effect; IDirectInputEffect *effect;
}; };
...@@ -82,10 +84,9 @@ struct Joystick ...@@ -82,10 +84,9 @@ struct Joystick
BOOL forcefeedback; BOOL forcefeedback;
BOOL is_xinput; BOOL is_xinput;
BOOL has_override; BOOL has_override;
int num_effects;
int cur_effect; struct list effects;
int chosen_effect; IDirectInputEffect *effect_selected;
struct Effect *effects;
}; };
struct Graphics struct Graphics
...@@ -162,17 +163,14 @@ static BOOL CALLBACK enum_effects( const DIEFFECTINFOW *info, void *context ) ...@@ -162,17 +163,14 @@ static BOOL CALLBACK enum_effects( const DIEFFECTINFOW *info, void *context )
.lEnd = DI_FFNOMINALMAX, .lEnd = DI_FFNOMINALMAX,
}; };
IDirectInputEffect *effect; IDirectInputEffect *effect;
struct effect *entry;
HRESULT hr; HRESULT hr;
if (joystick->effects == NULL)
{
joystick->num_effects += 1;
return DIENUM_CONTINUE;
}
hr = IDirectInputDevice8_Acquire( joystick->device ); hr = IDirectInputDevice8_Acquire( joystick->device );
if (FAILED(hr)) return DIENUM_CONTINUE; if (FAILED(hr)) return DIENUM_CONTINUE;
if (!(entry = calloc( 1, sizeof(*entry) ))) return DIENUM_STOP;
if (IsEqualGUID( &info->guid, &GUID_RampForce )) if (IsEqualGUID( &info->guid, &GUID_RampForce ))
{ {
params.cbTypeSpecificParams = sizeof(ramp); params.cbTypeSpecificParams = sizeof(ramp);
...@@ -211,11 +209,12 @@ static BOOL CALLBACK enum_effects( const DIEFFECTINFOW *info, void *context ) ...@@ -211,11 +209,12 @@ static BOOL CALLBACK enum_effects( const DIEFFECTINFOW *info, void *context )
if (FAILED(hr)) if (FAILED(hr))
{ {
FIXME( "Failed to create effect with type %s, hr %#lx\n", debugstr_guid( &info->guid ), hr ); FIXME( "Failed to create effect with type %s, hr %#lx\n", debugstr_guid( &info->guid ), hr );
free( entry );
return DIENUM_CONTINUE; return DIENUM_CONTINUE;
} }
joystick->effects[joystick->cur_effect].effect = effect; entry->effect = effect;
joystick->cur_effect += 1; list_add_tail( &joystick->effects, &entry->entry );
return DIENUM_CONTINUE; return DIENUM_CONTINUE;
} }
...@@ -256,11 +255,13 @@ static BOOL CALLBACK enum_callback(const DIDEVICEINSTANCEW *instance, void *cont ...@@ -256,11 +255,13 @@ static BOOL CALLBACK enum_callback(const DIDEVICEINSTANCEW *instance, void *cont
joystick->num_buttons = caps.dwButtons; joystick->num_buttons = caps.dwButtons;
joystick->num_axes = caps.dwAxes; joystick->num_axes = caps.dwAxes;
joystick->forcefeedback = caps.dwFlags & DIDC_FORCEFEEDBACK; joystick->forcefeedback = caps.dwFlags & DIDC_FORCEFEEDBACK;
joystick->num_effects = 0;
IDirectInputDevice8_GetProperty(joystick->device, DIPROP_GUIDANDPATH, &prop_guid_path.diph); IDirectInputDevice8_GetProperty(joystick->device, DIPROP_GUIDANDPATH, &prop_guid_path.diph);
joystick->is_xinput = wcsstr(prop_guid_path.wszPath, L"&ig_") != NULL; joystick->is_xinput = wcsstr(prop_guid_path.wszPath, L"&ig_") != NULL;
list_init( &joystick->effects );
joystick->effect_selected = NULL;
if (joystick->forcefeedback) data->num_ff++; if (joystick->forcefeedback) data->num_ff++;
/* Set axis range to ease the GUI visualization */ /* Set axis range to ease the GUI visualization */
...@@ -275,15 +276,7 @@ static BOOL CALLBACK enum_callback(const DIDEVICEINSTANCEW *instance, void *cont ...@@ -275,15 +276,7 @@ static BOOL CALLBACK enum_callback(const DIDEVICEINSTANCEW *instance, void *cont
if (!joystick->forcefeedback) return DIENUM_CONTINUE; if (!joystick->forcefeedback) return DIENUM_CONTINUE;
/* Count device effects and then store them */
joystick->num_effects = 0;
joystick->effects = NULL;
IDirectInputDevice8_EnumEffects( joystick->device, enum_effects, (void *)joystick, 0 ); IDirectInputDevice8_EnumEffects( joystick->device, enum_effects, (void *)joystick, 0 );
joystick->effects = malloc(sizeof(struct Effect) * joystick->num_effects);
joystick->cur_effect = 0;
IDirectInputDevice8_EnumEffects( joystick->device, enum_effects, (void *)joystick, 0 );
joystick->num_effects = joystick->cur_effect;
return DIENUM_CONTINUE; return DIENUM_CONTINUE;
} }
...@@ -307,18 +300,17 @@ static void initialize_joysticks(struct JoystickData *data) ...@@ -307,18 +300,17 @@ static void initialize_joysticks(struct JoystickData *data)
*/ */
static void destroy_joysticks(struct JoystickData *data) static void destroy_joysticks(struct JoystickData *data)
{ {
int i, j; int i;
for (i = 0; i < data->num_joysticks; i++) for (i = 0; i < data->num_joysticks; i++)
{ {
struct effect *effect, *next_effect;
if (data->joysticks[i].forcefeedback && data->joysticks[i].num_effects > 0) LIST_FOR_EACH_ENTRY_SAFE( effect, next_effect, &data->joysticks[i].effects, struct effect, entry )
{ {
for (j = 0; j < data->joysticks[i].num_effects; j++) list_remove( &effect->entry );
if (data->joysticks[i].effects[j].effect) IDirectInputEffect_Release( effect->effect );
IDirectInputEffect_Release(data->joysticks[i].effects[j].effect); free( effect );
free(data->joysticks[i].effects);
} }
IDirectInputDevice8_Unacquire(data->joysticks[i].device); IDirectInputDevice8_Unacquire(data->joysticks[i].device);
...@@ -858,16 +850,16 @@ static void draw_ff_axis(HWND hwnd, struct JoystickData *data) ...@@ -858,16 +850,16 @@ static void draw_ff_axis(HWND hwnd, struct JoystickData *data)
static void initialize_effects_list(HWND hwnd, struct Joystick* joy) static void initialize_effects_list(HWND hwnd, struct Joystick* joy)
{ {
int i; struct effect *effect;
SendDlgItemMessageW(hwnd, IDC_FFEFFECTLIST, LB_RESETCONTENT, 0, 0); SendDlgItemMessageW(hwnd, IDC_FFEFFECTLIST, LB_RESETCONTENT, 0, 0);
for (i=0; i < joy->num_effects; i++) LIST_FOR_EACH_ENTRY( effect, &joy->effects, struct effect, entry )
{ {
DIEFFECTINFOW info = {.dwSize = sizeof(DIEFFECTINFOW)}; DIEFFECTINFOW info = {.dwSize = sizeof(DIEFFECTINFOW)};
GUID guid; GUID guid;
if (FAILED(IDirectInputEffect_GetEffectGuid( joy->effects[i].effect, &guid ))) continue; if (FAILED(IDirectInputEffect_GetEffectGuid( effect->effect, &guid ))) continue;
if (FAILED(IDirectInputDevice8_GetEffectInfo( joy->device, &info, &guid ))) continue; if (FAILED(IDirectInputDevice8_GetEffectInfo( joy->device, &info, &guid ))) continue;
SendDlgItemMessageW(hwnd, IDC_FFEFFECTLIST, LB_ADDSTRING, 0, (LPARAM)(info.tszName + 5)); SendDlgItemMessageW(hwnd, IDC_FFEFFECTLIST, LB_ADDSTRING, 0, (LPARAM)(info.tszName + 5));
} }
...@@ -883,11 +875,18 @@ static void ff_handle_joychange(HWND hwnd, struct JoystickData *data) ...@@ -883,11 +875,18 @@ static void ff_handle_joychange(HWND hwnd, struct JoystickData *data)
static void ff_handle_effectchange(HWND hwnd, struct Joystick *joy) static void ff_handle_effectchange(HWND hwnd, struct Joystick *joy)
{ {
int sel = SendDlgItemMessageW(hwnd, IDC_FFEFFECTLIST, LB_GETCURSEL, 0, 0); struct list *entry;
int sel;
sel = SendDlgItemMessageW(hwnd, IDC_FFEFFECTLIST, LB_GETCURSEL, 0, 0);
if (sel < 0) return; if (sel < 0) return;
joy->chosen_effect = sel; entry = list_head( &joy->effects );
while (sel-- && entry) entry = list_next( &joy->effects, entry );
if (!entry) return;
joy->effect_selected = LIST_ENTRY( entry, struct effect, entry )->effect;
IDirectInputDevice8_Unacquire(joy->device); IDirectInputDevice8_Unacquire(joy->device);
IDirectInputDevice8_SetCooperativeLevel(joy->device, GetAncestor(hwnd, GA_ROOT), DISCL_BACKGROUND|DISCL_EXCLUSIVE); IDirectInputDevice8_SetCooperativeLevel(joy->device, GetAncestor(hwnd, GA_ROOT), DISCL_BACKGROUND|DISCL_EXCLUSIVE);
IDirectInputDevice8_Acquire(joy->device); IDirectInputDevice8_Acquire(joy->device);
...@@ -904,8 +903,8 @@ static DWORD WINAPI ff_input_thread(void *param) ...@@ -904,8 +903,8 @@ static DWORD WINAPI ff_input_thread(void *param)
{ {
int i; int i;
struct Joystick *joy = &data->joysticks[data->chosen_joystick]; struct Joystick *joy = &data->joysticks[data->chosen_joystick];
int chosen_effect = joy->chosen_effect;
DWORD flags = DIEP_AXES | DIEP_DIRECTION | DIEP_NORESTART; DWORD flags = DIEP_AXES | DIEP_DIRECTION | DIEP_NORESTART;
IDirectInputEffect *effect;
LONG direction[3] = {0}; LONG direction[3] = {0};
DWORD axes[3] = {0}; DWORD axes[3] = {0};
DIEFFECT params = DIEFFECT params =
...@@ -920,12 +919,11 @@ static DWORD WINAPI ff_input_thread(void *param) ...@@ -920,12 +919,11 @@ static DWORD WINAPI ff_input_thread(void *param)
Sleep(TEST_POLL_TIME); Sleep(TEST_POLL_TIME);
/* Skip this if we have no effects */ if (!(effect = joy->effect_selected)) continue;
if (joy->num_effects == 0 || chosen_effect < 0 || !joy->effects[chosen_effect].effect) continue;
poll_input(joy, &state); poll_input(joy, &state);
IDirectInputEffect_GetParameters( joy->effects[chosen_effect].effect, &params, flags ); IDirectInputEffect_GetParameters( effect, &params, flags );
params.rgdwAxes[0] = state.lX; params.rgdwAxes[0] = state.lX;
params.rgdwAxes[1] = state.lY; params.rgdwAxes[1] = state.lY;
...@@ -939,8 +937,8 @@ static DWORD WINAPI ff_input_thread(void *param) ...@@ -939,8 +937,8 @@ static DWORD WINAPI ff_input_thread(void *param)
for (i=0; i < TEST_MAX_BUTTONS; i++) for (i=0; i < TEST_MAX_BUTTONS; i++)
if (state.rgbButtons[i]) if (state.rgbButtons[i])
{ {
IDirectInputEffect_SetParameters( joy->effects[chosen_effect].effect, &params, flags ); IDirectInputEffect_SetParameters( effect, &params, flags );
IDirectInputEffect_Start(joy->effects[chosen_effect].effect, 1, 0); IDirectInputEffect_Start( effect, 1, 0 );
break; break;
} }
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment