added cur_controllers mutex for rumble safety

This commit is contained in:
thecozies 2024-04-16 09:28:51 -05:00 committed by Mr-Wiseguy
parent af3c4f4df7
commit 0fd4f8b859

View File

@ -26,6 +26,7 @@ static struct {
const Uint8* keys = nullptr; const Uint8* keys = nullptr;
int numkeys = 0; int numkeys = 0;
std::atomic_int32_t mouse_wheel_pos = 0; std::atomic_int32_t mouse_wheel_pos = 0;
std::mutex cur_controllers_mutex;
std::vector<SDL_GameController*> cur_controllers{}; std::vector<SDL_GameController*> cur_controllers{};
std::unordered_map<SDL_JoystickID, ControllerState> controller_states; std::unordered_map<SDL_JoystickID, ControllerState> controller_states;
std::array<float, 2> rotation_delta{}; std::array<float, 2> rotation_delta{};
@ -335,6 +336,8 @@ const recomp::DefaultN64Mappings recomp::default_n64_controller_mappings = {
void recomp::poll_inputs() { void recomp::poll_inputs() {
InputState.keys = SDL_GetKeyboardState(&InputState.numkeys); InputState.keys = SDL_GetKeyboardState(&InputState.numkeys);
{
std::lock_guard lock{ InputState.cur_controllers_mutex };
InputState.cur_controllers.clear(); InputState.cur_controllers.clear();
for (const auto& [id, state] : InputState.controller_states) { for (const auto& [id, state] : InputState.controller_states) {
@ -344,6 +347,7 @@ void recomp::poll_inputs() {
InputState.cur_controllers.push_back(controller); InputState.cur_controllers.push_back(controller);
} }
} }
}
// Read the deltas while resetting them to zero. // Read the deltas while resetting them to zero.
{ {
@ -398,19 +402,24 @@ void recomp::update_rumble() {
uint16_t rumble_strength = smooth_rumble * (recomp::get_rumble_strength() * 0xFFFF / 100); uint16_t rumble_strength = smooth_rumble * (recomp::get_rumble_strength() * 0xFFFF / 100);
uint32_t duration = 1000000; // Dummy duration value that lasts long enough to matter as the game will reset rumble on its own. uint32_t duration = 1000000; // Dummy duration value that lasts long enough to matter as the game will reset rumble on its own.
{
std::lock_guard lock{ InputState.cur_controllers_mutex };
for (const auto& controller : InputState.cur_controllers) { for (const auto& controller : InputState.cur_controllers) {
SDL_GameControllerRumble(controller, 0, rumble_strength, duration); SDL_GameControllerRumble(controller, 0, rumble_strength, duration);
} }
} }
}
bool controller_button_state(int32_t input_id) { bool controller_button_state(int32_t input_id) {
if (input_id >= 0 && input_id < SDL_GameControllerButton::SDL_CONTROLLER_BUTTON_MAX) { if (input_id >= 0 && input_id < SDL_GameControllerButton::SDL_CONTROLLER_BUTTON_MAX) {
SDL_GameControllerButton button = (SDL_GameControllerButton)input_id; SDL_GameControllerButton button = (SDL_GameControllerButton)input_id;
bool ret = false; bool ret = false;
{
std::lock_guard lock{ InputState.cur_controllers_mutex };
for (const auto& controller : InputState.cur_controllers) { for (const auto& controller : InputState.cur_controllers) {
ret |= SDL_GameControllerGetButton(controller, button); ret |= SDL_GameControllerGetButton(controller, button);
} }
}
return ret; return ret;
} }
@ -423,6 +432,8 @@ float controller_axis_state(int32_t input_id) {
bool negative_range = input_id < 0; bool negative_range = input_id < 0;
float ret = 0.0f; float ret = 0.0f;
{
std::lock_guard lock{ InputState.cur_controllers_mutex };
for (const auto& controller : InputState.cur_controllers) { for (const auto& controller : InputState.cur_controllers) {
float cur_val = SDL_GameControllerGetAxis(controller, axis) * (1/32768.0f); float cur_val = SDL_GameControllerGetAxis(controller, axis) * (1/32768.0f);
if (negative_range) { if (negative_range) {
@ -430,6 +441,7 @@ float controller_axis_state(int32_t input_id) {
} }
ret += std::clamp(cur_val, 0.0f, 1.0f); ret += std::clamp(cur_val, 0.0f, 1.0f);
} }
}
return std::clamp(ret, 0.0f, 1.0f); return std::clamp(ret, 0.0f, 1.0f);
} }