[Scummvm-git-logs] scummvm master -> 23dd458999e32ab7089c15e786f3788866c84165

neuromancer noreply at scummvm.org
Mon Aug 28 18:34:26 UTC 2023


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

Summary:
23dd458999 FREESCAPE: initial implementation of dark for cpc


Commit: 23dd458999e32ab7089c15e786f3788866c84165
    https://github.com/scummvm/scummvm/commit/23dd458999e32ab7089c15e786f3788866c84165
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2023-08-28T20:34:03+02:00

Commit Message:
FREESCAPE: initial implementation of dark for cpc

Changed paths:
  A engines/freescape/games/dark/cpc.cpp
    engines/freescape/detection.cpp
    engines/freescape/freescape.h
    engines/freescape/games/dark/dark.cpp
    engines/freescape/games/dark/zx.cpp
    engines/freescape/games/driller/cpc.cpp
    engines/freescape/gfx.cpp
    engines/freescape/module.mk


diff --git a/engines/freescape/detection.cpp b/engines/freescape/detection.cpp
index 9d02ee9fb40..faa0190aeae 100644
--- a/engines/freescape/detection.cpp
+++ b/engines/freescape/detection.cpp
@@ -429,6 +429,18 @@ static const ADGameDescription gameDescriptions[] = {
 		ADGF_TESTING,
 		GUIO1(GUIO_NOMIDI)
 	},
