-romout command line export
consolidate DivEngine::isROMExportViable function from FurnaceGUI::updateROMExportAvail to avoid copy-paste
This commit is contained in:
parent
addb50e384
commit
55a189444f
|
@ -81,6 +81,10 @@ the following parameters may be used:
|
||||||
- `-cmdout path`: output command stream dump to `path`.
|
- `-cmdout path`: output command stream dump to `path`.
|
||||||
- you must provide a file, otherwise Furnace will quit.
|
- you must provide a file, otherwise Furnace will quit.
|
||||||
|
|
||||||
|
- `-romout path`: output ROM file export to `path`.
|
||||||
|
- you must provide a file, otherwise Furnace will quit.
|
||||||
|
- there must be an available ROM export target for the system.
|
||||||
|
|
||||||
- `-txtout path`: output text file export to `path`.
|
- `-txtout path`: output text file export to `path`.
|
||||||
- you must provide a file, otherwise Furnace will quit.
|
- you must provide a file, otherwise Furnace will quit.
|
||||||
|
|
||||||
|
|
|
@ -908,6 +908,8 @@ class DivEngine {
|
||||||
|
|
||||||
// get ROM export definition
|
// get ROM export definition
|
||||||
const DivROMExportDef* getROMExportDef(DivROMExportOptions opt);
|
const DivROMExportDef* getROMExportDef(DivROMExportOptions opt);
|
||||||
|
// check whether ROM export option is viable for current song
|
||||||
|
bool isROMExportViable(DivROMExportOptions opt);
|
||||||
|
|
||||||
// convert sample rate format
|
// convert sample rate format
|
||||||
int fileToDivRate(int frate);
|
int fileToDivRate(int frate);
|
||||||
|
|
|
@ -25,6 +25,51 @@ const DivROMExportDef* DivEngine::getROMExportDef(DivROMExportOptions opt) {
|
||||||
return romExportDefs[opt];
|
return romExportDefs[opt];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool DivEngine::isROMExportViable(DivROMExportOptions opt)
|
||||||
|
{
|
||||||
|
const DivROMExportDef* newDef=getROMExportDef(opt);
|
||||||
|
if (newDef==NULL) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned char sysReqCount[DIV_SYSTEM_MAX];
|
||||||
|
memset(sysReqCount,0,DIV_SYSTEM_MAX);
|
||||||
|
for (int i=0; i<song.systemLen; i++) {
|
||||||
|
sysReqCount[song.system[i]]++;
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned char defReqCount[DIV_SYSTEM_MAX];
|
||||||
|
memset(defReqCount,0,DIV_SYSTEM_MAX);
|
||||||
|
for (DivSystem j: newDef->requisites) {
|
||||||
|
defReqCount[j]++;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (newDef->requisitePolicy) {
|
||||||
|
case DIV_REQPOL_EXACT:
|
||||||
|
for (int j=0; j<DIV_SYSTEM_MAX; j++) {
|
||||||
|
if (defReqCount[j]!=sysReqCount[j]) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case DIV_REQPOL_ANY:
|
||||||
|
for (int j=0; j<DIV_SYSTEM_MAX; j++) {
|
||||||
|
if (defReqCount[j]>sysReqCount[j]) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case DIV_REQPOL_LAX:
|
||||||
|
for (DivSystem j: newDef->requisites) {
|
||||||
|
if (defReqCount[j]<=sysReqCount[j]) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
void DivEngine::registerROMExports() {
|
void DivEngine::registerROMExports() {
|
||||||
logD("registering ROM exports...");
|
logD("registering ROM exports...");
|
||||||
|
|
||||||
|
|
|
@ -769,60 +769,13 @@ void FurnaceGUI::autoDetectSystem() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void FurnaceGUI::updateROMExportAvail() {
|
void FurnaceGUI::updateROMExportAvail() {
|
||||||
unsigned char sysReqCount[DIV_SYSTEM_MAX];
|
|
||||||
unsigned char defReqCount[DIV_SYSTEM_MAX];
|
|
||||||
|
|
||||||
memset(sysReqCount,0,DIV_SYSTEM_MAX);
|
|
||||||
for (int i=0; i<e->song.systemLen; i++) {
|
|
||||||
sysReqCount[e->song.system[i]]++;
|
|
||||||
}
|
|
||||||
|
|
||||||
memset(romExportAvail,0,sizeof(bool)*DIV_ROM_MAX);
|
memset(romExportAvail,0,sizeof(bool)*DIV_ROM_MAX);
|
||||||
romExportExists=false;
|
romExportExists=false;
|
||||||
|
|
||||||
for (int i=0; i<DIV_ROM_MAX; i++) {
|
for (int i=0; i<DIV_ROM_MAX; i++) {
|
||||||
const DivROMExportDef* newDef=e->getROMExportDef((DivROMExportOptions)i);
|
if (e->isROMExportViable((DivROMExportOptions)i)) {
|
||||||
if (newDef!=NULL) {
|
romExportAvail[i]=true;
|
||||||
// check for viability
|
romExportExists=true;
|
||||||
bool viable=true;
|
|
||||||
|
|
||||||
memset(defReqCount,0,DIV_SYSTEM_MAX);
|
|
||||||
for (DivSystem j: newDef->requisites) {
|
|
||||||
defReqCount[j]++;
|
|
||||||
}
|
|
||||||
|
|
||||||
switch (newDef->requisitePolicy) {
|
|
||||||
case DIV_REQPOL_EXACT:
|
|
||||||
for (int j=0; j<DIV_SYSTEM_MAX; j++) {
|
|
||||||
if (defReqCount[j]!=sysReqCount[j]) {
|
|
||||||
viable=false;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case DIV_REQPOL_ANY:
|
|
||||||
for (int j=0; j<DIV_SYSTEM_MAX; j++) {
|
|
||||||
if (defReqCount[j]>sysReqCount[j]) {
|
|
||||||
viable=false;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case DIV_REQPOL_LAX:
|
|
||||||
viable=false;
|
|
||||||
for (DivSystem j: newDef->requisites) {
|
|
||||||
if (defReqCount[j]<=sysReqCount[j]) {
|
|
||||||
viable=true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (viable) {
|
|
||||||
romExportAvail[i]=true;
|
|
||||||
romExportExists=true;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
65
src/main.cpp
65
src/main.cpp
|
@ -86,6 +86,7 @@ FurnaceCLI cli;
|
||||||
String outName;
|
String outName;
|
||||||
String vgmOutName;
|
String vgmOutName;
|
||||||
String cmdOutName;
|
String cmdOutName;
|
||||||
|
String romOutName;
|
||||||
String txtOutName;
|
String txtOutName;
|
||||||
int benchMode=0;
|
int benchMode=0;
|
||||||
int subsong=-1;
|
int subsong=-1;
|
||||||
|
@ -438,6 +439,12 @@ TAParamResult pCmdOut(String val) {
|
||||||
return TA_PARAM_SUCCESS;
|
return TA_PARAM_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TAParamResult pROMOut(String val) {
|
||||||
|
romOutName=val;
|
||||||
|
e.setAudio(DIV_AUDIO_DUMMY);
|
||||||
|
return TA_PARAM_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
TAParamResult pTxtOut(String val) {
|
TAParamResult pTxtOut(String val) {
|
||||||
txtOutName=val;
|
txtOutName=val;
|
||||||
e.setAudio(DIV_AUDIO_DUMMY);
|
e.setAudio(DIV_AUDIO_DUMMY);
|
||||||
|
@ -461,6 +468,7 @@ void initParams() {
|
||||||
params.push_back(TAParam("O","vgmout",true,pVGMOut,"<filename>","output .vgm data"));
|
params.push_back(TAParam("O","vgmout",true,pVGMOut,"<filename>","output .vgm data"));
|
||||||
params.push_back(TAParam("D","direct",false,pDirect,"","set VGM export direct stream mode"));
|
params.push_back(TAParam("D","direct",false,pDirect,"","set VGM export direct stream mode"));
|
||||||
params.push_back(TAParam("C","cmdout",true,pCmdOut,"<filename>","output command stream"));
|
params.push_back(TAParam("C","cmdout",true,pCmdOut,"<filename>","output command stream"));
|
||||||
|
params.push_back(TAParam("r","romout",true,pROMOut,"<filename>","export ROM file"));
|
||||||
params.push_back(TAParam("t","txtout",true,pTxtOut,"<filename>","export as text file"));
|
params.push_back(TAParam("t","txtout",true,pTxtOut,"<filename>","export as text file"));
|
||||||
params.push_back(TAParam("L","loglevel",true,pLogLevel,"debug|info|warning|error","set the log level (info by default)"));
|
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("v","view",true,pView,"pattern|commands|nothing","set visualization (nothing by default)"));
|
||||||
|
@ -557,6 +565,7 @@ int main(int argc, char** argv) {
|
||||||
outName="";
|
outName="";
|
||||||
vgmOutName="";
|
vgmOutName="";
|
||||||
cmdOutName="";
|
cmdOutName="";
|
||||||
|
romOutName="";
|
||||||
txtOutName="";
|
txtOutName="";
|
||||||
|
|
||||||
// load config for locale
|
// load config for locale
|
||||||
|
@ -725,7 +734,7 @@ int main(int argc, char** argv) {
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
const bool outputMode = outName!="" || vgmOutName!="" || cmdOutName!="" || txtOutName!="";
|
const bool outputMode = outName!="" || vgmOutName!="" || cmdOutName!="" || romOutName!="" || txtOutName!="";
|
||||||
|
|
||||||
if (fileName.empty() && (benchMode || infoMode || outputMode)) {
|
if (fileName.empty() && (benchMode || infoMode || outputMode)) {
|
||||||
logE("provide a file!");
|
logE("provide a file!");
|
||||||
|
@ -893,6 +902,60 @@ int main(int argc, char** argv) {
|
||||||
e.saveAudio(outName.c_str(),exportOptions);
|
e.saveAudio(outName.c_str(),exportOptions);
|
||||||
e.waitAudioFile();
|
e.waitAudioFile();
|
||||||
}
|
}
|
||||||
|
if (romOutName!="") {
|
||||||
|
e.setConsoleMode(true);
|
||||||
|
// select ROM target type
|
||||||
|
DivROMExportOptions romTarget = DIV_ROM_ABSTRACT;
|
||||||
|
for (int i=0; i<DIV_ROM_MAX; i++) {
|
||||||
|
DivROMExportOptions opt = (DivROMExportOptions)i;
|
||||||
|
if (e.isROMExportViable(opt)) {
|
||||||
|
const DivROMExportDef* newDef=e.getROMExportDef((DivROMExportOptions)i);
|
||||||
|
if (newDef->fileExt &&
|
||||||
|
romOutName.length()>=strlen(newDef->fileExt) &&
|
||||||
|
!stricmp(newDef->fileExt,romOutName.c_str()+(romOutName.length()-strlen(newDef->fileExt)))) {
|
||||||
|
romTarget = opt;
|
||||||
|
break; // extension matched, stop searching
|
||||||
|
}
|
||||||
|
if (romTarget == DIV_ROM_ABSTRACT) {
|
||||||
|
romTarget = opt; // use first viable, but keep searching for extension match
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (romTarget > DIV_ROM_ABSTRACT && romTarget < DIV_ROM_MAX) {
|
||||||
|
DivConfig romConfig; // TODO: no current way to pass config, maybe serialize them to .fur file?
|
||||||
|
DivROMExport* pendingExport = e.buildROM(romTarget);
|
||||||
|
if (pendingExport==NULL) {
|
||||||
|
reportError(_("could not create exporter! you may want to report this issue..."));
|
||||||
|
} else {
|
||||||
|
pendingExport->setConf(romConfig);
|
||||||
|
if (pendingExport->go(&e)) {
|
||||||
|
pendingExport->wait();
|
||||||
|
if (!pendingExport->hasFailed()) {
|
||||||
|
for (DivROMExportOutput& i: pendingExport->getResult()) {
|
||||||
|
String path=romOutName;
|
||||||
|
if (e.getROMExportDef(romTarget)->multiOutput) {
|
||||||
|
path+=DIR_SEPARATOR_STR;
|
||||||
|
path+=i.name;
|
||||||
|
}
|
||||||
|
FILE* f=ps_fopen(path.c_str(),"wb");
|
||||||
|
if (f!=NULL) {
|
||||||
|
fwrite(i.data->getFinalBuf(),1,i.data->size(),f);
|
||||||
|
fclose(f);
|
||||||
|
} else {
|
||||||
|
reportError(fmt::sprintf(_("could not open file! (%s)"),strerror(errno)));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
reportError(fmt::sprintf(_("ROM export failed! (%s)"),e.getLastError()));
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
reportError(_("could not begin exporting process! TODO: elaborate"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
reportError(_("no matching ROM export target is available."));
|
||||||
|
}
|
||||||
|
}
|
||||||
if (txtOutName!="") {
|
if (txtOutName!="") {
|
||||||
e.setConsoleMode(true);
|
e.setConsoleMode(true);
|
||||||
SafeWriter* w=e.saveText(false);
|
SafeWriter* w=e.saveText(false);
|
||||||
|
|
Loading…
Reference in a new issue