dev113 - loop detection changes
This commit is contained in:
parent
ac0decd01b
commit
187653a70f
|
@ -15,8 +15,8 @@ android {
|
|||
}
|
||||
minSdkVersion 21
|
||||
targetSdkVersion 26
|
||||
versionCode 112
|
||||
versionName "dev112"
|
||||
versionCode 113
|
||||
versionName "dev113"
|
||||
externalNativeBuild {
|
||||
cmake {
|
||||
arguments "-DANDROID_APP_PLATFORM=android-21", "-DANDROID_STL=c++_static"
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
package="org.tildearrow.furnace"
|
||||
android:versionCode="112"
|
||||
android:versionName="dev112"
|
||||
android:versionCode="113"
|
||||
android:versionName="dev113"
|
||||
android:installLocation="auto">
|
||||
|
||||
<!-- OpenGL ES 2.0 -->
|
||||
|
|
|
@ -32,6 +32,7 @@ these fields are 0 in format versions prior to 100 (0.6pre1).
|
|||
|
||||
the format versions are:
|
||||
|
||||
- 113: Furnace dev113
|
||||
- 112: Furnace dev112
|
||||
- 111: Furnace dev111
|
||||
- 110: Furnace dev110
|
||||
|
@ -338,7 +339,8 @@ size | description
|
|||
1 | broken initial position of porta after arp (>=101) or reserved
|
||||
1 | SN periods under 8 are treated as 1 (>=108) or reserved
|
||||
1 | cut/delay effect policy (>=110) or reserved
|
||||
5 | reserved
|
||||
1 | 0B/0D effect treatment (>=113) or reserved
|
||||
4 | reserved
|
||||
--- | **virtual tempo data**
|
||||
2 | virtual tempo numerator of first song (>=96) or reserved
|
||||
2 | virtual tempo denominator of first song (>=96) or reserved
|
||||
|
|
|
@ -1658,6 +1658,7 @@ void DivEngine::playSub(bool preserveDrift, int goalRow) {
|
|||
speedAB=false;
|
||||
playing=true;
|
||||
skipping=true;
|
||||
memset(walked,0,8192);
|
||||
for (int i=0; i<song.systemLen; i++) disCont[i].dispatch->setSkipRegisterWrites(true);
|
||||
while (playing && curOrder<goal) {
|
||||
if (nextTick(preserveDrift)) {
|
||||
|
|
|
@ -46,9 +46,8 @@
|
|||
#define BUSY_BEGIN_SOFT softLocked=true; isBusy.lock();
|
||||
#define BUSY_END isBusy.unlock(); softLocked=false;
|
||||
|
||||
#define DIV_VERSION "dev112"
|
||||
#define DIV_ENGINE_VERSION 112
|
||||
|
||||
#define DIV_VERSION "dev113"
|
||||
#define DIV_ENGINE_VERSION 113
|
||||
// for imports
|
||||
#define DIV_VERSION_MOD 0xff01
|
||||
#define DIV_VERSION_FC 0xff02
|
||||
|
@ -358,6 +357,8 @@ class DivEngine {
|
|||
double exportFadeOut;
|
||||
std::map<String,String> conf;
|
||||
std::deque<DivNoteEvent> pendingNotes;
|
||||
// bitfield
|
||||
unsigned char walked[8192];
|
||||
bool isMuted[DIV_MAX_CHANS];
|
||||
std::mutex isBusy, saveLock;
|
||||
String configPath;
|
||||
|
@ -1072,6 +1073,7 @@ class DivEngine {
|
|||
memset(reversePitchTable,0,4096*sizeof(int));
|
||||
memset(pitchTable,0,4096*sizeof(int));
|
||||
memset(sysDefs,0,256*sizeof(void*));
|
||||
memset(walked,0,8192);
|
||||
|
||||
for (int i=0; i<256; i++) {
|
||||
sysFileMapFur[i]=DIV_SYSTEM_NULL;
|
||||
|
|
|
@ -179,6 +179,7 @@ bool DivEngine::loadDMF(unsigned char* file, size_t len) {
|
|||
ds.brokenPortaArp=false;
|
||||
ds.snNoLowPeriods=true;
|
||||
ds.delayBehavior=0;
|
||||
ds.jumpTreatment=2;
|
||||
|
||||
// 1.1 compat flags
|
||||
if (ds.version>24) {
|
||||
|
@ -1081,6 +1082,9 @@ bool DivEngine::loadFur(unsigned char* file, size_t len) {
|
|||
if (ds.version<110) {
|
||||
ds.delayBehavior=1;
|
||||
}
|
||||
if (ds.version<113) {
|
||||
ds.jumpTreatment=1;
|
||||
}
|
||||
ds.isDMF=false;
|
||||
|
||||
reader.readS(); // reserved
|
||||
|
@ -1503,7 +1507,12 @@ bool DivEngine::loadFur(unsigned char* file, size_t len) {
|
|||
} else {
|
||||
reader.readC();
|
||||
}
|
||||
for (int i=0; i<5; i++) {
|
||||
if (ds.version>=113) {
|
||||
ds.jumpTreatment=reader.readC();
|
||||
} else {
|
||||
reader.readC();
|
||||
}
|
||||
for (int i=0; i<4; i++) {
|
||||
reader.readC();
|
||||
}
|
||||
}
|
||||
|
@ -3747,7 +3756,8 @@ SafeWriter* DivEngine::saveFur(bool notPrimary) {
|
|||
w->writeC(song.brokenPortaArp);
|
||||
w->writeC(song.snNoLowPeriods);
|
||||
w->writeC(song.delayBehavior);
|
||||
for (int i=0; i<5; i++) {
|
||||
w->writeC(song.jumpTreatment);
|
||||
for (int i=0; i<4; i++) {
|
||||
w->writeC(0);
|
||||
}
|
||||
|
||||
|
|
|
@ -31,7 +31,9 @@ void DivEngine::nextOrder() {
|
|||
curRow=0;
|
||||
if (repeatPattern) return;
|
||||
if (++curOrder>=curSubSong->ordersLen) {
|
||||
logV("end of orders reached");
|
||||
endOfSong=true;
|
||||
memset(walked,0,8192);
|
||||
curOrder=0;
|
||||
}
|
||||
}
|
||||
|
@ -348,16 +350,32 @@ void DivEngine::processRow(int i, bool afterDelay) {
|
|||
if (effectVal>0) speed2=effectVal;
|
||||
break;
|
||||
case 0x0b: // change order
|
||||
if (changeOrd==-1) {
|
||||
if (changeOrd==-1 || song.jumpTreatment==0) {
|
||||
changeOrd=effectVal;
|
||||
if (song.jumpTreatment==1 || song.jumpTreatment==2) {
|
||||
changePos=0;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 0x0d: // next order
|
||||
if (song.jumpTreatment==2) {
|
||||
if ((curOrder<(curSubSong->ordersLen-1) || !song.ignoreJumpAtEnd)) {
|
||||
changeOrd=-2;
|
||||
changePos=effectVal;
|
||||
}
|
||||
} else if (song.jumpTreatment==1) {
|
||||
if (changeOrd<0 && (curOrder<(curSubSong->ordersLen-1) || !song.ignoreJumpAtEnd)) {
|
||||
changeOrd=-2;
|
||||
changePos=effectVal;
|
||||
}
|
||||
} else {
|
||||
if (curOrder<(curSubSong->ordersLen-1) || !song.ignoreJumpAtEnd) {
|
||||
if (changeOrd<0) {
|
||||
changeOrd=-2;
|
||||
}
|
||||
changePos=effectVal;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 0xed: // delay
|
||||
if (effectVal!=0) {
|
||||
|
@ -911,18 +929,23 @@ void DivEngine::nextRow() {
|
|||
processRow(i,false);
|
||||
}
|
||||
|
||||
walked[((curOrder<<5)+(curRow>>3))&8191]|=1<<(curRow&7);
|
||||
|
||||
if (changeOrd!=-1) {
|
||||
if (repeatPattern) {
|
||||
curRow=0;
|
||||
changeOrd=-1;
|
||||
} else {
|
||||
curRow=changePos;
|
||||
changePos=0;
|
||||
if (changeOrd==-2) changeOrd=curOrder+1;
|
||||
if (changeOrd<=curOrder) endOfSong=true;
|
||||
// old loop detection routine
|
||||
//if (changeOrd<=curOrder) endOfSong=true;
|
||||
curOrder=changeOrd;
|
||||
if (curOrder>=curSubSong->ordersLen) {
|
||||
curOrder=0;
|
||||
endOfSong=true;
|
||||
memset(walked,0,8192);
|
||||
}
|
||||
changeOrd=-1;
|
||||
}
|
||||
|
@ -932,6 +955,13 @@ void DivEngine::nextRow() {
|
|||
if (haltOn==DIV_HALT_PATTERN) halted=true;
|
||||
}
|
||||
|
||||
// new loop detection routine
|
||||
if (!endOfSong && walked[((curOrder<<5)+(curRow>>3))&8191]&(1<<(curRow&7))) {
|
||||
logV("loop reached");
|
||||
endOfSong=true;
|
||||
memset(walked,0,8192);
|
||||
}
|
||||
|
||||
if (song.brokenSpeedSel) {
|
||||
if ((curSubSong->patLen&1) && curOrder&1) {
|
||||
ticks=((curRow&1)?speed2:speed1)*(curSubSong->timeBase+1);
|
||||
|
|
|
@ -468,6 +468,11 @@ struct DivSong {
|
|||
// 1: broken (don't allow value higher than speed)
|
||||
// 2: lax (allow value higher than speed)
|
||||
unsigned char delayBehavior;
|
||||
// 0B/0D treatment
|
||||
// 0: normal (0B/0D accepted)
|
||||
// 1: old Furnace (first one accepted)
|
||||
// 2: DefleMask (0D takes priority over 0B)
|
||||
unsigned char jumpTreatment;
|
||||
bool properNoiseLayout;
|
||||
bool waveDutyIsVol;
|
||||
bool resetMacroOnPorta;
|
||||
|
@ -571,6 +576,7 @@ struct DivSong {
|
|||
pitchSlideSpeed(4),
|
||||
loopModality(2),
|
||||
delayBehavior(2),
|
||||
jumpTreatment(0),
|
||||
properNoiseLayout(true),
|
||||
waveDutyIsVol(false),
|
||||
resetMacroOnPorta(false),
|
||||
|
|
|
@ -213,6 +213,26 @@ void FurnaceGUI::drawCompatFlags() {
|
|||
ImGui::SetTooltip("no checks (like FamiTracker)");
|
||||
}
|
||||
|
||||
ImGui::Text("Simultaneous jump (0B+0D) treatment:");
|
||||
if (ImGui::RadioButton("Normal",e->song.jumpTreatment==0)) {
|
||||
e->song.jumpTreatment=0;
|
||||
}
|
||||
if (ImGui::IsItemHovered()) {
|
||||
ImGui::SetTooltip("accept 0B+0D to jump to a specific row of an order");
|
||||
}
|
||||
if (ImGui::RadioButton("Old Furnace",e->song.jumpTreatment==1)) {
|
||||
e->song.jumpTreatment=1;
|
||||
}
|
||||
if (ImGui::IsItemHovered()) {
|
||||
ImGui::SetTooltip("only accept the first jump effect");
|
||||
}
|
||||
if (ImGui::RadioButton("DefleMask",e->song.jumpTreatment==2)) {
|
||||
e->song.jumpTreatment=2;
|
||||
}
|
||||
if (ImGui::IsItemHovered()) {
|
||||
ImGui::SetTooltip("only accept 0Dxx");
|
||||
}
|
||||
|
||||
ImGui::Separator();
|
||||
|
||||
ImGui::TextWrapped("the following flags are for compatibility with older Furnace versions.");
|
||||
|
|
Loading…
Reference in New Issue