[Scummvm-git-logs] scummvm master -> 1c8bf5205fa4932093d085b9c655537cdda1b6a6

mduggan noreply at scummvm.org
Fri Nov 22 10:13:15 UTC 2024


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

Summary:
ff57bb851b DGDS: Add CDS:TT3 data to packed data list
1c8bf5205f DGDS: Initial support for Willy Beamish voice acting


Commit: ff57bb851b756618f9e187dc241ff3b00d0c0a9f
    https://github.com/scummvm/scummvm/commit/ff57bb851b756618f9e187dc241ff3b00d0c0a9f
Author: Matthew Duggan (mgithub at guarana.org)
Date: 2024-11-22T21:13:06+11:00

Commit Message:
DGDS: Add CDS:TT3 data to packed data list

Changed paths:
    engines/dgds/includes.h
    engines/dgds/resource.cpp


diff --git a/engines/dgds/includes.h b/engines/dgds/includes.h
index 9a45f67dcf4..8fe56888ddc 100644
--- a/engines/dgds/includes.h
+++ b/engines/dgds/includes.h
@@ -66,6 +66,7 @@ namespace Dgds {
 #define EX_ADS MKTAG24('A', 'D', 'S')
 #define EX_AMG MKTAG24('A', 'M', 'G')
 #define EX_BMP MKTAG24('B', 'M', 'P')
+#define EX_CDS MKTAG24('C', 'D', 'S')
 #define EX_FNT MKTAG24('F', 'N', 'T')
 #define EX_GDS MKTAG24('G', 'D', 'S')
 #define EX_INS MKTAG24('I', 'N', 'S')
diff --git a/engines/dgds/resource.cpp b/engines/dgds/resource.cpp
index 890dd8ceafe..0d5a2f90f1b 100644
--- a/engines/dgds/resource.cpp
+++ b/engines/dgds/resource.cpp
@@ -175,6 +175,9 @@ bool DgdsChunkReader::isPacked() const {
 	case EX_BMP:
 		packed = (_id == ID_BIN || _id == ID_VGA);
 		break;
+	case EX_CDS:
+		packed = (_id == ID_TT3);
+		break;
 	case EX_GDS:
 	case EX_SDS:
 		packed = (_id == ID_SDS);


Commit: 1c8bf5205fa4932093d085b9c655537cdda1b6a6
    https://github.com/scummvm/scummvm/commit/1c8bf5205fa4932093d085b9c655537cdda1b6a6
Author: Matthew Duggan (mgithub at guarana.org)
Date: 2024-11-22T21:13:06+11:00

Commit Message:
DGDS: Initial support for Willy Beamish voice acting

Still doesn't properly play the dialog action voices.

Changed paths:
    engines/dgds/dialog.h
    engines/dgds/scene.cpp
    engines/dgds/scene.h
    engines/dgds/sound_raw.cpp
    engines/dgds/sound_raw.h


diff --git a/engines/dgds/dialog.h b/engines/dgds/dialog.h
index 8f111953526..e0352af0749 100644
--- a/engines/dgds/dialog.h
+++ b/engines/dgds/dialog.h
@@ -72,6 +72,7 @@ enum DialogDrawStage {
 };
 
 struct DialogAction {
+	int16 num;
 	// The game initializes str offsets to pointers, but let's be a bit nicer.
 	uint16 strStart; /// The start of the clickable text for this action
 	uint16 strEnd;	 /// End of clickable text for this action
diff --git a/engines/dgds/scene.cpp b/engines/dgds/scene.cpp
index dbed0dfb2c2..75e34a8ba92 100644
--- a/engines/dgds/scene.cpp
+++ b/engines/dgds/scene.cpp
@@ -46,6 +46,7 @@
 #include "dgds/minigames/dragon_arcade.h"
 #include "dgds/dragon_native.h"
 #include "dgds/hoc_intro.h"
+#include "dgds/sound_raw.h"
 
 namespace Dgds {
 
@@ -526,10 +527,11 @@ bool Scene::readDialogActionList(Common::SeekableReadStream *s, Common::Array<Di
 	// if (!list.empty())
 	//	list[0].val = 1;
 
-	for (DialogAction &dst : list) {
-		dst.strStart = s->readUint16LE();
-		dst.strEnd = s->readUint16LE();
-		readOpList(s, dst.sceneOpList);
+	for (uint i = 0; i < list.size(); i++) {
+		list[i].num = i;
+		list[i].strStart = s->readUint16LE();
+		list[i].strEnd = s->readUint16LE();
+		readOpList(s, list[i].sceneOpList);
 	}
 
 	return !s->err();
@@ -1063,6 +1065,10 @@ void SDSScene::unload() {
 	_triggers.clear();
 	_talkData.clear();
 	_dynamicRects.clear();
+	if (_dlgSound) {
+		_dlgSound->stop();
+		_dlgSound.reset();
+	}
 	_sceneDialogFlags = kDlgFlagNone;
 }
 
@@ -1217,8 +1223,13 @@ bool SDSScene::readTalkData(Common::SeekableReadStream *s, TalkData &dst) {
 			h._bmpFile = s->readString();
 			if (!h._bmpFile.empty()) {
 				DgdsEngine *engine = DgdsEngine::getInstance();
-				h._shape.reset(new Image(engine->getResourceManager(), engine->getDecompressor()));
-				h._shape->loadBitmap(h._bmpFile);
+				ResourceManager *resMan = engine->getResourceManager();
+				if (resMan->hasResource(h._bmpFile)) {
+					h._shape.reset(new Image(resMan, engine->getDecompressor()));
+					h._shape->loadBitmap(h._bmpFile);
+				} else {
+					warning("Couldn't load talkdata %d head %d BMP: %s", dst._num, h._num, h._bmpFile.c_str());
+				}
 			}
 		}
 		uint16 nsub = s->readUint16LE();
@@ -1280,10 +1291,15 @@ bool SDSScene::loadTalkData(uint16 num) {
 			_talkData.front()._num = num;
 			_version = oldVer;
 
-			if (!_talkData.front()._bmpFile.empty()) {
-				Image *img = new Image(resourceManager, decompressor);
-				img->loadBitmap(_talkData.front()._bmpFile);
-				_talkData.front()._shape.reset(img);
+			const Common::String &bmpFile = _talkData.front()._bmpFile;
+			if (!bmpFile.empty()) {
+				if (resourceManager->hasResource(bmpFile)) {
+					Image *img = new Image(resourceManager, decompressor);
+					img->loadBitmap(bmpFile);
+					_talkData.front()._shape.reset(img);
+				} else {
+					warning("Couldn't load talkdata %d head BMP: %s", num, bmpFile.c_str());
+				}
 			}
 		}
 	}
@@ -1293,6 +1309,7 @@ bool SDSScene::loadTalkData(uint16 num) {
 	return result;
 }
 
+
 void SDSScene::freeTalkData(uint16 num) {
 	for (int i = 0; i < (int)_talkData.size(); i++) {
 		if (_talkData[i]._num == num) {
@@ -1312,6 +1329,57 @@ void SDSScene::updateVisibleTalkers() {
 }
 
 
+bool SDSScene::loadCDSData(uint16 dlgFileNum, uint16 dlgNum, int16 sub) {
+	if (_dlgSound) {
+		_dlgSound->stop();
+		_dlgSound.reset();
+	}
+
+	Common::String fname;
+	if (sub >= 0) {
+		assert(sub < 26);
+		fname = Common::String::format("F%dB%d%c.CDS", dlgFileNum, dlgNum, 'A' + sub);
+	} else {
+		fname = Common::String::format("F%dB%d.CDS", dlgFileNum, dlgNum);
+	}
+
+	DgdsEngine *engine = DgdsEngine::getInstance();
+	ResourceManager *resourceManager = engine->getResourceManager();
+	Common::SeekableReadStream *cdsFile = resourceManager->getResource(fname);
+	if (!cdsFile)
+		return false;
+
+	DgdsChunkReader chunk(cdsFile);
+	Decompressor *decompressor = engine->getDecompressor();
+
+	bool result = false;
+
+	while (chunk.readNextHeader(EX_CDS, fname)) {
+		if (chunk.isContainer()) {
+			continue;
+		}
+
+		chunk.readContent(decompressor);
+		Common::SeekableReadStream *stream = chunk.getContent();
+
+		//
+		// All CDS files contain TT3 sections with little scripts that load
+		// and play a RAW sound file (eg F1B13.CDS loads CSCR013.RAW), but
+		// they also have RAW sections with the sound data, embedded and the named
+		// RAW files don't exist.
+		//
+		if (chunk.isSection(ID_RAW)) {
+			_dlgSound.reset(new SoundRaw(resourceManager, decompressor));
+			_dlgSound->loadFromStream(stream, chunk.getSize());
+			_dlgSound->play();
+			result = true;
+		}
+	}
+
+	delete cdsFile;
+	return result;
+}
+
 void SDSScene::drawHead(Graphics::ManagedSurface *dst, const TalkData &data, const TalkDataHead &head) {
 	uint drawtype = head._drawType ? head._drawType : 1;
 	// Use specific head shape if available (eg, in Willy Beamish), if not use talk data shape
@@ -1520,6 +1588,8 @@ void SDSScene::showDialog(uint16 fileNum, uint16 dlgNum) {
 				loadTalkDataAndSetFlags(dialog._talkDataNum, dialog._talkDataHeadNum);
 			}
 
+			loadCDSData(fileNum, dlgNum, -1);
+
 			// hide time gets set the first time it's drawn.
 			if (_dlgWithFlagLo8IsClosing && dialog.hasFlag(kDlgFlagLo8)) {
 				_sceneDialogFlags = static_cast<DialogFlags>(_sceneDialogFlags | kDlgFlagLo8 | kDlgFlagVisible);
@@ -1580,6 +1650,12 @@ bool SDSScene::checkDialogActive() {
 			if (action || dlg._action.empty()) {
 				dlg.setFlag(kDlgFlagHiFinished);
 				if (action) {
+					// TODO: We can load selected item voice acting here, but it generally
+					// immediately starts another dialog or changes scene, so the sound
+					// doesn't end up playing.
+					// Need to work out how to correctly delay until the sound finishes?
+					loadCDSData(dlg._fileNum, dlg._num, action->num);
+
 					// Take a copy of the dialog because the actions might change the scene
 					Dialog dlgCopy = dlg;
 					debug(1, "Dialog %d closing: run action (%d ops)", dlg._num, action->sceneOpList.size());
diff --git a/engines/dgds/scene.h b/engines/dgds/scene.h
index 7a2c17b6c81..0c915798e95 100644
--- a/engines/dgds/scene.h
+++ b/engines/dgds/scene.h
@@ -35,6 +35,7 @@ namespace Dgds {
 class ResourceManager;
 class Decompressor;
 class DgdsFont;
+class SoundRaw;
 
 enum SceneCondition {
 	kSceneCondNone = 0,
@@ -479,6 +480,7 @@ public:
 	void loadTalkDataAndSetFlags(uint16 talknum, uint16 headnum);
 	void drawVisibleHeads(Graphics::ManagedSurface *dst);
 	bool hasVisibleHead() const;
+	bool loadCDSData(uint16 num, uint16 num2, int16 sub);
 
 	// dragon-specific scene ops
 	void addAndShowTiredDialog();
@@ -527,6 +529,7 @@ private:
 	// From here on is mutable stuff that might need saving
 	Common::Array<Dialog> _dialogs;
 	Common::Array<SceneTrigger> _triggers;
+	Common::SharedPtr<SoundRaw> _dlgSound;
 
 	GameItem *_dragItem;
 	bool _shouldClearDlg;
diff --git a/engines/dgds/sound_raw.cpp b/engines/dgds/sound_raw.cpp
index 9ca58ca883a..937055ba1e5 100644
--- a/engines/dgds/sound_raw.cpp
+++ b/engines/dgds/sound_raw.cpp
@@ -42,8 +42,7 @@ void SoundRaw::load(const Common::String &filename) {
 		chunk.readContent(_decompressor);
 		Common::SeekableReadStream *stream = chunk.getContent();
 		if (chunk.isSection(ID_RAW)) {
-			_data.resize(chunk.getSize());
-			stream->read(_data.data(), chunk.getSize());
+			loadFromStream(stream, chunk.getSize());
 			break;
 		}
 	}
@@ -53,6 +52,10 @@ SoundRaw::~SoundRaw() {
 	stop();
 }
 
+void SoundRaw::loadFromStream(Common::SeekableReadStream *stream, int size) {
+	_data.resize(size);
+	stream->read(_data.data(), size);
+}
 
 void SoundRaw::play() {
 	Audio::Mixer *mixer = DgdsEngine::getInstance()->_mixer;
diff --git a/engines/dgds/sound_raw.h b/engines/dgds/sound_raw.h
index f3748c38430..1006595a321 100644
--- a/engines/dgds/sound_raw.h
+++ b/engines/dgds/sound_raw.h
@@ -45,6 +45,7 @@ public:
 	void play();
 	void stop();
 	bool isPlaying() const;
+	void loadFromStream(Common::SeekableReadStream *stream, int size);
 
 private:
 	Common::Array<byte> _data;




More information about the Scummvm-git-logs mailing list