Add dedicated RetroPad fast-forward button

This commit is contained in:
jdgleaver 2020-11-10 12:03:10 +00:00
parent 37430f22c5
commit 134aba2b37
4 changed files with 162 additions and 13 deletions

34
input.c
View File

@ -19,11 +19,18 @@
#include "common.h"
bool libretro_supports_bitmasks = false;
bool libretro_supports_ff_override = false;
bool libretro_ff_enabled = false;
bool libretro_ff_enabled_prev = false;
static u32 old_key = 0;
static retro_input_state_t input_state_cb;
void retro_set_input_state(retro_input_state_t cb) { input_state_cb = cb; }
extern void set_fastforward_override(bool fastforward);
static void trigger_key(u32 key)
{
u32 p1_cnt = io_registers[REG_P1CNT];
@ -53,8 +60,24 @@ u32 update_input(void)
if (!input_state_cb)
return 0;
for (i = 0; i < sizeof(btn_map) / sizeof(map); i++)
new_key |= input_state_cb(0, RETRO_DEVICE_JOYPAD, 0, btn_map[i].retropad) ? btn_map[i].gba : 0;
if (libretro_supports_bitmasks)
{
int16_t ret = input_state_cb(0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_MASK);
for (i = 0; i < sizeof(btn_map) / sizeof(map); i++)
new_key |= (ret & (1 << btn_map[i].retropad)) ? btn_map[i].gba : 0;
libretro_ff_enabled = libretro_supports_ff_override &&
(ret & (1 << RETRO_DEVICE_ID_JOYPAD_R2));
}
else
{
for (i = 0; i < sizeof(btn_map) / sizeof(map); i++)
new_key |= input_state_cb(0, RETRO_DEVICE_JOYPAD, 0, btn_map[i].retropad) ? btn_map[i].gba : 0;
libretro_ff_enabled = libretro_supports_ff_override &&
input_state_cb(0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_R2);
}
if ((new_key | old_key) != old_key)
trigger_key(new_key);
@ -62,6 +85,13 @@ u32 update_input(void)
old_key = new_key;
io_registers[REG_P1] = (~old_key) & 0x3FF;
/* Handle fast forward button */
if (libretro_ff_enabled != libretro_ff_enabled_prev)
{
set_fastforward_override(libretro_ff_enabled);
libretro_ff_enabled_prev = libretro_ff_enabled;
}
return 0;
}

View File

@ -56,6 +56,11 @@ static const map btn_map[] = {
{ RETRO_DEVICE_ID_JOYPAD_A, BUTTON_A }
};
extern bool libretro_supports_bitmasks;
extern bool libretro_supports_ff_override;
extern bool libretro_ff_enabled;
extern bool libretro_ff_enabled_prev;
void init_input(void);
u32 update_input(void);
void input_write_savestate(void);

View File

