Pixel perfect integer scaling improvements (#17098)

This commit is contained in:
sonninnos 2024-10-15 00:44:10 +03:00 committed by GitHub
parent b36d8da5d3
commit 84b58dd001
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
11 changed files with 326 additions and 55 deletions

View File

@ -520,7 +520,8 @@
* Overscale rounds up instead of down, default is downscale. * Overscale rounds up instead of down, default is downscale.
*/ */
#define DEFAULT_SCALE_INTEGER false #define DEFAULT_SCALE_INTEGER false
#define DEFAULT_SCALE_INTEGER_OVERSCALE false #define DEFAULT_SCALE_INTEGER_AXIS 0
#define DEFAULT_SCALE_INTEGER_SCALING 0
/* Controls aspect ratio handling. */ /* Controls aspect ratio handling. */

View File

@ -1863,7 +1863,6 @@ static struct config_bool_setting *populate_settings_bool(
SETTING_BOOL("video_windowed_fullscreen", &settings->bools.video_windowed_fullscreen, true, DEFAULT_WINDOWED_FULLSCREEN, false); SETTING_BOOL("video_windowed_fullscreen", &settings->bools.video_windowed_fullscreen, true, DEFAULT_WINDOWED_FULLSCREEN, false);
SETTING_BOOL("video_crop_overscan", &settings->bools.video_crop_overscan, true, DEFAULT_CROP_OVERSCAN, false); SETTING_BOOL("video_crop_overscan", &settings->bools.video_crop_overscan, true, DEFAULT_CROP_OVERSCAN, false);
SETTING_BOOL("video_scale_integer", &settings->bools.video_scale_integer, true, DEFAULT_SCALE_INTEGER, false); SETTING_BOOL("video_scale_integer", &settings->bools.video_scale_integer, true, DEFAULT_SCALE_INTEGER, false);
SETTING_BOOL("video_scale_integer_overscale", &settings->bools.video_scale_integer_overscale, true, DEFAULT_SCALE_INTEGER_OVERSCALE, false);
SETTING_BOOL("video_smooth", &settings->bools.video_smooth, true, DEFAULT_VIDEO_SMOOTH, false); SETTING_BOOL("video_smooth", &settings->bools.video_smooth, true, DEFAULT_VIDEO_SMOOTH, false);
SETTING_BOOL("video_ctx_scaling", &settings->bools.video_ctx_scaling, true, DEFAULT_VIDEO_CTX_SCALING, false); SETTING_BOOL("video_ctx_scaling", &settings->bools.video_ctx_scaling, true, DEFAULT_VIDEO_CTX_SCALING, false);
SETTING_BOOL("video_force_aspect", &settings->bools.video_force_aspect, true, DEFAULT_FORCE_ASPECT, false); SETTING_BOOL("video_force_aspect", &settings->bools.video_force_aspect, true, DEFAULT_FORCE_ASPECT, false);
@ -2456,6 +2455,8 @@ static struct config_uint_setting *populate_settings_uint(
SETTING_UINT("video_fullscreen_y", &settings->uints.video_fullscreen_y, true, DEFAULT_FULLSCREEN_Y, false); SETTING_UINT("video_fullscreen_y", &settings->uints.video_fullscreen_y, true, DEFAULT_FULLSCREEN_Y, false);
#endif #endif
SETTING_UINT("video_scale", &settings->uints.video_scale, true, DEFAULT_SCALE, false); SETTING_UINT("video_scale", &settings->uints.video_scale, true, DEFAULT_SCALE, false);
SETTING_UINT("video_scale_integer_axis", &settings->uints.video_scale_integer_axis, true, DEFAULT_SCALE_INTEGER_AXIS, false);
SETTING_UINT("video_scale_integer_scaling", &settings->uints.video_scale_integer_scaling, true, DEFAULT_SCALE_INTEGER_SCALING, false);
SETTING_UINT("video_window_opacity", &settings->uints.video_window_opacity, true, DEFAULT_WINDOW_OPACITY, false); SETTING_UINT("video_window_opacity", &settings->uints.video_window_opacity, true, DEFAULT_WINDOW_OPACITY, false);
SETTING_UINT("video_shader_delay", &settings->uints.video_shader_delay, true, DEFAULT_SHADER_DELAY, false); SETTING_UINT("video_shader_delay", &settings->uints.video_shader_delay, true, DEFAULT_SHADER_DELAY, false);
#ifdef GEKKO #ifdef GEKKO

View File

@ -242,6 +242,8 @@ typedef struct settings
unsigned video_fullscreen_x; unsigned video_fullscreen_x;
unsigned video_fullscreen_y; unsigned video_fullscreen_y;
unsigned video_scale; unsigned video_scale;
unsigned video_scale_integer_axis;
unsigned video_scale_integer_scaling;
unsigned video_max_swapchain_images; unsigned video_max_swapchain_images;
unsigned video_max_frame_latency; unsigned video_max_frame_latency;
unsigned video_swap_interval; unsigned video_swap_interval;
@ -617,7 +619,6 @@ typedef struct settings
bool video_aspect_ratio_auto; bool video_aspect_ratio_auto;
bool video_dingux_ipu_keep_aspect; bool video_dingux_ipu_keep_aspect;
bool video_scale_integer; bool video_scale_integer;
bool video_scale_integer_overscale;
bool video_shader_enable; bool video_shader_enable;
bool video_shader_watch_files; bool video_shader_watch_files;
bool video_shader_remember_last_dir; bool video_shader_remember_last_dir;

View File

@ -66,6 +66,25 @@ enum aspect_ratio
ASPECT_RATIO_END ASPECT_RATIO_END
}; };
enum video_scale_integer_axis
{
VIDEO_SCALE_INTEGER_AXIS_Y = 0,
VIDEO_SCALE_INTEGER_AXIS_Y_X,
VIDEO_SCALE_INTEGER_AXIS_Y_XHALF,
VIDEO_SCALE_INTEGER_AXIS_YHALF_XHALF,
VIDEO_SCALE_INTEGER_AXIS_X,
VIDEO_SCALE_INTEGER_AXIS_XHALF,
VIDEO_SCALE_INTEGER_AXIS_LAST
};
enum video_scale_integer_scaling
{
VIDEO_SCALE_INTEGER_SCALING_UNDERSCALE = 0,
VIDEO_SCALE_INTEGER_SCALING_OVERSCALE,
VIDEO_SCALE_INTEGER_SCALING_SMART,
VIDEO_SCALE_INTEGER_SCALING_LAST
};
enum rotation enum rotation
{ {
ORIENTATION_NORMAL = 0, ORIENTATION_NORMAL = 0,

View File

@ -2059,9 +2059,10 @@ void video_viewport_get_scaled_aspect(struct video_viewport *vp, unsigned viewpo
void video_viewport_get_scaled_aspect2(struct video_viewport *vp, unsigned viewport_width, unsigned viewport_height, bool ydown, float device_aspect, float desired_aspect) void video_viewport_get_scaled_aspect2(struct video_viewport *vp, unsigned viewport_width, unsigned viewport_height, bool ydown, float device_aspect, float desired_aspect)
{ {
settings_t *settings = config_get_ptr(); settings_t *settings = config_get_ptr();
int x = 0; video_driver_state_t *video_st = &video_driver_st;
int y = 0; int x = 0;
int y = 0;
float viewport_bias_x = settings->floats.video_viewport_bias_x; float viewport_bias_x = settings->floats.video_viewport_bias_x;
float viewport_bias_y = settings->floats.video_viewport_bias_y; float viewport_bias_y = settings->floats.video_viewport_bias_y;
@ -2119,10 +2120,15 @@ void video_viewport_get_scaled_aspect2(struct video_viewport *vp, unsigned viewp
viewport_height = (unsigned)roundf(2.0f * viewport_height * delta); viewport_height = (unsigned)roundf(2.0f * viewport_height * delta);
} }
} }
vp->x = x; vp->x = x;
vp->y = y; vp->y = y;
vp->width = viewport_width; vp->width = viewport_width;
vp->height = viewport_height; vp->height = viewport_height;
/* Statistics */
video_st->scale_width = vp->width;
video_st->scale_height = vp->height;
} }
void video_driver_update_viewport( void video_driver_update_viewport(
@ -2349,7 +2355,8 @@ void video_viewport_get_scaled_integer(struct video_viewport *vp,
settings_t *settings = config_get_ptr(); settings_t *settings = config_get_ptr();
video_driver_state_t *video_st = &video_driver_st; video_driver_state_t *video_st = &video_driver_st;
unsigned video_aspect_ratio_idx = settings->uints.video_aspect_ratio_idx; unsigned video_aspect_ratio_idx = settings->uints.video_aspect_ratio_idx;
bool overscale = settings->bools.video_scale_integer_overscale; unsigned scaling = settings->uints.video_scale_integer_scaling;
unsigned axis = settings->uints.video_scale_integer_axis;
int padding_x = 0; int padding_x = 0;
int padding_y = 0; int padding_y = 0;
float viewport_bias_x = settings->floats.video_viewport_bias_x; float viewport_bias_x = settings->floats.video_viewport_bias_x;
@ -2371,9 +2378,6 @@ void video_viewport_get_scaled_integer(struct video_viewport *vp,
if (rotation % 2) if (rotation % 2)
content_height = content_width; content_height = content_width;
if (content_height == 0)
content_height = 1;
/* Account for non-square pixels. /* Account for non-square pixels.
* This is sort of contradictory with the goal of integer scale, * This is sort of contradictory with the goal of integer scale,
* but it is desirable in some cases. * but it is desirable in some cases.
@ -2382,6 +2386,12 @@ void video_viewport_get_scaled_integer(struct video_viewport *vp,
* system->av_info.base_height. */ * system->av_info.base_height. */
content_width = (unsigned)roundf(content_height * aspect_ratio); content_width = (unsigned)roundf(content_height * aspect_ratio);
if (content_width < 2 || content_height < 2)
return;
content_width = (content_width > width) ? width : content_width;
content_height = (content_height > height) ? height : content_height;
if (video_aspect_ratio_idx == ASPECT_RATIO_CUSTOM) if (video_aspect_ratio_idx == ASPECT_RATIO_CUSTOM)
{ {
struct video_viewport *custom_vp = &settings->video_viewport_custom; struct video_viewport *custom_vp = &settings->video_viewport_custom;
@ -2406,18 +2416,134 @@ void video_viewport_get_scaled_integer(struct video_viewport *vp,
{ {
if (keep_aspect) if (keep_aspect)
{ {
/* X/Y scale must be same. */ int8_t half_w = 0;
unsigned max_scale = 1; int8_t half_h = 0;
uint8_t max_scale = 1;
uint8_t max_scale_w = 1;
uint8_t max_scale_h = 1;
if (overscale) /* Overscale if less screen is lost by cropping instead of empty added by underscale */
if (scaling == VIDEO_SCALE_INTEGER_SCALING_SMART)
{
unsigned overscale_w = (width / content_width) + !!(width % content_width);
unsigned underscale_w = (width / content_width);
unsigned overscale_h = (height / content_height) + !!(height % content_height);
unsigned underscale_h = (height / content_height);
int overscale_w_diff = (content_width * overscale_w) - width;
int underscale_w_diff = width - (content_width * underscale_w);
int overscale_h_diff = (content_height * overscale_h) - height;
int underscale_h_diff = height - (content_height * underscale_h);
int scale_h_diff = overscale_h_diff - underscale_h_diff;
max_scale_w = underscale_w;
max_scale_h = underscale_h;
/* Prefer nearest scale */
if (overscale_w_diff <= underscale_w_diff)
max_scale_w = overscale_w;
if (overscale_h_diff <= underscale_h_diff)
max_scale_h = overscale_h;
/* Allow overscale when it is close enough */
if (scale_h_diff > 0 && scale_h_diff < 64)
max_scale_h = overscale_h;
/* Overscale will be too much even if it is closer */
else if ((scale_h_diff < -155 && scale_h_diff > (int)-content_height / 2)
|| (scale_h_diff < -20 && scale_h_diff > -50)
|| (scale_h_diff > 20))
max_scale_h = underscale_h;
/* Sensible limiting for small sources */
if (content_height <= 200)
max_scale_h = underscale_h;
max_scale = MIN(max_scale_w, max_scale_h);
}
else if (scaling == VIDEO_SCALE_INTEGER_SCALING_OVERSCALE)
max_scale = MIN((width / content_width) + !!(width % content_width), max_scale = MIN((width / content_width) + !!(width % content_width),
(height / content_height) + !!(height % content_height)); (height / content_height) + !!(height % content_height));
else else
max_scale = MIN(width / content_width, max_scale = MIN(width / content_width,
height / content_height); height / content_height);
padding_x = width - content_width * max_scale; /* Reset both scales */
padding_y = height - content_height * max_scale; max_scale_w = max_scale_h = max_scale;
/* Pick the nearest width multiplier for preserving aspect ratio */
if (axis >= VIDEO_SCALE_INTEGER_AXIS_Y_X)
{
float target_ratio = (float)content_width / (float)content_height;
float underscale_ratio = 0;
float overscale_ratio = 0;
uint16_t content_width_ar = content_width;
uint8_t overscale_w = 0;
uint8_t i = 0;
/* Reset width to exact width */
content_width = (rotation % 2) ? video_st->frame_cache_height : video_st->frame_cache_width;
overscale_w = (width / content_width) + !!(width % content_width);
/* Populate the ratios */
for (i = 1; i < overscale_w + 1; i++)
{
float scale_w_ratio = (float)(content_width * i) / (float)(content_height * max_scale_h);
if (scale_w_ratio > target_ratio)
{
overscale_ratio = scale_w_ratio;
break;
}
underscale_ratio = scale_w_ratio;
}
/* Pick the nearest ratio */
if (overscale_ratio - target_ratio <= target_ratio - underscale_ratio)
max_scale_w = i;
else if (i > 1)
max_scale_w = i - 1;
/* Special half width scale for hi-res */
if ( axis == VIDEO_SCALE_INTEGER_AXIS_Y_XHALF
|| axis == VIDEO_SCALE_INTEGER_AXIS_YHALF_XHALF
|| axis == VIDEO_SCALE_INTEGER_AXIS_XHALF)
{
float scale_w_ratio = (float)(content_width * max_scale_w) / (float)(content_height * max_scale_h);
uint8_t hires_w = content_width / 512;
int content_width_diff = content_width_ar - (content_width / (hires_w + 1));
if ( content_width_ar - content_width_diff == (int)content_width / 2
&& content_width_diff < 20
&& scale_w_ratio - target_ratio > 0.25f
)
half_w = -1;
}
/* Special half height scale for hi-res */
if (axis == VIDEO_SCALE_INTEGER_AXIS_YHALF_XHALF)
{
if ( max_scale_h == (height / content_height)
&& content_height / 300
&& content_height * max_scale_h < height
)
{
float halfstep_prev_ratio = (float)(content_width * max_scale_w) / (float)(content_height * max_scale_h);
float halfstep_next_ratio = (float)(content_width * max_scale_w) / (float)(content_height * (max_scale_h + 0.5f));
half_h = 1;
if (halfstep_next_ratio - target_ratio <= target_ratio - halfstep_prev_ratio)
half_w = 1;
}
}
}
padding_x = width - content_width * (max_scale_w + (half_w * 0.5f));
padding_y = height - content_height * (max_scale_h + (half_h * 0.5f));
/* No Y padding when only touching X */
if (axis >= VIDEO_SCALE_INTEGER_AXIS_X)
padding_y = 0;
} }
else else
{ {
@ -2425,9 +2551,11 @@ void video_viewport_get_scaled_integer(struct video_viewport *vp,
padding_x = width % content_width; padding_x = width % content_width;
padding_y = height % content_height; padding_y = height % content_height;
} }
width -= padding_x; width -= padding_x;
height -= padding_y; height -= padding_y;
} }
x += padding_x * viewport_bias_x; x += padding_x * viewport_bias_x;
y += padding_y * viewport_bias_y; y += padding_y * viewport_bias_y;
@ -2435,6 +2563,10 @@ void video_viewport_get_scaled_integer(struct video_viewport *vp,
vp->height = height; vp->height = height;
vp->x = x; vp->x = x;
vp->y = y; vp->y = y;
/* Statistics */
video_st->scale_width = vp->width;
video_st->scale_height = vp->height;
} }
void video_driver_display_type_set(enum rarch_display_type type) void video_driver_display_type_set(enum rarch_display_type type)
@ -2664,6 +2796,8 @@ void video_driver_build_info(video_frame_info_t *video_info)
video_info->width = video_st->width; video_info->width = video_st->width;
video_info->height = video_st->height; video_info->height = video_st->height;
video_info->scale_width = video_st->scale_width;
video_info->scale_height = video_st->scale_height;
video_info->hdr_enable = settings->bools.video_hdr_enable; video_info->hdr_enable = settings->bools.video_hdr_enable;
@ -3850,6 +3984,7 @@ void video_driver_frame(const void *data, unsigned width,
float scale = ((float)video_info.height / 480) float scale = ((float)video_info.height / 480)
* 0.50f * (DEFAULT_FONT_SIZE / video_info.font_size); * 0.50f * (DEFAULT_FONT_SIZE / video_info.font_size);
struct retro_system_av_info *av_info = &video_st->av_info; struct retro_system_av_info *av_info = &video_st->av_info;
unsigned rotation = retroarch_get_rotation();
unsigned red = 235; unsigned red = 235;
unsigned green = 235; unsigned green = 235;
unsigned blue = 235; unsigned blue = 235;
@ -3941,7 +4076,9 @@ void video_driver_frame(const void *data, unsigned width,
" FPS: %3.2f\n" " FPS: %3.2f\n"
" Sample Rate: %6.2f\n" " Sample Rate: %6.2f\n"
"VIDEO: %s\n" "VIDEO: %s\n"
" Viewport: %d x %d\n" " Viewport: %u x %u\n"
" - Scale: %u x %u\n"
" - Scale X/Y: %2.2f / %2.2f\n"
" Refresh: %5.2f hz\n" " Refresh: %5.2f hz\n"
" Frame Rate: %5.2f fps\n" " Frame Rate: %5.2f fps\n"
" Frame Time: %5.2f ms\n" " Frame Time: %5.2f ms\n"
@ -3967,6 +4104,10 @@ void video_driver_frame(const void *data, unsigned width,
video_st->current_video->ident, video_st->current_video->ident,
video_info.width, video_info.width,
video_info.height, video_info.height,
video_info.scale_width,
video_info.scale_height,
(float)video_info.scale_width / ((rotation % 2) ? (float)video_st->frame_cache_height : (float)video_st->frame_cache_width),
(float)video_info.scale_height / ((rotation % 2) ? (float)video_st->frame_cache_width : (float)video_st->frame_cache_height),
video_info.refresh_rate, video_info.refresh_rate,
last_fps, last_fps,
frame_time / 1000.0f, frame_time / 1000.0f,

View File

@ -405,6 +405,8 @@ typedef struct video_frame_info
unsigned crt_switch_resolution_super; unsigned crt_switch_resolution_super;
unsigned width; unsigned width;
unsigned height; unsigned height;
unsigned scale_width;
unsigned scale_height;
unsigned xmb_theme; unsigned xmb_theme;
unsigned xmb_color_theme; unsigned xmb_color_theme;
unsigned menu_shader_pipeline; unsigned menu_shader_pipeline;
@ -837,6 +839,8 @@ typedef struct
unsigned frame_cache_height; unsigned frame_cache_height;
unsigned width; unsigned width;
unsigned height; unsigned height;
unsigned scale_width;
unsigned scale_height;
float core_hz; float core_hz;
float aspect_ratio; float aspect_ratio;

View File

@ -2559,15 +2559,35 @@ MSG_HASH(
) )
MSG_HASH( MSG_HASH(
MENU_ENUM_SUBLABEL_VIDEO_SCALE_INTEGER, MENU_ENUM_SUBLABEL_VIDEO_SCALE_INTEGER,
"Scale video in integer steps only. The base size depends on system-reported geometry and aspect ratio. If 'Force Aspect Ratio' is not set, X/Y will be integer scaled independently." "Scale video in integer steps only. The base size depends on core-reported geometry and aspect ratio."
) )
MSG_HASH( MSG_HASH(
MENU_ENUM_LABEL_VALUE_VIDEO_SCALE_INTEGER_OVERSCALE, MENU_ENUM_LABEL_VALUE_VIDEO_SCALE_INTEGER_AXIS,
"Integer Scale Overscale" "Integer Scale Axis"
) )
MSG_HASH( MSG_HASH(
MENU_ENUM_SUBLABEL_VIDEO_SCALE_INTEGER_OVERSCALE, MENU_ENUM_SUBLABEL_VIDEO_SCALE_INTEGER_AXIS,
"Force integer scaling to round up to the next larger integer instead of rounding down." "Scale only height, or both height and width. Half steps apply to high resolution sources."
)
MSG_HASH(
MENU_ENUM_LABEL_VALUE_VIDEO_SCALE_INTEGER_SCALING,
"Integer Scale Scaling"
)
MSG_HASH(
MENU_ENUM_SUBLABEL_VIDEO_SCALE_INTEGER_SCALING,
"Round down or up to the next integer. 'Smart' drops to underscale when image is cropped too much."
)
MSG_HASH(
MENU_ENUM_LABEL_VALUE_VIDEO_SCALE_INTEGER_SCALING_UNDERSCALE,
"Underscale"
)
MSG_HASH(
MENU_ENUM_LABEL_VALUE_VIDEO_SCALE_INTEGER_SCALING_OVERSCALE,
"Overscale"
)
MSG_HASH(
MENU_ENUM_LABEL_VALUE_VIDEO_SCALE_INTEGER_SCALING_SMART,
"Smart"
) )
MSG_HASH( MSG_HASH(
MENU_ENUM_LABEL_VALUE_VIDEO_ASPECT_RATIO_INDEX, MENU_ENUM_LABEL_VALUE_VIDEO_ASPECT_RATIO_INDEX,

View File

@ -720,7 +720,8 @@ DEFAULT_SUBLABEL_MACRO(action_bind_sublabel_input_overlay_dpad_diag_sens, MENU_
DEFAULT_SUBLABEL_MACRO(action_bind_sublabel_input_overlay_abxy_diag_sens, MENU_ENUM_SUBLABEL_INPUT_OVERLAY_ABXY_DIAGONAL_SENSITIVITY) DEFAULT_SUBLABEL_MACRO(action_bind_sublabel_input_overlay_abxy_diag_sens, MENU_ENUM_SUBLABEL_INPUT_OVERLAY_ABXY_DIAGONAL_SENSITIVITY)
DEFAULT_SUBLABEL_MACRO(action_bind_sublabel_content_collection_list, MENU_ENUM_SUBLABEL_PLAYLISTS_TAB) DEFAULT_SUBLABEL_MACRO(action_bind_sublabel_content_collection_list, MENU_ENUM_SUBLABEL_PLAYLISTS_TAB)
DEFAULT_SUBLABEL_MACRO(action_bind_sublabel_video_scale_integer, MENU_ENUM_SUBLABEL_VIDEO_SCALE_INTEGER) DEFAULT_SUBLABEL_MACRO(action_bind_sublabel_video_scale_integer, MENU_ENUM_SUBLABEL_VIDEO_SCALE_INTEGER)
DEFAULT_SUBLABEL_MACRO(action_bind_sublabel_video_scale_integer_overscale, MENU_ENUM_SUBLABEL_VIDEO_SCALE_INTEGER_OVERSCALE) DEFAULT_SUBLABEL_MACRO(action_bind_sublabel_video_scale_integer_axis, MENU_ENUM_SUBLABEL_VIDEO_SCALE_INTEGER_AXIS)
DEFAULT_SUBLABEL_MACRO(action_bind_sublabel_video_scale_integer_scaling, MENU_ENUM_SUBLABEL_VIDEO_SCALE_INTEGER_SCALING)
DEFAULT_SUBLABEL_MACRO(action_bind_sublabel_video_gpu_screenshot, MENU_ENUM_SUBLABEL_VIDEO_GPU_SCREENSHOT) DEFAULT_SUBLABEL_MACRO(action_bind_sublabel_video_gpu_screenshot, MENU_ENUM_SUBLABEL_VIDEO_GPU_SCREENSHOT)
DEFAULT_SUBLABEL_MACRO(action_bind_sublabel_video_rotation, MENU_ENUM_SUBLABEL_VIDEO_ROTATION) DEFAULT_SUBLABEL_MACRO(action_bind_sublabel_video_rotation, MENU_ENUM_SUBLABEL_VIDEO_ROTATION)
DEFAULT_SUBLABEL_MACRO(action_bind_sublabel_screen_orientation, MENU_ENUM_SUBLABEL_SCREEN_ORIENTATION) DEFAULT_SUBLABEL_MACRO(action_bind_sublabel_screen_orientation, MENU_ENUM_SUBLABEL_SCREEN_ORIENTATION)
@ -4243,8 +4244,11 @@ int menu_cbs_init_bind_sublabel(menu_file_list_cbs_t *cbs,
case MENU_ENUM_LABEL_VIDEO_SCALE_INTEGER: case MENU_ENUM_LABEL_VIDEO_SCALE_INTEGER:
BIND_ACTION_SUBLABEL(cbs, action_bind_sublabel_video_scale_integer); BIND_ACTION_SUBLABEL(cbs, action_bind_sublabel_video_scale_integer);
break; break;
case MENU_ENUM_LABEL_VIDEO_SCALE_INTEGER_OVERSCALE: case MENU_ENUM_LABEL_VIDEO_SCALE_INTEGER_AXIS:
BIND_ACTION_SUBLABEL(cbs, action_bind_sublabel_video_scale_integer_overscale); BIND_ACTION_SUBLABEL(cbs, action_bind_sublabel_video_scale_integer_axis);
break;
case MENU_ENUM_LABEL_VIDEO_SCALE_INTEGER_SCALING:
BIND_ACTION_SUBLABEL(cbs, action_bind_sublabel_video_scale_integer_scaling);
break; break;
case MENU_ENUM_LABEL_PLAYLISTS_TAB: case MENU_ENUM_LABEL_PLAYLISTS_TAB:
BIND_ACTION_SUBLABEL(cbs, action_bind_sublabel_content_collection_list); BIND_ACTION_SUBLABEL(cbs, action_bind_sublabel_content_collection_list);

View File

@ -9803,27 +9803,13 @@ unsigned menu_displaylist_build_list(
PARSE_ONLY_BOOL, false) == 0) PARSE_ONLY_BOOL, false) == 0)
count++; count++;
if (MENU_DISPLAYLIST_PARSE_SETTINGS_ENUM(list, if (MENU_DISPLAYLIST_PARSE_SETTINGS_ENUM(list,
MENU_ENUM_LABEL_VIDEO_SCALE_INTEGER_OVERSCALE, MENU_ENUM_LABEL_VIDEO_SCALE_INTEGER_AXIS,
PARSE_ONLY_BOOL, false) == 0) PARSE_ONLY_UINT, false) == 0)
count++; count++;
if (MENU_DISPLAYLIST_PARSE_SETTINGS_ENUM(list, if (MENU_DISPLAYLIST_PARSE_SETTINGS_ENUM(list,
MENU_ENUM_LABEL_VIDEO_VIEWPORT_BIAS_X, MENU_ENUM_LABEL_VIDEO_SCALE_INTEGER_SCALING,
PARSE_ONLY_FLOAT, false) == 0) PARSE_ONLY_UINT, false) == 0)
count++; count++;
if (MENU_DISPLAYLIST_PARSE_SETTINGS_ENUM(list,
MENU_ENUM_LABEL_VIDEO_VIEWPORT_BIAS_Y,
PARSE_ONLY_FLOAT, false) == 0)
count++;
#if defined(RARCH_MOBILE)
if (MENU_DISPLAYLIST_PARSE_SETTINGS_ENUM(list,
MENU_ENUM_LABEL_VIDEO_VIEWPORT_BIAS_PORTRAIT_X,
PARSE_ONLY_FLOAT, false) == 0)
count++;
if (MENU_DISPLAYLIST_PARSE_SETTINGS_ENUM(list,
MENU_ENUM_LABEL_VIDEO_VIEWPORT_BIAS_PORTRAIT_Y,
PARSE_ONLY_FLOAT, false) == 0)
count++;
#endif
if (MENU_DISPLAYLIST_PARSE_SETTINGS_ENUM(list, if (MENU_DISPLAYLIST_PARSE_SETTINGS_ENUM(list,
MENU_ENUM_LABEL_VIDEO_ASPECT_RATIO_INDEX, MENU_ENUM_LABEL_VIDEO_ASPECT_RATIO_INDEX,
PARSE_ONLY_UINT, false) == 0) PARSE_ONLY_UINT, false) == 0)
@ -9857,6 +9843,24 @@ unsigned menu_displaylist_build_list(
default: default:
break; break;
} }
if (MENU_DISPLAYLIST_PARSE_SETTINGS_ENUM(list,
MENU_ENUM_LABEL_VIDEO_VIEWPORT_BIAS_X,
PARSE_ONLY_FLOAT, false) == 0)
count++;
if (MENU_DISPLAYLIST_PARSE_SETTINGS_ENUM(list,
MENU_ENUM_LABEL_VIDEO_VIEWPORT_BIAS_Y,
PARSE_ONLY_FLOAT, false) == 0)
count++;
#if defined(RARCH_MOBILE)
if (MENU_DISPLAYLIST_PARSE_SETTINGS_ENUM(list,
MENU_ENUM_LABEL_VIDEO_VIEWPORT_BIAS_PORTRAIT_X,
PARSE_ONLY_FLOAT, false) == 0)
count++;
if (MENU_DISPLAYLIST_PARSE_SETTINGS_ENUM(list,
MENU_ENUM_LABEL_VIDEO_VIEWPORT_BIAS_PORTRAIT_Y,
PARSE_ONLY_FLOAT, false) == 0)
count++;
#endif
} }
if (MENU_DISPLAYLIST_PARSE_SETTINGS_ENUM(list, if (MENU_DISPLAYLIST_PARSE_SETTINGS_ENUM(list,

View File

@ -7346,6 +7346,59 @@ static void setting_get_string_representation_uint_quit_on_close_content(
} }
} }
static void setting_get_string_representation_uint_video_scale_integer_axis(
rarch_setting_t *setting,
char *s, size_t len)
{
if (!setting)
return;
switch (*setting->value.target.unsigned_integer)
{
default:
case VIDEO_SCALE_INTEGER_AXIS_Y:
strlcpy(s, "Y", len);
break;
case VIDEO_SCALE_INTEGER_AXIS_Y_X:
strlcpy(s, "Y + X", len);
break;
case VIDEO_SCALE_INTEGER_AXIS_Y_XHALF:
strlcpy(s, "Y + X.5", len);
break;
case VIDEO_SCALE_INTEGER_AXIS_YHALF_XHALF:
strlcpy(s, "Y.5 + X.5", len);
break;
case VIDEO_SCALE_INTEGER_AXIS_X:
strlcpy(s, "X", len);
break;
case VIDEO_SCALE_INTEGER_AXIS_XHALF:
strlcpy(s, "X.5", len);
break;
}
}
static void setting_get_string_representation_uint_video_scale_integer_scaling(
rarch_setting_t *setting,
char *s, size_t len)
{
if (!setting)
return;
switch (*setting->value.target.unsigned_integer)
{
default:
case VIDEO_SCALE_INTEGER_SCALING_UNDERSCALE:
strlcpy(s, msg_hash_to_str(MENU_ENUM_LABEL_VALUE_VIDEO_SCALE_INTEGER_SCALING_UNDERSCALE), len);
break;
case VIDEO_SCALE_INTEGER_SCALING_OVERSCALE:
strlcpy(s, msg_hash_to_str(MENU_ENUM_LABEL_VALUE_VIDEO_SCALE_INTEGER_SCALING_OVERSCALE), len);
break;
case VIDEO_SCALE_INTEGER_SCALING_SMART:
strlcpy(s, msg_hash_to_str(MENU_ENUM_LABEL_VALUE_VIDEO_SCALE_INTEGER_SCALING_SMART), len);
break;
}
}
static void setting_get_string_representation_uint_playlist_show_history_icons( static void setting_get_string_representation_uint_playlist_show_history_icons(
rarch_setting_t *setting, rarch_setting_t *setting,
char *s, size_t len) char *s, size_t len)
@ -13579,23 +13632,41 @@ static bool setting_append_list(
list_info, list_info,
CMD_EVENT_VIDEO_APPLY_STATE_CHANGES); CMD_EVENT_VIDEO_APPLY_STATE_CHANGES);
CONFIG_BOOL( CONFIG_UINT(
list, list_info, list, list_info,
&settings->bools.video_scale_integer_overscale, &settings->uints.video_scale_integer_axis,
MENU_ENUM_LABEL_VIDEO_SCALE_INTEGER_OVERSCALE, MENU_ENUM_LABEL_VIDEO_SCALE_INTEGER_AXIS,
MENU_ENUM_LABEL_VALUE_VIDEO_SCALE_INTEGER_OVERSCALE, MENU_ENUM_LABEL_VALUE_VIDEO_SCALE_INTEGER_AXIS,
DEFAULT_SCALE_INTEGER_OVERSCALE, DEFAULT_SCALE_INTEGER_AXIS,
MENU_ENUM_LABEL_VALUE_OFF,
MENU_ENUM_LABEL_VALUE_ON,
&group_info, &group_info,
&subgroup_info, &subgroup_info,
parent_group, parent_group,
general_write_handler, general_write_handler,
general_read_handler, general_read_handler);
SD_FLAG_NONE); (*list)[list_info->index - 1].action_ok = &setting_action_ok_uint;
(*list)[list_info->index - 1].action_ok = setting_bool_action_left_with_refresh; (*list)[list_info->index - 1].get_string_representation =
(*list)[list_info->index - 1].action_left = setting_bool_action_left_with_refresh; &setting_get_string_representation_uint_video_scale_integer_axis;
(*list)[list_info->index - 1].action_right = setting_bool_action_right_with_refresh; menu_settings_list_current_add_range(list, list_info, 0, VIDEO_SCALE_INTEGER_AXIS_LAST - 1, 1, true, true);
MENU_SETTINGS_LIST_CURRENT_ADD_CMD(
list,
list_info,
CMD_EVENT_VIDEO_APPLY_STATE_CHANGES);
CONFIG_UINT(
list, list_info,
&settings->uints.video_scale_integer_scaling,
MENU_ENUM_LABEL_VIDEO_SCALE_INTEGER_SCALING,
MENU_ENUM_LABEL_VALUE_VIDEO_SCALE_INTEGER_SCALING,
DEFAULT_SCALE_INTEGER_SCALING,
&group_info,
&subgroup_info,
parent_group,
general_write_handler,
general_read_handler);
(*list)[list_info->index - 1].action_ok = &setting_action_ok_uint;
(*list)[list_info->index - 1].get_string_representation =
&setting_get_string_representation_uint_video_scale_integer_scaling;
menu_settings_list_current_add_range(list, list_info, 0, VIDEO_SCALE_INTEGER_SCALING_LAST - 1, 1, true, true);
MENU_SETTINGS_LIST_CURRENT_ADD_CMD( MENU_SETTINGS_LIST_CURRENT_ADD_CMD(
list, list,
list_info, list_info,

View File

@ -1450,7 +1450,12 @@ enum msg_hash_enums
MENU_LABEL(VIDEO_NOTCH_WRITE_OVER), MENU_LABEL(VIDEO_NOTCH_WRITE_OVER),
MENU_LABEL(VIDEO_SCALE_INTEGER), MENU_LABEL(VIDEO_SCALE_INTEGER),
MENU_LABEL(VIDEO_SCALE_INTEGER_OVERSCALE), MENU_LABEL(VIDEO_SCALE_INTEGER_AXIS),
MENU_LABEL(VIDEO_SCALE_INTEGER_SCALING),
MENU_LABEL(VIDEO_SCALE_INTEGER_OVERSCALE), /* deprecated */
MENU_ENUM_LABEL_VALUE_VIDEO_SCALE_INTEGER_SCALING_UNDERSCALE,
MENU_ENUM_LABEL_VALUE_VIDEO_SCALE_INTEGER_SCALING_OVERSCALE,
MENU_ENUM_LABEL_VALUE_VIDEO_SCALE_INTEGER_SCALING_SMART,
MENU_LABEL(VIDEO_VIEWPORT_CUSTOM_X), MENU_LABEL(VIDEO_VIEWPORT_CUSTOM_X),
MENU_LABEL(VIDEO_VIEWPORT_CUSTOM_Y), MENU_LABEL(VIDEO_VIEWPORT_CUSTOM_Y),
MENU_LABEL(VIDEO_VIEWPORT_CUSTOM_WIDTH), MENU_LABEL(VIDEO_VIEWPORT_CUSTOM_WIDTH),