Merge branch 'tildearrow:master' into SID3
This commit is contained in:
commit
d38a2b4f37
BIN
demos/a2600/TIADeepIntoCode.fur
Normal file
BIN
demos/a2600/TIADeepIntoCode.fur
Normal file
Binary file not shown.
BIN
demos/a2600/Watch My Tone.fur
Normal file
BIN
demos/a2600/Watch My Tone.fur
Normal file
Binary file not shown.
BIN
demos/genesis/imaginarium.fur
Normal file
BIN
demos/genesis/imaginarium.fur
Normal file
Binary file not shown.
BIN
demos/opl/I won't be there again (Extended Mix).fur
Normal file
BIN
demos/opl/I won't be there again (Extended Mix).fur
Normal file
Binary file not shown.
|
@ -697,9 +697,8 @@ class DivEngine {
|
||||||
// save as .fur.
|
// save as .fur.
|
||||||
// if notPrimary is true then the song will not be altered
|
// if notPrimary is true then the song will not be altered
|
||||||
SafeWriter* saveFur(bool notPrimary=false, bool newPatternFormat=true);
|
SafeWriter* saveFur(bool notPrimary=false, bool newPatternFormat=true);
|
||||||
// build a ROM file (TODO).
|
// return a ROM exporter.
|
||||||
// specify system to build ROM for.
|
DivROMExport* buildROM(DivROMExportOptions sys);
|
||||||
std::vector<DivROMExportOutput> buildROM(DivROMExportOptions sys);
|
|
||||||
// dump to VGM.
|
// dump to VGM.
|
||||||
// set trailingTicks to:
|
// set trailingTicks to:
|
||||||
// - 0 to add one tick of trailing
|
// - 0 to add one tick of trailing
|
||||||
|
|
|
@ -21,7 +21,7 @@
|
||||||
|
|
||||||
#include "export/amigaValidation.h"
|
#include "export/amigaValidation.h"
|
||||||
|
|
||||||
std::vector<DivROMExportOutput> DivEngine::buildROM(DivROMExportOptions sys) {
|
DivROMExport* DivEngine::buildROM(DivROMExportOptions sys) {
|
||||||
DivROMExport* exporter=NULL;
|
DivROMExport* exporter=NULL;
|
||||||
switch (sys) {
|
switch (sys) {
|
||||||
case DIV_ROM_AMIGA_VALIDATION:
|
case DIV_ROM_AMIGA_VALIDATION:
|
||||||
|
@ -31,7 +31,5 @@ std::vector<DivROMExportOutput> DivEngine::buildROM(DivROMExportOptions sys) {
|
||||||
exporter=new DivROMExport;
|
exporter=new DivROMExport;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
std::vector<DivROMExportOutput> ret=exporter->go(this);
|
return exporter;
|
||||||
delete exporter;
|
|
||||||
return ret;
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -45,9 +45,25 @@ struct DivROMExportOutput {
|
||||||
data(NULL) {}
|
data(NULL) {}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct DivROMExportProgress {
|
||||||
|
String name;
|
||||||
|
float amount;
|
||||||
|
};
|
||||||
|
|
||||||
class DivROMExport {
|
class DivROMExport {
|
||||||
|
protected:
|
||||||
|
std::vector<String> exportLog;
|
||||||
|
std::vector<DivROMExportOutput> output;
|
||||||
|
std::mutex logLock;
|
||||||
|
void logAppend(String what);
|
||||||
public:
|
public:
|
||||||
virtual std::vector<DivROMExportOutput> go(DivEngine* e);
|
virtual bool go(DivEngine* eng);
|
||||||
|
virtual void abort();
|
||||||
|
virtual void wait();
|
||||||
|
std::vector<DivROMExportOutput>& getResult();
|
||||||
|
virtual bool hasFailed();
|
||||||
|
virtual bool isRunning();
|
||||||
|
virtual DivROMExportProgress getProgress();
|
||||||
virtual ~DivROMExport() {}
|
virtual ~DivROMExport() {}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -20,7 +20,38 @@
|
||||||
#include "../export.h"
|
#include "../export.h"
|
||||||
#include "../../ta-log.h"
|
#include "../../ta-log.h"
|
||||||
|
|
||||||
std::vector<DivROMExportOutput> DivROMExport::go(DivEngine* e) {
|
bool DivROMExport::go(DivEngine* eng) {
|
||||||
logW("what's this? the null ROM export?");
|
logW("what's this? the null ROM export?");
|
||||||
return std::vector<DivROMExportOutput>();
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void DivROMExport::abort() {
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<DivROMExportOutput>& DivROMExport::getResult() {
|
||||||
|
return output;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool DivROMExport::hasFailed() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
DivROMExportProgress DivROMExport::getProgress() {
|
||||||
|
DivROMExportProgress ret;
|
||||||
|
ret.name="Test";
|
||||||
|
ret.amount=0.0f;
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
void DivROMExport::logAppend(String what) {
|
||||||
|
logLock.lock();
|
||||||
|
exportLog.push_back(what);
|
||||||
|
logLock.unlock();
|
||||||
|
}
|
||||||
|
|
||||||
|
void DivROMExport::wait() {
|
||||||
|
}
|
||||||
|
|
||||||
|
bool DivROMExport::isRunning() {
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
|
@ -40,8 +40,7 @@ struct SampleBookEntry {
|
||||||
len(0) {}
|
len(0) {}
|
||||||
};
|
};
|
||||||
|
|
||||||
std::vector<DivROMExportOutput> DivExportAmigaValidation::go(DivEngine* e) {
|
void DivExportAmigaValidation::run() {
|
||||||
std::vector<DivROMExportOutput> ret;
|
|
||||||
std::vector<WaveEntry> waves;
|
std::vector<WaveEntry> waves;
|
||||||
std::vector<SampleBookEntry> sampleBook;
|
std::vector<SampleBookEntry> sampleBook;
|
||||||
unsigned int wavesDataPtr=0;
|
unsigned int wavesDataPtr=0;
|
||||||
|
@ -266,12 +265,34 @@ std::vector<DivROMExportOutput> DivExportAmigaValidation::go(DivEngine* e) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// finish
|
// finish
|
||||||
ret.reserve(5);
|
output.reserve(5);
|
||||||
ret.push_back(DivROMExportOutput("sbook.bin",sbook));
|
output.push_back(DivROMExportOutput("sbook.bin",sbook));
|
||||||
ret.push_back(DivROMExportOutput("wbook.bin",wbook));
|
output.push_back(DivROMExportOutput("wbook.bin",wbook));
|
||||||
ret.push_back(DivROMExportOutput("sample.bin",sample));
|
output.push_back(DivROMExportOutput("sample.bin",sample));
|
||||||
ret.push_back(DivROMExportOutput("wave.bin",wave));
|
output.push_back(DivROMExportOutput("wave.bin",wave));
|
||||||
ret.push_back(DivROMExportOutput("seq.bin",seq));
|
output.push_back(DivROMExportOutput("seq.bin",seq));
|
||||||
|
|
||||||
return ret;
|
running=false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool DivExportAmigaValidation::go(DivEngine* eng) {
|
||||||
|
e=eng;
|
||||||
|
running=true;
|
||||||
|
exportThread=new std::thread(&DivExportAmigaValidation::run,this);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void DivExportAmigaValidation::wait() {
|
||||||
|
if (exportThread!=NULL) {
|
||||||
|
exportThread->join();
|
||||||
|
delete exportThread;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void DivExportAmigaValidation::abort() {
|
||||||
|
wait();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool DivExportAmigaValidation::isRunning() {
|
||||||
|
return running;
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,8 +19,17 @@
|
||||||
|
|
||||||
#include "../export.h"
|
#include "../export.h"
|
||||||
|
|
||||||
|
#include <thread>
|
||||||
|
|
||||||
class DivExportAmigaValidation: public DivROMExport {
|
class DivExportAmigaValidation: public DivROMExport {
|
||||||
|
DivEngine* e;
|
||||||
|
std::thread* exportThread;
|
||||||
|
bool running;
|
||||||
|
void run();
|
||||||
public:
|
public:
|
||||||
std::vector<DivROMExportOutput> go(DivEngine* e);
|
bool go(DivEngine* e);
|
||||||
|
bool isRunning();
|
||||||
|
void abort();
|
||||||
|
void wait();
|
||||||
~DivExportAmigaValidation() {}
|
~DivExportAmigaValidation() {}
|
||||||
};
|
};
|
||||||
|
|
|
@ -651,7 +651,7 @@ void DivPlatformGB::reset() {
|
||||||
immWrite(0x26,0x8f);
|
immWrite(0x26,0x8f);
|
||||||
lastPan=0xff;
|
lastPan=0xff;
|
||||||
immWrite(0x25,procMute());
|
immWrite(0x25,procMute());
|
||||||
immWrite(0x24,0x77);
|
immWrite(0x24,0xff);
|
||||||
|
|
||||||
antiClickPeriodCount=0;
|
antiClickPeriodCount=0;
|
||||||
antiClickWavePos=0;
|
antiClickWavePos=0;
|
||||||
|
|
|
@ -26,53 +26,107 @@
|
||||||
#include "../ta-log.h"
|
#include "../ta-log.h"
|
||||||
|
|
||||||
struct TiunaNew {
|
struct TiunaNew {
|
||||||
short pitch=-1;
|
short pitch;
|
||||||
signed char ins=-1;
|
signed char ins;
|
||||||
signed char vol=-1;
|
signed char vol;
|
||||||
short sync=-1;
|
short sync;
|
||||||
|
TiunaNew():
|
||||||
|
pitch(-1),
|
||||||
|
ins(-1),
|
||||||
|
vol(-1),
|
||||||
|
sync(-1) {}
|
||||||
};
|
};
|
||||||
|
|
||||||
struct TiunaLast {
|
struct TiunaLast {
|
||||||
short pitch=0;
|
short pitch;
|
||||||
signed char ins=0;
|
signed char ins;
|
||||||
signed char vol=0;
|
signed char vol;
|
||||||
int tick=1;
|
int tick;
|
||||||
bool forcePitch=true;
|
bool forcePitch;
|
||||||
|
TiunaLast():
|
||||||
|
pitch(0),
|
||||||
|
ins(0),
|
||||||
|
vol(0),
|
||||||
|
tick(1),
|
||||||
|
forcePitch(true) {}
|
||||||
};
|
};
|
||||||
|
|
||||||
struct TiunaCmd {
|
struct TiunaCmd {
|
||||||
signed char pitchChange=-1;
|
signed char pitchChange;
|
||||||
short pitchSet=-1;
|
short pitchSet;
|
||||||
signed char ins=-1;
|
signed char ins;
|
||||||
signed char vol=-1;
|
signed char vol;
|
||||||
short sync=-1;
|
short sync;
|
||||||
short wait=-1;
|
short wait;
|
||||||
|
TiunaCmd():
|
||||||
|
pitchChange(-1),
|
||||||
|
pitchSet(-1),
|
||||||
|
ins(-1),
|
||||||
|
vol(-1),
|
||||||
|
sync(-1),
|
||||||
|
wait(-1) {}
|
||||||
};
|
};
|
||||||
|
|
||||||
struct TiunaBytes {
|
struct TiunaBytes {
|
||||||
unsigned char ch=0;
|
unsigned char ch;
|
||||||
int ticks=0;
|
int ticks;
|
||||||
unsigned char size=0;
|
unsigned char size;
|
||||||
unsigned char buf[16];
|
unsigned char buf[16];
|
||||||
friend bool operator==(const TiunaBytes& l, const TiunaBytes& r) {
|
friend bool operator==(const TiunaBytes& l, const TiunaBytes& r) {
|
||||||
if (l.size!=r.size) return false;
|
if (l.size!=r.size) return false;
|
||||||
if (l.ticks!=r.ticks) return false;
|
if (l.ticks!=r.ticks) return false;
|
||||||
return memcmp(l.buf,r.buf,l.size)==0;
|
return memcmp(l.buf,r.buf,l.size)==0;
|
||||||
}
|
}
|
||||||
|
TiunaBytes(unsigned char c, int t, unsigned char s, std::initializer_list<unsigned char> b):
|
||||||
|
ch(c),
|
||||||
|
ticks(t),
|
||||||
|
size(s) {
|
||||||
|
// because C++14 does not support data() on initializer_list
|
||||||
|
unsigned char p=0;
|
||||||
|
for (unsigned char i: b) {
|
||||||
|
buf[p++]=i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
TiunaBytes():
|
||||||
|
ch(0),
|
||||||
|
ticks(0),
|
||||||
|
size(0) {
|
||||||
|
memset(buf,0,16);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
struct TiunaMatch {
|
struct TiunaMatch {
|
||||||
int pos;
|
int pos;
|
||||||
int endPos;
|
int endPos;
|
||||||
int size;
|
int size;
|
||||||
int id;
|
int id;
|
||||||
|
TiunaMatch(int p, int ep, int s, int _i):
|
||||||
|
pos(p),
|
||||||
|
endPos(ep),
|
||||||
|
size(s),
|
||||||
|
id(_i) {}
|
||||||
|
TiunaMatch():
|
||||||
|
pos(0),
|
||||||
|
endPos(0),
|
||||||
|
size(0),
|
||||||
|
id(0) {}
|
||||||
};
|
};
|
||||||
|
|
||||||
struct TiunaMatches {
|
struct TiunaMatches {
|
||||||
int bytesSaved=INT32_MIN;
|
int bytesSaved;
|
||||||
int length=0;
|
int length;
|
||||||
int ticks=0;
|
int ticks;
|
||||||
std::vector<int> pos;
|
std::vector<int> pos;
|
||||||
|
TiunaMatches():
|
||||||
|
bytesSaved(INT32_MIN),
|
||||||
|
length(0),
|
||||||
|
ticks(0) {}
|
||||||
};
|
};
|
||||||
|
|
||||||
static void writeCmd(std::vector<TiunaBytes>& cmds, TiunaCmd& cmd, unsigned char ch, int& lastWait, int fromTick, int toTick) {
|
static void writeCmd(std::vector<TiunaBytes>& cmds, TiunaCmd& cmd, unsigned char ch, int& lastWait, int fromTick, int toTick) {
|
||||||
while (fromTick<toTick) {
|
while (fromTick<toTick) {
|
||||||
int val=MIN(toTick-fromTick,256);
|
int val=MIN(toTick-fromTick,256);
|
||||||
|
assert(val>0);
|
||||||
if (lastWait!=val) {
|
if (lastWait!=val) {
|
||||||
cmd.wait=val;
|
cmd.wait=val;
|
||||||
lastWait=val;
|
lastWait=val;
|
||||||
|
@ -293,9 +347,13 @@ SafeWriter* DivEngine::saveTiuna(const bool* sysToExport, const char* baseLabel,
|
||||||
std::vector<int> callTicks;
|
std::vector<int> callTicks;
|
||||||
int cmId=0;
|
int cmId=0;
|
||||||
int cmdSize=renderedCmds.size();
|
int cmdSize=renderedCmds.size();
|
||||||
std::vector<bool> processed=std::vector<bool>(cmdSize,false);
|
bool* processed=new bool[cmdSize];
|
||||||
|
memset(processed,0,cmdSize*sizeof(bool));
|
||||||
|
logI("max cmId: %d",(MAX(firstBankSize/1024,1))*256);
|
||||||
while (firstBankSize>768 && cmId<(MAX(firstBankSize/1024,1))*256) {
|
while (firstBankSize>768 && cmId<(MAX(firstBankSize/1024,1))*256) {
|
||||||
|
logI("start CM %04x...",cmId);
|
||||||
std::map<int,TiunaMatches> potentialMatches;
|
std::map<int,TiunaMatches> potentialMatches;
|
||||||
|
logD("scan %d size...",cmdSize-1);
|
||||||
for (int i=0; i<cmdSize-1;) {
|
for (int i=0; i<cmdSize-1;) {
|
||||||
// continue and skip if it's part of previous confirmed matches
|
// continue and skip if it's part of previous confirmed matches
|
||||||
while (i<cmdSize-1 && processed[i]) i++;
|
while (i<cmdSize-1 && processed[i]) i++;
|
||||||
|
@ -303,7 +361,8 @@ SafeWriter* DivEngine::saveTiuna(const bool* sysToExport, const char* baseLabel,
|
||||||
std::vector<TiunaMatch> match;
|
std::vector<TiunaMatch> match;
|
||||||
int ch=renderedCmds[i].ch;
|
int ch=renderedCmds[i].ch;
|
||||||
for (int j=i+1; j<cmdSize;) {
|
for (int j=i+1; j<cmdSize;) {
|
||||||
while (j<cmdSize && processed[i]) j++;
|
if (processed[i]) break;
|
||||||
|
//while (j<cmdSize && processed[i]) j++;
|
||||||
if (j>=cmdSize) break;
|
if (j>=cmdSize) break;
|
||||||
int k=0;
|
int k=0;
|
||||||
int ticks=0;
|
int ticks=0;
|
||||||
|
@ -322,7 +381,7 @@ SafeWriter* DivEngine::saveTiuna(const bool* sysToExport, const char* baseLabel,
|
||||||
size+=renderedCmds[i+k].size;
|
size+=renderedCmds[i+k].size;
|
||||||
k++;
|
k++;
|
||||||
}
|
}
|
||||||
if (size>2) match.push_back({j,j+k,size,0});
|
if (size>2) match.push_back(TiunaMatch(j,j+k,size,0));
|
||||||
if (k==0) k++;
|
if (k==0) k++;
|
||||||
j+=k;
|
j+=k;
|
||||||
}
|
}
|
||||||
|
@ -367,9 +426,13 @@ SafeWriter* DivEngine::saveTiuna(const bool* sysToExport, const char* baseLabel,
|
||||||
}
|
}
|
||||||
i++;
|
i++;
|
||||||
}
|
}
|
||||||
if (potentialMatches.empty()) break;
|
if (potentialMatches.empty()) {
|
||||||
|
logV("potentialMatches is empty");
|
||||||
|
break;
|
||||||
|
}
|
||||||
int maxPMIdx=0;
|
int maxPMIdx=0;
|
||||||
int maxPMVal=0;
|
int maxPMVal=0;
|
||||||
|
logV("looking through potentialMatches...");
|
||||||
for (const auto& i: potentialMatches) {
|
for (const auto& i: potentialMatches) {
|
||||||
if (i.second.bytesSaved>maxPMVal) {
|
if (i.second.bytesSaved>maxPMVal) {
|
||||||
maxPMVal=i.second.bytesSaved;
|
maxPMVal=i.second.bytesSaved;
|
||||||
|
@ -377,14 +440,17 @@ SafeWriter* DivEngine::saveTiuna(const bool* sysToExport, const char* baseLabel,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
int maxPMLen=potentialMatches[maxPMIdx].length;
|
int maxPMLen=potentialMatches[maxPMIdx].length;
|
||||||
|
logV("the other step...");
|
||||||
for (const int i: potentialMatches[maxPMIdx].pos) {
|
for (const int i: potentialMatches[maxPMIdx].pos) {
|
||||||
confirmedMatches.push_back({i,i+maxPMLen,0,cmId});
|
confirmedMatches.push_back({i,i+maxPMLen,0,cmId});
|
||||||
std::fill(processed.begin()+i,processed.begin()+(i+maxPMLen),true);
|
memset(processed+i,1,maxPMLen);
|
||||||
|
//std::fill(processed.begin()+i,processed.begin()+(i+maxPMLen),true);
|
||||||
}
|
}
|
||||||
callTicks.push_back(potentialMatches[maxPMIdx].ticks);
|
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);
|
logI("CM %04x added: pos=%d,len=%d,matches=%d,saved=%d",cmId,maxPMIdx,maxPMLen,potentialMatches[maxPMIdx].pos.size(),maxPMVal);
|
||||||
cmId++;
|
cmId++;
|
||||||
}
|
}
|
||||||
|
delete[] processed;
|
||||||
std::sort(confirmedMatches.begin(),confirmedMatches.end(),[](const TiunaMatch& l, const TiunaMatch& r){
|
std::sort(confirmedMatches.begin(),confirmedMatches.end(),[](const TiunaMatch& l, const TiunaMatch& r){
|
||||||
return l.pos<r.pos;
|
return l.pos<r.pos;
|
||||||
});
|
});
|
||||||
|
@ -462,7 +528,7 @@ SafeWriter* DivEngine::saveTiuna(const bool* sysToExport, const char* baseLabel,
|
||||||
if (callVisited[cmIter->id]) {
|
if (callVisited[cmIter->id]) {
|
||||||
unsigned char idLo=cmIter->id&0xff;
|
unsigned char idLo=cmIter->id&0xff;
|
||||||
unsigned char idHi=cmIter->id>>8;
|
unsigned char idHi=cmIter->id>>8;
|
||||||
cmd={cmd.ch,0,2,{idHi,idLo}};
|
cmd=TiunaBytes(cmd.ch,0,2,{idHi,idLo});
|
||||||
i=cmIter->endPos-1;
|
i=cmIter->endPos-1;
|
||||||
} else {
|
} else {
|
||||||
writeCall=cmIter->id;
|
writeCall=cmIter->id;
|
||||||
|
@ -508,11 +574,11 @@ SafeWriter* DivEngine::saveTiuna(const bool* sysToExport, const char* baseLabel,
|
||||||
totalSize++;
|
totalSize++;
|
||||||
logI("total size: %d bytes (%d banks)",totalSize,curBank+1);
|
logI("total size: %d bytes (%d banks)",totalSize,curBank+1);
|
||||||
|
|
||||||
FILE* f=ps_fopen("confirmedMatches.txt","wb");
|
//FILE* f=ps_fopen("confirmedMatches.txt","wb");
|
||||||
if (f!=NULL) {
|
//if (f!=NULL) {
|
||||||
fwrite(dbg.getFinalBuf(),1,dbg.size(),f);
|
// fwrite(dbg.getFinalBuf(),1,dbg.size(),f);
|
||||||
fclose(f);
|
// fclose(f);
|
||||||
}
|
//}
|
||||||
|
|
||||||
return w;
|
return w;
|
||||||
}
|
}
|
||||||
|
|
|
@ -619,41 +619,6 @@ void FurnaceGUI::drawMobileControls() {
|
||||||
if (ImGui::Button(_("Switch to Desktop Mode"))) {
|
if (ImGui::Button(_("Switch to Desktop Mode"))) {
|
||||||
toggleMobileUI(!mobileUI);
|
toggleMobileUI(!mobileUI);
|
||||||
}
|
}
|
||||||
|
|
||||||
int numAmiga=0;
|
|
||||||
for (int i=0; i<e->song.systemLen; i++) {
|
|
||||||
if (e->song.system[i]==DIV_SYSTEM_AMIGA) numAmiga++;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (numAmiga) {
|
|
||||||
ImGui::Text(_(
|
|
||||||
"this is NOT ROM export! only use for making sure the\n"
|
|
||||||
"Furnace Amiga emulator is working properly by\n"
|
|
||||||
"comparing it with real Amiga output."
|
|
||||||
));
|
|
||||||
ImGui::AlignTextToFramePadding();
|
|
||||||
ImGui::Text(_("Directory"));
|
|
||||||
ImGui::SameLine();
|
|
||||||
ImGui::InputText("##AVDPath",&workingDirROMExport);
|
|
||||||
if (ImGui::Button(_("Bake Data"))) {
|
|
||||||
std::vector<DivROMExportOutput> out=e->buildROM(DIV_ROM_AMIGA_VALIDATION);
|
|
||||||
if (workingDirROMExport.size()>0) {
|
|
||||||
if (workingDirROMExport[workingDirROMExport.size()-1]!=DIR_SEPARATOR) workingDirROMExport+=DIR_SEPARATOR_STR;
|
|
||||||
}
|
|
||||||
for (DivROMExportOutput& i: out) {
|
|
||||||
String path=workingDirROMExport+i.name;
|
|
||||||
FILE* outFile=ps_fopen(path.c_str(),"wb");
|
|
||||||
if (outFile!=NULL) {
|
|
||||||
fwrite(i.data->getFinalBuf(),1,i.data->size(),outFile);
|
|
||||||
fclose(outFile);
|
|
||||||
}
|
|
||||||
i.data->finish();
|
|
||||||
delete i.data;
|
|
||||||
}
|
|
||||||
showError(fmt::sprintf(_("Done! Baked %d files."),(int)out.size()));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -329,21 +329,31 @@ void FurnaceGUI::drawExportAmigaVal(bool onWindow) {
|
||||||
ImGui::SameLine();
|
ImGui::SameLine();
|
||||||
}
|
}
|
||||||
if (ImGui::Button(_("Bake Data"),ImVec2(200.0f*dpiScale,0))) {
|
if (ImGui::Button(_("Bake Data"),ImVec2(200.0f*dpiScale,0))) {
|
||||||
std::vector<DivROMExportOutput> out=e->buildROM(DIV_ROM_AMIGA_VALIDATION);
|
DivROMExport* ex=e->buildROM(DIV_ROM_AMIGA_VALIDATION);
|
||||||
if (workingDirROMExport.size()>0) {
|
if (ex->go(e)) {
|
||||||
if (workingDirROMExport[workingDirROMExport.size()-1]!=DIR_SEPARATOR) workingDirROMExport+=DIR_SEPARATOR_STR;
|
ex->wait();
|
||||||
}
|
if (ex->hasFailed()) {
|
||||||
for (DivROMExportOutput& i: out) {
|
showError("error!");
|
||||||
String path=workingDirROMExport+i.name;
|
} else {
|
||||||
FILE* outFile=ps_fopen(path.c_str(),"wb");
|
if (workingDirROMExport.size()>0) {
|
||||||
if (outFile!=NULL) {
|
if (workingDirROMExport[workingDirROMExport.size()-1]!=DIR_SEPARATOR) workingDirROMExport+=DIR_SEPARATOR_STR;
|
||||||
fwrite(i.data->getFinalBuf(),1,i.data->size(),outFile);
|
}
|
||||||
fclose(outFile);
|
for (DivROMExportOutput& i: ex->getResult()) {
|
||||||
|
String path=workingDirROMExport+i.name;
|
||||||
|
FILE* outFile=ps_fopen(path.c_str(),"wb");
|
||||||
|
if (outFile!=NULL) {
|
||||||
|
fwrite(i.data->getFinalBuf(),1,i.data->size(),outFile);
|
||||||
|
fclose(outFile);
|
||||||
|
}
|
||||||
|
i.data->finish();
|
||||||
|
delete i.data;
|
||||||
|
}
|
||||||
|
showError(fmt::sprintf(_("Done! Baked %d files."),(int)ex->getResult().size()));
|
||||||
}
|
}
|
||||||
i.data->finish();
|
} else {
|
||||||
delete i.data;
|
showError("error!");
|
||||||
}
|
}
|
||||||
showError(fmt::sprintf(_("Done! Baked %d files."),(int)out.size()));
|
delete ex;
|
||||||
ImGui::CloseCurrentPopup();
|
ImGui::CloseCurrentPopup();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
76
src/main.cpp
76
src/main.cpp
|
@ -87,6 +87,7 @@ String outName;
|
||||||
String vgmOutName;
|
String vgmOutName;
|
||||||
String zsmOutName;
|
String zsmOutName;
|
||||||
String cmdOutName;
|
String cmdOutName;
|
||||||
|
String tiunaOutName;
|
||||||
int benchMode=0;
|
int benchMode=0;
|
||||||
int subsong=-1;
|
int subsong=-1;
|
||||||
DivAudioExportOptions exportOptions;
|
DivAudioExportOptions exportOptions;
|
||||||
|
@ -109,6 +110,11 @@ bool safeModeWithAudio=false;
|
||||||
|
|
||||||
bool infoMode=false;
|
bool infoMode=false;
|
||||||
|
|
||||||
|
bool noReportError=false;
|
||||||
|
|
||||||
|
int tiunaFirstBankSize=3072;
|
||||||
|
int tiunaOtherBankSize=4096-48;
|
||||||
|
|
||||||
std::vector<TAParam> params;
|
std::vector<TAParam> params;
|
||||||
|
|
||||||
#ifdef HAVE_LOCALE
|
#ifdef HAVE_LOCALE
|
||||||
|
@ -199,6 +205,11 @@ TAParamResult pConsole(String val) {
|
||||||
return TA_PARAM_SUCCESS;
|
return TA_PARAM_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TAParamResult pQuiet(String val) {
|
||||||
|
noReportError=true;
|
||||||
|
return TA_PARAM_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
TAParamResult pNoStatus(String val) {
|
TAParamResult pNoStatus(String val) {
|
||||||
consoleNoStatus=true;
|
consoleNoStatus=true;
|
||||||
return TA_PARAM_SUCCESS;
|
return TA_PARAM_SUCCESS;
|
||||||
|
@ -436,6 +447,12 @@ TAParamResult pCmdOut(String val) {
|
||||||
return TA_PARAM_SUCCESS;
|
return TA_PARAM_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TAParamResult pTiunaOut(String val) {
|
||||||
|
tiunaOutName=val;
|
||||||
|
e.setAudio(DIV_AUDIO_DUMMY);
|
||||||
|
return TA_PARAM_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
bool needsValue(String param) {
|
bool needsValue(String param) {
|
||||||
for (size_t i=0; i<params.size(); i++) {
|
for (size_t i=0; i<params.size(); i++) {
|
||||||
if (params[i].name==param) {
|
if (params[i].name==param) {
|
||||||
|
@ -454,10 +471,12 @@ 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("T","tiunaout",true,pTiunaOut,"<filename>","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("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"));
|
||||||
params.push_back(TAParam("c","console",false,pConsole,"","enable console mode"));
|
params.push_back(TAParam("c","console",false,pConsole,"","enable console mode"));
|
||||||
|
params.push_back(TAParam("q","noreport",false,pQuiet,"","do not display message box on error"));
|
||||||
params.push_back(TAParam("n","nostatus",false,pNoStatus,"","disable playback status in console mode"));
|
params.push_back(TAParam("n","nostatus",false,pNoStatus,"","disable playback status in console mode"));
|
||||||
params.push_back(TAParam("N","nocontrols",false,pNoControls,"","disable standard input controls in console mode"));
|
params.push_back(TAParam("N","nocontrols",false,pNoControls,"","disable standard input controls in console mode"));
|
||||||
|
|
||||||
|
@ -476,18 +495,25 @@ void initParams() {
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
void reportError(String what) {
|
void reportError(String what) {
|
||||||
logE("%s",what);
|
logE("%s",what);
|
||||||
MessageBox(NULL,what.c_str(),"Furnace",MB_OK|MB_ICONERROR);
|
if (!noReportError) {
|
||||||
|
MessageBox(NULL,what.c_str(),"Furnace",MB_OK|MB_ICONERROR);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
#elif defined(ANDROID) || defined(__APPLE__)
|
#elif defined(ANDROID) || defined(__APPLE__)
|
||||||
void reportError(String what) {
|
void reportError(String what) {
|
||||||
logE("%s",what);
|
logE("%s",what);
|
||||||
#ifdef HAVE_SDL2
|
#ifdef HAVE_SDL2
|
||||||
SDL_ShowSimpleMessageBox(SDL_MESSAGEBOX_ERROR,"Error",what.c_str(),NULL);
|
if (!noReportError) {
|
||||||
|
SDL_ShowSimpleMessageBox(SDL_MESSAGEBOX_ERROR,"Error",what.c_str(),NULL);
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
void reportError(String what) {
|
void reportError(String what) {
|
||||||
logE("%s",what);
|
logE("%s",what);
|
||||||
|
if (!noReportError) {
|
||||||
|
// dummy
|
||||||
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -549,6 +575,7 @@ int main(int argc, char** argv) {
|
||||||
vgmOutName="";
|
vgmOutName="";
|
||||||
zsmOutName="";
|
zsmOutName="";
|
||||||
cmdOutName="";
|
cmdOutName="";
|
||||||
|
tiunaOutName="";
|
||||||
|
|
||||||
// load config for locale
|
// load config for locale
|
||||||
e.prePreInit();
|
e.prePreInit();
|
||||||
|
@ -716,14 +743,14 @@ int main(int argc, char** argv) {
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (fileName.empty() && (benchMode || infoMode || outName!="" || vgmOutName!="" || cmdOutName!="")) {
|
if (fileName.empty() && (benchMode || infoMode || outName!="" || vgmOutName!="" || zsmOutName!="" || cmdOutName!="" || tiunaOutName!="")) {
|
||||||
logE("provide a file!");
|
logE("provide a file!");
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef HAVE_GUI
|
#ifdef HAVE_GUI
|
||||||
if (e.preInit(consoleMode || benchMode || infoMode || outName!="" || vgmOutName!="" || cmdOutName!="")) {
|
if (e.preInit(consoleMode || benchMode || infoMode || outName!="" || vgmOutName!="" || zsmOutName!="" || cmdOutName!="" || tiunaOutName!="")) {
|
||||||
if (consoleMode || benchMode || infoMode || outName!="" || vgmOutName!="" || cmdOutName!="") {
|
if (consoleMode || benchMode || infoMode || outName!="" || vgmOutName!="" || zsmOutName!="" || cmdOutName!="" || tiunaOutName!="") {
|
||||||
logW("engine wants safe mode, but Furnace GUI is not going to start.");
|
logW("engine wants safe mode, but Furnace GUI is not going to start.");
|
||||||
} else {
|
} else {
|
||||||
safeMode=true;
|
safeMode=true;
|
||||||
|
@ -735,7 +762,7 @@ int main(int argc, char** argv) {
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (safeMode && (consoleMode || benchMode || infoMode || outName!="" || vgmOutName!="" || cmdOutName!="")) {
|
if (safeMode && (consoleMode || benchMode || infoMode || outName!="" || vgmOutName!="" || zsmOutName!="" || cmdOutName!="" || tiunaOutName!="")) {
|
||||||
logE("you can't use safe mode and console/export mode together.");
|
logE("you can't use safe mode and console/export mode together.");
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
@ -744,7 +771,7 @@ int main(int argc, char** argv) {
|
||||||
e.setAudio(DIV_AUDIO_DUMMY);
|
e.setAudio(DIV_AUDIO_DUMMY);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!fileName.empty() && ((!e.getConfBool("tutIntroPlayed",TUT_INTRO_PLAYED)) || e.getConfInt("alwaysPlayIntro",0)!=3 || consoleMode || benchMode || infoMode || outName!="" || vgmOutName!="" || cmdOutName!="")) {
|
if (!fileName.empty() && ((!e.getConfBool("tutIntroPlayed",TUT_INTRO_PLAYED)) || e.getConfInt("alwaysPlayIntro",0)!=3 || consoleMode || benchMode || infoMode || outName!="" || vgmOutName!="" || zsmOutName!="" || cmdOutName!="" || tiunaOutName!="")) {
|
||||||
logI("loading module...");
|
logI("loading module...");
|
||||||
FILE* f=ps_fopen(fileName.c_str(),"rb");
|
FILE* f=ps_fopen(fileName.c_str(),"rb");
|
||||||
if (f==NULL) {
|
if (f==NULL) {
|
||||||
|
@ -836,7 +863,7 @@ int main(int argc, char** argv) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (outName!="" || vgmOutName!="" || cmdOutName!="") {
|
if (outName!="" || vgmOutName!="" || zsmOutName!="" || cmdOutName!="" || tiunaOutName!="") {
|
||||||
if (cmdOutName!="") {
|
if (cmdOutName!="") {
|
||||||
SafeWriter* w=e.saveCommand();
|
SafeWriter* w=e.saveCommand();
|
||||||
if (w!=NULL) {
|
if (w!=NULL) {
|
||||||
|
@ -869,6 +896,39 @@ int main(int argc, char** argv) {
|
||||||
reportError(_("could not write VGM!"));
|
reportError(_("could not write VGM!"));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (zsmOutName!="") {
|
||||||
|
// TODO: changing parameters
|
||||||
|
SafeWriter* w=e.saveZSM(60,true,true);
|
||||||
|
if (w!=NULL) {
|
||||||
|
FILE* f=ps_fopen(zsmOutName.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 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!="") {
|
if (outName!="") {
|
||||||
e.setConsoleMode(true);
|
e.setConsoleMode(true);
|
||||||
e.saveAudio(outName.c_str(),exportOptions);
|
e.saveAudio(outName.c_str(),exportOptions);
|
||||||
|
|
BIN
wavetables/32x32/32x32sam.fuw
Normal file
BIN
wavetables/32x32/32x32sam.fuw
Normal file
Binary file not shown.
Loading…
Reference in a new issue