[Scummvm-git-logs] scummvm master -> 59d6c5e5fd0daeeb48f93034a8132949b0145ace
moralrecordings
code at moral.net.au
Sat Mar 21 15:40:41 UTC 2020
This automated email contains information about 4 new commits which have been
pushed to the 'scummvm' repo located at https://github.com/scummvm/scummvm .
Summary:
d36d0473d9 DIRECTOR: Implement loading for SND data
e68f7eebab DIRECTOR: Fix loading cast names with 13 letters
3382e3e965 DIRECTOR: LINGO: Add helper for fetching cast ID from a Datum
59d6c5e5fd DIRECTOR: Fix audio lifetime, implement b_puppetSound
Commit: d36d0473d9634dc3702dc3772161cd2d87e09a55
https://github.com/scummvm/scummvm/commit/d36d0473d9634dc3702dc3772161cd2d87e09a55
Author: Scott Percival (code at moral.net.au)
Date: 2020-03-21T23:37:50+08:00
Commit Message:
DIRECTOR: Implement loading for SND data
Changed paths:
engines/director/cast.cpp
engines/director/cast.h
engines/director/score.cpp
engines/director/score.h
engines/director/sound.cpp
engines/director/sound.h
diff --git a/engines/director/cast.cpp b/engines/director/cast.cpp
index 14e39e2627..e78e5323c9 100644
--- a/engines/director/cast.cpp
+++ b/engines/director/cast.cpp
@@ -121,6 +121,18 @@ BitmapCast::BitmapCast(Common::ReadStreamEndian &stream, uint32 castTag, uint16
_tag = castTag;
}
+SoundCast::SoundCast(Common::ReadStreamEndian &stream, uint16 version) {
+ _type = kCastSound;
+ _audio = nullptr;
+
+ if (version == 4) {
+ for (int i = 0; i < 0xe; i++) {
+ stream.readByte();
+ }
+ _looping = stream.readByte() & 0x10;
+ }
+}
+
TextCast::TextCast(Common::ReadStreamEndian &stream, uint16 version, int32 bgcolor) {
_type = kCastText;
diff --git a/engines/director/cast.h b/engines/director/cast.h
index 954b38d73d..caa564776b 100644
--- a/engines/director/cast.h
+++ b/engines/director/cast.h
@@ -30,6 +30,10 @@ namespace Graphics {
struct Surface;
}
+namespace Audio {
+struct SeekableAudioStream;
+}
+
namespace Common {
class SeekableReadStream;
class ReadStreamEndian;
@@ -71,6 +75,14 @@ public:
uint32 _tag;
};
+class SoundCast : public Cast {
+public:
+ SoundCast(Common::ReadStreamEndian &stream, uint16 version);
+
+ bool _looping;
+ Audio::SeekableAudioStream *_audio;
+};
+
class ShapeCast : public Cast {
public:
ShapeCast(Common::ReadStreamEndian &stream, uint16 version);
diff --git a/engines/director/score.cpp b/engines/director/score.cpp
index 82d001a57a..f856a32b5d 100644
--- a/engines/director/score.cpp
+++ b/engines/director/score.cpp
@@ -26,6 +26,7 @@
#include "common/memstream.h"
#include "common/substream.h"
+#include "audio/decoders/raw.h"
#include "engines/util.h"
#include "graphics/primitives.h"
#include "graphics/macgui/macfontmanager.h"
@@ -243,11 +244,6 @@ void Score::loadArchive() {
debug("STUB: Unhandled 'PICT' resource");
}
- // Sound resources
- if (_movieArchive->hasResource(MKTAG('s', 'n', 'd', ' '), -1)) {
- debug("STUB: Unhandled 'snd ' resource");
- }
-
// Film Loop resources
if (_movieArchive->hasResource(MKTAG('S', 'C', 'V', 'W'), -1)) {
debug("STUB: Unhandled 'SCVW' resource");
@@ -256,6 +252,7 @@ void Score::loadArchive() {
setSpriteCasts();
loadSpriteImages(false);
+ loadSpriteSounds(false);
// Now process STXTs
Common::Array<uint16> stxt = _movieArchive->getResourceIDList(MKTAG('S','T','X','T'));
@@ -375,6 +372,43 @@ void Score::loadSpriteImages(bool isSharedCast) {
}
}
+void Score::loadSpriteSounds(bool isSharedCast) {
+ debugC(1, kDebugLoading, "****** Preloading sprite sounds");
+
+ for (Common::HashMap<int, Cast *>::iterator c = _loadedCast->begin(); c != _loadedCast->end(); ++c) {
+ if (!c->_value)
+ continue;
+
+ if (c->_value->_type != kCastSound)
+ continue;
+
+ SoundCast *soundCast = (SoundCast *)c->_value;
+ uint32 tag = MKTAG('s', 'n', 'd', ' ');
+ uint16 sndId = (uint16)(c->_key + _castIDoffset);
+
+ if (_vm->getVersion() >= 4 && soundCast->_children.size() > 0) {
+ sndId = soundCast->_children[0].index;
+ tag = soundCast->_children[0].tag;
+ }
+
+ Common::SeekableSubReadStreamEndian *sndData = NULL;
+
+ switch (tag) {
+ case MKTAG('s', 'n', 'd', ' '):
+ if (_movieArchive->hasResource(MKTAG('s', 'n', 'd', ' '), sndId)) {
+ debugC(2, kDebugLoading, "****** Loading 'snd ' id: %d", sndId);
+ sndData = _movieArchive->getResource(MKTAG('s', 'n', 'd', ' '), sndId);
+ }
+ break;
+ }
+
+ if (sndData != NULL && soundCast != NULL) {
+ Audio::SeekableAudioStream *audio = makeSNDStream(sndData);
+ soundCast->_audio = audio;
+ }
+ }
+}
+
Score::~Score() {
if (_surface && _surface->w)
@@ -741,6 +775,10 @@ void Score::loadCastData(Common::SeekableSubReadStreamEndian &stream, uint16 id,
debugC(3, kDebugLoading, "Score::loadCastData(): loading kCastBitmap (%d children)", res->children.size());
_loadedCast->setVal(id, new BitmapCast(castStream, res->tag, _vm->getVersion()));
break;
+ case kCastSound:
+ debugC(3, kDebugLoading, "Score::loadCastData(): loading kCastSound (%d children)", res->children.size());
+ _loadedCast->setVal(id, new SoundCast(castStream, _vm->getVersion()));
+ break;
case kCastText:
debugC(3, kDebugLoading, "Score::loadCastData(): loading kCastText (%d children)", res->children.size());
_loadedCast->setVal(id, new TextCast(castStream, _vm->getVersion(), _stageColor));
@@ -773,10 +811,6 @@ void Score::loadCastData(Common::SeekableSubReadStreamEndian &stream, uint16 id,
warning("STUB: Score::loadCastData(): kCastPicture (%d children)", res->children.size());
size2 = 0;
break;
- case kCastSound:
- warning("STUB: Score::loadCastData(): kCastSound (%d children)", res->children.size());
- size2 = 0;
- break;
case kCastMovie:
warning("STUB: Score::loadCastData(): kCastMovie (%d children)", res->children.size());
size2 = 0;
diff --git a/engines/director/score.h b/engines/director/score.h
index 9b798b60c1..4ed654722f 100644
--- a/engines/director/score.h
+++ b/engines/director/score.h
@@ -89,6 +89,7 @@ public:
Sprite *getSpriteById(uint16 id);
void setSpriteCasts();
void loadSpriteImages(bool isSharedCast);
+ void loadSpriteSounds(bool isSharedCast);
void copyCastStxts();
Graphics::ManagedSurface *getSurface() { return _surface; }
diff --git a/engines/director/sound.cpp b/engines/director/sound.cpp
index 95939e49c3..86399ca8fb 100644
--- a/engines/director/sound.cpp
+++ b/engines/director/sound.cpp
@@ -21,12 +21,15 @@
*/
#include "common/file.h"
+#include "common/substream.h"
#include "audio/decoders/wave.h"
+#include "audio/decoders/raw.h"
#include "audio/mixer.h"
#include "audio/softsynth/pcspk.h"
#include "audio/decoders/aiff.h"
+#include "director/director.h"
#include "director/sound.h"
namespace Director {
@@ -92,6 +95,14 @@ void DirectorSound::playMCI(Audio::AudioStream &stream, uint32 from, uint32 to)
_mixer->playStream(Audio::Mixer::kSFXSoundType, _scriptSound, subSeekStream);
}
+void DirectorSound::playStream(Audio::AudioStream &stream, uint8 soundChannel) {
+ Audio::SeekableAudioStream *seekStream = dynamic_cast<Audio::SeekableAudioStream *>(&stream);
+ if (soundChannel == 1)
+ _mixer->playStream(Audio::Mixer::kSFXSoundType, _sound1, seekStream);
+ else
+ _mixer->playStream(Audio::Mixer::kSFXSoundType, _sound2, seekStream);
+}
+
bool DirectorSound::isChannelActive(uint8 channelID) {
if (channelID == 1) {
return _mixer->isSoundHandleActive(*_sound1);
@@ -114,4 +125,56 @@ void DirectorSound::systemBeep() {
_speaker->play(Audio::PCSpeaker::kWaveFormSquare, 500, 150);
}
+
+Audio::SeekableAudioStream *makeSNDStream(Common::SeekableSubReadStreamEndian *stream) {
+ if (debugChannelSet(5, kDebugLoading)) {
+ debugC(5, kDebugLoading, "snd header:");
+ stream->hexdump(0x4e);
+ }
+
+ // unk1
+ for (uint32 i = 0; i < 0x14; i++) {
+ stream->readByte();
+ }
+ uint16 channels = stream->readUint16();
+ if (channels != 1 || channels != 2) {
+ warning("STUB: loadSpriteSounds: no support for old sound format");
+ return NULL;
+ }
+ uint16 rate = stream->readUint16();
+
+ // unk2
+ for (uint32 i = 0; i < 0x06; i++) {
+ stream->readByte();
+ }
+ uint32 length = stream->readUint32();
+ /*uint16 unk3 =*/stream->readUint16();
+ /*uint32 length_copy =*/stream->readUint32();
+ /*uint8 unk4 =*/stream->readByte();
+ /*uint8 unk5 =*/stream->readByte();
+ /*uint16 unk6 =*/stream->readUint16();
+ // unk7
+ for (uint32 i = 0; i < 0x12; i++) {
+ stream->readByte();
+ }
+ uint16 bits = stream->readUint16();
+ // unk8
+ for (uint32 i = 0; i < 0x0c; i++) {
+ stream->readByte();
+ }
+
+ byte flags = 0;
+ flags |= channels == 2 ? Audio::FLAG_STEREO : 0;
+ flags |= bits == 16 ? Audio::FLAG_16BITS : 0;
+ flags |= bits == 8 ? Audio::FLAG_UNSIGNED : 0;
+ uint32 size = length * channels * (bits == 16 ? 2 : 1);
+
+ byte *data = (byte *)malloc(size);
+ assert(data);
+ stream->read(data, size);
+
+ return Audio::makeRawStream(data, size, rate, flags);
+}
+
+
} // End of namespace Director
diff --git a/engines/director/sound.h b/engines/director/sound.h
index 1205a9f8ef..2942ddd4a1 100644
--- a/engines/director/sound.h
+++ b/engines/director/sound.h
@@ -27,6 +27,7 @@ namespace Audio {
class AudioStream;
class SoundHandle;
class PCSpeaker;
+ class SeekableAudioStream;
}
namespace Director {
@@ -48,11 +49,14 @@ public:
void playWAV(Common::String filename, uint8 channelID);
void playAIFF(Common::String filename, uint8 channelID);
void playMCI(Audio::AudioStream &stream, uint32 from, uint32 to);
+ void playStream(Audio::AudioStream &stream, uint8 soundChannel);
void systemBeep();
bool isChannelActive(uint8 channelID);
void stopSound();
};
+Audio::SeekableAudioStream *makeSNDStream(Common::SeekableSubReadStreamEndian *stream);
+
} // End of namespace Director
#endif
Commit: e68f7eebab6a0ff838b38e6e3fcf37f421117c8a
https://github.com/scummvm/scummvm/commit/e68f7eebab6a0ff838b38e6e3fcf37f421117c8a
Author: Scott Percival (code at moral.net.au)
Date: 2020-03-21T23:37:50+08:00
Commit Message:
DIRECTOR: Fix loading cast names with 13 letters
Changed paths:
engines/director/score.cpp
diff --git a/engines/director/score.cpp b/engines/director/score.cpp
index f856a32b5d..becdb55c84 100644
--- a/engines/director/score.cpp
+++ b/engines/director/score.cpp
@@ -1369,10 +1369,10 @@ Common::Array<Common::String> Score::loadStrings(Common::SeekableSubReadStreamEn
for (uint16 i = 0; i < count - 1; i++) {
Common::String entryString;
- for (uint j = entries[i]; j < entries[i + 1]; j++)
+ for (uint j = entries[i] + 1; j < entries[i + 1]; j++) // Skip first byte which is string length
if (data[j] == '\r')
entryString += '\n';
- else if (j > entries[i] || data[j] >= 0x20) // Skip first byte which is string length
+ else if (data[j] >= 0x20)
entryString += data[j];
strings.push_back(entryString);
Commit: 3382e3e965e4aa8f4ce8b3a5b077a2a8183238ae
https://github.com/scummvm/scummvm/commit/3382e3e965e4aa8f4ce8b3a5b077a2a8183238ae
Author: Scott Percival (code at moral.net.au)
Date: 2020-03-21T23:37:50+08:00
Commit Message:
DIRECTOR: LINGO: Add helper for fetching cast ID from a Datum
Changed paths:
engines/director/lingo/lingo-codegen.cpp
engines/director/lingo/lingo.h
diff --git a/engines/director/lingo/lingo-codegen.cpp b/engines/director/lingo/lingo-codegen.cpp
index 76be97806a..36d7601474 100644
--- a/engines/director/lingo/lingo-codegen.cpp
+++ b/engines/director/lingo/lingo-codegen.cpp
@@ -485,6 +485,32 @@ void Lingo::processIf(int startlabel, int endlabel, int finalElse) {
}
}
+int Lingo::castIdFetch(Datum &var) {
+ Score *score = _vm->getCurrentScore();
+ if (!score) {
+ warning("castFetch: Score is empty");
+ return 0;
+ }
+
+ int id = 0;
+ if (var.type == STRING) {
+ if (score->_castsNames.contains(*var.u.s))
+ id = score->_castsNames[*var.u.s];
+ else
+ warning("castFetch: reference to non-existent cast member: %s", var.u.s->c_str());
+ } else if (var.type == INT || var.type == FLOAT) {
+ var.toInt();
+ if (!score->_loadedCast->contains(var.u.i))
+ warning("castFetch: reference to non-existent cast ID: %d", var.u.i);
+ else
+ id = var.u.i;
+ } else {
+ error("castFetch: was expecting STRING or INT, got %s", var.type2str());
+ }
+
+ return id;
+}
+
void Lingo::varAssign(Datum &var, Datum &value) {
if (var.type != VAR && var.type != REFERENCE) {
warning("varAssign: assignment to non-variable");
diff --git a/engines/director/lingo/lingo.h b/engines/director/lingo/lingo.h
index 9471aabe77..f434d646ac 100644
--- a/engines/director/lingo/lingo.h
+++ b/engines/director/lingo/lingo.h
@@ -208,6 +208,7 @@ public:
Symbol *define(Common::String &s, int nargs, ScriptData *code);
Symbol *define(Common::String &s, int start, int nargs, Common::String *prefix = NULL, int end = -1, bool removeCode = true);
void processIf(int elselabel, int endlabel, int finalElse);
+ int castIdFetch(Datum &var);
void varAssign(Datum &var, Datum &value);
Datum varFetch(Datum &var);
Commit: 59d6c5e5fd0daeeb48f93034a8132949b0145ace
https://github.com/scummvm/scummvm/commit/59d6c5e5fd0daeeb48f93034a8132949b0145ace
Author: Scott Percival (code at moral.net.au)
Date: 2020-03-21T23:40:13+08:00
Commit Message:
DIRECTOR: Fix audio lifetime, implement b_puppetSound
Changed paths:
engines/director/archive.cpp
engines/director/cast.cpp
engines/director/cast.h
engines/director/lingo/lingo-builtins.cpp
engines/director/lingo/lingo-codegen.cpp
engines/director/lingo/lingo-the.cpp
engines/director/score.cpp
engines/director/sound.cpp
engines/director/sound.h
diff --git a/engines/director/archive.cpp b/engines/director/archive.cpp
index 03f8cd6830..36b9b1ffc0 100644
--- a/engines/director/archive.cpp
+++ b/engines/director/archive.cpp
@@ -461,6 +461,7 @@ bool RIFXArchive::openStream(Common::SeekableReadStream *stream, uint32 startOff
tag == MKTAG('R', 'T', 'E', '0') ||
tag == MKTAG('R', 'T', 'E', '1') ||
tag == MKTAG('R', 'T', 'E', '2') ||
+ tag == MKTAG('s', 'n', 'd', ' ') ||
tag == MKTAG('L', 'c', 't', 'x') ||
tag == MKTAG('L', 'n', 'a', 'm') ||
tag == MKTAG('L', 's', 'c', 'r'))
diff --git a/engines/director/cast.cpp b/engines/director/cast.cpp
index e78e5323c9..4c4cb8e4b6 100644
--- a/engines/director/cast.cpp
+++ b/engines/director/cast.cpp
@@ -27,6 +27,7 @@
#include "director/cachedmactext.h"
#include "director/cast.h"
#include "director/score.h"
+#include "director/sound.h"
#include "director/stxt.h"
namespace Director {
diff --git a/engines/director/cast.h b/engines/director/cast.h
index caa564776b..51ae805adb 100644
--- a/engines/director/cast.h
+++ b/engines/director/cast.h
@@ -30,10 +30,6 @@ namespace Graphics {
struct Surface;
}
-namespace Audio {
-struct SeekableAudioStream;
-}
-
namespace Common {
class SeekableReadStream;
class ReadStreamEndian;
@@ -43,6 +39,7 @@ namespace Director {
class Stxt;
class CachedMacText;
+class SNDDecoder;
class Cast {
public:
@@ -80,7 +77,7 @@ public:
SoundCast(Common::ReadStreamEndian &stream, uint16 version);
bool _looping;
- Audio::SeekableAudioStream *_audio;
+ SNDDecoder *_audio;
};
class ShapeCast : public Cast {
diff --git a/engines/director/lingo/lingo-builtins.cpp b/engines/director/lingo/lingo-builtins.cpp
index 75a8be1e02..c3901885bd 100644
--- a/engines/director/lingo/lingo-builtins.cpp
+++ b/engines/director/lingo/lingo-builtins.cpp
@@ -23,11 +23,13 @@
#include "common/system.h"
#include "director/director.h"
+#include "director/cast.h"
#include "director/lingo/lingo.h"
#include "director/lingo/lingo-builtins.h"
#include "director/lingo/lingo-code.h"
#include "director/frame.h"
#include "director/score.h"
+#include "director/sound.h"
#include "director/sprite.h"
#include "director/stxt.h"
@@ -1394,11 +1396,33 @@ void LB::b_puppetPalette(int nargs) {
}
void LB::b_puppetSound(int nargs) {
- g_lingo->convertVOIDtoString(0, nargs);
+ if (nargs != 1) {
+ error("b_puppetSound: expected 1 argument, got %d", nargs);
+ g_lingo->dropStack(nargs);
+ return;
+ }
+ Score *score = g_director->getCurrentScore();
- g_lingo->printSTUBWithArglist("b_puppetSound", nargs);
+ DirectorSound *sound = g_director->getSoundManager();
+ Datum castMember = g_lingo->pop();
+ int castId = g_lingo->castIdFetch(castMember);
+
+ if (castId == 0) {
+ sound->stopSound(1);
+ } else {
+ Cast *cast = score->_loadedCast->getVal(castId);
+ if (cast->_type != kCastSound) {
+ error("b_puppetSound: attempted to play a non-SoundCast cast member");
+ return;
+ }
+ SNDDecoder *sd = ((SoundCast *)cast)->_audio;
+ if (!sd) {
+ warning("b_puppetSound: no audio data attached to cast");
+ return;
+ }
+ sound->playStream(*sd->getAudioStream(), 1);
+ }
- g_lingo->dropStack(nargs);
}
void LB::b_puppetSprite(int nargs) {
@@ -1802,29 +1826,7 @@ void LB::b_cast(int nargs) {
void LB::b_field(int nargs) {
Datum d = g_lingo->pop();
- int id;
-
- if (!g_director->getCurrentScore()) {
- warning("b_field: Assigning to a field in an empty score");
- d.u.i = 0;
- d.type = INT;
- g_lingo->push(d);
- return;
- }
-
- if (d.type == STRING) {
- if (g_director->getCurrentScore()->_castsNames.contains(*d.u.s))
- id = g_director->getCurrentScore()->_castsNames[*d.u.s];
- else
- error("b_field: Reference to non-existent field: %s", d.u.s->c_str());
- } else if (d.type == INT || d.type == FLOAT) {
- d.toInt();
- id = d.u.i;
- } else {
- error("b_field: Incorrect reference type: %s", d.type2str());
- }
-
- d.u.i = id;
+ d.u.i = g_lingo->castIdFetch(d);
d.type = REFERENCE;
diff --git a/engines/director/lingo/lingo-codegen.cpp b/engines/director/lingo/lingo-codegen.cpp
index 36d7601474..9ba7843854 100644
--- a/engines/director/lingo/lingo-codegen.cpp
+++ b/engines/director/lingo/lingo-codegen.cpp
@@ -488,7 +488,7 @@ void Lingo::processIf(int startlabel, int endlabel, int finalElse) {
int Lingo::castIdFetch(Datum &var) {
Score *score = _vm->getCurrentScore();
if (!score) {
- warning("castFetch: Score is empty");
+ warning("castIdFetch: Score is empty");
return 0;
}
@@ -497,15 +497,15 @@ int Lingo::castIdFetch(Datum &var) {
if (score->_castsNames.contains(*var.u.s))
id = score->_castsNames[*var.u.s];
else
- warning("castFetch: reference to non-existent cast member: %s", var.u.s->c_str());
+ warning("castIdFetch: reference to non-existent cast member: %s", var.u.s->c_str());
} else if (var.type == INT || var.type == FLOAT) {
var.toInt();
if (!score->_loadedCast->contains(var.u.i))
- warning("castFetch: reference to non-existent cast ID: %d", var.u.i);
+ warning("castIdFetch: reference to non-existent cast ID: %d", var.u.i);
else
id = var.u.i;
} else {
- error("castFetch: was expecting STRING or INT, got %s", var.type2str());
+ error("castIdFetch: was expecting STRING or INT, got %s", var.type2str());
}
return id;
diff --git a/engines/director/lingo/lingo-the.cpp b/engines/director/lingo/lingo-the.cpp
index c714498da1..63d97ce6f5 100644
--- a/engines/director/lingo/lingo-the.cpp
+++ b/engines/director/lingo/lingo-the.cpp
@@ -698,27 +698,9 @@ void Lingo::setTheSprite(Datum &id1, int field, Datum &d) {
Datum Lingo::getTheCast(Datum &id1, int field) {
Datum d;
- int id = 0;
- Score *score = _vm->getCurrentScore();
-
- if (!score) {
- warning("Lingo::getTheCast(): The cast %d field \"%s\" setting over non-active score", id, field2str(field));
- return d;
- }
-
- if (id1.type == INT) {
- id = id1.u.i;
- } else if (id1.type == STRING) {
- if (score->_castsNames.contains(*id1.u.s)) {
- id = score->_castsNames[*id1.u.s];
- } else {
- warning("Lingo::getTheCast(): Unknown the cast \"%s\"", id1.u.s->c_str());
- }
- } else {
- warning("Lingo::getTheCast(): Unknown the cast id type: %s", id1.type2str());
- return d;
- }
+ int id = g_lingo->castIdFetch(id1);
+ Score *score = _vm->getCurrentScore();
// Setting default type
d.type = INT;
diff --git a/engines/director/score.cpp b/engines/director/score.cpp
index becdb55c84..58488242bd 100644
--- a/engines/director/score.cpp
+++ b/engines/director/score.cpp
@@ -403,7 +403,8 @@ void Score::loadSpriteSounds(bool isSharedCast) {
}
if (sndData != NULL && soundCast != NULL) {
- Audio::SeekableAudioStream *audio = makeSNDStream(sndData);
+ SNDDecoder *audio = new SNDDecoder();
+ audio->loadStream(*sndData);
soundCast->_audio = audio;
}
}
diff --git a/engines/director/sound.cpp b/engines/director/sound.cpp
index 86399ca8fb..8b18dec4aa 100644
--- a/engines/director/sound.cpp
+++ b/engines/director/sound.cpp
@@ -97,10 +97,14 @@ void DirectorSound::playMCI(Audio::AudioStream &stream, uint32 from, uint32 to)
void DirectorSound::playStream(Audio::AudioStream &stream, uint8 soundChannel) {
Audio::SeekableAudioStream *seekStream = dynamic_cast<Audio::SeekableAudioStream *>(&stream);
+ playStream(*seekStream, soundChannel);
+}
+
+void DirectorSound::playStream(Audio::SeekableAudioStream &stream, uint8 soundChannel) {
if (soundChannel == 1)
- _mixer->playStream(Audio::Mixer::kSFXSoundType, _sound1, seekStream);
+ _mixer->playStream(Audio::Mixer::kSFXSoundType, _sound1, &stream);
else
- _mixer->playStream(Audio::Mixer::kSFXSoundType, _sound2, seekStream);
+ _mixer->playStream(Audio::Mixer::kSFXSoundType, _sound2, &stream);
}
bool DirectorSound::isChannelActive(uint8 channelID) {
@@ -115,6 +119,15 @@ bool DirectorSound::isChannelActive(uint8 channelID) {
return false;
}
+void DirectorSound::stopSound(uint8 channelID) {
+ if (channelID == 1) {
+ _mixer->stopHandle(*_sound1);
+ } else if (channelID == 2) {
+ _mixer->stopHandle(*_sound2);
+ }
+ return;
+}
+
void DirectorSound::stopSound() {
_mixer->stopHandle(*_sound1);
_mixer->stopHandle(*_sound2);
@@ -125,55 +138,78 @@ void DirectorSound::systemBeep() {
_speaker->play(Audio::PCSpeaker::kWaveFormSquare, 500, 150);
}
+SNDDecoder::SNDDecoder() {
+ _data = nullptr;
+ _channels = 0;
+ _size = 0;
+ _rate = 0;
+ _flags = 0;
+}
+
+SNDDecoder::~SNDDecoder() {
+ if (_data) {
+ free(_data);
+ }
+}
+
+
+bool SNDDecoder::loadStream(Common::SeekableSubReadStreamEndian &stream) {
+ if (_data) {
+ free(_data);
+ _data = nullptr;
+ }
-Audio::SeekableAudioStream *makeSNDStream(Common::SeekableSubReadStreamEndian *stream) {
if (debugChannelSet(5, kDebugLoading)) {
debugC(5, kDebugLoading, "snd header:");
- stream->hexdump(0x4e);
+ stream.hexdump(0x4e);
}
// unk1
for (uint32 i = 0; i < 0x14; i++) {
- stream->readByte();
+ stream.readByte();
}
- uint16 channels = stream->readUint16();
- if (channels != 1 || channels != 2) {
+ _channels = stream.readUint16();
+ if (!(_channels == 1 || _channels == 2)) {
warning("STUB: loadSpriteSounds: no support for old sound format");
- return NULL;
+ return false;
}
- uint16 rate = stream->readUint16();
+ _rate = stream.readUint16();
// unk2
for (uint32 i = 0; i < 0x06; i++) {
- stream->readByte();
+ stream.readByte();
}
- uint32 length = stream->readUint32();
- /*uint16 unk3 =*/stream->readUint16();
- /*uint32 length_copy =*/stream->readUint32();
- /*uint8 unk4 =*/stream->readByte();
- /*uint8 unk5 =*/stream->readByte();
- /*uint16 unk6 =*/stream->readUint16();
+ uint32 length = stream.readUint32();
+ /*uint16 unk3 =*/stream.readUint16();
+ /*uint32 length_copy =*/stream.readUint32();
+ /*uint8 unk4 =*/stream.readByte();
+ /*uint8 unk5 =*/stream.readByte();
+ /*uint16 unk6 =*/stream.readUint16();
// unk7
for (uint32 i = 0; i < 0x12; i++) {
- stream->readByte();
+ stream.readByte();
}
- uint16 bits = stream->readUint16();
+ uint16 bits = stream.readUint16();
// unk8
for (uint32 i = 0; i < 0x0c; i++) {
- stream->readByte();
+ stream.readByte();
}
- byte flags = 0;
- flags |= channels == 2 ? Audio::FLAG_STEREO : 0;
- flags |= bits == 16 ? Audio::FLAG_16BITS : 0;
- flags |= bits == 8 ? Audio::FLAG_UNSIGNED : 0;
- uint32 size = length * channels * (bits == 16 ? 2 : 1);
+ _flags = 0;
+ _flags |= _channels == 2 ? Audio::FLAG_STEREO : 0;
+ _flags |= bits == 16 ? Audio::FLAG_16BITS : 0;
+ _flags |= bits == 8 ? Audio::FLAG_UNSIGNED : 0;
+ _size = length * _channels * (bits == 16 ? 2 : 1);
- byte *data = (byte *)malloc(size);
- assert(data);
- stream->read(data, size);
+ _data = (byte *)malloc(_size);
+ assert(_data);
+ stream.read(_data, _size);
+
+ return true;
+}
- return Audio::makeRawStream(data, size, rate, flags);
+Audio::SeekableAudioStream *SNDDecoder::getAudioStream() {
+ return Audio::makeRawStream(_data, _size, _rate, _flags, DisposeAfterUse::NO);
}
diff --git a/engines/director/sound.h b/engines/director/sound.h
index 2942ddd4a1..38677a4a53 100644
--- a/engines/director/sound.h
+++ b/engines/director/sound.h
@@ -50,12 +50,29 @@ public:
void playAIFF(Common::String filename, uint8 channelID);
void playMCI(Audio::AudioStream &stream, uint32 from, uint32 to);
void playStream(Audio::AudioStream &stream, uint8 soundChannel);
+ void playStream(Audio::SeekableAudioStream &stream, uint8 soundChannel);
void systemBeep();
bool isChannelActive(uint8 channelID);
+ void stopSound(uint8 channelID);
void stopSound();
};
-Audio::SeekableAudioStream *makeSNDStream(Common::SeekableSubReadStreamEndian *stream);
+
+class SNDDecoder {
+public:
+ SNDDecoder();
+ ~SNDDecoder();
+
+ bool loadStream(Common::SeekableSubReadStreamEndian &stream);
+ Audio::SeekableAudioStream *getAudioStream();
+
+private:
+ byte *_data;
+ uint16 _channels;
+ uint32 _size;
+ uint16 _rate;
+ byte _flags;
+};
} // End of namespace Director
More information about the Scummvm-git-logs
mailing list