re-organize instrument loading code
This commit is contained in:
parent
82ae2bf877
commit
109f80d4da
|
@ -273,6 +273,13 @@ class DivEngine {
|
||||||
bool loadFur(unsigned char* file, size_t len);
|
bool loadFur(unsigned char* file, size_t len);
|
||||||
bool loadMod(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 initAudioBackend();
|
||||||
bool deinitAudioBackend();
|
bool deinitAudioBackend();
|
||||||
|
|
||||||
|
|
|
@ -33,136 +33,8 @@ enum DivInsFormats {
|
||||||
DIV_INSFORMAT_OPM
|
DIV_INSFORMAT_OPM
|
||||||
};
|
};
|
||||||
|
|
||||||
std::vector<DivInstrument*> DivEngine::instrumentFromFile(const char* path) {
|
void DivEngine::loadDMP(SafeReader& reader, std::vector<DivInstrument*>& ret, String& stripPath) {
|
||||||
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);
|
|
||||||
}
|
|
||||||
|
|
||||||
DivInstrument* ins=new DivInstrument;
|
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
|
// this is a ridiculous mess
|
||||||
unsigned char version=0;
|
unsigned char version=0;
|
||||||
unsigned char sys=0;
|
unsigned char sys=0;
|
||||||
|
@ -174,15 +46,13 @@ std::vector<DivInstrument*> DivEngine::instrumentFromFile(const char* path) {
|
||||||
lastError="premature end of file";
|
lastError="premature end of file";
|
||||||
logE("premature end of file!\n");
|
logE("premature end of file!\n");
|
||||||
delete ins;
|
delete ins;
|
||||||
delete[] buf;
|
return;
|
||||||
return ret;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (version>11) {
|
if (version>11) {
|
||||||
lastError="unknown instrument version!";
|
lastError="unknown instrument version!";
|
||||||
delete ins;
|
delete ins;
|
||||||
delete[] buf;
|
return;
|
||||||
return ret;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ins->name=stripPath;
|
ins->name=stripPath;
|
||||||
|
@ -228,16 +98,14 @@ std::vector<DivInstrument*> DivEngine::instrumentFromFile(const char* path) {
|
||||||
logD("instrument type is unknown\n");
|
logD("instrument type is unknown\n");
|
||||||
lastError="unknown instrument type!";
|
lastError="unknown instrument type!";
|
||||||
delete ins;
|
delete ins;
|
||||||
delete[] buf;
|
return;
|
||||||
return ret;
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
} catch (EndOfFileException& e) {
|
} catch (EndOfFileException& e) {
|
||||||
lastError="premature end of file";
|
lastError="premature end of file";
|
||||||
logE("premature end of file!\n");
|
logE("premature end of file!\n");
|
||||||
delete ins;
|
delete ins;
|
||||||
delete[] buf;
|
return;
|
||||||
return ret;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -429,12 +297,14 @@ std::vector<DivInstrument*> DivEngine::instrumentFromFile(const char* path) {
|
||||||
lastError="premature end of file";
|
lastError="premature end of file";
|
||||||
logE("premature end of file!\n");
|
logE("premature end of file!\n");
|
||||||
delete ins;
|
delete ins;
|
||||||
delete[] buf;
|
return;
|
||||||
return ret;
|
|
||||||
}
|
}
|
||||||
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 {
|
try {
|
||||||
reader.seek(0,SEEK_SET);
|
reader.seek(0,SEEK_SET);
|
||||||
|
|
||||||
|
@ -462,11 +332,14 @@ std::vector<DivInstrument*> DivEngine::instrumentFromFile(const char* path) {
|
||||||
lastError="premature end of file";
|
lastError="premature end of file";
|
||||||
logE("premature end of file!\n");
|
logE("premature end of file!\n");
|
||||||
delete ins;
|
delete ins;
|
||||||
delete[] buf;
|
return;
|
||||||
return ret;
|
|
||||||
}
|
}
|
||||||
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 {
|
try {
|
||||||
reader.seek(0,SEEK_SET);
|
reader.seek(0,SEEK_SET);
|
||||||
|
|
||||||
|
@ -501,17 +374,14 @@ std::vector<DivInstrument*> DivEngine::instrumentFromFile(const char* path) {
|
||||||
lastError="premature end of file";
|
lastError="premature end of file";
|
||||||
logE("premature end of file!\n");
|
logE("premature end of file!\n");
|
||||||
delete ins;
|
delete ins;
|
||||||
delete[] buf;
|
return;
|
||||||
return ret;
|
|
||||||
}
|
}
|
||||||
break;
|
|
||||||
case DIV_INSFORMAT_FTI: // TODO
|
ret.push_back(ins);
|
||||||
break;
|
}
|
||||||
case DIV_INSFORMAT_BTI: // TODO
|
|
||||||
break;
|
void DivEngine::loadS3I(SafeReader& reader, std::vector<DivInstrument*>& ret, String& stripPath) {
|
||||||
case DIV_INSFORMAT_OPM: // TODO
|
DivInstrument* ins=new DivInstrument;
|
||||||
break;
|
|
||||||
case DIV_INSFORMAT_S3I:
|
|
||||||
try {
|
try {
|
||||||
reader.seek(0, SEEK_SET);
|
reader.seek(0, SEEK_SET);
|
||||||
|
|
||||||
|
@ -581,16 +451,18 @@ std::vector<DivInstrument*> DivEngine::instrumentFromFile(const char* path) {
|
||||||
if (s3i_signature != 0x49524353) {
|
if (s3i_signature != 0x49524353) {
|
||||||
logW("S3I signature invalid.");
|
logW("S3I signature invalid.");
|
||||||
};
|
};
|
||||||
}
|
} catch (EndOfFileException& e) {
|
||||||
catch (EndOfFileException& e) {
|
|
||||||
lastError = "premature end of file";
|
lastError = "premature end of file";
|
||||||
logE("premature end of file!\n");
|
logE("premature end of file!\n");
|
||||||
delete ins;
|
delete ins;
|
||||||
delete[] buf;
|
return;
|
||||||
return ret;
|
|
||||||
}
|
}
|
||||||
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 {
|
try {
|
||||||
reader.seek(0, SEEK_SET);
|
reader.seek(0, SEEK_SET);
|
||||||
ins->type = DIV_INS_OPL;
|
ins->type = DIV_INS_OPL;
|
||||||
|
@ -753,9 +625,176 @@ std::vector<DivInstrument*> DivEngine::instrumentFromFile(const char* path) {
|
||||||
lastError = "premature end of file";
|
lastError = "premature end of file";
|
||||||
logE("premature end of file!\n");
|
logE("premature end of file!\n");
|
||||||
delete ins;
|
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;
|
delete[] buf;
|
||||||
return ret;
|
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;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -766,6 +805,5 @@ std::vector<DivInstrument*> DivEngine::instrumentFromFile(const char* path) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ret.push_back(ins);
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
Loading…
Reference in a new issue