From b2f1cfb50cd4713d3d194aa50cc5a76806063252 Mon Sep 17 00:00:00 2001 From: Taylor Richards Date: Sun, 31 Dec 2017 15:02:29 -0500 Subject: [PATCH] fix mouse handling when viewport is other than default size --- include/2d.h | 4 ++++ src/graphics/2d.cpp | 9 +++++++-- src/graphics/grgl1.cpp | 6 ++++++ src/graphics/grgl2.cpp | 6 ++++++ src/io/mouse.cpp | 41 +++++++++++++++++++---------------------- 5 files changed, 42 insertions(+), 24 deletions(-) diff --git a/include/2d.h b/include/2d.h index 7a97549..586cf81 100644 --- a/include/2d.h +++ b/include/2d.h @@ -383,6 +383,10 @@ typedef struct screen { int offset_x, offset_y; // The offsets into the screen int clip_width, clip_height; int fullscreen; + int viewport_offset_x; + int viewport_offset_y; + float viewport_scale_factor_x; + float viewport_scale_factor_y; float fog_near, fog_far; diff --git a/src/graphics/2d.cpp b/src/graphics/2d.cpp index 6ff510e..bfacbfa 100644 --- a/src/graphics/2d.cpp +++ b/src/graphics/2d.cpp @@ -481,6 +481,7 @@ #include "osregistry.h" #include "cfile.h" #include "cfilesystem.h" +#include "mouse.h" // Includes for different rendering systems #include "gropengl.h" @@ -771,6 +772,10 @@ int gr_init() gr_screen.clip_bottom = gr_screen.max_h - 1; gr_screen.clip_width = gr_screen.max_w; gr_screen.clip_height = gr_screen.max_h; + gr_screen.viewport_offset_x = 0; + gr_screen.viewport_offset_y = 0; + gr_screen.viewport_scale_factor_x = 1.0f; + gr_screen.viewport_scale_factor_y = 1.0f; Gr_textures_in = 0; @@ -841,7 +846,7 @@ void gr_force_windowed() if ( !rc ) { gr_screen.fullscreen = 0; - SDL_SetRelativeMouseMode(SDL_FALSE); + mouse_grab(0); // will be grabbed if needed } if (Os_debugger_running) { @@ -859,7 +864,7 @@ void gr_force_fullscreen() if ( !rc ) { gr_screen.fullscreen = 1; - SDL_SetRelativeMouseMode(SDL_TRUE); + mouse_grab(0); // will be grabbed if needed } if (Os_debugger_running) { diff --git a/src/graphics/grgl1.cpp b/src/graphics/grgl1.cpp index 80c2a54..bf9a84f 100644 --- a/src/graphics/grgl1.cpp +++ b/src/graphics/grgl1.cpp @@ -799,6 +799,12 @@ void gr_opengl1_set_viewport(int width, int height) GL_viewport_scale_w = w / i2fl(gr_screen.max_w); GL_viewport_scale_h = h / i2fl(gr_screen.max_h); + gr_screen.viewport_offset_x = x; + gr_screen.viewport_offset_y = y; + + gr_screen.viewport_scale_factor_x = 1.0f / GL_viewport_scale_w; + gr_screen.viewport_scale_factor_y = 1.0f / GL_viewport_scale_h; + glViewport(GL_viewport_x, GL_viewport_y, GL_viewport_w, GL_viewport_h); glMatrixMode(GL_PROJECTION); diff --git a/src/graphics/grgl2.cpp b/src/graphics/grgl2.cpp index 99a55d6..f8dd8fb 100644 --- a/src/graphics/grgl2.cpp +++ b/src/graphics/grgl2.cpp @@ -773,5 +773,11 @@ void gr_opengl2_set_viewport(int width, int height) GL_viewport_scale_w = w / i2fl(gr_screen.max_w); GL_viewport_scale_h = h / i2fl(gr_screen.max_h); + gr_screen.viewport_offset_x = x; + gr_screen.viewport_offset_y = y; + + gr_screen.viewport_scale_factor_x = 1.0f / GL_viewport_scale_w; + gr_screen.viewport_scale_factor_y = 1.0f / GL_viewport_scale_h; + opengl2_shader_update(); } diff --git a/src/io/mouse.cpp b/src/io/mouse.cpp index 8a9aa4c..80cb6ae 100644 --- a/src/io/mouse.cpp +++ b/src/io/mouse.cpp @@ -422,11 +422,18 @@ void mouse_get_delta(int *dx, int *dy, int *dz) // Forces the actual windows cursor to be at (x,y). This may be independent of our tracked (x,y) mouse pos. 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; + // only mess with windows's mouse if we are in control of it + if ( !os_foreground() ) { + return; } + + int x1 = fl2i(x / gr_screen.viewport_scale_factor_x) + gr_screen.viewport_offset_x; + int y1 = fl2i(y / gr_screen.viewport_scale_factor_y) + gr_screen.viewport_offset_y; + + SDL_WarpMouseInWindow(os_get_window(), x1, y1); + + Mouse_x = x; + Mouse_y = y; } static bool Mouse_grabbed = false; @@ -434,11 +441,6 @@ 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); @@ -447,10 +449,7 @@ void mouse_grab(int grab) } } else if (Mouse_grabbed) { SDL_SetWindowGrab(os_get_window(), SDL_FALSE); - - if ( !gr_screen.fullscreen ) { - SDL_SetRelativeMouseMode(SDL_FALSE); - } + SDL_SetRelativeMouseMode(SDL_FALSE); Mouse_grabbed = false; } @@ -516,16 +515,14 @@ void mouse_set_pos(int xpos, int ypos) void mouse_update_pos(int x, int y, int dx, int dy) { - if (gr_screen.fullscreen) { - Mouse_x += dx; - Mouse_y += dy; + int x1 = fl2i((x - gr_screen.viewport_offset_x) * gr_screen.viewport_scale_factor_x); + int y1 = fl2i((y - gr_screen.viewport_offset_y) * gr_screen.viewport_scale_factor_y); - 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; - } + CAP(x1, 0, gr_screen.max_w-1); + CAP(y1, 0, gr_screen.max_h-1); + + Mouse_x = x1; + Mouse_y = y1; Mouse_dx_inc += dx; Mouse_dy_inc += dy; -- 2.39.2