diff --git a/src/drivers/win/main.cpp b/src/drivers/win/main.cpp index cc9ca568..1cf8304a 100644 --- a/src/drivers/win/main.cpp +++ b/src/drivers/win/main.cpp @@ -748,7 +748,7 @@ int main(int argc,char *argv[]) if(FCEU_isFileInArchive(MovieToLoad)) replayReadOnlySetting = true; - FCEUI_LoadMovie(MovieToLoad, replayReadOnlySetting, false, replayStopFrameSetting!=0); + FCEUI_LoadMovie(MovieToLoad, replayReadOnlySetting, replayStopFrameSetting != 0); FCEUX_LoadMovieExtras(MovieToLoad); free(MovieToLoad); MovieToLoad = NULL; diff --git a/src/drivers/win/replay.cpp b/src/drivers/win/replay.cpp index 1db00508..660318ff 100644 --- a/src/drivers/win/replay.cpp +++ b/src/drivers/win/replay.cpp @@ -7,7 +7,7 @@ #include "archive.h" #include "utils/xstring.h" -static const char* fm2ext[] = {"fm2",0}; +static const char* fm2ext[] = { "fm2", "tas", 0}; int MetaPosX,MetaPosY; @@ -502,18 +502,6 @@ BOOL CALLBACK ReplayDialogProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lP { case WM_INITDIALOG: { - bool tasedit = lParam?true:false; - - //some of the controls are illogical with tasedit - //remove them, and rename the window - if(tasedit) - { - SetWindowText(hwndDlg,"Load TasEdit Movie"); - ShowWindow(GetDlgItem(hwndDlg,IDC_CHECK_READONLY),SW_HIDE); - ShowWindow(GetDlgItem(hwndDlg,IDC_CHECK_STOPMOVIE),SW_HIDE); - ShowWindow(GetDlgItem(hwndDlg,IDC_EDIT_STOPFRAME),SW_HIDE); - } - SendDlgItemMessage(hwndDlg, IDC_CHECK_READONLY, BM_SETCHECK, replayReadOnlySetting?BST_CHECKED:BST_UNCHECKED, 0); SendDlgItemMessage(hwndDlg, IDC_CHECK_STOPMOVIE,BM_SETCHECK, BST_UNCHECKED, 0); @@ -564,15 +552,16 @@ BOOL CALLBACK ReplayDialogProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lP //TODO - a big copy/pasted block below. factor out extension extractor or use another one - // filter out everything that's not an extension we like *.fm2 + // filter out everything that's not an extension we like (*.fm2 and *.tas) // (because FindFirstFile is too dumb to do that) { std::string ext = getExtension(wfd.cFileName); if(ext != "fm2") - if(ext != "zip") - if(ext != "rar") - if(ext != "7z") - continue; + if(ext != "tas") + if(ext != "zip") + if(ext != "rar") + if(ext != "7z") + continue; } char filename [512]; @@ -582,18 +571,23 @@ BOOL CALLBACK ReplayDialogProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lP SetCurrentDirectory(BaseDirectory.c_str()); ArchiveScanRecord asr = FCEUD_ScanArchive(filename); - if(!asr.isArchive()) { + if(!asr.isArchive()) + { FCEUFILE* fp = FCEU_fopen(filename,0,"rb",0); - if(fp) { + if(fp) + { fp->stream = fp->stream->memwrap(); - HandleScan(hwndDlg,fp ,items); + HandleScan(hwndDlg, fp, items); delete fp; } - } else { + } else + { asr.files.FilterByExtension(fm2ext); - for(uint32 i=0;i #include - #include "taseditlib/taseditproj.h" #include "utils/xstring.h" #include "Win32InputBox.h" @@ -793,7 +792,7 @@ void OpenProject() if(GetOpenFileName(&ofn)) // If it is a valid filename { - // If they haven't put ".tas" after it, stick it on ourselves + // If they haven't put ".tas", stick it on ourselves if (!strstr(nameo, ".tas")) strcat(nameo, ".tas"); LoadProject(nameo); @@ -1038,6 +1037,7 @@ void Export() break; } } + temp_md.loadFrameCount = -1; // dump to disk temp_md.dump(osRecordingMovie, false); delete osRecordingMovie; @@ -1269,14 +1269,12 @@ BOOL CALLBACK WndprocTasEdit(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lPar turbo = TASEdit_turbo_seek; break; case ID_VIEW_SHOW_LAG_FRAMES: - //switch "Highlight lag frames" flag TASEdit_show_lag_frames ^= 1; CheckMenuItem(hmenu, ID_VIEW_SHOW_LAG_FRAMES, TASEdit_show_lag_frames?MF_CHECKED : MF_UNCHECKED); tasedit_list.RedrawList(); bookmarks.RedrawBookmarksList(); break; case ID_VIEW_SHOW_MARKERS: - //switch "Show Markers" flag TASEdit_show_markers ^= 1; CheckMenuItem(hmenu, ID_VIEW_SHOW_MARKERS, TASEdit_show_markers?MF_CHECKED : MF_UNCHECKED); tasedit_list.RedrawList(); // no need to redraw Bookmarks, as Markers are only shown in main list @@ -1564,9 +1562,9 @@ BOOL CALLBACK WndprocTasEdit(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lPar return FALSE; } -void EnterTasEdit() +bool EnterTasEdit() { - if(!FCEU_IsValidUI(FCEUI_TASEDIT)) return; + if(!FCEU_IsValidUI(FCEUI_TASEDIT)) return false; if(!hwndTasEdit) hwndTasEdit = CreateDialog(fceu_hInstance,"TASEDIT", hAppWnd, WndprocTasEdit); if(hwndTasEdit) { @@ -1648,7 +1646,8 @@ void EnterTasEdit() SetFocus(history.hwndHistoryList); // set focus only once, to show selection cursor SetFocus(tasedit_list.hwndList); FCEU_DispMessage("TAS Editor engaged", 0); - } + return true; + } else return false; } bool ExitTasEdit() diff --git a/src/drivers/win/tasedit.h b/src/drivers/win/tasedit.h index 511cb194..663576c3 100644 --- a/src/drivers/win/tasedit.h +++ b/src/drivers/win/tasedit.h @@ -20,7 +20,7 @@ enum ECONTEXTMENU CONTEXTMENU_SELECTED = 1, }; -void EnterTasEdit(); +bool EnterTasEdit(); void InitDialog(); bool ExitTasEdit(); void UpdateTasEdit(); diff --git a/src/drivers/win/taseditlib/tasedit_list.cpp b/src/drivers/win/taseditlib/tasedit_list.cpp index 51837697..cf837749 100644 --- a/src/drivers/win/taseditlib/tasedit_list.cpp +++ b/src/drivers/win/taseditlib/tasedit_list.cpp @@ -430,52 +430,49 @@ LONG TASEDIT_LIST::CustomDraw(NMLVCUSTOMDRAW* msg) cell_x = msg->iSubItem; cell_y = msg->nmcd.dwItemSpec; - - if(cell_x > COLUMN_ICONS) { // text color if(TASEdit_enable_hot_changes && cell_x >= COLUMN_JOYPAD1_A && cell_x <= COLUMN_JOYPAD4_R) - { msg->clrText = hot_changes_colors[history.GetCurrentSnapshot().GetHotChangeInfo(cell_y, cell_x - COLUMN_JOYPAD1_A)]; - } else msg->clrText = NORMAL_TEXT_COLOR; + else + msg->clrText = NORMAL_TEXT_COLOR; // bg color and text font if(cell_x == COLUMN_FRAMENUM || cell_x == COLUMN_FRAMENUM2) { + // font + if(markers.GetMarker(cell_y)) + SelectObject(msg->nmcd.hdc, hMainListSelectFont); + else + SelectObject(msg->nmcd.hdc, hMainListFont); + // bg // frame number if (cell_y == history.GetUndoHint()) { // undo hint here - if(TASEdit_show_markers && markers.GetMarker(cell_y)) + if (TASEdit_show_markers && markers.GetMarker(cell_y)) { - SelectObject(msg->nmcd.hdc, hMainListSelectFont); msg->clrTextBk = MARKED_UNDOHINT_FRAMENUM_COLOR; } else { - SelectObject(msg->nmcd.hdc, hMainListFont); msg->clrTextBk = UNDOHINT_FRAMENUM_COLOR; } } else if (cell_y == currFrameCounter || cell_y == (playback.GetPauseFrame() - 1)) { // current frame - if(TASEdit_show_markers && markers.GetMarker(cell_y)) + if (TASEdit_show_markers && markers.GetMarker(cell_y)) { - // this frame is also marked - SelectObject(msg->nmcd.hdc, hMainListSelectFont); msg->clrTextBk = CUR_MARKED_FRAMENUM_COLOR; } else { - SelectObject(msg->nmcd.hdc, hMainListFont); msg->clrTextBk = CUR_FRAMENUM_COLOR; } - } else if(TASEdit_show_markers && markers.GetMarker(cell_y)) + } else if (TASEdit_show_markers && markers.GetMarker(cell_y)) { // marked frame - SelectObject(msg->nmcd.hdc, hMainListSelectFont); msg->clrTextBk = MARKED_FRAMENUM_COLOR; } else { - SelectObject(msg->nmcd.hdc, hMainListFont); if(cell_y < greenzone.greenZoneCount) { if (!greenzone.savestates[cell_y].empty()) @@ -499,7 +496,9 @@ LONG TASEDIT_LIST::CustomDraw(NMLVCUSTOMDRAW* msg) } else if((cell_x - COLUMN_JOYPAD1_A) / NUM_JOYPAD_BUTTONS == 0 || (cell_x - COLUMN_JOYPAD1_A) / NUM_JOYPAD_BUTTONS == 2) { // pad 1 or 3 + // font SelectObject(msg->nmcd.hdc, hMainListFont); + // bg if (cell_y == history.GetUndoHint()) { // undo hint here @@ -530,7 +529,9 @@ LONG TASEDIT_LIST::CustomDraw(NMLVCUSTOMDRAW* msg) } else if((cell_x - COLUMN_JOYPAD1_A) / NUM_JOYPAD_BUTTONS == 1 || (cell_x - COLUMN_JOYPAD1_A) / NUM_JOYPAD_BUTTONS == 3) { // pad 2 or 4 + // font SelectObject(msg->nmcd.hdc, hMainListFont); + // bg if (cell_y == history.GetUndoHint()) { // undo hint here diff --git a/src/drivers/win/taseditlib/taseditproj.cpp b/src/drivers/win/taseditlib/taseditproj.cpp index 865a8a46..e5aee85d 100644 --- a/src/drivers/win/taseditlib/taseditproj.cpp +++ b/src/drivers/win/taseditlib/taseditproj.cpp @@ -56,6 +56,7 @@ bool TASEDIT_PROJECT::save() const char* filename = PFN.c_str(); EMUFILE_FILE* ofs = FCEUD_UTF8_fstream(filename,"wb"); + currMovieData.loadFrameCount = currMovieData.records.size(); currMovieData.dump(ofs, true); markers.save(ofs); bookmarks.save(ofs); diff --git a/src/drivers/win/window.cpp b/src/drivers/win/window.cpp index 78952339..7b5e95a6 100644 --- a/src/drivers/win/window.cpp +++ b/src/drivers/win/window.cpp @@ -1458,9 +1458,10 @@ LRESULT FAR PASCAL AppWndProc(HWND hWnd,UINT msg,WPARAM wParam,LPARAM lParam) delete outf; if (!GameInfo) //If no game is loaded, load the Open Game dialog LoadNewGamey(hWnd, 0); - FCEUI_LoadMovie(outname.c_str(), 1, false, false); + FCEUI_LoadMovie(outname.c_str(), 1, false); FCEUX_LoadMovieExtras(outname.c_str()); - } else { + } else + { std::string msg = "Failure converting " + fileDropped + "\r\n\r\n" + EFCM_CONVERTRESULT_message(result); MessageBox(hWnd,msg.c_str(),"Failure converting fcm", 0); } @@ -1481,8 +1482,24 @@ LRESULT FAR PASCAL AppWndProc(HWND hWnd,UINT msg,WPARAM wParam,LPARAM lParam) { if (!GameInfo) //If no game is loaded, load the Open Game dialog LoadNewGamey(hWnd, 0); - if (GameInfo && !(fileDropped.find(".fm2") == string::npos)) { //.fm2 is at the end of the filename so that must be the extension - FCEUI_LoadMovie(ftmp, 1, false, false); //We are convinced it is a movie file, attempt to load it + if (GameInfo && !(fileDropped.find(".fm2") == string::npos)) + { + //.fm2 is at the end of the filename so that must be the extension + FCEUI_LoadMovie(ftmp, 1, false); //We are convinced it is a movie file, attempt to load it + FCEUX_LoadMovieExtras(ftmp); + } + } + //------------------------------------------------------- + //Check if TAS Editor file + //------------------------------------------------------- + else if (!(fileDropped.find(".tas") == string::npos) && (fileDropped.find(".tas") == fileDropped.length()-4)) //ROM is already loaded and .tas in filename + { + if (!GameInfo) //If no game is loaded, load the Open Game dialog + LoadNewGamey(hWnd, 0); + if (GameInfo && !(fileDropped.find(".tas") == string::npos)) + { + //.tas is at the end of the filename so that must be the extension + FCEUI_LoadMovie(ftmp, 1, false); //We are convinced it is a TAS Editor project file, attempt to load and replay it FCEUX_LoadMovieExtras(ftmp); } } @@ -1570,7 +1587,7 @@ LRESULT FAR PASCAL AppWndProc(HWND hWnd,UINT msg,WPARAM wParam,LPARAM lParam) char*& fname = recent_movie[wParam - MOVIE_FIRST_RECENT_FILE]; if(fname) { - if (!FCEUI_LoadMovie(fname, 1, false, false)) + if (!FCEUI_LoadMovie(fname, 1, false)) { int result = MessageBox(hWnd,"Remove from list?", "Could Not Open Recent File", MB_YESNO); if (result == IDYES) @@ -1924,7 +1941,7 @@ LRESULT FAR PASCAL AppWndProc(HWND hWnd,UINT msg,WPARAM wParam,LPARAM lParam) // break; // Removing this tool since it is redundant to both case MENU_TASEDIT: - extern void EnterTasEdit(); + extern bool EnterTasEdit(); EnterTasEdit(); break; case MENU_CONVERT_MOVIE: @@ -2082,7 +2099,7 @@ LRESULT FAR PASCAL AppWndProc(HWND hWnd,UINT msg,WPARAM wParam,LPARAM lParam) case FCEUX_CONTEXT_LOADLASTMOVIE: if(recent_movie[0]) { - if (!FCEUI_LoadMovie(recent_movie[0], 1, false, false)) + if (!FCEUI_LoadMovie(recent_movie[0], 1, false)) { int result = MessageBox(hWnd,"Remove from list?", "Could Not Open Recent File", MB_YESNO); if (result == IDYES) @@ -2090,7 +2107,8 @@ LRESULT FAR PASCAL AppWndProc(HWND hWnd,UINT msg,WPARAM wParam,LPARAM lParam) RemoveRecentItem(0, recent_movie, MAX_NUMBER_OF_MOVIE_RECENT_FILES); UpdateMovieRMenu(recentmoviemenu, recent_movie, MENU_MOVIE_RECENT, MOVIE_FIRST_RECENT_FILE); } - } else { + } else + { FCEUX_LoadMovieExtras(recent_movie[0]); } } diff --git a/src/input.cpp b/src/input.cpp index 64dd96eb..994d81dd 100644 --- a/src/input.cpp +++ b/src/input.cpp @@ -939,7 +939,7 @@ void LagCounterToggle(void) static void LaunchTasEdit(void) { #ifdef WIN32 - extern void EnterTasEdit(); + extern bool EnterTasEdit(); EnterTasEdit(); #endif } diff --git a/src/movie.cpp b/src/movie.cpp index 2f6a7a3c..f1cf5c67 100644 --- a/src/movie.cpp +++ b/src/movie.cpp @@ -489,8 +489,8 @@ int MovieData::dump(EMUFILE *os, bool binary) if(savestate.size()) os->fprintf("savestate %s\n" , BytesToString(&savestate[0],savestate.size()).c_str() ); - if(FCEUMOV_Mode(MOVIEMODE_TASEDIT)) - os->fprintf("length %d\n" , this->records.size() ); + if (this->loadFrameCount >= 0) + os->fprintf("length %d\n" , this->loadFrameCount); if(binary) { @@ -593,8 +593,8 @@ static void LoadFM2_binarychunk(MovieData& movieData, EMUFILE* fp, int size) //yuck... another custom text parser. bool LoadFM2(MovieData& movieData, EMUFILE* fp, int size, bool stopAfterHeader) { + // Non-TASEditor projects consume until EOF std::string a("length"), b("-1"); - // Non-TAS projects consume until EOF movieData.installValue(a, b); //first, look for an fcm signature @@ -821,9 +821,9 @@ void MovieData::dumpSavestateTo(std::vector* buf, int compressionLevel) } //begin playing an existing movie -bool FCEUI_LoadMovie(const char *fname, bool _read_only, bool tasedit, int _pauseframe) +bool FCEUI_LoadMovie(const char *fname, bool _read_only, int _pauseframe) { - if(!tasedit && !FCEU_IsValidUI(FCEUI_PLAYMOVIE)) + if(!FCEU_IsValidUI(FCEUI_PLAYMOVIE)) return true; //adelikat: file did not fail to load, so let's return true here, just do nothing assert(fname); @@ -866,12 +866,12 @@ bool FCEUI_LoadMovie(const char *fname, bool _read_only, bool tasedit, int _paus //fully reload the game to reinitialize everything before playing any movie poweron(true); - //WE NEED TO LOAD A SAVESTATE - if(currMovieData.savestate.size() != 0) + if(currMovieData.savestate.size()) { + //WE NEED TO LOAD A SAVESTATE movieFromPoweron = false; bool success = MovieData::loadSavestateFrom(&currMovieData.savestate); - if(!success) return true; //adelikat: I guess return true here? False is only for a bad movie filename, if it got this far the file was god? + if(!success) return true; //adelikat: I guess return true here? False is only for a bad movie filename, if it got this far the file was good? } else { movieFromPoweron = true; } @@ -887,24 +887,16 @@ bool FCEUI_LoadMovie(const char *fname, bool _read_only, bool tasedit, int _paus FCEUD_SetInput(currMovieData.fourscore, currMovieData.microphone, (ESI)currMovieData.ports[0], (ESI)currMovieData.ports[1], (ESIFC)currMovieData.ports[2]); //stuff that should only happen when we're ready to positively commit to the replay - if(tasedit) - { - currFrameCounter = 0; - pauseframe = _pauseframe; - } - else - { - currFrameCounter = 0; - pauseframe = _pauseframe; - movie_readonly = _read_only; - movieMode = MOVIEMODE_PLAY; - currRerecordCount = currMovieData.rerecordCount; + currFrameCounter = 0; + pauseframe = _pauseframe; + movie_readonly = _read_only; + movieMode = MOVIEMODE_PLAY; + currRerecordCount = currMovieData.rerecordCount; - if(movie_readonly) - FCEU_DispMessage("Replay started Read-Only.",0); - else - FCEU_DispMessage("Replay started Read+Write.",0); - } + if(movie_readonly) + FCEU_DispMessage("Replay started Read-Only.",0); + else + FCEU_DispMessage("Replay started Read+Write.",0); #ifdef WIN32 SetMainWindowText(); @@ -1068,7 +1060,8 @@ void FCEUMOV_AddInputState() if (fullSaveStateLoads && (currFrameCounter < (int)currMovieData.records.size())) currMovieData.truncateAt(currFrameCounter); - mr.dump(&currMovieData, osRecordingMovie,currMovieData.records.size()); + mr.dump(&currMovieData, osRecordingMovie,currMovieData.records.size()); // to disk + currMovieData.records.push_back(mr); } @@ -1188,11 +1181,31 @@ bool FCEUMOV_ReadState(EMUFILE* is, uint32 size) { load_successful = false; - //a little rule: cant load states in read+write mode with a movie from an archive. - //so we are going to switch it to readonly mode in that case - if(!movie_readonly && FCEU_isFileInArchive(curMovieFilename)) { - FCEU_PrintError("Cannot loadstate in Read+Write with movie from archive. Movie is now Read-Only."); - movie_readonly = true; + if (!movie_readonly) + { + if (currMovieData.loadFrameCount >= 0) + { + #ifdef WIN32 + int result = MessageBox(hAppWnd, "This movie is a TAS Editor project file.\nIt can be modified in TAS Editor only.\n\nOpen it in TAS Editor now?", "Movie Replay", MB_YESNO); + if (result == IDYES) + { + extern bool EnterTasEdit(); + extern bool LoadProject(char* fullname); + char fullname[512]; + strcpy(fullname, curMovieFilename); + if (EnterTasEdit()) + LoadProject(fullname); + } + #endif + movie_readonly = true; + } + if (FCEU_isFileInArchive(curMovieFilename)) + { + //a little rule: cant load states in read+write mode with a movie from an archive. + //so we are going to switch it to readonly mode in that case + FCEU_PrintError("Cannot loadstate in Read+Write with movie from archive. Movie is now Read-Only."); + movie_readonly = true; + } } MovieData tempMovieData = MovieData(); @@ -1508,12 +1521,13 @@ void FCEUI_MoviePlayFromBeginning(void) } else { + // movie starting from savestate - reload movie file string str = curMovieFilename; FCEUI_StopMovie(); - if (FCEUI_LoadMovie(str.c_str(),1, 0, 0)) + if (FCEUI_LoadMovie(str.c_str(), 1, 0)) { movieMode = MOVIEMODE_PLAY; - movie_readonly=true; + movie_readonly = true; FCEU_DispMessage("Movie is now Read-Only. Playing from beginning.",0); } //currMovieData.loadSavestateFrom(&currMovieData.savestate); //TODO: make something like this work instead so it doesn't have to reload diff --git a/src/movie.h b/src/movie.h index 0ca1af87..86e57e76 100644 --- a/src/movie.h +++ b/src/movie.h @@ -183,6 +183,7 @@ public: //was the frame data stored in binary? bool binaryFlag; + // TAS Editor project files contain additional data after input int loadFrameCount; //which ports are defined for the movie @@ -257,7 +258,7 @@ extern bool fullSaveStateLoads; void FCEUI_MakeBackupMovie(bool dispMessage); void FCEUI_CreateMovieFile(std::string fn); void FCEUI_SaveMovie(const char *fname, EMOVIE_FLAG flags, std::wstring author); -bool FCEUI_LoadMovie(const char *fname, bool read_only, bool tasedit, int _stopframe); +bool FCEUI_LoadMovie(const char *fname, bool read_only, int _stopframe); void FCEUI_MoviePlayFromBeginning(void); void FCEUI_StopMovie(void); bool FCEUI_MovieGetInfo(FCEUFILE* fp, MOVIE_INFO& info, bool skipFrameCount = false);