mirror of
https://github.com/tildearrow/furnace.git
synced 2024-12-04 18:27:25 +00:00
add two more compatibility flags
issue #167 and #249: - stop porta on note off - continuous vibrato
This commit is contained in:
parent
742e813e98
commit
8e5b3abab8
6 changed files with 39 additions and 10 deletions
|
@ -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:
|
||||||
|
|
||||||
|
- 62: Furnace dev62
|
||||||
- 61: Furnace dev61
|
- 61: Furnace dev61
|
||||||
- 60: Furnace dev60
|
- 60: Furnace dev60
|
||||||
- 59: Furnace dev59
|
- 59: Furnace dev59
|
||||||
|
@ -197,7 +198,9 @@ size | description
|
||||||
1 | wack algorithm macro (>=47) or reserved
|
1 | wack algorithm macro (>=47) or reserved
|
||||||
1 | broken shortcut slides (>=49) or reserved
|
1 | broken shortcut slides (>=49) or reserved
|
||||||
1 | ignore duplicate slides (>=50) or reserved
|
1 | ignore duplicate slides (>=50) or reserved
|
||||||
6 | reserved
|
1 | stop portamento on note off (>=62) or reserved
|
||||||
|
1 | continuous vibrato (>=62) or reserved
|
||||||
|
4 | reserved
|
||||||
4?? | pointers to instruments
|
4?? | pointers to instruments
|
||||||
4?? | pointers to wavetables
|
4?? | pointers to wavetables
|
||||||
4?? | pointers to samples
|
4?? | pointers to samples
|
||||||
|
|
|
@ -37,8 +37,8 @@
|
||||||
warnings+=(String("\n")+x); \
|
warnings+=(String("\n")+x); \
|
||||||
}
|
}
|
||||||
|
|
||||||
#define DIV_VERSION "dev61"
|
#define DIV_VERSION "dev62"
|
||||||
#define DIV_ENGINE_VERSION 61
|
#define DIV_ENGINE_VERSION 62
|
||||||
|
|
||||||
enum DivStatusView {
|
enum DivStatusView {
|
||||||
DIV_STATUS_NOTHING=0,
|
DIV_STATUS_NOTHING=0,
|
||||||
|
|
|
@ -796,6 +796,9 @@ bool DivEngine::loadFur(unsigned char* file, size_t len) {
|
||||||
if (ds.version<50) {
|
if (ds.version<50) {
|
||||||
ds.ignoreDuplicateSlides=false;
|
ds.ignoreDuplicateSlides=false;
|
||||||
}
|
}
|
||||||
|
if (ds.version<62) {
|
||||||
|
ds.stopPortaOnNoteOff=true;
|
||||||
|
}
|
||||||
ds.isDMF=false;
|
ds.isDMF=false;
|
||||||
|
|
||||||
reader.readS(); // reserved
|
reader.readS(); // reserved
|
||||||
|
@ -965,7 +968,14 @@ bool DivEngine::loadFur(unsigned char* file, size_t len) {
|
||||||
} else {
|
} else {
|
||||||
reader.readC();
|
reader.readC();
|
||||||
}
|
}
|
||||||
for (int i=0; i<6; i++) reader.readC();
|
if (ds.version>=62) {
|
||||||
|
ds.stopPortaOnNoteOff=reader.readC();
|
||||||
|
ds.continuousVibrato=reader.readC();
|
||||||
|
} else {
|
||||||
|
reader.readC();
|
||||||
|
reader.readC();
|
||||||
|
}
|
||||||
|
for (int i=0; i<4; i++) reader.readC();
|
||||||
} else {
|
} else {
|
||||||
for (int i=0; i<20; i++) reader.readC();
|
for (int i=0; i<20; i++) reader.readC();
|
||||||
}
|
}
|
||||||
|
@ -1404,7 +1414,9 @@ SafeWriter* DivEngine::saveFur() {
|
||||||
w->writeC(song.algMacroBehavior);
|
w->writeC(song.algMacroBehavior);
|
||||||
w->writeC(song.brokenShortcutSlides);
|
w->writeC(song.brokenShortcutSlides);
|
||||||
w->writeC(song.ignoreDuplicateSlides);
|
w->writeC(song.ignoreDuplicateSlides);
|
||||||
for (int i=0; i<6; i++) {
|
w->writeC(song.stopPortaOnNoteOff);
|
||||||
|
w->writeC(song.continuousVibrato);
|
||||||
|
for (int i=0; i<4; i++) {
|
||||||
w->writeC(0);
|
w->writeC(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -728,7 +728,7 @@ void DivEngine::processRow(int i, bool afterDelay) {
|
||||||
}
|
}
|
||||||
chan[i].portaStop=true;
|
chan[i].portaStop=true;
|
||||||
if (chan[i].keyOn) chan[i].doNote=false;
|
if (chan[i].keyOn) chan[i].doNote=false;
|
||||||
chan[i].stopOnOff=false; // what?!
|
chan[i].stopOnOff=song.stopPortaOnNoteOff; // what?!
|
||||||
chan[i].scheduledSlideReset=false;
|
chan[i].scheduledSlideReset=false;
|
||||||
dispatchCmd(DivCommand(DIV_CMD_PRE_PORTA,i,true,1));
|
dispatchCmd(DivCommand(DIV_CMD_PRE_PORTA,i,true,1));
|
||||||
lastSlide=0x1337; // i hate this so much
|
lastSlide=0x1337; // i hate this so much
|
||||||
|
@ -778,7 +778,7 @@ void DivEngine::processRow(int i, bool afterDelay) {
|
||||||
chan[i].portaSpeed=(effectVal>>4)*4;
|
chan[i].portaSpeed=(effectVal>>4)*4;
|
||||||
chan[i].portaStop=true;
|
chan[i].portaStop=true;
|
||||||
chan[i].nowYouCanStop=false;
|
chan[i].nowYouCanStop=false;
|
||||||
chan[i].stopOnOff=false; // what?!
|
chan[i].stopOnOff=song.stopPortaOnNoteOff; // what?!
|
||||||
chan[i].scheduledSlideReset=false;
|
chan[i].scheduledSlideReset=false;
|
||||||
if ((effectVal&15)!=0) {
|
if ((effectVal&15)!=0) {
|
||||||
chan[i].inPorta=true;
|
chan[i].inPorta=true;
|
||||||
|
@ -794,7 +794,7 @@ void DivEngine::processRow(int i, bool afterDelay) {
|
||||||
chan[i].portaSpeed=(effectVal>>4)*4;
|
chan[i].portaSpeed=(effectVal>>4)*4;
|
||||||
chan[i].portaStop=true;
|
chan[i].portaStop=true;
|
||||||
chan[i].nowYouCanStop=false;
|
chan[i].nowYouCanStop=false;
|
||||||
chan[i].stopOnOff=false; // what?!
|
chan[i].stopOnOff=song.stopPortaOnNoteOff; // what?!
|
||||||
chan[i].scheduledSlideReset=false;
|
chan[i].scheduledSlideReset=false;
|
||||||
if ((effectVal&15)!=0) {
|
if ((effectVal&15)!=0) {
|
||||||
chan[i].inPorta=true;
|
chan[i].inPorta=true;
|
||||||
|
@ -854,7 +854,9 @@ void DivEngine::processRow(int i, bool afterDelay) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (chan[i].doNote) {
|
if (chan[i].doNote) {
|
||||||
chan[i].vibratoPos=0;
|
if (!song.continuousVibrato) {
|
||||||
|
chan[i].vibratoPos=0;
|
||||||
|
}
|
||||||
dispatchCmd(DivCommand(DIV_CMD_PITCH,i,chan[i].pitch+(((chan[i].vibratoDepth*vibTable[chan[i].vibratoPos]*chan[i].vibratoFine)>>4)/15)));
|
dispatchCmd(DivCommand(DIV_CMD_PITCH,i,chan[i].pitch+(((chan[i].vibratoDepth*vibTable[chan[i].vibratoPos]*chan[i].vibratoFine)>>4)/15)));
|
||||||
if (chan[i].legato) {
|
if (chan[i].legato) {
|
||||||
dispatchCmd(DivCommand(DIV_CMD_LEGATO,i,chan[i].note));
|
dispatchCmd(DivCommand(DIV_CMD_LEGATO,i,chan[i].note));
|
||||||
|
|
|
@ -276,6 +276,8 @@ struct DivSong {
|
||||||
bool algMacroBehavior;
|
bool algMacroBehavior;
|
||||||
bool brokenShortcutSlides;
|
bool brokenShortcutSlides;
|
||||||
bool ignoreDuplicateSlides;
|
bool ignoreDuplicateSlides;
|
||||||
|
bool stopPortaOnNoteOff;
|
||||||
|
bool continuousVibrato;
|
||||||
|
|
||||||
DivOrders orders;
|
DivOrders orders;
|
||||||
std::vector<DivInstrument*> ins;
|
std::vector<DivInstrument*> ins;
|
||||||
|
@ -338,7 +340,9 @@ struct DivSong {
|
||||||
arpNonPorta(false),
|
arpNonPorta(false),
|
||||||
algMacroBehavior(false),
|
algMacroBehavior(false),
|
||||||
brokenShortcutSlides(false),
|
brokenShortcutSlides(false),
|
||||||
ignoreDuplicateSlides(false) {
|
ignoreDuplicateSlides(false),
|
||||||
|
stopPortaOnNoteOff(false),
|
||||||
|
continuousVibrato(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;
|
||||||
|
|
|
@ -2054,6 +2054,10 @@ void FurnaceGUI::drawCompatFlags() {
|
||||||
if (ImGui::IsItemHovered()) {
|
if (ImGui::IsItemHovered()) {
|
||||||
ImGui::SetTooltip("if this is on, only the first slide of a row in a channel will be considered.");
|
ImGui::SetTooltip("if this is on, only the first slide of a row in a channel will be considered.");
|
||||||
}
|
}
|
||||||
|
ImGui::Checkbox("Continuous vibrato",&e->song.continuousVibrato);
|
||||||
|
if (ImGui::IsItemHovered()) {
|
||||||
|
ImGui::SetTooltip("when enabled, vibrato will not be reset on a new note.");
|
||||||
|
}
|
||||||
|
|
||||||
ImGui::Text("Loop modality:");
|
ImGui::Text("Loop modality:");
|
||||||
if (ImGui::RadioButton("Reset channels",e->song.loopModality==0)) {
|
if (ImGui::RadioButton("Reset channels",e->song.loopModality==0)) {
|
||||||
|
@ -2091,6 +2095,10 @@ void FurnaceGUI::drawCompatFlags() {
|
||||||
if (ImGui::IsItemHovered()) {
|
if (ImGui::IsItemHovered()) {
|
||||||
ImGui::SetTooltip("behavior changed in 0.5.7");
|
ImGui::SetTooltip("behavior changed in 0.5.7");
|
||||||
}
|
}
|
||||||
|
ImGui::Checkbox("Stop portamento on note off",&e->song.stopPortaOnNoteOff);
|
||||||
|
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 a new issue