diff --git a/include/display_structs.hpp b/include/display_structs.hpp index 9f62ee1..ec1f988 100755 --- a/include/display_structs.hpp +++ b/include/display_structs.hpp @@ -33,7 +33,7 @@ struct ScreenInfo { }; struct DisplayData { - bool split = false; + bool split; }; #pragma pack(push, 1) diff --git a/include/frontend.hpp b/include/frontend.hpp index c2b7c6c..db1d37e 100755 --- a/include/frontend.hpp +++ b/include/frontend.hpp @@ -219,6 +219,7 @@ struct FrontendData { bool is_allowed_crop(const CropData* crop_data, ScreenType s_type); void insert_basic_crops(std::vector &crop_vector, ScreenType s_type); void insert_basic_pars(std::vector &par_vector); +void reset_display_data(DisplayData *display_data); void reset_fullscreen_info(ScreenInfo &info); void reset_screen_info(ScreenInfo &info); bool load_screen_info(std::string key, std::string value, std::string base, ScreenInfo &info); diff --git a/include/utils.hpp b/include/utils.hpp index 1d5aef8..0a0eee9 100755 --- a/include/utils.hpp +++ b/include/utils.hpp @@ -20,6 +20,12 @@ #define USB_NUM_CHECKS 3 #define USB_CHECKS_PER_SECOND ((USB_FPS + (USB_FPS / 12)) * USB_NUM_CHECKS) +#define STARTUP_FILE_INDEX -1 +#define SIMPLE_RESET_DATA_INDEX -2 + +std::string LayoutNameGenerator(int index); +std::string LayoutPathGenerator(int index); +std::string load_layout_name(int index, bool &success); bool is_big_endian(void); std::string get_float_str_decimals(float value, int decimals); diff --git a/source/WindowScreen.cpp b/source/WindowScreen.cpp index 311d9c7..ee57651 100755 --- a/source/WindowScreen.cpp +++ b/source/WindowScreen.cpp @@ -693,8 +693,7 @@ void WindowScreen::poll() { return; if(this->query_reset_request()) { this->reset_held_times(); - reset_screen_info(this->m_info); - this->reload(); + this->m_prepare_load = SIMPLE_RESET_DATA_INDEX; done = true; continue; } @@ -1987,6 +1986,7 @@ void WindowScreen::update_view_size() { } void WindowScreen::open() { + this->m_info.is_fullscreen = false; this->create_window(true); } diff --git a/source/cc3dsfs.cpp b/source/cc3dsfs.cpp index 8fa8ec0..05817b1 100755 --- a/source/cc3dsfs.cpp +++ b/source/cc3dsfs.cpp @@ -60,31 +60,23 @@ static void SuccessConnectionOutTextGenerator(OutTextData &out_text_data, Captur } } -static std::string LayoutNameGenerator(int index) { - return "layout" + std::to_string(index) + ".cfg"; -} - static bool load(const std::string path, const std::string name, ScreenInfo &top_info, ScreenInfo &bottom_info, ScreenInfo &joint_info, DisplayData &display_data, AudioData *audio_data, OutTextData &out_text_data) { std::ifstream file(path + name); std::string line; - reset_screen_info(top_info); - reset_screen_info(bottom_info); - reset_screen_info(joint_info); - - if (!file.good()) { + if(!file.good()) { UpdateOutText(out_text_data, "File " + path + name + " load failed.\nDefaults re-loaded.", "Load failed\nDefaults re-loaded", TEXT_KIND_ERROR); return false; } - while (std::getline(file, line)) { + while(std::getline(file, line)) { std::istringstream kvp(line); std::string key; - if (std::getline(kvp, key, '=')) { + if(std::getline(kvp, key, '=')) { std::string value; - if (std::getline(kvp, value)) { + if(std::getline(kvp, value)) { if(load_screen_info(key, value, "bot_", bottom_info)) continue; @@ -93,7 +85,7 @@ static bool load(const std::string path, const std::string name, ScreenInfo &top if(load_screen_info(key, value, "top_", top_info)) continue; - if (key == "split") { + if(key == "split") { display_data.split = std::stoi(value); continue; } @@ -108,18 +100,45 @@ static bool load(const std::string path, const std::string name, ScreenInfo &top return true; } -static bool save(const std::string path, const std::string name, const ScreenInfo &top_info, const ScreenInfo &bottom_info, const ScreenInfo &joint_info, DisplayData &display_data, AudioData *audio_data, OutTextData &out_text_data) { +static void load_layout_file(int load_index, FrontendData *frontend_data, AudioData* audio_data, OutTextData &out_text_data, bool skip_io) { + if(skip_io) + return; + + reset_screen_info(frontend_data->top_screen->m_info); + reset_screen_info(frontend_data->bot_screen->m_info); + reset_screen_info(frontend_data->joint_screen->m_info); + audio_data->reset(); + reset_display_data(&frontend_data->display_data); + frontend_data->reload = true; + + if(load_index == SIMPLE_RESET_DATA_INDEX) { + UpdateOutText(out_text_data, "Reset detected. Defaults re-loaded", "Reset detected\nDefaults re-loaded", TEXT_KIND_WARNING); + return; + } + + bool name_load_success = false; + std::string layout_name = LayoutNameGenerator(load_index); + std::string layout_path = LayoutPathGenerator(load_index); + bool op_success = load(layout_path, layout_name, frontend_data->top_screen->m_info, frontend_data->bot_screen->m_info, frontend_data->joint_screen->m_info, frontend_data->display_data, audio_data, out_text_data); + if((load_index != STARTUP_FILE_INDEX) && op_success) { + std::string load_name = load_layout_name(load_index, name_load_success); + UpdateOutText(out_text_data, "Layout loaded from: " + layout_path + layout_name, "Layout " + load_name + " loaded", TEXT_KIND_SUCCESS); + } +} + +static bool save(const std::string path, const std::string name, const std::string save_name, const ScreenInfo &top_info, const ScreenInfo &bottom_info, const ScreenInfo &joint_info, DisplayData &display_data, AudioData *audio_data, OutTextData &out_text_data) { #if (!defined(_MSC_VER)) || (_MSC_VER > 1916) std::filesystem::create_directories(path); #else std::experimental::filesystem::create_directories(path); #endif std::ofstream file(path + name); - if (!file.good()) { + if(!file.good()) { UpdateOutText(out_text_data, "File " + path + name + " save failed.", "Save failed", TEXT_KIND_ERROR); return false; } + file << "name=" << save_name << std::endl; file << save_screen_info("bot_", bottom_info); file << save_screen_info("joint_", joint_info); file << save_screen_info("top_", top_info); @@ -130,6 +149,23 @@ static bool save(const std::string path, const std::string name, const ScreenInf return true; } +static void save_layout_file(int save_index, FrontendData *frontend_data, AudioData* audio_data, OutTextData &out_text_data, bool skip_io) { + if(skip_io) + return; + + if(save_index == SIMPLE_RESET_DATA_INDEX) + return; + + bool name_load_success = false; + std::string save_name = load_layout_name(save_index, name_load_success); + std::string layout_name = LayoutNameGenerator(save_index); + std::string layout_path = LayoutPathGenerator(save_index); + bool op_success = save(layout_path, layout_name, save_name, frontend_data->top_screen->m_info, frontend_data->bot_screen->m_info, frontend_data->joint_screen->m_info, frontend_data->display_data, audio_data, out_text_data); + if((save_index != STARTUP_FILE_INDEX) && op_success) { + UpdateOutText(out_text_data, "Layout saved to: " + layout_path + layout_name, "Layout " + save_name + " saved", TEXT_KIND_SUCCESS); + } +} + static void soundCall(AudioData *audio_data, CaptureData* capture_data) { Audio audio(audio_data); sf::Int16 out_buf[NUM_CONCURRENT_AUDIO_BUFFERS][MAX_SAMPLES_IN]; @@ -137,7 +173,7 @@ static void soundCall(AudioData *audio_data, CaptureData* capture_data) { const bool endianness = is_big_endian(); volatile int loaded_samples; - while (capture_data->status.running) { + while(capture_data->status.running) { if(capture_data->status.connected) { bool timed_out = !capture_data->status.audio_wait.timed_lock(); curr_out = (capture_data->status.curr_in - 1 + NUM_CONCURRENT_DATA_BUFFERS) % NUM_CONCURRENT_DATA_BUFFERS; @@ -194,6 +230,7 @@ static void mainVideoOutputCall(AudioData* audio_data, CaptureData* capture_data int num_elements_fps_array = 0; int curr_out, prev_out = NUM_CONCURRENT_DATA_BUFFERS - 1; FrontendData frontend_data; + reset_display_data(&frontend_data.display_data); frontend_data.reload = true; bool skip_io = false; int num_allowed_blanks = MAX_ALLOWED_BLANKS; @@ -202,15 +239,6 @@ static void mainVideoOutputCall(AudioData* audio_data, CaptureData* capture_data OutTextData out_text_data; out_text_data.consumed = true; - #if !(defined(_WIN32) || defined(_WIN64)) - std::string cfg_dir = std::string(std::getenv("HOME")) + "/.config/" + std::string(NAME); - #else - std::string cfg_dir = ".config/" + std::string(NAME); - #endif - std::string base_path = cfg_dir + "/"; - std::string base_name = std::string(NAME) + ".cfg"; - std::string layout_path = cfg_dir + "/presets/"; - out_buf = new VideoOutputData; curr_fps_array = new double[FPS_WINDOW_SIZE]; memset(out_buf, 0, sizeof(VideoOutputData)); @@ -222,13 +250,11 @@ static void mainVideoOutputCall(AudioData* audio_data, CaptureData* capture_data frontend_data.bot_screen = &bot_screen; frontend_data.joint_screen = &joint_screen; - if(!skip_io) { - load(base_path, base_name, top_screen.m_info, bot_screen.m_info, joint_screen.m_info, frontend_data.display_data, audio_data, out_text_data); - // Due to the risk for seizures, at the start of the program, set BFI to false! - top_screen.m_info.bfi = false; - bot_screen.m_info.bfi = false; - joint_screen.m_info.bfi = false; - } + load_layout_file(STARTUP_FILE_INDEX, &frontend_data, audio_data, out_text_data, skip_io); + // Due to the risk for seizures, at the start of the program, set BFI to false! + top_screen.m_info.bfi = false; + bot_screen.m_info.bfi = false; + joint_screen.m_info.bfi = false; top_screen.build(); bot_screen.build(); @@ -241,13 +267,13 @@ static void mainVideoOutputCall(AudioData* audio_data, CaptureData* capture_data capture_data->status.connected = connect(true, capture_data, &frontend_data); SuccessConnectionOutTextGenerator(out_text_data, capture_data); - while (capture_data->status.running) { + while(capture_data->status.running) { if(capture_data->status.connected) { bool timed_out = !capture_data->status.video_wait.timed_lock(); curr_out = (capture_data->status.curr_in - 1 + NUM_CONCURRENT_DATA_BUFFERS) % NUM_CONCURRENT_DATA_BUFFERS; - if ((!capture_data->status.cooldown_curr_in) && (curr_out != prev_out)) { + if((!capture_data->status.cooldown_curr_in) && (curr_out != prev_out)) { double frame_time = capture_data->time_in_buf[curr_out]; if(capture_data->read[curr_out] >= sizeof(VideoInputData)) { convertVideoToOutput(&capture_data->capture_buf[curr_out].video_data, out_buf); @@ -314,24 +340,11 @@ static void mainVideoOutputCall(AudioData* audio_data, CaptureData* capture_data capture_data->status.running = false; } - if((load_index = top_screen.load_data()) || (load_index = bot_screen.load_data()) || (load_index = joint_screen.load_data())) { - if (!skip_io) { - std::string layout_name = LayoutNameGenerator(load_index); - bool op_success = load(layout_path, layout_name, top_screen.m_info, bot_screen.m_info, joint_screen.m_info, frontend_data.display_data, audio_data, out_text_data); - if(op_success) - UpdateOutText(out_text_data, "Layout loaded from: " + layout_path + layout_name, "Layout " + std::to_string(load_index) + " loaded", TEXT_KIND_SUCCESS); - frontend_data.reload = true; - } - } + if((load_index = top_screen.load_data()) || (load_index = bot_screen.load_data()) || (load_index = joint_screen.load_data())) + load_layout_file(load_index, &frontend_data, audio_data, out_text_data, skip_io); - if((save_index = top_screen.save_data()) || (save_index = bot_screen.save_data()) || (save_index = joint_screen.save_data())) { - if (!skip_io) { - std::string layout_name = LayoutNameGenerator(save_index); - bool op_success = save(layout_path, layout_name, top_screen.m_info, bot_screen.m_info, joint_screen.m_info, frontend_data.display_data, audio_data, out_text_data); - if(op_success) - UpdateOutText(out_text_data, "Layout saved to: " + layout_path + layout_name, "Layout " + std::to_string(save_index) + " saved", TEXT_KIND_SUCCESS); - } - } + if((save_index = top_screen.save_data()) || (save_index = bot_screen.save_data()) || (save_index = joint_screen.save_data())) + save_layout_file(save_index, &frontend_data, audio_data, out_text_data, skip_io); if(audio_data->has_text_to_print()) { UpdateOutText(out_text_data, "", audio_data->text_to_print(), TEXT_KIND_NORMAL); @@ -342,7 +355,7 @@ static void mainVideoOutputCall(AudioData* audio_data, CaptureData* capture_data capture_data->status.new_error_text = false; } - if(!out_text_data.consumed) { + if((!out_text_data.consumed) && (!frontend_data.reload)) { ConsoleOutText(out_text_data.full_text); top_screen.print_notification(out_text_data.small_text, out_text_data.kind); bot_screen.print_notification(out_text_data.small_text, out_text_data.kind); @@ -363,9 +376,7 @@ static void mainVideoOutputCall(AudioData* audio_data, CaptureData* capture_data bot_screen.after_thread_join(); joint_screen.after_thread_join(); - if (!skip_io) { - save(base_path, base_name, top_screen.m_info, bot_screen.m_info, joint_screen.m_info, frontend_data.display_data, audio_data, out_text_data); - } + save_layout_file(STARTUP_FILE_INDEX, &frontend_data, audio_data, out_text_data, skip_io); if(!out_text_data.consumed) { ConsoleOutText(out_text_data.full_text); diff --git a/source/frontend.cpp b/source/frontend.cpp index bef6ddd..d73ca2b 100755 --- a/source/frontend.cpp +++ b/source/frontend.cpp @@ -159,6 +159,10 @@ void insert_basic_pars(std::vector &par_vector) { } } +void reset_display_data(DisplayData *display_data) { + display_data->split = false; +} + void reset_fullscreen_info(ScreenInfo &info) { info.fullscreen_mode_width = 0; info.fullscreen_mode_height = 0; diff --git a/source/utils.cpp b/source/utils.cpp index 753b6a8..12bd99e 100755 --- a/source/utils.cpp +++ b/source/utils.cpp @@ -1,5 +1,8 @@ #include "utils.hpp" +#include +#include +#include #include #include #include @@ -33,6 +36,60 @@ std::string get_float_str_decimals(float value, int decimals) { return return_text; } + +std::string LayoutNameGenerator(int index) { + if(index == STARTUP_FILE_INDEX) + return std::string(NAME) + ".cfg"; + return "layout" + std::to_string(index) + ".cfg"; +} + +std::string LayoutPathGenerator(int index) { + #if !(defined(_WIN32) || defined(_WIN64)) + std::string cfg_dir = std::string(std::getenv("HOME")) + "/.config/" + std::string(NAME); + #else + std::string cfg_dir = ".config/" + std::string(NAME); + #endif + if(index == STARTUP_FILE_INDEX) + return cfg_dir + "/"; + return cfg_dir + "/presets/"; +} + +std::string load_layout_name(int index, bool &success) { + if(index == STARTUP_FILE_INDEX) { + success = true; + return "Initial"; + } + std::string name = LayoutNameGenerator(index); + std::string path = LayoutPathGenerator(index); + + std::ifstream file(path + name); + std::string line; + success = false; + + if(!file.good()) { + return std::to_string(index); + } + + success = true; + while(std::getline(file, line)) { + std::istringstream kvp(line); + std::string key; + + if(std::getline(kvp, key, '=')) { + std::string value; + if(std::getline(kvp, value)) { + + if(key == "name") { + file.close(); + return value; + } + } + } + } + + file.close(); + return std::to_string(index); +} //============================================================================ ConsumerMutex::ConsumerMutex() {