GUI: add a hint when an ins cannot be previewed

This commit is contained in:
tildearrow 2023-10-15 17:02:25 -05:00
parent 256140bc32
commit 061b8e7aa1
8 changed files with 32 additions and 6 deletions

View file

@ -3106,7 +3106,7 @@ void DivEngine::noteOff(int chan) {
BUSY_END; 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 isViable[DIV_MAX_CHANS];
bool canPlayAnyway=false; bool canPlayAnyway=false;
bool notInViableChannel=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 // 2. find a free channel
do { do {
@ -3150,7 +3150,7 @@ void DivEngine::autoNoteOn(int ch, int ins, int note, int vol) {
chan[finalChan].midiNote=note; chan[finalChan].midiNote=note;
chan[finalChan].midiAge=midiAgeCounter++; chan[finalChan].midiAge=midiAgeCounter++;
pendingNotes.push_back(DivNoteEvent(finalChan,ins,note,vol,true)); pendingNotes.push_back(DivNoteEvent(finalChan,ins,note,vol,true));
return; return true;
} }
if (++finalChan>=chans) { if (++finalChan>=chans) {
finalChan=0; finalChan=0;
@ -3171,6 +3171,7 @@ void DivEngine::autoNoteOn(int ch, int ins, int note, int vol) {
chan[candidate].midiNote=note; chan[candidate].midiNote=note;
chan[candidate].midiAge=midiAgeCounter++; chan[candidate].midiAge=midiAgeCounter++;
pendingNotes.push_back(DivNoteEvent(candidate,ins,note,vol,true)); pendingNotes.push_back(DivNoteEvent(candidate,ins,note,vol,true));
return true;
} }
void DivEngine::autoNoteOff(int ch, int note, int vol) { void DivEngine::autoNoteOff(int ch, int note, int vol) {

View file

@ -985,7 +985,8 @@ class DivEngine {
// stop note // stop note
void noteOff(int chan); 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 autoNoteOff(int chan, int note, int vol=-1);
void autoNoteOffAll(); void autoNoteOffAll();

View file

@ -118,6 +118,7 @@ void FurnaceGUI::doAction(int what) {
curOctave=7; curOctave=7;
} else { } else {
e->autoNoteOffAll(); e->autoNoteOffAll();
failedNoteOn=false;
} }
break; break;
case GUI_ACTION_OCTAVE_DOWN: case GUI_ACTION_OCTAVE_DOWN:
@ -125,6 +126,7 @@ void FurnaceGUI::doAction(int what) {
curOctave=-5; curOctave=-5;
} else { } else {
e->autoNoteOffAll(); e->autoNoteOffAll();
failedNoteOn=false;
} }
break; break;
case GUI_ACTION_INS_UP: case GUI_ACTION_INS_UP:

View file

@ -683,6 +683,7 @@ void FurnaceGUI::drawEditControls() {
if (curOctave>7) curOctave=7; if (curOctave>7) curOctave=7;
if (curOctave<-5) curOctave=-5; if (curOctave<-5) curOctave=-5;
e->autoNoteOffAll(); e->autoNoteOffAll();
failedNoteOn=false;
if (settings.insFocusesPattern && !ImGui::IsItemActive() && patternOpen) { if (settings.insFocusesPattern && !ImGui::IsItemActive() && patternOpen) {
nextWindow=GUI_WINDOW_PATTERN; nextWindow=GUI_WINDOW_PATTERN;
@ -830,6 +831,7 @@ void FurnaceGUI::drawEditControls() {
if (curOctave>7) curOctave=7; if (curOctave>7) curOctave=7;
if (curOctave<-5) curOctave=-5; if (curOctave<-5) curOctave=-5;
e->autoNoteOffAll(); e->autoNoteOffAll();
failedNoteOn=false;
if (settings.insFocusesPattern && !ImGui::IsItemActive() && patternOpen) { if (settings.insFocusesPattern && !ImGui::IsItemActive() && patternOpen) {
nextWindow=GUI_WINDOW_PATTERN; nextWindow=GUI_WINDOW_PATTERN;
@ -934,6 +936,7 @@ void FurnaceGUI::drawEditControls() {
if (curOctave>7) curOctave=7; if (curOctave>7) curOctave=7;
if (curOctave<-5) curOctave=-5; if (curOctave<-5) curOctave=-5;
e->autoNoteOffAll(); e->autoNoteOffAll();
failedNoteOn=false;
if (settings.insFocusesPattern && !ImGui::IsItemActive() && patternOpen) { if (settings.insFocusesPattern && !ImGui::IsItemActive() && patternOpen) {
nextWindow=GUI_WINDOW_PATTERN; nextWindow=GUI_WINDOW_PATTERN;
@ -1087,6 +1090,7 @@ void FurnaceGUI::drawEditControls() {
if (curOctave>7) curOctave=7; if (curOctave>7) curOctave=7;
if (curOctave<-5) curOctave=-5; if (curOctave<-5) curOctave=-5;
e->autoNoteOffAll(); e->autoNoteOffAll();
failedNoteOn=false;
if (settings.insFocusesPattern && !ImGui::IsItemActive() && patternOpen) { if (settings.insFocusesPattern && !ImGui::IsItemActive() && patternOpen) {
nextWindow=GUI_WINDOW_PATTERN; nextWindow=GUI_WINDOW_PATTERN;

View file

@ -1146,7 +1146,7 @@ void FurnaceGUI::stop() {
void FurnaceGUI::previewNote(int refChan, int note, bool autoNote) { void FurnaceGUI::previewNote(int refChan, int note, bool autoNote) {
e->setMidiBaseChan(refChan); e->setMidiBaseChan(refChan);
e->synchronized([this,note]() { 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->synchronized([this,num]() {
e->autoNoteOff(-1,num); e->autoNoteOff(-1,num);
failedNoteOn=false;
}); });
} }
} }
@ -6216,6 +6217,7 @@ bool FurnaceGUI::loop() {
switch (lastWindowCat) { switch (lastWindowCat) {
case 0: case 0:
e->autoNoteOffAll(); e->autoNoteOffAll();
failedNoteOn=false;
break; break;
case 1: case 1:
e->stopWavePreview(); e->stopWavePreview();
@ -7304,6 +7306,7 @@ FurnaceGUI::FurnaceGUI():
nextWindow(GUI_WINDOW_NOTHING), nextWindow(GUI_WINDOW_NOTHING),
curWindowLast(GUI_WINDOW_NOTHING), curWindowLast(GUI_WINDOW_NOTHING),
curWindowThreadSafe(GUI_WINDOW_NOTHING), curWindowThreadSafe(GUI_WINDOW_NOTHING),
failedNoteOn(false),
lastPatternWidth(0.0f), lastPatternWidth(0.0f),
longThreshold(0.48f), longThreshold(0.48f),
buttonLongThreshold(0.20f), buttonLongThreshold(0.20f),

View file

@ -1854,6 +1854,7 @@ class FurnaceGUI {
unsigned char lastAssetType; unsigned char lastAssetType;
FurnaceGUIWindows curWindow, nextWindow, curWindowLast; FurnaceGUIWindows curWindow, nextWindow, curWindowLast;
std::atomic<FurnaceGUIWindows> curWindowThreadSafe; std::atomic<FurnaceGUIWindows> curWindowThreadSafe;
std::atomic<bool> failedNoteOn;
float peak[DIV_MAX_OUTPUTS]; float peak[DIV_MAX_OUTPUTS];
float patChanX[DIV_MAX_CHANS+1]; float patChanX[DIV_MAX_CHANS+1];
float patChanSlideY[DIV_MAX_CHANS+1]; float patChanSlideY[DIV_MAX_CHANS+1];

View file

@ -2886,6 +2886,14 @@ void FurnaceGUI::drawInsEdit() {
ins->type=(DivInstrumentType)insType; 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])) { if (ImGui::BeginCombo("##Type",insTypes[insType][0])) {
std::vector<DivInstrumentType> insTypeList; std::vector<DivInstrumentType> insTypeList;
if (settings.displayAllInsTypes) { if (settings.displayAllInsTypes) {
@ -2943,7 +2951,12 @@ void FurnaceGUI::drawInsEdit() {
} }
} }
ImGui::EndCombo(); 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(); ImGui::EndTable();
} }

View file

@ -398,6 +398,7 @@ void FurnaceGUI::drawPiano() {
default: default:
e->synchronized([this,note]() { e->synchronized([this,note]() {
e->autoNoteOff(-1,note); e->autoNoteOff(-1,note);
failedNoteOn=false;
}); });
break; break;
} }
@ -423,7 +424,7 @@ void FurnaceGUI::drawPiano() {
alterSampleMap(1,note); alterSampleMap(1,note);
} else { } else {
e->synchronized([this,note]() { 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); if (edit && curWindow!=GUI_WINDOW_INS_LIST && curWindow!=GUI_WINDOW_INS_EDIT) noteInput(note,0);
} }