From 43455eb4fe954040f30a9a30ef1a82ba75912b73 Mon Sep 17 00:00:00 2001 From: TomCh Date: Sun, 25 Oct 2020 17:14:23 +0000 Subject: [PATCH] Improved determining path & filename when saving/loading a save-state (#691) (PR #849) Whenever harddisks/disks are inserted (or removed) and *if path has changed* then: . Then the internal save-state's path & filename will be updated to reflect the new defaults. . LoadConfiguration(): Read the save-state pathname from Registry before harddisks/disks. Also: . CiderPress: only save pathname on OK. . Refactored CPropertySheetHelper::BrowseToFile(). . Extended support for -d1,-d2,-h1, etc such that if the param is "", then it will eject/unplug the disk/harddisk. --- help/CommandLine.html | 2 +- source/Applewin.cpp | 38 +++--- source/CardManager.h | 2 +- source/Configuration/PageAdvanced.cpp | 15 +-- source/Configuration/PageDisk.cpp | 17 ++- source/Configuration/PropertySheet.cpp | 2 - source/Configuration/PropertySheetHelper.cpp | 115 ++++--------------- source/Configuration/PropertySheetHelper.h | 4 - source/Disk.cpp | 32 +++++- source/Disk.h | 1 + source/Disk2CardManager.cpp | 13 +++ source/Disk2CardManager.h | 1 + source/Harddisk.cpp | 36 +++++- source/Harddisk.h | 1 + source/SaveState.cpp | 59 +++++++++- source/SaveState.h | 9 +- 16 files changed, 207 insertions(+), 140 deletions(-) diff --git a/help/CommandLine.html b/help/CommandLine.html index a5eed164..fe3858b4 100644 --- a/help/CommandLine.html +++ b/help/CommandLine.html @@ -61,7 +61,7 @@ Emulate a RamWorks III card with 1 to 127 pages (each page is 64K, giving a max of 8MB) in the auxiliary slot in an Apple //e machine.

-load-state <savestate>
Load a save-state file (and auto power-on the Apple II).
- NB. This takes precedent over the -d1, -d2, -d#s#, -h1, -h2, s0-7, -model and -r switches.

+ NB. This takes precedent over the -d1, -d2, -s#d#, -h1, -h2, s0-7, -model and -r switches.

-f
Start in full-screen mode

-fs-height=<best|nnnn>
diff --git a/source/Applewin.cpp b/source/Applewin.cpp index 5e7ce8fa..e2391cbb 100644 --- a/source/Applewin.cpp +++ b/source/Applewin.cpp @@ -786,6 +786,13 @@ void LoadConfiguration(void) TCHAR szFilename[MAX_PATH]; + // Load save-state pathname *before* inserting any harddisk/disk images (for both init & reinit cases) + // NB. inserting harddisk/disk can change snapshot pathname + RegLoadString(TEXT(REG_CONFIG), TEXT(REGVALUE_SAVESTATE_FILENAME), 1, szFilename, MAX_PATH, TEXT("")); // Can be pathname or just filename + Snapshot_SetFilename(szFilename); // If not in Registry than default will be used (ie. g_sCurrentDir + default filename) + + // + RegLoadString(TEXT(REG_PREFS), TEXT(REGVALUE_PREF_HDV_START_DIR), 1, szFilename, MAX_PATH, TEXT("")); if (szFilename[0] == '\0') GetCurrentDirectory(sizeof(szFilename), szFilename); @@ -796,7 +803,7 @@ void LoadConfiguration(void) // - // Current/Starting Dir is the "root" of where the user keeps his disk images + // Current/Starting Dir is the "root" of where the user keeps their disk images RegLoadString(TEXT(REG_PREFS), TEXT(REGVALUE_PREF_START_DIR), 1, szFilename, MAX_PATH, TEXT("")); if (szFilename[0] == '\0') GetCurrentDirectory(sizeof(szFilename), szFilename); @@ -815,9 +822,6 @@ void LoadConfiguration(void) // - RegLoadString(TEXT(REG_CONFIG), TEXT(REGVALUE_SAVESTATE_FILENAME), 1, szFilename, MAX_PATH, TEXT("")); - Snapshot_SetFilename(szFilename); // If not in Registry than default will be used (ie. g_sCurrentDir + default filename) - RegLoadString(TEXT(REG_CONFIG), TEXT(REGVALUE_PRINTER_FILENAME), 1, szFilename, MAX_PATH, TEXT("")); Printer_SetFilename(szFilename); // If not in Registry than default will be used @@ -837,8 +841,7 @@ bool SetCurrentImageDir(const std::string & pszImageDir) { g_sCurrentDir = pszImageDir; - int nLen = g_sCurrentDir.size(); - if ((nLen > 0) && (g_sCurrentDir[ nLen - 1 ] != '\\')) + if (!g_sCurrentDir.empty() && *g_sCurrentDir.rbegin() != '\\') g_sCurrentDir += '\\'; if( SetCurrentDirectory(g_sCurrentDir.c_str()) ) @@ -1176,6 +1179,12 @@ static bool DoDiskInsert(const UINT slot, const int nDrive, LPCSTR szFileName) { Disk2InterfaceCard& disk2Card = dynamic_cast(GetCardMgr().GetRef(slot)); + if (szFileName[0] == '\0') + { + disk2Card.EjectDisk(nDrive); + return true; + } + std::string strPathName = GetFullPath(szFileName); if (strPathName.empty()) return false; @@ -1188,6 +1197,12 @@ static bool DoDiskInsert(const UINT slot, const int nDrive, LPCSTR szFileName) static bool DoHardDiskInsert(const int nDrive, LPCSTR szFileName) { + if (szFileName[0] == '\0') + { + HD_Unplug(nDrive); + return true; + } + std::string strPathName = GetFullPath(szFileName); if (strPathName.empty()) return false; @@ -2096,7 +2111,10 @@ static void RepeatInitialization(void) g_cmdLine.szImageName_harddisk[HARDDISK_1] = g_cmdLine.szImageName_harddisk[HARDDISK_2] = NULL; // Don't insert on a restart if (g_cmdLine.bSlotEmpty[7]) + { HD_SetEnabled(false); // Disable HDD controller, but don't persist this to Registry/conf.ini (consistent with other '-sn empty' cmds) + Snapshot_UpdatePath(); // If save-state's filename is a harddisk, and the floppy is in the same path, then the filename won't be updated + } } // Set *after* InsertFloppyDisks() & InsertHardDisks(), which both update g_sCurrentDir @@ -2160,7 +2178,7 @@ static void RepeatInitialization(void) { std::string strPathname(g_cmdLine.szSnapshotName); int nIdx = strPathname.find_last_of('\\'); - if (nIdx >= 0 && nIdx+1 < (int)strPathname.length()) + if (nIdx >= 0 && nIdx+1 < (int)strPathname.length()) // path exists? { const std::string strPath = strPathname.substr(0, nIdx+1); SetCurrentImageDir(strPath); @@ -2171,12 +2189,6 @@ static void RepeatInitialization(void) Snapshot_SetFilename(g_cmdLine.szSnapshotName); Snapshot_LoadState(); g_cmdLine.bBoot = true; -#if _DEBUG && 0 // Debug/test: Save a duplicate of the save-state file in tmp folder - std::string saveName = std::string("tmp\\") + std::string(szSnapshotName); - Snapshot_SetFilename(saveName); - g_bSaveStateOnExit = true; - bShutdown = true; -#endif g_cmdLine.szSnapshotName = NULL; } else diff --git a/source/CardManager.h b/source/CardManager.h index 41972efd..3e9d5b8f 100644 --- a/source/CardManager.h +++ b/source/CardManager.h @@ -29,7 +29,7 @@ public: void Insert(UINT slot, SS_CARDTYPE type); void Remove(UINT slot); - SS_CARDTYPE QuerySlot(UINT slot) { return m_slot[slot]->QueryType(); } + SS_CARDTYPE QuerySlot(UINT slot) { _ASSERT(slotQueryType(); } Card& GetRef(UINT slot) { SS_CARDTYPE t=QuerySlot(slot); _ASSERT((t==CT_SSC || t==CT_MouseInterface || t==CT_Disk2) && m_slot[slot]); diff --git a/source/Configuration/PageAdvanced.cpp b/source/Configuration/PageAdvanced.cpp index 8ff9120f..63924fb9 100644 --- a/source/Configuration/PageAdvanced.cpp +++ b/source/Configuration/PageAdvanced.cpp @@ -140,8 +140,6 @@ BOOL CPageAdvanced::DlgProcInternal(HWND hWnd, UINT message, WPARAM wparam, LPAR InitOptions(hWnd); - m_PropertySheetHelper.ClearSSNewDirectory(); - // Need to specify cmd-line switch: -printer-real to enable this control EnableWindow(GetDlgItem(hWnd, IDC_DUMPTOPRINTER), g_bEnableDumpToRealPrinter ? TRUE : FALSE); @@ -156,17 +154,8 @@ void CPageAdvanced::DlgOK(HWND hWnd) { // Update save-state filename { - char szFilename[MAX_PATH]; - memset(szFilename, 0, sizeof(szFilename)); - * (USHORT*) szFilename = sizeof(szFilename); - - UINT nLineLength = SendDlgItemMessage(hWnd, IDC_SAVESTATE_FILENAME, EM_LINELENGTH, 0, 0); - - SendDlgItemMessage(hWnd, IDC_SAVESTATE_FILENAME, EM_GETLINE, 0, (LPARAM)szFilename); - - nLineLength = nLineLength > sizeof(szFilename)-1 ? sizeof(szFilename)-1 : nLineLength; - szFilename[nLineLength] = 0x00; - + // NB. if SaveStateSelectImage() was called (by pressing the "Save State -> Browse..." button) + // and a new save-state file was selected ("OK" from the openfilename dialog) then m_bSSNewFilename etc. will have been set m_PropertySheetHelper.SaveStateUpdate(); } diff --git a/source/Configuration/PageDisk.cpp b/source/Configuration/PageDisk.cpp index 2f8b1c64..f74d339f 100644 --- a/source/Configuration/PageDisk.cpp +++ b/source/Configuration/PageDisk.cpp @@ -122,7 +122,6 @@ BOOL CPageDisk::DlgProcInternal(HWND hWnd, UINT message, WPARAM wparam, LPARAM l case IDC_CIDERPRESS_BROWSE: { std::string CiderPressLoc = m_PropertySheetHelper.BrowseToFile(hWnd, TEXT("Select path to CiderPress"), REGVALUE_CIDERPRESSLOC, TEXT("Applications (*.exe)\0*.exe\0") TEXT("All Files\0*.*\0") ); - RegSaveString(TEXT(REG_CONFIG), REGVALUE_CIDERPRESSLOC, 1, CiderPressLoc); SendDlgItemMessage(hWnd, IDC_CIDERPRESS_FILENAME, WM_SETTEXT, 0, (LPARAM) CiderPressLoc.c_str()); } break; @@ -198,6 +197,22 @@ void CPageDisk::InitComboHDD(HWND hWnd, UINT /*slot*/) void CPageDisk::DlgOK(HWND hWnd) { + // Update CiderPress pathname + { + char szFilename[MAX_PATH]; + memset(szFilename, 0, sizeof(szFilename)); + * (USHORT*) szFilename = sizeof(szFilename); + + UINT nLineLength = SendDlgItemMessage(hWnd, IDC_CIDERPRESS_FILENAME, EM_LINELENGTH, 0, 0); + + SendDlgItemMessage(hWnd, IDC_CIDERPRESS_FILENAME, EM_GETLINE, 0, (LPARAM)szFilename); + + nLineLength = nLineLength > sizeof(szFilename)-1 ? sizeof(szFilename)-1 : nLineLength; + szFilename[nLineLength] = 0x00; + + RegSaveString(TEXT(REG_CONFIG), REGVALUE_CIDERPRESSLOC, 1, szFilename); + } + const bool bNewEnhanceDisk = SendDlgItemMessage(hWnd, IDC_DISKTYPE,CB_GETCURSEL, 0, 0) ? true : false; if (bNewEnhanceDisk != GetCardMgr().GetDisk2CardMgr().GetEnhanceDisk()) { diff --git a/source/Configuration/PropertySheet.cpp b/source/Configuration/PropertySheet.cpp index 71848beb..65b4367a 100644 --- a/source/Configuration/PropertySheet.cpp +++ b/source/Configuration/PropertySheet.cpp @@ -92,8 +92,6 @@ DWORD CPropertySheet::GetVolumeMax() // Called when F11/F12 is pressed bool CPropertySheet::SaveStateSelectImage(HWND hWindow, bool bSave) { - m_PropertySheetHelper.ClearSSNewDirectory(); - if(m_PropertySheetHelper.SaveStateSelectImage(hWindow, bSave ? TEXT("Select Save State file") : TEXT("Select Load State file"), bSave)) { diff --git a/source/Configuration/PropertySheetHelper.cpp b/source/Configuration/PropertySheetHelper.cpp index 3e687098..294f5e72 100644 --- a/source/Configuration/PropertySheetHelper.cpp +++ b/source/Configuration/PropertySheetHelper.cpp @@ -147,23 +147,18 @@ void CPropertySheetHelper::SetSlot(UINT slot, SS_CARDTYPE newCardType) REGSAVE(slotText.c_str(), (DWORD)newCardType); } -// Looks like a (bad) C&P from SaveStateSelectImage() -// - eg. see "RAPCS" tags below... // Used by: // . CPageDisk: IDC_CIDERPRESS_BROWSE // . CPageAdvanced: IDC_PRINTER_DUMP_FILENAME_BROWSE std::string CPropertySheetHelper::BrowseToFile(HWND hWindow, TCHAR* pszTitle, TCHAR* REGVALUE, TCHAR* FILEMASKS) { - static std::string PathToFile; //This is a really awkward way to prevent mixing CiderPress and SaveStated values (RAPCS), but it seem the quickest. Here is its Line 1. - PathToFile = Snapshot_GetFilename(); //RAPCS, line 2. - TCHAR szDirectory[MAX_PATH] = TEXT(""); TCHAR szFilename[MAX_PATH]; - RegLoadString(TEXT("Configuration"), REGVALUE, 1, szFilename, MAX_PATH, TEXT("")); - std::string PathName = szFilename; + RegLoadString(REG_CONFIG, REGVALUE, 1, szFilename, MAX_PATH, TEXT("")); + std::string pathname = szFilename; OPENFILENAME ofn; ZeroMemory(&ofn,sizeof(OPENFILENAME)); - + ofn.lStructSize = sizeof(OPENFILENAME); ofn.hwndOwner = hWindow; ofn.hInstance = g_hInstance; @@ -173,121 +168,57 @@ std::string CPropertySheetHelper::BrowseToFile(HWND hWindow, TCHAR* pszTitle, TC TEXT("All Files\0*.*\0");*/ ofn.lpstrFile = szFilename; ofn.nMaxFile = MAX_PATH; - ofn.lpstrInitialDir = szDirectory; + ofn.lpstrInitialDir = ""; ofn.Flags = OFN_PATHMUSTEXIST | OFN_HIDEREADONLY; ofn.lpstrTitle = pszTitle; - + int nRes = GetOpenFileName(&ofn); - if(nRes) // Okay is pressed - { - m_szNewFilename = &szFilename[ofn.nFileOffset]; // TODO:TC: m_szNewFilename not used! (Was g_szNewFilename) + if (nRes) // OK is pressed + pathname = szFilename; - szFilename[ofn.nFileOffset] = 0; - if (_tcsicmp(szDirectory, szFilename)) - m_szSSNewDirectory = szFilename; // TODO:TC: m_szSSNewDirectory looks dodgy! (Was g_szSSNewDirectory) - - PathName = szFilename; - PathName.append (m_szNewFilename); - } - else // Cancel is pressed - { - RegLoadString(TEXT("Configuration"), REGVALUE, 1, szFilename, MAX_PATH, TEXT("")); - PathName = szFilename; - } - - m_szNewFilename = PathToFile; //RAPCS, line 3 (last). - return PathName; + return pathname; } void CPropertySheetHelper::SaveStateUpdate() { if (m_bSSNewFilename) { - Snapshot_SetFilename(m_szSSNewPathname); - - RegSaveString(TEXT(REG_CONFIG), REGVALUE_SAVESTATE_FILENAME, 1, m_szSSNewPathname); - - if(!m_szSSNewDirectory.empty()) - RegSaveString(TEXT(REG_PREFS), REGVALUE_PREF_START_DIR, 1, m_szSSNewDirectory); + Snapshot_SetFilename(m_szSSNewFilename, m_szSSNewDirectory); + RegSaveString(TEXT(REG_CONFIG), TEXT(REGVALUE_SAVESTATE_FILENAME), 1, Snapshot_GetPathname()); } } -void CPropertySheetHelper::GetDiskBaseNameWithAWS(std::string & pszFilename) -{ - if (GetCardMgr().QuerySlot(SLOT6) != CT_Disk2) - return; - - const std::string& diskName = dynamic_cast(GetCardMgr().GetRef(SLOT6)).GetBaseName(DRIVE_1); - if (!diskName.empty()) - { - pszFilename = diskName + ".aws.yaml"; - } -} - -// NB. OK'ing this property sheet will call Snapshot_SetFilename() with this new filename +// NB. OK'ing this property sheet will call SaveStateUpdate()->Snapshot_SetFilename() with this new path & filename int CPropertySheetHelper::SaveStateSelectImage(HWND hWindow, TCHAR* pszTitle, bool bSave) { - std::string szDirectory; - std::string tempFilename; + // Whenever harddisks/disks are inserted (or removed) and *if path has changed* then: + // . Snapshot's path & Snapshot's filename will be updated to reflect the new defaults. - if (bSave) - { - // Attempt to use drive1's image name as the name for the .aws file - // Else Attempt to use the Prop Sheet's filename - GetDiskBaseNameWithAWS(tempFilename); - if (tempFilename.empty()) - { - tempFilename = Snapshot_GetFilename(); - } - } - else // Load (or Browse) - { - // Attempt to use the Prop Sheet's filename first - // Else attempt to use drive1's image name as the name for the .aws file - tempFilename = Snapshot_GetFilename(); - if (tempFilename.empty()) - { - GetDiskBaseNameWithAWS(tempFilename); - } - - szDirectory = Snapshot_GetPath(); - } - + std::string szDirectory = Snapshot_GetPath(); if (szDirectory.empty()) szDirectory = g_sCurrentDir; - // convert tempFilename to char * for the rest of the function - TCHAR szFilename[MAX_PATH] = {0}; - strcpy(szFilename, tempFilename.c_str()); - tempFilename.clear(); // do NOT use this any longer + char szFilename[MAX_PATH]; + strcpy(szFilename, Snapshot_GetFilename().c_str()); // - + OPENFILENAME ofn; ZeroMemory(&ofn,sizeof(OPENFILENAME)); - + ofn.lStructSize = sizeof(OPENFILENAME); ofn.hwndOwner = hWindow; ofn.hInstance = g_hInstance; - if (bSave) - { - ofn.lpstrFilter = TEXT("Save State files (*.aws.yaml)\0*.aws.yaml\0"); + ofn.lpstrFilter = TEXT("Save State files (*.aws.yaml)\0*.aws.yaml\0"); TEXT("All Files\0*.*\0"); - } - else - { - ofn.lpstrFilter = TEXT("Save State files (*.aws,*.aws.yaml)\0*.aws;*.aws.yaml\0"); - TEXT("All Files\0*.*\0"); - } ofn.lpstrFile = szFilename; // Dialog strips the last .EXT from this string (eg. file.aws.yaml is displayed as: file.aws - ofn.nMaxFile = MAX_PATH; + ofn.nMaxFile = sizeof(szFilename); ofn.lpstrInitialDir = szDirectory.c_str(); ofn.Flags = OFN_PATHMUSTEXIST | OFN_HIDEREADONLY; ofn.lpstrTitle = pszTitle; int nRes = bSave ? GetSaveFileName(&ofn) : GetOpenFileName(&ofn); - - if(nRes) + if (nRes) { if (bSave) // Only for saving (allow loading of any file for backwards compatibility) { @@ -322,11 +253,9 @@ int CPropertySheetHelper::SaveStateSelectImage(HWND hWindow, TCHAR* pszTitle, bo } m_szSSNewFilename = &szFilename[ofn.nFileOffset]; - m_szSSNewPathname = szFilename; szFilename[ofn.nFileOffset] = 0; - if (_tcsicmp(szDirectory.c_str(), szFilename)) - m_szSSNewDirectory = szFilename; + m_szSSNewDirectory = szFilename; // always set this, even if unchanged } m_bSSNewFilename = nRes ? true : false; diff --git a/source/Configuration/PropertySheetHelper.h b/source/Configuration/PropertySheetHelper.h index 5e66a654..fe405f67 100644 --- a/source/Configuration/PropertySheetHelper.h +++ b/source/Configuration/PropertySheetHelper.h @@ -30,7 +30,6 @@ public: void SaveCurrentConfig(void); const std::string & GetSSNewFilename(void) { return m_szSSNewFilename; } - void ClearSSNewDirectory(void) { m_szSSNewDirectory.clear(); } // const CConfigNeedingRestart& GetConfigOld(void) { return m_ConfigOld; } CConfigNeedingRestart& GetConfigNew(void) { return m_ConfigNew; } bool IsConfigChanged(void) { return m_ConfigNew != m_ConfigOld; } @@ -49,15 +48,12 @@ private: void RestoreCurrentConfig(void); std::string GetSlot(const UINT uSlot); std::string GetCardName(const SS_CARDTYPE CardType); - void GetDiskBaseNameWithAWS(std::string & pszFilename); PAGETYPE m_LastPage; UINT32 m_bmPages; - std::string m_szNewFilename; bool m_bSSNewFilename; std::string m_szSSNewDirectory; std::string m_szSSNewFilename; - std::string m_szSSNewPathname; CConfigNeedingRestart m_ConfigOld; CConfigNeedingRestart m_ConfigNew; bool m_bDoBenchmark; diff --git a/source/Disk.cpp b/source/Disk.cpp index 1df0ea2e..11e1dfd8 100644 --- a/source/Disk.cpp +++ b/source/Disk.cpp @@ -40,6 +40,7 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA #include "Log.h" #include "Memory.h" #include "Registry.h" +#include "SaveState.h" #include "Video.h" #include "YamlHelper.h" @@ -342,6 +343,7 @@ void Disk2InterfaceCard::EjectDisk(const int drive) return; EjectDiskInternal(drive); + Snapshot_UpdatePath(); SaveLastDiskImage(drive); Video_ResetScreenshotCounter(""); @@ -562,6 +564,31 @@ const std::string & Disk2InterfaceCard::GetBaseName(const int drive) return m_floppyDrive[drive].m_disk.m_imagename; } +void Disk2InterfaceCard::GetFilenameAndPathForSaveState(std::string& filename, std::string& path) +{ + filename = ""; + path = ""; + + for (UINT i=DRIVE_1; i<=DRIVE_2; i++) + { + if (IsDriveEmpty(i)) + continue; + + filename = GetBaseName(i); + std::string pathname = DiskGetFullPathName(i); + + int idx = pathname.find_last_of('\\'); + if (idx >= 0 && idx+1 < (int)pathname.length()) // path exists? + { + path = pathname.substr(0, idx+1); + return; + } + + _ASSERT(0); + break; + } +} + const std::string & Disk2InterfaceCard::DiskGetFullPathName(const int drive) { return ImageGetPathname(m_floppyDrive[drive].m_disk.m_imagehandle); @@ -605,6 +632,7 @@ void Disk2InterfaceCard::GetLightStatus(Disk_Status_e *pDisk1Status, Disk_Status //=========================================================================== +// Pre: pszImageFilename is *not* qualified with path ImageError_e Disk2InterfaceCard::InsertDisk(const int drive, LPCTSTR pszImageFilename, const bool bForceWriteProtected, const bool bCreateIfNecessary) { FloppyDrive* pDrive = &m_floppyDrive[drive]; @@ -660,6 +688,8 @@ ImageError_e Disk2InterfaceCard::InsertDisk(const int drive, LPCTSTR pszImageFil if (Error == eIMAGE_ERROR_NONE) { GetImageTitle(pszImageFilename, pFloppy->m_imagename, pFloppy->m_fullname); + Snapshot_UpdatePath(); + Video_ResetScreenshotCounter(pFloppy->m_imagename); if (g_nAppMode == MODE_LOGO) @@ -1509,7 +1539,7 @@ bool Disk2InterfaceCard::UserSelectNewDiskImage(const int drive, LPCSTR pszFilen StringCbCopy(filename, MAX_PATH, pszFilename); - RegLoadString(TEXT(REG_PREFS), REGVALUE_PREF_START_DIR, 1, directory, MAX_PATH, TEXT("")); + RegLoadString(TEXT(REG_PREFS), TEXT(REGVALUE_PREF_START_DIR), 1, directory, MAX_PATH, TEXT("")); StringCbPrintf(title, 40, TEXT("Select Disk Image For Drive %d"), drive + 1); _ASSERT(sizeof(OPENFILENAME) == sizeof(OPENFILENAME_NT4)); // Required for Win98/ME support (selected by _WIN32_WINNT=0x0400 in stdafx.h) diff --git a/source/Disk.h b/source/Disk.h index b3070e1f..c0dc4985 100644 --- a/source/Disk.h +++ b/source/Disk.h @@ -135,6 +135,7 @@ public: const std::string & GetFullDiskFilename(const int drive); const std::string & GetFullName(const int drive); const std::string & GetBaseName(const int drive); + void GetFilenameAndPathForSaveState(std::string& filename, std::string& path); void GetLightStatus (Disk_Status_e* pDisk1Status, Disk_Status_e* pDisk2Status); ImageError_e InsertDisk(const int drive, LPCTSTR pszImageFilename, const bool bForceWriteProtected, const bool bCreateIfNecessary); diff --git a/source/Disk2CardManager.cpp b/source/Disk2CardManager.cpp index 0f7c7bcd..a56b4946 100644 --- a/source/Disk2CardManager.cpp +++ b/source/Disk2CardManager.cpp @@ -132,3 +132,16 @@ bool Disk2CardManager::IsAnyFirmware13Sector(void) } return false; } + +void Disk2CardManager::GetFilenameAndPathForSaveState(std::string& filename, std::string& path) +{ + for (int i = NUM_SLOTS-1; i >= 0; i--) // scan slots backwards: 7->0 + { + if (GetCardMgr().QuerySlot(i) == CT_Disk2) + { + dynamic_cast(GetCardMgr().GetRef(i)).GetFilenameAndPathForSaveState(filename, path); + if (!filename.empty()) + return; + } + } +} diff --git a/source/Disk2CardManager.h b/source/Disk2CardManager.h index 85bf193d..a3c4332e 100644 --- a/source/Disk2CardManager.h +++ b/source/Disk2CardManager.h @@ -14,4 +14,5 @@ public: void LoadLastDiskImage(void); void Destroy(void); bool IsAnyFirmware13Sector(void); + void GetFilenameAndPathForSaveState(std::string& filename, std::string& path); }; diff --git a/source/Harddisk.cpp b/source/Harddisk.cpp index d3ee00b1..aed70a07 100644 --- a/source/Harddisk.cpp +++ b/source/Harddisk.cpp @@ -37,6 +37,7 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA #include "Harddisk.h" #include "Memory.h" #include "Registry.h" +#include "SaveState.h" #include "YamlHelper.h" #include "../resource/resource.h" @@ -143,7 +144,7 @@ struct HDD } // From FloppyDisk - std::string imagename; // (ie. no extension) [not used] + std::string imagename; // (ie. no extension) std::string fullname; // or std::string strFilenameInZip; // "" or [not used] ImageInfo* imagehandle; // Init'd by HD_Insert() -> ImageOpen() @@ -313,11 +314,38 @@ const std::string & HD_GetFullPathName(const int iDrive) return ImageGetPathname(g_HardDisk[iDrive].imagehandle); } -static const std::string & HD_DiskGetBaseName(const int iDrive) // Not used +static const std::string & HD_DiskGetBaseName(const int iDrive) { return g_HardDisk[iDrive].imagename; } +void HD_GetFilenameAndPathForSaveState(std::string& filename, std::string& path) +{ + filename = ""; + path = ""; + + if (!g_bHD_Enabled) + return; + + for (UINT i=HARDDISK_1; i<=HARDDISK_2; i++) + { + if (!g_HardDisk[i].hd_imageloaded) + continue; + + filename = HD_DiskGetBaseName(i); + std::string pathname = HD_GetFullPathName(i); + + int idx = pathname.find_last_of('\\'); + if (idx >= 0 && idx+1 < (int)pathname.length()) // path exists? + { + path = pathname.substr(0, idx+1); + return; + } + + _ASSERT(0); + break; + } +} //------------------------------------- @@ -413,6 +441,7 @@ BOOL HD_Insert(const int iDrive, const std::string & pszImageFilename) if (Error == eIMAGE_ERROR_NONE) { GetImageTitle(pszImageFilename.c_str(), g_HardDisk[iDrive].imagename, g_HardDisk[iDrive].fullname); + Snapshot_UpdatePath(); } HD_SaveLastDiskImage(iDrive); @@ -474,7 +503,10 @@ bool HD_Select(const int iDrive) void HD_Unplug(const int iDrive) { if (g_HardDisk[iDrive].hd_imageloaded) + { HD_CleanupDrive(iDrive); + Snapshot_UpdatePath(); + } } bool HD_IsDriveUnplugged(const int iDrive) diff --git a/source/Harddisk.h b/source/Harddisk.h index 4fec7099..264751aa 100644 --- a/source/Harddisk.h +++ b/source/Harddisk.h @@ -35,6 +35,7 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA void HD_SetEnabled(const bool bEnabled); const std::string & HD_GetFullName(const int iDrive); const std::string & HD_GetFullPathName(const int iDrive); + void HD_GetFilenameAndPathForSaveState(std::string& filename, std::string& path); void HD_Reset(void); void HD_Load_Rom(const LPBYTE pCxRomPeripheral, const UINT uSlot); bool HD_Select(const int iDrive); diff --git a/source/SaveState.cpp b/source/SaveState.cpp index 2fabd05d..70cbe173 100644 --- a/source/SaveState.cpp +++ b/source/SaveState.cpp @@ -80,19 +80,18 @@ static YamlHelper yamlHelper; //----------------------------------------------------------------------------- -void Snapshot_SetFilename(const std::string & strPathname) +static void Snapshot_SetPathname(const std::string& strPathname) { if (strPathname.empty()) { g_strSaveStateFilename = DEFAULT_SNAPSHOT_NAME; g_strSaveStatePathname = g_sCurrentDir; - if (g_strSaveStatePathname.length() && g_strSaveStatePathname[g_strSaveStatePathname.length()-1] != '\\') + if (!g_strSaveStatePathname.empty() && *g_strSaveStatePathname.rbegin() != '\\') g_strSaveStatePathname += "\\"; g_strSaveStatePathname.append(DEFAULT_SNAPSHOT_NAME); g_strSaveStatePath = g_sCurrentDir; - return; } @@ -100,7 +99,7 @@ void Snapshot_SetFilename(const std::string & strPathname) g_strSaveStatePath.clear(); int nIdx = strPathname.find_last_of('\\'); - if (nIdx >= 0 && nIdx+1 < (int)strPathname.length()) + if (nIdx >= 0 && nIdx+1 < (int)strPathname.length()) // path exists? { strFilename = &strPathname[nIdx+1]; g_strSaveStatePath = strPathname.substr(0, nIdx+1); // Bugfix: 1.25.0.2 // Snapshot_LoadState() -> SetCurrentImageDir() -> g_sCurrentDir @@ -110,16 +109,64 @@ void Snapshot_SetFilename(const std::string & strPathname) g_strSaveStatePathname = strPathname; } -const std::string & Snapshot_GetFilename() +void Snapshot_SetFilename(const std::string& filename, const std::string& path/*=""*/) +{ + if (path.empty()) + return Snapshot_SetPathname(filename); + + _ASSERT(filename.find('\\') == std::string::npos); // since we have a path, then filename mustn't contain a path too! + + // Ensure path is suffixed with '\' before adding filename + std::string pathname = path; + if (*pathname.rbegin() != '\\') + pathname += "\\"; + + Snapshot_SetPathname(pathname+filename); +} + +const std::string& Snapshot_GetFilename(void) { return g_strSaveStateFilename; } -const std::string & Snapshot_GetPath() +const std::string& Snapshot_GetPath(void) { return g_strSaveStatePath; } +const std::string& Snapshot_GetPathname(void) +{ + return g_strSaveStatePathname; +} + +// Called on successful insertion and on prompting to save/load a save-state +void Snapshot_GetDefaultFilenameAndPath(std::string& defaultFilename, std::string& defaultPath) +{ + // Attempt to get a default filename/path based on harddisk plugged-in or floppy disk inserted + // . Priority given to harddisk over floppy images + HD_GetFilenameAndPathForSaveState(defaultFilename, defaultPath); + if (defaultFilename.empty()) + GetCardMgr().GetDisk2CardMgr().GetFilenameAndPathForSaveState(defaultFilename, defaultPath); +} + +// Called by Disk2InterfaceCard::InsertDisk() and HD_Insert() after a successful insertion +// Called by Disk2InterfaceCard::EjectDisk() and HD_Unplug() +// Called by RepeatInitialization() when Harddisk Controller card is disabled +void Snapshot_UpdatePath(void) +{ + std::string defaultFilename; + std::string defaultPath; + Snapshot_GetDefaultFilenameAndPath(defaultFilename, defaultPath); + + if (defaultPath.empty() || g_strSaveStatePath == defaultPath) + return; + + if (!defaultFilename.empty()) + defaultFilename += ".aws.yaml"; + + Snapshot_SetFilename(defaultFilename, defaultPath); +} + //----------------------------------------------------------------------------- static HANDLE m_hFile = INVALID_HANDLE_VALUE; diff --git a/source/SaveState.h b/source/SaveState.h index aac842c6..78b6d12d 100644 --- a/source/SaveState.h +++ b/source/SaveState.h @@ -2,9 +2,12 @@ extern bool g_bSaveStateOnExit; -void Snapshot_SetFilename(const std::string & strPathname); -const std::string & Snapshot_GetFilename(); -const std::string & Snapshot_GetPath(); +void Snapshot_SetFilename(const std::string& filename, const std::string& path=""); +const std::string& Snapshot_GetFilename(void); +const std::string& Snapshot_GetPath(void); +const std::string& Snapshot_GetPathname(void); +void Snapshot_GetDefaultFilenameAndPath(std::string& defaultFilename, std::string& defaultPath); +void Snapshot_UpdatePath(void); void Snapshot_LoadState(); void Snapshot_SaveState(); void Snapshot_Startup();