UI Improvements + dynamic toolbar in fullscreen + new scaling methods

This commit is contained in:
Fabrice CARUSO 2023-01-05 21:05:03 +01:00
parent 71076b9cce
commit bc132ea077
12 changed files with 1103 additions and 954 deletions

View File

@ -93,14 +93,14 @@ BEGIN
COMBOBOX IDC_COMPUTER,45,5,91,100,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP
CONTROL "Confirm reboot",IDC_CHECK_CONFIRM_REBOOT,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,142,8,62,10
GROUPBOX "Video",IDC_STATIC,5,22,200,74
LTEXT "Mo&de:",IDC_STATIC,12,33,33,8
COMBOBOX IDC_VIDEOTYPE,33,30,103,100,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP
PUSHBUTTON "Monochrome &Color...",IDC_MONOCOLOR,12,46,80,14
CONTROL "50% Scan lines",IDC_CHECK_HALF_SCAN_LINES,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,142,33,62,10
CONTROL "Vertical blend",IDC_CHECK_VERTICAL_BLEND,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,142,48,62,10
CONTROL "Full-Screen: Show drive/keyboard status",IDC_CHECK_FS_SHOW_SUBUNIT_STATUS,
"Button",BS_AUTOCHECKBOX | WS_TABSTOP,12,64,140,10
CONTROL "VidHD in slot 3",IDC_CHECK_VIDHD_IN_SLOT3,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,12,78,140,10
LTEXT "Mo&de:",IDC_STATIC,12,36,33,8
COMBOBOX IDC_VIDEOTYPE,33,33,103,100,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP
PUSHBUTTON "Monochrome &Color...",IDC_MONOCOLOR,10,55,80,14
CONTROL "50% Scan lines",IDC_CHECK_HALF_SCAN_LINES,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,142,34,62,10
CONTROL "Vertical blend",IDC_CHECK_VERTICAL_BLEND,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,142,49,62,10
CONTROL "Integer scale",IDC_CHECK_INTEGER_SCALE,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,142,78,60,10
CONTROL "Full stretch", IDC_CHECK_STRETCHVIDEO, "Button", BS_AUTOCHECKBOX | WS_TABSTOP, 142, 64, 60, 10
CONTROL "VidHD in slot 3",IDC_CHECK_VIDHD_IN_SLOT3,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,12,78,100,10
LTEXT "&Serial Port:",IDC_STATIC,5,108,40,8
COMBOBOX IDC_SERIALPORT,45,106,90,100,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP
PUSHBUTTON "&Ethernet Settings...",IDC_ETHERNET,4,124,80,14
@ -392,6 +392,16 @@ BEGIN
END
END
IDR_MENU_TOOLBAR MENU
BEGIN
POPUP "Toolbar Menu"
BEGIN
MENUITEM "Dock top", ID_TOOLBAR_TOP
MENUITEM "Dock left", ID_TOOLBAR_LEFT
MENUITEM "Dock bottom", ID_TOOLBAR_BOTTOM
MENUITEM "Dock right", ID_TOOLBAR_RIGHT
END
END
/////////////////////////////////////////////////////////////////////////////
//

View File

@ -112,7 +112,7 @@
#define IDC_COMBO_HDD2 1079
#define IDC_COMBO_DISK1 1080
#define IDC_COMBO_DISK2 1081
#define IDC_CHECK_FS_SHOW_SUBUNIT_STATUS 1082
#define IDC_CHECK_INTEGER_SCALE 1082
#define IDC_CHECK_VERTICAL_BLEND 1083
#define IDC_CHECK_50HZ_VIDEO 1084
#define IDC_COMBO_DISK1_SLOT5 1085
@ -123,6 +123,12 @@
#define IDC_CHECK_TFE_VIRTUAL_DNS 1090
#define IDC_TFE_NPCAP_INFO 1091
#define IDC_COMBO_GAME_IO_CONNECTOR 1092
#define IDR_MENU_TOOLBAR 1093
#define ID_TOOLBAR_TOP 1094
#define ID_TOOLBAR_LEFT 1095
#define ID_TOOLBAR_BOTTOM 1096
#define ID_TOOLBAR_RIGHT 1097
#define IDC_CHECK_STRETCHVIDEO 1098
#define IDM_EXIT 40001
#define IDM_HELP 40002
#define IDM_ABOUT 40003
@ -138,7 +144,7 @@
#define _APS_NO_MFC 1
#define _APS_NEXT_RESOURCE_VALUE 149
#define _APS_NEXT_COMMAND_VALUE 40012
#define _APS_NEXT_CONTROL_VALUE 1083
#define _APS_NEXT_CONTROL_VALUE 1099
#define _APS_NEXT_SYMED_VALUE 101
#endif
#endif

