diff --git a/desmume/src/addons/slot1_retail_auto.cpp b/desmume/src/addons/slot1_retail_auto.cpp index 6333495ff..b3ad5215f 100644 --- a/desmume/src/addons/slot1_retail_auto.cpp +++ b/desmume/src/addons/slot1_retail_auto.cpp @@ -48,10 +48,10 @@ public: ) selection = NDS_SLOT1_RETAIL_NAND; + slot1_selected_type = selection; mSelectedImplementation = slot1_List[selection]; mSelectedImplementation->connect(); printf("Slot1 auto-selected device type: %s\n",mSelectedImplementation->info()->name()); - slot1_selected_id = selection; } virtual void disconnect() diff --git a/desmume/src/addons/slot2_auto.cpp b/desmume/src/addons/slot2_auto.cpp index 1e0579f1f..75568e032 100644 --- a/desmume/src/addons/slot2_auto.cpp +++ b/desmume/src/addons/slot2_auto.cpp @@ -76,11 +76,11 @@ public: if (gameInfo.isHomebrew()) selection = NDS_SLOT2_PASSME; + slot2_selected_type = selection; mSelectedImplementation = slot2_List[selection]; mSelectedImplementation->connect(); - printf("Slot2 auto-selected device type: %s\n", mSelectedImplementation->info()->name()); - slot2_selected_id = selection; - + printf("Slot2 auto-selected device type: %s (0x%02X)\n", mSelectedImplementation->info()->name(), mSelectedImplementation->info()->id()); + #ifdef HOST_WINDOWS Guitar.Enabled = (selection == NDS_SLOT2_GUITARGRIP)?true:false; Piano.Enabled = (selection == NDS_SLOT2_EASYPIANO)?true:false; diff --git a/desmume/src/saves.cpp b/desmume/src/saves.cpp index 2bd8fa484..0f65d6962 100644 --- a/desmume/src/saves.cpp +++ b/desmume/src/saves.cpp @@ -43,6 +43,7 @@ #include "MMU_timing.h" #include "slot1.h" #include "slot2.h" +#include "svnrev.h" #include "path.h" @@ -56,6 +57,16 @@ int lastSaveState = 0; //Keeps track of last savestate used for quick save/load //since this isnt supported right now, it is declared in here to make things compile #define SS_INDIRECT 0x80000000 +u32 _DESMUME_version = EMU_DESMUME_VERSION_NUMERIC(); +#ifdef SVN_REV +#define _SVN_REV SVN_REV +#else +#define _SVN_REV 0 +#endif + +u32 svn_rev = _SVN_REV; +s64 save_time = 0; + savestates_t savestates[NB_STATES]; #define SAVESTATE_VERSION 12 @@ -64,9 +75,14 @@ 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; -SFORMAT SF_NDS_HEADER[]={ +SFORMAT SF_NDS_INFO[]={ { "GINF", 1, sizeof(gameInfo.header), &gameInfo.header}, { "GRSZ", 1, 4, &gameInfo.romsize}, + { "DVMJ", 1, 1, (void*)&DESMUME_VERSION_MAJOR}, + { "DVMI", 1, 1, (void*)&DESMUME_VERSION_MINOR}, + { "DSBD", 1, 1, (void*)&DESMUME_VERSION_BUILD}, + { "GREV", 1, 4, &svn_rev}, + { "GTIM", 1, 8, &save_time}, { 0 } }; @@ -393,7 +409,7 @@ static void s_slot1_savestate(EMUFILE* os) u32 version = 1; os->write32le(version); - u8 slotID = (u8)slot1_List[slot1_GetCurrentType()]->info()->id(); + u8 slotID = (u8)slot1_List[slot1_GetSelectedType()]->info()->id(); os->write32le(slotID); EMUFILE_MEMORY temp; @@ -412,7 +428,6 @@ static bool s_slot2_loadstate(EMUFILE* is, int size) u8 slotID = is->read32le(); if (version == 0) slot2_getTypeByID(slotID, slotType); - slot2_Change(slotType); EMUFILE_MEMORY temp; @@ -429,7 +444,8 @@ static void s_slot2_savestate(EMUFILE* os) u32 version = 0; os->write32le(version); - u8 slotID = (u8)slot2_List[slot2_GetCurrentType()]->info()->id(); + //version 0: + u8 slotID = (u8)slot2_List[slot2_GetSelectedType()]->info()->id(); os->write32le(slotID); EMUFILE_MEMORY temp; @@ -1007,6 +1023,16 @@ bool savestate_save (const char *file_name) } static void writechunks(EMUFILE* os) { + + DateTime tm = DateTime::get_Now(); +#ifdef PUBLIC_RELEASE + svn_rev = 0xFFFFFFFF; +#else + svn_rev = _SVN_REV; +#endif + + save_time = tm.get_Ticks(); + savestate_WriteChunk(os,1,SF_ARM9); savestate_WriteChunk(os,2,SF_ARM7); savestate_WriteChunk(os,3,cp15_savestate); @@ -1024,7 +1050,7 @@ static void writechunks(EMUFILE* os) { savestate_WriteChunk(os,101,mov_savestate); savestate_WriteChunk(os,110,SF_WIFI); savestate_WriteChunk(os,120,SF_RTC); - savestate_WriteChunk(os,130,SF_NDS_HEADER); + savestate_WriteChunk(os,130,SF_NDS_INFO); savestate_WriteChunk(os,140,s_slot1_savestate); savestate_WriteChunk(os,150,s_slot2_savestate); // reserved for future versions @@ -1040,11 +1066,21 @@ static bool ReadStateChunks(EMUFILE* is, s32 totalsize) bool ret = true; bool haveInfo = false; + s64 save_time = 0; u32 romsize = 0; + u8 version_major = 0; + u8 version_minor = 0; + u8 version_build = 0; + NDS_header header; - SFORMAT SF_HEADER[]={ + SFORMAT SF_INFO[]={ { "GINF", 1, sizeof(header), &header}, { "GRSZ", 1, 4, &romsize}, + { "DVMJ", 1, 1, &version_major}, + { "DVMI", 1, 1, &version_minor}, + { "DSBD", 1, 1, &version_build}, + { "GREV", 1, 4, &svn_rev}, + { "GTIM", 1, 8, &save_time}, { 0 } }; memset(&header, 0, sizeof(header)); @@ -1075,7 +1111,7 @@ static bool ReadStateChunks(EMUFILE* is, s32 totalsize) case 101: if(!mov_loadstate(is, size)) ret=false; break; case 110: if(!ReadStateChunk(is,SF_WIFI,size)) ret=false; break; case 120: if(!ReadStateChunk(is,SF_RTC,size)) ret=false; break; - case 130: if(!ReadStateChunk(is,SF_HEADER,size)) ret=false; else haveInfo=true; break; + case 130: if(!ReadStateChunk(is,SF_INFO,size)) ret=false; else haveInfo=true; break; case 140: if(!s_slot1_loadstate(is, size)) ret=false; break; case 150: if(!s_slot2_loadstate(is, size)) ret=false; break; // reserved for future versions @@ -1099,6 +1135,20 @@ static bool ReadStateChunks(EMUFILE* is, s32 totalsize) memset(&buf[0], 0, sizeof(buf)); memcpy(buf, header.gameTile, sizeof(header.gameTile)); printf("Savestate info:\n"); + if (version_major | version_minor | version_build) + { + char buf[32] = {0}; + if (svn_rev != 0xFFFFFFFF) + sprintf(buf, " svn %u", svn_rev); + printf("\tDeSmuME version: %u.%u.%u%s\n", version_major, version_minor, version_build, buf); + } + + if (save_time) + { + static const char *wday[] = { "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" }; + DateTime tm = save_time; + printf("\tSave created: %04d-%03s-%02d %s %02d:%02d:%02d\n", tm.get_Year(), DateTime::GetNameOfMonth(tm.get_Month()), tm.get_Day(), wday[tm.get_DayOfWeek()%7], tm.get_Hour(), tm.get_Minute(), tm.get_Second()); + } printf("\tGame title: %s\n", buf); printf("\tGame code: %c%c%c%c\n", header.gameCode[3], header.gameCode[2], header.gameCode[1], header.gameCode[0]); printf("\tMaker code: %c%c (0x%04X) - %s\n", header.makerCode & 0xFF, header.makerCode >> 8, header.makerCode, getDeveloperNameByID(header.makerCode).c_str()); @@ -1153,9 +1203,9 @@ bool savestate_load(EMUFILE* is) if(is->fail() || memcmp(header,magic,16)) return false; - u32 ssversion,dversion,len,comprlen; + u32 ssversion,len,comprlen; if(!read32le(&ssversion,is)) return false; - if(!read32le(&dversion,is)) return false; + if(!read32le(&_DESMUME_version,is)) return false; if(!read32le(&len,is)) return false; if(!read32le(&comprlen,is)) return false; diff --git a/desmume/src/slot1.cpp b/desmume/src/slot1.cpp index 7403c5cd0..61987bf69 100644 --- a/desmume/src/slot1.cpp +++ b/desmume/src/slot1.cpp @@ -36,8 +36,6 @@ Since GCROMCTRL[26:24] can't represent 'data block size' of 1 or 2, it is assume #include "utils/vfat.h" #include "path.h" -NDS_SLOT1_TYPE slot1_selected_id = NDS_SLOT1_NONE; - bool slot1_R4_path_type = false; //------- @@ -87,6 +85,7 @@ ISlot1Interface* slot1_List[NDS_SLOT1_COUNT] = {0}; ISlot1Interface* slot1_device = NULL; NDS_SLOT1_TYPE slot1_device_type = NDS_SLOT1_RETAIL_AUTO; //default for frontends that dont even configure this +NDS_SLOT1_TYPE slot1_selected_type = NDS_SLOT1_NONE; void slot1_Init() @@ -153,7 +152,8 @@ void slot1_Reset() bool slot1_Change(NDS_SLOT1_TYPE changeToType) { - if(changeToType == slot1_device_type) return FALSE; //nothing to do + if((changeToType == slot1_device_type) || (changeToType == slot1_GetSelectedType())) + return FALSE; //nothing to do if (changeToType > NDS_SLOT1_COUNT || changeToType < 0) return FALSE; if(slot1_device != NULL) slot1_device->disconnect(); @@ -194,7 +194,7 @@ NDS_SLOT1_TYPE slot1_GetCurrentType() NDS_SLOT1_TYPE slot1_GetSelectedType() { if (slot1_device_type == NDS_SLOT1_RETAIL_AUTO) - return slot1_selected_id; + return slot1_selected_type; return slot1_device_type; } diff --git a/desmume/src/slot1.h b/desmume/src/slot1.h index 0337a970b..04266570e 100644 --- a/desmume/src/slot1.h +++ b/desmume/src/slot1.h @@ -108,7 +108,7 @@ enum NDS_SLOT1_TYPE extern ISlot1Interface* slot1_device; //the current slot1 device instance extern ISlot1Interface* slot1_List[NDS_SLOT1_COUNT]; -extern NDS_SLOT1_TYPE slot1_selected_id; +extern NDS_SLOT1_TYPE slot1_selected_type; void slot1_Init(); bool slot1_Connect(); diff --git a/desmume/src/slot2.cpp b/desmume/src/slot2.cpp index eb5639336..96230925e 100644 --- a/desmume/src/slot2.cpp +++ b/desmume/src/slot2.cpp @@ -19,8 +19,6 @@ #include "mem.h" #include "MMU.h" -NDS_SLOT2_TYPE slot2_selected_id = NDS_SLOT2_NONE; - //this is the currently-configured cflash mode ADDON_CFLASH_MODE CFlash_Mode = ADDON_CFLASH_MODE_RomPath; @@ -34,7 +32,8 @@ char GBAgameName[MAX_PATH] = {0}; ISlot2Interface* slot2_List[NDS_SLOT2_COUNT] = {0}; ISlot2Interface* slot2_device = NULL; -NDS_SLOT2_TYPE slot2_device_type = NDS_SLOT2_NONE; +NDS_SLOT2_TYPE slot2_device_type = NDS_SLOT2_AUTO; +NDS_SLOT2_TYPE slot2_selected_type = NDS_SLOT2_NONE; void slot2_Init() @@ -103,7 +102,7 @@ void slot2_Reset() bool slot2_Change(NDS_SLOT2_TYPE changeToType) { - if(changeToType == slot2_device_type) + if((changeToType == slot2_device_type) || (changeToType == slot2_GetSelectedType())) return FALSE; //nothing to do if (changeToType > NDS_SLOT2_COUNT || changeToType < 0) return FALSE; @@ -142,10 +141,10 @@ NDS_SLOT2_TYPE slot2_GetCurrentType() return slot2_device_type; } -NDS_SLOT2_TYPE slot2_GetSelectetType() +NDS_SLOT2_TYPE slot2_GetSelectedType() { if (slot2_device_type == NDS_SLOT2_AUTO) - return slot2_selected_id; + return slot2_selected_type; return slot2_device_type; } diff --git a/desmume/src/slot2.h b/desmume/src/slot2.h index 053ac28db..6ae98dc61 100644 --- a/desmume/src/slot2.h +++ b/desmume/src/slot2.h @@ -97,7 +97,7 @@ enum NDS_SLOT2_TYPE extern ISlot2Interface* slot2_device; //the current slot2 device instance extern ISlot2Interface* slot2_List[NDS_SLOT2_COUNT]; -extern NDS_SLOT2_TYPE slot2_selected_id; +extern NDS_SLOT2_TYPE slot2_selected_type; void slot2_Init(); bool slot2_Connect(); diff --git a/desmume/src/version.cpp b/desmume/src/version.cpp index 35f1d3f93..a24e92c5a 100644 --- a/desmume/src/version.cpp +++ b/desmume/src/version.cpp @@ -115,6 +115,10 @@ #define DESMUME_JIT "" #endif +const u8 DESMUME_VERSION_MAJOR = 0; +const u8 DESMUME_VERSION_MINOR = 9; +const u8 DESMUME_VERSION_BUILD = 10; + #define DESMUME_VERSION_NUMERIC 91000 #define DESMUME_VERSION_STRING " " "0.9.10" DESMUME_SUBVERSION_STRING DESMUME_FEATURE_STRING DESMUME_PLATFORM_STRING DESMUME_JIT DESMUME_CPUEXT_STRING #define DESMUME_NAME_AND_VERSION DESMUME_NAME DESMUME_VERSION_STRING diff --git a/desmume/src/version.h b/desmume/src/version.h index 7e03d0cf3..3c3608211 100644 --- a/desmume/src/version.h +++ b/desmume/src/version.h @@ -18,6 +18,10 @@ #include #include "types.h" +extern const u8 DESMUME_VERSION_MAJOR; +extern const u8 DESMUME_VERSION_MINOR; +extern const u8 DESMUME_VERSION_BUILD; + u32 EMU_DESMUME_VERSION_NUMERIC(); const char* EMU_DESMUME_VERSION_STRING(); const char* EMU_DESMUME_SUBVERSION_STRING();