[Scummvm-cvs-logs] CVS: scummvm/scumm imuse.cpp,2.73,2.74 imuse.h,1.38,1.39 imuse_internal.h,2.12,2.13 imuse_player.cpp,2.16,2.17 script_v6.cpp,1.176,1.177 sound.cpp,1.193,1.194

Jamieson Christian jamieson630 at users.sourceforge.net
Wed Aug 6 11:21:03 CEST 2003


Update of /cvsroot/scummvm/scummvm/scumm
In directory sc8-pr-cvs1:/tmp/cvs-serv21567

Modified Files:
	imuse.cpp imuse.h imuse_internal.h imuse_player.cpp 
	script_v6.cpp sound.cpp 
Log Message:
Upgraded IMuse::doCommand() to support more than 8 parameters.
V6 scripts can specify up to 16 parameters to be passed to
doCommand(). In most cases 8 or fewer parameters were used,
but occasional uses of 9 or 10 parameters resulted in
incorrect iMuse behavior due to lost doCommand() data.

ImTrigger was also upgraded to support 8 parameters instead
of 4, since the incorrect behavior that was observed involved
the use of triggered commands that required more than 4
parameters. Since ImTrigger data is not currently being saved
(which is bad), we do not at this time have to go to another
savegame format to support the additional ImTrigger data
(which is good).

This fix corrects a problem in the Tunnel of Love. When the
"execution scene" music finishes and the hidden door opens,
the Tunnel of Love music is supposed to start up again. In
ScummVM, it never would, do to the loss of parameters for a
trigger-based "Parameter Fade" command.

A bit of miscellaneous cleanup has also been made.

Index: imuse.cpp
===================================================================
RCS file: /cvsroot/scummvm/scummvm/scumm/imuse.cpp,v
retrieving revision 2.73
retrieving revision 2.74
diff -u -d -r2.73 -r2.74
--- imuse.cpp	6 Aug 2003 17:47:29 -0000	2.73
+++ imuse.cpp	6 Aug 2003 18:20:14 -0000	2.74
@@ -643,120 +643,145 @@
 }
 
 int32 IMuseInternal::doCommand(int a, int b, int c, int d, int e, int f, int g, int h) {
+	int args[8];
+	args[0] = a;
+	args[1] = b;
+	args[2] = c;
+	args[3] = d;
+	args[4] = e;
+	args[5] = f;
+	args[6] = g;
+	args[7] = h;
+	return doCommand (8, args);
+}
+
+int32 IMuseInternal::doCommand (int numargs, int a[]) {
 	int i;
-	byte cmd = a & 0xFF;
-	byte param = a >> 8;
+
+	if (numargs < 1) return -1;
+	byte cmd = a[0] & 0xFF;
+	byte param = a[0] >> 8;
 	Player *player = NULL;
 
 	if (!_initialized &&(cmd || param))
 		return -1;
 
 #ifdef IMUSE_DEBUG
-	debug(0, "doCommand - %d(%d/%d), %d, %d, %d, %d, %d, %d, %d", a, (int) param, (int) cmd, b, c, d, e, f, g, h);
+	{
+		char string[128];
+		sprintf (string, "doCommand - %d (%d/%d)", a[0], (int) param, (int) cmd);
+		for (i = 1; i < numargs; ++i)
+			sprintf (string + strlen(string), ", %d", a[i]);
+		debug (0, string);
+	}
 #endif
 
 	if (param == 0) {
 		switch (cmd) {
 		case 6:
-			if (b > 127)
+			if (a[1] > 127)
 				return -1;
 			else
-				return set_master_volume((b << 1) |(b ? 0 : 1)); // Convert b from 0-127 to 0-255
+				return set_master_volume((a[1] << 1) |(a[1] ? 0 : 1)); // Convert from 0-127 to 0-255
 		case 7:
 			return _master_volume >> 1; // Convert from 0-255 to 0-127
 		case 8:
-			return startSound(b) ? 0 : -1;
+			return startSound(a[1]) ? 0 : -1;
 		case 9:
-			return stopSound(b);
+			return stopSound(a[1]);
 		case 10: // FIXME: Sam and Max - Not sure if this is correct
 			return stop_all_sounds();
 		case 11:
 			return stop_all_sounds();
 		case 12:
 			// Sam & Max: Player-scope commands
-			player = findActivePlayer(b);
+			player = findActivePlayer(a[1]);
 			if (!player)
 				return -1;
 
-			switch (d) {
+			switch (a[3]) {
 			case 6:
 				// Set player volume.
-				return player->setVolume(e);
+				return player->setVolume(a[4]);
 			default:
-				warning("IMuseInternal::doCommand(6) unsupported sub-command %d", d);
+				warning("IMuseInternal::doCommand(12) unsupported sub-command %d", a[3]);
 			}
 			return -1;
 		case 13:
-			return getSoundStatus(b);
+			return getSoundStatus(a[1]);
 		case 14:
 			// Sam and Max: Parameter fade
-			player = this->findActivePlayer(b);
+			player = this->findActivePlayer(a[1]);
 			if (player)
-				return player->addParameterFader(d, e, f);
+				return player->addParameterFader(a[3], a[4], a[5]);
 			return -1;
 
 		case 15:
 			// Sam & Max: Set hook for a "maybe" jump
-			player = findActivePlayer(b);
+			player = findActivePlayer(a[1]);
 			if (player) {
-				player->setHook(0, d, 0);
+				player->setHook(0, a[3], 0);
 				return 0;
 			}
 			return -1;
 		case 16:
-			return set_volchan(b, c);
+			return set_volchan(a[1], a[2]);
 		case 17:
 			if (g_scumm->_gameId != GID_SAMNMAX) {
-				return set_channel_volume(b, c);
+				return set_channel_volume(a[1], a[2]);
 			} else {
-				if (e || f || g || h) 
-					return ImSetTrigger(b, d, e, f, g, h);
-				else
-					return ImClearTrigger(b, d);
+				if (a[4]) {
+					int b[16];
+					memset (b, 0, sizeof(b));
+					for (i = 0; i < numargs; ++i)
+						b[i] = a[i];
+					return ImSetTrigger (b[1], b[3], b[4], b[5], b[6], b[7], b[8], b[9], b[10], b[11]);
+				} else {
+					return ImClearTrigger(a[1], a[3]);
+				}
 			}
 		case 18:
 			if (g_scumm->_gameId != GID_SAMNMAX) {
-				return set_volchan_entry(b, c);
+				return set_volchan_entry(a[1], a[2]);
 			} else {
 				// Sam & Max: ImCheckTrigger.
 				// According to Mike's notes to Ender,
 				// this function returns the number of triggers
 				// associated with a particular player ID and
 				// trigger ID.
-				a = 0;
+				a[0] = 0;
 				for (i = 0; i < 16; ++i) {
-					if (_snm_triggers [i].sound == b && _snm_triggers [i].id &&
-					   (d == -1 || _snm_triggers [i].id == d))
+					if (_snm_triggers [i].sound == a[1] && _snm_triggers [i].id &&
+					   (a[3] == -1 || _snm_triggers [i].id == a[3]))
 					{
-						++a;
+						++a[0];
 					}
 				}
-				return a;
+				return a[0];
 			}
 		case 19:
 			// Sam & Max: ImClearTrigger
 			// This should clear a trigger that's been set up
 			// with ImSetTrigger(cmd == 17). Seems to work....
-			return ImClearTrigger(b, d);
+			return ImClearTrigger(a[1], a[3]);
 		case 20:
 			// Sam & Max: Deferred Command
-			// warning("[--] doCommand(20): %3d %3d %3d %3d %3d %3d (%d)", c, d, e, f, g, h, b);
-			addDeferredCommand(b, c, d, e, f, g, h);
+			addDeferredCommand(a[1], a[2], a[3], a[4], a[5], a[6], a[7]);
 			return 0;
 		case 2:
 		case 3:
 			return 0;
 		default:
-			warning("doCommand(%d [%d/%d], %d, %d, %d, %d, %d, %d, %d) unsupported", a, param, cmd, b, c, d, e, f, g, h);
+			warning("doCommand(%d [%d/%d], %d, %d, %d, %d, %d, %d, %d) unsupported", a[0], param, cmd, a[1], a[2], a[3], a[4], a[5], a[6], a[7]);
 		}
 	} else if (param == 1) {
 		if ((1 << cmd) &(0x783FFF)) {
-			player = findActivePlayer(b);
+			player = findActivePlayer(a[1]);
 			if (!player)
 				return -1;
 			if ((1 << cmd) &(1 << 11 | 1 << 22)) {
-				assert(c >= 0 && c <= 15);
-				player = (Player *) player->getPart(c);
+				assert(a[2] >= 0 && a[2] <= 15);
+				player = (Player *) player->getPart(a[2]);
 				if (!player)
 					return -1;
 			}
@@ -765,70 +790,70 @@
 		switch (cmd) {
 		case 0:
 			if (g_scumm->_gameId == GID_SAMNMAX) {
-				if (d == 1) // Measure number
+				if (a[3] == 1) // Measure number
 					return ((player->getBeatIndex() - 1) >> 2) + 1;
-				else if (d == 2) // Beat number
+				else if (a[3] == 2) // Beat number
 					return player->getBeatIndex();
 				return -1;
 			} else {
-				return player->getParam(c, d);
+				return player->getParam(a[2], a[3]);
 			}
 		case 1:
 			if (g_scumm->_gameId == GID_SAMNMAX)
-				player->jump(d - 1, (e - 1) * 4 + f, ((g * player->getTicksPerBeat()) >> 2) + h);
+				player->jump(a[3] - 1, (a[4] - 1) * 4 + a[5], ((a[6] * player->getTicksPerBeat()) >> 2) + a[7]);
 			else
-				player->setPriority(c);
+				player->setPriority(a[2]);
 			return 0;
 		case 2:
-			return player->setVolume(c);
+			return player->setVolume(a[2]);
 		case 3:
-			player->setPan(c);
+			player->setPan(a[2]);
 			return 0;
 		case 4:
-			return player->setTranspose(c, d);
+			return player->setTranspose(a[2], a[3]);
 		case 5:
-			player->setDetune(c);
+			player->setDetune(a[2]);
 			return 0;
 		case 6:
-			player->setSpeed(c);
+			player->setSpeed(a[2]);
 			return 0;
 		case 7:
-			return player->jump(c, d, e) ? 0 : -1;
+			return player->jump(a[2], a[3], a[4]) ? 0 : -1;
 		case 8:
-			return player->scan(c, d, e);
+			return player->scan(a[2], a[3], a[4]);
 		case 9:
-			return player->setLoop(c, d, e, f, g) ? 0 : -1;
+			return player->setLoop(a[2], a[3], a[4], a[5], a[6]) ? 0 : -1;
 		case 10:
 			player->clearLoop();
 			return 0;
 		case 11:
-			((Part *)player)->set_onoff(d != 0);
+			((Part *)player)->set_onoff(a[3] != 0);
 			return 0;
 		case 12:
-			return player->setHook(c, d, e);
+			return player->setHook(a[2], a[3], a[4]);
 		case 13:
-			return player->addParameterFader(ParameterFader::pfVolume, c, d);
+			return player->addParameterFader (ParameterFader::pfVolume, a[2], a[3]);
 		case 14:
-			return enqueue_trigger(b, c);
+			return enqueue_trigger(a[1], a[2]);
 		case 15:
-			return enqueue_command(b, c, d, e, f, g, h);
+			return enqueue_command(a[1], a[2], a[3], a[4], a[5], a[6], a[7]);
 		case 16:
 			return clear_queue();
 		case 19:
-			return player->getParam(c, d);
+			return player->getParam(a[2], a[3]);
 		case 20:
-			return player->setHook(c, d, e);
+			return player->setHook(a[2], a[3], a[4]);
 		case 21:
 			return -1;
 		case 22:
-			((Part *)player)->setVolume(d);
+			((Part *)player)->setVolume(a[3]);
 			return 0;
 		case 23:
-			return query_queue(b);
+			return query_queue(a[1]);
 		case 24:
 			return 0;
 		default:
-			warning("doCommand(%d [%d/%d], %d, %d, %d, %d, %d, %d, %d) unsupported", a, param, cmd, b, c, d, e, f, g, h);
+			warning("doCommand(%d [%d/%d], %d, %d, %d, %d, %d, %d, %d) unsupported", a[0], param, cmd, a[1], a[2], a[3], a[4], a[5], a[6], a[7]);
 			return -1;
 		}
 	}
@@ -836,7 +861,7 @@
 	return -1;
 }
 
-int32 IMuseInternal::ImSetTrigger(int sound, int id, int a, int b, int c, int d) {
+int32 IMuseInternal::ImSetTrigger (int sound, int id, int a, int b, int c, int d, int e, int f, int g, int h) {
 	// Sam & Max: ImSetTrigger.
 	// Sets a trigger for a particular player and
 	// marker ID, along with doCommand parameters
@@ -880,6 +905,10 @@
 	trig->command [1] = b;
 	trig->command [2] = c;
 	trig->command [3] = d;
+	trig->command [4] = e;
+	trig->command [5] = f;
+	trig->command [6] = g;
+	trig->command [7] = h;
 
 	// If the command is to start a sound, stop that sound if it's already playing.
 	// This fixes some carnival music problems.
@@ -894,11 +923,12 @@
 int32 IMuseInternal::ImClearTrigger(int sound, int id) {
 	int count = 0;
 	int i;
-	for (i = 0; i < 16; ++i) {
-		if (_snm_triggers [i].sound == sound && _snm_triggers [i].id &&
-			(id == -1 || _snm_triggers [i].id == id))
+	ImTrigger *trig = _snm_triggers;
+	for (i = ARRAYSIZE(_snm_triggers); i; --i, ++trig) {
+		if ((sound == -1 || trig->sound == sound) &&
+		    trig->id && (id == -1 || trig->id == id))
 		{
-			_snm_triggers [i].sound = _snm_triggers [i].id = 0;
+			trig->sound = trig->id = 0;
 			++count;
 		}
 	}
@@ -913,11 +943,7 @@
 		if (_snm_triggers [i].sound == sound)
 		{
 			_snm_triggers [i].sound = _snm_triggers [i].id = 0;
-			doCommand(_snm_triggers [i].command [0],
-			           _snm_triggers [i].command [1],
-			           _snm_triggers [i].command [2],
-			           _snm_triggers [i].command [3],
-			           0, 0, 0, 0);
+			doCommand (8, _snm_triggers[i].command);
 			++count;
 		}
 	}
@@ -1735,7 +1761,8 @@
 int IMuse::stop_all_sounds() { in(); int ret = _target->stop_all_sounds(); out(); return ret; }
 int IMuse::getSoundStatus(int sound) { in(); int ret = _target->getSoundStatus(sound, true); out(); return ret; }
 bool IMuse::get_sound_active(int sound) { in(); bool ret = _target->getSoundStatus(sound, false) ? 1 : 0; out(); return ret; }
-int32 IMuse::doCommand(int a, int b, int c, int d, int e, int f, int g, int h) { in(); int32 ret = _target->doCommand(a,b,c,d,e,f,g,h); out(); return ret; }
+int32 IMuse::doCommand (int a, int b, int c, int d, int e, int f, int g, int h) { in(); int32 ret = _target->doCommand(a,b,c,d,e,f,g,h); out(); return ret; }
+int32 IMuse::doCommand (int numargs, int args[]) { in(); int32 ret = _target->doCommand (numargs, args); out(); return ret; }
 int IMuse::clear_queue() { in(); int ret = _target->clear_queue(); out(); return ret; }
 void IMuse::setBase(byte **base) { in(); _target->setBase(base); out(); }
 uint32 IMuse::property(int prop, uint32 value) { in(); uint32 ret = _target->property(prop, value); out(); return ret; }

Index: imuse.h
===================================================================
RCS file: /cvsroot/scummvm/scummvm/scumm/imuse.h,v
retrieving revision 1.38
retrieving revision 1.39
diff -u -d -r1.38 -r1.39
--- imuse.h	5 Aug 2003 23:58:24 -0000	1.38
+++ imuse.h	6 Aug 2003 18:20:15 -0000	1.39
@@ -67,7 +67,8 @@
 	int stop_all_sounds();
 	int getSoundStatus(int sound);
 	bool get_sound_active(int sound);
-	int32 doCommand(int a, int b, int c, int d, int e, int f, int g, int h);
+	int32 doCommand (int a, int b, int c, int d, int e, int f, int g, int h);
+	int32 doCommand (int numargs, int args[]);
 	int clear_queue();
 	void setBase(byte **base);
 	uint32 property(int prop, uint32 value);

Index: imuse_internal.h
===================================================================
RCS file: /cvsroot/scummvm/scummvm/scumm/imuse_internal.h,v
retrieving revision 2.12
retrieving revision 2.13
diff -u -d -r2.12 -r2.13
--- imuse_internal.h	5 Aug 2003 23:58:24 -0000	2.12
+++ imuse_internal.h	6 Aug 2003 18:20:15 -0000	2.13
@@ -139,7 +139,7 @@
 	int sound;
 	byte id;
 	uint16 expire;
-	byte command [4];
+	int command [8];
 	ImTrigger() { memset(this, 0, sizeof(ImTrigger)); }
 };
 
@@ -410,7 +410,7 @@
 	Player *allocate_player(byte priority);
 	Part *allocate_part(byte pri, MidiDriver *midi);
 
-	int32 ImSetTrigger(int sound, int id, int a, int b, int c, int d);
+	int32 ImSetTrigger(int sound, int id, int a, int b, int c, int d, int e, int f, int g, int h);
 	int32 ImClearTrigger(int sound, int id);
 	int32 ImFireAllTriggers(int sound);
 
@@ -461,7 +461,8 @@
 	int stopSound(int sound);
 	int stop_all_sounds();
 	int getSoundStatus(int sound, bool ignoreFadeouts = true);
-	int32 doCommand(int a, int b, int c, int d, int e, int f, int g, int h);
+	int32 doCommand (int a, int b, int c, int d, int e, int f, int g, int h);
+	int32 doCommand (int numargs, int args[]);
 	int clear_queue();
 	void setBase(byte **base);
 

Index: imuse_player.cpp
===================================================================
RCS file: /cvsroot/scummvm/scummvm/scumm/imuse_player.cpp,v
retrieving revision 2.16
retrieving revision 2.17
diff -u -d -r2.16 -r2.17
--- imuse_player.cpp	5 Aug 2003 23:58:24 -0000	2.16
+++ imuse_player.cpp	6 Aug 2003 18:20:15 -0000	2.17
@@ -94,16 +94,7 @@
 			warning("Player::startSound(): Couldn't find start of sound %d!", sound);
 			return false;
 	}
-/*
-	mdhd = _se->findTag(sound, MDHD_TAG, 0);
-	if (mdhd == NULL) {
-		mdhd = _se->findTag(sound, MDPG_TAG, 0);
-		if (mdhd == NULL) {
-				warning("P::startSound failed: Couldn't find %s", MDHD_TAG);
-				return false;
-		}
-	}
-*/
+	
 	_isMT32 = _se->isMT32(sound);
 	_isGM = _se->isGM(sound);
 
@@ -128,6 +119,10 @@
 		_midi = NULL;
 		return false;
 	}
+
+#ifdef IMUSE_DEBUG
+	debug (0, "Starting music %d", sound);
+#endif
 	return true;
 }
 
@@ -144,12 +139,20 @@
 }
 
 void Player::clear() {
+	if (!_active)
+		return;
+
+#ifdef IMUSE_DEBUG
+	debug (0, "Stopping music %d", _id);
+#endif
+
 	if (_parser)
 		_parser->unloadMusic();
 	uninit_parts();
 	_se->ImFireAllTriggers(_id);
 	_active = false;
 	_midi = NULL;
+	_id = 0;
 }
 
 void Player::hook_clear() {
@@ -389,11 +392,7 @@
 				    _se->_snm_triggers [a].id == *p)
 				{
 					_se->_snm_triggers [a].sound = _se->_snm_triggers [a].id = 0;
-					_se->doCommand(_se->_snm_triggers [a].command [0],
-					                 _se->_snm_triggers [a].command [1],
-					                 _se->_snm_triggers [a].command [2],
-					                 _se->_snm_triggers [a].command [3],
-					                 0, 0, 0, 0);
+					_se->doCommand (8, _se->_snm_triggers[a].command);
 					break;
 				}
 			}
