[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