mirror of
https://github.com/AppleWin/AppleWin.git
synced 2026-10-25 14:03:18 +00:00
1477 lines
45 KiB
C++
1477 lines
45 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-2014, Tom Charlesworth, Michael Pohoreski, Nick Westgate
|
|
|
|
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 "PageSlots.h"
|
|
#include "PropertySheet.h"
|
|
|
|
#include "../Common.h"
|
|
#include "../CardManager.h"
|
|
#include "../Disk.h"
|
|
#include "../Harddisk.h"
|
|
#include "../Interface.h"
|
|
#include "../Memory.h"
|
|
#include "../ParallelPrinter.h"
|
|
#include "../Registry.h"
|
|
#include "../SerialComms.h"
|
|
#include "../resource/resource.h"
|
|
#include "../Uthernet2.h"
|
|
#include "../Tfe/PCapBackend.h"
|
|
#include "../Windows/Win32Frame.h"
|
|
|
|
CPageSlots* CPageSlots::ms_this = nullptr; // reinit'd in ctor
|
|
UINT CPageSlots::ms_slot = 0;
|
|
|
|
const char CPageSlots::m_defaultDiskOptions[] =
|
|
"Select Disk...\0"
|
|
"Eject Disk\0";
|
|
|
|
const char CPageSlots::m_defaultHDDOptions[] =
|
|
"Select Hard Disk Image...\0"
|
|
"Unplug Hard Disk Image\0";
|
|
|
|
std::string CPageSlots::GetCardNameChoices(const std::vector<SS_CARDTYPE> &choicesList)
|
|
{
|
|
std::string choices;
|
|
for (const auto &card : choicesList)
|
|
{
|
|
choices += Card::GetCardName(card);
|
|
choices += '\0';
|
|
}
|
|
choices += '\0';
|
|
return choices;
|
|
}
|
|
|
|
INT_PTR CALLBACK CPageSlots::DlgProc(HWND hWnd, UINT message, WPARAM wparam, LPARAM lparam)
|
|
{
|
|
// Switch from static func to our instance
|
|
return CPageSlots::ms_this->DlgProcInternal(hWnd, message, wparam, lparam);
|
|
}
|
|
|
|
INT_PTR CPageSlots::DlgProcInternal(HWND hWnd, UINT message, WPARAM wparam, LPARAM lparam)
|
|
{
|
|
switch (message)
|
|
{
|
|
case WM_NOTIFY:
|
|
{
|
|
// Property Sheet notifications
|
|
|
|
switch (((LPPSHNOTIFY)lparam)->hdr.code)
|
|
{
|
|
case PSN_SETACTIVE:
|
|
// About to become the active page
|
|
m_PropertySheetHelper.SetLastPage(m_Page);
|
|
InitOptions(hWnd);
|
|
break;
|
|
case PSN_KILLACTIVE:
|
|
SetWindowLongPtr(hWnd, DWLP_MSGRESULT, FALSE); // Changes are valid
|
|
break;
|
|
case PSN_APPLY:
|
|
DlgOK(hWnd);
|
|
SetWindowLongPtr(hWnd, DWLP_MSGRESULT, PSNRET_NOERROR); // Changes are valid
|
|
break;
|
|
case PSN_QUERYCANCEL:
|
|
// Can use this to ask user to confirm cancel
|
|
break;
|
|
case PSN_RESET:
|
|
DlgCANCEL(hWnd);
|
|
break;
|
|
default:
|
|
return FALSE;
|
|
}
|
|
}
|
|
break;
|
|
|
|
case WM_COMMAND:
|
|
switch (LOWORD(wparam))
|
|
{
|
|
case IDC_SLOT0:
|
|
case IDC_SLOT1:
|
|
case IDC_SLOT2:
|
|
case IDC_SLOT3:
|
|
case IDC_SLOT4:
|
|
case IDC_SLOT5:
|
|
case IDC_SLOT6:
|
|
case IDC_SLOT7:
|
|
// Use CBN_CLOSEUP (instead of CBN_SELCHANGE - which fires for each cursor up/down)
|
|
if (HIWORD(wparam) == CBN_CLOSEUP)
|
|
{
|
|
const UINT slot = LOWORD(wparam) - IDC_SLOT0;
|
|
const uint32_t newChoiceItem = (uint32_t)SendDlgItemMessage(hWnd, LOWORD(wparam), CB_GETCURSEL, 0, 0);
|
|
|
|
SS_CARDTYPE newCard = CT_Empty;
|
|
if (newChoiceItem < m_choicesList[slot].size())
|
|
newCard = m_choicesList[slot][newChoiceItem];
|
|
else
|
|
_ASSERT(0);
|
|
|
|
if (m_PropertySheetHelper.GetConfigNew().m_Slot[slot] != newCard)
|
|
{
|
|
m_PropertySheetHelper.GetConfigNew().m_Slot[slot] = newCard;
|
|
ResetCardOptionsToDefault(slot);
|
|
InitOptions(hWnd);
|
|
}
|
|
}
|
|
break;
|
|
|
|
case IDC_SLOTAUX:
|
|
if (HIWORD(wparam) == CBN_SELCHANGE)
|
|
{
|
|
const uint32_t newChoiceItem = (uint32_t)SendDlgItemMessage(hWnd, LOWORD(wparam), CB_GETCURSEL, 0, 0);
|
|
|
|
SS_CARDTYPE newCard = CT_Empty;
|
|
if (newChoiceItem < m_choicesListAux.size())
|
|
newCard = m_choicesListAux[newChoiceItem];
|
|
else
|
|
_ASSERT(0);
|
|
|
|
if (m_PropertySheetHelper.GetConfigNew().m_SlotAux != newCard)
|
|
{
|
|
m_PropertySheetHelper.GetConfigNew().m_SlotAux = newCard;
|
|
ResetCardOptionsToDefault(SLOT_AUX);
|
|
InitOptions(hWnd); // Needed to enable/disable the options button (depending on card)
|
|
}
|
|
}
|
|
break;
|
|
|
|
case IDC_SLOT0_OPTION:
|
|
case IDC_SLOT1_OPTION:
|
|
case IDC_SLOT2_OPTION:
|
|
case IDC_SLOT3_OPTION:
|
|
case IDC_SLOT4_OPTION:
|
|
case IDC_SLOT5_OPTION:
|
|
case IDC_SLOT6_OPTION:
|
|
case IDC_SLOT7_OPTION:
|
|
{
|
|
ms_slot = LOWORD(wparam) - IDC_SLOT0_OPTION;
|
|
const SS_CARDTYPE cardInSlot = m_PropertySheetHelper.GetConfigNew().m_Slot[ms_slot];
|
|
|
|
if (!CardTypeHasOptions(cardInSlot))
|
|
break;
|
|
|
|
if (cardInSlot == CT_Disk2)
|
|
{
|
|
DialogBox(GetFrame().g_hInstance, (LPCTSTR)IDD_FLOPPY_DISK_DRIVES, hWnd, CPageSlots::DlgProcDisk2);
|
|
}
|
|
else if (cardInSlot == CT_GenericHDD)
|
|
{
|
|
DialogBox(GetFrame().g_hInstance, (LPCTSTR)IDD_HARD_DISK_DRIVES, hWnd, CPageSlots::DlgProcHarddisk);
|
|
}
|
|
else if (cardInSlot == CT_Uthernet || cardInSlot == CT_Uthernet2)
|
|
{
|
|
m_PageConfigTfe.m_enableVirtualDnsCheckbox = (cardInSlot == CT_Uthernet2);
|
|
DialogBox(GetFrame().g_hInstance, (LPCTSTR)IDD_TFE_SETTINGS_DIALOG, hWnd, CPageConfigTfe::DlgProc);
|
|
m_PropertySheetHelper.GetConfigNew().m_tfeInterface = m_PageConfigTfe.m_tfe_interface_name;
|
|
m_PropertySheetHelper.GetConfigNew().m_tfeVirtualDNS = m_PageConfigTfe.m_tfe_virtual_dns;
|
|
}
|
|
else if (cardInSlot == CT_SSC)
|
|
{
|
|
DialogBox(GetFrame().g_hInstance, (LPCTSTR)IDD_SSC, hWnd, CPageSlots::DlgProcSSC);
|
|
}
|
|
else if (cardInSlot == CT_GenericPrinter)
|
|
{
|
|
DialogBox(GetFrame().g_hInstance, (LPCTSTR)IDD_PRINTER, hWnd, CPageSlots::DlgProcPrinter);
|
|
}
|
|
else if (cardInSlot == CT_MouseInterface)
|
|
{
|
|
DialogBox(GetFrame().g_hInstance, (LPCTSTR)IDD_MOUSECARD, hWnd, CPageSlots::DlgProcMouseCard);
|
|
}
|
|
else if (cardInSlot == CT_Saturn128K)
|
|
{
|
|
DialogBox(GetFrame().g_hInstance, (LPCTSTR)IDD_SATURN, hWnd, CPageSlots::DlgProcSaturn);
|
|
}
|
|
else if (cardInSlot == CT_MockingboardC || cardInSlot == CT_Phasor)
|
|
{
|
|
DialogBox(GetFrame().g_hInstance, (LPCTSTR)IDD_MOCKINGBOARD, hWnd, CPageSlots::DlgProcMockingboard);
|
|
}
|
|
}
|
|
break;
|
|
|
|
case IDC_SLOTAUX_OPTION:
|
|
{
|
|
const SS_CARDTYPE cardInSlot = m_PropertySheetHelper.GetConfigNew().m_SlotAux;
|
|
|
|
if (!CardTypeHasOptions(cardInSlot))
|
|
break;
|
|
|
|
if (cardInSlot == CT_RamWorksIII)
|
|
{
|
|
DialogBox(GetFrame().g_hInstance, (LPCTSTR)IDD_RAMWORKS3, hWnd, CPageSlots::DlgProcRamWorks3);
|
|
}
|
|
}
|
|
break;
|
|
|
|
case IDC_SLOT_DEFAULT_CARDS:
|
|
if (!m_PropertySheetHelper.IsOkToResetConfig(hWnd))
|
|
break;
|
|
ResetToDefault();
|
|
InitOptions(hWnd);
|
|
break;
|
|
}
|
|
break;
|
|
|
|
case WM_INITDIALOG:
|
|
InitOptions(hWnd);
|
|
break;
|
|
|
|
default:
|
|
return FALSE;
|
|
}
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
int CPageSlots::CardTypeToComboItem(UINT slot)
|
|
{
|
|
int currentChoice = 0;
|
|
|
|
if (slot < NUM_SLOTS)
|
|
{
|
|
for (UINT i = 0; i < m_choicesList[slot].size(); i++)
|
|
if (m_PropertySheetHelper.GetConfigNew().m_Slot[slot] == m_choicesList[slot][i])
|
|
currentChoice = i;
|
|
}
|
|
else
|
|
{
|
|
_ASSERT(slot == SLOT_AUX);
|
|
for (UINT i = 0; i < m_choicesListAux.size(); i++)
|
|
if (m_PropertySheetHelper.GetConfigNew().m_SlotAux == m_choicesListAux[i])
|
|
currentChoice = i;
|
|
}
|
|
|
|
return currentChoice;
|
|
}
|
|
|
|
bool CPageSlots::CardTypeHasOptions(SS_CARDTYPE card)
|
|
{
|
|
switch (card)
|
|
{
|
|
case CT_Disk2:
|
|
case CT_GenericHDD:
|
|
case CT_SSC:
|
|
case CT_GenericPrinter:
|
|
case CT_MockingboardC:
|
|
case CT_MouseInterface:
|
|
case CT_Phasor:
|
|
case CT_Saturn128K:
|
|
case CT_Uthernet:
|
|
case CT_Uthernet2:
|
|
case CT_RamWorksIII:
|
|
return true;
|
|
default:
|
|
break;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
//
|
|
// For InitOptions(), DlgOK() and ApplyConfigAfterClose(), see comment in PageConfig.cpp about "Property Sheet Page flow"
|
|
//
|
|
|
|
void CPageSlots::InitOptions(HWND hWnd)
|
|
{
|
|
bool enable = false;
|
|
bool enableOpt = false;
|
|
|
|
SS_CARDTYPE currConfig[NUM_SLOTS];
|
|
for (int i = SLOT0; i < NUM_SLOTS; i++)
|
|
currConfig[i] = m_PropertySheetHelper.GetConfigNew().m_Slot[i];
|
|
|
|
for (int slot = SLOT0; slot < NUM_SLOTS; slot++)
|
|
{
|
|
if (slot == SLOT0 && IsAppleIIe(m_PropertySheetHelper.GetConfigNew().m_Apple2Type))
|
|
{
|
|
enable = false;
|
|
enableOpt = false;
|
|
}
|
|
else
|
|
{
|
|
GetCardMgr().GetCardChoicesForSlot(slot, currConfig, m_choicesList[slot]);
|
|
const std::string choices = GetCardNameChoices(m_choicesList[slot]);
|
|
int currentChoice = CardTypeToComboItem(slot);
|
|
m_PropertySheetHelper.FillComboBox(hWnd, IDC_SLOT0 + slot, choices.c_str(), currentChoice);
|
|
|
|
enable = true;
|
|
enableOpt = CardTypeHasOptions(m_PropertySheetHelper.GetConfigNew().m_Slot[slot]);
|
|
}
|
|
|
|
EnableWindow(GetDlgItem(hWnd, IDC_SLOT0 + slot), enable);
|
|
EnableWindow(GetDlgItem(hWnd, IDC_SLOT0_OPTION + slot), enableOpt);
|
|
}
|
|
|
|
if (IsAppleIIe(m_PropertySheetHelper.GetConfigNew().m_Apple2Type))
|
|
{
|
|
GetCardMgr().GetCardChoicesForAuxSlot(m_choicesListAux);
|
|
const std::string choices = GetCardNameChoices(m_choicesListAux);
|
|
int currentChoice = CardTypeToComboItem(SLOT_AUX);
|
|
m_PropertySheetHelper.FillComboBox(hWnd, IDC_SLOTAUX, choices.c_str(), currentChoice);
|
|
|
|
enable = true;
|
|
enableOpt = CardTypeHasOptions(m_PropertySheetHelper.GetConfigNew().m_SlotAux);
|
|
}
|
|
else
|
|
{
|
|
enable = false;
|
|
enableOpt = false;
|
|
}
|
|
|
|
EnableWindow(GetDlgItem(hWnd, IDC_SLOTAUX), enable);
|
|
EnableWindow(GetDlgItem(hWnd, IDC_SLOTAUX_OPTION), enableOpt);
|
|
|
|
//
|
|
|
|
// Find any Uthernet/Uthernet2 card and get its config
|
|
// NB. Assume we don't have both cards inserted - just use the 1st one we find
|
|
|
|
SS_CARDTYPE card = CT_Empty;
|
|
|
|
for (int slot = SLOT1; slot < NUM_SLOTS; slot++)
|
|
{
|
|
card = GetCardMgr().QuerySlot(slot);
|
|
if (card == CT_Uthernet || card == CT_Uthernet2)
|
|
{
|
|
m_PageConfigTfe.m_tfe_interface_name = PCapBackend::GetRegistryInterface(slot);
|
|
m_PageConfigTfe.m_tfe_virtual_dns = Uthernet2::GetRegistryVirtualDNS(slot);
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
void CPageSlots::DiskCardCleanup()
|
|
{
|
|
for (UINT i = DRIVE_1; i < NUM_DRIVES; i++)
|
|
m_PropertySheetHelper.GetConfigNew().m_disk2Card.EjectDisk(i); // close any open file handles
|
|
|
|
for (UINT i = HARDDISK_1; i < NUM_HARDDISKS; i++)
|
|
m_PropertySheetHelper.GetConfigNew().m_harddiskCard.Unplug(i); // close any open file handles
|
|
}
|
|
|
|
void CPageSlots::DlgCANCEL(HWND hWnd)
|
|
{
|
|
DiskCardCleanup();
|
|
}
|
|
|
|
void CPageSlots::DlgOK(HWND hWnd)
|
|
{
|
|
DiskCardCleanup();
|
|
m_PropertySheetHelper.PostMsgAfterClose(hWnd, m_Page);
|
|
}
|
|
|
|
void CPageSlots::ApplyConfigAfterClose()
|
|
{
|
|
// Disk II card
|
|
for (UINT slot = SLOT0; slot < NUM_SLOTS; slot++)
|
|
{
|
|
if (GetCardMgr().QuerySlot(slot) != CT_Disk2)
|
|
continue;
|
|
|
|
Disk2InterfaceCard& card = dynamic_cast<Disk2InterfaceCard&>(GetCardMgr().GetRef(slot));
|
|
for (UINT i = DRIVE_1; i < NUM_DRIVES; i++)
|
|
{
|
|
std::string pathname = m_PropertySheetHelper.GetConfigNew().m_slotInfoForFDC[slot].pathname[i];
|
|
|
|
if (card.DiskGetFullPathName(i) == pathname)
|
|
continue;
|
|
|
|
ImageError_e error = card.InsertDisk(i, pathname, false, false);
|
|
_ASSERT(error == eIMAGE_ERROR_NONE); // Should've already been rejected in HandleFloppyDriveCombo()
|
|
if (error != eIMAGE_ERROR_NONE)
|
|
card.NotifyInvalidImage(i, pathname, error);
|
|
}
|
|
}
|
|
|
|
GetFrame().FrameRefreshStatus(DRAW_BUTTON_DRIVES | DRAW_DISK_STATUS);
|
|
|
|
// Hard disk card
|
|
for (UINT slot = SLOT0; slot < NUM_SLOTS; slot++)
|
|
{
|
|
if (GetCardMgr().QuerySlot(slot) != CT_GenericHDD)
|
|
continue;
|
|
|
|
HarddiskInterfaceCard& card = dynamic_cast<HarddiskInterfaceCard&>(GetCardMgr().GetRef(slot));
|
|
for (UINT i = HARDDISK_1; i < NUM_HARDDISKS; i++)
|
|
{
|
|
const std::string& pathname = m_PropertySheetHelper.GetConfigNew().m_slotInfoForHDC[slot].pathname[i];
|
|
|
|
if (card.HarddiskGetFullPathName(i) == pathname)
|
|
continue;
|
|
|
|
bool error = card.Insert(i, pathname);
|
|
_ASSERT(error == true); // Should've already been rejected in HandleHDDCombo()
|
|
if (error != true)
|
|
card.NotifyInvalidImage(pathname);
|
|
}
|
|
}
|
|
|
|
// SSC
|
|
// . do any non-restart config changes here (none at the moment)
|
|
// . (A change to SerialPortName requires a restart)
|
|
|
|
// Parallel Printer card
|
|
CConfigNeedingRestart& config = const_cast<CConfigNeedingRestart&>(m_PropertySheetHelper.GetConfigNew());
|
|
config.m_parallelPrinterCard.SetRegistryConfig();
|
|
|
|
if (GetCardMgr().GetParallelPrinterCard())
|
|
*(GetCardMgr().GetParallelPrinterCard()) = config.m_parallelPrinterCard; // copy object
|
|
|
|
// Mouse card
|
|
m_mouseShowCrosshair = m_PropertySheetHelper.GetConfigNew().m_mouseShowCrosshair;
|
|
m_mouseRestrictToWindow = m_PropertySheetHelper.GetConfigNew().m_mouseRestrictToWindow;
|
|
REGSAVE(REGVALUE_MOUSE_CROSSHAIR, m_mouseShowCrosshair);
|
|
REGSAVE(REGVALUE_MOUSE_RESTRICT_TO_WINDOW, m_mouseRestrictToWindow);
|
|
|
|
// Mockingboard/Phasor card
|
|
// . do any non-restart config changes here (none at the moment)
|
|
// . (A change to ssi263A/ssi263B/sc01 requires a restart)
|
|
|
|
// RamWorks3 card
|
|
// . do any non-restart config changes here (none at the moment)
|
|
// . (A change to RamWorksMemorySize requires a restart)
|
|
}
|
|
|
|
void CPageSlots::ResetToDefault()
|
|
{
|
|
CConfigNeedingRestart& configNew = m_PropertySheetHelper.GetConfigNew();
|
|
|
|
for (UINT slot = SLOT0; slot < NUM_SLOTS; slot++)
|
|
configNew.m_Slot[slot] = GetCardMgr().QueryDefaultCardForSlot(slot, configNew.m_Apple2Type);
|
|
|
|
if (IsAppleIIe(m_PropertySheetHelper.GetConfigNew().m_Apple2Type))
|
|
configNew.m_SlotAux = GetCardMgr().QueryDefaultCardForSlot(SLOT_AUX, configNew.m_Apple2Type);
|
|
|
|
for (UINT slot = SLOT0; slot < NUM_SLOTS; slot++)
|
|
ResetCardOptionsToDefault(slot);
|
|
|
|
ResetCardOptionsToDefault(SLOT_AUX);
|
|
}
|
|
|
|
void CPageSlots::ResetCardOptionsToDefault(UINT slot)
|
|
{
|
|
if (slot < NUM_SLOTS)
|
|
{
|
|
ConfigResetDisk2(slot);
|
|
ConfigResetHarddisk(slot);
|
|
ConfigResetSSC(slot);
|
|
ConfigResetPrinter(slot);
|
|
ConfigResetMouseCard(slot);
|
|
ConfigResetSaturn(slot);
|
|
ConfigResetMockingboard(slot);
|
|
}
|
|
else
|
|
{
|
|
_ASSERT(slot == SLOT_AUX);
|
|
m_PropertySheetHelper.GetConfigNew().m_RamWorksMemorySize = 1; // Must be 1 for all others (Empty, 80Col, Extended80Col)
|
|
ConfigResetRamWorks();
|
|
}
|
|
}
|
|
|
|
//===========================================================================
|
|
|
|
INT_PTR CALLBACK CPageSlots::DlgProcDisk2(HWND hWnd, UINT message, WPARAM wparam, LPARAM lparam)
|
|
{
|
|
// Switch from static func to our instance
|
|
return CPageSlots::ms_this->DlgProcDisk2Internal(hWnd, message, wparam, lparam);
|
|
}
|
|
|
|
INT_PTR CPageSlots::DlgProcDisk2Internal(HWND hWnd, UINT message, WPARAM wparam, LPARAM lparam)
|
|
{
|
|
switch (message)
|
|
{
|
|
case WM_COMMAND:
|
|
switch (LOWORD(wparam))
|
|
{
|
|
case IDC_SLOT_OPT_COMBO_DISK1:
|
|
case IDC_SLOT_OPT_COMBO_DISK2:
|
|
if (HIWORD(wparam) == CBN_SELCHANGE)
|
|
{
|
|
UINT driveSelected = LOWORD(wparam) - IDC_SLOT_OPT_COMBO_DISK1;
|
|
HandleFloppyDriveCombo(hWnd, driveSelected, LOWORD(wparam), ms_slot);
|
|
}
|
|
break;
|
|
|
|
case IDC_SLOT_OPT_DISK_SWAP:
|
|
HandleFloppyDriveSwap(hWnd, ms_slot);
|
|
break;
|
|
|
|
case IDOK:
|
|
DlgDisk2OK(hWnd);
|
|
EndDialog(hWnd, 0);
|
|
break;
|
|
|
|
case IDCANCEL:
|
|
EndDialog(hWnd, 0);
|
|
break;
|
|
|
|
default:
|
|
return FALSE;
|
|
}
|
|
break;
|
|
|
|
case WM_CLOSE:
|
|
EndDialog(hWnd, 0);
|
|
break;
|
|
|
|
case WM_INITDIALOG:
|
|
InitComboFloppyDrive(hWnd, ms_slot);
|
|
|
|
CheckDlgButton(hWnd, IDC_DISKII_STATUS_ENABLE, Win32Frame::GetWin32Frame().GetWindowedModeShowDiskiiStatus() ? BST_CHECKED : BST_UNCHECKED);
|
|
|
|
if (ms_slot != SLOT5 && ms_slot != SLOT6)
|
|
EnableWindow(GetDlgItem(hWnd, IDC_DISKII_STATUS_ENABLE), FALSE);
|
|
|
|
CheckDlgButton(hWnd, IDC_DISKII_13_SECTOR_FW_ENABLE, m_PropertySheetHelper.GetConfigNew().m_diskII13SectorFirmware[ms_slot] ? BST_CHECKED : BST_UNCHECKED);
|
|
break;
|
|
|
|
default:
|
|
return FALSE;
|
|
}
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
void CPageSlots::InitComboFloppyDrive(HWND hWnd, UINT slot)
|
|
{
|
|
for (UINT i = DRIVE_1; i < NUM_DRIVES; i++)
|
|
{
|
|
m_PropertySheetHelper.FillComboBox(hWnd, IDC_SLOT_OPT_COMBO_DISK1 + i, m_defaultDiskOptions, -1);
|
|
|
|
std::string pathname = m_PropertySheetHelper.GetConfigNew().m_slotInfoForFDC[slot].pathname[i];
|
|
std::string imagename, fullname;
|
|
GetImageTitle(pathname.c_str(), imagename, fullname);
|
|
if (!pathname.empty())
|
|
{
|
|
SendDlgItemMessage(hWnd, IDC_SLOT_OPT_COMBO_DISK1 + i, CB_INSERTSTRING, 0, (LPARAM)fullname.c_str());
|
|
SendDlgItemMessage(hWnd, IDC_SLOT_OPT_COMBO_DISK1 + i, CB_SETCURSEL, 0, 0);
|
|
}
|
|
}
|
|
}
|
|
|
|
bool CPageSlots::CheckFloppyPathnameInUse(const std::string& pathname, BYTE& inUseSlot, BYTE& inUseDrive)
|
|
{
|
|
for (UINT slot = SLOT0; slot < NUM_SLOTS; slot++)
|
|
{
|
|
if (GetCardMgr().QuerySlot(slot) == CT_Disk2)
|
|
{
|
|
Disk2InterfaceCard& card = dynamic_cast<Disk2InterfaceCard&>(GetCardMgr().GetRef(slot));
|
|
for (UINT i = DRIVE_1; i < NUM_DRIVES; i++)
|
|
{
|
|
if (card.DiskGetFullPathName(i) == pathname)
|
|
{
|
|
inUseSlot = slot;
|
|
inUseDrive = i;
|
|
return true;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
void CPageSlots::HandleFloppyDriveCombo(HWND hWnd, UINT driveSelected, UINT comboSelected, UINT slot)
|
|
{
|
|
Disk2InterfaceCard& card = m_PropertySheetHelper.GetConfigNew().m_disk2Card;
|
|
|
|
// Search from "select floppy drive"
|
|
uint32_t dwOpenDialogIndex = (uint32_t)SendDlgItemMessage(hWnd, comboSelected, CB_FINDSTRINGEXACT, -1, (LPARAM)&m_defaultDiskOptions[0]);
|
|
uint32_t dwComboSelection = (uint32_t)SendDlgItemMessage(hWnd, comboSelected, CB_GETCURSEL, 0, 0);
|
|
|
|
SendDlgItemMessage(hWnd, comboSelected, CB_SETCURSEL, -1, 0); // Set to "empty" item
|
|
|
|
if (dwComboSelection == dwOpenDialogIndex)
|
|
{
|
|
EnableFloppyDrive(hWnd, false); // Prevent multiple Selection dialogs to be triggered
|
|
std::string pathname;
|
|
DWORD flags = 0;
|
|
bool bRes = card.UserSelectNewDiskImageOnly(driveSelected, "", pathname, flags);
|
|
EnableFloppyDrive(hWnd, true);
|
|
|
|
if (!bRes)
|
|
{
|
|
if (SendDlgItemMessage(hWnd, comboSelected, CB_GETCOUNT, 0, 0) == 3) // If there's already a disk...
|
|
SendDlgItemMessage(hWnd, comboSelected, CB_SETCURSEL, 0, 0); // then reselect it in the ComboBox
|
|
return;
|
|
}
|
|
|
|
// Check if pathname is in use by any of emulator's disk cards
|
|
BYTE inUseSlot = 0, inUseDrive = 0;
|
|
if (CheckFloppyPathnameInUse(pathname, inUseSlot, inUseDrive))
|
|
{
|
|
if (inUseSlot == slot && inUseDrive == driveSelected)
|
|
return InitComboFloppyDrive(hWnd, slot); // User picked the same image, so restore combo
|
|
|
|
m_PropertySheetHelper.GetConfigNew().m_slotInfoForFDC[ms_slot].pathname[driveSelected] = "";
|
|
|
|
std::string strText = StrFormat("%s already mounted in slot %d, drive %d.", pathname.c_str(), inUseSlot, inUseDrive + 1);
|
|
MessageBox(hWnd, strText.c_str(), g_pAppTitle.c_str(), MB_ICONEXCLAMATION | MB_SETFOREGROUND);
|
|
return;
|
|
}
|
|
|
|
// Not in use: insert image to validate it
|
|
ImageError_e error = card.InsertDisk(driveSelected, pathname, false, false);
|
|
if (error != eIMAGE_ERROR_NONE)
|
|
{
|
|
card.NotifyInvalidImage(driveSelected, pathname, error);
|
|
m_PropertySheetHelper.GetConfigNew().m_slotInfoForFDC[ms_slot].pathname[driveSelected] = "";
|
|
return;
|
|
}
|
|
|
|
m_PropertySheetHelper.GetConfigNew().m_slotInfoForFDC[ms_slot].pathname[driveSelected] = pathname;
|
|
|
|
// Add floppy drive name as item 0 and select it
|
|
if (dwOpenDialogIndex > 0)
|
|
{
|
|
//Remove old item first
|
|
SendDlgItemMessage(hWnd, comboSelected, CB_DELETESTRING, 0, 0);
|
|
}
|
|
|
|
std::string fullname = card.GetFullName(driveSelected);
|
|
SendDlgItemMessage(hWnd, comboSelected, CB_INSERTSTRING, 0, (LPARAM)fullname.c_str());
|
|
SendDlgItemMessage(hWnd, comboSelected, CB_SETCURSEL, 0, 0);
|
|
|
|
// If the FD was in the other combo, remove now
|
|
const uint32_t comboOther = (comboSelected == IDC_SLOT_OPT_COMBO_DISK1) ? IDC_SLOT_OPT_COMBO_DISK2 : IDC_SLOT_OPT_COMBO_DISK1;
|
|
|
|
const uint32_t duplicated = (uint32_t)SendDlgItemMessage(hWnd, comboOther, CB_FINDSTRINGEXACT, -1, (LPARAM)fullname.c_str());
|
|
if (duplicated != CB_ERR)
|
|
{
|
|
SendDlgItemMessage(hWnd, comboOther, CB_DELETESTRING, duplicated, 0);
|
|
SendDlgItemMessage(hWnd, comboOther, CB_SETCURSEL, -1, 0);
|
|
}
|
|
}
|
|
else if (dwComboSelection == (dwOpenDialogIndex + 1))
|
|
{
|
|
if (dwComboSelection > 1)
|
|
{
|
|
if (RemovalConfirmation(hWnd, comboSelected))
|
|
{
|
|
// Eject selected disk
|
|
card.EjectDisk(driveSelected);
|
|
m_PropertySheetHelper.GetConfigNew().m_slotInfoForFDC[ms_slot].pathname[driveSelected] = "";
|
|
// Remove drive from list
|
|
SendDlgItemMessage(hWnd, comboSelected, CB_DELETESTRING, 0, 0);
|
|
}
|
|
else
|
|
{
|
|
// Eject was cancelled: reselect the disk in the ComboBox
|
|
SendDlgItemMessage(hWnd, comboSelected, CB_SETCURSEL, 0, 0);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
void CPageSlots::EnableFloppyDrive(HWND hWnd, bool enable)
|
|
{
|
|
EnableWindow(GetDlgItem(hWnd, IDC_SLOT_OPT_COMBO_DISK1), enable);
|
|
EnableWindow(GetDlgItem(hWnd, IDC_SLOT_OPT_COMBO_DISK2), enable);
|
|
EnableWindow(GetDlgItem(hWnd, IDC_SLOT_OPT_DISK_SWAP), enable);
|
|
}
|
|
|
|
void CPageSlots::HandleFloppyDriveSwap(HWND hWnd, UINT slot)
|
|
{
|
|
if (!RemovalConfirmation(hWnd, IDC_SLOT_OPT_DISK_SWAP))
|
|
return;
|
|
|
|
std::string temp = m_PropertySheetHelper.GetConfigNew().m_slotInfoForFDC[ms_slot].pathname[DRIVE_1];
|
|
m_PropertySheetHelper.GetConfigNew().m_slotInfoForFDC[ms_slot].pathname[DRIVE_1] = m_PropertySheetHelper.GetConfigNew().m_slotInfoForFDC[ms_slot].pathname[DRIVE_2];
|
|
m_PropertySheetHelper.GetConfigNew().m_slotInfoForFDC[ms_slot].pathname[DRIVE_2] = temp;
|
|
|
|
InitComboFloppyDrive(hWnd, slot);
|
|
}
|
|
|
|
void CPageSlots::DlgDisk2OK(HWND hWnd)
|
|
{
|
|
if (ms_slot == SLOT5 || ms_slot == SLOT6)
|
|
{
|
|
Win32Frame& win32Frame = Win32Frame::GetWin32Frame();
|
|
const bool bNewDiskiiStatus = IsDlgButtonChecked(hWnd, IDC_DISKII_STATUS_ENABLE);
|
|
|
|
if (win32Frame.GetWindowedModeShowDiskiiStatus() != bNewDiskiiStatus)
|
|
{
|
|
REGSAVE(REGVALUE_SHOW_DISKII_STATUS, bNewDiskiiStatus);
|
|
win32Frame.SetWindowedModeShowDiskiiStatus(bNewDiskiiStatus);
|
|
|
|
if (!win32Frame.IsFullScreen())
|
|
win32Frame.FrameRefreshStatus(DRAW_BACKGROUND | DRAW_LEDS | DRAW_DISK_STATUS);
|
|
}
|
|
}
|
|
|
|
const bool newDiskii13SectorFW = IsDlgButtonChecked(hWnd, IDC_DISKII_13_SECTOR_FW_ENABLE);
|
|
m_PropertySheetHelper.GetConfigNew().m_diskII13SectorFirmware[ms_slot] = newDiskii13SectorFW;
|
|
}
|
|
|
|
void CPageSlots::ConfigResetDisk2(UINT slot)
|
|
{
|
|
CConfigNeedingRestart& configNew = m_PropertySheetHelper.GetConfigNew();
|
|
if (configNew.m_Slot[slot] == CT_Disk2)
|
|
{
|
|
configNew.m_diskII13SectorFirmware[slot] = false;
|
|
for (UINT i = DRIVE_1; i < NUM_DRIVES; i++)
|
|
configNew.m_slotInfoForFDC[slot].pathname[i] = "";
|
|
}
|
|
}
|
|
|
|
//===========================================================================
|
|
|
|
INT_PTR CALLBACK CPageSlots::DlgProcHarddisk(HWND hWnd, UINT message, WPARAM wparam, LPARAM lparam)
|
|
{
|
|
// Switch from static func to our instance
|
|
return CPageSlots::ms_this->DlgProcHarddiskInternal(hWnd, message, wparam, lparam);
|
|
}
|
|
|
|
INT_PTR CPageSlots::DlgProcHarddiskInternal(HWND hWnd, UINT message, WPARAM wparam, LPARAM lparam)
|
|
{
|
|
switch (message)
|
|
{
|
|
case WM_COMMAND:
|
|
switch (LOWORD(wparam))
|
|
{
|
|
case IDC_SLOT_OPT_COMBO_HDD1:
|
|
case IDC_SLOT_OPT_COMBO_HDD2:
|
|
case IDC_SLOT_OPT_COMBO_HDD3:
|
|
case IDC_SLOT_OPT_COMBO_HDD4:
|
|
case IDC_SLOT_OPT_COMBO_HDD5:
|
|
case IDC_SLOT_OPT_COMBO_HDD6:
|
|
case IDC_SLOT_OPT_COMBO_HDD7:
|
|
case IDC_SLOT_OPT_COMBO_HDD8:
|
|
if (HIWORD(wparam) == CBN_SELCHANGE)
|
|
{
|
|
UINT driveSelected = LOWORD(wparam) - IDC_SLOT_OPT_COMBO_HDD1;
|
|
HandleHDDCombo(hWnd, driveSelected, LOWORD(wparam), ms_slot);
|
|
}
|
|
break;
|
|
|
|
case IDC_SLOT_OPT_HDD_SWAP:
|
|
HandleHDDSwap(hWnd, ms_slot);
|
|
break;
|
|
|
|
case IDOK:
|
|
DlgHarddiskOK(hWnd);
|
|
EndDialog(hWnd, 0);
|
|
break;
|
|
|
|
case IDCANCEL:
|
|
EndDialog(hWnd, 0);
|
|
break;
|
|
|
|
default:
|
|
return FALSE;
|
|
}
|
|
break;
|
|
|
|
case WM_CLOSE:
|
|
EndDialog(hWnd, 0);
|
|
break;
|
|
|
|
case WM_INITDIALOG:
|
|
{
|
|
InitComboHDD(hWnd, ms_slot);
|
|
|
|
const char choices[] = "Auto\0SmartPort mode\0ProDOS block mode (2 devices)\0ProDOS block mode (4 devices)\0";
|
|
const int choice = (int) m_PropertySheetHelper.GetConfigNew().m_hdcFirmware[ms_slot];
|
|
m_PropertySheetHelper.FillComboBox(hWnd, IDC_SLOT_OPT_COMBO_HDC_FW, choices, choice);
|
|
}
|
|
break;
|
|
|
|
default:
|
|
return FALSE;
|
|
}
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
void CPageSlots::InitComboHDD(HWND hWnd, UINT slot)
|
|
{
|
|
for (UINT i = HARDDISK_1; i < NUM_HARDDISKS; i++)
|
|
{
|
|
m_PropertySheetHelper.FillComboBox(hWnd, IDC_SLOT_OPT_COMBO_HDD1 + i, m_defaultHDDOptions, -1);
|
|
|
|
std::string pathname = m_PropertySheetHelper.GetConfigNew().m_slotInfoForHDC[slot].pathname[i];
|
|
std::string imagename, fullname;
|
|
GetImageTitle(pathname.c_str(), imagename, fullname);
|
|
if (!pathname.empty())
|
|
{
|
|
SendDlgItemMessage(hWnd, IDC_SLOT_OPT_COMBO_HDD1 + i, CB_INSERTSTRING, 0, (LPARAM)fullname.c_str());
|
|
SendDlgItemMessage(hWnd, IDC_SLOT_OPT_COMBO_HDD1 + i, CB_SETCURSEL, 0, 0);
|
|
}
|
|
}
|
|
}
|
|
|
|
bool CPageSlots::CheckHDDPathnameInUse(const std::string& pathname, BYTE& inUseSlot, BYTE& inUseDrive)
|
|
{
|
|
for (UINT slot = SLOT0; slot < NUM_SLOTS; slot++)
|
|
{
|
|
if (GetCardMgr().QuerySlot(slot) == CT_GenericHDD)
|
|
{
|
|
HarddiskInterfaceCard& card = dynamic_cast<HarddiskInterfaceCard&>(GetCardMgr().GetRef(slot));
|
|
for (UINT i = HARDDISK_1; i < NUM_HARDDISKS; i++)
|
|
{
|
|
if (card.HarddiskGetFullPathName(i) == pathname)
|
|
{
|
|
inUseSlot = slot;
|
|
inUseDrive = i;
|
|
return true;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
void CPageSlots::HandleHDDCombo(HWND hWnd, UINT driveSelected, UINT comboSelected, UINT slot)
|
|
{
|
|
HarddiskInterfaceCard& card = m_PropertySheetHelper.GetConfigNew().m_harddiskCard;
|
|
|
|
// Search from "select hard drive"
|
|
uint32_t dwOpenDialogIndex = (uint32_t)SendDlgItemMessage(hWnd, comboSelected, CB_FINDSTRINGEXACT, -1, (LPARAM)&m_defaultHDDOptions[0]);
|
|
uint32_t dwComboSelection = (uint32_t)SendDlgItemMessage(hWnd, comboSelected, CB_GETCURSEL, 0, 0);
|
|
|
|
SendDlgItemMessage(hWnd, comboSelected, CB_SETCURSEL, -1, 0); // Set to "empty" item
|
|
|
|
if (dwComboSelection == dwOpenDialogIndex)
|
|
{
|
|
EnableHDD(hWnd, false); // Prevent multiple Selection dialogs to be triggered
|
|
std::string pathname;
|
|
DWORD flags = 0;
|
|
bool bRes = card.UserSelectNewDiskImageOnly(driveSelected, "", pathname, flags);
|
|
EnableHDD(hWnd, true);
|
|
|
|
if (!bRes)
|
|
{
|
|
if (SendDlgItemMessage(hWnd, comboSelected, CB_GETCOUNT, 0, 0) == 3) // If there's already a HDD...
|
|
SendDlgItemMessage(hWnd, comboSelected, CB_SETCURSEL, 0, 0); // then reselect it in the ComboBox
|
|
return;
|
|
}
|
|
|
|
// Check if pathname is in use by any of emulator's disk cards
|
|
BYTE inUseSlot = 0, inUseDrive = 0;
|
|
if (CheckHDDPathnameInUse(pathname, inUseSlot, inUseDrive))
|
|
{
|
|
if (inUseSlot == slot && inUseDrive == driveSelected)
|
|
return InitComboHDD(hWnd, slot); // User picked the same image, so restore combo
|
|
|
|
m_PropertySheetHelper.GetConfigNew().m_slotInfoForHDC[ms_slot].pathname[driveSelected] = "";
|
|
|
|
std::string strText = StrFormat("%s already mounted in slot %d, drive %d.", pathname.c_str(), inUseSlot, inUseDrive + 1);
|
|
MessageBox(hWnd, strText.c_str(), g_pAppTitle.c_str(), MB_ICONEXCLAMATION | MB_SETFOREGROUND);
|
|
return;
|
|
}
|
|
|
|
// Not in use: insert image to validate it
|
|
bool error = card.Insert(driveSelected, pathname);
|
|
if (error != true)
|
|
{
|
|
card.NotifyInvalidImage(pathname);
|
|
m_PropertySheetHelper.GetConfigNew().m_slotInfoForHDC[ms_slot].pathname[driveSelected] = "";
|
|
return;
|
|
}
|
|
|
|
m_PropertySheetHelper.GetConfigNew().m_slotInfoForHDC[ms_slot].pathname[driveSelected] = pathname;
|
|
|
|
// Add hard drive name as item 0 and select it
|
|
if (dwOpenDialogIndex > 0)
|
|
{
|
|
// Remove old item first
|
|
SendDlgItemMessage(hWnd, comboSelected, CB_DELETESTRING, 0, 0);
|
|
}
|
|
|
|
SendDlgItemMessage(hWnd, comboSelected, CB_INSERTSTRING, 0, (LPARAM)card.GetFullName(driveSelected).c_str());
|
|
SendDlgItemMessage(hWnd, comboSelected, CB_SETCURSEL, 0, 0);
|
|
|
|
// If the HD was in any other combo, remove now
|
|
for (UINT comboOther = IDC_SLOT_OPT_COMBO_HDD1; comboOther <= IDC_SLOT_OPT_COMBO_HDD8; comboOther++)
|
|
{
|
|
if (comboOther == comboSelected)
|
|
continue;
|
|
|
|
const uint32_t duplicated = (uint32_t)SendDlgItemMessage(hWnd, comboOther, CB_FINDSTRINGEXACT, -1, (LPARAM)card.GetFullName(driveSelected).c_str());
|
|
if (duplicated != CB_ERR)
|
|
{
|
|
SendDlgItemMessage(hWnd, comboOther, CB_DELETESTRING, duplicated, 0);
|
|
SendDlgItemMessage(hWnd, comboOther, CB_SETCURSEL, -1, 0);
|
|
|
|
card.Unplug(driveSelected);
|
|
m_PropertySheetHelper.GetConfigNew().m_slotInfoForHDC[ms_slot].pathname[driveSelected] = "";
|
|
}
|
|
}
|
|
}
|
|
else if (dwComboSelection == (dwOpenDialogIndex + 1))
|
|
{
|
|
if (dwComboSelection > 1)
|
|
{
|
|
if (RemovalConfirmation(hWnd, comboSelected))
|
|
{
|
|
// Unplug selected disk
|
|
card.Unplug(driveSelected);
|
|
m_PropertySheetHelper.GetConfigNew().m_slotInfoForHDC[ms_slot].pathname[driveSelected] = "";
|
|
// Remove drive from list
|
|
SendDlgItemMessage(hWnd, comboSelected, CB_DELETESTRING, 0, 0);
|
|
}
|
|
else
|
|
{
|
|
// Cancel the Unplug, and set the menu back to the image name
|
|
SendDlgItemMessage(hWnd, comboSelected, CB_SETCURSEL, 0, 0);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
void CPageSlots::EnableHDD(HWND hWnd, bool enable)
|
|
{
|
|
EnableWindow(GetDlgItem(hWnd, IDC_SLOT_OPT_COMBO_HDD1), enable);
|
|
EnableWindow(GetDlgItem(hWnd, IDC_SLOT_OPT_COMBO_HDD2), enable);
|
|
EnableWindow(GetDlgItem(hWnd, IDC_SLOT_OPT_HDD_SWAP), enable);
|
|
}
|
|
|
|
void CPageSlots::HandleHDDSwap(HWND hWnd, UINT slot)
|
|
{
|
|
if (!RemovalConfirmation(hWnd, IDC_SLOT_OPT_HDD_SWAP))
|
|
return;
|
|
|
|
std::string temp = m_PropertySheetHelper.GetConfigNew().m_slotInfoForHDC[ms_slot].pathname[HARDDISK_1];
|
|
m_PropertySheetHelper.GetConfigNew().m_slotInfoForHDC[ms_slot].pathname[HARDDISK_1] = m_PropertySheetHelper.GetConfigNew().m_slotInfoForHDC[ms_slot].pathname[HARDDISK_2];
|
|
m_PropertySheetHelper.GetConfigNew().m_slotInfoForHDC[ms_slot].pathname[HARDDISK_2] = temp;
|
|
|
|
InitComboHDD(hWnd, slot);
|
|
}
|
|
|
|
void CPageSlots::DlgHarddiskOK(HWND hWnd)
|
|
{
|
|
const HdcMode choice = (HdcMode)SendDlgItemMessage(hWnd, IDC_SLOT_OPT_COMBO_HDC_FW, CB_GETCURSEL, 0, 0);
|
|
m_PropertySheetHelper.GetConfigNew().m_hdcFirmware[ms_slot] = choice;
|
|
}
|
|
|
|
void CPageSlots::ConfigResetHarddisk(UINT slot)
|
|
{
|
|
CConfigNeedingRestart& configNew = m_PropertySheetHelper.GetConfigNew();
|
|
if (configNew.m_Slot[slot] == CT_GenericHDD)
|
|
{
|
|
m_PropertySheetHelper.GetConfigNew().m_hdcFirmware[slot] = HdcDefault;
|
|
for (UINT i = HARDDISK_1; i < NUM_HARDDISKS; i++)
|
|
configNew.m_slotInfoForHDC[slot].pathname[i] = "";
|
|
}
|
|
}
|
|
|
|
//===========================================================================
|
|
|
|
UINT CPageSlots::RemovalConfirmation(HWND hWnd, UINT command)
|
|
{
|
|
bool bMsgBox = true;
|
|
|
|
bool isFloppyDisk = false;
|
|
UINT drive = 0;
|
|
if (command == IDC_SLOT_OPT_COMBO_DISK1 || command == IDC_SLOT_OPT_COMBO_DISK2)
|
|
{
|
|
isFloppyDisk = true;
|
|
drive = command - IDC_SLOT_OPT_COMBO_DISK1;
|
|
}
|
|
|
|
std::string strText;
|
|
if (isFloppyDisk)
|
|
strText = StrFormat("Do you really want to eject the disk in drive-%c ?", '1' + drive);
|
|
else if (command == IDC_SLOT_OPT_DISK_SWAP)
|
|
strText = "Do you really want to swap the floppy disks?";
|
|
else if (command == IDC_SLOT_OPT_COMBO_HDD1 || command == IDC_SLOT_OPT_COMBO_HDD2)
|
|
strText = StrFormat("Do you really want to unplug harddisk-%c ?", '1' + command - IDC_SLOT_OPT_COMBO_HDD1);
|
|
else if (command == IDC_SLOT_OPT_HDD_SWAP)
|
|
strText = "Do you really want to swap the harddisk images?";
|
|
else
|
|
bMsgBox = false;
|
|
|
|
if (bMsgBox)
|
|
{
|
|
// Use MessageBox() and not FrameMessageBox(), so that dialog is modal (GH#1507)
|
|
int nRes = MessageBox(hWnd, strText.c_str(), "Eject/Unplug Warning", MB_ICONWARNING | MB_YESNO | MB_SETFOREGROUND);
|
|
if (nRes == IDNO)
|
|
command = 0;
|
|
}
|
|
|
|
return command;
|
|
}
|
|
|
|
//===========================================================================
|
|
|
|
INT_PTR CALLBACK CPageSlots::DlgProcSSC(HWND hWnd, UINT message, WPARAM wparam, LPARAM lparam)
|
|
{
|
|
// Switch from static func to our instance
|
|
return CPageSlots::ms_this->DlgProcSSCInternal(hWnd, message, wparam, lparam);
|
|
}
|
|
|
|
INT_PTR CPageSlots::DlgProcSSCInternal(HWND hWnd, UINT message, WPARAM wparam, LPARAM lparam)
|
|
{
|
|
switch (message)
|
|
{
|
|
case WM_COMMAND:
|
|
switch (LOWORD(wparam))
|
|
{
|
|
case IDOK:
|
|
DlgSSCOK(hWnd);
|
|
EndDialog(hWnd, 0);
|
|
break;
|
|
|
|
case IDCANCEL:
|
|
EndDialog(hWnd, 0);
|
|
break;
|
|
|
|
default:
|
|
return FALSE;
|
|
}
|
|
break;
|
|
|
|
case WM_CLOSE:
|
|
EndDialog(hWnd, 0);
|
|
break;
|
|
|
|
case WM_INITDIALOG:
|
|
{
|
|
CSuperSerialCard& cardForConfig = m_PropertySheetHelper.GetConfigNew().m_SSC;
|
|
const UINT serialPortItem = m_PropertySheetHelper.GetConfigNew().m_serialPortItem;
|
|
m_PropertySheetHelper.FillComboBox(hWnd, IDC_SERIALPORT, cardForConfig.GetSerialPortChoices().c_str(), serialPortItem);
|
|
|
|
CSuperSerialCard* card = GetCardMgr().GetSSC();
|
|
const bool enable = !card || !card->IsActive();
|
|
EnableWindow(GetDlgItem(hWnd, IDC_SERIALPORT), enable);
|
|
break;
|
|
}
|
|
|
|
default:
|
|
return FALSE;
|
|
}
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
void CPageSlots::DlgSSCOK(HWND hWnd)
|
|
{
|
|
const UINT serialPortItem = (UINT)SendDlgItemMessage(hWnd, IDC_SERIALPORT, CB_GETCURSEL, 0, 0);
|
|
m_PropertySheetHelper.GetConfigNew().m_serialPortItem = serialPortItem;
|
|
}
|
|
|
|
void CPageSlots::ConfigResetSSC(UINT slot)
|
|
{
|
|
CConfigNeedingRestart& configNew = m_PropertySheetHelper.GetConfigNew();
|
|
if (configNew.m_Slot[slot] == CT_SSC)
|
|
{
|
|
configNew.m_serialPortItem = 0; // "None"
|
|
}
|
|
}
|
|
|
|
//===========================================================================
|
|
|
|
INT_PTR CALLBACK CPageSlots::DlgProcPrinter(HWND hWnd, UINT message, WPARAM wparam, LPARAM lparam)
|
|
{
|
|
// Switch from static func to our instance
|
|
return CPageSlots::ms_this->DlgProcPrinterInternal(hWnd, message, wparam, lparam);
|
|
}
|
|
|
|
INT_PTR CPageSlots::DlgProcPrinterInternal(HWND hWnd, UINT message, WPARAM wparam, LPARAM lparam)
|
|
{
|
|
switch (message)
|
|
{
|
|
case WM_COMMAND:
|
|
switch (LOWORD(wparam))
|
|
{
|
|
case IDC_PRINTER_DUMP_FILENAME_BROWSE:
|
|
{
|
|
std::string strPrinterDumpLoc = m_PropertySheetHelper.BrowseToFile(hWnd, "Select printer dump file", REGVALUE_PRINTER_FILENAME, "Text files (*.txt)\0*.txt\0" "All Files\0*.*\0");
|
|
SendDlgItemMessage(hWnd, IDC_PRINTER_DUMP_FILENAME, WM_SETTEXT, 0, (LPARAM)strPrinterDumpLoc.c_str());
|
|
}
|
|
break;
|
|
|
|
case IDOK:
|
|
DlgPrinterOK(hWnd);
|
|
EndDialog(hWnd, 0);
|
|
break;
|
|
|
|
case IDCANCEL:
|
|
EndDialog(hWnd, 0);
|
|
break;
|
|
|
|
default:
|
|
return FALSE;
|
|
}
|
|
break;
|
|
|
|
case WM_CLOSE:
|
|
EndDialog(hWnd, 0);
|
|
break;
|
|
|
|
case WM_INITDIALOG:
|
|
{
|
|
ParallelPrinterCard& card = m_PropertySheetHelper.GetConfigNew().m_parallelPrinterCard;
|
|
|
|
CheckDlgButton(hWnd, IDC_DUMPTOPRINTER, card.GetDumpToPrinter() ? BST_CHECKED : BST_UNCHECKED);
|
|
CheckDlgButton(hWnd, IDC_PRINTER_CONVERT_ENCODING, card.GetConvertEncoding() ? BST_CHECKED : BST_UNCHECKED);
|
|
CheckDlgButton(hWnd, IDC_PRINTER_FILTER_UNPRINTABLE, card.GetFilterUnprintable() ? BST_CHECKED : BST_UNCHECKED);
|
|
CheckDlgButton(hWnd, IDC_PRINTER_APPEND, card.GetPrinterAppend() ? BST_CHECKED : BST_UNCHECKED);
|
|
SendDlgItemMessage(hWnd, IDC_SPIN_PRINTER_IDLE, UDM_SETRANGE, 0, MAKELONG(999, 0));
|
|
SendDlgItemMessage(hWnd, IDC_SPIN_PRINTER_IDLE, UDM_SETPOS, 0, MAKELONG(card.GetIdleLimit(), 0));
|
|
SendDlgItemMessage(hWnd, IDC_PRINTER_DUMP_FILENAME, WM_SETTEXT, 0, (LPARAM)card.GetFilename().c_str());
|
|
|
|
// Need to specify cmd-line switch: -printer-real to enable this control
|
|
EnableWindow(GetDlgItem(hWnd, IDC_DUMPTOPRINTER), card.GetEnableDumpToRealPrinter());
|
|
}
|
|
break;
|
|
|
|
default:
|
|
return FALSE;
|
|
}
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
void CPageSlots::DlgPrinterOK(HWND hWnd)
|
|
{
|
|
ParallelPrinterCard& card = m_PropertySheetHelper.GetConfigNew().m_parallelPrinterCard;
|
|
|
|
// Update printer dump filename
|
|
{
|
|
char szFilename[MAX_PATH];
|
|
memset(szFilename, 0, sizeof(szFilename));
|
|
*(USHORT*)szFilename = sizeof(szFilename);
|
|
|
|
LRESULT nLineLength = SendDlgItemMessage(hWnd, IDC_PRINTER_DUMP_FILENAME, EM_LINELENGTH, 0, 0);
|
|
|
|
SendDlgItemMessage(hWnd, IDC_PRINTER_DUMP_FILENAME, EM_GETLINE, 0, (LPARAM)szFilename);
|
|
|
|
nLineLength = nLineLength > sizeof(szFilename) - 1 ? sizeof(szFilename) - 1 : nLineLength;
|
|
szFilename[nLineLength] = 0x00;
|
|
|
|
card.SetFilename(szFilename);
|
|
}
|
|
|
|
card.SetDumpToPrinter(IsDlgButtonChecked(hWnd, IDC_DUMPTOPRINTER));
|
|
card.SetConvertEncoding(IsDlgButtonChecked(hWnd, IDC_PRINTER_CONVERT_ENCODING));
|
|
card.SetFilterUnprintable(IsDlgButtonChecked(hWnd, IDC_PRINTER_FILTER_UNPRINTABLE));
|
|
card.SetPrinterAppend(IsDlgButtonChecked(hWnd, IDC_PRINTER_APPEND));
|
|
|
|
card.SetIdleLimit((short)SendDlgItemMessage(hWnd, IDC_SPIN_PRINTER_IDLE, UDM_GETPOS, 0, 0));
|
|
}
|
|
|
|
void CPageSlots::ConfigResetPrinter(UINT slot)
|
|
{
|
|
CConfigNeedingRestart& configNew = m_PropertySheetHelper.GetConfigNew();
|
|
if (configNew.m_Slot[slot] == CT_GenericPrinter)
|
|
{
|
|
configNew.m_parallelPrinterCard.ResetDefaultOptions();
|
|
}
|
|
}
|
|
|
|
//===========================================================================
|
|
|
|
INT_PTR CALLBACK CPageSlots::DlgProcMouseCard(HWND hWnd, UINT message, WPARAM wparam, LPARAM lparam)
|
|
{
|
|
// Switch from static func to our instance
|
|
return CPageSlots::ms_this->DlgProcMouseCardInternal(hWnd, message, wparam, lparam);
|
|
}
|
|
|
|
INT_PTR CPageSlots::DlgProcMouseCardInternal(HWND hWnd, UINT message, WPARAM wparam, LPARAM lparam)
|
|
{
|
|
switch (message)
|
|
{
|
|
case WM_COMMAND:
|
|
switch (LOWORD(wparam))
|
|
{
|
|
case IDOK:
|
|
DlgMouseCardOK(hWnd);
|
|
EndDialog(hWnd, 0);
|
|
break;
|
|
|
|
case IDCANCEL:
|
|
EndDialog(hWnd, 0);
|
|
break;
|
|
|
|
default:
|
|
return FALSE;
|
|
}
|
|
break;
|
|
|
|
case WM_CLOSE:
|
|
EndDialog(hWnd, 0);
|
|
break;
|
|
|
|
case WM_INITDIALOG:
|
|
{
|
|
CheckDlgButton(hWnd, IDC_MOUSE_CROSSHAIR, m_mouseShowCrosshair ? BST_CHECKED : BST_UNCHECKED);
|
|
CheckDlgButton(hWnd, IDC_MOUSE_RESTRICT_TO_WINDOW, m_mouseRestrictToWindow ? BST_CHECKED : BST_UNCHECKED);
|
|
}
|
|
break;
|
|
|
|
default:
|
|
return FALSE;
|
|
}
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
void CPageSlots::DlgMouseCardOK(HWND hWnd)
|
|
{
|
|
m_PropertySheetHelper.GetConfigNew().m_mouseShowCrosshair = IsDlgButtonChecked(hWnd, IDC_MOUSE_CROSSHAIR) ? 1 : 0;
|
|
m_PropertySheetHelper.GetConfigNew().m_mouseRestrictToWindow = IsDlgButtonChecked(hWnd, IDC_MOUSE_RESTRICT_TO_WINDOW) ? 1 : 0;
|
|
}
|
|
|
|
void CPageSlots::ConfigResetMouseCard(UINT slot)
|
|
{
|
|
CConfigNeedingRestart& configNew = m_PropertySheetHelper.GetConfigNew();
|
|
if (configNew.m_Slot[slot] == CT_MouseInterface)
|
|
{
|
|
configNew.m_mouseShowCrosshair = 0;
|
|
configNew.m_mouseRestrictToWindow = 0;
|
|
}
|
|
}
|
|
|
|
//===========================================================================
|
|
|
|
INT_PTR CALLBACK CPageSlots::DlgProcSaturn(HWND hWnd, UINT message, WPARAM wparam, LPARAM lparam)
|
|
{
|
|
// Switch from static func to our instance
|
|
return CPageSlots::ms_this->DlgProcSaturnInternal(hWnd, message, wparam, lparam);
|
|
}
|
|
|
|
INT_PTR CPageSlots::DlgProcSaturnInternal(HWND hWnd, UINT message, WPARAM wparam, LPARAM lparam)
|
|
{
|
|
switch (message)
|
|
{
|
|
case WM_COMMAND:
|
|
switch (LOWORD(wparam))
|
|
{
|
|
case IDOK:
|
|
DlgSaturnOK(hWnd);
|
|
EndDialog(hWnd, 0);
|
|
break;
|
|
|
|
case IDCANCEL:
|
|
EndDialog(hWnd, 0);
|
|
break;
|
|
|
|
default:
|
|
return FALSE;
|
|
}
|
|
break;
|
|
|
|
case WM_CLOSE:
|
|
EndDialog(hWnd, 0);
|
|
break;
|
|
|
|
case WM_INITDIALOG:
|
|
{
|
|
SendDlgItemMessage(hWnd, IDC_SLIDER_SATURN_SIZE, TBM_SETRANGE, TRUE, MAKELONG(1, 8));
|
|
SendDlgItemMessage(hWnd, IDC_SLIDER_SATURN_SIZE, TBM_SETPAGESIZE, 0, 1);
|
|
SendDlgItemMessage(hWnd, IDC_SLIDER_SATURN_SIZE, TBM_SETTIC, 0, 1); // 16K
|
|
SendDlgItemMessage(hWnd, IDC_SLIDER_SATURN_SIZE, TBM_SETTIC, 0, 2); // 32K
|
|
SendDlgItemMessage(hWnd, IDC_SLIDER_SATURN_SIZE, TBM_SETTIC, 0, 4); // 64K
|
|
SendDlgItemMessage(hWnd, IDC_SLIDER_SATURN_SIZE, TBM_SETTIC, 0, 8); // 128K
|
|
|
|
const uint32_t size = m_PropertySheetHelper.GetConfigNew().m_SaturnMemorySize[ms_slot]; // 16K banks
|
|
SendDlgItemMessage(hWnd, IDC_SLIDER_SATURN_SIZE, TBM_SETPOS, TRUE, size);
|
|
}
|
|
break;
|
|
|
|
default:
|
|
return FALSE;
|
|
}
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
void CPageSlots::DlgSaturnOK(HWND hWnd)
|
|
{
|
|
const uint32_t size = (uint32_t)SendDlgItemMessage(hWnd, IDC_SLIDER_SATURN_SIZE, TBM_GETPOS, 0, 0);
|
|
m_PropertySheetHelper.GetConfigNew().m_SaturnMemorySize[ms_slot] = size;
|
|
}
|
|
|
|
void CPageSlots::ConfigResetSaturn(UINT slot)
|
|
{
|
|
CConfigNeedingRestart& configNew = m_PropertySheetHelper.GetConfigNew();
|
|
if (configNew.m_Slot[slot] == CT_Saturn128K)
|
|
{
|
|
configNew.m_SaturnMemorySize[slot] = Saturn128K::kMaxSaturnBanks;
|
|
}
|
|
}
|
|
|
|
//===========================================================================
|
|
|
|
INT_PTR CALLBACK CPageSlots::DlgProcMockingboard(HWND hWnd, UINT message, WPARAM wparam, LPARAM lparam)
|
|
{
|
|
// Switch from static func to our instance
|
|
return CPageSlots::ms_this->DlgProcMockingboardInternal(hWnd, message, wparam, lparam);
|
|
}
|
|
|
|
INT_PTR CPageSlots::DlgProcMockingboardInternal(HWND hWnd, UINT message, WPARAM wparam, LPARAM lparam)
|
|
{
|
|
switch (message)
|
|
{
|
|
case WM_COMMAND:
|
|
switch (LOWORD(wparam))
|
|
{
|
|
case IDOK:
|
|
DlgMockingboardOK(hWnd);
|
|
EndDialog(hWnd, 0);
|
|
break;
|
|
|
|
case IDCANCEL:
|
|
EndDialog(hWnd, 0);
|
|
break;
|
|
|
|
default:
|
|
return FALSE;
|
|
}
|
|
break;
|
|
|
|
case WM_CLOSE:
|
|
EndDialog(hWnd, 0);
|
|
break;
|
|
|
|
case WM_INITDIALOG:
|
|
{
|
|
// UI matches SMS's MB-C layout:
|
|
// . socket-1 (top) main SSI263
|
|
// . socket-0 (btm) unused except by mb-audit
|
|
// NB. Phasor's physical socket locations are reversed (bottom is main SSI263)
|
|
const char choices[] = "Empty\0SSI263P\0SSI263AP\0";
|
|
const SSI263Type ssi263B = m_PropertySheetHelper.GetConfigNew().m_Mockingboard[ms_slot].ssi263B;
|
|
const SSI263Type ssi263A = m_PropertySheetHelper.GetConfigNew().m_Mockingboard[ms_slot].ssi263A;
|
|
const SSI263Type sc01 = m_PropertySheetHelper.GetConfigNew().m_Mockingboard[ms_slot].sc01;
|
|
const int choiceB = ssi263B == SSI263P ? 1 : ssi263B == SSI263AP ? 2 : 0;
|
|
const int choiceA = ssi263A == SSI263P ? 1 : ssi263A == SSI263AP ? 2 : 0;
|
|
m_PropertySheetHelper.FillComboBox(hWnd, IDC_SLOT_OPT_COMBO_MB_SSI263_SOCKET1, choices, choiceB); // socket-1 (top) for main SSI263
|
|
m_PropertySheetHelper.FillComboBox(hWnd, IDC_SLOT_OPT_COMBO_MB_SSI263_SOCKET0, choices, choiceA);
|
|
CheckDlgButton(hWnd, IDC_SLOT_OPT_SC01_ENABLE, sc01 == SC01 ? BST_CHECKED : BST_UNCHECKED);
|
|
}
|
|
break;
|
|
|
|
default:
|
|
return FALSE;
|
|
}
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
void CPageSlots::DlgMockingboardOK(HWND hWnd)
|
|
{
|
|
const UINT choiceB = (UINT)SendDlgItemMessage(hWnd, IDC_SLOT_OPT_COMBO_MB_SSI263_SOCKET1, CB_GETCURSEL, 0, 0);
|
|
const UINT choiceA = (UINT)SendDlgItemMessage(hWnd, IDC_SLOT_OPT_COMBO_MB_SSI263_SOCKET0, CB_GETCURSEL, 0, 0);
|
|
const SSI263Type ssi263B = choiceB == 1 ? SSI263P : choiceB == 2 ? SSI263AP : SSI263Empty;
|
|
const SSI263Type ssi263A = choiceA == 1 ? SSI263P : choiceA == 2 ? SSI263AP : SSI263Empty;
|
|
const SSI263Type sc01 = IsDlgButtonChecked(hWnd, IDC_SLOT_OPT_SC01_ENABLE) ? SC01 : SSI263Empty;
|
|
m_PropertySheetHelper.GetConfigNew().m_Mockingboard[ms_slot].ssi263B = ssi263B;
|
|
m_PropertySheetHelper.GetConfigNew().m_Mockingboard[ms_slot].ssi263A = ssi263A;
|
|
m_PropertySheetHelper.GetConfigNew().m_Mockingboard[ms_slot].sc01 = sc01;
|
|
}
|
|
|
|
void CPageSlots::ConfigResetMockingboard(UINT slot)
|
|
{
|
|
CConfigNeedingRestart& configNew = m_PropertySheetHelper.GetConfigNew();
|
|
if (configNew.m_Slot[slot] == CT_MockingboardC || configNew.m_Slot[slot] == CT_Phasor)
|
|
{
|
|
configNew.m_Mockingboard[slot].ssi263A = kSSI263A_Default;
|
|
configNew.m_Mockingboard[slot].ssi263B = kSSI263B_Default;
|
|
configNew.m_Mockingboard[slot].sc01 = kSC01_Default;
|
|
}
|
|
}
|
|
|
|
//===========================================================================
|
|
|
|
static bool g_rw3SliderMoved = false;
|
|
|
|
INT_PTR CALLBACK CPageSlots::DlgProcRamWorks3(HWND hWnd, UINT message, WPARAM wparam, LPARAM lparam)
|
|
{
|
|
// Switch from static func to our instance
|
|
return CPageSlots::ms_this->DlgProcRamWorks3Internal(hWnd, message, wparam, lparam);
|
|
}
|
|
|
|
INT_PTR CPageSlots::DlgProcRamWorks3Internal(HWND hWnd, UINT message, WPARAM wparam, LPARAM lparam)
|
|
{
|
|
switch (message)
|
|
{
|
|
case WM_HSCROLL:
|
|
g_rw3SliderMoved = true;
|
|
break;
|
|
|
|
case WM_COMMAND:
|
|
switch (LOWORD(wparam))
|
|
{
|
|
case IDOK:
|
|
DlgRamWorks3OK(hWnd);
|
|
EndDialog(hWnd, 0);
|
|
break;
|
|
|
|
case IDCANCEL:
|
|
EndDialog(hWnd, 0);
|
|
break;
|
|
|
|
default:
|
|
return FALSE;
|
|
}
|
|
break;
|
|
|
|
case WM_CLOSE:
|
|
EndDialog(hWnd, 0);
|
|
break;
|
|
|
|
case WM_INITDIALOG:
|
|
{
|
|
SendDlgItemMessage(hWnd, IDC_SLIDER_RW3_SIZE, TBM_SETRANGE, TRUE, MAKELONG(1, 16));
|
|
SendDlgItemMessage(hWnd, IDC_SLIDER_RW3_SIZE, TBM_SETPAGESIZE, 0, 4);
|
|
SendDlgItemMessage(hWnd, IDC_SLIDER_RW3_SIZE, TBM_SETTIC, 0, 1);
|
|
SendDlgItemMessage(hWnd, IDC_SLIDER_RW3_SIZE, TBM_SETTIC, 0, 4);
|
|
SendDlgItemMessage(hWnd, IDC_SLIDER_RW3_SIZE, TBM_SETTIC, 0, 8);
|
|
SendDlgItemMessage(hWnd, IDC_SLIDER_RW3_SIZE, TBM_SETTIC, 0, 12);
|
|
SendDlgItemMessage(hWnd, IDC_SLIDER_RW3_SIZE, TBM_SETTIC, 0, 16);
|
|
|
|
const uint32_t size = m_PropertySheetHelper.GetConfigNew().m_RamWorksMemorySize / 16; // Convert from 64K banks to MB
|
|
SendDlgItemMessage(hWnd, IDC_SLIDER_RW3_SIZE, TBM_SETPOS, TRUE, size);
|
|
|
|
g_rw3SliderMoved = false;
|
|
}
|
|
break;
|
|
|
|
default:
|
|
return FALSE;
|
|
}
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
void CPageSlots::DlgRamWorks3OK(HWND hWnd)
|
|
{
|
|
// Slider UI is in 1MB chunks, but from save-state, can have finer granularity, eg. 4x 64K
|
|
// So only use slider position if user has touched it
|
|
if (!g_rw3SliderMoved)
|
|
return;
|
|
|
|
const uint32_t size = (uint32_t)SendDlgItemMessage(hWnd, IDC_SLIDER_RW3_SIZE, TBM_GETPOS, 0, 0);
|
|
m_PropertySheetHelper.GetConfigNew().m_RamWorksMemorySize = size * 16; // Convert from MB to 64K banks
|
|
}
|
|
|
|
void CPageSlots::ConfigResetRamWorks()
|
|
{
|
|
CConfigNeedingRestart& configNew = m_PropertySheetHelper.GetConfigNew();
|
|
if (configNew.m_SlotAux == CT_RamWorksIII)
|
|
{
|
|
configNew.m_RamWorksMemorySize = kDefaultExMemoryBanksRealRW3;
|
|
}
|
|
}
|