[Scummvm-cvs-logs] SF.net SVN: scummvm:[45862] scummvm/trunk/engines/sci

thebluegr at users.sourceforge.net thebluegr at users.sourceforge.net
Thu Nov 12 16:24:12 CET 2009


Revision: 45862
          http://scummvm.svn.sourceforge.net/scummvm/?rev=45862&view=rev
Author:   thebluegr
Date:     2009-11-12 15:24:11 +0000 (Thu, 12 Nov 2009)

Log Message:
-----------
Started objectifying kDoSound()

Modified Paths:
--------------
    scummvm/trunk/engines/sci/engine/ksound.cpp
    scummvm/trunk/engines/sci/engine/savegame.cpp
    scummvm/trunk/engines/sci/engine/state.cpp
    scummvm/trunk/engines/sci/engine/state.h
    scummvm/trunk/engines/sci/module.mk
    scummvm/trunk/engines/sci/sci.cpp

Added Paths:
-----------
    scummvm/trunk/engines/sci/sfx/soundcmd.cpp
    scummvm/trunk/engines/sci/sfx/soundcmd.h

Modified: scummvm/trunk/engines/sci/engine/ksound.cpp
===================================================================
--- scummvm/trunk/engines/sci/engine/ksound.cpp	2009-11-12 13:29:09 UTC (rev 45861)
+++ scummvm/trunk/engines/sci/engine/ksound.cpp	2009-11-12 15:24:11 UTC (rev 45862)
@@ -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) {

Modified: scummvm/trunk/engines/sci/engine/savegame.cpp
===================================================================
--- scummvm/trunk/engines/sci/engine/savegame.cpp	2009-11-12 13:29:09 UTC (rev 45861)
+++ scummvm/trunk/engines/sci/engine/savegame.cpp	2009-11-12 15:24:11 UTC (rev 45862)
@@ -55,8 +55,7 @@
 
 
 // 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 @@
 		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 @@
 
 	// Copy some old data
 	retval->gfx_state = s->gfx_state;
+	retval->_soundCmd = s->_soundCmd;
 
 	retval->saveLoadWithSerializer(ser);	// FIXME: Error handling?
 

Modified: scummvm/trunk/engines/sci/engine/state.cpp
===================================================================
--- scummvm/trunk/engines/sci/engine/state.cpp	2009-11-12 13:29:09 UTC (rev 45861)
+++ scummvm/trunk/engines/sci/engine/state.cpp	2009-11-12 15:24:11 UTC (rev 45862)
@@ -108,6 +108,8 @@
 	_moveCountType = kMoveCountUninitialized;
 	
 	_usesCdTrack = Common::File::exists("cdaudio.map");
+
+	_soundCmd = 0;
 }
 
 EngineState::~EngineState() {

Modified: scummvm/trunk/engines/sci/engine/state.h
===================================================================
--- scummvm/trunk/engines/sci/engine/state.h	2009-11-12 13:29:09 UTC (rev 45861)
+++ scummvm/trunk/engines/sci/engine/state.h	2009-11-12 15:24:11 UTC (rev 45862)
@@ -44,6 +44,7 @@
 #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 SciGui;
 class SciGuiCursor;
 class MessageState;
+class SoundCommandParser;
 
 struct GfxState;
 struct GfxPort;
@@ -137,6 +139,7 @@
 
 	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 */

Modified: scummvm/trunk/engines/sci/module.mk
===================================================================
--- scummvm/trunk/engines/sci/module.mk	2009-11-12 13:29:09 UTC (rev 45861)
+++ scummvm/trunk/engines/sci/module.mk	2009-11-12 15:24:11 UTC (rev 45862)
@@ -71,6 +71,7 @@
 	sfx/core.o \
 	sfx/iterator.o \
 	sfx/songlib.o \
+	sfx/soundcmd.o \
 	sfx/seq/gm.o \
 	sfx/seq/instrument-map.o \
 	sfx/seq/map-mt32-to-gm.o \

Modified: scummvm/trunk/engines/sci/sci.cpp
===================================================================
--- scummvm/trunk/engines/sci/sci.cpp	2009-11-12 13:29:09 UTC (rev 45861)
+++ scummvm/trunk/engines/sci/sci.cpp	2009-11-12 15:24:11 UTC (rev 45862)
@@ -41,6 +41,7 @@
 #include "sci/gui32/gui32.h"
 #endif
 #include "sci/sfx/audio.h"
+#include "sci/sfx/soundcmd.h"
 #include "sci/gui/gui.h"
 #include "sci/gui/gui_palette.h"
 #include "sci/gui/gui_cursor.h"
@@ -161,6 +162,8 @@
 	// since we cannot let the game control where saves are stored)
 	strcpy(_gamestate->sys_strings->_strings[SYS_STRING_SAVEDIR]._value, "/");
 
+	_gamestate->_soundCmd = new SoundCommandParser(_resMan, segMan, &_gamestate->_sound, _audio, _gamestate->detectDoSoundType());
+
 	GfxState gfx_state;
 	_gamestate->gfx_state = &gfx_state;
 
@@ -191,6 +194,8 @@
 	game_exit(_gamestate);
 	script_free_breakpoints(_gamestate);
 
+	delete _gamestate->_soundCmd;
+	delete _gamestate->_gui;
 	delete segMan;
 	delete cursor;
 	delete palette;

Added: scummvm/trunk/engines/sci/sfx/soundcmd.cpp
===================================================================
--- scummvm/trunk/engines/sci/sfx/soundcmd.cpp	                        (rev 0)
+++ scummvm/trunk/engines/sci/sfx/soundcmd.cpp	2009-11-12 15:24:11 UTC (rev 45862)
@@ -0,0 +1,567 @@
+/* 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/sfx/iterator.h"	// for SongIteratorStatus
+#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 */
+
+#define FROBNICATE_HANDLE(reg) ((reg).segment << 16 | (reg).offset)
+#define DEFROBNICATE_HANDLE(handle) (make_reg((handle >> 16) & 0xffff, handle & 0xffff))
+
+/* Sound status */
+enum {
+	_K_SOUND_STATUS_STOPPED = 0,
+	_K_SOUND_STATUS_INITIALIZED = 1,
+	_K_SOUND_STATUS_PAUSED = 2,
+	_K_SOUND_STATUS_PLAYING = 3
+};
+
+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, _K_SOUND_STATUS_STOPPED);
+			break;
+
+		default:
+			warning("Unexpected result from sfx_poll: %d", result);
+			break;
+		}
+	}
+}
+
+#define SOUNDCOMMAND(x) _soundCommands.push_back(new SciSoundCommand(#x, &SoundCommandParser::x))
+
+SoundCommandParser::SoundCommandParser(ResourceManager *resMan, SegManager *segMan, SfxState *state, AudioPlayer *audio, SciVersion doSoundVersion) : 
+	_resMan(resMan), _segMan(segMan), _state(state), _audio(audio), _doSoundVersion(doSoundVersion) {
+
+	switch (doSoundVersion) {
+	case SCI_VERSION_0_EARLY:
+		SOUNDCOMMAND(cmdInitHandle);
+		SOUNDCOMMAND(cmdPlayHandle);
+		SOUNDCOMMAND(cmdDummy);
+		SOUNDCOMMAND(cmdDisposeHandle);
+		SOUNDCOMMAND(cmdMuteSound);
+		SOUNDCOMMAND(cmdStopHandle);
+		SOUNDCOMMAND(cmdSuspendHandle);
+		SOUNDCOMMAND(cmdResumeHandle);
+		SOUNDCOMMAND(cmdVolume);
+		SOUNDCOMMAND(cmdHandlePriority);
+		SOUNDCOMMAND(cmdFadeHandle);
+		SOUNDCOMMAND(cmdGetPolyphony);
+		SOUNDCOMMAND(cmdGetPlayNext);
+		break;
+	case SCI_VERSION_1_EARLY:
+		SOUNDCOMMAND(cmdVolume);
+		SOUNDCOMMAND(cmdMuteSound);
+		SOUNDCOMMAND(cmdDummy);
+		SOUNDCOMMAND(cmdGetPolyphony);
+		SOUNDCOMMAND(cmdUpdateHandle);
+		SOUNDCOMMAND(cmdInitHandle);
+		SOUNDCOMMAND(cmdDisposeHandle);
+		SOUNDCOMMAND(cmdPlayHandle);
+		SOUNDCOMMAND(cmdStopHandle);
+		SOUNDCOMMAND(cmdSuspendHandle);
+		SOUNDCOMMAND(cmdFadeHandle);
+		SOUNDCOMMAND(cmdUpdateCues);
+		SOUNDCOMMAND(cmdSendMidi);
+		SOUNDCOMMAND(cmdReverb);
+		SOUNDCOMMAND(cmdHoldHandle);
+		break;
+	case SCI_VERSION_1_LATE:
+		SOUNDCOMMAND(cmdVolume);
+		SOUNDCOMMAND(cmdMuteSound);
+		SOUNDCOMMAND(cmdDummy);
+		SOUNDCOMMAND(cmdGetPolyphony);
+		SOUNDCOMMAND(cmdGetAudioCapability);
+		SOUNDCOMMAND(cmdSuspendSound);
+		SOUNDCOMMAND(cmdInitHandle);
+		SOUNDCOMMAND(cmdDisposeHandle);
+		SOUNDCOMMAND(cmdPlayHandle);
+		SOUNDCOMMAND(cmdStopHandle);
+		SOUNDCOMMAND(cmdSuspendHandle);
+		SOUNDCOMMAND(cmdFadeHandle);
+		SOUNDCOMMAND(cmdHoldHandle);
+		SOUNDCOMMAND(cmdDummy);
+		SOUNDCOMMAND(cmdSetHandleVolume);
+		SOUNDCOMMAND(cmdSetHandlePriority);
+		SOUNDCOMMAND(cmdSetHandleLoop);
+		SOUNDCOMMAND(cmdUpdateCues);
+		SOUNDCOMMAND(cmdSendMidi);
+		SOUNDCOMMAND(cmdReverb);
+		SOUNDCOMMAND(cmdUpdateVolumePriority);
+		break;
+	default:
+		warning("Sound command parser: unknown DoSound type %d", doSoundVersion);
+		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;
+	SongHandle handle = FROBNICATE_HANDLE(obj);
+	int value = (argc > 2) ? argv[2].toSint16() : 0;
+	_acc = acc;
+
+	if (argc > 5) {	// for cmdSendMidi
+		_midiCmd = argv[3].toUint16() == 0xff ?
+					  0xe0 : /* Pitch wheel */
+					  0xb0; /* argv[3].toUint16() is actually a controller number */
+		_controller = argv[3].toUint16();
+		_param = argv[4].toUint16();
+	}
+
+	if (command >= 0 && command < _soundCommands.size()) {
+		debugC(2, kDebugLevelSound, "%s", _soundCommands[command]->desc);
+		(this->*(_soundCommands[command]->sndCmd))(obj, handle, value);
+	} else {
+		warning("Invalid sound command requested (%d), valid range is 0-%d", command, _soundCommands.size() - 1);
+	}
+
+	return _acc;
+}
+
+void SoundCommandParser::cmdInitHandle(reg_t obj, SongHandle handle, int value) {
+	if (!obj.segment)
+		return;
+
+	SongIteratorType type = (_doSoundVersion == SCI_VERSION_0_EARLY) ? SCI_SONG_ITERATOR_TYPE_SCI0 : SCI_SONG_ITERATOR_TYPE_SCI1;
+	int number = GET_SEL32V(_segMan, obj, number);
+
+	if (_doSoundVersion != SCI_VERSION_0_EARLY) {
+		if (GET_SEL32V(_segMan, obj, nodePtr)) {
+			_state->sfx_song_set_status(handle, SOUND_STATUS_STOPPED);
+			_state->sfx_remove_song(handle);
+		}
+	}
+
+	// Some games try to init non-existing sounds (e.g. KQ6)
+	if (_doSoundVersion == SCI_VERSION_1_LATE) {
+		if (!obj.segment || !_resMan->testResource(ResourceId(kResourceTypeSound, value)))
+			return;
+	}
+
+	_state->sfx_add_song(build_iterator(_resMan, number, type, handle), 0, handle, number);
+
+	if (_doSoundVersion == SCI_VERSION_0_EARLY) {
+		PUT_SEL32V(_segMan, obj, state, _K_SOUND_STATUS_INITIALIZED);
+	} else {
+		PUT_SEL32(_segMan, obj, nodePtr, obj);
+	}
+
+	PUT_SEL32(_segMan, obj, handle, obj);
+}
+
+void SoundCommandParser::cmdPlayHandle(reg_t obj, SongHandle handle, int value) {
+	if (!obj.segment)
+		return;
+
+	_state->sfx_song_set_status(handle, SOUND_STATUS_PLAYING);
+	_state->sfx_song_set_loops(handle, GET_SEL32V(_segMan, obj, loop));
+
+	if (_doSoundVersion == SCI_VERSION_0_EARLY) {
+		PUT_SEL32V(_segMan, obj, state, _K_SOUND_STATUS_PLAYING);
+	} else if (_doSoundVersion == SCI_VERSION_1_EARLY) {
+		_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 (_doSoundVersion == 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);
+		}
+	}
+}
+
+void SoundCommandParser::cmdDummy(reg_t obj, SongHandle handle, int value) {
+	warning("cmdDummy invoked");	// not supposed to occur
+}
+
+void SoundCommandParser::changeHandleStatus(reg_t obj, SongHandle handle, int newStatus) {
+	if (obj.segment) {
+		_state->sfx_song_set_status(handle, newStatus);
+		if (_doSoundVersion == SCI_VERSION_0_EARLY)
+			PUT_SEL32V(_segMan, obj, state, newStatus);
+	}
+}
+
+void SoundCommandParser::cmdDisposeHandle(reg_t obj, SongHandle handle, int value) {
+	changeHandleStatus(obj, handle, SOUND_STATUS_STOPPED);
+
+	if (obj.segment) {
+		_state->sfx_remove_song(handle);
+
+		if (_doSoundVersion == SCI_VERSION_0_EARLY)
+			PUT_SEL32V(_segMan, obj, handle, 0x0000);
+	}
+}
+
+void SoundCommandParser::cmdStopHandle(reg_t obj, SongHandle handle, int value) {
+	changeHandleStatus(obj, handle, SOUND_STATUS_STOPPED);
+
+	if (_doSoundVersion != SCI_VERSION_0_EARLY)
+		PUT_SEL32V(_segMan, obj, signal, SIGNAL_OFFSET);
+}
+
+void SoundCommandParser::cmdSuspendHandle(reg_t obj, SongHandle handle, int value) {
+	if (_doSoundVersion == SCI_VERSION_0_EARLY)
+		changeHandleStatus(obj, handle, SOUND_STATUS_SUSPENDED);
+	else
+		changeHandleStatus(obj, handle, value ? SOUND_STATUS_SUSPENDED : SOUND_STATUS_PLAYING);
+}
+
+void SoundCommandParser::cmdResumeHandle(reg_t obj, SongHandle handle, int value) {
+	changeHandleStatus(obj, handle, SOUND_STATUS_PLAYING);
+}
+
+void SoundCommandParser::cmdMuteSound(reg_t obj, SongHandle handle, int value) {
+	// TODO
+
+	/* 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);*/
+}
+
+void SoundCommandParser::cmdVolume(reg_t obj, SongHandle handle, int value) {
+	if (obj != SIGNAL_REG)
+		_state->sfx_setVolume(obj.toSint16());
+
+	_acc = make_reg(0, _state->sfx_getVolume());
+}
+
+void SoundCommandParser::cmdHandlePriority(reg_t obj, SongHandle handle, int value) {
+	if (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));
+	}
+}
+
+void SoundCommandParser::cmdFadeHandle(reg_t obj, SongHandle handle, int value) {
+	/*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) {
+		_state->sfx_song_set_status(handle, SOUND_STATUS_STOPPED);
+		if (_doSoundVersion == SCI_VERSION_0_EARLY)
+			PUT_SEL32V(_segMan, obj, state, SOUND_STATUS_STOPPED);
+		PUT_SEL32V(_segMan, obj, signal, SIGNAL_OFFSET);
+	}
+
+#if 0
+		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);
+			}
+		}
+#endif
+}
+
+void SoundCommandParser::cmdGetPolyphony(reg_t obj, SongHandle handle, int value) {
+	_acc = make_reg(0, _state->sfx_get_player_polyphony());
+}
+
+void cmdGetPlayNext(EngineState *s, reg_t obj, SongHandle handle, int value) {
+	// TODO
+	// _state->sfx_all_stop();
+}
+
+void SoundCommandParser::cmdUpdateHandle(reg_t obj, SongHandle handle, int value) {
+	// 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 vol = GET_SEL32V(segMan, obj, vol);
+
+	_state->sfx_song_set_loops(handle, GET_SEL32V(_segMan, obj, loop));
+	_state->sfx_song_renice(handle, GET_SEL32V(_segMan, obj, 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);
+}
+
+void SoundCommandParser::cmdUpdateCues(reg_t obj, SongHandle handle, int value) {
+	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 = _state->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);
+}
+
+void SoundCommandParser::cmdSendMidi(reg_t obj, SongHandle handle, int value) {
+	int channel = value;
+
+	_state->sfx_send_midi(handle, channel, _midiCmd, _controller, _param);
+}
+
+void SoundCommandParser::cmdReverb(reg_t obj, SongHandle handle, int value) {
+	// TODO
+}
+void SoundCommandParser::cmdHoldHandle(reg_t obj, SongHandle handle, int value) {
+	_state->sfx_song_set_hold(handle, value);
+}
+
+void SoundCommandParser::cmdGetAudioCapability(reg_t obj, SongHandle handle, int value) {
+	// Tests for digital audio support
+	_acc = make_reg(0, 1);
+}
+
+void SoundCommandParser::cmdGetPlayNext(reg_t obj, SongHandle handle, int value) {
+}
+
+void SoundCommandParser::cmdSetHandleVolume(reg_t obj, SongHandle handle, int value) {
+	// TODO
+}
+
+void SoundCommandParser::cmdSetHandlePriority(reg_t obj, SongHandle handle, int value) {
+	script_set_priority(_resMan, _segMan, _state, obj, value);
+}
+
+void SoundCommandParser::cmdSetHandleLoop(reg_t obj, SongHandle handle, int value) {
+	if (!GET_SEL32(_segMan, obj, nodePtr).isNull()) {
+		uint16 looping = value;
+
+		if (looping < 65535)
+			looping = 1;
+
+		_state->sfx_song_set_loops(handle, looping);
+		PUT_SEL32V(_segMan, obj, loop, looping);
+	}
+}
+
+void SoundCommandParser::cmdSuspendSound(reg_t obj, SongHandle handle, int value) {
+	// TODO
+}
+
+void SoundCommandParser::cmdUpdateVolumePriority(reg_t obj, SongHandle handle, int value) {
+	// TODO
+}
+
+} // End of namespace Sci


Property changes on: scummvm/trunk/engines/sci/sfx/soundcmd.cpp
___________________________________________________________________
Added: svn:mime-type
   + text/plain
Added: svn:keywords
   + Date Rev Author URL Id
Added: svn:eol-style
   + native

Added: scummvm/trunk/engines/sci/sfx/soundcmd.h
===================================================================
--- scummvm/trunk/engines/sci/sfx/soundcmd.h	                        (rev 0)
+++ scummvm/trunk/engines/sci/sfx/soundcmd.h	2009-11-12 15:24:11 UTC (rev 45862)
@@ -0,0 +1,91 @@
+/* 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$
+ *
+ */
+
+#ifndef SCI_SOUNDCMD_H
+#define SCI_SOUNDCMD_H
+
+#include "sci/engine/state.h"
+
+namespace Sci {
+
+class SoundCommandParser;
+typedef void (SoundCommandParser::*SoundCommand)(reg_t obj, SongHandle handle, int value);
+
+struct SciSoundCommand {
+	SciSoundCommand(const char* d, SoundCommand c) : desc(d), sndCmd(c) {}
+	const char* desc;
+	SoundCommand sndCmd;
+};
+
+class SoundCommandParser {
+public:
+	SoundCommandParser(ResourceManager *resMan, SegManager *segMan, SfxState *state, AudioPlayer *audio, SciVersion doSoundVersion);
+	~SoundCommandParser();
+
+	reg_t parseCommand(int argc, reg_t *argv, reg_t acc);
+
+private:
+	Common::Array<SciSoundCommand*> _soundCommands;
+	ResourceManager *_resMan;
+	SegManager *_segMan;
+	SfxState *_state;
+	AudioPlayer *_audio;
+	SciVersion _doSoundVersion;
+	reg_t _acc;
+	int _midiCmd, _controller, _param;
+
+	void cmdInitHandle(reg_t obj, SongHandle handle, int value);
+	void cmdPlayHandle(reg_t obj, SongHandle handle, int value);
+	void cmdDummy(reg_t obj, SongHandle handle, int value);
+	void cmdMuteSound(reg_t obj, SongHandle handle, int value);
+	void cmdSuspendHandle(reg_t obj, SongHandle handle, int value);
+	void cmdResumeHandle(reg_t obj, SongHandle handle, int value);
+	void cmdStopHandle(reg_t obj, SongHandle handle, int value);
+	void cmdDisposeHandle(reg_t obj, SongHandle handle, int value);
+	void cmdVolume(reg_t obj, SongHandle handle, int value);
+	void cmdHandlePriority(reg_t obj, SongHandle handle, int value);
+	void cmdFadeHandle(reg_t obj, SongHandle handle, int value);
+	void cmdGetPolyphony(reg_t obj, SongHandle handle, int value);
+	void cmdGetPlayNext(reg_t obj, SongHandle handl, int valuee);
+
+	void initHandle(reg_t obj, SongHandle handle, bool isSci1);
+	void changeHandleStatus(reg_t obj, SongHandle handle, int newStatus);
+
+	void cmdUpdateHandle(reg_t obj, SongHandle handle, int value);
+	void cmdUpdateCues(reg_t obj, SongHandle handle, int value);
+	void cmdSendMidi(reg_t obj, SongHandle handle, int value);
+	void cmdReverb(reg_t obj, SongHandle handle, int value);
+	void cmdHoldHandle(reg_t obj, SongHandle handle, int value);
+	void cmdGetAudioCapability(reg_t obj, SongHandle handle, int value);
+	void cmdSetHandleVolume(reg_t obj, SongHandle handle, int value);
+	void cmdSetHandlePriority(reg_t obj, SongHandle handle, int value);
+	void cmdSetHandleLoop(reg_t obj, SongHandle handle, int value);
+	void cmdSuspendSound(reg_t obj, SongHandle handle, int value);
+	void cmdUpdateVolumePriority(reg_t obj, SongHandle handle, int value);
+};
+
+} // End of namespace Sci
+
+#endif // SCI_SOUNDCMD_H


Property changes on: scummvm/trunk/engines/sci/sfx/soundcmd.h
___________________________________________________________________
Added: svn:mime-type
   + text/plain
Added: svn:keywords
   + Date Rev Author URL Id
Added: svn:eol-style
   + native


This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.




More information about the Scummvm-git-logs mailing list