aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--engines/mads/audio.cpp129
-rw-r--r--engines/mads/audio.h64
-rw-r--r--engines/mads/debugger.cpp19
-rw-r--r--engines/mads/debugger.h1
-rw-r--r--engines/mads/game.h1
-rw-r--r--engines/mads/mads.cpp1
-rw-r--r--engines/mads/mads.h1
-rw-r--r--engines/mads/module.mk1
8 files changed, 217 insertions, 0 deletions
diff --git a/engines/mads/audio.cpp b/engines/mads/audio.cpp
new file mode 100644
index 0000000000..0a9637bfcf
--- /dev/null
+++ b/engines/mads/audio.cpp
@@ -0,0 +1,129 @@
+/* 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 2
+ * 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, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "mads/audio.h"
+#include "mads/compression.h"
+
+#include "common/stream.h"
+#include "audio/audiostream.h"
+#include "audio/mixer.h"
+#include "audio/decoders/raw.h"
+
+namespace MADS {
+
+AudioPlayer::AudioPlayer(Audio::Mixer *mixer, uint32 gameID) : _mixer(mixer), _gameID(gameID) {
+ setVolume(Audio::Mixer::kMaxChannelVolume);
+ setDefaultSoundGroup();
+}
+
+AudioPlayer::~AudioPlayer() {
+ _dsrEntries.clear();
+}
+
+bool AudioPlayer::isPlaying() const {
+ return _mixer->isSoundHandleActive(_handle);
+}
+
+void AudioPlayer::setVolume(int volume) {
+ _mixer->setVolumeForSoundType(Audio::Mixer::kSFXSoundType, volume);
+ _mixer->setVolumeForSoundType(Audio::Mixer::kSpeechSoundType, volume);
+}
+
+void AudioPlayer::setDefaultSoundGroup() {
+ switch (_gameID) {
+ case GType_RexNebular:
+ setSoundGroup("rex009.dsr");
+ break;
+ case GType_Dragonsphere:
+ setSoundGroup("drag009.dsr");
+ break;
+ case GType_Phantom:
+ setSoundGroup("phan009.dsr");
+ break;
+ default:
+ error("setDefaultSoundGroup: Unknown game");
+ }
+}
+
+void AudioPlayer::setSoundGroup(const Common::String &filename) {
+ _dsrEntries.clear();
+
+ _filename = filename;
+ _dsrFile.open(filename);
+
+ // Read header
+ uint16 entryCount = _dsrFile.readUint16LE();
+
+ for (uint16 i = 0; i < entryCount; i++) {
+ DSREntry newEntry;
+ newEntry.frequency = _dsrFile.readUint16LE();
+ newEntry.channels = _dsrFile.readUint32LE();
+ newEntry.compSize = _dsrFile.readUint32LE();
+ newEntry.uncompSize = _dsrFile.readUint32LE();
+ newEntry.offset = _dsrFile.readUint32LE();
+ _dsrEntries.push_back(newEntry);
+ }
+
+ _dsrFile.close();
+}
+
+void AudioPlayer::playSound(int soundIndex, bool loop) {
+ if (_dsrEntries.empty()) {
+ warning("DSR file not loaded, not playing sound");
+ return;
+ }
+
+ if (soundIndex < 0 || soundIndex > _dsrEntries.size() - 1) {
+ warning("Invalid sound index: %i (max %i), not playing sound", soundIndex, _dsrEntries.size() - 1);
+ return;
+ }
+
+ // Get sound data
+ FabDecompressor fab;
+ int32 compSize = _dsrEntries[soundIndex].compSize;
+ int32 uncompSize = _dsrEntries[soundIndex].uncompSize;
+ int32 offset = _dsrEntries[soundIndex].offset;
+ int16 frequency = _dsrEntries[soundIndex].frequency;
+ byte *compData = new byte[compSize];
+ byte *buffer = new byte[uncompSize];
+ _dsrFile.open(_filename);
+ _dsrFile.seek(offset, SEEK_SET);
+ _dsrFile.read(compData, compSize);
+ _dsrFile.close();
+
+ fab.decompress(compData, compSize, buffer, uncompSize);
+
+ // Play sound
+ Audio::AudioStream *stream = Audio::makeLoopingAudioStream(
+ Audio::makeRawStream(buffer, uncompSize, frequency, Audio::FLAG_UNSIGNED),
+ loop ? 0 : 1);
+ _mixer->playStream(Audio::Mixer::kSFXSoundType, &_handle, stream, -1, Audio::Mixer::kMaxChannelVolume);
+
+ /*
+ // Dump the sound file
+ FILE *destFile = fopen("sound.raw", "wb");
+ fwrite(_dsrFile.dsrEntries[soundIndex]->data, _dsrFile.dsrEntries[soundIndex].uncompSize, 1, destFile);
+ fclose(destFile);
+ */
+}
+
+} // End of namespace M4
diff --git a/engines/mads/audio.h b/engines/mads/audio.h
new file mode 100644
index 0000000000..21f4bed59a
--- /dev/null
+++ b/engines/mads/audio.h
@@ -0,0 +1,64 @@
+/* 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 2
+ * 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, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifndef MADS_AUDIO_H
+#define MADS_AUDIO_H
+
+#include "mads/resources.h"
+
+#include "common/array.h"
+#include "audio/mixer.h"
+
+namespace MADS {
+
+struct DSREntry {
+ int16 frequency;
+ int channels;
+ int32 compSize;
+ int32 uncompSize;
+ int32 offset;
+};
+
+class AudioPlayer {
+public:
+ AudioPlayer(Audio::Mixer *mixer, uint32 gameID);
+ ~AudioPlayer();
+
+ void setSoundGroup(const Common::String &filename);
+ void setDefaultSoundGroup();
+ void playSound(int soundIndex, bool loop = false);
+ void setVolume(int volume);
+ bool isPlaying() const;
+
+ private:
+ Audio::Mixer *_mixer;
+ Audio::SoundHandle _handle;
+ uint32 _gameID;
+
+ File _dsrFile;
+ Common::String _filename;
+ Common::Array<DSREntry> _dsrEntries;
+};
+
+} // End of namespace MADS
+
+#endif
diff --git a/engines/mads/debugger.cpp b/engines/mads/debugger.cpp
index a6192b2a34..80a8cb748e 100644
--- a/engines/mads/debugger.cpp
+++ b/engines/mads/debugger.cpp
@@ -35,6 +35,7 @@ Debugger::Debugger(MADSEngine *vm) : GUI::Debugger(), _vm(vm) {
DCmd_Register("show_hotspots", WRAP_METHOD(Debugger, Cmd_ShowHotSpots));
DCmd_Register("list_hotspots", WRAP_METHOD(Debugger, Cmd_ListHotSpots));
DCmd_Register("play_sound", WRAP_METHOD(Debugger, Cmd_PlaySound));
+ DCmd_Register("play_audio", WRAP_METHOD(Debugger, Cmd_PlayAudio));
DCmd_Register("show_codes", WRAP_METHOD(Debugger, Cmd_ShowCodes));
DCmd_Register("dump_file", WRAP_METHOD(Debugger, Cmd_DumpFile));
DCmd_Register("show_quote", WRAP_METHOD(Debugger, Cmd_ShowQuote));
@@ -125,6 +126,24 @@ bool Debugger::Cmd_PlaySound(int argc, const char **argv) {
return false;
}
+bool Debugger::Cmd_PlayAudio(int argc, const char **argv) {
+ if (argc < 2) {
+ DebugPrintf("Usage: %s <sound index> <sound group>\n", argv[0]);
+ DebugPrintf("If the sound group isn't defined, the default one will be used\n");
+ } else {
+ int index = strToInt(argv[1]);
+ Common::String soundGroup = (argc >= 3) ? argv[2] : "";
+ if (argc >= 3)
+ _vm->_audio->setSoundGroup(argv[2]);
+ else
+ _vm->_audio->setDefaultSoundGroup();
+
+ _vm->_audio->playSound(index);
+ }
+
+ return true;
+}
+
bool Debugger::Cmd_ShowCodes(int argc, const char **argv) {
Scene &scene = _vm->_game->_scene;
diff --git a/engines/mads/debugger.h b/engines/mads/debugger.h
index c2d66d9118..19827495d4 100644
--- a/engines/mads/debugger.h
+++ b/engines/mads/debugger.h
@@ -39,6 +39,7 @@ protected:
bool Cmd_ShowHotSpots(int argc, const char **argv);
bool Cmd_ListHotSpots(int argc, const char **argv);
bool Cmd_PlaySound(int argc, const char **argv);
+ bool Cmd_PlayAudio(int argc, const char **argv);
bool Cmd_ShowCodes(int argc, const char **argv);
bool Cmd_DumpFile(int argc, const char **argv);
bool Cmd_ShowQuote(int argc, const char **argv);
diff --git a/engines/mads/game.h b/engines/mads/game.h
index 982f880dca..246a7857a6 100644
--- a/engines/mads/game.h
+++ b/engines/mads/game.h
@@ -27,6 +27,7 @@
#include "common/savefile.h"
#include "common/str-array.h"
#include "common/serializer.h"
+#include "mads/audio.h"
#include "mads/scene.h"
#include "mads/game_data.h"
#include "mads/globals.h"
diff --git a/engines/mads/mads.cpp b/engines/mads/mads.cpp
index cb84f4da88..29db804f16 100644
--- a/engines/mads/mads.cpp
+++ b/engines/mads/mads.cpp
@@ -88,6 +88,7 @@ void MADSEngine::initialise() {
_font = new Font();
_screen.init();
_sound = new SoundManager(this, _mixer);
+ _audio = new AudioPlayer(_mixer, getGameID());
_game = Game::init(this);
_screen.empty();
diff --git a/engines/mads/mads.h b/engines/mads/mads.h
index d6a2a848bc..61d61a2564 100644
--- a/engines/mads/mads.h
+++ b/engines/mads/mads.h
@@ -98,6 +98,7 @@ public:
Resources *_resources;
ScreenSurface _screen;
SoundManager *_sound;
+ AudioPlayer *_audio;
bool _easyMouse;
bool _invObjectsAnimated;
bool _textWindowStill;
diff --git a/engines/mads/module.mk b/engines/mads/module.mk
index e5b9efefc8..9d5857904e 100644
--- a/engines/mads/module.mk
+++ b/engines/mads/module.mk
@@ -17,6 +17,7 @@ MODULE_OBJS := \
action.o \
animation.o \
assets.o \
+ audio.o \
compression.o \
debugger.o \
detection.o \