[Scummvm-cvs-logs] CVS: scummvm/scumm/imuse_digi dimuse_script.cpp,NONE,1.7.2.1 dimuse_track.cpp,NONE,1.17.2.1 dimuse.cpp,1.45.2.1,1.45.2.2 dimuse.h,1.31,1.31.2.1 dimuse_bndmgr.cpp,1.14.2.1,1.14.2.2 dimuse_bndmgr.h,1.5.2.1,1.5.2.2 dimuse_music.cpp,1.15,1.15.2.1 dimuse_sndmgr.cpp,1.26.2.2,1.26.2.3 dimuse_sndmgr.h,1.19,1.19.2.1 dimuse_tables.cpp,1.14,1.14.2.1

Pawel Kolodziejski aquadran at users.sourceforge.net
Sun May 2 09:37:13 CEST 2004


Update of /cvsroot/scummvm/scummvm/scumm/imuse_digi
In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv13901/scumm/imuse_digi

Modified Files:
      Tag: branch-0-6-0
	dimuse.cpp dimuse.h dimuse_bndmgr.cpp dimuse_bndmgr.h 
	dimuse_music.cpp dimuse_sndmgr.cpp dimuse_sndmgr.h 
	dimuse_tables.cpp 
Added Files:
      Tag: branch-0-6-0
	dimuse_script.cpp dimuse_track.cpp 
Log Message:
backported imuse digital from head cvs except save/load code

--- NEW FILE: dimuse_script.cpp ---
/* ScummVM - Scumm Interpreter
 * Copyright (C) 2001-2004 The ScummVM project
 *
 * 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., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 *
 * $Header: /cvsroot/scummvm/scummvm/scumm/imuse_digi/dimuse_script.cpp,v 1.7.2.1 2004/05/02 16:36:04 aquadran Exp $
 */

#include "stdafx.h"
#include "common/timer.h"

#include "scumm/actor.h"
#include "scumm/scumm.h"
#include "scumm/sound.h"
#include "scumm/imuse_digi/dimuse.h"
#include "scumm/imuse_digi/dimuse_bndmgr.h"

#include "sound/audiostream.h"
#include "sound/mixer.h"

namespace Scumm {

void IMuseDigital::parseScriptCmds(int a, int b, int c, int d, int e, int f, int g, int h) {
	int cmd = a;
	int soundId = b;
	int sub_cmd = c;

	if (!cmd)
		return;

	switch (cmd) {
	case 10: // ImuseStopAllSounds
		stopAllSounds();
		break;
	case 12: // ImuseSetParam
		switch (sub_cmd) {
		case 0x400: // select group volume
			selectVolumeGroup(soundId, d);
			break;
		case 0x500: // set priority
			setPriority(soundId, d);
			break;
		case 0x600: // set volume
			setVolume(soundId, d);
			break;
		case 0x700: // set pan
			setPan(soundId, d);
			break;
		default:
			warning("IMuseDigital::doCommand SetParam DEFAULT command %d", sub_cmd);
			break;
		}
		break;
	case 14: // ImuseFadeParam
		switch (sub_cmd) {
		case 0x600: // set volume fading
			if ((d != 0) && (e == 0))
				setVolume(soundId, d);
			else if ((d == 0) && (e == 0))
				stopSound(soundId);
			else
				setFade(soundId, d, e);
			break;
		default:
			warning("IMuseDigital::doCommand FadeParam DEFAULT sub command %d", sub_cmd);
			break;
		}
		break;
	case 25: // ImuseStartStream
		debug(5, "ImuseStartStream (%d, %d, %d)", soundId, c, d);
		break;
	case 26: // ImuseSwitchStream
		debug(5, "ImuseSwitchStream (%d, %d, %d, %d, %d)", soundId, c, d, e, f);
		break;
	case 0x1000: // ImuseSetState
		debug(5, "ImuseSetState (%d)", b);
		if ((_vm->_gameId == GID_DIG) && (_vm->_features & GF_DEMO)) {
			if (b == 1) {
				fadeOutMusic(200);
				startMusic(1, 127);
			} else {
				if (getSoundStatus(2) == 0) {
					fadeOutMusic(200);
					startMusic(2, 127);
				}
			}
		} else if ((_vm->_gameId == GID_CMI) && (_vm->_features & GF_DEMO)) {
			fadeOutMusic(120);
			if (b == 2) {
				startMusic("in1.imx", 1100, 0, 127);
			} else if (b == 4) {
				startMusic("in2.imx", 1120, 0, 127);
			} else if (b == 8) {
				startMusic("out1.imx", 1140, 0, 127);
			} else if (b == 9) {
				startMusic("out2.imx", 1150, 0, 127);
			} else if (b == 16) {
				startMusic("gun.imx", 1210, 0, 127);
			} else {
				warning("imuse digital: set state unknown for cmi demo: %d, room: %d", b, _vm->_currentRoom);
			}
		} else if (_vm->_gameId == GID_DIG) {
			setDigMusicState(b);
		} else if (_vm->_gameId == GID_CMI) {
			setComiMusicState(b);
		} else if (_vm->_gameId == GID_FT) {
			setFtMusicState(b);
		}
		break;
	case 0x1001: // ImuseSetSequence
		debug(5, "ImuseSetSequence (%d)", b);
		if (_vm->_gameId == GID_DIG) {
			setDigMusicSequence(b);
		} else if (_vm->_gameId == GID_CMI) {
			setComiMusicSequence(b);
		} else if (_vm->_gameId == GID_FT) {
			setFtMusicSequence(b);
		}
		break;
	case 0x1002: // ImuseSetCuePoint
		debug(5, "ImuseSetCuePoint (%d)", b);
		if (_vm->_gameId == GID_FT) {
			setFtMusicCuePoint(b);
		}
		break;
	case 0x1003: // ImuseSetAttribute
		debug(5, "ImuseSetAttribute (%d, %d)", b, c);
		assert((_vm->_gameId == GID_DIG) || (_vm->_gameId == GID_FT));
		if (_vm->_gameId == GID_DIG) {
			_attributes[b] = c;
		}
		break;
	case 0x2000: // ImuseSetGroupSfxVolume
		debug(5, "ImuseSetGroupSFXVolume (%d)", b);
//		setGroupSfxVolume(b);
		break;
	case 0x2001: // ImuseSetGroupVoiceVolume
		debug(5, "ImuseSetGroupVoiceVolume (%d)", b);
//		setGroupVoiceVolume(b);
		break;
	case 0x2002: // ImuseSetGroupMusicVolume
		debug(5, "ImuseSetGroupMusicVolume (%d)", b);
//		setGroupMusicVolume(b);
		break;
	default:
		error("IMuseDigital::doCommand DEFAULT command %d", cmd);
	}
}

void IMuseDigital::refreshScripts() {
	Common::StackLock lock(_mutex);
	bool found = false;
	for (int l = 0; l < MAX_DIGITAL_TRACKS; l++) {
		if ((_track[l]->used) && (_track[l]->volGroupId == IMUSE_VOLGRP_MUSIC)) {
			found = true;
		}
	}

	if ((!found) && (_curMusicSeq != 0)) {
		parseScriptCmds(0x1001, 0, 0, 0, 0, 0, 0, 0);
	}
}

void IMuseDigital::startVoice(int soundId, AudioStream *input) {
	debug(5, "startVoiceStream(%d)", soundId);
	startSound(soundId, "", 0, IMUSE_VOLGRP_VOICE, input, 0, 127, 127);
}

void IMuseDigital::startVoice(int soundId, const char *soundName) {
	debug(5, "startVoiceBundle(%s)", soundName);
	startSound(soundId, soundName, IMUSE_BUNDLE, IMUSE_VOLGRP_VOICE, NULL, 0, 127, 127);
}

void IMuseDigital::startMusic(int soundId, int volume) {
	debug(5, "startMusicResource(%d)", soundId);
	startSound(soundId, "", IMUSE_RESOURCE, IMUSE_VOLGRP_MUSIC, NULL, 0, volume, 126);
}

void IMuseDigital::startMusic(const char *soundName, int soundId, int hookId, int volume) {
	debug(5, "startMusicBundle(%s)", soundName);
	startSound(soundId, soundName, IMUSE_BUNDLE, IMUSE_VOLGRP_MUSIC, NULL, hookId, volume, 126);
}

void IMuseDigital::startSfx(int soundId, int priority) {
	debug(5, "startSfx(%d)", soundId);
	startSound(soundId, "", IMUSE_RESOURCE, IMUSE_VOLGRP_SFX, NULL, 0, 127, priority);
}

void IMuseDigital::getLipSync(int soundId, int syncId, int32 msPos, int32 &width, int32 &height) {
	int32 sync_size;
	byte *sync_ptr;

	msPos /= 16;
	if (msPos < 65536) {
		for (int l = 0; l < MAX_DIGITAL_TRACKS; l++) {
			if ((_track[l]->soundId == soundId) && _track[l]->used) {
				_sound->getSyncSizeAndPtrById(_track[l]->soundHandle, syncId, sync_size, &sync_ptr);
				if ((sync_size != 0) && (sync_ptr != NULL)) {
					sync_size /= 4;
					while (sync_size--) {
						if (READ_BE_UINT16(sync_ptr) >= msPos)
							break;
						sync_ptr += 4;
					}
					if (sync_size < 0)
						sync_ptr -= 4;
					else
						if (READ_BE_UINT16(sync_ptr) > msPos)
							sync_ptr -= 4;

					width = sync_ptr[2];
					height = sync_ptr[3];
					return;
				}
			}
		}
	}
}

int32 IMuseDigital::getPosInMs(int soundId) {
	for (int l = 0; l < MAX_DIGITAL_TRACKS; l++) {
		if ((_track[l]->soundId == soundId) && _track[l]->used) {
			int32 pos = (5 * (_track[l]->dataOffset + _track[l]->regionOffset)) / (_track[l]->iteration / 200);
			return pos;
		}
	}

	return 0;
}

int IMuseDigital::getSoundStatus(int sound) const {
	Common::StackLock lock(_mutex);
	debug(5, "IMuseDigital::getSoundStatus(%d)", sound);
	for (int l = 0; l < MAX_DIGITAL_TRACKS; l++) {
		if ((_track[l]->soundId == sound) && _track[l]->handle.isActive()) {
			return 1;
		}
	}

	return 0;
}

void IMuseDigital::stopSound(int soundId) {
	Common::StackLock lock(_mutex);
	debug(5, "IMuseDigital::stopSound(%d)", soundId);
	for (int l = 0; l < MAX_DIGITAL_TRACKS; l++) {
		if ((_track[l]->soundId == soundId) && (_track[l]->used)) {
			if (_track[l]->stream) {
				_track[l]->stream->finish();
				_track[l]->stream = NULL;
				_vm->_mixer->stopHandle(_track[l]->handle);
				_sound->closeSound(_track[l]->soundHandle);
				_track[l]->soundHandle = NULL;
			} else if (_track[l]->stream2) {
				_vm->_mixer->stopHandle(_track[l]->handle);
				delete _track[l]->stream2;
				_track[l]->stream2 = NULL;
			}
			_track[l]->used = false;
		}
	}
}

int32 IMuseDigital::getCurMusicPosInMs() {
	Common::StackLock lock(_mutex);
	int soundId = -1;

	for (int l = 0; l < MAX_DIGITAL_TRACKS; l++) {
		if ((_track[l]->volGroupId == IMUSE_VOLGRP_MUSIC) && _track[l]->used) {
			soundId = _track[l]->soundId;
		}
	}

	int32 msPos = getPosInMs(soundId);
	debug(5, "IMuseDigital::getCurMusicPosInMs(%d) = %d", soundId, msPos);
	return msPos;
}

int32 IMuseDigital::getCurVoiceLipSyncWidth() {
	Common::StackLock lock(_mutex);
	int32 msPos = getPosInMs(kTalkSoundID) + 50;
	int32 width = 0, height = 0;

	debug(5, "IMuseDigital::getCurVoiceLipSyncWidth(%d)", kTalkSoundID);
	getLipSync(kTalkSoundID, 0, msPos, width, height);
	return width;
}

int32 IMuseDigital::getCurVoiceLipSyncHeight() {
	Common::StackLock lock(_mutex);
	int32 msPos = getPosInMs(kTalkSoundID) + 50;
	int32 width = 0, height = 0;

	debug(5, "IMuseDigital::getCurVoiceLipSyncHeight(%d)", kTalkSoundID);
	getLipSync(kTalkSoundID, 0, msPos, width, height);
	return height;
}

int32 IMuseDigital::getCurMusicLipSyncWidth(int syncId) {
	Common::StackLock lock(_mutex);
	int soundId = -1;

	for (int l = 0; l < MAX_DIGITAL_TRACKS; l++) {
		if ((_track[l]->volGroupId == IMUSE_VOLGRP_MUSIC) && _track[l]->used) {
			soundId = _track[l]->soundId;
		}
	}

	int32 msPos = getPosInMs(soundId) + 50;
	int32 width = 0, height = 0;

	debug(5, "IMuseDigital::getCurVoiceLipSyncWidth(%d, %d)", soundId, msPos);
	getLipSync(soundId, syncId, msPos, width, height);
	return width;
}

int32 IMuseDigital::getCurMusicLipSyncHeight(int syncId) {
	Common::StackLock lock(_mutex);
	int soundId = -1;

	for (int l = 0; l < MAX_DIGITAL_TRACKS; l++) {
		if ((_track[l]->volGroupId == IMUSE_VOLGRP_MUSIC) && _track[l]->used) {
			soundId = _track[l]->soundId;
		}
	}

	int32 msPos = getPosInMs(soundId) + 50;
	int32 width = 0, height = 0;

	debug(5, "IMuseDigital::getCurVoiceLipSyncHeight(%d, %d)", soundId, msPos);
	getLipSync(soundId, syncId, msPos, width, height);
	return height;
}

void IMuseDigital::stopAllSounds() {
	Common::StackLock lock(_mutex);
	debug(5, "IMuseDigital::stopAllSounds");

	for (int l = 0; l < MAX_DIGITAL_TRACKS + MAX_DIGITAL_FADETRACKS; l++) {
		if (_track[l]->used) {
			if (_track[l]->stream) {
				_track[l]->stream->finish();
				_track[l]->stream = NULL;
				_vm->_mixer->stopHandle(_track[l]->handle);
				_sound->closeSound(_track[l]->soundHandle);
				_track[l]->soundHandle = NULL;
			} else if (_track[l]->stream2) {
				_vm->_mixer->stopHandle(_track[l]->handle);
				delete _track[l]->stream2;
				_track[l]->stream2 = NULL;
			}
			_track[l]->used = false;
		}
	}
}

void IMuseDigital::pause(bool p) {
	Common::StackLock lock(_mutex);
	for (int l = 0; l < MAX_DIGITAL_TRACKS + MAX_DIGITAL_FADETRACKS; l++) {
		if (_track[l]->used) {
			_vm->_mixer->pauseHandle(_track[l]->handle, p);
		}
	}
	_pause = p;
}

} // End of namespace Scumm

--- NEW FILE: dimuse_track.cpp ---
/* ScummVM - Scumm Interpreter
 * Copyright (C) 2001-2004 The ScummVM project
 *
 * 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., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 *
 * $Header: /cvsroot/scummvm/scummvm/scumm/imuse_digi/dimuse_track.cpp,v 1.17.2.1 2004/05/02 16:36:04 aquadran Exp $
 */

#include "stdafx.h"
#include "common/timer.h"

#include "scumm/actor.h"
#include "scumm/scumm.h"
#include "scumm/sound.h"
#include "scumm/imuse_digi/dimuse.h"
#include "scumm/imuse_digi/dimuse_bndmgr.h"

#include "sound/audiostream.h"
#include "sound/mixer.h"

namespace Scumm {

bool IMuseDigital::allocSlot(int priority) {
	int l;
	int lower_priority = 127;
	bool found_free = false;

	for (l = 0; l < MAX_DIGITAL_TRACKS; l++) {
		if (!_track[l]->used && !_track[l]->handle.isActive())
			found_free = true;
	}

	if (!found_free) {
		debug(5, "IMuseDigital::startSound(): All slots are full");
		for (l = 0; l < MAX_DIGITAL_TRACKS; l++) {
			if (_track[l]->used && _track[l]->handle.isActive() &&
					(lower_priority > _track[l]->priority) && (!_track[l]->stream2))
				lower_priority = _track[l]->priority;
		}
		if (lower_priority <= priority) {
			int track_id = -1;
			for (l = 0; l < MAX_DIGITAL_TRACKS; l++) {
				if (_track[l]->used && _track[l]->handle.isActive() &&
						(lower_priority == _track[l]->priority) && (!_track[l]->stream2)) {
					track_id = l;
				}
			}
			assert(track_id != -1);
			_track[track_id]->stream->finish();
			_track[track_id]->stream = NULL;
			_vm->_mixer->stopHandle(_track[track_id]->handle);
			_sound->closeSound(_track[track_id]->soundHandle);
			_track[track_id]->soundHandle = NULL;
			_track[track_id]->used = false;
			assert(!_track[track_id]->handle.isActive());
			debug(5, "IMuseDigital::startSound(): Removed sound %d from track %d", _track[track_id]->soundId, track_id);
		} else {
			debug(5, "IMuseDigital::startSound(): Priority sound too low");
			return false;
		}
	}

	return true;
}

void IMuseDigital::startSound(int soundId, const char *soundName, int soundType, int volGroupId, AudioStream *input, int hookId, int volume, int priority) {
	Common::StackLock lock(_mutex);
	debug(5, "IMuseDigital::startSound(%d)", soundId);
	int l;

	if (!allocSlot(priority)) {
		warning("IMuseDigital::startSound() Can't start sound - no free slots");
		return;
	}

	for (l = 0; l < MAX_DIGITAL_TRACKS; l++) {
		if (!_track[l]->used && !_track[l]->handle.isActive()) {
			_track[l]->pan = 64;
			_track[l]->vol = volume * 1000;
			_track[l]->volFadeDest = 0;
			_track[l]->volFadeStep = 0;
			_track[l]->volFadeDelay = 0;
			_track[l]->volFadeUsed = false;
			_track[l]->soundId = soundId;
			_track[l]->started = false;
			_track[l]->volGroupId = volGroupId;
			_track[l]->curHookId = hookId;
			_track[l]->priority = priority;
			_track[l]->curRegion = -1;
			_track[l]->dataOffset = 0;
			_track[l]->regionOffset = 0;
			_track[l]->trackOffset = 0;
			_track[l]->mod = 0;
			_track[l]->mixerFlags = 0;
			_track[l]->mixerPan = 0;
			_track[l]->mixerVol = volume;
			_track[l]->toBeRemoved = false;
			_track[l]->soundType = soundType;

			int bits = 0, freq = 0, channels = 0;

			if (input) {
				_track[l]->iteration = 0;
				_track[l]->souStream = true;
				_track[l]->soundName[0] = 0;
			} else {
				_track[l]->souStream = false;
				strcpy(_track[l]->soundName, soundName);
				_track[l]->soundHandle = _sound->openSound(soundId, soundName, soundType, volGroupId);

				if (_track[l]->soundHandle == NULL)
					return;

				bits = _sound->getBits(_track[l]->soundHandle);
				channels = _sound->getChannels(_track[l]->soundHandle);
				freq = _sound->getFreq(_track[l]->soundHandle);

				if ((soundId == kTalkSoundID) && (soundType == IMUSE_BUNDLE)) {
					if (_vm->_actorToPrintStrFor != 0xFF && _vm->_actorToPrintStrFor != 0) {
						Actor *a = _vm->derefActor(_vm->_actorToPrintStrFor, "IMuseDigital::startSound");
						freq = (freq * a->talkFrequency) / 256;
						_track[l]->pan = a->talkPan;
						_track[l]->vol = a->talkVolume * 1000;
					}
				}

				assert(bits == 8 || bits == 12 || bits == 16);
				assert(channels == 1 || channels == 2);
				assert(0 < freq && freq <= 65535);

				_track[l]->iteration = freq * channels;
				if (channels == 2)
					_track[l]->mixerFlags = SoundMixer::FLAG_STEREO | SoundMixer::FLAG_REVERSE_STEREO;

				if ((bits == 12) || (bits == 16)) {
					_track[l]->mixerFlags |= SoundMixer::FLAG_16BITS;
					_track[l]->iteration *= 2;
				} else if (bits == 8) {
					_track[l]->mixerFlags |= SoundMixer::FLAG_UNSIGNED;
				} else
					error("IMuseDigital::startSound(): Can't handle %d bit samples", bits);
			}

			if (input) {
				_track[l]->stream2 = input;
				_track[l]->stream = NULL;
				_track[l]->started = false;
			} else {
				// setup 1 second stream wrapped buffer
				int32 streamBufferSize = _track[l]->iteration;
				_track[l]->stream2 = NULL;
				_track[l]->stream = makeAppendableAudioStream(freq, _track[l]->mixerFlags, streamBufferSize);
				_vm->_mixer->playInputStream(&_track[l]->handle, _track[l]->stream, false, _track[l]->vol / 1000, _track[l]->pan, -1);
				_track[l]->started = true;
			}

			_track[l]->used = true;
			return;
		}
	}

	error("IMuseDigital::startSound(): We should never get here");
}

void IMuseDigital::setPriority(int soundId, int priority) {
	Common::StackLock lock(_mutex);
	debug(5, "IMuseDigital::setPriority(%d, %d)", soundId, priority);

	assert ((priority >= 0) && (priority <= 127));

	for (int l = 0; l < MAX_DIGITAL_TRACKS; l++) {
		if ((_track[l]->soundId == soundId) && _track[l]->used) {
			_track[l]->priority = priority;
		}
	}
}

void IMuseDigital::setVolume(int soundId, int volume) {
	Common::StackLock lock(_mutex);
	debug(5, "IMuseDigital::setVolume(%d, %d)", soundId, volume);
	for (int l = 0; l < MAX_DIGITAL_TRACKS; l++) {
		if ((_track[l]->soundId == soundId) && _track[l]->used) {
			_track[l]->vol = volume * 1000;
		}
	}
}

void IMuseDigital::setPan(int soundId, int pan) {
	Common::StackLock lock(_mutex);
	debug(5, "IMuseDigital::setPan(%d, %d)", soundId, pan);
	for (int l = 0; l < MAX_DIGITAL_TRACKS; l++) {
		if ((_track[l]->soundId == soundId) && _track[l]->used) {
			_track[l]->pan = pan;
		}
	}
}

void IMuseDigital::selectVolumeGroup(int soundId, int volGroupId) {
	Common::StackLock lock(_mutex);
	debug(5, "IMuseDigital::setGroupVolume(%d, %d)", soundId, volGroupId);
	assert((volGroupId >= 1) && (volGroupId <= 4));

	if (volGroupId == 4)
		volGroupId = 3;

	for (int l = 0; l < MAX_DIGITAL_TRACKS; l++) {
		if ((_track[l]->soundId == soundId) && _track[l]->used) {
			_track[l]->volGroupId = volGroupId;
		}
	}
}

void IMuseDigital::setFade(int soundId, int destVolume, int delay60HzTicks) {
	Common::StackLock lock(_mutex);
	debug(5, "IMuseDigital::setFade(%d, %d, %d)", soundId, destVolume, delay60HzTicks);
	for (int l = 0; l < MAX_DIGITAL_TRACKS; l++) {
		if ((_track[l]->soundId == soundId) && _track[l]->used) {
			_track[l]->volFadeDelay = delay60HzTicks;
			_track[l]->volFadeDest = destVolume * 1000;
			_track[l]->volFadeStep = (_track[l]->volFadeDest - _track[l]->vol) * 60 * 40 / (1000 * delay60HzTicks);
			_track[l]->volFadeUsed = true;
		}
	}
}

void IMuseDigital::fadeOutMusic(int fadeDelay) {
	Common::StackLock lock(_mutex);
	debug(5, "IMuseDigital::fadeOutMusic");
	for (int l = 0; l < MAX_DIGITAL_TRACKS; l++) {
		if ((_track[l]->volGroupId == IMUSE_VOLGRP_MUSIC) && _track[l]->used) {
			cloneToFadeOutTrack(l, fadeDelay, true);
		}
	}
}

int IMuseDigital::cloneToFadeOutTrack(int track, int fadeDelay, int killNormalTrack) {
	Common::StackLock lock(_mutex);
	debug(5, "IMuseDigital::cloneToFadeOutTrack(%d, %d)", track, fadeDelay);
	int fadeTrack = -1;

	for (int l = MAX_DIGITAL_TRACKS; l < MAX_DIGITAL_TRACKS + MAX_DIGITAL_FADETRACKS; l++) {
		if (!_track[l]->used && !_track[l]->handle.isActive()) {
			fadeTrack = l;
			break;
		}
	}
	if (fadeTrack == -1)
		error("IMuseDigital::cloneToFadeTrack() Can't find free fade track");

	// swap track to fade track
	Track *tmpTrack = _track[track];
	_track[track] = _track[fadeTrack];
	_track[fadeTrack] = tmpTrack;

	// copy track params from swaped fade track to new track
	_track[track]->pan = _track[fadeTrack]->pan;
	_track[track]->vol = _track[fadeTrack]->vol;
	_track[track]->volGroupId = _track[fadeTrack]->volGroupId;
	_track[track]->volFadeDelay = _track[fadeTrack]->volFadeDelay;
	_track[track]->volFadeDest = _track[fadeTrack]->volFadeDest;
	_track[track]->volFadeStep = _track[fadeTrack]->volFadeStep;
	_track[track]->volFadeUsed = _track[fadeTrack]->volFadeUsed;
	_track[track]->priority = _track[fadeTrack]->priority;
	_track[track]->soundId = _track[fadeTrack]->soundId;
	_track[track]->dataOffset = _track[fadeTrack]->dataOffset;
	_track[track]->regionOffset = _track[fadeTrack]->regionOffset;
	_track[track]->trackOffset = _track[fadeTrack]->trackOffset;
	_track[track]->curRegion = _track[fadeTrack]->curRegion;
	_track[track]->curHookId = _track[fadeTrack]->curHookId;
	_track[track]->iteration = _track[fadeTrack]->iteration;
	_track[track]->mixerFlags = _track[fadeTrack]->mixerFlags;
	_track[track]->mixerVol = _track[fadeTrack]->mixerVol;
	_track[track]->mixerPan = _track[fadeTrack]->mixerPan;
	_track[track]->mod = _track[fadeTrack]->mod;
	_track[track]->used = _track[fadeTrack]->used;
	_track[track]->toBeRemoved = _track[fadeTrack]->toBeRemoved;
	_track[track]->souStream = _track[fadeTrack]->souStream;
	_track[track]->started = _track[fadeTrack]->started;
	_track[track]->stream2 = _track[fadeTrack]->stream2;
	strcpy(_track[track]->soundName, _track[fadeTrack]->soundName);
	_track[track]->soundType = _track[fadeTrack]->soundType;

	_track[track]->soundHandle = NULL;
	_track[track]->stream = NULL;

	_track[fadeTrack]->volFadeDelay = fadeDelay;
	_track[fadeTrack]->volFadeDest = 0;
	_track[fadeTrack]->volFadeStep = (_track[fadeTrack]->volFadeDest - _track[fadeTrack]->vol) * 60 * 40 / (1000 * fadeDelay);
	_track[fadeTrack]->volFadeUsed = true;

	if (killNormalTrack) {
		_track[track]->used = false;
	} else {
		_track[track]->soundHandle = _sound->cloneSound(_track[fadeTrack]->soundHandle);
		// setup 1 second stream wrapped buffer
		int32 streamBufferSize = _track[track]->iteration;
		_track[track]->stream = makeAppendableAudioStream(_sound->getFreq(_track[track]->soundHandle), _track[track]->mixerFlags, streamBufferSize);
		_vm->_mixer->playInputStream(&_track[track]->handle, _track[track]->stream, false, _track[track]->vol / 1000, _track[track]->pan, -1);
		_track[track]->started = true;
	}

	return fadeTrack;
}

} // End of namespace Scumm

