mirror of
https://github.com/shadps4-emu/shadPS4.git
synced 2025-08-04 16:32:39 +00:00
Downgraded prints to log_debug, and implemented input hierarchy
This commit is contained in:
parent
0d87d0d730
commit
6ad6079c56
@ -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));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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.
|
||||||
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user