From c009cb3536645a9f6bb1d15f0baf6e835cf04a76 Mon Sep 17 00:00:00 2001 From: tildearrow Date: Mon, 22 Aug 2022 15:59:45 -0500 Subject: [PATCH] dev112 - prepare for advanced arp macro this new advanced arp macro offers more flexibility and reduces code duplication it allows you to set each step of the macro to either relative or fixed mode (instead of just one mode for the entire macro) the UI is still a work in progress and doesn't work well this change is big and may break things! further fixes incoming --- papers/format.md | 16 ++++++++++++- src/engine/engine.cpp | 5 ++++ src/engine/engine.h | 7 ++++-- src/engine/fileOps.cpp | 16 +++++++++---- src/engine/instrument.cpp | 15 +++++++++++- src/engine/platform/amiga.cpp | 14 ++--------- src/engine/platform/arcade.cpp | 11 +-------- src/engine/platform/ay.cpp | 11 +-------- src/engine/platform/ay8930.cpp | 11 +-------- src/engine/platform/bubsyswsg.cpp | 11 +-------- src/engine/platform/c64.cpp | 11 +-------- src/engine/platform/fds.cpp | 11 +-------- src/engine/platform/gb.cpp | 19 ++------------- src/engine/platform/genesis.cpp | 22 ++--------------- src/engine/platform/lynx.cpp | 19 +++------------ src/engine/platform/mmc5.cpp | 12 ++-------- src/engine/platform/n163.cpp | 11 +-------- src/engine/platform/namcowsg.cpp | 11 +-------- src/engine/platform/nes.cpp | 17 ++------------ src/engine/platform/opl.cpp | 22 ++--------------- src/engine/platform/opll.cpp | 11 +-------- src/engine/platform/pce.cpp | 22 +++-------------- src/engine/platform/pcmdac.cpp | 11 +-------- src/engine/platform/pcspkr.cpp | 11 +-------- src/engine/platform/pet.cpp | 11 +-------- src/engine/platform/qsound.cpp | 11 +-------- src/engine/platform/rf5c68.cpp | 11 +-------- src/engine/platform/saa.cpp | 11 +-------- src/engine/platform/scc.cpp | 11 +-------- src/engine/platform/segapcm.cpp | 11 +-------- src/engine/platform/sms.cpp | 22 +++++------------ src/engine/platform/su.cpp | 11 +-------- src/engine/platform/swan.cpp | 11 +-------- src/engine/platform/tia.cpp | 10 +++----- src/engine/platform/tx81z.cpp | 11 +-------- src/engine/platform/vera.cpp | 22 ++--------------- src/engine/platform/vic20.cpp | 11 +-------- src/engine/platform/vrc6.cpp | 11 +-------- src/engine/platform/x1_010.cpp | 11 +-------- src/engine/platform/ym2203.cpp | 11 +-------- src/engine/platform/ym2608.cpp | 22 ++--------------- src/engine/platform/ym2610.cpp | 22 ++--------------- src/engine/platform/ym2610b.cpp | 22 ++--------------- src/engine/platform/ymz280b.cpp | 11 +-------- src/engine/platform/zxbeeper.cpp | 11 +-------- src/gui/gui.cpp | 39 +++++++++++++++++++++++-------- src/gui/gui.h | 10 ++++---- src/gui/insEdit.cpp | 21 ++++++++++++++--- 48 files changed, 164 insertions(+), 518 deletions(-) diff --git a/papers/format.md b/papers/format.md index cfe159edd..def8cba16 100644 --- a/papers/format.md +++ b/papers/format.md @@ -32,6 +32,7 @@ these fields are 0 in format versions prior to 100 (0.6pre1). the format versions are: +- 112: Furnace dev112 - 111: Furnace dev111 - 110: Furnace dev110 - 109: Furnace dev109 @@ -454,6 +455,7 @@ size | description | - 29: SNES | - 30: Sound Unit | - 31: Namco WSG + | - 32: OPL (drums) 1 | reserved STR | instrument name --- | **FM instrument data** @@ -545,7 +547,18 @@ size | description 4 | extra 1 macro loop (>=17) 4 | extra 2 macro loop (>=17) 4 | extra 3 macro loop (>=17) - 1 | arp macro mode + 1 | arp macro mode (<112) or reserved + | - treat this value in a special way. + | - before version 112, this byte indicates whether the arp macro mode is fixed or not. + | - from that version onwards, the fixed mode is part of the macro values. + | - to convert a <112 macro mode to a modern one, do the following: + | - is the macro mode set to fixed? + | - if yes, then: + | - set bit 30 of all arp macro values (this is the fixed mode bit) + | - does the macro loop? + | - if yes, then do nothing else + | - if no, then add one to the macro length, and set the last macro value to 0 + | - if no, then do nothing 1 | reserved (>=17) or volume macro height (>=15) or reserved 1 | reserved (>=17) or duty macro height (>=15) or reserved 1 | reserved (>=17) or wave macro height (>=15) or reserved @@ -553,6 +566,7 @@ size | description | - before version 87, if this is the C64 relative cutoff macro, its values were stored offset by 18. 4?? | arp macro | - before version 31, this macro's values were stored offset by 12. + | - from version 112 onward, bit 30 of a value indicates fixed mode. 4?? | duty macro | - before version 87, if this is the C64 relative duty macro, its values were stored offset by 12. 4?? | wave macro diff --git a/src/engine/engine.cpp b/src/engine/engine.cpp index 7bf184f0a..4ee8e48bb 100644 --- a/src/engine/engine.cpp +++ b/src/engine/engine.cpp @@ -1712,6 +1712,11 @@ int DivEngine::calcFreq(int base, int pitch, bool period, int octave, int pitch2 base+((pitch*octave)>>1)+pitch2; } +int DivEngine::calcArp(int note, int arp, int offset) { + if (arp&0x40000000) return (arp&(~0x40000000))+offset; + return note+arp; +} + int DivEngine::convertPanSplitToLinear(unsigned int val, unsigned char bits, int range) { int panL=val>>bits; int panR=val&((1<std.arpMacro.len; j++) { ins->std.arpMacro.val[j]-=12; } + } else { + ins->std.arpMacro.mode=0; + for (int j=0; jstd.arpMacro.len; j++) { + ins->std.arpMacro.val[i]|=0x40000000; + } + if (ins->std.arpMacro.loopstd.arpMacro.len && ins->std.arpMacro.len<255) { + ins->std.arpMacro.val[ins->std.arpMacro.len++]=0; + } } ins->std.dutyMacro.len=reader.readC(); @@ -2886,9 +2894,6 @@ bool DivEngine::loadFC(unsigned char* file, size_t len) { loopMapFreq[j]=ins->std.arpMacro.len; loopMapWave[j]=ins->std.waveMacro.len; if (fm.val[j]==0xe1) { - if (ins->std.arpMacro.mode) { - ins->std.arpMacro.loop=(signed int)ins->std.arpMacro.len-1; - } break; } else if (fm.val[j]==0xe2 || fm.val[j]==0xe4) { if (++j>=64) break; @@ -2923,8 +2928,7 @@ bool DivEngine::loadFC(unsigned char* file, size_t len) { logV("unhandled pitch!"); } else { if (fm.val[j]>0x80) { - ins->std.arpMacro.val[ins->std.arpMacro.len]=fm.val[j]-0x80+24; - ins->std.arpMacro.mode=1; // TODO: variable fixed/relative mode + ins->std.arpMacro.val[ins->std.arpMacro.len]=(fm.val[j]-0x80+24)|0x40000000; } else { ins->std.arpMacro.val[ins->std.arpMacro.len]=fm.val[j]; } @@ -3293,6 +3297,7 @@ bool DivEngine::loadFTM(unsigned char* file, size_t len) { ins->std.arpMacro.len=reader.readC(); ins->std.arpMacro.loop=reader.readI(); ins->std.arpMacro.rel=reader.readI(); + // TODO: get rid ins->std.arpMacro.mode=reader.readI(); for (int j=0; jstd.arpMacro.len; j++) { ins->std.arpMacro.val[j]=reader.readC(); @@ -4204,6 +4209,7 @@ SafeWriter* DivEngine::saveDMF(unsigned char version) { } } + // TODO: take care of new arp macro format w->writeC(i->std.arpMacro.len); if (i->std.arpMacro.mode) { for (int j=0; jstd.arpMacro.len; j++) { diff --git a/src/engine/instrument.cpp b/src/engine/instrument.cpp index b2203ebf6..bd28834c4 100644 --- a/src/engine/instrument.cpp +++ b/src/engine/instrument.cpp @@ -132,7 +132,7 @@ void DivInstrument::putInsData(SafeWriter* w) { w->writeI(std.ex1Macro.loop); w->writeI(std.ex2Macro.loop); w->writeI(std.ex3Macro.loop); - w->writeC(std.arpMacro.mode); + w->writeC(0); // this was arp macro mode w->writeC(0); // reserved w->writeC(0); w->writeC(0); @@ -1342,6 +1342,19 @@ DivDataErrors DivInstrument::readInsData(SafeReader& reader, short version) { } } + // old arp macro format + if (version<112) { + if (std.arpMacro.mode) { + std.arpMacro.mode=0; + for (int i=0; istd.arpMacro.loop && std.arpMacro.len<255) { + std.arpMacro.val[std.arpMacro.len++]=0; + } + } + } + return DIV_DATA_SUCCESS; } diff --git a/src/engine/platform/amiga.cpp b/src/engine/platform/amiga.cpp index 57c0e3e21..ed71d76a4 100644 --- a/src/engine/platform/amiga.cpp +++ b/src/engine/platform/amiga.cpp @@ -163,19 +163,9 @@ void DivPlatformAmiga::tick(bool sysTick) { } } if (chan[i].std.arp.had) { - if (!chan[i].inPorta) { - if (chan[i].std.arp.mode) { - chan[i].baseFreq=round(off*NOTE_PERIODIC_NOROUND(chan[i].std.arp.val)); - } else { - chan[i].baseFreq=round(off*NOTE_PERIODIC_NOROUND(chan[i].note+chan[i].std.arp.val)); - } - } + // TODO: why the off mult? this may be a bug! + chan[i].baseFreq=round(off*NOTE_PERIODIC_NOROUND(parent->calcArp(chan[i].note,chan[i].std.arp.val))); chan[i].freqChanged=true; - } else { - if (chan[i].std.arp.mode && chan[i].std.arp.finished) { - chan[i].baseFreq=round(off*NOTE_PERIODIC_NOROUND(chan[i].note)); - chan[i].freqChanged=true; - } } if (chan[i].useWave && chan[i].std.wave.had) { if (chan[i].wave!=chan[i].std.wave.val || chan[i].ws.activeChanged()) { diff --git a/src/engine/platform/arcade.cpp b/src/engine/platform/arcade.cpp index 1f51dc9bd..cca54d28b 100644 --- a/src/engine/platform/arcade.cpp +++ b/src/engine/platform/arcade.cpp @@ -161,18 +161,9 @@ void DivPlatformArcade::tick(bool sysTick) { if (chan[i].std.arp.had) { if (!chan[i].inPorta) { - if (chan[i].std.arp.mode) { - chan[i].baseFreq=NOTE_LINEAR(chan[i].std.arp.val); - } else { - chan[i].baseFreq=NOTE_LINEAR(chan[i].note+(signed char)chan[i].std.arp.val); - } + chan[i].baseFreq=NOTE_LINEAR(parent->calcArp(chan[i].note,chan[i].std.arp.val)); } chan[i].freqChanged=true; - } else { - if (chan[i].std.arp.mode && chan[i].std.arp.finished) { - chan[i].baseFreq=NOTE_LINEAR(chan[i].note); - chan[i].freqChanged=true; - } } if (chan[i].std.duty.had) { diff --git a/src/engine/platform/ay.cpp b/src/engine/platform/ay.cpp index 1b24ac733..f45c51ea7 100644 --- a/src/engine/platform/ay.cpp +++ b/src/engine/platform/ay.cpp @@ -159,18 +159,9 @@ void DivPlatformAY8910::tick(bool sysTick) { } if (chan[i].std.arp.had) { if (!chan[i].inPorta) { - if (chan[i].std.arp.mode) { - chan[i].baseFreq=NOTE_PERIODIC(chan[i].std.arp.val); - } else { - chan[i].baseFreq=NOTE_PERIODIC(chan[i].note+chan[i].std.arp.val); - } + chan[i].baseFreq=NOTE_PERIODIC(parent->calcArp(chan[i].note,chan[i].std.arp.val)); } chan[i].freqChanged=true; - } else { - if (chan[i].std.arp.mode && chan[i].std.arp.finished) { - chan[i].baseFreq=NOTE_PERIODIC(chan[i].note); - chan[i].freqChanged=true; - } } if (chan[i].std.duty.had) { rWrite(0x06,31-chan[i].std.duty.val); diff --git a/src/engine/platform/ay8930.cpp b/src/engine/platform/ay8930.cpp index 0fc9091f2..d77457d66 100644 --- a/src/engine/platform/ay8930.cpp +++ b/src/engine/platform/ay8930.cpp @@ -167,18 +167,9 @@ void DivPlatformAY8930::tick(bool sysTick) { } if (chan[i].std.arp.had) { if (!chan[i].inPorta) { - if (chan[i].std.arp.mode) { - chan[i].baseFreq=NOTE_PERIODIC(chan[i].std.arp.val); - } else { - chan[i].baseFreq=NOTE_PERIODIC(chan[i].note+chan[i].std.arp.val); - } + chan[i].baseFreq=NOTE_PERIODIC(parent->calcArp(chan[i].note,chan[i].std.arp.val)); } chan[i].freqChanged=true; - } else { - if (chan[i].std.arp.mode && chan[i].std.arp.finished) { - chan[i].baseFreq=NOTE_PERIODIC(chan[i].note); - chan[i].freqChanged=true; - } } if (chan[i].std.duty.had) { rWrite(0x06,chan[i].std.duty.val); diff --git a/src/engine/platform/bubsyswsg.cpp b/src/engine/platform/bubsyswsg.cpp index fd00ebeeb..89503cceb 100644 --- a/src/engine/platform/bubsyswsg.cpp +++ b/src/engine/platform/bubsyswsg.cpp @@ -92,18 +92,9 @@ void DivPlatformBubSysWSG::tick(bool sysTick) { } if (chan[i].std.arp.had) { if (!chan[i].inPorta) { - if (chan[i].std.arp.mode) { - chan[i].baseFreq=NOTE_PERIODIC(chan[i].std.arp.val); - } else { - chan[i].baseFreq=NOTE_PERIODIC(chan[i].note+chan[i].std.arp.val); - } + chan[i].baseFreq=NOTE_PERIODIC(parent->calcArp(chan[i].note,chan[i].std.arp.val)); } chan[i].freqChanged=true; - } else { - if (chan[i].std.arp.mode && chan[i].std.arp.finished) { - chan[i].baseFreq=NOTE_PERIODIC(chan[i].note); - chan[i].freqChanged=true; - } } if (chan[i].std.wave.had) { if (chan[i].wave!=chan[i].std.wave.val || chan[i].ws.activeChanged()) { diff --git a/src/engine/platform/c64.cpp b/src/engine/platform/c64.cpp index dc0cd8a2d..9825f189e 100644 --- a/src/engine/platform/c64.cpp +++ b/src/engine/platform/c64.cpp @@ -104,18 +104,9 @@ void DivPlatformC64::tick(bool sysTick) { } if (chan[i].std.arp.had) { if (!chan[i].inPorta) { - if (chan[i].std.arp.mode) { - chan[i].baseFreq=NOTE_FREQUENCY(chan[i].std.arp.val); - } else { - chan[i].baseFreq=NOTE_FREQUENCY(chan[i].note+(signed char)chan[i].std.arp.val); - } + chan[i].baseFreq=NOTE_FREQUENCY(parent->calcArp(chan[i].note,chan[i].std.arp.val)); } chan[i].freqChanged=true; - } else { - if (chan[i].std.arp.mode && chan[i].std.arp.finished) { - chan[i].baseFreq=NOTE_FREQUENCY(chan[i].note); - chan[i].freqChanged=true; - } } if (chan[i].std.duty.had) { DivInstrument* ins=parent->getIns(chan[i].ins,DIV_INS_C64); diff --git a/src/engine/platform/fds.cpp b/src/engine/platform/fds.cpp index fc4d3e775..7622a0990 100644 --- a/src/engine/platform/fds.cpp +++ b/src/engine/platform/fds.cpp @@ -121,18 +121,9 @@ void DivPlatformFDS::tick(bool sysTick) { } if (chan[i].std.arp.had) { if (!chan[i].inPorta) { - if (chan[i].std.arp.mode) { - chan[i].baseFreq=NOTE_FREQUENCY(chan[i].std.arp.val); - } else { - chan[i].baseFreq=NOTE_FREQUENCY(chan[i].note+chan[i].std.arp.val); - } + chan[i].baseFreq=NOTE_FREQUENCY(parent->calcArp(chan[i].note,chan[i].std.arp.val)); } chan[i].freqChanged=true; - } else { - if (chan[i].std.arp.mode && chan[i].std.arp.finished) { - chan[i].baseFreq=NOTE_FREQUENCY(chan[i].note); - chan[i].freqChanged=true; - } } /* if (chan[i].std.duty.had) { diff --git a/src/engine/platform/gb.cpp b/src/engine/platform/gb.cpp index ab603266c..afed615d2 100644 --- a/src/engine/platform/gb.cpp +++ b/src/engine/platform/gb.cpp @@ -165,28 +165,13 @@ void DivPlatformGB::tick(bool sysTick) { } if (chan[i].std.arp.had) { if (i==3) { // noise - if (chan[i].std.arp.mode) { - chan[i].baseFreq=chan[i].std.arp.val+24; - } else { - chan[i].baseFreq=chan[i].note+chan[i].std.arp.val; - } + chan[i].baseFreq=parent->calcArp(chan[i].note,chan[i].std.arp.val,24); if (chan[i].baseFreq>255) chan[i].baseFreq=255; if (chan[i].baseFreq<0) chan[i].baseFreq=0; } else { - if (!chan[i].inPorta) { - if (chan[i].std.arp.mode) { - chan[i].baseFreq=NOTE_PERIODIC(chan[i].std.arp.val+24); - } else { - chan[i].baseFreq=NOTE_PERIODIC(chan[i].note+chan[i].std.arp.val); - } - } + chan[i].baseFreq=NOTE_PERIODIC(parent->calcArp(chan[i].note,chan[i].std.arp.val)); } chan[i].freqChanged=true; - } else { - if (chan[i].std.arp.mode && chan[i].std.arp.finished) { - chan[i].baseFreq=NOTE_PERIODIC(chan[i].note); - chan[i].freqChanged=true; - } } if (chan[i].std.duty.had) { chan[i].duty=chan[i].std.duty.val; diff --git a/src/engine/platform/genesis.cpp b/src/engine/platform/genesis.cpp index 7dde9790e..f499865ef 100644 --- a/src/engine/platform/genesis.cpp +++ b/src/engine/platform/genesis.cpp @@ -266,34 +266,16 @@ void DivPlatformGenesis::tick(bool sysTick) { if (i>=5 && chan[i].furnaceDac) { if (chan[i].std.arp.had) { if (!chan[i].inPorta) { - if (chan[i].std.arp.mode) { - chan[i].baseFreq=parent->calcBaseFreq(1,1,chan[i].std.arp.val,false); - } else { - chan[i].baseFreq=parent->calcBaseFreq(1,1,chan[i].note+(signed char)chan[i].std.arp.val,false); - } + chan[i].baseFreq=parent->calcBaseFreq(1,1,parent->calcArp(chan[i].note,chan[i].std.arp.val),false); } chan[i].freqChanged=true; - } else { - if (chan[i].std.arp.mode && chan[i].std.arp.finished) { - chan[i].baseFreq=parent->calcBaseFreq(1,1,chan[i].note,false); - chan[i].freqChanged=true; - } } } else { if (chan[i].std.arp.had) { if (!chan[i].inPorta) { - if (chan[i].std.arp.mode) { - chan[i].baseFreq=NOTE_FNUM_BLOCK(chan[i].std.arp.val,11); - } else { - chan[i].baseFreq=NOTE_FNUM_BLOCK(chan[i].note+(signed char)chan[i].std.arp.val,11); - } + chan[i].baseFreq=NOTE_FNUM_BLOCK(parent->calcArp(chan[i].note,chan[i].std.arp.val),11); } chan[i].freqChanged=true; - } else { - if (chan[i].std.arp.mode && chan[i].std.arp.finished) { - chan[i].baseFreq=NOTE_FNUM_BLOCK(chan[i].note,11); - chan[i].freqChanged=true; - } } } diff --git a/src/engine/platform/lynx.cpp b/src/engine/platform/lynx.cpp index ead20590a..f771be334 100644 --- a/src/engine/platform/lynx.cpp +++ b/src/engine/platform/lynx.cpp @@ -172,22 +172,9 @@ void DivPlatformLynx::tick(bool sysTick) { } if (chan[i].std.arp.had) { if (!chan[i].inPorta) { - if (chan[i].std.arp.mode) { - chan[i].baseFreq=NOTE_PERIODIC(chan[i].std.arp.val); - if (chan[i].pcm) chan[i].sampleBaseFreq=parent->calcBaseFreq(1.0,1.0,chan[i].std.arp.val,false); - chan[i].actualNote=chan[i].std.arp.val; - } else { - chan[i].baseFreq=NOTE_PERIODIC(chan[i].note+chan[i].std.arp.val); - if (chan[i].pcm) chan[i].sampleBaseFreq=parent->calcBaseFreq(1.0,1.0,chan[i].note+chan[i].std.arp.val,false); - chan[i].actualNote=chan[i].note+chan[i].std.arp.val; - } - chan[i].freqChanged=true; - } - } else { - if (chan[i].std.arp.mode && chan[i].std.arp.finished) { - chan[i].baseFreq=NOTE_PERIODIC(chan[i].note); - if (chan[i].pcm) chan[i].sampleBaseFreq=parent->calcBaseFreq(1.0,1.0,chan[i].note,false); - chan[i].actualNote=chan[i].note; + chan[i].actualNote=parent->calcArp(chan[i].note,chan[i].std.arp.val); + chan[i].baseFreq=NOTE_PERIODIC(chan[i].actualNote); + if (chan[i].pcm) chan[i].sampleBaseFreq=parent->calcBaseFreq(1.0,1.0,chan[i].actualNote,false); chan[i].freqChanged=true; } } diff --git a/src/engine/platform/mmc5.cpp b/src/engine/platform/mmc5.cpp index b5bb5a9e8..0a3bfb9e7 100644 --- a/src/engine/platform/mmc5.cpp +++ b/src/engine/platform/mmc5.cpp @@ -101,20 +101,12 @@ void DivPlatformMMC5::tick(bool sysTick) { if (chan[i].outVol<0) chan[i].outVol=0; rWrite(0x5000+i*4,0x30|chan[i].outVol|((chan[i].duty&3)<<6)); } + // TODO: arp macros on NES PCM? if (chan[i].std.arp.had) { if (!chan[i].inPorta) { - if (chan[i].std.arp.mode) { - chan[i].baseFreq=NOTE_PERIODIC(chan[i].std.arp.val); - } else { - chan[i].baseFreq=NOTE_PERIODIC(chan[i].note+chan[i].std.arp.val); - } + chan[i].baseFreq=NOTE_PERIODIC(parent->calcArp(chan[i].note,chan[i].std.arp.val)); } chan[i].freqChanged=true; - } else { - if (chan[i].std.arp.mode && chan[i].std.arp.finished) { - chan[i].baseFreq=NOTE_PERIODIC(chan[i].note); - chan[i].freqChanged=true; - } } if (chan[i].std.duty.had) { chan[i].duty=chan[i].std.duty.val; diff --git a/src/engine/platform/n163.cpp b/src/engine/platform/n163.cpp index 52352dc62..7da2e0a16 100644 --- a/src/engine/platform/n163.cpp +++ b/src/engine/platform/n163.cpp @@ -189,18 +189,9 @@ void DivPlatformN163::tick(bool sysTick) { } if (chan[i].std.arp.had) { if (!chan[i].inPorta) { - if (chan[i].std.arp.mode) { - chan[i].baseFreq=NOTE_FREQUENCY(chan[i].std.arp.val); - } else { - chan[i].baseFreq=NOTE_FREQUENCY(chan[i].note+(signed char)chan[i].std.arp.val); - } + chan[i].baseFreq=NOTE_FREQUENCY(parent->calcArp(chan[i].note,chan[i].std.arp.val)); } chan[i].freqChanged=true; - } else { - if (chan[i].std.arp.mode && chan[i].std.arp.finished) { - chan[i].baseFreq=NOTE_FREQUENCY(chan[i].note); - chan[i].freqChanged=true; - } } if (chan[i].std.duty.had) { if (chan[i].wavePos!=chan[i].std.duty.val) { diff --git a/src/engine/platform/namcowsg.cpp b/src/engine/platform/namcowsg.cpp index e88bb0ebf..236790e37 100644 --- a/src/engine/platform/namcowsg.cpp +++ b/src/engine/platform/namcowsg.cpp @@ -206,18 +206,9 @@ void DivPlatformNamcoWSG::tick(bool sysTick) { } if (chan[i].std.arp.had) { if (!chan[i].inPorta) { - if (chan[i].std.arp.mode) { - chan[i].baseFreq=NOTE_FREQUENCY(chan[i].std.arp.val); - } else { - chan[i].baseFreq=NOTE_FREQUENCY(chan[i].note+chan[i].std.arp.val); - } + chan[i].baseFreq=NOTE_FREQUENCY(parent->calcArp(chan[i].note,chan[i].std.arp.val)); } chan[i].freqChanged=true; - } else { - if (chan[i].std.arp.mode && chan[i].std.arp.finished) { - chan[i].baseFreq=NOTE_FREQUENCY(chan[i].note); - chan[i].freqChanged=true; - } } if (chan[i].std.wave.had) { if (chan[i].wave!=chan[i].std.wave.val || chan[i].ws.activeChanged()) { diff --git a/src/engine/platform/nes.cpp b/src/engine/platform/nes.cpp index a55199d15..ab466f1b5 100644 --- a/src/engine/platform/nes.cpp +++ b/src/engine/platform/nes.cpp @@ -219,28 +219,15 @@ void DivPlatformNES::tick(bool sysTick) { } if (chan[i].std.arp.had) { if (i==3) { // noise - if (chan[i].std.arp.mode) { - chan[i].baseFreq=chan[i].std.arp.val; - } else { - chan[i].baseFreq=chan[i].note+chan[i].std.arp.val; - } + chan[i].baseFreq=parent->calcArp(chan[i].note,chan[i].std.arp.val); if (chan[i].baseFreq>255) chan[i].baseFreq=255; if (chan[i].baseFreq<0) chan[i].baseFreq=0; } else { if (!chan[i].inPorta) { - if (chan[i].std.arp.mode) { - chan[i].baseFreq=NOTE_PERIODIC(chan[i].std.arp.val); - } else { - chan[i].baseFreq=NOTE_PERIODIC(chan[i].note+chan[i].std.arp.val); - } + chan[i].baseFreq=NOTE_PERIODIC(parent->calcArp(chan[i].note,chan[i].std.arp.val)); } } chan[i].freqChanged=true; - } else { - if (chan[i].std.arp.mode && chan[i].std.arp.finished) { - chan[i].baseFreq=NOTE_PERIODIC(chan[i].note); - chan[i].freqChanged=true; - } } if (chan[i].std.duty.had) { chan[i].duty=chan[i].std.duty.val; diff --git a/src/engine/platform/opl.cpp b/src/engine/platform/opl.cpp index 78ef25a29..eb49637e3 100644 --- a/src/engine/platform/opl.cpp +++ b/src/engine/platform/opl.cpp @@ -297,18 +297,9 @@ void DivPlatformOPL::tick(bool sysTick) { if (chan[i].std.arp.had) { if (!chan[i].inPorta) { - if (chan[i].std.arp.mode) { - chan[i].baseFreq=NOTE_FREQUENCY(chan[i].std.arp.val); - } else { - chan[i].baseFreq=NOTE_FREQUENCY(chan[i].note+(signed char)chan[i].std.arp.val); - } + chan[i].baseFreq=NOTE_FREQUENCY(parent->calcArp(chan[i].note,chan[i].std.arp.val)); } chan[i].freqChanged=true; - } else { - if (chan[i].std.arp.mode && chan[i].std.arp.finished) { - chan[i].baseFreq=NOTE_FREQUENCY(chan[i].note); - chan[i].freqChanged=true; - } } if (oplType==3 && chan[i].std.panL.had) { @@ -491,18 +482,9 @@ void DivPlatformOPL::tick(bool sysTick) { if (chan[adpcmChan].std.arp.had) { if (!chan[adpcmChan].inPorta) { - if (chan[adpcmChan].std.arp.mode) { - chan[adpcmChan].baseFreq=NOTE_ADPCMB(chan[adpcmChan].std.arp.val); - } else { - chan[adpcmChan].baseFreq=NOTE_ADPCMB(chan[adpcmChan].note+(signed char)chan[adpcmChan].std.arp.val); - } + chan[adpcmChan].baseFreq=NOTE_ADPCMB(parent->calcArp(chan[adpcmChan].note,chan[adpcmChan].std.arp.val)); } chan[adpcmChan].freqChanged=true; - } else { - if (chan[adpcmChan].std.arp.mode && chan[adpcmChan].std.arp.finished) { - chan[adpcmChan].baseFreq=NOTE_ADPCMB(chan[adpcmChan].note); - chan[adpcmChan].freqChanged=true; - } } } if (chan[adpcmChan].freqChanged) { diff --git a/src/engine/platform/opll.cpp b/src/engine/platform/opll.cpp index e29f6e622..9485551aa 100644 --- a/src/engine/platform/opll.cpp +++ b/src/engine/platform/opll.cpp @@ -107,18 +107,9 @@ void DivPlatformOPLL::tick(bool sysTick) { if (chan[i].std.arp.had) { if (!chan[i].inPorta) { - if (chan[i].std.arp.mode) { - chan[i].baseFreq=NOTE_FREQUENCY(chan[i].std.arp.val); - } else { - chan[i].baseFreq=NOTE_FREQUENCY(chan[i].note+(signed char)chan[i].std.arp.val); - } + chan[i].baseFreq=NOTE_FREQUENCY(parent->calcArp(chan[i].note,chan[i].std.arp.val)); } chan[i].freqChanged=true; - } else { - if (chan[i].std.arp.mode && chan[i].std.arp.finished) { - chan[i].baseFreq=NOTE_FREQUENCY(chan[i].note); - chan[i].freqChanged=true; - } } if (chan[i].std.wave.had && chan[i].state.opllPreset!=16) { diff --git a/src/engine/platform/pce.cpp b/src/engine/platform/pce.cpp index 1dcf24511..476b1ecca 100644 --- a/src/engine/platform/pce.cpp +++ b/src/engine/platform/pce.cpp @@ -162,28 +162,12 @@ void DivPlatformPCE::tick(bool sysTick) { } if (chan[i].std.arp.had) { if (!chan[i].inPorta) { - if (chan[i].std.arp.mode) { - chan[i].baseFreq=NOTE_PERIODIC(chan[i].std.arp.val); - // noise - int noiseSeek=chan[i].std.arp.val; - if (noiseSeek<0) noiseSeek=0; - chWrite(i,0x07,chan[i].noise?(0x80|(parent->song.properNoiseLayout?(noiseSeek&31):noiseFreq[noiseSeek%12])):0); - } else { - chan[i].baseFreq=NOTE_PERIODIC(chan[i].note+chan[i].std.arp.val); - int noiseSeek=chan[i].note+chan[i].std.arp.val; - if (noiseSeek<0) noiseSeek=0; - chWrite(i,0x07,chan[i].noise?(0x80|(parent->song.properNoiseLayout?(noiseSeek&31):noiseFreq[noiseSeek%12])):0); - } - } - chan[i].freqChanged=true; - } else { - if (chan[i].std.arp.mode && chan[i].std.arp.finished) { - chan[i].baseFreq=NOTE_PERIODIC(chan[i].note); - int noiseSeek=chan[i].note; + int noiseSeek=parent->calcArp(chan[i].note,chan[i].std.arp.val); + chan[i].baseFreq=NOTE_PERIODIC(noiseSeek); if (noiseSeek<0) noiseSeek=0; chWrite(i,0x07,chan[i].noise?(0x80|(parent->song.properNoiseLayout?(noiseSeek&31):noiseFreq[noiseSeek%12])):0); - chan[i].freqChanged=true; } + chan[i].freqChanged=true; } if (chan[i].std.wave.had && !chan[i].pcm) { if (chan[i].wave!=chan[i].std.wave.val || chan[i].ws.activeChanged()) { diff --git a/src/engine/platform/pcmdac.cpp b/src/engine/platform/pcmdac.cpp index 213cb85a3..026e989cc 100644 --- a/src/engine/platform/pcmdac.cpp +++ b/src/engine/platform/pcmdac.cpp @@ -83,18 +83,9 @@ void DivPlatformPCMDAC::tick(bool sysTick) { } if (chan.std.arp.had) { if (!chan.inPorta) { - if (chan.std.arp.mode) { - chan.baseFreq=NOTE_FREQUENCY(chan.std.arp.val); - } else { - chan.baseFreq=NOTE_FREQUENCY(chan.note+chan.std.arp.val); - } + chan.baseFreq=NOTE_FREQUENCY(parent->calcArp(chan.note,chan.std.arp.val)); } chan.freqChanged=true; - } else { - if (chan.std.arp.mode && chan.std.arp.finished) { - chan.baseFreq=NOTE_FREQUENCY(chan.note); - chan.freqChanged=true; - } } if (chan.useWave && chan.std.wave.had) { if (chan.wave!=chan.std.wave.val || chan.ws.activeChanged()) { diff --git a/src/engine/platform/pcspkr.cpp b/src/engine/platform/pcspkr.cpp index 260f5bbd6..ab3b8a7ca 100644 --- a/src/engine/platform/pcspkr.cpp +++ b/src/engine/platform/pcspkr.cpp @@ -347,18 +347,9 @@ void DivPlatformPCSpeaker::tick(bool sysTick) { } if (chan[i].std.arp.had) { if (!chan[i].inPorta) { - if (chan[i].std.arp.mode) { - chan[i].baseFreq=NOTE_PERIODIC(chan[i].std.arp.val); - } else { - chan[i].baseFreq=NOTE_PERIODIC(chan[i].note+chan[i].std.arp.val); - } + chan[i].baseFreq=NOTE_PERIODIC(parent->calcArp(chan[i].note,chan[i].std.arp.val)); } chan[i].freqChanged=true; - } else { - if (chan[i].std.arp.mode && chan[i].std.arp.finished) { - chan[i].baseFreq=NOTE_PERIODIC(chan[i].note); - chan[i].freqChanged=true; - } } if (chan[i].std.pitch.had) { if (chan[i].std.pitch.mode) { diff --git a/src/engine/platform/pet.cpp b/src/engine/platform/pet.cpp index 4e1c39a97..c314edf6f 100644 --- a/src/engine/platform/pet.cpp +++ b/src/engine/platform/pet.cpp @@ -104,18 +104,9 @@ void DivPlatformPET::tick(bool sysTick) { } if (chan.std.arp.had) { if (!chan.inPorta) { - if (chan.std.arp.mode) { - chan.baseFreq=NOTE_PERIODIC(chan.std.arp.val); - } else { - chan.baseFreq=NOTE_PERIODIC(chan.note+chan.std.arp.val); - } + chan.baseFreq=NOTE_PERIODIC(parent->calcArp(chan.note,chan.std.arp.val)); } chan.freqChanged=true; - } else { - if (chan.std.arp.mode && chan.std.arp.finished) { - chan.baseFreq=NOTE_PERIODIC(chan.note); - chan.freqChanged=true; - } } if (chan.std.wave.had) { if (chan.wave!=chan.std.wave.val) { diff --git a/src/engine/platform/qsound.cpp b/src/engine/platform/qsound.cpp index 863c0e1fd..1339d70af 100644 --- a/src/engine/platform/qsound.cpp +++ b/src/engine/platform/qsound.cpp @@ -297,18 +297,9 @@ void DivPlatformQSound::tick(bool sysTick) { } if (chan[i].std.arp.had) { if (!chan[i].inPorta) { - if (chan[i].std.arp.mode) { - chan[i].baseFreq=QS_NOTE_FREQUENCY(chan[i].std.arp.val); - } else { - chan[i].baseFreq=QS_NOTE_FREQUENCY(chan[i].note+chan[i].std.arp.val); - } + chan[i].baseFreq=QS_NOTE_FREQUENCY(parent->calcArp(chan[i].note,chan[i].std.arp.val)); } chan[i].freqChanged=true; - } else { - if (chan[i].std.arp.mode && chan[i].std.arp.finished) { - chan[i].baseFreq=QS_NOTE_FREQUENCY(chan[i].note); - chan[i].freqChanged=true; - } } if (chan[i].std.pitch.had) { if (chan[i].std.pitch.mode) { diff --git a/src/engine/platform/rf5c68.cpp b/src/engine/platform/rf5c68.cpp index e19b945b0..3aa922e47 100644 --- a/src/engine/platform/rf5c68.cpp +++ b/src/engine/platform/rf5c68.cpp @@ -84,18 +84,9 @@ void DivPlatformRF5C68::tick(bool sysTick) { } if (chan[i].std.arp.had) { if (!chan[i].inPorta) { - if (chan[i].std.arp.mode) { - chan[i].baseFreq=NOTE_FREQUENCY(chan[i].std.arp.val); - } else { - chan[i].baseFreq=NOTE_FREQUENCY(chan[i].note+chan[i].std.arp.val); - } + chan[i].baseFreq=NOTE_FREQUENCY(parent->calcArp(chan[i].note,chan[i].std.arp.val)); } chan[i].freqChanged=true; - } else { - if (chan[i].std.arp.mode && chan[i].std.arp.finished) { - chan[i].baseFreq=NOTE_FREQUENCY(chan[i].note); - chan[i].freqChanged=true; - } } if (chan[i].std.pitch.had) { if (chan[i].std.pitch.mode) { diff --git a/src/engine/platform/saa.cpp b/src/engine/platform/saa.cpp index a05a61d4f..b7a77d968 100644 --- a/src/engine/platform/saa.cpp +++ b/src/engine/platform/saa.cpp @@ -99,18 +99,9 @@ void DivPlatformSAA1099::tick(bool sysTick) { } if (chan[i].std.arp.had) { if (!chan[i].inPorta) { - if (chan[i].std.arp.mode) { - chan[i].baseFreq=NOTE_PERIODIC(chan[i].std.arp.val); - } else { - chan[i].baseFreq=NOTE_PERIODIC(chan[i].note+chan[i].std.arp.val); - } + chan[i].baseFreq=NOTE_PERIODIC(parent->calcArp(chan[i].note,chan[i].std.arp.val)); } chan[i].freqChanged=true; - } else { - if (chan[i].std.arp.mode && chan[i].std.arp.finished) { - chan[i].baseFreq=NOTE_PERIODIC(chan[i].note); - chan[i].freqChanged=true; - } } if (chan[i].std.duty.had) { saaNoise[i/3]=chan[i].std.duty.val&3; diff --git a/src/engine/platform/scc.cpp b/src/engine/platform/scc.cpp index a72257629..d8859cffd 100644 --- a/src/engine/platform/scc.cpp +++ b/src/engine/platform/scc.cpp @@ -115,18 +115,9 @@ void DivPlatformSCC::tick(bool sysTick) { } if (chan[i].std.arp.had) { if (!chan[i].inPorta) { - if (chan[i].std.arp.mode) { - chan[i].baseFreq=NOTE_PERIODIC(chan[i].std.arp.val); - } else { - chan[i].baseFreq=NOTE_PERIODIC(chan[i].note+chan[i].std.arp.val); - } + chan[i].baseFreq=NOTE_PERIODIC(parent->calcArp(chan[i].note,chan[i].std.arp.val)); } chan[i].freqChanged=true; - } else { - if (chan[i].std.arp.mode && chan[i].std.arp.finished) { - chan[i].baseFreq=NOTE_PERIODIC(chan[i].note); - chan[i].freqChanged=true; - } } if (chan[i].std.wave.had) { if (chan[i].wave!=chan[i].std.wave.val || chan[i].ws.activeChanged()) { diff --git a/src/engine/platform/segapcm.cpp b/src/engine/platform/segapcm.cpp index e406e293b..329e3b82a 100644 --- a/src/engine/platform/segapcm.cpp +++ b/src/engine/platform/segapcm.cpp @@ -88,18 +88,9 @@ void DivPlatformSegaPCM::tick(bool sysTick) { if (chan[i].std.arp.had) { if (!chan[i].inPorta) { - if (chan[i].std.arp.mode) { - chan[i].baseFreq=(chan[i].std.arp.val<<6); - } else { - chan[i].baseFreq=((chan[i].note+(signed char)chan[i].std.arp.val)<<6); - } + chan[i].baseFreq=(parent->calcArp(chan[i].note,chan[i].std.arp.val)<<6); } chan[i].freqChanged=true; - } else { - if (chan[i].std.arp.mode && chan[i].std.arp.finished) { - chan[i].baseFreq=(chan[i].note<<6); - chan[i].freqChanged=true; - } } if (chan[i].std.panL.had) { diff --git a/src/engine/platform/sms.cpp b/src/engine/platform/sms.cpp index 40a8616ef..497095c17 100644 --- a/src/engine/platform/sms.cpp +++ b/src/engine/platform/sms.cpp @@ -132,22 +132,12 @@ void DivPlatformSMS::tick(bool sysTick) { } if (chan[i].std.arp.had) { if (!chan[i].inPorta) { - if (chan[i].std.arp.mode) { - chan[i].baseFreq=NOTE_PERIODIC(chan[i].std.arp.val); - chan[i].actualNote=chan[i].std.arp.val; - } else { - // TODO: check whether this weird octave boundary thing applies to other systems as well - int areYouSerious=chan[i].note+chan[i].std.arp.val; - while (areYouSerious>0x60) areYouSerious-=12; - chan[i].baseFreq=NOTE_PERIODIC(areYouSerious); - chan[i].actualNote=areYouSerious; - } - chan[i].freqChanged=true; - } - } else { - if (chan[i].std.arp.mode && chan[i].std.arp.finished) { - chan[i].baseFreq=NOTE_PERIODIC(chan[i].note); - chan[i].actualNote=chan[i].note; + // TODO: check whether this weird octave boundary thing applies to other systems as well + // TODO: add compatibility flag. this is horrible. + int areYouSerious=parent->calcArp(chan[i].note,chan[i].std.arp.val); + while (areYouSerious>0x60) areYouSerious-=12; + chan[i].baseFreq=NOTE_PERIODIC(areYouSerious); + chan[i].actualNote=areYouSerious; chan[i].freqChanged=true; } } diff --git a/src/engine/platform/su.cpp b/src/engine/platform/su.cpp index ca933650f..a28ed3047 100644 --- a/src/engine/platform/su.cpp +++ b/src/engine/platform/su.cpp @@ -78,18 +78,9 @@ void DivPlatformSoundUnit::tick(bool sysTick) { } if (chan[i].std.arp.had) { if (!chan[i].inPorta) { - if (chan[i].std.arp.mode) { - chan[i].baseFreq=NOTE_SU(i,chan[i].std.arp.val); - } else { - chan[i].baseFreq=NOTE_SU(i,chan[i].note+chan[i].std.arp.val); - } + chan[i].baseFreq=NOTE_SU(i,parent->calcArp(chan[i].note,chan[i].std.arp.val)); } chan[i].freqChanged=true; - } else { - if (chan[i].std.arp.mode && chan[i].std.arp.finished) { - chan[i].baseFreq=NOTE_SU(i,chan[i].note); - chan[i].freqChanged=true; - } } if (chan[i].std.duty.had) { chan[i].duty=chan[i].std.duty.val; diff --git a/src/engine/platform/swan.cpp b/src/engine/platform/swan.cpp index cdab93d5c..7f1e10a02 100644 --- a/src/engine/platform/swan.cpp +++ b/src/engine/platform/swan.cpp @@ -134,18 +134,9 @@ void DivPlatformSwan::tick(bool sysTick) { } if (chan[i].std.arp.had) { if (!chan[i].inPorta) { - if (chan[i].std.arp.mode) { - chan[i].baseFreq=NOTE_PERIODIC(chan[i].std.arp.val); - } else { - chan[i].baseFreq=NOTE_PERIODIC(chan[i].note+chan[i].std.arp.val); - } + chan[i].baseFreq=NOTE_PERIODIC(parent->calcArp(chan[i].note,chan[i].std.arp.val)); } chan[i].freqChanged=true; - } else { - if (chan[i].std.arp.mode && chan[i].std.arp.finished) { - chan[i].baseFreq=NOTE_PERIODIC(chan[i].note); - chan[i].freqChanged=true; - } } if (chan[i].std.wave.had && !(i==1 && pcm)) { if (chan[i].wave!=chan[i].std.wave.val || chan[i].ws.activeChanged()) { diff --git a/src/engine/platform/tia.cpp b/src/engine/platform/tia.cpp index 18bdcb0c3..fe7273a1c 100644 --- a/src/engine/platform/tia.cpp +++ b/src/engine/platform/tia.cpp @@ -87,20 +87,16 @@ void DivPlatformTIA::tick(bool sysTick) { rWrite(0x19+i,chan[i].outVol&15); } } + // TODO: the way arps work on TIA is really weird if (chan[i].std.arp.had) { if (!chan[i].inPorta) { - if (chan[i].std.arp.mode) { - chan[i].baseFreq=0x80000000|chan[i].std.arp.val; + if (chan[i].std.arp.val&0x40000000) { + chan[i].baseFreq=0x80000000|(chan[i].std.arp.val&(~0x40000000)); } else { chan[i].baseFreq=(chan[i].note+chan[i].std.arp.val)<<8; } } chan[i].freqChanged=true; - } else { - if (chan[i].std.arp.mode && chan[i].std.arp.finished) { - chan[i].baseFreq=chan[i].note<<8; - chan[i].freqChanged=true; - } } if (chan[i].std.wave.had) { chan[i].shape=chan[i].std.wave.val&15; diff --git a/src/engine/platform/tx81z.cpp b/src/engine/platform/tx81z.cpp index e6e38a128..0fe0265e1 100644 --- a/src/engine/platform/tx81z.cpp +++ b/src/engine/platform/tx81z.cpp @@ -123,18 +123,9 @@ void DivPlatformTX81Z::tick(bool sysTick) { if (chan[i].std.arp.had) { if (!chan[i].inPorta) { - if (chan[i].std.arp.mode) { - chan[i].baseFreq=NOTE_LINEAR(chan[i].std.arp.val); - } else { - chan[i].baseFreq=NOTE_LINEAR(chan[i].note+(signed char)chan[i].std.arp.val); - } + chan[i].baseFreq=NOTE_LINEAR(parent->calcArp(chan[i].note,chan[i].std.arp.val)); } chan[i].freqChanged=true; - } else { - if (chan[i].std.arp.mode && chan[i].std.arp.finished) { - chan[i].baseFreq=NOTE_LINEAR(chan[i].note); - chan[i].freqChanged=true; - } } if (chan[i].std.duty.had) { diff --git a/src/engine/platform/vera.cpp b/src/engine/platform/vera.cpp index e50bcd6ea..bf47df5a5 100644 --- a/src/engine/platform/vera.cpp +++ b/src/engine/platform/vera.cpp @@ -159,18 +159,9 @@ void DivPlatformVERA::tick(bool sysTick) { } if (chan[i].std.arp.had) { if (!chan[i].inPorta) { - if (chan[i].std.arp.mode) { - chan[i].baseFreq=calcNoteFreq(0,chan[i].std.arp.val); - } else { - chan[i].baseFreq=calcNoteFreq(0,chan[i].note+chan[i].std.arp.val); - } + chan[i].baseFreq=calcNoteFreq(0,parent->calcArp(chan[i].note,chan[i].std.arp.val)); } chan[i].freqChanged=true; - } else { - if (chan[i].std.arp.mode && chan[i].std.arp.finished) { - chan[i].baseFreq=calcNoteFreq(0,chan[i].note); - chan[i].freqChanged=true; - } } if (chan[i].std.duty.had) { rWriteLo(i,3,chan[i].std.duty.val); @@ -209,18 +200,9 @@ void DivPlatformVERA::tick(bool sysTick) { } if (chan[16].std.arp.had) { if (!chan[16].inPorta) { - if (chan[16].std.arp.mode) { - chan[16].baseFreq=calcNoteFreq(16,chan[16].std.arp.val); - } else { - chan[16].baseFreq=calcNoteFreq(16,chan[16].note+chan[16].std.arp.val); - } + chan[16].baseFreq=calcNoteFreq(16,parent->calcArp(chan[16].note,chan[16].std.arp.val)); } chan[16].freqChanged=true; - } else { - if (chan[16].std.arp.mode && chan[16].std.arp.finished) { - chan[16].baseFreq=calcNoteFreq(16,chan[16].note); - chan[16].freqChanged=true; - } } if (chan[16].freqChanged) { double off=65536.0; diff --git a/src/engine/platform/vic20.cpp b/src/engine/platform/vic20.cpp index 5c0bdf461..93c119484 100644 --- a/src/engine/platform/vic20.cpp +++ b/src/engine/platform/vic20.cpp @@ -94,18 +94,9 @@ void DivPlatformVIC20::tick(bool sysTick) { } if (chan[i].std.arp.had) { if (!chan[i].inPorta) { - if (chan[i].std.arp.mode) { - chan[i].baseFreq=NOTE_PERIODIC(chan[i].std.arp.val); - } else { - chan[i].baseFreq=NOTE_PERIODIC(chan[i].note+chan[i].std.arp.val); - } + chan[i].baseFreq=NOTE_PERIODIC(parent->calcArp(chan[i].note,chan[i].std.arp.val)); } chan[i].freqChanged=true; - } else { - if (chan[i].std.arp.mode && chan[i].std.arp.finished) { - chan[i].baseFreq=NOTE_PERIODIC(chan[i].note); - chan[i].freqChanged=true; - } } if (chan[i].std.wave.had) { if (chan[i].wave!=chan[i].std.wave.val) { diff --git a/src/engine/platform/vrc6.cpp b/src/engine/platform/vrc6.cpp index 9a7bcef0d..2500ce190 100644 --- a/src/engine/platform/vrc6.cpp +++ b/src/engine/platform/vrc6.cpp @@ -153,18 +153,9 @@ void DivPlatformVRC6::tick(bool sysTick) { } if (chan[i].std.arp.had) { if (!chan[i].inPorta) { - if (chan[i].std.arp.mode) { - chan[i].baseFreq=NOTE_PERIODIC(chan[i].std.arp.val); - } else { - chan[i].baseFreq=NOTE_PERIODIC(chan[i].note+chan[i].std.arp.val); - } + chan[i].baseFreq=NOTE_PERIODIC(parent->calcArp(chan[i].note,chan[i].std.arp.val)); } chan[i].freqChanged=true; - } else { - if (chan[i].std.arp.mode && chan[i].std.arp.finished) { - chan[i].baseFreq=NOTE_PERIODIC(chan[i].note); - chan[i].freqChanged=true; - } } if (chan[i].std.duty.had) { chan[i].duty=chan[i].std.duty.val; diff --git a/src/engine/platform/x1_010.cpp b/src/engine/platform/x1_010.cpp index f6aa1c651..0f989ac9d 100644 --- a/src/engine/platform/x1_010.cpp +++ b/src/engine/platform/x1_010.cpp @@ -321,18 +321,9 @@ void DivPlatformX1_010::tick(bool sysTick) { if ((!chan[i].pcm) || chan[i].furnacePCM) { if (chan[i].std.arp.had) { if (!chan[i].inPorta) { - if (chan[i].std.arp.mode) { - chan[i].baseFreq=NoteX1_010(i,chan[i].std.arp.val); - } else { - chan[i].baseFreq=NoteX1_010(i,chan[i].note+chan[i].std.arp.val); - } + chan[i].baseFreq=NoteX1_010(i,parent->calcArp(chan[i].note,chan[i].std.arp.val)); } chan[i].freqChanged=true; - } else { - if (chan[i].std.arp.mode && chan[i].std.arp.finished) { - chan[i].baseFreq=NoteX1_010(i,chan[i].note); - chan[i].freqChanged=true; - } } } if (chan[i].std.wave.had && !chan[i].pcm) { diff --git a/src/engine/platform/ym2203.cpp b/src/engine/platform/ym2203.cpp index afb4f526c..178ef05b8 100644 --- a/src/engine/platform/ym2203.cpp +++ b/src/engine/platform/ym2203.cpp @@ -231,18 +231,9 @@ void DivPlatformYM2203::tick(bool sysTick) { if (chan[i].std.arp.had) { if (!chan[i].inPorta) { - if (chan[i].std.arp.mode) { - chan[i].baseFreq=NOTE_FNUM_BLOCK(chan[i].std.arp.val,11); - } else { - chan[i].baseFreq=NOTE_FNUM_BLOCK(chan[i].note+(signed char)chan[i].std.arp.val,11); - } + chan[i].baseFreq=NOTE_FNUM_BLOCK(parent->calcArp(chan[i].note,chan[i].std.arp.val),11); } chan[i].freqChanged=true; - } else { - if (chan[i].std.arp.mode && chan[i].std.arp.finished) { - chan[i].baseFreq=NOTE_FNUM_BLOCK(chan[i].note,11); - chan[i].freqChanged=true; - } } if (chan[i].std.pitch.had) { diff --git a/src/engine/platform/ym2608.cpp b/src/engine/platform/ym2608.cpp index 9e76e6e3f..244e4a16e 100644 --- a/src/engine/platform/ym2608.cpp +++ b/src/engine/platform/ym2608.cpp @@ -386,18 +386,9 @@ void DivPlatformYM2608::tick(bool sysTick) { if (chan[i].std.arp.had) { if (!chan[i].inPorta) { - if (chan[i].std.arp.mode) { - chan[i].baseFreq=NOTE_FNUM_BLOCK(chan[i].std.arp.val,11); - } else { - chan[i].baseFreq=NOTE_FNUM_BLOCK(chan[i].note+(signed char)chan[i].std.arp.val,11); - } + chan[i].baseFreq=NOTE_FNUM_BLOCK(parent->calcArp(chan[i].note,chan[i].std.arp.val),11); } chan[i].freqChanged=true; - } else { - if (chan[i].std.arp.mode && chan[i].std.arp.finished) { - chan[i].baseFreq=NOTE_FNUM_BLOCK(chan[i].note,11); - chan[i].freqChanged=true; - } } if (chan[i].std.panL.had) { @@ -538,18 +529,9 @@ void DivPlatformYM2608::tick(bool sysTick) { if (chan[15].std.arp.had) { if (!chan[15].inPorta) { - if (chan[15].std.arp.mode) { - chan[15].baseFreq=NOTE_ADPCMB(chan[15].std.arp.val); - } else { - chan[15].baseFreq=NOTE_ADPCMB(chan[15].note+(signed char)chan[15].std.arp.val); - } + chan[15].baseFreq=NOTE_ADPCMB(parent->calcArp(chan[15].note,chan[15].std.arp.val)); } chan[15].freqChanged=true; - } else { - if (chan[15].std.arp.mode && chan[15].std.arp.finished) { - chan[15].baseFreq=NOTE_ADPCMB(chan[15].note); - chan[15].freqChanged=true; - } } } if (chan[15].freqChanged) { diff --git a/src/engine/platform/ym2610.cpp b/src/engine/platform/ym2610.cpp index 920d9b144..064b49f2d 100644 --- a/src/engine/platform/ym2610.cpp +++ b/src/engine/platform/ym2610.cpp @@ -427,18 +427,9 @@ void DivPlatformYM2610::tick(bool sysTick) { if (chan[i].std.arp.had) { if (!chan[i].inPorta) { - if (chan[i].std.arp.mode) { - chan[i].baseFreq=NOTE_FNUM_BLOCK(chan[i].std.arp.val,11); - } else { - chan[i].baseFreq=NOTE_FNUM_BLOCK(chan[i].note+(signed char)chan[i].std.arp.val,11); - } + chan[i].baseFreq=NOTE_FNUM_BLOCK(parent->calcArp(chan[i].note,chan[i].std.arp.val),11); } chan[i].freqChanged=true; - } else { - if (chan[i].std.arp.mode && chan[i].std.arp.finished) { - chan[i].baseFreq=NOTE_FNUM_BLOCK(chan[i].note,11); - chan[i].freqChanged=true; - } } if (chan[i].std.panL.had) { @@ -580,18 +571,9 @@ void DivPlatformYM2610::tick(bool sysTick) { if (chan[13].std.arp.had) { if (!chan[13].inPorta) { - if (chan[13].std.arp.mode) { - chan[13].baseFreq=NOTE_ADPCMB(chan[13].std.arp.val); - } else { - chan[13].baseFreq=NOTE_ADPCMB(chan[13].note+(signed char)chan[13].std.arp.val); - } + chan[13].baseFreq=NOTE_ADPCMB(parent->calcArp(chan[13].note,chan[13].std.arp.val)); } chan[13].freqChanged=true; - } else { - if (chan[13].std.arp.mode && chan[13].std.arp.finished) { - chan[13].baseFreq=NOTE_ADPCMB(chan[13].note); - chan[13].freqChanged=true; - } } } if (chan[13].freqChanged) { diff --git a/src/engine/platform/ym2610b.cpp b/src/engine/platform/ym2610b.cpp index 039691e74..8d283374d 100644 --- a/src/engine/platform/ym2610b.cpp +++ b/src/engine/platform/ym2610b.cpp @@ -410,18 +410,9 @@ void DivPlatformYM2610B::tick(bool sysTick) { if (chan[i].std.arp.had) { if (!chan[i].inPorta) { - if (chan[i].std.arp.mode) { - chan[i].baseFreq=NOTE_FNUM_BLOCK(chan[i].std.arp.val,11); - } else { - chan[i].baseFreq=NOTE_FNUM_BLOCK(chan[i].note+(signed char)chan[i].std.arp.val,11); - } + chan[i].baseFreq=NOTE_FNUM_BLOCK(parent->calcArp(chan[i].note,chan[i].std.arp.val),11); } chan[i].freqChanged=true; - } else { - if (chan[i].std.arp.mode && chan[i].std.arp.finished) { - chan[i].baseFreq=NOTE_FNUM_BLOCK(chan[i].note,11); - chan[i].freqChanged=true; - } } if (chan[i].std.panL.had) { @@ -562,18 +553,9 @@ void DivPlatformYM2610B::tick(bool sysTick) { if (chan[15].std.arp.had) { if (!chan[15].inPorta) { - if (chan[15].std.arp.mode) { - chan[15].baseFreq=NOTE_ADPCMB(chan[15].std.arp.val); - } else { - chan[15].baseFreq=NOTE_ADPCMB(chan[15].note+(signed char)chan[15].std.arp.val); - } + chan[15].baseFreq=NOTE_ADPCMB(parent->calcArp(chan[15].note,chan[15].std.arp.val)); } chan[15].freqChanged=true; - } else { - if (chan[15].std.arp.mode && chan[15].std.arp.finished) { - chan[15].baseFreq=NOTE_ADPCMB(chan[15].note); - chan[15].freqChanged=true; - } } } if (chan[15].freqChanged) { diff --git a/src/engine/platform/ymz280b.cpp b/src/engine/platform/ymz280b.cpp index ca1b225d2..eb65a7bda 100644 --- a/src/engine/platform/ymz280b.cpp +++ b/src/engine/platform/ymz280b.cpp @@ -95,18 +95,9 @@ void DivPlatformYMZ280B::tick(bool sysTick) { } if (chan[i].std.arp.had) { if (!chan[i].inPorta) { - if (chan[i].std.arp.mode) { - chan[i].baseFreq=NOTE_FREQUENCY(chan[i].std.arp.val); - } else { - chan[i].baseFreq=NOTE_FREQUENCY(chan[i].note+chan[i].std.arp.val); - } + chan[i].baseFreq=NOTE_FREQUENCY(parent->calcArp(chan[i].note,chan[i].std.arp.val)); } chan[i].freqChanged=true; - } else { - if (chan[i].std.arp.mode && chan[i].std.arp.finished) { - chan[i].baseFreq=NOTE_FREQUENCY(chan[i].note); - chan[i].freqChanged=true; - } } if (chan[i].std.pitch.had) { if (chan[i].std.pitch.mode) { diff --git a/src/engine/platform/zxbeeper.cpp b/src/engine/platform/zxbeeper.cpp index d83903094..5fa3840bb 100644 --- a/src/engine/platform/zxbeeper.cpp +++ b/src/engine/platform/zxbeeper.cpp @@ -81,18 +81,9 @@ void DivPlatformZXBeeper::tick(bool sysTick) { } if (chan[i].std.arp.had) { if (!chan[i].inPorta) { - if (chan[i].std.arp.mode) { - chan[i].baseFreq=NOTE_FREQUENCY(chan[i].std.arp.val); - } else { - chan[i].baseFreq=NOTE_FREQUENCY(chan[i].note+chan[i].std.arp.val); - } + chan[i].baseFreq=NOTE_FREQUENCY(parent->calcArp(chan[i].note,chan[i].std.arp.val)); } chan[i].freqChanged=true; - } else { - if (chan[i].std.arp.mode && chan[i].std.arp.finished) { - chan[i].baseFreq=NOTE_FREQUENCY(chan[i].note); - chan[i].freqChanged=true; - } } if (chan[i].std.pitch.had) { if (chan[i].std.pitch.mode) { diff --git a/src/gui/gui.cpp b/src/gui/gui.cpp index b5ccbd7b2..c044ae664 100644 --- a/src/gui/gui.cpp +++ b/src/gui/gui.cpp @@ -195,23 +195,25 @@ void FurnaceGUI::decodeKeyMap(std::map& map, String source) { } } -void FurnaceGUI::encodeMMLStr(String& target, int* macro, int macroLen, int macroLoop, int macroRel, bool hex) { +void FurnaceGUI::encodeMMLStr(String& target, int* macro, int macroLen, int macroLoop, int macroRel, bool hex, bool bit30) { target=""; char buf[32]; for (int i=0; imacroMax) macro[macroLen]=macroMax; + if (setBit30) macro[macroLen]|=0x40000000; + setBit30=false; macroLen++; buf=0; } @@ -315,6 +325,8 @@ void FurnaceGUI::decodeMMLStr(String& source, int* macro, unsigned char& macroLe negaBuf=false; if (macro[macroLen]macroMax) macro[macroLen]=macroMax; + if (setBit30) macro[macroLen]|=0x40000000; + setBit30=false; macroLen++; buf=0; } @@ -329,6 +341,8 @@ void FurnaceGUI::decodeMMLStr(String& source, int* macro, unsigned char& macroLe negaBuf=false; if (macro[macroLen]macroMax) macro[macroLen]=macroMax; + if (setBit30) macro[macroLen]|=0x40000000; + setBit30=false; macroLen++; buf=0; } @@ -345,6 +359,8 @@ void FurnaceGUI::decodeMMLStr(String& source, int* macro, unsigned char& macroLe negaBuf=false; if (macro[macroLen]macroMax) macro[macroLen]=macroMax; + if (setBit30) macro[macroLen]|=0x40000000; + setBit30=false; macroLen++; buf=0; } @@ -1758,6 +1774,8 @@ void FurnaceGUI::showError(String what) { displayError=true; } +#define B30(tt) (macroDragBit30?((tt)&0x40000000):0) + #define MACRO_DRAG(t) \ if (macroDragBitMode) { \ if (macroDragLastX!=x || macroDragLastY!=y) { \ @@ -1790,25 +1808,25 @@ void FurnaceGUI::showError(String what) { } \ if (macroDragMouseMoved) { \ if ((int)round(x-macroDragLineInitial.x)==0) { \ - t[x]=macroDragLineInitial.y; \ + t[x]=B30(t[x])|(int)(macroDragLineInitial.y); \ } else { \ if ((int)round(x-macroDragLineInitial.x)<0) { \ for (int i=0; i<=(int)round(macroDragLineInitial.x-x); i++) { \ int index=(int)round(x+i); \ if (index<0) continue; \ - t[index]=y+(macroDragLineInitial.y-y)*((float)i/(float)(macroDragLineInitial.x-x)); \ + t[index]=B30(t[index])|(int)(y+(macroDragLineInitial.y-y)*((float)i/(float)(macroDragLineInitial.x-x))); \ } \ } else { \ for (int i=0; i<=(int)round(x-macroDragLineInitial.x); i++) { \ int index=(int)round(i+macroDragLineInitial.x); \ if (index<0) continue; \ - t[index]=macroDragLineInitial.y+(y-macroDragLineInitial.y)*((float)i/(x-macroDragLineInitial.x)); \ + t[index]=B30(t[index])|(int)(macroDragLineInitial.y+(y-macroDragLineInitial.y)*((float)i/(x-macroDragLineInitial.x))); \ } \ } \ } \ } \ } else { \ - t[x]=y; \ + t[x]=B30(t[x])|(y); \ } \ } @@ -4868,6 +4886,7 @@ FurnaceGUI::FurnaceGUI(): macroDragInitialValueSet(false), macroDragInitialValue(false), macroDragChar(false), + macroDragBit30(false), macroDragLineMode(false), macroDragMouseMoved(false), macroDragLineInitial(0,0), diff --git a/src/gui/gui.h b/src/gui/gui.h index f7b13b073..a7f906aea 100644 --- a/src/gui/gui.h +++ b/src/gui/gui.h @@ -869,10 +869,10 @@ struct FurnaceGUIMacroDesc { const char* modeName; ImVec4 color; unsigned int bitOffset; - bool isBitfield, blockMode; + bool isBitfield, blockMode, bit30; String (*hoverFunc)(int,float); - FurnaceGUIMacroDesc(const char* name, DivInstrumentMacro* m, int macroMin, int macroMax, float macroHeight, ImVec4 col=ImVec4(1.0f,1.0f,1.0f,1.0f), bool block=false, const char* mName=NULL, String (*hf)(int,float)=NULL, bool bitfield=false, const char** bfVal=NULL, unsigned int bitOff=0): + FurnaceGUIMacroDesc(const char* name, DivInstrumentMacro* m, int macroMin, int macroMax, float macroHeight, ImVec4 col=ImVec4(1.0f,1.0f,1.0f,1.0f), bool block=false, const char* mName=NULL, String (*hf)(int,float)=NULL, bool bitfield=false, const char** bfVal=NULL, unsigned int bitOff=0, bool bit30Special=false): macro(m), height(macroHeight), displayName(name), @@ -882,6 +882,7 @@ struct FurnaceGUIMacroDesc { bitOffset(bitOff), isBitfield(bitfield), blockMode(block), + bit30(bit30Special), hoverFunc(hf) { // MSVC -> hell this->min=macroMin; @@ -1395,6 +1396,7 @@ class FurnaceGUI { bool macroDragInitialValueSet; bool macroDragInitialValue; bool macroDragChar; + bool macroDragBit30; bool macroDragLineMode; bool macroDragMouseMoved; ImVec2 macroDragLineInitial; @@ -1686,8 +1688,8 @@ class FurnaceGUI { void applyUISettings(bool updateFonts=true); void initSystemPresets(); - void encodeMMLStr(String& target, int* macro, int macroLen, int macroLoop, int macroRel, bool hex=false); - void decodeMMLStr(String& source, int* macro, unsigned char& macroLen, unsigned char& macroLoop, int macroMin, int macroMax, unsigned char& macroRel); + void encodeMMLStr(String& target, int* macro, int macroLen, int macroLoop, int macroRel, bool hex=false, bool bit30=false); + void decodeMMLStr(String& source, int* macro, unsigned char& macroLen, unsigned char& macroLoop, int macroMin, int macroMax, unsigned char& macroRel, bool bit30=false); void decodeMMLStrW(String& source, int* macro, int& macroLen, int macroMax, bool hex=false); String encodeKeyMap(std::map& map); diff --git a/src/gui/insEdit.cpp b/src/gui/insEdit.cpp index f7e80c535..ea0717154 100644 --- a/src/gui/insEdit.cpp +++ b/src/gui/insEdit.cpp @@ -331,6 +331,11 @@ String macroHoverLoop(int id, float val) { return ""; } +String macroHoverBit30(int id, float val) { + if (val>0) return "Fixed"; + return "Relative"; +} + String macroHoverES5506FilterMode(int id, float val) { String mode="???"; switch (((int)val)&3) { @@ -1196,6 +1201,7 @@ void FurnaceGUI::drawMacros(std::vector& macros) { float asFloat[256]; int asInt[256]; float loopIndicator[256]; + float bit30Indicator[256]; bool doHighlight[256]; int index=0; @@ -1281,12 +1287,14 @@ void FurnaceGUI::drawMacros(std::vector& macros) { // macro area ImGui::TableNextColumn(); for (int j=0; j<256; j++) { + bit30Indicator[j]=0; if (j+macroDragScroll>=i.macro->len) { asFloat[j]=0; asInt[j]=0; } else { - asFloat[j]=i.macro->val[j+macroDragScroll]; - asInt[j]=i.macro->val[j+macroDragScroll]+i.bitOffset; + asFloat[j]=i.macro->val[j+macroDragScroll]&(i.bit30?(~0x40000000):0xffffffff); + asInt[j]=(i.macro->val[j+macroDragScroll]&(i.bit30?(~0x40000000):0xffffffff))+i.bitOffset; + if (i.bit30) bit30Indicator[j]=(i.macro->val[j+macroDragScroll]&0x40000000)?1:0; } if (j+macroDragScroll>=i.macro->len || (j+macroDragScroll>i.macro->rel && i.macro->looprel)) { loopIndicator[j]=0; @@ -1355,6 +1363,7 @@ void FurnaceGUI::drawMacros(std::vector& macros) { macroDragInitialValue=false; macroDragLen=totalFit; macroDragActive=true; + macroDragBit30=i.bit30; macroDragTarget=i.macro->val; macroDragChar=false; macroDragLineMode=(i.isBitfield)?false:ImGui::IsItemClicked(ImGuiMouseButton_Right); @@ -1422,6 +1431,12 @@ void FurnaceGUI::drawMacros(std::vector& macros) { } } + // bit 30 area + // TODO: ability to set it + if (i.bit30) { + PlotCustom("##IMacroBit30",bit30Indicator,totalFit,macroDragScroll,NULL,0,1,ImVec2(availableWidth,12.0f*dpiScale),sizeof(float),i.color,i.macro->len-macroDragScroll,¯oHoverBit30); + } + // loop area PlotCustom("##IMacroLoop",loopIndicator,totalFit,macroDragScroll,NULL,0,2,ImVec2(availableWidth,12.0f*dpiScale),sizeof(float),i.color,i.macro->len-macroDragScroll,¯oHoverLoop); if (ImGui::IsItemClicked(ImGuiMouseButton_Left)) { @@ -4178,7 +4193,7 @@ void FurnaceGUI::drawInsEdit() { if (volMax>0) { macroList.push_back(FurnaceGUIMacroDesc(volumeLabel,&ins->std.volMacro,volMin,volMax,160,uiColors[GUI_COLOR_MACRO_VOLUME])); } - macroList.push_back(FurnaceGUIMacroDesc("Arpeggio",&ins->std.arpMacro,-120,120,160,uiColors[GUI_COLOR_MACRO_PITCH],true,macroAbsoluteMode,ins->std.arpMacro.mode?(¯oHoverNote):NULL)); + macroList.push_back(FurnaceGUIMacroDesc("Arpeggio",&ins->std.arpMacro,-120,120,160,uiColors[GUI_COLOR_MACRO_PITCH],true,NULL,NULL,false,NULL,0,true)); if (dutyMax>0) { if (ins->type==DIV_INS_MIKEY) { macroList.push_back(FurnaceGUIMacroDesc(dutyLabel,&ins->std.dutyMacro,0,dutyMax,160,uiColors[GUI_COLOR_MACRO_OTHER],false,NULL,NULL,true,mikeyFeedbackBits));