From 3aa4714ce0a442c75e624e35ebe7eb99a1e9138e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Tue, 5 May 2026 01:23:09 +0200 Subject: [PATCH] Merge draw_text_win with draw_text_uwp. --- CMakeLists.txt | 8 +- Common/Render/Text/draw_text.cpp | 5 +- Common/Render/Text/draw_text_uwp.cpp | 59 ++++-- Common/Render/Text/draw_text_uwp.h | 18 +- Common/Render/Text/draw_text_win.cpp | 260 +-------------------------- Common/Render/Text/draw_text_win.h | 29 +-- UWP/XAudioSoundStream.cpp | 1 + Windows/PPSSPP.vcxproj | 14 +- headless/Headless.vcxproj | 12 +- unittest/UnitTests.vcxproj | 10 +- 10 files changed, 82 insertions(+), 334 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 910f32214e..88ffc50c45 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1575,7 +1575,7 @@ else() endif() if(WIN32) - target_link_libraries(Common winmm dsound dxguid Version) + target_link_libraries(Common winmm dsound dxguid d2d1 dwrite d3d11 Version) endif() if(NOT LIBRETRO) @@ -2952,6 +2952,9 @@ if(HEADLESS) endif() add_executable(PPSSPPHeadless ${HeadlessSource}) target_link_libraries(PPSSPPHeadless ${COCOA_LIBRARY} ${QUARTZ_CORE_LIBRARY} ${IOKIT_LIBRARY} ${LinkCommon}) + if(WIN32) + target_link_libraries(PPSSPPHeadless d2d1 dwrite d3d11) + endif() setup_target_project(PPSSPPHeadless headless) endif() @@ -2980,6 +2983,9 @@ if(UNITTEST) ) endif() target_link_libraries(PPSSPPUnitTest ${COCOA_LIBRARY} ${QUARTZ_CORE_LIBRARY} ${IOKIT_LIBRARY} ${LinkCommon} Common) + if(WIN32) + target_link_libraries(PPSSPPUnitTest d2d1 dwrite d3d11) + endif() setup_target_project(PPSSPPUnitTest unittest) add_test(arm64_emitter PPSSPPUnitTest Arm64Emitter) add_test(arm_emitter PPSSPPUnitTest ArmEmitter) diff --git a/Common/Render/Text/draw_text.cpp b/Common/Render/Text/draw_text.cpp index 6b1338960f..a20f8dedc8 100644 --- a/Common/Render/Text/draw_text.cpp +++ b/Common/Render/Text/draw_text.cpp @@ -10,7 +10,6 @@ #include "Common/Render/Text/draw_text.h" #include "Common/Render/Text/draw_text_win.h" #include "Common/Render/Text/draw_text_cocoa.h" -#include "Common/Render/Text/draw_text_uwp.h" #include "Common/Render/Text/draw_text_qt.h" #include "Common/Render/Text/draw_text_android.h" #include "Common/Render/Text/draw_text_sdl.h" @@ -273,10 +272,8 @@ TextDrawer *TextDrawer::Create(Draw::DrawContext *draw) { TextDrawer *drawer = nullptr; #if defined(__LIBRETRO__) // No text drawer -#elif defined(_WIN32) && !PPSSPP_PLATFORM(UWP) +#elif defined(_WIN32) && !defined(USING_QT_UI) drawer = new TextDrawerWin32(draw); -#elif PPSSPP_PLATFORM(UWP) - drawer = new TextDrawerUWP(draw); #elif PPSSPP_PLATFORM(MAC) || PPSSPP_PLATFORM(IOS) drawer = new TextDrawerCocoa(draw); #elif defined(USING_QT_UI) diff --git a/Common/Render/Text/draw_text_uwp.cpp b/Common/Render/Text/draw_text_uwp.cpp index bdef18e971..bc9113ae87 100644 --- a/Common/Render/Text/draw_text_uwp.cpp +++ b/Common/Render/Text/draw_text_uwp.cpp @@ -1,5 +1,4 @@ #include "ppsspp_config.h" - #include "Common/System/Display.h" #include "Common/GPU/thin3d.h" #include "Common/Data/Hash/Hash.h" @@ -12,7 +11,8 @@ #include "Common/StringUtils.h" #include "Common/File/Path.h" -#if PPSSPP_PLATFORM(UWP) +#if defined(_WIN32) && !defined(USING_QT_UI) + #include #include @@ -70,19 +70,42 @@ public: }; struct TextDrawerContext { - ID2D1Bitmap1 *bitmap; - ID2D1Bitmap1 *mirror_bmp; + ID2D1Bitmap1 *bitmap = nullptr; + ID2D1Bitmap1 *mirror_bmp = nullptr; }; TextDrawerUWP::TextDrawerUWP(Draw::DrawContext *draw) : TextDrawer(draw), ctx_(nullptr) { HRESULT hr; - // It's fine to assume we are using D3D11 in UWP - ID3D11Device* d3ddevice = (ID3D11Device *)draw->GetNativeObject(Draw::NativeObject::DEVICE); - IDXGIDevice* dxgiDevice; +#if PPSSPP_PLATFORM(UWP) + // On UWP we can assume D3D11 and reuse the existing device. + ID3D11Device *d3ddevice = (ID3D11Device *)draw->GetNativeObject(Draw::NativeObject::DEVICE); + IDXGIDevice *dxgiDevice; hr = d3ddevice->QueryInterface(__uuidof(IDXGIDevice), (void**)&dxgiDevice); if (FAILED(hr)) _assert_msg_(false, "ID3DDevice QueryInterface IDXGIDevice failed"); - +#else + // On non-UWP Win32 the draw context may use any backend (Vulkan, GL, etc.), so create + // an independent WARP (software) D3D11 device solely for D2D/DirectWrite rendering. + ID3D11Device *d3ddevice = nullptr; + D3D_FEATURE_LEVEL featureLevel; + hr = D3D11CreateDevice( + nullptr, + D3D_DRIVER_TYPE_WARP, + nullptr, + D3D11_CREATE_DEVICE_BGRA_SUPPORT, + nullptr, 0, + D3D11_SDK_VERSION, + &d3ddevice, + &featureLevel, + nullptr + ); + if (FAILED(hr)) _assert_msg_(false, "D3D11CreateDevice (WARP) for text rendering failed"); + IDXGIDevice *dxgiDevice; + hr = d3ddevice->QueryInterface(__uuidof(IDXGIDevice), (void**)&dxgiDevice); + d3ddevice->Release(); + if (FAILED(hr)) _assert_msg_(false, "WARP D3D11Device QueryInterface IDXGIDevice failed"); +#endif + // Initialize the Direct2D Factory. D2D1_FACTORY_OPTIONS options = {}; D2D1CreateFactory( @@ -100,7 +123,6 @@ TextDrawerUWP::TextDrawerUWP(Draw::DrawContext *draw) : TextDrawer(draw), ctx_(n ); // Create D2D Device and DeviceContext. - // TODO: We have one sitting right in DX::DeviceResource, there might be a way to use that instead. hr = m_d2dFactory->CreateDevice(dxgiDevice, &m_d2dDevice); dxgiDevice->Release(); if (FAILED(hr)) _assert_msg_(false, "D2D CreateDevice failed"); @@ -118,6 +140,7 @@ TextDrawerUWP::TextDrawerUWP(Draw::DrawContext *draw) : TextDrawer(draw), ctx_(n if (FAILED(hr)) { _assert_msg_(false, "D2D RegisterFontFileLoader failed"); } + // Load our fonts. const std::vector fontFilenames = GetAllFontFilenames(); for (const auto &fname : fontFilenames) { @@ -174,7 +197,7 @@ TextDrawerUWP::TextDrawerUWP(Draw::DrawContext *draw) : TextDrawer(draw), ctx_(n } ctx_ = new TextDrawerContext(); - + D2D1_BITMAP_PROPERTIES1 properties{}; properties.pixelFormat.format = DXGI_FORMAT_B8G8R8A8_UNORM; properties.pixelFormat.alphaMode = D2D1_ALPHA_MODE_PREMULTIPLIED; @@ -192,8 +215,8 @@ TextDrawerUWP::TextDrawerUWP(Draw::DrawContext *draw) : TextDrawer(draw), ctx_(n &ctx_->bitmap ); m_d2dContext->SetTarget(ctx_->bitmap); - - // Create mirror bitmap for mapping + + // Create mirror bitmap for CPU readback properties.bitmapOptions = D2D1_BITMAP_OPTIONS_CANNOT_DRAW | D2D1_BITMAP_OPTIONS_CPU_READ; m_d2dContext->CreateBitmap( D2D1::SizeU(MAX_TEXT_WIDTH, MAX_TEXT_HEIGHT), @@ -240,7 +263,7 @@ void TextDrawerUWP::SetOrCreateFont(const FontStyle &style) { } void TextDrawerUWP::MeasureStringInternal(std::string_view str, float *w, float *h) { - IDWriteTextFormat* format = nullptr; + IDWriteTextFormat *format = nullptr; auto iter = fontMap_.find(fontStyle_); if (iter != fontMap_.end()) { format = iter->second->textFmt; @@ -250,8 +273,8 @@ void TextDrawerUWP::MeasureStringInternal(std::string_view str, float *w, float std::wstring wstr = ConvertUTF8ToWString(ReplaceAll(str, "\n", "\r\n")); format->SetTextAlignment(DWRITE_TEXT_ALIGNMENT_LEADING); - - IDWriteTextLayout* layout = nullptr; + + IDWriteTextLayout *layout = nullptr; HRESULT hr = m_dwriteFactory->CreateTextLayout( (LPWSTR)wstr.c_str(), (int)wstr.size(), @@ -342,7 +365,7 @@ bool TextDrawerUWP::DrawStringBitmap(std::vector &bitmapData, TextStrin m_d2dContext->BeginDraw(); m_d2dContext->Clear(); - m_d2dContext->DrawTextLayout(D2D1::Point2F(0.0f, 0.0f), layout, m_d2dWhiteBrush, texFormat == Draw::DataFormat::R8G8B8A8_UNORM ? D2D1_DRAW_TEXT_OPTIONS_ENABLE_COLOR_FONT : D2D1_DRAW_TEXT_OPTIONS_NONE); + m_d2dContext->DrawTextLayout(D2D1::Point2F(0.0f, 0.0f), layout, m_d2dWhiteBrush, fullColor ? D2D1_DRAW_TEXT_OPTIONS_ENABLE_COLOR_FONT : D2D1_DRAW_TEXT_OPTIONS_NONE); m_d2dContext->EndDraw(); layout->Release(); @@ -357,8 +380,7 @@ bool TextDrawerUWP::DrawStringBitmap(std::vector &bitmapData, TextStrin return false; } - // Convert the bitmap to a Thin3D compatible array of 16-bit pixels. Can't use a single channel format - // because we need white. Well, we could using swizzle, but not all our backends support that. + // Convert the bitmap to a Thin3D compatible array of pixels. if (texFormat == Draw::DataFormat::R8G8B8A8_UNORM || texFormat == Draw::DataFormat::B8G8R8A8_UNORM) { bitmapData.resize(entry.bmWidth * entry.bmHeight * sizeof(uint32_t)); bool swap = texFormat == Draw::DataFormat::R8G8B8A8_UNORM; @@ -418,3 +440,4 @@ void TextDrawerUWP::ClearFonts() { } #endif + diff --git a/Common/Render/Text/draw_text_uwp.h b/Common/Render/Text/draw_text_uwp.h index 6ca02de944..447b30ce5e 100644 --- a/Common/Render/Text/draw_text_uwp.h +++ b/Common/Render/Text/draw_text_uwp.h @@ -5,7 +5,7 @@ #include #include "Common/Render/Text/draw_text.h" -#if PPSSPP_PLATFORM(UWP) +#if defined(_WIN32) && !defined(USING_QT_UI) #include #include @@ -32,16 +32,16 @@ protected: std::map> fontMap_; // Direct2D drawing components. - ID2D1Factory5* m_d2dFactory = nullptr; - ID2D1Device4* m_d2dDevice = nullptr; - ID2D1DeviceContext4* m_d2dContext = nullptr; - ID2D1SolidColorBrush* m_d2dWhiteBrush = nullptr; + ID2D1Factory5 *m_d2dFactory = nullptr; + ID2D1Device4 *m_d2dDevice = nullptr; + ID2D1DeviceContext4 *m_d2dContext = nullptr; + ID2D1SolidColorBrush *m_d2dWhiteBrush = nullptr; // DirectWrite drawing components. - IDWriteFactory5* m_dwriteFactory = nullptr; - IDWriteFontSet* m_fontSet = nullptr; - IDWriteFontSetBuilder1* m_fontSetBuilder = nullptr; - IDWriteFontCollection1* m_fontCollection = nullptr; + IDWriteFactory5 *m_dwriteFactory = nullptr; + IDWriteFontSet *m_fontSet = nullptr; + IDWriteFontSetBuilder1 *m_fontSetBuilder = nullptr; + IDWriteFontCollection1 *m_fontCollection = nullptr; IDWriteInMemoryFontFileLoader *m_inMemoryLoader = nullptr; std::vector> m_fontFiles; }; diff --git a/Common/Render/Text/draw_text_win.cpp b/Common/Render/Text/draw_text_win.cpp index 05bcf044bb..dfb348c96d 100644 --- a/Common/Render/Text/draw_text_win.cpp +++ b/Common/Render/Text/draw_text_win.cpp @@ -1,261 +1,5 @@ #include "ppsspp_config.h" -#include "Common/System/Display.h" -#include "Common/GPU/thin3d.h" -#include "Common/Data/Hash/Hash.h" -#include "Common/Data/Text/WrapText.h" -#include "Common/Data/Encoding/Utf8.h" -#include "Common/Render/Text/draw_text.h" -#include "Common/Render/Text/draw_text_win.h" - -#include "Common/Log.h" -#include "Common/StringUtils.h" - -#if defined(_WIN32) && !defined(USING_QT_UI) && !PPSSPP_PLATFORM(UWP) - -#define WIN32_LEAN_AND_MEAN -#include - -enum { - MAX_TEXT_WIDTH = 4096, - MAX_TEXT_HEIGHT = 512 -}; - -class TextDrawerFontContext { -public: - explicit TextDrawerFontContext(const FontStyle &_style, float _dpiScale) : hFont(0), style(_style), dpiScale(_dpiScale) { - FontStyleFlags styleFlags{}; - std::string fontName = GetFontNameForFontStyle(style, &styleFlags); - if (fontName.empty()) { - // Shouldn't happen. - fontName = "Tahoma"; - } - - int weight = FW_NORMAL; - if (styleFlags & FontStyleFlags::Bold) { - weight = FW_BOLD; - } - if (styleFlags & FontStyleFlags::Light) { - weight = FW_LIGHT; - } - - bool italic = (styleFlags & FontStyleFlags::Italic); - int height = style.sizePts; - - if (hFont) { - Destroy(); - } - // We apparently specify all font sizes in pts (1pt = 1.33px), so divide by only 72 for pixels. - int nHeight = -MulDiv(height, (int)(96.0f * (1.0f / dpiScale)), 72); - hFont = CreateFont(nHeight, 0, 0, 0, weight, italic, - FALSE, FALSE, DEFAULT_CHARSET, OUT_DEFAULT_PRECIS, - CLIP_DEFAULT_PRECIS, PROOF_QUALITY, - VARIABLE_PITCH, ConvertUTF8ToWString(fontName).c_str()); - } - - ~TextDrawerFontContext() { - Destroy(); - } - - void Destroy() { - DeleteObject(hFont); - hFont = 0; - } - - HFONT hFont = 0; - FontStyle style; - float dpiScale; -}; - -struct TextDrawerContext { - HDC hDC; - HBITMAP hbmBitmap; - int *pBitmapBits; -}; - -TextDrawerWin32::TextDrawerWin32(Draw::DrawContext *draw) : TextDrawer(draw), ctx_(nullptr) { - ctx_ = new TextDrawerContext(); - ctx_->hDC = CreateCompatibleDC(NULL); - - // Load the font files (pass the all flags so we get all filenames); - std::vector fonts = GetAllFontFilenames(); - for (const auto &iter : fonts) { - std::string fn = "assets/" + iter + ".ttf"; - int numFontsAdded = AddFontResourceEx(ConvertUTF8ToWString(fn).c_str(), FR_PRIVATE, NULL); - if (numFontsAdded == 0) { - ERROR_LOG(Log::G3D, "Failed to add font resource from %s", fn.c_str()); - } - } - - BITMAPINFO bmi{}; - bmi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER); - bmi.bmiHeader.biWidth = MAX_TEXT_WIDTH; - bmi.bmiHeader.biHeight = -MAX_TEXT_HEIGHT; - bmi.bmiHeader.biPlanes = 1; - bmi.bmiHeader.biCompression = BI_RGB; - bmi.bmiHeader.biBitCount = 32; - - ctx_->hbmBitmap = CreateDIBSection(ctx_->hDC, &bmi, DIB_RGB_COLORS, (VOID**)&ctx_->pBitmapBits, NULL, 0); - _assert_(ctx_->hbmBitmap != nullptr); - SetMapMode(ctx_->hDC, MM_TEXT); - - SelectObject(ctx_->hDC, ctx_->hbmBitmap); -} - -TextDrawerWin32::~TextDrawerWin32() { - ClearCache(); - ClearFonts(); - - // Unload the fonts. - std::vector fonts = GetAllFontFilenames(); - for (const auto &iter : fonts) { - std::string fn = "assets/" + iter + ".ttf"; - RemoveFontResourceEx(ConvertUTF8ToWString(fn).c_str(), FR_PRIVATE, NULL); - } - - DeleteObject(ctx_->hbmBitmap); - DeleteDC(ctx_->hDC); - delete ctx_; -} - -void TextDrawerWin32::SetOrCreateFont(const FontStyle &style) { - auto iter = fontMap_.find(style); - if (iter != fontMap_.end()) { - fontStyle_ = style; - return; - } - - fontMap_[style] = std::make_unique(style, dpiScale_); - fontStyle_ = style; -} - -void TextDrawerWin32::MeasureStringInternal(std::string_view str, float *w, float *h) { - auto iter = fontMap_.find(fontStyle_); - if (iter != fontMap_.end()) { - SelectObject(ctx_->hDC, iter->second->hFont); - } else { - ERROR_LOG(Log::G3D, "Failed to measure string"); - return; - } - - std::vector lines; - SplitString(str, '\n', lines); - - int extW = 0, extH = 0; - for (auto &line : lines) { - SIZE size; - std::wstring wstr = ConvertUTF8ToWString(line); - if (wstr.empty() && lines.size() > 1) { - // Measure empty lines as if it was a space. - wstr = L" "; - } - GetTextExtentPoint32(ctx_->hDC, wstr.c_str(), (int)wstr.size(), &size); - if (size.cx > extW) - extW = size.cx; - extH += size.cy; - } - - *w = extW; - *h = extH; -} - -bool TextDrawerWin32::DrawStringBitmap(std::vector &bitmapData, TextStringEntry &entry, Draw::DataFormat texFormat, std::string_view str, int align, bool fullColor) { - if (str.empty()) { - bitmapData.clear(); - return false; - } - std::wstring wstr = ConvertUTF8ToWString(ReplaceAll(str, "\n", "\r\n")); - - auto iter = fontMap_.find(fontStyle_); - if (iter != fontMap_.end()) { - SelectObject(ctx_->hDC, iter->second->hFont); - } - - // Set text properties - SetTextColor(ctx_->hDC, 0xFFFFFF); - SetBkColor(ctx_->hDC, 0); - SetTextAlign(ctx_->hDC, TA_TOP); - - // This matters for multi-line text - DT_CENTER is horizontal only. - UINT dtAlign = (align & ALIGN_HCENTER) == 0 ? DT_LEFT : DT_CENTER; - - RECT textRect = { 0 }; - DrawTextExW(ctx_->hDC, (LPWSTR)wstr.c_str(), (int)wstr.size(), &textRect, DT_NOPREFIX | DT_TOP | dtAlign | DT_CALCRECT, 0); - SIZE size; - size.cx = textRect.right; - size.cy = textRect.bottom; - - if (size.cx > MAX_TEXT_WIDTH) - size.cx = MAX_TEXT_WIDTH; - if (size.cy > MAX_TEXT_HEIGHT) - size.cy = MAX_TEXT_HEIGHT; - - if (size.cx == 0 || size.cy == 0) { - // Don't draw zero-sized textures. - WARN_LOG(Log::G3D, "Text '%.*s' caused a zero size image", (int)str.length(), str.data()); - return false; - } - - entry.texture = nullptr; - entry.width = size.cx; - entry.height = size.cy; - entry.bmWidth = (size.cx + 3) & ~3; - entry.bmHeight = (size.cy + 3) & ~3; - entry.lastUsedFrame = frameCount_; - - RECT rc = { 0 }; - rc.right = entry.bmWidth; - rc.bottom = entry.bmHeight; - FillRect(ctx_->hDC, &rc, (HBRUSH)GetStockObject(BLACK_BRUSH)); - DrawTextExW(ctx_->hDC, (LPWSTR)wstr.c_str(), (int)wstr.size(), &rc, DT_NOPREFIX | DT_TOP | dtAlign, 0); - - // Convert the bitmap to a Thin3D compatible array of 16-bit pixels. Can't use a single channel format - // because we need white. Well, we could using swizzle, but not all our backends support that. - if (texFormat == Draw::DataFormat::R8G8B8A8_UNORM || texFormat == Draw::DataFormat::B8G8R8A8_UNORM) { - bitmapData.resize(entry.bmWidth * entry.bmHeight * sizeof(uint32_t)); - uint32_t *bitmapData32 = (uint32_t *)&bitmapData[0]; - for (int y = 0; y < entry.bmHeight; y++) { - for (int x = 0; x < entry.bmWidth; x++) { - uint8_t bAlpha = (uint8_t)(ctx_->pBitmapBits[MAX_TEXT_WIDTH * y + x] & 0xff); - bitmapData32[entry.bmWidth * y + x] = AlphaToPremul8888(bAlpha); - } - } - } else if (texFormat == Draw::DataFormat::B4G4R4A4_UNORM_PACK16 || texFormat == Draw::DataFormat::R4G4B4A4_UNORM_PACK16) { - bitmapData.resize(entry.bmWidth * entry.bmHeight * sizeof(uint16_t)); - uint16_t *bitmapData16 = (uint16_t *)&bitmapData[0]; - for (int y = 0; y < entry.bmHeight; y++) { - for (int x = 0; x < entry.bmWidth; x++) { - uint8_t bAlpha = (uint8_t)(ctx_->pBitmapBits[MAX_TEXT_WIDTH * y + x] & 0xff); - bitmapData16[entry.bmWidth * y + x] = AlphaToPremul4444(bAlpha); - } - } - } else if (texFormat == Draw::DataFormat::A4R4G4B4_UNORM_PACK16) { - bitmapData.resize(entry.bmWidth * entry.bmHeight * sizeof(uint16_t)); - uint16_t *bitmapData16 = (uint16_t *)&bitmapData[0]; - for (int y = 0; y < entry.bmHeight; y++) { - for (int x = 0; x < entry.bmWidth; x++) { - uint8_t bAlpha = (uint8_t)(ctx_->pBitmapBits[MAX_TEXT_WIDTH * y + x] & 0xff); - bitmapData16[entry.bmWidth * y + x] = AlphaToPremul4444(bAlpha); - } - } - } else if (texFormat == Draw::DataFormat::R8_UNORM) { - bitmapData.resize(entry.bmWidth * entry.bmHeight); - for (int y = 0; y < entry.bmHeight; y++) { - for (int x = 0; x < entry.bmWidth; x++) { - uint8_t bAlpha = ctx_->pBitmapBits[MAX_TEXT_WIDTH * y + x] & 0xff; - bitmapData[entry.bmWidth * y + x] = bAlpha; - } - } - } else { - _assert_msg_(false, "Bad TextDrawer format"); - } - return true; -} - -void TextDrawerWin32::ClearFonts() { - for (auto &iter : fontMap_) { - iter.second->Destroy(); - } - fontMap_.clear(); -} +#if defined(_WIN32) && !defined(USING_QT_UI) +// TextDrawerWin32 is an alias of TextDrawerUWP; implementation is in draw_text_uwp.cpp. #endif diff --git a/Common/Render/Text/draw_text_win.h b/Common/Render/Text/draw_text_win.h index 3517aca572..5f894d5be8 100644 --- a/Common/Render/Text/draw_text_win.h +++ b/Common/Render/Text/draw_text_win.h @@ -1,31 +1,8 @@ #pragma once -#include "ppsspp_config.h" +#include "Common/Render/Text/draw_text_uwp.h" -#include -#include "Common/Render/Text/draw_text.h" - -#if defined(_WIN32) && !defined(USING_QT_UI) && !PPSSPP_PLATFORM(UWP) - -struct TextDrawerContext; -// Internal struct but all details in .cpp file (pimpl to avoid pulling in excessive headers here) -class TextDrawerFontContext; - -class TextDrawerWin32 : public TextDrawer { -public: - TextDrawerWin32(Draw::DrawContext *draw); - ~TextDrawerWin32(); - - void SetOrCreateFont(const FontStyle &style) override; - bool DrawStringBitmap(std::vector &bitmapData, TextStringEntry &entry, Draw::DataFormat texFormat, std::string_view str, int align, bool fullColor) override; - -protected: - void MeasureStringInternal(std::string_view str, float *w, float *h) override; - bool SupportsColorEmoji() const override { return false; } - void ClearFonts() override; - - TextDrawerContext *ctx_; - std::map> fontMap_; -}; +#if defined(_WIN32) && !defined(USING_QT_UI) +using TextDrawerWin32 = TextDrawerUWP; #endif diff --git a/UWP/XAudioSoundStream.cpp b/UWP/XAudioSoundStream.cpp index 8852ab3af8..c2d7eacb40 100644 --- a/UWP/XAudioSoundStream.cpp +++ b/UWP/XAudioSoundStream.cpp @@ -92,6 +92,7 @@ void XAudioBackend::Stop() { if (xaudioDevice) { xaudioDevice->Release(); xaudioDevice = nullptr; + sourceVoice_ = nullptr; } } diff --git a/Windows/PPSSPP.vcxproj b/Windows/PPSSPP.vcxproj index 3f62b6e383..18c8d5d8d7 100644 --- a/Windows/PPSSPP.vcxproj +++ b/Windows/PPSSPP.vcxproj @@ -1,4 +1,4 @@ - + @@ -194,7 +194,7 @@ stdcpp17 - avrt.lib;mmdevapi.lib;wbemuuid.lib;dwmapi.lib;winhttp.lib;uxtheme.lib;mfuuid.lib;shlwapi.lib;Winmm.lib;Ws2_32.lib;comctl32.lib;dxguid.lib;avcodec.lib;avformat.lib;avutil.lib;swresample.lib;swscale.lib;setupapi.lib;hid.lib;opengl32.lib;glu32.lib;%(AdditionalDependencies) + d2d1.lib;dwrite.lib;d3d11.lib;avrt.lib;mmdevapi.lib;wbemuuid.lib;dwmapi.lib;winhttp.lib;uxtheme.lib;mfuuid.lib;shlwapi.lib;Winmm.lib;Ws2_32.lib;comctl32.lib;dxguid.lib;avcodec.lib;avformat.lib;avutil.lib;swresample.lib;swscale.lib;setupapi.lib;hid.lib;opengl32.lib;glu32.lib;%(AdditionalDependencies) ../ffmpeg/Windows/x86/lib true Windows @@ -233,7 +233,7 @@ stdcpp17 - avrt.lib;mmdevapi.lib;wbemuuid.lib;dwmapi.lib;winhttp.lib;uxtheme.lib;mfuuid.lib;shlwapi.lib;Winmm.lib;Ws2_32.lib;comctl32.lib;dxguid.lib;avcodec.lib;avformat.lib;avutil.lib;swresample.lib;swscale.lib;setupapi.lib;hid.lib;opengl32.lib;glu32.lib;%(AdditionalDependencies) + d2d1.lib;dwrite.lib;d3d11.lib;avrt.lib;mmdevapi.lib;wbemuuid.lib;dwmapi.lib;winhttp.lib;uxtheme.lib;mfuuid.lib;shlwapi.lib;Winmm.lib;Ws2_32.lib;comctl32.lib;dxguid.lib;avcodec.lib;avformat.lib;avutil.lib;swresample.lib;swscale.lib;setupapi.lib;hid.lib;opengl32.lib;glu32.lib;%(AdditionalDependencies) ../ffmpeg/Windows/x86_64/lib true $(OutDir)$(ProjectName).pdb @@ -267,7 +267,7 @@ stdcpp17 - avrt.lib;mmdevapi.lib;wbemuuid.lib;dwmapi.lib;winhttp.lib;uxtheme.lib;mfuuid.lib;shlwapi.lib;Winmm.lib;Ws2_32.lib;comctl32.lib;dxguid.lib;avcodec.lib;avformat.lib;avutil.lib;swresample.lib;swscale.lib;setupapi.lib;hid.lib;oleaut32.lib;comdlg32.lib;shell32.lib;user32.lib;gdi32.lib;advapi32.lib;ole32.lib;%(AdditionalDependencies) + d2d1.lib;dwrite.lib;d3d11.lib;avrt.lib;mmdevapi.lib;wbemuuid.lib;dwmapi.lib;winhttp.lib;uxtheme.lib;mfuuid.lib;shlwapi.lib;Winmm.lib;Ws2_32.lib;comctl32.lib;dxguid.lib;avcodec.lib;avformat.lib;avutil.lib;swresample.lib;swscale.lib;setupapi.lib;hid.lib;oleaut32.lib;comdlg32.lib;shell32.lib;user32.lib;gdi32.lib;advapi32.lib;ole32.lib;%(AdditionalDependencies) ../ffmpeg/Windows/aarch64/lib true $(OutDir)$(ProjectName).pdb @@ -303,7 +303,7 @@ stdcpp17 - avrt.lib;mmdevapi.lib;wbemuuid.lib;dwmapi.lib;winhttp.lib;uxtheme.lib;mfuuid.lib;shlwapi.lib;Winmm.lib;Ws2_32.lib;comctl32.lib;dxguid.lib;avcodec.lib;avformat.lib;avutil.lib;swresample.lib;swscale.lib;setupapi.lib;hid.lib;opengl32.lib;glu32.lib;%(AdditionalDependencies) + d2d1.lib;dwrite.lib;d3d11.lib;avrt.lib;mmdevapi.lib;wbemuuid.lib;dwmapi.lib;winhttp.lib;uxtheme.lib;mfuuid.lib;shlwapi.lib;Winmm.lib;Ws2_32.lib;comctl32.lib;dxguid.lib;avcodec.lib;avformat.lib;avutil.lib;swresample.lib;swscale.lib;setupapi.lib;hid.lib;opengl32.lib;glu32.lib;%(AdditionalDependencies) ../ffmpeg/Windows/x86/lib;%(AdditionalLibraryDirectories) $(OutDir)$(TargetName)$(TargetExt) true @@ -351,7 +351,7 @@ stdcpp17 - avrt.lib;mmdevapi.lib;wbemuuid.lib;dwmapi.lib;winhttp.lib;uxtheme.lib;mfuuid.lib;shlwapi.lib;Winmm.lib;Ws2_32.lib;comctl32.lib;dxguid.lib;avcodec.lib;avformat.lib;avutil.lib;swresample.lib;swscale.lib;setupapi.lib;hid.lib;opengl32.lib;glu32.lib;%(AdditionalDependencies) + d2d1.lib;dwrite.lib;d3d11.lib;avrt.lib;mmdevapi.lib;wbemuuid.lib;dwmapi.lib;winhttp.lib;uxtheme.lib;mfuuid.lib;shlwapi.lib;Winmm.lib;Ws2_32.lib;comctl32.lib;dxguid.lib;avcodec.lib;avformat.lib;avutil.lib;swresample.lib;swscale.lib;setupapi.lib;hid.lib;opengl32.lib;glu32.lib;%(AdditionalDependencies) ../ffmpeg/Windows/x86_64/lib;%(AdditionalLibraryDirectories) true Windows @@ -393,7 +393,7 @@ stdcpp17 - avrt.lib;mmdevapi.lib;wbemuuid.lib;dwmapi.lib;winhttp.lib;uxtheme.lib;mfuuid.lib;shlwapi.lib;Winmm.lib;Ws2_32.lib;comctl32.lib;dxguid.lib;avcodec.lib;avformat.lib;avutil.lib;swresample.lib;swscale.lib;setupapi.lib;hid.lib;oleaut32.lib;comdlg32.lib;shell32.lib;user32.lib;gdi32.lib;advapi32.lib;ole32.lib;%(AdditionalDependencies) + d2d1.lib;dwrite.lib;d3d11.lib;avrt.lib;mmdevapi.lib;wbemuuid.lib;dwmapi.lib;winhttp.lib;uxtheme.lib;mfuuid.lib;shlwapi.lib;Winmm.lib;Ws2_32.lib;comctl32.lib;dxguid.lib;avcodec.lib;avformat.lib;avutil.lib;swresample.lib;swscale.lib;setupapi.lib;hid.lib;oleaut32.lib;comdlg32.lib;shell32.lib;user32.lib;gdi32.lib;advapi32.lib;ole32.lib;%(AdditionalDependencies) ../ffmpeg/Windows/aarch64/lib;%(AdditionalLibraryDirectories) true Windows diff --git a/headless/Headless.vcxproj b/headless/Headless.vcxproj index 52a171dc42..4ad32aa9fd 100644 --- a/headless/Headless.vcxproj +++ b/headless/Headless.vcxproj @@ -150,7 +150,7 @@ Console true - winhttp.lib;mfuuid.lib;shlwapi.lib;Winmm.lib;Ws2_32.lib;avcodec.lib;avformat.lib;avutil.lib;swresample.lib;swscale.lib;comctl32.lib;dxguid.lib;opengl32.lib;glu32.lib;%(AdditionalDependencies) + d2d1.lib;dwrite.lib;d3d11.lib;winhttp.lib;mfuuid.lib;shlwapi.lib;Winmm.lib;Ws2_32.lib;avcodec.lib;avformat.lib;avutil.lib;swresample.lib;swscale.lib;comctl32.lib;dxguid.lib;opengl32.lib;glu32.lib;%(AdditionalDependencies) 0x00400000 false true @@ -183,7 +183,7 @@ Console true - winhttp.lib;mfuuid.lib;shlwapi.lib;Winmm.lib;Ws2_32.lib;avcodec.lib;avformat.lib;avutil.lib;swresample.lib;swscale.lib;comctl32.lib;dxguid.lib;opengl32.lib;glu32.lib;%(AdditionalDependencies) + d2d1.lib;dwrite.lib;d3d11.lib;winhttp.lib;mfuuid.lib;shlwapi.lib;Winmm.lib;Ws2_32.lib;avcodec.lib;avformat.lib;avutil.lib;swresample.lib;swscale.lib;comctl32.lib;dxguid.lib;opengl32.lib;glu32.lib;%(AdditionalDependencies) 0x00400000 false true @@ -215,7 +215,7 @@ Console true - winhttp.lib;ole32.lib;mfuuid.lib;shlwapi.lib;Winmm.lib;Ws2_32.lib;avcodec.lib;avformat.lib;avutil.lib;swresample.lib;swscale.lib;comctl32.lib;dxguid.lib;shell32.lib;advapi32.lib;gdi32.lib;%(AdditionalDependencies) + d2d1.lib;dwrite.lib;d3d11.lib;winhttp.lib;ole32.lib;mfuuid.lib;shlwapi.lib;Winmm.lib;Ws2_32.lib;avcodec.lib;avformat.lib;avutil.lib;swresample.lib;swscale.lib;comctl32.lib;dxguid.lib;shell32.lib;advapi32.lib;gdi32.lib;%(AdditionalDependencies) /ignore:4049 /ignore:4217 %(AdditionalOptions) ../ffmpeg/Windows/aarch64/lib @@ -248,7 +248,7 @@ true true true - winhttp.lib;mfuuid.lib;shlwapi.lib;Winmm.lib;Ws2_32.lib;avcodec.lib;avformat.lib;avutil.lib;swresample.lib;swscale.lib;comctl32.lib;dxguid.lib;opengl32.lib;glu32.lib;%(AdditionalDependencies) + d2d1.lib;dwrite.lib;d3d11.lib;winhttp.lib;mfuuid.lib;shlwapi.lib;Winmm.lib;Ws2_32.lib;avcodec.lib;avformat.lib;avutil.lib;swresample.lib;swscale.lib;comctl32.lib;dxguid.lib;opengl32.lib;glu32.lib;%(AdditionalDependencies) 0x00400000 false true @@ -286,7 +286,7 @@ true true true - winhttp.lib;mfuuid.lib;shlwapi.lib;Winmm.lib;Ws2_32.lib;avcodec.lib;avformat.lib;avutil.lib;swresample.lib;swscale.lib;comctl32.lib;dxguid.lib;opengl32.lib;glu32.lib;%(AdditionalDependencies) + d2d1.lib;dwrite.lib;d3d11.lib;winhttp.lib;mfuuid.lib;shlwapi.lib;Winmm.lib;Ws2_32.lib;avcodec.lib;avformat.lib;avutil.lib;swresample.lib;swscale.lib;comctl32.lib;dxguid.lib;opengl32.lib;glu32.lib;%(AdditionalDependencies) 0x00400000 false true @@ -323,7 +323,7 @@ true true true - winhttp.lib;ole32.lib;mfuuid.lib;shlwapi.lib;Winmm.lib;Ws2_32.lib;avcodec.lib;avformat.lib;avutil.lib;swresample.lib;swscale.lib;comctl32.lib;dxguid.lib;shell32.lib;advapi32.lib;gdi32.lib;%(AdditionalDependencies) + d2d1.lib;dwrite.lib;d3d11.lib;winhttp.lib;ole32.lib;mfuuid.lib;shlwapi.lib;Winmm.lib;Ws2_32.lib;avcodec.lib;avformat.lib;avutil.lib;swresample.lib;swscale.lib;comctl32.lib;dxguid.lib;shell32.lib;advapi32.lib;gdi32.lib;%(AdditionalDependencies) /ignore:4049 /ignore:4217 %(AdditionalOptions) ../ffmpeg/Windows/aarch64/lib;%(AdditionalLibraryDirectories) diff --git a/unittest/UnitTests.vcxproj b/unittest/UnitTests.vcxproj index 13ac7577c7..00bbdc2bef 100644 --- a/unittest/UnitTests.vcxproj +++ b/unittest/UnitTests.vcxproj @@ -165,7 +165,7 @@ Console true - winhttp.lib;mfuuid.lib;shlwapi.lib;Ws2_32.lib;winmm.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;avcodec.lib;avformat.lib;avutil.lib;swresample.lib;swscale.lib;comctl32.lib;dxguid.lib;opengl32.lib;glu32.lib;%(AdditionalDependencies) + d2d1.lib;dwrite.lib;d3d11.lib;winhttp.lib;mfuuid.lib;shlwapi.lib;Ws2_32.lib;winmm.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;avcodec.lib;avformat.lib;avutil.lib;swresample.lib;swscale.lib;comctl32.lib;dxguid.lib;opengl32.lib;glu32.lib;%(AdditionalDependencies) /ignore:4049 /ignore:4217 %(AdditionalOptions) ../ffmpeg/Windows/x86_64/lib @@ -188,7 +188,7 @@ Console true - winhttp.lib;mfuuid.lib;shlwapi.lib;Ws2_32.lib;winmm.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;avcodec.lib;avformat.lib;avutil.lib;swresample.lib;swscale.lib;comctl32.lib;dxguid.lib;%(AdditionalDependencies) + d2d1.lib;dwrite.lib;d3d11.lib;winhttp.lib;mfuuid.lib;shlwapi.lib;Ws2_32.lib;winmm.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;avcodec.lib;avformat.lib;avutil.lib;swresample.lib;swscale.lib;comctl32.lib;dxguid.lib;%(AdditionalDependencies) /ignore:4049 /ignore:4217 %(AdditionalOptions) ../ffmpeg/Windows/aarch64/lib @@ -216,7 +216,7 @@ true true true - winhttp.lib;mfuuid.lib;shlwapi.lib;Ws2_32.lib;winmm.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;avcodec.lib;avformat.lib;avutil.lib;swresample.lib;swscale.lib;comctl32.lib;dxguid.lib;opengl32.lib;glu32.lib;%(AdditionalDependencies) + d2d1.lib;dwrite.lib;d3d11.lib;winhttp.lib;mfuuid.lib;shlwapi.lib;Ws2_32.lib;winmm.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;avcodec.lib;avformat.lib;avutil.lib;swresample.lib;swscale.lib;comctl32.lib;dxguid.lib;opengl32.lib;glu32.lib;%(AdditionalDependencies) /ignore:4049 /ignore:4217 %(AdditionalOptions) ../ffmpeg/Windows/x86/lib @@ -245,7 +245,7 @@ true true true - winhttp.lib;mfuuid.lib;shlwapi.lib;Ws2_32.lib;winmm.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;avcodec.lib;avformat.lib;avutil.lib;swresample.lib;swscale.lib;comctl32.lib;dxguid.lib;opengl32.lib;glu32.lib;%(AdditionalDependencies) + d2d1.lib;dwrite.lib;d3d11.lib;winhttp.lib;mfuuid.lib;shlwapi.lib;Ws2_32.lib;winmm.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;avcodec.lib;avformat.lib;avutil.lib;swresample.lib;swscale.lib;comctl32.lib;dxguid.lib;opengl32.lib;glu32.lib;%(AdditionalDependencies) /ignore:4049 /ignore:4217 %(AdditionalOptions) ../ffmpeg/Windows/x86_64/lib @@ -274,7 +274,7 @@ true true true - winhttp.lib;mfuuid.lib;shlwapi.lib;Ws2_32.lib;winmm.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;avcodec.lib;avformat.lib;avutil.lib;swresample.lib;swscale.lib;comctl32.lib;dxguid.lib;%(AdditionalDependencies) + d2d1.lib;dwrite.lib;d3d11.lib;winhttp.lib;mfuuid.lib;shlwapi.lib;Ws2_32.lib;winmm.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;avcodec.lib;avformat.lib;avutil.lib;swresample.lib;swscale.lib;comctl32.lib;dxguid.lib;%(AdditionalDependencies) /ignore:4049 /ignore:4217 %(AdditionalOptions) ../ffmpeg/Windows/aarch64/lib