mirror of
https://github.com/libretro/RetroArch
synced 2025-03-29 22:20:21 +00:00
Move runahead dirty_input to retroarch.c - allows us
to make retro_ctx and current_core static
This commit is contained in:
parent
d12e857644
commit
10c5331cc0
@ -265,7 +265,6 @@ OBJ += frontend/frontend.o \
|
||||
ifeq ($(HAVE_RUNAHEAD), 1)
|
||||
DEFINES += -DHAVE_RUNAHEAD
|
||||
OBJ += runahead/copy_load_info.o \
|
||||
runahead/dirty_input.o \
|
||||
runahead/mem_util.o \
|
||||
runahead/mylist.o \
|
||||
runahead/secondary_core.o
|
||||
|
2
core.h
2
core.h
@ -234,8 +234,6 @@ bool core_is_game_loaded(void);
|
||||
|
||||
void core_free_retro_game_info(struct retro_game_info *dest);
|
||||
|
||||
extern struct retro_callbacks retro_ctx;
|
||||
|
||||
RETRO_END_DECLS
|
||||
|
||||
#endif
|
||||
|
@ -1369,7 +1369,6 @@ MENU
|
||||
#include "../runahead/mem_util.c"
|
||||
#include "../runahead/secondary_core.c"
|
||||
#include "../runahead/copy_load_info.c"
|
||||
#include "../runahead/dirty_input.c"
|
||||
#include "../runahead/mylist.c"
|
||||
#endif
|
||||
|
||||
|
219
retroarch.c
219
retroarch.c
@ -240,6 +240,9 @@ typedef struct runloop_ctx_msg_info
|
||||
|
||||
static struct global g_extern;
|
||||
|
||||
static struct retro_callbacks retro_ctx;
|
||||
static struct retro_core_t current_core;
|
||||
|
||||
static jmp_buf error_sjlj_context;
|
||||
static enum rarch_core_type current_core_type = CORE_TYPE_PLAIN;
|
||||
static enum rarch_core_type explicit_current_core_type = CORE_TYPE_PLAIN;
|
||||
@ -11651,6 +11654,212 @@ static bool hard_disable_audio = false;
|
||||
/* Save State List for Run Ahead */
|
||||
static MyList *runahead_save_state_list = NULL;
|
||||
|
||||
static bool input_is_dirty = false;
|
||||
static MyList *input_state_list = NULL;
|
||||
|
||||
typedef struct InputListElement_t
|
||||
{
|
||||
unsigned port;
|
||||
unsigned device;
|
||||
unsigned index;
|
||||
int16_t *state;
|
||||
unsigned int state_size;
|
||||
} InputListElement;
|
||||
|
||||
typedef bool(*LoadStateFunction)(const void*, size_t);
|
||||
|
||||
static function_t retro_reset_callback_original = NULL;
|
||||
static LoadStateFunction retro_unserialize_callback_original = NULL;
|
||||
static retro_input_state_t input_state_callback_original;
|
||||
|
||||
static void* InputListElementConstructor(void)
|
||||
{
|
||||
const int size = sizeof(InputListElement);
|
||||
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 new_size)
|
||||
{
|
||||
if (new_size > element->state_size)
|
||||
{
|
||||
element->state = (int16_t*)realloc(element->state,
|
||||
new_size * sizeof(int16_t));
|
||||
memset(&element->state[element->state_size], 0,
|
||||
(new_size - element->state_size) * sizeof(int16_t));
|
||||
element->state_size = new_size;
|
||||
}
|
||||
}
|
||||
|
||||
static void InputListElementExpand(
|
||||
InputListElement *element, unsigned int newIndex)
|
||||
{
|
||||
unsigned int new_size = element->state_size;
|
||||
if (new_size == 0)
|
||||
new_size = 32;
|
||||
while (newIndex >= new_size)
|
||||
new_size *= 2;
|
||||
InputListElementRealloc(element, new_size);
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
static void input_state_set_last(unsigned port, unsigned device,
|
||||
unsigned index, unsigned id, int16_t value)
|
||||
{
|
||||
unsigned i;
|
||||
InputListElement *element = NULL;
|
||||
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, InputListElementDestructor);
|
||||
|
||||
/* find list item */
|
||||
for (i = 0; i < (unsigned)input_state_list->size; i++)
|
||||
{
|
||||
element = (InputListElement*)input_state_list->data[i];
|
||||
if ( (element->port == port) &&
|
||||
(element->device == device) &&
|
||||
(element->index == index)
|
||||
)
|
||||
{
|
||||
if (id >= element->state_size)
|
||||
InputListElementExpand(element, id);
|
||||
element->state[id] = value;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
element = (InputListElement*)
|
||||
mylist_add_element(input_state_list);
|
||||
element->port = port;
|
||||
element->device = device;
|
||||
element->index = index;
|
||||
if (id >= element->state_size)
|
||||
InputListElementExpand(element, id);
|
||||
element->state[id] = value;
|
||||
}
|
||||
|
||||
int16_t input_state_get_last(unsigned port,
|
||||
unsigned device, unsigned index, unsigned id)
|
||||
{
|
||||
unsigned i;
|
||||
|
||||
if (!input_state_list)
|
||||
return 0;
|
||||
|
||||
/* find list item */
|
||||
for (i = 0; i < (unsigned)input_state_list->size; i++)
|
||||
{
|
||||
InputListElement *element =
|
||||
(InputListElement*)input_state_list->data[i];
|
||||
|
||||
if ( (element->port == port) &&
|
||||
(element->device == device) &&
|
||||
(element->index == index))
|
||||
{
|
||||
if (id < element->state_size)
|
||||
return element->state[id];
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int16_t input_state_with_logging(unsigned port,
|
||||
unsigned device, unsigned index, unsigned id)
|
||||
{
|
||||
if (input_state_callback_original)
|
||||
{
|
||||
int16_t result = input_state_callback_original(
|
||||
port, device, index, id);
|
||||
int16_t last_input = input_state_get_last(port, device, index, id);
|
||||
if (result != last_input)
|
||||
input_is_dirty = true;
|
||||
input_state_set_last(port, device, index, id, result);
|
||||
return result;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void reset_hook(void)
|
||||
{
|
||||
input_is_dirty = true;
|
||||
if (retro_reset_callback_original)
|
||||
retro_reset_callback_original();
|
||||
}
|
||||
|
||||
static bool unserialze_hook(const void *buf, size_t size)
|
||||
{
|
||||
input_is_dirty = true;
|
||||
if (retro_unserialize_callback_original)
|
||||
return retro_unserialize_callback_original(buf, size);
|
||||
return false;
|
||||
}
|
||||
|
||||
static void add_input_state_hook(void)
|
||||
{
|
||||
if (!input_state_callback_original)
|
||||
{
|
||||
input_state_callback_original = retro_ctx.state_cb;
|
||||
retro_ctx.state_cb = input_state_with_logging;
|
||||
current_core.retro_set_input_state(retro_ctx.state_cb);
|
||||
}
|
||||
|
||||
if (!retro_reset_callback_original)
|
||||
{
|
||||
retro_reset_callback_original = current_core.retro_reset;
|
||||
current_core.retro_reset = reset_hook;
|
||||
}
|
||||
|
||||
if (!retro_unserialize_callback_original)
|
||||
{
|
||||
retro_unserialize_callback_original = current_core.retro_unserialize;
|
||||
current_core.retro_unserialize = unserialze_hook;
|
||||
}
|
||||
}
|
||||
|
||||
static void remove_input_state_hook(void)
|
||||
{
|
||||
if (input_state_callback_original)
|
||||
{
|
||||
retro_ctx.state_cb = input_state_callback_original;
|
||||
current_core.retro_set_input_state(retro_ctx.state_cb);
|
||||
input_state_callback_original = NULL;
|
||||
input_state_destroy();
|
||||
}
|
||||
|
||||
if (retro_reset_callback_original)
|
||||
{
|
||||
current_core.retro_reset = retro_reset_callback_original;
|
||||
retro_reset_callback_original = NULL;
|
||||
}
|
||||
|
||||
if (retro_unserialize_callback_original)
|
||||
{
|
||||
current_core.retro_unserialize = retro_unserialize_callback_original;
|
||||
retro_unserialize_callback_original = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
static void *runahead_save_state_alloc(void)
|
||||
{
|
||||
retro_ctx_serialize_info_t *savestate = (retro_ctx_serialize_info_t*)
|
||||
@ -11714,9 +11923,6 @@ static void runahead_save_state_list_rotate(void)
|
||||
static function_t originalRetroDeinit = NULL;
|
||||
static function_t originalRetroUnload = NULL;
|
||||
|
||||
extern struct retro_core_t current_core;
|
||||
extern struct retro_callbacks retro_ctx;
|
||||
|
||||
static void runahead_remove_hooks(void)
|
||||
{
|
||||
if (originalRetroDeinit)
|
||||
@ -11916,8 +12122,8 @@ static bool runahead_core_run_use_last_input(void)
|
||||
retro_input_poll_t old_poll_function = retro_ctx.poll_cb;
|
||||
retro_input_state_t old_input_function = retro_ctx.state_cb;
|
||||
|
||||
retro_ctx.poll_cb = retro_input_poll_null;
|
||||
retro_ctx.state_cb = input_state_get_last;
|
||||
retro_ctx.poll_cb = retro_input_poll_null;
|
||||
retro_ctx.state_cb = input_state_get_last;
|
||||
|
||||
current_core.retro_set_input_poll(retro_ctx.poll_cb);
|
||||
current_core.retro_set_input_state(retro_ctx.state_cb);
|
||||
@ -16715,9 +16921,6 @@ enum retro_language rarch_get_language_from_iso(const char *iso639)
|
||||
|
||||
/* Libretro core loader */
|
||||
|
||||
struct retro_callbacks retro_ctx;
|
||||
struct retro_core_t current_core;
|
||||
|
||||
static void retro_run_null(void)
|
||||
{
|
||||
}
|
||||
|
@ -1,223 +0,0 @@
|
||||
#include <stdlib.h>
|
||||
|
||||
#include <boolean.h>
|
||||
#include <dynamic/dylib.h>
|
||||
|
||||
#include "../core.h"
|
||||
#include "../dynamic.h"
|
||||
|
||||
#include "mylist.h"
|
||||
#include "mem_util.h"
|
||||
#include "dirty_input.h"
|
||||
|
||||
bool input_is_dirty = false;
|
||||
static MyList *input_state_list = NULL;
|
||||
|
||||
typedef struct InputListElement_t
|
||||
{
|
||||
unsigned port;
|
||||
unsigned device;
|
||||
unsigned index;
|
||||
int16_t *state;
|
||||
unsigned int state_size;
|
||||
} InputListElement;
|
||||
|
||||
extern struct retro_core_t current_core;
|
||||
extern struct retro_callbacks retro_ctx;
|
||||
|
||||
typedef bool(*LoadStateFunction)(const void*, size_t);
|
||||
|
||||
static function_t retro_reset_callback_original = NULL;
|
||||
static LoadStateFunction retro_unserialize_callback_original = NULL;
|
||||
static retro_input_state_t input_state_callback_original;
|
||||
|
||||
static void reset_hook(void);
|
||||
static bool unserialze_hook(const void *buf, size_t size);
|
||||
|
||||
static void* InputListElementConstructor(void)
|
||||
{
|
||||
const int size = sizeof(InputListElement);
|
||||
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 new_size)
|
||||
{
|
||||
if (new_size > element->state_size)
|
||||
{
|
||||
element->state = (int16_t*)realloc(element->state,
|
||||
new_size * sizeof(int16_t));
|
||||
memset(&element->state[element->state_size], 0,
|
||||
(new_size - element->state_size) * sizeof(int16_t));
|
||||
element->state_size = new_size;
|
||||
}
|
||||
}
|
||||
|
||||
static void InputListElementExpand(
|
||||
InputListElement *element, unsigned int newIndex)
|
||||
{
|
||||
unsigned int new_size = element->state_size;
|
||||
if (new_size == 0)
|
||||
new_size = 32;
|
||||
while (newIndex >= new_size)
|
||||
new_size *= 2;
|
||||
InputListElementRealloc(element, new_size);
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
static void input_state_set_last(unsigned port, unsigned device,
|
||||
unsigned index, unsigned id, int16_t value)
|
||||
{
|
||||
unsigned i;
|
||||
InputListElement *element = NULL;
|
||||
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, InputListElementDestructor);
|
||||
|
||||
/* find list item */
|
||||
for (i = 0; i < (unsigned)input_state_list->size; i++)
|
||||
{
|
||||
element = (InputListElement*)input_state_list->data[i];
|
||||
if ( (element->port == port) &&
|
||||
(element->device == device) &&
|
||||
(element->index == index)
|
||||
)
|
||||
{
|
||||
if (id >= element->state_size)
|
||||
InputListElementExpand(element, id);
|
||||
element->state[id] = value;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
element = (InputListElement*)
|
||||
mylist_add_element(input_state_list);
|
||||
element->port = port;
|
||||
element->device = device;
|
||||
element->index = index;
|
||||
if (id >= element->state_size)
|
||||
InputListElementExpand(element, id);
|
||||
element->state[id] = value;
|
||||
}
|
||||
|
||||
int16_t input_state_get_last(unsigned port,
|
||||
unsigned device, unsigned index, unsigned id)
|
||||
{
|
||||
unsigned i;
|
||||
|
||||
if (!input_state_list)
|
||||
return 0;
|
||||
|
||||
/* find list item */
|
||||
for (i = 0; i < (unsigned)input_state_list->size; i++)
|
||||
{
|
||||
InputListElement *element =
|
||||
(InputListElement*)input_state_list->data[i];
|
||||
|
||||
if ( (element->port == port) &&
|
||||
(element->device == device) &&
|
||||
(element->index == index))
|
||||
{
|
||||
if (id < element->state_size)
|
||||
return element->state[id];
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int16_t input_state_with_logging(unsigned port,
|
||||
unsigned device, unsigned index, unsigned id)
|
||||
{
|
||||
if (input_state_callback_original)
|
||||
{
|
||||
int16_t result = input_state_callback_original(
|
||||
port, device, index, id);
|
||||
int16_t last_input = input_state_get_last(port, device, index, id);
|
||||
if (result != last_input)
|
||||
input_is_dirty = true;
|
||||
input_state_set_last(port, device, index, id, result);
|
||||
return result;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void reset_hook(void)
|
||||
{
|
||||
input_is_dirty = true;
|
||||
if (retro_reset_callback_original)
|
||||
retro_reset_callback_original();
|
||||
}
|
||||
|
||||
static bool unserialze_hook(const void *buf, size_t size)
|
||||
{
|
||||
input_is_dirty = true;
|
||||
if (retro_unserialize_callback_original)
|
||||
return retro_unserialize_callback_original(buf, size);
|
||||
return false;
|
||||
}
|
||||
|
||||
void add_input_state_hook(void)
|
||||
{
|
||||
if (!input_state_callback_original)
|
||||
{
|
||||
input_state_callback_original = retro_ctx.state_cb;
|
||||
retro_ctx.state_cb = input_state_with_logging;
|
||||
current_core.retro_set_input_state(retro_ctx.state_cb);
|
||||
}
|
||||
|
||||
if (!retro_reset_callback_original)
|
||||
{
|
||||
retro_reset_callback_original = current_core.retro_reset;
|
||||
current_core.retro_reset = reset_hook;
|
||||
}
|
||||
|
||||
if (!retro_unserialize_callback_original)
|
||||
{
|
||||
retro_unserialize_callback_original = current_core.retro_unserialize;
|
||||
current_core.retro_unserialize = unserialze_hook;
|
||||
}
|
||||
}
|
||||
|
||||
void remove_input_state_hook(void)
|
||||
{
|
||||
if (input_state_callback_original)
|
||||
{
|
||||
retro_ctx.state_cb = input_state_callback_original;
|
||||
current_core.retro_set_input_state(retro_ctx.state_cb);
|
||||
input_state_callback_original = NULL;
|
||||
input_state_destroy();
|
||||
}
|
||||
|
||||
if (retro_reset_callback_original)
|
||||
{
|
||||
current_core.retro_reset = retro_reset_callback_original;
|
||||
retro_reset_callback_original = NULL;
|
||||
}
|
||||
|
||||
if (retro_unserialize_callback_original)
|
||||
{
|
||||
current_core.retro_unserialize = retro_unserialize_callback_original;
|
||||
retro_unserialize_callback_original = NULL;
|
||||
}
|
||||
}
|
@ -6,9 +6,6 @@
|
||||
|
||||
RETRO_BEGIN_DECLS
|
||||
|
||||
extern bool input_is_dirty;
|
||||
void add_input_state_hook(void);
|
||||
void remove_input_state_hook(void);
|
||||
int16_t input_state_get_last(unsigned port,
|
||||
unsigned device, unsigned index, unsigned id);
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user