From abe637b0f52cc0da583928ab0e3dac1460afff20 Mon Sep 17 00:00:00 2001 From: Johannes Schickel Date: Mon, 1 Oct 2012 01:51:04 +0200 Subject: AUDIO: Add support for Sam&Max's OPL3 output in our SCUMM AdLib driver. This is an initial implementation and does not implement the differences in voice allocation. --- audio/softsynth/adlib.cpp | 689 ++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 609 insertions(+), 80 deletions(-) (limited to 'audio/softsynth/adlib.cpp') diff --git a/audio/softsynth/adlib.cpp b/audio/softsynth/adlib.cpp index 44cd79b530..ba39e6d5e2 100644 --- a/audio/softsynth/adlib.cpp +++ b/audio/softsynth/adlib.cpp @@ -86,7 +86,9 @@ protected: bool _pedal; byte _program; byte _priEff; + byte _pan; AdLibInstrument _partInstr; + AdLibInstrument _partInstrSecondary; protected: MidiDriver_ADLIB *_owner; @@ -108,12 +110,14 @@ public: _pedal = 0; _program = 0; _priEff = 0; + _pan = 64; _owner = 0; _allocated = false; _channel = 0; memset(&_partInstr, 0, sizeof(_partInstr)); + memset(&_partInstrSecondary, 0, sizeof(_partInstrSecondary)); } MidiDriver *device(); @@ -132,7 +136,7 @@ public: void controlChange(byte control, byte value); void modulationWheel(byte value); void volume(byte value); - void panPosition(byte value) { return; } // Not supported + void panPosition(byte value); void pitchBendFactor(byte value); void detune(byte value); void priority(byte value); @@ -162,7 +166,6 @@ public: void noteOff(byte note); void noteOn(byte note, byte velocity); void programChange(byte program) { } - void pitchBend(int16 bend) { } // Control Change messages void modulationWheel(byte value) { } @@ -220,6 +223,9 @@ struct AdLibVoice { Struct10 _s10b; Struct11 _s11b; + byte _secTwoChan; + byte _secVol1, _secVol2; + AdLibVoice() { memset(this, 0, sizeof(AdLibVoice)); } }; @@ -487,6 +493,346 @@ static AdLibInstrument g_gmPercussionInstruments[39] = { { 0x0A, 0x0E, 0x7F, 0x00, 0x7D, 0x13, 0x20, 0x28, 0x03, 0x7C, 0x06, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0x00 } }; +static const AdLibInstrument g_gmInstrumentsOPL3[128][2] = { + { { 0xC2, 0xC2, 0x0A, 0x6B, 0xA0, 0xC2, 0x08, 0x0D, 0x88, 0xC8, 0x0A, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0x23 }, + { 0x02, 0x00, 0x0C, 0x78, 0x61, 0x04, 0x4C, 0x0B, 0x9A, 0xC8, 0x04, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0x23 } }, + { { 0x22, 0x53, 0x0E, 0x8A, 0x60, 0x14, 0x06, 0x1D, 0x7A, 0xB8, 0x06, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0x00 }, + { 0x22, 0x5A, 0x0E, 0x8A, 0x40, 0x14, 0x2F, 0x0E, 0x7A, 0x88, 0x06, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0x00 } }, + { { 0x06, 0x00, 0x1C, 0x79, 0x70, 0x02, 0x00, 0x4B, 0x79, 0xA8, 0x08, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0x00 }, + { 0x06, 0x00, 0x1A, 0x79, 0x60, 0x02, 0x00, 0x4C, 0xA9, 0xC8, 0x00, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0x00 } }, + { { 0xC2, 0x80, 0x0B, 0x89, 0x90, 0xC2, 0x06, 0x1B, 0xA8, 0xB0, 0x04, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0x23 }, + { 0x04, 0x28, 0x5D, 0xB8, 0x01, 0x02, 0x00, 0x3C, 0x70, 0x88, 0x0A, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0x00 } }, + { { 0xC2, 0x17, 0x3D, 0x6A, 0x00, 0xC4, 0x2E, 0x2D, 0xC9, 0x40, 0x00, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0x00 }, + { 0xC2, 0x17, 0x3D, 0x6A, 0x00, 0xC4, 0x2E, 0x2D, 0xC9, 0x40, 0x00, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0x00 } }, + { { 0x06, 0x1E, 0x1C, 0x99, 0x00, 0x02, 0x3A, 0x4C, 0x79, 0x00, 0x0C, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0x00 }, + { 0x06, 0x1E, 0x1C, 0x99, 0x00, 0x02, 0x3A, 0x4C, 0x79, 0x00, 0x0C, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0x00 } }, + { { 0x84, 0x40, 0x3B, 0x5A, 0x63, 0x81, 0x00, 0x3B, 0x5A, 0xD3, 0x0B, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0x00 }, + { 0x87, 0x40, 0x3A, 0x5A, 0x94, 0x82, 0x04, 0x3D, 0x59, 0xAC, 0x09, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0x00 } }, + { { 0x84, 0x40, 0x3B, 0x5A, 0xC3, 0x81, 0x00, 0x3B, 0x5A, 0xFB, 0x01, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0x00 }, + { 0x84, 0x40, 0x3B, 0x5A, 0xC3, 0x81, 0x00, 0x3B, 0x5A, 0xFB, 0x01, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0x00 } }, + { { 0x8C, 0x80, 0x05, 0xEA, 0xA9, 0x82, 0x04, 0x3D, 0xAA, 0xB0, 0x07, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0x00 }, + { 0x8C, 0x80, 0x06, 0x98, 0xA9, 0x86, 0x10, 0x36, 0x7A, 0xFD, 0x07, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0x00 } }, + { { 0x85, 0x40, 0x0D, 0xEC, 0xE1, 0x84, 0x58, 0x3E, 0xCB, 0xF8, 0x01, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0x00 }, + { 0x84, 0x40, 0x0D, 0xEB, 0xE0, 0x84, 0x48, 0x3E, 0xCA, 0xC0, 0x05, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0x00 } }, + { { 0x8A, 0xC0, 0x0C, 0xDC, 0xA0, 0x88, 0x58, 0x3D, 0xDA, 0xF8, 0x01, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0x00 }, + { 0x8A, 0xC0, 0x0C, 0xDC, 0xA0, 0x88, 0x58, 0x3D, 0xDA, 0xF8, 0x01, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0x00 } }, + { { 0xC9, 0x40, 0x2B, 0x78, 0x8A, 0xC2, 0x0A, 0x4C, 0x8A, 0xF8, 0x00, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0x1A }, + { 0xCA, 0x40, 0x47, 0xCA, 0xB4, 0xC2, 0x00, 0x57, 0x8A, 0xB8, 0x08, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0x1A } }, + { { 0x2A, 0x0E, 0x17, 0x89, 0x50, 0x22, 0x0C, 0x1B, 0x09, 0xE0, 0x0A, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0x00 }, + { 0x2A, 0x1A, 0x19, 0x8A, 0x00, 0x22, 0x38, 0x0B, 0x0A, 0x00, 0x0A, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0x00 } }, + { { 0xE7, 0x9B, 0x08, 0x08, 0x4A, 0xE2, 0x06, 0x0A, 0x08, 0xE0, 0x0A, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0x00 }, + { 0xE7, 0x9B, 0x08, 0x08, 0x4A, 0xE2, 0x2F, 0x0A, 0x08, 0x68, 0x0A, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0x00 } }, + { { 0xC5, 0x0A, 0x05, 0xDC, 0xB8, 0x84, 0x06, 0x00, 0xEC, 0xC0, 0x08, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0x00 }, + { 0x09, 0x10, 0x04, 0x5B, 0xA5, 0x02, 0x08, 0x00, 0xEC, 0x70, 0x06, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0x00 } }, + { { 0x86, 0x40, 0x5D, 0x5A, 0x81, 0x81, 0x00, 0x0B, 0x5A, 0xFB, 0x00, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0x00 }, + { 0x86, 0x40, 0x5D, 0x5A, 0x81, 0x81, 0x00, 0x0B, 0x5A, 0xFB, 0x00, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0x00 } }, + { { 0xED, 0x0F, 0x5B, 0xC8, 0xC8, 0xE2, 0x9F, 0x4A, 0xE9, 0xF9, 0x07, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0x00 }, + { 0xE6, 0x40, 0x0A, 0xA7, 0x64, 0xE2, 0x8B, 0x6A, 0x79, 0xB1, 0x01, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0x00 } }, + { { 0xE8, 0x4F, 0x3A, 0xD7, 0xF8, 0xE2, 0x97, 0x49, 0xF9, 0xF9, 0x05, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0x00 }, + { 0xC9, 0x02, 0x16, 0x9A, 0xAB, 0xC4, 0x15, 0x46, 0xBA, 0xF8, 0x04, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0x00 } }, + { { 0xE1, 0x08, 0x2F, 0xF7, 0xE1, 0xF3, 0x42, 0x8F, 0xC7, 0xC2, 0x07, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0x00 }, + { 0xE3, 0x00, 0x2D, 0xF7, 0xC1, 0xE4, 0x40, 0x7F, 0xC7, 0xD2, 0x09, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0x00 } }, + { { 0x01, 0x8C, 0x9F, 0xDA, 0xE8, 0xE4, 0x50, 0x9F, 0xDA, 0xF2, 0x09, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0x00 }, + { 0x02, 0x80, 0x9F, 0xDA, 0x00, 0xE3, 0x50, 0x9F, 0xD9, 0xFA, 0x03, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0x00 } }, + { { 0x08, 0xD5, 0x9D, 0xA5, 0x89, 0xE2, 0x3F, 0x9F, 0xD6, 0x91, 0x07, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0x00 }, + { 0x08, 0xD5, 0x9D, 0xA5, 0x89, 0xE2, 0x3F, 0x9F, 0xD6, 0x91, 0x07, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0x00 } }, + { { 0xE5, 0x0F, 0x7D, 0xB8, 0x5A, 0xA2, 0x0C, 0x7C, 0xC7, 0xC1, 0x04, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0x00 }, + { 0x06, 0x4C, 0xAC, 0x56, 0x31, 0x02, 0x08, 0x8D, 0x46, 0xDC, 0x00, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0x00 } }, + { { 0xF2, 0x2A, 0x9F, 0xDB, 0x01, 0xE1, 0x04, 0x8F, 0xD7, 0xC2, 0x0A, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0x00 }, + { 0xF2, 0x00, 0x9F, 0xDB, 0xA9, 0xE1, 0x00, 0x8F, 0xD7, 0xBA, 0x0A, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0x00 } }, + { { 0xE4, 0x88, 0x9C, 0x50, 0xC8, 0xE2, 0x18, 0x70, 0xC4, 0xF8, 0x0B, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0x00 }, + { 0xE6, 0x00, 0x9C, 0x50, 0xB0, 0xE4, 0x00, 0x70, 0xC4, 0xA0, 0x07, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0x00 } }, + { { 0x02, 0xA3, 0x0D, 0xDA, 0x01, 0xC2, 0x35, 0x5D, 0x58, 0x00, 0x06, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0x18 }, + { 0x02, 0xA3, 0x0D, 0xDA, 0x01, 0xC2, 0x35, 0x5D, 0x58, 0x00, 0x06, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0x18 } }, + { { 0x42, 0x53, 0x3E, 0xEB, 0x48, 0xD4, 0x05, 0x1D, 0xA9, 0xC9, 0x04, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0x18 }, + { 0x42, 0x54, 0x6F, 0xEB, 0x61, 0xD4, 0x02, 0x2E, 0xA9, 0xC8, 0x00, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0x18 } }, + { { 0xC2, 0x00, 0x59, 0x17, 0xB1, 0xC2, 0x1E, 0x6D, 0x98, 0xF8, 0x00, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0x19 }, + { 0xC2, 0x00, 0x08, 0xB3, 0x99, 0xC2, 0x06, 0x2B, 0x58, 0xFA, 0x08, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0x19 } }, + { { 0xC6, 0x01, 0x2D, 0xA7, 0x88, 0xC2, 0x08, 0x0E, 0xA7, 0xC1, 0x06, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0x00 }, + { 0xC4, 0x00, 0x2D, 0xA7, 0x91, 0xC2, 0x02, 0x0E, 0xA7, 0xD1, 0x00, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0x00 } }, + { { 0xC2, 0x0C, 0x06, 0x06, 0xA9, 0xC2, 0x3F, 0x08, 0xB8, 0xF9, 0x0A, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0x0A }, + { 0xC1, 0x00, 0x68, 0x50, 0xB8, 0xC2, 0x00, 0x48, 0x84, 0xF8, 0x0A, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0x0A } }, + { { 0xC2, 0x2E, 0x4F, 0x77, 0x00, 0xC4, 0x08, 0x0E, 0x98, 0xB1, 0x0A, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0x00 }, + { 0xC2, 0x2F, 0x6F, 0x79, 0x00, 0xC8, 0x0F, 0x5E, 0x98, 0xB9, 0x0A, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0x00 } }, + { { 0xC2, 0x30, 0x4F, 0xCA, 0x01, 0xC4, 0x0D, 0x0E, 0xB8, 0xFB, 0x08, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0x00 }, + { 0xC2, 0x30, 0x4F, 0xCA, 0x01, 0xC4, 0x0D, 0x0E, 0xB8, 0xFB, 0x08, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0x00 } }, + { { 0xC4, 0x29, 0x4F, 0xCA, 0x03, 0xC8, 0x0D, 0x0C, 0xB7, 0xF9, 0x00, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0x0B }, + { 0xC4, 0x29, 0x4F, 0xCA, 0x03, 0xC8, 0x0D, 0x0C, 0xB7, 0xF9, 0x00, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0x0B } }, + { { 0xC2, 0x41, 0x3D, 0x96, 0x88, 0xC4, 0xCA, 0x0E, 0xC7, 0xF8, 0x00, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0x20 }, + { 0xC2, 0x04, 0x58, 0xC9, 0x90, 0xC2, 0x94, 0x2C, 0xB9, 0xF0, 0x00, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0x20 } }, + { { 0x31, 0x13, 0x2D, 0xD7, 0x78, 0xE2, 0x18, 0x2E, 0xB8, 0xF8, 0x08, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0x00 }, + { 0x31, 0x13, 0x2D, 0xD7, 0x78, 0xE2, 0x18, 0x2E, 0xB8, 0xF8, 0x08, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0x00 } }, + { { 0x22, 0x86, 0x0D, 0xD7, 0xA0, 0xE4, 0x18, 0x5E, 0xB8, 0xF8, 0x06, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0x28 }, + { 0x22, 0x86, 0x0D, 0xD7, 0xA0, 0xE4, 0x18, 0x5E, 0xB8, 0xF8, 0x06, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0x28 } }, + { { 0xF2, 0x0A, 0x0D, 0xD7, 0x80, 0xE4, 0x1F, 0x5E, 0xB8, 0xF8, 0x0A, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0x00 }, + { 0xD2, 0x06, 0x9A, 0xD7, 0xA0, 0xC2, 0x1F, 0x59, 0xB8, 0xF8, 0x04, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0x00 } }, + { { 0xF2, 0x09, 0x4B, 0xD6, 0x90, 0xE4, 0x1F, 0x1C, 0xB8, 0xF8, 0x0A, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0x28 }, + { 0xF2, 0x09, 0x4B, 0xD6, 0x90, 0xE4, 0x1F, 0x1C, 0xB8, 0xF8, 0x0A, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0x28 } }, + { { 0x62, 0x11, 0x0C, 0xE6, 0x78, 0xE4, 0x1F, 0x0C, 0xC8, 0xF8, 0x0A, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0x00 }, + { 0x62, 0x11, 0x0C, 0xE6, 0x78, 0xE4, 0x1F, 0x0C, 0xC8, 0xF8, 0x0A, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0x00 } }, + { { 0xE2, 0x12, 0x3D, 0xE6, 0x68, 0xE4, 0x1F, 0x7D, 0xB8, 0xF8, 0x0A, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0x00 }, + { 0xE2, 0x12, 0x3D, 0xE6, 0x68, 0xE4, 0x1F, 0x7D, 0xB8, 0xF8, 0x0A, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0x00 } }, + { { 0xE2, 0x13, 0x3D, 0xE6, 0x68, 0xE4, 0x1F, 0x5D, 0xB8, 0xF9, 0x08, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0x00 }, + { 0xE2, 0x13, 0x3D, 0xE6, 0x68, 0xE4, 0x1F, 0x5D, 0xB8, 0xF9, 0x08, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0x00 } }, + { { 0xA2, 0x40, 0x5D, 0xBA, 0x7B, 0xE2, 0x00, 0x8F, 0xD8, 0xF1, 0x00, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0x00 }, + { 0xA2, 0x40, 0x5D, 0xBA, 0x7B, 0xE2, 0x00, 0x8F, 0xD8, 0xF1, 0x00, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0x00 } }, + { { 0xE2, 0x40, 0x3D, 0xDA, 0x73, 0xE1, 0x00, 0x7E, 0xD8, 0xF2, 0x04, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0x00 }, + { 0xE2, 0x40, 0x3D, 0xDA, 0x73, 0xE1, 0x00, 0x7E, 0xD8, 0xF2, 0x04, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0x00 } }, + { { 0x62, 0x00, 0x6D, 0xFA, 0xB9, 0xE2, 0x00, 0x8F, 0xC8, 0xF1, 0x04, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0x00 }, + { 0x62, 0x00, 0x6D, 0xFA, 0xB9, 0xE2, 0x00, 0x8F, 0xC8, 0xF1, 0x04, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0x00 } }, + { { 0xE1, 0x00, 0x4E, 0xDB, 0x92, 0xE3, 0x18, 0x6F, 0xE9, 0xFA, 0x00, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0x00 }, + { 0xE1, 0x00, 0x4E, 0xDB, 0xCA, 0xE2, 0x00, 0x6F, 0xE9, 0xFA, 0x06, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0x00 } }, + { { 0xE1, 0x00, 0x4E, 0xDB, 0xCA, 0xE2, 0x00, 0x7F, 0xE9, 0xFA, 0x06, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0x00 }, + { 0xE1, 0x00, 0x4E, 0xDB, 0xCA, 0xE2, 0x00, 0x7F, 0xE9, 0xFA, 0x06, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0x00 } }, + { { 0x02, 0x0F, 0x66, 0xAA, 0xA1, 0x02, 0x64, 0x29, 0xF9, 0xF8, 0x08, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0x04 }, + { 0x02, 0x00, 0x65, 0xAA, 0xF1, 0x02, 0x4A, 0x28, 0xF9, 0xF8, 0x08, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0x04 } }, + { { 0x16, 0x4A, 0x04, 0xBA, 0x71, 0xC2, 0x48, 0x2E, 0xCA, 0xF0, 0x0A, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0x03 }, + { 0x14, 0xC0, 0x66, 0x08, 0x90, 0xC2, 0x48, 0x2C, 0x0A, 0xA0, 0x00, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0x03 } }, + { { 0x02, 0x0A, 0x01, 0x7A, 0xB1, 0x02, 0x12, 0x2A, 0xEA, 0xF8, 0x08, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0x00 }, + { 0x02, 0x06, 0x75, 0x05, 0xB1, 0x01, 0x3F, 0x28, 0xEA, 0xF9, 0x06, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0x16 } }, + { { 0x62, 0x53, 0x9C, 0xBA, 0x61, 0x62, 0x5A, 0xAD, 0xCA, 0xC1, 0x04, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0x00 }, + { 0xF2, 0x40, 0x9F, 0x8A, 0x98, 0xE2, 0x11, 0x7F, 0xB8, 0xFA, 0x00, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0x00 } }, + { { 0xF2, 0x40, 0x6E, 0xDA, 0x91, 0xE2, 0x13, 0x8F, 0xF9, 0xF9, 0x08, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0x00 }, + { 0xF2, 0x40, 0x6E, 0xDA, 0x91, 0xE2, 0x13, 0x8F, 0xF9, 0xF9, 0x08, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0x00 } }, + { { 0xE2, 0x40, 0x8F, 0xFA, 0xA0, 0xF2, 0x04, 0x7F, 0xFA, 0xF9, 0x0A, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0x00 }, + { 0xE2, 0x40, 0x8F, 0xFA, 0xA0, 0xF2, 0x04, 0x7F, 0xFA, 0xF9, 0x0A, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0x00 } }, + { { 0xE4, 0xA0, 0xCE, 0x5B, 0x02, 0xE2, 0x32, 0x7F, 0xFB, 0x79, 0x04, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0x00 }, + { 0xE4, 0xA0, 0xCE, 0x5B, 0x02, 0xE2, 0x32, 0x7F, 0xFB, 0x79, 0x04, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0x00 } }, + { { 0xE6, 0x80, 0x9C, 0x99, 0x82, 0xE2, 0x04, 0x8D, 0x78, 0xC0, 0x04, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0x00 }, + { 0xE0, 0x44, 0x8A, 0xA9, 0x5B, 0xE1, 0x06, 0x8D, 0x79, 0xBA, 0x00, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0x00 } }, + { { 0xE8, 0xA0, 0xAC, 0x67, 0x02, 0xE2, 0x06, 0x7C, 0x7A, 0xF8, 0x06, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0x00 }, + { 0xEA, 0xA0, 0xAC, 0x67, 0x02, 0xE2, 0x00, 0x7C, 0x7A, 0xF8, 0x06, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0x00 } }, + { { 0xE7, 0x94, 0xAD, 0xB7, 0x03, 0xE2, 0x00, 0x7C, 0xBA, 0xF8, 0x00, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0x00 }, + { 0xE7, 0x94, 0xAD, 0xB7, 0x03, 0xE2, 0x00, 0x7C, 0xBA, 0xF8, 0x00, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0x00 } }, + { { 0xC3, 0x3F, 0x4B, 0xE9, 0xFA, 0xC1, 0x3F, 0x9B, 0xF9, 0xFB, 0x0B, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0x06 }, + { 0xC3, 0x3F, 0x4B, 0xE9, 0xFA, 0xC1, 0x3F, 0x9B, 0xF9, 0xFB, 0x0B, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0x06 } }, + { { 0xB2, 0x20, 0xAD, 0xE9, 0x00, 0x62, 0x05, 0x8F, 0xC8, 0xD0, 0x0E, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0x00 }, + { 0xB2, 0x25, 0xAD, 0xE9, 0x00, 0x62, 0x00, 0x8F, 0xC8, 0xF8, 0x0E, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0x00 } }, + { { 0xF2, 0x02, 0xAF, 0xFB, 0x90, 0xF6, 0x54, 0x8F, 0xE9, 0xF8, 0x0C, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0x00 }, + { 0xE2, 0x00, 0x9F, 0xFA, 0xB0, 0xF2, 0x58, 0x7F, 0xEA, 0xF8, 0x02, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0x00 } }, + { { 0xF2, 0x00, 0xAF, 0x88, 0xA8, 0xF2, 0x46, 0x6E, 0xC9, 0xE0, 0x0A, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0x00 }, + { 0xD2, 0x00, 0x7B, 0x88, 0xA8, 0xD2, 0x4C, 0x69, 0xE9, 0xF8, 0x06, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0x00 } }, + { { 0xF2, 0x2A, 0x9F, 0x98, 0x01, 0xE2, 0x8F, 0x4E, 0x78, 0xC0, 0x0E, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0x00 }, + { 0xD2, 0x02, 0x85, 0x89, 0xC8, 0xD2, 0x94, 0x77, 0x49, 0xF9, 0x08, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0x00 } }, + { { 0xE2, 0x02, 0x9F, 0xB8, 0x90, 0x22, 0x8A, 0x9F, 0xE8, 0xF8, 0x00, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0x00 }, + { 0xC2, 0x00, 0x86, 0xB8, 0x98, 0x02, 0x8F, 0x89, 0xE8, 0xF9, 0x04, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0x00 } }, + { { 0xE2, 0x2A, 0x7F, 0xB8, 0x01, 0xE4, 0x00, 0x0D, 0xC5, 0xF8, 0x0C, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0x00 }, + { 0xE2, 0x2A, 0x7F, 0xB8, 0x01, 0xE4, 0x00, 0x0D, 0xC5, 0xF8, 0x0C, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0x00 } }, + { { 0xE4, 0x28, 0x8E, 0xE8, 0x01, 0xF2, 0x00, 0x4D, 0xD6, 0xF9, 0x0C, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0x00 }, + { 0xE4, 0x28, 0x8E, 0xE8, 0x01, 0xF2, 0x00, 0x4D, 0xD6, 0xF9, 0x0C, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0x00 } }, + { { 0x62, 0x23, 0x8F, 0xEA, 0x00, 0xF2, 0x00, 0x5E, 0xD9, 0xF8, 0x0C, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0x00 }, + { 0x62, 0x23, 0x8F, 0xEA, 0x00, 0xF2, 0x00, 0x5E, 0xD9, 0xF8, 0x0C, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0x00 } }, + { { 0xB4, 0x26, 0x6E, 0x98, 0x01, 0x62, 0x00, 0x7D, 0xC8, 0xF9, 0x00, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0x00 }, + { 0xB4, 0x26, 0x6E, 0x98, 0x01, 0x62, 0x00, 0x7D, 0xC8, 0xF9, 0x00, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0x00 } }, + { { 0xE2, 0x2E, 0x20, 0xD9, 0x01, 0xF2, 0x1A, 0x90, 0xF8, 0xF8, 0x0E, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0x00 }, + { 0xD2, 0x10, 0x69, 0x18, 0xCF, 0xD4, 0x14, 0x5B, 0x04, 0xFD, 0x0A, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0x00 } }, + { { 0xE4, 0x28, 0x7E, 0xF8, 0x01, 0xE2, 0x23, 0x8E, 0xE8, 0xF9, 0x08, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0x00 }, + { 0xE4, 0x28, 0x7E, 0xF8, 0x01, 0xE2, 0x23, 0x8E, 0xE8, 0xF9, 0x08, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0x00 } }, + { { 0xB8, 0x28, 0x9E, 0x98, 0x01, 0x62, 0x00, 0x3D, 0xC8, 0xF9, 0x08, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0x00 }, + { 0xB8, 0x28, 0x9E, 0x98, 0x01, 0x62, 0x00, 0x3D, 0xC8, 0xF9, 0x08, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0x00 } }, + { { 0x62, 0x00, 0x8E, 0xC9, 0x79, 0xE6, 0x00, 0x7E, 0xD8, 0xD0, 0x0A, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0x00 }, + { 0x62, 0x00, 0x8E, 0xC9, 0x79, 0xE6, 0x00, 0x7E, 0xD8, 0xD0, 0x0A, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0x00 } }, + { { 0xE2, 0x00, 0x5F, 0xF9, 0x88, 0xE4, 0x9E, 0x8F, 0xF8, 0xF9, 0x08, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0x00 }, + { 0xC2, 0x00, 0x97, 0xF9, 0x90, 0xC9, 0x80, 0x69, 0x98, 0xA0, 0x00, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0x00 } }, + { { 0x62, 0x0C, 0x6E, 0xD8, 0x79, 0x2A, 0x09, 0x7D, 0xD8, 0xC0, 0x04, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0x00 }, + { 0x02, 0x04, 0x8A, 0xD8, 0x80, 0x0C, 0x12, 0x85, 0xD8, 0xF8, 0x0A, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0x00 } }, + { { 0xE4, 0x00, 0x7E, 0x89, 0x70, 0xE6, 0x8F, 0x80, 0xF8, 0xF0, 0x0C, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0x00 }, + { 0xC4, 0x00, 0x67, 0x59, 0x70, 0xC6, 0x8A, 0x77, 0xA8, 0xF8, 0x00, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0x00 } }, + { { 0xE4, 0x80, 0x6C, 0xD9, 0x60, 0xE2, 0x00, 0x8D, 0xC8, 0xF8, 0x00, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0x00 }, + { 0xE4, 0x80, 0x6C, 0xD9, 0x60, 0xE2, 0x00, 0x8D, 0xC8, 0xF8, 0x00, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0x00 } }, + { { 0xE2, 0x80, 0x88, 0x48, 0x98, 0xE2, 0x1E, 0x8E, 0xC9, 0xF8, 0x08, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0x00 }, + { 0xF2, 0x40, 0xA8, 0xB9, 0x80, 0xE2, 0x0C, 0x89, 0x09, 0xF8, 0x0E, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0x00 } }, + { { 0xE4, 0x00, 0x77, 0xC5, 0xA8, 0xE2, 0x00, 0x9E, 0xD7, 0xE0, 0x06, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0x00 }, + { 0xE4, 0x00, 0x77, 0xC5, 0xA8, 0xE2, 0x00, 0x9E, 0xD7, 0xE0, 0x06, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0x00 } }, + { { 0xE4, 0x80, 0x86, 0xB9, 0xA8, 0xE2, 0x14, 0x9F, 0xD7, 0xB0, 0x0A, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0x00 }, + { 0xC2, 0x80, 0x94, 0x09, 0x78, 0xC2, 0x00, 0x97, 0x97, 0xF8, 0x04, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0x00 } }, + { { 0xE2, 0x00, 0x68, 0x68, 0xAA, 0xE2, 0x0A, 0x9B, 0xB3, 0xF8, 0x08, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0x00 }, + { 0xC2, 0x00, 0x86, 0x68, 0xA0, 0xC2, 0x00, 0x77, 0x47, 0xE0, 0x04, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0x00 } }, + { { 0xE4, 0x00, 0xA6, 0x87, 0x81, 0xE2, 0x0A, 0x7E, 0xC9, 0xF8, 0x06, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0x00 }, + { 0xE2, 0x00, 0x89, 0x40, 0x79, 0xE2, 0x00, 0x7E, 0xC9, 0x90, 0x06, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0x00 } }, + { { 0xE4, 0x80, 0xAA, 0xB8, 0x90, 0xE2, 0x00, 0x9E, 0xF9, 0xC0, 0x09, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0x00 }, + { 0xE6, 0x80, 0x9D, 0xB8, 0x51, 0xE2, 0x00, 0x9E, 0xF9, 0xA0, 0x01, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0x00 } }, + { { 0xE2, 0x80, 0x8E, 0x64, 0xD0, 0xE2, 0x28, 0x6F, 0x73, 0xF8, 0x01, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0x00 }, + { 0xE2, 0x80, 0x8E, 0x64, 0xD0, 0xE2, 0x28, 0x6F, 0x73, 0xF8, 0x01, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0x00 } }, + { { 0xE8, 0x00, 0x7D, 0x99, 0xA8, 0xE6, 0x80, 0x80, 0xF8, 0xF8, 0x0C, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0x00 }, + { 0xE8, 0x00, 0x7D, 0x99, 0xA8, 0xE6, 0x80, 0x80, 0xF8, 0xF8, 0x0C, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0x00 } }, + { { 0xE6, 0x00, 0x9F, 0xB9, 0xD9, 0xE1, 0x00, 0x8F, 0xC8, 0xF9, 0x02, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0x00 }, + { 0xE6, 0x00, 0x9F, 0xB9, 0xD9, 0xE1, 0x00, 0x8F, 0xC8, 0xF9, 0x02, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0x00 } }, + { { 0xE4, 0x00, 0x09, 0x68, 0x92, 0xE2, 0x2B, 0x9E, 0xF3, 0xF8, 0x0E, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0x00 }, + { 0xE4, 0x00, 0x09, 0x68, 0x92, 0xE2, 0x2B, 0x9E, 0xF3, 0xF8, 0x0E, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0x00 } }, + { { 0xC4, 0x00, 0x99, 0xE8, 0x73, 0xE2, 0x25, 0x6F, 0x93, 0xF8, 0x0E, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0x00 }, + { 0xC4, 0x00, 0x99, 0xE8, 0x73, 0xE2, 0x25, 0x6F, 0x93, 0xF8, 0x0E, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0x00 } }, + { { 0xE6, 0x00, 0x6F, 0xDA, 0xC9, 0xE2, 0x05, 0x2F, 0xD8, 0xAA, 0x08, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0x00 }, + { 0xE2, 0x00, 0x4F, 0xDA, 0xC8, 0xE2, 0x00, 0x0F, 0xD8, 0xD0, 0x06, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0x00 } }, + { { 0xEC, 0x60, 0x9D, 0xC7, 0x00, 0xE2, 0x21, 0x7F, 0xC9, 0xF8, 0x06, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0x00 }, + { 0xEC, 0x60, 0x9D, 0xC7, 0x00, 0xE2, 0x21, 0x7F, 0xC9, 0xF8, 0x06, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0x00 } }, + { { 0xE3, 0x00, 0x0F, 0xF7, 0xF9, 0xE1, 0x3F, 0x0F, 0xA7, 0x01, 0x0D, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0x00 }, + { 0xE3, 0x00, 0x0F, 0xF7, 0xF9, 0xE1, 0x3F, 0x0F, 0xA7, 0x01, 0x0D, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0x00 } }, + { { 0xE4, 0xA9, 0x0F, 0xA8, 0x02, 0xE2, 0x3C, 0x5F, 0xDA, 0x78, 0x0E, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0x00 }, + { 0xE4, 0xA9, 0x0F, 0xA8, 0x02, 0xE2, 0x3C, 0x5F, 0xDA, 0x78, 0x0E, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0x00 } }, + { { 0xE8, 0x40, 0x0D, 0x89, 0xF9, 0xE2, 0x17, 0x7E, 0xD9, 0xF8, 0x07, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0x00 }, + { 0xE8, 0x40, 0x0D, 0x89, 0xF9, 0xE2, 0x17, 0x7E, 0xD9, 0xF8, 0x07, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0x00 } }, + { { 0xE1, 0x00, 0xDF, 0x8A, 0xAA, 0xE2, 0x5E, 0xCF, 0xBA, 0xFA, 0x08, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0x00 }, + { 0xE1, 0x00, 0xDF, 0x8A, 0xAA, 0xE2, 0x5E, 0xCF, 0xBA, 0xFA, 0x08, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0x00 } }, + { { 0xE2, 0x00, 0x0B, 0x68, 0xC0, 0xE2, 0x01, 0x9E, 0xB8, 0xF8, 0x0A, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0x00 }, + { 0xE2, 0x00, 0x0B, 0x68, 0xC0, 0xE2, 0x01, 0x9E, 0xB8, 0xF8, 0x0A, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0x00 } }, + { { 0xEA, 0x00, 0xAE, 0xAB, 0x91, 0xE2, 0x00, 0xAE, 0xBA, 0xD8, 0x08, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0x00 }, + { 0xEA, 0x00, 0xAE, 0xAB, 0x91, 0xE2, 0x00, 0xAE, 0xBA, 0xD8, 0x08, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0x00 } }, + { { 0xEB, 0x80, 0x8C, 0xCB, 0x72, 0xE2, 0x86, 0xAF, 0xCA, 0xF8, 0x08, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0x00 }, + { 0xEB, 0xC3, 0x9C, 0xCB, 0xA2, 0xE2, 0x4C, 0xAE, 0xCA, 0xFA, 0x08, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0x00 } }, + { { 0xE5, 0x40, 0xDB, 0x3B, 0x78, 0xE2, 0x80, 0xBE, 0xCA, 0xE1, 0x00, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0x00 }, + { 0xE2, 0x80, 0x8E, 0xCB, 0xC0, 0xE2, 0x90, 0xAE, 0xCA, 0xFB, 0x0A, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0x00 } }, + { { 0xE4, 0x00, 0x9E, 0xAA, 0x79, 0xE1, 0x43, 0x0F, 0xBA, 0xFA, 0x04, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0x00 }, + { 0xE4, 0x00, 0x9E, 0xAA, 0x79, 0xE1, 0x43, 0x0F, 0xBA, 0xFA, 0x04, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0x00 } }, + { { 0xE7, 0x40, 0xEB, 0xCA, 0x80, 0xE2, 0x03, 0xBF, 0xBA, 0xC2, 0x02, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0x00 }, + { 0xE3, 0x80, 0xDB, 0xCA, 0x40, 0xE2, 0x08, 0xDF, 0xBA, 0xC1, 0x04, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0x00 } }, + { { 0xEA, 0x00, 0x68, 0xB8, 0x90, 0xE2, 0x0A, 0x8E, 0xB8, 0xF8, 0x0C, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0x00 }, + { 0xEA, 0x00, 0x68, 0xB8, 0x90, 0xE2, 0x0A, 0x8E, 0xB8, 0xF8, 0x0C, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0x00 } }, + { { 0x61, 0x00, 0xBE, 0x99, 0xFA, 0xE3, 0x40, 0xCF, 0xCA, 0xF9, 0x09, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0x00 }, + { 0x62, 0x00, 0xCE, 0x9A, 0xA8, 0xE2, 0x45, 0xCF, 0xCA, 0xA0, 0x0A, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0x00 } }, + { { 0xCD, 0x00, 0x0B, 0x00, 0x90, 0xC2, 0x58, 0x0C, 0x00, 0xF8, 0x0C, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0x1C }, + { 0xCD, 0x00, 0x0B, 0x00, 0x90, 0xC2, 0x58, 0x0C, 0x00, 0xF8, 0x0C, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0x1C } }, + { { 0xE2, 0x00, 0x0E, 0x00, 0xA2, 0xE2, 0x58, 0x5F, 0xD0, 0xF9, 0x08, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0x00 }, + { 0xE2, 0x00, 0x0E, 0x00, 0xA2, 0xE2, 0x58, 0x5F, 0xD0, 0xF9, 0x08, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0x00 } }, + { { 0xEC, 0x00, 0x7D, 0xDA, 0x80, 0xE2, 0x00, 0x5E, 0x9B, 0xA8, 0x0C, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0x00 }, + { 0xE6, 0x0A, 0x4C, 0xC9, 0x60, 0xE2, 0x07, 0x0C, 0x7A, 0xB8, 0x08, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0x00 } }, + { { 0xE9, 0xC0, 0xEE, 0xD8, 0x83, 0xE2, 0x05, 0xDD, 0xAA, 0xE0, 0x06, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0x00 }, + { 0xED, 0x48, 0xDE, 0xD8, 0xB4, 0xE1, 0x00, 0xDD, 0xAA, 0xA9, 0x00, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0x00 } }, + { { 0xDA, 0x00, 0x8F, 0xAC, 0x92, 0x22, 0x05, 0x8D, 0x8A, 0xE9, 0x02, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0x00 }, + { 0xEF, 0x00, 0x8C, 0xAA, 0x67, 0x25, 0x00, 0x9D, 0xAB, 0xC1, 0x08, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0x00 } }, + { { 0x62, 0x82, 0xCB, 0x7A, 0xD8, 0xE6, 0x56, 0xAF, 0xDB, 0xE0, 0x02, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0x00 }, + { 0x62, 0x84, 0xBB, 0xAA, 0xCA, 0xCF, 0x41, 0xAC, 0xDA, 0xF8, 0x08, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0x00 } }, + { { 0xC2, 0x41, 0xAC, 0xBB, 0xBB, 0xC2, 0x85, 0x0E, 0xCB, 0xF9, 0x0A, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0x12 }, + { 0xC2, 0x03, 0x6A, 0x5B, 0xA4, 0xC2, 0x0D, 0x2A, 0xBB, 0xFC, 0x00, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0x12 } }, + { { 0x75, 0x00, 0x0E, 0xBB, 0xB2, 0xE2, 0x1E, 0x0A, 0xA9, 0xF9, 0x0A, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0x10 }, + { 0x62, 0x00, 0x04, 0x9A, 0xE8, 0xE2, 0x00, 0x0A, 0x48, 0xFD, 0x04, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0x10 } }, + { { 0x41, 0x00, 0x0E, 0xEA, 0xA3, 0xC2, 0x00, 0x08, 0xCA, 0xF8, 0x08, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0x07 }, + { 0x41, 0x00, 0x0E, 0xEA, 0xA3, 0xC2, 0x00, 0x08, 0xCA, 0xF8, 0x08, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0x07 } }, + { { 0xC1, 0x40, 0x0C, 0x59, 0xD2, 0xC2, 0x80, 0x3C, 0xAB, 0xF8, 0x08, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0x0D }, + { 0xC1, 0x40, 0x0C, 0x59, 0xD2, 0xC2, 0x80, 0x3C, 0xAB, 0xF8, 0x08, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0x0D } }, + { { 0x4B, 0x00, 0x0A, 0xF5, 0xC1, 0xC2, 0x19, 0x0C, 0xE9, 0xF8, 0x08, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0x07 }, + { 0x4B, 0x00, 0x0A, 0xF5, 0xC1, 0xC2, 0x19, 0x0C, 0xE9, 0xF8, 0x08, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0x07 } }, + { { 0x62, 0x00, 0x7F, 0xD8, 0xA8, 0xEA, 0x00, 0x8F, 0xD8, 0xF9, 0x0A, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0x00 }, + { 0x62, 0x00, 0x7F, 0xD8, 0xA8, 0xEA, 0x00, 0x8F, 0xD8, 0xF9, 0x0A, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0x00 } }, + { { 0xE1, 0x00, 0x7F, 0xD9, 0xAA, 0xE1, 0x00, 0x8F, 0xD8, 0xFA, 0x06, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0x00 }, + { 0xE1, 0x00, 0x7F, 0xD9, 0xAA, 0xE1, 0x00, 0x8F, 0xD8, 0xFA, 0x06, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0x00 } }, + { { 0xE1, 0x00, 0x7F, 0xD9, 0xAA, 0xE1, 0x00, 0x8F, 0xD8, 0xFA, 0x06, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0x00 }, + { 0xE1, 0x00, 0x7F, 0xD9, 0xAA, 0xE1, 0x00, 0x8F, 0xD8, 0xFA, 0x06, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0x00 } }, + { { 0xCF, 0x40, 0x09, 0xEA, 0xA8, 0xC4, 0x00, 0x0C, 0xDB, 0xC8, 0x08, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0x02 }, + { 0xCF, 0x40, 0x09, 0xEA, 0xA8, 0xC4, 0x00, 0x0C, 0xDB, 0xC8, 0x08, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0x02 } }, + { { 0xCF, 0x40, 0x0C, 0xAA, 0xA8, 0xC4, 0x00, 0x18, 0xF9, 0xC8, 0x0C, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0x02 }, + { 0xCF, 0x40, 0x0C, 0xAA, 0xA8, 0xC4, 0x00, 0x18, 0xF9, 0xC8, 0x0C, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0x02 } }, + { { 0xC9, 0x0C, 0x88, 0xD9, 0x6A, 0xC2, 0x14, 0x3A, 0xEA, 0xF8, 0x0C, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0x05 }, + { 0xC5, 0x00, 0x98, 0xD9, 0x92, 0xC1, 0x16, 0x6E, 0xF9, 0xE8, 0x06, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0x05 } }, + { { 0x03, 0x00, 0x15, 0x00, 0xC8, 0x02, 0x00, 0x08, 0x00, 0xF8, 0x09, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0x02 }, + { 0x03, 0x00, 0x15, 0x00, 0xC8, 0x02, 0x00, 0x08, 0x00, 0xF8, 0x09, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0x02 } }, + { { 0x01, 0x0C, 0x44, 0xE6, 0xE8, 0x01, 0x3F, 0x0C, 0xEA, 0xF8, 0x0C, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0x04 }, + { 0x02, 0x3F, 0x05, 0x08, 0xF8, 0x03, 0x3F, 0x3C, 0xF9, 0xF8, 0x0A, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0x06 } }, + { { 0x00, 0x00, 0x36, 0x67, 0xF8, 0x01, 0x3F, 0x0E, 0xFA, 0xF8, 0x00, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0x05 }, + { 0x00, 0x00, 0x36, 0x67, 0xF8, 0x01, 0x3F, 0x0E, 0xFA, 0xF8, 0x00, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0x05 } }, + { { 0x02, 0x00, 0x36, 0x68, 0xF8, 0x01, 0x3F, 0x0E, 0xFA, 0xF8, 0x00, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0x05 }, + { 0x02, 0x00, 0x36, 0x68, 0xF8, 0x01, 0x3F, 0x0E, 0xFA, 0xF8, 0x00, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0x05 } }, + { { 0xCB, 0x00, 0xAF, 0x00, 0xFA, 0xC0, 0x00, 0xC0, 0x06, 0xFB, 0x0E, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0x0F }, + { 0xCB, 0x00, 0xAF, 0x00, 0xFA, 0xC0, 0x00, 0xC0, 0x06, 0xFB, 0x0E, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0x0F } }, + { { 0x05, 0x0D, 0x80, 0xA6, 0xFB, 0x0B, 0x38, 0xA9, 0xD8, 0x00, 0x0E, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0x04 }, + { 0x05, 0x0D, 0x80, 0xA6, 0xFB, 0x0B, 0x38, 0xA9, 0xD8, 0x00, 0x0E, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0x04 } }, + { { 0x0F, 0x00, 0x90, 0xFA, 0xD0, 0x06, 0x00, 0xA7, 0x39, 0xA8, 0x0E, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0x06 }, + { 0x0F, 0x00, 0x90, 0xFA, 0xD0, 0x06, 0x00, 0xA7, 0x39, 0xA8, 0x0E, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0x06 } }, + { { 0xC9, 0x15, 0xDD, 0xFF, 0xF8, 0x00, 0x00, 0xE7, 0xFC, 0xD8, 0x0E, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0x38 }, + { 0xC9, 0x15, 0xDD, 0xFF, 0xF8, 0x00, 0x00, 0xE7, 0xFC, 0xD8, 0x0E, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0x38 } }, + { { 0x48, 0x3C, 0x30, 0xF6, 0x03, 0x0A, 0x38, 0x97, 0xE8, 0x00, 0x0E, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0x04 }, + { 0x48, 0x3C, 0x30, 0xF6, 0x03, 0x0A, 0x38, 0x97, 0xE8, 0x00, 0x0E, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0x04 } }, + { { 0x07, 0x80, 0x0B, 0xC8, 0xC9, 0x02, 0x3F, 0x0C, 0xEA, 0xF8, 0x0F, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0x05 }, + { 0x07, 0x80, 0x0B, 0xC8, 0xC9, 0x02, 0x3F, 0x0C, 0xEA, 0xF8, 0x0F, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0x05 } }, + { { 0x00, 0x21, 0x66, 0x40, 0x03, 0x00, 0x3F, 0x47, 0x00, 0x00, 0x0E, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0x02 }, + { 0x00, 0x21, 0x66, 0x40, 0x03, 0x00, 0x3F, 0x47, 0x00, 0x00, 0x0E, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0x02 } }, + { { 0x08, 0x00, 0x0B, 0x3C, 0xF8, 0x08, 0x3F, 0x06, 0xF3, 0x00, 0x0E, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0x02 }, + { 0x08, 0x00, 0x0B, 0x3C, 0xF8, 0x08, 0x3F, 0x06, 0xF3, 0x00, 0x0E, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0x02 } }, + { { 0x00, 0x3F, 0x4C, 0xFB, 0x00, 0x00, 0x3F, 0x0A, 0xE9, 0xF8, 0x0E, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0x05 }, + { 0x00, 0x3F, 0x4C, 0xFB, 0x00, 0x00, 0x3F, 0x0A, 0xE9, 0xF8, 0x0E, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0x05 } }, +}; + +static const AdLibInstrument g_gmPercussionInstrumentsOPL3[39][2] = { + { { 0x1A, 0x3F, 0x15, 0x05, 0xF8, 0x02, 0x21, 0x2B, 0xE4, 0xF8, 0x0E, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0x06 }, + { 0x11, 0x18, 0x15, 0x00, 0xF8, 0x12, 0x00, 0x2B, 0x03, 0xF8, 0x06, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0x06 } }, + { { 0x11, 0x12, 0x04, 0x07, 0xF8, 0x02, 0x18, 0x0B, 0xE5, 0xF8, 0x0E, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0x05 }, + { 0x11, 0x28, 0x06, 0x04, 0xF8, 0x02, 0x1E, 0x1B, 0x02, 0xF8, 0x0A, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0x05 } }, + { { 0x0A, 0x3F, 0x0B, 0x01, 0xF8, 0x1F, 0x13, 0x46, 0xD0, 0xF8, 0x0E, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0x01 }, + { 0x04, 0x18, 0x06, 0x01, 0xB0, 0x10, 0x00, 0x07, 0x00, 0x90, 0x00, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0x01 } }, + { { 0x00, 0x3F, 0x0F, 0x00, 0xF8, 0x10, 0x0A, 0x07, 0x00, 0xF8, 0x0E, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0x02 }, + { 0x02, 0x14, 0x04, 0x00, 0xC0, 0x11, 0x08, 0x07, 0x00, 0xC6, 0x02, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0x02 } }, + { { 0x0F, 0x3F, 0x0B, 0x00, 0xF8, 0x1F, 0x07, 0x19, 0xD0, 0xF8, 0x0E, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0x02 }, + { 0x0E, 0x32, 0x76, 0x03, 0xF8, 0x1F, 0x0F, 0x77, 0xD4, 0xFC, 0x0E, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0x02 } }, + { { 0x00, 0x3F, 0x1F, 0x00, 0xFA, 0x1F, 0x0C, 0x07, 0x00, 0xF8, 0x0E, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0x03 }, + { 0x07, 0x11, 0x13, 0x00, 0xA0, 0x13, 0x00, 0x07, 0x00, 0xC8, 0x04, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0x03 } }, + { { 0x12, 0x3F, 0x05, 0x06, 0xF8, 0x03, 0x16, 0x4A, 0xD9, 0xF8, 0x0E, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0x03 }, + { 0x02, 0x22, 0x05, 0xB6, 0xF8, 0x04, 0x0A, 0x59, 0x03, 0xF8, 0x0B, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0x03 } }, + { { 0xCF, 0x7F, 0x08, 0xFF, 0xFA, 0x00, 0xC0, 0x2D, 0xF7, 0xE3, 0x0E, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0x02 }, + { 0xD2, 0x7F, 0x04, 0x0F, 0xFA, 0x10, 0xCD, 0x24, 0x07, 0xFB, 0x0E, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0x02 } }, + { { 0x12, 0x3F, 0x05, 0x06, 0xF8, 0x43, 0x17, 0x0C, 0xE9, 0xF8, 0x0E, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0x03 }, + { 0x12, 0x13, 0x09, 0x96, 0xF8, 0x44, 0x0A, 0x07, 0x03, 0xF8, 0x07, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0x03 } }, + { { 0xCF, 0x7F, 0x08, 0xCF, 0xFA, 0x00, 0x40, 0x2A, 0xF8, 0x8B, 0x0E, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0x0C }, + { 0xCF, 0x7F, 0x05, 0x07, 0xFA, 0x00, 0x40, 0x25, 0x08, 0xC3, 0x0E, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0x0C } }, + { { 0x12, 0x3F, 0x06, 0x17, 0xF8, 0x03, 0x1D, 0x0B, 0xE9, 0xF8, 0x0E, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0x03 }, + { 0x12, 0x1A, 0x08, 0x96, 0xF8, 0x44, 0x00, 0x08, 0x03, 0xF8, 0x05, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0x03 } }, + { { 0xCF, 0x7F, 0x08, 0xCD, 0xFA, 0x00, 0x40, 0x1A, 0x69, 0xB3, 0x0E, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0x0C }, + { 0xCD, 0x3F, 0x36, 0x05, 0xFC, 0x0F, 0x47, 0x46, 0x06, 0xDF, 0x0E, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0x0C } }, + { { 0x13, 0x3F, 0x05, 0x06, 0xF8, 0x03, 0x0D, 0x0A, 0xD9, 0xF8, 0x0E, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0x03 }, + { 0x12, 0x14, 0x09, 0x96, 0xF8, 0x44, 0x02, 0x07, 0x03, 0xF8, 0x07, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0x03 } }, + { { 0x15, 0x3F, 0x05, 0x06, 0xF8, 0x03, 0x16, 0x0C, 0xE9, 0xF8, 0x0E, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0x03 }, + { 0x12, 0x00, 0x07, 0x96, 0xE8, 0x44, 0x02, 0x08, 0x03, 0xF8, 0x07, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0x03 } }, + { { 0xCF, 0x3F, 0x2B, 0xFB, 0xFA, 0xC0, 0x16, 0x1A, 0xCA, 0xFB, 0x0E, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0x10 }, + { 0xCF, 0x3F, 0x2B, 0xFB, 0xFA, 0xC0, 0x1E, 0x1A, 0xCA, 0xFB, 0x0E, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0x10 } }, + { { 0x17, 0x3F, 0x04, 0x09, 0xF8, 0x03, 0x18, 0x0D, 0xE9, 0xF8, 0x0E, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0x03 }, + { 0x12, 0x00, 0x07, 0x96, 0xF8, 0x44, 0x02, 0x08, 0xF9, 0xF8, 0x01, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0x03 } }, + { { 0xCF, 0x3F, 0x0F, 0x5E, 0xF8, 0xC6, 0x0C, 0x00, 0xCA, 0xFB, 0x04, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0x03 }, + { 0xCF, 0x3F, 0x04, 0x57, 0xF8, 0xC5, 0x13, 0x06, 0x05, 0xFF, 0x04, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0x03 } }, + { { 0xCF, 0x3F, 0x7E, 0x9D, 0xF8, 0xC8, 0xC0, 0x0A, 0xBA, 0xD0, 0x0E, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0x06 }, + { 0xCF, 0x3F, 0x77, 0x09, 0xF8, 0xC2, 0xC0, 0x08, 0xB5, 0xEA, 0x0E, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0x06 } }, + { { 0xCF, 0x3F, 0x4D, 0x9F, 0xF8, 0xC6, 0x00, 0x08, 0xDA, 0xAB, 0x04, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0x04 }, + { 0xCF, 0x3F, 0x47, 0x06, 0xF8, 0xCD, 0x00, 0x07, 0x05, 0xB3, 0x04, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0x04 } }, + { { 0xCF, 0x3F, 0x5D, 0xAA, 0xF2, 0xC0, 0x8A, 0x67, 0x99, 0xF8, 0x0A, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0x02 }, + { 0xCF, 0x3F, 0x9A, 0x69, 0xF8, 0xCF, 0x88, 0x88, 0x48, 0xFA, 0x00, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0x02 } }, + { { 0xCF, 0x3F, 0x4A, 0xFD, 0xF8, 0xCF, 0x00, 0x59, 0xEA, 0xD8, 0x0E, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0x02 }, + { 0xCF, 0x3F, 0x48, 0x06, 0xF8, 0xCF, 0x00, 0x54, 0x04, 0xF9, 0x0E, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0x02 } }, + { { 0x0F, 0x18, 0x0A, 0xFA, 0xAB, 0x06, 0x06, 0x06, 0x39, 0xF8, 0x0A, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0x02 }, + { 0x03, 0x18, 0x04, 0x09, 0xAC, 0x05, 0x07, 0x08, 0x07, 0xF8, 0x04, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0x02 } }, + { { 0xCF, 0x3F, 0x2B, 0xFC, 0xF8, 0xCC, 0xC4, 0x0B, 0xEA, 0xFB, 0x0E, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0x10 }, + { 0xCF, 0x3F, 0x25, 0x06, 0xF8, 0xCC, 0xD7, 0x05, 0x02, 0xF8, 0x0E, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0x10 } }, + { { 0x05, 0x1A, 0x04, 0x00, 0xF8, 0x12, 0x08, 0x0C, 0xEA, 0xE0, 0x0E, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0x07 }, + { 0x01, 0x00, 0x09, 0x08, 0x40, 0x13, 0x00, 0x2A, 0x0A, 0xD8, 0x00, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0x07 } }, + { { 0x04, 0x19, 0x04, 0x00, 0xF8, 0x12, 0x08, 0x2C, 0xEA, 0xE0, 0x0E, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0x04 }, + { 0x04, 0x00, 0x07, 0x08, 0x40, 0x12, 0x00, 0x29, 0x08, 0xE0, 0x00, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0x04 } }, + { { 0x04, 0x0A, 0x04, 0x00, 0xD8, 0x01, 0x02, 0x0D, 0xFA, 0xE0, 0x0E, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0x07 }, + { 0x04, 0x00, 0x03, 0x09, 0x93, 0x02, 0x00, 0x28, 0x09, 0xE8, 0x08, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0x07 } }, + { { 0x15, 0x14, 0x05, 0x00, 0xF9, 0x01, 0x03, 0x5C, 0xE9, 0xD8, 0x0E, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0x05 }, + { 0x05, 0x00, 0x03, 0x03, 0x49, 0x02, 0x00, 0x58, 0x08, 0xE0, 0x08, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0x05 } }, + { { 0x10, 0x10, 0x05, 0x08, 0xF8, 0x01, 0x03, 0x0D, 0xEA, 0xE8, 0x0E, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0x05 }, + { 0x10, 0x00, 0x0C, 0x0C, 0x48, 0x02, 0x00, 0x08, 0xB9, 0xE0, 0x00, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0x05 } }, + { { 0x11, 0x00, 0x06, 0x87, 0xFB, 0x02, 0x40, 0x09, 0x59, 0xC0, 0x0E, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0x08 }, + { 0x15, 0x00, 0x04, 0x87, 0xFB, 0x02, 0x40, 0x09, 0x59, 0xD0, 0x0E, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0x08 } }, + { { 0x13, 0x26, 0x04, 0x6A, 0xFB, 0x01, 0x00, 0x08, 0x5A, 0xE0, 0x0E, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0x08 }, + { 0x12, 0x26, 0x03, 0x6A, 0xFB, 0x02, 0x00, 0x06, 0x5A, 0xC0, 0x0E, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0x08 } }, + { { 0xCF, 0x4D, 0x0C, 0xAA, 0xA0, 0xC4, 0x00, 0x18, 0xF9, 0x90, 0x04, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0x02 }, + { 0xCF, 0x4E, 0x05, 0xA6, 0xA0, 0xC6, 0x00, 0x16, 0xF8, 0x60, 0x04, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0x02 } }, + { { 0xCF, 0x4D, 0x0C, 0xAA, 0xA0, 0xC3, 0x00, 0x18, 0xF8, 0x98, 0x04, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0x02 }, + { 0xCF, 0x4E, 0x06, 0xAA, 0xA0, 0xC5, 0x00, 0x19, 0xF9, 0x90, 0x04, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0x02 } }, + { { 0xCB, 0x3F, 0x8F, 0x00, 0xFA, 0xC5, 0x06, 0x98, 0xD6, 0xBB, 0x0E, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0x0D }, + { 0xC0, 0x00, 0xF0, 0x00, 0x00, 0xC0, 0x00, 0xF0, 0x00, 0x00, 0x00, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0x0D } }, + { { 0x0C, 0x18, 0x87, 0xB3, 0xFB, 0x19, 0x0B, 0x55, 0x75, 0xF8, 0x0E, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0x02 }, + { 0x0C, 0x18, 0x87, 0xB3, 0xFB, 0x1B, 0x10, 0x57, 0x75, 0xF8, 0x0E, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0x02 } }, + { { 0x05, 0x11, 0x15, 0x00, 0xC8, 0x02, 0x00, 0x08, 0x00, 0xA8, 0x09, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0x02 }, + { 0x02, 0x11, 0x13, 0x00, 0xC8, 0x02, 0x00, 0x05, 0x00, 0x80, 0x09, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0x02 } }, + { { 0x04, 0x08, 0x15, 0x00, 0x90, 0x01, 0x00, 0x08, 0x00, 0xC0, 0x08, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0x02 }, + { 0x03, 0x08, 0x14, 0x00, 0x90, 0x02, 0x00, 0x07, 0x00, 0xA8, 0x00, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0x02 } }, + { { 0xDA, 0x00, 0x53, 0x30, 0xC0, 0x07, 0x10, 0x49, 0xC4, 0xDA, 0x03, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0x00 }, + { 0xD2, 0x00, 0x56, 0x30, 0x90, 0x06, 0x00, 0x46, 0x56, 0x62, 0x09, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0x00 } }, + { { 0x1C, 0x00, 0x07, 0xBC, 0xC8, 0x0C, 0x0A, 0x0B, 0x6A, 0xF2, 0x0B, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0x03 }, + { 0x18, 0x00, 0x07, 0xBC, 0x88, 0x09, 0x00, 0x0B, 0x6A, 0xBA, 0x0B, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0x03 } }, + { { 0x0A, 0x0E, 0x7F, 0x00, 0xF9, 0x13, 0x16, 0x28, 0x03, 0xF8, 0x06, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0x00 }, + { 0x01, 0x0E, 0x54, 0x00, 0xF9, 0x15, 0x03, 0x27, 0x03, 0xF8, 0x06, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0x00 } }, +}; + static const byte g_gmPercussionInstrumentMap[128] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, @@ -587,14 +933,16 @@ public: // AudioStream API - bool isStereo() const { return false; } + bool isStereo() const { return _opl->isStereo(); } int getRate() const { return _mixer->getOutputRate(); } private: bool _scummSmallHeader; // FIXME: This flag controls a special mode for SCUMM V3 games + bool _opl3Mode; OPL::OPL *_opl; byte *_regCache; + byte *_regCacheSecondary; int _timerCounter; @@ -609,20 +957,25 @@ private: void generateSamples(int16 *buf, int len); void onTimer(); - void partKeyOn(AdLibPart *part, AdLibInstrument *instr, byte note, byte velocity); + void partKeyOn(AdLibPart *part, const AdLibInstrument *instr, byte note, byte velocity, const AdLibInstrument *second, byte pan); void partKeyOff(AdLibPart *part, byte note); void adlibKeyOff(int chan); void adlibNoteOn(int chan, byte note, int mod); void adlibNoteOnEx(int chan, byte note, int mod); int adlibGetRegValueParam(int chan, byte data); - void adlibSetupChannel(int chan, AdLibInstrument *instr, byte vol1, byte vol2); + void adlibSetupChannel(int chan, const AdLibInstrument *instr, byte vol1, byte vol2); + void adlibSetupChannelSecondary(int chan, const AdLibInstrument *instr, byte vol1, byte vol2, byte pan); byte adlibGetRegValue(byte reg) { return _regCache[reg]; } - void adlibSetParam(int channel, byte param, int value); + byte adlibGetRegValueSecondary(byte reg) { + return _regCacheSecondary[reg]; + } + void adlibSetParam(int channel, byte param, int value, bool primary = true); void adlibKeyOnOff(int channel); void adlibWrite(byte reg, byte value); + void adlibWriteSecondary(byte reg, byte value); void adlibPlayNote(int channel, int note); AdLibVoice *allocateVoice(byte pri); @@ -632,13 +985,13 @@ private: static void linkMc(AdLibPart *part, AdLibVoice *voice); void mcIncStuff(AdLibVoice *voice, Struct10 *s10, Struct11 *s11); void mcInitStuff(AdLibVoice *voice, Struct10 *s10, Struct11 *s11, byte flags, - InstrumentExtra *ie); + const InstrumentExtra *ie); - void struct10Init(Struct10 *s10, InstrumentExtra *ie); + void struct10Init(Struct10 *s10, const InstrumentExtra *ie); static byte struct10OnTimer(Struct10 *s10, Struct11 *s11); static void struct10Setup(Struct10 *s10); static int randomNr(int a); - void mcKeyOn(AdLibVoice *voice, AdLibInstrument *instr, byte note, byte velocity); + void mcKeyOn(AdLibVoice *voice, const AdLibInstrument *instr, byte note, byte velocity, const AdLibInstrument *second, byte pan); }; // MidiChannel method implementations @@ -669,7 +1022,7 @@ void AdLibPart::noteOn(byte note, byte velocity) { #ifdef DEBUG_ADLIB debug(6, "%10d: noteOn(%d,%d)", g_tick, note, velocity); #endif - _owner->partKeyOn(this, &_partInstr, note, velocity); + _owner->partKeyOn(this, &_partInstr, note, velocity, &_partInstrSecondary, _pan); } void AdLibPart::programChange(byte program) { @@ -685,7 +1038,12 @@ void AdLibPart::programChange(byte program) { warning("No AdLib instrument defined for GM program %d", (int)program); */ _program = program; - memcpy(&_partInstr, &g_gmInstruments[program], sizeof(AdLibInstrument)); + if (!_owner->_opl3Mode) { + memcpy(&_partInstr, &g_gmInstruments[program], sizeof(AdLibInstrument)); + } else { + memcpy(&_partInstr, &g_gmInstrumentsOPL3[program][0], sizeof(AdLibInstrument)); + memcpy(&_partInstrSecondary, &g_gmInstrumentsOPL3[program][1], sizeof(AdLibInstrument)); + } } void AdLibPart::pitchBend(int16 bend) { @@ -693,8 +1051,12 @@ void AdLibPart::pitchBend(int16 bend) { _pitchBend = bend; for (voice = _voice; voice; voice = voice->_next) { - _owner->adlibNoteOn(voice->_channel, voice->_note/* + _transposeEff*/, - (_pitchBend * _pitchBendFactor >> 6) + _detuneEff); + if (!_owner->_opl3Mode) { + _owner->adlibNoteOn(voice->_channel, voice->_note/* + _transposeEff*/, + (_pitchBend * _pitchBendFactor >> 6) + _detuneEff); + } else { + _owner->adlibNoteOn(voice->_channel, voice->_note, _pitchBend >> 1); + } } } @@ -711,7 +1073,7 @@ void AdLibPart::controlChange(byte control, byte value) { volume(value); break; case 10: - // Pan position. Not supported. + panPosition(value); break; case 16: pitchBendFactor(value); @@ -766,14 +1128,34 @@ void AdLibPart::volume(byte value) { _volEff = value; for (voice = _voice; voice; voice = voice->_next) { - _owner->adlibSetParam(voice->_channel, 0, g_volumeTable[g_volumeLookupTable[voice->_vol2][_volEff >> 2]]); - if (voice->_twoChan) { - _owner->adlibSetParam(voice->_channel, 13, g_volumeTable[g_volumeLookupTable[voice->_vol1][_volEff >> 2]]); + if (!_owner->_opl3Mode) { + _owner->adlibSetParam(voice->_channel, 0, g_volumeTable[g_volumeLookupTable[voice->_vol2][_volEff >> 2]]); + if (voice->_twoChan) { + _owner->adlibSetParam(voice->_channel, 13, g_volumeTable[g_volumeLookupTable[voice->_vol1][_volEff >> 2]]); + } + } else { + _owner->adlibSetParam(voice->_channel, 0, g_volumeTable[((voice->_vol2 + 1) * _volEff) >> 7], true); + _owner->adlibSetParam(voice->_channel, 0, g_volumeTable[((voice->_secVol2 + 1) * _volEff) >> 7], false); + if (voice->_twoChan) { + _owner->adlibSetParam(voice->_channel, 13, g_volumeTable[((voice->_vol1 + 1) * _volEff) >> 7], true); + } + if (voice->_secTwoChan) { + _owner->adlibSetParam(voice->_channel, 13, g_volumeTable[((voice->_secVol1 + 1) * _volEff) >> 7], false); + } } } } +void AdLibPart::panPosition(byte value) { + _pan = value; +} + void AdLibPart::pitchBendFactor(byte value) { + // Not supported in OPL3 mode. + if (_owner->_opl3Mode) { + return; + } + AdLibVoice *voice; _pitchBendFactor = value; @@ -784,6 +1166,16 @@ void AdLibPart::pitchBendFactor(byte value) { } void AdLibPart::detune(byte value) { + // Sam&Max's OPL3 driver uses this for a completly different purpose. It + // is related to voice allocation. We ignore this for now. + // TODO: We probably need to look how the interpreter side of Sam&Max's + // iMuse version handles all this too. Implementing the driver side here + // would be not that hard. + if (_owner->_opl3Mode) { + //_maxNotes = value; + return; + } + AdLibVoice *voice; _detuneEff = value; @@ -815,6 +1207,13 @@ void AdLibPart::allNotesOff() { } void AdLibPart::sysEx_customInstrument(uint32 type, const byte *instr) { + // Sam&Max allows for instrument overwrites, but we will not support it + // until we can find any track actually using it. + if (_owner->_opl3Mode) { + warning("AdLibPart::sysEx_customInstrument: Used in OPL3 mode"); + return; + } + if (type == 'ADL ') { memcpy(&_partInstr, instr, sizeof(AdLibInstrument)); } @@ -852,7 +1251,8 @@ void AdLibPercussionChannel::noteOff(byte note) { } void AdLibPercussionChannel::noteOn(byte note, byte velocity) { - AdLibInstrument *inst = NULL; + const AdLibInstrument *inst = NULL; + const AdLibInstrument *sec = NULL; // The custom instruments have priority over the default mapping inst = _customInstruments[note]; @@ -862,8 +1262,14 @@ void AdLibPercussionChannel::noteOn(byte note, byte velocity) { if (!inst) { // Use the default GM to FM mapping as a fallback byte key = g_gmPercussionInstrumentMap[note]; - if (key != 0xFF) - inst = &g_gmPercussionInstruments[key]; + if (key != 0xFF) { + if (!_owner->_opl3Mode) { + inst = &g_gmPercussionInstruments[key]; + } else { + inst = &g_gmPercussionInstrumentsOPL3[key][0]; + sec = &g_gmPercussionInstrumentsOPL3[key][1]; + } + } } if (!inst) { @@ -871,7 +1277,7 @@ void AdLibPercussionChannel::noteOn(byte note, byte velocity) { return; } - _owner->partKeyOn(this, inst, note, velocity); + _owner->partKeyOn(this, inst, note, velocity, sec, _pan); } void AdLibPercussionChannel::sysEx_customInstrument(uint32 type, const byte *instr) { @@ -907,11 +1313,13 @@ MidiDriver_ADLIB::MidiDriver_ADLIB(Audio::Mixer *mixer) uint i; _scummSmallHeader = false; + _opl3Mode = false; _regCache = 0; + _regCacheSecondary = 0; _timerCounter = 0; - _voiceIndex = 0; + _voiceIndex = -1; for (i = 0; i < ARRAYSIZE(_curNotTable); ++i) { _curNotTable[i] = 0; } @@ -922,6 +1330,7 @@ MidiDriver_ADLIB::MidiDriver_ADLIB(Audio::Mixer *mixer) _percussion.init(this, 9); _timerIncrease = 0xD69; _timerThreshold = 0x411B; + _opl = 0; } int MidiDriver_ADLIB::open() { @@ -939,15 +1348,29 @@ int MidiDriver_ADLIB::open() { voice->_s11b.s10 = &voice->_s10a; } - _regCache = (byte *)calloc(256, 1); + // Try to use OPL3 when requested. + if (_opl3Mode) { + _opl = OPL::Config::create(OPL::Config::kOpl3); + } - _opl = OPL::Config::create(); + // Initialize plain OPL2 when no OPL3 is intiailized already. + if (!_opl) { + _opl = OPL::Config::create(); + _opl3Mode = false; + } _opl->init(getRate()); - adlibWrite(1, 0x20); + _regCache = (byte *)calloc(256, 1); + adlibWrite(8, 0x40); adlibWrite(0xBD, 0x00); - createLookupTable(); + if (!_opl3Mode) { + adlibWrite(1, 0x20); + createLookupTable(); + } else { + _regCacheSecondary = (byte *)calloc(256, 1); + adlibWriteSecondary(5, 1); + } _mixer->playStream(Audio::Mixer::kPlainSoundType, &_mixerSoundHandle, this, -1, Audio::Mixer::kMaxChannelVolume, 0, DisposeAfterUse::NO, true); @@ -969,8 +1392,10 @@ void MidiDriver_ADLIB::close() { // Turn off the OPL emulation delete _opl; + _opl = 0; free(_regCache); + free(_regCacheSecondary); } void MidiDriver_ADLIB::send(uint32 b) { @@ -1032,12 +1457,21 @@ uint32 MidiDriver_ADLIB::property(int prop, uint32 param) { _timerThreshold = 0x411B; } return 1; + + case PROP_SCUMM_OPL3: // Sam&Max OPL3 support. + _opl3Mode = (param > 0); + return 1; } return 0; } void MidiDriver_ADLIB::setPitchBendRange(byte channel, uint range) { + // Not supported in OPL3 mode. + if (_opl3Mode) { + return; + } + AdLibVoice *voice; AdLibPart *part = &_parts[channel]; @@ -1069,8 +1503,9 @@ MidiChannel *MidiDriver_ADLIB::allocateChannel() { // All the code brought over from IMuseAdLib void MidiDriver_ADLIB::adlibWrite(byte reg, byte value) { - if (_regCache[reg] == value) + if (_regCache[reg] == value) { return; + } #ifdef DEBUG_ADLIB debug(6, "%10d: adlibWrite[%x] = %x", g_tick, reg, value); #endif @@ -1079,37 +1514,50 @@ void MidiDriver_ADLIB::adlibWrite(byte reg, byte value) { _opl->writeReg(reg, value); } +void MidiDriver_ADLIB::adlibWriteSecondary(byte reg, byte value) { + assert(_opl3Mode); + + if (_regCacheSecondary[reg] == value) { + return; + } +#ifdef DEBUG_ADLIB + debug(6, "%10d: adlibWriteSecondary[%x] = %x", g_tick, reg, value); +#endif + _regCacheSecondary[reg] = value; + + _opl->writeReg(reg | 0x100, value); +} + void MidiDriver_ADLIB::generateSamples(int16 *data, int len) { if (_opl->isStereo()) { len *= 2; } - _opl->readBuffer(data, len); } void MidiDriver_ADLIB::onTimer() { - AdLibVoice *voice; - int i; - _timerCounter += _timerIncrease; while (_timerCounter >= _timerThreshold) { _timerCounter -= _timerThreshold; #ifdef DEBUG_ADLIB g_tick++; #endif - voice = _voices; - for (i = 0; i != ARRAYSIZE(_voices); i++, voice++) { - if (!voice->_part) - continue; - if (voice->_duration && (voice->_duration -= 0x11) <= 0) { - mcOff(voice); - return; - } - if (voice->_s10a.active) { - mcIncStuff(voice, &voice->_s10a, &voice->_s11a); - } - if (voice->_s10b.active) { - mcIncStuff(voice, &voice->_s10b, &voice->_s11b); + // Sam&Max's OPL3 driver does not have any timer handling like this. + if (!_opl3Mode) { + AdLibVoice *voice = _voices; + for (int i = 0; i != ARRAYSIZE(_voices); i++, voice++) { + if (!voice->_part) + continue; + if (voice->_duration && (voice->_duration -= 0x11) <= 0) { + mcOff(voice); + return; + } + if (voice->_s10a.active) { + mcIncStuff(voice, &voice->_s10a, &voice->_s11a); + } + if (voice->_s10b.active) { + mcIncStuff(voice, &voice->_s10b, &voice->_s11b); + } } } } @@ -1179,6 +1627,9 @@ void MidiDriver_ADLIB::mcIncStuff(AdLibVoice *voice, Struct10 *s10, Struct11 *s1 void MidiDriver_ADLIB::adlibKeyOff(int chan) { byte reg = chan + 0xB0; adlibWrite(reg, adlibGetRegValue(reg) & ~0x20); + if (_opl3Mode) { + adlibWriteSecondary(reg, adlibGetRegValueSecondary(reg) & ~0x20); + } } byte MidiDriver_ADLIB::struct10OnTimer(Struct10 *s10, Struct11 *s11) { @@ -1224,11 +1675,12 @@ byte MidiDriver_ADLIB::struct10OnTimer(Struct10 *s10, Struct11 *s11) { return result; } -void MidiDriver_ADLIB::adlibSetParam(int channel, byte param, int value) { +void MidiDriver_ADLIB::adlibSetParam(int channel, byte param, int value, bool primary) { const AdLibSetParams *as; byte reg; assert(channel >= 0 && channel < 9); + assert(!_opl3Mode || (param == 0 || param == 13)); if (param <= 12) { reg = g_operator2Offsets[channel]; @@ -1255,10 +1707,16 @@ void MidiDriver_ADLIB::adlibSetParam(int channel, byte param, int value) { if (as->inversion) value = as->inversion - value; reg += as->registerBase; - adlibWrite(reg, (adlibGetRegValue(reg) & ~as->mask) | (((byte)value) << as->shift)); + if (primary) { + adlibWrite(reg, (adlibGetRegValue(reg) & ~as->mask) | (((byte)value) << as->shift)); + } else { + adlibWriteSecondary(reg, (adlibGetRegValueSecondary(reg) & ~as->mask) | (((byte)value) << as->shift)); + } } void MidiDriver_ADLIB::adlibKeyOnOff(int channel) { + assert(!_opl3Mode); + byte val; byte reg = channel + 0xB0; assert(channel >= 0 && channel < 9); @@ -1377,7 +1835,7 @@ void MidiDriver_ADLIB::partKeyOff(AdLibPart *part, byte note) { } } -void MidiDriver_ADLIB::partKeyOn(AdLibPart *part, AdLibInstrument *instr, byte note, byte velocity) { +void MidiDriver_ADLIB::partKeyOn(AdLibPart *part, const AdLibInstrument *instr, byte note, byte velocity, const AdLibInstrument *second, byte pan) { AdLibVoice *voice; voice = allocateVoice(part->_priEff); @@ -1385,7 +1843,7 @@ void MidiDriver_ADLIB::partKeyOn(AdLibPart *part, AdLibInstrument *instr, byte n return; linkMc(part, voice); - mcKeyOn(voice, instr, note, velocity); + mcKeyOn(voice, instr, note, velocity, second, pan); } AdLibVoice *MidiDriver_ADLIB::allocateVoice(byte pri) { @@ -1425,10 +1883,10 @@ void MidiDriver_ADLIB::linkMc(AdLibPart *part, AdLibVoice *voice) { voice->_next->_prev = voice; } -void MidiDriver_ADLIB::mcKeyOn(AdLibVoice *voice, AdLibInstrument *instr, byte note, byte velocity) { +void MidiDriver_ADLIB::mcKeyOn(AdLibVoice *voice, const AdLibInstrument *instr, byte note, byte velocity, const AdLibInstrument *second, byte pan) { AdLibPart *part = voice->_part; - int c; byte vol1, vol2; + byte secVol1, secVol2; voice->_twoChan = instr->feedback & 1; voice->_note = note; @@ -1437,52 +1895,81 @@ void MidiDriver_ADLIB::mcKeyOn(AdLibVoice *voice, AdLibInstrument *instr, byte n if (voice->_duration != 0) voice->_duration *= 63; - if (!_scummSmallHeader) + if (!_opl3Mode) vol1 = (instr->modScalingOutputLevel & 0x3F) + g_volumeLookupTable[velocity >> 1][instr->modWaveformSelect >> 2]; + else if (!_scummSmallHeader) + vol1 = (instr->modScalingOutputLevel & 0x3F) + (velocity * ((instr->modWaveformSelect >> 3) + 1)) / 64; else vol1 = 0x3f - (instr->modScalingOutputLevel & 0x3F); if (vol1 > 0x3F) vol1 = 0x3F; voice->_vol1 = vol1; - if (!_scummSmallHeader) + if (!_opl3Mode) vol2 = (instr->carScalingOutputLevel & 0x3F) + g_volumeLookupTable[velocity >> 1][instr->carWaveformSelect >> 2]; + else if (!_scummSmallHeader) + vol2 = (instr->carScalingOutputLevel & 0x3F) + (velocity * ((instr->carWaveformSelect >> 3) + 1)) / 64; else vol2 = 0x3f - (instr->carScalingOutputLevel & 0x3F); if (vol2 > 0x3F) vol2 = 0x3F; voice->_vol2 = vol2; - c = part->_volEff >> 2; + if (_opl3Mode) { + voice->_secTwoChan = second->feedback & 1; + secVol1 = (second->modScalingOutputLevel & 0x3F) + (velocity * ((second->modWaveformSelect >> 3) + 1)) / 64; + if (secVol1 > 0x3F) { + secVol1 = 0x3F; + } + voice->_secVol1 = secVol1; + secVol2 = (second->carScalingOutputLevel & 0x3F) + (velocity * ((second->carWaveformSelect >> 3) + 1)) / 64; + if (secVol2 > 0x3F) { + secVol2 = 0x3F; + } + voice->_secVol2 = secVol2; + } if (!_scummSmallHeader) { - vol2 = g_volumeTable[g_volumeLookupTable[vol2][c]]; - if (voice->_twoChan) - vol1 = g_volumeTable[g_volumeLookupTable[vol1][c]]; + if (!_opl3Mode) { + int c = part->_volEff >> 2; + vol2 = g_volumeTable[g_volumeLookupTable[vol2][c]]; + if (voice->_twoChan) + vol1 = g_volumeTable[g_volumeLookupTable[vol1][c]]; + } else { + vol2 = g_volumeTable[((vol2 + 1) * part->_volEff) >> 7]; + secVol2 = g_volumeTable[((secVol2 + 1) * part->_volEff) >> 7]; + if (voice->_twoChan) + vol1 = g_volumeTable[((vol1 + 1) * part->_volEff) >> 7]; + if (voice->_secTwoChan) + secVol1 = g_volumeTable[((secVol1 + 1) * part->_volEff) >> 7]; + } } adlibSetupChannel(voice->_channel, instr, vol1, vol2); - adlibNoteOnEx(voice->_channel, /*part->_transposeEff + */note, part->_detuneEff + (part->_pitchBend * part->_pitchBendFactor >> 6)); + if (!_opl3Mode) { + adlibNoteOnEx(voice->_channel, /*part->_transposeEff + */note, part->_detuneEff + (part->_pitchBend * part->_pitchBendFactor >> 6)); - if (instr->flagsA & 0x80) { - mcInitStuff(voice, &voice->_s10a, &voice->_s11a, instr->flagsA, &instr->extraA); - } else { - voice->_s10a.active = 0; - } + if (instr->flagsA & 0x80) { + mcInitStuff(voice, &voice->_s10a, &voice->_s11a, instr->flagsA, &instr->extraA); + } else { + voice->_s10a.active = 0; + } - if (instr->flagsB & 0x80) { - mcInitStuff(voice, &voice->_s10b, &voice->_s11b, instr->flagsB, &instr->extraB); + if (instr->flagsB & 0x80) { + mcInitStuff(voice, &voice->_s10b, &voice->_s11b, instr->flagsB, &instr->extraB); + } else { + voice->_s10b.active = 0; + } } else { - voice->_s10b.active = 0; + adlibSetupChannelSecondary(voice->_channel, second, secVol1, secVol2, pan); + adlibNoteOnEx(voice->_channel, note, part->_pitchBend >> 1); } } -void MidiDriver_ADLIB::adlibSetupChannel(int chan, AdLibInstrument *instr, byte vol1, byte vol2) { - byte channel; - +void MidiDriver_ADLIB::adlibSetupChannel(int chan, const AdLibInstrument *instr, byte vol1, byte vol2) { assert(chan >= 0 && chan < 9); - channel = g_operator1Offsets[chan]; + byte channel = g_operator1Offsets[chan]; adlibWrite(channel + 0x20, instr->modCharacteristic); adlibWrite(channel + 0x40, (instr->modScalingOutputLevel | 0x3F) - vol1); adlibWrite(channel + 0x60, 0xff & (~instr->modAttackDecay)); @@ -1496,20 +1983,40 @@ void MidiDriver_ADLIB::adlibSetupChannel(int chan, AdLibInstrument *instr, byte adlibWrite(channel + 0x80, 0xff & (~instr->carSustainRelease)); adlibWrite(channel + 0xE0, instr->carWaveformSelect); - adlibWrite((byte)chan + 0xC0, instr->feedback); + adlibWrite((byte)chan + 0xC0, instr->feedback | (_opl3Mode ? 0x30 : 0)); } -void MidiDriver_ADLIB::adlibNoteOnEx(int chan, byte note, int mod) { - int code; +void MidiDriver_ADLIB::adlibSetupChannelSecondary(int chan, const AdLibInstrument *instr, byte vol1, byte vol2, byte pan) { assert(chan >= 0 && chan < 9); - code = (note << 7) + mod; - _curNotTable[chan] = code; - _channelTable2[chan] = 0; - adlibPlayNote(chan, code); + assert(_opl3Mode); + + byte channel = g_operator1Offsets[chan]; + adlibWriteSecondary(channel + 0x20, instr->modCharacteristic); + adlibWriteSecondary(channel + 0x40, (instr->modScalingOutputLevel | 0x3F) - vol1); + adlibWriteSecondary(channel + 0x60, 0xff & (~instr->modAttackDecay)); + adlibWriteSecondary(channel + 0x80, 0xff & (~instr->modSustainRelease)); + adlibWriteSecondary(channel + 0xE0, instr->modWaveformSelect); + + channel = g_operator2Offsets[chan]; + adlibWriteSecondary(channel + 0x20, instr->carCharacteristic); + adlibWriteSecondary(channel + 0x40, (instr->carScalingOutputLevel | 0x3F) - vol2); + adlibWriteSecondary(channel + 0x60, 0xff & (~instr->carAttackDecay)); + adlibWriteSecondary(channel + 0x80, 0xff & (~instr->carSustainRelease)); + adlibWriteSecondary(channel + 0xE0, instr->carWaveformSelect); + + // The original uses the following (strange) behavior: +#if 0 + if (instr->feedback | (pan > 64)) { + adlibWriteSecondary((byte)chan + 0xC0, 0x10); + } else { + adlibWriteSecondary((byte)chan + 0xC0, 0x20); + } +#endif + adlibWriteSecondary((byte)chan + 0xC0, instr->feedback | ((pan > 64) ? 0x20 : 0x10)); } void MidiDriver_ADLIB::mcInitStuff(AdLibVoice *voice, Struct10 *s10, - Struct11 *s11, byte flags, InstrumentExtra *ie) { + Struct11 *s11, byte flags, const InstrumentExtra *ie) { AdLibPart *part = voice->_part; s11->modifyVal = 0; s11->flag0x40 = flags & 0x40; @@ -1546,7 +2053,7 @@ void MidiDriver_ADLIB::mcInitStuff(AdLibVoice *voice, Struct10 *s10, struct10Init(s10, ie); } -void MidiDriver_ADLIB::struct10Init(Struct10 *s10, InstrumentExtra *ie) { +void MidiDriver_ADLIB::struct10Init(Struct10 *s10, const InstrumentExtra *ie) { s10->active = 1; if (!_scummSmallHeader) { s10->curVal = 0; @@ -1605,13 +2112,35 @@ int MidiDriver_ADLIB::adlibGetRegValueParam(int chan, byte param) { } void MidiDriver_ADLIB::adlibNoteOn(int chan, byte note, int mod) { - int code; + if (_opl3Mode) { + adlibNoteOnEx(chan, note, mod); + return; + } + assert(chan >= 0 && chan < 9); - code = (note << 7) + mod; + int code = (note << 7) + mod; _curNotTable[chan] = code; adlibPlayNote(chan, (int16)_channelTable2[chan] + code); } +void MidiDriver_ADLIB::adlibNoteOnEx(int chan, byte note, int mod) { + assert(chan >= 0 && chan < 9); + + if (_opl3Mode) { + const int noteAdjusted = note + (mod >> 8) - 7; + const int pitchAdjust = (mod >> 5) & 7; + + adlibWrite(0xA0 + chan, g_noteFrequencies[(noteAdjusted % 12) * 8 + pitchAdjust + 6 * 8]); + adlibWriteSecondary(0xA0 + chan, g_noteFrequencies[(noteAdjusted % 12) * 8 + pitchAdjust + 6 * 8]); + adlibWrite(0xB0 + chan, (CLIP(noteAdjusted / 12, 0, 7) << 2) | 0x20); + adlibWriteSecondary(0xB0 + chan, (CLIP(noteAdjusted / 12, 0, 7) << 2) | 0x20); + } else { + int code = (note << 7) + mod; + _curNotTable[chan] = code; + _channelTable2[chan] = 0; + adlibPlayNote(chan, code); + } +} // Plugin interface -- cgit v1.2.3