From 8cd51ba15551816544c27189e559625f1cc6e625 Mon Sep 17 00:00:00 2001 From: TomCh Date: Thu, 17 Nov 2022 21:08:11 +0000 Subject: [PATCH] Show Disk II Slot 5 status (#1134, PR #1137) . In 2x windowed mode: always show slot 5 Disk II LEDs. . Add tooltips for slot 5/6 track/sector info (d1 & d2) - shows dec/hex & fractional track position. - but this track/sector info is now on a UI toggle in the Config -> Disk tab. . Debugger: add 'DISK SLOT n' - to set current slot of Disk II card - ie. support 'DISK INFO' for slot 5 --- resource/Applewin.rc | 5 +- resource/resource.h | 3 +- source/Common.h | 1 + source/Configuration/PageDisk.cpp | 14 + source/Debugger/Debug.cpp | 41 ++- source/Debugger/Debugger_Commands.cpp | 3 +- source/Debugger/Debugger_Types.h | 5 +- source/Disk.cpp | 13 +- source/Disk.h | 3 +- source/FrameBase.h | 1 + source/Utilities.cpp | 3 + source/Windows/Win32Frame.cpp | 16 +- source/Windows/Win32Frame.h | 63 +++- source/Windows/WinFrame.cpp | 500 +++++++++++++++++--------- 14 files changed, 460 insertions(+), 211 deletions(-) diff --git a/resource/Applewin.rc b/resource/Applewin.rc index dd3a842e..7c563bfc 100644 --- a/resource/Applewin.rc +++ b/resource/Applewin.rc @@ -180,14 +180,15 @@ CAPTION "Disk" FONT 8, "MS Shell Dlg", 0, 0, 0x0 BEGIN GROUPBOX "Floppy Disk Drives",IDC_STATIC,5,7,200,125 - CONTROL "&Enhanced disk access speed (all drives)",IDC_ENHANCE_DISK_ENABLE,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,10,19,150,10 + CONTROL "&Enhanced disk access speed (all drives)",IDC_ENHANCE_DISK_ENABLE,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,10,19,135,10 + CONTROL "Show status",IDC_DISKII_STATUS_ENABLE,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,150,19,50,10 LTEXT "Disk 1:",IDC_STATIC,10,36,23,8 LTEXT "Disk 2:",IDC_STATIC,10,53,23,8 COMBOBOX IDC_COMBO_DISK1,40,35,150,30,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP COMBOBOX IDC_COMBO_DISK2,40,52,150,30,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP - CONTROL "Enable &Disk II controller in slot 5",IDC_DISKII_SLOT5_ENABLE,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,10,76,122,10 + CONTROL "Enable &Disk II controller in slot 5",IDC_DISKII_SLOT5_ENABLE,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,10,76,115,10 LTEXT "Disk 1:",IDC_STATIC,11,93,23,8 LTEXT "Disk 2:",IDC_STATIC,11,110,23,8 COMBOBOX IDC_COMBO_DISK1_SLOT5,40,92,150,30,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP diff --git a/resource/resource.h b/resource/resource.h index 74eefc3a..94ef1002 100644 --- a/resource/resource.h +++ b/resource/resource.h @@ -61,7 +61,8 @@ #define IDC_MB_VOLUME 1010 #define IDC_SAVESTATE_BROWSE 1011 #define IDC_MONOCOLOR 1012 -#define IDC_DISKII_SLOT5_ENABLE 1020 +#define IDC_DISKII_SLOT5_ENABLE 1019 +#define IDC_DISKII_STATUS_ENABLE 1020 #define IDC_HDD_ENABLE 1021 #define IDC_HDD_SWAP 1022 #define IDC_PASTE_FROM_CLIPBOARD 1023 diff --git a/source/Common.h b/source/Common.h index 98256d9e..6047aa54 100644 --- a/source/Common.h +++ b/source/Common.h @@ -67,6 +67,7 @@ enum AppMode_e #define REGVALUE_OLD_APPLE2_TYPE "Computer Emulation" // Deprecated #define REGVALUE_CONFIRM_REBOOT "Confirm Reboot" // Added at 1.24.1 PageConfig #define REGVALUE_FS_SHOW_SUBUNIT_STATUS "Full-screen show subunit status" +#define REGVALUE_SHOW_DISKII_STATUS "Show Disk II Status" #define REGVALUE_SOUND_EMULATION "Sound Emulation" #define REGVALUE_SPKR_VOLUME "Speaker Volume" #define REGVALUE_MB_VOLUME "Mockingboard Volume" diff --git a/source/Configuration/PageDisk.cpp b/source/Configuration/PageDisk.cpp index 7d93a718..52f2f693 100644 --- a/source/Configuration/PageDisk.cpp +++ b/source/Configuration/PageDisk.cpp @@ -27,6 +27,7 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA #include "PropertySheet.h" #include "../Windows/AppleWin.h" +#include "../Windows/Win32Frame.h" #include "../CardManager.h" #include "../Disk.h" // Drive_e, Disk_Status_e #include "../Harddisk.h" @@ -182,6 +183,7 @@ INT_PTR CPageDisk::DlgProcInternal(HWND hWnd, UINT message, WPARAM wparam, LPARA case WM_INITDIALOG: { CheckDlgButton(hWnd, IDC_ENHANCE_DISK_ENABLE, GetCardMgr().GetDisk2CardMgr().GetEnhanceDisk() ? BST_CHECKED : BST_UNCHECKED); + CheckDlgButton(hWnd, IDC_DISKII_STATUS_ENABLE, Win32Frame::GetWin32Frame().GetWindowedModeShowDiskiiStatus() ? BST_CHECKED : BST_UNCHECKED); const UINT slot = SLOT6; if (GetCardMgr().QuerySlot(slot) == CT_Disk2) // NB. SLOT6 not setup in m_PropertySheetHelper.GetConfigNew().m_Slot[] @@ -279,6 +281,18 @@ void CPageDisk::DlgOK(HWND hWnd) REGSAVE(TEXT(REGVALUE_ENHANCE_DISK_SPEED), (DWORD)bNewEnhanceDisk); } + Win32Frame& win32Frame = Win32Frame::GetWin32Frame(); + const bool bNewDiskiiStatus = IsDlgButtonChecked(hWnd, IDC_DISKII_STATUS_ENABLE) ? true : false; + + if (win32Frame.GetWindowedModeShowDiskiiStatus() != bNewDiskiiStatus) + { + REGSAVE(REGVALUE_SHOW_DISKII_STATUS, bNewDiskiiStatus ? 1 : 0); + win32Frame.SetWindowedModeShowDiskiiStatus(bNewDiskiiStatus); + + if (!win32Frame.IsFullScreen()) + win32Frame.FrameRefreshStatus(DRAW_BACKGROUND | DRAW_LEDS | DRAW_DISK_STATUS); + } + m_PropertySheetHelper.PostMsgAfterClose(hWnd, m_Page); } diff --git a/source/Debugger/Debug.cpp b/source/Debugger/Debug.cpp index 813ee8ce..5bf9d4c0 100644 --- a/source/Debugger/Debug.cpp +++ b/source/Debugger/Debug.cpp @@ -3471,8 +3471,9 @@ Update_t CmdFlag (int nArgs) // Disk ___________________________________________________________________________________________ // Usage: +// DISK SLOT [#] // Show [or set] the current slot of the Disk II I/F card (for all other cmds to act on) +// DISK INFO // Info for current drive // DISK # EJECT // Unmount disk -// DISK INFO // DISK # PROTECT # // Write-protect disk on/off // DISK # "" // Mount filename as floppy disk // TODO: @@ -3480,20 +3481,40 @@ Update_t CmdFlag (int nArgs) // DISK # READ Addr:Addr // Read Track/Sector(s) // DISK # WRITE Addr:Addr // Write Track/Sector(s) // Examples: -// DISK 2 INFO -Update_t CmdDisk ( int nArgs) +// DISK INFO +Update_t CmdDisk (int nArgs) { + static UINT currentSlot = SLOT6; + if (! nArgs) return HelpLastCommand(); - if (GetCardMgr().QuerySlot(SLOT6) != CT_Disk2) - return ConsoleDisplayError("No DiskII card in slot-6"); - - Disk2InterfaceCard& diskCard = dynamic_cast(GetCardMgr().GetRef(SLOT6)); - - // check for info command + // check for info or slot command int iParam = 0; - FindParam( g_aArgs[ 1 ].sArg, MATCH_EXACT, iParam, _PARAM_DISK_BEGIN, _PARAM_DISK_END ); + FindParam(g_aArgs[1].sArg, MATCH_EXACT, iParam, _PARAM_DISK_BEGIN, _PARAM_DISK_END); + + if (iParam == PARAM_DISK_SET_SLOT) + { + if (nArgs > 2) + return HelpLastCommand(); + + if (nArgs > 1) + { + UINT slot = g_aArgs[2].nValue; + if (slot < SLOT1 || slot > SLOT7) + return HelpLastCommand(); + + currentSlot = slot; + } + + ConsoleBufferPushFormat("Current Disk II slot = %d", currentSlot); + return ConsoleUpdate(); + } + + if (GetCardMgr().QuerySlot(currentSlot) != CT_Disk2) + return ConsoleDisplayErrorFormat("No Disk II card in slot-%d", currentSlot); + + Disk2InterfaceCard& diskCard = dynamic_cast(GetCardMgr().GetRef(currentSlot)); if (iParam == PARAM_DISK_INFO) { diff --git a/source/Debugger/Debugger_Commands.cpp b/source/Debugger/Debugger_Commands.cpp index faa39160..82a65459 100644 --- a/source/Debugger/Debugger_Commands.cpp +++ b/source/Debugger/Debugger_Commands.cpp @@ -442,8 +442,9 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA {TEXT("SPACES") , NULL, PARAM_CONFIG_SPACES }, {TEXT("TARGET") , NULL, PARAM_CONFIG_TARGET }, // Disk - {TEXT("EJECT") , NULL, PARAM_DISK_EJECT }, {TEXT("INFO") , NULL, PARAM_DISK_INFO }, + {TEXT("SLOT") , NULL, PARAM_DISK_SET_SLOT }, + {TEXT("EJECT") , NULL, PARAM_DISK_EJECT }, {TEXT("PROTECT") , NULL, PARAM_DISK_PROTECT }, {TEXT("READ") , NULL, PARAM_DISK_READ }, // Font (Config) diff --git a/source/Debugger/Debugger_Types.h b/source/Debugger/Debugger_Types.h index 4ff5d59a..b4fb659c 100644 --- a/source/Debugger/Debugger_Types.h +++ b/source/Debugger/Debugger_Types.h @@ -1396,8 +1396,9 @@ const DisasmData_t* pDisasmData; // If != NULL then bytes are marked up as data // Disk , _PARAM_DISK_BEGIN = _PARAM_CONFIG_END // Daisy Chain - , PARAM_DISK_EJECT = _PARAM_DISK_BEGIN // DISK 1 EJECT - , PARAM_DISK_INFO // DISK 1 INFO + , PARAM_DISK_INFO = _PARAM_DISK_BEGIN // DISK INFO + , PARAM_DISK_SET_SLOT // DISK SLOT 6 + , PARAM_DISK_EJECT // DISK 1 EJECT , PARAM_DISK_PROTECT // DISK 1 PROTECT , PARAM_DISK_READ // DISK 1 READ Track Sector NumSectors MemAddress , _PARAM_DISK_END diff --git a/source/Disk.cpp b/source/Disk.cpp index 7ffa4b72..e725e0d5 100644 --- a/source/Disk.cpp +++ b/source/Disk.cpp @@ -107,24 +107,29 @@ int Disk2InterfaceCard::GetCurrentTrack(void) { return ImagePhaseToTrack(m_flop float Disk2InterfaceCard::GetCurrentPhase(void) { return m_floppyDrive[m_currDrive].m_phasePrecise; } UINT Disk2InterfaceCard::GetCurrentBitOffset(void) { return m_floppyDrive[m_currDrive].m_disk.m_bitOffset; } double Disk2InterfaceCard::GetCurrentExtraCycles(void) { return m_floppyDrive[m_currDrive].m_disk.m_extraCycles; } +float Disk2InterfaceCard::GetPhase(const int drive) { return m_floppyDrive[drive].m_phasePrecise; } int Disk2InterfaceCard::GetTrack(const int drive) { return ImagePhaseToTrack(m_floppyDrive[drive].m_disk.m_imagehandle, m_floppyDrive[drive].m_phasePrecise, false); } -std::string Disk2InterfaceCard::FormatPhaseString(float phase) +std::string Disk2InterfaceCard::FormatIntFracString(float phase, bool hex) { const UINT phaseInt = (UINT)phase; const UINT phaseFrac = (UINT)((phase - (float)phaseInt) * 100 + 0.5); - return StrFormat("%02X.%02d", phaseInt, phaseFrac); // "$NN.nn" + if (hex) + return StrFormat("%02X.%02d", phaseInt, phaseFrac); // (hex)"NN.nn" + else + return StrFormat("%02d.%02d", phaseInt, phaseFrac); // (dec)"NN.nn" + } std::string Disk2InterfaceCard::GetCurrentTrackString(void) { - return FormatPhaseString(m_floppyDrive[m_currDrive].m_phasePrecise / 2); + return FormatIntFracString(m_floppyDrive[m_currDrive].m_phasePrecise / 2, true); } std::string Disk2InterfaceCard::GetCurrentPhaseString(void) { - return FormatPhaseString(m_floppyDrive[m_currDrive].m_phasePrecise); + return FormatIntFracString(m_floppyDrive[m_currDrive].m_phasePrecise, true); } LPCTSTR Disk2InterfaceCard::GetCurrentState(void) diff --git a/source/Disk.h b/source/Disk.h index 5f192f23..5f7cb164 100644 --- a/source/Disk.h +++ b/source/Disk.h @@ -165,8 +165,9 @@ public: float GetCurrentPhase(void); UINT GetCurrentBitOffset(void); double GetCurrentExtraCycles(void); + float GetPhase(const int drive); int GetTrack(const int drive); - static std::string FormatPhaseString(float phase); + static std::string FormatIntFracString(float phase, bool hex); std::string GetCurrentTrackString(void); std::string GetCurrentPhaseString(void); LPCTSTR GetCurrentState(void); diff --git a/source/FrameBase.h b/source/FrameBase.h index fcf1c00e..98c0f9e7 100644 --- a/source/FrameBase.h +++ b/source/FrameBase.h @@ -28,6 +28,7 @@ public: virtual void FrameSetCursorPosByMousePos() = 0; virtual void SetFullScreenShowSubunitStatus(bool bShow) = 0; + virtual void SetWindowedModeShowDiskiiStatus(bool bShow) = 0; virtual bool GetBestDisplayResolutionForFullScreen(UINT& bestWidth, UINT& bestHeight, UINT userSpecifiedWidth=0, UINT userSpecifiedHeight=0) = 0; virtual int SetViewportScale(int nNewScale, bool bForce = false) = 0; virtual void SetAltEnterToggleFullScreen(bool mode) = 0; diff --git a/source/Utilities.cpp b/source/Utilities.cpp index 44bd1d8e..5820b9bc 100644 --- a/source/Utilities.cpp +++ b/source/Utilities.cpp @@ -193,6 +193,9 @@ void LoadConfiguration(bool loadImages) if(REGLOAD(TEXT(REGVALUE_FS_SHOW_SUBUNIT_STATUS), &dwTmp)) GetFrame().SetFullScreenShowSubunitStatus(dwTmp ? true : false); + if (REGLOAD(TEXT(REGVALUE_SHOW_DISKII_STATUS), &dwTmp)) + GetFrame().SetWindowedModeShowDiskiiStatus(dwTmp ? true : false); + if(REGLOAD(TEXT(REGVALUE_THE_FREEZES_F8_ROM), &dwTmp)) GetPropertySheet().SetTheFreezesF8Rom(dwTmp); diff --git a/source/Windows/Win32Frame.cpp b/source/Windows/Win32Frame.cpp index e0918df5..d30963d7 100644 --- a/source/Windows/Win32Frame.cpp +++ b/source/Windows/Win32Frame.cpp @@ -60,20 +60,20 @@ Win32Frame::Win32Frame() g_bScrollLock_FullSpeed = false; - g_nTrackDrive1 = -1; - g_nTrackDrive2 = -1; - g_nSectorDrive1 = -1; - g_nSectorDrive2 = -1; - g_strTrackDrive1 = "??"; - g_strTrackDrive2 = "??"; - g_strSectorDrive1 = "??"; - g_strSectorDrive2 = "??"; + for (UINT slot = 0; slot < NUM_SLOTS; slot++) + { + g_nSector[slot][0] = -1; + g_nSector[slot][1] = -1; + } g_eStatusDrive1 = DISK_STATUS_OFF; g_eStatusDrive2 = DISK_STATUS_OFF; // Set g_nViewportScale, g_nViewportCX, g_nViewportCY & buttonx, buttony SetViewportScale(kDEFAULT_VIEWPORT_SCALE, true); + + // Set m_showDiskiiStatus, m_redrawDiskiiStatus + SetWindowedModeShowDiskiiStatus(false); } void Win32Frame::VideoCreateDIBSection(bool resetVideoState) diff --git a/source/Windows/Win32Frame.h b/source/Windows/Win32Frame.h index 4f8c1183..77490479 100644 --- a/source/Windows/Win32Frame.h +++ b/source/Windows/Win32Frame.h @@ -2,6 +2,7 @@ #include "FrameBase.h" #include "DiskImage.h" +#include "Card.h" class Video; @@ -26,7 +27,7 @@ class Win32Frame : public FrameBase { public: Win32Frame(void); - virtual ~Win32Frame(void){} + virtual ~Win32Frame(void) {} static Win32Frame& GetWin32Frame(); static LRESULT CALLBACK FrameWndProc(HWND window, UINT message, WPARAM wparam, LPARAM lparam); @@ -39,7 +40,8 @@ public: virtual void FrameSetCursorPosByMousePos(); virtual void SetFullScreenShowSubunitStatus(bool bShow); - virtual bool GetBestDisplayResolutionForFullScreen(UINT& bestWidth, UINT& bestHeight, UINT userSpecifiedWidth=0, UINT userSpecifiedHeight=0); + virtual void SetWindowedModeShowDiskiiStatus(bool bShow); + virtual bool GetBestDisplayResolutionForFullScreen(UINT& bestWidth, UINT& bestHeight, UINT userSpecifiedWidth = 0, UINT userSpecifiedHeight = 0); virtual int SetViewportScale(int nNewScale, bool bForce = false); virtual void SetAltEnterToggleFullScreen(bool mode); @@ -57,9 +59,10 @@ public: virtual std::string Video_GetScreenShotFolder() const; - virtual std::shared_ptr CreateNetworkBackend(const std::string & interfaceName); + virtual std::shared_ptr CreateNetworkBackend(const std::string& interfaceName); bool GetFullScreenShowSubunitStatus(void); + bool GetWindowedModeShowDiskiiStatus(void); int GetFullScreenOffsetX(void); int GetFullScreenOffsetY(void); bool IsFullScreen(void); @@ -90,6 +93,9 @@ private: void Benchmark(void); void DisplayLogo(void); + void GetTrackSector(UINT slot, int& drive1Track, int& drive2Track, int& activeFloppy); + void CreateTrackSectorStrings(int track, int sector, std::string& strTrack, std::string& strSector); + void DrawTrackSector(HDC dc, UINT slot, int drive1Track, int drive1Sector, int drive2Track, int drive2Sector); void FrameDrawDiskLEDS(HDC hdc); // overloaded Win32 only, call via GetWin32Frame() void FrameDrawDiskStatus(HDC hdc); // overloaded Win32 only, call via GetWin32Frame() void EraseButton(int number); @@ -110,7 +116,7 @@ private: void FrameResizeWindow(int nNewScale); void RevealCursor(); void ScreenWindowResize(const bool bCtrlKey); - void UpdateMouseInAppleViewport(int iOutOfBoundsX, int iOutOfBoundsY, int x=0, int y=0); + void UpdateMouseInAppleViewport(int iOutOfBoundsX, int iOutOfBoundsY, int x = 0, int y = 0); void DrawCrosshairsMouse(); void FrameSetCursorPosByMousePos(int x, int y, int dx, int dy, bool bLeavingAppleScreen); void CreateGdiObjects(void); @@ -118,6 +124,7 @@ private: void FrameShowCursor(BOOL bShow); void FullScreenRevealCursor(void); void GetWidthHeight(int& nWidth, int& nHeight); + void SetSlotUIOffsets(void); bool g_bAltEnter_ToggleFullScreen; // Default for ALT+ENTER is to toggle between windowed and full-screen modes bool g_bIsFullScreen; @@ -134,8 +141,9 @@ private: bool g_bAppActive; bool g_bFrameActive; bool g_windowMinimized; - std::string driveTooltip; bool g_bFullScreen_ShowSubunitStatus; + bool m_showDiskiiStatus; + bool m_redrawDiskiiStatus; int g_win_fullscreen_offsetx; int g_win_fullscreen_offsety; UINT m_bestWidthForFullScreen; @@ -163,8 +171,13 @@ private: RECT framerect; BOOL helpquit; + static const UINT smallfontHeight = 11; HFONT smallfont; + HWND tooltipwindow; + std::string driveTooltip; + enum { TTID_DRIVE1_BUTTON = 0, TTID_DRIVE2_BUTTON, TTID_SLOT6_TRK_SEC_INFO, TTID_SLOT5_TRK_SEC_INFO, TTID_MAX }; + int viewportx; // Default to Normal (non-FullScreen) mode int viewporty; // Default to Normal (non-FullScreen) mode @@ -183,14 +196,38 @@ private: //=========================== HBITMAP g_hDiskWindowedLED[NUM_DISK_STATUS]; - int g_nTrackDrive1; - int g_nTrackDrive2; - int g_nSectorDrive1; - int g_nSectorDrive2; - std::string g_strTrackDrive1; - std::string g_strTrackDrive2; - std::string g_strSectorDrive1; - std::string g_strSectorDrive2; + // Y-offsets from end of last button + static const UINT yOffsetSlot6LEDNumbers = 5; + static const UINT yOffsetSlot6LEDs = yOffsetSlot6LEDNumbers + 1; + static const UINT yOffsetCapsLock = yOffsetSlot6LEDs + smallfontHeight; + static const UINT yOffsetHardDiskLED = yOffsetSlot6LEDs + smallfontHeight + 1; + // 2x (or more) Windowed mode: Disk II LEDs and track/sector info + struct D2FullUI // Disk II full UI + { + static const UINT yOffsetSlot6TrackInfo = 35; + static const UINT yOffsetSlot6SectorInfo = yOffsetSlot6TrackInfo + smallfontHeight; + static const UINT yOffsetSlot5Label = yOffsetSlot6SectorInfo + smallfontHeight + 3; + static const UINT yOffsetSlot5LEDNumbers = yOffsetSlot5Label + smallfontHeight + 1; + static const UINT yOffsetSlot5LEDs = yOffsetSlot5LEDNumbers + 1; + static const UINT yOffsetSlot5TrackInfo = yOffsetSlot5LEDs + smallfontHeight; + static const UINT yOffsetSlot5SectorInfo = yOffsetSlot5TrackInfo + smallfontHeight; + }; + // 2x (or more) Windowed mode: Disk II LEDs only (no track/sector info) + struct D2CompactUI // Disk II compact UI + { + static const UINT yOffsetSlot5Label = 35; + static const UINT yOffsetSlot5LEDNumbers = yOffsetSlot5Label + smallfontHeight + 1; + static const UINT yOffsetSlot5LEDs = yOffsetSlot5LEDNumbers + 1; + }; + const UINT yOffsetSlot6TrackInfo = D2FullUI::yOffsetSlot6TrackInfo; + const UINT yOffsetSlot6SectorInfo = D2FullUI::yOffsetSlot6SectorInfo; + UINT yOffsetSlot5Label; + UINT yOffsetSlot5LEDNumbers; + UINT yOffsetSlot5LEDs; + const UINT yOffsetSlot5TrackInfo = D2FullUI::yOffsetSlot5TrackInfo; + const UINT yOffsetSlot5SectorInfo = D2FullUI::yOffsetSlot5SectorInfo; + + int g_nSector[NUM_SLOTS][2]; Disk_Status_e g_eStatusDrive1; Disk_Status_e g_eStatusDrive2; diff --git a/source/Windows/WinFrame.cpp b/source/Windows/WinFrame.cpp index dcf7f023..44afb7f0 100644 --- a/source/Windows/WinFrame.cpp +++ b/source/Windows/WinFrame.cpp @@ -27,6 +27,7 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "StdAfx.h" +#include #include "Windows/Win32Frame.h" #include "Windows/AppleWin.h" @@ -231,7 +232,7 @@ void Win32Frame::CreateGdiObjects(void) btnfacepen = CreatePen(PS_SOLID,1,GetSysColor(COLOR_BTNFACE)); btnhighlightpen = CreatePen(PS_SOLID,1,GetSysColor(COLOR_BTNHIGHLIGHT)); btnshadowpen = CreatePen(PS_SOLID,1,GetSysColor(COLOR_BTNSHADOW)); - smallfont = CreateFont(11,6,0,0,FW_NORMAL,0,0,0,ANSI_CHARSET, + smallfont = CreateFont(smallfontHeight,6,0,0,FW_NORMAL,0,0,0,ANSI_CHARSET, OUT_DEFAULT_PRECIS,CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY,VARIABLE_PITCH | FF_SWISS, TEXT("Small Fonts")); @@ -519,6 +520,34 @@ void Win32Frame::SetFullScreenShowSubunitStatus(bool bShow) g_bFullScreen_ShowSubunitStatus = bShow; } +bool Win32Frame::GetWindowedModeShowDiskiiStatus(void) +{ + return m_showDiskiiStatus; +} + +void Win32Frame::SetWindowedModeShowDiskiiStatus(bool bShow) +{ + m_showDiskiiStatus = bShow; + m_redrawDiskiiStatus = true; + SetSlotUIOffsets(); +} + +void Win32Frame::SetSlotUIOffsets(void) +{ + if (m_showDiskiiStatus) + { + yOffsetSlot5Label = D2FullUI::yOffsetSlot5Label; + yOffsetSlot5LEDNumbers = D2FullUI::yOffsetSlot5LEDNumbers; + yOffsetSlot5LEDs = D2FullUI::yOffsetSlot5LEDs; + } + else + { + yOffsetSlot5Label = D2CompactUI::yOffsetSlot5Label; + yOffsetSlot5LEDNumbers = D2CompactUI::yOffsetSlot5LEDNumbers; + yOffsetSlot5LEDs = D2CompactUI::yOffsetSlot5LEDs; + } +} + void Win32Frame::FrameDrawDiskLEDS() { FrameDrawDiskLEDS((HDC)0); @@ -530,27 +559,14 @@ void Win32Frame::FrameDrawDiskLEDS( HDC passdc ) g_eStatusDrive1 = DISK_STATUS_OFF; g_eStatusDrive2 = DISK_STATUS_OFF; - // Slot6 drive takes priority unless it's off: if (GetCardMgr().QuerySlot(SLOT6) == CT_Disk2) dynamic_cast(GetCardMgr().GetRef(SLOT6)).GetLightStatus(&g_eStatusDrive1, &g_eStatusDrive2); - // Slot5: - { - Disk_Status_e eDrive1StatusSlot5 = DISK_STATUS_OFF; - Disk_Status_e eDrive2StatusSlot5 = DISK_STATUS_OFF; - if (GetCardMgr().QuerySlot(SLOT5) == CT_Disk2) - dynamic_cast(GetCardMgr().GetRef(SLOT5)).GetLightStatus(&eDrive1StatusSlot5, &eDrive2StatusSlot5); - - if (g_eStatusDrive1 == DISK_STATUS_OFF) g_eStatusDrive1 = eDrive1StatusSlot5; - if (g_eStatusDrive2 == DISK_STATUS_OFF) g_eStatusDrive2 = eDrive2StatusSlot5; - } - // Draw Track/Sector FrameReleaseDC(); HDC dc = (passdc ? passdc : GetDC(g_hFrameWindow)); - - int x = buttonx; - int y = buttony+BUTTONS*BUTTONCY+1; + const int x = buttonx; + const int y = buttony + BUTTONS * BUTTONCY + 1; if (g_bIsFullScreen) { @@ -562,17 +578,27 @@ void Win32Frame::FrameDrawDiskLEDS( HDC passdc ) SetBkColor(dc,RGB(0,0,0)); SetTextAlign(dc,TA_LEFT | TA_TOP); - SetTextColor(dc, g_aDiskFullScreenColorsLED[g_eStatusDrive1] ); + SetTextColor(dc, g_aDiskFullScreenColorsLED[g_eStatusDrive1]); TextOut(dc,x+ 3,y+2,TEXT("1"),1); - SetTextColor(dc, g_aDiskFullScreenColorsLED[g_eStatusDrive2] ); + SetTextColor(dc, g_aDiskFullScreenColorsLED[g_eStatusDrive2]); TextOut(dc,x+13,y+2,TEXT("2"),1); } else { - RECT rDiskLed = {0,0,8,8}; - DrawBitmapRect(dc,x+12,y+6,&rDiskLed,g_hDiskWindowedLED[g_eStatusDrive1]); - DrawBitmapRect(dc,x+31,y+6,&rDiskLed,g_hDiskWindowedLED[g_eStatusDrive2]); + RECT rDiskLed = { 0,0,8,8 }; + DrawBitmapRect(dc, x + 12, y + yOffsetSlot6LEDs, &rDiskLed, g_hDiskWindowedLED[g_eStatusDrive1]); + DrawBitmapRect(dc, x + 31, y + yOffsetSlot6LEDs, &rDiskLed, g_hDiskWindowedLED[g_eStatusDrive2]); + + if (g_nViewportScale > 1 && GetCardMgr().QuerySlot(SLOT5) == CT_Disk2) + { + Disk_Status_e eDrive1StatusSlot5 = DISK_STATUS_OFF; + Disk_Status_e eDrive2StatusSlot5 = DISK_STATUS_OFF; + dynamic_cast(GetCardMgr().GetRef(SLOT5)).GetLightStatus(&eDrive1StatusSlot5, &eDrive2StatusSlot5); + + DrawBitmapRect(dc, x + 12, y + yOffsetSlot5LEDs, &rDiskLed, g_hDiskWindowedLED[eDrive1StatusSlot5]); + DrawBitmapRect(dc, x + 31, y + yOffsetSlot5LEDs, &rDiskLed, g_hDiskWindowedLED[eDrive2StatusSlot5]); + } } } @@ -581,6 +607,123 @@ void Win32Frame::FrameDrawDiskStatus() FrameDrawDiskStatus((HDC)0); } +void Win32Frame::GetTrackSector(UINT slot, int& drive1Track, int& drive2Track, int& activeFloppy) +{ + // DOS3.3 ProDOS + // Slot $B7E9 $BE3C(DEFSLT=Default Slot) ; ref: Beneath Apple ProDOS 8-3 + // Drive $B7EA $BE3D(DEFDRV=Default Drive) ; ref: Beneath Apple ProDOS 8-3 + // Track $B7EC LC1 $D356 + // Sector $B7ED LC1 $D357 + // RWTS LC1 $D300 + + drive1Track = drive2Track = activeFloppy = 0; + if (GetCardMgr().QuerySlot(slot) != CT_Disk2) + return; + + Disk2InterfaceCard& disk2Card = dynamic_cast(GetCardMgr().GetRef(slot)); + activeFloppy = disk2Card.GetCurrentDrive(); + drive1Track = disk2Card.GetTrack(DRIVE_1); + drive2Track = disk2Card.GetTrack(DRIVE_2); + + // Probe known OS's for default Slot/Track/Sector + const bool isProDOS = mem[0xBF00] == 0x4C; + bool isSectorValid = false; + int drive1Sector = -1, drive2Sector = -1; + + // Try DOS3.3 Sector + if (!isProDOS) + { + const int nDOS33slot = mem[0xB7E9] / 16; + const int nDOS33track = mem[0xB7EC]; + const int nDOS33sector = mem[0xB7ED]; + + if ((nDOS33slot == slot) + && (nDOS33track >= 0 && nDOS33track < 40) + && (nDOS33sector >= 0 && nDOS33sector < 16)) + { +#if _DEBUG && 0 + if (nDOS33track != nDisk1Track) + { + LogOutput("\n\n\nWARNING: DOS33Track: %d (%02X) != nDisk1Track: %d (%02X)\n\n\n", nDOS33track, nDOS33track, nDisk1Track, nDisk1Track); + } +#endif // _DEBUG + + /**/ if (activeFloppy == 0) drive1Sector = nDOS33sector; + else if (activeFloppy == 1) drive2Sector = nDOS33sector; + + isSectorValid = true; + } + } + else // isProDOS + { + // we can't just read from mem[ 0xD357 ] since it might be bank-switched from ROM + // and we need the Language Card RAM + const int nProDOSslot = mem[0xBE3C]; + const int nProDOStrack = *MemGetMainPtr(0xC356); // LC1 $D356 + const int nProDOSsector = *MemGetMainPtr(0xC357); // LC1 $D357 + + if ((nProDOSslot == slot) + && (nProDOStrack >= 0 && nProDOStrack < 40) + && (nProDOSsector >= 0 && nProDOSsector < 16)) + { + /**/ if (activeFloppy == 0) drive1Sector = nProDOSsector; + else if (activeFloppy == 1) drive2Sector = nProDOSsector; + + isSectorValid = true; + } + } + + // Preserve sector so don't get "??" when switching drives, eg. if using COPYA to copy from drive-1 to drive-2 + if (isSectorValid) + { + if (activeFloppy == 0) g_nSector[slot][0] = drive1Sector; + else g_nSector[slot][1] = drive2Sector; + } + else + { + if (activeFloppy == 0) g_nSector[slot][0] = -1; + else g_nSector[slot][1] = -1; + } +} + +void Win32Frame::CreateTrackSectorStrings(int track, int sector, std::string& strTrack, std::string& strSector) +{ + strTrack = StrFormat("%2d", track); + strSector = (sector < 0) ? "??" : StrFormat("%2d", sector); +} + +void Win32Frame::DrawTrackSector(HDC dc, UINT slot, int drive1Track, int drive1Sector, int drive2Track, int drive2Sector) +{ + const int x = buttonx; + const int y = buttony + BUTTONS * BUTTONCY + 1; + + const UINT yOffsetSlotNTrackInfo = (slot == SLOT6) ? yOffsetSlot6TrackInfo : yOffsetSlot5TrackInfo; + const UINT yOffsetSlotNSectorInfo = yOffsetSlotNTrackInfo + smallfontHeight; + + // Erase background (TrackInfo + SectorInfo) + SelectObject(dc, GetStockObject(NULL_PEN)); + SelectObject(dc, btnfacebrush); + Rectangle(dc, x + 4, y + yOffsetSlotNTrackInfo, x + BUTTONCX + 1, y + yOffsetSlotNSectorInfo + smallfontHeight); + + SetTextColor(dc, RGB(0, 0, 0)); + SetBkMode(dc, TRANSPARENT); + + std::string strTrackDrive1, strSectorDrive1, strTrackDrive2, strSectorDrive2; + CreateTrackSectorStrings(drive1Track, drive1Sector, strTrackDrive1, strSectorDrive1); + CreateTrackSectorStrings(drive2Track, drive2Sector, strTrackDrive2, strSectorDrive2); + + std::string text; + text = "T" + strTrackDrive1; + TextOut(dc, x + 6, y + yOffsetSlotNTrackInfo, text.c_str(), text.length()); + text = "S" + strSectorDrive1; + TextOut(dc, x + 6, y + yOffsetSlotNSectorInfo, text.c_str(), text.length()); + + text = "T" + strTrackDrive2; + TextOut(dc, x + 26, y + yOffsetSlotNTrackInfo, text.c_str(), text.length()); + text = "S" + strSectorDrive2; + TextOut(dc, x + 26, y + yOffsetSlotNSectorInfo, text.c_str(), text.length()); +} + // Feature Request #201 Show track status // https://github.com/AppleWin/AppleWin/issues/201 //=========================================================================== @@ -595,87 +738,14 @@ void Win32Frame::FrameDrawDiskStatus( HDC passdc ) if (g_windowMinimized) // Prevent DC leaks when app window is minimised (GH#820) return; - // We use the actual drive since probing from memory doesn't tell us anything we don't already know. - // DOS3.3 ProDOS - // Drive $B7EA $BE3D - // Track $B7EC LC1 $D356 - // Sector $B7ED LC1 $D357 - // RWTS LC1 $D300 - - if (GetCardMgr().QuerySlot(SLOT6) != CT_Disk2) - return; - - Disk2InterfaceCard& disk2Card = dynamic_cast(GetCardMgr().GetRef(SLOT6)); - int nActiveFloppy = disk2Card.GetCurrentDrive(); - int nDisk1Track = disk2Card.GetTrack(DRIVE_1); - int nDisk2Track = disk2Card.GetTrack(DRIVE_2); - - // Probe known OS's for Track/Sector - int isProDOS = mem[ 0xBF00 ] == 0x4C; - bool isValid = true; - - // Try DOS3.3 Sector - if ( !isProDOS ) - { - int nDOS33track = mem[ 0xB7EC ]; - int nDOS33sector = mem[ 0xB7ED ]; - - if ((nDOS33track >= 0 && nDOS33track < 40) - && (nDOS33sector >= 0 && nDOS33sector < 16)) - { -#if _DEBUG && 0 - if (nDOS33track != nDisk1Track) - { - LogOutput( "\n\n\nWARNING: DOS33Track: %d (%02X) != nDisk1Track: %d (%02X)\n\n\n", nDOS33track, nDOS33track, nDisk1Track, nDisk1Track ); - } -#endif // _DEBUG - - /**/ if (nActiveFloppy == 0) g_nSectorDrive1 = nDOS33sector; - else if (nActiveFloppy == 1) g_nSectorDrive2 = nDOS33sector; - } - else - isValid = false; - } - else // isProDOS - { - // we can't just read from mem[ 0xD357 ] since it might be bank-switched from ROM - // and we need the Language Card RAM - // memrom[ 0xD350 ] = " ERROR\x07\x00" Applesoft error message - // T S - int nProDOStrack = *MemGetMainPtr( 0xC356 ); // LC1 $D356 - int nProDOSsector = *MemGetMainPtr( 0xC357 ); // LC1 $D357 - - if ((nProDOStrack >= 0 && nProDOStrack < 40) - && (nProDOSsector >= 0 && nProDOSsector < 16)) - { - /**/ if (nActiveFloppy == 0) g_nSectorDrive1 = nProDOSsector; - else if (nActiveFloppy == 1) g_nSectorDrive2 = nProDOSsector; - } - else - isValid = false; - } - - g_nTrackDrive1 = nDisk1Track; - g_nTrackDrive2 = nDisk2Track; - - if( !isValid ) - { - if (nActiveFloppy == 0) g_nSectorDrive1 = -1; - else g_nSectorDrive2 = -1; - } - - g_strTrackDrive1 = StrFormat( "%2d", g_nTrackDrive1 ); - g_strSectorDrive1 = (g_nSectorDrive1 < 0) ? "??" : StrFormat( "%2d", g_nSectorDrive1 ); - - g_strTrackDrive2 = StrFormat( "%2d", g_nTrackDrive2 ); - g_strSectorDrive2 = (g_nSectorDrive2 < 0) ? "??" : StrFormat( "%2d", g_nSectorDrive2 ); + int nDrive1Track, nDrive2Track, nActiveFloppy; + GetTrackSector(SLOT6, nDrive1Track, nDrive2Track, nActiveFloppy); // Draw Track/Sector FrameReleaseDC(); HDC dc = (passdc ? passdc : GetDC(g_hFrameWindow)); - - int x = buttonx; - int y = buttony+BUTTONS*BUTTONCY+4; + const int x = buttonx; + const int y = buttony + BUTTONS * BUTTONCY + 1; SelectObject(dc,smallfont); SetBkMode(dc,OPAQUE); @@ -684,54 +754,47 @@ void Win32Frame::FrameDrawDiskStatus( HDC passdc ) if (g_bIsFullScreen) { - // GH#57 - drive lights in full screen mode + // GH#57 - drive lights in full screen mode (Slot 6 only) if (!g_bFullScreen_ShowSubunitStatus) return; - SetTextColor(dc, g_aDiskFullScreenColorsLED[ g_eStatusDrive1 ]); - TextOut(dc, x+ 3, y+2, TEXT("1"), 1); + std::string strTrackDrive1, strSectorDrive1, strTrackDrive2, strSectorDrive2; + CreateTrackSectorStrings(nDrive1Track, g_nSector[SLOT6][0], strTrackDrive1, strSectorDrive1); + CreateTrackSectorStrings(nDrive2Track, g_nSector[SLOT6][1], strTrackDrive2, strSectorDrive2); - SetTextColor(dc, g_aDiskFullScreenColorsLED[ g_eStatusDrive2 ]); - TextOut(dc, x+13, y+2, TEXT("2"), 1); - - int dx = 0; std::string text = ( nActiveFloppy == 0 ) - ? StrFormat( "%s/%s ", g_strTrackDrive1.c_str(), g_strSectorDrive1.c_str() ) - : StrFormat( "%s/%s ", g_strTrackDrive2.c_str(), g_strSectorDrive2.c_str() ); + ? StrFormat( "%s/%s ", strTrackDrive1.c_str(), strSectorDrive1.c_str() ) + : StrFormat( "%s/%s ", strTrackDrive2.c_str(), strSectorDrive2.c_str() ); SetTextColor(dc, g_aDiskFullScreenColorsLED[ DISK_STATUS_READ ] ); - TextOut(dc, x+dx, y-12, text.c_str(), text.length()); // original: y+2; y-12 puts status in the Configuration Button Icon + TextOut(dc, x, y, text.c_str(), text.length()); + + SetTextColor(dc, g_aDiskFullScreenColorsLED[g_eStatusDrive1]); + TextOut(dc, x + 3, y + smallfontHeight, TEXT("1"), 1); + + SetTextColor(dc, g_aDiskFullScreenColorsLED[g_eStatusDrive2]); + TextOut(dc, x + 13, y + smallfontHeight, TEXT("2"), 1); } else { // NB. Only draw Track/Sector if 2x windowed - if (g_nViewportScale == 1) + if (g_nViewportScale == 1 || !GetWindowedModeShowDiskiiStatus()) return; - // Erase background - SelectObject(dc, GetStockObject(NULL_PEN)); - SelectObject(dc, btnfacebrush); - Rectangle(dc, x+4, y+32, x+BUTTONCX+1, y+56); // y+35 -> 44 -> 56 + DrawTrackSector(dc, SLOT6, nDrive1Track, g_nSector[SLOT6][0], nDrive2Track, g_nSector[SLOT6][1]); - SetTextColor(dc, RGB(0,0,0)); - SetBkMode(dc, TRANSPARENT); - - std::string text; - text = "T" + g_strTrackDrive1; - TextOut(dc, x+6, y+32, text.c_str(), text.length()); - text = "S" + g_strSectorDrive1; - TextOut(dc, x+6, y+42, text.c_str(), text.length()); - - text = "T" + g_strTrackDrive2; - TextOut(dc, x+26, y+32, text.c_str(), text.length()); - text = "S" + g_strSectorDrive2; - TextOut(dc, x+26, y+42, text.c_str(), text.length()); + // Slot 5's Disk II + if (GetCardMgr().QuerySlot(SLOT5) == CT_Disk2) + { + GetTrackSector(SLOT5, nDrive1Track, nDrive2Track, nActiveFloppy); + DrawTrackSector(dc, SLOT5, nDrive1Track, g_nSector[SLOT5][0], nDrive2Track, g_nSector[SLOT5][1]); + } } } //=========================================================================== -void Win32Frame::DrawStatusArea (HDC passdc, int drawflags) +void Win32Frame::DrawStatusArea(HDC passdc, int drawflags) { if (g_hFrameWindow == NULL) { @@ -743,8 +806,8 @@ void Win32Frame::DrawStatusArea (HDC passdc, int drawflags) FrameReleaseDC(); HDC dc = (passdc ? passdc : GetDC(g_hFrameWindow)); - int x = buttonx; - int y = buttony+BUTTONS*BUTTONCY+1; + const int x = buttonx; + const int y = buttony + BUTTONS * BUTTONCY + 1; const bool bCaps = KeybGetCapsStatus(); Disk_Status_e eHardDriveStatus = DISK_STATUS_OFF; @@ -822,11 +885,29 @@ void Win32Frame::DrawStatusArea (HDC passdc, int drawflags) SetTextAlign(dc,TA_CENTER | TA_TOP); SetTextColor(dc,RGB(0,0,0)); SetBkMode(dc,TRANSPARENT); - TextOut(dc,x+ 7,y+5,TEXT("1"),1); - TextOut(dc,x+27,y+5,TEXT("2"),1); + TextOut(dc, x + 7, y + yOffsetSlot6LEDNumbers, "1", 1); + TextOut(dc, x + 27, y + yOffsetSlot6LEDNumbers, "2", 1); // 1.19.0.0 Hard Disk Status/Indicator Light - TextOut(dc,x+ 7,y+17,TEXT("H"),1); + TextOut(dc, x + 7, y + yOffsetCapsLock, TEXT("H"), 1); + + if (g_nViewportScale > 1 && GetCardMgr().QuerySlot(SLOT5) == CT_Disk2) + { + if (m_redrawDiskiiStatus) + { + m_redrawDiskiiStatus = false; + + // Erase background (Slot6's TrackInfo + SectorInfo + "Slot 5" + LEDs + TrackInfo + SectorInfo) + SelectObject(dc, GetStockObject(NULL_PEN)); + SelectObject(dc, btnfacebrush); + Rectangle(dc, x + 1, y + yOffsetSlot6TrackInfo, x + BUTTONCX + 1, y + yOffsetSlot5SectorInfo + smallfontHeight); + } + + std::string slot5 = "Slot 5:"; + TextOut(dc, x + 15, y + yOffsetSlot5Label, slot5.c_str(), slot5.length()); + TextOut(dc, x + 7, y + yOffsetSlot5LEDNumbers, "1", 1); + TextOut(dc, x + 27, y + yOffsetSlot5LEDNumbers, "2", 1); + } } if (drawflags & DRAW_LEDS) @@ -841,18 +922,18 @@ void Win32Frame::DrawStatusArea (HDC passdc, int drawflags) RECT rCapsLed = {0,0,10,12}; // HACK: HARD-CODED bitmaps size switch (g_Apple2Type) { - case A2TYPE_APPLE2 : - case A2TYPE_APPLE2PLUS : - case A2TYPE_APPLE2E : - case A2TYPE_APPLE2EENHANCED: - default : DrawBitmapRect(dc,x+31,y+17,&rCapsLed,g_hCapsLockBitmap[bCaps != 0]); break; - case A2TYPE_PRAVETS82 : - case A2TYPE_PRAVETS8M : DrawBitmapRect(dc,x+31,y+17,&rCapsLed,g_hCapsBitmapP8 [bCaps != 0]); break; // TODO: FIXME: Shouldn't one of these use g_hCapsBitmapLat ?? - case A2TYPE_PRAVETS8A : DrawBitmapRect(dc,x+31,y+17,&rCapsLed,g_hCapsBitmapP8 [bCaps != 0]); break; + case A2TYPE_APPLE2: + case A2TYPE_APPLE2PLUS: + case A2TYPE_APPLE2E: + case A2TYPE_APPLE2EENHANCED: + default: DrawBitmapRect(dc, x + 31, y + yOffsetCapsLock, &rCapsLed, g_hCapsLockBitmap[bCaps != 0]); break; + case A2TYPE_PRAVETS82: + case A2TYPE_PRAVETS8M: DrawBitmapRect(dc, x + 31, y + yOffsetCapsLock, &rCapsLed, g_hCapsBitmapP8[bCaps != 0]); break; // TODO: FIXME: Shouldn't one of these use g_hCapsBitmapLat ?? + case A2TYPE_PRAVETS8A: DrawBitmapRect(dc, x + 31, y + yOffsetCapsLock, &rCapsLed, g_hCapsBitmapP8[bCaps != 0]); break; } RECT rDiskLed = {0,0,8,8}; - DrawBitmapRect(dc,x+12,y+18,&rDiskLed,g_hDiskWindowedLED[eHardDriveStatus]); + DrawBitmapRect(dc, x + 12, y + yOffsetHardDiskLED, &rDiskLed, g_hDiskWindowedLED[eHardDriveStatus]); } } @@ -1546,29 +1627,87 @@ LRESULT Win32Frame::WndProc( if (((LPNMTTDISPINFO)lparam)->hdr.hwndFrom == tooltipwindow && ((LPNMTTDISPINFO)lparam)->hdr.code == TTN_GETDISPINFO) { LPNMTTDISPINFO pInfo = (LPNMTTDISPINFO)lparam; - SendMessage(pInfo->hdr.hwndFrom, TTM_SETMAXTIPWIDTH, 0, 150); - - Disk2InterfaceCard *pDisk2Slot5 = NULL, *pDisk2Slot6 = NULL; - - if (GetCardMgr().QuerySlot(SLOT5) == CT_Disk2) - pDisk2Slot5 = dynamic_cast(GetCardMgr().GetObj(SLOT5)); - if (GetCardMgr().QuerySlot(SLOT6) == CT_Disk2) - pDisk2Slot6 = dynamic_cast(GetCardMgr().GetObj(SLOT6)); - - std::string slot5 = pDisk2Slot5 ? pDisk2Slot5->GetFullDiskFilename(((LPNMTTDISPINFO)lparam)->hdr.idFrom) : ""; - std::string slot6 = pDisk2Slot6 ? pDisk2Slot6->GetFullDiskFilename(((LPNMTTDISPINFO)lparam)->hdr.idFrom) : ""; - - if (pDisk2Slot5) + if (pInfo->hdr.idFrom == TTID_DRIVE1_BUTTON || pInfo->hdr.idFrom == TTID_DRIVE2_BUTTON) { - if (slot6.empty()) slot6 = ""; - if (slot5.empty()) slot5 = ""; - slot6 = std::string("Slot6: ") + slot6; - slot5 = std::string("Slot5: ") + slot5; - } + SendMessage(pInfo->hdr.hwndFrom, TTM_SETMAXTIPWIDTH, 0, 150); - std::string join = (!slot6.empty() && !slot5.empty()) ? "\r\n" : ""; - driveTooltip = slot6 + join + slot5; - ((LPNMTTDISPINFO)lparam)->lpszText = (LPTSTR)driveTooltip.c_str(); + Disk2InterfaceCard* pDisk2Slot5 = NULL, * pDisk2Slot6 = NULL; + + if (GetCardMgr().QuerySlot(SLOT5) == CT_Disk2) + pDisk2Slot5 = dynamic_cast(GetCardMgr().GetObj(SLOT5)); + if (GetCardMgr().QuerySlot(SLOT6) == CT_Disk2) + pDisk2Slot6 = dynamic_cast(GetCardMgr().GetObj(SLOT6)); + + std::string slot5 = pDisk2Slot5 ? pDisk2Slot5->GetFullDiskFilename(pInfo->hdr.idFrom) : ""; + std::string slot6 = pDisk2Slot6 ? pDisk2Slot6->GetFullDiskFilename(pInfo->hdr.idFrom) : ""; + + if (pDisk2Slot5) + { + if (slot6.empty()) slot6 = ""; + if (slot5.empty()) slot5 = ""; + slot6 = std::string("Slot6: ") + slot6; + slot5 = std::string("Slot5: ") + slot5; + } + + std::string join = (!slot6.empty() && !slot5.empty()) ? "\n" : ""; + driveTooltip = slot6 + join + slot5; + pInfo->lpszText = (LPTSTR)driveTooltip.c_str(); + } + else if (pInfo->hdr.idFrom == TTID_SLOT6_TRK_SEC_INFO || pInfo->hdr.idFrom == TTID_SLOT5_TRK_SEC_INFO) + { + if (!GetWindowedModeShowDiskiiStatus()) + break; + + SendMessage(pInfo->hdr.hwndFrom, TTM_SETMAXTIPWIDTH, 0, 200); + + const UINT slot = (pInfo->hdr.idFrom == TTID_SLOT6_TRK_SEC_INFO) ? SLOT6 : SLOT5; + Disk2InterfaceCard& disk2Card = dynamic_cast(GetCardMgr().GetRef(slot)); + float drive1Track = disk2Card.GetPhase(DRIVE_1) / 2; + float drive2Track = disk2Card.GetPhase(DRIVE_2) / 2; + + // Example tooltip: + // + // Drive 1: Drive 2: + // T$10.00 (T16.00) T$0C.00 (T12.00) + // S$06 (S06) S$0F (S15) + // + driveTooltip = "Drive 1:\t\tDrive 2:\n"; + driveTooltip += "T$"; + driveTooltip += disk2Card.FormatIntFracString(drive1Track, true); + driveTooltip += " (T"; + driveTooltip += disk2Card.FormatIntFracString(drive1Track, false); + driveTooltip += ")"; + driveTooltip += "\tT$"; + driveTooltip += disk2Card.FormatIntFracString(drive2Track, true); + driveTooltip += " (T"; + driveTooltip += disk2Card.FormatIntFracString(drive2Track, false); + driveTooltip += ")"; + driveTooltip += "\n"; + // hex sector + driveTooltip += "S$"; + char sector[3] = "??"; + if (g_nSector[slot][0] >= 0) sprintf_s(sector, "%02X", g_nSector[slot][0]); + driveTooltip += sector; + // dec sector + driveTooltip += " (S"; + strcpy(sector, "??"); + if (g_nSector[slot][0] >= 0) sprintf_s(sector, "%02d", g_nSector[slot][0]); + driveTooltip += sector; + driveTooltip += ")"; + // hex sector + driveTooltip += "\tS$"; + strcpy(sector, "??"); + if (g_nSector[slot][1] >= 0) sprintf_s(sector, "%02X", g_nSector[slot][1]); + driveTooltip += sector; + // dec sector + driveTooltip += " (S"; + strcpy(sector, "??"); + if (g_nSector[slot][1] >= 0) sprintf_s(sector, "%02d", g_nSector[slot][1]); + driveTooltip += sector; + driveTooltip += ")"; + + pInfo->lpszText = (LPTSTR)driveTooltip.c_str(); + } } break; @@ -2282,14 +2421,35 @@ void Win32Frame::SetupTooltipControls(void) toolinfo.lpszText = LPSTR_TEXTCALLBACK; toolinfo.rect.left = BUTTONX; toolinfo.rect.right = toolinfo.rect.left+BUTTONCX+1; - toolinfo.uId = 0; + + toolinfo.uId = TTID_DRIVE1_BUTTON; toolinfo.rect.top = BUTTONY+BTN_DRIVE1*BUTTONCY+1; toolinfo.rect.bottom = toolinfo.rect.top+BUTTONCY; SendMessage(tooltipwindow, TTM_ADDTOOL, 0, (LPARAM)&toolinfo); - toolinfo.uId = 1; + + toolinfo.uId = TTID_DRIVE2_BUTTON; toolinfo.rect.top = BUTTONY+BTN_DRIVE2*BUTTONCY+1; toolinfo.rect.bottom = toolinfo.rect.top+BUTTONCY; SendMessage(tooltipwindow, TTM_ADDTOOL, 0, (LPARAM)&toolinfo); + + if (g_nViewportScale > 1) + { + if (GetCardMgr().QuerySlot(SLOT6) == CT_Disk2) + { + toolinfo.uId = TTID_SLOT6_TRK_SEC_INFO; + toolinfo.rect.top = BUTTONY + BUTTONS * BUTTONCY + 1 + yOffsetSlot6TrackInfo; + toolinfo.rect.bottom = toolinfo.rect.top + smallfontHeight * 2; + SendMessage(tooltipwindow, TTM_ADDTOOL, 0, (LPARAM)&toolinfo); + } + + if (GetCardMgr().QuerySlot(SLOT5) == CT_Disk2) + { + toolinfo.uId = TTID_SLOT5_TRK_SEC_INFO; + toolinfo.rect.top = BUTTONY + BUTTONS * BUTTONCY + 1 + yOffsetSlot5TrackInfo; + toolinfo.rect.bottom = toolinfo.rect.top + smallfontHeight * 2; + SendMessage(tooltipwindow, TTM_ADDTOOL, 0, (LPARAM)&toolinfo); + } + } } // SM_CXPADDEDBORDER is not supported on 2000 & XP, but GetSystemMetrics() returns 0 for unknown values, so this use of SM_CXPADDEDBORDER works on 2000 & XP too: @@ -2360,10 +2520,12 @@ void Win32Frame::FrameResizeWindow(int nNewScale) TOOLINFO toolinfo = {0}; toolinfo.cbSize = sizeof(toolinfo); toolinfo.hwnd = g_hFrameWindow; - toolinfo.uId = 0; - SendMessage(tooltipwindow, TTM_DELTOOL, 0, (LPARAM)&toolinfo); - toolinfo.uId = 1; - SendMessage(tooltipwindow, TTM_DELTOOL, 0, (LPARAM)&toolinfo); + + for (UINT id = 0; id < TTID_MAX; id++) + { + toolinfo.uId = id; + SendMessage(tooltipwindow, TTM_DELTOOL, 0, (LPARAM)&toolinfo); + } // Setup the tooltips for the new window size SetupTooltipControls(); @@ -2455,7 +2617,7 @@ void Win32Frame::FrameCreateWindow(void) InitCommonControls(); tooltipwindow = CreateWindow( - TOOLTIPS_CLASS,NULL,TTS_ALWAYSTIP, + TOOLTIPS_CLASS,NULL,TTS_ALWAYSTIP|TTS_NOPREFIX /*Allow tabs in tooltips*/ , CW_USEDEFAULT,CW_USEDEFAULT,CW_USEDEFAULT,CW_USEDEFAULT, g_hFrameWindow, (HMENU)0,