diff --git a/input/input_driver.c b/input/input_driver.c
index 588734d82e..7870eaf4fa 100644
--- a/input/input_driver.c
+++ b/input/input_driver.c
@@ -17,7 +17,9 @@
* with RetroArch. If not, see .
**/
+#include
#include
+#include
#include "input_driver.h"
@@ -925,4 +927,538 @@ bool input_overlay_add_inputs(input_overlay_t *ol,
return button_pressed;
}
+
+/**
+ * inside_hitbox:
+ * @desc : Overlay descriptor handle.
+ * @x : X coordinate value.
+ * @y : Y coordinate value.
+ *
+ * Check whether the given @x and @y coordinates of the overlay
+ * descriptor @desc is inside the overlay descriptor's hitbox.
+ *
+ * Returns: true (1) if X, Y coordinates are inside a hitbox,
+ * otherwise false (0).
+ **/
+static bool inside_hitbox(const struct overlay_desc *desc, float x, float y)
+{
+ if (!desc)
+ return false;
+
+ switch (desc->hitbox)
+ {
+ case OVERLAY_HITBOX_RADIAL:
+ {
+ /* Ellipsis. */
+ float x_dist = (x - desc->x_shift) / desc->range_x_mod;
+ float y_dist = (y - desc->y_shift) / desc->range_y_mod;
+ float sq_dist = x_dist * x_dist + y_dist * y_dist;
+ return (sq_dist <= 1.0f);
+ }
+
+ case OVERLAY_HITBOX_RECT:
+ return
+ (fabs(x - desc->x_shift) <= desc->range_x_mod) &&
+ (fabs(y - desc->y_shift) <= desc->range_y_mod);
+ }
+
+ return false;
+}
+
+/**
+ * input_overlay_poll:
+ * @out : Polled output data.
+ * @norm_x : Normalized X coordinate.
+ * @norm_y : Normalized Y coordinate.
+ *
+ * Polls input overlay.
+ *
+ * @norm_x and @norm_y are the result of
+ * input_translate_coord_viewport().
+ **/
+void input_overlay_poll(
+ input_overlay_t *ol,
+ input_overlay_state_t *out,
+ int16_t norm_x, int16_t norm_y, float touch_scale)
+{
+ size_t i;
+
+ /* norm_x and norm_y is in [-0x7fff, 0x7fff] range,
+ * like RETRO_DEVICE_POINTER. */
+ float x = (float)(norm_x + 0x7fff) / 0xffff;
+ float y = (float)(norm_y + 0x7fff) / 0xffff;
+
+ x -= ol->active->mod_x;
+ y -= ol->active->mod_y;
+ x /= ol->active->mod_w;
+ y /= ol->active->mod_h;
+
+ x *= touch_scale;
+ y *= touch_scale;
+
+ for (i = 0; i < ol->active->size; i++)
+ {
+ float x_dist, y_dist;
+ unsigned int base = 0;
+ struct overlay_desc *desc = &ol->active->descs[i];
+
+ if (!inside_hitbox(desc, x, y))
+ continue;
+
+ desc->updated = true;
+ x_dist = x - desc->x_shift;
+ y_dist = y - desc->y_shift;
+
+ switch (desc->type)
+ {
+ case OVERLAY_TYPE_BUTTONS:
+ bits_or_bits(out->buttons.data,
+ desc->button_mask.data,
+ ARRAY_SIZE(desc->button_mask.data));
+
+ if (BIT256_GET(desc->button_mask, RARCH_OVERLAY_NEXT))
+ ol->next_index = desc->next_index;
+ break;
+ case OVERLAY_TYPE_KEYBOARD:
+ if (desc->retro_key_idx < RETROK_LAST)
+ OVERLAY_SET_KEY(out, desc->retro_key_idx);
+ break;
+ case OVERLAY_TYPE_ANALOG_RIGHT:
+ base = 2;
+ /* fall-through */
+ default:
+ {
+ float x_val = x_dist / desc->range_x;
+ float y_val = y_dist / desc->range_y;
+ float x_val_sat = x_val / desc->analog_saturate_pct;
+ float y_val_sat = y_val / desc->analog_saturate_pct;
+ out->analog[base + 0] = clamp_float(x_val_sat, -1.0f, 1.0f)
+ * 32767.0f;
+ out->analog[base + 1] = clamp_float(y_val_sat, -1.0f, 1.0f)
+ * 32767.0f;
+ }
+ break;
+ }
+
+ if (desc->movable)
+ {
+ desc->delta_x = clamp_float(x_dist, -desc->range_x, desc->range_x)
+ * ol->active->mod_w;
+ desc->delta_y = clamp_float(y_dist, -desc->range_y, desc->range_y)
+ * ol->active->mod_h;
+ }
+ }
+
+ if (!bits_any_set(out->buttons.data, ARRAY_SIZE(out->buttons.data)))
+ ol->blocked = false;
+ else if (ol->blocked)
+ memset(out, 0, sizeof(*out));
+}
+
+/**
+ * input_overlay_update_desc_geom:
+ * @ol : overlay handle.
+ * @desc : overlay descriptors handle.
+ *
+ * Update input overlay descriptors' vertex geometry.
+ **/
+static void input_overlay_update_desc_geom(input_overlay_t *ol,
+ struct overlay_desc *desc)
+{
+ if (!desc->image.pixels || !desc->movable)
+ return;
+
+ if (ol->iface->vertex_geom)
+ ol->iface->vertex_geom(ol->iface_data, desc->image_index,
+ desc->mod_x + desc->delta_x, desc->mod_y + desc->delta_y,
+ desc->mod_w, desc->mod_h);
+
+ desc->delta_x = 0.0f;
+ desc->delta_y = 0.0f;
+}
+
+void input_overlay_post_poll(
+ enum overlay_visibility *visibility,
+ input_overlay_t *ol,
+ bool show_input, float opacity)
+{
+ size_t i;
+
+ input_overlay_set_alpha_mod(visibility, ol, opacity);
+
+ for (i = 0; i < ol->active->size; i++)
+ {
+ struct overlay_desc *desc = &ol->active->descs[i];
+
+ desc->range_x_mod = desc->range_x;
+ desc->range_y_mod = desc->range_y;
+
+ if (desc->updated)
+ {
+ /* If pressed this frame, change the hitbox. */
+ desc->range_x_mod *= desc->range_mod;
+ desc->range_y_mod *= desc->range_mod;
+
+ if (show_input && desc->image.pixels)
+ {
+ if (ol->iface->set_alpha)
+ ol->iface->set_alpha(ol->iface_data, desc->image_index,
+ desc->alpha_mod * opacity);
+ }
+ }
+
+ input_overlay_update_desc_geom(ol, desc);
+ desc->updated = false;
+ }
+}
+
+/**
+ * input_overlay_set_scale_factor:
+ * @ol : Overlay handle.
+ * @layout_desc : Scale + offset factors.
+ *
+ * Scales the overlay and applies any aspect ratio/
+ * offset factors.
+ **/
+void input_overlay_set_scale_factor(
+ input_overlay_t *ol, const overlay_layout_desc_t *layout_desc,
+ unsigned video_driver_width,
+ unsigned video_driver_height
+)
+{
+ size_t i;
+ float display_aspect_ratio = 0.0f;
+
+ if (!ol || !layout_desc)
+ return;
+
+ if (video_driver_height > 0)
+ display_aspect_ratio = (float)video_driver_width /
+ (float)video_driver_height;
+
+ for (i = 0; i < ol->size; i++)
+ {
+ 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);
+}
+
+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++)
+ {
+ struct overlay_desc *desc = &ol->descs[i];
+ float x_shift_offset = 0.0f;
+ float y_shift_offset = 0.0f;
+ float scale_w;
+ float scale_h;
+ float adj_center_x;
+ float adj_center_y;
+
+ /* Apply 'x separation' factor */
+ if (desc->x < (0.5f - 0.0001f))
+ x_shift_offset = layout->x_separation * -1.0f;
+ else if (desc->x > (0.5f + 0.0001f))
+ 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 = layout->y_separation * -1.0f;
+ else if (desc->y > (0.5f + 0.0001f))
+ y_shift_offset = layout->y_separation;
+
+ desc->y_shift = desc->y + y_shift_offset;
+
+ scale_w = ol->mod_w * desc->range_x;
+ scale_h = ol->mod_h * desc->range_y;
+ adj_center_x = ol->mod_x + desc->x_shift * ol->mod_w;
+ adj_center_y = ol->mod_y + desc->y_shift * ol->mod_h;
+
+ desc->mod_w = 2.0f * scale_w;
+ desc->mod_h = 2.0f * scale_h;
+ desc->mod_x = adj_center_x - scale_w;
+ desc->mod_y = adj_center_y - scale_h;
+ }
+}
+
+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)
+ {
+ /* 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 */
+ overlay_layout->x_offset = layout_desc->x_offset_landscape;
+ overlay_layout->y_offset = layout_desc->y_offset_landscape * -1.0f;
+
+ 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 */
+ overlay_layout->x_scale = (aspect_adjust >= 0.0f) ?
+ (scale * (aspect_adjust + 1.0f)) :
+ (scale / ((aspect_adjust * -1.0f) + 1.0f));
+ overlay_layout->y_scale = scale;
+ }
+ }
+ /* > Portrait display orientations */
+ else
+ {
+ float scale = layout_desc->scale_portrait;
+ float aspect_adjust = layout_desc->aspect_adjust_portrait;
+
+ overlay_layout->x_offset = layout_desc->x_offset_portrait;
+ overlay_layout->y_offset = layout_desc->y_offset_portrait * -1.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 */
+ 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));
+ }
+ }
+}
+
+void input_overlay_set_vertex_geom(input_overlay_t *ol)
+{
+ size_t i;
+
+ if (ol->active->image.pixels)
+ ol->iface->vertex_geom(ol->iface_data, 0,
+ ol->active->mod_x, ol->active->mod_y,
+ ol->active->mod_w, ol->active->mod_h);
+
+ if (ol->iface->vertex_geom)
+ for (i = 0; i < ol->active->size; i++)
+ {
+ struct overlay_desc *desc = &ol->active->descs[i];
+
+ if (!desc->image.pixels)
+ continue;
+
+ ol->iface->vertex_geom(ol->iface_data, desc->image_index,
+ desc->mod_x, desc->mod_y, desc->mod_w, desc->mod_h);
+ }
+}
+
+
+void input_overlay_load_active(
+ enum overlay_visibility *visibility,
+ input_overlay_t *ol, float opacity)
+{
+ if (ol->iface->load)
+ ol->iface->load(ol->iface_data, ol->active->load_images,
+ ol->active->load_images_size);
+
+ input_overlay_set_alpha_mod(visibility, ol, opacity);
+ input_overlay_set_vertex_geom(ol);
+
+ if (ol->iface->full_screen)
+ ol->iface->full_screen(ol->iface_data, ol->active->full_screen);
+}
+
+void input_overlay_poll_clear(
+ enum overlay_visibility *visibility,
+ input_overlay_t *ol, float opacity)
+{
+ size_t i;
+
+ ol->blocked = false;
+
+ input_overlay_set_alpha_mod(visibility, ol, opacity);
+
+ for (i = 0; i < ol->active->size; i++)
+ {
+ struct overlay_desc *desc = &ol->active->descs[i];
+
+ desc->range_x_mod = desc->range_x;
+ desc->range_y_mod = desc->range_y;
+ desc->updated = false;
+
+ desc->delta_x = 0.0f;
+ desc->delta_y = 0.0f;
+ input_overlay_update_desc_geom(ol, desc);
+ }
+}
+
+void input_overlay_set_alpha_mod(
+ enum overlay_visibility *visibility,
+ input_overlay_t *ol, float mod)
+{
+ unsigned i;
+
+ if (!ol)
+ return;
+
+ for (i = 0; i < ol->active->load_images_size; i++)
+ {
+ if (input_overlay_get_visibility(visibility, i)
+ == OVERLAY_VISIBILITY_HIDDEN)
+ ol->iface->set_alpha(ol->iface_data, i, 0.0);
+ else
+ ol->iface->set_alpha(ol->iface_data, i, mod);
+ }
+}
+
+enum overlay_visibility input_overlay_get_visibility(
+ enum overlay_visibility *visibility,
+ int overlay_idx)
+{
+ if (!visibility)
+ return OVERLAY_VISIBILITY_DEFAULT;
+ if ((overlay_idx < 0) || (overlay_idx >= MAX_VISIBILITY))
+ return OVERLAY_VISIBILITY_DEFAULT;
+ return visibility[overlay_idx];
+}
+
+void input_overlay_free_overlays(input_overlay_t *ol)
+{
+ size_t i;
+
+ if (!ol || !ol->overlays)
+ return;
+
+ for (i = 0; i < ol->size; i++)
+ input_overlay_free_overlay(&ol->overlays[i]);
+
+ free(ol->overlays);
+ ol->overlays = NULL;
+}
+
+void input_overlay_free_overlay(struct overlay *overlay)
+{
+ size_t i;
+
+ if (!overlay)
+ return;
+
+ for (i = 0; i < overlay->size; i++)
+ image_texture_free(&overlay->descs[i].image);
+
+ if (overlay->load_images)
+ free(overlay->load_images);
+ overlay->load_images = NULL;
+ if (overlay->descs)
+ free(overlay->descs);
+ overlay->descs = NULL;
+ image_texture_free(&overlay->image);
+}
+
+void input_overlay_free(input_overlay_t *ol)
+{
+ if (!ol)
+ return;
+
+ input_overlay_free_overlays(ol);
+
+ if (ol->iface->enable)
+ ol->iface->enable(ol->iface_data, false);
+
+ free(ol);
+}
#endif
diff --git a/input/input_overlay.h b/input/input_overlay.h
index a248ecf158..e1e2db48be 100644
--- a/input/input_overlay.h
+++ b/input/input_overlay.h
@@ -316,6 +316,96 @@ bool input_overlay_add_inputs_inner(overlay_desc_t *desc,
bool input_overlay_add_inputs(input_overlay_t *ol,
bool show_touched, unsigned port);
+void input_overlay_poll(
+ input_overlay_t *ol,
+ input_overlay_state_t *out,
+ int16_t norm_x, int16_t norm_y, float touch_scale);
+
+/**
+ * input_overlay_poll_clear:
+ * @ol : overlay handle
+ *
+ * Call when there is nothing to poll. Allows overlay to
+ * clear certain state.
+ **/
+void input_overlay_poll_clear(
+ enum overlay_visibility *visibility,
+ input_overlay_t *ol, float opacity);
+
+/**
+ * input_overlay_post_poll:
+ *
+ * Called after all the input_overlay_poll() calls to
+ * update the range modifiers for pressed/unpressed regions
+ * and alpha mods.
+ **/
+void input_overlay_post_poll(
+ enum overlay_visibility *visibility,
+ input_overlay_t *ol,
+ bool show_input, float opacity);
+
+void input_overlay_load_active(
+ enum overlay_visibility *visibility,
+ input_overlay_t *ol, float opacity);
+
+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);
+
+void input_overlay_set_vertex_geom(input_overlay_t *ol);
+
+void input_overlay_free_overlays(input_overlay_t *ol);
+
+/**
+ * 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.
+ **/
+void input_overlay_scale(struct overlay *ol,
+ const overlay_layout_t *layout);
+
+/**
+ * input_overlay_set_scale_factor:
+ * @ol : Overlay handle.
+ * @layout_desc : Scale + offset factors.
+ *
+ * Scales the overlay and applies any aspect ratio/
+ * offset factors.
+ **/
+void input_overlay_set_scale_factor(
+ input_overlay_t *ol, const overlay_layout_desc_t *layout_desc,
+ unsigned video_driver_width,
+ unsigned video_driver_height);
+
+/**
+ * input_overlay_set_alpha_mod:
+ * @ol : Overlay handle.
+ * @mod : New modulating factor to apply.
+ *
+ * Sets a modulating factor for alpha channel. Default is 1.0.
+ * The alpha factor is applied for all overlays.
+ **/
+void input_overlay_set_alpha_mod(
+ enum overlay_visibility *visibility,
+ input_overlay_t *ol, float mod);
+
+enum overlay_visibility input_overlay_get_visibility(
+ enum overlay_visibility *visibility,
+ int overlay_idx);
+
+/**
+ * input_overlay_free:
+ * @ol : Overlay handle.
+ *
+ * Frees overlay handle.
+ **/
+void input_overlay_free(input_overlay_t *ol);
+
RETRO_END_DECLS
#endif
diff --git a/retroarch.c b/retroarch.c
index 21801d33e1..a2137e61bb 100644
--- a/retroarch.c
+++ b/retroarch.c
@@ -12334,7 +12334,7 @@ bool command_event(enum event_command cmd, void *data)
p_rarch->overlay_ptr->active = &p_rarch->overlay_ptr->overlays[
p_rarch->overlay_ptr->index];
- input_overlay_load_active(p_rarch,
+ input_overlay_load_active(p_rarch->overlay_visibility,
p_rarch->overlay_ptr, input_overlay_opacity);
p_rarch->overlay_ptr->blocked = true;
@@ -12609,7 +12609,8 @@ bool command_event(enum event_command cmd, void *data)
layout_desc.touch_scale = (float)settings->uints.input_touch_scale;
layout_desc.auto_scale = settings->bools.input_overlay_auto_scale;
- input_overlay_set_scale_factor(p_rarch, p_rarch->overlay_ptr, &layout_desc);
+ input_overlay_set_scale_factor(p_rarch->overlay_ptr, &layout_desc,
+ p_rarch->video_driver_width, p_rarch->video_driver_height);
}
#endif
break;
@@ -12619,7 +12620,7 @@ bool command_event(enum event_command cmd, void *data)
#ifdef HAVE_OVERLAY
{
float input_overlay_opacity = settings->floats.input_overlay_opacity;
- input_overlay_set_alpha_mod(p_rarch,
+ input_overlay_set_alpha_mod(p_rarch->overlay_visibility,
p_rarch->overlay_ptr, input_overlay_opacity);
}
#endif
@@ -18631,342 +18632,6 @@ static bool bsv_movie_check(struct rarch_state *p_rarch,
static bool video_driver_overlay_interface(
const video_overlay_interface_t **iface);
-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)
- {
- /* 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 */
- overlay_layout->x_offset = layout_desc->x_offset_landscape;
- overlay_layout->y_offset = layout_desc->y_offset_landscape * -1.0f;
-
- 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 */
- overlay_layout->x_scale = (aspect_adjust >= 0.0f) ?
- (scale * (aspect_adjust + 1.0f)) :
- (scale / ((aspect_adjust * -1.0f) + 1.0f));
- overlay_layout->y_scale = scale;
- }
- }
- /* > Portrait display orientations */
- else
- {
- float scale = layout_desc->scale_portrait;
- float aspect_adjust = layout_desc->aspect_adjust_portrait;
-
- overlay_layout->x_offset = layout_desc->x_offset_portrait;
- overlay_layout->y_offset = layout_desc->y_offset_portrait * -1.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 */
- 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));
- }
- }
-}
-
-/**
- * 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++)
- {
- struct overlay_desc *desc = &ol->descs[i];
- float x_shift_offset = 0.0f;
- float y_shift_offset = 0.0f;
- float scale_w;
- float scale_h;
- float adj_center_x;
- float adj_center_y;
-
- /* Apply 'x separation' factor */
- if (desc->x < (0.5f - 0.0001f))
- x_shift_offset = layout->x_separation * -1.0f;
- else if (desc->x > (0.5f + 0.0001f))
- 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 = layout->y_separation * -1.0f;
- else if (desc->y > (0.5f + 0.0001f))
- y_shift_offset = layout->y_separation;
-
- desc->y_shift = desc->y + y_shift_offset;
-
- scale_w = ol->mod_w * desc->range_x;
- scale_h = ol->mod_h * desc->range_y;
- adj_center_x = ol->mod_x + desc->x_shift * ol->mod_w;
- adj_center_y = ol->mod_y + desc->y_shift * ol->mod_h;
-
- desc->mod_w = 2.0f * scale_w;
- desc->mod_h = 2.0f * scale_h;
- desc->mod_x = adj_center_x - scale_w;
- desc->mod_y = adj_center_y - scale_h;
- }
-}
-
-static void input_overlay_set_vertex_geom(input_overlay_t *ol)
-{
- size_t i;
-
- if (ol->active->image.pixels)
- ol->iface->vertex_geom(ol->iface_data, 0,
- ol->active->mod_x, ol->active->mod_y,
- ol->active->mod_w, ol->active->mod_h);
-
- if (ol->iface->vertex_geom)
- for (i = 0; i < ol->active->size; i++)
- {
- struct overlay_desc *desc = &ol->active->descs[i];
-
- if (!desc->image.pixels)
- continue;
-
- ol->iface->vertex_geom(ol->iface_data, desc->image_index,
- desc->mod_x, desc->mod_y, desc->mod_w, desc->mod_h);
- }
-}
-
-/**
- * input_overlay_set_scale_factor:
- * @ol : Overlay handle.
- * @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, const overlay_layout_desc_t *layout_desc)
-{
- float display_aspect_ratio = 0.0f;
- size_t i;
-
- 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++)
- {
- 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);
-}
-
-void input_overlay_free_overlay(struct overlay *overlay)
-{
- size_t i;
-
- if (!overlay)
- return;
-
- for (i = 0; i < overlay->size; i++)
- image_texture_free(&overlay->descs[i].image);
-
- if (overlay->load_images)
- free(overlay->load_images);
- overlay->load_images = NULL;
- if (overlay->descs)
- free(overlay->descs);
- overlay->descs = NULL;
- image_texture_free(&overlay->image);
-}
-
-static void input_overlay_free_overlays(input_overlay_t *ol)
-{
- size_t i;
-
- if (!ol || !ol->overlays)
- return;
-
- for (i = 0; i < ol->size; i++)
- input_overlay_free_overlay(&ol->overlays[i]);
-
- free(ol->overlays);
- ol->overlays = NULL;
-}
-
-static enum overlay_visibility input_overlay_get_visibility(
- struct rarch_state *p_rarch,
- int overlay_idx)
-{
- enum overlay_visibility *visibility = p_rarch->overlay_visibility;
-
- if (!visibility)
- return OVERLAY_VISIBILITY_DEFAULT;
- if ((overlay_idx < 0) || (overlay_idx >= MAX_VISIBILITY))
- return OVERLAY_VISIBILITY_DEFAULT;
- return visibility[overlay_idx];
-}
-
-
-static bool input_overlay_is_hidden(
- struct rarch_state *p_rarch,
- int overlay_idx)
-{
- return (input_overlay_get_visibility(p_rarch, overlay_idx)
- == OVERLAY_VISIBILITY_HIDDEN);
-}
-
-/**
- * input_overlay_set_alpha_mod:
- * @ol : Overlay handle.
- * @mod : New modulating factor to apply.
- *
- * Sets a modulating factor for alpha channel. Default is 1.0.
- * The alpha factor is applied for all overlays.
- **/
-static void input_overlay_set_alpha_mod(
- struct rarch_state *p_rarch,
- input_overlay_t *ol, float mod)
-{
- unsigned i;
-
- if (!ol)
- return;
-
- for (i = 0; i < ol->active->load_images_size; i++)
- {
- if (input_overlay_is_hidden(p_rarch, i))
- ol->iface->set_alpha(ol->iface_data, i, 0.0);
- else
- ol->iface->set_alpha(ol->iface_data, i, mod);
- }
-}
-
-
-static void input_overlay_load_active(
- struct rarch_state *p_rarch,
- input_overlay_t *ol, float opacity)
-{
- if (ol->iface->load)
- ol->iface->load(ol->iface_data, ol->active->load_images,
- ol->active->load_images_size);
-
- input_overlay_set_alpha_mod(p_rarch, ol, opacity);
- input_overlay_set_vertex_geom(ol);
-
- if (ol->iface->full_screen)
- ol->iface->full_screen(ol->iface_data, ol->active->full_screen);
-}
-
/* Attempts to automatically rotate the specified overlay.
* Depends upon proper naming conventions in overlay
* config file. */
@@ -19037,249 +18702,6 @@ static void input_overlay_auto_rotate_(
}
}
-/**
- * inside_hitbox:
- * @desc : Overlay descriptor handle.
- * @x : X coordinate value.
- * @y : Y coordinate value.
- *
- * Check whether the given @x and @y coordinates of the overlay
- * descriptor @desc is inside the overlay descriptor's hitbox.
- *
- * Returns: true (1) if X, Y coordinates are inside a hitbox,
- * otherwise false (0).
- **/
-static bool inside_hitbox(const struct overlay_desc *desc, float x, float y)
-{
- if (!desc)
- return false;
-
- switch (desc->hitbox)
- {
- case OVERLAY_HITBOX_RADIAL:
- {
- /* Ellipsis. */
- float x_dist = (x - desc->x_shift) / desc->range_x_mod;
- float y_dist = (y - desc->y_shift) / desc->range_y_mod;
- float sq_dist = x_dist * x_dist + y_dist * y_dist;
- return (sq_dist <= 1.0f);
- }
-
- case OVERLAY_HITBOX_RECT:
- return
- (fabs(x - desc->x_shift) <= desc->range_x_mod) &&
- (fabs(y - desc->y_shift) <= desc->range_y_mod);
- }
-
- return false;
-}
-
-/**
- * input_overlay_poll:
- * @out : Polled output data.
- * @norm_x : Normalized X coordinate.
- * @norm_y : Normalized Y coordinate.
- *
- * Polls input overlay.
- *
- * @norm_x and @norm_y are the result of
- * input_translate_coord_viewport().
- **/
-static void input_overlay_poll(
- input_overlay_t *ol,
- input_overlay_state_t *out,
- int16_t norm_x, int16_t norm_y, float touch_scale)
-{
- size_t i;
-
- /* norm_x and norm_y is in [-0x7fff, 0x7fff] range,
- * like RETRO_DEVICE_POINTER. */
- float x = (float)(norm_x + 0x7fff) / 0xffff;
- float y = (float)(norm_y + 0x7fff) / 0xffff;
-
- x -= ol->active->mod_x;
- y -= ol->active->mod_y;
- x /= ol->active->mod_w;
- y /= ol->active->mod_h;
-
- x *= touch_scale;
- y *= touch_scale;
-
- for (i = 0; i < ol->active->size; i++)
- {
- float x_dist, y_dist;
- unsigned int base = 0;
- struct overlay_desc *desc = &ol->active->descs[i];
-
- if (!inside_hitbox(desc, x, y))
- continue;
-
- desc->updated = true;
- x_dist = x - desc->x_shift;
- y_dist = y - desc->y_shift;
-
- switch (desc->type)
- {
- case OVERLAY_TYPE_BUTTONS:
- {
- bits_or_bits(out->buttons.data,
- desc->button_mask.data,
- ARRAY_SIZE(desc->button_mask.data));
-
- if (BIT256_GET(desc->button_mask, RARCH_OVERLAY_NEXT))
- ol->next_index = desc->next_index;
- }
- break;
- case OVERLAY_TYPE_KEYBOARD:
- if (desc->retro_key_idx < RETROK_LAST)
- OVERLAY_SET_KEY(out, desc->retro_key_idx);
- break;
- case OVERLAY_TYPE_ANALOG_RIGHT:
- base = 2;
- /* fall-through */
- default:
- {
- float x_val = x_dist / desc->range_x;
- float y_val = y_dist / desc->range_y;
- float x_val_sat = x_val / desc->analog_saturate_pct;
- float y_val_sat = y_val / desc->analog_saturate_pct;
- out->analog[base + 0] = clamp_float(x_val_sat, -1.0f, 1.0f)
- * 32767.0f;
- out->analog[base + 1] = clamp_float(y_val_sat, -1.0f, 1.0f)
- * 32767.0f;
- }
- break;
- }
-
- if (desc->movable)
- {
- desc->delta_x = clamp_float(x_dist, -desc->range_x, desc->range_x)
- * ol->active->mod_w;
- desc->delta_y = clamp_float(y_dist, -desc->range_y, desc->range_y)
- * ol->active->mod_h;
- }
- }
-
- if (!bits_any_set(out->buttons.data, ARRAY_SIZE(out->buttons.data)))
- ol->blocked = false;
- else if (ol->blocked)
- memset(out, 0, sizeof(*out));
-}
-
-/**
- * input_overlay_update_desc_geom:
- * @ol : overlay handle.
- * @desc : overlay descriptors handle.
- *
- * Update input overlay descriptors' vertex geometry.
- **/
-static void input_overlay_update_desc_geom(input_overlay_t *ol,
- struct overlay_desc *desc)
-{
- if (!desc->image.pixels || !desc->movable)
- return;
-
- if (ol->iface->vertex_geom)
- ol->iface->vertex_geom(ol->iface_data, desc->image_index,
- desc->mod_x + desc->delta_x, desc->mod_y + desc->delta_y,
- desc->mod_w, desc->mod_h);
-
- desc->delta_x = 0.0f;
- desc->delta_y = 0.0f;
-}
-
-/**
- * input_overlay_post_poll:
- *
- * Called after all the input_overlay_poll() calls to
- * update the range modifiers for pressed/unpressed regions
- * and alpha mods.
- **/
-static void input_overlay_post_poll(
- struct rarch_state *p_rarch, input_overlay_t *ol,
- bool show_input, float opacity)
-{
- size_t i;
-
- input_overlay_set_alpha_mod(p_rarch, ol, opacity);
-
- for (i = 0; i < ol->active->size; i++)
- {
- struct overlay_desc *desc = &ol->active->descs[i];
-
- desc->range_x_mod = desc->range_x;
- desc->range_y_mod = desc->range_y;
-
- if (desc->updated)
- {
- /* If pressed this frame, change the hitbox. */
- desc->range_x_mod *= desc->range_mod;
- desc->range_y_mod *= desc->range_mod;
-
- if (show_input && desc->image.pixels)
- {
- if (ol->iface->set_alpha)
- ol->iface->set_alpha(ol->iface_data, desc->image_index,
- desc->alpha_mod * opacity);
- }
- }
-
- input_overlay_update_desc_geom(ol, desc);
- desc->updated = false;
- }
-}
-
-/**
- * input_overlay_poll_clear:
- * @ol : overlay handle
- *
- * Call when there is nothing to poll. Allows overlay to
- * clear certain state.
- **/
-static void input_overlay_poll_clear(
- struct rarch_state *p_rarch,
- input_overlay_t *ol, float opacity)
-{
- size_t i;
-
- ol->blocked = false;
-
- input_overlay_set_alpha_mod(p_rarch, ol, opacity);
-
- for (i = 0; i < ol->active->size; i++)
- {
- struct overlay_desc *desc = &ol->active->descs[i];
-
- desc->range_x_mod = desc->range_x;
- desc->range_y_mod = desc->range_y;
- desc->updated = false;
-
- desc->delta_x = 0.0f;
- desc->delta_y = 0.0f;
- input_overlay_update_desc_geom(ol, desc);
- }
-}
-
-
-/**
- * input_overlay_free:
- * @ol : Overlay handle.
- *
- * Frees overlay handle.
- **/
-static void input_overlay_free(input_overlay_t *ol)
-{
- if (!ol)
- return;
-
- input_overlay_free_overlays(ol);
-
- if (ol->iface->enable)
- ol->iface->enable(ol->iface_data, false);
-
- free(ol);
-}
-
/* task_data = overlay_task_data_t* */
static void input_overlay_loaded(retro_task_t *task,
void *task_data, void *user_data, const char *err)
@@ -19327,7 +18749,7 @@ static void input_overlay_loaded(retro_task_t *task,
ol->iface = iface;
ol->iface_data = p_rarch->video_driver_data;
- input_overlay_load_active(p_rarch, ol, data->overlay_opacity);
+ input_overlay_load_active(p_rarch->overlay_visibility, ol, data->overlay_opacity);
/* Enable or disable the overlay. */
ol->enable = data->overlay_enable;
@@ -19335,7 +18757,8 @@ 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_desc);
+ input_overlay_set_scale_factor(ol, &data->layout_desc,
+ p_rarch->video_driver_width, p_rarch->video_driver_height);
ol->next_index = (unsigned)((ol->index + 1) % ol->size);
ol->state = OVERLAY_STATUS_NONE;
@@ -19396,7 +18819,6 @@ void input_overlay_set_visibility(int overlay_idx,
ol->iface->set_alpha(ol->iface_data, overlay_idx, 0.0);
}
-
/*
* input_poll_overlay:
*
@@ -19596,9 +19018,9 @@ static void input_poll_overlay(
input_overlay_show_inputs_port);
if (button_pressed || polled)
- input_overlay_post_poll(p_rarch, ol, button_pressed, opacity);
+ input_overlay_post_poll(p_rarch->overlay_visibility, ol, button_pressed, opacity);
else
- input_overlay_poll_clear(p_rarch, ol, opacity);
+ input_overlay_poll_clear(p_rarch->overlay_visibility, ol, opacity);
}
static void retroarch_overlay_deinit(struct rarch_state *p_rarch)
diff --git a/retroarch_fwd_decls.h b/retroarch_fwd_decls.h
index a77efe621f..cab4b1a9e7 100644
--- a/retroarch_fwd_decls.h
+++ b/retroarch_fwd_decls.h
@@ -101,13 +101,6 @@ static bool recording_deinit(struct rarch_state *p_rarch);
#ifdef HAVE_OVERLAY
static void retroarch_overlay_init(struct rarch_state *p_rarch);
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, const overlay_layout_desc_t *layout_desc);
-static void input_overlay_load_active(
- struct rarch_state *p_rarch,
- input_overlay_t *ol, float opacity);
static void input_overlay_auto_rotate_(struct rarch_state *p_rarch,
bool input_overlay_enable, input_overlay_t *ol);
#endif