From 0a426efe126ca2ad751d74b00032bc6e5a5e80b8 Mon Sep 17 00:00:00 2001 From: tildearrow Date: Tue, 25 Jun 2024 16:35:22 -0500 Subject: [PATCH] IT import: more work on it --- src/engine/engine.h | 4 +- src/engine/fileOps/it.cpp | 189 +++++++++++++++++++++++--------------- src/gui/gui.cpp | 2 +- 3 files changed, 120 insertions(+), 75 deletions(-) diff --git a/src/engine/engine.h b/src/engine/engine.h index e756de35f..5bc4ef7ce 100644 --- a/src/engine/engine.h +++ b/src/engine/engine.h @@ -52,9 +52,9 @@ class DivWorkPool; #define EXTERN_BUSY_BEGIN_SOFT e->softLocked=true; e->isBusy.lock(); #define EXTERN_BUSY_END e->isBusy.unlock(); e->softLocked=false; -//#define DIV_UNSTABLE +#define DIV_UNSTABLE -#define DIV_VERSION "0.6.5" +#define DIV_VERSION "Another undercooked furnace update" #define DIV_ENGINE_VERSION 214 // for imports #define DIV_VERSION_MOD 0xff01 diff --git a/src/engine/fileOps/it.cpp b/src/engine/fileOps/it.cpp index 9af89610a..e85137c3f 100644 --- a/src/engine/fileOps/it.cpp +++ b/src/engine/fileOps/it.cpp @@ -35,17 +35,17 @@ bool DivEngine::loadIT(unsigned char* file, size_t len) { unsigned short patLen[256]; - bool doesPitchSlide[32]; - bool doesVibrato[32]; - bool doesPanning[32]; - bool doesVolSlide[32]; - bool doesArp[32]; + bool doesPitchSlide[64]; + bool doesVibrato[64]; + bool doesPanning[64]; + bool doesVolSlide[64]; + bool doesArp[64]; - memset(doesPitchSlide,0,32*sizeof(bool)); - memset(doesVibrato,0,32*sizeof(bool)); - memset(doesPanning,0,32*sizeof(bool)); - memset(doesVolSlide,0,32*sizeof(bool)); - memset(doesArp,0,32*sizeof(bool)); + memset(doesPitchSlide,0,64*sizeof(bool)); + memset(doesVibrato,0,64*sizeof(bool)); + memset(doesPanning,0,64*sizeof(bool)); + memset(doesVolSlide,0,64*sizeof(bool)); + memset(doesArp,0,64*sizeof(bool)); SafeReader reader=SafeReader(file,len); warnings=""; @@ -94,6 +94,27 @@ bool DivEngine::loadIT(unsigned char* file, size_t len) { unsigned short flags=reader.readS(); unsigned short special=reader.readS(); + if (ds.insLen<0 || ds.insLen>256) { + logE("too many instruments!"); + lastError="too many instruments"; + delete[] file; + return false; + } + + if (ds.sampleLen<0 || ds.sampleLen>256) { + logE("too many samples!"); + lastError="too many samples"; + delete[] file; + return false; + } + + if (patCount>256) { + logE("too many patterns!"); + lastError="too many patterns"; + delete[] file; + return false; + } + if (flags&8) { ds.linearPitch=2; } else { @@ -472,25 +493,25 @@ bool DivEngine::loadIT(unsigned char* file, size_t len) { // read patterns int maxChan=0; for (int i=0; i=patRows) break; + if (curRow>=patRows) { + if (curRow>0) { + // place end of pattern marker + DivPattern* p=ds.subsong[0]->pat[0].getPattern(i,true); + p->data[curRow-1][effectCol[0]++]=0x0d; + p->data[curRow-1][effectCol[0]++]=0; + + if ((effectCol[0]>>1)-2>ds.subsong[0]->pat[0].effectCols) { + ds.subsong[0]->pat[0].effectCols=(effectCol[0]>>1)-1; + } + } + break; + } continue; } @@ -683,12 +716,12 @@ bool DivEngine::loadIT(unsigned char* file, size_t len) { DivPattern* p=ds.subsong[0]->pat[chan].getPattern(i,true); if (hasNote) { - if (note[chan]==255) { // note off - p->data[curRow][0]=100; - p->data[curRow][1]=0; - } else if (note[chan]==254) { // note release + if (note[chan]==255) { // note release p->data[curRow][0]=101; p->data[curRow][1]=0; + } else if (note[chan]==254) { // note off + p->data[curRow][0]=100; + p->data[curRow][1]=0; } else if (note[chan]<120) { p->data[curRow][0]=note[chan]%12; p->data[curRow][1]=note[chan]/12; @@ -696,6 +729,9 @@ bool DivEngine::loadIT(unsigned char* file, size_t len) { p->data[curRow][0]=12; p->data[curRow][1]--; } + } else { // note fade, but Furnace does not have that + p->data[curRow][0]=102; + p->data[curRow][1]=0; } } if (hasIns) { @@ -841,6 +877,8 @@ bool DivEngine::loadIT(unsigned char* file, size_t len) { } } + logV("maxChan: %d",maxChan); + // set channel visibility for (int i=maxChan+1; i<((maxChan+32)&(~31)); i++) { ds.subsong[0]->chanShow[i]=false; @@ -848,11 +886,16 @@ bool DivEngine::loadIT(unsigned char* file, size_t len) { } // copy patterns to the rest of subsongs - // TODO: why does this use so much memory? int copiesMade=0; for (size_t i=1; iordersLen; j++) { + usedPat[ds.subsong[i]->orders.ord[0][j]]=true; + } for (int j=0; jpat[j].data[k]) { ds.subsong[0]->pat[j].data[k]->copyOn(ds.subsong[i]->pat[j].getPattern(k,true)); copiesMade++; @@ -868,12 +911,14 @@ bool DivEngine::loadIT(unsigned char* file, size_t len) { logV("copies made %d",copiesMade); - // set pattern lengths and place end of pattern markers + // set pattern lengths for (size_t i=0; iordersLen; j++) { - int nextLen=patLen[ds.subsong[i]->orders.ord[0][j]]; - if (patLenMaxorders.ord[0][j]]; + if (patLenMaxpatLen=patLenMax; } diff --git a/src/gui/gui.cpp b/src/gui/gui.cpp index af2b7dec6..f5b8c0390 100644 --- a/src/gui/gui.cpp +++ b/src/gui/gui.cpp @@ -1669,7 +1669,7 @@ void FurnaceGUI::openFileDialog(FurnaceGUIFileDialogs type) { if (!dirExists(workingDirSong)) workingDirSong=getHomeDir(); hasOpened=fileDialog->openLoad( _("Open File"), - {_("compatible files"), "*.fur *.dmf *.mod *.s3m *.fc13 *.fc14 *.smod *.fc *.ftm *.0cc *.dnm *.eft *.fub *.tfe", + {_("compatible files"), "*.fur *.dmf *.mod *.s3m *.xm *.it *.fc13 *.fc14 *.smod *.fc *.ftm *.0cc *.dnm *.eft *.fub *.tfe", _("all files"), "*"}, workingDirSong, dpiScale