Provide support for buttons and D-pads mapped to half axes, and
fix axes mapped to buttons and D-pads.
This commit is contained in:
parent
8ee44cc60c
commit
0c0c36be44
2 changed files with 100 additions and 75 deletions
|
@ -874,7 +874,7 @@ void Input::joy_button(int p_device, int p_button, bool p_pressed) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (map.type == TYPE_AXIS) {
|
if (map.type == TYPE_AXIS) {
|
||||||
_axis_event(p_device, map.index, p_pressed ? 1.0 : 0.0);
|
_axis_event(p_device, map.index, p_pressed ? map.value : 0.0);
|
||||||
}
|
}
|
||||||
// no event?
|
// no event?
|
||||||
}
|
}
|
||||||
|
@ -920,55 +920,42 @@ void Input::joy_axis(int p_device, int p_axis, const JoyAxis &p_value) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
JoyEvent map = _get_mapped_axis_event(map_db[joy.mapping], p_axis, p_value);
|
JoyEvent map = _get_mapped_axis_event(map_db[joy.mapping], p_axis, val);
|
||||||
|
|
||||||
if (map.type == TYPE_BUTTON) {
|
if (map.type == TYPE_BUTTON) {
|
||||||
if (map.index == JOY_BUTTON_DPAD_UP || map.index == JOY_BUTTON_DPAD_DOWN) {
|
bool pressed = map.value > 0.5;
|
||||||
bool pressed = p_value.value != 0.0f;
|
if (pressed == joy_buttons_pressed.has(_combine_device(map.index, p_device))) {
|
||||||
int button = p_value.value < 0 ? JOY_BUTTON_DPAD_UP : JOY_BUTTON_DPAD_DOWN;
|
// Button already pressed or released; so ignore.
|
||||||
|
return;
|
||||||
if (!pressed) {
|
|
||||||
if (joy_buttons_pressed.has(_combine_device(JOY_BUTTON_DPAD_UP, p_device))) {
|
|
||||||
_button_event(p_device, JOY_BUTTON_DPAD_UP, false);
|
|
||||||
}
|
}
|
||||||
|
_button_event(p_device, map.index, pressed);
|
||||||
|
|
||||||
|
// Ensure opposite D-Pad button is also released.
|
||||||
|
switch (map.index) {
|
||||||
|
case JOY_BUTTON_DPAD_UP:
|
||||||
if (joy_buttons_pressed.has(_combine_device(JOY_BUTTON_DPAD_DOWN, p_device))) {
|
if (joy_buttons_pressed.has(_combine_device(JOY_BUTTON_DPAD_DOWN, p_device))) {
|
||||||
_button_event(p_device, JOY_BUTTON_DPAD_DOWN, false);
|
_button_event(p_device, JOY_BUTTON_DPAD_DOWN, false);
|
||||||
}
|
}
|
||||||
|
break;
|
||||||
|
case JOY_BUTTON_DPAD_DOWN:
|
||||||
|
if (joy_buttons_pressed.has(_combine_device(JOY_BUTTON_DPAD_UP, p_device))) {
|
||||||
|
_button_event(p_device, JOY_BUTTON_DPAD_UP, false);
|
||||||
}
|
}
|
||||||
if (pressed == joy_buttons_pressed.has(_combine_device(button, p_device))) {
|
break;
|
||||||
return;
|
case JOY_BUTTON_DPAD_LEFT:
|
||||||
}
|
|
||||||
_button_event(p_device, button, true);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (map.index == JOY_BUTTON_DPAD_LEFT || map.index == JOY_BUTTON_DPAD_RIGHT) {
|
|
||||||
bool pressed = p_value.value != 0.0f;
|
|
||||||
int button = p_value.value < 0 ? JOY_BUTTON_DPAD_LEFT : JOY_BUTTON_DPAD_RIGHT;
|
|
||||||
|
|
||||||
if (!pressed) {
|
|
||||||
if (joy_buttons_pressed.has(_combine_device(JOY_BUTTON_DPAD_LEFT, p_device))) {
|
|
||||||
_button_event(p_device, JOY_BUTTON_DPAD_LEFT, false);
|
|
||||||
}
|
|
||||||
if (joy_buttons_pressed.has(_combine_device(JOY_BUTTON_DPAD_RIGHT, p_device))) {
|
if (joy_buttons_pressed.has(_combine_device(JOY_BUTTON_DPAD_RIGHT, p_device))) {
|
||||||
_button_event(p_device, JOY_BUTTON_DPAD_RIGHT, false);
|
_button_event(p_device, JOY_BUTTON_DPAD_RIGHT, false);
|
||||||
}
|
}
|
||||||
|
break;
|
||||||
|
case JOY_BUTTON_DPAD_RIGHT:
|
||||||
|
if (joy_buttons_pressed.has(_combine_device(JOY_BUTTON_DPAD_LEFT, p_device))) {
|
||||||
|
_button_event(p_device, JOY_BUTTON_DPAD_LEFT, false);
|
||||||
}
|
}
|
||||||
if (pressed == joy_buttons_pressed.has(_combine_device(button, p_device))) {
|
break;
|
||||||
return;
|
default:
|
||||||
|
// Nothing to do.
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
_button_event(p_device, button, true);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
float deadzone = p_value.min == 0 ? 0.5f : 0.0f;
|
|
||||||
bool pressed = p_value.value > deadzone;
|
|
||||||
if (pressed == joy_buttons_pressed.has(_combine_device(map.index, p_device))) {
|
|
||||||
// button already pressed or released, this is an axis bounce value
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
_button_event(p_device, map.index, pressed);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1007,18 +994,15 @@ void Input::joy_hat(int p_device, int p_val) {
|
||||||
|
|
||||||
int cur_val = joy_names[p_device].hat_current;
|
int cur_val = joy_names[p_device].hat_current;
|
||||||
|
|
||||||
if ((p_val & HAT_MASK_UP) != (cur_val & HAT_MASK_UP)) {
|
for (int hat_direction = 0, hat_mask = 1; hat_direction < HAT_MAX; hat_direction++, hat_mask <<= 1) {
|
||||||
_button_event(p_device, map[HAT_UP].index, p_val & HAT_MASK_UP);
|
if ((p_val & hat_mask) != (cur_val & hat_mask)) {
|
||||||
|
if (map[hat_direction].type == TYPE_BUTTON) {
|
||||||
|
_button_event(p_device, map[hat_direction].index, p_val & hat_mask);
|
||||||
}
|
}
|
||||||
|
if (map[hat_direction].type == TYPE_AXIS) {
|
||||||
if ((p_val & HAT_MASK_RIGHT) != (cur_val & HAT_MASK_RIGHT)) {
|
_axis_event(p_device, map[hat_direction].index, (p_val & hat_mask) ? map[hat_direction].value : 0.0);
|
||||||
_button_event(p_device, map[HAT_RIGHT].index, p_val & HAT_MASK_RIGHT);
|
|
||||||
}
|
}
|
||||||
if ((p_val & HAT_MASK_DOWN) != (cur_val & HAT_MASK_DOWN)) {
|
|
||||||
_button_event(p_device, map[HAT_DOWN].index, p_val & HAT_MASK_DOWN);
|
|
||||||
}
|
}
|
||||||
if ((p_val & HAT_MASK_LEFT) != (cur_val & HAT_MASK_LEFT)) {
|
|
||||||
_button_event(p_device, map[HAT_LEFT].index, p_val & HAT_MASK_LEFT);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
joy_names[p_device].hat_current = p_val;
|
joy_names[p_device].hat_current = p_val;
|
||||||
|
@ -1058,6 +1042,19 @@ Input::JoyEvent Input::_get_mapped_button_event(const JoyDeviceMapping &mapping,
|
||||||
return event;
|
return event;
|
||||||
case TYPE_AXIS:
|
case TYPE_AXIS:
|
||||||
event.index = binding.output.axis.axis;
|
event.index = binding.output.axis.axis;
|
||||||
|
switch (binding.output.axis.range) {
|
||||||
|
case POSITIVE_HALF_AXIS:
|
||||||
|
event.value = 1;
|
||||||
|
break;
|
||||||
|
case NEGATIVE_HALF_AXIS:
|
||||||
|
event.value = -1;
|
||||||
|
break;
|
||||||
|
case FULL_AXIS:
|
||||||
|
// It doesn't make sense for a button to map to a full axis,
|
||||||
|
// but keeping as a default for a trigger with a positive half-axis.
|
||||||
|
event.value = 1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
return event;
|
return event;
|
||||||
default:
|
default:
|
||||||
ERR_PRINT_ONCE("Joypad button mapping error.");
|
ERR_PRINT_ONCE("Joypad button mapping error.");
|
||||||
|
@ -1067,14 +1064,14 @@ Input::JoyEvent Input::_get_mapped_button_event(const JoyDeviceMapping &mapping,
|
||||||
return event;
|
return event;
|
||||||
}
|
}
|
||||||
|
|
||||||
Input::JoyEvent Input::_get_mapped_axis_event(const JoyDeviceMapping &mapping, int p_axis, const JoyAxis &p_value) {
|
Input::JoyEvent Input::_get_mapped_axis_event(const JoyDeviceMapping &mapping, int p_axis, float p_value) {
|
||||||
JoyEvent event;
|
JoyEvent event;
|
||||||
event.type = TYPE_MAX;
|
event.type = TYPE_MAX;
|
||||||
|
|
||||||
for (int i = 0; i < mapping.bindings.size(); i++) {
|
for (int i = 0; i < mapping.bindings.size(); i++) {
|
||||||
const JoyBinding binding = mapping.bindings[i];
|
const JoyBinding binding = mapping.bindings[i];
|
||||||
if (binding.inputType == TYPE_AXIS && binding.input.axis.axis == p_axis) {
|
if (binding.inputType == TYPE_AXIS && binding.input.axis.axis == p_axis) {
|
||||||
float value = p_value.value;
|
float value = p_value;
|
||||||
if (binding.input.axis.invert) {
|
if (binding.input.axis.invert) {
|
||||||
value = -value;
|
value = -value;
|
||||||
}
|
}
|
||||||
|
@ -1082,14 +1079,6 @@ Input::JoyEvent Input::_get_mapped_axis_event(const JoyDeviceMapping &mapping, i
|
||||||
(binding.input.axis.range == POSITIVE_HALF_AXIS && value > 0) ||
|
(binding.input.axis.range == POSITIVE_HALF_AXIS && value > 0) ||
|
||||||
(binding.input.axis.range == NEGATIVE_HALF_AXIS && value < 0)) {
|
(binding.input.axis.range == NEGATIVE_HALF_AXIS && value < 0)) {
|
||||||
event.type = binding.outputType;
|
event.type = binding.outputType;
|
||||||
switch (binding.outputType) {
|
|
||||||
case TYPE_BUTTON:
|
|
||||||
event.index = binding.output.button;
|
|
||||||
return event;
|
|
||||||
case TYPE_AXIS:
|
|
||||||
event.index = binding.output.axis.axis;
|
|
||||||
event.value = value;
|
|
||||||
if (binding.output.axis.range != binding.input.axis.range) {
|
|
||||||
float shifted_positive_value = 0;
|
float shifted_positive_value = 0;
|
||||||
switch (binding.input.axis.range) {
|
switch (binding.input.axis.range) {
|
||||||
case POSITIVE_HALF_AXIS:
|
case POSITIVE_HALF_AXIS:
|
||||||
|
@ -1102,6 +1091,28 @@ Input::JoyEvent Input::_get_mapped_axis_event(const JoyDeviceMapping &mapping, i
|
||||||
shifted_positive_value = (value + 1) / 2;
|
shifted_positive_value = (value + 1) / 2;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
switch (binding.outputType) {
|
||||||
|
case TYPE_BUTTON:
|
||||||
|
event.index = binding.output.button;
|
||||||
|
switch (binding.input.axis.range) {
|
||||||
|
case POSITIVE_HALF_AXIS:
|
||||||
|
event.value = shifted_positive_value;
|
||||||
|
break;
|
||||||
|
case NEGATIVE_HALF_AXIS:
|
||||||
|
event.value = 1 - shifted_positive_value;
|
||||||
|
break;
|
||||||
|
case FULL_AXIS:
|
||||||
|
// It doesn't make sense for a full axis to map to a button,
|
||||||
|
// but keeping as a default for a trigger with a positive half-axis.
|
||||||
|
event.value = (shifted_positive_value * 2) - 1;
|
||||||
|
;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return event;
|
||||||
|
case TYPE_AXIS:
|
||||||
|
event.index = binding.output.axis.axis;
|
||||||
|
event.value = value;
|
||||||
|
if (binding.output.axis.range != binding.input.axis.range) {
|
||||||
switch (binding.output.axis.range) {
|
switch (binding.output.axis.range) {
|
||||||
case POSITIVE_HALF_AXIS:
|
case POSITIVE_HALF_AXIS:
|
||||||
event.value = shifted_positive_value;
|
event.value = shifted_positive_value;
|
||||||
|
@ -1128,32 +1139,45 @@ void Input::_get_mapped_hat_events(const JoyDeviceMapping &mapping, int p_hat, J
|
||||||
for (int i = 0; i < mapping.bindings.size(); i++) {
|
for (int i = 0; i < mapping.bindings.size(); i++) {
|
||||||
const JoyBinding binding = mapping.bindings[i];
|
const JoyBinding binding = mapping.bindings[i];
|
||||||
if (binding.inputType == TYPE_HAT && binding.input.hat.hat == p_hat) {
|
if (binding.inputType == TYPE_HAT && binding.input.hat.hat == p_hat) {
|
||||||
int index;
|
int hat_direction;
|
||||||
switch (binding.input.hat.hat_mask) {
|
switch (binding.input.hat.hat_mask) {
|
||||||
case HAT_MASK_UP:
|
case HAT_MASK_UP:
|
||||||
index = 0;
|
hat_direction = HAT_UP;
|
||||||
break;
|
break;
|
||||||
case HAT_MASK_RIGHT:
|
case HAT_MASK_RIGHT:
|
||||||
index = 1;
|
hat_direction = HAT_RIGHT;
|
||||||
break;
|
break;
|
||||||
case HAT_MASK_DOWN:
|
case HAT_MASK_DOWN:
|
||||||
index = 2;
|
hat_direction = HAT_DOWN;
|
||||||
break;
|
break;
|
||||||
case HAT_MASK_LEFT:
|
case HAT_MASK_LEFT:
|
||||||
index = 3;
|
hat_direction = HAT_LEFT;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
ERR_PRINT_ONCE("Joypad button mapping error.");
|
ERR_PRINT_ONCE("Joypad button mapping error.");
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
r_events[index].type = binding.outputType;
|
r_events[hat_direction].type = binding.outputType;
|
||||||
switch (binding.outputType) {
|
switch (binding.outputType) {
|
||||||
case TYPE_BUTTON:
|
case TYPE_BUTTON:
|
||||||
r_events[index].index = binding.output.button;
|
r_events[hat_direction].index = binding.output.button;
|
||||||
break;
|
break;
|
||||||
case TYPE_AXIS:
|
case TYPE_AXIS:
|
||||||
r_events[index].index = binding.output.axis.axis;
|
r_events[hat_direction].index = binding.output.axis.axis;
|
||||||
|
switch (binding.output.axis.range) {
|
||||||
|
case POSITIVE_HALF_AXIS:
|
||||||
|
r_events[hat_direction].value = 1;
|
||||||
|
break;
|
||||||
|
case NEGATIVE_HALF_AXIS:
|
||||||
|
r_events[hat_direction].value = -1;
|
||||||
|
break;
|
||||||
|
case FULL_AXIS:
|
||||||
|
// It doesn't make sense for a hat direction to map to a full axis,
|
||||||
|
// but keeping as a default for a trigger with a positive half-axis.
|
||||||
|
r_events[hat_direction].value = 1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
ERR_PRINT_ONCE("Joypad button mapping error.");
|
ERR_PRINT_ONCE("Joypad button mapping error.");
|
||||||
|
@ -1213,12 +1237,12 @@ void Input::parse_mapping(String p_mapping) {
|
||||||
JoyAxisRange output_range = FULL_AXIS;
|
JoyAxisRange output_range = FULL_AXIS;
|
||||||
if (output[0] == '+' || output[0] == '-') {
|
if (output[0] == '+' || output[0] == '-') {
|
||||||
ERR_CONTINUE_MSG(output.length() < 2, String(entry[idx] + "\nInvalid output: " + entry[idx]));
|
ERR_CONTINUE_MSG(output.length() < 2, String(entry[idx] + "\nInvalid output: " + entry[idx]));
|
||||||
output = output.right(1);
|
|
||||||
if (output[0] == '+') {
|
if (output[0] == '+') {
|
||||||
output_range = POSITIVE_HALF_AXIS;
|
output_range = POSITIVE_HALF_AXIS;
|
||||||
} else if (output[0] == '-') {
|
} else if (output[0] == '-') {
|
||||||
output_range = NEGATIVE_HALF_AXIS;
|
output_range = NEGATIVE_HALF_AXIS;
|
||||||
}
|
}
|
||||||
|
output = output.right(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
JoyAxisRange input_range = FULL_AXIS;
|
JoyAxisRange input_range = FULL_AXIS;
|
||||||
|
@ -1232,6 +1256,7 @@ void Input::parse_mapping(String p_mapping) {
|
||||||
bool invert_axis = false;
|
bool invert_axis = false;
|
||||||
if (input[input.length() - 1] == '~') {
|
if (input[input.length() - 1] == '~') {
|
||||||
invert_axis = true;
|
invert_axis = true;
|
||||||
|
input = input.left(input.length() - 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
JoyButtonList output_button = _get_output_button(output);
|
JoyButtonList output_button = _get_output_button(output);
|
||||||
|
|
|
@ -217,7 +217,7 @@ private:
|
||||||
Vector<JoyDeviceMapping> map_db;
|
Vector<JoyDeviceMapping> map_db;
|
||||||
|
|
||||||
JoyEvent _get_mapped_button_event(const JoyDeviceMapping &mapping, int p_button);
|
JoyEvent _get_mapped_button_event(const JoyDeviceMapping &mapping, int p_button);
|
||||||
JoyEvent _get_mapped_axis_event(const JoyDeviceMapping &mapping, int p_axis, const JoyAxis &p_value);
|
JoyEvent _get_mapped_axis_event(const JoyDeviceMapping &mapping, int p_axis, float p_value);
|
||||||
void _get_mapped_hat_events(const JoyDeviceMapping &mapping, int p_hat, JoyEvent r_events[HAT_MAX]);
|
void _get_mapped_hat_events(const JoyDeviceMapping &mapping, int p_hat, JoyEvent r_events[HAT_MAX]);
|
||||||
JoyButtonList _get_output_button(String output);
|
JoyButtonList _get_output_button(String output);
|
||||||
JoyAxisList _get_output_axis(String output);
|
JoyAxisList _get_output_axis(String output);
|
||||||
|
|
Loading…
Reference in a new issue