View File

@ -36,14 +36,17 @@ enum AppMode_e
#define DRAW_BUTTON_DRIVES (1 << 3)
#define DRAW_DISK_STATUS (1 << 4)
#define BTN_HELP 0
#define BTN_RUN 1
#define BTN_DRIVE1 2
#define BTN_DRIVE2 3
#define BTN_DRIVESWAP 4
#define BTN_FULLSCR 5
#define BTN_DEBUG 6
#define BTN_SETUP 7
#define BTN_HELP 7
#define BTN_RUN 0
#define BTN_DRIVE1 1
#define BTN_DRIVE2 2
#define BTN_DRIVESWAP 3
#define BTN_FULLSCR 4
#define BTN_DEBUG 5
#define BTN_SETUP 6
#define TTID_SLOT6_TRK_SEC_INFO 8
#define TTID_SLOT5_TRK_SEC_INFO 9
// TODO: Move to StringTable.h
#define TITLE_APPLE_2 TEXT("Apple ][ Emulator")
@ -67,7 +70,8 @@ enum AppMode_e
#define REGVALUE_CPU_TYPE "CPU Type"
#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_INTEGERSCALE "Integer scale"
#define REGVALUE_STRETCHVIDEO "Stretch"
#define REGVALUE_SHOW_DISKII_STATUS "Show Disk II Status"
#define REGVALUE_SOUND_EMULATION "Sound Emulation"
#define REGVALUE_SPKR_VOLUME "Speaker Volume"
@ -130,6 +134,7 @@ enum AppMode_e
#define REGVALUE_PREF_WINDOW_X_POS "Window X-Position"
#define REGVALUE_PREF_WINDOW_Y_POS "Window Y-Position"
#define REGVALUE_PREF_HDV_START_DIR "HDV Starting Directory"
#define REGVALUE_PREF_TOOLBAR "Toolbar"
#define WM_USER_BENCHMARK WM_USER+1
#define WM_USER_SAVESTATE WM_USER+2

View File

