diff options
-rw-r--r-- | engines/kyra/sound_adlib.cpp | 184 |
1 files changed, 70 insertions, 114 deletions
diff --git a/engines/kyra/sound_adlib.cpp b/engines/kyra/sound_adlib.cpp index 91c6356624..fbf1ad5588 100644 --- a/engines/kyra/sound_adlib.cpp +++ b/engines/kyra/sound_adlib.cpp @@ -97,11 +97,11 @@ private: uint8 *dataptr; uint8 unk5; uint8 repeatCounter; - uint8 unk10; + int8 baseOctave; int8 unk2; uint8 dataptrStackPos; uint8 *dataptrStack[4]; - uint8 unk14; + int8 baseNote; uint8 unk29; int8 unk31; uint16 unk30; @@ -115,11 +115,11 @@ private: uint8 unk38; uint8 unk26; uint8 unk7; - uint8 unk15; + int8 baseFreq; int8 unk1; int8 unk4; - uint8 unk17; - uint8 unkOutputValue1; + uint8 regAx; + uint8 regBx; typedef void (AdlibDriver::*Callback)(OutputState&); Callback callback1; Callback callback2; @@ -139,7 +139,7 @@ private: uint8 unk22; uint16 offset; uint8 unk6; - uint8 unk13; + uint8 rawNote; int8 unk16; }; @@ -191,19 +191,19 @@ private: int update_jump(uint8 *&dataptr, OutputState &state, uint8 value); int update_jumpToSubroutine(uint8 *&dataptr, OutputState &state, uint8 value); int update_returnFromSubroutine(uint8 *&dataptr, OutputState &state, uint8 value); - int updateCallback8(uint8 *&dataptr, OutputState &state, uint8 value); + int update_setBaseOctave(uint8 *&dataptr, OutputState &state, uint8 value); int updateCallback9(uint8 *&dataptr, OutputState &state, uint8 value); int updateCallback10(uint8 *&dataptr, OutputState &state, uint8 value); int update_writeAdlib(uint8 *&dataptr, OutputState &state, uint8 value); int updateCallback12(uint8 *&dataptr, OutputState &state, uint8 value); - int updateCallback13(uint8 *&dataptr, OutputState &state, uint8 value); + int update_setBaseNote(uint8 *&dataptr, OutputState &state, uint8 value); int updateCallback14(uint8 *&dataptr, OutputState &state, uint8 value); int updateCallback15(uint8 *&dataptr, OutputState &state, uint8 value); int updateCallback16(uint8 *&dataptr, OutputState &state, uint8 value); int updateCallback17(uint8 *&dataptr, OutputState &state, uint8 value); int updateCallback18(uint8 *&dataptr, OutputState &state, uint8 value); int updateCallback19(uint8 *&dataptr, OutputState &state, uint8 value); - int updateCallback20(uint8 *&dataptr, OutputState &state, uint8 value); + int update_setBaseFreq(uint8 *&dataptr, OutputState &state, uint8 value); int updateCallback21(uint8 *&dataptr, OutputState &state, uint8 value); int updateCallback22(uint8 *&dataptr, OutputState &state, uint8 value); int updateCallback23(uint8 *&dataptr, OutputState &state, uint8 value); @@ -660,10 +660,10 @@ void AdlibDriver::noteOff(OutputState &table) { return; // This means the "Key On" bit will always be 0 - table.unkOutputValue1 &= 0xDF; + table.regBx &= 0xDF; // Octave / F-Number / Key-On - writeOPL(0xB0 + _curTable, table.unkOutputValue1); + writeOPL(0xB0 + _curTable, table.regBx); } void AdlibDriver::unkOutput2(uint8 num) { @@ -717,45 +717,45 @@ void AdlibDriver::update1(uint8 unk1, OutputState &state) { state.unk5 = unk1; } -void AdlibDriver::updateAndOutput1(uint8 unk1, OutputState &state) { - debugC(9, kDebugLevelSound, "updateAndOutput1(%d, %d)", unk1, &state - _outputTables); - state.unk13 = unk1; - uint8 unk2 = unk1 & 0xF0; - unk2 += state.unk10; - unk1 &= 0x0F; - unk1 += state.unk14; - - if ((int8)unk1 >= 0x0C) { - unk1 -= 0x0C; - unk2 += 0x10; - } else if ((int8)unk1 < 0) { - unk1 += 0x0C; - unk2 -= 0x10; +void AdlibDriver::updateAndOutput1(uint8 rawNote, OutputState &state) { + debugC(9, kDebugLevelSound, "updateAndOutput1(%d, %d)", rawNote, &state - _outputTables); + + state.rawNote = rawNote; + + int8 note = (rawNote & 0x0F) + state.baseNote; + int8 octave = ((rawNote >> 4) & 0x0F) + state.baseOctave; + + // There are only twelve notes. If we go outside that, we have to + // adjust the note and octave. + + if (note >= 12) { + note -= 12; + octave++; + } else if (note < 0) { + note += 12; + octave--; } - uint16 value = _unkTable[unk1] + state.unk15; + uint16 freq = _unkTable[note] + state.baseFreq; - unk2 >>= 2; - unk2 &= 0x1C; - unk2 |= (value & 0xFF00) >> 8; - value = (value & 0xFF) | (unk2 << 8); + if (state.unk16) { + const uint8 *table; - if (state.unk16 != 0) { if (state.unk16 > 0) { - const uint8 *table = _unkTables[(state.unk13 & 0x0F) + 2]; - value += table[state.unk16]; + table = _unkTables[(state.rawNote & 0x0F) + 2]; + freq += table[state.unk16]; } else { - const uint8 *table = _unkTables[state.unk13 & 0x0F]; - value -= table[(state.unk16 ^ 0xFF) + 1]; + table = _unkTables[state.rawNote & 0x0F]; + freq -= table[-state.unk16]; } } - state.unkOutputValue1 = (state.unkOutputValue1 & 0x20) | ((value & 0xFF00) >> 8); - state.unk17 = value & 0xFF; + state.regAx = freq & 0xFF; + state.regBx = (state.regBx & 0x20) | (octave << 2) | ((freq >> 8) & 0x03); - // Octave / F-Number / Key-On - writeOPL(0xA0 + _curTable, state.unk17); - writeOPL(0xB0 + _curTable, state.unkOutputValue1); + // Keep the note on or off + writeOPL(0xA0 + _curTable, state.regAx); + writeOPL(0xB0 + _curTable, state.regBx); } void AdlibDriver::updateAndOutput2(uint8 unk1, uint8 *dataptr, OutputState &state) { @@ -795,13 +795,13 @@ void AdlibDriver::updateAndOutput2(uint8 unk1, uint8 *dataptr, OutputState &stat void AdlibDriver::updateAndOutput3(OutputState &state) { debugC(9, kDebugLevelSound, "updateAndOutput3(%d)", &state - _outputTables); // This sets the "note on" bit. - state.unkOutputValue1 |= 0x20; + state.regBx |= 0x20; // Octave / F-Number / Key-On - writeOPL(0xB0 + _curTable, state.unkOutputValue1); + writeOPL(0xB0 + _curTable, state.regBx); int8 shift = 9 - state.unk33; - uint16 temp = state.unk17 | (state.unkOutputValue1 << 8); + uint16 temp = state.regAx | (state.regBx << 8); state.unk37 = ((temp & 0x3FF) >> shift) & 0xFF; state.unk38 = state.unk36; } @@ -825,8 +825,8 @@ void AdlibDriver::stateCallback1_1(OutputState &state) { state.unk31 += state.unk29; if ((int8)state.unk31 >= 0) return; - uint16 unk1 = ((state.unkOutputValue1 & 3) << 8) | state.unk17; - uint16 unk2 = ((state.unkOutputValue1 & 0x20) << 8) | (state.unkOutputValue1 & 0x1C); + uint16 unk1 = ((state.regBx & 3) << 8) | state.regAx; + uint16 unk2 = ((state.regBx & 0x20) << 8) | (state.regBx & 0x1C); int16 unk3 = (int16)state.unk30; if (unk3 >= 0) { @@ -851,14 +851,14 @@ void AdlibDriver::stateCallback1_1(OutputState &state) { unk1 &= 0x3FF; writeOPL(0xA0 + _curTable, unk1 & 0xFF); - state.unk17 = unk1 & 0xFF; + state.regAx = unk1 & 0xFF; uint8 value = unk1 >> 8; value |= (unk2 >> 8) & 0xFF; value |= unk2 & 0xFF; writeOPL(0xB0 + _curTable, value); - state.unkOutputValue1 = value; + state.regBx = value; } void AdlibDriver::stateCallback1_2(OutputState &state) { @@ -878,15 +878,15 @@ void AdlibDriver::stateCallback1_2(OutputState &state) { state.unk34 = state.unk35; } - uint16 temp3 = state.unk17 | (state.unkOutputValue1 << 8); + uint16 temp3 = state.regAx | (state.regBx << 8); temp2 += temp3 & 0x3FF; - state.unk17 = temp2 & 0xFF; + state.regAx = temp2 & 0xFF; - state.unkOutputValue1 = (state.unkOutputValue1 & 0xFC) | (temp3 >> 8); + state.regBx = (state.regBx & 0xFC) | (temp3 >> 8); // Octave / F-Number / Key-On - writeOPL(0xA0 + _curTable, state.unkOutputValue1); - writeOPL(0xB0 + _curTable, state.unkOutputValue1); + writeOPL(0xA0 + _curTable, state.regBx); + writeOPL(0xB0 + _curTable, state.regBx); } } @@ -995,8 +995,8 @@ int AdlibDriver::update_returnFromSubroutine(uint8 *&dataptr, OutputState &state return 0; } -int AdlibDriver::updateCallback8(uint8 *&dataptr, OutputState &state, uint8 value) { - state.unk10 = value; +int AdlibDriver::update_setBaseOctave(uint8 *&dataptr, OutputState &state, uint8 value) { + state.baseOctave = value; return 0; } @@ -1027,8 +1027,8 @@ int AdlibDriver::updateCallback12(uint8 *&dataptr, OutputState &state, uint8 val return (_continueFlag != 0); } -int AdlibDriver::updateCallback13(uint8 *&dataptr, OutputState &state, uint8 value) { - state.unk14 = value; +int AdlibDriver::update_setBaseNote(uint8 *&dataptr, OutputState &state, uint8 value) { + state.baseNote = value; return 0; } @@ -1083,8 +1083,8 @@ int AdlibDriver::updateCallback19(uint8 *&dataptr, OutputState &state, uint8 val return 0; } -int AdlibDriver::updateCallback20(uint8 *&dataptr, OutputState &state, uint8 value) { - state.unk15 = value; +int AdlibDriver::update_setBaseFreq(uint8 *&dataptr, OutputState &state, uint8 value) { + state.baseFreq = value; return 0; } @@ -1258,9 +1258,9 @@ int AdlibDriver::updateCallback39(uint8 *&dataptr, OutputState &state, uint8 val unk |= value << 8; unk &= getRandomNr(); - uint16 unk2 = ((state.unkOutputValue1 & 0x1F) << 8) | state.unk17; + uint16 unk2 = ((state.regBx & 0x1F) << 8) | state.regAx; unk2 += unk; - unk2 |= ((state.unkOutputValue1 & 0x20) << 8); + unk2 |= ((state.regBx & 0x20) << 8); // Frequency writeOPL(0xA0 + _curTable, unk2 & 0xFF); @@ -1279,47 +1279,7 @@ int AdlibDriver::updateCallback40(uint8 *&dataptr, OutputState &state, uint8 val int AdlibDriver::updateCallback41(uint8 *&dataptr, OutputState &state, uint8 value) { state.unk16 = value; - int8 unk1 = 0, unk2 = 0; - - unk1 = state.unk13 & 0xF0; - unk1 += state.unk10; - - unk2 = state.unk13 & 0x0F; - unk2 += state.unk14; - - if (unk2 >= 12) { - unk2 -= 12; - unk1 += 16; - } else if (unk2 < 0) { - unk2 += 12; - unk1 -= 16; - } - - uint16 unk3 = _unkTable[unk2] + state.unk15; - unk1 >>= 2; unk1 &= 0x1C; - unk1 |= (unk3 >> 8); - - uint16 unk4 = (unk1 << 8) | (unk3 & 0xFF); - if (state.unk16 >= 0) { - const uint8 *ptr = _unkTables[(state.unk13 & 0x0F) + 2]; - unk4 += ptr[state.unk16]; - } else { - const uint8 *ptr = _unkTables[state.unk13 & 0x0F]; - unk4 -= ptr[(state.unk16 ^ 0xFF) + 1]; - } - - unk2 = unk4 >> 8; - unk1 = unk4 & 0xFF; - - state.unkOutputValue1 = unk2 | (state.unkOutputValue1 & 0x20); - state.unk17 = unk1; - - // Frequency - writeOPL(0xA0 + _curTable, unk1); - - // Key On / Octave / Frequency - writeOPL(0xB0 + _curTable, state.unkOutputValue1); - + updateAndOutput1(state.rawNote, state); return 0; } @@ -1404,16 +1364,16 @@ int AdlibDriver::updateCallback48(uint8 *&dataptr, OutputState &state, uint8 val // Octave / F-Number / Key-On for channels 6, 7 and 8 - _outputTables[6].unkOutputValue1 = *dataptr++ & 0x2F; - writeOPL(0xB6, _outputTables[6].unkOutputValue1); + _outputTables[6].regBx = *dataptr++ & 0x2F; + writeOPL(0xB6, _outputTables[6].regBx); writeOPL(0xA6, *dataptr++); - _outputTables[7].unkOutputValue1 = *dataptr++ & 0x2F; - writeOPL(0xB7, _outputTables[7].unkOutputValue1); + _outputTables[7].regBx = *dataptr++ & 0x2F; + writeOPL(0xB7, _outputTables[7].regBx); writeOPL(0xA7, *dataptr++); - _outputTables[8].unkOutputValue1 = *dataptr++ & 0x2F; - writeOPL(0xB8, _outputTables[8].unkOutputValue1); + _outputTables[8].regBx = *dataptr++ & 0x2F; + writeOPL(0xB8, _outputTables[8].regBx); writeOPL(0xA8, *dataptr++); _unk4 = 0x20; @@ -1680,7 +1640,7 @@ const AdlibDriver::ParserOpcode AdlibDriver::_parserOpcodeTable[] = { COMMAND(update_jump), COMMAND(update_jumpToSubroutine), COMMAND(update_returnFromSubroutine), - COMMAND(updateCallback8), + COMMAND(update_setBaseOctave), // 8 COMMAND(updateCallback9), @@ -1689,7 +1649,7 @@ const AdlibDriver::ParserOpcode AdlibDriver::_parserOpcodeTable[] = { COMMAND(updateCallback12), // 12 - COMMAND(updateCallback13), + COMMAND(update_setBaseNote), COMMAND(updateCallback14), COMMAND(updateCallback15), COMMAND(updateCallback16), @@ -1698,7 +1658,7 @@ const AdlibDriver::ParserOpcode AdlibDriver::_parserOpcodeTable[] = { COMMAND(updateCallback17), COMMAND(updateCallback18), COMMAND(updateCallback19), - COMMAND(updateCallback20), + COMMAND(update_setBaseFreq), // 20 COMMAND(updateCallback9), @@ -1799,10 +1759,6 @@ const uint8 AdlibDriver::_outputTable[] = { // Given the size of this table, and the range of its values, it's probably the // F-Numbers (10 bits) for the notes of the 12-tone scale. However, it does not // match the table in the Adlib documentation I've seen. -// -// The values from this table is always added to state.unk15, which could make -// unk15 a pitch bend factor of some kind, and updateCallback20() would then -// be update_setPitchBend(). const uint16 AdlibDriver::_unkTable[] = { 0x0134, 0x0147, 0x015A, 0x016F, 0x0184, 0x019C, 0x01B4, 0x01CE, 0x01E9, |