+	{
+		"darkside",
+		"",
+		{
+			{"DARKCODE.BIN", 0, "203ce55b7582c556c811acd6a1cf4ab6", 35385},
+			AD_LISTEND
+		},
+		Common::EN_ANY,
+		Common::kPlatformAmstradCPC,
+		ADGF_UNSTABLE,
+		GUIO2(GUIO_NOMIDI, GAMEOPTION_AUTOMATIC_DRILLING)
+	},
 	{
 		"totaleclipse",
 		"",
diff --git a/engines/freescape/freescape.h b/engines/freescape/freescape.h
index a98cdddc672..3664252ec5c 100644
--- a/engines/freescape/freescape.h
+++ b/engines/freescape/freescape.h
@@ -564,11 +564,14 @@ public:
 	void initDOS();
 	void initAmigaAtari();
 	void initZX();
+	void initCPC();
 
 	void loadAssetsDOSFullGame() override;
 	void loadAssetsDOSDemo() override;
 	void loadAssetsAmigaFullGame() override;
 
+	void loadAssetsCPCFullGame() override;
+
 	void loadAssetsZXDemo() override;
 	void loadAssetsZXFullGame() override;
 	void loadMessagesVariableSize(Common::SeekableReadStream *file, int offset, int number) override;
@@ -583,6 +586,7 @@ public:
 	void drawSensorShoot(Sensor *sensor) override;
 	void drawDOSUI(Graphics::Surface *surface) override;
 	void drawZXUI(Graphics::Surface *surface) override;
+	void drawCPCUI(Graphics::Surface *surface) override;
 	void drawAmigaAtariSTUI(Graphics::Surface *surface) override;
 
 
diff --git a/engines/freescape/games/dark/cpc.cpp b/engines/freescape/games/dark/cpc.cpp
new file mode 100644
index 00000000000..be1f25c1df5
--- /dev/null
+++ b/engines/freescape/games/dark/cpc.cpp
@@ -0,0 +1,135 @@
+/* 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/>.
+ *
+ */
+
+#include "common/file.h"
+#include "common/memstream.h"
+
+#include "freescape/freescape.h"
+#include "freescape/games/dark/dark.h"
+#include "freescape/language/8bitDetokeniser.h"
+
+namespace Freescape {
+
+void DarkEngine::initCPC() {
+	_viewArea = Common::Rect(40, 24, 279, 124);
+
+}
+
+extern byte kCPCPaletteTitleData[4][3];
+extern byte kCPCPaletteBorderData[4][3];
+
+extern Graphics::ManagedSurface *readCPCImage(Common::SeekableReadStream *file, bool mode0);
+
+void DarkEngine::loadAssetsCPCFullGame() {
+	Common::File file;
+
+	file.open("DARK1.SCR");
+	if (!file.isOpen())
+		error("Failed to open DARK1.SCR");
+
+	_title = readCPCImage(&file, false);
+	_title->setPalette((byte*)&kCPCPaletteTitleData, 0, 4);
+
+	file.close();
+	file.open("DARK2.SCR");
+	if (!file.isOpen())
+		error("Failed to open DARK2.SCR");
+
+	_border = readCPCImage(&file, true);
+	_border->setPalette((byte*)&kCPCPaletteBorderData, 0, 4);
+
+	file.close();
+	file.open("DARKCODE.BIN");
+
+	if (!file.isOpen())
+		error("Failed to open DARKCODE.BIN");
+
+	loadMessagesFixedSize(&file, 0x5d9, 14, 20);
+	loadFonts(&file, 0x60f3);
+	loadGlobalObjects(&file, 0x9a, 8);
+	load8bitBinary(&file, 0x6255, 16);
+}
+
+void DarkEngine::drawCPCUI(Graphics::Surface *surface) {
+	uint32 color = 7;
+	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];
+	int ecds = _gameStateVars[kVariableActiveECDs];
+	drawStringInSurface(Common::String::format("%04d", int(2 * _position.x())), 191, 141, front, back, surface);
+	drawStringInSurface(Common::String::format("%04d", int(2 * _position.z())), 191, 149, front, back, surface);
+	drawStringInSurface(Common::String::format("%04d", int(2 * _position.y())), 191, 157, front, back, surface);
+
+	drawStringInSurface(Common::String::format("%02d", int(_angleRotations[_angleRotationIndex])), 78, 165, front, back, surface);
+	drawStringInSurface(Common::String::format("%3d", _playerSteps[_playerStepIndex]), 78, 173, front, back, surface);
+	drawStringInSurface(Common::String::format("%07d", score), 94, 13, front, back, surface);
+	drawStringInSurface(Common::String::format("%3d%%", ecds), 190, 13, front, back, surface);
+
+	int seconds, minutes, hours;
+	getTimeFromCountdown(seconds, minutes, hours);
+
+	Common::String message;
+	int deadline;
+	getLatestMessages(message, deadline);
+	if (deadline <= _countdown) {
+		drawStringInSurface(message, 112, 173, back, front, surface);
+		_temporaryMessages.push_back(message);
+		_temporaryMessageDeadlines.push_back(deadline);
+	} else
+		drawStringInSurface(_currentArea->_name, 112, 173, front, back, surface);
+
+	int energy = _gameStateVars[k8bitVariableEnergy]; // called fuel in this game
+	int shield = _gameStateVars[k8bitVariableShield];
+
+	if (shield >= 0) {
+		Common::Rect shieldBar;
+		shieldBar = Common::Rect(80, 140, 143 - (_maxShield - shield), 148);
+		surface->fillRect(shieldBar, back);
+
+		shieldBar = Common::Rect(80, 141, 143 - (_maxShield - shield), 147);
+		surface->fillRect(shieldBar, front);
+	}
+
+	if (energy >= 0) {
+		Common::Rect energyBar;
+		energyBar = Common::Rect(80, 147, 143 - (_maxEnergy - energy), 155);
+		surface->fillRect(energyBar, back);
+
+		energyBar = Common::Rect(80, 148, 143 - (_maxEnergy - energy), 154);
+		surface->fillRect(energyBar, front);
+	}
+	uint32 clockColor = _gfx->_texturePixelFormat.ARGBToColor(0xFF, 0xFF, 0x00, 0x00);
+	drawBinaryClock(surface, 273, 128, clockColor, back);
+	//drawIndicator(surface, 152, 140);
+}
+
+} // End of namespace Freescape
\ No newline at end of file
diff --git a/engines/freescape/games/dark/dark.cpp b/engines/freescape/games/dark/dark.cpp
index 60174a9c0cc..4a9bf4ef2a2 100644
--- a/engines/freescape/games/dark/dark.cpp
+++ b/engines/freescape/games/dark/dark.cpp
@@ -34,6 +34,8 @@ DarkEngine::DarkEngine(OSystem *syst, const ADGameDescription *gd) : FreescapeEn
 		initDOS();
 	else if (isSpectrum())
 		initZX();
+	else if (isCPC())
+		initCPC();
 	else if (isAmiga() || isAtariST())
 		initAmigaAtari();
 
diff --git a/engines/freescape/games/dark/zx.cpp b/engines/freescape/games/dark/zx.cpp
index 682cc28d5e9..74ac802e752 100644
--- a/engines/freescape/games/dark/zx.cpp
+++ b/engines/freescape/games/dark/zx.cpp
@@ -33,7 +33,6 @@ void DarkEngine::initZX() {
 	_maxShield = 63;
 }
 
