From bb5ad38fb65570c9161458949715269300d203ae Mon Sep 17 00:00:00 2001 From: tildearrow Date: Tue, 13 Aug 2024 16:50:13 -0500 Subject: [PATCH] port TIunA to export framework, part 1 part 2 includes progress bars and options --- CMakeLists.txt | 2 +- src/engine/engine.cpp | 6 + src/engine/engine.h | 4 + src/engine/export.cpp | 4 + src/engine/export.h | 8 +- src/engine/{tiunaOps.cpp => export/tiuna.cpp} | 361 ++++++++++-------- src/engine/export/tiuna.h | 36 ++ src/engine/exportDef.cpp | 9 +- src/gui/exportOptions.cpp | 103 ++--- src/gui/gui.cpp | 60 +-- src/gui/gui.h | 3 - src/main.cpp | 40 +- 12 files changed, 318 insertions(+), 318 deletions(-) rename src/engine/{tiunaOps.cpp => export/tiuna.cpp} (67%) create mode 100644 src/engine/export/tiuna.h diff --git a/CMakeLists.txt b/CMakeLists.txt index 464283d9f..24f4aee2a 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -711,7 +711,6 @@ src/engine/wavOps.cpp src/engine/vgmOps.cpp src/engine/zsmOps.cpp src/engine/zsm.cpp -src/engine/tiunaOps.cpp src/engine/platform/abstract.cpp src/engine/platform/genesis.cpp @@ -789,6 +788,7 @@ src/engine/platform/dummy.cpp src/engine/export/abstract.cpp src/engine/export/amigaValidation.cpp +src/engine/export/tiuna.cpp src/engine/effect/abstract.cpp src/engine/effect/dummy.cpp diff --git a/src/engine/engine.cpp b/src/engine/engine.cpp index bfde6906b..e9b3255c3 100644 --- a/src/engine/engine.cpp +++ b/src/engine/engine.cpp @@ -3589,6 +3589,12 @@ void DivEngine::synchronized(const std::function& what) { BUSY_END; } +void DivEngine::synchronizedSoft(const std::function& what) { + BUSY_BEGIN_SOFT; + what(); + BUSY_END; +} + void DivEngine::lockSave(const std::function& what) { saveLock.lock(); what(); diff --git a/src/engine/engine.h b/src/engine/engine.h index e30334fd4..f010d7001 100644 --- a/src/engine/engine.h +++ b/src/engine/engine.h @@ -657,6 +657,7 @@ class DivEngine { // add every export method here friend class DivROMExport; friend class DivExportAmigaValidation; + friend class DivExportTiuna; public: DivSong song; @@ -1299,6 +1300,9 @@ class DivEngine { // perform secure/sync operation void synchronized(const std::function& what); + // perform secure/sync operation (soft) + void synchronizedSoft(const std::function& what); + // perform secure/sync song operation void lockSave(const std::function& what); diff --git a/src/engine/export.cpp b/src/engine/export.cpp index 68794069e..33544e252 100644 --- a/src/engine/export.cpp +++ b/src/engine/export.cpp @@ -20,6 +20,7 @@ #include "engine.h" #include "export/amigaValidation.h" +#include "export/tiuna.h" DivROMExport* DivEngine::buildROM(DivROMExportOptions sys) { DivROMExport* exporter=NULL; @@ -27,6 +28,9 @@ DivROMExport* DivEngine::buildROM(DivROMExportOptions sys) { case DIV_ROM_AMIGA_VALIDATION: exporter=new DivExportAmigaValidation; break; + case DIV_ROM_TIUNA: + exporter=new DivExportTiuna; + break; default: exporter=new DivROMExport; break; diff --git a/src/engine/export.h b/src/engine/export.h index 49b96dd62..f9439fc95 100644 --- a/src/engine/export.h +++ b/src/engine/export.h @@ -72,6 +72,8 @@ class DivROMExport { virtual ~DivROMExport() {} }; +#define logAppendf(...) logAppend(fmt::sprintf(__VA_ARGS__)) + enum DivROMExportReqPolicy { // exactly these chips. DIV_REQPOL_EXACT=0, @@ -85,14 +87,18 @@ struct DivROMExportDef { const char* name; const char* author; const char* description; + const char* fileType; + const char* fileExt; std::vector requisites; bool multiOutput; DivROMExportReqPolicy requisitePolicy; - DivROMExportDef(const char* n, const char* a, const char* d, std::initializer_list req, bool multiOut, DivROMExportReqPolicy reqPolicy): + DivROMExportDef(const char* n, const char* a, const char* d, const char* ft, const char* fe, std::initializer_list req, bool multiOut, DivROMExportReqPolicy reqPolicy): name(n), author(a), description(d), + fileType(ft), + fileExt(fe), multiOutput(multiOut), requisitePolicy(reqPolicy) { requisites=req; diff --git a/src/engine/tiunaOps.cpp b/src/engine/export/tiuna.cpp similarity index 67% rename from src/engine/tiunaOps.cpp rename to src/engine/export/tiuna.cpp index 8a045cdf8..c4236d53a 100644 --- a/src/engine/tiunaOps.cpp +++ b/src/engine/export/tiuna.cpp @@ -17,13 +17,14 @@ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ +#include "tiuna.h" +#include "../engine.h" +#include "../ta-log.h" +#include #include #include #include #include -#include "engine.h" -#include "../fileutils.h" -#include "../ta-log.h" struct TiunaNew { short pitch; @@ -180,140 +181,156 @@ static void writeCmd(std::vector& cmds, TiunaCmd& cmd, unsigned char } } -SafeWriter* DivEngine::saveTiuna(const bool* sysToExport, const char* baseLabel, int firstBankSize, int otherBankSize) { - stop(); - repeatPattern=false; - shallStop=false; - setOrder(0); - BUSY_BEGIN_SOFT; - // determine loop point - // bool stopped=false; - int loopOrder=0; - int loopOrderRow=0; - int loopEnd=0; - walkSong(loopOrder,loopOrderRow,loopEnd); - logI("loop point: %d %d",loopOrder,loopOrderRow); - - SafeWriter* w=new SafeWriter; - w->init(); - - int tiaIdx=-1; - - for (int i=0; itoggleRegisterDump(true); - break; - } - } - if (tiaIdx<0) { - lastError="selected TIA system not found"; - return NULL; - } - - // write patterns - // bool writeLoop=false; - bool done=false; - playSub(false); - +void DivExportTiuna::run() { + int loopOrder, loopOrderRow, loopEnd; + int tiaIdx; int tick=0; - // int loopTick=-1; - TiunaLast last[2]; - TiunaNew news[2]; + SafeWriter* w; std::map allCmds[2]; - while (!done) { - // TODO implement loop - // if (loopTick<0 && loopOrder==curOrder && loopOrderRow==curRow - // && (ticks-((tempoAccum+virtualTempoN)/virtualTempoD))<=0 - // ) { - // writeLoop=true; - // loopTick=tick; - // // invalidate last register state so it always force an absolute write after loop - // for (int i=0; i<2; i++) { - // last[i]=TiunaLast(); - // last[i].pitch=-1; - // last[i].ins=-1; - // last[i].vol=-1; - // } - // } - if (nextTick(false,true) || !playing) { - // stopped=!playing; - done=true; - break; - } - for (int i=0; i<2; i++) { - news[i]=TiunaNew(); - } - // get register dumps - std::vector& writes=disCont[tiaIdx].dispatch->getRegisterWrites(); - for (const DivRegWrite& i: writes) { - switch (i.addr) { - case 0xfffe0000: - case 0xfffe0001: - news[i.addr&1].pitch=i.val; - break; - case 0xfffe0002: - news[0].sync=i.val; - break; - case 0x15: - case 0x16: - news[i.addr-0x15].ins=i.val; - break; - case 0x19: - case 0x1a: - news[i.addr-0x19].vol=i.val; - break; - default: break; - } - } - writes.clear(); - // collect changes - for (int i=0; i<2; i++) { - TiunaCmd cmds; - bool hasCmd=false; - if (news[i].pitch>=0 && (last[i].forcePitch || news[i].pitch!=last[i].pitch)) { - int dt=news[i].pitch-last[i].pitch; - if (!last[i].forcePitch && abs(dt)<=16) { - if (dt<0) cmds.pitchChange=15-dt; - else cmds.pitchChange=dt-1; - } - else cmds.pitchSet=news[i].pitch; - last[i].pitch=news[i].pitch; - last[i].forcePitch=false; - hasCmd=true; - } - if (news[i].ins>=0 && news[i].ins!=last[i].ins) { - cmds.ins=news[i].ins; - last[i].ins=news[i].ins; - hasCmd=true; - } - if (news[i].vol>=0 && news[i].vol!=last[i].vol) { - cmds.vol=(news[i].vol-last[i].vol)&0xf; - last[i].vol=news[i].vol; - hasCmd=true; - } - if (news[i].sync>=0) { - cmds.sync=news[i].sync; - hasCmd=true; - } - if (hasCmd) allCmds[i][tick]=cmds; - } - cmdStream.clear(); - tick++; - } - for (int i=0; igetRegisterWrites().clear(); - disCont[i].dispatch->toggleRegisterDump(false); - } - remainingLoops=-1; - playing=false; - freelance=false; - extValuePresent=false; - BUSY_END; + // config + int* sysToExport=NULL; + String baseLabel=conf.getString("baseLabel","song"); + int firstBankSize=conf.getInt("firstBankSize",3072); + int otherBankSize=conf.getInt("otherBankSize",4096-48); + + e->stop(); + e->repeatPattern=false; + e->shallStop=false; + e->setOrder(0); + e->synchronizedSoft([&]() { + // determine loop point + // bool stopped=false; + loopOrder=0; + loopOrderRow=0; + loopEnd=0; + e->walkSong(loopOrder,loopOrderRow,loopEnd); + logAppendf("loop point: %d %d",loopOrder,loopOrderRow); + + w=new SafeWriter; + w->init(); + + tiaIdx=-1; + + for (int i=0; isong.systemLen; i++) { + if (sysToExport!=NULL && !sysToExport[i]) continue; + if (e->song.system[i]==DIV_SYSTEM_TIA) { + tiaIdx=i; + e->disCont[i].dispatch->toggleRegisterDump(true); + break; + } + } + if (tiaIdx<0) { + logAppend("ERROR: selected TIA system not found"); + failed=true; + running=false; + return; + } + + // write patterns + // bool writeLoop=false; + logAppend("recording sequence..."); + bool done=false; + e->playSub(false); + + // int loopTick=-1; + TiunaLast last[2]; + TiunaNew news[2]; + while (!done) { + // TODO implement loop + // if (loopTick<0 && loopOrder==curOrder && loopOrderRow==curRow + // && (ticks-((tempoAccum+virtualTempoN)/virtualTempoD))<=0 + // ) { + // writeLoop=true; + // loopTick=tick; + // // invalidate last register state so it always force an absolute write after loop + // for (int i=0; i<2; i++) { + // last[i]=TiunaLast(); + // last[i].pitch=-1; + // last[i].ins=-1; + // last[i].vol=-1; + // } + // } + if (e->nextTick(false,true) || !e->playing) { + // stopped=!playing; + done=true; + break; + } + for (int i=0; i<2; i++) { + news[i]=TiunaNew(); + } + // get register dumps + std::vector& writes=e->disCont[tiaIdx].dispatch->getRegisterWrites(); + for (const DivRegWrite& i: writes) { + switch (i.addr) { + case 0xfffe0000: + case 0xfffe0001: + news[i.addr&1].pitch=i.val; + break; + case 0xfffe0002: + news[0].sync=i.val; + break; + case 0x15: + case 0x16: + news[i.addr-0x15].ins=i.val; + break; + case 0x19: + case 0x1a: + news[i.addr-0x19].vol=i.val; + break; + default: break; + } + } + writes.clear(); + // collect changes + for (int i=0; i<2; i++) { + TiunaCmd cmds; + bool hasCmd=false; + if (news[i].pitch>=0 && (last[i].forcePitch || news[i].pitch!=last[i].pitch)) { + int dt=news[i].pitch-last[i].pitch; + if (!last[i].forcePitch && abs(dt)<=16) { + if (dt<0) cmds.pitchChange=15-dt; + else cmds.pitchChange=dt-1; + } + else cmds.pitchSet=news[i].pitch; + last[i].pitch=news[i].pitch; + last[i].forcePitch=false; + hasCmd=true; + } + if (news[i].ins>=0 && news[i].ins!=last[i].ins) { + cmds.ins=news[i].ins; + last[i].ins=news[i].ins; + hasCmd=true; + } + if (news[i].vol>=0 && news[i].vol!=last[i].vol) { + cmds.vol=(news[i].vol-last[i].vol)&0xf; + last[i].vol=news[i].vol; + hasCmd=true; + } + if (news[i].sync>=0) { + cmds.sync=news[i].sync; + hasCmd=true; + } + if (hasCmd) allCmds[i][tick]=cmds; + } + e->cmdStream.clear(); + tick++; + } + for (int i=0; isong.systemLen; i++) { + e->disCont[i].dispatch->getRegisterWrites().clear(); + e->disCont[i].dispatch->toggleRegisterDump(false); + } + + e->remainingLoops=-1; + e->playing=false; + e->freelance=false; + e->extValuePresent=false; + }); + + if (failed) return; // render commands + logAppend("rendering commands..."); std::vector renderedCmds; w->writeText(fmt::format( "; Generated by Furnace " DIV_VERSION "\n" @@ -321,7 +338,7 @@ SafeWriter* DivEngine::saveTiuna(const bool* sysToExport, const char* baseLabel, "; Author: {}\n" "; Album: {}\n" "; Subsong #{}: {}\n\n", - song.name,song.author,song.category,curSubSongIndex+1,curSubSong->name + e->song.name,e->song.author,e->song.category,e->curSubSongIndex+1,e->curSubSong->name )); for (int i=0; i<2; i++) { TiunaCmd lastCmd; @@ -349,11 +366,20 @@ SafeWriter* DivEngine::saveTiuna(const bool* sysToExport, const char* baseLabel, int cmdSize=renderedCmds.size(); bool* processed=new bool[cmdSize]; memset(processed,0,cmdSize*sizeof(bool)); - logI("max cmId: %d",(MAX(firstBankSize/1024,1))*256); + logAppend("compressing! this may take a while."); + logAppendf("max cmId: %d",(MAX(firstBankSize/1024,1))*256); while (firstBankSize>768 && cmId<(MAX(firstBankSize/1024,1))*256) { - logI("start CM %04x...",cmId); + if (mustAbort) { + logAppend("aborted!"); + failed=true; + running=false; + delete[] processed; + return; + } + + logAppendf("start CM %04x...",cmId); std::map potentialMatches; - logD("scan %d size...",cmdSize-1); + logAppendf("scan %d size...",cmdSize-1); for (int i=0; imaxPMVal) { maxPMVal=i.second.bytesSaved; @@ -440,16 +466,16 @@ SafeWriter* DivEngine::saveTiuna(const bool* sysToExport, const char* baseLabel, } } int maxPMLen=potentialMatches[maxPMIdx].length; - logV("the other step..."); for (const int i: potentialMatches[maxPMIdx].pos) { confirmedMatches.push_back({i,i+maxPMLen,0,cmId}); memset(processed+i,1,maxPMLen); //std::fill(processed.begin()+i,processed.begin()+(i+maxPMLen),true); } callTicks.push_back(potentialMatches[maxPMIdx].ticks); - logI("CM %04x added: pos=%d,len=%d,matches=%d,saved=%d",cmId,maxPMIdx,maxPMLen,potentialMatches[maxPMIdx].pos.size(),maxPMVal); + logAppendf("CM %04x added: pos=%d,len=%d,matches=%d,saved=%d",cmId,maxPMIdx,maxPMLen,potentialMatches[maxPMIdx].pos.size(),maxPMVal); cmId++; } + logAppend("generating data..."); delete[] processed; std::sort(confirmedMatches.begin(),confirmedMatches.end(),[](const TiunaMatch& l, const TiunaMatch& r){ return l.poswriteC('\n'); if (totalSize>firstBankSize) { - lastError="first bank is not large enough to contain call table"; - return NULL; + logAppend("ERROR: first bank is not large enough to contain call table"); + failed=true; + running=false; + return; } int curBank=0; @@ -572,13 +602,40 @@ SafeWriter* DivEngine::saveTiuna(const bool* sysToExport, const char* baseLabel, } w->writeText(" .text x\"e0\"\n .endsection\n"); totalSize++; - logI("total size: %d bytes (%d banks)",totalSize,curBank+1); - - //FILE* f=ps_fopen("confirmedMatches.txt","wb"); - //if (f!=NULL) { - // fwrite(dbg.getFinalBuf(),1,dbg.size(),f); - // fclose(f); - //} + logAppendf("total size: %d bytes (%d banks)",totalSize,curBank+1); - return w; + output.push_back(DivROMExportOutput("export.asm",w)); + + logAppend("finished!"); + + running=false; +} + +bool DivExportTiuna::go(DivEngine* eng) { + e=eng; + running=true; + failed=false; + mustAbort=false; + exportThread=new std::thread(&DivExportTiuna::run,this); + return true; +} + +void DivExportTiuna::wait() { + if (exportThread!=NULL) { + exportThread->join(); + delete exportThread; + } +} + +void DivExportTiuna::abort() { + mustAbort=true; + wait(); +} + +bool DivExportTiuna::isRunning() { + return running; +} + +bool DivExportTiuna::hasFailed() { + return failed; } diff --git a/src/engine/export/tiuna.h b/src/engine/export/tiuna.h new file mode 100644 index 000000000..8e93b9fb4 --- /dev/null +++ b/src/engine/export/tiuna.h @@ -0,0 +1,36 @@ +/** + * Furnace Tracker - multi-system chiptune tracker + * Copyright (C) 2021-2024 tildearrow and contributors + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#include "../export.h" + +#include + +class DivExportTiuna: public DivROMExport { + DivEngine* e; + std::thread* exportThread; + bool running, failed, mustAbort; + void run(); + public: + bool go(DivEngine* e); + bool isRunning(); + bool hasFailed(); + void abort(); + void wait(); + ~DivExportTiuna() {} +}; diff --git a/src/engine/exportDef.cpp b/src/engine/exportDef.cpp index bdf881e65..00ee94a36 100644 --- a/src/engine/exportDef.cpp +++ b/src/engine/exportDef.cpp @@ -31,6 +31,7 @@ void DivEngine::registerROMExports() { romExportDefs[DIV_ROM_AMIGA_VALIDATION]=new DivROMExportDef( "Amiga Validation", "tildearrow", "a test export for ensuring Amiga emulation is accurate. do not use!", + NULL, NULL, {DIV_SYSTEM_AMIGA}, true, DIV_REQPOL_EXACT ); @@ -42,19 +43,21 @@ void DivEngine::registerROMExports() { "- https://github.com/mooinglemur/zsmkit (development)\n" "- https://github.com/mooinglemur/melodius (player)\n" "- https://github.com/ZeroByteOrg/calliope (player)\n", + "ZSM file", ".zsm", { DIV_SYSTEM_YM2151, DIV_SYSTEM_VERA }, - true, DIV_REQPOL_LAX + false, DIV_REQPOL_LAX ); romExportDefs[DIV_ROM_TIUNA]=new DivROMExportDef( "Atari 2600 (TIunA)", "Natt Akuma", "advanced driver with software tuning support.\n" "see https://github.com/AYCEdemo/twin-tiuna for code.", + "assembly files", ".asm", { DIV_SYSTEM_TIA }, - true, DIV_REQPOL_ANY + false, DIV_REQPOL_ANY ); -} \ No newline at end of file +} diff --git a/src/gui/exportOptions.cpp b/src/gui/exportOptions.cpp index 615873391..b216b3bcc 100644 --- a/src/gui/exportOptions.cpp +++ b/src/gui/exportOptions.cpp @@ -252,6 +252,13 @@ void FurnaceGUI::drawExportROM(bool onWindow) { if (ImGui::Selectable(newDef->name)) { romTarget=(DivROMExportOptions)i; romMultiFile=newDef->multiOutput; + if (newDef->fileExt==NULL) { + romFilterName=""; + romFilterExt=""; + } else { + romFilterName=newDef->fileType; + romFilterExt=newDef->fileExt; + } } } } @@ -264,6 +271,36 @@ void FurnaceGUI::drawExportROM(bool onWindow) { ImGui::TextWrapped("%s",def->description); } + /* + ImGui::InputText(_("base song label name"),&asmBaseLabel); // TODO: validate label + if (ImGui::InputInt(_("max size in first bank"),&tiunaFirstBankSize,1,100)) { + if (tiunaFirstBankSize<0) tiunaFirstBankSize=0; + if (tiunaFirstBankSize>4096) tiunaFirstBankSize=4096; + } + if (ImGui::InputInt(_("max size in other banks"),&tiunaOtherBankSize,1,100)) { + if (tiunaOtherBankSize<16) tiunaOtherBankSize=16; + if (tiunaOtherBankSize>4096) tiunaOtherBankSize=4096; + } + + ImGui::Text(_("chips to export:")); + int selected=0; + for (int i=0; isong.systemLen; i++) { + DivSystem sys=e->song.system[i]; + bool isTIA=sys==DIV_SYSTEM_TIA; + ImGui::BeginDisabled((!isTIA) || (selected>=1)); + ImGui::Checkbox(fmt::sprintf("%d. %s##_SYSV%d",i+1,getSystemName(e->song.system[i]),i).c_str(),&willExport[i]); + ImGui::EndDisabled(); + if (ImGui::IsItemHovered(ImGuiHoveredFlags_AllowWhenDisabled)) { + if (!isTIA) { + ImGui::SetTooltip(_("this chip is not supported by the file format!")); + } else if (selected>=1) { + ImGui::SetTooltip(_("only one Atari TIA is supported!")); + } + } + if (isTIA && willExport[i]) selected++; + } + */ + if (onWindow) { ImGui::Separator(); if (ImGui::Button(_("Cancel"),ImVec2(200.0f*dpiScale,0))) ImGui::CloseCurrentPopup(); @@ -297,56 +334,6 @@ void FurnaceGUI::drawExportZSM(bool onWindow) { } } -void FurnaceGUI::drawExportTiuna(bool onWindow) { - exitDisabledTimer=1; - - ImGui::Text(_("for use with TIunA driver. outputs asm source.")); - ImGui::InputText(_("base song label name"),&asmBaseLabel); // TODO: validate label - if (ImGui::InputInt(_("max size in first bank"),&tiunaFirstBankSize,1,100)) { - if (tiunaFirstBankSize<0) tiunaFirstBankSize=0; - if (tiunaFirstBankSize>4096) tiunaFirstBankSize=4096; - } - if (ImGui::InputInt(_("max size in other banks"),&tiunaOtherBankSize,1,100)) { - if (tiunaOtherBankSize<16) tiunaOtherBankSize=16; - if (tiunaOtherBankSize>4096) tiunaOtherBankSize=4096; - } - - ImGui::Text(_("chips to export:")); - int selected=0; - for (int i=0; isong.systemLen; i++) { - DivSystem sys=e->song.system[i]; - bool isTIA=sys==DIV_SYSTEM_TIA; - ImGui::BeginDisabled((!isTIA) || (selected>=1)); - ImGui::Checkbox(fmt::sprintf("%d. %s##_SYSV%d",i+1,getSystemName(e->song.system[i]),i).c_str(),&willExport[i]); - ImGui::EndDisabled(); - if (ImGui::IsItemHovered(ImGuiHoveredFlags_AllowWhenDisabled)) { - if (!isTIA) { - ImGui::SetTooltip(_("this chip is not supported by the file format!")); - } else if (selected>=1) { - ImGui::SetTooltip(_("only one Atari TIA is supported!")); - } - } - if (isTIA && willExport[i]) selected++; - } - if (selected>0) { - if (onWindow) { - ImGui::Separator(); - if (ImGui::Button(_("Cancel"),ImVec2(200.0f*dpiScale,0))) ImGui::CloseCurrentPopup(); - ImGui::SameLine(); - } - if (ImGui::Button(_("Export"),ImVec2(200.0f*dpiScale,0))) { - openFileDialog(GUI_FILE_EXPORT_TIUNA); - ImGui::CloseCurrentPopup(); - } - } else { - ImGui::Text(_("nothing to export")); - if (onWindow) { - ImGui::Separator(); - if (ImGui::Button(_("Cancel"),ImVec2(400.0f*dpiScale,0))) ImGui::CloseCurrentPopup(); - } - } -} - void FurnaceGUI::drawExportText(bool onWindow) { exitDisabledTimer=1; @@ -437,19 +424,6 @@ void FurnaceGUI::drawExport() { ImGui::EndTabItem(); } } - bool hasTiunaCompat=false; - for (int i=0; isong.systemLen; i++) { - if (e->song.system[i]==DIV_SYSTEM_TIA) { - hasTiunaCompat=true; - break; - } - } - if (hasTiunaCompat) { - if (ImGui::BeginTabItem("TIunA")) { - drawExportTiuna(true); - ImGui::EndTabItem(); - } - } if (ImGui::BeginTabItem(_("Text"))) { drawExportText(true); ImGui::EndTabItem(); @@ -477,9 +451,6 @@ void FurnaceGUI::drawExport() { case GUI_EXPORT_ZSM: drawExportZSM(true); break; - case GUI_EXPORT_TIUNA: - drawExportTiuna(true); - break; case GUI_EXPORT_TEXT: drawExportText(true); break; diff --git a/src/gui/gui.cpp b/src/gui/gui.cpp index f950b69fe..86948b0df 100644 --- a/src/gui/gui.cpp +++ b/src/gui/gui.cpp @@ -1950,15 +1950,6 @@ void FurnaceGUI::openFileDialog(FurnaceGUIFileDialogs type) { (settings.autoFillSave)?shortName:"" ); break; - case GUI_FILE_EXPORT_TIUNA: - if (!dirExists(workingDirROMExport)) workingDirROMExport=getHomeDir(); - hasOpened=fileDialog->openSave( - "Export TIunA", - {"assembly files", "*.asm"}, - workingDirROMExport, - dpiScale - ); - break; case GUI_FILE_EXPORT_TEXT: if (!dirExists(workingDirROMExport)) workingDirROMExport=getHomeDir(); hasOpened=fileDialog->openSave( @@ -1990,7 +1981,7 @@ void FurnaceGUI::openFileDialog(FurnaceGUIFileDialogs type) { } else { hasOpened=fileDialog->openSave( _("Export ROM"), - {romFilterName, romFilterExt}, + {romFilterName, "*"+romFilterExt}, workingDirROMExport, dpiScale, (settings.autoFillSave)?shortName:"" @@ -4324,19 +4315,6 @@ bool FurnaceGUI::loop() { ImGui::EndMenu(); } } - bool hasTiunaCompat=false; - for (int i=0; isong.systemLen; i++) { - if (e->song.system[i]==DIV_SYSTEM_TIA) { - hasTiunaCompat=true; - break; - } - } - if (hasTiunaCompat) { - if (ImGui::BeginMenu(_("export TIunA..."))) { - drawExportTiuna(); - ImGui::EndMenu(); - } - } if (ImGui::BeginMenu(_("export text..."))) { drawExportText(); ImGui::EndMenu(); @@ -4372,19 +4350,6 @@ bool FurnaceGUI::loop() { displayExport=true; } } - bool hasTiunaCompat=false; - for (int i=0; isong.systemLen; i++) { - if (e->song.system[i]==DIV_SYSTEM_TIA) { - hasTiunaCompat=true; - break; - } - } - if (hasTiunaCompat) { - if (ImGui::MenuItem(_("export TIunA..."))) { - curExportType=GUI_EXPORT_TIUNA; - displayExport=true; - } - } if (ImGui::MenuItem(_("export text..."))) { curExportType=GUI_EXPORT_TEXT; displayExport=true; @@ -4968,7 +4933,6 @@ bool FurnaceGUI::loop() { workingDirZSMExport=fileDialog->getPath()+DIR_SEPARATOR_STR; break; case GUI_FILE_EXPORT_ROM: - case GUI_FILE_EXPORT_TIUNA: case GUI_FILE_EXPORT_TEXT: case GUI_FILE_EXPORT_CMDSTREAM: workingDirROMExport=fileDialog->getPath()+DIR_SEPARATOR_STR; @@ -5527,27 +5491,6 @@ bool FurnaceGUI::loop() { } break; } - case GUI_FILE_EXPORT_TIUNA: { - SafeWriter* w=e->saveTiuna(willExport,asmBaseLabel.c_str(),tiunaFirstBankSize,tiunaOtherBankSize); - 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 TIunA! (%s)",e->getLastError())); - } - break; - } case GUI_FILE_EXPORT_ROM: romExportPath=copyOfName; pendingExport=e->buildROM(romTarget); @@ -5833,6 +5776,7 @@ bool FurnaceGUI::loop() { pendingExport->abort(); delete pendingExport; pendingExport=NULL; + romExportSave=false; ImGui::CloseCurrentPopup(); } } else { diff --git a/src/gui/gui.h b/src/gui/gui.h index 060db2a9c..7a7b8ed0f 100644 --- a/src/gui/gui.h +++ b/src/gui/gui.h @@ -599,7 +599,6 @@ enum FurnaceGUIFileDialogs { GUI_FILE_EXPORT_AUDIO_PER_CHANNEL, GUI_FILE_EXPORT_VGM, GUI_FILE_EXPORT_ZSM, - GUI_FILE_EXPORT_TIUNA, GUI_FILE_EXPORT_CMDSTREAM, GUI_FILE_EXPORT_TEXT, GUI_FILE_EXPORT_ROM, @@ -653,7 +652,6 @@ enum FurnaceGUIExportTypes { GUI_EXPORT_VGM, GUI_EXPORT_ROM, GUI_EXPORT_ZSM, - GUI_EXPORT_TIUNA, GUI_EXPORT_CMD_STREAM, GUI_EXPORT_TEXT, GUI_EXPORT_DMF @@ -2698,7 +2696,6 @@ class FurnaceGUI { void drawExportVGM(bool onWindow=false); void drawExportROM(bool onWindow=false); void drawExportZSM(bool onWindow=false); - void drawExportTiuna(bool onWindow=false); void drawExportText(bool onWindow=false); void drawExportCommand(bool onWindow=false); void drawExportDMF(bool onWindow=false); diff --git a/src/main.cpp b/src/main.cpp index 70999859e..ac6e231b2 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -87,7 +87,6 @@ String outName; String vgmOutName; String zsmOutName; String cmdOutName; -String tiunaOutName; int benchMode=0; int subsong=-1; DivAudioExportOptions exportOptions; @@ -112,9 +111,6 @@ bool infoMode=false; bool noReportError=false; -int tiunaFirstBankSize=3072; -int tiunaOtherBankSize=4096-48; - std::vector params; #ifdef HAVE_LOCALE @@ -445,12 +441,6 @@ TAParamResult pCmdOut(String val) { return TA_PARAM_SUCCESS; } -TAParamResult pTiunaOut(String val) { - tiunaOutName=val; - e.setAudio(DIV_AUDIO_DUMMY); - return TA_PARAM_SUCCESS; -} - bool needsValue(String param) { for (size_t i=0; i","output .zsm data for Commander X16 Zsound")); params.push_back(TAParam("C","cmdout",true,pCmdOut,"","output command stream")); - params.push_back(TAParam("T","tiunaout",true,pTiunaOut,"","output .asm data with TIunA sound data (TIA only)")); params.push_back(TAParam("L","loglevel",true,pLogLevel,"debug|info|warning|error","set the log level (info by default)")); params.push_back(TAParam("v","view",true,pView,"pattern|commands|nothing","set visualization (nothing by default)")); params.push_back(TAParam("i","info",false,pInfo,"","get info about a song")); @@ -573,7 +562,6 @@ int main(int argc, char** argv) { vgmOutName=""; zsmOutName=""; cmdOutName=""; - tiunaOutName=""; // load config for locale e.prePreInit(); @@ -741,14 +729,14 @@ int main(int argc, char** argv) { return 1; } - if (fileName.empty() && (benchMode || infoMode || outName!="" || vgmOutName!="" || zsmOutName!="" || cmdOutName!="" || tiunaOutName!="")) { + if (fileName.empty() && (benchMode || infoMode || outName!="" || vgmOutName!="" || zsmOutName!="" || cmdOutName!="")) { logE("provide a file!"); return 1; } #ifdef HAVE_GUI - if (e.preInit(consoleMode || benchMode || infoMode || outName!="" || vgmOutName!="" || zsmOutName!="" || cmdOutName!="" || tiunaOutName!="")) { - if (consoleMode || benchMode || infoMode || outName!="" || vgmOutName!="" || zsmOutName!="" || cmdOutName!="" || tiunaOutName!="") { + if (e.preInit(consoleMode || benchMode || infoMode || outName!="" || vgmOutName!="" || zsmOutName!="" || cmdOutName!="")) { + if (consoleMode || benchMode || infoMode || outName!="" || vgmOutName!="" || zsmOutName!="" || cmdOutName!="") { logW("engine wants safe mode, but Furnace GUI is not going to start."); } else { safeMode=true; @@ -760,7 +748,7 @@ int main(int argc, char** argv) { } #endif - if (safeMode && (consoleMode || benchMode || infoMode || outName!="" || vgmOutName!="" || zsmOutName!="" || cmdOutName!="" || tiunaOutName!="")) { + if (safeMode && (consoleMode || benchMode || infoMode || outName!="" || vgmOutName!="" || zsmOutName!="" || cmdOutName!="")) { logE("you can't use safe mode and console/export mode together."); return 1; } @@ -769,7 +757,7 @@ int main(int argc, char** argv) { e.setAudio(DIV_AUDIO_DUMMY); } - if (!fileName.empty() && ((!e.getConfBool("tutIntroPlayed",TUT_INTRO_PLAYED)) || e.getConfInt("alwaysPlayIntro",0)!=3 || consoleMode || benchMode || infoMode || outName!="" || vgmOutName!="" || zsmOutName!="" || cmdOutName!="" || tiunaOutName!="")) { + if (!fileName.empty() && ((!e.getConfBool("tutIntroPlayed",TUT_INTRO_PLAYED)) || e.getConfInt("alwaysPlayIntro",0)!=3 || consoleMode || benchMode || infoMode || outName!="" || vgmOutName!="" || zsmOutName!="" || cmdOutName!="")) { logI("loading module..."); FILE* f=ps_fopen(fileName.c_str(),"rb"); if (f==NULL) { @@ -861,7 +849,7 @@ int main(int argc, char** argv) { return 0; } - if (outName!="" || vgmOutName!="" || zsmOutName!="" || cmdOutName!="" || tiunaOutName!="") { + if (outName!="" || vgmOutName!="" || zsmOutName!="" || cmdOutName!="") { if (cmdOutName!="") { SafeWriter* w=e.saveCommand(); if (w!=NULL) { @@ -911,22 +899,6 @@ int main(int argc, char** argv) { reportError(fmt::sprintf(_("could not write ZSM! (%s)"),e.getLastError())); } } - if (tiunaOutName!="") { - SafeWriter* w=e.saveTiuna(NULL,"asmBaseLabel",tiunaFirstBankSize,tiunaOtherBankSize); - if (w!=NULL) { - FILE* f=ps_fopen(tiunaOutName.c_str(),"wb"); - if (f!=NULL) { - fwrite(w->getFinalBuf(),1,w->size(),f); - fclose(f); - } else { - reportError(fmt::sprintf(_("could not open file! (%s)"),e.getLastError())); - } - w->finish(); - delete w; - } else { - reportError(fmt::sprintf("could not write TIunA! (%s)",e.getLastError())); - } - } if (outName!="") { e.setConsoleMode(true); e.saveAudio(outName.c_str(),exportOptions);