mirror of
https://github.com/libretro/scummvm.git
synced 2025-01-31 07:53:36 +00:00
- Extended MidiDriver::sysEx to allow 264 byte sysEx messages
- Updated all drivers to allow 264+2 byte sysEx messages - Implemented sysEx processing for MT-32 for Kyra1 and HoF. MT-32 should now be working properly. svn-id: r35180
This commit is contained in:
parent
17a699a438
commit
2ebe04ac3e
@ -213,9 +213,9 @@ void MidiDriver_ALSA::send(uint32 b) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void MidiDriver_ALSA::sysEx(const byte *msg, uint16 length) {
|
void MidiDriver_ALSA::sysEx(const byte *msg, uint16 length) {
|
||||||
unsigned char buf[256];
|
unsigned char buf[266];
|
||||||
|
|
||||||
assert(length + 2 <= 256);
|
assert(length + 2 <= ARRAYSIZE(buf));
|
||||||
|
|
||||||
// Add SysEx frame
|
// Add SysEx frame
|
||||||
buf[0] = 0xF0;
|
buf[0] = 0xF0;
|
||||||
|
@ -115,9 +115,9 @@ void MidiDriver_CAMD::send(uint32 b) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void MidiDriver_CAMD::sysEx(const byte *msg, uint16 length) {
|
void MidiDriver_CAMD::sysEx(const byte *msg, uint16 length) {
|
||||||
unsigned char buf[256];
|
unsigned char buf[266];
|
||||||
|
|
||||||
assert(length + 2 <= 256);
|
assert(length + 2 <= ARRAYSIZE(buf));
|
||||||
|
|
||||||
// Add SysEx frame
|
// Add SysEx frame
|
||||||
buf[0] = 0xF0;
|
buf[0] = 0xF0;
|
||||||
|
@ -190,9 +190,9 @@ void MidiDriver_CORE::send(uint32 b) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void MidiDriver_CORE::sysEx(const byte *msg, uint16 length) {
|
void MidiDriver_CORE::sysEx(const byte *msg, uint16 length) {
|
||||||
unsigned char buf[256];
|
unsigned char buf[266];
|
||||||
|
|
||||||
assert(length + 2 <= 256);
|
assert(length + 2 <= ARRAYSIZE(buf));
|
||||||
assert(_auGraph != NULL);
|
assert(_auGraph != NULL);
|
||||||
|
|
||||||
// Add SysEx frame
|
// Add SysEx frame
|
||||||
|
@ -146,11 +146,11 @@ void MidiDriver_SEQ::send(uint32 b) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void MidiDriver_SEQ::sysEx (const byte *msg, uint16 length) {
|
void MidiDriver_SEQ::sysEx (const byte *msg, uint16 length) {
|
||||||
unsigned char buf [1024];
|
unsigned char buf [1330];
|
||||||
int position = 0;
|
int position = 0;
|
||||||
const byte *chr = msg;
|
const byte *chr = msg;
|
||||||
|
|
||||||
assert(length + 2 <= 256);
|
assert(length + 2 <= 266);
|
||||||
|
|
||||||
buf[position++] = SEQ_MIDIPUTC;
|
buf[position++] = SEQ_MIDIPUTC;
|
||||||
buf[position++] = 0xF0;
|
buf[position++] = 0xF0;
|
||||||
|
@ -91,7 +91,10 @@ void MidiDriver_STMIDI::send(uint32 b) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void MidiDriver_STMIDI::sysEx (const byte *msg, uint16 length) {
|
void MidiDriver_STMIDI::sysEx (const byte *msg, uint16 length) {
|
||||||
if (length > 254) {
|
// FIXME: LordHoto doesn't know if this will still work
|
||||||
|
// when sending 264 byte sysEx data, as needed by KYRA,
|
||||||
|
// feel free to revert it to 254 again if needed.
|
||||||
|
if (length > 264) {
|
||||||
warning ("Cannot send SysEx block - data too large");
|
warning ("Cannot send SysEx block - data too large");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -487,11 +487,11 @@ void MidiDriver_TIMIDITY::send(uint32 b) {
|
|||||||
|
|
||||||
void MidiDriver_TIMIDITY::sysEx(const byte *msg, uint16 length) {
|
void MidiDriver_TIMIDITY::sysEx(const byte *msg, uint16 length) {
|
||||||
fprintf(stderr, "Timidity::sysEx\n");
|
fprintf(stderr, "Timidity::sysEx\n");
|
||||||
unsigned char buf[1024];
|
unsigned char buf[1330];
|
||||||
int position = 0;
|
int position = 0;
|
||||||
const byte *chr = msg;
|
const byte *chr = msg;
|
||||||
|
|
||||||
assert(length + 2 <= 256);
|
assert(length + 2 <= 266);
|
||||||
|
|
||||||
buf[position++] = SEQ_MIDIPUTC;
|
buf[position++] = SEQ_MIDIPUTC;
|
||||||
buf[position++] = 0xF0;
|
buf[position++] = 0xF0;
|
||||||
|
@ -42,7 +42,7 @@
|
|||||||
class MidiDriver_WIN : public MidiDriver_MPU401 {
|
class MidiDriver_WIN : public MidiDriver_MPU401 {
|
||||||
private:
|
private:
|
||||||
MIDIHDR _streamHeader;
|
MIDIHDR _streamHeader;
|
||||||
byte _streamBuffer[256]; // SysEx blocks should be no larger than 256 bytes
|
byte _streamBuffer[266]; // SysEx blocks should be no larger than 266 bytes
|
||||||
HANDLE _streamEvent;
|
HANDLE _streamEvent;
|
||||||
HMIDIOUT _mo;
|
HMIDIOUT _mo;
|
||||||
bool _isOpen;
|
bool _isOpen;
|
||||||
@ -106,7 +106,7 @@ void MidiDriver_WIN::sysEx(const byte *msg, uint16 length) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
assert(length+2 <= 256);
|
assert(length+2 <= 266);
|
||||||
|
|
||||||
midiOutUnprepareHeader(_mo, &_streamHeader, sizeof(_streamHeader));
|
midiOutUnprepareHeader(_mo, &_streamHeader, sizeof(_streamHeader));
|
||||||
|
|
||||||
|
@ -112,7 +112,7 @@ void MidiDriver_Zodiac::send(uint32 b) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void MidiDriver_Zodiac::sysEx(const byte *msg, uint16 length) {
|
void MidiDriver_Zodiac::sysEx(const byte *msg, uint16 length) {
|
||||||
unsigned char buf[256];
|
unsigned char buf[266];
|
||||||
|
|
||||||
buf[0] = 0xF0;
|
buf[0] = 0xF0;
|
||||||
memcpy(buf + 1, msg, length);
|
memcpy(buf + 1, msg, length);
|
||||||
|
@ -110,6 +110,7 @@ class KyraEngine_v1 : public Engine {
|
|||||||
friend class Debugger;
|
friend class Debugger;
|
||||||
friend class ::KyraMetaEngine;
|
friend class ::KyraMetaEngine;
|
||||||
friend class GUI;
|
friend class GUI;
|
||||||
|
friend class SoundMidiPC; // For _eventMan
|
||||||
public:
|
public:
|
||||||
KyraEngine_v1(OSystem *system, const GameFlags &flags);
|
KyraEngine_v1(OSystem *system, const GameFlags &flags);
|
||||||
virtual ~KyraEngine_v1();
|
virtual ~KyraEngine_v1();
|
||||||
|
@ -182,8 +182,16 @@ void MidiOutput::send(uint32 b) {
|
|||||||
_channels[channel].program =
|
_channels[channel].program =
|
||||||
_sources[_curSource].channelProgram[channel] = param1;
|
_sources[_curSource].channelProgram[channel] = param1;
|
||||||
} else if (event == 0xB0) { // Controller change
|
} else if (event == 0xB0) { // Controller change
|
||||||
|
for (int i = 0; i < 9; ++i) {
|
||||||
|
Controller &cont = _sources[_curSource].controllers[channel][i];
|
||||||
|
if (cont.controller == param1) {
|
||||||
|
cont.value = param2;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (param1 == 0x07) {
|
if (param1 == 0x07) {
|
||||||
param1 = (param1 * _sources[_curSource].volume) >> 8;
|
param2 = (param2 * _sources[_curSource].volume) >> 8;
|
||||||
} else if (param1 == 0x6E) { // Lock Channel
|
} else if (param1 == 0x6E) { // Lock Channel
|
||||||
if (param2 >= 0x40) { // Lock Channel
|
if (param2 >= 0x40) { // Lock Channel
|
||||||
int chan = lockChannel();
|
int chan = lockChannel();
|
||||||
@ -206,15 +214,6 @@ void MidiOutput::send(uint32 b) {
|
|||||||
// on track change, we simply ignore it.
|
// on track change, we simply ignore it.
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int i = 0; i < 9; ++i) {
|
|
||||||
Controller &cont = _sources[_curSource].controllers[channel][i];
|
|
||||||
if (cont.controller == param1) {
|
|
||||||
cont.value = param2;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
} else if (event == 0x90 || event == 0x80) { // Note On/Off
|
} else if (event == 0x90 || event == 0x80) { // Note On/Off
|
||||||
if (!(_channels[channel].flags & kChannelLocked)) {
|
if (!(_channels[channel].flags & kChannelLocked)) {
|
||||||
const bool remove = (event == 0x80) || (param2 == 0x00);
|
const bool remove = (event == 0x80) || (param2 == 0x00);
|
||||||
@ -258,11 +257,7 @@ void MidiOutput::send(uint32 b) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void MidiOutput::sendIntern(const byte event, const byte channel, byte param1, const byte param2) {
|
void MidiOutput::sendIntern(const byte event, const byte channel, byte param1, const byte param2) {
|
||||||
if (event == 0xE0) {
|
if (event == 0xC0) {
|
||||||
_channels[channel].pitchWheel = (param2 << 8) | param1;
|
|
||||||
} else if (event == 0xC0) {
|
|
||||||
_channels[channel].program = param1;
|
|
||||||
|
|
||||||
// MT32 -> GM conversion
|
// MT32 -> GM conversion
|
||||||
if (!_isMT32 && _defaultMT32)
|
if (!_isMT32 && _defaultMT32)
|
||||||
param1 = _mt32ToGm[param1];
|
param1 = _mt32ToGm[param1];
|
||||||
@ -330,8 +325,6 @@ void MidiOutput::setSourceVolume(int source, uint8 volume, bool apply) {
|
|||||||
// Controller 0 in the state table should always be '7' aka
|
// Controller 0 in the state table should always be '7' aka
|
||||||
// volume control
|
// volume control
|
||||||
byte realVol = (_channels[i].controllers[0].value * volume) >> 8;
|
byte realVol = (_channels[i].controllers[0].value * volume) >> 8;
|
||||||
_channels[i].controllers[0].value = realVol;
|
|
||||||
|
|
||||||
sendIntern(0xB0, i, 0x07, realVol);
|
sendIntern(0xB0, i, 0x07, realVol);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -509,10 +502,26 @@ bool SoundMidiPC::init() {
|
|||||||
|
|
||||||
_output->setTimerCallback(this, SoundMidiPC::onTimer);
|
_output->setTimerCallback(this, SoundMidiPC::onTimer);
|
||||||
|
|
||||||
/*loadSoundFile("INTRO");
|
if (_nativeMT32) {
|
||||||
playTrack(0);
|
if (_vm->gameFlags().gameID == GI_KYRA1) {
|
||||||
while (_music->isPlaying())
|
loadSoundFile("INTRO");
|
||||||
_vm->_system->delayMillis(10);*/
|
} else if (_vm->gameFlags().gameID == GI_KYRA2) {
|
||||||
|
_vm->resource()->loadPakFile("AUDIO.PAK");
|
||||||
|
loadSoundFile("HOF_SYX");
|
||||||
|
}
|
||||||
|
|
||||||
|
playTrack(0);
|
||||||
|
|
||||||
|
Common::Event event;
|
||||||
|
while (isPlaying() && !_vm->shouldQuit()) {
|
||||||
|
_vm->_system->updateScreen();
|
||||||
|
_vm->_eventMan->pollEvent(event);
|
||||||
|
_vm->_system->delayMillis(10);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (_vm->gameFlags().gameID == GI_KYRA2)
|
||||||
|
_vm->resource()->unloadPakFile("AUDIO.PAK");
|
||||||
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -594,9 +603,12 @@ void SoundMidiPC::loadSfxFile(Common::String file) {
|
|||||||
|
|
||||||
void SoundMidiPC::playTrack(uint8 track) {
|
void SoundMidiPC::playTrack(uint8 track) {
|
||||||
Common::StackLock lock(_mutex);
|
Common::StackLock lock(_mutex);
|
||||||
_output->initSource(0);
|
|
||||||
_fadeMusicOut = false;
|
_fadeMusicOut = false;
|
||||||
_output->setSourceVolume(0, _musicVolume, true);
|
_output->setSourceVolume(0, _musicVolume, true);
|
||||||
|
|
||||||
|
_output->initSource(0);
|
||||||
|
_output->setSourceVolume(0, _musicVolume, true);
|
||||||
_music->setTrack(track);
|
_music->setTrack(track);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -620,7 +632,7 @@ void SoundMidiPC::playSoundEffect(uint8 track) {
|
|||||||
if (!_sfx[i]->isPlaying()) {
|
if (!_sfx[i]->isPlaying()) {
|
||||||
_output->initSource(i+1);
|
_output->initSource(i+1);
|
||||||
_sfx[i]->setTrack(track);
|
_sfx[i]->setTrack(track);
|
||||||
break;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -216,7 +216,7 @@ public:
|
|||||||
* do NOT include the leading 0xF0 and the trailing 0xF7.
|
* do NOT include the leading 0xF0 and the trailing 0xF7.
|
||||||
*
|
*
|
||||||
* Furthermore, the maximal supported length of a SysEx
|
* Furthermore, the maximal supported length of a SysEx
|
||||||
* is 254 bytes. Passing longer buffers can lead to
|
* is 264 bytes. Passing longer buffers can lead to
|
||||||
* undefined behavior (most likely, a crash).
|
* undefined behavior (most likely, a crash).
|
||||||
*/
|
*/
|
||||||
virtual void sysEx(const byte *msg, uint16 length) { }
|
virtual void sysEx(const byte *msg, uint16 length) { }
|
||||||
|
Loading…
x
Reference in New Issue
Block a user