Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
W
wine-winehq
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Registry
Registry
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
wine
wine-winehq
Commits
e3431a02
Commit
e3431a02
authored
Jan 30, 2024
by
Arkadiusz Hiler
Committed by
Alexandre Julliard
Jan 30, 2024
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
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.
parent
94a7b32a
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
50 additions
and
24 deletions
+50
-24
hid.c
dlls/winebus.sys/hid.c
+50
-24
No files found.
dlls/winebus.sys/hid.c
View file @
e3431a02
...
@@ -209,13 +209,14 @@ static BOOL hid_device_add_hatswitch_count(struct unix_device *iface, BYTE count
...
@@ -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
"
);
ERR
(
"hatswitches should be added before buttons!
\n
"
);
else
if
((
iface
->
hid_device_state
.
bit_size
%
8
))
else
if
((
iface
->
hid_device_state
.
bit_size
%
8
))
ERR
(
"hatswitches should be byte aligned, missing padding!
\n
"
);
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
"
);
ERR
(
"report size overflow, too many elements!
\n
"
);
else
else
{
{
if
(
!
iface
->
hid_device_state
.
hatswitch_count
)
iface
->
hid_device_state
.
hatswitch_start
=
offset
;
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
.
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
;
return
TRUE
;
}
}
...
@@ -231,16 +232,28 @@ BOOL hid_device_add_hatswitch(struct unix_device *iface, INT count)
...
@@ -231,16 +232,28 @@ BOOL hid_device_add_hatswitch(struct unix_device *iface, INT count)
USAGE
(
1
,
HID_USAGE_GENERIC_HATSWITCH
),
USAGE
(
1
,
HID_USAGE_GENERIC_HATSWITCH
),
LOGICAL_MINIMUM
(
1
,
1
),
LOGICAL_MINIMUM
(
1
,
1
),
LOGICAL_MAXIMUM
(
1
,
8
),
LOGICAL_MAXIMUM
(
1
,
8
),
REPORT_SIZE
(
1
,
8
),
REPORT_SIZE
(
1
,
4
),
REPORT_COUNT
(
4
,
count
),
REPORT_COUNT
(
4
,
count
),
UNIT
(
1
,
0x0
),
/* None */
UNIT
(
1
,
0x0
),
/* None */
INPUT
(
1
,
Data
|
Var
|
Abs
|
Null
),
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
))
if
(
!
hid_device_add_hatswitch_count
(
iface
,
count
))
return
FALSE
;
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
,
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)
...
@@ -1409,8 +1422,9 @@ BOOL hid_device_set_button(struct unix_device *iface, ULONG index, BOOL is_set)
* +1 | 6 5 4
* +1 | 6 5 4
* v
* 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
;
*
x
=
*
y
=
0
;
if
(
value
==
8
||
value
==
1
||
value
==
2
)
*
y
=
-
1
;
if
(
value
==
8
||
value
==
1
||
value
==
2
)
*
y
=
-
1
;
if
(
value
==
6
||
value
==
5
||
value
==
4
)
*
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)
...
@@ -1418,49 +1432,61 @@ static void hatswitch_decompose(BYTE value, LONG *x, LONG *y)
if
(
value
==
2
||
value
==
3
||
value
==
4
)
*
x
=
+
1
;
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
;
BYTE
new_value
=
0
;
else
if
(
x
==
0
&&
y
<
0
)
*
value
=
1
;
if
(
x
==
0
&&
y
==
0
)
new_value
=
0
;
else
if
(
x
>
0
&&
y
<
0
)
*
value
=
2
;
else
if
(
x
==
0
&&
y
<
0
)
new_value
=
1
;
else
if
(
x
>
0
&&
y
==
0
)
*
value
=
3
;
else
if
(
x
>
0
&&
y
<
0
)
new_value
=
2
;
else
if
(
x
>
0
&&
y
>
0
)
*
value
=
4
;
else
if
(
x
>
0
&&
y
==
0
)
new_value
=
3
;
else
if
(
x
==
0
&&
y
>
0
)
*
value
=
5
;
else
if
(
x
>
0
&&
y
>
0
)
new_value
=
4
;
else
if
(
x
<
0
&&
y
>
0
)
*
value
=
6
;
else
if
(
x
==
0
&&
y
>
0
)
new_value
=
5
;
else
if
(
x
<
0
&&
y
==
0
)
*
value
=
7
;
else
if
(
x
<
0
&&
y
>
0
)
new_value
=
6
;
else
if
(
x
<
0
&&
y
<
0
)
*
value
=
8
;
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
)
BOOL
hid_device_set_hatswitch_x
(
struct
unix_device
*
iface
,
ULONG
index
,
LONG
new_x
)
{
{
struct
hid_device_state
*
state
=
&
iface
->
hid_device_state
;
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
;
LONG
x
,
y
;
if
(
index
>
state
->
hatswitch_count
)
return
FALSE
;
if
(
index
>
state
->
hatswitch_count
)
return
FALSE
;
hatswitch_decompose
(
state
->
report_buf
[
offset
],
&
x
,
&
y
);
hatswitch_decompose
(
state
->
report_buf
[
offset
],
index
,
&
x
,
&
y
);
hatswitch_compose
(
new_x
,
y
,
&
state
->
report_buf
[
offset
]);
hatswitch_compose
(
new_x
,
y
,
&
state
->
report_buf
[
offset
]
,
index
);
return
TRUE
;
return
TRUE
;
}
}
BOOL
hid_device_set_hatswitch_y
(
struct
unix_device
*
iface
,
ULONG
index
,
LONG
new_y
)
BOOL
hid_device_set_hatswitch_y
(
struct
unix_device
*
iface
,
ULONG
index
,
LONG
new_y
)
{
{
struct
hid_device_state
*
state
=
&
iface
->
hid_device_state
;
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
;
LONG
x
,
y
;
if
(
index
>
state
->
hatswitch_count
)
return
FALSE
;
if
(
index
>
state
->
hatswitch_count
)
return
FALSE
;
hatswitch_decompose
(
state
->
report_buf
[
offset
],
&
x
,
&
y
);
hatswitch_decompose
(
state
->
report_buf
[
offset
],
index
,
&
x
,
&
y
);
hatswitch_compose
(
x
,
new_y
,
&
state
->
report_buf
[
offset
]);
hatswitch_compose
(
x
,
new_y
,
&
state
->
report_buf
[
offset
]
,
index
);
return
TRUE
;
return
TRUE
;
}
}
BOOL
hid_device_move_hatswitch
(
struct
unix_device
*
iface
,
ULONG
index
,
LONG
x
,
LONG
y
)
BOOL
hid_device_move_hatswitch
(
struct
unix_device
*
iface
,
ULONG
index
,
LONG
x
,
LONG
y
)
{
{
struct
hid_device_state
*
state
=
&
iface
->
hid_device_state
;
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
;
LONG
old_x
,
old_y
;
if
(
index
>
state
->
hatswitch_count
)
return
FALSE
;
if
(
index
>
state
->
hatswitch_count
)
return
FALSE
;
hatswitch_decompose
(
state
->
report_buf
[
offset
],
&
old_x
,
&
old_y
);
hatswitch_decompose
(
state
->
report_buf
[
offset
],
index
,
&
old_x
,
&
old_y
);
hatswitch_compose
(
old_x
+
x
,
old_y
+
y
,
&
state
->
report_buf
[
offset
]);
hatswitch_compose
(
old_x
+
x
,
old_y
+
y
,
&
state
->
report_buf
[
offset
]
,
index
);
return
TRUE
;
return
TRUE
;
}
}
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment