diff --git a/src/engine/engine.cpp b/src/engine/engine.cpp index c42db1bf2..fc61fa804 100644 --- a/src/engine/engine.cpp +++ b/src/engine/engine.cpp @@ -2149,6 +2149,13 @@ bool DivEngine::init(String outName) { loadConf(); + // load values + if (getConfString("audioEngine","SDL")=="JACK") { + audioEngine=DIV_AUDIO_JACK; + } else { + audioEngine=DIV_AUDIO_SDL; + } + // init the rest of engine SNDFILE* outFile=NULL; SF_INFO outInfo; @@ -2171,6 +2178,8 @@ bool DivEngine::init(String outName) { case DIV_AUDIO_JACK: #ifndef HAVE_JACK logE("Furnace was not compiled with JACK support!\n"); + setConf("audioEngine","SDL"); + saveConf(); return false; #else output=new TAAudioJACK; @@ -2183,8 +2192,8 @@ bool DivEngine::init(String outName) { logE("invalid audio engine!\n"); return false; } - want.bufsize=1024; - want.rate=44100; + want.bufsize=getConfInt("audioBufSize",1024); + want.rate=getConfInt("audioRate",44100); want.fragments=2; want.inChans=0; want.outChans=2; diff --git a/src/gui/gui.cpp b/src/gui/gui.cpp index b36c1bc50..0ab7ff705 100644 --- a/src/gui/gui.cpp +++ b/src/gui/gui.cpp @@ -1485,21 +1485,74 @@ void FurnaceGUI::drawAbout() { ImGui::End(); } +const char* mainFonts[]={ + "IBM Plex Sans", + "Liberation Sans", + "Roboto", + "", + "" +}; + +const char* patFonts[]={ + "IBM Plex Mono", + "Mononoki", + "PT Mono", + "Roboto Mono", + "", + "" +}; + +const char* audioBackends[]={ + "SDL", + "JACK" +}; + +const char* arcadeCores[]={ + "ymfm", + "Nuked-OPM" +}; + void FurnaceGUI::drawSettings() { if (!settingsOpen) return; + int curAudioBackend=0; + int curArcadeCore=0; + int curMainFont=0; + int curPatFont=0; if (ImGui::Begin("Settings",NULL,ImGuiWindowFlags_NoDocking)) { if (ImGui::BeginTabBar("settingsTab")) { if (ImGui::BeginTabItem("General")) { ImGui::Text("Hello world!"); ImGui::EndTabItem(); } + if (ImGui::BeginTabItem("Audio")) { + ImGui::Text("Backend"); + ImGui::SameLine(); + ImGui::Combo("##Backend",&curAudioBackend,audioBackends,2); + + ImGui::Text("Sample rate"); + + ImGui::Text("Buffer size"); + + ImGui::EndTabItem(); + } + if (ImGui::BeginTabItem("Emulation")) { + ImGui::Text("Arcade core"); + ImGui::SameLine(); + ImGui::Combo("##ArcadeCore",&curArcadeCore,arcadeCores,2); + + ImGui::EndTabItem(); + } if (ImGui::BeginTabItem("Appearance")) { ImGui::Text("Main font"); + ImGui::SameLine(); + ImGui::Combo("##MainFont",&curMainFont,mainFonts,5); if (ImGui::InputInt("Size##MainFontSize",&mainFontSize)) { if (mainFontSize<3) mainFontSize=3; if (mainFontSize>96) mainFontSize=96; } ImGui::Text("Pattern font"); + ImGui::SameLine(); + ImGui::Combo("##PatFont",&curPatFont,patFonts,6); if (ImGui::InputInt("Size##PatFontSize",&patFontSize)) { if (patFontSize<3) patFontSize=3; if (patFontSize>96) patFontSize=96; @@ -1728,6 +1781,49 @@ void FurnaceGUI::makeUndo(ActionType action) { } } +void FurnaceGUI::doSelectAll() { + finishSelection(); + curNibble=false; + if (selStart.xFine==0 && selEnd.xFine==2+e->song.pat[selEnd.xCoarse].effectRows*2) { + if (selStart.y==0 && selEnd.y==e->song.patLen-1) { // select entire pattern + selStart.xCoarse=0; + selStart.xFine=0; + selEnd.xCoarse=e->getChannelCount(e->song.system)-1; + selEnd.xFine=2+e->song.pat[selEnd.xCoarse].effectRows*2; + } else { // select entire column + selStart.y=0; + selEnd.y=e->song.patLen-1; + } + } else { + int selStartX=0; + int selEndX=0; + // find row position + for (SelectionPoint i; i.xCoarse!=selStart.xCoarse || i.xFine!=selStart.xFine; selStartX++) { + i.xFine++; + if (i.xFine>=3+e->song.pat[i.xCoarse].effectRows*2) { + i.xFine=0; + i.xCoarse++; + } + } + for (SelectionPoint i; i.xCoarse!=selEnd.xCoarse || i.xFine!=selEnd.xFine; selEndX++) { + i.xFine++; + if (i.xFine>=3+e->song.pat[i.xCoarse].effectRows*2) { + i.xFine=0; + i.xCoarse++; + } + } + + float aspect=float(selEndX-selStartX+1)/float(selEnd.y-selStart.y+1); + if (aspect<1.0f && !(selStart.y==0 && selEnd.y==e->song.patLen-1)) { // up-down + selStart.y=0; + selEnd.y=e->song.patLen-1; + } else { // left-right + selStart.xFine=0; + selEnd.xFine=2+e->song.pat[selEnd.xCoarse].effectRows*2; + } + } +} + void FurnaceGUI::doDelete() { finishSelection(); prepareUndo(GUI_ACTION_PATTERN_DELETE); @@ -2085,6 +2181,9 @@ void FurnaceGUI::keyDown(SDL_Event& ev) { case GUI_WINDOW_PATTERN: { if (ev.key.keysym.mod&KMOD_CTRL) { switch (ev.key.keysym.sym) { + case SDLK_a: + doSelectAll(); + break; case SDLK_x: doCopy(true); break; @@ -2534,19 +2633,19 @@ bool FurnaceGUI::loop() { ImGui::EndMenu(); } if (ImGui::BeginMenu("edit")) { - if (ImGui::MenuItem("undo")) doUndo(); - if (ImGui::MenuItem("redo")) doRedo(); + if (ImGui::MenuItem("undo","Ctrl-Z")) doUndo(); + if (ImGui::MenuItem("redo","Shift-Ctrl-Z")) doRedo(); ImGui::Separator(); - if (ImGui::MenuItem("cut")) doCopy(true); - if (ImGui::MenuItem("copy")) doCopy(false); - if (ImGui::MenuItem("paste")) doPaste(); - if (ImGui::MenuItem("delete")) doDelete(); - ImGui::MenuItem("select all"); + if (ImGui::MenuItem("cut","Ctrl-X")) doCopy(true); + if (ImGui::MenuItem("copy","Ctrl-C")) doCopy(false); + if (ImGui::MenuItem("paste","Ctrl-V")) doPaste(); + if (ImGui::MenuItem("delete","Delete")) doDelete(); + if (ImGui::MenuItem("select all","Ctrl-A")) doSelectAll(); ImGui::Separator(); - ImGui::MenuItem("note up"); - ImGui::MenuItem("note down"); - ImGui::MenuItem("octave up"); - ImGui::MenuItem("octave down"); + ImGui::MenuItem("note up","Alt-Q"); + ImGui::MenuItem("note down","Alt-A"); + ImGui::MenuItem("octave up","Alt-Shift-Q"); + ImGui::MenuItem("octave down","Alt-Shift-A"); ImGui::Separator(); ImGui::MenuItem("clear..."); ImGui::EndMenu(); diff --git a/src/gui/gui.h b/src/gui/gui.h index 4ad210dd2..53eae607c 100644 --- a/src/gui/gui.h +++ b/src/gui/gui.h @@ -230,6 +230,7 @@ class FurnaceGUI { void editAdvance(); void prepareUndo(ActionType action); void makeUndo(ActionType action); + void doSelectAll(); void doDelete(); void doPullDelete(); void doInsert();