From c93fca94f7fb2cbbc01e4b75ef048aa4fae55080 Mon Sep 17 00:00:00 2001 From: Taylor Richards Date: Fri, 17 Jun 2016 01:22:56 -0400 Subject: [PATCH] fix some mouse handling issues - relative mouse mode for fullscreen to fix offscreen cursor - grab cursor properly when using mouse to fly - ungrab cursor when necessary - make sure Int3() will release & reset cursor during debugging --- include/mouse.h | 1 + src/io/mouse.cpp | 52 ++++++++++++++++++++++++++++++++++----------- src/osapi/osapi.cpp | 15 +++++++++++++ 3 files changed, 56 insertions(+), 12 deletions(-) diff --git a/include/mouse.h b/include/mouse.h index 147ee73..9f5ae54 100644 --- a/include/mouse.h +++ b/include/mouse.h @@ -125,6 +125,7 @@ int mouse_down(int btn); // returns 1 if mouse button btn is down, 0 otherwise float mouse_down_time(int btn); // returns the fraction of time btn has been down since last call int mouse_is_visible(); // returns 1 if mouse is visible, 0 otherwise +void mouse_grab(int grab); void mouse_eval_deltas(); void mouse_get_delta(int *dx = NULL, int *dy = NULL, int *dz = NULL); diff --git a/src/io/mouse.cpp b/src/io/mouse.cpp index 6747b60..8a9aa4c 100644 --- a/src/io/mouse.cpp +++ b/src/io/mouse.cpp @@ -424,10 +424,38 @@ void mouse_force_pos(int x, int y) { if (os_foreground()) { // only mess with windows's mouse if we are in control of it SDL_WarpMouseInWindow(os_get_window(), x, y); + Mouse_x = x; + Mouse_y = y; } } static bool Mouse_grabbed = false; + +void mouse_grab(int grab) +{ + if (grab) { + // never grab when fullscreen + if (gr_screen.fullscreen) { + return; + } + + if ( !Mouse_grabbed ) { + SDL_SetWindowGrab(os_get_window(), SDL_TRUE); + SDL_SetRelativeMouseMode(SDL_TRUE); + + Mouse_grabbed = true; + } + } else if (Mouse_grabbed) { + SDL_SetWindowGrab(os_get_window(), SDL_FALSE); + + if ( !gr_screen.fullscreen ) { + SDL_SetRelativeMouseMode(SDL_FALSE); + } + + Mouse_grabbed = false; + } +} + void mouse_eval_deltas() { Mouse_dx = Mouse_dx_inc; @@ -437,17 +465,9 @@ void mouse_eval_deltas() // make sure mouse is bound to window if we're flying with it if (Keep_mouse_centered && Mouse_hidden) { - if ( !Mouse_grabbed ) { - SDL_SetRelativeMouseMode(SDL_TRUE); - SDL_SetWindowGrab(os_get_window(), SDL_TRUE); - Mouse_grabbed = true; - } + mouse_grab(1); } else { - if (Mouse_grabbed) { - SDL_SetRelativeMouseMode(SDL_FALSE); - SDL_SetWindowGrab(os_get_window(), SDL_FALSE); - Mouse_grabbed = false; - } + mouse_grab(0); } } @@ -496,8 +516,16 @@ void mouse_set_pos(int xpos, int ypos) void mouse_update_pos(int x, int y, int dx, int dy) { - Mouse_x = x; - Mouse_y = y; + if (gr_screen.fullscreen) { + Mouse_x += dx; + Mouse_y += dy; + + CAP(Mouse_x, 0, gr_screen.max_w-1); + CAP(Mouse_y, 0, gr_screen.max_h-1); + } else { + Mouse_x = x; + Mouse_y = y; + } Mouse_dx_inc += dx; Mouse_dy_inc += dy; diff --git a/src/osapi/osapi.cpp b/src/osapi/osapi.cpp index cd244d5..f887f87 100644 --- a/src/osapi/osapi.cpp +++ b/src/osapi/osapi.cpp @@ -433,9 +433,12 @@ void os_poll() switch (e.window.event) { case SDL_WINDOWEVENT_RESIZED: gr_set_viewport(e.window.data1, e.window.data2); + // ungrab mouse, it will be grabbed again if needed + mouse_grab(0); break; case SDL_WINDOWEVENT_FOCUS_LOST: + mouse_grab(0); joy_unacquire_ff(); break; @@ -443,6 +446,10 @@ void os_poll() joy_reacquire_ff(); break; + case SDL_WINDOWEVENT_MINIMIZED: + mouse_grab(0); + break; + case SDL_WINDOWEVENT_CLOSE: // gameseq_post_event(GS_EVENT_QUIT_GAME); break; @@ -463,5 +470,13 @@ void os_poll() void debug_int3() { + SDL_bool mode = SDL_GetRelativeMouseMode(); + SDL_SetRelativeMouseMode(SDL_FALSE); + SDL_bool grab = SDL_GetWindowGrab(Os_window); + SDL_SetWindowGrab(Os_window, SDL_FALSE); + SDL_TriggerBreakpoint(); + + SDL_SetRelativeMouseMode(mode); + SDL_SetWindowGrab(Os_window, grab); } -- 2.39.2