diff --git a/src/engine/engine.cpp b/src/engine/engine.cpp index 425599bce..a6b7ecfd2 100644 --- a/src/engine/engine.cpp +++ b/src/engine/engine.cpp @@ -3,6 +3,8 @@ #include "safeReader.h" #include "../ta-log.h" #include "../audio/sdl.h" +#include +#include #ifndef _WIN32 #include #include @@ -1053,6 +1055,146 @@ SafeWriter* DivEngine::save() { return w; } +#ifdef _WIN32 +#define CONFIG_FILE "\\furnace.cfg" +#else +#define CONFIG_FILE "/furnace.cfg" +#endif + +bool DivEngine::saveConf() { + configFile=configPath+String(CONFIG_FILE); + FILE* f=fopen(configFile.c_str(),"wb"); + if (f==NULL) { + logW("could not write config file! %s\n",strerror(errno)); + return false; + } + for (auto& i: conf) { + String toWrite=fmt::sprintf("%s=%s\n",i.first,i.second); + if (fwrite(toWrite.c_str(),1,toWrite.size(),f)!=toWrite.size()) { + logW("could not write config file! %s\n",strerror(errno)); + fclose(f); + return false; + } + } + fclose(f); + return true; +} + +bool DivEngine::loadConf() { + char line[4096]; + configFile=configPath+String(CONFIG_FILE); + FILE* f=fopen(configFile.c_str(),"rb"); + if (f==NULL) { + logI("creating default config.\n"); + return saveConf(); + } + logI("loading config.\n"); + while (!feof(f)) { + String key=""; + String value=""; + bool keyOrValue=false; + if (fgets(line,4095,f)==NULL) { + break; + } + for (char* i=line; *i; i++) { + if (*i=='\n') continue; + if (keyOrValue) { + value+=*i; + } else { + if (*i=='=') { + keyOrValue=true; + } else { + key+=*i; + } + } + } + if (keyOrValue) { + conf[key]=value; + } + } + fclose(f); + return true; +} + +bool DivEngine::getConfBool(String key, bool fallback) { + try { + String val=conf.at(key); + if (val=="true") { + return true; + } else if (val=="false") { + return false; + } + } catch (std::out_of_range& e) { + } + return fallback; +} + +int DivEngine::getConfInt(String key, int fallback) { + try { + String val=conf.at(key); + int ret=std::stoi(val); + return ret; + } catch (std::out_of_range& e) { + } catch (std::invalid_argument& e) { + } + return fallback; +} + +float DivEngine::getConfFloat(String key, float fallback) { + try { + String val=conf.at(key); + float ret=std::stof(val); + return ret; + } catch (std::out_of_range& e) { + } catch (std::invalid_argument& e) { + } + return fallback; +} + +double DivEngine::getConfDouble(String key, double fallback) { + try { + String val=conf.at(key); + double ret=std::stod(val); + return ret; + } catch (std::out_of_range& e) { + } catch (std::invalid_argument& e) { + } + return fallback; +} + +String DivEngine::getConfString(String key, String fallback) { + try { + String val=conf.at(key); + return val; + } catch (std::out_of_range& e) { + } + return fallback; +} + +void DivEngine::setConf(String key, bool value) { + if (value) { + conf[key]="true"; + } else { + conf[key]="false"; + } +} + +void DivEngine::setConf(String key, int value) { + conf[key]=fmt::sprintf("%d",value); +} + +void DivEngine::setConf(String key, float value) { + conf[key]=fmt::sprintf("%f",value); +} + +void DivEngine::setConf(String key, double value) { + conf[key]=fmt::sprintf("%f",value); +} + +void DivEngine::setConf(String key, String value) { + conf[key]=value; +} + // ADPCM code attribution: https://wiki.neogeodev.org/index.php?title=ADPCM_codecs static short adSteps[49]={ @@ -1636,6 +1778,8 @@ bool DivEngine::init(String outName) { #endif logD("config path: %s\n",configPath.c_str()); + loadConf(); + // init the rest of engine SNDFILE* outFile=NULL; SF_INFO outInfo; @@ -1758,5 +1902,7 @@ bool DivEngine::init(String outName) { bool DivEngine::quit() { output->quit(); quitDispatch(); + logI("saving config.\n"); + saveConf(); return true; } diff --git a/src/engine/engine.h b/src/engine/engine.h index 4ef3f83a4..558313feb 100644 --- a/src/engine/engine.h +++ b/src/engine/engine.h @@ -6,6 +6,7 @@ #include "../audio/taAudio.h" #include "blip_buf.h" #include +#include #define DIV_VERSION "0.1" #define DIV_ENGINE_VERSION 11 @@ -80,9 +81,11 @@ class DivEngine { DivStatusView view; DivChannelState chan[17]; DivAudioEngines audioEngine; + std::map conf; bool isMuted[17]; std::mutex isBusy; String configPath; + String configFile; short vibTable[64]; @@ -116,6 +119,26 @@ class DivEngine { // save as .dmf. SafeWriter* save(); + // save config + bool saveConf(); + + // load config + bool loadConf(); + + // get a config value + bool getConfBool(String key, bool fallback); + int getConfInt(String key, int fallback); + float getConfFloat(String key, float fallback); + double getConfDouble(String key, double fallback); + String getConfString(String key, String fallback); + + // set a config value + void setConf(String key, bool value); + void setConf(String key, int value); + void setConf(String key, float value); + void setConf(String key, double value); + void setConf(String key, String value); + // play void play();