add two more compatibility flags
for songs that relied upon pre-0.5.5 broken behavior
This commit is contained in:
parent
e115d9e23b
commit
62f2f67b9d
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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]) {
|
||||
|
|
|
@ -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]) {
|
||||
|
|
|
@ -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]) {
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue