Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -731,15 +731,15 @@ if(PLAYER_TARGET_PLATFORM STREQUAL "SDL3")
elseif(PLAYER_TARGET_PLATFORM STREQUAL "SDL2")
if(NINTENDO_WII)
set(PLAYER_AUDIO_BACKEND "SDL2" CACHE STRING "Audio system to use. Options: SDL2 AESND OFF")
set_property(CACHE PLAYER_AUDIO_BACKEND PROPERTY STRINGS SDL2 AESND)
set_property(CACHE PLAYER_AUDIO_BACKEND PROPERTY STRINGS SDL2 AESND OFF)
else()
set(PLAYER_AUDIO_BACKEND "SDL2" CACHE STRING "Audio system to use. Options: SDL2 OFF")
set_property(CACHE PLAYER_AUDIO_BACKEND PROPERTY STRINGS SDL2 OFF)
endif()
elseif(PLAYER_TARGET_PLATFORM STREQUAL "SDL1")
if(NINTENDO_WII)
set(PLAYER_AUDIO_BACKEND "AESND" CACHE STRING "Audio system to use. Options: SDL1 AESND OFF")
set_property(CACHE PLAYER_AUDIO_BACKEND PROPERTY STRINGS SDL1 AESND)
set_property(CACHE PLAYER_AUDIO_BACKEND PROPERTY STRINGS SDL1 AESND OFF)
else()
set(PLAYER_AUDIO_BACKEND "SDL1" CACHE STRING "Audio system to use. Options: SDL1 OFF")
set_property(CACHE PLAYER_AUDIO_BACKEND PROPERTY STRINGS SDL1 OFF)
Expand Down
9 changes: 9 additions & 0 deletions src/baseui.h
Original file line number Diff line number Diff line change
Expand Up @@ -254,6 +254,15 @@ class BaseUi {
/** Turns a touch ui on or off. */
virtual void ToggleTouchUi() {};

/**
* Adjusts the scaling of the screen (for overscan/underscan)
*
* @param scale Screen scaling in percent (50 - 150)
*/
virtual void SetScreenScale(int scale) {
(void)scale;
}

/**
* @return current video options.
*/
Expand Down
3 changes: 3 additions & 0 deletions src/game_config.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,7 @@ void Game_ConfigVideo::Hide() {
touch_ui.SetOptionVisible(false);
pause_when_focus_lost.SetOptionVisible(false);
game_resolution.SetOptionVisible(false);
screen_scale.SetOptionVisible(false);
}

void Game_ConfigAudio::Hide() {
Expand Down Expand Up @@ -598,6 +599,7 @@ void Game_Config::LoadFromStream(Filesystem_Stream::InputStream& is) {
video.touch_ui.FromIni(ini);
video.pause_when_focus_lost.FromIni(ini);
video.game_resolution.FromIni(ini);
video.screen_scale.FromIni(ini);

if (ini.HasValue("Video", "WindowX") && ini.HasValue("Video", "WindowY") && ini.HasValue("Video", "WindowWidth") && ini.HasValue("Video", "WindowHeight")) {
video.window_x.FromIni(ini);
Expand Down Expand Up @@ -695,6 +697,7 @@ void Game_Config::WriteToStream(Filesystem_Stream::OutputStream& os) const {
video.touch_ui.ToIni(os);
video.pause_when_focus_lost.ToIni(os);
video.game_resolution.ToIni(os);
video.screen_scale.ToIni(os);

// only preserve when toggling between window and fullscreen is supported
if (video.fullscreen.IsOptionVisible()) {
Expand Down
1 change: 1 addition & 0 deletions src/game_config.h
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,7 @@ struct Game_ConfigVideo {
Utils::MakeSvArray("Original (Recommended)", "Widescreen (Experimental)", "Ultrawide (Experimental)"),
Utils::MakeSvArray("original", "widescreen", "ultrawide"),
Utils::MakeSvArray("The default resolution (320x240, 4:3)", "Can cause glitches (416x240, 16:9)", "Can cause glitches (560x240, 21:9)")};
RangeConfigParam<int> screen_scale{ "Scaling", "Adjust screen scaling (Overscan/Underscan)", "Video", "ScreenScale", 100, 50, 150 };

// These are never shown and are used to restore the window to the previous position
ConfigParam<int> window_x{ "", "", "Video", "WindowX", -1 };
Expand Down
58 changes: 31 additions & 27 deletions src/platform/sdl/sdl2_ui.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -586,6 +586,11 @@ void Sdl2Ui::ToggleVsync() {
#endif
}

void Sdl2Ui::SetScreenScale(int scale) {
vcfg.screen_scale.Set(std::clamp(scale, 50, 150));
window.size_changed = true;
}

void Sdl2Ui::UpdateDisplay() {
#ifdef __WIIU__
if (vcfg.scaling_mode.Get() == ConfigEnum::ScalingMode::Bilinear && window.scale > 0.f) {
Expand All @@ -609,60 +614,55 @@ void Sdl2Ui::UpdateDisplay() {
// Based on SDL2 function UpdateLogicalSize
window.size_changed = false;

float width_float = static_cast<float>(window.width);
float height_float = static_cast<float>(window.height);
int win_width = window.width * vcfg.screen_scale.Get() / 100.0;
int win_height = window.height * vcfg.screen_scale.Get() / 100.0;

int border_x = (window.width - win_width) / 2;
int border_y = (window.height - win_height) / 2;

float width_float = static_cast<float>(win_width);
float height_float = static_cast<float>(win_height);

float want_aspect = (float)main_surface->width() / main_surface->height();
float real_aspect = width_float / height_float;

auto do_stretch = [this]() {
auto do_stretch = [this, border_x, win_width]() {
if (vcfg.stretch.Get()) {
viewport.x = 0;
viewport.w = window.width;
viewport.x = border_x;
viewport.w = win_width;
}
};

if (vcfg.scaling_mode.Get() == ConfigEnum::ScalingMode::Integer) {
// Integer division on purpose
if (want_aspect > real_aspect) {
window.scale = static_cast<float>(window.width / main_surface->width());
window.scale = static_cast<float>(win_width / main_surface->width());
} else {
window.scale = static_cast<float>(window.height / main_surface->height());
window.scale = static_cast<float>(win_height / main_surface->height());
}

viewport.w = static_cast<int>(ceilf(main_surface->width() * window.scale));
viewport.x = (window.width - viewport.w) / 2;
viewport.x = (win_width - viewport.w) / 2 + border_x;
viewport.h = static_cast<int>(ceilf(main_surface->height() * window.scale));
viewport.y = (window.height - viewport.h) / 2;
viewport.y = (win_height - viewport.h) / 2 + border_y;
do_stretch();

SDL_RenderSetViewport(sdl_renderer, &viewport);
} else if (fabs(want_aspect - real_aspect) < 0.0001) {
// The aspect ratios are the same, let SDL2 scale it
window.scale = width_float / main_surface->width();
SDL_RenderSetViewport(sdl_renderer, nullptr);

// Only used here for the mouse coordinates
viewport.x = 0;
viewport.y = 0;
viewport.w = window.width;
viewport.h = window.height;
} else if (want_aspect > real_aspect) {
// Letterboxing (black bars top and bottom)
window.scale = width_float / main_surface->width();
viewport.x = 0;
viewport.w = window.width;
viewport.x = border_x;
viewport.w = win_width;
viewport.h = static_cast<int>(ceilf(main_surface->height() * window.scale));
viewport.y = (window.height - viewport.h) / 2;
viewport.y = (win_height - viewport.h) / 2 + border_y;
do_stretch();
SDL_RenderSetViewport(sdl_renderer, &viewport);
} else {
// black bars left and right
// black bars left and right (or nothing when aspect ratio matches)
window.scale = height_float / main_surface->height();
viewport.y = 0;
viewport.h = window.height;
viewport.y = border_y;
viewport.h = win_height;
viewport.w = static_cast<int>(ceilf(main_surface->width() * window.scale));
viewport.x = (window.width - viewport.w) / 2;
viewport.x = (win_width - viewport.w) / 2 + border_x;
do_stretch();
SDL_RenderSetViewport(sdl_renderer, &viewport);
}
Expand Down Expand Up @@ -1291,6 +1291,10 @@ void Sdl2Ui::vGetConfig(Game_ConfigVideo& cfg) const {
cfg.stretch.SetOptionVisible(true);
cfg.game_resolution.SetOptionVisible(true);
cfg.pause_when_focus_lost.SetOptionVisible(true);
cfg.screen_scale.SetOptionVisible(true);
#if defined(__wii__)
cfg.screen_scale.SetMax(100);
#endif

cfg.vsync.Set(current_display_mode.vsync);
cfg.window_zoom.Set(current_display_mode.zoom);
Expand Down
1 change: 1 addition & 0 deletions src/platform/sdl/sdl2_ui.h
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,7 @@ class Sdl2Ui final : public BaseUi {
void SetScalingMode(ConfigEnum::ScalingMode) override;
void ToggleStretch() override;
void ToggleVsync() override;
void SetScreenScale(int scale) override;
void vGetConfig(Game_ConfigVideo& cfg) const override;
bool OpenURL(std::string_view url) override;
Rect GetWindowMetrics() const override;
Expand Down
54 changes: 28 additions & 26 deletions src/platform/sdl/sdl3_ui.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -517,6 +517,11 @@ void Sdl3Ui::ToggleVsync() {
}
}

void Sdl3Ui::SetScreenScale(int scale) {
vcfg.screen_scale.Set(std::clamp(scale, 50, 150));
window.size_changed = true;
}

void Sdl3Ui::UpdateDisplay() {
#ifdef __WIIU__
if (vcfg.scaling_mode.Get() == ConfigEnum::ScalingMode::Bilinear && window.scale > 0.f) {
Expand All @@ -540,60 +545,56 @@ void Sdl3Ui::UpdateDisplay() {
// Based on SDL2 function UpdateLogicalSize
window.size_changed = false;

float width_float = static_cast<float>(window.width);
float height_float = static_cast<float>(window.height);
int win_width = window.width * vcfg.screen_scale.Get() / 100.0;
int win_height = window.height * vcfg.screen_scale.Get() / 100.0;

int border_x = (window.width - win_width) / 2;
int border_y = (window.height - win_height) / 2;

float width_float = static_cast<float>(win_width);
float height_float = static_cast<float>(win_height);

float want_aspect = (float)main_surface->width() / main_surface->height();
float real_aspect = width_float / height_float;

auto do_stretch = [this]() {
auto do_stretch = [this, border_x, win_width]() {
if (vcfg.stretch.Get()) {
viewport.x = 0;
viewport.w = window.width;
viewport.x = border_x;
viewport.w = win_width;
}
};

if (vcfg.scaling_mode.Get() == ConfigEnum::ScalingMode::Integer) {
// Integer division on purpose
if (want_aspect > real_aspect) {
window.scale = static_cast<float>(window.width / main_surface->width());
window.scale = static_cast<float>(win_width / main_surface->width());
} else {
window.scale = static_cast<float>(window.height / main_surface->height());
window.scale = static_cast<float>(win_height / main_surface->height());
}

viewport.w = static_cast<int>(ceilf(main_surface->width() * window.scale));
viewport.x = (window.width - viewport.w) / 2;
viewport.x = (win_width - viewport.w) / 2 + border_x;
viewport.h = static_cast<int>(ceilf(main_surface->height() * window.scale));
viewport.y = (window.height - viewport.h) / 2;
viewport.y = (win_height - viewport.h) / 2 + border_y;
do_stretch();

SDL_SetRenderViewport(sdl_renderer, &viewport);
} else if (fabs(want_aspect - real_aspect) < 0.0001) {
// The aspect ratios are the same, let SDL2 scale it
window.scale = width_float / main_surface->width();
SDL_SetRenderViewport(sdl_renderer, nullptr);

// Only used here for the mouse coordinates
viewport.x = 0;
viewport.y = 0;
viewport.w = window.width;
viewport.h = window.height;
} else if (want_aspect > real_aspect) {
// Letterboxing (black bars top and bottom)
window.scale = width_float / main_surface->width();
viewport.x = 0;
viewport.w = window.width;
viewport.x = border_x;
viewport.w = win_width;
viewport.h = static_cast<int>(ceilf(main_surface->height() * window.scale));
viewport.y = (window.height - viewport.h) / 2;
viewport.y = (win_height - viewport.h) / 2 + border_y;
do_stretch();
SDL_SetRenderViewport(sdl_renderer, &viewport);
} else {
// black bars left and right
// black bars left and right (or nothing when aspect ratio matches)
window.scale = height_float / main_surface->height();
viewport.y = 0;
viewport.h = window.height;
viewport.y = border_y;
viewport.h = win_height;
viewport.w = static_cast<int>(ceilf(main_surface->width() * window.scale));
viewport.x = (window.width - viewport.w) / 2;
viewport.x = (win_width - viewport.w) / 2 + border_x;
do_stretch();
SDL_SetRenderViewport(sdl_renderer, &viewport);
}
Expand Down Expand Up @@ -1217,6 +1218,7 @@ void Sdl3Ui::vGetConfig(Game_ConfigVideo& cfg) const {
cfg.stretch.SetOptionVisible(true);
cfg.game_resolution.SetOptionVisible(true);
cfg.pause_when_focus_lost.SetOptionVisible(true);
cfg.screen_scale.SetOptionVisible(true);

cfg.vsync.Set(current_display_mode.vsync);
cfg.window_zoom.Set(current_display_mode.zoom);
Expand Down
1 change: 1 addition & 0 deletions src/platform/sdl/sdl3_ui.h
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,7 @@ class Sdl3Ui final : public BaseUi {
void SetScalingMode(ConfigEnum::ScalingMode) override;
void ToggleStretch() override;
void ToggleVsync() override;
void SetScreenScale(int scale) override;
void vGetConfig(Game_ConfigVideo& cfg) const override;
bool OpenURL(std::string_view url) override;
Rect GetWindowMetrics() const override;
Expand Down
1 change: 1 addition & 0 deletions src/window_settings.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -284,6 +284,7 @@ void Window_Settings::RefreshVideo() {
AddOption(cfg.pause_when_focus_lost, [cfg]() mutable { DisplayUi->SetPauseWhenFocusLost(cfg.pause_when_focus_lost.Toggle()); });
AddOption(cfg.touch_ui, [](){ DisplayUi->ToggleTouchUi(); });
AddOption(cfg.game_resolution, [this]() { DisplayUi->SetGameResolution(static_cast<ConfigEnum::GameResolution>(GetCurrentOption().current_value)); });
AddOption(cfg.screen_scale, [this](){ DisplayUi->SetScreenScale(GetCurrentOption().current_value); });
}

void Window_Settings::RefreshAudio() {
Expand Down