From eb65e0122b86c10ee306817fa68dea6b3cc5cde7 Mon Sep 17 00:00:00 2001 From: adelikat <adelikat@users.sf.net> Date: Sun, 23 Nov 2008 21:28:22 +0000 Subject: [PATCH] Movie subtitle system installed --- changelog.txt | 1 + src/drivers/win/replay.cpp | 50 +++++++++++++++++++++++++++++++++++ src/fceu.cpp | 1 + src/movie.cpp | 54 +++++++++++++++++++++++++++++++++++--- src/movie.h | 7 +++++ 5 files changed, 110 insertions(+), 3 deletions(-) diff --git a/changelog.txt b/changelog.txt index d1cad559..9d257da3 100644 --- a/changelog.txt +++ b/changelog.txt @@ -1,4 +1,5 @@ ---version 2.0.4 yet to be released--- +23-nov-2008 - adelikat - movie subtitle system installed 22-nov-2008 - adelikat - win32 - added help menu item to TASEdit and Hex Editor, Minor TASEdit clean up 22-nov-2008 - adelikat - win32 - fixed so that turbo works with VBlank sync settings 21-nov-2008 - qfox - Lua - added joypad.write and joypad.get for naming consistency. Added plane display toggle for lua: FCEU.fceu_setrenderplanes(sprites, background) which accepts two boolean args and toggles the drawing of those planes from Lua. Changed movie.framecount() to always return a number, even when no movie is playing. Should return the same number as in view; the number of frames since last reset, if no movie is playing. diff --git a/src/drivers/win/replay.cpp b/src/drivers/win/replay.cpp index 268e15cf..cf398691 100644 --- a/src/drivers/win/replay.cpp +++ b/src/drivers/win/replay.cpp @@ -14,6 +14,9 @@ static bool stopframeWasEditedByUser = false; //the comments contained in the currently-displayed movie static std::vector<std::wstring> currComments; +//the subtitles contained in the currently-displayed movie +static std::vector<std::string> currSubtitles; + extern FCEUGI *GameInfo; //retains the state of the readonly checkbox and stopframe value @@ -219,6 +222,7 @@ void UpdateReplayDialog(HWND hwndDlg) EnableWindow(GetDlgItem(hwndDlg,IDOK),TRUE); EnableWindow(GetDlgItem(hwndDlg,IDC_BUTTON_METADATA),TRUE); currComments = info.comments; + currSubtitles = info.subtitles; doClear = 0; } @@ -311,6 +315,50 @@ BOOL CALLBACK ReplayMetadataDialogProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, L lvc.cx = listRect.right - 100; ListView_InsertColumn(hwndList, colidx++, &lvc); + + //Display the Subtitles into the Metadata as well + for(uint32 i=0;i<currSubtitles.size();i++) + { + std::string& subtitle = currSubtitles[i]; + size_t splitat = subtitle.find_first_of(' '); + std::wstring key, value; + //if we can't split it then call it an unnamed key + if(splitat == std::string::npos) + { + value = mbstowcs(subtitle); + } else + { + key = mbstowcs(subtitle.substr(0,splitat)); + value = mbstowcs(subtitle.substr(splitat+1)); + } + + LVITEM lvi; + lvi.iItem = i; + lvi.mask = LVIF_TEXT; + lvi.iSubItem = 0; + lvi.pszText = (LPSTR)key.c_str(); + SendMessageW(hwndList, LVM_INSERTITEMW, 0, (LPARAM)&lvi); + + lvi.iSubItem = 1; + lvi.pszText = (LPSTR)value.c_str(); + SendMessageW(hwndList, LVM_SETITEMTEXTW, i, (LPARAM)&lvi); + } + + //Display Subtitle Heading + if (currSubtitles.size() > 0) //If no subtitles, don't bother with this heading + { + string Heading = "SUBTITLES"; + std::wstring& rHeading = mbstowcs(Heading); + + LVITEM lvSubtitle; + lvSubtitle.iItem = 0; + lvSubtitle.mask = LVIF_TEXT; + lvSubtitle.iSubItem = 0; + lvSubtitle.pszText = (LPSTR)rHeading.c_str(); + SendMessageW(hwndList, LVM_INSERTITEMW, 0, (LPARAM)&lvSubtitle); + } + + //Display the comments in the movie data for(uint32 i=0;i<currComments.size();i++) { std::wstring& comment = currComments[i]; @@ -338,6 +386,8 @@ BOOL CALLBACK ReplayMetadataDialogProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, L SendMessageW(hwndList, LVM_SETITEMTEXTW, i, (LPARAM)&lvi); } + + } break; diff --git a/src/fceu.cpp b/src/fceu.cpp index 53b176ea..4e7d4789 100644 --- a/src/fceu.cpp +++ b/src/fceu.cpp @@ -632,6 +632,7 @@ void FCEUI_Emulate(uint8 **pXBuf, int32 **SoundBuf, int32 *SoundBufSize, int ski } else justLagged = false; + ProcessSubtitles(); } void FCEUI_CloseGame(void) diff --git a/src/movie.cpp b/src/movie.cpp index 7acefa28..15edbcc4 100644 --- a/src/movie.cpp +++ b/src/movie.cpp @@ -24,6 +24,7 @@ #include "utils/memory.h" #include "utils/memorystream.h" #include "utils/xstring.h" +#include <sstream> #ifdef CREATE_AVI #include "drivers/videolog/nesvideos-piece.h" @@ -35,12 +36,12 @@ using namespace std; - #define MOVIE_VERSION 3 extern char FileBase[]; -using namespace std; +std::vector<int> subtitleFrames; +std::vector<string> subtitleMessages; //TODO - remove the synchack stuff from the replay gui and require it to be put into the fm2 file //which the user would have already converted from fcm @@ -350,6 +351,8 @@ void MovieData::installValue(std::string& key, std::string& val) installBool(val,binaryFlag); else if(key == "comment") comments.push_back(mbstowcs(val)); + else if (key == "subtitle") + subtitles.push_back(val); //mbstowcs(val)); else if(key == "savestate") { int len = Base64StringToBytesLength(val); @@ -379,6 +382,9 @@ int MovieData::dump(std::ostream *os, bool binary) for(uint32 i=0;i<comments.size();i++) *os << "comment " << wcstombs(comments[i]) << endl; + + for(uint32 i=0;i<subtitles.size();i++) + *os << "subtitle " << subtitles[i] << endl; if(binary) *os << "binary 1" << endl; @@ -492,7 +498,7 @@ static bool LoadFM2(MovieData& movieData, std::istream* fp, int size, bool stopA std::string key,value; enum { - NEWLINE, KEY, SEPARATOR, VALUE, RECORD, COMMENT + NEWLINE, KEY, SEPARATOR, VALUE, RECORD, COMMENT, SUBTITLE } state = NEWLINE; bool bail = false; for(;;) @@ -721,6 +727,7 @@ void FCEUI_LoadMovie(const char *fname, bool _read_only, bool tasedit, int _paus } LoadFM2(currMovieData, fp->stream, INT_MAX, false); + LoadSubtitles(); delete fp; //fully reload the game to reinitialize everything before playing any movie @@ -1168,6 +1175,47 @@ bool FCEUI_MovieGetInfo(FCEUFILE* fp, MOVIE_INFO& info, bool skipFrameCount) info.name_of_rom_used = md.romFilename; info.rerecord_count = md.rerecordCount; info.comments = md.comments; + info.subtitles = md.subtitles; return true; } + +//This function creates an array of frame numbers and corresponding strings for displaying subtitles +void LoadSubtitles(void) +{ + + extern std::vector<string> subtitles; + for(uint32 i=0;i<currMovieData.subtitles.size();i++) + { + std::string& subtitle = currMovieData.subtitles[i]; + size_t splitat = subtitle.find_first_of(' '); + std::string key, value; + + //If we can't split them, then don't process this one + if(splitat == std::string::npos) + { + } + //Else split the subtitle into the int and string arrays + else + { + key = subtitle.substr(0,splitat); + value = subtitle.substr(splitat+1); + + subtitleFrames.push_back(atoi(key.c_str())); + subtitleMessages.push_back(value); + } + } + +} + +//Every frame, this will be called to determine if a subtitle should be displayed, which one, and then to display it +void ProcessSubtitles(void) +{ + if (movieMode == MOVIEMODE_INACTIVE) return; + + for(uint32 i=0;i<currMovieData.subtitles.size();i++) + { + if (currFrameCounter == subtitleFrames[i]) + FCEUI_DispMessage("%s",subtitleMessages[i].c_str()); + } +} \ No newline at end of file diff --git a/src/movie.h b/src/movie.h index 7a4a8e8a..ab538ac7 100644 --- a/src/movie.h +++ b/src/movie.h @@ -42,6 +42,7 @@ typedef struct std::string name_of_rom_used; std::vector<std::wstring> comments; + std::vector<std::string> subtitles; } MOVIE_INFO; @@ -159,6 +160,7 @@ public: std::vector<char> savestate; std::vector<MovieRecord> records; std::vector<std::wstring> comments; + std::vector<std::string> subtitles; //this is the RERECORD COUNT. please rename variable. int rerecordCount; FCEU_Guid guid; @@ -243,4 +245,9 @@ bool FCEUI_GetMovieToggleReadOnly(); void FCEUI_MovieToggleFrameDisplay(); void FCEUI_ToggleInputDisplay(void); +void LoadSubtitles(void); +void ProcessSubtitles(void); + + + #endif //__MOVIE_H_