diff --git a/changelog.txt b/changelog.txt index 5aa67eab..9f97496c 100644 --- a/changelog.txt +++ b/changelog.txt @@ -1,3 +1,4 @@ +23-apr-2009 - shinydoofy - sdl - added --ripsubs for converting fm2 movie subtitles to an srt file 15-apr-2009 - shinydoofy - sdl - Lua is optional again, fixed the real issue 14-apr-2009 - punkrockguy - sdl - LUA is NO longer optional, so the SConscripts have been updated to reflect that change. This fixes the mysterious non-working input issue. 12-apr-2009 - shinydoofy - sdl - implemented saving/loading a savestate from a specific file on Alt+S/L diff --git a/src/drivers/sdl/config.cpp b/src/drivers/sdl/config.cpp index cd3cb050..722c55a9 100644 --- a/src/drivers/sdl/config.cpp +++ b/src/drivers/sdl/config.cpp @@ -205,7 +205,11 @@ InitConfig() config->addOption("mute", "SDL.MuteCapture", 0); #endif + // fcm -> fm2 conversion config->addOption("fcmconvert", "SDL.FCMConvert", ""); + + // fm2 -> srt conversion + config->addOption("ripsubs", "SDL.RipSubs", ""); // enable new PPU core config->addOption("newppu", "SDL.NewPPU", "0"); diff --git a/src/drivers/sdl/sdl.cpp b/src/drivers/sdl/sdl.cpp index 62d74a5a..34180f4a 100644 --- a/src/drivers/sdl/sdl.cpp +++ b/src/drivers/sdl/sdl.cpp @@ -10,6 +10,8 @@ #include #include #include +#include +#include #include "main.h" @@ -111,6 +113,7 @@ char *DriverUsage="\ --playmov f Plays back a recorded movie from filename f.\n\ --pauseframe x Pauses movie playback at frame x.\n\ --fcmconvert f Converts fcm movie file f to fm2.\n\ +--ripsubs f Converts movie's subtitles to srt\n\ --no-config {0,1} Don't change the config file"; /* Moved network options out while netplay is broken. @@ -538,7 +541,7 @@ SDL_GL_LoadLibrary(0); { int okcount = 0; std::string infname = s.c_str(); - // procude output filename + // produce output filename std::string outname; size_t dot = infname.find_last_of ("."); if (dot == std::string::npos) @@ -559,10 +562,78 @@ SDL_GL_LoadLibrary(0); } else { FCEUD_Message ("Something went wrong while converting your file...\n"); } + DriverKill(); SDL_Quit(); return 0; + } + + // check for a .fm2 file to rip the subtitles + g_config->getOption("SDL.RipSubs", &s); + g_config->setOption("SDL.RipSubs", ""); + if (!s.empty()) + { + MovieData md; + std::string infname; + infname = s.c_str(); + FCEUFILE *fp = FCEU_fopen(s.c_str(), 0, "rb", 0); + // load the movie and and subtitles + extern bool LoadFM2(MovieData&, std::istream*, int, bool); + LoadFM2(md, fp->stream, INT_MAX, false); + LoadSubtitles(md); // fill subtitleFrames and subtitleMessages + delete fp; + + // produce .srt file's name and open it for writing + std::string outname; + size_t dot = infname.find_last_of ("."); + if (dot == std::string::npos) + outname = infname + ".srt"; + else + outname = infname.substr(0,dot) + ".srt"; + FILE *srtfile; + srtfile = fopen(outname.c_str(), "w"); + + if (srtfile != NULL) + { + extern std::vector subtitleFrames; + extern std::vector subtitleMessages; + float fps = (md.palFlag == 0 ? 60.0988 : 50.0069); // NTSC vs PAL + float subduration = 3; // seconds for the subtitles to be displayed + for (int i = 0; i < subtitleFrames.size(); i++) + { + fprintf(srtfile, "%i\n", i+1); // starts with 1, not 0 + double seconds, ms, endseconds, endms; + seconds = subtitleFrames[i]/fps; + if (i+1 < subtitleFrames.size()) // there's another subtitle coming after this one + { + if (subtitleFrames[i+1]-subtitleFrames[i] < subduration*fps) // avoid two subtitles at the same time + { + endseconds = (subtitleFrames[i+1]-1)/fps; // frame x: subtitle1; frame x+1 subtitle2 + } else { + endseconds = seconds+subduration; + } + } else { + endseconds = seconds+subduration; + } + ms = modf(seconds, &seconds); + endms = modf(endseconds, &endseconds); + // this is just beyond ugly, don't show it to your kids + fprintf(srtfile, + "%02.0f:%02d:%02d,%03d --> %02.0f:%02d:%02d,%03d\n", // hh:mm:ss,ms --> hh:mm:ss,ms + floor(seconds/3600), (int)floor(seconds/60 ) % 60, (int)floor(seconds) % 60, (int)(ms*1000), + floor(endseconds/3600), (int)floor(endseconds/60) % 60, (int)floor(endseconds) % 60, (int)(endms*1000)); + fprintf(srtfile, "%s\n\n", subtitleMessages[i].c_str()); // new line for every subtitle + } + fclose(srtfile); + printf("%d subtitles have been ripped.\n", subtitleFrames.size()); + } else { + FCEUD_Message("Couldn't create output srt file...\n"); + } + + DriverKill(); + SDL_Quit(); + return 0; } if(romIndex <= 0) { diff --git a/src/movie.cpp b/src/movie.cpp index 946517e3..899a1c69 100644 --- a/src/movie.cpp +++ b/src/movie.cpp @@ -496,7 +496,7 @@ static void LoadFM2_binarychunk(MovieData& movieData, std::istream* fp, int size } //yuck... another custom text parser. -static bool LoadFM2(MovieData& movieData, std::istream* fp, int size, bool stopAfterHeader) +bool LoadFM2(MovieData& movieData, std::istream* fp, int size, bool stopAfterHeader) { //first, look for an fcm signature char fcmbuf[3]; @@ -750,7 +750,7 @@ void FCEUI_LoadMovie(const char *fname, bool _read_only, bool tasedit, int _paus } LoadFM2(currMovieData, fp->stream, INT_MAX, false); - LoadSubtitles(); + LoadSubtitles(currMovieData); delete fp; freshMovie = true; //Movie has been loaded, so it must be unaltered @@ -1235,13 +1235,12 @@ bool FCEUI_MovieGetInfo(FCEUFILE* fp, MOVIE_INFO& info, bool skipFrameCount) } //This function creates an array of frame numbers and corresponding strings for displaying subtitles -void LoadSubtitles(void) +void LoadSubtitles(MovieData moviedata) { - extern std::vector subtitles; - for(uint32 i=0;i