@@ -979,7 +978,7 @@
 
 // "time" is referenced as hundredths of a second.
 // IS THAT CORRECT??
-// We convert it to microseconds before prceeding
+// We convert it to microseconds before proceeding
 int Player::addParameterFader(int param, int target, int time) {
 	int start;
 
@@ -1002,25 +1001,29 @@
 	case ParameterFader::pfTranspose:
 		// FIXME: Is this transpose? And what's the scale?
 		// It's set to fade to -2400 in the tunnel of love.
-		warning("parameterTransition(3) outside Tunnel of Love?");
+//		warning("parameterTransition(3) outside Tunnel of Love?");
 		start = _transpose;
-		target /= 200;
+//		target /= 200;
 		break;
 
-	case ParameterFader::pfSpeed:
+	case ParameterFader::pfSpeed: // impSpeed
 		// FIXME: Is the speed from 0-100?
 		// Right now I convert it to 0-128.
 		start = _speed;
-		target = target * 128 / 100;
+//		target = target * 128 / 100;
 		break;
 
 	case 127:
-		// FIXME: This MIGHT fade ALL supported parameters,
-		// but I'm not sure.
-		return 0;
+		{ // FIXME? I *think* this clears all parameter faders.
+			ParameterFader *ptr = &_parameterFaders[0];
+			int i;
+			for (i = ARRAYSIZE(_parameterFaders); i; --i, ++ptr)
+				ptr->param = 0;
+			return 0;
+		}
 
 	default:
-		warning("Player::addParameterFader(): Unknown parameter %d", param);
+		warning("Player::addParameterFader (%d, %d, %d): Unknown parameter", param, target, time);
 		return 0; // Should be -1, but we'll let the script think it worked.
 	}
 
