mirror of
https://github.com/open-goal/jak-project.git
synced 2024-11-23 14:20:07 +00:00
game: Fix issues related to remapping with SDL axii's (ie. triggers) (#3294)
This was just not implemented end to end. There are still two notable issues, one that I can live with, one I need to narrow down eventually: 1. Rebinding confirm buttons with trigger (ie. X) behaviour is not 100% as it should be. I fixed it enough that I can live with it but it's still not proper. The difficulty is that unlike a button it will re-trigger the pressed state on the journey back to neutral (aka unpressed). 2. If you change the bind for the confirm button, then reset your bindings, the next confirm input is eaten. This is unrelated to these changes but I briefly looked into it and was unable to find the root cause.
This commit is contained in:
parent
4cccaf2645
commit
a80cff9a4c
@ -91,6 +91,23 @@ void GameController::process_event(const SDL_Event& event,
|
||||
binds.button_axii.find(event.caxis.axis) != binds.button_axii.end()) {
|
||||
// Binding re-assignment
|
||||
if (bind_assignment) {
|
||||
// In the event that the user binds an analog input to the confirm binds
|
||||
// (ie. a trigger on X) we wait until it hits a neutral position (0)
|
||||
// before proceeding to rebind.
|
||||
//
|
||||
// TODO - this still isn't perfect as the data mutation below will trigger it after the bind
|
||||
// assignment has been set but atleast it's in a mostly working state right now
|
||||
if (!bind_assignment->seen_controller_confirm_neutral) {
|
||||
for (const auto& confirm_bind : bind_assignment->controller_confirmation_binds) {
|
||||
if (confirm_bind.sdl_idx == event.caxis.axis) {
|
||||
if (event.caxis.value <= 0) {
|
||||
bind_assignment->seen_controller_confirm_neutral = true;
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (bind_assignment->device_type == InputDeviceType::CONTROLLER &&
|
||||
!bind_assignment->for_analog) {
|
||||
binds.assign_button_bind(event.caxis.axis, bind_assignment.value(), true);
|
||||
|
@ -122,10 +122,10 @@ void KeyboardDevice::process_event(const SDL_Event& event,
|
||||
// modifiers are instead inspected on a KEYUP, however if it's one of the keys
|
||||
// for triggering the binding assignment, and it's the first time we've seen it -- we ignore
|
||||
// it
|
||||
if (!bind_assignment->seen_confirm_up) {
|
||||
if (!bind_assignment->seen_keyboard_confirm_up) {
|
||||
for (const auto& confirm_bind : bind_assignment->keyboard_confirmation_binds) {
|
||||
if (confirm_bind.sdl_idx == key_event.keysym.sym) {
|
||||
bind_assignment->seen_confirm_up = true;
|
||||
bind_assignment->seen_keyboard_confirm_up = true;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
@ -150,7 +150,7 @@ std::vector<InputBindingInfo> InputBindingGroups::lookup_analog_binds(PadData::A
|
||||
InputBindingInfo new_info;
|
||||
switch (device_type) {
|
||||
case KEYBOARD:
|
||||
new_info = InputBindingInfo(bind, device_type, sdl_code);
|
||||
new_info = InputBindingInfo(bind, device_type, sdl_code, false);
|
||||
break;
|
||||
default:
|
||||
new_info.host_name = "TODO - NON-KB ANALOG BIND LOOKUP";
|
||||
@ -176,7 +176,7 @@ std::vector<InputBindingInfo> InputBindingGroups::lookup_button_binds(PadData::B
|
||||
if (bind.pad_data_index != idx) {
|
||||
continue;
|
||||
}
|
||||
InputBindingInfo new_info(bind, device_type, sdl_code);
|
||||
InputBindingInfo new_info(bind, device_type, sdl_code, false);
|
||||
entry.push_back(new_info);
|
||||
}
|
||||
}
|
||||
@ -185,7 +185,7 @@ std::vector<InputBindingInfo> InputBindingGroups::lookup_button_binds(PadData::B
|
||||
if (bind.pad_data_index != idx) {
|
||||
continue;
|
||||
}
|
||||
InputBindingInfo new_info(bind, device_type, sdl_code);
|
||||
InputBindingInfo new_info(bind, device_type, sdl_code, true);
|
||||
entry.push_back(new_info);
|
||||
}
|
||||
}
|
||||
@ -309,7 +309,7 @@ void InputBindingGroups::assign_button_bind(u32 sdl_idx,
|
||||
// unmapped
|
||||
const auto current_button_binds = lookup_button_binds((PadData::ButtonIndex)bind_meta.pad_idx);
|
||||
const auto current_analog_bind = find_analog_bind_from_sdl_idx(sdl_idx, modifiers);
|
||||
if (buttons.find(sdl_idx) != buttons.end()) {
|
||||
if (!analog_button && buttons.find(sdl_idx) != buttons.end()) {
|
||||
const auto existing_binds = buttons.at(sdl_idx);
|
||||
if (analog_button) {
|
||||
button_axii[sdl_idx] = {InputBinding((PadData::ButtonIndex)bind_meta.pad_idx, modifiers)};
|
||||
@ -324,6 +324,22 @@ void InputBindingGroups::assign_button_bind(u32 sdl_idx,
|
||||
buttons[current_button_binds.front().sdl_idx] = existing_binds;
|
||||
}
|
||||
}
|
||||
} else if (analog_button && button_axii.find(sdl_idx) != button_axii.end()) {
|
||||
// TODO - cleanup this duplication
|
||||
const auto existing_binds = button_axii.at(sdl_idx);
|
||||
if (analog_button) {
|
||||
button_axii[sdl_idx] = {InputBinding((PadData::ButtonIndex)bind_meta.pad_idx, modifiers)};
|
||||
} else {
|
||||
buttons[sdl_idx] = {InputBinding((PadData::ButtonIndex)bind_meta.pad_idx, modifiers)};
|
||||
}
|
||||
// there already a bind, so swap (as long as it's not the same key)
|
||||
if (!current_button_binds.empty() && current_button_binds.front().sdl_idx != (s32)sdl_idx) {
|
||||
if (current_button_binds.front().analog_button) {
|
||||
button_axii[current_button_binds.front().sdl_idx] = existing_binds;
|
||||
} else {
|
||||
buttons[current_button_binds.front().sdl_idx] = existing_binds;
|
||||
}
|
||||
}
|
||||
} else if (!current_button_binds.empty() && current_analog_bind.has_value()) {
|
||||
if (analog_button) {
|
||||
button_axii[sdl_idx] = {InputBinding((PadData::ButtonIndex)bind_meta.pad_idx, modifiers)};
|
||||
@ -357,12 +373,19 @@ void InputBindingGroups::set_bindings(const InputBindingGroups& binds) {
|
||||
|
||||
InputBindingInfo::InputBindingInfo(const InputBinding bind,
|
||||
const InputDeviceType device_type,
|
||||
const s32 sdl_code)
|
||||
: sdl_idx(sdl_code), pad_idx(bind.pad_data_index), modifiers(bind.modifiers) {
|
||||
analog_button = false;
|
||||
const s32 sdl_code,
|
||||
const bool _analog_button)
|
||||
: sdl_idx(sdl_code),
|
||||
pad_idx(bind.pad_data_index),
|
||||
modifiers(bind.modifiers),
|
||||
analog_button(_analog_button) {
|
||||
switch (device_type) {
|
||||
case CONTROLLER:
|
||||
host_name = sdl_util::get_controller_button_name(sdl_code);
|
||||
if (analog_button) {
|
||||
host_name = sdl_util::get_controller_axis_name(sdl_code);
|
||||
} else {
|
||||
host_name = sdl_util::get_controller_button_name(sdl_code);
|
||||
}
|
||||
break;
|
||||
case KEYBOARD:
|
||||
host_name = sdl_util::get_keyboard_button_name(sdl_code, modifiers);
|
||||
|
@ -219,7 +219,10 @@ struct InputBindingInfo {
|
||||
InputModifiers modifiers;
|
||||
|
||||
InputBindingInfo() = default;
|
||||
InputBindingInfo(const InputBinding bind, const InputDeviceType device_type, const s32 sdl_code);
|
||||
InputBindingInfo(const InputBinding bind,
|
||||
const InputDeviceType device_type,
|
||||
const s32 sdl_code,
|
||||
const bool analog_button);
|
||||
};
|
||||
|
||||
// Contains all info related to the current binding we are waiting for
|
||||
@ -230,18 +233,21 @@ struct InputBindAssignmentMeta {
|
||||
bool for_analog = false;
|
||||
bool for_analog_minimum = false;
|
||||
|
||||
// For only rebinding keyboards, we have to know what keys were originally bound to the
|
||||
// For only some rebindings, we have to know what keys were originally bound to the
|
||||
// confirmation buttons this is because the user has to hit said key to initiate waiting for the
|
||||
// new assignment
|
||||
//
|
||||
// For most input sources this doesn't matter because we listen for the DOWN event, but in order
|
||||
// to allow modifiers as binds (ie. Shift for X) we have to listen to UP events as well (only for
|
||||
// the modifiers)
|
||||
// the modifiers). This is also relevant for analog rebinds as the transition from fully pressed
|
||||
// to unpressed triggers another press.
|
||||
//
|
||||
// TLDR - we ignore the first UP event if it was bound to a confirmation key. Additionally, this
|
||||
// depends on the game as Jak 1 treats X or O as a confirm key...
|
||||
std::vector<InputBindingInfo> keyboard_confirmation_binds = {};
|
||||
bool seen_confirm_up = false;
|
||||
bool seen_keyboard_confirm_up = false;
|
||||
std::vector<InputBindingInfo> controller_confirmation_binds = {};
|
||||
bool seen_controller_confirm_neutral = false;
|
||||
|
||||
// Indicates the binding has been received, assigned, and we can proceed.
|
||||
bool assigned = false;
|
||||
|
@ -439,13 +439,38 @@ void InputManager::set_wait_for_bind(const InputDeviceType device_type,
|
||||
m_waiting_for_bind->pad_idx = input_idx;
|
||||
m_waiting_for_bind->for_analog = for_analog;
|
||||
m_waiting_for_bind->for_analog_minimum = for_minimum_analog;
|
||||
m_waiting_for_bind->seen_keyboard_confirm_up = false;
|
||||
m_waiting_for_bind->keyboard_confirmation_binds =
|
||||
m_settings->keyboard_binds.lookup_button_binds(PadData::CROSS);
|
||||
m_waiting_for_bind->seen_controller_confirm_neutral = false;
|
||||
if (m_controller_port_mapping.find(0) != m_controller_port_mapping.end() &&
|
||||
m_controller_port_mapping.at(0) < (int)m_available_controllers.size() &&
|
||||
m_settings->controller_binds.find(
|
||||
m_available_controllers.at(m_controller_port_mapping.at(0))->get_guid()) !=
|
||||
m_settings->controller_binds.end()) {
|
||||
m_waiting_for_bind->controller_confirmation_binds =
|
||||
m_settings->controller_binds
|
||||
.at(m_available_controllers.at(m_controller_port_mapping.at(0))->get_guid())
|
||||
.lookup_button_binds(PadData::CROSS);
|
||||
}
|
||||
if (g_game_version == GameVersion::Jak1) {
|
||||
auto circle_binds = m_settings->keyboard_binds.lookup_button_binds(PadData::CIRCLE);
|
||||
auto keyboard_circle_binds = m_settings->keyboard_binds.lookup_button_binds(PadData::CIRCLE);
|
||||
m_waiting_for_bind->keyboard_confirmation_binds.insert(
|
||||
m_waiting_for_bind->keyboard_confirmation_binds.end(), circle_binds.begin(),
|
||||
circle_binds.end());
|
||||
m_waiting_for_bind->keyboard_confirmation_binds.end(), keyboard_circle_binds.begin(),
|
||||
keyboard_circle_binds.end());
|
||||
if (m_controller_port_mapping.find(0) != m_controller_port_mapping.end() &&
|
||||
m_controller_port_mapping.at(0) < (int)m_available_controllers.size() &&
|
||||
m_settings->controller_binds.find(
|
||||
m_available_controllers.at(m_controller_port_mapping.at(0))->get_guid()) !=
|
||||
m_settings->controller_binds.end()) {
|
||||
auto controller_circle_binds =
|
||||
m_settings->controller_binds
|
||||
.at(m_available_controllers.at(m_controller_port_mapping.at(0))->get_guid())
|
||||
.lookup_button_binds(PadData::CIRCLE);
|
||||
m_waiting_for_bind->controller_confirmation_binds.insert(
|
||||
m_waiting_for_bind->controller_confirmation_binds.end(), controller_circle_binds.begin(),
|
||||
controller_circle_binds.end());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user