Skip to content

Commit

Permalink
Add "pixelperfect" window aspect.
Browse files Browse the repository at this point in the history
This mode makes sure that only integers are used as multiplier or divisor
for the viewport size. This works best with viewport stretch mode.
As opposed to the other aspects this mode will allow for black borders
on all sides to satisfy the requirement.
  • Loading branch information
bfloch committed Jan 16, 2021
1 parent 31d0f8a commit a63c016
Show file tree
Hide file tree
Showing 3 changed files with 27 additions and 3 deletions.
4 changes: 3 additions & 1 deletion main/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1829,6 +1829,8 @@ bool Main::start() {
sml_aspect = SceneTree::STRETCH_ASPECT_KEEP_HEIGHT;
else if (stretch_aspect == "expand")
sml_aspect = SceneTree::STRETCH_ASPECT_EXPAND;
else if (stretch_aspect == "pixelperfect")
sml_aspect = SceneTree::STRETCH_ASPECT_PIXELPERFECT;

sml->set_screen_stretch(sml_sm, sml_aspect, stretch_size, stretch_shrink);

Expand Down Expand Up @@ -1870,7 +1872,7 @@ bool Main::start() {
GLOBAL_DEF("display/window/stretch/mode", "disabled");
ProjectSettings::get_singleton()->set_custom_property_info("display/window/stretch/mode", PropertyInfo(Variant::STRING, "display/window/stretch/mode", PROPERTY_HINT_ENUM, "disabled,2d,viewport"));
GLOBAL_DEF("display/window/stretch/aspect", "ignore");
ProjectSettings::get_singleton()->set_custom_property_info("display/window/stretch/aspect", PropertyInfo(Variant::STRING, "display/window/stretch/aspect", PROPERTY_HINT_ENUM, "ignore,keep,keep_width,keep_height,expand"));
ProjectSettings::get_singleton()->set_custom_property_info("display/window/stretch/aspect", PropertyInfo(Variant::STRING, "display/window/stretch/aspect", PROPERTY_HINT_ENUM, "ignore,keep,keep_width,keep_height,expand,pixelperfect"));
GLOBAL_DEF("display/window/stretch/shrink", 1.0);
ProjectSettings::get_singleton()->set_custom_property_info("display/window/stretch/shrink", PropertyInfo(Variant::REAL, "display/window/stretch/shrink", PROPERTY_HINT_RANGE, "1.0,8.0,0.1"));
sml->set_auto_accept_quit(GLOBAL_DEF("application/config/auto_accept_quit", true));
Expand Down
25 changes: 23 additions & 2 deletions scene/main/scene_tree.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,8 @@
#include "viewport.h"

#include <stdio.h>
#include <algorithm>
#include <cmath>

void SceneTreeTimer::_bind_methods() {

Expand Down Expand Up @@ -1153,7 +1155,20 @@ void SceneTree::_update_root_rect() {
WARN_PRINT("Font oversampling only works with the resize modes 'Keep Width', 'Keep Height', and 'Expand'.");
}

if (stretch_aspect == STRETCH_ASPECT_IGNORE || Math::is_equal_approx(viewport_aspect, video_mode_aspect)) {
if (stretch_aspect == STRETCH_ASPECT_PIXELPERFECT) {
// only multiply or divide by integer
viewport_size = desired_res;

if (video_mode >= desired_res) {
Size2 scale_size = video_mode / desired_res;
int scale_factor = std::floor(std::min(scale_size.x, scale_size.y));
screen_size = desired_res * scale_factor;
} else {
Size2 scale_size = desired_res / video_mode;
int scale_factor = std::ceil(std::max(scale_size.x, scale_size.y));
screen_size = desired_res / scale_factor;
}
} else if (stretch_aspect == STRETCH_ASPECT_IGNORE || Math::is_equal_approx(viewport_aspect, video_mode_aspect)) {
//same aspect or ignore aspect
viewport_size = desired_res;
screen_size = video_mode;
Expand Down Expand Up @@ -1196,7 +1211,13 @@ void SceneTree::_update_root_rect() {
Size2 margin;
Size2 offset;
//black bars and margin
if (stretch_aspect != STRETCH_ASPECT_EXPAND && screen_size.x < video_mode.x) {
if (stretch_aspect == STRETCH_ASPECT_PIXELPERFECT) {
margin.y = Math::round((video_mode.y - screen_size.y) / 2.0);
margin.x = Math::round((video_mode.x - screen_size.x) / 2.0);
VisualServer::get_singleton()->black_bars_set_margins(margin.x, margin.y, margin.x, margin.y);
offset.x = Math::round(margin.x * viewport_size.y / screen_size.y);
offset.y = Math::round(margin.y * viewport_size.x / screen_size.x);
} else if (stretch_aspect != STRETCH_ASPECT_EXPAND && screen_size.x < video_mode.x) {
margin.x = Math::round((video_mode.x - screen_size.x) / 2.0);
VisualServer::get_singleton()->black_bars_set_margins(margin.x, 0, margin.x, 0);
offset.x = Math::round(margin.x * viewport_size.y / screen_size.y);
Expand Down
1 change: 1 addition & 0 deletions scene/main/scene_tree.h
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,7 @@ class SceneTree : public MainLoop {
STRETCH_ASPECT_KEEP_WIDTH,
STRETCH_ASPECT_KEEP_HEIGHT,
STRETCH_ASPECT_EXPAND,
STRETCH_ASPECT_PIXELPERFECT,
};

private:
Expand Down

0 comments on commit a63c016

Please sign in to comment.