[Scummvm-git-logs] scummvm master -> 0589fe091250cafccda8f9eaaf935ed678a04daf

neuromancer noreply at scummvm.org
Sat May 6 12:01:23 UTC 2023


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

Summary:
835f9e3fb4 FREESCAPE: added support for parsing (hardcoded) font for castle (DOS)
49f9ec8cd1 FREESCAPE: refactored castle (DOS) to use drawDOSUI
7b3bbd0286 FREESCAPE: initial support for castle demo (EGA)
ad0a27c9d8 FREESCAPE: expanded floor size
68c18f33e9 FREESCAPE: initial detection of castle demo for amiga
94d557de15 FREESCAPE: basic implementation of activation (only used in castle/crypt)
0589fe0912 MATH: added generic collision code for AABB class


Commit: 835f9e3fb481a1fbff2a15a25b8e1f908a2a27f3
    https://github.com/scummvm/scummvm/commit/835f9e3fb481a1fbff2a15a25b8e1f908a2a27f3
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2023-05-06T14:03:04+02:00

Commit Message:
FREESCAPE: added support for parsing (hardcoded) font for castle (DOS)

Changed paths:
    engines/freescape/freescape.cpp
    engines/freescape/freescape.h
    engines/freescape/games/castle.cpp
    engines/freescape/loaders/8bitBinaryLoader.cpp


