diff --git a/assets/opensb/interface/graphicsmenu/body.png.patch.lua b/assets/opensb/interface/graphicsmenu/body.png.patch.lua index 76ed0c4..32afe25 100644 --- a/assets/opensb/interface/graphicsmenu/body.png.patch.lua +++ b/assets/opensb/interface/graphicsmenu/body.png.patch.lua @@ -6,4 +6,6 @@ function patch(image) image:copyInto({119, 26}, checkbox) -- Object Lighting image:copyInto({19, 15}, checkbox) + -- Hardware Cursor + image:copyInto({119, 15}, checkbox) end \ No newline at end of file diff --git a/assets/opensb/interface/windowconfig/graphicsmenu.config.patch.lua b/assets/opensb/interface/windowconfig/graphicsmenu.config.patch.lua index 3f28954..50cf130 100644 --- a/assets/opensb/interface/windowconfig/graphicsmenu.config.patch.lua +++ b/assets/opensb/interface/windowconfig/graphicsmenu.config.patch.lua @@ -28,8 +28,11 @@ function patch(config) -- Create anti-aliasing toggle shift(clone(layout, "multiTextureLabel", "antiAliasingLabel"), 98).value = "SUPER-SAMPLED AA" shift(clone(layout, "multiTextureCheckbox", "antiAliasingCheckbox"), 99) --- Create object lighting toggle + -- Create object lighting toggle shift(clone(layout, "multiTextureLabel", "objectLightingLabel"), 0, -11).value = "NEW OBJECT LIGHTS" shift(clone(layout, "multiTextureCheckbox", "objectLightingCheckbox"), 0, -11) + -- Create hardware cursor toggle + shift(clone(layout, "multiTextureLabel", "hardwareCursorLabel"), 98, -11).value = "HARDWARE CURSOR" + shift(clone(layout, "multiTextureCheckbox", "hardwareCursorCheckbox"), 99, -11) return config end \ No newline at end of file diff --git a/source/application/StarApplicationController.hpp b/source/application/StarApplicationController.hpp index 0e288d2..9ae8a87 100644 --- a/source/application/StarApplicationController.hpp +++ b/source/application/StarApplicationController.hpp @@ -41,6 +41,7 @@ public: virtual void setVSyncEnabled(bool vSync) = 0; virtual void setCursorVisible(bool cursorVisible) = 0; virtual void setCursorPosition(Vec2I cursorPosition) = 0; + virtual void setCursorHardware(bool cursorHardware) = 0; virtual bool setCursorImage(const String& id, const ImageConstPtr& image, unsigned scale, const Vec2I& offset) = 0; virtual void setAcceptingTextInput(bool acceptingTextInput) = 0; diff --git a/source/application/StarMainApplication_sdl.cpp b/source/application/StarMainApplication_sdl.cpp index cb631ff..277df57 100644 --- a/source/application/StarMainApplication_sdl.cpp +++ b/source/application/StarMainApplication_sdl.cpp @@ -630,6 +630,10 @@ private: SDL_WarpMouseInWindow(parent->m_sdlWindow, cursorPosition[0], cursorPosition[1]); } + void setCursorHardware(bool hardware) override { + parent->m_cursorHardware = hardware; + } + bool setCursorImage(const String& id, const ImageConstPtr& image, unsigned scale, const Vec2I& offset) override { return parent->setCursorImage(id, image, scale, offset); } @@ -828,12 +832,16 @@ private: } } - static const size_t MaximumCursorDimensions = 128; - static const size_t MaximumCursorPixelCount = MaximumCursorDimensions * MaximumCursorDimensions; + static const size_t MaxCursorSize = 128; bool setCursorImage(const String& id, const ImageConstPtr& image, unsigned scale, const Vec2I& offset) { auto imageSize = image->size().piecewiseMultiply(Vec2U::filled(scale)); - if (!scale || imageSize.max() > MaximumCursorDimensions || (size_t)(imageSize[0] * imageSize[1]) > MaximumCursorPixelCount) + if (!m_cursorHardware || !scale || imageSize.max() > MaxCursorSize || imageSize.product() > square(MaxCursorSize)) { + if (auto defaultCursor = SDL_GetDefaultCursor()) { + if (SDL_GetCursor() != defaultCursor) + SDL_SetCursor(defaultCursor); + } return m_cursorVisible = false; + } auto& entry = m_cursorCache.get(m_currentCursor = { scale, offset, id }, [&](auto const&) { auto entry = std::make_shared(); @@ -926,6 +934,7 @@ private: bool m_windowVSync = true; unsigned m_maxFrameSkip = 5; bool m_cursorVisible = true; + bool m_cursorHardware = true; bool m_acceptingTextInput = false; bool m_audioEnabled = false; bool m_quitRequested = false; diff --git a/source/client/StarClientApplication.cpp b/source/client/StarClientApplication.cpp index c83c9e7..82d18cf 100644 --- a/source/client/StarClientApplication.cpp +++ b/source/client/StarClientApplication.cpp @@ -53,6 +53,7 @@ Json const AdditionalDefaultConfiguration = Json::parseJson(R"JSON( "sfxVol" : 100, "instrumentVol" : 100, "musicVol" : 70, + "hardwareCursor" : true, "windowedResolution" : [1000, 600], "fullscreenResolution" : [1920, 1080], "fullscreen" : false, @@ -207,6 +208,7 @@ void ClientApplication::applicationInit(ApplicationControllerPtr appController) appController->setTargetUpdateRate(updateRate); appController->setApplicationTitle(assets->json("/client.config:windowTitle").toString()); appController->setVSyncEnabled(vsync); + appController->setCursorHardware(configuration->get("hardwareCursor").optBool().value(true)); if (fullscreen) appController->setFullscreenWindow(fullscreenSize); diff --git a/source/frontend/StarGraphicsMenu.cpp b/source/frontend/StarGraphicsMenu.cpp index 210b318..a3d78e7 100644 --- a/source/frontend/StarGraphicsMenu.cpp +++ b/source/frontend/StarGraphicsMenu.cpp @@ -80,6 +80,12 @@ GraphicsMenu::GraphicsMenu() { Root::singleton().configuration()->set("antiAliasing", checked); syncGui(); }); + reader.registerCallback("hardwareCursorCheckbox", [=](Widget*) { + bool checked = fetchChild("hardwareCursorCheckbox")->isChecked(); + m_localChanges.set("hardwareCursor", checked); + Root::singleton().configuration()->set("hardwareCursor", checked); + GuiContext::singleton().applicationController()->setCursorHardware(checked); + }); reader.registerCallback("monochromeCheckbox", [=](Widget*) { bool checked = fetchChild("monochromeCheckbox")->isChecked(); m_localChanges.set("monochromeLighting", checked); @@ -146,6 +152,7 @@ StringList const GraphicsMenu::ConfigKeys = { "limitTextureAtlasSize", "useMultiTexturing", "antiAliasing", + "hardwareCursor", "monochromeLighting", "newObjectLighting" }; @@ -204,6 +211,7 @@ void GraphicsMenu::syncGui() { fetchChild("antiAliasingCheckbox")->setChecked(m_localChanges.get("antiAliasing").toBool()); fetchChild("monochromeCheckbox")->setChecked(m_localChanges.get("monochromeLighting").toBool()); fetchChild("objectLightingCheckbox")->setChecked(m_localChanges.get("newObjectLighting").optBool().value(true)); + fetchChild("hardwareCursorCheckbox")->setChecked(m_localChanges.get("hardwareCursor").toBool()); } void GraphicsMenu::apply() {