diff --git a/papers/format.md b/papers/format.md index bb0085f5..6d463a89 100644 --- a/papers/format.md +++ b/papers/format.md @@ -32,6 +32,8 @@ these fields are 0 in format versions prior to 100 (0.6pre1). the format versions are: +- 118: Furnace dev118 +- 117: Furnace dev117 - 116: Furnace 0.6pre1.5 - 115: Furnace dev115 - 114: Furnace dev114 @@ -905,6 +907,7 @@ size | description 1 | attack 1 | decay 1 | sustain + | - bit 3: sustain mode (>=118) 1 | release --- | **macro speeds/delays** (>=111) 1 | volume macro speed diff --git a/src/engine/engine.h b/src/engine/engine.h index 2219b6e2..19d86905 100644 --- a/src/engine/engine.h +++ b/src/engine/engine.h @@ -46,8 +46,8 @@ #define BUSY_BEGIN_SOFT softLocked=true; isBusy.lock(); #define BUSY_END isBusy.unlock(); softLocked=false; -#define DIV_VERSION "dev117" -#define DIV_ENGINE_VERSION 117 +#define DIV_VERSION "dev118" +#define DIV_ENGINE_VERSION 118 // for imports #define DIV_VERSION_MOD 0xff01 #define DIV_VERSION_FC 0xff02 diff --git a/src/engine/instrument.cpp b/src/engine/instrument.cpp index e944fdbf..a78bb8ff 100644 --- a/src/engine/instrument.cpp +++ b/src/engine/instrument.cpp @@ -559,13 +559,12 @@ void DivInstrument::putInsData(SafeWriter* w) { w->writeC(es5506.envelope.k2Slow); // SNES - // @tildearrow please update this w->writeC(snes.useEnv); - w->writeC(0); - w->writeC(0); + w->writeC(snes.gainMode); + w->writeC(snes.gain); w->writeC(snes.a); w->writeC(snes.d); - w->writeC(snes.s); + w->writeC((snes.s&7)|(snes.sus?8:0)); w->writeC(snes.r); // macro speed/delay @@ -1259,11 +1258,13 @@ DivDataErrors DivInstrument::readInsData(SafeReader& reader, short version) { // SNES if (version>=109) { snes.useEnv=reader.readC(); - reader.readC(); - reader.readC(); + snes.gainMode=(DivInstrumentSNES::GainMode)reader.readC(); + snes.gain=reader.readC(); snes.a=reader.readC(); snes.d=reader.readC(); snes.s=reader.readC(); + snes.sus=snes.s&8; + snes.s&=7; snes.r=reader.readC(); } diff --git a/src/engine/instrument.h b/src/engine/instrument.h index 01323d90..a8283430 100644 --- a/src/engine/instrument.h +++ b/src/engine/instrument.h @@ -527,12 +527,13 @@ struct DivInstrumentSNES { GAIN_MODE_INC_LINEAR=6, GAIN_MODE_INC_INVLOG=7 }; - bool useEnv; + bool useEnv, sus; GainMode gainMode; unsigned char gain; unsigned char a, d, s, r; DivInstrumentSNES(): useEnv(true), + sus(false), gainMode(GAIN_MODE_DIRECT), gain(127), a(15), diff --git a/src/engine/platform/snes.cpp b/src/engine/platform/snes.cpp index 0454ed35..5bd28b19 100644 --- a/src/engine/platform/snes.cpp +++ b/src/engine/platform/snes.cpp @@ -208,7 +208,9 @@ void DivPlatformSNES::tick(bool sysTick) { chan[i].keyOn=false; } if (chan[i].keyOff) { - koff|=(1<snes; + } + chan[c.chan].active=true; + if (chan[c.chan].insChanged || chan[c.chan].state.sus) { writeEnv(c.chan); } if (c.value!=DIV_NOTE_NULL) { @@ -303,19 +308,30 @@ int DivPlatformSNES::dispatch(DivCommand c) { chan[c.chan].freqChanged=true; chan[c.chan].note=c.value; } - chan[c.chan].active=true; chan[c.chan].keyOn=true; chan[c.chan].macroInit(ins); chan[c.chan].insChanged=false; break; } case DIV_CMD_NOTE_OFF: - chan[c.chan].sample=-1; chan[c.chan].active=false; chan[c.chan].keyOff=true; - chan[c.chan].macroInit(NULL); + chan[c.chan].keyOn=false; + if (chan[c.chan].state.sus) { + writeEnv(c.chan); + } else { + chan[c.chan].macroInit(NULL); + } break; case DIV_CMD_NOTE_OFF_ENV: + chan[c.chan].active=false; + chan[c.chan].keyOff=true; + chan[c.chan].keyOn=false; + if (chan[c.chan].state.sus) { + writeEnv(c.chan); + } + chan[c.chan].std.release(); + break; case DIV_CMD_ENV_RELEASE: chan[c.chan].std.release(); break; @@ -537,7 +553,11 @@ void DivPlatformSNES::writeOutVol(int ch) { void DivPlatformSNES::writeEnv(int ch) { if (chan[ch].state.useEnv) { chWrite(ch,5,chan[ch].state.a|(chan[ch].state.d<<4)|0x80); - chWrite(ch,6,chan[ch].state.r|(chan[ch].state.s<<5)); + if (chan[ch].state.sus && chan[ch].active) { + chWrite(ch,6,chan[ch].state.s<<5); + } else { + chWrite(ch,6,chan[ch].state.r|(chan[ch].state.s<<5)); + } } else { chWrite(ch,5,0); switch (chan[ch].state.gainMode) { diff --git a/src/gui/insEdit.cpp b/src/gui/insEdit.cpp index 15434a80..2ab022dd 100644 --- a/src/gui/insEdit.cpp +++ b/src/gui/insEdit.cpp @@ -4066,6 +4066,7 @@ void FurnaceGUI::drawInsEdit() { ImGui::EndTable(); } + ImGui::Checkbox("Make sustain effective",&ins->snes.sus); } else { if (ImGui::BeginTable("SNESGainParams",3,ImGuiTableFlags_NoHostExtendX)) { ImGui::TableSetupColumn("c0",ImGuiTableColumnFlags_WidthFixed);