[Scummvm-cvs-logs] CVS: scummvm/scumm bundle.cpp,1.49,1.50 imuse_digi.cpp,1.64,1.65 imuse_digi.h,1.18,1.19 resource.cpp,1.176,1.177 saveload.cpp,1.123,1.124 script_v8.cpp,2.205,2.206 sound.cpp,1.285,1.286 sound.h,1.55,1.56 string.cpp,1.170,1.171

Max Horn fingolfin at users.sourceforge.net
Mon Dec 22 00:23:01 CET 2003


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

Modified Files:
	bundle.cpp imuse_digi.cpp imuse_digi.h resource.cpp 
	saveload.cpp script_v8.cpp sound.cpp sound.h string.cpp 
Log Message:
Moved bundle music code from class Sound to IMuseDigital (seems more natural; and allows for various cleanup)

Index: bundle.cpp
===================================================================
RCS file: /cvsroot/scummvm/scummvm/scumm/bundle.cpp,v
retrieving revision 1.49
retrieving revision 1.50
diff -u -d -r1.49 -r1.50
--- bundle.cpp	16 Nov 2003 20:52:56 -0000	1.49
+++ bundle.cpp	22 Dec 2003 08:22:03 -0000	1.50
@@ -93,7 +93,7 @@
 	}
 };
 
-const byte imxShortTable[] = {
+static const byte imxShortTable[] = {
 	0, 0, 1, 3, 7, 15, 31, 63
 };
 
@@ -436,12 +436,16 @@
 	return number;
 }
 
