From affc694149db1bf351ff65b8745532e2667411b0 Mon Sep 17 00:00:00 2001 From: LuigiBlood Date: Mon, 12 Aug 2019 23:07:33 +0200 Subject: [PATCH] [Core & UI] Add RAM Area Only (*.ram) Disk Save Type - It's a bit hacky but it works for *.ndd files. - For *.d64 files, it might be more problematic for now --- Source/Project64-core/Multilanguage.h | 6 + .../Multilanguage/LanguageClass.cpp | 5 + .../Project64-core/N64System/N64DiskClass.cpp | 140 ++++++++++++++---- .../Project64-core/N64System/N64DiskClass.h | 5 + Source/Project64-core/N64System/N64Types.h | 5 + Source/Project64-core/Settings.cpp | 1 + Source/Project64-core/Settings/SettingsID.h | 1 + Source/Project64/UserInterface/UIResources.rc | 2 + Source/Project64/UserInterface/resource.h | 6 +- 9 files changed, 140 insertions(+), 31 deletions(-) diff --git a/Source/Project64-core/Multilanguage.h b/Source/Project64-core/Multilanguage.h index c3f57f06a..39bb97669 100644 --- a/Source/Project64-core/Multilanguage.h +++ b/Source/Project64-core/Multilanguage.h @@ -271,9 +271,11 @@ enum LanguageStringID OPTION_CHANGE_FR = 466, OPTION_CHECK_RUNNING = 467, OPTION_UNIQUE_SAVE_DIR = 468, + OPTION_IPL_ROM_PATH = 469, OPTION_IPL_ROM_USA_PATH = 470, OPTION_IPL_ROM_TOOL_PATH = 471, + OPTION_DISKSAVETYPE = 472, //Rom Browser Tab RB_MAX_ROMS = 480, @@ -405,6 +407,10 @@ enum LanguageStringID BOTTOM_RESET_ALL = 721, BOTTOM_APPLY = 722, BOTTOM_CLOSE = 723, + + //Disk Save Type + DISKSAVE_SHADOW = 730, + DISKSAVE_RAM = 731, /********************************************************************************* * ROM Information * diff --git a/Source/Project64-core/Multilanguage/LanguageClass.cpp b/Source/Project64-core/Multilanguage/LanguageClass.cpp index 5ee55b44e..fc625f30a 100644 --- a/Source/Project64-core/Multilanguage/LanguageClass.cpp +++ b/Source/Project64-core/Multilanguage/LanguageClass.cpp @@ -241,6 +241,7 @@ void CLanguage::LoadDefaultStrings(void) DEF_STR(OPTION_IPL_ROM_PATH, "Japanese Retail 64DD IPL ROM Path:"); DEF_STR(OPTION_IPL_ROM_USA_PATH, "American Retail 64DD IPL ROM Path:"); DEF_STR(OPTION_IPL_ROM_TOOL_PATH, "Development 64DD IPL ROM Path:"); + DEF_STR(OPTION_DISKSAVETYPE, "Disk Save Type:"); //ROM Browser Tab DEF_STR(RB_MAX_ROMS, "Max # of ROMs remembered (0-10):"); @@ -372,6 +373,10 @@ void CLanguage::LoadDefaultStrings(void) DEF_STR(BOTTOM_APPLY, "Apply"); DEF_STR(BOTTOM_CLOSE, "Close"); + //Disk Save Type + DEF_STR(DISKSAVE_SHADOW, "Full Disk Copy"); + DEF_STR(DISKSAVE_RAM, "Save Area Only"); + /********************************************************************************* * ROM Information * *********************************************************************************/ diff --git a/Source/Project64-core/N64System/N64DiskClass.cpp b/Source/Project64-core/N64System/N64DiskClass.cpp index f543486e6..9a83b8788 100644 --- a/Source/Project64-core/N64System/N64DiskClass.cpp +++ b/Source/Project64-core/N64System/N64DiskClass.cpp @@ -27,7 +27,9 @@ m_ErrorMsg(EMPTY_STRING), m_DiskBufAddress(0), m_DiskSysAddress(0), m_DiskIDAddress(0), -m_DiskRomAddress(0) +m_DiskRomAddress(0), +m_DiskRamAddress(0), +m_isShadowDisk(false) { } @@ -48,6 +50,7 @@ bool CN64Disk::LoadDiskImage(const char * FileLoc) WriteTrace(TraceN64System, TraceDebug, "Attempt to load shadow file."); if (!AllocateAndLoadDiskImage(ShadowFile.c_str())) { + m_isShadowDisk = false; WriteTrace(TraceN64System, TraceDebug, "Loading Shadow file failed"); UnallocateDiskImage(); if (!AllocateAndLoadDiskImage(FileLoc)) @@ -55,6 +58,10 @@ bool CN64Disk::LoadDiskImage(const char * FileLoc) return false; } } + else + { + m_isShadowDisk = true; + } char RomName[5]; m_FileName = FileLoc; @@ -91,6 +98,8 @@ bool CN64Disk::LoadDiskImage(const char * FileLoc) GenerateLBAToPhysTable(); InitSysDataD64(); + DetectRamAddress(); + LoadDiskRAMImage(); if (g_Disk == this) { @@ -112,37 +121,54 @@ bool CN64Disk::SaveDiskImage() return true; } - //Assume the file extension is *.ndd (it is the only case where it is loaded) - stdstr ShadowFile = m_FileName; - ShadowFile[ShadowFile.length() - 1] = 'r'; - - WriteTrace(TraceN64System, TraceDebug, "Trying to open %s (Shadow File)", ShadowFile.c_str()); - m_DiskFile.Close(); - if (!m_DiskFile.Open(ShadowFile.c_str(), CFileBase::modeWrite | CFileBase::modeCreate | CFileBase::modeNoTruncate)) + //Assume the file extension is *.ndd / *.d64 + if (m_DiskFormat == DiskFormatMAME || m_isShadowDisk || g_Settings->LoadDword(Setting_DiskSaveType) == 0) { - WriteTrace(TraceN64System, TraceError, "Failed to open %s (Shadow File)", ShadowFile.c_str()); - return false; - } + stdstr ShadowFile = m_FileName; + ShadowFile[ShadowFile.length() - 1] = 'r'; - m_DiskFile.SeekToBegin(); - ForceByteSwapDisk(); - - if (m_DiskFormat == DiskFormatMAME) - { - //If original file was MAME format, just copy - WriteTrace(TraceN64System, TraceDebug, "64DD disk is MAME format"); - } - else if (m_DiskFormat == DiskFormatSDK) - { - //If original file was SDK format, we need to convert it back - WriteTrace(TraceN64System, TraceDebug, "64DD disk is SDK format"); - } - - if (!m_DiskFile.Write(m_DiskImage, m_DiskFileSize)) - { + WriteTrace(TraceN64System, TraceDebug, "Trying to open %s (Shadow File)", ShadowFile.c_str()); m_DiskFile.Close(); - WriteTrace(TraceN64System, TraceError, "Failed to write file"); - return false; + if (!m_DiskFile.Open(ShadowFile.c_str(), CFileBase::modeWrite | CFileBase::modeCreate | CFileBase::modeNoTruncate)) + { + WriteTrace(TraceN64System, TraceError, "Failed to open %s (Shadow File)", ShadowFile.c_str()); + return false; + } + + m_DiskFile.SeekToBegin(); + ForceByteSwapDisk(); + + if (!m_DiskFile.Write(m_DiskImage, m_DiskFileSize)) + { + m_DiskFile.Close(); + WriteTrace(TraceN64System, TraceError, "Failed to write file"); + return false; + } + } + else + { + stdstr ShadowFile = m_FileName; + ShadowFile[ShadowFile.length() - 1] = 'm'; + ShadowFile[ShadowFile.length() - 2] = 'a'; + ShadowFile[ShadowFile.length() - 3] = 'r'; + + WriteTrace(TraceN64System, TraceDebug, "Trying to open %s (RAM File)", ShadowFile.c_str()); + m_DiskFile.Close(); + if (!m_DiskFile.Open(ShadowFile.c_str(), CFileBase::modeWrite | CFileBase::modeCreate | CFileBase::modeNoTruncate)) + { + WriteTrace(TraceN64System, TraceError, "Failed to open %s (RAM File)", ShadowFile.c_str()); + return false; + } + + m_DiskFile.SeekToBegin(); + ForceByteSwapDisk(); + + if (!m_DiskFile.Write(GetDiskAddressRam(), m_DiskFileSize - m_DiskRamAddress)) + { + m_DiskFile.Close(); + WriteTrace(TraceN64System, TraceError, "Failed to write file"); + return false; + } } m_DiskFile.Close(); @@ -403,6 +429,45 @@ bool CN64Disk::AllocateAndLoadDiskImage(const char * FileLoc) return true; } +bool CN64Disk::LoadDiskRAMImage() +{ + if (m_DiskFormat == DiskFormatMAME || m_isShadowDisk) + return true; + + CFile ramfile; + stdstr filename = m_FileName; + + filename[filename.length() - 1] = 'm'; + filename[filename.length() - 2] = 'a'; + filename[filename.length() - 3] = 'r'; + + WriteTrace(TraceN64System, TraceDebug, "Trying to open %s", filename); + if (!ramfile.Open(filename.c_str(), CFileBase::modeRead)) + { + WriteTrace(TraceN64System, TraceError, "Failed to open %s", filename); + return false; + } + + if (ramfile.GetLength() != m_DiskFileSize - m_DiskRamAddress) + { + ramfile.Close(); + WriteTrace(TraceN64System, TraceError, "RAM save file is the wrong size"); + return false; + } + + ForceByteSwapDisk(); + ramfile.SeekToBegin(); + if (ramfile.Read(GetDiskAddressRam(), m_DiskFileSize - m_DiskRamAddress) != (m_DiskFileSize - m_DiskRamAddress)) + { + ramfile.Close(); + WriteTrace(TraceN64System, TraceError, "Failed to read RAM save data"); + return false; + } + + ForceByteSwapDisk(); + return true; +} + void CN64Disk::ByteSwapDisk() { uint32_t count; @@ -713,6 +778,23 @@ void CN64Disk::GenerateLBAToPhysTable() } } +void CN64Disk::DetectRamAddress() +{ + if (m_DiskFormat == DiskFormatMAME) + { + //Not supported + m_DiskRamAddress = 0; + } + else if (m_DiskFormat == DiskFormatSDK) + { + m_DiskRamAddress = LBAToByte(0, RAM_START_LBA[m_DiskType]); + } + else //if (m_DiskFormat == DiskFormatD64) + { + m_DiskRamAddress = m_DiskRomAddress + LBAToByte(SYSTEM_LBAS, *(uint16_t*)(&GetDiskAddressSys()[0xE2])); + } +} + uint32_t CN64Disk::LBAToVZone(uint32_t lba) { for (uint32_t vzone = 0; vzone < 16; vzone++) { diff --git a/Source/Project64-core/N64System/N64DiskClass.h b/Source/Project64-core/N64System/N64DiskClass.h index e86385da3..42675b3b1 100644 --- a/Source/Project64-core/N64System/N64DiskClass.h +++ b/Source/Project64-core/N64System/N64DiskClass.h @@ -30,6 +30,7 @@ public: uint8_t * GetDiskAddressSys() { return m_DiskImage + m_DiskSysAddress; } uint8_t * GetDiskAddressID() { return m_DiskImage + m_DiskIDAddress; } uint8_t * GetDiskAddressRom() { return m_DiskImage + m_DiskRomAddress; } + uint8_t * GetDiskAddressRam() { return m_DiskImage + m_DiskRamAddress; } uint8_t * GetDiskHeader() { return m_DiskHeader; } void SetDiskAddressBuffer(uint32_t address) { m_DiskBufAddress = address; } uint32_t GetDiskAddressBlock(uint16_t head, uint16_t track, uint16_t block, uint16_t sector, uint16_t sectorsize); @@ -46,6 +47,7 @@ private: bool AllocateDiskImage(uint32_t DiskFileSize); bool AllocateDiskHeader(); bool AllocateAndLoadDiskImage(const char * FileLoc); + bool LoadDiskRAMImage(); void ByteSwapDisk(); void ForceByteSwapDisk(); void SetError(LanguageStringID ErrorMsg); @@ -56,6 +58,7 @@ private: void InitSysDataD64(); void DeinitSysDataD64(); void GenerateLBAToPhysTable(); + void DetectRamAddress(); uint32_t LBAToVZone(uint32_t lba); uint32_t LBAToByte(uint32_t lba, uint32_t nlbas); uint16_t LBAToPhys(uint32_t lba); @@ -76,11 +79,13 @@ private: uint32_t m_DiskSysAddress; uint32_t m_DiskIDAddress; uint32_t m_DiskRomAddress; + uint32_t m_DiskRamAddress; LanguageStringID m_ErrorMsg; Country m_Country; stdstr m_RomName, m_FileName, m_DiskIdent; uint8_t m_DiskFormat; //0 = MAME, 1 = SDK, 2 = D64 uint8_t m_DiskType; + bool m_isShadowDisk; //Disk Defines #define MAX_LBA 0x10DB diff --git a/Source/Project64-core/N64System/N64Types.h b/Source/Project64-core/N64System/N64Types.h index f06d1f865..268ad5b15 100644 --- a/Source/Project64-core/N64System/N64Types.h +++ b/Source/Project64-core/N64System/N64Types.h @@ -53,6 +53,11 @@ enum SAVE_CHIP_TYPE SaveChip_Auto = -1, SaveChip_Eeprom_4K, SaveChip_Eeprom_16K, SaveChip_Sram, SaveChip_FlashRam }; +enum SAVE_DISK_TYPE +{ + SaveDisk_ShadowFile = 0, SaveDisk_RAMFile = 1, +}; + enum FUNC_LOOKUP_METHOD { FuncFind_Default = -1, FuncFind_PhysicalLookup = 1, FuncFind_VirtualLookup = 2, FuncFind_ChangeMemory = 3, diff --git a/Source/Project64-core/Settings.cpp b/Source/Project64-core/Settings.cpp index afacbd066..74226bd3f 100644 --- a/Source/Project64-core/Settings.cpp +++ b/Source/Project64-core/Settings.cpp @@ -137,6 +137,7 @@ void CSettings::AddHowToHandleSetting(const char * BaseDirectory) AddHandler(Setting_LanguageDirDefault, new CSettingTypeRelativePath("Lang", "")); AddHandler(Setting_LanguageDir, new CSettingTypeApplicationPath("Lang Directory", "Directory", Setting_LanguageDirDefault)); AddHandler(Setting_SyncViaAudioEnabled, new CSettingTypeTempBool(false, "SyncViaAudioEnabled")); + AddHandler(Setting_DiskSaveType, new CSettingTypeApplication("Settings", "Disk Save Type", (uint32_t)1)); AddHandler(Default_RDRamSize, new CSettingTypeApplication("Defaults", "RDRAM Size", 0x400000u)); AddHandler(Default_UseHleGfx, new CSettingTypeApplication("Defaults", "HLE GFX Default", true)); diff --git a/Source/Project64-core/Settings/SettingsID.h b/Source/Project64-core/Settings/SettingsID.h index 29ade0e98..d772d980b 100644 --- a/Source/Project64-core/Settings/SettingsID.h +++ b/Source/Project64-core/Settings/SettingsID.h @@ -64,6 +64,7 @@ enum SettingID Setting_EnableDisk, Setting_SyncViaAudioEnabled, Setting_Enhancement, + Setting_DiskSaveType, //Default Settings Default_RDRamSize, diff --git a/Source/Project64/UserInterface/UIResources.rc b/Source/Project64/UserInterface/UIResources.rc index 90d9cc330..37a8e3f09 100644 --- a/Source/Project64/UserInterface/UIResources.rc +++ b/Source/Project64/UserInterface/UIResources.rc @@ -1379,6 +1379,8 @@ BEGIN EDITTEXT IDC_IPL_TL_DIR,7,78,184,12,ES_AUTOHSCROLL PUSHBUTTON "...",IDC_SELECT_IPL_TL_DIR,197,78,14,12 LTEXT "Development 64DD IPL ROM Path:",IDC_IPLDIR_TL_TXT,9,67,145,10 + LTEXT "Save File Type:",IDC_DISKSAVETYPE_TXT,9,106,83,10 + COMBOBOX IDC_DISKSAVETYPE,95,104,115,30,CBS_DROPDOWNLIST | CBS_SORT | WS_VSCROLL | WS_TABSTOP END diff --git a/Source/Project64/UserInterface/resource.h b/Source/Project64/UserInterface/resource.h index d49f4802e..fbc5ac4d2 100644 --- a/Source/Project64/UserInterface/resource.h +++ b/Source/Project64/UserInterface/resource.h @@ -695,6 +695,8 @@ #define IDC_IPL_TL_DIR 1544 #define IDC_SELECT_IPL_TL_DIR 1545 #define IDC_IPLDIR_TL_TXT 1546 +#define IDC_DISKSAVETYPE_TXT 1547 +#define IDC_DISKSAVETYPE 1548 #define ID_POPUPMENU_PLAYGAMEWITHDISK 40008 #define ID_POPUPMENU_ADDSYMBOL 40013 #define ID_POPUPMENU_VIEWDISASM 40017 @@ -753,9 +755,9 @@ // #ifdef APSTUDIO_INVOKED #ifndef APSTUDIO_READONLY_SYMBOLS -#define _APS_NEXT_RESOURCE_VALUE 217 +#define _APS_NEXT_RESOURCE_VALUE 219 #define _APS_NEXT_COMMAND_VALUE 40092 -#define _APS_NEXT_CONTROL_VALUE 1541 +#define _APS_NEXT_CONTROL_VALUE 1549 #define _APS_NEXT_SYMED_VALUE 102 #endif #endif