diff --git a/engines/freescape/freescape.cpp b/engines/freescape/freescape.cpp
index 351b96692db..b0253e24604 100644
--- a/engines/freescape/freescape.cpp
+++ b/engines/freescape/freescape.cpp
@@ -722,15 +722,20 @@ void FreescapeEngine::drawStringInSurface(const Common::String &str, int x, int
 	Common::String ustr = str;
 	ustr.toUppercase();
 
+	int sizeX = 8;
+	int sizeY = isCastle() ? 8 : 6;
+	int sep = isCastle() ? 9 : 8;
+	int additional = isCastle() ? 0 : 1;
+
 	if (isDOS() || isSpectrum() || isCPC() || isC64()) {
 		for (uint32 c = 0; c < ustr.size(); c++) {
 			assert(ustr[c] >= 32);
-			for (int j = 0; j < 6; j++) {
-				for (int i = 0; i < 8; i++) {
-					if (_font.get(48 * (offset + ustr[c] - 32) + 1 + j * 8 + i))
-						surface->setPixel(x + 8 - i + 8 * c, y + j, fontColor);
+			for (int j = 0; j < sizeY; j++) {
+				for (int i = 0; i < sizeX; i++) {
+					if (_font.get(sizeX * sizeY * (offset + ustr[c] - 32) + additional + j * 8 + i))
+						surface->setPixel(x + 8 - i + sep * c, y + j, fontColor);
 					else
-						surface->setPixel(x + 8 - i + 8 * c, y + j, backColor);
+						surface->setPixel(x + 8 - i + sep * c, y + j, backColor);
 				}
 			}
 		}
diff --git a/engines/freescape/freescape.h b/engines/freescape/freescape.h
index 66d56c02e82..256c1d5338c 100644
--- a/engines/freescape/freescape.h
+++ b/engines/freescape/freescape.h
@@ -358,6 +358,7 @@ public:
 	void loadMessagesVariableSize(Common::SeekableReadStream *file, int offset, int number);
 
 	void loadFonts(Common::SeekableReadStream *file, int offset);
+	void loadFonts(byte *font, int charNumber);
 	Common::StringArray _currentAreaMessages;
 	Common::StringArray _currentEphymeralMessages;
 	Common::BitArray _font;
@@ -565,12 +566,13 @@ public:
 	CastleEngine(OSystem *syst, const ADGameDescription *gd);
 	~CastleEngine();
 
-
 	Graphics::ManagedSurface *_option;
+	void initGameState() override;
 	void titleScreen() override;
 	void loadAssetsDOSFullGame() override;
 	void drawUI() override;
 
+	void executePrint(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;
diff --git a/engines/freescape/games/castle.cpp b/engines/freescape/games/castle.cpp
index c5747264ea2..254db2de65b 100644
--- a/engines/freescape/games/castle.cpp
+++ b/engines/freescape/games/castle.cpp
@@ -23,6 +23,7 @@
 #include "common/memstream.h"
 
 #include "freescape/freescape.h"
+#include "freescape/language/8bitDetokeniser.h"
 
 namespace Freescape {
 
@@ -99,6 +100,68 @@ byte kCastleBorderDOSPalette[16][3] = {
 	{0x00, 0x00, 0x00}
 };
 
+byte kFreescapeCastleFont[] = {
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x1c, 0x1c, 0x1c, 0x18, 0x18, 0x00, 0x18, 0x18,
+	0x66, 0x66, 0x44, 0x22, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x00,
+	0x10, 0x54, 0x38, 0xfe, 0x38, 0x54, 0x10, 0x00,
+	0x3c, 0x42, 0x9d, 0xb1, 0xb1, 0x9d, 0x42, 0x3c,
+	0x78, 0xcc, 0xcc, 0x78, 0xdb, 0xcf, 0xce, 0x7b,
+	0x30, 0x30, 0x10, 0x20, 0x00, 0x00, 0x00, 0x00,
+	0x10, 0x20, 0x40, 0x40, 0x40, 0x40, 0x20, 0x10,
+	0x10, 0x08, 0x04, 0x04, 0x04, 0x04, 0x08, 0x10,
+	0x10, 0x54, 0x38, 0xfe, 0x38, 0x54, 0x10, 0x00,
+	0x00, 0x00, 0x10, 0x10, 0x7c, 0x10, 0x10, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x08, 0x10,
+	0x00, 0x00, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18,
+	0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80,
+	0x18, 0x66, 0xc3, 0xc3, 0xc3, 0xc3, 0x66, 0x18,
+	0x18, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
+	0x9e, 0x61, 0x01, 0x7e, 0xe0, 0xc6, 0xe3, 0xfe,
+	0xee, 0x73, 0x03, 0x3e, 0x03, 0x01, 0x7f, 0xe6,
+	0x0e, 0x1c, 0x38, 0x71, 0xfd, 0xe6, 0x0c, 0x0c,
+	0xfd, 0x86, 0x80, 0x7e, 0x07, 0x63, 0xc7, 0x7c,
+	0x3d, 0x66, 0xc0, 0xf0, 0xfc, 0xc6, 0x66, 0x3c,
+	0xb3, 0x4e, 0x06, 0x0c, 0x0c, 0x18, 0x18, 0x3c,
+	0x7c, 0xc6, 0xc6, 0x7c, 0xc6, 0xc2, 0xfe, 0x4c,
+	0x3c, 0x4e, 0xc6, 0xc6, 0x4e, 0x36, 0x46, 0x3c,
+	0x00, 0x18, 0x18, 0x00, 0x00, 0x18, 0x18, 0x00,
+	0x00, 0x18, 0x18, 0x00, 0x00, 0x18, 0x08, 0x10,
+	0x03, 0x0c, 0x30, 0xc0, 0x30, 0x0c, 0x03, 0x00,
+	0x00, 0x00, 0xff, 0x00, 0xff, 0x00, 0x00, 0x00,
+	0xc0, 0x30, 0x0c, 0x03, 0x0c, 0x30, 0xc0, 0x00,
+	0x7c, 0xc6, 0x06, 0x0c, 0x30, 0x30, 0x00, 0x30,
+	0x00, 0x08, 0x0c, 0xfe, 0xff, 0xfe, 0x0c, 0x08,
+	0x1e, 0x1c, 0x1e, 0x66, 0xbe, 0x26, 0x43, 0xe3,
+	0xee, 0x73, 0x23, 0x3e, 0x23, 0x21, 0x7f, 0xe6,
+	0x39, 0x6e, 0xc6, 0xc0, 0xc0, 0xc2, 0x63, 0x3e,
+	0xec, 0x72, 0x23, 0x23, 0x23, 0x23, 0x72, 0xec,
+	0xce, 0x7f, 0x61, 0x6c, 0x78, 0x61, 0x7f, 0xce,
+	0xce, 0x7f, 0x61, 0x6c, 0x78, 0x60, 0x60, 0xf0,
+	0x3d, 0x66, 0xc0, 0xc1, 0xce, 0xc6, 0x66, 0x3c,
+	0xe7, 0x66, 0x66, 0x6e, 0x76, 0x66, 0x66, 0xe7,
+	0x66, 0x3c, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x66,
+	0x33, 0x1e, 0x0c, 0x8c, 0x4c, 0xcc, 0xdc, 0x78,
+	0xf2, 0x67, 0x64, 0x68, 0x7e, 0x66, 0x66, 0xf3,
+	0xd8, 0x70, 0x60, 0x60, 0x66, 0x61, 0xf3, 0x7e,
+	0xc3, 0x66, 0x6e, 0x76, 0x56, 0x46, 0x46, 0xef,
+	0x87, 0x62, 0x72, 0x7a, 0x5e, 0x4e, 0x46, 0xe1,
+	0x18, 0x66, 0xc3, 0xc3, 0xc3, 0xc3, 0x66, 0x18,
+	0xec, 0x72, 0x63, 0x63, 0x72, 0x6c, 0x60, 0xf0,
+	0x3c, 0x66, 0xc3, 0xc3, 0x66, 0x3c, 0x31, 0x1e,
+	0xec, 0x72, 0x63, 0x63, 0x76, 0x6c, 0x66, 0xf1,
+	0x79, 0x86, 0x80, 0x7e, 0x07, 0x63, 0xc7, 0x7c,
+	0x01, 0x7f, 0xfe, 0x98, 0x58, 0x18, 0x18, 0x3c,
+	0xf7, 0x62, 0x62, 0x62, 0x62, 0x62, 0xf2, 0x3c,
+	0xf3, 0x61, 0x72, 0x72, 0x32, 0x32, 0x1c, 0x3e,
+	0xc3, 0x62, 0x62, 0x6a, 0x6e, 0x76, 0x66, 0xc3,
+	0xf3, 0x72, 0x3c, 0x38, 0x1c, 0x3c, 0x4e, 0xcf,
+	0xe3, 0x72, 0x34, 0x38, 0x18, 0x18, 0x18, 0x3c,
+	0x7f, 0x87, 0x0e, 0x1c, 0x38, 0x71, 0xfd, 0xe6,
+};
+
 Common::SeekableReadStream *CastleEngine::decryptFile(const Common::String filename) {
 	Common::File file;
 	file.open(filename);
@@ -160,6 +223,7 @@ void CastleEngine::loadAssetsDOSFullGame() {
 				error("Invalid or unsupported language: %x", _language);
 		}
 
+		loadFonts(kFreescapeCastleFont, 59);
 		loadMessagesVariableSize(stream, 0x11, 164);
 		delete stream;
 
@@ -238,12 +302,36 @@ void CastleEngine::gotoArea(uint16 areaID, int entranceID) {
 void CastleEngine::drawUI() {
 	_gfx->setViewport(_fullscreenViewArea);
 
+	uint32 color = 10;
+	uint8 r, g, b;
+
+	_gfx->readFromPalette(color, r, g, b);
+	uint32 front = _gfx->_texturePixelFormat.ARGBToColor(0xFF, r, g, b);
+
+	color = 0;
+
+	_gfx->readFromPalette(color, r, g, b);
+	uint32 back = _gfx->_texturePixelFormat.ARGBToColor(0xFF, r, g, b);
+
 	Graphics::Surface *surface = new Graphics::Surface();
 	surface->create(_screenW, _screenH, _gfx->_texturePixelFormat);
 	uint32 gray = _gfx->_texturePixelFormat.ARGBToColor(0x00, 0xA0, 0xA0, 0xA0);
 	surface->fillRect(_fullscreenViewArea, gray);
 	drawCrossair(surface);
 
+	Common::Rect backRect(97, 181, 232, 190);
+	surface->fillRect(backRect, back);
+
+	Common::String message;
+	int deadline;
+	getLatestMessages(message, deadline);
+	if (deadline <= _countdown) {
+		drawStringInSurface(message, 97, 182, front, back, surface);
+		_temporaryMessages.push_back(message);
+		_temporaryMessageDeadlines.push_back(deadline);
+	} else
+		drawStringInSurface(_currentArea->_name, 97, 182, front, back, surface);
+
 	if (!_uiTexture)
 		_uiTexture = _gfx->createTexture(surface);
 	else
@@ -257,6 +345,48 @@ void CastleEngine::drawUI() {
 	_gfx->setViewport(_viewArea);
 }
 
+void CastleEngine::initGameState() {
+	_flyMode = false;
+	_noClipMode = false;
+	_shootingFrames = 0;
+	_underFireFrames = 0;
+	_yaw = 0;
+	_pitch = 0;
+
+	for (int i = 0; i < k8bitMaxVariable; i++) // TODO: check maximum variable
+		_gameStateVars[i] = 0;
+
+	for (auto &it : _areaMap) {
+		it._value->resetArea();
+		_gameStateBits[it._key] = 0;
+	}
+
+	//_gameStateVars[k8bitVariableEnergy] = _initialFuel;
+	//_gameStateVars[k8bitVariableShield] = _initialShield;
+
+	_playerHeightNumber = 1;
+	_playerHeight = _playerHeights[_playerHeightNumber];
+	removeTimers();
+	startCountdown(_initialCountdown);
+	_lastMinute = 0;
+	_demoIndex = 0;
+	_demoEvents.clear();
+}
+
+void CastleEngine::executePrint(FCLInstruction &instruction) {
+	uint16 index = instruction._source;
+	_currentAreaMessages.clear();
+	if (index > 127) {
+		index = _messagesList.size() - (index - 254) - 2;
+		// TODO
+		//drawFullscreenMessage(_messagesList[index]);
+		return;
+	}
+	debugC(1, kFreescapeDebugCode, "Printing message %d: \"%s\"", index, _messagesList[index].c_str());
+	insertTemporaryMessage(_messagesList[index], _countdown - 3);
+}
+
+
 Common::Error CastleEngine::saveGameStreamExtended(Common::WriteStream *stream, bool isAutosave) {
 	return Common::kNoError;
 }
diff --git a/engines/freescape/loaders/8bitBinaryLoader.cpp b/engines/freescape/loaders/8bitBinaryLoader.cpp
index 61265e7c4f2..bf54bcab306 100644
--- a/engines/freescape/loaders/8bitBinaryLoader.cpp
+++ b/engines/freescape/loaders/8bitBinaryLoader.cpp
@@ -664,7 +664,8 @@ void FreescapeEngine::load8bitBinary(Common::SeekableReadStream *file, int offse
 			_initialCountdown = 359999; // 99:59:59
 	} else if (isDark())
 		_initialCountdown = 2 * 3600; // 02:00:00
-
+	else if (isCastle())
+		_initialCountdown = 1000000000;
 
 	if (isAmiga() || isAtariST())
 		file->seek(offset + 0x190);
@@ -734,6 +735,17 @@ void FreescapeEngine::loadBundledImages() {
 	}*/
 }
 
+void FreescapeEngine::loadFonts(byte *font, int charNumber) {
+	if (isDOS() || isSpectrum() || isCPC() || isC64()) {
+		_font.set_size(64 * charNumber);
+		_font.set_bits(font);
+	} else if (isAmiga() || isAtariST()) {
+		error("Not implemented yet");
+	}
+	_fontLoaded = true;
+}
+
+
 void FreescapeEngine::loadFonts(Common::SeekableReadStream *file, int offset) {
 	file->seek(offset);
 	int charNumber = 60;


Commit: 49f9ec8cd1c4fa623b48a483c55097aa675017fa
    https://github.com/scummvm/scummvm/commit/49f9ec8cd1c4fa623b48a483c55097aa675017fa
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2023-05-06T14:03:04+02:00

Commit Message:
FREESCAPE: refactored castle (DOS) to use drawDOSUI

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


diff --git a/engines/freescape/freescape.h b/engines/freescape/freescape.h
index 256c1d5338c..ff8d87ad6bf 100644
--- a/engines/freescape/freescape.h
+++ b/engines/freescape/freescape.h
@@ -570,7 +570,8 @@ public:
 	void initGameState() override;
 	void titleScreen() override;
 	void loadAssetsDOSFullGame() override;
-	void drawUI() override;
+
+	void drawDOSUI(Graphics::Surface *surface) override;
 
 	void executePrint(FCLInstruction &instruction) override;
 	void gotoArea(uint16 areaID, int entranceID) override;
diff --git a/engines/freescape/games/castle.cpp b/engines/freescape/games/castle.cpp
index 254db2de65b..173cb3c9c2a 100644
--- a/engines/freescape/games/castle.cpp
+++ b/engines/freescape/games/castle.cpp
@@ -299,9 +299,7 @@ void CastleEngine::gotoArea(uint16 areaID, int entranceID) {
 	resetInput();
 }
 
-void CastleEngine::drawUI() {
-	_gfx->setViewport(_fullscreenViewArea);
-
+void CastleEngine::drawDOSUI(Graphics::Surface *surface) {
 	uint32 color = 10;
 	uint8 r, g, b;
 
@@ -313,12 +311,6 @@ void CastleEngine::drawUI() {
 	_gfx->readFromPalette(color, r, g, b);
 	uint32 back = _gfx->_texturePixelFormat.ARGBToColor(0xFF, r, g, b);
 
-	Graphics::Surface *surface = new Graphics::Surface();
-	surface->create(_screenW, _screenH, _gfx->_texturePixelFormat);
-	uint32 gray = _gfx->_texturePixelFormat.ARGBToColor(0x00, 0xA0, 0xA0, 0xA0);
-	surface->fillRect(_fullscreenViewArea, gray);
-	drawCrossair(surface);
-
 	Common::Rect backRect(97, 181, 232, 190);
 	surface->fillRect(backRect, back);
 
@@ -331,18 +323,6 @@ void CastleEngine::drawUI() {
 		_temporaryMessageDeadlines.push_back(deadline);
 	} else
 		drawStringInSurface(_currentArea->_name, 97, 182, front, back, surface);
-
-	if (!_uiTexture)
-		_uiTexture = _gfx->createTexture(surface);
-	else
-		_uiTexture->update(surface);
-
-	_gfx->drawTexturedRect2D(_fullscreenViewArea, _fullscreenViewArea, _uiTexture);
-
-	surface->free();
-	delete surface;
-
-	_gfx->setViewport(_viewArea);
 }
 
 void CastleEngine::initGameState() {


Commit: 7b3bbd02861a4f40feb77e02fd0403b9592b824e
    https://github.com/scummvm/scummvm/commit/7b3bbd02861a4f40feb77e02fd0403b9592b824e
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2023-05-06T14:03:04+02:00

Commit Message:
FREESCAPE: initial support for castle demo (EGA)

Changed paths:
    engines/freescape/detection.cpp
    engines/freescape/freescape.h
    engines/freescape/games/castle.cpp
    engines/freescape/language/8bitDetokeniser.cpp
    engines/freescape/loaders/8bitBinaryLoader.cpp


diff --git a/engines/freescape/detection.cpp b/engines/freescape/detection.cpp
index 097a5e98d48..1ebd60ab679 100644
--- a/engines/freescape/detection.cpp
+++ b/engines/freescape/detection.cpp
@@ -335,6 +335,20 @@ static const ADGameDescription gameDescriptions[] = {
 		ADGF_UNSUPPORTED,
 		GUIO2(GUIO_NOMIDI, GAMEOPTION_AUTOMATIC_DRILLING)
 	},
+	{
+		"castlemaster",
+		"Demo",
+		{
+			{"CASTLE.EXE", 0, "cbcf475b2d993c831a34a5203d2643e1", 2022},
+			{"CMDC.EXE", 0, "278fd1a96c61db71d952af472164ac57", 56526},
+			{"CMDE.EXE", 0, "428555ba83bc64d69bc2f7cb385f04f2", 88590},
+			AD_LISTEND
+		},
+		Common::EN_ANY,
+		Common::kPlatformDOS,
+		ADGF_UNSTABLE | ADGF_DEMO,
+		GUIO1(GUIO_NOMIDI)
+	},
 	{
 		"castlemaster",
 		"",
diff --git a/engines/freescape/freescape.h b/engines/freescape/freescape.h
index ff8d87ad6bf..7f5a2711797 100644
--- a/engines/freescape/freescape.h
+++ b/engines/freescape/freescape.h
@@ -570,6 +570,7 @@ public:
 	void initGameState() override;
 	void titleScreen() override;
 	void loadAssetsDOSFullGame() override;
+	void loadAssetsDOSDemo() override;
 
 	void drawDOSUI(Graphics::Surface *surface) override;
 
diff --git a/engines/freescape/games/castle.cpp b/engines/freescape/games/castle.cpp
index 173cb3c9c2a..1e2dc7fef20 100644
--- a/engines/freescape/games/castle.cpp
+++ b/engines/freescape/games/castle.cpp
@@ -243,6 +243,46 @@ void CastleEngine::loadAssetsDOSFullGame() {
 	// load8bitBinary(file, 0x791a, 16);
 }
 
+void CastleEngine::loadAssetsDOSDemo() {
+	Common::File file;
+	Common::SeekableReadStream *stream = nullptr;
+
+	if (_renderMode == Common::kRenderEGA) {
+		_viewArea = Common::Rect(40, 33, 280, 152);
+
+		file.open("CMLE.DAT");
+		_title = load8bitBinImage(&file, 0x0);
+		_title->setPalette((byte *)&kCastleTitleDOSPalette, 0, 16);
+		file.close();
+
+		file.open("CMOE.DAT");
+		_option = load8bitBinImage(&file, 0x0);
+		_option->setPalette((byte *)&kCastleOptionDOSPalette, 0, 16);
+		file.close();
+
+		file.open("CME.DAT");
+		_border = load8bitBinImage(&file, 0x0);
+		_border->setPalette((byte *)&kCastleBorderDOSPalette, 0, 16);
+		file.close();
+
+		stream = decryptFile("CMLD"); // Only english
+
+		loadFonts(kFreescapeCastleFont, 59);
+		loadMessagesVariableSize(stream, 0x11, 164);
+		delete stream;
+
+		stream = decryptFile("CDEDF");
+		load8bitBinary(stream, 0, 16);
+		for (auto &it : _areaMap)
+			it._value->addStructure(_areaMap[255]);
+
+		_areaMap[2]->addFloor();
+		delete stream;
+	} else
+		error("Not implemented yet");
+}
+
+
 void CastleEngine::titleScreen() {
 	if (isAmiga() || isAtariST()) // These releases has their own screens
 		return;
diff --git a/engines/freescape/language/8bitDetokeniser.cpp b/engines/freescape/language/8bitDetokeniser.cpp
index 775140d972a..e74d4182fef 100644
--- a/engines/freescape/language/8bitDetokeniser.cpp
+++ b/engines/freescape/language/8bitDetokeniser.cpp
@@ -115,7 +115,7 @@ Common::String detokenise8bitCondition(Common::Array<uint8> &tokenisedCondition,
 		// check we have enough bytes left to read
 		if (opcode > 48) {
 			debugC(1, kFreescapeDebugParser, "%s", detokenisedStream.c_str());
-			if (opcode != 0x3f)
+			if (opcode != 0x3f && opcode != 0x3b)
 				error("ERROR: failed to read opcode: %x", opcode);
 			break;
 		}
diff --git a/engines/freescape/loaders/8bitBinaryLoader.cpp b/engines/freescape/loaders/8bitBinaryLoader.cpp
index bf54bcab306..21cb38ed360 100644
--- a/engines/freescape/loaders/8bitBinaryLoader.cpp
+++ b/engines/freescape/loaders/8bitBinaryLoader.cpp
@@ -553,7 +553,7 @@ void FreescapeEngine::load8bitBinary(Common::SeekableReadStream *file, int offse
 	debugC(1, kFreescapeDebugParser, "Number of areas: %d", numberOfAreas);
 
 	if (isDOS() && isCastle()) // Castle Master for DOS has an invalid number of areas
-		numberOfAreas = 104;
+		numberOfAreas = isDemo() ? 31 : 104;
 
 	uint32 dbSize = readField(file, 16);
 	debugC(1, kFreescapeDebugParser, "Database ends at %x", dbSize);


Commit: ad0a27c9d836e3f45249a19ab6f83ba5a1478d6d
    https://github.com/scummvm/scummvm/commit/ad0a27c9d836e3f45249a19ab6f83ba5a1478d6d
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2023-05-06T14:03:04+02:00

Commit Message:
FREESCAPE: expanded floor size

Changed paths:
    engines/freescape/area.cpp


diff --git a/engines/freescape/area.cpp b/engines/freescape/area.cpp
index 3039bc5c5e1..ac168712e88 100644
--- a/engines/freescape/area.cpp
+++ b/engines/freescape/area.cpp
@@ -341,8 +341,8 @@ void Area::addFloor() {
 		ObjectType::kCubeType,
 		id,
 		0,                             // flags
-		Math::Vector3d(0, -1, 0),      // Position
-		Math::Vector3d(4128, 1, 4128), // size
+		Math::Vector3d(-4128, -1, -4128),      // Position
+		Math::Vector3d(4128 * 4, 1, 4128 * 4), // size
 		gColors,
 		nullptr,
 		FCLInstructionVector());


Commit: 68c18f33e9a2f763f3838adbb1530e9d02910b23
    https://github.com/scummvm/scummvm/commit/68c18f33e9a2f763f3838adbb1530e9d02910b23
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2023-05-06T14:03:04+02:00

Commit Message:
FREESCAPE: initial detection of castle demo for amiga

Changed paths:
    engines/freescape/detection.cpp
    engines/freescape/freescape.h
    engines/freescape/games/castle.cpp
    engines/freescape/loaders/8bitBinaryLoader.cpp


diff --git a/engines/freescape/detection.cpp b/engines/freescape/detection.cpp
index 1ebd60ab679..01b3f1d2412 100644
--- a/engines/freescape/detection.cpp
+++ b/engines/freescape/detection.cpp
@@ -349,6 +349,33 @@ static const ADGameDescription gameDescriptions[] = {
 		ADGF_UNSTABLE | ADGF_DEMO,
 		GUIO1(GUIO_NOMIDI)
 	},
+	{
+		"castlemaster",
+		"Demo",
+		{
+			{"cm", 0, "936b6ca92be53f122bd904a3397137e2", 1552},
+			{"x", 0, "c8c811439da0cf8a193e35feb5b5c6dc", 353388},
+			AD_LISTEND
+		},
+		Common::EN_ANY,
+		Common::kPlatformAmiga,
+		ADGF_UNSTABLE | ADGF_DEMO,
+		GUIO1(GUIO_NOMIDI)
+	},
+	// Stampede Amiga, Issue 1, July 1990
+	{
+		"castlemaster",
+		"Demo",
+		{
+			{"cm", 0, "b7e713a0742fa09aa81c9606bbbba4af", 4068},
+			{"x", 0, "c8c811439da0cf8a193e35feb5b5c6dc", 353388},
+			AD_LISTEND
+		},
+		Common::EN_ANY,
+		Common::kPlatformAmiga,
+		ADGF_UNSTABLE | ADGF_DEMO,
+		GUIO1(GUIO_NOMIDI)
+	},
 	{
 		"castlemaster",
 		"",
diff --git a/engines/freescape/freescape.h b/engines/freescape/freescape.h
index 7f5a2711797..383586298c2 100644
--- a/engines/freescape/freescape.h
+++ b/engines/freescape/freescape.h
@@ -571,6 +571,7 @@ public:
 	void titleScreen() override;
 	void loadAssetsDOSFullGame() override;
 	void loadAssetsDOSDemo() override;
+	void loadAssetsAmigaDemo() override;
 
 	void drawDOSUI(Graphics::Surface *surface) override;
 
diff --git a/engines/freescape/games/castle.cpp b/engines/freescape/games/castle.cpp
index 1e2dc7fef20..4165ee42b2c 100644
--- a/engines/freescape/games/castle.cpp
+++ b/engines/freescape/games/castle.cpp
@@ -282,6 +282,34 @@ void CastleEngine::loadAssetsDOSDemo() {
 		error("Not implemented yet");
 }
 
+void CastleEngine::loadAssetsAmigaDemo() {
+	Common::File file;
+	file.open("x");
+	if (!file.isOpen())
+		error("Failed to open 'x' file");
+
+	loadMessagesVariableSize(&file, 0x8bb2, 164);
+	load8bitBinary(&file, 0x162a6, 16);
+	assert(0);
+	//loadPalettes(&file, 0x0);
+
+	//file.close();
+	//file.open("driller");
+	//if (!file.isOpen())
+	//	error("Failed to open 'driller' file");
+
+	//loadFonts(&file, 0xa30);
+	//loadMessagesFixedSize(&file, 0x3960, 14, 20);
+	//loadGlobalObjects(&file, 0x3716, 8);
+
+	file.close();
+	//file.open("soundfx");
+	//if (!file.isOpen())
+	//	error("Failed to open 'soundfx' executable for Amiga");
+
+	//loadSoundsFx(&file, 0, 25);
+}
+
 
 void CastleEngine::titleScreen() {
 	if (isAmiga() || isAtariST()) // These releases has their own screens
diff --git a/engines/freescape/loaders/8bitBinaryLoader.cpp b/engines/freescape/loaders/8bitBinaryLoader.cpp
index 21cb38ed360..3c35b3d3497 100644
--- a/engines/freescape/loaders/8bitBinaryLoader.cpp
+++ b/engines/freescape/loaders/8bitBinaryLoader.cpp
@@ -471,12 +471,12 @@ Area *FreescapeEngine::load8bitArea(Common::SeekableReadStream *file, uint16 nco
 			i++;
 		}
 	} else if (isCastle()) {
-		byte idx = file->readByte();
+		byte idx = readField(file, 8);
 		name = _messagesList[idx + 41];
-		extraColor[0] = file->readByte();
-		extraColor[1] = file->readByte();
-		extraColor[2] = file->readByte();
-		extraColor[3] = file->readByte();
+		extraColor[0] = readField(file, 8);
+		extraColor[1] = readField(file, 8);
+		extraColor[2] = readField(file, 8);
+		extraColor[3] = readField(file, 8);
 	}
 	debugC(1, kFreescapeDebugParser, "Area name: %s", name.c_str());
 


Commit: 94d557de15e46c8fcb8f795fadde82543cc9d408
    https://github.com/scummvm/scummvm/commit/94d557de15e46c8fcb8f795fadde82543cc9d408
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2023-05-06T14:03:04+02:00

Commit Message:
FREESCAPE: basic implementation of activation (only used in castle/crypt)

Changed paths:
    engines/freescape/freescape.cpp
    engines/freescape/freescape.h
    engines/freescape/language/instruction.cpp
    engines/freescape/movement.cpp


diff --git a/engines/freescape/freescape.cpp b/engines/freescape/freescape.cpp
index b0253e24604..841e33f3c00 100644
--- a/engines/freescape/freescape.cpp
+++ b/engines/freescape/freescape.cpp
@@ -515,6 +515,12 @@ void FreescapeEngine::processInput() {
 			}
 			break;
 
+		case Common::EVENT_RBUTTONDOWN:
+			if (_hasFallen || !isCastle())
+				break;
+			activate();
+			break;
+
 		default:
 			break;
 		}
diff --git a/engines/freescape/freescape.h b/engines/freescape/freescape.h
index 383586298c2..97b00b2d94e 100644
--- a/engines/freescape/freescape.h
+++ b/engines/freescape/freescape.h
@@ -241,6 +241,7 @@ public:
 	float _lastFrame;
 
 	// Interaction
+	void activate();
 	void shoot();
 	void traverseEntrance(uint16 entranceID);
 
@@ -277,9 +278,9 @@ public:
 	bool checkCollisions(bool executeCode);
 	Math::Vector3d _objExecutingCodeSize;
 	virtual void executeMovementConditions();
-	void executeObjectConditions(GeometricObject *obj, bool shot, bool collided);
+	void executeObjectConditions(GeometricObject *obj, bool shot, bool collided, bool activated);
 	void executeLocalGlobalConditions(bool shot, bool collided, bool timer);
-	void executeCode(FCLInstructionVector &code, bool shot, bool collided, bool timer);
+	void executeCode(FCLInstructionVector &code, bool shot, bool collided, bool timer, bool activated);
 
 	// Instructions
 	bool checkConditional(FCLInstruction &instruction, bool shot, bool collided, bool timer, bool activated);
diff --git a/engines/freescape/language/instruction.cpp b/engines/freescape/language/instruction.cpp
index da9ed9ba5d4..beb817e9841 100644
--- a/engines/freescape/language/instruction.cpp
+++ b/engines/freescape/language/instruction.cpp
@@ -89,7 +89,7 @@ Token::Type FCLInstruction::getType() {
 	return _type;
 }
 
-void FreescapeEngine::executeObjectConditions(GeometricObject *obj, bool shot, bool collided) {
+void FreescapeEngine::executeObjectConditions(GeometricObject *obj, bool shot, bool collided, bool activated) {
 	assert(obj != nullptr);
 	if (!obj->_conditionSource.empty()) {
 		_firstSound = true;
@@ -98,9 +98,11 @@ void FreescapeEngine::executeObjectConditions(GeometricObject *obj, bool shot, b
 			debugC(1, kFreescapeDebugCode, "Executing with collision flag: %s", obj->_conditionSource.c_str());
 		else if (shot)
 			debugC(1, kFreescapeDebugCode, "Executing with shot flag: %s", obj->_conditionSource.c_str());
+		else if (activated)
+			debugC(1, kFreescapeDebugCode, "Executing with activated flag: %s", obj->_conditionSource.c_str());
 		else
 			error("Neither shot or collided flag is set!");
-		executeCode(obj->_condition, shot, collided, false); // TODO: check this last parameter
+		executeCode(obj->_condition, shot, collided, false, activated); // TODO: check this last parameter
 	}
 }
 
@@ -113,17 +115,17 @@ void FreescapeEngine::executeLocalGlobalConditions(bool shot, bool collided, boo
 
 	for (uint i = 0; i < conditions.size(); i++) {
 		debugC(1, kFreescapeDebugCode, "%s", conditionSources[i].c_str());
-		executeCode(conditions[i], shot, collided, timer);
+		executeCode(conditions[i], shot, collided, timer, false);
 	}
 
 	debugC(1, kFreescapeDebugCode, "Executing global conditions (%d)", _conditions.size());
 	for (uint i = 0; i < _conditions.size(); i++) {
 		debugC(1, kFreescapeDebugCode, "%s", _conditionSources[i].c_str());
-		executeCode(_conditions[i], shot, collided, timer);
+		executeCode(_conditions[i], shot, collided, timer, false);
 	}
 }
 
-void FreescapeEngine::executeCode(FCLInstructionVector &code, bool shot, bool collided, bool timer) {
+void FreescapeEngine::executeCode(FCLInstructionVector &code, bool shot, bool collided, bool timer, bool activated) {
 	assert(!(shot && collided));
 	int ip = 0;
 	bool skip = false;
@@ -149,8 +151,8 @@ void FreescapeEngine::executeCode(FCLInstructionVector &code, bool shot, bool co
 			break;
 
 		case Token::CONDITIONAL:
-			if (checkConditional(instruction, shot, collided, timer, false)) // TODO: implement interaction
-				executeCode(*instruction._thenInstructions, shot, collided, timer);
+			if (checkConditional(instruction, shot, collided, timer, activated))
+				executeCode(*instruction._thenInstructions, shot, collided, timer, activated);
 			// else branch is always empty
 			assert(instruction._elseInstructions == nullptr);
 			break;
diff --git a/engines/freescape/movement.cpp b/engines/freescape/movement.cpp
index aa432f1e3ee..7d89bafe446 100644
--- a/engines/freescape/movement.cpp
+++ b/engines/freescape/movement.cpp
@@ -69,6 +69,29 @@ void FreescapeEngine::traverseEntrance(uint16 entranceID) {
 	_sensors = _currentArea->getSensors();
 }
 
+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;
+
+	Math::Vector3d direction = directionToVector(_pitch - yoffset, _yaw - xoffset);
+	Math::Ray ray(_position, direction);
+	Object *interacted = _currentArea->shootRay(ray);
+	if (interacted) {
+		GeometricObject *gobj = (GeometricObject *)interacted;
+		debugC(1, kFreescapeDebugMove, "Interact with object %d with flags %x", gobj->getObjectID(), gobj->getObjectFlags());
+
+		if (!gobj->_conditionSource.empty())
+			debugC(1, kFreescapeDebugMove, "Must use interact = true when executing: %s", gobj->_conditionSource.c_str());
+
+		executeObjectConditions(gobj, false, false, true);
+	}
+	//executeLocalGlobalConditions(true, false, false); // Only execute "on shot" room/global conditions
+}
+
+
 void FreescapeEngine::shoot() {
 	playSound(1, false);
 	g_system->delayMillis(2);
@@ -90,7 +113,7 @@ void FreescapeEngine::shoot() {
 		if (!gobj->_conditionSource.empty())
 			debugC(1, kFreescapeDebugMove, "Must use shot = true when executing: %s", gobj->_conditionSource.c_str());
 
-		executeObjectConditions(gobj, true, false);
+		executeObjectConditions(gobj, true, false, false);
 	}
 	executeLocalGlobalConditions(true, false, false); // Only execute "on shot" room/global conditions
 }
@@ -375,7 +398,7 @@ bool FreescapeEngine::checkCollisions(bool executeCode) {
 			largeObjectWasBlocking = true;
 		}
 
-		executeObjectConditions(gobj, false, true);
+		executeObjectConditions(gobj, false, true, false);
 
 		if (areaID != _currentArea->getAreaID())
 			break;


Commit: 0589fe091250cafccda8f9eaaf935ed678a04daf
    https://github.com/scummvm/scummvm/commit/0589fe091250cafccda8f9eaaf935ed678a04daf
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2023-05-06T14:03:04+02:00

Commit Message:
MATH: added generic collision code for AABB class

Changed paths:
    engines/freescape/objects/geometricobject.cpp
    math/aabb.cpp
    math/aabb.h


diff --git a/engines/freescape/objects/geometricobject.cpp b/engines/freescape/objects/geometricobject.cpp
index 954f67755fb..ff74a5a3798 100644
--- a/engines/freescape/objects/geometricobject.cpp
+++ b/engines/freescape/objects/geometricobject.cpp
@@ -367,12 +367,7 @@ bool GeometricObject::collides(const Math::AABB &boundingBox_) {
 	if (isDestroyed() || isInvisible() || !_boundingBox.isValid() || !boundingBox_.isValid())
 		return false;
 
-	return (_boundingBox.getMax().x() > boundingBox_.getMin().x() &&
-			_boundingBox.getMin().x() < boundingBox_.getMax().x() &&
-			_boundingBox.getMax().y() > boundingBox_.getMin().y() &&
-			_boundingBox.getMin().y() < boundingBox_.getMax().y() &&
-			_boundingBox.getMax().z() > boundingBox_.getMin().z() &&
-			_boundingBox.getMin().z() < boundingBox_.getMax().z());
+	return _boundingBox.collides(boundingBox_);
 }
 
 void GeometricObject::draw(Freescape::Renderer *gfx) {
diff --git a/math/aabb.cpp b/math/aabb.cpp
index 8207051977c..01a22510042 100644
--- a/math/aabb.cpp
+++ b/math/aabb.cpp
@@ -77,4 +77,13 @@ void AABB::transform(const Math::Matrix4 &matrix) {
 	}
 }
 
+bool AABB::collides(const AABB &aabb) {
+	return (getMax().x() > aabb.getMin().x() &&
+			getMin().x() < aabb.getMax().x() &&
+			getMax().y() > aabb.getMin().y() &&
+			getMin().y() < aabb.getMax().y() &&
+			getMax().z() > aabb.getMin().z() &&
+			getMin().z() < aabb.getMax().z());
+}
+
 }
diff --git a/math/aabb.h b/math/aabb.h
index c28706bd239..8c80e12ef72 100644
--- a/math/aabb.h
+++ b/math/aabb.h
@@ -39,6 +39,7 @@ public:
 	Math::Vector3d getMin() const { return _min; }
 	Math::Vector3d getMax() const { return _max; }
 	bool isValid() const { return _valid; }
+	bool collides(const AABB &aabb);
 
 private:
 	Math::Vector3d _min, _max;




More information about the Scummvm-git-logs mailing list