mirror of
https://github.com/libretro/RetroArch
synced 2025-02-07 03:40:24 +00:00
Fix the dirty input system badly mishandling IDs out of the range of 0-35.
Now the state array is dynamic, and can handle any size. The initial size is 256 elements (0-255, fixes FBA). An arbitrary limit of 65536 IDs is currently in there, intended to detect invalid arguments.
This commit is contained in:
parent
3b6f3d027c
commit
a129cffbd6
@ -17,7 +17,8 @@ typedef struct InputListElement_t
|
||||
unsigned port;
|
||||
unsigned device;
|
||||
unsigned index;
|
||||
int16_t state[36];
|
||||
int16_t *state;
|
||||
unsigned int state_size;
|
||||
} InputListElement;
|
||||
|
||||
extern struct retro_core_t current_core;
|
||||
@ -35,11 +36,42 @@ static bool unserialze_hook(const void *buf, size_t size);
|
||||
static void* InputListElementConstructor(void)
|
||||
{
|
||||
const int size = sizeof(InputListElement);
|
||||
void *ptr = calloc(1, size);
|
||||
|
||||
const int initial_state_array_size = 256;
|
||||
void *ptr = calloc(1, size);
|
||||
InputListElement *element = (InputListElement*)ptr;
|
||||
element->state_size = initial_state_array_size;
|
||||
element->state = (int16_t*)calloc(element->state_size, sizeof(int16_t));
|
||||
return ptr;
|
||||
}
|
||||
|
||||
static void InputListElementRealloc(InputListElement *element, unsigned int newSize)
|
||||
{
|
||||
if (newSize > element->state_size)
|
||||
{
|
||||
element->state = realloc(element->state, newSize * sizeof(int16_t));
|
||||
memset(&element->state[element->state_size], 0, (newSize - element->state_size) * sizeof(int16_t));
|
||||
element->state_size = newSize;
|
||||
}
|
||||
}
|
||||
|
||||
static void InputListElementExpand(InputListElement *element, unsigned int newIndex)
|
||||
{
|
||||
unsigned int newSize = element->state_size;
|
||||
if (newSize == 0) newSize = 32;
|
||||
while (newIndex >= newSize)
|
||||
{
|
||||
newSize *= 2;
|
||||
}
|
||||
InputListElementRealloc(element, newSize);
|
||||
}
|
||||
|
||||
static void InputListElementDestructor(void* element_ptr)
|
||||
{
|
||||
InputListElement *element = (InputListElement*)element_ptr;
|
||||
free(element->state);
|
||||
free(element_ptr);
|
||||
}
|
||||
|
||||
static void input_state_destroy(void)
|
||||
{
|
||||
mylist_destroy(&input_state_list);
|
||||
@ -50,11 +82,11 @@ static void input_state_set_last(unsigned port, unsigned device,
|
||||
{
|
||||
unsigned i;
|
||||
InputListElement *element = NULL;
|
||||
const unsigned MAX_ID = sizeof(element->state) / sizeof(int16_t);
|
||||
if (id >= 65536) return; /*arbitrary limit of up to 65536 elements in state array*/
|
||||
|
||||
if (!input_state_list)
|
||||
mylist_create(&input_state_list, 16,
|
||||
InputListElementConstructor, free);
|
||||
InputListElementConstructor, InputListElementDestructor);
|
||||
|
||||
/* find list item */
|
||||
for (i = 0; i < (unsigned)input_state_list->size; i++)
|
||||
@ -62,10 +94,13 @@ static void input_state_set_last(unsigned port, unsigned device,
|
||||
element = (InputListElement*)input_state_list->data[i];
|
||||
if ( (element->port == port) &&
|
||||
(element->device == device) &&
|
||||
(element->index == index) &&
|
||||
(id < MAX_ID)
|
||||
(element->index == index)
|
||||
)
|
||||
{
|
||||
if (id >= element->state_size)
|
||||
{
|
||||
InputListElementExpand(element, id);
|
||||
}
|
||||
element->state[id] = value;
|
||||
return;
|
||||
}
|
||||
@ -76,8 +111,11 @@ static void input_state_set_last(unsigned port, unsigned device,
|
||||
element->port = port;
|
||||
element->device = device;
|
||||
element->index = index;
|
||||
if (id < MAX_ID)
|
||||
element->state[id] = value;
|
||||
if (id >= element->state_size)
|
||||
{
|
||||
InputListElementExpand(element, id);
|
||||
}
|
||||
element->state[id] = value;
|
||||
}
|
||||
|
||||
int16_t input_state_get_last(unsigned port,
|
||||
@ -97,10 +135,14 @@ int16_t input_state_get_last(unsigned port,
|
||||
|
||||
if ( (element->port == port) &&
|
||||
(element->device == device) &&
|
||||
(element->index == index) &&
|
||||
(id < MAX_ID)
|
||||
)
|
||||
return element->state[id];
|
||||
(element->index == index))
|
||||
{
|
||||
if (id < element->state_size)
|
||||
{
|
||||
return element->state[id];
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user