From 2a0aa19b2b1b9e329ee2bf732f5faae5aabb70d4 Mon Sep 17 00:00:00 2001 From: tildearrow Date: Fri, 11 Mar 2022 22:11:33 -0500 Subject: [PATCH] fix broken DAC mode adds new compat flag --- papers/format.md | 4 +++- src/engine/engine.h | 4 ++-- src/engine/fileOps.cpp | 14 ++++++++++++-- src/engine/platform/genesis.cpp | 12 ++++++++++++ src/engine/song.h | 4 +++- src/gui/gui.cpp | 4 ++++ 6 files changed, 36 insertions(+), 6 deletions(-) diff --git a/papers/format.md b/papers/format.md index 7bc30abe..882c5d8c 100644 --- a/papers/format.md +++ b/papers/format.md @@ -29,6 +29,7 @@ furthermore, an `or reserved` indicates this field is always present, but is res the format versions are: +- 64: Furnace dev64 - 63: Furnace dev63 - 62: Furnace dev62 - 61: Furnace dev61 @@ -203,7 +204,8 @@ size | description 1 | ignore duplicate slides (>=50) or reserved 1 | stop portamento on note off (>=62) or reserved 1 | continuous vibrato (>=62) or reserved - 4 | reserved + 1 | broken DAC mode (>=64) or reserved + 3 | reserved 4?? | pointers to instruments 4?? | pointers to wavetables 4?? | pointers to samples diff --git a/src/engine/engine.h b/src/engine/engine.h index d16a987c..29d5a779 100644 --- a/src/engine/engine.h +++ b/src/engine/engine.h @@ -37,8 +37,8 @@ warnings+=(String("\n")+x); \ } -#define DIV_VERSION "dev63" -#define DIV_ENGINE_VERSION 63 +#define DIV_VERSION "dev64" +#define DIV_ENGINE_VERSION 64 enum DivStatusView { DIV_STATUS_NOTHING=0, diff --git a/src/engine/fileOps.cpp b/src/engine/fileOps.cpp index 3a79cebe..9a927fdd 100644 --- a/src/engine/fileOps.cpp +++ b/src/engine/fileOps.cpp @@ -140,6 +140,7 @@ bool DivEngine::loadDMF(unsigned char* file, size_t len) { ds.algMacroBehavior=false; ds.brokenShortcutSlides=false; ds.ignoreDuplicateSlides=true; + ds.brokenDACMode=true; // 1.1 compat flags if (ds.version>24) { @@ -799,6 +800,9 @@ bool DivEngine::loadFur(unsigned char* file, size_t len) { if (ds.version<62) { ds.stopPortaOnNoteOff=true; } + if (ds.version<64) { + ds.brokenDACMode=false; + } ds.isDMF=false; reader.readS(); // reserved @@ -975,7 +979,12 @@ bool DivEngine::loadFur(unsigned char* file, size_t len) { reader.readC(); reader.readC(); } - for (int i=0; i<4; i++) reader.readC(); + if (ds.version>=64) { + ds.brokenDACMode=reader.readC(); + } else { + reader.readC(); + } + for (int i=0; i<3; i++) reader.readC(); } else { for (int i=0; i<20; i++) reader.readC(); } @@ -1417,7 +1426,8 @@ SafeWriter* DivEngine::saveFur() { w->writeC(song.ignoreDuplicateSlides); w->writeC(song.stopPortaOnNoteOff); w->writeC(song.continuousVibrato); - for (int i=0; i<4; i++) { + w->writeC(song.brokenDACMode); + for (int i=0; i<3; i++) { w->writeC(0); } diff --git a/src/engine/platform/genesis.cpp b/src/engine/platform/genesis.cpp index 16c44ae5..aefde827 100644 --- a/src/engine/platform/genesis.cpp +++ b/src/engine/platform/genesis.cpp @@ -99,6 +99,9 @@ void DivPlatformGenesis::acquire_nuked(short* bufL, short* bufR, size_t start, s dacPos=s->loopStart; } else { dacSample=-1; + if (parent->song.brokenDACMode) { + rWrite(0x2b,0); + } } } dacPeriod+=MAX(40,dacRate); @@ -163,6 +166,9 @@ void DivPlatformGenesis::acquire_ymfm(short* bufL, short* bufR, size_t start, si dacPos=s->loopStart; } else { dacSample=-1; + if (parent->song.brokenDACMode) { + rWrite(0x2b,0); + } } } dacPeriod+=MAX(40,dacRate); @@ -460,6 +466,7 @@ int DivPlatformGenesis::dispatch(DivCommand c) { if (dumpWrites) addWrite(0xffff0002,0); break; } else { + rWrite(0x2b,1<<7); if (dumpWrites) addWrite(0xffff0000,dacSample); } dacPos=0; @@ -477,6 +484,7 @@ int DivPlatformGenesis::dispatch(DivCommand c) { if (dumpWrites) addWrite(0xffff0002,0); break; } else { + rWrite(0x2b,1<<7); if (dumpWrites) addWrite(0xffff0000,dacSample); } dacPos=0; @@ -541,6 +549,10 @@ int DivPlatformGenesis::dispatch(DivCommand c) { if (c.chan==5) { dacSample=-1; if (dumpWrites) addWrite(0xffff0002,0); + if (parent->song.brokenDACMode) { + rWrite(0x2b,0); + break; + } } chan[c.chan].keyOff=true; chan[c.chan].keyOn=false; diff --git a/src/engine/song.h b/src/engine/song.h index 2eb4fe5d..44b02732 100644 --- a/src/engine/song.h +++ b/src/engine/song.h @@ -295,6 +295,7 @@ struct DivSong { bool ignoreDuplicateSlides; bool stopPortaOnNoteOff; bool continuousVibrato; + bool brokenDACMode; DivOrders orders; std::vector ins; @@ -359,7 +360,8 @@ struct DivSong { brokenShortcutSlides(false), ignoreDuplicateSlides(false), stopPortaOnNoteOff(false), - continuousVibrato(false) { + continuousVibrato(false), + brokenDACMode(false) { for (int i=0; i<32; i++) { system[i]=DIV_SYSTEM_NULL; systemVol[i]=64; diff --git a/src/gui/gui.cpp b/src/gui/gui.cpp index 657aa9e4..a1f176fa 100644 --- a/src/gui/gui.cpp +++ b/src/gui/gui.cpp @@ -2115,6 +2115,10 @@ void FurnaceGUI::drawCompatFlags() { if (ImGui::IsItemHovered()) { ImGui::SetTooltip("when enabled, vibrato will not be reset on a new note."); } + ImGui::Checkbox("Broken DAC mode",&e->song.brokenDACMode); + if (ImGui::IsItemHovered()) { + ImGui::SetTooltip("when enabled, the DAC in YM2612 will be disabled if there isn't any sample playing."); + } ImGui::Text("Loop modality:"); if (ImGui::RadioButton("Reset channels",e->song.loopModality==0)) {