Implement automatic pixel scale and enable it by default.

It will try to match the default resolution (1280x720). It will also try
to ensure that the scaled resolution is less than 1920x1080. This will
result scaling as soon as the 1920x1080 resoluton is exceeded, requiring
a minimum supported resolution of 960x540 or less, however in practice this
is not a huge problem even with the existing 800x600 theme.

In any case the pixel scale can of course be overridden in preferences.
This commit is contained in:
Tommy 2022-04-17 03:39:52 +12:00
parent cf0da8b1ac
commit b530a47502
4 changed files with 39 additions and 6 deletions

View File

@ -319,8 +319,16 @@ void preferences_dialog::initialize_sound_option_group(const std::string& id_suf
void preferences_dialog::apply_pixel_scale()
{
// Update pixel scale preference.
slider& ps_slider = find_widget<slider>(get_window(), "pixel_scale_slider", false);
set_pixel_scale(ps_slider.get_value());
// Update auto pixel scale preference.
toggle_button& auto_ps_toggle =
find_widget<toggle_button>(get_window(), "auto_pixel_scale", false);
set_auto_pixel_scale(auto_ps_toggle.get_value_bool());
// Update draw buffers, taking these into account.
CVideo::get_singleton().update_buffers();
}
@ -436,6 +444,11 @@ void preferences_dialog::post_build(window& window)
auto_pixel_scale, set_auto_pixel_scale,
[&](widget& w) { disable_widget_on_toggle_inverted<slider>(window, w, "pixel_scale_slider"); }, true);
toggle_button& auto_ps_toggle =
find_widget<toggle_button>(get_window(), "auto_pixel_scale", false);
connect_signal_mouse_left_click(auto_ps_toggle,
std::bind(&preferences_dialog::apply_pixel_scale, this));
/* SHOW FLOATING LABELS */
register_bool("show_floating_labels", true,
show_floating_labels, set_show_floating_labels);

View File

@ -69,6 +69,9 @@ const int min_window_height = 540;
const int def_window_width = 1280;
const int def_window_height = 720;
const int max_window_width = 1920;
const int max_window_height = 1080;
const int min_font_scaling = 80;
const int max_font_scaling = 150;

View File

@ -41,6 +41,9 @@ namespace preferences {
extern const int def_window_width;
extern const int def_window_height;
extern const int max_window_width;
extern const int max_window_height;
extern const int min_font_scaling;
extern const int max_font_scaling;

View File

@ -196,19 +196,33 @@ void CVideo::update_framebuffer()
// Find max valid pixel scale at current window size.
point wsize(window->get_size());
int max_xscale = wsize.x / preferences::min_window_width;
int max_yscale = wsize.y / preferences::min_window_height;
int max_scale = std::min(max_xscale, max_yscale);
int max_scale = std::min(
wsize.x / preferences::min_window_width,
wsize.y / preferences::min_window_height);
max_scale = std::min(max_scale, preferences::max_pixel_scale);
// get desired pixel scale up to this max
int scale = std::min(max_scale, preferences::pixel_scale());
// Determine best pixel scale according to preference and window size
int scale = 1;
if (preferences::auto_pixel_scale()) {
// Try to match the default size (1280x720) but do not reduce below
int def_scale = std::min(
wsize.x / preferences::def_window_width,
wsize.y / preferences::def_window_height);
scale = std::min(max_scale, def_scale);
// Otherwise reduce to keep below the max window size (1920x1080).
int min_scale = std::min(
wsize.x / (preferences::max_window_width+1) + 1,
wsize.y / (preferences::max_window_height+1) + 1);
scale = std::max(scale, min_scale);
} else {
scale = std::min(max_scale, preferences::pixel_scale());
}
// Update logical size if it doesn't match the current resolution and scale.
point lsize(window->get_logical_size());
point osize(window->get_output_size());
if (lsize.x != wsize.x / scale || lsize.y != wsize.y / scale) {
if (scale < preferences::pixel_scale()) {
if (!preferences::auto_pixel_scale() && scale < preferences::pixel_scale()) {
LOG_DP << "reducing pixel scale from desired "
<< preferences::pixel_scale() << " to maximum allowable "
<< scale << std::endl;