re-organize instrument loading code

This commit is contained in:
tildearrow 2022-04-03 13:53:34 -05:00
parent 82ae2bf877
commit 109f80d4da
2 changed files with 627 additions and 582 deletions

View file

@ -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();

View file

@ -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;
}