diff options
Diffstat (limited to 'engines/mads')
-rw-r--r-- | engines/mads/audio.cpp | 129 | ||||
-rw-r--r-- | engines/mads/audio.h | 64 | ||||
-rw-r--r-- | engines/mads/debugger.cpp | 19 | ||||
-rw-r--r-- | engines/mads/debugger.h | 1 | ||||
-rw-r--r-- | engines/mads/game.h | 1 | ||||
-rw-r--r-- | engines/mads/mads.cpp | 1 | ||||
-rw-r--r-- | engines/mads/mads.h | 1 | ||||
-rw-r--r-- | engines/mads/module.mk | 1 |
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 \ |