diff --git a/CMakeLists.txt b/CMakeLists.txt index 3026549..ed3330e 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -132,7 +132,7 @@ file(MAKE_DIRECTORY ${TOOLS_DATA_DIR}) set(OUTPUT_NAME cc3dsfs) add_executable(CMakeBin2C tools/bin2c.cpp) -add_executable(${OUTPUT_NAME} source/cc3dsfs.cpp source/utils.cpp source/audio_data.cpp source/audio.cpp source/frontend.cpp source/TextRectangle.cpp source/WindowScreen.cpp source/3dscapture.cpp source/conversions.cpp source/Menus/ConnectionMenu.cpp source/Menus/OptionSelectionMenu.cpp source/Menus/MainMenu.cpp source/Menus/VideoMenu.cpp source/Menus/CropMenu.cpp source/Menus/PARMenu.cpp source/Menus/RotationMenu.cpp source/Menus/OffsetMenu.cpp source/Menus/AudioMenu.cpp source/Menus/BFIMenu.cpp source/Menus/RelativePositionMenu.cpp source/Menus/ResolutionMenu.cpp source/Menus/FileConfigMenu.cpp source/Menus/ExtraSettingsMenu.cpp ${TOOLS_DATA_DIR}/font_ttf.cpp) +add_executable(${OUTPUT_NAME} source/cc3dsfs.cpp source/utils.cpp source/audio_data.cpp source/audio.cpp source/frontend.cpp source/TextRectangle.cpp source/WindowScreen.cpp source/3dscapture.cpp source/conversions.cpp source/Menus/ConnectionMenu.cpp source/Menus/OptionSelectionMenu.cpp source/Menus/MainMenu.cpp source/Menus/VideoMenu.cpp source/Menus/CropMenu.cpp source/Menus/PARMenu.cpp source/Menus/RotationMenu.cpp source/Menus/OffsetMenu.cpp source/Menus/AudioMenu.cpp source/Menus/BFIMenu.cpp source/Menus/RelativePositionMenu.cpp source/Menus/ResolutionMenu.cpp source/Menus/FileConfigMenu.cpp source/Menus/ExtraSettingsMenu.cpp source/Menus/StatusMenu.cpp ${TOOLS_DATA_DIR}/font_ttf.cpp) add_dependencies(${OUTPUT_NAME} FTD3XX_BUILD_PROJECT CMakeBin2C) target_link_libraries(${OUTPUT_NAME} PRIVATE sfml-graphics sfml-audio sfml-window sfml-system ${ftd3xx_BINARY_DIR}/${FTD3XX_SUBFOLDER}/${FTD3XX_LIB}) target_link_directories(${OUTPUT_NAME} PRIVATE ${ftd3xx_BINARY_DIR}/${FTD3XX_SUBFOLDER}) diff --git a/include/Menus/OptionSelectionMenu.hpp b/include/Menus/OptionSelectionMenu.hpp index 9a2df91..900a269 100755 --- a/include/Menus/OptionSelectionMenu.hpp +++ b/include/Menus/OptionSelectionMenu.hpp @@ -55,7 +55,7 @@ protected: void base_prepare(float menu_scaling_factor, int view_size_x, int view_size_y); std::string setTextOptionInt(int index, int value); std::string setTextOptionBool(int index, bool value); - std::string setTextOptionFloat(int index, float value); + std::string setTextOptionFloat(int index, float value, int num_decimals = 1); struct MenuData { int page = 0; diff --git a/include/Menus/StatusMenu.hpp b/include/Menus/StatusMenu.hpp new file mode 100755 index 0000000..73bbda2 --- /dev/null +++ b/include/Menus/StatusMenu.hpp @@ -0,0 +1,38 @@ +#ifndef __STATUSMENU_HPP +#define __STATUSMENU_HPP + +#include "OptionSelectionMenu.hpp" +#include + +#include "TextRectangle.hpp" +#include "sfml_gfx_structs.hpp" +#include "display_structs.hpp" + +enum StatusMenuOutAction{ + STATUS_MENU_NO_ACTION, + STATUS_MENU_BACK, +}; + +class StatusMenu : public OptionSelectionMenu { +public: + StatusMenu(bool font_load_success, sf::Font &text_font); + ~StatusMenu(); + void prepare(float scaling_factor, int view_size_x, int view_size_y, double in_fps, double poll_fps, double draw_fps); + void insert_data(); + StatusMenuOutAction selected_index = StatusMenuOutAction::STATUS_MENU_NO_ACTION; + void reset_output_option(); +protected: + bool is_option_inc_dec(int index); + bool is_option_selectable(int index, int action); + void set_output_option(int index, int action); + int get_num_options(); + std::string get_string_option(int index, int action); + void class_setup(); +private: + const float update_timeout = 1.0; + bool do_update; + std::chrono::time_point last_update_time; + int *options_indexes; + int num_enabled_options; +}; +#endif diff --git a/include/frontend.hpp b/include/frontend.hpp index b23d024..e56e3f2 100755 --- a/include/frontend.hpp +++ b/include/frontend.hpp @@ -25,6 +25,7 @@ #include "ResolutionMenu.hpp" #include "FileConfigMenu.hpp" #include "ExtraSettingsMenu.hpp" +#include "StatusMenu.hpp" #include "display_structs.hpp" struct HeldTime { @@ -32,6 +33,11 @@ struct HeldTime { bool started; }; +struct FPSArray { + double *data; + int index; +}; + class WindowScreen { public: ScreenInfo m_info; @@ -111,10 +117,16 @@ private: ResolutionMenu *resolution_menu; FileConfigMenu *fileconfig_menu; ExtraSettingsMenu *extra_menu; + StatusMenu *status_menu; std::vector possible_crops; std::vector possible_pars; std::vector possible_resolutions; std::vector possible_files; + FPSArray in_fps; + FPSArray draw_fps; + std::chrono::time_point last_draw_time; + FPSArray poll_fps; + std::chrono::time_point last_poll_time; sf::Texture in_tex; @@ -232,6 +244,6 @@ std::string save_screen_info(std::string base, const ScreenInfo &info); void get_par_size(float &width, float &height, float multiplier_factor, const PARData *correction_factor); void get_par_size(int &width, int &height, float multiplier_factor, const PARData *correction_factor); void default_sleep(); -void update_output(FrontendData* frontend_data, double frame_time = 0, VideoOutputData *out_buf = NULL); +void update_output(FrontendData* frontend_data, double frame_time = 0.0, VideoOutputData *out_buf = NULL); void screen_display_thread(WindowScreen *screen); #endif diff --git a/include/utils.hpp b/include/utils.hpp index db71d0b..6bcb406 100755 --- a/include/utils.hpp +++ b/include/utils.hpp @@ -17,7 +17,7 @@ // Use these to properly sleep, with small wakes to check if data is ready #define USB_FPS 60 #define BAD_USB_FPS 25 -#define USB_NUM_CHECKS 3 +#define USB_NUM_CHECKS 1 #define USB_CHECKS_PER_SECOND ((USB_FPS + (USB_FPS / 12)) * USB_NUM_CHECKS) #define STARTUP_FILE_INDEX -1 diff --git a/source/Menus/OptionSelectionMenu.cpp b/source/Menus/OptionSelectionMenu.cpp index 6d3ace6..dd7176b 100755 --- a/source/Menus/OptionSelectionMenu.cpp +++ b/source/Menus/OptionSelectionMenu.cpp @@ -222,8 +222,8 @@ std::string OptionSelectionMenu::setTextOptionBool(int index, bool value) { return this->get_string_option(index, DEFAULT_ACTION); return this->get_string_option(index, FALSE_ACTION); } -std::string OptionSelectionMenu::setTextOptionFloat(int index, float value) { - std::string out = this->get_string_option(index, DEFAULT_ACTION) + ": " + get_float_str_decimals(value, 1); +std::string OptionSelectionMenu::setTextOptionFloat(int index, float value, int num_decimals) { + std::string out = this->get_string_option(index, DEFAULT_ACTION) + ": " + get_float_str_decimals(value, num_decimals); return out; } diff --git a/source/Menus/StatusMenu.cpp b/source/Menus/StatusMenu.cpp new file mode 100755 index 0000000..2ad1b72 --- /dev/null +++ b/source/Menus/StatusMenu.cpp @@ -0,0 +1,156 @@ +#include "StatusMenu.hpp" + +#define NUM_TOTAL_MENU_OPTIONS (sizeof(pollable_options)/sizeof(pollable_options[0])) + +enum StatusMenuID { + STATUS_MENU_NAME_VERSION, + STATUS_MENU_URL, + STATUS_MENU_FPS_IN, + STATUS_MENU_FPS_POLL, + STATUS_MENU_FPS_DRAW, +}; + +struct StatusMenuOptionInfo { + const std::string base_name; + bool is_inc; + const StatusMenuID id; +}; + +static const StatusMenuOptionInfo status_name_version_option = { +.base_name = NAME, .is_inc = false, +.id = STATUS_MENU_NAME_VERSION}; + +static const StatusMenuOptionInfo status_url_option = { +.base_name = "github.com/Lorenzooone/cc3dsfs", .is_inc = false, +.id = STATUS_MENU_URL}; + +static const StatusMenuOptionInfo status_fps_in_option = { +.base_name = "Input FPS:", .is_inc = true, +.id = STATUS_MENU_FPS_IN}; + +static const StatusMenuOptionInfo status_fps_poll_option = { +.base_name = "Poll FPS:", .is_inc = true, +.id = STATUS_MENU_FPS_POLL}; + +static const StatusMenuOptionInfo status_fps_draw_option = { +.base_name = "Output FPS:", .is_inc = true, +.id = STATUS_MENU_FPS_DRAW}; + +static const StatusMenuOptionInfo* pollable_options[] = { +&status_name_version_option, +&status_url_option, +&status_fps_in_option, +&status_fps_poll_option, +&status_fps_draw_option, +}; + +StatusMenu::StatusMenu(bool font_load_success, sf::Font &text_font) : OptionSelectionMenu(){ + this->options_indexes = new int[NUM_TOTAL_MENU_OPTIONS]; + this->initialize(font_load_success, text_font); + this->num_enabled_options = 0; + this->last_update_time = std::chrono::high_resolution_clock::now(); + this->do_update = true; +} + +StatusMenu::~StatusMenu() { + delete []this->options_indexes; +} + +void StatusMenu::class_setup() { + this->num_options_per_screen = 5; + this->min_elements_text_scaling_factor = num_options_per_screen + 2; + this->width_factor_menu = 16; + this->width_divisor_menu = 9; + this->base_height_factor_menu = 12; + this->base_height_divisor_menu = 6; + this->min_text_size = 0.3; + this->max_width_slack = 1.1; + this->menu_color = sf::Color(30, 30, 60, 192); + this->title = "Offset Settings"; + this->show_back_x = true; + this->show_x = false; + this->show_title = true; +} + +void StatusMenu::insert_data() { + this->last_update_time = std::chrono::high_resolution_clock::now(); + this->do_update = true; + this->num_enabled_options = 0; + for(int i = 0; i < NUM_TOTAL_MENU_OPTIONS; i++) { + this->options_indexes[this->num_enabled_options] = i; + this->num_enabled_options++; + } + this->prepare_options(); +} + +void StatusMenu::reset_output_option() { + this->selected_index = StatusMenuOutAction::STATUS_MENU_NO_ACTION; +} + +void StatusMenu::set_output_option(int index, int action) { + if(index == BACK_X_OUTPUT_OPTION) + this->selected_index = STATUS_MENU_BACK; +} + +int StatusMenu::get_num_options() { + return this->num_enabled_options; +} + +bool StatusMenu::is_option_inc_dec(int index) { + return pollable_options[this->options_indexes[index]]->is_inc; +} + +std::string StatusMenu::get_string_option(int index, int action) { + if(action == DEC_ACTION) + return ""; + if(action == INC_ACTION) + return ""; + return pollable_options[this->options_indexes[index]]->base_name; +} + +bool StatusMenu::is_option_selectable(int index, int action) { + return false; +} + +void StatusMenu::prepare(float menu_scaling_factor, int view_size_x, int view_size_y, double in_fps, double poll_fps, double draw_fps) { + if(!this->do_update) { + auto curr_time = std::chrono::high_resolution_clock::now(); + const std::chrono::duration diff = curr_time - this->last_update_time; + if(diff.count() > this->update_timeout) + this->do_update = true; + } + + if(this->do_update) { + int num_pages = this->get_num_pages(); + if(this->future_data.page >= num_pages) + this->future_data.page = num_pages - 1; + int start = this->future_data.page * this->num_options_per_screen; + for(int i = 0; i < this->num_options_per_screen + 1; i++) { + int index = (i * this->single_option_multiplier) + this->elements_start_id; + if(!this->future_enabled_labels[index]) + continue; + int real_index = start + i; + int option_index = this->options_indexes[real_index]; + switch(pollable_options[option_index]->id) { + case STATUS_MENU_NAME_VERSION: + this->labels[index]->setText(this->get_string_option(real_index, DEFAULT_ACTION) + " - V." + get_version_string()); + break; + case STATUS_MENU_FPS_IN: + this->labels[index + INC_ACTION]->setText(get_float_str_decimals(in_fps, 2)); + break; + case STATUS_MENU_FPS_POLL: + this->labels[index + INC_ACTION]->setText(get_float_str_decimals(poll_fps, 2)); + break; + case STATUS_MENU_FPS_DRAW: + this->labels[index + INC_ACTION]->setText(get_float_str_decimals(draw_fps, 2)); + break; + default: + break; + } + } + this->do_update = false; + this->last_update_time = std::chrono::high_resolution_clock::now(); + } + + this->base_prepare(menu_scaling_factor, view_size_x, view_size_y); +} diff --git a/source/WindowScreen.cpp b/source/WindowScreen.cpp index c251584..1029dc4 100755 --- a/source/WindowScreen.cpp +++ b/source/WindowScreen.cpp @@ -3,11 +3,53 @@ #include #include "font_ttf.h" +#define FPS_WINDOW_SIZE 64 + #define LEFT_ROUNDED_PADDING 5 #define RIGHT_ROUNDED_PADDING 5 #define TOP_ROUNDED_PADDING 0 #define BOTTOM_ROUNDED_PADDING 5 +static void check_held_reset(bool value, HeldTime &action_time) { + if(value) { + if(!action_time.started) { + action_time.start_time = std::chrono::high_resolution_clock::now(); + action_time.started = true; + } + } + else + action_time.started = false; +} + +static float check_held_diff(std::chrono::time_point &curr_time, HeldTime &action_time) { + if(!action_time.started) + return 0.0; + const std::chrono::duration diff = curr_time - action_time.start_time; + return diff.count(); +} + +static void FPSArrayInsertElement(FPSArray *array, double frame_time) { + if(array->index < 0) + array->index = 0; + double rate = 0.0; + if(frame_time != 0.0) + rate = 1.0 / frame_time; + array->data[array->index % FPS_WINDOW_SIZE] = rate; + array->index++; + if(array->index == (2 * FPS_WINDOW_SIZE)) + array->index = FPS_WINDOW_SIZE; +} + +static double FPSArrayGetAverage(FPSArray *array) { + int available_fps = FPS_WINDOW_SIZE; + if(array->index < available_fps) + available_fps = array->index; + double fps_sum = 0; + for(int i = 0; i < available_fps; i++) + fps_sum += array->data[i]; + return fps_sum / available_fps; +} + WindowScreen::WindowScreen(ScreenType stype, CaptureStatus* capture_status, DisplayData* display_data, AudioData* audio_data, std::mutex* events_access) { this->m_stype = stype; insert_basic_crops(this->possible_crops, this->m_stype); @@ -33,6 +75,13 @@ WindowScreen::WindowScreen(ScreenType stype, CaptureStatus* capture_status, Disp this->resolution_menu = new ResolutionMenu(this->font_load_success, this->text_font); this->fileconfig_menu = new FileConfigMenu(this->font_load_success, this->text_font); this->extra_menu = new ExtraSettingsMenu(this->font_load_success, this->text_font); + this->status_menu = new StatusMenu(this->font_load_success, this->text_font); + this->in_fps.data = new double[FPS_WINDOW_SIZE]; + this->draw_fps.data = new double[FPS_WINDOW_SIZE]; + this->poll_fps.data = new double[FPS_WINDOW_SIZE]; + this->in_fps.index = 0; + this->draw_fps.index = 0; + this->poll_fps.index = 0; this->in_tex.create(IN_VIDEO_WIDTH, IN_VIDEO_HEIGHT); this->m_in_rect_top.setTexture(&this->in_tex); this->m_in_rect_bot.setTexture(&this->in_tex); @@ -40,6 +89,8 @@ WindowScreen::WindowScreen(ScreenType stype, CaptureStatus* capture_status, Disp this->audio_data = audio_data; this->last_window_creation_time = std::chrono::high_resolution_clock::now(); this->last_mouse_action_time = std::chrono::high_resolution_clock::now(); + this->last_draw_time = std::chrono::high_resolution_clock::now(); + this->last_poll_time = std::chrono::high_resolution_clock::now(); this->touch_right_click_action.started = false; this->reset_held_times(); WindowScreen::reset_operations(future_operations); @@ -72,6 +123,10 @@ WindowScreen::~WindowScreen() { delete this->resolution_menu; delete this->fileconfig_menu; delete this->extra_menu; + delete this->status_menu; + delete []this->in_fps.data; + delete []this->draw_fps.data; + delete []this->poll_fps.data; } void WindowScreen::build() { @@ -517,6 +572,12 @@ void WindowScreen::setup_extra_menu(bool reset_data) { } void WindowScreen::setup_status_menu(bool reset_data) { + if(this->curr_menu != STATUS_MENU_TYPE) { + this->curr_menu = STATUS_MENU_TYPE; + if(reset_data) + this->status_menu->reset_data(); + this->status_menu->insert_data(); + } } void WindowScreen::setup_licenses_menu(bool reset_data) { @@ -1250,6 +1311,22 @@ void WindowScreen::poll() { continue; } break; + case STATUS_MENU_TYPE: + if(this->status_menu->poll(event_data)) { + switch(this->status_menu->selected_index) { + case STATUS_MENU_BACK: + this->setup_main_menu(); + done = true; + break; + case STATUS_MENU_NO_ACTION: + break; + default: + break; + } + this->status_menu->reset_output_option(); + continue; + } + break; default: break; } @@ -1304,6 +1381,7 @@ void WindowScreen::after_thread_join() { } void WindowScreen::draw(double frame_time, VideoOutputData* out_buf) { + FPSArrayInsertElement(&in_fps, frame_time); if(!this->done_display) return; @@ -1320,7 +1398,15 @@ void WindowScreen::draw(double frame_time, VideoOutputData* out_buf) { this->m_info.is_fullscreen = false; this->loaded_menu = this->curr_menu; loaded_operations = future_operations; + if(this->loaded_operations.call_create) { + this->last_draw_time = std::chrono::high_resolution_clock::now(); + this->last_poll_time = std::chrono::high_resolution_clock::now(); + } if(this->m_win.isOpen() || this->loaded_operations.call_create) { + auto curr_time = std::chrono::high_resolution_clock::now(); + const std::chrono::duration diff = curr_time - this->last_draw_time; + FPSArrayInsertElement(&draw_fps, diff.count()); + this->last_draw_time = curr_time; WindowScreen::reset_operations(future_operations); if(out_buf != NULL) memcpy(this->saved_buf, out_buf, sizeof(VideoOutputData)); @@ -1383,6 +1469,9 @@ void WindowScreen::draw(double frame_time, VideoOutputData* out_buf) { case EXTRA_MENU_TYPE: this->extra_menu->prepare(this->loaded_info.menu_scaling_factor, view_size_x, view_size_y); break; + case STATUS_MENU_TYPE: + this->status_menu->prepare(this->loaded_info.menu_scaling_factor, view_size_x, view_size_y, FPSArrayGetAverage(&in_fps), FPSArrayGetAverage(&poll_fps), FPSArrayGetAverage(&draw_fps)); + break; default: break; } @@ -1511,25 +1600,6 @@ void WindowScreen::print_notification_float(std::string base_text, float value, this->print_notification(base_text + ": " + get_float_str_decimals(value, decimals)); } -static void check_held_reset(bool value, HeldTime &action_time) { - if(value) { - if(!action_time.started) { - action_time.start_time = std::chrono::high_resolution_clock::now(); - action_time.started = true; - } - } - else { - action_time.started = false; - } -} - -static float check_held_diff(std::chrono::time_point &curr_time, HeldTime &action_time) { - if(!action_time.started) - return 0.0; - const std::chrono::duration diff = curr_time - action_time.start_time; - return diff.count(); -} - bool WindowScreen::query_reset_request() { auto curr_time = std::chrono::high_resolution_clock::now(); if(check_held_diff(curr_time, this->right_click_action) > this->bad_resolution_timeout) @@ -1555,6 +1625,10 @@ void WindowScreen::reset_held_times() { void WindowScreen::poll_window() { if(this->m_win.isOpen()) { + auto curr_time = std::chrono::high_resolution_clock::now(); + const std::chrono::duration diff = curr_time - this->last_poll_time; + FPSArrayInsertElement(&poll_fps, diff.count()); + this->last_poll_time = curr_time; sf::Event event; this->events_access->lock(); while(this->m_win.pollEvent(event)) { @@ -1791,6 +1865,9 @@ void WindowScreen::display_data_to_window(bool actually_draw, bool is_debug) { case EXTRA_MENU_TYPE: this->extra_menu->draw(this->loaded_info.menu_scaling_factor, this->m_win); break; + case STATUS_MENU_TYPE: + this->status_menu->draw(this->loaded_info.menu_scaling_factor, this->m_win); + break; default: break; } diff --git a/source/cc3dsfs.cpp b/source/cc3dsfs.cpp index 3d399fb..f34bab2 100755 --- a/source/cc3dsfs.cpp +++ b/source/cc3dsfs.cpp @@ -25,8 +25,6 @@ #include "audio.hpp" #include "conversions.hpp" -#define FPS_WINDOW_SIZE 64 - // Threshold to keep the audio latency limited in "amount of frames". #define AUDIO_LATENCY_LIMIT 4 #define NUM_CONCURRENT_AUDIO_BUFFERS ((AUDIO_LATENCY_LIMIT * 2) + 1) @@ -226,7 +224,7 @@ static void soundCall(AudioData *audio_data, CaptureData* capture_data) { static void mainVideoOutputCall(AudioData* audio_data, CaptureData* capture_data) { VideoOutputData *out_buf; - double *curr_fps_array; + double last_frame_time = 0.0; int num_elements_fps_array = 0; int curr_out, prev_out = NUM_CONCURRENT_DATA_BUFFERS - 1; FrontendData frontend_data; @@ -234,13 +232,11 @@ static void mainVideoOutputCall(AudioData* audio_data, CaptureData* capture_data frontend_data.reload = true; bool skip_io = false; int num_allowed_blanks = MAX_ALLOWED_BLANKS; - double last_frame_time = 0; std::mutex events_access; OutTextData out_text_data; out_text_data.consumed = true; out_buf = new VideoOutputData; - curr_fps_array = new double[FPS_WINDOW_SIZE]; memset(out_buf, 0, sizeof(VideoOutputData)); WindowScreen top_screen(ScreenType::TOP, &capture_data->status, &frontend_data.display_data, audio_data, &events_access); @@ -269,12 +265,14 @@ static void mainVideoOutputCall(AudioData* audio_data, CaptureData* capture_data while(capture_data->status.running) { + VideoOutputData *chosen_buf = out_buf; + bool blank_out = false; 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)) { - double frame_time = capture_data->time_in_buf[curr_out]; + last_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); num_allowed_blanks = MAX_ALLOWED_BLANKS; @@ -287,43 +285,22 @@ static void mainVideoOutputCall(AudioData* audio_data, CaptureData* capture_data memset(out_buf, 0, sizeof(VideoOutputData)); } } - - update_output(&frontend_data, frame_time, out_buf); - last_frame_time = frame_time; - - curr_fps_array[num_elements_fps_array % FPS_WINDOW_SIZE] = 1.0 / frame_time; - num_elements_fps_array++; - if(num_elements_fps_array >= (2 * FPS_WINDOW_SIZE)) - num_elements_fps_array -= FPS_WINDOW_SIZE; } - else { - VideoOutputData *chosen_buf = out_buf; - if(capture_data->status.cooldown_curr_in) { - last_frame_time = 0; - chosen_buf = NULL; - } - update_output(&frontend_data, last_frame_time, chosen_buf); - } - + else if(capture_data->status.cooldown_curr_in) + blank_out = true; prev_out = curr_out; } else { - curr_fps_array[num_elements_fps_array % FPS_WINDOW_SIZE] = 0; - num_elements_fps_array++; - if(num_elements_fps_array >= (2 * FPS_WINDOW_SIZE)) - num_elements_fps_array -= FPS_WINDOW_SIZE; default_sleep(); + blank_out = true; } - - int available_fps = FPS_WINDOW_SIZE; - if(num_elements_fps_array < available_fps) - available_fps = num_elements_fps_array; - double fps_sum = 0; - for(int i = 0; i < available_fps; i++) - fps_sum += curr_fps_array[i]; - if(!capture_data->status.connected) - update_output(&frontend_data); + if(blank_out) { + last_frame_time = 0.0; + chosen_buf = NULL; + } + + update_output(&frontend_data, last_frame_time, chosen_buf); int load_index = 0; int save_index = 0; @@ -388,7 +365,6 @@ static void mainVideoOutputCall(AudioData* audio_data, CaptureData* capture_data } delete out_buf; - delete []curr_fps_array; } int main(int argc, char **argv) { diff --git a/source/utils.cpp b/source/utils.cpp index 5faa391..5deed0e 100755 --- a/source/utils.cpp +++ b/source/utils.cpp @@ -42,8 +42,11 @@ std::string get_float_str_decimals(float value, int decimals) { for(int i = 0; i < decimals; i++) return_text += "0"; } - else - return_text += "." + std::to_string(dec_part); + else { + return_text += "."; + for(int i = 0; i < decimals; i++) + return_text += std::to_string((dec_part % ((int)pow(10, decimals - i))) / ((int)pow(10, decimals - i - 1))); + } } return return_text;