aboutsummaryrefslogtreecommitdiff
path: root/engines/kyra
diff options
context:
space:
mode:
Diffstat (limited to 'engines/kyra')
-rw-r--r--engines/kyra/sound_adlib.cpp52
1 files changed, 31 insertions, 21 deletions
diff --git a/engines/kyra/sound_adlib.cpp b/engines/kyra/sound_adlib.cpp
index dda58f9353..767d4330a6 100644
--- a/engines/kyra/sound_adlib.cpp
+++ b/engines/kyra/sound_adlib.cpp
@@ -127,7 +127,7 @@ private:
uint8 unk24;
uint8 unk25;
uint8 unk28;
- uint8 unk23;
+ uint8 algorithm;
uint8 unk39;
uint8 unk40;
uint8 unk3;
@@ -157,7 +157,7 @@ private:
void update1(uint8 unk1, OutputState &state);
void updateAndOutput1(uint8 rawNote, OutputState &state, bool flag = false);
- void updateAndOutput2(uint8 unk1, uint8 *dataptr, OutputState &state);
+ void setInstrument(uint8 regOffset, uint8 *dataptr, OutputState &state);
void updateAndOutput3(OutputState &state);
void adjustVolume(OutputState &state);
@@ -771,38 +771,48 @@ void AdlibDriver::updateAndOutput1(uint8 rawNote, OutputState &state, bool flag)
writeOPL(0xB0 + _curTable, state.regBx);
}
-void AdlibDriver::updateAndOutput2(uint8 unk1, uint8 *dataptr, OutputState &state) {
- debugC(9, kDebugLevelSound, "updateAndOutput2(%d, %p, %d)", unk1, (const void *)dataptr, &state - _outputTables);
+void AdlibDriver::setInstrument(uint8 regOffset, uint8 *dataptr, OutputState &state) {
+ debugC(9, kDebugLevelSound, "setInstrument(%d, %p, %d)", regOffset, (const void *)dataptr, &state - _outputTables);
// Amplitude Modulation / Vibrato / Envelope Generator Type /
// Keyboard Scaling Rate / Modulator Frequency Multiple
- writeOPL(0x20 + unk1, *dataptr++);
- writeOPL(0x23 + unk1, *dataptr++);
+ writeOPL(0x20 + regOffset, *dataptr++);
+ writeOPL(0x23 + regOffset, *dataptr++);
uint8 temp = *dataptr++;
// Feedback / Algorithm
+
+ // It is very likely that _curTable really does refer to the same
+ // channel as regOffset, but there's only one Cx register per channel.
+
writeOPL(0xC0 + _curTable, temp);
- state.unk23 = temp & 1;
+ // The algorithm bit. I don't pretend to understand this fully, but
+ // "If set to 0, operator 1 modulates operator 2. In this case,
+ // operator 2 is the only one producing sound. If set to 1, both
+ // operators produce sound directly. Complex sounds are more easily
+ // created if the algorithm is set to 0."
+
+ state.algorithm = temp & 1;
// Waveform Select
- writeOPL(0xE0 + unk1, *dataptr++);
- writeOPL(0xE3 + unk1, *dataptr++);
+ writeOPL(0xE0 + regOffset, *dataptr++);
+ writeOPL(0xE3 + regOffset, *dataptr++);
state.unk24 = *dataptr++;
state.unk25 = *dataptr++;
// Level Key Scaling / Total Level
- writeOPL(0x40 + unk1, calculateLowByte1(state));
- writeOPL(0x43 + unk1, calculateLowByte2(state));
+ writeOPL(0x40 + regOffset, calculateLowByte1(state));
+ writeOPL(0x43 + regOffset, calculateLowByte2(state));
// Attack Rate / Decay Rate
- writeOPL(0x60 + unk1, *dataptr++);
- writeOPL(0x63 + unk1, *dataptr++);
+ writeOPL(0x60 + regOffset, *dataptr++);
+ writeOPL(0x63 + regOffset, *dataptr++);
// Sustain Level / Release Rate
- writeOPL(0x80 + unk1, *dataptr++);
- writeOPL(0x83 + unk1, *dataptr++);
+ writeOPL(0x80 + regOffset, *dataptr++);
+ writeOPL(0x83 + regOffset, *dataptr++);
}
void AdlibDriver::updateAndOutput3(OutputState &state) {
@@ -825,7 +835,7 @@ void AdlibDriver::adjustVolume(OutputState &state) {
// Level Key Scaling / Total Level
writeOPL(0x43 + _outputTable[_curTable], lowByte);
- if (state.unk23) {
+ if (state.algorithm) {
lowByte = calculateLowByte1(state);
// Level Key Scaling / Total Level
@@ -916,7 +926,7 @@ void AdlibDriver::stateCallback2_1(OutputState &state) {
uint8 AdlibDriver::calculateLowByte1(OutputState &state) {
int8 value = state.unk24 & 0x3F;
- if (state.unk23) {
+ if (state.algorithm) {
value += state.unk26;
value += state.unk27;
value += state.unk28;
@@ -1077,7 +1087,7 @@ int AdlibDriver::updateCallback16(uint8 *&dataptr, OutputState &state, uint8 val
int AdlibDriver::updateCallback17(uint8 *&dataptr, OutputState &state, uint8 value) {
uint8 *ptr = _soundData;
ptr += READ_LE_UINT16(_soundData + (value << 1) + 0x1F4);
- updateAndOutput2(_unkOutputByte1, ptr, state);
+ setInstrument(_unkOutputByte1, ptr, state);
return 0;
}
@@ -1353,7 +1363,7 @@ int AdlibDriver::updateCallback48(uint8 *&dataptr, OutputState &state, uint8 val
_unkOutputByte1 = _outputTable[6];
_unkValue6 = *(ptr + 6);
- updateAndOutput2(_unkOutputByte1, ptr, state);
+ setInstrument(_unkOutputByte1, ptr, state);
entry = *dataptr++ << 1;
ptr = _soundData + READ_LE_UINT16(_soundData + entry + 0x1F4);
@@ -1363,7 +1373,7 @@ int AdlibDriver::updateCallback48(uint8 *&dataptr, OutputState &state, uint8 val
_unkValue7 = entry = *(ptr + 5);
_unkValue8 = entry = *(ptr + 6);
- updateAndOutput2(_unkOutputByte1, ptr, state);
+ setInstrument(_unkOutputByte1, ptr, state);
entry = *dataptr++ << 1;
ptr = _soundData + READ_LE_UINT16(_soundData + entry + 0x1F4);
@@ -1373,7 +1383,7 @@ int AdlibDriver::updateCallback48(uint8 *&dataptr, OutputState &state, uint8 val
_unkValue9 = entry = *(ptr + 5);
_unkValue10 = entry = *(ptr + 6);
- updateAndOutput2(_unkOutputByte1, ptr, state);
+ setInstrument(_unkOutputByte1, ptr, state);
// Octave / F-Number / Key-On for channels 6, 7 and 8