dev97 - add old octave boundary compat flag
This commit is contained in:
parent
b40c95013a
commit
393d1c018d
|
@ -29,6 +29,7 @@ furthermore, an `or reserved` indicates this field is always present, but is res
|
|||
|
||||
the format versions are:
|
||||
|
||||
- 97: Furnace dev97
|
||||
- 96: Furnace dev96
|
||||
- 95: Furnace dev95
|
||||
- 94: Furnace dev94
|
||||
|
@ -300,7 +301,8 @@ size | description
|
|||
1 | SN duty macro always resets phase (>=86) or reserved
|
||||
1 | pitch macro is linear (>=90) or reserved
|
||||
1 | pitch slide speed in full linear pitch mode (>=94) or reserved
|
||||
14 | reserved
|
||||
1 | old octave boundary behavior (>=97) or reserved
|
||||
13 | reserved
|
||||
--- | **virtual tempo data**
|
||||
2 | virtual tempo numerator of first song (>=96) or reserved
|
||||
2 | virtual tempo denominator of first song (>=96) or reserved
|
||||
|
|
|
@ -45,8 +45,8 @@
|
|||
#define BUSY_BEGIN_SOFT softLocked=true; isBusy.lock();
|
||||
#define BUSY_END isBusy.unlock(); softLocked=false;
|
||||
|
||||
#define DIV_VERSION "dev96"
|
||||
#define DIV_ENGINE_VERSION 96
|
||||
#define DIV_VERSION "dev97"
|
||||
#define DIV_ENGINE_VERSION 97
|
||||
|
||||
// for imports
|
||||
#define DIV_VERSION_MOD 0xff01
|
||||
|
|
|
@ -166,6 +166,7 @@ bool DivEngine::loadDMF(unsigned char* file, size_t len) {
|
|||
ds.e1e2AlsoTakePriority=true;
|
||||
ds.fbPortaPause=true;
|
||||
ds.snDutyReset=true;
|
||||
ds.oldOctaveBoundary=false;
|
||||
|
||||
// 1.1 compat flags
|
||||
if (ds.version>24) {
|
||||
|
@ -1027,6 +1028,9 @@ bool DivEngine::loadFur(unsigned char* file, size_t len) {
|
|||
if (ds.version<90) {
|
||||
ds.pitchMacroIsLinear=false;
|
||||
}
|
||||
if (ds.version<97) {
|
||||
ds.oldOctaveBoundary=true;
|
||||
}
|
||||
ds.isDMF=false;
|
||||
|
||||
reader.readS(); // reserved
|
||||
|
@ -1404,7 +1408,12 @@ bool DivEngine::loadFur(unsigned char* file, size_t len) {
|
|||
} else {
|
||||
reader.readC();
|
||||
}
|
||||
for (int i=0; i<14; i++) {
|
||||
if (ds.version>=97) {
|
||||
ds.oldOctaveBoundary=reader.readC();
|
||||
} else {
|
||||
reader.readC();
|
||||
}
|
||||
for (int i=0; i<13; i++) {
|
||||
reader.readC();
|
||||
}
|
||||
}
|
||||
|
@ -2871,7 +2880,8 @@ SafeWriter* DivEngine::saveFur(bool notPrimary) {
|
|||
w->writeC(song.snDutyReset);
|
||||
w->writeC(song.pitchMacroIsLinear);
|
||||
w->writeC(song.pitchSlideSpeed);
|
||||
for (int i=0; i<14; i++) {
|
||||
w->writeC(song.oldOctaveBoundary);
|
||||
for (int i=0; i<13; i++) {
|
||||
w->writeC(0);
|
||||
}
|
||||
|
||||
|
|
|
@ -781,14 +781,22 @@ int DivPlatformGenesis::dispatch(DivCommand c) {
|
|||
// what the heck!
|
||||
if (!chan[c.chan].portaPause) {
|
||||
if ((newFreq&0x7ff)>boundaryTop && (newFreq&0xf800)<0x3800) {
|
||||
chan[c.chan].portaPauseFreq=(boundaryBottom)|((newFreq+0x800)&0xf800);
|
||||
chan[c.chan].portaPause=true;
|
||||
break;
|
||||
if (parent->song.fbPortaPause) {
|
||||
chan[c.chan].portaPauseFreq=(parent->song.oldOctaveBoundary?(newFreq>>1):boundaryBottom)|((newFreq+0x800)&0xf800);
|
||||
chan[c.chan].portaPause=true;
|
||||
break;
|
||||
} else {
|
||||
newFreq=(newFreq>>1)|((newFreq+0x800)&0xf800);
|
||||
}
|
||||
}
|
||||
if ((newFreq&0x7ff)<boundaryBottom && (newFreq&0xf800)>0) {
|
||||
chan[c.chan].portaPauseFreq=newFreq=(boundaryTop-1)|((newFreq-0x800)&0xf800);
|
||||
chan[c.chan].portaPause=true;
|
||||
break;
|
||||
if (parent->song.fbPortaPause) {
|
||||
chan[c.chan].portaPauseFreq=newFreq=(parent->song.oldOctaveBoundary?(newFreq<<1):(boundaryTop-1))|((newFreq-0x800)&0xf800);
|
||||
chan[c.chan].portaPause=true;
|
||||
break;
|
||||
} else {
|
||||
newFreq=(newFreq<<1)|((newFreq-0x800)&0xf800);
|
||||
}
|
||||
}
|
||||
}
|
||||
chan[c.chan].portaPause=false;
|
||||
|
|
|
@ -684,14 +684,22 @@ int DivPlatformYM2203::dispatch(DivCommand c) {
|
|||
// what the heck!
|
||||
if (!chan[c.chan].portaPause) {
|
||||
if ((newFreq&0x7ff)>boundaryTop && (newFreq&0xf800)<0x3800) {
|
||||
chan[c.chan].portaPauseFreq=(boundaryBottom)|((newFreq+0x800)&0xf800);
|
||||
chan[c.chan].portaPause=true;
|
||||
break;
|
||||
if (parent->song.fbPortaPause) {
|
||||
chan[c.chan].portaPauseFreq=(parent->song.oldOctaveBoundary?(newFreq>>1):boundaryBottom)|((newFreq+0x800)&0xf800);
|
||||
chan[c.chan].portaPause=true;
|
||||
break;
|
||||
} else {
|
||||
newFreq=(newFreq>>1)|((newFreq+0x800)&0xf800);
|
||||
}
|
||||
}
|
||||
if ((newFreq&0x7ff)<boundaryBottom && (newFreq&0xf800)>0) {
|
||||
chan[c.chan].portaPauseFreq=newFreq=(boundaryTop-1)|((newFreq-0x800)&0xf800);
|
||||
chan[c.chan].portaPause=true;
|
||||
break;
|
||||
if (parent->song.fbPortaPause) {
|
||||
chan[c.chan].portaPauseFreq=newFreq=(parent->song.oldOctaveBoundary?(newFreq<<1):(boundaryTop-1))|((newFreq-0x800)&0xf800);
|
||||
chan[c.chan].portaPause=true;
|
||||
break;
|
||||
} else {
|
||||
newFreq=(newFreq<<1)|((newFreq-0x800)&0xf800);
|
||||
}
|
||||
}
|
||||
}
|
||||
chan[c.chan].portaPause=false;
|
||||
|
|
|
@ -1005,14 +1005,22 @@ int DivPlatformYM2608::dispatch(DivCommand c) {
|
|||
// what the heck!
|
||||
if (!chan[c.chan].portaPause) {
|
||||
if ((newFreq&0x7ff)>boundaryTop && (newFreq&0xf800)<0x3800) {
|
||||
chan[c.chan].portaPauseFreq=(boundaryBottom)|((newFreq+0x800)&0xf800);
|
||||
chan[c.chan].portaPause=true;
|
||||
break;
|
||||
if (parent->song.fbPortaPause) {
|
||||
chan[c.chan].portaPauseFreq=(parent->song.oldOctaveBoundary?(newFreq>>1):boundaryBottom)|((newFreq+0x800)&0xf800);
|
||||
chan[c.chan].portaPause=true;
|
||||
break;
|
||||
} else {
|
||||
newFreq=(newFreq>>1)|((newFreq+0x800)&0xf800);
|
||||
}
|
||||
}
|
||||
if ((newFreq&0x7ff)<boundaryBottom && (newFreq&0xf800)>0) {
|
||||
chan[c.chan].portaPauseFreq=newFreq=(boundaryTop-1)|((newFreq-0x800)&0xf800);
|
||||
chan[c.chan].portaPause=true;
|
||||
break;
|
||||
if (parent->song.fbPortaPause) {
|
||||
chan[c.chan].portaPauseFreq=newFreq=(parent->song.oldOctaveBoundary?(newFreq<<1):(boundaryTop-1))|((newFreq-0x800)&0xf800);
|
||||
chan[c.chan].portaPause=true;
|
||||
break;
|
||||
} else {
|
||||
newFreq=(newFreq<<1)|((newFreq-0x800)&0xf800);
|
||||
}
|
||||
}
|
||||
}
|
||||
chan[c.chan].portaPause=false;
|
||||
|
|
|
@ -1052,14 +1052,22 @@ int DivPlatformYM2610::dispatch(DivCommand c) {
|
|||
// what the heck!
|
||||
if (!chan[c.chan].portaPause) {
|
||||
if ((newFreq&0x7ff)>boundaryTop && (newFreq&0xf800)<0x3800) {
|
||||
chan[c.chan].portaPauseFreq=(boundaryBottom)|((newFreq+0x800)&0xf800);
|
||||
chan[c.chan].portaPause=true;
|
||||
break;
|
||||
if (parent->song.fbPortaPause) {
|
||||
chan[c.chan].portaPauseFreq=(parent->song.oldOctaveBoundary?(newFreq>>1):boundaryBottom)|((newFreq+0x800)&0xf800);
|
||||
chan[c.chan].portaPause=true;
|
||||
break;
|
||||
} else {
|
||||
newFreq=(newFreq>>1)|((newFreq+0x800)&0xf800);
|
||||
}
|
||||
}
|
||||
if ((newFreq&0x7ff)<boundaryBottom && (newFreq&0xf800)>0) {
|
||||
chan[c.chan].portaPauseFreq=newFreq=(boundaryTop-1)|((newFreq-0x800)&0xf800);
|
||||
chan[c.chan].portaPause=true;
|
||||
break;
|
||||
if (parent->song.fbPortaPause) {
|
||||
chan[c.chan].portaPauseFreq=newFreq=(parent->song.oldOctaveBoundary?(newFreq<<1):(boundaryTop-1))|((newFreq-0x800)&0xf800);
|
||||
chan[c.chan].portaPause=true;
|
||||
break;
|
||||
} else {
|
||||
newFreq=(newFreq<<1)|((newFreq-0x800)&0xf800);
|
||||
}
|
||||
}
|
||||
}
|
||||
chan[c.chan].portaPause=false;
|
||||
|
|
|
@ -1030,14 +1030,22 @@ int DivPlatformYM2610B::dispatch(DivCommand c) {
|
|||
// what the heck!
|
||||
if (!chan[c.chan].portaPause) {
|
||||
if ((newFreq&0x7ff)>boundaryTop && (newFreq&0xf800)<0x3800) {
|
||||
chan[c.chan].portaPauseFreq=(boundaryBottom)|((newFreq+0x800)&0xf800);
|
||||
chan[c.chan].portaPause=true;
|
||||
break;
|
||||
if (parent->song.fbPortaPause) {
|
||||
chan[c.chan].portaPauseFreq=(parent->song.oldOctaveBoundary?(newFreq>>1):boundaryBottom)|((newFreq+0x800)&0xf800);
|
||||
chan[c.chan].portaPause=true;
|
||||
break;
|
||||
} else {
|
||||
newFreq=(newFreq>>1)|((newFreq+0x800)&0xf800);
|
||||
}
|
||||
}
|
||||
if ((newFreq&0x7ff)<boundaryBottom && (newFreq&0xf800)>0) {
|
||||
chan[c.chan].portaPauseFreq=newFreq=(boundaryTop-1)|((newFreq-0x800)&0xf800);
|
||||
chan[c.chan].portaPause=true;
|
||||
break;
|
||||
if (parent->song.fbPortaPause) {
|
||||
chan[c.chan].portaPauseFreq=newFreq=(parent->song.oldOctaveBoundary?(newFreq<<1):(boundaryTop-1))|((newFreq-0x800)&0xf800);
|
||||
chan[c.chan].portaPause=true;
|
||||
break;
|
||||
} else {
|
||||
newFreq=(newFreq<<1)|((newFreq-0x800)&0xf800);
|
||||
}
|
||||
}
|
||||
}
|
||||
chan[c.chan].portaPause=false;
|
||||
|
|
|
@ -393,6 +393,7 @@ struct DivSong {
|
|||
bool fbPortaPause;
|
||||
bool snDutyReset;
|
||||
bool pitchMacroIsLinear;
|
||||
bool oldOctaveBoundary;
|
||||
|
||||
std::vector<DivInstrument*> ins;
|
||||
std::vector<DivWavetable*> wave;
|
||||
|
@ -485,7 +486,8 @@ struct DivSong {
|
|||
newSegaPCM(true),
|
||||
fbPortaPause(false),
|
||||
snDutyReset(false),
|
||||
pitchMacroIsLinear(true) {
|
||||
pitchMacroIsLinear(true),
|
||||
oldOctaveBoundary(false) {
|
||||
for (int i=0; i<32; i++) {
|
||||
system[i]=DIV_SYSTEM_NULL;
|
||||
systemVol[i]=64;
|
||||
|
|
|
@ -209,6 +209,10 @@ void FurnaceGUI::drawCompatFlags() {
|
|||
if (ImGui::IsItemHovered()) {
|
||||
ImGui::SetTooltip("behavior changed in 0.6");
|
||||
}
|
||||
ImGui::Checkbox("Old FM octave boundary behavior",&e->song.oldOctaveBoundary);
|
||||
if (ImGui::IsItemHovered()) {
|
||||
ImGui::SetTooltip("behavior changed in 0.6");
|
||||
}
|
||||
}
|
||||
if (ImGui::IsWindowFocused(ImGuiFocusedFlags_ChildWindows)) curWindow=GUI_WINDOW_COMPAT_FLAGS;
|
||||
ImGui::End();
|
||||
|
|
Loading…
Reference in New Issue