aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--scumm/imuse.cpp165
-rw-r--r--scumm/imuse.h3
-rw-r--r--scumm/imuse_internal.h7
-rw-r--r--scumm/imuse_player.cpp65
-rw-r--r--scumm/script_v6.cpp2
-rw-r--r--scumm/sound.cpp9
6 files changed, 142 insertions, 109 deletions
diff --git a/scumm/imuse.cpp b/scumm/imuse.cpp
index 0b3e32774e..7ce26fb628 100644
--- a/scumm/imuse.cpp
+++ b/scumm/imuse.cpp
@@ -643,120 +643,145 @@ int IMuseInternal::enqueue_trigger(int sound, int marker) {
}
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 @@ int32 IMuseInternal::doCommand(int a, int b, int c, int d, int e, int f, int g,
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 @@ int32 IMuseInternal::doCommand(int a, int b, int c, int d, int e, int f, int g,
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 @@ int32 IMuseInternal::ImSetTrigger(int sound, int id, int a, int b, int c, int d)
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::ImSetTrigger(int sound, int id, int a, int b, int c, int d)
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 @@ int32 IMuseInternal::ImFireAllTriggers(int sound) {
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::stopSound(int sound) { in(); int ret = _target->stopSound(sound); out
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; }
diff --git a/scumm/imuse.h b/scumm/imuse.h
index 2b129e27f3..10280ee25b 100644
--- a/scumm/imuse.h
+++ b/scumm/imuse.h
@@ -67,7 +67,8 @@ public:
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);
diff --git a/scumm/imuse_internal.h b/scumm/imuse_internal.h
index 330dd2ea6a..16a9dc11e7 100644
--- a/scumm/imuse_internal.h
+++ b/scumm/imuse_internal.h
@@ -139,7 +139,7 @@ struct ImTrigger {
int sound;
byte id;
uint16 expire;
- byte command [4];
+ int command [8];
ImTrigger() { memset(this, 0, sizeof(ImTrigger)); }
};
@@ -410,7 +410,7 @@ private:
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 @@ public:
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);
diff --git a/scumm/imuse_player.cpp b/scumm/imuse_player.cpp
index 0e4ee34fdf..50cee4bae5 100644
--- a/scumm/imuse_player.cpp
+++ b/scumm/imuse_player.cpp
@@ -94,16 +94,7 @@ bool Player::startSound(int sound, MidiDriver *midi) {
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 @@ bool Player::startSound(int sound, MidiDriver *midi) {
_midi = NULL;
return false;
}
+
+#ifdef IMUSE_DEBUG
+ debug (0, "Starting music %d", sound);
+#endif
return true;
}
@@ -144,12 +139,20 @@ bool Player::isFadingOut() {
}
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 @@ void Player::sysEx(byte *p, uint16 len) {
_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 @@ void Player::onTimer() {
// "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 @@ int Player::addParameterFader(int param, int target, int time) {
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 @@ void Player::transitionParameters() {
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)
diff --git a/scumm/script_v6.cpp b/scumm/script_v6.cpp
index b87ca12aa0..0c50b13ec3 100644
--- a/scumm/script_v6.cpp
+++ b/scumm/script_v6.cpp
@@ -2630,7 +2630,7 @@ void Scumm_v6::o6_kernelSetFunctions() {
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]);
diff --git a/scumm/sound.cpp b/scumm/sound.cpp
index 2fc5816144..9a7f3e4b49 100644
--- a/scumm/sound.cpp
+++ b/scumm/sound.cpp
@@ -126,7 +126,7 @@ void Sound::addSoundToQueue2(int sound) {
void Sound::processSoundQues() {
int i = 0, d, num;
- int16 data[16];
+ int data[16];
processSfxQueues();
@@ -160,11 +160,8 @@ void Sound::processSoundQues() {
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);
}
}
}