aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rwxr-xr-xengines/startrek/sound.cpp191
-rwxr-xr-xengines/startrek/sound.h37
-rwxr-xr-xengines/startrek/startrek.cpp61
-rwxr-xr-xengines/startrek/startrek.h4
-rw-r--r--engines/startrek/text.cpp4
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;
}
}