diff options
| author | Matthew Stewart | 2018-05-07 16:40:13 -0400 | 
|---|---|---|
| committer | Eugene Sandulenko | 2018-08-09 08:37:30 +0200 | 
| commit | f43c5d468784b72c92e557c83b22c9c34f8ce497 (patch) | |
| tree | 0f904da33f76476c37763326c2f55c55f061b3f6 | |
| parent | 9c2ed1d9b72036b1d1a052b1a4826cc8402bbb21 (diff) | |
| download | scummvm-rg350-f43c5d468784b72c92e557c83b22c9c34f8ce497.tar.gz scummvm-rg350-f43c5d468784b72c92e557c83b22c9c34f8ce497.tar.bz2 scummvm-rg350-f43c5d468784b72c92e557c83b22c9c34f8ce497.zip | |
STARTREK: Implement CD Audio handling.
| -rwxr-xr-x | engines/startrek/graphics.cpp | 1 | ||||
| -rwxr-xr-x | engines/startrek/graphics.h | 1 | ||||
| -rwxr-xr-x | engines/startrek/sound.cpp | 90 | ||||
| -rwxr-xr-x | engines/startrek/sound.h | 17 | ||||
| -rwxr-xr-x | engines/startrek/startrek.cpp | 50 | ||||
| -rwxr-xr-x | engines/startrek/startrek.h | 9 | ||||
| -rw-r--r-- | engines/startrek/text.cpp | 38 | 
7 files changed, 164 insertions, 42 deletions
| diff --git a/engines/startrek/graphics.cpp b/engines/startrek/graphics.cpp index 029928d021..ed4113db40 100755 --- a/engines/startrek/graphics.cpp +++ b/engines/startrek/graphics.cpp @@ -49,6 +49,7 @@ Graphics::Graphics(StarTrekEngine *vm) : _vm(vm), _egaMode(false) {  	_backgroundImage = new Bitmap(_vm->openFile("DEMON0.BMP").get());  	_numSprites = 0; +	_textboxVar1 = 2;  	CursorMan.showMouse(true);  } diff --git a/engines/startrek/graphics.h b/engines/startrek/graphics.h index 578abdf705..47a0fbfe78 100755 --- a/engines/startrek/graphics.h +++ b/engines/startrek/graphics.h @@ -153,7 +153,6 @@ private:  	SharedPtr<Menu> _activeMenu;  	uint16 _textboxButtonVar4; -	uint16 _word_4B422;  };  } diff --git a/engines/startrek/sound.cpp b/engines/startrek/sound.cpp index 436316233b..32b31901b8 100755 --- a/engines/startrek/sound.cpp +++ b/engines/startrek/sound.cpp @@ -24,8 +24,10 @@  #include "common/file.h"  #include "common/macresman.h" -#include "audio/mods/protracker.h" +#include "audio/audiostream.h"  #include "audio/decoders/raw.h" +#include "audio/decoders/voc.h" +#include "audio/mods/protracker.h"  namespace StarTrek { @@ -59,6 +61,12 @@ Sound::Sound(StarTrekEngine *vm) : _vm(vm) {  	for (int i=1; i<8; i++) {  		_sfxSlotList.push_back(&_midiSlots[i]);  	} + +	if (!SearchMan.hasFile("voc/speech.mrk")) { +		error("Couldn't find 'voc/speech.mrk'. The 'trekcd/voc/' directory must be dumped from the CD"); +	} + +	_playingSpeech = false;  }  Sound::~Sound() { @@ -71,7 +79,7 @@ Sound::~Sound() {  void Sound::playMidiTrack(int track) { -	if (!_vm->_midiAudioEnabled) +	if (!_vm->_musicEnabled)  		return;  	/*  	if (!_vm->_word_467a8) @@ -94,7 +102,7 @@ void Sound::playMidiTrack(int track) {  	}  	// Take the least recently used slot and use that for the sound effect -	MidiSlot *slot = _sfxSlotList.front(); +	MidiPlaybackSlot *slot = _sfxSlotList.front();  	_sfxSlotList.pop_front();  	_sfxSlotList.push_back(slot);  	slot->track = track; @@ -124,10 +132,75 @@ void Sound::playSoundEffect(const char *baseSoundName) {  		playMacSoundEffect(baseSoundName);  	else  	*/ -	error("PC Sound Effects Not Supported"); +	if (scumm_stricmp(baseSoundName+4, "loop") == 0) +		_loopingAudioName = Common::String(baseSoundName); + +	if (!_vm->_sfxEnabled || !_vm->_audioEnabled) +		return; + +	/* +	if (word_5113a == 0) +		sub_2aaa3(); +	*/ + +	for (int i=0; i<MAX_SFX_PLAYING; i++) { +		if (_vm->_system->getMixer()->isSoundHandleActive(_sfxHandles[i])) +			continue; + +		Common::String soundName = Common::String("voc/sfx/") + baseSoundName + ".voc"; +		Common::SeekableReadStream *readStream = SearchMan.createReadStreamForMember(soundName); +		if (readStream == nullptr) +			error("Couldn't open '%s'", soundName.c_str()); + +		Audio::AudioStream *audioStream = Audio::makeVOCStream(readStream, Audio::FLAG_UNSIGNED, DisposeAfterUse::YES); +		_vm->_system->getMixer()->playStream(Audio::Mixer::kSFXSoundType, &_sfxHandles[i], audioStream); +		return; +	}  } -// PC Functions +void Sound::playSpeech(const Common::String &basename) { +	stopPlayingSpeech(); + +	Audio::QueuingAudioStream *audioQueue = nullptr; +	Common::String name = basename; + +	// Play a list of comma-separated audio files in sequence (usually there's only one) +	while (!name.empty()) { +		uint i = 0; +		while (i < name.size() && name[i] != ',') { +			if (name[i] == '\\') +				name.setChar('/', i); +			i++; +		} + +		Common::String filename = "voc/" + Common::String(name.c_str(), name.c_str()+i) + ".voc"; +		debug("Playing speech '%s'", filename.c_str()); +		Common::SeekableReadStream *readStream = SearchMan.createReadStreamForMember(filename); +		if (readStream == nullptr) +			error("Couldn't open '%s'", filename.c_str()); + +		Audio::AudioStream *audioStream = Audio::makeVOCStream(readStream, Audio::FLAG_UNSIGNED, DisposeAfterUse::YES); +		if (audioQueue == nullptr) +			audioQueue = Audio::makeQueuingAudioStream(audioStream->getRate(), audioStream->isStereo()); +		audioQueue->queueAudioStream(audioStream, DisposeAfterUse::YES); + +		name.erase(0,i+1); +	} + +	if (audioQueue != nullptr) { +		audioQueue->finish(); +		_vm->_system->getMixer()->playStream(Audio::Mixer::kSpeechSoundType, &_speechHandle, audioQueue); +	} + +	_playingSpeech = true; +} + +void Sound::stopPlayingSpeech() { +	if (_playingSpeech) { +		_playingSpeech = false; +		_vm->_system->getMixer()->stopHandle(_speechHandle); +	} +}  // XMIDI or SM sound @@ -179,10 +252,17 @@ void Sound::clearAllMidiSlots() {  	}  } +// Static callback method  void Sound::midiDriverCallback(void *data) {  	Sound *s = (Sound*)data;  	for (int i=0; i<8; i++)  		s->_midiSlots[i].midiParser->onTimer(); + +	// TODO: put this somewhere other than the midi callback... +	if (s->_playingSpeech && !s->_vm->_system->getMixer()->isSoundHandleActive(s->_speechHandle)) { +		s->stopPlayingSpeech(); +		s->_vm->_finishedPlayingSpeech = true; +	}  } diff --git a/engines/startrek/sound.h b/engines/startrek/sound.h index f314f2c688..a9116627d5 100755 --- a/engines/startrek/sound.h +++ b/engines/startrek/sound.h @@ -41,12 +41,16 @@ namespace StarTrek {  class StarTrekEngine; -struct MidiSlot { +const int MAX_LOADED_SFX_FILES = 8; +const int MAX_SFX_PLAYING = 4; + +struct MidiPlaybackSlot {  	int slot;  	int track;  	MidiParser *midiParser;  }; +  class Sound {  public:  	Sound(StarTrekEngine *vm); @@ -56,6 +60,8 @@ public:  	void loadMusicFile(const char *baseSoundName);  	void playSoundEffect(const char *baseSoundName); +	void playSpeech(const Common::String &basename); +	void stopPlayingSpeech();  private:  	StarTrekEngine *_vm; @@ -67,12 +73,17 @@ private:  	// MIDI-Related Variables  	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 +	MidiPlaybackSlot _midiSlots[8]; // 0 is for music; 1-7 are for sfx +	Common::List<MidiPlaybackSlot*> _sfxSlotList; // Sorts midi slots by most recently used  	byte *loadedSoundData;  	uint32 _midiDevice;	 +	// VOC-related variables +	Common::String _loopingAudioName; +	Audio::SoundHandle _sfxHandles[MAX_SFX_PLAYING]; +	Audio::SoundHandle _speechHandle; +	bool _playingSpeech;  	// Driver callback  	static void midiDriverCallback(void *data); diff --git a/engines/startrek/startrek.cpp b/engines/startrek/startrek.cpp index dba8a48756..d888d1f710 100755 --- a/engines/startrek/startrek.cpp +++ b/engines/startrek/startrek.cpp @@ -42,8 +42,11 @@ StarTrekEngine::StarTrekEngine(OSystem *syst, const StarTrekGameDescription *gam  	_gfx = nullptr;  	_sound = nullptr;  	_macResFork = nullptr; -  	_room = nullptr; + +	_audioEnabled = true; +	_musicEnabled = true; +	_sfxEnabled = true;  }  StarTrekEngine::~StarTrekEngine() { @@ -55,9 +58,6 @@ StarTrekEngine::~StarTrekEngine() {  }  Common::Error StarTrekEngine::run() { -	_cdAudioEnabled = true; -	_midiAudioEnabled = true; -  	_gfx = new Graphics(this);  	_sound = new Sound(this); @@ -101,7 +101,7 @@ Common::Error StarTrekEngine::run() {  		_gfx->loadPri("DEMON0.PRI");  		_gfx->redrawScreen(); -		_sound->loadMusicFile("BRIDGEW"); +		_sound->loadMusicFile("GROUND");  	} else {  		_gfx->drawBackgroundImage("BRIDGE.BGD");  	} @@ -191,50 +191,50 @@ void StarTrekEngine::pollSystemEvents() {  }  void StarTrekEngine::playSoundEffectIndex(int index) { -	switch(index-4) { -	case 0: +	switch(index) { +	case 0x04:  		_sound->playSoundEffect("tricorde");  		break; -	case 1: +	case 0x05:  		_sound->playSoundEffect("STDOOR1");  		break; -	case 2: +	case 0x06:  		_sound->playSoundEffect("PHASSHOT");  		break; -	case 3: +	case 0x07:  		_sound->playMidiTrack(index);  		break; -	case 4: +	case 0x08:  		_sound->playSoundEffect("TRANSDEM");  		break; -	case 5: +	case 0x09:  		_sound->playSoundEffect("TRANSMAT");  		break; -	case 6: +	case 0x0a:  		_sound->playSoundEffect("TRANSENE");  		break; -	case 0x0c: // Menu selection sound +	case 0x10: // Menu selection sound  		_sound->playMidiTrack(index);  		break; -	case 0x1e: +	case 0x22:  		_sound->playSoundEffect("HAILING");  		break; -	case 0x20: +	case 0x24:  		_sound->playSoundEffect("PHASSHOT");  		break; -	case 0x21: +	case 0x25:  		_sound->playSoundEffect("PHOTSHOT");  		break; -	case 0x22: +	case 0x26:  		_sound->playSoundEffect("HITSHIEL");  		break; -	case 0x23: +	case 0x27:  		_sound->playMidiTrack(index);  		break; -	case 0x24: +	case 0x28:  		_sound->playSoundEffect("REDALERT");  		break; -	case 0x25: +	case 0x29:  		_sound->playSoundEffect("WARP");  		break;  	default: @@ -242,6 +242,14 @@ void StarTrekEngine::playSoundEffectIndex(int index) {  	}  } +void StarTrekEngine::playSpeech(const Common::String &filename) { +	_sound->playSpeech(filename.c_str()); +} + +void StarTrekEngine::stopPlayingSpeech() { +	_sound->stopPlayingSpeech(); +} +  void StarTrekEngine::updateClockTicks() {  	// TODO (based on DOS interrupt 1A, AH=0; read system clock counter) diff --git a/engines/startrek/startrek.h b/engines/startrek/startrek.h index c190659d6a..232482a767 100755 --- a/engines/startrek/startrek.h +++ b/engines/startrek/startrek.h @@ -92,6 +92,8 @@ public:  	void pollSystemEvents();  	void playSoundEffectIndex(int index); +	void playSpeech(const Common::String &filename); +	void stopPlayingSpeech();  	// Events  public: @@ -135,11 +137,12 @@ public:  	uint32 _clockTicks; -	bool _midiAudioEnabled; -	bool _cdAudioEnabled; +	bool _musicEnabled; +	bool _sfxEnabled;  	uint16 _word_467a6;  	uint16 _word_467a8; -	bool _textboxVar4; +	bool _audioEnabled; +	bool _finishedPlayingSpeech;  private: diff --git a/engines/startrek/text.cpp b/engines/startrek/text.cpp index fe2f0eeb6c..2d875da397 100644 --- a/engines/startrek/text.cpp +++ b/engines/startrek/text.cpp @@ -88,12 +88,12 @@ int Graphics::showText(TextGetterFunc textGetter, int var, int xoffset, int yoff  	int choiceIndex = 0;  	int scrollOffset = 0;  	if (tmpTextboxVar1 != 0 && tmpTextboxVar1 != 1 && numChoices == 1 -			&& _vm->_cdAudioEnabled && !_vm->_textboxVar4) +			&& _vm->_sfxEnabled && !_vm->_audioEnabled)  		_textboxHasMultipleChoices = false;  	else  		_textboxHasMultipleChoices = true; -	if (tmpTextboxVar1 >= 0 && tmpTextboxVar1 <= 2 && _vm->_cdAudioEnabled && !_vm->_textboxVar4) +	if (tmpTextboxVar1 >= 0 && tmpTextboxVar1 <= 2 && _vm->_sfxEnabled && !_vm->_audioEnabled)  		_textboxVar6 = true;  	else  		_textboxVar6 = false; @@ -268,7 +268,7 @@ reloadText:  	}  	_textboxVar2 = _textboxVar3; -	// sub_29EE3(); +	_vm->stopPlayingSpeech();  	return choiceIndex;  } @@ -312,8 +312,8 @@ int Graphics::handleTextboxEvents(uint32 ticksUntilClickingEnabled, bool arg4) {  				// sub_10BE7();  				// sub_2A4B1(); -				if (_word_4B422 != 0) { -					_word_4B422 = 0; +				if (_vm->_finishedPlayingSpeech != 0) { +					_vm->_finishedPlayingSpeech = 0;  					if (_textboxVar1 != 0) {  						return TEXTEVENT_SPEECH_DONE;  					} @@ -539,13 +539,13 @@ String Graphics::readLineFormattedText(TextGetterFunc textGetter, int var, int c  	String headerText;  	String text = (this->*textGetter)(choiceIndex, &var, &headerText); -	if (_textboxVar1 == 2 && _vm->_cdAudioEnabled && _vm->_textboxVar4) { +	if (_textboxVar1 == 2 && _vm->_sfxEnabled && _vm->_audioEnabled) {  		uint32 oldSize = text.size();  		text = playTextAudio(text);  		if (oldSize != text.size())  			_textboxHasMultipleChoices = true;  	} -	else if ((_textboxVar1 == 0 || _textboxVar1 == 1) && _vm->_cdAudioEnabled && _vm->_textboxVar4) { +	else if ((_textboxVar1 == 0 || _textboxVar1 == 1) && _vm->_sfxEnabled && _vm->_audioEnabled) {  		text = playTextAudio(text);  	}  	else { @@ -682,9 +682,29 @@ String Graphics::skipTextAudioPrompt(const String &str) {  	return String(text+1);  } +/** + * Plays an audio prompt, if it exists, and returns the string starting at the end of the + * prompt. + */  String Graphics::playTextAudio(const String &str) { -	// TODO -	return skipTextAudioPrompt(str); +	const char *text = str.c_str(); +	char soundFile[0x100]; + +	if (*text != '#') +		return str; + +	int len = 0; +	text++; +	while (*text != '#') { +		if (*text == '\0' || len > 0xfa) +			return str; +		soundFile[len++] = *text++; +	} + +	soundFile[len] = '\0'; +	_vm->playSpeech(soundFile); + +	return String(text+1);  }  /** | 
