diff --git a/build-mingw.ps1 b/build-mingw.ps1 index c362d9b..cfd2c4f 100644 --- a/build-mingw.ps1 +++ b/build-mingw.ps1 @@ -104,6 +104,7 @@ if ($Windres -and (Test-Path $RcPath)) { @Sources ` @LinkInputs ` -lwinmm ` + -lgdiplus ` -lgdi32 ` -luser32 ` -o $ExePath diff --git a/src/include/Tetris.h b/src/include/Tetris.h index 8e10958..3be0caf 100644 --- a/src/include/Tetris.h +++ b/src/include/Tetris.h @@ -6,15 +6,15 @@ #pragma comment(lib, "winmm.lib") -constexpr int GRID = 30; +constexpr int GRID = 40; constexpr int nGameWidth = 10; constexpr int nGameHeight = 20; constexpr int nWidth = 16; constexpr int nHeight = 22; -constexpr int WINDOW_PADDING = 28; -constexpr int SIDE_PANEL_WIDTH = 280; -constexpr int SIDE_PANEL_GAP = 28; -constexpr int SIDE_PANEL_HEIGHT = 760; +constexpr int WINDOW_PADDING = 36; +constexpr int SIDE_PANEL_WIDTH = 304; +constexpr int SIDE_PANEL_GAP = 24; +constexpr int SIDE_PANEL_HEIGHT = 872; constexpr int WINDOW_CLIENT_WIDTH = WINDOW_PADDING * 2 + nGameWidth * GRID + SIDE_PANEL_GAP * 2 + SIDE_PANEL_WIDTH * 2; constexpr int BOARD_CLIENT_HEIGHT = WINDOW_PADDING * 2 + nGameHeight * GRID + 20; constexpr int WINDOW_CLIENT_HEIGHT = (BOARD_CLIENT_HEIGHT > SIDE_PANEL_HEIGHT) ? BOARD_CLIENT_HEIGHT : SIDE_PANEL_HEIGHT; diff --git a/src/source/TetrisRender.cpp b/src/source/TetrisRender.cpp index 9ed694e..f42b89f 100644 --- a/src/source/TetrisRender.cpp +++ b/src/source/TetrisRender.cpp @@ -1,5 +1,104 @@ #include "stdafx.h" #include "Tetris.h" +#include +#include +#include + +#pragma comment(lib, "gdiplus.lib") + +using namespace Gdiplus; + +static std::wstring BuildAssetPath(const wchar_t* relativePath) +{ + wchar_t modulePath[MAX_PATH] = {}; + GetModuleFileNameW(nullptr, modulePath, MAX_PATH); + + std::wstring basePath(modulePath); + size_t lastSlash = basePath.find_last_of(L"\\/"); + if (lastSlash != std::wstring::npos) + { + basePath.resize(lastSlash); + } + + std::wstring projectRelative = basePath + L"\\..\\..\\" + relativePath; + wchar_t fullPath[MAX_PATH] = {}; + DWORD result = GetFullPathNameW(projectRelative.c_str(), MAX_PATH, fullPath, nullptr); + if (result > 0 && result < MAX_PATH) + { + return fullPath; + } + + return projectRelative; +} + +static std::wstring BuildWorkingDirAssetPath(const wchar_t* relativePath) +{ + wchar_t currentDirectory[MAX_PATH] = {}; + DWORD length = GetCurrentDirectoryW(MAX_PATH, currentDirectory); + if (length == 0 || length >= MAX_PATH) + { + return L""; + } + + std::wstring candidate = std::wstring(currentDirectory) + L"\\" + relativePath; + wchar_t fullPath[MAX_PATH] = {}; + DWORD result = GetFullPathNameW(candidate.c_str(), MAX_PATH, fullPath, nullptr); + if (result > 0 && result < MAX_PATH) + { + return fullPath; + } + + return candidate; +} + +static Bitmap* LoadBackgroundImage() +{ + static ULONG_PTR gdiplusToken = 0; + static Bitmap* backgroundImage = nullptr; + static bool attempted = false; + + if (!attempted) + { + attempted = true; + + GdiplusStartupInput startupInput; + if (GdiplusStartup(&gdiplusToken, &startupInput, nullptr) == Ok) + { + const std::wstring candidates[] = + { + BuildAssetPath(L"assets\\images\\background.png"), + BuildWorkingDirAssetPath(L"assets\\images\\background.png"), + BuildAssetPath(L"assets\\images\\background.bmp"), + BuildWorkingDirAssetPath(L"assets\\images\\background.bmp") + }; + + for (const std::wstring& candidate : candidates) + { + if (candidate.empty()) + { + continue; + } + + DWORD attributes = GetFileAttributesW(candidate.c_str()); + if (attributes == INVALID_FILE_ATTRIBUTES || (attributes & FILE_ATTRIBUTE_DIRECTORY) != 0) + { + continue; + } + + Bitmap* loadedImage = Bitmap::FromFile(candidate.c_str(), FALSE); + if (loadedImage != nullptr && loadedImage->GetLastStatus() == Ok) + { + backgroundImage = loadedImage; + break; + } + + delete loadedImage; + } + } + } + + return backgroundImage; +} void TDrawScreen(HDC hdc, HWND hWnd) { @@ -39,6 +138,7 @@ void TDrawScreen(HDC hdc, HWND hWnd) }; int grid = SS(GRID); + int previewMiniCell = SS(16); int panelGap = SS(SIDE_PANEL_GAP); int panelWidth = SS(SIDE_PANEL_WIDTH); int panelHeight = SS(SIDE_PANEL_HEIGHT - WINDOW_PADDING * 2); @@ -80,41 +180,64 @@ void TDrawScreen(HDC hdc, HWND hWnd) const COLORREF titleColor = RGB(104, 62, 84); const COLORREF textColor = RGB(92, 73, 88); const COLORREF accentColor = RGB(228, 145, 182); + const BYTE shellAlpha = 142; + const BYTE panelAlpha = 150; + const BYTE panelNestedAlpha = 128; + const BYTE panelStrongAlpha = 168; - HBRUSH pageBrush = CreateSolidBrush(pageColor); - FillRect(hdc, &clientRect, pageBrush); - DeleteObject(pageBrush); + Bitmap* backgroundImage = LoadBackgroundImage(); + if (backgroundImage != nullptr) + { + Graphics graphics(hdc); + graphics.SetInterpolationMode(InterpolationModeHighQualityBicubic); + graphics.DrawImage( + backgroundImage, + Rect(0, 0, clientRect.right - clientRect.left, clientRect.bottom - clientRect.top)); + SolidBrush washBrush(Color(76, 255, 250, 252)); + graphics.FillRectangle(&washBrush, 0, 0, clientRect.right - clientRect.left, clientRect.bottom - clientRect.top); + } + else + { + HBRUSH pageBrush = CreateSolidBrush(pageColor); + FillRect(hdc, &clientRect, pageBrush); + DeleteObject(pageBrush); + } - HBRUSH blobBrushA = CreateSolidBrush(blobColorA); - HBRUSH blobBrushB = CreateSolidBrush(blobColorB); - HBRUSH oldBrush = (HBRUSH)SelectObject(hdc, blobBrushA); - HPEN oldPen = (HPEN)SelectObject(hdc, GetStockObject(NULL_PEN)); - Ellipse(hdc, clientRect.right - 260, -20, clientRect.right + 80, 260); - Ellipse(hdc, -80, clientRect.bottom - 200, 220, clientRect.bottom + 70); - SelectObject(hdc, blobBrushB); - Ellipse(hdc, clientRect.right - 180, clientRect.bottom - 220, clientRect.right + 120, clientRect.bottom + 40); - SelectObject(hdc, oldBrush); - SelectObject(hdc, oldPen); - DeleteObject(blobBrushA); - DeleteObject(blobBrushB); + HBRUSH oldBrush = nullptr; + HPEN oldPen = nullptr; + if (backgroundImage == nullptr) + { + HBRUSH blobBrushA = CreateSolidBrush(blobColorA); + HBRUSH blobBrushB = CreateSolidBrush(blobColorB); + oldBrush = (HBRUSH)SelectObject(hdc, blobBrushA); + oldPen = (HPEN)SelectObject(hdc, GetStockObject(NULL_PEN)); + Ellipse(hdc, clientRect.right - 260, -20, clientRect.right + 80, 260); + Ellipse(hdc, -80, clientRect.bottom - 200, 220, clientRect.bottom + 70); + SelectObject(hdc, blobBrushB); + Ellipse(hdc, clientRect.right - 180, clientRect.bottom - 220, clientRect.right + 120, clientRect.bottom + 40); + SelectObject(hdc, oldBrush); + SelectObject(hdc, oldPen); + DeleteObject(blobBrushA); + DeleteObject(blobBrushB); + } HFONT titleFont = CreateFont( - -SS(34), 0, 0, 0, FW_BOLD, FALSE, FALSE, FALSE, + -SS(36), 0, 0, 0, FW_BOLD, FALSE, FALSE, FALSE, DEFAULT_CHARSET, OUT_OUTLINE_PRECIS, CLIP_DEFAULT_PRECIS, CLEARTYPE_NATURAL_QUALITY, VARIABLE_PITCH, _T("Microsoft YaHei UI")); HFONT sectionFont = CreateFont( - -SS(24), 0, 0, 0, FW_BOLD, FALSE, FALSE, FALSE, + -SS(22), 0, 0, 0, FW_BOLD, FALSE, FALSE, FALSE, DEFAULT_CHARSET, OUT_OUTLINE_PRECIS, CLIP_DEFAULT_PRECIS, CLEARTYPE_NATURAL_QUALITY, VARIABLE_PITCH, _T("Microsoft YaHei UI")); HFONT bodyFont = CreateFont( - -SS(20), 0, 0, 0, FW_SEMIBOLD, FALSE, FALSE, FALSE, + -SS(18), 0, 0, 0, FW_SEMIBOLD, FALSE, FALSE, FALSE, DEFAULT_CHARSET, OUT_OUTLINE_PRECIS, CLIP_DEFAULT_PRECIS, CLEARTYPE_NATURAL_QUALITY, VARIABLE_PITCH, _T("Microsoft YaHei UI")); HFONT smallFont = CreateFont( - -SS(17), 0, 0, 0, FW_NORMAL, FALSE, FALSE, FALSE, + -SS(15), 0, 0, 0, FW_NORMAL, FALSE, FALSE, FALSE, DEFAULT_CHARSET, OUT_OUTLINE_PRECIS, CLIP_DEFAULT_PRECIS, CLEARTYPE_NATURAL_QUALITY, VARIABLE_PITCH, _T("Microsoft YaHei UI")); @@ -134,6 +257,51 @@ void TDrawScreen(HDC hdc, HWND hWnd) DeleteObject(cardPen); }; + auto DrawPanelCardAlpha = [&](const RECT& rect, COLORREF fillColor, COLORREF borderColor, int radius, BYTE alpha) + { + Graphics graphics(hdc); + graphics.SetSmoothingMode(SmoothingModeAntiAlias); + + GraphicsPath path; + INT left = static_cast(rect.left); + INT top = static_cast(rect.top); + INT width = static_cast(rect.right - rect.left); + INT height = static_cast(rect.bottom - rect.top); + INT corner = static_cast(SS(radius)); + + path.AddArc(left, top, corner, corner, 180.0f, 90.0f); + path.AddArc(left + width - corner, top, corner, corner, 270.0f, 90.0f); + path.AddArc(left + width - corner, top + height - corner, corner, corner, 0.0f, 90.0f); + path.AddArc(left, top + height - corner, corner, corner, 90.0f, 90.0f); + path.CloseFigure(); + + SolidBrush brush(Color(alpha, GetRValue(fillColor), GetGValue(fillColor), GetBValue(fillColor))); + Pen pen(Color(232, GetRValue(borderColor), GetGValue(borderColor), GetBValue(borderColor)), 1.0f); + graphics.FillPath(&brush, &path); + graphics.DrawPath(&pen, &path); + }; + + auto DrawPanelHeader = [&](const RECT& panelRect, const TCHAR* title, int lineWidth) + { + SelectObject(hdc, titleFont); + SetTextColor(hdc, titleColor); + RECT titleRect = + { + panelRect.left + SS(24), + panelRect.top + SS(20), + panelRect.right - SS(24), + panelRect.top + SS(62) + }; + DrawText(hdc, title, -1, &titleRect, DT_LEFT | DT_VCENTER | DT_SINGLELINE); + + HPEN localAccentPen = CreatePen(PS_SOLID, SS(3), accentColor); + HPEN savedPen = (HPEN)SelectObject(hdc, localAccentPen); + MoveToEx(hdc, panelRect.left + SS(24), panelRect.top + SS(78), nullptr); + LineTo(hdc, panelRect.left + SS(24) + SS(lineWidth), panelRect.top + SS(78)); + SelectObject(hdc, savedPen); + DeleteObject(localAccentPen); + }; + if (currentScreen == SCREEN_MENU) { RECT menuCard = @@ -398,24 +566,14 @@ void TDrawScreen(HDC hdc, HWND hWnd) return; } - HPEN framePen = CreatePen(PS_SOLID, 1, frameColor); - HBRUSH gameCardBrush = CreateSolidBrush(cardColor); - HBRUSH panelBrush = CreateSolidBrush(cardColor); - oldPen = (HPEN)SelectObject(hdc, framePen); - oldBrush = (HBRUSH)SelectObject(hdc, gameCardBrush); - RoundRect(hdc, gameRect.left - SS(10), gameRect.top - SS(10), gameRect.right + SS(10), gameRect.bottom + SS(10), SS(28), SS(28)); - SelectObject(hdc, panelBrush); - RoundRect(hdc, leftPanelRect.left, leftPanelRect.top, leftPanelRect.right, leftPanelRect.bottom, SS(30), SS(30)); - RoundRect(hdc, rightPanelRect.left, rightPanelRect.top, rightPanelRect.right, rightPanelRect.bottom, SS(30), SS(30)); - SelectObject(hdc, oldBrush); - SelectObject(hdc, oldPen); - DeleteObject(gameCardBrush); - DeleteObject(panelBrush); - DeleteObject(framePen); - - HBRUSH boardBrush = CreateSolidBrush(boardColor); - FillRect(hdc, &gameRect, boardBrush); - DeleteObject(boardBrush); + DrawPanelCardAlpha( + { gameRect.left - SS(10), gameRect.top - SS(10), gameRect.right + SS(10), gameRect.bottom + SS(10) }, + cardColor, + frameColor, + 28, + shellAlpha); + DrawPanelCardAlpha(leftPanelRect, cardColor, frameColor, 30, shellAlpha); + DrawPanelCardAlpha(rightPanelRect, cardColor, frameColor, 30, shellAlpha); RECT innerRect = { @@ -425,9 +583,23 @@ void TDrawScreen(HDC hdc, HWND hWnd) gameRect.bottom - SS(6) }; - HBRUSH innerBrush = CreateSolidBrush(boardInnerColor); - FillRect(hdc, &innerRect, innerBrush); - DeleteObject(innerBrush); + { + Graphics boardGraphics(hdc); + SolidBrush boardBrush(Color(164, GetRValue(boardColor), GetGValue(boardColor), GetBValue(boardColor))); + SolidBrush innerBrush(Color(176, GetRValue(boardInnerColor), GetGValue(boardInnerColor), GetBValue(boardInnerColor))); + boardGraphics.FillRectangle( + &boardBrush, + static_cast(gameRect.left), + static_cast(gameRect.top), + static_cast(gameRect.right - gameRect.left), + static_cast(gameRect.bottom - gameRect.top)); + boardGraphics.FillRectangle( + &innerBrush, + static_cast(innerRect.left), + static_cast(innerRect.top), + static_cast(innerRect.right - innerRect.left), + static_cast(innerRect.bottom - innerRect.top)); + } HPEN borderPen = CreatePen(PS_SOLID, SS(2), RGB(132, 108, 146)); oldPen = (HPEN)SelectObject(hdc, borderPen); @@ -582,17 +754,8 @@ void TDrawScreen(HDC hdc, HWND hWnd) } HFONT oldFont = (HFONT)SelectObject(hdc, titleFont); - SetTextColor(hdc, titleColor); - TextOut(hdc, leftPanelRect.left + SS(24), leftPanelRect.top + SS(22), _T("\u5bf9\u5c40\u4fe1\u606f"), lstrlen(_T("\u5bf9\u5c40\u4fe1\u606f"))); - - HPEN accentPen = CreatePen(PS_SOLID, SS(3), accentColor); - oldPen = (HPEN)SelectObject(hdc, accentPen); - MoveToEx(hdc, leftPanelRect.left + SS(24), leftPanelRect.top + SS(68), nullptr); - LineTo(hdc, leftPanelRect.left + SS(160), leftPanelRect.top + SS(68)); - MoveToEx(hdc, rightPanelRect.left + SS(24), rightPanelRect.top + SS(68), nullptr); - LineTo(hdc, rightPanelRect.left + SS(188), rightPanelRect.top + SS(68)); - SelectObject(hdc, oldPen); - DeleteObject(accentPen); + DrawPanelHeader(leftPanelRect, _T("\u5bf9\u5c40\u4fe1\u606f"), 120); + DrawPanelHeader(rightPanelRect, _T("\u9884\u89c8\u4e0e\u63d0\u793a"), 148); SelectObject(hdc, sectionFont); SetTextColor(hdc, textColor); @@ -600,50 +763,81 @@ void TDrawScreen(HDC hdc, HWND hWnd) RECT overviewRect = { leftPanelRect.left + SS(20), - leftPanelRect.top + SS(92), + leftPanelRect.top + SS(98), leftPanelRect.right - SS(20), - leftPanelRect.top + SS(208) + leftPanelRect.top + SS(252) }; - DrawPanelCard(overviewRect, RGB(255, 247, 250), RGB(233, 191, 208), 24); + DrawPanelCardAlpha(overviewRect, RGB(255, 247, 250), RGB(233, 191, 208), 24, panelAlpha); - TCHAR scoreText[64]; - _stprintf_s(scoreText, _T("\u5f53\u524d\u5f97\u5206 %d"), tScore); - TextOut(hdc, overviewRect.left + SS(18), overviewRect.top + SS(16), scoreText, lstrlen(scoreText)); + SelectObject(hdc, sectionFont); + SetTextColor(hdc, textColor); + RECT overviewTitleRect = + { + overviewRect.left + SS(18), + overviewRect.top + SS(12), + overviewRect.right - SS(18), + overviewRect.top + SS(42) + }; + DrawText(hdc, _T("\u57fa\u7840\u72b6\u6001"), -1, &overviewTitleRect, DT_LEFT | DT_VCENTER | DT_SINGLELINE); - TCHAR modeText[64]; - _stprintf_s(modeText, _T("\u5f53\u524d\u6a21\u5f0f %s"), currentMode == MODE_CLASSIC ? _T("\u7ecf\u5178") : _T("Rogue")); - TextOut(hdc, overviewRect.left + SS(18), overviewRect.top + SS(48), modeText, lstrlen(modeText)); - - TCHAR linesText[64]; + SelectObject(hdc, bodyFont); + TCHAR overviewText[160]; int totalLines = (currentMode == MODE_CLASSIC) ? classicStats.totalLinesCleared : rogueStats.totalLinesCleared; - _stprintf_s(linesText, _T("\u7d2f\u8ba1\u6d88\u884c %d"), totalLines); - TextOut(hdc, overviewRect.left + SS(18), overviewRect.top + SS(80), linesText, lstrlen(linesText)); + _stprintf_s( + overviewText, + _T("\u5f53\u524d\u5f97\u5206 %d\r\n\u5f53\u524d\u6a21\u5f0f %s\r\n\u7d2f\u8ba1\u6d88\u884c %d"), + tScore, + currentMode == MODE_CLASSIC ? _T("\u7ecf\u5178") : _T("Rogue"), + totalLines); + RECT overviewBodyRect = + { + overviewRect.left + SS(22), + overviewRect.top + SS(62), + overviewRect.right - SS(22), + overviewRect.bottom - SS(22) + }; + DrawText(hdc, overviewText, -1, &overviewBodyRect, DT_LEFT | DT_TOP | DT_WORDBREAK); if (currentMode == MODE_ROGUE) { RECT progressRect = { leftPanelRect.left + SS(20), - leftPanelRect.top + SS(224), + leftPanelRect.top + SS(270), leftPanelRect.right - SS(20), - leftPanelRect.top + SS(356) + leftPanelRect.top + SS(488) }; - DrawPanelCard(progressRect, RGB(255, 248, 251), RGB(233, 191, 208), 24); + DrawPanelCardAlpha(progressRect, RGB(255, 248, 251), RGB(233, 191, 208), 24, panelAlpha); - TCHAR levelText[64]; - _stprintf_s(levelText, _T("\u5f53\u524d\u7b49\u7ea7 %d"), rogueStats.level); - TextOut(hdc, progressRect.left + SS(18), progressRect.top + SS(16), levelText, lstrlen(levelText)); + SelectObject(hdc, sectionFont); + SetTextColor(hdc, textColor); + RECT progressTitleRect = + { + progressRect.left + SS(18), + progressRect.top + SS(12), + progressRect.right - SS(18), + progressRect.top + SS(42) + }; + DrawText(hdc, _T("\u6210\u957f\u8fdb\u5ea6"), -1, &progressTitleRect, DT_LEFT | DT_VCENTER | DT_SINGLELINE); - TCHAR expText[64]; - _stprintf_s(expText, _T("EXP %d / %d"), rogueStats.exp, rogueStats.requiredExp); - TextOut(hdc, progressRect.left + SS(18), progressRect.top + SS(46), expText, lstrlen(expText)); + SelectObject(hdc, bodyFont); + TCHAR progressText[96]; + _stprintf_s(progressText, _T("\u5f53\u524d\u7b49\u7ea7 %d\r\nEXP %d / %d"), rogueStats.level, rogueStats.exp, rogueStats.requiredExp); + RECT progressTextRect = + { + progressRect.left + SS(22), + progressRect.top + SS(56), + progressRect.right - SS(22), + progressRect.top + SS(120) + }; + DrawText(hdc, progressText, -1, &progressTextRect, DT_LEFT | DT_TOP | DT_WORDBREAK); RECT expBarRect = { - progressRect.left + SS(18), - progressRect.top + SS(82), - progressRect.right - SS(18), - progressRect.top + SS(106) + progressRect.left + SS(22), + progressRect.top + SS(122), + progressRect.right - SS(22), + progressRect.top + SS(148) }; HBRUSH expTrackBrush = CreateSolidBrush(RGB(240, 220, 229)); FillRect(hdc, &expBarRect, expTrackBrush); @@ -663,121 +857,59 @@ void TDrawScreen(HDC hdc, HWND hWnd) FillRect(hdc, &expFillRect, expFillBrush); DeleteObject(expFillBrush); - RECT growthRect = + const TCHAR* statLabels[2] = { - progressRect.left + SS(18), - progressRect.top + SS(118), - progressRect.right - SS(18), - progressRect.bottom - SS(16) + _T("\u5f97\u5206\u500d\u7387"), + _T("EXP \u500d\u7387") }; - SelectObject(hdc, smallFont); - SetTextColor(hdc, RGB(122, 95, 110)); - TCHAR growthText[128]; - _stprintf_s( - growthText, - _T("\u5206\u6570 %d%% EXP %d%% \u901f\u5ea6 %dms"), - rogueStats.scoreMultiplierPercent, - rogueStats.expMultiplierPercent, - currentFallInterval); - DrawText(hdc, growthText, -1, &growthRect, DT_LEFT | DT_TOP | DT_WORDBREAK); + TCHAR statValues[2][32]; + _stprintf_s(statValues[0], _T("%d%%"), rogueStats.scoreMultiplierPercent); + _stprintf_s(statValues[1], _T("%d%%"), rogueStats.expMultiplierPercent); - RECT combatRect = + int statGap = SS(8); + int statWidth = (progressRect.right - progressRect.left - SS(44) - statGap) / 2; + for (int statIndex = 0; statIndex < 2; statIndex++) { - leftPanelRect.left + SS(20), - leftPanelRect.top + SS(374), - leftPanelRect.right - SS(20), - leftPanelRect.top + SS(516) - }; - DrawPanelCard(combatRect, RGB(255, 247, 250), RGB(233, 191, 208), 24); - - SelectObject(hdc, sectionFont); - SetTextColor(hdc, textColor); - TextOut(hdc, combatRect.left + SS(18), combatRect.top + SS(16), _T("\u5f53\u524d\u6218\u6597\u72b6\u6001"), lstrlen(_T("\u5f53\u524d\u6218\u6597\u72b6\u6001"))); - - SelectObject(hdc, bodyFont); - TCHAR comboText[64]; - _stprintf_s(comboText, _T("\u8fde\u51fb\u94fe %d \u5956\u52b1\u5c42\u6570 %d"), rogueStats.comboChain, rogueStats.comboBonusStacks); - TextOut(hdc, combatRect.left + SS(18), combatRect.top + SS(50), comboText, lstrlen(comboText)); - - TCHAR summaryText[96]; - _stprintf_s( - summaryText, - _T("\u9884\u89c8 %d \u4fdd\u547d %d \u5df2\u9009 %d"), - rogueStats.previewCount, - rogueStats.lastChanceCount, - upgradeUiState.totalChosenCount); - TextOut(hdc, combatRect.left + SS(18), combatRect.top + SS(82), summaryText, lstrlen(summaryText)); - - SelectObject(hdc, smallFont); - SetTextColor(hdc, RGB(122, 95, 110)); - RECT combatBodyRect = - { - combatRect.left + SS(18), - combatRect.top + SS(112), - combatRect.right - SS(18), - combatRect.bottom - SS(16) - }; - - TCHAR combatSummary[512]; - combatSummary[0] = _T('\0'); - _stprintf_s( - combatSummary + lstrlen(combatSummary), - 512 - lstrlen(combatSummary), - _T("\u5f97\u5206 %d%% EXP %d%% \u901f\u5ea6 %dms\r\n"), - rogueStats.scoreMultiplierPercent, - rogueStats.expMultiplierPercent, - currentFallInterval); - if (rogueStats.sweeperLevel > 0) - { - int sweeperThreshold = 8 - (rogueStats.sweeperLevel - 1) * 2; - if (sweeperThreshold < 3) + RECT statRect = { - sweeperThreshold = 3; - } - _stprintf_s(combatSummary + lstrlen(combatSummary), 512 - lstrlen(combatSummary), _T("\u6e05\u626b\u8005 %d/%d\r\n"), rogueStats.sweeperCharge, sweeperThreshold); + progressRect.left + SS(22) + statIndex * (statWidth + statGap), + progressRect.top + SS(154), + progressRect.left + SS(22) + statIndex * (statWidth + statGap) + statWidth, + progressRect.top + SS(204) + }; + DrawPanelCardAlpha(statRect, RGB(255, 239, 245), RGB(232, 184, 202), 16, panelNestedAlpha); + + RECT statLabelRect = + { + statRect.left + SS(8), + statRect.top + SS(4), + statRect.right - SS(8), + statRect.top + SS(22) + }; + RECT statValueRect = + { + statRect.left + SS(8), + statRect.top + SS(21), + statRect.right - SS(8), + statRect.bottom - SS(2) + }; + + SelectObject(hdc, smallFont); + SetTextColor(hdc, RGB(132, 102, 118)); + DrawText(hdc, statLabels[statIndex], -1, &statLabelRect, DT_CENTER | DT_VCENTER | DT_SINGLELINE); + SelectObject(hdc, bodyFont); + SetTextColor(hdc, titleColor); + DrawText(hdc, statValues[statIndex], -1, &statValueRect, DT_CENTER | DT_VCENTER | DT_SINGLELINE); } - if (rogueStats.feverLevel > 0) - { - _stprintf_s(combatSummary + lstrlen(combatSummary), 512 - lstrlen(combatSummary), _T("\u72c2\u70ed\u5145\u80fd %d/20 \u5269\u4f59 %d \u79d2\r\n"), rogueStats.feverLineCharge, rogueStats.feverTicks); - } - if (rogueStats.explosiveLevel > 0) - { - _stprintf_s(combatSummary + lstrlen(combatSummary), 512 - lstrlen(combatSummary), _T("\u7206\u7834\u8ba1\u6570 %d/10 %s\r\n"), rogueStats.explosivePieceCounter, currentPieceIsExplosive ? _T("\u672c\u5757\u5df2\u7206\u7834") : _T("\u5f85\u89e6\u53d1")); - } - if (rogueStats.laserLevel > 0 || rogueStats.crossPieceLevel > 0 || rogueStats.rainbowPieceLevel > 0) - { - _stprintf_s( - combatSummary + lstrlen(combatSummary), - 512 - lstrlen(combatSummary), - _T("\u7279\u5757\uff1a%s%s%s\r\n"), - rogueStats.laserLevel > 0 ? _T("\u6fc0\u5149 ") : _T(""), - rogueStats.crossPieceLevel > 0 ? _T("\u5341\u5b57 ") : _T(""), - rogueStats.rainbowPieceLevel > 0 ? _T("\u5f69\u8679") : _T("")); - } - if (rogueStats.screenBombLevel > 0 || rogueStats.blackHoleLevel > 0 || rogueStats.reshapeLevel > 0) - { - _stprintf_s( - combatSummary + lstrlen(combatSummary), - 512 - lstrlen(combatSummary), - _T("\u4e3b\u52a8\uff1aX %d Z %d V %d\r\n"), - rogueStats.screenBombCount, - rogueStats.blackHoleCharges, - rogueStats.reshapeCharges); - } - if (rogueStats.highPressureLevel > 0 || rogueStats.tetrisGambleLevel > 0 || rogueStats.extremePlayerLevel > 0) - { - _stprintf_s(combatSummary + lstrlen(combatSummary), 512 - lstrlen(combatSummary), _T("\u98ce\u9669\u7ebf\u5df2\u542f\u7528\r\n")); - } - DrawText(hdc, combatSummary, -1, &combatBodyRect, DT_LEFT | DT_TOP | DT_WORDBREAK); RECT upgradeListRect = { leftPanelRect.left + SS(20), - leftPanelRect.top + SS(534), + leftPanelRect.top + SS(510), leftPanelRect.right - SS(20), leftPanelRect.bottom - SS(20) }; - DrawPanelCard(upgradeListRect, RGB(255, 248, 251), RGB(233, 191, 208), 24); + DrawPanelCardAlpha(upgradeListRect, RGB(255, 248, 251), RGB(233, 191, 208), 24, panelAlpha); SelectObject(hdc, sectionFont); SetTextColor(hdc, textColor); @@ -787,10 +919,10 @@ void TDrawScreen(HDC hdc, HWND hWnd) SetTextColor(hdc, RGB(128, 104, 118)); RECT upgradeBodyRect = { - upgradeListRect.left + SS(18), - upgradeListRect.top + SS(48), - upgradeListRect.right - SS(18), - upgradeListRect.bottom - SS(14) + upgradeListRect.left + SS(22), + upgradeListRect.top + SS(56), + upgradeListRect.right - SS(22), + upgradeListRect.bottom - SS(20) }; TCHAR upgradeSummary[512]; @@ -981,57 +1113,86 @@ void TDrawScreen(HDC hdc, HWND hWnd) RECT classicInfoRect = { leftPanelRect.left + SS(20), - leftPanelRect.top + SS(224), + leftPanelRect.top + SS(270), leftPanelRect.right - SS(20), - leftPanelRect.top + SS(360) + leftPanelRect.top + SS(458) }; - DrawPanelCard(classicInfoRect, RGB(255, 248, 251), RGB(233, 191, 208), 24); + DrawPanelCardAlpha(classicInfoRect, RGB(255, 248, 251), RGB(233, 191, 208), 24, panelAlpha); SelectObject(hdc, smallFont); SetTextColor(hdc, RGB(128, 104, 118)); RECT classicBodyRect = { - classicInfoRect.left + SS(18), - classicInfoRect.top + SS(18), - classicInfoRect.right - SS(18), - classicInfoRect.bottom - SS(18) + classicInfoRect.left + SS(22), + classicInfoRect.top + SS(24), + classicInfoRect.right - SS(22), + classicInfoRect.bottom - SS(24) }; DrawText(hdc, _T("\u7ecf\u5178\u6a21\u5f0f\u4fdd\u6301\u539f\u7248\u7b80\u5355\u8ba1\u5206\u3002\r\n\r\n\u6682\u4e0d\u63a5\u5165\u7b49\u7ea7\u3001EXP \u548c\u5f3a\u5316\u7cfb\u7edf\uff0c\u4e13\u6ce8\u4e8e\u57fa\u7840\u4fc4\u7f57\u65af\u65b9\u5757\u5bf9\u5c40\u3002"), -1, &classicBodyRect, DT_LEFT | DT_TOP | DT_WORDBREAK); } - SelectObject(hdc, titleFont); - SetTextColor(hdc, titleColor); - TextOut(hdc, rightPanelRect.left + SS(24), rightPanelRect.top + SS(22), _T("\u64cd\u4f5c\u4e0e\u9884\u89c8"), lstrlen(_T("\u64cd\u4f5c\u4e0e\u9884\u89c8"))); - RECT holdNextRect = { rightPanelRect.left + SS(20), - rightPanelRect.top + SS(92), + rightPanelRect.top + SS(98), rightPanelRect.right - SS(20), - rightPanelRect.top + SS(360) + rightPanelRect.top + SS(326) }; - DrawPanelCard(holdNextRect, RGB(255, 247, 250), RGB(233, 191, 208), 24); + DrawPanelCardAlpha(holdNextRect, RGB(255, 247, 250), RGB(233, 191, 208), 24, panelAlpha); RECT holdCard = { - holdNextRect.left + SS(18), - holdNextRect.top + SS(54), - holdNextRect.left + SS(18) + grid * 2 + SS(40), - holdNextRect.top + SS(54) + grid * 2 + SS(40) + holdNextRect.left + SS(88), + holdNextRect.top + SS(24), + holdNextRect.left + SS(150), + holdNextRect.top + SS(86) }; RECT nextSectionRect = { - holdCard.right + SS(18), - holdNextRect.top + SS(54), + holdNextRect.left + SS(18), + holdNextRect.top + SS(146), holdNextRect.right - SS(18), - holdNextRect.bottom - SS(18) + holdNextRect.bottom - SS(22) }; SelectObject(hdc, sectionFont); SetTextColor(hdc, textColor); - TextOut(hdc, holdNextRect.left + SS(18), holdNextRect.top + SS(16), _T("Hold"), lstrlen(_T("Hold"))); - TextOut(hdc, nextSectionRect.left, holdNextRect.top + SS(16), _T("\u4e0b\u4e00\u4e2a"), lstrlen(_T("\u4e0b\u4e00\u4e2a"))); + RECT holdTitleRect = + { + holdNextRect.left + SS(18), + holdNextRect.top + SS(34), + holdNextRect.left + SS(80), + holdNextRect.top + SS(70) + }; + DrawText(hdc, _T("Hold"), -1, &holdTitleRect, DT_LEFT | DT_VCENTER | DT_SINGLELINE); - DrawPanelCard(holdCard, RGB(255, 238, 244), RGB(233, 191, 208), 22); + RECT nextTitleRect = + { + nextSectionRect.left, + holdNextRect.top + SS(102), + holdNextRect.right - SS(18), + holdNextRect.top + SS(136) + }; + DrawText(hdc, _T("\u4e0b\u4e00\u4e2a"), -1, &nextTitleRect, DT_LEFT | DT_VCENTER | DT_SINGLELINE); + + DrawPanelCardAlpha(holdCard, RGB(255, 238, 244), RGB(233, 191, 208), 22, panelNestedAlpha); + + SelectObject(hdc, smallFont); + SetTextColor(hdc, RGB(128, 104, 118)); + RECT holdHintRect = + { + holdCard.right + SS(14), + holdCard.top + SS(2), + holdNextRect.right - SS(18), + holdCard.bottom - SS(2) + }; + DrawText( + hdc, + currentMode == MODE_ROGUE && rogueStats.holdUnlocked > 0 + ? (holdUsedThisTurn ? _T("\u5df2\u4f7f\u7528\r\n\u843d\u5730\u540e\u6062\u590d") : _T("C / Shift\r\n\u6682\u5b58\u4e00\u6b21")) + : _T("\u672a\u89e3\u9501\r\nHold \u5f3a\u5316"), + -1, + &holdHintRect, + DT_LEFT | DT_VCENTER | DT_WORDBREAK); if (currentMode == MODE_ROGUE) { @@ -1042,11 +1203,11 @@ void TDrawScreen(HDC hdc, HWND hWnd) RECT holdLockedRect = { holdCard.left + SS(10), - holdCard.top + SS(18), + holdCard.top + SS(10), holdCard.right - SS(10), holdCard.bottom - SS(10) }; - DrawText(hdc, _T("\u672a\u89e3\u9501\r\n\u9700 Hold \u5f3a\u5316"), -1, &holdLockedRect, DT_CENTER | DT_VCENTER | DT_WORDBREAK); + DrawText(hdc, _T("\u9501\u5b9a"), -1, &holdLockedRect, DT_CENTER | DT_VCENTER | DT_WORDBREAK); } else if (holdType >= 0) { @@ -1056,12 +1217,21 @@ void TDrawScreen(HDC hdc, HWND hWnd) { if (bricks[holdType][0][i][j] != 0) { + int holdAvailableWidth = holdCard.right - holdCard.left - SS(16); + int holdAvailableHeight = holdCard.bottom - holdCard.top - SS(16); + int holdMiniCell = holdAvailableWidth < holdAvailableHeight ? holdAvailableWidth / 4 : holdAvailableHeight / 4; + if (holdMiniCell < SS(7)) + { + holdMiniCell = SS(7); + } + int holdOffsetX = holdCard.left + (holdCard.right - holdCard.left - holdMiniCell * 4) / 2; + int holdOffsetY = holdCard.top + (holdCard.bottom - holdCard.top - holdMiniCell * 4) / 2; RECT brickRect = { - holdCard.left + SS(14) + j * (grid / 2), - holdCard.top + SS(14) + i * (grid / 2), - holdCard.left + SS(14) + (j + 1) * (grid / 2) - SS(1), - holdCard.top + SS(14) + (i + 1) * (grid / 2) - SS(1) + holdOffsetX + j * holdMiniCell, + holdOffsetY + i * holdMiniCell, + holdOffsetX + (j + 1) * holdMiniCell - SS(1), + holdOffsetY + (i + 1) * holdMiniCell - SS(1) }; HBRUSH brickBrush = CreateSolidBrush(BrickColor[holdType]); @@ -1084,11 +1254,11 @@ void TDrawScreen(HDC hdc, HWND hWnd) RECT emptyHoldRect = { holdCard.left + SS(10), - holdCard.top + SS(18), + holdCard.top + SS(10), holdCard.right - SS(10), holdCard.bottom - SS(10) }; - DrawText(hdc, _T("\u6682\u65e0\u6682\u5b58"), -1, &emptyHoldRect, DT_CENTER | DT_VCENTER | DT_WORDBREAK); + DrawText(hdc, _T("\u7a7a"), -1, &emptyHoldRect, DT_CENTER | DT_VCENTER | DT_WORDBREAK); } } else @@ -1098,11 +1268,11 @@ void TDrawScreen(HDC hdc, HWND hWnd) RECT classicHoldRect = { holdCard.left + SS(10), - holdCard.top + SS(18), + holdCard.top + SS(10), holdCard.right - SS(10), holdCard.bottom - SS(10) }; - DrawText(hdc, _T("\u7ecf\u5178\u6a21\u5f0f\r\n\u4e0d\u542f\u7528 Hold"), -1, &classicHoldRect, DT_CENTER | DT_VCENTER | DT_WORDBREAK); + DrawText(hdc, _T("\u5173"), -1, &classicHoldRect, DT_CENTER | DT_VCENTER | DT_WORDBREAK); } int previewCount = 1; @@ -1121,23 +1291,17 @@ void TDrawScreen(HDC hdc, HWND hWnd) for (int previewIndex = 0; previewIndex < previewCount; previewIndex++) { + int nextCardGap = SS(8); + int nextCardWidth = (nextSectionRect.right - nextSectionRect.left - nextCardGap * 2) / 3; RECT nextCard = { - nextSectionRect.left + (previewIndex % 2) * SS(94), - nextSectionRect.top + (previewIndex / 2) * SS(94), - nextSectionRect.left + (previewIndex % 2) * SS(94) + grid * 2 + SS(40), - nextSectionRect.top + (previewIndex / 2) * SS(94) + grid * 2 + SS(40) + nextSectionRect.left + previewIndex * (nextCardWidth + nextCardGap), + nextSectionRect.top, + nextSectionRect.left + previewIndex * (nextCardWidth + nextCardGap) + nextCardWidth, + nextSectionRect.bottom }; - HBRUSH nextCardBrush = CreateSolidBrush(RGB(255, 238, 244)); - HPEN nextCardPen = CreatePen(PS_SOLID, 1, RGB(233, 191, 208)); - oldPen = (HPEN)SelectObject(hdc, nextCardPen); - oldBrush = (HBRUSH)SelectObject(hdc, nextCardBrush); - RoundRect(hdc, nextCard.left, nextCard.top, nextCard.right, nextCard.bottom, SS(22), SS(22)); - SelectObject(hdc, oldBrush); - SelectObject(hdc, oldPen); - DeleteObject(nextCardBrush); - DeleteObject(nextCardPen); + DrawPanelCardAlpha(nextCard, RGB(255, 247, 250), RGB(233, 191, 208), 18, panelStrongAlpha); int previewType = nextTypes[previewIndex]; @@ -1147,12 +1311,21 @@ void TDrawScreen(HDC hdc, HWND hWnd) { if (bricks[previewType][0][i][j] != 0) { + int nextAvailableWidth = nextCard.right - nextCard.left - SS(14); + int nextAvailableHeight = nextCard.bottom - nextCard.top - SS(14); + int nextMiniCell = nextAvailableWidth < nextAvailableHeight ? nextAvailableWidth / 4 : nextAvailableHeight / 4; + if (nextMiniCell < SS(7)) + { + nextMiniCell = SS(7); + } + int previewOffsetX = nextCard.left + (nextCard.right - nextCard.left - nextMiniCell * 4) / 2; + int previewOffsetY = nextCard.top + (nextCard.bottom - nextCard.top - nextMiniCell * 4) / 2; RECT brickRect = { - nextCard.left + SS(14) + j * (grid / 2), - nextCard.top + SS(14) + i * (grid / 2), - nextCard.left + SS(14) + (j + 1) * (grid / 2) - SS(1), - nextCard.top + SS(14) + (i + 1) * (grid / 2) - SS(1) + previewOffsetX + j * nextMiniCell, + previewOffsetY + i * nextMiniCell, + previewOffsetX + (j + 1) * nextMiniCell - SS(1), + previewOffsetY + (i + 1) * nextMiniCell - SS(1) }; HBRUSH brickBrush = CreateSolidBrush(BrickColor[previewType]); @@ -1172,35 +1345,87 @@ void TDrawScreen(HDC hdc, HWND hWnd) RECT controlRect = { rightPanelRect.left + SS(20), - rightPanelRect.top + SS(378), + rightPanelRect.top + SS(346), rightPanelRect.right - SS(20), rightPanelRect.bottom - SS(20) }; - DrawPanelCard(controlRect, RGB(255, 248, 251), RGB(233, 191, 208), 24); + DrawPanelCardAlpha(controlRect, RGB(255, 248, 251), RGB(233, 191, 208), 24, panelAlpha); SelectObject(hdc, sectionFont); SetTextColor(hdc, textColor); - TextOut(hdc, controlRect.left + SS(18), controlRect.top + SS(16), _T("\u5feb\u6377\u64cd\u4f5c"), lstrlen(_T("\u5feb\u6377\u64cd\u4f5c"))); + TextOut(hdc, controlRect.left + SS(18), controlRect.top + SS(16), _T("\u6e38\u620f\u63d0\u793a"), lstrlen(_T("\u6e38\u620f\u63d0\u793a"))); + + RECT feedbackPanelRect = + { + controlRect.left + SS(18), + controlRect.top + SS(56), + controlRect.right - SS(18), + controlRect.top + SS(172) + }; + DrawPanelCardAlpha(feedbackPanelRect, RGB(255, 244, 248), RGB(232, 184, 202), 20, panelNestedAlpha); + + SelectObject(hdc, bodyFont); + SetTextColor(hdc, titleColor); + RECT feedbackTitleRect = + { + feedbackPanelRect.left + SS(16), + feedbackPanelRect.top + SS(14), + feedbackPanelRect.right - SS(16), + feedbackPanelRect.top + SS(42) + }; + DrawText( + hdc, + feedbackState.visibleTicks > 0 ? feedbackState.title : _T("\u5f53\u524d\u52a8\u6001"), + -1, + &feedbackTitleRect, + DT_LEFT | DT_VCENTER | DT_SINGLELINE); SelectObject(hdc, smallFont); + SetTextColor(hdc, RGB(116, 90, 104)); + RECT feedbackBodyRect = + { + feedbackPanelRect.left + SS(16), + feedbackPanelRect.top + SS(46), + feedbackPanelRect.right - SS(16), + feedbackPanelRect.bottom - SS(14) + }; + DrawText( + hdc, + feedbackState.visibleTicks > 0 + ? feedbackState.detail + : _T("\u6682\u65e0\u65b0\u4e8b\u4ef6\u3002\u5347\u7ea7\u9009\u62e9\u3001\u4e3b\u52a8\u6280\u80fd\u548c\u7279\u6b8a\u89e6\u53d1\u90fd\u4f1a\u5728\u8fd9\u91cc\u663e\u793a\u3002"), + -1, + &feedbackBodyRect, + DT_LEFT | DT_TOP | DT_WORDBREAK); + + SelectObject(hdc, sectionFont); + SetTextColor(hdc, textColor); + RECT tipsTitleRect = + { + controlRect.left + SS(22), + controlRect.top + SS(192), + controlRect.right - SS(22), + controlRect.top + SS(224) + }; + DrawText(hdc, _T("\u57fa\u672c\u6309\u952e"), -1, &tipsTitleRect, DT_LEFT | DT_VCENTER | DT_SINGLELINE); + + SelectObject(hdc, bodyFont); SetTextColor(hdc, RGB(128, 104, 118)); RECT controlBodyRect = { - controlRect.left + SS(18), - controlRect.top + SS(52), - controlRect.right - SS(18), - controlRect.bottom - SS(18) + controlRect.left + SS(22), + controlRect.top + SS(232), + controlRect.right - SS(22), + controlRect.bottom - SS(22) }; if (currentMode == MODE_ROGUE) { DrawText( hdc, - _T("\u2190/\u2192 \u6216 A/D\uff1a\u5de6\u53f3\u79fb\u52a8\r\n") - _T("\u2191 \u6216 W\uff1a\u65cb\u8f6c \u2193 \u6216 S\uff1a\u8f6f\u964d\r\n") - _T("Space\uff1a\u786c\u964d P\uff1a\u6682\u505c R\uff1a\u91cd\u5f00\r\n") - _T("C/Shift\uff1aHold M\uff1a\u8fd4\u56de\u83dc\u5355\r\n") - _T("Z\uff1a\u9ed1\u6d1e X\uff1a\u6e05\u5c4f\u70b8\u5f39 V\uff1a\u7a7a\u4e2d\u6362\u5f62\r\n\r\n") - _T("\u5f53\u524d\u8bf4\u660e\uff1a\u4e3b\u754c\u9762\u53ea\u4fdd\u7559\u5bf9\u5c40\u5173\u952e\u4fe1\u606f\uff0c\u8be6\u7ec6\u5f3a\u5316\u6548\u679c\u4ee5\u540e\u518d\u505a\u5c55\u5f00\u5c42\u3002"), + _T("\u79fb\u52a8\uff1a\u2190/\u2192 \u6216 A/D\r\n") + _T("\u65cb\u8f6c/\u4e0b\u843d\uff1a\u2191/W\u3001\u2193/S\u3001Space\r\n") + _T("\u5bf9\u5c40\uff1aP \u6682\u505c R \u91cd\u5f00 M \u83dc\u5355\r\n") + _T("Rogue\uff1aC Hold Z \u9ed1\u6d1e X \u6e05\u5c4f V \u6362\u5f62"), -1, &controlBodyRect, DT_LEFT | DT_TOP | DT_WORDBREAK); @@ -1209,57 +1434,22 @@ void TDrawScreen(HDC hdc, HWND hWnd) { DrawText( hdc, - _T("\u2190/\u2192 \u6216 A/D\uff1a\u5de6\u53f3\u79fb\u52a8\r\n") - _T("\u2191 \u6216 W\uff1a\u65cb\u8f6c \u2193 \u6216 S\uff1a\u8f6f\u964d\r\n") - _T("Space\uff1a\u786c\u964d P\uff1a\u6682\u505c R\uff1a\u91cd\u5f00\r\n") - _T("M\uff1a\u8fd4\u56de\u83dc\u5355"), + _T("\u79fb\u52a8\uff1a\u2190/\u2192 \u6216 A/D\r\n") + _T("\u65cb\u8f6c/\u4e0b\u843d\uff1a\u2191/W\u3001\u2193/S\u3001Space\r\n") + _T("\u5bf9\u5c40\uff1aP \u6682\u505c R \u91cd\u5f00 M \u83dc\u5355"), -1, &controlBodyRect, DT_LEFT | DT_TOP | DT_WORDBREAK); } - if (feedbackState.visibleTicks > 0) - { - RECT feedbackRect = - { - gameRect.left + SS(16), - gameRect.top + SS(16), - gameRect.right - SS(16), - gameRect.top + SS(98) - }; - DrawPanelCard(feedbackRect, RGB(255, 245, 249), RGB(232, 170, 194), 22); - - SelectObject(hdc, bodyFont); - SetTextColor(hdc, titleColor); - RECT titleRect = - { - feedbackRect.left + SS(16), - feedbackRect.top + SS(12), - feedbackRect.right - SS(16), - feedbackRect.top + SS(40) - }; - DrawText(hdc, feedbackState.title, -1, &titleRect, DT_LEFT | DT_VCENTER | DT_SINGLELINE); - - SelectObject(hdc, smallFont); - SetTextColor(hdc, RGB(116, 90, 104)); - RECT detailRect = - { - feedbackRect.left + SS(16), - feedbackRect.top + SS(42), - feedbackRect.right - SS(16), - feedbackRect.bottom - SS(12) - }; - DrawText(hdc, feedbackState.detail, -1, &detailRect, DT_LEFT | DT_WORDBREAK); - } - if (suspendFlag || gameOverFlag) { RECT overlayRect = { - gameRect.left + grid, - gameRect.top + grid * 6, - gameRect.right - grid, - gameRect.top + grid * 13 + gameRect.left + SS(48), + gameRect.top + grid * 7, + gameRect.right - SS(48), + gameRect.top + grid * 11 + SS(18) }; HBRUSH overlayBrush = CreateSolidBrush(RGB(255, 241, 246)); @@ -1274,18 +1464,18 @@ void TDrawScreen(HDC hdc, HWND hWnd) RECT titleRect = { - overlayRect.left, - overlayRect.top + grid, - overlayRect.right, - overlayRect.top + grid * 3 + overlayRect.left + SS(24), + overlayRect.top + SS(18), + overlayRect.right - SS(24), + overlayRect.top + SS(78) }; RECT tipRect = { - overlayRect.left + SS(20), - overlayRect.top + grid * 3, - overlayRect.right - SS(20), - overlayRect.bottom - grid + overlayRect.left + SS(28), + overlayRect.top + SS(86), + overlayRect.right - SS(28), + overlayRect.bottom - SS(20) }; SetTextColor(hdc, RGB(121, 76, 99)); @@ -1295,13 +1485,13 @@ void TDrawScreen(HDC hdc, HWND hWnd) { DrawText(hdc, _T("\u6e38\u620f\u5df2\u6682\u505c"), -1, &titleRect, DT_CENTER | DT_VCENTER | DT_SINGLELINE); SelectObject(hdc, bodyFont); - DrawText(hdc, _T("\u6309 P \u952e\u7ee7\u7eed\u6e38\u620f"), -1, &tipRect, DT_CENTER | DT_VCENTER | DT_SINGLELINE); + DrawText(hdc, _T("\u6309 P \u952e\u7ee7\u7eed\u6e38\u620f"), -1, &tipRect, DT_CENTER | DT_VCENTER | DT_WORDBREAK); } else { DrawText(hdc, _T("\u6e38\u620f\u7ed3\u675f"), -1, &titleRect, DT_CENTER | DT_VCENTER | DT_SINGLELINE); SelectObject(hdc, bodyFont); - DrawText(hdc, _T("\u6309 R \u952e\u91cd\u65b0\u5f00\u59cb \u6216 M \u8fd4\u56de\u83dc\u5355"), -1, &tipRect, DT_CENTER | DT_VCENTER | DT_SINGLELINE); + DrawText(hdc, _T("\u6309 R \u952e\u91cd\u65b0\u5f00\u59cb\r\n\u6216\u6309 M \u8fd4\u56de\u83dc\u5355"), -1, &tipRect, DT_CENTER | DT_VCENTER | DT_WORDBREAK); } }