From e164457c02dc02a191dcc44856e04427f49733d6 Mon Sep 17 00:00:00 2001 From: Themaister Date: Tue, 31 Dec 2013 17:15:28 +0100 Subject: [PATCH] Add support for movable overlay elements. Very useful for visual feedback of analog controls. --- input/overlay.c | 46 +++++++++++++++++++++++++++--- media/overlays/example/example.cfg | 7 ++++- retroarch.c | 3 +- 3 files changed, 50 insertions(+), 6 deletions(-) diff --git a/input/overlay.c b/input/overlay.c index 52f56aec49..7023e3a523 100644 --- a/input/overlay.c +++ b/input/overlay.c @@ -47,6 +47,7 @@ struct overlay_desc float range_x, range_y; float range_x_mod, range_y_mod; float mod_x, mod_y, mod_w, mod_h; + float delta_x, delta_y; enum overlay_type type; uint64_t key_mask; @@ -62,6 +63,7 @@ struct overlay_desc float range_mod; bool updated; + bool movable; }; struct overlay @@ -391,6 +393,12 @@ static bool input_overlay_load_desc(input_overlay_t *ol, config_file_t *conf, st desc->range_mod = range_mod; config_get_float(conf, conf_key, &desc->range_mod); + snprintf(conf_key, sizeof(conf_key), "overlay%u_desc%u_movable", ol_index, desc_index); + desc->movable = false; + desc->delta_x = 0.0f; + desc->delta_y = 0.0f; + config_get_bool(conf, conf_key, &desc->movable); + desc->range_x_mod = desc->range_x; desc->range_y_mod = desc->range_y; @@ -762,12 +770,24 @@ void input_overlay_poll(input_overlay_t *ol, input_overlay_state_t *out, int16_t } else { - float x_val = (x - desc->x) / desc->range_x_mod / desc->analog_saturate_pct; - float y_val = (y - desc->y) / desc->range_y_mod / desc->analog_saturate_pct; + float x_dist = x - desc->x; + float y_dist = y - desc->y; + float x_val = x_dist / desc->range_x_mod; + float y_val = y_dist / desc->range_y_mod; + float x_val_sat = x_val / desc->analog_saturate_pct; + float y_val_sat = y_val / desc->analog_saturate_pct; unsigned int base = (desc->type == OVERLAY_TYPE_ANALOG_RIGHT) ? 2 : 0; - out->analog[base + 0] = clamp(x_val, -1.0f, 1.0f) * 32767.0f; - out->analog[base + 1] = clamp(y_val, -1.0f, 1.0f) * 32767.0f; + out->analog[base + 0] = clamp(x_val_sat, -1.0f, 1.0f) * 32767.0f; + out->analog[base + 1] = clamp(y_val_sat, -1.0f, 1.0f) * 32767.0f; + } + + if (desc->movable) + { + float x_dist = x - desc->x; + float y_dist = y - desc->y; + desc->delta_x = clamp(x_dist, -desc->range_x, desc->range_x) * ol->active->mod_w; + desc->delta_y = clamp(y_dist, -desc->range_y, desc->range_y) * ol->active->mod_h; } } @@ -777,6 +797,19 @@ void input_overlay_poll(input_overlay_t *ol, input_overlay_state_t *out, int16_t memset(out, 0, sizeof(*out)); } +static void input_overlay_update_desc_geom(input_overlay_t *ol, struct overlay_desc *desc) +{ + if (desc->image.image && desc->movable) + { + 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(input_overlay_t *ol) { size_t i; @@ -803,6 +836,7 @@ void input_overlay_post_poll(input_overlay_t *ol) desc->range_y_mod = desc->range_y; } + input_overlay_update_desc_geom(ol, desc); desc->updated = false; } } @@ -819,6 +853,10 @@ void input_overlay_poll_clear(input_overlay_t *ol) 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); } } diff --git a/media/overlays/example/example.cfg b/media/overlays/example/example.cfg index c9545599b1..ac391321f9 100644 --- a/media/overlays/example/example.cfg +++ b/media/overlays/example/example.cfg @@ -8,7 +8,7 @@ overlay0_alpha_mod = 2.0 # If we press a button desc, it will have twice the alp overlay0_range_mod = 1.5 # If we press a button desc, the hitbox range will be 1.5x the size until it's released. overlay0_normalized = true # Descriptor coordinates use normalized coordinates [0, 1] instead of pixels. -overlay0_descs = 5 +overlay0_descs = 6 overlay0_desc0_overlay = left.png overlay0_desc1_overlay = right.png overlay0_desc2_overlay = up.png @@ -20,3 +20,8 @@ overlay0_desc3 = "down,0.50,0.75,rect,0.125,0.125" overlay0_desc4 = "nul,0.30,0.90,rect,0.28,0.08" # Paste an arbitrary image. Input associated with this is nul. overlay0_desc4_overlay = logo.png + +overlay0_desc5 = "analog_left,0.1,0.1,radial,0.10,0.15" +overlay0_desc5_overlay = analog.png +overlay0_desc5_range_mod = 2.0 +overlay0_desc5_movable = true diff --git a/retroarch.c b/retroarch.c index 186c4e328c..7d0a5c242f 100644 --- a/retroarch.c +++ b/retroarch.c @@ -511,8 +511,9 @@ static inline void input_poll_overlay(void) driver.overlay_state.buttons |= polled_data.buttons; + // Fingers pressed later take prio and matched up with overlay poll priorities. for (j = 0; j < 4; j++) - if (!driver.overlay_state.analog[j]) + if (polled_data.analog[j]) driver.overlay_state.analog[j] = polled_data.analog[j]; polled = true;