From: Holger Schemel Date: Tue, 29 Nov 2016 20:29:15 +0000 (+0100) Subject: adjust drawable screen size to cover the whole device display (Android) X-Git-Tag: 4.0.0.0~10 X-Git-Url: https://git.artsoft.org/?p=rocksndiamonds.git;a=commitdiff_plain;h=bf9e47bb97f16c998644758a383209fa4d4fc87b adjust drawable screen size to cover the whole device display (Android) --- diff --git a/src/events.c b/src/events.c index 64744622..0aa4185a 100644 --- a/src/events.c +++ b/src/events.c @@ -58,6 +58,18 @@ static int FilterEvents(const Event *event) return 0; #endif + if (event->type == EVENT_BUTTONPRESS || + event->type == EVENT_BUTTONRELEASE) + { + ((ButtonEvent *)event)->x -= video.screen_xoffset; + ((ButtonEvent *)event)->y -= video.screen_yoffset; + } + else if (event->type == EVENT_MOTIONNOTIFY) + { + ((MotionEvent *)event)->x -= video.screen_xoffset; + ((MotionEvent *)event)->y -= video.screen_yoffset; + } + /* non-motion events are directly passed to event handler functions */ if (event->type != EVENT_MOTIONNOTIFY) return 1; @@ -509,32 +521,52 @@ void HandleWindowEvent(WindowEvent *event) SDLRedrawWindow(); #endif - if (event->event == SDL_WINDOWEVENT_RESIZED && !video.fullscreen_enabled) + if (event->event == SDL_WINDOWEVENT_RESIZED) { - int new_window_width = event->data1; - int new_window_height = event->data2; - - // if window size has changed after resizing, calculate new scaling factor - if (new_window_width != video.window_width || - new_window_height != video.window_height) + if (!video.fullscreen_enabled) { - int new_xpercent = (100 * new_window_width / video.width); - int new_ypercent = (100 * new_window_height / video.height); + int new_window_width = event->data1; + int new_window_height = event->data2; + + // if window size has changed after resizing, calculate new scaling factor + if (new_window_width != video.window_width || + new_window_height != video.window_height) + { + int new_xpercent = (100 * new_window_width / video.screen_width); + int new_ypercent = (100 * new_window_height / video.screen_height); + + // (extreme window scaling allowed, but cannot be saved permanently) + video.window_scaling_percent = MIN(new_xpercent, new_ypercent); + setup.window_scaling_percent = + MIN(MAX(MIN_WINDOW_SCALING_PERCENT, video.window_scaling_percent), + MAX_WINDOW_SCALING_PERCENT); - // (extreme window scaling allowed, but cannot be saved permanently) - video.window_scaling_percent = MIN(new_xpercent, new_ypercent); - setup.window_scaling_percent = - MIN(MAX(MIN_WINDOW_SCALING_PERCENT, video.window_scaling_percent), - MAX_WINDOW_SCALING_PERCENT); + video.window_width = new_window_width; + video.window_height = new_window_height; - video.window_width = new_window_width; - video.window_height = new_window_height; + if (game_status == GAME_MODE_SETUP) + RedrawSetupScreenAfterFullscreenToggle(); - if (game_status == GAME_MODE_SETUP) - RedrawSetupScreenAfterFullscreenToggle(); + SetWindowTitle(); + } + } +#if defined(PLATFORM_ANDROID) + else + { + int new_display_width = event->data1; + int new_display_height = event->data2; - SetWindowTitle(); + // if fullscreen display size has changed, device has been rotated + if (new_display_width != video.display_width || + new_display_height != video.display_height) + { + video.display_width = new_display_width; + video.display_height = new_display_height; + + SDLSetScreenProperties(); + } } +#endif } } diff --git a/src/libgame/sdl.c b/src/libgame/sdl.c index 7a108238..661bf6fb 100644 --- a/src/libgame/sdl.c +++ b/src/libgame/sdl.c @@ -129,9 +129,18 @@ static void UpdateScreenExt(SDL_Rect *rect, boolean with_frame_delay) SDL_UpdateTexture(sdl_texture, NULL, screen->pixels, screen->pitch); } + int xoff = video.screen_xoffset; + int yoff = video.screen_yoffset; + SDL_Rect dst_rect_screen = { xoff, yoff, video.width, video.height }; SDL_Rect *src_rect1 = NULL, *dst_rect1 = NULL; SDL_Rect *src_rect2 = NULL, *dst_rect2 = NULL; + if (video.screen_rendering_mode == SPECIAL_RENDERING_TARGET || + video.screen_rendering_mode == SPECIAL_RENDERING_DOUBLE) + dst_rect2 = &dst_rect_screen; + else + dst_rect1 = &dst_rect_screen; + #if defined(HAS_SCREEN_KEYBOARD) if (video.shifted_up || video.shifted_up_delay) { @@ -153,8 +162,8 @@ static void UpdateScreenExt(SDL_Rect *rect, boolean with_frame_delay) video.shifted_up_delay = 0; } - SDL_Rect src_rect_up = { 0, pos, video.width, video.height - pos }; - SDL_Rect dst_rect_up = { 0, 0, video.width, video.height - pos }; + SDL_Rect src_rect_up = { 0, pos, video.width, video.height - pos }; + SDL_Rect dst_rect_up = { xoff, yoff, video.width, video.height - pos }; if (video.screen_rendering_mode == SPECIAL_RENDERING_TARGET || video.screen_rendering_mode == SPECIAL_RENDERING_DOUBLE) @@ -553,14 +562,18 @@ static boolean SDLCreateScreen(boolean fullscreen) #endif #endif + SDLSetScreenSizeAndOffsets(video.width, video.height); + int width = video.width; int height = video.height; + int screen_width = video.screen_width; + int screen_height = video.screen_height; int surface_flags = (fullscreen ? surface_flags_fullscreen : surface_flags_window); // default window size is unscaled - video.window_width = video.width; - video.window_height = video.height; + video.window_width = screen_width; + video.window_height = screen_height; #if defined(TARGET_SDL2) @@ -569,8 +582,8 @@ static boolean SDLCreateScreen(boolean fullscreen) float window_scaling_factor = (float)setup.window_scaling_percent / 100; - video.window_width = window_scaling_factor * width; - video.window_height = window_scaling_factor * height; + video.window_width = window_scaling_factor * screen_width; + video.window_height = window_scaling_factor * screen_height; if (sdl_texture_stream) { @@ -614,7 +627,7 @@ static boolean SDLCreateScreen(boolean fullscreen) if (sdl_renderer != NULL) { - SDL_RenderSetLogicalSize(sdl_renderer, width, height); + SDL_RenderSetLogicalSize(sdl_renderer, screen_width, screen_height); // SDL_SetHint(SDL_HINT_RENDER_SCALE_QUALITY, "linear"); SDL_SetHint(SDL_HINT_RENDER_SCALE_QUALITY, setup.window_scaling_quality); @@ -800,8 +813,8 @@ void SDLSetWindowScaling(int window_scaling_percent) return; float window_scaling_factor = (float)window_scaling_percent / 100; - int new_window_width = (int)(window_scaling_factor * video.width); - int new_window_height = (int)(window_scaling_factor * video.height); + int new_window_width = (int)(window_scaling_factor * video.screen_width); + int new_window_height = (int)(window_scaling_factor * video.screen_height); SDL_SetWindowSize(sdl_window, new_window_width, new_window_height); @@ -873,6 +886,67 @@ void SDLSetWindowFullscreen(boolean fullscreen) video.fullscreen_initial = FALSE; } } + +void SDLSetDisplaySize() +{ + SDL_Rect display_bounds; + + SDL_GetDisplayBounds(0, &display_bounds); + + video.display_width = display_bounds.w; + video.display_height = display_bounds.h; + +#if 0 + Error(ERR_DEBUG, "SDL real screen size: %d x %d", + video.display_width, video.display_height); +#endif +} + +void SDLSetScreenSizeAndOffsets(int width, int height) +{ + // set default video screen size and offsets + video.screen_width = width; + video.screen_height = height; + video.screen_xoffset = 0; + video.screen_yoffset = 0; + +#if defined(PLATFORM_ANDROID) + float ratio_video = (float) width / height; + float ratio_display = (float) video.display_width / video.display_height; + + if (ratio_video != ratio_display) + { + // adjust drawable screen size to cover the whole device display + + if (ratio_video < ratio_display) + video.screen_width *= ratio_display / ratio_video; + else + video.screen_height *= ratio_video / ratio_display; + + video.screen_xoffset = (video.screen_width - width) / 2; + video.screen_yoffset = (video.screen_height - height) / 2; + +#if 0 + Error(ERR_DEBUG, "Changing screen from %dx%d to %dx%d (%.2f to %.2f)", + width, height, + video.screen_width, video.screen_height, + ratio_video, ratio_display); +#endif + } +#endif +} + +void SDLSetScreenSizeForRenderer(int width, int height) +{ + SDL_RenderSetLogicalSize(sdl_renderer, width, height); +} + +void SDLSetScreenProperties() +{ + SDLSetScreenSizeAndOffsets(video.width, video.height); + SDLSetScreenSizeForRenderer(video.screen_width, video.screen_height); +} + #endif void SDLSetScreenRenderingMode(char *screen_rendering_mode) diff --git a/src/libgame/sdl.h b/src/libgame/sdl.h index 60a8411f..c88b6a82 100644 --- a/src/libgame/sdl.h +++ b/src/libgame/sdl.h @@ -440,6 +440,10 @@ SDL_Surface *SDL_DisplayFormat(SDL_Surface *); void SDLSetWindowScaling(int); void SDLSetWindowScalingQuality(char *); void SDLSetWindowFullscreen(boolean); +void SDLSetDisplaySize(void); +void SDLSetScreenSizeAndOffsets(int, int); +void SDLSetScreenSizeForRenderer(int, int); +void SDLSetScreenProperties(void); #endif void SDLSetScreenRenderingMode(char *); diff --git a/src/libgame/system.c b/src/libgame/system.c index 222b6f60..98ccd70c 100644 --- a/src/libgame/system.c +++ b/src/libgame/system.c @@ -363,6 +363,7 @@ void LimitScreenUpdates(boolean enable) void InitVideoDisplay(void) { SDLInitVideoDisplay(); + SDLSetDisplaySize(); } void CloseVideoDisplay(void) @@ -378,6 +379,11 @@ void InitVideoBuffer(int width, int height, int depth, boolean fullscreen) video.height = height; video.depth = GetRealDepth(depth); + video.screen_width = width; + video.screen_height = height; + video.screen_xoffset = 0; + video.screen_yoffset = 0; + video.fullscreen_available = FULLSCREEN_STATUS; video.fullscreen_enabled = FALSE; diff --git a/src/libgame/system.h b/src/libgame/system.h index a11c6b8e..3b51f91d 100644 --- a/src/libgame/system.h +++ b/src/libgame/system.h @@ -788,6 +788,9 @@ struct VideoSystemInfo int default_depth; int width, height, depth; int window_width, window_height; + int display_width, display_height; + int screen_width, screen_height; + int screen_xoffset, screen_yoffset; boolean fullscreen_available; boolean fullscreen_enabled;