mirror of
https://github.com/tildearrow/furnace.git
synced 2025-01-06 23:51:21 +00:00
new ins format, part 7
FM instruments now loadable
This commit is contained in:
parent
badf91d447
commit
5ec4f2d1f0
4 changed files with 93 additions and 10 deletions
|
@ -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...
|
the main issue with Furnace instrument files is that they are too big, even if the instrument is nothing more than the FM setup...
|
||||||
|
|
||||||
|
|
|
@ -47,8 +47,8 @@
|
||||||
#define BUSY_BEGIN_SOFT softLocked=true; isBusy.lock();
|
#define BUSY_BEGIN_SOFT softLocked=true; isBusy.lock();
|
||||||
#define BUSY_END isBusy.unlock(); softLocked=false;
|
#define BUSY_END isBusy.unlock(); softLocked=false;
|
||||||
|
|
||||||
#define DIV_VERSION "dev125"
|
#define DIV_VERSION "dev126"
|
||||||
#define DIV_ENGINE_VERSION 125
|
#define DIV_ENGINE_VERSION 126
|
||||||
// for imports
|
// for imports
|
||||||
#define DIV_VERSION_MOD 0xff01
|
#define DIV_VERSION_MOD 0xff01
|
||||||
#define DIV_VERSION_FC 0xff02
|
#define DIV_VERSION_FC 0xff02
|
||||||
|
|
|
@ -1880,10 +1880,19 @@ std::vector<DivInstrument*> DivEngine::instrumentFromFile(const char* path) {
|
||||||
|
|
||||||
unsigned char magic[16];
|
unsigned char magic[16];
|
||||||
bool isFurnaceInstr=false;
|
bool isFurnaceInstr=false;
|
||||||
|
bool isOldFurnaceIns=false;
|
||||||
try {
|
try {
|
||||||
reader.read(magic,16);
|
reader.read(magic,4);
|
||||||
if (memcmp("-Furnace instr.-",magic,16)==0) {
|
if (memcmp("FINS",magic,4)==0) {
|
||||||
isFurnaceInstr=true;
|
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) {
|
} catch (EndOfFileException& e) {
|
||||||
reader.seek(0,SEEK_SET);
|
reader.seek(0,SEEK_SET);
|
||||||
|
@ -1892,17 +1901,25 @@ std::vector<DivInstrument*> DivEngine::instrumentFromFile(const char* path) {
|
||||||
if (isFurnaceInstr) {
|
if (isFurnaceInstr) {
|
||||||
DivInstrument* ins=new DivInstrument;
|
DivInstrument* ins=new DivInstrument;
|
||||||
try {
|
try {
|
||||||
short version=reader.readS();
|
short version=0;
|
||||||
reader.readS(); // reserved
|
if (isOldFurnaceIns) {
|
||||||
|
version=reader.readS();
|
||||||
|
reader.readS(); // reserved
|
||||||
|
} else {
|
||||||
|
version=reader.readS();
|
||||||
|
reader.seek(0,SEEK_SET);
|
||||||
|
}
|
||||||
|
|
||||||
if (version>DIV_ENGINE_VERSION) {
|
if (version>DIV_ENGINE_VERSION) {
|
||||||
warnings="this instrument is made with a more recent version of Furnace!";
|
warnings="this instrument is made with a more recent version of Furnace!";
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned int dataPtr=reader.readI();
|
if (isOldFurnaceIns) {
|
||||||
reader.seek(dataPtr,SEEK_SET);
|
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!";
|
lastError="invalid instrument header/data!";
|
||||||
delete ins;
|
delete ins;
|
||||||
delete[] buf;
|
delete[] buf;
|
||||||
|
|
|
@ -1738,6 +1738,71 @@ void DivInstrument::readFeatureNA(SafeReader& reader) {
|
||||||
void DivInstrument::readFeatureFM(SafeReader& reader) {
|
void DivInstrument::readFeatureFM(SafeReader& reader) {
|
||||||
READ_FEAT_BEGIN;
|
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;
|
READ_FEAT_END;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2644,6 +2709,7 @@ DivDataErrors DivInstrument::readInsData(SafeReader& reader, short version, DivS
|
||||||
}
|
}
|
||||||
|
|
||||||
if (type==1 || type==2) {
|
if (type==1 || type==2) {
|
||||||
|
logV("reading new instrument data...");
|
||||||
return readInsDataNew(reader,version,type==2,song);
|
return readInsDataNew(reader,version,type==2,song);
|
||||||
}
|
}
|
||||||
return readInsDataOld(reader,version);
|
return readInsDataOld(reader,version);
|
||||||
|
|
Loading…
Reference in a new issue