[Scummvm-cvs-logs] scummvm master -> 6dcc8b03b89902020f7a52f4823706bc8376e0b3

wjp wjp at usecode.org
Sun Feb 15 14:18:08 CET 2015


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

Summary:
84d2414a7d SCI: Avoid resetting already unused channels
f1e34f11d7 SCI: Initialize voice counts in SCI1+
26d55b09a8 SCI: Match SSCI channel reset order
58ef44eb8d SCI: Register and save playBed option to PlaySound
5964cc239b SCI: Always re-sort playlist in soundPlay
e42a512357 SCI: Don't remap channels from playBed songs
b80e74af5d SCI: Handle voice limits differently
0aadd20aea SCI: Add debugging output
0018bb0f6f SCI: Give songs that start playing later higher priority
5028487038 SCI: Use sound resource priority by default for songs
1c5722f014 SCI: Allow channel remapping from audio thread too
d0cb5f51fd SCI: Only allow a single 'playBed' song in SCI1early
2b49b5f95e SCI: Fix sound object frame selector rate
6dcc8b03b8 Merge branch 'sci_audio'


Commit: 84d2414a7dceca9d5140936667aae05fbbfdcf99
    https://github.com/scummvm/scummvm/commit/84d2414a7dceca9d5140936667aae05fbbfdcf99
Author: Willem Jan Palenstijn (wjp at usecode.org)
Date: 2015-02-14T16:06:55+01:00

Commit Message:
SCI: Avoid resetting already unused channels

Changed paths:
    engines/sci/sound/music.cpp



diff --git a/engines/sci/sound/music.cpp b/engines/sci/sound/music.cpp
index 7a6eaf6..5a37357 100644
--- a/engines/sci/sound/music.cpp
+++ b/engines/sci/sound/music.cpp
@@ -1063,7 +1063,7 @@ void SciMusic::remapChannels() {
 
 	// And finally, stop any empty channels
 	for (int i = _driverFirstChannel; i <= _driverLastChannel; ++i) {
-		if (!_channelMap[i]._song)
+		if (!_channelMap[i]._song && currentMap[i]._song)
 			resetDeviceChannel(i);
 	}
 


Commit: f1e34f11d742ef32ed48926092d93f3448732f2e
    https://github.com/scummvm/scummvm/commit/f1e34f11d742ef32ed48926092d93f3448732f2e
Author: Willem Jan Palenstijn (wjp at usecode.org)
Date: 2015-02-14T16:06:55+01:00

Commit Message:
SCI: Initialize voice counts in SCI1+

Changed paths:
    engines/sci/sound/midiparser_sci.cpp



diff --git a/engines/sci/sound/midiparser_sci.cpp b/engines/sci/sound/midiparser_sci.cpp
index c0b4f31..7ee9cc9 100644
--- a/engines/sci/sound/midiparser_sci.cpp
+++ b/engines/sci/sound/midiparser_sci.cpp
@@ -360,6 +360,13 @@ void MidiParser_SCI::sendInitCommands() {
 					sendToDriver(0xB0 | i, 0x4B, voiceCount);
 				}
 			}
+		} else {
+			for (int i = 0; i < _track->channelCount; ++i) {
+				byte voiceCount = _track->channels[i].poly;
+				byte num = _track->channels[i].number;
+				// TODO: Should we skip the control channel?
+				sendToDriver(0xB0 | num, 0x4B, voiceCount);
+			}
 		}
 	}
 


Commit: 26d55b09a8b198b0a9b9349d684eec6376d98c8c
    https://github.com/scummvm/scummvm/commit/26d55b09a8b198b0a9b9349d684eec6376d98c8c
Author: Willem Jan Palenstijn (wjp at usecode.org)
Date: 2015-02-14T16:06:55+01:00

Commit Message:
SCI: Match SSCI channel reset order

It may or may not matter for a driver's voice mapping.

Changed paths:
    engines/sci/sound/music.cpp



diff --git a/engines/sci/sound/music.cpp b/engines/sci/sound/music.cpp
index 5a37357..05605c0 100644
--- a/engines/sci/sound/music.cpp
+++ b/engines/sci/sound/music.cpp
@@ -1062,7 +1062,7 @@ void SciMusic::remapChannels() {
 	}
 
 	// And finally, stop any empty channels
-	for (int i = _driverFirstChannel; i <= _driverLastChannel; ++i) {
+	for (int i = _driverLastChannel; i >= _driverFirstChannel; --i) {
 		if (!_channelMap[i]._song && currentMap[i]._song)
 			resetDeviceChannel(i);
 	}


Commit: 58ef44eb8d9d3eb78eb013441a8d6d12940ee5e3
    https://github.com/scummvm/scummvm/commit/58ef44eb8d9d3eb78eb013441a8d6d12940ee5e3
Author: Willem Jan Palenstijn (wjp at usecode.org)
Date: 2015-02-14T16:06:55+01:00

Commit Message:
SCI: Register and save playBed option to PlaySound

The playBed option is not handled yet, only stored. This increases
the savegame format version.

Changed paths:
    engines/sci/console.cpp
    engines/sci/engine/kernel_tables.h
    engines/sci/engine/savegame.cpp
    engines/sci/engine/savegame.h
    engines/sci/sound/music.cpp
    engines/sci/sound/music.h
    engines/sci/sound/soundcmd.cpp
    engines/sci/sound/soundcmd.h



diff --git a/engines/sci/console.cpp b/engines/sci/console.cpp
index e233c4c..a3abf60 100644
--- a/engines/sci/console.cpp
+++ b/engines/sci/console.cpp
@@ -2172,6 +2172,7 @@ bool Console::cmdStartSound(int argc, const char **argv) {
 		return true;
 	}
 
+	// TODO: Maybe also add a playBed option.
 	g_sci->_soundCmd->startNewSound(number);
 	return cmdExit(0, 0);
 }
