From f2d730a52fcb70f5719f5b9a77ea6a9439efb873 Mon Sep 17 00:00:00 2001 From: Gleb Mazovetskiy Date: Sat, 20 May 2023 14:44:53 +0100 Subject: [PATCH] Delay hardware cursor reinit until it is visible We previously reinitialized the hardware cursor during fade in even if it was not visible (e.g. fading into the credits screen). --- Source/hwcursor.cpp | 3 +- Source/hwcursor.hpp | 85 ++++++++++++++++++++++++++++++++------------- 2 files changed, 62 insertions(+), 26 deletions(-) diff --git a/Source/hwcursor.cpp b/Source/hwcursor.cpp index 268a34dbd..8b0f4af92 100644 --- a/Source/hwcursor.cpp +++ b/Source/hwcursor.cpp @@ -151,7 +151,7 @@ bool SetHardwareCursorFromSprite(int pcurs) } // namespace -CursorInfo GetCurrentCursorInfo() +CursorInfo &GetCurrentCursorInfo() { return CurrentCursorInfo; } @@ -160,6 +160,7 @@ void SetHardwareCursor(CursorInfo cursorInfo) { #if SDL_VERSION_ATLEAST(2, 0, 0) CurrentCursorInfo = cursorInfo; + CurrentCursorInfo.setNeedsReinitialization(false); switch (cursorInfo.type()) { case CursorType::Game: #if LOG_HWCURSOR diff --git a/Source/hwcursor.hpp b/Source/hwcursor.hpp index 4d82596b0..b8df88b83 100644 --- a/Source/hwcursor.hpp +++ b/Source/hwcursor.hpp @@ -10,12 +10,10 @@ #include #include "options.h" +#include "utils/log.hpp" // Set this to 1 to log the hardware cursor state changes. #define LOG_HWCURSOR 0 -#if LOG_HWCURSOR -#include "utils/log.hpp" -#endif namespace devilution { @@ -29,24 +27,6 @@ inline bool IsHardwareCursorEnabled() #endif } -/** - * @return Whether the cursor was previously visible. - */ -inline bool SetHardwareCursorVisible(bool visible) -{ -#if SDL_VERSION_ATLEAST(2, 0, 0) -#if LOG_HWCURSOR - const bool isVisible = SDL_ShowCursor(SDL_QUERY) == SDL_ENABLE; - if (isVisible != visible) { - Log("hwcursor: SetHardwareCursorVisible {}", visible); - } -#endif - return SDL_ShowCursor(visible ? SDL_ENABLE : SDL_DISABLE) == 1; -#else - return false; -#endif -} - enum class CursorType : uint8_t { Unknown, UserInterface, @@ -90,11 +70,28 @@ public: void SetEnabled(bool value) { #if LOG_HWCURSOR - Log("hwcursor: SetEnabled {}", value); + if (enabled_ != value) { + Log("hwcursor: SetEnabled {}", value); + } #endif enabled_ = value; } + [[nodiscard]] bool needsReinitialization() + { + return needs_reinitialization_; + } + + void setNeedsReinitialization(bool value) + { +#if LOG_HWCURSOR + if (needs_reinitialization_ != value) { + Log("hwcursor: setNeedsReinitialization {}", value); + } +#endif + needs_reinitialization_ = value; + } + bool operator==(const CursorInfo &other) const { return type_ == other.type_ && (type_ != CursorType::Game || id_ == other.id_); @@ -118,9 +115,11 @@ private: int id_; bool enabled_ = false; + + bool needs_reinitialization_ = false; }; -CursorInfo GetCurrentCursorInfo(); +CursorInfo &GetCurrentCursorInfo(); // Whether the current cursor is a hardware cursor. inline bool IsHardwareCursor() @@ -130,12 +129,48 @@ inline bool IsHardwareCursor() void SetHardwareCursor(CursorInfo cursorInfo); -inline void ReinitializeHardwareCursor() +inline void DoReinitializeHardwareCursor() { #if LOG_HWCURSOR - Log("hwcursor: ReinitializeHardwareCursor"); + Log("hwcursor: DoReinitializeHardwareCursor"); #endif SetHardwareCursor(GetCurrentCursorInfo()); } +inline bool IsHardwareCursorVisible() +{ +#if SDL_VERSION_ATLEAST(2, 0, 0) + return SDL_ShowCursor(SDL_QUERY) == SDL_ENABLE; +#else + return false; +#endif +} + +inline void SetHardwareCursorVisible(bool visible) +{ +#if SDL_VERSION_ATLEAST(2, 0, 0) + if (IsHardwareCursorVisible() == visible) + return; + if (visible && GetCurrentCursorInfo().needsReinitialization()) { + DoReinitializeHardwareCursor(); + } +#if LOG_HWCURSOR + Log("hwcursor: SetHardwareCursorVisible {}", visible); +#endif + if (SDL_ShowCursor(visible ? SDL_ENABLE : SDL_DISABLE) < 0) { + LogError("{}", SDL_GetError()); + SDL_ClearError(); + } +#endif +} + +inline void ReinitializeHardwareCursor() +{ + if (IsHardwareCursorVisible()) { + DoReinitializeHardwareCursor(); + } else { + GetCurrentCursorInfo().setNeedsReinitialization(true); + } +} + } // namespace devilution