From 934da36062e4986bfdb0325855ebe88ed002a883 Mon Sep 17 00:00:00 2001 From: Lorenzooone Date: Fri, 3 May 2024 21:51:56 +0200 Subject: [PATCH] Add PAR correction setting --- README.md | 2 ++ include/frontend.hpp | 9 +++-- source/WindowScreen.cpp | 78 +++++++++++++++++++++++++++++------------ source/frontend.cpp | 41 ++++++++++++++++++++++ 4 files changed, 106 insertions(+), 24 deletions(-) diff --git a/README.md b/README.md index 01947db..df4220f 100644 --- a/README.md +++ b/README.md @@ -80,6 +80,8 @@ On MacOS, you may also be prompted to install the Apple Command Line Developer T - __Z key__: Decreases the Menu Scaling multiplier by 0.1. 0.3 is the minimum. - __X key__: Increases the Menu Scaling multiplier by 0.1. 5.0 is the maximum. - __R key__: Toggles extra padding on/off. It can be used to account for windows with rounded corners. +- __2 key__: Changes the Pixel Aspect Ratio (PAR) for the top screen. +- __3 key__: Changes the Pixel Aspect Ratio (PAR) for the bottom screen. - __M key__: Toggles mute on/off. - __, key__: Decrements the volume by 5 units. 0 is the minimum. - __. key__: Increments the volume by 5 units. 100 is the maximum. diff --git a/include/frontend.hpp b/include/frontend.hpp index e213fe7..64e716b 100755 --- a/include/frontend.hpp +++ b/include/frontend.hpp @@ -15,6 +15,7 @@ #include "ConnectionMenu.hpp" enum Crop { DEFAULT_3DS, SPECIAL_DS, SCALED_DS, NATIVE_DS, SCALED_GBA, NATIVE_GBA, SCALED_GB, NATIVE_GB, SCALED_SNES, NATIVE_SNES, NATIVE_NES, CROP_END }; +enum ParCorrection { PAR_NORMAL, PAR_SNES_HORIZONTAL, PAR_SNES_VERTICAL, PAR_END }; enum BottomRelativePosition { UNDER_TOP, LEFT_TOP, ABOVE_TOP, RIGHT_TOP, BOT_REL_POS_END }; enum OffsetAlgorithm { NO_DISTANCE, HALF_DISTANCE, MAX_DISTANCE, OFF_ALGO_END }; enum CurrMenuType { DEFAULT_MENU_TYPE, CONNECT_MENU_TYPE }; @@ -35,6 +36,8 @@ struct ScreenInfo { double bfi_divider; double menu_scaling_factor; bool rounded_corners_fix; + ParCorrection top_par; + ParCorrection bot_par; }; struct DisplayData { @@ -158,8 +161,8 @@ private: void window_render_call(); int apply_offset_algo(int offset_contribute, OffsetAlgorithm chosen_algo); void set_position_screens(sf::Vector2f &curr_top_screen_size, sf::Vector2f &curr_bot_screen_size, int offset_x, int offset_y, int max_x, int max_y, bool do_work = true); - int prepare_screen_ratio(sf::Vector2f &screen_size, int own_rotation, int width_limit, int height_limit, int other_rotation); - void calc_scaling_resize_screens(sf::Vector2f &own_screen_size, sf::Vector2f &other_screen_size, int &own_scaling, int &other_scaling, int own_rotation, int other_rotation, bool increase, bool mantain, bool set_to_zero); + int prepare_screen_ratio(sf::Vector2f &screen_size, int own_rotation, int width_limit, int height_limit, int other_rotation, ParCorrection own_par); + void calc_scaling_resize_screens(sf::Vector2f &own_screen_size, sf::Vector2f &other_screen_size, int &own_scaling, int &other_scaling, int own_rotation, int other_rotation, bool increase, bool mantain, bool set_to_zero, ParCorrection own_par, ParCorrection other_par); void prepare_size_ratios(bool top_increase, bool bot_increase); int get_fullscreen_offset_x(int top_width, int top_height, int bot_width, int bot_height); int get_fullscreen_offset_y(int top_width, int top_height, int bot_width, int bot_height); @@ -184,6 +187,8 @@ struct FrontendData { bool reload; }; +void get_par_size(float &width, float &height, float multiplier_factor, ParCorrection &correction_factor); +void get_par_size(int &width, int &height, float multiplier_factor, ParCorrection &correction_factor); void default_sleep(); void update_output(FrontendData* frontend_data, double frame_time = 0, VideoOutputData *out_buf = NULL); void screen_display_thread(WindowScreen *screen); diff --git a/source/WindowScreen.cpp b/source/WindowScreen.cpp index f1ca58f..c763456 100755 --- a/source/WindowScreen.cpp +++ b/source/WindowScreen.cpp @@ -21,6 +21,8 @@ static int bot_screen_crop_x[] = {0, 0, 0, (BOT_WIDTH_3DS - WIDTH_DS) / 2, 0, 0, static int bot_screen_crop_y[] = {0, 0, 0, HEIGHT_3DS - HEIGHT_DS, 0, 0, 0, 0, 0, 0, 0}; static std::string crop_names[] = {"3DS", "16:10", "Scaled DS", "Native DS", "Scaled GBA", "Native GBA", "Scaled VC GB", "VC GB", "Scaled SNES", "VC SNES", "VC NES"}; +static std::string par_width_names[] = {"1:1", "SNES Horizontal", "SNES Vertical"}; + WindowScreen::WindowScreen(WindowScreen::ScreenType stype, CaptureStatus* capture_status, DisplayData* display_data, AudioData* audio_data, std::mutex* events_access) { this->m_stype = stype; this->events_access = events_access; @@ -338,6 +340,26 @@ bool WindowScreen::main_poll(SFEvent &event_data) { break; + case '2': + if(this->m_stype == WindowScreen::ScreenType::BOTTOM) + break; + this->m_info.top_par = static_cast((this->m_info.top_par + 1) % (ParCorrection::PAR_END)); + this->prepare_size_ratios(false, false); + this->future_operations.call_screen_settings_update = true; + this->print_notification("Top PAR: " + par_width_names[this->m_info.top_par]); + + break; + + case '3': + if(this->m_stype == WindowScreen::ScreenType::TOP) + break; + this->m_info.bot_par = static_cast((this->m_info.bot_par + 1) % (ParCorrection::PAR_END)); + this->prepare_size_ratios(false, false); + this->future_operations.call_screen_settings_update = true; + this->print_notification("Bottom PAR: " + par_width_names[this->m_info.bot_par]); + + break; + case 'm': audio_data->change_audio_mute(); break; @@ -917,12 +939,14 @@ void WindowScreen::set_position_screens(sf::Vector2f &curr_top_screen_size, sf:: this->m_height = bot_end_y; } -int WindowScreen::prepare_screen_ratio(sf::Vector2f &screen_size, int own_rotation, int width_limit, int height_limit, int other_rotation) { - int own_width = screen_size.x; - int own_height = screen_size.y; - if((own_width <= 0) || (own_height <= 0)) +int WindowScreen::prepare_screen_ratio(sf::Vector2f &screen_size, int own_rotation, int width_limit, int height_limit, int other_rotation, ParCorrection own_par) { + float own_width = screen_size.x; + float own_height = screen_size.y; + if((own_width < 1.0) || (own_height < 1.0)) return 0; + get_par_size(own_width, own_height, 1, own_par); + if((own_rotation / 10) % 2) std::swap(own_width, own_height); if((other_rotation / 10) % 2) @@ -949,8 +973,11 @@ int WindowScreen::prepare_screen_ratio(sf::Vector2f &screen_size, int own_rotati return height_ratio; } -void WindowScreen::calc_scaling_resize_screens(sf::Vector2f &own_screen_size, sf::Vector2f &other_screen_size, int &own_scaling, int &other_scaling, int own_rotation, int other_rotation, bool increase, bool mantain, bool set_to_zero) { - int chosen_ratio = prepare_screen_ratio(own_screen_size, own_rotation, other_screen_size.x, other_screen_size.y, other_rotation); +void WindowScreen::calc_scaling_resize_screens(sf::Vector2f &own_screen_size, sf::Vector2f &other_screen_size, int &own_scaling, int &other_scaling, int own_rotation, int other_rotation, bool increase, bool mantain, bool set_to_zero, ParCorrection own_par, ParCorrection other_par) { + int min_other_width = other_screen_size.x; + int min_other_height = other_screen_size.y; + get_par_size(min_other_width, min_other_height, 1, other_par); + int chosen_ratio = prepare_screen_ratio(own_screen_size, own_rotation, min_other_width, min_other_height, other_rotation, own_par); if(increase && (chosen_ratio > own_scaling) && (own_scaling > 0)) own_scaling += 1; else if(mantain && (chosen_ratio >= own_scaling) && (own_scaling > 0)) @@ -959,16 +986,18 @@ void WindowScreen::calc_scaling_resize_screens(sf::Vector2f &own_screen_size, sf own_scaling = chosen_ratio; if(set_to_zero) own_scaling = 0; - int own_height = own_scaling * own_screen_size.y; - int own_width = own_scaling * own_screen_size.x; - other_scaling = prepare_screen_ratio(other_screen_size, other_rotation, own_width, own_height, own_rotation); + int own_height = own_screen_size.y; + int own_width = own_screen_size.x; + get_par_size(own_width, own_height, own_scaling, own_par); + other_scaling = prepare_screen_ratio(other_screen_size, other_rotation, own_width, own_height, own_rotation, other_par); if(this->m_stype == WindowScreen::ScreenType::JOINT) { // Due to size differences, it may be possible that // the chosen screen might be able to increase its // scaling even more without compromising the other one... - int other_height = other_scaling * other_screen_size.y; - int other_width = other_scaling * other_screen_size.x; - own_scaling = prepare_screen_ratio(own_screen_size, own_rotation, other_width, other_height, other_rotation); + int other_height = other_screen_size.y; + int other_width = other_screen_size.x; + get_par_size(other_width, other_height, other_scaling, other_par); + own_scaling = prepare_screen_ratio(own_screen_size, own_rotation, other_width, other_height, other_rotation, own_par); } } @@ -994,9 +1023,9 @@ void WindowScreen::prepare_size_ratios(bool top_increase, bool bot_increase) { } bool prioritize_top = (!bot_increase) && (top_increase || (this->m_info.bottom_pos == UNDER_TOP) || (this->m_info.bottom_pos == RIGHT_TOP)); if(prioritize_top) - calc_scaling_resize_screens(top_screen_size, bot_screen_size, this->m_info.top_scaling, this->m_info.bot_scaling, this->m_info.top_rotation, this->m_info.bot_rotation, top_increase, try_mantain_ratio, this->m_stype == WindowScreen::ScreenType::BOTTOM); + calc_scaling_resize_screens(top_screen_size, bot_screen_size, this->m_info.top_scaling, this->m_info.bot_scaling, this->m_info.top_rotation, this->m_info.bot_rotation, top_increase, try_mantain_ratio, this->m_stype == WindowScreen::ScreenType::BOTTOM, this->m_info.top_par, this->m_info.bot_par); else - calc_scaling_resize_screens(bot_screen_size, top_screen_size, this->m_info.bot_scaling, this->m_info.top_scaling, this->m_info.bot_rotation, this->m_info.top_rotation, bot_increase, try_mantain_ratio, this->m_stype == WindowScreen::ScreenType::TOP); + calc_scaling_resize_screens(bot_screen_size, top_screen_size, this->m_info.bot_scaling, this->m_info.top_scaling, this->m_info.bot_rotation, this->m_info.top_rotation, bot_increase, try_mantain_ratio, this->m_stype == WindowScreen::ScreenType::TOP, this->m_info.bot_par, this->m_info.top_par); } int WindowScreen::get_fullscreen_offset_x(int top_width, int top_height, int bot_width, int bot_height) { @@ -1050,25 +1079,30 @@ int WindowScreen::get_fullscreen_offset_y(int top_width, int top_height, int bot void WindowScreen::resize_window_and_out_rects(bool do_work) { sf::Vector2f top_screen_size = getShownScreenSize(true, this->loaded_info.crop_kind); sf::Vector2f bot_screen_size = getShownScreenSize(false, this->loaded_info.crop_kind); - int top_height = this->loaded_info.scaling * top_screen_size.y; - int top_width = this->loaded_info.scaling * top_screen_size.x; - int bot_height = this->loaded_info.scaling * bot_screen_size.y; - int bot_width = this->loaded_info.scaling * bot_screen_size.x; + int top_width = top_screen_size.x; + int top_height = top_screen_size.y; + float top_scaling = this->loaded_info.scaling; + int bot_width = bot_screen_size.x; + int bot_height = bot_screen_size.y; + float bot_scaling = this->loaded_info.scaling; int offset_x = 0; int offset_y = 0; int max_x = 0; int max_y = 0; + if(this->loaded_info.is_fullscreen) { + top_scaling = this->loaded_info.top_scaling; + bot_scaling = this->loaded_info.bot_scaling; + } + get_par_size(top_width, top_height, top_scaling, this->loaded_info.top_par); + get_par_size(bot_width, bot_height, bot_scaling, this->loaded_info.bot_par); + if((!this->loaded_info.is_fullscreen) && this->loaded_info.rounded_corners_fix) { offset_y = TOP_ROUNDED_PADDING; offset_x = LEFT_ROUNDED_PADDING; } if(this->loaded_info.is_fullscreen) { - top_height = this->loaded_info.top_scaling * top_screen_size.y; - top_width = this->loaded_info.top_scaling * top_screen_size.x; - bot_height = this->loaded_info.bot_scaling * bot_screen_size.y; - bot_width = this->loaded_info.bot_scaling * bot_screen_size.x; offset_x = get_fullscreen_offset_x(top_width, top_height, bot_width, bot_height); offset_y = get_fullscreen_offset_y(top_width, top_height, bot_width, bot_height); max_x = curr_desk_mode.width; diff --git a/source/frontend.cpp b/source/frontend.cpp index 7709d8d..69b41f1 100755 --- a/source/frontend.cpp +++ b/source/frontend.cpp @@ -1,6 +1,10 @@ #include "frontend.hpp" #include +static float par_width_multiplier[] = {1.0, 8.0, 8.0}; +static float par_width_divisor[] = {1.0, 7.0, 7.0}; +static bool par_width_main[] = {true, true, false}; + void reset_screen_info(ScreenInfo &info) { info.is_blurred = false; info.crop_kind = DEFAULT_3DS; @@ -26,6 +30,8 @@ void reset_screen_info(ScreenInfo &info) { info.bfi_divider = 2.0; info.menu_scaling_factor = 1.0; info.rounded_corners_fix = false; + info.top_par = ParCorrection::PAR_NORMAL; + info.bot_par = ParCorrection::PAR_NORMAL; } bool load_screen_info(std::string key, std::string value, std::string base, ScreenInfo &info) { @@ -119,6 +125,14 @@ bool load_screen_info(std::string key, std::string value, std::string base, Scre info.rounded_corners_fix = std::stoi(value); return true; } + if(key == (base + "top_par")) { + info.top_par = static_cast(std::stoi(value) % ParCorrection::PAR_END); + return true; + } + if(key == (base + "bot_par")) { + info.bot_par = static_cast(std::stoi(value) % ParCorrection::PAR_END); + return true; + } return false; } @@ -143,6 +157,8 @@ std::string save_screen_info(std::string base, const ScreenInfo &info) { out += base + "bfi_divider=" + std::to_string(info.bfi_divider) + "\n"; out += base + "menu_scaling_factor=" + std::to_string(info.menu_scaling_factor) + "\n"; out += base + "rounded_corners_fix=" + std::to_string(info.rounded_corners_fix) + "\n"; + out += base + "top_par=" + std::to_string(info.top_par) + "\n"; + out += base + "bot_par=" + std::to_string(info.bot_par) + "\n"; return out; } @@ -158,6 +174,31 @@ void joystick_axis_poll(std::queue &events_queue) { } } +void get_par_size(int &width, int &height, float multiplier_factor, ParCorrection &correction_factor) { + if(correction_factor >= ParCorrection::PAR_END) + correction_factor = ParCorrection::PAR_NORMAL; + int par_corr_index = correction_factor - ParCorrection::PAR_NORMAL; + width *= multiplier_factor; + height *= multiplier_factor; + if(par_width_main[par_corr_index]) + width = (width * par_width_multiplier[par_corr_index]) / par_width_divisor[par_corr_index]; + else + height = (height * par_width_divisor[par_corr_index]) / par_width_multiplier[par_corr_index]; +} + +void get_par_size(float &width, float &height, float multiplier_factor, ParCorrection &correction_factor) { + if(correction_factor >= ParCorrection::PAR_END) + correction_factor = ParCorrection::PAR_NORMAL; + int par_corr_index = correction_factor - ParCorrection::PAR_NORMAL; + width *= multiplier_factor; + height *= multiplier_factor; + if(par_width_main[par_corr_index]) { + width = (width * par_width_multiplier[par_corr_index]) / par_width_divisor[par_corr_index]; + } + else + height = (height * par_width_divisor[par_corr_index]) / par_width_multiplier[par_corr_index]; +} + JoystickDirection get_joystick_direction(uint32_t joystickId, sf::Joystick::Axis axis, float position) { bool is_horizontal = false; if((axis == sf::Joystick::Z) || (axis == sf::Joystick::R))