diff options
-rwxr-xr-x | engines/startrek/sound.cpp | 191 | ||||
-rwxr-xr-x | engines/startrek/sound.h | 37 | ||||
-rwxr-xr-x | engines/startrek/startrek.cpp | 61 | ||||
-rwxr-xr-x | engines/startrek/startrek.h | 4 | ||||
-rw-r--r-- | engines/startrek/text.cpp | 4 |
5 files changed, 173 insertions, 124 deletions
diff --git a/engines/startrek/sound.cpp b/engines/startrek/sound.cpp index 5191fc404c..436316233b 100755 --- a/engines/startrek/sound.cpp +++ b/engines/startrek/sound.cpp @@ -17,10 +17,6 @@ * 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. - * - * $URL: https://scummvm-startrek.googlecode.com/svn/trunk/sound.cpp $ - * $Id: sound.cpp 15 2010-06-27 06:13:42Z clone2727 $ - * */ #include "startrek/sound.h" @@ -37,38 +33,78 @@ namespace StarTrek { Sound::Sound(StarTrekEngine *vm) : _vm(vm) { if (_vm->getPlatform() == Common::kPlatformDOS || _vm->getPlatform() == Common::kPlatformMacintosh) { - // The main PC versions use XMIDI. ST25 Demo and Macintosh versions use SMF. - if ((_vm->getGameType() == GType_ST25 && _vm->getFeatures() & GF_DEMO) || _vm->getPlatform() == Common::kPlatformMacintosh) - _midiParser = MidiParser::createParser_SMF(); - else - _midiParser = MidiParser::createParser_XMIDI(); - _midiDevice = MidiDriver::detectDevice(MDT_PCSPK|MDT_ADLIB|MDT_MIDI); _midiDriver = MidiDriver::createMidi(_midiDevice); _midiDriver->open(); - _midiParser->setMidiDriver(_midiDriver); - _midiParser->setTimerRate(_midiDriver->getBaseTempo()); - } + _midiDriver->setTimerCallback(this, Sound::midiDriverCallback); - if (_vm->getPlatform() == Common::kPlatformMacintosh) { - _macAudioResFork = new Common::MacResManager(); - if (!_macAudioResFork->open("Star Trek Audio")) - error("Could not open 'Star Trek Audio'"); - assert(_macAudioResFork->hasResFork()); - } else - _macAudioResFork = 0; + for (int i=0; i<8; i++) { + _midiSlots[i].slot = i; + _midiSlots[i].track = -1; + + // The main PC versions use XMIDI. ST25 Demo and Macintosh versions use SMF. + if ((_vm->getGameType() == GType_ST25 && _vm->getFeatures() & GF_DEMO) || _vm->getPlatform() == Common::kPlatformMacintosh) + _midiSlots[i].midiParser = MidiParser::createParser_SMF(); + else + _midiSlots[i].midiParser = MidiParser::createParser_XMIDI(); + + _midiSlots[i].midiParser->setMidiDriver(_midiDriver); + _midiSlots[i].midiParser->setTimerRate(_midiDriver->getBaseTempo()); + } + } _soundHandle = new Audio::SoundHandle(); + loadedSoundData = nullptr; + + for (int i=1; i<8; i++) { + _sfxSlotList.push_back(&_midiSlots[i]); + } } Sound::~Sound() { - delete _midiParser; + for (int i=0; i<8; i++) + delete _midiSlots[i].midiParser; delete _midiDriver; delete _soundHandle; - delete _macAudioResFork; + delete[] loadedSoundData; +} + + +void Sound::playMidiTrack(int track) { + if (!_vm->_midiAudioEnabled) + return; + /* + if (!_vm->_word_467a8) + return; + */ + + assert(loadedSoundData != NULL); + + // Check if a midi slot for this track exists already + for (int i=1; i<8; i++) { + if (_midiSlots[i].track == track) { + _midiSlots[i].midiParser->loadMusic(loadedSoundData, sizeof(loadedSoundData)); + _midiSlots[i].midiParser->setTrack(track); + + // Shift this to the back (most recently used) + _sfxSlotList.remove(&_midiSlots[i]); + _sfxSlotList.push_back(&_midiSlots[i]); + return; + } + } + + // Take the least recently used slot and use that for the sound effect + MidiSlot *slot = _sfxSlotList.front(); + _sfxSlotList.pop_front(); + _sfxSlotList.push_back(slot); + slot->track = track; + slot->midiParser->loadMusic(loadedSoundData, sizeof(loadedSoundData)); + slot->midiParser->setTrack(track); } -void Sound::playSound(const char *baseSoundName) { +void Sound::loadMusicFile(const char *baseSoundName) { + clearAllMidiSlots(); + /* if (_vm->getPlatform() == Common::kPlatformAmiga) playAmigaSound(baseSoundName); else if (_vm->getPlatform() == Common::kPlatformMacintosh) @@ -76,115 +112,78 @@ void Sound::playSound(const char *baseSoundName) { else if (_vm->getFeatures() & GF_DEMO) playSMFSound(baseSoundName); else - playXMIDISound(baseSoundName); + */ + loadPCMusicFile(baseSoundName); } void Sound::playSoundEffect(const char *baseSoundName) { + /* if (_vm->getPlatform() == Common::kPlatformAmiga) playAmigaSoundEffect(baseSoundName); else if (_vm->getPlatform() == Common::kPlatformMacintosh) playMacSoundEffect(baseSoundName); else - error("PC Sound Effects Not Supported"); + */ + error("PC Sound Effects Not Supported"); } // PC Functions -void Sound::playSMFSound(const char *baseSoundName) { - Common::String soundName = baseSoundName; - - soundName += '.'; - - switch (MidiDriver::getMusicType(_midiDevice)) { - case MT_MT32: - soundName += "ROL"; - break; - case MT_PCSPK: - return; // Not supported... - default: - soundName += "ADL"; - break; - } - - debug(0, "Playing sound \'%s\'\n", soundName.c_str()); - SharedPtr<Common::SeekableReadStream> soundStream = _vm->openFile(soundName.c_str()); - - byte *soundData = (byte *)malloc(soundStream->size()); - soundStream->read(soundData, soundStream->size()); - _midiParser->loadMusic(soundData, soundStream->size()); - - _midiDriver->setTimerCallback(_midiParser, MidiParser::timerCallback); -} -void Sound::playXMIDISound(const char *baseSoundName) { +// XMIDI or SM sound +void Sound::loadPCMusicFile(const char *baseSoundName) { Common::String soundName = baseSoundName; soundName += '.'; switch (MidiDriver::getMusicType(_midiDevice)) { case MT_MT32: - soundName += "MT"; + if (_vm->getFeatures() & GF_DEMO) + soundName += "ROL"; + else + soundName += "MT"; break; case MT_PCSPK: - soundName += "PC"; + if (_vm->getFeatures() & GF_DEMO) + return; // Not supported... + else + soundName += "PC"; break; default: - soundName += "AD"; + if (_vm->getFeatures() & GF_DEMO) + soundName += "ADL"; + else + soundName += "AD"; break; } debug(0, "Playing sound \'%s\'\n", soundName.c_str()); SharedPtr<Common::SeekableReadStream> soundStream = _vm->openFile(soundName.c_str()); - byte *soundData = (byte *)malloc(soundStream->size()); - soundStream->read(soundData, soundStream->size()); - _midiParser->loadMusic(soundData, soundStream->size()); - - _midiDriver->setTimerCallback(_midiParser, MidiParser::timerCallback); + if (loadedSoundData != nullptr) + delete[] loadedSoundData; + loadedSoundData = new byte[soundStream->size()]; + soundStream->read(loadedSoundData, soundStream->size()); + _midiSlots[0].midiParser->loadMusic(loadedSoundData, soundStream->size()); } -// Amiga Functions - -void Sound::playAmigaSound(const char *baseSoundName) { - // Nope, this is wrong... see http://protracker.de/files/amiga/formats/theplayer_41_format.txt -#if 0 - Common::String soundName = baseSoundName; - soundName += ".SNG"; - if (_vm->_mixer->isSoundHandleActive(*_soundHandle)) - _vm->_mixer->stopHandle(*_soundHandle); - _vm->_mixer->playInputStream(Audio::Mixer::kMusicSoundType, _soundHandle, Audio::makeProtrackerStream(_vm->openFile(soundName.c_str()))); -#endif +void Sound::clearMidiSlot(int slot) { + _midiSlots[slot].midiParser->stopPlaying(); + _midiSlots[slot].midiParser->unloadMusic(); + _midiSlots[slot].track = -1; } -void Sound::playAmigaSoundEffect(const char *baseSoundName) { - Common::String soundName = baseSoundName; - soundName += ".SFX"; - - if (_vm->_mixer->isSoundHandleActive(*_soundHandle)) - _vm->_mixer->stopHandle(*_soundHandle); - - Audio::AudioStream *audStream = (Audio::AudioStream *)Audio::makeRawStream(_vm->openFile(soundName.c_str()).get(), 11025, 0); - _vm->_mixer->playStream(Audio::Mixer::kSFXSoundType, _soundHandle, audStream); +void Sound::clearAllMidiSlots() { + for (int i=0; i<8; i++) { + clearMidiSlot(i); + } } -// Macintosh Functions - -void Sound::playMacSMFSound(const char *baseSoundName) { - Common::SeekableReadStream *soundStream = _macAudioResFork->getResource(baseSoundName); - byte *soundData = (byte *)malloc(soundStream->size()); - soundStream->read(soundData, soundStream->size()); - _midiParser->loadMusic(soundData, soundStream->size()); - delete soundStream; - - _midiDriver->setTimerCallback(_midiParser, MidiParser::timerCallback); +void Sound::midiDriverCallback(void *data) { + Sound *s = (Sound*)data; + for (int i=0; i<8; i++) + s->_midiSlots[i].midiParser->onTimer(); } -void Sound::playMacSoundEffect(const char *baseSoundName) { - if (_vm->_mixer->isSoundHandleActive(*_soundHandle)) - _vm->_mixer->stopHandle(*_soundHandle); - - Audio::AudioStream *audStream = (Audio::AudioStream *)Audio::makeRawStream(_macAudioResFork->getResource(baseSoundName), 11025, 0); - _vm->_mixer->playStream(Audio::Mixer::kSFXSoundType, _soundHandle, audStream); -} } // End of namespace StarTrek diff --git a/engines/startrek/sound.h b/engines/startrek/sound.h index f8f9b88696..f314f2c688 100755 --- a/engines/startrek/sound.h +++ b/engines/startrek/sound.h @@ -40,35 +40,42 @@ namespace StarTrek { class StarTrekEngine; + +struct MidiSlot { + int slot; + int track; + MidiParser *midiParser; +}; + class Sound { public: Sound(StarTrekEngine *vm); ~Sound(); - void playSound(const char *baseSoundName); - void playSoundEffect(const char *baseSoundName); + void playMidiTrack(int track); + + void loadMusicFile(const char *baseSoundName); + void playSoundEffect(const char *baseSoundName); private: StarTrekEngine *_vm; Audio::SoundHandle *_soundHandle; - // PC Sound Functions - void playXMIDISound(const char *baseSoundName); - void playSMFSound(const char *baseSoundName); - - // Macintosh Sound Functions - void playMacSMFSound(const char *baseSoundName); - void playMacSoundEffect(const char *baseSoundName); - Common::MacResManager *_macAudioResFork; - - // Amiga Sound Functions - void playAmigaSound(const char *baseSoundName); - void playAmigaSoundEffect(const char *baseSoundName); + void loadPCMusicFile(const char *baseSoundName); + void clearMidiSlot(int slot); + void clearAllMidiSlots(); // MIDI-Related Variables - MidiParser *_midiParser; MidiDriver *_midiDriver; + MidiSlot _midiSlots[8]; // 0 is for music; 1-7 are for sfx + Common::List<MidiSlot*> _sfxSlotList; // Sorts midi slots by most recently used + + byte *loadedSoundData; uint32 _midiDevice; + + + // Driver callback + static void midiDriverCallback(void *data); }; } diff --git a/engines/startrek/startrek.cpp b/engines/startrek/startrek.cpp index 1b333b925a..dba8a48756 100755 --- a/engines/startrek/startrek.cpp +++ b/engines/startrek/startrek.cpp @@ -101,14 +101,7 @@ Common::Error StarTrekEngine::run() { _gfx->loadPri("DEMON0.PRI"); _gfx->redrawScreen(); - if (getPlatform() == Common::kPlatformAmiga) - _sound->playSoundEffect("TREK2"); - else if (getPlatform() == Common::kPlatformMacintosh) - _sound->playSound("title 2"); - else if (getFeatures() & GF_DEMO) - _sound->playSound("STTITLE"); - else - _sound->playSound("TITLE"); + _sound->loadMusicFile("BRIDGEW"); } else { _gfx->drawBackgroundImage("BRIDGE.BGD"); } @@ -197,8 +190,56 @@ void StarTrekEngine::pollSystemEvents() { _system->delayMillis(1000/60); } -void StarTrekEngine::playSound(int id) { - // TODO +void StarTrekEngine::playSoundEffectIndex(int index) { + switch(index-4) { + case 0: + _sound->playSoundEffect("tricorde"); + break; + case 1: + _sound->playSoundEffect("STDOOR1"); + break; + case 2: + _sound->playSoundEffect("PHASSHOT"); + break; + case 3: + _sound->playMidiTrack(index); + break; + case 4: + _sound->playSoundEffect("TRANSDEM"); + break; + case 5: + _sound->playSoundEffect("TRANSMAT"); + break; + case 6: + _sound->playSoundEffect("TRANSENE"); + break; + case 0x0c: // Menu selection sound + _sound->playMidiTrack(index); + break; + case 0x1e: + _sound->playSoundEffect("HAILING"); + break; + case 0x20: + _sound->playSoundEffect("PHASSHOT"); + break; + case 0x21: + _sound->playSoundEffect("PHOTSHOT"); + break; + case 0x22: + _sound->playSoundEffect("HITSHIEL"); + break; + case 0x23: + _sound->playMidiTrack(index); + break; + case 0x24: + _sound->playSoundEffect("REDALERT"); + break; + case 0x25: + _sound->playSoundEffect("WARP"); + break; + default: + break; + } } void StarTrekEngine::updateClockTicks() { diff --git a/engines/startrek/startrek.h b/engines/startrek/startrek.h index a0b97b9760..c190659d6a 100755 --- a/engines/startrek/startrek.h +++ b/engines/startrek/startrek.h @@ -91,7 +91,7 @@ public: Room *getRoom(); void pollSystemEvents(); - void playSound(int id); // TODO: rename, figure out what it is + void playSoundEffectIndex(int index); // Events public: @@ -137,6 +137,8 @@ public: bool _midiAudioEnabled; bool _cdAudioEnabled; + uint16 _word_467a6; + uint16 _word_467a8; bool _textboxVar4; diff --git a/engines/startrek/text.cpp b/engines/startrek/text.cpp index 6ac31b02a4..fe2f0eeb6c 100644 --- a/engines/startrek/text.cpp +++ b/engines/startrek/text.cpp @@ -328,13 +328,13 @@ int Graphics::handleTextboxEvents(uint32 ticksUntilClickingEnabled, bool arg4) { case TREKEVENT_LBUTTONDOWN: if (_activeMenu->selectedButton != -1) { - _vm->playSound(0x10); + _vm->playSoundEffectIndex(0x10); return _activeMenu->retvals[_activeMenu->selectedButton]; } else { Common::Point mouse = getMousePos(); if (getMenuButtonAt(*_activeMenu, mouse.x, mouse.y) == -1) { - _vm->playSound(0x10); + _vm->playSoundEffectIndex(0x10); return TEXTEVENT_LCLICK_OFFBUTTON; } } |