[Scummvm-git-logs] scummvm master -> b0d08564810321178c4ef2c2407baee19851c865

mgerhardy noreply at scummvm.org
Sun Jul 5 11:47:13 UTC 2026


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

Summary:
b0d0856481 MACS2: debug logging and pathfinding fixes for the last scenes with the plate puzzle


Commit: b0d08564810321178c4ef2c2407baee19851c865
    https://github.com/scummvm/scummvm/commit/b0d08564810321178c4ef2c2407baee19851c865
Author: Martin Gerhardy (martin.gerhardy at gmail.com)
Date: 2026-07-05T13:46:43+02:00

Commit Message:
MACS2: debug logging and pathfinding fixes for the last scenes with the plate puzzle

Changed paths:
    engines/macs2/debugtools.cpp
    engines/macs2/macs2.cpp
    engines/macs2/macs2.h
    engines/macs2/scriptexecutor.cpp
    engines/macs2/scriptexecutor.h
    engines/macs2/view1.cpp
    engines/macs2/view1.h


diff --git a/engines/macs2/debugtools.cpp b/engines/macs2/debugtools.cpp
index a1e6c29dc05..761eec1e2bd 100644
--- a/engines/macs2/debugtools.cpp
+++ b/engines/macs2/debugtools.cpp
@@ -1673,7 +1673,7 @@ static void showSceneMapsWindow() {
 						if (overrideActive)
 							ImGui::SetTooltip("(%d, %d) = %u (0x%02X) [override zone → %u = %s]",
 											  mx, my, val, val, overrideResult,
-											  overrideResult < 0xC8 ? "WALKABLE" : "non-walkable");
+											  Macs2Engine::isWalkabilityWalkable(overrideResult) ? "WALKABLE" : "non-walkable");
 						else
 							ImGui::SetTooltip("(%d, %d) = %u (0x%02X) [override zone, DISABLED → non-walkable]",
 											  mx, my, val, val);
