Merge branch 'master' of https://github.com/tildearrow/furnace into ymf278b
This commit is contained in:
commit
4b0080c509
76 changed files with 24622 additions and 23877 deletions
|
|
@ -23,6 +23,7 @@
|
|||
#ifdef _WIN32
|
||||
#include <pa_win_wasapi.h>
|
||||
#endif
|
||||
#include <fmt/printf.h>
|
||||
|
||||
int taPAProcess(const void* in, void* out, unsigned long nframes, const PaStreamCallbackTimeInfo* timeInfo, PaStreamCallbackFlags flags, void* inst) {
|
||||
TAAudioPA* instance=(TAAudioPA*)inst;
|
||||
|
|
|
|||
|
|
@ -98,10 +98,6 @@ const char* DivEngine::getEffectDesc(unsigned char effect, int chan, bool notNul
|
|||
break;
|
||||
case 0xc0: case 0xc1: case 0xc2: case 0xc3:
|
||||
return _("Cxxx: Set tick rate (hz)");
|
||||
case 0xd8:
|
||||
return _("D8xx: Set volume slide bottom boundary");
|
||||
case 0xd9:
|
||||
return _("D9xx: Set volume slide top boundary");
|
||||
case 0xdc:
|
||||
return _("DCxx: Delayed mute");
|
||||
case 0xe0:
|
||||
|
|
@ -2114,7 +2110,6 @@ void DivEngine::reset() {
|
|||
chan[i]=DivChannelState();
|
||||
if (i<chans) chan[i].volMax=(disCont[dispatchOfChan[i]].dispatch->dispatch(DivCommand(DIV_CMD_GET_VOLMAX,dispatchChanOfChan[i]))<<8)|0xff;
|
||||
chan[i].volume=chan[i].volMax;
|
||||
chan[i].volTop=chan[i].volMax;
|
||||
if (song.linearPitch==0) chan[i].vibratoFine=4;
|
||||
}
|
||||
extValue=0;
|
||||
|
|
|
|||
|
|
@ -133,7 +133,7 @@ struct DivAudioExportOptions {
|
|||
struct DivChannelState {
|
||||
std::vector<DivDelayedCommand> delayed;
|
||||
int note, oldNote, lastIns, pitch, portaSpeed, portaNote;
|
||||
int volume, volSpeed, cut, volCut, legatoDelay, legatoTarget, rowDelay, volMax, volBottom, volTop;
|
||||
int volume, volSpeed, cut, volCut, legatoDelay, legatoTarget, rowDelay, volMax;
|
||||
int delayOrder, delayRow, retrigSpeed, retrigTick;
|
||||
int vibratoDepth, vibratoRate, vibratoPos, vibratoPosGiant, vibratoShape, vibratoFine;
|
||||
int tremoloDepth, tremoloRate, tremoloPos;
|
||||
|
|
@ -163,8 +163,6 @@ struct DivChannelState {
|
|||
legatoTarget(0),
|
||||
rowDelay(0),
|
||||
volMax(0),
|
||||
volBottom(0),
|
||||
volTop(0),
|
||||
delayOrder(0),
|
||||
delayRow(0),
|
||||
retrigSpeed(0),
|
||||
|
|
|
|||
|
|
@ -948,14 +948,6 @@ void DivEngine::processRow(int i, bool afterDelay) {
|
|||
clockDrift=0;
|
||||
subticks=0;
|
||||
break;
|
||||
case 0xd8: // vol slide bottom
|
||||
chan[i].volBottom=(effectVal<<8)|0xff;
|
||||
if (chan[i].volBottom>chan[i].volMax) chan[i].volBottom=chan[i].volMax;
|
||||
break;
|
||||
case 0xd9: // vol slide top
|
||||
chan[i].volTop=(effectVal<<8)|0xff;
|
||||
if (chan[i].volTop>chan[i].volMax) chan[i].volTop=chan[i].volMax;
|
||||
break;
|
||||
case 0xdc: // delayed mute
|
||||
if (effectVal>0 && (song.delayBehavior==2 || effectVal<nextSpeed)) {
|
||||
chan[i].volCut=effectVal+1;
|
||||
|
|
@ -1119,13 +1111,13 @@ void DivEngine::processRow(int i, bool afterDelay) {
|
|||
break;
|
||||
case 0xf8: // single volume ramp up
|
||||
chan[i].volSpeed=0; // add compat flag?
|
||||
chan[i].volume=MIN(chan[i].volume+effectVal*256,chan[i].volTop);
|
||||
chan[i].volume=MIN(chan[i].volume+effectVal*256,chan[i].volMax);
|
||||
dispatchCmd(DivCommand(DIV_CMD_VOLUME,i,chan[i].volume>>8));
|
||||
dispatchCmd(DivCommand(DIV_CMD_HINT_VOLUME,i,chan[i].volume>>8));
|
||||
break;
|
||||
case 0xf9: // single volume ramp down
|
||||
chan[i].volSpeed=0; // add compat flag?
|
||||
chan[i].volume=MAX(chan[i].volume-effectVal*256,chan[i].volBottom);
|
||||
chan[i].volume=MAX(chan[i].volume-effectVal*256,0);
|
||||
dispatchCmd(DivCommand(DIV_CMD_VOLUME,i,chan[i].volume>>8));
|
||||
dispatchCmd(DivCommand(DIV_CMD_HINT_VOLUME,i,chan[i].volume>>8));
|
||||
break;
|
||||
|
|
@ -1612,19 +1604,19 @@ bool DivEngine::nextTick(bool noAccum, bool inhibitLowLat) {
|
|||
if (chan[i].volSpeed!=0) {
|
||||
chan[i].volume=(chan[i].volume&0xff)|(dispatchCmd(DivCommand(DIV_CMD_GET_VOLUME,i))<<8);
|
||||
chan[i].volume+=chan[i].volSpeed;
|
||||
if (chan[i].volume>chan[i].volTop) {
|
||||
chan[i].volume=chan[i].volTop;
|
||||
if (chan[i].volume>chan[i].volMax) {
|
||||
chan[i].volume=chan[i].volMax;
|
||||
chan[i].volSpeed=0;
|
||||
dispatchCmd(DivCommand(DIV_CMD_HINT_VOLUME,i,chan[i].volume>>8));
|
||||
dispatchCmd(DivCommand(DIV_CMD_VOLUME,i,chan[i].volume>>8));
|
||||
dispatchCmd(DivCommand(DIV_CMD_HINT_VOL_SLIDE,i,0));
|
||||
} else if (chan[i].volume<chan[i].volBottom) {
|
||||
} else if (chan[i].volume<0) {
|
||||
chan[i].volSpeed=0;
|
||||
dispatchCmd(DivCommand(DIV_CMD_HINT_VOL_SLIDE,i,0));
|
||||
if (song.legacyVolumeSlides) {
|
||||
chan[i].volume=chan[i].volTop+1;
|
||||
chan[i].volume=chan[i].volMax+1;
|
||||
} else {
|
||||
chan[i].volume=chan[i].volBottom;
|
||||
chan[i].volume=0;
|
||||
}
|
||||
dispatchCmd(DivCommand(DIV_CMD_VOLUME,i,chan[i].volume>>8));
|
||||
dispatchCmd(DivCommand(DIV_CMD_HINT_VOLUME,i,chan[i].volume>>8));
|
||||
|
|
|
|||
|
|
@ -441,10 +441,26 @@ void FurnaceGUI::drawInsList(bool asChild) {
|
|||
if (ImGui::MenuItem(_("save raw sample..."))) {
|
||||
doAction(GUI_ACTION_SAMPLE_LIST_SAVE_RAW);
|
||||
}
|
||||
|
||||
ImGui::Separator();
|
||||
|
||||
if (ImGui::MenuItem(_("save all instruments..."))) {
|
||||
doAction(GUI_ACTION_INS_LIST_SAVE_ALL);
|
||||
}
|
||||
if (ImGui::MenuItem(_("save all wavetables..."))) {
|
||||
doAction(GUI_ACTION_WAVE_LIST_SAVE_ALL);
|
||||
}
|
||||
if (ImGui::MenuItem(_("save all samples..."))) {
|
||||
doAction(GUI_ACTION_SAMPLE_LIST_SAVE_ALL);
|
||||
}
|
||||
} else {
|
||||
if (ImGui::MenuItem(_("save as .dmp..."))) {
|
||||
doAction(GUI_ACTION_INS_LIST_SAVE_DMP);
|
||||
}
|
||||
|
||||
if (ImGui::MenuItem(_("save all..."))) {
|
||||
doAction(GUI_ACTION_INS_LIST_SAVE_ALL);
|
||||
}
|
||||
}
|
||||
ImGui::EndPopup();
|
||||
}
|
||||
|
|
@ -750,6 +766,9 @@ void FurnaceGUI::drawWaveList(bool asChild) {
|
|||
if (ImGui::MenuItem(_("save raw..."))) {
|
||||
doAction(GUI_ACTION_WAVE_LIST_SAVE_RAW);
|
||||
}
|
||||
if (ImGui::MenuItem(_("save all..."))) {
|
||||
doAction(GUI_ACTION_WAVE_LIST_SAVE_ALL);
|
||||
}
|
||||
ImGui::EndPopup();
|
||||
}
|
||||
}
|
||||
|
|
@ -893,6 +912,9 @@ void FurnaceGUI::drawSampleList(bool asChild) {
|
|||
if (ImGui::MenuItem(_("save raw..."))) {
|
||||
doAction(GUI_ACTION_SAMPLE_LIST_SAVE_RAW);
|
||||
}
|
||||
if (ImGui::MenuItem(_("save all..."))) {
|
||||
doAction(GUI_ACTION_SAMPLE_LIST_SAVE_ALL);
|
||||
}
|
||||
ImGui::EndPopup();
|
||||
}
|
||||
ImGui::SameLine();
|
||||
|
|
|
|||
|
|
@ -781,8 +781,14 @@ void FurnaceGUI::doAction(int what) {
|
|||
case GUI_ACTION_INS_LIST_DIR_VIEW:
|
||||
insListDir=!insListDir;
|
||||
break;
|
||||
case GUI_ACTION_INS_LIST_SAVE_ALL:
|
||||
if (e->song.ins.empty()) {
|
||||
showError(_("this song doesn't have any instruments."));
|
||||
} else {
|
||||
openFileDialog(GUI_FILE_INS_SAVE_ALL);
|
||||
}
|
||||
break;
|
||||
|
||||
|
||||
case GUI_ACTION_WAVE_LIST_ADD: {
|
||||
std::vector<DivSystem> alreadyDone;
|
||||
waveSizeList.clear();
|
||||
|
|
@ -902,6 +908,13 @@ void FurnaceGUI::doAction(int what) {
|
|||
case GUI_ACTION_WAVE_LIST_DIR_VIEW:
|
||||
waveListDir=!waveListDir;
|
||||
break;
|
||||
case GUI_ACTION_WAVE_LIST_SAVE_ALL:
|
||||
if (e->song.wave.empty()) {
|
||||
showError(_("this song doesn't have any wavetables."));
|
||||
} else {
|
||||
openFileDialog(GUI_FILE_WAVE_SAVE_ALL);
|
||||
}
|
||||
break;
|
||||
|
||||
case GUI_ACTION_SAMPLE_LIST_ADD:
|
||||
curSample=e->addSample();
|
||||
|
|
@ -1056,6 +1069,13 @@ void FurnaceGUI::doAction(int what) {
|
|||
displayInsTypeListMakeInsSample=-2;
|
||||
break;
|
||||
}
|
||||
case GUI_ACTION_SAMPLE_LIST_SAVE_ALL:
|
||||
if (e->song.sample.empty()) {
|
||||
showError(_("this song doesn't have any samples."));
|
||||
} else {
|
||||
openFileDialog(GUI_FILE_SAMPLE_SAVE_ALL);
|
||||
}
|
||||
break;
|
||||
|
||||
case GUI_ACTION_SAMPLE_SELECT:
|
||||
if (curSample<0 || curSample>=(int)e->song.sample.size()) break;
|
||||
|
|
|
|||
|
|
@ -13,12 +13,13 @@
|
|||
|
||||
#ifdef USE_NFD
|
||||
struct NFDState {
|
||||
bool isSave, allowMultiple;
|
||||
unsigned char isSave;
|
||||
bool allowMultiple;
|
||||
String header;
|
||||
std::vector<String> filter;
|
||||
String path;
|
||||
FileDialogSelectCallback clickCallback;
|
||||
NFDState(bool save, String h, std::vector<String> filt, String pa, FileDialogSelectCallback cc, bool multi):
|
||||
NFDState(unsigned char save, String h, std::vector<String> filt, String pa, FileDialogSelectCallback cc, bool multi):
|
||||
isSave(save),
|
||||
allowMultiple(multi),
|
||||
header(h),
|
||||
|
|
@ -36,7 +37,9 @@ void _nfdThread(const NFDState state, std::atomic<bool>* ok, std::vector<String>
|
|||
|
||||
result->clear();
|
||||
|
||||
if (state.isSave) {
|
||||
if (state.isSave==2) {
|
||||
ret=NFD_PickFolder(state.path.c_str(),&out);
|
||||
} else if (state.isSave==1) {
|
||||
ret=NFD_SaveDialog(state.filter,state.path.c_str(),&out,state.clickCallback);
|
||||
} else {
|
||||
if (state.allowMultiple) {
|
||||
|
|
@ -112,7 +115,7 @@ void FurnaceGUIFileDialog::convertFilterList(std::vector<String>& filter) {
|
|||
|
||||
bool FurnaceGUIFileDialog::openLoad(String header, std::vector<String> filter, String path, double dpiScale, FileDialogSelectCallback clickCallback, bool allowMultiple, String hint) {
|
||||
if (opened) return false;
|
||||
saving=false;
|
||||
dialogType=0;
|
||||
curPath=path;
|
||||
|
||||
// strip excess directory separators
|
||||
|
|
@ -128,9 +131,9 @@ bool FurnaceGUIFileDialog::openLoad(String header, std::vector<String> filter, S
|
|||
#ifdef USE_NFD
|
||||
dialogOK=false;
|
||||
#ifdef NFD_NON_THREADED
|
||||
_nfdThread(NFDState(false,header,filter,path,clickCallback,allowMultiple),&dialogOK,&nfdResult,&hasError);
|
||||
_nfdThread(NFDState(0,header,filter,path,clickCallback,allowMultiple),&dialogOK,&nfdResult,&hasError);
|
||||
#else
|
||||
dialogO=new std::thread(_nfdThread,NFDState(false,header,filter,path,clickCallback,allowMultiple),&dialogOK,&nfdResult,&hasError);
|
||||
dialogO=new std::thread(_nfdThread,NFDState(0,header,filter,path,clickCallback,allowMultiple),&dialogOK,&nfdResult,&hasError);
|
||||
#endif
|
||||
#elif defined(ANDROID)
|
||||
hasError=false;
|
||||
|
|
@ -190,7 +193,7 @@ bool FurnaceGUIFileDialog::openLoad(String header, std::vector<String> filter, S
|
|||
ImGuiFileDialog::Instance()->DpiScale=dpiScale;
|
||||
ImGuiFileDialog::Instance()->mobileMode=mobileUI;
|
||||
ImGuiFileDialog::Instance()->homePath=getHomeDir();
|
||||
ImGuiFileDialog::Instance()->OpenModal("FileDialog",header,noSysFilter,path,hint,allowMultiple?999:1,nullptr,0,clickCallback);
|
||||
ImGuiFileDialog::Instance()->OpenModal("FileDialog",header,filter.empty()?NULL:noSysFilter,path,hint,allowMultiple?999:1,nullptr,0,clickCallback);
|
||||
}
|
||||
opened=true;
|
||||
return true;
|
||||
|
|
@ -205,7 +208,7 @@ bool FurnaceGUIFileDialog::openSave(String header, std::vector<String> filter, S
|
|||
}
|
||||
#endif
|
||||
|
||||
saving=true;
|
||||
dialogType=1;
|
||||
curPath=path;
|
||||
|
||||
// strip excess directory separators
|
||||
|
|
@ -220,9 +223,9 @@ bool FurnaceGUIFileDialog::openSave(String header, std::vector<String> filter, S
|
|||
#ifdef USE_NFD
|
||||
dialogOK=false;
|
||||
#ifdef NFD_NON_THREADED
|
||||
_nfdThread(NFDState(true,header,filter,path,NULL,false),&dialogOK,&nfdResult,&hasError);
|
||||
_nfdThread(NFDState(1,header,filter,path,NULL,false),&dialogOK,&nfdResult,&hasError);
|
||||
#else
|
||||
dialogS=new std::thread(_nfdThread,NFDState(true,header,filter,path,NULL,false),&dialogOK,&nfdResult,&hasError);
|
||||
dialogS=new std::thread(_nfdThread,NFDState(1,header,filter,path,NULL,false),&dialogOK,&nfdResult,&hasError);
|
||||
#endif
|
||||
#elif defined(ANDROID)
|
||||
hasError=false;
|
||||
|
|
@ -282,6 +285,54 @@ bool FurnaceGUIFileDialog::openSave(String header, std::vector<String> filter, S
|
|||
return true;
|
||||
}
|
||||
|
||||
bool FurnaceGUIFileDialog::openSelectDir(String header, String path, double dpiScale, String hint) {
|
||||
if (opened) return false;
|
||||
dialogType=2;
|
||||
curPath=path;
|
||||
|
||||
// strip excess directory separators
|
||||
while (!curPath.empty()) {
|
||||
if (curPath[curPath.size()-1]!=DIR_SEPARATOR) break;
|
||||
curPath.erase(curPath.size()-1);
|
||||
}
|
||||
curPath+=DIR_SEPARATOR;
|
||||
|
||||
logD("opening select dir dialog with curPath %s",curPath.c_str());
|
||||
if (sysDialog) {
|
||||
curPath+=hint;
|
||||
#ifdef USE_NFD
|
||||
dialogOK=false;
|
||||
#ifdef NFD_NON_THREADED
|
||||
_nfdThread(NFDState(2,header,std::vector<String>(),path,NULL,false),&dialogOK,&nfdResult,&hasError);
|
||||
#else
|
||||
dialogF=new std::thread(_nfdThread,NFDState(2,header,std::vector<String>(),path,NULL,false),&dialogOK,&nfdResult,&hasError);
|
||||
#endif
|
||||
#elif defined(ANDROID)
|
||||
hasError=true;
|
||||
return false;
|
||||
#else
|
||||
dialogF=new pfd::select_folder(header,path);
|
||||
hasError=!pfd::settings::available();
|
||||
#endif
|
||||
} else {
|
||||
hasError=false;
|
||||
|
||||
#ifdef ANDROID
|
||||
if (!SDL_AndroidRequestPermission("android.permission.READ_EXTERNAL_STORAGE")) {
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
|
||||
ImGuiFileDialog::Instance()->singleClickSel=mobileUI;
|
||||
ImGuiFileDialog::Instance()->DpiScale=dpiScale;
|
||||
ImGuiFileDialog::Instance()->mobileMode=mobileUI;
|
||||
ImGuiFileDialog::Instance()->homePath=getHomeDir();
|
||||
ImGuiFileDialog::Instance()->OpenModal("FileDialog",header,NULL,path,hint,1,nullptr,0);
|
||||
}
|
||||
opened=true;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool FurnaceGUIFileDialog::accepted() {
|
||||
if (sysDialog) {
|
||||
return (!fileName.empty());
|
||||
|
|
@ -292,7 +343,17 @@ bool FurnaceGUIFileDialog::accepted() {
|
|||
|
||||
void FurnaceGUIFileDialog::close() {
|
||||
if (sysDialog) {
|
||||
if (saving) {
|
||||
if (dialogType==2) {
|
||||
if (dialogF!=NULL) {
|
||||
#ifdef USE_NFD
|
||||
dialogF->join();
|
||||
#endif
|
||||
#ifndef ANDROID
|
||||
delete dialogF;
|
||||
#endif
|
||||
dialogF=NULL;
|
||||
}
|
||||
} else if (dialogType==1) {
|
||||
if (dialogS!=NULL) {
|
||||
#ifdef USE_NFD
|
||||
dialogS->join();
|
||||
|
|
@ -302,7 +363,7 @@ void FurnaceGUIFileDialog::close() {
|
|||
#endif
|
||||
dialogS=NULL;
|
||||
}
|
||||
} else {
|
||||
} else if (dialogType==0) {
|
||||
if (dialogO!=NULL) {
|
||||
#ifdef USE_NFD
|
||||
dialogO->join();
|
||||
|
|
@ -312,6 +373,8 @@ void FurnaceGUIFileDialog::close() {
|
|||
#endif
|
||||
dialogO=NULL;
|
||||
}
|
||||
} else {
|
||||
logE("what...");
|
||||
}
|
||||
#ifdef USE_NFD
|
||||
dialogOK=false;
|
||||
|
|
@ -343,7 +406,18 @@ bool FurnaceGUIFileDialog::render(const ImVec2& min, const ImVec2& max) {
|
|||
// TODO: detect when file picker is closed
|
||||
return false;
|
||||
#else
|
||||
if (saving) {
|
||||
if (dialogType==2) {
|
||||
if (dialogF!=NULL) {
|
||||
if (dialogF->ready(0)) {
|
||||
fileName.clear();
|
||||
fileName.push_back(dialogF->result());
|
||||
size_t dsPos=fileName[0].rfind(DIR_SEPARATOR);
|
||||
if (dsPos!=String::npos) curPath=fileName[0].substr(0,dsPos);
|
||||
logD("returning %s",fileName[0]);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
} else if (dialogType==1) {
|
||||
if (dialogS!=NULL) {
|
||||
if (dialogS->ready(0)) {
|
||||
fileName.clear();
|
||||
|
|
@ -354,7 +428,7 @@ bool FurnaceGUIFileDialog::render(const ImVec2& min, const ImVec2& max) {
|
|||
return true;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
} else if (dialogType==0) {
|
||||
if (dialogO!=NULL) {
|
||||
if (dialogO->ready(0)) {
|
||||
if (dialogO->result().empty()) {
|
||||
|
|
@ -375,6 +449,8 @@ bool FurnaceGUIFileDialog::render(const ImVec2& min, const ImVec2& max) {
|
|||
return true;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
logE("what!");
|
||||
}
|
||||
return false;
|
||||
#endif
|
||||
|
|
@ -410,7 +486,7 @@ std::vector<String>& FurnaceGUIFileDialog::getFileName() {
|
|||
return fileName;
|
||||
} else {
|
||||
fileName.clear();
|
||||
if (saving) {
|
||||
if (dialogType!=0) {
|
||||
fileName.push_back(ImGuiFileDialog::Instance()->GetFilePathName());
|
||||
} else {
|
||||
for (auto& i: ImGuiFileDialog::Instance()->GetSelection()) {
|
||||
|
|
|
|||
|
|
@ -21,6 +21,7 @@
|
|||
namespace pfd {
|
||||
class open_file;
|
||||
class save_file;
|
||||
class select_folder;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
|
@ -29,7 +30,7 @@ typedef std::function<void(const char*)> FileDialogSelectCallback;
|
|||
class FurnaceGUIFileDialog {
|
||||
bool sysDialog;
|
||||
bool opened;
|
||||
bool saving;
|
||||
unsigned char dialogType;
|
||||
bool hasError;
|
||||
char noSysFilter[4096];
|
||||
String curPath;
|
||||
|
|
@ -37,15 +38,18 @@ class FurnaceGUIFileDialog {
|
|||
#ifdef USE_NFD
|
||||
std::thread* dialogO;
|
||||
std::thread* dialogS;
|
||||
std::thread* dialogF;
|
||||
std::atomic<bool> dialogOK;
|
||||
std::vector<String> nfdResult;
|
||||
#elif defined(ANDROID)
|
||||
JNIEnv* jniEnv;
|
||||
void* dialogO;
|
||||
void* dialogS;
|
||||
void* dialogF;
|
||||
#else
|
||||
pfd::open_file* dialogO;
|
||||
pfd::save_file* dialogS;
|
||||
pfd::select_folder* dialogF;
|
||||
#endif
|
||||
|
||||
void convertFilterList(std::vector<String>& filter);
|
||||
|
|
@ -53,6 +57,7 @@ class FurnaceGUIFileDialog {
|
|||
bool mobileUI;
|
||||
bool openLoad(String header, std::vector<String> filter, String path, double dpiScale, FileDialogSelectCallback clickCallback=NULL, bool allowMultiple=false, String hint="");
|
||||
bool openSave(String header, std::vector<String> filter, String path, double dpiScale, String hint="");
|
||||
bool openSelectDir(String header, String path, double dpiScale, String hint="");
|
||||
bool accepted();
|
||||
void close();
|
||||
bool render(const ImVec2& min, const ImVec2& max);
|
||||
|
|
@ -63,7 +68,7 @@ class FurnaceGUIFileDialog {
|
|||
explicit FurnaceGUIFileDialog(bool system):
|
||||
sysDialog(system),
|
||||
opened(false),
|
||||
saving(false),
|
||||
dialogType(0),
|
||||
hasError(false),
|
||||
#ifdef ANDROID
|
||||
jniEnv(NULL),
|
||||
|
|
|
|||
104
src/gui/gui.cpp
104
src/gui/gui.cpp
|
|
@ -1794,6 +1794,14 @@ void FurnaceGUI::openFileDialog(FurnaceGUIFileDialogs type) {
|
|||
(settings.autoFillSave)?e->getIns(curIns)->name:""
|
||||
);
|
||||
break;
|
||||
case GUI_FILE_INS_SAVE_ALL:
|
||||
if (!dirExists(workingDirIns)) workingDirIns=getHomeDir();
|
||||
hasOpened=fileDialog->openSelectDir(
|
||||
_("Save All Instruments"),
|
||||
workingDirIns,
|
||||
dpiScale
|
||||
);
|
||||
break;
|
||||
case GUI_FILE_WAVE_OPEN:
|
||||
case GUI_FILE_WAVE_OPEN_REPLACE:
|
||||
if (!dirExists(workingDirWave)) workingDirWave=getHomeDir();
|
||||
|
|
@ -1834,6 +1842,14 @@ void FurnaceGUI::openFileDialog(FurnaceGUIFileDialogs type) {
|
|||
dpiScale
|
||||
);
|
||||
break;
|
||||
case GUI_FILE_WAVE_SAVE_ALL:
|
||||
if (!dirExists(workingDirWave)) workingDirWave=getHomeDir();
|
||||
hasOpened=fileDialog->openSelectDir(
|
||||
_("Save All Wavetables"),
|
||||
workingDirWave,
|
||||
dpiScale
|
||||
);
|
||||
break;
|
||||
case GUI_FILE_SAMPLE_OPEN:
|
||||
case GUI_FILE_SAMPLE_OPEN_REPLACE:
|
||||
if (!dirExists(workingDirSample)) workingDirSample=getHomeDir();
|
||||
|
|
@ -1876,6 +1892,14 @@ void FurnaceGUI::openFileDialog(FurnaceGUIFileDialogs type) {
|
|||
(settings.autoFillSave)?e->getSample(curSample)->name:""
|
||||
);
|
||||
break;
|
||||
case GUI_FILE_SAMPLE_SAVE_ALL:
|
||||
if (!dirExists(workingDirSample)) workingDirSample=getHomeDir();
|
||||
hasOpened=fileDialog->openSelectDir(
|
||||
_("Save All Samples"),
|
||||
workingDirSample,
|
||||
dpiScale
|
||||
);
|
||||
break;
|
||||
case GUI_FILE_EXPORT_AUDIO_ONE:
|
||||
if (!dirExists(workingDirAudioExport)) workingDirAudioExport=getHomeDir();
|
||||
hasOpened=fileDialog->openSave(
|
||||
|
|
@ -4909,6 +4933,7 @@ bool FurnaceGUI::loop() {
|
|||
case GUI_FILE_INS_OPEN_REPLACE:
|
||||
case GUI_FILE_INS_SAVE:
|
||||
case GUI_FILE_INS_SAVE_DMP:
|
||||
case GUI_FILE_INS_SAVE_ALL:
|
||||
workingDirIns=fileDialog->getPath()+DIR_SEPARATOR_STR;
|
||||
break;
|
||||
case GUI_FILE_WAVE_OPEN:
|
||||
|
|
@ -4916,6 +4941,7 @@ bool FurnaceGUI::loop() {
|
|||
case GUI_FILE_WAVE_SAVE:
|
||||
case GUI_FILE_WAVE_SAVE_DMW:
|
||||
case GUI_FILE_WAVE_SAVE_RAW:
|
||||
case GUI_FILE_WAVE_SAVE_ALL:
|
||||
workingDirWave=fileDialog->getPath()+DIR_SEPARATOR_STR;
|
||||
break;
|
||||
case GUI_FILE_SAMPLE_OPEN:
|
||||
|
|
@ -4924,6 +4950,7 @@ bool FurnaceGUI::loop() {
|
|||
case GUI_FILE_SAMPLE_OPEN_REPLACE_RAW:
|
||||
case GUI_FILE_SAMPLE_SAVE:
|
||||
case GUI_FILE_SAMPLE_SAVE_RAW:
|
||||
case GUI_FILE_SAMPLE_SAVE_ALL:
|
||||
workingDirSample=fileDialog->getPath()+DIR_SEPARATOR_STR;
|
||||
break;
|
||||
case GUI_FILE_EXPORT_AUDIO_ONE:
|
||||
|
|
@ -5132,6 +5159,81 @@ bool FurnaceGUI::loop() {
|
|||
}
|
||||
}
|
||||
break;
|
||||
case GUI_FILE_INS_SAVE_ALL: {
|
||||
String errors;
|
||||
for (int i=0; i<e->song.insLen; i++) {
|
||||
String nextPath=copyOfName;
|
||||
nextPath+=DIR_SEPARATOR_STR;
|
||||
nextPath+=fmt::sprintf("%.2X_",i);
|
||||
for (char j: e->song.ins[i]->name) {
|
||||
switch (j) {
|
||||
// these chars are reserved
|
||||
case '/': case '<': case '>': case ':': case '"': case '\\': case '|': case '?': case '*':
|
||||
nextPath+='_';
|
||||
break;
|
||||
default:
|
||||
nextPath+=j;
|
||||
break;
|
||||
}
|
||||
}
|
||||
nextPath+=".fui";
|
||||
logV("%s",nextPath);
|
||||
if (!e->song.ins[i]->save(nextPath.c_str(),&e->song,settings.writeInsNames)) {
|
||||
errors+=fmt::sprintf("%s: could not save!\n",e->song.ins[i]->name);
|
||||
}
|
||||
}
|
||||
|
||||
if (!errors.empty()) {
|
||||
showError(errors);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case GUI_FILE_WAVE_SAVE_ALL: {
|
||||
String errors;
|
||||
for (int i=0; i<e->song.waveLen; i++) {
|
||||
String nextPath=copyOfName;
|
||||
nextPath+=DIR_SEPARATOR_STR;
|
||||
nextPath+=fmt::sprintf("%.2X.fuw",i);
|
||||
logV("%s",nextPath);
|
||||
if (!e->song.wave[i]->save(nextPath.c_str())) {
|
||||
errors+=fmt::sprintf("%d: could not save!\n",i);
|
||||
}
|
||||
}
|
||||
|
||||
if (!errors.empty()) {
|
||||
showError(errors);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case GUI_FILE_SAMPLE_SAVE_ALL: {
|
||||
String errors;
|
||||
for (int i=0; i<e->song.sampleLen; i++) {
|
||||
String nextPath=copyOfName;
|
||||
nextPath+=DIR_SEPARATOR_STR;
|
||||
nextPath+=fmt::sprintf("%.2X_",i);
|
||||
for (char j: e->song.sample[i]->name) {
|
||||
switch (j) {
|
||||
// these chars are reserved
|
||||
case '/': case '<': case '>': case ':': case '"': case '\\': case '|': case '?': case '*':
|
||||
nextPath+='_';
|
||||
break;
|
||||
default:
|
||||
nextPath+=j;
|
||||
break;
|
||||
}
|
||||
}
|
||||
nextPath+=".wav";
|
||||
logV("%s",nextPath);
|
||||
if (!e->song.sample[i]->save(nextPath.c_str())) {
|
||||
errors+=fmt::sprintf("%s: could not save!\n",e->song.sample[i]->name);
|
||||
}
|
||||
}
|
||||
|
||||
if (!errors.empty()) {
|
||||
showError(errors);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case GUI_FILE_WAVE_SAVE:
|
||||
if (curWave>=0 && curWave<(int)e->song.wave.size()) {
|
||||
if (e->song.wave[curWave]->save(copyOfName.c_str())) {
|
||||
|
|
@ -5162,7 +5264,7 @@ bool FurnaceGUI::loop() {
|
|||
if (fileDialog->getFileName().size()>1) {
|
||||
warn=true;
|
||||
errs+=fmt::sprintf("- %s: %s\n",i,e->getLastError());
|
||||
} else {
|
||||
} else {;
|
||||
showError(e->getLastError());
|
||||
}
|
||||
} else {
|
||||
|
|
|
|||
|
|
@ -580,17 +580,20 @@ enum FurnaceGUIFileDialogs {
|
|||
GUI_FILE_INS_OPEN_REPLACE,
|
||||
GUI_FILE_INS_SAVE,
|
||||
GUI_FILE_INS_SAVE_DMP,
|
||||
GUI_FILE_INS_SAVE_ALL,
|
||||
GUI_FILE_WAVE_OPEN,
|
||||
GUI_FILE_WAVE_OPEN_REPLACE,
|
||||
GUI_FILE_WAVE_SAVE,
|
||||
GUI_FILE_WAVE_SAVE_DMW,
|
||||
GUI_FILE_WAVE_SAVE_RAW,
|
||||
GUI_FILE_WAVE_SAVE_ALL,
|
||||
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_RAW,
|
||||
GUI_FILE_SAMPLE_SAVE_ALL,
|
||||
GUI_FILE_EXPORT_AUDIO_ONE,
|
||||
GUI_FILE_EXPORT_AUDIO_PER_SYS,
|
||||
GUI_FILE_EXPORT_AUDIO_PER_CHANNEL,
|
||||
|
|
@ -831,6 +834,7 @@ enum FurnaceGUIActions {
|
|||
GUI_ACTION_INS_LIST_UP,
|
||||
GUI_ACTION_INS_LIST_DOWN,
|
||||
GUI_ACTION_INS_LIST_DIR_VIEW,
|
||||
GUI_ACTION_INS_LIST_SAVE_ALL,
|
||||
GUI_ACTION_INS_LIST_MAX,
|
||||
|
||||
GUI_ACTION_WAVE_LIST_MIN,
|
||||
|
|
@ -848,6 +852,7 @@ enum FurnaceGUIActions {
|
|||
GUI_ACTION_WAVE_LIST_UP,
|
||||
GUI_ACTION_WAVE_LIST_DOWN,
|
||||
GUI_ACTION_WAVE_LIST_DIR_VIEW,
|
||||
GUI_ACTION_WAVE_LIST_SAVE_ALL,
|
||||
GUI_ACTION_WAVE_LIST_MAX,
|
||||
|
||||
GUI_ACTION_SAMPLE_LIST_MIN,
|
||||
|
|
@ -869,6 +874,7 @@ enum FurnaceGUIActions {
|
|||
GUI_ACTION_SAMPLE_LIST_STOP_PREVIEW,
|
||||
GUI_ACTION_SAMPLE_LIST_DIR_VIEW,
|
||||
GUI_ACTION_SAMPLE_LIST_MAKE_MAP,
|
||||
GUI_ACTION_SAMPLE_LIST_SAVE_ALL,
|
||||
GUI_ACTION_SAMPLE_LIST_MAX,
|
||||
|
||||
GUI_ACTION_SAMPLE_MIN,
|
||||
|
|
@ -1953,6 +1959,7 @@ class FurnaceGUI {
|
|||
int backupInterval;
|
||||
int backupMaxCopies;
|
||||
int autoFillSave;
|
||||
int autoMacroStepSize;
|
||||
unsigned int maxUndoSteps;
|
||||
float vibrationStrength;
|
||||
int vibrationLength;
|
||||
|
|
@ -2210,6 +2217,7 @@ class FurnaceGUI {
|
|||
backupInterval(30),
|
||||
backupMaxCopies(5),
|
||||
autoFillSave(0),
|
||||
autoMacroStepSize(0),
|
||||
maxUndoSteps(100),
|
||||
vibrationStrength(0.5f),
|
||||
vibrationLength(20),
|
||||
|
|
@ -2753,6 +2761,7 @@ class FurnaceGUI {
|
|||
void drawMacros(std::vector<FurnaceGUIMacroDesc>& macros, FurnaceGUIMacroEditState& state);
|
||||
void alterSampleMap(int column, int val);
|
||||
|
||||
void insTabFMModernHeader(DivInstrument* ins);
|
||||
void insTabFM(DivInstrument* ins);
|
||||
void insTabSample(DivInstrument* ins);
|
||||
|
||||
|
|
|
|||
|
|
@ -478,8 +478,8 @@ const FurnaceGUIColors fxColors[256]={
|
|||
GUI_COLOR_PATTERN_EFFECT_INVALID,
|
||||
GUI_COLOR_PATTERN_EFFECT_INVALID,
|
||||
GUI_COLOR_PATTERN_EFFECT_INVALID,
|
||||
GUI_COLOR_PATTERN_EFFECT_VOLUME, // D8
|
||||
GUI_COLOR_PATTERN_EFFECT_VOLUME, // D9
|
||||
GUI_COLOR_PATTERN_EFFECT_INVALID,
|
||||
GUI_COLOR_PATTERN_EFFECT_INVALID,
|
||||
GUI_COLOR_PATTERN_EFFECT_INVALID,
|
||||
GUI_COLOR_PATTERN_EFFECT_INVALID,
|
||||
GUI_COLOR_PATTERN_EFFECT_VOLUME, // DC
|
||||
|
|
@ -703,6 +703,7 @@ const FurnaceGUIActionDef guiActions[GUI_ACTION_MAX]={
|
|||
D("INS_LIST_UP", _N("Instrument cursor up"), SDLK_UP),
|
||||
D("INS_LIST_DOWN", _N("Instrument cursor down"), SDLK_DOWN),
|
||||
D("INS_LIST_DIR_VIEW", _N("Instruments: toggle folders/standard view"), FURKMOD_CMD|SDLK_v),
|
||||
D("INS_LIST_SAVE_ALL", _N("Save all instruments"), 0),
|
||||
D("INS_LIST_MAX", "", NOT_AN_ACTION),
|
||||
|
||||
D("WAVE_LIST_MIN", _N("---Wavetable list"), NOT_AN_ACTION),
|
||||
|
|
@ -720,6 +721,7 @@ const FurnaceGUIActionDef guiActions[GUI_ACTION_MAX]={
|
|||
D("WAVE_LIST_UP", _N("Wavetable cursor up"), SDLK_UP),
|
||||
D("WAVE_LIST_DOWN", _N("Wavetable cursor down"), SDLK_DOWN),
|
||||
D("WAVE_LIST_DIR_VIEW", _N("Wavetables: toggle folders/standard view"), FURKMOD_CMD|SDLK_v),
|
||||
D("WAVE_LIST_SAVE_ALL", _N("Save all wavetables"), 0),
|
||||
D("WAVE_LIST_MAX", "", NOT_AN_ACTION),
|
||||
|
||||
D("SAMPLE_LIST_MIN", _N("---Sample list"), NOT_AN_ACTION),
|
||||
|
|
@ -741,6 +743,7 @@ const FurnaceGUIActionDef guiActions[GUI_ACTION_MAX]={
|
|||
D("SAMPLE_LIST_STOP_PREVIEW", _N("Stop sample preview"), 0),
|
||||
D("SAMPLE_LIST_DIR_VIEW", _N("Samples: Toggle folders/standard view"), FURKMOD_CMD|SDLK_v),
|
||||
D("SAMPLE_LIST_MAKE_MAP", _N("Samples: Make me a drum kit"), 0),
|
||||
D("SAMPLE_LIST_SAVE_ALL", _N("Save all samples"), 0),
|
||||
D("SAMPLE_LIST_MAX", "", NOT_AN_ACTION),
|
||||
|
||||
D("SAMPLE_MIN", _N("---Sample editor"), NOT_AN_ACTION),
|
||||
|
|
|
|||
|
|
@ -1780,7 +1780,7 @@ void FurnaceGUI::drawMacroEdit(FurnaceGUIMacroDesc& i, int totalFit, float avail
|
|||
if ((i.macro->vScroll+i.macro->vZoom)>(i.max-i.min)) {
|
||||
i.macro->vScroll=(i.max-i.min)-i.macro->vZoom;
|
||||
}
|
||||
} else {
|
||||
} else if (!settings.autoMacroStepSize) {
|
||||
macroPointSize+=wheelY;
|
||||
if (macroPointSize<1) macroPointSize=1;
|
||||
if (macroPointSize>256) macroPointSize=256;
|
||||
|
|
@ -2163,17 +2163,23 @@ void FurnaceGUI::drawMacros(std::vector<FurnaceGUIMacroDesc>& macros, FurnaceGUI
|
|||
ImGui::TableNextColumn();
|
||||
float lenAvail=ImGui::GetContentRegionAvail().x;
|
||||
//ImGui::Dummy(ImVec2(120.0f*dpiScale,dpiScale));
|
||||
ImGui::SetNextItemWidth(120.0f*dpiScale);
|
||||
if (ImGui::InputInt("##MacroPointSize",¯oPointSize,1,4)) {
|
||||
if (macroPointSize<1) macroPointSize=1;
|
||||
if (macroPointSize>256) macroPointSize=256;
|
||||
if (!settings.autoMacroStepSize) {
|
||||
ImGui::SetNextItemWidth(120.0f*dpiScale);
|
||||
if (ImGui::InputInt("##MacroPointSize",¯oPointSize,1,4)) {
|
||||
if (macroPointSize<1) macroPointSize=1;
|
||||
if (macroPointSize>256) macroPointSize=256;
|
||||
}
|
||||
}
|
||||
ImGui::TableNextColumn();
|
||||
float availableWidth=ImGui::GetContentRegionAvail().x-reservedSpace;
|
||||
int totalFit=MIN(255,availableWidth/MAX(1,macroPointSize*dpiScale));
|
||||
int scrollMax=0;
|
||||
if (settings.autoMacroStepSize) totalFit=1;
|
||||
for (FurnaceGUIMacroDesc& i: macros) {
|
||||
if (i.macro->len>scrollMax) scrollMax=i.macro->len;
|
||||
if (settings.autoMacroStepSize) {
|
||||
if ((i.macro->open&6)==0 && totalFit<i.macro->len) totalFit=i.macro->len;
|
||||
}
|
||||
}
|
||||
scrollMax-=totalFit;
|
||||
if (scrollMax<0) scrollMax=0;
|
||||
|
|
@ -2353,6 +2359,7 @@ void FurnaceGUI::drawMacros(std::vector<FurnaceGUIMacroDesc>& macros, FurnaceGUI
|
|||
for (FurnaceGUIMacroDesc& i: macros) {
|
||||
if (i.macro->len>scrollMax) scrollMax=i.macro->len;
|
||||
}
|
||||
if (settings.autoMacroStepSize) totalFit=MAX(1,m.macro->len);
|
||||
scrollMax-=totalFit;
|
||||
if (scrollMax<0) scrollMax=0;
|
||||
if (macroDragScroll>scrollMax) {
|
||||
|
|
@ -2366,15 +2373,17 @@ void FurnaceGUI::drawMacros(std::vector<FurnaceGUIMacroDesc>& macros, FurnaceGUI
|
|||
}
|
||||
ImGui::EndDisabled();
|
||||
|
||||
ImGui::SameLine();
|
||||
ImGui::Button(ICON_FA_SEARCH_PLUS "##MacroZoomB");
|
||||
if (ImGui::BeginPopupContextItem("MacroZoomP",ImGuiPopupFlags_MouseButtonLeft)) {
|
||||
ImGui::SetNextItemWidth(120.0f*dpiScale);
|
||||
if (ImGui::InputInt("##MacroPointSize",¯oPointSize,1,4)) {
|
||||
if (macroPointSize<1) macroPointSize=1;
|
||||
if (macroPointSize>256) macroPointSize=256;
|
||||
if (!settings.autoMacroStepSize) {
|
||||
ImGui::SameLine();
|
||||
ImGui::Button(ICON_FA_SEARCH_PLUS "##MacroZoomB");
|
||||
if (ImGui::BeginPopupContextItem("MacroZoomP",ImGuiPopupFlags_MouseButtonLeft)) {
|
||||
ImGui::SetNextItemWidth(120.0f*dpiScale);
|
||||
if (ImGui::InputInt("##MacroPointSize",¯oPointSize,1,4)) {
|
||||
if (macroPointSize<1) macroPointSize=1;
|
||||
if (macroPointSize>256) macroPointSize=256;
|
||||
}
|
||||
ImGui::EndPopup();
|
||||
}
|
||||
ImGui::EndPopup();
|
||||
}
|
||||
|
||||
m.height=ImGui::GetContentRegionAvail().y-ImGui::GetFontSize()-ImGui::GetFrameHeightWithSpacing()-(m.bit30?28.0f:12.0f)*dpiScale-ImGui::GetStyle().ItemSpacing.y*3.0f;
|
||||
|
|
@ -3069,6 +3078,151 @@ void FurnaceGUI::insTabSample(DivInstrument* ins) {
|
|||
}
|
||||
}
|
||||
|
||||
void FurnaceGUI::insTabFMModernHeader(DivInstrument* ins) {
|
||||
ImGui::TableNextRow(ImGuiTableRowFlags_Headers);
|
||||
ImGui::TableNextColumn();
|
||||
if (ins->type==DIV_INS_ESFM) {
|
||||
ImGui::TableNextColumn();
|
||||
CENTER_TEXT(ESFM_SHORT_NAME(ESFM_MODIN));
|
||||
ImGui::TextUnformatted(ESFM_SHORT_NAME(ESFM_MODIN));
|
||||
TOOLTIP_TEXT(ESFM_LONG_NAME(ESFM_MODIN));
|
||||
ImGui::TableNextColumn();
|
||||
ImGui::TableNextColumn();
|
||||
CENTER_TEXT(ESFM_SHORT_NAME(ESFM_DELAY));
|
||||
ImGui::TextUnformatted(ESFM_SHORT_NAME(ESFM_DELAY));
|
||||
TOOLTIP_TEXT(ESFM_LONG_NAME(ESFM_DELAY));
|
||||
}
|
||||
ImGui::TableNextColumn();
|
||||
CENTER_TEXT(FM_SHORT_NAME(FM_AR));
|
||||
ImGui::TextUnformatted(FM_SHORT_NAME(FM_AR));
|
||||
TOOLTIP_TEXT(FM_NAME(FM_AR));
|
||||
ImGui::TableNextColumn();
|
||||
CENTER_TEXT(FM_SHORT_NAME(FM_DR));
|
||||
ImGui::TextUnformatted(FM_SHORT_NAME(FM_DR));
|
||||
TOOLTIP_TEXT(FM_NAME(FM_DR));
|
||||
if (settings.susPosition==0) {
|
||||
ImGui::TableNextColumn();
|
||||
CENTER_TEXT(FM_SHORT_NAME(FM_SL));
|
||||
ImGui::TextUnformatted(FM_SHORT_NAME(FM_SL));
|
||||
TOOLTIP_TEXT(FM_NAME(FM_SL));
|
||||
}
|
||||
if (ins->type==DIV_INS_FM || ins->type==DIV_INS_OPZ || ins->type==DIV_INS_OPM) {
|
||||
ImGui::TableNextColumn();
|
||||
CENTER_TEXT(FM_SHORT_NAME(FM_D2R));
|
||||
ImGui::TextUnformatted(FM_SHORT_NAME(FM_D2R));
|
||||
TOOLTIP_TEXT(FM_NAME(FM_D2R));
|
||||
}
|
||||
ImGui::TableNextColumn();
|
||||
CENTER_TEXT(FM_SHORT_NAME(FM_RR));
|
||||
ImGui::TextUnformatted(FM_SHORT_NAME(FM_RR));
|
||||
TOOLTIP_TEXT(FM_NAME(FM_RR));
|
||||
if (settings.susPosition==1) {
|
||||
ImGui::TableNextColumn();
|
||||
CENTER_TEXT(FM_SHORT_NAME(FM_SL));
|
||||
ImGui::TextUnformatted(FM_SHORT_NAME(FM_SL));
|
||||
TOOLTIP_TEXT(FM_NAME(FM_SL));
|
||||
}
|
||||
ImGui::TableNextColumn();
|
||||
if (settings.susPosition==2) {
|
||||
ImGui::TableNextColumn();
|
||||
CENTER_TEXT(FM_SHORT_NAME(FM_SL));
|
||||
ImGui::TextUnformatted(FM_SHORT_NAME(FM_SL));
|
||||
TOOLTIP_TEXT(FM_NAME(FM_SL));
|
||||
}
|
||||
ImGui::TableNextColumn();
|
||||
CENTER_TEXT(FM_SHORT_NAME(FM_TL));
|
||||
ImGui::TextUnformatted(FM_SHORT_NAME(FM_TL));
|
||||
TOOLTIP_TEXT(FM_NAME(FM_TL));
|
||||
if (settings.susPosition==3) {
|
||||
ImGui::TableNextColumn();
|
||||
CENTER_TEXT(FM_SHORT_NAME(FM_SL));
|
||||
ImGui::TextUnformatted(FM_SHORT_NAME(FM_SL));
|
||||
TOOLTIP_TEXT(FM_NAME(FM_SL));
|
||||
}
|
||||
ImGui::TableNextColumn();
|
||||
if (ins->type==DIV_INS_FM || ins->type==DIV_INS_OPZ || ins->type==DIV_INS_OPM) {
|
||||
CENTER_TEXT(FM_SHORT_NAME(FM_RS));
|
||||
ImGui::TextUnformatted(FM_SHORT_NAME(FM_RS));
|
||||
TOOLTIP_TEXT(FM_NAME(FM_RS));
|
||||
} else {
|
||||
CENTER_TEXT(FM_SHORT_NAME(FM_KSL));
|
||||
ImGui::TextUnformatted(FM_SHORT_NAME(FM_KSL));
|
||||
TOOLTIP_TEXT(FM_NAME(FM_KSL));
|
||||
}
|
||||
if (ins->type==DIV_INS_OPZ) {
|
||||
ImGui::TableNextColumn();
|
||||
CENTER_TEXT(FM_SHORT_NAME(FM_EGSHIFT));
|
||||
ImGui::TextUnformatted(FM_SHORT_NAME(FM_EGSHIFT));
|
||||
TOOLTIP_TEXT(FM_NAME(FM_EGSHIFT));
|
||||
ImGui::TableNextColumn();
|
||||
CENTER_TEXT(FM_SHORT_NAME(FM_REV));
|
||||
ImGui::TextUnformatted(FM_SHORT_NAME(FM_REV));
|
||||
TOOLTIP_TEXT(FM_NAME(FM_REV));
|
||||
}
|
||||
if (ins->type==DIV_INS_ESFM) {
|
||||
ImGui::TableNextColumn();
|
||||
CENTER_TEXT(ESFM_SHORT_NAME(ESFM_OUTLVL));
|
||||
ImGui::TextUnformatted(ESFM_SHORT_NAME(ESFM_OUTLVL));
|
||||
TOOLTIP_TEXT(ESFM_LONG_NAME(ESFM_OUTLVL));
|
||||
}
|
||||
ImGui::TableNextColumn();
|
||||
CENTER_TEXT(FM_SHORT_NAME(FM_MULT));
|
||||
ImGui::TextUnformatted(FM_SHORT_NAME(FM_MULT));
|
||||
TOOLTIP_TEXT(FM_NAME(FM_MULT));
|
||||
if (ins->type==DIV_INS_OPZ) {
|
||||
ImGui::TableNextColumn();
|
||||
CENTER_TEXT(FM_SHORT_NAME(FM_FINE));
|
||||
ImGui::TextUnformatted(FM_SHORT_NAME(FM_FINE));
|
||||
TOOLTIP_TEXT(FM_NAME(FM_FINE));
|
||||
}
|
||||
if (ins->type==DIV_INS_ESFM) {
|
||||
ImGui::TableNextColumn();
|
||||
CENTER_TEXT(ESFM_SHORT_NAME(ESFM_CT));
|
||||
ImGui::TextUnformatted(ESFM_SHORT_NAME(ESFM_CT));
|
||||
TOOLTIP_TEXT(ESFM_LONG_NAME(ESFM_CT));
|
||||
}
|
||||
ImGui::TableNextColumn();
|
||||
if (ins->type==DIV_INS_FM || ins->type==DIV_INS_OPZ || ins->type==DIV_INS_OPM) {
|
||||
CENTER_TEXT(FM_SHORT_NAME(FM_DT));
|
||||
ImGui::TextUnformatted(FM_SHORT_NAME(FM_DT));
|
||||
TOOLTIP_TEXT(FM_NAME(FM_DT));
|
||||
ImGui::TableNextColumn();
|
||||
}
|
||||
if (ins->type==DIV_INS_ESFM) {
|
||||
CENTER_TEXT(ESFM_SHORT_NAME(ESFM_DT));
|
||||
ImGui::TextUnformatted(ESFM_SHORT_NAME(ESFM_DT));
|
||||
TOOLTIP_TEXT(ESFM_LONG_NAME(ESFM_DT));
|
||||
ImGui::TableNextColumn();
|
||||
}
|
||||
if (ins->type==DIV_INS_OPZ || ins->type==DIV_INS_OPM) {
|
||||
CENTER_TEXT(FM_SHORT_NAME(FM_DT2));
|
||||
ImGui::TextUnformatted(FM_SHORT_NAME(FM_DT2));
|
||||
TOOLTIP_TEXT(FM_NAME(FM_DT2));
|
||||
ImGui::TableNextColumn();
|
||||
}
|
||||
if (ins->type==DIV_INS_FM || ins->type==DIV_INS_OPM) {
|
||||
CENTER_TEXT(FM_SHORT_NAME(FM_AM));
|
||||
ImGui::TextUnformatted(FM_SHORT_NAME(FM_AM));
|
||||
TOOLTIP_TEXT(FM_NAME(FM_AM));
|
||||
} else {
|
||||
CENTER_TEXT("Other");
|
||||
ImGui::TextUnformatted("Other");
|
||||
}
|
||||
ImGui::TableNextColumn();
|
||||
if (ins->type==DIV_INS_OPL || ins->type==DIV_INS_OPL_DRUMS || ins->type==DIV_INS_OPZ || ins->type==DIV_INS_ESFM) {
|
||||
ImGui::TableNextColumn();
|
||||
CENTER_TEXT(FM_NAME(FM_WS));
|
||||
ImGui::TextUnformatted(FM_NAME(FM_WS));
|
||||
} else if (ins->type!=DIV_INS_OPLL && ins->type!=DIV_INS_OPM) {
|
||||
ImGui::TableNextColumn();
|
||||
CENTER_TEXT(FM_NAME(FM_SSG));
|
||||
ImGui::TextUnformatted(FM_NAME(FM_SSG));
|
||||
}
|
||||
ImGui::TableNextColumn();
|
||||
CENTER_TEXT(_("Envelope"));
|
||||
ImGui::TextUnformatted(_("Envelope"));
|
||||
}
|
||||
|
||||
void FurnaceGUI::insTabFM(DivInstrument* ins) {
|
||||
int opCount=4;
|
||||
if (ins->type==DIV_INS_OPLL) opCount=2;
|
||||
|
|
@ -3365,7 +3519,7 @@ void FurnaceGUI::insTabFM(DivInstrument* ins) {
|
|||
}
|
||||
|
||||
ImGui::BeginDisabled(!willDisplayOps);
|
||||
if (settings.fmLayout==0) {
|
||||
if (settings.fmLayout==0 || settings.fmLayout==7) {
|
||||
int numCols=15;
|
||||
if (ins->type==DIV_INS_OPL ||ins->type==DIV_INS_OPL_DRUMS) numCols=13;
|
||||
if (ins->type==DIV_INS_OPLL) numCols=12;
|
||||
|
|
@ -3420,144 +3574,23 @@ void FurnaceGUI::insTabFM(DivInstrument* ins) {
|
|||
}
|
||||
ImGui::TableSetupColumn("c14",ImGuiTableColumnFlags_WidthStretch,0.3f); // env
|
||||
|
||||
float sliderHeight=((ImGui::GetContentRegionAvail().y-ImGui::GetFrameHeightWithSpacing()*(settings.fmLayout==7?4.0f:1.0f))/opCount)-ImGui::GetStyle().ItemSpacing.y;
|
||||
|
||||
// header
|
||||
ImGui::TableNextRow(ImGuiTableRowFlags_Headers);
|
||||
ImGui::TableNextColumn();
|
||||
if (ins->type==DIV_INS_ESFM) {
|
||||
ImGui::TableNextColumn();
|
||||
CENTER_TEXT(ESFM_SHORT_NAME(ESFM_MODIN));
|
||||
ImGui::TextUnformatted(ESFM_SHORT_NAME(ESFM_MODIN));
|
||||
TOOLTIP_TEXT(ESFM_LONG_NAME(ESFM_MODIN));
|
||||
ImGui::TableNextColumn();
|
||||
ImGui::TableNextColumn();
|
||||
CENTER_TEXT(ESFM_SHORT_NAME(ESFM_DELAY));
|
||||
ImGui::TextUnformatted(ESFM_SHORT_NAME(ESFM_DELAY));
|
||||
TOOLTIP_TEXT(ESFM_LONG_NAME(ESFM_DELAY));
|
||||
if (settings.fmLayout==0) {
|
||||
insTabFMModernHeader(ins);
|
||||
}
|
||||
ImGui::TableNextColumn();
|
||||
CENTER_TEXT(FM_SHORT_NAME(FM_AR));
|
||||
ImGui::TextUnformatted(FM_SHORT_NAME(FM_AR));
|
||||
TOOLTIP_TEXT(FM_NAME(FM_AR));
|
||||
ImGui::TableNextColumn();
|
||||
CENTER_TEXT(FM_SHORT_NAME(FM_DR));
|
||||
ImGui::TextUnformatted(FM_SHORT_NAME(FM_DR));
|
||||
TOOLTIP_TEXT(FM_NAME(FM_DR));
|
||||
if (settings.susPosition==0) {
|
||||
ImGui::TableNextColumn();
|
||||
CENTER_TEXT(FM_SHORT_NAME(FM_SL));
|
||||
ImGui::TextUnformatted(FM_SHORT_NAME(FM_SL));
|
||||
TOOLTIP_TEXT(FM_NAME(FM_SL));
|
||||
}
|
||||
if (ins->type==DIV_INS_FM || ins->type==DIV_INS_OPZ || ins->type==DIV_INS_OPM) {
|
||||
ImGui::TableNextColumn();
|
||||
CENTER_TEXT(FM_SHORT_NAME(FM_D2R));
|
||||
ImGui::TextUnformatted(FM_SHORT_NAME(FM_D2R));
|
||||
TOOLTIP_TEXT(FM_NAME(FM_D2R));
|
||||
}
|
||||
ImGui::TableNextColumn();
|
||||
CENTER_TEXT(FM_SHORT_NAME(FM_RR));
|
||||
ImGui::TextUnformatted(FM_SHORT_NAME(FM_RR));
|
||||
TOOLTIP_TEXT(FM_NAME(FM_RR));
|
||||
if (settings.susPosition==1) {
|
||||
ImGui::TableNextColumn();
|
||||
CENTER_TEXT(FM_SHORT_NAME(FM_SL));
|
||||
ImGui::TextUnformatted(FM_SHORT_NAME(FM_SL));
|
||||
TOOLTIP_TEXT(FM_NAME(FM_SL));
|
||||
}
|
||||
ImGui::TableNextColumn();
|
||||
ImGui::TableNextColumn();
|
||||
CENTER_TEXT(FM_SHORT_NAME(FM_TL));
|
||||
ImGui::TextUnformatted(FM_SHORT_NAME(FM_TL));
|
||||
TOOLTIP_TEXT(FM_NAME(FM_TL));
|
||||
ImGui::TableNextColumn();
|
||||
if (ins->type==DIV_INS_FM || ins->type==DIV_INS_OPZ || ins->type==DIV_INS_OPM) {
|
||||
CENTER_TEXT(FM_SHORT_NAME(FM_RS));
|
||||
ImGui::TextUnformatted(FM_SHORT_NAME(FM_RS));
|
||||
TOOLTIP_TEXT(FM_NAME(FM_RS));
|
||||
} else {
|
||||
CENTER_TEXT(FM_SHORT_NAME(FM_KSL));
|
||||
ImGui::TextUnformatted(FM_SHORT_NAME(FM_KSL));
|
||||
TOOLTIP_TEXT(FM_NAME(FM_KSL));
|
||||
}
|
||||
if (ins->type==DIV_INS_OPZ) {
|
||||
ImGui::TableNextColumn();
|
||||
CENTER_TEXT(FM_SHORT_NAME(FM_EGSHIFT));
|
||||
ImGui::TextUnformatted(FM_SHORT_NAME(FM_EGSHIFT));
|
||||
TOOLTIP_TEXT(FM_NAME(FM_EGSHIFT));
|
||||
ImGui::TableNextColumn();
|
||||
CENTER_TEXT(FM_SHORT_NAME(FM_REV));
|
||||
ImGui::TextUnformatted(FM_SHORT_NAME(FM_REV));
|
||||
TOOLTIP_TEXT(FM_NAME(FM_REV));
|
||||
}
|
||||
if (ins->type==DIV_INS_ESFM) {
|
||||
ImGui::TableNextColumn();
|
||||
CENTER_TEXT(ESFM_SHORT_NAME(ESFM_OUTLVL));
|
||||
ImGui::TextUnformatted(ESFM_SHORT_NAME(ESFM_OUTLVL));
|
||||
TOOLTIP_TEXT(ESFM_LONG_NAME(ESFM_OUTLVL));
|
||||
}
|
||||
ImGui::TableNextColumn();
|
||||
CENTER_TEXT(FM_SHORT_NAME(FM_MULT));
|
||||
ImGui::TextUnformatted(FM_SHORT_NAME(FM_MULT));
|
||||
TOOLTIP_TEXT(FM_NAME(FM_MULT));
|
||||
if (ins->type==DIV_INS_OPZ) {
|
||||
ImGui::TableNextColumn();
|
||||
CENTER_TEXT(FM_SHORT_NAME(FM_FINE));
|
||||
ImGui::TextUnformatted(FM_SHORT_NAME(FM_FINE));
|
||||
TOOLTIP_TEXT(FM_NAME(FM_FINE));
|
||||
}
|
||||
if (ins->type==DIV_INS_ESFM) {
|
||||
ImGui::TableNextColumn();
|
||||
CENTER_TEXT(ESFM_SHORT_NAME(ESFM_CT));
|
||||
ImGui::TextUnformatted(ESFM_SHORT_NAME(ESFM_CT));
|
||||
TOOLTIP_TEXT(ESFM_LONG_NAME(ESFM_CT));
|
||||
}
|
||||
ImGui::TableNextColumn();
|
||||
if (ins->type==DIV_INS_FM || ins->type==DIV_INS_OPZ || ins->type==DIV_INS_OPM) {
|
||||
CENTER_TEXT(FM_SHORT_NAME(FM_DT));
|
||||
ImGui::TextUnformatted(FM_SHORT_NAME(FM_DT));
|
||||
TOOLTIP_TEXT(FM_NAME(FM_DT));
|
||||
ImGui::TableNextColumn();
|
||||
}
|
||||
if (ins->type==DIV_INS_ESFM) {
|
||||
CENTER_TEXT(ESFM_SHORT_NAME(ESFM_DT));
|
||||
ImGui::TextUnformatted(ESFM_SHORT_NAME(ESFM_DT));
|
||||
TOOLTIP_TEXT(ESFM_LONG_NAME(ESFM_DT));
|
||||
ImGui::TableNextColumn();
|
||||
}
|
||||
if (ins->type==DIV_INS_OPZ || ins->type==DIV_INS_OPM) {
|
||||
CENTER_TEXT(FM_SHORT_NAME(FM_DT2));
|
||||
ImGui::TextUnformatted(FM_SHORT_NAME(FM_DT2));
|
||||
TOOLTIP_TEXT(FM_NAME(FM_DT2));
|
||||
ImGui::TableNextColumn();
|
||||
}
|
||||
if (ins->type==DIV_INS_FM || ins->type==DIV_INS_OPM) {
|
||||
CENTER_TEXT(FM_SHORT_NAME(FM_AM));
|
||||
ImGui::TextUnformatted(FM_SHORT_NAME(FM_AM));
|
||||
TOOLTIP_TEXT(FM_NAME(FM_AM));
|
||||
} else {
|
||||
CENTER_TEXT("Other");
|
||||
ImGui::TextUnformatted("Other");
|
||||
}
|
||||
ImGui::TableNextColumn();
|
||||
if (ins->type==DIV_INS_OPL || ins->type==DIV_INS_OPL_DRUMS || ins->type==DIV_INS_OPZ || ins->type==DIV_INS_ESFM) {
|
||||
ImGui::TableNextColumn();
|
||||
CENTER_TEXT(FM_NAME(FM_WS));
|
||||
ImGui::TextUnformatted(FM_NAME(FM_WS));
|
||||
} else if (ins->type!=DIV_INS_OPLL && ins->type!=DIV_INS_OPM) {
|
||||
ImGui::TableNextColumn();
|
||||
CENTER_TEXT(FM_NAME(FM_SSG));
|
||||
ImGui::TextUnformatted(FM_NAME(FM_SSG));
|
||||
}
|
||||
ImGui::TableNextColumn();
|
||||
CENTER_TEXT(_("Envelope"));
|
||||
ImGui::TextUnformatted(_("Envelope"));
|
||||
|
||||
float sliderHeight=32.0f*dpiScale;
|
||||
|
||||
// main view
|
||||
for (int i=0; i<opCount; i++) {
|
||||
DivInstrumentFM::Operator& op=fmOrigin.op[(opCount==4 && ins->type!=DIV_INS_OPL_DRUMS && ins->type!=DIV_INS_ESFM)?opOrder[i]:i];
|
||||
DivInstrumentESFM::Operator& opE=ins->esfm.op[i];
|
||||
|
||||
// modern with more labels
|
||||
if (settings.fmLayout==7) {
|
||||
insTabFMModernHeader(ins);
|
||||
}
|
||||
|
||||
ImGui::TableNextRow();
|
||||
ImGui::TableNextColumn();
|
||||
|
||||
|
|
@ -3609,7 +3642,6 @@ void FurnaceGUI::insTabFM(DivInstrument* ins) {
|
|||
}
|
||||
|
||||
if (i==0) {
|
||||
sliderHeight=(ImGui::GetContentRegionAvail().y/opCount)-ImGui::GetStyle().ItemSpacing.y;
|
||||
float sliderMinHeightOPL=ImGui::GetFrameHeight()*4.0+ImGui::GetStyle().ItemSpacing.y*3.0;
|
||||
float sliderMinHeightESFM=ImGui::GetFrameHeight()*5.0+ImGui::GetStyle().ItemSpacing.y*4.0;
|
||||
if ((ins->type==DIV_INS_OPL || ins->type==DIV_INS_OPL_DRUMS || ins->type==DIV_INS_OPLL) && sliderHeight<sliderMinHeightOPL) {
|
||||
|
|
@ -3717,11 +3749,25 @@ void FurnaceGUI::insTabFM(DivInstrument* ins) {
|
|||
ImGui::TableNextColumn();
|
||||
ImGui::Dummy(ImVec2(4.0f*dpiScale,2.0f*dpiScale));
|
||||
|
||||
if (settings.susPosition==2) {
|
||||
ImGui::TableNextColumn();
|
||||
op.sl&=15;
|
||||
CENTER_VSLIDER;
|
||||
P(CWVSliderScalar("##SL",ImVec2(20.0f*dpiScale,sliderHeight),ImGuiDataType_U8,&op.sl,&_FIFTEEN,&_ZERO)); rightClickable
|
||||
}
|
||||
|
||||
ImGui::TableNextColumn();
|
||||
op.tl&=maxTl;
|
||||
CENTER_VSLIDER;
|
||||
P(CWVSliderScalar("##TL",ImVec2(20.0f*dpiScale,sliderHeight),ImGuiDataType_U8,&op.tl,&maxTl,&_ZERO)); rightClickable
|
||||
|
||||
if (settings.susPosition==3) {
|
||||
ImGui::TableNextColumn();
|
||||
op.sl&=15;
|
||||
CENTER_VSLIDER;
|
||||
P(CWVSliderScalar("##SL",ImVec2(20.0f*dpiScale,sliderHeight),ImGuiDataType_U8,&op.sl,&_FIFTEEN,&_ZERO)); rightClickable
|
||||
}
|
||||
|
||||
ImGui::TableNextColumn();
|
||||
CENTER_VSLIDER;
|
||||
if (ins->type==DIV_INS_FM || ins->type==DIV_INS_OPZ || ins->type==DIV_INS_OPM) {
|
||||
|
|
@ -4195,7 +4241,7 @@ void FurnaceGUI::insTabFM(DivInstrument* ins) {
|
|||
float textX_RR=ImGui::GetCursorPosX();
|
||||
P(CWVSliderScalar("##RR",ImVec2(20.0f*dpiScale,sliderHeight),ImGuiDataType_U8,&op.rr,&_FIFTEEN,&_ZERO)); rightClickable
|
||||
|
||||
if (settings.susPosition==1) {
|
||||
if (settings.susPosition>0) {
|
||||
ImGui::SameLine();
|
||||
op.sl&=15;
|
||||
textX_SL=ImGui::GetCursorPosX();
|
||||
|
|
@ -4911,7 +4957,7 @@ void FurnaceGUI::insTabFM(DivInstrument* ins) {
|
|||
ImGui::TableNextColumn();
|
||||
ImGui::Text("%s",FM_NAME(FM_RR));
|
||||
|
||||
if (settings.susPosition==1) {
|
||||
if (settings.susPosition>0) {
|
||||
ImGui::TableNextRow();
|
||||
ImGui::TableNextColumn();
|
||||
ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x);
|
||||
|
|
|
|||
|
|
@ -531,6 +531,11 @@ void FurnaceGUI::initSystemPresets() {
|
|||
CH(DIV_SYSTEM_OPL4_DRUMS, 1.0f, 0, "")
|
||||
}
|
||||
);
|
||||
ENTRY(
|
||||
"NEC PC-6001", {
|
||||
CH(DIV_SYSTEM_AY8910, 1.0f, 0, "customClock=3993600")
|
||||
}
|
||||
);
|
||||
ENTRY(
|
||||
"NEC PC-88", {}
|
||||
);
|
||||
|
|
@ -1227,6 +1232,18 @@ void FurnaceGUI::initSystemPresets() {
|
|||
CH(DIV_SYSTEM_MSM6258, 1.0f, 0, "clockSel=2")
|
||||
}
|
||||
);
|
||||
ENTRY(
|
||||
"FM-7", {
|
||||
CH(DIV_SYSTEM_AY8910, 1.0f, 0, "clockSel=12"),
|
||||
CH(DIV_SYSTEM_YM2203, 1.0f, 0, "clockSel=5")
|
||||
}
|
||||
);
|
||||
SUB_ENTRY(
|
||||
"FM-7 (extended channel 3)", {
|
||||
CH(DIV_SYSTEM_AY8910, 1.0f, 0, "clockSel=12"),
|
||||
CH(DIV_SYSTEM_YM2203_EXT, 1.0f, 0, "clockSel=5")
|
||||
}
|
||||
);
|
||||
ENTRY(
|
||||
"FM Towns", {
|
||||
CH(DIV_SYSTEM_YM2612, 1.0f, 0, "clockSel=2"), // YM3438
|
||||
|
|
@ -1271,6 +1288,14 @@ void FurnaceGUI::initSystemPresets() {
|
|||
)
|
||||
}
|
||||
);
|
||||
ENTRY(
|
||||
"Sord M5", {
|
||||
CH(DIV_SYSTEM_SMS, 1.0f, 0,
|
||||
"customClock=1773447\n"
|
||||
"chipType=1\n"
|
||||
)
|
||||
}
|
||||
);
|
||||
CATEGORY_END;
|
||||
|
||||
CATEGORY_BEGIN("Arcade systems","INSERT COIN");
|
||||
|
|
|
|||
|
|
@ -3624,6 +3624,14 @@ void FurnaceGUI::drawSettings() {
|
|||
settingsChanged=true;
|
||||
}
|
||||
|
||||
ImGui::BeginDisabled(settings.macroLayout==2);
|
||||
bool autoMacroStepSizeB=settings.autoMacroStepSize;
|
||||
if (ImGui::Checkbox(_("Automatic macro step size/horizontal zoom"),&autoMacroStepSizeB)) {
|
||||
settings.autoMacroStepSize=autoMacroStepSizeB;
|
||||
settingsChanged=true;
|
||||
}
|
||||
ImGui::EndDisabled();
|
||||
|
||||
// SUBSECTION WAVE EDITOR
|
||||
CONFIG_SUBSECTION(_("Wave Editor"));
|
||||
bool waveLayoutB=settings.waveLayout;
|
||||
|
|
@ -3662,6 +3670,10 @@ void FurnaceGUI::drawSettings() {
|
|||
settings.fmLayout=0;
|
||||
settingsChanged=true;
|
||||
}
|
||||
if (ImGui::RadioButton(_("Modern with more labels##fml7"),settings.fmLayout==7)) {
|
||||
settings.fmLayout=7;
|
||||
settingsChanged=true;
|
||||
}
|
||||
if (ImGui::RadioButton(_("Compact (2x2, classic)##fml1"),settings.fmLayout==1)) {
|
||||
settings.fmLayout=1;
|
||||
settingsChanged=true;
|
||||
|
|
@ -3698,6 +3710,16 @@ void FurnaceGUI::drawSettings() {
|
|||
settings.susPosition=1;
|
||||
settingsChanged=true;
|
||||
}
|
||||
ImGui::BeginDisabled(settings.fmLayout!=0);
|
||||
if (ImGui::RadioButton(_("After Release Rate, after spacing##susp2"),settings.susPosition==2)) {
|
||||
settings.susPosition=2;
|
||||
settingsChanged=true;
|
||||
}
|
||||
if (ImGui::RadioButton(_("After TL##susp3"),settings.susPosition==3)) {
|
||||
settings.susPosition=3;
|
||||
settingsChanged=true;
|
||||
}
|
||||
ImGui::EndDisabled();
|
||||
ImGui::Unindent();
|
||||
|
||||
bool separateFMColorsB=settings.separateFMColors;
|
||||
|
|
@ -4938,6 +4960,8 @@ void FurnaceGUI::readConfig(DivConfig& conf, FurnaceGUISettingGroups groups) {
|
|||
settings.capitalMenuBar=conf.getInt("capitalMenuBar",0);
|
||||
settings.insIconsStyle=conf.getInt("insIconsStyle",1);
|
||||
settings.sysSeparators=conf.getInt("sysSeparators",1);
|
||||
|
||||
settings.autoMacroStepSize=conf.getInt("autoMacroStepSize",0);
|
||||
}
|
||||
|
||||
if (groups&GUI_SETTINGS_LAYOUTS) {
|
||||
|
|
@ -5134,7 +5158,7 @@ void FurnaceGUI::readConfig(DivConfig& conf, FurnaceGUISettingGroups groups) {
|
|||
clampSetting(settings.loadKorean,0,1);
|
||||
clampSetting(settings.loadFallback,0,1);
|
||||
clampSetting(settings.fmLayout,0,6);
|
||||
clampSetting(settings.susPosition,0,1);
|
||||
clampSetting(settings.susPosition,0,3);
|
||||
clampSetting(settings.effectCursorDir,0,2);
|
||||
clampSetting(settings.cursorPastePos,0,1);
|
||||
clampSetting(settings.titleBarInfo,0,3);
|
||||
|
|
@ -5252,6 +5276,7 @@ void FurnaceGUI::readConfig(DivConfig& conf, FurnaceGUISettingGroups groups) {
|
|||
clampSetting(settings.backupInterval,10,86400);
|
||||
clampSetting(settings.backupMaxCopies,1,100);
|
||||
clampSetting(settings.autoFillSave,0,1);
|
||||
clampSetting(settings.autoMacroStepSize,0,1);
|
||||
|
||||
if (settings.exportLoops<0.0) settings.exportLoops=0.0;
|
||||
if (settings.exportFadeOut<0.0) settings.exportFadeOut=0.0;
|
||||
|
|
@ -5523,6 +5548,7 @@ void FurnaceGUI::writeConfig(DivConfig& conf, FurnaceGUISettingGroups groups) {
|
|||
conf.set("capitalMenuBar",settings.capitalMenuBar);
|
||||
conf.set("insIconsStyle",settings.insIconsStyle);
|
||||
conf.set("sysSeparators",settings.sysSeparators);
|
||||
conf.set("autoMacroStepSize",settings.autoMacroStepSize);
|
||||
}
|
||||
|
||||
// layout
|
||||
|
|
|
|||
|
|
@ -679,7 +679,7 @@ void FurnaceGUI::drawTutorial() {
|
|||
ImGui::TextWrapped(_(
|
||||
"if you need help, you may:\n"
|
||||
"- read the manual (a file called manual.pdf)\n"
|
||||
"- ask for help in Discussions (https://github.com/tildearrow/furnace/discussions), the Furnace Discord (https://discord.gg/EfrwT2wq7z) or Furnace in Revolt (official: https://rvlt.gg/GRPS6tmc)"
|
||||
"- ask for help in Discussions (https://github.com/tildearrow/furnace/discussions)"
|
||||
));
|
||||
|
||||
ImGui::Separator();
|
||||
|
|
|
|||
|
|
@ -192,7 +192,7 @@ void writeSubEntries(FILE* f, std::vector<FurnaceGUISysDef>& entries, int depth)
|
|||
String safeName;
|
||||
safeName.reserve(i.name.size());
|
||||
bool beginning=false;
|
||||
for (char j: i.name) {
|
||||
for (unsigned char j: i.name) {
|
||||
if (beginning && j==' ') continue;
|
||||
if (j=='=') continue;
|
||||
if (j<0x20) continue;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue