Merge pull request #11340 from jdgleaver/overlay-autoscale

Add option to scale overlays automatically (with aspect ratio correction)
This commit is contained in:
Autechre 2020-09-17 21:09:43 +02:00 committed by GitHub
commit 27bb73dd37
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
13 changed files with 326 additions and 98 deletions

View File

@ -385,6 +385,7 @@
#define DEFAULT_INPUT_OVERLAY_SCALE_PORTRAIT 1.0f
#define DEFAULT_INPUT_OVERLAY_ASPECT_ADJUST_PORTRAIT 0.0f
#define DEFAULT_INPUT_OVERLAY_X_SEPARATION_PORTRAIT 0.0f
#define DEFAULT_INPUT_OVERLAY_Y_SEPARATION_PORTRAIT 0.0f
#define DEFAULT_INPUT_OVERLAY_X_OFFSET_PORTRAIT 0.0f
#define DEFAULT_INPUT_OVERLAY_Y_OFFSET_PORTRAIT 0.0f
@ -394,6 +395,12 @@
#define DEFAULT_OVERLAY_AUTO_ROTATE false
#endif
#if defined(RARCH_MOBILE)
#define DEFAULT_INPUT_OVERLAY_AUTO_SCALE true
#else
#define DEFAULT_INPUT_OVERLAY_AUTO_SCALE false
#endif
#include "runtime_file.h"
#ifdef HAVE_MENU
#include "menu/menu_driver.h"

View File

