[Scummvm-git-logs] scummvm master -> 00c4aa1fac1d3d426beff92d65f9c4f38779057f

neuromancer noreply at scummvm.org
Mon Jan 27 21:39:29 UTC 2025


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:
00c4aa1fac FREESCAPE: reworked the C64 implementation of driller


Commit: 00c4aa1fac1d3d426beff92d65f9c4f38779057f
    https://github.com/scummvm/scummvm/commit/00c4aa1fac1d3d426beff92d65f9c4f38779057f
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2025-01-27T22:37:19+01:00

Commit Message:
FREESCAPE: reworked the C64 implementation of driller

Changed paths:
  A devtools/create_freescape/driller_border_Commodore 64.bmp
    dists/engine-data/freescape.dat
    engines/freescape/detection.cpp
    engines/freescape/font.cpp
    engines/freescape/games/driller/c64.cpp
    engines/freescape/games/driller/driller.h
    engines/freescape/gfx.cpp
    engines/freescape/loaders/8bitBinaryLoader.cpp


diff --git a/devtools/create_freescape/driller_border_Commodore 64.bmp b/devtools/create_freescape/driller_border_Commodore 64.bmp
new file mode 100644
index 00000000000..eab73cef00f
Binary files /dev/null and b/devtools/create_freescape/driller_border_Commodore 64.bmp differ
diff --git a/dists/engine-data/freescape.dat b/dists/engine-data/freescape.dat
index 5022299c86c..01ee7e2e1fb 100644
Binary files a/dists/engine-data/freescape.dat and b/dists/engine-data/freescape.dat differ
diff --git a/engines/freescape/detection.cpp b/engines/freescape/detection.cpp
index c6fe79d2369..03a8b985b8e 100644
--- a/engines/freescape/detection.cpp
+++ b/engines/freescape/detection.cpp
@@ -103,6 +103,15 @@ static const ADGameDescription gameDescriptions[] = {
 		ADGF_UNSTABLE,
 		GUIO2(GUIO_NOMIDI, GAMEOPTION_AUTOMATIC_DRILLING)
 	},
