mirror of
https://github.com/AppleWin/AppleWin.git
synced 2026-10-25 14:03:18 +00:00
1. Registry functions The set of functions are changed to consistently use bool arguments. The macros are changed to inline functions to improve type checking. RegSaveValue() are overloaded with help of templates to reduce typecasting at call sites. For instance, bool value would be converted consistently instead of relying on call sites to convert bool to int values. 2. Memory functions BOOL usages were unnecessary. Mostly internal usages which can simply be bool. 3. FrameBase Some member variables are changed to bool. BOOL was used because of those Registry functions. Additional changes: - Some expressions are forced to be bool when assigning to bool variables.
660 lines
21 KiB
C++
660 lines
21 KiB
C++
/*
|
|
AppleWin : An Apple //e emulator for Windows
|
|
|
|
Copyright (C) 1994-1996, Michael O'Brien
|
|
Copyright (C) 1999-2001, Oliver Schmidt
|
|
Copyright (C) 2002-2005, Tom Charlesworth
|
|
Copyright (C) 2006-2012, Tom Charlesworth, Michael Pohoreski
|
|
|
|
AppleWin is free software; you can redistribute it and/or modify
|
|
it under the terms of the GNU General Public License as published by
|
|
the Free Software Foundation; either version 2 of the License, or
|
|
(at your option) any later version.
|
|
|
|
AppleWin is distributed in the hope that it will be useful,
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
GNU General Public License for more details.
|
|
|
|
You should have received a copy of the GNU General Public License
|
|
along with AppleWin; if not, write to the Free Software
|
|
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|
*/
|
|
|
|
#include "StdAfx.h"
|
|
|
|
#include "PropertySheet.h"
|
|
#include "PropertySheetHelper.h"
|
|
|
|
#include "../Windows/AppleWin.h" // g_nAppMode, g_uScrollLockToggle, sg_PropertySheet
|
|
#include "../CardManager.h"
|
|
#include "../Memory.h"
|
|
#include "../Disk.h"
|
|
#include "../Log.h"
|
|
#include "../Registry.h"
|
|
#include "../SaveState.h"
|
|
#include "../Interface.h"
|
|
#include "../Uthernet2.h"
|
|
#include "../Tfe/PCapBackend.h"
|
|
|
|
/*
|
|
Config causing AfterClose msgs:
|
|
===============================
|
|
|
|
Page: Action: Comment:
|
|
------------------------------------------------------------------------
|
|
Config
|
|
. Computer WM_USER_RESTART
|
|
. Video frequency WM_USER_RESTART
|
|
Slot
|
|
. <Slot change> WM_USER_RESTART
|
|
. <Card config change> WM_USER_RESTART Depends on change
|
|
Advanced
|
|
. Save State WM_USER_SAVESTATE
|
|
. Load State WM_USER_LOADSTATE
|
|
. Clone WM_USER_RESTART
|
|
. MrFreeze Rom WM_USER_RESTART
|
|
. Benchmark PSBTN_OK -> WM_USER_BENCHMARK Forces PSBTN_OK
|
|
|
|
Requirements:
|
|
-------------
|
|
. Want to change multiple HW at once.
|
|
. Allow change Computer & Load State (ie. multiple AfterClose msgs)
|
|
|
|
Design:
|
|
-------
|
|
. At PropSheet init, copy original config state (for above items)
|
|
. On last Page close, compare new config state, if changed:
|
|
- Show 1 restart + confirm msg (if necessary)
|
|
- Cancel will rollback to original config (for above items), but other items will be applied
|
|
. Load State button
|
|
- Don't action it immediately.
|
|
- .aws should contain config (but doesn't), so should override any config changes.
|
|
- so this can just discard any config changes
|
|
- if any config change, then show msg box to say they won't be applied
|
|
. Save State button
|
|
- Don't action it immediately.
|
|
- save state applies to current config (prior to restart).
|
|
- so this can just discard any config changes
|
|
- if any config change, then show msg box to say they won't be applied
|
|
. Benchmark button
|
|
- Action it immediately.
|
|
- If config has changed:
|
|
- Prompt to either do benchmark (and lose new config) or cancel benchmark (and drop back to Configuration dialog).
|
|
*/
|
|
|
|
void CPropertySheetHelper::FillComboBox(HWND window, int controlid, LPCTSTR choices, int currentchoice)
|
|
{
|
|
_ASSERT(choices);
|
|
HWND combowindow = GetDlgItem(window, controlid);
|
|
SendMessage(combowindow, CB_RESETCONTENT, 0, 0);
|
|
while (choices && *choices)
|
|
{
|
|
SendMessage(combowindow, CB_ADDSTRING, 0, (LPARAM)(LPCTSTR)choices);
|
|
choices += strlen(choices)+1;
|
|
}
|
|
|
|
if (SendMessage(combowindow, CB_SETCURSEL, currentchoice, 0) == CB_ERR && currentchoice != -1)
|
|
{
|
|
_ASSERT(0);
|
|
SendMessage(combowindow, CB_SETCURSEL, 0, 0); // GH#434: Failed to set currentchoice, so select item-0
|
|
}
|
|
}
|
|
|
|
void CPropertySheetHelper::SaveComputerType(eApple2Type NewApple2Type)
|
|
{
|
|
if (NewApple2Type == A2TYPE_CLONE) // Clone picked from Config tab, but no specific one picked from Advanced tab
|
|
NewApple2Type = A2TYPE_PRAVETS82;
|
|
|
|
ConfigSaveApple2Type(NewApple2Type);
|
|
}
|
|
|
|
void CPropertySheetHelper::ConfigSaveApple2Type(eApple2Type apple2Type)
|
|
{
|
|
REGSAVE(REGVALUE_APPLE2_TYPE, apple2Type);
|
|
LogFileOutput("Config: Apple2 Type changed to %d\n", apple2Type);
|
|
}
|
|
|
|
void CPropertySheetHelper::SaveCpuType(eCpuType NewCpuType)
|
|
{
|
|
REGSAVE(REGVALUE_CPU_TYPE, NewCpuType);
|
|
}
|
|
|
|
void CPropertySheetHelper::SetSlot(UINT slot, SS_CARDTYPE newCardType)
|
|
{
|
|
if (slot <= SLOT7)
|
|
{
|
|
if (GetCardMgr().QuerySlot(slot) == newCardType)
|
|
return;
|
|
|
|
GetCardMgr().Insert(slot, newCardType);
|
|
}
|
|
else if (slot == SLOT_AUX)
|
|
{
|
|
if (GetCardMgr().QueryAux() == newCardType)
|
|
return;
|
|
|
|
GetCardMgr().InsertAux(newCardType);
|
|
}
|
|
else
|
|
{
|
|
_ASSERT(0);
|
|
}
|
|
}
|
|
|
|
// Used by:
|
|
// . CPageAdvanced: IDC_CIDERPRESS_BROWSE
|
|
// . CPageSlots: IDC_PRINTER_DUMP_FILENAME_BROWSE
|
|
std::string CPropertySheetHelper::BrowseToFile(HWND hWindow, const char* pszTitle, const char* REGVALUE, const char* FILEMASKS)
|
|
{
|
|
char szFilename[MAX_PATH];
|
|
RegLoadString(REG_CONFIG, REGVALUE, true, szFilename, MAX_PATH, "");
|
|
std::string pathname = szFilename;
|
|
|
|
OPENFILENAME ofn;
|
|
memset(&ofn, 0, sizeof(OPENFILENAME));
|
|
|
|
ofn.lStructSize = sizeof(OPENFILENAME);
|
|
ofn.hwndOwner = hWindow;
|
|
ofn.hInstance = GetFrame().g_hInstance;
|
|
ofn.lpstrFilter = FILEMASKS;
|
|
/*ofn.lpstrFilter = "Applications (*.exe)\0*.exe\0"
|
|
"Text files (*.txt)\0*.txt\0"
|
|
"All Files\0*.*\0";*/
|
|
ofn.lpstrFile = szFilename;
|
|
ofn.nMaxFile = MAX_PATH;
|
|
ofn.lpstrInitialDir = "";
|
|
ofn.Flags = OFN_PATHMUSTEXIST | OFN_HIDEREADONLY;
|
|
ofn.lpstrTitle = pszTitle;
|
|
|
|
int nRes = GetOpenFileName(&ofn);
|
|
if (nRes) // OK is pressed
|
|
pathname = szFilename;
|
|
|
|
return pathname;
|
|
}
|
|
|
|
void CPropertySheetHelper::SaveStateUpdate()
|
|
{
|
|
if (m_bSSNewFilename)
|
|
{
|
|
Snapshot_SetFilename(m_szSSNewFilename, m_szSSNewDirectory);
|
|
RegSaveString(REG_CONFIG, REGVALUE_SAVESTATE_FILENAME, true, Snapshot_GetPathname());
|
|
}
|
|
}
|
|
|
|
// NB. OK'ing this property sheet will call SaveStateUpdate()->Snapshot_SetFilename() with this new path & filename
|
|
int CPropertySheetHelper::SaveStateSelectImage(HWND hWindow, const char* pszTitle, bool bSave)
|
|
{
|
|
// 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.
|
|
|
|
std::string szDirectory = Snapshot_GetPath();
|
|
if (szDirectory.empty())
|
|
szDirectory = g_sCurrentDir;
|
|
|
|
char szFilename[MAX_PATH];
|
|
strcpy(szFilename, Snapshot_GetFilename().c_str());
|
|
|
|
//
|
|
|
|
OPENFILENAME ofn;
|
|
memset(&ofn, 0, sizeof(OPENFILENAME));
|
|
|
|
ofn.lStructSize = sizeof(OPENFILENAME);
|
|
ofn.hwndOwner = hWindow;
|
|
ofn.hInstance = GetFrame().g_hInstance;
|
|
ofn.lpstrFilter = "Save State files (*.aws.yaml)\0*.aws.yaml\0"
|
|
"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 = 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 (bSave) // Only for saving (allow loading of any file for backwards compatibility)
|
|
{
|
|
// Append .aws.yaml if it's not there
|
|
const char szAWS_EXT1[] = ".aws";
|
|
const char szAWS_EXT2[] = ".yaml";
|
|
const char szAWS_EXT3[] = ".aws.yaml";
|
|
const size_t uStrLenFile = strlen(&szFilename[ofn.nFileOffset]);
|
|
const size_t uStrLenExt1 = strlen(szAWS_EXT1);
|
|
const size_t uStrLenExt2 = strlen(szAWS_EXT2);
|
|
const size_t uStrLenExt3 = strlen(szAWS_EXT3);
|
|
if (uStrLenFile <= uStrLenExt1)
|
|
{
|
|
strcpy(&szFilename[ofn.nFileOffset+uStrLenFile], szAWS_EXT3); // "file" += ".aws.yaml"
|
|
}
|
|
else if (uStrLenFile <= uStrLenExt2)
|
|
{
|
|
if (strcmp(&szFilename[ofn.nFileOffset+uStrLenFile-uStrLenExt1], szAWS_EXT1) == 0)
|
|
strcpy(&szFilename[ofn.nFileOffset+uStrLenFile-uStrLenExt1], szAWS_EXT3); // "file.aws" -> "file" + ".aws.yaml"
|
|
else
|
|
strcpy(&szFilename[ofn.nFileOffset+uStrLenFile], szAWS_EXT3); // "file" += ".aws.yaml"
|
|
}
|
|
else if ((uStrLenFile <= uStrLenExt3) || (strcmp(&szFilename[ofn.nFileOffset+uStrLenFile-uStrLenExt3], szAWS_EXT3) != 0))
|
|
{
|
|
if (strcmp(&szFilename[ofn.nFileOffset+uStrLenFile-uStrLenExt1], szAWS_EXT1) == 0)
|
|
strcpy(&szFilename[ofn.nFileOffset+uStrLenFile-uStrLenExt1], szAWS_EXT3); // "file.aws" -> "file" + ".aws.yaml"
|
|
else if (strcmp(&szFilename[ofn.nFileOffset+uStrLenFile-uStrLenExt2], szAWS_EXT2) == 0)
|
|
strcpy(&szFilename[ofn.nFileOffset+uStrLenFile-uStrLenExt2], szAWS_EXT3); // "file.yaml" -> "file" + ".aws.yaml"
|
|
else
|
|
strcpy(&szFilename[ofn.nFileOffset+uStrLenFile], szAWS_EXT3); // "file" += ".aws.yaml"
|
|
}
|
|
}
|
|
|
|
m_szSSNewFilename = &szFilename[ofn.nFileOffset];
|
|
|
|
szFilename[ofn.nFileOffset] = 0;
|
|
m_szSSNewDirectory = szFilename; // always set this, even if unchanged
|
|
}
|
|
|
|
m_bSSNewFilename = nRes ? true : false;
|
|
return nRes;
|
|
}
|
|
|
|
// On OK: Optionally post a single "uAfterClose" msg after last page closes
|
|
void CPropertySheetHelper::PostMsgAfterClose(HWND hWnd, PAGETYPE page)
|
|
{
|
|
m_bmPages &= ~(1<<(UINT32)page);
|
|
if (m_bmPages)
|
|
return; // Still pages to close
|
|
|
|
//
|
|
|
|
if (m_ConfigNew.m_uSaveLoadStateMsg && IsConfigChangedForRestart() && IsOkToSaveLoadState(hWnd))
|
|
{
|
|
// Drop any config changes, and do load/save state
|
|
PostMessage(GetFrame().g_hFrameWindow, m_ConfigNew.m_uSaveLoadStateMsg, 0, 0);
|
|
return;
|
|
}
|
|
|
|
if (m_bDoBenchmark)
|
|
{
|
|
// Drop any config changes, and do benchmark
|
|
PostMessage(GetFrame().g_hFrameWindow, WM_USER_BENCHMARK, 0, 0); // NB. doesn't do WM_USER_RESTART
|
|
return;
|
|
}
|
|
|
|
if (m_ConfigNew.m_Apple2Type == A2TYPE_CLONE)
|
|
{
|
|
MessageBox(hWnd, "Error - Unable to change configuration\n\nReason: A specific clone wasn't selected from the Advanced tab", g_pAppTitle.c_str(), MB_ICONSTOP | MB_SETFOREGROUND);
|
|
return;
|
|
}
|
|
|
|
_ASSERT(m_ConfigNew.m_CpuType != CPU_UNKNOWN); // NB. Could only ever be CPU_UNKNOWN for a clone (and only if a mistake was made when adding a new clone)
|
|
if (m_ConfigNew.m_CpuType == CPU_UNKNOWN)
|
|
{
|
|
m_ConfigNew.m_CpuType = ProbeMainCpuDefault(m_ConfigNew.m_Apple2Type);
|
|
}
|
|
|
|
bool restart = false;
|
|
|
|
if (IsConfigChangedForRestart()) // Only for config that requires a restart
|
|
{
|
|
if (!HardwareConfigChanged(hWnd))
|
|
return; // Cancelled
|
|
|
|
if (!IsOkToRestart(hWnd))
|
|
return; // Cancelled
|
|
|
|
ApplyNewConfigForRestart();
|
|
restart = true;
|
|
}
|
|
|
|
GetPropertySheet().ApplyConfigAfterClose(m_bmAfterClosePages); // For config that does NOT require a restart
|
|
|
|
if (restart)
|
|
GetFrame().Restart();
|
|
}
|
|
|
|
#define CONFIG_CHANGED(var) \
|
|
(m_ConfigOld.var != m_ConfigNew.var)
|
|
|
|
// Apply changes to Registry
|
|
void CPropertySheetHelper::ApplyNewConfigForRestart()
|
|
{
|
|
if (CONFIG_CHANGED(m_Apple2Type))
|
|
SaveComputerType(m_ConfigNew.m_Apple2Type);
|
|
|
|
if (CONFIG_CHANGED(m_CpuType))
|
|
SaveCpuType(m_ConfigNew.m_CpuType);
|
|
|
|
// For all slots (except aux) that have changed:
|
|
// . first empty them
|
|
// . then insert the new card
|
|
// Reason: s1=empty, s2=SSC -> s1=SSC, s2=empty
|
|
// . if we just insert, then we'll go via the intermediate state of "s1=SSC, s2=SSC" - but only 1 instance of SSC is permitted
|
|
for (UINT slot = SLOT0; slot < NUM_SLOTS; slot++)
|
|
{
|
|
if (CONFIG_CHANGED(m_Slot[slot]))
|
|
SetSlot(slot, CT_Empty);
|
|
}
|
|
|
|
for (UINT slot = SLOT0; slot < NUM_SLOTS; slot++)
|
|
{
|
|
if (CONFIG_CHANGED(m_Slot[slot]))
|
|
SetSlot(slot, m_ConfigNew.m_Slot[slot]);
|
|
|
|
// Keep going, as card may not have changed, but card's config could have
|
|
|
|
if (m_ConfigNew.m_Slot[slot] == CT_Disk2)
|
|
{
|
|
if (CONFIG_CHANGED(m_diskII13SectorFirmware[slot]))
|
|
dynamic_cast<Disk2InterfaceCard&>(GetCardMgr().GetRef(slot)).Set13SectorFirmware(m_ConfigNew.m_diskII13SectorFirmware[slot]);
|
|
}
|
|
|
|
if (m_ConfigNew.m_Slot[slot] == CT_GenericHDD)
|
|
{
|
|
if (CONFIG_CHANGED(m_hdcFirmware[slot]))
|
|
dynamic_cast<HarddiskInterfaceCard&>(GetCardMgr().GetRef(slot)).SetHdcFirmwareMode(m_ConfigNew.m_hdcFirmware[slot]);
|
|
}
|
|
|
|
if (m_ConfigNew.m_Slot[slot] == CT_Uthernet || m_ConfigNew.m_Slot[slot] == CT_Uthernet2)
|
|
{
|
|
// NB. Assume we don't have both cards inserted
|
|
PCapBackend::SetRegistryInterface(slot, m_ConfigNew.m_tfeInterface);
|
|
Uthernet2::SetRegistryVirtualDNS(slot, m_ConfigNew.m_tfeVirtualDNS);
|
|
}
|
|
|
|
if (m_ConfigNew.m_Slot[slot] == CT_SSC)
|
|
{
|
|
if (CONFIG_CHANGED(m_serialPortItem))
|
|
GetCardMgr().GetSSC()->RescanCOMPortsAndSetSerialPortItem(m_ConfigNew.m_serialPortItem);
|
|
}
|
|
|
|
if (m_ConfigNew.m_Slot[slot] == CT_Saturn128K)
|
|
{
|
|
if (CONFIG_CHANGED(m_SaturnMemorySize[slot]))
|
|
dynamic_cast<Saturn128K&>(GetCardMgr().GetRef(slot)).SetSaturnMemorySize(m_ConfigNew.m_SaturnMemorySize[slot]);
|
|
}
|
|
|
|
if (m_ConfigNew.m_Slot[slot] == CT_MockingboardC || m_ConfigNew.m_Slot[slot] == CT_Phasor)
|
|
{
|
|
if (CONFIG_CHANGED(m_Mockingboard[slot].ssi263A))
|
|
dynamic_cast<MockingboardCard&>(GetCardMgr().GetRef(slot)).SetSocketSSI263(0, m_ConfigNew.m_Mockingboard[slot].ssi263A);
|
|
if (CONFIG_CHANGED(m_Mockingboard[slot].ssi263B))
|
|
dynamic_cast<MockingboardCard&>(GetCardMgr().GetRef(slot)).SetSocketSSI263(1, m_ConfigNew.m_Mockingboard[slot].ssi263B);
|
|
if (CONFIG_CHANGED(m_Mockingboard[slot].sc01))
|
|
dynamic_cast<MockingboardCard&>(GetCardMgr().GetRef(slot)).SetSocketSC01(m_ConfigNew.m_Mockingboard[slot].sc01);
|
|
}
|
|
}
|
|
|
|
if (CONFIG_CHANGED(m_SlotAux))
|
|
{
|
|
SetApple2Type(m_ConfigNew.m_Apple2Type); // Needed by InsertAux()
|
|
SetSlot(SLOT_AUX, m_ConfigNew.m_SlotAux);
|
|
}
|
|
|
|
if (CONFIG_CHANGED(m_RamWorksMemorySize))
|
|
SetRamWorksMemorySize(m_ConfigNew.m_RamWorksMemorySize);
|
|
|
|
if (CONFIG_CHANGED(m_videoRefreshRate))
|
|
REGSAVE(REGVALUE_VIDEO_REFRESH_RATE, m_ConfigNew.m_videoRefreshRate);
|
|
|
|
if (CONFIG_CHANGED(m_enableTheFreezesF8Rom))
|
|
REGSAVE(REGVALUE_THE_FREEZES_F8_ROM, m_ConfigNew.m_enableTheFreezesF8Rom);
|
|
|
|
if (CONFIG_CHANGED(m_NoSlotClock))
|
|
REGSAVE(REGVALUE_NO_SLOT_CLOCK, m_ConfigNew.m_NoSlotClock);
|
|
}
|
|
|
|
// Called from Snapshot_LoadState_v2()
|
|
// . A convenient way to save newly loaded state to Registry
|
|
void CPropertySheetHelper::ApplyNewConfigFromSnapshot()
|
|
{
|
|
CConfigNeedingRestart config;
|
|
config.Reload();
|
|
|
|
SaveComputerType(config.m_Apple2Type);
|
|
SaveCpuType(config.m_CpuType);
|
|
|
|
for (UINT slot = SLOT0; slot < NUM_SLOTS; slot++)
|
|
{
|
|
// if (config.m_Slot[slot] == CT_Disk2)
|
|
// dynamic_cast<Disk2InterfaceCard&>(GetCardMgr().GetRef(slot)).Set13SectorFirmware(config.m_diskII13SectorFirmware[slot]); // Not currently in save-state
|
|
|
|
// if (config.m_Slot[slot] == CT_GenericHDD)
|
|
// dynamic_cast<HarddiskInterfaceCard&>(GetCardMgr().GetRef(slot)).SetHdcFirmwareMode(config.m_hdcFirmware[slot]); // Not currently in save-state
|
|
|
|
if (config.m_Slot[slot] == CT_Saturn128K)
|
|
dynamic_cast<Saturn128K&>(GetCardMgr().GetRef(slot)).SetSaturnMemorySize(config.m_SaturnMemorySize[slot]);
|
|
|
|
if (config.m_Slot[slot] == CT_MockingboardC || config.m_Slot[slot] == CT_Phasor)
|
|
{
|
|
dynamic_cast<MockingboardCard&>(GetCardMgr().GetRef(slot)).SetSocketSSI263(0, config.m_Mockingboard[slot].ssi263A);
|
|
dynamic_cast<MockingboardCard&>(GetCardMgr().GetRef(slot)).SetSocketSSI263(1, config.m_Mockingboard[slot].ssi263B);
|
|
dynamic_cast<MockingboardCard&>(GetCardMgr().GetRef(slot)).SetSocketSC01(config.m_Mockingboard[slot].sc01);
|
|
}
|
|
}
|
|
|
|
SetRamWorksMemorySize(config.m_RamWorksMemorySize);
|
|
REGSAVE(REGVALUE_VIDEO_REFRESH_RATE, config.m_videoRefreshRate);
|
|
//REGSAVE(REGVALUE_THE_FREEZES_F8_ROM, config.m_bEnableTheFreezesF8Rom); // Not currently in save-state
|
|
REGSAVE(REGVALUE_NO_SLOT_CLOCK, config.m_NoSlotClock);
|
|
}
|
|
|
|
// Called when PSPs are created
|
|
void CPropertySheetHelper::SaveCurrentConfig(void)
|
|
{
|
|
m_ConfigOld.Reload();
|
|
m_ConfigNew = m_ConfigOld; // Setup ConfigNew
|
|
|
|
// Reset flags each time:
|
|
m_bDoBenchmark = false;
|
|
}
|
|
|
|
bool CPropertySheetHelper::IsOkToSaveLoadState(HWND hWnd)
|
|
{
|
|
if (MessageBox(hWnd,
|
|
"The hardware configuration has changed. Save/Load state will lose these changes.\n\n"
|
|
"Are you sure you want to do this?",
|
|
REG_CONFIG,
|
|
MB_ICONQUESTION | MB_OKCANCEL | MB_SETFOREGROUND) == IDCANCEL)
|
|
return false;
|
|
|
|
return true;
|
|
}
|
|
|
|
bool CPropertySheetHelper::IsOkToRestart(HWND hWnd)
|
|
{
|
|
if (g_nAppMode == MODE_LOGO)
|
|
return true;
|
|
|
|
if (MessageBox(hWnd,
|
|
"Restarting the emulator will reset the state "
|
|
"of the emulated machine, causing you to lose any "
|
|
"unsaved work.\n\n"
|
|
"Are you sure you want to do this?",
|
|
REG_CONFIG,
|
|
MB_ICONQUESTION | MB_OKCANCEL | MB_SETFOREGROUND) == IDCANCEL)
|
|
return false;
|
|
|
|
return true;
|
|
}
|
|
|
|
bool CPropertySheetHelper::IsOkToResetConfig(HWND hWnd)
|
|
{
|
|
if (g_nAppMode == MODE_LOGO)
|
|
return true;
|
|
|
|
if (MessageBox(hWnd,
|
|
"Resetting configuration to the default values whilst the machine is being emulated "
|
|
"could result in loss of unsaved work, or corruption of floppy or hard disk images.\n\n"
|
|
"Are you sure you want to do this?",
|
|
"Reset Configuration",
|
|
MB_ICONEXCLAMATION | MB_OKCANCEL | MB_SETFOREGROUND) == IDCANCEL)
|
|
return false;
|
|
|
|
return true;
|
|
}
|
|
|
|
bool CPropertySheetHelper::HardwareConfigChanged(HWND hWnd)
|
|
{
|
|
std::string strMsg("The emulator needs to restart as the hardware configuration has changed:\n");
|
|
strMsg += "\n";
|
|
|
|
std::string strMsgMain;
|
|
{
|
|
if (CONFIG_CHANGED(m_Apple2Type))
|
|
strMsgMain += ". Emulated computer has changed\n";
|
|
|
|
if (CONFIG_CHANGED(m_CpuType))
|
|
strMsgMain += ". Emulated main CPU has changed\n";
|
|
|
|
if (CONFIG_CHANGED(m_videoRefreshRate))
|
|
strMsgMain += ". Video refresh rate has changed\n";
|
|
|
|
for (UINT slot = SLOT0; slot < NUM_SLOTS; slot++)
|
|
{
|
|
if (CONFIG_CHANGED(m_Slot[slot]))
|
|
strMsgMain += GetSlot(slot);
|
|
}
|
|
|
|
if (CONFIG_CHANGED(m_SlotAux))
|
|
strMsgMain += GetSlot(SLOT_AUX);
|
|
else if (m_ConfigNew.m_SlotAux == CT_RamWorksIII && CONFIG_CHANGED(m_RamWorksMemorySize))
|
|
strMsgMain += ". RamWorks III memory size changed\n";
|
|
|
|
if (memcmp(m_ConfigOld.m_SaturnMemorySize, m_ConfigNew.m_SaturnMemorySize, sizeof(m_ConfigOld.m_SaturnMemorySize)) != 0)
|
|
{
|
|
for (UINT slot = SLOT0; slot < NUM_SLOTS; slot++)
|
|
{
|
|
if (CONFIG_CHANGED(m_Slot[slot]))
|
|
continue;
|
|
|
|
if (CONFIG_CHANGED(m_SaturnMemorySize[slot]))
|
|
{
|
|
strMsgMain += ". Slot ";
|
|
strMsgMain += '0' + slot;
|
|
strMsgMain += ": ";
|
|
strMsgMain += "Saturn memory size has changed\n";
|
|
}
|
|
}
|
|
}
|
|
|
|
if (memcmp(m_ConfigOld.m_Mockingboard, m_ConfigNew.m_Mockingboard, sizeof(m_ConfigOld.m_Mockingboard)) != 0)
|
|
strMsgMain += ". Mockingboard/Phasor config has changed\n";
|
|
|
|
if (memcmp(m_ConfigOld.m_diskII13SectorFirmware, m_ConfigNew.m_diskII13SectorFirmware, sizeof(m_ConfigOld.m_diskII13SectorFirmware)) != 0)
|
|
strMsgMain += ". Disk II firmware has changed\n";
|
|
|
|
if (memcmp(m_ConfigOld.m_hdcFirmware, m_ConfigNew.m_hdcFirmware, sizeof(m_ConfigOld.m_hdcFirmware)) != 0)
|
|
strMsgMain += ". HDC firmware has changed\n";
|
|
|
|
if (CONFIG_CHANGED(m_tfeInterface))
|
|
strMsgMain += ". Uthernet interface has changed\n";
|
|
|
|
if (CONFIG_CHANGED(m_tfeVirtualDNS))
|
|
strMsgMain += ". Uthernet Virtual DNS has changed\n";
|
|
|
|
if (CONFIG_CHANGED(m_serialPortItem))
|
|
strMsgMain += ". SSC config has changed\n";
|
|
|
|
if (CONFIG_CHANGED(m_enableTheFreezesF8Rom))
|
|
strMsgMain += ". F8 ROM changed (The Freeze's F8 Rom)\n";
|
|
|
|
if (CONFIG_CHANGED(m_NoSlotClock))
|
|
strMsgMain += ". No-Slot clock has changed\n";
|
|
}
|
|
|
|
std::string strMsgPost("\n");
|
|
strMsgPost += "This change will not take effect until the next time you restart the emulator.\n\n";
|
|
strMsgPost += "Would you like to restart the emulator now?";
|
|
|
|
strMsg += strMsgMain;
|
|
strMsg += strMsgPost;
|
|
|
|
if (MessageBox(hWnd,
|
|
strMsg.c_str(),
|
|
REG_CONFIG,
|
|
MB_ICONQUESTION | MB_OKCANCEL | MB_SETFOREGROUND) == IDCANCEL)
|
|
return false;
|
|
|
|
return true;
|
|
}
|
|
|
|
std::string CPropertySheetHelper::GetSlot(const UINT slot)
|
|
{
|
|
std::string strMsg;
|
|
SS_CARDTYPE oldCardType, newCardType;
|
|
|
|
if (slot <= SLOT7)
|
|
{
|
|
// strMsg = ". Slot n: ";
|
|
strMsg = ". Slot ";
|
|
strMsg += '0' + slot;
|
|
strMsg += ": ";
|
|
|
|
oldCardType = m_ConfigOld.m_Slot[slot];
|
|
newCardType = m_ConfigNew.m_Slot[slot];
|
|
}
|
|
else if (slot == SLOT_AUX)
|
|
{
|
|
strMsg = ". Slot Aux: ";
|
|
|
|
oldCardType = m_ConfigOld.m_SlotAux;
|
|
newCardType = m_ConfigNew.m_SlotAux;
|
|
}
|
|
else
|
|
{
|
|
_ASSERT(0);
|
|
return "Error: Illegal Slot!";
|
|
}
|
|
|
|
if (oldCardType == CT_LanguageCardIIe || newCardType == CT_LanguageCardIIe)
|
|
{
|
|
// Switch model: II/II+ (slot 0) <-> //e (no slot 0)
|
|
if (newCardType == CT_LanguageCardIIe)
|
|
{
|
|
if (oldCardType != CT_Empty)
|
|
{
|
|
strMsg += Card::GetCardName(oldCardType);
|
|
strMsg += " card removed\n";
|
|
}
|
|
else
|
|
{
|
|
strMsg = "";
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if (newCardType != CT_Empty)
|
|
{
|
|
strMsg += Card::GetCardName(newCardType);
|
|
strMsg += " card added\n";
|
|
}
|
|
else
|
|
{
|
|
strMsg = "";
|
|
}
|
|
}
|
|
}
|
|
else if (oldCardType == CT_Empty || newCardType == CT_Empty)
|
|
{
|
|
if (newCardType == CT_Empty)
|
|
{
|
|
strMsg += Card::GetCardName(oldCardType);
|
|
strMsg += " card removed\n";
|
|
}
|
|
else
|
|
{
|
|
strMsg += Card::GetCardName(newCardType);
|
|
strMsg += " card added\n";
|
|
}
|
|
}
|
|
else
|
|
{
|
|
strMsg += Card::GetCardName(oldCardType);
|
|
strMsg += " card removed & ";
|
|
strMsg += Card::GetCardName(newCardType);
|
|
strMsg += " card added\n";
|
|
}
|
|
|
|
return strMsg;
|
|
}
|