Skip to content

Commit 63dacd6

Browse files
committed
I added some functionality and changed the controls to expose
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 dc44c08 commit 63dacd6

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)