diff --git a/TODO.md b/TODO.md index 4af99b6fa..20c54eb9a 100644 --- a/TODO.md +++ b/TODO.md @@ -3,14 +3,10 @@ - tutorial? - ease-of-use improvements... ideas: - preset compat flags - - setting to toggle the Choose a System screen on new project - maybe reduced set of presets for the sake of simplicity - a more preferable highlight/drag system - some speed/intuitive workflow improvements that go a long way - - Had a hard time finding the docs on github and in Furnace's folder. - make .pdf manual out of doc/ - - you're going too slow; please run - break compatibility if it relieves complexity -- ins/wave/sample organization (folders and all) - multi-key binds - bug fixes diff --git a/demos/gameboy/finger.fur b/demos/gameboy/finger.fur new file mode 100644 index 000000000..eb1917a34 Binary files /dev/null and b/demos/gameboy/finger.fur differ diff --git a/demos/x16/Cafe - 010 Editor 2.0kg.fur b/demos/x16/Cafe - 010 Editor 2.0kg.fur index 6533a3846..ef1c9fea3 100644 Binary files a/demos/x16/Cafe - 010 Editor 2.0kg.fur and b/demos/x16/Cafe - 010 Editor 2.0kg.fur differ diff --git a/demos/x16/her11.fur b/demos/x16/her11.fur index 1cfabac19..06c4870f8 100644 Binary files a/demos/x16/her11.fur and b/demos/x16/her11.fur differ diff --git a/demos/x16/keygen19.fur b/demos/x16/keygen19.fur new file mode 100644 index 000000000..26d04ea82 Binary files /dev/null and b/demos/x16/keygen19.fur differ diff --git a/doc/7-systems/pce.md b/doc/7-systems/pce.md index cfa71a531..80f4af109 100644 --- a/doc/7-systems/pce.md +++ b/doc/7-systems/pce.md @@ -19,4 +19,4 @@ furthermore, it has some PCM and LFO! - when LFO is enabled, channel 2 is muted and its output is passed to channel 1's frequency. - `13xx`: **set LFO speed.** - `17xx`: **toggle PCM mode.** - - _this effect is here for compatibility reasons;_ it is otherwise recommended to use Sample type instruments (which automatically enable PCM mode when used). + - _this effect is here for compatibility reasons_; it is otherwise recommended to use Sample type instruments (which automatically enable PCM mode when used). diff --git a/instruments/FM/drums/OPM Power Snare.fui b/instruments/FM/drums/OPM Power Snare.fui new file mode 100644 index 000000000..588465823 Binary files /dev/null and b/instruments/FM/drums/OPM Power Snare.fui differ diff --git a/instruments/other/AY Heavy Kick and Snare.fui b/instruments/other/AY Heavy Kick and Snare.fui new file mode 100644 index 000000000..2bcb7d954 Binary files /dev/null and b/instruments/other/AY Heavy Kick and Snare.fui differ diff --git a/instruments/other/AY Heavy Kick.fui b/instruments/other/AY Heavy Kick.fui new file mode 100644 index 000000000..3f3de6fca Binary files /dev/null and b/instruments/other/AY Heavy Kick.fui differ diff --git a/src/audio/rtmidi.cpp b/src/audio/rtmidi.cpp index cbf4dca42..ea1903c36 100644 --- a/src/audio/rtmidi.cpp +++ b/src/audio/rtmidi.cpp @@ -160,6 +160,7 @@ bool TAMidiInRtMidi::quit() { bool TAMidiOutRtMidi::send(const TAMidiMessage& what) { if (!isOpen) return false; + if (!isWorking) return false; if (what.type<0x80) return false; size_t len=0; switch (what.type&0xf0) { @@ -190,6 +191,7 @@ bool TAMidiOutRtMidi::send(const TAMidiMessage& what) { port->sendMessage(what.sysExData.get(),len); } catch (RtMidiError& e) { logE("MIDI output error! %s",e.what()); + isWorking=false; return false; } return true; @@ -209,6 +211,7 @@ bool TAMidiOutRtMidi::send(const TAMidiMessage& what) { port->sendMessage((const unsigned char*)&what.type,len); } catch (RtMidiError& e) { logE("MIDI output error! %s",e.what()); + isWorking=false; return false; } return true; @@ -237,17 +240,20 @@ bool TAMidiOutRtMidi::openDevice(String name) { } isOpen=portOpen; if (!portOpen) logW("could not find MIDI out device..."); + isWorking=true; return portOpen; } catch (RtMidiError& e) { logW("could not open MIDI out device! %s",e.what()); return false; } + isWorking=true; return true; } bool TAMidiOutRtMidi::closeDevice() { if (port==NULL) return false; if (!isOpen) return false; + isWorking=false; try { port->closePort(); } catch (RtMidiError& e) { diff --git a/src/audio/rtmidi.h b/src/audio/rtmidi.h index 5a8e06e0b..33a71af56 100644 --- a/src/audio/rtmidi.h +++ b/src/audio/rtmidi.h @@ -38,7 +38,7 @@ class TAMidiInRtMidi: public TAMidiIn { class TAMidiOutRtMidi: public TAMidiOut { RtMidiOut* port; - bool isOpen; + bool isOpen, isWorking; public: bool send(const TAMidiMessage& what); bool isDeviceOpen(); @@ -49,5 +49,6 @@ class TAMidiOutRtMidi: public TAMidiOut { bool init(); TAMidiOutRtMidi(): port(NULL), - isOpen(false) {} + isOpen(false), + isWorking(false) {} }; \ No newline at end of file diff --git a/src/engine/platform/segapcm.cpp b/src/engine/platform/segapcm.cpp index 47411496a..9376bb0cf 100644 --- a/src/engine/platform/segapcm.cpp +++ b/src/engine/platform/segapcm.cpp @@ -423,7 +423,7 @@ const void* DivPlatformSegaPCM::getSampleMem(int index) { } size_t DivPlatformSegaPCM::getSampleMemCapacity(int index) { - return index == 0 ? 16777216 : 0; + return index == 0 ? 2097152 : 0; } size_t DivPlatformSegaPCM::getSampleMemUsage(int index) { @@ -465,7 +465,7 @@ void DivPlatformSegaPCM::reset() { void DivPlatformSegaPCM::renderSamples(int sysID) { size_t memPos=0; - memset(sampleMem,0,16777216); + memset(sampleMem,0,2097152); memset(sampleLoaded,0,256*sizeof(bool)); memset(sampleOffSegaPCM,0,256*sizeof(unsigned int)); memset(sampleEndSegaPCM,0,256); @@ -482,7 +482,7 @@ void DivPlatformSegaPCM::renderSamples(int sysID) { } logV("- sample %d will be at %x with length %x",i,memPos,alignedSize); sampleLoaded[i]=true; - if (memPos>=16777216) break; + if (memPos>=2097152) break; sampleOffSegaPCM[i]=memPos; for (unsigned int j=0; j=sample->samples) { @@ -491,10 +491,10 @@ void DivPlatformSegaPCM::renderSamples(int sysID) { sampleMem[memPos++]=((unsigned char)sample->data8[j]+0x80); } sampleEndSegaPCM[i]=((memPos+0xff)>>8)-1; - if (memPos>=16777216) break; + if (memPos>=2097152) break; } logV(" and it ends in %d",sampleEndSegaPCM[i]); - if (memPos>=16777216) break; + if (memPos>=2097152) break; } sampleMemLen=memPos; } @@ -522,10 +522,10 @@ int DivPlatformSegaPCM::init(DivEngine* p, int channels, int sugRate, const DivC isMuted[i]=false; oscBuf[i]=new DivDispatchOscBuffer; } - sampleMem=new unsigned char[16777216]; + sampleMem=new unsigned char[2097152]; pcm.set_bank(segapcm_device::BANK_12M|segapcm_device::BANK_MASKF8); pcm.set_read([this](unsigned int addr) -> unsigned char { - return sampleMem[addr&0xffffff]; + return sampleMem[addr&0x1fffff]; }); setFlags(flags); reset(); diff --git a/src/engine/playback.cpp b/src/engine/playback.cpp index 0021d93b1..ce94b883b 100644 --- a/src/engine/playback.cpp +++ b/src/engine/playback.cpp @@ -1691,6 +1691,10 @@ void DivEngine::runMidiTime(int totalCycles) { } void DivEngine::nextBuf(float** in, float** out, int inChans, int outChans, unsigned int size) { + if (!size) { + logW("nextBuf called with size 0!"); + return; + } lastLoopPos=-1; if (out!=NULL) { diff --git a/src/gui/gui.cpp b/src/gui/gui.cpp index 4edaeab23..d67888055 100644 --- a/src/gui/gui.cpp +++ b/src/gui/gui.cpp @@ -497,6 +497,15 @@ bool FurnaceGUI::InvCheckbox(const char* label, bool* value) { return false; } +void FurnaceGUI::sameLineMaybe(float width) { + if (width<0.0f) width=ImGui::GetFrameHeight(); + + logV("sameLineMaybe: %f %f",ImGui::GetContentRegionAvail().x,width); + + ImGui::SameLine(); + if (ImGui::GetContentRegionAvail().xcreateNewFromDefaults(); + undoHist.clear(); + redoHist.clear(); + curFileName=""; + modified=false; + curNibble=false; + orderNibble=false; + orderCursor=-1; + samplePos=0; + updateSampleTex=true; + selStart=SelectionPoint(); + selEnd=SelectionPoint(); + cursor=SelectionPoint(); + updateWindowTitle(); + } else { + ImGui::OpenPopup("New Song"); + } } if (displayEditString) { diff --git a/src/gui/gui.h b/src/gui/gui.h index 77199a6cb..8bce5fa4e 100644 --- a/src/gui/gui.h +++ b/src/gui/gui.h @@ -1508,6 +1508,7 @@ class FurnaceGUI { int renderClearPos; int insertBehavior; int pullDeleteRow; + int newSongBehavior; unsigned int maxUndoSteps; String mainFontPath; String patFontPath; @@ -1659,6 +1660,7 @@ class FurnaceGUI { renderClearPos(0), insertBehavior(1), pullDeleteRow(1), + newSongBehavior(0), maxUndoSteps(100), mainFontPath(""), patFontPath(""), @@ -2089,6 +2091,8 @@ class FurnaceGUI { void pushWarningColor(bool warnCond, bool errorCond=false); void popWarningColor(); + void sameLineMaybe(float width=-1.0f); + float calcBPM(const DivGroovePattern& speeds, float hz, int vN, int vD); void patternRow(int i, bool isPlaying, float lineHeight, int chans, int ord, const DivPattern** patCache, bool inhibitSel); diff --git a/src/gui/insEdit.cpp b/src/gui/insEdit.cpp index ca254d2c8..f0de1c614 100644 --- a/src/gui/insEdit.cpp +++ b/src/gui/insEdit.cpp @@ -59,79 +59,79 @@ const char* opllVariants[4]={ const char* opllInsNames[4][17]={ /* YM2413 */ { "User", - "Violin", - "Guitar", - "Piano", - "Flute", - "Clarinet", - "Oboe", - "Trumpet", - "Organ", - "Horn", - "Synth", - "Harpsichord", - "Vibraphone", - "Synth Bass", - "Acoustic Bass", - "Electric Guitar", + "1. Violin", + "2. Guitar", + "3. Piano", + "4. Flute", + "5. Clarinet", + "6. Oboe", + "7. Trumpet", + "8. Organ", + "9. Horn", + "10. Synth", + "11. Harpsichord", + "12. Vibraphone", + "13. Synth Bass", + "14. Acoustic Bass", + "15. Electric Guitar", "Drums" }, /* YMF281 */ { "User", - "Electric String", - "Bow wow", - "Electric Guitar", - "Organ", - "Clarinet", - "Saxophone", - "Trumpet", - "Street Organ", - "Synth Brass", - "Electric Piano", - "Bass", - "Vibraphone", - "Chime", - "Tom Tom II", - "Noise", + "1. Electric String", + "2. Bow wow", + "3. Electric Guitar", + "4. Organ", + "5. Clarinet", + "6. Saxophone", + "7. Trumpet", + "8. Street Organ", + "9. Synth Brass", + "10. Electric Piano", + "11. Bass", + "12. Vibraphone", + "13. Chime", + "14. Tom Tom II", + "15. Noise", "Drums" }, /* YM2423 */ { "User", - "Strings", - "Guitar", - "Electric Guitar", - "Electric Piano", - "Flute", - "Marimba", - "Trumpet", - "Harmonica", - "Tuba", - "Synth Brass", - "Short Saw", - "Vibraphone", - "Electric Guitar 2", - "Synth Bass", - "Sitar", + "1. Strings", + "2. Guitar", + "3. Electric Guitar", + "4. Electric Piano", + "5. Flute", + "6. Marimba", + "7. Trumpet", + "8. Harmonica", + "9. Tuba", + "10. Synth Brass", + "11. Short Saw", + "12. Vibraphone", + "13. Electric Guitar 2", + "14. Synth Bass", + "15. Sitar", "Drums" }, // stolen from FamiTracker /* VRC7 */ { "User", - "Bell", - "Guitar", - "Piano", - "Flute", - "Clarinet", - "Rattling Bell", - "Trumpet", - "Reed Organ", - "Soft Bell", - "Xylophone", - "Vibraphone", - "Brass", - "Bass Guitar", - "Synth", - "Chorus", + "1. Bell", + "2. Guitar", + "3. Piano", + "4. Flute", + "5. Clarinet", + "6. Rattling Bell", + "7. Trumpet", + "8. Reed Organ", + "9. Soft Bell", + "10. Xylophone", + "11. Vibraphone", + "12. Brass", + "13. Bass Guitar", + "14. Synth", + "15. Chorus", "Drums" } }; diff --git a/src/gui/sampleEdit.cpp b/src/gui/sampleEdit.cpp index 0ce5b9182..d3b8a19a2 100644 --- a/src/gui/sampleEdit.cpp +++ b/src/gui/sampleEdit.cpp @@ -200,6 +200,9 @@ void FurnaceGUI::drawSampleEdit() { SAMPLE_WARN(warnLoopPos,"QSound: loop cannot be longer than 32767 samples"); } } + if (sample->samples>65535) { + SAMPLE_WARN(warnLength,"QSound: maximum sample length is 65535"); + } break; case DIV_SYSTEM_NES: if (sample->loop) { @@ -207,11 +210,17 @@ void FurnaceGUI::drawSampleEdit() { SAMPLE_WARN(warnLoopPos,"NES: loop point ignored on DPCM (may only loop entire sample)"); } } + if (sample->samples>32648) { + SAMPLE_WARN(warnLength,"NES: maximum DPCM sample length is 32648"); + } break; case DIV_SYSTEM_X1_010: if (sample->loop) { SAMPLE_WARN(warnLoop,"X1-010: samples can't loop"); } + if (sample->samples>131072) { + SAMPLE_WARN(warnLength,"X1-010: maximum sample length is 131072"); + } break; case DIV_SYSTEM_GA20: if (sample->loop) { @@ -235,9 +244,12 @@ void FurnaceGUI::drawSampleEdit() { if (sample->loop) { SAMPLE_WARN(warnLoop,"YM2610: ADPCM-A samples can't loop"); if (sample->loopStart!=0 || sample->loopEnd!=(int)(sample->samples)) { - SAMPLE_WARN(warnLoopPos,"YM2608: loop point ignored on ADPCM-B (may only loop entire sample)"); + SAMPLE_WARN(warnLoopPos,"YM2610: loop point ignored on ADPCM-B (may only loop entire sample)"); } } + if (sample->samples>2097152) { + SAMPLE_WARN(warnLength,"YM2610: maximum ADPCM-A sample length is 2097152"); + } break; case DIV_SYSTEM_AMIGA: if (sample->loop) { @@ -245,10 +257,28 @@ void FurnaceGUI::drawSampleEdit() { SAMPLE_WARN(warnLoopPos,"Amiga: loop must be a multiple of 2"); } } + if (sample->samples>131070) { + SAMPLE_WARN(warnLength,"Amiga: maximum sample length is 131070"); + } + break; + case DIV_SYSTEM_SEGAPCM: + case DIV_SYSTEM_SEGAPCM_COMPAT: + if (sample->samples>65280) { + SAMPLE_WARN(warnLength,"SegaPCM: maximum sample length is 65280"); + } break; default: break; } + if (e->song.system[i]!=DIV_SYSTEM_PCM_DAC) { + if (e->song.system[i]==DIV_SYSTEM_ES5506) { + if (sample->loopMode==DIV_SAMPLE_LOOP_BACKWARD) { + SAMPLE_WARN(warnLoopMode,"ES5506: backward loop mode isn't supported"); + } + } else if (sample->loopMode!=DIV_SAMPLE_LOOP_FORWARD) { + SAMPLE_WARN(warnLoopMode,"backward/ping-pong only supported in Generic PCM DAC\nping-pong also on ES5506"); + } + } // chips grid DivDispatch* dispatch=e->getDispatch(i); @@ -514,6 +544,9 @@ void FurnaceGUI::drawSampleEdit() { } ImGui::EndCombo(); } + if (ImGui::IsItemHovered() && !warnLoopMode.empty()) { + ImGui::SetTooltip("%s",warnLoopMode.c_str()); + } popWarningColor(); pushWarningColor(!warnLoopPos.empty()); @@ -682,7 +715,7 @@ void FurnaceGUI::drawSampleEdit() { if (ImGui::IsItemHovered()) { ImGui::SetTooltip("Edit mode: Select"); } - ImGui::SameLine(); + sameLineMaybe(); pushToggleColors(sampleDragMode); if (ImGui::Button(ICON_FA_PENCIL "##SDraw")) { sampleDragMode=true; @@ -692,9 +725,9 @@ void FurnaceGUI::drawSampleEdit() { ImGui::SetTooltip("Edit mode: Draw"); } ImGui::BeginDisabled(sample->depth!=DIV_SAMPLE_DEPTH_8BIT && sample->depth!=DIV_SAMPLE_DEPTH_16BIT); - ImGui::SameLine(); + sameLineMaybe(); ImGui::Dummy(ImVec2(4.0*dpiScale,dpiScale)); - ImGui::SameLine(); + sameLineMaybe(); ImGui::Button(ICON_FA_ARROWS_H "##SResize"); if (ImGui::IsItemClicked()) { resizeSize=sample->samples; @@ -729,7 +762,7 @@ void FurnaceGUI::drawSampleEdit() { } else { resizeSize=sample->samples; } - ImGui::SameLine(); + sameLineMaybe(); ImGui::Button(ICON_FA_EXPAND "##SResample"); if (ImGui::IsItemClicked()) { resampleTarget=targetRate; @@ -786,14 +819,14 @@ void FurnaceGUI::drawSampleEdit() { } ImGui::SameLine(); ImGui::Dummy(ImVec2(4.0*dpiScale,dpiScale)); - ImGui::SameLine(); + sameLineMaybe(); if (ImGui::Button(ICON_FA_UNDO "##SUndo")) { doUndoSample(); } if (ImGui::IsItemHovered()) { ImGui::SetTooltip("Undo"); } - ImGui::SameLine(); + sameLineMaybe(); if (ImGui::Button(ICON_FA_REPEAT "##SRedo")) { doRedoSample(); } @@ -802,7 +835,7 @@ void FurnaceGUI::drawSampleEdit() { } ImGui::SameLine(); ImGui::Dummy(ImVec2(4.0*dpiScale,dpiScale)); - ImGui::SameLine(); + sameLineMaybe(); ImGui::Button(ICON_FA_VOLUME_UP "##SAmplify"); if (ImGui::IsItemHovered()) { ImGui::SetTooltip("Amplify"); @@ -850,28 +883,28 @@ void FurnaceGUI::drawSampleEdit() { } ImGui::EndPopup(); } - ImGui::SameLine(); + sameLineMaybe(); if (ImGui::Button(ICON_FA_ARROWS_V "##SNormalize")) { doAction(GUI_ACTION_SAMPLE_NORMALIZE); } if (ImGui::IsItemHovered()) { ImGui::SetTooltip("Normalize"); } - ImGui::SameLine(); + sameLineMaybe(); if (ImGui::Button(ICON_FA_ARROW_UP "##SFadeIn")) { doAction(GUI_ACTION_SAMPLE_FADE_IN); } if (ImGui::IsItemHovered()) { ImGui::SetTooltip("Fade in"); } - ImGui::SameLine(); + sameLineMaybe(); if (ImGui::Button(ICON_FA_ARROW_DOWN "##SFadeOut")) { doAction(GUI_ACTION_SAMPLE_FADE_OUT); } if (ImGui::IsItemHovered()) { ImGui::SetTooltip("Fade out"); } - ImGui::SameLine(); + sameLineMaybe(); ImGui::Button(ICON_FA_ADJUST "##SInsertSilence"); if (ImGui::IsItemHovered()) { ImGui::SetTooltip("Insert silence"); @@ -902,21 +935,21 @@ void FurnaceGUI::drawSampleEdit() { } ImGui::EndPopup(); } - ImGui::SameLine(); + sameLineMaybe(); if (ImGui::Button(ICON_FA_ERASER "##SSilence")) { doAction(GUI_ACTION_SAMPLE_SILENCE); } if (ImGui::IsItemHovered()) { ImGui::SetTooltip("Apply silence"); } - ImGui::SameLine(); + sameLineMaybe(); if (ImGui::Button(ICON_FA_TIMES "##SDelete")) { doAction(GUI_ACTION_SAMPLE_DELETE); } if (ImGui::IsItemHovered()) { ImGui::SetTooltip("Delete"); } - ImGui::SameLine(); + sameLineMaybe(); if (ImGui::Button(ICON_FA_CROP "##STrim")) { doAction(GUI_ACTION_SAMPLE_TRIM); } @@ -925,28 +958,28 @@ void FurnaceGUI::drawSampleEdit() { } ImGui::SameLine(); ImGui::Dummy(ImVec2(4.0*dpiScale,dpiScale)); - ImGui::SameLine(); + sameLineMaybe(); if (ImGui::Button(ICON_FA_BACKWARD "##SReverse")) { doAction(GUI_ACTION_SAMPLE_REVERSE); } if (ImGui::IsItemHovered()) { ImGui::SetTooltip("Reverse"); } - ImGui::SameLine(); + sameLineMaybe(); if (ImGui::Button(ICON_FA_SORT_AMOUNT_ASC "##SInvert")) { doAction(GUI_ACTION_SAMPLE_INVERT); } if (ImGui::IsItemHovered()) { ImGui::SetTooltip("Invert"); } - ImGui::SameLine(); + sameLineMaybe(); if (ImGui::Button(ICON_FA_LEVEL_DOWN "##SSign")) { doAction(GUI_ACTION_SAMPLE_SIGN); } if (ImGui::IsItemHovered()) { ImGui::SetTooltip("Signed/unsigned exchange"); } - ImGui::SameLine(); + sameLineMaybe(); ImGui::Button(ICON_FA_INDUSTRY "##SFilter"); if (ImGui::IsItemHovered()) { ImGui::SetTooltip("Apply filter"); @@ -1062,21 +1095,21 @@ void FurnaceGUI::drawSampleEdit() { ImGui::EndDisabled(); ImGui::SameLine(); ImGui::Dummy(ImVec2(4.0*dpiScale,dpiScale)); - ImGui::SameLine(); + sameLineMaybe(); if (ImGui::Button(ICON_FA_PLAY "##PreviewSample")) { e->previewSample(curSample); } if (ImGui::IsItemHovered()) { ImGui::SetTooltip("Preview sample"); } - ImGui::SameLine(); + sameLineMaybe(); if (ImGui::Button(ICON_FA_STOP "##StopSample")) { e->stopSamplePreview(); } if (ImGui::IsItemHovered()) { ImGui::SetTooltip("Stop sample preview"); } - ImGui::SameLine(); + sameLineMaybe(); if (ImGui::Button(ICON_FA_UPLOAD "##MakeIns")) { doAction(GUI_ACTION_SAMPLE_MAKE_INS); } @@ -1084,7 +1117,7 @@ void FurnaceGUI::drawSampleEdit() { ImGui::SetTooltip("Create instrument from sample"); } - ImGui::SameLine(); + sameLineMaybe(ImGui::CalcTextSize("Zoom").x+150.0f*dpiScale+ImGui::CalcTextSize("100%").x); double zoomPercent=100.0/sampleZoom; bool checkZoomLimit=false; ImGui::Text("Zoom"); @@ -1702,7 +1735,16 @@ void FurnaceGUI::drawSampleEdit() { ImGui::TableNextColumn(); ImGui::TextUnformatted(statusBar2.c_str()); ImGui::TableNextColumn(); - ImGui::TextUnformatted(statusBar3.c_str()); + if (!warnLength.empty()) { + ImGui::PushStyleColor(ImGuiCol_Text,uiColors[GUI_COLOR_WARNING]); + ImGui::TextUnformatted(statusBar3.c_str()); + ImGui::PopStyleColor(); + if (ImGui::IsItemHovered()) { + ImGui::SetTooltip("%s",warnLength.c_str()); + } + } else { + ImGui::TextUnformatted(statusBar3.c_str()); + } ImGui::EndTable(); } diff --git a/src/gui/settings.cpp b/src/gui/settings.cpp index 33a6c5c6e..3da603169 100644 --- a/src/gui/settings.cpp +++ b/src/gui/settings.cpp @@ -508,6 +508,14 @@ void FurnaceGUI::drawSettings() { settings.alwaysPlayIntro=3; } + ImGui::Text("When creating new song:"); + if (ImGui::RadioButton("Display system preset selector##NSB0",settings.newSongBehavior==0)) { + settings.newSongBehavior=0; + } + if (ImGui::RadioButton("Start with initial system##NSB1",settings.newSongBehavior==1)) { + settings.newSongBehavior=1; + } + ImGui::Separator(); if (CWSliderFloat("Double-click time (seconds)",&settings.doubleClickTime,0.02,1.0,"%.2f")) { @@ -2757,6 +2765,7 @@ void FurnaceGUI::syncSettings() { settings.renderClearPos=e->getConfInt("renderClearPos",0); settings.insertBehavior=e->getConfInt("insertBehavior",1); settings.pullDeleteRow=e->getConfInt("pullDeleteRow",1); + settings.newSongBehavior=e->getConfInt("newSongBehavior",0); clampSetting(settings.mainFontSize,2,96); clampSetting(settings.patFontSize,2,96); @@ -2882,6 +2891,7 @@ void FurnaceGUI::syncSettings() { clampSetting(settings.renderClearPos,0,1); clampSetting(settings.insertBehavior,0,1); clampSetting(settings.pullDeleteRow,0,1); + clampSetting(settings.newSongBehavior,0,1); if (settings.exportLoops<0.0) settings.exportLoops=0.0; if (settings.exportFadeOut<0.0) settings.exportFadeOut=0.0; @@ -3103,6 +3113,7 @@ void FurnaceGUI::commitSettings() { e->setConf("renderClearPos",settings.renderClearPos); e->setConf("insertBehavior",settings.insertBehavior); e->setConf("pullDeleteRow",settings.pullDeleteRow); + e->setConf("newSongBehavior",settings.newSongBehavior); // colors for (int i=0; i