add broken speed alternation flag - dev70

This commit is contained in:
tildearrow 2022-03-23 01:35:57 -05:00
parent afc701b0b9
commit ac79e7d6af
6 changed files with 44 additions and 9 deletions

View file

@ -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:
- 70: Furnace dev70
- 69: Furnace dev69 - 69: Furnace dev69
- 68: Furnace dev68 - 68: Furnace dev68
- 67: Furnace dev67 - 67: Furnace dev67
@ -235,6 +236,9 @@ size | description
STR | song comment STR | song comment
4f | master volume, 1.0f=100% (>=59) 4f | master volume, 1.0f=100% (>=59)
| this is 2.0f for modules before 59 | this is 2.0f for modules before 59
--- | **extended compatibility flags** (>=70)
1 | broken speed selection
31 | reserved
``` ```
# instrument # instrument

View file

@ -38,8 +38,8 @@
warnings+=(String("\n")+x); \ warnings+=(String("\n")+x); \
} }
#define DIV_VERSION "dev69" #define DIV_VERSION "dev70"
#define DIV_ENGINE_VERSION 69 #define DIV_ENGINE_VERSION 70
// for imports // for imports
#define DIV_VERSION_MOD 0xff01 #define DIV_VERSION_MOD 0xff01

View file

@ -144,6 +144,7 @@ bool DivEngine::loadDMF(unsigned char* file, size_t len) {
ds.oneTickCut=false; ds.oneTickCut=false;
ds.newInsTriggersInPorta=true; ds.newInsTriggersInPorta=true;
ds.arp0Reset=true; ds.arp0Reset=true;
ds.brokenSpeedSel=true;
// 1.1 compat flags // 1.1 compat flags
if (ds.version>24) { if (ds.version>24) {
@ -1067,6 +1068,14 @@ bool DivEngine::loadFur(unsigned char* file, size_t len) {
ds.masterVol=2.0f; ds.masterVol=2.0f;
} }
if (ds.version>=70) {
// extended compat flags
ds.brokenSpeedSel=reader.readC();
for (int i=0; i<31; i++) {
reader.readC();
}
}
// read instruments // read instruments
for (int i=0; i<ds.insLen; i++) { for (int i=0; i<ds.insLen; i++) {
DivInstrument* ins=new DivInstrument; DivInstrument* ins=new DivInstrument;
@ -1905,6 +1914,12 @@ SafeWriter* DivEngine::saveFur(bool notPrimary) {
w->writeF(song.masterVol); w->writeF(song.masterVol);
// extended compat flags
w->writeC(song.brokenSpeedSel);
for (int i=0; i<31; i++) {
w->writeC(0);
}
/// INSTRUMENT /// INSTRUMENT
for (int i=0; i<song.insLen; i++) { for (int i=0; i<song.insLen; i++) {
DivInstrument* ins=song.ins[i]; DivInstrument* ins=song.ins[i];

View file

@ -1179,6 +1179,15 @@ void DivEngine::nextRow() {
if (haltOn==DIV_HALT_PATTERN) halted=true; if (haltOn==DIV_HALT_PATTERN) halted=true;
} }
if (song.brokenSpeedSel) {
if ((song.patLen&1) && curOrder&1) {
ticks=((curRow&1)?speed2:speed1)*(song.timeBase+1);
nextSpeed=(curRow&1)?speed1:speed2;
} else {
ticks=((curRow&1)?speed1:speed2)*(song.timeBase+1);
nextSpeed=(curRow&1)?speed2:speed1;
}
} else {
if (speedAB) { if (speedAB) {
ticks=speed2*(song.timeBase+1); ticks=speed2*(song.timeBase+1);
nextSpeed=speed1; nextSpeed=speed1;
@ -1187,6 +1196,7 @@ void DivEngine::nextRow() {
nextSpeed=speed2; nextSpeed=speed2;
} }
speedAB=!speedAB; speedAB=!speedAB;
}
// post row details // post row details
for (int i=0; i<chans; i++) { for (int i=0; i<chans; i++) {

View file

@ -301,6 +301,7 @@ struct DivSong {
bool oneTickCut; bool oneTickCut;
bool newInsTriggersInPorta; bool newInsTriggersInPorta;
bool arp0Reset; bool arp0Reset;
bool brokenSpeedSel;
DivOrders orders; DivOrders orders;
std::vector<DivInstrument*> ins; std::vector<DivInstrument*> ins;
@ -373,7 +374,8 @@ struct DivSong {
brokenDACMode(false), brokenDACMode(false),
oneTickCut(false), oneTickCut(false),
newInsTriggersInPorta(true), newInsTriggersInPorta(true),
arp0Reset(true) { arp0Reset(true),
brokenSpeedSel(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

@ -81,6 +81,10 @@ void FurnaceGUI::drawCompatFlags() {
if (ImGui::IsItemHovered()) { if (ImGui::IsItemHovered()) {
ImGui::SetTooltip("when enabled, a one-tick note cut will be inserted between non-legato/non-portamento notes.\nthis simulates the behavior of some Amiga/SNES music engines."); ImGui::SetTooltip("when enabled, a one-tick note cut will be inserted between non-legato/non-portamento notes.\nthis simulates the behavior of some Amiga/SNES music engines.");
} }
ImGui::Checkbox("Broken speed alternation",&e->song.brokenSpeedSel);
if (ImGui::IsItemHovered()) {
ImGui::SetTooltip("determines next speed based on whether the row is odd/even instead of alternating between speeds.");
}
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)) {