diff --git a/Source/DiabloUI/credits.cpp b/Source/DiabloUI/credits.cpp index 4d5dd2df2..6c39d5670 100644 --- a/Source/DiabloUI/credits.cpp +++ b/Source/DiabloUI/credits.cpp @@ -200,7 +200,7 @@ bool TextDialog() CreditsRenderer creditsRenderer; bool endMenu = false; - if (IsHardwareCursorEnabled()) + if (IsHardwareCursor()) SetHardwareCursorVisible(false); SDL_Event event; diff --git a/Source/DiabloUI/diabloui.cpp b/Source/DiabloUI/diabloui.cpp index ad0b19396..331cd5cd9 100644 --- a/Source/DiabloUI/diabloui.cpp +++ b/Source/DiabloUI/diabloui.cpp @@ -690,7 +690,7 @@ void UiPollAndRender() UiFadeIn(); // Must happen after the very first UiFadeIn, which sets the cursor. - if (IsHardwareCursorEnabled()) + if (IsHardwareCursor()) SetHardwareCursorVisible(!sgbControllerActive); } @@ -953,7 +953,7 @@ bool UiItemMouseEvents(SDL_Event *event, const std::vector &items) void DrawMouse() { - if (IsHardwareCursorEnabled() || sgbControllerActive) + if (IsHardwareCursor() || sgbControllerActive) return; DrawArt(MouseX, MouseY, &ArtCursor); diff --git a/Source/DiabloUI/dialogs.cpp b/Source/DiabloUI/dialogs.cpp index 422047e82..d286270f6 100644 --- a/Source/DiabloUI/dialogs.cpp +++ b/Source/DiabloUI/dialogs.cpp @@ -264,7 +264,7 @@ void UiOkDialog(const char *text, const char *caption, bool error, const std::ve static bool inDialog = false; if (!gbActive || inDialog) { - if (!IsHardwareCursorEnabled()) { + if (!IsHardwareCursor()) { if (SDL_ShowCursor(SDL_ENABLE) <= -1) { Log("{}", SDL_GetError()); } diff --git a/Source/hwcursor.cpp b/Source/hwcursor.cpp index f3a1578f9..7697d6fe8 100644 --- a/Source/hwcursor.cpp +++ b/Source/hwcursor.cpp @@ -40,7 +40,7 @@ Point GetHotpointPosition(const SDL_Surface &surface, HotpointPosition position) app_fatal("Unhandled enum value"); } -void SetHardwareCursor(SDL_Surface *surface, HotpointPosition hotpointPosition) +bool SetHardwareCursor(SDL_Surface *surface, HotpointPosition hotpointPosition) { float scaleX; float scaleY; @@ -63,11 +63,14 @@ void SetHardwareCursor(SDL_Surface *surface, HotpointPosition hotpointPosition) const Point hotpoint = GetHotpointPosition(*scaledSurface, hotpointPosition); newCursor = SDLCursorUniquePtr { SDL_CreateColorCursor(scaledSurface.get(), hotpoint.x, hotpoint.y) }; } + if (newCursor == nullptr) + return false; SDL_SetCursor(newCursor.get()); CurrentCursor = std::move(newCursor); + return true; } -void SetHardwareCursorFromSprite(int pcurs) +bool SetHardwareCursorFromSprite(int pcurs) { const bool isItem = IsItemSprite(pcurs); const int outlineWidth = isItem ? 1 : 0; @@ -88,8 +91,9 @@ void SetHardwareCursorFromSprite(int pcurs) SDL_SetColorKey(out.surface, 1, TransparentColor); CelDrawCursor(out, { outlineWidth, height - outlineWidth }, pcurs); - SetHardwareCursor(out.surface, isItem ? HotpointPosition::Center : HotpointPosition::TopLeft); + const bool result = SetHardwareCursor(out.surface, isItem ? HotpointPosition::Center : HotpointPosition::TopLeft); out.Free(); + return result; } #endif @@ -106,15 +110,16 @@ void SetHardwareCursor(CursorInfo cursorInfo) CurrentCursorInfo = cursorInfo; switch (cursorInfo.type()) { case CursorType::Game: - SetHardwareCursorFromSprite(cursorInfo.id()); + CurrentCursorInfo.SetEnabled(SetHardwareCursorFromSprite(cursorInfo.id())); break; case CursorType::UserInterface: // ArtCursor is null while loading the game on the progress screen, // called via palette fade from ShowProgress. if (ArtCursor.surface != nullptr) - SetHardwareCursor(ArtCursor.surface.get(), HotpointPosition::TopLeft); + CurrentCursorInfo.SetEnabled(SetHardwareCursor(ArtCursor.surface.get(), HotpointPosition::TopLeft)); break; case CursorType::Unknown: + CurrentCursorInfo.SetEnabled(false); break; } #endif diff --git a/Source/hwcursor.hpp b/Source/hwcursor.hpp index 0daeb8d78..02a5b3600 100644 --- a/Source/hwcursor.hpp +++ b/Source/hwcursor.hpp @@ -9,6 +9,7 @@ namespace devilution { +// Whether the hardware cursor is enabled in settings. inline bool IsHardwareCursorEnabled() { #if SDL_VERSION_ATLEAST(2, 0, 0) @@ -60,6 +61,16 @@ public: return id_; } + [[nodiscard]] bool Enabled() const + { + return enabled_; + } + + void SetEnabled(bool value) + { + enabled_ = value; + } + bool operator==(const CursorInfo &other) const { return type_ == other.type_ && (type_ != CursorType::Game || id_ == other.id_); @@ -73,6 +84,7 @@ private: explicit CursorInfo(CursorType type, int id = 0) : type_(type) , id_(id) + , enabled_(false) { } @@ -80,10 +92,18 @@ private: // ID for CursorType::Game int id_; + + bool enabled_ = false; }; CursorInfo GetCurrentCursorInfo(); +// Whether the current cursor is a hardware cursor. +inline bool IsHardwareCursor() +{ + return GetCurrentCursorInfo().Enabled(); +} + void SetHardwareCursor(CursorInfo cursorInfo); inline void ReinitializeHardwareCursor() diff --git a/Source/interfac.cpp b/Source/interfac.cpp index 174eeac86..448927fe7 100644 --- a/Source/interfac.cpp +++ b/Source/interfac.cpp @@ -225,7 +225,7 @@ void ShowProgress(interface_mode uMsg) BlackPalette(); DrawCutscene(); - if (IsHardwareCursorEnabled()) + if (IsHardwareCursor()) SetHardwareCursorVisible(false); PaletteFadeIn(8); diff --git a/Source/inv.cpp b/Source/inv.cpp index 6f50867fb..ad75eb0d5 100644 --- a/Source/inv.cpp +++ b/Source/inv.cpp @@ -809,8 +809,8 @@ void CheckInvPaste(int pnum, Point cursorPosition) auto &player = plr[pnum]; SetICursor(player.HoldItem._iCurs + CURSOR_FIRSTITEM); - int i = cursorPosition.x + (IsHardwareCursorEnabled() ? 0 : (icursW / 2)); - int j = cursorPosition.y + (IsHardwareCursorEnabled() ? 0 : (icursH / 2)); + int i = cursorPosition.x + (IsHardwareCursor() ? 0 : (icursW / 2)); + int j = cursorPosition.y + (IsHardwareCursor() ? 0 : (icursH / 2)); int sx = icursW28; int sy = icursH28; bool done = false; @@ -1178,7 +1178,7 @@ void CheckInvPaste(int pnum, Point cursorPosition) } CalcPlrInv(pnum, true); if (pnum == myplr) { - if (cn == CURSOR_HAND && !IsHardwareCursorEnabled()) + if (cn == CURSOR_HAND && !IsHardwareCursor()) SetCursorPos(MouseX + (cursW / 2), MouseY + (cursH / 2)); NewCursor(cn); } @@ -1417,7 +1417,7 @@ void CheckInvCut(int pnum, Point cursorPosition, bool automaticMove) holdItem._itype = ITYPE_NONE; } else { NewCursor(holdItem._iCurs + CURSOR_FIRSTITEM); - if (!IsHardwareCursorEnabled()) { + if (!IsHardwareCursor()) { // For a hardware cursor, we set the "hot point" to the center of the item instead. SetCursorPos(cursorPosition.x - (cursW / 2), cursorPosition.y - (cursH / 2)); } diff --git a/Source/palette.cpp b/Source/palette.cpp index 7ec488da3..7ce116d84 100644 --- a/Source/palette.cpp +++ b/Source/palette.cpp @@ -228,7 +228,7 @@ void SetFadeLevel(int fadeval) system_palette[i].b = (fadeval * logical_palette[i].b) / 256; } palette_update(); - if (IsHardwareCursorEnabled()) { + if (IsHardwareCursor()) { ReinitializeHardwareCursor(); } } diff --git a/Source/scrollrt.cpp b/Source/scrollrt.cpp index 2013b2628..57caae772 100644 --- a/Source/scrollrt.cpp +++ b/Source/scrollrt.cpp @@ -1528,7 +1528,7 @@ void scrollrt_draw_game_screen() hgt = gnScreenHeight; } - if (IsHardwareCursorEnabled()) { + if (IsHardwareCursor()) { SetHardwareCursorVisible(ShouldShowCursor()); } else { lock_buf(0); @@ -1540,7 +1540,7 @@ void scrollrt_draw_game_screen() RenderPresent(); - if (!IsHardwareCursorEnabled()) { + if (!IsHardwareCursor()) { lock_buf(0); UndrawCursor(GlobalBackBuffer()); unlock_buf(0); @@ -1604,7 +1604,7 @@ void DrawAndBlit() } DrawXPBar(out); - if (IsHardwareCursorEnabled()) { + if (IsHardwareCursor()) { SetHardwareCursorVisible(ShouldShowCursor()); } else { DrawCursor(out);