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

neuromancer noreply at scummvm.org
Sun Aug 4 13:38:56 UTC 2024


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

Summary:
b2f5cdaffa FREESCAPE: execute opcode implementation and castle zx fixes
018597fae2 FREESCAPE: compute, save and load spirit meter in castle
e28c0d5e37 FREESCAPE: initial implementation of the spirit meter in castle for zx


Commit: b2f5cdaffa5ab1a37e0c470c245ed8e1f80b78e4
    https://github.com/scummvm/scummvm/commit/b2f5cdaffa5ab1a37e0c470c245ed8e1f80b78e4
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2024-08-04T15:31:24+02:00

Commit Message:
FREESCAPE: execute opcode implementation and castle zx fixes

Changed paths:
    engines/freescape/freescape.h
    engines/freescape/games/castle/castle.cpp
    engines/freescape/games/castle/castle.h
    engines/freescape/games/castle/zx.cpp
    engines/freescape/language/instruction.cpp


diff --git a/engines/freescape/freescape.h b/engines/freescape/freescape.h
index 64112c2cba2..04a82803ad3 100644
--- a/engines/freescape/freescape.h
+++ b/engines/freescape/freescape.h
@@ -354,7 +354,7 @@ public:
 	void executeSetVariable(FCLInstruction &instruction);
 	void executeGoto(FCLInstruction &instruction);
 	void executeIfThenElse(FCLInstruction &instruction);
-	void executeMakeInvisible(FCLInstruction &instruction);
+	virtual void executeMakeInvisible(FCLInstruction &instruction);
 	void executeMakeVisible(FCLInstruction &instruction);
 	void executeToggleVisibility(FCLInstruction &instruction);
 	void executeDestroy(FCLInstruction &instruction);
diff --git a/engines/freescape/games/castle/castle.cpp b/engines/freescape/games/castle/castle.cpp
index 8be1c9b4665..3065032d6fc 100644
--- a/engines/freescape/games/castle/castle.cpp
+++ b/engines/freescape/games/castle/castle.cpp
@@ -58,6 +58,8 @@ CastleEngine::CastleEngine(OSystem *syst, const ADGameDescription *gd) : Freesca
 	_menu = nullptr;
 
 	_numberKeys = 0;
