mirror of
https://github.com/libretro/RetroArch
synced 2025-03-29 22:20:21 +00:00
(RGUI) Allow selection of thumbnail downscaling method
This commit is contained in:
parent
7ba6ffdfbe
commit
bd56e1e29c
@ -752,6 +752,8 @@ static const unsigned menu_timedate_style = 5;
|
||||
|
||||
static const bool xmb_vertical_thumbnails = false;
|
||||
|
||||
static unsigned rgui_thumbnail_downscaler = RGUI_THUMB_SCALE_POINT;
|
||||
|
||||
#ifdef IOS
|
||||
static const bool ui_companion_start_on_boot = false;
|
||||
#else
|
||||
|
@ -1654,6 +1654,7 @@ static struct config_uint_setting *populate_settings_uint(settings_t *settings,
|
||||
SETTING_UINT("menu_thumbnails", &settings->uints.menu_thumbnails, true, menu_thumbnails_default, false);
|
||||
SETTING_UINT("menu_timedate_style", &settings->uints.menu_timedate_style, true, menu_timedate_style, false);
|
||||
SETTING_UINT("rgui_menu_color_theme", &settings->uints.menu_rgui_color_theme, true, rgui_color_theme, false);
|
||||
SETTING_UINT("rgui_thumbnail_downscaler", &settings->uints.menu_rgui_thumbnail_downscaler, true, rgui_thumbnail_downscaler, false);
|
||||
#ifdef HAVE_LIBNX
|
||||
SETTING_UINT("split_joycon_p1", &settings->uints.input_split_joycon[0], true, 0, false);
|
||||
SETTING_UINT("split_joycon_p2", &settings->uints.input_split_joycon[1], true, 0, false);
|
||||
|
@ -403,6 +403,7 @@ typedef struct settings
|
||||
unsigned menu_timedate_style;
|
||||
unsigned menu_thumbnails;
|
||||
unsigned menu_left_thumbnails;
|
||||
unsigned menu_rgui_thumbnail_downscaler;
|
||||
unsigned menu_dpi_override_value;
|
||||
unsigned menu_entry_normal_color;
|
||||
unsigned menu_entry_hover_color;
|
||||
|
@ -1117,6 +1117,8 @@ MSG_HASH(MENU_ENUM_LABEL_LEFT_THUMBNAILS,
|
||||
"left thumbnails")
|
||||
MSG_HASH(MENU_ENUM_LABEL_XMB_VERTICAL_THUMBNAILS,
|
||||
"xmb_vertical_thumbnails")
|
||||
MSG_HASH(MENU_ENUM_LABEL_MENU_RGUI_THUMBNAIL_DOWNSCALER,
|
||||
"rgui_thumbnail_downscaler")
|
||||
MSG_HASH(MENU_ENUM_LABEL_THUMBNAILS_DIRECTORY,
|
||||
"thumbnails_directory")
|
||||
MSG_HASH(MENU_ENUM_LABEL_THUMBNAILS_UPDATER_LIST,
|
||||
|
@ -2934,6 +2934,22 @@ MSG_HASH(
|
||||
MENU_ENUM_LABEL_VALUE_XMB_VERTICAL_THUMBNAILS,
|
||||
"Thumbnails Vertical Disposition"
|
||||
)
|
||||
MSG_HASH(
|
||||
MENU_ENUM_LABEL_VALUE_MENU_RGUI_THUMBNAIL_DOWNSCALER,
|
||||
"Thumbnail Downscaling Method"
|
||||
)
|
||||
MSG_HASH(
|
||||
MENU_ENUM_LABEL_VALUE_RGUI_THUMB_SCALE_POINT,
|
||||
"Nearest Neighbour (Fast)"
|
||||
)
|
||||
MSG_HASH(
|
||||
MENU_ENUM_LABEL_VALUE_RGUI_THUMB_SCALE_BILINEAR,
|
||||
"Bilinear"
|
||||
)
|
||||
MSG_HASH(
|
||||
MENU_ENUM_LABEL_VALUE_RGUI_THUMB_SCALE_SINC,
|
||||
"Sinc/Lanczos3 (Slow)"
|
||||
)
|
||||
MSG_HASH(
|
||||
MENU_ENUM_LABEL_VALUE_THUMBNAILS_DIRECTORY,
|
||||
"Thumbnails"
|
||||
|
@ -53,6 +53,7 @@
|
||||
/* Thumbnail additions */
|
||||
#include <streams/file_stream.h>
|
||||
#include "../../tasks/tasks_internal.h"
|
||||
#include <gfx/scaler/scaler.h>
|
||||
|
||||
#define RGUI_TERM_START_X(width) (width / 21)
|
||||
#define RGUI_TERM_START_Y(height) (height / 9)
|
||||
@ -422,6 +423,7 @@ typedef struct
|
||||
char *thumbnail_path;
|
||||
char *thumbnail_playlist;
|
||||
uint32_t thumbnail_queue_size;
|
||||
struct scaler_ctx image_scaler;
|
||||
} rgui_t;
|
||||
|
||||
#define THUMB_MAX_WIDTH 320
|
||||
@ -589,14 +591,12 @@ static void request_thumbnail(rgui_t *rgui, const char *path)
|
||||
}
|
||||
}
|
||||
|
||||
static bool downscale_thumbnail(struct texture_image *image_src, struct texture_image *image_dst)
|
||||
static bool downscale_thumbnail(rgui_t *rgui, struct texture_image *image_src, struct texture_image *image_dst)
|
||||
{
|
||||
uint32_t x_ratio, y_ratio;
|
||||
unsigned x_src, y_src;
|
||||
unsigned x_dst, y_dst;
|
||||
static const float display_aspect_ratio = (float)THUMB_MAX_WIDTH / (float)THUMB_MAX_HEIGHT;
|
||||
settings_t *settings = config_get_ptr();
|
||||
|
||||
/* Determine output dimensions */
|
||||
static const float display_aspect_ratio = (float)THUMB_MAX_WIDTH / (float)THUMB_MAX_HEIGHT;
|
||||
float aspect_ratio = (float)image_src->width / (float)image_src->height;
|
||||
if (aspect_ratio > display_aspect_ratio)
|
||||
{
|
||||
@ -620,19 +620,65 @@ static bool downscale_thumbnail(struct texture_image *image_src, struct texture_
|
||||
if (!image_dst->pixels)
|
||||
return false;
|
||||
|
||||
/* Perform nearest neighbour resampling */
|
||||
x_ratio = ((image_src->width << 16) / image_dst->width);
|
||||
y_ratio = ((image_src->height << 16) / image_dst->height);
|
||||
|
||||
for (y_dst = 0; y_dst < image_dst->height; y_dst++)
|
||||
/* Determine scaling method */
|
||||
if (settings->uints.menu_rgui_thumbnail_downscaler == RGUI_THUMB_SCALE_POINT)
|
||||
{
|
||||
y_src = (y_dst * y_ratio) >> 16;
|
||||
for (x_dst = 0; x_dst < image_dst->width; x_dst++)
|
||||
uint32_t x_ratio, y_ratio;
|
||||
unsigned x_src, y_src;
|
||||
unsigned x_dst, y_dst;
|
||||
|
||||
/* Perform nearest neighbour resampling
|
||||
* > Fastest method, minimal performance impact */
|
||||
x_ratio = ((image_src->width << 16) / image_dst->width);
|
||||
y_ratio = ((image_src->height << 16) / image_dst->height);
|
||||
|
||||
for (y_dst = 0; y_dst < image_dst->height; y_dst++)
|
||||
{
|
||||
x_src = (x_dst * x_ratio) >> 16;
|
||||
image_dst->pixels[(y_dst * image_dst->width) + x_dst] = image_src->pixels[(y_src * image_src->width) + x_src];
|
||||
y_src = (y_dst * y_ratio) >> 16;
|
||||
for (x_dst = 0; x_dst < image_dst->width; x_dst++)
|
||||
{
|
||||
x_src = (x_dst * x_ratio) >> 16;
|
||||
image_dst->pixels[(y_dst * image_dst->width) + x_dst] = image_src->pixels[(y_src * image_src->width) + x_src];
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Perform either bilinear or sinc (Lanczos3) resampling
|
||||
* using libretro-common scaler
|
||||
* > Better quality, but substantially higher performance
|
||||
* impact - although not an issue on desktop-class
|
||||
* hardware */
|
||||
rgui->image_scaler.in_width = image_src->width;
|
||||
rgui->image_scaler.in_height = image_src->height;
|
||||
rgui->image_scaler.in_stride = image_src->width * sizeof(uint32_t);
|
||||
rgui->image_scaler.in_fmt = SCALER_FMT_ARGB8888;
|
||||
|
||||
rgui->image_scaler.out_width = image_dst->width;
|
||||
rgui->image_scaler.out_height = image_dst->height;
|
||||
rgui->image_scaler.out_stride = image_dst->width * sizeof(uint32_t);
|
||||
rgui->image_scaler.out_fmt = SCALER_FMT_ARGB8888;
|
||||
|
||||
rgui->image_scaler.scaler_type = (settings->uints.menu_rgui_thumbnail_downscaler == RGUI_THUMB_SCALE_SINC) ?
|
||||
SCALER_TYPE_SINC : SCALER_TYPE_BILINEAR;
|
||||
|
||||
/* This reset is redundant, since scaler_ctx_gen_filter()
|
||||
* calls it - but do it anyway in case the
|
||||
* scaler_ctx_gen_filter() internals ever change... */
|
||||
scaler_ctx_gen_reset(&rgui->image_scaler);
|
||||
if(!scaler_ctx_gen_filter(&rgui->image_scaler))
|
||||
{
|
||||
/* Could be leftovers if scaler_ctx_gen_filter()
|
||||
* fails, so reset just in case... */
|
||||
scaler_ctx_gen_reset(&rgui->image_scaler);
|
||||
return false;
|
||||
}
|
||||
|
||||
scaler_ctx_scale(&rgui->image_scaler, image_dst->pixels, image_src->pixels);
|
||||
/* Reset again - don't want to leave anything hanging around
|
||||
* if the user switches back to nearest neighbour scaling */
|
||||
scaler_ctx_gen_reset(&rgui->image_scaler);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
@ -668,7 +714,7 @@ static void process_thumbnail(rgui_t *rgui, struct texture_image *image_src)
|
||||
/* Downscale thumbnail if it exceeds maximum size limits */
|
||||
if ((image_src->width > THUMB_MAX_WIDTH) || (image_src->height > THUMB_MAX_HEIGHT))
|
||||
{
|
||||
if (!downscale_thumbnail(image_src, &image_resampled))
|
||||
if (!downscale_thumbnail(rgui, image_src, &image_resampled))
|
||||
return;
|
||||
image = &image_resampled;
|
||||
}
|
||||
|
@ -6119,6 +6119,10 @@ bool menu_displaylist_ctl(enum menu_displaylist_ctl_state type, menu_displaylist
|
||||
MENU_ENUM_LABEL_XMB_VERTICAL_THUMBNAILS,
|
||||
PARSE_ONLY_BOOL, false) == 0)
|
||||
count++;
|
||||
if (menu_displaylist_parse_settings_enum(menu, info,
|
||||
MENU_ENUM_LABEL_MENU_RGUI_THUMBNAIL_DOWNSCALER,
|
||||
PARSE_ONLY_UINT, false) == 0)
|
||||
count++;
|
||||
|
||||
if (count == 0)
|
||||
menu_entries_append_enum(info->list,
|
||||
|
@ -383,6 +383,14 @@ enum menu_toggle_reason
|
||||
MENU_TOGGLE_REASON_MESSAGE
|
||||
};
|
||||
|
||||
enum rgui_thumbnail_scaler
|
||||
{
|
||||
RGUI_THUMB_SCALE_POINT = 0,
|
||||
RGUI_THUMB_SCALE_BILINEAR,
|
||||
RGUI_THUMB_SCALE_SINC,
|
||||
RGUI_THUMB_SCALE_LAST
|
||||
};
|
||||
|
||||
typedef uintptr_t menu_texture_item;
|
||||
|
||||
typedef struct menu_display_ctx_clearcolor
|
||||
|
@ -786,6 +786,36 @@ static void setting_get_string_representation_uint_rgui_menu_color_theme(
|
||||
}
|
||||
}
|
||||
|
||||
static void setting_get_string_representation_uint_rgui_thumbnail_scaler(
|
||||
rarch_setting_t *setting,
|
||||
char *s, size_t len)
|
||||
{
|
||||
if (!setting)
|
||||
return;
|
||||
|
||||
switch (*setting->value.target.unsigned_integer)
|
||||
{
|
||||
case RGUI_THUMB_SCALE_POINT:
|
||||
strlcpy(s,
|
||||
msg_hash_to_str(
|
||||
MENU_ENUM_LABEL_VALUE_RGUI_THUMB_SCALE_POINT),
|
||||
len);
|
||||
break;
|
||||
case RGUI_THUMB_SCALE_BILINEAR:
|
||||
strlcpy(s,
|
||||
msg_hash_to_str(
|
||||
MENU_ENUM_LABEL_VALUE_RGUI_THUMB_SCALE_BILINEAR),
|
||||
len);
|
||||
break;
|
||||
case RGUI_THUMB_SCALE_SINC:
|
||||
strlcpy(s,
|
||||
msg_hash_to_str(
|
||||
MENU_ENUM_LABEL_VALUE_RGUI_THUMB_SCALE_SINC),
|
||||
len);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void setting_get_string_representation_uint_xmb_icon_theme(
|
||||
rarch_setting_t *setting,
|
||||
char *s, size_t len)
|
||||
@ -8741,6 +8771,25 @@ static bool setting_append_list(
|
||||
menu_settings_list_current_add_range(list, list_info, 0, 3, 1, true, true);
|
||||
}
|
||||
|
||||
if (string_is_equal(settings->arrays.menu_driver, "rgui"))
|
||||
{
|
||||
CONFIG_UINT(
|
||||
list, list_info,
|
||||
&settings->uints.menu_rgui_thumbnail_downscaler,
|
||||
MENU_ENUM_LABEL_MENU_RGUI_THUMBNAIL_DOWNSCALER,
|
||||
MENU_ENUM_LABEL_VALUE_MENU_RGUI_THUMBNAIL_DOWNSCALER,
|
||||
rgui_thumbnail_downscaler,
|
||||
&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_rgui_thumbnail_scaler;
|
||||
menu_settings_list_current_add_range(list, list_info, 0, RGUI_THUMB_SCALE_LAST-1, 1, true, true);
|
||||
}
|
||||
|
||||
if (string_is_equal(settings->arrays.menu_driver, "xmb") || string_is_equal(settings->arrays.menu_driver, "ozone"))
|
||||
{
|
||||
CONFIG_UINT(
|
||||
|
@ -883,6 +883,7 @@ enum msg_hash_enums
|
||||
MENU_LABEL(THUMBNAILS),
|
||||
MENU_LABEL(LEFT_THUMBNAILS),
|
||||
MENU_LABEL(XMB_VERTICAL_THUMBNAILS),
|
||||
MENU_LABEL(MENU_RGUI_THUMBNAIL_DOWNSCALER),
|
||||
MENU_LABEL(TIMEDATE_ENABLE),
|
||||
MENU_LABEL(TIMEDATE_STYLE),
|
||||
MENU_LABEL(BATTERY_LEVEL_ENABLE),
|
||||
@ -1943,6 +1944,10 @@ enum msg_hash_enums
|
||||
MENU_ENUM_LABEL_VALUE_THUMBNAIL_MODE_SCREENSHOTS,
|
||||
MENU_ENUM_LABEL_VALUE_THUMBNAIL_MODE_TITLE_SCREENS,
|
||||
|
||||
MENU_ENUM_LABEL_VALUE_RGUI_THUMB_SCALE_POINT,
|
||||
MENU_ENUM_LABEL_VALUE_RGUI_THUMB_SCALE_BILINEAR,
|
||||
MENU_ENUM_LABEL_VALUE_RGUI_THUMB_SCALE_SINC,
|
||||
|
||||
/* Callback strings */
|
||||
MENU_ENUM_LABEL_CB_CORE_CONTENT_DIRS_LIST,
|
||||
MENU_ENUM_LABEL_CB_CORE_CONTENT_DOWNLOAD,
|
||||
|
Loading…
x
Reference in New Issue
Block a user