Skip to content

Commit

Permalink
Improved determining path & filename when saving/loading a save-state (
Browse files Browse the repository at this point in the history
…#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.
  • Loading branch information
tomcw committed Oct 25, 2020
1 parent aa322db commit 43455eb
Show file tree
Hide file tree
Showing 16 changed files with 207 additions and 140 deletions.
2 changes: 1 addition & 1 deletion help/CommandLine.html
Expand Up @@ -61,7 +61,7 @@ <h2 style="COLOR: rgb(0,128,0)">Command line</h2>
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.<br><br>
-load-state &lt;savestate&gt;<br>
Load a save-state file (and auto power-on the Apple II).<br>
NB. This takes precedent over the -d1, -d2, -d#s#, -h1, -h2, s0-7, -model and -r switches.<br><br>
NB. This takes precedent over the -d1, -d2, -s#d#, -h1, -h2, s0-7, -model and -r switches.<br><br>
-f<br>
Start in full-screen mode<br><br>
-fs-height=&lt;best|nnnn&gt;<br>
Expand Down
38 changes: 25 additions & 13 deletions source/Applewin.cpp
Expand Up @@ -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);
Expand All @@ -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);
Expand All @@ -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

Expand All @@ -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()) )
Expand Down Expand Up @@ -1176,6 +1179,12 @@ static bool DoDiskInsert(const UINT slot, const int nDrive, LPCSTR szFileName)
{
Disk2InterfaceCard& disk2Card = dynamic_cast<Disk2InterfaceCard&>(GetCardMgr().GetRef(slot));

if (szFileName[0] == '\0')
{
disk2Card.EjectDisk(nDrive);
return true;
}

std::string strPathName = GetFullPath(szFileName);
if (strPathName.empty()) return false;

Expand All @@ -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;

Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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);
Expand All @@ -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
Expand Down
2 changes: 1 addition & 1 deletion source/CardManager.h
Expand Up @@ -29,7 +29,7 @@ class CardManager

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(slot<NUM_SLOTS); return m_slot[slot]->QueryType(); }
Card& GetRef(UINT slot)
{
SS_CARDTYPE t=QuerySlot(slot); _ASSERT((t==CT_SSC || t==CT_MouseInterface || t==CT_Disk2) && m_slot[slot]);
Expand Down
15 changes: 2 additions & 13 deletions source/Configuration/PageAdvanced.cpp
Expand Up @@ -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);

Expand All @@ -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();
}

Expand Down
17 changes: 16 additions & 1 deletion source/Configuration/PageDisk.cpp
Expand Up @@ -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;
Expand Down Expand Up @@ -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())
{
Expand Down
2 changes: 0 additions & 2 deletions source/Configuration/PropertySheet.cpp
Expand Up @@ -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))
{
Expand Down
115 changes: 22 additions & 93 deletions source/Configuration/PropertySheetHelper.cpp
Expand Up @@ -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;
Expand All @@ -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)

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;
}
int nRes = GetOpenFileName(&ofn);
if (nRes) // OK is pressed
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);
}
}

void CPropertySheetHelper::GetDiskBaseNameWithAWS(std::string & pszFilename)
{
if (GetCardMgr().QuerySlot(SLOT6) != CT_Disk2)
return;

const std::string& diskName = dynamic_cast<Disk2InterfaceCard&>(GetCardMgr().GetRef(SLOT6)).GetBaseName(DRIVE_1);
if (!diskName.empty())
{
pszFilename = diskName + ".aws.yaml";
Snapshot_SetFilename(m_szSSNewFilename, m_szSSNewDirectory);
RegSaveString(TEXT(REG_CONFIG), TEXT(REGVALUE_SAVESTATE_FILENAME), 1, Snapshot_GetPathname());
}
}

// 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");
TEXT("All Files\0*.*\0");
}
else
{
ofn.lpstrFilter = TEXT("Save State files (*.aws,*.aws.yaml)\0*.aws;*.aws.yaml\0");
ofn.lpstrFilter = TEXT("Save State files (*.aws.yaml)\0*.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)
{
Expand Down Expand Up @@ -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;
Expand Down
4 changes: 0 additions & 4 deletions source/Configuration/PropertySheetHelper.h
Expand Up @@ -30,7 +30,6 @@ class CPropertySheetHelper

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; }
Expand All @@ -49,15 +48,12 @@ class CPropertySheetHelper
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;
Expand Down

0 comments on commit 43455eb

Please sign in to comment.