summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAutechre2021-05-13 17:16:23 +0200
committerGitHub2021-05-13 17:16:23 +0200
commitcc1a07462113e7018a2e898b8293bcc15057a5bf (patch)
tree2c9cafd8e27b012582cc5ee5f1a49678bc509dc8
parent37430f22c5234cb09f2325575806b830f947bf8a (diff)
parent134aba2b37ca7fec28b6fcd1cd6fca0dd1abc9ab (diff)
downloadpicogpsp-cc1a07462113e7018a2e898b8293bcc15057a5bf.tar.gz
picogpsp-cc1a07462113e7018a2e898b8293bcc15057a5bf.tar.bz2
picogpsp-cc1a07462113e7018a2e898b8293bcc15057a5bf.zip
Merge pull request #86 from jdgleaver/ff-button
Add dedicated RetroPad fast-forward button
-rw-r--r--input.c34
-rw-r--r--input.h5
-rw-r--r--libretro.c81
-rw-r--r--libretro.h55
4 files changed, 162 insertions, 13 deletions
diff --git a/input.c b/input.c
index f4ab6e8..44455d2 100644
--- a/input.c
+++ b/input.c
@@ -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;
}
diff --git a/input.h b/input.h
index bec7997..90fc930 100644
--- a/input.h
+++ b/input.h
@@ -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);
diff --git a/libretro.c b/libretro.c
index 4126eca..28db9dd 100644
--- a/libretro.c
+++ b/libretro.c
@@ -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 },
+ };
+
+ 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 },
};
- environ_cb(RETRO_ENVIRONMENT_SET_INPUT_DESCRIPTORS, descriptors);
+ 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)
diff --git a/libretro.h b/libretro.h
index d843114..bda0b77 100644
--- a/libretro.h
+++ b/libretro.h
@@ -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