mirror of
https://github.com/tildearrow/furnace.git
synced 2025-01-05 15:11:19 +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...
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Reference in a new issue