@@ -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+
615632void 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+
23102369size_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; }
23172418void * CORE_PREFIX (retro_get_memory_data )(unsigned id ) { return NULL ; }
23182419size_t CORE_PREFIX (retro_get_memory_size )(unsigned id ) { return 0 ; }
23192420void CORE_PREFIX (retro_cheat_reset )(void ) { }
0 commit comments