diff --git a/engines/macs2/macs2.cpp b/engines/macs2/macs2.cpp
index 1904014ce66..d1766f988d1 100644
--- a/engines/macs2/macs2.cpp
+++ b/engines/macs2/macs2.cpp
@@ -807,7 +807,7 @@ void Macs2Engine::snapToWalkablePosition(int16 *pTargetY, int16 *pTargetX, int16
 	// Condition: walkability >= 200 OR (targetY - walkability) < savedY
 	while (true) {
 		uint16 w = getWalkabilityAt(*pTargetY, savedX);
-		if (w < 200 && (*pTargetY - (int16)w >= savedY)) {
+		if (isWalkabilityWalkable(w) && (*pTargetY - (int16)w >= savedY)) {
 			break;
 		}
 		if (*pTargetY >= 199) {
@@ -832,8 +832,8 @@ void Macs2Engine::snapToWalkablePosition(int16 *pTargetY, int16 *pTargetX, int16
 	// Phase 3: If at screen bottom and still non-walkable, scan upward
 	if (*pTargetY == 199) {
 		uint16 w = getWalkabilityAt(*pTargetY, *pTargetX);
-		if (w >= 200) {
-			while (w >= 200 && *pTargetY > 0) {
+		if (isWalkabilityBlocking(w)) {
+			while (isWalkabilityBlocking(w) && *pTargetY > 0) {
 				*pTargetY = *pTargetY - 1;
 				w = getWalkabilityAt(*pTargetY, *pTargetX);
 			}
@@ -842,13 +842,13 @@ void Macs2Engine::snapToWalkablePosition(int16 *pTargetY, int16 *pTargetX, int16
 
 	// Phase 4: If still non-walkable, scan X toward character
 	uint16 w = getWalkabilityAt(*pTargetY, *pTargetX);
-	if (w >= 200) {
+	if (isWalkabilityBlocking(w)) {
 		*pTargetX = savedX;
 		*pTargetY = savedY;
 		if (charX < *pTargetX) {
 			while (true) {
 				uint16 w2 = getWalkabilityAt(*pTargetY, *pTargetX);
-				if (w2 < 200)
+				if (isWalkabilityWalkable(w2))
 					break;
 				if (*pTargetX <= 0)
 					break;
@@ -857,7 +857,7 @@ void Macs2Engine::snapToWalkablePosition(int16 *pTargetY, int16 *pTargetX, int16
 		} else {
 			while (true) {
 				uint16 w2 = getWalkabilityAt(*pTargetY, *pTargetX);
-				if (w2 < 200)
+				if (isWalkabilityWalkable(w2))
 					break;
 				if (*pTargetX >= 319)
 					break;
@@ -866,7 +866,7 @@ void Macs2Engine::snapToWalkablePosition(int16 *pTargetY, int16 *pTargetX, int16
 		}
 		// Phase 5: If all failed, fall back to character position
 		uint16 w2 = getWalkabilityAt(*pTargetY, *pTargetX);
-		if (w2 >= 200) {
+		if (isWalkabilityBlocking(w2)) {
 			*pTargetX = charX;
 			*pTargetY = charY;
 		}
@@ -875,44 +875,44 @@ void Macs2Engine::snapToWalkablePosition(int16 *pTargetY, int16 *pTargetX, int16
 	// Phase 6: Gradient-based wall push
 	int16 pushX = 0;
 	int16 pushY = 0;
-	if (getWalkabilityAt(*pTargetY, *pTargetX + 1) >= 200)
+	if (isWalkabilityBlocking(getWalkabilityAt(*pTargetY, *pTargetX + 1)))
 		pushX--;
-	if (getWalkabilityAt(*pTargetY, *pTargetX - 1) >= 200)
+	if (isWalkabilityBlocking(getWalkabilityAt(*pTargetY, *pTargetX - 1)))
 		pushX++;
-	if (getWalkabilityAt(*pTargetY + 1, *pTargetX) >= 200)
+	if (isWalkabilityBlocking(getWalkabilityAt(*pTargetY + 1, *pTargetX)))
 		pushY--;
-	if (getWalkabilityAt(*pTargetY - 1, *pTargetX) >= 200)
+	if (isWalkabilityBlocking(getWalkabilityAt(*pTargetY - 1, *pTargetX)))
 		pushY++;
-	if (getWalkabilityAt(*pTargetY, *pTargetX + 2) >= 200)
+	if (isWalkabilityBlocking(getWalkabilityAt(*pTargetY, *pTargetX + 2)))
 		pushX--;
-	if (getWalkabilityAt(*pTargetY, *pTargetX - 2) >= 200)
+	if (isWalkabilityBlocking(getWalkabilityAt(*pTargetY, *pTargetX - 2)))
 		pushX++;
-	if (getWalkabilityAt(*pTargetY + 2, *pTargetX) >= 200)
+	if (isWalkabilityBlocking(getWalkabilityAt(*pTargetY + 2, *pTargetX)))
 		pushY--;
-	if (getWalkabilityAt(*pTargetY - 2, *pTargetX) >= 200)
+	if (isWalkabilityBlocking(getWalkabilityAt(*pTargetY - 2, *pTargetX)))
 		pushY++;
 
 	while (pushX != 0 || pushY != 0) {
 		if (pushX < 0) {
-			if (getWalkabilityAt(*pTargetY, *pTargetX - 1) < 200) {
+			if (isWalkabilityWalkable(getWalkabilityAt(*pTargetY, *pTargetX - 1))) {
 				*pTargetX = *pTargetX - 1;
 			}
 			pushX++;
 		}
 		if (pushX > 0) {
-			if (getWalkabilityAt(*pTargetY, *pTargetX + 1) < 200) {
+			if (isWalkabilityWalkable(getWalkabilityAt(*pTargetY, *pTargetX + 1))) {
 				*pTargetX = *pTargetX + 1;
 			}
 			pushX--;
 		}
 		if (pushY < 0) {
-			if (getWalkabilityAt(*pTargetY - 1, *pTargetX) < 200) {
+			if (isWalkabilityWalkable(getWalkabilityAt(*pTargetY - 1, *pTargetX))) {
 				*pTargetY = *pTargetY - 1;
 			}
 			pushY++;
 		}
 		if (pushY > 0) {
-			if (getWalkabilityAt(*pTargetY + 1, *pTargetX) < 200) {
+			if (isWalkabilityWalkable(getWalkabilityAt(*pTargetY + 1, *pTargetX))) {
 				*pTargetY = *pTargetY + 1;
 			}
 			pushY--;
@@ -987,11 +987,11 @@ bool Macs2Engine::isPathWalkable(int16 y1, int16 x1, int16 y2, int16 x2) {
 		}
 
 		if (absDx > absDy && steppedX) {
-			if (getWalkabilityAt(curY, curX) >= 0xC8)
+			if (isWalkabilityBlocking(getWalkabilityAt(curY, curX)))
 				result = false;
 		}
 		if (absDx <= absDy && !steppedX) {
-			if (getWalkabilityAt(curY, curX) >= 0xC8)
+			if (isWalkabilityBlocking(getWalkabilityAt(curY, curX)))
 				result = false;
 		}
 	} while (curX != x1 || curY != y1);
diff --git a/engines/macs2/macs2.h b/engines/macs2/macs2.h
index b26e55a112d..c3dd78bc047 100644
--- a/engines/macs2/macs2.h
+++ b/engines/macs2/macs2.h
@@ -309,6 +309,15 @@ public:
 	bool getPathfindingOverride(uint16 index, uint16 &result);
 	void setPathfindingOverride(uint16 index, uint16 overrideValue);
 
+	// Walkability threshold 0xC8 uses signed 16-bit comparison in the binary (JL/JGE).
+	// Values with (int16)value < 0xC8 are walkable heights; e.g. -2 (0xFFFE) is walkable.
+	static inline bool isWalkabilityBlocking(uint16 value) {
+		return (int16)value >= 0xC8;
+	}
+	static inline bool isWalkabilityWalkable(uint16 value) {
+		return (int16)value < 0xC8;
+	}
+
 	// This one implements the lookup relative to es:[di+4EA8h] vs. the other one at es:[di+4EA5h] and es:[di+4EA6h]
 	uint16 getPathfindingOverride2(uint16 index);
 	void removePathfindingOverride(uint16 index);
diff --git a/engines/macs2/scriptexecutor.cpp b/engines/macs2/scriptexecutor.cpp
index bedff69742b..2df81ddf388 100644
--- a/engines/macs2/scriptexecutor.cpp
+++ b/engines/macs2/scriptexecutor.cpp
@@ -520,6 +520,39 @@ Common::Point ScriptExecutor::getCharPosition() {
 	return actor ? actor->_position : Common::Point();
 }
 
+void ScriptExecutor::debugLogActorWalkState(const char *context) {
+	if (!debugChannelSet(-1, kDebugScript))
+		return;
+
+	const uint16 actorIndex = Scenes::instance()._currentActorIndex;
+	const GameObject *actor = GameObjects::getObjectByIndex(actorIndex);
+	if (actor == nullptr) {
+		debugC(kDebugScript, "%s: no actor object", context);
+		return;
+	}
+
+	const int16 x = actor->_position.x;
+	const int16 y = actor->_position.y;
+	const uint16 area = getAreaAtPoint((uint16)x, (uint16)y);
+	const uint16 walk = _engine->getWalkabilityAt(y, x);
+	View1 *view = (View1 *)_engine->findView("View1");
+	Character *character = view ? view->getCharacterByIndex(actorIndex) : nullptr;
+
+	debugC(kDebugScript,
+		   "%s: actor=(%d,%d) area=%u walk=%u/0x%04x int16=%d walkable=%s var[122]=%u "
+		   "cursor=0x%02x executorState=%u walkWaitObj=%u frameWait=%u soundWait=%d musicWait=%d "
+		   "pendingVMotion=%s vOff=%u motionTgt=%u motionProg=%u/%u repeatRun=%d",
+		   context, x, y, area, walk, walk, (int16)walk, Macs2Engine::isWalkabilityWalkable(walk) ? "yes" : "NO",
+		   getVariableValue(122), (uint)_cursorMode, (uint)_state, _walkTargetObjectIndex,
+		   _frameWaitTicksRemaining, _waitForPcmSound ? 1 : 0, _waitForMusicControl ? 1 : 0,
+		   (character && character->hasPendingVerticalMotion()) ? "yes" : "no",
+		   actor->_verticalOffsetScale,
+		   character ? character->_motionTargetVerticalOffset : 0u,
+		   character ? character->_motionProgress : 0u,
+		   character ? character->_motionDistanceUnits : 0u,
+		   _repeatRunFlag ? 1 : 0);
+}
+
 bool ScriptExecutor::isRelevantObject(const GameObject *obj) const {
 	// Original logic (runScriptExecutor at 1008:e3e7):
 	// An object is relevant if it has runtime data allocated (non-null pointer at object+0xa).
@@ -1291,7 +1324,7 @@ void Script::ScriptExecutor::scriptWalkToPosition() {
 	c->_pathFinalDestination = target;
 
 	bool directPath = _engine->isPathWalkable(y, x, current.y, current.x);
-	if (!directPath && _engine->getWalkabilityAt(y, x) < 200) {
+	if (!directPath && Macs2Engine::isWalkabilityWalkable(_engine->getWalkabilityAt(y, x))) {
 		c->calculatePath(target);
 	}
 	if (c->_path.empty()) {
@@ -1344,6 +1377,7 @@ ExecutionResult Script::ScriptExecutor::scriptWaitForWalk() {
 	_walkTargetObjectIndex = objectID;
 	endTimer();
 	endBuffering(_lastOpcodeTriggeredSkip);
+	debugLogActorWalkState("waitForWalk start");
 	enterBlockingWaitCursor();
 	// Binary: opcode 0x11 exits executeOpcodes with g_wScriptIsExecuting still true.
 	// runScriptExecutor returns immediately (no object iteration, no cursor restore).
@@ -1456,6 +1490,7 @@ ExecutionResult Script::ScriptExecutor::scriptShowDialogueChoice() {
 ExecutionResult Script::ScriptExecutor::scriptDismissPanel() {
 	// Set the stream to the end and let the calling code figure out that we are done
 	// for this run.
+	debugLogActorWalkState("dismissPanel (opcode 0x18)");
 	_stream->seek(_stream->size(), SEEK_SET);
 	endBuffering(_lastOpcodeTriggeredSkip);
 	return ExecutionResult::ScriptFinished;
@@ -1884,6 +1919,7 @@ void Script::ScriptExecutor::scriptSetMotion() {
 
 	Character *character = getOrCreateCharacter((uint16)objectID);
 	seedMotionState(object, character, targetVerticalOffset, verticalOffsetDelta, motionDistance);
+	debugLogActorWalkState("after setMotion");
 }
 
 bool Script::ScriptExecutor::scriptSetOrientation() {
@@ -1938,7 +1974,7 @@ void Script::ScriptExecutor::scriptMoveToPosition() {
 
 	const Common::Point target(x, y);
 	if (!_engine->isPathWalkable(object->_position.y, object->_position.x, y, x) &&
-		_engine->getWalkabilityAt(target) < 0xC8) {
+		Macs2Engine::isWalkabilityWalkable(_engine->getWalkabilityAt(target))) {
 		setScriptError(0x15);
 		return;
 	}
@@ -2508,6 +2544,7 @@ void Script::ScriptExecutor::scriptFrameWait() {
 	// once per game tick, rather than using a wall-clock timer.
 	uint16 duration = scriptReadValue16();
 	debugC(kDebugScript, "SCRIPT::frameWait(duration=%u)", duration);
+	debugLogActorWalkState("frameWait start");
 	startFrameWait(duration);
 	enterBlockingWaitCursor();
 	endBuffering(_lastOpcodeTriggeredSkip);
@@ -2520,7 +2557,9 @@ void Script::ScriptExecutor::scriptSetPathfinding() {
 	uint16 areaID = scriptReadValue16();
 	uint16 active = scriptReadValue16();
 	uint16 overrideValue = scriptReadValue16();
-	debugC(kDebugScript, "SCRIPT::setPathfinding(areaID=%u, active=%u, overrideValue=%u)", areaID, active, overrideValue);
+	debugC(kDebugScript, "SCRIPT::setPathfinding(areaID=%u, active=%u, overrideValue=%u/0x%04x int16=%d walkable=%s)",
+		   areaID, active, overrideValue, overrideValue, (int16)overrideValue,
+		   (!active || Macs2Engine::isWalkabilityWalkable(overrideValue)) ? "yes" : "NO");
 	if (areaID < 200 || areaID > 0xEF) {
 		setScriptError(0x0D);
 		return;
@@ -2530,6 +2569,7 @@ void Script::ScriptExecutor::scriptSetPathfinding() {
 	} else {
 		g_engine->removePathfindingOverride(areaID);
 	}
+	debugLogActorWalkState("after setPathfinding");
 }
 
 void Script::ScriptExecutor::scriptTestSceneAnimFrame() {
@@ -2609,9 +2649,14 @@ bool Script::ScriptExecutor::scriptWaitForSound() {
 		_waitForPcmSound = true;
 		endTimer();
 		endBuffering(_lastOpcodeTriggeredSkip);
+		debugC(kDebugScript, "SCRIPT::waitForSound start (soundPlaying=%d hasSound=%d)",
+			   g_engine->isCurrentSoundPlaying() ? 1 : 0, g_engine->hasCurrentSound() ? 1 : 0);
+		debugLogActorWalkState("waitForSound start");
 		enterBlockingWaitCursor();
 		return true;
 	}
+	debugC(kDebugScript, "SCRIPT::waitForSound skipped (soundEnabled=%d soundSystemActive=%d)",
+		   _soundEnabled ? 1 : 0, _soundSystemActive ? 1 : 0);
 	return false;
 }
 
diff --git a/engines/macs2/scriptexecutor.h b/engines/macs2/scriptexecutor.h
index 9d3b03cd812..b4a9b0b7aa5 100644
--- a/engines/macs2/scriptexecutor.h
+++ b/engines/macs2/scriptexecutor.h
@@ -433,6 +433,9 @@ public:
 	void setRepeatRunFlag(bool val) { _repeatRunFlag = val; }
 	uint32 getVariableValue(int index) const;
 
+	// Plate / walk debugging: log actor position, area, walkability, script waits.
+	void debugLogActorWalkState(const char *context);
+
 	// Computes the read-only runtime value for a type 0xFF special
 	// (FF:value), inlined in scriptReadValue in the original binary
 	uint32 getSpecialValue(uint16 value);
diff --git a/engines/macs2/view1.cpp b/engines/macs2/view1.cpp
index 0f509a4aa3f..d282ba676a5 100644
--- a/engines/macs2/view1.cpp
+++ b/engines/macs2/view1.cpp
@@ -1559,7 +1559,7 @@ bool View1::handleInput(const MouseDownMessage &msg) {
 			protagonist->_path.clear();
 
 			const bool directPath = g_engine->isPathWalkable(target.y, target.x, charPos.y, charPos.x);
-			if (directPath || g_engine->getWalkabilityAt(target.y, target.x) >= 200) {
+			if (directPath || Macs2Engine::isWalkabilityBlocking(g_engine->getWalkabilityAt(target.y, target.x))) {
 				protagonist->_targetPosition = target;
 			} else {
 				const bool found = protagonist->calculatePath(target);
@@ -2184,6 +2184,8 @@ bool View1::tick() {
 					}
 					if (walkComplete) {
 						if (!executor->_pickupInProgress) {
+							debugC(kDebugScript, "waitForWalk complete obj=%u", walkTarget);
+							executor->debugLogActorWalkState("waitForWalk complete");
 							executor->_walkTargetObjectIndex = 0;
 							g_engine->runScriptExecutor();
 						} else if (c != nullptr && c->_gameObject->_orientation != 0x11) {
@@ -2197,6 +2199,8 @@ bool View1::tick() {
 			} else if (executor->_waitForPcmSound) {
 				drawSceneUpdate();
 				if (!g_engine->isCurrentSoundPlaying()) {
+					debugC(kDebugScript, "waitForSound complete");
+					executor->debugLogActorWalkState("waitForSound complete");
 					executor->_waitForPcmSound = false;
 					g_engine->runScriptExecutor();
 				}
@@ -2216,6 +2220,8 @@ bool View1::tick() {
 		} else {
 			drawSceneUpdate();
 			if (executor->getFrameWaitCounter() == 0) {
+				debugC(kDebugScript, "frameWait complete");
+				executor->debugLogActorWalkState("frameWait complete");
 				executor->endFrameWait();
 				g_engine->runScriptExecutor();
 			}
@@ -2376,7 +2382,7 @@ void View1::drawAllCharacters(Graphics::ManagedSurface *surface, bool fullUpdate
 			int16 walkabilityOffset = 0;
 			if (g_engine->_pathfindingMap.w > 0) {
 				walkabilityOffset = g_engine->getWalkabilityAt(charY, charX);
-				if (walkabilityOffset >= 200)
+				if (Macs2Engine::isWalkabilityBlocking((uint16)walkabilityOffset))
 					walkabilityOffset = 0;
 			}
 			if (obj->_verticalOffsetScale != 0)
@@ -2453,10 +2459,24 @@ void View1::drawAllCharacters(Graphics::ManagedSurface *surface, bool fullUpdate
 	}
 
 	// Binary drawAllCharacters tail: movement-finished repeat run (opcode 0x27 area checks).
-	if (fullUpdate && g_engine->_movementFinishedFlag && !executor->isScriptWaitDeferred()) {
-		executor->_isRepeatRun = true;
-		g_engine->runScriptExecutor();
-		executor->_isRepeatRun = false;
+	if (fullUpdate && g_engine->_movementFinishedFlag) {
+		if (executor->isScriptWaitDeferred()) {
+			debugC(kDebugScript,
+				   "repeatRun deferred: walkWait=%u frameWait=%u soundWait=%d musicWait=%d adlibWait=%d",
+				   executor->_walkTargetObjectIndex, executor->getFrameWaitCounter(),
+				   executor->_waitForPcmSound ? 1 : 0, executor->_waitForMusicControl ? 1 : 0,
+				   executor->_waitForAdlibReady ? 1 : 0);
+		} else {
+			const Common::Point actorPos = executor->getCharPosition();
+			const uint16 area = executor->getAreaAtPoint(actorPos.x, actorPos.y);
+			debugC(kDebugScript, "repeatRun start: actor=(%d,%d) areaRepeatRun=%u var[122]=%u",
+				   actorPos.x, actorPos.y, area, executor->getVariableValue(122));
+			executor->debugLogActorWalkState("repeatRun start");
+			executor->_isRepeatRun = true;
+			g_engine->runScriptExecutor();
+			executor->_isRepeatRun = false;
+			executor->debugLogActorWalkState("repeatRun end");
+		}
 	}
 }
 
@@ -3110,27 +3130,12 @@ bool Character::HandleWalkability(Character *c) {
 	return true;
 }
 
-uint8 Character::lookupWalkability(const Common::Point &p) const {
-	Common::Rect screenRect(320, 200);
-	if (!screenRect.contains(p)) {
-		return 0x00;
-	}
-	uint32 value = g_engine->_pathfindingMap.getPixel(p.x, p.y);
-	// Values 0xC8..0xEF use the pathfinding override table (opcode 0x12)
-	if (value >= 0xC8 && value <= 0xEF) {
-		uint16 overrideResult;
-		if (g_engine->getPathfindingOverride(value, overrideResult)) {
-			return (uint8)overrideResult;
-		}
-		// Override not active - return non-walkable
-		return 0xFF;
-	}
-	return (uint8)value;
+uint16 Character::lookupWalkability(const Common::Point &p) const {
+	return g_engine->getWalkabilityAt((int16)p.y, (int16)p.x);
 }
 
 bool Character::isWalkable(const Common::Point &p) const {
-	uint8 walkability = lookupWalkability(p);
-	return walkability < 0xC8;
+	return Macs2Engine::isWalkabilityWalkable(lookupWalkability(p));
 }
 
 Character::Character() {
@@ -3288,7 +3293,7 @@ void Character::setPosition(const Common::Point &newPosition) {
 
 uint16 Character::getVerticalOffset() const {
 	uint16 result = g_engine->getWalkabilityAt(getPosition());
-	if (result >= 0xC8) {
+	if (Macs2Engine::isWalkabilityBlocking(result)) {
 		result = 0;
 	}
 
@@ -3451,7 +3456,7 @@ void Character::startPickup(Macs2::GameObject *object) {
 	_path.clear();
 
 	bool directPath = g_engine->isPathWalkable(destY, destX, current.y, current.x);
-	if (!directPath && g_engine->getWalkabilityAt(destY, destX) < 200) {
+	if (!directPath && Macs2Engine::isWalkabilityWalkable(g_engine->getWalkabilityAt(destY, destX))) {
 		calculatePath(Common::Point(destX, destY));
 	}
 
@@ -3686,45 +3691,52 @@ void Character::update() {
 			}
 			// Walkability check - binary uses getWalkabilityAt(posY, posX) >= 0xC8
 			if (!isWalkable(pos)) {
+				const uint16 tileArea = g_engine->_scriptExecutor->getAreaAtPoint(pos.x, pos.y);
+				if (tileArea >= 210 && tileArea <= 215) {
+					debugC(kDebugPath,
+						   "walk blocked on plate area %u at (%d,%d) walk=%u int16=%d target=(%d,%d)",
+						   tileArea, pos.x, pos.y, lookupWalkability(pos), (int16)lookupWalkability(pos),
+						   _targetPosition.x, _targetPosition.y);
+				}
 				// Revert position
 				pos = savedPos;
 				// Wall-sliding: build push vector from ±1 and ±2 samples
 				int pushX = 0, pushY = 0;
-				if (lookupWalkability(Common::Point(pos.x + 1, pos.y)) >= 200)
+				if (Macs2Engine::isWalkabilityBlocking(lookupWalkability(Common::Point(pos.x + 1, pos.y))))
 					pushX--;
-				if (lookupWalkability(Common::Point(pos.x - 1, pos.y)) >= 200)
+				if (Macs2Engine::isWalkabilityBlocking(lookupWalkability(Common::Point(pos.x - 1, pos.y))))
 					pushX++;
-				if (lookupWalkability(Common::Point(pos.x, pos.y + 1)) >= 200)
+				if (Macs2Engine::isWalkabilityBlocking(lookupWalkability(Common::Point(pos.x, pos.y + 1))))
 					pushY--;
-				if (lookupWalkability(Common::Point(pos.x, pos.y - 1)) >= 200)
+				if (Macs2Engine::isWalkabilityBlocking(lookupWalkability(Common::Point(pos.x, pos.y - 1))))
 					pushY++;
-				if (lookupWalkability(Common::Point(pos.x + 2, pos.y)) >= 200)
+				if (Macs2Engine::isWalkabilityBlocking(lookupWalkability(Common::Point(pos.x + 2, pos.y))))
 					pushX--;
-				if (lookupWalkability(Common::Point(pos.x - 2, pos.y)) >= 200)
+				if (Macs2Engine::isWalkabilityBlocking(lookupWalkability(Common::Point(pos.x - 2, pos.y))))
 					pushX++;
-				if (lookupWalkability(Common::Point(pos.x, pos.y + 2)) >= 200)
+				if (Macs2Engine::isWalkabilityBlocking(lookupWalkability(Common::Point(pos.x, pos.y + 2))))
 					pushY--;
-				if (lookupWalkability(Common::Point(pos.x, pos.y - 2)) >= 200)
+				if (Macs2Engine::isWalkabilityBlocking(lookupWalkability(Common::Point(pos.x, pos.y - 2))))
 					pushY++;
 				// Apply push vector
 				while (pushX != 0 || pushY != 0) {
 					if (pushX < 0) {
-						if (lookupWalkability(Common::Point(pos.x - 1, pos.y)) < 200)
+						if (Macs2Engine::isWalkabilityWalkable(lookupWalkability(Common::Point(pos.x - 1, pos.y))))
 							pos.x--;
 						pushX++;
 					}
 					if (pushX > 0) {
-						if (lookupWalkability(Common::Point(pos.x + 1, pos.y)) < 200)
+						if (Macs2Engine::isWalkabilityWalkable(lookupWalkability(Common::Point(pos.x + 1, pos.y))))
 							pos.x++;
 						pushX--;
 					}
 					if (pushY < 0) {
-						if (lookupWalkability(Common::Point(pos.x, pos.y - 1)) < 200)
+						if (Macs2Engine::isWalkabilityWalkable(lookupWalkability(Common::Point(pos.x, pos.y - 1))))
 							pos.y--;
 						pushY++;
 					}
 					if (pushY > 0) {
-						if (lookupWalkability(Common::Point(pos.x, pos.y + 1)) < 200)
+						if (Macs2Engine::isWalkabilityWalkable(lookupWalkability(Common::Point(pos.x, pos.y + 1))))
 							pos.y++;
 						pushY--;
 					}
@@ -3740,6 +3752,17 @@ void Character::update() {
 
 	// Binary (2280): if pixelsMoved != walkSpeed -> revert and cancel
 	if (pixelsMoved != walkSpeed) {
+		const uint16 tileArea = g_engine->_scriptExecutor->getAreaAtPoint(pos.x, pos.y);
+		if (tileArea >= 210 && tileArea <= 215) {
+			debugC(kDebugPath,
+				   "walk cancelled pixelsMoved=%d walkSpeed=%d at (%d,%d) area=%u walk=%u finalDest=(%d,%d)",
+				   pixelsMoved, walkSpeed, pos.x, pos.y, tileArea, lookupWalkability(pos),
+				   _pathFinalDestination.x, _pathFinalDestination.y);
+		} else if (Macs2Engine::isWalkabilityBlocking(lookupWalkability(pos))) {
+			debugC(kDebugPath,
+				   "walk cancelled (non-walkable) pixelsMoved=%d walkSpeed=%d at (%d,%d) walk=%u",
+				   pixelsMoved, walkSpeed, pos.x, pos.y, lookupWalkability(pos));
+		}
 		pos = savedPos;
 		_targetPosition = pos;
 		_pathFinalDestination = pos;
diff --git a/engines/macs2/view1.h b/engines/macs2/view1.h
index f3b83dd3fc4..37faf599802 100644
--- a/engines/macs2/view1.h
+++ b/engines/macs2/view1.h
@@ -80,7 +80,7 @@ private:
 	bool HandleWalkability(Character *c);
 
 	// fn0037_0E8C proc
-	uint8 lookupWalkability(const Common::Point &p) const;
+	uint16 lookupWalkability(const Common::Point &p) const;
 
 public:
 	Character();




More information about the Scummvm-git-logs mailing list