[Scummvm-git-logs] scummvm branch-2-8 -> 41bab0c0bf775ea0246c590322dd991df77491ea

fracturehill noreply at scummvm.org
Thu Jan 25 07:54:34 UTC 2024


This automated email contains information about 6 new commits which have been
pushed to the 'scummvm' repo located at https://github.com/scummvm/scummvm .

Summary:
63c6b7defb NANCY: Fix RaycastPuzzle crash in movement code
c54240b112 NANCY: Mark keymap names as translateable
0aa5ce46b6 NANCY: Improve keymap disabling behavior
fcab9da22c NANCY: Consistently show/hide virtual keyboard
f32bfb6342 NANCY: Clean up RaycastPuzzle floor/ceiling drawing
41bab0c0bf NANCY: Fix RaycastPuzzle floor/ceiling drawing on ARM


Commit: 63c6b7defb762fe6a4322019cf936a2ab972a951
    https://github.com/scummvm/scummvm/commit/63c6b7defb762fe6a4322019cf936a2ab972a951
Author: Kaloyan Chehlarski (strahy at outlook.com)
Date: 2024-01-25T08:39:18+01:00

Commit Message:
NANCY: Fix RaycastPuzzle crash in movement code

Added better clipping of the cell ids used when checking
for walls and other obstacles. Also made some of the
formatting in the function prettier.

Changed paths:
    engines/nancy/action/puzzle/raycastpuzzle.cpp


