diff --git a/AGENTS.md b/AGENTS.md index 6c0d1e600b..bf5fbe3b6a 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -221,6 +221,12 @@ UWP/PPSSPP_UWPMain.cpp android/jni/app-android.cpp libretro/libretro.cpp +**Never include `Common/GPU/Vulkan/VulkanLoader.h` directly from `UI/`.** On Linux the Vulkan headers +bring in X11, whose definitions (`Screen` among them) break `Common/UI/Screen.h`. Windows and Android +builds don't show it, so it only fails on CI. The same goes for including UI headers (`View.h`, `Screen.h`) in a +file that has the Vulkan ones. Put what UI code needs in a header without Vulkan includes, like +`Common/GPU/Vulkan/VulkanDriverVars.h`, or pass the value in from the UI side. + ## Reverse-engineering the firmware When a question about hardware behaviour can't be settled from the docs or from JPCSP - what a field in diff --git a/Common/GPU/Vulkan/VulkanDriverVars.h b/Common/GPU/Vulkan/VulkanDriverVars.h index 8ad15da167..e516601475 100644 --- a/Common/GPU/Vulkan/VulkanDriverVars.h +++ b/Common/GPU/Vulkan/VulkanDriverVars.h @@ -1,5 +1,6 @@ #pragma once +#include #include #include "Common/Common.h" @@ -18,3 +19,12 @@ const AdrenoEnvVarDef *GetAdrenoEnvVarDefs(int *count); // False where AdrenoTools' linker namespace tricks are known or suspected to break (Android 17 and its previews). bool VulkanCustomDriverAllowedByOS(); + +// Declared here rather than in VulkanLoader.h, whose Vulkan headers bring in X11 on Linux, and its Screen +// clashes with ours. + +// When Vulkan didn't work with a custom driver: clears the setting and unloads the library, so the next +// try gets the system's driver. Returns false if no custom driver was in use. +bool VulkanDisableCustomDriver(); +// The custom driver that failed (and was cleared) since the last call, if any. +std::string VulkanTakeFailedCustomDriver(); diff --git a/Common/GPU/Vulkan/VulkanLoader.cpp b/Common/GPU/Vulkan/VulkanLoader.cpp index 94fc47e97a..8e5f5448a7 100644 --- a/Common/GPU/Vulkan/VulkanLoader.cpp +++ b/Common/GPU/Vulkan/VulkanLoader.cpp @@ -362,6 +362,24 @@ static const char * const so_names[] = { }; #endif +// The custom driver that didn't work, for VulkanTakeFailedCustomDriver. +static std::string g_failedCustomDriver; + +static bool CustomDriverInUse() { +#if PPSSPP_PLATFORM(ANDROID) && PPSSPP_ARCH(ARM64) + return !g_Config.sCustomDriver.empty() && g_Config.sCustomDriver != "Default" && VulkanCustomDriverAllowedByOS(); +#else + return false; +#endif +} + +// Forgets the custom driver, so that the next try (and the next run) uses the system's. +static void ForgetCustomDriver() { + ERROR_LOG(Log::G3D, "Custom driver '%s' failed, switching to the system driver", g_Config.sCustomDriver.c_str()); + g_failedCustomDriver = g_Config.sCustomDriver; + g_Config.sCustomDriver.clear(); +} + static VulkanLibraryHandle VulkanLoadLibrary(std::string *errorString) { #if PPSSPP_PLATFORM(SWITCH) // Always unavailable, for now. @@ -376,7 +394,7 @@ static VulkanLibraryHandle VulkanLoadLibrary(std::string *errorString) { #if PPSSPP_PLATFORM(ANDROID) && PPSSPP_ARCH(ARM64) if (!g_Config.sCustomDriver.empty() && g_Config.sCustomDriver != "Default" && !VulkanCustomDriverAllowedByOS()) { WARN_LOG(Log::G3D, "Custom driver '%s' ignored, not supported on this Android version", g_Config.sCustomDriver.c_str()); - } else if (!g_Config.sCustomDriver.empty() && g_Config.sCustomDriver != "Default") { + } else if (CustomDriverInUse()) { const Path driverPath = g_Config.internalDataDirectory / "drivers" / g_Config.sCustomDriver; json::JsonReader meta = json::JsonReader((driverPath / "meta.json").c_str()); @@ -402,6 +420,12 @@ static VulkanLibraryHandle VulkanLoadLibrary(std::string *errorString) { } else { INFO_LOG(Log::G3D, "Vulkan library loaded with AdrenoTools ('%s')", g_Config.sCustomDriver.c_str()); } + } else { + ERROR_LOG(Log::G3D, "Custom driver '%s' has no readable meta.json", g_Config.sCustomDriver.c_str()); + } + if (!lib) { + // The system's driver is loaded below instead. + ForgetCustomDriver(); } } #endif @@ -435,6 +459,22 @@ static void VulkanFreeLibrary(VulkanLibraryHandle &h) { } } +bool VulkanDisableCustomDriver() { + if (!CustomDriverInUse()) { + return false; + } + ForgetCustomDriver(); + VulkanFreeLibrary(vulkanLibrary); + g_vulkanAvailabilityChecked = false; + return true; +} + +std::string VulkanTakeFailedCustomDriver() { + std::string driver = std::move(g_failedCustomDriver); + g_failedCustomDriver.clear(); + return driver; +} + void VulkanSetAvailable(bool available) { INFO_LOG(Log::G3D, "Setting Vulkan availability to true"); g_vulkanAvailabilityChecked = true; @@ -480,6 +520,8 @@ bool VulkanMayBeAvailable() { std::string errorStr; VulkanLibraryHandle lib = VulkanLoadLibrary(&errorStr); + // After the load, which forgets a custom driver that didn't load at all. + const bool usedCustomDriver = CustomDriverInUse(); if (!lib) { INFO_LOG(Log::G3D, "Vulkan loader: Library not available: %s", errorStr.c_str()); g_vulkanAvailabilityChecked = true; @@ -678,6 +720,10 @@ bail: } if (!g_vulkanMayBeAvailable) { WARN_LOG(Log::G3D, "Vulkan with working device not detected."); + // Try the system's driver before giving up on Vulkan. + if (usedCustomDriver && VulkanDisableCustomDriver()) { + return VulkanMayBeAvailable(); + } } return g_vulkanMayBeAvailable; #endif diff --git a/Common/UI/Context.cpp b/Common/UI/Context.cpp index 030af9206d..428cca2e5d 100644 --- a/Common/UI/Context.cpp +++ b/Common/UI/Context.cpp @@ -16,14 +16,12 @@ #include "Common/Render/AtlasGen.h" UIContext::UIContext() { - fontStyle_ = new FontStyle(); bounds_ = Bounds(0, 0, g_display.dp_xres, g_display.dp_yres); } UIContext::~UIContext() { if (sampler_) sampler_->Release(); - delete fontStyle_; delete textDrawer_; if (uitexture_) uitexture_->Release(); @@ -43,10 +41,6 @@ void UIContext::Init(Draw::DrawContext *thin3d, Draw::Pipeline *uipipe, Draw::Pi void UIContext::BeginFrame() { frameStartTime_ = time_now_d(); - // Text drawn before anything set a style uses the theme's. - if (fontStyle_->sizePts <= 0 && theme) { - *fontStyle_ = theme->uiFont; - } if (atlasInvalid_ || !uitexture_) { if (uitexture_) { uitexture_->Release(); @@ -281,10 +275,6 @@ void UIContext::SetFontScale(float scaleX, float scaleY) { fontScaleY_ = scaleY; } -void UIContext::SetFontStyle(const FontStyle &fontStyle) { - *fontStyle_ = fontStyle; -} - static FontID AtlasFontFromStyle(const FontStyle &style) { // For now, we only have one font in the atlas. return FontID("UBUNTU24"); @@ -312,59 +302,59 @@ void UIContext::MeasureTextRect(const FontStyle &style, float scaleX, float scal } } -void UIContext::DrawText(std::string_view str, float x, float y, uint32_t color, int align) { +void UIContext::DrawText(const FontStyle &style, std::string_view str, float x, float y, uint32_t color, int align) { _dbg_assert_(str.data() != nullptr); if (!textDrawer_ || (align & FLAG_DYNAMIC_ASCII)) { // Use the font texture if this font is in that texture instead. - bool useFontTexture = Draw()->GetFontAtlas()->getFont(AtlasFontFromStyle(*fontStyle_)) != nullptr; + bool useFontTexture = Draw()->GetFontAtlas()->getFont(AtlasFontFromStyle(style)) != nullptr; if (useFontTexture) { Flush(); BindFontTexture(); } - float sizeFactor = (float)fontStyle_->sizePts / 24.0f; + float sizeFactor = (float)style.sizePts / 24.0f; Draw()->SetFontScale(fontScaleX_ * sizeFactor, fontScaleY_ * sizeFactor); - Draw()->DrawText(AtlasFontFromStyle(*fontStyle_), str, x, y, color, align); + Draw()->DrawText(AtlasFontFromStyle(style), str, x, y, color, align); if (useFontTexture) Flush(); } else { - textDrawer_->DrawString(*Draw(), *fontStyle_, fontScaleX_, fontScaleY_, str, x, y, color, align); + textDrawer_->DrawString(*Draw(), style, fontScaleX_, fontScaleY_, str, x, y, color, align); } RebindTexture(); } -void UIContext::DrawTextShadow(std::string_view str, float x, float y, uint32_t color, int align) { +void UIContext::DrawTextShadow(const FontStyle &style, std::string_view str, float x, float y, uint32_t color, int align) { uint32_t alpha = (color >> 1) & 0xFF000000; - DrawText(str, x + 2, y + 2, alpha, align); - DrawText(str, x, y, color, align); + DrawText(style, str, x + 2, y + 2, alpha, align); + DrawText(style, str, x, y, color, align); } -void UIContext::DrawTextRect(std::string_view str, const Bounds &bounds, uint32_t color, int align) { +void UIContext::DrawTextRect(const FontStyle &style, std::string_view str, const Bounds &bounds, uint32_t color, int align) { if (!textDrawer_ || (align & FLAG_DYNAMIC_ASCII)) { // Use the font texture if this font is in that texture instead. - bool useFontTexture = Draw()->GetFontAtlas()->getFont(AtlasFontFromStyle(*fontStyle_)) != nullptr; + bool useFontTexture = Draw()->GetFontAtlas()->getFont(AtlasFontFromStyle(style)) != nullptr; if (useFontTexture) { Flush(); BindFontTexture(); } - float sizeFactor = (float)fontStyle_->sizePts / 24.0f; + float sizeFactor = (float)style.sizePts / 24.0f; Draw()->SetFontScale(fontScaleX_ * sizeFactor, fontScaleY_ * sizeFactor); - Draw()->DrawTextRect(AtlasFontFromStyle(*fontStyle_), str, bounds.x, bounds.y, bounds.w, bounds.h, color, align); + Draw()->DrawTextRect(AtlasFontFromStyle(style), str, bounds.x, bounds.y, bounds.w, bounds.h, color, align); if (useFontTexture) Flush(); } else { Bounds rounded = bounds; rounded.x = floorf(rounded.x); rounded.y = floorf(rounded.y); - textDrawer_->DrawStringRect(*Draw(), *fontStyle_, fontScaleX_, fontScaleY_, str, rounded, color, align); + textDrawer_->DrawStringRect(*Draw(), style, fontScaleX_, fontScaleY_, str, rounded, color, align); } RebindTexture(); } static constexpr float MIN_TEXT_SCALE = 0.7f; -float UIContext::CalculateTextScale(std::string_view str, float availWidth) const { +float UIContext::CalculateTextScale(const FontStyle &style, std::string_view str, float availWidth) const { float actualWidth, actualHeight; - MeasureTextRect(theme->uiFont, 1.0f, 1.0f, str, availWidth, &actualWidth, &actualHeight, ALIGN_VCENTER); + MeasureTextRect(style, 1.0f, 1.0f, str, availWidth, &actualWidth, &actualHeight, ALIGN_VCENTER); if (actualWidth > availWidth) { // TODO: Return feedback that wrapping was needed. // Shave off a little, since float rounding can otherwise leave the scaled text a hair @@ -374,25 +364,25 @@ float UIContext::CalculateTextScale(std::string_view str, float availWidth) cons return 1.0f; } -void UIContext::DrawTextRectSqueeze(std::string_view str, const Bounds &bounds, uint32_t color, int align) { +void UIContext::DrawTextRectSqueeze(const FontStyle &style, std::string_view str, const Bounds &bounds, uint32_t color, int align) { if (bounds.w <= 0 || bounds.h <= 0) { // Probably mid-layout. return; } float origScaleX = fontScaleX_; float origScaleY = fontScaleY_; - float scale = CalculateTextScale(str, bounds.w / origScaleX); + float scale = CalculateTextScale(style, str, bounds.w / origScaleX); SetFontScale(scale * origScaleX, scale * origScaleY); Bounds textBounds(bounds.x, bounds.y, bounds.w, bounds.h); - DrawTextRect(str, textBounds, color, align); + DrawTextRect(style, str, textBounds, color, align); SetFontScale(origScaleX, origScaleY); } -void UIContext::DrawTextShadowRect(std::string_view str, const Bounds &bounds, uint32_t color, int align) { +void UIContext::DrawTextShadowRect(const FontStyle &style, std::string_view str, const Bounds &bounds, uint32_t color, int align) { uint32_t alpha = (color >> 1) & 0xFF000000; Bounds shadowBounds(bounds.x+2, bounds.y+2, bounds.w, bounds.h); - DrawTextRect(str, shadowBounds, alpha, align); - DrawTextRect(str, bounds, color, align); + DrawTextRect(style, str, shadowBounds, alpha, align); + DrawTextRect(style, str, bounds, color, align); } void UIContext::FillRoundRect(const UI::Drawable &drawable, const Bounds &bounds, float radius) { diff --git a/Common/UI/Context.h b/Common/UI/Context.h index 996420d09e..e8448aa064 100644 --- a/Common/UI/Context.h +++ b/Common/UI/Context.h @@ -94,19 +94,17 @@ public: // High level drawing functions. They generally assume the default texture to be bounds. - void SetFontStyle(const FontStyle &style); - const FontStyle &GetFontStyle() { return *fontStyle_; } void SetFontScale(float scaleX, float scaleY); void MeasureText(const FontStyle &style, float scaleX, float scaleY, std::string_view str, float *x, float *y, int align = 0) const; void MeasureTextRect(const FontStyle &style, float scaleX, float scaleY, std::string_view str, float maxWidth, float *x, float *y, int align = 0) const; - void DrawText(std::string_view str, float x, float y, uint32_t color, int align = 0); - void DrawTextShadow(std::string_view str, float x, float y, uint32_t color, int align = 0); - void DrawTextRect(std::string_view str, const Bounds &bounds, uint32_t color, int align = 0); - void DrawTextShadowRect(std::string_view str, const Bounds &bounds, uint32_t color, int align = 0); + void DrawText(const FontStyle &style, std::string_view str, float x, float y, uint32_t color, int align = 0); + void DrawTextShadow(const FontStyle &style, std::string_view str, float x, float y, uint32_t color, int align = 0); + void DrawTextRect(const FontStyle &style, std::string_view str, const Bounds &bounds, uint32_t color, int align = 0); + void DrawTextShadowRect(const FontStyle &style, std::string_view str, const Bounds &bounds, uint32_t color, int align = 0); // Will squeeze the text into the bounds if needed. - void DrawTextRectSqueeze(std::string_view str, const Bounds &bounds, uint32_t color, int align = 0); + void DrawTextRectSqueeze(const FontStyle &style, std::string_view str, const Bounds &bounds, uint32_t color, int align = 0); - float CalculateTextScale(std::string_view str, float availWidth) const; + float CalculateTextScale(const FontStyle &style, std::string_view str, float availWidth) const; void FillRoundRect(const UI::Drawable &drawable, const Bounds &bounds, float radius); void FillRoundRect(const UI::Drawable &drawable, const Bounds &bounds, float radius, RoundCorners corners); @@ -152,7 +150,6 @@ private: float fontScaleX_ = 1.0f; float fontScaleY_ = 1.0f; - FontStyle *fontStyle_ = nullptr; TextDrawer *textDrawer_ = nullptr; Draw::SamplerState *sampler_ = nullptr; diff --git a/Common/UI/Notice.cpp b/Common/UI/Notice.cpp index 106d5d1d1a..1ff3689bec 100644 --- a/Common/UI/Notice.cpp +++ b/Common/UI/Notice.cpp @@ -95,8 +95,6 @@ void MeasureNotice(const UIContext &dc, NoticeLevel level, std::string_view text void RenderNotice(UIContext &dc, Bounds bounds, float height1, NoticeLevel level, std::string_view text, std::string_view details, std::string_view iconName, int align, float alpha, OSDMessageFlags flags, float timeVal, float padding, float radius, RoundCorners corners) { UI::Drawable background = UI::Drawable(colorAlpha(GetNoticeBackgroundColor(level), alpha)); - dc.SetFontStyle(dc.GetTheme().uiFont); - uint32_t foreGround = whiteAlpha(alpha); if (!(flags & OSDMessageFlags::Transparent)) { @@ -152,7 +150,7 @@ void RenderNotice(UIContext &dc, Bounds bounds, float height1, NoticeLevel level titleAlign |= FLAG_ELLIPSIZE_TEXT; } - dc.DrawTextShadowRect(text, primaryBounds.Inset(2.0f, 0.0f, 1.0f, 0.0f), foreGround, titleAlign); + dc.DrawTextShadowRect(dc.GetTheme().uiFont, text, primaryBounds.Inset(2.0f, 0.0f, 1.0f, 0.0f), foreGround, titleAlign); if (!details.empty()) { Bounds bottomTextBounds = bounds.Inset(3.0f, height1 + 5.0f, 3.0f, 3.0f); @@ -160,8 +158,6 @@ void RenderNotice(UIContext &dc, Bounds bounds, float height1, NoticeLevel level UI::Drawable backgroundDark = UI::Drawable(colorAlpha(darkenColor(GetNoticeBackgroundColor(level)), alpha)); dc.FillRect(backgroundDark, bottomTextBounds); } - dc.SetFontStyle(dc.GetTheme().uiFontSmall); - dc.DrawTextRect(details, bottomTextBounds.Inset(1.0f, 1.0f), foreGround, (align & FLAG_DYNAMIC_ASCII) | ALIGN_LEFT | FLAG_WRAP_TEXT); + dc.DrawTextRect(dc.GetTheme().uiFontSmall, details, bottomTextBounds.Inset(1.0f, 1.0f), foreGround, (align & FLAG_DYNAMIC_ASCII) | ALIGN_LEFT | FLAG_WRAP_TEXT); } - dc.SetFontStyle(dc.GetTheme().uiFont); } diff --git a/Common/UI/PopupScreens.cpp b/Common/UI/PopupScreens.cpp index a30a27541b..0130bed583 100644 --- a/Common/UI/PopupScreens.cpp +++ b/Common/UI/PopupScreens.cpp @@ -1073,7 +1073,6 @@ void AbstractChoiceWithValueDisplay::Draw(UIContext &dc) { style = dc.GetTheme().itemDisabledStyle; } int paddingX = 12; - dc.SetFontStyle(dc.GetTheme().uiFont); bool shadow; std::string valueText = ValueText(&shadow); @@ -1105,7 +1104,7 @@ void AbstractChoiceWithValueDisplay::Draw(UIContext &dc) { } dc.SetFontScale(scale, scale); Bounds valueBounds(bounds.x2() - textPadding_.right - imagePadding, bounds.y, w, bounds.h); - dc.DrawTextRect(valueText, valueBounds, color, ALIGN_RIGHT | ALIGN_VCENTER | FLAG_WRAP_TEXT); + dc.DrawTextRect(dc.GetTheme().uiFont, valueText, valueBounds,color, ALIGN_RIGHT | ALIGN_VCENTER | FLAG_WRAP_TEXT); dc.SetFontScale(1.0f, 1.0f); } else { Choice::Draw(dc); @@ -1119,7 +1118,7 @@ void AbstractChoiceWithValueDisplay::Draw(UIContext &dc) { float scale = CalculateValueScale(dc, valueText, bounds.w); dc.SetFontScale(scale, scale); - dc.DrawTextRect(valueText, bounds.Expand(-paddingX, 0.0f), color, ALIGN_LEFT | ALIGN_VCENTER | FLAG_WRAP_TEXT); + dc.DrawTextRect(dc.GetTheme().uiFont, valueText, bounds.Expand(-paddingX, 0.0f), color, ALIGN_LEFT | ALIGN_VCENTER | FLAG_WRAP_TEXT); dc.SetFontScale(1.0f, 1.0f); } } diff --git a/Common/UI/View.cpp b/Common/UI/View.cpp index 31535a9713..66d19b7941 100644 --- a/Common/UI/View.cpp +++ b/Common/UI/View.cpp @@ -484,13 +484,11 @@ void ClickableItem::DrawHint(UIContext &dc, const Style &style) const { if (hintText_.empty()) { return; } - dc.SetFontStyle(dc.GetTheme().uiFontTiny); dc.SetFontScale(1.0f, 1.0f); const float textHeight = hintHeight_ - HINT_PADDING_BOTTOM + HINT_TITLE_OVERLAP; const float indent = HintIndent(); Bounds hintBounds(bounds_.x + indent, bounds_.y2() - HINT_PADDING_BOTTOM - textHeight, bounds_.w - indent - HINT_PADDING_X, textHeight); - dc.DrawTextRect(hintText_, hintBounds, style.fgColor, ALIGN_TOPLEFT | FLAG_WRAP_TEXT); - dc.SetFontStyle(dc.GetTheme().uiFont); + dc.DrawTextRect(dc.GetTheme().uiFontTiny, hintText_, hintBounds, style.fgColor, ALIGN_TOPLEFT | FLAG_WRAP_TEXT); } float ClickableItem::HintIndent() const { @@ -521,7 +519,7 @@ void Choice::GetContentDimensionsBySpec(const UIContext &dc, MeasureSpec horiz, } if (horiz.type != EXACTLY && layoutParams_->width > 0.0f && availWidth > layoutParams_->width) availWidth = layoutParams_->width; - float scale = dc.CalculateTextScale(text_, availWidth); + float scale = dc.CalculateTextScale(dc.GetTheme().uiFont, text_, availWidth); float textW = 0.0f, textH = 0.0f; dc.MeasureTextRect(dc.GetTheme().uiFont, scale, scale, text_, availWidth, &textW, &textH, FLAG_WRAP_TEXT); textW += 4; // We need a small fudge factor here, not sure why yet. @@ -561,8 +559,6 @@ void Choice::Draw(UIContext &dc) { DrawIconShine(dc, b.Inset(5.0f, 5.0f), 0.65f, false); } } else if (!text_.empty() && !hideTitle_) { - dc.SetFontStyle(dc.GetTheme().uiFont); - int paddingLeft = 12; int paddingRight = 12; @@ -587,7 +583,7 @@ void Choice::Draw(UIContext &dc) { float availWidth = bounds.w - (paddingLeft + paddingRight + textPadding_.horiz()); if (centered_) { - dc.DrawTextRectSqueeze(text_, bounds, style.fgColor, ALIGN_CENTER | FLAG_WRAP_TEXT | drawTextFlags_); + dc.DrawTextRectSqueeze(dc.GetTheme().uiFont, text_, bounds, style.fgColor, ALIGN_CENTER | FLAG_WRAP_TEXT | drawTextFlags_); } else { if (rightIconImage_.isValid()) { uint32_t col = rightIconKeepColor_ ? 0xffffffff : style.fgColor; // Don't apply theme to gold icon @@ -601,7 +597,7 @@ void Choice::Draw(UIContext &dc) { dc.Draw()->DrawImageRotated(rightIconImage_, iconX, bounds.centerY(), rightIconScale_, rightIconRot_, col, rightIconFlipH_); } Bounds textBounds(bounds.x + paddingLeft + textPadding_.left, bounds.y, availWidth, bounds.h); - dc.DrawTextRectSqueeze(text_, textBounds, style.fgColor, ALIGN_VCENTER | FLAG_WRAP_TEXT | drawTextFlags_); + dc.DrawTextRectSqueeze(dc.GetTheme().uiFont, text_, textBounds, style.fgColor, ALIGN_VCENTER | FLAG_WRAP_TEXT | drawTextFlags_); } dc.SetFontScale(1.0f, 1.0f); } @@ -670,7 +666,7 @@ void InfoItem::Draw(UIContext &dc) { if (rightText_.empty()) { int paddingX = 12; Bounds padBounds = bounds_.Expand(-paddingX, 0); - dc.DrawTextRect(text_, padBounds, style.fgColor, ALIGN_VCENTER | FLAG_WRAP_TEXT); + dc.DrawTextRect(dc.GetTheme().uiFont, text_, padBounds, style.fgColor, ALIGN_VCENTER | FLAG_WRAP_TEXT); return; } @@ -680,12 +676,11 @@ void InfoItem::Draw(UIContext &dc) { float leftWidth, leftHeight; dc.MeasureTextRect(dc.GetTheme().uiFont, 1.0f, 1.0f, text_, padBounds.w, &leftWidth, &leftHeight, ALIGN_VCENTER); - dc.SetFontStyle(dc.GetTheme().uiFont); - dc.DrawTextRect(text_, padBounds, style.fgColor, ALIGN_VCENTER); + dc.DrawTextRect(dc.GetTheme().uiFont, text_, padBounds, style.fgColor, ALIGN_VCENTER); // The info item should not look too clickable even if it has a background. Make the right side dimmed a little. Bounds rightBounds(padBounds.x + leftWidth, padBounds.y, padBounds.w - leftWidth, padBounds.h); - dc.DrawTextRect(rightText_, rightBounds, alphaMul(style.fgColor, 0.75f), ALIGN_VCENTER | ALIGN_RIGHT | FLAG_WRAP_TEXT); + dc.DrawTextRect(dc.GetTheme().uiFont, rightText_, rightBounds, alphaMul(style.fgColor, 0.75f), ALIGN_VCENTER | ALIGN_RIGHT | FLAG_WRAP_TEXT); } std::string InfoItem::DescribeText() const { @@ -700,11 +695,11 @@ ItemHeader::ItemHeader(std::string_view text, LayoutParams *layoutParams) } void ItemHeader::Draw(UIContext &dc) { - dc.SetFontStyle(large_ ? dc.GetTheme().uiFont : dc.GetTheme().uiFontSmall); + const FontStyle &fontStyle = large_ ? dc.GetTheme().uiFont : dc.GetTheme().uiFontSmall; const UI::Style &style = popupStyle_ ? dc.GetTheme().popupStyle : dc.GetTheme().itemStyle; dc.FillRoundRect(style.background, bounds_, dc.GetTheme().choiceRoundRadius, roundCorners_); - dc.DrawText(text_, bounds_.x + 12, bounds_.centerY(), style.fgColor, ALIGN_LEFT | ALIGN_VCENTER); + dc.DrawText(fontStyle, text_, bounds_.x + 12, bounds_.centerY(), style.fgColor, ALIGN_LEFT | ALIGN_VCENTER); dc.Draw()->DrawImageCenterTexel(dc.GetTheme().whiteImage, bounds_.x, bounds_.y2()-2, bounds_.x2(), bounds_.y2(), style.fgColor); } @@ -743,8 +738,7 @@ void PopupHeader::Draw(UIContext &dc) { const float availableWidth = bounds_.w; float tw, th; - dc.SetFontStyle(dc.GetTheme().uiFontBig); - dc.MeasureText(dc.GetFontStyle(), 1.0f, 1.0f, text_, &tw, &th, 0); + dc.MeasureText(dc.GetTheme().uiFontBig, 1.0f, 1.0f, text_, &tw, &th, 0); float sineWidth = std::max(0.0f, (tw - availableWidth)) / 2.0f; @@ -761,7 +755,7 @@ void PopupHeader::Draw(UIContext &dc) { // Header background dc.FillRoundRect(dc.GetTheme().popupTitleStyle.background, bounds_, dc.GetTheme().choiceRoundRadius, roundCorners_); // Header title text - dc.DrawText(text_, bounds_.x + tx, bounds_.centerY(), dc.GetTheme().popupTitleStyle.fgColor, ALIGN_LEFT | ALIGN_VCENTER); + dc.DrawText(dc.GetTheme().uiFontBig, text_, bounds_.x + tx, bounds_.centerY(), dc.GetTheme().popupTitleStyle.fgColor, ALIGN_LEFT | ALIGN_VCENTER); // Underline. Skipping it with the new style. // dc.Draw()->DrawImageCenterTexel(dc.GetTheme().whiteImage, bounds_.x, bounds_.y2()-2, bounds_.x2(), bounds_.y2(), dc.GetTheme().popupTitleStyle.fgColor); @@ -792,8 +786,7 @@ void CollapsibleHeader::Draw(UIContext &dc) { float xoff = 37.0f; - dc.SetFontStyle(dc.GetTheme().uiFontSmall); - dc.DrawText(text_, bounds_.x + 6 + xoff, bounds_.centerY(), style.fgColor, ALIGN_LEFT | ALIGN_VCENTER); + dc.DrawText(dc.GetTheme().uiFontSmall, text_, bounds_.x + 6 + xoff, bounds_.centerY(), style.fgColor, ALIGN_LEFT | ALIGN_VCENTER); if (underline_) { dc.Draw()->DrawImageCenterTexel(dc.GetTheme().whiteImage, bounds_.x, bounds_.y2() - 2, bounds_.x2(), bounds_.y2(), style.fgColor); } @@ -905,7 +898,6 @@ void CheckBox::Draw(UIContext &dc) { } } - dc.SetFontStyle(dc.GetTheme().uiFont); DrawBG(dc, style, dc.GetTheme().choiceRoundRadius); @@ -919,7 +911,7 @@ void CheckBox::Draw(UIContext &dc) { const Bounds bounds = ContentBounds(); if (!text_.empty()) { Bounds textBounds(bounds.x + paddingX, bounds.y, availWidth, bounds.h); - dc.DrawTextRectSqueeze(text_, textBounds, style.fgColor, ALIGN_VCENTER | FLAG_WRAP_TEXT); + dc.DrawTextRectSqueeze(dc.GetTheme().uiFont, text_, textBounds, style.fgColor, ALIGN_VCENTER | FLAG_WRAP_TEXT); } dc.Draw()->DrawImage(image, bounds.x2() - paddingX, bounds.centerY(), 1.0f, style.fgColor, ALIGN_RIGHT | ALIGN_VCENTER); DrawHint(dc, style); @@ -962,7 +954,7 @@ void CheckBox::GetContentDimensions(const UIContext &dc, float &w, float &h) con } if (!text_.empty()) { - float scale = dc.CalculateTextScale(text_, availWidth); + float scale = dc.CalculateTextScale(dc.GetTheme().uiFont, text_, availWidth); float actualWidth, actualHeight; dc.MeasureTextRect(dc.GetTheme().uiFont, scale, scale, text_, availWidth, &actualWidth, &actualHeight, ALIGN_VCENTER | FLAG_WRAP_TEXT); @@ -1065,7 +1057,6 @@ void Button::Draw(UIContext &dc) { if (tw > bounds_.w || imageId.isValid()) { dc.PushScissor(bounds_); } - dc.SetFontStyle(dc.GetTheme().uiFont); dc.SetFontScale(scale_, scale_); if (imageId.isValid() && (ignoreText_ || text_.empty())) { dc.Draw()->DrawImage(imageId, bounds_.centerX(), bounds_.centerY(), scale_, style.fgColor, ALIGN_CENTER); @@ -1078,7 +1069,7 @@ void Button::Draw(UIContext &dc) { textX += img->w / 2.0f; } } - dc.DrawText(text_, textX, bounds_.centerY(), style.fgColor, ALIGN_CENTER); + dc.DrawText(dc.GetTheme().uiFont, text_, textX, bounds_.centerY(), style.fgColor, ALIGN_CENTER); } dc.SetFontScale(1.0f, 1.0f); @@ -1134,12 +1125,11 @@ void RadioButton::Draw(UIContext &dc) { const ImageID image(checked ? "I_RADIO_SELECTED" : "I_RADIO_EMPTY"); dc.Draw()->DrawImage(image, bounds.x + paddingW_ + radioRadius_, bounds.centerY(), 1.0f, style.fgColor, ALIGN_CENTER); - dc.SetFontStyle(dc.GetTheme().uiFont); if (!text_.empty()) { const float textX = bounds.x + paddingW_ * 2.0f + radioRadius_ * 2.0f; const Bounds textBounds(textX, bounds.y, bounds.x2() - paddingW_ - textX, bounds.h); - dc.DrawTextRect(text_, textBounds, style.fgColor, ALIGN_LEFT | ALIGN_VCENTER | FLAG_WRAP_TEXT); + dc.DrawTextRect(dc.GetTheme().uiFont, text_, textBounds, style.fgColor, ALIGN_LEFT | ALIGN_VCENTER | FLAG_WRAP_TEXT); } DrawHint(dc, style); @@ -1177,8 +1167,7 @@ void SimpleTextView::GetContentDimensions(const UIContext &dc, float &w, float & void SimpleTextView::Draw(UIContext &dc) { uint32_t textColor = dc.GetTheme().itemStyle.fgColor; - dc.SetFontStyle(*ComputeStyle(dc)); - dc.DrawText(text_, bounds_.x, bounds_.y, textColor, 0); + dc.DrawText(*ComputeStyle(dc), text_, bounds_.x, bounds_.y, textColor, 0); } const FontStyle *SimpleTextView::ComputeStyle(const UIContext &dc) const { @@ -1264,7 +1253,6 @@ void TextView::Draw(UIContext &dc) { } const FontStyle *style = GetTextStyle(dc, textSize_); - dc.SetFontStyle(*style); Bounds textBounds = bounds_; @@ -1287,14 +1275,10 @@ void TextView::Draw(UIContext &dc) { } else if (shadow_) { // Old-fashioned double-draw shadow. uint32_t shadowColor = 0x80000000; - dc.DrawTextRect(text_, textBounds.Offset(1.0f, 1.0f), shadowColor, textFlags); + dc.DrawTextRect(*style, text_, textBounds.Offset(1.0f, 1.0f), shadowColor, textFlags); } - dc.DrawTextRect(text_, textBounds, textColor, textFlags); - if (textSize_ != TextSize::Normal) { - // If we changed font style, reset it. - dc.SetFontStyle(dc.GetTheme().uiFont); - } + dc.DrawTextRect(*style, text_, textBounds, textColor, textFlags); if (clip) { dc.PopScissor(); } @@ -1384,7 +1368,6 @@ void TextEdit::FocusChanged(FocusFlags focusFlags) { void TextEdit::Draw(UIContext &dc) { Bounds textBounds = bounds_.Inset(padding_.left, padding_.top, padding_.right, padding_.bottom); - dc.SetFontStyle(dc.GetTheme().uiFont); // TODO: make background themeable? dc.FillRoundRect(HasFocus() ? UI::Drawable(0x80000000) : UI::Drawable(0x30000000), bounds_, dc.GetTheme().choiceRoundRadius * 0.5f); @@ -1406,10 +1389,10 @@ void TextEdit::Draw(UIContext &dc) { if (text_.empty()) { if (placeholderText_.size()) { uint32_t c = textColor & 0x50FFFFFF; - dc.DrawTextRect(placeholderText_, origTextBounds, c, ALIGN_CENTER); + dc.DrawTextRect(dc.GetTheme().uiFont, placeholderText_, origTextBounds, c, ALIGN_CENTER); } } else { - dc.DrawTextRect(textToDisplay, textBounds, textColor, ALIGN_VCENTER | ALIGN_LEFT | align_); + dc.DrawTextRect(dc.GetTheme().uiFont, textToDisplay, textBounds, textColor, ALIGN_VCENTER | ALIGN_LEFT | align_); } // Hack to find the caret position. Might want to find a better way... @@ -1660,8 +1643,7 @@ void ProgressBar::Draw(UIContext &dc) { done.w = std::max(bounds_.w * progress_, std::min(bounds_.w, radius * 2.0f)); dc.FillRoundRect(dc.GetTheme().itemFocusedStyle.background, done, radius, roundCorners_); } - dc.SetFontStyle(dc.GetTheme().uiFont); - dc.DrawTextRect(temp, bounds_, 0xFFFFFFFF, ALIGN_CENTER); + dc.DrawTextRect(dc.GetTheme().uiFont, temp, bounds_, 0xFFFFFFFF, ALIGN_CENTER); } std::string ProgressBar::DescribeText() const { @@ -1881,8 +1863,7 @@ void Slider::Draw(UIContext &dc) { snprintf(temp, sizeof(temp), "%d%%", *value_); else snprintf(temp, sizeof(temp), "%d", *value_); - dc.SetFontStyle(dc.GetTheme().uiFont); - dc.DrawText(temp, bounds_.x2() - 22, bounds_.centerY(), sliderColor, ALIGN_CENTER | FLAG_DYNAMIC_ASCII); + dc.DrawText(dc.GetTheme().uiFont, temp, bounds_.x2() - 22, bounds_.centerY(), sliderColor, ALIGN_CENTER | FLAG_DYNAMIC_ASCII); } std::string Slider::DescribeText() const { @@ -2038,8 +2019,7 @@ void SliderFloat::Draw(UIContext &dc) { dc.Draw()->DrawImage(dc.GetTheme().sliderKnob, knobX, bounds_.centerY(), 1.0f, sliderColor, ALIGN_CENTER); char temp[64]; snprintf(temp, sizeof(temp), "%0.2f", *value_); - dc.SetFontStyle(dc.GetTheme().uiFont); - dc.DrawText(temp, bounds_.x2() - 22, bounds_.centerY(), sliderColor, ALIGN_CENTER); + dc.DrawText(dc.GetTheme().uiFont, temp, bounds_.x2() - 22, bounds_.centerY(), sliderColor, ALIGN_CENTER); } std::string SliderFloat::DescribeText() const { diff --git a/Core/Util/PSARUnpack.cpp b/Core/Util/PSARUnpack.cpp index 2ff1ed082d..c4973c2cd0 100644 --- a/Core/Util/PSARUnpack.cpp +++ b/Core/Util/PSARUnpack.cpp @@ -1621,6 +1621,16 @@ std::string ReadMountedDiscUpdaterVersion() { return ReadUpdaterVersionFromArchiveHeader(); } +// Keeps Android's media scanner out of the firmware. +static void CreateNoMediaFile(const Path &dir) { +#if PPSSPP_PLATFORM(ANDROID) + const Path noMedia = dir / ".nomedia"; + if (!File::Exists(noMedia) && !File::CreateEmptyFile(noMedia)) { + WARN_LOG(Log::Loader, "Couldn't create %s", noMedia.c_str()); + } +#endif +} + bool UnpackUpdaterFromMountedDisc(const Path &outputDir, const PSARUnpackOptions &options, PSARUnpackStats *stats, std::string *error) { std::string localError; if (!error) { @@ -1633,10 +1643,7 @@ bool UnpackUpdaterFromMountedDisc(const Path &outputDir, const PSARUnpackOptions return false; } - // Write a nomedia file to avoid Android indexing the files. -#if PPSSPP_PLATFORM(ANDROID) - File::CreateEmptyFile(outputDir / ".nomedia"); -#endif + CreateNoMediaFile(outputDir); INFO_LOG(Log::Loader, "Found a %d byte updater on the mounted disc", (int)psar.size()); return UnpackPSAR(psar.data(), psar.size(), outputDir, options, stats, error); @@ -1750,6 +1757,9 @@ bool InstallFirmware(const Path &updater, const Path &nandRoot, const PSARUnpack ok = SwapStagingIntoPlace(nandRoot, staging, error); } if (ok) { + // Whichever way the firmware came, and also into a NAND that was set up without one. + CreateNoMediaFile(nandRoot); + // The shell refuses to install a theme without this directory, and the updater's archive // doesn't have it (6.61's has nothing under flash1), so the real updater must create it. const Path themeDir = nandRoot / "flash1/vsh/theme"; @@ -1786,11 +1796,7 @@ bool AutoInstallFirmwareFromDisc() { } const Path nandRoot = GetSysDirectory(DIRECTORY_NAND); - - // Write a nomedia file to avoid Android indexing the files. -#if PPSSPP_PLATFORM(ANDROID) - File::CreateEmptyFile(nandRoot / ".nomedia"); -#endif + CreateNoMediaFile(nandRoot); InstalledFirmwareInfo installed; ReadInstalledFirmwareInfo(nandRoot, &installed, false); diff --git a/GPU/Vulkan/DebugVisVulkan.cpp b/GPU/Vulkan/DebugVisVulkan.cpp index 989a031a96..f92c96cc03 100644 --- a/GPU/Vulkan/DebugVisVulkan.cpp +++ b/GPU/Vulkan/DebugVisVulkan.cpp @@ -42,7 +42,7 @@ bool comparePushBufferNames(const GPUMemoryManager *a, const GPUMemoryManager *b return strcmp(a->Name(), b->Name()) < 0; } -void DrawGPUMemoryVis(UIContext *ui, GPUCommon *gpu) { +void DrawGPUMemoryVis(UIContext *ui, const FontStyle &font, GPUCommon *gpu) { // This one will simply display stats. Draw::DrawContext *draw = ui->GetDrawContext(); @@ -88,12 +88,12 @@ void DrawGPUMemoryVis(UIContext *ui, GPUCommon *gpu) { int y = starty; ui->SetFontScale(0.7f, 0.7f); - ui->DrawTextShadow(str.str(), x, y, 0xFFFFFFFF, FLAG_DYNAMIC_ASCII); + ui->DrawTextShadow(font, str.str(), x, y, 0xFFFFFFFF, FLAG_DYNAMIC_ASCII); ui->SetFontScale(1.0f, 1.0f); ui->Flush(); } -void DrawGPUProfilerVis(UIContext *ui, GPUCommon *gpu) { +void DrawGPUProfilerVis(UIContext *ui, const FontStyle &font, GPUCommon *gpu) { using namespace Draw; const int padding = 10 + System_GetPropertyFloat(SYSPROP_DISPLAY_SAFE_INSET_LEFT); const int starty = 50 + System_GetPropertyFloat(SYSPROP_DISPLAY_SAFE_INSET_TOP); @@ -111,7 +111,7 @@ void DrawGPUProfilerVis(UIContext *ui, GPUCommon *gpu) { std::string text = ui->GetDrawContext()->GetGpuProfileString(); ui->SetFontScale(0.4f, 0.4f); - ui->DrawTextShadow(text, x, y, 0xFFFFFFFF, FLAG_DYNAMIC_ASCII); + ui->DrawTextShadow(font, text, x, y, 0xFFFFFFFF, FLAG_DYNAMIC_ASCII); ui->SetFontScale(1.0f, 1.0f); ui->Flush(); } diff --git a/GPU/Vulkan/DebugVisVulkan.h b/GPU/Vulkan/DebugVisVulkan.h index f86eb8aa51..6746a82b27 100644 --- a/GPU/Vulkan/DebugVisVulkan.h +++ b/GPU/Vulkan/DebugVisVulkan.h @@ -21,7 +21,9 @@ class GPUCommon; class UIContext; +struct FontStyle; // gpu MUST be an instance of GPU_Vulkan. If not, will definitely crash. -void DrawGPUMemoryVis(UIContext *ui, GPUCommon *gpu); -void DrawGPUProfilerVis(UIContext *ui, GPUCommon *gpu); +// Takes the font, since the UI headers that define the theme can't be included with the Vulkan ones (X11). +void DrawGPUMemoryVis(UIContext *ui, const FontStyle &font, GPUCommon *gpu); +void DrawGPUProfilerVis(UIContext *ui, const FontStyle &font, GPUCommon *gpu); diff --git a/UI/DebugOverlay.cpp b/UI/DebugOverlay.cpp index b67e030b2d..d7beceb2fa 100644 --- a/UI/DebugOverlay.cpp +++ b/UI/DebugOverlay.cpp @@ -292,12 +292,12 @@ void DrawDebugOverlay(UIContext *ctx, const Bounds &bounds, DebugOverlay overlay #if !PPSSPP_PLATFORM(UWP) && !PPSSPP_PLATFORM(SWITCH) case DebugOverlay::GPU_PROFILE: if (inGame && (g_Config.iGPUBackend == (int)GPUBackend::VULKAN || g_Config.iGPUBackend == (int)GPUBackend::OPENGL)) { - DrawGPUProfilerVis(ctx, gpu); + DrawGPUProfilerVis(ctx, ctx->GetTheme().uiFont, gpu); } break; case DebugOverlay::GPU_ALLOCATOR: if (inGame && (g_Config.iGPUBackend == (int)GPUBackend::VULKAN || g_Config.iGPUBackend == (int)GPUBackend::OPENGL)) { - DrawGPUMemoryVis(ctx, gpu); + DrawGPUMemoryVis(ctx, ctx->GetTheme().uiFont, gpu); } break; #endif diff --git a/UI/DevScreens.cpp b/UI/DevScreens.cpp index 7ca740db4c..90a0377514 100644 --- a/UI/DevScreens.cpp +++ b/UI/DevScreens.cpp @@ -861,7 +861,7 @@ void TouchTestScreen::DrawForeground(UIContext &dc) { if (touches_[i].id != -1) { dc.Draw()->Circle(touches_[i].x, touches_[i].y, 100.0, 3.0, 80, 0.0f, 0xFFFFFFFF, 1.0); snprintf(buffer, sizeof(buffer), "%0.1fx%0.1f", touches_[i].x, touches_[i].y); - dc.DrawText(buffer, touches_[i].x, touches_[i].y + (touches_[i].y > g_display.dp_yres - 100.0f ? -135.0f : 95.0f), 0xFFFFFFFF, ALIGN_HCENTER | FLAG_DYNAMIC_ASCII); + dc.DrawText(dc.GetTheme().uiFont, buffer, touches_[i].x, touches_[i].y + (touches_[i].y > g_display.dp_yres - 100.0f ? -135.0f : 95.0f), 0xFFFFFFFF, ALIGN_HCENTER | FLAG_DYNAMIC_ASCII); } } @@ -882,7 +882,7 @@ void TouchTestScreen::DrawForeground(UIContext &dc) { extra_debug); // On Android, also add joystick debug data. - dc.DrawTextShadow(buffer, bounds.centerX(), bounds.y + 20.0f, 0xFFFFFFFF, FLAG_DYNAMIC_ASCII); + dc.DrawTextShadow(dc.GetTheme().uiFont, buffer, bounds.centerX(), bounds.y + 20.0f, 0xFFFFFFFF, FLAG_DYNAMIC_ASCII); dc.Flush(); } @@ -1066,14 +1066,13 @@ void ColorTestView::Draw(UIContext &dc) { dc.Flush(); dc.Begin(); - dc.SetFontStyle(*GetTextStyle(dc, TextSize::Tiny)); + const FontStyle &tinyFont = *GetTextStyle(dc, TextSize::Tiny); for (const Label &label : labels) { - dc.DrawText(label.text, label.x, label.y, label.color, ALIGN_CENTER | FLAG_DYNAMIC_ASCII); + dc.DrawText(tinyFont, label.text, label.x, label.y, label.color, ALIGN_CENTER | FLAG_DYNAMIC_ASCII); } - dc.DrawText("Blurred, the lines match 188 if averaged in linear light, 128 if averaged as encoded", gammaX, y, 0xFFFFFFFF, ALIGN_TOPLEFT); + dc.DrawText(tinyFont, "Blurred, the lines match 188 if averaged in linear light, 128 if averaged as encoded", gammaX, y, 0xFFFFFFFF, ALIGN_TOPLEFT); const std::string header = StringFromFormat("%s%s, %dx%d pixels", dc.GetDrawContext()->GetInfoString(Draw::InfoField::APINAME).c_str(), IsVREnabled() ? ", VR" : "", g_display.pixel_xres, g_display.pixel_yres); - dc.SetFontStyle(*GetTextStyle(dc, TextSize::Small)); - dc.DrawText(header, bounds_.x + margin, bounds_.y + 4.0f, 0xFFFFFFFF, ALIGN_TOPLEFT); + dc.DrawText(*GetTextStyle(dc, TextSize::Small), header, bounds_.x + margin, bounds_.y + 4.0f, 0xFFFFFFFF, ALIGN_TOPLEFT); dc.Flush(); dc.Begin(); } diff --git a/UI/EmuScreen.cpp b/UI/EmuScreen.cpp index 4c1ab9c18b..075d1bdfd1 100644 --- a/UI/EmuScreen.cpp +++ b/UI/EmuScreen.cpp @@ -1619,7 +1619,7 @@ void EmuScreen::drawGameOnOutputMessage() { auto di = GetI18NCategory(I18NCat::DIALOG); const Bounds &bounds = dc.GetBounds(); dc.Begin(); - dc.DrawText(di->T("Playing on TV"), bounds.centerX(), bounds.centerY(), 0xFF505050, ALIGN_CENTER); + dc.DrawText(dc.GetTheme().uiFont, di->T("Playing on TV"), bounds.centerX(), bounds.centerY(), 0xFF505050, ALIGN_CENTER); dc.Flush(); } diff --git a/UI/GPUDriverTestScreen.cpp b/UI/GPUDriverTestScreen.cpp index 673d20becb..174cfbf43a 100644 --- a/UI/GPUDriverTestScreen.cpp +++ b/UI/GPUDriverTestScreen.cpp @@ -463,9 +463,9 @@ void GPUDriverTestScreen::DiscardTest(UIContext &dc) { std::string apiName = screenManager()->getDrawContext()->GetInfoString(InfoField::APINAME); std::string vendor = screenManager()->getDrawContext()->GetInfoString(InfoField::VENDORSTRING); std::string driver = screenManager()->getDrawContext()->GetInfoString(InfoField::DRIVER); - dc.DrawText(apiName, layoutBounds.centerX(), 20, 0xFFFFFFFF, ALIGN_CENTER); - dc.DrawText(vendor, layoutBounds.centerX(), 60, 0xFFFFFFFF, ALIGN_CENTER); - dc.DrawText(driver, layoutBounds.centerX(), 100, 0xFFFFFFFF, ALIGN_CENTER); + dc.DrawText(dc.GetTheme().uiFont, apiName, layoutBounds.centerX(), 20, 0xFFFFFFFF, ALIGN_CENTER); + dc.DrawText(dc.GetTheme().uiFont, vendor, layoutBounds.centerX(), 60, 0xFFFFFFFF, ALIGN_CENTER); + dc.DrawText(dc.GetTheme().uiFont, driver, layoutBounds.centerX(), 100, 0xFFFFFFFF, ALIGN_CENTER); dc.Flush(); float testW = 170.f; @@ -476,14 +476,14 @@ void GPUDriverTestScreen::DiscardTest(UIContext &dc) { for (int j = 0; j < numWriteModes; j++, y += 120.f + padding) { float x = layoutBounds.x + (layoutBounds.w - (float)numTests * testW - (float)(numTests - 1) * padding) / 2.0f; dc.Begin(); - dc.DrawText(writeModeNames[j], layoutBounds.x + padding, y + 40, 0xFFFFFFFF, FLAG_DYNAMIC_ASCII); + dc.DrawText(dc.GetTheme().uiFont, writeModeNames[j], layoutBounds.x + padding, y + 40, 0xFFFFFFFF, FLAG_DYNAMIC_ASCII); dc.Flush(); for (int i = 0; i < numTests; i++, x += testW + padding) { if (!validCombinations[j][i]) continue; dc.Begin(); Bounds bounds = { x, y + 40, testW, 70 }; - dc.DrawText(testNames[i], bounds.x, y, style.fgColor, FLAG_DYNAMIC_ASCII); + dc.DrawText(dc.GetTheme().uiFont, testNames[i], bounds.x, y, style.fgColor, FLAG_DYNAMIC_ASCII); dc.Flush(); dc.BeginPipeline(writePipelines[j], samplerNearest_); @@ -497,7 +497,7 @@ void GPUDriverTestScreen::DiscardTest(UIContext &dc) { draw->SetStencilParams(0xff, 0xFF, 0xFF); dc.SetCurZ(0.9f); - dc.DrawTextRect("TEST OK", bounds, textColorBAD, ALIGN_HCENTER | ALIGN_VCENTER | FLAG_DYNAMIC_ASCII); + dc.DrawTextRect(dc.GetTheme().uiFont, "TEST OK", bounds, textColorBAD, ALIGN_HCENTER | ALIGN_VCENTER | FLAG_DYNAMIC_ASCII); dc.Flush(); // Draw rectangle that should result in the text @@ -569,15 +569,15 @@ void GPUDriverTestScreen::ShaderTest(UIContext &dc) { std::string apiName = screenManager()->getDrawContext()->GetInfoString(InfoField::APINAME); std::string vendor = screenManager()->getDrawContext()->GetInfoString(InfoField::VENDORSTRING); std::string driver = screenManager()->getDrawContext()->GetInfoString(InfoField::DRIVER); - dc.DrawText(apiName, layoutBounds.centerX(), 20, 0xFFFFFFFF, ALIGN_CENTER); - dc.DrawText(vendor, layoutBounds.centerX(), 60, 0xFFFFFFFF, ALIGN_CENTER); - dc.DrawText(driver, layoutBounds.centerX(), 100, 0xFFFFFFFF, ALIGN_CENTER); + dc.DrawText(dc.GetTheme().uiFont, apiName, layoutBounds.centerX(), 20, 0xFFFFFFFF, ALIGN_CENTER); + dc.DrawText(dc.GetTheme().uiFont, vendor, layoutBounds.centerX(), 60, 0xFFFFFFFF, ALIGN_CENTER); + dc.DrawText(dc.GetTheme().uiFont, driver, layoutBounds.centerX(), 100, 0xFFFFFFFF, ALIGN_CENTER); dc.Flush(); float y = layoutBounds.y + 150; float x = layoutBounds.x + 10; dc.Begin(); - dc.DrawText("Adreno logic", x, y, 0xFFFFFFFF, FLAG_DYNAMIC_ASCII); + dc.DrawText(dc.GetTheme().uiFont, "Adreno logic", x, y, 0xFFFFFFFF, FLAG_DYNAMIC_ASCII); dc.Flush(); float testW = 170.f; @@ -591,14 +591,14 @@ void GPUDriverTestScreen::ShaderTest(UIContext &dc) { // Draw text on it using the shader. dc.BeginPipeline(adrenoLogicDiscardPipeline_, samplerNearest_); - dc.DrawTextRect("TEST OK", bounds, textColorOK, ALIGN_HCENTER | ALIGN_VCENTER | FLAG_DYNAMIC_ASCII); + dc.DrawTextRect(dc.GetTheme().uiFont, "TEST OK", bounds, textColorOK, ALIGN_HCENTER | ALIGN_VCENTER | FLAG_DYNAMIC_ASCII); dc.Flush(); y += 100; dc.Begin(); - dc.DrawText("Flat shaded tex", x, y, 0xFFFFFFFF, FLAG_DYNAMIC_ASCII); - dc.DrawText("(TEST OK if logo but no gradient!)", x + 400, y, 0xFFFFFFFF, ALIGN_LEFT); + dc.DrawText(dc.GetTheme().uiFont, "Flat shaded tex", x, y, 0xFFFFFFFF, FLAG_DYNAMIC_ASCII); + dc.DrawText(dc.GetTheme().uiFont, "(TEST OK if logo but no gradient!)", x + 400, y, 0xFFFFFFFF, ALIGN_LEFT); dc.Flush(); bounds = { x + 200, y, 100, 100 }; @@ -613,7 +613,7 @@ void GPUDriverTestScreen::ShaderTest(UIContext &dc) { y += 120; dc.Begin(); - dc.DrawText("Test done", x, y, 0xFFFFFFFF, FLAG_DYNAMIC_ASCII); + dc.DrawText(dc.GetTheme().uiFont, "Test done", x, y, 0xFFFFFFFF, FLAG_DYNAMIC_ASCII); dc.Flush(); } diff --git a/UI/GameButton.cpp b/UI/GameButton.cpp index 8a971b84e6..22c93305fc 100644 --- a/UI/GameButton.cpp +++ b/UI/GameButton.cpp @@ -279,8 +279,8 @@ void GameButton::Draw(UIContext &dc) { idStr = ga->T("SaveData"); } dc.SetFontScale(0.5f * g_Config.fGameGridScale, 0.5f * g_Config.fGameGridScale); - dc.DrawText(idStr, bounds_.x + 5, iconBounds.y + 1, 0xFF000000, ALIGN_TOPLEFT); - dc.DrawText(idStr, bounds_.x + 4, iconBounds.y, dc.GetTheme().infoStyle.fgColor, ALIGN_TOPLEFT); + dc.DrawText(dc.GetTheme().uiFont, idStr, bounds_.x + 5, iconBounds.y + 1, 0xFF000000, ALIGN_TOPLEFT); + dc.DrawText(dc.GetTheme().uiFont, idStr, bounds_.x + 4, iconBounds.y, dc.GetTheme().infoStyle.fgColor, ALIGN_TOPLEFT); dc.SetFontScale(1.0f, 1.0f); } @@ -288,10 +288,9 @@ void GameButton::Draw(UIContext &dc) { Bounds bounds = bounds_; float tw, th; - dc.MeasureText(dc.GetFontStyle(), g_Config.fGameGridScale, g_Config.fGameGridScale, text, &tw, &th, 0); + dc.MeasureText(dc.GetTheme().uiFont, g_Config.fGameGridScale, g_Config.fGameGridScale, text, &tw, &th, 0); dc.PushScissor(bounds); const FontStyle *fontStyle = GetTextStyle(dc, UI::TextSize::Small); - dc.SetFontStyle(*GetTextStyle(dc, UI::TextSize::Small)); int iconSize = imageIcon == ImageID("I_UP_DIRECTORY") ? (float)dc.Draw()->GetAtlas()->getImage(imageIcon)->h : bounds.h * 0.3f; float textWidth = 0.0f; @@ -309,15 +308,14 @@ void GameButton::Draw(UIContext &dc) { } if (imageIcon != ImageID("I_UP_DIRECTORY") && imageIcon != ImageID("I_PIN") && imageIcon != ImageID("I_UNPIN")) { - dc.DrawTextRect(text, bounds.Inset(5, y + iconSize + 4, 5, 2), style.fgColor, ALIGN_HCENTER | FLAG_WRAP_TEXT); + dc.DrawTextRect(*fontStyle, text, bounds.Inset(5, y + iconSize + 4, 5, 2), style.fgColor, ALIGN_HCENTER | FLAG_WRAP_TEXT); } dc.PopScissor(); - dc.SetFontStyle(dc.GetTheme().uiFont); } else if (!texture) { // Just draw the text, centered. dc.Draw()->Flush(); dc.PushScissor(bounds_); - dc.DrawText(title_, bounds_.x + 4, bounds_.centerY(), style.fgColor, ALIGN_VCENTER); + dc.DrawText(dc.GetTheme().uiFont, title_, bounds_.x + 4, bounds_.centerY(), style.fgColor, ALIGN_VCENTER); dc.Draw()->Flush(); dc.PopScissor(); } @@ -327,7 +325,7 @@ void GameButton::Draw(UIContext &dc) { std::string_view rightText = g_Config.bShowIDOnGameIcon ? std::string_view(id_version) : std::string_view(); float tw, th; - dc.MeasureText(dc.GetFontStyle(), 1.0f, 1.0f, text, &tw, &th, 0); + dc.MeasureText(dc.GetTheme().uiFont, 1.0f, 1.0f, text, &tw, &th, 0); if (imageIcon.isValid()) { // Dirs are fixed height. @@ -339,10 +337,10 @@ void GameButton::Draw(UIContext &dc) { int availableWidth = bounds.w - textX - LIST_TEXT_RIGHT_MARGIN; if (!rightText.empty()) { float vw, vh; - dc.MeasureText(dc.GetFontStyle(), 0.7f, 0.7f, rightText, &vw, &vh, 0); + dc.MeasureText(dc.GetTheme().uiFont, 0.7f, 0.7f, rightText, &vw, &vh, 0); availableWidth -= vw + 20; dc.SetFontScale(0.7f, 0.7f); - dc.DrawText(rightText, bounds.x + availableWidth + textX + 10, bounds.centerY(), style.fgColor, ALIGN_VCENTER); + dc.DrawText(dc.GetTheme().uiFont, rightText, bounds.x + availableWidth + textX + 10, bounds.centerY(), style.fgColor, ALIGN_VCENTER); dc.SetFontScale(1.0f, 1.0f); } float sineWidth = std::max(0.0f, (tw - availableWidth)) / 2.0f; @@ -353,7 +351,7 @@ void GameButton::Draw(UIContext &dc) { tb.w = availableWidth; dc.PushScissor(tb); } - dc.DrawText(text, bounds.x + tx, bounds.centerY(), style.fgColor, ALIGN_VCENTER | FLAG_WRAP_TEXT); + dc.DrawText(dc.GetTheme().uiFont, text, bounds.x + tx, bounds.centerY(), style.fgColor, ALIGN_VCENTER | FLAG_WRAP_TEXT); if (availableWidth < tw) { dc.PopScissor(); } @@ -421,10 +419,9 @@ void GameButton::Draw(UIContext &dc) { auto ga = GetI18NCategory(I18NCat::GAME); dc.FillRect(Drawable(0xD0505050), iconBounds); const float scale = 0.8f * (viewMode_ == GameBrowserViewMode::GRID ? g_Config.fGameGridScale : g_Config.fGameListScale); - dc.SetFontStyle(dc.GetTheme().uiFont); dc.SetFontScale(scale, scale); const std::string text = std::string(ga->T("Compressing...")) + StringFromFormat("\n%d%%", (int)(packStatus.progress * 100.0f)); - dc.DrawTextRectSqueeze(text, iconBounds, 0xFFFFFFFF, ALIGN_CENTER); + dc.DrawTextRectSqueeze(dc.GetTheme().uiFont, text, iconBounds, 0xFFFFFFFF, ALIGN_CENTER); dc.SetFontScale(1.0f, 1.0f); } diff --git a/UI/GamePacker.cpp b/UI/GamePacker.cpp index 0bcfe10eef..83623f8a9a 100644 --- a/UI/GamePacker.cpp +++ b/UI/GamePacker.cpp @@ -400,10 +400,9 @@ public: const float textX = bounds_.x + 60.0f; const float textW = bounds_.w - 70.0f; - dc.SetFontStyle(dc.GetTheme().uiFont); - dc.DrawTextRectSqueeze(title_, Bounds(textX, bounds_.y + 6.0f, textW, 32.0f), style.fgColor, ALIGN_VCENTER); + dc.DrawTextRectSqueeze(dc.GetTheme().uiFont, title_, Bounds(textX, bounds_.y + 6.0f, textW, 32.0f), style.fgColor, ALIGN_VCENTER); dc.SetFontScale(0.7f, 0.7f); - dc.DrawTextRectSqueeze(description_, Bounds(textX, bounds_.y + 36.0f, textW, 28.0f), alphaMul(style.fgColor, 0.75f), ALIGN_VCENTER); + dc.DrawTextRectSqueeze(dc.GetTheme().uiFont, description_, Bounds(textX, bounds_.y + 36.0f, textW, 28.0f), alphaMul(style.fgColor, 0.75f), ALIGN_VCENTER); dc.SetFontScale(1.0f, 1.0f); } diff --git a/UI/GameScreen.cpp b/UI/GameScreen.cpp index c4abce42de..c3015a6ca9 100644 --- a/UI/GameScreen.cpp +++ b/UI/GameScreen.cpp @@ -673,9 +673,8 @@ void GameScreen::DrawForeground(UIContext &dc) { std::string eta = seconds >= 3600 ? StringFromFormat("%d:%02d:%02d", seconds / 3600, (seconds / 60) % 60, seconds % 60) : StringFromFormat("%d:%02d", seconds / 60, seconds % 60); text += " " + ApplySafeSubstitutions(ga->T("PackTimeLeft", "~%1 left"), eta); } - dc.SetFontStyle(dc.GetTheme().uiFont); dc.SetFontScale(0.8f, 0.8f); - dc.DrawTextRectSqueeze(text, track.Inset(8.0f, 0.0f), 0xFFFFFFFF, ALIGN_CENTER); + dc.DrawTextRectSqueeze(dc.GetTheme().uiFont, text, track.Inset(8.0f, 0.0f), 0xFFFFFFFF, ALIGN_CENTER); dc.SetFontScale(1.0f, 1.0f); } diff --git a/UI/ImposeHome.cpp b/UI/ImposeHome.cpp index dfc99e7160..a4b593a9cb 100644 --- a/UI/ImposeHome.cpp +++ b/UI/ImposeHome.cpp @@ -783,7 +783,6 @@ void ImposeHomeScreen::Draw(UIContext &dc, const Bounds &screen) { // No firmware: the same screen with our font, at the firmware's positions (English layout). auto di = GetI18NCategory(I18NCat::DIALOG); const UI::Theme &theme = dc.GetTheme(); - dc.SetFontStyle(theme.uiFont); auto FitText = [&](std::string_view text, const Bounds &bounds, uint32_t color, int align) { // Scale the font to the bitmap's height, then squeeze if the translation is longer. float w, h; @@ -794,7 +793,7 @@ void ImposeHomeScreen::Draw(UIContext &dc, const Bounds &screen) { } dc.SetFontScale(scale, scale); const float x = (align & ALIGN_HCENTER) ? bounds.centerX() : bounds.x; - dc.DrawText(text, x, bounds.centerY(), color, (align & ALIGN_HCENTER) ? ALIGN_CENTER : (ALIGN_LEFT | ALIGN_VCENTER)); + dc.DrawText(theme.uiFont, text, x, bounds.centerY(), color, (align & ALIGN_HCENTER) ? ALIGN_CENTER : (ALIGN_LEFT | ALIGN_VCENTER)); }; // Status bar: the clock right-aligned at the top, the battery as its level in quarters. @@ -815,7 +814,7 @@ void ImposeHomeScreen::Draw(UIContext &dc, const Bounds &screen) { dc.MeasureText(theme.uiFont, 1.0f, 1.0f, clock, &w, &h); const float scale = h > 0.0f ? 15.0f * sy / h : 1.0f; dc.SetFontScale(scale, scale); - dc.DrawText(clock, screen.x + (clockRight - 6.0f) * sx, screen.y + 12.5f * sy, 0xFFFFFFFF, ALIGN_RIGHT | ALIGN_VCENTER); + dc.DrawText(theme.uiFont, clock, screen.x + (clockRight - 6.0f) * sx, screen.y + 12.5f * sy, 0xFFFFFFFF, ALIGN_RIGHT | ALIGN_VCENTER); } // The lines above and below the question. diff --git a/UI/JoystickHistoryView.cpp b/UI/JoystickHistoryView.cpp index 72f171a29b..82b98c0a13 100644 --- a/UI/JoystickHistoryView.cpp +++ b/UI/JoystickHistoryView.cpp @@ -19,7 +19,7 @@ void JoystickHistoryView::Draw(UIContext &dc) { dc.Flush(); dc.Begin(); Bounds textBounds(bounds_.x, bounds_.centerY() + minRadius + 5.0, bounds_.w, bounds_.h / 2 - minRadius - 5.0); - dc.DrawTextShadowRect(title_, textBounds, 0xFFFFFFFF, ALIGN_TOP | ALIGN_HCENTER | FLAG_WRAP_TEXT); + dc.DrawTextShadowRect(dc.GetTheme().uiFont, title_, textBounds, 0xFFFFFFFF, ALIGN_TOP | ALIGN_HCENTER | FLAG_WRAP_TEXT); dc.Flush(); dc.BeginNoTex(); dc.Draw()->RectOutline(bounds_.centerX() - minRadius, bounds_.centerY() - minRadius, minRadius * 2.0f, minRadius * 2.0f, 0x80FFFFFF); diff --git a/UI/MainScreen.cpp b/UI/MainScreen.cpp index 4f8247dfbb..6af1642838 100644 --- a/UI/MainScreen.cpp +++ b/UI/MainScreen.cpp @@ -330,12 +330,10 @@ public: const bool tiny = versionString.size() > 10; const FontStyle *style = GetTextStyle(dc, tiny ? TextSize::Tiny : TextSize::Small); - dc.SetFontStyle(*style); - dc.DrawText(versionString, + dc.DrawText(*style, versionString, bounds_.x + iconImg->w + 8, bounds_.y + logoImg->h + (tiny ? 8 : 6), dc.GetTheme().infoStyle.fgColor); - dc.SetFontStyle(dc.GetTheme().uiFont); } void GetContentDimensions(const UIContext &dc, float &w, float &h) const override { diff --git a/UI/MemStickScreen.cpp b/UI/MemStickScreen.cpp index 3c8fa46787..247402ffce 100644 --- a/UI/MemStickScreen.cpp +++ b/UI/MemStickScreen.cpp @@ -555,11 +555,10 @@ public: void Draw(UIContext &dc) override { const UI::Style &style = dc.GetTheme().itemStyle; dc.FillRoundRect(style.background, bounds_, dc.GetTheme().choiceRoundRadius, roundCorners_); - dc.SetFontStyle(dc.GetTheme().uiFont); if (minLines_ > 1) { - dc.DrawTextRect(text_, bounds_.Expand(-PADDING_X, -PADDING_Y), style.fgColor, FLAG_WRAP_TEXT); + dc.DrawTextRect(dc.GetTheme().uiFont, text_, bounds_.Expand(-PADDING_X, -PADDING_Y), style.fgColor, FLAG_WRAP_TEXT); } else { - dc.DrawTextRect(text_, bounds_.Expand(-PADDING_X, 0), style.fgColor, ALIGN_VCENTER | FLAG_WRAP_TEXT); + dc.DrawTextRect(dc.GetTheme().uiFont, text_, bounds_.Expand(-PADDING_X, 0), style.fgColor, ALIGN_VCENTER | FLAG_WRAP_TEXT); } } diff --git a/UI/MiscScreens.cpp b/UI/MiscScreens.cpp index cffe0042a0..829faf0d8d 100644 --- a/UI/MiscScreens.cpp +++ b/UI/MiscScreens.cpp @@ -116,7 +116,7 @@ bool BackgroundScreen::renderOutput(const OutputDisplay &output) { } const Bounds &bounds = dc.GetBounds(); dc.Begin(); - dc.DrawText(text, bounds.centerX(), bounds.centerY(), 0xFF505050, ALIGN_CENTER); + dc.DrawText(dc.GetTheme().uiFont, text, bounds.centerX(), bounds.centerY(), 0xFF505050, ALIGN_CENTER); dc.Flush(); return true; } @@ -509,11 +509,10 @@ void LogoScreen::DrawForeground(UIContext &dc) { dc.Draw()->DrawImage(ImageID("I_LOGO"), bounds.centerX() + 45, startY, 1.5f, 0xFFFFFFFF, ALIGN_CENTER); //dc.Draw()->DrawTextShadow(UBUNTU48, "PPSSPP", bounds.w / 2, bounds.h / 2 - 30, textColor, ALIGN_CENTER); dc.SetFontScale(1.0f, 1.0f); - dc.SetFontStyle(dc.GetTheme().uiFont); - dc.DrawText(temp, bounds.centerX(), startY + 70, textColor, ALIGN_CENTER); - dc.DrawText(cr->T_cstr("license", "Free Software under GPL 2.0+"), bounds.centerX(), startY + 110, textColor, ALIGN_CENTER); + dc.DrawText(dc.GetTheme().uiFont, temp, bounds.centerX(), startY + 70, textColor, ALIGN_CENTER); + dc.DrawText(dc.GetTheme().uiFont, cr->T_cstr("license", "Free Software under GPL 2.0+"), bounds.centerX(), startY + 110, textColor, ALIGN_CENTER); - dc.DrawText("www.ppsspp.org", bounds.centerX(), startY + 160, textColor, ALIGN_CENTER); + dc.DrawText(dc.GetTheme().uiFont, "www.ppsspp.org", bounds.centerX(), startY + 160, textColor, ALIGN_CENTER); #if !PPSSPP_PLATFORM(UWP) || defined(_DEBUG) // Draw the graphics API, except on UWP where it's always D3D11 @@ -523,7 +522,7 @@ void LogoScreen::DrawForeground(UIContext &dc) { // Add some emoji for testing. apiName += CodepointToUTF8(0x1F41B) + CodepointToUTF8(0x1F41C) + CodepointToUTF8(0x1F914); #endif - dc.DrawText(apiName, bounds.centerX(), startY + 200, textColor, ALIGN_CENTER); + dc.DrawText(dc.GetTheme().uiFont, apiName, bounds.centerX(), startY + 200, textColor, ALIGN_CENTER); #endif dc.Flush(); @@ -827,7 +826,7 @@ void CreditsScroller::Draw(UIContext &dc) { if (alpha > 0.0f) { dc.SetFontScale(ease(alpha), ease(alpha)); - dc.DrawText(credits[i], bounds.centerX(), y + bounds.y, textColor, ALIGN_HCENTER); + dc.DrawText(dc.GetTheme().uiFont, credits[i], bounds.centerX(), y + bounds.y, textColor, ALIGN_HCENTER); dc.SetFontScale(1.0f, 1.0f); } } diff --git a/UI/MiscViews.cpp b/UI/MiscViews.cpp index e91b4a2983..79eb57eb31 100644 --- a/UI/MiscViews.cpp +++ b/UI/MiscViews.cpp @@ -338,7 +338,7 @@ void SearchBar::Draw(UIContext &dc) { dc.Draw()->DrawImage(searchIcon, bounds_.x + leftMargin, bounds_.centerY(), 1.0f, 0xFFFFFFFF, ALIGN_VCENTER); leftMargin += image->w + 10; } - dc.DrawText(searchFilter_, bounds_.x + leftMargin, bounds_.centerY(), 0xFFFFFFFF, ALIGN_VCENTER); + dc.DrawText(dc.GetTheme().uiFont, searchFilter_, bounds_.x + leftMargin, bounds_.centerY(), 0xFFFFFFFF, ALIGN_VCENTER); } SearchBar::SearchBar(UI::LayoutParams *params) : UI::InertView(params) { diff --git a/UI/NativeApp.cpp b/UI/NativeApp.cpp index 628646b54c..0ef6df30b2 100644 --- a/UI/NativeApp.cpp +++ b/UI/NativeApp.cpp @@ -65,6 +65,7 @@ #include "Common/GPU/OpenGL/GLFeatures.h" #include "Common/GPU/thin3d.h" #include "Common/GPU/Vulkan/FixedSPIRVCache.h" +#include "Common/GPU/Vulkan/VulkanDriverVars.h" #include "Common/UI/UI.h" #include "Common/UI/Screen.h" #include "Common/UI/ScreenManager.h" @@ -506,12 +507,17 @@ static void CheckFailedGPUBackends() { return; #endif + // Only a custom driver is given up on, never the backend. + bool customDriverOnly = false; #if PPSSPP_PLATFORM(ANDROID) if (System_GetPropertyInt(SYSPROP_SYSTEMVERSION) >= 30) { - // In Android 11 or later, Vulkan is as stable as OpenGL, so let's not even bother. - // Have also seen unexplained issues with random fallbacks to OpenGL for no good reason, - // especially when debugging. - return; + // In Android 11 or later, Vulkan is as stable as OpenGL, so the only thing to check for is a custom + // driver that crashes. Have also seen unexplained issues with random fallbacks to OpenGL for no good + // reason, especially when debugging. + if (g_Config.iGPUBackend != (int)GPUBackend::VULKAN || g_Config.sCustomDriver.empty()) { + return; + } + customDriverOnly = true; } #endif @@ -538,8 +544,26 @@ static void CheckFailedGPUBackends() { ERROR_LOG(Log::Loader, "Failed graphics backends: %s", g_Config.sFailedGPUBackends.c_str()); } +#if PPSSPP_PLATFORM(ANDROID) + // A crash in Vulkan with a custom driver gets another try with the system's driver before leaving Vulkan. + std::vector failed; + SplitString(g_Config.sFailedGPUBackends, ',', failed); + if (g_Config.iGPUBackend == (int)GPUBackend::VULKAN && ContainsNoCase(failed, "VULKAN") && VulkanDisableCustomDriver()) { + RemoveNoCase(failed, "VULKAN"); + g_Config.sFailedGPUBackends.clear(); + for (const std::string &backend : failed) { + if (!g_Config.sFailedGPUBackends.empty()) { + g_Config.sFailedGPUBackends += ","; + } + g_Config.sFailedGPUBackends += backend; + } + } +#endif + // Okay, let's not try a backend in the failed list. - g_Config.iGPUBackend = g_Config.NextValidBackend(); + if (!customDriverOnly) { + g_Config.iGPUBackend = g_Config.NextValidBackend(); + } if (lastBackend != g_Config.iGPUBackend) { // This is the expected path. std::string param = GPUBackendToString((GPUBackend)lastBackend) + " -> " + GPUBackendToString((GPUBackend)g_Config.iGPUBackend); diff --git a/UI/OnScreenDisplay.cpp b/UI/OnScreenDisplay.cpp index 195d85c540..06e2ec1393 100644 --- a/UI/OnScreenDisplay.cpp +++ b/UI/OnScreenDisplay.cpp @@ -89,14 +89,13 @@ static void RenderOSDProgressBar(UIContext &dc, const OnScreenDisplay::Entry &en dc.FillRoundRect(background, bounds, radius); } - dc.SetFontStyle(dc.GetTheme().uiFont); dc.SetFontScale(1.0f, 1.0f); - dc.DrawTextShadowRect(entry.text, bounds, colorAlpha(0xFFFFFFFF, alpha), (align & FLAG_DYNAMIC_ASCII) | ALIGN_CENTER); + dc.DrawTextShadowRect(dc.GetTheme().uiFont, entry.text, bounds, colorAlpha(0xFFFFFFFF, alpha), (align & FLAG_DYNAMIC_ASCII) | ALIGN_CENTER); } static void MeasureLeaderboardTracker(UIContext &dc, const std::string &text, float *width, float *height) { - dc.MeasureText(dc.GetFontStyle(), 1.0f, 1.0f, text, width, height); + dc.MeasureText(dc.GetTheme().uiFont, 1.0f, 1.0f, text, width, height); *width += 16.0f; *height += 10.0f; } @@ -107,9 +106,8 @@ static void RenderLeaderboardTracker(UIContext &dc, const Bounds &bounds, const UI::Drawable background = UI::Drawable(backgroundColor); dc.DrawRectDropShadow(bounds, 12.0f, 0.7f * alpha); dc.FillRoundRect(background, bounds, dc.GetTheme().choiceRoundRadius * 0.75f); - dc.SetFontStyle(dc.GetTheme().uiFont); dc.SetFontScale(1.0f, 1.0f); - dc.DrawTextShadowRect(text, bounds.Inset(5.0f, 5.0f), colorAlpha(0xFFFFFFFF, alpha), ALIGN_VCENTER | ALIGN_HCENTER); + dc.DrawTextShadowRect(dc.GetTheme().uiFont, text, bounds.Inset(5.0f, 5.0f), colorAlpha(0xFFFFFFFF, alpha), ALIGN_VCENTER | ALIGN_HCENTER); } void OnScreenMessagesView::Draw(UIContext &dc) { @@ -170,7 +168,6 @@ void OnScreenMessagesView::Draw(UIContext &dc) { typeEdges[(size_t)OSDType::STATUS_ICON] = ScreenEdgePosition::TOP_LEFT; typeEdges[(size_t)OSDType::PROGRESS_BAR] = ScreenEdgePosition::TOP_CENTER; // These only function at the top currently, needs fixing. - dc.SetFontStyle(dc.GetTheme().uiFont); dc.SetFontScale(1.0f, 1.0f); // Indexed by the enum ScreenEdgePosition. diff --git a/UI/ProfilerDraw.cpp b/UI/ProfilerDraw.cpp index aa5727fefe..52efda7379 100644 --- a/UI/ProfilerDraw.cpp +++ b/UI/ProfilerDraw.cpp @@ -60,7 +60,6 @@ void DrawProfile(UIContext &ui) { int numThreads = Profiler_GetNumThreads(); int historyLength = Profiler_GetHistoryLength(); - ui.SetFontStyle(ui.theme->uiFont); static float lastMaxVal = 1.0f / 60.0f; float legendMinVal = lastMaxVal * (1.0f / 120.0f); @@ -92,7 +91,7 @@ void DrawProfile(UIContext &ui) { // So they don't move horizontally, we always measure. float w = 0.0f, h = 0.0f; - ui.MeasureText(ui.GetFontStyle(), 1.0f, 1.0f, name, &w, &h); + ui.MeasureText(ui.GetTheme().uiFont, 1.0f, 1.0f, name, &w, &h); if (w > legendWidth) { legendWidth = w; } @@ -117,7 +116,7 @@ void DrawProfile(UIContext &ui) { if (catStatus[i] == PROFILE_CAT_VISIBLE) { float y = legendStartY + legendNum++ * rowH; ui.FillRect(UI::Drawable(opacity | color), Bounds(legendStartX, y, rowH - 2, rowH - 2)); - ui.DrawTextShadow(name, legendStartX + rowH + 2, y, 0xFFFFFFFF, ALIGN_VBASELINE); + ui.DrawTextShadow(ui.GetTheme().uiFont, name, legendStartX + rowH + 2, y, 0xFFFFFFFF, ALIGN_VBASELINE); } } @@ -147,8 +146,8 @@ void DrawProfile(UIContext &ui) { ui.FillRect(UI::Drawable(0x80FFFF00), Bounds(0, y_60th, graphWidth, 2)); ui.FillRect(UI::Drawable(0x80FFFF00), Bounds(0, y_1ms, graphWidth, 2)); - ui.DrawTextShadow("1/60s", 5, y_60th, 0x80FFFF00); - ui.DrawTextShadow("1ms", 5, y_1ms, 0x80FFFF00); + ui.DrawTextShadow(ui.GetTheme().uiFont, "1/60s", 5, y_60th, 0x80FFFF00); + ui.DrawTextShadow(ui.GetTheme().uiFont, "1ms", 5, y_1ms, 0x80FFFF00); std::vector total; total.resize(historyLength); diff --git a/UI/RetroAchievementScreens.cpp b/UI/RetroAchievementScreens.cpp index e62d4ce446..7dadb108ea 100644 --- a/UI/RetroAchievementScreens.cpp +++ b/UI/RetroAchievementScreens.cpp @@ -607,7 +607,6 @@ void RenderAchievement(UIContext &dc, const rc_client_achievement_t *achievement dc.Flush(); dc.Begin(); - dc.SetFontStyle(*GetTextStyle(dc, UI::TextSize::Normal)); char temp[512]; @@ -636,31 +635,28 @@ void RenderAchievement(UIContext &dc, const rc_client_achievement_t *achievement break; } - dc.DrawTextRect(title, bounds.Inset(iconSpace + 12.0f, 2.0f, padding, padding), fgColor, ALIGN_TOPLEFT); + dc.DrawTextRect(*GetTextStyle(dc, UI::TextSize::Normal), title, bounds.Inset(iconSpace + 12.0f, 2.0f, padding, padding), fgColor, ALIGN_TOPLEFT); - dc.SetFontStyle(*GetTextStyle(dc, UI::TextSize::Small)); - dc.DrawTextRectSqueeze(DeNull(achievement->description), bounds.Inset(iconSpace + 12.0f, 39.0f, padding, padding), fgColor, ALIGN_TOPLEFT); + dc.DrawTextRectSqueeze(*GetTextStyle(dc, UI::TextSize::Small), DeNull(achievement->description), bounds.Inset(iconSpace + 12.0f, 39.0f, padding, padding), fgColor, ALIGN_TOPLEFT); - dc.DrawTextRect(badge, bounds, fgColor, ALIGN_TOPRIGHT); + dc.DrawTextRect(*GetTextStyle(dc, UI::TextSize::Small), badge, bounds, fgColor, ALIGN_TOPRIGHT); if (style == AchievementRenderStyle::LISTED && strlen(achievement->measured_progress) > 0) { - dc.SetFontStyle(*GetTextStyle(dc, UI::TextSize::Normal)); - dc.DrawTextRect(achievement->measured_progress, bounds.Inset(iconSpace + 12.0f, padding, padding + 100.0f, padding), fgColor, ALIGN_VCENTER | ALIGN_RIGHT); + dc.DrawTextRect(*GetTextStyle(dc, UI::TextSize::Normal), achievement->measured_progress, bounds.Inset(iconSpace + 12.0f, padding, padding + 100.0f, padding), fgColor, ALIGN_VCENTER | ALIGN_RIGHT); } // TODO: Draw measured_progress / measured_percent in a cute way snprintf(temp, sizeof(temp), "%d", achievement->points); // The points number to the right. - dc.SetFontStyle(*GetTextStyle(dc, UI::TextSize::Big)); - dc.DrawTextRect(temp, bounds.Expand(-5.0f, -5.0f), fgColor, ALIGN_RIGHT | (badge.empty() ? ALIGN_VCENTER : ALIGN_BOTTOMRIGHT)); + dc.DrawTextRect(*GetTextStyle(dc, UI::TextSize::Big), temp, bounds.Expand(-5.0f, -5.0f), fgColor, ALIGN_RIGHT | (badge.empty() ? ALIGN_VCENTER : ALIGN_BOTTOMRIGHT)); dc.Flush(); break; } case AchievementRenderStyle::PROGRESS_INDICATOR: // TODO: Also render a progress bar. - dc.DrawTextRect(achievement->measured_progress, bounds.Inset(iconSpace + padding * 2.0f, padding, padding, padding), fgColor, ALIGN_LEFT | ALIGN_VCENTER); + dc.DrawTextRect(*GetTextStyle(dc, UI::TextSize::Normal), achievement->measured_progress, bounds.Inset(iconSpace + padding * 2.0f, padding, padding, padding), fgColor, ALIGN_LEFT | ALIGN_VCENTER); // Show the unlocked icon. iconState = RC_CLIENT_ACHIEVEMENT_STATE_UNLOCKED; break; @@ -679,7 +675,6 @@ void RenderAchievement(UIContext &dc, const rc_client_achievement_t *achievement dc.Draw()->DrawTexRect(Bounds(bounds.x + padding, bounds.y + padding, iconSpace, iconSpace), 0.0f, 0.0f, 1.0f, 1.0f, whiteAlpha(alpha)); } } - dc.SetFontStyle(*GetTextStyle(dc, UI::TextSize::Normal)); dc.Flush(); dc.RebindTexture(); dc.PopScissor(); @@ -712,16 +707,13 @@ static void RenderGameAchievementSummary(UIContext &dc, const Bounds &bounds, fl dc.FillRect(background, bounds); dc.SetFontScale(1.0f, 1.0f); - dc.SetFontStyle(dc.GetTheme().uiFont); - dc.DrawTextRect(gameInfo->title, bounds.Inset(iconSpace + 5.0f, 2.0f, 5.0f, 5.0f), fgColor, ALIGN_TOPLEFT | FLAG_ELLIPSIZE_TEXT); + dc.DrawTextRect(dc.GetTheme().uiFont, gameInfo->title, bounds.Inset(iconSpace + 5.0f, 2.0f, 5.0f, 5.0f), fgColor, ALIGN_TOPLEFT | FLAG_ELLIPSIZE_TEXT); std::string description = Achievements::GetGameAchievementSummary(subsetId); - dc.SetFontStyle(dc.GetTheme().uiFontSmall); - dc.DrawTextRect(description, bounds.Inset(iconSpace + 5.0f, 38.0f, 5.0f, 5.0f), fgColor, ALIGN_TOPLEFT | FLAG_WRAP_TEXT); + dc.DrawTextRect(dc.GetTheme().uiFontSmall, description, bounds.Inset(iconSpace + 5.0f, 38.0f, 5.0f, 5.0f), fgColor, ALIGN_TOPLEFT | FLAG_WRAP_TEXT); - dc.SetFontStyle(dc.GetTheme().uiFont); dc.Flush(); if (gameInfo->badge_url && strlen(gameInfo->badge_url) > 0) { @@ -758,23 +750,20 @@ static void RenderLeaderboardSummary(UIContext &dc, const rc_client_leaderboard_ dc.FillRect(background, bounds); dc.SetFontScale(1.0f, 1.0f); - dc.SetFontStyle(dc.GetTheme().uiFont); - dc.DrawTextRect(DeNull(leaderboard->title), bounds.Inset(12.0f, 2.0f, 5.0f, 5.0f), fgColor, ALIGN_TOPLEFT); + dc.DrawTextRect(dc.GetTheme().uiFont, DeNull(leaderboard->title), bounds.Inset(12.0f, 2.0f, 5.0f, 5.0f), fgColor, ALIGN_TOPLEFT); - dc.SetFontStyle(dc.GetTheme().uiFontSmall); - dc.DrawTextRectSqueeze(DeNull(leaderboard->description), bounds.Inset(12.0f, 39.0f, 5.0f, 5.0f), fgColor, ALIGN_TOPLEFT); + dc.DrawTextRectSqueeze(dc.GetTheme().uiFontSmall, DeNull(leaderboard->description), bounds.Inset(12.0f, 39.0f, 5.0f, 5.0f), fgColor, ALIGN_TOPLEFT); /* char temp[64]; snprintf(temp, sizeof(temp), "%d", leaderboard.points); dc.SetFontScale(1.5f, 1.5f); - dc.DrawTextRect(temp, bounds.Expand(-5.0f, -5.0f), fgColor, ALIGN_RIGHT | ALIGN_VCENTER); + dc.DrawTextRect(dc.GetTheme().uiFontSmall, temp, bounds.Expand(-5.0f, -5.0f), fgColor, ALIGN_RIGHT | ALIGN_VCENTER); dc.Flush(); */ - dc.SetFontStyle(dc.GetTheme().uiFont); dc.Flush(); dc.RebindTexture(); @@ -809,17 +798,13 @@ static void RenderLeaderboardEntry(UIContext &dc, const rc_client_leaderboard_en dc.FillRect(background, bounds); dc.SetFontScale(1.0f, 1.0f); - dc.SetFontStyle(dc.GetTheme().uiFontBig); - dc.DrawTextRect(StringFromFormat("%d", entry->rank), Bounds(bounds.x + 4.0f, bounds.y + 4.0f, numberSpace - 10.0f, bounds.h - 4.0f * 2.0f), fgColor, ALIGN_TOPRIGHT); + dc.DrawTextRect(dc.GetTheme().uiFontBig, StringFromFormat("%d", entry->rank), Bounds(bounds.x + 4.0f, bounds.y + 4.0f, numberSpace - 10.0f, bounds.h - 4.0f * 2.0f), fgColor, ALIGN_TOPRIGHT); - dc.SetFontStyle(dc.GetTheme().uiFont); - dc.DrawTextRect(entry->user, bounds.Inset(iconSpace + 5.0f, 2.0f, 5.0f, 5.0f), fgColor, ALIGN_TOPLEFT); + dc.DrawTextRect(dc.GetTheme().uiFont, entry->user, bounds.Inset(iconSpace + 5.0f, 2.0f, 5.0f, 5.0f), fgColor, ALIGN_TOPLEFT); - dc.SetFontStyle(dc.GetTheme().uiFontSmall); - dc.DrawTextRect(DeNull(entry->display), bounds.Inset(iconSpace + 5.0f, 38.0f, 5.0f, 5.0f), fgColor, ALIGN_TOPLEFT); + dc.DrawTextRect(dc.GetTheme().uiFontSmall, DeNull(entry->display), bounds.Inset(iconSpace + 5.0f, 38.0f, 5.0f, 5.0f), fgColor, ALIGN_TOPLEFT); - dc.SetFontStyle(dc.GetTheme().uiFont); dc.Flush(); // Come up with a unique name for the icon entry. diff --git a/UI/SavedataScreen.cpp b/UI/SavedataScreen.cpp index 5bbab0cc07..2ece491bc5 100644 --- a/UI/SavedataScreen.cpp +++ b/UI/SavedataScreen.cpp @@ -374,14 +374,13 @@ void SavedataButton::Draw(UIContext &dc) { dc.Draw()->Flush(); dc.RebindTexture(); - dc.SetFontStyle(dc.GetTheme().uiFont); float tw, th; dc.Draw()->Flush(); dc.PushScissor(bounds_); UpdateText(ginfo); - dc.MeasureText(dc.GetFontStyle(), 1.0f, 1.0f, title_, &tw, &th, 0); + dc.MeasureText(dc.GetTheme().uiFont, 1.0f, 1.0f, title_, &tw, &th, 0); int availableWidth = bounds_.w - 150; float sineWidth = std::max(0.0f, (tw - availableWidth)) / 2.0f; @@ -395,9 +394,9 @@ void SavedataButton::Draw(UIContext &dc) { tb.w = std::max(1.0f, bounds_.w - 150.0f); dc.PushScissor(tb); } - dc.DrawText(title_, bounds_.x + tx, bounds_.y + 4, style.fgColor, ALIGN_TOPLEFT); + dc.DrawText(dc.GetTheme().uiFont, title_, bounds_.x + tx, bounds_.y + 4, style.fgColor, ALIGN_TOPLEFT); dc.SetFontScale(0.6f, 0.6f); - dc.DrawText(subtitle_, bounds_.x + tx, bounds_.y2() - 7, style.fgColor, ALIGN_BOTTOM); + dc.DrawText(dc.GetTheme().uiFont, subtitle_, bounds_.x + tx, bounds_.y2() - 7, style.fgColor, ALIGN_BOTTOM); dc.SetFontScale(1.0f, 1.0f); if (availableWidth < tw) { diff --git a/android/jni/app-android.cpp b/android/jni/app-android.cpp index c05fa5ffb6..cd646f9f1e 100644 --- a/android/jni/app-android.cpp +++ b/android/jni/app-android.cpp @@ -61,6 +61,7 @@ struct JNIEnv {}; #define JNI_VERSION_1_6 16 #endif +#include "Common/Data/Text/I18n.h" #include "Common/Log.h" #include "Common/LogReporting.h" @@ -839,10 +840,15 @@ retry: GraphicsContext *ctx = new VulkanGraphicsContext(); std::string errorMessage; if (!ctx->InitAPI(nullptr, &g_Config.sVulkanDevice, &errorMessage)) { + delete ctx; + // Only fall back to OpenGL when the system's driver doesn't work either. + if (VulkanDisableCustomDriver()) { + ERROR_LOG(Log::System, "Failed to initialize Vulkan with a custom driver, retrying with the system's: %s", errorMessage.c_str()); + goto retry; + } ERROR_LOG(Log::System, "Failed to initialize Vulkan, switching to OpenGL: %s", errorMessage.c_str()); g_Config.iGPUBackend = (int)GPUBackend::OPENGL; SetGPUBackend(GPUBackend::OPENGL); - delete ctx; goto retry; } ((VulkanContext *)ctx->GetAPIContext())->SetCbGetDrawSize([]() { @@ -858,6 +864,14 @@ retry: g_Config.iGPUBackend = (int)GPUBackend::OPENGL; goto retry; } + + // Here rather than where the driver failed, which can be before the translations are loaded. + const std::string failedDriver = VulkanTakeFailedCustomDriver(); + if (!failedDriver.empty()) { + auto gr = GetI18NCategory(I18NCat::GRAPHICS); + g_OSD.Show(OSDType::MESSAGE_ERROR, gr->T("The custom Vulkan driver failed to load. Switching back to default."), failedDriver, 10.0f); + g_Config.Save("CustomDriverFailed"); + } } extern "C" void Java_org_ppsspp_ppsspp_NativeApp_setAchievementsHostOverride(JNIEnv *env, jclass, jstring jhost) { diff --git a/assets/compat.ini b/assets/compat.ini index 3a4a6f3022..2a016625e9 100644 --- a/assets/compat.ini +++ b/assets/compat.ini @@ -1316,6 +1316,13 @@ WEBF00752 = true ULUS10202 = true ULES00645 = true +# Gitaroo Man (title screen circles) +ULES00383 = true +ULKS41071 = true +ULUS10207 = true +ULJM05130 = true +NPJH50035 = true + [ZZT3SelectHack] # Bypass softlock on Zettai Zetsumei Toshi 3 character select screen #4901 # This problem affects the game also on PS3 diff --git a/assets/lang/ar_AE.ini b/assets/lang/ar_AE.ini index 4f58256078..7996038b9f 100644 --- a/assets/lang/ar_AE.ini +++ b/assets/lang/ar_AE.ini @@ -920,6 +920,7 @@ Texture Filtering = مفلتر الرسوم Texture replacement pack activated = تم تفعيل حزمة استبدال الرسوم # AI translated Texture upscaling = تكبير الرسوم The chosen ZIP file doesn't contain a valid driver = ملف ZIP المختار لا يحتوي على تعريف صالح # AI translated +The custom Vulkan driver failed to load. Switching back to default. = تعذّر تحميل برنامج تشغيل Vulkan المخصص. جارٍ الرجوع إلى الافتراضي. # AI translated Unlimited = لا محدود Up to 1 = حتى 1 # AI translated Up to 2 = حتى 2 # AI translated diff --git a/assets/lang/az_AZ.ini b/assets/lang/az_AZ.ini index bb44e6ab65..ac21aeb0c0 100644 --- a/assets/lang/az_AZ.ini +++ b/assets/lang/az_AZ.ini @@ -912,6 +912,7 @@ Texture Filtering = Toxuma süzgüsü Texture replacement pack activated = Toxuma yerdəyişməsi bağlaması işə salınıb Texture upscaling = Toxuma ölçəklənişi The chosen ZIP file doesn't contain a valid driver = Seçilmiş ZIP fayl keçərli sürücü daşımır +The custom Vulkan driver failed to load. Switching back to default. = Fərdi Vulkan drayveri yüklənmədi. Standart drayverə qayıdılır. # AI translated Unlimited = Sınırsız Up to 1 = 1'ə qədər Up to 2 = 2'yə qədər diff --git a/assets/lang/be_BY.ini b/assets/lang/be_BY.ini index 0c22324e78..44b011463e 100644 --- a/assets/lang/be_BY.ini +++ b/assets/lang/be_BY.ini @@ -912,6 +912,7 @@ Texture Filtering = Фільтраванне тэкстур Texture replacement pack activated = Пакет замены тэкстур актываваны # AI translated Texture upscaling = Маштабаванне тэкстур The chosen ZIP file doesn't contain a valid driver = Выбраны ZIP-файл не змяшчае прыдатнага драйвера # AI translated +The custom Vulkan driver failed to load. Switching back to default. = Не ўдалося загрузіць карыстальніцкі драйвер Vulkan. Вяртаемся да стандартнага. # AI translated Unlimited = Неабмежаваны Up to 1 = Да 1 Up to 2 = Да 2 diff --git a/assets/lang/bg_BG.ini b/assets/lang/bg_BG.ini index 237076d0c8..b72abe744c 100644 --- a/assets/lang/bg_BG.ini +++ b/assets/lang/bg_BG.ini @@ -912,6 +912,7 @@ Texture Filtering = Текстурно филтриране Texture replacement pack activated = Пакетът за замяна на текстури е включен # AI translated Texture upscaling = Текстурно мащабиране The chosen ZIP file doesn't contain a valid driver = Избраният ZIP файл не съдържа валиден драйвер +The custom Vulkan driver failed to load. Switching back to default. = Персонализираният драйвер за Vulkan не можа да се зареди. Връщане към стандартния. # AI translated Unlimited = Няма ограничения Up to 1 = До 1 Up to 2 = До 2 diff --git a/assets/lang/ca_ES.ini b/assets/lang/ca_ES.ini index 9f9018b532..715482fb63 100644 --- a/assets/lang/ca_ES.ini +++ b/assets/lang/ca_ES.ini @@ -912,6 +912,7 @@ Texture Filtering = Filtrat de textures Texture replacement pack activated = Paquet de reemplaçament de textures activat # AI translated Texture upscaling = Escalat de textures The chosen ZIP file doesn't contain a valid driver = El fitxer ZIP triat no conté cap controlador vàlid # AI translated +The custom Vulkan driver failed to load. Switching back to default. = No s'ha pogut carregar el controlador Vulkan personalitzat. Es torna al predeterminat. # AI translated Unlimited = Il·limitat Up to 1 = Fins a 1 Up to 2 = Fins a 2 diff --git a/assets/lang/cz_CZ.ini b/assets/lang/cz_CZ.ini index fd70ffba04..2f43f5674c 100644 --- a/assets/lang/cz_CZ.ini +++ b/assets/lang/cz_CZ.ini @@ -912,6 +912,7 @@ Texture Filtering = Filtrování textur Texture replacement pack activated = Balíček náhradních textur aktivován # AI translated Texture upscaling = Zvětšení textur # AI translated The chosen ZIP file doesn't contain a valid driver = Zvolený soubor ZIP neobsahuje platný ovladač # AI translated +The custom Vulkan driver failed to load. Switching back to default. = Vlastní ovladač Vulkan se nepodařilo načíst. Přepínám zpět na výchozí. # AI translated Unlimited = Neomezené Up to 1 = Až 1 # AI translated Up to 2 = Až 2 # AI translated diff --git a/assets/lang/da_DK.ini b/assets/lang/da_DK.ini index edf90e26ee..d0a9e04c94 100644 --- a/assets/lang/da_DK.ini +++ b/assets/lang/da_DK.ini @@ -912,6 +912,7 @@ Texture Filtering = Texturefiltrering # AI translated Texture replacement pack activated = Pakke med erstatningstextures aktiveret # AI translated Texture upscaling = Texture-opskalering # AI translated The chosen ZIP file doesn't contain a valid driver = Den valgte ZIP-fil indeholder ikke en gyldig driver # AI translated +The custom Vulkan driver failed to load. Switching back to default. = Den brugerdefinerede Vulkan-driver kunne ikke indlæses. Skifter tilbage til standard. # AI translated Unlimited = Ubegrænset Up to 1 = Op til 1 # AI translated Up to 2 = Op til 2 # AI translated diff --git a/assets/lang/de_DE.ini b/assets/lang/de_DE.ini index 7063dc19c4..85080919a8 100644 --- a/assets/lang/de_DE.ini +++ b/assets/lang/de_DE.ini @@ -911,6 +911,7 @@ Texture Filtering = Texturfilterung Texture replacement pack activated = Textur-Ersatzpaket aktiviert Texture upscaling = Texturskalierung The chosen ZIP file doesn't contain a valid driver = Die gewählte ZIP-Datei enthält keinen gültigen Treiber +The custom Vulkan driver failed to load. Switching back to default. = Der benutzerdefinierte Vulkan-Treiber konnte nicht geladen werden. Es wird wieder der Standardtreiber verwendet. # AI translated Unlimited = Unbegrenzt Up to 1 = Bis zu 1 Up to 2 = Bis zu 2 diff --git a/assets/lang/dr_ID.ini b/assets/lang/dr_ID.ini index aa81f7d593..93d4069f62 100644 --- a/assets/lang/dr_ID.ini +++ b/assets/lang/dr_ID.ini @@ -912,6 +912,7 @@ Texture Filtering = Saring i Texture Texture replacement pack activated = Texture replacement pack activated Texture upscaling = Petonggoi Texture The chosen ZIP file doesn't contain a valid driver = The chosen ZIP file doesn't contain a valid driver +The custom Vulkan driver failed to load. Switching back to default. = The custom Vulkan driver failed to load. Switching back to default. Unlimited = Unlimited Up to 1 = Up to 1 Up to 2 = Up to 2 diff --git a/assets/lang/en_US.ini b/assets/lang/en_US.ini index 3ce06d1a89..88fb41c31d 100644 --- a/assets/lang/en_US.ini +++ b/assets/lang/en_US.ini @@ -936,6 +936,7 @@ Texture Filtering = Texture filtering Texture replacement pack activated = Texture replacement pack activated Texture upscaling = Texture upscaling The chosen ZIP file doesn't contain a valid driver = The chosen ZIP file doesn't contain a valid driver +The custom Vulkan driver failed to load. Switching back to default. = The custom Vulkan driver failed to load. Switching back to default. Unlimited = Unlimited Up to 1 = Up to 1 Up to 2 = Up to 2 diff --git a/assets/lang/es_ES.ini b/assets/lang/es_ES.ini index 5100ad2cc8..deaff51758 100644 --- a/assets/lang/es_ES.ini +++ b/assets/lang/es_ES.ini @@ -913,6 +913,7 @@ Texture Filtering = Filtrado de texturas Texture replacement pack activated = Paquete de reemplazo de textura activado Texture upscaling = Escalado de texturas The chosen ZIP file doesn't contain a valid driver = El archivo ZIP seleccionado no contiene un controlador válido +The custom Vulkan driver failed to load. Switching back to default. = No se ha podido cargar el controlador Vulkan personalizado. Se vuelve al predeterminado. # AI translated Unlimited = Ilimitado Up to 1 = Hasta 1 Up to 2 = Hasta 2 diff --git a/assets/lang/es_LA.ini b/assets/lang/es_LA.ini index 76b9390fce..41987fcbe7 100644 --- a/assets/lang/es_LA.ini +++ b/assets/lang/es_LA.ini @@ -912,6 +912,7 @@ Texture Filtering = Filtrado de texturas Texture replacement pack activated = Paquete de reemplazo de texturas activado # AI translated Texture upscaling = Escalado de texturas The chosen ZIP file doesn't contain a valid driver = El archivo ZIP elegido no contiene un controlador válido # AI translated +The custom Vulkan driver failed to load. Switching back to default. = No se pudo cargar el controlador Vulkan personalizado. Se regresa al predeterminado. # AI translated Unlimited = Ilimitado Up to 1 = Hasta 1 Up to 2 = Hasta 2 diff --git a/assets/lang/fa_IR.ini b/assets/lang/fa_IR.ini index d88cdb837f..764fc4f476 100644 --- a/assets/lang/fa_IR.ini +++ b/assets/lang/fa_IR.ini @@ -912,6 +912,7 @@ Texture Filtering = فیلتر کردن بافت Texture replacement pack activated = بستهٔ جایگزینی بافت فعال شد # AI translated Texture upscaling = افزایش سایز بافت‌ها # AI translated The chosen ZIP file doesn't contain a valid driver = فایل ZIP انتخاب‌شده درایور معتبری ندارد # AI translated +The custom Vulkan driver failed to load. Switching back to default. = درایور سفارشی Vulkan بارگذاری نشد. بازگشت به درایور پیش‌فرض. # AI translated Unlimited = نامحدود Up to 1 = حداکثر ۱ # AI translated Up to 2 = حداکثر ۲ # AI translated diff --git a/assets/lang/fi_FI.ini b/assets/lang/fi_FI.ini index 38e1cb6f07..81395493a1 100644 --- a/assets/lang/fi_FI.ini +++ b/assets/lang/fi_FI.ini @@ -912,6 +912,7 @@ Texture Filtering = Tekstuurin suodatus Texture replacement pack activated = Tekstuurin korvauspaketti aktivoitu # AI translated Texture upscaling = Tekstuurin skaalaus The chosen ZIP file doesn't contain a valid driver = Valittu ZIP-tiedosto ei sisällä kelvollista ajuria # AI translated +The custom Vulkan driver failed to load. Switching back to default. = Mukautetun Vulkan-ajurin lataaminen epäonnistui. Palataan oletukseen. # AI translated Unlimited = Rajoittamaton Up to 1 = Enintään 1 Up to 2 = Enintään 2 diff --git a/assets/lang/fr_FR.ini b/assets/lang/fr_FR.ini index 41b04a25eb..0be68e3cf7 100644 --- a/assets/lang/fr_FR.ini +++ b/assets/lang/fr_FR.ini @@ -936,6 +936,7 @@ Texture Filtering = Filtrage des textures Texture replacement pack activated = Pack de remplacement de textures activé # AI translated Texture upscaling = Mise à l'échelle des textures The chosen ZIP file doesn't contain a valid driver = Le fichier ZIP sélectionné ne contient pas de pilote valide +The custom Vulkan driver failed to load. Switching back to default. = Le pilote Vulkan personnalisé n'a pas pu être chargé. Retour au pilote par défaut. # AI translated Unlimited = Illimité Up to 1 = Max 1 Up to 2 = Max 2 diff --git a/assets/lang/gl_ES.ini b/assets/lang/gl_ES.ini index 85404853a6..c0f399f775 100644 --- a/assets/lang/gl_ES.ini +++ b/assets/lang/gl_ES.ini @@ -912,6 +912,7 @@ Texture Filtering = Filtrado de texturas Texture replacement pack activated = Paquete de substitución de texturas activado # AI translated Texture upscaling = Escalado de texturas The chosen ZIP file doesn't contain a valid driver = O ficheiro ZIP escollido non contén un controlador válido # AI translated +The custom Vulkan driver failed to load. Switching back to default. = Non se puido cargar o controlador Vulkan personalizado. Vólvese ao predeterminado. # AI translated Unlimited = Ilimitado # AI translated Up to 1 = Ata 1 # AI translated Up to 2 = Ata 2 # AI translated diff --git a/assets/lang/gr_EL.ini b/assets/lang/gr_EL.ini index 9bd57a7ccb..d2670a0f2e 100644 --- a/assets/lang/gr_EL.ini +++ b/assets/lang/gr_EL.ini @@ -912,6 +912,7 @@ Texture Filtering = Φιλτράρισμα Υφών Texture replacement pack activated = Το πακέτο αντικατάστασης υφών ενεργοποιήθηκε # AI translated Texture upscaling = Κλιμάκωση Υφών The chosen ZIP file doesn't contain a valid driver = Το επιλεγμένο αρχείο ZIP δεν περιέχει έγκυρο οδηγό # AI translated +The custom Vulkan driver failed to load. Switching back to default. = Δεν ήταν δυνατή η φόρτωση του προσαρμοσμένου προγράμματος οδήγησης Vulkan. Γίνεται επιστροφή στο προεπιλεγμένο. # AI translated Unlimited = Απεριόριστο Up to 1 = Έως 1 # AI translated Up to 2 = Έως 2 # AI translated diff --git a/assets/lang/he_IL.ini b/assets/lang/he_IL.ini index ac93a6d1d0..4441f8f53c 100644 --- a/assets/lang/he_IL.ini +++ b/assets/lang/he_IL.ini @@ -912,6 +912,7 @@ Texture Filtering = סינון טקסטורות # AI translated Texture replacement pack activated = חבילת החלפת טקסטורות הופעלה # AI translated Texture upscaling = הגדלת טקסטורות # AI translated The chosen ZIP file doesn't contain a valid driver = קובץ ה-ZIP שנבחר אינו מכיל מנהל התקן תקין # AI translated +The custom Vulkan driver failed to load. Switching back to default. = טעינת מנהל ההתקן המותאם אישית של Vulkan נכשלה. חוזרים לברירת המחדל. # AI translated Unlimited = ללא הגבלה # AI translated Up to 1 = עד 1 # AI translated Up to 2 = עד 2 # AI translated diff --git a/assets/lang/hr_HR.ini b/assets/lang/hr_HR.ini index 8ac969dd09..ee514d36c2 100644 --- a/assets/lang/hr_HR.ini +++ b/assets/lang/hr_HR.ini @@ -912,6 +912,7 @@ Texture Filtering = Filtriranje tekstura Texture replacement pack activated = Paket zamjenskih tekstura aktiviran # AI translated Texture upscaling = Povećanje tekstura # AI translated The chosen ZIP file doesn't contain a valid driver = Odabrana ZIP datoteka ne sadrži ispravan driver # AI translated +The custom Vulkan driver failed to load. Switching back to default. = Prilagođeni Vulkan upravljački program nije se uspio učitati. Vraćanje na zadani. # AI translated Unlimited = Neograničeno Up to 1 = Do 1 # AI translated Up to 2 = Do 2 # AI translated diff --git a/assets/lang/hu_HU.ini b/assets/lang/hu_HU.ini index 8a72cfad67..7b4589860a 100644 --- a/assets/lang/hu_HU.ini +++ b/assets/lang/hu_HU.ini @@ -912,6 +912,7 @@ Texture Filtering = Textúra szűrés Texture replacement pack activated = Textúracsere-csomag aktiválva # AI translated Texture upscaling = Textúra felskálázás The chosen ZIP file doesn't contain a valid driver = A kiválasztott ZIP fájl nem tartalmaz érvényes drivert # AI translated +The custom Vulkan driver failed to load. Switching back to default. = Az egyéni Vulkan-illesztőprogramot nem sikerült betölteni. Visszaváltás az alapértelmezettre. # AI translated Unlimited = Korlátlan Up to 1 = Legfeljebb 1 Up to 2 = Legfeljebb 2 diff --git a/assets/lang/id_ID.ini b/assets/lang/id_ID.ini index f2b65d4747..f390dad47f 100644 --- a/assets/lang/id_ID.ini +++ b/assets/lang/id_ID.ini @@ -912,6 +912,7 @@ Texture Filtering = Pemfilteran tekstur Texture replacement pack activated = Paket penggantian tekstur diaktifkan Texture upscaling = Penskala tekstur The chosen ZIP file doesn't contain a valid driver = File ZIP yang dipilih tidak berisi driver yang valid +The custom Vulkan driver failed to load. Switching back to default. = Driver Vulkan kustom gagal dimuat. Beralih kembali ke bawaan. # AI translated Unlimited = Tak terbatas Up to 1 = Hingga 1 Up to 2 = Hingga 2 diff --git a/assets/lang/it_IT.ini b/assets/lang/it_IT.ini index 47d8b22fb8..f90d5922ac 100644 --- a/assets/lang/it_IT.ini +++ b/assets/lang/it_IT.ini @@ -913,6 +913,7 @@ Texture Filtering = Filtraggio delle texture Texture replacement pack activated = Pacchetto di sostituzione delle texture attivato Texture upscaling = Scalatura delle texture The chosen ZIP file doesn't contain a valid driver = Il file ZIP scelto non contiene un driver valido +The custom Vulkan driver failed to load. Switching back to default. = Impossibile caricare il driver Vulkan personalizzato. Si torna a quello predefinito. # AI translated Unlimited = Illimitato Up to 1 = Max 1 Up to 2 = Max 2 diff --git a/assets/lang/ja_JP.ini b/assets/lang/ja_JP.ini index 82f3ca9f2c..af60342ce8 100644 --- a/assets/lang/ja_JP.ini +++ b/assets/lang/ja_JP.ini @@ -912,6 +912,7 @@ Texture Filtering = テクスチャフィルタリング Texture replacement pack activated = テクスチャ置換パックが有効化されました Texture upscaling = テクスチャスケーリング The chosen ZIP file doesn't contain a valid driver = 選択されたZIPファイルには有効なドライバが含まれていません +The custom Vulkan driver failed to load. Switching back to default. = カスタムVulkanドライバーを読み込めませんでした。デフォルトに戻します。 # AI translated Unlimited = 無制限 Up to 1 = 最大1 Up to 2 = 最大2 diff --git a/assets/lang/jv_ID.ini b/assets/lang/jv_ID.ini index fd03f903b4..a01a35736b 100644 --- a/assets/lang/jv_ID.ini +++ b/assets/lang/jv_ID.ini @@ -912,6 +912,7 @@ Texture Filtering = Penyaring Tekstur Texture replacement pack activated = Texture replacement pack activated Texture upscaling = Skala Tekstur The chosen ZIP file doesn't contain a valid driver = The chosen ZIP file doesn't contain a valid driver +The custom Vulkan driver failed to load. Switching back to default. = The custom Vulkan driver failed to load. Switching back to default. Unlimited = Ora Ana Watesan Up to 1 = Up to 1 Up to 2 = Up to 2 diff --git a/assets/lang/km_KH.ini b/assets/lang/km_KH.ini index 4cd26993d0..4dcec79088 100644 --- a/assets/lang/km_KH.ini +++ b/assets/lang/km_KH.ini @@ -912,6 +912,7 @@ Texture Filtering =តម្រងវាយនភាព Texture replacement pack activated =កញ្ចប់ជំនួសវាយនភាពត្រូវបានធ្វើឱ្យសកម្ម Texture upscaling =ការបង្កើនទំហំផ្ទៃ The chosen ZIP file doesn't contain a valid driver =ឯកសារ ZIP ដែលបានជ្រើសរើសមិនមានកម្មវិធីបញ្ជាត្រឹមត្រូវទេ។ +The custom Vulkan driver failed to load. Switching back to default. = The custom Vulkan driver failed to load. Switching back to default. Unlimited =គ្មានដែនកំណត់ Up to 1 =រហូតដល់ 1 Up to 2 =រហូតដល់ 2 diff --git a/assets/lang/ko_KR.ini b/assets/lang/ko_KR.ini index a069e4629f..d5f5cfa0b9 100644 --- a/assets/lang/ko_KR.ini +++ b/assets/lang/ko_KR.ini @@ -912,6 +912,7 @@ Texture Filtering = 텍스처 필터링 Texture replacement pack activated = 텍스처 교체 팩 활성화 Texture upscaling = 텍스처 스케일링 The chosen ZIP file doesn't contain a valid driver = 선택한 ZIP 파일에는 유효한 드라이버가 포함되어 있지 않습니다. +The custom Vulkan driver failed to load. Switching back to default. = 사용자 지정 Vulkan 드라이버를 불러오지 못했습니다. 기본 드라이버로 되돌립니다. # AI translated Unlimited = 무제한 Up to 1 = 최대 1까지 Up to 2 = 최대 2까지 diff --git a/assets/lang/ku_SO.ini b/assets/lang/ku_SO.ini index f4e82d6fd1..bc0f6727bc 100644 --- a/assets/lang/ku_SO.ini +++ b/assets/lang/ku_SO.ini @@ -926,6 +926,7 @@ Texture Filtering = Texture filtering Texture replacement pack activated = Texture replacement pack activated Texture upscaling = Texture upscaling The chosen ZIP file doesn't contain a valid driver = The chosen ZIP file doesn't contain a valid driver +The custom Vulkan driver failed to load. Switching back to default. = The custom Vulkan driver failed to load. Switching back to default. Unlimited = Unlimited Up to 1 = Up to 1 Up to 2 = Up to 2 diff --git a/assets/lang/lo_LA.ini b/assets/lang/lo_LA.ini index def577c06c..3ba7ecb517 100644 --- a/assets/lang/lo_LA.ini +++ b/assets/lang/lo_LA.ini @@ -912,6 +912,7 @@ Texture Filtering = ຕອງພື້ນຜິວ Texture replacement pack activated = Texture replacement pack activated Texture upscaling = ປັບພື້ນຜິວ The chosen ZIP file doesn't contain a valid driver = The chosen ZIP file doesn't contain a valid driver +The custom Vulkan driver failed to load. Switching back to default. = The custom Vulkan driver failed to load. Switching back to default. Unlimited = ບໍ່ຈຳກັດ Up to 1 = Up to 1 Up to 2 = Up to 2 diff --git a/assets/lang/lt-LT.ini b/assets/lang/lt-LT.ini index a4012ea857..887f2c094b 100644 --- a/assets/lang/lt-LT.ini +++ b/assets/lang/lt-LT.ini @@ -912,6 +912,7 @@ Texture Filtering = Tekstūrų filtravimas Texture replacement pack activated = Tekstūrų pakeitimo paketas aktyvuotas # AI translated Texture upscaling = Tekstūrų didinimas # AI translated The chosen ZIP file doesn't contain a valid driver = Pasirinktame ZIP faile nėra tinkamos tvarkyklės # AI translated +The custom Vulkan driver failed to load. Switching back to default. = Nepavyko įkelti pasirinktinės Vulkan tvarkyklės. Grįžtama prie numatytosios. # AI translated Unlimited = Neribota # AI translated Up to 1 = Iki 1 # AI translated Up to 2 = Iki 2 # AI translated diff --git a/assets/lang/ms_MY.ini b/assets/lang/ms_MY.ini index daffc78c24..9a781010d7 100644 --- a/assets/lang/ms_MY.ini +++ b/assets/lang/ms_MY.ini @@ -912,6 +912,7 @@ Texture Filtering = Penapisan Tekstur Texture replacement pack activated = Pek penggantian tekstur diaktifkan Texture upscaling = Penskalaan atas tekstur The chosen ZIP file doesn't contain a valid driver = Fail ZIP yang dipilih tidak mengandungi pemacu yang sah +The custom Vulkan driver failed to load. Switching back to default. = Pemacu Vulkan tersuai gagal dimuatkan. Beralih kembali ke lalai. # AI translated Unlimited = Tanpa had Up to 1 = Sehingga 1 Up to 2 = Sehingga 2 diff --git a/assets/lang/nl_NL.ini b/assets/lang/nl_NL.ini index 8db5ec2d45..029fbde54d 100644 --- a/assets/lang/nl_NL.ini +++ b/assets/lang/nl_NL.ini @@ -912,6 +912,7 @@ Texture Filtering = Texturefilter Texture replacement pack activated = Texturevervangingspakket geactiveerd # AI translated Texture upscaling = Textures opschalen # AI translated The chosen ZIP file doesn't contain a valid driver = Het gekozen ZIP-bestand bevat geen geldige driver # AI translated +The custom Vulkan driver failed to load. Switching back to default. = Het aangepaste Vulkan-stuurprogramma kon niet worden geladen. Terug naar de standaard. # AI translated Unlimited = Onbeperkt Up to 1 = Maximaal 1 # AI translated Up to 2 = Maximaal 2 # AI translated diff --git a/assets/lang/nn_NO.ini b/assets/lang/nn_NO.ini index 04d3d81376..9957f93131 100644 --- a/assets/lang/nn_NO.ini +++ b/assets/lang/nn_NO.ini @@ -936,6 +936,7 @@ Texture Filtering = Teksturfiltrering Texture replacement pack activated = Teksturerstatningspakke aktivert Texture upscaling = Teksturoppskalering The chosen ZIP file doesn't contain a valid driver = Den valde ZIP-fila inneheld ikkje ein gyldig drivar +The custom Vulkan driver failed to load. Switching back to default. = Den eigendefinerte Vulkan-drivaren kunne ikkje lastast. Byter tilbake til standard. # AI translated Unlimited = Uavgrensa Up to 1 = Opptil 1 Up to 2 = Opptil 2 diff --git a/assets/lang/no_NO.ini b/assets/lang/no_NO.ini index 84f9e016a6..8b6957d75f 100644 --- a/assets/lang/no_NO.ini +++ b/assets/lang/no_NO.ini @@ -936,6 +936,7 @@ Texture Filtering = Tekstur filtrering Texture replacement pack activated = Teksturerstatningspakke aktivert Texture upscaling = Teksturoppskalering # AI translated The chosen ZIP file doesn't contain a valid driver = Den valgte ZIP-filen inneholder ikke en gyldig driver +The custom Vulkan driver failed to load. Switching back to default. = Den egendefinerte Vulkan-driveren kunne ikke lastes inn. Bytter tilbake til standard. # AI translated Unlimited = Ubegrenset Up to 1 = Opptil 1 Up to 2 = Opptil 2 diff --git a/assets/lang/pl_PL.ini b/assets/lang/pl_PL.ini index 94138c0a62..8db11b797e 100644 --- a/assets/lang/pl_PL.ini +++ b/assets/lang/pl_PL.ini @@ -912,6 +912,7 @@ Texture Filtering = Filtrowanie tekstur Texture replacement pack activated = Paczka podmienionych tekstur aktywowana Texture upscaling = Skalowanie tekstur The chosen ZIP file doesn't contain a valid driver = Wybrany plik ZIP nie zawiera prawidłowego sterownika +The custom Vulkan driver failed to load. Switching back to default. = Nie udało się wczytać niestandardowego sterownika Vulkan. Przywracanie domyślnego. # AI translated Unlimited = Bez limitu Up to 1 = Maks. jeden Up to 2 = Maks. dwa diff --git a/assets/lang/pt_BR.ini b/assets/lang/pt_BR.ini index adfe67291e..3538f85486 100644 --- a/assets/lang/pt_BR.ini +++ b/assets/lang/pt_BR.ini @@ -937,6 +937,7 @@ Texture Filtering = Filtragem das texturas Texture replacement pack activated = Pacote de substituição das texturas ativado Texture upscaling = Ampliação das texturas The chosen ZIP file doesn't contain a valid driver = O arquivo ZIP escolhido não contém um driver válido +The custom Vulkan driver failed to load. Switching back to default. = Não foi possível carregar o driver Vulkan personalizado. Voltando ao padrão. # AI translated Unlimited = Ilimitado Up to 1 = Até 1 Up to 2 = Até 2 diff --git a/assets/lang/pt_PT.ini b/assets/lang/pt_PT.ini index 4124ea402d..59928e7e90 100644 --- a/assets/lang/pt_PT.ini +++ b/assets/lang/pt_PT.ini @@ -936,6 +936,7 @@ Texture Filtering = Filtração das texturas Texture replacement pack activated = Pacote de substituição de texturas ativado Texture upscaling = Dimensionamento das texturas The chosen ZIP file doesn't contain a valid driver = O ficheiro .zip escolhido não contém um driver válido +The custom Vulkan driver failed to load. Switching back to default. = Não foi possível carregar o controlador Vulkan personalizado. A voltar ao predefinido. # AI translated Unlimited = Ilimitado Up to 1 = Até 1 Up to 2 = Até 2 diff --git a/assets/lang/ro_RO.ini b/assets/lang/ro_RO.ini index 02b258794b..c64da7abed 100644 --- a/assets/lang/ro_RO.ini +++ b/assets/lang/ro_RO.ini @@ -913,6 +913,7 @@ Texture Filtering = Filtrare texturi Texture replacement pack activated = Pachet de înlocuire texturi activat # AI translated Texture upscaling = Suprascalare texturi # AI translated The chosen ZIP file doesn't contain a valid driver = Fișierul ZIP ales nu conține un driver valid # AI translated +The custom Vulkan driver failed to load. Switching back to default. = Driverul Vulkan personalizat nu a putut fi încărcat. Se revine la cel implicit. # AI translated Unlimited = Nelimitat # AI translated Up to 1 = Până la 1 # AI translated Up to 2 = Până la 2 # AI translated diff --git a/assets/lang/ru_RU.ini b/assets/lang/ru_RU.ini index a34c3d11be..430f89e85f 100644 --- a/assets/lang/ru_RU.ini +++ b/assets/lang/ru_RU.ini @@ -912,6 +912,7 @@ Texture Filtering = Фильтрация текстур Texture replacement pack activated = Пакет замены текстур активирован Texture upscaling = Масштабирование текстур The chosen ZIP file doesn't contain a valid driver = Выбранный файл ZIP не содержит корректный драйвер +The custom Vulkan driver failed to load. Switching back to default. = Не удалось загрузить пользовательский драйвер Vulkan. Возврат к стандартному. # AI translated Unlimited = Без ограничений Up to 1 = До 1 Up to 2 = До 2 diff --git a/assets/lang/sv_SE.ini b/assets/lang/sv_SE.ini index 615d504553..74e0ce303e 100644 --- a/assets/lang/sv_SE.ini +++ b/assets/lang/sv_SE.ini @@ -913,6 +913,7 @@ Texture Filtering = Texturfiltrering Texture replacement pack activated = Texturersättningspaket aktiverat Texture upscaling = Texturuppskalning The chosen ZIP file doesn't contain a valid driver = Den valda ZIP-filen innehåller inte en giltig drivrutin +The custom Vulkan driver failed to load. Switching back to default. = Den anpassade Vulkan-drivrutinen kunde inte läsas in. Byter tillbaka till standard. # AI translated Unlimited = Obegränsad Up to 1 = Upp till 1 Up to 2 = Upp till 2 diff --git a/assets/lang/tg_PH.ini b/assets/lang/tg_PH.ini index 29d3ced9da..fa08229342 100644 --- a/assets/lang/tg_PH.ini +++ b/assets/lang/tg_PH.ini @@ -913,6 +913,7 @@ Texture Filtering = Pagsala sa Texture Texture replacement pack activated = Na-activate ang texture replacement pack # AI translated Texture upscaling = Pag-upscale ng texture # AI translated The chosen ZIP file doesn't contain a valid driver = Walang wastong driver sa napiling ZIP file # AI translated +The custom Vulkan driver failed to load. Switching back to default. = Hindi na-load ang custom na Vulkan driver. Bumabalik sa default. # AI translated Unlimited = Walang hangganan Up to 1 = Hanggang 1 # AI translated Up to 2 = Hanggang 2 # AI translated diff --git a/assets/lang/th_TH.ini b/assets/lang/th_TH.ini index 9d83712530..ce61537619 100644 --- a/assets/lang/th_TH.ini +++ b/assets/lang/th_TH.ini @@ -918,6 +918,7 @@ Texture Filtering = การกรองพื้นผิว Texture replacement pack activated = แพ็คการแทนที่พื้นผิวถูกเปิดใช้งาน Texture upscaling = การปรับสเกลพื้นผิว The chosen ZIP file doesn't contain a valid driver = ไฟล์ ZIP ที่เลือกไว้ ไม่มีข้อมูลไดรเวอร์ที่ถูกต้อง +The custom Vulkan driver failed to load. Switching back to default. = โหลดไดรเวอร์ Vulkan แบบกำหนดเองไม่สำเร็จ กำลังกลับไปใช้ค่าเริ่มต้น # AI translated Unlimited = ไม่จำกัด Up to 1 = เพิ่มไปที่ 1 Up to 2 = เพิ่มไปที่ 2 diff --git a/assets/lang/tr_TR.ini b/assets/lang/tr_TR.ini index 72b8ecd18a..804b0fe6f2 100644 --- a/assets/lang/tr_TR.ini +++ b/assets/lang/tr_TR.ini @@ -914,6 +914,7 @@ Texture Filtering = Doku Filtreleme Texture replacement pack activated = Doku değiştirme paketi etkinleştirildi Texture upscaling = Doku ölçekleme The chosen ZIP file doesn't contain a valid driver = Seçilen ZIP dosyası geçerli bir sürücü içermiyor +The custom Vulkan driver failed to load. Switching back to default. = Özel Vulkan sürücüsü yüklenemedi. Varsayılana geri dönülüyor. # AI translated Unlimited = Sınırsız Up to 1 = 1 Kadar Up to 2 = 2 Kadar diff --git a/assets/lang/uk_UA.ini b/assets/lang/uk_UA.ini index a708522818..2a62b11ea3 100644 --- a/assets/lang/uk_UA.ini +++ b/assets/lang/uk_UA.ini @@ -912,6 +912,7 @@ Texture Filtering = Фільтрація текстур Texture replacement pack activated = Пакет заміни текстур активовано Texture upscaling = Масштабування текстур The chosen ZIP file doesn't contain a valid driver = Обраний ZIP файл не містить дійсного драйвера +The custom Vulkan driver failed to load. Switching back to default. = Не вдалося завантажити користувацький драйвер Vulkan. Повернення до стандартного. # AI translated Unlimited = Необмежено Up to 1 = До 1 Up to 2 = До 2 diff --git a/assets/lang/vi_VN.ini b/assets/lang/vi_VN.ini index 73f76f10bc..2b60c7e9e4 100644 --- a/assets/lang/vi_VN.ini +++ b/assets/lang/vi_VN.ini @@ -912,6 +912,7 @@ Texture Filtering = Lọc texture Texture replacement pack activated = Đã kích hoạt gói thay thế texture # AI translated Texture upscaling = Upscale texture # AI translated The chosen ZIP file doesn't contain a valid driver = Tệp ZIP đã chọn không chứa driver hợp lệ # AI translated +The custom Vulkan driver failed to load. Switching back to default. = Không thể tải trình điều khiển Vulkan tùy chỉnh. Đang chuyển về mặc định. # AI translated Unlimited = Không giới hạn Up to 1 = Tối đa 1 # AI translated Up to 2 = Tối đa 2 # AI translated diff --git a/assets/lang/zh_CN.ini b/assets/lang/zh_CN.ini index cf0881206e..a7b295b1b6 100644 --- a/assets/lang/zh_CN.ini +++ b/assets/lang/zh_CN.ini @@ -912,6 +912,7 @@ Texture Filtering = 纹理过滤 Texture replacement pack activated = 纹理替换包已生效 Texture upscaling = 纹理缩放 The chosen ZIP file doesn't contain a valid driver = 选择的ZIP文件里没有可用的驱动程序。 +The custom Vulkan driver failed to load. Switching back to default. = 无法加载自定义 Vulkan 驱动。正在切换回默认驱动。 # AI translated Unlimited = 无限制 Up to 1 = 最高缓冲1帧 Up to 2 = 最高缓冲2帧 diff --git a/assets/lang/zh_TW.ini b/assets/lang/zh_TW.ini index decbcd4454..1d741aeda2 100644 --- a/assets/lang/zh_TW.ini +++ b/assets/lang/zh_TW.ini @@ -912,6 +912,7 @@ Texture Filtering = 紋理過濾 Texture replacement pack activated = 紋理取代套件已啟用 Texture upscaling = 紋理縮放 The chosen ZIP file doesn't contain a valid driver = 選擇的 ZIP 檔案不包含有效的驅動程式 +The custom Vulkan driver failed to load. Switching back to default. = 無法載入自訂 Vulkan 驅動程式。正在切換回預設驅動程式。 # AI translated Unlimited = 無限制 Up to 1 = 最多至 1 Up to 2 = 最多至 2