mirror of
https://github.com/tildearrow/furnace.git
synced 2024-11-30 16:33:01 +00:00
re-organize instrument loading code
This commit is contained in:
parent
82ae2bf877
commit
109f80d4da
2 changed files with 627 additions and 582 deletions
|
@ -273,6 +273,13 @@ class DivEngine {
|
|||
bool loadFur(unsigned char* file, size_t len);
|
||||
bool loadMod(unsigned char* file, size_t len);
|
||||
|
||||
void loadDMP(SafeReader& reader, std::vector<DivInstrument*>& ret, String& stripPath);
|
||||
void loadTFI(SafeReader& reader, std::vector<DivInstrument*>& ret, String& stripPath);
|
||||
void loadVGI(SafeReader& reader, std::vector<DivInstrument*>& ret, String& stripPath);
|
||||
void loadS3I(SafeReader& reader, std::vector<DivInstrument*>& ret, String& stripPath);
|
||||
void loadSBI(SafeReader& reader, std::vector<DivInstrument*>& ret, String& stripPath);
|
||||
void loadOPM(SafeReader& reader, std::vector<DivInstrument*>& ret, String& stripPath);
|
||||
|
||||
bool initAudioBackend();
|
||||
bool deinitAudioBackend();
|
||||
|
||||
|
|
|
@ -33,136 +33,8 @@ enum DivInsFormats {
|
|||
DIV_INSFORMAT_OPM
|
||||
};
|
||||
|
||||
std::vector<DivInstrument*> DivEngine::instrumentFromFile(const char* path) {
|
||||
std::vector<DivInstrument*> ret;
|
||||
warnings="";
|
||||
|
||||
const char* pathRedux=strrchr(path,DIR_SEPARATOR);
|
||||
if (pathRedux==NULL) {
|
||||
pathRedux=path;
|
||||
} else {
|
||||
pathRedux++;
|
||||
}
|
||||
String stripPath;
|
||||
const char* pathReduxEnd=strrchr(pathRedux,'.');
|
||||
if (pathReduxEnd==NULL) {
|
||||
stripPath=pathRedux;
|
||||
} else {
|
||||
for (const char* i=pathRedux; i!=pathReduxEnd && (*i); i++) {
|
||||
stripPath+=*i;
|
||||
}
|
||||
}
|
||||
|
||||
FILE* f=ps_fopen(path,"rb");
|
||||
if (f==NULL) {
|
||||
lastError=strerror(errno);
|
||||
return ret;
|
||||
}
|
||||
unsigned char* buf;
|
||||
ssize_t len;
|
||||
if (fseek(f,0,SEEK_END)!=0) {
|
||||
lastError=strerror(errno);
|
||||
fclose(f);
|
||||
return ret;
|
||||
}
|
||||
len=ftell(f);
|
||||
if (len<0) {
|
||||
lastError=strerror(errno);
|
||||
fclose(f);
|
||||
return ret;
|
||||
}
|
||||
if (len==0) {
|
||||
lastError=strerror(errno);
|
||||
fclose(f);
|
||||
return ret;
|
||||
}
|
||||
if (fseek(f,0,SEEK_SET)!=0) {
|
||||
lastError=strerror(errno);
|
||||
fclose(f);
|
||||
return ret;
|
||||
}
|
||||
buf=new unsigned char[len];
|
||||
if (fread(buf,1,len,f)!=(size_t)len) {
|
||||
logW("did not read entire instrument file buffer!\n");
|
||||
lastError="did not read entire instrument file!";
|
||||
delete[] buf;
|
||||
return ret;
|
||||
}
|
||||
fclose(f);
|
||||
|
||||
SafeReader reader=SafeReader(buf,len);
|
||||
|
||||
unsigned char magic[16];
|
||||
bool isFurnaceInstr=false;
|
||||
try {
|
||||
reader.read(magic,16);
|
||||
if (memcmp("-Furnace instr.-",magic,16)==0) {
|
||||
isFurnaceInstr=true;
|
||||
}
|
||||
} catch (EndOfFileException& e) {
|
||||
reader.seek(0,SEEK_SET);
|
||||
}
|
||||
|
||||
void DivEngine::loadDMP(SafeReader& reader, std::vector<DivInstrument*>& ret, String& stripPath) {
|
||||
DivInstrument* ins=new DivInstrument;
|
||||
if (isFurnaceInstr) {
|
||||
try {
|
||||
short version=reader.readS();
|
||||
reader.readS(); // reserved
|
||||
|
||||
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 (ins->readInsData(reader,version)!=DIV_DATA_SUCCESS) {
|
||||
lastError="invalid instrument header/data!";
|
||||
delete ins;
|
||||
delete[] buf;
|
||||
return ret;
|
||||
}
|
||||
} catch (EndOfFileException& e) {
|
||||
lastError="premature end of file";
|
||||
logE("premature end of file!\n");
|
||||
delete ins;
|
||||
delete[] buf;
|
||||
return ret;
|
||||
}
|
||||
} else { // read as a different format
|
||||
const char* ext=strrchr(path,'.');
|
||||
DivInsFormats format=DIV_INSFORMAT_DMP;
|
||||
if (ext!=NULL) {
|
||||
String extS;
|
||||
for (; *ext; ext++) {
|
||||
char i=*ext;
|
||||
if (i>='A' && i<='Z') {
|
||||
i+='a'-'A';
|
||||
}
|
||||
extS+=i;
|
||||
}
|
||||
if (extS==String(".dmp")) {
|
||||
format=DIV_INSFORMAT_DMP;
|
||||
} else if (extS==String(".tfi")) {
|
||||
format=DIV_INSFORMAT_TFI;
|
||||
} else if (extS==String(".vgi")) {
|
||||
format=DIV_INSFORMAT_VGI;
|
||||
} else if (extS==String(".fti")) {
|
||||
format=DIV_INSFORMAT_FTI;
|
||||
} else if (extS==String(".bti")) {
|
||||
format=DIV_INSFORMAT_BTI;
|
||||
} else if (extS==String(".s3i")) {
|
||||
format=DIV_INSFORMAT_S3I;
|
||||
} else if (extS==String(".sbi")) {
|
||||
format=DIV_INSFORMAT_SBI;
|
||||
} else if (extS==String(".opm")) {
|
||||
format=DIV_INSFORMAT_OPM;
|
||||
}
|
||||
}
|
||||
|
||||
// TDOO these really should be re-organized to separate functions per instrument file type.
|
||||
switch (format) {
|
||||
case DIV_INSFORMAT_DMP: {
|
||||
// this is a ridiculous mess
|
||||
unsigned char version=0;
|
||||
unsigned char sys=0;
|
||||
|
@ -174,15 +46,13 @@ std::vector<DivInstrument*> DivEngine::instrumentFromFile(const char* path) {
|
|||
lastError="premature end of file";
|
||||
logE("premature end of file!\n");
|
||||
delete ins;
|
||||
delete[] buf;
|
||||
return ret;
|
||||
return;
|
||||
}
|
||||
|
||||
if (version>11) {
|
||||
lastError="unknown instrument version!";
|
||||
delete ins;
|
||||
delete[] buf;
|
||||
return ret;
|
||||
return;
|
||||
}
|
||||
|
||||
ins->name=stripPath;
|
||||
|
@ -228,16 +98,14 @@ std::vector<DivInstrument*> DivEngine::instrumentFromFile(const char* path) {
|
|||
logD("instrument type is unknown\n");
|
||||
lastError="unknown instrument type!";
|
||||
delete ins;
|
||||
delete[] buf;
|
||||
return ret;
|
||||
return;
|
||||
break;
|
||||
}
|
||||
} catch (EndOfFileException& e) {
|
||||
lastError="premature end of file";
|
||||
logE("premature end of file!\n");
|
||||
delete ins;
|
||||
delete[] buf;
|
||||
return ret;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -429,12 +297,14 @@ std::vector<DivInstrument*> DivEngine::instrumentFromFile(const char* path) {
|
|||
lastError="premature end of file";
|
||||
logE("premature end of file!\n");
|
||||
delete ins;
|
||||
delete[] buf;
|
||||
return ret;
|
||||
return;
|
||||
}
|
||||
break;
|
||||
|
||||
ret.push_back(ins);
|
||||
}
|
||||
case DIV_INSFORMAT_TFI:
|
||||
|
||||
void DivEngine::loadTFI(SafeReader& reader, std::vector<DivInstrument*>& ret, String& stripPath) {
|
||||
DivInstrument* ins=new DivInstrument;
|
||||
try {
|
||||
reader.seek(0,SEEK_SET);
|
||||
|
||||
|
@ -462,11 +332,14 @@ std::vector<DivInstrument*> DivEngine::instrumentFromFile(const char* path) {
|
|||
lastError="premature end of file";
|
||||
logE("premature end of file!\n");
|
||||
delete ins;
|
||||
delete[] buf;
|
||||
return ret;
|
||||
return;
|
||||
}
|
||||
break;
|
||||
case DIV_INSFORMAT_VGI:
|
||||
|
||||
ret.push_back(ins);
|
||||
}
|
||||
|
||||
void DivEngine::loadVGI(SafeReader& reader, std::vector<DivInstrument*>& ret, String& stripPath) {
|
||||
DivInstrument* ins=new DivInstrument;
|
||||
try {
|
||||
reader.seek(0,SEEK_SET);
|
||||
|
||||
|
@ -501,17 +374,14 @@ std::vector<DivInstrument*> DivEngine::instrumentFromFile(const char* path) {
|
|||
lastError="premature end of file";
|
||||
logE("premature end of file!\n");
|
||||
delete ins;
|
||||
delete[] buf;
|
||||
return ret;
|
||||
return;
|
||||
}
|
||||
break;
|
||||
case DIV_INSFORMAT_FTI: // TODO
|
||||
break;
|
||||
case DIV_INSFORMAT_BTI: // TODO
|
||||
break;
|
||||
case DIV_INSFORMAT_OPM: // TODO
|
||||
break;
|
||||
case DIV_INSFORMAT_S3I:
|
||||
|
||||
ret.push_back(ins);
|
||||
}
|
||||
|
||||
void DivEngine::loadS3I(SafeReader& reader, std::vector<DivInstrument*>& ret, String& stripPath) {
|
||||
DivInstrument* ins=new DivInstrument;
|
||||
try {
|
||||
reader.seek(0, SEEK_SET);
|
||||
|
||||
|
@ -581,16 +451,18 @@ std::vector<DivInstrument*> DivEngine::instrumentFromFile(const char* path) {
|
|||
if (s3i_signature != 0x49524353) {
|
||||
logW("S3I signature invalid.");
|
||||
};
|
||||
}
|
||||
catch (EndOfFileException& e) {
|
||||
} catch (EndOfFileException& e) {
|
||||
lastError = "premature end of file";
|
||||
logE("premature end of file!\n");
|
||||
delete ins;
|
||||
delete[] buf;
|
||||
return ret;
|
||||
return;
|
||||
}
|
||||
break;
|
||||
case DIV_INSFORMAT_SBI:
|
||||
|
||||
ret.push_back(ins);
|
||||
}
|
||||
|
||||
void DivEngine::loadSBI(SafeReader& reader, std::vector<DivInstrument*>& ret, String& stripPath) {
|
||||
DivInstrument* ins=new DivInstrument;
|
||||
try {
|
||||
reader.seek(0, SEEK_SET);
|
||||
ins->type = DIV_INS_OPL;
|
||||
|
@ -753,9 +625,176 @@ std::vector<DivInstrument*> DivEngine::instrumentFromFile(const char* path) {
|
|||
lastError = "premature end of file";
|
||||
logE("premature end of file!\n");
|
||||
delete ins;
|
||||
return;
|
||||
}
|
||||
|
||||
ret.push_back(ins);
|
||||
}
|
||||
|
||||
void DivEngine::loadOPM(SafeReader& reader, std::vector<DivInstrument*>& ret, String& stripPath) {
|
||||
DivInstrument* ins[128];
|
||||
memset(ins,0,128*sizeof(DivInstrument*));
|
||||
|
||||
try {
|
||||
String line;
|
||||
|
||||
} catch (EndOfFileException& e) {
|
||||
lastError="premature end of file";
|
||||
logE("premature end of file!\n");
|
||||
delete ins;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
std::vector<DivInstrument*> DivEngine::instrumentFromFile(const char* path) {
|
||||
std::vector<DivInstrument*> ret;
|
||||
warnings="";
|
||||
|
||||
const char* pathRedux=strrchr(path,DIR_SEPARATOR);
|
||||
if (pathRedux==NULL) {
|
||||
pathRedux=path;
|
||||
} else {
|
||||
pathRedux++;
|
||||
}
|
||||
String stripPath;
|
||||
const char* pathReduxEnd=strrchr(pathRedux,'.');
|
||||
if (pathReduxEnd==NULL) {
|
||||
stripPath=pathRedux;
|
||||
} else {
|
||||
for (const char* i=pathRedux; i!=pathReduxEnd && (*i); i++) {
|
||||
stripPath+=*i;
|
||||
}
|
||||
}
|
||||
|
||||
FILE* f=ps_fopen(path,"rb");
|
||||
if (f==NULL) {
|
||||
lastError=strerror(errno);
|
||||
return ret;
|
||||
}
|
||||
unsigned char* buf;
|
||||
ssize_t len;
|
||||
if (fseek(f,0,SEEK_END)!=0) {
|
||||
lastError=strerror(errno);
|
||||
fclose(f);
|
||||
return ret;
|
||||
}
|
||||
len=ftell(f);
|
||||
if (len<0) {
|
||||
lastError=strerror(errno);
|
||||
fclose(f);
|
||||
return ret;
|
||||
}
|
||||
if (len==0) {
|
||||
lastError=strerror(errno);
|
||||
fclose(f);
|
||||
return ret;
|
||||
}
|
||||
if (fseek(f,0,SEEK_SET)!=0) {
|
||||
lastError=strerror(errno);
|
||||
fclose(f);
|
||||
return ret;
|
||||
}
|
||||
buf=new unsigned char[len];
|
||||
if (fread(buf,1,len,f)!=(size_t)len) {
|
||||
logW("did not read entire instrument file buffer!\n");
|
||||
lastError="did not read entire instrument file!";
|
||||
delete[] buf;
|
||||
return ret;
|
||||
}
|
||||
fclose(f);
|
||||
|
||||
SafeReader reader=SafeReader(buf,len);
|
||||
|
||||
unsigned char magic[16];
|
||||
bool isFurnaceInstr=false;
|
||||
try {
|
||||
reader.read(magic,16);
|
||||
if (memcmp("-Furnace instr.-",magic,16)==0) {
|
||||
isFurnaceInstr=true;
|
||||
}
|
||||
} catch (EndOfFileException& e) {
|
||||
reader.seek(0,SEEK_SET);
|
||||
}
|
||||
|
||||
if (isFurnaceInstr) {
|
||||
DivInstrument* ins=new DivInstrument;
|
||||
try {
|
||||
short version=reader.readS();
|
||||
reader.readS(); // reserved
|
||||
|
||||
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 (ins->readInsData(reader,version)!=DIV_DATA_SUCCESS) {
|
||||
lastError="invalid instrument header/data!";
|
||||
delete ins;
|
||||
delete[] buf;
|
||||
return ret;
|
||||
}
|
||||
} catch (EndOfFileException& e) {
|
||||
lastError="premature end of file";
|
||||
logE("premature end of file!\n");
|
||||
delete ins;
|
||||
delete[] buf;
|
||||
return ret;
|
||||
}
|
||||
} else { // read as a different format
|
||||
const char* ext=strrchr(path,'.');
|
||||
DivInsFormats format=DIV_INSFORMAT_DMP;
|
||||
if (ext!=NULL) {
|
||||
String extS;
|
||||
for (; *ext; ext++) {
|
||||
char i=*ext;
|
||||
if (i>='A' && i<='Z') {
|
||||
i+='a'-'A';
|
||||
}
|
||||
extS+=i;
|
||||
}
|
||||
if (extS==String(".dmp")) {
|
||||
format=DIV_INSFORMAT_DMP;
|
||||
} else if (extS==String(".tfi")) {
|
||||
format=DIV_INSFORMAT_TFI;
|
||||
} else if (extS==String(".vgi")) {
|
||||
format=DIV_INSFORMAT_VGI;
|
||||
} else if (extS==String(".fti")) {
|
||||
format=DIV_INSFORMAT_FTI;
|
||||
} else if (extS==String(".bti")) {
|
||||
format=DIV_INSFORMAT_BTI;
|
||||
} else if (extS==String(".s3i")) {
|
||||
format=DIV_INSFORMAT_S3I;
|
||||
} else if (extS==String(".sbi")) {
|
||||
format=DIV_INSFORMAT_SBI;
|
||||
} else if (extS==String(".opm")) {
|
||||
format=DIV_INSFORMAT_OPM;
|
||||
}
|
||||
}
|
||||
|
||||
switch (format) {
|
||||
case DIV_INSFORMAT_DMP: {
|
||||
loadDMP(reader,ret,stripPath);
|
||||
break;
|
||||
}
|
||||
case DIV_INSFORMAT_TFI:
|
||||
loadTFI(reader,ret,stripPath);
|
||||
break;
|
||||
case DIV_INSFORMAT_VGI:
|
||||
loadVGI(reader,ret,stripPath);
|
||||
break;
|
||||
case DIV_INSFORMAT_FTI: // TODO
|
||||
break;
|
||||
case DIV_INSFORMAT_BTI: // TODO
|
||||
break;
|
||||
case DIV_INSFORMAT_OPM: // TODO
|
||||
break;
|
||||
case DIV_INSFORMAT_S3I:
|
||||
loadS3I(reader,ret,stripPath);
|
||||
break;
|
||||
case DIV_INSFORMAT_SBI:
|
||||
loadSBI(reader,ret,stripPath);
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -766,6 +805,5 @@ std::vector<DivInstrument*> DivEngine::instrumentFromFile(const char* path) {
|
|||
}
|
||||
}
|
||||
|
||||
ret.push_back(ins);
|
||||
return ret;
|
||||
}
|
Loading…
Reference in a new issue