Permalink
Browse files

STARTREK: Implement sound effects in the midis

Removed amiga and mac sound code for now since I can't test it.
  • Loading branch information...
Drenn1 authored and sev- committed May 6, 2018
1 parent fd26d0a commit 9c2ed1d9b72036b1d1a052b1a4826cc8402bbb21
Showing with 173 additions and 124 deletions.
  1. +95 −96 engines/startrek/sound.cpp
  2. +22 −15 engines/startrek/sound.h
  3. +51 −10 engines/startrek/startrek.cpp
  4. +3 −1 engines/startrek/startrek.h
  5. +2 −2 engines/startrek/text.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,154 +33,157 @@ 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)
playMacSMFSound(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
@@ -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);
};

}
@@ -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() {
Oops, something went wrong.

0 comments on commit 9c2ed1d

Please sign in to comment.