From 044e1ec655eea7461542371668134d13a58cc5dd Mon Sep 17 00:00:00 2001 From: Tony <45124675+sonninnos@users.noreply.github.com> Date: Fri, 8 Apr 2022 22:46:00 +0300 Subject: [PATCH] (WinRaw) Fix multiple light guns (#13840) * (WinRaw) Fix multiple light guns * Strip non-ASCII characters from mouse display names --- input/drivers/winraw_input.c | 58 ++++++++++++++++++---- input/input_driver.c | 10 +++- libretro-common/include/string/stdstring.h | 3 ++ libretro-common/string/stdstring.c | 21 ++++++++ 4 files changed, 81 insertions(+), 11 deletions(-) diff --git a/input/drivers/winraw_input.c b/input/drivers/winraw_input.c index 1aedc7b881..400a982338 100644 --- a/input/drivers/winraw_input.c +++ b/input/drivers/winraw_input.c @@ -35,6 +35,10 @@ extern "C" { #include "../../gfx/common/win32_common.h" #endif +#ifdef HAVE_MENU +#include "../../menu/menu_driver.h" +#endif + #include "../input_keymaps.h" #include "../../configuration.h" @@ -53,6 +57,7 @@ typedef struct LONG x, y, dlt_x, dlt_y; LONG whl_u, whl_d; bool btn_l, btn_m, btn_r, btn_b4, btn_b5; + int device; } winraw_mouse_t; struct winraw_pointer_status @@ -402,18 +407,49 @@ static void winraw_update_mouse_state(winraw_input_t *wr, } else if (state->lLastX || state->lLastY) { - InterlockedExchangeAdd(&mouse->dlt_x, state->lLastX); - InterlockedExchangeAdd(&mouse->dlt_y, state->lLastY); - - if (!GetCursorPos(&crs_pos)) - RARCH_DBG("[WinRaw]: GetCursorPos failed with error %lu.\n", GetLastError()); - else if (!ScreenToClient((HWND)video_driver_window_get(), &crs_pos)) - RARCH_DBG("[WinRaw]: ScreenToClient failed with error %lu.\n", GetLastError()); - else + /* Menu requires GetCursorPos() for accurate + * positioning, but using that always will + * break multiple mice positions */ +#ifdef HAVE_MENU + if (menu_state_get_ptr()->alive) { - mouse->x = crs_pos.x; - mouse->y = crs_pos.y; + if (!GetCursorPos(&crs_pos)) + RARCH_DBG("[WinRaw]: GetCursorPos failed with error %lu.\n", GetLastError()); + else if (!ScreenToClient((HWND)video_driver_window_get(), &crs_pos)) + RARCH_DBG("[WinRaw]: ScreenToClient failed with error %lu.\n", GetLastError()); } + else +#endif + { + /* Handle different sensitivity for lightguns */ + if (mouse->device == RETRO_DEVICE_LIGHTGUN) + { + InterlockedExchange(&mouse->dlt_x, state->lLastX); + InterlockedExchange(&mouse->dlt_y, state->lLastY); + } + else + { + InterlockedExchangeAdd(&mouse->dlt_x, state->lLastX); + InterlockedExchangeAdd(&mouse->dlt_y, state->lLastY); + } + + crs_pos.x = mouse->x + mouse->dlt_x; + crs_pos.y = mouse->y + mouse->dlt_y; + + /* Prevent travel outside active window */ + if (crs_pos.x < wr->active_rect.left) + crs_pos.x = wr->active_rect.left; + else if (crs_pos.x > wr->active_rect.right) + crs_pos.x = wr->active_rect.right; + + if (crs_pos.y < wr->active_rect.top) + crs_pos.y = wr->active_rect.top; + else if (crs_pos.y > wr->active_rect.bottom) + crs_pos.y = wr->active_rect.bottom; + } + + mouse->x = crs_pos.x; + mouse->y = crs_pos.y; } if (state->usButtonFlags & RI_MOUSE_LEFT_BUTTON_DOWN) @@ -684,6 +720,8 @@ static int16_t winraw_input_state( if (i == settings->uints.input_mouse_index[port]) { mouse = &wr->mice[i]; + if (mouse && device > RETRO_DEVICE_JOYPAD) + g_mice[i].device = device; break; } } diff --git a/input/input_driver.c b/input/input_driver.c index 1632786a28..d2966c07dc 100644 --- a/input/input_driver.c +++ b/input/input_driver.c @@ -3025,8 +3025,16 @@ const char *input_config_get_mouse_display_name(unsigned port) void input_config_set_mouse_display_name(unsigned port, const char *name) { input_driver_state_t *input_st = &input_driver_st; + char name_ascii[256]; + + name_ascii[0] = '\0'; + + /* Strip non-ASCII characters */ if (!string_is_empty(name)) - strlcpy(input_st->input_mouse_info[port].display_name, name, + string_copy_only_ascii(name_ascii, name); + + if (!string_is_empty(name_ascii)) + strlcpy(input_st->input_mouse_info[port].display_name, name_ascii, sizeof(input_st->input_mouse_info[port].display_name)); } diff --git a/libretro-common/include/string/stdstring.h b/libretro-common/include/string/stdstring.h index 2dc00e3316..fb156d0984 100644 --- a/libretro-common/include/string/stdstring.h +++ b/libretro-common/include/string/stdstring.h @@ -282,6 +282,9 @@ int string_index_last_occurance(char str[], char t); /* Find the position of a substring in a string. */ int string_find_index_substring_string(const char* str1, const char* str2); +/* Strips non-ASCII characters from a string. */ +void string_copy_only_ascii(char *str_stripped, const char* str); + RETRO_END_DECLS #endif diff --git a/libretro-common/string/stdstring.c b/libretro-common/string/stdstring.c index 45446ca77b..2029f3f68f 100644 --- a/libretro-common/string/stdstring.c +++ b/libretro-common/string/stdstring.c @@ -630,3 +630,24 @@ int string_find_index_substring_string(const char* str1, const char* str2) return -1; } + +/* Strips non-ASCII characters from a string. */ +void string_copy_only_ascii(char *str_stripped, const char* str) +{ + if (!string_is_empty(str)) + { + unsigned i = 0; + unsigned j = 0; + + for (i = 0; i < strlen(str); i++) + { + if (str[i] > 0x1F && str[i] < 0x80) + { + str_stripped[j] = str[i]; + j++; + } + } + + str_stripped[j] = '\0'; + } +}