From e05c17dfbbef8b38cc9a8cd1fda7a3e5dc01542f Mon Sep 17 00:00:00 2001 From: zeromus Date: Wed, 26 Aug 2009 08:54:48 +0000 Subject: [PATCH] transform a bunch of iostream stuff into EMUFILE. main savestate and savedata codepaths work, movies may still be borked. ill fix it soon. --- desmume/src/GPU.cpp | 11 +- desmume/src/GPU.h | 5 +- desmume/src/NDSSystem.cpp | 33 +- desmume/src/NDSSystem.h | 7 +- desmume/src/SPU.cpp | 6 +- desmume/src/SPU.h | 12 +- desmume/src/emufile.h | 232 ++++++++++++- desmume/src/gfx3d.cpp | 4 +- desmume/src/gfx3d.h | 20 +- desmume/src/mc.cpp | 58 ++-- desmume/src/mc.h | 8 +- desmume/src/memorystream.h | 19 ++ desmume/src/mic.h | 4 +- desmume/src/movie.cpp | 52 +-- desmume/src/readwrite.cpp | 73 ++-- desmume/src/readwrite.h | 55 ++- desmume/src/saves.cpp | 131 ++++--- desmume/src/utils/xstring.h | 18 +- desmume/src/windows/DeSmuME_2005.vcproj | 432 ++++++++++++------------ desmume/src/windows/mic.cpp | 14 +- desmume/src/windows/replay.cpp | 24 +- 21 files changed, 730 insertions(+), 488 deletions(-) diff --git a/desmume/src/GPU.cpp b/desmume/src/GPU.cpp index 125fee8b2..71a79fb1f 100644 --- a/desmume/src/GPU.cpp +++ b/desmume/src/GPU.cpp @@ -4,6 +4,7 @@ Copyright (C) 2006-2007 Theo Berkau Copyright (C) 2007 shash + Copyright (C) 2008-2009 DeSmuME team This file is part of DeSmuME @@ -2600,12 +2601,12 @@ void GPU_ligne(NDS_Screen * screen, u16 l, bool skip) GPU_ligne_MasterBrightness(screen, l); } -void gpu_savestate(std::ostream* os) +void gpu_savestate(EMUFILE* os) { //version write32le(1,os); - os->write((char*)GPU_screen,sizeof(GPU_screen)); + os->fwrite((char*)GPU_screen,sizeof(GPU_screen)); write32le(MainScreen.gpu->affineInfo[0].x,os); write32le(MainScreen.gpu->affineInfo[0].y,os); @@ -2617,10 +2618,10 @@ void gpu_savestate(std::ostream* os) write32le(SubScreen.gpu->affineInfo[1].y,os); } -bool gpu_loadstate(std::istream* is, int size) +bool gpu_loadstate(EMUFILE* is, int size) { //read version - int version; + u32 version; //sigh.. shouldve used a new version number if(size == 256*192*2*2) @@ -2636,7 +2637,7 @@ bool gpu_loadstate(std::istream* is, int size) if(version<0||version>1) return false; - is->read((char*)GPU_screen,sizeof(GPU_screen)); + is->fread((char*)GPU_screen,sizeof(GPU_screen)); if(version==1) { diff --git a/desmume/src/GPU.h b/desmume/src/GPU.h index 028695acb..f3681558a 100644 --- a/desmume/src/GPU.h +++ b/desmume/src/GPU.h @@ -4,6 +4,7 @@ Copyright (C) 2006-2007 Theo Berkau Copyright (C) 2007 shash + Copyright (C) 2009-2009 DeSmuME team This file is part of DeSmuME @@ -36,8 +37,8 @@ //#undef FORCEINLINE //#define FORCEINLINE -void gpu_savestate(std::ostream* os); -bool gpu_loadstate(std::istream* is, int size); +void gpu_savestate(EMUFILE* os); +bool gpu_loadstate(EMUFILE* is, int size); /******************************************************************************* this structure is for display control, diff --git a/desmume/src/NDSSystem.cpp b/desmume/src/NDSSystem.cpp index c9eb901d3..8b4eb10cb 100644 --- a/desmume/src/NDSSystem.cpp +++ b/desmume/src/NDSSystem.cpp @@ -1,4 +1,3 @@ - /* Copyright (C) 2006 yopyop yopyop156@ifrance.com yopyop156.ifrance.com @@ -1507,14 +1506,14 @@ struct TSequenceItem u32 param; bool enabled; - virtual void save(std::ostream* os) + virtual void save(EMUFILE* os) { write64le(timestamp,os); write32le(param,os); writebool(enabled,os); } - virtual bool load(std::istream* is) + virtual bool load(EMUFILE* is) { if(read64le(×tamp,is) != 1) return false; if(read32le(¶m,is) != 1) return false; @@ -1730,7 +1729,7 @@ struct Sequencer void execHardware(); u64 findNext(); - void save(std::ostream* os) + void save(EMUFILE* os) { write64le(nds_timer,os); write64le(nds_arm9_timer,os); @@ -1748,7 +1747,7 @@ struct Sequencer #undef SAVE } - bool load(std::istream* is, int version) + bool load(EMUFILE* is, int version) { if(read64le(&nds_timer,is) != 1) return false; if(read64le(&nds_arm9_timer,is) != 1) return false; @@ -2054,10 +2053,10 @@ void Sequencer::execHardware() void execHardware_interrupts(); -static void saveUserInput(std::ostream* os); -static bool loadUserInput(std::istream* is, int version); +static void saveUserInput(EMUFILE* os); +static bool loadUserInput(EMUFILE* is, int version); -void nds_savestate(std::ostream* os) +void nds_savestate(EMUFILE* os) { //version write32le(2,os); @@ -2067,10 +2066,10 @@ void nds_savestate(std::ostream* os) saveUserInput(os); } -bool nds_loadstate(std::istream* is, int size) +bool nds_loadstate(EMUFILE* is, int size) { //read version - int version; + u32 version; if(read32le(&version,is) != 1) return false; if(version > 2) return false; @@ -2558,17 +2557,17 @@ const UserInput& NDS_getFinalUserInput() } -static void saveUserInput(std::ostream* os, UserInput& input) +static void saveUserInput(EMUFILE* os, UserInput& input) { - os->write((const char*)input.buttons.array, 14); + os->fwrite((const char*)input.buttons.array, 14); writebool(input.touch.isTouch, os); write16le(input.touch.touchX, os); write16le(input.touch.touchY, os); write32le(input.mic.micButtonPressed, os); } -static bool loadUserInput(std::istream* is, UserInput& input, int version) +static bool loadUserInput(EMUFILE* is, UserInput& input, int version) { - is->read((char*)input.buttons.array, 14); + is->fread((char*)input.buttons.array, 14); readbool(&input.touch.isTouch, is); read16le(&input.touch.touchX, is); read16le(&input.touch.touchY, is); @@ -2576,7 +2575,7 @@ static bool loadUserInput(std::istream* is, UserInput& input, int version) return true; } // (userinput is kind of a misnomer, e.g. finalUserInput has to mirror nds.pad, nds.touchX, etc.) -static void saveUserInput(std::ostream* os) +static void saveUserInput(EMUFILE* os) { saveUserInput(os, finalUserInput); saveUserInput(os, intermediateUserInput); // saved in case a savestate is made during input processing (which Lua could do if nothing else) @@ -2584,14 +2583,14 @@ static void saveUserInput(std::ostream* os) for(int i = 0; i < 14; i++) write32le(TurboTime.array[i], os); // saved to make autofire more tolerable to use with re-recording } -static bool loadUserInput(std::istream* is, int version) +static bool loadUserInput(EMUFILE* is, int version) { bool rv = true; rv &= loadUserInput(is, finalUserInput, version); rv &= loadUserInput(is, intermediateUserInput, version); readbool(&validToProcessInput, is); for(int i = 0; i < 14; i++) - read32le(&TurboTime.array[i], is); + read32le((u32*)&TurboTime.array[i], is); return rv; } diff --git a/desmume/src/NDSSystem.h b/desmume/src/NDSSystem.h index 198e59213..ea7255de9 100644 --- a/desmume/src/NDSSystem.h +++ b/desmume/src/NDSSystem.h @@ -32,6 +32,7 @@ #include "SPU.h" #include "mem.h" #include "wifi.h" +#include "emufile.h" #include @@ -295,7 +296,7 @@ struct UserTouch }; struct UserMicrophone { - BOOL micButtonPressed; + u32 micButtonPressed; }; struct UserInput { @@ -347,8 +348,8 @@ void NDS_Reset(); int NDS_ImportSave(const char *filename); bool NDS_ExportSave(const char *filename); -void nds_savestate(std::ostream* os); -bool nds_loadstate(std::istream* is, int size); +void nds_savestate(EMUFILE* os); +bool nds_loadstate(EMUFILE* is, int size); int NDS_WriteBMP(const char *filename); int NDS_LoadFirmware(const char *filename); diff --git a/desmume/src/SPU.cpp b/desmume/src/SPU.cpp index a4e68983a..a41070972 100644 --- a/desmume/src/SPU.cpp +++ b/desmume/src/SPU.cpp @@ -1242,7 +1242,7 @@ void WAV_WavSoundUpdate(void* soundData, int numSamples) ////////////////////////////////////////////////////////////////////////////// -void spu_savestate(std::ostream* os) +void spu_savestate(EMUFILE* os) { //version write32le(2,os); @@ -1277,12 +1277,12 @@ void spu_savestate(std::ostream* os) write64le(double_to_u64(samples),os); } -bool spu_loadstate(std::istream* is, int size) +bool spu_loadstate(EMUFILE* is, int size) { u64 temp64; //read version - int version; + u32 version; if(read32le(&version,is) != 1) return false; SPU_struct *spu = SPU_core; diff --git a/desmume/src/SPU.h b/desmume/src/SPU.h index 493f62bfd..0adb14520 100644 --- a/desmume/src/SPU.h +++ b/desmume/src/SPU.h @@ -23,11 +23,13 @@ #ifndef SPU_H #define SPU_H -#include "types.h" -#include "matrix.h" #include #include #include +#include "types.h" +#include "matrix.h" +#include "emufile.h" + #define SNDCORE_DEFAULT -1 #define SNDCORE_DUMMY 0 @@ -73,7 +75,7 @@ struct channel_struct channel_struct() : cacheItem(NULL) {} - int num; + u32 num; u8 vol; u8 datashift; u8 hold; @@ -144,8 +146,8 @@ void SPU_Emulate_user(void); extern SPU_struct *SPU_core, *SPU_user; extern int spu_core_samples; -void spu_savestate(std::ostream* os); -bool spu_loadstate(std::istream* is, int size); +void spu_savestate(EMUFILE* os); +bool spu_loadstate(EMUFILE* is, int size); class WavWriter { diff --git a/desmume/src/emufile.h b/desmume/src/emufile.h index 49c756a4b..f53a65d74 100644 --- a/desmume/src/emufile.h +++ b/desmume/src/emufile.h @@ -1,45 +1,249 @@ + /* Copyright (C) 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 EMUFILE_H #define EMUFILE_H -class EMUFILE{ +#include +#include +#include "types.h" +#include +#include +#include + +class EMUFILE { +protected: + bool failbit; + +public: + EMUFILE() + : failbit(false) + {} + + virtual ~EMUFILE() {} + + + bool fail() { return failbit; } + + void fread(const void *ptr, size_t bytes){ + _fread(ptr,bytes); + } + + void unget() { fseek(-1,SEEK_CUR); } + + //virtuals +public: + + virtual FILE *get_fp() = 0; + + virtual int fprintf(const char *format, ...) = 0; + + virtual int fgetc() = 0; + virtual int fputc(int c) = 0; + + virtual size_t _fread(const void *ptr, size_t bytes) = 0; + + //removing these return values for now so we can find any code that might be using them and make sure + //they handle the return values correctly + + virtual void fwrite(const void *ptr, size_t bytes) = 0; + + virtual int fseek(int offset, int origin) = 0; + + virtual int ftell() = 0; + virtual int size() = 0; +}; + +//todo - handle read-only specially? +class EMUFILE_MEMORY : public EMUFILE { +private: + std::vector *vec; + s32 pos, len; + bool ownvec; + + void reserve(u32 amt) { + if(vec->size() < amt) + vec->resize(amt); + } + +public: + + EMUFILE_MEMORY(std::vector *underlying) : vec(underlying), ownvec(false), pos(0), len(underlying->size()) { } + EMUFILE_MEMORY(u32 preallocate) : vec(new std::vector()), ownvec(true), pos(0), len(0) { vec->reserve(preallocate); } + EMUFILE_MEMORY() : vec(new std::vector()), ownvec(true), pos(0), len(0) { vec->reserve(1024); } + + ~EMUFILE_MEMORY() { + if(ownvec) delete vec; + } + + u8* buf() { return &(*vec)[0]; } + + virtual FILE *get_fp() { return NULL; } + + virtual int fprintf(const char *format, ...) { + va_list argptr; + va_start(argptr, format); + + //we dont generate straight into the buffer because it will null terminate (one more byte than we want) + int amt = vsnprintf(0,0,format,argptr); + char* tempbuf = new char[amt+1]; + vsprintf(tempbuf,format,argptr); + memcpy((char*)buf()+pos,tempbuf,amt); + pos += amt; + len = std::max(pos,len); + + va_end(argptr); + + return amt; + }; + + virtual int fgetc() { + u8 temp; + if(_fread(&temp,1) != 1) + return EOF; + else return temp; + } + virtual int fputc(int c) { + u8 temp = (u8)c; + //TODO + //if(fwrite(&temp,1)!=1) return EOF; + fwrite(&temp,1); + + return 0; + } + + virtual size_t _fread(const void *ptr, size_t bytes){ + u32 remain = len-pos; + u32 todo = std::min(remain,bytes); + memcpy((void*)ptr,buf()+pos,todo); + pos += todo; + if(todo=1024) { + assert(false); + return -1; + } + fwrite(temp,ret); + va_end(argptr); + return ret; }; - int fgetc() { + virtual int fgetc() { return ::fgetc(fp); } - int fputc(int c) { + virtual int fputc(int c) { return ::fputc(c, fp); } - size_t fread(void *ptr, size_t size, size_t nobj){ - return ::fread(ptr, size, nobj, fp); + virtual size_t _fread(const void *ptr, size_t bytes){ + size_t ret = ::fread((void*)ptr, 1, bytes, fp); + if(ret < bytes) failbit = true; + return ret; } - size_t fwrite(void *ptr, size_t size, size_t nobj){ - return ::fwrite(ptr, size, nobj, fp); + //removing these return values for now so we can find any code that might be using them and make sure + //they handle the return values correctly + + virtual void fwrite(const void *ptr, size_t bytes){ + size_t ret = ::fwrite((void*)ptr, 1, bytes, fp); + if(ret < bytes) failbit = true; } - int fseek(long int offset, int origin){ + virtual int fseek(int offset, int origin){ return ::fseek(fp, offset, origin); } - long int ftell() { - return ::ftell(fp); + virtual int ftell() { + return (u32)::ftell(fp); + } + + virtual int size() { + int oldpos = ftell(); + fseek(0,SEEK_END); + int len = ftell(); + fseek(oldpos,SEEK_SET); + return len; } }; diff --git a/desmume/src/gfx3d.cpp b/desmume/src/gfx3d.cpp index 8f1f9a0cc..5228f10dd 100644 --- a/desmume/src/gfx3d.cpp +++ b/desmume/src/gfx3d.cpp @@ -2446,7 +2446,7 @@ SFORMAT SF_GFX3D[]={ }; //-------------savestate -void gfx3d_savestate(std::ostream* os) +void gfx3d_savestate(EMUFILE* os) { //version write32le(2,os); @@ -2467,7 +2467,7 @@ void gfx3d_savestate(std::ostream* os) } } -bool gfx3d_loadstate(std::istream* is, int size) +bool gfx3d_loadstate(EMUFILE* is, int size) { int version; if(read32le(&version,is) != 1) return false; diff --git a/desmume/src/gfx3d.h b/desmume/src/gfx3d.h index c39d5ebde..7905a66ef 100644 --- a/desmume/src/gfx3d.h +++ b/desmume/src/gfx3d.h @@ -24,10 +24,12 @@ #ifndef _GFX3D_H_ #define _GFX3D_H_ -#include "types.h" #include #include #include +#include "types.h" +#include "emufile.h" + //produce a 32bpp color from a DS RGB16 #define RGB16TO32(col,alpha) (((alpha)<<24) | ((((col) & 0x7C00)>>7)<<16) | ((((col) & 0x3E0)>>2)<<8) | (((col) & 0x1F)<<3)) @@ -89,8 +91,8 @@ inline u32 gfx3d_extendDepth_15_to_24(u32 depth) void gfx3d_init(); void gfx3d_reset(); -#define OSWRITE(x) os->write((char*)&(x),sizeof((x))); -#define OSREAD(x) is->read((char*)&(x),sizeof((x))); +#define OSWRITE(x) os->fwrite((char*)&(x),sizeof((x))); +#define OSREAD(x) is->fread((char*)&(x),sizeof((x))); struct POLY { int type; //tri or quad @@ -116,7 +118,7 @@ struct POLY { int getAlpha() { return (polyAttr>>16)&0x1F; } - void save(std::ostream* os) + void save(EMUFILE* os) { OSWRITE(type); OSWRITE(vertIndexes[0]); OSWRITE(vertIndexes[1]); OSWRITE(vertIndexes[2]); OSWRITE(vertIndexes[3]); @@ -126,7 +128,7 @@ struct POLY { OSWRITE(maxy); } - void load(std::istream* is) + void load(EMUFILE* is) { OSREAD(type); OSREAD(vertIndexes[0]); OSREAD(vertIndexes[1]); OSREAD(vertIndexes[2]); OSREAD(vertIndexes[3]); @@ -164,14 +166,14 @@ struct VERT { fcolor[1] = color[1]; fcolor[2] = color[2]; } - void save(std::ostream* os) + void save(EMUFILE* os) { OSWRITE(x); OSWRITE(y); OSWRITE(z); OSWRITE(w); OSWRITE(u); OSWRITE(v); OSWRITE(color[0]); OSWRITE(color[1]); OSWRITE(color[2]); OSWRITE(fcolor[0]); OSWRITE(fcolor[1]); OSWRITE(fcolor[2]); } - void load(std::istream* is) + void load(EMUFILE* is) { OSREAD(x); OSREAD(y); OSREAD(z); OSREAD(w); OSREAD(u); OSREAD(v); @@ -346,7 +348,7 @@ void gfx3d_GetLineData15bpp(int line, u16** dst); struct SFORMAT; extern SFORMAT SF_GFX3D[]; -void gfx3d_savestate(std::ostream* os); -bool gfx3d_loadstate(std::istream* is, int size); +void gfx3d_savestate(EMUFILE* os); +bool gfx3d_loadstate(EMUFILE* is, int size); #endif diff --git a/desmume/src/mc.cpp b/desmume/src/mc.cpp index 7f37d7a44..dacb32a23 100644 --- a/desmume/src/mc.cpp +++ b/desmume/src/mc.cpp @@ -226,9 +226,9 @@ u8 fw_transfer(memory_chip_t *mc, u8 data) return data; } -bool BackupDevice::save_state(std::ostream* os) +bool BackupDevice::save_state(EMUFILE* os) { - int version = 1; + u32 version = 1; write32le(version,os); write32le(write_enable,os); write32le(com,os); @@ -241,12 +241,12 @@ bool BackupDevice::save_state(std::ostream* os) return true; } -bool BackupDevice::load_state(std::istream* is) +bool BackupDevice::load_state(EMUFILE* is) { - int version; + u32 version; if(read32le(&version,is)!=1) return false; if(version==0 || version==1) { - read32le(&write_enable,is); + readbool(&write_enable,is); read32le(&com,is); read32le(&addr_size,is); read32le(&addr_counter,is); @@ -731,10 +731,11 @@ void BackupDevice::loadfile() if(isMovieMode) return; if(filename.length() ==0) return; //No sense crashing if no filename supplied - FILE* inf = fopen(filename.c_str(),"rb"); - if(!inf) + EMUFILE_FILE* inf = new EMUFILE_FILE(filename.c_str(),"rb"); + if(inf->fail()) { - //no dsv found; we need to try auto-importing a file with .sav extension + delete inf; + //no dsv found; we need to try auto-importing a file with .sav extension printf("DeSmuME .dsv save file not found. Trying to load an old raw .sav file.\n"); //change extension to sav @@ -743,13 +744,14 @@ void BackupDevice::loadfile() tmp[strlen(tmp)-3] = 0; strcat(tmp,"sav"); - inf = fopen(tmp,"rb"); - if(!inf) + inf = new EMUFILE_FILE(tmp,"rb"); + if(inf->fail()) { + delete inf; printf("Missing save file %s\n",filename.c_str()); return; } - fclose(inf); + delete inf; if (!load_no_gba(tmp)) load_raw(tmp); @@ -759,29 +761,29 @@ void BackupDevice::loadfile() //scan for desmume save footer const s32 cookieLen = (s32)strlen(kDesmumeSaveCookie); char *sigbuf = new char[cookieLen]; - fseek(inf, -cookieLen, SEEK_END); - fread(sigbuf,1,cookieLen,inf); + inf->fseek(-cookieLen, SEEK_END); + inf->fread(sigbuf,cookieLen); int cmp = memcmp(sigbuf,kDesmumeSaveCookie,cookieLen); delete[] sigbuf; if(cmp) { //maybe it is a misnamed raw save file. try loading it that way printf("Not a DeSmuME .dsv save file. Trying to load as raw.\n"); - fclose(inf); + delete inf; if (!load_no_gba(filename.c_str())) load_raw(filename.c_str()); return; } //desmume format - fseek(inf, -cookieLen, SEEK_END); - fseek(inf, -4, SEEK_CUR); + inf->fseek(-cookieLen, SEEK_END); + inf->fseek(-4, SEEK_CUR); u32 version = 0xFFFFFFFF; read32le(&version,inf); if(version!=0) { printf("Unknown save file format\n"); return; } - fseek(inf, -24, SEEK_CUR); + inf->fseek(-24, SEEK_CUR); struct { u32 size,padSize,type,addr_size,mem_size; } info; @@ -793,14 +795,14 @@ void BackupDevice::loadfile() //establish the save data data.resize(info.size); - fseek(inf, 0, SEEK_SET); + inf->fseek(0, SEEK_SET); if(info.size>0) - fread(&data[0],1,info.size,inf); //read all the raw data we have + inf->fread(&data[0],info.size); //read all the raw data we have state = RUNNING; addr_size = info.addr_size; //none of the other fields are used right now - fclose(inf); + delete inf; } } @@ -846,11 +848,11 @@ void BackupDevice::flush() //never use save files if we are in movie mode if(isMovieMode) return; - FILE* outf = fopen(filename.c_str(),"wb"); - if(outf) + EMUFILE* outf = new EMUFILE_FILE(filename.c_str(),"wb"); + if(!outf->fail()) { if(data.size()>0) - fwrite(&data[0],1,data.size(),outf); + outf->fwrite(&data[0],data.size()); //write the footer. we use a footer so that we can maximize the chance of the //save file being recognized as a raw save file by other emulators etc. @@ -860,10 +862,10 @@ void BackupDevice::flush() u32 padSize = pad_up_size(size); for(u32 i=size;ifputc(kUninitializedSaveDataValue); //this is just for humans to read - fprintf(outf,"|<--Snip above here to create a raw sav by excluding this DeSmuME savedata footer:"); + outf->fprintf("|<--Snip above here to create a raw sav by excluding this DeSmuME savedata footer:"); //and now the actual footer write32le(size,outf); //the size of data that has actually been written @@ -872,13 +874,13 @@ void BackupDevice::flush() write32le(addr_size,outf); write32le(0,outf); //save memory size write32le(0,outf); //version number - fprintf(outf, "%s", kDesmumeSaveCookie); //this is what we'll use to recognize the desmume format save + outf->fprintf("%s", kDesmumeSaveCookie); //this is what we'll use to recognize the desmume format save - - fclose(outf); + delete outf; } else { + delete outf; printf("Unable to open savefile %s\n",filename.c_str()); } } diff --git a/desmume/src/mc.h b/desmume/src/mc.h index 66598121e..0906f365f 100644 --- a/desmume/src/mc.h +++ b/desmume/src/mc.h @@ -1,5 +1,6 @@ /* Copyright (C) 2006 thoduv Copyright (C) 2006 Theo Berkau + Copyright (C) 2008-2009 DeSmuME team This file is part of DeSmuME @@ -25,6 +26,7 @@ #include #include #include "types.h" +#include "emufile.h" #define MC_TYPE_AUTODETECT 0x0 #define MC_TYPE_EEPROM1 0x1 @@ -76,8 +78,8 @@ public: void reset(); void close_rom(); - bool save_state(std::ostream* os); - bool load_state(std::istream* is); + bool save_state(EMUFILE* os); + bool load_state(EMUFILE* is); //commands from mmu void reset_command(); @@ -110,7 +112,7 @@ public: void lazy_flush(); private: - BOOL write_enable; //is write enabled? + bool write_enable; //is write enabled? u32 com; //persistent command actually handled u32 addr_size, addr_counter; u32 addr; diff --git a/desmume/src/memorystream.h b/desmume/src/memorystream.h index c796f7cf1..83ebc9e94 100644 --- a/desmume/src/memorystream.h +++ b/desmume/src/memorystream.h @@ -1,3 +1,22 @@ +/* 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_ diff --git a/desmume/src/mic.h b/desmume/src/mic.h index aa92286e9..89e99a242 100644 --- a/desmume/src/mic.h +++ b/desmume/src/mic.h @@ -38,7 +38,7 @@ void Mic_Reset(); void Mic_DeInit(); u8 Mic_ReadSample(); -void mic_savestate(std::ostream* os); -bool mic_loadstate(std::istream* is, int size); +void mic_savestate(EMUFILE* os); +bool mic_loadstate(EMUFILE* is, int size); #endif diff --git a/desmume/src/movie.cpp b/desmume/src/movie.cpp index 8a021782d..c2ccb84c3 100644 --- a/desmume/src/movie.cpp +++ b/desmume/src/movie.cpp @@ -118,7 +118,7 @@ void MovieRecord::parsePad(EMUFILE* fp, u16& pad) { char buf[13]; - fp->fread(buf,13,1); + fp->fread(buf,13); pad = 0; for(int i=0;i<13;i++) { @@ -133,14 +133,14 @@ void MovieRecord::parse(MovieData* md, EMUFILE* fp) //by the time we get in here, the initial pipe has already been extracted //extract the commands - commands = u32DecFromIstream(fp->get_fp()); + commands = u32DecFromIstream(fp); fp->fgetc(); //eat the pipe parsePad(fp, pad); - touch.x = u32DecFromIstream(fp->get_fp()); - touch.y = u32DecFromIstream(fp->get_fp()); - touch.touch = u32DecFromIstream(fp->get_fp()); + touch.x = u32DecFromIstream(fp); + touch.y = u32DecFromIstream(fp); + touch.touch = u32DecFromIstream(fp); fp->fgetc(); //eat the pipe @@ -153,13 +153,13 @@ void MovieRecord::dump(MovieData* md, EMUFILE* fp, int index) //dump the misc commands //*os << '|' << setw(1) << (int)commands; fp->fputc('|'); - putdec(fp->get_fp(),commands); + putdec(fp,commands); fp->fputc('|'); dumpPad(fp, pad); - putdec(fp->get_fp(),touch.x); fp->fputc(' '); - putdec(fp->get_fp(),touch.y); fp->fputc(' '); - putdec(fp->get_fp(),touch.touch); + putdec(fp,touch.x); fp->fputc(' '); + putdec(fp,touch.y); fp->fputc(' '); + putdec(fp,touch.touch); fp->fputc('|'); //each frame is on a new line @@ -276,7 +276,7 @@ bool LoadFM2(MovieData& movieData, EMUFILE* fp, int size, bool stopAfterHeader) //movie must start with "version 1" char buf[9]; curr = fp->ftell(); - fp->fread(buf,9,1); + fp->fread(buf,9); fp->fseek(curr, SEEK_SET); // if(fp->fail()) return false; if(memcmp(buf,"version 1",9)) @@ -444,7 +444,7 @@ const char* _CDECL_ FCEUI_LoadMovie(const char *fname, bool _read_only, bool tas bool loadedfm2 = false; bool opened = false; // { - EMUFILE* fp = new EMUFILE(fname, "rb"); + EMUFILE* fp = new EMUFILE_FILE(fname, "rb"); // if(fs.is_open()) // { loadedfm2 = LoadFM2(currMovieData, fp, INT_MAX, false); @@ -506,7 +506,7 @@ const char* _CDECL_ FCEUI_LoadMovie(const char *fname, bool _read_only, bool tas static void openRecordingMovie(const char* fname) { //osRecordingMovie = FCEUD_UTF8_fstream(fname, "wb"); - osRecordingMovie = new EMUFILE(fname, "wb"); + osRecordingMovie = new EMUFILE_FILE(fname, "wb"); /*if(!osRecordingMovie) FCEU_PrintError("Error opening movie output file: %s",fname);*/ strcpy(curMovieFilename, fname); @@ -665,7 +665,7 @@ void _CDECL_ FCEUI_SaveMovie(const char *fname, std::wstring author, int flag, s input.touch.touchX = mr->touch.x << 4; input.touch.touchY = mr->touch.y << 4; - input.touch.isTouch = mr->touch.touch; + input.touch.isTouch = mr->touch.touch != 0; } //if we are on the last frame, then pause the emulator if the player requested it @@ -766,12 +766,12 @@ void mov_savestate(EMUFILE* fp) //else return 0; if(movieMode == MOVIEMODE_RECORD || movieMode == MOVIEMODE_PLAY) { - write32le(kMOVI,fp->get_fp()); + write32le(kMOVI,fp); currMovieData.dump(fp, true); } else { - write32le(kNOMO,fp->get_fp()); + write32le(kNOMO,fp); } } @@ -784,7 +784,7 @@ bool mov_loadstate(EMUFILE* fp, int size) load_successful = false; u32 cookie; - if(read32le(&cookie,fp->get_fp()) != 1) return false; + if(read32le(&cookie,fp) != 1) return false; if(cookie == kNOMO) return true; else if(cookie != kMOVI) @@ -901,7 +901,7 @@ bool mov_loadstate(EMUFILE* fp, int size) currMovieData.rerecordCount = currRerecordCount; openRecordingMovie(curMovieFilename); - if(!osRecordingMovie->get_fp()) + if(!osRecordingMovie) { osd->setLineColor(255, 0, 0); osd->addLine("Can't save movie file!"); @@ -961,10 +961,10 @@ bool FCEUI_MovieGetInfo(std::istream* fp, MOVIE_INFO& info, bool skipFrameCount) bool MovieRecord::parseBinary(MovieData* md, EMUFILE* fp) { commands=fp->fgetc(); - fp->fread((char *) &pad, sizeof pad,1); - fp->fread((char *) &touch.x, sizeof touch.x,1); - fp->fread((char *) &touch.y, sizeof touch.y,1); - fp->fread((char *) &touch.touch, sizeof touch.touch,1); + fp->fread((char *) &pad, sizeof pad); + fp->fread((char *) &touch.x, sizeof touch.x); + fp->fread((char *) &touch.y, sizeof touch.y); + fp->fread((char *) &touch.touch, sizeof touch.touch); return true; } @@ -972,10 +972,10 @@ bool MovieRecord::parseBinary(MovieData* md, EMUFILE* fp) void MovieRecord::dumpBinary(MovieData* md, EMUFILE* fp, int index) { fp->fputc(md->records[index].commands); - fp->fwrite((char *) &md->records[index].pad, sizeof md->records[index].pad,1); - fp->fwrite((char *) &md->records[index].touch.x, sizeof md->records[index].touch.x,1); - fp->fwrite((char *) &md->records[index].touch.y, sizeof md->records[index].touch.y,1); - fp->fwrite((char *) &md->records[index].touch.touch, sizeof md->records[index].touch.touch,1); + fp->fwrite((char *) &md->records[index].pad, sizeof md->records[index].pad); + fp->fwrite((char *) &md->records[index].touch.x, sizeof md->records[index].touch.x); + fp->fwrite((char *) &md->records[index].touch.y, sizeof md->records[index].touch.y); + fp->fwrite((char *) &md->records[index].touch.touch, sizeof md->records[index].touch.touch); } void LoadFM2_binarychunk(MovieData& movieData, EMUFILE* fp, int size) @@ -1076,7 +1076,7 @@ void FCEUI_MakeBackupMovie(bool dispMessage) } MovieData md = currMovieData; //Get current movie data - EMUFILE* outf = new EMUFILE(backupFn.c_str(),"wb"); //FCEUD_UTF8_fstream(backupFn, "wb"); //open/create file + EMUFILE* outf = new EMUFILE_FILE(backupFn.c_str(),"wb"); //FCEUD_UTF8_fstream(backupFn, "wb"); //open/create file md.dump(outf,false); //dump movie data // delete outf; //clean up, delete file object diff --git a/desmume/src/readwrite.cpp b/desmume/src/readwrite.cpp index 5c2e98ecc..78b8f9653 100644 --- a/desmume/src/readwrite.cpp +++ b/desmume/src/readwrite.cpp @@ -23,71 +23,46 @@ #include "types.h" //well. just for the sake of consistency -int write8le(u8 b, FILE *fp) +int write8le(u8 b, EMUFILE*os) { - return((fwrite(&b,1,1,fp)<1)?0:1); -} - -//well. just for the sake of consistency -int write8le(u8 b, std::ostream *os) -{ - os->write((char*)&b,1); + os->fwrite((char*)&b,1); return 1; } //well. just for the sake of consistency -int read8le(u8 *Bufo, std::istream *is) +int read8le(u8 *Bufo, EMUFILE*is) { - if(is->read((char*)Bufo,1).gcount() != 1) + if(is->_fread((char*)Bufo,1) != 1) return 0; return 1; } ///writes a little endian 16bit value to the specified file -int write16le(u16 b, FILE *fp) +int write16le(u16 b, EMUFILE *fp) { u8 s[2]; s[0]=(u8)b; s[1]=(u8)(b>>8); - return((fwrite(s,1,2,fp)<2)?0:2); -} - - -///writes a little endian 16bit value to the specified file -int write16le(u16 b, std::ostream *os) -{ - u8 s[2]; - s[0]=(u8)b; - s[1]=(u8)(b>>8); - os->write((char*)&s,2); + fp->fwrite(s,2); return 2; } -///writes a little endian 32bit value to the specified file -int write32le(u32 b, FILE *fp) -{ - u8 s[4]; - s[0]=(u8)b; - s[1]=(u8)(b>>8); - s[2]=(u8)(b>>16); - s[3]=(u8)(b>>24); - return((fwrite(s,1,4,fp)<4)?0:4); -} -int write32le(u32 b, std::ostream* os) +///writes a little endian 32bit value to the specified file +int write32le(u32 b, EMUFILE *fp) { u8 s[4]; s[0]=(u8)b; s[1]=(u8)(b>>8); s[2]=(u8)(b>>16); s[3]=(u8)(b>>24); - os->write((char*)&s,4); + fp->fwrite(s,4); return 4; } -void writebool(bool b, std::ostream* os) { write32le(b?1:0,os); } +void writebool(bool b, EMUFILE* os) { write32le(b?1:0,os); } -int write64le(u64 b, std::ostream* os) +int write64le(u64 b, EMUFILE* os) { u8 s[8]; s[0]=(u8)b; @@ -98,16 +73,15 @@ int write64le(u64 b, std::ostream* os) s[5]=(u8)(b>>40); s[6]=(u8)(b>>48); s[7]=(u8)(b>>56); - os->write((char*)&s,8); + os->fwrite((char*)&s,8); return 8; } -///reads a little endian 32bit value from the specified file -int read32le(u32 *Bufo, FILE *fp) +int read32le(u32 *Bufo, EMUFILE *fp) { u32 buf; - if(fread(&buf,1,4,fp)<4) + if(fp->_fread(&buf,4)<4) return 0; #ifdef LOCAL_LE *(u32*)Bufo=buf; @@ -117,10 +91,10 @@ int read32le(u32 *Bufo, FILE *fp) return 1; } -int read16le(u16 *Bufo, std::istream *is) +int read16le(u16 *Bufo, EMUFILE *is) { u16 buf; - if(is->read((char*)&buf,2).gcount() != 2) + if(is->_fread((char*)&buf,2) != 2) return 0; #ifdef LOCAL_LE *Bufo=buf; @@ -130,11 +104,10 @@ int read16le(u16 *Bufo, std::istream *is) return 1; } -///reads a little endian 64bit value from the specified file -int read64le(u64 *Bufo, std::istream *is) +int read64le(u64 *Bufo, EMUFILE *is) { u64 buf; - if(is->read((char*)&buf,8).gcount() != 8) + if(is->_fread((char*)&buf,8) != 8) return 0; #ifdef LOCAL_LE *Bufo=buf; @@ -157,7 +130,7 @@ int read32le(u32 *Bufo, std::istream *is) return 1; } -int readbool(bool *b, std::istream* is) +int readbool(bool *b, EMUFILE* is) { u32 temp; int ret = read32le(&temp,is); @@ -165,19 +138,19 @@ int readbool(bool *b, std::istream* is) return ret; } -int readbuffer(std::vector &vec, std::istream* is) +int readbuffer(std::vector &vec, EMUFILE* is) { u32 size; if(read32le(&size,is) != 1) return 0; vec.resize(size); - if(size>0) is->read((char*)&vec[0],size); + if(size>0) is->fread((char*)&vec[0],size); return 1; } -int writebuffer(std::vector& vec, std::ostream* os) +int writebuffer(std::vector& vec, EMUFILE* os) { u32 size = vec.size(); write32le(size,os); - if(size>0) os->write((char*)&vec[0],size); + if(size>0) os->fwrite((char*)&vec[0],size); return 1; } diff --git a/desmume/src/readwrite.h b/desmume/src/readwrite.h index 6ee2f6225..83b40397c 100644 --- a/desmume/src/readwrite.h +++ b/desmume/src/readwrite.h @@ -1,30 +1,49 @@ + /* 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 _READWRITE_H_ #define _READWRITE_H_ #include "types.h" +#include "emufile.h" #include #include #include //well. just for the sake of consistency -int write8le(u8 b, FILE *fp); -int write8le(u8 b, std::ostream *os); -int write16le(u16 b, FILE *fp); -int write16le(u16 b, std::ostream* os); -int write32le(u32 b, FILE *fp); -int write32le(u32 b, std::ostream* os); -int write64le(u64 b, std::ostream* os); -int read64le(u64 *Bufo, std::istream *is); -int read32le(u32 *Bufo, std::istream *is); -inline int read32le(int *Bufo, std::istream *is) { return read32le((u32*)Bufo,is); } -int read32le(u32 *Bufo, FILE *fp); -int read16le(u16 *Bufo, std::istream *is); -inline int read16le(s16 *Bufo, std::istream* is) { return read16le((u16*)Bufo,is); } -int read8le(u8 *Bufo, std::istream *is); -int readbool(bool *b, std::istream* is); -void writebool(bool b, std::ostream* os); +int write8le(u8 b, EMUFILE *fp); +int write16le(u16 b, EMUFILE* os); +int write32le(u32 b, EMUFILE* os); +int write64le(u64 b, EMUFILE* os); -int readbuffer(std::vector &vec, std::istream* is); -int writebuffer(std::vector& vec, std::ostream* os); +int read8le(u8 *Bufo, EMUFILE*is); +int read16le(u16 *Bufo, EMUFILE*is); +inline int read16le(s16 *Bufo, EMUFILE*is) { return read16le((u16*)Bufo,is); } +int read32le(u32 *Bufo, EMUFILE*is); +inline int read32le(s32 *Bufo, EMUFILE*is) { return read32le((u32*)Bufo,is); } +int read64le(u64 *Bufo, EMUFILE*is); +int read16le(u16 *Bufo, std::istream *is); + +int readbool(bool *b, EMUFILE* is); +void writebool(bool b, EMUFILE* os); + +int readbuffer(std::vector &vec, EMUFILE* is); +int writebuffer(std::vector& vec, EMUFILE* os); #endif diff --git a/desmume/src/saves.cpp b/desmume/src/saves.cpp index 163a2bd48..d3916c2ef 100644 --- a/desmume/src/saves.cpp +++ b/desmume/src/saves.cpp @@ -1,6 +1,7 @@ /* Copyright (C) 2006 Normmatt Copyright (C) 2006 Theo Berkau Copyright (C) 2007 Pascal Giard + Copyright (C) 2008-2009 DeSmuME team This file is part of DeSmuME @@ -263,7 +264,7 @@ SFORMAT SF_MOVIE[]={ { 0 } }; -static void mmu_savestate(std::ostream* os) +static void mmu_savestate(EMUFILE* os) { //version write32le(2,os); @@ -371,10 +372,10 @@ SFORMAT SF_WIFI[]={ { 0 } }; -static bool mmu_loadstate(std::istream* is, int size) +static bool mmu_loadstate(EMUFILE* is, int size) { //read version - int version; + u32 version; if(read32le(&version,is) != 1) return false; if(version == 0 || version == 1) @@ -394,7 +395,7 @@ static bool mmu_loadstate(std::istream* is, int size) else if(version == 1) { //version 1 reinitializes the save system with the type that was saved - int bupmem_type; + u32 bupmem_type; if(read32le(&bupmem_type,is) != 1) return false; if(read32le(&bupmem_size,is) != 1) return false; addr_size = BackupDevice::addr_size_for_old_save_type(bupmem_type); @@ -406,7 +407,7 @@ static bool mmu_loadstate(std::istream* is, int size) return false; u8* temp = new u8[bupmem_size]; - is->read((char*)temp,bupmem_size); + is->fread((char*)temp,bupmem_size); MMU_new.backupDevice.load_old_state(addr_size,temp,bupmem_size); delete[] temp; if(is->fail()) return false; @@ -420,7 +421,7 @@ static bool mmu_loadstate(std::istream* is, int size) return true; } -static void cp15_saveone(armcp15_t *cp15, std::ostream* os) +static void cp15_saveone(armcp15_t *cp15, EMUFILE* os) { write32le(cp15->IDCode,os); write32le(cp15->cacheType,os); @@ -463,7 +464,7 @@ static void cp15_saveone(armcp15_t *cp15, std::ostream* os) for(int i=0;i<8;i++) write32le(cp15->regionExecuteSet_SYS[i],os); } -static void cp15_savestate(std::ostream* os) +static void cp15_savestate(EMUFILE* os) { //version write32le(0,os); @@ -472,7 +473,7 @@ static void cp15_savestate(std::ostream* os) cp15_saveone((armcp15_t *)NDS_ARM7.coproc[15],os); } -static bool cp15_loadone(armcp15_t *cp15, std::istream* is) +static bool cp15_loadone(armcp15_t *cp15, EMUFILE* is) { if(!read32le(&cp15->IDCode,is)) return false; if(!read32le(&cp15->cacheType,is)) return false; @@ -517,10 +518,10 @@ static bool cp15_loadone(armcp15_t *cp15, std::istream* is) return true; } -static bool cp15_loadstate(std::istream* is, int size) +static bool cp15_loadstate(EMUFILE* is, int size) { //read version - int version; + u32 version; if(read32le(&version,is) != 1) return false; if(version != 0) return false; @@ -729,18 +730,18 @@ static const SFORMAT *CheckS(const SFORMAT *guessSF, const SFORMAT *firstSF, u32 } -static bool ReadStateChunk(std::istream* is, const SFORMAT *sf, int size) +static bool ReadStateChunk(EMUFILE* is, const SFORMAT *sf, int size) { const SFORMAT *tmp = NULL; const SFORMAT *guessSF = NULL; - int temp = is->tellg(); + int temp = is->ftell(); - while(is->tellg()ftell()read(toa,4); + is->fread(toa,4); if(is->fail()) return false; @@ -751,15 +752,15 @@ static bool ReadStateChunk(std::istream* is, const SFORMAT *sf, int size) { #ifdef LOCAL_LE // no need to ever loop one at a time if not flipping byte order - is->read((char *)tmp->v,sz*count); + is->fread((char *)tmp->v,sz*count); #else if(sz == 1) { //special case: read a huge byte array - is->read((char *)tmp->v,count); + is->fread((char *)tmp->v,count); } else { for(unsigned int i=0;iread((char *)tmp->v + i*sz,sz); + is->fread((char *)tmp->v + i*sz,sz); FlipByteOrder((u8*)tmp->v + i*sz,sz); } } @@ -768,7 +769,7 @@ static bool ReadStateChunk(std::istream* is, const SFORMAT *sf, int size) } else { - is->seekg(sz*count,std::ios::cur); + is->fseek(sz*count,SEEK_CUR); guessSF = NULL; } } // while(...) @@ -777,7 +778,7 @@ static bool ReadStateChunk(std::istream* is, const SFORMAT *sf, int size) -static int SubWrite(std::ostream* os, const SFORMAT *sf) +static int SubWrite(EMUFILE* os, const SFORMAT *sf) { uint32 acc=0; @@ -816,21 +817,21 @@ static int SubWrite(std::ostream* os, const SFORMAT *sf) if(os) //Are we writing or calculating the size of this block? { - os->write(sf->desc,4); + os->fwrite(sf->desc,4); write32le(sf->size,os); write32le(sf->count,os); #ifdef LOCAL_LE // no need to ever loop one at a time if not flipping byte order - os->write((char *)sf->v,size*count); + os->fwrite((char *)sf->v,size*count); #else if(sz == 1) { //special case: write a huge byte array - os->write((char *)sf->v,count); + os->fwrite((char *)sf->v,1,count); } else { for(int i=0;iv + i*size, size); - os->write((char*)sf->v + i*size,size); + os->fwrite((char*)sf->v + i*size,size); //Now restore the original byte order. FlipByteOrder((u8*)sf->v + i*size, size); } @@ -843,11 +844,11 @@ static int SubWrite(std::ostream* os, const SFORMAT *sf) return(acc); } -static int savestate_WriteChunk(std::ostream* os, int type, const SFORMAT *sf) +static int savestate_WriteChunk(EMUFILE* os, int type, const SFORMAT *sf) { write32le(type,os); if(!sf) return 4; - int bsize = SubWrite((std::ostream*)0,sf); + int bsize = SubWrite((EMUFILE*)0,sf); write32le(bsize,os); if(!SubWrite(os,sf)) @@ -857,9 +858,9 @@ static int savestate_WriteChunk(std::ostream* os, int type, const SFORMAT *sf) return (bsize+8); } -static void savestate_WriteChunk(std::ostream* os, int type, void (*saveproc)(std::ostream* os)) +static void savestate_WriteChunk(EMUFILE* os, int type, void (*saveproc)(EMUFILE* os)) { - u32 pos1 = os->tellp(); + u32 pos1 = os->ftell(); //write the type, size(placeholder), and data write32le(type,os); @@ -867,14 +868,14 @@ static void savestate_WriteChunk(std::ostream* os, int type, void (*saveproc)(st saveproc(os); //get the size - u32 pos2 = os->tellp(); + u32 pos2 = os->ftell(); assert(pos2 != (u32)-1); // if this assert fails, saveproc did something bad u32 size = (pos2 - pos1) - (2 * sizeof(u32)); //fill in the actual size - os->seekp(pos1 + sizeof(u32)); + os->fseek(pos1 + sizeof(u32),SEEK_SET); write32le(size,os); - os->seekp(pos2); + os->fseek(pos2,SEEK_SET); /* // old version of this function, @@ -896,35 +897,32 @@ static void savestate_WriteChunk(std::ostream* os, int type, void (*saveproc)(st */ } -static void writechunks(std::ostream* os); +static void writechunks(EMUFILE* os); -static bool savestate_save(std::ostream* outstream, int compressionLevel) +static bool savestate_save(EMUFILE* outstream, int compressionLevel) { #ifndef HAVE_LIBZ compressionLevel = Z_NO_COMPRESSION; #endif - memorystream ms; - std::ostream* os; + EMUFILE_MEMORY ms; + EMUFILE* os; if(compressionLevel != Z_NO_COMPRESSION) { //generate the savestate in memory first - os = (std::ostream*)&ms; + os = (EMUFILE*)&ms; writechunks(os); - ms.flush(); } else { os = outstream; - os->seekp(32); //skip the header + os->fseek(32,SEEK_SET); //skip the header writechunks(os); } - os->flush(); - //save the length of the file - u32 len = os->tellp(); + u32 len = os->ftell(); u32 comprlen = 0xFFFFFFFF; u8* cbuf; @@ -933,30 +931,29 @@ static bool savestate_save(std::ostream* outstream, int compressionLevel) int error = Z_OK; if(compressionLevel != Z_NO_COMPRESSION) { - cbuf = (u8*)ms.buf(); + cbuf = ms.buf(); uLongf comprlen2; //worst case compression. //zlib says "0.1% larger than sourceLen plus 12 bytes" comprlen = (len>>9)+12 + len; cbuf = new u8[comprlen]; - /* Workaround to make it compile under linux 64bit */ + // Workaround to make it compile under linux 64bit comprlen2 = comprlen; - error = compress2(cbuf,&comprlen2,(u8*)ms.buf(),len,compressionLevel); + error = compress2(cbuf,&comprlen2,ms.buf(),len,compressionLevel); comprlen = (u32)comprlen2; } //dump the header - outstream->seekp(0); - outstream->write(magic,16); + outstream->fseek(0,SEEK_SET); + outstream->fwrite(magic,16); write32le(SAVESTATE_VERSION,outstream); write32le(DESMUME_VERSION_NUMERIC,outstream); //desmume version write32le(len,outstream); //uncompressed length write32le(comprlen,outstream); //compressed length (-1 if it is not compressed) - outstream->flush(); if(compressionLevel != Z_NO_COMPRESSION) { - outstream->write((char*)cbuf,comprlen==(u32)-1?len:comprlen); + outstream->fwrite((char*)cbuf,comprlen==(u32)-1?len:comprlen); delete[] cbuf; } @@ -965,7 +962,7 @@ static bool savestate_save(std::ostream* outstream, int compressionLevel) bool savestate_save (const char *file_name) { - memorystream ms; + EMUFILE_MEMORY ms; size_t elems_written; #ifdef HAVE_LIBZ if(!savestate_save(&ms, Z_DEFAULT_COMPRESSION)) @@ -973,7 +970,6 @@ bool savestate_save (const char *file_name) if(!savestate_save(&ms, 0)) #endif return false; - ms.flush(); FILE* file = fopen(file_name,"wb"); if(file) { @@ -985,7 +981,7 @@ bool savestate_save (const char *file_name) extern SFORMAT SF_RTC[]; -static void writechunks(std::ostream* os) { +static void writechunks(EMUFILE* os) { savestate_WriteChunk(os,1,SF_ARM9); savestate_WriteChunk(os,2,SF_ARM7); savestate_WriteChunk(os,3,cp15_savestate); @@ -1006,7 +1002,7 @@ static void writechunks(std::ostream* os) { savestate_WriteChunk(os,0xFFFFFFFF,(SFORMAT*)0); } -static bool ReadStateChunks(std::istream* is, s32 totalsize) +static bool ReadStateChunks(EMUFILE* is, s32 totalsize) { bool ret = true; while(totalsize > 0) @@ -1075,11 +1071,11 @@ static void loadstate() SetupMMU(nds.debugConsole); } -static bool savestate_load(std::istream* is) +static bool savestate_load(EMUFILE* is) { SAV_silent_fail_flag = false; char header[16]; - is->read(header,16); + is->fread(header,16); if(is->fail() || memcmp(header,magic,16)) return false; @@ -1091,7 +1087,7 @@ static bool savestate_load(std::istream* is) if(ssversion != SAVESTATE_VERSION) return false; - std::vector buf(len); + std::vector buf(len); if(comprlen != 0xFFFFFFFF) { #ifndef HAVE_LIBZ @@ -1099,7 +1095,7 @@ static bool savestate_load(std::istream* is) return false; #endif std::vector cbuf(comprlen); - is->read(&cbuf[0],comprlen); + is->fread(&cbuf[0],comprlen); if(is->fail()) return false; #ifdef HAVE_LIBZ @@ -1109,7 +1105,7 @@ static bool savestate_load(std::istream* is) return false; #endif } else { - is->read((char*)&buf[0],len); + is->fread((char*)&buf[0],len); } //GO!! READ THE SAVESTATE @@ -1133,7 +1129,7 @@ static bool savestate_load(std::istream* is) //gpu3D->NDS_3D_Reset(); //SPU_Reset(); - memorystream mstemp(&buf); + EMUFILE_MEMORY mstemp(&buf); bool x = ReadStateChunks(&mstemp,(s32)len); if(!x && !SAV_silent_fail_flag) @@ -1157,15 +1153,14 @@ static bool savestate_load(std::istream* is) bool savestate_load(const char *file_name) { - std::ifstream f; - f.open(file_name,std::ios_base::binary|std::ios_base::in); - if(!f) return false; + EMUFILE_FILE f(file_name,"rb"); + if(f.fail()) return false; return savestate_load(&f); } -static std::stack rewindFreeList; -static std::vector rewindbuffer; +static std::stack rewindFreeList; +static std::vector rewindbuffer; int rewindstates = 16; int rewindinterval = 4; @@ -1178,21 +1173,17 @@ void rewindsave () { //printf("rewindsave"); printf("%d%s", currFrameCounter, "\n"); - memorystream *ms; + EMUFILE_MEMORY *ms; if(!rewindFreeList.empty()) { ms = rewindFreeList.top(); rewindFreeList.pop(); } else { - ms = new memorystream(); + ms = new EMUFILE_MEMORY(1024*1024*12); } - ms->getStreambuf().expand(1024*1024*12); - if(!savestate_save(ms, Z_NO_COMPRESSION)) return; - ms->sync(); - rewindbuffer.push_back(ms); if((int)rewindbuffer.size() > rewindstates) { @@ -1220,8 +1211,8 @@ void dorewind() printf("%d", size); - memorystream* loadms = rewindbuffer[size-1]; - loadms->seekg(32, std::ios::beg); + EMUFILE_MEMORY* loadms = rewindbuffer[size-1]; + loadms->fseek(32, SEEK_SET); ReadStateChunks(loadms,loadms->size()-32); loadstate(); diff --git a/desmume/src/utils/xstring.h b/desmume/src/utils/xstring.h index 1c24e9e61..59ed48dce 100644 --- a/desmume/src/utils/xstring.h +++ b/desmume/src/utils/xstring.h @@ -1,4 +1,5 @@ -//taken from fceux on 10/27/08 +//taken from fceux on 27-oct-2008 +//subsequently modified for desmume #ifndef _STRINGUTIL_H_ #define _STRINGUTIL_H_ @@ -11,6 +12,7 @@ #include #include "../types.h" +#include "emufile.h" //definitions for str_strip() flags @@ -56,14 +58,14 @@ std::string stditoa(int n); std::string readNullTerminatedAscii(std::istream* is); //extracts a decimal uint from an istream -template T templateIntegerDecFromIstream(std::istream* is) +template T templateIntegerDecFromIstream(EMUFILE* is) { unsigned int ret = 0; bool pre = true; for(;;) { - int c = is->get(); + int c = is->fgetc(); if(c == -1) return ret; int d = c - '0'; if((d<0 || d>9)) @@ -82,11 +84,11 @@ template T templateIntegerDecFromIstream(std::istream* is) return ret; } -inline u32 u32DecFromIstream(std::istream* is) { return templateIntegerDecFromIstream(is); } -inline u64 u64DecFromIstream(std::istream* is) { return templateIntegerDecFromIstream(is); } +inline u32 u32DecFromIstream(EMUFILE* is) { return templateIntegerDecFromIstream(is); } +inline u64 u64DecFromIstream(EMUFILE* is) { return templateIntegerDecFromIstream(is); } //puts an optionally 0-padded decimal integer of type T into the ostream (0-padding is quicker) -template void putdec(std::ostream* os, T dec) +template void putdec(EMUFILE* os, T dec) { char temp[DIGITS]; int ctr = 0; @@ -102,9 +104,9 @@ template void putdec(std::ostream* os, T dec) dec = quot; } if(!PAD) - os->write(temp+DIGITS-ctr-1,ctr+1); + os->fwrite(temp+DIGITS-ctr-1,ctr+1); else - os->write(temp,DIGITS); + os->fwrite(temp,DIGITS); } std::string mass_replace(const std::string &source, const std::string &victim, const std::string &replacement); diff --git a/desmume/src/windows/DeSmuME_2005.vcproj b/desmume/src/windows/DeSmuME_2005.vcproj index e2b909543..c42798eb2 100644 --- a/desmume/src/windows/DeSmuME_2005.vcproj +++ b/desmume/src/windows/DeSmuME_2005.vcproj @@ -1,4 +1,4 @@ - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -1009,7 +1000,7 @@ /> + + + + + diff --git a/desmume/src/windows/mic.cpp b/desmume/src/windows/mic.cpp index 2fbbef14e..3f53a7d0c 100644 --- a/desmume/src/windows/mic.cpp +++ b/desmume/src/windows/mic.cpp @@ -239,27 +239,27 @@ u8 Mic_ReadSample() } // maybe a bit paranoid... -void mic_savestate(std::ostream* os) +void mic_savestate(EMUFILE* os) { //version write32le(0,os); assert(MIC_BUFSIZE == 4096); // else needs new version - os->write((char*)Mic_Buffer[0], MIC_BUFSIZE); - os->write((char*)Mic_Buffer[1], MIC_BUFSIZE); + os->fwrite((char*)Mic_Buffer[0], MIC_BUFSIZE); + os->fwrite((char*)Mic_Buffer[1], MIC_BUFSIZE); write16le(Mic_BufPos,os); write8le(Mic_WriteBuf,os); // seems OK to save... write8le(Mic_PlayBuf,os); write32le(micReadSamplePos,os); } -bool mic_loadstate(std::istream* is, int size) +bool mic_loadstate(EMUFILE* is, int size) { u32 version; if(read32le(&version,is) != 1) return false; - if(version > 0) { is->seekg(size-4, std::ios::cur); return true; } + if(version > 0) { is->fseek(size-4, SEEK_CUR); return true; } - is->read((char*)Mic_Buffer[0], MIC_BUFSIZE); - is->read((char*)Mic_Buffer[1], MIC_BUFSIZE); + is->fread((char*)Mic_Buffer[0], MIC_BUFSIZE); + is->fread((char*)Mic_Buffer[1], MIC_BUFSIZE); read16le(&Mic_BufPos,is); read8le(&Mic_WriteBuf,is); read8le(&Mic_PlayBuf,is); diff --git a/desmume/src/windows/replay.cpp b/desmume/src/windows/replay.cpp index 62bb05ac0..ea0ab6337 100644 --- a/desmume/src/windows/replay.cpp +++ b/desmume/src/windows/replay.cpp @@ -1,3 +1,23 @@ +/* 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 +*/ + + #include #include #include "resource.h" @@ -98,10 +118,10 @@ static char playfilename[MAX_PATH] = ""; void Describe(HWND hwndDlg) { - EMUFILE* fp = new EMUFILE(playfilename,"rb"); + EMUFILE* fp = new EMUFILE_FILE(playfilename,"rb"); MovieData md; LoadFM2(md, fp, INT_MAX, false); - fs.close(); + delete fp; u32 num_frames = md.records.size();