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

neuromancer noreply at scummvm.org
Thu Oct 9 19:00:39 UTC 2025


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

Summary:
685aeeb27c FREESCAPE: make sure waitInLoop will not trigger group instructions recursively
5cbebfeec8 FREESCAPE: various fixes for castle (dos)
b2ad68c764 FREESCAPE: avoiding incorrect parsing of AGAIN (thanks for @farmboy0)
d011e500d9 FREESCAPE: normalize activation vector similar to shoot


Commit: 685aeeb27c6098ea828894f001e4295e8186f03e
    https://github.com/scummvm/scummvm/commit/685aeeb27c6098ea828894f001e4295e8186f03e
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2025-10-09T16:00:17-03:00

Commit Message:
FREESCAPE: make sure waitInLoop will not trigger group instructions recursively

Changed paths:
    engines/freescape/area.cpp
    engines/freescape/area.h
    engines/freescape/freescape.cpp
    engines/freescape/ui.cpp


diff --git a/engines/freescape/area.cpp b/engines/freescape/area.cpp
index 4473342476d..202b284507e 100644
--- a/engines/freescape/area.cpp
+++ b/engines/freescape/area.cpp
@@ -234,7 +234,7 @@ void Area::resetArea() {
 }
 
 
-void Area::draw(Freescape::Renderer *gfx, uint32 animationTicks, Math::Vector3d camera, Math::Vector3d direction) {
+void Area::draw(Freescape::Renderer *gfx, uint32 animationTicks, Math::Vector3d camera, Math::Vector3d direction, bool insideWait) {
 	bool runAnimation = animationTicks != _lastTick;
 	assert(_drawableObjects.size() > 0);
 	ObjectArray planarObjects;
@@ -251,7 +251,7 @@ void Area::draw(Freescape::Renderer *gfx, uint32 animationTicks, Math::Vector3d
 			}
 
 			if (obj->getType() == ObjectType::kGroupType) {
-				drawGroup(gfx, (Group *)obj, runAnimation);
+				drawGroup(gfx, (Group *)obj, runAnimation && !insideWait);
 				continue;
 			}
 
diff --git a/engines/freescape/area.h b/engines/freescape/area.h
index fbb1397f93d..dea4c7a8e51 100644
--- a/engines/freescape/area.h
+++ b/engines/freescape/area.h
@@ -54,7 +54,7 @@ public:
 	uint8 getScale();
 	void remapColor(int index, int color);
 	void unremapColor(int index);
-	void draw(Renderer *gfx, uint32 animationTicks, Math::Vector3d camera, Math::Vector3d direction);
+	void draw(Renderer *gfx, uint32 animationTicks, Math::Vector3d camera, Math::Vector3d direction, bool insideWait);
 	void drawGroup(Renderer *gfx, Group *group, bool runAnimation);
 	void show();
 
diff --git a/engines/freescape/freescape.cpp b/engines/freescape/freescape.cpp
index d07c80b0d3e..41db4af5a6e 100644
--- a/engines/freescape/freescape.cpp
+++ b/engines/freescape/freescape.cpp
@@ -456,7 +456,7 @@ void FreescapeEngine::drawFrame() {
 
 	drawBackground();
 	if (_avoidRenderingFrames == 0) { // Avoid rendering inside objects
-		_currentArea->draw(_gfx, _ticks / 10, _position, _cameraFront);
+		_currentArea->draw(_gfx, _ticks / 10, _position, _cameraFront, false);
 		if (_gameStateControl == kFreescapeGameStatePlaying &&
 		    _currentArea->hasActiveGroups() && _ticks % 50 == 0) {
 			executeMovementConditions();
diff --git a/engines/freescape/ui.cpp b/engines/freescape/ui.cpp
index b907bc0755e..78621ffc2d2 100644
--- a/engines/freescape/ui.cpp
+++ b/engines/freescape/ui.cpp
@@ -85,7 +85,7 @@ void FreescapeEngine::waitInLoop(int maxWait) {
 		_gfx->positionCamera(_position, _position + _cameraFront, _roll);
 
 		drawBackground();
-		_currentArea->draw(_gfx, _ticks / 10, _position, _cameraFront);
+		_currentArea->draw(_gfx, _ticks / 10, _position, _cameraFront, true);
 		drawBorder();
 		drawUI();
 


Commit: 5cbebfeec8aaaee73257eac43e94f26ff801dbdf
    https://github.com/scummvm/scummvm/commit/5cbebfeec8aaaee73257eac43e94f26ff801dbdf
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2025-10-09T16:00:17-03:00

Commit Message:
FREESCAPE: various fixes for castle (dos)

Changed paths:
    engines/freescape/area.cpp
    engines/freescape/area.h
    engines/freescape/games/castle/castle.cpp
    engines/freescape/games/castle/dos.cpp
    engines/freescape/language/instruction.cpp
    engines/freescape/loaders/8bitBinaryLoader.cpp


diff --git a/engines/freescape/area.cpp b/engines/freescape/area.cpp
index 202b284507e..f24ca8d5492 100644
--- a/engines/freescape/area.cpp
+++ b/engines/freescape/area.cpp
@@ -60,11 +60,12 @@ uint8 Area::getScale() {
 	return _scale;
 }
 
-Area::Area(uint16 areaID_, uint16 areaFlags_, ObjectMap *objectsByID_, ObjectMap *entrancesByID_) {
+Area::Area(uint16 areaID_, uint16 areaFlags_, ObjectMap *objectsByID_, ObjectMap *entrancesByID_, bool isCastle_) {
 	_areaID = areaID_;
 	_areaFlags = areaFlags_;
 	_objectsByID = objectsByID_;
 	_entrancesByID = entrancesByID_;
+	_isCastle = isCastle_;
 
 	_scale = 0;
 	_skyColor = 255;
@@ -491,9 +492,9 @@ Math::Vector3d Area::resolveCollisions(const Math::Vector3d &lastPosition_, cons
 	float reductionHeight = 0.0;
 	// Ugly hack to fix the collisions in tight spaces in the stores and junk room
 	// for Castle Master
-	if (_name == "    STORES     " && _areaID == 62) {
+	if (_isCastle && _areaID == 62) {
 		reductionHeight = 0.3f;
-	} else if (_name == "   JUNK ROOM   " && _areaID == 61) {
+	} else if (_isCastle && _areaID == 61) {
 		reductionHeight = 0.3f;
 	}
 
diff --git a/engines/freescape/area.h b/engines/freescape/area.h
index dea4c7a8e51..87bfbddb918 100644
--- a/engines/freescape/area.h
+++ b/engines/freescape/area.h
@@ -39,7 +39,7 @@ typedef Common::HashMap<uint16, Object *> ObjectMap;
 typedef Common::Array<Object *> ObjectArray;
 class Area {
 public:
-	Area(uint16 areaID, uint16 areaFlags, ObjectMap *objectsByID, ObjectMap *entrancesByID);
+	Area(uint16 areaID, uint16 areaFlags, ObjectMap *objectsByID, ObjectMap *entrancesByID, bool isCastle);
 	virtual ~Area();
 
 	Common::String _name;
@@ -86,6 +86,9 @@ public:
 	Common::Point _gasPocketPosition;
 	uint32 _gasPocketRadius;
 
+	// Castle Master specific
+	bool _isCastle;
+
 	uint8 _scale;
 	uint8 _skyColor;
 	uint8 _groundColor;
diff --git a/engines/freescape/games/castle/castle.cpp b/engines/freescape/games/castle/castle.cpp
index b0a69e8755f..7c889990cc5 100644
--- a/engines/freescape/games/castle/castle.cpp
+++ b/engines/freescape/games/castle/castle.cpp
@@ -468,7 +468,7 @@ bool CastleEngine::checkIfGameEnded() {
 		}
 	}
 
-	if (getGameBit(31) || _currentArea->getAreaID() == 74) { // Escaped!
+	if (getGameBit(31) && _currentArea->getAreaID() == 74) { // Escaped!
 		_gameStateControl = kFreescapeGameStateEnd;
 		return true;
 	} else
diff --git a/engines/freescape/games/castle/dos.cpp b/engines/freescape/games/castle/dos.cpp
index 6d717b0adb1..23b33d6ff64 100644
--- a/engines/freescape/games/castle/dos.cpp
+++ b/engines/freescape/games/castle/dos.cpp
@@ -270,6 +270,8 @@ void CastleEngine::loadAssetsDOSFullGame() {
 			case Common::ES_ESP:
 				stream = decryptFile("CMLS");
 				loadRiddles(stream, 0xaae - 2 - 22 * 2, 22);
+				// Fixes for incorrect or wrong translations
+				Common::replace(_riddleList[16]._lines[5]._text, "IN", "EN");
 				break;
 			case Common::FR_FRA:
 				stream = decryptFile("CMLF");
diff --git a/engines/freescape/language/instruction.cpp b/engines/freescape/language/instruction.cpp
index 2c03944ee35..55963fa0a78 100644
--- a/engines/freescape/language/instruction.cpp
+++ b/engines/freescape/language/instruction.cpp
@@ -365,6 +365,10 @@ void FreescapeEngine::executeExecute(FCLInstruction &instruction, bool shot, boo
 		obj = _areaMap[255]->objectWithID(objId);
 		if (!obj) {
 			obj = _areaMap[255]->entranceWithID(objId);
+			if (!obj) {
+				debugC(1, kFreescapeDebugCode, "WARNING: executing instructions from a non-existent object %d", objId);
+				return;
+			} 
 			assert(obj);
 			FCLInstructionVector &condition = ((Entrance *)obj)->_condition;
 			executeCode(condition, shot, collided, false, activated);
diff --git a/engines/freescape/loaders/8bitBinaryLoader.cpp b/engines/freescape/loaders/8bitBinaryLoader.cpp
index 33033fdebbb..66fa75f0e93 100644
--- a/engines/freescape/loaders/8bitBinaryLoader.cpp
+++ b/engines/freescape/loaders/8bitBinaryLoader.cpp
@@ -785,7 +785,7 @@ Area *FreescapeEngine::load8bitArea(Common::SeekableReadStream *file, uint16 nco
 	uint8 numConditions = readField(file, 8);
 	debugC(1, kFreescapeDebugParser, "%d area conditions at %x of area %d", numConditions, base + cPtr, areaNumber);
 
-	Area *area = new Area(areaNumber, areaFlags, objectsByID, entrancesByID);
+	Area *area = new Area(areaNumber, areaFlags, objectsByID, entrancesByID, isCastle());
 	area->_name = name;
 	area->_scale = scale;
 	area->_skyColor = skyColor;
@@ -1112,7 +1112,7 @@ void FreescapeEngine::loadGlobalObjects(Common::SeekableReadStream *file, int of
 		(*globalObjectsByID)[gobj->getObjectID()] = gobj;
 	}
 
-	_areaMap[255] = new Area(255, 0, globalObjectsByID, nullptr);
+	_areaMap[255] = new Area(255, 0, globalObjectsByID, nullptr, isCastle());
 }
 
 void FreescapeEngine::parseAmigaAtariHeader(Common::SeekableReadStream *stream) {


Commit: b2ad68c764879d917ab6281498d20b77862dc2af
    https://github.com/scummvm/scummvm/commit/b2ad68c764879d917ab6281498d20b77862dc2af
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2025-10-09T16:00:17-03:00

Commit Message:
FREESCAPE: avoiding incorrect parsing of AGAIN (thanks for @farmboy0)

Changed paths:
    engines/freescape/language/8bitDetokeniser.cpp


diff --git a/engines/freescape/language/8bitDetokeniser.cpp b/engines/freescape/language/8bitDetokeniser.cpp
index c9cec3af1d1..e806e1c3d0b 100644
--- a/engines/freescape/language/8bitDetokeniser.cpp
+++ b/engines/freescape/language/8bitDetokeniser.cpp
@@ -332,7 +332,6 @@ Common::String detokenise8bitCondition(Common::Array<uint16> &tokenisedCondition
 			currentInstruction = FCLInstruction(Token::AGAIN);
 			conditionalInstructions->push_back(currentInstruction);
 			currentInstruction = FCLInstruction(Token::UNKNOWN);
-			bytePointer++;
 			numberOfArguments = 0;
 			break;
 


Commit: d011e500d97c92a773f3c62e0525676caf6806bd
    https://github.com/scummvm/scummvm/commit/d011e500d97c92a773f3c62e0525676caf6806bd
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2025-10-09T16:00:17-03:00

Commit Message:
FREESCAPE: normalize activation vector similar to shoot

Changed paths:
    engines/freescape/movement.cpp


diff --git a/engines/freescape/movement.cpp b/engines/freescape/movement.cpp
index d036aed48b4..d527b33dd60 100644
--- a/engines/freescape/movement.cpp
+++ b/engines/freescape/movement.cpp
@@ -190,12 +190,20 @@ void FreescapeEngine::traverseEntrance(uint16 entranceID) {
 
 void FreescapeEngine::activate() {
 	Common::Point center(_viewArea.left + _viewArea.width() / 2, _viewArea.top + _viewArea.height() / 2);
-	float xoffset = _crossairPosition.x - center.x;
-	float yoffset = _crossairPosition.y - center.y;
-	xoffset = xoffset * 0.33;
-	yoffset = yoffset * 0.50;
+	// Convert to normalized coordinates [-1, 1]
+	float ndcX = (2.0f * (_crossairPosition.x - _viewArea.left) / _viewArea.width()) - 1.0f;
+	float ndcY = 1.0f - (2.0f * (_crossairPosition.y - _viewArea.top) / _viewArea.height());
 
-	Math::Vector3d direction = directionToVector(_pitch - yoffset, _yaw - xoffset, false);
+	// Calculate angular offsets using perspective projection
+	float fovHorizontalRad = (float)(75.0f * M_PI / 180.0f);
+	float aspectRatio = isCastle() ? 1.6 : 2.18;
+	float fovVerticalRad = 2.0f * atan(tan(fovHorizontalRad / 2.0f) / aspectRatio);
+
+	// Convert NDC to angle offset
+	float angleOffsetX = atan(ndcX * tan(fovHorizontalRad / 2.0f)) * 180.0f / M_PI;
+	float angleOffsetY = atan(ndcY * tan(fovVerticalRad / 2.0f)) * 180.0f / M_PI;
+
+	Math::Vector3d direction = directionToVector(_pitch + angleOffsetY, _yaw - angleOffsetX, false);
 	Math::Ray ray(_position, direction);
 	Object *interacted = _currentArea->checkCollisionRay(ray, 1250.0 / _currentArea->getScale());
 	if (interacted) {




More information about the Scummvm-git-logs mailing list