From 41a10c95f5e7b74f6f30dd1e9530133b3000e3b8 Mon Sep 17 00:00:00 2001 From: zeromus Date: Wed, 26 Aug 2009 19:01:21 +0000 Subject: [PATCH] finish porting iostream stuff to EMUFILE*. movies and sram-start movies work once again --- desmume/src/Makefile.am | 3 +- desmume/src/NDSSystem.cpp | 2 - desmume/src/emufile.cpp | 14 + desmume/src/emufile.h | 12 +- desmume/src/mc.cpp | 24 +- desmume/src/mc.h | 2 +- desmume/src/memorystream.h | 324 ------------------------ desmume/src/movie.cpp | 78 +++--- desmume/src/movie.h | 11 +- desmume/src/saves.cpp | 1 - desmume/src/windows/DeSmuME_2005.vcproj | 6 +- desmume/src/windows/DeSmuME_2008.vcproj | 12 +- desmume/src/windows/replay.cpp | 10 +- desmume/src/windows/resources.rc | Bin 688730 -> 688386 bytes desmume/src/windows/soundView.cpp | 1 - 15 files changed, 89 insertions(+), 411 deletions(-) create mode 100644 desmume/src/emufile.cpp delete mode 100644 desmume/src/memorystream.h 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 b9036672daa3b9b7fbd1a4f4016f12295821269a..a418805e07e52a09a89690d940d05995519e9470 100644 GIT binary patch delta 1265 zcmbu=<24nXxR2(3$@e?H=nI#>q1drvDiZ)DU*;2dSKCm zLc)oTA0mw)3~G}Mj~}+hN+d$V3W`cBqoN0dNk~XVcXVdd&wZN9x##?6hWq2bKIy8j zceQ<{LK1k0G#~m?skJ>)x-LvB44U2Yv_eMIhfQePLFWnW%c?9#!2OkWwU2)E&xKr* z)YESL9a@cdN~IA&2|N`coJK6r>62>U_)4<_eA&X-_zE}sr7Z<`6C_8OTJU1z7pb-s z`EsNLYfhMbQ5e2xE?uN<#$j^UT$h5aeWtEmm%Qu|_|A}M%uOSwBnXtTR;s=8c zW}oQV8)7|L!~RwhuQgzEkfdnwaI2fyaribd>C^Fl%gvFaa?gT^Fyo=rp-L+?G( ztwmo88x8ohdoud%YyCTh9}^L)dq^kMeq`1Ve~GVm@+JHFh$jkzgQQ{hlw-49`XowN zJwj^pwJO$l=x!4PGR0)9&lKHRO6`v-rLEkd^jB_y@4sj?UO6DHkkwOtf|rkqS(Q`s zIzEY`Wm5`POjt!TbSY~1hzRcv%P#b1HEMgR(vmKLrHF1;+-Fna<_7v`Vousf9|#amk;K3dJlEl66=vj8uf(WGcjs%T$9cx!`CH7Q6PaQZ zxl!FNaFsD=?O?;&xg)1($m1gI7`Vp_d7Pyk8y+%49=B_eiEgdUT8jBzAGHaQX6X38SG$fL11W|2P= zzRk;v)ysxImqIW?wqkyyJjQp7`$%QWz0Z;Bb+*7|*)VpioR!1D{)F;!*?|F&i^rjc capzUJGadNN5r=6n<$*llSBV2%@fLUGKQxS*h5!Hn delta 1640 zcmbu9T}TvB7>0M|%$Yr-w&`kXYniy%pM+SLMW+3zwXU_UX(iInR+4rTu|-kTB2p3* z6;1G2h)Nf_7h%SxUzCN|DkNTL6!b?)q(m2DArxBCnIY?D<|1O4VZJ%%J@0#%?>TjK z>95YFcYLI3pfO4H&a#E=a;u;h8FBXTn01+=72%AyFWbYe>IFe~=3|a<#pu+WaQSp? zF512FgrIiR*udeFk3dtYoCN+HVG8+Mpb+gKCzWExNBO=N_|uIOsbZ)Y-_%*XanSo* znTrM2tXWGn-CXpA#OwGYn~58*bg~dNQbXbMT#dz%)zX4BFnLWm2&>PLWBBT*RG_Hk(-Hh|M%q}d zDS&GoSTQP1l>S*Du!?5u9j^7hwp^u%%kt?(5qiAz6s%7cmO#gBD#M_M?tq_%ST?Ni z(zL5V7wjtGUxp^=66kSC3=%feeyBaEq~rTSDhiP2p?-Kc6@xX`rSs7+Ud7U|XWZIRi5yP96*-fQ zi5iYo1%`j_^)2?#AV%Lc({K>2hFy#tKNE^Lc}}eDW+v^=@pEEJFEinmGibssC(qas zIdCQ#&YH0XIA%`V^VBRQXU&Ph7iK9ra3+o%E@MZ0Il_LVz)e}1-#Mx5XF3+`(F$uj zr6`hKReqK15Spd@oT<`q%%)5dz2pQXU{t(P_ZPvgoyyu=