@ -1670,6 +1670,7 @@ static struct config_bool_setting *populate_settings_bool(
SETTING_BOOL("input_overlay_hide_when_gamepad_connected", &settings->bools.input_overlay_hide_when_gamepad_connected, true, DEFAULT_OVERLAY_HIDE_WHEN_GAMEPAD_CONNECTED, false);
SETTING_BOOL("input_overlay_show_mouse_cursor", &settings->bools.input_overlay_show_mouse_cursor, true, DEFAULT_OVERLAY_SHOW_MOUSE_CURSOR, false);
SETTING_BOOL("input_overlay_auto_rotate", &settings->bools.input_overlay_auto_rotate, true, DEFAULT_OVERLAY_AUTO_ROTATE, false);
SETTING_BOOL("input_overlay_auto_scale", &settings->bools.input_overlay_auto_scale, true, DEFAULT_INPUT_OVERLAY_AUTO_SCALE, false);
#endif
#ifdef HAVE_VIDEO_LAYOUT
SETTING_BOOL("video_layout_enable", &settings->bools.video_layout_enable, true, true, false);
@ -1789,6 +1790,7 @@ static struct config_float_setting *populate_settings_float(
SETTING_FLOAT("input_overlay_scale_portrait", &settings->floats.input_overlay_scale_portrait, true, DEFAULT_INPUT_OVERLAY_SCALE_PORTRAIT, false);
SETTING_FLOAT("input_overlay_aspect_adjust_portrait", &settings->floats.input_overlay_aspect_adjust_portrait, true, DEFAULT_INPUT_OVERLAY_ASPECT_ADJUST_PORTRAIT, false);
SETTING_FLOAT("input_overlay_x_separation_portrait", &settings->floats.input_overlay_x_separation_portrait, true, DEFAULT_INPUT_OVERLAY_X_SEPARATION_PORTRAIT, false);
SETTING_FLOAT("input_overlay_y_separation_portrait", &settings->floats.input_overlay_y_separation_portrait, true, DEFAULT_INPUT_OVERLAY_Y_SEPARATION_PORTRAIT, false);
SETTING_FLOAT("input_overlay_x_offset_portrait", &settings->floats.input_overlay_x_offset_portrait, true, DEFAULT_INPUT_OVERLAY_X_OFFSET_PORTRAIT, false);
SETTING_FLOAT("input_overlay_y_offset_portrait", &settings->floats.input_overlay_y_offset_portrait, true, DEFAULT_INPUT_OVERLAY_Y_OFFSET_PORTRAIT, false);
#endif

View File

@ -312,6 +312,7 @@ typedef struct settings
float input_overlay_scale_portrait;
float input_overlay_aspect_adjust_portrait;
float input_overlay_x_separation_portrait;
float input_overlay_y_separation_portrait;
float input_overlay_x_offset_portrait;
float input_overlay_y_offset_portrait;
@ -504,6 +505,7 @@ typedef struct settings
bool input_overlay_show_physical_inputs;
bool input_overlay_show_mouse_cursor;
bool input_overlay_auto_rotate;
bool input_overlay_auto_scale;
bool input_descriptor_label_show;
bool input_descriptor_hide_unbound;
bool input_menu_swap_ok_cancel_buttons;

View File

@ -120,6 +120,7 @@ struct overlay
float mod_x, mod_y, mod_w, mod_h;
float x, y, w, h;
float center_x, center_y;
float aspect_ratio;
struct
{
@ -154,6 +155,8 @@ struct overlay
bool full_screen;
bool block_scale;
bool block_x_separation;
bool block_y_separation;
char name[64];
};
@ -211,8 +214,22 @@ typedef struct
float scale_portrait;
float aspect_adjust_portrait;
float x_separation_portrait;
float y_separation_portrait;
float x_offset_portrait;
float y_offset_portrait;
bool auto_scale;
} overlay_layout_desc_t;
/* Holds derived overlay layout information
* for a specific display orientation */
typedef struct
{
float x_scale;
float y_scale;
float x_separation;
float y_separation;
float x_offset;
float y_offset;
} overlay_layout_t;
typedef struct overlay_desc overlay_desc_t;
@ -225,7 +242,7 @@ typedef struct
struct overlay *active;
size_t size;
float overlay_opacity;
overlay_layout_t layout;
overlay_layout_desc_t layout_desc;
bool overlay_enable;
bool hide_in_menu;
bool hide_when_gamepad_connected;

View File

@ -1420,6 +1420,10 @@ MSG_HASH(
MENU_ENUM_LABEL_INPUT_OVERLAY_AUTO_ROTATE,
"input_overlay_auto_rotate"
)
MSG_HASH(
MENU_ENUM_LABEL_INPUT_OVERLAY_AUTO_SCALE,
"input_overlay_auto_scale"
)
MSG_HASH(
MENU_ENUM_LABEL_INPUT_PLAYER_ANALOG_DPAD_MODE,
"input_player%u_analog_dpad_mode"
@ -2032,6 +2036,10 @@ MSG_HASH(
MENU_ENUM_LABEL_OVERLAY_X_SEPARATION_PORTRAIT,
"input_overlay_x_separation_portrait"
)
MSG_HASH(
MENU_ENUM_LABEL_OVERLAY_Y_SEPARATION_PORTRAIT,
"input_overlay_y_separation_portrait"
)
MSG_HASH(
MENU_ENUM_LABEL_OVERLAY_X_OFFSET_PORTRAIT,
"input_overlay_x_offset_portrait"

View File

@ -3314,6 +3314,14 @@ MSG_HASH(
MENU_ENUM_SUBLABEL_INPUT_OVERLAY_AUTO_ROTATE,
"If supported by current overlay, automatically rotate layout to match screen orientation/aspect ratio."
)
MSG_HASH(
MENU_ENUM_LABEL_VALUE_INPUT_OVERLAY_AUTO_SCALE,
"Auto-Scale Overlay"
)
MSG_HASH(
MENU_ENUM_SUBLABEL_INPUT_OVERLAY_AUTO_SCALE,
"Automatically adjust overlay scale and UI element spacing to match screen aspect ratio. Produces best results with controller overlays."
)
MSG_HASH(
MENU_ENUM_LABEL_VALUE_OVERLAY,
"Overlay"
@ -3360,7 +3368,7 @@ MSG_HASH(
)
MSG_HASH(
MENU_ENUM_SUBLABEL_OVERLAY_X_SEPARATION_LANDSCAPE,
"Adjust the spacing between UI elements in the left and right halves of an overlay when using landscape display orientations. Positive values increase (while negative values decrease) the separation of the two halves."
"If supported by current preset, adjusts the spacing between UI elements in the left and right halves of an overlay when using landscape display orientations. Positive values increase (while negative values decrease) the separation of the two halves."
)
MSG_HASH(
MENU_ENUM_LABEL_VALUE_OVERLAY_Y_SEPARATION_LANDSCAPE,
@ -3368,7 +3376,7 @@ MSG_HASH(
)
MSG_HASH(
MENU_ENUM_SUBLABEL_OVERLAY_Y_SEPARATION_LANDSCAPE,
"Adjust the spacing between UI elements in the top and bottom halves of an overlay when using landscape display orientations. Positive values increase (while negative values decrease) the separation of the two halves."
"If supported by current preset, adjusts the spacing between UI elements in the top and bottom halves of an overlay when using landscape display orientations. Positive values increase (while negative values decrease) the separation of the two halves."
)
MSG_HASH(
MENU_ENUM_LABEL_VALUE_OVERLAY_X_OFFSET_LANDSCAPE,
@ -3408,7 +3416,15 @@ MSG_HASH(
)
MSG_HASH(
MENU_ENUM_SUBLABEL_OVERLAY_X_SEPARATION_PORTRAIT,
"Adjust the spacing between UI elements in the left and right halves of an overlay when using portrait display orientations. Positive values increase (while negative values decrease) the separation of the two halves."
"If supported by current preset, adjusts the spacing between UI elements in the left and right halves of an overlay when using portrait display orientations. Positive values increase (while negative values decrease) the separation of the two halves."
)
MSG_HASH(
MENU_ENUM_LABEL_VALUE_OVERLAY_Y_SEPARATION_PORTRAIT,
"(Portrait) Overlay Vertical Separation"
)
MSG_HASH(
MENU_ENUM_SUBLABEL_OVERLAY_Y_SEPARATION_PORTRAIT,
"If supported by current preset, adjusts the spacing between UI elements in the top and bottom halves of an overlay when using portrait display orientations. Positive values increase (while negative values decrease) the separation of the two halves."
)
MSG_HASH(
MENU_ENUM_LABEL_VALUE_OVERLAY_X_OFFSET_PORTRAIT,

View File

@ -415,6 +415,7 @@ DEFAULT_SUBLABEL_MACRO(action_bind_sublabel_input_overlay_hide_when_gamepad_conn
#endif
DEFAULT_SUBLABEL_MACRO(action_bind_sublabel_input_overlay_show_mouse_cursor, MENU_ENUM_SUBLABEL_INPUT_OVERLAY_SHOW_MOUSE_CURSOR)
DEFAULT_SUBLABEL_MACRO(action_bind_sublabel_input_overlay_auto_rotate, MENU_ENUM_SUBLABEL_INPUT_OVERLAY_AUTO_ROTATE)
DEFAULT_SUBLABEL_MACRO(action_bind_sublabel_input_overlay_auto_scale, MENU_ENUM_SUBLABEL_INPUT_OVERLAY_AUTO_SCALE)
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_gpu_screenshot, MENU_ENUM_SUBLABEL_VIDEO_GPU_SCREENSHOT)
@ -523,6 +524,7 @@ DEFAULT_SUBLABEL_MACRO(action_bind_sublabel_overlay_y_offset_landscape, MEN
DEFAULT_SUBLABEL_MACRO(action_bind_sublabel_overlay_scale_portrait, MENU_ENUM_SUBLABEL_OVERLAY_SCALE_PORTRAIT)
DEFAULT_SUBLABEL_MACRO(action_bind_sublabel_overlay_aspect_adjust_portrait, MENU_ENUM_SUBLABEL_OVERLAY_ASPECT_ADJUST_PORTRAIT)
DEFAULT_SUBLABEL_MACRO(action_bind_sublabel_overlay_x_separation_portrait, MENU_ENUM_SUBLABEL_OVERLAY_X_SEPARATION_PORTRAIT)
DEFAULT_SUBLABEL_MACRO(action_bind_sublabel_overlay_y_separation_portrait, MENU_ENUM_SUBLABEL_OVERLAY_Y_SEPARATION_PORTRAIT)
DEFAULT_SUBLABEL_MACRO(action_bind_sublabel_overlay_x_offset_portrait, MENU_ENUM_SUBLABEL_OVERLAY_X_OFFSET_PORTRAIT)
DEFAULT_SUBLABEL_MACRO(action_bind_sublabel_overlay_y_offset_portrait, MENU_ENUM_SUBLABEL_OVERLAY_Y_OFFSET_PORTRAIT)
DEFAULT_SUBLABEL_MACRO(action_bind_sublabel_overlay_enable, MENU_ENUM_SUBLABEL_INPUT_OVERLAY_ENABLE)
@ -2727,6 +2729,9 @@ int menu_cbs_init_bind_sublabel(menu_file_list_cbs_t *cbs,
case MENU_ENUM_LABEL_OVERLAY_X_SEPARATION_PORTRAIT:
BIND_ACTION_SUBLABEL(cbs, action_bind_sublabel_overlay_x_separation_portrait);
break;
case MENU_ENUM_LABEL_OVERLAY_Y_SEPARATION_PORTRAIT:
BIND_ACTION_SUBLABEL(cbs, action_bind_sublabel_overlay_y_separation_portrait);
break;
case MENU_ENUM_LABEL_OVERLAY_X_OFFSET_PORTRAIT:
BIND_ACTION_SUBLABEL(cbs, action_bind_sublabel_overlay_x_offset_portrait);
break;
@ -3068,6 +3073,9 @@ int menu_cbs_init_bind_sublabel(menu_file_list_cbs_t *cbs,
case MENU_ENUM_LABEL_INPUT_OVERLAY_AUTO_ROTATE:
BIND_ACTION_SUBLABEL(cbs, action_bind_sublabel_input_overlay_auto_rotate);
break;
case MENU_ENUM_LABEL_INPUT_OVERLAY_AUTO_SCALE:
BIND_ACTION_SUBLABEL(cbs, action_bind_sublabel_input_overlay_auto_scale);
break;
case MENU_ENUM_LABEL_VIDEO_FONT_SIZE:
BIND_ACTION_SUBLABEL(cbs, action_bind_sublabel_video_font_size);
break;

View File

@ -7553,6 +7553,8 @@ unsigned menu_displaylist_build_list(
{
settings_t *settings = config_get_ptr();
bool input_overlay_enable = settings->bools.input_overlay_enable;
bool input_overlay_auto_scale = settings->bools.input_overlay_auto_scale;
menu_displaylist_build_info_selective_t build_list[] = {
{MENU_ENUM_LABEL_INPUT_OVERLAY_ENABLE, PARSE_ONLY_BOOL, true },
{MENU_ENUM_LABEL_INPUT_OVERLAY_HIDE_IN_MENU, PARSE_ONLY_BOOL, false },
@ -7561,6 +7563,7 @@ unsigned menu_displaylist_build_list(
{MENU_ENUM_LABEL_INPUT_OVERLAY_SHOW_PHYSICAL_INPUTS_PORT, PARSE_ONLY_BOOL, false },
{MENU_ENUM_LABEL_INPUT_OVERLAY_SHOW_MOUSE_CURSOR, PARSE_ONLY_BOOL, false },
{MENU_ENUM_LABEL_INPUT_OVERLAY_AUTO_ROTATE, PARSE_ONLY_BOOL, false },
{MENU_ENUM_LABEL_INPUT_OVERLAY_AUTO_SCALE, PARSE_ONLY_BOOL, false },
{MENU_ENUM_LABEL_OVERLAY_PRESET, PARSE_ONLY_PATH, false },
{MENU_ENUM_LABEL_OVERLAY_OPACITY, PARSE_ONLY_FLOAT, false },
{MENU_ENUM_LABEL_OVERLAY_SCALE_LANDSCAPE, PARSE_ONLY_FLOAT, false },
@ -7572,6 +7575,7 @@ unsigned menu_displaylist_build_list(
{MENU_ENUM_LABEL_OVERLAY_SCALE_PORTRAIT, PARSE_ONLY_FLOAT, false },
{MENU_ENUM_LABEL_OVERLAY_ASPECT_ADJUST_PORTRAIT, PARSE_ONLY_FLOAT, false },
{MENU_ENUM_LABEL_OVERLAY_X_SEPARATION_PORTRAIT, PARSE_ONLY_FLOAT, false },
{MENU_ENUM_LABEL_OVERLAY_Y_SEPARATION_PORTRAIT, PARSE_ONLY_FLOAT, false },
{MENU_ENUM_LABEL_OVERLAY_X_OFFSET_PORTRAIT, PARSE_ONLY_FLOAT, false },
{MENU_ENUM_LABEL_OVERLAY_Y_OFFSET_PORTRAIT, PARSE_ONLY_FLOAT, false },
};
@ -7586,8 +7590,12 @@ unsigned menu_displaylist_build_list(
case MENU_ENUM_LABEL_INPUT_OVERLAY_SHOW_PHYSICAL_INPUTS_PORT:
case MENU_ENUM_LABEL_INPUT_OVERLAY_SHOW_MOUSE_CURSOR:
case MENU_ENUM_LABEL_INPUT_OVERLAY_AUTO_ROTATE:
case MENU_ENUM_LABEL_INPUT_OVERLAY_AUTO_SCALE:
case MENU_ENUM_LABEL_OVERLAY_PRESET:
case MENU_ENUM_LABEL_OVERLAY_OPACITY:
if (input_overlay_enable)
build_list[i].checked = true;
break;
case MENU_ENUM_LABEL_OVERLAY_SCALE_LANDSCAPE:
case MENU_ENUM_LABEL_OVERLAY_ASPECT_ADJUST_LANDSCAPE:
case MENU_ENUM_LABEL_OVERLAY_X_SEPARATION_LANDSCAPE:
@ -7597,9 +7605,11 @@ unsigned menu_displaylist_build_list(
case MENU_ENUM_LABEL_OVERLAY_SCALE_PORTRAIT:
case MENU_ENUM_LABEL_OVERLAY_ASPECT_ADJUST_PORTRAIT:
case MENU_ENUM_LABEL_OVERLAY_X_SEPARATION_PORTRAIT:
case MENU_ENUM_LABEL_OVERLAY_Y_SEPARATION_PORTRAIT:
case MENU_ENUM_LABEL_OVERLAY_X_OFFSET_PORTRAIT:
case MENU_ENUM_LABEL_OVERLAY_Y_OFFSET_PORTRAIT:
if (input_overlay_enable)
if (input_overlay_enable &&
!input_overlay_auto_scale)
build_list[i].checked = true;
break;
default:

View File

@ -13103,6 +13103,27 @@ static bool setting_append_list(
);
(*list)[list_info->index - 1].change_handler = overlay_auto_rotate_toggle_change_handler;
CONFIG_BOOL(
list, list_info,
&settings->bools.input_overlay_auto_scale,
MENU_ENUM_LABEL_INPUT_OVERLAY_AUTO_SCALE,
MENU_ENUM_LABEL_VALUE_INPUT_OVERLAY_AUTO_SCALE,
DEFAULT_INPUT_OVERLAY_AUTO_SCALE,
MENU_ENUM_LABEL_VALUE_OFF,
MENU_ENUM_LABEL_VALUE_ON,
&group_info,
&subgroup_info,
parent_group,
general_write_handler,
general_read_handler,
SD_FLAG_NONE
);
(*list)[list_info->index - 1].action_ok = &setting_bool_action_left_with_refresh;
(*list)[list_info->index - 1].action_left = &setting_bool_action_left_with_refresh;
(*list)[list_info->index - 1].action_right = &setting_bool_action_right_with_refresh;
MENU_SETTINGS_LIST_CURRENT_ADD_CMD(list, list_info, CMD_EVENT_OVERLAY_SET_SCALE_FACTOR);
SETTINGS_DATA_LIST_CURRENT_ADD_FLAGS(list, list_info, SD_FLAG_CMD_APPLY_AUTO);
CONFIG_PATH(
list, list_info,
settings->paths.path_overlay,
@ -13288,6 +13309,23 @@ static bool setting_append_list(
menu_settings_list_current_add_range(list, list_info, -2.0f, 2.0f, 0.005f, true, true);
SETTINGS_DATA_LIST_CURRENT_ADD_FLAGS(list, list_info, SD_FLAG_CMD_APPLY_AUTO);
CONFIG_FLOAT(
list, list_info,
&settings->floats.input_overlay_y_separation_portrait,
MENU_ENUM_LABEL_OVERLAY_Y_SEPARATION_PORTRAIT,
MENU_ENUM_LABEL_VALUE_OVERLAY_Y_SEPARATION_PORTRAIT,
DEFAULT_INPUT_OVERLAY_Y_SEPARATION_PORTRAIT,
"%.3f",
&group_info,
&subgroup_info,
parent_group,
general_write_handler,
general_read_handler);
(*list)[list_info->index - 1].action_ok = &setting_action_ok_uint;
MENU_SETTINGS_LIST_CURRENT_ADD_CMD(list, list_info, CMD_EVENT_OVERLAY_SET_SCALE_FACTOR);
menu_settings_list_current_add_range(list, list_info, -2.0f, 2.0f, 0.005f, true, true);
SETTINGS_DATA_LIST_CURRENT_ADD_FLAGS(list, list_info, SD_FLAG_CMD_APPLY_AUTO);
CONFIG_FLOAT(
list, list_info,
&settings->floats.input_overlay_x_offset_portrait,

View File

@ -934,6 +934,7 @@ enum msg_hash_enums
MENU_LABEL(INPUT_OVERLAY_SHOW_PHYSICAL_INPUTS_PORT),
MENU_LABEL(INPUT_OVERLAY_SHOW_MOUSE_CURSOR),
MENU_LABEL(INPUT_OVERLAY_AUTO_ROTATE),
MENU_LABEL(INPUT_OVERLAY_AUTO_SCALE),
MENU_LABEL(INPUT_KEYBOARD_GAMEPAD_MAPPING_TYPE),
MENU_LABEL(INPUT_SMALL_KEYBOARD_ENABLE),
MENU_LABEL(INPUT_TOUCH_ENABLE),
@ -1783,6 +1784,7 @@ enum msg_hash_enums
MENU_LABEL(OVERLAY_SCALE_PORTRAIT),
MENU_LABEL(OVERLAY_ASPECT_ADJUST_PORTRAIT),
MENU_LABEL(OVERLAY_X_SEPARATION_PORTRAIT),
MENU_LABEL(OVERLAY_Y_SEPARATION_PORTRAIT),
MENU_LABEL(OVERLAY_X_OFFSET_PORTRAIT),
MENU_LABEL(OVERLAY_Y_OFFSET_PORTRAIT),
MENU_LABEL(OVERLAY_PRESET),

View File

@ -2835,7 +2835,7 @@ static void retroarch_overlay_deinit(struct rarch_state *p_rarch);
static void input_overlay_set_alpha_mod(struct rarch_state *p_rarch,
input_overlay_t *ol, float mod);
static void input_overlay_set_scale_factor(struct rarch_state *p_rarch,
input_overlay_t *ol, overlay_layout_t *layout);
input_overlay_t *ol, const overlay_layout_desc_t *layout_desc);
static void input_overlay_load_active(
struct rarch_state *p_rarch,
input_overlay_t *ol, float opacity);
@ -16645,21 +16645,23 @@ bool command_event(enum event_command cmd, void *data)
case CMD_EVENT_OVERLAY_SET_SCALE_FACTOR:
#ifdef HAVE_OVERLAY
{
overlay_layout_t layout;
overlay_layout_desc_t layout_desc;
layout.scale_landscape = settings->floats.input_overlay_scale_landscape;
layout.aspect_adjust_landscape = settings->floats.input_overlay_aspect_adjust_landscape;
layout.x_separation_landscape = settings->floats.input_overlay_x_separation_landscape;
layout.y_separation_landscape = settings->floats.input_overlay_y_separation_landscape;
layout.x_offset_landscape = settings->floats.input_overlay_x_offset_landscape;
layout.y_offset_landscape = settings->floats.input_overlay_y_offset_landscape;
layout.scale_portrait = settings->floats.input_overlay_scale_portrait;
layout.aspect_adjust_portrait = settings->floats.input_overlay_aspect_adjust_portrait;
layout.x_separation_portrait = settings->floats.input_overlay_x_separation_portrait;
layout.x_offset_portrait = settings->floats.input_overlay_x_offset_portrait;
layout.y_offset_portrait = settings->floats.input_overlay_y_offset_portrait;
layout_desc.scale_landscape = settings->floats.input_overlay_scale_landscape;
layout_desc.aspect_adjust_landscape = settings->floats.input_overlay_aspect_adjust_landscape;
layout_desc.x_separation_landscape = settings->floats.input_overlay_x_separation_landscape;
layout_desc.y_separation_landscape = settings->floats.input_overlay_y_separation_landscape;
layout_desc.x_offset_landscape = settings->floats.input_overlay_x_offset_landscape;
layout_desc.y_offset_landscape = settings->floats.input_overlay_y_offset_landscape;
layout_desc.scale_portrait = settings->floats.input_overlay_scale_portrait;
layout_desc.aspect_adjust_portrait = settings->floats.input_overlay_aspect_adjust_portrait;
layout_desc.x_separation_portrait = settings->floats.input_overlay_x_separation_portrait;
layout_desc.y_separation_portrait = settings->floats.input_overlay_y_separation_portrait;
layout_desc.x_offset_portrait = settings->floats.input_overlay_x_offset_portrait;
layout_desc.y_offset_portrait = settings->floats.input_overlay_y_offset_portrait;
layout_desc.auto_scale = settings->bools.input_overlay_auto_scale;
input_overlay_set_scale_factor(p_rarch, p_rarch->overlay_ptr, &layout);
input_overlay_set_scale_factor(p_rarch, p_rarch->overlay_ptr, &layout_desc);
}
#endif
break;
@ -22918,84 +22920,151 @@ static bool input_overlay_add_inputs(input_overlay_t *ol,
return button_pressed;
}
/**
* input_overlay_scale:
* @ol : Overlay handle.
* @layout : Scale + offset factors.
* @is_landscape : True if current display has a
* landscape orientation
*
* Scales the overlay and all its associated descriptors
* and applies any aspect ratio/offset factors.
**/
static void input_overlay_scale(struct overlay *ol,
overlay_layout_t *layout, bool is_landscape)
{
float scale_x = 1.0f;
float scale_y = 1.0f;
float x_separation;
float y_separation;
float x_offset;
float y_offset;
size_t i;
if (is_landscape)
static void input_overlay_parse_layout(
const struct overlay *ol,
const overlay_layout_desc_t *layout_desc,
float display_aspect_ratio,
overlay_layout_t *overlay_layout)
{
/* Set default values */
overlay_layout->x_scale = 1.0f;
overlay_layout->y_scale = 1.0f;
overlay_layout->x_separation = 0.0f;
overlay_layout->y_separation = 0.0f;
overlay_layout->x_offset = 0.0f;
overlay_layout->y_offset = 0.0f;
/* Perform auto-scaling, if required */
if (layout_desc->auto_scale)
{
float scale = layout->scale_landscape;
float aspect_adjust = layout->aspect_adjust_landscape;
/* Sanity check - if scaling is blocked,
* or aspect ratios are invalid, then we
* can do nothing */
if (ol->block_scale ||
(ol->aspect_ratio <= 0.0f) ||
(display_aspect_ratio <= 0.0f))
return;
/* If display is wider than overlay,
* reduce width */
if (display_aspect_ratio >
ol->aspect_ratio)
{
overlay_layout->x_scale = ol->aspect_ratio /
display_aspect_ratio;
if (overlay_layout->x_scale <= 0.0f)
{
overlay_layout->x_scale = 1.0f;
return;
}
/* If X separation is permitted, move elements
* horizontally towards the edges of the screen */
if (!ol->block_x_separation)
overlay_layout->x_separation = ((1.0f / overlay_layout->x_scale) - 1.0f) * 0.5f;
}
/* If display is taller than overlay,
* reduce height */
else
{
overlay_layout->y_scale = display_aspect_ratio /
ol->aspect_ratio;
if (overlay_layout->y_scale <= 0.0f)
{
overlay_layout->y_scale = 1.0f;
return;
}
/* If Y separation is permitted and display has
* a *landscape* orientation, move elements
* vertically towards the edges of the screen
* > Portrait overlays typically have all elements
* below the centre line, so Y separation
* provides no real benefit */
if ((display_aspect_ratio > 1.0f) &&
!ol->block_y_separation)
overlay_layout->y_separation = ((1.0f / overlay_layout->y_scale) - 1.0f) * 0.5f;
}
return;
}
/* Regular 'manual' scaling/position adjustment
* > Landscape display orientations */
if (display_aspect_ratio > 1.0f)
{
float scale = layout_desc->scale_landscape;
float aspect_adjust = layout_desc->aspect_adjust_landscape;
/* Note: Y offsets have their sign inverted,
* since from a usability perspective positive
* values should move the overlay upwards */
x_offset = layout->x_offset_landscape;
y_offset = layout->y_offset_landscape * -1.0f;
overlay_layout->x_offset = layout_desc->x_offset_landscape;
overlay_layout->y_offset = layout_desc->y_offset_landscape * -1.0f;
x_separation = layout->x_separation_landscape;
y_separation = layout->y_separation_landscape;
if (!ol->block_x_separation)
overlay_layout->x_separation = layout_desc->x_separation_landscape;
if (!ol->block_y_separation)
overlay_layout->y_separation = layout_desc->y_separation_landscape;
if (!ol->block_scale)
{
/* In landscape orientations, aspect correction
* adjusts the overlay width */
scale_x = (aspect_adjust >= 0.0f) ?
overlay_layout->x_scale = (aspect_adjust >= 0.0f) ?
(scale * (aspect_adjust + 1.0f)) :
(scale / ((aspect_adjust * -1.0f) + 1.0f));
scale_y = scale;
overlay_layout->y_scale = scale;
}
}
/* > Portrait display orientations */
else
{
float scale = layout->scale_portrait;
float aspect_adjust = layout->aspect_adjust_portrait;
float scale = layout_desc->scale_portrait;
float aspect_adjust = layout_desc->aspect_adjust_portrait;
x_offset = layout->x_offset_portrait;
y_offset = layout->y_offset_portrait * -1.0f;
overlay_layout->x_offset = layout_desc->x_offset_portrait;
overlay_layout->y_offset = layout_desc->y_offset_portrait * -1.0f;
/* Note: 'y separation' makes little sense when
* dealing with portrait layouts, since UI
* elements are typically always placed below
* the centre line. Just set y_separation to
* zero in this case... */
x_separation = layout->x_separation_portrait;
y_separation = 0.0f;
if (!ol->block_x_separation)
overlay_layout->x_separation = layout_desc->x_separation_portrait;
if (!ol->block_y_separation)
overlay_layout->y_separation = layout_desc->y_separation_portrait;
if (!ol->block_scale)
{
/* In portrait orientations, aspect correction
* adjusts the overlay height */
scale_x = scale;
scale_y = (aspect_adjust >= 0.0f) ?
overlay_layout->x_scale = scale;
overlay_layout->y_scale = (aspect_adjust >= 0.0f) ?
(scale * (aspect_adjust + 1.0f)) :
(scale / ((aspect_adjust * -1.0f) + 1.0f));
}
}
}
ol->mod_w = ol->w * scale_x;
ol->mod_h = ol->h * scale_y;
ol->mod_x = (ol->center_x +
(ol->x - ol->center_x) * scale_x) + x_offset;
ol->mod_y = (ol->center_y +
(ol->y - ol->center_y) * scale_y) + y_offset;
/**
* input_overlay_scale:
* @ol : Overlay handle.
* @layout : Scale + offset factors.
*
* Scales the overlay and all its associated descriptors
* and applies any aspect ratio/offset factors.
**/
static void input_overlay_scale(struct overlay *ol,
const overlay_layout_t *layout)
{
size_t i;
ol->mod_w = ol->w * layout->x_scale;
ol->mod_h = ol->h * layout->y_scale;
ol->mod_x = (ol->center_x + (ol->x - ol->center_x) *
layout->x_scale) + layout->x_offset;
ol->mod_y = (ol->center_y + (ol->y - ol->center_y) *
layout->y_scale) + layout->y_offset;
for (i = 0; i < ol->size; i++)
{
@ -23009,17 +23078,17 @@ static void input_overlay_scale(struct overlay *ol,
/* Apply 'x separation' factor */
if (desc->x < (0.5f - 0.0001f))
x_shift_offset = x_separation * -1.0f;
x_shift_offset = layout->x_separation * -1.0f;
else if (desc->x > (0.5f + 0.0001f))
x_shift_offset = x_separation;
x_shift_offset = layout->x_separation;
desc->x_shift = desc->x + x_shift_offset;
/* Apply 'y separation' factor */
if (desc->y < (0.5f - 0.0001f))
y_shift_offset = y_separation * -1.0f;
y_shift_offset = layout->y_separation * -1.0f;
else if (desc->y > (0.5f + 0.0001f))
y_shift_offset = y_separation;
y_shift_offset = layout->y_separation;
desc->y_shift = desc->y + y_shift_offset;
@ -23060,24 +23129,33 @@ static void input_overlay_set_vertex_geom(input_overlay_t *ol)
/**
* input_overlay_set_scale_factor:
* @ol : Overlay handle.
* @layout : Scale + offset factors.
* @layout_desc : Scale + offset factors.
*
* Scales the overlay and applies any aspect ratio/
* offset factors.
**/
static void input_overlay_set_scale_factor(struct rarch_state *p_rarch,
input_overlay_t *ol, overlay_layout_t *layout)
input_overlay_t *ol, const overlay_layout_desc_t *layout_desc)
{
bool is_landscape = p_rarch->video_driver_width >
p_rarch->video_driver_height;
float display_aspect_ratio = 0.0f;
size_t i;
if (!ol || !layout)
if (!ol || !layout_desc)
return;
if (p_rarch->video_driver_height > 0)
display_aspect_ratio = (float)p_rarch->video_driver_width /
(float)p_rarch->video_driver_height;
for (i = 0; i < ol->size; i++)
input_overlay_scale(&ol->overlays[i],
layout, is_landscape);
{
struct overlay *current_overlay = &ol->overlays[i];
overlay_layout_t overlay_layout;
input_overlay_parse_layout(current_overlay,
layout_desc, display_aspect_ratio, &overlay_layout);
input_overlay_scale(current_overlay, &overlay_layout);
}
input_overlay_set_vertex_geom(ol);
}
@ -23557,7 +23635,7 @@ static void input_overlay_loaded(retro_task_t *task,
if (ol->iface->enable)
ol->iface->enable(ol->iface_data, data->overlay_enable);
input_overlay_set_scale_factor(p_rarch, ol, &data->layout);
input_overlay_set_scale_factor(p_rarch, ol, &data->layout_desc);
ol->next_index = (unsigned)((ol->index + 1) % ol->size);
ol->state = OVERLAY_STATUS_NONE;
@ -23826,6 +23904,7 @@ static void retroarch_overlay_init(struct rarch_state *p_rarch)
{
settings_t *settings = p_rarch->configuration_settings;
bool input_overlay_enable = settings->bools.input_overlay_enable;
bool input_overlay_auto_scale = settings->bools.input_overlay_auto_scale;
const char *path_overlay = settings->paths.path_overlay;
float overlay_opacity = settings->floats.input_overlay_opacity;
float overlay_scale_landscape = settings->floats.input_overlay_scale_landscape;
@ -23837,6 +23916,7 @@ static void retroarch_overlay_init(struct rarch_state *p_rarch)
float overlay_scale_portrait = settings->floats.input_overlay_scale_portrait;
float overlay_aspect_adjust_portrait = settings->floats.input_overlay_aspect_adjust_portrait;
float overlay_x_separation_portrait = settings->floats.input_overlay_x_separation_portrait;
float overlay_y_separation_portrait = settings->floats.input_overlay_y_separation_portrait;
float overlay_x_offset_portrait = settings->floats.input_overlay_x_offset_portrait;
float overlay_y_offset_portrait = settings->floats.input_overlay_y_offset_portrait;
bool load_enabled = input_overlay_enable;
@ -23869,19 +23949,21 @@ static void retroarch_overlay_init(struct rarch_state *p_rarch)
if (load_enabled)
{
overlay_layout_t layout;
overlay_layout_desc_t layout_desc;
layout.scale_landscape = overlay_scale_landscape;
layout.aspect_adjust_landscape = overlay_aspect_adjust_landscape;
layout.x_separation_landscape = overlay_x_separation_landscape;
layout.y_separation_landscape = overlay_y_separation_landscape;
layout.x_offset_landscape = overlay_x_offset_landscape;
layout.y_offset_landscape = overlay_y_offset_landscape;
layout.scale_portrait = overlay_scale_portrait;
layout.aspect_adjust_portrait = overlay_aspect_adjust_portrait;
layout.x_separation_portrait = overlay_x_separation_portrait;
layout.x_offset_portrait = overlay_x_offset_portrait;
layout.y_offset_portrait = overlay_y_offset_portrait;
layout_desc.scale_landscape = overlay_scale_landscape;
layout_desc.aspect_adjust_landscape = overlay_aspect_adjust_landscape;
layout_desc.x_separation_landscape = overlay_x_separation_landscape;
layout_desc.y_separation_landscape = overlay_y_separation_landscape;
layout_desc.x_offset_landscape = overlay_x_offset_landscape;
layout_desc.y_offset_landscape = overlay_y_offset_landscape;
layout_desc.scale_portrait = overlay_scale_portrait;
layout_desc.aspect_adjust_portrait = overlay_aspect_adjust_portrait;
layout_desc.x_separation_portrait = overlay_x_separation_portrait;
layout_desc.y_separation_portrait = overlay_y_separation_portrait;
layout_desc.x_offset_portrait = overlay_x_offset_portrait;
layout_desc.y_offset_portrait = overlay_y_offset_portrait;
layout_desc.auto_scale = input_overlay_auto_scale;
task_push_overlay_load_default(input_overlay_loaded,
path_overlay,
@ -23889,7 +23971,7 @@ static void retroarch_overlay_init(struct rarch_state *p_rarch)
overlay_hide_when_gamepad_connected,
input_overlay_enable,
overlay_opacity,
&layout,
&layout_desc,
NULL);
}
}

View File

@ -46,7 +46,7 @@ struct overlay_loader
unsigned pos_increment;
float overlay_opacity;
overlay_layout_t layout;
overlay_layout_desc_t layout_desc;
enum overlay_status state;
enum overlay_image_transfer_status loading_status;
@ -600,6 +600,26 @@ static void task_overlay_deferred_load(retro_task_t *task)
config_get_array(conf, overlay->config.names.key,
overlay->name, sizeof(overlay->name));
/* Attempt to determine native aspect ratio */
snprintf(conf_key, sizeof(conf_key),
"overlay%u_aspect_ratio", loader->pos);
overlay->aspect_ratio = 0.0f;
if (config_get_float(conf, conf_key, &tmp_float))
overlay->aspect_ratio = tmp_float;
if (overlay->aspect_ratio <= 0.0f)
{
/* No ratio has been set - assume 16:9
* (or 16:9 rotated) */
/* Check whether overlay name indicates a
* portrait layout */
if (strstr(overlay->name, "portrait"))
overlay->aspect_ratio = 0.5625f; /* 1 / (16/9) */
else
overlay->aspect_ratio = 1.7777778f; /* 16/9 */
}
/* By default, we stretch the overlay out in full. */
overlay->x = overlay->y = 0.0f;
overlay->w = overlay->h = 1.0f;
@ -636,6 +656,20 @@ static void task_overlay_deferred_load(retro_task_t *task)
overlay->block_scale = false;
overlay->center_x = overlay->x + 0.5f * overlay->w;
overlay->center_y = overlay->y + 0.5f * overlay->h;
/* Check whether x/y separation are force disabled
* for this overlay */
snprintf(conf_key, sizeof(conf_key),
"overlay%u_block_x_separation", loader->pos);
overlay->block_x_separation = false;
if (config_get_bool(conf, conf_key, &tmp_bool))
overlay->block_x_separation = tmp_bool;
snprintf(conf_key, sizeof(conf_key),
"overlay%u_block_y_separation", loader->pos);
overlay->block_y_separation = false;
if (config_get_bool(conf, conf_key, &tmp_bool))
overlay->block_y_separation = tmp_bool;
}
return;
@ -713,7 +747,8 @@ static void task_overlay_handler(retro_task_t *task)
data->hide_in_menu = loader->overlay_hide_in_menu;
data->hide_when_gamepad_connected = loader->overlay_hide_when_gamepad_connected;
memcpy(&data->layout, &loader->layout, sizeof(overlay_layout_t));
memcpy(&data->layout_desc, &loader->layout_desc,
sizeof(overlay_layout_desc_t));
task_set_data(task, data);
}
@ -743,7 +778,7 @@ bool task_push_overlay_load_default(
bool overlay_hide_when_gamepad_connected,
bool input_overlay_enable,
float input_overlay_opacity,
overlay_layout_t *layout,
overlay_layout_desc_t *layout_desc,
void *user_data)
{
task_finder_data_t find_data;
@ -751,7 +786,7 @@ bool task_push_overlay_load_default(
config_file_t *conf = NULL;
overlay_loader_t *loader = NULL;
if (string_is_empty(overlay_path) || !layout)
if (string_is_empty(overlay_path) || !layout_desc)
return false;
/* Prevent overlay from being loaded if it already is being loaded */
@ -801,7 +836,8 @@ bool task_push_overlay_load_default(
loader->driver_rgba_support = video_driver_supports_rgba();
#endif
memcpy(&loader->layout, layout, sizeof(overlay_layout_t));
memcpy(&loader->layout_desc, layout_desc,
sizeof(overlay_layout_desc_t));
t = task_init();

View File

@ -174,7 +174,7 @@ bool task_push_overlay_load_default(
bool overlay_hide_when_gamepad_connected,
bool input_overlay_enable,
float input_overlay_opacity,
overlay_layout_t *layout,
overlay_layout_desc_t *layout_desc,
void *user_data);
#endif