mirror of
https://github.com/CTCaer/RetroArch.git
synced 2025-02-22 04:31:17 +00:00
Deterministic input for RunAhead, guaranteed to match the last polled input.
This commit is contained in:
parent
adb72755e1
commit
821462409e
@ -80,7 +80,7 @@ static void input_state_set_last(unsigned port, unsigned device,
|
||||
element->state[id] = value;
|
||||
}
|
||||
|
||||
static int16_t input_state_get_last(unsigned port,
|
||||
int16_t input_state_get_last(unsigned port,
|
||||
unsigned device, unsigned index, unsigned id)
|
||||
{
|
||||
unsigned i;
|
||||
|
@ -9,6 +9,8 @@ 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);
|
||||
|
||||
RETRO_END_DECLS
|
||||
|
||||
|
@ -30,6 +30,8 @@ static void unset_fast_savestate(void);
|
||||
static void set_hard_disable_audio(void);
|
||||
static void unset_hard_disable_audio(void);
|
||||
|
||||
static bool core_run_use_last_input(void);
|
||||
|
||||
static size_t runahead_save_state_size = 0;
|
||||
static bool runahead_save_state_size_known = false;
|
||||
|
||||
@ -174,13 +176,19 @@ static void runahead_clear_variables(void)
|
||||
runahead_last_frame_count = 0;
|
||||
}
|
||||
|
||||
static uint64_t runahead_get_frame_count()
|
||||
{
|
||||
bool is_alive, is_focused = false;
|
||||
uint64_t frame_count = 0;
|
||||
video_driver_get_status(&frame_count, &is_alive, &is_focused);
|
||||
return frame_count;
|
||||
}
|
||||
|
||||
|
||||
static void runahead_check_for_gui(void)
|
||||
{
|
||||
/* Hack: If we were in the GUI, force a resync. */
|
||||
bool is_alive, is_focused = false;
|
||||
uint64_t frame_count = 0;
|
||||
|
||||
video_driver_get_status(&frame_count, &is_alive, &is_focused);
|
||||
uint64_t frame_count = runahead_get_frame_count();
|
||||
|
||||
if (frame_count != runahead_last_frame_count + 1)
|
||||
runahead_force_input_dirty = true;
|
||||
@ -241,7 +249,7 @@ void run_ahead(int runahead_count, bool useSecondary)
|
||||
if (frame_number == 0)
|
||||
core_run();
|
||||
else
|
||||
core_run_no_input_polling();
|
||||
core_run_use_last_input();
|
||||
|
||||
if (suspended_frame)
|
||||
{
|
||||
@ -418,7 +426,7 @@ static bool runahead_load_state_secondary(void)
|
||||
|
||||
static bool runahead_run_secondary(void)
|
||||
{
|
||||
if (!secondary_core_run_no_input_polling())
|
||||
if (!secondary_core_run_use_last_input())
|
||||
{
|
||||
runahead_secondary_core_available = false;
|
||||
return false;
|
||||
@ -489,3 +497,32 @@ static void unset_hard_disable_audio(void)
|
||||
{
|
||||
hard_disable_audio = false;
|
||||
}
|
||||
|
||||
static void runahead_input_poll_null(void)
|
||||
{
|
||||
}
|
||||
|
||||
static bool core_run_use_last_input(void)
|
||||
{
|
||||
extern struct retro_callbacks retro_ctx;
|
||||
extern struct retro_core_t current_core;
|
||||
|
||||
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 = runahead_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);
|
||||
|
||||
current_core.retro_run();
|
||||
|
||||
retro_ctx.poll_cb = old_poll_function;
|
||||
retro_ctx.state_cb = old_input_function;
|
||||
|
||||
current_core.retro_set_input_poll(retro_ctx.poll_cb);
|
||||
current_core.retro_set_input_state(retro_ctx.state_cb);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@ -23,6 +23,7 @@
|
||||
#include "../content.h"
|
||||
|
||||
#include "secondary_core.h"
|
||||
#include "dirty_input.h"
|
||||
|
||||
static int port_map[16];
|
||||
|
||||
@ -304,11 +305,32 @@ void secondary_core_set_variable_update(void)
|
||||
has_variable_update = true;
|
||||
}
|
||||
|
||||
bool secondary_core_run_no_input_polling(void)
|
||||
static void secondary_core_input_poll_null(void)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
bool secondary_core_run_use_last_input(void)
|
||||
{
|
||||
if (secondary_core_ensure_exists())
|
||||
{
|
||||
retro_input_poll_t old_poll_function = secondary_callbacks.poll_cb;
|
||||
retro_input_state_t old_input_function = secondary_callbacks.state_cb;
|
||||
|
||||
secondary_callbacks.poll_cb = secondary_core_input_poll_null;
|
||||
secondary_callbacks.state_cb = input_state_get_last;
|
||||
|
||||
secondary_core.retro_set_input_poll(secondary_callbacks.poll_cb);
|
||||
secondary_core.retro_set_input_state(secondary_callbacks.state_cb);
|
||||
|
||||
secondary_core.retro_run();
|
||||
|
||||
secondary_callbacks.poll_cb = old_poll_function;
|
||||
secondary_callbacks.state_cb = old_input_function;
|
||||
|
||||
secondary_core.retro_set_input_poll(secondary_callbacks.poll_cb);
|
||||
secondary_core.retro_set_input_state(secondary_callbacks.state_cb);
|
||||
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
|
@ -10,7 +10,7 @@
|
||||
|
||||
RETRO_BEGIN_DECLS
|
||||
|
||||
bool secondary_core_run_no_input_polling(void);
|
||||
bool secondary_core_run_use_last_input(void);
|
||||
bool secondary_core_deserialize(const void *buffer, int size);
|
||||
bool secondary_core_ensure_exists(void);
|
||||
void secondary_core_destroy(void);
|
||||
|
Loading…
x
Reference in New Issue
Block a user