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

thebluegr at users.sourceforge.net thebluegr at users.sourceforge.net
Fri Jun 11 16:47:14 CEST 2010


Revision: 49597
          http://scummvm.svn.sourceforge.net/scummvm/?rev=49597&view=rev
Author:   thebluegr
Date:     2010-06-11 14:47:13 +0000 (Fri, 11 Jun 2010)

Log Message:
-----------
- Added a new debug command, verify_midi, which can be used to check all the songs of a game for unmapped instruments (still WIP and disabled)
- Fixed a bug in the verify_scripts command (it was loading the script resource twice)

Modified Paths:
--------------
    scummvm/trunk/engines/sci/console.cpp
    scummvm/trunk/engines/sci/console.h
    scummvm/trunk/engines/sci/sound/midiparser_sci.cpp
    scummvm/trunk/engines/sci/sound/midiparser_sci.h

Modified: scummvm/trunk/engines/sci/console.cpp
===================================================================
--- scummvm/trunk/engines/sci/console.cpp	2010-06-11 11:08:37 UTC (rev 49596)
+++ scummvm/trunk/engines/sci/console.cpp	2010-06-11 14:47:13 UTC (rev 49597)
@@ -39,6 +39,7 @@
 #include "sci/sound/iterator/songlib.h"	// for SongLibrary
 #include "sci/sound/iterator/iterator.h"	// for SCI_SONG_ITERATOR_TYPE_SCI0
 #else
+#include "sci/sound/midiparser_sci.h"
 #include "sci/sound/music.h"
 #endif
 #include "sci/sound/drivers/mididriver.h"
@@ -106,6 +107,7 @@
 	DCmd_Register("list",				WRAP_METHOD(Console, cmdList));
 	DCmd_Register("hexgrep",			WRAP_METHOD(Console, cmdHexgrep));
 	DCmd_Register("verify_scripts",		WRAP_METHOD(Console, cmdVerifyScripts));
+	DCmd_Register("verify_midi",		WRAP_METHOD(Console, cmdVerifyMidi));
 	// Game
 	DCmd_Register("save_game",			WRAP_METHOD(Console, cmdSaveGame));
 	DCmd_Register("restore_game",		WRAP_METHOD(Console, cmdRestoreGame));
@@ -326,6 +328,7 @@
 	DebugPrintf(" list - Lists all the resources of a given type\n");
 	DebugPrintf(" hexgrep - Searches some resources for a particular sequence of bytes, represented as hexadecimal numbers\n");
 	DebugPrintf(" verify_scripts - Performs sanity checks on SCI1.1-SCI2.1 game scripts (e.g. if they're up to 64KB in total)\n");
+	DebugPrintf(" verify_midi - Performs checks on MIDI patches, for unmapped instruments\n");
 	DebugPrintf("\n");
 	DebugPrintf("Game:\n");
 	DebugPrintf(" save_game - Saves the current game state to the hard disk\n");
@@ -832,7 +835,7 @@
 		if (!script)
 			DebugPrintf("Error: script %d couldn't be loaded\n", itr->number);
 
-		heap = _engine->getResMan()->findResource(*itr, false);
+		heap = _engine->getResMan()->findResource(ResourceId(kResourceTypeHeap, itr->number), false);
 		if (!heap)
 			DebugPrintf("Error: script %d doesn't have a corresponding heap\n", itr->number);
 
@@ -848,6 +851,107 @@
 	return true;
 }
 
