add two more compatibility flags

for songs that relied upon pre-0.5.5 broken behavior
This commit is contained in:
tildearrow 2022-02-09 22:07:32 -05:00
parent e115d9e23b
commit 62f2f67b9d
9 changed files with 55 additions and 13 deletions

View File

@ -25,6 +25,8 @@ furthermore, an `or reserved` indicates this field is always present, but is res
the format versions are:
- 47: Furnace 0.5.6pre1
- 46: Furnace 0.5.5
- 45: Furnace 0.5.5pre3
- 44: Furnace 0.5.5pre2
- 43: Furnace 0.5.5pre1
@ -161,7 +163,9 @@ size | description
1 | compatible arpeggio (>=45) or reserved
1 | note off resets slides (>=45) or reserved
1 | target resets slides (>=45) or reserved
10 | reserved
1 | arpeggio inhibits portamento (>=47) or reserved
1 | wack algorithm macro (>=47) or reserved
8 | reserved
4?? | pointers to instruments
4?? | pointers to wavetables
4?? | pointers to samples

View File

@ -1551,6 +1551,8 @@ bool DivEngine::loadDMF(unsigned char* file, size_t len) {
ds.compatibleArpeggio=true;
ds.noteOffResetsSlides=true;
ds.targetResetsSlides=true;
ds.arpNonPorta=false;
ds.algMacroBehavior=false;
// Neo Geo detune
if (ds.system[0]==DIV_SYSTEM_YM2610 || ds.system[0]==DIV_SYSTEM_YM2610_EXT) {
@ -2093,6 +2095,13 @@ bool DivEngine::loadFur(unsigned char* file, size_t len) {
ds.noteOffResetsSlides=true;
ds.targetResetsSlides=true;
}
if (ds.version<46) {
ds.arpNonPorta=true;
ds.algMacroBehavior=true;
} else {
ds.arpNonPorta=false;
ds.algMacroBehavior=false;
}
reader.readS(); // reserved
int infoSeek=reader.readI();
@ -2200,7 +2209,17 @@ bool DivEngine::loadFur(unsigned char* file, size_t len) {
} else {
reader.readC();
}
for (int i=0; i<10; i++) reader.readC();
if (ds.version>=47) {
ds.arpNonPorta=reader.readC();
} else {
reader.readC();
}
if (ds.version>=47) {
ds.algMacroBehavior=reader.readC();
} else {
reader.readC();
}
for (int i=0; i<8; i++) reader.readC();
} else {
for (int i=0; i<20; i++) reader.readC();
}
@ -2581,7 +2600,9 @@ SafeWriter* DivEngine::saveFur() {
w->writeC(song.compatibleArpeggio);
w->writeC(song.noteOffResetsSlides);
w->writeC(song.targetResetsSlides);
for (int i=0; i<10; i++) {
w->writeC(song.arpNonPorta);
w->writeC(song.algMacroBehavior);
for (int i=0; i<8; i++) {
w->writeC(0);
}

View File

@ -11,8 +11,8 @@
#include <map>
#include <queue>
#define DIV_VERSION "0.5.5"
#define DIV_ENGINE_VERSION 46
#define DIV_VERSION "0.5.6pre1"
#define DIV_ENGINE_VERSION 47
enum DivStatusView {
DIV_STATUS_NOTHING=0,

View File

@ -276,7 +276,7 @@ void DivPlatformArcade::tick() {
} else {
rWrite(chanOffs[i]+ADDR_LR_FB_ALG,(chan[i].state.alg&7)|(chan[i].state.fb<<3)|((chan[i].chVolL&1)<<6)|((chan[i].chVolR&1)<<7));
}
for (int j=0; j<4; j++) {
if (!parent->song.algMacroBehavior) for (int j=0; j<4; j++) {
unsigned short baseAddr=chanOffs[i]|opOffs[j];
DivInstrumentFM::Operator& op=chan[i].state.op[j];
if (isMuted[i]) {

View File

@ -201,7 +201,7 @@ void DivPlatformGenesis::tick() {
if (chan[i].std.hadAlg) {
chan[i].state.alg=chan[i].std.alg;
rWrite(chanOffs[i]+ADDR_FB_ALG,(chan[i].state.alg&7)|(chan[i].state.fb<<3));
for (int j=0; j<4; j++) {
if (!parent->song.algMacroBehavior) for (int j=0; j<4; j++) {
unsigned short baseAddr=chanOffs[i]|opOffs[j];
DivInstrumentFM::Operator& op=chan[i].state.op[j];
if (isMuted[i]) {

View File

@ -183,7 +183,7 @@ void DivPlatformYM2610::tick() {
if (chan[i].std.hadAlg) {
chan[i].state.alg=chan[i].std.alg;
rWrite(chanOffs[i]+ADDR_FB_ALG,(chan[i].state.alg&7)|(chan[i].state.fb<<3));
for (int j=0; j<4; j++) {
if (!parent->song.algMacroBehavior) for (int j=0; j<4; j++) {
unsigned short baseAddr=chanOffs[i]|opOffs[j];
DivInstrumentFM::Operator& op=chan[i].state.op[j];
if (isMuted[i]) {

View File

@ -565,7 +565,7 @@ void DivEngine::processRow(int i, bool afterDelay) {
chan[i].portaNote=-1;
chan[i].portaSpeed=-1;
chan[i].inPorta=false;
dispatchCmd(DivCommand(DIV_CMD_PRE_PORTA,i,false,0));
if (!song.arpNonPorta) dispatchCmd(DivCommand(DIV_CMD_PRE_PORTA,i,false,0));
} else {
chan[i].portaNote=song.limitSlides?0x60:255;
chan[i].portaSpeed=effectVal;
@ -574,7 +574,7 @@ void DivEngine::processRow(int i, bool afterDelay) {
chan[i].stopOnOff=false;
chan[i].scheduledSlideReset=false;
chan[i].inPorta=false;
dispatchCmd(DivCommand(DIV_CMD_PRE_PORTA,i,true,0));
if (!song.arpNonPorta) dispatchCmd(DivCommand(DIV_CMD_PRE_PORTA,i,true,0));
}
break;
case 0x02: // ramp down
@ -582,7 +582,7 @@ void DivEngine::processRow(int i, bool afterDelay) {
chan[i].portaNote=-1;
chan[i].portaSpeed=-1;
chan[i].inPorta=false;
dispatchCmd(DivCommand(DIV_CMD_PRE_PORTA,i,false,0));
if (!song.arpNonPorta) dispatchCmd(DivCommand(DIV_CMD_PRE_PORTA,i,false,0));
} else {
chan[i].portaNote=song.limitSlides?disCont[dispatchOfChan[i]].dispatch->getPortaFloor(dispatchChanOfChan[i]):-60;
chan[i].portaSpeed=effectVal;
@ -591,7 +591,7 @@ void DivEngine::processRow(int i, bool afterDelay) {
chan[i].stopOnOff=false;
chan[i].scheduledSlideReset=false;
chan[i].inPorta=false;
dispatchCmd(DivCommand(DIV_CMD_PRE_PORTA,i,true,0));
if (!song.arpNonPorta) dispatchCmd(DivCommand(DIV_CMD_PRE_PORTA,i,true,0));
}
break;
case 0x03: // portamento

View File

@ -224,6 +224,8 @@ struct DivSong {
bool compatibleArpeggio;
bool noteOffResetsSlides;
bool targetResetsSlides;
bool arpNonPorta;
bool algMacroBehavior;
DivOrders orders;
std::vector<DivInstrument*> ins;
@ -279,7 +281,9 @@ struct DivSong {
legacyVolumeSlides(false),
compatibleArpeggio(false),
noteOffResetsSlides(true),
targetResetsSlides(true) {
targetResetsSlides(true),
arpNonPorta(false),
algMacroBehavior(false) {
for (int i=0; i<32; i++) {
system[i]=DIV_SYSTEM_NULL;
systemVol[i]=64;

View File

@ -3997,6 +3997,19 @@ void FurnaceGUI::drawCompatFlags() {
if (ImGui::IsItemHovered()) {
ImGui::SetTooltip("select to not reset channels on loop.");
}
ImGui::Separator();
ImGui::TextWrapped("the following flags are for compatibility with older Furnace versions.");
ImGui::Checkbox("Arpeggio inhibits non-porta slides",&e->song.arpNonPorta);
if (ImGui::IsItemHovered()) {
ImGui::SetTooltip("behavior changed in 0.5.5");
}
ImGui::Checkbox("Wack FM algorithm macro",&e->song.algMacroBehavior);
if (ImGui::IsItemHovered()) {
ImGui::SetTooltip("behavior changed in 0.5.5");
}
}
ImGui::End();
}