+	{
+		"driller", // Tape re-releae
+		"",
+		AD_ENTRY1s("DRILLER.C64.DATA", "606bc969e5442634c8ab057bfde9d9d2", 64750),
+		Common::EN_ANY,
+		Common::kPlatformC64,
+		ADGF_UNSTABLE,
+		GUIO2(GUIO_NOMIDI, GAMEOPTION_AUTOMATIC_DRILLING)
+	},
 	{
 		"driller",
 		"",
diff --git a/engines/freescape/font.cpp b/engines/freescape/font.cpp
index c1f496f7761..cc89e022425 100644
--- a/engines/freescape/font.cpp
+++ b/engines/freescape/font.cpp
@@ -115,7 +115,7 @@ Common::Array<Graphics::ManagedSurface *> FreescapeEngine::getChars(Common::Seek
 	file->read(fontBuffer, 6 * charsNumber);
 
 	Common::BitArray font;
-	font.set_size(48 * charsNumber);
+	font.set_size(48 * charsNumber); // Enough to hold characters for all platforms
 	font.set_bits(fontBuffer);
 
 	Common::Array<Graphics::ManagedSurface *> chars;
@@ -128,15 +128,20 @@ Common::Array<Graphics::ManagedSurface *> FreescapeEngine::getChars(Common::Seek
 		int position = sizeX * sizeY * c;
 
 		Graphics::ManagedSurface *surface = new Graphics::ManagedSurface();
-		surface->create(_renderMode == Common::kRenderHercG ? 16 : 8, sizeY, Graphics::PixelFormat::createFormatCLUT8());
+
+		int charWidth = sizeX;
+		if (_renderMode == Common::kRenderHercG || isC64())
+			charWidth *= 2;
+
+		surface->create(charWidth, sizeY, Graphics::PixelFormat::createFormatCLUT8());
 		for (int j = 0; j < sizeY; j++) {
 			for (int i = 0; i < sizeX; i++) {
 				if (font.get(position + additional + j * 8 + i)) {
-					if (_renderMode != Common::kRenderHercG) {
-						surface->setPixel(7 - i, j, 1);
-					} else {
+					if (_renderMode == Common::kRenderHercG || isC64()) {
 						surface->setPixel(2 * (7 - i), j, 1);
 						surface->setPixel(2 * (7 - i) + 1, j, 1);
+					} else {
+						surface->setPixel(7 - i, j, 1);
 					}
 				}
 			}
diff --git a/engines/freescape/games/driller/c64.cpp b/engines/freescape/games/driller/c64.cpp
index 11b92a14cbe..e05bc42dbcd 100644
--- a/engines/freescape/games/driller/c64.cpp
+++ b/engines/freescape/games/driller/c64.cpp
@@ -28,7 +28,7 @@
 namespace Freescape {
 
 void DrillerEngine::initC64() {
-	_viewArea = Common::Rect(32, 16, 288, 119);
+	_viewArea = Common::Rect(32, 16, 288, 120);
 }
 
 void DrillerEngine::loadAssetsC64FullGame() {
@@ -41,23 +41,32 @@ void DrillerEngine::loadAssetsC64FullGame() {
 		loadGlobalObjects(&file, 0x1855, 8);
 	} else if (_targetName.hasPrefix("driller")) {
 		file.open("driller.c64.data");
-		loadMessagesFixedSize(&file, 0x167a - 0x400, 14, 20);
+		//loadMessagesFixedSize(&file, 0x167a - 0x400, 14, 20);
 		//loadFonts(&file, 0xae54);
-		load8bitBinary(&file, 0x8e02 - 0x400, 4);
-		loadGlobalObjects(&file, 0x1855 - 0x400, 8);
+		loadFonts(&file, 0x4ee);
+		load8bitBinary(&file, 0x8eef - 1, 16);
+		loadMessagesFixedSize(&file, 0x1766, 14, 20);
+
+		Graphics::Surface *surf = loadBundledImage("driller_border");
+		surf->convertToInPlace(_gfx->_texturePixelFormat);
+		_border = new Graphics::ManagedSurface();
+		_border->copyFrom(*surf);
+
+		//_border = _title;
+		//loadGlobalObjects(&file, 0x1855 - 0x400, 8);
 	} else
 		error("Unknown C64 release");
 }
 
 
 void DrillerEngine::drawC64UI(Graphics::Surface *surface) {
-	uint32 color = 1;
+
 	uint8 r, g, b;
+	uint32 front = _gfx->_texturePixelFormat.ARGBToColor(0xFF, 0xAA, 0xAA, 0xAA);
 
-	_gfx->selectColorFromFourColorPalette(color, r, g, b);
-	uint32 front = _gfx->_texturePixelFormat.ARGBToColor(0xFF, r, g, b);
+	Common::Rect cover;
 
-	color = 0;
+	uint32 color = 0;
 	if (_gfx->_colorRemaps && _gfx->_colorRemaps->contains(color)) {
 		color = (*_gfx->_colorRemaps)[color];
 	}
@@ -66,30 +75,33 @@ void DrillerEngine::drawC64UI(Graphics::Surface *surface) {
 	uint32 back = _gfx->_texturePixelFormat.ARGBToColor(0xFF, r, g, b);
 
 	int score = _gameStateVars[k8bitVariableScore];
-	drawStringInSurface(_currentArea->_name, 200, 188, front, back, surface);
-	drawStringInSurface(Common::String::format("%04d", int(2 * _position.x())), 149, 148, front, back, surface);
-	drawStringInSurface(Common::String::format("%04d", int(2 * _position.z())), 149, 156, front, back, surface);
-	drawStringInSurface(Common::String::format("%04d", int(2 * _position.y())), 149, 164, front, back, surface);
+	drawStringInSurface(_currentArea->_name, 200, 184, front, back, surface);
+	cover = Common::Rect(150, 143, 183, 167);
+
+	surface->fillRect(cover, back);
+	drawStringInSurface(Common::String::format("%04d", int(2 * _position.x())), 150, 148 - 4, front, back, surface);
+	drawStringInSurface(Common::String::format("%04d", int(2 * _position.z())), 150, 156 - 4, front, back, surface);
+	drawStringInSurface(Common::String::format("%04d", int(2 * _position.y())), 150, 164 - 4, front, back, surface);
 	if (_playerHeightNumber >= 0)
-		drawStringInSurface(Common::String::format("%d", _playerHeightNumber), 54, 164, front, back, surface);
+		drawStringInSurface(Common::String::format("%d", _playerHeightNumber), 54 + 6, 164 - 3, front, back, surface);
 	else
-		drawStringInSurface(Common::String::format("%s", "J"), 54, 164, front, back, surface);
+		drawStringInSurface(Common::String::format("%s", "J"), 54 + 6, 164 - 3, front, back, surface);
 
-	drawStringInSurface(Common::String::format("%02d", int(_angleRotations[_angleRotationIndex])), 46, 148, front, back, surface);
-	drawStringInSurface(Common::String::format("%3d", _playerSteps[_playerStepIndex]), 44, 156, front, back, surface);
-	drawStringInSurface(Common::String::format("%07d", score), 240, 128, front, back, surface);
+	drawStringInSurface(Common::String::format("%02d", int(_angleRotations[_angleRotationIndex])), 46, 148 - 3, front, back, surface);
+	drawStringInSurface(Common::String::format("%3d", _playerSteps[_playerStepIndex]), 46, 156 - 3, front, back, surface);
+	drawStringInSurface(Common::String::format("%07d", score), 239, 128, front, back, surface);
 
 	int seconds, minutes, hours;
 	getTimeFromCountdown(seconds, minutes, hours);
-	drawStringInSurface(Common::String::format("%02d", hours), 209, 11, front, back, surface);
-	drawStringInSurface(Common::String::format("%02d", minutes), 232, 11, front, back, surface);
-	drawStringInSurface(Common::String::format("%02d", seconds), 254, 11, front, back, surface);
+	drawStringInSurface(Common::String::format("%02d", hours), 207, 8, front, back, surface);
+	drawStringInSurface(Common::String::format("%02d", minutes), 230, 8, front, back, surface);
+	drawStringInSurface(Common::String::format("%02d", seconds), 254, 8, front, back, surface);
 
 	Common::String message;
 	int deadline;
 	getLatestMessages(message, deadline);
 	if (deadline <= _countdown) {
-		drawStringInSurface(message, 191, 180, back, front, surface);
+		drawStringInSurface(message, 191, 176, back, front, surface);
 		_temporaryMessages.push_back(message);
 		_temporaryMessageDeadlines.push_back(deadline);
 	} else {
@@ -100,25 +112,26 @@ void DrillerEngine::drawC64UI(Graphics::Surface *surface) {
 		else
 			message = _messagesList[1];
 
-		drawStringInSurface(message, 191, 180, front, back, surface);
+		drawStringInSurface(message, 191, 176, front, back, surface);
 	}
 
+	uint32 green = _gfx->_texturePixelFormat.ARGBToColor(0xFF, 0x68, 0xa9, 0x41);
 	int energy = _gameStateVars[k8bitVariableEnergy];
 	int shield = _gameStateVars[k8bitVariableShield];
 
 	if (energy >= 0) {
-		Common::Rect backBar(25, 187, 89 - energy, 194);
+		Common::Rect backBar(21, 183, 85 - energy, 190);
 		surface->fillRect(backBar, back);
-		Common::Rect energyBar(88 - energy, 187, 88, 194);
-		surface->fillRect(energyBar, front);
+		Common::Rect energyBar(84 - energy, 184, 84, 190);
+		surface->fillRect(energyBar, green);
 	}
 
 	if (shield >= 0) {
-		Common::Rect backBar(25, 180, 89 - shield, 186);
+		Common::Rect backBar(25 - 4, 180 - 4, 89 - shield - 4, 186 - 4);
 		surface->fillRect(backBar, back);
 
-		Common::Rect shieldBar(88 - shield, 180, 88, 186);
-		surface->fillRect(shieldBar, front);
+		Common::Rect shieldBar(88 - 4  - shield, 180 - 4, 88 - 4, 186 - 4);
+		surface->fillRect(shieldBar, green);
 	}
 }
 
diff --git a/engines/freescape/games/driller/driller.h b/engines/freescape/games/driller/driller.h
index bd190ed1911..cb0aac4ab92 100644
--- a/engines/freescape/games/driller/driller.h
+++ b/engines/freescape/games/driller/driller.h
@@ -19,6 +19,10 @@
  *
  */
 
+#include "audio/audiostream.h"
+#include "audio/mixer.h"
+#include "audio/softsynth/sid.h"
+
 namespace Freescape {
 
 class DrillerEngine : public FreescapeEngine {
@@ -114,4 +118,33 @@ enum DrillerReleaseFlags {
 	GF_ATARI_MAGAZINE_DEMO = (1 << 1),
 };
 
+class Player_SID : public Audio::AudioStream {
+public:
+	Player_SID(Audio::Mixer *mixer);
+	~Player_SID() override;
+
+	void startMusic();
+	void stopMusic();
+
+	// AudioStream API
+	int readBuffer(int16 *buffer, const int numSamples) override;
+	bool isStereo() const override { return false; }
+	bool endOfData() const override { return false; }
+	int getRate() const override { return _sampleRate; }
+
+private:
+	Resid::SID *_sid;
+	void SID_Write(int reg, uint8 data);
+	void initSID();
+	uint8 *getResource(int resID);
+
+	// Unclear if this is needed
+	// number of cpu cycles until next frame update
+	//Resid::cycle_count _cpuCyclesLeft;
+
+	Audio::Mixer *_mixer;
+	Audio::SoundHandle _soundHandle;
+	int _sampleRate;
+};
+
 }
diff --git a/engines/freescape/gfx.cpp b/engines/freescape/gfx.cpp
index c4699bc353b..5200ca6c9d3 100644
--- a/engines/freescape/gfx.cpp
+++ b/engines/freescape/gfx.cpp
@@ -111,6 +111,14 @@ byte getCGAPixel(byte x, int index) {
 		error("Invalid index %d requested", index);
 }
 
+byte getC64Pixel(byte x, int index) {
+	if (index < 0 || index > 3) {
+		error("Invalid index %d requested\n", index);
+	}
+	// Extract the corresponding 2-bit pair based on the index
+	return ((x >> (index * 2)) & 0x3);
+}
+
 byte getCGAStipple(byte x, int back, int fore) {
 	int c0 = getCGAPixel(x, 0);
 	assert(c0 == back || c0 == fore || back == fore);
@@ -137,6 +145,32 @@ byte getCGAStipple(byte x, int back, int fore) {
 	return st;
 }
 
+byte getC64Stipple(byte x, int back, int fore) {
+	int c0 = getC64Pixel(x, 0);
+	assert(c0 == back || c0 == fore || back == fore);
+	int c1 = getC64Pixel(x, 1);
+	assert(c1 == back || c1 == fore || back == fore);
+	int c2 = getC64Pixel(x, 2);
+	assert(c2 == back || c2 == fore || back == fore);
+	int c3 = getC64Pixel(x, 3);
+	assert(c3 == back || c3 == fore || back == fore);
+
+	byte st = 0;
+	if (c0 == fore)
+		st = st | 0x3;
+
+	if (c1 == fore)
+		st = st | (0x3 << 2);
+
+	if (c2 == fore)
+		st = st | (0x3 << 4);
+
+	if (c3 == fore)
+		st = st |  (0x3 << 6);
+
+	return st;
+}
+
 void Renderer::clearColorPairArray() {
 	for (int i = 0; i < 16; i++)
 		_colorPair[i] = 0;
@@ -150,6 +184,8 @@ void Renderer::fillColorPairArray() {
 			c1 = getCGAPixel(entry[0], 0);
 		else if (_renderMode == Common::kRenderCPC)
 			c1 = getCPCPixel(entry[0], 0, true);
+		else if (_renderMode == Common::kRenderC64)
+			c1 = getC64Pixel(entry[0], 0);
 		else
 			error("Not implemented");
 
@@ -162,6 +198,8 @@ void Renderer::fillColorPairArray() {
 					c = getCGAPixel(entry[j], k);
 				else if (_renderMode == Common::kRenderCPC)
 					c = getCPCPixel(entry[j], k, true);
+				else if (_renderMode == Common::kRenderC64)
+					c = getC64Pixel(entry[j], k);
 				else
 					error("Not implemented");
 				if (c1 != c) {
@@ -226,7 +264,7 @@ void Renderer::setColorMap(ColorMap *colorMap_) {
 			byte c2 = (pair >> 4) & 0xf;
 			byte *entry = (*_colorMap)[i];
 			for (int j = 0; j < 128; j++)
-				_stipples[i][j] = getCPCStipple(entry[(j / 8) % 4], c1, c2) ;
+				_stipples[i][j] = getCPCStipple(entry[(j / 8) % 4], c1, c2);
 		}
 	} else if (_renderMode == Common::kRenderCGA) {
 		fillColorPairArray();
@@ -236,9 +274,19 @@ void Renderer::setColorMap(ColorMap *colorMap_) {
 			byte c2 = (pair >> 4) & 0xf;
 			byte *entry = (*_colorMap)[i];
 			for (int j = 0; j < 128; j++)
-				_stipples[i][j] = getCGAStipple(entry[(j / 8) % 4], c1, c2) ;
+				_stipples[i][j] = getCGAStipple(entry[(j / 8) % 4], c1, c2);
 		}
-	}
+	} /*else if (_renderMode == Common::kRenderC64) {
+		fillColorPairArray();
+		for (int i = 4; i < 15; i++) {
+			byte pair = _colorPair[i];
+			byte c1 = pair & 0xf;
+			byte c2 = (pair >> 4) & 0xf;
+			byte *entry = (*_colorMap)[i];
+			for (int j = 0; j < 128; j++)
+				_stipples[i][j] = getC64Stipple(entry[(j / 8) % 4], c1, c2);
+		}
+	}*/
 
 	if (_isAccelerated && _authenticGraphics) {
 		for (int i = 1; i <= 14; i++) {
@@ -315,21 +363,6 @@ void Renderer::extractC64Indexes(uint8 cm1, uint8 cm2, uint8 &i1, uint8 &i2) {
 	} else if (cm1 == 0x41 && cm2 == 0x52) {
 		i1 = 0;
 		i2 = 3;
-// Covered by the default of i1 = 0, i2 = 0
-#if 0
-	} else if (cm1 == 0x5a && cm2 == 0xa5) {
-		i1 = 0;
-		i2 = 0;
-	} else if (cm1 == 0xbb && cm2 == 0xee) {
-		i1 = 0;
-		i2 = 0;
-	} else if (cm1 == 0x5f && cm2 == 0xaf) {
-		i1 = 0;
-		i2 = 0;
-	} else if (cm1 == 0xfb && cm2 == 0xfe) {
-		i1 = 0;
-		i2 = 0;
-#endif
 	} else {
 		i1 = 0;
 		i2 = 0;
diff --git a/engines/freescape/loaders/8bitBinaryLoader.cpp b/engines/freescape/loaders/8bitBinaryLoader.cpp
index 9150774bd65..40e64ea4e53 100644
--- a/engines/freescape/loaders/8bitBinaryLoader.cpp
+++ b/engines/freescape/loaders/8bitBinaryLoader.cpp
@@ -625,7 +625,7 @@ Area *FreescapeEngine::load8bitArea(Common::SeekableReadStream *file, uint16 nco
 	uint8 paperColor = 0;
 	uint8 inkColor = 0;
 
-	if (!(isCastle() && (isSpectrum() || isCPC()))) {
+	if (!(isCastle() && (isSpectrum() || isCPC() || isC64()))) {
 		usualBackgroundColor = readField(file, 8);
 		underFireBackgroundColor = readField(file, 8);
 		paperColor = readField(file, 8);
@@ -993,7 +993,24 @@ void FreescapeEngine::loadFonts(Common::SeekableReadStream *file, int offset) {
 
 	if (isAmiga() || isAtariST())
 		chars = getCharsAmigaAtari(file, offset, 85);
-	else
+	else if (isC64()) {
+		Common::Array<Graphics::ManagedSurface *> rawChars = getChars(file, offset, 85);
+
+		Common::Rect charRect;
+		for (Graphics::ManagedSurface *rawChar : rawChars) {
+			charRect = Common::Rect(0, 0, 8, 6);
+			Graphics::ManagedSurface *charSurface = new Graphics::ManagedSurface();
+			charSurface->create(8, 6, Graphics::PixelFormat::createFormatCLUT8());
+			charSurface->copyRectToSurface(*rawChar, 0, 0, charRect);
+			chars.push_back(charSurface);
+
+			charRect = Common::Rect(8, 0, 16, 6);
+			charSurface = new Graphics::ManagedSurface();
+			charSurface->create(8, 6, Graphics::PixelFormat::createFormatCLUT8());
+			charSurface->copyRectToSurface(*rawChar, 0, 0, charRect);
+			chars.push_back(charSurface);
+		}
+	} else
 		chars = getChars(file, offset, 85);
 
 	_font = Font(chars);




More information about the Scummvm-git-logs mailing list