@@ -1079,15 +1082,19 @@
 			setVolume((byte) value);
 			break;
 
-		case ParameterFader::pfSpeed:
+		case ParameterFader::pfTranspose:
+			// FIXME: Is this really transpose?
+			setTranspose (0, value / 100);
+			setDetune (value % 100);
+			break;
+
+		case ParameterFader::pfSpeed: // impSpeed:
 			// Speed.
 			setSpeed((byte) value);
 			break;
 
-		case ParameterFader::pfTranspose:
-			// FIXME: Is this really transpose?
-			setTranspose(0, value);
-			break;
+		default:
+			ptr->param = 0;
 		}
 
 		if (ptr->current_time >= ptr->total_time)

Index: script_v6.cpp
===================================================================
RCS file: /cvsroot/scummvm/scummvm/scumm/script_v6.cpp,v
retrieving revision 1.176
retrieving revision 1.177
diff -u -d -r1.176 -r1.177
--- script_v6.cpp	24 Jul 2003 17:44:00 -0000	1.176
+++ script_v6.cpp	6 Aug 2003 18:20:15 -0000	1.177
@@ -2630,7 +2630,7 @@
 			break;
 		case 122:
 			VAR(VAR_SOUNDRESULT) =
-				(short)_imuse->doCommand(args[1], args[2], args[3], args[4], args[5], args[6], args[7], args[8]);
+				(short)_imuse->doCommand (num - 1, &args[1]);
 			break;
 		case 123:
 			copyPalColor(args[2], args[1]);

