dinput: Fix POV calculation.
Combine and simplify the POV calculations. Linux provides X,Y for the POV. While DirectInput returns dial-degrees*1000 (12 o-click is 0 degrees).
This commit is contained in:
parent
1fdc0230f0
commit
19183e71d4
|
@ -82,6 +82,9 @@ extern int id_to_object(LPCDIDATAFORMAT df, int id);
|
|||
extern int id_to_offset(const DataFormat *df, int id);
|
||||
extern int find_property(const DataFormat *df, LPCDIPROPHEADER ph);
|
||||
|
||||
/* Common joystick stuff */
|
||||
extern DWORD joystick_map_pov(POINTL *p);
|
||||
|
||||
/**
|
||||
* Callback Data used by specific callback
|
||||
* for EnumObject on 'W' interfaces
|
||||
|
|
|
@ -83,11 +83,6 @@ typedef struct {
|
|||
LONG lSaturation;
|
||||
} ObjProps;
|
||||
|
||||
typedef struct {
|
||||
LONG lX;
|
||||
LONG lY;
|
||||
} POV;
|
||||
|
||||
typedef struct JoystickImpl JoystickImpl;
|
||||
static const IDirectInputDevice8AVtbl JoystickAvt;
|
||||
static const IDirectInputDevice8WVtbl JoystickWvt;
|
||||
|
@ -107,7 +102,7 @@ struct JoystickImpl
|
|||
int *axis_map;
|
||||
int axes;
|
||||
int buttons;
|
||||
POV povs[4];
|
||||
POINTL povs[4];
|
||||
};
|
||||
|
||||
static const GUID DInput_Wine_Joystick_GUID = { /* 9e573ed9-7734-11d2-8d4a-23903fb6bdf7 */
|
||||
|
@ -506,7 +501,10 @@ static HRESULT alloc_device(REFGUID rguid, const void *jvt, IDirectInputImpl *di
|
|||
if (wine_obj < 8)
|
||||
df->rgodf[idx++].dwType = DIDFT_MAKEINSTANCE(wine_obj) | DIDFT_ABSAXIS;
|
||||
else
|
||||
{
|
||||
df->rgodf[idx++].dwType = DIDFT_MAKEINSTANCE(wine_obj - 8) | DIDFT_POV;
|
||||
i++; /* POV takes 2 axes */
|
||||
}
|
||||
}
|
||||
for (i = 0; i < newDevice->buttons; i++)
|
||||
{
|
||||
|
@ -700,34 +698,6 @@ static LONG map_axis(JoystickImpl * This, short val, short index)
|
|||
return fret;
|
||||
}
|
||||
|
||||
static LONG calculate_pov(JoystickImpl *This, int index)
|
||||
{
|
||||
if (This->povs[index].lX < -16384) {
|
||||
if (This->povs[index].lY < -16384)
|
||||
This->js.rgdwPOV[index] = 31500;
|
||||
else if (This->povs[index].lY > 16384)
|
||||
This->js.rgdwPOV[index] = 22500;
|
||||
else
|
||||
This->js.rgdwPOV[index] = 27000;
|
||||
} else if (This->povs[index].lX > 16384) {
|
||||
if (This->povs[index].lY < -16384)
|
||||
This->js.rgdwPOV[index] = 4500;
|
||||
else if (This->povs[index].lY > 16384)
|
||||
This->js.rgdwPOV[index] = 13500;
|
||||
else
|
||||
This->js.rgdwPOV[index] = 9000;
|
||||
} else {
|
||||
if (This->povs[index].lY < -16384)
|
||||
This->js.rgdwPOV[index] = 0;
|
||||
else if (This->povs[index].lY > 16384)
|
||||
This->js.rgdwPOV[index] = 18000;
|
||||
else
|
||||
This->js.rgdwPOV[index] = -1;
|
||||
}
|
||||
|
||||
return This->js.rgdwPOV[index];
|
||||
}
|
||||
|
||||
static void joy_polldev(JoystickImpl *This) {
|
||||
struct pollfd plfd;
|
||||
struct js_event jse;
|
||||
|
@ -761,71 +731,37 @@ static void joy_polldev(JoystickImpl *This) {
|
|||
{
|
||||
int number = This->axis_map[jse.number]; /* wine format object index */
|
||||
|
||||
if (number < 12)
|
||||
{
|
||||
if (number < 0) return;
|
||||
inst_id = DIDFT_MAKEINSTANCE(number) | (number < 8 ? DIDFT_ABSAXIS : DIDFT_POV);
|
||||
value = map_axis(This, jse.value, id_to_object(This->base.data_format.wine_df, inst_id));
|
||||
/* FIXME do deadzone and saturation here */
|
||||
|
||||
TRACE("changing axis %d => %d\n", jse.number, number);
|
||||
switch (number) {
|
||||
case 0:
|
||||
This->js.lX = value;
|
||||
break;
|
||||
case 1:
|
||||
This->js.lY = value;
|
||||
break;
|
||||
case 2:
|
||||
This->js.lZ = value;
|
||||
break;
|
||||
case 3:
|
||||
This->js.lRx = value;
|
||||
break;
|
||||
case 4:
|
||||
This->js.lRy = value;
|
||||
break;
|
||||
case 5:
|
||||
This->js.lRz = value;
|
||||
break;
|
||||
case 6:
|
||||
This->js.rglSlider[0] = value;
|
||||
break;
|
||||
case 7:
|
||||
This->js.rglSlider[1] = value;
|
||||
break;
|
||||
case 8:
|
||||
/* FIXME don't go off array */
|
||||
if (This->axis_map[jse.number + 1] == number)
|
||||
This->povs[0].lX = jse.value;
|
||||
else if (This->axis_map[jse.number - 1] == number)
|
||||
This->povs[0].lY = jse.value;
|
||||
value = calculate_pov(This, 0);
|
||||
break;
|
||||
case 9:
|
||||
if (This->axis_map[jse.number + 1] == number)
|
||||
This->povs[1].lX = jse.value;
|
||||
else if (This->axis_map[jse.number - 1] == number)
|
||||
This->povs[1].lY = jse.value;
|
||||
value = calculate_pov(This, 1);
|
||||
break;
|
||||
case 10:
|
||||
if (This->axis_map[jse.number + 1] == number)
|
||||
This->povs[2].lX = jse.value;
|
||||
else if (This->axis_map[jse.number - 1] == number)
|
||||
This->povs[2].lY = jse.value;
|
||||
value = calculate_pov(This, 2);
|
||||
break;
|
||||
case 11:
|
||||
if (This->axis_map[jse.number + 1] == number)
|
||||
This->povs[3].lX = jse.value;
|
||||
else if (This->axis_map[jse.number - 1] == number)
|
||||
This->povs[3].lY = jse.value;
|
||||
value = calculate_pov(This, 3);
|
||||
switch (number)
|
||||
{
|
||||
case 0: This->js.lX = value; break;
|
||||
case 1: This->js.lY = value; break;
|
||||
case 2: This->js.lZ = value; break;
|
||||
case 3: This->js.lRx = value; break;
|
||||
case 4: This->js.lRy = value; break;
|
||||
case 5: This->js.lRz = value; break;
|
||||
case 6: This->js.rglSlider[0] = value; break;
|
||||
case 7: This->js.rglSlider[1] = value; break;
|
||||
case 8: case 9: case 10: case 11:
|
||||
{
|
||||
int idx = number - 8;
|
||||
|
||||
if (jse.number % 2)
|
||||
This->povs[idx].y = jse.value;
|
||||
else
|
||||
This->povs[idx].x = jse.value;
|
||||
|
||||
This->js.rgdwPOV[idx] = value = joystick_map_pov(&This->povs[idx]);
|
||||
break;
|
||||
}
|
||||
} else
|
||||
default:
|
||||
WARN("axis %d not supported\n", number);
|
||||
}
|
||||
}
|
||||
if (inst_id >= 0)
|
||||
queue_event((LPDIRECTINPUTDEVICE8A)This,
|
||||
id_to_offset(&This->base.data_format, inst_id),
|
||||
|
|
|
@ -65,6 +65,26 @@
|
|||
|
||||
WINE_DEFAULT_DEBUG_CHANNEL(dinput);
|
||||
|
||||
|
||||
/*
|
||||
* Maps POV x & y event values to a DX "clock" position:
|
||||
* 0
|
||||
* 31500 4500
|
||||
* 27000 -1 9000
|
||||
* 22500 13500
|
||||
* 18000
|
||||
*/
|
||||
DWORD joystick_map_pov(POINTL *p)
|
||||
{
|
||||
if (p->x > 0)
|
||||
return p->y < 0 ? 4500 : !p->y ? 9000 : 13500;
|
||||
else if (p->x < 0)
|
||||
return p->y < 0 ? 31500 : !p->y ? 27000 : 22500;
|
||||
else
|
||||
return p->y < 0 ? 0 : !p->y ? -1 : 18000;
|
||||
}
|
||||
|
||||
|
||||
#ifdef HAVE_CORRECT_LINUXINPUT_H
|
||||
|
||||
#define EVDEVPREFIX "/dev/input/event"
|
||||
|
@ -139,6 +159,7 @@ struct JoystickImpl
|
|||
struct ObjProps props[ABS_MAX];
|
||||
|
||||
int axes[ABS_MAX];
|
||||
POINTL povs[4];
|
||||
|
||||
/* LUT for KEY_ to offset in rgbButtons */
|
||||
BYTE buttons[KEY_MAX];
|
||||
|
@ -153,7 +174,6 @@ struct JoystickImpl
|
|||
};
|
||||
|
||||
static void fake_current_js_state(JoystickImpl *ji);
|
||||
static DWORD map_pov(int event_value, int is_x);
|
||||
static void find_joydevs(void);
|
||||
|
||||
/* This GUID is slightly different from the linux joystick one. Take note. */
|
||||
|
@ -596,31 +616,6 @@ static void fake_current_js_state(JoystickImpl *ji)
|
|||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Maps an event value to a DX "clock" position:
|
||||
* 0
|
||||
* 27000 -1 9000
|
||||
* 18000
|
||||
*/
|
||||
static DWORD map_pov(int event_value, int is_x)
|
||||
{
|
||||
DWORD ret = -1;
|
||||
if (is_x) {
|
||||
if (event_value<0) {
|
||||
ret = 27000;
|
||||
} else if (event_value>0) {
|
||||
ret = 9000;
|
||||
}
|
||||
} else {
|
||||
if (event_value<0) {
|
||||
ret = 0;
|
||||
} else if (event_value>0) {
|
||||
ret = 18000;
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* convert wine format offset to user format object index */
|
||||
static void joy_polldev(JoystickImpl *This)
|
||||
{
|
||||
|
@ -678,25 +673,21 @@ static void joy_polldev(JoystickImpl *This)
|
|||
case ABS_RZ: This->js.lRz = value; break;
|
||||
case ABS_THROTTLE: This->js.rglSlider[0] = value; break;
|
||||
case ABS_RUDDER: This->js.rglSlider[1] = value; break;
|
||||
case ABS_HAT0X:
|
||||
case ABS_HAT0Y:
|
||||
This->js.rgdwPOV[0] = value = map_pov(ie.value, ie.code==ABS_HAT0X);
|
||||
break;
|
||||
case ABS_HAT1X:
|
||||
case ABS_HAT1Y:
|
||||
This->js.rgdwPOV[1] = value = map_pov(ie.value, ie.code==ABS_HAT1X);
|
||||
break;
|
||||
case ABS_HAT2X:
|
||||
case ABS_HAT2Y:
|
||||
This->js.rgdwPOV[2] = value = map_pov(ie.value, ie.code==ABS_HAT2X);
|
||||
break;
|
||||
case ABS_HAT3X:
|
||||
case ABS_HAT3Y:
|
||||
This->js.rgdwPOV[3] = value = map_pov(ie.value, ie.code==ABS_HAT3X);
|
||||
case ABS_HAT0X: case ABS_HAT0Y: case ABS_HAT1X: case ABS_HAT1Y:
|
||||
case ABS_HAT2X: case ABS_HAT2Y: case ABS_HAT3X: case ABS_HAT3Y:
|
||||
{
|
||||
int idx = (ie.code - ABS_HAT0X) / 2;
|
||||
|
||||
if (ie.code % 2)
|
||||
This->povs[idx].y = ie.value;
|
||||
else
|
||||
This->povs[idx].x = ie.value;
|
||||
|
||||
This->js.rgdwPOV[idx] = value = joystick_map_pov(&This->povs[idx]);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
FIXME("unhandled joystick axis event (code %d, value %d)\n",ie.code,ie.value);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue