diff options
-rw-r--r-- | engines/supernova/module.mk | 1 | ||||
-rw-r--r-- | engines/supernova/msn_def.h | 29 | ||||
-rw-r--r-- | engines/supernova/rooms.cpp | 24 | ||||
-rw-r--r-- | engines/supernova/sound.cpp | 79 | ||||
-rw-r--r-- | engines/supernova/sound.h | 81 | ||||
-rw-r--r-- | engines/supernova/state.cpp | 50 | ||||
-rw-r--r-- | engines/supernova/state.h | 4 | ||||
-rw-r--r-- | engines/supernova/supernova.cpp | 44 | ||||
-rw-r--r-- | engines/supernova/supernova.h | 7 |
9 files changed, 219 insertions, 100 deletions
diff --git a/engines/supernova/module.mk b/engines/supernova/module.mk index 9baf196c7c..520c3ae8ce 100644 --- a/engines/supernova/module.mk +++ b/engines/supernova/module.mk @@ -6,6 +6,7 @@ MODULE_OBJS := \ graphics.o \ supernova.o \ rooms.o \ + sound.o \ state.o MODULE_DIRS += \ diff --git a/engines/supernova/msn_def.h b/engines/supernova/msn_def.h index c18baa068c..22a73582f6 100644 --- a/engines/supernova/msn_def.h +++ b/engines/supernova/msn_def.h @@ -50,35 +50,6 @@ enum MessagePosition { kMessageTop }; -enum AudioIndex { - kAudioFoundLocation, // 44|0 - kAudioCrash, // 45|0 - kAudioVoiceHalt, // 46|0 - kAudioGunShot, // 46|2510 - kAudioSmash, // 46|4020 - kAudioVoiceSupernova, // 47|0 - kAudioVoiceYeah, // 47|24010 - kAudioRobotShock, // 48|0 - kAudioRobotBreaks, // 48|2510 - kAudioShock, // 48|10520 - kAudioTurntable, // 48|13530 - kAudioSiren, // 50|0 - kAudioSnoring, // 50|12786 - kAudioRocks, // 51|0 - kAudioDeath, // 53|0 - kAudioAlarm, // 54|0 - kAudioSuccess, // 54|8010 - kAudioSlideDoor, // 54|24020 - kAudioDoorOpen, // 54|30030 - kAudioDoorClose, // 54|31040 - kAudioNumSamples -}; - -enum MusicIndex { - kMusicIntro = 52, - kMusicOutro = 49 -}; - struct AudioInfo { int _filenumber; int _offsetStart; diff --git a/engines/supernova/rooms.cpp b/engines/supernova/rooms.cpp index ad42a171a2..0e1841199f 100644 --- a/engines/supernova/rooms.cpp +++ b/engines/supernova/rooms.cpp @@ -256,7 +256,7 @@ void Intro::titleScreen() { _vm->paletteFadeIn(); _gm->wait(1); _vm->playSound(kAudioVoiceSupernova); - while (_vm->_mixer->isSoundHandleActive(_vm->_soundHandle)) + while (_vm->_sound->isPlaying()) _gm->wait(1); titleFadeIn(); _vm->renderText(kStringTitleVersion, 295, 190, kColorWhite44); @@ -268,7 +268,7 @@ void Intro::titleScreen() { _vm->renderText(title3, 78 - _vm->textWidth(title3) / 2, 142, kColorWhite99); _gm->wait(1); CursorMan.showMouse(true); - _vm->playSoundMod(kMusicIntro); + _vm->playSound(kMusicIntro); Marquee marquee(_vm, Marquee::kMarqueeIntro, _introText.c_str()); while (!_vm->shouldQuit()) { @@ -280,7 +280,7 @@ void Intro::titleScreen() { g_system->delayMillis(_vm->_delay); } _vm->playSound(kAudioVoiceYeah); - while (_vm->_mixer->isSoundHandleActive(_vm->_soundHandle)) + while (_vm->_sound->isPlaying()) _gm->wait(1); _vm->paletteFadeOut(); } @@ -527,7 +527,7 @@ void Intro::cutscene() { return; _vm->paletteFadeOut(); - while (_vm->_mixer->isSoundHandleActive(_vm->_soundHandle)) + while (_vm->_sound->isPlaying()) exitOnEscape(1); _vm->_system->fillScreen(kColorBlack); @@ -562,15 +562,15 @@ void Intro::cutscene() { _vm->paletteBrightness(); exitOnEscape(10); _vm->playSound(kAudioSnoring); - while (_vm->_mixer->isSoundHandleActive(_vm->_soundHandle)) + while (_vm->_sound->isPlaying()) _gm->wait(1); exitOnEscape(10); _vm->playSound(kAudioSnoring); - while (_vm->_mixer->isSoundHandleActive(_vm->_soundHandle)) + while (_vm->_sound->isPlaying()) _gm->wait(1); exitOnEscape(10); _vm->playSound(kAudioSnoring); - while (_vm->_mixer->isSoundHandleActive(_vm->_soundHandle)) + while (_vm->_sound->isPlaying()) _gm->wait(1); exitOnEscape(30); CursorMan.showMouse(true); @@ -1004,7 +1004,7 @@ bool ShipCabinL3::interact(Action verb, Object &obj1, Object &obj2) { setSectionVisible(15, false); for (int i = 3; i; i--) { _vm->playSound(kAudioTurntable); - while (_vm->_mixer->isSoundHandleActive(_vm->_soundHandle)) { + while (_vm->_sound->isPlaying()) { if (isSectionVisible(13)) { _vm->renderImage(14); setSectionVisible(13, false); @@ -2362,7 +2362,7 @@ bool ArsanoMeetup3::interact(Action verb, Object &obj1, Object &obj2) { _vm->renderImage(4); _vm->playSound(kAudioGunShot); - while (_vm->_mixer->isSoundHandleActive(_vm->_soundHandle)) + while (_vm->_sound->isPlaying()) _gm->wait(1); _vm->renderImage(5); @@ -2370,7 +2370,7 @@ bool ArsanoMeetup3::interact(Action verb, Object &obj1, Object &obj2) { _vm->renderImage(4); _vm->playSound(kAudioGunShot); - while (_vm->_mixer->isSoundHandleActive(_vm->_soundHandle)) + while (_vm->_sound->isPlaying()) _gm->wait(1); _vm->renderImage(5); @@ -2604,7 +2604,7 @@ bool AxacussCell::interact(Action verb, Object &obj1, Object &obj2) { return false; _vm->playSound(kAudioGunShot); - while (_vm->_mixer->isSoundHandleActive(_vm->_soundHandle)) + while (_vm->_sound->isPlaying()) _gm->wait(1); _vm->playSound(kAudioGunShot); @@ -3295,7 +3295,7 @@ void Outro::onEntrance() { _vm->renderImage(_gm->invertSection(i)); } - _vm->playSoundMod(kMusicOutro); + _vm->playSound(kMusicOutro); Marquee marquee(_vm, Marquee::kMarqueeOutro, _outroText.c_str()); while (!_vm->shouldQuit()) { _gm->updateEvents(); diff --git a/engines/supernova/sound.cpp b/engines/supernova/sound.cpp new file mode 100644 index 0000000000..a306a4819a --- /dev/null +++ b/engines/supernova/sound.cpp @@ -0,0 +1,79 @@ +/* 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 "audio/audiostream.h" +#include "audio/mixer.h" +#include "audio/decoders/raw.h" +#include "audio/mods/protracker.h" +#include "common/system.h" + +#include "supernova/sound.h" +#include "supernova/supernova.h" + +namespace Supernova { + +Sound::Sound(SupernovaEngine *vm, Audio::Mixer *mixer) + : _mixer(mixer) + , _vm(vm) + , _rate(11931) { +} + +void Sound::play(AudioIndex index) { + Audio::AudioStream *stream; + byte flags = Audio::FLAG_LITTLE_ENDIAN | Audio::FLAG_UNSIGNED; + stream = Audio::makeRawStream(_vm->_soundSamples[index]._buffer, + _vm->_soundSamples[index]._length, + _rate, flags); + + stop(); + _mixer->playStream(Audio::Mixer::kPlainSoundType, &_soundHandle, stream, + -1, Audio::Mixer::kMaxChannelVolume, 0, DisposeAfterUse::NO); +} + +void Sound::play(MusicIndex index) { + Audio::AudioStream *stream; + switch (index) { + case kMusicIntro: + stream = Audio::makeProtrackerStream(_vm->_soundMusicIntro); + break; + case kMusicOutro: + stream = Audio::makeProtrackerStream(_vm->_soundMusicOutro); + break; + default: + error("Reuqested music file does not exist"); + } + + stop(); + _mixer->playStream(Audio::Mixer::kMusicSoundType, &_soundHandle, stream, + -1, Audio::Mixer::kMaxChannelVolume, 0, DisposeAfterUse::NO); +} + +bool Sound::isPlaying() { + return _mixer->isSoundHandleActive(_soundHandle); +} + +void Sound::stop() { + if (_mixer->isSoundHandleActive(_soundHandle)) + _mixer->stopHandle(_soundHandle); +} + +} diff --git a/engines/supernova/sound.h b/engines/supernova/sound.h new file mode 100644 index 0000000000..a486fe5b59 --- /dev/null +++ b/engines/supernova/sound.h @@ -0,0 +1,81 @@ +/* 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 SUPERNOVA_SOUND_H +#define SUPERNOVA_SOUND_H + +#include "audio/mixer.h" + +namespace Supernova { + +class SupernovaEngine; +class ResourceManager; + +enum AudioIndex { + kAudioFoundLocation, // 44|0 + kAudioCrash, // 45|0 + kAudioVoiceHalt, // 46|0 + kAudioGunShot, // 46|2510 + kAudioSmash, // 46|4020 + kAudioVoiceSupernova, // 47|0 + kAudioVoiceYeah, // 47|24010 + kAudioRobotShock, // 48|0 + kAudioRobotBreaks, // 48|2510 + kAudioShock, // 48|10520 + kAudioTurntable, // 48|13530 + kAudioSiren, // 50|0 + kAudioSnoring, // 50|12786 + kAudioRocks, // 51|0 + kAudioDeath, // 53|0 + kAudioAlarm, // 54|0 + kAudioSuccess, // 54|8010 + kAudioSlideDoor, // 54|24020 + kAudioDoorOpen, // 54|30030 + kAudioDoorClose, // 54|31040 + kAudioNumSamples +}; + +enum MusicIndex { + kMusicIntro = 49, + kMusicOutro = 52 +}; + +class Sound { +public: + +public: + Sound(SupernovaEngine *vm, Audio::Mixer *mixer); + + void play(AudioIndex index); + void play(MusicIndex index); + void stop(); + bool isPlaying(); +private: + Audio::Mixer *_mixer; + SupernovaEngine *_vm; + Audio::SoundHandle _soundHandle; + int _rate; +}; + +} + +#endif diff --git a/engines/supernova/state.cpp b/engines/supernova/state.cpp index 08b6d2b63a..2e887660ed 100644 --- a/engines/supernova/state.cpp +++ b/engines/supernova/state.cpp @@ -285,9 +285,10 @@ StringID GameManager::guiStatusCommands[] = { kStringStatusCommandPress, kStringStatusCommandPull, kStringStatusCommandUse, kStringStatusCommandTalk, kStringStatusCommandGive }; -GameManager::GameManager(SupernovaEngine *vm) +GameManager::GameManager(SupernovaEngine *vm, Sound *sound) : _inventory(_inventoryScroll) - , _vm(vm) { + , _vm(vm) + , _sound(sound) { initRooms(); changeRoom(INTRO); initState(); @@ -556,8 +557,7 @@ void GameManager::updateEvents() { case Common::EVENT_LBUTTONUP: // fallthrough case Common::EVENT_RBUTTONUP: - if (_currentRoom->getId() != INTRO && - _vm->_mixer->isSoundHandleActive(_vm->_soundHandle)) + if (_currentRoom->getId() != INTRO && _sound->isPlaying()) return; _mouseClicked = true; // fallthrough @@ -1021,13 +1021,13 @@ void GameManager::busted(int i) { i = 5; if (!_currentRoom->getObject(0)->hasProperty(OPENED)) { _vm->renderImage(i - 1); - _vm->playSound(kAudioDoorOpen); + _sound->play(kAudioDoorOpen); wait(2); } _vm->renderImage(i); wait(3); _vm->renderImage(i + 3); - _vm->playSound(kAudioVoiceHalt); + _sound->play(kAudioVoiceHalt); _vm->renderImage(i); wait(5); if (_currentRoom->getId() == OFFICE_L2) @@ -1047,7 +1047,7 @@ void GameManager::busted(int i) { else _vm->renderImage(33); // above } - _vm->playSound(kAudioVoiceHalt); + _sound->play(kAudioVoiceHalt); wait(3); shot(0, 0); } @@ -1210,7 +1210,7 @@ void GameManager::guardWalkEvent() { if (!behind) { _vm->renderImage(_state._origin + 1); _prevImgId = _state._origin + 1; - _vm->playSound(kAudioDoorOpen); + _sound->play(kAudioDoorOpen); wait(3); } @@ -1234,7 +1234,7 @@ void GameManager::guardWalkEvent() { if (!behind) { wait(3); _vm->renderImage(_prevImgId + 128); - _vm->playSound(kAudioDoorClose); + _sound->play(kAudioDoorClose); } _prevImgId = imgId; @@ -1295,12 +1295,12 @@ void GameManager::guardWalkEvent() { if (behind) { _vm->renderImage(_state._destination + 1); - _vm->playSound(kAudioDoorOpen); + _sound->play(kAudioDoorOpen); wait(3); _vm->renderImage(_prevImgId + 128); wait(3); _vm->renderImage(_state._destination + 1 + 128); - _vm->playSound(kAudioDoorClose); + _sound->play(kAudioDoorClose); _rooms[BCORRIDOR]->getObject(_state._destination + 4)->setProperty(OCCUPIED); _state._destination = 255; } else if (_rooms[BCORRIDOR]->isSectionVisible(_state._destination + 1)) { @@ -1340,7 +1340,7 @@ void GameManager::taxiEvent() { _vm->renderImage(1); _vm->renderImage(2); - _vm->playSound(kAudioRocks); + _sound->play(kAudioRocks); screenShake(); _vm->renderImage(9); _currentRoom->getObject(1)->setProperty(OPENED); @@ -1366,7 +1366,7 @@ void GameManager::great(uint number) { if (number && (_state._greatFlag & (1 << number))) return; - _vm->playSound(kAudioSuccess); + _sound->play(kAudioSuccess); _state._greatFlag |= 1 << number; } @@ -1729,7 +1729,7 @@ void GameManager::screenShake() { } void GameManager::shock() { - _vm->playSound(kAudioShock); + _sound->play(kAudioShock); dead(kStringShock); } @@ -1837,14 +1837,14 @@ void GameManager::edit(Common::String &input, int x, int y, uint length) { void GameManager::shot(int a, int b) { if (a) _vm->renderImage(a); - _vm->playSound(kAudioGunShot); + _sound->play(kAudioGunShot); wait(2); if (b) _vm->renderImage(b); wait(2); if (a) _vm->renderImage(a); - _vm->playSound(kAudioGunShot); + _sound->play(kAudioGunShot); wait(2); if (b) _vm->renderImage(b); @@ -1908,7 +1908,7 @@ void GameManager::dead(StringID messageId) { _vm->setCurrentImage(11); _vm->renderImage(0); _vm->renderMessage(messageId); - _vm->playSound(kAudioDeath); + _sound->play(kAudioDeath); _vm->paletteFadeIn(); getInput(); _vm->paletteFadeOut(); @@ -2261,7 +2261,7 @@ void GameManager::handleInput() { byte i = _inputObject[0]->_click; _inputObject[0]->_click = _inputObject[0]->_click2; _inputObject[0]->_click2 = i; - _vm->playSound(kAudioDoorOpen); + _sound->play(kAudioDoorOpen); } break; @@ -2280,7 +2280,7 @@ void GameManager::handleInput() { byte i = _inputObject[0]->_click; _inputObject[0]->_click = _inputObject[0]->_click2; _inputObject[0]->_click2 = i; - _vm->playSound(kAudioDoorClose); + _sound->play(kAudioDoorClose); } break; @@ -2341,8 +2341,8 @@ void GameManager::guardShot() { wait(3); _vm->renderImage(2); - _vm->playSound(kAudioVoiceHalt); - while (_vm->_mixer->isSoundHandleActive(_vm->_soundHandle)) + _sound->play(kAudioVoiceHalt); + while (_sound->isPlaying()) wait(1); _vm->renderImage(5); @@ -2356,8 +2356,8 @@ void GameManager::guardShot() { void GameManager::guard3Shot() { _vm->renderImage(1); wait(3); - _vm->playSound(kAudioVoiceHalt); // 46/0 - while (_vm->_mixer->isSoundHandleActive(_vm->_soundHandle)) + _sound->play(kAudioVoiceHalt); // 46/0 + while (_sound->isPlaying()) wait(1); wait(5); @@ -2408,8 +2408,8 @@ void GameManager::alarmSound() { int32 end = _state._time + ticksToMsec(_messageDuration); do { - _vm->playSound(kAudioAlarm); - while (_vm->_mixer->isSoundHandleActive(_vm->_soundHandle)) { + _sound->play(kAudioAlarm); + while (_sound->isPlaying()) { g_system->delayMillis(_vm->_delay); updateEvents(); g_system->updateScreen(); diff --git a/engines/supernova/state.h b/engines/supernova/state.h index b805369160..46387811d1 100644 --- a/engines/supernova/state.h +++ b/engines/supernova/state.h @@ -26,6 +26,7 @@ #include "common/rect.h" #include "common/keyboard.h" #include "supernova/rooms.h" +#include "supernova/sound.h" namespace Supernova { @@ -121,7 +122,7 @@ private: class GameManager { public: - GameManager(SupernovaEngine *vm); + GameManager(SupernovaEngine *vm, Sound *sound); ~GameManager(); void updateEvents(); @@ -134,6 +135,7 @@ public: static StringID guiCommands[]; static StringID guiStatusCommands[]; SupernovaEngine *_vm; + Sound *_sound; Common::KeyState _key; Common::EventType _mouseClickType; bool _mouseClicked; diff --git a/engines/supernova/supernova.cpp b/engines/supernova/supernova.cpp index 248fb2a818..7ac8d59245 100644 --- a/engines/supernova/supernova.cpp +++ b/engines/supernova/supernova.cpp @@ -42,6 +42,7 @@ #include "graphics/thumbnail.h" #include "gui/saveload.h" +#include "supernova/sound.h" #include "supernova/supernova.h" #include "supernova/state.h" @@ -130,6 +131,7 @@ SupernovaEngine::~SupernovaEngine() { delete _currentImage; delete _console; delete _gm; + delete _sound; delete _soundMusicIntro; delete _soundMusicOutro; } @@ -145,12 +147,13 @@ Common::Error SupernovaEngine::run() { if (status.getCode() != Common::kNoError) return status; - _gm = new GameManager(this); - _console = new Console(this, _gm); - initData(); initPalette(); + _sound = new Sound(this, _mixer); + _gm = new GameManager(this, _sound); + _console = new Console(this, _gm); + CursorMan.replaceCursor(_mouseNormal, 16, 16, 0, 0, kColorCursorTransparent); CursorMan.replaceCursorPalette(initVGAPalette, 0, 16); CursorMan.showMouse(true); @@ -174,7 +177,7 @@ Common::Error SupernovaEngine::run() { _system->delayMillis(end); } - stopSound(); + _mixer->stopAll(); return Common::kNoError; } @@ -283,8 +286,8 @@ void SupernovaEngine::initData() { file.close(); } - _soundMusicIntro = convertToMod("msn_data.049"); - _soundMusicOutro = convertToMod("msn_data.052"); + _soundMusicIntro = convertToMod("msn_data.052"); + _soundMusicOutro = convertToMod("msn_data.049"); // Cursor const uint16 *bufferNormal = reinterpret_cast<const uint16 *>(mouseNormal); @@ -309,34 +312,15 @@ void SupernovaEngine::initPalette() { } void SupernovaEngine::playSound(AudioIndex sample) { - if (sample > kAudioNumSamples - 1) - return; - - Audio::SeekableAudioStream *audioStream = Audio::makeRawStream( - _soundSamples[sample]._buffer, _soundSamples[sample]._length, - 11931, Audio::FLAG_UNSIGNED | Audio::FLAG_LITTLE_ENDIAN, DisposeAfterUse::NO); - stopSound(); - _mixer->playStream(Audio::Mixer::kPlainSoundType, &_soundHandle, audioStream); + _sound->play(sample); } -void SupernovaEngine::stopSound() { - if (_mixer->isSoundHandleActive(_soundHandle)) - _mixer->stopHandle(_soundHandle); +void SupernovaEngine::stopAudio() { + _sound->stop(); } -void SupernovaEngine::playSoundMod(int filenumber) -{ - Audio::AudioStream *audioStream; - if (filenumber == 49) - audioStream = Audio::makeProtrackerStream(_soundMusicIntro); - else if (filenumber == 52) - audioStream = Audio::makeProtrackerStream(_soundMusicOutro); - else - return; - - stopSound(); - _mixer->playStream(Audio::Mixer::kMusicSoundType, &_soundHandle, audioStream, - -1, Audio::Mixer::kMaxChannelVolume, 0); +void SupernovaEngine::playSound(MusicIndex index) { + _sound->play(index); } void SupernovaEngine::renderImageSection(int section) { diff --git a/engines/supernova/supernova.h b/engines/supernova/supernova.h index 2a71a111ae..2f21422fce 100644 --- a/engines/supernova/supernova.h +++ b/engines/supernova/supernova.h @@ -38,6 +38,7 @@ #include "supernova/graphics.h" #include "supernova/msn_def.h" #include "supernova/rooms.h" +#include "supernova/sound.h" namespace Supernova { @@ -101,7 +102,7 @@ public: Common::RandomSource _rnd; GameManager *_gm; Console *_console; - Audio::SoundHandle _soundHandle; + Sound *_sound; ScreenBufferStack _screenBuffer; byte _mouseNormal[256]; byte _mouseWait[256]; @@ -134,8 +135,8 @@ public: void paletteFadeOut(); void paletteBrightness(); void playSound(AudioIndex sample); - void playSoundMod(int filenumber); - void stopSound(); + void playSound(MusicIndex index); + void stopAudio(); void renderImageSection(int section); void renderImage(int section); bool setCurrentImage(int filenumber); |