remove text command stream export
NOTE: this is not removal of text export.
This commit is contained in:
parent
5dd62d45fa
commit
db9a11a674
|
@ -76,10 +76,9 @@ click on **Begin Export** to... you know.
|
||||||
|
|
||||||
## export command stream
|
## export command stream
|
||||||
|
|
||||||
this option exports a text or binary file which contains a dump of the internal command stream produced when playing the song.
|
this option exports a binary file which contains a dump of the internal command stream produced when playing the song.
|
||||||
|
|
||||||
it's not really useful, unless you're a developer and want to use a command stream dump for some reason (e.g. writing a hardware sound driver).
|
it's not really useful, unless you're a developer and want to use a command stream dump for some reason (e.g. writing a hardware sound driver).
|
||||||
|
|
||||||
- **export (binary)**: exports in Furnace's own command stream format (FCS). see `export-tech.md` in `papers/` for details.
|
- **export**: exports in Furnace's own command stream format (FCS). see `export-tech.md` in `papers/` for details.
|
||||||
- **export (text)**: exports the command stream as a text file. only useful for analysis, really.
|
|
||||||
|
|
||||||
|
|
|
@ -83,7 +83,6 @@ 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.
|
||||||
- `-binary`: set command stream output format to binary.
|
|
||||||
|
|
||||||
## COMMAND LINE INTERFACE
|
## COMMAND LINE INTERFACE
|
||||||
|
|
||||||
|
|
|
@ -21,26 +21,19 @@
|
||||||
#include "../ta-log.h"
|
#include "../ta-log.h"
|
||||||
|
|
||||||
#define WRITE_TICK(x) \
|
#define WRITE_TICK(x) \
|
||||||
if (binary) { \
|
if (!wroteTick[x]) { \
|
||||||
if (!wroteTick[x]) { \
|
wroteTick[x]=true; \
|
||||||
wroteTick[x]=true; \
|
if (tick-lastTick[x]>255) { \
|
||||||
if (tick-lastTick[x]>255) { \
|
chanStream[x]->writeC(0xfc); \
|
||||||
chanStream[x]->writeC(0xfc); \
|
chanStream[x]->writeS(tick-lastTick[x]); \
|
||||||
chanStream[x]->writeS(tick-lastTick[x]); \
|
} else if (tick-lastTick[x]>1) { \
|
||||||
} else if (tick-lastTick[x]>1) { \
|
delayPopularity[tick-lastTick[x]]++; \
|
||||||
delayPopularity[tick-lastTick[x]]++; \
|
chanStream[x]->writeC(0xfd); \
|
||||||
chanStream[x]->writeC(0xfd); \
|
chanStream[x]->writeC(tick-lastTick[x]); \
|
||||||
chanStream[x]->writeC(tick-lastTick[x]); \
|
} else if (tick-lastTick[x]>0) { \
|
||||||
} else if (tick-lastTick[x]>0) { \
|
chanStream[x]->writeC(0xfe); \
|
||||||
chanStream[x]->writeC(0xfe); \
|
|
||||||
} \
|
|
||||||
lastTick[x]=tick; \
|
|
||||||
} \
|
|
||||||
} else { \
|
|
||||||
if (!wroteTickGlobal) { \
|
|
||||||
wroteTickGlobal=true; \
|
|
||||||
w->writeText(fmt::sprintf(">> TICK %d\n",tick)); \
|
|
||||||
} \
|
} \
|
||||||
|
lastTick[x]=tick; \
|
||||||
}
|
}
|
||||||
|
|
||||||
void writePackedCommandValues(SafeWriter* w, const DivCommand& c) {
|
void writePackedCommandValues(SafeWriter* w, const DivCommand& c) {
|
||||||
|
@ -205,7 +198,7 @@ void writePackedCommandValues(SafeWriter* w, const DivCommand& c) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
SafeWriter* DivEngine::saveCommand(bool binary) {
|
SafeWriter* DivEngine::saveCommand() {
|
||||||
stop();
|
stop();
|
||||||
repeatPattern=false;
|
repeatPattern=false;
|
||||||
shallStop=false;
|
shallStop=false;
|
||||||
|
@ -243,49 +236,23 @@ SafeWriter* DivEngine::saveCommand(bool binary) {
|
||||||
w->init();
|
w->init();
|
||||||
|
|
||||||
// write header
|
// write header
|
||||||
if (binary) {
|
w->write("FCS",4);
|
||||||
w->write("FCS",4);
|
w->writeI(chans);
|
||||||
w->writeI(chans);
|
// offsets
|
||||||
// offsets
|
for (int i=0; i<chans; i++) {
|
||||||
for (int i=0; i<chans; i++) {
|
chanStream[i]=new SafeWriter;
|
||||||
chanStream[i]=new SafeWriter;
|
chanStream[i]->init();
|
||||||
chanStream[i]->init();
|
w->writeI(0);
|
||||||
w->writeI(0);
|
}
|
||||||
}
|
// preset delays and speed dial
|
||||||
// preset delays and speed dial
|
for (int i=0; i<32; i++) {
|
||||||
for (int i=0; i<32; i++) {
|
w->writeC(0);
|
||||||
w->writeC(0);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
w->writeText("# Furnace Command Stream\n\n");
|
|
||||||
|
|
||||||
w->writeText("[Information]\n");
|
|
||||||
w->writeText(fmt::sprintf("name: %s\n",song.name));
|
|
||||||
w->writeText(fmt::sprintf("author: %s\n",song.author));
|
|
||||||
w->writeText(fmt::sprintf("category: %s\n",song.category));
|
|
||||||
w->writeText(fmt::sprintf("system: %s\n",song.systemName));
|
|
||||||
|
|
||||||
w->writeText("\n");
|
|
||||||
|
|
||||||
w->writeText("[SubSongInformation]\n");
|
|
||||||
w->writeText(fmt::sprintf("name: %s\n",curSubSong->name));
|
|
||||||
w->writeText(fmt::sprintf("tickRate: %f\n",curSubSong->hz));
|
|
||||||
|
|
||||||
w->writeText("\n");
|
|
||||||
|
|
||||||
w->writeText("[SysDefinition]\n");
|
|
||||||
// TODO
|
|
||||||
|
|
||||||
w->writeText("\n");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// play the song ourselves
|
// play the song ourselves
|
||||||
bool done=false;
|
bool done=false;
|
||||||
playSub(false);
|
playSub(false);
|
||||||
|
|
||||||
if (!binary) {
|
|
||||||
w->writeText("[Stream]\n");
|
|
||||||
}
|
|
||||||
int tick=0;
|
int tick=0;
|
||||||
bool oldCmdStreamEnabled=cmdStreamEnabled;
|
bool oldCmdStreamEnabled=cmdStreamEnabled;
|
||||||
cmdStreamEnabled=true;
|
cmdStreamEnabled=true;
|
||||||
|
@ -305,12 +272,8 @@ SafeWriter* DivEngine::saveCommand(bool binary) {
|
||||||
if (curDivider!=divider) {
|
if (curDivider!=divider) {
|
||||||
curDivider=divider;
|
curDivider=divider;
|
||||||
WRITE_TICK(0);
|
WRITE_TICK(0);
|
||||||
if (binary) {
|
chanStream[0]->writeC(0xfb);
|
||||||
chanStream[0]->writeC(0xfb);
|
chanStream[0]->writeI((int)(curDivider*65536));
|
||||||
chanStream[0]->writeI((int)(curDivider*65536));
|
|
||||||
} else {
|
|
||||||
w->writeText(fmt::sprintf(">> SET_RATE %f\n",curDivider));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
for (DivCommand& i: cmdStream) {
|
for (DivCommand& i: cmdStream) {
|
||||||
switch (i.cmd) {
|
switch (i.cmd) {
|
||||||
|
@ -329,12 +292,8 @@ SafeWriter* DivEngine::saveCommand(bool binary) {
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
WRITE_TICK(i.chan);
|
WRITE_TICK(i.chan);
|
||||||
if (binary) {
|
cmdPopularity[i.cmd]++;
|
||||||
cmdPopularity[i.cmd]++;
|
writePackedCommandValues(chanStream[i.chan],i);
|
||||||
writePackedCommandValues(chanStream[i.chan],i);
|
|
||||||
} else {
|
|
||||||
w->writeText(fmt::sprintf(" %d: %s %d %d\n",i.chan,cmdName[i.cmd],i.value,i.value2));
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -348,192 +307,184 @@ SafeWriter* DivEngine::saveCommand(bool binary) {
|
||||||
}
|
}
|
||||||
cmdStreamEnabled=oldCmdStreamEnabled;
|
cmdStreamEnabled=oldCmdStreamEnabled;
|
||||||
|
|
||||||
if (binary) {
|
int sortCand=-1;
|
||||||
int sortCand=-1;
|
int sortPos=0;
|
||||||
int sortPos=0;
|
while (sortPos<16) {
|
||||||
while (sortPos<16) {
|
|
||||||
sortCand=-1;
|
|
||||||
for (int i=DIV_CMD_SAMPLE_MODE; i<256; i++) {
|
|
||||||
if (cmdPopularity[i]) {
|
|
||||||
if (sortCand==-1) {
|
|
||||||
sortCand=i;
|
|
||||||
} else if (cmdPopularity[sortCand]<cmdPopularity[i]) {
|
|
||||||
sortCand=i;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (sortCand==-1) break;
|
|
||||||
|
|
||||||
sortedCmdPopularity[sortPos]=cmdPopularity[sortCand];
|
|
||||||
sortedCmd[sortPos]=sortCand;
|
|
||||||
cmdPopularity[sortCand]=0;
|
|
||||||
sortPos++;
|
|
||||||
}
|
|
||||||
|
|
||||||
sortCand=-1;
|
sortCand=-1;
|
||||||
sortPos=0;
|
for (int i=DIV_CMD_SAMPLE_MODE; i<256; i++) {
|
||||||
while (sortPos<16) {
|
if (cmdPopularity[i]) {
|
||||||
sortCand=-1;
|
if (sortCand==-1) {
|
||||||
for (int i=0; i<256; i++) {
|
sortCand=i;
|
||||||
if (delayPopularity[i]) {
|
} else if (cmdPopularity[sortCand]<cmdPopularity[i]) {
|
||||||
if (sortCand==-1) {
|
sortCand=i;
|
||||||
sortCand=i;
|
|
||||||
} else if (delayPopularity[sortCand]<delayPopularity[i]) {
|
|
||||||
sortCand=i;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (sortCand==-1) break;
|
|
||||||
|
|
||||||
sortedDelayPopularity[sortPos]=delayPopularity[sortCand];
|
|
||||||
sortedDelay[sortPos]=sortCand;
|
|
||||||
delayPopularity[sortCand]=0;
|
|
||||||
sortPos++;
|
|
||||||
}
|
}
|
||||||
|
if (sortCand==-1) break;
|
||||||
|
|
||||||
for (int i=0; i<chans; i++) {
|
sortedCmdPopularity[sortPos]=cmdPopularity[sortCand];
|
||||||
chanStream[i]->writeC(0xff);
|
sortedCmd[sortPos]=sortCand;
|
||||||
// optimize stream
|
cmdPopularity[sortCand]=0;
|
||||||
SafeWriter* oldStream=chanStream[i];
|
sortPos++;
|
||||||
SafeReader* reader=oldStream->toReader();
|
}
|
||||||
chanStream[i]=new SafeWriter;
|
|
||||||
chanStream[i]->init();
|
|
||||||
|
|
||||||
while (1) {
|
sortCand=-1;
|
||||||
try {
|
sortPos=0;
|
||||||
unsigned char next=reader->readC();
|
while (sortPos<16) {
|
||||||
switch (next) {
|
sortCand=-1;
|
||||||
case 0xb8: // instrument
|
for (int i=0; i<256; i++) {
|
||||||
case 0xc0: // pre porta
|
if (delayPopularity[i]) {
|
||||||
case 0xc3: // vibrato range
|
if (sortCand==-1) {
|
||||||
case 0xc4: // vibrato shape
|
sortCand=i;
|
||||||
case 0xc5: // pitch
|
} else if (delayPopularity[sortCand]<delayPopularity[i]) {
|
||||||
case 0xc7: // volume
|
sortCand=i;
|
||||||
case 0xca: // legato
|
|
||||||
chanStream[i]->writeC(next);
|
|
||||||
next=reader->readC();
|
|
||||||
chanStream[i]->writeC(next);
|
|
||||||
break;
|
|
||||||
case 0xbe: // panning
|
|
||||||
case 0xc2: // vibrato
|
|
||||||
case 0xc6: // arpeggio
|
|
||||||
case 0xc8: // vol slide
|
|
||||||
case 0xc9: // porta
|
|
||||||
chanStream[i]->writeC(next);
|
|
||||||
next=reader->readC();
|
|
||||||
chanStream[i]->writeC(next);
|
|
||||||
next=reader->readC();
|
|
||||||
chanStream[i]->writeC(next);
|
|
||||||
break;
|
|
||||||
case 0xf0: { // full command (pre)
|
|
||||||
unsigned char cmd=reader->readC();
|
|
||||||
bool foundShort=false;
|
|
||||||
for (int j=0; j<16; j++) {
|
|
||||||
if (sortedCmd[j]==cmd) {
|
|
||||||
chanStream[i]->writeC(0xd0+j);
|
|
||||||
foundShort=true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (!foundShort) {
|
|
||||||
chanStream[i]->writeC(0xf7); // full command
|
|
||||||
chanStream[i]->writeC(cmd);
|
|
||||||
}
|
|
||||||
|
|
||||||
unsigned char cmdLen=reader->readC();
|
|
||||||
logD("cmdLen: %d",cmdLen);
|
|
||||||
for (unsigned char j=0; j<cmdLen; j++) {
|
|
||||||
next=reader->readC();
|
|
||||||
chanStream[i]->writeC(next);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case 0xfb: // tick rate
|
|
||||||
chanStream[i]->writeC(next);
|
|
||||||
next=reader->readC();
|
|
||||||
chanStream[i]->writeC(next);
|
|
||||||
next=reader->readC();
|
|
||||||
chanStream[i]->writeC(next);
|
|
||||||
next=reader->readC();
|
|
||||||
chanStream[i]->writeC(next);
|
|
||||||
next=reader->readC();
|
|
||||||
chanStream[i]->writeC(next);
|
|
||||||
break;
|
|
||||||
case 0xfc: { // 16-bit wait
|
|
||||||
unsigned short delay=reader->readS();
|
|
||||||
bool foundShort=false;
|
|
||||||
for (int j=0; j<16; j++) {
|
|
||||||
if (sortedDelay[j]==delay) {
|
|
||||||
chanStream[i]->writeC(0xe0+j);
|
|
||||||
foundShort=true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (!foundShort) {
|
|
||||||
chanStream[i]->writeC(next);
|
|
||||||
chanStream[i]->writeS(delay);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case 0xfd: { // 8-bit wait
|
|
||||||
unsigned char delay=reader->readC();
|
|
||||||
bool foundShort=false;
|
|
||||||
for (int j=0; j<16; j++) {
|
|
||||||
if (sortedDelay[j]==delay) {
|
|
||||||
chanStream[i]->writeC(0xe0+j);
|
|
||||||
foundShort=true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (!foundShort) {
|
|
||||||
chanStream[i]->writeC(next);
|
|
||||||
chanStream[i]->writeC(delay);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
default:
|
|
||||||
chanStream[i]->writeC(next);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
} catch (EndOfFileException& e) {
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
if (sortCand==-1) break;
|
||||||
|
|
||||||
oldStream->finish();
|
sortedDelayPopularity[sortPos]=delayPopularity[sortCand];
|
||||||
delete oldStream;
|
sortedDelay[sortPos]=sortCand;
|
||||||
|
delayPopularity[sortCand]=0;
|
||||||
|
sortPos++;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i=0; i<chans; i++) {
|
||||||
|
chanStream[i]->writeC(0xff);
|
||||||
|
// optimize stream
|
||||||
|
SafeWriter* oldStream=chanStream[i];
|
||||||
|
SafeReader* reader=oldStream->toReader();
|
||||||
|
chanStream[i]=new SafeWriter;
|
||||||
|
chanStream[i]->init();
|
||||||
|
|
||||||
|
while (1) {
|
||||||
|
try {
|
||||||
|
unsigned char next=reader->readC();
|
||||||
|
switch (next) {
|
||||||
|
case 0xb8: // instrument
|
||||||
|
case 0xc0: // pre porta
|
||||||
|
case 0xc3: // vibrato range
|
||||||
|
case 0xc4: // vibrato shape
|
||||||
|
case 0xc5: // pitch
|
||||||
|
case 0xc7: // volume
|
||||||
|
case 0xca: // legato
|
||||||
|
chanStream[i]->writeC(next);
|
||||||
|
next=reader->readC();
|
||||||
|
chanStream[i]->writeC(next);
|
||||||
|
break;
|
||||||
|
case 0xbe: // panning
|
||||||
|
case 0xc2: // vibrato
|
||||||
|
case 0xc6: // arpeggio
|
||||||
|
case 0xc8: // vol slide
|
||||||
|
case 0xc9: // porta
|
||||||
|
chanStream[i]->writeC(next);
|
||||||
|
next=reader->readC();
|
||||||
|
chanStream[i]->writeC(next);
|
||||||
|
next=reader->readC();
|
||||||
|
chanStream[i]->writeC(next);
|
||||||
|
break;
|
||||||
|
case 0xf0: { // full command (pre)
|
||||||
|
unsigned char cmd=reader->readC();
|
||||||
|
bool foundShort=false;
|
||||||
|
for (int j=0; j<16; j++) {
|
||||||
|
if (sortedCmd[j]==cmd) {
|
||||||
|
chanStream[i]->writeC(0xd0+j);
|
||||||
|
foundShort=true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!foundShort) {
|
||||||
|
chanStream[i]->writeC(0xf7); // full command
|
||||||
|
chanStream[i]->writeC(cmd);
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned char cmdLen=reader->readC();
|
||||||
|
logD("cmdLen: %d",cmdLen);
|
||||||
|
for (unsigned char j=0; j<cmdLen; j++) {
|
||||||
|
next=reader->readC();
|
||||||
|
chanStream[i]->writeC(next);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 0xfb: // tick rate
|
||||||
|
chanStream[i]->writeC(next);
|
||||||
|
next=reader->readC();
|
||||||
|
chanStream[i]->writeC(next);
|
||||||
|
next=reader->readC();
|
||||||
|
chanStream[i]->writeC(next);
|
||||||
|
next=reader->readC();
|
||||||
|
chanStream[i]->writeC(next);
|
||||||
|
next=reader->readC();
|
||||||
|
chanStream[i]->writeC(next);
|
||||||
|
break;
|
||||||
|
case 0xfc: { // 16-bit wait
|
||||||
|
unsigned short delay=reader->readS();
|
||||||
|
bool foundShort=false;
|
||||||
|
for (int j=0; j<16; j++) {
|
||||||
|
if (sortedDelay[j]==delay) {
|
||||||
|
chanStream[i]->writeC(0xe0+j);
|
||||||
|
foundShort=true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!foundShort) {
|
||||||
|
chanStream[i]->writeC(next);
|
||||||
|
chanStream[i]->writeS(delay);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 0xfd: { // 8-bit wait
|
||||||
|
unsigned char delay=reader->readC();
|
||||||
|
bool foundShort=false;
|
||||||
|
for (int j=0; j<16; j++) {
|
||||||
|
if (sortedDelay[j]==delay) {
|
||||||
|
chanStream[i]->writeC(0xe0+j);
|
||||||
|
foundShort=true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!foundShort) {
|
||||||
|
chanStream[i]->writeC(next);
|
||||||
|
chanStream[i]->writeC(delay);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
chanStream[i]->writeC(next);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
} catch (EndOfFileException& e) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int i=0; i<chans; i++) {
|
oldStream->finish();
|
||||||
chanStreamOff[i]=w->tell();
|
delete oldStream;
|
||||||
logI("- %d: off %x size %ld",i,chanStreamOff[i],chanStream[i]->size());
|
}
|
||||||
w->write(chanStream[i]->getFinalBuf(),chanStream[i]->size());
|
|
||||||
chanStream[i]->finish();
|
|
||||||
delete chanStream[i];
|
|
||||||
}
|
|
||||||
|
|
||||||
w->seek(8,SEEK_SET);
|
for (int i=0; i<chans; i++) {
|
||||||
for (int i=0; i<chans; i++) {
|
chanStreamOff[i]=w->tell();
|
||||||
w->writeI(chanStreamOff[i]);
|
logI("- %d: off %x size %ld",i,chanStreamOff[i],chanStream[i]->size());
|
||||||
}
|
w->write(chanStream[i]->getFinalBuf(),chanStream[i]->size());
|
||||||
|
chanStream[i]->finish();
|
||||||
|
delete chanStream[i];
|
||||||
|
}
|
||||||
|
|
||||||
logD("delay popularity:");
|
w->seek(8,SEEK_SET);
|
||||||
for (int i=0; i<16; i++) {
|
for (int i=0; i<chans; i++) {
|
||||||
w->writeC(sortedDelay[i]);
|
w->writeI(chanStreamOff[i]);
|
||||||
if (sortedDelayPopularity[i]) logD("- %d: %d",sortedDelay[i],sortedDelayPopularity[i]);
|
}
|
||||||
}
|
|
||||||
|
|
||||||
logD("command popularity:");
|
logD("delay popularity:");
|
||||||
for (int i=0; i<16; i++) {
|
for (int i=0; i<16; i++) {
|
||||||
w->writeC(sortedCmd[i]);
|
w->writeC(sortedDelay[i]);
|
||||||
if (sortedCmdPopularity[i]) logD("- %s: %d",cmdName[sortedCmd[i]],sortedCmdPopularity[i]);
|
if (sortedDelayPopularity[i]) logD("- %d: %d",sortedDelay[i],sortedDelayPopularity[i]);
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
if (!playing) {
|
logD("command popularity:");
|
||||||
w->writeText(">> END\n");
|
for (int i=0; i<16; i++) {
|
||||||
} else {
|
w->writeC(sortedCmd[i]);
|
||||||
w->writeText(">> LOOP 0\n");
|
if (sortedCmdPopularity[i]) logD("- %s: %d",cmdName[sortedCmd[i]],sortedCmdPopularity[i]);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
remainingLoops=-1;
|
remainingLoops=-1;
|
||||||
|
|
|
@ -655,7 +655,7 @@ class DivEngine {
|
||||||
// dump to ZSM.
|
// dump to ZSM.
|
||||||
SafeWriter* saveZSM(unsigned int zsmrate=60, bool loop=true, bool optimize=true);
|
SafeWriter* saveZSM(unsigned int zsmrate=60, bool loop=true, bool optimize=true);
|
||||||
// dump command stream.
|
// dump command stream.
|
||||||
SafeWriter* saveCommand(bool binary=false);
|
SafeWriter* saveCommand();
|
||||||
// export to text
|
// export to text
|
||||||
SafeWriter* saveText(bool separatePatterns=true);
|
SafeWriter* saveText(bool separatePatterns=true);
|
||||||
// export to an audio file
|
// export to an audio file
|
||||||
|
|
|
@ -44,7 +44,7 @@ void FurnaceGUI::drawCSPlayer() {
|
||||||
}
|
}
|
||||||
ImGui::SameLine();
|
ImGui::SameLine();
|
||||||
if (ImGui::Button("Burn Current Song")) {
|
if (ImGui::Button("Burn Current Song")) {
|
||||||
SafeWriter* w=e->saveCommand(true);
|
SafeWriter* w=e->saveCommand();
|
||||||
if (w!=NULL) {
|
if (w!=NULL) {
|
||||||
if (!e->playStream(w->getFinalBuf(),w->size())) {
|
if (!e->playStream(w->getFinalBuf(),w->size())) {
|
||||||
showError(e->getLastError());
|
showError(e->getLastError());
|
||||||
|
|
|
@ -242,15 +242,10 @@ void FurnaceGUI::drawExportCommand(bool onWindow) {
|
||||||
);
|
);
|
||||||
if (onWindow) {
|
if (onWindow) {
|
||||||
ImGui::Separator();
|
ImGui::Separator();
|
||||||
if (ImGui::Button("Cancel",ImVec2(133.3f*dpiScale,0))) ImGui::CloseCurrentPopup();
|
if (ImGui::Button("Cancel",ImVec2(200.0f*dpiScale,0))) ImGui::CloseCurrentPopup();
|
||||||
ImGui::SameLine();
|
ImGui::SameLine();
|
||||||
}
|
}
|
||||||
if (ImGui::Button("Export (binary)",ImVec2(133.3f*dpiScale,0))) {
|
if (ImGui::Button("Export",ImVec2(200.0f*dpiScale,0))) {
|
||||||
openFileDialog(GUI_FILE_EXPORT_CMDSTREAM_BINARY);
|
|
||||||
ImGui::CloseCurrentPopup();
|
|
||||||
}
|
|
||||||
ImGui::SameLine();
|
|
||||||
if (ImGui::Button("Export (text)",ImVec2(133.3f*dpiScale,0))) {
|
|
||||||
openFileDialog(GUI_FILE_EXPORT_CMDSTREAM);
|
openFileDialog(GUI_FILE_EXPORT_CMDSTREAM);
|
||||||
ImGui::CloseCurrentPopup();
|
ImGui::CloseCurrentPopup();
|
||||||
}
|
}
|
||||||
|
|
|
@ -1894,15 +1894,6 @@ void FurnaceGUI::openFileDialog(FurnaceGUIFileDialogs type) {
|
||||||
);
|
);
|
||||||
break;
|
break;
|
||||||
case GUI_FILE_EXPORT_CMDSTREAM:
|
case GUI_FILE_EXPORT_CMDSTREAM:
|
||||||
if (!dirExists(workingDirROMExport)) workingDirROMExport=getHomeDir();
|
|
||||||
hasOpened=fileDialog->openSave(
|
|
||||||
"Export Command Stream",
|
|
||||||
{"text file", "*.txt"},
|
|
||||||
workingDirROMExport,
|
|
||||||
dpiScale
|
|
||||||
);
|
|
||||||
break;
|
|
||||||
case GUI_FILE_EXPORT_CMDSTREAM_BINARY:
|
|
||||||
if (!dirExists(workingDirROMExport)) workingDirROMExport=getHomeDir();
|
if (!dirExists(workingDirROMExport)) workingDirROMExport=getHomeDir();
|
||||||
hasOpened=fileDialog->openSave(
|
hasOpened=fileDialog->openSave(
|
||||||
"Export Command Stream",
|
"Export Command Stream",
|
||||||
|
@ -4829,7 +4820,6 @@ bool FurnaceGUI::loop() {
|
||||||
case GUI_FILE_EXPORT_ROM:
|
case GUI_FILE_EXPORT_ROM:
|
||||||
case GUI_FILE_EXPORT_TEXT:
|
case GUI_FILE_EXPORT_TEXT:
|
||||||
case GUI_FILE_EXPORT_CMDSTREAM:
|
case GUI_FILE_EXPORT_CMDSTREAM:
|
||||||
case GUI_FILE_EXPORT_CMDSTREAM_BINARY:
|
|
||||||
workingDirROMExport=fileDialog->getPath()+DIR_SEPARATOR_STR;
|
workingDirROMExport=fileDialog->getPath()+DIR_SEPARATOR_STR;
|
||||||
break;
|
break;
|
||||||
case GUI_FILE_LOAD_MAIN_FONT:
|
case GUI_FILE_LOAD_MAIN_FONT:
|
||||||
|
@ -4919,10 +4909,10 @@ bool FurnaceGUI::loop() {
|
||||||
if (curFileDialog==GUI_FILE_EXPORT_ZSM) {
|
if (curFileDialog==GUI_FILE_EXPORT_ZSM) {
|
||||||
checkExtension(".zsm");
|
checkExtension(".zsm");
|
||||||
}
|
}
|
||||||
if (curFileDialog==GUI_FILE_EXPORT_CMDSTREAM || curFileDialog==GUI_FILE_EXPORT_TEXT) {
|
if (curFileDialog==GUI_FILE_EXPORT_TEXT) {
|
||||||
checkExtension(".txt");
|
checkExtension(".txt");
|
||||||
}
|
}
|
||||||
if (curFileDialog==GUI_FILE_EXPORT_CMDSTREAM_BINARY) {
|
if (curFileDialog==GUI_FILE_EXPORT_CMDSTREAM) {
|
||||||
checkExtension(".bin");
|
checkExtension(".bin");
|
||||||
}
|
}
|
||||||
if (curFileDialog==GUI_FILE_EXPORT_COLORS) {
|
if (curFileDialog==GUI_FILE_EXPORT_COLORS) {
|
||||||
|
@ -5316,11 +5306,8 @@ bool FurnaceGUI::loop() {
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case GUI_FILE_EXPORT_CMDSTREAM:
|
case GUI_FILE_EXPORT_CMDSTREAM: {
|
||||||
case GUI_FILE_EXPORT_CMDSTREAM_BINARY: {
|
SafeWriter* w=e->saveCommand();
|
||||||
bool isBinary=(curFileDialog==GUI_FILE_EXPORT_CMDSTREAM_BINARY);
|
|
||||||
|
|
||||||
SafeWriter* w=e->saveCommand(isBinary);
|
|
||||||
if (w!=NULL) {
|
if (w!=NULL) {
|
||||||
FILE* f=ps_fopen(copyOfName.c_str(),"wb");
|
FILE* f=ps_fopen(copyOfName.c_str(),"wb");
|
||||||
if (f!=NULL) {
|
if (f!=NULL) {
|
||||||
|
|
|
@ -537,7 +537,6 @@ enum FurnaceGUIFileDialogs {
|
||||||
GUI_FILE_EXPORT_VGM,
|
GUI_FILE_EXPORT_VGM,
|
||||||
GUI_FILE_EXPORT_ZSM,
|
GUI_FILE_EXPORT_ZSM,
|
||||||
GUI_FILE_EXPORT_CMDSTREAM,
|
GUI_FILE_EXPORT_CMDSTREAM,
|
||||||
GUI_FILE_EXPORT_CMDSTREAM_BINARY,
|
|
||||||
GUI_FILE_EXPORT_TEXT,
|
GUI_FILE_EXPORT_TEXT,
|
||||||
GUI_FILE_EXPORT_ROM,
|
GUI_FILE_EXPORT_ROM,
|
||||||
GUI_FILE_LOAD_MAIN_FONT,
|
GUI_FILE_LOAD_MAIN_FONT,
|
||||||
|
|
|
@ -72,7 +72,6 @@ bool consoleMode=true;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
bool displayEngineFailError=false;
|
bool displayEngineFailError=false;
|
||||||
bool cmdOutBinary=false;
|
|
||||||
bool vgmOutDirect=false;
|
bool vgmOutDirect=false;
|
||||||
|
|
||||||
bool safeMode=false;
|
bool safeMode=false;
|
||||||
|
@ -153,11 +152,6 @@ TAParamResult pSafeModeAudio(String val) {
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
TAParamResult pBinary(String val) {
|
|
||||||
cmdOutBinary=true;
|
|
||||||
return TA_PARAM_SUCCESS;
|
|
||||||
}
|
|
||||||
|
|
||||||
TAParamResult pDirect(String val) {
|
TAParamResult pDirect(String val) {
|
||||||
vgmOutDirect=true;
|
vgmOutDirect=true;
|
||||||
return TA_PARAM_SUCCESS;
|
return TA_PARAM_SUCCESS;
|
||||||
|
@ -373,7 +367,6 @@ void initParams() {
|
||||||
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("Z","zsmout",true,pZSMOut,"<filename>","output .zsm data for Commander X16 Zsound"));
|
params.push_back(TAParam("Z","zsmout",true,pZSMOut,"<filename>","output .zsm data for Commander X16 Zsound"));
|
||||||
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("b","binary",false,pBinary,"","set command stream output format to binary"));
|
|
||||||
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)"));
|
||||||
params.push_back(TAParam("i","info",false,pInfo,"","get info about a song"));
|
params.push_back(TAParam("i","info",false,pInfo,"","get info about a song"));
|
||||||
|
@ -660,7 +653,7 @@ int main(int argc, char** argv) {
|
||||||
|
|
||||||
if (outName!="" || vgmOutName!="" || cmdOutName!="") {
|
if (outName!="" || vgmOutName!="" || cmdOutName!="") {
|
||||||
if (cmdOutName!="") {
|
if (cmdOutName!="") {
|
||||||
SafeWriter* w=e.saveCommand(cmdOutBinary);
|
SafeWriter* w=e.saveCommand();
|
||||||
if (w!=NULL) {
|
if (w!=NULL) {
|
||||||
FILE* f=fopen(cmdOutName.c_str(),"wb");
|
FILE* f=fopen(cmdOutName.c_str(),"wb");
|
||||||
if (f!=NULL) {
|
if (f!=NULL) {
|
||||||
|
|
Loading…
Reference in a new issue