Support high-resolution cursor textures (feature 6933)

crashfix_debugdraw
Andrei Kortunov 2 years ago
parent db619c684f
commit a2c02d2999

@ -18,6 +18,7 @@
Bug #6987: Set/Mod Blindness should not darken the screen Bug #6987: Set/Mod Blindness should not darken the screen
Bug #6992: Crossbow reloading doesn't look the same as in Morrowind 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 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 #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 #6979: Add support of loading and displaying LOD assets purely based on their filename extension
Feature #6983: PCVisionBonus script functions Feature #6983: PCVisionBonus script functions

@ -2128,9 +2128,6 @@ namespace MWGui
void WindowManager::createCursors() 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(); MyGUI::ResourceManager::EnumeratorPtr enumerator = MyGUI::ResourceManager::getInstance().getEnumerator();
while (enumerator.next()) while (enumerator.next())
{ {
@ -2148,8 +2145,9 @@ namespace MWGui
Uint8 hotspot_x = imgSetPointer->getHotSpot().left; Uint8 hotspot_x = imgSetPointer->getHotSpot().left;
Uint8 hotspot_y = imgSetPointer->getHotSpot().top; Uint8 hotspot_y = imgSetPointer->getHotSpot().top;
int rotation = imgSetPointer->getRotation(); 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);
} }
} }
} }

@ -79,14 +79,14 @@ namespace SDLUtil
SDL_SetCursor(it->second); 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 #ifndef ANDROID
_createCursorFromResource(name, rotDegrees, image, hotspot_x, hotspot_y); _createCursorFromResource(name, rotDegrees, image, hotspot_x, hotspot_y, cursorWidth, cursorHeight);
#endif #endif
} }
SDLUtil::SurfaceUniquePtr decompress(osg::ref_ptr<osg::Image> source, float rotDegrees) SDLUtil::SurfaceUniquePtr decompress(osg::ref_ptr<osg::Image> source, float rotDegrees, int cursorWidth, int cursorHeight)
{ {
int width = source->s(); int width = source->s();
int height = source->t(); int height = source->t();
@ -114,7 +114,7 @@ namespace SDLUtil
blueMask, blueMask,
alphaMask); 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_Renderer *renderer = SDL_CreateSoftwareRenderer(targetSurface);
SDL_RenderClear(renderer); SDL_RenderClear(renderer);
@ -131,13 +131,13 @@ namespace SDLUtil
return SDLUtil::SurfaceUniquePtr(targetSurface, SDL_FreeSurface); 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()) if (mCursorMap.find(name) != mCursorMap.end())
return; return;
try { try {
auto surface = decompress(image, static_cast<float>(rotDegrees)); auto surface = decompress(image, static_cast<float>(rotDegrees), cursorWidth, cursorHeight);
//set the cursor and store it for later //set the cursor and store it for later
SDL_Cursor* curs = SDL_CreateColorCursor(surface.get(), hotspot_x, hotspot_y); SDL_Cursor* curs = SDL_CreateColorCursor(surface.get(), hotspot_x, hotspot_y);

@ -29,10 +29,10 @@ namespace SDLUtil
/// name of the cursor we changed to ("arrow", "ibeam", etc) /// name of the cursor we changed to ("arrow", "ibeam", etc)
virtual void cursorChanged(const std::string &name); 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: 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 _putPixel(SDL_Surface *surface, int x, int y, Uint32 pixel);
void _setGUICursor(const std::string& name); void _setGUICursor(const std::string& name);

@ -4,21 +4,21 @@
<!-- Cursors --> <!-- Cursors -->
<Resource type="ResourceImageSet" name="ArrowPointerImage"> <Resource type="ResourceImageSet" name="ArrowPointerImage">
<Group name="Pointer" texture="textures\tx_cursor.dds" size="32 32"> <Group name="Pointer" texture="textures\tx_cursor.dds">
<Index name="Pointer" > <Index name="Pointer" >
<Frame point="0 0"/> <Frame point="0 0"/>
</Index> </Index>
</Group> </Group>
</Resource> </Resource>
<Resource type="ResourceImageSet" name="HResizePointerImage"> <Resource type="ResourceImageSet" name="HResizePointerImage">
<Group name="Pointer" texture="textures\tx_cursormove.dds" size="32 32"> <Group name="Pointer" texture="textures\tx_cursormove.dds">
<Index name="Pointer" > <Index name="Pointer" >
<Frame point="0 0"/> <Frame point="0 0"/>
</Index> </Index>
</Group> </Group>
</Resource> </Resource>
<Resource type="ResourceImageSet" name="DropGroundPointerImage"> <Resource type="ResourceImageSet" name="DropGroundPointerImage">
<Group name="Pointer" texture="textures\cursor_drop_ground.dds" size="32 32"> <Group name="Pointer" texture="textures\cursor_drop_ground.dds">
<Index name="Pointer" > <Index name="Pointer" >
<Frame point="0 0"/> <Frame point="0 0"/>
</Index> </Index>

Loading…
Cancel
Save