new ins format, part 7

FM instruments now loadable
This commit is contained in:
tildearrow 2022-11-20 14:28:43 -05:00
parent badf91d447
commit 5ec4f2d1f0
4 changed files with 93 additions and 10 deletions

View File

@ -1,4 +1,4 @@
# possible new Furnace instrument format
# new Furnace instrument format
the main issue with Furnace instrument files is that they are too big, even if the instrument is nothing more than the FM setup...

View File

@ -47,8 +47,8 @@
#define BUSY_BEGIN_SOFT softLocked=true; isBusy.lock();
#define BUSY_END isBusy.unlock(); softLocked=false;
#define DIV_VERSION "dev125"
#define DIV_ENGINE_VERSION 125
#define DIV_VERSION "dev126"
#define DIV_ENGINE_VERSION 126
// for imports
#define DIV_VERSION_MOD 0xff01
#define DIV_VERSION_FC 0xff02

View File

@ -1880,10 +1880,19 @@ std::vector<DivInstrument*> DivEngine::instrumentFromFile(const char* path) {
unsigned char magic[16];
bool isFurnaceInstr=false;
bool isOldFurnaceIns=false;
try {
reader.read(magic,16);
if (memcmp("-Furnace instr.-",magic,16)==0) {
reader.read(magic,4);
if (memcmp("FINS",magic,4)==0) {
isFurnaceInstr=true;
logV("found a new Furnace ins");
} else {
reader.read(&magic[4],12);
if (memcmp("-Furnace instr.-",magic,16)==0) {
logV("found an old Furnace ins");
isFurnaceInstr=true;
isOldFurnaceIns=true;
}
}
} catch (EndOfFileException& e) {
reader.seek(0,SEEK_SET);
@ -1892,17 +1901,25 @@ std::vector<DivInstrument*> DivEngine::instrumentFromFile(const char* path) {
if (isFurnaceInstr) {
DivInstrument* ins=new DivInstrument;
try {
short version=reader.readS();
reader.readS(); // reserved
short version=0;
if (isOldFurnaceIns) {
version=reader.readS();
reader.readS(); // reserved
} else {
version=reader.readS();
reader.seek(0,SEEK_SET);
}
if (version>DIV_ENGINE_VERSION) {
warnings="this instrument is made with a more recent version of Furnace!";
}
unsigned int dataPtr=reader.readI();
reader.seek(dataPtr,SEEK_SET);
if (isOldFurnaceIns) {
unsigned int dataPtr=reader.readI();
reader.seek(dataPtr,SEEK_SET);
}
if (ins->readInsData(reader,version)!=DIV_DATA_SUCCESS) {
if (ins->readInsData(reader,version,&song)!=DIV_DATA_SUCCESS) {
lastError="invalid instrument header/data!";
delete ins;
delete[] buf;

View File

@ -1738,6 +1738,71 @@ void DivInstrument::readFeatureNA(SafeReader& reader) {
void DivInstrument::readFeatureFM(SafeReader& reader) {
READ_FEAT_BEGIN;
unsigned char opCount=reader.readC();
fm.op[0].enable=(opCount&16);
fm.op[1].enable=(opCount&32);
fm.op[2].enable=(opCount&64);
fm.op[3].enable=(opCount&128);
opCount&=15;
unsigned char next=reader.readC();
fm.alg=(next>>4)&7;
fm.fb=next&7;
next=reader.readC();
fm.fms2=(next>>5)&7;
fm.ams=(next>>3)&3;
fm.fms=next&7;
next=reader.readC();
fm.ams2=(next>>6)&3;
fm.ops=(next&32)?4:2;
fm.opllPreset=next&31;
// read operators
for (int i=0; i<opCount; i++) {
DivInstrumentFM::Operator& op=fm.op[i];
next=reader.readC();
op.ksr=(next&128)?1:0;
op.dt=(next>>4)&7;
op.mult=next&15;
next=reader.readC();
op.sus=(next&128)?1:0;
op.tl=next&127;
next=reader.readC();
op.rs=(next>>6)&3;
op.vib=(next&32)?1:0;
op.ar=next&31;
next=reader.readC();
op.am=(next&128)?1:0;
op.ksl=(next>>5)&3;
op.dr=next&31;
next=reader.readC();
op.egt=(next&128)?1:0;
op.kvs=(next>>5)&3;
op.d2r=next&31;
next=reader.readC();
op.sl=(next>>4)&15;
op.rr=next&15;
next=reader.readC();
op.dvb=(next>>4)&15;
op.ssgEnv=next&15;
next=reader.readC();
op.dam=(next>>5)&7;
op.dt2=(next>>3)&3;
op.ws=next&7;
}
READ_FEAT_END;
}
@ -2644,6 +2709,7 @@ DivDataErrors DivInstrument::readInsData(SafeReader& reader, short version, DivS
}
if (type==1 || type==2) {
logV("reading new instrument data...");
return readInsDataNew(reader,version,type==2,song);
}
return readInsDataOld(reader,version);