aboutsummaryrefslogtreecommitdiff
path: root/engines/sci/sfx/soundcmd.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'engines/sci/sfx/soundcmd.cpp')
-rw-r--r--engines/sci/sfx/soundcmd.cpp1090
1 files changed, 0 insertions, 1090 deletions
diff --git a/engines/sci/sfx/soundcmd.cpp b/engines/sci/sfx/soundcmd.cpp
deleted file mode 100644
index f42ecc1099..0000000000
--- a/engines/sci/sfx/soundcmd.cpp
+++ /dev/null
@@ -1,1090 +0,0 @@
-/* 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.
- *
- * $URL$
- * $Id$
- *
- */
-
-#include "sci/sci.h" // for USE_OLD_MUSIC_FUNCTIONS
-
-#ifdef USE_OLD_MUSIC_FUNCTIONS
-#include "sci/sfx/iterator/iterator.h" // for SongIteratorStatus
-#endif
-
-#include "sci/sfx/music.h"
-#include "sci/sfx/soundcmd.h"
-
-namespace Sci {
-
-#define SCI1_SOUND_FLAG_MAY_PAUSE 1 /* Only here for completeness; The interpreter doesn't touch this bit */
-#define SCI1_SOUND_FLAG_SCRIPTED_PRI 2 /* but does touch this */
-
-#ifdef USE_OLD_MUSIC_FUNCTIONS
-#define FROBNICATE_HANDLE(reg) ((reg).segment << 16 | (reg).offset)
-#define DEFROBNICATE_HANDLE(handle) (make_reg((handle >> 16) & 0xffff, handle & 0xffff))
-#endif
-
-#define SOUNDCOMMAND(x) _soundCommands.push_back(new MusicEntryCommand(#x, &SoundCommandParser::x))
-
-#ifdef USE_OLD_MUSIC_FUNCTIONS
-static void script_set_priority(ResourceManager *resMan, SegManager *segMan, SfxState *state, reg_t obj, int priority) {
- int song_nr = GET_SEL32V(segMan, obj, number);
- Resource *song = resMan->findResource(ResourceId(kResourceTypeSound, song_nr), 0);
- int flags = GET_SEL32V(segMan, obj, flags);
-
- if (priority == -1) {
- if (song->data[0] == 0xf0)
- priority = song->data[1];
- else
- warning("Attempt to unset song priority when there is no built-in value");
-
- flags &= ~SCI1_SOUND_FLAG_SCRIPTED_PRI;
- } else flags |= SCI1_SOUND_FLAG_SCRIPTED_PRI;
-
- state->sfx_song_renice(FROBNICATE_HANDLE(obj), priority);
- PUT_SEL32V(segMan, obj, flags, flags);
-}
-
-SongIterator *build_iterator(ResourceManager *resMan, int song_nr, SongIteratorType type, songit_id_t id) {
- Resource *song = resMan->findResource(ResourceId(kResourceTypeSound, song_nr), 0);
-
- if (!song)
- return NULL;
-
- return songit_new(song->data, song->size, type, id);
-}
-
-void process_sound_events(EngineState *s) { /* Get all sound events, apply their changes to the heap */
- int result;
- SongHandle handle;
- int cue;
- SegManager *segMan = s->_segMan;
-
- if (getSciVersion() > SCI_VERSION_01)
- return;
- // SCI1 and later explicitly poll for everything
-
- while ((result = s->_sound.sfx_poll(&handle, &cue))) {
- reg_t obj = DEFROBNICATE_HANDLE(handle);
- if (!s->_segMan->isObject(obj)) {
- warning("Non-object %04x:%04x received sound signal (%d/%d)", PRINT_REG(obj), result, cue);
- return;
- }
-
- switch (result) {
-
- case SI_LOOP:
- debugC(2, kDebugLevelSound, "[process-sound] Song %04x:%04x looped (to %d)\n",
- PRINT_REG(obj), cue);
- /* PUT_SEL32V(segMan, obj, loops, GET_SEL32V(segMan, obj, loop) - 1);*/
- PUT_SEL32V(segMan, obj, signal, SIGNAL_OFFSET);
- break;
-
- case SI_RELATIVE_CUE:
- debugC(2, kDebugLevelSound, "[process-sound] Song %04x:%04x received relative cue %d\n",
- PRINT_REG(obj), cue);
- PUT_SEL32V(segMan, obj, signal, cue + 0x7f);
- break;
-
- case SI_ABSOLUTE_CUE:
- debugC(2, kDebugLevelSound, "[process-sound] Song %04x:%04x received absolute cue %d\n",
- PRINT_REG(obj), cue);
- PUT_SEL32V(segMan, obj, signal, cue);
- break;
-
- case SI_FINISHED:
- debugC(2, kDebugLevelSound, "[process-sound] Song %04x:%04x finished\n",
- PRINT_REG(obj));
- PUT_SEL32V(segMan, obj, signal, SIGNAL_OFFSET);
- PUT_SEL32V(segMan, obj, state, kSoundStopped);
- break;
-
- default:
- warning("Unexpected result from sfx_poll: %d", result);
- break;
- }
- }
-}
-
-#endif
-SoundCommandParser::SoundCommandParser(ResourceManager *resMan, SegManager *segMan, AudioPlayer *audio, SciVersion soundVersion) :
- _resMan(resMan), _segMan(segMan), _audio(audio), _soundVersion(soundVersion) {
-
-#ifdef USE_OLD_MUSIC_FUNCTIONS
- // The following hack is needed to ease the change from old to new sound code (because the new sound code does not use SfxState)
- _state = &((SciEngine *)g_engine)->getEngineState()->_sound; // HACK
-#endif
-
- #ifndef USE_OLD_MUSIC_FUNCTIONS
- _music = new SciMusic(_soundVersion);
- _music->init();
- #endif
-
- switch (_soundVersion) {
- case SCI_VERSION_0_EARLY:
- case SCI_VERSION_0_LATE:
- SOUNDCOMMAND(cmdInitSound);
- SOUNDCOMMAND(cmdPlaySound);
- SOUNDCOMMAND(cmdDummy);
- SOUNDCOMMAND(cmdDisposeSound);
- SOUNDCOMMAND(cmdMuteSound);
- SOUNDCOMMAND(cmdStopSound);
- SOUNDCOMMAND(cmdPauseSound);
- SOUNDCOMMAND(cmdResumeSound);
- SOUNDCOMMAND(cmdMasterVolume);
- SOUNDCOMMAND(cmdUpdateSound);
- SOUNDCOMMAND(cmdFadeSound);
- SOUNDCOMMAND(cmdGetPolyphony);
- SOUNDCOMMAND(cmdStopAllSounds);
- _cmdUpdateCuesIndex = -1;
- break;
- case SCI_VERSION_1_EARLY:
- SOUNDCOMMAND(cmdMasterVolume);
- SOUNDCOMMAND(cmdMuteSound);
- SOUNDCOMMAND(cmdDummy);
- SOUNDCOMMAND(cmdGetPolyphony);
- SOUNDCOMMAND(cmdUpdateSound);
- SOUNDCOMMAND(cmdInitSound);
- SOUNDCOMMAND(cmdDisposeSound);
- SOUNDCOMMAND(cmdPlaySound);
- SOUNDCOMMAND(cmdStopSound);
- SOUNDCOMMAND(cmdPauseSound);
- SOUNDCOMMAND(cmdFadeSound);
- SOUNDCOMMAND(cmdUpdateCues);
- SOUNDCOMMAND(cmdSendMidi);
- SOUNDCOMMAND(cmdReverb);
- SOUNDCOMMAND(cmdSetSoundHold);
- _cmdUpdateCuesIndex = 11;
- break;
- case SCI_VERSION_1_LATE:
- SOUNDCOMMAND(cmdMasterVolume);
- SOUNDCOMMAND(cmdMuteSound);
- SOUNDCOMMAND(cmdDummy);
- SOUNDCOMMAND(cmdGetPolyphony);
- SOUNDCOMMAND(cmdGetAudioCapability);
- SOUNDCOMMAND(cmdSuspendSound);
- SOUNDCOMMAND(cmdInitSound);
- SOUNDCOMMAND(cmdDisposeSound);
- SOUNDCOMMAND(cmdPlaySound);
- SOUNDCOMMAND(cmdStopSound);
- SOUNDCOMMAND(cmdPauseSound);
- SOUNDCOMMAND(cmdFadeSound);
- SOUNDCOMMAND(cmdSetSoundHold);
- SOUNDCOMMAND(cmdDummy);
- SOUNDCOMMAND(cmdSetSoundVolume);
- SOUNDCOMMAND(cmdSetSoundPriority);
- SOUNDCOMMAND(cmdSetSoundLoop);
- SOUNDCOMMAND(cmdUpdateCues);
- SOUNDCOMMAND(cmdSendMidi);
- SOUNDCOMMAND(cmdReverb);
- SOUNDCOMMAND(cmdUpdateSound);
- _cmdUpdateCuesIndex = 17;
- break;
- default:
- warning("Sound command parser: unknown sound version %d", _soundVersion);
- break;
- }
-}
-
-SoundCommandParser::~SoundCommandParser() {
-}
-
-reg_t SoundCommandParser::parseCommand(int argc, reg_t *argv, reg_t acc) {
- uint16 command = argv[0].toUint16();
- reg_t obj = (argc > 1) ? argv[1] : NULL_REG;
- int16 value = (argc > 2) ? argv[2].toSint16() : 0;
- _acc = acc;
- _argc = argc;
- _argv = argv;
-
- if (argc == 6) { // cmdSendMidi
- byte channel = argv[2].toUint16() & 0xf;
- byte midiCmd = argv[3].toUint16() & 0xff;
-
- uint16 controller = argv[4].toUint16();
- uint16 param = argv[5].toUint16();
-
- _midiCommand = (channel | midiCmd) | ((uint32)controller << 8) | ((uint32)param << 16);
- }
-
- if (command < _soundCommands.size()) {
- if (command != _cmdUpdateCuesIndex) {
- //printf("%s, object %04x:%04x\n", _soundCommands[command]->desc, PRINT_REG(obj)); // debug
- debugC(2, kDebugLevelSound, "%s, object %04x:%04x", _soundCommands[command]->desc, PRINT_REG(obj));
- }
-
- (this->*(_soundCommands[command]->sndCmd))(obj, value);
- } else {
- warning("Invalid sound command requested (%d), valid range is 0-%d", command, _soundCommands.size() - 1);
- }
-
- return _acc;
-}
-
-void SoundCommandParser::cmdInitSound(reg_t obj, int16 value) {
- if (!obj.segment)
- return;
-
- int number = obj.segment ? GET_SEL32V(_segMan, obj, number) : 0;
-
-#ifdef USE_OLD_MUSIC_FUNCTIONS
-
- SongHandle handle = FROBNICATE_HANDLE(obj);
-
- if (_soundVersion != SCI_VERSION_1_LATE) {
- if (!obj.segment)
- return;
- }
-
- SongIteratorType type = (_soundVersion <= SCI_VERSION_0_LATE) ? SCI_SONG_ITERATOR_TYPE_SCI0 : SCI_SONG_ITERATOR_TYPE_SCI1;
-
- if (_soundVersion <= SCI_VERSION_0_LATE) {
- if (GET_SEL32V(_segMan, obj, nodePtr)) {
- _state->sfx_song_set_status(handle, SOUND_STATUS_STOPPED);
- _state->sfx_remove_song(handle);
- }
- }
-
- if (!obj.segment || !_resMan->testResource(ResourceId(kResourceTypeSound, number)))
- return;
-
- _state->sfx_add_song(build_iterator(_resMan, number, type, handle), 0, handle, number);
-
-
- // Notify the engine
- if (_soundVersion <= SCI_VERSION_0_LATE)
- PUT_SEL32V(_segMan, obj, state, kSoundInitialized);
- else
- PUT_SEL32(_segMan, obj, nodePtr, obj);
-
- PUT_SEL32(_segMan, obj, handle, obj);
-
-#else
-
- MusicEntry *newSound = new MusicEntry();
- newSound->resnum = number;
- if (number && _resMan->testResource(ResourceId(kResourceTypeSound, number)))
- newSound->soundRes = new SoundResource(number, _resMan, _soundVersion);
- else
- newSound->soundRes = 0;
-
- newSound->soundObj = obj;
- newSound->loop = GET_SEL32V(_segMan, obj, loop);
- newSound->prio = GET_SEL32V(_segMan, obj, pri) & 0xFF;
- if (_soundVersion >= SCI_VERSION_1_LATE)
- newSound->volume = CLIP<int>(GET_SEL32V(_segMan, obj, vol), 0, MUSIC_VOLUME_MAX);
-
- // Check if a track with the same sound object is already playing
- MusicEntry *oldSound = _music->getSlot(obj);
- if (oldSound)
- cmdDisposeSound(obj, value);
-
- // In SCI1.1 games, sound effects are started from here. If we can find
- // a relevant audio resource, play it, otherwise switch to synthesized
- // effects. If the resource exists, play it using map 65535 (sound
- // effects map)
-
- if (getSciVersion() >= SCI_VERSION_1_1 && _resMan->testResource(ResourceId(kResourceTypeAudio, number))) {
- // Found a relevant audio resource, play it
- int sampleLen;
- newSound->pStreamAud = _audio->getAudioStream(number, 65535, &sampleLen);
- newSound->soundType = Audio::Mixer::kSpeechSoundType;
- } else {
- if (newSound->soundRes)
- _music->soundInitSnd(newSound);
- }
-
- _music->pushBackSlot(newSound);
-
- if (newSound->soundRes || newSound->pStreamAud) {
- // Notify the engine
- if (_soundVersion <= SCI_VERSION_0_LATE)
- PUT_SEL32V(_segMan, obj, state, kSoundInitialized);
- else
- PUT_SEL32(_segMan, obj, nodePtr, obj);
-
- PUT_SEL32(_segMan, obj, handle, obj);
- }
-#endif
-
-}
-
-void SoundCommandParser::cmdPlaySound(reg_t obj, int16 value) {
- if (!obj.segment)
- return;
-
-#ifdef USE_OLD_MUSIC_FUNCTIONS
- SongHandle handle = FROBNICATE_HANDLE(obj);
-
- if (_soundVersion <= SCI_VERSION_0_LATE) {
- _state->sfx_song_set_status(handle, SOUND_STATUS_PLAYING);
- _state->sfx_song_set_loops(handle, GET_SEL32V(_segMan, obj, loop));
- PUT_SEL32V(_segMan, obj, state, kSoundPlaying);
- } else if (_soundVersion == SCI_VERSION_1_EARLY) {
- _state->sfx_song_set_status(handle, SOUND_STATUS_PLAYING);
- _state->sfx_song_set_loops(handle, GET_SEL32V(_segMan, obj, loop));
- _state->sfx_song_renice(handle, GET_SEL32V(_segMan, obj, pri));
- RESTORE_BEHAVIOR rb = (RESTORE_BEHAVIOR) value; /* Too lazy to look up a default value for this */
- _state->_songlib.setSongRestoreBehavior(handle, rb);
- PUT_SEL32V(_segMan, obj, signal, 0);
- } else if (_soundVersion == SCI_VERSION_1_LATE) {
- int looping = GET_SEL32V(_segMan, obj, loop);
- //int vol = GET_SEL32V(_segMan, obj, vol);
- int pri = GET_SEL32V(_segMan, obj, pri);
- int sampleLen = 0;
- Song *song = _state->_songlib.findSong(handle);
- int songNumber = GET_SEL32V(_segMan, obj, number);
-
- if (GET_SEL32V(_segMan, obj, nodePtr) && (song && songNumber != song->_resourceNum)) {
- _state->sfx_song_set_status(handle, SOUND_STATUS_STOPPED);
- _state->sfx_remove_song(handle);
- PUT_SEL32(_segMan, obj, nodePtr, NULL_REG);
- }
-
- if (!GET_SEL32V(_segMan, obj, nodePtr) && obj.segment) {
- // In SCI1.1 games, sound effects are started from here. If we can find
- // a relevant audio resource, play it, otherwise switch to synthesized
- // effects. If the resource exists, play it using map 65535 (sound
- // effects map)
- if (_resMan->testResource(ResourceId(kResourceTypeAudio, songNumber)) &&
- getSciVersion() >= SCI_VERSION_1_1) {
- // Found a relevant audio resource, play it
- _audio->stopAudio();
- warning("Initializing audio resource instead of requested sound resource %d", songNumber);
- sampleLen = _audio->startAudio(65535, songNumber);
- // Also create iterator, that will fire SI_FINISHED event, when the sound is done playing
- _state->sfx_add_song(new_timer_iterator(sampleLen), 0, handle, songNumber);
- } else {
- if (!_resMan->testResource(ResourceId(kResourceTypeSound, songNumber))) {
- warning("Could not open song number %d", songNumber);
- // Send a "stop handle" event so that the engine won't wait forever here
- _state->sfx_song_set_status(handle, SOUND_STATUS_STOPPED);
- PUT_SEL32V(_segMan, obj, signal, SIGNAL_OFFSET);
- return;
- }
- debugC(2, kDebugLevelSound, "Initializing song number %d\n", songNumber);
- _state->sfx_add_song(build_iterator(_resMan, songNumber, SCI_SONG_ITERATOR_TYPE_SCI1,
- handle), 0, handle, songNumber);
- }
-
- PUT_SEL32(_segMan, obj, nodePtr, obj);
- PUT_SEL32(_segMan, obj, handle, obj);
- }
-
- if (obj.segment) {
- _state->sfx_song_set_status(handle, SOUND_STATUS_PLAYING);
- _state->sfx_song_set_loops(handle, looping);
- _state->sfx_song_renice(handle, pri);
- PUT_SEL32V(_segMan, obj, signal, 0);
- }
- }
-
-#else
-
- MusicEntry *musicSlot = _music->getSlot(obj);
- if (!musicSlot) {
- warning("cmdPlaySound: Slot not found (%04x:%04x)", PRINT_REG(obj));
- return;
- }
-
- int number = obj.segment ? GET_SEL32V(_segMan, obj, number) : -1;
-
- if (musicSlot->resnum != number) { // another sound loaded into struct
- cmdDisposeSound(obj, value);
- cmdInitSound(obj, value);
- // Find slot again :)
- musicSlot = _music->getSlot(obj);
- }
- int16 loop = GET_SEL32V(_segMan, obj, loop);
- debugC(2, kDebugLevelSound, "cmdPlaySound: resource number %d, loop %d", number, loop);
-
- PUT_SEL32(_segMan, obj, handle, obj);
-
- if (_soundVersion >= SCI_VERSION_1_EARLY) {
- PUT_SEL32(_segMan, obj, nodePtr, obj);
- PUT_SEL32V(_segMan, obj, min, 0);
- PUT_SEL32V(_segMan, obj, sec, 0);
- PUT_SEL32V(_segMan, obj, frame, 0);
- PUT_SEL32V(_segMan, obj, signal, 0);
- } else {
- PUT_SEL32V(_segMan, obj, state, kSoundPlaying);
- }
-
- musicSlot->loop = GET_SEL32V(_segMan, obj, loop);
- musicSlot->prio = GET_SEL32V(_segMan, obj, priority);
- if (_soundVersion >= SCI_VERSION_1_LATE)
- musicSlot->volume = GET_SEL32V(_segMan, obj, vol);
- _music->soundPlay(musicSlot);
-
-#endif
-
-}
-
-void SoundCommandParser::cmdDummy(reg_t obj, int16 value) {
- warning("cmdDummy invoked"); // not supposed to occur
-}
-
-#ifdef USE_OLD_MUSIC_FUNCTIONS
-void SoundCommandParser::changeSoundStatus(reg_t obj, int newStatus) {
- SongHandle handle = FROBNICATE_HANDLE(obj);
- if (obj.segment) {
- _state->sfx_song_set_status(handle, newStatus);
- if (_soundVersion <= SCI_VERSION_0_LATE)
- PUT_SEL32V(_segMan, obj, state, newStatus);
- }
-}
-#endif
-
-void SoundCommandParser::cmdDisposeSound(reg_t obj, int16 value) {
- if (!obj.segment)
- return;
-
-#ifdef USE_OLD_MUSIC_FUNCTIONS
- SongHandle handle = FROBNICATE_HANDLE(obj);
- changeSoundStatus(obj, SOUND_STATUS_STOPPED);
-
- if (obj.segment) {
- _state->sfx_remove_song(handle);
-
- if (_soundVersion <= SCI_VERSION_0_LATE)
- PUT_SEL32V(_segMan, obj, handle, 0x0000);
- }
-
-#else
-
- MusicEntry *musicSlot = _music->getSlot(obj);
- if (!musicSlot) {
- warning("cmdDisposeSound: Slot not found (%04x:%04x)", PRINT_REG(obj));
- return;
- }
-
- cmdStopSound(obj, value);
-
- _music->soundKill(musicSlot);
- if (_soundVersion >= SCI_VERSION_1_EARLY)
- PUT_SEL32(_segMan, obj, nodePtr, NULL_REG);
- else
- PUT_SEL32V(_segMan, obj, state, kSoundStopped);
-#endif
-}
-
-void SoundCommandParser::cmdStopSound(reg_t obj, int16 value) {
- if (!obj.segment)
- return;
-
-#ifdef USE_OLD_MUSIC_FUNCTIONS
- changeSoundStatus(obj, SOUND_STATUS_STOPPED);
-
- if (_soundVersion >= SCI_VERSION_1_EARLY)
- PUT_SEL32V(_segMan, obj, signal, SIGNAL_OFFSET);
-#else
- MusicEntry *musicSlot = _music->getSlot(obj);
- if (!musicSlot) {
- warning("cmdStopSound: Slot not found (%04x:%04x)", PRINT_REG(obj));
- return;
- }
-
- PUT_SEL32V(_segMan, obj, handle, 0);
- if (_soundVersion <= SCI_VERSION_0_LATE)
- PUT_SEL32V(_segMan, obj, state, kSoundStopped);
- else
- PUT_SEL32V(_segMan, obj, signal, SIGNAL_OFFSET);
-
- musicSlot->dataInc = 0;
- musicSlot->signal = 0;
- _music->soundStop(musicSlot);
-#endif
-}
-
-void SoundCommandParser::cmdPauseSound(reg_t obj, int16 value) {
-#ifdef USE_OLD_MUSIC_FUNCTIONS
- if (!obj.segment)
- return;
-
- if (_soundVersion <= SCI_VERSION_0_LATE)
- changeSoundStatus(obj, SOUND_STATUS_SUSPENDED);
- else
- changeSoundStatus(obj, value ? SOUND_STATUS_SUSPENDED : SOUND_STATUS_PLAYING);
-#else
-
- MusicEntry *musicSlot = NULL;
- MusicList::iterator slotLoop = NULL;
- MusicList::iterator listEnd = NULL;
-
- if (!obj.segment) {
- // Pausing/Resuming the whole playlist was introduced
- // in the SCI1 late sound scheme
- if (_soundVersion <= SCI_VERSION_1_EARLY)
- return;
- _music->_mutex.lock();
- slotLoop = _music->getPlayListStart();
- listEnd = _music->getPlayListEnd();
- musicSlot = *slotLoop;
- _music->_mutex.unlock();
- } else {
- _music->_mutex.lock();
- musicSlot = _music->getSlot(obj);
- _music->_mutex.unlock();
- if (!musicSlot) {
- warning("cmdPauseSound: Slot not found (%04x:%04x)", PRINT_REG(obj));
- return;
- }
- }
-
- do {
- if (_soundVersion <= SCI_VERSION_0_LATE) {
- PUT_SEL32V(_segMan, musicSlot->soundObj, state, kSoundPaused);
- _music->soundPause(musicSlot);
- } else {
- if (value)
- _music->soundPause(musicSlot);
- else
- _music->soundResume(musicSlot);
- }
-
- if (slotLoop) {
- if (slotLoop == listEnd) {
- break;
- } else {
- _music->_mutex.lock();
- musicSlot = *(slotLoop++);
- _music->_mutex.unlock();
- }
- }
- } while (slotLoop);
-
-#endif
-}
-
-void SoundCommandParser::cmdResumeSound(reg_t obj, int16 value) {
- // SCI0 only command
-
- if (!obj.segment)
- return;
-
-#ifdef USE_OLD_MUSIC_FUNCTIONS
- changeSoundStatus(obj, SOUND_STATUS_PLAYING);
-#else
- MusicEntry *musicSlot = _music->getSlot(obj);
- if (!musicSlot) {
- warning("cmdResumeSound: Slot not found (%04x:%04x)", PRINT_REG(obj));
- return;
- }
-
- PUT_SEL32V(_segMan, musicSlot->soundObj, state, kSoundPlaying);
- _music->soundResume(musicSlot);
-#endif
-}
-
-void SoundCommandParser::cmdMuteSound(reg_t obj, int16 value) {
-#ifndef USE_OLD_MUSIC_FUNCTIONS
- if (_argc > 1) // the first parameter is the sound command
- _music->soundSetSoundOn(obj.toUint16());
- _acc = make_reg(0, _music->soundGetSoundOn());
-#endif
-}
-
-void SoundCommandParser::cmdMasterVolume(reg_t obj, int16 value) {
-#ifdef USE_OLD_MUSIC_FUNCTIONS
- if (obj != SIGNAL_REG)
- _state->sfx_setVolume(obj.toSint16());
-
- _acc = make_reg(0, _state->sfx_getVolume());
-#else
- debugC(2, kDebugLevelSound, "cmdMasterVolume: %d", value);
- if (_argc > 1) // the first parameter is the sound command
- _music->soundSetMasterVolume(obj.toSint16());
- _acc = make_reg(0, _music->soundGetMasterVolume());
-#endif
-}
-
-void SoundCommandParser::cmdFadeSound(reg_t obj, int16 value) {
- if (!obj.segment)
- return;
-
-#ifdef USE_OLD_MUSIC_FUNCTIONS
- SongHandle handle = FROBNICATE_HANDLE(obj);
- if (_soundVersion != SCI_VERSION_1_LATE) {
- /*s->sound_server->command(s, SOUND_COMMAND_FADE_HANDLE, obj, 120);*/ /* Fade out in 2 secs */
- /* FIXME: The next couple of lines actually STOP the handle, rather
- ** than fading it! */
- _state->sfx_song_set_status(handle, SOUND_STATUS_STOPPED);
- if (_soundVersion <= SCI_VERSION_0_LATE)
- PUT_SEL32V(_segMan, obj, state, SOUND_STATUS_STOPPED);
- PUT_SEL32V(_segMan, obj, signal, SIGNAL_OFFSET);
- } else {
- fade_params_t fade;
- fade.final_volume = _argv[2].toUint16();
- fade.ticks_per_step = _argv[3].toUint16();
- fade.step_size = _argv[4].toUint16();
- fade.action = _argv[5].toUint16() ?
- FADE_ACTION_FADE_AND_STOP :
- FADE_ACTION_FADE_AND_CONT;
-
- _state->sfx_song_set_fade(handle, &fade);
-
- /* FIXME: The next couple of lines actually STOP the handle, rather
- ** than fading it! */
- if (_argv[5].toUint16()) {
- PUT_SEL32V(_segMan, obj, signal, SIGNAL_OFFSET);
- _state->sfx_song_set_status(handle, SOUND_STATUS_STOPPED);
- } else {
- // FIXME: Support fade-and-continue. For now, send signal right away.
- PUT_SEL32V(_segMan, obj, signal, SIGNAL_OFFSET);
- }
- }
-#else
- MusicEntry *musicSlot = _music->getSlot(obj);
- if (!musicSlot) {
- warning("cmdFadeSound: Slot not found (%04x:%04x)", PRINT_REG(obj));
- return;
- }
-
- int volume = musicSlot->volume;
-
- switch (_argc) {
- case 2: // SCI0
- // SCI0 fades out all the time and when fadeout is done it will also stop the music from playing
- musicSlot->fadeTo = 0;
- musicSlot->fadeStep = -5;
- musicSlot->fadeTickerStep = 10 * 16667 / _music->soundGetTempo();
- musicSlot->fadeTicker = 0;
- break;
-
- case 5: // Possibly SCI1?!
- case 6: // SCI 1.1 TODO: find out what additional parameter is
- musicSlot->fadeTo = CLIP<uint16>(_argv[2].toUint16(), 0, MUSIC_VOLUME_MAX);
- musicSlot->fadeStep = volume > _argv[2].toUint16() ? -_argv[4].toUint16() : _argv[4].toUint16();
- musicSlot->fadeTickerStep = _argv[3].toUint16() * 16667 / _music->soundGetTempo();
- musicSlot->fadeTicker = 0;
- break;
-
- default:
- error("cmdFadeSound: unsupported argc %d", _argc);
- }
-
- debugC(2, kDebugLevelSound, "cmdFadeSound: to %d, step %d, ticker %d", musicSlot->fadeTo, musicSlot->fadeStep, musicSlot->fadeTickerStep);
-#endif
-}
-
-void SoundCommandParser::cmdGetPolyphony(reg_t obj, int16 value) {
-#ifdef USE_OLD_MUSIC_FUNCTIONS
- _acc = make_reg(0, _state->sfx_get_player_polyphony());
-#else
- _acc = make_reg(0, _music->soundGetVoices()); // Get the number of voices
-#endif
-}
-
-void SoundCommandParser::cmdUpdateSound(reg_t obj, int16 value) {
- if (!obj.segment)
- return;
-
-#ifdef USE_OLD_MUSIC_FUNCTIONS
- SongHandle handle = FROBNICATE_HANDLE(obj);
- if (_soundVersion <= SCI_VERSION_0_LATE && obj.segment) {
- _state->sfx_song_set_loops(handle, GET_SEL32V(_segMan, obj, loop));
- script_set_priority(_resMan, _segMan, _state, obj, GET_SEL32V(_segMan, obj, pri));
- }
-#else
- MusicEntry *musicSlot = _music->getSlot(obj);
- if (!musicSlot) {
- warning("cmdUpdateSound: Slot not found (%04x:%04x)", PRINT_REG(obj));
- return;
- }
-
- musicSlot->loop = GET_SEL32V(_segMan, obj, loop);
- int16 objVol = CLIP<int>(GET_SEL32V(_segMan, obj, vol), 0, 255);
- if (objVol != musicSlot->volume)
- _music->soundSetVolume(musicSlot, objVol);
- uint32 objPrio = GET_SEL32V(_segMan, obj, pri);
- if (objPrio != musicSlot->prio)
- _music->soundSetPriority(musicSlot, objPrio);
-
-#endif
-}
-
-void SoundCommandParser::cmdUpdateCues(reg_t obj, int16 value) {
- if (!obj.segment)
- return;
-
-#ifdef USE_OLD_MUSIC_FUNCTIONS
- int signal = 0;
- int min = 0;
- int sec = 0;
- int frame = 0;
- int result = SI_LOOP; // small hack
- SongHandle handle = FROBNICATE_HANDLE(obj);
-
- while (result == SI_LOOP)
- result = _state->sfx_poll_specific(handle, &signal);
-
- switch (result) {
- case SI_ABSOLUTE_CUE:
- debugC(2, kDebugLevelSound, "--- [CUE] %04x:%04x Absolute Cue: %d\n",
- PRINT_REG(obj), signal);
- debugC(2, kDebugLevelSound, "abs-signal %04X\n", signal);
- PUT_SEL32V(_segMan, obj, signal, signal);
- break;
-
- case SI_RELATIVE_CUE:
- debugC(2, kDebugLevelSound, "--- [CUE] %04x:%04x Relative Cue: %d\n",
- PRINT_REG(obj), signal);
-
- /* FIXME to match commented-out semantics
- * below, with proper storage of dataInc and
- * signal in the iterator code. */
- PUT_SEL32V(_segMan, obj, dataInc, signal);
- debugC(2, kDebugLevelSound, "rel-signal %04X\n", signal);
- if (_soundVersion == SCI_VERSION_1_EARLY)
- PUT_SEL32V(_segMan, obj, signal, signal);
- else
- PUT_SEL32V(_segMan, obj, signal, signal + 127);
- break;
-
- case SI_FINISHED:
- debugC(2, kDebugLevelSound, "--- [FINISHED] %04x:%04x\n", PRINT_REG(obj));
- PUT_SEL32V(_segMan, obj, signal, SIGNAL_OFFSET);
- break;
-
- case SI_LOOP:
- break; // Doesn't happen
- }
-
- //switch (signal) {
- //case 0x00:
- // if (dataInc!=GET_SEL32V(segMan, obj, dataInc)) {
- // PUT_SEL32V(segMan, obj, dataInc, dataInc);
- // PUT_SEL32V(segMan, obj, signal, dataInc+0x7f);
- // } else {
- // PUT_SEL32V(segMan, obj, signal, signal);
- // }
- // break;
- //case 0xFF: // May be unnecessary
- // s->_sound.sfx_song_set_status(handle, SOUND_STATUS_STOPPED);
- // break;
- //default :
- // if (dataInc!=GET_SEL32V(segMan, obj, dataInc)) {
- // PUT_SEL32V(segMan, obj, dataInc, dataInc);
- // PUT_SEL32V(segMan, obj, signal, dataInc + 0x7f);
- // } else {
- // PUT_SEL32V(segMan, obj, signal, signal);
- // }
- // break;
- //}
-
- if (_soundVersion == SCI_VERSION_1_EARLY) {
- PUT_SEL32V(_segMan, obj, min, min);
- PUT_SEL32V(_segMan, obj, sec, sec);
- PUT_SEL32V(_segMan, obj, frame, frame);
- }
-#else
- MusicEntry *musicSlot = _music->getSlot(obj);
- if (!musicSlot) {
- warning("cmdUpdateCues: Slot not found (%04x:%04x)", PRINT_REG(obj));
- return;
- }
-
- if (musicSlot->pStreamAud) {
- // Update digital sound effect slots here
- Audio::Mixer *mixer = g_system->getMixer();
-
- uint currentLoopCounter = musicSlot->pStreamAud->getNumPlayedLoops();
- if (currentLoopCounter != musicSlot->sampleLoopCounter) {
- // during last time we looped at least one time, update loop accordingly
- musicSlot->loop -= currentLoopCounter - musicSlot->sampleLoopCounter;
- musicSlot->sampleLoopCounter = currentLoopCounter;
- }
- if (!mixer->isSoundHandleActive(musicSlot->hCurrentAud)) {
- cmdStopSound(obj, 0);
- } else {
- musicSlot->ticker = (uint16)(mixer->getSoundElapsedTime(musicSlot->hCurrentAud) * 0.06);
- }
- // We get a flag from MusicEntry::doFade() here to set volume for the stream
- if (musicSlot->fadeSetVolume) {
- mixer->setChannelVolume(musicSlot->hCurrentAud, musicSlot->volume);
- musicSlot->fadeSetVolume = false;
- }
- } else {
- switch (musicSlot->signal) {
- case 0:
- if (musicSlot->dataInc != GET_SEL32V(_segMan, obj, dataInc)) {
- PUT_SEL32V(_segMan, obj, dataInc, musicSlot->dataInc);
- PUT_SEL32V(_segMan, obj, signal, musicSlot->dataInc + 127);
- }
- break;
- case SIGNAL_OFFSET:
- PUT_SEL32V(_segMan, obj, signal, SIGNAL_OFFSET);
- break;
- default:
- // Sync the signal of the sound object
- PUT_SEL32V(_segMan, obj, signal, musicSlot->signal);
- break;
- }
- }
-
- if (musicSlot->fadeCompleted) {
- musicSlot->fadeCompleted = false;
- if (_soundVersion <= SCI_VERSION_0_LATE) {
- cmdStopSound(obj, 0);
- } else {
- PUT_SEL32V(_segMan, obj, signal, SIGNAL_OFFSET);
- }
- }
-
- // Sync loop selector for SCI0
- if (_soundVersion <= SCI_VERSION_0_LATE)
- PUT_SEL32V(_segMan, obj, loop, musicSlot->loop);
-
- musicSlot->signal = 0;
-
- if (_soundVersion >= SCI_VERSION_1_EARLY) {
- PUT_SEL32V(_segMan, obj, min, musicSlot->ticker / 3600);
- PUT_SEL32V(_segMan, obj, sec, musicSlot->ticker % 3600 / 60);
- PUT_SEL32V(_segMan, obj, frame, musicSlot->ticker);
- }
-
-#endif
-}
-
-void SoundCommandParser::cmdSendMidi(reg_t obj, int16 value) {
-#ifdef USE_OLD_MUSIC_FUNCTIONS
- //SongHandle handle = FROBNICATE_HANDLE(obj);
- //_state->sfx_send_midi(handle, value, _midiCmd, _controller, _param);
-#else
- _music->sendMidiCommand(_midiCommand);
-#endif
-}
-
-void SoundCommandParser::cmdReverb(reg_t obj, int16 value) {
-#ifndef USE_OLD_MUSIC_FUNCTIONS
- _music->setReverb(obj.toUint16() & 0xF);
-#endif
-}
-
-void SoundCommandParser::cmdSetSoundHold(reg_t obj, int16 value) {
-#ifdef USE_OLD_MUSIC_FUNCTIONS
- SongHandle handle = FROBNICATE_HANDLE(obj);
- _state->sfx_song_set_hold(handle, value);
-#else
- MusicEntry *musicSlot = _music->getSlot(obj);
- if (!musicSlot) {
- warning("cmdSetSoundHold: Slot not found (%04x:%04x)", PRINT_REG(obj));
- return;
- }
-
- // Set the special hold marker ID where the song should be looped at.
- musicSlot->hold = value;
-#endif
-}
-
-void SoundCommandParser::cmdGetAudioCapability(reg_t obj, int16 value) {
- // Tests for digital audio support
- _acc = make_reg(0, 1);
-}
-
-void SoundCommandParser::cmdStopAllSounds(reg_t obj, int16 value) {
-#ifndef USE_OLD_MUSIC_FUNCTIONS
- Common::StackLock(_music->_mutex);
-
- const MusicList::iterator end = _music->getPlayListEnd();
- for (MusicList::iterator i = _music->getPlayListStart(); i != end; ++i) {
- if (_soundVersion <= SCI_VERSION_0_LATE)
- PUT_SEL32V(_segMan, (*i)->soundObj, state, kSoundStopped);
- else
- PUT_SEL32V(_segMan, (*i)->soundObj, signal, SIGNAL_OFFSET);
-
- (*i)->dataInc = 0;
- _music->soundStop(*i);
- }
-#endif
-}
-
-void SoundCommandParser::cmdSetSoundVolume(reg_t obj, int16 value) {
- if (!obj.segment)
- return;
-
-#ifndef USE_OLD_MUSIC_FUNCTIONS
- MusicEntry *musicSlot = _music->getSlot(obj);
- if (!musicSlot) {
- // Do not throw a warning if the sound can't be found, as in some games
- // this is called before the actual sound is loaded (e.g. SQ4CD, with the
- // drum sounds of the energizer bunny at the beginning), so this is normal
- // behavior
- //warning("cmdSetSoundVolume: Slot not found (%04x:%04x)", PRINT_REG(obj));
- return;
- }
-
- debugC(2, kDebugLevelSound, "cmdSetSoundVolume: %d", value);
-
- value = CLIP<int>(value, 0, MUSIC_VOLUME_MAX);
-
- if (musicSlot->volume != value) {
- musicSlot->volume = value;
- _music->soundSetVolume(musicSlot, value);
- PUT_SEL32V(_segMan, obj, vol, value);
- }
-#endif
-}
-
-void SoundCommandParser::cmdSetSoundPriority(reg_t obj, int16 value) {
- if (!obj.segment)
- return;
-
-#ifdef USE_OLD_MUSIC_FUNCTIONS
- script_set_priority(_resMan, _segMan, _state, obj, value);
-#else
- MusicEntry *musicSlot = _music->getSlot(obj);
- if (!musicSlot) {
- warning("cmdSetSoundPriority: Slot not found (%04x:%04x)", PRINT_REG(obj));
- return;
- }
-
- if (value == -1) {
- // Set priority from the song data
- Resource *song = _resMan->findResource(ResourceId(kResourceTypeSound, musicSlot->resnum), 0);
- if (song->data[0] == 0xf0)
- _music->soundSetPriority(musicSlot, song->data[1]);
- else
- warning("cmdSetSoundPriority: Attempt to unset song priority when there is no built-in value");
-
- //pSnd->prio=0;field_15B=0
- PUT_SEL32V(_segMan, obj, flags, GET_SEL32V(_segMan, obj, flags) & 0xFD);
- } else {
- // Scripted priority
-
- //pSnd->field_15B=1;
- PUT_SEL32V(_segMan, obj, flags, GET_SEL32V(_segMan, obj, flags) | 2);
- //DoSOund(0xF,hobj,w)
- }
-#endif
-}
-
-void SoundCommandParser::cmdSetSoundLoop(reg_t obj, int16 value) {
- if (!obj.segment)
- return;
-
-#ifdef USE_OLD_MUSIC_FUNCTIONS
- if (!GET_SEL32(_segMan, obj, nodePtr).isNull()) {
- SongHandle handle = FROBNICATE_HANDLE(obj);
- _state->sfx_song_set_loops(handle, value);
- }
-#else
- MusicEntry *musicSlot = _music->getSlot(obj);
- if (!musicSlot) {
- // Apparently, it's perfectly normal for a game to call cmdSetSoundLoop
- // before actually initializing the sound and adding it to the playlist
- // with cmdInitSound. Usually, it doesn't matter if the game doesn't
- // request to loop the sound, so in this case, don't throw any warning,
- // otherwise do, because the sound won't be looped
- if (value == -1) {
- warning("cmdSetSoundLoop: Slot not found (%04x:%04x) and the song was requested to be looped", PRINT_REG(obj));
- } else {
- // Doesn't really matter
- }
- return;
- }
- if (value == -1) {
- musicSlot->loop = 0xFFFF;
- } else {
- musicSlot->loop = 1; // actually plays the music once
- }
-
- PUT_SEL32V(_segMan, obj, loop, musicSlot->loop);
-#endif
-}
-
-void SoundCommandParser::cmdSuspendSound(reg_t obj, int16 value) {
- // TODO
- warning("STUB: cmdSuspendSound");
-}
-
-#ifndef USE_OLD_MUSIC_FUNCTIONS
-
-void SoundCommandParser::updateSci0Cues() {
- Common::StackLock(_music->_mutex);
-
- const MusicList::iterator end = _music->getPlayListEnd();
- for (MusicList::iterator i = _music->getPlayListStart(); i != end; ++i) {
- // Is the sound stopped, and the sound object updated too? If yes, skip
- // this sound, as SCI0 only allows one active song
- if ((*i)->signal == 0 && (*i)->status != kSoundPlaying)
- continue;
-
- cmdUpdateCues((*i)->soundObj, 0);
- }
-}
-
-#endif
-
-void SoundCommandParser::clearPlayList() {
-#ifndef USE_OLD_MUSIC_FUNCTIONS
- _music->clearPlayList();
-#endif
-}
-
-void SoundCommandParser::syncPlayList(Common::Serializer &s) {
-#ifndef USE_OLD_MUSIC_FUNCTIONS
- _music->saveLoadWithSerializer(s);
-#endif
-}
-
-void SoundCommandParser::reconstructPlayList(int savegame_version) {
-#ifndef USE_OLD_MUSIC_FUNCTIONS
- Common::StackLock lock(_music->_mutex);
-
- _music->resetDriver();
-
- const MusicList::iterator end = _music->getPlayListEnd();
- for (MusicList::iterator i = _music->getPlayListStart(); i != end; ++i) {
- if (savegame_version < 14) {
- (*i)->dataInc = GET_SEL32V(_segMan, (*i)->soundObj, dataInc);
- (*i)->signal = GET_SEL32V(_segMan, (*i)->soundObj, signal);
-
- if (_soundVersion >= SCI_VERSION_1_LATE)
- (*i)->volume = GET_SEL32V(_segMan, (*i)->soundObj, vol);
- }
-
- if ((*i)->resnum && _resMan->testResource(ResourceId(kResourceTypeSound, (*i)->resnum))) {
- (*i)->soundRes = new SoundResource((*i)->resnum, _resMan, _soundVersion);
- _music->soundInitSnd(*i);
- } else {
- (*i)->soundRes = 0;
- }
- if ((*i)->status == kSoundPlaying)
- cmdPlaySound((*i)->soundObj, 0);
- }
-
-#endif
-}
-
-void SoundCommandParser::printPlayList(Console *con) {
-#ifndef USE_OLD_MUSIC_FUNCTIONS
- _music->printPlayList(con);
-#endif
-}
-
-void SoundCommandParser::resetDriver() {
-#ifndef USE_OLD_MUSIC_FUNCTIONS
- _music->resetDriver();
-#endif
-}
-
-} // End of namespace Sci