From c570f68e6d871eb777995fde609f8376ea570633 Mon Sep 17 00:00:00 2001 From: Lorenzooone Date: Sun, 8 Feb 2026 21:43:23 +0100 Subject: [PATCH] Fix issue with bad frames changing the frame type of previous frames --- include/frontend.hpp | 4 ++-- source/WindowScreen.cpp | 22 ++++++++++++---------- source/cc3dsfs.cpp | 5 ++++- source/frontend.cpp | 14 +++++++------- 4 files changed, 25 insertions(+), 20 deletions(-) diff --git a/include/frontend.hpp b/include/frontend.hpp index 65b23c8..2dd9056 100755 --- a/include/frontend.hpp +++ b/include/frontend.hpp @@ -85,7 +85,7 @@ public: void display_thread(); void end(); void after_thread_join(); - void draw(double frame_time, VideoOutputData* out_buf, InputVideoDataType video_data_type); + void draw(double frame_time, VideoOutputData* out_buf, InputVideoDataType video_data_type, bool update_rendered_buffer); void setup_connection_menu(std::vector *devices_list, bool reset_data = true); void setup_reconnection_menu(bool reset_data = true); int check_connection_menu_result(); @@ -473,7 +473,7 @@ void get_par_size(float &width, float &height, float multiplier_factor, const PA SecondScreen3DRelativePosition get_second_screen_pos(ScreenInfo* info, ScreenType stype); bool should_do_output(FrontendData* frontend_data); -void update_output(FrontendData* frontend_data, double frame_time = 0.0, VideoOutputData *out_buf = NULL, InputVideoDataType video_data_type = VIDEO_DATA_RGB); +void update_output(FrontendData* frontend_data, double frame_time = 0.0, VideoOutputData *out_buf = NULL, InputVideoDataType video_data_type = VIDEO_DATA_RGB, bool update_rendered_buffer = true); void update_connected_3ds_ds(FrontendData* frontend_data, const CaptureDevice &old_cc_device, const CaptureDevice &new_cc_device); void update_connected_specific_settings(FrontendData* frontend_data, const CaptureDevice &cc_device); diff --git a/source/WindowScreen.cpp b/source/WindowScreen.cpp index 6823a44..0b9d2a7 100755 --- a/source/WindowScreen.cpp +++ b/source/WindowScreen.cpp @@ -284,7 +284,7 @@ void WindowScreen::after_thread_join() { } } -void WindowScreen::draw(double frame_time, VideoOutputData* out_buf, InputVideoDataType video_data_type) { +void WindowScreen::draw(double frame_time, VideoOutputData* out_buf, InputVideoDataType video_data_type, bool update_rendered_buffer) { FPSArrayInsertElement(&this->in_fps, frame_time); if(!this->done_display) return; @@ -323,13 +323,17 @@ void WindowScreen::draw(double frame_time, VideoOutputData* out_buf, InputVideoD FPSArrayInsertElement(&this->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)); - else { - memset(this->saved_buf, 0, sizeof(VideoOutputData)); - this->was_last_frame_null = true; + if(update_rendered_buffer) { + if(out_buf != NULL) { + memcpy(this->saved_buf, out_buf, sizeof(VideoOutputData)); + this->was_last_frame_null = false; + } + else { + memset(this->saved_buf, 0, sizeof(VideoOutputData)); + this->was_last_frame_null = true; + } + this->curr_video_data_type = video_data_type; } - this->curr_video_data_type = video_data_type; loaded_info = m_info; m_info.initial_pos_x = DEFAULT_NO_POS_WINDOW_VALUE; m_info.initial_pos_y = DEFAULT_NO_POS_WINDOW_VALUE; @@ -892,10 +896,8 @@ int WindowScreen::_choose_base_input_shader(bool is_top) { } int WindowScreen::_choose_shader(PossibleShaderTypes shader_type, bool is_top) { - if(this->was_last_frame_null) { - this->was_last_frame_null = false; + if(this->was_last_frame_null) return NO_EFFECT_FRAGMENT_SHADER; - } switch(shader_type) { case BASE_FINAL_OUTPUT_SHADER_TYPE: return NO_EFFECT_FRAGMENT_SHADER; diff --git a/source/cc3dsfs.cpp b/source/cc3dsfs.cpp index bba6cd4..55483f1 100755 --- a/source/cc3dsfs.cpp +++ b/source/cc3dsfs.cpp @@ -715,6 +715,7 @@ static int mainVideoOutputCall(AudioData* audio_data, CaptureData* capture_data, VideoOutputData *chosen_buf = out_buf; InputVideoDataType video_data_type = VIDEO_DATA_RGB; bool blank_out = false; + bool update_rendered_buffer = true; bool is_connected = capture_data->status.connected; if(is_connected != last_connected) { update_connected_specific_settings(&frontend_data, capture_data->status.device); @@ -756,6 +757,8 @@ static int mainVideoOutputCall(AudioData* audio_data, CaptureData* capture_data, if(capture_data->status.cooldown_curr_in || (!capture_data->status.connected)) blank_out = true; no_data_consecutive++; + if(!blank_out) + update_rendered_buffer = false; } last_connection_time = std::chrono::high_resolution_clock::now(); } @@ -775,7 +778,7 @@ static int mainVideoOutputCall(AudioData* audio_data, CaptureData* capture_data, *can_do_output = should_do_output(&frontend_data); if(*can_do_output) - update_output(&frontend_data, last_frame_time, chosen_buf, video_data_type); + update_output(&frontend_data, last_frame_time, chosen_buf, video_data_type, update_rendered_buffer); if(!frontend_data.shared_data.input_data.fast_poll) poll_all_windows(&frontend_data, poll_everything, polled); diff --git a/source/frontend.cpp b/source/frontend.cpp index 321b505..76f0b77 100755 --- a/source/frontend.cpp +++ b/source/frontend.cpp @@ -1079,7 +1079,7 @@ bool should_do_output(FrontendData* frontend_data) { #endif } -void update_output(FrontendData* frontend_data, double frame_time, VideoOutputData *out_buf, InputVideoDataType video_data_type) { +void update_output(FrontendData* frontend_data, double frame_time, VideoOutputData *out_buf, InputVideoDataType video_data_type, bool update_rendered_buffer) { if(frontend_data->reload) { frontend_data->top_screen->reload(); frontend_data->bot_screen->reload(); @@ -1088,17 +1088,17 @@ void update_output(FrontendData* frontend_data, double frame_time, VideoOutputDa } // Make sure the window is closed before showing split/non-split if(!frontend_data->joint_screen->m_info.window_enabled) - frontend_data->joint_screen->draw(frame_time, out_buf, video_data_type); + frontend_data->joint_screen->draw(frame_time, out_buf, video_data_type, update_rendered_buffer); if(!frontend_data->top_screen->m_info.window_enabled) - frontend_data->top_screen->draw(frame_time, out_buf, video_data_type); + frontend_data->top_screen->draw(frame_time, out_buf, video_data_type, update_rendered_buffer); if(!frontend_data->bot_screen->m_info.window_enabled) - frontend_data->bot_screen->draw(frame_time, out_buf, video_data_type); + frontend_data->bot_screen->draw(frame_time, out_buf, video_data_type, update_rendered_buffer); if(frontend_data->joint_screen->m_info.window_enabled) - frontend_data->joint_screen->draw(frame_time, out_buf, video_data_type); + frontend_data->joint_screen->draw(frame_time, out_buf, video_data_type, update_rendered_buffer); if(frontend_data->top_screen->m_info.window_enabled) - frontend_data->top_screen->draw(frame_time, out_buf, video_data_type); + frontend_data->top_screen->draw(frame_time, out_buf, video_data_type, update_rendered_buffer); if(frontend_data->bot_screen->m_info.window_enabled) - frontend_data->bot_screen->draw(frame_time, out_buf, video_data_type); + frontend_data->bot_screen->draw(frame_time, out_buf, video_data_type, update_rendered_buffer); } static bool are_cc_device_screens_same(const CaptureDevice &old_cc_device, const CaptureDevice &new_cc_device) {