Downgraded prints to log_debug, and implemented input hierarchy

This commit is contained in:
kalaposfos13 2024-11-14 13:15:14 +01:00
parent 0d87d0d730
commit 6ad6079c56
3 changed files with 73 additions and 48 deletions

View File

@ -46,7 +46,7 @@ float mouse_deadzone_offset = 0.5, mouse_speed = 1, mouse_speed_offset = 0.1250;
Uint32 mouse_polling_id = 0; Uint32 mouse_polling_id = 0;
bool mouse_enabled = false, leftjoystick_halfmode = false, rightjoystick_halfmode = false; bool mouse_enabled = false, leftjoystick_halfmode = false, rightjoystick_halfmode = false;
std::list<u32> pressed_keys = std::list<u32>(); std::list<std::pair<u32, bool>> pressed_keys;
std::list<BindingConnection> connections = std::list<BindingConnection>(); std::list<BindingConnection> connections = std::list<BindingConnection>();
void toggleMouseEnabled() { void toggleMouseEnabled() {
@ -161,7 +161,7 @@ void parseInputConfig(const std::string game_id = "") {
// Split the line by '=' // Split the line by '='
std::size_t equal_pos = line.find('='); std::size_t equal_pos = line.find('=');
if (equal_pos == std::string::npos) { if (equal_pos == std::string::npos) {
LOG_ERROR(Input, "Invalid format at line: {}, data: \"{}\", skipping line.", lineCount, line); LOG_DEBUG(Input, "Invalid format at line: {}, data: \"{}\", skipping line.", lineCount, line);
continue; continue;
} }
@ -185,14 +185,14 @@ void parseInputConfig(const std::string game_id = "") {
if (before_equals == "modkey_toggle") { if (before_equals == "modkey_toggle") {
if (comma_pos != std::string::npos) { if (comma_pos != std::string::npos) {
// handle key-to-key toggling (separate list?) // handle key-to-key toggling (separate list?)
LOG_ERROR(Input, "todo: {}", line); LOG_DEBUG(Input, "todo: {}", line);
continue; continue;
} }
LOG_ERROR(Input, "Invalid format at line: {}, data: \"{}\", skipping line.", lineCount, line); LOG_DEBUG(Input, "Invalid format at line: {}, data: \"{}\", skipping line.", lineCount, line);
continue; continue;
} }
if (before_equals == "mouse_movement_params") { if (before_equals == "mouse_movement_params") {
LOG_ERROR(Input, "todo: {}", line); LOG_DEBUG(Input, "todo: {}", line);
continue; continue;
} }
@ -203,7 +203,7 @@ void parseInputConfig(const std::string game_id = "") {
auto axis_it = string_to_axis_map.find(before_equals); auto axis_it = string_to_axis_map.find(before_equals);
if(binding.isEmpty()) { if(binding.isEmpty()) {
LOG_ERROR(Input, "Invalid format at line: {}, data: \"{}\", skipping line.", lineCount, line); LOG_DEBUG(Input, "Invalid format at line: {}, data: \"{}\", skipping line.", lineCount, line);
continue; continue;
} }
if (button_it != string_to_cbutton_map.end()) { if (button_it != string_to_cbutton_map.end()) {
@ -214,18 +214,19 @@ void parseInputConfig(const std::string game_id = "") {
connection = BindingConnection(binding, getOutputPointer(ControllerOutput(0, axis_it->second.axis)), axis_it->second.value); connection = BindingConnection(binding, getOutputPointer(ControllerOutput(0, axis_it->second.axis)), axis_it->second.value);
connections.insert(connections.end(), connection); connections.insert(connections.end(), connection);
} else { } else {
LOG_ERROR(Input, "Invalid format at line: {}, data: \"{}\", skipping line.", lineCount, line); LOG_DEBUG(Input, "Invalid format at line: {}, data: \"{}\", skipping line.", lineCount, line);
continue; continue;
} }
//LOG_INFO(Input, "Succesfully parsed line {}", lineCount); //LOG_INFO(Input, "Succesfully parsed line {}", lineCount);
} }
file.close(); file.close();
LOG_INFO(Input, "Done parsing the input config!"); connections.sort();
LOG_DEBUG(Input, "Done parsing the input config!");
} }
u32 getMouseWheelEvent(const SDL_Event& event) { u32 getMouseWheelEvent(const SDL_Event& event) {
if (event.type != SDL_EVENT_MOUSE_WHEEL && event.type != SDL_EVENT_MOUSE_WHEEL_OFF) { if (event.type != SDL_EVENT_MOUSE_WHEEL && event.type != SDL_EVENT_MOUSE_WHEEL_OFF) {
LOG_ERROR(Input, "Something went wrong with wheel input parsing!"); LOG_DEBUG(Input, "Something went wrong with wheel input parsing!");
return 0; return 0;
} }
if (event.wheel.y > 0) { if (event.wheel.y > 0) {
@ -273,10 +274,10 @@ void ControllerOutput::update(bool pressed, int a_value) {
controller->CheckButton(0, button, pressed); controller->CheckButton(0, button, pressed);
break; break;
case LEFTJOYSTICK_HALFMODE: case LEFTJOYSTICK_HALFMODE:
leftjoystick_halfmode ^= pressed; // toggle if pressed, don't change otherwise leftjoystick_halfmode = pressed;
break; break;
case RIGHTJOYSTICK_HALFMODE: case RIGHTJOYSTICK_HALFMODE:
rightjoystick_halfmode ^= pressed; rightjoystick_halfmode = pressed;
break; break;
default: // is a normal key (hopefully) default: // is a normal key (hopefully)
controller->CheckButton(0, button, pressed); controller->CheckButton(0, button, pressed);
@ -307,7 +308,7 @@ void ControllerOutput::update(bool pressed, int a_value) {
int ax = GetAxis(-0x80, 0x80, axis_value); int ax = GetAxis(-0x80, 0x80, axis_value);
controller->Axis(0, axis, ax); controller->Axis(0, axis, ax);
} else { } else {
LOG_ERROR(Input, "Controller output with no values detected!"); LOG_DEBUG(Input, "Controller output with no values detected!");
} }
} }
void ControllerOutput::addUpdate(bool pressed, int a_value) { void ControllerOutput::addUpdate(bool pressed, int a_value) {
@ -359,77 +360,93 @@ void ControllerOutput::addUpdate(bool pressed, int a_value) {
controller->Axis(0, axis, GetAxis(-0x80, 0x80, axis_value)); controller->Axis(0, axis, GetAxis(-0x80, 0x80, axis_value));
//LOG_INFO(Input, "Axis value delta: {} final value: {}", (pressed ? a_value : 0), axis_value); //LOG_INFO(Input, "Axis value delta: {} final value: {}", (pressed ? a_value : 0), axis_value);
} else { } else {
LOG_ERROR(Input, "Controller output with no values detected!"); LOG_DEBUG(Input, "Controller output with no values detected!");
} }
} }
void updatePressedKeys(u32 value, bool is_pressed) { void updatePressedKeys(u32 value, bool is_pressed) {
if (is_pressed) { if (is_pressed) {
// Find the correct position for insertion to maintain order // Find the correct position for insertion to maintain order
auto it = std::lower_bound(pressed_keys.begin(), pressed_keys.end(), value); auto it = std::lower_bound(pressed_keys.begin(), pressed_keys.end(), value,
[](const std::pair<u32, bool>& pk, u32 v) { return pk.first < v; });
// Insert only if 'value' is not already in the list // Insert only if 'value' is not already in the list
if (it == pressed_keys.end() || *it != value) { if (it == pressed_keys.end() || it->first != value) {
pressed_keys.insert(it, value); pressed_keys.insert(it, {value, false});
} }
} else { } else {
// Remove 'value' from the list if it's not pressed // Remove 'value' from the list if it's not pressed
pressed_keys.remove(value); auto it = std::find_if(pressed_keys.begin(), pressed_keys.end(),
[value](const std::pair<u32, bool>& pk) { return pk.first == value; });
if (it != pressed_keys.end()) {
pressed_keys.erase(it); // Remove the key entirely from the list
}
} }
} }
// Check if a given binding's all keys are currently active. // Check if a given binding's all keys are currently active.
bool isInputActive(const InputBinding& i) { bool isInputActive(const InputBinding& i) {
/* how to check if a binding is currently held down: bool* flag1 = nullptr;
iterate until connection.InputBinding.key3 is found or we reach the end bool* flag2 = nullptr;
iterate from that point until connection.InputBinding.key2 is found or we reach the end bool* flag3 = nullptr;
iterate from that point until connection.InputBinding.key1 is found or we reach the end
if we ever reach the end, return false
if the next key to find would be 0, return true
if all three are found return true
*/
auto it = pressed_keys.begin();
if (i.key1 != 0) { // First pass: locate each key and save pointers to their flags if found
it = std::find(it, pressed_keys.end(), i.key1); for (auto& entry : pressed_keys) {
if (it == pressed_keys.end()) return false; u32 key = entry.first;
++it; // Move to the next element for subsequent checks bool& is_active = entry.second;
if (i.key1 != 0 && key == i.key1 && !flag1) {
flag1 = &is_active;
} else if (i.key2 != 0 && key == i.key2 && !flag2) {
flag2 = &is_active;
} else if (i.key3 != 0 && key == i.key3 && !flag3) {
flag3 = &is_active;
break;
} else {
return false; // an all 0 input never gets activated
}
} }
if (i.key2 != 0) { // If any required key was not found, return false without updating flags
it = std::find(it, pressed_keys.end(), i.key2); if ((i.key1 != 0 && !flag1) || (i.key2 != 0 && !flag2) || (i.key3 != 0 && !flag3)) {
if (it == pressed_keys.end()) return false; return false;
++it;
} }
if (i.key3 != 0) { // Check if all flags are already true, which indicates this input is overridden (only if the key is not 0)
it = std::find(it, pressed_keys.end(), i.key3); if ((i.key1 == 0 || (flag1 && *flag1)) &&
if (it == pressed_keys.end()) return false; (i.key2 == 0 || (flag2 && *flag2)) &&
(i.key3 == 0 || (flag3 && *flag3))) {
return false; // This input is overridden by another input
} }
// All required keys were found in order // Set flags to true only after confirming all keys are present and not overridden
LOG_INFO(Input, "A valid held input is found!"); if (flag1) *flag1 = true;
if (flag2) *flag2 = true;
if (flag3) *flag3 = true;
LOG_DEBUG(Input, "A valid held input is found: {}, flag ptrs: {} {} {}", i.toString(), fmt::ptr(flag1), fmt::ptr(flag2), fmt::ptr(flag3));
return true; return true;
} }
void activateOutputsFromInputs() { void activateOutputsFromInputs() {
LOG_DEBUG(Input, "Starting input scan...");
// reset everything // reset everything
for(auto it = connections.begin(); it != connections.end(); it++) { for(auto it = connections.begin(); it != connections.end(); it++) {
if (it->output) { if (it->output) {
it->output->update(false, 0); it->output->update(false, 0);
} else { } else {
// LOG_ERROR(Input, "Null output in BindingConnection at position {}\n data: {}: {}", LOG_DEBUG(Input, "Null output in BindingConnection at position {}", std::distance(connections.begin(), it));
// std::distance(connections.begin(), it),
// it->binding.toString(), it->output->toString());
LOG_ERROR(Input, "Null output in BindingConnection at position {}", std::distance(connections.begin(), it));
} }
} }
for (auto it : pressed_keys) {
it.second = false;
}
// iterates over the connections, and updates them depending on whether the corresponding input trio is found // iterates over the connections, and updates them depending on whether the corresponding input trio is found
for(auto it = connections.begin(); it != connections.end(); it++) { for(auto it = connections.begin(); it != connections.end(); it++) {
if (it->output) { if (it->output) {
it->output->addUpdate(isInputActive(it->binding), it->axis_value); it->output->addUpdate(isInputActive(it->binding), it->axis_value);
} else { } else {
//LOG_ERROR(Input, "Null output in BindingConnection at position {}", std::distance(connections.begin(), it)); //LOG_DEBUG(Input, "Null output in BindingConnection at position {}", std::distance(connections.begin(), it));
} }
} }
} }

View File

@ -218,10 +218,17 @@ public:
// but reverse order makes it check the actual keys first instead of possible 0-s, // but reverse order makes it check the actual keys first instead of possible 0-s,
// potenially skipping the later expressions of the three-way AND // potenially skipping the later expressions of the three-way AND
} }
inline int keyCount() const {
return (key1 ? 1 : 0) + (key2 ? 1 : 0) + (key3 ? 1 : 0);
}
// Sorts by the amount of non zero keys - left side is 'bigger' here
bool operator<(const InputBinding& other) const {
return keyCount() > other.keyCount();
}
inline bool isEmpty() { inline bool isEmpty() {
return key1 == 0 && key2 == 0 && key3 == 0; return key1 == 0 && key2 == 0 && key3 == 0;
} }
std::string toString() { std::string toString() const {
return fmt::format("({}, {}, {})", key1, key2, key3); return fmt::format("({}, {}, {})", key1, key2, key3);
} }
@ -269,7 +276,9 @@ public:
// todo: check if out is in the allowed array // todo: check if out is in the allowed array
output = out; output = out;
} }
bool operator<(const BindingConnection& other) {
return binding < other.binding;
}
}; };
// Check if the 3 key input is currently active. // Check if the 3 key input is currently active.

View File

@ -136,7 +136,6 @@ void WindowSDL::waitEvent() {
void WindowSDL::initTimers() { void WindowSDL::initTimers() {
SDL_AddTimer(100, &PollController, controller); SDL_AddTimer(100, &PollController, controller);
// todo: add back mouse polling here
SDL_AddTimer(33, Input::mousePolling, (void*)controller); SDL_AddTimer(33, Input::mousePolling, (void*)controller);
} }