-
 void DarkEngine::loadAssetsZXFullGame() {
 	Common::File file;
 
diff --git a/engines/freescape/games/driller/cpc.cpp b/engines/freescape/games/driller/cpc.cpp
index 79016c4c0e7..06795c3bef0 100644
--- a/engines/freescape/games/driller/cpc.cpp
+++ b/engines/freescape/games/driller/cpc.cpp
@@ -45,7 +45,7 @@ byte kCPCPaletteBorderData[4][3] = {
 	{0x00, 0x80, 0x00},
 };
 
-byte getCPCPixel(byte cpc_byte, int index) {
+byte getCPCPixelMode0(byte cpc_byte, int index) {
 	if (index == 0)
 		return ((cpc_byte & 0x08) >> 2) | ((cpc_byte & 0x80) >> 7);
 	else if (index == 1)
@@ -58,7 +58,24 @@ byte getCPCPixel(byte cpc_byte, int index) {
 		error("Invalid index %d requested", index);
 }
 
-Graphics::ManagedSurface *readCPCImage(Common::SeekableReadStream *file) {
+byte getCPCPixelMode1(byte cpc_byte, int index) {
+	if (index == 0)
+		return ((cpc_byte & 0x08) >> 0) | ((cpc_byte & 0x80) >> 5) |
+	           ((cpc_byte & 0x20) >> 4) | ((cpc_byte & 0x02) >> 1);
+	else if (index == 2)
+		return ((cpc_byte & 0x04) >> 1) | ((cpc_byte & 0x40) >> 6);
+	else
+		return 0;//error("Invalid index %d requested", index);
+}
+
+byte getCPCPixel(byte cpc_byte, int index, bool mode0) {
+	if (mode0)
+		return getCPCPixelMode0(cpc_byte, index);
+	else
+		return getCPCPixelMode1(cpc_byte, index);
+}
+
+Graphics::ManagedSurface *readCPCImage(Common::SeekableReadStream *file, bool mode0) {
 	Graphics::ManagedSurface *surface = new Graphics::ManagedSurface();
 	surface->create(320, 200, Graphics::PixelFormat::createFormatCLUT8());
 	surface->fillRect(Common::Rect(0, 0, 320, 200), 0);
@@ -71,28 +88,34 @@ Graphics::ManagedSurface *readCPCImage(Common::SeekableReadStream *file) {
 				byte cpc_byte = file->readByte(); // Get CPC byte
 
 				// Process first pixel
-				int pixel_0 = getCPCPixel(cpc_byte, 0); // %Aa
+				int pixel_0 = getCPCPixel(cpc_byte, 0, mode0); // %Aa
 				y = line * 8 + block ; // Coord Y for the pixel
 				x = 4 * offset + 0; // Coord X for the pixel
 				surface->setPixel(x, y, pixel_0);
 
 				// Process second pixel
-				int pixel_1 = getCPCPixel(cpc_byte, 1); // %Bb
 				y = line * 8 + block ; // Coord Y for the pixel
 				x = 4 * offset + 1; // Coord X for the pixel
-				surface->setPixel(x, y, pixel_1);
+				if (mode0) {
+					int pixel_1 = getCPCPixel(cpc_byte, 1, mode0); // %Bb
+					surface->setPixel(x, y, pixel_1);
+				} else
+					surface->setPixel(x, y, pixel_0);
 
 				// Process third pixel
-				int pixel_2 = getCPCPixel(cpc_byte, 2); // %Cc
+				int pixel_2 = getCPCPixel(cpc_byte, 2, mode0); // %Cc
 				y = line * 8 + block ; // Coord Y for the pixel
 				x = 4 * offset + 2; // Coord X for the pixel
 				surface->setPixel(x, y, pixel_2);
 
 				// Process fourth pixel
-				int pixel_3 = getCPCPixel(cpc_byte, 3); // %Dd
 				y = line * 8 + block ; // Coord Y for the pixel
 				x = 4 * offset + 3; // Coord X for the pixel
-				surface->setPixel(x, y, pixel_3);
+				if (mode0) {
+					int pixel_3 = getCPCPixel(cpc_byte, 3, mode0); // %Dd
+					surface->setPixel(x, y, pixel_3);
+				} else
+					surface->setPixel(x, y, pixel_2);
 			}
 		}
 		// We should skip the next 48 bytes, because they are padding the block to be 2048 bytes
@@ -108,7 +131,7 @@ void DrillerEngine::loadAssetsCPCFullGame() {
 	if (!file.isOpen())
 		error("Failed to open DSCN1.BIN");
 
-	_title = readCPCImage(&file);
+	_title = readCPCImage(&file, true);
 	_title->setPalette((byte*)&kCPCPaletteTitleData, 0, 4);
 
 	file.close();
@@ -116,7 +139,7 @@ void DrillerEngine::loadAssetsCPCFullGame() {
 	if (!file.isOpen())
 		error("Failed to open DSCN2.BIN");
 
-	_border = readCPCImage(&file);
+	_border = readCPCImage(&file, true);
 	_border->setPalette((byte*)&kCPCPaletteBorderData, 0, 4);
 
 	file.close();
diff --git a/engines/freescape/gfx.cpp b/engines/freescape/gfx.cpp
index 2a6ef480d61..f589958e477 100644
--- a/engines/freescape/gfx.cpp
+++ b/engines/freescape/gfx.cpp
@@ -59,16 +59,16 @@ Renderer::Renderer(int screenW, int screenH, Common::RenderMode renderMode) {
 
 Renderer::~Renderer() {}
 
-extern byte getCPCPixel(byte cpc_byte, int index);
+extern byte getCPCPixel(byte cpc_byte, int index, bool mode0);
 
 byte getCPCStipple(byte cpc_byte, int back, int fore) {
-	int c0 = getCPCPixel(cpc_byte, 0);
+	int c0 = getCPCPixel(cpc_byte, 0, true);
 	assert(c0 == back || c0 == fore);
-	int c1 = getCPCPixel(cpc_byte, 1);
+	int c1 = getCPCPixel(cpc_byte, 1, true);
 	assert(c1 == back || c1 == fore);
-	int c2 = getCPCPixel(cpc_byte, 2);
+	int c2 = getCPCPixel(cpc_byte, 2, true);
 	assert(c2 == back || c2 == fore);
-	int c3 = getCPCPixel(cpc_byte, 3);
+	int c3 = getCPCPixel(cpc_byte, 3, true);
 	assert(c3 == back || c3 == fore);
 
 	byte st = 0;
@@ -138,7 +138,7 @@ void Renderer::fillColorPairArray() {
 		if (_renderMode == Common::kRenderCGA)
 			c1 = getCGAPixel(entry[0], 0);
 		else if (_renderMode == Common::kRenderCPC)
-			c1 = getCPCPixel(entry[0], 0);
+			c1 = getCPCPixel(entry[0], 0, true);
 		else
 			error("Not implemented");
 
@@ -150,7 +150,7 @@ void Renderer::fillColorPairArray() {
 				if (_renderMode == Common::kRenderCGA)
 					c = getCGAPixel(entry[j], k);
 				else if (_renderMode == Common::kRenderCPC)
-					c = getCPCPixel(entry[j], k);
+					c = getCPCPixel(entry[j], k, true);
 				else
 					error("Not implemented");
 				if (c1 != c) {
@@ -372,8 +372,8 @@ bool Renderer::getRGBAtCPC(uint8 index, uint8 &r1, uint8 &g1, uint8 &b1, uint8 &
 
 	stipple = (byte *)_stipples[index - 1];
 	byte *entry = (*_colorMap)[index - 1];
-	uint8 i1 = getCPCPixel(entry[0], 0);
-	uint8 i2 = getCPCPixel(entry[0], 1);
+	uint8 i1 = getCPCPixel(entry[0], 0, true);
+	uint8 i2 = getCPCPixel(entry[0], 1, true);
 	selectColorFromFourColorPalette(i1, r1, g1, b1);
 	selectColorFromFourColorPalette(i2, r2, g2, b2);
 	return true;
diff --git a/engines/freescape/module.mk b/engines/freescape/module.mk
index 8ffaa241953..61254259f01 100644
--- a/engines/freescape/module.mk
+++ b/engines/freescape/module.mk
@@ -7,6 +7,7 @@ MODULE_OBJS := \
 	freescape.o \
 	games/castle.o \
 	games/dark/amiga.o \
+	games/dark/cpc.o \
 	games/dark/dark.o \
 	games/dark/dos.o \
 	games/dark/zx.o \




More information about the Scummvm-git-logs mailing list