+bool Console::cmdVerifyMidi(int argc, const char **argv) {
+	// TODO: Sometimes this goes out of bounds with some songs, as it misses
+	// the EOT signal
+#if 0
+	SciVersion doSoundVersion = _engine->_features->detectDoSoundType();
+	MidiPlayer *player = MidiPlayer_Midi_create(doSoundVersion);
+	MidiParser_SCI *parser = new MidiParser_SCI(doSoundVersion);
+	parser->setMidiDriver(player);
+
+	Common::List<ResourceId> *resources = _engine->getResMan()->listResources(kResourceTypeSound);
+	sort(resources->begin(), resources->end(), ResourceIdLess());
+	Common::List<ResourceId>::iterator itr = resources->begin();
+
+	DebugPrintf("%d sounds found, checking their instrument mappings...\n", resources->size());
+
+	SoundResource *sound;
+
+	while (itr != resources->end()) {
+		sound = new SoundResource(itr->number, _engine->getResMan(), doSoundVersion);
+		int channelFilterMask = sound->getChannelFilterMask(player->getPlayId(), player->hasRhythmChannel());
+		SoundResource::Track *track = sound->getTrackByType(player->getPlayId());
+		if (track->digitalChannelNr != -1) {
+			// Skip digitized sound effects
+			delete sound;
+			continue;
+		}
+
+		parser->loadMusic(track, NULL, channelFilterMask, doSoundVersion);
+		const byte *channelData = parser->getMixedData();
+
+		byte param1 = 0;
+		byte command = 0, prev = 0;
+		byte curEvent = 0;
+		bool endOfTrack = false;
+
+		do {
+			while (*channelData == 0xF8)
+				channelData++;
+
+			channelData++;	// delta
+
+			if ((*channelData & 0xF0) >= 0x80)
+				curEvent = *(channelData++);
+			else
+				curEvent = prev;
+			if (curEvent < 0x80)
+				continue;
+
+			prev = curEvent;
+			command = curEvent >> 4;
+
+			switch (command) {
+			case 0xC:	// program change
+				param1 = *channelData++;
+				// TODO: verify that the instrument is mapped
+				printf("Song %d, patch %d\n", itr->number, param1);
+				break;
+			case 0xD:
+			case 0xB:
+				param1 = *channelData++;
+				break;
+			case 0x8:
+			case 0x9:
+			case 0xA:
+			case 0xE:
+				param1 = *channelData++;
+				*channelData++;	// param2
+				break;
+			case 0xF:
+				if ((curEvent & 0x0F) == 0x2) {
+					param1 = *channelData++;
+					*channelData++;	// param2
+				} else if ((curEvent & 0x0F) == 0x3) {
+					param1 = *channelData++;
+				} 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);
+
+		delete sound;
+		++itr;
+	}
+
+	delete parser;
+	delete player;
+
+	DebugPrintf("Music check finished\n");
+#endif
+
+	return true;
+}
+
 bool Console::cmdList(int argc, const char **argv) {
 	if (argc < 2) {
 		DebugPrintf("Lists all the resources of a given type\n");

Modified: scummvm/trunk/engines/sci/console.h
===================================================================
--- scummvm/trunk/engines/sci/console.h	2010-06-11 11:08:37 UTC (rev 49596)
+++ scummvm/trunk/engines/sci/console.h	2010-06-11 14:47:13 UTC (rev 49597)
@@ -74,6 +74,7 @@
 	bool cmdList(int argc, const char **argv);
 	bool cmdHexgrep(int argc, const char **argv);
 	bool cmdVerifyScripts(int argc, const char **argv);
+	bool cmdVerifyMidi(int argc, const char **argv);
 	// Game
 	bool cmdSaveGame(int argc, const char **argv);
 	bool cmdRestoreGame(int argc, const char **argv);

Modified: scummvm/trunk/engines/sci/sound/midiparser_sci.cpp
===================================================================
--- scummvm/trunk/engines/sci/sound/midiparser_sci.cpp	2010-06-11 11:08:37 UTC (rev 49596)
+++ scummvm/trunk/engines/sci/sound/midiparser_sci.cpp	2010-06-11 14:47:13 UTC (rev 49597)
@@ -75,7 +75,8 @@
 	_pSnd = psnd;
 	_soundVersion = soundVersion;
 
-	setVolume(psnd->volume);
+	if (_pSnd)
+		setVolume(psnd->volume);
 
 	if (channelFilterMask) {
 		// SCI0 only has 1 data stream, but we need to filter out channels depending on music hardware selection
@@ -86,30 +87,35 @@
 
 	_num_tracks = 1;
 	_tracks[0] = _mixedData;
-	setTrack(0);
+	if (_pSnd)
+		setTrack(0);
 	_loopTick = 0;
 
-	if (_soundVersion <= SCI_VERSION_0_LATE) {
-		// Set initial voice count
+	if (_pSnd) {
+		if (_soundVersion <= SCI_VERSION_0_LATE) {
+			// Set initial voice count
+			for (int i = 0; i < 16; ++i) {
+				byte voiceCount = 0;
+				if (channelFilterMask & (1 << i))
+					voiceCount = psnd->soundRes->getInitialVoiceCount(i);
+				_driver->send(0xB0 | i, 0x4B, voiceCount);
+			}
+		}
+
+		// Send a velocity off signal to all channels
 		for (int i = 0; i < 16; ++i) {
-			byte voiceCount = 0;
-			if (channelFilterMask & (1 << i))
-				voiceCount = psnd->soundRes->getInitialVoiceCount(i);
-			_driver->send(0xB0 | i, 0x4B, voiceCount);
+			_driver->send(0xB0 | i, 0x4E, 0);	// Reset velocity
 		}
 	}
 
-	// Send a velocity off signal to all channels
-	for (int i = 0; i < 16; ++i) {
-		_driver->send(0xB0 | i, 0x4E, 0);	// Reset velocity
-	}
-
 	return true;
 }
 
 void MidiParser_SCI::unloadMusic() {
-	resetTracking();
-	allNotesOff();
+	if (_pSnd) {
+		resetTracking();
+		allNotesOff();
+	}
 	_num_tracks = 0;
 	_active_track = 255;
 	_resetOnPause = false;
@@ -120,7 +126,7 @@
 	}
 
 	// Center the pitch wheels and hold pedal in preparation for the next piece of music
-	if (_driver) {
+	if (_driver && _pSnd) {
 		for (int i = 0; i < 16; ++i) {
 			if (isChannelUsed(i)) {
 				_driver->send(0xE0 | i, 0, 0x40);	// Reset pitch wheel
@@ -359,10 +365,10 @@
 	long new_delta;
 	SoundResource::Channel *channel;
 
-	while ((curr = midiGetNextChannel(ticker)) != 0xFF) { // there is still active channel
+	while ((curr = midiGetNextChannel(ticker)) != 0xFF) { // there is still an active channel
 		channel = &_track->channels[curr];
 		curDelta = *channel->data++;
-		channel->time += (curDelta == 0xF8 ? 240 : curDelta); // when the comamnd is supposed to occur
+		channel->time += (curDelta == 0xF8 ? 240 : curDelta); // when the command is supposed to occur
 		if (curDelta == 0xF8)
 			continue;
 		new_delta = channel->time - ticker;

Modified: scummvm/trunk/engines/sci/sound/midiparser_sci.h
===================================================================
--- scummvm/trunk/engines/sci/sound/midiparser_sci.h	2010-06-11 11:08:37 UTC (rev 49596)
+++ scummvm/trunk/engines/sci/sound/midiparser_sci.h	2010-06-11 14:47:13 UTC (rev 49597)
@@ -79,6 +79,8 @@
 
 	void clearUsedChannels() { _channelsUsed = 0; }
 
+	const byte *getMixedData() const { return _mixedData; }
+
 protected:
 	bool isChannelUsed(byte channel) const { return _channelsUsed & (1 << channel); }
 	void setChannelUsed(byte channel) { _channelsUsed |= (1 << channel); }


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