[Scummvm-cvs-logs] scummvm master -> 76dfbbede41dd43dad3fa114f409654807c239a3

clone2727 clone2727 at gmail.com
Fri May 4 00:58:21 CEST 2012


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

Summary:
b93b17e7f4 TINSEL: Capitalize 'demo'
76dfbbede4 TINSEL: Add basic PSX SEQ playback support


Commit: b93b17e7f4af0ad28ad0d2bde36302cdbd3aeeff
    https://github.com/scummvm/scummvm/commit/b93b17e7f4af0ad28ad0d2bde36302cdbd3aeeff
Author: Matthew Hoops (clone2727 at gmail.com)
Date: 2012-05-03T14:59:19-07:00

Commit Message:
TINSEL: Capitalize 'demo'

Changed paths:
    engines/tinsel/detection_tables.h



diff --git a/engines/tinsel/detection_tables.h b/engines/tinsel/detection_tables.h
index be44b1c..b6b19f6 100644
--- a/engines/tinsel/detection_tables.h
+++ b/engines/tinsel/detection_tables.h
@@ -397,7 +397,7 @@ static const TinselGameDescription gameDescriptions[] = {
 	{	// multilanguage PSX demo
 		{
 			"dw",
-			"CD demo",
+			"CD Demo",
 			{
 				{"french.txt", 0, "e7020d35f58d0d187052ac406d86cc87", 273914},
 				{"german.txt", 0, "52f0a01e0ff0d340b02a36fd5109d705", 263942},


Commit: 76dfbbede41dd43dad3fa114f409654807c239a3
    https://github.com/scummvm/scummvm/commit/76dfbbede41dd43dad3fa114f409654807c239a3
Author: Matthew Hoops (clone2727 at gmail.com)
Date: 2012-05-03T15:19:54-07:00

Commit Message:
TINSEL: Add basic PSX SEQ playback support

Instrument bank support is not implemented yet

Changed paths:
    engines/tinsel/music.cpp
    engines/tinsel/music.h
    engines/tinsel/tinlib.cpp



diff --git a/engines/tinsel/music.cpp b/engines/tinsel/music.cpp
index 781a378..fa5334a 100644
--- a/engines/tinsel/music.cpp
+++ b/engines/tinsel/music.cpp
@@ -131,11 +131,6 @@ bool PlayMidiSequence(uint32 dwFileOffset, bool bLoop) {
 	g_currentMidi = dwFileOffset;
 	g_currentLoop = bLoop;
 
-	// Tinsel V1 PSX uses a different music format, so i
-	// disable it here.
-	// TODO: Maybe this should be moved to a better place...
-	if (TinselV1PSX) return false;
-
 	if (_vm->_config->_musicVolume != 0) {
 		bool mute = false;
 		if (ConfMan.hasKey("mute"))
@@ -231,14 +226,14 @@ bool PlayMidiSequence(uint32 dwFileOffset, bool bLoop) {
 			_vm->_midiMusic->send(0x7F07B0 | 13);
 		}
 
-		_vm->_midiMusic->playXMIDI(g_midiBuffer.pDat, dwSeqLen, bLoop);
+		_vm->_midiMusic->playMIDI(dwSeqLen, bLoop);
 
 		// Store the length
 		//dwLastSeqLen = dwSeqLen;
 	} else {
 	 	// dwFileOffset == dwLastMidiIndex
 		_vm->_midiMusic->stop();
-		_vm->_midiMusic->playXMIDI(g_midiBuffer.pDat, dwSeqLen, bLoop);
+		_vm->_midiMusic->playMIDI(dwSeqLen, bLoop);
 	}
 
 	return true;
@@ -314,8 +309,7 @@ void OpenMidiFiles() {
 	Common::File midiStream;
 
 	// Demo version has no midi file
-	// Also, Discworld PSX uses still unsupported psx SEQ format for music...
-	if ((_vm->getFeatures() & GF_DEMO) || (TinselVersion == TINSEL_V2) || TinselV1PSX)
+	if ((_vm->getFeatures() & GF_DEMO) || (TinselVersion == TINSEL_V2))
 		return;
 
 	if (g_midiBuffer.pDat)
@@ -412,7 +406,7 @@ void MidiMusicPlayer::send(uint32 b) {
 	}
 }
 
-void MidiMusicPlayer::playXMIDI(byte *midiData, uint32 size, bool loop) {
+void MidiMusicPlayer::playMIDI(uint32 size, bool loop) {
 	Common::StackLock lock(_mutex);
 
 	if (_isPlaying)
@@ -420,6 +414,13 @@ void MidiMusicPlayer::playXMIDI(byte *midiData, uint32 size, bool loop) {
 
 	stop();
 
+	if (TinselV1PSX)
+		playSEQ(size, loop);
+	else
+		playXMIDI(size, loop);
+}
+
+void MidiMusicPlayer::playXMIDI(uint32 size, bool loop) {
 	// It seems like not all music (the main menu music, for instance) set
 	// all the instruments explicitly. That means the music will sound
 	// different, depending on which music played before it. This appears
@@ -433,7 +434,78 @@ void MidiMusicPlayer::playXMIDI(byte *midiData, uint32 size, bool loop) {
 	// Load XMID resource data
 
 	MidiParser *parser = MidiParser::createParser_XMIDI();
-	if (parser->loadMusic(midiData, size)) {
+	if (parser->loadMusic(g_midiBuffer.pDat, size)) {
+		parser->setTrack(0);
+		parser->setMidiDriver(this);
+		parser->setTimerRate(getBaseTempo());
+		parser->property(MidiParser::mpCenterPitchWheelOnUnload, 1);
+		parser->property(MidiParser::mpSendSustainOffOnNotesOff, 1);
+
+		_parser = parser;
+
+		_isLooping = loop;
+		_isPlaying = true;
+	} else {
+		delete parser;
+	}
+}
+
+void MidiMusicPlayer::playSEQ(uint32 size, bool loop) {
+	// MIDI.DAT holds the file names in DW1 PSX
+	Common::String baseName((char *)g_midiBuffer.pDat, size);
+	Common::String seqName = baseName + ".SEQ";
+
+	// TODO: Load the instrument bank (<baseName>.VB and <baseName>.VH)
+
+	Common::File seqFile;
+	if (!seqFile.open(seqName))
+		error("Failed to open SEQ file '%s'", seqName.c_str());
+
+	if (seqFile.readUint32LE() != MKTAG('S', 'E', 'Q', 'p'))
+		error("Failed to find SEQp tag");
+
+	// Make sure we don't have a SEP file (with multiple SEQ's inside)
+	if (seqFile.readUint32BE() != 1)
+		error("Can only play SEQ files, not SEP");
+
+	uint16 ppqn = seqFile.readUint16BE();
+	uint32 tempo = seqFile.readUint16BE() << 8;
+	tempo |= seqFile.readByte();
+	/* uint16 beat = */ seqFile.readUint16BE();
+
+	// SEQ is directly based on SMF and we'll use that to our advantage here
+	// and convert to SMF and then use the SMF MidiParser.
+
+	// Calculate the SMF size we'll need
+	uint32 dataSize = seqFile.size() - 15;
+	uint32 actualSize = dataSize + 7 + 22;
+
+	// Resize the buffer if necessary
+	if (g_midiBuffer.size < actualSize) {
+		g_midiBuffer.pDat = (byte *)realloc(g_midiBuffer.pDat, actualSize);
+		assert(g_midiBuffer.pDat);
+	}
+
+	// Now construct the header
+	WRITE_BE_UINT32(g_midiBuffer.pDat, MKTAG('M', 'T', 'h', 'd'));
+	WRITE_BE_UINT32(g_midiBuffer.pDat + 4, 6); // header size
+	WRITE_BE_UINT16(g_midiBuffer.pDat + 8, 0); // type 0
+	WRITE_BE_UINT16(g_midiBuffer.pDat + 10, 1); // one track
+	WRITE_BE_UINT16(g_midiBuffer.pDat + 12, ppqn);
+	WRITE_BE_UINT32(g_midiBuffer.pDat + 14, MKTAG('M', 'T', 'r', 'k'));
+	WRITE_BE_UINT32(g_midiBuffer.pDat + 18, dataSize + 7); // SEQ data size + tempo change event size
+
+	// Add in a fake tempo change event
+	WRITE_BE_UINT32(g_midiBuffer.pDat + 22, 0x00FF5103); // no delta, meta event, tempo change, param size = 3
+	WRITE_BE_UINT16(g_midiBuffer.pDat + 26, tempo >> 8);
+	g_midiBuffer.pDat[28] = tempo & 0xFF;
+
+	// Now copy in the rest of the events
+	seqFile.read(g_midiBuffer.pDat + 29, dataSize);
+	seqFile.close();
+
+	MidiParser *parser = MidiParser::createParser_SMF();
+	if (parser->loadMusic(g_midiBuffer.pDat, actualSize)) {
 		parser->setTrack(0);
 		parser->setMidiDriver(this);
 		parser->setTimerRate(getBaseTempo());
diff --git a/engines/tinsel/music.h b/engines/tinsel/music.h
index d43fed2..121bf3d 100644
--- a/engines/tinsel/music.h
+++ b/engines/tinsel/music.h
@@ -64,7 +64,7 @@ public:
 
 	virtual void setVolume(int volume);
 
-	void playXMIDI(byte *midiData, uint32 size, bool loop);
+	void playMIDI(uint32 size, bool loop);
 
 //	void stop();
 	void pause();
@@ -76,6 +76,10 @@ public:
 	// The original sets the "sequence timing" to 109 Hz, whatever that
 	// means. The default is 120.
 	uint32 getBaseTempo()	{ return _driver ? (109 * _driver->getBaseTempo()) / 120 : 0; }
+
+private:
+	void playXMIDI(uint32 size, bool loop);
+	void playSEQ(uint32 size, bool loop);
 };
 
 class PCMMusicPlayer : public Audio::AudioStream {
diff --git a/engines/tinsel/tinlib.cpp b/engines/tinsel/tinlib.cpp
index c652abc..cd65a4e 100644
--- a/engines/tinsel/tinlib.cpp
+++ b/engines/tinsel/tinlib.cpp
@@ -1626,7 +1626,7 @@ static void Play(CORO_PARAM, SCNHANDLE hFilm, int x, int y, bool bComplete, int
  */
 static void PlayMidi(CORO_PARAM, SCNHANDLE hMidi, int loop, bool complete) {
 	// FIXME: This is a workaround for the FIXME below
-	if (GetMidiVolume() == 0 || TinselV1PSX)
+	if (GetMidiVolume() == 0)
 		return;
 
 	CORO_BEGIN_CONTEXT;






More information about the Scummvm-git-logs mailing list