Ticket #8905: xmidi2.diff
File xmidi2.diff, 4.7 KB (added by , 16 years ago) |
---|
-
engines/agos/midi.cpp
538 538 error("Expected 'FORM' tag but found '%c%c%c%c' instead", buf[0], buf[1], buf[2], buf[3]); 539 539 } 540 540 541 MidiParser *parser = MidiParser::createParser_XMIDI(); 541 // In the DOS version of Simon the Sorcerer 2, the music contains lots 542 // of XMIDI callback controller events. As far as we know, they aren't 543 // actually used, so we disable the callback handler explicitly. 544 545 MidiParser *parser = MidiParser::createParser_XMIDI(NULL); 542 546 parser->setMidiDriver(this); 543 547 parser->setTimerRate(_driver->getBaseTempo()); 544 548 if (!parser->loadMusic(p->data, size)) -
sound/midiparser.h
352 352 }; 353 353 354 354 public: 355 typedef void (*XMidiCallbackProc)(byte eventData, void *refCon); 356 355 357 MidiParser(); 356 358 virtual ~MidiParser() { allNotesOff(); } 357 359 … … 370 372 uint32 getPPQN() { return _ppqn; } 371 373 virtual uint32 getTick() { return _position._play_tick; } 372 374 375 static void defaultXMidiCallback(byte eventData, void *refCon); 376 373 377 static MidiParser *createParser_SMF(); 374 static MidiParser *createParser_XMIDI( );378 static MidiParser *createParser_XMIDI(XMidiCallbackProc proc = defaultXMidiCallback, void *refCon = 0); 375 379 static void timerCallback(void *data) { ((MidiParser *) data)->onTimer(); } 376 380 }; 377 381 -
sound/midiparser_xmidi.cpp
46 46 Loop _loop[4]; 47 47 int _loopCount; 48 48 49 XMidiCallbackProc _callbackProc; 50 void *_callbackData; 51 49 52 protected: 50 53 uint32 readVLQ2(byte * &data); 51 54 void resetTracking(); 52 55 void parseNextEvent(EventInfo &info); 53 56 54 57 public: 55 MidiParser_XMIDI( ) : _inserted_delta(0) {}58 MidiParser_XMIDI(XMidiCallbackProc proc, void *data) : _inserted_delta(0), _callbackProc(proc), _callbackData(data) {} 56 59 ~MidiParser_XMIDI() { } 57 60 58 61 bool loadMusic(byte *data, uint32 size); … … 103 106 info.basic.param1 = *(_position._play_pos++); 104 107 info.basic.param2 = *(_position._play_pos++); 105 108 109 // This isn't a full XMIDI implementation, but it should 110 // hopefully be "good enough" for most things. 111 112 switch (info.basic.param1) { 106 113 // Simplified XMIDI looping. 107 // 108 // I would really like to turn the loop events into some sort 109 // of NOP event (perhaps a dummy META event?), but for now we 110 // just pass them on to the MIDI driver. That has worked in the 111 // past, so it shouldn't cause any actual damage... 114 case 0x74: { // XMIDI_CONTROLLER_FOR_LOOP 115 byte *pos = _position._play_pos; 116 if (_loopCount < ARRAYSIZE(_loop) - 1) 117 _loopCount++; 112 118 113 if (info.basic.param1 == 0x74) { 114 // XMIDI_CONTROLLER_FOR_LOOP 115 byte *pos = _position._play_pos; 116 if (_loopCount < ARRAYSIZE(_loop) - 1) 117 _loopCount++; 119 _loop[_loopCount].pos = pos; 120 _loop[_loopCount].repeat = info.basic.param2; 121 break; 122 } 118 123 119 _loop[_loopCount].pos = pos; 120 _loop[_loopCount].repeat = info.basic.param2; 121 } else if (info.basic.param1 == 0x75) { 122 // XMIDI_CONTROLLER_NEXT_BREAK 124 case 0x75: // XMIDI_CONTORLLER_NEXT_BREAK 123 125 if (_loopCount >= 0) { 124 126 if (info.basic.param2 < 64) { 125 127 // End the current loop. … … 133 135 } 134 136 } 135 137 } 136 } else if (info.basic.param1 >= 0x6e && info.basic.param1 <= 0x78) { 137 warning("Unsupported XMIDI controller %d (0x%2x)", 138 info.basic.param1, info.basic.param1); 138 break; 139 140 case 0x77: // XMIDI_CONTROLLER_CALLBACK_TRIG 141 if (_callbackProc) 142 _callbackProc(info.basic.param2, _callbackData); 143 break; 144 145 default: 146 if (info.basic.param1 >= 0x6e && info.basic.param1 <= 0x78) { 147 warning("Unsupported XMIDI controller %d (0x%2x)", 148 info.basic.param1, info.basic.param1); 149 } 150 break; 139 151 } 152 153 // Should we really keep passing the XMIDI controller events to 154 // the MIDI driver, or should we turn them into some kind of 155 // NOP events? (Dummy meta events, perhaps?) Ah well, it has 156 // worked so far, so it shouldn't cause any damage... 157 140 158 break; 141 159 142 160 case 0xF: // Meta or SysEx event … … 336 354 _inserted_delta = 0; 337 355 } 338 356 339 MidiParser *MidiParser::createParser_XMIDI() { return new MidiParser_XMIDI; } 357 void MidiParser::defaultXMidiCallback(byte eventData, void *data) { 358 warning("MidiParser: defaultXMidiCallback(%d)", eventData); 359 } 360 361 MidiParser *MidiParser::createParser_XMIDI(XMidiCallbackProc proc, void *data) { 362 return new MidiParser_XMIDI(proc, data); 363 }