Index: dimuse.cpp
===================================================================
RCS file: /cvsroot/scummvm/scummvm/scumm/imuse_digi/dimuse.cpp,v
retrieving revision 1.45.2.1
retrieving revision 1.45.2.2
diff -u -d -r1.45.2.1 -r1.45.2.2
--- dimuse.cpp	15 Feb 2004 06:30:47 -0000	1.45.2.1
+++ dimuse.cpp	2 May 2004 16:36:04 -0000	1.45.2.2
@@ -46,137 +46,174 @@
 	_mutex = g_system->create_mutex();
 	_pause = false;
 	_sound = new ImuseDigiSndMgr(_vm);
+	_volVoice = 0;
+	_volSfx = 0;
+	_volMusic = 0;
+	resetState();
+	for (int l = 0; l < MAX_DIGITAL_TRACKS + MAX_DIGITAL_FADETRACKS; l++) {
+		_track[l] = new Track;
+		_track[l]->used = false;
+	}
 	_vm->_timer->installTimerProc(timer_handler, 1000000 / 25, this);
-
-	_curMusicState = 0;
-	_curMusicSeq = 0;
-	_curMusicCue = 0;
-	memset(_attributesSeq, 0, sizeof(_attributesSeq));
-	memset(_attributesState, 0, sizeof(_attributesState));
-	memset(_attributesTable, 0, sizeof(_attributesTable));
-	_curSeqAtribPos = 0;
 }
 
 IMuseDigital::~IMuseDigital() {
-	stopAllSounds(true);
+	Common::StackLock lock(_mutex);
+	stopAllSounds();
 	_vm->_timer->removeTimerProc(timer_handler);
+	for (int l = 0; l < MAX_DIGITAL_TRACKS + MAX_DIGITAL_FADETRACKS; l++) {
+		delete _track[l];
+	}
 	delete _sound;
 	g_system->delete_mutex(_mutex);
 }
 
