[Scummvm-cvs-logs] scummvm master -> b86de198a01d840d71706bca7facb4f1ce8cb997

lordhoto lordhoto at gmail.com
Fri Aug 5 23:01:59 CEST 2011


This automated email contains information about 1 new commit which have been
pushed to the 'scummvm' repo located at https://github.com/scummvm/scummvm .

Summary:
b86de198a0 SCUMM: Fix up CMS player implementation.


Commit: b86de198a01d840d71706bca7facb4f1ce8cb997
    https://github.com/scummvm/scummvm/commit/b86de198a01d840d71706bca7facb4f1ce8cb997
Author: Johannes Schickel (lordhoto at scummvm.org)
Date: 2011-08-05T13:58:50-07:00

Commit Message:
SCUMM: Fix up CMS player implementation.

It's much better now and hopefully quite close to the original when it comes
to the music part. The intro music of Loom and Monkey Island 1 EGA sounds fine
to me now at least.

Changed paths:
    engines/scumm/player_v2cms.cpp
    engines/scumm/player_v2cms.h
    engines/scumm/scumm.cpp
    engines/scumm/sound.cpp



diff --git a/engines/scumm/player_v2cms.cpp b/engines/scumm/player_v2cms.cpp
index 21e7f19..c39b360 100644
--- a/engines/scumm/player_v2cms.cpp
+++ b/engines/scumm/player_v2cms.cpp
@@ -70,40 +70,40 @@ static const byte freqTable[] = {
 	0x80, 0x90, 0xA0, 0xB0, 0xC0, 0xD0, 0xE0, 0xF0
 };*/
 
