Merge branch 'master' into spectrum

This commit is contained in:
Eknous-P 2025-11-01 17:19:30 +04:00
commit 4f85dec801
23 changed files with 488 additions and 124 deletions

View file

@ -868,6 +868,39 @@ void FurnaceGUI::autoDetectSystem() {
}
}
void FurnaceGUI::setCurIns(int newIns) {
curIns=newIns;
memset(multiIns,-1,7*sizeof(int));
}
bool FurnaceGUI::setMultiIns(int newIns) {
// set primary instrument if not set (or if polyphony is mono)
if (curIns<0 || noteInputMode==GUI_NOTE_INPUT_MONO) {
setCurIns(newIns);
return true;
}
// don't allow using the primary instrument twice
if (curIns==newIns) return false;
for (int i=0; i<7; i++) {
// don't allow using an instrument more than once
if (multiIns[i]==newIns) return false;
// if slot is empty, assign instrument to it
if (multiIns[i]==-1) {
multiIns[i]=newIns;
return true;
}
}
// no more slots available
return false;
}
bool FurnaceGUI::isMultiInsActive() {
for (int i=0; i<7; i++) {
if (multiIns[i]>=0) return true;
}
return false;
}
void FurnaceGUI::updateROMExportAvail() {
memset(romExportAvail,0,sizeof(bool)*DIV_ROM_MAX);
romExportExists=false;
@ -1338,6 +1371,11 @@ void FurnaceGUI::previewNote(int refChan, int note, bool autoNote) {
e->setMidiBaseChan(refChan);
e->synchronized([this,note]() {
if (!e->autoNoteOn(-1,curIns,note)) failedNoteOn=true;
for (int mi=0; mi<7; mi++) {
if (multiIns[mi]!=-1) {
e->autoNoteOn(-1,multiIns[mi],note,-1,multiInsTranspose[mi]);
}
}
});
}
@ -1367,7 +1405,7 @@ void FurnaceGUI::noteInput(int num, int key, int vol, int chanOff) {
int tick=0;
int speed=0;
if (chanOff>0 && noteInputChord) {
if (chanOff>0 && noteInputMode==GUI_NOTE_INPUT_CHORD) {
ch=e->getViableChannel(ch,chanOff,curIns);
if ((!e->isPlaying() || !followPattern)) {
y-=editStep;
@ -1434,7 +1472,7 @@ void FurnaceGUI::noteInput(int num, int key, int vol, int chanOff) {
pat->newData[y][DIV_PAT_VOL]=-1;
}
}
if ((!e->isPlaying() || !followPattern) && (chanOff<1 || !noteInputChord)) {
if ((!e->isPlaying() || !followPattern) && (chanOff<1 || noteInputMode!=GUI_NOTE_INPUT_CHORD)) {
editAdvance();
}
makeUndo(GUI_UNDO_PATTERN_EDIT,UndoRegion(ord,ch,y,ord,ch,y));
@ -1474,7 +1512,7 @@ void FurnaceGUI::valueInput(int num, bool direct, int target) {
}
}
if (settings.absorbInsInput) {
curIns=pat->newData[y][target];
setCurIns(pat->newData[y][target]);
wavePreviewInit=true;
updateFMPreview=true;
}
@ -1854,10 +1892,8 @@ void FurnaceGUI::keyDown(SDL_Event& ev) {
}
void FurnaceGUI::keyUp(SDL_Event& ev) {
// this is very, very lazy...
if (--chordInputOffset<0) {
chordInputOffset=0;
}
// this is very, very lazy... but it works.
chordInputOffset=0;
}
bool dirExists(String s) {
@ -1982,7 +2018,7 @@ void FurnaceGUI::openFileDialog(FurnaceGUIFileDialogs type) {
if (curIns!=-2) {
prevIns=curIns;
}
curIns=-2;
setCurIns(-2);
}
}
for (DivInstrument* i: instruments) delete i;
@ -3865,6 +3901,7 @@ bool FurnaceGUI::loop() {
DECLARE_METRIC(effectList)
DECLARE_METRIC(userPresets)
DECLARE_METRIC(refPlayer)
DECLARE_METRIC(multiInsSetup)
DECLARE_METRIC(popup)
#ifdef IS_MOBILE
@ -4052,7 +4089,7 @@ bool FurnaceGUI::loop() {
instrumentCount=e->addInstrumentPtr(i);
}
if (instrumentCount>=0 && settings.selectAssetOnLoad) {
curIns=instrumentCount-1;
setCurIns(instrumentCount-1);
}
nextWindow=GUI_WINDOW_INS_LIST;
MARK_MODIFIED;
@ -4208,7 +4245,7 @@ bool FurnaceGUI::loop() {
doAction(action);
} else switch (msg.type&0xf0) {
case TA_MIDI_NOTE_OFF:
if (--chordInputOffset<0) chordInputOffset=0;
chordInputOffset=0;
break;
case TA_MIDI_NOTE_ON:
if (midiMap.valueInputStyle==0 || midiMap.valueInputStyle>3 || cursor.xFine==0) {
@ -4246,8 +4283,8 @@ bool FurnaceGUI::loop() {
break;
case TA_MIDI_PROGRAM:
if (midiMap.programChange && !(midiMap.directChannel && midiMap.directProgram)) {
curIns=msg.data[0];
if (curIns>=(int)e->song.ins.size()) curIns=e->song.ins.size()-1;
setCurIns(msg.data[0]);
if (curIns>=(int)e->song.ins.size()) setCurIns(e->song.ins.size()-1);
wavePreviewInit=true;
updateFMPreview=true;
}
@ -4489,6 +4526,7 @@ bool FurnaceGUI::loop() {
IMPORT_CLOSE(csPlayerOpen);
IMPORT_CLOSE(userPresetsOpen);
IMPORT_CLOSE(refPlayerOpen);
IMPORT_CLOSE(multiInsSetupOpen);
} else if (pendingLayoutImportStep==1) {
// let the UI settle
} else if (pendingLayoutImportStep==2) {
@ -4863,6 +4901,7 @@ bool FurnaceGUI::loop() {
if (ImGui::MenuItem(_("play/edit controls"),BIND_FOR(GUI_ACTION_WINDOW_EDIT_CONTROLS),editControlsOpen)) editControlsOpen=!editControlsOpen;
if (ImGui::MenuItem(_("piano/input pad"),BIND_FOR(GUI_ACTION_WINDOW_PIANO),pianoOpen)) pianoOpen=!pianoOpen;
if (ImGui::MenuItem(_("reference music player"),BIND_FOR(GUI_ACTION_WINDOW_REF_PLAYER),refPlayerOpen)) refPlayerOpen=!refPlayerOpen;
if (ImGui::MenuItem(_("multi-ins setup"),BIND_FOR(GUI_ACTION_WINDOW_MULTI_INS_SETUP),multiInsSetupOpen)) multiInsSetupOpen=!multiInsSetupOpen;
if (spoilerOpen) if (ImGui::MenuItem(_("spoiler"),NULL,spoilerOpen)) spoilerOpen=!spoilerOpen;
ImGui::EndMenu();
@ -5063,6 +5102,7 @@ bool FurnaceGUI::loop() {
MEASURE(effectList,drawEffectList());
MEASURE(userPresets,drawUserPresets());
MEASURE(refPlayer,drawRefPlayer());
MEASURE(multiInsSetup,drawMultiInsSetup());
MEASURE(patManager,drawPatManager());
} else {
@ -5111,6 +5151,7 @@ bool FurnaceGUI::loop() {
MEASURE(effectList,drawEffectList());
MEASURE(userPresets,drawUserPresets());
MEASURE(refPlayer,drawRefPlayer());
MEASURE(multiInsSetup,drawMultiInsSetup());
}
@ -5180,7 +5221,7 @@ bool FurnaceGUI::loop() {
}
}
} else {
curIns=prevIns;
setCurIns(prevIns);
wavePreviewInit=true;
updateFMPreview=true;
}
@ -5686,7 +5727,7 @@ bool FurnaceGUI::loop() {
MARK_MODIFIED;
}
if (instrumentCount>=0 && settings.selectAssetOnLoad) {
curIns=instrumentCount-1;
setCurIns(instrumentCount-1);
}
}
}
@ -6563,7 +6604,7 @@ bool FurnaceGUI::loop() {
e->lockEngine([this]() {
e->song.clearInstruments();
});
curIns=-1;
setCurIns(-1);
MARK_MODIFIED;
ImGui::CloseCurrentPopup();
}
@ -6768,7 +6809,7 @@ bool FurnaceGUI::loop() {
strncpy(temp,insTypes[i][0],1023);
if (ImGui::MenuItem(temp)) {
// create ins
curIns=e->addInstrument(-1,i);
setCurIns(e->addInstrument(-1,i));
if (curIns==-1) {
showError(_("too many instruments!"));
} else {
@ -7628,7 +7669,7 @@ bool FurnaceGUI::init() {
initSystemPresets();
e->setAutoNotePoly(noteInputPoly);
e->setAutoNotePoly(noteInputMode!=GUI_NOTE_INPUT_MONO);
SDL_SetHint(SDL_HINT_VIDEO_ALLOW_SCREENSAVER,"1");
#if SDL_VERSION_ATLEAST(2,0,17)
@ -8264,6 +8305,7 @@ void FurnaceGUI::syncState() {
spoilerOpen=e->getConfBool("spoilerOpen",false);
userPresetsOpen=e->getConfBool("userPresetsOpen",false);
refPlayerOpen=e->getConfBool("refPlayerOpen",false);
multiInsSetupOpen=e->getConfBool("multiInsSetupOpen",false);
insListDir=e->getConfBool("insListDir",false);
waveListDir=e->getConfBool("waveListDir",false);
@ -8298,8 +8340,10 @@ void FurnaceGUI::syncState() {
orderLock=e->getConfBool("orderLock",false);
followOrders=e->getConfBool("followOrders",true);
followPattern=e->getConfBool("followPattern",true);
noteInputPoly=e->getConfBool("noteInputPoly",true);
noteInputChord=e->getConfBool("noteInputChord",false);
noteInputMode=e->getConfInt("noteInputMode",GUI_NOTE_INPUT_POLY);
if (noteInputMode!=GUI_NOTE_INPUT_MONO && noteInputMode!=GUI_NOTE_INPUT_POLY && noteInputMode!=GUI_NOTE_INPUT_CHORD) {
noteInputMode=GUI_NOTE_INPUT_POLY;
}
filePlayerSync=e->getConfBool("filePlayerSync",true);
audioExportOptions.loops=e->getConfInt("exportLoops",0);
if (audioExportOptions.loops<0) audioExportOptions.loops=0;
@ -8329,6 +8373,7 @@ void FurnaceGUI::syncState() {
pianoOffsetEdit=e->getConfInt("pianoOffsetEdit",pianoOffsetEdit);
pianoView=e->getConfInt("pianoView",pianoView);
pianoInputPadMode=e->getConfInt("pianoInputPadMode",pianoInputPadMode);
pianoLabelsMode=e->getConfInt("pianoLabelsMode",pianoLabelsMode);
chanOscCols=e->getConfInt("chanOscCols",3);
chanOscAutoColsType=e->getConfInt("chanOscAutoColsType",0);
@ -8437,6 +8482,7 @@ void FurnaceGUI::commitState(DivConfig& conf) {
conf.set("spoilerOpen",spoilerOpen);
conf.set("userPresetsOpen",userPresetsOpen);
conf.set("refPlayerOpen",refPlayerOpen);
conf.set("multiInsSetupOpen",multiInsSetupOpen);
// commit dir state
conf.set("insListDir",insListDir);
@ -8467,8 +8513,7 @@ void FurnaceGUI::commitState(DivConfig& conf) {
conf.set("followOrders",followOrders);
conf.set("followPattern",followPattern);
conf.set("orderEditMode",orderEditMode);
conf.set("noteInputPoly",noteInputPoly);
conf.set("noteInputChord",noteInputChord);
conf.set("noteInputMode",(int)noteInputMode);
conf.set("filePlayerSync",filePlayerSync);
if (settings.persistFadeOut) {
conf.set("exportLoops",audioExportOptions.loops);
@ -8498,6 +8543,7 @@ void FurnaceGUI::commitState(DivConfig& conf) {
conf.set("pianoOffsetEdit",pianoOffsetEdit);
conf.set("pianoView",pianoView);
conf.set("pianoInputPadMode",pianoInputPadMode);
conf.set("pianoLabelsMode",pianoLabelsMode);
// commit per-chan osc state
conf.set("chanOscCols",chanOscCols);
@ -8677,8 +8723,7 @@ FurnaceGUI::FurnaceGUI():
preserveChanPos(false),
sysDupCloneChannels(true),
sysDupEnd(false),
noteInputPoly(true),
noteInputChord(false),
noteInputMode(GUI_NOTE_INPUT_POLY),
notifyWaveChange(false),
notifySampleChange(false),
recalcTimestamps(true),
@ -8827,6 +8872,7 @@ FurnaceGUI::FurnaceGUI():
curPaletteChoice(0),
curPaletteType(0),
soloTimeout(0.0f),
mobileMultiInsToggle(false),
purgeYear(2021),
purgeMonth(4),
purgeDay(4),
@ -8877,6 +8923,7 @@ FurnaceGUI::FurnaceGUI():
cvOpen(false),
userPresetsOpen(false),
refPlayerOpen(false),
multiInsSetupOpen(false),
cvNotSerious(false),
shortIntro(false),
insListDir(false),
@ -9178,6 +9225,7 @@ FurnaceGUI::FurnaceGUI():
pianoOffsetEdit(9),
pianoView(PIANO_LAYOUT_AUTOMATIC),
pianoInputPadMode(PIANO_INPUT_PAD_SPLIT_AUTO),
pianoLabelsMode(PIANO_LABELS_OCTAVE),
#else
pianoOctaves(7),
pianoOctavesEdit(4),
@ -9188,6 +9236,7 @@ FurnaceGUI::FurnaceGUI():
pianoOffsetEdit(6),
pianoView(PIANO_LAYOUT_STANDARD),
pianoInputPadMode(PIANO_INPUT_PAD_DISABLE),
pianoLabelsMode(PIANO_LABELS_OCTAVE),
#endif
hasACED(false),
waveGenBaseShape(0),
@ -9345,6 +9394,9 @@ FurnaceGUI::FurnaceGUI():
memset(romExportAvail,0,sizeof(bool)*DIV_ROM_MAX);
memset(multiIns,-1,7*sizeof(int));
memset(multiInsTranspose,0,7*sizeof(int));
strncpy(noteOffLabel,"OFF",32);
strncpy(noteRelLabel,"===",32);
strncpy(macroRelLabel,"REL",32);