@@ -2198,9 +2199,10 @@ bool Console::cmdToggleSound(int argc, const char **argv) {
 	Common::String newState = argv[2];
 	newState.toLowercase();
 
-	if (newState == "play")
-		g_sci->_soundCmd->processPlaySound(id);
-	else if (newState == "stop")
+	if (newState == "play") {
+		// Maybe also have a 'playbed' option. (Second argument to processPlaySound.)
+		g_sci->_soundCmd->processPlaySound(id, false);
+	} else if (newState == "stop")
 		g_sci->_soundCmd->processStopSound(id, false);
 	else
 		debugPrintf("New state can either be 'play' or 'stop'");
diff --git a/engines/sci/engine/kernel_tables.h b/engines/sci/engine/kernel_tables.h
index 0c2fd4e..2cbd793 100644
--- a/engines/sci/engine/kernel_tables.h
+++ b/engines/sci/engine/kernel_tables.h
@@ -105,10 +105,6 @@ static const SciKernelMapSubEntry kDoSound_subops[] = {
 	{ SIG_SOUNDSCI1EARLY,  5, MAP_CALL(DoSoundInit),               NULL,                   NULL },
 	{ SIG_SOUNDSCI1EARLY,  6, MAP_CALL(DoSoundDispose),            NULL,                   NULL },
 	{ SIG_SOUNDSCI1EARLY,  7, MAP_CALL(DoSoundPlay),               "oi",                   NULL },
-	// ^^ TODO: In SCI1-SCI1.1 DoSound (play) is called by 2 methods of the Sound object: play and
-	//  playBed. The methods are the same, apart from the second integer parameter: it's 0 in
-	//  play and 1 in playBed, to distinguish the caller. It's passed on, we should find out what
-	//  it actually does internally
 	{ SIG_SOUNDSCI1EARLY,  8, MAP_CALL(DoSoundStop),               NULL,                   NULL },
 	{ SIG_SOUNDSCI1EARLY,  9, MAP_CALL(DoSoundPause),              "[o0]i",                NULL },
 	{ SIG_SOUNDSCI1EARLY, 10, MAP_CALL(DoSoundFade),               "oiiii",                kDoSoundFade_workarounds },
diff --git a/engines/sci/engine/savegame.cpp b/engines/sci/engine/savegame.cpp
index 0b55425..692fa77 100644
--- a/engines/sci/engine/savegame.cpp
+++ b/engines/sci/engine/savegame.cpp
@@ -617,6 +617,10 @@ void MusicEntry::saveLoadWithSerializer(Common::Serializer &s) {
 	s.syncAsSint32LE(fadeTicker);
 	s.syncAsSint32LE(fadeTickerStep);
 	s.syncAsByte(status);
+	if (s.getVersion() >= 32)
+		s.syncAsByte(playBed);
+	else if (s.isLoading())
+		playBed = false;
 
 	// pMidiParser and pStreamAud will be initialized when the
 	// sound list is reconstructed in gamestate_restore()
@@ -650,7 +654,7 @@ void SoundCommandParser::reconstructPlayList() {
 			if (_soundVersion >= SCI_VERSION_1_EARLY)
 				writeSelectorValue(_segMan, (*i)->soundObj, SELECTOR(vol), (*i)->volume);
 
-			processPlaySound((*i)->soundObj);
+			processPlaySound((*i)->soundObj, (*i)->playBed);
 		}
 	}
 }
diff --git a/engines/sci/engine/savegame.h b/engines/sci/engine/savegame.h
index 8f28356..be6d05c 100644
--- a/engines/sci/engine/savegame.h
+++ b/engines/sci/engine/savegame.h
@@ -37,6 +37,7 @@ struct EngineState;
  *
  * Version - new/changed feature
  * =============================
+ *      32 - new playBed flag in MusicEntry
  *      31 - priority for sound effects/music is now a signed int16, instead of a byte
  *      30 - synonyms
  *      29 - system strings
@@ -56,7 +57,7 @@ struct EngineState;
  */
 
 enum {
-	CURRENT_SAVEGAME_VERSION = 31,
+	CURRENT_SAVEGAME_VERSION = 32,
 	MINIMUM_SAVEGAME_VERSION = 14
 };
 
diff --git a/engines/sci/sound/music.cpp b/engines/sci/sound/music.cpp
index 05605c0..4606d66 100644
--- a/engines/sci/sound/music.cpp
+++ b/engines/sci/sound/music.cpp
@@ -334,6 +334,7 @@ void SciMusic::soundInitSnd(MusicEntry *pSnd) {
 			pSnd->pLoopStream = 0;
 			pSnd->soundType = Audio::Mixer::kSFXSoundType;
 			pSnd->hCurrentAud = Audio::SoundHandle();
+			pSnd->playBed = false;
 		} else {
 			// play MIDI track
 			Common::StackLock lock(_mutex);
@@ -380,6 +381,7 @@ void SciMusic::soundInitSnd(MusicEntry *pSnd) {
 			int16 prevHold = pSnd->hold;
 			pSnd->loop = 0;
 			pSnd->hold = -1;
+			pSnd->playBed = false;
 
 			pSnd->pMidiParser->loadMusic(track, pSnd, channelFilterMask, _soundVersion);
 			pSnd->reverb = pSnd->pMidiParser->getSongReverb();
diff --git a/engines/sci/sound/music.h b/engines/sci/sound/music.h
index 4e44074..0fbd5a0 100644
--- a/engines/sci/sound/music.h
+++ b/engines/sci/sound/music.h
@@ -85,6 +85,7 @@ public:
 	int16 volume;
 	int16 hold;
 	int8 reverb;
+	bool playBed;
 
 	int16 pauseCounter;
 	uint sampleLoopCounter;
diff --git a/engines/sci/sound/soundcmd.cpp b/engines/sci/sound/soundcmd.cpp
index 73e0a23..47ab9bd 100644
--- a/engines/sci/sound/soundcmd.cpp
+++ b/engines/sci/sound/soundcmd.cpp
@@ -142,11 +142,14 @@ void SoundCommandParser::processInitSound(reg_t obj) {
 
 reg_t SoundCommandParser::kDoSoundPlay(int argc, reg_t *argv, reg_t acc) {
 	debugC(kDebugLevelSound, "kDoSound(play): %04x:%04x", PRINT_REG(argv[0]));
-	processPlaySound(argv[0]);
+	bool playBed = false;
+	if (argc >= 2 && !argv[1].isNull())
+		playBed = true;
+	processPlaySound(argv[0], playBed);
 	return acc;
 }
 
-void SoundCommandParser::processPlaySound(reg_t obj) {
+void SoundCommandParser::processPlaySound(reg_t obj, bool playBed) {
 	MusicEntry *musicSlot = _music->getSlot(obj);
 	if (!musicSlot) {
 		warning("kDoSound(play): Slot not found (%04x:%04x), initializing it manually", PRINT_REG(obj));
@@ -185,11 +188,12 @@ void SoundCommandParser::processPlaySound(reg_t obj) {
 	// Reset hold when starting a new song. kDoSoundSetHold is always called after
 	// kDoSoundPlay to set it properly, if needed. Fixes bug #3413589.
 	musicSlot->hold = -1;
+	musicSlot->playBed = playBed;
 	if (_soundVersion >= SCI_VERSION_1_EARLY)
 		musicSlot->volume = readSelectorValue(_segMan, obj, SELECTOR(vol));
 
-	debugC(kDebugLevelSound, "kDoSound(play): %04x:%04x number %d, loop %d, prio %d, vol %d", PRINT_REG(obj),
-			resourceId, musicSlot->loop, musicSlot->priority, musicSlot->volume);
+	debugC(kDebugLevelSound, "kDoSound(play): %04x:%04x number %d, loop %d, prio %d, vol %d, bed %d", PRINT_REG(obj),
+			resourceId, musicSlot->loop, musicSlot->priority, musicSlot->volume, playBed ? 1 : 0);
 
 	_music->soundPlay(musicSlot);
 
@@ -777,6 +781,8 @@ void SoundCommandParser::stopAllSounds() {
 }
 
 void SoundCommandParser::startNewSound(int number) {
+	// NB: This is only used by the debugging console.
+
 	Common::StackLock lock(_music->_mutex);
 
 	// Overwrite the first sound in the playlist
@@ -785,7 +791,7 @@ void SoundCommandParser::startNewSound(int number) {
 	processDisposeSound(soundObj);
 	writeSelectorValue(_segMan, soundObj, SELECTOR(number), number);
 	processInitSound(soundObj);
-	processPlaySound(soundObj);
+	processPlaySound(soundObj, false);
 }
 
 void SoundCommandParser::setMasterVolume(int vol) {
diff --git a/engines/sci/sound/soundcmd.h b/engines/sci/sound/soundcmd.h
index 4effda6..5bb7cf2 100644
--- a/engines/sci/sound/soundcmd.h
+++ b/engines/sci/sound/soundcmd.h
@@ -63,7 +63,7 @@ public:
 	void printPlayList(Console *con);
 	void printSongInfo(reg_t obj, Console *con);
 
-	void processPlaySound(reg_t obj);
+	void processPlaySound(reg_t obj, bool playBed);
 	void processStopSound(reg_t obj, bool sampleFinishedPlaying);
 	void initSoundResource(MusicEntry *newSound);
 


Commit: 5964cc239b920a4a5d3b8475cb6c0b111e968e03
    https://github.com/scummvm/scummvm/commit/5964cc239b920a4a5d3b8475cb6c0b111e968e03
Author: Willem Jan Palenstijn (wjp at usecode.org)
Date: 2015-02-15T13:57:03+01:00

Commit Message:
SCI: Always re-sort playlist in soundPlay

Previously, it would only sort if a song wasn't already in the playlist.
Since initSound already adds it, this effectively prevented the list
from being sorted.

Changed paths:
    engines/sci/engine/savegame.cpp
    engines/sci/sound/music.cpp



diff --git a/engines/sci/engine/savegame.cpp b/engines/sci/engine/savegame.cpp
index 692fa77..eee4c49 100644
--- a/engines/sci/engine/savegame.cpp
+++ b/engines/sci/engine/savegame.cpp
@@ -639,8 +639,12 @@ void SoundCommandParser::syncPlayList(Common::Serializer &s) {
 void SoundCommandParser::reconstructPlayList() {
 	Common::StackLock lock(_music->_mutex);
 
-	const MusicList::iterator end = _music->getPlayListEnd();
-	for (MusicList::iterator i = _music->getPlayListStart(); i != end; ++i) {
+	// We store all songs here because starting songs may re-shuffle their order
+	MusicList songs;
+	for (MusicList::iterator i = _music->getPlayListStart(); i != _music->getPlayListEnd(); ++i)
+		songs.push_back(*i);
+
+	for (MusicList::iterator i = songs.begin(); i != songs.end(); ++i) {
 		initSoundResource(*i);
 
 		if ((*i)->status == kSoundPlaying) {
diff --git a/engines/sci/sound/music.cpp b/engines/sci/sound/music.cpp
index 4606d66..5b205c8 100644
--- a/engines/sci/sound/music.cpp
+++ b/engines/sci/sound/music.cpp
@@ -410,9 +410,10 @@ void SciMusic::soundPlay(MusicEntry *pSnd) {
 	}
 	if (playListNo == playListCount) { // not found
 		_playList.push_back(pSnd);
-		sortPlayList();
 	}
 
+	sortPlayList();
+
 	_mutex.unlock();	// unlock to perform mixer-related calls
 
 	if (pSnd->pMidiParser) {


Commit: e42a5123572cabf435a90eee2f9c01ababbe8528
    https://github.com/scummvm/scummvm/commit/e42a5123572cabf435a90eee2f9c01ababbe8528
Author: Willem Jan Palenstijn (wjp at usecode.org)
Date: 2015-02-15T13:57:11+01:00

Commit Message:
SCI: Don't remap channels from playBed songs

Changed paths:
    engines/sci/sound/music.cpp



diff --git a/engines/sci/sound/music.cpp b/engines/sci/sound/music.cpp
index 5b205c8..d58479f 100644
--- a/engines/sci/sound/music.cpp
+++ b/engines/sci/sound/music.cpp
@@ -397,6 +397,9 @@ void SciMusic::soundInitSnd(MusicEntry *pSnd) {
 void SciMusic::soundPlay(MusicEntry *pSnd) {
 	_mutex.lock();
 
+	// TODO: if pSnd->playBed, and version <= SCI1_EARLY, then kill
+	// existing sounds with playBed enabled.
+
 	uint playListCount = _playList.size();
 	uint playListNo = playListCount;
 	MusicEntry *alreadyPlaying = NULL;
@@ -1126,8 +1129,10 @@ ChannelRemapping *SciMusic::determineChannelMap() {
 			if (channel._mute)
 				continue;
 
+			bool dontRemap = channel._dontRemap || song->playBed;
+
 #ifdef DEBUG_REMAP
-			debug("  Channel %d: prio %d, %d voice%s%s", c, channel._prio, channel._voices, channel._voices == 1 ? "" : "s", channel._dontRemap ? ", dontRemap" : "" );
+			debug("  Channel %d: prio %d, %d voice%s%s", c, channel._prio, channel._voices, channel._voices == 1 ? "" : "s", dontRemap ? ", dontRemap" : "" );
 #endif
 
 			DeviceChannelUsage dc = { song, c };
@@ -1135,7 +1140,7 @@ ChannelRemapping *SciMusic::determineChannelMap() {
 			// our target
 			int devChannel = -1;
 
-			if (channel._dontRemap && map->_map[c]._song == 0) {
+			if (dontRemap && map->_map[c]._song == 0) {
 				// unremappable channel, with channel still free
 				devChannel = c;
 			}
@@ -1232,10 +1237,10 @@ ChannelRemapping *SciMusic::determineChannelMap() {
 			map->_map[devChannel] = dc;
 			map->_voices[devChannel] = neededVoices;
 			map->_prio[devChannel] = prio;
-			map->_dontRemap[devChannel] = channel._dontRemap;
+			map->_dontRemap[devChannel] = dontRemap;
 			map->_freeVoices -= neededVoices;
 
-			if (!channel._dontRemap || devChannel == c) {
+			if (!dontRemap || devChannel == c) {
 				// If this channel fits here, we're done.
 #ifdef DEBUG_REMAP
 				debug("    OK");


Commit: b80e74af5dec7675a2bf4a3f51da8501518c2be2
    https://github.com/scummvm/scummvm/commit/b80e74af5dec7675a2bf4a3f51da8501518c2be2
Author: Willem Jan Palenstijn (wjp at usecode.org)
Date: 2015-02-15T13:57:11+01:00

Commit Message:
SCI: Handle voice limits differently

For playBed songs, SCI1early remappers didn't unmap the entire song when
there weren't enough voices for a channel. Thanks waltervn.

Changed paths:
    engines/sci/sound/music.cpp



diff --git a/engines/sci/sound/music.cpp b/engines/sci/sound/music.cpp
index d58479f..f69f40e 100644
--- a/engines/sci/sound/music.cpp
+++ b/engines/sci/sound/music.cpp
@@ -1200,8 +1200,12 @@ ChannelRemapping *SciMusic::determineChannelMap() {
 			int neededVoices = channel._voices;
 			// do we have enough free voices?
 			if (map->_freeVoices < neededVoices) {
-				// We only care for essential channels
-				if (prio > 0) {
+				// We only care for essential channels.
+				// Note: In early SCI1 interpreters, a song started by 'playBed'
+				// would not be skipped even if some channels couldn't be
+				// mapped due to voice limits. So, we treat all channels as
+				// non-essential here for playBed songs.
+				if (prio > 0 || (song->playBed && _soundVersion <= SCI_VERSION_1_EARLY)) {
 #ifdef DEBUG_REMAP
 					debug("   not enough voices; need %d, have %d. Skipping this channel.", neededVoices, map->_freeVoices);
 #endif


Commit: 0aadd20aeaac1d241087e913a2bf8171bb0def68
    https://github.com/scummvm/scummvm/commit/0aadd20aeaac1d241087e913a2bf8171bb0def68
Author: Willem Jan Palenstijn (wjp at usecode.org)
Date: 2015-02-15T14:01:35+01:00

Commit Message:
SCI: Add debugging output

Changed paths:
    engines/sci/sound/midiparser_sci.cpp
    engines/sci/sound/music.cpp



diff --git a/engines/sci/sound/midiparser_sci.cpp b/engines/sci/sound/midiparser_sci.cpp
index 7ee9cc9..7ebe476 100644
--- a/engines/sci/sound/midiparser_sci.cpp
+++ b/engines/sci/sound/midiparser_sci.cpp
@@ -487,6 +487,8 @@ void MidiParser_SCI::trackState(uint32 b) {
 			s._sustain = (op2 != 0);
 			break;
 		case 0x4B: // voices
+			if (s._voices != op2)
+				warning("Voice change (%d to %d) without remapping", s._voices, op2);
 			s._voices = op2;
 			_pSnd->_chan[channel]._voices = op2; // Also sync our MusicEntry
 			break;
diff --git a/engines/sci/sound/music.cpp b/engines/sci/sound/music.cpp
index f69f40e..62b17b2 100644
--- a/engines/sci/sound/music.cpp
+++ b/engines/sci/sound/music.cpp
@@ -1111,7 +1111,8 @@ ChannelRemapping *SciMusic::determineChannelMap() {
 
 
 #ifdef DEBUG_REMAP
-		debug(" Song %d (%p), prio %d", songIndex, (void*)song, song->priority);
+		const char* name = g_sci->getEngineState()->_segMan->getObjectName(song->soundObj);
+		debug(" Song %d (%p) [%s], prio %d%s", songIndex, (void*)song, name, song->priority, song->playBed ? ", bed" : "");
 #endif
 
 		// Store backup. If we fail to map this song, we will revert to this.


Commit: 0018bb0f6f36fd1798ec92d2e7e6654e026fe19b
    https://github.com/scummvm/scummvm/commit/0018bb0f6f36fd1798ec92d2e7e6654e026fe19b
Author: Willem Jan Palenstijn (wjp at usecode.org)
Date: 2015-02-15T14:01:44+01:00

Commit Message:
SCI: Give songs that start playing later higher priority

Changed paths:
    engines/sci/sound/music.cpp
    engines/sci/sound/music.h



diff --git a/engines/sci/sound/music.cpp b/engines/sci/sound/music.cpp
index 62b17b2..2b73bcf 100644
--- a/engines/sci/sound/music.cpp
+++ b/engines/sci/sound/music.cpp
@@ -144,6 +144,7 @@ void SciMusic::init() {
 		_globalReverb = _pMidiDrv->getReverb();	// Init global reverb for SCI0
 
 	_currentlyPlayingSample = NULL;
+	_timeCounter = 0;
 }
 
 void SciMusic::miditimerCallback(void *p) {
@@ -285,8 +286,10 @@ byte SciMusic::getCurrentReverb() {
 	return _pMidiDrv->getReverb();
 }
 
+// A larger priority value has higher priority. For equal priority values,
+// songs that have been added later have higher priority.
 static bool musicEntryCompare(const MusicEntry *l, const MusicEntry *r) {
-	return (l->priority > r->priority);
+	return (l->priority > r->priority) || (l->priority == r->priority && l->time > r->time);
 }
 
 void SciMusic::sortPlayList() {
@@ -317,6 +320,8 @@ void SciMusic::soundInitSnd(MusicEntry *pSnd) {
 			track = digital;
 	}
 
+	pSnd->time = ++_timeCounter;
+
 	if (track) {
 		// Play digital sample
 		if (track->digitalChannelNr != -1) {
@@ -415,6 +420,7 @@ void SciMusic::soundPlay(MusicEntry *pSnd) {
 		_playList.push_back(pSnd);
 	}
 
+	pSnd->time = ++_timeCounter;
 	sortPlayList();
 
 	_mutex.unlock();	// unlock to perform mixer-related calls
@@ -560,6 +566,7 @@ void SciMusic::soundSetPriority(MusicEntry *pSnd, byte prio) {
 	Common::StackLock lock(_mutex);
 
 	pSnd->priority = prio;
+	pSnd->time = ++_timeCounter;
 	sortPlayList();
 }
 
diff --git a/engines/sci/sound/music.h b/engines/sci/sound/music.h
index 0fbd5a0..1347177 100644
--- a/engines/sci/sound/music.h
+++ b/engines/sci/sound/music.h
@@ -75,6 +75,8 @@ public:
 	SoundResource *soundRes;
 	uint16 resourceId;
 
+	int time; // "tim"estamp to indicate in which order songs have been added
+
 	bool isQueued; // for SCI0 only!
 
 	uint16 dataInc;
@@ -267,6 +269,9 @@ private:
 	int _driverLastChannel;
 
 	MusicEntry *_currentlyPlayingSample;
+
+	int _timeCounter; // Used to keep track of the order in which MusicEntries
+	                  // are added, for priority purposes.
 };
 
 } // End of namespace Sci


Commit: 5028487038fd3572d68af3cd253fc28917245e63
    https://github.com/scummvm/scummvm/commit/5028487038fd3572d68af3cd253fc28917245e63
Author: Willem Jan Palenstijn (wjp at usecode.org)
Date: 2015-02-15T14:05:36+01:00

Commit Message:
SCI: Use sound resource priority by default for songs

SCI1 sound resources can have an embedded priority. We now use that by
default, unless an explicit DoSound/SetPriority call overrides it.
Thanks waltervn.

This fixes relative priority of songs in at least PQ3 room 29.

Also increase savegame version to 33.

Changed paths:
    engines/sci/engine/savegame.cpp
    engines/sci/engine/savegame.h
    engines/sci/resource.h
    engines/sci/resource_audio.cpp
    engines/sci/sound/music.cpp
    engines/sci/sound/music.h
    engines/sci/sound/soundcmd.cpp



diff --git a/engines/sci/engine/savegame.cpp b/engines/sci/engine/savegame.cpp
index eee4c49..61f8058 100644
--- a/engines/sci/engine/savegame.cpp
+++ b/engines/sci/engine/savegame.cpp
@@ -621,6 +621,10 @@ void MusicEntry::saveLoadWithSerializer(Common::Serializer &s) {
 		s.syncAsByte(playBed);
 	else if (s.isLoading())
 		playBed = false;
+	if (s.getVersion() >= 33)
+		s.syncAsByte(overridePriority);
+	else if (s.isLoading())
+		overridePriority = false;
 
 	// pMidiParser and pStreamAud will be initialized when the
 	// sound list is reconstructed in gamestate_restore()
diff --git a/engines/sci/engine/savegame.h b/engines/sci/engine/savegame.h
index be6d05c..7f482ed 100644
--- a/engines/sci/engine/savegame.h
+++ b/engines/sci/engine/savegame.h
@@ -37,6 +37,7 @@ struct EngineState;
  *
  * Version - new/changed feature
  * =============================
+ *      33 - new overridePriority flag in MusicEntry
  *      32 - new playBed flag in MusicEntry
  *      31 - priority for sound effects/music is now a signed int16, instead of a byte
  *      30 - synonyms
@@ -57,7 +58,7 @@ struct EngineState;
  */
 
 enum {
-	CURRENT_SAVEGAME_VERSION = 32,
+	CURRENT_SAVEGAME_VERSION = 33,
 	MINIMUM_SAVEGAME_VERSION = 14
 };
 
diff --git a/engines/sci/resource.h b/engines/sci/resource.h
index 62f3c58..ef48998 100644
--- a/engines/sci/resource.h
+++ b/engines/sci/resource.h
@@ -596,6 +596,7 @@ public:
 	Track *getDigitalTrack();
 	int getChannelFilterMask(int hardwareMask, bool wantsRhythm);
 	byte getInitialVoiceCount(byte channel);
+	byte getSoundPriority() const { return _soundPriority; }
 
 private:
 	SciVersion _soundVersion;
@@ -603,6 +604,7 @@ private:
 	Track *_tracks;
 	Resource *_innerResource;
 	ResourceManager *_resMan;
+	byte _soundPriority;
 };
 
 } // End of namespace Sci
diff --git a/engines/sci/resource_audio.cpp b/engines/sci/resource_audio.cpp
index c775f50..3a43774 100644
--- a/engines/sci/resource_audio.cpp
+++ b/engines/sci/resource_audio.cpp
@@ -579,6 +579,7 @@ SoundResource::SoundResource(uint32 resourceNr, ResourceManager *resMan, SciVers
 		return;
 
 	_innerResource = resource;
+	_soundPriority = 0xFF;
 
 	byte *data, *data2;
 	byte *dataEnd;
@@ -725,6 +726,9 @@ SoundResource::SoundResource(uint32 resourceNr, ResourceManager *resMan, SciVers
 					data += 6;
 				}
 			} else {
+				// The first byte of the 0xF0 track's channel list is priority
+				_soundPriority = *data;
+
 				// Skip over digital track
 				data += 6;
 			}
diff --git a/engines/sci/sound/music.cpp b/engines/sci/sound/music.cpp
index 2b73bcf..dab02c9 100644
--- a/engines/sci/sound/music.cpp
+++ b/engines/sci/sound/music.cpp
@@ -340,6 +340,7 @@ void SciMusic::soundInitSnd(MusicEntry *pSnd) {
 			pSnd->soundType = Audio::Mixer::kSFXSoundType;
 			pSnd->hCurrentAud = Audio::SoundHandle();
 			pSnd->playBed = false;
+			pSnd->overridePriority = false;
 		} else {
 			// play MIDI track
 			Common::StackLock lock(_mutex);
@@ -387,6 +388,7 @@ void SciMusic::soundInitSnd(MusicEntry *pSnd) {
 			pSnd->loop = 0;
 			pSnd->hold = -1;
 			pSnd->playBed = false;
+			pSnd->overridePriority = false;
 
 			pSnd->pMidiParser->loadMusic(track, pSnd, channelFilterMask, _soundVersion);
 			pSnd->reverb = pSnd->pMidiParser->getSongReverb();
diff --git a/engines/sci/sound/music.h b/engines/sci/sound/music.h
index 1347177..8770748 100644
--- a/engines/sci/sound/music.h
+++ b/engines/sci/sound/music.h
@@ -88,6 +88,7 @@ public:
 	int16 hold;
 	int8 reverb;
 	bool playBed;
+	bool overridePriority; // Use soundObj's priority instead of resource's
 
 	int16 pauseCounter;
 	uint sampleLoopCounter;
diff --git a/engines/sci/sound/soundcmd.cpp b/engines/sci/sound/soundcmd.cpp
index 47ab9bd..682c88f 100644
--- a/engines/sci/sound/soundcmd.cpp
+++ b/engines/sci/sound/soundcmd.cpp
@@ -184,7 +184,15 @@ void SoundCommandParser::processPlaySound(reg_t obj, bool playBed) {
 	}
 
 	musicSlot->loop = readSelectorValue(_segMan, obj, SELECTOR(loop));
-	musicSlot->priority = readSelectorValue(_segMan, obj, SELECTOR(priority));
+
+	// Get song priority from either obj or soundRes
+	byte resourcePriority = musicSlot->soundRes->getSoundPriority();
+	if (!musicSlot->overridePriority && resourcePriority != 0xFF) {
+		musicSlot->priority = resourcePriority;
+	} else {
+		musicSlot->priority = readSelectorValue(_segMan, obj, SELECTOR(priority));
+	}
+
 	// Reset hold when starting a new song. kDoSoundSetHold is always called after
 	// kDoSoundPlay to set it properly, if needed. Fixes bug #3413589.
 	musicSlot->hold = -1;
@@ -677,23 +685,19 @@ reg_t SoundCommandParser::kDoSoundSetPriority(int argc, reg_t *argv, reg_t acc)
 	}
 
 	if (value == -1) {
-		uint16 resourceId = musicSlot->resourceId;
+		musicSlot->overridePriority = false;
+		musicSlot->priority = 0;
 
-		// Set priority from the song data
-		Resource *song = _resMan->findResource(ResourceId(kResourceTypeSound, resourceId), 0);
-		if (song->data[0] == 0xf0)
-			_music->soundSetPriority(musicSlot, song->data[1]);
-		else
-			warning("kDoSound(setPriority): Attempt to unset song priority when there is no built-in value");
+		// NB: It seems SSCI doesn't actually reset the priority here.
 
-		//pSnd->prio=0;field_15B=0
 		writeSelectorValue(_segMan, obj, SELECTOR(flags), readSelectorValue(_segMan, obj, SELECTOR(flags)) & 0xFD);
 	} else {
 		// Scripted priority
+		musicSlot->overridePriority = true;
 
-		//pSnd->field_15B=1;
 		writeSelectorValue(_segMan, obj, SELECTOR(flags), readSelectorValue(_segMan, obj, SELECTOR(flags)) | 2);
-		//DoSOund(0xF,hobj,w)
+
+		_music->soundSetPriority(musicSlot, value);
 	}
 	return acc;
 }


Commit: 1c5722f014d1f5a34c79d8d1cb7f5ed86e0b822d
    https://github.com/scummvm/scummvm/commit/1c5722f014d1f5a34c79d8d1cb7f5ed86e0b822d
Author: Willem Jan Palenstijn (wjp at usecode.org)
Date: 2015-02-15T14:05:56+01:00

Commit Message:
SCI: Allow channel remapping from audio thread too

Changed paths:
    engines/sci/sound/midiparser_sci.cpp
    engines/sci/sound/music.cpp
    engines/sci/sound/music.h



diff --git a/engines/sci/sound/midiparser_sci.cpp b/engines/sci/sound/midiparser_sci.cpp
index 7ebe476..25facac 100644
--- a/engines/sci/sound/midiparser_sci.cpp
+++ b/engines/sci/sound/midiparser_sci.cpp
@@ -487,8 +487,11 @@ void MidiParser_SCI::trackState(uint32 b) {
 			s._sustain = (op2 != 0);
 			break;
 		case 0x4B: // voices
-			if (s._voices != op2)
-				warning("Voice change (%d to %d) without remapping", s._voices, op2);
+			if (s._voices != op2) {
+				// CHECKME: Should we directly call remapChannels() if _mainThreadCalled?
+				debugC(2, kDebugLevelSound, "Dynamic voice change (%d to %d)", s._voices, op2);
+				_music->needsRemap();
+			}
 			s._voices = op2;
 			_pSnd->_chan[channel]._voices = op2; // Also sync our MusicEntry
 			break;
@@ -500,8 +503,9 @@ void MidiParser_SCI::trackState(uint32 b) {
 				bool m = op2;
 				if (_pSnd->_chan[channel]._mute != m) {
 					_pSnd->_chan[channel]._mute = m;
-					// TODO: If muting/unmuting a channel, remap channels.
-					warning("Mute change without immediate remapping (mainThread = %d)", _mainThreadCalled);
+					// CHECKME: Should we directly call remapChannels() if _mainThreadCalled?
+					_music->needsRemap();
+					debugC(2, kDebugLevelSound, "Dynamic mute change (mainThread = %d)", _mainThreadCalled);
 				}
 			}
 			break;
diff --git a/engines/sci/sound/music.cpp b/engines/sci/sound/music.cpp
index dab02c9..37bf6a7 100644
--- a/engines/sci/sound/music.cpp
+++ b/engines/sci/sound/music.cpp
@@ -145,6 +145,7 @@ void SciMusic::init() {
 
 	_currentlyPlayingSample = NULL;
 	_timeCounter = 0;
+	_needsRemap = false;
 }
 
 void SciMusic::miditimerCallback(void *p) {
@@ -159,6 +160,11 @@ void SciMusic::onTimer() {
 	// sending out queued commands that were "sent" via main thread
 	sendMidiCommandsFromQueue();
 
+	// remap channels, if requested
+	if (_needsRemap)
+		remapChannels(false);
+	_needsRemap = false;
+
 	for (MusicList::iterator i = _playList.begin(); i != end; ++i)
 		(*i)->onTimer();
 }
@@ -920,12 +926,12 @@ int ChannelRemapping::lowestPrio() const {
 }
 
 
-void SciMusic::remapChannels() {
+void SciMusic::remapChannels(bool mainThread) {
 	if (_soundVersion <= SCI_VERSION_0_LATE)
 		return;
 
-	// NB: This function should only be called from the main thread,
-	// with _mutex locked
+	// NB: This function should only be called with _mutex locked
+	// Make sure to set the mainThread argument correctly.
 
 
 	ChannelRemapping *map = determineChannelMap();
@@ -978,9 +984,9 @@ void SciMusic::remapChannels() {
 
 		for (int j = 0; j < 16; ++j) {
 			if (!channelMapped[j]) {
-				song->pMidiParser->mainThreadBegin();
+				if (mainThread) song->pMidiParser->mainThreadBegin();
 				song->pMidiParser->remapChannel(j, -1);
-				song->pMidiParser->mainThreadEnd();
+				if (mainThread) song->pMidiParser->mainThreadEnd();
 #ifdef DEBUG_REMAP
 				if (channelUsed[j])
 					debug(" Unmapping song %d, channel %d", songIndex, j);
@@ -1012,9 +1018,9 @@ void SciMusic::remapChannels() {
 #ifdef DEBUG_REMAP
 			debug(" Mapping (dontRemap) song %d, channel %d to device channel %d", songIndex, _channelMap[i]._channel, i);
 #endif
-			_channelMap[i]._song->pMidiParser->mainThreadBegin();
+			if (mainThread) _channelMap[i]._song->pMidiParser->mainThreadBegin();
 			_channelMap[i]._song->pMidiParser->remapChannel(_channelMap[i]._channel, i);
-			_channelMap[i]._song->pMidiParser->mainThreadEnd();
+			if (mainThread) _channelMap[i]._song->pMidiParser->mainThreadEnd();
 		}
 
 	}
@@ -1067,9 +1073,9 @@ void SciMusic::remapChannels() {
 #ifdef DEBUG_REMAP
 				debug(" Mapping song %d, channel %d to device channel %d", songIndex, _channelMap[j]._channel, j);
 #endif
-				_channelMap[j]._song->pMidiParser->mainThreadBegin();
+				if (mainThread) _channelMap[j]._song->pMidiParser->mainThreadBegin();
 				_channelMap[j]._song->pMidiParser->remapChannel(_channelMap[j]._channel, j);
-				_channelMap[j]._song->pMidiParser->mainThreadEnd();
+				if (mainThread) _channelMap[j]._song->pMidiParser->mainThreadEnd();
 				break;
 			}
 		}
@@ -1079,7 +1085,7 @@ void SciMusic::remapChannels() {
 	// And finally, stop any empty channels
 	for (int i = _driverLastChannel; i >= _driverFirstChannel; --i) {
 		if (!_channelMap[i]._song && currentMap[i]._song)
-			resetDeviceChannel(i);
+			resetDeviceChannel(i, mainThread);
 	}
 
 	delete map;
@@ -1307,14 +1313,18 @@ ChannelRemapping *SciMusic::determineChannelMap() {
 	return map;
 }
 
-void SciMusic::resetDeviceChannel(int devChannel) {
-	// NB: This function should only be called from the main thread
-
+void SciMusic::resetDeviceChannel(int devChannel, bool mainThread) {
 	assert(devChannel >= 0 && devChannel <= 0x0F);
 
-	putMidiCommandInQueue(0x0040B0 | devChannel); // sustain off
-	putMidiCommandInQueue(0x007BB0 | devChannel); // notes off
-	putMidiCommandInQueue(0x004BB0 | devChannel); // release voices
+	if (mainThread) {
+		putMidiCommandInQueue(0x0040B0 | devChannel); // sustain off
+		putMidiCommandInQueue(0x007BB0 | devChannel); // notes off
+		putMidiCommandInQueue(0x004BB0 | devChannel); // release voices
+	} else {
+		_pMidiDrv->send(0x0040B0 | devChannel); // sustain off
+		_pMidiDrv->send(0x007BB0 | devChannel); // notes off
+		_pMidiDrv->send(0x004BB0 | devChannel); // release voices
+	}
 }
 
 
diff --git a/engines/sci/sound/music.h b/engines/sci/sound/music.h
index 8770748..a610f32 100644
--- a/engines/sci/sound/music.h
+++ b/engines/sci/sound/music.h
@@ -228,6 +228,8 @@ public:
 
 	byte getCurrentReverb();
 
+	void needsRemap() { _needsRemap = true; }
+
 	virtual void saveLoadWithSerializer(Common::Serializer &ser);
 
 	// Mutex for music code. Used to guard access to the song playlist, to the
@@ -249,9 +251,9 @@ protected:
 	bool _useDigitalSFX;
 
 	// remapping:
-	void remapChannels();
+	void remapChannels(bool mainThread = true);
 	ChannelRemapping *determineChannelMap();
-	void resetDeviceChannel(int devChannel);
+	void resetDeviceChannel(int devChannel, bool mainThread);
 
 private:
 	MusicList _playList;
@@ -260,6 +262,7 @@ private:
 	MusicEntry *_usedChannel[16];
 	int8 _channelRemap[16];
 	int8 _globalReverb;
+	bool _needsRemap;
 
 	DeviceChannelUsage _channelMap[16];
 


Commit: d0cb5f51fddcd74461914fb28ef4fbd685833eae
    https://github.com/scummvm/scummvm/commit/d0cb5f51fddcd74461914fb28ef4fbd685833eae
Author: Willem Jan Palenstijn (wjp at usecode.org)
Date: 2015-02-15T14:14:28+01:00

Commit Message:
SCI: Only allow a single 'playBed' song in SCI1early

Changed paths:
    engines/sci/sound/music.cpp



diff --git a/engines/sci/sound/music.cpp b/engines/sci/sound/music.cpp
index 37bf6a7..7156e3c 100644
--- a/engines/sci/sound/music.cpp
+++ b/engines/sci/sound/music.cpp
@@ -410,8 +410,22 @@ void SciMusic::soundInitSnd(MusicEntry *pSnd) {
 void SciMusic::soundPlay(MusicEntry *pSnd) {
 	_mutex.lock();
 
-	// TODO: if pSnd->playBed, and version <= SCI1_EARLY, then kill
-	// existing sounds with playBed enabled.
+	if (_soundVersion <= SCI_VERSION_1_EARLY && pSnd->playBed) {
+		// If pSnd->playBed, and version <= SCI1_EARLY, then kill
+		// existing sounds with playBed enabled.
+
+		uint playListCount = _playList.size();
+		for (uint i = 0; i < playListCount; i++) {
+			if (_playList[i] != pSnd && _playList[i]->playBed) {
+				debugC(2, kDebugLevelSound, "Automatically stopping old playBed song from soundPlay");
+				MusicEntry *old = _playList[i];
+				_mutex.unlock();
+				soundStop(old);
+				_mutex.lock();
+				break;
+			}
+		}
+	}
 
 	uint playListCount = _playList.size();
 	uint playListNo = playListCount;


Commit: 2b49b5f95e8d6bd5ea3ab8ffb20ebad2ae7fc95e
    https://github.com/scummvm/scummvm/commit/2b49b5f95e8d6bd5ea3ab8ffb20ebad2ae7fc95e
Author: Willem Jan Palenstijn (wjp at usecode.org)
Date: 2015-02-15T14:14:46+01:00

Commit Message:
SCI: Fix sound object frame selector rate

Thanks waltervn. Verified against asm (QfG2, KQ6CD)

Changed paths:
    engines/sci/sound/soundcmd.cpp



diff --git a/engines/sci/sound/soundcmd.cpp b/engines/sci/sound/soundcmd.cpp
index 682c88f..64991cb 100644
--- a/engines/sci/sound/soundcmd.cpp
+++ b/engines/sci/sound/soundcmd.cpp
@@ -550,7 +550,7 @@ void SoundCommandParser::processUpdateCues(reg_t obj) {
 	if (_soundVersion >= SCI_VERSION_1_EARLY) {
 		writeSelectorValue(_segMan, obj, SELECTOR(min), musicSlot->ticker / 3600);
 		writeSelectorValue(_segMan, obj, SELECTOR(sec), musicSlot->ticker % 3600 / 60);
-		writeSelectorValue(_segMan, obj, SELECTOR(frame), musicSlot->ticker);
+		writeSelectorValue(_segMan, obj, SELECTOR(frame), musicSlot->ticker % 60 / 2);
 	}
 }
 


Commit: 6dcc8b03b89902020f7a52f4823706bc8376e0b3
    https://github.com/scummvm/scummvm/commit/6dcc8b03b89902020f7a52f4823706bc8376e0b3
Author: Willem Jan Palenstijn (wjp at usecode.org)
Date: 2015-02-15T14:16:02+01:00

Commit Message:
Merge branch 'sci_audio'

This branch contains a number of improvements to how song priorities are
handled. We are now much closer to how SSCI treats priority.

It also increases the SCI savegame version from 31 to 33.

Changed paths:
    engines/sci/console.cpp
    engines/sci/engine/kernel_tables.h
    engines/sci/engine/savegame.cpp
    engines/sci/engine/savegame.h
    engines/sci/resource.h
    engines/sci/resource_audio.cpp
    engines/sci/sound/midiparser_sci.cpp
    engines/sci/sound/music.cpp
    engines/sci/sound/music.h
    engines/sci/sound/soundcmd.cpp
    engines/sci/sound/soundcmd.h









More information about the Scummvm-git-logs mailing list