From a2c02d2999c59649accadf1c6b79012ed110a1d9 Mon Sep 17 00:00:00 2001 From: Andrei Kortunov Date: Thu, 11 Aug 2022 14:38:00 +0400 Subject: [PATCH] Support high-resolution cursor textures (feature 6933) --- CHANGELOG.md | 1 + apps/openmw/mwgui/windowmanagerimp.cpp | 6 ++---- components/sdlutil/sdlcursormanager.cpp | 12 ++++++------ components/sdlutil/sdlcursormanager.hpp | 4 ++-- files/data/mygui/openmw_resources.xml | 6 +++--- 5 files changed, 14 insertions(+), 15 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 3ceb2952dc..f3769c8eaf 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -18,6 +18,7 @@ Bug #6987: Set/Mod Blindness should not darken the screen Bug #6992: Crossbow reloading doesn't look the same as in Morrowind Bug #6993: Shooting your last round of ammunition causes the attack animation to cancel + Feature #6933: Support high-resolution cursor textures Feature #6945: Support S3TC-compressed and BGR/BGRA NiPixelData Feature #6979: Add support of loading and displaying LOD assets purely based on their filename extension Feature #6983: PCVisionBonus script functions diff --git a/apps/openmw/mwgui/windowmanagerimp.cpp b/apps/openmw/mwgui/windowmanagerimp.cpp index 8889c970c1..6927229fa9 100644 --- a/apps/openmw/mwgui/windowmanagerimp.cpp +++ b/apps/openmw/mwgui/windowmanagerimp.cpp @@ -2128,9 +2128,6 @@ namespace MWGui void WindowManager::createCursors() { - // FIXME: currently we do not scale cursor since it is not a MyGUI widget. - // In theory, we can do it manually (rescale the cursor image via osg::Imag::scaleImage() and scale the hotspot position). - // Unfortunately, this apploach can lead to driver crashes on some setups (e.g. on laptops with nvidia-prime on Linux). MyGUI::ResourceManager::EnumeratorPtr enumerator = MyGUI::ResourceManager::getInstance().getEnumerator(); while (enumerator.next()) { @@ -2148,8 +2145,9 @@ namespace MWGui Uint8 hotspot_x = imgSetPointer->getHotSpot().left; Uint8 hotspot_y = imgSetPointer->getHotSpot().top; int rotation = imgSetPointer->getRotation(); + MyGUI::IntSize pointerSize = imgSetPointer->getSize(); - mCursorManager->createCursor(imgSetPointer->getResourceName(), rotation, image, hotspot_x, hotspot_y); + mCursorManager->createCursor(imgSetPointer->getResourceName(), rotation, image, hotspot_x, hotspot_y, pointerSize.width, pointerSize.height); } } } diff --git a/components/sdlutil/sdlcursormanager.cpp b/components/sdlutil/sdlcursormanager.cpp index 6a67119ad8..340da4d35a 100644 --- a/components/sdlutil/sdlcursormanager.cpp +++ b/components/sdlutil/sdlcursormanager.cpp @@ -79,14 +79,14 @@ namespace SDLUtil SDL_SetCursor(it->second); } - void SDLCursorManager::createCursor(const std::string& name, int rotDegrees, osg::Image* image, Uint8 hotspot_x, Uint8 hotspot_y) + void SDLCursorManager::createCursor(const std::string& name, int rotDegrees, osg::Image* image, Uint8 hotspot_x, Uint8 hotspot_y, int cursorWidth, int cursorHeight) { #ifndef ANDROID - _createCursorFromResource(name, rotDegrees, image, hotspot_x, hotspot_y); + _createCursorFromResource(name, rotDegrees, image, hotspot_x, hotspot_y, cursorWidth, cursorHeight); #endif } - SDLUtil::SurfaceUniquePtr decompress(osg::ref_ptr source, float rotDegrees) + SDLUtil::SurfaceUniquePtr decompress(osg::ref_ptr source, float rotDegrees, int cursorWidth, int cursorHeight) { int width = source->s(); int height = source->t(); @@ -114,7 +114,7 @@ namespace SDLUtil blueMask, alphaMask); - SDL_Surface *targetSurface = SDL_CreateRGBSurface(0, width, height, 32, redMask, greenMask, blueMask, alphaMask); + SDL_Surface *targetSurface = SDL_CreateRGBSurface(0, cursorWidth, cursorHeight, 32, redMask, greenMask, blueMask, alphaMask); SDL_Renderer *renderer = SDL_CreateSoftwareRenderer(targetSurface); SDL_RenderClear(renderer); @@ -131,13 +131,13 @@ namespace SDLUtil return SDLUtil::SurfaceUniquePtr(targetSurface, SDL_FreeSurface); } - void SDLCursorManager::_createCursorFromResource(const std::string& name, int rotDegrees, osg::Image* image, Uint8 hotspot_x, Uint8 hotspot_y) + void SDLCursorManager::_createCursorFromResource(const std::string& name, int rotDegrees, osg::Image* image, Uint8 hotspot_x, Uint8 hotspot_y, int cursorWidth, int cursorHeight) { if (mCursorMap.find(name) != mCursorMap.end()) return; try { - auto surface = decompress(image, static_cast(rotDegrees)); + auto surface = decompress(image, static_cast(rotDegrees), cursorWidth, cursorHeight); //set the cursor and store it for later SDL_Cursor* curs = SDL_CreateColorCursor(surface.get(), hotspot_x, hotspot_y); diff --git a/components/sdlutil/sdlcursormanager.hpp b/components/sdlutil/sdlcursormanager.hpp index f338778d1a..7d0efe9879 100644 --- a/components/sdlutil/sdlcursormanager.hpp +++ b/components/sdlutil/sdlcursormanager.hpp @@ -29,10 +29,10 @@ namespace SDLUtil /// name of the cursor we changed to ("arrow", "ibeam", etc) virtual void cursorChanged(const std::string &name); - virtual void createCursor(const std::string &name, int rotDegrees, osg::Image* image, Uint8 hotspot_x, Uint8 hotspot_y); + virtual void createCursor(const std::string &name, int rotDegrees, osg::Image* image, Uint8 hotspot_x, Uint8 hotspot_y, int cursorWidth, int cursorHeight); private: - void _createCursorFromResource(const std::string &name, int rotDegrees, osg::Image* image, Uint8 hotspot_x, Uint8 hotspot_y); + void _createCursorFromResource(const std::string &name, int rotDegrees, osg::Image* image, Uint8 hotspot_x, Uint8 hotspot_y, int cursorWidth, int cursorHeight); void _putPixel(SDL_Surface *surface, int x, int y, Uint32 pixel); void _setGUICursor(const std::string& name); diff --git a/files/data/mygui/openmw_resources.xml b/files/data/mygui/openmw_resources.xml index 70fccbfbe7..4c32512004 100644 --- a/files/data/mygui/openmw_resources.xml +++ b/files/data/mygui/openmw_resources.xml @@ -4,21 +4,21 @@ - + - + - +