Fixes for overlay buttons

This commit is contained in:
David Walters 2017-12-17 12:36:18 +00:00
parent 2fa03755eb
commit adffa5fc4c
4 changed files with 123 additions and 94 deletions

View File

@ -43,7 +43,7 @@ typedef struct input_overlay_state
int16_t analog[4];
uint32_t keys[RETROK_LAST / 32 + 1];
/* This is a bitmask of (1 << key_bind_id). */
uint64_t buttons;
retro_bits_t buttons;
} input_overlay_state_t;
struct input_overlay
@ -302,17 +302,15 @@ static void input_overlay_poll(
{
case OVERLAY_TYPE_BUTTONS:
{
uint64_t mask = desc->key_mask;
bits_or_bits(out->buttons.data, desc->button_mask.data, ARRAY_SIZE(desc->button_mask.data));
out->buttons |= mask;
if (mask & (UINT64_C(1) << RARCH_OVERLAY_NEXT))
if (BIT256_GET(desc->button_mask, RARCH_OVERLAY_NEXT))
ol->next_index = desc->next_index;
}
break;
case OVERLAY_TYPE_KEYBOARD:
if (desc->key_mask < RETROK_LAST)
OVERLAY_SET_KEY(out, desc->key_mask);
if (desc->retro_key_idx < RETROK_LAST)
OVERLAY_SET_KEY(out, desc->retro_key_idx);
break;
default:
{
@ -338,7 +336,7 @@ static void input_overlay_poll(
}
}
if (!out->buttons)
if (bits_any_set(out->buttons.data, ARRAY_SIZE(out->buttons.data)))
ol->blocked = false;
else if (ol->blocked)
memset(out, 0, sizeof(*out));
@ -556,12 +554,12 @@ bool input_overlay_is_alive(input_overlay_t *ol)
return false;
}
bool input_overlay_key_pressed(input_overlay_t *ol, int key)
bool input_overlay_key_pressed(input_overlay_t *ol, unsigned key)
{
input_overlay_state_t *ol_state = ol ? &ol->overlay_state : NULL;
if (!ol)
return false;
return (ol_state->buttons & (UINT64_C(1) << key));
return (BIT256_GET(ol_state->buttons, key));
}
/*
@ -616,12 +614,12 @@ void input_poll_overlay(input_overlay_t *ol, float opacity, unsigned analog_dpad
else
ol->blocked = false;
ol_state->buttons |= polled_data.buttons;
bits_or_bits(ol_state->buttons.data, polled_data.buttons.data, ARRAY_SIZE(polled_data.buttons.data));
for (j = 0; j < ARRAY_SIZE(ol_state->keys); j++)
ol_state->keys[j] |= polled_data.keys[j];
/* Fingers pressed later take prio and matched up
/* Fingers pressed later take priority and matched up
* with overlay poll priorities. */
for (j = 0; j < 4; j++)
if (polled_data.analog[j])
@ -693,13 +691,13 @@ void input_poll_overlay(input_overlay_t *ol, float opacity, unsigned analog_dpad
analog_y = (float)ol_state->analog[analog_base + 1] / 0x7fff;
if (analog_x <= -axis_threshold)
BIT32_SET(ol_state->buttons, RETRO_DEVICE_ID_JOYPAD_LEFT);
BIT256_SET(ol_state->buttons, RETRO_DEVICE_ID_JOYPAD_LEFT);
if (analog_x >= axis_threshold)
BIT32_SET(ol_state->buttons, RETRO_DEVICE_ID_JOYPAD_RIGHT);
BIT256_SET(ol_state->buttons, RETRO_DEVICE_ID_JOYPAD_RIGHT);
if (analog_y <= -axis_threshold)
BIT32_SET(ol_state->buttons, RETRO_DEVICE_ID_JOYPAD_UP);
BIT256_SET(ol_state->buttons, RETRO_DEVICE_ID_JOYPAD_UP);
if (analog_y >= axis_threshold)
BIT32_SET(ol_state->buttons, RETRO_DEVICE_ID_JOYPAD_DOWN);
BIT256_SET(ol_state->buttons, RETRO_DEVICE_ID_JOYPAD_DOWN);
break;
}
@ -767,14 +765,100 @@ void input_state_overlay(input_overlay_t *ol, int16_t *ret,
* Adds inputs from current_input to the overlay, so it's displayed
* returns true if an input that is pressed will change the overlay
*/
static bool input_overlay_add_inputs_inner(overlay_desc_t *desc,
unsigned port, unsigned analog_dpad_mode)
{
switch(desc->type)
{
case OVERLAY_TYPE_BUTTONS:
{
unsigned i;
unsigned id;
uint32_t bank_mask;
bool all_buttons_pressed = false;
/*Check each bank of the mask*/
for (i=0; i<ARRAY_SIZE(desc->button_mask.data); ++i)
{
/*Get bank*/
bank_mask = BITS_GET_ELEM(desc->button_mask,i);
id = i*32;
/*Worth pursuing? Have we got any bits left in here?*/
while (bank_mask)
{
/*If this bit is set then we need to query the pad
*The button must be pressed.*/
if (bank_mask & 1)
{
/* Light up the button if pressed */
if(input_state(port, RETRO_DEVICE_JOYPAD, 0, id))
{
all_buttons_pressed = true;
desc->updated = true;
}
else
{
/*we need ALL of the inputs to be active*/
all_buttons_pressed = false;
desc->updated = false;
/*abort*/
return false;
}
}
bank_mask >>= 1;
++id;
}
}
return all_buttons_pressed;
}
case OVERLAY_TYPE_ANALOG_LEFT:
case OVERLAY_TYPE_ANALOG_RIGHT:
{
float analog_x, analog_y;
float dx, dy;
unsigned int index = (desc->type == OVERLAY_TYPE_ANALOG_RIGHT) ?
RETRO_DEVICE_INDEX_ANALOG_RIGHT : RETRO_DEVICE_INDEX_ANALOG_LEFT;
analog_x = input_state(port, RETRO_DEVICE_ANALOG, index, RETRO_DEVICE_ID_ANALOG_X);
analog_y = input_state(port, RETRO_DEVICE_ANALOG, index, RETRO_DEVICE_ID_ANALOG_Y);
dx = (analog_x/0x8000)*(desc->range_x/2);
dy = (analog_y/0x8000)*(desc->range_y/2);
desc->delta_x = dx;
desc->delta_y = dy;
/*Maybe use some option here instead of 0, only display
changes greater than some magnitude.
*/
if((dx*dx) > 0 || (dy*dy) > 0)
return true;
}
break;
case OVERLAY_TYPE_KEYBOARD:
if(input_state(port, RETRO_DEVICE_KEYBOARD, 0, desc->retro_key_idx))
{
desc->updated = true;
return true;
}
break;
default:
break;
}
return false;
}
static bool input_overlay_add_inputs(input_overlay_t *ol,
unsigned port, unsigned analog_dpad_mode)
{
unsigned i;
uint64_t mask;
int id;
bool button_pressed = false;
bool current_button_pressed = false;
input_overlay_state_t *ol_state = &ol->overlay_state;
if(!ol_state)
@ -783,73 +867,7 @@ static bool input_overlay_add_inputs(input_overlay_t *ol,
for(i = 0; i < ol->active->size; i++)
{
overlay_desc_t *desc = &(ol->active->descs[i]);
switch(desc->type)
{
case OVERLAY_TYPE_BUTTONS:
mask = desc->key_mask;
id = RETRO_DEVICE_ID_JOYPAD_B;
/* Need to check all bits in the mask,
* multiple ones can be pressed */
current_button_pressed = false;
while(mask)
{
/* Get the next button ID */
while(mask && (mask & 1) == 0)
{
id+=1;
mask = mask >> 1;
}
/* Light up the button if pressed */
if(input_state(port, RETRO_DEVICE_JOYPAD, 0, id))
{
current_button_pressed = true;
desc->updated = true;
id+=1;
mask = mask >> 1;
}
else
{
/* One of the buttons not pressed */
current_button_pressed = false;
desc->updated = false;
break;
}
}
button_pressed = button_pressed || current_button_pressed;
break;
case OVERLAY_TYPE_ANALOG_LEFT:
case OVERLAY_TYPE_ANALOG_RIGHT:
{
float analog_x, analog_y;
float dx, dy;
unsigned int index = (desc->type == OVERLAY_TYPE_ANALOG_RIGHT) ?
RETRO_DEVICE_INDEX_ANALOG_RIGHT : RETRO_DEVICE_INDEX_ANALOG_LEFT;
analog_x = input_state(port, RETRO_DEVICE_ANALOG, index, RETRO_DEVICE_ID_ANALOG_X);
analog_y = input_state(port, RETRO_DEVICE_ANALOG, index, RETRO_DEVICE_ID_ANALOG_Y);
dx = (analog_x/0x8000)*(desc->range_x/2);
dy = (analog_y/0x8000)*(desc->range_y/2);
desc->delta_x = dx;
desc->delta_y = dy;
/*Maybe use some option here instead of 0, only display
changes greater than some magnitude.
*/
if((dx*dx) > 0 || (dy*dy) > 0)
button_pressed = true;
}
break;
case OVERLAY_TYPE_KEYBOARD:
if(input_state(port, RETRO_DEVICE_KEYBOARD, 0, (unsigned)desc->key_mask))
{
desc->updated = true;
button_pressed = true;
}
break;
default:
break;
}
button_pressed |= input_overlay_add_inputs_inner(desc, port, analog_dpad_mode);
}
return button_pressed;

View File

@ -172,7 +172,11 @@ struct overlay_desc
float x;
float y;
uint64_t key_mask;
/* This is a retro_key value for keyboards */
unsigned retro_key_idx;
/* This is a bit mask of all input binds to set with this overlay control */
retro_bits_t button_mask;
char next_index_name[64];
@ -247,7 +251,7 @@ void input_state_overlay(input_overlay_t *ol,
int16_t *ret, unsigned port, unsigned device, unsigned idx,
unsigned id);
bool input_overlay_key_pressed(input_overlay_t *ol, int key);
bool input_overlay_key_pressed(input_overlay_t *ol, unsigned key);
bool input_overlay_is_alive(input_overlay_t *ol);

View File

@ -42,6 +42,13 @@
#include <compat/msvc.h>
#endif
static INLINE void bits_or_bits(uint32_t *a, uint32_t *b, uint32_t count)
{
uint32_t i;
for (i = 0; i < count;i++)
a[i] |= b[i];
}
static INLINE void bits_clear_bits(uint32_t *a, uint32_t *b, uint32_t count)
{
uint32_t i;

View File

@ -177,7 +177,8 @@ static bool task_overlay_load_desc(
box_hash = djb2_calculate(box);
key_hash = djb2_calculate(key);
desc->key_mask = 0;
desc->retro_key_idx = 0;
BIT256_CLEAR_ALL(desc->button_mask);
switch (key_hash)
{
@ -190,8 +191,8 @@ static bool task_overlay_load_desc(
default:
if (strstr(key, "retrok_") == key)
{
desc->type = OVERLAY_TYPE_KEYBOARD;
desc->key_mask = input_config_translate_str_to_rk(key + 7);
desc->type = OVERLAY_TYPE_KEYBOARD;
desc->retro_key_idx = input_config_translate_str_to_rk(key + 7);
}
else
{
@ -203,11 +204,10 @@ static bool task_overlay_load_desc(
for (; tmp; tmp = strtok_r(NULL, "|", &save))
{
if (!string_is_equal(tmp, file_path_str(FILE_PATH_NUL)))
desc->key_mask |= UINT64_C(1)
<< input_config_translate_str_to_bind_id(tmp);
BIT256_SET(desc->button_mask, input_config_translate_str_to_bind_id(tmp));
}
if (desc->key_mask & (UINT64_C(1) << RARCH_OVERLAY_NEXT))
if (BIT256_GET(desc->button_mask, RARCH_OVERLAY_NEXT))
{
char overlay_target_key[64];