[Scummvm-cvs-logs] SF.net SVN: scummvm:[54478] scummvm/trunk/engines/sci

thebluegr at users.sourceforge.net thebluegr at users.sourceforge.net
Thu Nov 25 17:09:46 CET 2010


Revision: 54478
          http://scummvm.svn.sourceforge.net/scummvm/?rev=54478&view=rev
Author:   thebluegr
Date:     2010-11-25 16:09:45 +0000 (Thu, 25 Nov 2010)

Log Message:
-----------
SCI: implemented reverb handling and related functionality

Modified Paths:
--------------
    scummvm/trunk/engines/sci/engine/savegame.cpp
    scummvm/trunk/engines/sci/sound/midiparser_sci.cpp
    scummvm/trunk/engines/sci/sound/midiparser_sci.h
    scummvm/trunk/engines/sci/sound/music.cpp
    scummvm/trunk/engines/sci/sound/music.h
    scummvm/trunk/engines/sci/sound/soundcmd.cpp

Modified: scummvm/trunk/engines/sci/engine/savegame.cpp
===================================================================
--- scummvm/trunk/engines/sci/engine/savegame.cpp	2010-11-25 15:59:30 UTC (rev 54477)
+++ scummvm/trunk/engines/sci/engine/savegame.cpp	2010-11-25 16:09:45 UTC (rev 54478)
@@ -601,6 +601,7 @@
 		soundRes = 0;
 		pMidiParser = 0;
 		pStreamAud = 0;
+		reverb = -1;	// invalid reverb, will be initialized in processInitSound()
 	}
 }
 

Modified: scummvm/trunk/engines/sci/sound/midiparser_sci.cpp
===================================================================
--- scummvm/trunk/engines/sci/sound/midiparser_sci.cpp	2010-11-25 15:59:30 UTC (rev 54477)
+++ scummvm/trunk/engines/sci/sound/midiparser_sci.cpp	2010-11-25 16:09:45 UTC (rev 54478)
@@ -500,11 +500,16 @@
 			// http://wiki.scummvm.org/index.php/SCI/Specifications/Sound/SCI0_Resource_Format#Status_Reference
 			// Also, sci/sound/iterator/iterator.cpp, function BaseSongIterator::parseMidiCommand()
 			switch (info.basic.param1) {
-			case kSetReverb:
-				// TODO: This should be the song's reverb, and we need to check it against
-				// the global one
-				if (info.basic.param2 != 127)	// 127: SCI invalid, ignore
-					((MidiPlayer *)_driver)->setReverb(info.basic.param2);
+			case kSetReverb: {
+					MidiPlayer *driver = ((MidiPlayer *)_driver);
+					if (info.basic.param2 == 127) {		// Set global reverb instead
+						byte globalReverb = _music->getGlobalReverb();
+						if (globalReverb != 127)
+							driver->setReverb(globalReverb);
+					} else {
+						driver->setReverb(info.basic.param2);
+					}
+				}
 				break;
 			case kMidiHold:
 				// Check if the hold ID marker is the same as the hold ID
@@ -627,6 +632,74 @@
 	}// switch (info.command())
 }
 
