the final piece of f-num/block work

This commit is contained in:
tildearrow 2022-04-24 14:40:07 -05:00
parent dd9bb8327a
commit 23be8d9336
6 changed files with 41 additions and 13 deletions

View file

@ -29,6 +29,8 @@ furthermore, an `or reserved` indicates this field is always present, but is res
the format versions are: the format versions are:
- 85: Furnace dev85
- 84: Furnace dev84
- 83: Furnace dev83 - 83: Furnace dev83
- 82: Furnace dev82 - 82: Furnace dev82
- 81: Furnace dev81 - 81: Furnace dev81
@ -269,7 +271,9 @@ size | description
1 | ExtCh channel state is shared (>=78) or reserved 1 | ExtCh channel state is shared (>=78) or reserved
1 | ignore DAC mode change outside of intended channel (>=83) or reserved 1 | ignore DAC mode change outside of intended channel (>=83) or reserved
1 | E1xx and E2xx also take priority over Slide00 (>=83) or reserved 1 | E1xx and E2xx also take priority over Slide00 (>=83) or reserved
23 | reserved 1 | new Sega PCM (with macros and proper vol/pan) (>=84) or reserved
1 | weird f-num/block-based chip pitch slides (>=85) or reserved
21 | reserved
``` ```
# instrument # instrument

View file

@ -43,8 +43,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 "dev84" #define DIV_VERSION "dev85"
#define DIV_ENGINE_VERSION 84 #define DIV_ENGINE_VERSION 85
// for imports // for imports
#define DIV_VERSION_MOD 0xff01 #define DIV_VERSION_MOD 0xff01

View file

@ -162,6 +162,7 @@ bool DivEngine::loadDMF(unsigned char* file, size_t len) {
ds.gbInsAffectsEnvelope=true; ds.gbInsAffectsEnvelope=true;
ds.ignoreDACModeOutsideIntendedChannel=false; ds.ignoreDACModeOutsideIntendedChannel=false;
ds.e1e2AlsoTakePriority=true; ds.e1e2AlsoTakePriority=true;
ds.fbPortaPause=true;
// 1.1 compat flags // 1.1 compat flags
if (ds.version>24) { if (ds.version>24) {
@ -993,6 +994,9 @@ bool DivEngine::loadFur(unsigned char* file, size_t len) {
if (ds.version<84) { if (ds.version<84) {
ds.newSegaPCM=false; ds.newSegaPCM=false;
} }
if (ds.version<85) {
ds.fbPortaPause=true;
}
ds.isDMF=false; ds.isDMF=false;
reader.readS(); // reserved reader.readS(); // reserved
@ -1342,7 +1346,12 @@ bool DivEngine::loadFur(unsigned char* file, size_t len) {
} else { } else {
reader.readC(); reader.readC();
} }
for (int i=0; i<22; i++) { if (ds.version>=85) {
ds.fbPortaPause=reader.readC();
} else {
reader.readC();
}
for (int i=0; i<21; i++) {
reader.readC(); reader.readC();
} }
} }
@ -2283,7 +2292,8 @@ SafeWriter* DivEngine::saveFur(bool notPrimary) {
w->writeC(song.ignoreDACModeOutsideIntendedChannel); w->writeC(song.ignoreDACModeOutsideIntendedChannel);
w->writeC(song.e1e2AlsoTakePriority); w->writeC(song.e1e2AlsoTakePriority);
w->writeC(song.newSegaPCM); w->writeC(song.newSegaPCM);
for (int i=0; i<22; i++) { w->writeC(song.fbPortaPause);
for (int i=0; i<21; i++) {
w->writeC(0); w->writeC(0);
} }

View file

@ -149,14 +149,22 @@ int DivPlatformGenesisExt::dispatch(DivCommand c) {
// what the heck! // what the heck!
if (!opChan[ch].portaPause) { if (!opChan[ch].portaPause) {
if ((newFreq&0x7ff)>1288) { if ((newFreq&0x7ff)>1288) {
opChan[ch].portaPauseFreq=(644)|((newFreq+0x800)&0xf800); if (parent->song.fbPortaPause) {
opChan[ch].portaPause=true; opChan[ch].portaPauseFreq=(644)|((newFreq+0x800)&0xf800);
break; opChan[ch].portaPause=true;
break;
} else {
newFreq=(newFreq>>1)|((newFreq+0x800)&0xf800);
}
} }
if ((newFreq&0x7ff)<644) { if ((newFreq&0x7ff)<644) {
opChan[ch].portaPauseFreq=newFreq=(1287)|((newFreq-0x800)&0xf800); if (parent->song.fbPortaPause) {
opChan[ch].portaPause=true; opChan[ch].portaPauseFreq=newFreq=(1287)|((newFreq-0x800)&0xf800);
break; opChan[ch].portaPause=true;
break;
} else {
newFreq=(newFreq<<1)|((newFreq-0x800)&0xf800);
}
} }
} }
opChan[ch].portaPause=false; opChan[ch].portaPause=false;

View file

@ -324,6 +324,7 @@ struct DivSong {
bool ignoreDACModeOutsideIntendedChannel; bool ignoreDACModeOutsideIntendedChannel;
bool e1e2AlsoTakePriority; bool e1e2AlsoTakePriority;
bool newSegaPCM; bool newSegaPCM;
bool fbPortaPause;
DivOrders orders; DivOrders orders;
std::vector<DivInstrument*> ins; std::vector<DivInstrument*> ins;
@ -406,7 +407,8 @@ struct DivSong {
sharedExtStat(true), sharedExtStat(true),
ignoreDACModeOutsideIntendedChannel(false), ignoreDACModeOutsideIntendedChannel(false),
e1e2AlsoTakePriority(false), e1e2AlsoTakePriority(false),
newSegaPCM(true) { newSegaPCM(true),
fbPortaPause(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

@ -101,6 +101,10 @@ void FurnaceGUI::drawCompatFlags() {
if (ImGui::IsItemHovered()) { if (ImGui::IsItemHovered()) {
ImGui::SetTooltip("simulates a bug in where portamento does not work after sliding."); ImGui::SetTooltip("simulates a bug in where portamento does not work after sliding.");
} }
ImGui::Checkbox("FM pitch slide octave boundary odd behavior",&e->song.fbPortaPause);
if (ImGui::IsItemHovered()) {
ImGui::SetTooltip("if this is on, a pitch slide that crosses the octave boundary will stop for one tick and then continue from the nearest octave boundary.\nfor .dmf compatibility.");
}
ImGui::Checkbox("Apply Game Boy envelope on note-less instrument change",&e->song.gbInsAffectsEnvelope); ImGui::Checkbox("Apply Game Boy envelope on note-less instrument change",&e->song.gbInsAffectsEnvelope);
if (ImGui::IsItemHovered()) { if (ImGui::IsItemHovered()) {
ImGui::SetTooltip("if this is on, an instrument change will also affect the envelope."); ImGui::SetTooltip("if this is on, an instrument change will also affect the envelope.");