diff --git a/engines/nancy/action/puzzle/raycastpuzzle.cpp b/engines/nancy/action/puzzle/raycastpuzzle.cpp
index e7f637e6782..3b811b0456c 100644
--- a/engines/nancy/action/puzzle/raycastpuzzle.cpp
+++ b/engines/nancy/action/puzzle/raycastpuzzle.cpp
@@ -1243,18 +1243,21 @@ void RaycastPuzzle::handleInput(NancyInput &input) {
 		int32 yCell = ((int32)newY) & 0x7F;
 
 		int collisionSize = 48;
+		int c = 0;
+
+#define ClampCell(x) (c = x, c >= 0 && c < (int)_wallMap.size() && xGrid > 0 && yGrid > 0 && xGrid < _mapFullWidth && yGrid < _mapFullHeight) ? _wallMap[c] : 1;
 
 		// Check neighboring cells
-		uint32 cellLeft = xGrid > 0 ? _wallMap[yGrid * _mapFullWidth + xGrid - 1] : 1;
-		uint32 cellTop = yGrid > 0 ? _wallMap[(yGrid - 1) * _mapFullWidth + xGrid] : 1;
-		uint32 cellRight = xGrid < _mapFullWidth ? _wallMap[yGrid * _mapFullWidth + xGrid + 1] : 1;
-		uint32 cellBottom = yGrid < _mapFullHeight ? _wallMap[(yGrid + 1) * _mapFullWidth + xGrid] : 1;
+		uint32 cellLeft 	= ClampCell(yGrid * _mapFullWidth + xGrid - 1);
+		uint32 cellTop 		= ClampCell((yGrid - 1) * _mapFullWidth + xGrid);
+		uint32 cellRight 	= ClampCell(yGrid * _mapFullWidth + xGrid + 1);
+		uint32 cellBottom 	= ClampCell((yGrid + 1) * _mapFullWidth + xGrid);
 
 		// Allow passage through doors
-		cellLeft = (cellLeft & kDoor) ? 0 : cellLeft;
-		cellTop = (cellTop & kDoor) ? 0 : cellTop;
-		cellRight = (cellRight & kDoor) ? 0 : cellRight;
-		cellBottom = (cellBottom & kDoor) ? 0 : cellBottom;
+		cellLeft	= (cellLeft & kDoor)	? 0 : cellLeft;
+		cellTop		= (cellTop & kDoor)		? 0 : cellTop;
+		cellRight	= (cellRight & kDoor)	? 0 : cellRight;
+		cellBottom	= (cellBottom & kDoor)	? 0 : cellBottom;
 
 		if (cellLeft && yCell < collisionSize) {
 			newY = (((int32)newY) & 0xFF80) + collisionSize;
@@ -1282,20 +1285,20 @@ void RaycastPuzzle::handleInput(NancyInput &input) {
 		cellRight = xGrid < _mapFullWidth ? _wallMap[yGrid * _mapFullWidth + xGrid + 1] : 1;
 		cellBottom = yGrid < _mapFullHeight ? _wallMap[(yGrid + 1) * _mapFullWidth + xGrid] : 1;
 
-		uint32 cellTopLeft = (xGrid > 0 && yGrid > 0) ? _wallMap[(yGrid - 1) * _mapFullWidth + xGrid - 1] : 1;
-		uint32 cellTopRight = (xGrid < _mapFullWidth && yGrid > 0) ? _wallMap[(yGrid - 1) * _mapFullWidth + xGrid + 1] : 1;
-		uint32 cellBottomLeft = (xGrid > 0 && yGrid < _mapFullHeight) ? _wallMap[(yGrid + 1) * _mapFullWidth + xGrid - 1] : 1;
-		uint32 cellBottomRight = (xGrid < _mapFullWidth && yGrid < _mapFullHeight) ? _wallMap[(yGrid + 1) * _mapFullWidth + xGrid + 1] : 1;
+		uint32 cellTopLeft 		= ClampCell((yGrid - 1) * _mapFullWidth + xGrid - 1);
+		uint32 cellTopRight 	= ClampCell((yGrid - 1) * _mapFullWidth + xGrid + 1);
+		uint32 cellBottomLeft 	= ClampCell((yGrid + 1) * _mapFullWidth + xGrid - 1);
+		uint32 cellBottomRight 	= ClampCell((yGrid + 1) * _mapFullWidth + xGrid + 1);
 
-		cellLeft = (cellLeft & kDoor) ? 0 : cellLeft;
-		cellTop = (cellTop & kDoor) ? 0 : cellTop;
-		cellRight = (cellRight & kDoor) ? 0 : cellRight;
-		cellBottom = (cellBottom & kDoor) ? 0 : cellBottom;
+		cellLeft 		= (cellLeft & kDoor) 		? 0 : cellLeft;
+		cellTop 		= (cellTop & kDoor) 		? 0 : cellTop;
+		cellRight 		= (cellRight & kDoor) 		? 0 : cellRight;
+		cellBottom 		= (cellBottom & kDoor) 		? 0 : cellBottom;
 
-		cellTopLeft = (cellTopLeft & kDoor) ? 0 : cellTopLeft;
-		cellTopRight = (cellTopRight & kDoor) ? 0 : cellTopRight;
-		cellBottomLeft = (cellBottomLeft & kDoor) ? 0 : cellBottomLeft;
-		cellBottomRight = (cellBottomRight & kDoor) ? 0 : cellBottomRight;
+		cellTopLeft 	= (cellTopLeft & kDoor) 	? 0 : cellTopLeft;
+		cellTopRight 	= (cellTopRight & kDoor) 	? 0 : cellTopRight;
+		cellBottomLeft 	= (cellBottomLeft & kDoor) 	? 0 : cellBottomLeft;
+		cellBottomRight	= (cellBottomRight & kDoor)	? 0 : cellBottomRight;
 
 		// Make sure the player doesn't clip diagonally into a wall
 		// Improvement: in the original engine the player just gets stuck when hitting a corner;


Commit: c54240b112e1dfb8045a641779c71f17f1bca58b
    https://github.com/scummvm/scummvm/commit/c54240b112e1dfb8045a641779c71f17f1bca58b
Author: Kaloyan Chehlarski (strahy at outlook.com)
Date: 2024-01-25T08:39:18+01:00

Commit Message:
NANCY: Mark keymap names as translateable

Changed paths:
    engines/nancy/input.cpp


diff --git a/engines/nancy/input.cpp b/engines/nancy/input.cpp
index 8338a0e1c7d..a4e1fb1c67f 100644
--- a/engines/nancy/input.cpp
+++ b/engines/nancy/input.cpp
@@ -170,7 +170,7 @@ void InputManager::initKeymaps(Common::KeymapArray &keymaps, const char *target)
 	using namespace Nancy;
 
 	Common::String gameId = ConfMan.get("gameid", target);
-	Keymap *mainKeymap = new Keymap(Keymap::kKeymapTypeGame, "nancy-main", "Nancy Drew");
+	Keymap *mainKeymap = new Keymap(Keymap::kKeymapTypeGame, "nancy-main", _("Nancy Drew"));
 	Action *act;
 
 	act = new Action(kStandardActionLeftClick, _("Left Click Interact"));
@@ -226,7 +226,7 @@ void InputManager::initKeymaps(Common::KeymapArray &keymaps, const char *target)
 	keymaps.push_back(mainKeymap);
 	
 	if (gameId == "nancy3" || gameId == "nancy6") {
-		Keymap *mazeKeymap = new Keymap(Keymap::kKeymapTypeGame, mazeKeymapID, "Nancy Drew - Maze");
+		Keymap *mazeKeymap = new Keymap(Keymap::kKeymapTypeGame, mazeKeymapID, _("Nancy Drew - Maze"));
 
 		act = new Action("RAYCM", _("Show/hide maze map"));
 		act->setCustomEngineActionEvent(kNancyActionShowRaycastMap);


Commit: 0aa5ce46b6bc83afe8e665bd4d051154809fee21
    https://github.com/scummvm/scummvm/commit/0aa5ce46b6bc83afe8e665bd4d051154809fee21
Author: Kaloyan Chehlarski (strahy at outlook.com)
Date: 2024-01-25T08:40:13+01:00

Commit Message:
NANCY: Improve keymap disabling behavior

Changed the way keymaps are disabled/enabled to reduce
calls to the InputManager, and make sure secondary
keymaps are only enabled when needed, and kept disabled
the rest of the time.

Changed paths:
    engines/nancy/action/puzzle/passwordpuzzle.cpp
    engines/nancy/action/puzzle/raycastpuzzle.cpp
    engines/nancy/action/puzzle/raycastpuzzle.h
    engines/nancy/action/puzzle/riddlepuzzle.cpp
    engines/nancy/input.cpp
    engines/nancy/input.h
    engines/nancy/state/loadsave.cpp


diff --git a/engines/nancy/action/puzzle/passwordpuzzle.cpp b/engines/nancy/action/puzzle/passwordpuzzle.cpp
index b77360cd971..d538731ac3d 100644
--- a/engines/nancy/action/puzzle/passwordpuzzle.cpp
+++ b/engines/nancy/action/puzzle/passwordpuzzle.cpp
@@ -92,7 +92,6 @@ void PasswordPuzzle::execute() {
 		init();
 		registerGraphics();
 		g_system->setFeatureState(OSystem::kFeatureVirtualKeyboard, true);
-		g_nancy->_input->enableSecondaryKeymaps(false);
 		_nextBlinkTime = g_nancy->getTotalPlayTime() + _cursorBlinkTime;
 		_state = kRun;
 		// fall through
@@ -181,7 +180,6 @@ void PasswordPuzzle::execute() {
 		}
 
 		g_system->setFeatureState(OSystem::kFeatureVirtualKeyboard, false);
-		g_nancy->_input->enableSecondaryKeymaps(true);
 		finishExecution();
 	}
 }
diff --git a/engines/nancy/action/puzzle/raycastpuzzle.cpp b/engines/nancy/action/puzzle/raycastpuzzle.cpp
index 3b811b0456c..f9d0a132884 100644
--- a/engines/nancy/action/puzzle/raycastpuzzle.cpp
+++ b/engines/nancy/action/puzzle/raycastpuzzle.cpp
@@ -1063,6 +1063,10 @@ bool RaycastDeferredLoader::loadInner() {
 	return _isDone;
 }
 
+RaycastPuzzle::~RaycastPuzzle() {
+	g_nancy->_input->setKeymapEnabled(Nancy::InputManager::_mazeKeymapID, false);
+}
+
 void RaycastPuzzle::init() {
 	_puzzleData = GetEngineData(RCPR);
 	assert(_puzzleData);
@@ -1107,6 +1111,7 @@ void RaycastPuzzle::execute() {
 	switch (_state) {
 	case kBegin:
 		init();
+		g_nancy->_input->setKeymapEnabled(Nancy::InputManager::_mazeKeymapID, true);
 		break;
 	case kRun:
 		checkSwitch();
@@ -1126,6 +1131,11 @@ void RaycastPuzzle::execute() {
 	}
 }
 
+void RaycastPuzzle::onPause(bool pause) {
+	RenderActionRecord::onPause(pause);
+	g_nancy->_input->setKeymapEnabled(Nancy::InputManager::_mazeKeymapID, !pause);
+}
+
 void RaycastPuzzle::handleInput(NancyInput &input) {
 	if (_state != kRun) {
 		return;
diff --git a/engines/nancy/action/puzzle/raycastpuzzle.h b/engines/nancy/action/puzzle/raycastpuzzle.h
index 9ab2bc67830..7d442723b3e 100644
--- a/engines/nancy/action/puzzle/raycastpuzzle.h
+++ b/engines/nancy/action/puzzle/raycastpuzzle.h
@@ -38,14 +38,15 @@ class RaycastPuzzle : public RenderActionRecord {
 	friend class RaycastDeferredLoader;
 	friend class RaycastLevelBuilder;
 public:
-	RaycastPuzzle()  : RenderActionRecord(7), _map(7) {}
-	~RaycastPuzzle() override {}
+	RaycastPuzzle() : RenderActionRecord(7), _map(7) {}
+	~RaycastPuzzle() override;
 
 	void init() override;
 	void registerGraphics() override;
 
 	void readData(Common::SeekableReadStream &stream) override;
 	void execute() override;
+	void onPause(bool pause) override;
 	void handleInput(NancyInput &input) override;
 	void updateGraphics() override;
 
diff --git a/engines/nancy/action/puzzle/riddlepuzzle.cpp b/engines/nancy/action/puzzle/riddlepuzzle.cpp
index 09238414efd..67385440f61 100644
--- a/engines/nancy/action/puzzle/riddlepuzzle.cpp
+++ b/engines/nancy/action/puzzle/riddlepuzzle.cpp
@@ -145,8 +145,6 @@ void RiddlePuzzle::execute() {
 			if (!g_nancy->_sound->isSoundPlaying(_riddles[_riddleID].sound)) {
 				_solveState = kNotSolved;
 				g_system->setFeatureState(OSystem::kFeatureVirtualKeyboard, true);
-				g_nancy->_input->enableSecondaryKeymaps(false);
-
 			}
 
 			break;
@@ -258,7 +256,6 @@ void RiddlePuzzle::execute() {
 
 		sceneChange->execute();
 		g_system->setFeatureState(OSystem::kFeatureVirtualKeyboard, false);
-		g_nancy->_input->enableSecondaryKeymaps(true);
 		finishExecution();
 	}
 	}
diff --git a/engines/nancy/input.cpp b/engines/nancy/input.cpp
index a4e1fb1c67f..10a13635631 100644
--- a/engines/nancy/input.cpp
+++ b/engines/nancy/input.cpp
@@ -31,7 +31,7 @@
 
 namespace Nancy {
 
-static const char *mazeKeymapID = "nancy-maze";
+const char *InputManager::_mazeKeymapID = "nancy-maze";
 
 void InputManager::processEvents() {
 	using namespace Common;
@@ -158,11 +158,11 @@ void InputManager::forceCleanInput() {
 	_otherKbdInput.clear();
 }
 
-void InputManager::enableSecondaryKeymaps(bool enabled) {
+void InputManager::setKeymapEnabled(Common::String keymapName, bool enabled) {
 	Common::Keymapper *keymapper = g_nancy->getEventManager()->getKeymapper();
-	Common::Keymap *mazeKeymap = keymapper->getKeymap(mazeKeymapID);
-	if (mazeKeymap)
-		mazeKeymap->setEnabled(enabled);
+	Common::Keymap *keymap = keymapper->getKeymap(keymapName);
+	if (keymap)
+		keymap->setEnabled(enabled);
 }
 
 void InputManager::initKeymaps(Common::KeymapArray &keymaps, const char *target) {
@@ -226,13 +226,14 @@ void InputManager::initKeymaps(Common::KeymapArray &keymaps, const char *target)
 	keymaps.push_back(mainKeymap);
 	
 	if (gameId == "nancy3" || gameId == "nancy6") {
-		Keymap *mazeKeymap = new Keymap(Keymap::kKeymapTypeGame, mazeKeymapID, _("Nancy Drew - Maze"));
+		Keymap *mazeKeymap = new Keymap(Keymap::kKeymapTypeGame, _mazeKeymapID, _("Nancy Drew - Maze"));
 
 		act = new Action("RAYCM", _("Show/hide maze map"));
 		act->setCustomEngineActionEvent(kNancyActionShowRaycastMap);
 		act->addDefaultInputMapping("m");
 		act->addDefaultInputMapping("JOY_RIGHT_SHOULDER");
 		mazeKeymap->addAction(act);
+		mazeKeymap->setEnabled(false);
 
 		keymaps.push_back(mazeKeymap);
 	}
diff --git a/engines/nancy/input.h b/engines/nancy/input.h
index b09b32c8904..eaacb2c04c9 100644
--- a/engines/nancy/input.h
+++ b/engines/nancy/input.h
@@ -93,10 +93,12 @@ public:
 	NancyInput getInput() const;
 	void forceCleanInput();
 	void setMouseInputEnabled(bool enabled) { _mouseEnabled = enabled; }
-	void enableSecondaryKeymaps(bool enabled);
+	void setKeymapEnabled(Common::String keymapName, bool enabled);
 
 	static void initKeymaps(Common::KeymapArray &keymaps, const char *target);
 
+	static const char *_mazeKeymapID;
+
 private:
 	uint16 _inputs;
 	Common::Array<Common::KeyState> _otherKbdInput;
diff --git a/engines/nancy/state/loadsave.cpp b/engines/nancy/state/loadsave.cpp
index ccb3315f87d..454fb840212 100644
--- a/engines/nancy/state/loadsave.cpp
+++ b/engines/nancy/state/loadsave.cpp
@@ -69,7 +69,6 @@ void LoadSaveMenu::process() {
 	switch (_state) {
 	case kInit:
 		init();
-		g_nancy->_input->enableSecondaryKeymaps(false);
 		// fall through
 	case kRun:
 		run();
@@ -93,7 +92,6 @@ void LoadSaveMenu::process() {
 	// Make sure stop runs on the same frame
 	if (_state == kStop) {
 		stop();
-		g_nancy->_input->enableSecondaryKeymaps(true);
 	}
 
 	g_nancy->_cursorManager->setCursorType(CursorManager::kNormalArrow);


Commit: fcab9da22c76986179bddeb09311cb59cf66b2c8
    https://github.com/scummvm/scummvm/commit/fcab9da22c76986179bddeb09311cb59cf66b2c8
Author: Kaloyan Chehlarski (strahy at outlook.com)
Date: 2024-01-25T08:40:13+01:00

Commit Message:
NANCY: Consistently show/hide virtual keyboard

Fixed edge cases where the mobile virtual keyboard
wouldn't show/hide properly when it should.

Changed paths:
    engines/nancy/action/puzzle/passwordpuzzle.cpp
    engines/nancy/action/puzzle/passwordpuzzle.h
    engines/nancy/action/puzzle/riddlepuzzle.cpp
    engines/nancy/action/puzzle/riddlepuzzle.h
    engines/nancy/input.cpp
    engines/nancy/input.h
    engines/nancy/state/loadsave.cpp


diff --git a/engines/nancy/action/puzzle/passwordpuzzle.cpp b/engines/nancy/action/puzzle/passwordpuzzle.cpp
index d538731ac3d..9547f119f3c 100644
--- a/engines/nancy/action/puzzle/passwordpuzzle.cpp
+++ b/engines/nancy/action/puzzle/passwordpuzzle.cpp
@@ -32,6 +32,10 @@
 namespace Nancy {
 namespace Action {
 
+PasswordPuzzle::~PasswordPuzzle() {
+	g_nancy->_input->setVKEnabled(false);
+}
+
 void PasswordPuzzle::init() {
 	_drawSurface.create(_screenPosition.width(), _screenPosition.height(), g_nancy->_graphicsManager->getInputPixelFormat());
 	_drawSurface.clear(g_nancy->_graphicsManager->getTransColor());
@@ -91,7 +95,7 @@ void PasswordPuzzle::execute() {
 	case kBegin:
 		init();
 		registerGraphics();
-		g_system->setFeatureState(OSystem::kFeatureVirtualKeyboard, true);
+		g_nancy->_input->setVKEnabled(true);
 		_nextBlinkTime = g_nancy->getTotalPlayTime() + _cursorBlinkTime;
 		_state = kRun;
 		// fall through
@@ -179,11 +183,16 @@ void PasswordPuzzle::execute() {
 			break;
 		}
 
-		g_system->setFeatureState(OSystem::kFeatureVirtualKeyboard, false);
+		g_nancy->_input->setVKEnabled(false);
 		finishExecution();
 	}
 }
 
+void PasswordPuzzle::onPause(bool paused) {
+	g_nancy->_input->setVKEnabled(!paused);
+	RenderActionRecord::onPause(paused);
+}
+
 void PasswordPuzzle::handleInput(NancyInput &input) {
 	if (_solveState != kNotSolved) {
 		return;
diff --git a/engines/nancy/action/puzzle/passwordpuzzle.h b/engines/nancy/action/puzzle/passwordpuzzle.h
index 17780039ee1..abd7ad182a0 100644
--- a/engines/nancy/action/puzzle/passwordpuzzle.h
+++ b/engines/nancy/action/puzzle/passwordpuzzle.h
@@ -31,12 +31,13 @@ class PasswordPuzzle : public RenderActionRecord {
 public:
 	enum SolveState { kNotSolved, kFailed, kSolved };
 	PasswordPuzzle() : RenderActionRecord(7) {}
-	virtual ~PasswordPuzzle() {}
+	virtual ~PasswordPuzzle();
 
 	void init() override;
 
 	void readData(Common::SeekableReadStream &stream) override;
 	void execute() override;
+	void onPause(bool paused) override;
 	void handleInput(NancyInput &input) override;
 
 	uint16 _fontID = 0;
diff --git a/engines/nancy/action/puzzle/riddlepuzzle.cpp b/engines/nancy/action/puzzle/riddlepuzzle.cpp
index 67385440f61..c8210d9dac4 100644
--- a/engines/nancy/action/puzzle/riddlepuzzle.cpp
+++ b/engines/nancy/action/puzzle/riddlepuzzle.cpp
@@ -35,6 +35,10 @@
 namespace Nancy {
 namespace Action {
 
+RiddlePuzzle::~RiddlePuzzle() {
+	g_nancy->_input->setVKEnabled(false);
+}
+
 void RiddlePuzzle::init() {
 	_drawSurface.create(_screenPosition.width(), _screenPosition.height(), g_nancy->_graphicsManager->getInputPixelFormat());
 	_drawSurface.clear(g_nancy->_graphicsManager->getTransColor());
@@ -144,7 +148,7 @@ void RiddlePuzzle::execute() {
 		case kWaitForSound:
 			if (!g_nancy->_sound->isSoundPlaying(_riddles[_riddleID].sound)) {
 				_solveState = kNotSolved;
-				g_system->setFeatureState(OSystem::kFeatureVirtualKeyboard, true);
+				g_nancy->_input->setVKEnabled(true);
 			}
 
 			break;
@@ -255,12 +259,17 @@ void RiddlePuzzle::execute() {
 		g_nancy->_sound->stopSound(_enterSound);
 
 		sceneChange->execute();
-		g_system->setFeatureState(OSystem::kFeatureVirtualKeyboard, false);
+		g_nancy->_input->setVKEnabled(false);
 		finishExecution();
 	}
 	}
 }
 
+void RiddlePuzzle::onPause(bool paused) {
+	g_nancy->_input->setVKEnabled(!paused);
+	RenderActionRecord::onPause(paused);
+}
+
 void RiddlePuzzle::handleInput(NancyInput &input) {
 	if (_solveState != kNotSolved) {
 		return;
diff --git a/engines/nancy/action/puzzle/riddlepuzzle.h b/engines/nancy/action/puzzle/riddlepuzzle.h
index a56ceae54c5..22baf52fde0 100644
--- a/engines/nancy/action/puzzle/riddlepuzzle.h
+++ b/engines/nancy/action/puzzle/riddlepuzzle.h
@@ -34,12 +34,13 @@ class RiddlePuzzle : public RenderActionRecord {
 public:
 	enum SolveState { kWaitForSound, kNotSolved, kFailed, kSolvedOne, kSolvedAll };
 	RiddlePuzzle() : RenderActionRecord(7) {}
-	virtual ~RiddlePuzzle() {}
+	virtual ~RiddlePuzzle();
 
 	void init() override;
 
 	void readData(Common::SeekableReadStream &stream) override;
 	void execute() override;
+	void onPause(bool paused) override;
 	void handleInput(NancyInput &input) override;
 
 protected:
diff --git a/engines/nancy/input.cpp b/engines/nancy/input.cpp
index 10a13635631..a02b17d62fd 100644
--- a/engines/nancy/input.cpp
+++ b/engines/nancy/input.cpp
@@ -20,6 +20,7 @@
  */
 
 #include "common/translation.h"
+#include "common/system.h"
 
 #include "backends/keymapper/action.h"
 #include "backends/keymapper/keymap.h"
@@ -165,6 +166,10 @@ void InputManager::setKeymapEnabled(Common::String keymapName, bool enabled) {
 		keymap->setEnabled(enabled);
 }
 
+void InputManager::setVKEnabled(bool enabled) {
+	g_system->setFeatureState(OSystem::kFeatureVirtualKeyboard, enabled);
+}
+
 void InputManager::initKeymaps(Common::KeymapArray &keymaps, const char *target) {
 	using namespace Common;
 	using namespace Nancy;
diff --git a/engines/nancy/input.h b/engines/nancy/input.h
index eaacb2c04c9..7d12c2282e7 100644
--- a/engines/nancy/input.h
+++ b/engines/nancy/input.h
@@ -94,6 +94,7 @@ public:
 	void forceCleanInput();
 	void setMouseInputEnabled(bool enabled) { _mouseEnabled = enabled; }
 	void setKeymapEnabled(Common::String keymapName, bool enabled);
+	void setVKEnabled(bool enabled);
 
 	static void initKeymaps(Common::KeymapArray &keymaps, const char *target);
 
diff --git a/engines/nancy/state/loadsave.cpp b/engines/nancy/state/loadsave.cpp
index 454fb840212..25ab6109308 100644
--- a/engines/nancy/state/loadsave.cpp
+++ b/engines/nancy/state/loadsave.cpp
@@ -59,6 +59,8 @@ LoadSaveMenu::~LoadSaveMenu() {
 
 	delete _exitButton;
 	delete _cancelButton;
+
+	g_nancy->_input->setVKEnabled(false);
 }
 
 void LoadSaveMenu::process() {
@@ -98,10 +100,14 @@ void LoadSaveMenu::process() {
 }
 
 void LoadSaveMenu::onStateEnter(const NancyState::NancyState prevState) {
+	if (_state == kEnterFilename) {
+		g_nancy->_input->setVKEnabled(true);
+	}
 	registerGraphics();
 }
 
 bool LoadSaveMenu::onStateExit(const NancyState::NancyState nextState) {
+	g_nancy->_input->setVKEnabled(false);
 	return _destroyOnExit;
 }
 
@@ -399,7 +405,7 @@ void LoadSaveMenu::enterFilename() {
 		_blinkingCursorOverlay.setVisible(true);
 		_nextBlink = g_nancy->getTotalPlayTime() + _loadSaveData->_blinkingTimeDelay;
 		_enteringNewState = false;
-		g_system->setFeatureState(OSystem::kFeatureVirtualKeyboard, true);
+		g_nancy->_input->setVKEnabled(true);
 	}
 
 	// Perform cursor blinking
@@ -437,7 +443,7 @@ void LoadSaveMenu::enterFilename() {
 		_state = kRun;
 		_enteringNewState = true;
 		g_nancy->_sound->playSound("BULS");
-		g_system->setFeatureState(OSystem::kFeatureVirtualKeyboard, false);
+		g_nancy->_input->setVKEnabled(false);
 		return;
 	}
 
@@ -446,7 +452,7 @@ void LoadSaveMenu::enterFilename() {
 		_state = kSave;
 		_enteringNewState = true;
 		g_nancy->_sound->playSound("BULS");
-		g_system->setFeatureState(OSystem::kFeatureVirtualKeyboard, false);
+		g_nancy->_input->setVKEnabled(false);
 		return;
 	}
 }


Commit: f32bfb6342c799f23f8cb25d2814a7d54e8bc079
    https://github.com/scummvm/scummvm/commit/f32bfb6342c799f23f8cb25d2814a7d54e8bc079
Author: Kaloyan Chehlarski (strahy at outlook.com)
Date: 2024-01-25T08:40:13+01:00

Commit Message:
NANCY: Clean up RaycastPuzzle floor/ceiling drawing

This makes the floor/ceiling drawing more readable and
more accurate to the original engine.

Changed paths:
    engines/nancy/action/puzzle/raycastpuzzle.cpp


diff --git a/engines/nancy/action/puzzle/raycastpuzzle.cpp b/engines/nancy/action/puzzle/raycastpuzzle.cpp
index f9d0a132884..6945b166856 100644
--- a/engines/nancy/action/puzzle/raycastpuzzle.cpp
+++ b/engines/nancy/action/puzzle/raycastpuzzle.cpp
@@ -1948,30 +1948,30 @@ void RaycastPuzzle::drawMaze() {
 		uint16 *ceilingDest = (uint16 *)_drawSurface.getBasePtr(viewBounds.left, ceilingY);
 
 		{
-			float floorSrcX, floorSrcY, ceilingSrcX, ceilingSrcY;
+			float floorViewAngle	= ((float)_fov / (float)(floorY - viewportCenterY))		* (float)_playerAltitude;
+			float ceilingViewAngle	= ((float)_fov / (float)(viewportCenterY - ceilingY))	* (float)((_wallHeight * 128) - _playerAltitude);
 
-			float floorViewAngle = ((float)_fov / (float)(floorY - viewportCenterY)) * (float)_playerAltitude;
-			float ceilingViewAngle = ((float)_fov / (float)(viewportCenterY - ceilingY)) * (float)((_wallHeight * 128) - _playerAltitude);
+			float floorLeftX    =	_cosTable[leftAngle]  *  (floorViewAngle   / _cosTable[_leftmostAngle])  + (float)_playerY;
+			float floorRightX   =	_cosTable[rightAngle] *  (floorViewAngle   / _cosTable[_rightmostAngle]) + (float)_playerY;
+			float floorLeftY    =	_sinTable[leftAngle]  * -(floorViewAngle   / _cosTable[_leftmostAngle])  + (float)_playerX;
+			float floorRightY   =	_sinTable[rightAngle] * -(floorViewAngle   / _cosTable[_rightmostAngle]) + (float)_playerX;
 
-			floorSrcX = _cosTable[leftAngle] * (floorViewAngle / _cosTable[_leftmostAngle]) + (float)_playerY;
-			floorSrcY = _sinTable[leftAngle] * -(floorViewAngle / _cosTable[_leftmostAngle]) + (float)_playerX;
-			ceilingSrcX = _cosTable[leftAngle] * (ceilingViewAngle / _cosTable[_leftmostAngle]) + (float)_playerY;
-			ceilingSrcY = _sinTable[leftAngle] * -(ceilingViewAngle / _cosTable[_leftmostAngle]) + (float)_playerX;
+			float ceilingLeftX  =	_cosTable[leftAngle]  *  (ceilingViewAngle / _cosTable[_leftmostAngle])  + (float)_playerY;
+			float ceilingRightX =	_cosTable[rightAngle] *  (ceilingViewAngle / _cosTable[_rightmostAngle]) + (float)_playerY;
+			float ceilingLeftY  =	_sinTable[leftAngle]  * -(ceilingViewAngle / _cosTable[_leftmostAngle])  + (float)_playerX;
+			float ceilingRightY =	_sinTable[rightAngle] * -(ceilingViewAngle / _cosTable[_rightmostAngle]) + (float)_playerX;
 
-			floorSrcFracX = (uint32)(floorSrcX * 65536.0);
-			floorSrcFracY = (uint32)(floorSrcY * 65536.0);
+			floorSrcFracX	= (uint32)(floorLeftX	* 65536.0);
+			floorSrcFracY	= (uint32)(floorLeftY	* 65536.0);
 
-			ceilingSrcFracX = (uint32)(ceilingSrcX * 65536.0);
-			ceilingSrcFracY = (uint32)(ceilingSrcY * 65536.0);
+			ceilingSrcFracX = (uint32)(ceilingLeftX * 65536.0);
+			ceilingSrcFracY = (uint32)(ceilingLeftY * 65536.0);
 
-			floorViewAngle /= _cosTable[_rightmostAngle];
-			ceilingViewAngle /= _cosTable[_rightmostAngle];
+			floorSrcIncrementX 		= (uint32)(((floorRightX	- floorLeftX)	/ (float)viewBounds.width()) * 65536.0);
+			floorSrcIncrementY 		= (uint32)(((floorRightY	- floorLeftY)	/ (float)viewBounds.width()) * 65536.0);
 
-			floorSrcIncrementX = (uint32)(((_cosTable[rightAngle] * floorViewAngle + (float)_playerY - floorSrcX) / (float)viewBounds.width()) * 65536.0);
-			floorSrcIncrementY = (uint32)(((_sinTable[rightAngle] * -(floorViewAngle) + (float)_playerX - floorSrcY) / (float)viewBounds.width()) * 65536.0);
-
-			ceilingSrcIncrementX = (uint32)(((_cosTable[rightAngle] * ceilingViewAngle + (float)_playerY - ceilingSrcX) / (float)viewBounds.width()) * 65536.0);
-			ceilingSrcIncrementY = (uint32)(((_sinTable[rightAngle] * -(ceilingViewAngle) + (float)_playerX - ceilingSrcY) / (float)viewBounds.width()) * 65536.0);
+			ceilingSrcIncrementX 	= (uint32)(((ceilingRightX	- ceilingLeftX) / (float)viewBounds.width()) * 65536.0);
+			ceilingSrcIncrementY 	= (uint32)(((ceilingRightY	- ceilingLeftY) / (float)viewBounds.width()) * 65536.0);
 		}
 
 		for (int x = viewBounds.left; x < viewBounds.right; ++x) {


Commit: 41bab0c0bf775ea0246c590322dd991df77491ea
    https://github.com/scummvm/scummvm/commit/41bab0c0bf775ea0246c590322dd991df77491ea
Author: Kaloyan Chehlarski (strahy at outlook.com)
Date: 2024-01-25T08:44:22+01:00

Commit Message:
NANCY: Fix RaycastPuzzle floor/ceiling drawing on ARM

This commit removes all instances of casts between
negative floats to unsigned int, which is UB. This fixes
the incorrect drawing of floors and ceilings on ARM
machines, as well as the occasional crashes it caused.

Changed paths:
    engines/nancy/action/puzzle/raycastpuzzle.cpp


diff --git a/engines/nancy/action/puzzle/raycastpuzzle.cpp b/engines/nancy/action/puzzle/raycastpuzzle.cpp
index 6945b166856..04b024d5470 100644
--- a/engines/nancy/action/puzzle/raycastpuzzle.cpp
+++ b/engines/nancy/action/puzzle/raycastpuzzle.cpp
@@ -1961,17 +1961,18 @@ void RaycastPuzzle::drawMaze() {
 			float ceilingLeftY  =	_sinTable[leftAngle]  * -(ceilingViewAngle / _cosTable[_leftmostAngle])  + (float)_playerX;
 			float ceilingRightY =	_sinTable[rightAngle] * -(ceilingViewAngle / _cosTable[_rightmostAngle]) + (float)_playerX;
 
-			floorSrcFracX	= (uint32)(floorLeftX	* 65536.0);
-			floorSrcFracY	= (uint32)(floorLeftY	* 65536.0);
+			// Casting between negative float and uint is undefined behavior, hence the cast to signed int first
+			floorSrcFracX	= (uint32)((int32)(floorLeftX	* 65536.0));
+			floorSrcFracY	= (uint32)((int32)(floorLeftY	* 65536.0));
 
-			ceilingSrcFracX = (uint32)(ceilingLeftX * 65536.0);
-			ceilingSrcFracY = (uint32)(ceilingLeftY * 65536.0);
+			ceilingSrcFracX = (uint32)((int32)(ceilingLeftX * 65536.0));
+			ceilingSrcFracY = (uint32)((int32)(ceilingLeftY * 65536.0));
 
-			floorSrcIncrementX 		= (uint32)(((floorRightX	- floorLeftX)	/ (float)viewBounds.width()) * 65536.0);
-			floorSrcIncrementY 		= (uint32)(((floorRightY	- floorLeftY)	/ (float)viewBounds.width()) * 65536.0);
+			floorSrcIncrementX 		= (uint32)((int32)(((floorRightX	- floorLeftX)	/ (float)viewBounds.width()) * 65536.0));
+			floorSrcIncrementY 		= (uint32)((int32)(((floorRightY	- floorLeftY)	/ (float)viewBounds.width()) * 65536.0));
 
-			ceilingSrcIncrementX 	= (uint32)(((ceilingRightX	- ceilingLeftX) / (float)viewBounds.width()) * 65536.0);
-			ceilingSrcIncrementY 	= (uint32)(((ceilingRightY	- ceilingLeftY) / (float)viewBounds.width()) * 65536.0);
+			ceilingSrcIncrementX 	= (uint32)((int32)(((ceilingRightX	- ceilingLeftX) / (float)viewBounds.width()) * 65536.0));
+			ceilingSrcIncrementY 	= (uint32)((int32)(((ceilingRightY	- ceilingLeftY) / (float)viewBounds.width()) * 65536.0));
 		}
 
 		for (int x = viewBounds.left; x < viewBounds.right; ++x) {




More information about the Scummvm-git-logs mailing list