Index: sound.cpp
===================================================================
RCS file: /cvsroot/scummvm/scummvm/scumm/sound.cpp,v
retrieving revision 1.193
retrieving revision 1.194
diff -u -d -r1.193 -r1.194
--- sound.cpp	6 Aug 2003 12:11:10 -0000	1.193
+++ sound.cpp	6 Aug 2003 18:20:15 -0000	1.194
@@ -126,7 +126,7 @@
 
 void Sound::processSoundQues() {
 	int i = 0, d, num;
-	int16 data[16];
+	int data[16];
 
 	processSfxQueues();
 
@@ -160,11 +160,8 @@
 				if (_scumm->_imuseDigital)
 					_scumm->_imuseDigital->doCommand(data[0], data[1], data[2], data[3], data[4],
 																	data[5], data[6], data[7]);
-			} else {
-				if (_scumm->_imuse)
-					_scumm->VAR(_scumm->VAR_SOUNDRESULT) =
-						(short)_scumm->_imuse->doCommand(data[0], data[1], data[2], data[3], data[4],
-																	data[5], data[6], data[7]);
+			} else if (_scumm->_imuse) {
+				_scumm->VAR(_scumm->VAR_SOUNDRESULT) = (short)_scumm->_imuse->doCommand (num, data);
 			}
 		}
 	}





More information about the Scummvm-git-logs mailing list