diff --git a/src/engine/engine.cpp b/src/engine/engine.cpp index 320425c7f..e96005405 100644 --- a/src/engine/engine.cpp +++ b/src/engine/engine.cpp @@ -1594,6 +1594,7 @@ void DivEngine::unmuteAll() { } int DivEngine::addInstrument(int refChan) { + if (song.ins.size()>=256) return -1; BUSY_BEGIN; DivInstrument* ins=new DivInstrument; int insCount=(int)song.ins.size(); @@ -1624,6 +1625,10 @@ int DivEngine::addInstrument(int refChan) { } int DivEngine::addInstrumentPtr(DivInstrument* which) { + if (song.ins.size()>=256) { + delete which; + return -1; + } BUSY_BEGIN; saveLock.lock(); song.ins.push_back(which); @@ -1668,6 +1673,7 @@ void DivEngine::delInstrument(int index) { } int DivEngine::addWave() { + if (song.wave.size()>=256) return -1; BUSY_BEGIN; saveLock.lock(); DivWavetable* wave=new DivWavetable; @@ -1680,37 +1686,48 @@ int DivEngine::addWave() { } bool DivEngine::addWaveFromFile(const char* path) { + if (song.wave.size()>=256) { + lastError="too many wavetables!"; + return false; + } FILE* f=ps_fopen(path,"rb"); if (f==NULL) { + lastError=fmt::sprintf("%s",strerror(errno)); return false; } unsigned char* buf; ssize_t len; if (fseek(f,0,SEEK_END)!=0) { fclose(f); + lastError=fmt::sprintf("could not seek to end: %s",strerror(errno)); return false; } len=ftell(f); if (len<0) { fclose(f); + lastError=fmt::sprintf("could not determine file size: %s",strerror(errno)); return false; } if (len==(SIZE_MAX>>1)) { fclose(f); + lastError="file size is invalid!"; return false; } if (len==0) { fclose(f); + lastError="file is empty"; return false; } if (fseek(f,0,SEEK_SET)!=0) { fclose(f); + lastError=fmt::sprintf("could not seek to beginning: %s",strerror(errno)); return false; } buf=new unsigned char[len]; if (fread(buf,1,len,f)!=(size_t)len) { logW("did not read entire wavetable file buffer!"); delete[] buf; + lastError=fmt::sprintf("could not read entire file: %s",strerror(errno)); return false; } fclose(f); @@ -1790,6 +1807,7 @@ bool DivEngine::addWaveFromFile(const char* path) { } catch (EndOfFileException& e) { delete wave; delete[] buf; + lastError="premature end of file"; return false; } @@ -1816,6 +1834,7 @@ void DivEngine::delWave(int index) { } int DivEngine::addSample() { + if (song.sample.size()>=256) return -1; BUSY_BEGIN; saveLock.lock(); DivSample* sample=new DivSample; @@ -1830,6 +1849,10 @@ int DivEngine::addSample() { } int DivEngine::addSampleFromFile(const char* path) { + if (song.sample.size()>=256) { + lastError="too many samples!"; + return -1; + } BUSY_BEGIN; warnings=""; diff --git a/src/gui/doAction.cpp b/src/gui/doAction.cpp index 2e1dd3779..8a71d9a38 100644 --- a/src/gui/doAction.cpp +++ b/src/gui/doAction.cpp @@ -525,14 +525,22 @@ void FurnaceGUI::doAction(int what) { case GUI_ACTION_INS_LIST_ADD: curIns=e->addInstrument(cursor.xCoarse); - MARK_MODIFIED; + if (curIns==-1) { + showError("too many instruments!"); + } else { + MARK_MODIFIED; + } break; case GUI_ACTION_INS_LIST_DUPLICATE: if (curIns>=0 && curIns<(int)e->song.ins.size()) { int prevIns=curIns; curIns=e->addInstrument(cursor.xCoarse); - (*e->song.ins[curIns])=(*e->song.ins[prevIns]); - MARK_MODIFIED; + if (curIns==-1) { + showError("too many instruments!"); + } else { + (*e->song.ins[curIns])=(*e->song.ins[prevIns]); + MARK_MODIFIED; + } } break; case GUI_ACTION_INS_LIST_OPEN: @@ -571,14 +579,22 @@ void FurnaceGUI::doAction(int what) { case GUI_ACTION_WAVE_LIST_ADD: curWave=e->addWave(); - MARK_MODIFIED; + if (curWave==-1) { + showError("too many wavetables!"); + } else { + MARK_MODIFIED; + } break; case GUI_ACTION_WAVE_LIST_DUPLICATE: if (curWave>=0 && curWave<(int)e->song.wave.size()) { int prevWave=curWave; curWave=e->addWave(); - (*e->song.wave[curWave])=(*e->song.wave[prevWave]); - MARK_MODIFIED; + if (curWave==-1) { + showError("too many wavetables!"); + } else { + (*e->song.wave[curWave])=(*e->song.wave[prevWave]); + MARK_MODIFIED; + } } break; case GUI_ACTION_WAVE_LIST_OPEN: @@ -614,31 +630,39 @@ void FurnaceGUI::doAction(int what) { case GUI_ACTION_SAMPLE_LIST_ADD: curSample=e->addSample(); + if (curSample==-1) { + showError("too many samples!"); + } else { + MARK_MODIFIED; + } updateSampleTex=true; - MARK_MODIFIED; break; case GUI_ACTION_SAMPLE_LIST_DUPLICATE: if (curSample>=0 && curSample<(int)e->song.sample.size()) { DivSample* prevSample=e->getSample(curSample); curSample=e->addSample(); - updateSampleTex=true; - e->lockEngine([this,prevSample]() { - DivSample* sample=e->getSample(curSample); - if (sample!=NULL) { - sample->rate=prevSample->rate; - sample->centerRate=prevSample->centerRate; - sample->name=prevSample->name; - sample->loopStart=prevSample->loopStart; - sample->depth=prevSample->depth; - if (sample->init(prevSample->samples)) { - if (prevSample->getCurBuf()!=NULL) { - memcpy(sample->getCurBuf(),prevSample->getCurBuf(),prevSample->getCurBufLen()); + if (curSample==-1) { + showError("too many samples!"); + } else { + e->lockEngine([this,prevSample]() { + DivSample* sample=e->getSample(curSample); + if (sample!=NULL) { + sample->rate=prevSample->rate; + sample->centerRate=prevSample->centerRate; + sample->name=prevSample->name; + sample->loopStart=prevSample->loopStart; + sample->depth=prevSample->depth; + if (sample->init(prevSample->samples)) { + if (prevSample->getCurBuf()!=NULL) { + memcpy(sample->getCurBuf(),prevSample->getCurBuf(),prevSample->getCurBufLen()); + } } } - } - e->renderSamples(); - }); - MARK_MODIFIED; + e->renderSamples(); + }); + MARK_MODIFIED; + } + updateSampleTex=true; } break; case GUI_ACTION_SAMPLE_LIST_OPEN: @@ -1154,11 +1178,15 @@ void FurnaceGUI::doAction(int what) { if (curSample<0 || curSample>=(int)e->song.sample.size()) break; DivSample* sample=e->song.sample[curSample]; curIns=e->addInstrument(cursor.xCoarse); - e->song.ins[curIns]->type=DIV_INS_AMIGA; - e->song.ins[curIns]->name=sample->name; - e->song.ins[curIns]->amiga.initSample=curSample; - nextWindow=GUI_WINDOW_INS_EDIT; - MARK_MODIFIED; + if (curIns==-1) { + showError("too many instruments!"); + } else { + e->song.ins[curIns]->type=DIV_INS_AMIGA; + e->song.ins[curIns]->name=sample->name; + e->song.ins[curIns]->amiga.initSample=curSample; + nextWindow=GUI_WINDOW_INS_EDIT; + MARK_MODIFIED; + } break; } diff --git a/src/gui/gui.cpp b/src/gui/gui.cpp index c52809b05..00f0da2b3 100644 --- a/src/gui/gui.cpp +++ b/src/gui/gui.cpp @@ -3161,8 +3161,11 @@ bool FurnaceGUI::loop() { break; } case GUI_FILE_WAVE_OPEN: - e->addWaveFromFile(copyOfName.c_str()); - MARK_MODIFIED; + if (!e->addWaveFromFile(copyOfName.c_str())) { + showError("cannot load wavetable! ("+e->getLastError()+")"); + } else { + MARK_MODIFIED; + } break; case GUI_FILE_EXPORT_VGM: { SafeWriter* w=e->saveVGM(willExport,vgmExportLoop,vgmExportVersion);