-#define NextBit bit = mask & 1; mask >>= 1;				\
-								if (!--bitsleft) {								\
-									mask = READ_LE_UINT16(srcptr);	\
-									srcptr += 2;										\
-									bitsleft = 16;									\
-								}
+#define NextBit                            \
+	do {                                   \
+		bit = mask & 1;                    \
+		mask >>= 1;                        \
+		if (!--bitsleft) {                 \
+			mask = READ_LE_UINT16(srcptr); \
+			srcptr += 2;                   \
+			bitsleft = 16;                 \
+		}                                  \
+	} while (0)
 
 static int32 compDecode(byte *src, byte *dst) {
 	byte *result, *srcptr = src, *dstptr = dst;
@@ -449,12 +453,16 @@
 	srcptr += 2;
 
 	while (1) {
-		NextBit if (bit) {
+		NextBit;
+		if (bit) {
 			*dstptr++ = *srcptr++;
 		} else {
-			NextBit if (!bit) {
-				NextBit size = bit << 1;
-				NextBit size = (size | bit) + 3;
+			NextBit;
+			if (!bit) {
+				NextBit;
+				size = bit << 1;
+				NextBit;
+				size = (size | bit) + 3;
 				data = *srcptr++ | 0xffffff00;
 			} else {
 				data = *srcptr++;

Index: imuse_digi.cpp
===================================================================
RCS file: /cvsroot/scummvm/scummvm/scumm/imuse_digi.cpp,v
retrieving revision 1.64
retrieving revision 1.65
diff -u -d -r1.64 -r1.65
--- imuse_digi.cpp	21 Dec 2003 01:17:02 -0000	1.64
+++ imuse_digi.cpp	22 Dec 2003 08:22:03 -0000	1.65
@@ -20,6 +20,8 @@
 
 #include "stdafx.h"
 #include "common/timer.h"
+#include "scumm/actor.h"
+#include "scumm/bundle.h"
 #include "scumm/imuse_digi.h"
 #include "scumm/scumm.h"
 #include "scumm/sound.h"
@@ -684,6 +686,37 @@
 	return ret_sound;
 }
 
+static uint32 decode12BitsSample(byte *src, byte **dst, uint32 size, bool stereo) {
+	uint32 s_size = (size / 3) * 4;
+	uint32 loop_size = s_size / 4;
+	if (stereo) {
+		s_size *= 2;
+	}
+	byte *ptr = *dst = (byte *)malloc(s_size);
+
+	uint32 tmp;
+	while (loop_size--) {
+		byte v1 = *src++;
+		byte v2 = *src++;
+		byte v3 = *src++;
+		tmp = ((((v2 & 0x0f) << 8) | v1) << 4) - 0x8000;
+		*ptr++ = (byte)((tmp >> 8) & 0xff);
+		*ptr++ = (byte)(tmp & 0xff);
+		if (stereo) {
+			*ptr++ = (byte)((tmp >> 8) & 0xff);
+			*ptr++ = (byte)(tmp & 0xff);
+		}
+		tmp = ((((v2 & 0xf0) << 4) | v3) << 4) - 0x8000;
+		*ptr++ = (byte)((tmp >> 8) & 0xff);
+		*ptr++ = (byte)(tmp & 0xff);
+		if (stereo) {
+			*ptr++ = (byte)((tmp >> 8) & 0xff);
+			*ptr++ = (byte)(tmp & 0xff);
+		}
+	}
+	return s_size;
+}
+
 void IMuseDigital::timer_handler(void *refCon) {
 	IMuseDigital *imuseDigital = (IMuseDigital *)refCon;
 	imuseDigital->musicTimer();
@@ -697,6 +730,13 @@
 	}
 	_scumm->_timer->installTimerProc(timer_handler, 200000, this);
 	_pause = false;
+
+	_nameBundleMusic = "";
+	_musicBundleBufFinal = NULL;
+	_musicBundleBufOutput = NULL;
+	_musicDisk = 0;
+	
+	_bundle = new Bundle();
 }
 
 IMuseDigital::~IMuseDigital() {
@@ -705,6 +745,8 @@
 	for (int l = 0; l < MAX_DIGITAL_CHANNELS; l++) {
 		_scumm->_mixer->stopHandle(_channel[l]._handle);
 	}
+
+	delete _bundle;
 }
 
 void IMuseDigital::musicTimer() {
@@ -883,7 +925,7 @@
 				if (_channel[l]._bits == 12) {
 					_channel[l]._mixerSize *= 2;
 					_channel[l]._mixerFlags |= SoundMixer::FLAG_16BITS;
-					_channel[l]._size = _scumm->_sound->decode12BitsSample(ptr, &_channel[l]._data, size, (_channel[l]._channels == 2) ? false : true);
+					_channel[l]._size = decode12BitsSample(ptr, &_channel[l]._data, size, (_channel[l]._channels == 2) ? false : true);
 				} else if (_channel[l]._bits == 8) {
 					_channel[l]._mixerFlags |= SoundMixer::FLAG_UNSIGNED;
 					if (_channel[l]._channels == 1) {
@@ -928,6 +970,7 @@
 
 void IMuseDigital::pause(bool p) {
 	_pause = p;
+	pauseBundleMusic(p);
 }
 
 int32 IMuseDigital::doCommand(int a, int b, int c, int d, int e, int f, int g, int h) {
@@ -1041,7 +1084,7 @@
 		}
 		if (_scumm->_gameId == GID_DIG) {
 			if (b == 1000) {		// STATE_NULL
-				_scumm->_sound->stopBundleMusic();
+				stopBundleMusic();
 				return 0;
 			}
 			for (l = 0;; l++) {
@@ -1052,30 +1095,30 @@
 					int music = _digStateMusicMap[l].table_index;
 					debug(5, "Play imuse music: %s, %s, %s", _digStateMusicTable[music].name, _digStateMusicTable[music].title, _digStateMusicTable[music].filename);
 					if ((_digStateMusicTable[music].filename[0] != 0) && 
-						(strcmp(_digStateMusicTable[_digStateMusicTable[music].unk3].filename, _scumm->_sound->_nameBundleMusic) != 0) ) {
-						_scumm->_sound->playBundleMusic(_digStateMusicTable[music].filename);
+						(strcmp(_digStateMusicTable[_digStateMusicTable[music].unk3].filename, _nameBundleMusic) != 0) ) {
+						playBundleMusic(_digStateMusicTable[music].filename);
 					}
 					return 0;
 				}
 			}
 		} else if ((_scumm->_gameId == GID_CMI) && (_scumm->_features & GF_DEMO)) {
 			if (b == 2) {
-				_scumm->_sound->playBundleMusic("in1.imx");
+				playBundleMusic("in1.imx");
 			} else if (b == 4) {
-				_scumm->_sound->playBundleMusic("in2.imx");
+				playBundleMusic("in2.imx");
 			} else if (b == 8) {
-				_scumm->_sound->playBundleMusic("out1.imx");
+				playBundleMusic("out1.imx");
 			} else if (b == 9) {
-				_scumm->_sound->playBundleMusic("out2.imx");
+				playBundleMusic("out2.imx");
 			} else if (b == 16) {
-				_scumm->_sound->playBundleMusic("gun.imx");
+				playBundleMusic("gun.imx");
 			} else {
 				warning("imuse digital: set state unknown for cmi demo: %d, room: %d", b, this->_scumm->_currentRoom);
 				return 1;
 			}
 		} else if (_scumm->_gameId == GID_CMI) {
 			if (b == 1000) {		// STATE_NULL
-				_scumm->_sound->stopBundleMusic();
+				stopBundleMusic();
 				return 0;
 			}
 			for (l = 0;; l++) {
@@ -1085,7 +1128,7 @@
 				if ((_comiStateMusicTable[l].id == b)) {
 					debug(5, "Play imuse music: %s, %s, %s", _comiStateMusicTable[l].name, _comiStateMusicTable[l].title, _comiStateMusicTable[l].filename);
 					if (_comiStateMusicTable[l].filename[0] != 0) {
-						_scumm->_sound->playBundleMusic(_comiStateMusicTable[l].filename);
+						playBundleMusic(_comiStateMusicTable[l].filename);
 					}
 					return 0;
 				}
@@ -1119,7 +1162,7 @@
 				if ((_digSeqMusicTable[l].room == b)) {
 					debug(5, "Play imuse music: %s, %s, %s", _digSeqMusicTable[l].name, _digSeqMusicTable[l].title, _digSeqMusicTable[l].filename);
 					if (_digSeqMusicTable[l].filename[0] != 0) {
-						_scumm->_sound->playBundleMusic(_digSeqMusicTable[l].filename);
+						playBundleMusic(_digSeqMusicTable[l].filename);
 					}
 					return 0;
 				}
@@ -1132,7 +1175,7 @@
 				if ((_comiSeqMusicTable[l].id == b)) {
 					debug(5, "Play imuse music: %s, %s, %s", _comiSeqMusicTable[l].name, _comiSeqMusicTable[l].title, _comiSeqMusicTable[l].filename);
 					if (_comiSeqMusicTable[l].filename[0] != 0) {
-						_scumm->_sound->playBundleMusic(_comiSeqMusicTable[l].filename);
+						playBundleMusic(_comiSeqMusicTable[l].filename);
 					}
 					return 0;
 				}
@@ -1187,6 +1230,318 @@
 
 	return 0;
 }
+
+#pragma mark -
+
+void IMuseDigital::music_handler(void *refCon) {
+	((IMuseDigital *)refCon)->bundleMusicHandler();
+}
+
+void IMuseDigital::playBundleMusic(const char *song) {
+	if (_scumm->_silentDigitalImuse) {
+		return;
+	}
+
+	if (_nameBundleMusic[0] == 0) {
+		if (_scumm->_gameId == GID_CMI) {
+			_outputMixerSize = (22050 * 2 * 2);
+
+			char bunfile[20];
+			if (_scumm->_features & GF_DEMO) {
+				if (_bundle->openMusicFile("music.bun", _scumm->getGameDataPath()) == false) {
+					_outputMixerSize = 0;
+					return;
+				}
+			} else {
+
+				sprintf(bunfile, "musdisk%d.bun", _scumm->VAR(_scumm->VAR_CURRENTDISK));
+				if (_musicDisk != _scumm->VAR(_scumm->VAR_CURRENTDISK)) 
+					_bundle->closeMusicFile();
+
+				if (_bundle->openMusicFile(bunfile, _scumm->getGameDataPath()) == false) {
+					if (_bundle->openMusicFile("music.bun", _scumm->getGameDataPath()) == false) {
+						_outputMixerSize = 0;
+						return;
+					}
+				}
+
+				_musicDisk = (byte)_scumm->VAR(_scumm->VAR_CURRENTDISK);
+			}
+		} else {
+			_outputMixerSize = ((22050 * 2 * 2) / 4) * 3;
+
+			if (_bundle->openMusicFile("digmusic.bun", _scumm->getGameDataPath()) == false)
+				return;
+		}
+		_musicBundleBufFinal = (byte *)malloc(_outputMixerSize);
+		_musicBundleBufOutput = (byte *)malloc(((_outputMixerSize / 0x2000) + 1) * _outputMixerSize);
+		_currentSampleBundleMusic = 0;
+		_offsetSampleBundleMusic = 0;
+		_offsetBufBundleMusic = 0;
+		_bundleMusicPosition = 0;
+		_bundleSongPosInMs = 0;
+		_pauseBundleMusic = false;
+		_musicBundleToBeChanged = false;
+		_bundleMusicTrack = 0;
+		_numberSamplesBundleMusic = _bundle->getNumberOfMusicSamplesByName(song);
+		_nameBundleMusic = song;
+		_scumm->_timer->installTimerProc(&music_handler, 1000000, this);
+	} else if (strcmp(_nameBundleMusic, song) != 0) {
+		_newNameBundleMusic = song;
+		_musicBundleToBeChanged = true;
+	}
+}
+
+void IMuseDigital::pauseBundleMusic(bool state) {
+	_pauseBundleMusic = state;
+}
+
+void IMuseDigital::stopBundleMusic() {
+	// First stop the music timer
+	_scumm->_timer->removeTimerProc(&music_handler);
+	_nameBundleMusic = "";
+	_scumm->_mixer->stopHandle(_bundleMusicTrack);
+	if (_musicBundleBufFinal) {
+		free(_musicBundleBufFinal);
+		_musicBundleBufFinal = NULL;
+	}
+	if (_musicBundleBufOutput) {
+		free(_musicBundleBufOutput);
+		_musicBundleBufOutput = NULL;
+	}
+}
+
+void IMuseDigital::bundleMusicHandler() {
+	byte *ptr;
+	int32 l, num = _numberSamplesBundleMusic, length, k;
+	int32 rate = 22050;
+	int32 tag, size = -1, header_size = 0;
+
+	if (_pauseBundleMusic)
+		return;
+
+	if (_musicBundleToBeChanged) {
+		_nameBundleMusic = _newNameBundleMusic;
+		_numberSamplesBundleMusic = _bundle->getNumberOfMusicSamplesByName(_nameBundleMusic);
+		_currentSampleBundleMusic = 0;
+		_offsetSampleBundleMusic = 0;
+		_offsetBufBundleMusic = 0;
+		_musicBundleToBeChanged = false;
+		_bundleMusicPosition = 0;
+		_bundleSongPosInMs = 0;
+	}
+
+	ptr = _musicBundleBufOutput;
+
+	for (k = 0, l = _currentSampleBundleMusic; l < num; k++) {
+		length = _bundle->decompressMusicSampleByName(_nameBundleMusic, l, (_musicBundleBufOutput + ((k * 0x2000) + _offsetBufBundleMusic)));
+		_offsetSampleBundleMusic += length;
+
+		if (l == 0) {
+			tag = READ_BE_UINT32(ptr); ptr += 4;
+			if (tag != MKID_BE('iMUS')) {
+				error("Decompressing bundle song failed (unknown tag '%s')", tag2str(tag));
+			}
+
+			ptr += 12;
+			while (tag != MKID_BE('DATA')) {
+				tag = READ_BE_UINT32(ptr);  ptr += 4;
+				switch(tag) {
+				case MKID_BE('FRMT'):
+					ptr += 12;
+					_bundleMusicSampleBits = READ_BE_UINT32(ptr); ptr += 4;
+					rate = READ_BE_UINT32(ptr); ptr += 4;
+					_bundleSampleChannels = READ_BE_UINT32(ptr); ptr += 4;
+				break;
+				case MKID_BE('TEXT'):
+				case MKID_BE('REGN'):
+				case MKID_BE('STOP'):
+				case MKID_BE('JUMP'):
+				case MKID_BE('SYNC'):
+					size = READ_BE_UINT32(ptr); ptr += size + 4;
+				break;
+					case MKID_BE('DATA'):
+					size = READ_BE_UINT32(ptr); ptr += 4;
+				break;
+
+				default:
+					error("Unknown sound header %c%c%c%c",
+						(byte)(tag >> 24),
+						(byte)(tag >> 16),
+						(byte)(tag >> 8),
+						(byte)tag);
+				}
+			}
+			if (size < 0) {
+				error("Decompressing sound failed (missing size field)");
+			}
+			header_size = (ptr - _musicBundleBufOutput);
+		}
+
+		l++;
+		_currentSampleBundleMusic = l;
+
+		if (_offsetSampleBundleMusic >= _outputMixerSize + header_size) {
+			memcpy(_musicBundleBufFinal, (_musicBundleBufOutput + header_size), _outputMixerSize);
+			_offsetBufBundleMusic = _offsetSampleBundleMusic - _outputMixerSize - header_size;
+			memcpy(_musicBundleBufOutput, (_musicBundleBufOutput + (_outputMixerSize + header_size)), _offsetBufBundleMusic);
+			_offsetSampleBundleMusic = _offsetBufBundleMusic;
+			break;
+		}
+	}
+
+	if (_currentSampleBundleMusic == num) {
+		_currentSampleBundleMusic = 0;
+		_offsetSampleBundleMusic = 0;
+		_offsetBufBundleMusic = 0;
+		_bundleMusicPosition = 0;
+		_bundleSongPosInMs = 0;
+	}
+
+	ptr = _musicBundleBufFinal;
+
+	byte *buffer = NULL;
+	uint32 final_size;
+	if (_bundleMusicSampleBits == 12) {
+		final_size = decode12BitsSample(ptr, &buffer, _outputMixerSize, false);
+	} else if (_bundleMusicSampleBits == 16) {
+		buffer = (byte *)malloc(_outputMixerSize);
+		final_size = _outputMixerSize;
+		memcpy(buffer, ptr, _outputMixerSize);
+	} else {
+		warning("IMuseDigital::bundleMusicHandler TODO: more newStream options...");
+		return;
+	}
+
+	_bundleSongPosInMs = (_bundleMusicPosition * 5) / (_outputMixerSize / 200);
+	_bundleMusicPosition += final_size;
+	if (_bundleMusicTrack == 0)
+		_scumm->_mixer->newStream(&_bundleMusicTrack, rate, SoundMixer::FLAG_16BITS | SoundMixer::FLAG_STEREO, 300000);
+	_scumm->_mixer->appendStream(_bundleMusicTrack, buffer, final_size);
+	free(buffer);
+}
+
+void IMuseDigital::playBundleSound(const char *sound, PlayingSoundHandle *handle) {
+	byte *ptr = 0, *orig_ptr = 0;
+	byte *final;
+	bool result;
+
+	if (_scumm->_noDigitalSamples)
+		return;	
+
+	if (_scumm->_gameId == GID_CMI) {
+		if (_scumm->_features & GF_DEMO) {
+			result = _bundle->openVoiceFile("voice.bun", _scumm->getGameDataPath());
+		} else {
+			char voxfile[20];
+			sprintf(voxfile, "voxdisk%d.bun", _scumm->VAR(_scumm->VAR_CURRENTDISK));
+			if (_voiceDisk != _scumm->VAR(_scumm->VAR_CURRENTDISK))
+				_bundle->closeVoiceFile();
+
+			result = _bundle->openVoiceFile(voxfile, _scumm->getGameDataPath());
+
+			if (result == false) 
+				result = _bundle->openVoiceFile("voice.bun", _scumm->getGameDataPath());
+			_voiceDisk = (byte)_scumm->VAR(_scumm->VAR_CURRENTDISK);
+		}
+	} else if (_scumm->_gameId == GID_DIG)
+		result = _bundle->openVoiceFile("digvoice.bun", _scumm->getGameDataPath());
+	else
+		error("Don't know which bundle file to load");
+
+	if (!result)
+		return;
+
+	int32 rate = 22050, pan = 0, channels, output_size = 0;
+	int32 tag, size = -1, bits = 0;
+
+	if (_scumm->_gameId == GID_CMI) {
+		char name[20];
+		strcpy(name, sound);
+		if (!(_scumm->_features & GF_DEMO)) // CMI demo does not have .IMX for voice but does for music...
+			strcat(name, ".IMX");
+		output_size = _bundle->decompressVoiceSampleByName(name, &ptr);
+	} else {
+		output_size = _bundle->decompressVoiceSampleByName(sound, &ptr);
+	}
+
+	orig_ptr = ptr;
+	if (output_size == 0 || orig_ptr == 0) {
+		goto bail;
+	}
+
+	tag = READ_BE_UINT32(ptr); ptr += 4;
+	if (tag != MKID_BE('iMUS')) {
+		warning("Decompression of bundle sound failed");
+		goto bail;
+	}
+
+	ptr += 12;
+	while (tag != MKID_BE('DATA')) {
+		tag = READ_BE_UINT32(ptr); ptr += 4;
+		switch(tag) {
+		case MKID_BE('FRMT'):
+			ptr += 12;
+			bits = READ_BE_UINT32(ptr); ptr += 4;
+			rate = READ_BE_UINT32(ptr); ptr += 4;
+			channels = READ_BE_UINT32(ptr); ptr += 4;
+			break;
+		case MKID_BE('TEXT'):
+		case MKID_BE('REGN'):
+		case MKID_BE('STOP'):
+		case MKID_BE('JUMP'):
+		case MKID_BE('SYNC'):
+			size = READ_BE_UINT32(ptr); ptr += size + 4;
+			break;
+		case MKID_BE('DATA'):
+			size = READ_BE_UINT32(ptr); ptr += 4;
+			break;
+		default:
+			error("Unknown sound header %c%c%c%c",
+				(byte)(tag >> 24),
+				(byte)(tag >> 16),
+				(byte)(tag >> 8),
+				(byte)tag);
+		}
+	}
+
+	if (size < 0) {
+		warning("Decompression sound failed (no size field)");
+		goto bail;
+	}
+
+	final = (byte *)malloc(size);
+	memcpy(final, ptr, size);
+
+	if (_scumm->_actorToPrintStrFor != 0xFF && _scumm->_actorToPrintStrFor != 0) {
+		Actor *a = _scumm->derefActor(_scumm->_actorToPrintStrFor, "playBundleSound");
+		rate = (rate * a->talkFrequency) / 256;
+
+		// Adjust to fit the mixer's notion of panning.
+		if (pan != 64)
+			pan = 2 * a->talkPan - 127;
+	}
+	
+	// Stop any sound currently playing on the given handle
+	if (handle)
+		_scumm->_mixer->stopHandle(*handle);
+
+	if (bits == 8) {
+		_scumm->_mixer->playRaw(handle, final, size, rate, SoundMixer::FLAG_UNSIGNED | SoundMixer::FLAG_AUTOFREE, -1, 255, pan);
+	} else if (bits == 16) {
+		// FIXME: For some weird reasons, sometimes we get an odd size, even though
+		// the data is supposed to be in 16 bit format... that makes no sense...
+		size &= ~1;
+		_scumm->_mixer->playRaw(handle, final, size, rate, SoundMixer::FLAG_16BITS | SoundMixer::FLAG_AUTOFREE, -1, 255, pan);
+	} else {
+		warning("IMuseDigital::playBundleSound() to do more options to playRaw...");
+	}
+	
+bail:
+	free(orig_ptr);
+}
+
+
 
 } // End of namespace Scumm
 

Index: imuse_digi.h
===================================================================
RCS file: /cvsroot/scummvm/scummvm/scumm/imuse_digi.h,v
retrieving revision 1.18
retrieving revision 1.19
diff -u -d -r1.18 -r1.19
--- imuse_digi.h	21 Dec 2003 01:17:02 -0000	1.18
+++ imuse_digi.h	22 Dec 2003 08:22:03 -0000	1.19
@@ -34,6 +34,7 @@
 #define MAX_IMUSE_REGIONS 3
 
 class ScummEngine;
+class Bundle;
 
 /**
  * iMuse Digital Implementation for SCUMM v7 and higher.
@@ -68,8 +69,42 @@
 	ScummEngine *_scumm;
 	bool _pause;
 
-	static void timer_handler(void *engine);
+	static void timer_handler(void *refConf);
 	void musicTimer();
+
+	//
+	// Bundle music
+	//
+	const char *_nameBundleMusic;
+	const char *_newNameBundleMusic;
+	byte _musicDisk;
+	byte _voiceDisk;
+	int32 _currentSampleBundleMusic;
+	int32 _numberSamplesBundleMusic;
+	int32 _offsetSampleBundleMusic;
+	int32 _offsetBufBundleMusic;
+	byte *_musicBundleBufFinal;
+	byte *_musicBundleBufOutput;
+	bool _pauseBundleMusic;
+	PlayingSoundHandle _bundleMusicTrack;
+	bool _musicBundleToBeChanged;
+	int32 _bundleMusicSampleBits;
+	int32 _outputMixerSize;
+	int32 _bundleSampleChannels;
+	int32 _bundleMusicPosition;
+
+	static void music_handler(void *refCon);
+	void bundleMusicHandler();
+
+	void playBundleMusic(const char *song);
+	void pauseBundleMusic(bool state);
+
+public:
+	int32 _bundleSongPosInMs;
+	Bundle *_bundle;	// FIXME: should be protected but is used by ScummEngine::askForDisk
+
+	void stopBundleMusic();
+	void playBundleSound(const char *sound, PlayingSoundHandle *handle);
 
 public:
 	IMuseDigital(ScummEngine *scumm);

Index: resource.cpp
===================================================================
RCS file: /cvsroot/scummvm/scummvm/scumm/resource.cpp,v
retrieving revision 1.176
retrieving revision 1.177
diff -u -d -r1.176 -r1.177
--- resource.cpp	28 Nov 2003 22:29:56 -0000	1.176
+++ resource.cpp	22 Dec 2003 08:22:03 -0000	1.177
@@ -26,6 +26,7 @@
 #include "scumm/bundle.h"
 #include "scumm/dialogs.h"
 #include "scumm/imuse.h"
+#include "scumm/imuse_digi.h"
 #include "scumm/object.h"
 #include "scumm/resource.h"
 #include "scumm/scumm.h"
@@ -227,8 +228,8 @@
 	if (_version == 8) {
 		char result;
 
-		_sound->_bundle->closeVoiceFile();
-		_sound->_bundle->closeMusicFile();
+		_imuseDigital->_bundle->closeVoiceFile();
+		_imuseDigital->_bundle->closeMusicFile();
 
 #ifdef MACOSX
 		sprintf(buf, "Cannot find file: '%s'\nPlease insert disc %d.\nHit OK to retry, Cancel to exit", filename, disknum);

Index: saveload.cpp
===================================================================
RCS file: /cvsroot/scummvm/scummvm/scumm/saveload.cpp,v
retrieving revision 1.123
retrieving revision 1.124
diff -u -d -r1.123 -r1.124
--- saveload.cpp	15 Dec 2003 14:54:35 -0000	1.123
+++ saveload.cpp	22 Dec 2003 08:22:03 -0000	1.124
@@ -126,7 +126,8 @@
 	memcpy(_saveLoadName, hdr.name, sizeof(hdr.name));
 
 	_sound->stopAllSounds();
-	_sound->stopBundleMusic();
+	if (_imuseDigital)
+		_imuseDigital->stopBundleMusic();
 	_sound->stopCD();
 
 	_sound->pauseSounds(true);

Index: script_v8.cpp
===================================================================
RCS file: /cvsroot/scummvm/scummvm/scumm/script_v8.cpp,v
retrieving revision 2.205
retrieving revision 2.206
diff -u -d -r2.205 -r2.206
--- script_v8.cpp	5 Dec 2003 00:02:00 -0000	2.205
+++ script_v8.cpp	22 Dec 2003 08:22:03 -0000	2.206
@@ -24,6 +24,7 @@
 #include "scumm/actor.h"
 #include "scumm/akos.h"
 #include "scumm/charset.h"
+#include "scumm/imuse_digi.h"
 #include "scumm/intern.h"
 #include "scumm/object.h"
 #include "scumm/resource.h"
@@ -1483,7 +1484,7 @@
 	case 0xE1:		// imGetMusicPosition
 		warning("o8_kernelGetFunctions: imGetMusicPosition(stub)");
 		// FIXME - get this stuff to be properly implemented
-		push(_sound->_bundleSongPosInMs);
+		push(_imuseDigital->_bundleSongPosInMs);
 		break;
 	case 0xE2:		// musicLipSyncWidth
 	case 0xE3:		// musicLipSyncHeight

Index: sound.cpp
===================================================================
RCS file: /cvsroot/scummvm/scummvm/scumm/sound.cpp,v
retrieving revision 1.285
retrieving revision 1.286
diff -u -d -r1.285 -r1.286
--- sound.cpp	21 Dec 2003 16:01:38 -0000	1.285
+++ sound.cpp	22 Dec 2003 08:22:03 -0000	1.286
@@ -22,7 +22,6 @@
 
 #include "stdafx.h"
 #include "scumm/actor.h"
-#include "scumm/bundle.h"
 #include "scumm/imuse.h"
 #include "scumm/imuse_digi.h"
 #include "scumm/scumm.h"
@@ -57,21 +56,14 @@
 	memset(this,0,sizeof(Sound));	// palmos
 	
 	_scumm = parent;
-	_nameBundleMusic = "";
-	_musicBundleBufFinal = NULL;
-	_musicBundleBufOutput = NULL;
-	_musicDisk = 0;
 	_talkChannelHandle = 0;
 	_currentCDSound = 0;
 
 	_sfxFile = 0;
-	
-	_bundle = new Bundle();
 }
 
 Sound::~Sound() {
 	delete _sfxFile;
-	delete _bundle;
 }
 
 void Sound::addSoundToQueue(int sound) {
@@ -821,8 +813,6 @@
 
 	_scumm->_mixer->pauseAll(pause);
 
-	_scumm->_sound->pauseBundleMusic(pause);
-
 	if (_scumm->_imuseDigital) {
 		_scumm->_imuseDigital->pause(pause);
 	}
@@ -976,346 +966,6 @@
 
 bool Sound::isSfxFinished() const {
 	return !_scumm->_mixer->hasActiveSFXChannel();
-}
-
-uint32 Sound::decode12BitsSample(byte *src, byte **dst, uint32 size, bool stereo) {
-	uint32 s_size = (size / 3) * 4;
-	uint32 loop_size = s_size / 4;
-	if (stereo) {
-		s_size *= 2;
-	}
-	byte *ptr = *dst = (byte *)malloc(s_size);
-
-	uint32 tmp;
-	while (loop_size--) {
-		byte v1 = *src++;
-		byte v2 = *src++;
-		byte v3 = *src++;
-		tmp = ((((v2 & 0x0f) << 8) | v1) << 4) - 0x8000;
-		*ptr++ = (byte)((tmp >> 8) & 0xff);
-		*ptr++ = (byte)(tmp & 0xff);
-		if (stereo) {
-			*ptr++ = (byte)((tmp >> 8) & 0xff);
-			*ptr++ = (byte)(tmp & 0xff);
-		}
-		tmp = ((((v2 & 0xf0) << 4) | v3) << 4) - 0x8000;
-		*ptr++ = (byte)((tmp >> 8) & 0xff);
-		*ptr++ = (byte)(tmp & 0xff);
-		if (stereo) {
-			*ptr++ = (byte)((tmp >> 8) & 0xff);
-			*ptr++ = (byte)(tmp & 0xff);
-		}
-	}
-	return s_size;
-}
-
-static void music_handler(void *refCon) {
-	Sound *sound = (Sound *)refCon;
-	sound->bundleMusicHandler(g_scumm);
-}
-
-void Sound::playBundleMusic(const char *song) {
-	if (_scumm->_silentDigitalImuse) {
-		return;
-	}
-
-	if (_nameBundleMusic[0] == 0) {
-		if (_scumm->_gameId == GID_CMI) {
-			_outputMixerSize = (22050 * 2 * 2);
-
-			char bunfile[20];
-			if (_scumm->_features & GF_DEMO) {
-				if (_bundle->openMusicFile("music.bun", _scumm->getGameDataPath()) == false) {
-					_outputMixerSize = 0;
-					return;
-				}
-			} else {
-
-				sprintf(bunfile, "musdisk%d.bun", _scumm->VAR(_scumm->VAR_CURRENTDISK));
-				if (_musicDisk != _scumm->VAR(_scumm->VAR_CURRENTDISK)) 
-					_bundle->closeMusicFile();
-
-				if (_bundle->openMusicFile(bunfile, _scumm->getGameDataPath()) == false) {
-					if (_bundle->openMusicFile("music.bun", _scumm->getGameDataPath()) == false) {
-						_outputMixerSize = 0;
-						return;
-					}
-				}
-
-				_musicDisk = (byte)_scumm->VAR(_scumm->VAR_CURRENTDISK);
-			}
-		} else {
-			_outputMixerSize = ((22050 * 2 * 2) / 4) * 3;
-
-			if (_bundle->openMusicFile("digmusic.bun", _scumm->getGameDataPath()) == false)
-				return;
-		}
-		_musicBundleBufFinal = (byte *)malloc(_outputMixerSize);
-		_musicBundleBufOutput = (byte *)malloc(((_outputMixerSize / 0x2000) + 1) * _outputMixerSize);
-		_currentSampleBundleMusic = 0;
-		_offsetSampleBundleMusic = 0;
-		_offsetBufBundleMusic = 0;
-		_bundleMusicPosition = 0;
-		_bundleSongPosInMs = 0;
-		_pauseBundleMusic = false;
-		_musicBundleToBeChanged = false;
-		_bundleMusicTrack = 0;
-		_numberSamplesBundleMusic = _bundle->getNumberOfMusicSamplesByName(song);
-		_nameBundleMusic = song;
-		_scumm->_timer->installTimerProc(&music_handler, 1000000, this);
-	} else if (strcmp(_nameBundleMusic, song) != 0) {
-		_newNameBundleMusic = song;
-		_musicBundleToBeChanged = true;
-	}
-}
-
-void Sound::pauseBundleMusic(bool state) {
-	_pauseBundleMusic = state;
-}
-
-void Sound::stopBundleMusic() {
-	// First stop the music timer
-	_scumm->_timer->removeTimerProc(&music_handler);
-	_nameBundleMusic = "";
-	_scumm->_mixer->stopHandle(_bundleMusicTrack);
-	if (_musicBundleBufFinal) {
-		free(_musicBundleBufFinal);
-		_musicBundleBufFinal = NULL;
-	}
-	if (_musicBundleBufOutput) {
-		free(_musicBundleBufOutput);
-		_musicBundleBufOutput = NULL;
-	}
-}
-
-void Sound::bundleMusicHandler(ScummEngine *scumm) {
-	byte *ptr;
-	int32 l, num = _numberSamplesBundleMusic, length, k;
-	int32 rate = 22050;
-	int32 tag, size = -1, header_size = 0;
-
-	if (_pauseBundleMusic)
-		return;
-
-	if (_musicBundleToBeChanged) {
-		_nameBundleMusic = _newNameBundleMusic;
-		_numberSamplesBundleMusic = _bundle->getNumberOfMusicSamplesByName(_nameBundleMusic);
-		_currentSampleBundleMusic = 0;
-		_offsetSampleBundleMusic = 0;
-		_offsetBufBundleMusic = 0;
-		_musicBundleToBeChanged = false;
-		_bundleMusicPosition = 0;
-		_bundleSongPosInMs = 0;
-	}
-
-	ptr = _musicBundleBufOutput;
-
-	for (k = 0, l = _currentSampleBundleMusic; l < num; k++) {
-		length = _bundle->decompressMusicSampleByName(_nameBundleMusic, l, (_musicBundleBufOutput + ((k * 0x2000) + _offsetBufBundleMusic)));
-		_offsetSampleBundleMusic += length;
-
-		if (l == 0) {
-			tag = READ_BE_UINT32(ptr); ptr += 4;
-			if (tag != MKID_BE('iMUS')) {
-				error("Decompressing bundle song failed (unknown tag '%s')", tag2str(tag));
-			}
-
-			ptr += 12;
-			while (tag != MKID_BE('DATA')) {
-				tag = READ_BE_UINT32(ptr);  ptr += 4;
-				switch(tag) {
-				case MKID_BE('FRMT'):
-					ptr += 12;
-					_bundleMusicSampleBits = READ_BE_UINT32(ptr); ptr += 4;
-					rate = READ_BE_UINT32(ptr); ptr += 4;
-					_bundleSampleChannels = READ_BE_UINT32(ptr); ptr += 4;
-				break;
-				case MKID_BE('TEXT'):
-				case MKID_BE('REGN'):
-				case MKID_BE('STOP'):
-				case MKID_BE('JUMP'):
-				case MKID_BE('SYNC'):
-					size = READ_BE_UINT32(ptr); ptr += size + 4;
-				break;
-					case MKID_BE('DATA'):
-					size = READ_BE_UINT32(ptr); ptr += 4;
-				break;
-
-				default:
-					error("Unknown sound header %c%c%c%c",
-						(byte)(tag >> 24),
-						(byte)(tag >> 16),
-						(byte)(tag >> 8),
-						(byte)tag);
-				}
-			}
-			if (size < 0) {
-				error("Decompressing sound failed (missing size field)");
-			}
-			header_size = (ptr - _musicBundleBufOutput);
-		}
-
-		l++;
-		_currentSampleBundleMusic = l;
-
-		if (_offsetSampleBundleMusic >= _outputMixerSize + header_size) {
-			memcpy(_musicBundleBufFinal, (_musicBundleBufOutput + header_size), _outputMixerSize);
-			_offsetBufBundleMusic = _offsetSampleBundleMusic - _outputMixerSize - header_size;
-			memcpy(_musicBundleBufOutput, (_musicBundleBufOutput + (_outputMixerSize + header_size)), _offsetBufBundleMusic);
-			_offsetSampleBundleMusic = _offsetBufBundleMusic;
-			break;
-		}
-	}
-
-	if (_currentSampleBundleMusic == num) {
-		_currentSampleBundleMusic = 0;
-		_offsetSampleBundleMusic = 0;
-		_offsetBufBundleMusic = 0;
-		_bundleMusicPosition = 0;
-		_bundleSongPosInMs = 0;
-	}
-
-	ptr = _musicBundleBufFinal;
-
-	byte *buffer = NULL;
-	uint32 final_size;
-	if (_bundleMusicSampleBits == 12) {
-		final_size = decode12BitsSample(ptr, &buffer, _outputMixerSize, false);
-	} else if (_bundleMusicSampleBits == 16) {
-		buffer = (byte *)malloc(_outputMixerSize);
-		final_size = _outputMixerSize;
-		memcpy(buffer, ptr, _outputMixerSize);
-	} else {
-		warning("Sound::bundleMusicHandler TODO: more newStream options...");
-		return;
-	}
-
-	_bundleSongPosInMs = (_bundleMusicPosition * 5) / (_outputMixerSize / 200);
-	_bundleMusicPosition += final_size;
-	if (_bundleMusicTrack == 0)
-		_scumm->_mixer->newStream(&_bundleMusicTrack, rate, SoundMixer::FLAG_16BITS | SoundMixer::FLAG_STEREO, 300000);
-	_scumm->_mixer->appendStream(_bundleMusicTrack, buffer, final_size);
-	free(buffer);
-}
-
-void Sound::playBundleSound(char *sound, PlayingSoundHandle *handle) {
-	byte *ptr = 0, *orig_ptr = 0;
-	byte *final;
-	bool result;
-
-	if (_scumm->_noDigitalSamples)
-		return;	
-
-	if (_scumm->_gameId == GID_CMI) {
-		if (_scumm->_features & GF_DEMO) {
-			result = _bundle->openVoiceFile("voice.bun", _scumm->getGameDataPath());
-		} else {
-			char voxfile[20];
-			sprintf(voxfile, "voxdisk%d.bun", _scumm->VAR(_scumm->VAR_CURRENTDISK));
-			if (_voiceDisk != _scumm->VAR(_scumm->VAR_CURRENTDISK))
-				_bundle->closeVoiceFile();
-
-			result = _bundle->openVoiceFile(voxfile, _scumm->getGameDataPath());
-
-			if (result == false) 
-				result = _bundle->openVoiceFile("voice.bun", _scumm->getGameDataPath());
-			_voiceDisk = (byte)_scumm->VAR(_scumm->VAR_CURRENTDISK);
-		}
-	} else if (_scumm->_gameId == GID_DIG)
-		result = _bundle->openVoiceFile("digvoice.bun", _scumm->getGameDataPath());
-	else
-		error("Don't know which bundle file to load");
-
-	if (!result)
-		return;
-
-	int32 rate = 22050, pan = 0, channels, output_size = 0;
-	int32 tag, size = -1, bits = 0;
-
-	if (_scumm->_gameId == GID_CMI) {
-		char name[20];
-		strcpy(name, sound);
-		if (!(_scumm->_features & GF_DEMO)) // CMI demo does not have .IMX for voice but does for music...
-			strcat(name, ".IMX");
-		output_size = _bundle->decompressVoiceSampleByName(name, &ptr);
-	} else {
-		output_size = _bundle->decompressVoiceSampleByName(sound, &ptr);
-	}
-
-	orig_ptr = ptr;
-	if (output_size == 0 || orig_ptr == 0) {
-		goto bail;
-	}
-
-	tag = READ_BE_UINT32(ptr); ptr += 4;
-	if (tag != MKID_BE('iMUS')) {
-		warning("Decompression of bundle sound failed");
-		goto bail;
-	}
-
-	ptr += 12;
-	while (tag != MKID_BE('DATA')) {
-		tag = READ_BE_UINT32(ptr); ptr += 4;
-		switch(tag) {
-		case MKID_BE('FRMT'):
-			ptr += 12;
-			bits = READ_BE_UINT32(ptr); ptr += 4;
-			rate = READ_BE_UINT32(ptr); ptr += 4;
-			channels = READ_BE_UINT32(ptr); ptr += 4;
-			break;
-		case MKID_BE('TEXT'):
-		case MKID_BE('REGN'):
-		case MKID_BE('STOP'):
-		case MKID_BE('JUMP'):
-		case MKID_BE('SYNC'):
-			size = READ_BE_UINT32(ptr); ptr += size + 4;
-			break;
-		case MKID_BE('DATA'):
-			size = READ_BE_UINT32(ptr); ptr += 4;
-			break;
-		default:
-			error("Unknown sound header %c%c%c%c",
-				(byte)(tag >> 24),
-				(byte)(tag >> 16),
-				(byte)(tag >> 8),
-				(byte)tag);
-		}
-	}
-
-	if (size < 0) {
-		warning("Decompression sound failed (no size field)");
-		goto bail;
-	}
-
-	final = (byte *)malloc(size);
-	memcpy(final, ptr, size);
-
-	if (_scumm->_actorToPrintStrFor != 0xFF && _scumm->_actorToPrintStrFor != 0) {
-		Actor *a = _scumm->derefActor(_scumm->_actorToPrintStrFor, "playBundleSound");
-		rate = (rate * a->talkFrequency) / 256;
-
-		// Adjust to fit the mixer's notion of panning.
-		if (pan != 64)
-			pan = 2 * a->talkPan - 127;
-	}
-	
-	// Stop any sound currently playing on the given handle
-	if (handle)
-		_scumm->_mixer->stopHandle(*handle);
-
-	if (bits == 8) {
-		_scumm->_mixer->playRaw(handle, final, size, rate, SoundMixer::FLAG_UNSIGNED | SoundMixer::FLAG_AUTOFREE, -1, 255, pan);
-	} else if (bits == 16) {
-		// FIXME: For some weird reasons, sometimes we get an odd size, even though
-		// the data is supposed to be in 16 bit format... that makes no sense...
-		size &= ~1;
-		_scumm->_mixer->playRaw(handle, final, size, rate, SoundMixer::FLAG_16BITS | SoundMixer::FLAG_AUTOFREE, -1, 255, pan);
-	} else {
-		warning("Sound::playBundleSound() to do more options to playRaw...");
-	}
-	
-bail:
-	free(orig_ptr);
 }
 
 void Sound::playSfxSound(void *sound, uint32 size, uint rate, bool isUnsigned, PlayingSoundHandle *handle) {

Index: sound.h
===================================================================
RCS file: /cvsroot/scummvm/scummvm/scumm/sound.h,v
retrieving revision 1.55
retrieving revision 1.56
diff -u -d -r1.55 -r1.56
--- sound.h	29 Nov 2003 12:11:01 -0000	1.55
+++ sound.h	22 Dec 2003 08:22:03 -0000	1.56
@@ -28,7 +28,6 @@
 
 namespace Scumm {
 
-class Bundle;
 class ScummEngine;
 
 struct MP3OffsetTable;
@@ -38,28 +37,6 @@
 	int16 _soundQuePos, _soundQue[0x100];
 	int16 _soundQue2Pos, _soundQue2[10];
 
-public:
-	const char *_nameBundleMusic;
-	int32 _bundleMusicPosition;
-	int32 _bundleSongPosInMs;
-
-protected:
-	const char *_newNameBundleMusic;
-	byte _musicDisk;
-	byte _voiceDisk;
-	int32 _currentSampleBundleMusic;
-	int32 _numberSamplesBundleMusic;
-	int32 _offsetSampleBundleMusic;
-	int32 _offsetBufBundleMusic;
-	byte *_musicBundleBufFinal;
-	byte *_musicBundleBufOutput;
-	bool _pauseBundleMusic;
-	PlayingSoundHandle _bundleMusicTrack;
-	bool _musicBundleToBeChanged;
-	int32 _bundleMusicSampleBits;
-	int32 _outputMixerSize;
-	int32 _bundleSampleChannels;
-
 	File *_sfxFile;
 	uint32 _talk_sound_a1, _talk_sound_a2, _talk_sound_b1, _talk_sound_b2;
 	byte _talk_sound_mode;
@@ -81,8 +58,6 @@
 	PlayingSoundHandle _talkChannelHandle;	// Handle of mixer channel actor is talking on
 	bool _soundsPaused;
 	byte _sfxMode;
-	
-	Bundle *_bundle;	// FIXME: should be protected but is used by ScummEngine::askForDisk
 
 public:
 	Sound(ScummEngine *parent);
@@ -104,14 +79,6 @@
 	void talkSound(uint32 a, uint32 b, int mode, int frame);
 	void setupSound();
 	void pauseSounds(bool pause);
-
-	void playBundleMusic(const char *song);
-	void pauseBundleMusic(bool state);
-	void bundleMusicHandler(ScummEngine *scumm);
-	void stopBundleMusic();
-	void playBundleSound(char *sound, PlayingSoundHandle *handle);
-
-	uint32 decode12BitsSample(byte *src, byte **dst, uint32 size, bool stereo);
 
 	void startCDTimer();
 	void stopCDTimer();

Index: string.cpp
===================================================================
RCS file: /cvsroot/scummvm/scummvm/scumm/string.cpp,v
retrieving revision 1.170
retrieving revision 1.171
diff -u -d -r1.170 -r1.171
--- string.cpp	17 Nov 2003 21:16:43 -0000	1.170
+++ string.cpp	22 Dec 2003 08:22:03 -0000	1.171
@@ -25,6 +25,7 @@
 #include "scumm/actor.h"
 #include "scumm/charset.h"
 #include "scumm/dialogs.h"
+#include "scumm/imuse_digi.h"
 #include "scumm/verbs.h"
 #include "scumm/sound.h"
 
@@ -899,7 +900,7 @@
 		pointer[j] = 0;
 
 		// Play speech
-		_sound->playBundleSound(pointer, &_sound->_talkChannelHandle);
+		_imuseDigital->playBundleSound(pointer, &_sound->_talkChannelHandle);
 
 		ptr = _transText;
 	}





More information about the Scummvm-git-logs mailing list