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

neuromancer noreply at scummvm.org
Sun Feb 5 17:15:00 UTC 2023


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

Summary:
0f9f46a550 FREESCAPE: refactor to use executeMovementConditions instead of executeLocalGlobalConditions directly
8501ccc9c0 FREESCAPE: read strings from dark EGA releases (and demo)
4e59cf8f8c FREESCAPE: refactor game bits handling and set bit 31 when colliding
7797331c95 FREESCAPE: improve dark UI for dos release and demo
b67cf12349 FREESCAPE: implemented area connections in dark


Commit: 0f9f46a55082e7445ab63d58073d47536399e69b
    https://github.com/scummvm/scummvm/commit/0f9f46a55082e7445ab63d58073d47536399e69b
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2023-02-05T18:11:59+01:00

Commit Message:
FREESCAPE: refactor to use executeMovementConditions instead of executeLocalGlobalConditions directly

Changed paths:
    engines/freescape/freescape.cpp
    engines/freescape/freescape.h
    engines/freescape/games/dark.cpp
    engines/freescape/movement.cpp


diff --git a/engines/freescape/freescape.cpp b/engines/freescape/freescape.cpp
index d91f73ddc3c..9c56b05a237 100644
--- a/engines/freescape/freescape.cpp
+++ b/engines/freescape/freescape.cpp
@@ -498,6 +498,11 @@ void FreescapeEngine::processInput() {
 	}
 }
 
