diff --git a/gui/layout/options.dat b/gui/layout/options.dat
index ebdec74f4..5a27bfcf7 100755
--- a/gui/layout/options.dat
+++ b/gui/layout/options.dat
@@ -38,3 +38,6 @@ CB 6995 240 159
// Reverse mouse
CB 6994 240 179
+
+// Grab mouse
+CB 11002 240 199
diff --git a/machstrg.xml b/machstrg.xml
index fff7ec258..9bbb031d9 100755
--- a/machstrg.xml
+++ b/machstrg.xml
@@ -1494,4 +1494,6 @@ BELONGING TO
>Scale Factor
The UI Scale Factor settings will not take effect until you re-run the game.
+Grab Mouse
diff --git a/src/libdev/machgui/ctxoptns.cpp b/src/libdev/machgui/ctxoptns.cpp
index 8e23b9e4f..2296b8238 100644
--- a/src/libdev/machgui/ctxoptns.cpp
+++ b/src/libdev/machgui/ctxoptns.cpp
@@ -45,9 +45,10 @@
#define OPTIONS_AREA_MINX 95
#define OPTIONS_AREA_MINY 50
#define OPTIMISATIONS_AREA_MINX OPTIONS_AREA_MINX
-#define OPTIMISATIONS_AREA_MINY 209
+#define OPTIMISATIONS_AREA_MINY 239
const char c_ScaleFactorOptionKey[] = "Options\\Scale Factor";
+const char c_GrabCursorOptionKey[] = "Options\\Grab Cursor";
class MachGuiCtxOptions;
@@ -154,6 +155,7 @@ MachGuiCtxOptions::MachGuiCtxOptions(MachGuiStartupScreens* pStartupScreens)
const MachGuiOptionsLayout::CheckBoxInfo& cursorType = screenLayout.checkBoxInfo(3);
const MachGuiOptionsLayout::CheckBoxInfo& reverseKeys = screenLayout.checkBoxInfo(4);
const MachGuiOptionsLayout::CheckBoxInfo& reverseMouse = screenLayout.checkBoxInfo(5);
+ const MachGuiOptionsLayout::CheckBoxInfo& grabMouse = screenLayout.checkBoxInfo(6);
// Create control labels
new MachGuiMenuText(
@@ -210,6 +212,9 @@ MachGuiCtxOptions::MachGuiCtxOptions(MachGuiStartupScreens* pStartupScreens)
pReverseMouse_
= new MachGuiCheckBox(pStartupScreens, pStartupScreens, reverseMouse.topLeft, reverseMouse.stringId);
+ pGrabMouse_
+ = new MachGuiCheckBox(pStartupScreens, pStartupScreens, grabMouse.topLeft, grabMouse.stringId);
+
// Create volume sliders
pMusicVolume_ = new MachGuiSlideBar(pStartupScreens, pStartupScreens, musicVolSl.topLeft, musicVolSl.range);
pMusicVolume_->minMax(0, 100);
@@ -445,6 +450,11 @@ MachGuiCtxOptions::MachGuiCtxOptions(MachGuiStartupScreens* pStartupScreens)
readFromConfig();
+ pGrabMouse_->setCallback([](MachGuiCheckBox* pCheckBox) {
+ RenDisplay* pDisplay_ = W4dManager::instance().sceneManager()->pDevice()->display();
+ pDisplay_->setCursorGrabEnabled(pCheckBox->isChecked());
+ });
+
TEST_INVARIANT;
}
@@ -558,6 +568,9 @@ void MachGuiCtxOptions::buttonEvent(MachGuiStartupScreens::ButtonEvent buttonEve
pGammaCorrection_->setValue(gammaCorrection_);
}
pStartupScreens_->buttonAction(MachGuiStartupScreens::EXIT);
+
+ const bool grabCursorEnabled = SysRegistry::instance().queryBooleanValue(c_GrabCursorOptionKey, "on", true);
+ pGrabMouse_->setChecked(grabCursorEnabled);
}
}
@@ -649,6 +662,7 @@ void MachGuiCtxOptions::writeToConfig()
// Store reverse direction of up/down keys/mouse
SysRegistry::instance().setIntegerValue("Options\\Reverse UpDown Keys", "on", pReverseKeys_->isChecked());
SysRegistry::instance().setIntegerValue("Options\\Reverse BackForward Mouse", "on", pReverseMouse_->isChecked());
+ SysRegistry::instance().setIntegerValue(c_GrabCursorOptionKey, "on", pGrabMouse_->isChecked());
// Access all the boolean optimisations
const MachPhysComplexityManager::BooleanItems& boolItems = MachPhysComplexityManager::instance().booleanItems();
@@ -726,6 +740,9 @@ void MachGuiCtxOptions::readFromConfig()
pReverseKeys_->setChecked(SysRegistry::instance().queryIntegerValue("Options\\Reverse UpDown Keys", "on"));
pReverseMouse_->setChecked(SysRegistry::instance().queryIntegerValue("Options\\Reverse BackForward Mouse", "on"));
+ const bool grabCursorEnabled = SysRegistry::instance().queryBooleanValue(c_GrabCursorOptionKey, "on", true);
+ pGrabMouse_->setChecked(grabCursorEnabled);
+
pTransitions_->setChecked(pStartupScreens_->startupData()->transitionFlicsOn());
// Access all the boolean optimisations
diff --git a/src/libdev/machgui/ctxoptns.hpp b/src/libdev/machgui/ctxoptns.hpp
index 4c9c60de9..b581c0f98 100644
--- a/src/libdev/machgui/ctxoptns.hpp
+++ b/src/libdev/machgui/ctxoptns.hpp
@@ -75,6 +75,7 @@ class MachGuiCtxOptions : public MachGuiStartupScreenContext
MachGuiCheckBox* pCursorType_ = nullptr;
MachGuiCheckBox* pReverseKeys_ = nullptr;
MachGuiCheckBox* pReverseMouse_ = nullptr;
+ MachGuiCheckBox* pGrabMouse_{};
MachGuiDropDownListBoxCreator* pScreenSize_ = nullptr;
BooleanOptimisations booleanOptimisations_;
ChoicesOptimisations choicesOptimisations_;
diff --git a/src/libdev/machgui/internal/strings.hpp b/src/libdev/machgui/internal/strings.hpp
index c9d00c9dc..009401799 100644
--- a/src/libdev/machgui/internal/strings.hpp
+++ b/src/libdev/machgui/internal/strings.hpp
@@ -800,3 +800,4 @@
#define IDS_SCALE_FACTOR 11000
#define IDS_MENUMESSAGE_SCALE_FACTOR 11001
+#define IDS_GRAB_MOUSE 11002
diff --git a/src/libdev/render/display.cpp b/src/libdev/render/display.cpp
index 0c8e809b5..764faaaf5 100644
--- a/src/libdev/render/display.cpp
+++ b/src/libdev/render/display.cpp
@@ -587,6 +587,11 @@ const RenCursor2d* RenDisplay::currentCursor() const
return pImpl_->currentCursor();
}
+void RenDisplay::setCursorGrabEnabled(bool enabled)
+{
+ SDL_SetWindowGrab(pImpl_->pWnd_, enabled ? SDL_TRUE : SDL_FALSE);
+}
+
uint32_t RenDisplay::frameNumber() const
{
CB_RenDisplay_DEPIMPL();
diff --git a/src/libdev/render/display.hpp b/src/libdev/render/display.hpp
index abfa232da..df886dd44 100644
--- a/src/libdev/render/display.hpp
+++ b/src/libdev/render/display.hpp
@@ -165,6 +165,8 @@ class RenDisplay
void useCursor(const RenCursor2d*);
const RenCursor2d* currentCursor() const;
+ void setCursorGrabEnabled(bool enabled);
+
void supportsGammaCorrection(bool);
bool supportsGammaCorrection() const;
void gammaCorrection(const double& gammaCorrection);
diff --git a/src/projects/machines/sdlapp.cpp b/src/projects/machines/sdlapp.cpp
index dbf3721e3..cf8943620 100644
--- a/src/projects/machines/sdlapp.cpp
+++ b/src/projects/machines/sdlapp.cpp
@@ -368,6 +368,10 @@ bool SDLApp::clientStartup()
}
DevMouse::instance().scaleCoordinates(mode.width(), mode.height());
+ {
+ const bool grabEnabled = SysRegistry::instance().queryBooleanValue("Options\\Grab Cursor", "on", true);
+ pDisplay_->setCursorGrabEnabled(grabEnabled);
+ }
spdlog::info("Initializing the rendering device...");
std::unique_ptr pDevice = std::make_unique(pDisplay_);