From 9599117c2821f20055786fd7db9ccd09caa95c6d Mon Sep 17 00:00:00 2001 From: Benau Date: Wed, 22 Jul 2020 09:41:15 +0800 Subject: [PATCH] Add high dpi support to supported platforms --- data/SuperTuxKart-Info.plist | 4 +- lib/irrlicht/include/IrrlichtDevice.h | 3 +- .../source/Irrlicht/CIrrDeviceSDL.cpp | 119 ++++++++++++------ lib/irrlicht/source/Irrlicht/CIrrDeviceSDL.h | 14 +-- lib/irrlicht/source/Irrlicht/CIrrDeviceiOS.mm | 3 +- src/graphics/irr_driver.cpp | 18 --- src/guiengine/widgets/CGUIEditBox.cpp | 13 +- 7 files changed, 103 insertions(+), 71 deletions(-) diff --git a/data/SuperTuxKart-Info.plist b/data/SuperTuxKart-Info.plist index 3dba0d695..97841eeb1 100644 --- a/data/SuperTuxKart-Info.plist +++ b/data/SuperTuxKart-Info.plist @@ -25,6 +25,8 @@ CSResourcesFileMapped LSMinimumSystemVersion - 10.9 + 10.9 + NSHighResolutionCapable + diff --git a/lib/irrlicht/include/IrrlichtDevice.h b/lib/irrlicht/include/IrrlichtDevice.h index f18f65111..d8f4be68e 100644 --- a/lib/irrlicht/include/IrrlichtDevice.h +++ b/lib/irrlicht/include/IrrlichtDevice.h @@ -314,7 +314,8 @@ namespace irr virtual s32 getBottomPadding() { return 0; } virtual s32 getLeftPadding() { return 0; } virtual s32 getRightPadding() { return 0; } - virtual f32 getNativeScale() const { return 1.0f; } + virtual f32 getNativeScaleX() const { return 1.0f; } + virtual f32 getNativeScaleY() const { return 1.0f; } virtual void setWindowMinimumSize(u32 width, u32 height) {} virtual void resetPaused() {} virtual void resetUnpaused() {} diff --git a/lib/irrlicht/source/Irrlicht/CIrrDeviceSDL.cpp b/lib/irrlicht/source/Irrlicht/CIrrDeviceSDL.cpp index f70d562f0..bd75fec9b 100644 --- a/lib/irrlicht/source/Irrlicht/CIrrDeviceSDL.cpp +++ b/lib/irrlicht/source/Irrlicht/CIrrDeviceSDL.cpp @@ -19,6 +19,8 @@ #include "SIrrCreationParameters.h" #include "COpenGLExtensionHandler.h" +#include "guiengine/engine.hpp" + extern bool GLContextDebugBit; namespace irr @@ -35,16 +37,19 @@ namespace irr } // end namespace irr -extern "C" void init_objc(SDL_SysWMinfo* info, float* ns, float* top, float* bottom, float* left, float* right); +extern "C" void init_objc(SDL_SysWMinfo* info, float* top, float* bottom, float* left, float* right); extern "C" int handle_app_event(void* userdata, SDL_Event* event); namespace irr { +float g_native_scale_x = 1.0f; +float g_native_scale_y = 1.0f; + //! constructor CIrrDeviceSDL::CIrrDeviceSDL(const SIrrlichtCreationParameters& param) : CIrrDeviceStub(param), - Window(0), Context(0), NativeScale(1.0f), + Window(0), Context(0), MouseX(0), MouseY(0), MouseButtonStates(0), Width(param.WindowSize.Width), Height(param.WindowSize.Height), TopPadding(0), BottomPadding(0), LeftPadding(0), RightPadding(0), @@ -85,11 +90,7 @@ CIrrDeviceSDL::CIrrDeviceSDL(const SIrrlichtCreationParameters& param) if (!SDL_GetWindowWMInfo(Window, &Info)) return; #ifdef IOS_STK - init_objc(&Info, &NativeScale, &TopPadding, &BottomPadding, &LeftPadding, &RightPadding); - Width *= NativeScale; - Height *= NativeScale; - CreationParams.WindowSize.Width = Width; - CreationParams.WindowSize.Height = Height; + init_objc(&Info, &TopPadding, &BottomPadding, &LeftPadding, &RightPadding); #endif core::stringc sdlversion = "SDL Version "; sdlversion += Info.version.major; @@ -113,6 +114,32 @@ CIrrDeviceSDL::CIrrDeviceSDL(const SIrrlichtCreationParameters& param) else return; } +#ifndef ANDROID + else if (!GUIEngine::isNoGraphics()) + { + // Get highdpi native scale using renderer so it will work with any + // backend later (opengl or vulkan) + // Android doesn't use high dpi + SDL_Window* window = NULL; + SDL_Renderer* renderer = NULL; + if (SDL_CreateWindowAndRenderer(640, 480, + SDL_WINDOW_ALLOW_HIGHDPI | SDL_WINDOW_HIDDEN, + &window, &renderer) == 0) + { + int w, h, rw, rh; + w = h = rw = rh = 0; + SDL_GetWindowSize(window, &w, &h); + SDL_GetRendererOutputSize(renderer, &rw, &rh); + if (w != 0 && h != 0 && rw != 0 && rh != 0) + { + g_native_scale_x = (float)rw / (float)w; + g_native_scale_y = (float)rh / (float)h; + } + SDL_DestroyRenderer(renderer); + SDL_DestroyWindow(window); + } + } +#endif // create cursor control CursorControl = new CCursorControl(this); @@ -289,7 +316,7 @@ bool CIrrDeviceSDL::createWindow() SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 16); } - u32 flags = SDL_WINDOW_SHOWN; + u32 flags = SDL_WINDOW_SHOWN | SDL_WINDOW_ALLOW_HIGHDPI; if (CreationParams.Fullscreen) flags |= SDL_WINDOW_FULLSCREEN; @@ -298,7 +325,7 @@ bool CIrrDeviceSDL::createWindow() flags |= SDL_WINDOW_OPENGL; #ifdef MOBILE_STK - flags |= SDL_WINDOW_BORDERLESS | SDL_WINDOW_ALLOW_HIGHDPI | SDL_WINDOW_MAXIMIZED; + flags |= SDL_WINDOW_BORDERLESS | SDL_WINDOW_MAXIMIZED; #endif tryCreateOpenGLContext(flags); @@ -344,9 +371,11 @@ start: SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 3); SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 0); - Window = SDL_CreateWindow("", CreationParams.WindowPosition.X, - CreationParams.WindowPosition.Y, CreationParams.WindowSize.Width, - CreationParams.WindowSize.Height, flags); + Window = SDL_CreateWindow("", + (float)CreationParams.WindowPosition.X / g_native_scale_x, + (float)CreationParams.WindowPosition.Y / g_native_scale_y, + (float)CreationParams.WindowSize.Width / g_native_scale_x, + (float)CreationParams.WindowSize.Height / g_native_scale_y, flags); if (Window) { Context = SDL_GL_CreateContext(Window); @@ -367,9 +396,11 @@ start: SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 4); SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 3); - Window = SDL_CreateWindow("", CreationParams.WindowPosition.X, - CreationParams.WindowPosition.Y, CreationParams.WindowSize.Width, - CreationParams.WindowSize.Height, flags); + Window = SDL_CreateWindow("", + (float)CreationParams.WindowPosition.X / g_native_scale_x, + (float)CreationParams.WindowPosition.Y / g_native_scale_y, + (float)CreationParams.WindowSize.Width / g_native_scale_x, + (float)CreationParams.WindowSize.Height / g_native_scale_y, flags); if (Window) { Context = SDL_GL_CreateContext(Window); @@ -389,9 +420,11 @@ start: SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 3); SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 3); - Window = SDL_CreateWindow("", CreationParams.WindowPosition.X, - CreationParams.WindowPosition.Y, CreationParams.WindowSize.Width, - CreationParams.WindowSize.Height, flags); + Window = SDL_CreateWindow("", + (float)CreationParams.WindowPosition.X / g_native_scale_x, + (float)CreationParams.WindowPosition.Y / g_native_scale_y, + (float)CreationParams.WindowSize.Width / g_native_scale_x, + (float)CreationParams.WindowSize.Height / g_native_scale_y, flags); if (Window) { Context = SDL_GL_CreateContext(Window); @@ -411,9 +444,11 @@ start: SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 3); SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 1); - Window = SDL_CreateWindow("", CreationParams.WindowPosition.X, - CreationParams.WindowPosition.Y, CreationParams.WindowSize.Width, - CreationParams.WindowSize.Height, flags); + Window = SDL_CreateWindow("", + (float)CreationParams.WindowPosition.X / g_native_scale_x, + (float)CreationParams.WindowPosition.Y / g_native_scale_y, + (float)CreationParams.WindowSize.Width / g_native_scale_x, + (float)CreationParams.WindowSize.Height / g_native_scale_y, flags); if (Window) { Context = SDL_GL_CreateContext(Window); @@ -445,9 +480,11 @@ legacy: SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_ES); else SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, 0); - Window = SDL_CreateWindow("", CreationParams.WindowPosition.X, - CreationParams.WindowPosition.Y, CreationParams.WindowSize.Width, - CreationParams.WindowSize.Height, flags); + Window = SDL_CreateWindow("", + (float)CreationParams.WindowPosition.X / g_native_scale_x, + (float)CreationParams.WindowPosition.Y / g_native_scale_y, + (float)CreationParams.WindowSize.Width / g_native_scale_x, + (float)CreationParams.WindowSize.Height / g_native_scale_y, flags); if (Window) { Context = SDL_GL_CreateContext(Window); @@ -594,8 +631,8 @@ bool CIrrDeviceSDL::run() case SDL_MOUSEMOTION: irrevent.EventType = irr::EET_MOUSE_INPUT_EVENT; irrevent.MouseInput.Event = irr::EMIE_MOUSE_MOVED; - MouseX = irrevent.MouseInput.X = SDL_event.motion.x * NativeScale; - MouseY = irrevent.MouseInput.Y = SDL_event.motion.y * NativeScale; + MouseX = irrevent.MouseInput.X = SDL_event.motion.x * g_native_scale_x; + MouseY = irrevent.MouseInput.Y = SDL_event.motion.y * g_native_scale_y; irrevent.MouseInput.ButtonStates = MouseButtonStates; postEventFromUser(irrevent); @@ -605,8 +642,8 @@ bool CIrrDeviceSDL::run() case SDL_MOUSEBUTTONUP: irrevent.EventType = irr::EET_MOUSE_INPUT_EVENT; - irrevent.MouseInput.X = SDL_event.button.x * NativeScale; - irrevent.MouseInput.Y = SDL_event.button.y * NativeScale; + irrevent.MouseInput.X = SDL_event.button.x * g_native_scale_x; + irrevent.MouseInput.Y = SDL_event.button.y * g_native_scale_y; irrevent.MouseInput.Event = irr::EMIE_MOUSE_MOVED; @@ -712,8 +749,8 @@ bool CIrrDeviceSDL::run() case SDL_WINDOWEVENT: { - u32 new_width = SDL_event.window.data1 * NativeScale; - u32 new_height = SDL_event.window.data2 * NativeScale; + u32 new_width = SDL_event.window.data1 * g_native_scale_x; + u32 new_height = SDL_event.window.data2 * g_native_scale_y; if (SDL_event.window.event == SDL_WINDOWEVENT_SIZE_CHANGED && ((new_width != Width) || (new_height != Height))) { @@ -851,20 +888,20 @@ video::IVideoModeList* CIrrDeviceSDL::getVideoModeList() if (SDL_GetDesktopDisplayMode(0, &mode) == 0) { VideoModeList.setDesktop(SDL_BITSPERPIXEL(mode.format), - core::dimension2d(mode.w * NativeScale, mode.h * NativeScale)); + core::dimension2d(mode.w * g_native_scale_x, mode.h * g_native_scale_y)); } #ifdef MOBILE_STK // SDL2 will return w,h and h,w for mobile STK, as we only use landscape // so we just use desktop resolution for now - VideoModeList.addMode(core::dimension2d(mode.w * NativeScale, mode.h * NativeScale), + VideoModeList.addMode(core::dimension2d(mode.w * g_native_scale_x, mode.h * g_native_scale_y), SDL_BITSPERPIXEL(mode.format)); #else for (int i = 0; i < mode_count; i++) { if (SDL_GetDisplayMode(0, i, &mode) == 0) { - VideoModeList.addMode(core::dimension2d(mode.w * NativeScale, mode.h * NativeScale), + VideoModeList.addMode(core::dimension2d(mode.w * g_native_scale_x, mode.h * g_native_scale_y), SDL_BITSPERPIXEL(mode.format)); } } @@ -1287,7 +1324,7 @@ extern "C" int Android_getMovedHeight(); s32 CIrrDeviceSDL::getMovedHeight() const { #if defined(IOS_STK) - return SDL_GetMovedHeightByScreenKeyboard() * NativeScale; + return SDL_GetMovedHeightByScreenKeyboard() * g_native_scale_y; #elif defined(ANDROID) return Android_getMovedHeight(); #else @@ -1300,7 +1337,7 @@ extern "C" int Android_getKeyboardHeight(); u32 CIrrDeviceSDL::getOnScreenKeyboardHeight() const { #if defined(IOS_STK) - return SDL_GetScreenKeyboardHeight() * NativeScale; + return SDL_GetScreenKeyboardHeight() * g_native_scale_y; #elif defined(ANDROID) return Android_getKeyboardHeight(); #else @@ -1308,6 +1345,18 @@ u32 CIrrDeviceSDL::getOnScreenKeyboardHeight() const #endif } + +f32 CIrrDeviceSDL::getNativeScaleX() const +{ + return g_native_scale_x; +} + + +f32 CIrrDeviceSDL::getNativeScaleY() const +{ + return g_native_scale_y; +} + } // end namespace irr #endif // _IRR_COMPILE_WITH_SDL_DEVICE_ diff --git a/lib/irrlicht/source/Irrlicht/CIrrDeviceSDL.h b/lib/irrlicht/source/Irrlicht/CIrrDeviceSDL.h index 231b6317f..ec34d1370 100644 --- a/lib/irrlicht/source/Irrlicht/CIrrDeviceSDL.h +++ b/lib/irrlicht/source/Irrlicht/CIrrDeviceSDL.h @@ -106,7 +106,7 @@ namespace irr //! Get the device type virtual E_DEVICE_TYPE getType() const { - return EIDT_SDL; + return EIDT_SDL; } SDL_Window* getWindow() const { return Window; } @@ -115,25 +115,26 @@ namespace irr virtual s32 getTopPadding() { - return TopPadding * NativeScale; + return TopPadding * getNativeScaleY(); } virtual s32 getBottomPadding() { - return BottomPadding * NativeScale; + return BottomPadding * getNativeScaleY(); } virtual s32 getLeftPadding() { - return LeftPadding * NativeScale; + return LeftPadding * getNativeScaleX(); } virtual s32 getRightPadding() { - return RightPadding * NativeScale; + return RightPadding * getNativeScaleX(); } - virtual f32 getNativeScale() const { return NativeScale; } + virtual f32 getNativeScaleX() const; + virtual f32 getNativeScaleY() const; virtual bool hasOnScreenKeyboard() const; @@ -255,7 +256,6 @@ namespace irr SDL_Window* Window; SDL_GLContext Context; - f32 NativeScale; s32 MouseX, MouseY; u32 MouseButtonStates; diff --git a/lib/irrlicht/source/Irrlicht/CIrrDeviceiOS.mm b/lib/irrlicht/source/Irrlicht/CIrrDeviceiOS.mm index d333c3b06..88ad0039b 100644 --- a/lib/irrlicht/source/Irrlicht/CIrrDeviceiOS.mm +++ b/lib/irrlicht/source/Irrlicht/CIrrDeviceiOS.mm @@ -35,9 +35,8 @@ void irr::CIrrDeviceiOS::debugPrint(const char* line) NSLog(@"%@", ns); } -extern "C" void init_objc(SDL_SysWMinfo* info, float* ns, float* top, float* bottom, float* left, float* right) +extern "C" void init_objc(SDL_SysWMinfo* info, float* top, float* bottom, float* left, float* right) { - *ns = info->info.uikit.window.screen.nativeScale; if (@available(iOS 11.0, *)) { *top = info->info.uikit.window.safeAreaInsets.top, diff --git a/src/graphics/irr_driver.cpp b/src/graphics/irr_driver.cpp index 2cc8240fe..d57866f69 100644 --- a/src/graphics/irr_driver.cpp +++ b/src/graphics/irr_driver.cpp @@ -589,24 +589,6 @@ void IrrDriver::initDevice() } #endif -#ifdef IOS_STK - // After real device is created reload video mode list with native scale - video::IVideoModeList* modes = m_device->getVideoModeList(); - if (UserConfigParams::m_fullscreen) - { - const core::dimension2d ssize = modes->getDesktopResolution(); - if (ssize.Width < 1 || ssize.Height < 1) - { - Log::warn("irr_driver", "Unknown desktop resolution."); - } - UserConfigParams::m_width = ssize.Width; - UserConfigParams::m_height = ssize.Height; - m_modes.clear(); - VideoMode mode(UserConfigParams::m_width, UserConfigParams::m_height); - m_modes.push_back(mode); - } -#endif - m_scene_manager = m_device->getSceneManager(); m_gui_env = m_device->getGUIEnvironment(); m_video_driver = m_device->getVideoDriver(); diff --git a/src/guiengine/widgets/CGUIEditBox.cpp b/src/guiengine/widgets/CGUIEditBox.cpp index 19ad41272..8b88689b7 100644 --- a/src/guiengine/widgets/CGUIEditBox.cpp +++ b/src/guiengine/widgets/CGUIEditBox.cpp @@ -1382,13 +1382,12 @@ void CGUIEditBox::calculateScrollPos() rect.w = 1; rect.h = CurrentTextRect.LowerRightCorner.Y - CurrentTextRect.UpperLeftCorner.Y; - float inverse_scale = 1.0f; - if (irr_driver->getDevice()->getNativeScale() > 0.0f) - inverse_scale = 1.0f / irr_driver->getDevice()->getNativeScale(); - rect.x *= inverse_scale; - rect.y *= inverse_scale; - rect.w *= inverse_scale; - rect.h *= inverse_scale; + float inverse_scale_x = 1.0f / irr_driver->getDevice()->getNativeScaleX(); + float inverse_scale_y = 1.0f / irr_driver->getDevice()->getNativeScaleY(); + rect.x *= inverse_scale_x; + rect.y *= inverse_scale_y; + rect.w *= inverse_scale_x; + rect.h *= inverse_scale_y; SDL_SetTextInputRect(&rect); #endif