diff --git a/src/engine/engine.cpp b/src/engine/engine.cpp index 876a8b2d..d465a1be 100644 --- a/src/engine/engine.cpp +++ b/src/engine/engine.cpp @@ -1260,6 +1260,16 @@ int DivEngine::addInstrument(int refChan) { return insCount; } +int DivEngine::addInstrumentPtr(DivInstrument* which) { + BUSY_BEGIN; + saveLock.lock(); + song.ins.push_back(which); + song.insLen=song.ins.size(); + saveLock.unlock(); + BUSY_END; + return song.insLen; +} + enum DivInsFormats { DIV_INSFORMAT_DMP, DIV_INSFORMAT_TFI, @@ -1268,12 +1278,14 @@ enum DivInsFormats { DIV_INSFORMAT_BTI, DIV_INSFORMAT_S3I, DIV_INSFORMAT_SBI, + DIV_INSFORMAT_OPM }; // TODO: re-organize this function to: // - support replacing instruments // - support instrument formats which contain multiple instruments -bool DivEngine::addInstrumentFromFile(const char* path) { +std::vector DivEngine::instrumentFromFile(const char* path) { + std::vector ret; warnings=""; const char* pathRedux=strrchr(path,DIR_SEPARATOR); @@ -1295,37 +1307,37 @@ bool DivEngine::addInstrumentFromFile(const char* path) { FILE* f=ps_fopen(path,"rb"); if (f==NULL) { lastError=strerror(errno); - return false; + return ret; } unsigned char* buf; ssize_t len; if (fseek(f,0,SEEK_END)!=0) { lastError=strerror(errno); fclose(f); - return false; + return ret; } len=ftell(f); if (len<0) { lastError=strerror(errno); fclose(f); - return false; + return ret; } if (len==0) { lastError=strerror(errno); fclose(f); - return false; + return ret; } if (fseek(f,0,SEEK_SET)!=0) { lastError=strerror(errno); fclose(f); - return false; + 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 false; + return ret; } fclose(f); @@ -1359,14 +1371,14 @@ bool DivEngine::addInstrumentFromFile(const char* path) { lastError="invalid instrument header/data!"; delete ins; delete[] buf; - return false; + return ret; } } catch (EndOfFileException& e) { lastError="premature end of file"; logE("premature end of file!\n"); delete ins; delete[] buf; - return false; + return ret; } } else { // read as a different format const char* ext=strrchr(path,'.'); @@ -1412,14 +1424,14 @@ bool DivEngine::addInstrumentFromFile(const char* path) { logE("premature end of file!\n"); delete ins; delete[] buf; - return false; + return ret; } if (version>11) { lastError="unknown instrument version!"; delete ins; delete[] buf; - return false; + return ret; } ins->name=stripPath; @@ -1466,7 +1478,7 @@ bool DivEngine::addInstrumentFromFile(const char* path) { lastError="unknown instrument type!"; delete ins; delete[] buf; - return false; + return ret; break; } } catch (EndOfFileException& e) { @@ -1474,7 +1486,7 @@ bool DivEngine::addInstrumentFromFile(const char* path) { logE("premature end of file!\n"); delete ins; delete[] buf; - return false; + return ret; } } @@ -1661,7 +1673,7 @@ bool DivEngine::addInstrumentFromFile(const char* path) { logE("premature end of file!\n"); delete ins; delete[] buf; - return false; + return ret; } break; } @@ -1694,7 +1706,7 @@ bool DivEngine::addInstrumentFromFile(const char* path) { logE("premature end of file!\n"); delete ins; delete[] buf; - return false; + return ret; } break; case DIV_INSFORMAT_VGI: @@ -1733,12 +1745,14 @@ bool DivEngine::addInstrumentFromFile(const char* path) { logE("premature end of file!\n"); delete ins; delete[] buf; - return false; + return ret; } break; - case DIV_INSFORMAT_FTI: + case DIV_INSFORMAT_FTI: // TODO break; - case DIV_INSFORMAT_BTI: + case DIV_INSFORMAT_BTI: // TODO + break; + case DIV_INSFORMAT_OPM: // TODO break; case DIV_INSFORMAT_S3I: try { @@ -1816,7 +1830,7 @@ bool DivEngine::addInstrumentFromFile(const char* path) { logE("premature end of file!\n"); delete ins; delete[] buf; - return false; + return ret; } break; case DIV_INSFORMAT_SBI: @@ -1983,7 +1997,7 @@ bool DivEngine::addInstrumentFromFile(const char* path) { logE("premature end of file!\n"); delete ins; delete[] buf; - return false; + return ret; } break; } @@ -1995,14 +2009,8 @@ bool DivEngine::addInstrumentFromFile(const char* path) { } } - BUSY_BEGIN; - saveLock.lock(); - int insCount=(int)song.ins.size(); - song.ins.push_back(ins); - song.insLen=insCount+1; - saveLock.unlock(); - BUSY_END; - return true; + ret.push_back(ins); + return ret; } void DivEngine::delInstrument(int index) { diff --git a/src/engine/engine.h b/src/engine/engine.h index c8f539e9..56ab10b0 100644 --- a/src/engine/engine.h +++ b/src/engine/engine.h @@ -491,8 +491,12 @@ class DivEngine { // add instrument int addInstrument(int refChan=0); - // add instrument from file - bool addInstrumentFromFile(const char* path); + // add instrument from pointer + int addInstrumentPtr(DivInstrument* which); + + // get instrument from file + // if the returned vector is empty then there was an error. + std::vector instrumentFromFile(const char* path); // delete instrument void delInstrument(int index); diff --git a/src/gui/gui.cpp b/src/gui/gui.cpp index cac32346..2d7a4222 100644 --- a/src/gui/gui.cpp +++ b/src/gui/gui.cpp @@ -2628,15 +2628,20 @@ bool FurnaceGUI::loop() { case GUI_FILE_EXPORT_AUDIO_PER_CHANNEL: exportAudio(copyOfName,DIV_EXPORT_MODE_MANY_CHAN); break; - case GUI_FILE_INS_OPEN: - if (e->addInstrumentFromFile(copyOfName.c_str())) { + case GUI_FILE_INS_OPEN: { + std::vector instruments=e->instrumentFromFile(copyOfName.c_str()); + if (!instruments.empty()) { if (!e->getWarnings().empty()) { showWarning(e->getWarnings(),GUI_WARN_GENERIC); } + for (DivInstrument* i: instruments) { + e->addInstrumentPtr(i); + } } else { showError("cannot load instrument! ("+e->getLastError()+")"); } break; + } case GUI_FILE_WAVE_OPEN: e->addWaveFromFile(copyOfName.c_str()); MARK_MODIFIED;