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