Merge pull request #23029 from hrydgard/misc-fixes

Font style refactor, custom Vulkan driver fallback, firmware .nomedia
This commit is contained in:
Henrik Rydgård authored and GitHub committed 2026-11-10 16:43:52 +01:00
commit 0155d9be34
77 files changed
+311 -219

No files matched your search

+6
View File
@@ -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
+10
View File
@@ -1,5 +1,6 @@
#pragma once
#include <string>
#include <string_view>
#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();
+47 -1
View File
@@ -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
+21 -31
View File
@@ -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) {
+6 -9
View File
@@ -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;
+2 -6
View File
@@ -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);
}
+2 -3
View File
@@ -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);
}
}
+24 -44
View File
@@ -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 {
+15 -9
View File
@@ -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);
+4 -4
View File
@@ -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();
}
+4 -2
View File
@@ -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);
+2 -2
View File
@@ -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
+6 -7
View File
@@ -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();
}
+1 -1
View File
@@ -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();
}
+14 -14
View File
@@ -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();
}
+10 -13
View File
@@ -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);
}
+2 -3
View File
@@ -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);
}
+1 -2
View File
@@ -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);
}
+2 -3
View File
@@ -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.
+1 -1
View File
@@ -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);
+1 -3
View File
@@ -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 {
+2 -3
View File
@@ -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);
}
}
+6 -7
View File
@@ -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);
}
}
+1 -1
View File
@@ -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) {
+29 -5
View File
@@ -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<std::string> 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);
+3 -6
View File
@@ -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.
+4 -5
View File
@@ -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<float> total;
total.resize(historyLength);
+14 -29
View File
@@ -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.
+3 -4
View File
@@ -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) {
+15 -1
View File
@@ -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) {
+7
View File
@@ -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
+1
View File
@@ -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
+1
View File
@@ -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
+1
View File
@@ -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
+1
View File
@@ -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
+1
View File
@@ -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
+1
View File
@@ -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
+1
View File
@@ -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
+1
View File
@@ -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
+1
View File
@@ -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
+1
View File
@@ -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
+1
View File
@@ -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
+1
View File
@@ -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
+1
View File
@@ -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
+1
View File
@@ -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
+1
View File
@@ -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
+1
View File
@@ -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
+1
View File
@@ -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
+1
View File
@@ -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
+1
View File
@@ -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
+1
View File
@@ -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
+1
View File
@@ -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
+1
View File
@@ -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
+1
View File
@@ -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
+1
View File
@@ -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
+1
View File
@@ -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
+1
View File
@@ -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까지
+1
View File
@@ -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
+1
View File
@@ -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
+1
View File
@@ -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
+1
View File
@@ -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
+1
View File
@@ -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
+1
View File
@@ -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
+1
View File
@@ -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
+1
View File
@@ -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
+1
View File
@@ -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
+1
View File
@@ -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
+1
View File
@@ -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
+1
View File
@@ -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
+1
View File
@@ -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
+1
View File
@@ -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
+1
View File
@@ -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
+1
View File
@@ -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
+1
View File
@@ -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
+1
View File
@@ -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
+1
View File
@@ -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帧
+1
View File
@@ -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