diff --git a/papers/format.md b/papers/format.md index 235e8dce0..d60dc0a15 100644 --- a/papers/format.md +++ b/papers/format.md @@ -179,6 +179,7 @@ size | description 1 | reserved (>=17) or wave macro height (>=15) or reserved 4?? | volume macro 4?? | arp macro + | - before version 31, this macro's values were stored offset by 12. 4?? | duty macro 4?? | wave macro 4?? | pitch macro (>=17) diff --git a/src/engine/engine.cpp b/src/engine/engine.cpp index 1582b841f..d24f935a2 100644 --- a/src/engine/engine.cpp +++ b/src/engine/engine.cpp @@ -1010,6 +1010,11 @@ bool DivEngine::loadDMF(unsigned char* file, size_t len) { if (ds.version>0x0f) { ins->std.arpMacroMode=reader.readC(); } + if (!ins->std.arpMacroMode) { + for (int j=0; jstd.arpMacroLen; j++) { + ins->std.arpMacro[j]-=12; + } + } ins->std.dutyMacroLen=reader.readC(); for (int j=0; jstd.dutyMacroLen; j++) { @@ -1902,7 +1907,13 @@ SafeWriter* DivEngine::saveDMF() { } w->writeC(i->std.arpMacroLen); - w->write(i->std.arpMacro,4*i->std.arpMacroLen); + if (i->std.arpMacroMode) { + w->write(i->std.arpMacro,4*i->std.arpMacroLen); + } else { + for (int j=0; jstd.arpMacroLen; j++) { + w->writeI(i->std.arpMacro[j]+12); + } + } if (i->std.arpMacroLen>0) { w->writeC(i->std.arpMacroLoop); } diff --git a/src/engine/engine.h b/src/engine/engine.h index bf2b2b4d9..5bd36304b 100644 --- a/src/engine/engine.h +++ b/src/engine/engine.h @@ -11,8 +11,8 @@ #include #include -#define DIV_VERSION "0.5pre1" -#define DIV_ENGINE_VERSION 30 +#define DIV_VERSION "0.5pre2" +#define DIV_ENGINE_VERSION 31 enum DivStatusView { DIV_STATUS_NOTHING=0, diff --git a/src/engine/instrument.cpp b/src/engine/instrument.cpp index 0268a5d4d..97739d0a6 100644 --- a/src/engine/instrument.cpp +++ b/src/engine/instrument.cpp @@ -375,6 +375,11 @@ DivDataErrors DivInstrument::readInsData(SafeReader& reader, short version) { reader.read(std.arpMacro,4*std.arpMacroLen); reader.read(std.dutyMacro,4*std.dutyMacroLen); reader.read(std.waveMacro,4*std.waveMacroLen); + if (version<31) { + if (!std.arpMacroMode) for (int j=0; j=17) { reader.read(std.pitchMacro,4*std.pitchMacroLen); reader.read(std.ex1Macro,4*std.ex1MacroLen); diff --git a/src/engine/platform/amiga.cpp b/src/engine/platform/amiga.cpp index 265c2d03c..1c81e6b8a 100644 --- a/src/engine/platform/amiga.cpp +++ b/src/engine/platform/amiga.cpp @@ -60,7 +60,7 @@ void DivPlatformAmiga::tick() { if (chan[i].std.arpMode) { chan[i].baseFreq=round(FREQ_BASE/pow(2.0f,((float)(chan[i].std.arp)/12.0f))); } else { - chan[i].baseFreq=round(FREQ_BASE/pow(2.0f,((float)(chan[i].note+chan[i].std.arp-12)/12.0f))); + chan[i].baseFreq=round(FREQ_BASE/pow(2.0f,((float)(chan[i].note+chan[i].std.arp)/12.0f))); } } chan[i].freqChanged=true; diff --git a/src/engine/platform/ay.cpp b/src/engine/platform/ay.cpp index 5aba42992..511de8159 100644 --- a/src/engine/platform/ay.cpp +++ b/src/engine/platform/ay.cpp @@ -47,7 +47,7 @@ void DivPlatformAY8910::tick() { if (chan[i].std.arpMode) { chan[i].baseFreq=round(PSG_FREQ_BASE/pow(2.0f,((float)(chan[i].std.arp)/12.0f))); } else { - chan[i].baseFreq=round(PSG_FREQ_BASE/pow(2.0f,((float)(chan[i].note+chan[i].std.arp-12)/12.0f))); + chan[i].baseFreq=round(PSG_FREQ_BASE/pow(2.0f,((float)(chan[i].note+chan[i].std.arp)/12.0f))); } } chan[i].freqChanged=true; diff --git a/src/engine/platform/ay8930.cpp b/src/engine/platform/ay8930.cpp index cd7523273..9953d6c4f 100644 --- a/src/engine/platform/ay8930.cpp +++ b/src/engine/platform/ay8930.cpp @@ -68,7 +68,7 @@ void DivPlatformAY8930::tick() { if (chan[i].std.arpMode) { chan[i].baseFreq=round(PSG_FREQ_BASE/pow(2.0f,((float)(chan[i].std.arp)/12.0f))); } else { - chan[i].baseFreq=round(PSG_FREQ_BASE/pow(2.0f,((float)(chan[i].note+chan[i].std.arp-12)/12.0f))); + chan[i].baseFreq=round(PSG_FREQ_BASE/pow(2.0f,((float)(chan[i].note+chan[i].std.arp)/12.0f))); } } chan[i].freqChanged=true; diff --git a/src/engine/platform/c64.cpp b/src/engine/platform/c64.cpp index 0a5ade492..eb590b781 100644 --- a/src/engine/platform/c64.cpp +++ b/src/engine/platform/c64.cpp @@ -44,7 +44,7 @@ void DivPlatformC64::tick() { if (chan[i].std.arpMode) { chan[i].baseFreq=round(FREQ_BASE*pow(2.0f,((float)(chan[i].std.arp)/12.0f))); } else { - chan[i].baseFreq=round(FREQ_BASE*pow(2.0f,((float)(chan[i].note+(signed char)chan[i].std.arp-12)/12.0f))); + chan[i].baseFreq=round(FREQ_BASE*pow(2.0f,((float)(chan[i].note+(signed char)chan[i].std.arp)/12.0f))); } } chan[i].freqChanged=true; @@ -207,7 +207,7 @@ int DivPlatformC64::dispatch(DivCommand c) { rWrite(c.chan*7+4,(chan[c.chan].wave<<4)|(chan[c.chan].ring<<2)|(chan[c.chan].sync<<1)|chan[c.chan].active); break; case DIV_CMD_LEGATO: - chan[c.chan].baseFreq=round(FREQ_BASE*pow(2.0f,((float)(c.value+((chan[c.chan].std.willArp && !chan[c.chan].std.arpMode)?(chan[c.chan].std.arp-12):(0)))/12.0f))); + chan[c.chan].baseFreq=round(FREQ_BASE*pow(2.0f,((float)(c.value+((chan[c.chan].std.willArp && !chan[c.chan].std.arpMode)?(chan[c.chan].std.arp):(0)))/12.0f))); chan[c.chan].freqChanged=true; chan[c.chan].note=c.value; break; diff --git a/src/engine/platform/gb.cpp b/src/engine/platform/gb.cpp index 8b54f0f1a..802a118d7 100644 --- a/src/engine/platform/gb.cpp +++ b/src/engine/platform/gb.cpp @@ -84,7 +84,7 @@ void DivPlatformGB::tick() { if (chan[i].std.arpMode) { chan[i].baseFreq=chan[i].std.arp+24; } else { - chan[i].baseFreq=chan[i].note+chan[i].std.arp-12; + chan[i].baseFreq=chan[i].note+chan[i].std.arp; } if (chan[i].baseFreq>255) chan[i].baseFreq=255; if (chan[i].baseFreq<0) chan[i].baseFreq=0; @@ -93,7 +93,7 @@ void DivPlatformGB::tick() { if (chan[i].std.arpMode) { chan[i].baseFreq=round(FREQ_BASE/pow(2.0f,((float)(chan[i].std.arp+24)/12.0f))); } else { - chan[i].baseFreq=round(FREQ_BASE/pow(2.0f,((float)(chan[i].note+chan[i].std.arp-12)/12.0f))); + chan[i].baseFreq=round(FREQ_BASE/pow(2.0f,((float)(chan[i].note+chan[i].std.arp)/12.0f))); } } } @@ -261,7 +261,7 @@ int DivPlatformGB::dispatch(DivCommand c) { } case DIV_CMD_LEGATO: if (c.chan==3) break; - chan[c.chan].baseFreq=round(FREQ_BASE/pow(2.0f,((float)(c.value+((chan[c.chan].std.willArp && !chan[c.chan].std.arpMode)?(chan[c.chan].std.arp-12):(0)))/12.0f))); + chan[c.chan].baseFreq=round(FREQ_BASE/pow(2.0f,((float)(c.value+((chan[c.chan].std.willArp && !chan[c.chan].std.arpMode)?(chan[c.chan].std.arp):(0)))/12.0f))); chan[c.chan].freqChanged=true; chan[c.chan].note=c.value; break; diff --git a/src/engine/platform/genesis.cpp b/src/engine/platform/genesis.cpp index 7602823ab..b535bf99d 100644 --- a/src/engine/platform/genesis.cpp +++ b/src/engine/platform/genesis.cpp @@ -93,7 +93,7 @@ void DivPlatformGenesis::tick() { if (chan[i].std.arpMode) { chan[i].baseFreq=644.0f*pow(2.0f,((float)chan[i].std.arp/12.0f)); } else { - chan[i].baseFreq=644.0f*pow(2.0f,((float)(chan[i].note+(signed char)chan[i].std.arp-12)/12.0f)); + chan[i].baseFreq=644.0f*pow(2.0f,((float)(chan[i].note+(signed char)chan[i].std.arp)/12.0f)); } } chan[i].freqChanged=true; diff --git a/src/engine/platform/nes.cpp b/src/engine/platform/nes.cpp index 64620d3ff..5e5addc67 100644 --- a/src/engine/platform/nes.cpp +++ b/src/engine/platform/nes.cpp @@ -90,7 +90,7 @@ void DivPlatformNES::tick() { if (chan[i].std.arpMode) { chan[i].baseFreq=chan[i].std.arp; } else { - chan[i].baseFreq=chan[i].note+chan[i].std.arp-12; + chan[i].baseFreq=chan[i].note+chan[i].std.arp; } if (chan[i].baseFreq>255) chan[i].baseFreq=255; if (chan[i].baseFreq<0) chan[i].baseFreq=0; @@ -99,7 +99,7 @@ void DivPlatformNES::tick() { if (chan[i].std.arpMode) { chan[i].baseFreq=round(freqBase/pow(2.0f,((float)(chan[i].std.arp)/12.0f))); } else { - chan[i].baseFreq=round(freqBase/pow(2.0f,((float)(chan[i].note+chan[i].std.arp-12)/12.0f))); + chan[i].baseFreq=round(freqBase/pow(2.0f,((float)(chan[i].note+chan[i].std.arp)/12.0f))); } } } @@ -309,7 +309,7 @@ int DivPlatformNES::dispatch(DivCommand c) { break; case DIV_CMD_LEGATO: if (c.chan==3) break; - chan[c.chan].baseFreq=round(freqBase/pow(2.0f,((float)(c.value+((chan[c.chan].std.willArp && !chan[c.chan].std.arpMode)?(chan[c.chan].std.arp-12):(0)))/12.0f))); + chan[c.chan].baseFreq=round(freqBase/pow(2.0f,((float)(c.value+((chan[c.chan].std.willArp && !chan[c.chan].std.arpMode)?(chan[c.chan].std.arp):(0)))/12.0f))); chan[c.chan].freqChanged=true; chan[c.chan].note=c.value; break; @@ -394,7 +394,6 @@ int DivPlatformNES::init(DivEngine* p, int channels, int sugRate, bool pal) { for (int i=0; i<5; i++) { isMuted[i]=false; } - setPAL(pal); nes=new struct NESAPU; init_nla_table(500,500); diff --git a/src/engine/platform/pce.cpp b/src/engine/platform/pce.cpp index fb3345ec2..9ed7254a1 100644 --- a/src/engine/platform/pce.cpp +++ b/src/engine/platform/pce.cpp @@ -109,8 +109,8 @@ void DivPlatformPCE::tick() { // noise chWrite(i,0x07,chan[i].noise?(0x80|noiseFreq[(chan[i].std.arp)%12]):0); } else { - chan[i].baseFreq=round(FREQ_BASE/pow(2.0f,((float)(chan[i].note+chan[i].std.arp-12)/12.0f))); - chWrite(i,0x07,chan[i].noise?(0x80|noiseFreq[(chan[i].note+chan[i].std.arp-12)%12]):0); + chan[i].baseFreq=round(FREQ_BASE/pow(2.0f,((float)(chan[i].note+chan[i].std.arp)/12.0f))); + chWrite(i,0x07,chan[i].noise?(0x80|noiseFreq[(chan[i].note+chan[i].std.arp)%12]):0); } } chan[i].freqChanged=true; @@ -306,7 +306,7 @@ int DivPlatformPCE::dispatch(DivCommand c) { break; } case DIV_CMD_LEGATO: - chan[c.chan].baseFreq=round(FREQ_BASE/pow(2.0f,((float)(c.value+((chan[c.chan].std.willArp && !chan[c.chan].std.arpMode)?(chan[c.chan].std.arp-12):(0)))/12.0f))); + chan[c.chan].baseFreq=round(FREQ_BASE/pow(2.0f,((float)(c.value+((chan[c.chan].std.willArp && !chan[c.chan].std.arpMode)?(chan[c.chan].std.arp):(0)))/12.0f))); chan[c.chan].freqChanged=true; chan[c.chan].note=c.value; break; diff --git a/src/engine/platform/saa.cpp b/src/engine/platform/saa.cpp index ce0c0d9ae..a264cf449 100644 --- a/src/engine/platform/saa.cpp +++ b/src/engine/platform/saa.cpp @@ -50,7 +50,7 @@ void DivPlatformSAA1099::tick() { if (chan[i].std.arpMode) { chan[i].baseFreq=round(PSG_FREQ_BASE/pow(2.0f,((float)(chan[i].std.arp)/12.0f))); } else { - chan[i].baseFreq=round(PSG_FREQ_BASE/pow(2.0f,((float)(chan[i].note+chan[i].std.arp-12)/12.0f))); + chan[i].baseFreq=round(PSG_FREQ_BASE/pow(2.0f,((float)(chan[i].note+chan[i].std.arp)/12.0f))); } } chan[i].freqChanged=true; diff --git a/src/engine/platform/sms.cpp b/src/engine/platform/sms.cpp index eda4c8fb1..831aec87e 100644 --- a/src/engine/platform/sms.cpp +++ b/src/engine/platform/sms.cpp @@ -27,7 +27,7 @@ void DivPlatformSMS::tick() { if (chan[i].std.arpMode) { chan[i].baseFreq=round(FREQ_BASE/pow(2.0f,((float)(chan[i].std.arp)/12.0f))); } else { - chan[i].baseFreq=round(FREQ_BASE/pow(2.0f,((float)(chan[i].note+chan[i].std.arp-12)/12.0f))); + chan[i].baseFreq=round(FREQ_BASE/pow(2.0f,((float)(chan[i].note+chan[i].std.arp)/12.0f))); } chan[i].freqChanged=true; } else { @@ -154,7 +154,7 @@ int DivPlatformSMS::dispatch(DivCommand c) { updateSNMode=true; break; case DIV_CMD_LEGATO: - chan[c.chan].baseFreq=round(FREQ_BASE/pow(2.0f,((float)(c.value+((chan[c.chan].std.willArp && !chan[c.chan].std.arpMode)?(chan[c.chan].std.arp-12):(0)))/12.0f))); + chan[c.chan].baseFreq=round(FREQ_BASE/pow(2.0f,((float)(c.value+((chan[c.chan].std.willArp && !chan[c.chan].std.arpMode)?(chan[c.chan].std.arp):(0)))/12.0f))); chan[c.chan].freqChanged=true; chan[c.chan].note=c.value; break; diff --git a/src/engine/platform/tia.cpp b/src/engine/platform/tia.cpp index f97658973..e31c507d7 100644 --- a/src/engine/platform/tia.cpp +++ b/src/engine/platform/tia.cpp @@ -58,7 +58,7 @@ void DivPlatformTIA::tick() { if (chan[i].std.arpMode) { chan[i].baseFreq=0x80000000|chan[i].std.arp; } else { - chan[i].baseFreq=(chan[i].note+chan[i].std.arp-12)<<8; + chan[i].baseFreq=(chan[i].note+chan[i].std.arp)<<8; } } chan[i].freqChanged=true; diff --git a/src/engine/platform/ym2610.cpp b/src/engine/platform/ym2610.cpp index 864f2f511..8087c98e1 100644 --- a/src/engine/platform/ym2610.cpp +++ b/src/engine/platform/ym2610.cpp @@ -59,7 +59,7 @@ void DivPlatformYM2610::tick() { if (chan[i].std.arpMode) { chan[i].baseFreq=round(PSG_FREQ_BASE/pow(2.0f,((float)(chan[i].std.arp)/12.0f))); } else { - chan[i].baseFreq=round(PSG_FREQ_BASE/pow(2.0f,((float)(chan[i].note+chan[i].std.arp-12)/12.0f))); + chan[i].baseFreq=round(PSG_FREQ_BASE/pow(2.0f,((float)(chan[i].note+chan[i].std.arp)/12.0f))); } } chan[i].freqChanged=true; diff --git a/src/gui/gui.cpp b/src/gui/gui.cpp index 8c71bac8c..81c229870 100644 --- a/src/gui/gui.cpp +++ b/src/gui/gui.cpp @@ -1248,7 +1248,7 @@ void FurnaceGUI::drawInsEdit() { if (settings.macroView==0) { // modern view MACRO_BEGIN(28*dpiScale); NORMAL_MACRO(ins->std.volMacro,ins->std.volMacroLen,ins->std.volMacroLoop,volMin,volMax,"vol",volumeLabel,160,ins->std.volMacroOpen,false,NULL,false,NULL,0,0,0,NULL,uiColors[GUI_COLOR_MACRO_VOLUME],mmlString[0],volMin,volMax); - NORMAL_MACRO(ins->std.arpMacro,ins->std.arpMacroLen,ins->std.arpMacroLoop,arpMacroScroll,arpMacroScroll+24,"arp","Arpeggio",160,ins->std.arpMacroOpen,false,NULL,true,&arpMacroScroll,(arpMode?0:-80),(arpMode?0:-12),0,&ins->std.arpMacroMode,uiColors[GUI_COLOR_MACRO_PITCH],mmlString[1],-92,94); + NORMAL_MACRO(ins->std.arpMacro,ins->std.arpMacroLen,ins->std.arpMacroLoop,arpMacroScroll,arpMacroScroll+24,"arp","Arpeggio",160,ins->std.arpMacroOpen,false,NULL,true,&arpMacroScroll,(arpMode?0:-80),0,0,&ins->std.arpMacroMode,uiColors[GUI_COLOR_MACRO_PITCH],mmlString[1],-92,94); if (dutyMax>0) { NORMAL_MACRO(ins->std.dutyMacro,ins->std.dutyMacroLen,ins->std.dutyMacroLoop,0,dutyMax,"duty",dutyLabel,160,ins->std.dutyMacroOpen,false,NULL,false,NULL,0,0,0,NULL,uiColors[GUI_COLOR_MACRO_OTHER],mmlString[2],0,dutyMax); } @@ -1315,7 +1315,7 @@ void FurnaceGUI::drawInsEdit() { ImGui::Separator(); ImGui::Text("Arpeggio Macro"); for (int i=0; istd.arpMacroLen; i++) { - asFloat[i]=arpMode?ins->std.arpMacro[i]:(ins->std.arpMacro[i]-12); + asFloat[i]=ins->std.arpMacro[i]; loopIndicator[i]=(ins->std.arpMacroLoop!=-1 && i>=ins->std.arpMacroLoop); } ImGui::PushStyleVar(ImGuiStyleVar_FramePadding,ImVec2(0.0f,0.0f));