GUI: add replace for wave/sample and prepare for
raw sample import
This commit is contained in:
parent
4707eb7002
commit
ce2d322e47
|
@ -2196,7 +2196,10 @@ void DivEngine::delInstrument(int index) {
|
||||||
}
|
}
|
||||||
|
|
||||||
int DivEngine::addWave() {
|
int DivEngine::addWave() {
|
||||||
if (song.wave.size()>=256) return -1;
|
if (song.wave.size()>=256) {
|
||||||
|
lastError="too many wavetables!";
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
BUSY_BEGIN;
|
BUSY_BEGIN;
|
||||||
saveLock.lock();
|
saveLock.lock();
|
||||||
DivWavetable* wave=new DivWavetable;
|
DivWavetable* wave=new DivWavetable;
|
||||||
|
@ -2208,50 +2211,62 @@ int DivEngine::addWave() {
|
||||||
return waveCount;
|
return waveCount;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool DivEngine::addWaveFromFile(const char* path, bool addRaw) {
|
int DivEngine::addWavePtr(DivWavetable* which) {
|
||||||
if (song.wave.size()>=256) {
|
if (song.wave.size()>=256) {
|
||||||
lastError="too many wavetables!";
|
lastError="too many wavetables!";
|
||||||
return false;
|
delete which;
|
||||||
|
return -1;
|
||||||
}
|
}
|
||||||
|
BUSY_BEGIN;
|
||||||
|
saveLock.lock();
|
||||||
|
int waveCount=(int)song.wave.size();
|
||||||
|
song.wave.push_back(which);
|
||||||
|
song.waveLen=waveCount+1;
|
||||||
|
saveLock.unlock();
|
||||||
|
BUSY_END;
|
||||||
|
return song.waveLen;
|
||||||
|
}
|
||||||
|
|
||||||
|
DivWavetable* DivEngine::waveFromFile(const char* path, bool addRaw) {
|
||||||
FILE* f=ps_fopen(path,"rb");
|
FILE* f=ps_fopen(path,"rb");
|
||||||
if (f==NULL) {
|
if (f==NULL) {
|
||||||
lastError=fmt::sprintf("%s",strerror(errno));
|
lastError=fmt::sprintf("%s",strerror(errno));
|
||||||
return false;
|
return NULL;
|
||||||
}
|
}
|
||||||
unsigned char* buf;
|
unsigned char* buf;
|
||||||
ssize_t len;
|
ssize_t len;
|
||||||
if (fseek(f,0,SEEK_END)!=0) {
|
if (fseek(f,0,SEEK_END)!=0) {
|
||||||
fclose(f);
|
fclose(f);
|
||||||
lastError=fmt::sprintf("could not seek to end: %s",strerror(errno));
|
lastError=fmt::sprintf("could not seek to end: %s",strerror(errno));
|
||||||
return false;
|
return NULL;
|
||||||
}
|
}
|
||||||
len=ftell(f);
|
len=ftell(f);
|
||||||
if (len<0) {
|
if (len<0) {
|
||||||
fclose(f);
|
fclose(f);
|
||||||
lastError=fmt::sprintf("could not determine file size: %s",strerror(errno));
|
lastError=fmt::sprintf("could not determine file size: %s",strerror(errno));
|
||||||
return false;
|
return NULL;
|
||||||
}
|
}
|
||||||
if (len==(SIZE_MAX>>1)) {
|
if (len==(SIZE_MAX>>1)) {
|
||||||
fclose(f);
|
fclose(f);
|
||||||
lastError="file size is invalid!";
|
lastError="file size is invalid!";
|
||||||
return false;
|
return NULL;
|
||||||
}
|
}
|
||||||
if (len==0) {
|
if (len==0) {
|
||||||
fclose(f);
|
fclose(f);
|
||||||
lastError="file is empty";
|
lastError="file is empty";
|
||||||
return false;
|
return NULL;
|
||||||
}
|
}
|
||||||
if (fseek(f,0,SEEK_SET)!=0) {
|
if (fseek(f,0,SEEK_SET)!=0) {
|
||||||
fclose(f);
|
fclose(f);
|
||||||
lastError=fmt::sprintf("could not seek to beginning: %s",strerror(errno));
|
lastError=fmt::sprintf("could not seek to beginning: %s",strerror(errno));
|
||||||
return false;
|
return NULL;
|
||||||
}
|
}
|
||||||
buf=new unsigned char[len];
|
buf=new unsigned char[len];
|
||||||
if (fread(buf,1,len,f)!=(size_t)len) {
|
if (fread(buf,1,len,f)!=(size_t)len) {
|
||||||
logW("did not read entire wavetable file buffer!");
|
logW("did not read entire wavetable file buffer!");
|
||||||
delete[] buf;
|
delete[] buf;
|
||||||
lastError=fmt::sprintf("could not read entire file: %s",strerror(errno));
|
lastError=fmt::sprintf("could not read entire file: %s",strerror(errno));
|
||||||
return false;
|
return NULL;
|
||||||
}
|
}
|
||||||
fclose(f);
|
fclose(f);
|
||||||
|
|
||||||
|
@ -2279,7 +2294,7 @@ bool DivEngine::addWaveFromFile(const char* path, bool addRaw) {
|
||||||
lastError="invalid wavetable header/data!";
|
lastError="invalid wavetable header/data!";
|
||||||
delete wave;
|
delete wave;
|
||||||
delete[] buf;
|
delete[] buf;
|
||||||
return false;
|
return NULL;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
try {
|
try {
|
||||||
|
@ -2320,7 +2335,7 @@ bool DivEngine::addWaveFromFile(const char* path, bool addRaw) {
|
||||||
} else {
|
} else {
|
||||||
delete wave;
|
delete wave;
|
||||||
delete[] buf;
|
delete[] buf;
|
||||||
return false;
|
return NULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} catch (EndOfFileException& e) {
|
} catch (EndOfFileException& e) {
|
||||||
|
@ -2338,7 +2353,7 @@ bool DivEngine::addWaveFromFile(const char* path, bool addRaw) {
|
||||||
} else {
|
} else {
|
||||||
delete wave;
|
delete wave;
|
||||||
delete[] buf;
|
delete[] buf;
|
||||||
return false;
|
return NULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2346,17 +2361,10 @@ bool DivEngine::addWaveFromFile(const char* path, bool addRaw) {
|
||||||
delete wave;
|
delete wave;
|
||||||
delete[] buf;
|
delete[] buf;
|
||||||
lastError="premature end of file";
|
lastError="premature end of file";
|
||||||
return false;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
BUSY_BEGIN;
|
return wave;
|
||||||
saveLock.lock();
|
|
||||||
int waveCount=(int)song.wave.size();
|
|
||||||
song.wave.push_back(wave);
|
|
||||||
song.waveLen=waveCount+1;
|
|
||||||
saveLock.unlock();
|
|
||||||
BUSY_END;
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void DivEngine::delWave(int index) {
|
void DivEngine::delWave(int index) {
|
||||||
|
@ -2372,7 +2380,10 @@ void DivEngine::delWave(int index) {
|
||||||
}
|
}
|
||||||
|
|
||||||
int DivEngine::addSample() {
|
int DivEngine::addSample() {
|
||||||
if (song.sample.size()>=256) return -1;
|
if (song.sample.size()>=256) {
|
||||||
|
lastError="too many samples!";
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
BUSY_BEGIN;
|
BUSY_BEGIN;
|
||||||
saveLock.lock();
|
saveLock.lock();
|
||||||
DivSample* sample=new DivSample;
|
DivSample* sample=new DivSample;
|
||||||
|
@ -2388,11 +2399,28 @@ int DivEngine::addSample() {
|
||||||
return sampleCount;
|
return sampleCount;
|
||||||
}
|
}
|
||||||
|
|
||||||
int DivEngine::addSampleFromFile(const char* path) {
|
int DivEngine::addSamplePtr(DivSample* which) {
|
||||||
if (song.sample.size()>=256) {
|
if (song.sample.size()>=256) {
|
||||||
lastError="too many samples!";
|
lastError="too many samples!";
|
||||||
|
delete which;
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
int sampleCount=(int)song.sample.size();
|
||||||
|
BUSY_BEGIN;
|
||||||
|
saveLock.lock();
|
||||||
|
song.sample.push_back(which);
|
||||||
|
song.sampleLen=sampleCount+1;
|
||||||
|
saveLock.unlock();
|
||||||
|
renderSamples();
|
||||||
|
BUSY_END;
|
||||||
|
return sampleCount;
|
||||||
|
}
|
||||||
|
|
||||||
|
DivSample* DivEngine::sampleFromFile(const char* path) {
|
||||||
|
if (song.sample.size()>=256) {
|
||||||
|
lastError="too many samples!";
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
BUSY_BEGIN;
|
BUSY_BEGIN;
|
||||||
warnings="";
|
warnings="";
|
||||||
|
|
||||||
|
@ -2425,7 +2453,6 @@ int DivEngine::addSampleFromFile(const char* path) {
|
||||||
if (extS==".dmc") { // read as .dmc
|
if (extS==".dmc") { // read as .dmc
|
||||||
size_t len=0;
|
size_t len=0;
|
||||||
DivSample* sample=new DivSample;
|
DivSample* sample=new DivSample;
|
||||||
int sampleCount=(int)song.sample.size();
|
|
||||||
sample->name=stripPath;
|
sample->name=stripPath;
|
||||||
|
|
||||||
FILE* f=ps_fopen(path,"rb");
|
FILE* f=ps_fopen(path,"rb");
|
||||||
|
@ -2433,7 +2460,7 @@ int DivEngine::addSampleFromFile(const char* path) {
|
||||||
BUSY_END;
|
BUSY_END;
|
||||||
lastError=fmt::sprintf("could not open file! (%s)",strerror(errno));
|
lastError=fmt::sprintf("could not open file! (%s)",strerror(errno));
|
||||||
delete sample;
|
delete sample;
|
||||||
return -1;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (fseek(f,0,SEEK_END)<0) {
|
if (fseek(f,0,SEEK_END)<0) {
|
||||||
|
@ -2441,7 +2468,7 @@ int DivEngine::addSampleFromFile(const char* path) {
|
||||||
BUSY_END;
|
BUSY_END;
|
||||||
lastError=fmt::sprintf("could not get file length! (%s)",strerror(errno));
|
lastError=fmt::sprintf("could not get file length! (%s)",strerror(errno));
|
||||||
delete sample;
|
delete sample;
|
||||||
return -1;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
len=ftell(f);
|
len=ftell(f);
|
||||||
|
@ -2451,7 +2478,7 @@ int DivEngine::addSampleFromFile(const char* path) {
|
||||||
BUSY_END;
|
BUSY_END;
|
||||||
lastError="file is empty!";
|
lastError="file is empty!";
|
||||||
delete sample;
|
delete sample;
|
||||||
return -1;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (len==(SIZE_MAX>>1)) {
|
if (len==(SIZE_MAX>>1)) {
|
||||||
|
@ -2459,7 +2486,7 @@ int DivEngine::addSampleFromFile(const char* path) {
|
||||||
BUSY_END;
|
BUSY_END;
|
||||||
lastError="file is invalid!";
|
lastError="file is invalid!";
|
||||||
delete sample;
|
delete sample;
|
||||||
return -1;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (fseek(f,0,SEEK_SET)<0) {
|
if (fseek(f,0,SEEK_SET)<0) {
|
||||||
|
@ -2467,7 +2494,7 @@ int DivEngine::addSampleFromFile(const char* path) {
|
||||||
BUSY_END;
|
BUSY_END;
|
||||||
lastError=fmt::sprintf("could not seek to beginning of file! (%s)",strerror(errno));
|
lastError=fmt::sprintf("could not seek to beginning of file! (%s)",strerror(errno));
|
||||||
delete sample;
|
delete sample;
|
||||||
return -1;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
sample->rate=33144;
|
sample->rate=33144;
|
||||||
|
@ -2480,22 +2507,16 @@ int DivEngine::addSampleFromFile(const char* path) {
|
||||||
BUSY_END;
|
BUSY_END;
|
||||||
lastError=fmt::sprintf("could not read file! (%s)",strerror(errno));
|
lastError=fmt::sprintf("could not read file! (%s)",strerror(errno));
|
||||||
delete sample;
|
delete sample;
|
||||||
return -1;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
saveLock.lock();
|
|
||||||
song.sample.push_back(sample);
|
|
||||||
song.sampleLen=sampleCount+1;
|
|
||||||
saveLock.unlock();
|
|
||||||
renderSamples();
|
|
||||||
BUSY_END;
|
BUSY_END;
|
||||||
return sampleCount;
|
return sample;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifndef HAVE_SNDFILE
|
#ifndef HAVE_SNDFILE
|
||||||
lastError="Furnace was not compiled with libsndfile!";
|
lastError="Furnace was not compiled with libsndfile!";
|
||||||
return -1;
|
return NULL;
|
||||||
#else
|
#else
|
||||||
SF_INFO si;
|
SF_INFO si;
|
||||||
SFWrapper sfWrap;
|
SFWrapper sfWrap;
|
||||||
|
@ -2507,15 +2528,15 @@ int DivEngine::addSampleFromFile(const char* path) {
|
||||||
if (err==SF_ERR_SYSTEM) {
|
if (err==SF_ERR_SYSTEM) {
|
||||||
lastError=fmt::sprintf("could not open file! (%s %s)",sf_error_number(err),strerror(errno));
|
lastError=fmt::sprintf("could not open file! (%s %s)",sf_error_number(err),strerror(errno));
|
||||||
} else {
|
} else {
|
||||||
lastError=fmt::sprintf("could not open file! (%s)",sf_error_number(err));
|
lastError=fmt::sprintf("could not open file! (%s)\nif this is raw sample data, you may import it by right-clicking the Load Sample icon and selecting \"import raw\".",sf_error_number(err));
|
||||||
}
|
}
|
||||||
return -1;
|
return NULL;
|
||||||
}
|
}
|
||||||
if (si.frames>16777215) {
|
if (si.frames>16777215) {
|
||||||
lastError="this sample is too big! max sample size is 16777215.";
|
lastError="this sample is too big! max sample size is 16777215.";
|
||||||
sfWrap.doClose();
|
sfWrap.doClose();
|
||||||
BUSY_END;
|
BUSY_END;
|
||||||
return -1;
|
return NULL;
|
||||||
}
|
}
|
||||||
void* buf=NULL;
|
void* buf=NULL;
|
||||||
sf_count_t sampleLen=sizeof(short);
|
sf_count_t sampleLen=sizeof(short);
|
||||||
|
@ -2613,13 +2634,8 @@ int DivEngine::addSampleFromFile(const char* path) {
|
||||||
if (sample->centerRate<4000) sample->centerRate=4000;
|
if (sample->centerRate<4000) sample->centerRate=4000;
|
||||||
if (sample->centerRate>64000) sample->centerRate=64000;
|
if (sample->centerRate>64000) sample->centerRate=64000;
|
||||||
sfWrap.doClose();
|
sfWrap.doClose();
|
||||||
saveLock.lock();
|
|
||||||
song.sample.push_back(sample);
|
|
||||||
song.sampleLen=sampleCount+1;
|
|
||||||
saveLock.unlock();
|
|
||||||
renderSamples();
|
|
||||||
BUSY_END;
|
BUSY_END;
|
||||||
return sampleCount;
|
return sample;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -706,8 +706,11 @@ class DivEngine {
|
||||||
// add wavetable
|
// add wavetable
|
||||||
int addWave();
|
int addWave();
|
||||||
|
|
||||||
// add wavetable from file
|
// add wavetable from pointer
|
||||||
bool addWaveFromFile(const char* path, bool loadRaw=true);
|
int addWavePtr(DivWavetable* which);
|
||||||
|
|
||||||
|
// get wavetable from file
|
||||||
|
DivWavetable* waveFromFile(const char* path, bool loadRaw=true);
|
||||||
|
|
||||||
// delete wavetable
|
// delete wavetable
|
||||||
void delWave(int index);
|
void delWave(int index);
|
||||||
|
@ -715,8 +718,14 @@ class DivEngine {
|
||||||
// add sample
|
// add sample
|
||||||
int addSample();
|
int addSample();
|
||||||
|
|
||||||
// add sample from file
|
// add sample from pointer
|
||||||
int addSampleFromFile(const char* path);
|
int addSamplePtr(DivSample* which);
|
||||||
|
|
||||||
|
// get sample from file
|
||||||
|
DivSample* sampleFromFile(const char* path);
|
||||||
|
|
||||||
|
// get raw sample
|
||||||
|
DivSample* sampleFromFileRaw(const char* path, DivSampleDepth depth, int channels, bool bigEndian);
|
||||||
|
|
||||||
// delete sample
|
// delete sample
|
||||||
void delSample(int index);
|
void delSample(int index);
|
||||||
|
|
|
@ -420,6 +420,12 @@ void FurnaceGUI::drawWaveList() {
|
||||||
if (ImGui::Button(ICON_FA_FOLDER_OPEN "##WaveLoad")) {
|
if (ImGui::Button(ICON_FA_FOLDER_OPEN "##WaveLoad")) {
|
||||||
doAction(GUI_ACTION_WAVE_LIST_OPEN);
|
doAction(GUI_ACTION_WAVE_LIST_OPEN);
|
||||||
}
|
}
|
||||||
|
if (ImGui::BeginPopupContextItem("WaveOpenOpt")) {
|
||||||
|
if (ImGui::MenuItem("replace...")) {
|
||||||
|
doAction((curWave>=0 && curWave<(int)e->song.wave.size())?GUI_ACTION_WAVE_LIST_OPEN_REPLACE:GUI_ACTION_WAVE_LIST_OPEN);
|
||||||
|
}
|
||||||
|
ImGui::EndPopup();
|
||||||
|
}
|
||||||
ImGui::SameLine();
|
ImGui::SameLine();
|
||||||
if (ImGui::Button(ICON_FA_FLOPPY_O "##WaveSave")) {
|
if (ImGui::Button(ICON_FA_FLOPPY_O "##WaveSave")) {
|
||||||
doAction(GUI_ACTION_WAVE_LIST_SAVE);
|
doAction(GUI_ACTION_WAVE_LIST_SAVE);
|
||||||
|
@ -470,6 +476,19 @@ void FurnaceGUI::drawSampleList() {
|
||||||
if (ImGui::Button(ICON_FA_FOLDER_OPEN "##SampleLoad")) {
|
if (ImGui::Button(ICON_FA_FOLDER_OPEN "##SampleLoad")) {
|
||||||
doAction(GUI_ACTION_SAMPLE_LIST_OPEN);
|
doAction(GUI_ACTION_SAMPLE_LIST_OPEN);
|
||||||
}
|
}
|
||||||
|
if (ImGui::BeginPopupContextItem("SampleOpenOpt")) {
|
||||||
|
if (ImGui::MenuItem("replace...")) {
|
||||||
|
doAction((curSample>=0 && curSample<(int)e->song.sample.size())?GUI_ACTION_SAMPLE_LIST_OPEN_REPLACE:GUI_ACTION_SAMPLE_LIST_OPEN);
|
||||||
|
}
|
||||||
|
ImGui::Separator();
|
||||||
|
if (ImGui::MenuItem("import raw...")) {
|
||||||
|
doAction(GUI_ACTION_SAMPLE_LIST_OPEN_RAW);
|
||||||
|
}
|
||||||
|
if (ImGui::MenuItem("import raw (replace)...")) {
|
||||||
|
doAction((curSample>=0 && curSample<(int)e->song.sample.size())?GUI_ACTION_SAMPLE_LIST_OPEN_REPLACE_RAW:GUI_ACTION_SAMPLE_LIST_OPEN_RAW);
|
||||||
|
}
|
||||||
|
ImGui::EndPopup();
|
||||||
|
}
|
||||||
ImGui::SameLine();
|
ImGui::SameLine();
|
||||||
if (ImGui::Button(ICON_FA_FLOPPY_O "##SampleSave")) {
|
if (ImGui::Button(ICON_FA_FLOPPY_O "##SampleSave")) {
|
||||||
doAction(GUI_ACTION_SAMPLE_LIST_SAVE);
|
doAction(GUI_ACTION_SAMPLE_LIST_SAVE);
|
||||||
|
|
|
@ -648,6 +648,9 @@ void FurnaceGUI::doAction(int what) {
|
||||||
case GUI_ACTION_WAVE_LIST_OPEN:
|
case GUI_ACTION_WAVE_LIST_OPEN:
|
||||||
openFileDialog(GUI_FILE_WAVE_OPEN);
|
openFileDialog(GUI_FILE_WAVE_OPEN);
|
||||||
break;
|
break;
|
||||||
|
case GUI_ACTION_WAVE_LIST_OPEN_REPLACE:
|
||||||
|
openFileDialog(GUI_FILE_WAVE_OPEN_REPLACE);
|
||||||
|
break;
|
||||||
case GUI_ACTION_WAVE_LIST_SAVE:
|
case GUI_ACTION_WAVE_LIST_SAVE:
|
||||||
if (curWave>=0 && curWave<(int)e->song.wave.size()) openFileDialog(GUI_FILE_WAVE_SAVE);
|
if (curWave>=0 && curWave<(int)e->song.wave.size()) openFileDialog(GUI_FILE_WAVE_SAVE);
|
||||||
break;
|
break;
|
||||||
|
@ -728,6 +731,15 @@ void FurnaceGUI::doAction(int what) {
|
||||||
case GUI_ACTION_SAMPLE_LIST_OPEN:
|
case GUI_ACTION_SAMPLE_LIST_OPEN:
|
||||||
openFileDialog(GUI_FILE_SAMPLE_OPEN);
|
openFileDialog(GUI_FILE_SAMPLE_OPEN);
|
||||||
break;
|
break;
|
||||||
|
case GUI_ACTION_SAMPLE_LIST_OPEN_REPLACE:
|
||||||
|
openFileDialog(GUI_FILE_SAMPLE_OPEN_REPLACE);
|
||||||
|
break;
|
||||||
|
case GUI_ACTION_SAMPLE_LIST_OPEN_RAW:
|
||||||
|
openFileDialog(GUI_FILE_SAMPLE_OPEN_RAW);
|
||||||
|
break;
|
||||||
|
case GUI_ACTION_SAMPLE_LIST_OPEN_REPLACE_RAW:
|
||||||
|
openFileDialog(GUI_FILE_SAMPLE_OPEN_REPLACE_RAW);
|
||||||
|
break;
|
||||||
case GUI_ACTION_SAMPLE_LIST_SAVE:
|
case GUI_ACTION_SAMPLE_LIST_SAVE:
|
||||||
if (curSample>=0 && curSample<(int)e->song.sample.size()) openFileDialog(GUI_FILE_SAMPLE_SAVE);
|
if (curSample>=0 && curSample<(int)e->song.sample.size()) openFileDialog(GUI_FILE_SAMPLE_SAVE);
|
||||||
break;
|
break;
|
||||||
|
|
126
src/gui/gui.cpp
126
src/gui/gui.cpp
|
@ -1320,6 +1320,7 @@ void FurnaceGUI::openFileDialog(FurnaceGUIFileDialogs type) {
|
||||||
);
|
);
|
||||||
break;
|
break;
|
||||||
case GUI_FILE_WAVE_OPEN:
|
case GUI_FILE_WAVE_OPEN:
|
||||||
|
case GUI_FILE_WAVE_OPEN_REPLACE:
|
||||||
if (!dirExists(workingDirWave)) workingDirWave=getHomeDir();
|
if (!dirExists(workingDirWave)) workingDirWave=getHomeDir();
|
||||||
hasOpened=fileDialog->openLoad(
|
hasOpened=fileDialog->openLoad(
|
||||||
"Load Wavetable",
|
"Load Wavetable",
|
||||||
|
@ -1341,6 +1342,7 @@ void FurnaceGUI::openFileDialog(FurnaceGUIFileDialogs type) {
|
||||||
);
|
);
|
||||||
break;
|
break;
|
||||||
case GUI_FILE_SAMPLE_OPEN:
|
case GUI_FILE_SAMPLE_OPEN:
|
||||||
|
case GUI_FILE_SAMPLE_OPEN_REPLACE:
|
||||||
if (!dirExists(workingDirSample)) workingDirSample=getHomeDir();
|
if (!dirExists(workingDirSample)) workingDirSample=getHomeDir();
|
||||||
hasOpened=fileDialog->openLoad(
|
hasOpened=fileDialog->openLoad(
|
||||||
"Load Sample",
|
"Load Sample",
|
||||||
|
@ -1351,6 +1353,17 @@ void FurnaceGUI::openFileDialog(FurnaceGUIFileDialogs type) {
|
||||||
dpiScale
|
dpiScale
|
||||||
);
|
);
|
||||||
break;
|
break;
|
||||||
|
case GUI_FILE_SAMPLE_OPEN_RAW:
|
||||||
|
case GUI_FILE_SAMPLE_OPEN_REPLACE_RAW:
|
||||||
|
if (!dirExists(workingDirSample)) workingDirSample=getHomeDir();
|
||||||
|
hasOpened=fileDialog->openLoad(
|
||||||
|
"Load Raw Sample",
|
||||||
|
{"all files", ".*"},
|
||||||
|
".*",
|
||||||
|
workingDirSample,
|
||||||
|
dpiScale
|
||||||
|
);
|
||||||
|
break;
|
||||||
case GUI_FILE_SAMPLE_SAVE:
|
case GUI_FILE_SAMPLE_SAVE:
|
||||||
if (!dirExists(workingDirSample)) workingDirSample=getHomeDir();
|
if (!dirExists(workingDirSample)) workingDirSample=getHomeDir();
|
||||||
hasOpened=fileDialog->openSave(
|
hasOpened=fileDialog->openSave(
|
||||||
|
@ -2630,6 +2643,8 @@ bool FurnaceGUI::loop() {
|
||||||
case SDL_DROPFILE:
|
case SDL_DROPFILE:
|
||||||
if (ev.drop.file!=NULL) {
|
if (ev.drop.file!=NULL) {
|
||||||
std::vector<DivInstrument*> instruments=e->instrumentFromFile(ev.drop.file);
|
std::vector<DivInstrument*> instruments=e->instrumentFromFile(ev.drop.file);
|
||||||
|
DivWavetable* droppedWave=NULL;
|
||||||
|
DivSample* droppedSample=NULL;;
|
||||||
if (!instruments.empty()) {
|
if (!instruments.empty()) {
|
||||||
if (!e->getWarnings().empty()) {
|
if (!e->getWarnings().empty()) {
|
||||||
showWarning(e->getWarnings(),GUI_WARN_GENERIC);
|
showWarning(e->getWarnings(),GUI_WARN_GENERIC);
|
||||||
|
@ -2639,10 +2654,12 @@ bool FurnaceGUI::loop() {
|
||||||
}
|
}
|
||||||
nextWindow=GUI_WINDOW_INS_LIST;
|
nextWindow=GUI_WINDOW_INS_LIST;
|
||||||
MARK_MODIFIED;
|
MARK_MODIFIED;
|
||||||
} else if (e->addWaveFromFile(ev.drop.file,false)) {
|
} else if ((droppedWave=e->waveFromFile(ev.drop.file,false))!=NULL) {
|
||||||
|
e->addWavePtr(droppedWave);
|
||||||
nextWindow=GUI_WINDOW_WAVE_LIST;
|
nextWindow=GUI_WINDOW_WAVE_LIST;
|
||||||
MARK_MODIFIED;
|
MARK_MODIFIED;
|
||||||
} else if (e->addSampleFromFile(ev.drop.file)!=-1) {
|
} else if ((droppedSample=e->sampleFromFile(ev.drop.file))!=NULL) {
|
||||||
|
e->addSamplePtr(droppedSample);
|
||||||
nextWindow=GUI_WINDOW_SAMPLE_LIST;
|
nextWindow=GUI_WINDOW_SAMPLE_LIST;
|
||||||
MARK_MODIFIED;
|
MARK_MODIFIED;
|
||||||
} else if (modified) {
|
} else if (modified) {
|
||||||
|
@ -3269,10 +3286,14 @@ bool FurnaceGUI::loop() {
|
||||||
workingDirIns=fileDialog->getPath()+DIR_SEPARATOR_STR;
|
workingDirIns=fileDialog->getPath()+DIR_SEPARATOR_STR;
|
||||||
break;
|
break;
|
||||||
case GUI_FILE_WAVE_OPEN:
|
case GUI_FILE_WAVE_OPEN:
|
||||||
|
case GUI_FILE_WAVE_OPEN_REPLACE:
|
||||||
case GUI_FILE_WAVE_SAVE:
|
case GUI_FILE_WAVE_SAVE:
|
||||||
workingDirWave=fileDialog->getPath()+DIR_SEPARATOR_STR;
|
workingDirWave=fileDialog->getPath()+DIR_SEPARATOR_STR;
|
||||||
break;
|
break;
|
||||||
case GUI_FILE_SAMPLE_OPEN:
|
case GUI_FILE_SAMPLE_OPEN:
|
||||||
|
case GUI_FILE_SAMPLE_OPEN_RAW:
|
||||||
|
case GUI_FILE_SAMPLE_OPEN_REPLACE:
|
||||||
|
case GUI_FILE_SAMPLE_OPEN_REPLACE_RAW:
|
||||||
case GUI_FILE_SAMPLE_SAVE:
|
case GUI_FILE_SAMPLE_SAVE:
|
||||||
workingDirSample=fileDialog->getPath()+DIR_SEPARATOR_STR;
|
workingDirSample=fileDialog->getPath()+DIR_SEPARATOR_STR;
|
||||||
break;
|
break;
|
||||||
|
@ -3438,13 +3459,45 @@ bool FurnaceGUI::loop() {
|
||||||
e->song.wave[curWave]->save(copyOfName.c_str());
|
e->song.wave[curWave]->save(copyOfName.c_str());
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case GUI_FILE_SAMPLE_OPEN:
|
case GUI_FILE_SAMPLE_OPEN: {
|
||||||
if (e->addSampleFromFile(copyOfName.c_str())==-1) {
|
DivSample* s=e->sampleFromFile(copyOfName.c_str());
|
||||||
|
if (s==NULL) {
|
||||||
showError(e->getLastError());
|
showError(e->getLastError());
|
||||||
} else {
|
} else {
|
||||||
MARK_MODIFIED;
|
if (e->addSamplePtr(s)==-1) {
|
||||||
|
showError(e->getLastError());
|
||||||
|
} else {
|
||||||
|
MARK_MODIFIED;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
|
case GUI_FILE_SAMPLE_OPEN_REPLACE: {
|
||||||
|
DivSample* s=e->sampleFromFile(copyOfName.c_str());
|
||||||
|
if (s==NULL) {
|
||||||
|
showError(e->getLastError());
|
||||||
|
} else {
|
||||||
|
if (curSample>=0 && curSample<(int)e->song.sample.size()) {
|
||||||
|
e->lockEngine([this,s]() {
|
||||||
|
// if it crashes here please tell me...
|
||||||
|
DivSample* oldSample=e->song.sample[curSample];
|
||||||
|
e->song.sample[curSample]=s;
|
||||||
|
delete oldSample;
|
||||||
|
e->renderSamples();
|
||||||
|
MARK_MODIFIED;
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
showError("...but you haven't selected a sample!");
|
||||||
|
delete s;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case GUI_FILE_SAMPLE_OPEN_RAW:
|
||||||
|
case GUI_FILE_SAMPLE_OPEN_REPLACE_RAW:
|
||||||
|
pendingRawSample=copyOfName;
|
||||||
|
displayPendingRawSample=true;
|
||||||
|
break;
|
||||||
case GUI_FILE_SAMPLE_SAVE:
|
case GUI_FILE_SAMPLE_SAVE:
|
||||||
if (curSample>=0 && curSample<(int)e->song.sample.size()) {
|
if (curSample>=0 && curSample<(int)e->song.sample.size()) {
|
||||||
e->song.sample[curSample]->save(copyOfName.c_str());
|
e->song.sample[curSample]->save(copyOfName.c_str());
|
||||||
|
@ -3508,13 +3561,36 @@ bool FurnaceGUI::loop() {
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case GUI_FILE_WAVE_OPEN:
|
case GUI_FILE_WAVE_OPEN: {
|
||||||
if (!e->addWaveFromFile(copyOfName.c_str())) {
|
DivWavetable* wave=e->waveFromFile(copyOfName.c_str());
|
||||||
|
if (wave==NULL) {
|
||||||
showError("cannot load wavetable! ("+e->getLastError()+")");
|
showError("cannot load wavetable! ("+e->getLastError()+")");
|
||||||
} else {
|
} else {
|
||||||
MARK_MODIFIED;
|
if (e->addWavePtr(wave)==-1) {
|
||||||
|
showError("cannot load wavetable! ("+e->getLastError()+")");
|
||||||
|
} else {
|
||||||
|
MARK_MODIFIED;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
|
case GUI_FILE_WAVE_OPEN_REPLACE: {
|
||||||
|
DivWavetable* wave=e->waveFromFile(copyOfName.c_str());
|
||||||
|
if (wave==NULL) {
|
||||||
|
showError("cannot load wavetable! ("+e->getLastError()+")");
|
||||||
|
} else {
|
||||||
|
if (curWave>=0 && curWave<(int)e->song.wave.size()) {
|
||||||
|
e->lockEngine([this,wave]() {
|
||||||
|
*e->song.wave[curWave]=*wave;
|
||||||
|
MARK_MODIFIED;
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
showError("...but you haven't selected a wavetable!");
|
||||||
|
}
|
||||||
|
delete wave;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
case GUI_FILE_EXPORT_VGM: {
|
case GUI_FILE_EXPORT_VGM: {
|
||||||
SafeWriter* w=e->saveVGM(willExport,vgmExportLoop,vgmExportVersion,vgmExportPatternHints);
|
SafeWriter* w=e->saveVGM(willExport,vgmExportLoop,vgmExportVersion,vgmExportPatternHints);
|
||||||
if (w!=NULL) {
|
if (w!=NULL) {
|
||||||
|
@ -3641,6 +3717,11 @@ bool FurnaceGUI::loop() {
|
||||||
ImGui::OpenPopup("Select Instrument");
|
ImGui::OpenPopup("Select Instrument");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (displayPendingRawSample) {
|
||||||
|
displayPendingRawSample=false;
|
||||||
|
ImGui::OpenPopup("Import Raw Sample");
|
||||||
|
}
|
||||||
|
|
||||||
if (displayExporting) {
|
if (displayExporting) {
|
||||||
displayExporting=false;
|
displayExporting=false;
|
||||||
ImGui::OpenPopup("Rendering...");
|
ImGui::OpenPopup("Rendering...");
|
||||||
|
@ -4071,6 +4152,34 @@ bool FurnaceGUI::loop() {
|
||||||
ImGui::EndPopup();
|
ImGui::EndPopup();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool doRespond=false;
|
||||||
|
if (ImGui::BeginPopupModal("Import Raw Sample",NULL,ImGuiWindowFlags_AlwaysAutoResize)) {
|
||||||
|
ImGui::Text("Work In Progress - sorry");
|
||||||
|
if (ImGui::Button("Oh... really?")) {
|
||||||
|
ImGui::CloseCurrentPopup();
|
||||||
|
}
|
||||||
|
ImGui::SameLine();
|
||||||
|
if (ImGui::Button("Why are you so hostile? I'm just trying to import a raw sample.")) {
|
||||||
|
doRespond=true;
|
||||||
|
ImGui::CloseCurrentPopup();
|
||||||
|
}
|
||||||
|
ImGui::EndPopup();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (doRespond) {
|
||||||
|
doRespond=false;
|
||||||
|
ImGui::OpenPopup("Fatal Alert");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ImGui::BeginPopupModal("Fatal Alert",NULL,ImGuiWindowFlags_AlwaysAutoResize)) {
|
||||||
|
ImGui::Text("Well, I'd rather you didn't. So, good night.");
|
||||||
|
if (ImGui::Button("Fine")) {
|
||||||
|
abort();
|
||||||
|
ImGui::CloseCurrentPopup();
|
||||||
|
}
|
||||||
|
ImGui::EndPopup();
|
||||||
|
}
|
||||||
|
|
||||||
layoutTimeEnd=SDL_GetPerformanceCounter();
|
layoutTimeEnd=SDL_GetPerformanceCounter();
|
||||||
|
|
||||||
// backup trigger
|
// backup trigger
|
||||||
|
@ -4521,6 +4630,7 @@ FurnaceGUI::FurnaceGUI():
|
||||||
noteInputPoly(true),
|
noteInputPoly(true),
|
||||||
displayPendingIns(false),
|
displayPendingIns(false),
|
||||||
pendingInsSingle(false),
|
pendingInsSingle(false),
|
||||||
|
displayPendingRawSample(false),
|
||||||
vgmExportVersion(0x171),
|
vgmExportVersion(0x171),
|
||||||
drawHalt(10),
|
drawHalt(10),
|
||||||
macroPointSize(16),
|
macroPointSize(16),
|
||||||
|
|
|
@ -259,8 +259,12 @@ enum FurnaceGUIFileDialogs {
|
||||||
GUI_FILE_INS_OPEN_REPLACE,
|
GUI_FILE_INS_OPEN_REPLACE,
|
||||||
GUI_FILE_INS_SAVE,
|
GUI_FILE_INS_SAVE,
|
||||||
GUI_FILE_WAVE_OPEN,
|
GUI_FILE_WAVE_OPEN,
|
||||||
|
GUI_FILE_WAVE_OPEN_REPLACE,
|
||||||
GUI_FILE_WAVE_SAVE,
|
GUI_FILE_WAVE_SAVE,
|
||||||
GUI_FILE_SAMPLE_OPEN,
|
GUI_FILE_SAMPLE_OPEN,
|
||||||
|
GUI_FILE_SAMPLE_OPEN_RAW,
|
||||||
|
GUI_FILE_SAMPLE_OPEN_REPLACE,
|
||||||
|
GUI_FILE_SAMPLE_OPEN_REPLACE_RAW,
|
||||||
GUI_FILE_SAMPLE_SAVE,
|
GUI_FILE_SAMPLE_SAVE,
|
||||||
GUI_FILE_EXPORT_AUDIO_ONE,
|
GUI_FILE_EXPORT_AUDIO_ONE,
|
||||||
GUI_FILE_EXPORT_AUDIO_PER_SYS,
|
GUI_FILE_EXPORT_AUDIO_PER_SYS,
|
||||||
|
@ -451,6 +455,7 @@ enum FurnaceGUIActions {
|
||||||
GUI_ACTION_WAVE_LIST_ADD,
|
GUI_ACTION_WAVE_LIST_ADD,
|
||||||
GUI_ACTION_WAVE_LIST_DUPLICATE,
|
GUI_ACTION_WAVE_LIST_DUPLICATE,
|
||||||
GUI_ACTION_WAVE_LIST_OPEN,
|
GUI_ACTION_WAVE_LIST_OPEN,
|
||||||
|
GUI_ACTION_WAVE_LIST_OPEN_REPLACE,
|
||||||
GUI_ACTION_WAVE_LIST_SAVE,
|
GUI_ACTION_WAVE_LIST_SAVE,
|
||||||
GUI_ACTION_WAVE_LIST_MOVE_UP,
|
GUI_ACTION_WAVE_LIST_MOVE_UP,
|
||||||
GUI_ACTION_WAVE_LIST_MOVE_DOWN,
|
GUI_ACTION_WAVE_LIST_MOVE_DOWN,
|
||||||
|
@ -464,6 +469,9 @@ enum FurnaceGUIActions {
|
||||||
GUI_ACTION_SAMPLE_LIST_ADD,
|
GUI_ACTION_SAMPLE_LIST_ADD,
|
||||||
GUI_ACTION_SAMPLE_LIST_DUPLICATE,
|
GUI_ACTION_SAMPLE_LIST_DUPLICATE,
|
||||||
GUI_ACTION_SAMPLE_LIST_OPEN,
|
GUI_ACTION_SAMPLE_LIST_OPEN,
|
||||||
|
GUI_ACTION_SAMPLE_LIST_OPEN_REPLACE,
|
||||||
|
GUI_ACTION_SAMPLE_LIST_OPEN_RAW,
|
||||||
|
GUI_ACTION_SAMPLE_LIST_OPEN_REPLACE_RAW,
|
||||||
GUI_ACTION_SAMPLE_LIST_SAVE,
|
GUI_ACTION_SAMPLE_LIST_SAVE,
|
||||||
GUI_ACTION_SAMPLE_LIST_MOVE_UP,
|
GUI_ACTION_SAMPLE_LIST_MOVE_UP,
|
||||||
GUI_ACTION_SAMPLE_LIST_MOVE_DOWN,
|
GUI_ACTION_SAMPLE_LIST_MOVE_DOWN,
|
||||||
|
@ -958,13 +966,15 @@ class FurnaceGUI {
|
||||||
bool quit, warnQuit, willCommit, edit, modified, displayError, displayExporting, vgmExportLoop, vgmExportPatternHints;
|
bool quit, warnQuit, willCommit, edit, modified, displayError, displayExporting, vgmExportLoop, vgmExportPatternHints;
|
||||||
bool wantCaptureKeyboard, oldWantCaptureKeyboard, displayMacroMenu;
|
bool wantCaptureKeyboard, oldWantCaptureKeyboard, displayMacroMenu;
|
||||||
bool displayNew, fullScreen, preserveChanPos, wantScrollList, noteInputPoly;
|
bool displayNew, fullScreen, preserveChanPos, wantScrollList, noteInputPoly;
|
||||||
bool displayPendingIns, pendingInsSingle;
|
bool displayPendingIns, pendingInsSingle, displayPendingRawSample;
|
||||||
bool willExport[32];
|
bool willExport[32];
|
||||||
int vgmExportVersion;
|
int vgmExportVersion;
|
||||||
int drawHalt;
|
int drawHalt;
|
||||||
int macroPointSize;
|
int macroPointSize;
|
||||||
int waveEditStyle;
|
int waveEditStyle;
|
||||||
|
|
||||||
|
String pendingRawSample;
|
||||||
|
|
||||||
ImGuiWindowFlags globalWinFlags;
|
ImGuiWindowFlags globalWinFlags;
|
||||||
|
|
||||||
FurnaceGUIFileDialogs curFileDialog;
|
FurnaceGUIFileDialogs curFileDialog;
|
||||||
|
|
|
@ -581,6 +581,7 @@ const FurnaceGUIActionDef guiActions[GUI_ACTION_MAX]={
|
||||||
D("WAVE_LIST_ADD", "Add", SDLK_INSERT),
|
D("WAVE_LIST_ADD", "Add", SDLK_INSERT),
|
||||||
D("WAVE_LIST_DUPLICATE", "Duplicate", FURKMOD_CMD|SDLK_d),
|
D("WAVE_LIST_DUPLICATE", "Duplicate", FURKMOD_CMD|SDLK_d),
|
||||||
D("WAVE_LIST_OPEN", "Open", 0),
|
D("WAVE_LIST_OPEN", "Open", 0),
|
||||||
|
D("WAVE_LIST_OPEN_REPLACE", "Open (replace current)", 0),
|
||||||
D("WAVE_LIST_SAVE", "Save", 0),
|
D("WAVE_LIST_SAVE", "Save", 0),
|
||||||
D("WAVE_LIST_MOVE_UP", "Move up", FURKMOD_SHIFT|SDLK_UP),
|
D("WAVE_LIST_MOVE_UP", "Move up", FURKMOD_SHIFT|SDLK_UP),
|
||||||
D("WAVE_LIST_MOVE_DOWN", "Move down", FURKMOD_SHIFT|SDLK_DOWN),
|
D("WAVE_LIST_MOVE_DOWN", "Move down", FURKMOD_SHIFT|SDLK_DOWN),
|
||||||
|
@ -594,6 +595,9 @@ const FurnaceGUIActionDef guiActions[GUI_ACTION_MAX]={
|
||||||
D("SAMPLE_LIST_ADD", "Add", SDLK_INSERT),
|
D("SAMPLE_LIST_ADD", "Add", SDLK_INSERT),
|
||||||
D("SAMPLE_LIST_DUPLICATE", "Duplicate", FURKMOD_CMD|SDLK_d),
|
D("SAMPLE_LIST_DUPLICATE", "Duplicate", FURKMOD_CMD|SDLK_d),
|
||||||
D("SAMPLE_LIST_OPEN", "Open", 0),
|
D("SAMPLE_LIST_OPEN", "Open", 0),
|
||||||
|
D("SAMPLE_LIST_OPEN_REPLACE", "Open (replace current)", 0),
|
||||||
|
D("SAMPLE_LIST_OPEN_RAW", "Import raw data", 0),
|
||||||
|
D("SAMPLE_LIST_OPEN_REPLACE_RAW", "Import raw data (replace current)", 0),
|
||||||
D("SAMPLE_LIST_SAVE", "Save", 0),
|
D("SAMPLE_LIST_SAVE", "Save", 0),
|
||||||
D("SAMPLE_LIST_MOVE_UP", "Move up", FURKMOD_SHIFT|SDLK_UP),
|
D("SAMPLE_LIST_MOVE_UP", "Move up", FURKMOD_SHIFT|SDLK_UP),
|
||||||
D("SAMPLE_LIST_MOVE_DOWN", "Move down", FURKMOD_SHIFT|SDLK_DOWN),
|
D("SAMPLE_LIST_MOVE_DOWN", "Move down", FURKMOD_SHIFT|SDLK_DOWN),
|
||||||
|
|
|
@ -131,9 +131,8 @@ void FurnaceGUI::drawWaveEdit() {
|
||||||
if (curWave>=(int)e->song.wave.size()) curWave=e->song.wave.size()-1;
|
if (curWave>=(int)e->song.wave.size()) curWave=e->song.wave.size()-1;
|
||||||
}
|
}
|
||||||
ImGui::SameLine();
|
ImGui::SameLine();
|
||||||
// TODO: load replace
|
|
||||||
if (ImGui::Button(ICON_FA_FOLDER_OPEN "##WELoad")) {
|
if (ImGui::Button(ICON_FA_FOLDER_OPEN "##WELoad")) {
|
||||||
doAction(GUI_ACTION_WAVE_LIST_OPEN);
|
doAction(GUI_ACTION_WAVE_LIST_OPEN_REPLACE);
|
||||||
}
|
}
|
||||||
ImGui::SameLine();
|
ImGui::SameLine();
|
||||||
if (ImGui::Button(ICON_FA_FLOPPY_O "##WESave")) {
|
if (ImGui::Button(ICON_FA_FLOPPY_O "##WESave")) {
|
||||||
|
|
Loading…
Reference in a new issue