yay for more compatibility flags

ignore duplicate slides on .dmf
This commit is contained in:
tildearrow 2022-02-18 02:03:31 -05:00
parent 86e5b77981
commit ce2af4303e
6 changed files with 32 additions and 6 deletions

View file

@ -25,6 +25,9 @@ furthermore, an `or reserved` indicates this field is always present, but is res
the format versions are: the format versions are:
- 50: Furnace 0.5.7pre2
- 49: Furnace 0.5.7pre1
- 48: Furnace 0.5.6
- 47: Furnace 0.5.6pre1 - 47: Furnace 0.5.6pre1
- 46: Furnace 0.5.5 - 46: Furnace 0.5.5
- 45: Furnace 0.5.5pre3 - 45: Furnace 0.5.5pre3
@ -166,7 +169,8 @@ size | description
1 | arpeggio inhibits portamento (>=47) or reserved 1 | arpeggio inhibits portamento (>=47) or reserved
1 | wack algorithm macro (>=47) or reserved 1 | wack algorithm macro (>=47) or reserved
1 | broken shortcut slides (>=49) or reserved 1 | broken shortcut slides (>=49) or reserved
8 | reserved 1 | ignore duplicate slides (>=50) or reserved
6 | reserved
4?? | pointers to instruments 4?? | pointers to instruments
4?? | pointers to wavetables 4?? | pointers to wavetables
4?? | pointers to samples 4?? | pointers to samples

View file

@ -1565,6 +1565,7 @@ bool DivEngine::loadDMF(unsigned char* file, size_t len) {
ds.arpNonPorta=false; ds.arpNonPorta=false;
ds.algMacroBehavior=false; ds.algMacroBehavior=false;
ds.brokenShortcutSlides=false; ds.brokenShortcutSlides=false;
ds.ignoreDuplicateSlides=true;
// Neo Geo detune // Neo Geo detune
if (ds.system[0]==DIV_SYSTEM_YM2610 || ds.system[0]==DIV_SYSTEM_YM2610_EXT) { if (ds.system[0]==DIV_SYSTEM_YM2610 || ds.system[0]==DIV_SYSTEM_YM2610_EXT) {
@ -2117,6 +2118,9 @@ bool DivEngine::loadFur(unsigned char* file, size_t len) {
if (ds.version<49) { if (ds.version<49) {
ds.brokenShortcutSlides=true; ds.brokenShortcutSlides=true;
} }
if (ds.version<50) {
ds.ignoreDuplicateSlides=false;
}
reader.readS(); // reserved reader.readS(); // reserved
int infoSeek=reader.readI(); int infoSeek=reader.readI();
@ -2239,7 +2243,12 @@ bool DivEngine::loadFur(unsigned char* file, size_t len) {
} else { } else {
reader.readC(); reader.readC();
} }
for (int i=0; i<7; i++) reader.readC(); if (ds.version>=50) {
ds.ignoreDuplicateSlides=reader.readC();
} else {
reader.readC();
}
for (int i=0; i<6; i++) reader.readC();
} else { } else {
for (int i=0; i<20; i++) reader.readC(); for (int i=0; i<20; i++) reader.readC();
} }
@ -2623,7 +2632,8 @@ SafeWriter* DivEngine::saveFur() {
w->writeC(song.arpNonPorta); w->writeC(song.arpNonPorta);
w->writeC(song.algMacroBehavior); w->writeC(song.algMacroBehavior);
w->writeC(song.brokenShortcutSlides); w->writeC(song.brokenShortcutSlides);
for (int i=0; i<7; i++) { w->writeC(song.ignoreDuplicateSlides);
for (int i=0; i<6; i++) {
w->writeC(0); w->writeC(0);
} }

View file

@ -30,8 +30,8 @@
#include <map> #include <map>
#include <queue> #include <queue>
#define DIV_VERSION "0.5.7pre1" #define DIV_VERSION "0.5.7pre2"
#define DIV_ENGINE_VERSION 49 #define DIV_ENGINE_VERSION 50
enum DivStatusView { enum DivStatusView {
DIV_STATUS_NOTHING=0, DIV_STATUS_NOTHING=0,

View file

@ -552,6 +552,8 @@ void DivEngine::processRow(int i, bool afterDelay) {
chan[i].retrigSpeed=0; chan[i].retrigSpeed=0;
short lastSlide=-1;
// effects // effects
for (int j=0; j<song.pat[i].effectRows; j++) { for (int j=0; j<song.pat[i].effectRows; j++) {
short effect=pat->data[whatRow][4+(j<<1)]; short effect=pat->data[whatRow][4+(j<<1)];
@ -583,6 +585,8 @@ void DivEngine::processRow(int i, bool afterDelay) {
dispatchCmd(DivCommand(DIV_CMD_PANNING,i,effectVal)); dispatchCmd(DivCommand(DIV_CMD_PANNING,i,effectVal));
break; break;
case 0x01: // ramp up case 0x01: // ramp up
if (song.ignoreDuplicateSlides && lastSlide==0x01) break;
lastSlide=0x01;
if (effectVal==0) { if (effectVal==0) {
chan[i].portaNote=-1; chan[i].portaNote=-1;
chan[i].portaSpeed=-1; chan[i].portaSpeed=-1;
@ -600,6 +604,8 @@ void DivEngine::processRow(int i, bool afterDelay) {
} }
break; break;
case 0x02: // ramp down case 0x02: // ramp down
if (song.ignoreDuplicateSlides && lastSlide==0x02) break;
lastSlide=0x02;
if (effectVal==0) { if (effectVal==0) {
chan[i].portaNote=-1; chan[i].portaNote=-1;
chan[i].portaSpeed=-1; chan[i].portaSpeed=-1;

View file

@ -246,6 +246,7 @@ struct DivSong {
bool arpNonPorta; bool arpNonPorta;
bool algMacroBehavior; bool algMacroBehavior;
bool brokenShortcutSlides; bool brokenShortcutSlides;
bool ignoreDuplicateSlides;
DivOrders orders; DivOrders orders;
std::vector<DivInstrument*> ins; std::vector<DivInstrument*> ins;
@ -304,7 +305,8 @@ struct DivSong {
targetResetsSlides(true), targetResetsSlides(true),
arpNonPorta(false), arpNonPorta(false),
algMacroBehavior(false), algMacroBehavior(false),
brokenShortcutSlides(false) { brokenShortcutSlides(false),
ignoreDuplicateSlides(false) {
for (int i=0; i<32; i++) { for (int i=0; i<32; i++) {
system[i]=DIV_SYSTEM_NULL; system[i]=DIV_SYSTEM_NULL;
systemVol[i]=64; systemVol[i]=64;

View file

@ -1810,6 +1810,10 @@ void FurnaceGUI::drawCompatFlags() {
if (ImGui::IsItemHovered()) { if (ImGui::IsItemHovered()) {
ImGui::SetTooltip("when enabled, the slide effect is disabled after it reaches its target."); ImGui::SetTooltip("when enabled, the slide effect is disabled after it reaches its target.");
} }
ImGui::Checkbox("Ignore duplicate slide effects",&e->song.ignoreDuplicateSlides);
if (ImGui::IsItemHovered()) {
ImGui::SetTooltip("if this is on, only the first slide of a row in a channel will be considered.");
}
ImGui::Text("Loop modality:"); ImGui::Text("Loop modality:");
if (ImGui::RadioButton("Reset channels",e->song.loopModality==0)) { if (ImGui::RadioButton("Reset channels",e->song.loopModality==0)) {