From 3e599d04d3a58bc1ace0363fd8167f804e5f180b Mon Sep 17 00:00:00 2001 From: sonninnos <45124675+sonninnos@users.noreply.github.com> Date: Sat, 14 Jan 2023 22:33:26 +0200 Subject: [PATCH] (WIN32) Add support for mouse button swap (#14846) --- gfx/common/win32_common.c | 14 ++++-- gfx/common/win32_common.h | 9 ++-- input/drivers/dinput.c | 56 +++++++++++++++------ input/drivers/winraw_input.c | 94 +++++++++++++++++++++--------------- 4 files changed, 112 insertions(+), 61 deletions(-) diff --git a/gfx/common/win32_common.c b/gfx/common/win32_common.c index e5d8ad4106..200a3e1343 100644 --- a/gfx/common/win32_common.c +++ b/gfx/common/win32_common.c @@ -2626,13 +2626,21 @@ bool win32_window_init(WNDCLASSEX *wndclass, wndclass->hCursor = LoadCursor(NULL, IDC_ARROW); wndclass->lpszClassName = class_name ? class_name : "RetroArch"; wndclass->hIcon = LoadIcon(GetModuleHandle(NULL), - MAKEINTRESOURCE(IDI_ICON)); + MAKEINTRESOURCE(IDI_ICON)); wndclass->hIconSm = (HICON)LoadImage(GetModuleHandle(NULL), - MAKEINTRESOURCE(IDI_ICON), IMAGE_ICON, 16, 16, 0); + MAKEINTRESOURCE(IDI_ICON), IMAGE_ICON, 16, 16, 0); + + if (GetSystemMetrics(SM_SWAPBUTTON)) + g_win32_flags |= WIN32_CMN_FLAG_SWAP_MOUSE_BTNS; + else + g_win32_flags &= ~WIN32_CMN_FLAG_SWAP_MOUSE_BTNS; + if (!fullscreen) wndclass->hbrBackground = (HBRUSH)COLOR_WINDOW; + if (class_name) - wndclass->style |= CS_CLASSDC; + wndclass->style |= CS_CLASSDC; + return RegisterClassEx(wndclass); } #endif diff --git a/gfx/common/win32_common.h b/gfx/common/win32_common.h index fc9f1158ff..29d4174953 100644 --- a/gfx/common/win32_common.h +++ b/gfx/common/win32_common.h @@ -70,7 +70,8 @@ enum win32_common_flags WIN32_CMN_FLAG_RESIZED = (1 << 1), WIN32_CMN_FLAG_TASKBAR_CREATED = (1 << 2), WIN32_CMN_FLAG_RESTORE_DESKTOP = (1 << 3), - WIN32_CMN_FLAG_INITED = (1 << 4) + WIN32_CMN_FLAG_INITED = (1 << 4), + WIN32_CMN_FLAG_SWAP_MOUSE_BTNS = (1 << 5) }; extern uint8_t g_win32_flags; @@ -104,8 +105,8 @@ bool win32_get_video_output(DEVMODE *dm, int mode, size_t len); bool win32_window_init(WNDCLASSEX *wndclass, bool fullscreen, const char *class_name); void win32_set_style(MONITORINFOEX *current_mon, HMONITOR *hm_to_use, - unsigned *width, unsigned *height, bool fullscreen, bool windowed_full, - RECT *rect, RECT *mon_rect, DWORD *style); + unsigned *width, unsigned *height, bool fullscreen, bool windowed_full, + RECT *rect, RECT *mon_rect, DWORD *style); #endif void win32_monitor_from_window(void); #endif @@ -123,7 +124,7 @@ bool win32_window_create(void *data, unsigned style, bool win32_suppress_screensaver(void *data, bool enable); bool win32_get_metrics(void *data, - enum display_metric_types type, float *value); + enum display_metric_types type, float *value); void win32_show_cursor(void *data, bool state); diff --git a/input/drivers/dinput.c b/input/drivers/dinput.c index c3617e65ee..2cd25606ce 100644 --- a/input/drivers/dinput.c +++ b/input/drivers/dinput.c @@ -307,6 +307,7 @@ static void dinput_poll(void *data) POINT point; DIMOUSESTATE2 mouse_state; BYTE *rgb_buttons_ptr = &mouse_state.rgbButtons[0]; + bool swap_mouse_buttons = g_win32_flags & WIN32_CMN_FLAG_SWAP_MOUSE_BTNS; point.x = 0; point.y = 0; @@ -340,32 +341,59 @@ static void dinput_poll(void *data) di->mouse_rel_x = mouse_state.lX; di->mouse_rel_y = mouse_state.lY; - if (!mouse_state.rgbButtons[0]) - di->flags &= ~DINP_FLAG_DBCLK_ON_TITLEBAR; + if (swap_mouse_buttons) + { + if (!mouse_state.rgbButtons[1]) + di->flags &= ~DINP_FLAG_DBCLK_ON_TITLEBAR; - if (di->flags & DINP_FLAG_DBCLK_ON_TITLEBAR) - di->flags &= ~DINP_FLAG_MOUSE_L_BTN; + if (di->flags & DINP_FLAG_DBCLK_ON_TITLEBAR) + di->flags &= ~DINP_FLAG_MOUSE_R_BTN; + else + { + if (mouse_state.rgbButtons[0]) + di->flags |= DINP_FLAG_MOUSE_R_BTN; + else + di->flags &= ~DINP_FLAG_MOUSE_R_BTN; + } + + if (mouse_state.rgbButtons[1]) + di->flags |= DINP_FLAG_MOUSE_L_BTN; + else + di->flags &= ~DINP_FLAG_MOUSE_L_BTN; + } else { - if (mouse_state.rgbButtons[0]) - di->flags |= DINP_FLAG_MOUSE_L_BTN; - else + if (!mouse_state.rgbButtons[0]) + di->flags &= ~DINP_FLAG_DBCLK_ON_TITLEBAR; + + if (di->flags & DINP_FLAG_DBCLK_ON_TITLEBAR) di->flags &= ~DINP_FLAG_MOUSE_L_BTN; + else + { + if (mouse_state.rgbButtons[0]) + di->flags |= DINP_FLAG_MOUSE_L_BTN; + else + di->flags &= ~DINP_FLAG_MOUSE_L_BTN; + } + + if (mouse_state.rgbButtons[1]) + di->flags |= DINP_FLAG_MOUSE_R_BTN; + else + di->flags &= ~DINP_FLAG_MOUSE_R_BTN; } - if (mouse_state.rgbButtons[1]) - di->flags |= DINP_FLAG_MOUSE_R_BTN; - else - di->flags &= ~DINP_FLAG_MOUSE_R_BTN; + if (mouse_state.rgbButtons[2]) - di->flags |= DINP_FLAG_MOUSE_M_BTN; + di->flags |= DINP_FLAG_MOUSE_M_BTN; else di->flags &= ~DINP_FLAG_MOUSE_M_BTN; + if (mouse_state.rgbButtons[3]) - di->flags |= DINP_FLAG_MOUSE_B4_BTN; + di->flags |= DINP_FLAG_MOUSE_B4_BTN; else di->flags &= ~DINP_FLAG_MOUSE_B4_BTN; + if (mouse_state.rgbButtons[4]) - di->flags |= DINP_FLAG_MOUSE_B5_BTN; + di->flags |= DINP_FLAG_MOUSE_B5_BTN; else di->flags &= ~DINP_FLAG_MOUSE_B5_BTN; diff --git a/input/drivers/winraw_input.c b/input/drivers/winraw_input.c index a4724ebcb3..e70b258a5e 100644 --- a/input/drivers/winraw_input.c +++ b/input/drivers/winraw_input.c @@ -320,7 +320,7 @@ static bool winraw_mouse_button_pressed( winraw_mouse_t *mouse, unsigned port, unsigned key) { - switch (key) + switch (key) { case RETRO_DEVICE_ID_MOUSE_LEFT: return mouse->btn_l; @@ -338,7 +338,7 @@ static bool winraw_mouse_button_pressed( return mouse->whl_d; } - return false; + return false; } static void winraw_init_mouse_xy_mapping(winraw_input_t *wr) @@ -368,6 +368,7 @@ static void winraw_update_mouse_state(winraw_input_t *wr, winraw_mouse_t *mouse, RAWMOUSE *state) { POINT crs_pos; + bool swap_mouse_buttons = g_win32_flags & WIN32_CMN_FLAG_SWAP_MOUSE_BTNS; /* Used for fixing coordinates after switching resolutions */ GetClientRect((HWND)video_driver_window_get(), &wr->prev_rect); @@ -381,11 +382,11 @@ static void winraw_update_mouse_state(winraw_input_t *wr, } else { - int bottom = wr->prev_rect.bottom; - int right = wr->prev_rect.right; - wr->active_rect = wr->prev_rect; - winraw_init_mouse_xy_mapping(wr); - wr->rect_delay = 0; + int bottom = wr->prev_rect.bottom; + int right = wr->prev_rect.right; + wr->active_rect = wr->prev_rect; + winraw_init_mouse_xy_mapping(wr); + wr->rect_delay = 0; } } @@ -465,20 +466,35 @@ static void winraw_update_mouse_state(winraw_input_t *wr, mouse->y = crs_pos.y; } - if (state->usButtonFlags & RI_MOUSE_LEFT_BUTTON_DOWN) - mouse->btn_l = true; - else if (state->usButtonFlags & RI_MOUSE_LEFT_BUTTON_UP) - mouse->btn_l = false; + if (swap_mouse_buttons) + { + if (state->usButtonFlags & RI_MOUSE_LEFT_BUTTON_DOWN) + mouse->btn_r = true; + else if (state->usButtonFlags & RI_MOUSE_LEFT_BUTTON_UP) + mouse->btn_r = false; + + if (state->usButtonFlags & RI_MOUSE_RIGHT_BUTTON_DOWN) + mouse->btn_l = true; + else if (state->usButtonFlags & RI_MOUSE_RIGHT_BUTTON_UP) + mouse->btn_l = false; + } + else + { + if (state->usButtonFlags & RI_MOUSE_LEFT_BUTTON_DOWN) + mouse->btn_l = true; + else if (state->usButtonFlags & RI_MOUSE_LEFT_BUTTON_UP) + mouse->btn_l = false; + + if (state->usButtonFlags & RI_MOUSE_RIGHT_BUTTON_DOWN) + mouse->btn_r = true; + else if (state->usButtonFlags & RI_MOUSE_RIGHT_BUTTON_UP) + mouse->btn_r = false; + } if (state->usButtonFlags & RI_MOUSE_MIDDLE_BUTTON_DOWN) - mouse->btn_m = true; + mouse->btn_m = true; else if (state->usButtonFlags & RI_MOUSE_MIDDLE_BUTTON_UP) - mouse->btn_m = false; - - if (state->usButtonFlags & RI_MOUSE_RIGHT_BUTTON_DOWN) - mouse->btn_r = true; - else if (state->usButtonFlags & RI_MOUSE_RIGHT_BUTTON_UP) - mouse->btn_r = false; + mouse->btn_m = false; if (state->usButtonFlags & RI_MOUSE_BUTTON_4_DOWN) mouse->btn_b4 = true; @@ -955,28 +971,26 @@ static int16_t winraw_input_state( } break; case RETRO_DEVICE_LIGHTGUN: - switch (id) - { - /*aiming*/ - case RETRO_DEVICE_ID_LIGHTGUN_SCREEN_X: - case RETRO_DEVICE_ID_LIGHTGUN_SCREEN_Y: - case RETRO_DEVICE_ID_LIGHTGUN_IS_OFFSCREEN: - if (mouse) - return winraw_lightgun_aiming_state(wr, mouse, port, id); - break; - /*buttons*/ - case RETRO_DEVICE_ID_LIGHTGUN_TRIGGER: - case RETRO_DEVICE_ID_LIGHTGUN_RELOAD: - case RETRO_DEVICE_ID_LIGHTGUN_AUX_A: - case RETRO_DEVICE_ID_LIGHTGUN_AUX_B: - case RETRO_DEVICE_ID_LIGHTGUN_AUX_C: - case RETRO_DEVICE_ID_LIGHTGUN_START: - case RETRO_DEVICE_ID_LIGHTGUN_SELECT: - case RETRO_DEVICE_ID_LIGHTGUN_DPAD_UP: - case RETRO_DEVICE_ID_LIGHTGUN_DPAD_DOWN: - case RETRO_DEVICE_ID_LIGHTGUN_DPAD_LEFT: - case RETRO_DEVICE_ID_LIGHTGUN_DPAD_RIGHT: - case RETRO_DEVICE_ID_LIGHTGUN_PAUSE: /* deprecated */ + switch (id) + { + case RETRO_DEVICE_ID_LIGHTGUN_SCREEN_X: + case RETRO_DEVICE_ID_LIGHTGUN_SCREEN_Y: + case RETRO_DEVICE_ID_LIGHTGUN_IS_OFFSCREEN: + if (mouse) + return winraw_lightgun_aiming_state(wr, mouse, port, id); + break; + case RETRO_DEVICE_ID_LIGHTGUN_TRIGGER: + case RETRO_DEVICE_ID_LIGHTGUN_RELOAD: + case RETRO_DEVICE_ID_LIGHTGUN_AUX_A: + case RETRO_DEVICE_ID_LIGHTGUN_AUX_B: + case RETRO_DEVICE_ID_LIGHTGUN_AUX_C: + case RETRO_DEVICE_ID_LIGHTGUN_START: + case RETRO_DEVICE_ID_LIGHTGUN_SELECT: + case RETRO_DEVICE_ID_LIGHTGUN_DPAD_UP: + case RETRO_DEVICE_ID_LIGHTGUN_DPAD_DOWN: + case RETRO_DEVICE_ID_LIGHTGUN_DPAD_LEFT: + case RETRO_DEVICE_ID_LIGHTGUN_DPAD_RIGHT: + case RETRO_DEVICE_ID_LIGHTGUN_PAUSE: /* deprecated */ { unsigned new_id = winraw_retro_id_to_rarch(id); const uint64_t bind_joykey = input_config_binds[port][new_id].joykey;