Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
godot
Project
Overview
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
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
community
godot
Commits
1176e078
Commit
1176e078
authored
Apr 23, 2020
by
Marcel Admiraal
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Parse SDL game controller half axis and inverted axis entries.
parent
a92f5f30
Show whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
287 additions
and
120 deletions
+287
-120
input.cpp
core/input/input.cpp
+215
-102
input.h
core/input/input.h
+72
-7
input_builders.py
core/input/input_builders.py
+0
-11
No files found.
core/input/input.cpp
View file @
1176e078
...
...
@@ -831,21 +831,9 @@ void Input::joy_button(int p_device, int p_button, bool p_pressed) {
return
;
}
const
Map
<
int
,
JoyEvent
>::
Element
*
el
=
map_db
[
joy
.
mapping
].
buttons
.
find
(
p_button
);
if
(
!
el
)
{
//don't process un-mapped events for now, it could mess things up badly for devices with additional buttons/axis
//return _button_event(p_last_id, p_device, p_button, p_pressed);
return
;
}
JoyEvent
map
=
_get_mapped_button_event
(
map_db
[
joy
.
mapping
],
p_button
);
JoyEvent
map
=
el
->
get
();
if
(
map
.
type
==
TYPE_BUTTON
)
{
//fake additional axis event for triggers
if
(
map
.
index
==
JOY_L2
||
map
.
index
==
JOY_R2
)
{
float
value
=
p_pressed
?
1.0
f
:
0.0
f
;
int
axis
=
map
.
index
==
JOY_L2
?
JOY_ANALOG_L2
:
JOY_ANALOG_R2
;
_axis_event
(
p_device
,
axis
,
value
);
}
_button_event
(
p_device
,
map
.
index
,
p_pressed
);
return
;
}
...
...
@@ -901,13 +889,7 @@ void Input::joy_axis(int p_device, int p_axis, const JoyAxis &p_value) {
return
;
};
const
Map
<
int
,
JoyEvent
>::
Element
*
el
=
map_db
[
joy
.
mapping
].
axis
.
find
(
p_axis
);
if
(
!
el
)
{
//return _axis_event(p_last_id, p_device, p_axis, p_value);
return
;
};
JoyEvent
map
=
el
->
get
();
JoyEvent
map
=
_get_mapped_axis_event
(
map_db
[
joy
.
mapping
],
p_axis
);
if
(
map
.
type
==
TYPE_BUTTON
)
{
//send axis event for triggers
...
...
@@ -976,12 +958,26 @@ void Input::joy_hat(int p_device, int p_val) {
_THREAD_SAFE_METHOD_
;
const
Joypad
&
joy
=
joy_names
[
p_device
];
const
JoyEvent
*
map
;
JoyEvent
map
[
HAT_MAX
]
;
if
(
joy
.
mapping
==
-
1
)
{
map
=
hat_map_default
;
}
else
{
map
=
map_db
[
joy
.
mapping
].
hat
;
map
[
HAT_UP
].
type
=
TYPE_BUTTON
;
map
[
HAT_UP
].
index
=
SDL_BUTTON_DPAD_UP
;
map
[
HAT_UP
].
value
=
0
;
map
[
HAT_RIGHT
].
type
=
TYPE_BUTTON
;
map
[
HAT_RIGHT
].
index
=
SDL_BUTTON_DPAD_RIGHT
;
map
[
HAT_RIGHT
].
value
=
0
;
map
[
HAT_DOWN
].
type
=
TYPE_BUTTON
;
map
[
HAT_DOWN
].
index
=
SDL_BUTTON_DPAD_DOWN
;
map
[
HAT_DOWN
].
value
=
0
;
map
[
HAT_LEFT
].
type
=
TYPE_BUTTON
;
map
[
HAT_LEFT
].
index
=
SDL_BUTTON_DPAD_LEFT
;
map
[
HAT_LEFT
].
value
=
0
;
if
(
joy
.
mapping
!=
-
1
)
{
_get_mapped_hat_events
(
map_db
[
joy
.
mapping
],
0
,
map
);
};
int
cur_val
=
joy_names
[
p_device
].
hat_current
;
...
...
@@ -1025,50 +1021,145 @@ void Input::_axis_event(int p_device, int p_axis, float p_value) {
parse_input_event
(
ievent
);
};
Input
::
JoyEvent
Input
::
_
find_to_event
(
String
p_to
)
{
Input
::
JoyEvent
Input
::
_
get_mapped_button_event
(
const
JoyDeviceMapping
&
mapping
,
int
p_button
)
{
// string names of the SDL buttons in the same order as input_event.h godot buttons
static
const
char
*
buttons
[]
=
{
"a"
,
"b"
,
"x"
,
"y"
,
"leftshoulder"
,
"rightshoulder"
,
"lefttrigger"
,
"righttrigger"
,
"leftstick"
,
"rightstick"
,
"back"
,
"start"
,
"dpup"
,
"dpdown"
,
"dpleft"
,
"dpright"
,
"guide"
,
nullptr
}
;
JoyEvent
event
;
event
.
type
=
TYPE_MAX
;
static
const
char
*
axis
[]
=
{
"leftx"
,
"lefty"
,
"rightx"
,
"righty"
,
nullptr
};
for
(
int
i
=
0
;
i
<
mapping
.
bindings
.
size
();
i
++
)
{
const
SDLExtendedJoyBind
binding
=
mapping
.
bindings
[
i
];
if
(
binding
.
inputType
==
TYPE_BUTTON
&&
binding
.
input
.
button
==
p_button
)
{
event
.
type
=
binding
.
outputType
;
switch
(
binding
.
outputType
)
{
case
TYPE_BUTTON
:
event
.
index
=
binding
.
output
.
button
;
break
;
case
TYPE_AXIS
:
event
.
index
=
binding
.
output
.
axis
.
axis
;
break
;
default
:
ERR_PRINT_ONCE
(
"Joypad button mapping error."
);
}
}
}
return
event
;
}
JoyEvent
ret
;
ret
.
type
=
-
1
;
ret
.
index
=
0
;
Input
::
JoyEvent
Input
::
_get_mapped_axis_event
(
const
JoyDeviceMapping
&
mapping
,
int
p_axis
)
{
int
i
=
0
;
while
(
buttons
[
i
])
{
JoyEvent
event
;
event
.
type
=
TYPE_MAX
;
if
(
p_to
==
buttons
[
i
])
{
ret
.
type
=
TYPE_BUTTON
;
ret
.
index
=
i
;
ret
.
value
=
0
;
return
ret
;
};
++
i
;
};
for
(
int
i
=
0
;
i
<
mapping
.
bindings
.
size
();
i
++
)
{
const
SDLExtendedJoyBind
binding
=
mapping
.
bindings
[
i
];
if
(
binding
.
inputType
==
TYPE_AXIS
&&
binding
.
input
.
axis
.
axis
==
p_axis
)
{
event
.
type
=
binding
.
outputType
;
switch
(
binding
.
outputType
)
{
case
TYPE_BUTTON
:
event
.
index
=
binding
.
output
.
button
;
break
;
case
TYPE_AXIS
:
event
.
index
=
binding
.
output
.
axis
.
axis
;
break
;
default
:
ERR_PRINT_ONCE
(
"Joypad button mapping error."
);
}
}
}
return
event
;
}
i
=
0
;
while
(
axis
[
i
])
{
void
Input
::
_get_mapped_hat_events
(
const
JoyDeviceMapping
&
mapping
,
int
p_hat
,
JoyEvent
r_events
[])
{
if
(
p_to
==
axis
[
i
])
{
ret
.
type
=
TYPE_AXIS
;
ret
.
index
=
i
;
ret
.
value
=
0
;
return
ret
;
};
++
i
;
};
for
(
int
i
=
0
;
i
<
mapping
.
bindings
.
size
();
i
++
)
{
const
SDLExtendedJoyBind
binding
=
mapping
.
bindings
[
i
];
if
(
binding
.
inputType
==
TYPE_HAT
&&
binding
.
input
.
hat
.
hat
==
p_hat
)
{
return
ret
;
int
index
;
switch
(
binding
.
input
.
hat
.
hat_mask
)
{
case
HAT_MASK_UP
:
index
=
0
;
break
;
case
HAT_MASK_RIGHT
:
index
=
1
;
break
;
case
HAT_MASK_DOWN
:
index
=
2
;
break
;
case
HAT_MASK_LEFT
:
index
=
3
;
break
;
default
:
ERR_PRINT_ONCE
(
"Joypad button mapping error."
);
continue
;
}
r_events
[
index
].
type
=
binding
.
outputType
;
switch
(
binding
.
outputType
)
{
case
TYPE_BUTTON
:
r_events
[
index
].
index
=
binding
.
output
.
button
;
break
;
case
TYPE_AXIS
:
r_events
[
index
].
index
=
binding
.
output
.
axis
.
axis
;
break
;
default
:
ERR_PRINT_ONCE
(
"Joypad button mapping error."
);
}
}
}
}
static
const
char
*
sdl_buttons
[]
=
{
"a"
,
"b"
,
"x"
,
"y"
,
"back"
,
"guide"
,
"start"
,
"leftstick"
,
"rightstick"
,
"leftshoulder"
,
"rightshoulder"
,
"dpup"
,
"dpdown"
,
"dpleft"
,
"dpright"
,
nullptr
};
Input
::
SDLJoyButton
Input
::
_get_output_button
(
String
output
)
{
for
(
int
i
=
0
;
sdl_buttons
[
i
];
i
++
)
{
if
(
output
==
sdl_buttons
[
i
])
return
SDLJoyButton
(
i
);
}
return
SDLJoyButton
::
SDL_INVALID_BUTTON
;
}
static
const
char
*
sdl_axes
[]
=
{
"leftx"
,
"lefty"
,
"rightx"
,
"righty"
,
"lefttrigger"
,
"righttrigger"
,
nullptr
};
Input
::
SDLJoyAxis
Input
::
_get_output_axis
(
String
output
)
{
for
(
int
i
=
0
;
sdl_axes
[
i
];
i
++
)
{
if
(
output
==
sdl_axes
[
i
])
return
SDLJoyAxis
(
i
);
}
return
SDLJoyAxis
::
SDL_INVALID_AXIS
;
}
void
Input
::
parse_mapping
(
String
p_mapping
)
{
_THREAD_SAFE_METHOD_
;
JoyDeviceMapping
mapping
;
for
(
int
i
=
0
;
i
<
HAT_MAX
;
++
i
)
mapping
.
hat
[
i
].
index
=
1024
+
i
;
Vector
<
String
>
entry
=
p_mapping
.
split
(
","
);
if
(
entry
.
size
()
<
2
)
{
...
...
@@ -1087,45 +1178,83 @@ void Input::parse_mapping(String p_mapping) {
if
(
entry
[
idx
]
==
""
)
continue
;
String
from
=
entry
[
idx
].
get_slice
(
":"
,
1
).
replace
(
" "
,
""
);
String
to
=
entry
[
idx
].
get_slice
(
":"
,
0
).
replace
(
" "
,
""
);
String
output
=
entry
[
idx
].
get_slice
(
":"
,
0
).
replace
(
" "
,
""
);
String
input
=
entry
[
idx
].
get_slice
(
":"
,
1
).
replace
(
" "
,
""
);
ERR_CONTINUE_MSG
(
output
.
length
()
<
1
||
input
.
length
()
<
2
,
String
(
entry
[
idx
]
+
"
\n
Invalid device mapping entry: "
+
entry
[
idx
]));
JoyEvent
to_event
=
_find_to_event
(
to
);
if
(
to_event
.
type
==
-
1
)
if
(
output
==
"platform"
)
continue
;
String
etype
=
from
.
substr
(
0
,
1
);
if
(
etype
==
"a"
)
{
int
aid
=
from
.
substr
(
1
,
from
.
length
()
-
1
).
to_int
();
mapping
.
axis
[
aid
]
=
to_event
;
}
else
if
(
etype
==
"b"
)
{
int
bid
=
from
.
substr
(
1
,
from
.
length
()
-
1
).
to_int
();
mapping
.
buttons
[
bid
]
=
to_event
;
}
else
if
(
etype
==
"h"
)
{
int
hat_value
=
from
.
get_slice
(
"."
,
1
).
to_int
();
switch
(
hat_value
)
{
case
1
:
mapping
.
hat
[
HAT_UP
]
=
to_event
;
break
;
case
2
:
mapping
.
hat
[
HAT_RIGHT
]
=
to_event
;
JoyAxisRange
output_range
=
FULL_AXIS
;
if
(
output
[
0
]
==
'+'
||
output
[
0
]
==
'-'
)
{
ERR_CONTINUE_MSG
(
output
.
length
()
<
2
,
String
(
entry
[
idx
]
+
"
\n
Invalid output: "
+
entry
[
idx
]));
output
=
output
.
right
(
1
);
if
(
output
[
0
]
==
'+'
)
output_range
=
POSITIVE_HALF_AXIS
;
else
if
(
output
[
0
]
==
'-'
)
output_range
=
NEGATIVE_HALF_AXIS
;
}
JoyAxisRange
input_range
=
FULL_AXIS
;
if
(
input
[
0
]
==
'+'
)
{
input_range
=
POSITIVE_HALF_AXIS
;
input
=
input
.
right
(
1
);
}
else
if
(
input
[
0
]
==
'-'
)
{
input_range
=
NEGATIVE_HALF_AXIS
;
input
=
input
.
right
(
1
);
}
bool
invert_axis
=
false
;
if
(
input
[
input
.
length
()
-
1
]
==
'~'
)
invert_axis
=
true
;
SDLJoyButton
output_button
=
_get_output_button
(
output
);
SDLJoyAxis
output_axis
=
_get_output_axis
(
output
);
ERR_CONTINUE_MSG
(
output_button
==
SDL_INVALID_BUTTON
&&
output_axis
==
SDL_INVALID_AXIS
,
String
(
entry
[
idx
]
+
"
\n
Unrecognised output string: "
+
output
));
ERR_CONTINUE_MSG
(
output_button
!=
SDL_INVALID_BUTTON
&&
output_axis
!=
SDL_INVALID_AXIS
,
String
(
"BUG: Output string matched both button and axis: "
+
output
));
SDLExtendedJoyBind
binding
;
if
(
output_button
!=
SDL_INVALID_BUTTON
)
{
binding
.
outputType
=
TYPE_BUTTON
;
binding
.
output
.
button
=
output_button
;
}
else
if
(
output_axis
!=
SDL_INVALID_AXIS
)
{
binding
.
outputType
=
TYPE_AXIS
;
binding
.
output
.
axis
.
axis
=
output_axis
;
binding
.
output
.
axis
.
range
=
output_range
;
}
switch
(
input
[
0
])
{
case
'b'
:
binding
.
inputType
=
TYPE_BUTTON
;
binding
.
input
.
button
=
input
.
right
(
1
).
to_int
();
break
;
case
4
:
mapping
.
hat
[
HAT_DOWN
]
=
to_event
;
case
'a'
:
binding
.
inputType
=
TYPE_AXIS
;
binding
.
input
.
axis
.
axis
=
input
.
right
(
1
).
to_int
();
binding
.
input
.
axis
.
range
=
input_range
;
if
(
invert_axis
)
{
int
int_range
=
static_cast
<
int
>
(
input_range
);
int_range
=
-
int_range
;
binding
.
input
.
axis
.
range
=
static_cast
<
JoyAxisRange
>
(
int_range
);
}
break
;
case
8
:
mapping
.
hat
[
HAT_LEFT
]
=
to_event
;
case
'h'
:
ERR_CONTINUE_MSG
(
input
.
length
()
!=
4
||
input
[
2
]
!=
'.'
,
String
(
entry
[
idx
]
+
"
\n
Invalid hat input: "
+
input
));
binding
.
inputType
=
TYPE_HAT
;
binding
.
input
.
hat
.
hat
=
input
.
substr
(
1
,
1
).
to_int
();
binding
.
input
.
hat
.
hat_mask
=
static_cast
<
HatMask
>
(
input
.
right
(
3
).
to_int
());
break
;
default
:
ERR_CONTINUE_MSG
(
true
,
String
(
entry
[
idx
]
+
"
\n
Unrecognised input string: "
+
input
));
}
mapping
.
bindings
.
push_back
(
binding
);
};
};
};
map_db
.
push_back
(
mapping
);
//printf("added mapping with uuid %ls\n", mapping.uid.c_str());
};
void
Input
::
add_joy_mapping
(
String
p_mapping
,
bool
p_update_existing
)
{
...
...
@@ -1268,22 +1397,6 @@ Input::Input() {
event_dispatch_function
=
nullptr
;
default_shape
=
CURSOR_ARROW
;
hat_map_default
[
HAT_UP
].
type
=
TYPE_BUTTON
;
hat_map_default
[
HAT_UP
].
index
=
JOY_DPAD_UP
;
hat_map_default
[
HAT_UP
].
value
=
0
;
hat_map_default
[
HAT_RIGHT
].
type
=
TYPE_BUTTON
;
hat_map_default
[
HAT_RIGHT
].
index
=
JOY_DPAD_RIGHT
;
hat_map_default
[
HAT_RIGHT
].
value
=
0
;
hat_map_default
[
HAT_DOWN
].
type
=
TYPE_BUTTON
;
hat_map_default
[
HAT_DOWN
].
index
=
JOY_DPAD_DOWN
;
hat_map_default
[
HAT_DOWN
].
value
=
0
;
hat_map_default
[
HAT_LEFT
].
type
=
TYPE_BUTTON
;
hat_map_default
[
HAT_LEFT
].
index
=
JOY_DPAD_LEFT
;
hat_map_default
[
HAT_LEFT
].
value
=
0
;
fallback_mapping
=
-
1
;
// Parse default mappings.
...
...
core/input/input.h
View file @
1176e078
...
...
@@ -183,26 +183,91 @@ private:
TYPE_MAX
,
};
enum
SDLJoyButton
{
SDL_INVALID_BUTTON
=
-
1
,
SDL_BUTTON_A
,
SDL_BUTTON_B
,
SDL_BUTTON_X
,
SDL_BUTTON_Y
,
SDL_BUTTON_BACK
,
SDL_BUTTON_GUIDE
,
SDL_BUTTON_START
,
SDL_BUTTON_LEFTSTICK
,
SDL_BUTTON_RIGHTSTICK
,
SDL_BUTTON_LEFTSHOULDER
,
SDL_BUTTON_RIGHTSHOULDER
,
SDL_BUTTON_DPAD_UP
,
SDL_BUTTON_DPAD_DOWN
,
SDL_BUTTON_DPAD_LEFT
,
SDL_BUTTON_DPAD_RIGHT
,
SDL_BUTTON_MAX
};
enum
SDLJoyAxis
{
SDL_INVALID_AXIS
=
-
1
,
SDL_AXIS_LEFTX
,
SDL_AXIS_LEFTY
,
SDL_AXIS_RIGHTX
,
SDL_AXIS_RIGHTY
,
SDL_AXIS_TRIGGERLEFT
,
SDL_AXIS_TRIGGERRIGHT
,
SDL_AXIS_MAX
,
};
enum
JoyAxisRange
{
NEGATIVE_HALF_AXIS
=
-
1
,
FULL_AXIS
=
0
,
POSITIVE_HALF_AXIS
=
1
};
struct
JoyEvent
{
int
type
;
int
index
;
int
value
;
};
struct
JoyDeviceMapping
{
struct
SDLExtendedJoyBind
{
JoyType
inputType
;
union
{
int
button
;
struct
{
int
axis
;
JoyAxisRange
range
;
}
axis
;
struct
{
int
hat
;
HatMask
hat_mask
;
}
hat
;
}
input
;
JoyType
outputType
;
union
{
SDLJoyButton
button
;
struct
{
SDLJoyAxis
axis
;
JoyAxisRange
range
;
}
axis
;
}
output
;
};
struct
JoyDeviceMapping
{
String
uid
;
String
name
;
Map
<
int
,
JoyEvent
>
buttons
;
Map
<
int
,
JoyEvent
>
axis
;
JoyEvent
hat
[
HAT_MAX
];
Vector
<
SDLExtendedJoyBind
>
bindings
;
};
JoyEvent
hat_map_default
[
HAT_MAX
];
Vector
<
JoyDeviceMapping
>
map_db
;
JoyEvent
_find_to_event
(
String
p_to
);
JoyEvent
_get_mapped_button_event
(
const
JoyDeviceMapping
&
mapping
,
int
p_button
);
JoyEvent
_get_mapped_axis_event
(
const
JoyDeviceMapping
&
mapping
,
int
p_axis
);
void
_get_mapped_hat_events
(
const
JoyDeviceMapping
&
mapping
,
int
p_hat
,
JoyEvent
r_events
[
HAT_MAX
]);
SDLJoyButton
_get_output_button
(
String
output
);
SDLJoyAxis
_get_output_axis
(
String
output
);
void
_button_event
(
int
p_device
,
int
p_index
,
bool
p_pressed
);
void
_axis_event
(
int
p_device
,
int
p_axis
,
float
p_value
);
float
_handle_deadzone
(
int
p_device
,
int
p_axis
,
float
p_value
);
...
...
core/input/input_builders.py
View file @
1176e078
...
...
@@ -42,17 +42,6 @@ def make_default_controller_mappings(target, source, env):
src_path
,
current_platform
,
platform_mappings
[
current_platform
][
guid
]
)
)
valid_mapping
=
True
for
input_map
in
line_parts
[
2
:]:
if
"+"
in
input_map
or
"-"
in
input_map
or
"~"
in
input_map
:
g
.
write
(
"// WARNING - DISCARDED UNSUPPORTED MAPPING TYPE FROM DATABASE {}: {} {}
\n
"
.
format
(
src_path
,
current_platform
,
line
)
)
valid_mapping
=
False
break
if
valid_mapping
:
platform_mappings
[
current_platform
][
guid
]
=
line
platform_variables
=
{
...
...
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