Skip to content

Commit 1edc22d

Browse files
authored
I added some functionality and changed the controls to expose (#18691)
the new functionality. The biggest change is that save states work for most (I say most because one can't seek through some broken by design test files I have available.) files. I've also added a seek that increments or decrements the position in the file according to a strength which cycles through a fixed set of seconds by again pressing the relevant button. I also changed the audio and subtitle controls to allow more handling by moving forwards or backwards through the available streams within the given file. Finally, I made a null subtitle state so that subtitles can be disabled by simply cycling through the available streams.
1 parent 6229ff1 commit 1edc22d

1 file changed

Lines changed: 139 additions & 38 deletions

File tree

cores/libretro-ffmpeg/ffmpeg_core.c

Lines changed: 139 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -612,17 +612,38 @@ static void seek_frame(int seek_frames)
612612
slock_unlock(fifo_lock);
613613
}
614614

615+
static int seek_adjust(int target)
616+
{
617+
switch (target)
618+
{
619+
case 0: return 10; /* The logic is kind of */
620+
case 10: return 30; /* silly on the face of */
621+
case 30: return 60; /* it, but we needed a */
622+
case 60: return 90; /* strong seek to get to */
623+
case 90: return 300; /* the middle or end of */
624+
case 300: return 310; /* a long film; the result */
625+
case 310: return 330; /* is this block which is */
626+
case 330: return 360; /* used to adjust the seek */
627+
case 360: return 390; /* strength without using */
628+
case 390: return 10; /* multiple variables. */
629+
}
630+
}
631+
615632
void CORE_PREFIX(retro_run)(void)
616633
{
617634
static bool last_left;
618635
static bool last_right;
619636
static bool last_up;
620637
static bool last_down;
621-
static bool last_l;
622-
static bool last_r;
638+
static bool last_l1;
639+
static bool last_l2;
640+
static bool last_r1;
641+
static bool last_r2;
642+
static int seek_l2;
643+
static int seek_r2;
623644
double min_pts;
624645
int16_t audio_buffer[media.sample_rate / 20];
625-
bool left, right, up, down, l, r;
646+
bool left, right, up, down, l1, l2, r1, r2;
626647
int16_t ret = 0;
627648
size_t to_read_frames = 0;
628649
int seek_frames = 0;
@@ -666,35 +687,54 @@ void CORE_PREFIX(retro_run)(void)
666687
}
667688

668689
if (CORE_PREFIX(input_state_cb)(0, RETRO_DEVICE_MOUSE, 0, RETRO_DEVICE_ID_MOUSE_WHEELUP))
669-
ret |= (1 << RETRO_DEVICE_ID_JOYPAD_UP);
690+
ret |= (1 << RETRO_DEVICE_ID_JOYPAD_R);
670691
if (CORE_PREFIX(input_state_cb)(0, RETRO_DEVICE_MOUSE, 0, RETRO_DEVICE_ID_MOUSE_WHEELDOWN))
671-
ret |= (1 << RETRO_DEVICE_ID_JOYPAD_DOWN);
692+
ret |= (1 << RETRO_DEVICE_ID_JOYPAD_L);
672693

673694
left = ret & (1 << RETRO_DEVICE_ID_JOYPAD_LEFT);
674695
right = ret & (1 << RETRO_DEVICE_ID_JOYPAD_RIGHT);
675696
up = ret & (1 << RETRO_DEVICE_ID_JOYPAD_UP);
676697
down = ret & (1 << RETRO_DEVICE_ID_JOYPAD_DOWN);
677-
l = ret & (1 << RETRO_DEVICE_ID_JOYPAD_L);
678-
r = ret & (1 << RETRO_DEVICE_ID_JOYPAD_R);
698+
l1 = ret & (1 << RETRO_DEVICE_ID_JOYPAD_L);
699+
l2 = ret & (1 << RETRO_DEVICE_ID_JOYPAD_L2);
700+
r1 = ret & (1 << RETRO_DEVICE_ID_JOYPAD_R);
701+
r2 = ret & (1 << RETRO_DEVICE_ID_JOYPAD_R2);
702+
703+
if (l1 && !last_l1)
704+
{
705+
seek_frames -= 30 * media.interpolate_fps;
706+
seek_l2 = 0;
707+
}
708+
if (r1 && !last_r1)
709+
{
710+
seek_frames += 30 * media.interpolate_fps;
711+
seek_l2 = 0;
712+
}
679713

680-
if (left && !last_left)
681-
seek_frames -= 10 * media.interpolate_fps;
682-
if (right && !last_right)
683-
seek_frames += 10 * media.interpolate_fps;
684-
if (up && !last_up)
685-
seek_frames += 60 * media.interpolate_fps;
686-
if (down && !last_down)
687-
seek_frames -= 60 * media.interpolate_fps;
714+
if (l2 && !last_l2)
715+
{
716+
seek_l2 = seek_adjust(seek_l2);
717+
seek_frames -= seek_l2 * media.interpolate_fps;
718+
}
688719

689-
if (l && !last_l && audio_streams_num > 0)
720+
if (r2 && !last_r2)
721+
{
722+
seek_r2 = seek_adjust(seek_r2);
723+
seek_frames += seek_r2 * media.interpolate_fps;
724+
}
725+
726+
if (((up && !last_up) || (down && !last_down)) && audio_streams_num > 0)
690727
{
691728
char msg[256];
692729
struct retro_message_ext msg_obj = {0};
730+
int adjustment = (up) ? (+1) : ((down) ? (-1) : (0));
731+
732+
seek_l2 = 0;
693733

694734
msg[0] = '\0';
695735

696736
slock_lock(decode_thread_lock);
697-
audio_streams_ptr = (audio_streams_ptr + 1) % audio_streams_num;
737+
audio_streams_ptr = (((audio_streams_ptr + adjustment) % audio_streams_num) + audio_streams_num) % audio_streams_num;
698738
slock_unlock(decode_thread_lock);
699739

700740
snprintf(msg, sizeof(msg), "Audio Track #%d.", audio_streams_ptr);
@@ -708,18 +748,25 @@ void CORE_PREFIX(retro_run)(void)
708748
msg_obj.progress = -1;
709749
CORE_PREFIX(environ_cb)(RETRO_ENVIRONMENT_SET_MESSAGE_EXT, &msg_obj);
710750
}
711-
else if (r && !last_r && subtitle_streams_num > 0)
751+
752+
if (((right && !last_right) || (left && !last_left)) && subtitle_streams_num > 0)
712753
{
713754
char msg[256];
714755
struct retro_message_ext msg_obj = {0};
756+
int adjustment = (right) ? (+1) : ((left) ? (-1) : (0));
757+
758+
seek_l2 = 0;
715759

716760
msg[0] = '\0';
717761

718762
slock_lock(decode_thread_lock);
719-
subtitle_streams_ptr = (subtitle_streams_ptr + 1) % subtitle_streams_num;
763+
subtitle_streams_ptr = (((subtitle_streams_ptr + adjustment) % (subtitle_streams_num + 1)) + (subtitle_streams_num + 1)) % (subtitle_streams_num + 1);
720764
slock_unlock(decode_thread_lock);
721765

722-
snprintf(msg, sizeof(msg), "Subtitle Track #%d.", subtitle_streams_ptr);
766+
if(subtitle_streams_ptr)
767+
snprintf(msg, sizeof(msg), "Subtitle Track #%d.", subtitle_streams_ptr - 1);
768+
else
769+
snprintf(msg, sizeof(msg), "Subtitles Disabled.");
723770

724771
msg_obj.msg = msg;
725772
msg_obj.duration = 3000;
@@ -735,8 +782,10 @@ void CORE_PREFIX(retro_run)(void)
735782
last_right = right;
736783
last_up = up;
737784
last_down = down;
738-
last_l = l;
739-
last_r = r;
785+
last_l1 = l1;
786+
last_l2 = l2;
787+
last_r1 = r1;
788+
last_r2 = r2;
740789

741790
if (reset_triggered)
742791
{
@@ -1228,6 +1277,7 @@ static bool codec_id_is_ass(enum AVCodecID id)
12281277
{
12291278
case AV_CODEC_ID_ASS:
12301279
case AV_CODEC_ID_SSA:
1280+
case AV_CODEC_ID_SUBRIP:
12311281
return true;
12321282
default:
12331283
break;
@@ -1699,11 +1749,11 @@ static void decode_thread_seek(double time)
16991749
avcodec_flush_buffers(actx[audio_streams_ptr]);
17001750
if (vctx)
17011751
avcodec_flush_buffers(vctx);
1702-
if (sctx[subtitle_streams_ptr])
1703-
avcodec_flush_buffers(sctx[subtitle_streams_ptr]);
1752+
if (subtitle_streams_ptr && sctx[subtitle_streams_ptr - 1])
1753+
avcodec_flush_buffers(sctx[subtitle_streams_ptr - 1]);
17041754
#ifdef HAVE_SSA
1705-
if (ass_track[subtitle_streams_ptr])
1706-
ass_flush_events(ass_track[subtitle_streams_ptr]);
1755+
if (subtitle_streams_ptr && ass_track[subtitle_streams_ptr - 1])
1756+
ass_flush_events(ass_track[subtitle_streams_ptr - 1]);
17071757
#endif
17081758
}
17091759

@@ -1815,11 +1865,11 @@ static void decode_thread(void *data)
18151865
slock_lock(decode_thread_lock);
18161866
audio_stream_index = audio_streams[audio_streams_ptr];
18171867
audio_stream_ptr = audio_streams_ptr;
1818-
subtitle_stream = subtitle_streams[subtitle_streams_ptr];
1868+
subtitle_stream = subtitle_streams_ptr ? subtitle_streams[subtitle_streams_ptr - 1] : 0;
18191869
actx_active = actx[audio_streams_ptr];
1820-
sctx_active = sctx[subtitle_streams_ptr];
1870+
sctx_active = subtitle_streams_ptr ? sctx[subtitle_streams_ptr - 1] : 0;
18211871
#ifdef HAVE_SSA
1822-
ass_track_active = ass_track[subtitle_streams_ptr];
1872+
ass_track_active = subtitle_streams_ptr ? ass_track[subtitle_streams_ptr - 1] : 0;
18231873
#endif
18241874
audio_timebase = av_q2d(fctx->streams[audio_stream_index]->time_base);
18251875
if (video_stream_index >= 0)
@@ -2176,12 +2226,14 @@ bool CORE_PREFIX(retro_load_game)(const struct retro_game_info *info)
21762226
enum retro_pixel_format fmt = RETRO_PIXEL_FORMAT_XRGB8888;
21772227

21782228
struct retro_input_descriptor desc[] = {
2179-
{ 0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_LEFT, "Seek -10 seconds" },
2180-
{ 0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_UP, "Seek +60 seconds" },
2181-
{ 0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_DOWN, "Seek -60 seconds" },
2182-
{ 0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_RIGHT, "Seek +10 seconds" },
2183-
{ 0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_L, "Cycle Audio Track" },
2184-
{ 0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_R, "Cycle Subtitle Track" },
2229+
{ 0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_LEFT, "Decrement Subtitle Index" },
2230+
{ 0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_RIGHT, "Increment Subtitle Index" },
2231+
{ 0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_UP, "Increment Audio Index" },
2232+
{ 0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_DOWN, "Decrement Audio Index" },
2233+
{ 0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_L, "Seek -60 seconds" },
2234+
{ 0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_R, "Seek +60 seconds" },
2235+
{ 0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_L2, "Seek Decrementally" },
2236+
{ 0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_R2, "Seek Incrementally" },
21852237

21862238
{ 0 },
21872239
};
@@ -2307,13 +2359,62 @@ bool CORE_PREFIX(retro_load_game_special)(unsigned type, const struct retro_game
23072359
return false;
23082360
}
23092361

2362+
typedef struct
2363+
{
2364+
uint64_t frame_cnt;
2365+
int audio_streams_ptr;
2366+
int subtitle_streams_ptr;
2367+
} serialized_data;
2368+
23102369
size_t CORE_PREFIX(retro_serialize_size)(void)
23112370
{
2312-
return 0;
2371+
return sizeof(serialized_data);
2372+
}
2373+
2374+
bool CORE_PREFIX(retro_serialize)(void *data, size_t len)
2375+
{
2376+
serialized_data info;
2377+
2378+
slock_lock(decode_thread_lock);
2379+
info.frame_cnt = frame_cnt;
2380+
info.audio_streams_ptr = audio_streams_ptr;
2381+
info.subtitle_streams_ptr = subtitle_streams_ptr;
2382+
slock_unlock(decode_thread_lock);
2383+
2384+
if (sizeof(serialized_data) <= len)
2385+
{
2386+
memcpy(data, &info, sizeof(serialized_data));
2387+
2388+
return true;
2389+
}
2390+
2391+
return false;
2392+
}
2393+
2394+
bool CORE_PREFIX(retro_unserialize)(const void *data, size_t len)
2395+
{
2396+
serialized_data info;
2397+
info.frame_cnt = 0;
2398+
info.audio_streams_ptr = 0;
2399+
info.subtitle_streams_ptr = 0;
2400+
2401+
if (sizeof(serialized_data) <= len)
2402+
{
2403+
memcpy(&info, data, sizeof(serialized_data));
2404+
2405+
slock_lock(decode_thread_lock);
2406+
audio_streams_ptr = info.audio_streams_ptr;
2407+
subtitle_streams_ptr = info.subtitle_streams_ptr;
2408+
slock_unlock(decode_thread_lock);
2409+
2410+
seek_frame(info.frame_cnt - frame_cnt);
2411+
2412+
return true;
2413+
}
2414+
2415+
return false;
23132416
}
23142417

2315-
bool CORE_PREFIX(retro_serialize)(void *data, size_t len) { return false; }
2316-
bool CORE_PREFIX(retro_unserialize)(const void *data, size_t len) { return false; }
23172418
void *CORE_PREFIX(retro_get_memory_data)(unsigned id) { return NULL; }
23182419
size_t CORE_PREFIX(retro_get_memory_size)(unsigned id) { return 0; }
23192420
void CORE_PREFIX(retro_cheat_reset)(void) { }

0 commit comments

Comments
 (0)