@ -339,6 +339,31 @@ static void init_post_processing(void)
/* Video post processing END */
/* Fast forward override */
void set_fastforward_override(bool fastforward)
{
struct retro_fastforwarding_override ff_override;
if (!libretro_supports_ff_override)
return;
ff_override.ratio = -1.0f;
ff_override.notification = true;
if (fastforward)
{
ff_override.fastforward = true;
ff_override.inhibit_toggle = true;
}
else
{
ff_override.fastforward = false;
ff_override.inhibit_toggle = false;
}
environ_cb(RETRO_ENVIRONMENT_SET_FASTFORWARDING_OVERRIDE, &ff_override);
}
static void video_run(void)
{
u16 *gba_screen_pixels_buf = gba_screen_pixels;
@ -496,6 +521,14 @@ void retro_init(void)
gba_screen_pixels = (uint16_t*)malloc(GBA_SCREEN_PITCH * GBA_SCREEN_HEIGHT * sizeof(uint16_t));
#endif
libretro_supports_bitmasks = false;
if (environ_cb(RETRO_ENVIRONMENT_GET_INPUT_BITMASKS, NULL))
libretro_supports_bitmasks = true;
libretro_supports_ff_override = false;
if (environ_cb(RETRO_ENVIRONMENT_SET_FASTFORWARDING_OVERRIDE, NULL))
libretro_supports_ff_override = true;
current_frameskip_type = no_frameskip;
frameskip_threshold = 0;
frameskip_interval = 0;
@ -813,20 +846,38 @@ static void check_variables(int started_from_load)
static void set_input_descriptors()
{
struct retro_input_descriptor descriptors[] = {
{ 0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_LEFT, "D-Pad Left" },
{ 0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_UP, "D-Pad Up" },
{ 0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_DOWN, "D-Pad Down" },
{ 0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_RIGHT, "D-Pad Right" },
{ 0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_B, "B" },
{ 0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_A, "A" },
{ 0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_SELECT, "Select" },
{ 0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_START, "Start" },
{ 0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_L, "L" },
{ 0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_R, "R" },
{ 0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_LEFT, "D-Pad Left" },
{ 0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_UP, "D-Pad Up" },
{ 0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_DOWN, "D-Pad Down" },
{ 0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_RIGHT, "D-Pad Right" },
{ 0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_B, "B" },
{ 0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_A, "A" },
{ 0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_SELECT, "Select" },
{ 0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_START, "Start" },
{ 0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_L, "L" },
{ 0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_R, "R" },
{ 0 },
};
environ_cb(RETRO_ENVIRONMENT_SET_INPUT_DESCRIPTORS, descriptors);
struct retro_input_descriptor descriptors_ff[] = {
{ 0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_LEFT, "D-Pad Left" },
{ 0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_UP, "D-Pad Up" },
{ 0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_DOWN, "D-Pad Down" },
{ 0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_RIGHT, "D-Pad Right" },
{ 0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_B, "B" },
{ 0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_A, "A" },
{ 0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_SELECT, "Select" },
{ 0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_START, "Start" },
{ 0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_L, "L" },
{ 0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_R, "R" },
{ 0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_R2, "Fast Forward" },
{ 0 },
};
if (libretro_supports_ff_override)
environ_cb(RETRO_ENVIRONMENT_SET_INPUT_DESCRIPTORS, descriptors_ff);
else
environ_cb(RETRO_ENVIRONMENT_SET_INPUT_DESCRIPTORS, descriptors);
}
static void set_memory_descriptors(void)
@ -921,6 +972,14 @@ bool retro_load_game_special(unsigned game_type,
void retro_unload_game(void)
{
update_backup();
if (libretro_ff_enabled)
set_fastforward_override(false);
libretro_supports_bitmasks = false;
libretro_supports_ff_override = false;
libretro_ff_enabled = false;
libretro_ff_enabled_prev = false;
}
unsigned retro_get_region(void)

View File

@ -282,6 +282,7 @@ enum retro_language
RETRO_LANGUAGE_PERSIAN = 20,
RETRO_LANGUAGE_HEBREW = 21,
RETRO_LANGUAGE_ASTURIAN = 22,
RETRO_LANGUAGE_FINNISH = 23,
RETRO_LANGUAGE_LAST,
/* Ensure sizeof(enum) == sizeof(int) */
@ -712,6 +713,9 @@ enum retro_mod
* state of rumble motors in controllers.
* A strong and weak motor is supported, and they can be
* controlled indepedently.
* Should be called from either retro_init() or retro_load_game().
* Should not be called from retro_set_environment().
* Returns false if rumble functionality is unavailable.
*/
#define RETRO_ENVIRONMENT_GET_INPUT_DEVICE_CAPABILITIES 24
/* uint64_t * --
@ -1374,6 +1378,16 @@ enum retro_mod
* call will target the newly initialized driver.
*/
#define RETRO_ENVIRONMENT_SET_FASTFORWARDING_OVERRIDE 64
/* const struct retro_fastforwarding_override * --
* Used by a libretro core to override the current
* fastforwarding mode of the frontend.
* If NULL is passed to this function, the frontend
* will return true if fastforwarding override
* functionality is supported (no change in
* fastforwarding state will occur in this case).
*/
/* VFS functionality */
/* File paths:
@ -2934,6 +2948,47 @@ struct retro_framebuffer
Set by frontend in GET_CURRENT_SOFTWARE_FRAMEBUFFER. */
};
/* Used by a libretro core to override the current
* fastforwarding mode of the frontend */
struct retro_fastforwarding_override
{
/* Specifies the runtime speed multiplier that
* will be applied when 'fastforward' is true.
* For example, a value of 5.0 when running 60 FPS
* content will cap the fast-forward rate at 300 FPS.
* Note that the target multiplier may not be achieved
* if the host hardware has insufficient processing
* power.
* Setting a value of 0.0 (or greater than 0.0 but
* less than 1.0) will result in an uncapped
* fast-forward rate (limited only by hardware
* capacity).
* If the value is negative, it will be ignored
* (i.e. the frontend will use a runtime speed
* multiplier of its own choosing) */
float ratio;
/* If true, fastforwarding mode will be enabled.
* If false, fastforwarding mode will be disabled. */
bool fastforward;
/* If true, and if supported by the frontend, an
* on-screen notification will be displayed while
* 'fastforward' is true.
* If false, and if supported by the frontend, any
* on-screen fast-forward notifications will be
* suppressed */
bool notification;
/* If true, the core will have sole control over
* when fastforwarding mode is enabled/disabled;
* the frontend will not be able to change the
* state set by 'fastforward' until either
* 'inhibit_toggle' is set to false, or the core
* is unloaded */
bool inhibit_toggle;
};
/* Callbacks */
/* Environment callback. Gives implementations a way of performing