Merge branch 'master' into ZSMv1

This commit is contained in:
ZeroByteOrg 2022-06-06 09:44:57 -05:00
commit 378f6a957b
3651 changed files with 495554 additions and 653 deletions

View file

@ -1667,6 +1667,8 @@ int FurnaceGUI::load(String path) {
curNibble=false;
orderNibble=false;
orderCursor=-1;
curOrder=0;
oldRow=0;
samplePos=0;
updateSampleTex=true;
selStart=SelectionPoint();
@ -1676,6 +1678,7 @@ int FurnaceGUI::load(String path) {
undoHist.clear();
redoHist.clear();
updateWindowTitle();
updateScroll(0);
if (!e->getWarnings().empty()) {
showWarning(e->getWarnings(),GUI_WARN_GENERIC);
}
@ -1683,7 +1686,7 @@ int FurnaceGUI::load(String path) {
}
void FurnaceGUI::exportAudio(String path, DivAudioExportModes mode) {
e->saveAudio(path.c_str(),exportLoops+1,mode);
e->saveAudio(path.c_str(),exportLoops+1,mode,exportFadeOut);
displayExporting=true;
}
@ -1906,6 +1909,12 @@ void FurnaceGUI::processDrags(int dragX, int dragY) {
void FurnaceGUI::editOptions(bool topMenu) {
char id[4096];
editOptsVisible=true;
if (topMenu) {
ImGui::Text("...");
ImGui::Separator();
}
if (ImGui::MenuItem("cut",BIND_FOR(GUI_ACTION_PAT_CUT))) doCopy(true);
if (ImGui::MenuItem("copy",BIND_FOR(GUI_ACTION_PAT_COPY))) doCopy(false);
if (ImGui::MenuItem("paste",BIND_FOR(GUI_ACTION_PAT_PASTE))) doPaste();
@ -2208,6 +2217,17 @@ void FurnaceGUI::editOptions(bool topMenu) {
if (ImGui::MenuItem("expand",BIND_FOR(GUI_ACTION_PAT_EXPAND_ROWS))) doExpand(2);
if (topMenu) {
ImGui::Separator();
if (ImGui::MenuItem("find/replace",BIND_FOR(GUI_ACTION_WINDOW_FIND),findOpen)) {
if (findOpen) {
findOpen=false;
} else {
nextWindow=GUI_WINDOW_FIND;
}
}
}
/*if (topMenu) {
ImGui::Separator();
ImGui::MenuItem("collapse pattern",BIND_FOR(GUI_ACTION_PAT_COLLAPSE_PAT));
ImGui::MenuItem("expand pattern",BIND_FOR(GUI_ACTION_PAT_EXPAND_PAT));
@ -2215,7 +2235,7 @@ void FurnaceGUI::editOptions(bool topMenu) {
ImGui::Separator();
ImGui::MenuItem("collapse song",BIND_FOR(GUI_ACTION_PAT_COLLAPSE_SONG));
ImGui::MenuItem("expand song",BIND_FOR(GUI_ACTION_PAT_EXPAND_SONG));
}
}*/
}
void FurnaceGUI::toggleMobileUI(bool enable, bool force) {
@ -2253,7 +2273,20 @@ int FurnaceGUI::processEvent(SDL_Event* ev) {
int key=noteKeys.at(ev->key.keysym.scancode);
int num=12*curOctave+key;
if (key!=100 && key!=101 && key!=102) {
e->previewSample(curSample,num);
int pStart=-1;
int pEnd=-1;
if (curWindow==GUI_WINDOW_SAMPLE_EDIT) {
if (sampleSelStart!=sampleSelEnd) {
pStart=sampleSelStart;
pEnd=sampleSelEnd;
if (pStart>pEnd) {
pStart^=pEnd;
pEnd^=pStart;
pStart^=pEnd;
}
}
}
e->previewSample(curSample,num,pStart,pEnd);
samplePreviewOn=true;
samplePreviewKey=ev->key.keysym.scancode;
samplePreviewNote=num;
@ -2378,6 +2411,10 @@ void FurnaceGUI::processPoint(SDL_Event& ev) {
point->x=ev.tfinger.x*scrW*dpiScale;
point->y=ev.tfinger.y*scrH*dpiScale;
point->z=ev.tfinger.pressure;
if (point->id==0) {
ImGui::GetIO().AddMousePosEvent(point->x,point->y);
}
}
break;
}
@ -2393,6 +2430,11 @@ void FurnaceGUI::processPoint(SDL_Event& ev) {
TouchPoint newPoint(ev.tfinger.fingerId,ev.tfinger.x*scrW*dpiScale,ev.tfinger.y*scrH*dpiScale,ev.tfinger.pressure);
activePoints.push_back(newPoint);
pressedPoints.push_back(newPoint);
if (newPoint.id==0) {
ImGui::GetIO().AddMousePosEvent(newPoint.x,newPoint.y);
ImGui::GetIO().AddMouseButtonEvent(ImGuiMouseButton_Left,true);
}
break;
}
case SDL_FINGERUP: {
@ -2401,6 +2443,11 @@ void FurnaceGUI::processPoint(SDL_Event& ev) {
if (point.id==ev.tfinger.fingerId) {
releasedPoints.push_back(point);
activePoints.erase(activePoints.begin()+i);
if (point.id==0) {
ImGui::GetIO().AddMouseButtonEvent(ImGuiMouseButton_Left,false);
ImGui::GetIO().AddMousePosEvent(-FLT_MAX,-FLT_MAX);
}
break;
}
}
@ -2540,7 +2587,23 @@ bool FurnaceGUI::loop() {
break;
case SDL_DROPFILE:
if (ev.drop.file!=NULL) {
if (modified) {
std::vector<DivInstrument*> instruments=e->instrumentFromFile(ev.drop.file);
if (!instruments.empty()) {
if (!e->getWarnings().empty()) {
showWarning(e->getWarnings(),GUI_WARN_GENERIC);
}
for (DivInstrument* i: instruments) {
e->addInstrumentPtr(i);
}
nextWindow=GUI_WINDOW_INS_LIST;
MARK_MODIFIED;
} else if (e->addWaveFromFile(ev.drop.file,false)) {
nextWindow=GUI_WINDOW_WAVE_LIST;
MARK_MODIFIED;
} else if (e->addSampleFromFile(ev.drop.file)!=-1) {
nextWindow=GUI_WINDOW_SAMPLE_LIST;
MARK_MODIFIED;
} else if (modified) {
nextFile=ev.drop.file;
showWarning("Unsaved changes! Save changes before opening file?",GUI_WARN_OPEN_DROP);
} else {
@ -2791,6 +2854,9 @@ bool FurnaceGUI::loop() {
if (ImGui::InputInt("Loops",&exportLoops,1,2)) {
if (exportLoops<0) exportLoops=0;
}
if (ImGui::InputDouble("Fade out (seconds)",&exportFadeOut,1.0,2.0,"%.1f")) {
if (exportFadeOut<0.0) exportFadeOut=0.0;
}
ImGui::EndMenu();
}
if (ImGui::BeginMenu("export VGM...")) {
@ -2947,9 +3013,13 @@ bool FurnaceGUI::loop() {
if (ImGui::BeginMenu("window")) {
if (ImGui::MenuItem("song information",BIND_FOR(GUI_ACTION_WINDOW_SONG_INFO),songInfoOpen)) songInfoOpen=!songInfoOpen;
if (ImGui::MenuItem("subsongs",BIND_FOR(GUI_ACTION_WINDOW_SUBSONGS),subSongsOpen)) subSongsOpen=!subSongsOpen;
if (ImGui::MenuItem("instruments",BIND_FOR(GUI_ACTION_WINDOW_INS_LIST),insListOpen)) insListOpen=!insListOpen;
if (ImGui::MenuItem("wavetables",BIND_FOR(GUI_ACTION_WINDOW_WAVE_LIST),waveListOpen)) waveListOpen=!waveListOpen;
if (ImGui::MenuItem("samples",BIND_FOR(GUI_ACTION_WINDOW_SAMPLE_LIST),sampleListOpen)) sampleListOpen=!sampleListOpen;
if (settings.unifiedDataView) {
if (ImGui::MenuItem("assets",BIND_FOR(GUI_ACTION_WINDOW_INS_LIST),insListOpen)) insListOpen=!insListOpen;
} else {
if (ImGui::MenuItem("instruments",BIND_FOR(GUI_ACTION_WINDOW_INS_LIST),insListOpen)) insListOpen=!insListOpen;
if (ImGui::MenuItem("wavetables",BIND_FOR(GUI_ACTION_WINDOW_WAVE_LIST),waveListOpen)) waveListOpen=!waveListOpen;
if (ImGui::MenuItem("samples",BIND_FOR(GUI_ACTION_WINDOW_SAMPLE_LIST),sampleListOpen)) sampleListOpen=!sampleListOpen;
}
if (ImGui::MenuItem("orders",BIND_FOR(GUI_ACTION_WINDOW_ORDERS),ordersOpen)) ordersOpen=!ordersOpen;
if (ImGui::MenuItem("pattern",BIND_FOR(GUI_ACTION_WINDOW_PATTERN),patternOpen)) patternOpen=!patternOpen;
if (ImGui::MenuItem("mixer",BIND_FOR(GUI_ACTION_WINDOW_MIXER),mixerOpen)) mixerOpen=!mixerOpen;
@ -3061,6 +3131,7 @@ bool FurnaceGUI::loop() {
ImGui::DockSpaceOverViewport(NULL,lockLayout?(ImGuiDockNodeFlags_NoWindowMenuButton|ImGuiDockNodeFlags_NoMove|ImGuiDockNodeFlags_NoResize|ImGuiDockNodeFlags_NoCloseButton|ImGuiDockNodeFlags_NoDocking|ImGuiDockNodeFlags_NoDockingSplitMe|ImGuiDockNodeFlags_NoDockingSplitOther):0);
drawSubSongs();
drawFindReplace();
drawPattern();
drawEditControls();
drawSongInfo();
@ -3319,8 +3390,16 @@ bool FurnaceGUI::loop() {
if (!e->getWarnings().empty()) {
showWarning(e->getWarnings(),GUI_WARN_GENERIC);
}
for (DivInstrument* i: instruments) {
e->addInstrumentPtr(i);
if (instruments.size()>1) { // ask which instruments to load
for (DivInstrument* i: instruments) {
pendingIns.push_back(std::make_pair(i,false));
}
displayPendingIns=true;
pendingInsSingle=false;
} else { // load the only instrument
for (DivInstrument* i: instruments) {
e->addInstrumentPtr(i);
}
}
} else {
showError("cannot load instrument! ("+e->getLastError()+")");
@ -3333,13 +3412,21 @@ bool FurnaceGUI::loop() {
if (!e->getWarnings().empty()) {
showWarning(e->getWarnings(),GUI_WARN_GENERIC);
}
if (curIns>=0 && curIns<(int)e->song.ins.size()) {
*e->song.ins[curIns]=*instruments[0];
} else {
showError("...but you haven't selected an instrument!");
}
for (DivInstrument* i: instruments) {
delete i;
if (instruments.size()>1) { // ask which instrument
for (DivInstrument* i: instruments) {
pendingIns.push_back(std::make_pair(i,false));
}
displayPendingIns=true;
pendingInsSingle=true;
} else { // replace with the only instrument
if (curIns>=0 && curIns<(int)e->song.ins.size()) {
*e->song.ins[curIns]=*instruments[0];
} else {
showError("...but you haven't selected an instrument!");
}
for (DivInstrument* i: instruments) {
delete i;
}
}
} else {
showError("cannot load instrument! ("+e->getLastError()+")");
@ -3451,6 +3538,11 @@ bool FurnaceGUI::loop() {
ImGui::OpenPopup("Error");
}
if (displayPendingIns) {
displayPendingIns=false;
ImGui::OpenPopup("Select Instrument");
}
if (displayExporting) {
displayExporting=false;
ImGui::OpenPopup("Rendering...");
@ -3801,6 +3893,86 @@ bool FurnaceGUI::loop() {
ImGui::EndPopup();
}
// TODO:
// - multiple selection
// - replace instrument
if (ImGui::BeginPopupModal("Select Instrument",NULL,ImGuiWindowFlags_AlwaysAutoResize)) {
bool quitPlease=false;
if (pendingInsSingle) {
ImGui::Text("this is an instrument bank! select which one to use:");
} else {
ImGui::Text("this is an instrument bank! select which ones to load:");
ImGui::SameLine();
if (ImGui::Button("All")) {
for (std::pair<DivInstrument*,bool>& i: pendingIns) {
i.second=true;
}
}
ImGui::SameLine();
if (ImGui::Button("None")) {
for (std::pair<DivInstrument*,bool>& i: pendingIns) {
i.second=false;
}
}
}
bool anySelected=false;
float sizeY=ImGui::GetFrameHeightWithSpacing()*pendingIns.size();
if (sizeY>(scrH-180.0)*dpiScale) {
sizeY=(scrH-180.0)*dpiScale;
if (sizeY<60.0*dpiScale) sizeY=60.0*dpiScale;
}
if (ImGui::BeginTable("PendingInsList",1,ImGuiTableFlags_ScrollY,ImVec2(0.0f,sizeY))) {
for (size_t i=0; i<pendingIns.size(); i++) {
ImGui::TableNextRow();
ImGui::TableNextColumn();
String id=fmt::sprintf("%d: %s",(int)i,pendingIns[i].first->name);
if (pendingInsSingle) {
if (ImGui::Selectable(id.c_str())) {
pendingIns[i].second=true;
quitPlease=true;
}
} else {
ImGui::Checkbox(id.c_str(),&pendingIns[i].second);
}
if (pendingIns[i].second) anySelected=true;
}
ImGui::EndTable();
}
if (!pendingInsSingle) {
ImGui::BeginDisabled(!anySelected);
if (ImGui::Button("OK")) {
quitPlease=true;
}
ImGui::EndDisabled();
ImGui::SameLine();
}
if (ImGui::Button("Cancel")) {
for (std::pair<DivInstrument*,bool>& i: pendingIns) {
i.second=false;
}
quitPlease=true;
}
if (quitPlease) {
ImGui::CloseCurrentPopup();
for (std::pair<DivInstrument*,bool>& i: pendingIns) {
if (!i.second || pendingInsSingle) {
if (i.second) {
if (curIns>=0 && curIns<(int)e->song.ins.size()) {
*e->song.ins[curIns]=*i.first;
} else {
showError("...but you haven't selected an instrument!");
}
}
delete i.first;
} else {
e->addInstrumentPtr(i.first);
}
}
pendingIns.clear();
}
ImGui::EndPopup();
}
layoutTimeEnd=SDL_GetPerformanceCounter();
// backup trigger
@ -3933,10 +4105,15 @@ bool FurnaceGUI::init() {
edit=e->getConfBool("edit",false);
followOrders=e->getConfBool("followOrders",true);
followPattern=e->getConfBool("followPattern",true);
noteInputPoly=e->getConfBool("noteInputPoly",true);
orderEditMode=e->getConfInt("orderEditMode",0);
if (orderEditMode<0) orderEditMode=0;
if (orderEditMode>3) orderEditMode=3;
oscZoom=e->getConfFloat("oscZoom",0.5f);
oscZoomSlider=e->getConfBool("oscZoomSlider",false);
oscWindowSize=e->getConfFloat("oscWindowSize",20.0f);
pianoOctaves=e->getConfInt("pianoOctaves",pianoOctaves);
pianoOctavesEdit=e->getConfInt("pianoOctavesEdit",pianoOctavesEdit);
pianoOptions=e->getConfBool("pianoOptions",pianoOptions);
@ -3955,6 +4132,8 @@ bool FurnaceGUI::init() {
initSystemPresets();
e->setAutoNotePoly(noteInputPoly);
#if !(defined(__APPLE__) || defined(_WIN32))
unsigned char* furIcon=getFurnaceIcon();
SDL_Surface* icon=SDL_CreateRGBSurfaceFrom(furIcon,256,256,32,256*4,0xff,0xff00,0xff0000,0xff000000);
@ -3967,8 +4146,13 @@ bool FurnaceGUI::init() {
SDL_Rect displaySize;
#endif
SDL_SetHint("SDL_HINT_VIDEO_ALLOW_SCREENSAVER","1");
SDL_SetHint("SDL_HINT_ANDROID_SEPARATE_MOUSE_AND_TOUCH","1");
SDL_SetHint(SDL_HINT_VIDEO_ALLOW_SCREENSAVER,"1");
SDL_SetHint(SDL_HINT_MOUSE_TOUCH_EVENTS,"0");
SDL_SetHint(SDL_HINT_TOUCH_MOUSE_EVENTS,"0");
// don't disable compositing on KWin
#if SDL_VERSION_ATLEAST(2,0,22)
SDL_SetHint(SDL_HINT_X11_WINDOW_TYPE,"_NET_WM_WINDOW_TYPE_NORMAL");
#endif
SDL_Init(SDL_INIT_VIDEO);
@ -4144,6 +4328,12 @@ bool FurnaceGUI::finish() {
e->setConf("followOrders",followOrders);
e->setConf("followPattern",followPattern);
e->setConf("orderEditMode",orderEditMode);
e->setConf("noteInputPoly",noteInputPoly);
// commit oscilloscope state
e->setConf("oscZoom",oscZoom);
e->setConf("oscZoomSlider",oscZoomSlider);
e->setConf("oscWindowSize",oscWindowSize);
// commit piano state
e->setConf("pianoOctaves",pianoOctaves);
@ -4191,6 +4381,9 @@ FurnaceGUI::FurnaceGUI():
fullScreen(false),
preserveChanPos(false),
wantScrollList(false),
noteInputPoly(true),
displayPendingIns(false),
pendingInsSingle(false),
vgmExportVersion(0x171),
drawHalt(10),
zsmExportTickRate(60),
@ -4239,6 +4432,7 @@ FurnaceGUI::FurnaceGUI():
latchTarget(0),
wheelX(0),
wheelY(0),
exportFadeOut(5.0),
editControlsOpen(true),
ordersOpen(true),
insListOpen(true),
@ -4266,35 +4460,7 @@ FurnaceGUI::FurnaceGUI():
effectListOpen(false),
chanOscOpen(false),
subSongsOpen(true),
/*
editControlsDocked(false),
ordersDocked(false),
insListDocked(false),
songInfoDocked(false),
patternDocked(false),
insEditDocked(false),
waveListDocked(false),
waveEditDocked(false),
sampleListDocked(false),
sampleEditDocked(false),
aboutDocked(false),
settingsDocked(false),
mixerDocked(false),
debugDocked(false),
inspectorDocked(false),
oscDocked(false),
volMeterDocked(false),
statsDocked(false),
compatFlagsDocked(false),
pianoDocked(false),
notesDocked(false),
channelsDocked(false),
regViewDocked(false),
logDocked(false),
effectListDocked(false),
chanOscDocked(false),
subSongsDocked(false),
*/
findOpen(false),
selecting(false),
selectingFull(false),
curNibble(false),
@ -4432,6 +4598,7 @@ FurnaceGUI::FurnaceGUI():
openSampleFilterOpt(false),
oscTotal(0),
oscZoom(0.5f),
oscWindowSize(20.0f),
oscZoomSlider(false),
chanOscCols(3),
chanOscWindowSize(20.0f),