aboutsummaryrefslogtreecommitdiff
path: root/sound/midiparser_xmidi.cpp
diff options
context:
space:
mode:
authorStephen Kennedy2008-07-22 00:15:13 +0000
committerStephen Kennedy2008-07-22 00:15:13 +0000
commit0861fa4c00f0ecb82f3607127c8278d55f95376c (patch)
treed757c116b163a401f00859503a7db755b6627504 /sound/midiparser_xmidi.cpp
parenta58080bd58bbcc9f7c710fade55620049bae14e4 (diff)
parente09eb75ef77d6e76b763b3a47540a530013a887f (diff)
downloadscummvm-rg350-0861fa4c00f0ecb82f3607127c8278d55f95376c.tar.gz
scummvm-rg350-0861fa4c00f0ecb82f3607127c8278d55f95376c.tar.bz2
scummvm-rg350-0861fa4c00f0ecb82f3607127c8278d55f95376c.zip
Merged revisions 32879,32883,32895,32899,32902-32904,32910-32912,32923-32924,32930-32931,32938,32940,32948-32949,32951,32960-32964,32966-32970,32972-32974,32976,32978,32983,32986-32990,32992,32994,33002-33004,33006-33007,33009-33010,33014,33017,33021-33023,33030,33033,33052-33053,33056-33058,33061-33064,33068,33070,33072,33075,33078-33079,33083,33086-33087,33089,33094-33096,33098-33099,33104,33108-33109,33114-33117,33120,33135-33146,33160,33162,33165,33167-33169 via svnmerge from
https://scummvm.svn.sourceforge.net/svnroot/scummvm/scummvm/trunk svn-id: r33185
Diffstat (limited to 'sound/midiparser_xmidi.cpp')
-rw-r--r--sound/midiparser_xmidi.cpp61
1 files changed, 58 insertions, 3 deletions
diff --git a/sound/midiparser_xmidi.cpp b/sound/midiparser_xmidi.cpp
index d2aac49351..7cf114dcc6 100644
--- a/sound/midiparser_xmidi.cpp
+++ b/sound/midiparser_xmidi.cpp
@@ -38,6 +38,14 @@ protected:
NoteTimer _notes_cache[32];
uint32 _inserted_delta; // Track simulated deltas for note-off events
+ struct Loop {
+ byte *pos;
+ byte repeat;
+ };
+
+ Loop _loop[4];
+ int _loopCount;
+
protected:
uint32 readVLQ2(byte * &data);
void resetTracking();
@@ -78,16 +86,56 @@ void MidiParser_XMIDI::parseNextEvent(EventInfo &info) {
}
break;
- case 0xC: case 0xD:
+ case 0xC:
+ case 0xD:
info.basic.param1 = *(_position._play_pos++);
info.basic.param2 = 0;
break;
- case 0x8: case 0xA: case 0xB: case 0xE:
+ case 0x8:
+ case 0xA:
+ case 0xE:
info.basic.param1 = *(_position._play_pos++);
info.basic.param2 = *(_position._play_pos++);
break;
+ case 0xB:
+ info.basic.param1 = *(_position._play_pos++);
+ info.basic.param2 = *(_position._play_pos++);
+
+ // Simplified XMIDI looping.
+ //
+ // I would really like to turn the loop events into some sort
+ // of NOP event (perhaps a dummy META event?), but for now we
+ // just pass them on to the MIDI driver. That has worked in the
+ // past, so it shouldn't cause any actual damage...
+
+ if (info.basic.param1 == 0x74) {
+ // XMIDI_CONTROLLER_FOR_LOOP
+ byte *pos = _position._play_pos;
+ if (_loopCount < ARRAYSIZE(_loop) - 1)
+ _loopCount++;
+
+ _loop[_loopCount].pos = pos;
+ _loop[_loopCount].repeat = info.basic.param2;
+ } else if (info.basic.param1 == 0x75) {
+ // XMIDI_CONTROLLER_NEXT_BREAK
+ if (_loopCount >= 0) {
+ if (info.basic.param2 < 64) {
+ // End the current loop.
+ _loopCount--;
+ } else {
+ _position._play_pos = _loop[_loopCount].pos;
+ // Repeat 0 means "loop forever".
+ if (_loop[_loopCount].repeat) {
+ if (--_loop[_loopCount].repeat == 0)
+ _loopCount--;
+ }
+ }
+ }
+ }
+ break;
+
case 0xF: // Meta or SysEx event
switch (info.event & 0x0F) {
case 0x2: // Song Position Pointer
@@ -100,7 +148,12 @@ void MidiParser_XMIDI::parseNextEvent(EventInfo &info) {
info.basic.param2 = 0;
break;
- case 0x6: case 0x8: case 0xA: case 0xB: case 0xC: case 0xE:
+ case 0x6:
+ case 0x8:
+ case 0xA:
+ case 0xB:
+ case 0xC:
+ case 0xE:
info.basic.param1 = info.basic.param2 = 0;
break;
@@ -136,6 +189,8 @@ bool MidiParser_XMIDI::loadMusic(byte *data, uint32 size) {
uint32 chunk_len;
char buf[32];
+ _loopCount = -1;
+
unloadMusic();
byte *pos = data;