+	_spiritsDestroyed = 0;
+	_spiritsMeter = 32;
 }
 
 CastleEngine::~CastleEngine() {
@@ -129,6 +131,8 @@ void CastleEngine::initGameState() {
 	_gameStateVars[k8bitVariableEnergy] = 1;
 	_countdown = INT_MAX;
 	_numberKeys = 0;
+	_spiritsDestroyed = 0;
+	_spiritsMeter = 32;
 
 	if (_useRockTravel) // Enable cheat
 		setGameBit(k8bitGameBitTravelRock);
@@ -275,6 +279,35 @@ void CastleEngine::drawInfoMenu() {
 	g_system->showMouse(false);
 }
 
+void CastleEngine::executeMakeInvisible(FCLInstruction &instruction) {
+	uint16 objectID = 0;
+	uint16 areaID = _currentArea->getAreaID();
+
+	if (instruction._destination > 0) {
+		objectID = instruction._destination;
+		areaID = instruction._source;
+	} else {
+		objectID = instruction._source;
+	}
+
+	debugC(1, kFreescapeDebugCode, "Making obj %d invisible in area %d!", objectID, areaID);
+	if (_areaMap.contains(areaID)) {
+		Object *obj = _areaMap[areaID]->objectWithID(objectID);
+		if (!obj && isCastle())
+			return; // No side effects
+		assert(obj); // We assume the object was there
+
+		if (!obj->isInvisible() && obj->getType() == kSensorType && isCastle()) {
+			_spiritsDestroyed++;
+		}
+
+		obj->makeInvisible();
+	} else {
+		assert(isDOS() && isDemo()); // Should only happen in the DOS demo
+	}
+
+}
+
 void CastleEngine::executePrint(FCLInstruction &instruction) {
 	uint16 index = instruction._source;
 	_currentAreaMessages.clear();
diff --git a/engines/freescape/games/castle/castle.h b/engines/freescape/games/castle/castle.h
index 4f43ad62333..830c203cd86 100644
--- a/engines/freescape/games/castle/castle.h
+++ b/engines/freescape/games/castle/castle.h
@@ -50,6 +50,7 @@ public:
 	void updateTimeVariables() override;
 
 	void executePrint(FCLInstruction &instruction) override;
+	void executeMakeInvisible(FCLInstruction &instruction) override;
 	void gotoArea(uint16 areaID, int entranceID) override;
 	Common::Error saveGameStreamExtended(Common::WriteStream *stream, bool isAutosave = false) override;
 	Common::Error loadGameStreamExtended(Common::SeekableReadStream *stream) override;
@@ -67,6 +68,8 @@ public:
 	Graphics::Surface *_keysFrame;
 	int _numberKeys;
 	bool _useRockTravel;
+	int _spiritsDestroyed;
+	int _spiritsMeter;
 
 private:
 	Common::SeekableReadStream *decryptFile(const Common::Path &filename);
diff --git a/engines/freescape/games/castle/zx.cpp b/engines/freescape/games/castle/zx.cpp
index 281c5f63ded..33d248d2641 100644
--- a/engines/freescape/games/castle/zx.cpp
+++ b/engines/freescape/games/castle/zx.cpp
@@ -140,6 +140,14 @@ void CastleEngine::loadAssetsZXFullGame() {
 	addGhosts();
 	_areaMap[1]->addFloor();
 	_areaMap[2]->addFloor();
+
+	// Discard the first three global conditions
+	// It is unclear why they hide/unhide objects that formed the spirits
+	for (int i = 0; i < 3; i++) {
+		_conditions.remove_at(i);
+		_conditionSources.remove_at(i);
+	}
+
 }
 
 void CastleEngine::drawZXUI(Graphics::Surface *surface) {
diff --git a/engines/freescape/language/instruction.cpp b/engines/freescape/language/instruction.cpp
index 19af2c2ebce..5aa35ff2b63 100644
--- a/engines/freescape/language/instruction.cpp
+++ b/engines/freescape/language/instruction.cpp
@@ -157,7 +157,6 @@ void FreescapeEngine::executeCode(FCLInstructionVector &code, bool shot, bool co
 
 		switch (instruction.getType()) {
 		default:
-			//if (!isCastle())
 			error("Instruction %x at ip: %d not implemented!", instruction.getType(), ip);
 			break;
 		case Token::NOP:
@@ -223,6 +222,7 @@ void FreescapeEngine::executeCode(FCLInstructionVector &code, bool shot, bool co
 			break;
 		case Token::EXECUTE:
 			executeExecute(instruction);
+			ip = codeSize;
 			break;
 		case Token::DELAY:
 			executeDelay(instruction);
@@ -293,9 +293,19 @@ void FreescapeEngine::executeRedraw(FCLInstruction &instruction) {
 }
 
 void FreescapeEngine::executeExecute(FCLInstruction &instruction) {
-	// TODO
 	uint16 objId = instruction._source;
 	debugC(1, kFreescapeDebugCode, "Executing instructions from object %d", objId);
+	Object *obj = _currentArea->objectWithID(objId);
+	if (!obj) {
+		obj = _areaMap[255]->objectWithID(objId);
+		if (!obj) {
+			obj = _areaMap[255]->entranceWithID(objId);
+			assert(obj);
+			executeEntranceConditions((Entrance *)obj);
+		}
+	} else
+		executeObjectConditions((GeometricObject *)obj, true, false, false);
+
 }
 
 void FreescapeEngine::executeSound(FCLInstruction &instruction) {
@@ -512,6 +522,9 @@ void FreescapeEngine::executeDestroy(FCLInstruction &instruction) {
 }
 
 void FreescapeEngine::executeMakeInvisible(FCLInstruction &instruction) {
+	// Castle uses their own implementation which is hard to
+	// integrate with this code without duplicating most of it
+	assert(!isCastle());
 	uint16 objectID = 0;
 	uint16 areaID = _currentArea->getAreaID();
 
@@ -525,12 +538,10 @@ void FreescapeEngine::executeMakeInvisible(FCLInstruction &instruction) {
 	debugC(1, kFreescapeDebugCode, "Making obj %d invisible in area %d!", objectID, areaID);
 	if (_areaMap.contains(areaID)) {
 		Object *obj = _areaMap[areaID]->objectWithID(objectID);
-		if (!obj && isCastle())
-			return; // No side effects
 		assert(obj); // We assume the object was there
 		obj->makeInvisible();
 	} else {
-		assert(isDOS() && isDemo()); // Should only happen in the DOS demo
+		assert(isDriller() && isDOS() && isDemo());
 	}
 
 }


Commit: 018597fae2f29af85da3e5b7db62c30f2a805666
    https://github.com/scummvm/scummvm/commit/018597fae2f29af85da3e5b7db62c30f2a805666
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2024-08-04T15:31:24+02:00

Commit Message:
FREESCAPE: compute, save and load spirit meter in castle

Changed paths:
    engines/freescape/freescape.cpp
    engines/freescape/games/castle/castle.cpp
    engines/freescape/games/castle/castle.h
    engines/freescape/games/castle/zx.cpp


diff --git a/engines/freescape/freescape.cpp b/engines/freescape/freescape.cpp
index 1c761e57dc2..c48329f4f89 100644
--- a/engines/freescape/freescape.cpp
+++ b/engines/freescape/freescape.cpp
@@ -850,7 +850,7 @@ bool FreescapeEngine::checkIfGameEnded() {
 			insertTemporaryMessage(_forceEndGameMessage, _countdown - 4);
 		_gameStateControl = kFreescapeGameStateEnd;
 	}
-	return false; // TODO
+	return false;
 }
 
 void FreescapeEngine::setGameBit(int index) {
diff --git a/engines/freescape/games/castle/castle.cpp b/engines/freescape/games/castle/castle.cpp
index 3065032d6fc..d1c59e48e4c 100644
--- a/engines/freescape/games/castle/castle.cpp
+++ b/engines/freescape/games/castle/castle.cpp
@@ -60,6 +60,7 @@ CastleEngine::CastleEngine(OSystem *syst, const ADGameDescription *gd) : Freesca
 	_numberKeys = 0;
 	_spiritsDestroyed = 0;
 	_spiritsMeter = 32;
+	_spiritsToKill = 26;
 }
 
 CastleEngine::~CastleEngine() {
@@ -133,11 +134,16 @@ void CastleEngine::initGameState() {
 	_numberKeys = 0;
 	_spiritsDestroyed = 0;
 	_spiritsMeter = 32;
+	_spiritsMeterMax = 64;
 
 	if (_useRockTravel) // Enable cheat
 		setGameBit(k8bitGameBitTravelRock);
 }
 
+bool CastleEngine::checkIfGameEnded() {
+	return FreescapeEngine::checkIfGameEnded();
+}
+
 void CastleEngine::endGame() {
 	_shootingFrames = 0;
 	_delayedShootObject = nullptr;
@@ -661,6 +667,16 @@ void CastleEngine::updateTimeVariables() {
 		_gameStateVars[32] = 0;
 		_numberKeys++;
 	}
+
+	int seconds, minutes, hours;
+	getTimeFromCountdown(seconds, minutes, hours);
+	if (_lastMinute != minutes / 2) {
+		_lastMinute = minutes / 2;
+		_spiritsMeter++;
+		_spiritsMeterPosition = _spiritsMeter * (_spiritsToKill - _spiritsDestroyed) / _spiritsToKill;
+		if (_spiritsMeterPosition >= _spiritsMeterMax)
+			_countdown = -1;
+	}
 }
 
 void CastleEngine::borderScreen() {
@@ -759,11 +775,15 @@ void CastleEngine::selectCharacterScreen() {
 
 Common::Error CastleEngine::saveGameStreamExtended(Common::WriteStream *stream, bool isAutosave) {
 	stream->writeUint32LE(_numberKeys);
+	stream->writeUint32LE(_spiritsMeter);
+	stream->writeUint32LE(_spiritsDestroyed);
 	return Common::kNoError;
 }
 
 Common::Error CastleEngine::loadGameStreamExtended(Common::SeekableReadStream *stream) {
 	_numberKeys = stream->readUint32LE();
+	_spiritsMeter = stream->readUint32LE();
+	_spiritsDestroyed = stream->readUint32LE();
 
 	if (_useRockTravel) // Enable cheat
 		setGameBit(k8bitGameBitTravelRock);
diff --git a/engines/freescape/games/castle/castle.h b/engines/freescape/games/castle/castle.h
index 830c203cd86..e36dc199f87 100644
--- a/engines/freescape/games/castle/castle.h
+++ b/engines/freescape/games/castle/castle.h
@@ -49,6 +49,8 @@ public:
 	void checkSensors() override;
 	void updateTimeVariables() override;
 
+	bool checkIfGameEnded() override;
+
 	void executePrint(FCLInstruction &instruction) override;
 	void executeMakeInvisible(FCLInstruction &instruction) override;
 	void gotoArea(uint16 areaID, int entranceID) override;
@@ -70,6 +72,9 @@ public:
 	bool _useRockTravel;
 	int _spiritsDestroyed;
 	int _spiritsMeter;
+	int _spiritsMeterPosition;
+	int _spiritsMeterMax;
+	int _spiritsToKill;
 
 private:
 	Common::SeekableReadStream *decryptFile(const Common::Path &filename);
diff --git a/engines/freescape/games/castle/zx.cpp b/engines/freescape/games/castle/zx.cpp
index 33d248d2641..84cf5cf9fe6 100644
--- a/engines/freescape/games/castle/zx.cpp
+++ b/engines/freescape/games/castle/zx.cpp
@@ -148,6 +148,11 @@ void CastleEngine::loadAssetsZXFullGame() {
 		_conditionSources.remove_at(i);
 	}
 
+	_timeoutMessage = _messagesList[1];
+	// Shield is unused in Castle Master
+	_noEnergyMessage = _messagesList[1];
+	_fallenMessage = _messagesList[4];
+	_crushedMessage = _messagesList[3];
 }
 
 void CastleEngine::drawZXUI(Graphics::Surface *surface) {


Commit: e28c0d5e37a0d4e83c8ec08e28e12b4ea3f3e725
    https://github.com/scummvm/scummvm/commit/e28c0d5e37a0d4e83c8ec08e28e12b4ea3f3e725
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2024-08-04T15:31:24+02:00

Commit Message:
FREESCAPE: initial implementation of the spirit meter in castle for zx

Changed paths:
    engines/freescape/games/castle/castle.cpp
    engines/freescape/games/castle/castle.h
    engines/freescape/games/castle/zx.cpp


diff --git a/engines/freescape/games/castle/castle.cpp b/engines/freescape/games/castle/castle.cpp
index d1c59e48e4c..a390e42ecc3 100644
--- a/engines/freescape/games/castle/castle.cpp
+++ b/engines/freescape/games/castle/castle.cpp
@@ -55,6 +55,7 @@ CastleEngine::CastleEngine(OSystem *syst, const ADGameDescription *gd) : Freesca
 	_option = nullptr;
 	_optionTexture = nullptr;
 	_keysFrame = nullptr;
+	_spiritsMeterIndicatorFrame = nullptr;
 	_menu = nullptr;
 
 	_numberKeys = 0;
diff --git a/engines/freescape/games/castle/castle.h b/engines/freescape/games/castle/castle.h
index e36dc199f87..dbfef4d1273 100644
--- a/engines/freescape/games/castle/castle.h
+++ b/engines/freescape/games/castle/castle.h
@@ -68,6 +68,7 @@ public:
 	Graphics::Surface *loadFrames(Common::SeekableReadStream *file, Graphics::Surface *surface, int width, int height, uint32 back);
 
 	Graphics::Surface *_keysFrame;
+	Graphics::Surface *_spiritsMeterIndicatorFrame;
 	int _numberKeys;
 	bool _useRockTravel;
 	int _spiritsDestroyed;
diff --git a/engines/freescape/games/castle/zx.cpp b/engines/freescape/games/castle/zx.cpp
index 84cf5cf9fe6..da63270f9fc 100644
--- a/engines/freescape/games/castle/zx.cpp
+++ b/engines/freescape/games/castle/zx.cpp
@@ -111,6 +111,10 @@ void CastleEngine::loadAssetsZXFullGame() {
 	_gfx->readFromPalette(2, r, g, b);
 	uint32 red = _gfx->_texturePixelFormat.ARGBToColor(0xFF, r, g, b);
 	_keysFrame = loadFramesWithHeader(&file, 0xdf7, 1, red);
+
+	uint32 green = _gfx->_texturePixelFormat.ARGBToColor(0xFF, 0, 0xff, 0);
+	_spiritsMeterIndicatorFrame = loadFramesWithHeader(&file, _language == Common::ES_ESP ? 0xe5e : 0xe4f, 1, green);
+
 	Graphics::Surface *background = new Graphics::Surface();
 
 	_gfx->readFromPalette(4, r, g, b);
@@ -182,7 +186,11 @@ void CastleEngine::drawZXUI(Graphics::Surface *surface) {
 	for (int k = 0; k < _numberKeys; k++) {
 		surface->copyRectToSurface((const Graphics::Surface)*_keysFrame, 99 - k * 4, 177, Common::Rect(0, 0, 6, 11));
 	}
-	//surface->copyRectToSurface((const Graphics::Surface)*_background, 0, 0, Common::Rect(0, 0, 8 * 16, 18));
+
+	uint32 green = _gfx->_texturePixelFormat.ARGBToColor(0xFF, 0, 0xff, 0);
+
+	surface->fillRect(Common::Rect(152, 156, 216, 164), green);
+	surface->copyRectToSurface((const Graphics::Surface)*_spiritsMeterIndicatorFrame, 140 + _spiritsMeterPosition, 156, Common::Rect(0, 0, 15, 8));
 	//drawEnergyMeter(surface);
 }
 




More information about the Scummvm-git-logs mailing list