diff options
author | Filippos Karapetis | 2009-11-12 15:24:11 +0000 |
---|---|---|
committer | Filippos Karapetis | 2009-11-12 15:24:11 +0000 |
commit | fbfafb576e14bdd31d69eb1b6a262bb8d667e852 (patch) | |
tree | 0a31b65e91f3c444cb821e504726f651053a9b6d /engines/sci/engine | |
parent | 3d796d6c088677ab30f1aae0226651f46d46013f (diff) | |
download | scummvm-rg350-fbfafb576e14bdd31d69eb1b6a262bb8d667e852.tar.gz scummvm-rg350-fbfafb576e14bdd31d69eb1b6a262bb8d667e852.tar.bz2 scummvm-rg350-fbfafb576e14bdd31d69eb1b6a262bb8d667e852.zip |
Started objectifying kDoSound()
svn-id: r45862
Diffstat (limited to 'engines/sci/engine')
-rw-r--r-- | engines/sci/engine/ksound.cpp | 964 | ||||
-rw-r--r-- | engines/sci/engine/savegame.cpp | 7 | ||||
-rw-r--r-- | engines/sci/engine/state.cpp | 2 | ||||
-rw-r--r-- | engines/sci/engine/state.h | 3 |
4 files changed, 10 insertions, 966 deletions
diff --git a/engines/sci/engine/ksound.cpp b/engines/sci/engine/ksound.cpp index 9e38799156..31aeb981d0 100644 --- a/engines/sci/engine/ksound.cpp +++ b/engines/sci/engine/ksound.cpp @@ -27,6 +27,7 @@ #include "sci/engine/state.h" #include "sci/sfx/iterator.h" #include "sci/sfx/misc.h" +#include "sci/sfx/soundcmd.h" #include "sci/engine/kernel.h" #include "sci/engine/vm.h" // for Object @@ -34,972 +35,11 @@ namespace Sci { -/* Sound status */ -enum { - _K_SOUND_STATUS_STOPPED = 0, - _K_SOUND_STATUS_INITIALIZED = 1, - _K_SOUND_STATUS_PAUSED = 2, - _K_SOUND_STATUS_PLAYING = 3 -}; - -enum { - _K_SCI0_SOUND_INIT_HANDLE = 0, - _K_SCI0_SOUND_PLAY_HANDLE = 1, - _K_SCI0_SOUND_NOP = 2, - _K_SCI0_SOUND_DISPOSE_HANDLE = 3, - _K_SCI0_SOUND_MUTE_SOUND = 4, - _K_SCI0_SOUND_STOP_HANDLE = 5, - _K_SCI0_SOUND_SUSPEND_HANDLE = 6, - _K_SCI0_SOUND_RESUME_HANDLE = 7, - _K_SCI0_SOUND_VOLUME = 8, - _K_SCI0_SOUND_UPDATE_VOL_PRI = 9, - _K_SCI0_SOUND_FADE_HANDLE = 10, - _K_SCI0_SOUND_GET_POLYPHONY = 11, - _K_SCI0_SOUND_PLAY_NEXT = 12 -}; - -enum { - _K_SCI01_SOUND_MASTER_VOLME = 0, /* Set/Get */ - _K_SCI01_SOUND_MUTE_SOUND = 1, - _K_SCI01_SOUND_UNUSED = 2, - _K_SCI01_SOUND_GET_POLYPHONY = 3, - _K_SCI01_SOUND_UPDATE_HANDLE = 4, - _K_SCI01_SOUND_INIT_HANDLE = 5, - _K_SCI01_SOUND_DISPOSE_HANDLE = 6, - _K_SCI01_SOUND_PLAY_HANDLE = 7, - _K_SCI01_SOUND_STOP_HANDLE = 8, - _K_SCI01_SOUND_SUSPEND_HANDLE = 9, /* or resume */ - _K_SCI01_SOUND_FADE_HANDLE = 10, - _K_SCI01_SOUND_UPDATE_CUES = 11, - _K_SCI01_SOUND_MIDI_SEND = 12, - _K_SCI01_SOUND_REVERB = 13, /* Get/Set */ - _K_SCI01_SOUND_HOLD = 14 -}; - -enum { - _K_SCI1_SOUND_MASTER_VOLME = 0, /* Set/Get */ - _K_SCI1_SOUND_MUTE_SOUND = 1, - _K_SCI1_SOUND_UNUSED1 = 2, - _K_SCI1_SOUND_GET_POLYPHONY = 3, - _K_SCI1_SOUND_GET_AUDIO_CAPABILITY = 4, - _K_SCI1_SOUND_SUSPEND_SOUND = 5, - _K_SCI1_SOUND_INIT_HANDLE = 6, - _K_SCI1_SOUND_DISPOSE_HANDLE = 7, - _K_SCI1_SOUND_PLAY_HANDLE = 8, - _K_SCI1_SOUND_STOP_HANDLE = 9, - _K_SCI1_SOUND_SUSPEND_HANDLE = 10, /* or resume */ - _K_SCI1_SOUND_FADE_HANDLE = 11, - _K_SCI1_SOUND_HOLD_HANDLE = 12, - _K_SCI1_SOUND_UNUSED2 = 13, - _K_SCI1_SOUND_SET_HANDLE_VOLUME = 14, - _K_SCI1_SOUND_SET_HANDLE_PRIORITY = 15, - _K_SCI1_SOUND_SET_HANDLE_LOOP = 16, - _K_SCI1_SOUND_UPDATE_CUES = 17, - _K_SCI1_SOUND_MIDI_SEND = 18, - _K_SCI1_SOUND_REVERB = 19, /* Get/Set */ - _K_SCI1_SOUND_UPDATE_VOL_PRI = 20 -}; - -#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 */ -//#define DEBUG_SOUND // enable for sound debugging - -#define FROBNICATE_HANDLE(reg) ((reg).segment << 16 | (reg).offset) -#define DEFROBNICATE_HANDLE(handle) (make_reg((handle >> 16) & 0xffff, handle & 0xffff)) - - -static void script_set_priority(EngineState *s, reg_t obj, int priority) { - SegManager *segMan = s->_segMan; - int song_nr = GET_SEL32V(segMan, obj, number); - Resource *song = s->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; - - s->_sound.sfx_song_renice(FROBNICATE_HANDLE(obj), priority); - PUT_SEL32V(segMan, obj, flags, flags); -} - -SongIterator *build_iterator(EngineState *s, int song_nr, SongIteratorType type, songit_id_t id) { - Resource *song = s->resMan->findResource(ResourceId(kResourceTypeSound, song_nr), 0); - - if (!song) - return NULL; - - return songit_new(song->data, song->size, type, id); -} - -SongIterator *build_timeriterator(EngineState *s, int delta) { - return new_timer_iterator(delta); -} - -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, _K_SOUND_STATUS_STOPPED); - break; - - default: - warning("Unexpected result from sfx_poll: %d", result); - break; - } - } -} - - -static reg_t kDoSoundSci0(EngineState *s, int argc, reg_t *argv) { - SegManager *segMan = s->_segMan; - reg_t obj = (argc > 1) ? argv[1] : NULL_REG; - uint16 command = argv[0].toUint16(); - SongHandle handle = FROBNICATE_HANDLE(obj); - int number = obj.segment ? - GET_SEL32V(segMan, obj, number) : - -1; /* We were not going to use it anyway */ - -#ifdef DEBUG_SOUND - int i; - - debugC(2, kDebugLevelSound, "Command 0x%x", command); - switch (command) { - case 0: - debugC(2, kDebugLevelSound, "[InitObj]"); - break; - case 1: - debugC(2, kDebugLevelSound, "[Play]"); - break; - case 2: - debugC(2, kDebugLevelSound, "[NOP]"); - break; - case 3: - debugC(2, kDebugLevelSound, "[DisposeHandle]"); - break; - case 4: - debugC(2, kDebugLevelSound, "[SetSoundOn(?)]"); - break; - case 5: - debugC(2, kDebugLevelSound, "[Stop]"); - break; - case 6: - debugC(2, kDebugLevelSound, "[Suspend]"); - break; - case 7: - debugC(2, kDebugLevelSound, "[Resume]"); - break; - case 8: - debugC(2, kDebugLevelSound, "[Get(Set?)Volume]"); - break; - case 9: - debugC(2, kDebugLevelSound, "[Signal: Obj changed]"); - break; - case 10: - debugC(2, kDebugLevelSound, "[Fade(?)]"); - break; - case 11: - debugC(2, kDebugLevelSound, "[ChkDriver]"); - break; - case 12: - debugC(2, kDebugLevelSound, "[PlayNextSong (formerly StopAll)]"); - break; - default: - debugC(2, kDebugLevelSound, "[unknown]"); - break; - } - - debugC(2, kDebugLevelSound, "("); - for (i = 1; i < argc; i++) { - debugC(2, kDebugLevelSound, "%04x:%04x", PRINT_REG(argv[i])); - if (i + 1 < argc) - debugC(2, kDebugLevelSound, ", "); - } - debugC(2, kDebugLevelSound, ")\n"); -#endif // DEBUG_SOUND - - - switch (command) { - case _K_SCI0_SOUND_INIT_HANDLE: - if (obj.segment) { - debugC(2, kDebugLevelSound, "Initializing song number %d\n", GET_SEL32V(segMan, obj, number)); - s->_sound.sfx_add_song(build_iterator(s, number, SCI_SONG_ITERATOR_TYPE_SCI0, - handle), 0, handle, number); - - PUT_SEL32V(segMan, obj, state, _K_SOUND_STATUS_INITIALIZED); - PUT_SEL32(segMan, obj, handle, obj); /* ``sound handle'': we use the object address */ - } - break; - - case _K_SCI0_SOUND_PLAY_HANDLE: - if (obj.segment) { - s->_sound.sfx_song_set_status(handle, SOUND_STATUS_PLAYING); - s->_sound.sfx_song_set_loops(handle, GET_SEL32V(segMan, obj, loop)); - PUT_SEL32V(segMan, obj, state, _K_SOUND_STATUS_PLAYING); - } - break; - - case _K_SCI0_SOUND_NOP: - break; - - case _K_SCI0_SOUND_DISPOSE_HANDLE: - if (obj.segment) { - s->_sound.sfx_remove_song(handle); - } - PUT_SEL32V(segMan, obj, handle, 0x0000); - break; - - case _K_SCI0_SOUND_STOP_HANDLE: - if (obj.segment) { - s->_sound.sfx_song_set_status(handle, SOUND_STATUS_STOPPED); - PUT_SEL32V(segMan, obj, state, SOUND_STATUS_STOPPED); - } - break; - - case _K_SCI0_SOUND_SUSPEND_HANDLE: - if (obj.segment) { - s->_sound.sfx_song_set_status(handle, SOUND_STATUS_SUSPENDED); - PUT_SEL32V(segMan, obj, state, SOUND_STATUS_SUSPENDED); - } - break; - - case _K_SCI0_SOUND_RESUME_HANDLE: - if (obj.segment) { - s->_sound.sfx_song_set_status(handle, SOUND_STATUS_PLAYING); - PUT_SEL32V(segMan, obj, state, SOUND_STATUS_PLAYING); - } - break; - - case _K_SCI0_SOUND_MUTE_SOUND: { - /* if there's a parameter, we're setting it. Otherwise, - we're querying it. */ - /*int param = UPARAM_OR_ALT(1,-1); - - if (param != -1) - s->acc = s->sound_server->command(s, SOUND_COMMAND_SET_MUTE, 0, param); - else - s->acc = s->sound_server->command(s, SOUND_COMMAND_GET_MUTE, 0, 0);*/ - - } - break; - - case _K_SCI0_SOUND_VOLUME: { - /* range from 0x0 to 0xf */ - /* parameter optional. If present, set.*/ - int vol = (argc > 1) ? argv[1].toSint16() : -1; - - if (vol != -1) - s->_sound.sfx_setVolume(vol); - else - s->r_acc = make_reg(0, s->_sound.sfx_getVolume()); - } - break; - - case _K_SCI0_SOUND_UPDATE_VOL_PRI: - if (obj.segment) { - s->_sound.sfx_song_set_loops(handle, GET_SEL32V(segMan, obj, loop)); - script_set_priority(s, obj, GET_SEL32V(segMan, obj, pri)); - } - break; - - case _K_SCI0_SOUND_FADE_HANDLE: - /*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! */ - if (obj.segment) { - s->_sound.sfx_song_set_status(handle, SOUND_STATUS_STOPPED); - PUT_SEL32V(segMan, obj, state, SOUND_STATUS_STOPPED); - PUT_SEL32V(segMan, obj, signal, SIGNAL_OFFSET); - } - break; - - case _K_SCI0_SOUND_GET_POLYPHONY: - s->r_acc = make_reg(0, s->_sound.sfx_get_player_polyphony()); - break; - - case _K_SCI0_SOUND_PLAY_NEXT: - /* s->_sound.sfx_all_stop();*/ - break; - - default: - warning("Unhandled DoSound command: %x", command); - - } - // process_sound_events(s); /* Take care of incoming events */ - - return s->r_acc; -} - - -static reg_t kDoSoundSci1Early(EngineState *s, int argc, reg_t *argv) { - SegManager *segMan = s->_segMan; - uint16 command = argv[0].toUint16(); - reg_t obj = (argc > 1) ? argv[1] : NULL_REG; - SongHandle handle = FROBNICATE_HANDLE(obj); - int number = obj.segment ? - GET_SEL32V(segMan, obj, number) : - -1; /* We were not going to use it anyway */ - -#ifdef DEBUG_SOUND - if (command != _K_SCI01_SOUND_UPDATE_CUES) { - int i; - - debugC(2, kDebugLevelSound, "Command 0x%x", command); - switch (command) { - case 0: - debugC(2, kDebugLevelSound, "[MasterVolume]"); - break; - case 1: - debugC(2, kDebugLevelSound, "[Mute]"); - break; - case 2: - debugC(2, kDebugLevelSound, "[NOP(2)]"); - break; - case 3: - debugC(2, kDebugLevelSound, "[GetPolyphony]"); - break; - case 4: - debugC(2, kDebugLevelSound, "[Update]"); - break; - case 5: - debugC(2, kDebugLevelSound, "[Init]"); - break; - case 6: - debugC(2, kDebugLevelSound, "[Dispose]"); - break; - case 7: - debugC(2, kDebugLevelSound, "[Play]"); - break; - case 8: - debugC(2, kDebugLevelSound, "[Stop]"); - break; - case 9: - debugC(2, kDebugLevelSound, "[Suspend]"); - break; - case 10: - debugC(2, kDebugLevelSound, "[Fade]"); - break; - case 11: - debugC(2, kDebugLevelSound, "[UpdateCues]"); - break; - case 12: - debugC(2, kDebugLevelSound, "[MidiSend]"); - break; - case 13: - debugC(2, kDebugLevelSound, "[Reverb]"); - break; - case 14: - debugC(2, kDebugLevelSound, "[Hold]"); - break; - default: - debugC(2, kDebugLevelSound, "[unknown]"); - break; - } - - debugC(2, kDebugLevelSound, "("); - for (i = 1; i < argc; i++) { - debugC(2, kDebugLevelSound, "%04x:%04x", PRINT_REG(argv[i])); - if (i + 1 < argc) - debugC(2, kDebugLevelSound, ", "); - } - debugC(2, kDebugLevelSound, ")\n"); - } -#endif - - switch (command) { - case _K_SCI01_SOUND_MASTER_VOLME : { - int vol = (argc > 1) ? argv[1].toSint16() : -1; - - if (vol != -1) - s->_sound.sfx_setVolume(vol); - else - s->r_acc = make_reg(0, s->_sound.sfx_getVolume()); - break; - } - case _K_SCI01_SOUND_MUTE_SOUND : { - /* if there's a parameter, we're setting it. Otherwise, - we're querying it. */ - /*int param = UPARAM_OR_ALT(1,-1); - - if (param != -1) - s->acc = s->sound_server->command(s, SOUND_COMMAND_SET_MUTE, 0, param); - else - s->acc = s->sound_server->command(s, SOUND_COMMAND_GET_MUTE, 0, 0);*/ - - break; - } - case _K_SCI01_SOUND_UNUSED : { - break; - } - case _K_SCI01_SOUND_GET_POLYPHONY : { - s->r_acc = make_reg(0, s->_sound.sfx_get_player_polyphony()); - break; - } - case _K_SCI01_SOUND_PLAY_HANDLE : { - int looping = GET_SEL32V(segMan, obj, loop); - //int vol = GET_SEL32V(segMan, obj, vol); - int pri = GET_SEL32V(segMan, obj, pri); - RESTORE_BEHAVIOR rb = (RESTORE_BEHAVIOR) argv[2].toUint16(); /* Too lazy to look up a default value for this */ - - if (obj.segment) { - s->_sound.sfx_song_set_status(handle, SOUND_STATUS_PLAYING); - s->_sound.sfx_song_set_loops(handle, looping); - s->_sound.sfx_song_renice(handle, pri); - s->_sound._songlib.setSongRestoreBehavior(handle, rb); - PUT_SEL32V(segMan, obj, signal, 0); - } - - break; - } - case _K_SCI01_SOUND_INIT_HANDLE : { - //int looping = GET_SEL32V(segMan, obj, loop); - //int vol = GET_SEL32V(segMan, obj, vol); - //int pri = GET_SEL32V(segMan, obj, pri); - - if (obj.segment && (s->resMan->testResource(ResourceId(kResourceTypeSound, number)))) { - debugC(2, kDebugLevelSound, "Initializing song number %d\n", number); - s->_sound.sfx_add_song(build_iterator(s, number, SCI_SONG_ITERATOR_TYPE_SCI1, - handle), 0, handle, number); - PUT_SEL32(segMan, obj, nodePtr, obj); - PUT_SEL32(segMan, obj, handle, obj); - } - break; - } - case _K_SCI01_SOUND_DISPOSE_HANDLE : { - if (obj.segment) { - s->_sound.sfx_song_set_status(handle, SOUND_STATUS_STOPPED); - s->_sound.sfx_remove_song(handle); - } - break; - } - case _K_SCI01_SOUND_UPDATE_HANDLE : { - /* FIXME: Get these from the sound server */ - int signal = 0; - int min = 0; - int sec = 0; - int frame = 0; - - /* FIXME: Update the sound server state with 'vol' */ - int looping = GET_SEL32V(segMan, obj, loop); - //int vol = GET_SEL32V(segMan, obj, vol); - int pri = GET_SEL32V(segMan, obj, pri); - - s->_sound.sfx_song_set_loops(handle, looping); - s->_sound.sfx_song_renice(handle, pri); - - debugC(2, kDebugLevelSound, "[sound01-update-handle] -- CUE %04x:%04x", PRINT_REG(obj)); - - PUT_SEL32V(segMan, obj, signal, signal); - PUT_SEL32V(segMan, obj, min, min); - PUT_SEL32V(segMan, obj, sec, sec); - PUT_SEL32V(segMan, obj, frame, frame); - - break; - } - case _K_SCI01_SOUND_STOP_HANDLE : { - PUT_SEL32V(segMan, obj, signal, SIGNAL_OFFSET); - if (obj.segment) { - s->_sound.sfx_song_set_status(handle, SOUND_STATUS_STOPPED); - } - break; - } - case _K_SCI01_SOUND_SUSPEND_HANDLE : { - int state = argv[2].toUint16(); - int setstate = (state) ? - SOUND_STATUS_SUSPENDED : SOUND_STATUS_PLAYING; - - if (obj.segment) { - s->_sound.sfx_song_set_status(handle, setstate); - } - break; - } - case _K_SCI01_SOUND_FADE_HANDLE : { - /* There are four parameters that control the fade here. - * TODO: Figure out the exact semantics */ - - /* FIXME: The next couple of lines actually STOP the song right away */ - PUT_SEL32V(segMan, obj, signal, SIGNAL_OFFSET); - if (obj.segment) { - s->_sound.sfx_song_set_status(handle, SOUND_STATUS_STOPPED); - } - break; - } - case _K_SCI01_SOUND_UPDATE_CUES : { - int signal = 0; - int min = 0; - int sec = 0; - int frame = 0; - int result = SI_LOOP; /* small hack */ - int cue = 0; - - while (result == SI_LOOP) - result = s->_sound.sfx_poll_specific(handle, &cue); - - switch (result) { - - case SI_ABSOLUTE_CUE: - signal = cue; - debugC(2, kDebugLevelSound, "--- [CUE] %04x:%04x Absolute Cue: %d\n", - PRINT_REG(obj), signal); - - PUT_SEL32V(segMan, obj, signal, signal); - break; - - case SI_RELATIVE_CUE: - signal = cue; - debugC(2, kDebugLevelSound, "--- [CUE] %04x:%04x Relative Cue: %d\n", - PRINT_REG(obj), cue); - - /* FIXME to match commented-out semantics - * below, with proper storage of dataInc and - * signal in the iterator code. */ - PUT_SEL32V(segMan, obj, dataInc, signal); - PUT_SEL32V(segMan, obj, signal, signal); - 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; */ - /* } */ - - PUT_SEL32V(segMan, obj, min, min); - PUT_SEL32V(segMan, obj, sec, sec); - PUT_SEL32V(segMan, obj, frame, frame); - break; - } - case _K_SCI01_SOUND_MIDI_SEND : { - int channel = argv[2].toSint16(); - int midiCmd = argv[3].toUint16() == 0xff ? - 0xe0 : /* Pitch wheel */ - 0xb0; /* argv[3].toUint16() is actually a controller number */ - int controller = argv[3].toUint16(); - int param = argv[4].toUint16(); - - s->_sound.sfx_send_midi(handle, - channel, midiCmd, controller, param); - break; - } - case _K_SCI01_SOUND_REVERB : { - break; - } - case _K_SCI01_SOUND_HOLD : { - //int flag = argv[2].toSint16(); - break; - } - } - - return s->r_acc; -} - -static reg_t kDoSoundSci1Late(EngineState *s, int argc, reg_t *argv) { - SegManager *segMan = s->_segMan; - uint16 command = argv[0].toUint16(); - reg_t obj = (argc > 1) ? argv[1] : NULL_REG; - SongHandle handle = FROBNICATE_HANDLE(obj); - int number = obj.segment ? - GET_SEL32V(segMan, obj, number) : - -1; /* We were not going to use it anyway */ - -#ifdef DEBUG_SOUND - if (command != _K_SCI1_SOUND_UPDATE_CUES) { - int i; - - debugC(2, kDebugLevelSound, "Command 0x%x", command); - switch (command) { - case 0: - debugC(2, kDebugLevelSound, "[MasterVolume]"); - break; - case 1: - debugC(2, kDebugLevelSound, "[Mute]"); - break; - case 2: - debugC(2, kDebugLevelSound, "[NOP(2)]"); - break; - case 3: - debugC(2, kDebugLevelSound, "[GetPolyphony]"); - break; - case 4: - debugC(2, kDebugLevelSound, "[GetAudioCapability]"); - break; - case 5: - debugC(2, kDebugLevelSound, "[GlobalSuspend]"); - break; - case 6: - debugC(2, kDebugLevelSound, "[Init]"); - break; - case 7: - debugC(2, kDebugLevelSound, "[Dispose]"); - break; - case 8: - debugC(2, kDebugLevelSound, "[Play]"); - break; - case 9: - debugC(2, kDebugLevelSound, "[Stop]"); - break; - case 10: - debugC(2, kDebugLevelSound, "[SuspendHandle]"); - break; - case 11: - debugC(2, kDebugLevelSound, "[Fade]"); - break; - case 12: - debugC(2, kDebugLevelSound, "[Hold]"); - break; - case 13: - debugC(2, kDebugLevelSound, "[Unused(13)]"); - break; - case 14: - debugC(2, kDebugLevelSound, "[SetVolume]"); - break; - case 15: - debugC(2, kDebugLevelSound, "[SetPriority]"); - break; - case 16: - debugC(2, kDebugLevelSound, "[SetLoop]"); - break; - case 17: - debugC(2, kDebugLevelSound, "[UpdateCues]"); - break; - case 18: - debugC(2, kDebugLevelSound, "[MidiSend]"); - break; - case 19: - debugC(2, kDebugLevelSound, "[Reverb]"); - break; - case 20: - debugC(2, kDebugLevelSound, "[UpdateVolPri]"); - break; - default: - debugC(2, kDebugLevelSound, "[unknown]"); - break; - } - - debugC(2, kDebugLevelSound, "("); - for (i = 1; i < argc; i++) { - debugC(2, kDebugLevelSound, "%04x:%04x", PRINT_REG(argv[i])); - if (i + 1 < argc) - debugC(2, kDebugLevelSound, ", "); - } - debugC(2, kDebugLevelSound, ")\n"); - } -#endif // DEBUG_SOUND - - switch (command) { - case _K_SCI1_SOUND_MASTER_VOLME : { - int vol = (argc > 1 ? argv[1].offset : -1); - - if (vol != -1) - s->_sound.sfx_setVolume(vol); - - s->r_acc = make_reg(0, s->_sound.sfx_getVolume()); - break; - } - case _K_SCI1_SOUND_MUTE_SOUND : { - /* if there's a parameter, we're setting it. Otherwise, - we're querying it. */ - /*int param = UPARAM_OR_ALT(1,-1); - - if (param != -1) - s->acc = s->sound_server->command(s, SOUND_COMMAND_SET_MUTE, 0, param); - else - s->acc = s->sound_server->command(s, SOUND_COMMAND_GET_MUTE, 0, 0); - break;*/ - } - case _K_SCI1_SOUND_UNUSED1 : { - break; - } - case _K_SCI1_SOUND_GET_POLYPHONY : { - /*s->acc = s->sound_server->command(s, SOUND_COMMAND_TEST, 0, 0);*/ - break; - } - case _K_SCI1_SOUND_GET_AUDIO_CAPABILITY : { - // Tests for digital audio support - return make_reg(0, 1); - } - case _K_SCI1_SOUND_PLAY_HANDLE : { - 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 = s->_sound._songlib.findSong(handle); - - if (GET_SEL32V(segMan, obj, nodePtr) && (song && number != song->_resourceNum)) { - s->_sound.sfx_song_set_status(handle, SOUND_STATUS_STOPPED); - s->_sound.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 (s->resMan->testResource(ResourceId(kResourceTypeAudio, number)) && - getSciVersion() >= SCI_VERSION_1_1) { - // Found a relevant audio resource, play it - s->_audio->stopAudio(); - warning("Initializing audio resource instead of requested sound resource %d", number); - sampleLen = s->_audio->startAudio(65535, number); - // Also create iterator, that will fire SI_FINISHED event, when the sound is done playing - s->_sound.sfx_add_song(build_timeriterator(s, sampleLen), 0, handle, number); - } else { - if (!s->resMan->testResource(ResourceId(kResourceTypeSound, number))) { - warning("Could not open song number %d", number); - // Send a "stop handle" event so that the engine won't wait forever here - s->_sound.sfx_song_set_status(handle, SOUND_STATUS_STOPPED); - PUT_SEL32V(segMan, obj, signal, SIGNAL_OFFSET); - return s->r_acc; - } - debugC(2, kDebugLevelSound, "Initializing song number %d\n", number); - s->_sound.sfx_add_song(build_iterator(s, number, SCI_SONG_ITERATOR_TYPE_SCI1, - handle), 0, handle, number); - } - - PUT_SEL32(segMan, obj, nodePtr, obj); - PUT_SEL32(segMan, obj, handle, obj); - } - - if (obj.segment) { - s->_sound.sfx_song_set_status(handle, SOUND_STATUS_PLAYING); - s->_sound.sfx_song_set_loops(handle, looping); - s->_sound.sfx_song_renice(handle, pri); - PUT_SEL32V(segMan, obj, signal, 0); - } - - break; - } - case _K_SCI1_SOUND_INIT_HANDLE : { - //int looping = GET_SEL32V(segMan, obj, loop); - //int vol = GET_SEL32V(segMan, obj, vol); - //int pri = GET_SEL32V(segMan, obj, pri); - - if (GET_SEL32V(segMan, obj, nodePtr)) { - s->_sound.sfx_song_set_status(handle, SOUND_STATUS_STOPPED); - s->_sound.sfx_remove_song(handle); - } - - if (obj.segment && (s->resMan->testResource(ResourceId(kResourceTypeSound, number)))) { - debugC(2, kDebugLevelSound, "Initializing song number %d\n", number); - s->_sound.sfx_add_song(build_iterator(s, number, SCI_SONG_ITERATOR_TYPE_SCI1, - handle), 0, handle, number); - PUT_SEL32(segMan, obj, nodePtr, obj); - PUT_SEL32(segMan, obj, handle, obj); - } - break; - } - case _K_SCI1_SOUND_DISPOSE_HANDLE : { - if (obj.segment) { - s->_sound.sfx_song_set_status(handle, SOUND_STATUS_STOPPED); - s->_sound.sfx_remove_song(handle); - } - break; - } - case _K_SCI1_SOUND_STOP_HANDLE : { - PUT_SEL32V(segMan, obj, signal, SIGNAL_OFFSET); - if (obj.segment) { - s->_sound.sfx_song_set_status(handle, SOUND_STATUS_STOPPED); - } - break; - } - case _K_SCI1_SOUND_SUSPEND_HANDLE : { - break; - } - case _K_SCI1_SOUND_FADE_HANDLE : { - fade_params_t fade; - if (obj.segment) { - 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; - - s->_sound.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); - s->_sound.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); - } - } - break; - } - case _K_SCI1_SOUND_HOLD_HANDLE : { - int value = argv[2].toSint16(); - - s->_sound.sfx_song_set_hold(handle, value); - break; - } - case _K_SCI1_SOUND_UNUSED2 : { - break; - } - case _K_SCI1_SOUND_SET_HANDLE_VOLUME : { - break; - } - case _K_SCI1_SOUND_SET_HANDLE_PRIORITY : { - int value = argv[2].toSint16(); - - script_set_priority(s, obj, value); - break; - } - case _K_SCI1_SOUND_SET_HANDLE_LOOP : { - if (!GET_SEL32(segMan, obj, nodePtr).isNull()) { - uint16 looping = argv[2].toUint16(); - - if (looping < 65535) - looping = 1; - - s->_sound.sfx_song_set_loops(handle, looping); - PUT_SEL32V(segMan, obj, loop, looping); - } - break; - } - case _K_SCI1_SOUND_UPDATE_CUES : { - int signal = 0; - //int min = 0; - //int sec = 0; - //int frame = 0; - int result = SI_LOOP; /* small hack */ - int cue = 0; - - while (result == SI_LOOP) - result = s->_sound.sfx_poll_specific(handle, &cue); - - switch (result) { - - case SI_ABSOLUTE_CUE: - signal = cue; - debugC(2, kDebugLevelSound, "[CUE] %04x:%04x Absolute Cue: %d\n", - PRINT_REG(obj), 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), cue); - - PUT_SEL32V(segMan, obj, dataInc, cue); - PUT_SEL32V(segMan, obj, signal, cue + 127); - break; - - case SI_FINISHED: - PUT_SEL32V(segMan, obj, signal, SIGNAL_OFFSET); - break; - - case SI_LOOP: - break; /* Doesn't happen */ - } - break; - } - case _K_SCI1_SOUND_MIDI_SEND : { - s->_sound.sfx_send_midi(handle, - argv[2].toUint16(), argv[3].toUint16(), argv[4].toUint16(), argv[5].toUint16()); - break; - } - case _K_SCI1_SOUND_REVERB : { - break; - } - case _K_SCI1_SOUND_UPDATE_VOL_PRI : { - break; - } - } - return s->r_acc; -} - /** * Used for synthesized music playback */ reg_t kDoSound(EngineState *s, int argc, reg_t *argv) { - switch (s->detectDoSoundType()) { - case SCI_VERSION_0_EARLY: - return kDoSoundSci0(s, argc, argv); - case SCI_VERSION_1_EARLY: - return kDoSoundSci1Early(s, argc, argv); - case SCI_VERSION_1_LATE: - return kDoSoundSci1Late(s, argc, argv); - default: - warning("Unknown DoSound type"); - return NULL_REG; - } + return s->_soundCmd->parseCommand(argc, argv, s->r_acc); } reg_t kDoCdAudio(EngineState *s, int argc, reg_t *argv) { diff --git a/engines/sci/engine/savegame.cpp b/engines/sci/engine/savegame.cpp index 046d4194d9..03b31b39c7 100644 --- a/engines/sci/engine/savegame.cpp +++ b/engines/sci/engine/savegame.cpp @@ -55,8 +55,7 @@ const uint32 INTMAPPER_MAGIC_KEY = 0xDEADBEEF; // from ksound.cpp: -//SongIterator *build_iterator(ResourceManager *resMan, int song_nr, SongIteratorType type, songit_id_t id); -SongIterator *build_iterator(EngineState *s, int song_nr, SongIteratorType type, songit_id_t id); +SongIterator *build_iterator(ResourceManager *resMan, int song_nr, SongIteratorType type, songit_id_t id); #pragma mark - @@ -708,8 +707,7 @@ static void reconstruct_sounds(EngineState *s) { int oldstatus; SongIterator::Message msg; - //base = ff = build_iterator(s->resMan, seeker->_resourceNum, it_type, seeker->_handle); - base = ff = build_iterator(s, seeker->_resourceNum, it_type, seeker->_handle); + base = ff = build_iterator(s->resMan, seeker->_resourceNum, it_type, seeker->_handle); if (seeker->_restoreBehavior == RESTORE_BEHAVIOR_CONTINUE) ff = new_fast_forward_iterator(base, seeker->_restoreTime); ff->init(); @@ -772,6 +770,7 @@ EngineState *gamestate_restore(EngineState *s, Common::SeekableReadStream *fh) { // Copy some old data retval->gfx_state = s->gfx_state; + retval->_soundCmd = s->_soundCmd; retval->saveLoadWithSerializer(ser); // FIXME: Error handling? diff --git a/engines/sci/engine/state.cpp b/engines/sci/engine/state.cpp index 5f325cd794..9245d7c1df 100644 --- a/engines/sci/engine/state.cpp +++ b/engines/sci/engine/state.cpp @@ -108,6 +108,8 @@ EngineState::EngineState(ResourceManager *res, Kernel *kernel, Vocabulary *voc, _moveCountType = kMoveCountUninitialized; _usesCdTrack = Common::File::exists("cdaudio.map"); + + _soundCmd = 0; } EngineState::~EngineState() { diff --git a/engines/sci/engine/state.h b/engines/sci/engine/state.h index e2368a505d..7332eae61c 100644 --- a/engines/sci/engine/state.h +++ b/engines/sci/engine/state.h @@ -44,6 +44,7 @@ namespace Common { #include "sci/gfx/gfx_system.h" #include "sci/sfx/audio.h" #include "sci/sfx/core.h" +#include "sci/sfx/soundcmd.h" namespace Sci { @@ -51,6 +52,7 @@ class Menubar; class SciGui; class SciGuiCursor; class MessageState; +class SoundCommandParser; struct GfxState; struct GfxPort; @@ -137,6 +139,7 @@ public: AudioPlayer *_audio; SfxState _sound; /**< sound subsystem */ + SoundCommandParser *_soundCmd; int sfx_init_flags; /**< flags the sfx subsystem was initialised with */ byte restarting_flags; /**< Flags used for restarting */ |