mirror of
https://github.com/libretro/RetroArch
synced 2025-03-29 22:20:21 +00:00
Merge pull request #1064 from CyberShadow/pull-20140928-032517
Fix/reimplement input flushing
This commit is contained in:
commit
3b5746b6c2
1
.gitignore
vendored
1
.gitignore
vendored
@ -61,6 +61,7 @@ apple/RetroArch_iOS.xcodeproj/project.xcworkspace/*
|
||||
/rsound.h
|
||||
.pc
|
||||
/media/shaders_glsl/
|
||||
/obj-w32/
|
||||
|
||||
# Android
|
||||
/android/phoenix/obj/
|
||||
|
10
driver.h
10
driver.h
@ -433,12 +433,13 @@ typedef struct driver
|
||||
const location_driver_t *location;
|
||||
struct retro_callbacks retro_ctx;
|
||||
|
||||
void *osk_data;
|
||||
void *camera_data;
|
||||
void *location_data;
|
||||
void *audio_data;
|
||||
void *video_data;
|
||||
void *input_data;
|
||||
void *osk_data;
|
||||
void *camera_data;
|
||||
void *location_data;
|
||||
|
||||
#ifdef HAVE_MENU
|
||||
menu_handle_t *menu;
|
||||
const menu_ctx_driver_t *menu_ctx;
|
||||
@ -480,10 +481,9 @@ typedef struct driver
|
||||
#endif
|
||||
bool stdin_claimed;
|
||||
bool block_hotkey;
|
||||
unsigned block_hotkey_until;
|
||||
bool block_input;
|
||||
bool block_libretro_input;
|
||||
unsigned block_libretro_input_until;
|
||||
bool flushing_input;
|
||||
bool nonblock_state;
|
||||
|
||||
/* Opaque handles to currently running window.
|
||||
|
@ -344,13 +344,6 @@ static void glui_free(void *data)
|
||||
g_extern.core_info = NULL;
|
||||
}
|
||||
|
||||
static int glui_input_postprocess(uint64_t old_state)
|
||||
{
|
||||
(void)old_state;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static GLuint glui_png_texture_load(const char * file_name)
|
||||
{
|
||||
struct texture_image ti = {0};
|
||||
@ -404,7 +397,7 @@ menu_ctx_driver_t menu_ctx_glui = {
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
glui_input_postprocess,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
|
@ -984,10 +984,10 @@ static void lakka_free(void *data)
|
||||
g_extern.core_info = NULL;
|
||||
}
|
||||
|
||||
static int lakka_input_postprocess(uint64_t old_state)
|
||||
static int lakka_input_postprocess(retro_input_t state, retro_input_t old_state)
|
||||
{
|
||||
if ((driver.menu && driver.menu->trigger_state
|
||||
& (1ULL << RARCH_MENU_TOGGLE)) &&
|
||||
retro_input_t trigger_state = state & ~old_state;
|
||||
if ((driver.menu && check_enter_menu_func(trigger_state)) &&
|
||||
g_extern.main_is_init &&
|
||||
!g_extern.libretro_dummy)
|
||||
global_alpha = 0;
|
||||
|
@ -18,7 +18,7 @@ typedef struct menu_ctx_driver
|
||||
void (*populate_entries)(void*, const char *, const char *,
|
||||
unsigned);
|
||||
void (*iterate)(void*, unsigned);
|
||||
int (*input_postprocess)(uint64_t);
|
||||
int (*input_postprocess)(uint64_t, uint64_t);
|
||||
void (*navigation_clear)(void *);
|
||||
void (*navigation_decrement)(void *);
|
||||
void (*navigation_increment)(void *);
|
||||
|
@ -447,11 +447,6 @@ static void rgui_free(void *data)
|
||||
free((uint8_t*)menu->font);
|
||||
}
|
||||
|
||||
static int rgui_input_postprocess(uint64_t old_state)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
void rgui_set_texture(void *data)
|
||||
{
|
||||
menu_handle_t *menu = (menu_handle_t*)data;
|
||||
@ -473,7 +468,7 @@ menu_ctx_driver_t menu_ctx_rgui = {
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
rgui_input_postprocess,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
|
@ -103,8 +103,6 @@ bool load_menu_content(void)
|
||||
/* redraw menu frame */
|
||||
if (driver.menu)
|
||||
{
|
||||
driver.menu->old_input_state = driver.menu->trigger_state = 0;
|
||||
driver.menu->do_held = false;
|
||||
driver.menu->msg_force = true;
|
||||
}
|
||||
|
||||
@ -172,9 +170,6 @@ void *menu_init(const void *data)
|
||||
menu_entries_push_list(menu, menu->selection_buf,
|
||||
"", "mainmenu", 0);
|
||||
|
||||
menu->trigger_state = 0;
|
||||
menu->old_input_state = 0;
|
||||
menu->do_held = false;
|
||||
menu->current_pad = 0;
|
||||
|
||||
update_libretro_info(&g_extern.menu.info);
|
||||
@ -302,8 +297,14 @@ bool menu_iterate(retro_input_t input,
|
||||
unsigned action = MENU_ACTION_NOOP;
|
||||
static bool initial_held = true;
|
||||
static bool first_held = false;
|
||||
uint64_t input_state = 0;
|
||||
int32_t ret = 0;
|
||||
static const retro_input_t input_repeat =
|
||||
(1ULL << RETRO_DEVICE_ID_JOYPAD_UP)
|
||||
| (1ULL << RETRO_DEVICE_ID_JOYPAD_DOWN)
|
||||
| (1ULL << RETRO_DEVICE_ID_JOYPAD_LEFT)
|
||||
| (1ULL << RETRO_DEVICE_ID_JOYPAD_RIGHT)
|
||||
| (1ULL << RETRO_DEVICE_ID_JOYPAD_L)
|
||||
| (1ULL << RETRO_DEVICE_ID_JOYPAD_R);
|
||||
|
||||
if (!driver.menu)
|
||||
return false;
|
||||
@ -316,9 +317,7 @@ bool menu_iterate(retro_input_t input,
|
||||
|
||||
driver.retro_ctx.poll_cb();
|
||||
|
||||
input_state = menu_input();
|
||||
|
||||
if (driver.menu->do_held)
|
||||
if (input & input_repeat)
|
||||
{
|
||||
if (!first_held)
|
||||
{
|
||||
@ -330,7 +329,7 @@ bool menu_iterate(retro_input_t input,
|
||||
if (driver.menu->delay_count >= driver.menu->delay_timer)
|
||||
{
|
||||
first_held = false;
|
||||
driver.menu->trigger_state = input_state;
|
||||
trigger_input |= input & input_repeat;
|
||||
driver.menu->scroll_accel = min(driver.menu->scroll_accel + 1, 64);
|
||||
}
|
||||
|
||||
@ -344,15 +343,14 @@ bool menu_iterate(retro_input_t input,
|
||||
}
|
||||
|
||||
driver.menu->delay_count++;
|
||||
driver.menu->old_input_state = input_state;
|
||||
|
||||
if (driver.block_input)
|
||||
driver.menu->trigger_state = 0;
|
||||
trigger_input = 0;
|
||||
|
||||
/* don't run anything first frame, only capture held inputs
|
||||
* for old_input_state.
|
||||
*/
|
||||
action = input_frame(driver.menu->trigger_state);
|
||||
action = input_frame(trigger_input);
|
||||
|
||||
if (driver.menu_ctx && driver.menu_ctx->backend
|
||||
&& driver.menu_ctx->backend->iterate)
|
||||
@ -362,7 +360,7 @@ bool menu_iterate(retro_input_t input,
|
||||
draw_frame(false);
|
||||
|
||||
if (driver.menu_ctx && driver.menu_ctx->input_postprocess)
|
||||
driver.menu_ctx->input_postprocess(driver.menu->old_input_state);
|
||||
driver.menu_ctx->input_postprocess(input, old_input);
|
||||
|
||||
#if 0
|
||||
/* Go back to Main Menu when exiting */
|
||||
|
@ -67,10 +67,7 @@ struct menu_bind_state
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint64_t old_input_state;
|
||||
uint64_t trigger_state;
|
||||
bool do_held;
|
||||
|
||||
/* Used for key repeat */
|
||||
unsigned delay_timer;
|
||||
unsigned delay_count;
|
||||
|
||||
|
@ -56,7 +56,7 @@ static void menu_key_end_line(void *data)
|
||||
menu->keyboard.label_setting = NULL;
|
||||
|
||||
/* Avoid triggering states on pressing return. */
|
||||
menu->old_input_state = -1ULL;
|
||||
driver.flushing_input = true;
|
||||
}
|
||||
|
||||
static void menu_search_callback(void *userdata, const char *str)
|
||||
@ -298,43 +298,6 @@ bool menu_custom_bind_keyboard_cb(void *data, unsigned code)
|
||||
return menu->binds.begin <= menu->binds.last;
|
||||
}
|
||||
|
||||
uint64_t menu_input(void)
|
||||
{
|
||||
unsigned i;
|
||||
retro_input_t input_state = 0;
|
||||
static const struct retro_keybind *binds[] = { g_settings.input.binds[0] };
|
||||
|
||||
if (!driver.menu)
|
||||
return 0;
|
||||
|
||||
input_push_analog_dpad((struct retro_keybind*)binds[0],
|
||||
(g_settings.input.analog_dpad_mode[0] == ANALOG_DPAD_NONE) ?
|
||||
ANALOG_DPAD_LSTICK : g_settings.input.analog_dpad_mode[0]);
|
||||
|
||||
for (i = 0; i < MAX_PLAYERS; i++)
|
||||
input_push_analog_dpad(g_settings.input.autoconf_binds[i],
|
||||
g_settings.input.analog_dpad_mode[i]);
|
||||
|
||||
input_state = input_keys_pressed(0, RARCH_FIRST_CUSTOM_BIND, binds);
|
||||
|
||||
input_pop_analog_dpad((struct retro_keybind*)binds[0]);
|
||||
for (i = 0; i < MAX_PLAYERS; i++)
|
||||
input_pop_analog_dpad(g_settings.input.autoconf_binds[i]);
|
||||
|
||||
driver.menu->trigger_state = input_state & ~driver.menu->old_input_state;
|
||||
|
||||
driver.menu->do_held = (input_state & (
|
||||
(1ULL << RETRO_DEVICE_ID_JOYPAD_UP)
|
||||
| (1ULL << RETRO_DEVICE_ID_JOYPAD_DOWN)
|
||||
| (1ULL << RETRO_DEVICE_ID_JOYPAD_LEFT)
|
||||
| (1ULL << RETRO_DEVICE_ID_JOYPAD_RIGHT)
|
||||
| (1ULL << RETRO_DEVICE_ID_JOYPAD_L)
|
||||
| (1ULL << RETRO_DEVICE_ID_JOYPAD_R)
|
||||
));
|
||||
|
||||
return input_state;
|
||||
}
|
||||
|
||||
int menu_input_bind_iterate(void *data)
|
||||
{
|
||||
char msg[PATH_MAX];
|
||||
@ -358,22 +321,22 @@ int menu_input_bind_iterate(void *data)
|
||||
&& driver.menu_ctx->render_messagebox)
|
||||
driver.menu_ctx->render_messagebox(msg);
|
||||
|
||||
driver.block_input = true;
|
||||
menu_poll_bind_state(&binds);
|
||||
|
||||
driver.block_hotkey_until = g_extern.frame_count + (15);
|
||||
|
||||
if ((binds.skip && !menu->binds.skip) ||
|
||||
menu_poll_find_trigger(&menu->binds, &binds))
|
||||
{
|
||||
driver.block_input = false;
|
||||
|
||||
/* Avoid new binds triggering things right away. */
|
||||
driver.flushing_input = true;
|
||||
|
||||
binds.begin++;
|
||||
if (binds.begin <= binds.last)
|
||||
binds.target++;
|
||||
else
|
||||
return 1;
|
||||
|
||||
/* Avoid new binds triggering things right away. */
|
||||
menu->trigger_state = 0;
|
||||
menu->old_input_state = -1ULL;
|
||||
}
|
||||
menu->binds = binds;
|
||||
|
||||
@ -416,14 +379,11 @@ int menu_input_bind_iterate_keyboard(void *data)
|
||||
timed_out = true;
|
||||
}
|
||||
|
||||
driver.block_hotkey_until = g_extern.frame_count + (15);
|
||||
|
||||
/* binds.begin is updated in keyboard_press callback. */
|
||||
if (menu->binds.begin > menu->binds.last)
|
||||
{
|
||||
/* Avoid new binds triggering things right away. */
|
||||
menu->trigger_state = 0;
|
||||
menu->old_input_state = -1ULL;
|
||||
driver.flushing_input = true;
|
||||
|
||||
/* We won't be getting any key events, so just cancel early. */
|
||||
if (timed_out)
|
||||
|
@ -42,6 +42,4 @@ int menu_input_bind_iterate(void *data);
|
||||
|
||||
int menu_input_bind_iterate_keyboard(void *data);
|
||||
|
||||
uint64_t menu_input(void);
|
||||
|
||||
#endif
|
||||
|
@ -503,9 +503,7 @@ static int android_input_get_id(android_input_t *android, AInputEvent *event)
|
||||
|
||||
static bool pause_key_pressed(void)
|
||||
{
|
||||
retro_input_t old_input = 0;
|
||||
retro_input_t input = meta_input_keys_pressed(RARCH_PAUSE_TOGGLE, RARCH_PAUSE_TOGGLE+1, &old_input);
|
||||
return BIND_PRESSED(input, RARCH_PAUSE_TOGGLE);
|
||||
return driver.input->key_pressed(driver.input_data, RARCH_PAUSE_TOGGLE);
|
||||
}
|
||||
|
||||
/* Handle all events. If our activity is in pause state,
|
||||
|
@ -1625,6 +1625,10 @@ retro_input_t input_keys_pressed(unsigned key,
|
||||
* from the specified key up until the last queryable key
|
||||
* (key_end).
|
||||
*
|
||||
* Because this function keeps a copy of the old input state,
|
||||
* it should only be called once per frame (currently in
|
||||
* rarch_main_iterate);
|
||||
*
|
||||
* TODO: In case RARCH_BIND_LIST_END starts exceeding 64,
|
||||
* and you need a bitmask of more than 64 entries, don't
|
||||
* use this function.
|
||||
@ -1634,20 +1638,29 @@ retro_input_t meta_input_keys_pressed(unsigned key,
|
||||
unsigned key_end, retro_input_t *old_state)
|
||||
{
|
||||
static retro_input_t old_ret = 0;
|
||||
static const struct retro_keybind *binds[] = { g_settings.input.binds[0] };
|
||||
retro_input_t ret = 0;
|
||||
*old_state = old_ret;
|
||||
int i;
|
||||
|
||||
#ifdef RARCH_INTERNAL
|
||||
rarch_check_block_hotkey(driver.input->key_pressed(driver.input_data,
|
||||
RARCH_ENABLE_HOTKEY));
|
||||
#endif
|
||||
|
||||
input_push_analog_dpad((struct retro_keybind*)binds[0],
|
||||
(g_settings.input.analog_dpad_mode[0] == ANALOG_DPAD_NONE) ?
|
||||
ANALOG_DPAD_LSTICK : g_settings.input.analog_dpad_mode[0]);
|
||||
|
||||
for (i = 0; i < MAX_PLAYERS; i++)
|
||||
input_push_analog_dpad(g_settings.input.autoconf_binds[i],
|
||||
g_settings.input.analog_dpad_mode[i]);
|
||||
|
||||
for (; key < key_end; key++)
|
||||
{
|
||||
bool state = false;
|
||||
|
||||
if (!driver.block_hotkey
|
||||
&& g_extern.frame_count > driver.block_hotkey_until)
|
||||
if (!driver.block_hotkey)
|
||||
state = driver.input->key_pressed(driver.input_data, key);
|
||||
|
||||
#ifdef HAVE_OVERLAY
|
||||
@ -1663,6 +1676,10 @@ retro_input_t meta_input_keys_pressed(unsigned key,
|
||||
ret |= (1ULL << key);
|
||||
}
|
||||
|
||||
input_pop_analog_dpad((struct retro_keybind*)binds[0]);
|
||||
for (i = 0; i < MAX_PLAYERS; i++)
|
||||
input_pop_analog_dpad(g_settings.input.autoconf_binds[i]);
|
||||
|
||||
old_ret = ret;
|
||||
|
||||
return ret;
|
||||
|
@ -183,8 +183,7 @@ static int16_t input_state(unsigned port, unsigned device,
|
||||
|
||||
if (!driver.block_libretro_input &&
|
||||
((id < RARCH_FIRST_META_KEY ||
|
||||
device == RETRO_DEVICE_KEYBOARD) &&
|
||||
(g_extern.frame_count > driver.block_libretro_input_until))
|
||||
device == RETRO_DEVICE_KEYBOARD))
|
||||
)
|
||||
res = driver.input->input_state(driver.input_data, binds, port,
|
||||
device, index, id);
|
||||
@ -203,6 +202,35 @@ static int16_t input_state(unsigned port, unsigned device,
|
||||
}
|
||||
#endif
|
||||
|
||||
{
|
||||
/* Last frame input_state was called. */
|
||||
static unsigned flush_frame = 0;
|
||||
/* Last frame which had input. */
|
||||
static unsigned flush_frame_input = 0;
|
||||
|
||||
if (driver.flushing_input)
|
||||
{
|
||||
if (flush_frame != g_extern.frame_count &&
|
||||
flush_frame != flush_frame_input)
|
||||
{
|
||||
/* At least one entire frame has passed with no input. */
|
||||
driver.flushing_input = false;
|
||||
flush_frame = flush_frame_input = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
flush_frame = g_extern.frame_count;
|
||||
if (res)
|
||||
{
|
||||
flush_frame_input = g_extern.frame_count;
|
||||
res = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
flush_frame = flush_frame_input = 0;
|
||||
}
|
||||
|
||||
/* Don't allow turbo for D-pad. */
|
||||
if (device == RETRO_DEVICE_JOYPAD && (id < RETRO_DEVICE_ID_JOYPAD_UP ||
|
||||
id > RETRO_DEVICE_ID_JOYPAD_RIGHT))
|
||||
|
@ -20,12 +20,15 @@
|
||||
#include <stdarg.h>
|
||||
#include <android/log.h>
|
||||
|
||||
// Log tag. Used for logcat filtering, e.g.: adb logcat RetroArch:V *:S
|
||||
#define RARCH_LOG_TAG "RetroArch"
|
||||
|
||||
#ifndef RARCH_LOG
|
||||
#define RARCH_LOG(...) __android_log_print(ANDROID_LOG_INFO, "RetroArch: ", __VA_ARGS__)
|
||||
#define RARCH_LOG(...) __android_log_print(ANDROID_LOG_INFO, RARCH_LOG_TAG, __VA_ARGS__)
|
||||
#endif
|
||||
|
||||
#ifndef RARCH_LOG_V
|
||||
#define RARCH_LOG_V(tag, fmt, vp) __android_log_vprint(ANDROID_LOG_INFO, "RetroArch: " tag, fmt, vp)
|
||||
#define RARCH_LOG_V(tag, fmt, vp) __android_log_vprint(ANDROID_LOG_INFO, RARCH_LOG_TAG tag, fmt, vp)
|
||||
#endif
|
||||
|
||||
#ifndef RARCH_LOG_OUTPUT
|
||||
@ -37,19 +40,19 @@
|
||||
#endif
|
||||
|
||||
#ifndef RARCH_ERR
|
||||
#define RARCH_ERR(...) __android_log_print(ANDROID_LOG_INFO, "RetroArch [ERROR] :: ", __VA_ARGS__)
|
||||
#define RARCH_ERR(...) __android_log_print(ANDROID_LOG_ERROR, RARCH_LOG_TAG, __VA_ARGS__)
|
||||
#endif
|
||||
|
||||
#ifndef RARCH_ERR_V
|
||||
#define RARCH_ERR_V(tag, fmt, vp) __android_log_vprint(ANDROID_LOG_INFO, "RetroArch [ERROR] :: " tag, fmt, vp)
|
||||
#define RARCH_ERR_V(tag, fmt, vp) __android_log_vprint(ANDROID_LOG_ERROR, RARCH_LOG_TAG tag, fmt, vp)
|
||||
#endif
|
||||
|
||||
#ifndef RARCH_WARN
|
||||
#define RARCH_WARN(...) __android_log_print(ANDROID_LOG_INFO, "RetroArch [WARN] :: ", __VA_ARGS__)
|
||||
#define RARCH_WARN(...) __android_log_print(ANDROID_LOG_WARN, RARCH_LOG_TAG, __VA_ARGS__)
|
||||
#endif
|
||||
|
||||
#ifndef RARCH_WARN_V
|
||||
#define RARCH_WARN_V(tag, fmt, vp) __android_log_print(ANDROID_LOG_INFO, "RetroArch [WARN] :: " tag, fmt, vp)
|
||||
#define RARCH_WARN_V(tag, fmt, vp) __android_log_print(ANDROID_LOG_WARN, RARCH_LOG_TAG tag, fmt, vp)
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
@ -1,20 +0,0 @@
|
||||
|
||||
Microsoft Visual Studio Solution File, Format Version 11.00
|
||||
# Visual C++ Express 2010
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "RetroArch-msvc2010", "RetroArch-msvc2010.vcxproj", "{27FF7CE1-4059-4AA1-8062-FD529560FA54}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Win32 = Debug|Win32
|
||||
Release|Win32 = Release|Win32
|
||||
EndGlobalSection
|
||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||
{27FF7CE1-4059-4AA1-8062-FD529560FA54}.Debug|Win32.ActiveCfg = Debug|Win32
|
||||
{27FF7CE1-4059-4AA1-8062-FD529560FA54}.Debug|Win32.Build.0 = Debug|Win32
|
||||
{27FF7CE1-4059-4AA1-8062-FD529560FA54}.Release|Win32.ActiveCfg = Release|Win32
|
||||
{27FF7CE1-4059-4AA1-8062-FD529560FA54}.Release|Win32.Build.0 = Release|Win32
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
EndGlobalSection
|
||||
EndGlobal
|
14
retroarch.c
14
retroarch.c
@ -2838,7 +2838,9 @@ void rarch_main_set_state(unsigned cmd)
|
||||
|
||||
rarch_main_command(RARCH_CMD_AUDIO_START);
|
||||
|
||||
driver.block_libretro_input_until = g_extern.frame_count + (5);
|
||||
/* Prevent stray input from going to libretro core */
|
||||
driver.flushing_input = true;
|
||||
|
||||
/* Restore libretro keyboard callback. */
|
||||
g_extern.system.key_event = g_extern.frontend_key_event;
|
||||
break;
|
||||
@ -3226,9 +3228,17 @@ bool rarch_main_iterate(void)
|
||||
{
|
||||
unsigned i;
|
||||
retro_input_t old_input, trigger_input;
|
||||
retro_input_t input = meta_input_keys_pressed(RARCH_FIRST_META_KEY,
|
||||
retro_input_t input = meta_input_keys_pressed(0,
|
||||
RARCH_BIND_LIST_END, &old_input);
|
||||
|
||||
if (driver.flushing_input)
|
||||
{
|
||||
if (input)
|
||||
input = 0;
|
||||
else
|
||||
driver.flushing_input = false;
|
||||
}
|
||||
|
||||
trigger_input = input & ~old_input;
|
||||
|
||||
/* Time to drop? */
|
||||
|
Loading…
x
Reference in New Issue
Block a user