improve logging facility
we have a log viewer within the program now
This commit is contained in:
parent
4ae13c15e6
commit
fddd05dc1a
|
@ -394,6 +394,7 @@ src/gui/doAction.cpp
|
||||||
src/gui/editing.cpp
|
src/gui/editing.cpp
|
||||||
src/gui/editControls.cpp
|
src/gui/editControls.cpp
|
||||||
src/gui/insEdit.cpp
|
src/gui/insEdit.cpp
|
||||||
|
src/gui/log.cpp
|
||||||
src/gui/mixer.cpp
|
src/gui/mixer.cpp
|
||||||
src/gui/midiMap.cpp
|
src/gui/midiMap.cpp
|
||||||
src/gui/newSong.cpp
|
src/gui/newSong.cpp
|
||||||
|
|
|
@ -44,18 +44,18 @@ bool TAMidiInRtMidi::gather() {
|
||||||
|
|
||||||
std::vector<String> TAMidiInRtMidi::listDevices() {
|
std::vector<String> TAMidiInRtMidi::listDevices() {
|
||||||
std::vector<String> ret;
|
std::vector<String> ret;
|
||||||
logD("listing devices.\n");
|
logD("listing devices.");
|
||||||
if (port==NULL) return ret;
|
if (port==NULL) return ret;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
unsigned int count=port->getPortCount();
|
unsigned int count=port->getPortCount();
|
||||||
logD("got port count.\n");
|
logD("got port count.");
|
||||||
for (unsigned int i=0; i<count; i++) {
|
for (unsigned int i=0; i<count; i++) {
|
||||||
String name=port->getPortName(i);
|
String name=port->getPortName(i);
|
||||||
if (name!="") ret.push_back(name);
|
if (name!="") ret.push_back(name);
|
||||||
}
|
}
|
||||||
} catch (RtMidiError& e) {
|
} catch (RtMidiError& e) {
|
||||||
logW("could not get MIDI inputs! %s\n",e.what());
|
logW("could not get MIDI inputs! %s",e.what());
|
||||||
}
|
}
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
@ -78,10 +78,10 @@ bool TAMidiInRtMidi::openDevice(String name) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
isOpen=portOpen;
|
isOpen=portOpen;
|
||||||
if (!portOpen) logW("could not find MIDI in device...\n");
|
if (!portOpen) logW("could not find MIDI in device...");
|
||||||
return portOpen;
|
return portOpen;
|
||||||
} catch (RtMidiError& e) {
|
} catch (RtMidiError& e) {
|
||||||
logW("could not open MIDI in device! %s\n",e.what());
|
logW("could not open MIDI in device! %s",e.what());
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
|
@ -93,7 +93,7 @@ bool TAMidiInRtMidi::closeDevice() {
|
||||||
try {
|
try {
|
||||||
port->closePort();
|
port->closePort();
|
||||||
} catch (RtMidiError& e) {
|
} catch (RtMidiError& e) {
|
||||||
logW("could not close MIDI in device! %s\n",e.what());
|
logW("could not close MIDI in device! %s",e.what());
|
||||||
isOpen=false; // still
|
isOpen=false; // still
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -106,7 +106,7 @@ bool TAMidiInRtMidi::init() {
|
||||||
try {
|
try {
|
||||||
port=new RtMidiIn;
|
port=new RtMidiIn;
|
||||||
} catch (RtMidiError& e) {
|
} catch (RtMidiError& e) {
|
||||||
logW("could not initialize RtMidi in! %s\n",e.what());
|
logW("could not initialize RtMidi in! %s",e.what());
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
|
@ -176,10 +176,10 @@ bool TAMidiOutRtMidi::openDevice(String name) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
isOpen=portOpen;
|
isOpen=portOpen;
|
||||||
if (!portOpen) logW("could not find MIDI out device...\n");
|
if (!portOpen) logW("could not find MIDI out device...");
|
||||||
return portOpen;
|
return portOpen;
|
||||||
} catch (RtMidiError& e) {
|
} catch (RtMidiError& e) {
|
||||||
logW("could not open MIDI out device! %s\n",e.what());
|
logW("could not open MIDI out device! %s",e.what());
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
|
@ -191,7 +191,7 @@ bool TAMidiOutRtMidi::closeDevice() {
|
||||||
try {
|
try {
|
||||||
port->closePort();
|
port->closePort();
|
||||||
} catch (RtMidiError& e) {
|
} catch (RtMidiError& e) {
|
||||||
logW("could not close MIDI out device! %s\n",e.what());
|
logW("could not close MIDI out device! %s",e.what());
|
||||||
isOpen=false; // still
|
isOpen=false; // still
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -210,7 +210,7 @@ std::vector<String> TAMidiOutRtMidi::listDevices() {
|
||||||
if (name!="") ret.push_back(name);
|
if (name!="") ret.push_back(name);
|
||||||
}
|
}
|
||||||
} catch (RtMidiError& e) {
|
} catch (RtMidiError& e) {
|
||||||
logW("could not get MIDI outputs! %s\n",e.what());
|
logW("could not get MIDI outputs! %s",e.what());
|
||||||
}
|
}
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
@ -220,7 +220,7 @@ bool TAMidiOutRtMidi::init() {
|
||||||
try {
|
try {
|
||||||
port=new RtMidiOut;
|
port=new RtMidiOut;
|
||||||
} catch (RtMidiError& e) {
|
} catch (RtMidiError& e) {
|
||||||
logW("could not initialize RtMidi out! %s\n",e.what());
|
logW("could not initialize RtMidi out! %s",e.what());
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
|
|
|
@ -75,7 +75,7 @@ std::vector<String> TAAudioSDL::listAudioDevices() {
|
||||||
std::vector<String> ret;
|
std::vector<String> ret;
|
||||||
if (!audioSysStarted) {
|
if (!audioSysStarted) {
|
||||||
if (SDL_Init(SDL_INIT_AUDIO)<0) {
|
if (SDL_Init(SDL_INIT_AUDIO)<0) {
|
||||||
logE("could not initialize SDL to list audio devices\n");
|
logE("could not initialize SDL to list audio devices");
|
||||||
} else {
|
} else {
|
||||||
audioSysStarted=true;
|
audioSysStarted=true;
|
||||||
}
|
}
|
||||||
|
@ -96,12 +96,12 @@ std::vector<String> TAAudioSDL::listAudioDevices() {
|
||||||
|
|
||||||
bool TAAudioSDL::init(TAAudioDesc& request, TAAudioDesc& response) {
|
bool TAAudioSDL::init(TAAudioDesc& request, TAAudioDesc& response) {
|
||||||
if (initialized) {
|
if (initialized) {
|
||||||
logE("audio already initialized\n");
|
logE("audio already initialized");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (!audioSysStarted) {
|
if (!audioSysStarted) {
|
||||||
if (SDL_Init(SDL_INIT_AUDIO)<0) {
|
if (SDL_Init(SDL_INIT_AUDIO)<0) {
|
||||||
logE("could not initialize SDL\n");
|
logE("could not initialize SDL");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
audioSysStarted=true;
|
audioSysStarted=true;
|
||||||
|
@ -119,7 +119,7 @@ bool TAAudioSDL::init(TAAudioDesc& request, TAAudioDesc& response) {
|
||||||
|
|
||||||
ai=SDL_OpenAudioDevice(request.deviceName.empty()?NULL:request.deviceName.c_str(),0,&ac,&ar,SDL_AUDIO_ALLOW_FREQUENCY_CHANGE);
|
ai=SDL_OpenAudioDevice(request.deviceName.empty()?NULL:request.deviceName.c_str(),0,&ac,&ar,SDL_AUDIO_ALLOW_FREQUENCY_CHANGE);
|
||||||
if (ai==0) {
|
if (ai==0) {
|
||||||
logE("could not open audio device: %s\n",SDL_GetError());
|
logE("could not open audio device: %s",SDL_GetError());
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -32,13 +32,13 @@ bool DivEngine::saveConf() {
|
||||||
configFile=configPath+String(CONFIG_FILE);
|
configFile=configPath+String(CONFIG_FILE);
|
||||||
FILE* f=ps_fopen(configFile.c_str(),"wb");
|
FILE* f=ps_fopen(configFile.c_str(),"wb");
|
||||||
if (f==NULL) {
|
if (f==NULL) {
|
||||||
logW("could not write config file! %s\n",strerror(errno));
|
logW("could not write config file! %s",strerror(errno));
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
for (auto& i: conf) {
|
for (auto& i: conf) {
|
||||||
String toWrite=fmt::sprintf("%s=%s\n",i.first,i.second);
|
String toWrite=fmt::sprintf("%s=%s\n",i.first,i.second);
|
||||||
if (fwrite(toWrite.c_str(),1,toWrite.size(),f)!=toWrite.size()) {
|
if (fwrite(toWrite.c_str(),1,toWrite.size(),f)!=toWrite.size()) {
|
||||||
logW("could not write config file! %s\n",strerror(errno));
|
logW("could not write config file! %s",strerror(errno));
|
||||||
fclose(f);
|
fclose(f);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -52,10 +52,10 @@ bool DivEngine::loadConf() {
|
||||||
configFile=configPath+String(CONFIG_FILE);
|
configFile=configPath+String(CONFIG_FILE);
|
||||||
FILE* f=ps_fopen(configFile.c_str(),"rb");
|
FILE* f=ps_fopen(configFile.c_str(),"rb");
|
||||||
if (f==NULL) {
|
if (f==NULL) {
|
||||||
logI("creating default config.\n");
|
logI("creating default config.");
|
||||||
return saveConf();
|
return saveConf();
|
||||||
}
|
}
|
||||||
logI("loading config.\n");
|
logI("loading config.");
|
||||||
while (!feof(f)) {
|
while (!feof(f)) {
|
||||||
String key="";
|
String key="";
|
||||||
String value="";
|
String value="";
|
||||||
|
|
|
@ -148,13 +148,13 @@ void DivDispatchContainer::init(DivSystem sys, DivEngine* eng, int chanCount, do
|
||||||
|
|
||||||
bb[0]=blip_new(32768);
|
bb[0]=blip_new(32768);
|
||||||
if (bb[0]==NULL) {
|
if (bb[0]==NULL) {
|
||||||
logE("not enough memory!\n");
|
logE("not enough memory!");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
bb[1]=blip_new(32768);
|
bb[1]=blip_new(32768);
|
||||||
if (bb[1]==NULL) {
|
if (bb[1]==NULL) {
|
||||||
logE("not enough memory!\n");
|
logE("not enough memory!");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -312,7 +312,7 @@ void DivDispatchContainer::init(DivSystem sys, DivEngine* eng, int chanCount, do
|
||||||
dispatch=new DivPlatformMMC5;
|
dispatch=new DivPlatformMMC5;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
logW("this system is not supported yet! using dummy platform.\n");
|
logW("this system is not supported yet! using dummy platform.");
|
||||||
dispatch=new DivPlatformDummy;
|
dispatch=new DivPlatformDummy;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
|
@ -193,7 +193,7 @@ void DivEngine::runExportThread() {
|
||||||
|
|
||||||
sf=sf_open(exportPath.c_str(),SFM_WRITE,&si);
|
sf=sf_open(exportPath.c_str(),SFM_WRITE,&si);
|
||||||
if (sf==NULL) {
|
if (sf==NULL) {
|
||||||
logE("could not open file for writing! (%s)\n",sf_strerror(NULL));
|
logE("could not open file for writing! (%s)",sf_strerror(NULL));
|
||||||
exporting=false;
|
exporting=false;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -207,7 +207,7 @@ void DivEngine::runExportThread() {
|
||||||
deinitAudioBackend();
|
deinitAudioBackend();
|
||||||
playSub(false);
|
playSub(false);
|
||||||
|
|
||||||
logI("rendering to file...\n");
|
logI("rendering to file...");
|
||||||
|
|
||||||
while (playing) {
|
while (playing) {
|
||||||
nextBuf(NULL,outBuf,0,2,EXPORT_BUFSIZE);
|
nextBuf(NULL,outBuf,0,2,EXPORT_BUFSIZE);
|
||||||
|
@ -216,10 +216,10 @@ void DivEngine::runExportThread() {
|
||||||
outBuf[2][1+(i<<1)]=MAX(-1.0f,MIN(1.0f,outBuf[1][i]));
|
outBuf[2][1+(i<<1)]=MAX(-1.0f,MIN(1.0f,outBuf[1][i]));
|
||||||
}
|
}
|
||||||
if (totalProcessed>EXPORT_BUFSIZE) {
|
if (totalProcessed>EXPORT_BUFSIZE) {
|
||||||
logE("error: total processed is bigger than export bufsize! %d>%d\n",totalProcessed,EXPORT_BUFSIZE);
|
logE("error: total processed is bigger than export bufsize! %d>%d",totalProcessed,EXPORT_BUFSIZE);
|
||||||
}
|
}
|
||||||
if (sf_writef_float(sf,outBuf[2],totalProcessed)!=(int)totalProcessed) {
|
if (sf_writef_float(sf,outBuf[2],totalProcessed)!=(int)totalProcessed) {
|
||||||
logE("error: failed to write entire buffer!\n");
|
logE("error: failed to write entire buffer!");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -229,7 +229,7 @@ void DivEngine::runExportThread() {
|
||||||
delete[] outBuf[2];
|
delete[] outBuf[2];
|
||||||
|
|
||||||
if (sf_close(sf)!=0) {
|
if (sf_close(sf)!=0) {
|
||||||
logE("could not close audio file!\n");
|
logE("could not close audio file!");
|
||||||
}
|
}
|
||||||
exporting=false;
|
exporting=false;
|
||||||
|
|
||||||
|
@ -239,10 +239,10 @@ void DivEngine::runExportThread() {
|
||||||
disCont[i].setQuality(lowQuality);
|
disCont[i].setQuality(lowQuality);
|
||||||
}
|
}
|
||||||
if (!output->setRun(true)) {
|
if (!output->setRun(true)) {
|
||||||
logE("error while activating audio!\n");
|
logE("error while activating audio!");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
logI("done!\n");
|
logI("done!");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case DIV_EXPORT_MODE_MANY_SYS: {
|
case DIV_EXPORT_MODE_MANY_SYS: {
|
||||||
|
@ -262,10 +262,10 @@ void DivEngine::runExportThread() {
|
||||||
|
|
||||||
for (int i=0; i<song.systemLen; i++) {
|
for (int i=0; i<song.systemLen; i++) {
|
||||||
fname[i]=fmt::sprintf("%s_s%02d.wav",exportPath,i+1);
|
fname[i]=fmt::sprintf("%s_s%02d.wav",exportPath,i+1);
|
||||||
logI("- %s\n",fname[i].c_str());
|
logI("- %s",fname[i].c_str());
|
||||||
sf[i]=sf_open(fname[i].c_str(),SFM_WRITE,&si[i]);
|
sf[i]=sf_open(fname[i].c_str(),SFM_WRITE,&si[i]);
|
||||||
if (sf[i]==NULL) {
|
if (sf[i]==NULL) {
|
||||||
logE("could not open file for writing! (%s)\n",sf_strerror(NULL));
|
logE("could not open file for writing! (%s)",sf_strerror(NULL));
|
||||||
for (int j=0; j<i; j++) {
|
for (int j=0; j<i; j++) {
|
||||||
sf_close(sf[i]);
|
sf_close(sf[i]);
|
||||||
}
|
}
|
||||||
|
@ -282,7 +282,7 @@ void DivEngine::runExportThread() {
|
||||||
deinitAudioBackend();
|
deinitAudioBackend();
|
||||||
playSub(false);
|
playSub(false);
|
||||||
|
|
||||||
logI("rendering to files...\n");
|
logI("rendering to files...");
|
||||||
|
|
||||||
while (playing) {
|
while (playing) {
|
||||||
nextBuf(NULL,outBuf,0,2,EXPORT_BUFSIZE);
|
nextBuf(NULL,outBuf,0,2,EXPORT_BUFSIZE);
|
||||||
|
@ -296,10 +296,10 @@ void DivEngine::runExportThread() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (totalProcessed>EXPORT_BUFSIZE) {
|
if (totalProcessed>EXPORT_BUFSIZE) {
|
||||||
logE("error: total processed is bigger than export bufsize! (%d) %d>%d\n",i,totalProcessed,EXPORT_BUFSIZE);
|
logE("error: total processed is bigger than export bufsize! (%d) %d>%d",i,totalProcessed,EXPORT_BUFSIZE);
|
||||||
}
|
}
|
||||||
if (sf_writef_short(sf[i],sysBuf,totalProcessed)!=(int)totalProcessed) {
|
if (sf_writef_short(sf[i],sysBuf,totalProcessed)!=(int)totalProcessed) {
|
||||||
logE("error: failed to write entire buffer! (%d)\n",i);
|
logE("error: failed to write entire buffer! (%d)",i);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -311,7 +311,7 @@ void DivEngine::runExportThread() {
|
||||||
|
|
||||||
for (int i=0; i<song.systemLen; i++) {
|
for (int i=0; i<song.systemLen; i++) {
|
||||||
if (sf_close(sf[i])!=0) {
|
if (sf_close(sf[i])!=0) {
|
||||||
logE("could not close audio file!\n");
|
logE("could not close audio file!");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
exporting=false;
|
exporting=false;
|
||||||
|
@ -322,10 +322,10 @@ void DivEngine::runExportThread() {
|
||||||
disCont[i].setQuality(lowQuality);
|
disCont[i].setQuality(lowQuality);
|
||||||
}
|
}
|
||||||
if (!output->setRun(true)) {
|
if (!output->setRun(true)) {
|
||||||
logE("error while activating audio!\n");
|
logE("error while activating audio!");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
logI("done!\n");
|
logI("done!");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case DIV_EXPORT_MODE_MANY_CHAN: {
|
case DIV_EXPORT_MODE_MANY_CHAN: {
|
||||||
|
@ -338,20 +338,20 @@ void DivEngine::runExportThread() {
|
||||||
outBuf[2]=new float[EXPORT_BUFSIZE*2];
|
outBuf[2]=new float[EXPORT_BUFSIZE*2];
|
||||||
int loopCount=remainingLoops;
|
int loopCount=remainingLoops;
|
||||||
|
|
||||||
logI("rendering to files...\n");
|
logI("rendering to files...");
|
||||||
|
|
||||||
for (int i=0; i<chans; i++) {
|
for (int i=0; i<chans; i++) {
|
||||||
SNDFILE* sf;
|
SNDFILE* sf;
|
||||||
SF_INFO si;
|
SF_INFO si;
|
||||||
String fname=fmt::sprintf("%s_c%02d.wav",exportPath,i+1);
|
String fname=fmt::sprintf("%s_c%02d.wav",exportPath,i+1);
|
||||||
logI("- %s\n",fname.c_str());
|
logI("- %s",fname.c_str());
|
||||||
si.samplerate=got.rate;
|
si.samplerate=got.rate;
|
||||||
si.channels=2;
|
si.channels=2;
|
||||||
si.format=SF_FORMAT_WAV|SF_FORMAT_PCM_16;
|
si.format=SF_FORMAT_WAV|SF_FORMAT_PCM_16;
|
||||||
|
|
||||||
sf=sf_open(fname.c_str(),SFM_WRITE,&si);
|
sf=sf_open(fname.c_str(),SFM_WRITE,&si);
|
||||||
if (sf==NULL) {
|
if (sf==NULL) {
|
||||||
logE("could not open file for writing! (%s)\n",sf_strerror(NULL));
|
logE("could not open file for writing! (%s)",sf_strerror(NULL));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -374,16 +374,16 @@ void DivEngine::runExportThread() {
|
||||||
outBuf[2][1+(j<<1)]=MAX(-1.0f,MIN(1.0f,outBuf[1][j]));
|
outBuf[2][1+(j<<1)]=MAX(-1.0f,MIN(1.0f,outBuf[1][j]));
|
||||||
}
|
}
|
||||||
if (totalProcessed>EXPORT_BUFSIZE) {
|
if (totalProcessed>EXPORT_BUFSIZE) {
|
||||||
logE("error: total processed is bigger than export bufsize! %d>%d\n",totalProcessed,EXPORT_BUFSIZE);
|
logE("error: total processed is bigger than export bufsize! %d>%d",totalProcessed,EXPORT_BUFSIZE);
|
||||||
}
|
}
|
||||||
if (sf_writef_float(sf,outBuf[2],totalProcessed)!=(int)totalProcessed) {
|
if (sf_writef_float(sf,outBuf[2],totalProcessed)!=(int)totalProcessed) {
|
||||||
logE("error: failed to write entire buffer!\n");
|
logE("error: failed to write entire buffer!");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (sf_close(sf)!=0) {
|
if (sf_close(sf)!=0) {
|
||||||
logE("could not close audio file!\n");
|
logE("could not close audio file!");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
exporting=false;
|
exporting=false;
|
||||||
|
@ -405,10 +405,10 @@ void DivEngine::runExportThread() {
|
||||||
disCont[i].setQuality(lowQuality);
|
disCont[i].setQuality(lowQuality);
|
||||||
}
|
}
|
||||||
if (!output->setRun(true)) {
|
if (!output->setRun(true)) {
|
||||||
logE("error while activating audio!\n");
|
logE("error while activating audio!");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
logI("done!\n");
|
logI("done!");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -479,12 +479,12 @@ void DivEngine::renderSamples() {
|
||||||
memPos=(memPos+0xfffff)&0xf00000;
|
memPos=(memPos+0xfffff)&0xf00000;
|
||||||
}
|
}
|
||||||
if (memPos>=16777216) {
|
if (memPos>=16777216) {
|
||||||
logW("out of ADPCM-A memory for sample %d!\n",i);
|
logW("out of ADPCM-A memory for sample %d!",i);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (memPos+paddedLen>=16777216) {
|
if (memPos+paddedLen>=16777216) {
|
||||||
memcpy(adpcmAMem+memPos,s->dataA,16777216-memPos);
|
memcpy(adpcmAMem+memPos,s->dataA,16777216-memPos);
|
||||||
logW("out of ADPCM-A memory for sample %d!\n",i);
|
logW("out of ADPCM-A memory for sample %d!",i);
|
||||||
} else {
|
} else {
|
||||||
memcpy(adpcmAMem+memPos,s->dataA,paddedLen);
|
memcpy(adpcmAMem+memPos,s->dataA,paddedLen);
|
||||||
}
|
}
|
||||||
|
@ -504,12 +504,12 @@ void DivEngine::renderSamples() {
|
||||||
memPos=(memPos+0xfffff)&0xf00000;
|
memPos=(memPos+0xfffff)&0xf00000;
|
||||||
}
|
}
|
||||||
if (memPos>=16777216) {
|
if (memPos>=16777216) {
|
||||||
logW("out of ADPCM-B memory for sample %d!\n",i);
|
logW("out of ADPCM-B memory for sample %d!",i);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (memPos+paddedLen>=16777216) {
|
if (memPos+paddedLen>=16777216) {
|
||||||
memcpy(adpcmBMem+memPos,s->dataB,16777216-memPos);
|
memcpy(adpcmBMem+memPos,s->dataB,16777216-memPos);
|
||||||
logW("out of ADPCM-B memory for sample %d!\n",i);
|
logW("out of ADPCM-B memory for sample %d!",i);
|
||||||
} else {
|
} else {
|
||||||
memcpy(adpcmBMem+memPos,s->dataB,paddedLen);
|
memcpy(adpcmBMem+memPos,s->dataB,paddedLen);
|
||||||
}
|
}
|
||||||
|
@ -533,14 +533,14 @@ void DivEngine::renderSamples() {
|
||||||
memPos=(memPos+0xffff)&0xff0000;
|
memPos=(memPos+0xffff)&0xff0000;
|
||||||
}
|
}
|
||||||
if (memPos>=16777216) {
|
if (memPos>=16777216) {
|
||||||
logW("out of QSound PCM memory for sample %d!\n",i);
|
logW("out of QSound PCM memory for sample %d!",i);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (memPos+length>=16777216) {
|
if (memPos+length>=16777216) {
|
||||||
for (unsigned int i=0; i<16777216-(memPos+length); i++) {
|
for (unsigned int i=0; i<16777216-(memPos+length); i++) {
|
||||||
qsoundMem[(memPos+i)^0x8000]=s->data8[i];
|
qsoundMem[(memPos+i)^0x8000]=s->data8[i];
|
||||||
}
|
}
|
||||||
logW("out of QSound PCM memory for sample %d!\n",i);
|
logW("out of QSound PCM memory for sample %d!",i);
|
||||||
} else {
|
} else {
|
||||||
for (int i=0; i<length; i++) {
|
for (int i=0; i<length; i++) {
|
||||||
qsoundMem[(memPos+i)^0x8000]=s->data8[i];
|
qsoundMem[(memPos+i)^0x8000]=s->data8[i];
|
||||||
|
@ -567,12 +567,12 @@ void DivEngine::renderSamples() {
|
||||||
memPos=(memPos+0x1ffff)&0xfe0000;
|
memPos=(memPos+0x1ffff)&0xfe0000;
|
||||||
}
|
}
|
||||||
if (memPos>=1048576) {
|
if (memPos>=1048576) {
|
||||||
logW("out of X1-010 memory for sample %d!\n",i);
|
logW("out of X1-010 memory for sample %d!",i);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (memPos+paddedLen>=1048576) {
|
if (memPos+paddedLen>=1048576) {
|
||||||
memcpy(x1_010Mem+memPos,s->data8,1048576-memPos);
|
memcpy(x1_010Mem+memPos,s->data8,1048576-memPos);
|
||||||
logW("out of X1-010 memory for sample %d!\n",i);
|
logW("out of X1-010 memory for sample %d!",i);
|
||||||
} else {
|
} else {
|
||||||
memcpy(x1_010Mem+memPos,s->data8,paddedLen);
|
memcpy(x1_010Mem+memPos,s->data8,paddedLen);
|
||||||
}
|
}
|
||||||
|
@ -824,7 +824,7 @@ void DivEngine::playSub(bool preserveDrift, int goalRow) {
|
||||||
skipping=false;
|
skipping=false;
|
||||||
cmdStream.clear();
|
cmdStream.clear();
|
||||||
std::chrono::high_resolution_clock::time_point timeEnd=std::chrono::high_resolution_clock::now();
|
std::chrono::high_resolution_clock::time_point timeEnd=std::chrono::high_resolution_clock::now();
|
||||||
logV("playSub() tool %dµs\n",std::chrono::duration_cast<std::chrono::microseconds>(timeEnd-timeStart).count());
|
logV("playSub() tool %dµs",std::chrono::duration_cast<std::chrono::microseconds>(timeEnd-timeStart).count());
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -1346,7 +1346,7 @@ bool DivEngine::addWaveFromFile(const char* path) {
|
||||||
}
|
}
|
||||||
buf=new unsigned char[len];
|
buf=new unsigned char[len];
|
||||||
if (fread(buf,1,len,f)!=(size_t)len) {
|
if (fread(buf,1,len,f)!=(size_t)len) {
|
||||||
logW("did not read entire wavetable file buffer!\n");
|
logW("did not read entire wavetable file buffer!");
|
||||||
delete[] buf;
|
delete[] buf;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -1386,22 +1386,22 @@ bool DivEngine::addWaveFromFile(const char* path) {
|
||||||
wave->max=(unsigned char)reader.readC();
|
wave->max=(unsigned char)reader.readC();
|
||||||
if (wave->max==255) { // new wavetable format
|
if (wave->max==255) { // new wavetable format
|
||||||
unsigned char waveVersion=reader.readC();
|
unsigned char waveVersion=reader.readC();
|
||||||
logI("reading modern .dmw...\n");
|
logI("reading modern .dmw...");
|
||||||
logD("wave version %d\n",waveVersion);
|
logD("wave version %d",waveVersion);
|
||||||
wave->max=reader.readC();
|
wave->max=reader.readC();
|
||||||
for (int i=0; i<len; i++) {
|
for (int i=0; i<len; i++) {
|
||||||
wave->data[i]=reader.readI();
|
wave->data[i]=reader.readI();
|
||||||
}
|
}
|
||||||
} else if (reader.size()==(size_t)(len+5)) {
|
} else if (reader.size()==(size_t)(len+5)) {
|
||||||
// read as .dmw
|
// read as .dmw
|
||||||
logI("reading .dmw...\n");
|
logI("reading .dmw...");
|
||||||
if (len>256) len=256;
|
if (len>256) len=256;
|
||||||
for (int i=0; i<len; i++) {
|
for (int i=0; i<len; i++) {
|
||||||
wave->data[i]=(unsigned char)reader.readC();
|
wave->data[i]=(unsigned char)reader.readC();
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// read as binary
|
// read as binary
|
||||||
logI("reading binary...\n");
|
logI("reading binary...");
|
||||||
len=reader.size();
|
len=reader.size();
|
||||||
if (len>256) len=256;
|
if (len>256) len=256;
|
||||||
reader.seek(0,SEEK_SET);
|
reader.seek(0,SEEK_SET);
|
||||||
|
@ -1414,7 +1414,7 @@ bool DivEngine::addWaveFromFile(const char* path) {
|
||||||
} catch (EndOfFileException& e) {
|
} catch (EndOfFileException& e) {
|
||||||
// read as binary
|
// read as binary
|
||||||
len=reader.size();
|
len=reader.size();
|
||||||
logI("reading binary for being too small...\n");
|
logI("reading binary for being too small...");
|
||||||
if (len>256) len=256;
|
if (len>256) len=256;
|
||||||
reader.seek(0,SEEK_SET);
|
reader.seek(0,SEEK_SET);
|
||||||
for (int i=0; i<len; i++) {
|
for (int i=0; i<len; i++) {
|
||||||
|
@ -1488,7 +1488,7 @@ int DivEngine::addSampleFromFile(const char* path) {
|
||||||
}
|
}
|
||||||
short* buf=new short[si.channels*si.frames];
|
short* buf=new short[si.channels*si.frames];
|
||||||
if (sf_readf_short(f,buf,si.frames)!=si.frames) {
|
if (sf_readf_short(f,buf,si.frames)!=si.frames) {
|
||||||
logW("sample read size mismatch!\n");
|
logW("sample read size mismatch!");
|
||||||
}
|
}
|
||||||
DivSample* sample=new DivSample;
|
DivSample* sample=new DivSample;
|
||||||
int sampleCount=(int)song.sample.size();
|
int sampleCount=(int)song.sample.size();
|
||||||
|
@ -1623,18 +1623,18 @@ void DivEngine::deepCloneOrder(bool where) {
|
||||||
BUSY_BEGIN_SOFT;
|
BUSY_BEGIN_SOFT;
|
||||||
for (int i=0; i<chans; i++) {
|
for (int i=0; i<chans; i++) {
|
||||||
bool didNotFind=true;
|
bool didNotFind=true;
|
||||||
logD("channel %d\n",i);
|
logD("channel %d",i);
|
||||||
order[i]=song.orders.ord[i][curOrder];
|
order[i]=song.orders.ord[i][curOrder];
|
||||||
// find free slot
|
// find free slot
|
||||||
for (int j=0; j<256; j++) {
|
for (int j=0; j<256; j++) {
|
||||||
logD("finding free slot in %d...\n",j);
|
logD("finding free slot in %d...",j);
|
||||||
if (song.pat[i].data[j]==NULL) {
|
if (song.pat[i].data[j]==NULL) {
|
||||||
int origOrd=order[i];
|
int origOrd=order[i];
|
||||||
order[i]=j;
|
order[i]=j;
|
||||||
DivPattern* oldPat=song.pat[i].getPattern(origOrd,false);
|
DivPattern* oldPat=song.pat[i].getPattern(origOrd,false);
|
||||||
DivPattern* pat=song.pat[i].getPattern(j,true);
|
DivPattern* pat=song.pat[i].getPattern(j,true);
|
||||||
memcpy(pat->data,oldPat->data,256*32*sizeof(short));
|
memcpy(pat->data,oldPat->data,256*32*sizeof(short));
|
||||||
logD("found at %d\n",j);
|
logD("found at %d",j);
|
||||||
didNotFind=false;
|
didNotFind=false;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -1953,7 +1953,7 @@ bool DivEngine::switchMaster() {
|
||||||
disCont[i].setQuality(lowQuality);
|
disCont[i].setQuality(lowQuality);
|
||||||
}
|
}
|
||||||
if (!output->setRun(true)) {
|
if (!output->setRun(true)) {
|
||||||
logE("error while activating audio!\n");
|
logE("error while activating audio!");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
@ -2071,9 +2071,9 @@ void DivEngine::quitDispatch() {
|
||||||
#define CHECK_CONFIG_DIR_MAC() \
|
#define CHECK_CONFIG_DIR_MAC() \
|
||||||
configPath+="/Library/Application Support/Furnace"; \
|
configPath+="/Library/Application Support/Furnace"; \
|
||||||
if (stat(configPath.c_str(),&st)<0) { \
|
if (stat(configPath.c_str(),&st)<0) { \
|
||||||
logI("creating config dir...\n"); \
|
logI("creating config dir..."); \
|
||||||
if (mkdir(configPath.c_str(),0755)<0) { \
|
if (mkdir(configPath.c_str(),0755)<0) { \
|
||||||
logW("could not make config dir! (%s)\n",strerror(errno)); \
|
logW("could not make config dir! (%s)",strerror(errno)); \
|
||||||
configPath="."; \
|
configPath="."; \
|
||||||
} \
|
} \
|
||||||
}
|
}
|
||||||
|
@ -2081,18 +2081,18 @@ void DivEngine::quitDispatch() {
|
||||||
#define CHECK_CONFIG_DIR() \
|
#define CHECK_CONFIG_DIR() \
|
||||||
configPath+="/.config"; \
|
configPath+="/.config"; \
|
||||||
if (stat(configPath.c_str(),&st)<0) { \
|
if (stat(configPath.c_str(),&st)<0) { \
|
||||||
logI("creating user config dir...\n"); \
|
logI("creating user config dir..."); \
|
||||||
if (mkdir(configPath.c_str(),0755)<0) { \
|
if (mkdir(configPath.c_str(),0755)<0) { \
|
||||||
logW("could not make user config dir! (%s)\n",strerror(errno)); \
|
logW("could not make user config dir! (%s)",strerror(errno)); \
|
||||||
configPath="."; \
|
configPath="."; \
|
||||||
} \
|
} \
|
||||||
} \
|
} \
|
||||||
if (configPath!=".") { \
|
if (configPath!=".") { \
|
||||||
configPath+="/furnace"; \
|
configPath+="/furnace"; \
|
||||||
if (stat(configPath.c_str(),&st)<0) { \
|
if (stat(configPath.c_str(),&st)<0) { \
|
||||||
logI("creating config dir...\n"); \
|
logI("creating config dir..."); \
|
||||||
if (mkdir(configPath.c_str(),0755)<0) { \
|
if (mkdir(configPath.c_str(),0755)<0) { \
|
||||||
logW("could not make config dir! (%s)\n",strerror(errno)); \
|
logW("could not make config dir! (%s)",strerror(errno)); \
|
||||||
configPath="."; \
|
configPath="."; \
|
||||||
} \
|
} \
|
||||||
} \
|
} \
|
||||||
|
@ -2114,7 +2114,7 @@ bool DivEngine::initAudioBackend() {
|
||||||
switch (audioEngine) {
|
switch (audioEngine) {
|
||||||
case DIV_AUDIO_JACK:
|
case DIV_AUDIO_JACK:
|
||||||
#ifndef HAVE_JACK
|
#ifndef HAVE_JACK
|
||||||
logE("Furnace was not compiled with JACK support!\n");
|
logE("Furnace was not compiled with JACK support!");
|
||||||
setConf("audioEngine","SDL");
|
setConf("audioEngine","SDL");
|
||||||
saveConf();
|
saveConf();
|
||||||
output=new TAAudioSDL;
|
output=new TAAudioSDL;
|
||||||
|
@ -2129,7 +2129,7 @@ bool DivEngine::initAudioBackend() {
|
||||||
output=new TAAudio;
|
output=new TAAudio;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
logE("invalid audio engine!\n");
|
logE("invalid audio engine!");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2147,7 +2147,7 @@ bool DivEngine::initAudioBackend() {
|
||||||
output->setCallback(process,this);
|
output->setCallback(process,this);
|
||||||
|
|
||||||
if (!output->init(want,got)) {
|
if (!output->init(want,got)) {
|
||||||
logE("error while initializing audio!\n");
|
logE("error while initializing audio!");
|
||||||
delete output;
|
delete output;
|
||||||
output=NULL;
|
output=NULL;
|
||||||
audioEngine=DIV_AUDIO_NULL;
|
audioEngine=DIV_AUDIO_NULL;
|
||||||
|
@ -2158,15 +2158,15 @@ bool DivEngine::initAudioBackend() {
|
||||||
midiIns=output->midiIn->listDevices();
|
midiIns=output->midiIn->listDevices();
|
||||||
midiOuts=output->midiOut->listDevices();
|
midiOuts=output->midiOut->listDevices();
|
||||||
} else {
|
} else {
|
||||||
logW("error while initializing MIDI!\n");
|
logW("error while initializing MIDI!");
|
||||||
}
|
}
|
||||||
if (output->midiIn) {
|
if (output->midiIn) {
|
||||||
String inName=getConfString("midiInDevice","");
|
String inName=getConfString("midiInDevice","");
|
||||||
if (!inName.empty()) {
|
if (!inName.empty()) {
|
||||||
// try opening device
|
// try opening device
|
||||||
logI("opening MIDI input.\n");
|
logI("opening MIDI input.");
|
||||||
if (!output->midiIn->openDevice(inName)) {
|
if (!output->midiIn->openDevice(inName)) {
|
||||||
logW("could not open MIDI input device!\n");
|
logW("could not open MIDI input device!");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2174,9 +2174,9 @@ bool DivEngine::initAudioBackend() {
|
||||||
String outName=getConfString("midiOutDevice","");
|
String outName=getConfString("midiOutDevice","");
|
||||||
if (!outName.empty()) {
|
if (!outName.empty()) {
|
||||||
// try opening device
|
// try opening device
|
||||||
logI("opening MIDI output.\n");
|
logI("opening MIDI output.");
|
||||||
if (!output->midiOut->openDevice(outName)) {
|
if (!output->midiOut->openDevice(outName)) {
|
||||||
logW("could not open MIDI output device!\n");
|
logW("could not open MIDI output device!");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2188,13 +2188,13 @@ bool DivEngine::deinitAudioBackend() {
|
||||||
if (output!=NULL) {
|
if (output!=NULL) {
|
||||||
if (output->midiIn) {
|
if (output->midiIn) {
|
||||||
if (output->midiIn->isDeviceOpen()) {
|
if (output->midiIn->isDeviceOpen()) {
|
||||||
logI("closing MIDI input.\n");
|
logI("closing MIDI input.");
|
||||||
output->midiIn->closeDevice();
|
output->midiIn->closeDevice();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (output->midiOut) {
|
if (output->midiOut) {
|
||||||
if (output->midiOut->isDeviceOpen()) {
|
if (output->midiOut->isDeviceOpen()) {
|
||||||
logI("closing MIDI output.\n");
|
logI("closing MIDI output.");
|
||||||
output->midiOut->closeDevice();
|
output->midiOut->closeDevice();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2222,7 +2222,7 @@ bool DivEngine::init() {
|
||||||
int uid=getuid();
|
int uid=getuid();
|
||||||
struct passwd* entry=getpwuid(uid);
|
struct passwd* entry=getpwuid(uid);
|
||||||
if (entry==NULL) {
|
if (entry==NULL) {
|
||||||
logW("unable to determine config directory! (%s)\n",strerror(errno));
|
logW("unable to determine config directory! (%s)",strerror(errno));
|
||||||
configPath=".";
|
configPath=".";
|
||||||
} else {
|
} else {
|
||||||
configPath=entry->pw_dir;
|
configPath=entry->pw_dir;
|
||||||
|
@ -2241,21 +2241,21 @@ bool DivEngine::init() {
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
logD("config path: %s\n",configPath.c_str());
|
logD("config path: %s",configPath.c_str());
|
||||||
|
|
||||||
loadConf();
|
loadConf();
|
||||||
|
|
||||||
// init the rest of engine
|
// init the rest of engine
|
||||||
bool haveAudio=false;
|
bool haveAudio=false;
|
||||||
if (!initAudioBackend()) {
|
if (!initAudioBackend()) {
|
||||||
logE("no audio output available!\n");
|
logE("no audio output available!");
|
||||||
} else {
|
} else {
|
||||||
haveAudio=true;
|
haveAudio=true;
|
||||||
}
|
}
|
||||||
|
|
||||||
samp_bb=blip_new(32768);
|
samp_bb=blip_new(32768);
|
||||||
if (samp_bb==NULL) {
|
if (samp_bb==NULL) {
|
||||||
logE("not enough memory!\n");
|
logE("not enough memory!");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2290,7 +2290,7 @@ bool DivEngine::init() {
|
||||||
return false;
|
return false;
|
||||||
} else {
|
} else {
|
||||||
if (!output->setRun(true)) {
|
if (!output->setRun(true)) {
|
||||||
logE("error while activating!\n");
|
logE("error while activating!");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2300,7 +2300,7 @@ bool DivEngine::init() {
|
||||||
bool DivEngine::quit() {
|
bool DivEngine::quit() {
|
||||||
deinitAudioBackend();
|
deinitAudioBackend();
|
||||||
quitDispatch();
|
quitDispatch();
|
||||||
logI("saving config.\n");
|
logI("saving config.");
|
||||||
saveConf();
|
saveConf();
|
||||||
active=false;
|
active=false;
|
||||||
delete[] oscBuf[0];
|
delete[] oscBuf[0];
|
||||||
|
|
|
@ -62,15 +62,15 @@ bool DivEngine::loadDMF(unsigned char* file, size_t len) {
|
||||||
ds.isDMF=true;
|
ds.isDMF=true;
|
||||||
|
|
||||||
if (!reader.seek(16,SEEK_SET)) {
|
if (!reader.seek(16,SEEK_SET)) {
|
||||||
logE("premature end of file!\n");
|
logE("premature end of file!");
|
||||||
lastError="incomplete file";
|
lastError="incomplete file";
|
||||||
delete[] file;
|
delete[] file;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
ds.version=(unsigned char)reader.readC();
|
ds.version=(unsigned char)reader.readC();
|
||||||
logI("module version %d (0x%.2x)\n",ds.version,ds.version);
|
logI("module version %d (0x%.2x)",ds.version,ds.version);
|
||||||
if (ds.version>0x1a) {
|
if (ds.version>0x1a) {
|
||||||
logE("this version is not supported by Furnace yet!\n");
|
logE("this version is not supported by Furnace yet!");
|
||||||
lastError="this version is not supported by Furnace yet";
|
lastError="this version is not supported by Furnace yet";
|
||||||
delete[] file;
|
delete[] file;
|
||||||
return false;
|
return false;
|
||||||
|
@ -106,23 +106,23 @@ bool DivEngine::loadDMF(unsigned char* file, size_t len) {
|
||||||
ds.manInfo=reader.readString((unsigned char)reader.readC());
|
ds.manInfo=reader.readString((unsigned char)reader.readC());
|
||||||
ds.createdDate=reader.readString((unsigned char)reader.readC());
|
ds.createdDate=reader.readString((unsigned char)reader.readC());
|
||||||
ds.revisionDate=reader.readString((unsigned char)reader.readC());
|
ds.revisionDate=reader.readString((unsigned char)reader.readC());
|
||||||
logI("%s by %s\n",ds.name.c_str(),ds.author.c_str());
|
logI("%s by %s",ds.name.c_str(),ds.author.c_str());
|
||||||
logI("has YMU-specific data:\n");
|
logI("has YMU-specific data:");
|
||||||
logI("- carrier: %s\n",ds.carrier.c_str());
|
logI("- carrier: %s",ds.carrier.c_str());
|
||||||
logI("- category: %s\n",ds.category.c_str());
|
logI("- category: %s",ds.category.c_str());
|
||||||
logI("- vendor: %s\n",ds.vendor.c_str());
|
logI("- vendor: %s",ds.vendor.c_str());
|
||||||
logI("- writer: %s\n",ds.writer.c_str());
|
logI("- writer: %s",ds.writer.c_str());
|
||||||
logI("- composer: %s\n",ds.composer.c_str());
|
logI("- composer: %s",ds.composer.c_str());
|
||||||
logI("- arranger: %s\n",ds.arranger.c_str());
|
logI("- arranger: %s",ds.arranger.c_str());
|
||||||
logI("- copyright: %s\n",ds.copyright.c_str());
|
logI("- copyright: %s",ds.copyright.c_str());
|
||||||
logI("- management group: %s\n",ds.manGroup.c_str());
|
logI("- management group: %s",ds.manGroup.c_str());
|
||||||
logI("- management info: %s\n",ds.manInfo.c_str());
|
logI("- management info: %s",ds.manInfo.c_str());
|
||||||
logI("- created on: %s\n",ds.createdDate.c_str());
|
logI("- created on: %s",ds.createdDate.c_str());
|
||||||
logI("- revision date: %s\n",ds.revisionDate.c_str());
|
logI("- revision date: %s",ds.revisionDate.c_str());
|
||||||
} else {
|
} else {
|
||||||
ds.name=reader.readString((unsigned char)reader.readC());
|
ds.name=reader.readString((unsigned char)reader.readC());
|
||||||
ds.author=reader.readString((unsigned char)reader.readC());
|
ds.author=reader.readString((unsigned char)reader.readC());
|
||||||
logI("%s by %s\n",ds.name.c_str(),ds.author.c_str());
|
logI("%s by %s",ds.name.c_str(),ds.author.c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
// compatibility flags
|
// compatibility flags
|
||||||
|
@ -164,7 +164,7 @@ bool DivEngine::loadDMF(unsigned char* file, size_t len) {
|
||||||
ds.tuning=443.23;
|
ds.tuning=443.23;
|
||||||
}
|
}
|
||||||
|
|
||||||
logI("reading module data...\n");
|
logI("reading module data...");
|
||||||
if (ds.version>0x0c) {
|
if (ds.version>0x0c) {
|
||||||
ds.hilightA=reader.readC();
|
ds.hilightA=reader.readC();
|
||||||
ds.hilightB=reader.readC();
|
ds.hilightB=reader.readC();
|
||||||
|
@ -186,7 +186,7 @@ bool DivEngine::loadDMF(unsigned char* file, size_t len) {
|
||||||
try {
|
try {
|
||||||
ds.hz=std::stoi(hz);
|
ds.hz=std::stoi(hz);
|
||||||
} catch (std::exception& e) {
|
} catch (std::exception& e) {
|
||||||
logW("invalid custom Hz!\n");
|
logW("invalid custom Hz!");
|
||||||
ds.hz=60;
|
ds.hz=60;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -199,25 +199,25 @@ bool DivEngine::loadDMF(unsigned char* file, size_t len) {
|
||||||
ds.ordersLen=(unsigned char)reader.readC();
|
ds.ordersLen=(unsigned char)reader.readC();
|
||||||
|
|
||||||
if (ds.patLen<0) {
|
if (ds.patLen<0) {
|
||||||
logE("pattern length is negative!\n");
|
logE("pattern length is negative!");
|
||||||
lastError="pattern lengrh is negative!";
|
lastError="pattern lengrh is negative!";
|
||||||
delete[] file;
|
delete[] file;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (ds.patLen>256) {
|
if (ds.patLen>256) {
|
||||||
logE("pattern length is too large!\n");
|
logE("pattern length is too large!");
|
||||||
lastError="pattern length is too large!";
|
lastError="pattern length is too large!";
|
||||||
delete[] file;
|
delete[] file;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (ds.ordersLen<0) {
|
if (ds.ordersLen<0) {
|
||||||
logE("song length is negative!\n");
|
logE("song length is negative!");
|
||||||
lastError="song length is negative!";
|
lastError="song length is negative!";
|
||||||
delete[] file;
|
delete[] file;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (ds.ordersLen>127) {
|
if (ds.ordersLen>127) {
|
||||||
logE("song is too long!\n");
|
logE("song is too long!");
|
||||||
lastError="song is too long!";
|
lastError="song is too long!";
|
||||||
delete[] file;
|
delete[] file;
|
||||||
return false;
|
return false;
|
||||||
|
@ -258,12 +258,12 @@ bool DivEngine::loadDMF(unsigned char* file, size_t len) {
|
||||||
addWarning("Yamaha YMU759 emulation is incomplete! please migrate your song to the OPL3 system.");
|
addWarning("Yamaha YMU759 emulation is incomplete! please migrate your song to the OPL3 system.");
|
||||||
}
|
}
|
||||||
|
|
||||||
logI("reading pattern matrix (%d)...\n",ds.ordersLen);
|
logI("reading pattern matrix (%d)...",ds.ordersLen);
|
||||||
for (int i=0; i<getChannelCount(ds.system[0]); i++) {
|
for (int i=0; i<getChannelCount(ds.system[0]); i++) {
|
||||||
for (int j=0; j<ds.ordersLen; j++) {
|
for (int j=0; j<ds.ordersLen; j++) {
|
||||||
ds.orders.ord[i][j]=reader.readC();
|
ds.orders.ord[i][j]=reader.readC();
|
||||||
if (ds.orders.ord[i][j]>0x7f) {
|
if (ds.orders.ord[i][j]>0x7f) {
|
||||||
logE("order at %d, %d out of range! (%d)\n",i,j,ds.orders.ord[i][j]);
|
logE("order at %d, %d out of range! (%d)",i,j,ds.orders.ord[i][j]);
|
||||||
lastError=fmt::sprintf("order at %d, %d out of range! (%d)",i,j,ds.orders.ord[i][j]);
|
lastError=fmt::sprintf("order at %d, %d out of range! (%d)",i,j,ds.orders.ord[i][j]);
|
||||||
delete[] file;
|
delete[] file;
|
||||||
return false;
|
return false;
|
||||||
|
@ -279,19 +279,19 @@ bool DivEngine::loadDMF(unsigned char* file, size_t len) {
|
||||||
} else {
|
} else {
|
||||||
ds.insLen=16;
|
ds.insLen=16;
|
||||||
}
|
}
|
||||||
logI("reading instruments (%d)...\n",ds.insLen);
|
logI("reading instruments (%d)...",ds.insLen);
|
||||||
for (int i=0; i<ds.insLen; i++) {
|
for (int i=0; i<ds.insLen; i++) {
|
||||||
DivInstrument* ins=new DivInstrument;
|
DivInstrument* ins=new DivInstrument;
|
||||||
if (ds.version>0x03) {
|
if (ds.version>0x03) {
|
||||||
ins->name=reader.readString((unsigned char)reader.readC());
|
ins->name=reader.readString((unsigned char)reader.readC());
|
||||||
}
|
}
|
||||||
logD("%d name: %s\n",i,ins->name.c_str());
|
logD("%d name: %s",i,ins->name.c_str());
|
||||||
if (ds.version<0x0b) {
|
if (ds.version<0x0b) {
|
||||||
// instruments in ancient versions were all FM or STD.
|
// instruments in ancient versions were all FM or STD.
|
||||||
ins->mode=1;
|
ins->mode=1;
|
||||||
} else {
|
} else {
|
||||||
unsigned char mode=reader.readC();
|
unsigned char mode=reader.readC();
|
||||||
if (mode>1) logW("%d: invalid instrument mode %d!\n",i,mode);
|
if (mode>1) logW("%d: invalid instrument mode %d!",i,mode);
|
||||||
ins->mode=mode;
|
ins->mode=mode;
|
||||||
}
|
}
|
||||||
ins->type=ins->mode?DIV_INS_FM:DIV_INS_STD;
|
ins->type=ins->mode?DIV_INS_FM:DIV_INS_STD;
|
||||||
|
@ -336,7 +336,7 @@ bool DivEngine::loadDMF(unsigned char* file, size_t len) {
|
||||||
ins->fm.ops=4;
|
ins->fm.ops=4;
|
||||||
}
|
}
|
||||||
if (ins->fm.ops!=2 && ins->fm.ops!=4) {
|
if (ins->fm.ops!=2 && ins->fm.ops!=4) {
|
||||||
logE("invalid op count %d. did we read it wrong?\n",ins->fm.ops);
|
logE("invalid op count %d. did we read it wrong?",ins->fm.ops);
|
||||||
lastError="file is corrupt or unreadable at operators";
|
lastError="file is corrupt or unreadable at operators";
|
||||||
delete[] file;
|
delete[] file;
|
||||||
return false;
|
return false;
|
||||||
|
@ -399,7 +399,7 @@ bool DivEngine::loadDMF(unsigned char* file, size_t len) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
logD("OP%d: AM %d AR %d DAM %d DR %d DVB %d EGT %d KSL %d MULT %d RR %d SL %d SUS %d TL %d VIB %d WS %d RS %d DT %d D2R %d SSG-EG %d\n",j,
|
logD("OP%d: AM %d AR %d DAM %d DR %d DVB %d EGT %d KSL %d MULT %d RR %d SL %d SUS %d TL %d VIB %d WS %d RS %d DT %d D2R %d SSG-EG %d",j,
|
||||||
ins->fm.op[j].am,
|
ins->fm.op[j].am,
|
||||||
ins->fm.op[j].ar,
|
ins->fm.op[j].ar,
|
||||||
ins->fm.op[j].dam,
|
ins->fm.op[j].dam,
|
||||||
|
@ -532,7 +532,7 @@ bool DivEngine::loadDMF(unsigned char* file, size_t len) {
|
||||||
ins->gb.soundLen=reader.readC();
|
ins->gb.soundLen=reader.readC();
|
||||||
ins->std.volMacro.open=false;
|
ins->std.volMacro.open=false;
|
||||||
|
|
||||||
logD("GB data: vol %d dir %d len %d sl %d\n",ins->gb.envVol,ins->gb.envDir,ins->gb.envLen,ins->gb.soundLen);
|
logD("GB data: vol %d dir %d len %d sl %d",ins->gb.envVol,ins->gb.envDir,ins->gb.envLen,ins->gb.soundLen);
|
||||||
} else if (ds.system[0]==DIV_SYSTEM_GB) {
|
} else if (ds.system[0]==DIV_SYSTEM_GB) {
|
||||||
// try to convert macro to envelope
|
// try to convert macro to envelope
|
||||||
if (ins->std.volMacro.len>0) {
|
if (ins->std.volMacro.len>0) {
|
||||||
|
@ -553,7 +553,7 @@ bool DivEngine::loadDMF(unsigned char* file, size_t len) {
|
||||||
|
|
||||||
if (ds.version>0x0b) {
|
if (ds.version>0x0b) {
|
||||||
ds.waveLen=(unsigned char)reader.readC();
|
ds.waveLen=(unsigned char)reader.readC();
|
||||||
logI("reading wavetables (%d)...\n",ds.waveLen);
|
logI("reading wavetables (%d)...",ds.waveLen);
|
||||||
for (int i=0; i<ds.waveLen; i++) {
|
for (int i=0; i<ds.waveLen; i++) {
|
||||||
DivWavetable* wave=new DivWavetable;
|
DivWavetable* wave=new DivWavetable;
|
||||||
wave->len=(unsigned char)reader.readI();
|
wave->len=(unsigned char)reader.readI();
|
||||||
|
@ -564,12 +564,12 @@ bool DivEngine::loadDMF(unsigned char* file, size_t len) {
|
||||||
wave->max=63;
|
wave->max=63;
|
||||||
}
|
}
|
||||||
if (wave->len>65) {
|
if (wave->len>65) {
|
||||||
logE("invalid wave length %d. are we doing something wrong?\n",wave->len);
|
logE("invalid wave length %d. are we doing something wrong?",wave->len);
|
||||||
lastError="file is corrupt or unreadable at wavetables";
|
lastError="file is corrupt or unreadable at wavetables";
|
||||||
delete[] file;
|
delete[] file;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
logD("%d length %d\n",i,wave->len);
|
logD("%d length %d",i,wave->len);
|
||||||
for (int j=0; j<wave->len; j++) {
|
for (int j=0; j<wave->len; j++) {
|
||||||
if (ds.version<0x0e) {
|
if (ds.version<0x0e) {
|
||||||
wave->data[j]=reader.readC();
|
wave->data[j]=reader.readC();
|
||||||
|
@ -588,7 +588,7 @@ bool DivEngine::loadDMF(unsigned char* file, size_t len) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
logI("reading patterns (%d channels, %d orders)...\n",getChannelCount(ds.system[0]),ds.ordersLen);
|
logI("reading patterns (%d channels, %d orders)...",getChannelCount(ds.system[0]),ds.ordersLen);
|
||||||
for (int i=0; i<getChannelCount(ds.system[0]); i++) {
|
for (int i=0; i<getChannelCount(ds.system[0]); i++) {
|
||||||
DivChannelData& chan=ds.pat[i];
|
DivChannelData& chan=ds.pat[i];
|
||||||
if (ds.version<0x0a) {
|
if (ds.version<0x0a) {
|
||||||
|
@ -597,9 +597,9 @@ bool DivEngine::loadDMF(unsigned char* file, size_t len) {
|
||||||
chan.effectRows=reader.readC();
|
chan.effectRows=reader.readC();
|
||||||
|
|
||||||
}
|
}
|
||||||
logD("%d fx rows: %d\n",i,chan.effectRows);
|
logD("%d fx rows: %d",i,chan.effectRows);
|
||||||
if (chan.effectRows>4 || chan.effectRows<1) {
|
if (chan.effectRows>4 || chan.effectRows<1) {
|
||||||
logE("invalid effect row count %d. are you sure everything is ok?\n",chan.effectRows);
|
logE("invalid effect row count %d. are you sure everything is ok?",chan.effectRows);
|
||||||
lastError="file is corrupt or unreadable at effect rows";
|
lastError="file is corrupt or unreadable at effect rows";
|
||||||
delete[] file;
|
delete[] file;
|
||||||
return false;
|
return false;
|
||||||
|
@ -629,7 +629,7 @@ bool DivEngine::loadDMF(unsigned char* file, size_t len) {
|
||||||
pat->data[k][1]+=2;
|
pat->data[k][1]+=2;
|
||||||
}
|
}
|
||||||
if (pat->data[k][0]==0 && pat->data[k][1]!=0) {
|
if (pat->data[k][0]==0 && pat->data[k][1]!=0) {
|
||||||
logD("what? %d:%d:%d note %d octave %d\n",i,j,k,pat->data[k][0],pat->data[k][1]);
|
logD("what? %d:%d:%d note %d octave %d",i,j,k,pat->data[k][0],pat->data[k][1]);
|
||||||
pat->data[k][0]=12;
|
pat->data[k][0]=12;
|
||||||
pat->data[k][1]--;
|
pat->data[k][1]--;
|
||||||
}
|
}
|
||||||
|
@ -676,7 +676,7 @@ bool DivEngine::loadDMF(unsigned char* file, size_t len) {
|
||||||
}
|
}
|
||||||
|
|
||||||
ds.sampleLen=(unsigned char)reader.readC();
|
ds.sampleLen=(unsigned char)reader.readC();
|
||||||
logI("reading samples (%d)...\n",ds.sampleLen);
|
logI("reading samples (%d)...",ds.sampleLen);
|
||||||
if (ds.version<0x0b && ds.sampleLen>0) { // TODO what is this for?
|
if (ds.version<0x0b && ds.sampleLen>0) { // TODO what is this for?
|
||||||
reader.readC();
|
reader.readC();
|
||||||
}
|
}
|
||||||
|
@ -687,7 +687,7 @@ bool DivEngine::loadDMF(unsigned char* file, size_t len) {
|
||||||
int vol=50;
|
int vol=50;
|
||||||
short* data;
|
short* data;
|
||||||
if (length<0) {
|
if (length<0) {
|
||||||
logE("invalid sample length %d. are we doing something wrong?\n",length);
|
logE("invalid sample length %d. are we doing something wrong?",length);
|
||||||
lastError="file is corrupt or unreadable at samples";
|
lastError="file is corrupt or unreadable at samples";
|
||||||
delete[] file;
|
delete[] file;
|
||||||
return false;
|
return false;
|
||||||
|
@ -697,7 +697,7 @@ bool DivEngine::loadDMF(unsigned char* file, size_t len) {
|
||||||
} else {
|
} else {
|
||||||
sample->name="";
|
sample->name="";
|
||||||
}
|
}
|
||||||
logD("%d name %s (%d)\n",i,sample->name.c_str(),length);
|
logD("%d name %s (%d)",i,sample->name.c_str(),length);
|
||||||
sample->rate=22050;
|
sample->rate=22050;
|
||||||
if (ds.version>=0x0b) {
|
if (ds.version>=0x0b) {
|
||||||
sample->rate=fileToDivRate(reader.readC());
|
sample->rate=fileToDivRate(reader.readC());
|
||||||
|
@ -707,7 +707,7 @@ bool DivEngine::loadDMF(unsigned char* file, size_t len) {
|
||||||
if (ds.version>0x15) {
|
if (ds.version>0x15) {
|
||||||
sample->depth=reader.readC();
|
sample->depth=reader.readC();
|
||||||
if (sample->depth!=8 && sample->depth!=16) {
|
if (sample->depth!=8 && sample->depth!=16) {
|
||||||
logW("%d: sample depth is wrong! (%d)\n",i,sample->depth);
|
logW("%d: sample depth is wrong! (%d)",i,sample->depth);
|
||||||
sample->depth=16;
|
sample->depth=16;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
@ -724,12 +724,12 @@ bool DivEngine::loadDMF(unsigned char* file, size_t len) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pitch!=5) {
|
if (pitch!=5) {
|
||||||
logD("%d: scaling from %d...\n",i,pitch);
|
logD("%d: scaling from %d...",i,pitch);
|
||||||
}
|
}
|
||||||
|
|
||||||
// render data
|
// render data
|
||||||
if (!sample->init((double)length/samplePitches[pitch])) {
|
if (!sample->init((double)length/samplePitches[pitch])) {
|
||||||
logE("%d: error while initializing sample!\n",i);
|
logE("%d: error while initializing sample!",i);
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned int k=0;
|
unsigned int k=0;
|
||||||
|
@ -754,7 +754,7 @@ bool DivEngine::loadDMF(unsigned char* file, size_t len) {
|
||||||
|
|
||||||
if (reader.tell()<reader.size()) {
|
if (reader.tell()<reader.size()) {
|
||||||
if ((reader.tell()+1)!=reader.size()) {
|
if ((reader.tell()+1)!=reader.size()) {
|
||||||
logW("premature end of song (we are at %x, but size is %x)\n",reader.tell(),reader.size());
|
logW("premature end of song (we are at %x, but size is %x)",reader.tell(),reader.size());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -806,7 +806,7 @@ bool DivEngine::loadDMF(unsigned char* file, size_t len) {
|
||||||
syncReset();
|
syncReset();
|
||||||
}
|
}
|
||||||
} catch (EndOfFileException& e) {
|
} catch (EndOfFileException& e) {
|
||||||
logE("premature end of file!\n");
|
logE("premature end of file!");
|
||||||
lastError="incomplete file";
|
lastError="incomplete file";
|
||||||
delete[] file;
|
delete[] file;
|
||||||
return false;
|
return false;
|
||||||
|
@ -828,16 +828,16 @@ bool DivEngine::loadFur(unsigned char* file, size_t len) {
|
||||||
DivSong ds;
|
DivSong ds;
|
||||||
|
|
||||||
if (!reader.seek(16,SEEK_SET)) {
|
if (!reader.seek(16,SEEK_SET)) {
|
||||||
logE("premature end of file!\n");
|
logE("premature end of file!");
|
||||||
lastError="incomplete file";
|
lastError="incomplete file";
|
||||||
delete[] file;
|
delete[] file;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
ds.version=reader.readS();
|
ds.version=reader.readS();
|
||||||
logI("module version %d (0x%.2x)\n",ds.version,ds.version);
|
logI("module version %d (0x%.2x)",ds.version,ds.version);
|
||||||
|
|
||||||
if (ds.version>DIV_ENGINE_VERSION) {
|
if (ds.version>DIV_ENGINE_VERSION) {
|
||||||
logW("this module was created with a more recent version of Furnace!\n");
|
logW("this module was created with a more recent version of Furnace!");
|
||||||
addWarning("this module was created with a more recent version of Furnace!");
|
addWarning("this module was created with a more recent version of Furnace!");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -903,7 +903,7 @@ bool DivEngine::loadFur(unsigned char* file, size_t len) {
|
||||||
int infoSeek=reader.readI();
|
int infoSeek=reader.readI();
|
||||||
|
|
||||||
if (!reader.seek(infoSeek,SEEK_SET)) {
|
if (!reader.seek(infoSeek,SEEK_SET)) {
|
||||||
logE("couldn't seek to info header at %d!\n",infoSeek);
|
logE("couldn't seek to info header at %d!",infoSeek);
|
||||||
lastError="couldn't seek to info header!";
|
lastError="couldn't seek to info header!";
|
||||||
delete[] file;
|
delete[] file;
|
||||||
return false;
|
return false;
|
||||||
|
@ -912,7 +912,7 @@ bool DivEngine::loadFur(unsigned char* file, size_t len) {
|
||||||
// read header
|
// read header
|
||||||
reader.read(magic,4);
|
reader.read(magic,4);
|
||||||
if (strcmp(magic,"INFO")!=0) {
|
if (strcmp(magic,"INFO")!=0) {
|
||||||
logE("invalid info header!\n");
|
logE("invalid info header!");
|
||||||
lastError="invalid info header!";
|
lastError="invalid info header!";
|
||||||
delete[] file;
|
delete[] file;
|
||||||
return false;
|
return false;
|
||||||
|
@ -939,49 +939,49 @@ bool DivEngine::loadFur(unsigned char* file, size_t len) {
|
||||||
int numberOfPats=reader.readI();
|
int numberOfPats=reader.readI();
|
||||||
|
|
||||||
if (ds.patLen<0) {
|
if (ds.patLen<0) {
|
||||||
logE("pattern length is negative!\n");
|
logE("pattern length is negative!");
|
||||||
lastError="pattern lengrh is negative!";
|
lastError="pattern lengrh is negative!";
|
||||||
delete[] file;
|
delete[] file;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (ds.patLen>256) {
|
if (ds.patLen>256) {
|
||||||
logE("pattern length is too large!\n");
|
logE("pattern length is too large!");
|
||||||
lastError="pattern length is too large!";
|
lastError="pattern length is too large!";
|
||||||
delete[] file;
|
delete[] file;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (ds.ordersLen<0) {
|
if (ds.ordersLen<0) {
|
||||||
logE("song length is negative!\n");
|
logE("song length is negative!");
|
||||||
lastError="song length is negative!";
|
lastError="song length is negative!";
|
||||||
delete[] file;
|
delete[] file;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (ds.ordersLen>256) {
|
if (ds.ordersLen>256) {
|
||||||
logE("song is too long!\n");
|
logE("song is too long!");
|
||||||
lastError="song is too long!";
|
lastError="song is too long!";
|
||||||
delete[] file;
|
delete[] file;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (ds.insLen<0 || ds.insLen>256) {
|
if (ds.insLen<0 || ds.insLen>256) {
|
||||||
logE("invalid instrument count!\n");
|
logE("invalid instrument count!");
|
||||||
lastError="invalid instrument count!";
|
lastError="invalid instrument count!";
|
||||||
delete[] file;
|
delete[] file;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (ds.waveLen<0 || ds.waveLen>256) {
|
if (ds.waveLen<0 || ds.waveLen>256) {
|
||||||
logE("invalid wavetable count!\n");
|
logE("invalid wavetable count!");
|
||||||
lastError="invalid wavetable count!";
|
lastError="invalid wavetable count!";
|
||||||
delete[] file;
|
delete[] file;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (ds.sampleLen<0 || ds.sampleLen>256) {
|
if (ds.sampleLen<0 || ds.sampleLen>256) {
|
||||||
logE("invalid sample count!\n");
|
logE("invalid sample count!");
|
||||||
lastError="invalid sample count!";
|
lastError="invalid sample count!";
|
||||||
delete[] file;
|
delete[] file;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (numberOfPats<0) {
|
if (numberOfPats<0) {
|
||||||
logE("invalid pattern count!\n");
|
logE("invalid pattern count!");
|
||||||
lastError="invalid pattern count!";
|
lastError="invalid pattern count!";
|
||||||
delete[] file;
|
delete[] file;
|
||||||
return false;
|
return false;
|
||||||
|
@ -991,7 +991,7 @@ bool DivEngine::loadFur(unsigned char* file, size_t len) {
|
||||||
unsigned char sysID=reader.readC();
|
unsigned char sysID=reader.readC();
|
||||||
ds.system[i]=systemFromFileFur(sysID);
|
ds.system[i]=systemFromFileFur(sysID);
|
||||||
if (sysID!=0 && systemToFileFur(ds.system[i])==0) {
|
if (sysID!=0 && systemToFileFur(ds.system[i])==0) {
|
||||||
logE("unrecognized system ID %.2x\n",ds.system[i]);
|
logE("unrecognized system ID %.2x",ds.system[i]);
|
||||||
lastError=fmt::sprintf("unrecognized system ID %.2x!",ds.system[i]);
|
lastError=fmt::sprintf("unrecognized system ID %.2x!",ds.system[i]);
|
||||||
delete[] file;
|
delete[] file;
|
||||||
return false;
|
return false;
|
||||||
|
@ -1004,7 +1004,7 @@ bool DivEngine::loadFur(unsigned char* file, size_t len) {
|
||||||
}
|
}
|
||||||
if (tchans>DIV_MAX_CHANS) {
|
if (tchans>DIV_MAX_CHANS) {
|
||||||
tchans=DIV_MAX_CHANS;
|
tchans=DIV_MAX_CHANS;
|
||||||
logW("too many channels!\n");
|
logW("too many channels!");
|
||||||
}
|
}
|
||||||
|
|
||||||
// system volume
|
// system volume
|
||||||
|
@ -1061,7 +1061,7 @@ bool DivEngine::loadFur(unsigned char* file, size_t len) {
|
||||||
|
|
||||||
ds.name=reader.readString();
|
ds.name=reader.readString();
|
||||||
ds.author=reader.readString();
|
ds.author=reader.readString();
|
||||||
logI("%s by %s\n",ds.name.c_str(),ds.author.c_str());
|
logI("%s by %s",ds.name.c_str(),ds.author.c_str());
|
||||||
|
|
||||||
if (ds.version>=33) {
|
if (ds.version>=33) {
|
||||||
ds.tuning=reader.readF();
|
ds.tuning=reader.readF();
|
||||||
|
@ -1167,7 +1167,7 @@ bool DivEngine::loadFur(unsigned char* file, size_t len) {
|
||||||
reader.read(samplePtr,ds.sampleLen*4);
|
reader.read(samplePtr,ds.sampleLen*4);
|
||||||
for (int i=0; i<numberOfPats; i++) patPtr.push_back(reader.readI());
|
for (int i=0; i<numberOfPats; i++) patPtr.push_back(reader.readI());
|
||||||
|
|
||||||
logD("reading orders (%d)...\n",ds.ordersLen);
|
logD("reading orders (%d)...",ds.ordersLen);
|
||||||
for (int i=0; i<tchans; i++) {
|
for (int i=0; i<tchans; i++) {
|
||||||
for (int j=0; j<ds.ordersLen; j++) {
|
for (int j=0; j<ds.ordersLen; j++) {
|
||||||
ds.orders.ord[i][j]=reader.readC();
|
ds.orders.ord[i][j]=reader.readC();
|
||||||
|
@ -1177,7 +1177,7 @@ bool DivEngine::loadFur(unsigned char* file, size_t len) {
|
||||||
for (int i=0; i<tchans; i++) {
|
for (int i=0; i<tchans; i++) {
|
||||||
ds.pat[i].effectRows=reader.readC();
|
ds.pat[i].effectRows=reader.readC();
|
||||||
if (ds.pat[i].effectRows<1 || ds.pat[i].effectRows>8) {
|
if (ds.pat[i].effectRows<1 || ds.pat[i].effectRows>8) {
|
||||||
logE("channel %d has zero or too many effect columns! (%d)\n",i,ds.pat[i].effectRows);
|
logE("channel %d has zero or too many effect columns! (%d)",i,ds.pat[i].effectRows);
|
||||||
lastError=fmt::sprintf("channel %d has too many effect columns! (%d)",i,ds.pat[i].effectRows);
|
lastError=fmt::sprintf("channel %d has too many effect columns! (%d)",i,ds.pat[i].effectRows);
|
||||||
delete[] file;
|
delete[] file;
|
||||||
return false;
|
return false;
|
||||||
|
@ -1242,9 +1242,9 @@ bool DivEngine::loadFur(unsigned char* file, size_t len) {
|
||||||
// read instruments
|
// read instruments
|
||||||
for (int i=0; i<ds.insLen; i++) {
|
for (int i=0; i<ds.insLen; i++) {
|
||||||
DivInstrument* ins=new DivInstrument;
|
DivInstrument* ins=new DivInstrument;
|
||||||
logD("reading instrument %d at %x...\n",i,insPtr[i]);
|
logD("reading instrument %d at %x...",i,insPtr[i]);
|
||||||
if (!reader.seek(insPtr[i],SEEK_SET)) {
|
if (!reader.seek(insPtr[i],SEEK_SET)) {
|
||||||
logE("couldn't seek to instrument %d!\n",i);
|
logE("couldn't seek to instrument %d!",i);
|
||||||
lastError=fmt::sprintf("couldn't seek to instrument %d!",i);
|
lastError=fmt::sprintf("couldn't seek to instrument %d!",i);
|
||||||
ds.unload();
|
ds.unload();
|
||||||
delete ins;
|
delete ins;
|
||||||
|
@ -1266,9 +1266,9 @@ bool DivEngine::loadFur(unsigned char* file, size_t len) {
|
||||||
// read wavetables
|
// read wavetables
|
||||||
for (int i=0; i<ds.waveLen; i++) {
|
for (int i=0; i<ds.waveLen; i++) {
|
||||||
DivWavetable* wave=new DivWavetable;
|
DivWavetable* wave=new DivWavetable;
|
||||||
logD("reading wavetable %d at %x...\n",i,wavePtr[i]);
|
logD("reading wavetable %d at %x...",i,wavePtr[i]);
|
||||||
if (!reader.seek(wavePtr[i],SEEK_SET)) {
|
if (!reader.seek(wavePtr[i],SEEK_SET)) {
|
||||||
logE("couldn't seek to wavetable %d!\n",i);
|
logE("couldn't seek to wavetable %d!",i);
|
||||||
lastError=fmt::sprintf("couldn't seek to wavetable %d!",i);
|
lastError=fmt::sprintf("couldn't seek to wavetable %d!",i);
|
||||||
ds.unload();
|
ds.unload();
|
||||||
delete wave;
|
delete wave;
|
||||||
|
@ -1293,7 +1293,7 @@ bool DivEngine::loadFur(unsigned char* file, size_t len) {
|
||||||
int pitch=0;
|
int pitch=0;
|
||||||
|
|
||||||
if (!reader.seek(samplePtr[i],SEEK_SET)) {
|
if (!reader.seek(samplePtr[i],SEEK_SET)) {
|
||||||
logE("couldn't seek to sample %d!\n",i);
|
logE("couldn't seek to sample %d!",i);
|
||||||
lastError=fmt::sprintf("couldn't seek to sample %d!",i);
|
lastError=fmt::sprintf("couldn't seek to sample %d!",i);
|
||||||
ds.unload();
|
ds.unload();
|
||||||
delete[] file;
|
delete[] file;
|
||||||
|
@ -1302,7 +1302,7 @@ bool DivEngine::loadFur(unsigned char* file, size_t len) {
|
||||||
|
|
||||||
reader.read(magic,4);
|
reader.read(magic,4);
|
||||||
if (strcmp(magic,"SMPL")!=0) {
|
if (strcmp(magic,"SMPL")!=0) {
|
||||||
logE("%d: invalid sample header!\n",i);
|
logE("%d: invalid sample header!",i);
|
||||||
lastError="invalid sample header!";
|
lastError="invalid sample header!";
|
||||||
ds.unload();
|
ds.unload();
|
||||||
delete[] file;
|
delete[] file;
|
||||||
|
@ -1310,7 +1310,7 @@ bool DivEngine::loadFur(unsigned char* file, size_t len) {
|
||||||
}
|
}
|
||||||
reader.readI();
|
reader.readI();
|
||||||
DivSample* sample=new DivSample;
|
DivSample* sample=new DivSample;
|
||||||
logD("reading sample %d at %x...\n",i,samplePtr[i]);
|
logD("reading sample %d at %x...",i,samplePtr[i]);
|
||||||
|
|
||||||
sample->name=reader.readString();
|
sample->name=reader.readString();
|
||||||
sample->samples=reader.readI();
|
sample->samples=reader.readI();
|
||||||
|
@ -1348,12 +1348,12 @@ bool DivEngine::loadFur(unsigned char* file, size_t len) {
|
||||||
reader.read(data,2*length);
|
reader.read(data,2*length);
|
||||||
|
|
||||||
if (pitch!=5) {
|
if (pitch!=5) {
|
||||||
logD("%d: scaling from %d...\n",i,pitch);
|
logD("%d: scaling from %d...",i,pitch);
|
||||||
}
|
}
|
||||||
|
|
||||||
// render data
|
// render data
|
||||||
if (sample->depth!=8 && sample->depth!=16) {
|
if (sample->depth!=8 && sample->depth!=16) {
|
||||||
logW("%d: sample depth is wrong! (%d)\n",i,sample->depth);
|
logW("%d: sample depth is wrong! (%d)",i,sample->depth);
|
||||||
sample->depth=16;
|
sample->depth=16;
|
||||||
}
|
}
|
||||||
sample->samples=(double)sample->samples/samplePitches[pitch];
|
sample->samples=(double)sample->samples/samplePitches[pitch];
|
||||||
|
@ -1383,16 +1383,16 @@ bool DivEngine::loadFur(unsigned char* file, size_t len) {
|
||||||
// read patterns
|
// read patterns
|
||||||
for (int i: patPtr) {
|
for (int i: patPtr) {
|
||||||
if (!reader.seek(i,SEEK_SET)) {
|
if (!reader.seek(i,SEEK_SET)) {
|
||||||
logE("couldn't seek to pattern in %x!\n",i);
|
logE("couldn't seek to pattern in %x!",i);
|
||||||
lastError=fmt::sprintf("couldn't seek to pattern in %x!",i);
|
lastError=fmt::sprintf("couldn't seek to pattern in %x!",i);
|
||||||
ds.unload();
|
ds.unload();
|
||||||
delete[] file;
|
delete[] file;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
reader.read(magic,4);
|
reader.read(magic,4);
|
||||||
logD("reading pattern in %x...\n",i);
|
logD("reading pattern in %x...",i);
|
||||||
if (strcmp(magic,"PATR")!=0) {
|
if (strcmp(magic,"PATR")!=0) {
|
||||||
logE("%x: invalid pattern header!\n",i);
|
logE("%x: invalid pattern header!",i);
|
||||||
lastError="invalid pattern header!";
|
lastError="invalid pattern header!";
|
||||||
ds.unload();
|
ds.unload();
|
||||||
delete[] file;
|
delete[] file;
|
||||||
|
@ -1404,17 +1404,17 @@ bool DivEngine::loadFur(unsigned char* file, size_t len) {
|
||||||
int index=reader.readS();
|
int index=reader.readS();
|
||||||
reader.readI();
|
reader.readI();
|
||||||
|
|
||||||
logD("- %d, %d\n",chan,index);
|
logD("- %d, %d",chan,index);
|
||||||
|
|
||||||
if (chan<0 || chan>=tchans) {
|
if (chan<0 || chan>=tchans) {
|
||||||
logE("pattern channel out of range!\n",i);
|
logE("pattern channel out of range!",i);
|
||||||
lastError="pattern channel out of range!";
|
lastError="pattern channel out of range!";
|
||||||
ds.unload();
|
ds.unload();
|
||||||
delete[] file;
|
delete[] file;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (index<0 || index>255) {
|
if (index<0 || index>255) {
|
||||||
logE("pattern index out of range!\n",i);
|
logE("pattern index out of range!",i);
|
||||||
lastError="pattern index out of range!";
|
lastError="pattern index out of range!";
|
||||||
ds.unload();
|
ds.unload();
|
||||||
delete[] file;
|
delete[] file;
|
||||||
|
@ -1440,7 +1440,7 @@ bool DivEngine::loadFur(unsigned char* file, size_t len) {
|
||||||
|
|
||||||
if (reader.tell()<reader.size()) {
|
if (reader.tell()<reader.size()) {
|
||||||
if ((reader.tell()+1)!=reader.size()) {
|
if ((reader.tell()+1)!=reader.size()) {
|
||||||
logW("premature end of song (we are at %x, but size is %x)\n",reader.tell(),reader.size());
|
logW("premature end of song (we are at %x, but size is %x)",reader.tell(),reader.size());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1458,7 +1458,7 @@ bool DivEngine::loadFur(unsigned char* file, size_t len) {
|
||||||
syncReset();
|
syncReset();
|
||||||
}
|
}
|
||||||
} catch (EndOfFileException& e) {
|
} catch (EndOfFileException& e) {
|
||||||
logE("premature end of file!\n");
|
logE("premature end of file!");
|
||||||
lastError="incomplete file";
|
lastError="incomplete file";
|
||||||
delete[] file;
|
delete[] file;
|
||||||
return false;
|
return false;
|
||||||
|
@ -1501,28 +1501,28 @@ bool DivEngine::loadMod(unsigned char* file, size_t len) {
|
||||||
|
|
||||||
// check mod magic bytes
|
// check mod magic bytes
|
||||||
if (!reader.seek(1080,SEEK_SET)) {
|
if (!reader.seek(1080,SEEK_SET)) {
|
||||||
logD("couldn't seek to 1080\n");
|
logD("couldn't seek to 1080");
|
||||||
throw EndOfFileException(&reader,reader.tell());
|
throw EndOfFileException(&reader,reader.tell());
|
||||||
}
|
}
|
||||||
reader.read(magic,4);
|
reader.read(magic,4);
|
||||||
if (memcmp(magic,"M.K.",4)==0 || memcmp(magic,"M!K!",4)==0 || memcmp(magic,"M&K!",4)==0) {
|
if (memcmp(magic,"M.K.",4)==0 || memcmp(magic,"M!K!",4)==0 || memcmp(magic,"M&K!",4)==0) {
|
||||||
logD("detected a ProTracker module\n");
|
logD("detected a ProTracker module");
|
||||||
chCount=4;
|
chCount=4;
|
||||||
} else if (memcmp(magic,"CD81",4)==0 || memcmp(magic,"OKTA",4)==0 || memcmp(magic,"OCTA",4)==0) {
|
} else if (memcmp(magic,"CD81",4)==0 || memcmp(magic,"OKTA",4)==0 || memcmp(magic,"OCTA",4)==0) {
|
||||||
logD("detected an Oktalyzer/Octalyzer/OctaMED module\n");
|
logD("detected an Oktalyzer/Octalyzer/OctaMED module");
|
||||||
chCount=8;
|
chCount=8;
|
||||||
} else if (memcmp(magic+1,"CHN",3)==0 && magic[0]>='1' && magic[0]<='9') {
|
} else if (memcmp(magic+1,"CHN",3)==0 && magic[0]>='1' && magic[0]<='9') {
|
||||||
logD("detected a FastTracker module\n");
|
logD("detected a FastTracker module");
|
||||||
chCount=magic[0]-'0';
|
chCount=magic[0]-'0';
|
||||||
} else if (memcmp(magic,"FLT",3)==0 && magic[3]>='1' && magic[3]<='9') {
|
} else if (memcmp(magic,"FLT",3)==0 && magic[3]>='1' && magic[3]<='9') {
|
||||||
logD("detected a Fairlight module\n");
|
logD("detected a Fairlight module");
|
||||||
chCount=magic[3]-'0';
|
chCount=magic[3]-'0';
|
||||||
} else if (memcmp(magic,"TDZ",3)==0 && magic[3]>='1' && magic[3]<='9') {
|
} else if (memcmp(magic,"TDZ",3)==0 && magic[3]>='1' && magic[3]<='9') {
|
||||||
logD("detected a TakeTracker module\n");
|
logD("detected a TakeTracker module");
|
||||||
chCount=magic[3]-'0';
|
chCount=magic[3]-'0';
|
||||||
} else if ((memcmp(magic+2,"CH",2)==0 || memcmp(magic+2,"CN",2)==0) &&
|
} else if ((memcmp(magic+2,"CH",2)==0 || memcmp(magic+2,"CN",2)==0) &&
|
||||||
(magic[0]>='1' && magic[0]<='9' && magic[1]>='0' && magic[1]<='9')) {
|
(magic[0]>='1' && magic[0]<='9' && magic[1]>='0' && magic[1]<='9')) {
|
||||||
logD("detected a Fast/TakeTracker module\n");
|
logD("detected a Fast/TakeTracker module");
|
||||||
chCount=((magic[0]-'0')*10)+(magic[1]-'0');
|
chCount=((magic[0]-'0')*10)+(magic[1]-'0');
|
||||||
} else {
|
} else {
|
||||||
// TODO: Soundtracker MOD?
|
// TODO: Soundtracker MOD?
|
||||||
|
@ -1832,10 +1832,10 @@ bool DivEngine::loadMod(unsigned char* file, size_t len) {
|
||||||
}
|
}
|
||||||
success=true;
|
success=true;
|
||||||
} catch (EndOfFileException& e) {
|
} catch (EndOfFileException& e) {
|
||||||
//logE("premature end of file!\n");
|
//logE("premature end of file!");
|
||||||
lastError="incomplete file";
|
lastError="incomplete file";
|
||||||
} catch (InvalidHeaderException& e) {
|
} catch (InvalidHeaderException& e) {
|
||||||
//logE("invalid info header!\n");
|
//logE("invalid info header!");
|
||||||
lastError="invalid info header!";
|
lastError="invalid info header!";
|
||||||
}
|
}
|
||||||
return success;
|
return success;
|
||||||
|
@ -1853,14 +1853,14 @@ bool DivEngine::load(unsigned char* f, size_t slen) {
|
||||||
if (memcmp(f,DIV_DMF_MAGIC,16)!=0 && memcmp(f,DIV_FUR_MAGIC,16)!=0) {
|
if (memcmp(f,DIV_DMF_MAGIC,16)!=0 && memcmp(f,DIV_FUR_MAGIC,16)!=0) {
|
||||||
// try loading as a .mod first before trying to decompress
|
// try loading as a .mod first before trying to decompress
|
||||||
// TODO: move to a different location?
|
// TODO: move to a different location?
|
||||||
logD("loading as .mod...\n");
|
logD("loading as .mod...");
|
||||||
if (loadMod(f,slen)) {
|
if (loadMod(f,slen)) {
|
||||||
delete[] f;
|
delete[] f;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
lastError="not a .mod song";
|
lastError="not a .mod song";
|
||||||
logD("loading as zlib...\n");
|
logD("loading as zlib...");
|
||||||
// try zlib
|
// try zlib
|
||||||
z_stream zl;
|
z_stream zl;
|
||||||
memset(&zl,0,sizeof(z_stream));
|
memset(&zl,0,sizeof(z_stream));
|
||||||
|
@ -1875,9 +1875,9 @@ bool DivEngine::load(unsigned char* f, size_t slen) {
|
||||||
nextErr=inflateInit(&zl);
|
nextErr=inflateInit(&zl);
|
||||||
if (nextErr!=Z_OK) {
|
if (nextErr!=Z_OK) {
|
||||||
if (zl.msg==NULL) {
|
if (zl.msg==NULL) {
|
||||||
logE("zlib error: unknown! %d\n",nextErr);
|
logE("zlib error: unknown! %d",nextErr);
|
||||||
} else {
|
} else {
|
||||||
logE("zlib error: %s\n",zl.msg);
|
logE("zlib error: %s",zl.msg);
|
||||||
}
|
}
|
||||||
inflateEnd(&zl);
|
inflateEnd(&zl);
|
||||||
delete[] f;
|
delete[] f;
|
||||||
|
@ -1894,10 +1894,10 @@ bool DivEngine::load(unsigned char* f, size_t slen) {
|
||||||
nextErr=inflate(&zl,Z_SYNC_FLUSH);
|
nextErr=inflate(&zl,Z_SYNC_FLUSH);
|
||||||
if (nextErr!=Z_OK && nextErr!=Z_STREAM_END) {
|
if (nextErr!=Z_OK && nextErr!=Z_STREAM_END) {
|
||||||
if (zl.msg==NULL) {
|
if (zl.msg==NULL) {
|
||||||
logE("zlib error: unknown error! %d\n",nextErr);
|
logE("zlib error: unknown error! %d",nextErr);
|
||||||
lastError="unknown decompression error";
|
lastError="unknown decompression error";
|
||||||
} else {
|
} else {
|
||||||
logE("zlib inflate: %s\n",zl.msg);
|
logE("zlib inflate: %s",zl.msg);
|
||||||
lastError=fmt::sprintf("decompression error: %s",zl.msg);
|
lastError=fmt::sprintf("decompression error: %s",zl.msg);
|
||||||
}
|
}
|
||||||
for (InflateBlock* i: blocks) delete i;
|
for (InflateBlock* i: blocks) delete i;
|
||||||
|
@ -1916,10 +1916,10 @@ bool DivEngine::load(unsigned char* f, size_t slen) {
|
||||||
nextErr=inflateEnd(&zl);
|
nextErr=inflateEnd(&zl);
|
||||||
if (nextErr!=Z_OK) {
|
if (nextErr!=Z_OK) {
|
||||||
if (zl.msg==NULL) {
|
if (zl.msg==NULL) {
|
||||||
logE("zlib end error: unknown error! %d\n",nextErr);
|
logE("zlib end error: unknown error! %d",nextErr);
|
||||||
lastError="unknown decompression finish error";
|
lastError="unknown decompression finish error";
|
||||||
} else {
|
} else {
|
||||||
logE("zlib end: %s\n",zl.msg);
|
logE("zlib end: %s",zl.msg);
|
||||||
lastError=fmt::sprintf("decompression finish error: %s",zl.msg);
|
lastError=fmt::sprintf("decompression finish error: %s",zl.msg);
|
||||||
}
|
}
|
||||||
for (InflateBlock* i: blocks) delete i;
|
for (InflateBlock* i: blocks) delete i;
|
||||||
|
@ -1934,7 +1934,7 @@ bool DivEngine::load(unsigned char* f, size_t slen) {
|
||||||
finalSize+=i->blockSize;
|
finalSize+=i->blockSize;
|
||||||
}
|
}
|
||||||
if (finalSize<1) {
|
if (finalSize<1) {
|
||||||
logE("compressed too small!\n");
|
logE("compressed too small!");
|
||||||
lastError="file too small";
|
lastError="file too small";
|
||||||
for (InflateBlock* i: blocks) delete i;
|
for (InflateBlock* i: blocks) delete i;
|
||||||
blocks.clear();
|
blocks.clear();
|
||||||
|
@ -1951,7 +1951,7 @@ bool DivEngine::load(unsigned char* f, size_t slen) {
|
||||||
len=finalSize;
|
len=finalSize;
|
||||||
delete[] f;
|
delete[] f;
|
||||||
} else {
|
} else {
|
||||||
logD("loading as uncompressed\n");
|
logD("loading as uncompressed");
|
||||||
file=(unsigned char*)f;
|
file=(unsigned char*)f;
|
||||||
len=slen;
|
len=slen;
|
||||||
}
|
}
|
||||||
|
@ -1960,7 +1960,7 @@ bool DivEngine::load(unsigned char* f, size_t slen) {
|
||||||
} else if (memcmp(file,DIV_FUR_MAGIC,16)==0) {
|
} else if (memcmp(file,DIV_FUR_MAGIC,16)==0) {
|
||||||
return loadFur(file,len);
|
return loadFur(file,len);
|
||||||
}
|
}
|
||||||
logE("not a valid module!\n");
|
logE("not a valid module!");
|
||||||
lastError="not a compatible song";
|
lastError="not a compatible song";
|
||||||
delete[] file;
|
delete[] file;
|
||||||
return false;
|
return false;
|
||||||
|
@ -2227,7 +2227,7 @@ SafeWriter* DivEngine::saveFur(bool notPrimary) {
|
||||||
SafeWriter* DivEngine::saveDMF(unsigned char version) {
|
SafeWriter* DivEngine::saveDMF(unsigned char version) {
|
||||||
// fail if version is not supported
|
// fail if version is not supported
|
||||||
if (version<24 || version>26) {
|
if (version<24 || version>26) {
|
||||||
logE("cannot save in this version!\n");
|
logE("cannot save in this version!");
|
||||||
lastError="invalid version to save in! this is a bug!";
|
lastError="invalid version to save in! this is a bug!";
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
@ -2255,60 +2255,60 @@ SafeWriter* DivEngine::saveDMF(unsigned char version) {
|
||||||
}
|
}
|
||||||
// fail if more than one system
|
// fail if more than one system
|
||||||
if (!isFlat && song.systemLen!=1) {
|
if (!isFlat && song.systemLen!=1) {
|
||||||
logE("cannot save multiple systems in this format!\n");
|
logE("cannot save multiple systems in this format!");
|
||||||
lastError="multiple systems not possible on .dmf";
|
lastError="multiple systems not possible on .dmf";
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
// fail if this is an YMU759 song
|
// fail if this is an YMU759 song
|
||||||
if (song.system[0]==DIV_SYSTEM_YMU759) {
|
if (song.system[0]==DIV_SYSTEM_YMU759) {
|
||||||
logE("cannot save YMU759 song!\n");
|
logE("cannot save YMU759 song!");
|
||||||
lastError="YMU759 song saving is not supported";
|
lastError="YMU759 song saving is not supported";
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
// fail if the system is SMS+OPLL and version<25
|
// fail if the system is SMS+OPLL and version<25
|
||||||
if (version<25 && song.system[0]==DIV_SYSTEM_SMS && song.system[1]==DIV_SYSTEM_OPLL) {
|
if (version<25 && song.system[0]==DIV_SYSTEM_SMS && song.system[1]==DIV_SYSTEM_OPLL) {
|
||||||
logE("Master System FM expansion not supported in 1.0/legacy .dmf!\n");
|
logE("Master System FM expansion not supported in 1.0/legacy .dmf!");
|
||||||
lastError="Master System FM expansion not supported in 1.0/legacy .dmf!";
|
lastError="Master System FM expansion not supported in 1.0/legacy .dmf!";
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
// fail if the system is NES+VRC7 and version<25
|
// fail if the system is NES+VRC7 and version<25
|
||||||
if (version<25 && song.system[0]==DIV_SYSTEM_NES && song.system[1]==DIV_SYSTEM_VRC7) {
|
if (version<25 && song.system[0]==DIV_SYSTEM_NES && song.system[1]==DIV_SYSTEM_VRC7) {
|
||||||
logE("NES + VRC7 not supported in 1.0/legacy .dmf!\n");
|
logE("NES + VRC7 not supported in 1.0/legacy .dmf!");
|
||||||
lastError="NES + VRC7 not supported in 1.0/legacy .dmf!";
|
lastError="NES + VRC7 not supported in 1.0/legacy .dmf!";
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
// fail if the system is FDS and version<25
|
// fail if the system is FDS and version<25
|
||||||
if (version<25 && song.system[0]==DIV_SYSTEM_NES && song.system[1]==DIV_SYSTEM_FDS) {
|
if (version<25 && song.system[0]==DIV_SYSTEM_NES && song.system[1]==DIV_SYSTEM_FDS) {
|
||||||
logE("FDS not supported in 1.0/legacy .dmf!\n");
|
logE("FDS not supported in 1.0/legacy .dmf!");
|
||||||
lastError="FDS not supported in 1.0/legacy .dmf!";
|
lastError="FDS not supported in 1.0/legacy .dmf!";
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
// fail if the system is Furnace-exclusive
|
// fail if the system is Furnace-exclusive
|
||||||
if (!isFlat && systemToFileDMF(song.system[0])==0) {
|
if (!isFlat && systemToFileDMF(song.system[0])==0) {
|
||||||
logE("cannot save Furnace-exclusive system song!\n");
|
logE("cannot save Furnace-exclusive system song!");
|
||||||
lastError="this system is not possible on .dmf";
|
lastError="this system is not possible on .dmf";
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
// fail if values are out of range
|
// fail if values are out of range
|
||||||
if (song.ordersLen>127) {
|
if (song.ordersLen>127) {
|
||||||
logE("maximum .dmf song length is 127!\n");
|
logE("maximum .dmf song length is 127!");
|
||||||
lastError="maximum .dmf song length is 127";
|
lastError="maximum .dmf song length is 127";
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
if (song.ins.size()>128) {
|
if (song.ins.size()>128) {
|
||||||
logE("maximum number of instruments in .dmf is 128!\n");
|
logE("maximum number of instruments in .dmf is 128!");
|
||||||
lastError="maximum number of instruments in .dmf is 128";
|
lastError="maximum number of instruments in .dmf is 128";
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
if (song.wave.size()>64) {
|
if (song.wave.size()>64) {
|
||||||
logE("maximum number of wavetables in .dmf is 64!\n");
|
logE("maximum number of wavetables in .dmf is 64!");
|
||||||
lastError="maximum number of wavetables in .dmf is 64";
|
lastError="maximum number of wavetables in .dmf is 64";
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
for (int i=0; i<chans; i++) {
|
for (int i=0; i<chans; i++) {
|
||||||
for (int j=0; j<song.ordersLen; j++) {
|
for (int j=0; j<song.ordersLen; j++) {
|
||||||
if (song.orders.ord[i][j]>0x7f) {
|
if (song.orders.ord[i][j]>0x7f) {
|
||||||
logE("order %d, %d is out of range (0-127)!\n",song.orders.ord[i][j]);
|
logE("order %d, %d is out of range (0-127)!",song.orders.ord[i][j]);
|
||||||
lastError=fmt::sprintf("order %d, %d is out of range (0-127)",song.orders.ord[i][j]);
|
lastError=fmt::sprintf("order %d, %d is out of range (0-127)",song.orders.ord[i][j]);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
@ -2486,7 +2486,7 @@ SafeWriter* DivEngine::saveDMF(unsigned char version) {
|
||||||
w->writeC(i->c64.s);
|
w->writeC(i->c64.s);
|
||||||
w->writeC(i->c64.r);
|
w->writeC(i->c64.r);
|
||||||
|
|
||||||
logW("duty and cutoff precision will be lost!\n");
|
logW("duty and cutoff precision will be lost!");
|
||||||
w->writeC((i->c64.duty*100)/4095);
|
w->writeC((i->c64.duty*100)/4095);
|
||||||
|
|
||||||
w->writeC(i->c64.ringMod);
|
w->writeC(i->c64.ringMod);
|
||||||
|
|
|
@ -41,10 +41,10 @@ void DivEngine::loadDMP(SafeReader& reader, std::vector<DivInstrument*>& ret, St
|
||||||
try {
|
try {
|
||||||
reader.seek(0,SEEK_SET);
|
reader.seek(0,SEEK_SET);
|
||||||
version=reader.readC();
|
version=reader.readC();
|
||||||
logD(".dmp version %d\n",version);
|
logD(".dmp version %d",version);
|
||||||
} catch (EndOfFileException& e) {
|
} catch (EndOfFileException& e) {
|
||||||
lastError="premature end of file";
|
lastError="premature end of file";
|
||||||
logE("premature end of file!\n");
|
logE("premature end of file!");
|
||||||
delete ins;
|
delete ins;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -64,38 +64,38 @@ void DivEngine::loadDMP(SafeReader& reader, std::vector<DivInstrument*>& ret, St
|
||||||
switch (sys) {
|
switch (sys) {
|
||||||
case 1: // YMU759
|
case 1: // YMU759
|
||||||
ins->type=DIV_INS_FM;
|
ins->type=DIV_INS_FM;
|
||||||
logD("instrument type is YMU759\n");
|
logD("instrument type is YMU759");
|
||||||
break;
|
break;
|
||||||
case 2: // Genesis
|
case 2: // Genesis
|
||||||
ins->type=DIV_INS_FM;
|
ins->type=DIV_INS_FM;
|
||||||
logD("instrument type is Genesis\n");
|
logD("instrument type is Genesis");
|
||||||
break;
|
break;
|
||||||
case 3: // SMS
|
case 3: // SMS
|
||||||
ins->type=DIV_INS_STD;
|
ins->type=DIV_INS_STD;
|
||||||
logD("instrument type is SMS\n");
|
logD("instrument type is SMS");
|
||||||
break;
|
break;
|
||||||
case 4: // Game Boy
|
case 4: // Game Boy
|
||||||
ins->type=DIV_INS_GB;
|
ins->type=DIV_INS_GB;
|
||||||
logD("instrument type is Game Boy\n");
|
logD("instrument type is Game Boy");
|
||||||
break;
|
break;
|
||||||
case 5: // PC Engine
|
case 5: // PC Engine
|
||||||
ins->type=DIV_INS_PCE;
|
ins->type=DIV_INS_PCE;
|
||||||
logD("instrument type is PC Engine\n");
|
logD("instrument type is PC Engine");
|
||||||
break;
|
break;
|
||||||
case 6: // NES
|
case 6: // NES
|
||||||
ins->type=DIV_INS_STD;
|
ins->type=DIV_INS_STD;
|
||||||
logD("instrument type is NES\n");
|
logD("instrument type is NES");
|
||||||
break;
|
break;
|
||||||
case 7: case 0x17: // C64
|
case 7: case 0x17: // C64
|
||||||
ins->type=DIV_INS_C64;
|
ins->type=DIV_INS_C64;
|
||||||
logD("instrument type is C64\n");
|
logD("instrument type is C64");
|
||||||
break;
|
break;
|
||||||
case 8: // Arcade
|
case 8: // Arcade
|
||||||
ins->type=DIV_INS_FM;
|
ins->type=DIV_INS_FM;
|
||||||
logD("instrument type is Arcade\n");
|
logD("instrument type is Arcade");
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
logD("instrument type is unknown\n");
|
logD("instrument type is unknown");
|
||||||
lastError="unknown instrument type!";
|
lastError="unknown instrument type!";
|
||||||
delete ins;
|
delete ins;
|
||||||
return;
|
return;
|
||||||
|
@ -103,7 +103,7 @@ void DivEngine::loadDMP(SafeReader& reader, std::vector<DivInstrument*>& ret, St
|
||||||
}
|
}
|
||||||
} catch (EndOfFileException& e) {
|
} catch (EndOfFileException& e) {
|
||||||
lastError="premature end of file";
|
lastError="premature end of file";
|
||||||
logE("premature end of file!\n");
|
logE("premature end of file!");
|
||||||
delete ins;
|
delete ins;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -113,7 +113,7 @@ void DivEngine::loadDMP(SafeReader& reader, std::vector<DivInstrument*>& ret, St
|
||||||
bool mode=true;
|
bool mode=true;
|
||||||
if (version>1) {
|
if (version>1) {
|
||||||
mode=reader.readC();
|
mode=reader.readC();
|
||||||
logD("instrument mode is %d\n",mode);
|
logD("instrument mode is %d",mode);
|
||||||
if (mode==0) {
|
if (mode==0) {
|
||||||
if (version<11) {
|
if (version<11) {
|
||||||
ins->type=DIV_INS_STD;
|
ins->type=DIV_INS_STD;
|
||||||
|
@ -126,7 +126,7 @@ void DivEngine::loadDMP(SafeReader& reader, std::vector<DivInstrument*>& ret, St
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mode) { // FM
|
if (mode) { // FM
|
||||||
logD("reading FM data...\n");
|
logD("reading FM data...");
|
||||||
if (version<10) {
|
if (version<10) {
|
||||||
if (version>1) {
|
if (version>1) {
|
||||||
// bullcrap! no way to determine the instrument type other than a vague FM/STD!
|
// bullcrap! no way to determine the instrument type other than a vague FM/STD!
|
||||||
|
@ -151,7 +151,7 @@ void DivEngine::loadDMP(SafeReader& reader, std::vector<DivInstrument*>& ret, St
|
||||||
if (sys!=1) ins->fm.ams=reader.readC();
|
if (sys!=1) ins->fm.ams=reader.readC();
|
||||||
|
|
||||||
for (int j=0; j<ins->fm.ops; j++) {
|
for (int j=0; j<ins->fm.ops; j++) {
|
||||||
logD("OP%d is at %d\n",j,reader.tell());
|
logD("OP%d is at %d",j,reader.tell());
|
||||||
ins->fm.op[j].mult=reader.readC();
|
ins->fm.op[j].mult=reader.readC();
|
||||||
ins->fm.op[j].tl=reader.readC();
|
ins->fm.op[j].tl=reader.readC();
|
||||||
ins->fm.op[j].ar=reader.readC();
|
ins->fm.op[j].ar=reader.readC();
|
||||||
|
@ -179,7 +179,7 @@ void DivEngine::loadDMP(SafeReader& reader, std::vector<DivInstrument*>& ret, St
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else { // STD
|
} else { // STD
|
||||||
logD("reading STD data...\n");
|
logD("reading STD data...");
|
||||||
if (ins->type!=DIV_INS_GB) {
|
if (ins->type!=DIV_INS_GB) {
|
||||||
ins->std.volMacro.len=reader.readC();
|
ins->std.volMacro.len=reader.readC();
|
||||||
if (version>5) {
|
if (version>5) {
|
||||||
|
@ -295,7 +295,7 @@ void DivEngine::loadDMP(SafeReader& reader, std::vector<DivInstrument*>& ret, St
|
||||||
}
|
}
|
||||||
} catch (EndOfFileException& e) {
|
} catch (EndOfFileException& e) {
|
||||||
lastError="premature end of file";
|
lastError="premature end of file";
|
||||||
logE("premature end of file!\n");
|
logE("premature end of file!");
|
||||||
delete ins;
|
delete ins;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -330,7 +330,7 @@ void DivEngine::loadTFI(SafeReader& reader, std::vector<DivInstrument*>& ret, St
|
||||||
}
|
}
|
||||||
} catch (EndOfFileException& e) {
|
} catch (EndOfFileException& e) {
|
||||||
lastError="premature end of file";
|
lastError="premature end of file";
|
||||||
logE("premature end of file!\n");
|
logE("premature end of file!");
|
||||||
delete ins;
|
delete ins;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -372,7 +372,7 @@ void DivEngine::loadVGI(SafeReader& reader, std::vector<DivInstrument*>& ret, St
|
||||||
}
|
}
|
||||||
} catch (EndOfFileException& e) {
|
} catch (EndOfFileException& e) {
|
||||||
lastError="premature end of file";
|
lastError="premature end of file";
|
||||||
logE("premature end of file!\n");
|
logE("premature end of file!");
|
||||||
delete ins;
|
delete ins;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -453,7 +453,7 @@ void DivEngine::loadS3I(SafeReader& reader, std::vector<DivInstrument*>& ret, St
|
||||||
};
|
};
|
||||||
} catch (EndOfFileException& e) {
|
} catch (EndOfFileException& e) {
|
||||||
lastError = "premature end of file";
|
lastError = "premature end of file";
|
||||||
logE("premature end of file!\n");
|
logE("premature end of file!");
|
||||||
delete ins;
|
delete ins;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -623,7 +623,7 @@ void DivEngine::loadSBI(SafeReader& reader, std::vector<DivInstrument*>& ret, St
|
||||||
|
|
||||||
} catch (EndOfFileException& e) {
|
} catch (EndOfFileException& e) {
|
||||||
lastError = "premature end of file";
|
lastError = "premature end of file";
|
||||||
logE("premature end of file!\n");
|
logE("premature end of file!");
|
||||||
delete ins;
|
delete ins;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -640,7 +640,7 @@ void DivEngine::loadOPM(SafeReader& reader, std::vector<DivInstrument*>& ret, St
|
||||||
|
|
||||||
} catch (EndOfFileException& e) {
|
} catch (EndOfFileException& e) {
|
||||||
lastError="premature end of file";
|
lastError="premature end of file";
|
||||||
logE("premature end of file!\n");
|
logE("premature end of file!");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -695,7 +695,7 @@ std::vector<DivInstrument*> DivEngine::instrumentFromFile(const char* path) {
|
||||||
}
|
}
|
||||||
buf=new unsigned char[len];
|
buf=new unsigned char[len];
|
||||||
if (fread(buf,1,len,f)!=(size_t)len) {
|
if (fread(buf,1,len,f)!=(size_t)len) {
|
||||||
logW("did not read entire instrument file buffer!\n");
|
logW("did not read entire instrument file buffer!");
|
||||||
lastError="did not read entire instrument file!";
|
lastError="did not read entire instrument file!";
|
||||||
delete[] buf;
|
delete[] buf;
|
||||||
return ret;
|
return ret;
|
||||||
|
@ -738,7 +738,7 @@ std::vector<DivInstrument*> DivEngine::instrumentFromFile(const char* path) {
|
||||||
}
|
}
|
||||||
} catch (EndOfFileException& e) {
|
} catch (EndOfFileException& e) {
|
||||||
lastError="premature end of file";
|
lastError="premature end of file";
|
||||||
logE("premature end of file!\n");
|
logE("premature end of file!");
|
||||||
delete ins;
|
delete ins;
|
||||||
delete[] buf;
|
delete[] buf;
|
||||||
return ret;
|
return ret;
|
||||||
|
|
|
@ -30,7 +30,7 @@ float* DivFilterTables::sincIntegralTable=NULL;
|
||||||
// licensed under same license as this program.
|
// licensed under same license as this program.
|
||||||
float* DivFilterTables::getCubicTable() {
|
float* DivFilterTables::getCubicTable() {
|
||||||
if (cubicTable==NULL) {
|
if (cubicTable==NULL) {
|
||||||
logD("initializing cubic spline table.\n");
|
logD("initializing cubic spline table.");
|
||||||
cubicTable=new float[4096];
|
cubicTable=new float[4096];
|
||||||
|
|
||||||
for (int i=0; i<1024; i++) {
|
for (int i=0; i<1024; i++) {
|
||||||
|
@ -46,7 +46,7 @@ float* DivFilterTables::getCubicTable() {
|
||||||
|
|
||||||
float* DivFilterTables:: getSincTable() {
|
float* DivFilterTables:: getSincTable() {
|
||||||
if (sincTable==NULL) {
|
if (sincTable==NULL) {
|
||||||
logD("initializing sinc table.\n");
|
logD("initializing sinc table.");
|
||||||
sincTable=new float[65536];
|
sincTable=new float[65536];
|
||||||
|
|
||||||
sincTable[0]=1.0f;
|
sincTable[0]=1.0f;
|
||||||
|
@ -66,7 +66,7 @@ float* DivFilterTables:: getSincTable() {
|
||||||
|
|
||||||
float* DivFilterTables::getSincIntegralTable() {
|
float* DivFilterTables::getSincIntegralTable() {
|
||||||
if (sincIntegralTable==NULL) {
|
if (sincIntegralTable==NULL) {
|
||||||
logD("initializing sinc integral table.\n");
|
logD("initializing sinc integral table.");
|
||||||
sincIntegralTable=new float[65536];
|
sincIntegralTable=new float[65536];
|
||||||
|
|
||||||
sincIntegralTable[0]=-0.5f;
|
sincIntegralTable[0]=-0.5f;
|
||||||
|
|
|
@ -486,7 +486,7 @@ DivDataErrors DivInstrument::readInsData(SafeReader& reader, short version) {
|
||||||
char magic[4];
|
char magic[4];
|
||||||
reader.read(magic,4);
|
reader.read(magic,4);
|
||||||
if (memcmp(magic,"INST",4)!=0) {
|
if (memcmp(magic,"INST",4)!=0) {
|
||||||
logE("invalid instrument header!\n");
|
logE("invalid instrument header!");
|
||||||
return DIV_DATA_INVALID_HEADER;
|
return DIV_DATA_INVALID_HEADER;
|
||||||
}
|
}
|
||||||
reader.readI();
|
reader.readI();
|
||||||
|
@ -949,12 +949,12 @@ bool DivInstrument::save(const char* path) {
|
||||||
|
|
||||||
FILE* outFile=ps_fopen(path,"wb");
|
FILE* outFile=ps_fopen(path,"wb");
|
||||||
if (outFile==NULL) {
|
if (outFile==NULL) {
|
||||||
logE("could not save instrument: %s!\n",strerror(errno));
|
logE("could not save instrument: %s!",strerror(errno));
|
||||||
w->finish();
|
w->finish();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (fwrite(w->getFinalBuf(),1,w->size(),outFile)!=w->size()) {
|
if (fwrite(w->getFinalBuf(),1,w->size(),outFile)!=w->size()) {
|
||||||
logW("did not write entire instrument!\n");
|
logW("did not write entire instrument!");
|
||||||
}
|
}
|
||||||
fclose(outFile);
|
fclose(outFile);
|
||||||
w->finish();
|
w->finish();
|
||||||
|
|
|
@ -431,11 +431,11 @@ int DivPlatformAY8910::dispatch(DivCommand c) {
|
||||||
if (c.value) { // port B
|
if (c.value) { // port B
|
||||||
ioPortB=true;
|
ioPortB=true;
|
||||||
portBVal=c.value2;
|
portBVal=c.value2;
|
||||||
logI("AY I/O port B write: %x\n",portBVal);
|
logI("AY I/O port B write: %x",portBVal);
|
||||||
} else { // port A
|
} else { // port A
|
||||||
ioPortA=true;
|
ioPortA=true;
|
||||||
portAVal=c.value2;
|
portAVal=c.value2;
|
||||||
logI("AY I/O port A write: %x\n",portAVal);
|
logI("AY I/O port A write: %x",portAVal);
|
||||||
}
|
}
|
||||||
updateOutSel(true);
|
updateOutSel(true);
|
||||||
immWrite(14+(c.value?1:0),(c.value?portBVal:portAVal));
|
immWrite(14+(c.value?1:0),(c.value?portBVal:portAVal));
|
||||||
|
|
|
@ -456,11 +456,11 @@ int DivPlatformAY8930::dispatch(DivCommand c) {
|
||||||
if (c.value) { // port B
|
if (c.value) { // port B
|
||||||
ioPortB=true;
|
ioPortB=true;
|
||||||
portBVal=c.value2;
|
portBVal=c.value2;
|
||||||
logI("AY I/O port B write: %x\n",portBVal);
|
logI("AY I/O port B write: %x",portBVal);
|
||||||
} else { // port A
|
} else { // port A
|
||||||
ioPortA=true;
|
ioPortA=true;
|
||||||
portAVal=c.value2;
|
portAVal=c.value2;
|
||||||
logI("AY I/O port A write: %x\n",portAVal);
|
logI("AY I/O port A write: %x",portAVal);
|
||||||
}
|
}
|
||||||
updateOutSel(true);
|
updateOutSel(true);
|
||||||
immWrite(14+(c.value?1:0),(c.value?portBVal:portAVal));
|
immWrite(14+(c.value?1:0),(c.value?portBVal:portAVal));
|
||||||
|
|
|
@ -336,7 +336,7 @@ void DivPlatformQSound::tick() {
|
||||||
rWrite(q1_reg_map[Q1V_LOOP][i], qsound_loop);
|
rWrite(q1_reg_map[Q1V_LOOP][i], qsound_loop);
|
||||||
rWrite(q1_reg_map[Q1V_START][i], qsound_addr);
|
rWrite(q1_reg_map[Q1V_START][i], qsound_addr);
|
||||||
rWrite(q1_reg_map[Q1V_PHASE][i], 0x8000);
|
rWrite(q1_reg_map[Q1V_PHASE][i], 0x8000);
|
||||||
//logW("ch %d bank=%04x, addr=%04x, end=%04x, loop=%04x!\n",i,qsound_bank,qsound_addr,qsound_end,qsound_loop);
|
//logV("ch %d bank=%04x, addr=%04x, end=%04x, loop=%04x!",i,qsound_bank,qsound_addr,qsound_end,qsound_loop);
|
||||||
// Write sample address. Enable volume
|
// Write sample address. Enable volume
|
||||||
if (!chan[i].std.vol.had) {
|
if (!chan[i].std.vol.had) {
|
||||||
rWrite(q1_reg_map[Q1V_VOL][i], chan[i].vol << 4);
|
rWrite(q1_reg_map[Q1V_VOL][i], chan[i].vol << 4);
|
||||||
|
@ -347,7 +347,7 @@ void DivPlatformQSound::tick() {
|
||||||
rWrite(q1_reg_map[Q1V_VOL][i], 0);
|
rWrite(q1_reg_map[Q1V_VOL][i], 0);
|
||||||
rWrite(q1_reg_map[Q1V_FREQ][i], 0);
|
rWrite(q1_reg_map[Q1V_FREQ][i], 0);
|
||||||
} else if (chan[i].active) {
|
} else if (chan[i].active) {
|
||||||
//logW("ch %d frequency set to %04x, off=%f, note=%d, %04x!\n",i,chan[i].freq,off,chan[i].note,QS_NOTE_FREQUENCY(chan[i].note));
|
//logV("ch %d frequency set to %04x, off=%f, note=%d, %04x!",i,chan[i].freq,off,chan[i].note,QS_NOTE_FREQUENCY(chan[i].note));
|
||||||
rWrite(q1_reg_map[Q1V_FREQ][i], chan[i].freq);
|
rWrite(q1_reg_map[Q1V_FREQ][i], chan[i].freq);
|
||||||
}
|
}
|
||||||
if (chan[i].keyOn) chan[i].keyOn=false;
|
if (chan[i].keyOn) chan[i].keyOn=false;
|
||||||
|
|
|
@ -1660,7 +1660,7 @@ void DivEngine::nextBuf(float** in, float** out, int inChans, int outChans, unsi
|
||||||
|
|
||||||
if (softLocked) {
|
if (softLocked) {
|
||||||
if (!isBusy.try_lock()) {
|
if (!isBusy.try_lock()) {
|
||||||
logV("audio is soft-locked (%d)\n",softLockCount++);
|
logV("audio is soft-locked (%d)",softLockCount++);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
@ -1712,7 +1712,7 @@ void DivEngine::nextBuf(float** in, float** out, int inChans, int outChans, unsi
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
logD("%.2x\n",msg.type);
|
logD("%.2x",msg.type);
|
||||||
output->midiIn->queue.pop();
|
output->midiIn->queue.pop();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1845,7 +1845,7 @@ void DivEngine::nextBuf(float** in, float** out, int inChans, int outChans, unsi
|
||||||
if (remainingLoops>0) {
|
if (remainingLoops>0) {
|
||||||
remainingLoops--;
|
remainingLoops--;
|
||||||
if (!remainingLoops) {
|
if (!remainingLoops) {
|
||||||
logI("end of song!\n");
|
logI("end of song!");
|
||||||
remainingLoops=-1;
|
remainingLoops=-1;
|
||||||
playing=false;
|
playing=false;
|
||||||
freelance=false;
|
freelance=false;
|
||||||
|
@ -1881,9 +1881,9 @@ void DivEngine::nextBuf(float** in, float** out, int inChans, int outChans, unsi
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
//logD("attempts: %d\n",attempts);
|
//logD("attempts: %d",attempts);
|
||||||
if (attempts>=100) {
|
if (attempts>=100) {
|
||||||
logE("hang detected! stopping! at %d seconds %d micro\n",totalSeconds,totalTicks);
|
logE("hang detected! stopping! at %d seconds %d micro",totalSeconds,totalTicks);
|
||||||
freelance=false;
|
freelance=false;
|
||||||
playing=false;
|
playing=false;
|
||||||
extValuePresent=false;
|
extValuePresent=false;
|
||||||
|
|
|
@ -57,7 +57,7 @@ size_t SafeReader::size() {
|
||||||
|
|
||||||
int SafeReader::read(void* where, size_t count) {
|
int SafeReader::read(void* where, size_t count) {
|
||||||
#ifdef READ_DEBUG
|
#ifdef READ_DEBUG
|
||||||
logD("SR: reading %d bytes at %x\n",count,curSeek);
|
logD("SR: reading %d bytes at %x",count,curSeek);
|
||||||
#endif
|
#endif
|
||||||
if (count==0) return 0;
|
if (count==0) return 0;
|
||||||
if (curSeek+count>len) throw EndOfFileException(this,len);
|
if (curSeek+count>len) throw EndOfFileException(this,len);
|
||||||
|
@ -68,23 +68,23 @@ int SafeReader::read(void* where, size_t count) {
|
||||||
|
|
||||||
signed char SafeReader::readC() {
|
signed char SafeReader::readC() {
|
||||||
#ifdef READ_DEBUG
|
#ifdef READ_DEBUG
|
||||||
logD("SR: reading char %x:\n",curSeek);
|
logD("SR: reading char %x:",curSeek);
|
||||||
#endif
|
#endif
|
||||||
if (curSeek+1>len) throw EndOfFileException(this,len);
|
if (curSeek+1>len) throw EndOfFileException(this,len);
|
||||||
#ifdef READ_DEBUG
|
#ifdef READ_DEBUG
|
||||||
logD("SR: %.2x\n",buf[curSeek]);
|
logD("SR: %.2x",buf[curSeek]);
|
||||||
#endif
|
#endif
|
||||||
return (signed char)buf[curSeek++];
|
return (signed char)buf[curSeek++];
|
||||||
}
|
}
|
||||||
|
|
||||||
short SafeReader::readS() {
|
short SafeReader::readS() {
|
||||||
#ifdef READ_DEBUG
|
#ifdef READ_DEBUG
|
||||||
logD("SR: reading short %x:\n",curSeek);
|
logD("SR: reading short %x:",curSeek);
|
||||||
#endif
|
#endif
|
||||||
if (curSeek+2>len) throw EndOfFileException(this,len);
|
if (curSeek+2>len) throw EndOfFileException(this,len);
|
||||||
short ret=*(short*)(&buf[curSeek]);
|
short ret=*(short*)(&buf[curSeek]);
|
||||||
#ifdef READ_DEBUG
|
#ifdef READ_DEBUG
|
||||||
logD("SR: %.4x\n",ret);
|
logD("SR: %.4x",ret);
|
||||||
#endif
|
#endif
|
||||||
curSeek+=2;
|
curSeek+=2;
|
||||||
return ret;
|
return ret;
|
||||||
|
@ -99,13 +99,13 @@ short SafeReader::readS_BE() {
|
||||||
|
|
||||||
int SafeReader::readI() {
|
int SafeReader::readI() {
|
||||||
#ifdef READ_DEBUG
|
#ifdef READ_DEBUG
|
||||||
logD("SR: reading int %x:\n",curSeek);
|
logD("SR: reading int %x:",curSeek);
|
||||||
#endif
|
#endif
|
||||||
if (curSeek+4>len) throw EndOfFileException(this,len);
|
if (curSeek+4>len) throw EndOfFileException(this,len);
|
||||||
int ret=*(int*)(&buf[curSeek]);
|
int ret=*(int*)(&buf[curSeek]);
|
||||||
curSeek+=4;
|
curSeek+=4;
|
||||||
#ifdef READ_DEBUG
|
#ifdef READ_DEBUG
|
||||||
logD("SR: %.8x\n",ret);
|
logD("SR: %.8x",ret);
|
||||||
#endif
|
#endif
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
@ -141,7 +141,7 @@ double SafeReader::readD() {
|
||||||
String SafeReader::readString(size_t stlen) {
|
String SafeReader::readString(size_t stlen) {
|
||||||
String ret;
|
String ret;
|
||||||
#ifdef READ_DEBUG
|
#ifdef READ_DEBUG
|
||||||
logD("SR: reading string len %d at %x\n",stlen,curSeek);
|
logD("SR: reading string len %d at %x",stlen,curSeek);
|
||||||
#endif
|
#endif
|
||||||
size_t curPos=0;
|
size_t curPos=0;
|
||||||
while (curPos<stlen) {
|
while (curPos<stlen) {
|
||||||
|
|
|
@ -50,7 +50,7 @@ bool DivSample::save(const char* path) {
|
||||||
f=sf_open(path,SFM_WRITE,&si);
|
f=sf_open(path,SFM_WRITE,&si);
|
||||||
|
|
||||||
if (f==NULL) {
|
if (f==NULL) {
|
||||||
logE("could not open wave file for saving! %s\n",sf_error_number(sf_error(f)));
|
logE("could not open wave file for saving! %s",sf_error_number(sf_error(f)));
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -822,7 +822,7 @@ DivSampleHistory* DivSample::prepareUndo(bool data, bool doNotPush) {
|
||||||
initInternal(h->depth,h->samples); \
|
initInternal(h->depth,h->samples); \
|
||||||
samples=h->samples; \
|
samples=h->samples; \
|
||||||
\
|
\
|
||||||
if (h->length!=getCurBufLen()) logW("undo buffer length not equal to current buffer length! %d != %d\n",h->length,getCurBufLen()); \
|
if (h->length!=getCurBufLen()) logW("undo buffer length not equal to current buffer length! %d != %d",h->length,getCurBufLen()); \
|
||||||
\
|
\
|
||||||
void* buf=getCurBuf(); \
|
void* buf=getCurBuf(); \
|
||||||
\
|
\
|
||||||
|
|
|
@ -415,7 +415,7 @@ void DivEngine::performVGMWrite(SafeWriter* w, DivSystem sys, DivRegWrite& write
|
||||||
}
|
}
|
||||||
if (write.addr>=0xffff0000) { // Furnace special command
|
if (write.addr>=0xffff0000) { // Furnace special command
|
||||||
unsigned char streamID=streamOff+((write.addr&0xff00)>>8);
|
unsigned char streamID=streamOff+((write.addr&0xff00)>>8);
|
||||||
logD("writing stream command %x:%x with stream ID %d\n",write.addr,write.val,streamID);
|
logD("writing stream command %x:%x with stream ID %d",write.addr,write.val,streamID);
|
||||||
switch (write.addr&0xff) {
|
switch (write.addr&0xff) {
|
||||||
case 0: // play sample
|
case 0: // play sample
|
||||||
if (write.val<song.sampleLen) {
|
if (write.val<song.sampleLen) {
|
||||||
|
@ -599,7 +599,7 @@ void DivEngine::performVGMWrite(SafeWriter* w, DivSystem sys, DivRegWrite& write
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
logW("write not handled!\n");
|
logW("write not handled!");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -620,7 +620,7 @@ SafeWriter* DivEngine::saveVGM(bool* sysToExport, bool loop, int version) {
|
||||||
int loopRow=0;
|
int loopRow=0;
|
||||||
int loopEnd=0;
|
int loopEnd=0;
|
||||||
walkSong(loopOrder,loopRow,loopEnd);
|
walkSong(loopOrder,loopRow,loopEnd);
|
||||||
logI("loop point: %d %d\n",loopOrder,loopRow);
|
logI("loop point: %d %d",loopOrder,loopRow);
|
||||||
warnings="";
|
warnings="";
|
||||||
|
|
||||||
curOrder=0;
|
curOrder=0;
|
||||||
|
@ -1162,7 +1162,7 @@ SafeWriter* DivEngine::saveVGM(bool* sysToExport, bool loop, int version) {
|
||||||
unsigned int sampleSeek=0;
|
unsigned int sampleSeek=0;
|
||||||
for (int i=0; i<song.sampleLen; i++) {
|
for (int i=0; i<song.sampleLen; i++) {
|
||||||
DivSample* sample=song.sample[i];
|
DivSample* sample=song.sample[i];
|
||||||
logI("setting seek to %d\n",sampleSeek);
|
logI("setting seek to %d",sampleSeek);
|
||||||
sample->off8=sampleSeek;
|
sample->off8=sampleSeek;
|
||||||
sampleSeek+=sample->length8;
|
sampleSeek+=sample->length8;
|
||||||
}
|
}
|
||||||
|
@ -1447,7 +1447,7 @@ SafeWriter* DivEngine::saveVGM(bool* sysToExport, bool loop, int version) {
|
||||||
if (waitTime>0) {
|
if (waitTime>0) {
|
||||||
w->writeC(0x61);
|
w->writeC(0x61);
|
||||||
w->writeS(waitTime);
|
w->writeS(waitTime);
|
||||||
printf("wait is: %f\n",waitTime);
|
logV("wait is: %f",waitTime);
|
||||||
totalWait-=waitTime;
|
totalWait-=waitTime;
|
||||||
tickCount+=waitTime;
|
tickCount+=waitTime;
|
||||||
}
|
}
|
||||||
|
@ -1561,7 +1561,7 @@ SafeWriter* DivEngine::saveVGM(bool* sysToExport, bool loop, int version) {
|
||||||
freelance=false;
|
freelance=false;
|
||||||
extValuePresent=false;
|
extValuePresent=false;
|
||||||
|
|
||||||
logI("%d register writes total.\n",writeCount);
|
logI("%d register writes total.",writeCount);
|
||||||
|
|
||||||
BUSY_END;
|
BUSY_END;
|
||||||
return w;
|
return w;
|
||||||
|
|
|
@ -73,12 +73,12 @@ bool DivWavetable::save(const char* path) {
|
||||||
|
|
||||||
FILE* outFile=ps_fopen(path,"wb");
|
FILE* outFile=ps_fopen(path,"wb");
|
||||||
if (outFile==NULL) {
|
if (outFile==NULL) {
|
||||||
logE("could not save wavetable: %s!\n",strerror(errno));
|
logE("could not save wavetable: %s!",strerror(errno));
|
||||||
w->finish();
|
w->finish();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (fwrite(w->getFinalBuf(),1,w->size(),outFile)!=w->size()) {
|
if (fwrite(w->getFinalBuf(),1,w->size(),outFile)!=w->size()) {
|
||||||
logW("did not write entire wavetable!\n");
|
logW("did not write entire wavetable!");
|
||||||
}
|
}
|
||||||
fclose(outFile);
|
fclose(outFile);
|
||||||
w->finish();
|
w->finish();
|
||||||
|
|
|
@ -33,15 +33,15 @@ String getWinConfigPath() {
|
||||||
configPath=path;
|
configPath=path;
|
||||||
configPath+=L"\\furnace";
|
configPath+=L"\\furnace";
|
||||||
if (!PathIsDirectoryW(configPath.c_str())) {
|
if (!PathIsDirectoryW(configPath.c_str())) {
|
||||||
logI("creating config dir...\n");
|
logI("creating config dir...");
|
||||||
int mkdirRet;
|
int mkdirRet;
|
||||||
if ((mkdirRet=SHCreateDirectory(NULL,configPath.c_str()))!=ERROR_SUCCESS) {
|
if ((mkdirRet=SHCreateDirectory(NULL,configPath.c_str()))!=ERROR_SUCCESS) {
|
||||||
logW("could not make config dir! (%.8x)\n",mkdirRet);
|
logW("could not make config dir! (%.8x)",mkdirRet);
|
||||||
configPath=L".";
|
configPath=L".";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
logW("unable to determine config directory! (%.8x)\n",configHR);
|
logW("unable to determine config directory! (%.8x)",configHR);
|
||||||
configPath=L".";
|
configPath=L".";
|
||||||
}
|
}
|
||||||
return utf16To8(configPath.c_str());
|
return utf16To8(configPath.c_str());
|
||||||
|
|
|
@ -212,6 +212,9 @@ void FurnaceGUI::doAction(int what) {
|
||||||
case GUI_ACTION_WINDOW_REGISTER_VIEW:
|
case GUI_ACTION_WINDOW_REGISTER_VIEW:
|
||||||
nextWindow=GUI_WINDOW_REGISTER_VIEW;
|
nextWindow=GUI_WINDOW_REGISTER_VIEW;
|
||||||
break;
|
break;
|
||||||
|
case GUI_ACTION_WINDOW_LOG:
|
||||||
|
nextWindow=GUI_WINDOW_LOG;
|
||||||
|
break;
|
||||||
|
|
||||||
case GUI_ACTION_COLLAPSE_WINDOW:
|
case GUI_ACTION_COLLAPSE_WINDOW:
|
||||||
collapseWindow=true;
|
collapseWindow=true;
|
||||||
|
|
|
@ -546,8 +546,8 @@ void FurnaceGUI::doPaste(PasteMode mode) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (invalidData) {
|
if (invalidData) {
|
||||||
logW("invalid clipboard data! failed at line %d char %d\n",i,charPos);
|
logW("invalid clipboard data! failed at line %d char %d",i,charPos);
|
||||||
logW("%s\n",line.c_str());
|
logW("%s",line.c_str());
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
j++;
|
j++;
|
||||||
|
|
|
@ -65,7 +65,7 @@ bool FurnaceGUIFileDialog::render(const ImVec2& min, const ImVec2& max) {
|
||||||
if (dialogS!=NULL) {
|
if (dialogS!=NULL) {
|
||||||
if (dialogS->ready(0)) {
|
if (dialogS->ready(0)) {
|
||||||
fileName=dialogS->result();
|
fileName=dialogS->result();
|
||||||
logD("returning %s\n",fileName.c_str());
|
logD("returning %s",fileName.c_str());
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -74,10 +74,10 @@ bool FurnaceGUIFileDialog::render(const ImVec2& min, const ImVec2& max) {
|
||||||
if (dialogO->ready(0)) {
|
if (dialogO->ready(0)) {
|
||||||
if (dialogO->result().empty()) {
|
if (dialogO->result().empty()) {
|
||||||
fileName="";
|
fileName="";
|
||||||
logD("returning nothing\n");
|
logD("returning nothing");
|
||||||
} else {
|
} else {
|
||||||
fileName=dialogO->result()[0];
|
fileName=dialogO->result()[0];
|
||||||
logD("returning %s\n",fileName.c_str());
|
logD("returning %s",fileName.c_str());
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
|
@ -815,10 +815,10 @@ void FurnaceGUI::prepareLayout() {
|
||||||
}
|
}
|
||||||
|
|
||||||
// copy initial layout
|
// copy initial layout
|
||||||
logI("loading default layout.\n");
|
logI("loading default layout.");
|
||||||
check=ps_fopen(finalLayoutPath,"w");
|
check=ps_fopen(finalLayoutPath,"w");
|
||||||
if (check==NULL) {
|
if (check==NULL) {
|
||||||
logW("could not write default layout!\n");
|
logW("could not write default layout!");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1539,7 +1539,7 @@ int FurnaceGUI::save(String path, int dmfVersion) {
|
||||||
memset(&zl,0,sizeof(z_stream));
|
memset(&zl,0,sizeof(z_stream));
|
||||||
ret=deflateInit(&zl,Z_DEFAULT_COMPRESSION);
|
ret=deflateInit(&zl,Z_DEFAULT_COMPRESSION);
|
||||||
if (ret!=Z_OK) {
|
if (ret!=Z_OK) {
|
||||||
logE("zlib error!\n");
|
logE("zlib error!");
|
||||||
lastError="compression error";
|
lastError="compression error";
|
||||||
fclose(outFile);
|
fclose(outFile);
|
||||||
w->finish();
|
w->finish();
|
||||||
|
@ -1551,7 +1551,7 @@ int FurnaceGUI::save(String path, int dmfVersion) {
|
||||||
zl.avail_out=131072;
|
zl.avail_out=131072;
|
||||||
zl.next_out=zbuf;
|
zl.next_out=zbuf;
|
||||||
if ((ret=deflate(&zl,Z_NO_FLUSH))==Z_STREAM_ERROR) {
|
if ((ret=deflate(&zl,Z_NO_FLUSH))==Z_STREAM_ERROR) {
|
||||||
logE("zlib stream error!\n");
|
logE("zlib stream error!");
|
||||||
lastError="zlib stream error";
|
lastError="zlib stream error";
|
||||||
deflateEnd(&zl);
|
deflateEnd(&zl);
|
||||||
fclose(outFile);
|
fclose(outFile);
|
||||||
|
@ -1561,7 +1561,7 @@ int FurnaceGUI::save(String path, int dmfVersion) {
|
||||||
size_t amount=131072-zl.avail_out;
|
size_t amount=131072-zl.avail_out;
|
||||||
if (amount>0) {
|
if (amount>0) {
|
||||||
if (fwrite(zbuf,1,amount,outFile)!=amount) {
|
if (fwrite(zbuf,1,amount,outFile)!=amount) {
|
||||||
logE("did not write entirely: %s!\n",strerror(errno));
|
logE("did not write entirely: %s!",strerror(errno));
|
||||||
lastError=strerror(errno);
|
lastError=strerror(errno);
|
||||||
deflateEnd(&zl);
|
deflateEnd(&zl);
|
||||||
fclose(outFile);
|
fclose(outFile);
|
||||||
|
@ -1573,7 +1573,7 @@ int FurnaceGUI::save(String path, int dmfVersion) {
|
||||||
zl.avail_out=131072;
|
zl.avail_out=131072;
|
||||||
zl.next_out=zbuf;
|
zl.next_out=zbuf;
|
||||||
if ((ret=deflate(&zl,Z_FINISH))==Z_STREAM_ERROR) {
|
if ((ret=deflate(&zl,Z_FINISH))==Z_STREAM_ERROR) {
|
||||||
logE("zlib finish stream error!\n");
|
logE("zlib finish stream error!");
|
||||||
lastError="zlib finish stream error";
|
lastError="zlib finish stream error";
|
||||||
deflateEnd(&zl);
|
deflateEnd(&zl);
|
||||||
fclose(outFile);
|
fclose(outFile);
|
||||||
|
@ -1582,7 +1582,7 @@ int FurnaceGUI::save(String path, int dmfVersion) {
|
||||||
}
|
}
|
||||||
if (131072-zl.avail_out>0) {
|
if (131072-zl.avail_out>0) {
|
||||||
if (fwrite(zbuf,1,131072-zl.avail_out,outFile)!=(131072-zl.avail_out)) {
|
if (fwrite(zbuf,1,131072-zl.avail_out,outFile)!=(131072-zl.avail_out)) {
|
||||||
logE("did not write entirely: %s!\n",strerror(errno));
|
logE("did not write entirely: %s!",strerror(errno));
|
||||||
lastError=strerror(errno);
|
lastError=strerror(errno);
|
||||||
deflateEnd(&zl);
|
deflateEnd(&zl);
|
||||||
fclose(outFile);
|
fclose(outFile);
|
||||||
|
@ -1593,7 +1593,7 @@ int FurnaceGUI::save(String path, int dmfVersion) {
|
||||||
deflateEnd(&zl);
|
deflateEnd(&zl);
|
||||||
#else
|
#else
|
||||||
if (fwrite(w->getFinalBuf(),1,w->size(),outFile)!=w->size()) {
|
if (fwrite(w->getFinalBuf(),1,w->size(),outFile)!=w->size()) {
|
||||||
logE("did not write entirely: %s!\n",strerror(errno));
|
logE("did not write entirely: %s!",strerror(errno));
|
||||||
lastError=strerror(errno);
|
lastError=strerror(errno);
|
||||||
fclose(outFile);
|
fclose(outFile);
|
||||||
w->finish();
|
w->finish();
|
||||||
|
@ -1613,7 +1613,7 @@ int FurnaceGUI::save(String path, int dmfVersion) {
|
||||||
|
|
||||||
int FurnaceGUI::load(String path) {
|
int FurnaceGUI::load(String path) {
|
||||||
if (!path.empty()) {
|
if (!path.empty()) {
|
||||||
logI("loading module...\n");
|
logI("loading module...");
|
||||||
FILE* f=ps_fopen(path.c_str(),"rb");
|
FILE* f=ps_fopen(path.c_str(),"rb");
|
||||||
if (f==NULL) {
|
if (f==NULL) {
|
||||||
perror("error");
|
perror("error");
|
||||||
|
@ -1635,7 +1635,7 @@ int FurnaceGUI::load(String path) {
|
||||||
}
|
}
|
||||||
if (len<1) {
|
if (len<1) {
|
||||||
if (len==0) {
|
if (len==0) {
|
||||||
logE("that file is empty!\n");
|
logE("that file is empty!");
|
||||||
lastError="file is empty";
|
lastError="file is empty";
|
||||||
} else {
|
} else {
|
||||||
perror("tell error");
|
perror("tell error");
|
||||||
|
@ -1662,7 +1662,7 @@ int FurnaceGUI::load(String path) {
|
||||||
fclose(f);
|
fclose(f);
|
||||||
if (!e->load(file,(size_t)len)) {
|
if (!e->load(file,(size_t)len)) {
|
||||||
lastError=e->getLastError();
|
lastError=e->getLastError();
|
||||||
logE("could not open file!\n");
|
logE("could not open file!");
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2076,7 +2076,7 @@ bool FurnaceGUI::loop() {
|
||||||
macroLoopDragActive=false;
|
macroLoopDragActive=false;
|
||||||
waveDragActive=false;
|
waveDragActive=false;
|
||||||
if (sampleDragActive) {
|
if (sampleDragActive) {
|
||||||
logD("stopping sample drag\n");
|
logD("stopping sample drag");
|
||||||
if (sampleDragMode) {
|
if (sampleDragMode) {
|
||||||
e->renderSamplesP();
|
e->renderSamplesP();
|
||||||
} else {
|
} else {
|
||||||
|
@ -2506,6 +2506,7 @@ bool FurnaceGUI::loop() {
|
||||||
if (ImGui::MenuItem("oscilloscope",BIND_FOR(GUI_ACTION_WINDOW_OSCILLOSCOPE),oscOpen)) oscOpen=!oscOpen;
|
if (ImGui::MenuItem("oscilloscope",BIND_FOR(GUI_ACTION_WINDOW_OSCILLOSCOPE),oscOpen)) oscOpen=!oscOpen;
|
||||||
if (ImGui::MenuItem("volume meter",BIND_FOR(GUI_ACTION_WINDOW_VOL_METER),volMeterOpen)) volMeterOpen=!volMeterOpen;
|
if (ImGui::MenuItem("volume meter",BIND_FOR(GUI_ACTION_WINDOW_VOL_METER),volMeterOpen)) volMeterOpen=!volMeterOpen;
|
||||||
if (ImGui::MenuItem("register view",BIND_FOR(GUI_ACTION_WINDOW_REGISTER_VIEW),regViewOpen)) regViewOpen=!regViewOpen;
|
if (ImGui::MenuItem("register view",BIND_FOR(GUI_ACTION_WINDOW_REGISTER_VIEW),regViewOpen)) regViewOpen=!regViewOpen;
|
||||||
|
if (ImGui::MenuItem("log viewer",BIND_FOR(GUI_ACTION_WINDOW_LOG),logOpen)) logOpen=!logOpen;
|
||||||
if (ImGui::MenuItem("statistics",BIND_FOR(GUI_ACTION_WINDOW_STATS),statsOpen)) statsOpen=!statsOpen;
|
if (ImGui::MenuItem("statistics",BIND_FOR(GUI_ACTION_WINDOW_STATS),statsOpen)) statsOpen=!statsOpen;
|
||||||
|
|
||||||
ImGui::EndMenu();
|
ImGui::EndMenu();
|
||||||
|
@ -2613,6 +2614,7 @@ bool FurnaceGUI::loop() {
|
||||||
drawNotes();
|
drawNotes();
|
||||||
drawChannels();
|
drawChannels();
|
||||||
drawRegView();
|
drawRegView();
|
||||||
|
drawLog();
|
||||||
|
|
||||||
if (inspectorOpen) ImGui::ShowMetricsWindow(&inspectorOpen);
|
if (inspectorOpen) ImGui::ShowMetricsWindow(&inspectorOpen);
|
||||||
|
|
||||||
|
@ -2713,7 +2715,7 @@ bool FurnaceGUI::loop() {
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case GUI_FILE_SAVE: {
|
case GUI_FILE_SAVE: {
|
||||||
logD("saving: %s\n",copyOfName.c_str());
|
logD("saving: %s",copyOfName.c_str());
|
||||||
String lowerCase=fileName;
|
String lowerCase=fileName;
|
||||||
for (char& i: lowerCase) {
|
for (char& i: lowerCase) {
|
||||||
if (i>='A' && i<='Z') i+='a'-'A';
|
if (i>='A' && i<='Z') i+='a'-'A';
|
||||||
|
@ -2730,7 +2732,7 @@ bool FurnaceGUI::loop() {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case GUI_FILE_SAVE_DMF_LEGACY:
|
case GUI_FILE_SAVE_DMF_LEGACY:
|
||||||
logD("saving: %s\n",copyOfName.c_str());
|
logD("saving: %s",copyOfName.c_str());
|
||||||
if (save(copyOfName,24)>0) {
|
if (save(copyOfName,24)>0) {
|
||||||
showError(fmt::sprintf("Error while saving file! (%s)",lastError));
|
showError(fmt::sprintf("Error while saving file! (%s)",lastError));
|
||||||
}
|
}
|
||||||
|
@ -2865,7 +2867,7 @@ bool FurnaceGUI::loop() {
|
||||||
if (aboutOpen) drawAbout();
|
if (aboutOpen) drawAbout();
|
||||||
|
|
||||||
if (ImGui::BeginPopupModal("Rendering...",NULL,ImGuiWindowFlags_AlwaysAutoResize)) {
|
if (ImGui::BeginPopupModal("Rendering...",NULL,ImGuiWindowFlags_AlwaysAutoResize)) {
|
||||||
ImGui::Text("Please wait...\n");
|
ImGui::Text("Please wait...");
|
||||||
if (ImGui::Button("Abort")) {
|
if (ImGui::Button("Abort")) {
|
||||||
if (e->haltAudioFile()) {
|
if (e->haltAudioFile()) {
|
||||||
ImGui::CloseCurrentPopup();
|
ImGui::CloseCurrentPopup();
|
||||||
|
@ -2947,22 +2949,22 @@ bool FurnaceGUI::loop() {
|
||||||
if (backupTimer<=0) {
|
if (backupTimer<=0) {
|
||||||
backupTask=std::async(std::launch::async,[this]() -> bool {
|
backupTask=std::async(std::launch::async,[this]() -> bool {
|
||||||
if (backupPath==curFileName) {
|
if (backupPath==curFileName) {
|
||||||
logD("backup file open. not saving backup.\n");
|
logD("backup file open. not saving backup.");
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
logD("saving backup...\n");
|
logD("saving backup...");
|
||||||
SafeWriter* w=e->saveFur(true);
|
SafeWriter* w=e->saveFur(true);
|
||||||
|
|
||||||
if (w!=NULL) {
|
if (w!=NULL) {
|
||||||
FILE* outFile=ps_fopen(backupPath.c_str(),"wb");
|
FILE* outFile=ps_fopen(backupPath.c_str(),"wb");
|
||||||
if (outFile!=NULL) {
|
if (outFile!=NULL) {
|
||||||
if (fwrite(w->getFinalBuf(),1,w->size(),outFile)!=w->size()) {
|
if (fwrite(w->getFinalBuf(),1,w->size(),outFile)!=w->size()) {
|
||||||
logW("did not write backup entirely: %s!\n",strerror(errno));
|
logW("did not write backup entirely: %s!",strerror(errno));
|
||||||
w->finish();
|
w->finish();
|
||||||
}
|
}
|
||||||
fclose(outFile);
|
fclose(outFile);
|
||||||
} else {
|
} else {
|
||||||
logW("could not save backup: %s!\n",strerror(errno));
|
logW("could not save backup: %s!",strerror(errno));
|
||||||
w->finish();
|
w->finish();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -3037,6 +3039,7 @@ bool FurnaceGUI::init() {
|
||||||
notesOpen=e->getConfBool("notesOpen",false);
|
notesOpen=e->getConfBool("notesOpen",false);
|
||||||
channelsOpen=e->getConfBool("channelsOpen",false);
|
channelsOpen=e->getConfBool("channelsOpen",false);
|
||||||
regViewOpen=e->getConfBool("regViewOpen",false);
|
regViewOpen=e->getConfBool("regViewOpen",false);
|
||||||
|
logOpen=e->getConfBool("logOpen",false);
|
||||||
|
|
||||||
tempoView=e->getConfBool("tempoView",true);
|
tempoView=e->getConfBool("tempoView",true);
|
||||||
waveHex=e->getConfBool("waveHex",false);
|
waveHex=e->getConfBool("waveHex",false);
|
||||||
|
@ -3066,7 +3069,7 @@ bool FurnaceGUI::init() {
|
||||||
|
|
||||||
sdlWin=SDL_CreateWindow("Furnace",SDL_WINDOWPOS_CENTERED,SDL_WINDOWPOS_CENTERED,scrW*dpiScale,scrH*dpiScale,SDL_WINDOW_RESIZABLE|SDL_WINDOW_ALLOW_HIGHDPI);
|
sdlWin=SDL_CreateWindow("Furnace",SDL_WINDOWPOS_CENTERED,SDL_WINDOWPOS_CENTERED,scrW*dpiScale,scrH*dpiScale,SDL_WINDOW_RESIZABLE|SDL_WINDOW_ALLOW_HIGHDPI);
|
||||||
if (sdlWin==NULL) {
|
if (sdlWin==NULL) {
|
||||||
logE("could not open window! %s\n",SDL_GetError());
|
logE("could not open window! %s",SDL_GetError());
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3091,14 +3094,14 @@ bool FurnaceGUI::init() {
|
||||||
SDL_FreeSurface(icon);
|
SDL_FreeSurface(icon);
|
||||||
free(furIcon);
|
free(furIcon);
|
||||||
} else {
|
} else {
|
||||||
logW("could not create icon!\n");
|
logW("could not create icon!");
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
sdlRend=SDL_CreateRenderer(sdlWin,-1,SDL_RENDERER_ACCELERATED|SDL_RENDERER_PRESENTVSYNC|SDL_RENDERER_TARGETTEXTURE);
|
sdlRend=SDL_CreateRenderer(sdlWin,-1,SDL_RENDERER_ACCELERATED|SDL_RENDERER_PRESENTVSYNC|SDL_RENDERER_TARGETTEXTURE);
|
||||||
|
|
||||||
if (sdlRend==NULL) {
|
if (sdlRend==NULL) {
|
||||||
logE("could not init renderer! %s\n",SDL_GetError());
|
logE("could not init renderer! %s",SDL_GetError());
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3115,14 +3118,14 @@ bool FurnaceGUI::init() {
|
||||||
applyUISettings();
|
applyUISettings();
|
||||||
|
|
||||||
if (!ImGui::GetIO().Fonts->Build()) {
|
if (!ImGui::GetIO().Fonts->Build()) {
|
||||||
logE("error while building font atlas!\n");
|
logE("error while building font atlas!");
|
||||||
showError("error while loading fonts! please check your settings.");
|
showError("error while loading fonts! please check your settings.");
|
||||||
ImGui::GetIO().Fonts->Clear();
|
ImGui::GetIO().Fonts->Clear();
|
||||||
mainFont=ImGui::GetIO().Fonts->AddFontDefault();
|
mainFont=ImGui::GetIO().Fonts->AddFontDefault();
|
||||||
patFont=mainFont;
|
patFont=mainFont;
|
||||||
ImGui_ImplSDLRenderer_DestroyFontsTexture();
|
ImGui_ImplSDLRenderer_DestroyFontsTexture();
|
||||||
if (!ImGui::GetIO().Fonts->Build()) {
|
if (!ImGui::GetIO().Fonts->Build()) {
|
||||||
logE("error again while building font atlas!\n");
|
logE("error again while building font atlas!");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3199,6 +3202,7 @@ bool FurnaceGUI::finish() {
|
||||||
e->setConf("notesOpen",notesOpen);
|
e->setConf("notesOpen",notesOpen);
|
||||||
e->setConf("channelsOpen",channelsOpen);
|
e->setConf("channelsOpen",channelsOpen);
|
||||||
e->setConf("regViewOpen",regViewOpen);
|
e->setConf("regViewOpen",regViewOpen);
|
||||||
|
e->setConf("logOpen",logOpen);
|
||||||
|
|
||||||
// commit last window size
|
// commit last window size
|
||||||
e->setConf("lastWindowWidth",scrW);
|
e->setConf("lastWindowWidth",scrW);
|
||||||
|
@ -3298,6 +3302,7 @@ FurnaceGUI::FurnaceGUI():
|
||||||
notesOpen(false),
|
notesOpen(false),
|
||||||
channelsOpen(false),
|
channelsOpen(false),
|
||||||
regViewOpen(false),
|
regViewOpen(false),
|
||||||
|
logOpen(false),
|
||||||
/*
|
/*
|
||||||
editControlsDocked(false),
|
editControlsDocked(false),
|
||||||
ordersDocked(false),
|
ordersDocked(false),
|
||||||
|
|
|
@ -167,6 +167,12 @@ enum FurnaceGUIColors {
|
||||||
GUI_COLOR_PATTERN_EFFECT_SYS_SECONDARY,
|
GUI_COLOR_PATTERN_EFFECT_SYS_SECONDARY,
|
||||||
GUI_COLOR_PATTERN_EFFECT_MISC,
|
GUI_COLOR_PATTERN_EFFECT_MISC,
|
||||||
|
|
||||||
|
GUI_COLOR_LOGLEVEL_ERROR,
|
||||||
|
GUI_COLOR_LOGLEVEL_WARNING,
|
||||||
|
GUI_COLOR_LOGLEVEL_INFO,
|
||||||
|
GUI_COLOR_LOGLEVEL_DEBUG,
|
||||||
|
GUI_COLOR_LOGLEVEL_TRACE,
|
||||||
|
|
||||||
GUI_COLOR_EE_VALUE,
|
GUI_COLOR_EE_VALUE,
|
||||||
GUI_COLOR_PLAYBACK_STAT,
|
GUI_COLOR_PLAYBACK_STAT,
|
||||||
GUI_COLOR_MAX
|
GUI_COLOR_MAX
|
||||||
|
@ -195,7 +201,8 @@ enum FurnaceGUIWindows {
|
||||||
GUI_WINDOW_PIANO,
|
GUI_WINDOW_PIANO,
|
||||||
GUI_WINDOW_NOTES,
|
GUI_WINDOW_NOTES,
|
||||||
GUI_WINDOW_CHANNELS,
|
GUI_WINDOW_CHANNELS,
|
||||||
GUI_WINDOW_REGISTER_VIEW
|
GUI_WINDOW_REGISTER_VIEW,
|
||||||
|
GUI_WINDOW_LOG
|
||||||
};
|
};
|
||||||
|
|
||||||
enum FurnaceGUIFileDialogs {
|
enum FurnaceGUIFileDialogs {
|
||||||
|
@ -290,6 +297,7 @@ enum FurnaceGUIActions {
|
||||||
GUI_ACTION_WINDOW_NOTES,
|
GUI_ACTION_WINDOW_NOTES,
|
||||||
GUI_ACTION_WINDOW_CHANNELS,
|
GUI_ACTION_WINDOW_CHANNELS,
|
||||||
GUI_ACTION_WINDOW_REGISTER_VIEW,
|
GUI_ACTION_WINDOW_REGISTER_VIEW,
|
||||||
|
GUI_ACTION_WINDOW_LOG,
|
||||||
|
|
||||||
GUI_ACTION_COLLAPSE_WINDOW,
|
GUI_ACTION_COLLAPSE_WINDOW,
|
||||||
GUI_ACTION_CLOSE_WINDOW,
|
GUI_ACTION_CLOSE_WINDOW,
|
||||||
|
@ -848,7 +856,7 @@ class FurnaceGUI {
|
||||||
bool editControlsOpen, ordersOpen, insListOpen, songInfoOpen, patternOpen, insEditOpen;
|
bool editControlsOpen, ordersOpen, insListOpen, songInfoOpen, patternOpen, insEditOpen;
|
||||||
bool waveListOpen, waveEditOpen, sampleListOpen, sampleEditOpen, aboutOpen, settingsOpen;
|
bool waveListOpen, waveEditOpen, sampleListOpen, sampleEditOpen, aboutOpen, settingsOpen;
|
||||||
bool mixerOpen, debugOpen, inspectorOpen, oscOpen, volMeterOpen, statsOpen, compatFlagsOpen;
|
bool mixerOpen, debugOpen, inspectorOpen, oscOpen, volMeterOpen, statsOpen, compatFlagsOpen;
|
||||||
bool pianoOpen, notesOpen, channelsOpen, regViewOpen;
|
bool pianoOpen, notesOpen, channelsOpen, regViewOpen, logOpen;
|
||||||
|
|
||||||
/* there ought to be a better way...
|
/* there ought to be a better way...
|
||||||
bool editControlsDocked, ordersDocked, insListDocked, songInfoDocked, patternDocked, insEditDocked;
|
bool editControlsDocked, ordersDocked, insListDocked, songInfoDocked, patternDocked, insEditDocked;
|
||||||
|
@ -1044,6 +1052,7 @@ class FurnaceGUI {
|
||||||
void drawSettings();
|
void drawSettings();
|
||||||
void drawDebug();
|
void drawDebug();
|
||||||
void drawNewSong();
|
void drawNewSong();
|
||||||
|
void drawLog();
|
||||||
|
|
||||||
void parseKeybinds();
|
void parseKeybinds();
|
||||||
void promptKey(int which);
|
void promptKey(int which);
|
||||||
|
|
|
@ -191,6 +191,7 @@ const FurnaceGUIActionDef guiActions[GUI_ACTION_MAX]={
|
||||||
D("WINDOW_NOTES", "Song Comments", 0),
|
D("WINDOW_NOTES", "Song Comments", 0),
|
||||||
D("WINDOW_CHANNELS", "Channels", 0),
|
D("WINDOW_CHANNELS", "Channels", 0),
|
||||||
D("WINDOW_REGISTER_VIEW", "Register View", 0),
|
D("WINDOW_REGISTER_VIEW", "Register View", 0),
|
||||||
|
D("WINDOW_LOG", "Log Viewer", 0),
|
||||||
|
|
||||||
D("COLLAPSE_WINDOW", "Collapse/expand current window", 0),
|
D("COLLAPSE_WINDOW", "Collapse/expand current window", 0),
|
||||||
D("CLOSE_WINDOW", "Close current window", FURKMOD_SHIFT|SDLK_ESCAPE),
|
D("CLOSE_WINDOW", "Close current window", FURKMOD_SHIFT|SDLK_ESCAPE),
|
||||||
|
@ -473,6 +474,12 @@ const FurnaceGUIColorDef guiColors[GUI_COLOR_MAX]={
|
||||||
D(GUI_COLOR_PATTERN_EFFECT_SYS_SECONDARY,"",ImVec4(0.0f,1.0f,0.5f,1.0f)),
|
D(GUI_COLOR_PATTERN_EFFECT_SYS_SECONDARY,"",ImVec4(0.0f,1.0f,0.5f,1.0f)),
|
||||||
D(GUI_COLOR_PATTERN_EFFECT_MISC,"",ImVec4(0.3f,0.3f,1.0f,1.0f)),
|
D(GUI_COLOR_PATTERN_EFFECT_MISC,"",ImVec4(0.3f,0.3f,1.0f,1.0f)),
|
||||||
|
|
||||||
|
D(GUI_COLOR_LOGLEVEL_ERROR,"",ImVec4(1.0f,0.2f,0.2f,1.0f)),
|
||||||
|
D(GUI_COLOR_LOGLEVEL_WARNING,"",ImVec4(1.0f,1.0f,0.2f,1.0f)),
|
||||||
|
D(GUI_COLOR_LOGLEVEL_INFO,"",ImVec4(0.4f,1.0f,0.4f,1.0f)),
|
||||||
|
D(GUI_COLOR_LOGLEVEL_DEBUG,"",ImVec4(0.3f,0.5f,1.0f,1.0f)),
|
||||||
|
D(GUI_COLOR_LOGLEVEL_TRACE,"",ImVec4(0.8f,0.8f,0.8f,1.0f)),
|
||||||
|
|
||||||
D(GUI_COLOR_EE_VALUE,"",ImVec4(0.0f,1.0f,1.0f,1.0f)),
|
D(GUI_COLOR_EE_VALUE,"",ImVec4(0.0f,1.0f,1.0f,1.0f)),
|
||||||
D(GUI_COLOR_PLAYBACK_STAT,"",ImVec4(0.6f,0.6f,0.6f,1.0f)),
|
D(GUI_COLOR_PLAYBACK_STAT,"",ImVec4(0.6f,0.6f,0.6f,1.0f)),
|
||||||
};
|
};
|
||||||
|
|
|
@ -0,0 +1,71 @@
|
||||||
|
#include "gui.h"
|
||||||
|
#include "../ta-log.h"
|
||||||
|
#include <chrono>
|
||||||
|
#include <imgui.h>
|
||||||
|
|
||||||
|
const char* logLevels[5]={
|
||||||
|
"ERROR",
|
||||||
|
"warning",
|
||||||
|
"info",
|
||||||
|
"debug",
|
||||||
|
"trace"
|
||||||
|
};
|
||||||
|
|
||||||
|
FurnaceGUIColors logColors[5]={
|
||||||
|
GUI_COLOR_LOGLEVEL_ERROR,
|
||||||
|
GUI_COLOR_LOGLEVEL_WARNING,
|
||||||
|
GUI_COLOR_LOGLEVEL_INFO,
|
||||||
|
GUI_COLOR_LOGLEVEL_DEBUG,
|
||||||
|
GUI_COLOR_LOGLEVEL_TRACE
|
||||||
|
};
|
||||||
|
|
||||||
|
void FurnaceGUI::drawLog() {
|
||||||
|
if (nextWindow==GUI_WINDOW_LOG) {
|
||||||
|
logOpen=true;
|
||||||
|
ImGui::SetNextWindowFocus();
|
||||||
|
nextWindow=GUI_WINDOW_NOTHING;
|
||||||
|
}
|
||||||
|
if (!logOpen) return;
|
||||||
|
if (ImGui::Begin("Log Viewer",&logOpen)) {
|
||||||
|
ImGui::Text("Level");
|
||||||
|
ImGui::SameLine();
|
||||||
|
ImGui::Combo("##LogLevel",&logLevel,logLevels,5);
|
||||||
|
if (ImGui::BeginTable("LogView",3,ImGuiTableFlags_ScrollY|ImGuiTableFlags_BordersInnerV)) {
|
||||||
|
ImGui::PushFont(patFont);
|
||||||
|
|
||||||
|
float timeChars=ImGui::CalcTextSize("00:00:00").x;
|
||||||
|
float levelChars=ImGui::CalcTextSize("warning").x;
|
||||||
|
|
||||||
|
ImGui::TableSetupColumn("c0",ImGuiTableColumnFlags_WidthFixed,timeChars);
|
||||||
|
ImGui::TableSetupColumn("c1",ImGuiTableColumnFlags_WidthFixed,levelChars);
|
||||||
|
ImGui::TableSetupColumn("c2",ImGuiTableColumnFlags_WidthStretch);
|
||||||
|
|
||||||
|
ImGui::TableNextRow(ImGuiTableRowFlags_Headers);
|
||||||
|
ImGui::TableNextColumn();
|
||||||
|
ImGui::TextUnformatted("time");
|
||||||
|
ImGui::TableNextColumn();
|
||||||
|
ImGui::TextUnformatted("level");
|
||||||
|
ImGui::TableNextColumn();
|
||||||
|
ImGui::TextUnformatted("message");
|
||||||
|
|
||||||
|
int pos=logPosition;
|
||||||
|
for (int i=0; i<TA_LOG_SIZE; i++) {
|
||||||
|
const LogEntry& logEntry=logEntries[(pos+i)&(TA_LOG_SIZE-1)];
|
||||||
|
if (!logEntry.ready) continue;
|
||||||
|
if (logLevel<logEntry.loglevel) continue;
|
||||||
|
ssize_t t=std::chrono::time_point_cast<std::chrono::seconds>(logEntry.time).time_since_epoch().count();
|
||||||
|
ImGui::TableNextRow();
|
||||||
|
ImGui::TableNextColumn();
|
||||||
|
// this will fail on 32-bit :<
|
||||||
|
ImGui::Text("%02ld:%02ld:%02ld",(t/3600)%24,(t/60)%60,t%60);
|
||||||
|
ImGui::TableNextColumn();
|
||||||
|
ImGui::TextColored(uiColors[logColors[logEntry.loglevel]],"%s",logLevels[logEntry.loglevel]);
|
||||||
|
ImGui::TableNextColumn();
|
||||||
|
ImGui::TextWrapped("%s",logEntry.text.c_str());
|
||||||
|
}
|
||||||
|
ImGui::PopFont();
|
||||||
|
ImGui::EndTable();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ImGui::End();
|
||||||
|
}
|
|
@ -64,7 +64,7 @@ int MIDIMap::at(const TAMidiMessage& where) {
|
||||||
|
|
||||||
#define UNDERSTAND_ARRAY_OPTION(x,yMax) if (optionNameS==#x) { \
|
#define UNDERSTAND_ARRAY_OPTION(x,yMax) if (optionNameS==#x) { \
|
||||||
if (optionIndex<0 || optionIndex>=yMax) { \
|
if (optionIndex<0 || optionIndex>=yMax) { \
|
||||||
logW("MIDI map array option %d out of range (0-%d) at line %d: %s\n",optionIndex,yMax,curLine,line); \
|
logW("MIDI map array option %d out of range (0-%d) at line %d: %s",optionIndex,yMax,curLine,line); \
|
||||||
break; \
|
break; \
|
||||||
} \
|
} \
|
||||||
x[optionIndex]=std::stoi(optionValueS); \
|
x[optionIndex]=std::stoi(optionValueS); \
|
||||||
|
@ -76,7 +76,7 @@ bool MIDIMap::read(String path) {
|
||||||
FILE* f=fopen(path.c_str(),"rb");
|
FILE* f=fopen(path.c_str(),"rb");
|
||||||
if (f==NULL) {
|
if (f==NULL) {
|
||||||
if (errno!=ENOENT) {
|
if (errno!=ENOENT) {
|
||||||
logE("error while loading MIDI mapping! %s\n",strerror(errno));
|
logE("error while loading MIDI mapping! %s",strerror(errno));
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -93,7 +93,7 @@ bool MIDIMap::read(String path) {
|
||||||
|
|
||||||
int result=sscanf(line,"aOption %255s %d %255s",optionName,&optionIndex,optionValue);
|
int result=sscanf(line,"aOption %255s %d %255s",optionName,&optionIndex,optionValue);
|
||||||
if (result!=3) {
|
if (result!=3) {
|
||||||
logW("MIDI map garbage data at line %d: %s\n",curLine,line);
|
logW("MIDI map garbage data at line %d: %s",curLine,line);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -105,12 +105,12 @@ bool MIDIMap::read(String path) {
|
||||||
UNDERSTAND_ARRAY_OPTION(valueInputSpecificMSB,18) else
|
UNDERSTAND_ARRAY_OPTION(valueInputSpecificMSB,18) else
|
||||||
UNDERSTAND_ARRAY_OPTION(valueInputSpecificLSB,18) else
|
UNDERSTAND_ARRAY_OPTION(valueInputSpecificLSB,18) else
|
||||||
UNDERSTAND_ARRAY_OPTION(valueInputSpecificSingle,18) else {
|
UNDERSTAND_ARRAY_OPTION(valueInputSpecificSingle,18) else {
|
||||||
logW("MIDI map unknown array option %s at line %d: %s\n",optionName,curLine,line);
|
logW("MIDI map unknown array option %s at line %d: %s",optionName,curLine,line);
|
||||||
}
|
}
|
||||||
} catch (std::out_of_range& e) {
|
} catch (std::out_of_range& e) {
|
||||||
logW("MIDI map invalid value %s for array option %s at line %d: %s\n",optionValue,optionName,curLine,line);
|
logW("MIDI map invalid value %s for array option %s at line %d: %s",optionValue,optionName,curLine,line);
|
||||||
} catch (std::invalid_argument& e) {
|
} catch (std::invalid_argument& e) {
|
||||||
logW("MIDI map invalid value %s for array option %s at line %d: %s\n",optionValue,optionName,curLine,line);
|
logW("MIDI map invalid value %s for array option %s at line %d: %s",optionValue,optionName,curLine,line);
|
||||||
}
|
}
|
||||||
|
|
||||||
curLine++;
|
curLine++;
|
||||||
|
@ -122,7 +122,7 @@ bool MIDIMap::read(String path) {
|
||||||
String optionNameS, optionValueS;
|
String optionNameS, optionValueS;
|
||||||
int result=sscanf(line,"option %255s %255s",optionName,optionValue);
|
int result=sscanf(line,"option %255s %255s",optionName,optionValue);
|
||||||
if (result!=2) {
|
if (result!=2) {
|
||||||
logW("MIDI map garbage data at line %d: %s\n",curLine,line);
|
logW("MIDI map garbage data at line %d: %s",curLine,line);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -143,12 +143,12 @@ bool MIDIMap::read(String path) {
|
||||||
UNDERSTAND_OPTION(valueInputControlLSB) else
|
UNDERSTAND_OPTION(valueInputControlLSB) else
|
||||||
UNDERSTAND_OPTION(valueInputControlSingle) else
|
UNDERSTAND_OPTION(valueInputControlSingle) else
|
||||||
UNDERSTAND_FLOAT_OPTION(volExp) else {
|
UNDERSTAND_FLOAT_OPTION(volExp) else {
|
||||||
logW("MIDI map unknown option %s at line %d: %s\n",optionName,curLine,line);
|
logW("MIDI map unknown option %s at line %d: %s",optionName,curLine,line);
|
||||||
}
|
}
|
||||||
} catch (std::out_of_range& e) {
|
} catch (std::out_of_range& e) {
|
||||||
logW("MIDI map invalid value %s for option %s at line %d: %s\n",optionValue,optionName,curLine,line);
|
logW("MIDI map invalid value %s for option %s at line %d: %s",optionValue,optionName,curLine,line);
|
||||||
} catch (std::invalid_argument& e) {
|
} catch (std::invalid_argument& e) {
|
||||||
logW("MIDI map invalid value %s for option %s at line %d: %s\n",optionValue,optionName,curLine,line);
|
logW("MIDI map invalid value %s for option %s at line %d: %s",optionValue,optionName,curLine,line);
|
||||||
}
|
}
|
||||||
|
|
||||||
curLine++;
|
curLine++;
|
||||||
|
@ -159,7 +159,7 @@ bool MIDIMap::read(String path) {
|
||||||
MIDIBind bind;
|
MIDIBind bind;
|
||||||
int result=sscanf(line,"%d %d %d %d %255s",&bind.type,&bind.channel,&bind.data1,&bind.data2,bindAction);
|
int result=sscanf(line,"%d %d %d %d %255s",&bind.type,&bind.channel,&bind.data1,&bind.data2,bindAction);
|
||||||
if (result!=5 || result==EOF) {
|
if (result!=5 || result==EOF) {
|
||||||
logW("MIDI map garbage data at line %d: %s\n",curLine,line);
|
logW("MIDI map garbage data at line %d: %s",curLine,line);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -172,7 +172,7 @@ bool MIDIMap::read(String path) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!foundAction) {
|
if (!foundAction) {
|
||||||
logW("MIDI map unknown action %s at line %d: %s\n",bindAction,curLine,line);
|
logW("MIDI map unknown action %s at line %d: %s",bindAction,curLine,line);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -191,7 +191,7 @@ bool MIDIMap::read(String path) {
|
||||||
bool MIDIMap::write(String path) {
|
bool MIDIMap::write(String path) {
|
||||||
FILE* f=fopen(path.c_str(),"wb");
|
FILE* f=fopen(path.c_str(),"wb");
|
||||||
if (f==NULL) {
|
if (f==NULL) {
|
||||||
logE("error while saving MIDI mapping! %s\n",strerror(errno));
|
logE("error while saving MIDI mapping! %s",strerror(errno));
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -218,7 +218,7 @@ bool MIDIMap::write(String path) {
|
||||||
|
|
||||||
for (MIDIBind& i: binds) {
|
for (MIDIBind& i: binds) {
|
||||||
if (fprintf(f,"%d %d %d %d %s\n",i.type,i.channel,i.data1,i.data2,guiActions[i.action].name)<0) {
|
if (fprintf(f,"%d %d %d %d %s\n",i.type,i.channel,i.data1,i.data2,guiActions[i.action].name)<0) {
|
||||||
logW("did not write MIDI mapping entirely! %s\n",strerror(errno));
|
logW("did not write MIDI mapping entirely! %s",strerror(errno));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -274,6 +274,6 @@ void MIDIMap::compile() {
|
||||||
}
|
}
|
||||||
|
|
||||||
map[i.type-8][i.channel][i.data1][i.data2]=i.action;
|
map[i.type-8][i.channel][i.data1][i.data2]=i.action;
|
||||||
logD("MIDI mapping %d %d %d %d to %d\n",i.type-8,i.channel,i.data1,i.data2,i.action);
|
logD("MIDI mapping %d %d %d %d to %d",i.type-8,i.channel,i.data1,i.data2,i.action);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -874,6 +874,6 @@ void FurnaceGUI::drawPattern() {
|
||||||
if (ImGui::IsWindowFocused(ImGuiFocusedFlags_ChildWindows)) curWindow=GUI_WINDOW_PATTERN;
|
if (ImGui::IsWindowFocused(ImGuiFocusedFlags_ChildWindows)) curWindow=GUI_WINDOW_PATTERN;
|
||||||
ImGui::End();
|
ImGui::End();
|
||||||
//int delta1=SDL_GetPerformanceCounter();
|
//int delta1=SDL_GetPerformanceCounter();
|
||||||
//logV("render time: %dµs\n",(delta1-delta0)/(SDL_GetPerformanceFrequency()/1000000));
|
//logV("render time: %dµs",(delta1-delta0)/(SDL_GetPerformanceFrequency()/1000000));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -579,12 +579,12 @@ void FurnaceGUI::drawSampleEdit() {
|
||||||
sampleTex=NULL;
|
sampleTex=NULL;
|
||||||
}
|
}
|
||||||
if (avail.x>=1 && avail.y>=1) {
|
if (avail.x>=1 && avail.y>=1) {
|
||||||
logD("recreating sample texture.\n");
|
logD("recreating sample texture.");
|
||||||
sampleTex=SDL_CreateTexture(sdlRend,SDL_PIXELFORMAT_ABGR8888,SDL_TEXTUREACCESS_STREAMING,avail.x,avail.y);
|
sampleTex=SDL_CreateTexture(sdlRend,SDL_PIXELFORMAT_ABGR8888,SDL_TEXTUREACCESS_STREAMING,avail.x,avail.y);
|
||||||
sampleTexW=avail.x;
|
sampleTexW=avail.x;
|
||||||
sampleTexH=avail.y;
|
sampleTexH=avail.y;
|
||||||
if (sampleTex==NULL) {
|
if (sampleTex==NULL) {
|
||||||
logE("error while creating sample texture! %s\n",SDL_GetError());
|
logE("error while creating sample texture! %s",SDL_GetError());
|
||||||
} else {
|
} else {
|
||||||
updateSampleTex=true;
|
updateSampleTex=true;
|
||||||
}
|
}
|
||||||
|
@ -595,9 +595,9 @@ void FurnaceGUI::drawSampleEdit() {
|
||||||
if (updateSampleTex) {
|
if (updateSampleTex) {
|
||||||
unsigned int* data=NULL;
|
unsigned int* data=NULL;
|
||||||
int pitch=0;
|
int pitch=0;
|
||||||
logD("updating sample texture.\n");
|
logD("updating sample texture.");
|
||||||
if (SDL_LockTexture(sampleTex,NULL,(void**)&data,&pitch)!=0) {
|
if (SDL_LockTexture(sampleTex,NULL,(void**)&data,&pitch)!=0) {
|
||||||
logE("error while locking sample texture! %s\n",SDL_GetError());
|
logE("error while locking sample texture! %s",SDL_GetError());
|
||||||
} else {
|
} else {
|
||||||
ImU32 bgColor=ImGui::GetColorU32(ImGuiCol_FrameBg);
|
ImU32 bgColor=ImGui::GetColorU32(ImGuiCol_FrameBg);
|
||||||
ImU32 bgColorLoop=ImAlphaBlendColors(bgColor,ImGui::GetColorU32(ImGuiCol_FrameBgHovered,0.5));
|
ImU32 bgColorLoop=ImAlphaBlendColors(bgColor,ImGui::GetColorU32(ImGuiCol_FrameBgHovered,0.5));
|
||||||
|
|
|
@ -384,8 +384,8 @@ void FurnaceGUI::drawSettings() {
|
||||||
TAAudioDesc& audioWant=e->getAudioDescWant();
|
TAAudioDesc& audioWant=e->getAudioDescWant();
|
||||||
TAAudioDesc& audioGot=e->getAudioDescGot();
|
TAAudioDesc& audioGot=e->getAudioDescGot();
|
||||||
|
|
||||||
ImGui::Text("want: %d samples @ %.0fHz\n",audioWant.bufsize,audioWant.rate);
|
ImGui::Text("want: %d samples @ %.0fHz",audioWant.bufsize,audioWant.rate);
|
||||||
ImGui::Text("got: %d samples @ %.0fHz\n",audioGot.bufsize,audioGot.rate);
|
ImGui::Text("got: %d samples @ %.0fHz",audioGot.bufsize,audioGot.rate);
|
||||||
|
|
||||||
ImGui::Separator();
|
ImGui::Separator();
|
||||||
|
|
||||||
|
@ -1053,6 +1053,14 @@ void FurnaceGUI::drawSettings() {
|
||||||
UI_COLOR_CONFIG(GUI_COLOR_EE_VALUE,"External command output");
|
UI_COLOR_CONFIG(GUI_COLOR_EE_VALUE,"External command output");
|
||||||
ImGui::TreePop();
|
ImGui::TreePop();
|
||||||
}
|
}
|
||||||
|
if (ImGui::TreeNode("Log Viewer")) {
|
||||||
|
UI_COLOR_CONFIG(GUI_COLOR_LOGLEVEL_ERROR,"Log level: Error");
|
||||||
|
UI_COLOR_CONFIG(GUI_COLOR_LOGLEVEL_WARNING,"Log level: Warning");
|
||||||
|
UI_COLOR_CONFIG(GUI_COLOR_LOGLEVEL_INFO,"Log level: Info");
|
||||||
|
UI_COLOR_CONFIG(GUI_COLOR_LOGLEVEL_DEBUG,"Log level: Debug");
|
||||||
|
UI_COLOR_CONFIG(GUI_COLOR_LOGLEVEL_TRACE,"Log level: Trace/Verbose");
|
||||||
|
ImGui::TreePop();
|
||||||
|
}
|
||||||
ImGui::TreePop();
|
ImGui::TreePop();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1126,6 +1134,7 @@ void FurnaceGUI::drawSettings() {
|
||||||
UI_KEYBIND_CONFIG(GUI_ACTION_WINDOW_NOTES);
|
UI_KEYBIND_CONFIG(GUI_ACTION_WINDOW_NOTES);
|
||||||
UI_KEYBIND_CONFIG(GUI_ACTION_WINDOW_CHANNELS);
|
UI_KEYBIND_CONFIG(GUI_ACTION_WINDOW_CHANNELS);
|
||||||
UI_KEYBIND_CONFIG(GUI_ACTION_WINDOW_REGISTER_VIEW);
|
UI_KEYBIND_CONFIG(GUI_ACTION_WINDOW_REGISTER_VIEW);
|
||||||
|
UI_KEYBIND_CONFIG(GUI_ACTION_WINDOW_LOG);
|
||||||
|
|
||||||
UI_KEYBIND_CONFIG(GUI_ACTION_COLLAPSE_WINDOW);
|
UI_KEYBIND_CONFIG(GUI_ACTION_COLLAPSE_WINDOW);
|
||||||
UI_KEYBIND_CONFIG(GUI_ACTION_CLOSE_WINDOW);
|
UI_KEYBIND_CONFIG(GUI_ACTION_CLOSE_WINDOW);
|
||||||
|
@ -1633,14 +1642,14 @@ void FurnaceGUI::commitSettings() {
|
||||||
|
|
||||||
ImGui_ImplSDLRenderer_DestroyFontsTexture();
|
ImGui_ImplSDLRenderer_DestroyFontsTexture();
|
||||||
if (!ImGui::GetIO().Fonts->Build()) {
|
if (!ImGui::GetIO().Fonts->Build()) {
|
||||||
logE("error while building font atlas!\n");
|
logE("error while building font atlas!");
|
||||||
showError("error while loading fonts! please check your settings.");
|
showError("error while loading fonts! please check your settings.");
|
||||||
ImGui::GetIO().Fonts->Clear();
|
ImGui::GetIO().Fonts->Clear();
|
||||||
mainFont=ImGui::GetIO().Fonts->AddFontDefault();
|
mainFont=ImGui::GetIO().Fonts->AddFontDefault();
|
||||||
patFont=mainFont;
|
patFont=mainFont;
|
||||||
ImGui_ImplSDLRenderer_DestroyFontsTexture();
|
ImGui_ImplSDLRenderer_DestroyFontsTexture();
|
||||||
if (!ImGui::GetIO().Fonts->Build()) {
|
if (!ImGui::GetIO().Fonts->Build()) {
|
||||||
logE("error again while building font atlas!\n");
|
logE("error again while building font atlas!");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1648,7 +1657,7 @@ void FurnaceGUI::commitSettings() {
|
||||||
bool FurnaceGUI::importColors(String path) {
|
bool FurnaceGUI::importColors(String path) {
|
||||||
FILE* f=ps_fopen(path.c_str(),"rb");
|
FILE* f=ps_fopen(path.c_str(),"rb");
|
||||||
if (f==NULL) {
|
if (f==NULL) {
|
||||||
logW("error while opening color file for import: %s\n",strerror(errno));
|
logW("error while opening color file for import: %s",strerror(errno));
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
resetColors();
|
resetColors();
|
||||||
|
@ -1689,7 +1698,7 @@ bool FurnaceGUI::importColors(String path) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!found) logW("line invalid: %s\n",line);
|
if (!found) logW("line invalid: %s",line);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
fclose(f);
|
fclose(f);
|
||||||
|
@ -1699,12 +1708,12 @@ bool FurnaceGUI::importColors(String path) {
|
||||||
bool FurnaceGUI::exportColors(String path) {
|
bool FurnaceGUI::exportColors(String path) {
|
||||||
FILE* f=ps_fopen(path.c_str(),"wb");
|
FILE* f=ps_fopen(path.c_str(),"wb");
|
||||||
if (f==NULL) {
|
if (f==NULL) {
|
||||||
logW("error while opening color file for export: %s\n",strerror(errno));
|
logW("error while opening color file for export: %s",strerror(errno));
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
for (int i=0; i<GUI_COLOR_MAX; i++) {
|
for (int i=0; i<GUI_COLOR_MAX; i++) {
|
||||||
if (fprintf(f,"%s=%d\n",guiColors[i].name,ImGui::ColorConvertFloat4ToU32(uiColors[i]))<0) {
|
if (fprintf(f,"%s=%d\n",guiColors[i].name,ImGui::ColorConvertFloat4ToU32(uiColors[i]))<0) {
|
||||||
logW("error while exporting colors: %s\n",strerror(errno));
|
logW("error while exporting colors: %s",strerror(errno));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1715,7 +1724,7 @@ bool FurnaceGUI::exportColors(String path) {
|
||||||
bool FurnaceGUI::importKeybinds(String path) {
|
bool FurnaceGUI::importKeybinds(String path) {
|
||||||
FILE* f=ps_fopen(path.c_str(),"rb");
|
FILE* f=ps_fopen(path.c_str(),"rb");
|
||||||
if (f==NULL) {
|
if (f==NULL) {
|
||||||
logW("error while opening keybind file for import: %s\n",strerror(errno));
|
logW("error while opening keybind file for import: %s",strerror(errno));
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
resetKeybinds();
|
resetKeybinds();
|
||||||
|
@ -1756,7 +1765,7 @@ bool FurnaceGUI::importKeybinds(String path) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!found) logW("line invalid: %s\n",line);
|
if (!found) logW("line invalid: %s",line);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
fclose(f);
|
fclose(f);
|
||||||
|
@ -1766,13 +1775,13 @@ bool FurnaceGUI::importKeybinds(String path) {
|
||||||
bool FurnaceGUI::exportKeybinds(String path) {
|
bool FurnaceGUI::exportKeybinds(String path) {
|
||||||
FILE* f=ps_fopen(path.c_str(),"wb");
|
FILE* f=ps_fopen(path.c_str(),"wb");
|
||||||
if (f==NULL) {
|
if (f==NULL) {
|
||||||
logW("error while opening keybind file for export: %s\n",strerror(errno));
|
logW("error while opening keybind file for export: %s",strerror(errno));
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
for (int i=0; i<GUI_ACTION_MAX; i++) {
|
for (int i=0; i<GUI_ACTION_MAX; i++) {
|
||||||
if (guiActions[i].defaultBind==-1) continue;
|
if (guiActions[i].defaultBind==-1) continue;
|
||||||
if (fprintf(f,"%s=%d\n",guiActions[i].name,actionKeys[i])<0) {
|
if (fprintf(f,"%s=%d\n",guiActions[i].name,actionKeys[i])<0) {
|
||||||
logW("error while exporting keybinds: %s\n",strerror(errno));
|
logW("error while exporting keybinds: %s",strerror(errno));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1783,7 +1792,7 @@ bool FurnaceGUI::exportKeybinds(String path) {
|
||||||
bool FurnaceGUI::importLayout(String path) {
|
bool FurnaceGUI::importLayout(String path) {
|
||||||
FILE* f=ps_fopen(path.c_str(),"rb");
|
FILE* f=ps_fopen(path.c_str(),"rb");
|
||||||
if (f==NULL) {
|
if (f==NULL) {
|
||||||
logW("error while opening keybind file for import: %s\n",strerror(errno));
|
logW("error while opening keybind file for import: %s",strerror(errno));
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (fseek(f,0,SEEK_END)<0) {
|
if (fseek(f,0,SEEK_END)<0) {
|
||||||
|
@ -1797,7 +1806,7 @@ bool FurnaceGUI::importLayout(String path) {
|
||||||
}
|
}
|
||||||
if (len<1) {
|
if (len<1) {
|
||||||
if (len==0) {
|
if (len==0) {
|
||||||
logE("that file is empty!\n");
|
logE("that file is empty!");
|
||||||
lastError="file is empty";
|
lastError="file is empty";
|
||||||
} else {
|
} else {
|
||||||
perror("tell error");
|
perror("tell error");
|
||||||
|
@ -1830,13 +1839,13 @@ bool FurnaceGUI::importLayout(String path) {
|
||||||
bool FurnaceGUI::exportLayout(String path) {
|
bool FurnaceGUI::exportLayout(String path) {
|
||||||
FILE* f=ps_fopen(path.c_str(),"wb");
|
FILE* f=ps_fopen(path.c_str(),"wb");
|
||||||
if (f==NULL) {
|
if (f==NULL) {
|
||||||
logW("error while opening layout file for export: %s\n",strerror(errno));
|
logW("error while opening layout file for export: %s",strerror(errno));
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
size_t dataSize=0;
|
size_t dataSize=0;
|
||||||
const char* data=ImGui::SaveIniSettingsToMemory(&dataSize);
|
const char* data=ImGui::SaveIniSettingsToMemory(&dataSize);
|
||||||
if (fwrite(data,1,dataSize,f)!=dataSize) {
|
if (fwrite(data,1,dataSize,f)!=dataSize) {
|
||||||
logW("error while exporting layout: %s\n",strerror(errno));
|
logW("error while exporting layout: %s",strerror(errno));
|
||||||
}
|
}
|
||||||
fclose(f);
|
fclose(f);
|
||||||
return true;
|
return true;
|
||||||
|
@ -2100,11 +2109,11 @@ void FurnaceGUI::applyUISettings() {
|
||||||
if (settings.patFont<0 || settings.patFont>6) settings.patFont=0;
|
if (settings.patFont<0 || settings.patFont>6) settings.patFont=0;
|
||||||
|
|
||||||
if (settings.mainFont==6 && settings.mainFontPath.empty()) {
|
if (settings.mainFont==6 && settings.mainFontPath.empty()) {
|
||||||
logW("UI font path is empty! reverting to default font\n");
|
logW("UI font path is empty! reverting to default font");
|
||||||
settings.mainFont=0;
|
settings.mainFont=0;
|
||||||
}
|
}
|
||||||
if (settings.patFont==6 && settings.patFontPath.empty()) {
|
if (settings.patFont==6 && settings.patFontPath.empty()) {
|
||||||
logW("pattern font path is empty! reverting to default font\n");
|
logW("pattern font path is empty! reverting to default font");
|
||||||
settings.patFont=0;
|
settings.patFont=0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2113,10 +2122,10 @@ void FurnaceGUI::applyUISettings() {
|
||||||
|
|
||||||
if (settings.mainFont==6) { // custom font
|
if (settings.mainFont==6) { // custom font
|
||||||
if ((mainFont=ImGui::GetIO().Fonts->AddFontFromFileTTF(settings.mainFontPath.c_str(),e->getConfInt("mainFontSize",18)*dpiScale,NULL,fontRange))==NULL) {
|
if ((mainFont=ImGui::GetIO().Fonts->AddFontFromFileTTF(settings.mainFontPath.c_str(),e->getConfInt("mainFontSize",18)*dpiScale,NULL,fontRange))==NULL) {
|
||||||
logW("could not load UI font! reverting to default font\n");
|
logW("could not load UI font! reverting to default font");
|
||||||
settings.mainFont=0;
|
settings.mainFont=0;
|
||||||
if ((mainFont=ImGui::GetIO().Fonts->AddFontFromMemoryCompressedTTF(builtinFont[settings.mainFont],builtinFontLen[settings.mainFont],e->getConfInt("mainFontSize",18)*dpiScale,NULL,fontRange))==NULL) {
|
if ((mainFont=ImGui::GetIO().Fonts->AddFontFromMemoryCompressedTTF(builtinFont[settings.mainFont],builtinFontLen[settings.mainFont],e->getConfInt("mainFontSize",18)*dpiScale,NULL,fontRange))==NULL) {
|
||||||
logE("could not load UI font! falling back to Proggy Clean.\n");
|
logE("could not load UI font! falling back to Proggy Clean.");
|
||||||
mainFont=ImGui::GetIO().Fonts->AddFontDefault();
|
mainFont=ImGui::GetIO().Fonts->AddFontDefault();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2124,10 +2133,10 @@ void FurnaceGUI::applyUISettings() {
|
||||||
if ((mainFont=ImGui::GetIO().Fonts->AddFontFromFileTTF(SYSTEM_FONT_PATH_1,e->getConfInt("mainFontSize",18)*dpiScale,NULL,fontRange))==NULL) {
|
if ((mainFont=ImGui::GetIO().Fonts->AddFontFromFileTTF(SYSTEM_FONT_PATH_1,e->getConfInt("mainFontSize",18)*dpiScale,NULL,fontRange))==NULL) {
|
||||||
if ((mainFont=ImGui::GetIO().Fonts->AddFontFromFileTTF(SYSTEM_FONT_PATH_2,e->getConfInt("mainFontSize",18)*dpiScale,NULL,fontRange))==NULL) {
|
if ((mainFont=ImGui::GetIO().Fonts->AddFontFromFileTTF(SYSTEM_FONT_PATH_2,e->getConfInt("mainFontSize",18)*dpiScale,NULL,fontRange))==NULL) {
|
||||||
if ((mainFont=ImGui::GetIO().Fonts->AddFontFromFileTTF(SYSTEM_FONT_PATH_3,e->getConfInt("mainFontSize",18)*dpiScale,NULL,fontRange))==NULL) {
|
if ((mainFont=ImGui::GetIO().Fonts->AddFontFromFileTTF(SYSTEM_FONT_PATH_3,e->getConfInt("mainFontSize",18)*dpiScale,NULL,fontRange))==NULL) {
|
||||||
logW("could not load UI font! reverting to default font\n");
|
logW("could not load UI font! reverting to default font");
|
||||||
settings.mainFont=0;
|
settings.mainFont=0;
|
||||||
if ((mainFont=ImGui::GetIO().Fonts->AddFontFromMemoryCompressedTTF(builtinFont[settings.mainFont],builtinFontLen[settings.mainFont],e->getConfInt("mainFontSize",18)*dpiScale,NULL,fontRange))==NULL) {
|
if ((mainFont=ImGui::GetIO().Fonts->AddFontFromMemoryCompressedTTF(builtinFont[settings.mainFont],builtinFontLen[settings.mainFont],e->getConfInt("mainFontSize",18)*dpiScale,NULL,fontRange))==NULL) {
|
||||||
logE("could not load UI font! falling back to Proggy Clean.\n");
|
logE("could not load UI font! falling back to Proggy Clean.");
|
||||||
mainFont=ImGui::GetIO().Fonts->AddFontDefault();
|
mainFont=ImGui::GetIO().Fonts->AddFontDefault();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2135,7 +2144,7 @@ void FurnaceGUI::applyUISettings() {
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if ((mainFont=ImGui::GetIO().Fonts->AddFontFromMemoryCompressedTTF(builtinFont[settings.mainFont],builtinFontLen[settings.mainFont],e->getConfInt("mainFontSize",18)*dpiScale,NULL,fontRange))==NULL) {
|
if ((mainFont=ImGui::GetIO().Fonts->AddFontFromMemoryCompressedTTF(builtinFont[settings.mainFont],builtinFontLen[settings.mainFont],e->getConfInt("mainFontSize",18)*dpiScale,NULL,fontRange))==NULL) {
|
||||||
logE("could not load UI font! falling back to Proggy Clean.\n");
|
logE("could not load UI font! falling back to Proggy Clean.");
|
||||||
mainFont=ImGui::GetIO().Fonts->AddFontDefault();
|
mainFont=ImGui::GetIO().Fonts->AddFontDefault();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2149,18 +2158,18 @@ void FurnaceGUI::applyUISettings() {
|
||||||
fc.GlyphMinAdvanceX=e->getConfInt("iconSize",16)*dpiScale;
|
fc.GlyphMinAdvanceX=e->getConfInt("iconSize",16)*dpiScale;
|
||||||
static const ImWchar fontRangeIcon[]={ICON_MIN_FA,ICON_MAX_FA,0};
|
static const ImWchar fontRangeIcon[]={ICON_MIN_FA,ICON_MAX_FA,0};
|
||||||
if ((iconFont=ImGui::GetIO().Fonts->AddFontFromMemoryCompressedTTF(iconFont_compressed_data,iconFont_compressed_size,e->getConfInt("iconSize",16)*dpiScale,&fc,fontRangeIcon))==NULL) {
|
if ((iconFont=ImGui::GetIO().Fonts->AddFontFromMemoryCompressedTTF(iconFont_compressed_data,iconFont_compressed_size,e->getConfInt("iconSize",16)*dpiScale,&fc,fontRangeIcon))==NULL) {
|
||||||
logE("could not load icon font!\n");
|
logE("could not load icon font!");
|
||||||
}
|
}
|
||||||
if (settings.mainFontSize==settings.patFontSize && settings.patFont<5 && builtinFontM[settings.patFont]==builtinFont[settings.mainFont]) {
|
if (settings.mainFontSize==settings.patFontSize && settings.patFont<5 && builtinFontM[settings.patFont]==builtinFont[settings.mainFont]) {
|
||||||
logD("using main font for pat font.\n");
|
logD("using main font for pat font.");
|
||||||
patFont=mainFont;
|
patFont=mainFont;
|
||||||
} else {
|
} else {
|
||||||
if (settings.patFont==6) { // custom font
|
if (settings.patFont==6) { // custom font
|
||||||
if ((patFont=ImGui::GetIO().Fonts->AddFontFromFileTTF(settings.patFontPath.c_str(),e->getConfInt("patFontSize",18)*dpiScale,NULL,upTo800))==NULL) {
|
if ((patFont=ImGui::GetIO().Fonts->AddFontFromFileTTF(settings.patFontPath.c_str(),e->getConfInt("patFontSize",18)*dpiScale,NULL,upTo800))==NULL) {
|
||||||
logW("could not load pattern font! reverting to default font\n");
|
logW("could not load pattern font! reverting to default font");
|
||||||
settings.patFont=0;
|
settings.patFont=0;
|
||||||
if ((patFont=ImGui::GetIO().Fonts->AddFontFromMemoryCompressedTTF(builtinFontM[settings.patFont],builtinFontMLen[settings.patFont],e->getConfInt("patFontSize",18)*dpiScale,NULL,upTo800))==NULL) {
|
if ((patFont=ImGui::GetIO().Fonts->AddFontFromMemoryCompressedTTF(builtinFontM[settings.patFont],builtinFontMLen[settings.patFont],e->getConfInt("patFontSize",18)*dpiScale,NULL,upTo800))==NULL) {
|
||||||
logE("could not load pattern font! falling back to Proggy Clean.\n");
|
logE("could not load pattern font! falling back to Proggy Clean.");
|
||||||
patFont=ImGui::GetIO().Fonts->AddFontDefault();
|
patFont=ImGui::GetIO().Fonts->AddFontDefault();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2168,10 +2177,10 @@ void FurnaceGUI::applyUISettings() {
|
||||||
if ((patFont=ImGui::GetIO().Fonts->AddFontFromFileTTF(SYSTEM_PAT_FONT_PATH_1,e->getConfInt("patFontSize",18)*dpiScale,NULL,upTo800))==NULL) {
|
if ((patFont=ImGui::GetIO().Fonts->AddFontFromFileTTF(SYSTEM_PAT_FONT_PATH_1,e->getConfInt("patFontSize",18)*dpiScale,NULL,upTo800))==NULL) {
|
||||||
if ((patFont=ImGui::GetIO().Fonts->AddFontFromFileTTF(SYSTEM_PAT_FONT_PATH_2,e->getConfInt("patFontSize",18)*dpiScale,NULL,upTo800))==NULL) {
|
if ((patFont=ImGui::GetIO().Fonts->AddFontFromFileTTF(SYSTEM_PAT_FONT_PATH_2,e->getConfInt("patFontSize",18)*dpiScale,NULL,upTo800))==NULL) {
|
||||||
if ((patFont=ImGui::GetIO().Fonts->AddFontFromFileTTF(SYSTEM_PAT_FONT_PATH_3,e->getConfInt("patFontSize",18)*dpiScale,NULL,upTo800))==NULL) {
|
if ((patFont=ImGui::GetIO().Fonts->AddFontFromFileTTF(SYSTEM_PAT_FONT_PATH_3,e->getConfInt("patFontSize",18)*dpiScale,NULL,upTo800))==NULL) {
|
||||||
logW("could not load pattern font! reverting to default font\n");
|
logW("could not load pattern font! reverting to default font");
|
||||||
settings.patFont=0;
|
settings.patFont=0;
|
||||||
if ((patFont=ImGui::GetIO().Fonts->AddFontFromMemoryCompressedTTF(builtinFontM[settings.patFont],builtinFontMLen[settings.patFont],e->getConfInt("patFontSize",18)*dpiScale,NULL,upTo800))==NULL) {
|
if ((patFont=ImGui::GetIO().Fonts->AddFontFromMemoryCompressedTTF(builtinFontM[settings.patFont],builtinFontMLen[settings.patFont],e->getConfInt("patFontSize",18)*dpiScale,NULL,upTo800))==NULL) {
|
||||||
logE("could not load pattern font! falling back to Proggy Clean.\n");
|
logE("could not load pattern font! falling back to Proggy Clean.");
|
||||||
patFont=ImGui::GetIO().Fonts->AddFontDefault();
|
patFont=ImGui::GetIO().Fonts->AddFontDefault();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2179,13 +2188,13 @@ void FurnaceGUI::applyUISettings() {
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if ((patFont=ImGui::GetIO().Fonts->AddFontFromMemoryCompressedTTF(builtinFontM[settings.patFont],builtinFontMLen[settings.patFont],e->getConfInt("patFontSize",18)*dpiScale,NULL,upTo800))==NULL) {
|
if ((patFont=ImGui::GetIO().Fonts->AddFontFromMemoryCompressedTTF(builtinFontM[settings.patFont],builtinFontMLen[settings.patFont],e->getConfInt("patFontSize",18)*dpiScale,NULL,upTo800))==NULL) {
|
||||||
logE("could not load pattern font!\n");
|
logE("could not load pattern font!");
|
||||||
patFont=ImGui::GetIO().Fonts->AddFontDefault();
|
patFont=ImGui::GetIO().Fonts->AddFontDefault();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if ((bigFont=ImGui::GetIO().Fonts->AddFontFromMemoryCompressedTTF(font_plexSans_compressed_data,font_plexSans_compressed_size,40*dpiScale))==NULL) {
|
if ((bigFont=ImGui::GetIO().Fonts->AddFontFromMemoryCompressedTTF(font_plexSans_compressed_data,font_plexSans_compressed_size,40*dpiScale))==NULL) {
|
||||||
logE("could not load big UI font!\n");
|
logE("could not load big UI font!");
|
||||||
}
|
}
|
||||||
|
|
||||||
mainFont->FallbackChar='?';
|
mainFont->FallbackChar='?';
|
||||||
|
|
54
src/log.cpp
54
src/log.cpp
|
@ -17,12 +17,16 @@
|
||||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
// TODO: improve these routines to allow logging to memory for eventual log window!
|
|
||||||
|
|
||||||
#include "ta-log.h"
|
#include "ta-log.h"
|
||||||
|
|
||||||
int logLevel=LOGLEVEL_INFO;
|
int logLevel=LOGLEVEL_INFO;
|
||||||
|
|
||||||
|
std::atomic<unsigned short> logPosition;
|
||||||
|
|
||||||
|
LogEntry logEntries[TA_LOG_SIZE];
|
||||||
|
|
||||||
|
static constexpr unsigned int TA_LOG_MASK=TA_LOG_SIZE-1;
|
||||||
|
|
||||||
int logV(const char* format, ...) {
|
int logV(const char* format, ...) {
|
||||||
va_list va;
|
va_list va;
|
||||||
int ret;
|
int ret;
|
||||||
|
@ -55,21 +59,6 @@ int logD(const char* format, ...) {
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
int logI(const char* format, ...) {
|
|
||||||
va_list va;
|
|
||||||
int ret;
|
|
||||||
if (logLevel<LOGLEVEL_INFO) return 0;
|
|
||||||
#ifdef _WIN32
|
|
||||||
printf("[info] ");
|
|
||||||
#else
|
|
||||||
printf("\x1b[1;32m[info]\x1b[m ");
|
|
||||||
#endif
|
|
||||||
va_start(va,format);
|
|
||||||
ret=vprintf(format,va);
|
|
||||||
va_end(va);
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
int logW(const char* format, ...) {
|
int logW(const char* format, ...) {
|
||||||
va_list va;
|
va_list va;
|
||||||
int ret;
|
int ret;
|
||||||
|
@ -100,3 +89,34 @@ int logE(const char* format, ...) {
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int writeLog(int level, const char* msg, fmt::printf_args& args) {
|
||||||
|
int pos=logPosition;
|
||||||
|
logPosition=(logPosition+1)&TA_LOG_MASK;
|
||||||
|
|
||||||
|
logEntries[pos].text=fmt::vsprintf(msg,args);
|
||||||
|
logEntries[pos].time=std::chrono::system_clock::now();
|
||||||
|
logEntries[pos].loglevel=level;
|
||||||
|
logEntries[pos].ready=true;
|
||||||
|
|
||||||
|
if (logLevel<level) return 0;
|
||||||
|
switch (level) {
|
||||||
|
case LOGLEVEL_ERROR:
|
||||||
|
return fmt::printf("\x1b[1;31m[ERROR]\x1b[m %s\n",logEntries[pos].text);
|
||||||
|
case LOGLEVEL_WARN:
|
||||||
|
return fmt::printf("\x1b[1;33m[warning]\x1b[m %s\n",logEntries[pos].text);
|
||||||
|
case LOGLEVEL_INFO:
|
||||||
|
return fmt::printf("\x1b[1;32m[info]\x1b[m %s\n",logEntries[pos].text);
|
||||||
|
case LOGLEVEL_DEBUG:
|
||||||
|
return fmt::printf("\x1b[1;34m[debug]\x1b[m %s\n",logEntries[pos].text);
|
||||||
|
case LOGLEVEL_TRACE:
|
||||||
|
return fmt::printf("\x1b[1;37m[trace]\x1b[m %s\n",logEntries[pos].text);
|
||||||
|
}
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
void initLog() {
|
||||||
|
logPosition=0;
|
||||||
|
for (int i=0; i<TA_LOG_SIZE; i++) {
|
||||||
|
logEntries[i].text.reserve(128);
|
||||||
|
}
|
||||||
|
}
|
39
src/main.cpp
39
src/main.cpp
|
@ -75,7 +75,7 @@ bool pHelp(String) {
|
||||||
|
|
||||||
bool pAudio(String val) {
|
bool pAudio(String val) {
|
||||||
if (outName!="") {
|
if (outName!="") {
|
||||||
logE("can't use -audio and -output at the same time.\n");
|
logE("can't use -audio and -output at the same time.");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (val=="jack") {
|
if (val=="jack") {
|
||||||
|
@ -83,7 +83,7 @@ bool pAudio(String val) {
|
||||||
} else if (val=="sdl") {
|
} else if (val=="sdl") {
|
||||||
e.setAudio(DIV_AUDIO_SDL);
|
e.setAudio(DIV_AUDIO_SDL);
|
||||||
} else {
|
} else {
|
||||||
logE("invalid value for audio engine! valid values are: jack, sdl.\n");
|
logE("invalid value for audio engine! valid values are: jack, sdl.");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
|
@ -97,7 +97,7 @@ bool pView(String val) {
|
||||||
} else if (val=="nothing") {
|
} else if (val=="nothing") {
|
||||||
e.setView(DIV_STATUS_NOTHING);
|
e.setView(DIV_STATUS_NOTHING);
|
||||||
} else {
|
} else {
|
||||||
logE("invalid value for view type! valid values are: pattern, commands, nothing.\n");
|
logE("invalid value for view type! valid values are: pattern, commands, nothing.");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
|
@ -120,7 +120,7 @@ bool pLogLevel(String val) {
|
||||||
} else if (val=="error") {
|
} else if (val=="error") {
|
||||||
logLevel=LOGLEVEL_ERROR;
|
logLevel=LOGLEVEL_ERROR;
|
||||||
} else {
|
} else {
|
||||||
logE("invalid value for loglevel! valid values are: trace, debug, info, warning, error.\n");
|
logE("invalid value for loglevel! valid values are: trace, debug, info, warning, error.");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
|
@ -181,7 +181,7 @@ bool pLoops(String val) {
|
||||||
loops=count+1;
|
loops=count+1;
|
||||||
}
|
}
|
||||||
} catch (std::exception& e) {
|
} catch (std::exception& e) {
|
||||||
logE("loop count shall be a number.\n");
|
logE("loop count shall be a number.");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
|
@ -195,7 +195,7 @@ bool pOutMode(String val) {
|
||||||
} else if (val=="perchan") {
|
} else if (val=="perchan") {
|
||||||
outMode=DIV_EXPORT_MODE_MANY_CHAN;
|
outMode=DIV_EXPORT_MODE_MANY_CHAN;
|
||||||
} else {
|
} else {
|
||||||
logE("invalid value for outmode! valid values are: one, persys and perchan.\n");
|
logE("invalid value for outmode! valid values are: one, persys and perchan.");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
|
@ -240,6 +240,7 @@ void initParams() {
|
||||||
}
|
}
|
||||||
|
|
||||||
int main(int argc, char** argv) {
|
int main(int argc, char** argv) {
|
||||||
|
initLog();
|
||||||
#if !(defined(__APPLE__) || defined(_WIN32))
|
#if !(defined(__APPLE__) || defined(_WIN32))
|
||||||
// workaround for Wayland HiDPI issue
|
// workaround for Wayland HiDPI issue
|
||||||
if (getenv("SDL_VIDEODRIVER")==NULL) {
|
if (getenv("SDL_VIDEODRIVER")==NULL) {
|
||||||
|
@ -270,7 +271,7 @@ int main(int argc, char** argv) {
|
||||||
val=argv[i+1];
|
val=argv[i+1];
|
||||||
i++;
|
i++;
|
||||||
} else {
|
} else {
|
||||||
logE("incomplete param %s.\n",arg.c_str());
|
logE("incomplete param %s.",arg.c_str());
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -307,12 +308,12 @@ int main(int argc, char** argv) {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (fileName.empty() && consoleMode) {
|
if (fileName.empty() && consoleMode) {
|
||||||
logI("usage: %s file\n",argv[0]);
|
logI("usage: %s file",argv[0]);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
logI("Furnace version " DIV_VERSION ".\n");
|
logI("Furnace version " DIV_VERSION ".");
|
||||||
if (!fileName.empty()) {
|
if (!fileName.empty()) {
|
||||||
logI("loading module...\n");
|
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) {
|
||||||
perror("error");
|
perror("error");
|
||||||
|
@ -353,12 +354,12 @@ int main(int argc, char** argv) {
|
||||||
}
|
}
|
||||||
fclose(f);
|
fclose(f);
|
||||||
if (!e.load(file,(size_t)len)) {
|
if (!e.load(file,(size_t)len)) {
|
||||||
logE("could not open file!\n");
|
logE("could not open file!");
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!e.init()) {
|
if (!e.init()) {
|
||||||
logE("could not initialize engine!\n");
|
logE("could not initialize engine!");
|
||||||
if (consoleMode) {
|
if (consoleMode) {
|
||||||
return 1;
|
return 1;
|
||||||
} else {
|
} else {
|
||||||
|
@ -374,12 +375,12 @@ int main(int argc, char** argv) {
|
||||||
fwrite(w->getFinalBuf(),1,w->size(),f);
|
fwrite(w->getFinalBuf(),1,w->size(),f);
|
||||||
fclose(f);
|
fclose(f);
|
||||||
} else {
|
} else {
|
||||||
logE("could not open file! %s\n",strerror(errno));
|
logE("could not open file! %s",strerror(errno));
|
||||||
}
|
}
|
||||||
w->finish();
|
w->finish();
|
||||||
delete w;
|
delete w;
|
||||||
} else {
|
} else {
|
||||||
logE("could not write VGM!\n");
|
logE("could not write VGM!");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (outName!="") {
|
if (outName!="") {
|
||||||
|
@ -391,7 +392,7 @@ int main(int argc, char** argv) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (consoleMode) {
|
if (consoleMode) {
|
||||||
logI("playing...\n");
|
logI("playing...");
|
||||||
e.play();
|
e.play();
|
||||||
#ifdef HAVE_GUI
|
#ifdef HAVE_GUI
|
||||||
SDL_Event ev;
|
SDL_Event ev;
|
||||||
|
@ -417,7 +418,7 @@ int main(int argc, char** argv) {
|
||||||
if (!g.init()) return 1;
|
if (!g.init()) return 1;
|
||||||
|
|
||||||
if (displayEngineFailError) {
|
if (displayEngineFailError) {
|
||||||
logE("displaying engine fail error.\n");
|
logE("displaying engine fail error.");
|
||||||
g.showError("error while initializing audio!");
|
g.showError("error while initializing audio!");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -426,13 +427,13 @@ int main(int argc, char** argv) {
|
||||||
}
|
}
|
||||||
|
|
||||||
g.loop();
|
g.loop();
|
||||||
logI("closing GUI.\n");
|
logI("closing GUI.");
|
||||||
g.finish();
|
g.finish();
|
||||||
#else
|
#else
|
||||||
logE("GUI requested but GUI not compiled!\n");
|
logE("GUI requested but GUI not compiled!");
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
logI("stopping engine.\n");
|
logI("stopping engine.");
|
||||||
e.quit();
|
e.quit();
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
54
src/ta-log.h
54
src/ta-log.h
|
@ -19,8 +19,12 @@
|
||||||
|
|
||||||
#ifndef _TA_LOG_H
|
#ifndef _TA_LOG_H
|
||||||
#define _TA_LOG_H
|
#define _TA_LOG_H
|
||||||
|
#include <chrono>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdarg.h>
|
#include <stdarg.h>
|
||||||
|
#include <atomic>
|
||||||
|
#include <string>
|
||||||
|
#include <fmt/printf.h>
|
||||||
|
|
||||||
#define LOGLEVEL_ERROR 0
|
#define LOGLEVEL_ERROR 0
|
||||||
#define LOGLEVEL_WARN 1
|
#define LOGLEVEL_WARN 1
|
||||||
|
@ -28,11 +32,51 @@
|
||||||
#define LOGLEVEL_DEBUG 3
|
#define LOGLEVEL_DEBUG 3
|
||||||
#define LOGLEVEL_TRACE 4
|
#define LOGLEVEL_TRACE 4
|
||||||
|
|
||||||
|
// this has to be a power of 2
|
||||||
|
#define TA_LOG_SIZE 2048
|
||||||
|
|
||||||
extern int logLevel;
|
extern int logLevel;
|
||||||
|
|
||||||
int logV(const char* format, ...);
|
extern std::atomic<unsigned short> logPosition;
|
||||||
int logD(const char* format, ...);
|
|
||||||
int logI(const char* format, ...);
|
struct LogEntry {
|
||||||
int logW(const char* format, ...);
|
int loglevel;
|
||||||
int logE(const char* format, ...);
|
std::chrono::system_clock::time_point time;
|
||||||
|
std::string text;
|
||||||
|
bool ready;
|
||||||
|
LogEntry():
|
||||||
|
loglevel(0),
|
||||||
|
ready(false) {}
|
||||||
|
};
|
||||||
|
|
||||||
|
int writeLog(int level, const char* msg, fmt::printf_args& args);
|
||||||
|
|
||||||
|
extern LogEntry logEntries[TA_LOG_SIZE];
|
||||||
|
|
||||||
|
template<typename... T> int logV(const char* msg, const T&... args) {
|
||||||
|
fmt::printf_args a=fmt::make_printf_args(args...);
|
||||||
|
return writeLog(LOGLEVEL_TRACE,msg,a);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename... T> int logD(const char* msg, const T&... args) {
|
||||||
|
fmt::printf_args a=fmt::make_printf_args(args...);
|
||||||
|
return writeLog(LOGLEVEL_DEBUG,msg,a);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename... T> int logI(const char* msg, const T&... args) {
|
||||||
|
fmt::printf_args a=fmt::make_printf_args(args...);
|
||||||
|
return writeLog(LOGLEVEL_INFO,msg,a);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename... T> int logW(const char* msg, const T&... args) {
|
||||||
|
fmt::printf_args a=fmt::make_printf_args(args...);
|
||||||
|
return writeLog(LOGLEVEL_WARN,msg,a);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename... T> int logE(const char* msg, const T&... args) {
|
||||||
|
fmt::printf_args a=fmt::make_printf_args(args...);
|
||||||
|
return writeLog(LOGLEVEL_ERROR,msg,a);
|
||||||
|
}
|
||||||
|
|
||||||
|
void initLog();
|
||||||
#endif
|
#endif
|
||||||
|
|
Loading…
Reference in New Issue