Add mode to force 50:50 ratio in fullscreen mode

This commit is contained in:
Lorenzooone 2025-03-02 17:22:57 +01:00
parent 829fbb7949
commit 065fecff6e
7 changed files with 140 additions and 17 deletions

View File

@ -17,6 +17,7 @@ enum ScalingRatioMenuOutAction{
SCALING_RATIO_MENU_NON_INT_SCALING_BOTTOM,
SCALING_RATIO_MENU_ALGO_INC,
SCALING_RATIO_MENU_ALGO_DEC,
SCALING_RATIO_MENU_FORCE_SAME_SCALING,
};
class ScalingRatioMenu : public OptionSelectionMenu {

View File

@ -44,6 +44,7 @@ struct ScreenInfo {
bool v_sync_enabled;
bool async;
int top_scaling, bot_scaling;
bool force_same_scaling;
float non_integer_top_scaling, non_integer_bot_scaling;
bool bfi;
int bfi_divider;

View File

@ -241,6 +241,7 @@ private:
void menu_scaling_change(bool positive);
void window_scaling_change(bool positive);
void rotation_change(int &value, bool right);
void force_same_scaling_change();
void ratio_change(bool top_priority, bool cycle = false);
void bfi_change();
void input_toggle_change(bool &target);
@ -271,6 +272,7 @@ private:
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);
float get_max_float_screen_multiplier(ResizingScreenData *own_screen, int width_limit, int height_limit, int other_rotation);
int prepare_screen_ratio(ResizingScreenData *own_screen, int width_limit, int height_limit, int other_rotation);
float get_ratio_compared_other_screen(ResizingScreenData *own_screen, ResizingScreenData* other_screen, float other_scaling);
bool can_non_integerly_scale();
void calc_scaling_resize_screens(ResizingScreenData *own_screen, ResizingScreenData* other_screen, bool increase, bool mantain, bool set_to_zero, bool cycle);
void rescale_nonint_subscreen(ResizingScreenData *main_screen_resize_data, ResizingScreenData *sub_screen_resize_data);
@ -278,6 +280,8 @@ private:
void non_int_scale_screens_with_main(ResizingScreenData *main_screen_resize_data, ResizingScreenData *sub_screen_resize_data, int sub_min_width, int sub_height_min);
void non_int_scale_screens_both(ResizingScreenData *main_screen_resize_data, ResizingScreenData *sub_screen_resize_data, int free_width, int free_height, float multiplier_main, int main_min_width, int main_height_min, int sub_min_width, int sub_height_min);
void non_integer_scale_screens(ResizingScreenData *top_screen_resize_data, ResizingScreenData *bot_screen_resize_data);
void merge_screens_data(ResizingScreenData* top_screen_resize_data, ResizingScreenData* bot_screen_resize_data, ResizingScreenData* merged_screen_resize_data, BottomRelativePosition bottom_pos);
bool prepare_screens_same_scaling_factor(ResizingScreenData* top_screen_resize_data, ResizingScreenData* bot_screen_resize_data);
void prepare_size_ratios(bool top_increase, bool bot_increase, bool cycle = false);
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);
@ -342,7 +346,9 @@ void override_set_data_to_screen_info(override_win_data &override_win, ScreenInf
void reset_screen_info(ScreenInfo &info);
bool load_screen_info(std::string key, std::string value, std::string base, ScreenInfo &info);
std::string save_screen_info(std::string base, const ScreenInfo &info);
const PARData* get_base_par();
void get_par_size(int &width, int &height, float multiplier_factor, const PARData *correction_factor);
void get_par_size(float &width, float &height, float multiplier_factor, const PARData *correction_factor);
float get_par_mult_factor(float width, float height, float max_width, float max_height, const PARData *correction_factor, bool is_rotated);
void update_output(FrontendData* frontend_data, double frame_time = 0.0, VideoOutputData *out_buf = NULL);
void update_connected_3ds_ds(FrontendData* frontend_data, const CaptureDevice &old_cc_device, const CaptureDevice &new_cc_device);

View File

@ -33,11 +33,17 @@ static const ScalingRatioMenuOptionInfo ratio_algo_option = {
.is_inc = true, .dec_str = "<", .inc_str = ">", .inc_out_action = SCALING_RATIO_MENU_ALGO_INC,
.out_action = SCALING_RATIO_MENU_ALGO_DEC};
static const ScalingRatioMenuOptionInfo force_same_scaling_option = {
.base_name = "Allow Different Scaling", .false_name = "Force 50/50 Ratio",
.is_inc = false, .dec_str = "", .inc_str = "", .inc_out_action = SCALING_RATIO_MENU_NO_ACTION,
.out_action = SCALING_RATIO_MENU_FORCE_SAME_SCALING};
static const ScalingRatioMenuOptionInfo* pollable_options[] = {
&ratio_option,
&top_fill_option,
&bot_fill_option,
&ratio_algo_option,
&force_same_scaling_option,
};
ScalingRatioMenu::ScalingRatioMenu(bool font_load_success, sf::Font &text_font) : OptionSelectionMenu(){
@ -144,6 +150,9 @@ void ScalingRatioMenu::prepare(float menu_scaling_factor, int view_size_x, int v
case SCALING_RATIO_MENU_ALGO_DEC:
this->labels[index]->setText(this->setTextOptionString(real_index, get_name_non_int_mode(info->non_integer_mode)));
break;
case SCALING_RATIO_MENU_FORCE_SAME_SCALING:
this->labels[index]->setText(this->setTextOptionBool(real_index, info->force_same_scaling));
break;
default:
break;
}

View File

@ -754,8 +754,12 @@ void WindowScreen::set_position_screens(sf::Vector2f &curr_top_screen_size, sf::
this->m_height = bot_end_y;
}
static bool is_size_valid(sf::Vector2f &size) {
return (size.x > 0.0) && (size.y > 0.0);
}
float WindowScreen::get_max_float_screen_multiplier(ResizingScreenData *own_screen, int width_limit, int height_limit, int other_rotation) {
if((own_screen->size.x < 1.0) || (own_screen->size.y < 1.0))
if(!is_size_valid(own_screen->size))
return 0;
if((other_rotation / 10) % 2)
@ -784,11 +788,15 @@ int WindowScreen::prepare_screen_ratio(ResizingScreenData *own_screen, int width
return this->get_max_float_screen_multiplier(own_screen, width_limit, height_limit, other_rotation);
}
void WindowScreen::calc_scaling_resize_screens(ResizingScreenData *own_screen, ResizingScreenData* other_screen, bool increase, bool mantain, bool set_to_zero, bool cycle) {
float WindowScreen::get_ratio_compared_other_screen(ResizingScreenData *own_screen, ResizingScreenData* other_screen, float other_scaling) {
int other_width = other_screen->size.x;
int other_height = other_screen->size.y;
get_par_size(other_width, other_height, 1, other_screen->par);
int chosen_ratio = prepare_screen_ratio(own_screen, other_width, other_height, other_screen->rotation);
get_par_size(other_width, other_height, other_scaling, other_screen->par);
return prepare_screen_ratio(own_screen, other_width, other_height, other_screen->rotation);
}
void WindowScreen::calc_scaling_resize_screens(ResizingScreenData *own_screen, ResizingScreenData* other_screen, bool increase, bool mantain, bool set_to_zero, bool cycle) {
int chosen_ratio = get_ratio_compared_other_screen(own_screen, other_screen, 1);
if(chosen_ratio <= 0) {
chosen_ratio = prepare_screen_ratio(own_screen, 0, 0, other_screen->rotation);
if(chosen_ratio <= 0)
@ -805,23 +813,17 @@ void WindowScreen::calc_scaling_resize_screens(ResizingScreenData *own_screen, R
(*own_screen->scaling) = chosen_ratio;
if(set_to_zero)
(*own_screen->scaling) = 0;
int own_height = own_screen->size.y;
int own_width = own_screen->size.x;
get_par_size(own_width, own_height, *own_screen->scaling, own_screen->par);
if((increase && ((old_scaling == (*own_screen->scaling)) || ((*other_screen->scaling) == 0)) || (mantain && ((*other_screen->scaling) == 0))) && ((*own_screen->scaling) > 0))
(*other_screen->scaling) = 0;
else
(*other_screen->scaling) = prepare_screen_ratio(other_screen, own_width, own_height, own_screen->rotation);
(*other_screen->scaling) = get_ratio_compared_other_screen(other_screen, own_screen, *own_screen->scaling);
if((*other_screen->scaling) < 0)
(*other_screen->scaling) = 0;
if((this->m_stype == ScreenType::JOINT) && (((*own_screen->scaling) > 0) || (((*other_screen->scaling) == 0) && ((*own_screen->scaling) == 0)))) {
// 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...
other_width = other_screen->size.x;
other_height = other_screen->size.y;
get_par_size(other_width, other_height, *other_screen->scaling, other_screen->par);
(*own_screen->scaling) = prepare_screen_ratio(own_screen, other_width, other_height, other_screen->rotation);
(*own_screen->scaling) = get_ratio_compared_other_screen(own_screen, other_screen, *other_screen->scaling);
if((*own_screen->scaling) < 0)
(*own_screen->scaling) = 0;
}
@ -945,6 +947,64 @@ void WindowScreen::non_integer_scale_screens(ResizingScreenData *top_screen_resi
}
}
void WindowScreen::merge_screens_data(ResizingScreenData* top_screen_resize_data, ResizingScreenData* bot_screen_resize_data, ResizingScreenData* merged_screen_resize_data, BottomRelativePosition bottom_pos) {
// Due to PARs and rotations, this is a bit annoying, but whatever...
float top_width = top_screen_resize_data->size.x;
float top_height = top_screen_resize_data->size.y;
get_par_size(top_width, top_height, 1.0, top_screen_resize_data->par);
float bot_width = bot_screen_resize_data->size.x;
float bot_height = bot_screen_resize_data->size.y;
get_par_size(bot_width, bot_height, 1.0, bot_screen_resize_data->par);
if((top_screen_resize_data->rotation / 10) % 2)
std::swap(top_width, top_height);
if((bot_screen_resize_data->rotation / 10) % 2)
std::swap(bot_width, bot_height);
float final_width = std::max(top_width, bot_width);
float final_height = std::max(top_height, bot_height);
switch(bottom_pos) {
case UNDER_TOP:
case ABOVE_TOP:
final_height = top_height + bot_height;
break;
case LEFT_TOP:
case RIGHT_TOP:
final_width = top_width + bot_width;
break;
default:
break;
}
merged_screen_resize_data->size.x = final_width;
merged_screen_resize_data->size.y = final_height;
if(top_screen_resize_data->use_non_int_scaling || bot_screen_resize_data->use_non_int_scaling)
merged_screen_resize_data->use_non_int_scaling = true;
else
merged_screen_resize_data->use_non_int_scaling = false;
merged_screen_resize_data->rotation = 0;
*merged_screen_resize_data->scaling = 1.0;
*merged_screen_resize_data->non_int_scaling = 1.0;
merged_screen_resize_data->par = get_base_par();
}
bool WindowScreen::prepare_screens_same_scaling_factor(ResizingScreenData* top_screen_resize_data, ResizingScreenData* bot_screen_resize_data) {
if((!is_size_valid(top_screen_resize_data->size)) || (!is_size_valid(bot_screen_resize_data->size)))
return false;
int scaling_merged = 1;
float non_int_scaling_merged = 1.0;
ResizingScreenData merged_screen_resize_data = {.size = {}, .scaling = &scaling_merged, .non_int_scaling = &non_int_scaling_merged, .use_non_int_scaling = false, .rotation = 0, .par = NULL};
merge_screens_data(top_screen_resize_data, bot_screen_resize_data, &merged_screen_resize_data, this->m_info.bottom_pos);
non_int_scaling_merged = this->get_max_float_screen_multiplier(&merged_screen_resize_data, 0, 0, 0);
scaling_merged = non_int_scaling_merged;
if(non_int_scaling_merged < 1.0)
return false;
*top_screen_resize_data->non_int_scaling = scaling_merged;
*bot_screen_resize_data->non_int_scaling = scaling_merged;
if(merged_screen_resize_data.use_non_int_scaling) {
*top_screen_resize_data->non_int_scaling = non_int_scaling_merged;
*bot_screen_resize_data->non_int_scaling = non_int_scaling_merged;
}
return true;
}
void WindowScreen::prepare_size_ratios(bool top_increase, bool bot_increase, bool cycle) {
if(!this->m_info.is_fullscreen)
return;
@ -972,12 +1032,19 @@ void WindowScreen::prepare_size_ratios(bool top_increase, bool bot_increase, boo
this->m_info.bot_par = 0;
ResizingScreenData top_screen_resize_data = {.size = top_screen_size, .scaling = &this->m_info.top_scaling, .non_int_scaling = &this->m_info.non_integer_top_scaling, .use_non_int_scaling = this->m_info.use_non_integer_scaling_top, .rotation = this->m_info.top_rotation, .par = this->possible_pars[this->m_info.top_par]};
ResizingScreenData bot_screen_resize_data = {.size = bot_screen_size, .scaling = &this->m_info.bot_scaling, .non_int_scaling = &this->m_info.non_integer_bot_scaling, .use_non_int_scaling = this->m_info.use_non_integer_scaling_bottom, .rotation = this->m_info.bot_rotation, .par = this->possible_pars[this->m_info.bot_par]};
if(prioritize_top)
calc_scaling_resize_screens(&top_screen_resize_data, &bot_screen_resize_data, top_increase, try_mantain_ratio, this->m_stype == ScreenType::BOTTOM, cycle);
else
calc_scaling_resize_screens(&bot_screen_resize_data, &top_screen_resize_data, bot_increase, try_mantain_ratio, this->m_stype == ScreenType::TOP, cycle);
this->non_integer_scale_screens(&top_screen_resize_data, &bot_screen_resize_data);
bool processed = false;
if(this->m_stype == ScreenType::JOINT && this->m_info.force_same_scaling)
processed = this->prepare_screens_same_scaling_factor(&top_screen_resize_data, &bot_screen_resize_data);
if(!processed) {
if(prioritize_top)
calc_scaling_resize_screens(&top_screen_resize_data, &bot_screen_resize_data, top_increase, try_mantain_ratio, this->m_stype == ScreenType::BOTTOM, cycle);
else
calc_scaling_resize_screens(&bot_screen_resize_data, &top_screen_resize_data, bot_increase, try_mantain_ratio, this->m_stype == ScreenType::TOP, cycle);
this->non_integer_scale_screens(&top_screen_resize_data, &bot_screen_resize_data);
}
}
int WindowScreen::get_fullscreen_offset_x(int top_width, int top_height, int bot_width, int bot_height) {

View File

@ -376,6 +376,12 @@ void WindowScreen::rotation_change(int &value, bool right) {
this->future_operations.call_rotate = true;
}
void WindowScreen::force_same_scaling_change() {
this->m_info.force_same_scaling = !this->m_info.force_same_scaling;
this->prepare_size_ratios(true, true, false);
this->future_operations.call_screen_settings_update = true;
}
void WindowScreen::ratio_change(bool top_priority, bool cycle) {
this->prepare_size_ratios(top_priority, !top_priority, cycle);
this->future_operations.call_screen_settings_update = true;
@ -1926,6 +1932,9 @@ void WindowScreen::poll(bool do_everything) {
case SCALING_RATIO_MENU_ALGO_INC:
this->non_int_mode_change(true);
break;
case SCALING_RATIO_MENU_FORCE_SAME_SCALING:
this->force_same_scaling_change();
break;
default:
break;
}

View File

@ -441,6 +441,7 @@ void reset_screen_info(ScreenInfo &info) {
info.async = true;
info.top_scaling = DEFAULT_NO_SCALING_VALUE;
info.bot_scaling = DEFAULT_NO_SCALING_VALUE;
info.force_same_scaling = false;
info.non_integer_top_scaling = DEFAULT_NO_SCALING_VALUE;
info.non_integer_bot_scaling = DEFAULT_NO_SCALING_VALUE;
info.bfi = false;
@ -607,6 +608,10 @@ 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 + "force_same_scaling")) {
info.force_same_scaling = std::stoi(value);
return true;
}
if(key == (base + "top_par")) {
info.top_par = std::stoi(value);
return true;
@ -707,6 +712,7 @@ std::string save_screen_info(std::string base, const ScreenInfo &info) {
out += base + "frame_blending_top=" + std::to_string(info.frame_blending_top) + "\n";
out += base + "frame_blending_bot=" + std::to_string(info.frame_blending_bot) + "\n";
out += base + "window_enabled=" + std::to_string(info.window_enabled) + "\n";
out += base + "force_same_scaling=" + std::to_string(info.force_same_scaling) + "\n";
return out;
}
@ -722,6 +728,10 @@ void joystick_axis_poll(std::queue<SFEvent> &events_queue) {
}
}
const PARData* get_base_par() {
return basic_possible_pars[0];
}
void get_par_size(int &width, int &height, float multiplier_factor, const PARData *correction_factor) {
width *= multiplier_factor;
height *= multiplier_factor;
@ -743,6 +753,26 @@ void get_par_size(int &width, int &height, float multiplier_factor, const PARDat
}
}
void get_par_size(float &width, float &height, float multiplier_factor, const PARData *correction_factor) {
width *= multiplier_factor;
height *= multiplier_factor;
float correction_factor_divisor = correction_factor->width_multiplier;
if(correction_factor->is_width_main)
correction_factor_divisor = correction_factor->width_divisor;
if(correction_factor->is_fit) {
if(correction_factor->is_width_main)
width = (height * correction_factor->width_multiplier) / correction_factor_divisor;
else
height = (width * correction_factor->width_divisor) / correction_factor_divisor;
}
else {
if(correction_factor->is_width_main)
width = (width * correction_factor->width_multiplier) / correction_factor_divisor;
else
height = (height * correction_factor->width_divisor) / correction_factor_divisor;
}
}
float get_par_mult_factor(float width, float height, float max_width, float max_height, const PARData *correction_factor, bool is_rotated) {
float correction_factor_divisor = correction_factor->width_multiplier;
float correction_factor_multiplier = correction_factor->width_divisor;