diff --git a/src/engine/platform/genesis.cpp b/src/engine/platform/genesis.cpp index 7abfb41a..85074228 100644 --- a/src/engine/platform/genesis.cpp +++ b/src/engine/platform/genesis.cpp @@ -285,7 +285,7 @@ void DivPlatformGenesis::tick(bool sysTick) { chan[i].freqChanged=true; } } else { - if (chan[i].std.arp.had) { + if (chan[i].std.arp.had) { if (!chan[i].inPorta) { chan[i].baseFreq=NOTE_FNUM_BLOCK(parent->calcArp(chan[i].note,chan[i].std.arp.val),11); } diff --git a/src/engine/platform/genesisext.cpp b/src/engine/platform/genesisext.cpp index a1108e41..6e7897a0 100644 --- a/src/engine/platform/genesisext.cpp +++ b/src/engine/platform/genesisext.cpp @@ -52,6 +52,15 @@ int DivPlatformGenesisExt::dispatch(DivCommand c) { chan[2].state.ams=ins->fm.ams; chan[2].state.op[ordch]=ins->fm.op[ordch]; } + + if (noExtMacros) { + opChan[ch].macroInit(NULL); + } else { + opChan[ch].macroInit(ins); + } + if (!opChan[ch].std.vol.will) { + opChan[ch].outVol=opChan[ch].vol; + } unsigned short baseAddr=chanOffs[2]|opOffs[ordch]; DivInstrumentFM::Operator& op=chan[2].state.op[ordch]; @@ -60,7 +69,7 @@ int DivPlatformGenesisExt::dispatch(DivCommand c) { rWrite(baseAddr+0x40,127); } else { if (opChan[ch].insChanged) { - rWrite(baseAddr+0x40,127-VOL_SCALE_LOG_BROKEN(127-op.tl,opChan[ch].vol&0x7f,127)); + rWrite(baseAddr+0x40,127-VOL_SCALE_LOG_BROKEN(127-op.tl,opChan[ch].outVol&0x7f,127)); } } if (opChan[ch].insChanged) { @@ -81,6 +90,7 @@ int DivPlatformGenesisExt::dispatch(DivCommand c) { if (c.value!=DIV_NOTE_NULL) { opChan[ch].baseFreq=NOTE_FNUM_BLOCK(c.value,11); opChan[ch].portaPause=false; + opChan[ch].note=c.value; opChan[ch].freqChanged=true; } opChan[ch].keyOn=true; @@ -94,12 +104,15 @@ int DivPlatformGenesisExt::dispatch(DivCommand c) { break; case DIV_CMD_VOLUME: { opChan[ch].vol=c.value; + if (!opChan[ch].std.vol.has) { + opChan[ch].outVol=c.value; + } unsigned short baseAddr=chanOffs[2]|opOffs[ordch]; DivInstrumentFM::Operator& op=chan[2].state.op[ordch]; if (isOpMuted[ch]) { rWrite(baseAddr+0x40,127); } else { - rWrite(baseAddr+0x40,127-VOL_SCALE_LOG_BROKEN(127-op.tl,opChan[ch].vol&0x7f,127)); + rWrite(baseAddr+0x40,127-VOL_SCALE_LOG_BROKEN(127-op.tl,opChan[ch].outVol&0x7f,127)); } break; } @@ -210,7 +223,7 @@ int DivPlatformGenesisExt::dispatch(DivCommand c) { if (isOpMuted[ch]) { rWrite(baseAddr+0x40,127); } else if (KVS(2,c.value)) { - rWrite(baseAddr+0x40,127-VOL_SCALE_LOG_BROKEN(127-op.tl,opChan[ch].vol&0x7f,127)); + rWrite(baseAddr+0x40,127-VOL_SCALE_LOG_BROKEN(127-op.tl,opChan[ch].outVol&0x7f,127)); } else { rWrite(baseAddr+0x40,op.tl); } @@ -393,8 +406,8 @@ void DivPlatformGenesisExt::muteChannel(int ch, bool mute) { rWrite(baseAddr+0x40,127); immWrite(baseAddr+0x40,127); } else if (KVS(2,ordch)) { - rWrite(baseAddr+0x40,127-VOL_SCALE_LOG_BROKEN(127-op.tl,opChan[ch-2].vol&0x7f,127)); - immWrite(baseAddr+0x40,127-VOL_SCALE_LOG_BROKEN(127-op.tl,opChan[ch-2].vol&0x7f,127)); + rWrite(baseAddr+0x40,127-VOL_SCALE_LOG_BROKEN(127-op.tl,opChan[ch-2].outVol&0x7f,127)); + immWrite(baseAddr+0x40,127-VOL_SCALE_LOG_BROKEN(127-op.tl,opChan[ch-2].outVol&0x7f,127)); } else { rWrite(baseAddr+0x40,op.tl); immWrite(baseAddr+0x40,op.tl); @@ -440,6 +453,42 @@ void DivPlatformGenesisExt::tick(bool sysTick) { DivPlatformGenesis::tick(sysTick); + if (extMode && !noExtMacros) for (int i=0; i<4; i++) { + opChan[i].std.next(); + + if (opChan[i].std.vol.had) { + opChan[i].outVol=VOL_SCALE_LOG_BROKEN(opChan[i].vol,MIN(127,opChan[i].std.vol.val),127); + unsigned short baseAddr=chanOffs[2]|opOffs[orderedOps[i]]; + DivInstrumentFM::Operator& op=chan[2].state.op[orderedOps[i]]; + if (isOpMuted[i]) { + rWrite(baseAddr+ADDR_TL,127); + } else { + if (KVS(2,i)) { + rWrite(baseAddr+ADDR_TL,127-VOL_SCALE_LOG_BROKEN(127-op.tl,opChan[i].outVol&0x7f,127)); + } else { + rWrite(baseAddr+ADDR_TL,op.tl); + } + } + } + + if (opChan[i].std.arp.had) { + if (!opChan[i].inPorta) { + opChan[i].baseFreq=NOTE_FNUM_BLOCK(parent->calcArp(opChan[i].note,opChan[i].std.arp.val),11); + } + opChan[i].freqChanged=true; + } + + if (opChan[i].std.pitch.had) { + if (opChan[i].std.pitch.mode) { + opChan[i].pitch2+=opChan[i].std.pitch.val; + CLAMP_VAR(opChan[i].pitch2,-32768,32767); + } else { + opChan[i].pitch2=opChan[i].std.pitch.val; + } + opChan[i].freqChanged=true; + } + } + bool writeNoteOn=false; unsigned char writeMask=2; if (extMode) for (int i=0; i<4; i++) { @@ -527,7 +576,7 @@ void DivPlatformGenesisExt::forceIns() { if (isOpMuted[j]) { rWrite(baseAddr+0x40,127); } else if (KVS(i,j)) { - rWrite(baseAddr+0x40,127-VOL_SCALE_LOG_BROKEN(127-op.tl,opChan[j].vol&0x7f,127)); + rWrite(baseAddr+0x40,127-VOL_SCALE_LOG_BROKEN(127-op.tl,opChan[j].outVol&0x7f,127)); } else { rWrite(baseAddr+0x40,op.tl); } @@ -601,6 +650,7 @@ void DivPlatformGenesisExt::reset() { for (int i=0; i<4; i++) { opChan[i]=DivPlatformGenesisExt::OpChannel(); + opChan[i].std.setEngine(parent); opChan[i].vol=127; opChan[i].outVol=127; } diff --git a/src/engine/platform/genesisext.h b/src/engine/platform/genesisext.h index c1550f5b..fb68ecff 100644 --- a/src/engine/platform/genesisext.h +++ b/src/engine/platform/genesisext.h @@ -25,7 +25,7 @@ class DivPlatformGenesisExt: public DivPlatformGenesis { struct OpChannel { DivMacroInt std; unsigned char freqH, freqL; - int freq, baseFreq, pitch, pitch2, portaPauseFreq, ins; + int freq, baseFreq, pitch, pitch2, portaPauseFreq, ins, note; signed char konCycles; bool active, insChanged, freqChanged, keyOn, keyOff, portaPause, inPorta, mask; int vol, outVol; @@ -43,6 +43,7 @@ class DivPlatformGenesisExt: public DivPlatformGenesis { pitch2(0), portaPauseFreq(0), ins(-1), + note(0), active(false), insChanged(true), freqChanged(false),