-static const byte octaveTable[] = {
-	0x00, 0x00, 0x00, 0x01, 0x00, 0x02, 0x00, 0x03,
-	0x00, 0x04, 0x00, 0x05, 0x00, 0x06, 0x00, 0x07,
-	0x00, 0x08, 0x00, 0x09, 0x00, 0x0A, 0x00, 0x0B,
-	0x01, 0x00, 0x01, 0x01, 0x01, 0x02, 0x01, 0x03,
-	0x01, 0x04, 0x01, 0x05, 0x01, 0x06, 0x01, 0x07,
-	0x01, 0x08, 0x01, 0x09, 0x01, 0x0A, 0x01, 0x0B,
-	0x02, 0x00, 0x02, 0x01, 0x02, 0x02, 0x02, 0x03,
-	0x02, 0x04, 0x02, 0x05, 0x02, 0x06, 0x02, 0x07,
-	0x02, 0x08, 0x02, 0x09, 0x02, 0x0A, 0x02, 0x0B,
-	0x03, 0x00, 0x03, 0x01, 0x03, 0x02, 0x03, 0x03,
-	0x03, 0x04, 0x03, 0x05, 0x03, 0x06, 0x03, 0x07,
-	0x03, 0x08, 0x03, 0x09, 0x03, 0x0A, 0x03, 0x0B,
-	0x04, 0x00, 0x04, 0x01, 0x04, 0x02, 0x04, 0x03,
-	0x04, 0x04, 0x04, 0x05, 0x04, 0x06, 0x04, 0x07,
-	0x04, 0x08, 0x04, 0x09, 0x04, 0x0A, 0x04, 0x0B,
-	0x05, 0x00, 0x05, 0x01, 0x05, 0x02, 0x05, 0x03,
-	0x05, 0x04, 0x05, 0x05, 0x05, 0x06, 0x05, 0x07,
-	0x05, 0x08, 0x05, 0x09, 0x05, 0x0A, 0x05, 0x0B,
-	0x06, 0x00, 0x06, 0x01, 0x06, 0x02, 0x06, 0x03,
-	0x06, 0x04, 0x06, 0x05, 0x06, 0x06, 0x06, 0x07,
-	0x06, 0x08, 0x06, 0x09, 0x06, 0x0A, 0x06, 0x0B,
-	0x07, 0x00, 0x07, 0x01, 0x07, 0x02, 0x07, 0x03,
-	0x07, 0x04, 0x07, 0x05, 0x07, 0x06, 0x07, 0x07,
-	0x07, 0x08, 0x07, 0x09, 0x07, 0x0A, 0x07, 0x0B,
-	0x08, 0x00, 0x08, 0x01, 0x08, 0x02, 0x08, 0x03,
-	0x08, 0x04, 0x08, 0x05, 0x08, 0x06, 0x08, 0x07,
-	0x08, 0x08, 0x08, 0x09, 0x08, 0x0A, 0x08, 0x0B,
-	0x09, 0x00, 0x09, 0x01, 0x09, 0x02, 0x09, 0x03,
-	0x09, 0x04, 0x09, 0x05, 0x09, 0x06, 0x09, 0x07,
-	0x09, 0x08, 0x09, 0x09, 0x09, 0x0A, 0x09, 0x0B,
-	0x0A, 0x00, 0x0A, 0x01, 0x0A, 0x02, 0x0A, 0x03,
-	0x0A, 0x04, 0x0A, 0x05, 0x0A, 0x06, 0x0A, 0x07,
-	0x0A, 0x08, 0x0A, 0x09, 0x0A, 0x0A, 0x0A, 0x0B
+static const uint16 noteTable[] = {
+	0x000, 0x100, 0x200, 0x300,
+	0x400, 0x500, 0x600, 0x700,
+	0x800, 0x900, 0xA00, 0xB00,
+	0x001, 0x101, 0x201, 0x301,
+	0x401, 0x501, 0x601, 0x701,
+	0x801, 0x901, 0xA01, 0xB01,
+	0x002, 0x102, 0x202, 0x302,
+	0x402, 0x502, 0x602, 0x702,
+	0x802, 0x902, 0xA02, 0xB02,
+	0x003, 0x103, 0x203, 0x303,
+	0x403, 0x503, 0x603, 0x703,
+	0x803, 0x903, 0xA03, 0xB03,
+	0x004, 0x104, 0x204, 0x304,
+	0x404, 0x504, 0x604, 0x704,
+	0x804, 0x904, 0xA04, 0xB04,
+	0x005, 0x105, 0x205, 0x305,
+	0x405, 0x505, 0x605, 0x705,
+	0x805, 0x905, 0xA05, 0xB05,
+	0x006, 0x106, 0x206, 0x306,
+	0x406, 0x506, 0x606, 0x706,
+	0x806, 0x906, 0xA06, 0xB06,
+	0x007, 0x107, 0x207, 0x307,
+	0x407, 0x507, 0x607, 0x707,
+	0x807, 0x907, 0xA07, 0xB07,
+	0x008, 0x108, 0x208, 0x308,
+	0x408, 0x508, 0x608, 0x708,
+	0x808, 0x908, 0xA08, 0xB08,
+	0x009, 0x109, 0x209, 0x309,
+	0x409, 0x509, 0x609, 0x709,
+	0x809, 0x909, 0xA09, 0xB09,
+	0x00A, 0x10A, 0x20A, 0x30A,
+	0x40A, 0x50A, 0x60A, 0x70A,
+	0x80A, 0x90A, 0xA0A, 0xB0A
 };
 
 static const byte attackRate[] = {
@@ -131,6 +131,12 @@ static const byte volumeTable[] = {
 	0x33, 0x44, 0x55, 0x66, 0x88, 0xAA, 0xCC, 0xFF
 };
 
+static const byte cmsInitData[13*2] = {
+	0x1C, 0x02,
+	0x00, 0x00, 0x01, 0x00, 0x02, 0x00, 0x03, 0x00, 0x04, 0x00, 0x05, 0x00,
+	0x14, 0x3F, 0x15, 0x00, 0x16, 0x00, 0x18, 0x00, 0x19, 0x00, 0x1C, 0x01
+};
+
 Player_V2CMS::Player_V2CMS(ScummEngine *scumm, Audio::Mixer *mixer)
 	: Player_V2Base(scumm, mixer, true) {
 	int i;
@@ -142,6 +148,7 @@ Player_V2CMS::Player_V2CMS(ScummEngine *scumm, Audio::Mixer *mixer)
 	memset(_cmsChips, 0, sizeof(MusicChip)*2);
 	_midiDelay = _octaveMask = _looping = _tempo = 0;
 	_midiData = _midiSongBegin = 0;
+	_musicTimer = _musicTimerTicks = 0;
 	_loadedMidiSong = 0;
 	memset(_midiChannel, 0, sizeof(Voice2*)*16);
 	memset(_midiChannelUse, 0, sizeof(byte)*16);
@@ -173,12 +180,6 @@ Player_V2CMS::Player_V2CMS(ScummEngine *scumm, Audio::Mixer *mixer)
 
 	// inits the CMS Emulator like in the original
 	_cmsEmu = new CMSEmulator(_sampleRate);
-	static const byte cmsInitData[13*2] = {
-		0x1C, 0x02,
-		0x00, 0x00, 0x01, 0x00, 0x02, 0x00, 0x03, 0x00, 0x04, 0x00, 0x05, 0x00,
-		0x14, 0x3F, 0x15, 0x00, 0x16, 0x00, 0x18, 0x00, 0x19, 0x00, 0x1C, 0x01
-	};
-
 	i = 0;
 	for (int cmsPort = 0x220; i < 2; cmsPort += 2, ++i) {
 		for (int off = 0; off < 13; ++off) {
@@ -200,6 +201,10 @@ Player_V2CMS::~Player_V2CMS() {
 void Player_V2CMS::setMusicVolume(int vol) {
 }
 
+int Player_V2CMS::getMusicTimer() {
+	return _midiData ? _musicTimer : Player_V2Base::getMusicTimer();
+}
+
 void Player_V2CMS::stopAllSounds() {
 	Common::StackLock lock(_mutex);
 
@@ -211,6 +216,7 @@ void Player_V2CMS::stopAllSounds() {
 	_midiData = 0;
 	_midiSongBegin = 0;
 	_midiDelay = 0;
+	_musicTimer = _musicTimerTicks = 0;
 	offAllChannels();
 }
 
@@ -244,6 +250,7 @@ void Player_V2CMS::startSound(int nr) {
 	assert(data);
 
 	if (data[6] == 0x80) {
+		_musicTimer = _musicTimerTicks = 0;
 		loadMidiData(data, nr);
 	} else {
 		int cprio = _current_data ? *(_current_data + _header_len) : 0;
@@ -351,11 +358,17 @@ int Player_V2CMS::getSoundStatus(int nr) const {
 	return _current_nr == nr || _next_nr == nr || _loadedMidiSong == nr;
 }
 
-void Player_V2CMS::processMidiData(uint ticks) {
+void Player_V2CMS::processMidiData() {
 	byte *currentData = _midiData;
 	byte command = 0x00;
 	int16 temp = 0;
 
+	++_musicTimerTicks;
+	if (_musicTimerTicks > 60) {
+		_musicTimerTicks = 0;
+		++_musicTimer;
+	}
+
 	if (!_midiDelay) {
 		while (true) {
 			if ((command = *currentData++) == 0xFF) {
@@ -365,6 +378,8 @@ void Player_V2CMS::processMidiData(uint ticks) {
 						continue;
 					}
 					_midiData = _midiSongBegin = 0;
+					_midiDelay = 0;
+					_loadedMidiSong = 0;
 					offAllChannels();
 					return;
 				} else {
@@ -400,7 +415,7 @@ void Player_V2CMS::processMidiData(uint ticks) {
 		_midiDelay = temp;
 	}
 
-	_midiDelay -= ticks;
+	--_midiDelay;
 	if (_midiDelay < 0)
 		_midiDelay = 0;
 
@@ -415,27 +430,21 @@ int Player_V2CMS::readBuffer(int16 *buffer, const int numSamples) {
 
 	// maybe this needs a complete rewrite
 	do {
-		if (_midiData) {
-			--_clkFrequenz;
-			if (!(_clkFrequenz & 0x01)) {
-				playVoice();
-			}
-
-			_tempoSum += _tempo;
-			// FIXME: _tempoSum is declared as char; on some systems char is unsigned.
-			// E.g. on OS X. Hence the following check is always false.
-			// Moral of the story: Use uint8, int8 or any of the other types provided by
-			// ScummVM if you want to ensure signedness and number of available bits.
-			if (_tempoSum < 0) {
-				// this have to be called in the same rate as in the original (I think)
-				processMidiData(1);
+		if (!(_next_tick >> FIXP_SHIFT)) {
+			if (_midiData) {
+				--_clkFrequenz;
+				if (!(_clkFrequenz & 0x01))
+					playVoice();
+
+				int newTempoSum = _tempo + _tempoSum;
+				_tempoSum = newTempoSum & 0xFF;
+				if (newTempoSum > 0xFF)
+					processMidiData();
+			} else {
+				nextTick();
+				play();
 			}
-		}
-
-		if (!(_next_tick >> FIXP_SHIFT) && !_midiData) {
 			_next_tick += _tick_len;
-			nextTick();
-			play();
 		}
 
 		step = len;
@@ -456,29 +465,26 @@ void Player_V2CMS::playVoice() {
 	}
 
 	_octaveMask = 0xF0;
-	Voice2 *voice =0;
+	Voice2 *voice = 0;
 	for (int i = 0; i < 8; ++i) {
 		voice = &_cmsVoices[i];
 		_octaveMask = ~_octaveMask;
 
 		if (voice->chanNumber != 0xFF) {
 			processChannel(voice);
-			continue;
-		}
-
-		if (!voice->curVolume) {
-			*(voice->amplitudeOutput) = 0;
-		}
+		} else {
+			if (!voice->curVolume) {
+				*(voice->amplitudeOutput) = 0;
+			}
 
-		int volume = voice->curVolume - voice->releaseRate;
-		voice->curVolume = volume;
+			int volume = voice->curVolume - voice->releaseRate;
+			if (volume < 0)
+				volume = 0;
 
-		if (volume < 0) {
-			volume = voice->curVolume = 0;
+			voice->curVolume = volume;
+			*(voice->amplitudeOutput) = ((volume >> 4) | (volume & 0xF0)) & voice->channel;
+			++_outputTableReady;
 		}
-
-		*(voice->amplitudeOutput) = ((volume >> 4) | (volume & 0xF0)) & voice->channel;
-		++_outputTableReady;
 	}
 }
 
@@ -511,44 +517,50 @@ void Player_V2CMS::processChannel(Voice2 *channel) {
 }
 
 void Player_V2CMS::processRelease(Voice2 *channel) {
-	channel->curVolume -= channel->releaseRate;
-	if (channel->curVolume < 0)
-		channel->curVolume = 0;
+	int newVolume = channel->curVolume - channel->releaseRate;
+	if (newVolume < 0)
+		newVolume = 0;
+
+	channel->curVolume = newVolume;
 	processVibrato(channel);
 }
 
 void Player_V2CMS::processAttack(Voice2 *channel) {
-	channel->curVolume += channel->attackRate;
-	if (channel->curVolume >= 0) {
-		if (channel->curVolume <= channel->maxAmpl)
-			return processVibrato(channel);
+	int newVolume = channel->curVolume + channel->attackRate;
+	if (newVolume > channel->maxAmpl) {
+		channel->curVolume = channel->maxAmpl;
+		channel->nextProcessState = PROCESS_DECAY;
+	} else {
+		channel->curVolume = newVolume;
 	}
-	channel->curVolume = channel->maxAmpl;
-	channel->nextProcessState = PROCESS_DECAY;
+
 	processVibrato(channel);
 }
 
 void Player_V2CMS::processDecay(Voice2 *channel) {
-	channel->curVolume -= channel->decayRate;
-	if (channel->curVolume >= 0) {
-		if (channel->curVolume > channel->sustainRate)
-			return processVibrato(channel);
+	int newVolume = channel->curVolume - channel->decayRate;
+	if (newVolume <= channel->sustainRate) {
+		channel->curVolume = channel->sustainRate;
+		channel->nextProcessState = PROCESS_SUSTAIN;
+	} else {
+		channel->curVolume = newVolume;
 	}
-	channel->curVolume = channel->sustainRate;
-	channel->nextProcessState = PROCESS_SUSTAIN;
+
 	processVibrato(channel);
 }
 
 void Player_V2CMS::processSustain(Voice2 *channel) {
 	if (channel->unkVibratoRate) {
-		int volume = (int)channel->curVolume + (int)channel->unkRate;
+		int16 volume = channel->curVolume + channel->unkRate;
 		if (volume & 0xFF00) {
-			volume = ((~volume) >> 8) & 0xFF;
+			volume = int8(volume >> 8);
+			volume = -volume;
 		}
+
 		channel->curVolume = volume;
-		--(channel->unkCount);
+		--channel->unkCount;
 		if (!channel->unkCount) {
-			channel->unkRate = ~(channel->unkRate);
+			channel->unkRate = -channel->unkRate;
 			channel->unkCount = (channel->unkVibratoDepth & 0x0F) << 1;
 		}
 	}
@@ -557,12 +569,13 @@ void Player_V2CMS::processSustain(Voice2 *channel) {
 
 void Player_V2CMS::processVibrato(Voice2 *channel) {
 	if (channel->vibratoRate) {
-		uint16 temp = channel->curFreq + channel->curVibratoRate;
+		int16 temp = channel->curFreq + channel->curVibratoRate;
 		channel->curOctave += (temp & 0xFF00) >> 8;
 		channel->curFreq = temp & 0xFF;
-		--(channel->curVibratoUnk);
+
+		--channel->curVibratoUnk;
 		if (!channel->curVibratoUnk) {
-			channel->curVibratoRate = ~(channel->curVibratoRate);
+			channel->curVibratoRate = -channel->curVibratoRate;
 			channel->curVibratoUnk = (channel->vibratoDepth & 0x0F) << 1;
 		}
 	}
@@ -572,25 +585,16 @@ void Player_V2CMS::processVibrato(Voice2 *channel) {
 	output = channel->freqOutput;
 	*output = channel->curFreq;
 	output = channel->octaveOutput;
-	*output = ((((channel->curOctave >> 4) | (channel->curOctave & 0x0F)) & _octaveMask) | ((~_octaveMask) & *output));
+	*output = ((((channel->curOctave << 4) | (channel->curOctave & 0x0F)) & _octaveMask) | ((~_octaveMask) & *output));
 }
 
 void Player_V2CMS::offAllChannels() {
-	warning("offAllChannels STUB");
-/*
-	// after using this sound can not be played anymore (since it would deinit the emulator)
-	static const byte cmsOffData[10*2] = {
-		0x1C, 0x02,
-		0x00, 0x00, 0x01, 0x00, 0x02, 0x00, 0x03, 0x00, 0x04, 0x00, 0x05, 0x00,
-		0x14, 0x3F, 0x15, 0x00, 0x16, 0x00
-	};
-
 	for (int cmsPort = 0x220, i = 0; i < 2; cmsPort += 2, ++i) {
-		for (int off = 0; off < 10; ++off) {
-			_cmsEmu->portWrite(cmsPort+1, cmsOffData[off*2]);
-			_cmsEmu->portWrite(cmsPort, cmsOffData[off*2+1]);
+		for (int off = 1; off <= 10; ++off) {
+			_cmsEmu->portWrite(cmsPort+1, cmsInitData[off*2]);
+			_cmsEmu->portWrite(cmsPort, cmsInitData[off*2+1]);
 		}
-	}*/
+	}
 }
 
 Player_V2CMS::Voice2 *Player_V2CMS::getFreeVoice() {
@@ -637,8 +641,10 @@ void Player_V2CMS::playNote(byte *&data) {
 			freeVoice->sustainRate = voice->sustain;
 			freeVoice->releaseRate = voice->release;
 			freeVoice->octaveAdd = voice->octadd;
-			freeVoice->vibratoRate = freeVoice->curVibratoRate = voice->vibrato;
-			freeVoice->unkVibratoRate = freeVoice->unkRate = voice->vibrato2;
+			freeVoice->vibratoRate = freeVoice->curVibratoRate = voice->vibrato & 0xFF;
+			freeVoice->vibratoDepth = freeVoice->curVibratoUnk = voice->vibrato >> 8;
+			freeVoice->unkVibratoRate = freeVoice->unkRate = voice->vibrato2 & 0xFF;
+			freeVoice->unkVibratoDepth = freeVoice->unkCount = voice->vibrato2 >> 8;
 			freeVoice->maxAmpl = 0xFF;
 
 			uint8 rate = freeVoice->attackRate;
@@ -650,7 +656,10 @@ void Player_V2CMS::playNote(byte *&data) {
 			rate -= freeVoice->attackRate;
 			freeVoice->curVolume = rate;
 			freeVoice->playingNote = *data;
-			int octave = octaveTable[(*data + 3) << 1] + freeVoice->octaveAdd - 3;
+
+			uint16 note = noteTable[*data + 3];
+
+			int octave = int8(note & 0xFF) + freeVoice->octaveAdd - 3;
 			if (octave < 0)
 				octave = 0;
 			if (octave > 7)
@@ -658,10 +667,10 @@ void Player_V2CMS::playNote(byte *&data) {
 			if (!octave)
 				++octave;
 			freeVoice->curOctave = octave;
-			freeVoice->curFreq = freqTable[volume << 2];
+			freeVoice->curFreq = freqTable[(note >> 8) << 2];
 			freeVoice->curVolume = 0;
 			freeVoice->nextProcessState = PROCESS_ATTACK;
-			if (_lastMidiCommand & 1)
+			if (!(_lastMidiCommand & 1))
 				freeVoice->channel = 0xF0;
 			else
 				freeVoice->channel = 0x0F;
@@ -672,35 +681,27 @@ void Player_V2CMS::playNote(byte *&data) {
 
 Player_V2CMS::Voice2 *Player_V2CMS::getPlayVoice(byte param) {
 	byte channelNum = _lastMidiCommand & 0x0F;
-	Voice2 *channel = _midiChannel[channelNum];
+	Voice2 *curVoice = _midiChannel[channelNum];
 
-	if (channel) {
-		Voice2 *backUp = 0;
+	if (curVoice) {
+		Voice2 *prevVoice = 0;
 		while (true) {
-			if (channel->playingNote == param)
+			if (curVoice->playingNote == param)
 				break;
 
-			backUp = channel;
-			channel = channel->nextVoice;
-			if (!channel)
+			prevVoice = curVoice;
+			curVoice = curVoice->nextVoice;
+			if (!curVoice)
 				return 0;
 		}
 
-		Voice2 *backUp2 = channel->nextVoice;
-		{
-			Voice2 *temp = backUp;
-			backUp = channel;
-			channel = temp;
-		}
-		if (channel) {
-			channel->nextVoice = backUp2;
-		} else {
-			_midiChannel[channelNum] = backUp2;
-		}
-		channel = backUp;
+		if (prevVoice)
+			prevVoice->nextVoice = curVoice->nextVoice;
+		else
+			_midiChannel[channelNum] = curVoice->nextVoice;
 	}
 
-	return channel;
+	return curVoice;
 }
 
 void Player_V2CMS::clearNote(byte *&data) {
diff --git a/engines/scumm/player_v2cms.h b/engines/scumm/player_v2cms.h
index f7dc0c1..ba2c3f2 100644
--- a/engines/scumm/player_v2cms.h
+++ b/engines/scumm/player_v2cms.h
@@ -42,7 +42,7 @@ public:
 	virtual void startSound(int sound);
 	virtual void stopSound(int sound);
 	virtual void stopAllSounds();
-//	virtual int  getMusicTimer();
+	virtual int  getMusicTimer();
 	virtual int  getSoundStatus(int sound) const;
 
 	// AudioStream API
@@ -72,12 +72,12 @@ protected:
 
 		uint8 channel;
 		int8 sustainLevel;
-		int8 attackRate;
+		uint8 attackRate;
 		uint8 maxAmpl;
-		int8 decayRate;
-		int8 sustainRate;
-		int8 releaseRate;
-		int8 releaseTime;
+		uint8 decayRate;
+		uint8 sustainRate;
+		uint8 releaseRate;
+		uint8 releaseTime;
 		int8 vibratoRate;
 		int8 vibratoDepth;
 
@@ -91,9 +91,9 @@ protected:
 		int8 unkCount;
 
 		int nextProcessState;
-		int8 curVolume;
-		int8 curOctave;
-		int8 curFreq;
+		uint8 curVolume;
+		uint8 curOctave;
+		uint8 curFreq;
 
 		int8 octaveAdd;
 
@@ -114,8 +114,8 @@ protected:
 	Voice2 _cmsVoices[8];
 	MusicChip _cmsChips[2];
 
-	int8 _tempo;
-	int8 _tempoSum;
+	uint8 _tempo;
+	uint8 _tempoSum;
 	byte _looping;
 	byte _octaveMask;
 	int16 _midiDelay;
@@ -132,6 +132,8 @@ protected:
 	byte _restart;
 	byte _curSno;
 
+	int _musicTimer, _musicTimerTicks;
+
 	void loadMidiData(byte *data, int sound);
 	void play();
 
@@ -147,7 +149,7 @@ protected:
 	void clearNote(byte *&data);
 	void offAllChannels();
 	void playVoice();
-	void processMidiData(uint ticks);
+	void processMidiData();
 
 	Voice2 *getFreeVoice();
 	Voice2 *getPlayVoice(byte param);
diff --git a/engines/scumm/scumm.cpp b/engines/scumm/scumm.cpp
index 0f01e39..d546f03 100644
--- a/engines/scumm/scumm.cpp
+++ b/engines/scumm/scumm.cpp
@@ -1754,12 +1754,8 @@ void ScummEngine::setupMusic(int midi) {
 	case MT_PCJR:
 		_musicType = MDT_PCJR;
 		break;
-	//case MT_CMS:
-#if 1
-		_musicType = MDT_ADLIB;
-#else
-		_musicType = MDT_CMS; // Still has number of bugs, disable by default
-#endif
+	case MT_CMS:
+		_musicType = MDT_CMS;
 		break;
 	case MT_TOWNS:
 		_musicType = MDT_TOWNS;
diff --git a/engines/scumm/sound.cpp b/engines/scumm/sound.cpp
index a74fa36..b4836d0 100644
--- a/engines/scumm/sound.cpp
+++ b/engines/scumm/sound.cpp
@@ -2104,18 +2104,37 @@ int ScummEngine::readSoundResourceSmallHeader(ResId idx) {
 			_fileHandle->read(_res->createResource(rtSound, idx, wa_size + 6), wa_size + 6);
 		}
 		return 1;
-	} else if (_musicType == MDT_CMS && ad_offs != 0) {
+	} else if (_musicType == MDT_CMS) {
 		if (_game.features & GF_OLD_BUNDLE) {
-			_fileHandle->seek(wa_offs + wa_size + 6, SEEK_SET);
-			byte musType = _fileHandle->readByte();
+			bool hasAdLibMusicTrack = false;
 
-			if (musType == 0x80) {
+			if (ad_offs) {
+				_fileHandle->seek(ad_offs + 4 + 2, SEEK_SET);
+				hasAdLibMusicTrack = (_fileHandle->readByte() == 0x80);
+			}
+
+			if (hasAdLibMusicTrack) {
 				_fileHandle->seek(ad_offs, SEEK_SET);
 				_fileHandle->read(_res->createResource(rtSound, idx, ad_size), ad_size);
 			} else {
 				_fileHandle->seek(wa_offs, SEEK_SET);
 				_fileHandle->read(_res->createResource(rtSound, idx, wa_size), wa_size);
 			}
+		} else {
+			bool hasAdLibMusicTrack = false;
+
+			if (ad_offs) {
+				_fileHandle->seek(ad_offs + 2, SEEK_SET);
+				hasAdLibMusicTrack = (_fileHandle->readByte() == 0x80);
+			}
+
+			if (hasAdLibMusicTrack) {
+				_fileHandle->seek(ad_offs - 4, SEEK_SET);
+				_fileHandle->read(_res->createResource(rtSound, idx, ad_size + 4), ad_size + 4);
+			} else {
+				_fileHandle->seek(wa_offs - 6, SEEK_SET);
+				_fileHandle->read(_res->createResource(rtSound, idx, wa_size + 6), wa_size + 6);
+			}
 		}
 	} else if (ad_offs != 0) {
 		// AD resources have a header, instrument definitions and one MIDI track.






More information about the Scummvm-git-logs mailing list