From 061b8e7aa18e9ec58885811dc7573dd9c9ba5fdf Mon Sep 17 00:00:00 2001 From: tildearrow Date: Sun, 15 Oct 2023 17:02:25 -0500 Subject: [PATCH] GUI: add a hint when an ins cannot be previewed --- src/engine/engine.cpp | 7 ++++--- src/engine/engine.h | 3 ++- src/gui/doAction.cpp | 2 ++ src/gui/editControls.cpp | 4 ++++ src/gui/gui.cpp | 5 ++++- src/gui/gui.h | 1 + src/gui/insEdit.cpp | 13 +++++++++++++ src/gui/piano.cpp | 3 ++- 8 files changed, 32 insertions(+), 6 deletions(-) diff --git a/src/engine/engine.cpp b/src/engine/engine.cpp index 1467377c1..84c6a6de6 100644 --- a/src/engine/engine.cpp +++ b/src/engine/engine.cpp @@ -3106,7 +3106,7 @@ void DivEngine::noteOff(int chan) { BUSY_END; } -void DivEngine::autoNoteOn(int ch, int ins, int note, int vol) { +bool DivEngine::autoNoteOn(int ch, int ins, int note, int vol) { bool isViable[DIV_MAX_CHANS]; bool canPlayAnyway=false; bool notInViableChannel=false; @@ -3142,7 +3142,7 @@ void DivEngine::autoNoteOn(int ch, int ins, int note, int vol) { } } - if (!canPlayAnyway) return; + if (!canPlayAnyway) return false; // 2. find a free channel do { @@ -3150,7 +3150,7 @@ void DivEngine::autoNoteOn(int ch, int ins, int note, int vol) { chan[finalChan].midiNote=note; chan[finalChan].midiAge=midiAgeCounter++; pendingNotes.push_back(DivNoteEvent(finalChan,ins,note,vol,true)); - return; + return true; } if (++finalChan>=chans) { finalChan=0; @@ -3171,6 +3171,7 @@ void DivEngine::autoNoteOn(int ch, int ins, int note, int vol) { chan[candidate].midiNote=note; chan[candidate].midiAge=midiAgeCounter++; pendingNotes.push_back(DivNoteEvent(candidate,ins,note,vol,true)); + return true; } void DivEngine::autoNoteOff(int ch, int note, int vol) { diff --git a/src/engine/engine.h b/src/engine/engine.h index 164379948..33ed54206 100644 --- a/src/engine/engine.h +++ b/src/engine/engine.h @@ -985,7 +985,8 @@ class DivEngine { // stop note void noteOff(int chan); - void autoNoteOn(int chan, int ins, int note, int vol=-1); + // returns whether it could + bool autoNoteOn(int chan, int ins, int note, int vol=-1); void autoNoteOff(int chan, int note, int vol=-1); void autoNoteOffAll(); diff --git a/src/gui/doAction.cpp b/src/gui/doAction.cpp index 24c491ffe..69b24947d 100644 --- a/src/gui/doAction.cpp +++ b/src/gui/doAction.cpp @@ -118,6 +118,7 @@ void FurnaceGUI::doAction(int what) { curOctave=7; } else { e->autoNoteOffAll(); + failedNoteOn=false; } break; case GUI_ACTION_OCTAVE_DOWN: @@ -125,6 +126,7 @@ void FurnaceGUI::doAction(int what) { curOctave=-5; } else { e->autoNoteOffAll(); + failedNoteOn=false; } break; case GUI_ACTION_INS_UP: diff --git a/src/gui/editControls.cpp b/src/gui/editControls.cpp index b26e773f0..7189b6e00 100644 --- a/src/gui/editControls.cpp +++ b/src/gui/editControls.cpp @@ -683,6 +683,7 @@ void FurnaceGUI::drawEditControls() { if (curOctave>7) curOctave=7; if (curOctave<-5) curOctave=-5; e->autoNoteOffAll(); + failedNoteOn=false; if (settings.insFocusesPattern && !ImGui::IsItemActive() && patternOpen) { nextWindow=GUI_WINDOW_PATTERN; @@ -830,6 +831,7 @@ void FurnaceGUI::drawEditControls() { if (curOctave>7) curOctave=7; if (curOctave<-5) curOctave=-5; e->autoNoteOffAll(); + failedNoteOn=false; if (settings.insFocusesPattern && !ImGui::IsItemActive() && patternOpen) { nextWindow=GUI_WINDOW_PATTERN; @@ -934,6 +936,7 @@ void FurnaceGUI::drawEditControls() { if (curOctave>7) curOctave=7; if (curOctave<-5) curOctave=-5; e->autoNoteOffAll(); + failedNoteOn=false; if (settings.insFocusesPattern && !ImGui::IsItemActive() && patternOpen) { nextWindow=GUI_WINDOW_PATTERN; @@ -1087,6 +1090,7 @@ void FurnaceGUI::drawEditControls() { if (curOctave>7) curOctave=7; if (curOctave<-5) curOctave=-5; e->autoNoteOffAll(); + failedNoteOn=false; if (settings.insFocusesPattern && !ImGui::IsItemActive() && patternOpen) { nextWindow=GUI_WINDOW_PATTERN; diff --git a/src/gui/gui.cpp b/src/gui/gui.cpp index 7f28ac0d7..e670f2463 100644 --- a/src/gui/gui.cpp +++ b/src/gui/gui.cpp @@ -1146,7 +1146,7 @@ void FurnaceGUI::stop() { void FurnaceGUI::previewNote(int refChan, int note, bool autoNote) { e->setMidiBaseChan(refChan); e->synchronized([this,note]() { - e->autoNoteOn(-1,curIns,note); + if (!e->autoNoteOn(-1,curIns,note)) failedNoteOn=true; }); } @@ -1164,6 +1164,7 @@ void FurnaceGUI::stopPreviewNote(SDL_Scancode scancode, bool autoNote) { e->synchronized([this,num]() { e->autoNoteOff(-1,num); + failedNoteOn=false; }); } } @@ -6216,6 +6217,7 @@ bool FurnaceGUI::loop() { switch (lastWindowCat) { case 0: e->autoNoteOffAll(); + failedNoteOn=false; break; case 1: e->stopWavePreview(); @@ -7304,6 +7306,7 @@ FurnaceGUI::FurnaceGUI(): nextWindow(GUI_WINDOW_NOTHING), curWindowLast(GUI_WINDOW_NOTHING), curWindowThreadSafe(GUI_WINDOW_NOTHING), + failedNoteOn(false), lastPatternWidth(0.0f), longThreshold(0.48f), buttonLongThreshold(0.20f), diff --git a/src/gui/gui.h b/src/gui/gui.h index a7b1f3ac1..e7e5d1177 100644 --- a/src/gui/gui.h +++ b/src/gui/gui.h @@ -1854,6 +1854,7 @@ class FurnaceGUI { unsigned char lastAssetType; FurnaceGUIWindows curWindow, nextWindow, curWindowLast; std::atomic curWindowThreadSafe; + std::atomic failedNoteOn; float peak[DIV_MAX_OUTPUTS]; float patChanX[DIV_MAX_CHANS+1]; float patChanSlideY[DIV_MAX_CHANS+1]; diff --git a/src/gui/insEdit.cpp b/src/gui/insEdit.cpp index f6c6310eb..1a18a0e2e 100644 --- a/src/gui/insEdit.cpp +++ b/src/gui/insEdit.cpp @@ -2886,6 +2886,14 @@ void FurnaceGUI::drawInsEdit() { ins->type=(DivInstrumentType)insType; } */ + bool warnType=true; + for (DivInstrumentType i: e->getPossibleInsTypes()) { + if (i==insType) { + warnType=false; + } + } + + pushWarningColor(warnType,warnType && failedNoteOn); if (ImGui::BeginCombo("##Type",insTypes[insType][0])) { std::vector insTypeList; if (settings.displayAllInsTypes) { @@ -2943,7 +2951,12 @@ void FurnaceGUI::drawInsEdit() { } } ImGui::EndCombo(); + } else if (warnType) { + if (ImGui::IsItemHovered()) { + ImGui::SetTooltip("none of the currently present chips are able to play this instrument type!"); + } } + popWarningColor(); ImGui::EndTable(); } diff --git a/src/gui/piano.cpp b/src/gui/piano.cpp index 1b7fb067b..a167b1b89 100644 --- a/src/gui/piano.cpp +++ b/src/gui/piano.cpp @@ -398,6 +398,7 @@ void FurnaceGUI::drawPiano() { default: e->synchronized([this,note]() { e->autoNoteOff(-1,note); + failedNoteOn=false; }); break; } @@ -423,7 +424,7 @@ void FurnaceGUI::drawPiano() { alterSampleMap(1,note); } else { e->synchronized([this,note]() { - e->autoNoteOn(-1,curIns,note); + if (!e->autoNoteOn(-1,curIns,note)) failedNoteOn=true; }); if (edit && curWindow!=GUI_WINDOW_INS_LIST && curWindow!=GUI_WINDOW_INS_EDIT) noteInput(note,0); }