From d99a94cbdc478c4fc7ed8a32ef959195fe5305a4 Mon Sep 17 00:00:00 2001 From: Florent CURE Date: Sun, 26 May 2019 19:14:12 +0100 Subject: [PATCH 01/11] Add search of config and data directory This work is handled by the ApplicationSettings class. On linux, it searches the config.json file first in working directory (directory level), then in ~/.config/bonzomatic (user level), then in /etc/bonzomatic (system level). It also infers the data directory (where are stored textures and other files) based on that location. In directory level and user level it is the same directory, in system level it's /usr/share/bonzomatic. --- src/Config.cpp | 94 ++++++++++++++++++++++++++++++++++ src/Config.h | 45 +++++++++++++++++ src/main.cpp | 133 ++++++++++++++++++++++++------------------------- 3 files changed, 203 insertions(+), 69 deletions(-) create mode 100644 src/Config.cpp create mode 100644 src/Config.h diff --git a/src/Config.cpp b/src/Config.cpp new file mode 100644 index 00000000..860e36f9 --- /dev/null +++ b/src/Config.cpp @@ -0,0 +1,94 @@ +#include "Config.h" + +#include +#include +#include + +#include + + +namespace Config +{ + ApplicationSettings::ApplicationSettings( const std::string& cfg_filename ) + : _location( Location::NONE ), _config_filename( cfg_filename ) + { + + } + + void ApplicationSettings::load() + { + find_location(); + + if( _location != Location::NONE ) + { + read_config(); + } + + + } + + void ApplicationSettings::read_config() + { + std::string config_path( _config_directory + "/" + _config_filename ); + std::ifstream fconf( config_path ); + fconf.seekg( 0, std::ios::end ); + size_t file_size_in_byte = fconf.tellg(); + std::vector< char > data; + data.resize( file_size_in_byte ); + fconf.seekg( 0, std::ios::beg ); + fconf.read( &data[0], file_size_in_byte ); + _options.parse( &data[ 0 ] ); + } + + void ApplicationSettings::find_location() + { + const std::string sysPath( "/etc/bonzomatic" ); + const std::string userPath( getenv( "HOME" ) ); + const std::string localConfigPath = "/.config/bonzomatic"; + std::string localPath = userPath + localConfigPath; + + char cwd[ 256 ]; + getcwd( cwd, 255 ); + std::string curDir( cwd ); + + // 1. search in current directory + std::ifstream cfgFile( _config_filename ); + if( cfgFile.is_open() ) + { + _config_directory = curDir; + _data_directory = curDir; + cfgFile.close(); + _location = Location::DIRECTORY; + std::cout << "Config file found in current directory (" << _config_directory << ")...\n"; + return; + } + + // 2. search in user config path + std::ifstream userCfgFile( localPath + std::string( "/" ) + _config_filename ); + if( userCfgFile.is_open() ) + { + _config_directory = userPath; + _data_directory = userPath; + userCfgFile.close(); + _location = Location::USER; + std::cout << "Config file found in user directory (" << _config_directory << ")...\n"; + return; + } + + // 3. search in system config path + std::ifstream sysCfgFile( sysPath + std::string( "/" ) + _config_filename ); + if( sysCfgFile.is_open() ) + { + _config_directory = sysPath; + _data_directory = "/usr/share/bonzomatic"; + sysCfgFile.close(); + _location = Location::SYSTEM; + std::cout << "Config file found in system config path (" << _config_directory << ")...\n"; + return; + } + + _config_directory = curDir; + _location = Location::NONE; + std::cout << "No config file found, using default ApplicationSettings...\n"; + } +} \ No newline at end of file diff --git a/src/Config.h b/src/Config.h new file mode 100644 index 00000000..8f567bc3 --- /dev/null +++ b/src/Config.h @@ -0,0 +1,45 @@ +#pragma once + +#include "jsonxx.h" + +#include + +namespace Config +{ + + class ApplicationSettings + { + public: + enum Location + { + SYSTEM, + USER, + DIRECTORY, + NONE + }; + + ApplicationSettings( const std::string& cfg_filename ); + + void load(); + + const jsonxx::Object get_options() const { return _options; } + const std::string get_config_directory() const { return _config_directory; } + const std::string get_data_directory() const { return _data_directory; } + + private: + void find_location(); + void read_config(); + + Location _location; + std::string _config_filename; + jsonxx::Object _options; + + std::string _config_directory; + std::string _data_directory; + }; + + + + + +} \ No newline at end of file diff --git a/src/main.cpp b/src/main.cpp index 335adde7..80cf16a1 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -19,6 +19,11 @@ #include "jsonxx.h" #include "Capture.h" +// #FLO +#include "Config.h" + +#include + void ReplaceTokens( std::string &sDefShader, const char * sTokenBegin, const char * sTokenName, const char * sTokenEnd, std::vector &tokens ) { if (sDefShader.find(sTokenBegin) != std::string::npos @@ -48,38 +53,24 @@ void ReplaceTokens( std::string &sDefShader, const char * sTokenBegin, const cha } } + + + + int main(int argc, const char *argv[]) { Misc::PlatformStartup(); - const char * configFile = "config.json"; + std::string cfg_file_name( "config.json" ); + if ( argc > 1 ) { - configFile = argv[ 1 ]; - printf( "Loading config file '%s'...\n", configFile ); - } - else - { - char configPath[ 256 ] = { 0 }; - if ( getcwd( configPath, 255 ) ) - { - printf( "Looking for config.json in '%s'...\n", configPath ); - } + cfg_file_name = argv[ 1 ]; } + std::cout << "Loading config file '" << cfg_file_name << "'...\n"; - jsonxx::Object options; - FILE * fConf = fopen( configFile, "rb" ); - if (fConf) - { - printf("Config file found, parsing...\n"); - - char szConfig[65535]; - memset( szConfig, 0, 65535 ); - fread( szConfig, 1, 65535, fConf ); - fclose(fConf); - - options.parse( szConfig ); - } + Config::ApplicationSettings app_settings( cfg_file_name ); + app_settings.load(); RENDERER_SETTINGS settings; settings.bVsync = false; @@ -91,14 +82,15 @@ int main(int argc, const char *argv[]) settings.nWidth = 1920; settings.nHeight = 1080; settings.windowMode = RENDERER_WINDOWMODE_FULLSCREEN; - if (options.has("window")) + jsonxx::Object opts = app_settings.get_options(); + if (opts.has("window")) { - if (options.get("window").has("width")) - settings.nWidth = options.get("window").get("width"); - if (options.get("window").has("height")) - settings.nHeight = options.get("window").get("height"); - if (options.get("window").has("fullscreen")) - settings.windowMode = options.get("window").get("fullscreen") ? RENDERER_WINDOWMODE_FULLSCREEN : RENDERER_WINDOWMODE_WINDOWED; + if (opts.get("window").has("width")) + settings.nWidth = opts.get("window").get("width"); + if (opts.get("window").has("height")) + settings.nHeight = opts.get("window").get("height"); + if (opts.get("window").has("fullscreen")) + settings.windowMode = opts.get("window").get("fullscreen") ? RENDERER_WINDOWMODE_FULLSCREEN : RENDERER_WINDOWMODE_WINDOWED; } if (!Renderer::OpenSetupDialog( &settings )) return -1; @@ -150,40 +142,43 @@ int main(int argc, const char *argv[]) std::string sPostExitCmd; - if (!options.empty()) + if (!opts.empty()) { - if (options.has("rendering")) + if (opts.has("rendering")) { - if (options.get("rendering").has("fftSmoothFactor")) - fFFTSmoothingFactor = options.get("rendering").get("fftSmoothFactor"); - if (options.get("rendering").has("fftAmplification")) - FFT::fAmplification = options.get("rendering").get("fftAmplification"); + if (opts.get("rendering").has("fftSmoothFactor")) + fFFTSmoothingFactor = opts.get("rendering").get("fftSmoothFactor"); + if (opts.get("rendering").has("fftAmplification")) + FFT::fAmplification = opts.get("rendering").get("fftAmplification"); } - if (options.has("textures")) + if (opts.has("textures")) { printf("Loading textures...\n"); - std::map tex = options.get("textures").kv_map(); + std::map tex = opts.get("textures").kv_map(); for (std::map::iterator it = tex.begin(); it != tex.end(); it++) { - const char * fn = it->second->string_value_->c_str(); - printf("* %s...\n",fn); - Renderer::Texture * tex = Renderer::CreateRGBA8TextureFromFile( fn ); + //const char * fn = it->second->string_value_->c_str(); + std::string file_name = app_settings.get_data_directory() + std::string( "/" ) + std::string( it->second->string_value_->c_str() ); + //printf("* %s...\n",fn); + std::cout << file_name << "...\n"; + //Renderer::Texture * tex = Renderer::CreateRGBA8TextureFromFile( fn ); + Renderer::Texture * tex = Renderer::CreateRGBA8TextureFromFile( file_name.c_str() ); if (!tex) { - printf("Renderer::CreateRGBA8TextureFromFile(%s) failed\n",fn); + printf("Renderer::CreateRGBA8TextureFromFile(%s) failed\n",file_name.c_str()); return -1; } textures[it->first] = tex; } } - if (options.has("font")) + if (opts.has("font")) { - if (options.get("font").has("size")) - editorOptions.nFontSize = options.get("font").get("size"); - if (options.get("font").has("file")) + if (opts.get("font").has("size")) + editorOptions.nFontSize = opts.get("font").get("size"); + if (opts.get("font").has("file")) { - std::string fontpath = options.get("font").get("file"); + std::string fontpath = opts.get("font").get("file"); if (!Misc::FileExists(fontpath.c_str())) { printf("Font path (%s) is invalid!\n", fontpath.c_str()); @@ -192,23 +187,23 @@ int main(int argc, const char *argv[]) editorOptions.sFontPath = fontpath; } } - if (options.has("gui")) + if (opts.has("gui")) { - if (options.get("gui").has("outputHeight")) - nDebugOutputHeight = options.get("gui").get("outputHeight"); - if (options.get("gui").has("texturePreviewWidth")) - nTexPreviewWidth = options.get("gui").get("texturePreviewWidth"); - if (options.get("gui").has("opacity")) - editorOptions.nOpacity = options.get("gui").get("opacity"); - if (options.get("gui").has("spacesForTabs")) - editorOptions.bUseSpacesForTabs = options.get("gui").get("spacesForTabs"); - if (options.get("gui").has("tabSize")) - editorOptions.nTabSize = options.get("gui").get("tabSize"); - if (options.get("gui").has("visibleWhitespace")) - editorOptions.bVisibleWhitespace = options.get("gui").get("visibleWhitespace"); - if (options.get("gui").has("autoIndent")) + if (opts.get("gui").has("outputHeight")) + nDebugOutputHeight = opts.get("gui").get("outputHeight"); + if (opts.get("gui").has("texturePreviewWidth")) + nTexPreviewWidth = opts.get("gui").get("texturePreviewWidth"); + if (opts.get("gui").has("opacity")) + editorOptions.nOpacity = opts.get("gui").get("opacity"); + if (opts.get("gui").has("spacesForTabs")) + editorOptions.bUseSpacesForTabs = opts.get("gui").get("spacesForTabs"); + if (opts.get("gui").has("tabSize")) + editorOptions.nTabSize = opts.get("gui").get("tabSize"); + if (opts.get("gui").has("visibleWhitespace")) + editorOptions.bVisibleWhitespace = opts.get("gui").get("visibleWhitespace"); + if (opts.get("gui").has("autoIndent")) { - std::string autoIndent = options.get("gui").get("autoIndent"); + std::string autoIndent = opts.get("gui").get("autoIndent"); if (autoIndent == "smart") { editorOptions.eAutoIndent = aitSmart; } else if (autoIndent == "preserve") { @@ -218,19 +213,19 @@ int main(int argc, const char *argv[]) } } } - if (options.has("midi")) + if (opts.has("midi")) { - std::map tex = options.get("midi").kv_map(); + std::map tex = opts.get("midi").kv_map(); for (std::map::iterator it = tex.begin(); it != tex.end(); it++) { midiRoutes[it->second->number_value_] = it->first; } } - if (options.has("postExitCmd")) + if (opts.has("postExitCmd")) { - sPostExitCmd = options.get("postExitCmd"); + sPostExitCmd = opts.get("postExitCmd"); } - Capture::LoadSettings( options ); + Capture::LoadSettings( opts ); } if (!editorOptions.sFontPath.size()) { @@ -389,7 +384,7 @@ int main(int argc, const char *argv[]) mDebugOutput.SetText( szError ); } } - else if (Renderer::keyEventBuffer[i].scanCode == 292 || (Renderer::keyEventBuffer[i].ctrl && Renderer::keyEventBuffer[i].scanCode == 'f')) // F11 or Ctrl/Cmd-f + else if (Renderer::keyEventBuffer[i].scanCode == 292 || (Renderer::keyEventBuffer[i].ctrl && Renderer::keyEventBuffer[i].scanCode == 'f')) // F11 or Ctrl/Cmd-f { bShowGui = !bShowGui; } From 36825d010f5a498f59db8a469768ea583679a72b Mon Sep 17 00:00:00 2001 From: Florent CURE Date: Mon, 27 May 2019 22:38:56 +0100 Subject: [PATCH 02/11] Add common platform Config implementation The platform_common (Windows and OSX) implementation always searches for config.json in current working directory. --- CMakeLists.txt | 10 +++- config.json | 41 +++++++++++++++ src/Config.cpp | 94 ---------------------------------- src/Config.h | 42 ++++++++++----- src/Utils.h | 11 ++++ src/platform_common/Config.cpp | 35 +++++++++++++ src/platform_common/Utils.cpp | 20 ++++++++ src/platform_linux/Config.cpp | 65 +++++++++++++++++++++++ 8 files changed, 209 insertions(+), 109 deletions(-) create mode 100644 config.json delete mode 100644 src/Config.cpp create mode 100644 src/Utils.h create mode 100644 src/platform_common/Config.cpp create mode 100644 src/platform_common/Utils.cpp create mode 100644 src/platform_linux/Config.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index bcf8a731..c0a0fad6 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -34,7 +34,7 @@ endif () if (WIN32) set(BONZOMATIC_WINDOWS_FLAVOR "GLFW" CACHE STRING "Windows renderer flavor selected at CMake configure time (DX11, DX9 or GLFW)") - set_property(CACHE BONZOMATIC_WINDOWS_FLAVOR PROPERTY STRINGS DX11 DX9 GLFW) + set_property(CACHE BONZOMATIC_WINDOWS_FLAVOR PROPERTY STRINGS DX11 DX9 GLFW) endif () if (NOT (UNIX AND (NOT APPLE))) #if not linux @@ -151,7 +151,7 @@ set(BZC_PROJECT_LIBS ${BZC_PROJECT_LIBS} bzc_jsonxx) ############################################################################## # NDI if (WIN32 AND BONZOMATIC_NDI) - if(DEFINED ENV{NDI_SDK_DIR}) + if(DEFINED ENV{NDI_SDK_DIR}) set(NDI_SDK_DIR "$ENV{NDI_SDK_DIR}") else() message(FATAL_ERROR "Could not find NDI SDK. The NDI_SDK_DIR environment variable must be set to the SDK path.") @@ -330,6 +330,7 @@ if (APPLE) set(BZC_PLATFORM_SRCS ${CMAKE_SOURCE_DIR}/src/platform_glfw/Renderer.cpp ${CMAKE_SOURCE_DIR}/src/platform_common/FFT.cpp + ${CMAKE_SOURCE_DIR}/src/platform_common/Utils.cpp ${CMAKE_SOURCE_DIR}/src/platform_x11/MIDI.cpp ${CMAKE_SOURCE_DIR}/src/platform_osx/Misc.mm ${CMAKE_SOURCE_DIR}/src/platform_x11/Timer.cpp @@ -346,11 +347,13 @@ elseif (UNIX) set(BZC_PLATFORM_SRCS ${CMAKE_SOURCE_DIR}/src/platform_glfw/Renderer.cpp ${CMAKE_SOURCE_DIR}/src/platform_common/FFT.cpp + ${CMAKE_SOURCE_DIR}/src/platform_common/Utils.cpp ${CMAKE_SOURCE_DIR}/src/platform_x11/MIDI.cpp ${CMAKE_SOURCE_DIR}/src/platform_x11/Misc.cpp ${CMAKE_SOURCE_DIR}/src/platform_x11/SetupDialog.cpp ${CMAKE_SOURCE_DIR}/src/platform_x11/Timer.cpp ${CMAKE_SOURCE_DIR}/src/platform_x11/Clipboard.cpp + ${CMAKE_SOURCE_DIR}/src/platform_linux/Config.cpp ) source_group("Bonzomatic\\Platform" FILES ${BZC_PLATFORM_SRCS}) elseif (WIN32) @@ -358,6 +361,7 @@ elseif (WIN32) set(BZC_PLATFORM_SRCS ${CMAKE_SOURCE_DIR}/src/platform_w32_dx11/Renderer.cpp ${CMAKE_SOURCE_DIR}/src/platform_common/FFT.cpp + ${CMAKE_SOURCE_DIR}/src/platform_common/Utils.cpp ${CMAKE_SOURCE_DIR}/src/platform_w32_common/MIDI.cpp ${CMAKE_SOURCE_DIR}/src/platform_w32_common/Misc.cpp ${CMAKE_SOURCE_DIR}/src/platform_w32_common/SetupDialog.cpp @@ -369,6 +373,7 @@ elseif (WIN32) set(BZC_PLATFORM_SRCS ${CMAKE_SOURCE_DIR}/src/platform_w32_dx9/Renderer.cpp ${CMAKE_SOURCE_DIR}/src/platform_common/FFT.cpp + ${CMAKE_SOURCE_DIR}/src/platform_common/Utils.cpp ${CMAKE_SOURCE_DIR}/src/platform_w32_common/MIDI.cpp ${CMAKE_SOURCE_DIR}/src/platform_w32_common/Misc.cpp ${CMAKE_SOURCE_DIR}/src/platform_w32_common/SetupDialog.cpp @@ -380,6 +385,7 @@ elseif (WIN32) set(BZC_PLATFORM_SRCS ${CMAKE_SOURCE_DIR}/src/platform_glfw/Renderer.cpp ${CMAKE_SOURCE_DIR}/src/platform_common/FFT.cpp + ${CMAKE_SOURCE_DIR}/src/platform_common/Utils.cpp ${CMAKE_SOURCE_DIR}/src/platform_w32_common/MIDI.cpp ${CMAKE_SOURCE_DIR}/src/platform_w32_common/Misc.cpp ${CMAKE_SOURCE_DIR}/src/platform_w32_common/SetupDialog.cpp diff --git a/config.json b/config.json new file mode 100644 index 00000000..02a3ec1b --- /dev/null +++ b/config.json @@ -0,0 +1,41 @@ +{ + "window":{ // default window size / state, if there's a setup dialog, it will override it + "width":1920, + "height":1080, + "fullscreen":true, + }, +// "font":{ // all paths in the file are also relative to the binary, but again, can be absolute paths if that's more convenient +// "file":"Input-Regular_(InputMono-Medium).ttf", +// "size":16, +// }, + "rendering":{ + "fftSmoothFactor": 0.9, // 0.0 means there's no smoothing at all, 1.0 means the FFT is completely smoothed flat + "fftAmplification": 1.0, // 1.0 means no change, larger values will result in brighter/stronger bands, smaller values in darker/weaker ones + }, + "textures":{ // the keys below will become the shader variable names + "texChecker":"textures/checker.png", + "texNoise":"textures/noise.png", + "texTex1":"textures/tex1.jpg", + }, + "gui":{ + "outputHeight": 200, + "opacity": 192, // 255 means the editor occludes the effect completely, 0 means the editor is fully transparent + "texturePreviewWidth": 128, + "spacesForTabs": false, + "tabSize": 8, + "visibleWhitespace": false, + "autoIndent": "smart", // can be "none", "preserve" or "smart" + }, + "midi":{ // the keys below will become the shader variable names, the values are the CC numbers + "fMidiKnob": 16, // e.g. this would be CC#16, i.e. by default the leftmost knob on a nanoKONTROL 2 + }, + // this section is if you want to enable NDI streaming; otherwise just ignore it + "ndi":{ + "enabled": true, + "connectionString": "", // metadata sent to the receiver; completely optional + "identifier": "hello!", // additional string to the device name; helps source discovery/identification in the receiver if there are multiple sources on the network + "frameRate": 60.0, // frames per second + "progressive": true, // progressive or interleaved? + }, + "postExitCmd":"copy_to_dropbox.bat" // this command gets ran when you quit Bonzomatic, and the shader filename gets passed to it as first parameter. Use this to take regular backups. +} \ No newline at end of file diff --git a/src/Config.cpp b/src/Config.cpp deleted file mode 100644 index 860e36f9..00000000 --- a/src/Config.cpp +++ /dev/null @@ -1,94 +0,0 @@ -#include "Config.h" - -#include -#include -#include - -#include - - -namespace Config -{ - ApplicationSettings::ApplicationSettings( const std::string& cfg_filename ) - : _location( Location::NONE ), _config_filename( cfg_filename ) - { - - } - - void ApplicationSettings::load() - { - find_location(); - - if( _location != Location::NONE ) - { - read_config(); - } - - - } - - void ApplicationSettings::read_config() - { - std::string config_path( _config_directory + "/" + _config_filename ); - std::ifstream fconf( config_path ); - fconf.seekg( 0, std::ios::end ); - size_t file_size_in_byte = fconf.tellg(); - std::vector< char > data; - data.resize( file_size_in_byte ); - fconf.seekg( 0, std::ios::beg ); - fconf.read( &data[0], file_size_in_byte ); - _options.parse( &data[ 0 ] ); - } - - void ApplicationSettings::find_location() - { - const std::string sysPath( "/etc/bonzomatic" ); - const std::string userPath( getenv( "HOME" ) ); - const std::string localConfigPath = "/.config/bonzomatic"; - std::string localPath = userPath + localConfigPath; - - char cwd[ 256 ]; - getcwd( cwd, 255 ); - std::string curDir( cwd ); - - // 1. search in current directory - std::ifstream cfgFile( _config_filename ); - if( cfgFile.is_open() ) - { - _config_directory = curDir; - _data_directory = curDir; - cfgFile.close(); - _location = Location::DIRECTORY; - std::cout << "Config file found in current directory (" << _config_directory << ")...\n"; - return; - } - - // 2. search in user config path - std::ifstream userCfgFile( localPath + std::string( "/" ) + _config_filename ); - if( userCfgFile.is_open() ) - { - _config_directory = userPath; - _data_directory = userPath; - userCfgFile.close(); - _location = Location::USER; - std::cout << "Config file found in user directory (" << _config_directory << ")...\n"; - return; - } - - // 3. search in system config path - std::ifstream sysCfgFile( sysPath + std::string( "/" ) + _config_filename ); - if( sysCfgFile.is_open() ) - { - _config_directory = sysPath; - _data_directory = "/usr/share/bonzomatic"; - sysCfgFile.close(); - _location = Location::SYSTEM; - std::cout << "Config file found in system config path (" << _config_directory << ")...\n"; - return; - } - - _config_directory = curDir; - _location = Location::NONE; - std::cout << "No config file found, using default ApplicationSettings...\n"; - } -} \ No newline at end of file diff --git a/src/Config.h b/src/Config.h index 8f567bc3..e6c2b24b 100644 --- a/src/Config.h +++ b/src/Config.h @@ -2,6 +2,8 @@ #include "jsonxx.h" +#include "Utils.h" + #include namespace Config @@ -18,24 +20,38 @@ namespace Config NONE }; - ApplicationSettings( const std::string& cfg_filename ); + ApplicationSettings( const std::string& cfg_filename ) + : location_( Location::NONE ), config_filename_( cfg_filename ) {} - void load(); + void load() + { + find_location(); + if( location_ != Location::NONE ) + { + read_config(); + } + } - const jsonxx::Object get_options() const { return _options; } - const std::string get_config_directory() const { return _config_directory; } - const std::string get_data_directory() const { return _data_directory; } + const jsonxx::Object get_options() const { return options_; } + const std::string get_config_directory_() const { return config_directory_; } + const std::string get_data_directory() const { return data_directory_; } private: void find_location(); - void read_config(); - - Location _location; - std::string _config_filename; - jsonxx::Object _options; - - std::string _config_directory; - std::string _data_directory; + void read_config() + { + std::string config_path( config_directory_ + "/" + config_filename_ ); + std::vector< char > data; + Utils::read_file( config_path, data ); + options_.parse( &data[ 0 ] ); + } + + Location location_; + std::string config_filename_; + jsonxx::Object options_; + + std::string config_directory_; + std::string data_directory_; }; diff --git a/src/Utils.h b/src/Utils.h new file mode 100644 index 00000000..3fb3a120 --- /dev/null +++ b/src/Utils.h @@ -0,0 +1,11 @@ +#pragma once + +#include +#include + +namespace Utils +{ + + bool read_file( const std::string& filename, std::vector< char >& out ); + +} \ No newline at end of file diff --git a/src/platform_common/Config.cpp b/src/platform_common/Config.cpp new file mode 100644 index 00000000..45913b13 --- /dev/null +++ b/src/platform_common/Config.cpp @@ -0,0 +1,35 @@ +#include "Config.h" + +#ifdef _WIN32 +#include +#define getcwd _getcwd +#else +#include +#endif + + +namespace Config +{ + + void ApplicationSettings::find_location() + { + char cwd[ 256 ]; + getcwd( cwd, 255 ); + std::string curDir( cwd ); + + std::ifstream cfgFile( config_filename_ ); + if( cfgFile.is_open() ) + { + config_directory_ = curDir; + data_directory_ = curDir; + cfgFile.close(); + location_ = Location::DIRECTORY; + std::cout << "Config file found in current directory (" << config_directory_ << ")...\n"; + return; + } + + config_directory_ = curDir; + location_ = Location::NONE; + std::cout << "No config file found, using default settings...\n"; + } +} \ No newline at end of file diff --git a/src/platform_common/Utils.cpp b/src/platform_common/Utils.cpp new file mode 100644 index 00000000..8b67d133 --- /dev/null +++ b/src/platform_common/Utils.cpp @@ -0,0 +1,20 @@ +#include +#include +#include + +namespace Utils +{ + + bool read_file( const std::string& filename, std::vector< char >& out ) + { + std::ifstream fp( filename ); + if( !fp.is_open() ) return false; + fp.seekg( 0, std::ios::end ); + size_t file_size_in_byte = fp.tellg(); + out.resize( file_size_in_byte ); + fp.seekg( 0, std::ios::beg ); + fp.read( &out[ 0 ], file_size_in_byte ); + return true; + } + +} \ No newline at end of file diff --git a/src/platform_linux/Config.cpp b/src/platform_linux/Config.cpp new file mode 100644 index 00000000..5fcec6ad --- /dev/null +++ b/src/platform_linux/Config.cpp @@ -0,0 +1,65 @@ +#include "Config.h" + +#include +#include +#include + +#include + + +namespace Config +{ + + void ApplicationSettings::find_location() + { + const std::string sysPath( "/etc/bonzomatic" ); + const std::string userPath( getenv( "HOME" ) ); + const std::string localConfigPath = "/.config/bonzomatic"; + std::string localPath = userPath + localConfigPath; + + char cwd[ 256 ]; + getcwd( cwd, 255 ); + std::string curDir( cwd ); + + // 1. search in current directory + std::ifstream cfgFile( config_filename_ ); + if( cfgFile.is_open() ) + { + config_directory_ = curDir; + data_directory_ = curDir; + cfgFile.close(); + location_ = Location::DIRECTORY; + std::cout << "Config file found in current directory (" << config_directory_ << ")...\n"; + return; + } + + // 2. search in user config path + std::ifstream userCfgFile( localPath + std::string( "/" ) + config_filename_ ); + if( userCfgFile.is_open() ) + { + config_directory_ = userPath; + data_directory_ = userPath; + userCfgFile.close(); + location_ = Location::USER; + std::cout << "Config file found in user directory (" << config_directory_ << ")...\n"; + return; + } + + // 3. search in system config path + std::ifstream sysCfgFile( sysPath + std::string( "/" ) + config_filename_ ); + if( sysCfgFile.is_open() ) + { + config_directory_ = sysPath; + data_directory_ = "/usr/share/bonzomatic"; + sysCfgFile.close(); + location_ = Location::SYSTEM; + std::cout << "Config file found in system config path (" << config_directory_ << ")...\n"; + return; + } + + config_directory_ = curDir; + location_ = Location::NONE; + std::cout << "No config file found, using default settings...\n"; + } + +} \ No newline at end of file From a9c9ab3a15a1b96f95b364764403b5afa286347e Mon Sep 17 00:00:00 2001 From: Florent CURE Date: Mon, 27 May 2019 23:02:54 +0100 Subject: [PATCH 03/11] Add loading of shader from correct data directory Default shader is now loaded from data directory according to where config.json was found. --- src/main.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/main.cpp b/src/main.cpp index 80cf16a1..4d542ac3 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -245,7 +245,8 @@ int main(int argc, const char *argv[]) bool shaderInitSuccessful = false; char szShader[65535]; char szError[4096]; - FILE * f = fopen(Renderer::defaultShaderFilename,"rb"); + std::string defaultShaderFilePath = app_settings.get_data_directory() + std::string("/") + std::string(Renderer::defaultShaderFilename); + FILE * f = fopen( defaultShaderFilePath.c_str(),"rb" ); if (f) { printf("Loading last shader...\n"); From c2314cf0fd43d5e4f50b57b8fa2446389ef90487 Mon Sep 17 00:00:00 2001 From: Florent CURE Date: Mon, 27 May 2019 23:03:19 +0100 Subject: [PATCH 04/11] Update Readme.md to reflect modifications --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index f670baf2..a6a41107 100644 --- a/README.md +++ b/README.md @@ -25,6 +25,7 @@ On recent macOS, to allow sound input to be captured (for FFT textures to be gen ## Configuration You can configure Bonzomatic by creating a `config.json` and placing it next to the binary executable you're planning to run in the working directory for the binary; Bonzomatic will helpfully print this directory out for you when you run it, and you can also pass a file (with absolute or relative path, whichever you want) to load any other file as `config.json`. This allows you to have multiple configurations for multiple situations. +On Linux this file will be searched, in this order, in the executable directory, then in `~/.config/bonzomatic`, and finally in `/etc/bonzomatic`. Data (textures and last shader) will then be searched in a directory relative to where the `config.json` file was found. The only exception is if `config.json` is found in `/etc/bonzomatic` then data will be searched in `/usr/share/bonzomatic`. The file can have the following contents: (all fields are optional) ``` javascript From 032ed094c5b6aa422ee903436289e481efea4ca9 Mon Sep 17 00:00:00 2001 From: Florent CURE Date: Mon, 27 May 2019 23:18:35 +0100 Subject: [PATCH 05/11] Improved formatting in Readme.md --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index a6a41107..b7d1c059 100644 --- a/README.md +++ b/README.md @@ -25,6 +25,7 @@ On recent macOS, to allow sound input to be captured (for FFT textures to be gen ## Configuration You can configure Bonzomatic by creating a `config.json` and placing it next to the binary executable you're planning to run in the working directory for the binary; Bonzomatic will helpfully print this directory out for you when you run it, and you can also pass a file (with absolute or relative path, whichever you want) to load any other file as `config.json`. This allows you to have multiple configurations for multiple situations. + On Linux this file will be searched, in this order, in the executable directory, then in `~/.config/bonzomatic`, and finally in `/etc/bonzomatic`. Data (textures and last shader) will then be searched in a directory relative to where the `config.json` file was found. The only exception is if `config.json` is found in `/etc/bonzomatic` then data will be searched in `/usr/share/bonzomatic`. The file can have the following contents: (all fields are optional) From 9f87a2b59d6d00a752c2e98bf36f17a70fb8428a Mon Sep 17 00:00:00 2001 From: Florent CURE Date: Mon, 27 May 2019 23:41:36 +0100 Subject: [PATCH 06/11] Added forgotten platform_common/Config.cpp in CMakeLists.txt --- CMakeLists.txt | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/CMakeLists.txt b/CMakeLists.txt index c0a0fad6..ffd3e63b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -331,6 +331,7 @@ if (APPLE) ${CMAKE_SOURCE_DIR}/src/platform_glfw/Renderer.cpp ${CMAKE_SOURCE_DIR}/src/platform_common/FFT.cpp ${CMAKE_SOURCE_DIR}/src/platform_common/Utils.cpp + ${CMAKE_SOURCE_DIR}/src/platform_common/Config.cpp ${CMAKE_SOURCE_DIR}/src/platform_x11/MIDI.cpp ${CMAKE_SOURCE_DIR}/src/platform_osx/Misc.mm ${CMAKE_SOURCE_DIR}/src/platform_x11/Timer.cpp @@ -362,6 +363,7 @@ elseif (WIN32) ${CMAKE_SOURCE_DIR}/src/platform_w32_dx11/Renderer.cpp ${CMAKE_SOURCE_DIR}/src/platform_common/FFT.cpp ${CMAKE_SOURCE_DIR}/src/platform_common/Utils.cpp + ${CMAKE_SOURCE_DIR}/src/platform_common/Config.cpp ${CMAKE_SOURCE_DIR}/src/platform_w32_common/MIDI.cpp ${CMAKE_SOURCE_DIR}/src/platform_w32_common/Misc.cpp ${CMAKE_SOURCE_DIR}/src/platform_w32_common/SetupDialog.cpp @@ -374,6 +376,7 @@ elseif (WIN32) ${CMAKE_SOURCE_DIR}/src/platform_w32_dx9/Renderer.cpp ${CMAKE_SOURCE_DIR}/src/platform_common/FFT.cpp ${CMAKE_SOURCE_DIR}/src/platform_common/Utils.cpp + ${CMAKE_SOURCE_DIR}/src/platform_common/Config.cpp ${CMAKE_SOURCE_DIR}/src/platform_w32_common/MIDI.cpp ${CMAKE_SOURCE_DIR}/src/platform_w32_common/Misc.cpp ${CMAKE_SOURCE_DIR}/src/platform_w32_common/SetupDialog.cpp @@ -386,6 +389,7 @@ elseif (WIN32) ${CMAKE_SOURCE_DIR}/src/platform_glfw/Renderer.cpp ${CMAKE_SOURCE_DIR}/src/platform_common/FFT.cpp ${CMAKE_SOURCE_DIR}/src/platform_common/Utils.cpp + ${CMAKE_SOURCE_DIR}/src/platform_common/Config.cpp ${CMAKE_SOURCE_DIR}/src/platform_w32_common/MIDI.cpp ${CMAKE_SOURCE_DIR}/src/platform_w32_common/Misc.cpp ${CMAKE_SOURCE_DIR}/src/platform_w32_common/SetupDialog.cpp From e204b366059d474707696c6cf90ef86716d3670d Mon Sep 17 00:00:00 2001 From: Florent CURE Date: Tue, 28 May 2019 09:39:43 +0100 Subject: [PATCH 07/11] Add missing headers --- src/platform_common/Config.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/platform_common/Config.cpp b/src/platform_common/Config.cpp index 45913b13..0caa5b6f 100644 --- a/src/platform_common/Config.cpp +++ b/src/platform_common/Config.cpp @@ -1,5 +1,8 @@ #include "Config.h" +#include +#include + #ifdef _WIN32 #include #define getcwd _getcwd From 18866b5a58d8c7fc3c9e6ed07b856e0d05e448a1 Mon Sep 17 00:00:00 2001 From: Florent CURE Date: Tue, 28 May 2019 09:40:33 +0100 Subject: [PATCH 08/11] Correct enum syntax related error --- src/Config.h | 12 ++++++------ src/platform_common/Config.cpp | 4 ++-- src/platform_linux/Config.cpp | 8 ++++---- 3 files changed, 12 insertions(+), 12 deletions(-) diff --git a/src/Config.h b/src/Config.h index e6c2b24b..15dcab7a 100644 --- a/src/Config.h +++ b/src/Config.h @@ -14,19 +14,19 @@ namespace Config public: enum Location { - SYSTEM, - USER, - DIRECTORY, - NONE + LOC_SYSTEM, + LOC_USER, + LOC_DIRECTORY, + LOC_NONE }; ApplicationSettings( const std::string& cfg_filename ) - : location_( Location::NONE ), config_filename_( cfg_filename ) {} + : location_( LOC_NONE ), config_filename_( cfg_filename ) {} void load() { find_location(); - if( location_ != Location::NONE ) + if( location_ != LOC_NONE ) { read_config(); } diff --git a/src/platform_common/Config.cpp b/src/platform_common/Config.cpp index 0caa5b6f..749b9650 100644 --- a/src/platform_common/Config.cpp +++ b/src/platform_common/Config.cpp @@ -26,13 +26,13 @@ namespace Config config_directory_ = curDir; data_directory_ = curDir; cfgFile.close(); - location_ = Location::DIRECTORY; + location_ = LOC_DIRECTORY; std::cout << "Config file found in current directory (" << config_directory_ << ")...\n"; return; } config_directory_ = curDir; - location_ = Location::NONE; + location_ = LOC_NONE; std::cout << "No config file found, using default settings...\n"; } } \ No newline at end of file diff --git a/src/platform_linux/Config.cpp b/src/platform_linux/Config.cpp index 5fcec6ad..945c76bc 100644 --- a/src/platform_linux/Config.cpp +++ b/src/platform_linux/Config.cpp @@ -28,7 +28,7 @@ namespace Config config_directory_ = curDir; data_directory_ = curDir; cfgFile.close(); - location_ = Location::DIRECTORY; + location_ = LOC_DIRECTORY; std::cout << "Config file found in current directory (" << config_directory_ << ")...\n"; return; } @@ -40,7 +40,7 @@ namespace Config config_directory_ = userPath; data_directory_ = userPath; userCfgFile.close(); - location_ = Location::USER; + location_ = LOC_USER; std::cout << "Config file found in user directory (" << config_directory_ << ")...\n"; return; } @@ -52,13 +52,13 @@ namespace Config config_directory_ = sysPath; data_directory_ = "/usr/share/bonzomatic"; sysCfgFile.close(); - location_ = Location::SYSTEM; + location_ = LOC_SYSTEM; std::cout << "Config file found in system config path (" << config_directory_ << ")...\n"; return; } config_directory_ = curDir; - location_ = Location::NONE; + location_ = LOC_NONE; std::cout << "No config file found, using default settings...\n"; } From fa346813cba1f3ca00ad1415fa81e2e100d5dabf Mon Sep 17 00:00:00 2001 From: Florent CURE Date: Tue, 28 May 2019 09:51:37 +0100 Subject: [PATCH 09/11] Fix read_file which didnt compile on some platform --- src/platform_common/Utils.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/platform_common/Utils.cpp b/src/platform_common/Utils.cpp index 8b67d133..101ce613 100644 --- a/src/platform_common/Utils.cpp +++ b/src/platform_common/Utils.cpp @@ -7,7 +7,7 @@ namespace Utils bool read_file( const std::string& filename, std::vector< char >& out ) { - std::ifstream fp( filename ); + std::ifstream fp( filename.c_str() ); if( !fp.is_open() ) return false; fp.seekg( 0, std::ios::end ); size_t file_size_in_byte = fp.tellg(); From 3ee002380854b42e8a1c47481686f7e178a2023e Mon Sep 17 00:00:00 2001 From: Florent CURE Date: Tue, 28 May 2019 09:56:37 +0100 Subject: [PATCH 10/11] Fix missing header for getenv() --- src/platform_linux/Config.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/platform_linux/Config.cpp b/src/platform_linux/Config.cpp index 945c76bc..24be680a 100644 --- a/src/platform_linux/Config.cpp +++ b/src/platform_linux/Config.cpp @@ -5,6 +5,7 @@ #include #include +#include namespace Config From 76a9f393ea723084696101a5e1e9c200a4c02125 Mon Sep 17 00:00:00 2001 From: Florent CURE Date: Tue, 28 May 2019 10:04:19 +0100 Subject: [PATCH 11/11] Fixed some file openings that didn't compile on some platform --- src/platform_common/Config.cpp | 2 +- src/platform_linux/Config.cpp | 8 +++++--- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/src/platform_common/Config.cpp b/src/platform_common/Config.cpp index 749b9650..8d62a6a2 100644 --- a/src/platform_common/Config.cpp +++ b/src/platform_common/Config.cpp @@ -20,7 +20,7 @@ namespace Config getcwd( cwd, 255 ); std::string curDir( cwd ); - std::ifstream cfgFile( config_filename_ ); + std::ifstream cfgFile( config_filename_.c_str() ); if( cfgFile.is_open() ) { config_directory_ = curDir; diff --git a/src/platform_linux/Config.cpp b/src/platform_linux/Config.cpp index 24be680a..e6e74260 100644 --- a/src/platform_linux/Config.cpp +++ b/src/platform_linux/Config.cpp @@ -23,7 +23,7 @@ namespace Config std::string curDir( cwd ); // 1. search in current directory - std::ifstream cfgFile( config_filename_ ); + std::ifstream cfgFile( config_filename_.c_str() ); if( cfgFile.is_open() ) { config_directory_ = curDir; @@ -35,7 +35,8 @@ namespace Config } // 2. search in user config path - std::ifstream userCfgFile( localPath + std::string( "/" ) + config_filename_ ); + std::string userCfgPath( localPath + std::string( "/" ) + config_filename_ ); + std::ifstream userCfgFile( userCfgPath.c_str() ); if( userCfgFile.is_open() ) { config_directory_ = userPath; @@ -47,7 +48,8 @@ namespace Config } // 3. search in system config path - std::ifstream sysCfgFile( sysPath + std::string( "/" ) + config_filename_ ); + std::string sysCfgPath( sysPath + std::string( "/" ) + config_filename_ ); + std::ifstream sysCfgFile( sysCfgPath.c_str()); if( sysCfgFile.is_open() ) { config_directory_ = sysPath;