+void IMuseDigital::resetState() {
+	_curMusicState = 0;
+	_curMusicSeq = 0;
+	_curMusicCue = 0;
+	memset(_attributes, 0, sizeof(_attributes));
+	_nextSeqToPlay = 0;
+}
+
+void IMuseDigital::saveOrLoad(Serializer *ser) {
+	// save-load code not backported
+}
+
 void IMuseDigital::callback() {
-	Common::StackLock lock(_mutex, g_system, "IMuseDigital::callback()");
+	Common::StackLock lock(_mutex);
 	int l = 0;
 
 	if (_pause || !_vm)
 		return;
 
-	for (l = 0; l < MAX_DIGITAL_TRACKS;l ++) {
-		if (_track[l].used) {
-			if (_track[l].waitForEndSeq) {
-				if ((_curMusicState != 0) && (_curMusicSeq == 0))
-					_track[l].waitForEndSeq = false;
-				else
-					continue;
-			}
-			if (_track[l].stream2) {
-				if (!_track[l].handle.isActive() && _track[l].started) {
-					debug(5, "IMuseDigital::callback(): stoped sound: %d", _track[l].soundId);
-					delete _track[l].stream2;
-					_track[l].stream2 = NULL;
-					_track[l].used = false;
+	for (l = 0; l < MAX_DIGITAL_TRACKS + MAX_DIGITAL_FADETRACKS; l++) {
+		if (_track[l]->used) {
+			if (_track[l]->stream2) {
+				if (!_track[l]->handle.isActive() && _track[l]->started) {
+					debug(5, "IMuseDigital::callback() A: stopped sound: %d", _track[l]->soundId);
+					delete _track[l]->stream2;
+					_track[l]->stream2 = NULL;
+					_track[l]->used = false;
 					continue;
 				}
-			} else if (_track[l].stream) {
-				if ((_track[l].toBeRemoved)) {
-					debug(5, "IMuseDigital::callback(): stoped sound: %d", _track[l].soundId);
-					_track[l].stream->finish();
-					_track[l].stream = NULL;
-					_sound->closeSound(_track[l].soundHandle);
-					_curMusicSeq = 0;
-					_track[l].used = false;
+			} else if (_track[l]->stream) {
+				if (_track[l]->toBeRemoved) {
+					debug(5, "IMuseDigital::callback() B: stopped sound: %d", _track[l]->soundId);
+					_track[l]->stream->finish();
+					_track[l]->stream = NULL;
+					_sound->closeSound(_track[l]->soundHandle);
+					_track[l]->soundHandle = NULL;
+					_track[l]->used = false;
 					continue;
 				}
 			}
 
-			if (_track[l].volFadeUsed) {
-				if (_track[l].volFadeStep < 0) {
-					if (_track[l].vol > _track[l].volFadeDest) {
-						_track[l].vol += _track[l].volFadeStep;
-						if (_track[l].vol < _track[l].volFadeDest) {
-							_track[l].vol = _track[l].volFadeDest;
-							_track[l].volFadeUsed = false;
+			if (_track[l]->volFadeUsed) {
+				if (_track[l]->volFadeStep < 0) {
+					if (_track[l]->vol > _track[l]->volFadeDest) {
+						_track[l]->vol += _track[l]->volFadeStep;
+						if (_track[l]->vol < _track[l]->volFadeDest) {
+							_track[l]->vol = _track[l]->volFadeDest;
+							_track[l]->volFadeUsed = false;
 						}
-						if (_track[l].vol == 0) {
-							_track[l].toBeRemoved = true;
+						if (_track[l]->vol == 0) {
+							_track[l]->toBeRemoved = true;
 						}
 					}
-				} else if (_track[l].volFadeStep > 0) {
-					if (_track[l].vol < _track[l].volFadeDest) {
-						_track[l].vol += _track[l].volFadeStep;
-						if (_track[l].vol > _track[l].volFadeDest) {
-							_track[l].vol = _track[l].volFadeDest;
-							_track[l].volFadeUsed = false;
+				} else if (_track[l]->volFadeStep > 0) {
+					if (_track[l]->vol < _track[l]->volFadeDest) {
+						_track[l]->vol += _track[l]->volFadeStep;
+						if (_track[l]->vol > _track[l]->volFadeDest) {
+							_track[l]->vol = _track[l]->volFadeDest;
+							_track[l]->volFadeUsed = false;
 						}
 					}
 				}
-				debug(5, "Fade: sound(%d), Vol(%d)", _track[l].soundId, _track[l].vol / 1000);
+				debug(5, "Fade: sound(%d), Vol(%d)", _track[l]->soundId, _track[l]->vol / 1000);
 			}
 
-			int pan = (_track[l].pan != 64) ? 2 * _track[l].pan - 127 : 0;
+			int pan = (_track[l]->pan != 64) ? 2 * _track[l]->pan - 127 : 0;
+			int vol = _track[l]->vol / 1000;
+
+			if (_track[l]->volGroupId == 1)
+				vol = (vol * _volVoice) / 128;
+			if (_track[l]->volGroupId == 2)
+				vol = (vol * _volSfx) / 128;
+			if (_track[l]->volGroupId == 3)
+				vol = (vol * _volMusic) / 128;
 
 			if (_vm->_mixer->isReady()) {
-				if (_track[l].stream2) {
-					if (!_track[l].started) {
-						_track[l].started = true;
-						_vm->_mixer->playInputStream(&_track[l].handle, _track[l].stream2, true, _track[l].vol / 1000, _track[l].pan, -1, false);
+				if (_track[l]->stream2) {
+					if (!_track[l]->started) {
+						_track[l]->started = true;
+						_vm->_mixer->playInputStream(&_track[l]->handle, _track[l]->stream2, false, _track[l]->vol / 1000, _track[l]->pan, -1, false);
 					} else {
-						_vm->_mixer->setChannelVolume(_track[l].handle, _track[l].vol / 1000);
-						_vm->_mixer->setChannelBalance(_track[l].handle, pan);
+						_vm->_mixer->setChannelVolume(_track[l]->handle, vol);
+						_vm->_mixer->setChannelBalance(_track[l]->handle, pan);
 					}
 					continue;
 				}
 			}
 
-			if (_track[l].stream) {
-				int32 mixer_size = _track[l].pullSize;
+			if (_track[l]->stream) {
 				byte *data = NULL;
 				int32 result = 0;
 
-				if (_track[l].stream->endOfData()) {
-					mixer_size *= 2;
+				if (_track[l]->curRegion == -1) {
+					switchToNextRegion(l);
+					if (_track[l]->toBeRemoved)
+						continue;
 				}
 
-				if (_track[l].curRegion == -1)
-					switchToNextRegion(l);
+				int bits = _sound->getBits(_track[l]->soundHandle);
+				int channels = _sound->getChannels(_track[l]->soundHandle);
+
+				int32 bufferUsage = _track[l]->iteration - _track[l]->stream->getFreeSpace() - 4;
+				int32 bufferMin = (_track[l]->iteration * 1) / 10;
+				if (bufferMin < bufferUsage)
+					continue;
+
+				int32 mixer_size = bufferMin - bufferUsage;
+
+				if ((bits == 12) || (bits == 16)) {
+					if (channels == 1)
+						mixer_size &= ~1;
+					if (channels == 2)
+						mixer_size &= ~3;
+				} else {
+					if (channels == 2)
+						mixer_size &= ~1;
+				}
+
+				if (mixer_size == 0)
+					continue;
 
-				int bits = _sound->getBits(_track[l].soundHandle);
 				do {
 					if (bits == 12) {
 						byte *ptr = NULL;
 
-						mixer_size += _track[l].mod;
+						mixer_size += _track[l]->mod;
 						int mixer_size_12 = (mixer_size * 3) / 4;
 						int length = (mixer_size_12 / 3) * 4;
-						_track[l].mod = mixer_size - length;
+						_track[l]->mod = mixer_size - length;
 
-						int32 offset = (_track[l].regionOffset * 3) / 4;
-						int result2 = _sound->getDataFromRegion(_track[l].soundHandle, _track[l].curRegion, &ptr, offset, mixer_size_12);
+						int32 offset = (_track[l]->regionOffset * 3) / 4;
+						int result2 = _sound->getDataFromRegion(_track[l]->soundHandle, _track[l]->curRegion, &ptr, offset, mixer_size_12);
 						result = BundleCodecs::decode12BitsSample(ptr, &data, result2);
 
 						free(ptr);
 					} else if (bits == 16) {
-						result = _sound->getDataFromRegion(_track[l].soundHandle, _track[l].curRegion, &data, _track[l].regionOffset, mixer_size);
-						if (_sound->getChannels(_track[l].soundHandle) == 1) {
+						result = _sound->getDataFromRegion(_track[l]->soundHandle, _track[l]->curRegion, &data, _track[l]->regionOffset, mixer_size);
+						if (channels == 1) {
 							result &= ~1;
 						}
-						if (_sound->getChannels(_track[l].soundHandle) == 2) {
-							if (result & 2)
-								result &= ~2;
+						if (channels == 2) {
+							result &= ~3;
 						}
 					} else if (bits == 8) {
-						result = _sound->getDataFromRegion(_track[l].soundHandle, _track[l].curRegion, &data, _track[l].regionOffset, mixer_size);
-						if (_sound->getChannels(_track[l].soundHandle) == 2) {
+						result = _sound->getDataFromRegion(_track[l]->soundHandle, _track[l]->curRegion, &data, _track[l]->regionOffset, mixer_size);
+						if (channels == 2) {
 							result &= ~1;
 						}
 					}
@@ -185,17 +222,17 @@
 						result = mixer_size;
 
 					if (_vm->_mixer->isReady()) {
-						_vm->_mixer->setChannelVolume(_track[l].handle, _track[l].vol / 1000);
-						_vm->_mixer->setChannelBalance(_track[l].handle, pan);
-						_track[l].stream->append(data, result);
-						_track[l].regionOffset += result;
-						_track[l].trackOffset += result;
+						_vm->_mixer->setChannelVolume(_track[l]->handle, vol);
+						_vm->_mixer->setChannelBalance(_track[l]->handle, pan);
+						_track[l]->stream->append(data, result);
+						_track[l]->regionOffset += result;
+						_track[l]->trackOffset += result;
 						free(data);
 					}
-					
-					if (_sound->isEndOfRegion(_track[l].soundHandle, _track[l].curRegion)) {
+
+					if (_sound->isEndOfRegion(_track[l]->soundHandle, _track[l]->curRegion)) {
 						switchToNextRegion(l);
-						if (_track[l].toBeRemoved)
+						if (_track[l]->toBeRemoved)
 							break;
 					}
 					mixer_size -= result;
@@ -207,470 +244,59 @@
 }
 
 void IMuseDigital::switchToNextRegion(int track) {
-	int num_regions = _sound->getNumRegions(_track[track].soundHandle);
+	debug(5, "switchToNextRegion(track:%d)", track);
 
-	if (++_track[track].curRegion == num_regions) {
-		_track[track].toBeRemoved = true;
+	if (track >= MAX_DIGITAL_TRACKS) {
+		_track[track]->toBeRemoved = true;
+		debug(5, "exit (fadetrack can't go next region) switchToNextRegion(track:%d)", track);
 		return;
 	}
 
-	int jumpId = _sound->getJumpIdByRegionAndHookId(_track[track].soundHandle, _track[track].curRegion, _track[track].curHookId);
-	if (jumpId != -1) {
-		int region = _sound->getRegionIdByJumpId(_track[track].soundHandle, jumpId);
-		if (region != -1) {
-			_track[track].curRegion = region;
-			debug(5, "switchToNextRegion-sound(%d) jump to %d region, curHookId: %d", _track[track].soundId, _track[track].curRegion, _track[track].curHookId);
-			_track[track].curHookId = 0;
-		}
-	}
-
-	debug(5, "switchToNextRegion-sound(%d) select %d region, curHookId: %d", _track[track].soundId, _track[track].curRegion, _track[track].curHookId);
-	_track[track].dataOffset = _sound->getRegionOffset(_track[track].soundHandle, _track[track].curRegion);
-	_track[track].regionOffset = 0;
-}
-
-void IMuseDigital::startSound(int soundId, const char *soundName, int soundType, int soundGroup, AudioStream *input, bool sequence, int hookId, int volume, bool wait) {
-	Common::StackLock lock(_mutex, g_system, "IMuseDigital::startSound()");
-	debug(5, "IMuseDigital::startSound(%d)", soundId);
-	int l;
-
-	for (l = 0; l < MAX_DIGITAL_TRACKS; l++) {
-		if (!_track[l].used && !_track[l].handle.isActive()) {
-			_track[l].pan = 64;
-			_track[l].vol = volume * 1000;
-			_track[l].volFadeDest = 0;
-			_track[l].volFadeStep = 0;
-			_track[l].volFadeDelay = 0;
-			_track[l].volFadeUsed = false;
-			_track[l].soundId = soundId;
-			_track[l].started = false;
-			_track[l].soundGroup = soundGroup;
-			_track[l].curHookId = hookId;
-			_track[l].curRegion = -1;
-			_track[l].dataOffset = 0;
-			_track[l].regionOffset = 0;
-			_track[l].trackOffset = 0;
-			_track[l].mod = 0;
-			_track[l].toBeRemoved = false;
-			_track[l].sequence = sequence;
-			_track[l].waitForEndSeq = wait;
-
-			int bits = 0, freq = 0, channels = 0, mixerFlags = 0;
-
-			if (input) {
-				_track[l].iteration = 1; // ?
-				// Do nothing here, we already have an audio stream
-			} else {
-				_track[l].soundHandle = _sound->openSound(soundId, soundName, soundType, soundGroup);
-
-				if (_track[l].soundHandle == NULL)
-					return;
-
-				bits = _sound->getBits(_track[l].soundHandle);
-				channels = _sound->getChannels(_track[l].soundHandle);
-				freq = _sound->getFreq(_track[l].soundHandle);
-
-				if ((soundId == kTalkSoundID) && (soundType == IMUSE_BUNDLE)) {
-					if (_vm->_actorToPrintStrFor != 0xFF && _vm->_actorToPrintStrFor != 0) {
-						Actor *a = _vm->derefActor(_vm->_actorToPrintStrFor, "IMuseDigital::startSound");
-						freq = (freq * a->talkFrequency) / 256;
-						_track[l].pan = a->talkPan;
-						_track[l].vol = a->talkVolume * 1000;
-					}
-				}
-
-				assert(bits == 8 || bits == 12 || bits == 16);
-				assert(channels == 1 || channels == 2);
-				assert(0 < freq && freq <= 65535);
-
-				// Round the frequency to a multiple of 25. This is done to 
-				// ensure we don't run into data under-/overflows (this is a
-				// design limitation of the current IMuseDigital code, which
-				// pushes data 'blindly' into the mixer, instead of providing
-				// a pull based interface, i.e. a custom AudioInputStream
-				// subclass).
-				freq -= (freq % 25);
-
-				_track[l].iteration = _track[l].pullSize = freq * channels;
-
-				if (channels == 2)
-					mixerFlags = SoundMixer::FLAG_STEREO | SoundMixer::FLAG_REVERSE_STEREO;
-
-				if ((bits == 12) || (bits == 16)) {
-					mixerFlags |= SoundMixer::FLAG_16BITS;
-					_track[l].iteration = _track[l].pullSize *= 2;
-				} else if (bits == 8) {
-					mixerFlags |= SoundMixer::FLAG_UNSIGNED;
-				} else
-					error("IMuseDigital::startSound(): Can't handle %d bit samples", bits);
-
-				_track[l].pullSize /= 25;	// We want a "frame rate" of 25 audio blocks per second
-			}
-
-			if (input) {
-				_track[l].stream2 = input;
-				_track[l].stream = NULL;
-			} else {
-				_track[l].stream2 = NULL;
-				_track[l].stream = makeAppendableAudioStream(freq, mixerFlags, 100000);
-				_vm->_mixer->playInputStream(&_track[l].handle, _track[l].stream, true, _track[l].vol / 1000, _track[l].pan, -1);
-			}
-
-			_track[l].used = true;
-			return;
-		}
-	}
-	warning("IMuseDigital::startSound(): All slots are full");
-}
-
-void IMuseDigital::stopSound(int soundId) {
-	Common::StackLock lock(_mutex, g_system, "IMuseDigital::stopSound()");
-	debug(5, "IMuseDigital::stopSound(%d)", soundId);
-	for (int l = 0; l < MAX_DIGITAL_TRACKS; l++) {
-		if ((_track[l].soundId == soundId) && _track[l].used) {
-			if (_track[l].stream) {
-				_track[l].toBeRemoved = true;
-			}
-			else if (_track[l].stream2)
-				_vm->_mixer->stopHandle(_track[l].handle);
-		}
-	}
-}
-
-void IMuseDigital::setVolume(int soundId, int volume) {
-	Common::StackLock lock(_mutex, g_system, "IMuseDigital::setVolume()");
-	debug(5, "IMuseDigital::setVolumeSound(%d, %d)", soundId, volume);
-	for (int l = 0; l < MAX_DIGITAL_TRACKS; l++) {
-		if ((_track[l].soundId == soundId) && _track[l].used) {
-			_track[l].vol = volume * 1000;
-		}
-	}
-}
-
-void IMuseDigital::setPan(int soundId, int pan) {
-	Common::StackLock lock(_mutex, g_system, "IMuseDigital::setPan()");
-	debug(5, "IMuseDigital::setVolumeSound(%d, %d)", soundId, pan);
-	for (int l = 0; l < MAX_DIGITAL_TRACKS; l++) {
-		if ((_track[l].soundId == soundId) && _track[l].used) {
-			_track[l].pan = pan;
-		}
-	}
-}
-
-void IMuseDigital::setFade(int soundId, int destVolume, int delay60HzTicks) {
-	Common::StackLock lock(_mutex, g_system, "IMuseDigital::setFade()");
-	debug(5, "IMuseDigital::setFade(%d, %d, %d)", soundId, destVolume, delay60HzTicks);
-	for (int l = 0; l < MAX_DIGITAL_TRACKS; l++) {
-		if ((_track[l].soundId == soundId) && _track[l].used) {
-			_track[l].volFadeDelay = delay60HzTicks;
-			_track[l].volFadeDest = destVolume * 1000;
-			_track[l].volFadeStep = (_track[l].volFadeDest - _track[l].vol) * 60 * 40 / (1000 * delay60HzTicks);
-			_track[l].volFadeUsed = true;
-		}
-	}
-}
-
-void IMuseDigital::stopAllSounds(bool waitForStop) {
-	Common::StackLock lock(_mutex, g_system, "IMuseDigital::stopAllSounds()");
-	debug(5, "IMuseDigital::stopAllSounds");
-	for (int l = 0; l < MAX_DIGITAL_TRACKS; l++) {
-		if (_track[l].used) {
-			if (_track[l].stream) {
-				_track[l].toBeRemoved = true;
-			} else if (_track[l].stream2)
-				_vm->_mixer->stopHandle(_track[l].handle);
-		}
-	}
-/*
-	if (waitForStop) {
-		bool used;
-		do {
-			used = false;
-			for (int l = 0; l < MAX_DIGITAL_TRACKS; l++) {
-				if (_track[l].used)
-					used = true;
-			}
-			g_system->delay_msecs(10);
-		} while (used);
-	}*/
-}
-
-void IMuseDigital::fadeOutMusic(int fadeDelay) {
-	Common::StackLock lock(_mutex, g_system, "IMuseDigital::fadeOutMusic()");
-	debug(5, "IMuseDigital::fadeOutMusic");
-	for (int l = 0; l < MAX_DIGITAL_TRACKS; l++) {
-		if ((_track[l].used) && (!_track[l].waitForEndSeq) && (_track[l].soundGroup == IMUSE_MUSIC) && (!_track[l].volFadeUsed)) {
-			_track[l].volFadeDelay = fadeDelay;
-			_track[l].volFadeDest = 0;
-			_track[l].volFadeStep = (_track[l].volFadeDest - _track[l].vol) * 60 * 40 / (1000 * fadeDelay);
-			_track[l].volFadeUsed = true;
-		}
-	}
-}
-
-void IMuseDigital::pause(bool p) {
-	Common::StackLock lock(_mutex, g_system, "IMuseDigital::pause()");
-	for (int l = 0; l < MAX_DIGITAL_TRACKS; l++) {
-		if (_track[l].used) {
-			_vm->_mixer->pauseHandle(_track[l].handle, p);
-		}
-	}
-	_pause = p;
-}
-
-void IMuseDigital::parseScriptCmds(int a, int b, int c, int d, int e, int f, int g, int h) {
-	int cmd = a;
-	int soundId = b;
-	int sub_cmd = c;
+	int num_regions = _sound->getNumRegions(_track[track]->soundHandle);
 
-	if (!cmd)
+	if (++_track[track]->curRegion == num_regions) {
+		_track[track]->toBeRemoved = true;
+		debug(5, "exit (end of regions) switchToNextRegion(track:%d)", track);
 		return;
-
-	switch (cmd) {
-	case 10: // ImuseStopAllSounds
-		stopAllSounds();
-		break;
-	case 12: // ImuseSetParam
-		switch (sub_cmd) {
-		case 0x400: // set group volume
-			debug(5, "set group volume (0x400), soundId(%d), group volume(%d)", soundId, d);
-			break;
-		case 0x500: // set priority - could be ignored
-			break;
-		case 0x600: // set volume
-			setVolume(soundId, d);
-			break;
-		case 0x700: // set pan
-			setPan(soundId, d);
-			break;
-		default:
-			warning("IMuseDigital::doCommand SetParam DEFAULT command %d", sub_cmd);
-			break;
-		}
-		break;
-	case 14: // ImuseFadeParam
-		switch (sub_cmd) {
-		case 0x600: // set volume fading
-			if ((d != 0) && (e == 0))
-				setVolume(soundId, d);
-			else if ((d == 0) && (e == 0))
-				stopSound(soundId);
-			else
-				setFade(soundId, d, e);
-			break;
-		default:
-			warning("IMuseDigital::doCommand FadeParam DEFAULT sub command %d", sub_cmd);
-			break;
-		}
-		break;
-	case 25: // ImuseStartStream
-		debug(5, "ImuseStartStream (%d, %d, %d)", soundId, c, d);
-		break;
-	case 26: // ImuseSwitchStream
-		debug(5, "ImuseSwitchStream (%d, %d, %d, %d, %d)", soundId, c, d, e, f);
-		break;
-	case 0x1000: // ImuseSetState
-		debug(5, "ImuseSetState (%d)", b);
-		if ((_vm->_gameId == GID_DIG) && (_vm->_features & GF_DEMO)) {
-			if (b == 1) {
-				fadeOutMusic(200);
-				startMusic(1, false, 127, false);
-			} else {
-				if (getSoundStatus(2) == 0) {
-					fadeOutMusic(200);
-					startMusic(2, false, 127, false);
-				}
-			}
-		} else if ((_vm->_gameId == GID_CMI) && (_vm->_features & GF_DEMO)) {
-			if (b == 2) {
-				fadeOutMusic(120);
-				startMusic("in1.imx", 2002, false, 0, 127, false);
-			} else if (b == 4) {
-				fadeOutMusic(120);
-				startMusic("in2.imx", 2004, false, 0, 127, false);
-			} else if (b == 8) {
-				fadeOutMusic(120);
-				startMusic("out1.imx", 2008, false, 0, 127, false);
-			} else if (b == 9) {
-				fadeOutMusic(120);
-				startMusic("out2.imx", 2009, false, 0, 127, false);
-			} else if (b == 16) {
-				fadeOutMusic(120);
-				startMusic("gun.imx", 2016, false, 0, 127, false);
-			} else {
-				warning("imuse digital: set state unknown for cmi demo: %d, room: %d", b, this->_vm->_currentRoom);
-			}
-		} else if (_vm->_gameId == GID_DIG) {
-			setDigMusicState(b);
-		} else if (_vm->_gameId == GID_CMI) {
-			setComiMusicState(b);
-		} else if (_vm->_gameId == GID_FT) {
-			setFtMusicState(b);
-		}
-		break;
-	case 0x1001: // ImuseSetSequence
-		debug(5, "ImuseSetSequence (%d)", b);
-		if (_vm->_gameId == GID_DIG) {
-			setDigMusicSequence(b);
-		} else if (_vm->_gameId == GID_CMI) {
-			setComiMusicSequence(b);
-		} else if (_vm->_gameId == GID_FT) {
-			setFtMusicSequence(b);
-		}
-		break;
-	case 0x1002: // ImuseSetCuePoint
-		debug(5, "ImuseSetCuePoint (%d)", b);
-		if (_vm->_gameId == GID_FT) {
-			setFtMusicCuePoint(b);
-		}
-		break;
-	case 0x1003: // ImuseSetAttribute
-		debug(5, "ImuseSetAttribute (%d, %d)", b, c);
-		if (_vm->_gameId == GID_DIG) {
-			assert(b >= 0 && b < 11);
-			_attributesTable[b] = c;
-		}
-		break;
-	case 0x2000: // ImuseSetMasterSFXVolume
-		debug(5, "ImuseSetMasterSFXVolume (%d)", b);
-		// TODO
-		break;
-	case 0x2001: // ImuseSetMasterVoiceVolume
-		debug(5, "ImuseSetMasterVoiceVolume (%d)", b);
-		// TODO
-		break;
-	case 0x2002: // ImuseSetMasterMusicVolume
-		debug(5, "ImuseSetMasterMusicVolume (%d)", b);
-		// TODO
-		break;
-	default:
-		warning("IMuseDigital::doCommand DEFAULT command %d", cmd);
 	}
-}
-
-int IMuseDigital::getSoundStatus(int sound) const {
-	Common::StackLock lock(_mutex, g_system, "IMuseDigital::getSoundStatus()");
-	debug(5, "IMuseDigital::getSoundStatus(%d)", sound);
-	for (int l = 0; l < MAX_DIGITAL_TRACKS; l++) {
-		if ((_track[l].soundId == sound) && _track[l].used) {
-			return 1;
-		}
-	}
-
-	return 0;
-}
-
-void IMuseDigital::getLipSync(int soundId, int syncId, int32 msPos, int32 &width, int32 &height) {
-	int32 sync_size;
-	byte *sync_ptr;
-
-	msPos /= 16;
-	if (msPos < 65536) {
-		for (int l = 0; l < MAX_DIGITAL_TRACKS; l++) {
-			if ((_track[l].soundId == soundId) && _track[l].used) {
-				_sound->getSyncSizeAndPtrById(_track[l].soundHandle, syncId, sync_size, &sync_ptr);
-				if ((sync_size != 0) && (sync_ptr != NULL)) {
-					sync_size /= 4;
-					while (sync_size--) {
-						if (READ_BE_UINT16(sync_ptr) >= msPos)
-							break;
-						sync_ptr += 4;
-					}
-					if (sync_size < 0)
-						sync_ptr -= 4;
-					else
-						if (READ_BE_UINT16(sync_ptr) > msPos)
-							sync_ptr -= 4;
 
-					width = sync_ptr[2];
-					height = sync_ptr[3];
-					return;
+	int jumpId = _sound->getJumpIdByRegionAndHookId(_track[track]->soundHandle, _track[track]->curRegion, _track[track]->curHookId);
+	if (jumpId == -1)
+		jumpId = _sound->getJumpIdByRegionAndHookId(_track[track]->soundHandle, _track[track]->curRegion, 0);
+	if (jumpId != -1) {
+		int region = _sound->getRegionIdByJumpId(_track[track]->soundHandle, jumpId);
+		assert(region != -1);
+		int sampleHookId = _sound->getJumpHookId(_track[track]->soundHandle, jumpId);
+		assert(sampleHookId != -1);
+		int fadeDelay = (60 * _sound->getJumpFade(_track[track]->soundHandle, jumpId)) / 1000;
+		if (sampleHookId != 0) {
+			if (_track[track]->curHookId == sampleHookId) {
+				if (fadeDelay != 0) {
+					int fadeTrack = cloneToFadeOutTrack(track, fadeDelay, false);
+					_track[fadeTrack]->dataOffset = _sound->getRegionOffset(_track[fadeTrack]->soundHandle, _track[fadeTrack]->curRegion);
+					_track[fadeTrack]->regionOffset = 0;
+					debug(5, "switchToNextRegion-sound(%d) select %d region, curHookId: %d", _track[fadeTrack]->soundId, _track[fadeTrack]->curRegion, _track[fadeTrack]->curHookId);
+					_track[fadeTrack]->curHookId = 0;
 				}
+				_track[track]->curRegion = region;
+				debug(5, "switchToNextRegion-sound(%d) jump to %d region, curHookId: %d", _track[track]->soundId, _track[track]->curRegion, _track[track]->curHookId);
+				_track[track]->curHookId = 0;
 			}
-		}
-	}
-}
-
-int32 IMuseDigital::getPosInMs(int soundId) {
-	for (int l = 0; l < MAX_DIGITAL_TRACKS; l++) {
-		if ((_track[l].soundId == soundId) && (_track[l].used)) {
-			int32 pos = (5 * (_track[l].dataOffset + _track[l].regionOffset)) / (_track[l].iteration / 200);
-			return pos;
-		}
-	}
-
-	return 0;
-}
-
-int32 IMuseDigital::getCurMusicPosInMs() {
-	Common::StackLock lock(_mutex, g_system, "IMuseDigital::getCurMusicPosInMs()");
-	int soundId = -1;
-
-	for (int l = 0; l < MAX_DIGITAL_TRACKS; l++) {
-		if ((_track[l].used) && (!_track[l].waitForEndSeq) && (_track[l].soundGroup == IMUSE_MUSIC) && (!_track[l].volFadeUsed)) {
-			soundId = _track[l].soundId;
-		}
-	}
-
-	int32 msPos = getPosInMs(soundId);
-	debug(5, "IMuseDigital::getCurMusicPosInMs(%d) = %d", soundId, msPos);
-	return msPos;
-}
-
-int32 IMuseDigital::getCurVoiceLipSyncWidth() {
-	Common::StackLock lock(_mutex, g_system, "IMuseDigital::getCutVoiceLipSyncWidth()");
-	int32 msPos = getPosInMs(kTalkSoundID) + _vm->VAR(_vm->VAR_SYNC) + 50;
-	int32 width = 0, height = 0;
-
-	debug(5, "IMuseDigital::getCurVoiceLipSyncWidth(%d)", kTalkSoundID);
-	getLipSync(kTalkSoundID, 0, msPos, width, height);
-	return width;
-}
-
-int32 IMuseDigital::getCurVoiceLipSyncHeight() {
-	Common::StackLock lock(_mutex, g_system, "IMuseDigital::getCurVoiceLipSyncHeight()");
-	int32 msPos = getPosInMs(kTalkSoundID) + _vm->VAR(_vm->VAR_SYNC) + 50;
-	int32 width = 0, height = 0;
-
-	debug(5, "IMuseDigital::getCurVoiceLipSyncHeight(%d)", kTalkSoundID);
-	getLipSync(kTalkSoundID, 0, msPos, width, height);
-	return height;
-}
-
-int32 IMuseDigital::getCurMusicLipSyncWidth(int syncId) {
-	Common::StackLock lock(_mutex, g_system, "IMuseDigital::getCurMusicLipSyncWidth()");
-	int soundId = -1;
-
-	for (int l = 0; l < MAX_DIGITAL_TRACKS; l++) {
-		if ((_track[l].used) && (!_track[l].waitForEndSeq) && (_track[l].soundGroup == IMUSE_MUSIC) && (!_track[l].volFadeUsed)) {
-			soundId = _track[l].soundId;
-		}
-	}
-
-	int32 msPos = getPosInMs(soundId) + _vm->VAR(_vm->VAR_SYNC) + 50;
-	int32 width = 0, height = 0;
-
-	debug(5, "IMuseDigital::getCurVoiceLipSyncWidth(%d, %d)", soundId, msPos);
-	getLipSync(soundId, syncId, msPos, width, height);
-	return width;
-}
-
-int32 IMuseDigital::getCurMusicLipSyncHeight(int syncId) {
-	Common::StackLock lock(_mutex, g_system, "IMuseDigital::getCurMusicLipSyncHeight()");
-	int soundId = -1;
-
-	for (int l = 0; l < MAX_DIGITAL_TRACKS; l++) {
-		if ((_track[l].used) && (!_track[l].waitForEndSeq) && (_track[l].soundGroup == IMUSE_MUSIC) && (!_track[l].volFadeUsed)) {
-			soundId = _track[l].soundId;
+		} else {
+			if (fadeDelay != 0) {
+				int fadeTrack = cloneToFadeOutTrack(track, fadeDelay, false);
+				_track[fadeTrack]->dataOffset = _sound->getRegionOffset(_track[fadeTrack]->soundHandle, _track[fadeTrack]->curRegion);
+				_track[fadeTrack]->regionOffset = 0;
+				debug(5, "switchToNextRegion-sound(%d) select %d region, curHookId: %d", _track[fadeTrack]->soundId, _track[fadeTrack]->curRegion, _track[fadeTrack]->curHookId);
+			}
+			_track[track]->curRegion = region;
+			debug(5, "switchToNextRegion-sound(%d) jump to %d region, curHookId: %d", _track[track]->soundId, _track[track]->curRegion, _track[track]->curHookId);
 		}
 	}
 
-	int32 msPos = getPosInMs(soundId) + _vm->VAR(_vm->VAR_SYNC) + 50;
-	int32 width = 0, height = 0;
-
-	debug(5, "IMuseDigital::getCurVoiceLipSyncHeight(%d, %d)", soundId, msPos);
-	getLipSync(soundId, syncId, msPos, width, height);
-	return height;
+	debug(5, "switchToNextRegion-sound(%d) select %d region, curHookId: %d", _track[track]->soundId, _track[track]->curRegion, _track[track]->curHookId);
+	_track[track]->dataOffset = _sound->getRegionOffset(_track[track]->soundHandle, _track[track]->curRegion);
+	_track[track]->regionOffset = 0;
 }
 
 } // End of namespace Scumm

Index: dimuse.h
===================================================================
RCS file: /cvsroot/scummvm/scummvm/scumm/imuse_digi/dimuse.h,v
retrieving revision 1.31
retrieving revision 1.31.2.1
diff -u -d -r1.31 -r1.31.2.1
--- dimuse.h	20 Jan 2004 00:21:24 -0000	1.31
+++ dimuse.h	2 May 2004 16:36:04 -0000	1.31.2.1
@@ -27,13 +27,15 @@
 #include "scumm/imuse_digi/dimuse_bndmgr.h"
 #include "scumm/imuse_digi/dimuse_sndmgr.h"
 #include "scumm/music.h"
+#include "scumm/saveload.h"
 
 #include "sound/mixer.h"
 #include "sound/audiostream.h"
 
 namespace Scumm {
 
-#define MAX_DIGITAL_TRACKS 16
+#define MAX_DIGITAL_TRACKS 8
+#define MAX_DIGITAL_FADETRACKS 8
 
 struct imuseDigTable;
 struct imuseComiTable;
@@ -49,21 +51,26 @@
 		int32 volFadeDelay;	//
 		bool volFadeUsed;	//
 
-		int soundId;
+		int32 soundId;
+		char soundName[15];
 		bool used;
 		bool toBeRemoved;
 		bool started;
-		bool waitForEndSeq;
+		bool souStream;
+		int32 priority;
 		int32 regionOffset;
 		int32 trackOffset;
 		int32 dataOffset;
-		bool sequence;
-		int curRegion;
-		int curHookId;
-		int soundGroup;
-		int iteration;
-		int mod;
-		int32 pullSize;
+		int32 curRegion;
+		int32 curHookId;
+		int32 volGroupId;
+		int32 soundType;
+		int32 iteration;
+		int32 mod;
+		int32 mixerFlags;
+		int32 mixerVol;
+		int32 mixerPan;
+
 		ImuseDigiSndMgr::soundStruct *soundHandle;
 		PlayingSoundHandle handle;
 		AppendableAudioStream *stream;
@@ -72,72 +79,83 @@
 		Track();
 	};
 
-	Track _track[MAX_DIGITAL_TRACKS];
+	Track *_track[MAX_DIGITAL_TRACKS + MAX_DIGITAL_FADETRACKS];
 
 	OSystem::MutexRef _mutex;
 	ScummEngine *_vm;
 	ImuseDigiSndMgr *_sound;
-	bool _pause;
 
-	int _attributesTable[11];
-	int _attributesState[97];
-	int _attributesSeq[91];
-	int _curSeqAtribPos;
+	int32 _volVoice;
+	int32 _volSfx;
+	int32 _volMusic;
 
-	int _curMusicState;
-	int _curMusicSeq;
-	int _curMusicCue;
+	bool _pause;
+
+	int32 _attributes[188];
+	int32 _nextSeqToPlay;
+	int32 _curMusicState;
+	int32 _curMusicSeq;
+	int32 _curMusicCue;
 
 	static void timer_handler(void *refConf);
 	void callback();
 	void switchToNextRegion(int track);
-	void startSound(int soundId, const char *soundName, int soundType, int soundGroup, AudioStream *input, bool sequence, int hookId, int volume, bool wait);
+	bool allocSlot(int priority);
+	void startSound(int soundId, const char *soundName, int soundType, int volGroupId, AudioStream *input, int hookId, int volume, int priority);
+	void selectVolumeGroup(int soundId, int volGroupId);
 
 	int32 getPosInMs(int soundId);
 	void getLipSync(int soundId, int syncId, int32 msPos, int32 &width, int32 &height);
 
 	int getSoundIdByName(const char *soundName);
 	void fadeOutMusic(int fadeDelay);
+	int cloneToFadeOutTrack(int track, int fadeDelay, int killNormalTrack);
 
 	void setFtMusicState(int stateId);
 	void setFtMusicSequence(int seqId);
 	void setFtMusicCuePoint(int cueId);
-	void playFtMusic(const char *songName, int opcode, int volume, bool sequence, bool wait);
+	void playFtMusic(const char *songName, int opcode, int volume);
 
 	void setComiMusicState(int stateId);
 	void setComiMusicSequence(int seqId);
-	void playComiMusic(const char *songName, const imuseComiTable *table, int atribPos, bool sequence, bool wait);
+	void playComiMusic(const char *songName, const imuseComiTable *table, int atribPos, bool sequence);
 
 	void setDigMusicState(int stateId);
 	void setDigMusicSequence(int seqId);
-	void playDigMusic(const char *songName, const imuseDigTable *table, int atribPos, bool sequence, bool wait);
+	void playDigMusic(const char *songName, const imuseDigTable *table, int atribPos, bool sequence);
 
 public:
 	IMuseDigital(ScummEngine *scumm);
 	virtual ~IMuseDigital();
 
-	void startVoice(int soundId, AudioStream *input)
-		{ debug(5, "startVoiceStream(%d)", soundId); startSound(soundId, NULL, 0, IMUSE_VOICE, input, false, 0, 127, false); }
-	void startVoice(int soundId, const char *soundName)
-		{ debug(5, "startVoiceBundle(%s)", soundName); startSound(soundId, soundName, IMUSE_BUNDLE, IMUSE_VOICE, NULL, false, 0, 127, false); }
-	void startMusic(int soundId, bool sequence, int volume, bool wait)
-		{ debug(5, "startMusicResource(%d)", soundId); startSound(soundId, NULL, IMUSE_RESOURCE, IMUSE_MUSIC, NULL, sequence, 0, volume, wait); }
-	void startMusic(const char *soundName, int soundId, bool sequence, int hookId, int volume, bool wait)
-		{ debug(5, "startMusicBundle(%s)", soundName); startSound(soundId, soundName, IMUSE_BUNDLE, IMUSE_MUSIC, NULL, sequence, hookId, volume, wait); }
-	void startSfx(int soundId)
-		{ debug(5, "startSfx(%d)", soundId); startSound(soundId, NULL, IMUSE_RESOURCE, IMUSE_SFX, NULL, false, 0, 127, false); }
+	void startVoice(int soundId, AudioStream *input);
+	void startVoice(int soundId, const char *soundName);
+	void startMusic(int soundId, int volume);
+	void startMusic(const char *soundName, int soundId, int hookId, int volume);
+	void startSfx(int soundId, int priority);
 	void startSound(int soundId)
 		{ error("MusicEngine::startSound() Should be never called"); }
 
+	void saveOrLoad(Serializer *ser);
+	void resetState();
+
+	void setGroupVoiceVolume(int volume) { _volVoice = volume; }
+	void setGroupSfxVolume(int volume) { _volSfx = volume; }
+	void setGroupMusicVolume(int volume) { _volMusic = volume; }
+	int getGroupVoiceVolume() { return _volVoice; }
+	int getGroupSfxVolume() { return _volSfx; }
+	int getGroupMusicVolume() { return _volMusic; }
+
+	void setPriority(int soundId, int priority);
 	void setVolume(int soundId, int volume);
 	void setPan(int soundId, int pan);
 	void setFade(int soundId, int destVolume, int delay60HzTicks);
 	void setMasterVolume(int vol) {}
 	void stopSound(int soundId);
-	void stopAllSounds() { stopAllSounds(false); }
-	void stopAllSounds(bool waitForStop);
+	void stopAllSounds();
 	void pause(bool pause);
 	void parseScriptCmds(int a, int b, int c, int d, int e, int f, int g, int h);
+	void refreshScripts();
 	int getSoundStatus(int sound) const;
 	int32 getCurMusicPosInMs();
 	int32 getCurVoiceLipSyncWidth();
@@ -148,18 +166,19 @@
 
 struct imuseRoomMap {
 	int8 roomId;
-	byte musicTableIndex;
-	byte unk1;
-	byte unk2;
-	byte unk3;
-	byte unk4;
+	byte stateIndex1;
+	byte offset;
+	byte stateIndex2;
+	byte atribPos;
+	byte stateIndex3;
 };
 
 struct imuseDigTable {
 	byte opcode;
 	int16 soundId;
 	char name[20];
-	byte param;
+	byte atribPos;
+	byte hookId;
 	char filename[13];
 };
 
@@ -167,9 +186,9 @@
 	byte opcode;
 	int16 soundId;
 	char name[20];
-	byte param;
+	byte atribPos;
 	byte hookId;
-	int16 fadeDelay;
+	int16 fadeOut60TicksDelay;
 	char filename[13];
 };
 



Index: dimuse_music.cpp
===================================================================
RCS file: /cvsroot/scummvm/scummvm/scumm/imuse_digi/dimuse_music.cpp,v
retrieving revision 1.15
retrieving revision 1.15.2.1
diff -u -d -r1.15 -r1.15.2.1
--- dimuse_music.cpp	22 Jan 2004 00:00:31 -0000	1.15
+++ dimuse_music.cpp	2 May 2004 16:36:04 -0000	1.15.2.1
@@ -25,6 +25,10 @@
 
 namespace Scumm {
 
+#define DIG_STATE_OFFSET 11
+#define DIG_SEQ_OFFSET (DIG_STATE_OFFSET + 65)
+#define COMI_STATE_OFFSET 3
+
 void IMuseDigital::setDigMusicState(int stateId) {
 	int l, num = -1;
 
@@ -44,19 +48,19 @@
 		}
 		num = l;
 
-		int val2 = _attributesTable[_digStateMusicMap[num].unk1];
-		if (val2 == 0) {
-			if (_attributesTable[_digStateMusicMap[num].unk3] != 0) {
-				num = _digStateMusicMap[num].unk4;
+		int offset = _attributes[_digStateMusicMap[num].offset];
+		if (offset == 0) {
+			if (_attributes[_digStateMusicMap[num].atribPos] != 0) {
+				num = _digStateMusicMap[num].stateIndex3;
 			} else {
-				num = _digStateMusicMap[num].musicTableIndex;
+				num = _digStateMusicMap[num].stateIndex1;
 			}
 		} else {
-			int val = _attributesTable[_digStateMusicMap[num].unk2];
-			if (val == 0) {
-				num = _digStateMusicMap[num].musicTableIndex + val2;
+			int stateIndex2 = _digStateMusicMap[num].stateIndex2;
+			if (stateIndex2 == 0) {
+				num = _digStateMusicMap[num].stateIndex1 + offset;
 			} else {
-				num = val;
+				num = stateIndex2;
 			}
 		}
 	}
@@ -66,17 +70,11 @@
 	if (_curMusicState == num)
 		return;
 
-	bool wait = false;
-
-	if (_curMusicSeq != 0) {
-		wait = true;
-	}
-
-	if ((_curMusicSeq == 0) || (wait)) {
+	if (_curMusicSeq == 0) {
 		if (num == 0)
-			playDigMusic(NULL, &_digStateMusicTable[num], num, false, wait);
+			playDigMusic(NULL, &_digStateMusicTable[0], num, false);
 		else
-			playDigMusic(_digStateMusicTable[num].name, &_digStateMusicTable[num], num, false, wait);
+			playDigMusic(_digStateMusicTable[num].name, &_digStateMusicTable[num], num, false);
 	}
 
 	_curMusicState = num;
@@ -104,30 +102,30 @@
 
 	if (num != 0) {
 		if (_curMusicSeq == 0) {
-			playDigMusic(_digSeqMusicTable[num].name, &_digSeqMusicTable[num], 0, true, false);
-			_curSeqAtribPos = 0;
-			_attributesSeq[num] = 1;
+			playDigMusic(_digSeqMusicTable[num].name, &_digSeqMusicTable[num], 0, true);
+			_nextSeqToPlay = 0;
+			_attributes[DIG_SEQ_OFFSET + num] = 1;
 		} else {
-			if ((_digSeqMusicTable[_curMusicSeq].opcode == 4) && (_digSeqMusicTable[_curMusicSeq].opcode == 6)) {
-				_curSeqAtribPos = num;
+			if ((_digSeqMusicTable[_curMusicSeq].opcode == 4) || (_digSeqMusicTable[_curMusicSeq].opcode == 6)) {
+				_nextSeqToPlay = num;
 				return;
-			} else if (_digSeqMusicTable[_curMusicSeq].opcode == 6) {
-				playDigMusic(_digSeqMusicTable[num].name, &_digSeqMusicTable[num], 0, true, false);
-				_curSeqAtribPos = 0;
-				_attributesSeq[num] = 1;
+			} else {
+				playDigMusic(_digSeqMusicTable[num].name, &_digSeqMusicTable[num], 0, true);
+				_nextSeqToPlay = 0;
+				_attributes[DIG_SEQ_OFFSET + num] = 1;
 			}
 		}
 	} else {
-		if (_curSeqAtribPos != 0) {
-			playDigMusic(_digSeqMusicTable[_curSeqAtribPos].name, &_digSeqMusicTable[num], 0, true, false);
-			_attributesSeq[_curSeqAtribPos] = 1;
-			_curSeqAtribPos = 0;
-			num = _curSeqAtribPos;
+		if (_nextSeqToPlay != 0) {
+			playDigMusic(_digSeqMusicTable[_nextSeqToPlay].name, &_digSeqMusicTable[_nextSeqToPlay], 0, true);
+			_attributes[DIG_SEQ_OFFSET + _nextSeqToPlay] = 1;
+			num = _nextSeqToPlay;
+			_nextSeqToPlay = 0;
 		} else {
-			if (_curMusicState != 0)
-				playDigMusic(_digStateMusicTable[_curMusicState].name, &_digSeqMusicTable[num], _curMusicState, false, false);
-			else
-				playDigMusic(NULL, &_digStateMusicTable[num], _curMusicState, false, false);
+			if (_curMusicState != 0) {
+				playDigMusic(_digStateMusicTable[_curMusicState].name, &_digStateMusicTable[_curMusicState], _curMusicState, true);
+			} else
+				playDigMusic(NULL, &_digStateMusicTable[0], _curMusicState, true);
 			num = 0;
 		}
 	}
@@ -135,37 +133,41 @@
 	_curMusicSeq = num;
 }
 
-void IMuseDigital::playDigMusic(const char *songName, const imuseDigTable *table, int atribPos, bool sequence, bool wait) {
+void IMuseDigital::playDigMusic(const char *songName, const imuseDigTable *table, int atribPos, bool sequence) {
 	int hookId = 0;
 
 	if (songName != NULL) {
-		if ((_attributesSeq[38] != 0) && (_attributesSeq[41] == _attributesSeq[38])) {
+		if ((_attributes[DIG_SEQ_OFFSET + 38] != 0) && (_attributes[DIG_SEQ_OFFSET + 41] == _attributes[DIG_SEQ_OFFSET + 38])) {
 			if ((atribPos == 43) || (atribPos == 44))
 				hookId = 3;
 		}
 
-		if ((_attributesSeq[46] != 0) && (_attributesSeq[48] == 0)) {
+		if ((_attributes[DIG_SEQ_OFFSET + 46] != 0) && (_attributes[DIG_SEQ_OFFSET + 48] == 0)) {
 			if ((atribPos == 38) || (atribPos == 39))
 				hookId = 3;
 		}
 
-		if ((_attributesSeq[53] != 0)) {
+		if ((_attributes[DIG_SEQ_OFFSET + 53] != 0)) {
 			if ((atribPos == 50) || (atribPos == 51))
 				hookId = 3;
 		}
 
 		if ((atribPos != 0) && (hookId == 0)) {
-			if (table->param != 0)
-				atribPos = table->param;
-			hookId = _attributesSeq[atribPos];
+			if (table->atribPos != 0)
+				atribPos = table->atribPos;
+			hookId = _attributes[DIG_STATE_OFFSET + atribPos];
+			if (table->hookId != 0) {
+				if ((hookId != 0) && (table->hookId <= 1)) {
+					_attributes[DIG_STATE_OFFSET + atribPos] = hookId + 1;
+					if (table->hookId < hookId + 1)
+						_attributes[DIG_STATE_OFFSET + atribPos] = 1;
+				} else {
+					_attributes[DIG_STATE_OFFSET + atribPos] = 2;
+				}
+			}
 		}
 	}
 
-	if (table->filename[0] == 0) {
-		fadeOutMusic(120);
-		return;
-	}
-
 	fadeOutMusic(120);
 
 	switch(table->opcode) {
@@ -174,15 +176,16 @@
 		case 6:
 			break;
 		case 3:
-			if ((!sequence) && (table->param != 0)) {
-				if (table->param == _digStateMusicTable[_curMusicState].param) {
-					startMusic(table->filename, table->soundId, sequence, 0, 127, wait);
-				} 
-			} else {
-				startMusic(table->filename, table->soundId, sequence, hookId, 127, wait);
-			}
 		case 4:
-			startMusic(table->filename, table->soundId, sequence, 0, 127, wait);
+			if (table->filename[0] == 0) {
+				return;
+			}
+			if ((!sequence) && (table->atribPos != 0) &&
+					(table->atribPos == _digStateMusicTable[_curMusicState].atribPos)) {
+				startMusic(table->filename, table->soundId, 0, 127);
+				return;
+			}
+			startMusic(table->filename, table->soundId, hookId, 127);
 			break;
 	}
 }
@@ -205,17 +208,11 @@
 	if (_curMusicState == num)
 		return;
 
-	bool wait = false;
-
-	if (_curMusicSeq != 0) {
-		wait = true;
-	}
-
-	if ((_curMusicSeq == 0) || (wait)) {
+	if (_curMusicSeq == 0) {
 		if (num == 0)
-			playComiMusic(NULL, &_comiStateMusicTable[num], num, false, wait);
+			playComiMusic(NULL, &_comiStateMusicTable[0], num, false);
 		else
-			playComiMusic(_comiStateMusicTable[num].name, &_comiStateMusicTable[num], num, false, wait);
+			playComiMusic(_comiStateMusicTable[num].name, &_comiStateMusicTable[num], num, false);
 	}
 
 	_curMusicState = num;
@@ -241,30 +238,27 @@
 
 	if (num != 0) {
 		if (_curMusicSeq == 0) {
-			playComiMusic(_comiSeqMusicTable[num].name, &_comiSeqMusicTable[num], 0, true, false);
-			_curSeqAtribPos = 0;
-			_attributesSeq[num] = 1;
+			playComiMusic(_comiSeqMusicTable[num].name, &_comiSeqMusicTable[num], 0, true);
+			_nextSeqToPlay = 0;
 		} else {
-			if ((_comiSeqMusicTable[_curMusicSeq].opcode == 4) && (_comiSeqMusicTable[_curMusicSeq].opcode == 6)) {
-				_curSeqAtribPos = num;
+			if ((_comiSeqMusicTable[_curMusicSeq].opcode == 4) || (_comiSeqMusicTable[_curMusicSeq].opcode == 6)) {
+				_nextSeqToPlay = num;
 				return;
-			} else if (_comiSeqMusicTable[_curMusicSeq].opcode == 6) {
-				playComiMusic(_comiSeqMusicTable[num].name, &_comiSeqMusicTable[num], 0, true, false);
-				_curSeqAtribPos = 0;
-				_attributesSeq[num] = 1;
+			} else {
+				playComiMusic(_comiSeqMusicTable[num].name, &_comiSeqMusicTable[num], 0, true);
+				_nextSeqToPlay = 0;
 			}
 		}
 	} else {
-		if (_curSeqAtribPos != 0) {
-			playComiMusic(_comiSeqMusicTable[_curSeqAtribPos].name, &_comiSeqMusicTable[num], 0, true, false);
-			_attributesSeq[_curSeqAtribPos] = 1;
-			_curSeqAtribPos = 0;
-			num = _curSeqAtribPos;
+		if (_nextSeqToPlay != 0) {
+			playComiMusic(_comiSeqMusicTable[_nextSeqToPlay].name, &_comiSeqMusicTable[_nextSeqToPlay], 0, true);
+			num = _nextSeqToPlay;
+			_nextSeqToPlay = 0;
 		} else {
-			if (_curMusicState != 0)
-				playComiMusic(_comiStateMusicTable[_curMusicState].name, &_comiSeqMusicTable[num], _curMusicState, false, false);
-			else
-				playComiMusic(NULL, &_comiStateMusicTable[num], _curMusicState, false, false);
+			if (_curMusicState != 0) {
+				playComiMusic(_comiStateMusicTable[_curMusicState].name, &_comiStateMusicTable[_curMusicState], _curMusicState, true);
+			} else
+				playComiMusic(NULL, &_comiStateMusicTable[0], _curMusicState, true);
 			num = 0;
 		}
 	}
@@ -272,27 +266,24 @@
 	_curMusicSeq = num;
 }
 
-void IMuseDigital::playComiMusic(const char *songName, const imuseComiTable *table, int atribPos, bool sequence, bool wait) {
+void IMuseDigital::playComiMusic(const char *songName, const imuseComiTable *table, int atribPos, bool sequence) {
 	int hookId = 0;
 
 	if ((songName != NULL) && (atribPos != 0)) {
-		hookId = _attributesSeq[atribPos];
+		if (table->atribPos != 0)
+			atribPos = table->atribPos;
+		hookId = _attributes[COMI_STATE_OFFSET + atribPos];
 		if (table->hookId != 0) {
 			if ((hookId != 0) && (table->hookId <= 1)) {
-				_attributesSeq[atribPos] = hookId + 1;
+				_attributes[COMI_STATE_OFFSET + atribPos] = hookId + 1;
 				if (table->hookId < hookId + 1)
-					_attributesSeq[atribPos] = 1;
+					_attributes[COMI_STATE_OFFSET + atribPos] = 1;
 			} else {
-				_attributesSeq[atribPos] = 2;
+				_attributes[COMI_STATE_OFFSET + atribPos] = 2;
 			}
 		}
 	}
 
-	if (table->filename[0] == 0) {
-		fadeOutMusic(120);
-		return;
-	}
-
 	switch(table->opcode) {
 		case 0:
 		case 8:
@@ -300,31 +291,40 @@
 			fadeOutMusic(120);
 			break;
 		case 1:
+			if (table->filename[0] == 0) {
+				fadeOutMusic(120);
+				return;
+			}
 			fadeOutMusic(120);
-			startMusic(table->filename, table->soundId, sequence, 0, 1, wait);
+			startMusic(table->filename, table->soundId, 0, 1);
 			setFade(table->soundId, 127, 120);
 			break;
 		case 2:
-			fadeOutMusic(table->fadeDelay);
-			startMusic(table->filename, table->soundId, sequence, table->hookId, 127, wait);
+			if (table->filename[0] == 0) {
+				fadeOutMusic(60);
+				return;
+			}
+			fadeOutMusic(table->fadeOut60TicksDelay);
+			startMusic(table->filename, table->soundId, table->hookId, 127);
 			break;
 		case 3:
-			if ((!sequence) && (table->param != 0)) {
-				if (table->param == _comiStateMusicTable[_curMusicState].param) {
-					fadeOutMusic(table->fadeDelay);
-					startMusic(table->filename, table->soundId, sequence, 0, 127, wait);
-				} 
-			} else {
-				fadeOutMusic(table->fadeDelay);
-				startMusic(table->filename, table->soundId, sequence, table->hookId, 127, wait);
-			}
 		case 4:
-			fadeOutMusic(120);
-			startMusic(table->filename, table->soundId, sequence, 0, 127, wait);
-			break;
 		case 12:
-			fadeOutMusic(table->fadeDelay);
-			startMusic(table->filename, table->soundId, sequence, table->hookId, 127, wait);
+			if (table->filename[0] == 0) {
+				fadeOutMusic(60);
+				return;
+			}
+			fadeOutMusic(table->fadeOut60TicksDelay);
+			if ((!sequence) && (table->atribPos != 0) &&
+					(table->atribPos == _comiStateMusicTable[_curMusicState].atribPos)) {
+				startMusic(table->filename, table->soundId, 0, 127);
+				return;
+			}
+			if (table->opcode == 12) {
+				startMusic(table->filename, table->soundId, table->hookId, 127);
+			} else {
+				startMusic(table->filename, table->soundId, hookId, 127);
+			}
 			break;
 	}
 }
@@ -338,17 +338,11 @@
 	if (_curMusicState == stateId)
 		return;
 
-	bool wait = false;
-
-	if (_curMusicSeq != 0) {
-		wait = true;
-	}
-
-	if ((_curMusicSeq == 0) || (wait)) {
+	if (_curMusicSeq == 0) {
 		if (stateId == 0)
-			playFtMusic(NULL, 0, 0, false, wait);
+			playFtMusic(NULL, 0, 0);
 		else
-			playFtMusic(_ftStateMusicTable[stateId].audioName, _ftStateMusicTable[stateId].opcode, _ftStateMusicTable[stateId].volume, false, wait);
+			playFtMusic(_ftStateMusicTable[stateId].audioName, _ftStateMusicTable[stateId].opcode, _ftStateMusicTable[stateId].volume);
 	}
 
 	_curMusicState = stateId;
@@ -358,19 +352,20 @@
 	if (seqId > 52)
 		return;
 
-	debug(5, "Sequence music: %s, %s", _ftSeqNames[seqId].name);
+	debug(5, "Sequence music: %s", _ftSeqNames[seqId].name);
 
 	if (_curMusicSeq == seqId)
 		return;
 
 	if (seqId == 0) {
 		if (_curMusicState == 0)
-			playFtMusic(NULL, 0, 0, true, false);
-		else
-			playFtMusic(_ftStateMusicTable[seqId].audioName, _ftStateMusicTable[seqId].opcode, _ftStateMusicTable[seqId].volume, true, false);
+			playFtMusic(NULL, 0, 0);
+		else {
+			playFtMusic(_ftStateMusicTable[_curMusicState].audioName, _ftStateMusicTable[_curMusicState].opcode, _ftStateMusicTable[_curMusicState].volume);
+		}
 	} else {
 		int seq = (seqId - 1) * 4;
-		playFtMusic(_ftSeqMusicTable[seq].audioName, _ftSeqMusicTable[seq].opcode, _ftSeqMusicTable[seq].volume, false, false);
+		playFtMusic(_ftSeqMusicTable[seq].audioName, _ftSeqMusicTable[seq].opcode, _ftSeqMusicTable[seq].volume);
 	}
 
 	_curMusicSeq = seqId;
@@ -390,10 +385,10 @@
 		return;
 
 	if (cueId == 0)
-		playFtMusic(NULL, 0, 0, true, false);
+		playFtMusic(NULL, 0, 0);
 	else {
-		int seq = ((_curMusicSeq - 1) + cueId) * 4;
-		playFtMusic(_ftSeqMusicTable[seq].audioName, _ftSeqMusicTable[seq].opcode, _ftSeqMusicTable[seq].volume, true, false);
+		int seq = ((_curMusicSeq - 1) * 4) + cueId;
+		playFtMusic(_ftSeqMusicTable[seq].audioName, _ftSeqMusicTable[seq].opcode, _ftSeqMusicTable[seq].volume);
 	}
 
 	_curMusicCue = cueId;
@@ -411,7 +406,7 @@
 	return -1;
 }
 
-void IMuseDigital::playFtMusic(const char *songName, int opcode, int volume, bool sequence, bool wait) {
+void IMuseDigital::playFtMusic(const char *songName, int opcode, int volume) {
 	fadeOutMusic(200);
 
 	switch(opcode) {
@@ -423,8 +418,9 @@
 		case 3:
 			{
 				int soundId = getSoundIdByName(songName);
-				if (soundId != -1)
-					startMusic(soundId, sequence, volume, wait);
+				if (soundId != -1) {
+					startMusic(soundId, volume);
+				}
 			}
 			break;
 	}

Index: dimuse_sndmgr.cpp
===================================================================
RCS file: /cvsroot/scummvm/scummvm/scumm/imuse_digi/dimuse_sndmgr.cpp,v
retrieving revision 1.26.2.2
retrieving revision 1.26.2.3
diff -u -d -r1.26.2.2 -r1.26.2.3
--- dimuse_sndmgr.cpp	26 Feb 2004 19:14:20 -0000	1.26.2.2
+++ dimuse_sndmgr.cpp	2 May 2004 16:36:04 -0000	1.26.2.3
@@ -23,6 +23,7 @@
 #include "common/util.h"
 #include "sound/voc.h"
 #include "scumm/scumm.h"
+#include "scumm/imuse_digi/dimuse.h"
 #include "scumm/imuse_digi/dimuse_sndmgr.h"
 #include "scumm/imuse_digi/dimuse_bndmgr.h"
 
@@ -47,38 +48,118 @@
 #endif
 }
 
+void ImuseDigiSndMgr::countElements(byte *ptr, int &numRegions, int &numJumps, int &numSyncs) {
+	uint32 tag;
+	int32 size = 0;
+
+	do {
+		tag = READ_BE_UINT32(ptr); ptr += 4;
+		switch(tag) {
+		case MKID_BE('TEXT'):
+		case MKID_BE('STOP'):
+		case MKID_BE('FRMT'):
+		case MKID_BE('DATA'):
+			size = READ_BE_UINT32(ptr); ptr += size + 4;
+			break;
+		case MKID_BE('REGN'):
+			numRegions++;
+			size = READ_BE_UINT32(ptr); ptr += size + 4;
+			break;
+		case MKID_BE('JUMP'):
+			numJumps++;
+			size = READ_BE_UINT32(ptr); ptr += size + 4;
+			break;
+		case MKID_BE('SYNC'):
+			numSyncs++;
+			size = READ_BE_UINT32(ptr); ptr += size + 4;
+			break;
+		default:
+			error("ImuseDigiSndMgr::countElements() Unknown sfx header '%s'", tag2str(tag));
+		}
+	} while (tag != MKID_BE('DATA'));
+}
+
 void ImuseDigiSndMgr::prepareSound(byte *ptr, int slot) {
 	if (READ_UINT32(ptr) == MKID('Crea')) {
-		int size = 0, rate = 0, loops = 0, begin_loop = 0, end_loop = 0;
-		_sounds[slot].resPtr = readVOCFromMemory(ptr, size, rate, loops, begin_loop, end_loop);
-		_sounds[slot].freeResPtr = true;
+		bool quit = false;
+		int len;
+
+		int32 offset = READ_LE_UINT16(ptr + 20);
+		int16 code = READ_LE_UINT16(ptr + 24);
+
+		_sounds[slot].region = (_region *)malloc(sizeof(_region) * 70);
+		_sounds[slot].jump = (_jump *)malloc(sizeof(_jump));
+		_sounds[slot].resPtr = ptr;
+		_vm->lock(rtSound, _sounds[slot].soundId);
 		_sounds[slot].bits = 8;
-		_sounds[slot].freq = rate;
 		_sounds[slot].channels = 1;
-		_sounds[slot].region[0].offset = 0;
-		_sounds[slot].region[0].length = size;
-		_sounds[slot].numRegions++;
-		if (loops != 0) {
-			if (begin_loop == 0) {
-				_sounds[slot].region[1].offset = end_loop;
+
+		while (!quit) {
+			len = READ_LE_UINT32(ptr + offset);
+			code = len & 0xFF;
+			if ((code != 0) && (code != 1) && (code != 6) && (code != 7)) {
+				// try again with 2 bytes forward (workaround for some FT sounds (ex.362, 363)
+				offset += 2;
+				len = READ_LE_UINT32(ptr + offset);
+				code = len & 0xFF;
+				if ((code != 0) && (code != 1) && (code != 6) && (code != 7)) {
+					error("Invalid code in VOC file : %d", code);
+				}
+			}
+			offset += 4;
+			len >>= 8;
+			switch(code) {
+			case 0:
+				quit = true;
+				break;
+			case 1:
+				{
+					int time_constant = ptr[offset];
+					offset += 2;
+					len -= 2;
+					_sounds[slot].freq = getSampleRateFromVOCRate(time_constant);
+					_sounds[slot].region[_sounds[slot].numRegions].offset = offset;
+					_sounds[slot].region[_sounds[slot].numRegions].length = len;
+					_sounds[slot].numRegions++;
+				}
+				break;
+			case 6:	// begin of loop
+				_sounds[slot].jump[0].dest = offset + 8;
+				_sounds[slot].jump[0].hookId = 0;
+				_sounds[slot].jump[0].fadeDelay = 0;
+				break;
+			case 7:	// end of loop
+				_sounds[slot].jump[0].offset = offset - 4;
+				_sounds[slot].numJumps++;
+				_sounds[slot].region[_sounds[slot].numRegions].offset = offset - 4;
+				_sounds[slot].region[_sounds[slot].numRegions].length = 0;
 				_sounds[slot].numRegions++;
-			} else {
-				_sounds[slot].region[0].length = begin_loop;
-				_sounds[slot].region[1].offset = begin_loop;
-				_sounds[slot].region[1].length = end_loop - begin_loop;
-				_sounds[slot].region[2].offset = end_loop;
-				_sounds[slot].numRegions += 2;
+				break;
+			default:
+				error("Invalid code in VOC file : %d", code);
+				quit = true;
+				break;
 			}
-			_sounds[slot].jump[0].dest = begin_loop;
-			_sounds[slot].jump[0].offset = end_loop;
-			_sounds[slot].numJumps++;
+			offset += len;
 		}
 	} else if (READ_UINT32(ptr) == MKID('iMUS')) {
 		uint32 tag;
 		int32 size = 0;
 		byte *s_ptr = ptr;
-
 		ptr += 16;
+
+		int curIndexRegion = 0;
+		int curIndexJump = 0;
+		int curIndexSync = 0;
+
+		_sounds[slot].numRegions = 0;
+		_sounds[slot].numJumps = 0;
+		_sounds[slot].numSyncs = 0;
+		countElements(ptr, _sounds[slot].numRegions, _sounds[slot].numJumps, _sounds[slot].numSyncs);
+		_sounds[slot].region = (_region *)malloc(sizeof(_region) * _sounds[slot].numRegions);
+		_sounds[slot].jump = (_jump *)malloc(sizeof(_jump) * _sounds[slot].numJumps);
+		_sounds[slot].sync = (_sync *)malloc(sizeof(_sync) * _sounds[slot].numSyncs);
+
 		do {
 			tag = READ_BE_UINT32(ptr); ptr += 4;
 			switch(tag) {
@@ -87,57 +168,35 @@
 				_sounds[slot].bits = READ_BE_UINT32(ptr); ptr += 4;
 				_sounds[slot].freq = READ_BE_UINT32(ptr); ptr += 4;
 				_sounds[slot].channels = READ_BE_UINT32(ptr); ptr += 4;
-			break;
+				break;
 			case MKID_BE('TEXT'):
+			case MKID_BE('STOP'):
 				size = READ_BE_UINT32(ptr); ptr += size + 4;
 				break;
 			case MKID_BE('REGN'):
-				size = READ_BE_UINT32(ptr); ptr += 4;
-				if (_sounds[slot].numRegions >= MAX_IMUSE_REGIONS) {
-					warning("ImuseDigiSndMgr::prepareSound(%d/%s) Not enough space for Region", _sounds[slot].soundId, _sounds[slot].name);
-					ptr += 8;
-					break;
-				}
-				_sounds[slot].region[_sounds[slot].numRegions].offset = READ_BE_UINT32(ptr); ptr += 4;
-				_sounds[slot].region[_sounds[slot].numRegions].length = READ_BE_UINT32(ptr); ptr += 4;
-//				if (_sounds[slot].soundId == 2311)
-//					printf("REGN: offset: %d, length: %d\n", _sounds[slot].region[_sounds[slot].numRegions].offset, _sounds[slot].region[_sounds[slot].numRegions].length);
-				_sounds[slot].numRegions++;
-				break;
-			case MKID_BE('STOP'):
 				ptr += 4;
-				_sounds[slot].offsetStop = READ_BE_UINT32(ptr); ptr += 4;
+				_sounds[slot].region[curIndexRegion].offset = READ_BE_UINT32(ptr); ptr += 4;
+				_sounds[slot].region[curIndexRegion].length = READ_BE_UINT32(ptr); ptr += 4;
+				curIndexRegion++;
 				break;
 			case MKID_BE('JUMP'):
-				size = READ_BE_UINT32(ptr); ptr += 4;
-				if (_sounds[slot].numJumps >= MAX_IMUSE_JUMPS) {
-					warning("ImuseDigiSndMgr::prepareSound(%d/%s) Not enough space for Jump", _sounds[slot].soundId, _sounds[slot].name);
-					ptr += size;
-					break;
-				}
-				_sounds[slot].jump[_sounds[slot].numJumps].offset = READ_BE_UINT32(ptr); ptr += 4;
-				_sounds[slot].jump[_sounds[slot].numJumps].dest = READ_BE_UINT32(ptr); ptr += 4;
-				_sounds[slot].jump[_sounds[slot].numJumps].hookId = READ_BE_UINT32(ptr); ptr += 4;
-				_sounds[slot].jump[_sounds[slot].numJumps].fadeDelay = READ_BE_UINT32(ptr); ptr += 4;
-//				if (_sounds[slot].soundId == 2311)
-//					printf("JUMP: offset: %d, dest: %d, hookId: %d\n",  _sounds[slot].jump[_sounds[slot].numJumps].offset, _sounds[slot].jump[_sounds[slot].numJumps].dest, _sounds[slot].jump[_sounds[slot].numJumps].hookId);
-				_sounds[slot].numJumps++;
+				ptr += 4;
+				_sounds[slot].jump[curIndexJump].offset = READ_BE_UINT32(ptr); ptr += 4;
+				_sounds[slot].jump[curIndexJump].dest = READ_BE_UINT32(ptr); ptr += 4;
+				_sounds[slot].jump[curIndexJump].hookId = READ_BE_UINT32(ptr); ptr += 4;
+				_sounds[slot].jump[curIndexJump].fadeDelay = READ_BE_UINT32(ptr); ptr += 4;
+				curIndexJump++;
 				break;
 			case MKID_BE('SYNC'):
 				size = READ_BE_UINT32(ptr); ptr += 4;
-				if (_sounds[slot].numSyncs >= MAX_IMUSE_SYNCS) {
-					warning("ImuseDigiSndMgr::prepareSound(%d/%s) Not enough space for Sync", _sounds[slot].soundId, _sounds[slot].name);
-					ptr += size;
-					break;
-				}
-				_sounds[slot].sync[_sounds[slot].numSyncs].size = size;
-				_sounds[slot].sync[_sounds[slot].numSyncs].ptr = (byte *)malloc(size);
-				memcpy(_sounds[slot].sync[_sounds[slot].numSyncs].ptr, ptr, size);
-				_sounds[slot].numSyncs++;
+				_sounds[slot].sync[curIndexSync].size = size;
+				_sounds[slot].sync[curIndexSync].ptr = (byte *)malloc(size);
+				memcpy(_sounds[slot].sync[curIndexSync].ptr, ptr, size);
+				curIndexSync++;
 				ptr += size;
 				break;
 			case MKID_BE('DATA'):
-				size = READ_BE_UINT32(ptr); ptr += 4;
+				ptr += 4;
 				break;
 			default:
 				error("ImuseDigiSndMgr::prepareSound(%d/%s) Unknown sfx header '%s'", _sounds[slot].soundId, _sounds[slot].name, tag2str(tag));
@@ -163,24 +222,28 @@
 bool ImuseDigiSndMgr::openMusicBundle(int slot) {
 	bool result = false;
 
-	_sounds[slot]._bundle = new BundleMgr(_cacheBundleDir);
+	_sounds[slot].bundle = new BundleMgr(_cacheBundleDir);
 	if (_vm->_gameId == GID_CMI) {
 		if (_vm->_features & GF_DEMO) {
-			result = _sounds[slot]._bundle->openFile("music.bun", _vm->getGameDataPath());
+			result = _sounds[slot].bundle->openFile("music.bun", _vm->getGameDataPath());
 		} else {
 			char musicfile[20];
 			sprintf(musicfile, "musdisk%d.bun", _vm->VAR(_vm->VAR_CURRENTDISK));
-			if (_disk != _vm->VAR(_vm->VAR_CURRENTDISK))
-				_sounds[slot]._bundle->closeFile();
+			if (_disk != _vm->VAR(_vm->VAR_CURRENTDISK)) {
+//				_vm->_imuseDigital->parseScriptCmds(0x1000, 0, 0, 0, 0, 0, 0, 0);
+//				_vm->_imuseDigital->parseScriptCmds(0x2000, 0, 0, 0, 0, 0, 0, 0);
+//				_vm->_imuseDigital->stopAllSounds();
+				_sounds[slot].bundle->closeFile();
+			}
 
-			result = _sounds[slot]._bundle->openFile(musicfile, _vm->getGameDataPath());
+			result = _sounds[slot].bundle->openFile(musicfile, _vm->getGameDataPath());
 
 			if (result == false)
-				result = _sounds[slot]._bundle->openFile("music.bun", _vm->getGameDataPath());
+				result = _sounds[slot].bundle->openFile("music.bun", _vm->getGameDataPath());
 			_disk = (byte)_vm->VAR(_vm->VAR_CURRENTDISK);
 		}
 	} else if (_vm->_gameId == GID_DIG)
-		result = _sounds[slot]._bundle->openFile("digmusic.bun", _vm->getGameDataPath());
+		result = _sounds[slot].bundle->openFile("digmusic.bun", _vm->getGameDataPath());
 	else
 		error("ImuseDigiSndMgr::openMusicBundle() Don't know which bundle file to load");
 
@@ -190,44 +253,48 @@
 bool ImuseDigiSndMgr::openVoiceBundle(int slot) {
 	bool result = false;
 
-	_sounds[slot]._bundle = new BundleMgr(_cacheBundleDir);
+	_sounds[slot].bundle = new BundleMgr(_cacheBundleDir);
 	if (_vm->_gameId == GID_CMI) {
 		if (_vm->_features & GF_DEMO) {
-			result = _sounds[slot]._bundle->openFile("voice.bun", _vm->getGameDataPath());
+			result = _sounds[slot].bundle->openFile("voice.bun", _vm->getGameDataPath());
 		} else {
 			char voxfile[20];
 			sprintf(voxfile, "voxdisk%d.bun", _vm->VAR(_vm->VAR_CURRENTDISK));
-			if (_disk != _vm->VAR(_vm->VAR_CURRENTDISK))
-				_sounds[slot]._bundle->closeFile();
+			if (_disk != _vm->VAR(_vm->VAR_CURRENTDISK)) {
+//				_vm->_imuseDigital->parseScriptCmds(0x1000, 0, 0, 0, 0, 0, 0, 0);
+//				_vm->_imuseDigital->parseScriptCmds(0x2000, 0, 0, 0, 0, 0, 0, 0);
+//				_vm->_imuseDigital->stopAllSounds();
+				_sounds[slot].bundle->closeFile();
+			}
 
-			result = _sounds[slot]._bundle->openFile(voxfile, _vm->getGameDataPath());
+			result = _sounds[slot].bundle->openFile(voxfile, _vm->getGameDataPath());
 
 			if (result == false)
-				result = _sounds[slot]._bundle->openFile("voice.bun", _vm->getGameDataPath());
+				result = _sounds[slot].bundle->openFile("voice.bun", _vm->getGameDataPath());
 			_disk = (byte)_vm->VAR(_vm->VAR_CURRENTDISK);
 		}
 	} else if (_vm->_gameId == GID_DIG)
-		result = _sounds[slot]._bundle->openFile("digvoice.bun", _vm->getGameDataPath());
+		result = _sounds[slot].bundle->openFile("digvoice.bun", _vm->getGameDataPath());
 	else
 		error("ImuseDigiSndMgr::openVoiceBundle() Don't know which bundle file to load");
 
 	return result;
 }
 
-ImuseDigiSndMgr::soundStruct *ImuseDigiSndMgr::openSound(int32 soundId, const char *soundName, int soundType, int soundGroup) {
+ImuseDigiSndMgr::soundStruct *ImuseDigiSndMgr::openSound(int32 soundId, const char *soundName, int soundType, int volGroupId) {
 	assert(soundId >= 0);
 	assert(soundType);
 
 	int slot = allocSlot();
 	if (slot == -1) {
-		warning("ImuseDigiSndMgr::openSound() can't alloc free sound slot");
-		return NULL;
+		error("ImuseDigiSndMgr::openSound() can't alloc free sound slot");
 	}
 
 	bool result = false;
 	byte *ptr = NULL;
 
-	if (soundName == NULL) {
+	if (soundName[0] == 0) {
+		_sounds[slot].name[0] = 0;
 		if ((soundType == IMUSE_RESOURCE)) {
 			ptr = _vm->getResourceAddress(rtSound, soundId);
 			if (ptr == NULL) {
@@ -235,33 +302,47 @@
 				return NULL;
 			}
 			_sounds[slot].resPtr = ptr;
+			_sounds[slot].soundId = soundId;
+			_sounds[slot].type = soundType;
+			_sounds[slot].volGroupId = volGroupId;
 			result = true;
 		} else if (soundType == IMUSE_BUNDLE) {
 			bool header_outside = ((_vm->_gameId == GID_CMI) && !(_vm->_features & GF_DEMO));
-			if (soundGroup == IMUSE_VOICE)
+			if (volGroupId == IMUSE_VOLGRP_VOICE)
 				result = openVoiceBundle(slot);
-			else if (soundGroup == IMUSE_MUSIC)
+			else if (volGroupId == IMUSE_VOLGRP_MUSIC)
 				result = openMusicBundle(slot);
-			else 
+			else
 				error("ImuseDigiSndMgr::openSound() Don't know how load sound: %d", soundId);
-			_sounds[slot]._bundle->decompressSampleByIndex(soundId, 0, 0x2000, &ptr, 0, header_outside);
-			_sounds[slot].name[0] = 0;
+			if (!result) {
+				closeSound(&_sounds[slot]);
+				return NULL;
+			}
+			_sounds[slot].bundle->decompressSampleByIndex(soundId, 0, 0x2000, &ptr, 0, header_outside);
 			_sounds[slot].soundId = soundId;
+			_sounds[slot].type = soundType;
+			_sounds[slot].volGroupId = volGroupId;
 		} else {
 			error("ImuseDigiSndMgr::openSound() Don't know how load sound: %d", soundId);
 		}
 	} else {
 		if (soundType == IMUSE_BUNDLE) {
 			bool header_outside = ((_vm->_gameId == GID_CMI) && !(_vm->_features & GF_DEMO));
-			if (soundGroup == IMUSE_VOICE)
+			if (volGroupId == IMUSE_VOLGRP_VOICE)
 				result = openVoiceBundle(slot);
-			else if (soundGroup == IMUSE_MUSIC)
+			else if (volGroupId == IMUSE_VOLGRP_MUSIC)
 				result = openMusicBundle(slot);
 			else
 				error("ImuseDigiSndMgr::openSound() Don't know how load sound: %d", soundId);
-			_sounds[slot]._bundle->decompressSampleByName(soundName, 0, 0x2000, &ptr, header_outside);
+			if (!result) {
+				closeSound(&_sounds[slot]);
+				return NULL;
+			}
+			_sounds[slot].bundle->decompressSampleByName(soundName, 0, 0x2000, &ptr, header_outside);
 			strcpy(_sounds[slot].name, soundName);
 			_sounds[slot].soundId = soundId;
+			_sounds[slot].type = soundType;
+			_sounds[slot].volGroupId = volGroupId;
 		} else {
 			error("ImuseDigiSndMgr::openSound() Don't know how load sound: %s", soundName);
 		}
@@ -282,18 +363,22 @@
 void ImuseDigiSndMgr::closeSound(soundStruct *soundHandle) {
 	assert(soundHandle && checkForProperHandle(soundHandle));
 
-	for (int l = 0; l < MAX_IMUSE_SOUNDS; l++) {
-		if (&_sounds[l] == soundHandle) {
-			if (_sounds[l].freeResPtr)
-				free(_sounds[l].resPtr);
-			if (_sounds[l]._bundle)
-				delete _sounds[l]._bundle;
-			for (int r = 0; r < _sounds[l].numSyncs; r++)
-				if (_sounds[l].sync[r].ptr)
-					free(_sounds[l].sync[r].ptr);
-			memset(&_sounds[l], 0, sizeof(soundStruct));
-		}
-	}
+	if (soundHandle->resPtr)
+		_vm->unlock(rtSound, soundHandle->soundId);
+
+	delete soundHandle->bundle;
+	for (int r = 0; r < soundHandle->numSyncs; r++)
+		free(soundHandle->sync[r].ptr);
+	free(soundHandle->region);
+	free(soundHandle->jump);
+	free(soundHandle->sync);
+	memset(soundHandle, 0, sizeof(soundStruct));
+}
+
+ImuseDigiSndMgr::soundStruct *ImuseDigiSndMgr::cloneSound(soundStruct *soundHandle) {
+	assert(soundHandle && checkForProperHandle(soundHandle));
+
+	return openSound(soundHandle->soundId, soundHandle->name, soundHandle->type, soundHandle->volGroupId);
 }
 
 bool ImuseDigiSndMgr::checkForProperHandle(soundStruct *soundHandle) {
@@ -336,12 +421,14 @@
 }
 
 int ImuseDigiSndMgr::getRegionOffset(soundStruct *soundHandle, int region) {
+	debug(5, "getRegionOffset() region:%d");
 	assert(soundHandle && checkForProperHandle(soundHandle));
 	assert(region >= 0 && region < soundHandle->numRegions);
 	return soundHandle->region[region].offset;
 }
 
 int ImuseDigiSndMgr::getJumpIdByRegionAndHookId(soundStruct *soundHandle, int region, int hookId) {
+	debug(5, "getJumpIdByRegionAndHookId() region:%d, hookId:%d", region, hookId);
 	assert(soundHandle && checkForProperHandle(soundHandle));
 	assert(region >= 0 && region < soundHandle->numRegions);
 	for (int l = 0; l < soundHandle->numJumps; l++) {
@@ -367,6 +454,7 @@
 }
 
 int ImuseDigiSndMgr::getRegionIdByJumpId(soundStruct *soundHandle, int jumpId) {
+	debug(5, "getRegionIdByJumpId() jumpId:%d", jumpId);
 	assert(soundHandle && checkForProperHandle(soundHandle));
 	assert(jumpId >= 0 && jumpId < soundHandle->numJumps);
 	for (int l = 0; l < soundHandle->numRegions; l++) {
@@ -379,18 +467,21 @@
 }
 
 int ImuseDigiSndMgr::getJumpHookId(soundStruct *soundHandle, int number) {
+	debug(5, "getJumpHookId() number:%d", number);
 	assert(soundHandle && checkForProperHandle(soundHandle));
 	assert(number >= 0 && number < soundHandle->numJumps);
 	return soundHandle->jump[number].hookId;
 }
 
 int ImuseDigiSndMgr::getJumpFade(soundStruct *soundHandle, int number) {
+	debug(5, "getJumpFade() number:%d", number);
 	assert(soundHandle && checkForProperHandle(soundHandle));
 	assert(number >= 0 && number < soundHandle->numJumps);
 	return soundHandle->jump[number].fadeDelay;
 }
 
 int32 ImuseDigiSndMgr::getDataFromRegion(soundStruct *soundHandle, int region, byte **buf, int32 offset, int32 size) {
+	debug(5, "getDataFromRegion() region:%d, offset:%d, size:%d, numRegions:%d", region, offset, size, soundHandle->numRegions);
 	assert(soundHandle && checkForProperHandle(soundHandle));
 	assert(buf && offset >= 0 && size >= 0);
 	assert(region >= 0 && region < soundHandle->numRegions);
@@ -409,8 +500,8 @@
 
 	int header_size = soundHandle->offsetData;
 	bool header_outside = ((_vm->_gameId == GID_CMI) && !(_vm->_features & GF_DEMO));
-	if (soundHandle->_bundle) {
-		size = soundHandle->_bundle->decompressSampleByCurIndex(start + offset, size, buf, header_size, header_outside);
+	if (soundHandle->bundle) {
+		size = soundHandle->bundle->decompressSampleByCurIndex(start + offset, size, buf, header_size, header_outside);
 	} else if (soundHandle->resPtr) {
 		*buf = (byte *)malloc(size);
 		memcpy(*buf, soundHandle->resPtr + start + offset + header_size, size);

Index: dimuse_sndmgr.h
===================================================================
RCS file: /cvsroot/scummvm/scummvm/scumm/imuse_digi/dimuse_sndmgr.h,v
retrieving revision 1.19
retrieving revision 1.19.2.1
diff -u -d -r1.19 -r1.19.2.1
--- dimuse_sndmgr.h	22 Jan 2004 19:43:36 -0000	1.19
+++ dimuse_sndmgr.h	2 May 2004 16:36:04 -0000	1.19.2.1
@@ -34,16 +34,14 @@
 class ImuseDigiSndMgr {
 public:
 
-#define MAX_IMUSE_SOUNDS 16
-#define MAX_IMUSE_JUMPS 80
-#define MAX_IMUSE_REGIONS 85
-#define MAX_IMUSE_SYNCS 4
+#define MAX_IMUSE_SOUNDS 10
 
 #define IMUSE_RESOURCE 1
 #define IMUSE_BUNDLE 2
-#define IMUSE_VOICE 1
-#define IMUSE_SFX 2
-#define IMUSE_MUSIC 3
+
+#define IMUSE_VOLGRP_VOICE 1
+#define IMUSE_VOLGRP_SFX 2
+#define IMUSE_VOLGRP_MUSIC 3
 
 private:
 	struct _region {
@@ -54,25 +52,27 @@
 	struct _jump {
 		int32 offset;		// jump offset position
 		int32 dest;			// jump to dest position
-		byte hookId;			// id of hook
-		int16 fadeDelay;		// fade delay in ms
+		byte hookId;		// id of hook
+		int16 fadeDelay;	// fade delay in ms
 	};
 
 	struct _sync {
-		int32 size;		// size of sync
-		byte *ptr;		// pointer to sync
+		int32 size;			// size of sync
+		byte *ptr;			// pointer to sync
 	};
 	
 public:
 
 	struct soundStruct {
-		uint16 freq;			// frequency
+		uint16 freq;		// frequency
 		byte channels;		// stereo or mono
 		byte bits;			// 8, 12, 16
-		int8 numJumps;		// number of Jumps
-		int8 numRegions;		// number of Regions
-		int8 numSyncs;		// number of Syncs
-		int32 offsetStop;	// end offset in source data
+		int numJumps;		// number of Jumps
+		int numRegions;		// number of Regions
+		int numSyncs;		// number of Syncs
+		_region *region;
+		_jump *jump;
+		_sync *sync;
 		bool endFlag;
 		bool inUse;
 		byte *allData;
@@ -80,11 +80,9 @@
 		byte *resPtr;
 		char name[15];
 		int16 soundId;
-		bool freeResPtr;
-		BundleMgr *_bundle;
-		_region region[MAX_IMUSE_REGIONS];
-		_jump jump[MAX_IMUSE_JUMPS];
-		_sync sync[MAX_IMUSE_SYNCS];
+		BundleMgr *bundle;
+		int type;
+		int volGroupId;
 	};
 
 private:
@@ -102,13 +100,16 @@
 	bool openMusicBundle(int slot);
 	bool openVoiceBundle(int slot);
 
+	void countElements(byte *ptr, int &numRegions, int &numJumps, int &numSyncs);
+
 public:
 
 	ImuseDigiSndMgr(ScummEngine *scumm);
 	~ImuseDigiSndMgr();
-	
-	soundStruct * openSound(int32 soundId, const char *soundName, int soundType, int soundGroup);
+
+	soundStruct *openSound(int32 soundId, const char *soundName, int soundType, int volGroupId);
 	void closeSound(soundStruct *soundHandle);
+	soundStruct *cloneSound(soundStruct *soundHandle);
 
 	int getFreq(soundStruct *soundHandle);
 	int getBits(soundStruct *soundHandle);

Index: dimuse_tables.cpp
===================================================================
RCS file: /cvsroot/scummvm/scummvm/scumm/imuse_digi/dimuse_tables.cpp,v
retrieving revision 1.14
retrieving revision 1.14.2.1
diff -u -d -r1.14 -r1.14.2.1
--- dimuse_tables.cpp	18 Jan 2004 19:42:55 -0000	1.14
+++ dimuse_tables.cpp	2 May 2004 16:36:04 -0000	1.14.2.1
@@ -152,331 +152,331 @@
 };
 
 const imuseDigTable _digStateMusicTable[] = {
-	{0, 1000, "STATE_NULL",          0, ""},
-	{0, 1001, "stateNoChange",       0, ""},
-	{3, 1100, "stateAstShip",        2, "ASTERO~1.IMU"},
-	{3, 1120, "stateAstClose",       2, "ASTERO~2.IMU"},
-	{3, 1140, "stateAstInside",      0, "ASTERO~3.IMU"},
-	{3, 1150, "stateAstCore",        0, "ASTERO~4.IMU"},
-	{3, 1200, "stateCanyonClose",    0, "CANYON~1.IMU"},
-	{3, 1205, "stateCanyonClose_m",  0, "CANYON~2.IMU"},
-	{3, 1210, "stateCanyonOver",     0, "CANYON~3.IMU"},
-	{3, 1220, "stateCanyonWreck",    0, "CANYON~4.IMU"},
-	{3, 1300, "stateNexusCanyon",   10, "NEXUS(~1.IMU"},
-	{3, 1310, "stateNexusPlan",     10, "NEXUS(~1.IMU"},
-	{3, 1320, "stateNexusRamp",     10, "NEXUS(~2.IMU"},
-	{3, 1330, "stateNexusMuseum",   10, "NEXUS(~3.IMU"},
-	{3, 1340, "stateNexusMap",      10, "NEXUS(~4.IMU"},
-	{3, 1350, "stateNexusTomb",     10, "NE3706~5.IMU"},
-	{3, 1360, "stateNexusCath",     10, "NE3305~5.IMU"},
-	{3, 1370, "stateNexusAirlock",   0, "NE2D3A~5.IMU"},
-	{3, 1380, "stateNexusPowerOff",  0, "NE8522~5.IMU"},
-	{3, 1400, "stateMuseumTramNear", 0, "TRAM(M~1.IMU"},
-	{3, 1410, "stateMuseumTramFar",  0, "TRAM(M~2.IMU"},
-	{3, 1420, "stateMuseumLockup",   0, "MUSEUM~1.IMU"},
-	{3, 1433, "stateMuseumPool",    22, "MUSEUM~2.IMU"},
-	{3, 1436, "stateMuseumSpire",   22, "MUSEUM~3.IMU"},
-	{3, 1440, "stateMuseumMuseum",  22, "MUSEUM~4.IMU"},
-	{3, 1450, "stateMuseumLibrary",  0, "MUB575~5.IMU"},
-	{3, 1460, "stateMuseumCavern",   0, "MUF9BE~5.IMU"},
-	{3, 1500, "stateTombTramNear",   0, "TRAM(T~1.IMU"},
-	{3, 1510, "stateTombBase",      28, "TOMB(A~1.IMU"},
-	{3, 1520, "stateTombSpire",     28, "TOMB(A~2.IMU"},
-	{3, 1530, "stateTombCave",      28, "TOMB(A~3.IMU"},
-	{3, 1540, "stateTombCrypt",     31, "TOMB(C~1.IMU"},
-	{3, 1550, "stateTombGuards",    31, "TOMB(C~2.IMU"},
-	{3, 1560, "stateTombInner",      0, "TOMB(I~1.IMU"},
-	{3, 1570, "stateTombCreator1",   0, "TOMB(C~3.IMU"},
-	{3, 1580, "stateTombCreator2",   0, "TOMB(C~4.IMU"},
-	{3, 1600, "statePlanTramNear",   0, "TRAM(P~1.IMU"},
-	{3, 1610, "statePlanTramFar",    0, "TRAM(P~2.IMU"},
-	{3, 1620, "statePlanBase",      38, "PLAN(A~1.IMU"},
-	{3, 1630, "statePlanSpire",     38, "PLAN(A~2.IMU"},
-	{3, 1650, "statePlanDome",       0, "PLAN(D~1.IMU"},
-	{3, 1700, "stateMapTramNear",    0, "TRAM(M~3.IMU"},
-	{3, 1710, "stateMapTramFar",     0, "TRAM(M~4.IMU"},
-	{3, 1720, "stateMapCanyon",     43, "MAP(AM~1.IMU"},
-	{3, 1730, "stateMapExposed",    43, "MAP(AM~2.IMU"},
-	{3, 1750, "stateMapNestEmpty",  43, "MAP(AM~4.IMU"},
-	{3, 1760, "stateMapNestMonster", 0, "MAP(MO~1.IMU"},
-	{3, 1770, "stateMapKlein",       0, "MAP(KL~1.IMU"},
-	{3, 1800, "stateCathTramNear",   0, "TRAM(C~1.IMU"},
-	{3, 1810, "stateCathTramFar",    0, "TRAM(C~2.IMU"},
-	{3, 1820, "stateCathLab",       50, "CATH(A~1.IMU"},
-	{3, 1830, "stateCathOutside",   50, "CATH(A~2.IMU"},
-	{3, 1900, "stateWorldMuseum",   52, "WORLD(~1.IMU"},
-	{3, 1901, "stateWorldPlan",     52, "WORLD(~2.IMU"},
-	{3, 1902, "stateWorldTomb",     52, "WORLD(~3.IMU"},
-	{3, 1903, "stateWorldMap",      52, "WORLD(~4.IMU"},
-	{3, 1904, "stateWorldCath",     52, "WO3227~5.IMU"},
-	{3, 1910, "stateEye1",           0, "EYE1~1.IMU"},
-	{3, 1911, "stateEye2",           0, "EYE2~1.IMU"},
-	{3, 1912, "stateEye3",           0, "EYE3~1.IMU"},
-	{3, 1913, "stateEye4",           0, "EYE4~1.IMU"},
-	{3, 1914, "stateEye5",           0, "EYE5~1.IMU"},
-	{3, 1915, "stateEye6",           0, "EYE6~1.IMU"},
-	{3, 1916, "stateEye7",           0, "EYE7~1.IMU"},
-	{0,   -1,  "",                   0, ""}
+	{0, 1000, "STATE_NULL",          0, 0, ""},             /* 00 */
+	{0, 1001, "stateNoChange",       0, 0, ""},	            /* 01 */
+	{3, 1100, "stateAstShip",        2, 0, "ASTERO~1.IMU"}, /* 02 */
+	{3, 1120, "stateAstClose",       2, 0, "ASTERO~2.IMU"}, /* 03 */
+	{3, 1140, "stateAstInside",      0, 0, "ASTERO~3.IMU"}, /* 04 */
+	{3, 1150, "stateAstCore",        0, 2, "ASTERO~4.IMU"}, /* 05 */
+	{3, 1200, "stateCanyonClose",    0, 1, "CANYON~1.IMU"}, /* 06 */
+	{3, 1205, "stateCanyonClose_m",  0, 0, "CANYON~2.IMU"}, /* 07 */
+	{3, 1210, "stateCanyonOver",     0, 1, "CANYON~3.IMU"}, /* 08 */
+	{3, 1220, "stateCanyonWreck",    0, 1, "CANYON~4.IMU"}, /* 09 */
+	{3, 1300, "stateNexusCanyon",   10, 0, "NEXUS(~1.IMU"}, /* 10 */
+	{3, 1310, "stateNexusPlan",     10, 0, "NEXUS(~1.IMU"}, /* 11 */
+	{3, 1320, "stateNexusRamp",     10, 0, "NEXUS(~2.IMU"}, /* 12 */
+	{3, 1330, "stateNexusMuseum",   10, 0, "NEXUS(~3.IMU"}, /* 13 */
+	{3, 1340, "stateNexusMap",      10, 0, "NEXUS(~4.IMU"}, /* 14 */
+	{3, 1350, "stateNexusTomb",     10, 0, "NE3706~5.IMU"}, /* 15 */
+	{3, 1360, "stateNexusCath",     10, 0, "NE3305~5.IMU"}, /* 16 */
+	{3, 1370, "stateNexusAirlock",   0, 0, "NE2D3A~5.IMU"}, /* 17 */
+	{3, 1380, "stateNexusPowerOff",  0, 1, "NE8522~5.IMU"}, /* 18 */
+	{3, 1400, "stateMuseumTramNear", 0, 1, "TRAM(M~1.IMU"}, /* 19 */
+	{3, 1410, "stateMuseumTramFar",  0, 0, "TRAM(M~2.IMU"}, /* 20 */
+	{3, 1420, "stateMuseumLockup",   0, 0, "MUSEUM~1.IMU"}, /* 21 */
+	{3, 1433, "stateMuseumPool",    22, 1, "MUSEUM~2.IMU"}, /* 22 */
+	{3, 1436, "stateMuseumSpire",   22, 2, "MUSEUM~3.IMU"}, /* 23 */
+	{3, 1440, "stateMuseumMuseum",  22, 2, "MUSEUM~4.IMU"}, /* 24 */
+	{3, 1450, "stateMuseumLibrary",  0, 0, "MUB575~5.IMU"}, /* 25 */
+	{3, 1460, "stateMuseumCavern",   0, 0, "MUF9BE~5.IMU"}, /* 26 */
+	{3, 1500, "stateTombTramNear",   0, 1, "TRAM(T~1.IMU"}, /* 27 */
+	{3, 1510, "stateTombBase",      28, 2, "TOMB(A~1.IMU"}, /* 28 */
+	{3, 1520, "stateTombSpire",     28, 2, "TOMB(A~2.IMU"}, /* 29 */
+	{3, 1530, "stateTombCave",      28, 2, "TOMB(A~3.IMU"}, /* 30 */
+	{3, 1540, "stateTombCrypt",     31, 1, "TOMB(C~1.IMU"}, /* 31 */
+	{3, 1550, "stateTombGuards",    31, 1, "TOMB(C~2.IMU"}, /* 32 */
+	{3, 1560, "stateTombInner",      0, 1, "TOMB(I~1.IMU"}, /* 33 */
+	{3, 1570, "stateTombCreator1",   0, 0, "TOMB(C~3.IMU"}, /* 34 */
+	{3, 1580, "stateTombCreator2",   0, 0, "TOMB(C~4.IMU"}, /* 35 */
+	{3, 1600, "statePlanTramNear",   0, 1, "TRAM(P~1.IMU"}, /* 36 */
+	{3, 1610, "statePlanTramFar",    0, 0, "TRAM(P~2.IMU"}, /* 37 */
+	{3, 1620, "statePlanBase",      38, 2, "PLAN(A~1.IMU"}, /* 38 */
+	{3, 1630, "statePlanSpire",     38, 2, "PLAN(A~2.IMU"}, /* 39 */
+	{3, 1650, "statePlanDome",       0, 0, "PLAN(D~1.IMU"}, /* 40 */
+	{3, 1700, "stateMapTramNear",    0, 1, "TRAM(M~3.IMU"}, /* 41 */
+	{3, 1710, "stateMapTramFar",     0, 0, "TRAM(M~4.IMU"}, /* 42 */
+	{3, 1720, "stateMapCanyon",     43, 2, "MAP(AM~1.IMU"}, /* 43 */
+	{3, 1730, "stateMapExposed",    43, 2, "MAP(AM~2.IMU"}, /* 44 */
+	{3, 1750, "stateMapNestEmpty",  43, 2, "MAP(AM~4.IMU"}, /* 45 */
+	{3, 1760, "stateMapNestMonster", 0, 0, "MAP(MO~1.IMU"}, /* 46 */
+	{3, 1770, "stateMapKlein",       0, 0, "MAP(KL~1.IMU"}, /* 47 */
+	{3, 1800, "stateCathTramNear",   0, 1, "TRAM(C~1.IMU"}, /* 48 */
+	{3, 1810, "stateCathTramFar",    0, 0, "TRAM(C~2.IMU"}, /* 49 */
+	{3, 1820, "stateCathLab",       50, 1, "CATH(A~1.IMU"}, /* 50 */
+	{3, 1830, "stateCathOutside",   50, 1, "CATH(A~2.IMU"}, /* 51 */
+	{3, 1900, "stateWorldMuseum",   52, 0, "WORLD(~1.IMU"}, /* 52 */
+	{3, 1901, "stateWorldPlan",     52, 0, "WORLD(~2.IMU"}, /* 53 */
+	{3, 1902, "stateWorldTomb",     52, 0, "WORLD(~3.IMU"}, /* 54 */
+	{3, 1903, "stateWorldMap",      52, 0, "WORLD(~4.IMU"}, /* 55 */
+	{3, 1904, "stateWorldCath",     52, 0, "WO3227~5.IMU"}, /* 56 */
+	{3, 1910, "stateEye1",           0, 0, "EYE1~1.IMU"},   /* 57 */
+	{3, 1911, "stateEye2",           0, 0, "EYE2~1.IMU"},   /* 58 */
+	{3, 1912, "stateEye3",           0, 0, "EYE3~1.IMU"},   /* 59 */
+	{3, 1913, "stateEye4",           0, 0, "EYE4~1.IMU"},   /* 60 */
+	{3, 1914, "stateEye5",           0, 0, "EYE5~1.IMU"},   /* 61 */
+	{3, 1915, "stateEye6",           0, 0, "EYE6~1.IMU"},   /* 62 */
+	{3, 1916, "stateEye7",           0, 0, "EYE7~1.IMU"},   /* 63 */
+	{0,   -1,  "",                   0, 0, ""}
 };
 
 const imuseDigTable _digSeqMusicTable[] = {
-	{0, 2000, "SEQ_NULL",            0, ""},
-	{0, 2005, "seqLogo",             0, ""},
-	{0, 2010, "seqIntro",            0, ""},
-	{6, 2020, "seqExplosion1b",      0, ""},
-	{3, 2030, "seqAstTunnel1a",      0, "SEQ(AS~1.IMU"},
-	{6, 2031, "seqAstTunnel2b",      0, ""},
-	{4, 2032, "seqAstTunnel3a",      0, "SEQ(AS~2.IMU"},
-	{5, 2040, "seqToPlanet1b",       0, ""},
-	{4, 2045, "seqArgBegin",         0, "SEQ(AR~1.IMU"},
-	{4, 2046, "seqArgEnd",           0, "SEQ(AR~2.IMU"},
-	{4, 2050, "seqWreckGhost",       0, "SEQ(GH~1.IMU"},
-	{4, 2060, "seqCanyonGhost",      0, "SEQ(GH~2.IMU"},
-	{0, 2070, "seqBrinkFall",        0, ""},
-	{4, 2080, "seqPanUpCanyon",      0, "SEQ(PA~1.IMU"},
-	{6, 2091, "seqAirlockTunnel1b",  0, ""},
-	{6, 2100, "seqTramToMu",         0, ""},
-	{6, 2101, "seqTramFromMu",       0, ""},
-	{6, 2102, "seqTramToTomb",       0, ""},
-	{6, 2103, "seqTramFromTomb",     0, ""},
-	{6, 2104, "seqTramToPlan",       0, ""},
-	{6, 2105, "seqTramFromPlan",     0, ""},
-	{6, 2106, "seqTramToMap",        0, ""},
-	{6, 2107, "seqTramFromMap",      0, ""},
-	{6, 2108, "seqTramToCath",       0, ""},
-	{6, 2109, "seqTramFromCath",     0, ""},
-	{0, 2110, "seqMuseumGhost",      0, ""},
-	{0, 2120, "seqSerpentAppears",   0, ""},
-	{0, 2130, "seqSerpentEats",      0, ""},
-	{6, 2140, "seqBrinkRes1b",       0, ""},
-	{4, 2141, "seqBrinkRes2a",       0, "SEQ(BR~1.IMU"},
-	{3, 2150, "seqLockupEntry",      0, "SEQ(BR~1.IMU"},
-	{0, 2160, "seqSerpentExplodes",  0, ""},
-	{4, 2170, "seqSwimUnderwater",   0, "SEQ(DE~1.IMU"},
-	{4, 2175, "seqWavesPlunge",      0, "SEQ(PL~1.IMU"},
-	{0, 2180, "seqCryptOpens",       0, ""},
-	{0, 2190, "seqGuardsFight",      0, ""},
-	{3, 2200, "seqCreatorRes1.1a",   0, "SEQ(CR~1.IMU"},
-	{6, 2201, "seqCreatorRes1.2b",   0, ""},
-	{6, 2210, "seqMaggieCapture1b",  0, ""},
-	{3, 2220, "seqStealCrystals",    0, "SEQ(BR~1.IMU"},
-	{0, 2230, "seqGetByMonster",     0, ""},
-	{6, 2240, "seqKillMonster1b",    0, ""},
-	{3, 2250, "seqCreatorRes2.1a",   0, "SEQ(CR~2.IMU"},
-	{6, 2251, "seqCreatorRes2.2b",   0, ""},
-	{4, 2252, "seqCreatorRes2.3a",   0, "SEQ(CR~3.IMU"},
-	{0, 2260, "seqMaggieInsists",    0, ""},
-	{0, 2270, "seqBrinkHelpCall",    0, ""},
-	{3, 2280, "seqBrinkCrevice1a",   0, "SEQ(BR~2.IMU"},
-	{3, 2281, "seqBrinkCrevice2a",   0, "SEQ(BR~3.IMU"},
-	{6, 2290, "seqCathAccess1b",     0, ""},
-	{4, 2291, "seqCathAccess2a",     0, "SEQ(CA~1.IMU"},
-	{3, 2300, "seqBrinkAtGenerator", 0, "SEQ(BR~1.IMU"},
-	{6, 2320, "seqFightBrink1b",     0, ""},
-	{6, 2340, "seqMaggieDies1b",     0, ""},
-	{6, 2346, "seqMaggieRes1b",      0, ""},
-	{4, 2347, "seqMaggieRes2a",      0, "SEQ(MA~1.IMU"},
-	{0, 2350, "seqCreatureFalls",    0, ""},
-	{5, 2360, "seqFinale1b",         0, ""},
-	{3, 2370, "seqFinale2a",         0, "SEQ(FI~1.IMU"},
-	{6, 2380, "seqFinale3b1",        0, ""},
-	{6, 2390, "seqFinale3b2",        0, ""},
-	{3, 2400, "seqFinale4a",         0, "SEQ(FI~2.IMU"},
-	{3, 2410, "seqFinale5a",         0, "SEQ(FI~3.IMU"},
-	{3, 2420, "seqFinale6a",         0, "SEQ(FI~4.IMU"},
-	{3, 2430, "seqFinale7a",         0, "SE3D2B~5.IMU"},
-	{6, 2440, "seqFinale8b",         0, ""},
-	{4, 2450, "seqFinale9a",         0, "SE313B~5.IMU"},
-	{0,   -1, "",                    0, ""}
+	{0, 2000, "SEQ_NULL",            0, 0, ""},
+	{0, 2005, "seqLogo",             0, 0, ""},
+	{0, 2010, "seqIntro",            0, 0, ""},
+	{6, 2020, "seqExplosion1b",      0, 0, ""},
+	{3, 2030, "seqAstTunnel1a",      0, 0, "SEQ(AS~1.IMU"},
+	{6, 2031, "seqAstTunnel2b",      0, 0, ""},
+	{4, 2032, "seqAstTunnel3a",      0, 0, "SEQ(AS~2.IMU"},
+	{5, 2040, "seqToPlanet1b",       0, 0, ""},
+	{4, 2045, "seqArgBegin",         0, 0, "SEQ(AR~1.IMU"},
+	{4, 2046, "seqArgEnd",           0, 0, "SEQ(AR~2.IMU"},
+	{4, 2050, "seqWreckGhost",       0, 0, "SEQ(GH~1.IMU"},
+	{4, 2060, "seqCanyonGhost",      0, 0, "SEQ(GH~2.IMU"},
+	{0, 2070, "seqBrinkFall",        0, 0, ""},
+	{4, 2080, "seqPanUpCanyon",      0, 0, "SEQ(PA~1.IMU"},
+	{6, 2091, "seqAirlockTunnel1b",  0, 0, ""},
+	{6, 2100, "seqTramToMu",         0, 0, ""},
+	{6, 2101, "seqTramFromMu",       0, 0, ""},
+	{6, 2102, "seqTramToTomb",       0, 0, ""},
+	{6, 2103, "seqTramFromTomb",     0, 0, ""},
+	{6, 2104, "seqTramToPlan",       0, 0, ""},
+	{6, 2105, "seqTramFromPlan",     0, 0, ""},
+	{6, 2106, "seqTramToMap",        0, 0, ""},
+	{6, 2107, "seqTramFromMap",      0, 0, ""},
+	{6, 2108, "seqTramToCath",       0, 0, ""},
+	{6, 2109, "seqTramFromCath",     0, 0, ""},
+	{0, 2110, "seqMuseumGhost",      0, 0, ""},
+	{0, 2120, "seqSerpentAppears",   0, 0, ""},
+	{0, 2130, "seqSerpentEats",      0, 0, ""},
+	{6, 2140, "seqBrinkRes1b",       0, 0, ""},
+	{4, 2141, "seqBrinkRes2a",       0, 0, "SEQ(BR~1.IMU"},
+	{3, 2150, "seqLockupEntry",      0, 0, "SEQ(BR~1.IMU"},
+	{0, 2160, "seqSerpentExplodes",  0, 0, ""},
+	{4, 2170, "seqSwimUnderwater",   0, 0, "SEQ(DE~1.IMU"},
+	{4, 2175, "seqWavesPlunge",      0, 0, "SEQ(PL~1.IMU"},
+	{0, 2180, "seqCryptOpens",       0, 0, ""},
+	{0, 2190, "seqGuardsFight",      0, 0, ""},
+	{3, 2200, "seqCreatorRes1.1a",   0, 0, "SEQ(CR~1.IMU"},
+	{6, 2201, "seqCreatorRes1.2b",   0, 0, ""},
+	{6, 2210, "seqMaggieCapture1b",  0, 0, ""},
+	{3, 2220, "seqStealCrystals",    0, 0, "SEQ(BR~1.IMU"},
+	{0, 2230, "seqGetByMonster",     0, 0, ""},
+	{6, 2240, "seqKillMonster1b",    0, 0, ""},
+	{3, 2250, "seqCreatorRes2.1a",   0, 0, "SEQ(CR~2.IMU"},
+	{6, 2251, "seqCreatorRes2.2b",   0, 0, ""},
+	{4, 2252, "seqCreatorRes2.3a",   0, 0, "SEQ(CR~3.IMU"},
+	{0, 2260, "seqMaggieInsists",    0, 0, ""},
+	{0, 2270, "seqBrinkHelpCall",    0, 0, ""},
+	{3, 2280, "seqBrinkCrevice1a",   0, 0, "SEQ(BR~2.IMU"},
+	{3, 2281, "seqBrinkCrevice2a",   0, 0, "SEQ(BR~3.IMU"},
+	{6, 2290, "seqCathAccess1b",     0, 0, ""},
+	{4, 2291, "seqCathAccess2a",     0, 0, "SEQ(CA~1.IMU"},
+	{3, 2300, "seqBrinkAtGenerator", 0, 0, "SEQ(BR~1.IMU"},
+	{6, 2320, "seqFightBrink1b",     0, 0, ""},
+	{6, 2340, "seqMaggieDies1b",     0, 0, ""},
+	{6, 2346, "seqMaggieRes1b",      0, 0, ""},
+	{4, 2347, "seqMaggieRes2a",      0, 0, "SEQ(MA~1.IMU"},
+	{0, 2350, "seqCreatureFalls",    0, 0, ""},
+	{5, 2360, "seqFinale1b",         0, 0, ""},
+	{3, 2370, "seqFinale2a",         0, 0, "SEQ(FI~1.IMU"},
+	{6, 2380, "seqFinale3b1",        0, 0, ""},
+	{6, 2390, "seqFinale3b2",        0, 0, ""},
+	{3, 2400, "seqFinale4a",         0, 0, "SEQ(FI~2.IMU"},
+	{3, 2410, "seqFinale5a",         0, 0, "SEQ(FI~3.IMU"},
+	{3, 2420, "seqFinale6a",         0, 0, "SEQ(FI~4.IMU"},
+	{3, 2430, "seqFinale7a",         0, 0, "SE3D2B~5.IMU"},
+	{6, 2440, "seqFinale8b",         0, 0, ""},
+	{4, 2450, "seqFinale9a",         0, 0, "SE313B~5.IMU"},
+	{0,   -1, "",                    0, 0, ""}
 };
 
 const imuseComiTable _comiStateMusicTable[] = {
-	{0, 1000, "STATE_NULL",         0, 0,    0, ""},
-	{0, 1001, "stateNoChange",      0, 0,    0, ""},
-	{3, 1098, "stateCredits1",      0, 0, 1000, "1098-C~1.IMX"},
-	{3, 1099, "stateMenu",          0, 0, 1000, "1099-M~1.IMX"},
-	{3, 1100, "stateHold1",         4, 0, 1000, "1100-H~1.IMX"},
-	{3, 1101, "stateWaterline1",    4, 0, 1000, "1101-W~1.IMX"},
-	{3, 1102, "stateHold2",         6, 1, 1000, "1102-H~1.IMX"},
-	{3, 1103, "stateWaterline2",    6, 0, 1000, "1103-W~1.IMX"},
-	{3, 1104, "stateCannon",        0, 0, 1000, "1104-C~1.IMX"},
-	{3, 1105, "stateTreasure",      0, 0, 1000, "1105-T~1.IMX"},
-	{3, 1200, "stateFortBase",     10, 1, 1000, "1200-F~1.IMX"},
-	{3, 1201, "statePreFort",      10, 1, 1000, "1201-P~1.IMX"},
-	{3, 1202, "statePreVooOut",    12, 0, 1000, "1202-P~1.IMX"},
-	{3, 1203, "statePreVooIn",     12, 0, 1000, "1203-P~1.IMX"},
-	{3, 1204, "statePreVooLady",   12, 0, 1000, "1204-P~1.IMX"},
-	{3, 1205, "stateVoodooOut",     0, 0, 1000, "1205-V~1.IMX"},
-	{3, 1210, "stateVoodooIn",      0, 0, 1000, "1210-V~1.IMX"},
-	{12,1212, "stateVoodooInAlt",   0, 1,  700, "1210-V~1.IMX"},
-	{3, 1215, "stateVoodooLady",    0, 0, 1000, "1215-V~1.IMX"},
-	{3, 1219, "statePrePlundermap", 0, 0, 1000, "1219-P~1.IMX"},
-	{3, 1220, "statePlundermap",    0, 0, 1000, "1220-P~1.IMX"},
-	{3, 1222, "statePreCabana",     0, 0, 1000, "1222-P~1.IMX"},
-	{3, 1223, "stateCabana",        0, 0, 1000, "1223-C~1.IMX"},
-	{3, 1224, "statePostCabana",   23, 0, 1000, "1224-P~1.IMX"},
-	{3, 1225, "stateBeachClub",    23, 0, 1000, "1225-B~1.IMX"},
-	{3, 1230, "stateCliff",         0, 0, 1000, "1230-C~1.IMX"},
-	{3, 1232, "stateBelly",         0, 0,  800, "1232-B~1.IMX"},
-	{3, 1235, "stateQuicksand",     0, 0, 1000, "1235-Q~1.IMX"},
-	{3, 1240, "stateDangerBeach",   0, 0,  800, "1240-D~1.IMX"},
-	{12,1241, "stateDangerBeachAlt",0, 2,  800, "1240-D~1.IMX"},
-	{3, 1245, "stateRowBoat",       0, 0, 1000, "1245-R~1.IMX"},
-	{3, 1247, "stateAlongside",     0, 0,  800, "1247-A~1.IMX"},
-	{12,1248, "stateAlongsideAlt",  0, 1,  800, "1247-A~1.IMX"},
-	{3, 1250, "stateChimpBoat",     0, 0,  500, "1250-C~1.IMX"},
-	{3, 1255, "stateMrFossey",      0, 0,  800, "1255-M~1.IMX"},
-	{3, 1259, "statePreTown",       0, 0, 1000, "1259-P~1.IMX"},
-	{3, 1260, "stateTown",          0, 0, 1000, "1260-T~1.IMX"},
-	{3, 1264, "statePreMeadow",     0, 0, 1000, "1264-P~1.IMX"},
-	{3, 1265, "stateMeadow",        0, 0, 1000, "1265-M~1.IMX"},
-	{3, 1266, "stateMeadowAmb",     0, 0, 1000, "1266-M~1.IMX"},
-	{3, 1270, "stateWardrobePre",  40, 0, 1000, "1270-W~1.IMX"},
-	{3, 1272, "statePreShow",      40, 0, 1000, "1272-P~1.IMX"},
-	{3, 1274, "stateWardrobeShow", 42, 0, 1000, "1274-W~1.IMX"},
-	{3, 1276, "stateShow",         42, 0, 1000, "1276-S~1.IMX"},
-	{3, 1277, "stateWardrobeJug",  44, 0, 1000, "1277-W~1.IMX"},
-	{3, 1278, "stateJuggling",     44, 0, 1000, "1278-J~1.IMX"},
-	{3, 1279, "statePostShow",      0, 0, 1000, "1279-P~1.IMX"},
-	{3, 1280, "stateChickenShop",   0, 0, 1000, "1280-C~1.IMX"},
-	{3, 1285, "stateBarberShop",   48, 0, 1000, "1285-B~1.IMX"},
-	{3, 1286, "stateVanHelgen",    48, 0, 1000, "1286-V~1.IMX"},
-	{3, 1287, "stateBill",         48, 0, 1000, "1287-B~1.IMX"},
-	{3, 1288, "stateHaggis",       48, 0, 1000, "1288-H~1.IMX"},
-	{3, 1289, "stateRottingham",   48, 0, 1000, "1289-R~1.IMX"},
-	{3, 1305, "stateDeck",          0, 0, 1000, "1305-D~1.IMX"},
-	{3, 1310, "stateCombatMap",     0, 0, 1000, "1310-C~1.IMX"},
-	{3, 1320, "stateShipCombat",    0, 0, 1000, "1320-S~1.IMX"},
-	{3, 1325, "stateSwordfight",    0, 0, 1000, "1325-S~1.IMX"},
-	{3, 1327, "stateSwordRott",     0, 0, 1000, "1327-S~1.IMX"},
-	{3, 1330, "stateTownEdge",      0, 0, 1000, "1330-T~1.IMX"},
-	{3, 1335, "stateSwordLose",     0, 0, 1000, "1335-S~1.IMX"},
-	{3, 1340, "stateSwordWin",      0, 0, 1000, "1340-S~1.IMX"},
-	{3, 1345, "stateGetMap",        0, 0, 1000, "1345-G~1.IMX"},
-	{3, 1400, "stateWreckBeach",    0, 0, 1000, "1400-W~1.IMX"},
-	{3, 1405, "stateBloodMap",     63, 0, 1000, "1405-B~1.IMX"},
-	{3, 1410, "stateClearing",      0, 0, 1000, "1410-C~1.IMX"},
-	{3, 1415, "stateLighthouse",   63, 0, 1000, "1415-L~1.IMX"},
-	{3, 1420, "stateVillage",      66, 0, 1000, "1420-V~1.IMX"},
-	{3, 1423, "stateVolcano",      66, 0, 1000, "1423-V~1.IMX"},
-	{3, 1425, "stateAltar",        66, 0, 1000, "1425-A~1.IMX"},
-	{3, 1430, "stateHotelOut",      0, 0, 1000, "1430-H~1.IMX"},
-	{3, 1435, "stateHotelBar",     70, 0, 1000, "1435-H~1.IMX"},
-	{3, 1440, "stateHotelIn",      70, 0, 1000, "1440-H~1.IMX"},
-	{3, 1445, "stateTarotLady",    70, 0, 1000, "1445-T~1.IMX"},
-	{3, 1447, "stateGoodsoup",     70, 0, 1000, "1447-G~1.IMX"},
-	{3, 1448, "stateGuestRoom",     0, 0, 1000, "1448-G~1.IMX"},
-	{3, 1450, "stateWindmill",     63, 0, 1000, "1450-W~1.IMX"},
-	{3, 1455, "stateCemetary",      0, 0, 1000, "1455-C~1.IMX"},
-	{3, 1460, "stateCrypt",        77, 0, 1000, "1460-C~1.IMX"},
-	{3, 1463, "stateGraveDigger",  77, 0, 1000, "1463-G~1.IMX"},
-	{3, 1465, "stateMonkey1",       0, 0, 1000, "1465-M~1.IMX"},
-	{3, 1475, "stateStanDark",      0, 0, 1000, "1475-S~1.IMX"},
-	{3, 1477, "stateStanLight",     0, 0, 1000, "1477-S~1.IMX"},
-	{3, 1480, "stateEggBeach",     63, 0, 1000, "1480-E~1.IMX"},
-	{3, 1485, "stateSkullIsland",   0, 0, 1000, "1485-S~1.IMX"},
-	{3, 1490, "stateSmugglersCave", 0, 0, 1000, "1490-S~1.IMX"},
-	{3, 1500, "stateLeChuckTalk",   0, 0, 1000, "1500-L~1.IMX"},
-	{3, 1505, "stateCarnival",      0, 0, 1000, "1505-C~1.IMX"},
-	{3, 1511, "stateHang",         87, 0, 1000, "1511-H~1.IMX"},
-	{3, 1512, "stateRum",          87, 0, 1000, "1512-RUM.IMX"},
-	{3, 1513, "stateTorture",      87, 0, 1000, "1513-T~1.IMX"},
-	{3, 1514, "stateSnow",         87, 0, 1000, "1514-S~1.IMX"},
-	{3, 1515, "stateCredits",       0, 0, 1000, "1515-C~1.IMX"},
-	{3, 1520, "stateCarnAmb",       0, 0, 1000, "1520-C~1.IMX"},
+	{0, 1000, "STATE_NULL",         0, 0,    0, ""},             /* 00 */
+	{0, 1001, "stateNoChange",      0, 0,    0, ""},             /* 01 */
+	{3, 1098, "stateCredits1",      0, 0,   60, "1098-C~1.IMX"}, /* 02 */
+	{3, 1099, "stateMenu",          0, 0,   60, "1099-M~1.IMX"}, /* 03 */
+	{3, 1100, "stateHold1",         4, 0,   60, "1100-H~1.IMX"}, /* 04 */
+	{3, 1101, "stateWaterline1",    4, 0,   60, "1101-W~1.IMX"}, /* 05 */
+	{3, 1102, "stateHold2",         6, 1,   60, "1102-H~1.IMX"}, /* 06 */
+	{3, 1103, "stateWaterline2",    6, 0,   60, "1103-W~1.IMX"}, /* 07 */
+	{3, 1104, "stateCannon",        0, 0,   60, "1104-C~1.IMX"}, /* 08 */
+	{3, 1105, "stateTreasure",      0, 0,   60, "1105-T~1.IMX"}, /* 09 */
+	{3, 1200, "stateFortBase",     10, 1,   60, "1200-F~1.IMX"}, /* 10 */
+	{3, 1201, "statePreFort",      10, 1,   60, "1201-P~1.IMX"}, /* 11 */
+	{3, 1202, "statePreVooOut",    12, 0,   60, "1202-P~1.IMX"}, /* 12 */
+	{3, 1203, "statePreVooIn",     12, 0,   60, "1203-P~1.IMX"}, /* 13 */
+	{3, 1204, "statePreVooLady",   12, 0,   60, "1204-P~1.IMX"}, /* 14 */
+	{3, 1205, "stateVoodooOut",     0, 0,   60, "1205-V~1.IMX"}, /* 15 */
+	{3, 1210, "stateVoodooIn",      0, 0,   60, "1210-V~1.IMX"}, /* 16 */
+	{12,1212, "stateVoodooInAlt",   0, 1,   42, "1210-V~1.IMX"}, /* 17 */
+	{3, 1215, "stateVoodooLady",    0, 0,   60, "1215-V~1.IMX"}, /* 18 */
+	{3, 1219, "statePrePlundermap", 0, 0,   60, "1219-P~1.IMX"}, /* 19 */
+	{3, 1220, "statePlundermap",    0, 0,   60, "1220-P~1.IMX"}, /* 20 */
+	{3, 1222, "statePreCabana",     0, 0,   60, "1222-P~1.IMX"}, /* 21 */
+	{3, 1223, "stateCabana",        0, 0,   60, "1223-C~1.IMX"}, /* 22 */
+	{3, 1224, "statePostCabana",   23, 0,   60, "1224-P~1.IMX"}, /* 23 */
+	{3, 1225, "stateBeachClub",    23, 0,   60, "1225-B~1.IMX"}, /* 24 */
+	{3, 1230, "stateCliff",         0, 0,   60, "1230-C~1.IMX"}, /* 25 */
+	{3, 1232, "stateBelly",         0, 0,   48, "1232-B~1.IMX"}, /* 26 */
+	{3, 1235, "stateQuicksand",     0, 0,   60, "1235-Q~1.IMX"}, /* 27 */
+	{3, 1240, "stateDangerBeach",   0, 0,   48, "1240-D~1.IMX"}, /* 28 */
+	{12,1241, "stateDangerBeachAlt",0, 2,   48, "1240-D~1.IMX"}, /* 29 */
+	{3, 1245, "stateRowBoat",       0, 0,   60, "1245-R~1.IMX"}, /* 30 */
+	{3, 1247, "stateAlongside",     0, 0,   48, "1247-A~1.IMX"}, /* 31 */
+	{12,1248, "stateAlongsideAlt",  0, 1,   48, "1247-A~1.IMX"}, /* 32 */
+	{3, 1250, "stateChimpBoat",     0, 0,   30, "1250-C~1.IMX"}, /* 33 */
+	{3, 1255, "stateMrFossey",      0, 0,   48, "1255-M~1.IMX"}, /* 34 */
+	{3, 1259, "statePreTown",       0, 0,   60, "1259-P~1.IMX"}, /* 35 */
+	{3, 1260, "stateTown",          0, 0,   60, "1260-T~1.IMX"}, /* 36 */
+	{3, 1264, "statePreMeadow",     0, 0,   60, "1264-P~1.IMX"}, /* 37 */
+	{3, 1265, "stateMeadow",        0, 0,   60, "1265-M~1.IMX"}, /* 38 */
+	{3, 1266, "stateMeadowAmb",     0, 0,   60, "1266-M~1.IMX"}, /* 39 */
+	{3, 1270, "stateWardrobePre",  40, 0,   60, "1270-W~1.IMX"}, /* 40 */
+	{3, 1272, "statePreShow",      40, 0,   60, "1272-P~1.IMX"}, /* 41 */
+	{3, 1274, "stateWardrobeShow", 42, 0,   60, "1274-W~1.IMX"}, /* 42 */
+	{3, 1276, "stateShow",         42, 0,   60, "1276-S~1.IMX"}, /* 43 */
+	{3, 1277, "stateWardrobeJug",  44, 0,   60, "1277-W~1.IMX"}, /* 44 */
+	{3, 1278, "stateJuggling",     44, 0,   60, "1278-J~1.IMX"}, /* 45 */
+	{3, 1279, "statePostShow",      0, 0,   60, "1279-P~1.IMX"}, /* 46 */
+	{3, 1280, "stateChickenShop",   0, 0,   60, "1280-C~1.IMX"}, /* 47 */
+	{3, 1285, "stateBarberShop",   48, 0,   60, "1285-B~1.IMX"}, /* 48 */
+	{3, 1286, "stateVanHelgen",    48, 0,   60, "1286-V~1.IMX"}, /* 49 */
+	{3, 1287, "stateBill",         48, 0,   60, "1287-B~1.IMX"}, /* 50 */
+	{3, 1288, "stateHaggis",       48, 0,   60, "1288-H~1.IMX"}, /* 51 */
+	{3, 1289, "stateRottingham",   48, 0,   60, "1289-R~1.IMX"}, /* 52 */
+	{3, 1305, "stateDeck",          0, 0,   60, "1305-D~1.IMX"}, /* 53 */
+	{3, 1310, "stateCombatMap",     0, 0,   60, "1310-C~1.IMX"}, /* 54 */
+	{3, 1320, "stateShipCombat",    0, 0,   60, "1320-S~1.IMX"}, /* 55 */
+	{3, 1325, "stateSwordfight",    0, 0,   60, "1325-S~1.IMX"}, /* 56 */
+	{3, 1327, "stateSwordRott",     0, 0,   60, "1327-S~1.IMX"}, /* 57 */
+	{3, 1330, "stateTownEdge",      0, 0,   60, "1330-T~1.IMX"}, /* 58 */
+	{3, 1335, "stateSwordLose",     0, 0,   60, "1335-S~1.IMX"}, /* 59 */
+	{3, 1340, "stateSwordWin",      0, 0,   60, "1340-S~1.IMX"}, /* 60 */
+	{3, 1345, "stateGetMap",        0, 0,   60, "1345-G~1.IMX"}, /* 61 */
+	{3, 1400, "stateWreckBeach",    0, 0,   60, "1400-W~1.IMX"}, /* 62 */
+	{3, 1405, "stateBloodMap",     63, 0,   60, "1405-B~1.IMX"}, /* 63 */
+	{3, 1410, "stateClearing",      0, 0,   60, "1410-C~1.IMX"}, /* 64 */
+	{3, 1415, "stateLighthouse",   63, 0,   60, "1415-L~1.IMX"}, /* 65 */
+	{3, 1420, "stateVillage",      66, 0,   60, "1420-V~1.IMX"}, /* 66 */
+	{3, 1423, "stateVolcano",      66, 0,   60, "1423-V~1.IMX"}, /* 67 */
+	{3, 1425, "stateAltar",        66, 0,   60, "1425-A~1.IMX"}, /* 68 */
+	{3, 1430, "stateHotelOut",      0, 0,   60, "1430-H~1.IMX"}, /* 69 */
+	{3, 1435, "stateHotelBar",     70, 0,   60, "1435-H~1.IMX"}, /* 70 */
+	{3, 1440, "stateHotelIn",      70, 0,   60, "1440-H~1.IMX"}, /* 71 */
+	{3, 1445, "stateTarotLady",    70, 0,   60, "1445-T~1.IMX"}, /* 72 */
+	{3, 1447, "stateGoodsoup",     70, 0,   60, "1447-G~1.IMX"}, /* 73 */
+	{3, 1448, "stateGuestRoom",     0, 0,   60, "1448-G~1.IMX"}, /* 74 */
+	{3, 1450, "stateWindmill",     63, 0,   60, "1450-W~1.IMX"}, /* 75 */
+	{3, 1455, "stateCemetary",      0, 0,   60, "1455-C~1.IMX"}, /* 76 */
+	{3, 1460, "stateCrypt",        77, 0,   60, "1460-C~1.IMX"}, /* 77 */
+	{3, 1463, "stateGraveDigger",  77, 0,   60, "1463-G~1.IMX"}, /* 78 */
+	{3, 1465, "stateMonkey1",       0, 0,   60, "1465-M~1.IMX"}, /* 79 */
+	{3, 1475, "stateStanDark",      0, 0,   60, "1475-S~1.IMX"}, /* 80 */
+	{3, 1477, "stateStanLight",     0, 0,   60, "1477-S~1.IMX"}, /* 81 */
+	{3, 1480, "stateEggBeach",     63, 0,   60, "1480-E~1.IMX"}, /* 82 */
+	{3, 1485, "stateSkullIsland",   0, 0,   60, "1485-S~1.IMX"}, /* 83 */
+	{3, 1490, "stateSmugglersCave", 0, 0,   60, "1490-S~1.IMX"}, /* 84 */
+	{3, 1500, "stateLeChuckTalk",   0, 0,   60, "1500-L~1.IMX"}, /* 85 */
+	{3, 1505, "stateCarnival",      0, 0,   60, "1505-C~1.IMX"}, /* 86 */
+	{3, 1511, "stateHang",         87, 0,   60, "1511-H~1.IMX"}, /* 87 */
+	{3, 1512, "stateRum",          87, 0,   60, "1512-RUM.IMX"}, /* 88 */
+	{3, 1513, "stateTorture",      87, 0,   60, "1513-T~1.IMX"}, /* 89 */
+	{3, 1514, "stateSnow",         87, 0,   60, "1514-S~1.IMX"}, /* 90 */
+	{3, 1515, "stateCredits",       0, 0,   60, "1515-C~1.IMX"}, /* 91 */
+	{3, 1520, "stateCarnAmb",       0, 0,   60, "1520-C~1.IMX"}, /* 92 */
 	{0,   -1, "",                   0, 0,    0, ""}
 };
 
 const imuseComiTable _comiSeqMusicTable[] = {
 	{0, 2000, "SEQ_NULL",        0, 0,    0, ""},
 	{0, 2100, "seqINTRO",        0, 0,    0, ""},
-	{3, 2105, "seqInterlude1",   0, 0, 1000, "2105-I~1.IMX"},
+	{3, 2105, "seqInterlude1",   0, 0,   60, "2105-I~1.IMX"},
 	{8, 2110, "seqLastBoat",     0, 1,    0, ""},
 	{0, 2115, "seqSINK_SHIP",    0, 0,    0, ""},
-	{0, 2120, "seqCURSED_RING",  0, 0, 1000, ""},
-	{3, 2200, "seqInterlude2",   0, 0, 1000, "2200-I~1.IMX"},
-	{3, 2210, "seqKidnapped",    0, 0, 1000, "2210-K~1.IMX"},
+	{0, 2120, "seqCURSED_RING",  0, 0,   60, ""},
+	{3, 2200, "seqInterlude2",   0, 0,   60, "2200-I~1.IMX"},
+	{3, 2210, "seqKidnapped",    0, 0,   60, "2210-K~1.IMX"},
 	{8, 2220, "seqSnakeVomits",  0, 1,    0, ""},
 	{8, 2222, "seqPopBalloon",   0, 1,    0, ""},
-	{3, 2225, "seqDropBalls",    0, 0, 1000, "2225-D~1.IMX"},
-	{4, 2232, "seqArriveBarber", 0, 0, 1000, "2232-A~1.IMX"},
-	{3, 2233, "seqAtonal",       0, 0, 1000, "2233-A~1.IMX"},
-	{3, 2235, "seqShaveHead1",   0, 0, 1000, "2235-S~1.IMX"},
-	{2, 2236, "seqShaveHead2",   0, 2, 1000, "2235-S~1.IMX"},
-	{3, 2245, "seqCaberLose",    0, 0, 1000, "2245-C~1.IMX"},
-	{3, 2250, "seqCaberWin",     0, 0, 1000, "2250-C~1.IMX"},
-	{3, 2255, "seqDuel1",        0, 0, 1000, "2255-D~1.IMX"},
-	{2, 2256, "seqDuel2",        0, 2, 1000, "2255-D~1.IMX"},
-	{2, 2257, "seqDuel3",        0, 3, 1000, "2255-D~1.IMX"},
-	{3, 2260, "seqBlowUpTree1",  0, 0, 1000, "2260-B~1.IMX"},
-	{2, 2261, "seqBlowUpTree2",  0, 2, 1000, "2260-B~1.IMX"},
-	{3, 2275, "seqMonkeys",      0, 0, 1000, "2275-M~1.IMX"},
+	{3, 2225, "seqDropBalls",    0, 0,   60, "2225-D~1.IMX"},
+	{4, 2232, "seqArriveBarber", 0, 0,   60, "2232-A~1.IMX"},
+	{3, 2233, "seqAtonal",       0, 0,   60, "2233-A~1.IMX"},
+	{3, 2235, "seqShaveHead1",   0, 0,   60, "2235-S~1.IMX"},
+	{2, 2236, "seqShaveHead2",   0, 2,   60, "2235-S~1.IMX"},
+	{3, 2245, "seqCaberLose",    0, 0,   60, "2245-C~1.IMX"},
+	{3, 2250, "seqCaberWin",     0, 0,   60, "2250-C~1.IMX"},
+	{3, 2255, "seqDuel1",        0, 0,   60, "2255-D~1.IMX"},
+	{2, 2256, "seqDuel2",        0, 2,   60, "2255-D~1.IMX"},
+	{2, 2257, "seqDuel3",        0, 3,   60, "2255-D~1.IMX"},
+	{3, 2260, "seqBlowUpTree1",  0, 0,   60, "2260-B~1.IMX"},
+	{2, 2261, "seqBlowUpTree2",  0, 2,   60, "2260-B~1.IMX"},
+	{3, 2275, "seqMonkeys",      0, 0,   60, "2275-M~1.IMX"},
 	{9, 2277, "seqAttack",       0, 1,    0, ""},
-	{3, 2285, "seqSharks",       0, 0, 1000, "2285-S~1.IMX"},
-	{3, 2287, "seqTowelWalk",    0, 0, 1000, "2287-T~1.IMX"},
+	{3, 2285, "seqSharks",       0, 0,   60, "2285-S~1.IMX"},
+	{3, 2287, "seqTowelWalk",    0, 0,   60, "2287-T~1.IMX"},
 	{0, 2293, "seqNICE_BOOTS",   0, 0,    0, ""},
 	{0, 2295, "seqBIG_BONED",    0, 0,    0, ""},
-	{3, 2300, "seqToBlood",      0, 0, 1000, "2300-T~1.IMX"},
-	{3, 2301, "seqInterlude3",   0, 0, 1000, "2301-I~1.IMX"},
-	{3, 2302, "seqRott1",        0, 0, 1000, "2302-R~1.IMX"},
-	{2, 2304, "seqRott2",        0, 2, 1000, "2302-R~1.IMX"},
-	{2, 2305, "seqRott2b",       0,21, 1000, "2302-R~1.IMX"},
-	{2, 2306, "seqRott3",        0, 3, 1000, "2302-R~1.IMX"},
-	{2, 2308, "seqRott4",        0, 4, 1000, "2302-R~1.IMX"},
-	{2, 2309, "seqRott5",        0, 5, 1000, "2302-R~1.IMX"},
-	{3, 2311, "seqVerse1",       0, 0, 1000, "2311-S~1.IMX"},
-	{2, 2312, "seqVerse2",       0, 2, 1000, "2311-S~1.IMX"},
-	{2, 2313, "seqVerse3",       0, 3, 1000, "2311-S~1.IMX"},
-	{2, 2314, "seqVerse4",       0, 4, 1000, "2311-S~1.IMX"},
-	{2, 2315, "seqVerse5",       0, 5, 1000, "2311-S~1.IMX"},
-	{2, 2316, "seqVerse6",       0, 6, 1000, "2311-S~1.IMX"},
-	{2, 2317, "seqVerse7",       0, 7, 1000, "2311-S~1.IMX"},
-	{2, 2318, "seqVerse8",       0, 8, 1000, "2311-S~1.IMX"},
-	{2, 2319, "seqSongEnd",      0, 9, 1000, "2311-S~1.IMX"},
-	{2, 2336, "seqRiposteLose",  0, 0, 1000, "2336-R~1.IMX"},
-	{2, 2337, "seqRiposteWin",   0, 0, 1000, "2337-R~1.IMX"},
-	{2, 2338, "seqInsultLose",   0, 0, 1000, "2338-I~1.IMX"},
-	{2, 2339, "seqInsultWin",    0, 0, 1000, "2339-I~1.IMX"},
-	{3, 2340, "seqSwordLose",    0, 0, 1000, "1335-S~1.IMX"},
-	{3, 2345, "seqSwordWin",     0, 0, 1000, "1340-S~1.IMX"},
-	{3, 2347, "seqGetMap",       0, 0, 1000, "1345-G~1.IMX"},
-	{3, 2400, "seqInterlude4",   0, 0, 1000, "2400-I~1.IMX"},
+	{3, 2300, "seqToBlood",      0, 0,   60, "2300-T~1.IMX"},
+	{3, 2301, "seqInterlude3",   0, 0,   60, "2301-I~1.IMX"},
+	{3, 2302, "seqRott1",        0, 0,   60, "2302-R~1.IMX"},
+	{2, 2304, "seqRott2",        0, 2,   60, "2302-R~1.IMX"},
+	{2, 2305, "seqRott2b",       0,21,   60, "2302-R~1.IMX"},
+	{2, 2306, "seqRott3",        0, 3,   60, "2302-R~1.IMX"},
+	{2, 2308, "seqRott4",        0, 4,   60, "2302-R~1.IMX"},
+	{2, 2309, "seqRott5",        0, 5,   60, "2302-R~1.IMX"},
+	{3, 2311, "seqVerse1",       0, 0,   60, "2311-S~1.IMX"},
+	{2, 2312, "seqVerse2",       0, 2,   60, "2311-S~1.IMX"},
+	{2, 2313, "seqVerse3",       0, 3,   60, "2311-S~1.IMX"},
+	{2, 2314, "seqVerse4",       0, 4,   60, "2311-S~1.IMX"},
+	{2, 2315, "seqVerse5",       0, 5,   60, "2311-S~1.IMX"},
+	{2, 2316, "seqVerse6",       0, 6,   60, "2311-S~1.IMX"},
+	{2, 2317, "seqVerse7",       0, 7,   60, "2311-S~1.IMX"},
+	{2, 2318, "seqVerse8",       0, 8,   60, "2311-S~1.IMX"},
+	{2, 2319, "seqSongEnd",      0, 9,   60, "2311-S~1.IMX"},
+	{2, 2336, "seqRiposteLose",  0, 0,   60, "2336-R~1.IMX"},
+	{2, 2337, "seqRiposteWin",   0, 0,   60, "2337-R~1.IMX"},
+	{2, 2338, "seqInsultLose",   0, 0,   60, "2338-I~1.IMX"},
+	{2, 2339, "seqInsultWin",    0, 0,   60, "2339-I~1.IMX"},
+	{3, 2340, "seqSwordLose",    0, 0,   60, "1335-S~1.IMX"},
+	{3, 2345, "seqSwordWin",     0, 0,   60, "1340-S~1.IMX"},
+	{3, 2347, "seqGetMap",       0, 0,   60, "1345-G~1.IMX"},
+	{3, 2400, "seqInterlude4",   0, 0,   60, "2400-I~1.IMX"},
 	{0, 2405, "seqSHIPWRECK",    0, 0,    0, ""},
-	{3, 2408, "seqFakeCredits",  0, 0, 1000, "2408-F~1.IMX"},
-	{3, 2410, "seqPassOut",      0, 0, 1000, "2410-P~1.IMX"},
-	{3, 2414, "seqGhostTalk",    0, 0, 1000, "2414-G~1.IMX"},
-	{2, 2415, "seqGhostWedding", 0, 1, 1000, "2414-G~1.IMX"},
-	{3, 2420, "seqEruption",     0, 0, 1000, "2420-E~1.IMX"},
-	{3, 2425, "seqSacrifice",    0, 0, 1000, "2425-S~1.IMX"},
-	{2, 2426, "seqSacrificeEnd", 0, 1, 1000, "2425-S~1.IMX"},
-	{3, 2430, "seqScareDigger",  0, 0, 1000, "2430-S~1.IMX"},
-	{3, 2445, "seqSkullArrive",  0, 0, 1000, "2445-S~1.IMX"},
-	{3, 2450, "seqFloat",        0, 0, 1000, "2450-C~1.IMX"},
-	{2, 2451, "seqFall",         0, 1, 1000, "2450-C~1.IMX"},
-	{2, 2452, "seqUmbrella",     0, 0, 1000, "2450-C~1.IMX"},
-	{3, 2460, "seqFight",        0, 0, 1000, "2460-F~1.IMX"},
+	{3, 2408, "seqFakeCredits",  0, 0,   60, "2408-F~1.IMX"},
+	{3, 2410, "seqPassOut",      0, 0,   60, "2410-P~1.IMX"},
+	{3, 2414, "seqGhostTalk",    0, 0,   60, "2414-G~1.IMX"},
+	{2, 2415, "seqGhostWedding", 0, 1,   60, "2414-G~1.IMX"},
+	{3, 2420, "seqEruption",     0, 0,   60, "2420-E~1.IMX"},
+	{3, 2425, "seqSacrifice",    0, 0,   60, "2425-S~1.IMX"},
+	{2, 2426, "seqSacrificeEnd", 0, 1,   60, "2425-S~1.IMX"},
+	{3, 2430, "seqScareDigger",  0, 0,   60, "2430-S~1.IMX"},
+	{3, 2445, "seqSkullArrive",  0, 0,   60, "2445-S~1.IMX"},
+	{3, 2450, "seqFloat",        0, 0,   60, "2450-C~1.IMX"},
+	{2, 2451, "seqFall",         0, 1,   60, "2450-C~1.IMX"},
+	{2, 2452, "seqUmbrella",     0, 0,   60, "2450-C~1.IMX"},
+	{3, 2460, "seqFight",        0, 0,   60, "2460-F~1.IMX"},
 	{0, 2465, "seqLAVE_RIDE",    0, 0,    0, ""},
 	{0, 2470, "seqMORE_SLAW",    0, 0,    0, ""},
 	{0, 2475, "seqLIFT_CURSE",   0, 0,    0, ""},
-	{3, 2500, "seqInterlude5",   0, 0, 1000, "2500-I~1.IMX"},
-	{3, 2502, "seqExitSkycar",   0, 0, 1000, "2502-E~1.IMX"},
-	{3, 2504, "seqGrow1",        0, 0, 1000, "2504-G~1.IMX"},
-	{2, 2505, "seqGrow2",        0, 1, 1000, "2504-G~1.IMX"},
-	{3, 2508, "seqInterlude6",   0, 0, 1000, "2508-I~1.IMX"},
+	{3, 2500, "seqInterlude5",   0, 0,   60, "2500-I~1.IMX"},
+	{3, 2502, "seqExitSkycar",   0, 0,   60, "2502-E~1.IMX"},
+	{3, 2504, "seqGrow1",        0, 0,   60, "2504-G~1.IMX"},
+	{2, 2505, "seqGrow2",        0, 1,   60, "2504-G~1.IMX"},
+	{3, 2508, "seqInterlude6",   0, 0,   60, "2508-I~1.IMX"},
 	{0, 2515, "seqFINALE",       0, 0,    0, ""},
-	{3, 2520, "seqOut",          0, 0, 1000, "2520-OUT.IMX"},
-	{3, 2530, "seqZap1a",        0, 0, 1000, "2530-Z~1.IMX"},
-	{2, 2531, "seqZap1b",        0, 1, 1000, "2530-Z~1.IMX"},
-	{2, 2532, "seqZap1c",        0, 2, 1000, "2530-Z~1.IMX"},
-	{2, 2540, "seqZap2a",        0, 0, 1000, "2540-Z~1.IMX"},
-	{2, 2541, "seqZap2b",        0, 1, 1000, "2540-Z~1.IMX"},
-	{2, 2542, "seqZap2c",        0, 2, 1000, "2540-Z~1.IMX"},
-	{3, 2550, "seqZap3a",        0, 0, 1000, "2550-Z~1.IMX"},
-	{2, 2551, "seqZap3b",        0, 1, 1000, "2550-Z~1.IMX"},
-	{2, 2552, "seqZap3c",        0, 2, 1000, "2550-Z~1.IMX"},
-	{3, 2560, "seqZap4a",        0, 0, 1000, "2560-Z~1.IMX"},
-	{2, 2561, "seqZap4b",        0, 1, 1000, "2560-Z~1.IMX"},
-	{2, 2562, "seqZap4c",        0, 2, 1000, "2560-Z~1.IMX"},
+	{3, 2520, "seqOut",          0, 0,   60, "2520-OUT.IMX"},
+	{3, 2530, "seqZap1a",        0, 0,   60, "2530-Z~1.IMX"},
+	{2, 2531, "seqZap1b",        0, 1,   60, "2530-Z~1.IMX"},
+	{2, 2532, "seqZap1c",        0, 2,   60, "2530-Z~1.IMX"},
+	{2, 2540, "seqZap2a",        0, 0,   60, "2540-Z~1.IMX"},
+	{2, 2541, "seqZap2b",        0, 1,   60, "2540-Z~1.IMX"},
+	{2, 2542, "seqZap2c",        0, 2,   60, "2540-Z~1.IMX"},
+	{3, 2550, "seqZap3a",        0, 0,   60, "2550-Z~1.IMX"},
+	{2, 2551, "seqZap3b",        0, 1,   60, "2550-Z~1.IMX"},
+	{2, 2552, "seqZap3c",        0, 2,   60, "2550-Z~1.IMX"},
+	{3, 2560, "seqZap4a",        0, 0,   60, "2560-Z~1.IMX"},
+	{2, 2561, "seqZap4b",        0, 1,   60, "2560-Z~1.IMX"},
+	{2, 2562, "seqZap4c",        0, 2,   60, "2560-Z~1.IMX"},
 	{0,   -1, "",                0, 0,    0, ""}
 };
 





More information about the Scummvm-git-logs mailing list