diff --git a/src/GPU.cpp b/src/GPU.cpp index 9ce8c314d..e492a0334 100644 --- a/src/GPU.cpp +++ b/src/GPU.cpp @@ -3127,7 +3127,9 @@ void GPU_ligne(NDS_Screen * screen, u16 l) //SPP level 3-8 rotoscale room //NSMB raster fx backdrops //bubble bobble revolution classic mode - gpu->refreshAffineStartRegs(); + //NOTE: + //I am REALLY unsatisfied with this logic now. But it seems to be working.. + gpu->refreshAffineStartRegs(-1,-1); } //cache some parameters which are assumed to be stable throughout the rendering of the entire line @@ -3212,7 +3214,7 @@ void GPU_ligne(NDS_Screen * screen, u16 l) void gpu_savestate(std::ostream* os) { //version - write32le(0,os); + write32le(1,os); os->write((char*)GPU_screen,sizeof(GPU_screen)); @@ -3230,21 +3232,37 @@ bool gpu_loadstate(std::istream* is, int size) { //read version int version; - if(read32le(&version,is) != 1) return false; - if(version != 0) return false; + + //sigh.. shouldve used a new version number + if(size == 256*192*2*2) + version = 0; + else if(size== 0x30024) + { + read32le(&version,is); + version = 1; + } + else + if(read32le(&version,is) != 1) return false; + + + if(version<0||version>1) return false; is->read((char*)GPU_screen,sizeof(GPU_screen)); - read32le(&MainScreen.gpu->affineInfo[0].x,is); - read32le(&MainScreen.gpu->affineInfo[0].y,is); - read32le(&MainScreen.gpu->affineInfo[1].x,is); - read32le(&MainScreen.gpu->affineInfo[1].y,is); - read32le(&SubScreen.gpu->affineInfo[0].x,is); - read32le(&SubScreen.gpu->affineInfo[0].y,is); - read32le(&SubScreen.gpu->affineInfo[1].x,is); - read32le(&SubScreen.gpu->affineInfo[1].y,is); - MainScreen.gpu->refreshAffineStartRegs(); - SubScreen.gpu->refreshAffineStartRegs(); + if(version==1) + { + read32le(&MainScreen.gpu->affineInfo[0].x,is); + read32le(&MainScreen.gpu->affineInfo[0].y,is); + read32le(&MainScreen.gpu->affineInfo[1].x,is); + read32le(&MainScreen.gpu->affineInfo[1].y,is); + read32le(&SubScreen.gpu->affineInfo[0].x,is); + read32le(&SubScreen.gpu->affineInfo[0].y,is); + read32le(&SubScreen.gpu->affineInfo[1].x,is); + read32le(&SubScreen.gpu->affineInfo[1].y,is); + MainScreen.gpu->refreshAffineStartRegs(-1,-1); + SubScreen.gpu->refreshAffineStartRegs(-1,-1); + } + MainScreen.gpu->updateBLDALPHA(); SubScreen.gpu->updateBLDALPHA(); return !is->fail(); @@ -3268,22 +3286,35 @@ void GPU::setAffineStart(int layer, int xy, u32 val) { if(xy==0) affineInfo[layer-2].x = val; else affineInfo[layer-2].y = val; - refreshAffineStartRegs(); + refreshAffineStartRegs(layer,xy); } -void GPU::refreshAffineStartRegs() +void GPU::refreshAffineStartRegs(const int num, const int xy) { - for(int num=2;num<=3;num++) + if(num==-1) { - BGxPARMS * parms; - if (num==2) - parms = &(dispx_st)->dispx_BG2PARMS; - else - parms = &(dispx_st)->dispx_BG3PARMS; - - parms->BGxX = affineInfo[num-2].x; - parms->BGxY = affineInfo[num-2].y; + refreshAffineStartRegs(2,xy); + refreshAffineStartRegs(3,xy); + return; } + + if(xy==-1) + { + refreshAffineStartRegs(num,0); + refreshAffineStartRegs(num,1); + return; + } + + BGxPARMS * parms; + if (num==2) + parms = &(dispx_st)->dispx_BG2PARMS; + else + parms = &(dispx_st)->dispx_BG3PARMS; + + if(xy==0) + parms->BGxX = affineInfo[num-2].x; + else + parms->BGxY = affineInfo[num-2].y; } void gpu_UpdateRender() diff --git a/src/GPU.h b/src/GPU.h index c4279a39d..f77b8ba7e 100644 --- a/src/GPU.h +++ b/src/GPU.h @@ -775,7 +775,7 @@ struct GPU void setAffineStart(int layer, int xy, u32 val); void setAffineStartWord(int layer, int xy, u16 val, int word); u32 getAffineStart(int layer, int xy); - void refreshAffineStartRegs(); + void refreshAffineStartRegs(const int num, const int xy); struct AffineInfo { AffineInfo() : x(0), y(0) {} diff --git a/src/NDSSystem.cpp b/src/NDSSystem.cpp index f8f1fb1ed..c43718e45 100644 --- a/src/NDSSystem.cpp +++ b/src/NDSSystem.cpp @@ -845,7 +845,10 @@ int NDS_LoadROM( const char *filename, int bmtype, u32 bmsize, return ret; } -void MovieSRAM(int bmtype, u32 bmsize) { +void MovieSRAM() +{ + int bmtype = MMU.bupmem.type; + u32 bmsize = MMU.bupmem.size; char buf[MAX_PATH]; @@ -859,7 +862,6 @@ void MovieSRAM(int bmtype, u32 bmsize) { mc_realloc(&MMU.bupmem, bmtype, bmsize); mc_load_file(&MMU.bupmem, buf); - } void NDS_FreeROM(void) @@ -882,6 +884,12 @@ void NDS_Reset( void) if (!header) return ; + if (MMU.bupmem.fp) + { + fclose(MMU.bupmem.fp); + MMU.bupmem.fp = NULL; + } + lagframecounter=0; LagFrameFlag=0; lastLag=0; diff --git a/src/NDSSystem.h b/src/NDSSystem.h index 83fca58e3..6be3edd1d 100644 --- a/src/NDSSystem.h +++ b/src/NDSSystem.h @@ -385,6 +385,7 @@ public: virtual BOOL WIFI_Host_InitSystem() { return FALSE; } virtual void WIFI_Host_ShutdownSystem() {} virtual BOOL AVI_IsRecording() { return FALSE; } + virtual void USR_InfoMessage(const char *message) { printf("%s\n", message); } }; extern Driver* driver; @@ -392,7 +393,7 @@ extern std::string InputDisplayString; extern int LagFrameFlag; extern int lastLag, TotalLagFrames; -void MovieSRAM(int bmtype, u32 bmsize); +void MovieSRAM(); void ClearAutoHold(void); diff --git a/src/cocoa/sndOSX.mm b/src/cocoa/sndOSX.mm index 112b274b9..43beb47a9 100644 --- a/src/cocoa/sndOSX.mm +++ b/src/cocoa/sndOSX.mm @@ -26,7 +26,7 @@ #include #include -#include +#include //desmume includes #define OBJ_C diff --git a/src/ctrlssdl.cpp b/src/ctrlssdl.cpp index d14436b5d..a07a8757a 100644 --- a/src/ctrlssdl.cpp +++ b/src/ctrlssdl.cpp @@ -292,8 +292,15 @@ void set_mouse_coord(signed long x,signed long y) /* Update NDS keypad */ void update_keypad(u16 keys) { +#ifdef WORDS_BIGENDIAN + ARM9Mem.ARM9_REG[0x130] = ~keys & 0xFF; + ARM9Mem.ARM9_REG[0x131] = (~keys >> 8) & 0x3; + MMU.ARM7_REG[0x130] = ~keys & 0xFF; + MMU.ARM7_REG[0x131] = (~keys >> 8) & 0x3; +#else ((u16 *)ARM9Mem.ARM9_REG)[0x130>>1] = ~keys & 0x3FF; ((u16 *)MMU.ARM7_REG)[0x130>>1] = ~keys & 0x3FF; +#endif /* Update X and Y buttons */ MMU.ARM7_REG[0x136] = ( ~( keys >> 10) & 0x3 ) | (MMU.ARM7_REG[0x136] & ~0x3); } @@ -304,7 +311,11 @@ u16 get_keypad( void) u16 keypad; keypad = ~MMU.ARM7_REG[0x136]; keypad = (keypad & 0x3) << 10; +#ifdef WORDS_BIGENDIAN + keypad |= ~(ARM9Mem.ARM9_REG[0x130] | (ARM9Mem.ARM9_REG[0x131] << 8)) & 0x3FF; +#else keypad |= ~((u16 *)ARM9Mem.ARM9_REG)[0x130>>1] & 0x3FF; +#endif return keypad; } diff --git a/src/gfx3d.cpp b/src/gfx3d.cpp index a924df224..c0f42dce6 100644 --- a/src/gfx3d.cpp +++ b/src/gfx3d.cpp @@ -28,6 +28,7 @@ #include #include #include +#include #include "armcpu.h" #include "debug.h" #include "gfx3d.h" @@ -2364,4 +2365,4 @@ bool gfx3d_loadstate(std::istream* is, int size) gfx3d.vertlist->count=0; return true; -} \ No newline at end of file +} diff --git a/src/mc.cpp b/src/mc.cpp index 69af93a48..abccf08b9 100644 --- a/src/mc.cpp +++ b/src/mc.cpp @@ -82,6 +82,7 @@ u8 *mc_alloc(memory_chip_t *mc, u32 size) { u8 *buffer; buffer = new u8[size]; + memset(buffer,0,size); mc->data = buffer; if(!buffer) { return NULL; } @@ -199,9 +200,9 @@ void mc_reset_com(memory_chip_t *mc) void mc_realloc(memory_chip_t *mc, int type, u32 size) { - if(mc->data) delete[] mc->data; - mc_init(mc, type); - mc_alloc(mc, size); + if(mc->data) delete[] mc->data; + mc_init(mc, type); + mc_alloc(mc, size); } void mc_load_file(memory_chip_t *mc, const char* filename) @@ -213,7 +214,7 @@ void mc_load_file(memory_chip_t *mc, const char* filename) if(movieMode != MOVIEMODE_INACTIVE) { mc->filename = strdup(filename); - return; + return; } else file = fopen(filename, "rb+"); diff --git a/src/movie.cpp b/src/movie.cpp index 471301658..e4dd0ab88 100644 --- a/src/movie.cpp +++ b/src/movie.cpp @@ -22,7 +22,6 @@ #include #include #include -#include "main.h" #include "utils/guid.h" #include "utils/xstring.h" #include "movie.h" @@ -355,7 +354,7 @@ static void closeRecordingMovie() /// Stop movie playback. static void StopPlayback() { - SetMessageToDisplay("Movie playback stopped."); + driver->USR_InfoMessage("Movie playback stopped."); movieMode = MOVIEMODE_INACTIVE; } @@ -363,7 +362,7 @@ static void StopPlayback() /// Stop movie recording static void StopRecording() { - SetMessageToDisplay("Movie recording stopped."); + driver->USR_InfoMessage("Movie recording stopped."); movieMode = MOVIEMODE_INACTIVE; closeRecordingMovie(); @@ -436,14 +435,14 @@ void FCEUI_LoadMovie(const char *fname, bool _read_only, bool tasedit, int _paus movieMode = MOVIEMODE_PLAY; currRerecordCount = currMovieData.rerecordCount; InitMovieTime(); - MovieSRAM(backupmemorytype, backupmemorysize); + MovieSRAM(); freshMovie = true; ClearAutoHold(); if(movie_readonly) - SetMessageToDisplay("Replay started Read-Only."); + driver->USR_InfoMessage("Replay started Read-Only."); else - SetMessageToDisplay("Replay started Read+Write."); + driver->USR_InfoMessage("Replay started Read+Write."); } static void openRecordingMovie(const char* fname) @@ -492,9 +491,9 @@ static void openRecordingMovie(const char* fname) movie_readonly = false; currRerecordCount = 0; InitMovieTime(); - MovieSRAM(backupmemorytype, backupmemorysize); - - SetMessageToDisplay("Movie recording started."); + MovieSRAM(); + + driver->USR_InfoMessage("Movie recording started."); } void NDS_setTouchFromMovie(void) { @@ -609,6 +608,9 @@ static void FCEUMOV_AddCommand(int cmd) //DoEncode((cmd>>3)&0x3,cmd&0x7,1); } +//little endian 4-byte cookies +static const int kMOVI = 0x49564F4D; +static const int kNOMO = 0x4F4D4F4E; void mov_savestate(std::ostream* os) { @@ -618,12 +620,12 @@ void mov_savestate(std::ostream* os) //else return 0; if(movieMode == MOVIEMODE_RECORD || movieMode == MOVIEMODE_PLAY) { - write32le('MOVI',os); + write32le(kMOVI,os); currMovieData.dump(os, true); } else { - write32le('NOMO',os); + write32le(kNOMO,os); } } @@ -637,9 +639,9 @@ bool mov_loadstate(std::istream* is, int size) int cookie; if(read32le(&cookie,is) != 1) return false; - if(cookie == 'NOMO') + if(cookie == kNOMO) return true; - else if(cookie != 'MOVI') + else if(cookie != kMOVI) return false; size -= 4; @@ -851,7 +853,7 @@ void LoadFM2_binarychunk(MovieData& movieData, std::istream* fp, int size) #include -bool CheckFileExists(const char* filename) +static bool CheckFileExists(const char* filename) { //This function simply checks to see if the given filename exists string checkFilename; diff --git a/src/rasterize.cpp b/src/rasterize.cpp index d04e1468c..f5fd52982 100644 --- a/src/rasterize.cpp +++ b/src/rasterize.cpp @@ -1145,6 +1145,7 @@ static void SoftRastRender() { Fragment clearFragment; FragmentColor clearFragmentColor; + clearFragment.pad = 0; clearFragmentColor.r = gfx3d.clearColor&0x1F; clearFragmentColor.g = (gfx3d.clearColor>>5)&0x1F; clearFragmentColor.b = (gfx3d.clearColor>>10)&0x1F; diff --git a/src/saves.cpp b/src/saves.cpp index 5255144a8..084993354 100644 --- a/src/saves.cpp +++ b/src/saves.cpp @@ -37,7 +37,9 @@ #include "readwrite.h" #include "gfx3d.h" #include "movie.h" +#ifdef _MSC_VER #include "windows/main.h" +#endif //void*v is actually a void** which will be indirected before reading @@ -49,6 +51,9 @@ savestates_t savestates[NB_STATES]; #define SAVESTATE_VERSION 11 static const char* magic = "DeSmuME SState\0"; +//a savestate chunk loader can set this if it wants to permit a silent failure (for compatibility) +static bool SAV_silent_fail_flag; + #ifndef MAX_PATH #define MAX_PATH 256 #endif @@ -145,7 +150,9 @@ SFORMAT SF_MEM[]={ { "VMEM", 1, sizeof(ARM9Mem.ARM9_VMEM), ARM9Mem.ARM9_VMEM}, { "OAMS", 1, sizeof(ARM9Mem.ARM9_OAM), ARM9Mem.ARM9_OAM}, - { "LCDM", 1, sizeof(ARM9Mem.ARM9_LCD), ARM9Mem.ARM9_LCD}, + + //this size is specially chosen to avoid saving the blank space at the end + { "LCDM", 1, 0xA4000, ARM9Mem.ARM9_LCD}, { 0 } }; @@ -248,7 +255,7 @@ SFORMAT SF_MOVIE[]={ static void mmu_savestate(std::ostream* os) { //version - write32le(0,os); + write32le(1,os); write32le(MMU.bupmem.type,os); write32le(MMU.bupmem.size,os); @@ -260,14 +267,27 @@ static bool mmu_loadstate(std::istream* is, int size) //read version int version; if(read32le(&version,is) != 1) return false; - if(version != 0) return false; - - int bupmem_type; - u32 bupmem_size; - if(read32le(&bupmem_type,is) != 1) return false; - if(read32le(&bupmem_size,is) != 1) return false; - mc_realloc(&MMU.bupmem,bupmem_type,bupmem_size); + + u32 bupmem_size; + + if(version == 0) + { + //version 0 was buggy and didnt save the type. + //it would silently fail if there was a size mismatch + SAV_silent_fail_flag = true; + if(read32le(&bupmem_size,is) != 1) return false; + //if(bupmem_size != MMU.bupmem.size) return false; //mismatch between current initialized and saved size + mc_realloc(&MMU.bupmem,MC_TYPE_AUTODETECT,bupmem_size); + } + else + { + //version 1 reinitializes the save system with the type that was saved + int bupmem_type; + if(read32le(&bupmem_type,is) != 1) return false; + if(read32le(&bupmem_size,is) != 1) return false; + mc_realloc(&MMU.bupmem,bupmem_type,bupmem_size); + } is->read((char*)MMU.bupmem.data,bupmem_size); if(is->fail()) return false; @@ -593,7 +613,7 @@ static int SubWrite(std::ostream* os, SFORMAT *sf) int size = sf->size; //add size of current node to the accumulator - acc += sizeof(sf->desc) + sizeof(sf->size) + sizeof(sf->count); + acc += 4 + sizeof(sf->size) + sizeof(sf->count); acc += count * size; if(os) //Are we writing or calculating the size of this block? @@ -668,16 +688,6 @@ static bool savestate_save(std::ostream* outstream, int compressionLevel) writechunks(os); ms.flush(); - for(int i=0x2000;i<0x1000000;i++) - if(ARM9Mem.ARM9_REG[i] != 0) { - MessageBox(0,"Debug check fail: ARM9Mem.ARM9_REG",0,0); - } - - for(int i=0;i<0x20000;i++) - if(ARM9Mem.blank_memory[i] != 0) { - MessageBox(0,"Debug check fail: ARM9Mem.blank_memory",0,0); - } - //save the length of the file u32 len = ms.size(); @@ -737,8 +747,6 @@ bool savestate_save (const char *file_name) } else return false; } -//u8 GPU_screen[4*256*192]; - static void writechunks(std::ostream* os) { savestate_WriteChunk(os,1,SF_ARM9); savestate_WriteChunk(os,2,SF_ARM7); @@ -812,6 +820,7 @@ static void loadstate() static bool savestate_load(std::istream* is) { + SAV_silent_fail_flag = false; char header[16]; is->read(header,16); if(is->fail() || memcmp(header,magic,16)) @@ -867,10 +876,11 @@ static bool savestate_load(std::istream* is) memorystream mstemp(&buf); bool x = ReadStateChunks(&mstemp,(s32)len); - if(!x) + if(!x && !SAV_silent_fail_flag) { printf("Error loading savestate. It failed halfway through;\nSince there is no savestate backup system, your current game session is wrecked"); #ifdef _MSC_VER + //HACK! we really need a better way to handle this kind of feedback MessageBox(0,"Error loading savestate. It failed halfway through;\nSince there is no savestate backup system, your current game session is wrecked",0,0); #endif return false; diff --git a/src/windows/main.cpp b/src/windows/main.cpp index cf4852234..709b4e927 100644 --- a/src/windows/main.cpp +++ b/src/windows/main.cpp @@ -1464,6 +1464,11 @@ class WinDriver : public Driver { return ::AVI_IsRecording(); } + + virtual void USR_InfoMessage(const char *message) + { + SetMessageToDisplay(message); + } }; int WINAPI WinMain (HINSTANCE hThisInstance, diff --git a/src/windows/ram_search.cpp b/src/windows/ram_search.cpp index 16daf0c25..ad40237c6 100644 --- a/src/windows/ram_search.cpp +++ b/src/windows/ram_search.cpp @@ -71,7 +71,7 @@ static BOOL s_itemIndicesInvalid = true; // if true, the link from listbox items static BOOL s_prevValuesNeedUpdate = true; // if true, the "prev" values should be updated using the "cur" values on the next frame update signaled static unsigned int s_maxItemIndex = 0; // max currently valid item index, the listbox sometimes tries to update things past the end of the list so we need to know this to ignore those attempts -static const MemoryRegion s_prgRegion = { 0x02000000, 0x400000, (unsigned char*)ARM9Mem.MAIN_MEM, true}; +static const MemoryRegion s_prgRegion = { 0x02000000, 0x400000, (unsigned char*)ARM9Mem.MAIN_MEM, false}; /* static const MemoryRegion s_prgRegion = { 0x020000, SEGACD_RAM_PRG_SIZE, (unsigned char*)Ram_Prg, true}; diff --git a/src/windows/targetver.h b/src/windows/targetver.h deleted file mode 100644 index f583181df..000000000 --- a/src/windows/targetver.h +++ /dev/null @@ -1,24 +0,0 @@ -#pragma once - -// The following macros define the minimum required platform. The minimum required platform -// is the earliest version of Windows, Internet Explorer etc. that has the necessary features to run -// your application. The macros work by enabling all features available on platform versions up to and -// including the version specified. - -// Modify the following defines if you have to target a platform prior to the ones specified below. -// Refer to MSDN for the latest info on corresponding values for different platforms. -#ifndef WINVER // Specifies that the minimum required platform is Windows Vista. -#define WINVER 0x0600 // Change this to the appropriate value to target other versions of Windows. -#endif - -#ifndef _WIN32_WINNT // Specifies that the minimum required platform is Windows Vista. -#define _WIN32_WINNT 0x0600 // Change this to the appropriate value to target other versions of Windows. -#endif - -#ifndef _WIN32_WINDOWS // Specifies that the minimum required platform is Windows 98. -#define _WIN32_WINDOWS 0x0410 // Change this to the appropriate value to target Windows Me or later. -#endif - -#ifndef _WIN32_IE // Specifies that the minimum required platform is Internet Explorer 7.0. -#define _WIN32_IE 0x0700 // Change this to the appropriate value to target other versions of IE. -#endif