GUI: threaded command stream export, part 1

no progress bar yet
This commit is contained in:
tildearrow 2025-04-08 04:59:00 -05:00
parent ad5fb97822
commit 05da08d6da
3 changed files with 99 additions and 30 deletions

View file

@ -207,17 +207,7 @@ void FurnaceGUI::drawCSPlayer() {
ImGui::SameLine(); ImGui::SameLine();
if (ImGui::Button(_("Burn Current Song"))) { if (ImGui::Button(_("Burn Current Song"))) {
e->killStream(); e->killStream();
SafeWriter* w=e->saveCommand(NULL,csExportDisablePass); exportCmdStream(true,"");
if (w!=NULL) {
if (!e->playStream(w->getFinalBuf(),w->size())) {
showError(e->getLastError());
w->finish();
delete w;
} else {
w->disown();
delete w;
}
}
} }
if (ImGui::IsItemClicked(ImGuiMouseButton_Right)) { if (ImGui::IsItemClicked(ImGuiMouseButton_Right)) {
ImGui::OpenPopup("CSOptions"); ImGui::OpenPopup("CSOptions");

View file

@ -2648,6 +2648,18 @@ void FurnaceGUI::exportAudio(String path, DivAudioExportModes mode) {
displayExporting=true; displayExporting=true;
} }
void FurnaceGUI::exportCmdStream(bool target, String path) {
csExportPath=path;
csExportTarget=target;
csExportDone=false;
csExportThread=new std::thread([this]() {
SafeWriter* w=e->saveCommand(&csProgress,csExportDisablePass);
csExportResult=w;
csExportDone=true;
});
displayExportingCS=true;
}
void FurnaceGUI::editStr(String* which) { void FurnaceGUI::editStr(String* which) {
editString=which; editString=which;
displayEditString=true; displayEditString=true;
@ -5694,24 +5706,7 @@ bool FurnaceGUI::loop() {
break; break;
} }
case GUI_FILE_EXPORT_CMDSTREAM: { case GUI_FILE_EXPORT_CMDSTREAM: {
SafeWriter* w=e->saveCommand(NULL,csExportDisablePass); exportCmdStream(false,copyOfName);
if (w!=NULL) {
FILE* f=ps_fopen(copyOfName.c_str(),"wb");
if (f!=NULL) {
fwrite(w->getFinalBuf(),1,w->size(),f);
fclose(f);
pushRecentSys(copyOfName.c_str());
} else {
showError(_("could not open file!"));
}
w->finish();
delete w;
if (!e->getWarnings().empty()) {
showWarning(e->getWarnings(),GUI_WARN_GENERIC);
}
} else {
showError(fmt::sprintf(_("could not write command stream! (%s)"),e->getLastError()));
}
break; break;
} }
case GUI_FILE_LOAD_MAIN_FONT: case GUI_FILE_LOAD_MAIN_FONT:
@ -5847,6 +5842,11 @@ bool FurnaceGUI::loop() {
ImGui::OpenPopup(_("ROM Export Progress")); ImGui::OpenPopup(_("ROM Export Progress"));
} }
if (displayExportingCS) {
displayExportingCS=false;
ImGui::OpenPopup(_("CmdStream Export Progress"));
}
if (displayNew) { if (displayNew) {
newSongQuery=""; newSongQuery="";
newSongFirstFrame=true; newSongFirstFrame=true;
@ -6045,6 +6045,74 @@ bool FurnaceGUI::loop() {
ImGui::EndPopup(); ImGui::EndPopup();
} }
centerNextWindow(_("CmdStream Export Progress"),canvasW,canvasH);
ImGui::SetNextWindowSizeConstraints(romExportMinSize,romExportMaxSize);
if (ImGui::BeginPopupModal(_("CmdStream Export Progress"),NULL)) {
if (csExportThread==NULL) {
ImGui::TextWrapped("%s",_("it appears your Furnace has too many bugs in it. any song you can export?"));
ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x);
if (ImGui::Button(_("Talk With Devs"),ImVec2(ImGui::GetContentRegionAvail().x/3.0f,0.0f))) {
ImGui::CloseCurrentPopup();
}
ImGui::SameLine();
if (ImGui::Button(_("Ask on Bug Report"),ImVec2(ImGui::GetContentRegionAvail().x/3.0f,0.0f))) {
ImGui::CloseCurrentPopup();
}
ImGui::SameLine();
if (ImGui::Button(_("View Issues"),ImVec2(ImGui::GetContentRegionAvail().x/3.0f,0.0f))) {
ImGui::CloseCurrentPopup();
}
} else {
WAKE_UP;
ImGui::Text("Exporting...");
// check whether we're done
if (csExportDone) {
csExportThread->join();
delete csExportThread;
csExportThread=NULL;
if (csExportTarget) { // command stream player
if (csExportResult!=NULL) {
if (!e->playStream(csExportResult->getFinalBuf(),csExportResult->size())) {
showError(e->getLastError());
csExportResult->finish();
delete csExportResult;
} else {
csExportResult->disown();
delete csExportResult;
}
} else {
showError(_("oh no! it broke!"));
}
csExportResult=NULL;
} else { // command stream export
if (csExportResult!=NULL) {
FILE* f=ps_fopen(csExportPath.c_str(),"wb");
if (f!=NULL) {
fwrite(csExportResult->getFinalBuf(),1,csExportResult->size(),f);
fclose(f);
pushRecentSys(csExportPath.c_str());
} else {
showError(_("could not open file!"));
}
csExportResult->finish();
delete csExportResult;
if (!e->getWarnings().empty()) {
showWarning(e->getWarnings(),GUI_WARN_GENERIC);
}
} else {
showError(fmt::sprintf(_("could not write command stream! (%s)"),e->getLastError()));
}
csExportResult=NULL;
}
ImGui::CloseCurrentPopup();
}
}
ImGui::EndPopup();
}
drawTutorial(); drawTutorial();
ImVec2 newSongMinSize=mobileUI?ImVec2(canvasW-(portrait?0:(60.0*dpiScale)),canvasH-60.0*dpiScale):ImVec2(400.0f*dpiScale,200.0f*dpiScale); ImVec2 newSongMinSize=mobileUI?ImVec2(canvasW-(portrait?0:(60.0*dpiScale)),canvasH-60.0*dpiScale):ImVec2(400.0f*dpiScale,200.0f*dpiScale);
@ -8382,6 +8450,7 @@ FurnaceGUI::FurnaceGUI():
displayPendingSamples(false), displayPendingSamples(false),
replacePendingSample(false), replacePendingSample(false),
displayExportingROM(false), displayExportingROM(false),
displayExportingCS(false),
changeCoarse(false), changeCoarse(false),
mobileEdit(false), mobileEdit(false),
killGraphics(false), killGraphics(false),
@ -8875,6 +8944,11 @@ FurnaceGUI::FurnaceGUI():
introStopped(false), introStopped(false),
curTutorial(-1), curTutorial(-1),
curTutorialStep(0), curTutorialStep(0),
csDisAsmAddr(0),
csExportThread(NULL),
csExportResult(NULL),
csExportTarget(false),
csExportDone(false),
dmfExportVersion(0), dmfExportVersion(0),
curExportType(GUI_EXPORT_NONE), curExportType(GUI_EXPORT_NONE),
csExportDisablePass(0), csExportDisablePass(0),

View file

@ -1676,7 +1676,7 @@ class FurnaceGUI {
bool wantScrollListIns, wantScrollListWave, wantScrollListSample; bool wantScrollListIns, wantScrollListWave, wantScrollListSample;
bool displayPendingIns, pendingInsSingle, displayPendingRawSample, snesFilterHex, modTableHex, displayEditString; bool displayPendingIns, pendingInsSingle, displayPendingRawSample, snesFilterHex, modTableHex, displayEditString;
bool displayPendingSamples, replacePendingSample; bool displayPendingSamples, replacePendingSample;
bool displayExportingROM; bool displayExportingROM, displayExportingCS;
bool changeCoarse; bool changeCoarse;
bool mobileEdit; bool mobileEdit;
bool killGraphics; bool killGraphics;
@ -2756,6 +2756,10 @@ class FurnaceGUI {
ImGuiListClipper csClipper; ImGuiListClipper csClipper;
unsigned int csDisAsmAddr; unsigned int csDisAsmAddr;
std::vector<CSDisAsmIns> csDisAsm; std::vector<CSDisAsmIns> csDisAsm;
std::thread* csExportThread;
SafeWriter* csExportResult;
bool csExportTarget, csExportDone;
String csExportPath;
// export options // export options
DivAudioExportOptions audioExportOptions; DivAudioExportOptions audioExportOptions;
@ -3053,6 +3057,7 @@ class FurnaceGUI {
void pushRecentFile(String path); void pushRecentFile(String path);
void pushRecentSys(const char* path); void pushRecentSys(const char* path);
void exportAudio(String path, DivAudioExportModes mode); void exportAudio(String path, DivAudioExportModes mode);
void exportCmdStream(bool target, String path);
void delFirstBackup(String name); void delFirstBackup(String name);
bool parseSysEx(unsigned char* data, size_t len); bool parseSysEx(unsigned char* data, size_t len);