@ -129,11 +129,15 @@ INT_PTR CPageConfig::DlgProcInternal(HWND hWnd, UINT message, WPARAM wparam, LPA
case IDC_CHECK_CONFIRM_REBOOT:
case IDC_CHECK_HALF_SCAN_LINES:
case IDC_CHECK_VERTICAL_BLEND:
case IDC_CHECK_FS_SHOW_SUBUNIT_STATUS:
case IDC_CHECK_INTEGER_SCALE:
case IDC_CHECK_50HZ_VIDEO:
// Checked in DlgOK()
break;
case IDC_CHECK_STRETCHVIDEO:
EnableWindow(GetDlgItem(hWnd, IDC_CHECK_INTEGER_SCALE), !IsDlgButtonChecked(hWnd, IDC_CHECK_STRETCHVIDEO));
break;
case IDC_CHECK_VIDHD_IN_SLOT3:
{
const UINT newState = IsDlgButtonChecked(hWnd, IDC_CHECK_VIDHD_IN_SLOT3) ? 1 : 0;
@ -218,8 +222,10 @@ INT_PTR CPageConfig::DlgProcInternal(HWND hWnd, UINT message, WPARAM wparam, LPA
m_PropertySheetHelper.FillComboBox(hWnd,IDC_VIDEOTYPE, GetVideo().GetVideoChoices(), GetVideo().GetVideoType());
CheckDlgButton(hWnd, IDC_CHECK_HALF_SCAN_LINES, GetVideo().IsVideoStyle(VS_HALF_SCANLINES) ? BST_CHECKED : BST_UNCHECKED);
Win32Frame& win32Frame = Win32Frame::GetWin32Frame();
CheckDlgButton(hWnd, IDC_CHECK_FS_SHOW_SUBUNIT_STATUS, win32Frame.GetFullScreenShowSubunitStatus() ? BST_CHECKED : BST_UNCHECKED);
CheckDlgButton(hWnd, IDC_CHECK_STRETCHVIDEO, win32Frame.GetStretchVideo() ? BST_CHECKED : BST_UNCHECKED);
CheckDlgButton(hWnd, IDC_CHECK_INTEGER_SCALE, win32Frame.GetIntegerScale() ? BST_CHECKED : BST_UNCHECKED);
EnableWindow(GetDlgItem(hWnd, IDC_CHECK_INTEGER_SCALE), !win32Frame.GetStretchVideo());
CheckDlgButton(hWnd, IDC_CHECK_VERTICAL_BLEND, GetVideo().IsVideoStyle(VS_COLOR_VERTICAL_BLEND) ? BST_CHECKED : BST_UNCHECKED);
EnableWindow(GetDlgItem(hWnd, IDC_CHECK_VERTICAL_BLEND), (GetVideo().GetVideoType() == VT_COLOR_IDEALIZED) ? TRUE : FALSE);
@ -350,12 +356,23 @@ void CPageConfig::DlgOK(HWND hWnd)
//
const bool bNewFSSubunitStatus = IsDlgButtonChecked(hWnd, IDC_CHECK_FS_SHOW_SUBUNIT_STATUS) ? true : false;
const bool bNewFSSubunitStatus = IsDlgButtonChecked(hWnd, IDC_CHECK_INTEGER_SCALE) ? true : false;
if (win32Frame.GetFullScreenShowSubunitStatus() != bNewFSSubunitStatus)
if (win32Frame.GetIntegerScale() != bNewFSSubunitStatus)
{
REGSAVE(TEXT(REGVALUE_FS_SHOW_SUBUNIT_STATUS), bNewFSSubunitStatus ? 1 : 0);
win32Frame.SetFullScreenShowSubunitStatus(bNewFSSubunitStatus);
REGSAVE(TEXT(REGVALUE_INTEGERSCALE), bNewFSSubunitStatus ? 1 : 0);
win32Frame.SetIntegerScale(bNewFSSubunitStatus);
if (win32Frame.IsFullScreen())
win32Frame.FrameRefreshStatus(DRAW_BACKGROUND | DRAW_LEDS | DRAW_DISK_STATUS);
}
const bool bNewStretchVideoStatus = IsDlgButtonChecked(hWnd, IDC_CHECK_STRETCHVIDEO) ? true : false;
if (win32Frame.GetStretchVideo() != bNewStretchVideoStatus)
{
REGSAVE(TEXT(REGVALUE_STRETCHVIDEO), bNewStretchVideoStatus ? 1 : 0);
win32Frame.SetStretchVideo(bNewStretchVideoStatus);
if (win32Frame.IsFullScreen())
win32Frame.FrameRefreshStatus(DRAW_BACKGROUND | DRAW_LEDS | DRAW_DISK_STATUS);

View File

@ -632,21 +632,21 @@ void StretchBltMemToFrameDC(void)
{
Win32Frame& win32Frame = Win32Frame::GetWin32Frame();
int nViewportCX, nViewportCY;
win32Frame.GetViewportCXCY(nViewportCX, nViewportCY);
RECT rc = win32Frame.GetVideoRect();
int xdest = win32Frame.IsFullScreen() ? win32Frame.GetFullScreenOffsetX() : GetVideo().GetFrameBufferCentringOffsetX() * win32Frame.GetViewportScale();
int ydest = win32Frame.IsFullScreen() ? win32Frame.GetFullScreenOffsetY() : GetVideo().GetFrameBufferCentringOffsetY() * win32Frame.GetViewportScale();
int wdest = nViewportCX;
int hdest = nViewportCY;
#if RENDER_BORDERMARGIN
int border = GetVideo().GetFrameBufferBorderWidth();
::InflateRect(&rc, -border, -border);
#endif
BOOL bRes = StretchBlt(
win32Frame.FrameGetDC(), // HDC hdcDest,
xdest, ydest, // int nXOriginDest, int nYOriginDest,
wdest, hdest, // int nWidthDest, int nHeightDest,
rc.left, rc.top, // int nXOriginDest, int nYOriginDest,
rc.right - rc.left, rc.bottom - rc.top, // int nWidthDest, int nHeightDest,
GetDebuggerMemDC(), // HDC hdcSrc,
0, 0, // int nXOriginSrc, int nYOriginSrc,
GetVideo().GetFrameBufferBorderlessWidth(), GetVideo().GetFrameBufferBorderlessHeight(), // int nWidthSrc, int nHeightSrc,
GetVideo().GetFrameBufferBorderlessWidth(), // int nWidthSrc,
GetVideo().GetFrameBufferBorderlessHeight(), // int nHeightSrc,
SRCCOPY // DWORD dwRop
);
}

View File

@ -340,8 +340,9 @@ void DebuggerMouseClick(int x, int y)
// do picking
// NB. Full-screen + VidHD isn't centred yet
const int nOffsetX = win32Frame.IsFullScreen() ? win32Frame.GetFullScreenOffsetX() : win32Frame.Get3DBorderWidth() + GetVideo().GetFrameBufferCentringOffsetX() * win32Frame.GetViewportScale();
const int nOffsetY = win32Frame.IsFullScreen() ? win32Frame.GetFullScreenOffsetY() : win32Frame.Get3DBorderHeight();
RECT rc = win32Frame.GetVideoRect();
const int nOffsetX = rc.left;
const int nOffsetY = rc.top;
const int nOffsetInScreenX = x - nOffsetX;
const int nOffsetInScreenY = y - nOffsetY;

View File

@ -27,10 +27,10 @@ public:
virtual void FrameUpdateApple2Type() = 0;
virtual void FrameSetCursorPosByMousePos() = 0;
virtual void SetFullScreenShowSubunitStatus(bool bShow) = 0;
virtual void SetIntegerScale(bool bShow) = 0;
virtual void SetStretchVideo(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 bool GetBestDisplayResolutionForFullScreen(UINT& bestWidth, UINT& bestHeight, UINT userSpecifiedWidth=0, UINT userSpecifiedHeight=0) = 0;
virtual void SetAltEnterToggleFullScreen(bool mode) = 0;
virtual void SetLoadedSaveStateFlag(const bool bFlag) = 0;

View File

@ -198,8 +198,11 @@ void LoadConfiguration(bool loadImages)
DWORD dwTmp = 0;
if(REGLOAD(TEXT(REGVALUE_FS_SHOW_SUBUNIT_STATUS), &dwTmp))
GetFrame().SetFullScreenShowSubunitStatus(dwTmp ? true : false);
if(REGLOAD(TEXT(REGVALUE_INTEGERSCALE), &dwTmp))
GetFrame().SetIntegerScale(dwTmp ? true : false);
if (REGLOAD(TEXT(REGVALUE_STRETCHVIDEO), &dwTmp))
GetFrame().SetStretchVideo(dwTmp ? true : false);
if (REGLOAD(TEXT(REGVALUE_SHOW_DISKII_STATUS), &dwTmp))
GetFrame().SetWindowedModeShowDiskiiStatus(dwTmp ? true : false);
@ -314,11 +317,6 @@ void LoadConfiguration(bool loadImages)
if (GetCardMgr().IsParallelPrinterCardInstalled())
GetCardMgr().GetParallelPrinterCard()->GetRegistryConfig();
//
if (REGLOAD(TEXT(REGVALUE_WINDOW_SCALE), &dwTmp))
GetFrame().SetViewportScale(dwTmp);
if (REGLOAD(TEXT(REGVALUE_CONFIRM_REBOOT), &dwTmp))
GetFrame().g_bConfirmReboot = dwTmp;
}

View File

@ -804,8 +804,6 @@ static void RepeatInitialization(void)
// Create window after inserting/removing VidHD card (as it affects width & height)
{
Win32Frame::GetWin32Frame().SetViewportScale(Win32Frame::GetWin32Frame().GetViewportScale(), true);
GetFrame().Initialize(true); // g_pFramebufferinfo been created now & COM init'ed
LogFileOutput("Main: VideoInitialize()\n");

View File

@ -17,13 +17,15 @@
Win32Frame::Win32Frame()
{
m_toolbarPosition = ToolbarPosition::TOP;
m_fullScreenToolbarVisible = false;
g_pFramebufferinfo = NULL;
num_draw_devices = 0;
g_lpDD = NULL;
g_hLogoBitmap = (HBITMAP)0;
g_hDeviceBitmap = (HBITMAP)0;
g_hDeviceDC = (HDC)0;
g_bAltEnter_ToggleFullScreen = false;
g_bAltEnter_ToggleFullScreen = true;
g_bIsFullScreen = false;
g_bShowingCursor = true;
g_bLastCursorInAppleViewport = false;
@ -33,15 +35,12 @@ Win32Frame::Win32Frame()
g_bAppActive = false;
g_bFrameActive = false;
g_windowMinimized = false;
g_bFullScreen_ShowSubunitStatus = true;
g_win_fullscreen_offsetx = 0;
g_win_fullscreen_offsety = 0;
g_bIntegerScale = false;
g_bStretchVideo = false;
m_bestWidthForFullScreen = 0;
m_bestHeightForFullScreen = 0;
m_changedDisplaySettings = false;
g_nMaxViewportScale = kDEFAULT_VIEWPORT_SCALE; // Max scale in Windowed mode with borders, buttons etc (full-screen may be +1)
btnfacebrush = (HBRUSH)0;
btnfacepen = (HPEN)0;
btnhighlightpen = (HPEN)0;
@ -55,8 +54,6 @@ Win32Frame::Win32Frame()
helpquit = 0;
smallfont = (HFONT)0;
tooltipwindow = (HWND)0;
viewportx = VIEWPORTX; // Default to Normal (non-FullScreen) mode
viewporty = VIEWPORTY; // Default to Normal (non-FullScreen) mode
g_bScrollLock_FullSpeed = false;
@ -69,9 +66,6 @@ Win32Frame::Win32Frame()
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);
}
@ -354,33 +348,21 @@ void Win32Frame::ChooseMonochromeColor(void)
//===========================================================================
void Win32Frame::VideoDrawLogoBitmap(HDC hDstDC, int xoff, int yoff, int srcw, int srch, int scale)
{
HDC hSrcDC = CreateCompatibleDC(hDstDC);
SelectObject(hSrcDC, g_hLogoBitmap);
StretchBlt(
hDstDC, // hdcDest
xoff, yoff, // nXDest, nYDest
scale * srcw, scale * srch, // nWidth, nHeight
hSrcDC, // hdcSrc
0, 0, // nXSrc, nYSrc
srcw, srch,
SRCCOPY // dwRop
);
DeleteObject(hSrcDC);
}
//===========================================================================
void Win32Frame::DisplayLogo(void)
{
Video& video = GetVideo();
int nLogoX = 0, nLogoY = 0;
int scale = GetViewportScale();
HDC hFrameDC = FrameGetDC();
RECT rc = GetClientArea();
if (!IsFullScreen() || m_fullScreenToolbarVisible)
{
RECT rcToolbar = GetToolbarRect();
ExcludeClipRect(hFrameDC, rcToolbar.left, rcToolbar.top, rcToolbar.right, rcToolbar.bottom);
}
// DRAW THE LOGO
SelectObject(hFrameDC, GetStockObject(NULL_PEN));
@ -389,16 +371,19 @@ void Win32Frame::DisplayLogo(void)
BITMAP bm;
if (GetObject(g_hLogoBitmap, sizeof(bm), &bm))
{
nLogoX = (g_nViewportCX - scale * bm.bmWidth) / 2;
nLogoY = (g_nViewportCY - scale * bm.bmHeight) / 2;
HDC hSrcDC = CreateCompatibleDC(hFrameDC);
SelectObject(hSrcDC, g_hLogoBitmap);
StretchBlt(
hFrameDC, // hdcDest
rc.left, rc.top, // nXDest, nYDest
rc.right - rc.left, rc.bottom - rc.top, // nWidth, nHeight
hSrcDC, // hdcSrc
0, 0, // nXSrc, nYSrc
bm.bmWidth, bm.bmHeight,
SRCCOPY // dwRop
);
if (IsFullScreen())
{
nLogoX += GetFullScreenOffsetX();
nLogoY += GetFullScreenOffsetY();
}
VideoDrawLogoBitmap(hFrameDC, nLogoX, nLogoY, bm.bmWidth, bm.bmHeight, scale);
DeleteObject(hSrcDC);
}
}
@ -409,16 +394,26 @@ void Win32Frame::DisplayLogo(void)
VARIABLE_PITCH | 4 | FF_SWISS,
sFontName);
SelectObject(hFrameDC, font);
SetTextAlign(hFrameDC, TA_RIGHT | TA_TOP);
SetTextAlign(hFrameDC, TA_LEFT | TA_TOP);
SetBkMode(hFrameDC, TRANSPARENT);
std::string strVersion = "Version " + g_VERSIONSTRING;
int xoff = GetFullScreenOffsetX(), yoff = GetFullScreenOffsetY();
#if _DEBUG
strVersion += " - DEBUG";
#endif
int xoff = -8;
int yoff = -8;
SIZE sz;
GetTextExtentPoint32(hFrameDC, strVersion.c_str(), strVersion.length(), &sz);
#define DRAWVERSION(x,y,c) \
SetTextColor(hFrameDC,c); \
TextOut(hFrameDC, \
scale*540+x+xoff,scale*358+y+yoff, \
rc.right - sz.cx + x + xoff, \
rc.bottom - sz.cy + y + yoff, \
strVersion.c_str(), \
strVersion.length());
@ -433,20 +428,182 @@ void Win32Frame::DisplayLogo(void)
DRAWVERSION(0, 0, PALETTERGB(0x70, 0x30, 0xE0));
}
#if _DEBUG
strVersion = "DEBUG";
DRAWVERSION(2, -358 * scale, RGB(0x00, 0x00, 0x00));
DRAWVERSION(1, -357 * scale, RGB(0x00, 0x00, 0x00));
DRAWVERSION(0, -356 * scale, RGB(0xFF, 0x00, 0xFF));
#endif
#undef DRAWVERSION
#undef DRAWVERSION
SelectClipRgn(hFrameDC, NULL);
DeleteObject(font);
}
//===========================================================================
RECT Win32Frame::GetClientArea()
{
RECT rc;
GetClientRect(g_hFrameWindow, &rc);
if (!IsFullScreen())
{
RECT rcToolbar = GetToolbarRect();
SubtractRect(&rc, &rc, &rcToolbar);
}
return rc;
}
RECT Win32Frame::GetToolbarRect()
{
RECT rcClient;
GetClientRect(g_hFrameWindow, &rcClient);
switch (m_toolbarPosition)
{
case ToolbarPosition::RIGHT:
return { rcClient.right - BUTTONCX, rcClient.top, rcClient.right, rcClient.bottom };
case ToolbarPosition::LEFT:
return { rcClient.left, rcClient.top, rcClient.left + BUTTONCX, rcClient.bottom };
case ToolbarPosition::BOTTOM:
return { rcClient.left, rcClient.bottom - BUTTONCY, rcClient.right, rcClient.bottom};
}
// ToolbarPosition::TOP
return { rcClient.left, rcClient.top, rcClient.right, rcClient.top + BUTTONCY };
}
RECT Win32Frame::GetButtonRect(int number)
{
RECT rect = GetToolbarRect();
if (m_toolbarPosition == ToolbarPosition::TOP || m_toolbarPosition == ToolbarPosition::BOTTOM)
{
rect.left = rect.left + number * BUTTONCX;
rect.right = rect.left + BUTTONCX;
}
else
{
rect.top = rect.top + number * BUTTONCY;
rect.bottom = rect.top + BUTTONCY;
}
return rect;
}
int Win32Frame::HitTestButton(int x, int y)
{
RECT rect = GetToolbarRect();
POINT pt = { x, y };
if (::PtInRect(&rect, pt))
{
if (m_toolbarPosition == ToolbarPosition::TOP || m_toolbarPosition == ToolbarPosition::BOTTOM)
{
if (x >= 0 && x <= BUTTONS * BUTTONCX)
return (x - rect.left - 1) / BUTTONCX;
}
else
{
if (y >= 0 && y <= BUTTONS * BUTTONCY)
return (y - rect.top - 1) / BUTTONCY;
}
}
return -1;
}
RECT Win32Frame::GetStatusRect(int number)
{
RECT rc = GetToolbarRect();
int x = rc.left;
int y = rc.top;
if (m_toolbarPosition == ToolbarPosition::TOP || m_toolbarPosition == ToolbarPosition::BOTTOM)
{
x = rc.right - (number + 1) * BUTTONCX - 2;
if (number > 0 && x < BUTTONS * BUTTONCX)
return RECT{ -1, -1, -1, -1 };
}
else
{
y = rc.bottom - (number + 1) * BUTTONCY - 1;
if (number > 0 && y < BUTTONS * BUTTONCY)
return RECT{ -1, -1, -1, -1 };
}
return RECT{ x, y, x + BUTTONCX, y + BUTTONCY };
}
RECT Win32Frame::GetVideoRect()
{
Video& video = GetVideo();
RECT rc = GetClientArea();
// TODO
if (g_bStretchVideo)
return rc;
int h = rc.bottom - rc.top;
int w = rc.right - rc.left;
int x = rc.left + w / 2;
int y = rc.top;
if (g_bIntegerScale)
{
// Integer scale
#if RENDER_BORDERMARGIN
w = video.GetFrameBufferWidth();
h = video.GetFrameBufferHeight();
#else
w = video.GetFrameBufferBorderlessWidth();
h = video.GetFrameBufferBorderlessHeight();
#endif
while (w * 2 <= rc.right - rc.left && h * 2 <= rc.bottom - rc.top)
{
w *= 2;
h *= 2;
}
x = rc.left + (rc.right - rc.left) / 2 - (w / 2);
y = rc.top + (rc.bottom - rc.top) / 2 - (h / 2);
}
else
{
#if RENDER_BORDERMARGIN
float frameBufferRatio = (float)video.GetFrameBufferHeight() / (float)video.GetFrameBufferWidth();
#else
float frameBufferRatio = (float)video.GetFrameBufferBorderlessHeight() / (float)video.GetFrameBufferBorderlessWidth();
#endif
w = (int) (h / frameBufferRatio);
if (w > rc.right - rc.left)
{
w = rc.right - rc.left;
h = (int)(w * frameBufferRatio);
y = rc.top + (rc.bottom - rc.top) / 2 - h / 2;
x = rc.left;
}
else
x = rc.left + (rc.right - rc.left) / 2 - (w / 2);
// Fullscreen : Make sure the diplay fits into a 4:3 display
if (IsFullScreen() && !m_bestWidthForFullScreen && !m_bestHeightForFullScreen)
{
float frameRatio = 3.0 / 4.0;
if (frameRatio > frameBufferRatio)
{
w = (int) (w / frameRatio * frameBufferRatio);
h = (int) (h / frameRatio * frameBufferRatio);
x = rc.left + (rc.right - rc.left) / 2 - (w / 2);
y = rc.top + (rc.bottom - rc.top) / 2 - (h / 2);
}
}
}
return RECT { x, y, x + w, y + h };
}
void Win32Frame::VideoPresentScreen(void)
{
HDC hFrameDC = FrameGetDC();
@ -454,25 +611,53 @@ void Win32Frame::VideoPresentScreen(void)
if (hFrameDC)
{
Video& video = GetVideo();
int xSrc = video.GetFrameBufferBorderWidth();
int ySrc = video.GetFrameBufferBorderHeight();
int xdest = IsFullScreen() ? GetFullScreenOffsetX() : 0;
int ydest = IsFullScreen() ? GetFullScreenOffsetY() : 0;
int wdest = g_nViewportCX;
int hdest = g_nViewportCY;
RECT rc = GetClientArea();
RECT rcVid = GetVideoRect();
SetStretchBltMode(hFrameDC, COLORONCOLOR);
ExcludeClipRect(hFrameDC, rcVid.left, rcVid.top, rcVid.right, rcVid.bottom);
if (m_fullScreenToolbarVisible)
{
RECT rcToolbar = GetToolbarRect();
SubtractRect(&rc, &rc, &rcToolbar);
}
FillSolidRect(hFrameDC, rc.left, rc.top, rc.right, rc.bottom, IsFullScreen() ? 0 : RGB(8, 8, 8));
SelectClipRgn(hFrameDC, NULL);
if (!IsFullScreen() || m_fullScreenToolbarVisible)
{
RECT rcToolbar = GetToolbarRect();
ExcludeClipRect(hFrameDC, rcToolbar.left, rcToolbar.top, rcToolbar.right, rcToolbar.bottom);
}
SetStretchBltMode(hFrameDC, (rcVid.bottom - rcVid.top) < (int) video.GetFrameBufferHeight() ? HALFTONE : COLORONCOLOR); // COLORONCOLOR
#if RENDER_BORDERMARGIN
StretchBlt(
hFrameDC,
xdest, ydest,
wdest, hdest,
rcVid.left, rcVid.top,
rcVid.right - rcVid.left, rcVid.bottom - rcVid.top,
g_hDeviceDC,
xSrc, ySrc,
0, 0,
video.GetFrameBufferWidth(), video.GetFrameBufferHeight(),
SRCCOPY);
#else
// Render without border !?
StretchBlt(
hFrameDC,
rcVid.left, rcVid.top,
rcVid.right - rcVid.left, rcVid.bottom - rcVid.top,
g_hDeviceDC,
video.GetFrameBufferBorderWidth(), video.GetFrameBufferBorderHeight(),
video.GetFrameBufferBorderlessWidth(), video.GetFrameBufferBorderlessHeight(),
SRCCOPY);
}
#endif
SelectClipRgn(hFrameDC, NULL);
}
#ifdef NO_DIRECT_X
#else
//if (g_lpDD) g_lpDD->WaitForVerticalBlank(DDWAITVB_BLOCKBEGIN, NULL);

View File

@ -6,28 +6,18 @@
class Video;
#if 0 // enable non-integral full-screen scaling
#define FULLSCREEN_SCALE_TYPE float
#else
#define FULLSCREEN_SCALE_TYPE int
#endif
// 3D border around the 560x384 Apple II display
#define VIEWPORTX 5
#define VIEWPORTY 5
#define BUTTONX (g_nViewportCX + VIEWPORTX*2)
#define BUTTONY 0
#define BUTTONCX 45
#define BUTTONCY 45
#define BUTTONCX 48
#define BUTTONCY 48
#define BUTTONS 8
// Comment to render without black borders
#define RENDER_BORDERMARGIN 1
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,10 +29,10 @@ public:
virtual void FrameUpdateApple2Type();
virtual void FrameSetCursorPosByMousePos();
virtual void SetFullScreenShowSubunitStatus(bool bShow);
virtual void SetIntegerScale(bool bShow);
virtual void SetStretchVideo(bool bShow);
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);
virtual void SetLoadedSaveStateFlag(const bool bFlag);
@ -59,22 +49,18 @@ public:
virtual std::string Video_GetScreenShotFolder() const;
virtual std::shared_ptr<NetworkBackend> CreateNetworkBackend(const std::string& interfaceName);
virtual std::shared_ptr<NetworkBackend> CreateNetworkBackend(const std::string & interfaceName);
bool GetFullScreenShowSubunitStatus(void);
bool GetIntegerScale(void);
bool GetStretchVideo(void);
bool GetWindowedModeShowDiskiiStatus(void);
int GetFullScreenOffsetX(void);
int GetFullScreenOffsetY(void);
bool IsFullScreen(void);
void FrameRegisterClass();
void FrameCreateWindow(void);
void ChooseMonochromeColor(void);
UINT Get3DBorderWidth(void);
UINT Get3DBorderHeight(void);
void ChooseMonochromeColor(void);
int GetViewportScale(void);
void GetViewportCXCY(int& nViewportCX, int& nViewportCY);
void SetFullScreenViewportScale(int nNewXScale, int nNewYScale);
void ApplyVideoModeChange(void);
HDC FrameGetDC();
@ -82,12 +68,20 @@ public:
bool g_bScrollLock_FullSpeed;
RECT GetClientArea();
RECT GetVideoRect();
RECT GetToolbarRect();
private:
static BOOL CALLBACK DDEnumProc(LPGUID lpGUID, LPCTSTR lpszDesc, LPCTSTR lpszDrvName, LPVOID lpContext);
LRESULT WndProc(HWND window, UINT message, WPARAM wparam, LPARAM lparam);
void VideoCreateDIBSection(bool resetVideoState);
void VideoDrawLogoBitmap(HDC hDstDC, int xoff, int yoff, int srcw, int srch, int scale);
int HitTestButton(int x, int y);
RECT GetButtonRect(int number);
RECT GetStatusRect(int number);
void OnSizeChanged();
void VideoCreateDIBSection(bool resetVideoState);
bool DDInit(void);
void DDUninit(void);
@ -104,10 +98,12 @@ private:
void DrawFrameWindow(bool bPaintingWindow = false);
void DrawStatusArea(HDC passdc, int drawflags);
void Draw3dRect(HDC dc, int x1, int y1, int x2, int y2, BOOL out);
void DrawBitmapRect(HDC dc, int x, int y, LPRECT rect, HBITMAP bitmap);
void DrawBitmapRect(HDC dc, int x, int y, LPRECT rect, HBITMAP bitmap, BOOL transparent);
void FillSolidRect(HDC dc, int x1, int y1, int x2, int y2, COLORREF color);
void ProcessButtonClick(int button, bool bFromButtonUI = false);
bool ConfirmReboot(bool bFromButtonUI);
void ProcessDiskPopupMenu(HWND hwnd, POINT pt, const int iDrive);
void ProcessToolbarPopupMenu(HWND hWnd, POINT point);
void RelayEvent(UINT message, WPARAM wparam, LPARAM lparam);
void SetFullScreenMode(void);
void SetNormalMode(void);
@ -122,8 +118,8 @@ private:
void CreateGdiObjects(void);
void DeleteGdiObjects(void);
void FrameShowCursor(BOOL bShow);
void FullScreenRevealCursor(void);
void GetWidthHeight(int& nWidth, int& nHeight);
void FullScreenRevealCursor(void);
SIZE GetWidthHeight(int scaleFactor);
void SetSlotUIOffsets(void);
bool g_bAltEnter_ToggleFullScreen; // Default for ALT+ENTER is to toggle between windowed and full-screen modes
@ -141,11 +137,11 @@ private:
bool g_bAppActive;
bool g_bFrameActive;
bool g_windowMinimized;
bool g_bFullScreen_ShowSubunitStatus;
bool g_bIntegerScale;
bool m_showDiskiiStatus;
bool m_redrawDiskiiStatus;
int g_win_fullscreen_offsetx;
int g_win_fullscreen_offsety;
bool g_bStretchVideo;
UINT m_bestWidthForFullScreen;
UINT m_bestHeightForFullScreen;
bool m_changedDisplaySettings;
@ -165,8 +161,6 @@ private:
int buttonactive;
int buttondown;
int buttonover;
int buttonx;
int buttony;
HDC g_hFrameDC;
RECT framerect;
@ -176,16 +170,11 @@ private:
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
RECT g_main_window_saved_rect;
int g_main_window_saved_style;
int g_main_window_saved_exstyle;
HBITMAP g_hCapsLockBitmap[2];
HBITMAP g_hHardDiskBitmap[2];
@ -201,6 +190,7 @@ private:
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
{
@ -231,9 +221,10 @@ private:
Disk_Status_e g_eStatusDrive1;
Disk_Status_e g_eStatusDrive2;
enum class ToolbarPosition { TOP = 0, RIGHT = 1, BOTTOM = 2, LEFT = 3 };
ToolbarPosition m_toolbarPosition;
BOOL m_fullScreenToolbarVisible;
static const int kDEFAULT_VIEWPORT_SCALE = 2;
int g_nViewportCX;
int g_nViewportCY;
int g_nViewportScale; // saved REGSAVE
int g_nMaxViewportScale; // Max scale in Windowed mode with borders, buttons etc (full-screen may be +1)
};

File diff suppressed because it is too large Load Diff