+byte MidiParser_SCI::getSongReverb() {
+	byte curEvent = 0, prevEvent = 0, command = 0;
+	bool endOfTrack = false;
+	const byte *channelData = _mixedData;
+
+	do {
+		while (*channelData == 0xF8)
+			channelData++;
+
+		channelData++;	// delta
+
+		if ((*channelData & 0xF0) >= 0x80)
+			curEvent = *(channelData++);
+		else
+			curEvent = prevEvent;
+		if (curEvent < 0x80)
+			continue;
+
+		prevEvent = curEvent;
+		command = curEvent >> 4;
+
+		byte channel;
+
+		switch (command) {
+		case 0xC:	// program change
+		case 0xD:
+			channelData++;	// param1
+			break;
+		case 0xB: {
+				byte param1 = *channelData++;
+				byte param2 = *channelData++;
+				channel = curEvent & 0x0F;
+				if (channel == 0xF) {	// SCI special
+					if (param1 == kSetReverb)
+						return param2;
+				}
+			}
+			break;
+		case 0x8:
+		case 0x9:
+		case 0xA:
+		case 0xE:
+			channelData++;	// param1
+			channelData++;	// param2
+			break;
+		case 0xF:
+			if ((curEvent & 0x0F) == 0x2) {
+				channelData++;	// param1
+				channelData++;	// param2
+			} else if ((curEvent & 0x0F) == 0x3) {
+				channelData++;	// param1
+			} else if ((curEvent & 0x0F) == 0xF) {	// META
+				byte type = *channelData++;
+				if (type == 0x2F) {// end of track reached
+					endOfTrack = true;
+				} else {
+					// no further processing necessary
+				}
+			}
+			break;
+		default:
+			break;
+		}
+	} while (!endOfTrack);
+
+	return 127;	// no reverb found, return invalid
+}
+
 void MidiParser_SCI::allNotesOff() {
 	if (!_driver)
 		return;

Modified: scummvm/trunk/engines/sci/sound/midiparser_sci.h
===================================================================
--- scummvm/trunk/engines/sci/sound/midiparser_sci.h	2010-11-25 15:59:30 UTC (rev 54477)
+++ scummvm/trunk/engines/sci/sound/midiparser_sci.h	2010-11-25 16:09:45 UTC (rev 54478)
@@ -80,6 +80,7 @@
 	void allNotesOff();
 
 	const byte *getMixedData() const { return _mixedData; }
+	byte getSongReverb();
 
 	void tryToOwnChannels();
 	void lostChannels();

Modified: scummvm/trunk/engines/sci/sound/music.cpp
===================================================================
--- scummvm/trunk/engines/sci/sound/music.cpp	2010-11-25 15:59:30 UTC (rev 54477)
+++ scummvm/trunk/engines/sci/sound/music.cpp	2010-11-25 16:09:45 UTC (rev 54478)
@@ -39,7 +39,7 @@
 namespace Sci {
 
 SciMusic::SciMusic(SciVersion soundVersion)
-	: _soundVersion(soundVersion), _soundOn(true), _masterVolume(0) {
+	: _soundVersion(soundVersion), _soundOn(true), _masterVolume(0), _globalReverb(-1) {
 
 	// Reserve some space in the playlist, to avoid expensive insertion
 	// operations
@@ -225,15 +225,30 @@
 	return highestPrioritySlot;
 }
 
-void SciMusic::setGlobalReverb(byte reverb) {
+void SciMusic::setGlobalReverb(int8 reverb) {
 	Common::StackLock lock(_mutex);
 	if (reverb != 127) {
 		// Set global reverb normally
-		// TODO: Set global music reverb
-		// TODO: Only set reverb when the reverb of the active song is 127
-		_pMidiDrv->setReverb(reverb);
+		_globalReverb = reverb;
+
+		// Check the reverb of the active song...
+		const MusicList::iterator end = _playList.end();
+		for (MusicList::iterator i = _playList.begin(); i != end; ++i) {
+			if ((*i)->status == kSoundPlaying) {
+				if ((*i)->reverb == 127)			// Active song has no reverb
+					_pMidiDrv->setReverb(reverb);	// Set the global reverb
+				break;
+			}
+		}
 	} else {
-		// TODO: Set reverb of the active song
+		// Set reverb of the active song
+		const MusicList::iterator end = _playList.end();
+		for (MusicList::iterator i = _playList.begin(); i != end; ++i) {
+			if ((*i)->status == kSoundPlaying) {
+				_pMidiDrv->setReverb((*i)->reverb);	// Set the song's reverb
+				break;
+			}
+		}
 	}
 }
 
@@ -300,6 +315,7 @@
 
 			pSnd->pMidiParser->mainThreadBegin();
 			pSnd->pMidiParser->loadMusic(track, pSnd, channelFilterMask, _soundVersion);
+			pSnd->reverb = pSnd->pMidiParser->getSongReverb();
 			pSnd->pMidiParser->mainThreadEnd();
 			_mutex.unlock();
 		}

Modified: scummvm/trunk/engines/sci/sound/music.h
===================================================================
--- scummvm/trunk/engines/sci/sound/music.h	2010-11-25 15:59:30 UTC (rev 54477)
+++ scummvm/trunk/engines/sci/sound/music.h	2010-11-25 16:09:45 UTC (rev 54478)
@@ -76,7 +76,7 @@
 	uint16 loop;
 	int16 volume;
 	int16 hold;
-	int16 reverb;
+	int8 reverb;
 
 	int16 pauseCounter;
 	uint sampleLoopCounter;
@@ -188,7 +188,9 @@
 	void sendMidiCommand(uint32 cmd);
 	void sendMidiCommand(MusicEntry *pSnd, uint32 cmd);
 
-	void setGlobalReverb(byte reverb);
+	void setGlobalReverb(int8 reverb);
+	int8 getGlobalReverb() { return _globalReverb; }
+
 	byte getCurrentReverb();
 
 	virtual void saveLoadWithSerializer(Common::Serializer &ser);
@@ -220,6 +222,7 @@
 	bool _soundOn;
 	byte _masterVolume;
 	MusicEntry *_usedChannel[16];
+	int8 _globalReverb;
 
 	MidiCommandQueue _queuedCommands;
 	MusicType _musicType;

Modified: scummvm/trunk/engines/sci/sound/soundcmd.cpp
===================================================================
--- scummvm/trunk/engines/sci/sound/soundcmd.cpp	2010-11-25 15:59:30 UTC (rev 54477)
+++ scummvm/trunk/engines/sci/sound/soundcmd.cpp	2010-11-25 16:09:45 UTC (rev 54478)
@@ -75,6 +75,7 @@
 	newSound->priority = readSelectorValue(_segMan, obj, SELECTOR(pri)) & 0xFF;
 	if (_soundVersion >= SCI_VERSION_1_EARLY)
 		newSound->volume = CLIP<int>(readSelectorValue(_segMan, obj, SELECTOR(vol)), 0, MUSIC_VOLUME_MAX);
+	newSound->reverb = -1;	// initialize to SCI invalid, it'll be set correctly in soundInitSnd() below
 
 	debugC(2, kDebugLevelSound, "kDoSound(init): %04x:%04x number %d, loop %d, prio %d, vol %d", PRINT_REG(obj),
 			resourceId,	newSound->loop, newSound->priority, newSound->volume);


This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.




More information about the Scummvm-git-logs mailing list