+void FreescapeEngine::executeMovementConditions() {
+	// Only execute "on collision" room/global conditions
+	executeLocalGlobalConditions(false, true);
+}
+
 void FreescapeEngine::updateTimeVariables() {
 	int seconds, minutes, hours;
 	getTimeFromCountdown(seconds, minutes, hours);
diff --git a/engines/freescape/freescape.h b/engines/freescape/freescape.h
index b4641f73912..5747f2825aa 100644
--- a/engines/freescape/freescape.h
+++ b/engines/freescape/freescape.h
@@ -237,6 +237,7 @@ public:
 
 	bool checkCollisions(bool executeCode);
 	Math::Vector3d _objExecutingCodeSize;
+	virtual void executeMovementConditions();
 	void executeObjectConditions(GeometricObject *obj, bool shot, bool collided);
 	void executeLocalGlobalConditions(bool shot, bool collided);
 	void executeCode(FCLInstructionVector &code, bool shot, bool collided);
@@ -356,7 +357,7 @@ public:
 	int _lastMinute;
 
 	void getTimeFromCountdown(int &seconds, int &minutes, int &hours);
-	void updateTimeVariables();
+	virtual void updateTimeVariables();
 
 	// Cheats
 	bool _useExtendedTimer;
@@ -438,11 +439,16 @@ public:
 	DarkEngine(OSystem *syst, const ADGameDescription *gd);
 
 	void loadAssets() override;
+	void initGameState() override;
+
 	void gotoArea(uint16 areaID, int entranceID) override;
 	void pressedKey(const int keycode) override;
 
 	void loadAssetsDemo();
 	void loadAssetsFullGame();
+	int _lastTenSeconds;
+	void updateTimeVariables() override;
+	void executeMovementConditions() override;
 
 	void drawUI() override;
 	Common::Error saveGameStreamExtended(Common::WriteStream *stream, bool isAutosave = false) override;
diff --git a/engines/freescape/games/dark.cpp b/engines/freescape/games/dark.cpp
index cf338790f29..55d33f0bead 100644
--- a/engines/freescape/games/dark.cpp
+++ b/engines/freescape/games/dark.cpp
@@ -35,6 +35,7 @@ DarkEngine::DarkEngine(OSystem *syst, const ADGameDescription *gd) : FreescapeEn
 	_playerHeight = _playerHeights[_playerHeightNumber];
 	_playerWidth = 12;
 	_playerDepth = 32;
+	_lastTenSeconds = -1;
 }
 
 void DarkEngine::loadAssets() {
@@ -67,6 +68,31 @@ void DarkEngine::loadAssetsDemo() {
 		error("Invalid or unsupported render mode %s for Dark Side", Common::getRenderModeDescription(_renderMode));
 }
 
+void DarkEngine::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;
+	}
+
+	_playerHeightNumber = 1;
+	_playerHeight = _playerHeights[_playerHeightNumber];
+	removeTimers();
+	startCountdown(_initialCountdown);
+	_lastMinute = 0;
+	_demoIndex = 0;
+	_demoEvents.clear();
+}
+
 void DarkEngine::loadAssetsFullGame() {
 	Common::File file;
 	if (_renderMode == Common::kRenderEGA) {
@@ -155,6 +181,30 @@ void DarkEngine::pressedKey(const int keycode) {
 	}
 }
 
+void DarkEngine::executeMovementConditions() {
+	// Only execute "on collision" room/global conditions
+	if (_currentArea->getAreaFlags() == 1)
+		executeLocalGlobalConditions(false, true);
+}
+
+void DarkEngine::updateTimeVariables() {
+	// This function only executes "on collision" room/global conditions
+	int seconds, minutes, hours;
+	getTimeFromCountdown(seconds, minutes, hours);
+	if (_lastTenSeconds != seconds / 10) {
+		_lastTenSeconds = seconds / 10;
+		if (_currentArea->getAreaFlags() == 0)
+			executeLocalGlobalConditions(false, true);
+	}
+
+	if (_lastMinute != minutes) {
+		_lastMinute = minutes;
+		_gameStateVars[0x1e] += 1;
+		_gameStateVars[0x1f] += 1;
+		executeLocalGlobalConditions(false, true);
+	}
+}
+
 void DarkEngine::drawUI() {
 	uint32 gray = _gfx->_texturePixelFormat.ARGBToColor(0x00, 0xA0, 0xA0, 0xA0);
 	uint32 yellow = _gfx->_texturePixelFormat.ARGBToColor(0xFF, 0xFF, 0xFF, 0x55);
diff --git a/engines/freescape/movement.cpp b/engines/freescape/movement.cpp
index d3db2059aaf..69f7c3b1561 100644
--- a/engines/freescape/movement.cpp
+++ b/engines/freescape/movement.cpp
@@ -149,7 +149,7 @@ void FreescapeEngine::rise() {
 
 	_lastPosition = _position;
 	debugC(1, kFreescapeDebugMove, "new player position: %f, %f, %f", _position.x(), _position.y(), _position.z());
-	executeLocalGlobalConditions(false, true); // Only execute "on collision" room/global conditions
+	executeMovementConditions();
 }
 
 void FreescapeEngine::lower() {
@@ -174,7 +174,7 @@ void FreescapeEngine::lower() {
 
 	_lastPosition = _position;
 	debugC(1, kFreescapeDebugMove, "new player position: %f, %f, %f", _position.x(), _position.y(), _position.z());
-	executeLocalGlobalConditions(false, true); // Only execute "on collision" room/global conditions
+	executeMovementConditions();
 }
 
 void FreescapeEngine::move(CameraMovement direction, uint8 scale, float deltaTime) {
@@ -267,7 +267,7 @@ void FreescapeEngine::move(CameraMovement direction, uint8 scale, float deltaTim
 	debugC(1, kFreescapeDebugMove, "new player position: %f, %f, %f", _position.x(), _position.y(), _position.z());
 	//debugC(1, kFreescapeDebugMove, "player height: %f", _position.y() - areaScale * _playerHeight);
 	if (_currentArea->getAreaID() == previousAreaID)
-		executeLocalGlobalConditions(false, true); // Only execute "on collision" room/global conditions
+		executeMovementConditions();
 }
 
 bool FreescapeEngine::checkFloor(Math::Vector3d currentPosition) {


Commit: 8501ccc9c086143f9b4676ee3900966d907c735c
    https://github.com/scummvm/scummvm/commit/8501ccc9c086143f9b4676ee3900966d907c735c
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2023-02-05T18:11:59+01:00

Commit Message:
FREESCAPE: read strings from dark EGA releases (and demo)

Changed paths:
    engines/freescape/games/dark.cpp


diff --git a/engines/freescape/games/dark.cpp b/engines/freescape/games/dark.cpp
index 55d33f0bead..70307ccc113 100644
--- a/engines/freescape/games/dark.cpp
+++ b/engines/freescape/games/dark.cpp
@@ -53,7 +53,7 @@ void DarkEngine::loadAssetsDemo() {
 
 		if (!file.isOpen())
 			error("Failed to open DSIDEE.EXE");
-
+		loadMessagesFixedSize(&file, 0x4525, 16, 27);
 		loadFonts(&file, 0xa598);
 		load8bitBinary(&file, 0xa700, 16);
 	} else if (isDOS() && _renderMode == Common::kRenderCGA) {
@@ -103,6 +103,7 @@ void DarkEngine::loadAssetsFullGame() {
 			error("Failed to open DSIDEE.EXE");
 
 		loadFonts(&file, 0xa113);
+		loadMessagesFixedSize(&file, 0x4525, 16, 27);
 		load8bitBinary(&file, 0xa280, 16);
 	} else if (_renderMode == Common::kRenderCGA) {
 		loadBundledImages();


Commit: 4e59cf8f8c6c54cef3b5a5b89aeb80b40b49a9c6
    https://github.com/scummvm/scummvm/commit/4e59cf8f8c6c54cef3b5a5b89aeb80b40b49a9c6
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2023-02-05T18:11:59+01:00

Commit Message:
FREESCAPE: refactor game bits handling and set bit 31 when colliding

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 9c56b05a237..6481d0dc7ff 100644
--- a/engines/freescape/freescape.cpp
+++ b/engines/freescape/freescape.cpp
@@ -626,6 +626,19 @@ bool FreescapeEngine::checkIfGameEnded() {
 	return false; // TODO
 }
 
+void FreescapeEngine::setGameBit(int index) {
+	_gameStateBits[_currentArea->getAreaID()] |= (1 << (index - 1));
+}
+
+void FreescapeEngine::clearGameBit(int index) {
+	_gameStateBits[_currentArea->getAreaID()] &= ~(1 << (index - 1));
+}
+
+void FreescapeEngine::toggleGameBit(int index) {
+	_gameStateBits[_currentArea->getAreaID()] ^= (1 << (index - 1));
+}
+
+
 void FreescapeEngine::initGameState() {
 	for (int i = 0; i < k8bitMaxVariable; i++) // TODO: check maximum variable
 		_gameStateVars[i] = 0;
diff --git a/engines/freescape/freescape.h b/engines/freescape/freescape.h
index 5747f2825aa..8403333de22 100644
--- a/engines/freescape/freescape.h
+++ b/engines/freescape/freescape.h
@@ -325,6 +325,10 @@ public:
 
 	// Game state
 	virtual void initGameState();
+	void setGameBit(int index);
+	void clearGameBit(int index);
+	void toggleGameBit(int index);
+
 	StateVars _gameStateVars;
 	StateBits _gameStateBits;
 	virtual bool checkIfGameEnded();
diff --git a/engines/freescape/language/instruction.cpp b/engines/freescape/language/instruction.cpp
index ef9e656ffa9..3389ca99493 100644
--- a/engines/freescape/language/instruction.cpp
+++ b/engines/freescape/language/instruction.cpp
@@ -446,23 +446,23 @@ void FreescapeEngine::executeGoto(FCLInstruction &instruction) {
 }
 
 void FreescapeEngine::executeSetBit(FCLInstruction &instruction) {
-	uint16 index = instruction._source - 1; // Starts in 1
-	assert(index < 32);
-	_gameStateBits[_currentArea->getAreaID()] |= (1 << index);
+	uint16 index = instruction._source; // Starts at 1
+	assert(index > 0 && index <= 32);
+	setGameBit(index);
 	debugC(1, kFreescapeDebugCode, "Setting bit %d", index);
-	// debug("v: %d", (_gameStateBits[_currentArea->getAreaID()] & (1 << index)));
 }
 
 void FreescapeEngine::executeClearBit(FCLInstruction &instruction) {
-	uint16 index = instruction._source - 1; // Starts in 1
-	assert(index < 32);
-	_gameStateBits[_currentArea->getAreaID()] &= ~(1 << index);
+	uint16 index = instruction._source; // Starts at 1
+	assert(index > 0 && index <= 32);
+	clearGameBit(index);
 	debugC(1, kFreescapeDebugCode, "Clearing bit %d", index);
 }
 
 void FreescapeEngine::executeToggleBit(FCLInstruction &instruction) {
-	uint16 index = instruction._source - 1; // Starts in 1
-	_gameStateBits[_currentArea->getAreaID()] ^= (1 << index);
+	uint16 index = instruction._source; // Starts at 1
+	assert(index > 0 && index <= 32);
+	toggleGameBit(index);
 	debugC(1, kFreescapeDebugCode, "Toggling bit %d", index);
 }
 
diff --git a/engines/freescape/movement.cpp b/engines/freescape/movement.cpp
index 69f7c3b1561..35e537ff8d2 100644
--- a/engines/freescape/movement.cpp
+++ b/engines/freescape/movement.cpp
@@ -239,10 +239,12 @@ void FreescapeEngine::move(CameraMovement direction, uint8 scale, float deltaTim
 				playSound(3, false);
 		}
 		debugC(1, kFreescapeDebugCode, "Runing effects:");
+		if (_flyMode)
+			setGameBit(31);
 		checkCollisions(true); // run the effects
 	} else {
 		debugC(1, kFreescapeDebugCode, "Runing effects: at: %f, %f, %f", _position.x(), _position.y(), _position.z());
-
+		setGameBit(31);
 		checkCollisions(true); // run the effects
 		if (_currentArea->getAreaID() == previousAreaID) {
 			if (_flyMode)
@@ -268,6 +270,7 @@ void FreescapeEngine::move(CameraMovement direction, uint8 scale, float deltaTim
 	//debugC(1, kFreescapeDebugMove, "player height: %f", _position.y() - areaScale * _playerHeight);
 	if (_currentArea->getAreaID() == previousAreaID)
 		executeMovementConditions();
+	clearGameBit(31);
 }
 
 bool FreescapeEngine::checkFloor(Math::Vector3d currentPosition) {


Commit: 7797331c955ff413a5239a71e818c5ecdaba6c40
    https://github.com/scummvm/scummvm/commit/7797331c955ff413a5239a71e818c5ecdaba6c40
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2023-02-05T18:11:59+01:00

Commit Message:
FREESCAPE: improve dark UI for dos release and demo

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


diff --git a/engines/freescape/freescape.h b/engines/freescape/freescape.h
index 8403333de22..1ac2e84d572 100644
--- a/engines/freescape/freescape.h
+++ b/engines/freescape/freescape.h
@@ -442,6 +442,9 @@ class DarkEngine : public FreescapeEngine {
 public:
 	DarkEngine(OSystem *syst, const ADGameDescription *gd);
 
+	uint32 _initialFuel;
+	uint32 _initialShield;
+
 	void loadAssets() override;
 	void initGameState() override;
 
@@ -455,6 +458,7 @@ public:
 	void executeMovementConditions() override;
 
 	void drawUI() override;
+	void drawDOSUI(Graphics::Surface *surface);
 	Common::Error saveGameStreamExtended(Common::WriteStream *stream, bool isAutosave = false) override;
 	Common::Error loadGameStreamExtended(Common::SeekableReadStream *stream) override;
 };
diff --git a/engines/freescape/games/dark.cpp b/engines/freescape/games/dark.cpp
index 70307ccc113..55dfb12d2a8 100644
--- a/engines/freescape/games/dark.cpp
+++ b/engines/freescape/games/dark.cpp
@@ -36,6 +36,16 @@ DarkEngine::DarkEngine(OSystem *syst, const ADGameDescription *gd) : FreescapeEn
 	_playerWidth = 12;
 	_playerDepth = 32;
 	_lastTenSeconds = -1;
+
+	_angleRotations.push_back(5);
+	_angleRotations.push_back(10);
+	_angleRotations.push_back(15);
+	_angleRotations.push_back(30);
+	_angleRotations.push_back(45);
+	_angleRotations.push_back(90);
+
+	_initialFuel = 11;
+	_initialShield = 15;
 }
 
 void DarkEngine::loadAssets() {
@@ -84,6 +94,9 @@ void DarkEngine::initGameState() {
 		_gameStateBits[it._key] = 0;
 	}
 
+	_gameStateVars[k8bitVariableEnergy] = _initialFuel;
+	_gameStateVars[k8bitVariableShield] = _initialShield;
+
 	_playerHeightNumber = 1;
 	_playerHeight = _playerHeights[_playerHeightNumber];
 	removeTimers();
@@ -206,13 +219,73 @@ void DarkEngine::updateTimeVariables() {
 	}
 }
 
-void DarkEngine::drawUI() {
-	uint32 gray = _gfx->_texturePixelFormat.ARGBToColor(0x00, 0xA0, 0xA0, 0xA0);
-	uint32 yellow = _gfx->_texturePixelFormat.ARGBToColor(0xFF, 0xFF, 0xFF, 0x55);
-	uint32 black = _gfx->_texturePixelFormat.ARGBToColor(0xFF, 0x00, 0x00, 0x00);
+void DarkEngine::drawDOSUI(Graphics::Surface *surface) {
+	uint32 color = _renderMode == Common::kRenderCGA ? 1 : 14;
+	uint8 r, g, b;
+
+	_gfx->readFromPalette(color, r, g, b);
+	uint32 front = _gfx->_texturePixelFormat.ARGBToColor(0xFF, r, g, b);
+
+	color = _currentArea->_usualBackgroundColor;
+	if (_gfx->_colorRemaps && _gfx->_colorRemaps->contains(color)) {
+		color = (*_gfx->_colorRemaps)[color];
+	}
+
+	_gfx->readFromPalette(color, r, g, b);
+	uint32 back = _gfx->_texturePixelFormat.ARGBToColor(0xFF, r, g, b);
+
+	int score = _gameStateVars[k8bitVariableScore];
+	drawStringInSurface(Common::String::format("%04d", int(2 * _position.x())), 199, 137, front, back, surface);
+	drawStringInSurface(Common::String::format("%04d", int(2 * _position.z())), 199, 145, front, back, surface);
+	drawStringInSurface(Common::String::format("%04d", int(2 * _position.y())), 199, 153, front, back, surface);
+
+	drawStringInSurface(Common::String::format("%02d", int(_angleRotations[_angleRotationIndex])), 71, 168, front, back, surface);
+	drawStringInSurface(Common::String::format("%3d", _playerSteps[_playerStepIndex]), 71, 177, front, back, surface);
+	drawStringInSurface(Common::String::format("%07d", score), 95, 8, front, back, surface);
+
+	int seconds, minutes, hours;
+	getTimeFromCountdown(seconds, minutes, hours);
+	// TODO: implement binary clock
+
+	Common::String message;
+	int deadline;
+	getLatestMessages(message, deadline);
+	if (deadline <= _countdown) {
+		drawStringInSurface(message, 112, 177, back, front, surface);
+		_temporaryMessages.push_back(message);
+		_temporaryMessageDeadlines.push_back(deadline);
+	} else
+		drawStringInSurface(_currentArea->_name, 112, 177, front, back, surface);
+
+	int energy = _gameStateVars[k8bitVariableEnergy]; // called fuel in this game
+	int shield = _gameStateVars[k8bitVariableShield];
+
+	_gfx->readFromPalette(9, r, g, b);
+	uint32 blue = _gfx->_texturePixelFormat.ARGBToColor(0xFF, r, g, b);
+
+	if (shield >= 0) {
+		Common::Rect shieldBar;
+		shieldBar = Common::Rect(72, 139, 151 - (k8bitMaxShield - shield), 146);
+		surface->fillRect(shieldBar, front);
+
+		shieldBar = Common::Rect(72, 140, 151 - (k8bitMaxShield - shield), 145);
+		surface->fillRect(shieldBar, blue);
+	}
+
+	if (energy >= 0) {
+		Common::Rect energyBar;
+		energyBar = Common::Rect(72, 147, 151 - (k8bitMaxEnergy - energy), 154);
+		surface->fillRect(energyBar, front);
 
+		energyBar = Common::Rect(72, 148, 151 - (k8bitMaxEnergy - energy), 153);
+		surface->fillRect(energyBar, blue);
+	}
+}
+
+void DarkEngine::drawUI() {
 	Graphics::Surface *surface = nullptr;
-	if (_border) {
+	if (_border) { // This can be removed when all the borders are loaded
+		uint32 gray = _gfx->_texturePixelFormat.ARGBToColor(0x00, 0xA0, 0xA0, 0xA0);
 		surface = new Graphics::Surface();
 		surface->create(_screenW, _screenH, _gfx->_texturePixelFormat);
 		surface->fillRect(_fullscreenViewArea, gray);
@@ -220,14 +293,10 @@ void DarkEngine::drawUI() {
 	} else
 		return;
 
-	if (_currentAreaMessages.size() == 1) {
-		int score = _gameStateVars[k8bitVariableScore];
-		drawStringInSurface(_currentAreaMessages[0], 112, 177, yellow, black, surface);
-		drawStringInSurface(Common::String::format("%04d", 2 * int(_position.x())), 199, 137, yellow, black, surface);
-		drawStringInSurface(Common::String::format("%04d", 2 * int(_position.z())), 199, 145, yellow, black, surface);
-		drawStringInSurface(Common::String::format("%04d", 2 * int(_position.y())), 199, 153, yellow, black, surface);
-		drawStringInSurface(Common::String::format("%07d", score), 95, 8, yellow, black, surface);
-	}
+	if (isDOS())
+		drawDOSUI(surface);
+	else
+		error("UI not implemented yet");
 
 	if (!_uiTexture)
 		_uiTexture = _gfx->createTexture(surface);
diff --git a/engines/freescape/loaders/8bitBinaryLoader.cpp b/engines/freescape/loaders/8bitBinaryLoader.cpp
index ff395a1a2ce..80a5e6b6fbb 100644
--- a/engines/freescape/loaders/8bitBinaryLoader.cpp
+++ b/engines/freescape/loaders/8bitBinaryLoader.cpp
@@ -438,6 +438,15 @@ void FreescapeEngine::load8bitBinary(Common::SeekableReadStream *file, int offse
 	debugC(1, kFreescapeDebugParser, "Start area: %d", startArea);
 	uint8 startEntrance = readField(file, 8);
 	debugC(1, kFreescapeDebugParser, "Entrace area: %d", startEntrance);
+	readField(file, 8); // Unknown
+
+	uint8 initialEnergy1 = readField(file, 8);
+	uint8 initialShield1 = readField(file, 8);
+	uint8 initialEnergy2 = readField(file, 8);
+	uint8 initialShield2 = readField(file, 8);
+
+	debugC(1, kFreescapeDebugParser, "Initial levels of energy: %d and shield: %d", initialEnergy1, initialShield1);
+	debugC(1, kFreescapeDebugParser, "Initial levels of energy: %d and shield: %d", initialEnergy2, initialShield2);
 
 	if (isAmiga() || isAtariST())
 		file->seek(offset + 0x14);


Commit: b67cf1234929c07e4224a5ac19ab955cfd0f81e4
    https://github.com/scummvm/scummvm/commit/b67cf1234929c07e4224a5ac19ab955cfd0f81e4
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2023-02-05T18:11:59+01:00

Commit Message:
FREESCAPE: implemented area connections in dark

Changed paths:
  A engines/freescape/objects/connections.h
    engines/freescape/freescape.h
    engines/freescape/games/dark.cpp
    engines/freescape/loaders/8bitBinaryLoader.cpp
    engines/freescape/movement.cpp


diff --git a/engines/freescape/freescape.h b/engines/freescape/freescape.h
index 1ac2e84d572..a7ec3096b61 100644
--- a/engines/freescape/freescape.h
+++ b/engines/freescape/freescape.h
@@ -187,6 +187,7 @@ public:
 	void generateDemoInput();
 	virtual void pressedKey(const int keycode);
 	void move(CameraMovement direction, uint8 scale, float deltaTime);
+	virtual void checkIfStillInArea();
 	void changePlayerHeight(int index);
 	void increaseStepSize();
 	void decreaseStepSize();
@@ -449,6 +450,7 @@ public:
 	void initGameState() override;
 
 	void gotoArea(uint16 areaID, int entranceID) override;
+	void checkIfStillInArea() override;
 	void pressedKey(const int keycode) override;
 
 	void loadAssetsDemo();
diff --git a/engines/freescape/games/dark.cpp b/engines/freescape/games/dark.cpp
index 55dfb12d2a8..60e1b86bfd0 100644
--- a/engines/freescape/games/dark.cpp
+++ b/engines/freescape/games/dark.cpp
@@ -23,6 +23,7 @@
 
 #include "freescape/freescape.h"
 #include "freescape/language/8bitDetokeniser.h"
+#include "freescape/objects/connections.h"
 
 namespace Freescape {
 
@@ -195,6 +196,30 @@ void DarkEngine::pressedKey(const int keycode) {
 	}
 }
 
+void DarkEngine::checkIfStillInArea() {
+	AreaConnections *cons = (AreaConnections *)_currentArea->entranceWithID(254);
+	if (!cons) {
+		FreescapeEngine::checkIfStillInArea();
+		return;
+	}
+
+	int nextAreaID = 0;
+
+	if (_position.z() >= 4064 - 16)
+		nextAreaID = cons->_connections[1];
+	else if (_position.x() >= 4064 - 16)
+		nextAreaID = cons->_connections[3];
+	else if (_position.z() <= 16)
+		nextAreaID = cons->_connections[5];
+	else if (_position.x() <= 16)
+		nextAreaID = cons->_connections[7];
+
+	if (nextAreaID > 0)
+		gotoArea(nextAreaID, 0);
+	else
+		FreescapeEngine::checkIfStillInArea();
+}
+
 void DarkEngine::executeMovementConditions() {
 	// Only execute "on collision" room/global conditions
 	if (_currentArea->getAreaFlags() == 1)
diff --git a/engines/freescape/loaders/8bitBinaryLoader.cpp b/engines/freescape/loaders/8bitBinaryLoader.cpp
index 80a5e6b6fbb..b0b2edefc0c 100644
--- a/engines/freescape/loaders/8bitBinaryLoader.cpp
+++ b/engines/freescape/loaders/8bitBinaryLoader.cpp
@@ -26,6 +26,7 @@
 
 #include "freescape/freescape.h"
 #include "freescape/language/8bitDetokeniser.h"
+#include "freescape/objects/connections.h"
 #include "freescape/objects/global.h"
 #include "freescape/objects/group.h"
 #include "freescape/objects/sensor.h"
@@ -115,6 +116,21 @@ Object *FreescapeEngine::load8bitObject(Common::SeekableReadStream *file) {
 		while(--byteSizeOfObject > 0)
 			structureArray.push_back(file->readByte());
 		return new GlobalStructure(structureArray);
+	} else if (objectID == 254 && objectType == ObjectType::kEntranceType) {
+		debugC(1, kFreescapeDebugParser, "Found the area connections (objectID: 254 with size %d)", byteSizeOfObject + 6);
+		Common::Array<uint8> connectionsArray;
+		connectionsArray.push_back(uint8(position.x()));
+		connectionsArray.push_back(uint8(position.y()));
+		connectionsArray.push_back(uint8(position.z()));
+
+		connectionsArray.push_back(uint8(v.x()));
+		connectionsArray.push_back(uint8(v.y()));
+		connectionsArray.push_back(uint8(v.z()));
+
+		byteSizeOfObject++;
+		while(--byteSizeOfObject > 0)
+			connectionsArray.push_back(file->readByte());
+		return new AreaConnections(connectionsArray);
 	}
 
 	debugC(1, kFreescapeDebugParser, "Object %d ; type %d ; size %d", objectID, (int)objectType, byteSizeOfObject);
diff --git a/engines/freescape/movement.cpp b/engines/freescape/movement.cpp
index 35e537ff8d2..c9055e80248 100644
--- a/engines/freescape/movement.cpp
+++ b/engines/freescape/movement.cpp
@@ -177,6 +177,17 @@ void FreescapeEngine::lower() {
 	executeMovementConditions();
 }
 
+void FreescapeEngine::checkIfStillInArea() {
+	for (int i = 0; i < 3; i++) {
+		if (_position.getValue(i) < 0)
+			_position.setValue(i, 0);
+		else if (_position.getValue(i) > 8128)
+			_position.setValue(i, 8128);
+	}
+	if (_position.y() >= 2016)
+		_position.y() = _lastPosition.z();
+}
+
 void FreescapeEngine::move(CameraMovement direction, uint8 scale, float deltaTime) {
 	debugC(1, kFreescapeDebugMove, "old player position: %f, %f, %f", _position.x(), _position.y(), _position.z());
 	int previousAreaID = _currentArea->getAreaID();
@@ -207,14 +218,9 @@ void FreescapeEngine::move(CameraMovement direction, uint8 scale, float deltaTim
 	if (!_flyMode)
 		_position.set(_position.x(), positionY, _position.z());
 
-	for (int i = 0; i < 3; i++) {
-		if (_position.getValue(i) < 0)
-			_position.setValue(i, 0);
-		else if (_position.getValue(i) > 8128)
-			_position.setValue(i, 8128);
-	}
-	if (_position.y() >= 2016)
-		_position.y() = _lastPosition.z();
+	checkIfStillInArea();
+	if (_currentArea->getAreaID() != previousAreaID)
+		return;
 
 	bool collided = checkCollisions(false);
 
diff --git a/engines/freescape/objects/connections.h b/engines/freescape/objects/connections.h
new file mode 100644
index 00000000000..75e705fcceb
--- /dev/null
+++ b/engines/freescape/objects/connections.h
@@ -0,0 +1,45 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#ifndef FREESCAPE_CONNECTIONS_H
+#define FREESCAPE_CONNECTIONS_H
+
+#include "freescape/objects/object.h"
+
+namespace Freescape {
+
+class AreaConnections : public Object {
+public:
+	Common::Array<byte> _connections;
+	AreaConnections(const Common::Array<byte> connections_) {
+		_objectID = 254;
+		_connections = connections_;
+	}
+
+	ObjectType getType() override { return ObjectType::kEntranceType; };
+	void draw(Freescape::Renderer *gfx) override { error("cannot render AreaConnections"); };
+	void scale(int factor) override { warning("cannot scale AreaConnections"); };
+	Object *duplicate() override { error("cannot duplicate AreaConnections"); };
+};
+
+} // End of namespace Freescape
+
+#endif // FREESCAPE_CONNECTIONS_H
\ No newline at end of file




More information about the Scummvm-git-logs mailing list