winebus.sys: Use 4 bits for hat switches.
Declaring them as 8 bits crashes game due to how Unity's native hid support parses the data.
This commit is contained in:
parent
94a7b32a55
commit
e3431a02e1
1 changed files with 50 additions and 24 deletions
|
@ -209,13 +209,14 @@ static BOOL hid_device_add_hatswitch_count(struct unix_device *iface, BYTE count
|
|||
ERR("hatswitches should be added before buttons!\n");
|
||||
else if ((iface->hid_device_state.bit_size % 8))
|
||||
ERR("hatswitches should be byte aligned, missing padding!\n");
|
||||
else if (iface->hid_device_state.bit_size + 8 * count > 0x80000)
|
||||
else if (iface->hid_device_state.bit_size + 4 * (count + 1) > 0x80000)
|
||||
ERR("report size overflow, too many elements!\n");
|
||||
else
|
||||
{
|
||||
if (!iface->hid_device_state.hatswitch_count) iface->hid_device_state.hatswitch_start = offset;
|
||||
iface->hid_device_state.hatswitch_count += count;
|
||||
iface->hid_device_state.bit_size += 8 * count;
|
||||
iface->hid_device_state.bit_size += 4 * count;
|
||||
if (count % 2) iface->hid_device_state.bit_size += 4;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
@ -231,16 +232,28 @@ BOOL hid_device_add_hatswitch(struct unix_device *iface, INT count)
|
|||
USAGE(1, HID_USAGE_GENERIC_HATSWITCH),
|
||||
LOGICAL_MINIMUM(1, 1),
|
||||
LOGICAL_MAXIMUM(1, 8),
|
||||
REPORT_SIZE(1, 8),
|
||||
REPORT_SIZE(1, 4),
|
||||
REPORT_COUNT(4, count),
|
||||
UNIT(1, 0x0), /* None */
|
||||
INPUT(1, Data|Var|Abs|Null),
|
||||
};
|
||||
const BYTE template_pad[] =
|
||||
{
|
||||
REPORT_COUNT(1, 4),
|
||||
REPORT_SIZE(1, 1),
|
||||
INPUT(1, Cnst|Ary|Abs),
|
||||
};
|
||||
|
||||
if (!hid_device_add_hatswitch_count(iface, count))
|
||||
return FALSE;
|
||||
|
||||
return hid_report_descriptor_append(desc, template, sizeof(template));
|
||||
if (!hid_report_descriptor_append(desc, template, sizeof(template)))
|
||||
return FALSE;
|
||||
|
||||
if ((count % 2) && !hid_report_descriptor_append(desc, template_pad, sizeof(template_pad)))
|
||||
return FALSE;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static BOOL hid_device_add_axis_count(struct unix_device *iface, BOOL rel, BYTE count,
|
||||
|
@ -1409,8 +1422,9 @@ BOOL hid_device_set_button(struct unix_device *iface, ULONG index, BOOL is_set)
|
|||
* +1 | 6 5 4
|
||||
* v
|
||||
*/
|
||||
static void hatswitch_decompose(BYTE value, LONG *x, LONG *y)
|
||||
static void hatswitch_decompose(BYTE value, ULONG index, LONG *x, LONG *y)
|
||||
{
|
||||
value = (index % 2) ? (value >> 4) : (value & 0x0f);
|
||||
*x = *y = 0;
|
||||
if (value == 8 || value == 1 || value == 2) *y = -1;
|
||||
if (value == 6 || value == 5 || value == 4) *y = +1;
|
||||
|
@ -1418,49 +1432,61 @@ static void hatswitch_decompose(BYTE value, LONG *x, LONG *y)
|
|||
if (value == 2 || value == 3 || value == 4) *x = +1;
|
||||
}
|
||||
|
||||
static void hatswitch_compose(LONG x, LONG y, BYTE *value)
|
||||
static void hatswitch_compose(LONG x, LONG y, BYTE *value, ULONG index)
|
||||
{
|
||||
if (x == 0 && y == 0) *value = 0;
|
||||
else if (x == 0 && y < 0) *value = 1;
|
||||
else if (x > 0 && y < 0) *value = 2;
|
||||
else if (x > 0 && y == 0) *value = 3;
|
||||
else if (x > 0 && y > 0) *value = 4;
|
||||
else if (x == 0 && y > 0) *value = 5;
|
||||
else if (x < 0 && y > 0) *value = 6;
|
||||
else if (x < 0 && y == 0) *value = 7;
|
||||
else if (x < 0 && y < 0) *value = 8;
|
||||
BYTE new_value = 0;
|
||||
if (x == 0 && y == 0) new_value = 0;
|
||||
else if (x == 0 && y < 0) new_value = 1;
|
||||
else if (x > 0 && y < 0) new_value = 2;
|
||||
else if (x > 0 && y == 0) new_value = 3;
|
||||
else if (x > 0 && y > 0) new_value = 4;
|
||||
else if (x == 0 && y > 0) new_value = 5;
|
||||
else if (x < 0 && y > 0) new_value = 6;
|
||||
else if (x < 0 && y == 0) new_value = 7;
|
||||
else if (x < 0 && y < 0) new_value = 8;
|
||||
|
||||
if (index % 2)
|
||||
{
|
||||
*value &= 0xf;
|
||||
*value |= new_value << 4;
|
||||
}
|
||||
else
|
||||
{
|
||||
*value &= 0xf0;
|
||||
*value |= new_value;
|
||||
}
|
||||
}
|
||||
|
||||
BOOL hid_device_set_hatswitch_x(struct unix_device *iface, ULONG index, LONG new_x)
|
||||
{
|
||||
struct hid_device_state *state = &iface->hid_device_state;
|
||||
ULONG offset = state->hatswitch_start + index;
|
||||
ULONG offset = state->hatswitch_start + index / 2;
|
||||
LONG x, y;
|
||||
if (index > state->hatswitch_count) return FALSE;
|
||||
hatswitch_decompose(state->report_buf[offset], &x, &y);
|
||||
hatswitch_compose(new_x, y, &state->report_buf[offset]);
|
||||
hatswitch_decompose(state->report_buf[offset], index, &x, &y);
|
||||
hatswitch_compose(new_x, y, &state->report_buf[offset], index);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
BOOL hid_device_set_hatswitch_y(struct unix_device *iface, ULONG index, LONG new_y)
|
||||
{
|
||||
struct hid_device_state *state = &iface->hid_device_state;
|
||||
ULONG offset = state->hatswitch_start + index;
|
||||
ULONG offset = state->hatswitch_start + index / 2;
|
||||
LONG x, y;
|
||||
if (index > state->hatswitch_count) return FALSE;
|
||||
hatswitch_decompose(state->report_buf[offset], &x, &y);
|
||||
hatswitch_compose(x, new_y, &state->report_buf[offset]);
|
||||
hatswitch_decompose(state->report_buf[offset], index, &x, &y);
|
||||
hatswitch_compose(x, new_y, &state->report_buf[offset], index);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
BOOL hid_device_move_hatswitch(struct unix_device *iface, ULONG index, LONG x, LONG y)
|
||||
{
|
||||
struct hid_device_state *state = &iface->hid_device_state;
|
||||
ULONG offset = state->hatswitch_start + index;
|
||||
ULONG offset = state->hatswitch_start + index / 2;
|
||||
LONG old_x, old_y;
|
||||
if (index > state->hatswitch_count) return FALSE;
|
||||
hatswitch_decompose(state->report_buf[offset], &old_x, &old_y);
|
||||
hatswitch_compose(old_x + x, old_y + y, &state->report_buf[offset]);
|
||||
hatswitch_decompose(state->report_buf[offset], index, &old_x, &old_y);
|
||||
hatswitch_compose(old_x + x, old_y + y, &state->report_buf[offset], index);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue