From c64e50151eaa9e360a72d25632089ad072311b33 Mon Sep 17 00:00:00 2001 From: p989 Date: Sat, 20 Jun 2009 06:28:23 +0000 Subject: [PATCH] starting a movie from sram --- desmume/src/commandline.cpp | 2 +- desmume/src/mc.cpp | 38 ++++++++++++++++ desmume/src/mc.h | 1 + desmume/src/movie.cpp | 74 ++++++++++++++++++++++++++++++- desmume/src/movie.h | 6 ++- desmume/src/windows/replay.cpp | 43 +++++++++++++++++- desmume/src/windows/resource.h | 3 ++ desmume/src/windows/resources.rc | Bin 705172 -> 705844 bytes 8 files changed, 162 insertions(+), 5 deletions(-) diff --git a/desmume/src/commandline.cpp b/desmume/src/commandline.cpp index c49f238f4..8407d56a5 100644 --- a/desmume/src/commandline.cpp +++ b/desmume/src/commandline.cpp @@ -122,6 +122,6 @@ void CommandLine::process_movieCommands() } else if(record_movie_file != "") { - FCEUI_SaveMovie(record_movie_file.c_str(), L""); + FCEUI_SaveMovie(record_movie_file.c_str(), L"", 0, NULL); } } diff --git a/desmume/src/mc.cpp b/desmume/src/mc.cpp index 51f1243f1..ed21cfcee 100644 --- a/desmume/src/mc.cpp +++ b/desmume/src/mc.cpp @@ -777,3 +777,41 @@ bool BackupDevice::load_duc(const char* filename) return true; } + +bool BackupDevice::load_movie(std::istream* is) { + + const u32 cookieLen = strlen(kDesmumeSaveCookie); + + is->seekg(-cookieLen, std::ios::end); + is->seekg(-4, std::ios::cur); + + u32 version = 0xFFFFFFFF; + is->read((char*)&version,4); + if(version!=0) { + printf("Unknown save file format\n"); + return false; + } + is->seekg(-24, std::ios::cur); + + struct{ + u32 size,padSize,type,addr_size,mem_size; + }info; + + is->read((char*)&info.size,4); + is->read((char*)&info.padSize,4); + is->read((char*)&info.type,4); + is->read((char*)&info.addr_size,4); + is->read((char*)&info.mem_size,4); + + //establish the save data + data.resize(info.size); + is->seekg(0, std::ios::beg); + if(info.size>0) + is->read((char*)&data[0],info.size); + + state = RUNNING; + addr_size = info.addr_size; + //none of the other fields are used right now + + return true; +} diff --git a/desmume/src/mc.h b/desmume/src/mc.h index c457641fb..8cdc4f580 100644 --- a/desmume/src/mc.h +++ b/desmume/src/mc.h @@ -100,6 +100,7 @@ public: bool load_duc(const char* filename); bool load_raw(const char* filename); bool save_raw(const char* filename); + bool load_movie(std::istream* is); //call me once a second or so to lazy flush the save data //here's the reason for this system: we want to dump save files when theyre READ diff --git a/desmume/src/movie.cpp b/desmume/src/movie.cpp index f69737ded..709b2c63d 100644 --- a/desmume/src/movie.cpp +++ b/desmume/src/movie.cpp @@ -32,6 +32,7 @@ #include "common.h" #include "mic.h" #include "version.h" +#include "memorystream.h" using namespace std; bool freshMovie = false; //True when a movie loads, false when movie is altered. Used to determine if a movie has been altered since opening @@ -209,6 +210,16 @@ void MovieData::installValue(std::string& key, std::string& val) StringToBytes(val,&savestate[0],len); // decodes either base64 or hex } } + else if(key == "sram") + { + int len = Base64StringToBytesLength(val); + if(len == -1) len = HexStringToBytesLength(val); // wasn't base64, try hex + if(len >= 1) + { + sram.resize(len); + StringToBytes(val,&sram[0],len); // decodes either base64 or hex + } + } } @@ -231,6 +242,8 @@ int MovieData::dump(std::ostream *os, bool binary) if(savestate.size() != 0) *os << "savestate " << BytesToString(&savestate[0],savestate.size()) << endl; + if(sram.size() != 0) + *os << "sram " << BytesToString(&sram[0],sram.size()) << endl; if(binary) { //put one | to start the binary dump @@ -442,6 +455,11 @@ void _CDECL_ FCEUI_LoadMovie(const char *fname, bool _read_only, bool tasedit, i currRerecordCount = currMovieData.rerecordCount; InitMovieTime(); MMU_new.backupDevice.movie_mode(); + if(currMovieData.sram.size() != 0) + { + bool success = MovieData::loadSramFrom(&currMovieData.sram); + if(!success) return; + } freshMovie = true; ClearAutoHold(); @@ -460,10 +478,55 @@ static void openRecordingMovie(const char* fname) strcpy(curMovieFilename, fname); } +bool MovieData::loadSramFrom(std::vector* buf) +{ + memorystream ms(buf); + MMU_new.backupDevice.load_movie(&ms); + return true; +} + +bool FCEUSS_SaveSRAM(std::ostream* outstream, std:: string fname) +{ + //a temp memory stream. we'll dump some data here and then compress + //TODO - support dumping directly without compressing to save a buffer copy + + memorystream ms; + std::ostream* os = (std::ostream*)&ms; + + //size it + FILE * fp = fopen( fname.c_str(), "r" ); + if(!fp) + return 0; + + fseek( fp, 0, SEEK_END ); + int size = ftell(fp); + fclose(fp); + + filebuf fb; + fb.open (fname.c_str(), ios::in | ios::binary);//ios::in + istream is(&fb); + + char *buffer = new char[size]; + + is.read(buffer, size); + + outstream->write((char*)buffer,size); + + fb.close(); + + return true; +} + +void MovieData::dumpSramTo(std::vector* buf, std::string sramfname) { + + memorystream ms(buf); + FCEUSS_SaveSRAM(&ms, sramfname); + ms.trim(); +} //begin recording a new movie //TODO - BUG - the record-from-another-savestate doesnt work. - void _CDECL_ FCEUI_SaveMovie(const char *fname, std::wstring author) +void _CDECL_ FCEUI_SaveMovie(const char *fname, std::wstring author, int flag, std::string sramfname) { //if(!FCEU_IsValidUI(FCEUI_RECORDMOVIE)) // return; @@ -495,6 +558,9 @@ static void openRecordingMovie(const char* fname) //else // MovieData::dumpSavestateTo(&currMovieData.savestate,Z_BEST_COMPRESSION); + if(flag == 1) + MovieData::dumpSramTo(&currMovieData.sram, sramfname); + //we are going to go ahead and dump the header. from now on we will only be appending frames currMovieData.dump(osRecordingMovie, false); @@ -504,6 +570,12 @@ static void openRecordingMovie(const char* fname) InitMovieTime(); MMU_new.backupDevice.movie_mode(); + if(currMovieData.sram.size() != 0) + { + bool success = MovieData::loadSramFrom(&currMovieData.sram); + if(!success) return; + } + driver->USR_InfoMessage("Movie recording started."); } diff --git a/desmume/src/movie.h b/desmume/src/movie.h index a32c3ec03..cb79d6ff3 100644 --- a/desmume/src/movie.h +++ b/desmume/src/movie.h @@ -119,6 +119,7 @@ public: std::string romSerial; std::string romFilename; std::vector savestate; + std::vector sram; std::vector records; std::vector comments; @@ -166,6 +167,9 @@ public: static bool loadSavestateFrom(std::vector* buf); static void dumpSavestateTo(std::vector* buf, int compressionLevel); + + static bool loadSramFrom(std::vector* buf); + static void dumpSramTo(std::vector* buf, std::string sramfname); //void TryDumpIncremental(); private: @@ -185,7 +189,7 @@ extern EMOVIEMODE movieMode; //adelikat: main needs this for frame counter disp extern MovieData currMovieData; //adelikat: main needs this for frame counter display bool FCEUI_MovieGetInfo(std::istream* fp, MOVIE_INFO& info, bool skipFrameCount); -void _CDECL_ FCEUI_SaveMovie(const char *fname, std::wstring author); +void _CDECL_ FCEUI_SaveMovie(const char *fname, std::wstring author, int flag, std::string sramfname); void _CDECL_ FCEUI_LoadMovie(const char *fname, bool _read_only, bool tasedit, int _pauseframe); void FCEUI_StopMovie(); void FCEUMOV_AddInputState(); diff --git a/desmume/src/windows/replay.cpp b/desmume/src/windows/replay.cpp index a69bca91a..3d3a1cd26 100644 --- a/desmume/src/windows/replay.cpp +++ b/desmume/src/windows/replay.cpp @@ -111,6 +111,8 @@ BOOL CALLBACK ReplayDialogProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lP return false; } +int flag=0; +std::string sramfname; //Record movie dialog static BOOL CALLBACK RecordDialogProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam) @@ -122,6 +124,7 @@ static BOOL CALLBACK RecordDialogProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LP switch(uMsg) { case WM_INITDIALOG: + CheckDlgButton(hwndDlg, IDC_START_FROM_SRAM, ((flag == 1) ? BST_CHECKED : BST_UNCHECKED)); return false; case WM_COMMAND: @@ -132,7 +135,7 @@ static BOOL CALLBACK RecordDialogProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LP fname = GetDlgItemText(hwndDlg,IDC_EDIT_FILENAME); if (fname.length()) { - FCEUI_SaveMovie(fname.c_str(), author); + FCEUI_SaveMovie(fname.c_str(), author, flag, sramfname); EndDialog(hwndDlg, 0); } return true; @@ -171,11 +174,47 @@ static BOOL CALLBACK RecordDialogProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LP return true; } + case IDC_BUTTON_BROWSESRAM: + { + OPENFILENAME ofn; + char szChoice[MAX_PATH]={0}; + // browse button + ZeroMemory(&ofn, sizeof(ofn)); + ofn.lStructSize = sizeof(ofn); + ofn.hwndOwner = MainWindow->getHWnd(); + ofn.lpstrFilter = "Desmume SRAM File (*.dsv)\0*.dsv\0All files(*.*)\0*.*\0\0"; + ofn.lpstrFile = szChoice; + ofn.lpstrTitle = "Choose SRAM"; + ofn.lpstrDefExt = "dsv"; + ofn.nMaxFile = MAX_PATH; + ofn.Flags = OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT; + GetOpenFileName(&ofn); + + //If user did not specify an extension, add .dsm for them + fname = szChoice; + x = fname.find_last_of("."); + if (x < 0) + fname.append(".dsv"); + + SetDlgItemText(hwndDlg, IDC_EDIT_SRAMFILENAME, fname.c_str()); + sramfname=(std::string)fname; + //if(GetSaveFileName(&ofn)) + // UpdateRecordDialogPath(hwndDlg,szChoice); + + return true; + } } - } + + HWND cur = GetDlgItem(hwndDlg, IDC_EDIT_SRAMFILENAME); + IsDlgButtonChecked(hwndDlg, IDC_START_FROM_SRAM) ? flag=1 : flag=0; + IsDlgButtonChecked(hwndDlg, IDC_START_FROM_SRAM) ? EnableWindow(cur, TRUE) : EnableWindow(cur, FALSE); + + cur = GetDlgItem(hwndDlg, IDC_BUTTON_BROWSESRAM); + IsDlgButtonChecked(hwndDlg, IDC_START_FROM_SRAM) ? EnableWindow(cur, TRUE) : EnableWindow(cur, FALSE); + return false; } diff --git a/desmume/src/windows/resource.h b/desmume/src/windows/resource.h index 7f10b8cf1..f1911c8ed 100644 --- a/desmume/src/windows/resource.h +++ b/desmume/src/windows/resource.h @@ -203,6 +203,9 @@ #define IDD_IOREG_VIEW_SPI 973 #define IDD_IOREG_VIEW_CP15 975 #define IDD_SOUND_VIEW 977 +#define IDC_START_FROM_SRAM 978 +#define IDC_EDIT_SRAMFILENAME 979 +#define IDC_BUTTON_BROWSESRAM 980 #define IDC_C_WATCH_UP 980 #define IDD_EDITWATCH 980 #define IDC_C_WATCH_DOWN 981 diff --git a/desmume/src/windows/resources.rc b/desmume/src/windows/resources.rc index f9609c51bbff68487a5fda59ce1f5d15cba19ca2..eb968aebf86d55463c18cf6a1c57e86bd5239e9a 100644 GIT binary patch delta 352 zcmbQzs=cL4yP<`#g{g(Pg{6hHg{_5s3r9g0t098{gT?fXsT{f6A9Qi>F)~_Achq8& zp1$B4yVB%>Uo6uNdN`^eg3i+eE;4gXKk$@UXggOg2M5#i3x!-9lN-J&O`q_dnN7Ti zp@cz!A&sGkA)g@^$O>i%VsK>eoxZS=MR>Zxeohv_cm_A1m_LIrLp(%wy5n+|!08`K zI9R5)&Ek-o{-ATTU+&52KQhO7{`7H(rvKRw|EGtYFZPs|b1FTCZ*nO?AhC89lG0tXOtZV#Bi