mirror of
https://github.com/libretro/RetroArch
synced 2025-03-20 10:20:51 +00:00
Add integer scale options.
This commit is contained in:
parent
ab2ed14738
commit
61707d2783
@ -224,6 +224,11 @@ static const bool video_smooth = true;
|
||||
// On resize and fullscreen, rendering area will stay 4:3
|
||||
static const bool force_aspect = true;
|
||||
|
||||
// Only scale in integer steps.
|
||||
// The base size depends on system-reported geometry and aspect ratio.
|
||||
// If video_force_aspect is not set, X/Y will be integer scaled independently.
|
||||
static const bool scale_integer = false;
|
||||
|
||||
// Controls aspect ratio handling.
|
||||
static const float aspect_ratio = DEFAULT_ASPECT_RATIO; // Automatic
|
||||
static const bool aspect_ratio_auto = false; // 1:1 PAR
|
||||
|
@ -157,6 +157,7 @@ struct settings
|
||||
bool crop_overscan;
|
||||
float aspect_ratio;
|
||||
bool aspect_ratio_auto;
|
||||
bool scale_integer;
|
||||
unsigned aspect_ratio_idx;
|
||||
char cg_shader_path[PATH_MAX];
|
||||
char bsnes_shader_path[PATH_MAX];
|
||||
|
@ -176,3 +176,41 @@ void gfx_set_dwm(void)
|
||||
}
|
||||
#endif
|
||||
|
||||
void gfx_scale_integer(struct rarch_viewport *vp, unsigned width, unsigned height, float aspect_ratio, bool keep_aspect)
|
||||
{
|
||||
// Use system reported sizes as these define the geometry for the "normal" case.
|
||||
unsigned base_height = g_extern.system.av_info.geometry.base_height;
|
||||
// Account for non-square pixels.
|
||||
// This is sort of contradictory with the goal of integer scale,
|
||||
// but it is desirable in some cases.
|
||||
// If square pixels are used, base_height will be equal to g_extern.system.av_info.base_height.
|
||||
unsigned base_width = (unsigned)roundf(base_height * aspect_ratio);
|
||||
|
||||
unsigned padding_x = 0;
|
||||
unsigned padding_y = 0;
|
||||
|
||||
// Make sure that we don't get 0x scale ...
|
||||
if (width >= base_width && height >= base_height)
|
||||
{
|
||||
if (keep_aspect) // X/Y scale must be same.
|
||||
{
|
||||
unsigned max_scale = min(width / base_width, height / base_height);
|
||||
padding_x = width - base_width * max_scale;
|
||||
padding_y = height - base_height * max_scale;
|
||||
}
|
||||
else // X/Y can be independent, each scaled as much as possible.
|
||||
{
|
||||
padding_x = width % base_width;
|
||||
padding_y = height % base_height;
|
||||
}
|
||||
}
|
||||
|
||||
width -= padding_x;
|
||||
height -= padding_y;
|
||||
|
||||
vp->width = width;
|
||||
vp->height = height;
|
||||
vp->x = padding_x >> 1;
|
||||
vp->y = padding_y >> 1;
|
||||
}
|
||||
|
||||
|
@ -21,6 +21,7 @@ extern "C" {
|
||||
#endif
|
||||
|
||||
#include <stddef.h>
|
||||
#include "../general.h"
|
||||
#include "../boolean.h"
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
@ -36,6 +37,9 @@ void gfx_window_title_reset(void);
|
||||
void gfx_set_dwm(void);
|
||||
#endif
|
||||
|
||||
void gfx_scale_integer(struct rarch_viewport *vp, unsigned win_width, unsigned win_height,
|
||||
float aspect_ratio, bool keep_aspect);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
26
gfx/gl.c
26
gfx/gl.c
@ -674,7 +674,11 @@ void gl_set_viewport(void *data, unsigned width, unsigned height, bool force_ful
|
||||
else
|
||||
device_aspect = (float)width / height;
|
||||
|
||||
if (gl->keep_aspect && !force_full)
|
||||
if (g_settings.video.scale_integer && !force_full)
|
||||
{
|
||||
gfx_scale_integer(&gl->vp, width, height, g_settings.video.aspect_ratio, gl->keep_aspect);
|
||||
}
|
||||
else if (gl->keep_aspect && !force_full)
|
||||
{
|
||||
float desired_aspect = g_settings.video.aspect_ratio;
|
||||
float delta;
|
||||
@ -708,20 +712,26 @@ void gl_set_viewport(void *data, unsigned width, unsigned height, bool force_ful
|
||||
height = (unsigned)(2.0 * height * delta);
|
||||
}
|
||||
}
|
||||
|
||||
gl->vp.x = x;
|
||||
gl->vp.y = y;
|
||||
gl->vp.width = width;
|
||||
gl->vp.height = height;
|
||||
}
|
||||
else
|
||||
{
|
||||
gl->vp.x = gl->vp.y = 0;
|
||||
gl->vp.width = width;
|
||||
gl->vp.height = height;
|
||||
}
|
||||
|
||||
#ifdef ANDROID
|
||||
// In portrait mode, we want viewport to gravitate to top of screen.
|
||||
if (device_aspect < 1.0f)
|
||||
y *= 2;
|
||||
gl->vp.y *= 2;
|
||||
#endif
|
||||
|
||||
glViewport(x, y, width, height);
|
||||
gl->vp.x = x;
|
||||
gl->vp.y = y;
|
||||
gl->vp.width = width;
|
||||
gl->vp.height = height;
|
||||
|
||||
glViewport(gl->vp.x, gl->vp.y, gl->vp.width, gl->vp.height);
|
||||
gl_set_projection(gl, &ortho, allow_rotate);
|
||||
|
||||
// Set last backbuffer viewport.
|
||||
|
@ -533,7 +533,11 @@ static void calc_out_rect(bool keep_aspect, struct rarch_viewport *vp, unsigned
|
||||
vp->full_width = vp_width;
|
||||
vp->full_height = vp_height;
|
||||
|
||||
if (!keep_aspect)
|
||||
if (g_settings.video.scale_integer)
|
||||
{
|
||||
gfx_scale_integer(vp, vp_width, vp_height, g_settings.video.aspect_ratio, keep_aspect);
|
||||
}
|
||||
else if (!keep_aspect)
|
||||
{
|
||||
vp->x = 0; vp->y = 0;
|
||||
vp->width = vp_width;
|
||||
@ -679,6 +683,8 @@ static bool xv_frame(void *data, const void *frame, unsigned width, unsigned hei
|
||||
xv->render_func(xv, frame, width, height, pitch);
|
||||
|
||||
calc_out_rect(xv->keep_aspect, &xv->vp, target.width, target.height);
|
||||
xv->vp.full_width = target.width;
|
||||
xv->vp.full_height = target.width;
|
||||
|
||||
if (msg)
|
||||
xv_render_msg(xv, msg, width << 1, height << 1);
|
||||
|
@ -71,6 +71,11 @@
|
||||
# Forces rendering area to stay equal to game aspect ratio or as defined in video_aspect_ratio.
|
||||
# video_force_aspect = true
|
||||
|
||||
# Only scales video in integer steps.
|
||||
# The base size depends on system-reported geometry and aspect ratio.
|
||||
# If video_force_aspect is not set, X/Y will be integer scaled independently.
|
||||
# video_scale_integer = false
|
||||
|
||||
# A floating point value for video aspect ratio (width / height).
|
||||
# If this is not set, aspect ratio is assumed to be automatic.
|
||||
# Behavior then is defined by video_aspect_ratio_auto.
|
||||
|
@ -161,6 +161,7 @@ void config_set_defaults(void)
|
||||
g_settings.video.vsync = vsync;
|
||||
g_settings.video.smooth = video_smooth;
|
||||
g_settings.video.force_aspect = force_aspect;
|
||||
g_settings.video.scale_integer = scale_integer;
|
||||
g_settings.video.crop_overscan = crop_overscan;
|
||||
g_settings.video.aspect_ratio = aspect_ratio;
|
||||
g_settings.video.aspect_ratio_auto = aspect_ratio_auto; // Let implementation decide if automatic, or 1:1 PAR.
|
||||
@ -436,6 +437,7 @@ bool config_load_file(const char *path)
|
||||
CONFIG_GET_BOOL(video.vsync, "video_vsync");
|
||||
CONFIG_GET_BOOL(video.smooth, "video_smooth");
|
||||
CONFIG_GET_BOOL(video.force_aspect, "video_force_aspect");
|
||||
CONFIG_GET_BOOL(video.scale_integer, "video_scale_integer");
|
||||
CONFIG_GET_BOOL(video.crop_overscan, "video_crop_overscan");
|
||||
CONFIG_GET_FLOAT(video.aspect_ratio, "video_aspect_ratio");
|
||||
CONFIG_GET_BOOL(video.aspect_ratio_auto, "video_aspect_ratio_auto");
|
||||
|
Loading…
x
Reference in New Issue
Block a user