diff --git a/desmume/src/Makefile.am b/desmume/src/Makefile.am index 8e6a218fb..d81b15cb5 100644 --- a/desmume/src/Makefile.am +++ b/desmume/src/Makefile.am @@ -18,11 +18,10 @@ libdesmume_a_SOURCES = \ common.cpp common.h \ debug.cpp debug.h driver.h \ Disassembler.cpp Disassembler.h \ - dscard.h fat.h FIFO.cpp FIFO.h \ + dscard.h emufile.h emufile.cpp fat.h FIFO.cpp FIFO.h \ GPU.cpp GPU.h \ GPU_osd.cpp GPU_osd.h \ mem.h mc.cpp mc.h \ - memorystream.h \ path.h \ readwrite.cpp readwrite.h \ wifi.cpp wifi.h \ diff --git a/desmume/src/NDSSystem.cpp b/desmume/src/NDSSystem.cpp index 8b4eb10cb..fdc3b9678 100644 --- a/desmume/src/NDSSystem.cpp +++ b/desmume/src/NDSSystem.cpp @@ -717,8 +717,6 @@ void GameInfo::populate() } } #ifdef WIN32 -#include "memorystream.h" -#include static std::vector buffer; static std::vector v; diff --git a/desmume/src/emufile.cpp b/desmume/src/emufile.cpp new file mode 100644 index 000000000..7068220a1 --- /dev/null +++ b/desmume/src/emufile.cpp @@ -0,0 +1,14 @@ +#include "types.h" +#include "emufile.h" + +#include + +bool EMUFILE::readAllBytes(std::vector* dstbuf, const std::string& fname) +{ + EMUFILE_FILE file(fname.c_str(),"rb"); + if(file.fail()) return false; + int size = file.size(); + dstbuf->resize(size); + file.fread(&dstbuf->at(0),size); + return true; +} \ No newline at end of file diff --git a/desmume/src/emufile.h b/desmume/src/emufile.h index f53a65d74..ccb8ac5bb 100644 --- a/desmume/src/emufile.h +++ b/desmume/src/emufile.h @@ -38,6 +38,7 @@ public: virtual ~EMUFILE() {} + static bool readAllBytes(std::vector* buf, const std::string& fname); bool fail() { return failbit; } @@ -157,7 +158,7 @@ public: pos += offset; break; case SEEK_END: - pos = size()-len; + pos = size()+offset; break; default: assert(false); @@ -195,16 +196,9 @@ public: } virtual int fprintf(const char *format, ...) { - //TODO - BLEHHHHHHHH - char temp[1024]; va_list argptr; va_start(argptr, format); - int ret = ::vsprintf(temp, format, argptr); - if(ret<0 || ret>=1024) { - assert(false); - return -1; - } - fwrite(temp,ret); + int ret = ::vfprintf(fp, format, argptr); va_end(argptr); return ret; }; diff --git a/desmume/src/mc.cpp b/desmume/src/mc.cpp index dacb32a23..7bb6e4b7f 100644 --- a/desmume/src/mc.cpp +++ b/desmume/src/mc.cpp @@ -961,36 +961,36 @@ bool BackupDevice::load_duc(const char* filename) } -bool BackupDevice::load_movie(std::istream* is) { +bool BackupDevice::load_movie(EMUFILE* is) { const s32 cookieLen = (s32)strlen(kDesmumeSaveCookie); - is->seekg(-cookieLen, std::ios::end); - is->seekg(-4, std::ios::cur); + is->fseek(-cookieLen, SEEK_END); + is->fseek(-4, SEEK_CUR); u32 version = 0xFFFFFFFF; - is->read((char*)&version,4); + is->fread((char*)&version,4); if(version!=0) { printf("Unknown save file format\n"); return false; } - is->seekg(-24, std::ios::cur); + is->fseek(-24, SEEK_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); + is->fread((char*)&info.size,4); + is->fread((char*)&info.padSize,4); + is->fread((char*)&info.type,4); + is->fread((char*)&info.addr_size,4); + is->fread((char*)&info.mem_size,4); //establish the save data data.resize(info.size); - is->seekg(0, std::ios::beg); + is->fseek(0, SEEK_SET); if(info.size>0) - is->read((char*)&data[0],info.size); + is->fread((char*)&data[0],info.size); state = RUNNING; addr_size = info.addr_size; diff --git a/desmume/src/mc.h b/desmume/src/mc.h index 0906f365f..f0aa9f8f4 100644 --- a/desmume/src/mc.h +++ b/desmume/src/mc.h @@ -103,7 +103,7 @@ public: bool load_no_gba(const char *fname); bool load_raw(const char* filename); bool save_raw(const char* filename); - bool load_movie(std::istream* is); + bool load_movie(EMUFILE* 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/memorystream.h b/desmume/src/memorystream.h deleted file mode 100644 index 83ebc9e94..000000000 --- a/desmume/src/memorystream.h +++ /dev/null @@ -1,324 +0,0 @@ -/* Copyright (C) 2008-2009 DeSmuME team - - This file is part of DeSmuME - - DeSmuME is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - DeSmuME is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with DeSmuME; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#ifndef _memorystream_h_ -#define _memorystream_h_ - -#include -#include -#include -#include -#include -#include - -template -class memory_streambuf: public std::streambuf { -private: - - friend class memorystream; - - //the current buffer - T* buf; - - //the current allocated capacity of the buffer - size_t capacity; - - //whether the sequence is owned by the stringbuf - bool myBuf; - - //the logical length of the buffer - size_t length; - - //the current 'write window' starting position within the buffer for writing. - size_t ww; - - //a vector that we have been told to use - std::vector* usevec; - - -public: - - memory_streambuf(int _capacity) - : buf(new T[capacity=_capacity]) - , myBuf(true) - , length(_capacity) - , ww(0) - , usevec(0) - { - sync(); - } - - - memory_streambuf() - : buf(new T[capacity = 128]) - , myBuf(true) - , length(0) - , ww(0) - , usevec(0) - { - sync(); - } - - //constructs a non-expandable streambuf around the provided buffer - memory_streambuf(T* usebuf, int buflength) - : buf(usebuf) - , myBuf(false) - , length(buflength) - , ww(0) - , usevec(0) - { - sync(); - } - - //constructs an expandable streambuf around the provided buffer - memory_streambuf(std::vector* _usevec) - : capacity(_usevec->size()) - , myBuf(false) - , length(_usevec->size()) - , ww(0) - , usevec(_usevec) - { - if(length>0) - buf = &(*_usevec)[0]; - else buf = 0; - - sync(); - } - - ~memory_streambuf() - { - //only cleanup if we own the seq - if(myBuf) delete[] buf; - } - - //the logical length of the buffer - size_t size() - { - sync(); - return length; - } - - //to avoid copying, rebuilds the provided vector and copies the streambuf contents into it - void toVector(std::vector& out) - { - out.resize(length); - memcpy(&out[0],buf,length); - } - - //maybe the compiler can avoid copying, but maybe not: returns a vector representing the current streambuf - std::vector toVector() - { - return std::vector(buf,buf+length); - } - - //if the memorystream wraps a vector, the vector will be trimmed to the correct size,. - //you probably need to use this if you are using the vector wrapper - void trim() - { - if(!usevec) return; - usevec->resize(size()); - } - - //tells the current read or write position - std::streampos tell(std::ios::openmode which) - { - if(which == std::ios::in) - return tellRead(); - else if(which == std::ios::out) - return tellWrite(); - else return -1; - } - - //tells the current read position - std::streampos tellRead() - { - return gptr()-eback(); - } - - //tells the current write position - std::streampos tellWrite() - { - return pptr()-pbase() + ww; - } - - int sync() - { - dosync(-1); - return 0; - } - - T* getbuf() - { - sync(); - return buf; - } - - //if we were provided a buffer, then calling this gives us ownership of it - void giveBuf() { - myBuf = true; - } - - void expand(size_t upto) - { - if(!myBuf && !usevec) - throw new std::runtime_error("memory_streambuf is not expandable"); - - size_t newcapacity; - if(upto == (size_t)-1) - newcapacity = capacity + capacity/2 + 2; - else - newcapacity = std::max(upto,capacity); - - if(newcapacity == capacity) return; - - //if we are supposed to use the vector, then do it now - if(usevec) - { - usevec->resize(newcapacity); - capacity = usevec->size(); - buf = &(*usevec)[0]; - } - else - { - //otherwise, manage our own buffer - T* newbuf = new T[newcapacity]; - memcpy(newbuf,buf,capacity); - delete[] buf; - capacity = newcapacity; - buf = newbuf; - } - } - -private: - - void dosync(int c) - { - size_t wp = tellWrite(); - size_t rp = tellRead(); - - //if we are supposed to insert a character.. - if(c != -1) - { - buf[wp] = c; - wp++; - } - - //the length is determined by the highest character that was ever inserted - length = std::max(length,wp); - - //the write window advances to begin at the current write insertion point - ww = wp; - - //set the new write and read windows - setp(buf+ww, buf + capacity); - setg(buf, buf+rp, buf + length); - } - -protected: - - int overflow(int c) - { - expand((size_t)-1); - dosync(c); - return 1; - } - - std::streambuf::pos_type seekpos(pos_type pos, std::ios::openmode which) - { - //extend if we are seeking the write cursor - if(which & std::ios_base::out) - expand(pos); - - sync(); - - if(which & std::ios_base::in) - setg(buf, buf+pos, buf + length); - if(which & std::ios_base::out) - { - ww = pos; - setp(buf+pos, buf + capacity); - } - - return pos; - } - - pos_type seekoff(off_type off, std::ios::seekdir way, std::ios::openmode which) - { - switch(way) { - case std::ios::beg: - return seekpos(off, which); - case std::ios::cur: - return seekpos(tell(which)+off, which); - case std::ios::end: - return seekpos(length+off, which); - default: - return -1; - } - } - -}; - -//an iostream that uses the memory_streambuf to effectively act much like a c# memorystream -//please call sync() after writing data if you want to read it back -class memorystream : public std::basic_iostream > -{ -public: - memorystream() - : std::basic_iostream >(&streambuf) - {} - - memorystream(int sz) - : std::basic_iostream >(&streambuf) - , streambuf(sz) - {} - - memorystream(char* usebuf, int buflength) - : std::basic_iostream >(&streambuf) - , streambuf(usebuf, buflength) - {} - - memorystream(std::vector* usevec) - : std::basic_iostream >(&streambuf) - , streambuf(usevec) - {} - - //the underlying memory_streambuf - memory_streambuf streambuf; - - -public: - - size_t size() { return streambuf.size(); } - char* buf() { return streambuf.getbuf(); } - //flushes all the writing state and ensures the stream is ready for reading - void sync() { streambuf.sync(); } - //rewinds the cursors to offset 0 - void rewind() { streambuf.seekpos(0,std::ios::in | std::ios::out); } - - //if the memorystream wraps a vector, the vector will be trimmed to the correct size,. - //you probably need to use this if you are using the vector wrapper - void trim() { streambuf.trim(); } - - void giveBuf() { streambuf.giveBuf(); } - - memory_streambuf& getStreambuf() { return streambuf; } -}; - - -#endif diff --git a/desmume/src/movie.cpp b/desmume/src/movie.cpp index c2ccb84c3..958e37ad5 100644 --- a/desmume/src/movie.cpp +++ b/desmume/src/movie.cpp @@ -32,7 +32,6 @@ #include "mic.h" #include "version.h" #include "GPU_osd.h" -//#include "memorystream.h" #include "path.h" #include "emufile.h" @@ -512,50 +511,45 @@ static void openRecordingMovie(const char* fname) strcpy(curMovieFilename, fname); } -bool MovieData::loadSramFrom(std::vector* buf) -{//TODO -// memorystream ms(buf); -// MMU_new.backupDevice.load_movie(&ms); - return true; -} - -static bool FCEUSS_SaveSRAM(std::ostream* outstream, std:: string fname) +bool MovieData::loadSramFrom(std::vector* buf) { - //a temp memory stream. we'll dump some data here and then compress - //TODO - support dumping directly without compressing to save a buffer copy -//TODO -/* memorystream 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(); -*/ + EMUFILE_MEMORY ms(buf); + MMU_new.backupDevice.load_movie(&ms); return true; } -void MovieData::dumpSramTo(std::vector* buf, std::string sramfname) { -//TODO -// memorystream ms(buf); -// FCEUSS_SaveSRAM(&ms, sramfname); -// ms.trim(); -} +//static bool FCEUSS_SaveSRAM(EMUFILE* outstream, const 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 +////TODO +///* memorystream 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; +//} //begin recording a new movie //TODO - BUG - the record-from-another-savestate doesnt work. @@ -589,7 +583,7 @@ void _CDECL_ FCEUI_SaveMovie(const char *fname, std::wstring author, int flag, s // MovieData::dumpSavestateTo(&currMovieData.savestate,Z_BEST_COMPRESSION); if(flag == 1) - MovieData::dumpSramTo(&currMovieData.sram, sramfname); + EMUFILE::readAllBytes(&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); diff --git a/desmume/src/movie.h b/desmume/src/movie.h index 28c4d2c8b..6b1be485f 100644 --- a/desmume/src/movie.h +++ b/desmume/src/movie.h @@ -119,8 +119,8 @@ public: u32 romChecksum; std::string romSerial; std::string romFilename; - std::vector savestate; - std::vector sram; + std::vector savestate; + std::vector sram; std::vector records; std::vector comments; @@ -166,11 +166,10 @@ public: void clearRecordRange(int start, int len); void insertEmpty(int at, int frames); - static bool loadSavestateFrom(std::vector* buf); - static void dumpSavestateTo(std::vector* buf, int compressionLevel); + 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); + static bool loadSramFrom(std::vector* buf); //void TryDumpIncremental(); private: diff --git a/desmume/src/saves.cpp b/desmume/src/saves.cpp index d3916c2ef..be78da14b 100644 --- a/desmume/src/saves.cpp +++ b/desmume/src/saves.cpp @@ -37,7 +37,6 @@ #include "GPU_osd.h" #include "version.h" -#include "memorystream.h" #include "readwrite.h" #include "gfx3d.h" #include "movie.h" diff --git a/desmume/src/windows/DeSmuME_2005.vcproj b/desmume/src/windows/DeSmuME_2005.vcproj index c42798eb2..9648a8f7e 100644 --- a/desmume/src/windows/DeSmuME_2005.vcproj +++ b/desmume/src/windows/DeSmuME_2005.vcproj @@ -1,4 +1,4 @@ - + + + diff --git a/desmume/src/windows/DeSmuME_2008.vcproj b/desmume/src/windows/DeSmuME_2008.vcproj index a09448ed8..a698ac381 100644 --- a/desmume/src/windows/DeSmuME_2008.vcproj +++ b/desmume/src/windows/DeSmuME_2008.vcproj @@ -665,6 +665,10 @@ RelativePath="..\Disassembler.cpp" > + + @@ -1227,6 +1231,10 @@ RelativePath="..\driver.h" > + + @@ -1275,10 +1283,6 @@ RelativePath="..\mem.h" > - - diff --git a/desmume/src/windows/replay.cpp b/desmume/src/windows/replay.cpp index ea0ab6337..200617c83 100644 --- a/desmume/src/windows/replay.cpp +++ b/desmume/src/windows/replay.cpp @@ -118,10 +118,10 @@ static char playfilename[MAX_PATH] = ""; void Describe(HWND hwndDlg) { - EMUFILE* fp = new EMUFILE_FILE(playfilename,"rb"); + EMUFILE_FILE fp(playfilename,"rb"); + if(fp.fail()) return; MovieData md; - LoadFM2(md, fp, INT_MAX, false); - delete fp; + LoadFM2(md, &fp, INT_MAX, false); u32 num_frames = md.records.size(); @@ -241,7 +241,6 @@ INT_PTR CALLBACK ReplayDialogProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM int flag=0; -std::string sramfname; //Record movie dialog static INT_PTR CALLBACK RecordDialogProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam) @@ -249,7 +248,6 @@ static INT_PTR CALLBACK RecordDialogProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, static struct CreateMovieParameters* p = NULL; std::wstring author = L""; std::string fname; - int x; //temp vairable switch(uMsg) { case WM_INITDIALOG: @@ -263,6 +261,7 @@ static INT_PTR CALLBACK RecordDialogProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, case IDOK: { author = GetDlgItemTextW<500>(hwndDlg,IDC_EDIT_AUTHOR); fname = GetDlgItemText(hwndDlg,IDC_EDIT_FILENAME); + std::string sramfname = GetDlgItemText(hwndDlg,IDC_EDIT_SRAMFILENAME); if (fname.length()) { FCEUI_SaveMovie(fname.c_str(), author, flag, sramfname); @@ -332,7 +331,6 @@ static INT_PTR CALLBACK RecordDialogProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, fname.append(".dsv"); */ SetDlgItemText(hwndDlg, IDC_EDIT_SRAMFILENAME, fname.c_str()); - sramfname=(std::string)fname; } //if(GetSaveFileName(&ofn)) // UpdateRecordDialogPath(hwndDlg,szChoice); diff --git a/desmume/src/windows/resources.rc b/desmume/src/windows/resources.rc index b9036672d..a418805e0 100644 Binary files a/desmume/src/windows/resources.rc and b/desmume/src/windows/resources.rc differ diff --git a/desmume/src/windows/soundView.cpp b/desmume/src/windows/soundView.cpp index 8be6a49b2..2f6d221ed 100644 --- a/desmume/src/windows/soundView.cpp +++ b/desmume/src/windows/soundView.cpp @@ -248,7 +248,6 @@ static void SoundView_SwitchChanOfs(SoundView_DataStruct *data) static INT_PTR CALLBACK SoundView_DlgProc(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam) { - LONG_PTR x; SoundView_DataStruct *data = (SoundView_DataStruct*)GetWindowLongPtr(hDlg, DWLP_USER); if((data == NULL) && (uMsg != WM_INITDIALOG)) return 0;