[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