Merge branch 'shadps4-emu:main' into shader_cache

This commit is contained in:
Fire Cube 2025-02-28 20:43:26 +01:00 committed by GitHub
commit 08cd231180
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
45 changed files with 1212 additions and 532 deletions

View File

@ -8,7 +8,7 @@ set(CMAKE_CXX_STANDARD 23)
set(CMAKE_CXX_STANDARD_REQUIRED True) set(CMAKE_CXX_STANDARD_REQUIRED True)
if(APPLE) if(APPLE)
enable_language(OBJC) list(APPEND ADDITIONAL_LANGUAGES OBJC)
set(CMAKE_OSX_DEPLOYMENT_TARGET 14) set(CMAKE_OSX_DEPLOYMENT_TARGET 14)
endif() endif()
@ -16,7 +16,7 @@ if (NOT CMAKE_BUILD_TYPE)
set(CMAKE_BUILD_TYPE Release) set(CMAKE_BUILD_TYPE Release)
endif() endif()
project(shadPS4 CXX C ASM) project(shadPS4 CXX C ASM ${ADDITIONAL_LANGUAGES})
# Forcing PIE makes sure that the base address is high enough so that it doesn't clash with the PS4 memory. # Forcing PIE makes sure that the base address is high enough so that it doesn't clash with the PS4 memory.
if(UNIX AND NOT APPLE) if(UNIX AND NOT APPLE)
@ -954,12 +954,6 @@ set(QT_GUI src/qt_gui/about_dialog.cpp
) )
endif() endif()
set(RESOURCEFOLDER Resources/bronze.png
Resources/gold.png
Resources/platinum.png
Resources/silver.png
)
if (ENABLE_QT_GUI) if (ENABLE_QT_GUI)
qt_add_executable(shadps4 qt_add_executable(shadps4
${AUDIO_CORE} ${AUDIO_CORE}
@ -971,7 +965,6 @@ if (ENABLE_QT_GUI)
${SHADER_RECOMPILER} ${SHADER_RECOMPILER}
${VIDEO_CORE} ${VIDEO_CORE}
${EMULATOR} ${EMULATOR}
${RESOURCEFOLDER}
src/images/shadPS4.icns src/images/shadPS4.icns
) )
else() else()
@ -984,7 +977,6 @@ else()
${SHADER_RECOMPILER} ${SHADER_RECOMPILER}
${VIDEO_CORE} ${VIDEO_CORE}
${EMULATOR} ${EMULATOR}
${RESOURCEFOLDER}
src/main.cpp src/main.cpp
src/emulator.cpp src/emulator.cpp
src/emulator.h src/emulator.h
@ -1117,7 +1109,10 @@ include(CMakeRC)
cmrc_add_resource_library(embedded-resources cmrc_add_resource_library(embedded-resources
ALIAS res::embedded ALIAS res::embedded
NAMESPACE res NAMESPACE res
${RESOURCEFOLDER}) src/images/bronze.png
src/images/gold.png
src/images/platinum.png
src/images/silver.png)
target_link_libraries(shadps4 PRIVATE res::embedded) target_link_libraries(shadps4 PRIVATE res::embedded)

View File

@ -19,11 +19,11 @@ path = [
"documents/Screenshots/*", "documents/Screenshots/*",
"documents/Screenshots/Linux/*", "documents/Screenshots/Linux/*",
"externals/MoltenVK/MoltenVK_icd.json", "externals/MoltenVK/MoltenVK_icd.json",
"Resources/bronze.png",
"Resources/gold.png",
"Resources/platinum.png",
"Resources/silver.png",
"scripts/ps4_names.txt", "scripts/ps4_names.txt",
"src/images/bronze.png",
"src/images/gold.png",
"src/images/platinum.png",
"src/images/silver.png",
"src/images/about_icon.png", "src/images/about_icon.png",
"src/images/controller_icon.png", "src/images/controller_icon.png",
"src/images/discord.png", "src/images/discord.png",

View File

@ -18,8 +18,6 @@ endif()
# Boost # Boost
if (NOT TARGET Boost::headers) if (NOT TARGET Boost::headers)
set(BOOST_ROOT "${CMAKE_SOURCE_DIR}/externals/ext-boost" CACHE STRING "")
set(Boost_NO_SYSTEM_PATHS ON CACHE BOOL "")
add_subdirectory(ext-boost) add_subdirectory(ext-boost)
endif() endif()
@ -77,6 +75,7 @@ endif()
# SDL3 # SDL3
if (NOT TARGET SDL3::SDL3) if (NOT TARGET SDL3::SDL3)
set(SDL_TEST_LIBRARY OFF)
set(SDL_PIPEWIRE OFF) set(SDL_PIPEWIRE OFF)
add_subdirectory(sdl3) add_subdirectory(sdl3)
endif() endif()
@ -131,6 +130,14 @@ endif()
# Toml11 # Toml11
if (NOT TARGET toml11::toml11) if (NOT TARGET toml11::toml11)
add_subdirectory(toml11) add_subdirectory(toml11)
if (CMAKE_CXX_COMPILER_ID STREQUAL "Clang")
if (CMAKE_CXX_COMPILER_FRONTEND_VARIANT STREQUAL "MSVC")
get_target_property(_toml11_compile_options toml11 INTERFACE_COMPILE_OPTIONS)
list(REMOVE_ITEM _toml11_compile_options "/Zc:preprocessor")
set_target_properties(toml11 PROPERTIES INTERFACE_COMPILE_OPTIONS ${_toml11_compile_options})
endif()
endif()
endif() endif()
# xxHash # xxHash

View File

@ -3,6 +3,10 @@
project(gcn LANGUAGES CXX) project(gcn LANGUAGES CXX)
add_library(gcn dummy.cpp) add_library(gcn INTERFACE)
target_sources(gcn PRIVATE
"include/gcn/si_ci_vi_merged_offset.h"
"include/gcn/si_ci_vi_merged_pm4_it_opcodes.h"
)
target_include_directories(gcn INTERFACE include) target_include_directories(gcn INTERFACE include)

View File

@ -1,2 +0,0 @@
// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later

View File

@ -53,6 +53,7 @@ static bool isShaderDebug = false;
static bool isShowSplash = false; static bool isShowSplash = false;
static bool isAutoUpdate = false; static bool isAutoUpdate = false;
static bool isAlwaysShowChangelog = false; static bool isAlwaysShowChangelog = false;
static bool isLeftSideTrophy = false;
static bool isNullGpu = false; static bool isNullGpu = false;
static bool shouldCopyGPUBuffers = false; static bool shouldCopyGPUBuffers = false;
static bool shouldDumpShaders = false; static bool shouldDumpShaders = false;
@ -69,6 +70,7 @@ static bool isFpsColor = true;
static bool isSeparateLogFilesEnabled = false; static bool isSeparateLogFilesEnabled = false;
static s16 cursorState = HideCursorState::Idle; static s16 cursorState = HideCursorState::Idle;
static int cursorHideTimeout = 5; // 5 seconds (default) static int cursorHideTimeout = 5; // 5 seconds (default)
static double trophyNotificationDuration = 6.0;
static bool useUnifiedInputConfig = true; static bool useUnifiedInputConfig = true;
static bool overrideControllerColor = false; static bool overrideControllerColor = false;
static int controllerCustomColorRGB[3] = {0, 0, 255}; static int controllerCustomColorRGB[3] = {0, 0, 255};
@ -196,6 +198,10 @@ int getCursorHideTimeout() {
return cursorHideTimeout; return cursorHideTimeout;
} }
double getTrophyNotificationDuration() {
return trophyNotificationDuration;
}
u32 getScreenWidth() { u32 getScreenWidth() {
return screenWidth; return screenWidth;
} }
@ -264,6 +270,10 @@ bool alwaysShowChangelog() {
return isAlwaysShowChangelog; return isAlwaysShowChangelog;
} }
bool leftSideTrophy() {
return isLeftSideTrophy;
}
bool nullGpu() { bool nullGpu() {
return isNullGpu; return isNullGpu;
} }
@ -371,6 +381,9 @@ void setAutoUpdate(bool enable) {
void setAlwaysShowChangelog(bool enable) { void setAlwaysShowChangelog(bool enable) {
isAlwaysShowChangelog = enable; isAlwaysShowChangelog = enable;
} }
void setLeftSideTrophy(bool enable) {
isLeftSideTrophy = enable;
}
void setNullGpu(bool enable) { void setNullGpu(bool enable) {
isNullGpu = enable; isNullGpu = enable;
@ -435,6 +448,9 @@ void setCursorState(s16 newCursorState) {
void setCursorHideTimeout(int newcursorHideTimeout) { void setCursorHideTimeout(int newcursorHideTimeout) {
cursorHideTimeout = newcursorHideTimeout; cursorHideTimeout = newcursorHideTimeout;
} }
void setTrophyNotificationDuration(double newTrophyNotificationDuration) {
trophyNotificationDuration = newTrophyNotificationDuration;
}
void setLanguage(u32 language) { void setLanguage(u32 language) {
m_language = language; m_language = language;
@ -706,6 +722,8 @@ void load(const std::filesystem::path& path) {
isNeo = toml::find_or<bool>(general, "isPS4Pro", false); isNeo = toml::find_or<bool>(general, "isPS4Pro", false);
playBGM = toml::find_or<bool>(general, "playBGM", false); playBGM = toml::find_or<bool>(general, "playBGM", false);
isTrophyPopupDisabled = toml::find_or<bool>(general, "isTrophyPopupDisabled", false); isTrophyPopupDisabled = toml::find_or<bool>(general, "isTrophyPopupDisabled", false);
trophyNotificationDuration =
toml::find_or<double>(general, "trophyNotificationDuration", 5.0);
BGMvolume = toml::find_or<int>(general, "BGMvolume", 50); BGMvolume = toml::find_or<int>(general, "BGMvolume", 50);
enableDiscordRPC = toml::find_or<bool>(general, "enableDiscordRPC", true); enableDiscordRPC = toml::find_or<bool>(general, "enableDiscordRPC", true);
logFilter = toml::find_or<std::string>(general, "logFilter", ""); logFilter = toml::find_or<std::string>(general, "logFilter", "");
@ -719,6 +737,7 @@ void load(const std::filesystem::path& path) {
isShowSplash = toml::find_or<bool>(general, "showSplash", true); isShowSplash = toml::find_or<bool>(general, "showSplash", true);
isAutoUpdate = toml::find_or<bool>(general, "autoUpdate", false); isAutoUpdate = toml::find_or<bool>(general, "autoUpdate", false);
isAlwaysShowChangelog = toml::find_or<bool>(general, "alwaysShowChangelog", false); isAlwaysShowChangelog = toml::find_or<bool>(general, "alwaysShowChangelog", false);
isLeftSideTrophy = toml::find_or<bool>(general, "leftSideTrophy", false);
separateupdatefolder = toml::find_or<bool>(general, "separateUpdateEnabled", false); separateupdatefolder = toml::find_or<bool>(general, "separateUpdateEnabled", false);
compatibilityData = toml::find_or<bool>(general, "compatibilityEnabled", false); compatibilityData = toml::find_or<bool>(general, "compatibilityEnabled", false);
checkCompatibilityOnStartup = checkCompatibilityOnStartup =
@ -834,7 +853,7 @@ void load(const std::filesystem::path& path) {
} }
void save(const std::filesystem::path& path) { void save(const std::filesystem::path& path) {
toml::value data; toml::ordered_value data;
std::error_code error; std::error_code error;
if (std::filesystem::exists(path, error)) { if (std::filesystem::exists(path, error)) {
@ -842,7 +861,8 @@ void save(const std::filesystem::path& path) {
std::ifstream ifs; std::ifstream ifs;
ifs.exceptions(std::ifstream::failbit | std::ifstream::badbit); ifs.exceptions(std::ifstream::failbit | std::ifstream::badbit);
ifs.open(path, std::ios_base::binary); ifs.open(path, std::ios_base::binary);
data = toml::parse(ifs, std::string{fmt::UTF(path.filename().u8string()).data}); data = toml::parse<toml::ordered_type_config>(
ifs, std::string{fmt::UTF(path.filename().u8string()).data});
} catch (const std::exception& ex) { } catch (const std::exception& ex) {
fmt::print("Exception trying to parse config file. Exception: {}\n", ex.what()); fmt::print("Exception trying to parse config file. Exception: {}\n", ex.what());
return; return;
@ -856,6 +876,7 @@ void save(const std::filesystem::path& path) {
data["General"]["isPS4Pro"] = isNeo; data["General"]["isPS4Pro"] = isNeo;
data["General"]["isTrophyPopupDisabled"] = isTrophyPopupDisabled; data["General"]["isTrophyPopupDisabled"] = isTrophyPopupDisabled;
data["General"]["trophyNotificationDuration"] = trophyNotificationDuration;
data["General"]["playBGM"] = playBGM; data["General"]["playBGM"] = playBGM;
data["General"]["BGMvolume"] = BGMvolume; data["General"]["BGMvolume"] = BGMvolume;
data["General"]["enableDiscordRPC"] = enableDiscordRPC; data["General"]["enableDiscordRPC"] = enableDiscordRPC;
@ -867,6 +888,7 @@ void save(const std::filesystem::path& path) {
data["General"]["showSplash"] = isShowSplash; data["General"]["showSplash"] = isShowSplash;
data["General"]["autoUpdate"] = isAutoUpdate; data["General"]["autoUpdate"] = isAutoUpdate;
data["General"]["alwaysShowChangelog"] = isAlwaysShowChangelog; data["General"]["alwaysShowChangelog"] = isAlwaysShowChangelog;
data["General"]["leftSideTrophy"] = isLeftSideTrophy;
data["General"]["separateUpdateEnabled"] = separateupdatefolder; data["General"]["separateUpdateEnabled"] = separateupdatefolder;
data["General"]["compatibilityEnabled"] = compatibilityData; data["General"]["compatibilityEnabled"] = compatibilityData;
data["General"]["checkCompatibilityOnStartup"] = checkCompatibilityOnStartup; data["General"]["checkCompatibilityOnStartup"] = checkCompatibilityOnStartup;
@ -924,7 +946,7 @@ void save(const std::filesystem::path& path) {
} }
void saveMainWindow(const std::filesystem::path& path) { void saveMainWindow(const std::filesystem::path& path) {
toml::value data; toml::ordered_value data;
std::error_code error; std::error_code error;
if (std::filesystem::exists(path, error)) { if (std::filesystem::exists(path, error)) {
@ -932,7 +954,8 @@ void saveMainWindow(const std::filesystem::path& path) {
std::ifstream ifs; std::ifstream ifs;
ifs.exceptions(std::ifstream::failbit | std::ifstream::badbit); ifs.exceptions(std::ifstream::failbit | std::ifstream::badbit);
ifs.open(path, std::ios_base::binary); ifs.open(path, std::ios_base::binary);
data = toml::parse(ifs, std::string{fmt::UTF(path.filename().u8string()).data}); data = toml::parse<toml::ordered_type_config>(
ifs, std::string{fmt::UTF(path.filename().u8string()).data});
} catch (const std::exception& ex) { } catch (const std::exception& ex) {
fmt::print("Exception trying to parse config file. Exception: {}\n", ex.what()); fmt::print("Exception trying to parse config file. Exception: {}\n", ex.what());
return; return;
@ -986,6 +1009,7 @@ void setDefaultValues() {
chooseHomeTab = "General"; chooseHomeTab = "General";
cursorState = HideCursorState::Idle; cursorState = HideCursorState::Idle;
cursorHideTimeout = 5; cursorHideTimeout = 5;
trophyNotificationDuration = 6.0;
backButtonBehavior = "left"; backButtonBehavior = "left";
useSpecialPad = false; useSpecialPad = false;
specialPadClass = 1; specialPadClass = 1;
@ -994,6 +1018,7 @@ void setDefaultValues() {
isShowSplash = false; isShowSplash = false;
isAutoUpdate = false; isAutoUpdate = false;
isAlwaysShowChangelog = false; isAlwaysShowChangelog = false;
isLeftSideTrophy = false;
isNullGpu = false; isNullGpu = false;
shouldDumpShaders = false; shouldDumpShaders = false;
vblankDivider = 1; vblankDivider = 1;

View File

@ -41,6 +41,7 @@ std::string getChooseHomeTab();
s16 getCursorState(); s16 getCursorState();
int getCursorHideTimeout(); int getCursorHideTimeout();
double getTrophyNotificationDuration();
std::string getBackButtonBehavior(); std::string getBackButtonBehavior();
bool getUseSpecialPad(); bool getUseSpecialPad();
int getSpecialPadClass(); int getSpecialPadClass();
@ -62,6 +63,7 @@ bool collectShadersForDebug();
bool showSplash(); bool showSplash();
bool autoUpdate(); bool autoUpdate();
bool alwaysShowChangelog(); bool alwaysShowChangelog();
bool leftSideTrophy();
bool nullGpu(); bool nullGpu();
bool copyGPUCmdBuffers(); bool copyGPUCmdBuffers();
bool dumpShaders(); bool dumpShaders();
@ -75,6 +77,7 @@ void setCollectShaderForDebug(bool enable);
void setShowSplash(bool enable); void setShowSplash(bool enable);
void setAutoUpdate(bool enable); void setAutoUpdate(bool enable);
void setAlwaysShowChangelog(bool enable); void setAlwaysShowChangelog(bool enable);
void setLeftSideTrophy(bool enable);
void setNullGpu(bool enable); void setNullGpu(bool enable);
void setAllowHDR(bool enable); void setAllowHDR(bool enable);
void setCopyGPUCmdBuffers(bool enable); void setCopyGPUCmdBuffers(bool enable);
@ -104,6 +107,7 @@ void setShowBackgroundImage(bool show);
void setCursorState(s16 cursorState); void setCursorState(s16 cursorState);
void setCursorHideTimeout(int newcursorHideTimeout); void setCursorHideTimeout(int newcursorHideTimeout);
void setTrophyNotificationDuration(double newTrophyNotificationDuration);
void setBackButtonBehavior(const std::string& type); void setBackButtonBehavior(const std::string& type);
void setUseSpecialPad(bool use); void setUseSpecialPad(bool use);
void setSpecialPadClass(int type); void setSpecialPadClass(int type);

View File

@ -128,6 +128,7 @@ static auto UserPaths = [] {
create_path(PathType::CheatsDir, user_dir / CHEATS_DIR); create_path(PathType::CheatsDir, user_dir / CHEATS_DIR);
create_path(PathType::PatchesDir, user_dir / PATCHES_DIR); create_path(PathType::PatchesDir, user_dir / PATCHES_DIR);
create_path(PathType::MetaDataDir, user_dir / METADATA_DIR); create_path(PathType::MetaDataDir, user_dir / METADATA_DIR);
create_path(PathType::CustomTrophy, user_dir / CUSTOM_TROPHY);
return paths; return paths;
}(); }();

View File

@ -27,6 +27,7 @@ enum class PathType {
CheatsDir, // Where cheats are stored. CheatsDir, // Where cheats are stored.
PatchesDir, // Where patches are stored. PatchesDir, // Where patches are stored.
MetaDataDir, // Where game metadata (e.g. trophies and menu backgrounds) is stored. MetaDataDir, // Where game metadata (e.g. trophies and menu backgrounds) is stored.
CustomTrophy, // Where custom files for trophies are stored.
}; };
constexpr auto PORTABLE_DIR = "user"; constexpr auto PORTABLE_DIR = "user";
@ -44,6 +45,7 @@ constexpr auto CAPTURES_DIR = "captures";
constexpr auto CHEATS_DIR = "cheats"; constexpr auto CHEATS_DIR = "cheats";
constexpr auto PATCHES_DIR = "patches"; constexpr auto PATCHES_DIR = "patches";
constexpr auto METADATA_DIR = "game_data"; constexpr auto METADATA_DIR = "game_data";
constexpr auto CUSTOM_TROPHY = "custom_trophy";
// Filenames // Filenames
constexpr auto LOG_FILE = "shad_log.txt"; constexpr auto LOG_FILE = "shad_log.txt";

View File

@ -923,15 +923,16 @@ int PS4_SYSV_ABI sceNpTrophyUnlockTrophy(OrbisNpTrophyContext context, OrbisNpTr
node.attribute("unlockstate").set_value("true"); node.attribute("unlockstate").set_value("true");
} }
Rtc::OrbisRtcTick trophyTimestamp; auto trophyTimestamp = std::chrono::duration_cast<std::chrono::seconds>(
Rtc::sceRtcGetCurrentTick(&trophyTimestamp); std::chrono::system_clock::now().time_since_epoch())
.count();
if (node.attribute("timestamp").empty()) { if (node.attribute("timestamp").empty()) {
node.append_attribute("timestamp") = node.append_attribute("timestamp") =
std::to_string(trophyTimestamp.tick).c_str(); std::to_string(trophyTimestamp).c_str();
} else { } else {
node.attribute("timestamp") node.attribute("timestamp")
.set_value(std::to_string(trophyTimestamp.tick).c_str()); .set_value(std::to_string(trophyTimestamp).c_str());
} }
std::string trophy_icon_file = "TROP"; std::string trophy_icon_file = "TROP";
@ -955,15 +956,16 @@ int PS4_SYSV_ABI sceNpTrophyUnlockTrophy(OrbisNpTrophyContext context, OrbisNpTr
platinum_node.attribute("unlockstate").set_value("true"); platinum_node.attribute("unlockstate").set_value("true");
} }
Rtc::OrbisRtcTick trophyTimestamp; auto trophyTimestamp = std::chrono::duration_cast<std::chrono::seconds>(
Rtc::sceRtcGetCurrentTick(&trophyTimestamp); std::chrono::system_clock::now().time_since_epoch())
.count();
if (platinum_node.attribute("timestamp").empty()) { if (platinum_node.attribute("timestamp").empty()) {
platinum_node.append_attribute("timestamp") = platinum_node.append_attribute("timestamp") =
std::to_string(trophyTimestamp.tick).c_str(); std::to_string(trophyTimestamp).c_str();
} else { } else {
platinum_node.attribute("timestamp") platinum_node.attribute("timestamp")
.set_value(std::to_string(trophyTimestamp.tick).c_str()); .set_value(std::to_string(trophyTimestamp).c_str());
} }
int platinum_trophy_id = int platinum_trophy_id =

View File

@ -2,9 +2,17 @@
// SPDX-License-Identifier: GPL-2.0-or-later // SPDX-License-Identifier: GPL-2.0-or-later
#include <chrono> #include <chrono>
#include <filesystem>
#include <fstream>
#include <mutex> #include <mutex>
#include <cmrc/cmrc.hpp> #include <cmrc/cmrc.hpp>
#include <common/path_util.h>
#include <imgui.h> #include <imgui.h>
#ifdef ENABLE_QT_GUI
#include <qt_gui/background_music_player.h>
#endif
#include "common/assert.h" #include "common/assert.h"
#include "common/config.h" #include "common/config.h"
#include "common/singleton.h" #include "common/singleton.h"
@ -12,18 +20,23 @@
#include "trophy_ui.h" #include "trophy_ui.h"
CMRC_DECLARE(res); CMRC_DECLARE(res);
namespace fs = std::filesystem;
using namespace ImGui; using namespace ImGui;
namespace Libraries::NpTrophy { namespace Libraries::NpTrophy {
std::optional<TrophyUI> current_trophy_ui; std::optional<TrophyUI> current_trophy_ui;
std::queue<TrophyInfo> trophy_queue; std::queue<TrophyInfo> trophy_queue;
std::mutex queueMtx; std::mutex queueMtx;
bool isLeftSide;
double trophy_timer;
TrophyUI::TrophyUI(const std::filesystem::path& trophyIconPath, const std::string& trophyName, TrophyUI::TrophyUI(const std::filesystem::path& trophyIconPath, const std::string& trophyName,
const std::string_view& rarity) const std::string_view& rarity)
: trophy_name(trophyName), trophy_type(rarity) { : trophy_name(trophyName), trophy_type(rarity) {
isLeftSide = Config::leftSideTrophy();
trophy_timer = Config::getTrophyNotificationDuration();
if (std::filesystem::exists(trophyIconPath)) { if (std::filesystem::exists(trophyIconPath)) {
trophy_icon = RefCountedTexture::DecodePngFile(trophyIconPath); trophy_icon = RefCountedTexture::DecodePngFile(trophyIconPath);
} else { } else {
@ -31,23 +44,57 @@ TrophyUI::TrophyUI(const std::filesystem::path& trophyIconPath, const std::strin
fmt::UTF(trophyIconPath.u8string())); fmt::UTF(trophyIconPath.u8string()));
} }
std::string pathString; std::string pathString = "src/images/";
if (trophy_type == "P") { if (trophy_type == "P") {
pathString = "Resources/platinum.png"; pathString += "platinum.png";
} else if (trophy_type == "G") { } else if (trophy_type == "G") {
pathString = "Resources/gold.png"; pathString += "gold.png";
} else if (trophy_type == "S") { } else if (trophy_type == "S") {
pathString = "Resources/silver.png"; pathString += "silver.png";
} else if (trophy_type == "B") { } else if (trophy_type == "B") {
pathString = "Resources/bronze.png"; pathString += "bronze.png";
}
const auto CustomTrophy_Dir = Common::FS::GetUserPath(Common::FS::PathType::CustomTrophy);
std::string customPath;
if (trophy_type == "P" && fs::exists(CustomTrophy_Dir / "platinum.png")) {
customPath = (CustomTrophy_Dir / "platinum.png").string();
} else if (trophy_type == "G" && fs::exists(CustomTrophy_Dir / "gold.png")) {
customPath = (CustomTrophy_Dir / "gold.png").string();
} else if (trophy_type == "S" && fs::exists(CustomTrophy_Dir / "silver.png")) {
customPath = (CustomTrophy_Dir / "silver.png").string();
} else if (trophy_type == "B" && fs::exists(CustomTrophy_Dir / "bronze.png")) {
customPath = (CustomTrophy_Dir / "bronze.png").string();
}
std::vector<u8> imgdata;
if (!customPath.empty()) {
std::ifstream file(customPath, std::ios::binary);
if (file) {
imgdata = std::vector<u8>(std::istreambuf_iterator<char>(file),
std::istreambuf_iterator<char>());
} else {
LOG_ERROR(Lib_NpTrophy, "Could not open custom file for trophy in {}", customPath);
}
} else {
auto resource = cmrc::res::get_filesystem();
auto file = resource.open(pathString);
imgdata = std::vector<u8>(file.begin(), file.end());
} }
auto resource = cmrc::res::get_filesystem();
auto file = resource.open(pathString);
std::vector<u8> imgdata(file.begin(), file.end());
trophy_type_icon = RefCountedTexture::DecodePngTexture(imgdata); trophy_type_icon = RefCountedTexture::DecodePngTexture(imgdata);
AddLayer(this); AddLayer(this);
#ifdef ENABLE_QT_GUI
QString musicPath = QString::fromStdString(CustomTrophy_Dir.string() + "/trophy.mp3");
if (fs::exists(musicPath.toStdString())) {
BackgroundMusicPlayer::getInstance().setVolume(100);
BackgroundMusicPlayer::getInstance().playMusic(musicPath, false);
}
#endif
} }
TrophyUI::~TrophyUI() { TrophyUI::~TrophyUI() {
@ -58,6 +105,13 @@ void TrophyUI::Finish() {
RemoveLayer(this); RemoveLayer(this);
} }
float fade_opacity = 0.0f; // Initial opacity (invisible)
ImVec2 start_pos = ImVec2(1280.0f, 50.0f); // Starts off screen, right
ImVec2 target_pos = ImVec2(0.0f, 50.0f); // Final position
float animation_duration = 0.5f; // Animation duration
float elapsed_time = 0.0f; // Animation time
float fade_out_duration = 0.5f; // Final fade duration
void TrophyUI::Draw() { void TrophyUI::Draw() {
const auto& io = GetIO(); const auto& io = GetIO();
@ -68,26 +122,60 @@ void TrophyUI::Draw() {
std::min(io.DisplaySize.y, (70 * AdjustHeight)), std::min(io.DisplaySize.y, (70 * AdjustHeight)),
}; };
elapsed_time += io.DeltaTime;
float progress = std::min(elapsed_time / animation_duration, 1.0f);
// left or right position
float final_pos_x;
if (isLeftSide) {
start_pos.x = -window_size.x;
final_pos_x = 20 * AdjustWidth;
} else {
start_pos.x = io.DisplaySize.x;
final_pos_x = io.DisplaySize.x - window_size.x - 20 * AdjustWidth;
}
ImVec2 current_pos = ImVec2(start_pos.x + (final_pos_x - start_pos.x) * progress,
start_pos.y + (target_pos.y - start_pos.y) * progress);
trophy_timer -= io.DeltaTime;
// If the remaining time of the trophy is less than or equal to 1 second, the fade-out begins.
if (trophy_timer <= 1.0f) {
float fade_out_time = 1.0f - (trophy_timer / 1.0f);
fade_opacity = 1.0f - fade_out_time;
} else {
// Fade in , 0 to 1
fade_opacity = progress;
}
fade_opacity = std::max(0.0f, std::min(fade_opacity, 1.0f));
SetNextWindowSize(window_size); SetNextWindowSize(window_size);
SetNextWindowPos(current_pos);
SetNextWindowCollapsed(false); SetNextWindowCollapsed(false);
SetNextWindowPos(ImVec2(io.DisplaySize.x - (370 * AdjustWidth), (50 * AdjustHeight)));
KeepNavHighlight(); KeepNavHighlight();
PushStyleVar(ImGuiStyleVar_Alpha, fade_opacity);
if (Begin("Trophy Window", nullptr, if (Begin("Trophy Window", nullptr,
ImGuiWindowFlags_NoDecoration | ImGuiWindowFlags_NoSavedSettings | ImGuiWindowFlags_NoDecoration | ImGuiWindowFlags_NoSavedSettings |
ImGuiWindowFlags_NoInputs)) { ImGuiWindowFlags_NoInputs)) {
// Displays the trophy icon
if (trophy_type_icon) { if (trophy_type_icon) {
SetCursorPosY((window_size.y * 0.5f) - (25 * AdjustHeight)); SetCursorPosY((window_size.y * 0.5f) - (25 * AdjustHeight));
Image(trophy_type_icon.GetTexture().im_id, Image(trophy_type_icon.GetTexture().im_id,
ImVec2((50 * AdjustWidth), (50 * AdjustHeight))); ImVec2((50 * AdjustWidth), (50 * AdjustHeight)));
ImGui::SameLine(); ImGui::SameLine();
} else { } else {
// placeholder // Placeholder
const auto pos = GetCursorScreenPos(); const auto pos = GetCursorScreenPos();
ImGui::GetWindowDrawList()->AddRectFilled(pos, pos + ImVec2{50.0f * AdjustHeight}, ImGui::GetWindowDrawList()->AddRectFilled(pos, pos + ImVec2{50.0f * AdjustHeight},
GetColorU32(ImVec4{0.7f})); GetColorU32(ImVec4{0.7f}));
ImGui::Indent(60); ImGui::Indent(60);
} }
// Displays the name of the trophy
const std::string combinedString = "Trophy earned!\n%s" + trophy_name; const std::string combinedString = "Trophy earned!\n%s" + trophy_name;
const float wrap_width = const float wrap_width =
CalcWrapWidthForPos(GetCursorScreenPos(), (window_size.x - (60 * AdjustWidth))); CalcWrapWidthForPos(GetCursorScreenPos(), (window_size.x - (60 * AdjustWidth)));
@ -108,11 +196,12 @@ void TrophyUI::Draw() {
TextWrapped("Trophy earned!\n%s", trophy_name.c_str()); TextWrapped("Trophy earned!\n%s", trophy_name.c_str());
ImGui::SameLine(window_size.x - (60 * AdjustWidth)); ImGui::SameLine(window_size.x - (60 * AdjustWidth));
// Displays the trophy icon
if (trophy_icon) { if (trophy_icon) {
SetCursorPosY((window_size.y * 0.5f) - (25 * AdjustHeight)); SetCursorPosY((window_size.y * 0.5f) - (25 * AdjustHeight));
Image(trophy_icon.GetTexture().im_id, ImVec2((50 * AdjustWidth), (50 * AdjustHeight))); Image(trophy_icon.GetTexture().im_id, ImVec2((50 * AdjustWidth), (50 * AdjustHeight)));
} else { } else {
// placeholder // Placeholder
const auto pos = GetCursorScreenPos(); const auto pos = GetCursorScreenPos();
ImGui::GetWindowDrawList()->AddRectFilled(pos, pos + ImVec2{50.0f * AdjustHeight}, ImGui::GetWindowDrawList()->AddRectFilled(pos, pos + ImVec2{50.0f * AdjustHeight},
GetColorU32(ImVec4{0.7f})); GetColorU32(ImVec4{0.7f}));
@ -120,7 +209,8 @@ void TrophyUI::Draw() {
} }
End(); End();
trophy_timer -= io.DeltaTime; PopStyleVar();
if (trophy_timer <= 0) { if (trophy_timer <= 0) {
std::lock_guard<std::mutex> lock(queueMtx); std::lock_guard<std::mutex> lock(queueMtx);
if (!trophy_queue.empty()) { if (!trophy_queue.empty()) {
@ -141,13 +231,27 @@ void AddTrophyToQueue(const std::filesystem::path& trophyIconPath, const std::st
if (Config::getisTrophyPopupDisabled()) { if (Config::getisTrophyPopupDisabled()) {
return; return;
} else if (current_trophy_ui.has_value()) { } else if (current_trophy_ui.has_value()) {
TrophyInfo new_trophy; current_trophy_ui.reset();
new_trophy.trophy_icon_path = trophyIconPath; }
new_trophy.trophy_name = trophyName;
new_trophy.trophy_type = rarity; TrophyInfo new_trophy;
trophy_queue.push(new_trophy); new_trophy.trophy_icon_path = trophyIconPath;
} else { new_trophy.trophy_name = trophyName;
current_trophy_ui.emplace(trophyIconPath, trophyName, rarity); new_trophy.trophy_type = rarity;
trophy_queue.push(new_trophy);
if (!current_trophy_ui.has_value()) {
#ifdef ENABLE_QT_GUI
BackgroundMusicPlayer::getInstance().stopMusic();
#endif
// Resetting the animation for the next trophy
elapsed_time = 0.0f; // Resetting animation time
fade_opacity = 0.0f; // Starts invisible
start_pos = ImVec2(1280.0f, 50.0f); // Starts off screen, right
TrophyInfo next_trophy = trophy_queue.front();
trophy_queue.pop();
current_trophy_ui.emplace(next_trophy.trophy_icon_path, next_trophy.trophy_name,
next_trophy.trophy_type);
} }
} }

View File

@ -28,7 +28,6 @@ public:
private: private:
std::string trophy_name; std::string trophy_name;
std::string_view trophy_type; std::string_view trophy_type;
float trophy_timer = 5.0f;
ImGui::RefCountedTexture trophy_icon; ImGui::RefCountedTexture trophy_icon;
ImGui::RefCountedTexture trophy_type_icon; ImGui::RefCountedTexture trophy_type_icon;
}; };

View File

@ -315,12 +315,13 @@ int PS4_SYSV_ABI scePadRead(s32 handle, OrbisPadData* pData, s32 num) {
pData[i].angularVelocity.x = states[i].angularVelocity.x; pData[i].angularVelocity.x = states[i].angularVelocity.x;
pData[i].angularVelocity.y = states[i].angularVelocity.y; pData[i].angularVelocity.y = states[i].angularVelocity.y;
pData[i].angularVelocity.z = states[i].angularVelocity.z; pData[i].angularVelocity.z = states[i].angularVelocity.z;
pData[i].orientation = {0.0f, 0.0f, 0.0f, 1.0f};
if (engine) { if (engine) {
const auto accel_poll_rate = engine->GetAccelPollRate(); const auto gyro_poll_rate = engine->GetAccelPollRate();
if (accel_poll_rate != 0.0f) { if (gyro_poll_rate != 0.0f) {
GameController::CalculateOrientation(pData[i].acceleration, GameController::CalculateOrientation(pData[i].acceleration,
pData[i].angularVelocity, pData[i].angularVelocity,
1.0f / accel_poll_rate, pData[i].orientation); 1.0f / gyro_poll_rate, pData[i].orientation);
} }
} }
pData[i].touchData.touchNum = pData[i].touchData.touchNum =
@ -384,11 +385,12 @@ int PS4_SYSV_ABI scePadReadState(s32 handle, OrbisPadData* pData) {
pData->angularVelocity.x = state.angularVelocity.x; pData->angularVelocity.x = state.angularVelocity.x;
pData->angularVelocity.y = state.angularVelocity.y; pData->angularVelocity.y = state.angularVelocity.y;
pData->angularVelocity.z = state.angularVelocity.z; pData->angularVelocity.z = state.angularVelocity.z;
pData->orientation = {0.0f, 0.0f, 0.0f, 1.0f};
if (engine) { if (engine) {
const auto accel_poll_rate = engine->GetAccelPollRate(); const auto gyro_poll_rate = engine->GetAccelPollRate();
if (accel_poll_rate != 0.0f) { if (gyro_poll_rate != 0.0f) {
GameController::CalculateOrientation(pData->acceleration, pData->angularVelocity, GameController::CalculateOrientation(pData->acceleration, pData->angularVelocity,
1.0f / accel_poll_rate, pData->orientation); 1.0f / gyro_poll_rate, pData->orientation);
} }
} }
pData->touchData.touchNum = pData->touchData.touchNum =

View File

@ -107,6 +107,11 @@ void Emulator::Run(const std::filesystem::path& file, const std::vector<std::str
Common::PSFAttributes psf_attributes{}; Common::PSFAttributes psf_attributes{};
const auto param_sfo_path = mnt->GetHostPath("/app0/sce_sys/param.sfo"); const auto param_sfo_path = mnt->GetHostPath("/app0/sce_sys/param.sfo");
if (!std::filesystem::exists(param_sfo_path) || !Config::getSeparateLogFilesEnabled()) {
Common::Log::Initialize();
Common::Log::Start();
}
if (std::filesystem::exists(param_sfo_path)) { if (std::filesystem::exists(param_sfo_path)) {
auto* param_sfo = Common::Singleton<PSF>::Instance(); auto* param_sfo = Common::Singleton<PSF>::Instance();
const bool success = param_sfo->Open(param_sfo_path); const bool success = param_sfo->Open(param_sfo_path);
@ -117,10 +122,8 @@ void Emulator::Run(const std::filesystem::path& file, const std::vector<std::str
if (Config::getSeparateLogFilesEnabled()) { if (Config::getSeparateLogFilesEnabled()) {
Common::Log::Initialize(id + ".log"); Common::Log::Initialize(id + ".log");
} else { Common::Log::Start();
Common::Log::Initialize();
} }
Common::Log::Start();
LOG_INFO(Loader, "Starting shadps4 emulator v{} ", Common::VERSION); LOG_INFO(Loader, "Starting shadps4 emulator v{} ", Common::VERSION);
LOG_INFO(Loader, "Revision {}", Common::g_scm_rev); LOG_INFO(Loader, "Revision {}", Common::g_scm_rev);
LOG_INFO(Loader, "Branch {}", Common::g_scm_branch); LOG_INFO(Loader, "Branch {}", Common::g_scm_branch);

View File

Before

Width:  |  Height:  |  Size: 40 KiB

After

Width:  |  Height:  |  Size: 40 KiB

View File

Before

Width:  |  Height:  |  Size: 43 KiB

After

Width:  |  Height:  |  Size: 43 KiB

View File

Before

Width:  |  Height:  |  Size: 44 KiB

After

Width:  |  Height:  |  Size: 44 KiB

View File

Before

Width:  |  Height:  |  Size: 33 KiB

After

Width:  |  Height:  |  Size: 33 KiB

View File

@ -182,7 +182,7 @@ void GameController::CalculateOrientation(Libraries::Pad::OrbisFVector3& acceler
// Normalize accelerometer measurement // Normalize accelerometer measurement
float norm = std::sqrt(ax * ax + ay * ay + az * az); float norm = std::sqrt(ax * ax + ay * ay + az * az);
if (norm == 0.0f) if (norm == 0.0f || deltaTime == 0.0f)
return; // Handle NaN return; // Handle NaN
norm = 1.0f / norm; norm = 1.0f / norm;
ax *= norm; ax *= norm;

View File

@ -7,7 +7,6 @@ BackgroundMusicPlayer::BackgroundMusicPlayer(QObject* parent) : QObject(parent)
m_mediaPlayer = new QMediaPlayer(this); m_mediaPlayer = new QMediaPlayer(this);
m_audioOutput = new QAudioOutput(this); m_audioOutput = new QAudioOutput(this);
m_mediaPlayer->setAudioOutput(m_audioOutput); m_mediaPlayer->setAudioOutput(m_audioOutput);
m_mediaPlayer->setLoops(QMediaPlayer::Infinite);
} }
void BackgroundMusicPlayer::setVolume(int volume) { void BackgroundMusicPlayer::setVolume(int volume) {
@ -16,7 +15,7 @@ void BackgroundMusicPlayer::setVolume(int volume) {
m_audioOutput->setVolume(linearVolume); m_audioOutput->setVolume(linearVolume);
} }
void BackgroundMusicPlayer::playMusic(const QString& snd0path) { void BackgroundMusicPlayer::playMusic(const QString& snd0path, bool loops) {
if (snd0path.isEmpty()) { if (snd0path.isEmpty()) {
stopMusic(); stopMusic();
return; return;
@ -28,6 +27,12 @@ void BackgroundMusicPlayer::playMusic(const QString& snd0path) {
return; return;
} }
if (loops) {
m_mediaPlayer->setLoops(QMediaPlayer::Infinite);
} else {
m_mediaPlayer->setLoops(1);
}
m_currentMusic = newMusic; m_currentMusic = newMusic;
m_mediaPlayer->setSource(newMusic); m_mediaPlayer->setSource(newMusic);
m_mediaPlayer->play(); m_mediaPlayer->play();

View File

@ -17,7 +17,7 @@ public:
} }
void setVolume(int volume); void setVolume(int volume);
void playMusic(const QString& snd0path); void playMusic(const QString& snd0path, bool loops = true);
void stopMusic(); void stopMusic();
private: private:

View File

@ -1082,7 +1082,11 @@ void CheatsPatches::addCheatsToLayout(const QJsonArray& modsArray, const QJsonAr
QLabel* creditsLabel = new QLabel(); QLabel* creditsLabel = new QLabel();
QString creditsText = tr("Author: "); QString creditsText = tr("Author: ");
if (!creditsArray.isEmpty()) { if (!creditsArray.isEmpty()) {
creditsText += creditsArray[0].toString(); QStringList authors;
for (const QJsonValue& credit : creditsArray) {
authors << credit.toString();
}
creditsText += authors.join(", ");
} }
creditsLabel->setText(creditsText); creditsLabel->setText(creditsText);
creditsLabel->setAlignment(Qt::AlignLeft); creditsLabel->setAlignment(Qt::AlignLeft);

View File

@ -78,25 +78,38 @@ void CompatibilityInfoClass::UpdateCompatibilityDatabase(QWidget* parent, bool f
CompatibilityEntry CompatibilityInfoClass::GetCompatibilityInfo(const std::string& serial) { CompatibilityEntry CompatibilityInfoClass::GetCompatibilityInfo(const std::string& serial) {
QString title_id = QString::fromStdString(serial); QString title_id = QString::fromStdString(serial);
if (m_compatibility_database.contains(title_id)) { if (m_compatibility_database.contains(title_id)) {
{ QJsonObject compatibility_obj = m_compatibility_database[title_id].toObject();
QJsonObject compatibility_obj = m_compatibility_database[title_id].toObject();
for (int os_int = 0; os_int != static_cast<int>(OSType::Last); os_int++) { // Set current_os automatically
QString os_string = OSTypeToString.at(static_cast<OSType>(os_int)); QString current_os;
if (compatibility_obj.contains(os_string)) { #ifdef Q_OS_WIN
QJsonObject compatibility_entry_obj = compatibility_obj[os_string].toObject(); current_os = "os-windows";
CompatibilityEntry compatibility_entry{ #elif defined(Q_OS_MAC)
LabelToCompatStatus.at(compatibility_entry_obj["status"].toString()), current_os = "os-macOS";
compatibility_entry_obj["version"].toString(), #elif defined(Q_OS_LINUX)
QDateTime::fromString(compatibility_entry_obj["last_tested"].toString(), current_os = "os-linux";
Qt::ISODate), #else
compatibility_entry_obj["url"].toString(), current_os = "os-unknown";
compatibility_entry_obj["issue_number"].toString()}; #endif
return compatibility_entry; // Check if the game is compatible with the current operating system
} if (compatibility_obj.contains(current_os)) {
} QJsonObject compatibility_entry_obj = compatibility_obj[current_os].toObject();
CompatibilityEntry compatibility_entry{
LabelToCompatStatus.at(compatibility_entry_obj["status"].toString()),
compatibility_entry_obj["version"].toString(),
QDateTime::fromString(compatibility_entry_obj["last_tested"].toString(),
Qt::ISODate),
compatibility_entry_obj["url"].toString(),
compatibility_entry_obj["issue_number"].toString()};
return compatibility_entry;
} else {
// If there is no entry for the current operating system, return "Unknown"
return CompatibilityEntry{CompatibilityStatus::Unknown, "",
QDateTime::currentDateTime(), "", 0};
} }
} }
// If title not found, return "Unknown"
return CompatibilityEntry{CompatibilityStatus::Unknown, "", QDateTime::currentDateTime(), "", return CompatibilityEntry{CompatibilityStatus::Unknown, "", QDateTime::currentDateTime(), "",
0}; 0};
} }
@ -200,4 +213,4 @@ const QString CompatibilityInfoClass::GetCompatStatusString(const CompatibilityS
default: default:
return tr("Unknown"); return tr("Unknown");
} }
} }

View File

@ -97,11 +97,13 @@ public:
QAction* deleteUpdate = new QAction(tr("Delete Update"), widget); QAction* deleteUpdate = new QAction(tr("Delete Update"), widget);
QAction* deleteSaveData = new QAction(tr("Delete Save Data"), widget); QAction* deleteSaveData = new QAction(tr("Delete Save Data"), widget);
QAction* deleteDLC = new QAction(tr("Delete DLC"), widget); QAction* deleteDLC = new QAction(tr("Delete DLC"), widget);
QAction* deleteTrophy = new QAction(tr("Delete Trophy"), widget);
deleteMenu->addAction(deleteGame); deleteMenu->addAction(deleteGame);
deleteMenu->addAction(deleteUpdate); deleteMenu->addAction(deleteUpdate);
deleteMenu->addAction(deleteSaveData); deleteMenu->addAction(deleteSaveData);
deleteMenu->addAction(deleteDLC); deleteMenu->addAction(deleteDLC);
deleteMenu->addAction(deleteTrophy);
menu.addMenu(deleteMenu); menu.addMenu(deleteMenu);
@ -155,10 +157,54 @@ public:
} }
if (selected == openLogFolder) { if (selected == openLogFolder) {
QString userPath; QString logPath;
Common::FS::PathToQString(userPath, Common::FS::PathToQString(logPath,
Common::FS::GetUserPath(Common::FS::PathType::UserDir)); Common::FS::GetUserPath(Common::FS::PathType::LogDir));
QDesktopServices::openUrl(QUrl::fromLocalFile(userPath + "/log")); if (!Config::getSeparateLogFilesEnabled()) {
QDesktopServices::openUrl(QUrl::fromLocalFile(logPath));
} else {
QString fileName = QString::fromStdString(m_games[itemID].serial) + ".log";
QString filePath = logPath + "/" + fileName;
QStringList arguments;
if (QFile::exists(filePath)) {
#ifdef Q_OS_WIN
arguments << "/select," << filePath.replace("/", "\\");
QProcess::startDetached("explorer", arguments);
#elif defined(Q_OS_MAC)
arguments << "-R" << filePath;
QProcess::startDetached("open", arguments);
#elif defined(Q_OS_LINUX)
QStringList arguments;
arguments << "--select" << filePath;
if (!QProcess::startDetached("nautilus", arguments)) {
// Failed to open Nautilus to select file
arguments.clear();
arguments << logPath;
if (!QProcess::startDetached("xdg-open", arguments)) {
// Failed to open directory on Linux
}
}
#else
QDesktopServices::openUrl(QUrl::fromLocalFile(logPath));
#endif
} else {
QMessageBox msgBox;
msgBox.setIcon(QMessageBox::Information);
msgBox.setText(tr("No log file found for this game!"));
QPushButton* okButton = msgBox.addButton(QMessageBox::Ok);
QPushButton* openFolderButton =
msgBox.addButton(tr("Open Log Folder"), QMessageBox::ActionRole);
msgBox.exec();
if (msgBox.clickedButton() == openFolderButton) {
QDesktopServices::openUrl(QUrl::fromLocalFile(logPath));
}
}
}
} }
if (selected == &openSfoViewer) { if (selected == &openSfoViewer) {
@ -380,9 +426,9 @@ public:
} }
if (selected == deleteGame || selected == deleteUpdate || selected == deleteDLC || if (selected == deleteGame || selected == deleteUpdate || selected == deleteDLC ||
selected == deleteSaveData) { selected == deleteSaveData || selected == deleteTrophy) {
bool error = false; bool error = false;
QString folder_path, game_update_path, dlc_path, save_data_path; QString folder_path, game_update_path, dlc_path, save_data_path, trophy_data_path;
Common::FS::PathToQString(folder_path, m_games[itemID].path); Common::FS::PathToQString(folder_path, m_games[itemID].path);
game_update_path = folder_path + "-UPDATE"; game_update_path = folder_path + "-UPDATE";
Common::FS::PathToQString( Common::FS::PathToQString(
@ -391,6 +437,11 @@ public:
Common::FS::PathToQString(save_data_path, Common::FS::PathToQString(save_data_path,
Common::FS::GetUserPath(Common::FS::PathType::UserDir) / Common::FS::GetUserPath(Common::FS::PathType::UserDir) /
"savedata/1" / m_games[itemID].serial); "savedata/1" / m_games[itemID].serial);
Common::FS::PathToQString(trophy_data_path,
Common::FS::GetUserPath(Common::FS::PathType::MetaDataDir) /
m_games[itemID].serial / "TrophyFiles");
QString message_type = tr("Game"); QString message_type = tr("Game");
if (selected == deleteUpdate) { if (selected == deleteUpdate) {
@ -420,6 +471,16 @@ public:
folder_path = save_data_path; folder_path = save_data_path;
message_type = tr("Save Data"); message_type = tr("Save Data");
} }
} else if (selected == deleteTrophy) {
if (!std::filesystem::exists(Common::FS::PathFromQString(trophy_data_path))) {
QMessageBox::critical(
nullptr, tr("Error"),
QString(tr("This game has no saved trophies to delete!")));
error = true;
} else {
folder_path = trophy_data_path;
message_type = tr("Trophy");
}
} }
if (!error) { if (!error) {
QString gameName = QString::fromStdString(m_games[itemID].name); QString gameName = QString::fromStdString(m_games[itemID].name);

View File

@ -130,6 +130,7 @@ void MainWindow::CreateActions() {
m_theme_act_group->addAction(ui->setThemeViolet); m_theme_act_group->addAction(ui->setThemeViolet);
m_theme_act_group->addAction(ui->setThemeGruvbox); m_theme_act_group->addAction(ui->setThemeGruvbox);
m_theme_act_group->addAction(ui->setThemeTokyoNight); m_theme_act_group->addAction(ui->setThemeTokyoNight);
m_theme_act_group->addAction(ui->setThemeOled);
} }
void MainWindow::AddUiWidgets() { void MainWindow::AddUiWidgets() {
@ -651,6 +652,14 @@ void MainWindow::CreateConnects() {
isIconBlack = false; isIconBlack = false;
} }
}); });
connect(ui->setThemeOled, &QAction::triggered, &m_window_themes, [this]() {
m_window_themes.SetWindowTheme(Theme::Oled, ui->mw_searchbar);
Config::setMainWindowTheme(static_cast<int>(Theme::Oled));
if (isIconBlack) {
SetUiIcons(false);
isIconBlack = false;
}
});
} }
void MainWindow::StartGame() { void MainWindow::StartGame() {
@ -1098,6 +1107,11 @@ void MainWindow::SetLastUsedTheme() {
isIconBlack = false; isIconBlack = false;
SetUiIcons(false); SetUiIcons(false);
break; break;
case Theme::Oled:
ui->setThemeOled->setChecked(true);
isIconBlack = false;
SetUiIcons(false);
break;
} }
} }

View File

@ -6,6 +6,7 @@
void WindowThemes::SetWindowTheme(Theme theme, QLineEdit* mw_searchbar) { void WindowThemes::SetWindowTheme(Theme theme, QLineEdit* mw_searchbar) {
QPalette themePalette; QPalette themePalette;
qApp->setStyleSheet("");
switch (theme) { switch (theme) {
case Theme::Dark: case Theme::Dark:
mw_searchbar->setStyleSheet( mw_searchbar->setStyleSheet(
@ -165,5 +166,29 @@ void WindowThemes::SetWindowTheme(Theme theme, QLineEdit* mw_searchbar) {
themePalette.setColor(QPalette::HighlightedText, Qt::black); themePalette.setColor(QPalette::HighlightedText, Qt::black);
qApp->setPalette(themePalette); qApp->setPalette(themePalette);
break; break;
case Theme::Oled:
mw_searchbar->setStyleSheet("QLineEdit:focus {"
"border: 1px solid #2A82DA; }");
themePalette.setColor(QPalette::Window, Qt::black);
themePalette.setColor(QPalette::WindowText, Qt::white);
themePalette.setColor(QPalette::Base, Qt::black);
themePalette.setColor(QPalette::AlternateBase, Qt::black);
themePalette.setColor(QPalette::ToolTipBase, Qt::black);
themePalette.setColor(QPalette::ToolTipText, Qt::white);
themePalette.setColor(QPalette::Text, Qt::white);
themePalette.setColor(QPalette::Button, QColor(5, 5, 5));
themePalette.setColor(QPalette::ButtonText, Qt::white);
themePalette.setColor(QPalette::BrightText, Qt::red);
themePalette.setColor(QPalette::Link, QColor(42, 130, 218));
themePalette.setColor(QPalette::Highlight, QColor(42, 130, 218));
themePalette.setColor(QPalette::HighlightedText, Qt::black);
qApp->setPalette(themePalette);
qApp->setStyleSheet("QLineEdit {"
"background-color: #000000; color: #ffffff; border: 1px solid #a0a0a0; "
"border-radius: 4px; padding: 5px; }"
"QCheckBox::indicator:unchecked {"
"border: 1px solid #808080; border-radius: 4px; }");
break;
} }
} }

View File

@ -7,7 +7,7 @@
#include <QLineEdit> #include <QLineEdit>
#include <QWidget> #include <QWidget>
enum class Theme : int { Dark, Light, Green, Blue, Violet, Gruvbox, TokyoNight }; enum class Theme : int { Dark, Light, Green, Blue, Violet, Gruvbox, TokyoNight, Oled };
class WindowThemes : public QObject { class WindowThemes : public QObject {
Q_OBJECT Q_OBJECT

View File

@ -39,6 +39,7 @@ public:
QAction* setThemeViolet; QAction* setThemeViolet;
QAction* setThemeGruvbox; QAction* setThemeGruvbox;
QAction* setThemeTokyoNight; QAction* setThemeTokyoNight;
QAction* setThemeOled;
QWidget* centralWidget; QWidget* centralWidget;
QLineEdit* mw_searchbar; QLineEdit* mw_searchbar;
QPushButton* playButton; QPushButton* playButton;
@ -171,6 +172,9 @@ public:
setThemeTokyoNight = new QAction(MainWindow); setThemeTokyoNight = new QAction(MainWindow);
setThemeTokyoNight->setObjectName("setThemeTokyoNight"); setThemeTokyoNight->setObjectName("setThemeTokyoNight");
setThemeTokyoNight->setCheckable(true); setThemeTokyoNight->setCheckable(true);
setThemeOled = new QAction(MainWindow);
setThemeOled->setObjectName("setThemeOled");
setThemeOled->setCheckable(true);
centralWidget = new QWidget(MainWindow); centralWidget = new QWidget(MainWindow);
centralWidget->setObjectName("centralWidget"); centralWidget->setObjectName("centralWidget");
sizePolicy.setHeightForWidth(centralWidget->sizePolicy().hasHeightForWidth()); sizePolicy.setHeightForWidth(centralWidget->sizePolicy().hasHeightForWidth());
@ -303,6 +307,7 @@ public:
menuThemes->addAction(setThemeViolet); menuThemes->addAction(setThemeViolet);
menuThemes->addAction(setThemeGruvbox); menuThemes->addAction(setThemeGruvbox);
menuThemes->addAction(setThemeTokyoNight); menuThemes->addAction(setThemeTokyoNight);
menuThemes->addAction(setThemeOled);
menuGame_List_Icons->addAction(setIconSizeTinyAct); menuGame_List_Icons->addAction(setIconSizeTinyAct);
menuGame_List_Icons->addAction(setIconSizeSmallAct); menuGame_List_Icons->addAction(setIconSizeSmallAct);
menuGame_List_Icons->addAction(setIconSizeMediumAct); menuGame_List_Icons->addAction(setIconSizeMediumAct);
@ -393,6 +398,7 @@ public:
setThemeViolet->setText(QCoreApplication::translate("MainWindow", "Violet", nullptr)); setThemeViolet->setText(QCoreApplication::translate("MainWindow", "Violet", nullptr));
setThemeGruvbox->setText("Gruvbox"); setThemeGruvbox->setText("Gruvbox");
setThemeTokyoNight->setText("Tokyo Night"); setThemeTokyoNight->setText("Tokyo Night");
setThemeOled->setText("OLED");
toolBar->setWindowTitle(QCoreApplication::translate("MainWindow", "toolBar", nullptr)); toolBar->setWindowTitle(QCoreApplication::translate("MainWindow", "toolBar", nullptr));
} // retranslateUi } // retranslateUi
}; };

View File

@ -225,6 +225,17 @@ SettingsDialog::SettingsDialog(std::span<const QString> physical_devices,
Config::setShowBackgroundImage(state == Qt::Checked); Config::setShowBackgroundImage(state == Qt::Checked);
}); });
} }
// User TAB
{
connect(ui->OpenCustomTrophyLocationButton, &QPushButton::clicked, this, []() {
QString userPath;
Common::FS::PathToQString(userPath,
Common::FS::GetUserPath(Common::FS::PathType::CustomTrophy));
QDesktopServices::openUrl(QUrl::fromLocalFile(userPath));
});
}
// Input TAB // Input TAB
{ {
connect(ui->hideCursorComboBox, QOverload<int>::of(&QComboBox::currentIndexChanged), this, connect(ui->hideCursorComboBox, QOverload<int>::of(&QComboBox::currentIndexChanged), this,
@ -280,8 +291,8 @@ SettingsDialog::SettingsDialog(std::span<const QString> physical_devices,
connect(ui->OpenLogLocationButton, &QPushButton::clicked, this, []() { connect(ui->OpenLogLocationButton, &QPushButton::clicked, this, []() {
QString userPath; QString userPath;
Common::FS::PathToQString(userPath, Common::FS::PathToQString(userPath,
Common::FS::GetUserPath(Common::FS::PathType::UserDir)); Common::FS::GetUserPath(Common::FS::PathType::LogDir));
QDesktopServices::openUrl(QUrl::fromLocalFile(userPath + "/log")); QDesktopServices::openUrl(QUrl::fromLocalFile(userPath));
}); });
} }
@ -308,6 +319,9 @@ SettingsDialog::SettingsDialog(std::span<const QString> physical_devices,
ui->checkCompatibilityOnStartupCheckBox->installEventFilter(this); ui->checkCompatibilityOnStartupCheckBox->installEventFilter(this);
ui->updateCompatibilityButton->installEventFilter(this); ui->updateCompatibilityButton->installEventFilter(this);
// User
ui->OpenCustomTrophyLocationButton->installEventFilter(this);
// Input // Input
ui->hideCursorGroupBox->installEventFilter(this); ui->hideCursorGroupBox->installEventFilter(this);
ui->idleTimeoutGroupBox->installEventFilter(this); ui->idleTimeoutGroupBox->installEventFilter(this);
@ -403,6 +417,9 @@ void SettingsDialog::LoadValuesFromConfig() {
ui->playBGMCheckBox->setChecked(toml::find_or<bool>(data, "General", "playBGM", false)); ui->playBGMCheckBox->setChecked(toml::find_or<bool>(data, "General", "playBGM", false));
ui->disableTrophycheckBox->setChecked( ui->disableTrophycheckBox->setChecked(
toml::find_or<bool>(data, "General", "isTrophyPopupDisabled", false)); toml::find_or<bool>(data, "General", "isTrophyPopupDisabled", false));
ui->popUpDurationSpinBox->setValue(Config::getTrophyNotificationDuration());
ui->radioButton_Left->setChecked(Config::leftSideTrophy());
ui->radioButton_Right->setChecked(!ui->radioButton_Left->isChecked());
ui->BGMVolumeSlider->setValue(toml::find_or<int>(data, "General", "BGMvolume", 50)); ui->BGMVolumeSlider->setValue(toml::find_or<int>(data, "General", "BGMvolume", 50));
ui->discordRPCCheckbox->setChecked( ui->discordRPCCheckbox->setChecked(
toml::find_or<bool>(data, "General", "enableDiscordRPC", true)); toml::find_or<bool>(data, "General", "enableDiscordRPC", true));
@ -593,6 +610,11 @@ void SettingsDialog::updateNoteTextEdit(const QString& elementName) {
text = tr("Update Compatibility Database:\\nImmediately update the compatibility database."); text = tr("Update Compatibility Database:\\nImmediately update the compatibility database.");
} }
//User
if (elementName == "OpenCustomTrophyLocationButton") {
text = tr("Open the custom trophy images/sounds folder:\\nYou can add custom images to the trophies and an audio.\\nAdd the files to custom_trophy with the following names:\\nthophy.mp3, bronze.png, gold.png, platinum.png, silver.png");
}
// Input // Input
if (elementName == "hideCursorGroupBox") { if (elementName == "hideCursorGroupBox") {
text = tr("Hide Cursor:\\nChoose when the cursor will disappear:\\nNever: You will always see the mouse.\\nidle: Set a time for it to disappear after being idle.\\nAlways: you will never see the mouse."); text = tr("Hide Cursor:\\nChoose when the cursor will disappear:\\nNever: You will always see the mouse.\\nidle: Set a time for it to disappear after being idle.\\nAlways: you will never see the mouse.");
@ -677,11 +699,14 @@ void SettingsDialog::UpdateSettings() {
const QVector<std::string> TouchPadIndex = {"left", "center", "right", "none"}; const QVector<std::string> TouchPadIndex = {"left", "center", "right", "none"};
Config::setBackButtonBehavior(TouchPadIndex[ui->backButtonBehaviorComboBox->currentIndex()]); Config::setBackButtonBehavior(TouchPadIndex[ui->backButtonBehaviorComboBox->currentIndex()]);
Config::setIsFullscreen(ui->displayModeComboBox->currentText().toStdString() != "Windowed"); Config::setIsFullscreen(screenModeMap.value(ui->displayModeComboBox->currentText()) !=
"Windowed");
Config::setFullscreenMode( Config::setFullscreenMode(
screenModeMap.value(ui->displayModeComboBox->currentText()).toStdString()); screenModeMap.value(ui->displayModeComboBox->currentText()).toStdString());
Config::setIsMotionControlsEnabled(ui->motionControlsCheckBox->isChecked()); Config::setIsMotionControlsEnabled(ui->motionControlsCheckBox->isChecked());
Config::setisTrophyPopupDisabled(ui->disableTrophycheckBox->isChecked()); Config::setisTrophyPopupDisabled(ui->disableTrophycheckBox->isChecked());
Config::setTrophyNotificationDuration(ui->popUpDurationSpinBox->value());
Config::setLeftSideTrophy(ui->radioButton_Left->isChecked());
Config::setPlayBGM(ui->playBGMCheckBox->isChecked()); Config::setPlayBGM(ui->playBGMCheckBox->isChecked());
Config::setAllowHDR(ui->enableHDRCheckBox->isChecked()); Config::setAllowHDR(ui->enableHDRCheckBox->isChecked());
Config::setLogType(logTypeMap.value(ui->logTypeComboBox->currentText()).toStdString()); Config::setLogType(logTypeMap.value(ui->logTypeComboBox->currentText()).toStdString());

View File

@ -59,7 +59,7 @@
</size> </size>
</property> </property>
<property name="currentIndex"> <property name="currentIndex">
<number>6</number> <number>0</number>
</property> </property>
<widget class="QScrollArea" name="generalTab"> <widget class="QScrollArea" name="generalTab">
<property name="widgetResizable"> <property name="widgetResizable">
@ -73,8 +73,8 @@
<rect> <rect>
<x>0</x> <x>0</x>
<y>0</y> <y>0</y>
<width>718</width> <width>946</width>
<height>332</height> <height>545</height>
</rect> </rect>
</property> </property>
<layout class="QVBoxLayout" name="generalTabVLayout" stretch="0"> <layout class="QVBoxLayout" name="generalTabVLayout" stretch="0">
@ -454,8 +454,8 @@
<rect> <rect>
<x>0</x> <x>0</x>
<y>0</y> <y>0</y>
<width>646</width> <width>946</width>
<height>395</height> <height>545</height>
</rect> </rect>
</property> </property>
<layout class="QVBoxLayout" name="guiTabVLayout" stretch="0"> <layout class="QVBoxLayout" name="guiTabVLayout" stretch="0">
@ -903,8 +903,8 @@
<rect> <rect>
<x>0</x> <x>0</x>
<y>0</y> <y>0</y>
<width>545</width> <width>946</width>
<height>141</height> <height>545</height>
</rect> </rect>
</property> </property>
<layout class="QVBoxLayout" name="graphicsTabVLayout" stretch="0,0"> <layout class="QVBoxLayout" name="graphicsTabVLayout" stretch="0,0">
@ -1198,8 +1198,8 @@
<rect> <rect>
<x>0</x> <x>0</x>
<y>0</y> <y>0</y>
<width>234</width> <width>946</width>
<height>292</height> <height>545</height>
</rect> </rect>
</property> </property>
<layout class="QVBoxLayout" name="userTabVLayout" stretch="0,0,1"> <layout class="QVBoxLayout" name="userTabVLayout" stretch="0,0,1">
@ -1264,30 +1264,121 @@
<item> <item>
<widget class="QCheckBox" name="disableTrophycheckBox"> <widget class="QCheckBox" name="disableTrophycheckBox">
<property name="text"> <property name="text">
<string>Disable Trophy Pop-ups</string> <string>Disable Trophy Notification</string>
</property> </property>
</widget> </widget>
</item> </item>
<item> <item>
<widget class="QLabel" name="label_Trophy"> <layout class="QHBoxLayout" name="horizontalLayout_SidePopUps">
<property name="bottomMargin">
<number>0</number>
</property>
<item>
<widget class="QLabel" name="label_SidePopUps">
<property name="sizePolicy">
<sizepolicy hsizetype="Maximum" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>Trophy Notification Position</string>
</property>
</widget>
</item>
<item>
<widget class="QRadioButton" name="radioButton_Left">
<property name="text">
<string>Left</string>
</property>
</widget>
</item>
<item>
<widget class="QRadioButton" name="radioButton_Right">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>Right</string>
</property>
</widget>
</item>
</layout>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_PopUpsDuration">
<property name="bottomMargin">
<number>0</number>
</property>
<item>
<widget class="QLabel" name="label_PopUpDuration">
<property name="sizePolicy">
<sizepolicy hsizetype="Maximum" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>Notification Duration</string>
</property>
</widget>
</item>
<item>
<widget class="QDoubleSpinBox" name="popUpDurationSpinBox">
</widget>
</item>
<item>
<spacer name="horizontalSpacer_4">
<property name="orientation">
<enum>Qt::Orientation::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
</layout>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_trophyKey">
<property name="bottomMargin">
<number>0</number>
</property>
<item>
<widget class="QLabel" name="label_Trophy">
<property name="text">
<string>Trophy Key</string>
</property>
</widget>
</item>
<item>
<widget class="QLineEdit" name="trophyKeyLineEdit">
<property name="minimumSize">
<size>
<width>0</width>
<height>0</height>
</size>
</property>
<property name="font">
<font>
<pointsize>10</pointsize>
<bold>false</bold>
</font>
</property>
</widget>
</item>
</layout>
</item>
<item>
<widget class="QPushButton" name="OpenCustomTrophyLocationButton">
<property name="text"> <property name="text">
<string>Trophy Key</string> <string>Open the custom trophy images/sounds folder</string>
</property>
</widget>
</item>
<item>
<widget class="QLineEdit" name="trophyKeyLineEdit">
<property name="minimumSize">
<size>
<width>0</width>
<height>0</height>
</size>
</property>
<property name="font">
<font>
<pointsize>10</pointsize>
<bold>false</bold>
</font>
</property> </property>
</widget> </widget>
</item> </item>
@ -1342,8 +1433,8 @@
<rect> <rect>
<x>0</x> <x>0</x>
<y>0</y> <y>0</y>
<width>455</width> <width>946</width>
<height>252</height> <height>545</height>
</rect> </rect>
</property> </property>
<layout class="QVBoxLayout" name="inputTabVLayout" stretch="0,0"> <layout class="QVBoxLayout" name="inputTabVLayout" stretch="0,0">
@ -1626,8 +1717,8 @@
<rect> <rect>
<x>0</x> <x>0</x>
<y>0</y> <y>0</y>
<width>216</width> <width>946</width>
<height>254</height> <height>545</height>
</rect> </rect>
</property> </property>
<layout class="QVBoxLayout" name="pathsTabLayout"> <layout class="QVBoxLayout" name="pathsTabLayout">
@ -1717,7 +1808,7 @@
<x>0</x> <x>0</x>
<y>0</y> <y>0</y>
<width>946</width> <width>946</width>
<height>536</height> <height>545</height>
</rect> </rect>
</property> </property>
<layout class="QVBoxLayout" name="debugTabVLayout" stretch="0,0"> <layout class="QVBoxLayout" name="debugTabVLayout" stretch="0,0">

View File

@ -419,11 +419,11 @@
</message> </message>
<message> <message>
<source>Left</source> <source>Left</source>
<translation type="unfinished"></translation> <translation type="unfinished">Left</translation>
</message> </message>
<message> <message>
<source>Right</source> <source>Right</source>
<translation type="unfinished"></translation> <translation type="unfinished">Right</translation>
</message> </message>
<message> <message>
<source>Down</source> <source>Down</source>
@ -775,6 +775,10 @@
<source>Delete DLC</source> <source>Delete DLC</source>
<translation>Delete DLC</translation> <translation>Delete DLC</translation>
</message> </message>
<message>
<source>Delete Trophy</source>
<translation>Delete Trophy</translation>
</message>
<message> <message>
<source>Compatibility...</source> <source>Compatibility...</source>
<translation>Compatibility...</translation> <translation>Compatibility...</translation>
@ -851,6 +855,10 @@
<source>This game has no update folder to open!</source> <source>This game has no update folder to open!</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message>
<source>No log file found for this game!</source>
<translation type="unfinished"></translation>
</message>
<message> <message>
<source>Failed to convert icon.</source> <source>Failed to convert icon.</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
@ -859,10 +867,18 @@
<source>This game has no save data to delete!</source> <source>This game has no save data to delete!</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message>
<source>This game has no saved trophies to delete!</source>
<translation type="unfinished"></translation>
</message>
<message> <message>
<source>Save Data</source> <source>Save Data</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message>
<source>Trophy</source>
<translation type="unfinished">Trophy</translation>
</message>
<message> <message>
<source>SFO Viewer for </source> <source>SFO Viewer for </source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
@ -1311,6 +1327,10 @@
<source>Trophy</source> <source>Trophy</source>
<translation>Trophy</translation> <translation>Trophy</translation>
</message> </message>
<message>
<source>Open the custom trophy images/sounds folder</source>
<translation>Open the custom trophy images/sounds folder</translation>
</message>
<message> <message>
<source>Logger</source> <source>Logger</source>
<translation>Logger</translation> <translation>Logger</translation>
@ -1476,8 +1496,8 @@
<translation>Title Music</translation> <translation>Title Music</translation>
</message> </message>
<message> <message>
<source>Disable Trophy Pop-ups</source> <source>Disable Trophy Notification</source>
<translation>Disable Trophy Pop-ups</translation> <translation>Disable Trophy Notification</translation>
</message> </message>
<message> <message>
<source>Background Image</source> <source>Background Image</source>
@ -1611,6 +1631,10 @@
<source>Update Compatibility Database:\nImmediately update the compatibility database.</source> <source>Update Compatibility Database:\nImmediately update the compatibility database.</source>
<translation>Update Compatibility Database:\nImmediately update the compatibility database.</translation> <translation>Update Compatibility Database:\nImmediately update the compatibility database.</translation>
</message> </message>
<message>
<source>Open the custom trophy images/sounds folder:\nYou can add custom images to the trophies and an audio.\nAdd the files to custom_trophy with the following names:\nthophy.mp3, bronze.png, gold.png, platinum.png, silver.png</source>
<translation>Open the custom trophy images/sounds folder:\nYou can add custom images to the trophies and an audio.\nAdd the files to custom_trophy with the following names:\nthophy.mp3, bronze.png, gold.png, platinum.png, silver.png</translation>
</message>
<message> <message>
<source>Never</source> <source>Never</source>
<translation>Never</translation> <translation>Never</translation>
@ -1803,6 +1827,22 @@
<source>Separate Log Files:\nWrites a separate logfile for each game.</source> <source>Separate Log Files:\nWrites a separate logfile for each game.</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message>
<source>Trophy Notification Position</source>
<translation>Trophy Notification Position</translation>
</message>
<message>
<source>Left</source>
<translation>Left</translation>
</message>
<message>
<source>Right</source>
<translation>Right</translation>
</message>
<message>
<source>Notification Duration</source>
<translation>Notification Duration</translation>
</message>
</context> </context>
<context> <context>
<name>TrophyViewer</name> <name>TrophyViewer</name>
@ -1810,5 +1850,21 @@
<source>Trophy Viewer</source> <source>Trophy Viewer</source>
<translation>Trophy Viewer</translation> <translation>Trophy Viewer</translation>
</message> </message>
<message>
<source>Progress</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Show Earned Trophies</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Show Not Earned Trophies</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Show Hidden Trophies</source>
<translation type="unfinished"></translation>
</message>
</context> </context>
</TS> </TS>

View File

@ -411,7 +411,7 @@
</message> </message>
<message> <message>
<source>D-Pad</source> <source>D-Pad</source>
<translation type="unfinished">D-Pad</translation> <translation>Botones de dirección</translation>
</message> </message>
<message> <message>
<source>Up</source> <source>Up</source>
@ -419,27 +419,27 @@
</message> </message>
<message> <message>
<source>Left</source> <source>Left</source>
<translation type="unfinished">Left</translation> <translation>Izquierda</translation>
</message> </message>
<message> <message>
<source>Right</source> <source>Right</source>
<translation type="unfinished">Right</translation> <translation>Derecha</translation>
</message> </message>
<message> <message>
<source>Down</source> <source>Down</source>
<translation type="unfinished">Down</translation> <translation>Abajo</translation>
</message> </message>
<message> <message>
<source>Left Stick Deadzone (def:2 max:127)</source> <source>Left Stick Deadzone (def:2 max:127)</source>
<translation type="unfinished">Left Stick Deadzone (def:2 max:127)</translation> <translation>Zona muerta del stick izquierdo (defecto: 2, máx.: 127)</translation>
</message> </message>
<message> <message>
<source>Left Deadzone</source> <source>Left Deadzone</source>
<translation type="unfinished">Left Deadzone</translation> <translation>Zona muerta del stick izquierdo</translation>
</message> </message>
<message> <message>
<source>Left Stick</source> <source>Left Stick</source>
<translation type="unfinished">Left Stick</translation> <translation>Stick izquierdo</translation>
</message> </message>
<message> <message>
<source>Config Selection</source> <source>Config Selection</source>
@ -455,31 +455,31 @@
</message> </message>
<message> <message>
<source>L1 / LB</source> <source>L1 / LB</source>
<translation type="unfinished">L1 / LB</translation> <translation>L1/LB</translation>
</message> </message>
<message> <message>
<source>L2 / LT</source> <source>L2 / LT</source>
<translation type="unfinished">L2 / LT</translation> <translation>L2/LT</translation>
</message> </message>
<message> <message>
<source>Back</source> <source>Back</source>
<translation type="unfinished">Back</translation> <translation>Back</translation>
</message> </message>
<message> <message>
<source>R1 / RB</source> <source>R1 / RB</source>
<translation type="unfinished">R1 / RB</translation> <translation>R1/RB</translation>
</message> </message>
<message> <message>
<source>R2 / RT</source> <source>R2 / RT</source>
<translation type="unfinished">R2 / RT</translation> <translation>R2/RT</translation>
</message> </message>
<message> <message>
<source>L3</source> <source>L3</source>
<translation type="unfinished">L3</translation> <translation>L3</translation>
</message> </message>
<message> <message>
<source>Options / Start</source> <source>Options / Start</source>
<translation type="unfinished">Options / Start</translation> <translation>Options/Start</translation>
</message> </message>
<message> <message>
<source>R3</source> <source>R3</source>
@ -487,19 +487,19 @@
</message> </message>
<message> <message>
<source>Face Buttons</source> <source>Face Buttons</source>
<translation type="unfinished">Face Buttons</translation> <translation>Botones de acción</translation>
</message> </message>
<message> <message>
<source>Triangle / Y</source> <source>Triangle / Y</source>
<translation type="unfinished">Triangle / Y</translation> <translation>Triángulo/Y</translation>
</message> </message>
<message> <message>
<source>Square / X</source> <source>Square / X</source>
<translation type="unfinished">Square / X</translation> <translation>Cuadrado/X</translation>
</message> </message>
<message> <message>
<source>Circle / B</source> <source>Circle / B</source>
<translation type="unfinished">Circle / B</translation> <translation>Círculo/B</translation>
</message> </message>
<message> <message>
<source>Cross / A</source> <source>Cross / A</source>
@ -507,31 +507,31 @@
</message> </message>
<message> <message>
<source>Right Stick Deadzone (def:2, max:127)</source> <source>Right Stick Deadzone (def:2, max:127)</source>
<translation type="unfinished">Right Stick Deadzone (def:2, max:127)</translation> <translation>Zona muerta del stick derecho (defecto: 2, máx.: 127)</translation>
</message> </message>
<message> <message>
<source>Right Deadzone</source> <source>Right Deadzone</source>
<translation type="unfinished">Right Deadzone</translation> <translation>Zona muerta del stick derecho</translation>
</message> </message>
<message> <message>
<source>Right Stick</source> <source>Right Stick</source>
<translation type="unfinished">Right Stick</translation> <translation>Stick derecho</translation>
</message> </message>
<message> <message>
<source>Color Adjustment</source> <source>Color Adjustment</source>
<translation type="unfinished">Color Adjustment</translation> <translation>Calibración de color</translation>
</message> </message>
<message> <message>
<source>R:</source> <source>R:</source>
<translation type="unfinished">R:</translation> <translation>R:</translation>
</message> </message>
<message> <message>
<source>G:</source> <source>G:</source>
<translation type="unfinished">G:</translation> <translation>V:</translation>
</message> </message>
<message> <message>
<source>B:</source> <source>B:</source>
<translation type="unfinished">B:</translation> <translation>A:</translation>
</message> </message>
<message> <message>
<source>Override Lightbar Color</source> <source>Override Lightbar Color</source>
@ -580,11 +580,11 @@
</message> </message>
<message> <message>
<source>Error</source> <source>Error</source>
<translation type="unfinished">Error</translation> <translation>Error</translation>
</message> </message>
<message> <message>
<source>Directory to install DLC</source> <source>Directory to install DLC</source>
<translation type="unfinished">Directory to install DLC</translation> <translation>Carpeta para instalar DLC</translation>
</message> </message>
</context> </context>
<context> <context>
@ -603,7 +603,7 @@
</message> </message>
<message> <message>
<source>Compatibility</source> <source>Compatibility</source>
<translation type="unfinished">Compatibility</translation> <translation>Compatibilidad</translation>
</message> </message>
<message> <message>
<source>Region</source> <source>Region</source>
@ -611,7 +611,7 @@
</message> </message>
<message> <message>
<source>Firmware</source> <source>Firmware</source>
<translation type="unfinished">Firmware</translation> <translation>Firmware</translation>
</message> </message>
<message> <message>
<source>Size</source> <source>Size</source>
@ -635,31 +635,31 @@
</message> </message>
<message> <message>
<source>h</source> <source>h</source>
<translation type="unfinished">h</translation> <translation>h</translation>
</message> </message>
<message> <message>
<source>m</source> <source>m</source>
<translation type="unfinished">m</translation> <translation>m</translation>
</message> </message>
<message> <message>
<source>s</source> <source>s</source>
<translation type="unfinished">s</translation> <translation>s</translation>
</message> </message>
<message> <message>
<source>Compatibility is untested</source> <source>Compatibility is untested</source>
<translation type="unfinished">Compatibility is untested</translation> <translation>Compatibilidad no comprobada</translation>
</message> </message>
<message> <message>
<source>Game does not initialize properly / crashes the emulator</source> <source>Game does not initialize properly / crashes the emulator</source>
<translation type="unfinished">Game does not initialize properly / crashes the emulator</translation> <translation>El juego no se inicia correctamente o cuelga el emulador</translation>
</message> </message>
<message> <message>
<source>Game boots, but only displays a blank screen</source> <source>Game boots, but only displays a blank screen</source>
<translation type="unfinished">Game boots, but only displays a blank screen</translation> <translation>El juego arranca, pero se queda en blanco</translation>
</message> </message>
<message> <message>
<source>Game displays an image but does not go past the menu</source> <source>Game displays an image but does not go past the menu</source>
<translation type="unfinished">Game displays an image but does not go past the menu</translation> <translation>El juego muestra imágenes, pero no va más allá de los menús</translation>
</message> </message>
<message> <message>
<source>Game has game-breaking glitches or unplayable performance</source> <source>Game has game-breaking glitches or unplayable performance</source>
@ -667,7 +667,7 @@
</message> </message>
<message> <message>
<source>Game can be completed with playable performance and no major glitches</source> <source>Game can be completed with playable performance and no major glitches</source>
<translation type="unfinished">Game can be completed with playable performance and no major glitches</translation> <translation>El juego puede completarse con un rendimiento jugable y sin errores de importancia</translation>
</message> </message>
<message> <message>
<source>Click to see details on github</source> <source>Click to see details on github</source>
@ -682,19 +682,19 @@
<name>GameListUtils</name> <name>GameListUtils</name>
<message> <message>
<source>B</source> <source>B</source>
<translation type="unfinished">B</translation> <translation>B</translation>
</message> </message>
<message> <message>
<source>KB</source> <source>KB</source>
<translation type="unfinished">KB</translation> <translation>KB</translation>
</message> </message>
<message> <message>
<source>MB</source> <source>MB</source>
<translation type="unfinished">MB</translation> <translation>MB</translation>
</message> </message>
<message> <message>
<source>GB</source> <source>GB</source>
<translation type="unfinished">GB</translation> <translation>GB</translation>
</message> </message>
<message> <message>
<source>TB</source> <source>TB</source>
@ -749,7 +749,7 @@
</message> </message>
<message> <message>
<source>Copy Version</source> <source>Copy Version</source>
<translation type="unfinished">Copy Version</translation> <translation>Copiar versión</translation>
</message> </message>
<message> <message>
<source>Copy Size</source> <source>Copy Size</source>
@ -761,11 +761,11 @@
</message> </message>
<message> <message>
<source>Delete...</source> <source>Delete...</source>
<translation type="unfinished">Delete...</translation> <translation>Eliminar...</translation>
</message> </message>
<message> <message>
<source>Delete Game</source> <source>Delete Game</source>
<translation type="unfinished">Delete Game</translation> <translation>Eliminar juego</translation>
</message> </message>
<message> <message>
<source>Delete Update</source> <source>Delete Update</source>
@ -773,23 +773,23 @@
</message> </message>
<message> <message>
<source>Delete DLC</source> <source>Delete DLC</source>
<translation type="unfinished">Delete DLC</translation> <translation>Eliminar DLC</translation>
</message> </message>
<message> <message>
<source>Compatibility...</source> <source>Compatibility...</source>
<translation type="unfinished">Compatibility...</translation> <translation>Compatibilidad...</translation>
</message> </message>
<message> <message>
<source>Update database</source> <source>Update database</source>
<translation type="unfinished">Update database</translation> <translation>Actualizar base de datos</translation>
</message> </message>
<message> <message>
<source>View report</source> <source>View report</source>
<translation type="unfinished">View report</translation> <translation>Ver informe</translation>
</message> </message>
<message> <message>
<source>Submit a report</source> <source>Submit a report</source>
<translation type="unfinished">Submit a report</translation> <translation>Enviar un informe</translation>
</message> </message>
<message> <message>
<source>Shortcut creation</source> <source>Shortcut creation</source>
@ -801,7 +801,7 @@
</message> </message>
<message> <message>
<source>Error</source> <source>Error</source>
<translation type="unfinished">Error</translation> <translation>Error</translation>
</message> </message>
<message> <message>
<source>Error creating shortcut!</source> <source>Error creating shortcut!</source>
@ -813,59 +813,59 @@
</message> </message>
<message> <message>
<source>Game</source> <source>Game</source>
<translation type="unfinished">Game</translation> <translation>Juego</translation>
</message> </message>
<message> <message>
<source>This game has no update to delete!</source> <source>This game has no update to delete!</source>
<translation type="unfinished">This game has no update to delete!</translation> <translation>¡Este juego no tiene actualizaciones!</translation>
</message> </message>
<message> <message>
<source>Update</source> <source>Update</source>
<translation type="unfinished">Update</translation> <translation>Actualización</translation>
</message> </message>
<message> <message>
<source>This game has no DLC to delete!</source> <source>This game has no DLC to delete!</source>
<translation type="unfinished">This game has no DLC to delete!</translation> <translation>¡Este juego no tiene DLCs!</translation>
</message> </message>
<message> <message>
<source>DLC</source> <source>DLC</source>
<translation type="unfinished">DLC</translation> <translation>DLC</translation>
</message> </message>
<message> <message>
<source>Delete %1</source> <source>Delete %1</source>
<translation type="unfinished">Delete %1</translation> <translation>Eliminar %1</translation>
</message> </message>
<message> <message>
<source>Are you sure you want to delete %1&apos;s %2 directory?</source> <source>Are you sure you want to delete %1&apos;s %2 directory?</source>
<translation type="unfinished">Are you sure you want to delete %1&apos;s %2 directory?</translation> <translation>¿Seguro que quieres eliminar el directorio %2 de %1?</translation>
</message> </message>
<message> <message>
<source>Open Update Folder</source> <source>Open Update Folder</source>
<translation type="unfinished">Open Update Folder</translation> <translation>Abrir carpeta de actualizaciones</translation>
</message> </message>
<message> <message>
<source>Delete Save Data</source> <source>Delete Save Data</source>
<translation type="unfinished">Delete Save Data</translation> <translation>Eliminar datos guardados</translation>
</message> </message>
<message> <message>
<source>This game has no update folder to open!</source> <source>This game has no update folder to open!</source>
<translation type="unfinished">This game has no update folder to open!</translation> <translation>¡Este juego no tiene carpeta de actualizaciones!</translation>
</message> </message>
<message> <message>
<source>Failed to convert icon.</source> <source>Failed to convert icon.</source>
<translation type="unfinished">Failed to convert icon.</translation> <translation>Error al convertir el icono.</translation>
</message> </message>
<message> <message>
<source>This game has no save data to delete!</source> <source>This game has no save data to delete!</source>
<translation type="unfinished">This game has no save data to delete!</translation> <translation>¡Este juego no tiene datos guardados!</translation>
</message> </message>
<message> <message>
<source>Save Data</source> <source>Save Data</source>
<translation type="unfinished">Save Data</translation> <translation>Datos guardados</translation>
</message> </message>
<message> <message>
<source>SFO Viewer for </source> <source>SFO Viewer for </source>
<translation type="unfinished">SFO Viewer for </translation> <translation>Visualizador de SFO para </translation>
</message> </message>
</context> </context>
<context> <context>
@ -876,15 +876,15 @@
</message> </message>
<message> <message>
<source>Select which directory you want to install to.</source> <source>Select which directory you want to install to.</source>
<translation type="unfinished">Select which directory you want to install to.</translation> <translation>Selecciona el directorio de instalación.</translation>
</message> </message>
<message> <message>
<source>Install All Queued to Selected Folder</source> <source>Install All Queued to Selected Folder</source>
<translation type="unfinished">Install All Queued to Selected Folder</translation> <translation>Instalar toda la cola en la carpeta seleccionada</translation>
</message> </message>
<message> <message>
<source>Delete PKG File on Install</source> <source>Delete PKG File on Install</source>
<translation type="unfinished">Delete PKG File on Install</translation> <translation>Eliminar archivo PKG tras la instalación</translation>
</message> </message>
</context> </context>
<context> <context>
@ -923,7 +923,7 @@
</message> </message>
<message> <message>
<source>Open shadPS4 Folder</source> <source>Open shadPS4 Folder</source>
<translation type="unfinished">Open shadPS4 Folder</translation> <translation>Abrir carpeta de shadPS4</translation>
</message> </message>
<message> <message>
<source>Exit</source> <source>Exit</source>
@ -1163,7 +1163,7 @@
</message> </message>
<message> <message>
<source>Run Game</source> <source>Run Game</source>
<translation type="unfinished">Run Game</translation> <translation>Ejecutar juego</translation>
</message> </message>
<message> <message>
<source>Eboot.bin file not found</source> <source>Eboot.bin file not found</source>
@ -1171,19 +1171,19 @@
</message> </message>
<message> <message>
<source>PKG File (*.PKG *.pkg)</source> <source>PKG File (*.PKG *.pkg)</source>
<translation type="unfinished">PKG File (*.PKG *.pkg)</translation> <translation>Archivo PKG (*.PKG *.pkg)</translation>
</message> </message>
<message> <message>
<source>PKG is a patch or DLC, please install the game first!</source> <source>PKG is a patch or DLC, please install the game first!</source>
<translation type="unfinished">PKG is a patch or DLC, please install the game first!</translation> <translation>El archivo PKG es un parche o un DLC, ¡debes instalar el juego primero!</translation>
</message> </message>
<message> <message>
<source>Game is already running!</source> <source>Game is already running!</source>
<translation type="unfinished">Game is already running!</translation> <translation>¡El juego ya se está ejecutando!</translation>
</message> </message>
<message> <message>
<source>shadPS4</source> <source>shadPS4</source>
<translation type="unfinished">shadPS4</translation> <translation>shadPS4</translation>
</message> </message>
</context> </context>
<context> <context>
@ -1214,19 +1214,19 @@
</message> </message>
<message> <message>
<source>Category</source> <source>Category</source>
<translation type="unfinished">Category</translation> <translation>Categoría</translation>
</message> </message>
<message> <message>
<source>Type</source> <source>Type</source>
<translation type="unfinished">Type</translation> <translation>Tipo</translation>
</message> </message>
<message> <message>
<source>App Ver</source> <source>App Ver</source>
<translation type="unfinished">App Ver</translation> <translation>Versión de aplicación</translation>
</message> </message>
<message> <message>
<source>FW</source> <source>FW</source>
<translation type="unfinished">FW</translation> <translation>FW</translation>
</message> </message>
<message> <message>
<source>Region</source> <source>Region</source>
@ -1234,7 +1234,7 @@
</message> </message>
<message> <message>
<source>Flags</source> <source>Flags</source>
<translation type="unfinished">Flags</translation> <translation>Etiquetas</translation>
</message> </message>
<message> <message>
<source>Path</source> <source>Path</source>
@ -1250,7 +1250,7 @@
</message> </message>
<message> <message>
<source>Package</source> <source>Package</source>
<translation type="unfinished">Package</translation> <translation>Paquete</translation>
</message> </message>
</context> </context>
<context> <context>
@ -1261,7 +1261,7 @@
</message> </message>
<message> <message>
<source>General</source> <source>General</source>
<translation type="unfinished">General</translation> <translation>General</translation>
</message> </message>
<message> <message>
<source>System</source> <source>System</source>
@ -1281,7 +1281,7 @@
</message> </message>
<message> <message>
<source>Enable Separate Update Folder</source> <source>Enable Separate Update Folder</source>
<translation type="unfinished">Enable Separate Update Folder</translation> <translation>Habilitar carpeta independiente de actualizaciones</translation>
</message> </message>
<message> <message>
<source>Default tab when opening settings</source> <source>Default tab when opening settings</source>
@ -1305,11 +1305,11 @@
</message> </message>
<message> <message>
<source>Trophy Key</source> <source>Trophy Key</source>
<translation type="unfinished">Trophy Key</translation> <translation>Clave de trofeos</translation>
</message> </message>
<message> <message>
<source>Trophy</source> <source>Trophy</source>
<translation type="unfinished">Trophy</translation> <translation>Trofeo</translation>
</message> </message>
<message> <message>
<source>Logger</source> <source>Logger</source>
@ -1333,7 +1333,7 @@
</message> </message>
<message> <message>
<source>Cursor</source> <source>Cursor</source>
<translation type="unfinished">Cursor</translation> <translation>Cursor</translation>
</message> </message>
<message> <message>
<source>Hide Cursor</source> <source>Hide Cursor</source>
@ -1345,7 +1345,7 @@
</message> </message>
<message> <message>
<source>s</source> <source>s</source>
<translation type="unfinished">s</translation> <translation>s</translation>
</message> </message>
<message> <message>
<source>Controller</source> <source>Controller</source>
@ -1389,7 +1389,7 @@
</message> </message>
<message> <message>
<source>Enable HDR</source> <source>Enable HDR</source>
<translation type="unfinished">Enable HDR</translation> <translation>Habilitar HDR</translation>
</message> </message>
<message> <message>
<source>Paths</source> <source>Paths</source>
@ -1429,15 +1429,15 @@
</message> </message>
<message> <message>
<source>Enable Crash Diagnostics</source> <source>Enable Crash Diagnostics</source>
<translation type="unfinished">Enable Crash Diagnostics</translation> <translation>Habilitar diagnóstico de fallos</translation>
</message> </message>
<message> <message>
<source>Collect Shaders</source> <source>Collect Shaders</source>
<translation type="unfinished">Collect Shaders</translation> <translation>Recopilar shaders</translation>
</message> </message>
<message> <message>
<source>Copy GPU Buffers</source> <source>Copy GPU Buffers</source>
<translation type="unfinished">Copy GPU Buffers</translation> <translation>Copiar búferes de GPU</translation>
</message> </message>
<message> <message>
<source>Host Debug Markers</source> <source>Host Debug Markers</source>
@ -1473,11 +1473,11 @@
</message> </message>
<message> <message>
<source>Title Music</source> <source>Title Music</source>
<translation type="unfinished">Title Music</translation> <translation>Música de título</translation>
</message> </message>
<message> <message>
<source>Disable Trophy Pop-ups</source> <source>Disable Trophy Pop-ups</source>
<translation type="unfinished">Disable Trophy Pop-ups</translation> <translation>Deshabilitar mensajes de trofeos</translation>
</message> </message>
<message> <message>
<source>Background Image</source> <source>Background Image</source>
@ -1497,7 +1497,7 @@
</message> </message>
<message> <message>
<source>Update Compatibility Database On Startup</source> <source>Update Compatibility Database On Startup</source>
<translation type="unfinished">Update Compatibility Database On Startup</translation> <translation>Actualizar base de datos de compatibilidad al iniciar</translation>
</message> </message>
<message> <message>
<source>Game Compatibility</source> <source>Game Compatibility</source>
@ -1505,11 +1505,11 @@
</message> </message>
<message> <message>
<source>Display Compatibility Data</source> <source>Display Compatibility Data</source>
<translation type="unfinished">Display Compatibility Data</translation> <translation>Mostrar datos de compatibilidad</translation>
</message> </message>
<message> <message>
<source>Update Compatibility Database</source> <source>Update Compatibility Database</source>
<translation type="unfinished">Update Compatibility Database</translation> <translation>Actualizar base de datos de compatibilidad</translation>
</message> </message>
<message> <message>
<source>Volume</source> <source>Volume</source>
@ -1721,11 +1721,11 @@
</message> </message>
<message> <message>
<source>Release</source> <source>Release</source>
<translation type="unfinished">Release</translation> <translation>Principal</translation>
</message> </message>
<message> <message>
<source>Nightly</source> <source>Nightly</source>
<translation type="unfinished">Nightly</translation> <translation>Nightly</translation>
</message> </message>
<message> <message>
<source>Set the volume of the background music.</source> <source>Set the volume of the background music.</source>
@ -1733,11 +1733,11 @@
</message> </message>
<message> <message>
<source>Enable Motion Controls</source> <source>Enable Motion Controls</source>
<translation type="unfinished">Enable Motion Controls</translation> <translation>Habilitar controles de movimiento</translation>
</message> </message>
<message> <message>
<source>Save Data Path</source> <source>Save Data Path</source>
<translation type="unfinished">Save Data Path</translation> <translation>Ruta de datos guardados</translation>
</message> </message>
<message> <message>
<source>Browse</source> <source>Browse</source>
@ -1753,7 +1753,7 @@
</message> </message>
<message> <message>
<source>Auto Select</source> <source>Auto Select</source>
<translation type="unfinished">Auto Select</translation> <translation>Selección automática</translation>
</message> </message>
<message> <message>
<source>Directory to install games</source> <source>Directory to install games</source>
@ -1761,39 +1761,39 @@
</message> </message>
<message> <message>
<source>Directory to save data</source> <source>Directory to save data</source>
<translation type="unfinished">Directory to save data</translation> <translation>Directorio para guardar datos</translation>
</message> </message>
<message> <message>
<source>Video</source> <source>Video</source>
<translation type="unfinished">Video</translation> <translation>deo</translation>
</message> </message>
<message> <message>
<source>Display Mode</source> <source>Display Mode</source>
<translation type="unfinished">Display Mode</translation> <translation>Modo de imagen</translation>
</message> </message>
<message> <message>
<source>Windowed</source> <source>Windowed</source>
<translation type="unfinished">Windowed</translation> <translation>Ventana</translation>
</message> </message>
<message> <message>
<source>Fullscreen</source> <source>Fullscreen</source>
<translation type="unfinished">Fullscreen</translation> <translation>Pantalla completa</translation>
</message> </message>
<message> <message>
<source>Fullscreen (Borderless)</source> <source>Fullscreen (Borderless)</source>
<translation type="unfinished">Fullscreen (Borderless)</translation> <translation>Pantalla completa (sin bordes)</translation>
</message> </message>
<message> <message>
<source>Window Size</source> <source>Window Size</source>
<translation type="unfinished">Window Size</translation> <translation>Tamaño de ventana</translation>
</message> </message>
<message> <message>
<source>W:</source> <source>W:</source>
<translation type="unfinished">W:</translation> <translation>Ancho:</translation>
</message> </message>
<message> <message>
<source>H:</source> <source>H:</source>
<translation type="unfinished">H:</translation> <translation>Alto:</translation>
</message> </message>
<message> <message>
<source>Separate Log Files</source> <source>Separate Log Files</source>

View File

@ -519,19 +519,19 @@
</message> </message>
<message> <message>
<source>Color Adjustment</source> <source>Color Adjustment</source>
<translation type="unfinished">Color Adjustment</translation> <translation>Ajustement des couleurs</translation>
</message> </message>
<message> <message>
<source>R:</source> <source>R:</source>
<translation type="unfinished">R:</translation> <translation>R:</translation>
</message> </message>
<message> <message>
<source>G:</source> <source>G:</source>
<translation type="unfinished">G:</translation> <translation>G:</translation>
</message> </message>
<message> <message>
<source>B:</source> <source>B:</source>
<translation type="unfinished">B:</translation> <translation>B:</translation>
</message> </message>
<message> <message>
<source>Override Lightbar Color</source> <source>Override Lightbar Color</source>
@ -539,7 +539,7 @@
</message> </message>
<message> <message>
<source>Override Color</source> <source>Override Color</source>
<translation type="unfinished">Override Color</translation> <translation>Remplacer la couleur</translation>
</message> </message>
</context> </context>
<context> <context>
@ -1234,7 +1234,7 @@
</message> </message>
<message> <message>
<source>Flags</source> <source>Flags</source>
<translation type="unfinished">Flags</translation> <translation>Les indicateurs</translation>
</message> </message>
<message> <message>
<source>Path</source> <source>Path</source>
@ -1577,7 +1577,7 @@
</message> </message>
<message> <message>
<source>Background Image:\nControl the opacity of the game background image.</source> <source>Background Image:\nControl the opacity of the game background image.</source>
<translation type="unfinished">Background Image:\nControl the opacity of the game background image.</translation> <translation>Image de fond :\nContrôle l'opacité de l'image de fond du jeu.</translation>
</message> </message>
<message> <message>
<source>Play Title Music:\nIf a game supports it, enable playing special music when selecting the game in the GUI.</source> <source>Play Title Music:\nIf a game supports it, enable playing special music when selecting the game in the GUI.</source>
@ -1661,7 +1661,7 @@
</message> </message>
<message> <message>
<source>Enable HDR:\nEnables HDR in games that support it.\nYour monitor must have support for the BT2020 PQ color space and the RGB10A2 swapchain format.</source> <source>Enable HDR:\nEnables HDR in games that support it.\nYour monitor must have support for the BT2020 PQ color space and the RGB10A2 swapchain format.</source>
<translation type="unfinished">Enable HDR:\nEnables HDR in games that support it.\nYour monitor must have support for the BT2020 PQ color space and the RGB10A2 swapchain format.</translation> <translation>Activer HDR:\nActive le HDR dans les jeux qui le supportent.\nVotre moniteur doit avoir la prise en charge de l'espace couleur PQ BT2020 et du format swapchain RGB10A2.</translation>
</message> </message>
<message> <message>
<source>Game Folders:\nThe list of folders to check for installed games.</source> <source>Game Folders:\nThe list of folders to check for installed games.</source>
@ -1721,11 +1721,11 @@
</message> </message>
<message> <message>
<source>Release</source> <source>Release</source>
<translation type="unfinished">Release</translation> <translation>Sortie</translation>
</message> </message>
<message> <message>
<source>Nightly</source> <source>Nightly</source>
<translation type="unfinished">Nightly</translation> <translation>Nocturne</translation>
</message> </message>
<message> <message>
<source>Set the volume of the background music.</source> <source>Set the volume of the background music.</source>
@ -1737,7 +1737,7 @@
</message> </message>
<message> <message>
<source>Save Data Path</source> <source>Save Data Path</source>
<translation type="unfinished">Save Data Path</translation> <translation>Enregistrer le chemin vers les données</translation>
</message> </message>
<message> <message>
<source>Browse</source> <source>Browse</source>
@ -1745,15 +1745,15 @@
</message> </message>
<message> <message>
<source>async</source> <source>async</source>
<translation type="unfinished">async</translation> <translation>asynchrone</translation>
</message> </message>
<message> <message>
<source>sync</source> <source>sync</source>
<translation type="unfinished">sync</translation> <translation>synchrone</translation>
</message> </message>
<message> <message>
<source>Auto Select</source> <source>Auto Select</source>
<translation type="unfinished">Auto Select</translation> <translation>Sélection automatique</translation>
</message> </message>
<message> <message>
<source>Directory to install games</source> <source>Directory to install games</source>
@ -1761,39 +1761,39 @@
</message> </message>
<message> <message>
<source>Directory to save data</source> <source>Directory to save data</source>
<translation type="unfinished">Directory to save data</translation> <translation>Répertoire d'enregistrement des données</translation>
</message> </message>
<message> <message>
<source>Video</source> <source>Video</source>
<translation type="unfinished">Video</translation> <translation>Vidéo</translation>
</message> </message>
<message> <message>
<source>Display Mode</source> <source>Display Mode</source>
<translation type="unfinished">Display Mode</translation> <translation>Mode d'affichage</translation>
</message> </message>
<message> <message>
<source>Windowed</source> <source>Windowed</source>
<translation type="unfinished">Windowed</translation> <translation>Fenêtré</translation>
</message> </message>
<message> <message>
<source>Fullscreen</source> <source>Fullscreen</source>
<translation type="unfinished">Fullscreen</translation> <translation>Plein écran</translation>
</message> </message>
<message> <message>
<source>Fullscreen (Borderless)</source> <source>Fullscreen (Borderless)</source>
<translation type="unfinished">Fullscreen (Borderless)</translation> <translation>Plein écran (sans bordure)</translation>
</message> </message>
<message> <message>
<source>Window Size</source> <source>Window Size</source>
<translation type="unfinished">Window Size</translation> <translation>Taille de fenêtre</translation>
</message> </message>
<message> <message>
<source>W:</source> <source>W:</source>
<translation type="unfinished">W:</translation> <translation>W:</translation>
</message> </message>
<message> <message>
<source>H:</source> <source>H:</source>
<translation type="unfinished">H:</translation> <translation>H:</translation>
</message> </message>
<message> <message>
<source>Separate Log Files</source> <source>Separate Log Files</source>

View File

@ -22,7 +22,7 @@
<name>CheatsPatches</name> <name>CheatsPatches</name>
<message> <message>
<source>Cheats / Patches for </source> <source>Cheats / Patches for </source>
<translation>Kody / Łatki dla </translation> <translation>Kody / Poprawki dla </translation>
</message> </message>
<message> <message>
<source>Cheats/Patches are experimental.\nUse with caution.\n\nDownload cheats individually by selecting the repository and clicking the download button.\nIn the Patches tab, you can download all patches at once, choose which ones you want to use, and save your selection.\n\nSince we do not develop the Cheats/Patches,\nplease report issues to the cheat author.\n\nCreated a new cheat? Visit:\n</source> <source>Cheats/Patches are experimental.\nUse with caution.\n\nDownload cheats individually by selecting the repository and clicking the download button.\nIn the Patches tab, you can download all patches at once, choose which ones you want to use, and save your selection.\n\nSince we do not develop the Cheats/Patches,\nplease report issues to the cheat author.\n\nCreated a new cheat? Visit:\n</source>
@ -58,15 +58,15 @@
</message> </message>
<message> <message>
<source>Delete File</source> <source>Delete File</source>
<translation type="unfinished">Delete File</translation> <translation>Usuń plik</translation>
</message> </message>
<message> <message>
<source>No files selected.</source> <source>No files selected.</source>
<translation type="unfinished">No files selected.</translation> <translation>Nie wybrano pliku.</translation>
</message> </message>
<message> <message>
<source>You can delete the cheats you don&apos;t want after downloading them.</source> <source>You can delete the cheats you don&apos;t want after downloading them.</source>
<translation type="unfinished">You can delete the cheats you don&apos;t want after downloading them.</translation> <translation>Możesz usunąć kody, których nie chcesz po ich pobraniu.</translation>
</message> </message>
<message> <message>
<source>Do you want to delete the selected file?\n%1</source> <source>Do you want to delete the selected file?\n%1</source>
@ -202,7 +202,7 @@
</message> </message>
<message> <message>
<source>You may need to update your game.</source> <source>You may need to update your game.</source>
<translation>Możesz potrzebować zaktualizować swoją grę.</translation> <translation>Może być konieczne uaktualnienie gry.</translation>
</message> </message>
<message> <message>
<source>Incompatibility Notice</source> <source>Incompatibility Notice</source>
@ -230,11 +230,11 @@
</message> </message>
<message> <message>
<source>Failed to open files.json for reading.</source> <source>Failed to open files.json for reading.</source>
<translation type="unfinished">Failed to open files.json for reading.</translation> <translation>Nie można otworzyć pliku files.json do odczytu.</translation>
</message> </message>
<message> <message>
<source>Name:</source> <source>Name:</source>
<translation type="unfinished">Name:</translation> <translation>Nazwa:</translation>
</message> </message>
<message> <message>
<source>Can&apos;t apply cheats before the game is started</source> <source>Can&apos;t apply cheats before the game is started</source>
@ -249,7 +249,7 @@
<name>CheckUpdate</name> <name>CheckUpdate</name>
<message> <message>
<source>Auto Updater</source> <source>Auto Updater</source>
<translation>Automatyczne aktualizacje</translation> <translation>Asystent aktualizacji</translation>
</message> </message>
<message> <message>
<source>Error</source> <source>Error</source>
@ -289,7 +289,7 @@
</message> </message>
<message> <message>
<source>Update Channel</source> <source>Update Channel</source>
<translation>Kanał Aktualizacji</translation> <translation>Kanał aktualizacji</translation>
</message> </message>
<message> <message>
<source>Current Version</source> <source>Current Version</source>
@ -297,7 +297,7 @@
</message> </message>
<message> <message>
<source>Latest Version</source> <source>Latest Version</source>
<translation>Ostatnia wersja</translation> <translation>Najnowsza wersja</translation>
</message> </message>
<message> <message>
<source>Do you want to update?</source> <source>Do you want to update?</source>
@ -388,7 +388,7 @@
</message> </message>
<message> <message>
<source>Boots</source> <source>Boots</source>
<translation>Buty</translation> <translation>Uruchamia się</translation>
</message> </message>
<message> <message>
<source>Menus</source> <source>Menus</source>
@ -400,146 +400,146 @@
</message> </message>
<message> <message>
<source>Playable</source> <source>Playable</source>
<translation>Do grania</translation> <translation>Grywalne</translation>
</message> </message>
</context> </context>
<context> <context>
<name>ControlSettings</name> <name>ControlSettings</name>
<message> <message>
<source>Configure Controls</source> <source>Configure Controls</source>
<translation type="unfinished">Configure Controls</translation> <translation>Skonfiguruj sterowanie</translation>
</message> </message>
<message> <message>
<source>D-Pad</source> <source>D-Pad</source>
<translation type="unfinished">D-Pad</translation> <translation>Krzyżak</translation>
</message> </message>
<message> <message>
<source>Up</source> <source>Up</source>
<translation type="unfinished">Up</translation> <translation>Góra</translation>
</message> </message>
<message> <message>
<source>Left</source> <source>Left</source>
<translation type="unfinished">Left</translation> <translation>Lewo</translation>
</message> </message>
<message> <message>
<source>Right</source> <source>Right</source>
<translation type="unfinished">Right</translation> <translation>Prawo</translation>
</message> </message>
<message> <message>
<source>Down</source> <source>Down</source>
<translation type="unfinished">Down</translation> <translation>Dół</translation>
</message> </message>
<message> <message>
<source>Left Stick Deadzone (def:2 max:127)</source> <source>Left Stick Deadzone (def:2 max:127)</source>
<translation type="unfinished">Left Stick Deadzone (def:2 max:127)</translation> <translation>Martwa strefa lewego drążka (def:2 max:127)</translation>
</message> </message>
<message> <message>
<source>Left Deadzone</source> <source>Left Deadzone</source>
<translation type="unfinished">Left Deadzone</translation> <translation>Martwa strefa lewego drążka</translation>
</message> </message>
<message> <message>
<source>Left Stick</source> <source>Left Stick</source>
<translation type="unfinished">Left Stick</translation> <translation>Lewy drążek</translation>
</message> </message>
<message> <message>
<source>Config Selection</source> <source>Config Selection</source>
<translation type="unfinished">Config Selection</translation> <translation>Wybór konfiguracji</translation>
</message> </message>
<message> <message>
<source>Common Config</source> <source>Common Config</source>
<translation type="unfinished">Common Config</translation> <translation>Typowa konfiguracja</translation>
</message> </message>
<message> <message>
<source>Use per-game configs</source> <source>Use per-game configs</source>
<translation type="unfinished">Use per-game configs</translation> <translation>Użyj osobnej konfiguracji dla każdej gry</translation>
</message> </message>
<message> <message>
<source>L1 / LB</source> <source>L1 / LB</source>
<translation type="unfinished">L1 / LB</translation> <translation>L1 / LB</translation>
</message> </message>
<message> <message>
<source>L2 / LT</source> <source>L2 / LT</source>
<translation type="unfinished">L2 / LT</translation> <translation>L2 / LT</translation>
</message> </message>
<message> <message>
<source>Back</source> <source>Back</source>
<translation type="unfinished">Back</translation> <translation>Wstecz</translation>
</message> </message>
<message> <message>
<source>R1 / RB</source> <source>R1 / RB</source>
<translation type="unfinished">R1 / RB</translation> <translation>R1 / RB</translation>
</message> </message>
<message> <message>
<source>R2 / RT</source> <source>R2 / RT</source>
<translation type="unfinished">R2 / RT</translation> <translation>R2 / RT</translation>
</message> </message>
<message> <message>
<source>L3</source> <source>L3</source>
<translation type="unfinished">L3</translation> <translation>L3</translation>
</message> </message>
<message> <message>
<source>Options / Start</source> <source>Options / Start</source>
<translation type="unfinished">Options / Start</translation> <translation>Opcje / Start</translation>
</message> </message>
<message> <message>
<source>R3</source> <source>R3</source>
<translation type="unfinished">R3</translation> <translation>R3</translation>
</message> </message>
<message> <message>
<source>Face Buttons</source> <source>Face Buttons</source>
<translation type="unfinished">Face Buttons</translation> <translation>Przyciski akcji</translation>
</message> </message>
<message> <message>
<source>Triangle / Y</source> <source>Triangle / Y</source>
<translation type="unfinished">Triangle / Y</translation> <translation>Trójkąt / Y</translation>
</message> </message>
<message> <message>
<source>Square / X</source> <source>Square / X</source>
<translation type="unfinished">Square / X</translation> <translation>Kwadrat / X</translation>
</message> </message>
<message> <message>
<source>Circle / B</source> <source>Circle / B</source>
<translation type="unfinished">Circle / B</translation> <translation>Kółko / B</translation>
</message> </message>
<message> <message>
<source>Cross / A</source> <source>Cross / A</source>
<translation type="unfinished">Cross / A</translation> <translation>Krzyżyk / A</translation>
</message> </message>
<message> <message>
<source>Right Stick Deadzone (def:2, max:127)</source> <source>Right Stick Deadzone (def:2, max:127)</source>
<translation type="unfinished">Right Stick Deadzone (def:2, max:127)</translation> <translation>Martwa strefa prawego drążka (def:2 max:127)</translation>
</message> </message>
<message> <message>
<source>Right Deadzone</source> <source>Right Deadzone</source>
<translation type="unfinished">Right Deadzone</translation> <translation>Martwa strefa prawego drążka</translation>
</message> </message>
<message> <message>
<source>Right Stick</source> <source>Right Stick</source>
<translation type="unfinished">Right Stick</translation> <translation>Prawy drążek</translation>
</message> </message>
<message> <message>
<source>Color Adjustment</source> <source>Color Adjustment</source>
<translation type="unfinished">Color Adjustment</translation> <translation>Dostosowanie koloru</translation>
</message> </message>
<message> <message>
<source>R:</source> <source>R:</source>
<translation type="unfinished">R:</translation> <translation>Czerwony:</translation>
</message> </message>
<message> <message>
<source>G:</source> <source>G:</source>
<translation type="unfinished">G:</translation> <translation>Zielony:</translation>
</message> </message>
<message> <message>
<source>B:</source> <source>B:</source>
<translation type="unfinished">B:</translation> <translation>Niebieski:</translation>
</message> </message>
<message> <message>
<source>Override Lightbar Color</source> <source>Override Lightbar Color</source>
<translation type="unfinished">Override Lightbar Color</translation> <translation>Zastąp kolor paska świetlnego</translation>
</message> </message>
<message> <message>
<source>Override Color</source> <source>Override Color</source>
<translation type="unfinished">Override Color</translation> <translation>Zastąp kolor</translation>
</message> </message>
</context> </context>
<context> <context>
@ -584,7 +584,7 @@
</message> </message>
<message> <message>
<source>Directory to install DLC</source> <source>Directory to install DLC</source>
<translation type="unfinished">Directory to install DLC</translation> <translation>Katalog do instalacji dodatkowej zawartości (DLC)</translation>
</message> </message>
</context> </context>
<context> <context>
@ -603,11 +603,11 @@
</message> </message>
<message> <message>
<source>Compatibility</source> <source>Compatibility</source>
<translation>Zgodność</translation> <translation>Kompatybilność</translation>
</message> </message>
<message> <message>
<source>Region</source> <source>Region</source>
<translation type="unfinished">Region</translation> <translation>Region</translation>
</message> </message>
<message> <message>
<source>Firmware</source> <source>Firmware</source>
@ -635,15 +635,15 @@
</message> </message>
<message> <message>
<source>h</source> <source>h</source>
<translation type="unfinished">h</translation> <translation>godz.</translation>
</message> </message>
<message> <message>
<source>m</source> <source>m</source>
<translation type="unfinished">m</translation> <translation>min</translation>
</message> </message>
<message> <message>
<source>s</source> <source>s</source>
<translation type="unfinished">s</translation> <translation>s</translation>
</message> </message>
<message> <message>
<source>Compatibility is untested</source> <source>Compatibility is untested</source>
@ -682,23 +682,23 @@
<name>GameListUtils</name> <name>GameListUtils</name>
<message> <message>
<source>B</source> <source>B</source>
<translation type="unfinished">B</translation> <translation>B</translation>
</message> </message>
<message> <message>
<source>KB</source> <source>KB</source>
<translation type="unfinished">KB</translation> <translation>KB</translation>
</message> </message>
<message> <message>
<source>MB</source> <source>MB</source>
<translation type="unfinished">MB</translation> <translation>MB</translation>
</message> </message>
<message> <message>
<source>GB</source> <source>GB</source>
<translation type="unfinished">GB</translation> <translation>GB</translation>
</message> </message>
<message> <message>
<source>TB</source> <source>TB</source>
<translation type="unfinished">TB</translation> <translation>TB</translation>
</message> </message>
</context> </context>
<context> <context>
@ -729,7 +729,7 @@
</message> </message>
<message> <message>
<source>Open Save Data Folder</source> <source>Open Save Data Folder</source>
<translation>Otwórz Folder Danych Zapisów</translation> <translation>Otwórz folder zapisanych danych</translation>
</message> </message>
<message> <message>
<source>Open Log Folder</source> <source>Open Log Folder</source>
@ -749,11 +749,11 @@
</message> </message>
<message> <message>
<source>Copy Version</source> <source>Copy Version</source>
<translation type="unfinished">Copy Version</translation> <translation>Kopiuj wersję</translation>
</message> </message>
<message> <message>
<source>Copy Size</source> <source>Copy Size</source>
<translation type="unfinished">Copy Size</translation> <translation>Kopiuj rozmiar</translation>
</message> </message>
<message> <message>
<source>Copy All</source> <source>Copy All</source>
@ -765,19 +765,19 @@
</message> </message>
<message> <message>
<source>Delete Game</source> <source>Delete Game</source>
<translation>Usuń G</translation> <translation>Usuń g</translation>
</message> </message>
<message> <message>
<source>Delete Update</source> <source>Delete Update</source>
<translation>Usuń Aktualizację</translation> <translation>Usuń aktualizację</translation>
</message> </message>
<message> <message>
<source>Delete DLC</source> <source>Delete DLC</source>
<translation>Usuń DLC</translation> <translation>Usuń dodatkową zawartość (DLC)</translation>
</message> </message>
<message> <message>
<source>Compatibility...</source> <source>Compatibility...</source>
<translation>kompatybilność...</translation> <translation>Kompatybilność...</translation>
</message> </message>
<message> <message>
<source>Update database</source> <source>Update database</source>
@ -825,11 +825,11 @@
</message> </message>
<message> <message>
<source>This game has no DLC to delete!</source> <source>This game has no DLC to delete!</source>
<translation>Ta gra nie ma DLC do usunięcia!</translation> <translation>Ta gra nie ma dodatkowej zawartości (DLC) do usunięcia!</translation>
</message> </message>
<message> <message>
<source>DLC</source> <source>DLC</source>
<translation type="unfinished">DLC</translation> <translation>Dodatkowa zawartość (DLC)</translation>
</message> </message>
<message> <message>
<source>Delete %1</source> <source>Delete %1</source>
@ -841,31 +841,31 @@
</message> </message>
<message> <message>
<source>Open Update Folder</source> <source>Open Update Folder</source>
<translation type="unfinished">Open Update Folder</translation> <translation>Otwórz folder aktualizacji</translation>
</message> </message>
<message> <message>
<source>Delete Save Data</source> <source>Delete Save Data</source>
<translation type="unfinished">Delete Save Data</translation> <translation>Usuń zapisane dane</translation>
</message> </message>
<message> <message>
<source>This game has no update folder to open!</source> <source>This game has no update folder to open!</source>
<translation type="unfinished">This game has no update folder to open!</translation> <translation>Ta gra nie ma folderu aktualizacji do otwarcia!</translation>
</message> </message>
<message> <message>
<source>Failed to convert icon.</source> <source>Failed to convert icon.</source>
<translation type="unfinished">Failed to convert icon.</translation> <translation>Nie udało się przekonwertować ikony.</translation>
</message> </message>
<message> <message>
<source>This game has no save data to delete!</source> <source>This game has no save data to delete!</source>
<translation type="unfinished">This game has no save data to delete!</translation> <translation>Ta gra nie ma zapisów do usunięcia!</translation>
</message> </message>
<message> <message>
<source>Save Data</source> <source>Save Data</source>
<translation type="unfinished">Save Data</translation> <translation>Zapisane dane</translation>
</message> </message>
<message> <message>
<source>SFO Viewer for </source> <source>SFO Viewer for </source>
<translation type="unfinished">SFO Viewer for </translation> <translation>Menedżer plików SFO dla </translation>
</message> </message>
</context> </context>
<context> <context>
@ -880,11 +880,11 @@
</message> </message>
<message> <message>
<source>Install All Queued to Selected Folder</source> <source>Install All Queued to Selected Folder</source>
<translation type="unfinished">Install All Queued to Selected Folder</translation> <translation>Zainstaluj wszystkie oczekujące do wybranego folderu</translation>
</message> </message>
<message> <message>
<source>Delete PKG File on Install</source> <source>Delete PKG File on Install</source>
<translation type="unfinished">Delete PKG File on Install</translation> <translation>Usuń plik PKG po instalacji</translation>
</message> </message>
</context> </context>
<context> <context>
@ -1127,15 +1127,15 @@
</message> </message>
<message> <message>
<source>DLC Installation</source> <source>DLC Installation</source>
<translation>Instalacja DLC</translation> <translation>Instalacja dodatkowej zawartości (DLC)</translation>
</message> </message>
<message> <message>
<source>Would you like to install DLC: %1?</source> <source>Would you like to install DLC: %1?</source>
<translation>Czy chcesz zainstalować DLC: %1?</translation> <translation>Czy chcesz zainstalować dodatkową zawartość (DLC): %1?</translation>
</message> </message>
<message> <message>
<source>DLC already installed:</source> <source>DLC already installed:</source>
<translation>DLC już zainstalowane:</translation> <translation>Dodatkowa zawartość (DLC) już zainstalowana:</translation>
</message> </message>
<message> <message>
<source>Game already installed</source> <source>Game already installed</source>
@ -1163,27 +1163,27 @@
</message> </message>
<message> <message>
<source>Run Game</source> <source>Run Game</source>
<translation type="unfinished">Run Game</translation> <translation>Uruchom grę</translation>
</message> </message>
<message> <message>
<source>Eboot.bin file not found</source> <source>Eboot.bin file not found</source>
<translation type="unfinished">Eboot.bin file not found</translation> <translation>Nie znaleziono pliku EBOOT.BIN</translation>
</message> </message>
<message> <message>
<source>PKG File (*.PKG *.pkg)</source> <source>PKG File (*.PKG *.pkg)</source>
<translation type="unfinished">PKG File (*.PKG *.pkg)</translation> <translation>Plik PKG (*.PKG *.pkg)</translation>
</message> </message>
<message> <message>
<source>PKG is a patch or DLC, please install the game first!</source> <source>PKG is a patch or DLC, please install the game first!</source>
<translation type="unfinished">PKG is a patch or DLC, please install the game first!</translation> <translation>PKG jest aktualizacją lub dodatkową zawartością (DLC), najpierw zainstaluj grę!</translation>
</message> </message>
<message> <message>
<source>Game is already running!</source> <source>Game is already running!</source>
<translation type="unfinished">Game is already running!</translation> <translation>Gra jest już uruchomiona!</translation>
</message> </message>
<message> <message>
<source>shadPS4</source> <source>shadPS4</source>
<translation type="unfinished">shadPS4</translation> <translation>shadPS4</translation>
</message> </message>
</context> </context>
<context> <context>
@ -1206,7 +1206,7 @@
</message> </message>
<message> <message>
<source>Installed</source> <source>Installed</source>
<translation type="unfinished">Installed</translation> <translation>Zainstalowano</translation>
</message> </message>
<message> <message>
<source>Size</source> <source>Size</source>
@ -1214,27 +1214,27 @@
</message> </message>
<message> <message>
<source>Category</source> <source>Category</source>
<translation type="unfinished">Category</translation> <translation>Kategoria</translation>
</message> </message>
<message> <message>
<source>Type</source> <source>Type</source>
<translation type="unfinished">Type</translation> <translation>Typ</translation>
</message> </message>
<message> <message>
<source>App Ver</source> <source>App Ver</source>
<translation type="unfinished">App Ver</translation> <translation>Wersja aplikacji</translation>
</message> </message>
<message> <message>
<source>FW</source> <source>FW</source>
<translation type="unfinished">FW</translation> <translation>Oprogramowanie</translation>
</message> </message>
<message> <message>
<source>Region</source> <source>Region</source>
<translation type="unfinished">Region</translation> <translation>Region</translation>
</message> </message>
<message> <message>
<source>Flags</source> <source>Flags</source>
<translation type="unfinished">Flags</translation> <translation>Flagi</translation>
</message> </message>
<message> <message>
<source>Path</source> <source>Path</source>
@ -1250,7 +1250,7 @@
</message> </message>
<message> <message>
<source>Package</source> <source>Package</source>
<translation type="unfinished">Package</translation> <translation>Paczka</translation>
</message> </message>
</context> </context>
<context> <context>
@ -1265,7 +1265,7 @@
</message> </message>
<message> <message>
<source>System</source> <source>System</source>
<translation type="unfinished">System</translation> <translation>System</translation>
</message> </message>
<message> <message>
<source>Console Language</source> <source>Console Language</source>
@ -1277,7 +1277,7 @@
</message> </message>
<message> <message>
<source>Emulator</source> <source>Emulator</source>
<translation type="unfinished">Emulator</translation> <translation>Emulator</translation>
</message> </message>
<message> <message>
<source>Enable Separate Update Folder</source> <source>Enable Separate Update Folder</source>
@ -1329,7 +1329,7 @@
</message> </message>
<message> <message>
<source>Input</source> <source>Input</source>
<translation>Wejście</translation> <translation>Sterowanie</translation>
</message> </message>
<message> <message>
<source>Cursor</source> <source>Cursor</source>
@ -1345,7 +1345,7 @@
</message> </message>
<message> <message>
<source>s</source> <source>s</source>
<translation type="unfinished">s</translation> <translation>s</translation>
</message> </message>
<message> <message>
<source>Controller</source> <source>Controller</source>
@ -1389,7 +1389,7 @@
</message> </message>
<message> <message>
<source>Enable HDR</source> <source>Enable HDR</source>
<translation type="unfinished">Enable HDR</translation> <translation>Włącz HDR</translation>
</message> </message>
<message> <message>
<source>Paths</source> <source>Paths</source>
@ -1429,23 +1429,23 @@
</message> </message>
<message> <message>
<source>Enable Crash Diagnostics</source> <source>Enable Crash Diagnostics</source>
<translation type="unfinished">Enable Crash Diagnostics</translation> <translation>Włącz diagnostykę awarii</translation>
</message> </message>
<message> <message>
<source>Collect Shaders</source> <source>Collect Shaders</source>
<translation type="unfinished">Collect Shaders</translation> <translation>Zbieraj cienie</translation>
</message> </message>
<message> <message>
<source>Copy GPU Buffers</source> <source>Copy GPU Buffers</source>
<translation type="unfinished">Copy GPU Buffers</translation> <translation>Kopiuj bufory GPU</translation>
</message> </message>
<message> <message>
<source>Host Debug Markers</source> <source>Host Debug Markers</source>
<translation type="unfinished">Host Debug Markers</translation> <translation>Znaczniki diagnostyczne gospodarza</translation>
</message> </message>
<message> <message>
<source>Guest Debug Markers</source> <source>Guest Debug Markers</source>
<translation type="unfinished">Guest Debug Markers</translation> <translation>Znaczniki diagnostyczne gościa</translation>
</message> </message>
<message> <message>
<source>Update</source> <source>Update</source>
@ -1473,7 +1473,7 @@
</message> </message>
<message> <message>
<source>Title Music</source> <source>Title Music</source>
<translation type="unfinished">Title Music</translation> <translation>Muzyka tytułowa</translation>
</message> </message>
<message> <message>
<source>Disable Trophy Pop-ups</source> <source>Disable Trophy Pop-ups</source>
@ -1481,15 +1481,15 @@
</message> </message>
<message> <message>
<source>Background Image</source> <source>Background Image</source>
<translation type="unfinished">Background Image</translation> <translation>Obraz tła</translation>
</message> </message>
<message> <message>
<source>Show Background Image</source> <source>Show Background Image</source>
<translation type="unfinished">Show Background Image</translation> <translation>Pokaż obraz tła</translation>
</message> </message>
<message> <message>
<source>Opacity</source> <source>Opacity</source>
<translation type="unfinished">Opacity</translation> <translation>Przezroczystość</translation>
</message> </message>
<message> <message>
<source>Play title music</source> <source>Play title music</source>
@ -1577,7 +1577,7 @@
</message> </message>
<message> <message>
<source>Background Image:\nControl the opacity of the game background image.</source> <source>Background Image:\nControl the opacity of the game background image.</source>
<translation type="unfinished">Background Image:\nControl the opacity of the game background image.</translation> <translation>Obraz tła:\nKontroluj przezroczystość obrazu tła gry.</translation>
</message> </message>
<message> <message>
<source>Play Title Music:\nIf a game supports it, enable playing special music when selecting the game in the GUI.</source> <source>Play Title Music:\nIf a game supports it, enable playing special music when selecting the game in the GUI.</source>
@ -1661,7 +1661,7 @@
</message> </message>
<message> <message>
<source>Enable HDR:\nEnables HDR in games that support it.\nYour monitor must have support for the BT2020 PQ color space and the RGB10A2 swapchain format.</source> <source>Enable HDR:\nEnables HDR in games that support it.\nYour monitor must have support for the BT2020 PQ color space and the RGB10A2 swapchain format.</source>
<translation type="unfinished">Enable HDR:\nEnables HDR in games that support it.\nYour monitor must have support for the BT2020 PQ color space and the RGB10A2 swapchain format.</translation> <translation>Włącz HDR:\nWłącza HDR w grach, które go wspierają.\nTwój monitor musi mieć wsparcie dla przestrzeni kolorów BT2020 PQ oraz formatu RGB10A2 swapchain.</translation>
</message> </message>
<message> <message>
<source>Game Folders:\nThe list of folders to check for installed games.</source> <source>Game Folders:\nThe list of folders to check for installed games.</source>
@ -1693,51 +1693,51 @@
</message> </message>
<message> <message>
<source>Collect Shaders:\nYou need this enabled to edit shaders with the debug menu (Ctrl + F10).</source> <source>Collect Shaders:\nYou need this enabled to edit shaders with the debug menu (Ctrl + F10).</source>
<translation type="unfinished">Collect Shaders:\nYou need this enabled to edit shaders with the debug menu (Ctrl + F10).</translation> <translation>Zbieranie cieni:\nPotrzebujesz tej opcji aby edytować cienie za pomocą menu debugowania (Ctrl + F10).</translation>
</message> </message>
<message> <message>
<source>Crash Diagnostics:\nCreates a .yaml file with info about the Vulkan state at the time of crashing.\nUseful for debugging &apos;Device lost&apos; errors. If you have this enabled, you should enable Host AND Guest Debug Markers.\nDoes not work on Intel GPUs.\nYou need Vulkan Validation Layers enabled and the Vulkan SDK for this to work.</source> <source>Crash Diagnostics:\nCreates a .yaml file with info about the Vulkan state at the time of crashing.\nUseful for debugging &apos;Device lost&apos; errors. If you have this enabled, you should enable Host AND Guest Debug Markers.\nDoes not work on Intel GPUs.\nYou need Vulkan Validation Layers enabled and the Vulkan SDK for this to work.</source>
<translation type="unfinished">Crash Diagnostics:\nCreates a .yaml file with info about the Vulkan state at the time of crashing.\nUseful for debugging &apos;Device lost&apos; errors. If you have this enabled, you should enable Host AND Guest Debug Markers.\nDoes not work on Intel GPUs.\nYou need Vulkan Validation Layers enabled and the Vulkan SDK for this to work.</translation> <translation>Diagnostyka awarii:\nTworzy plik .yaml z informacjami o stanie Vulkan w momencie awarii.\nPrzydatne do debugowania błędów &apos;DEVICE LOST&apos; . Jeśli ta opcja jest włączona, powinieneś włączyć "Znaczniki błędów gospodarza" oraz "Znaczniki błędów gościa".\nNie działa na kartach graficznych Intela.\nOpcja "Włącz warstwy walidacji Vulkan" i Vulkan SDK jest wymagana do działania.</translation>
</message> </message>
<message> <message>
<source>Copy GPU Buffers:\nGets around race conditions involving GPU submits.\nMay or may not help with PM4 type 0 crashes.</source> <source>Copy GPU Buffers:\nGets around race conditions involving GPU submits.\nMay or may not help with PM4 type 0 crashes.</source>
<translation type="unfinished">Copy GPU Buffers:\nGets around race conditions involving GPU submits.\nMay or may not help with PM4 type 0 crashes.</translation> <translation>Kopiowanie buforów karty graficznej:\nOmija problemy wyścigów związane z przesyłaniem danych do karty graficznej.\nMoże, ale nie musi, pomóc w przypadku awarii typu PM4 0.</translation>
</message> </message>
<message> <message>
<source>Host Debug Markers:\nInserts emulator-side information like markers for specific AMDGPU commands around Vulkan commands, as well as giving resources debug names.\nIf you have this enabled, you should enable Crash Diagnostics.\nUseful for programs like RenderDoc.</source> <source>Host Debug Markers:\nInserts emulator-side information like markers for specific AMDGPU commands around Vulkan commands, as well as giving resources debug names.\nIf you have this enabled, you should enable Crash Diagnostics.\nUseful for programs like RenderDoc.</source>
<translation type="unfinished">Host Debug Markers:\nInserts emulator-side information like markers for specific AMDGPU commands around Vulkan commands, as well as giving resources debug names.\nIf you have this enabled, you should enable Crash Diagnostics.\nUseful for programs like RenderDoc.</translation> <translation>Wskaźniki debugowania gospodarza:\nWstawia informacje emulatora, takie jak znaczniki dla konkretnych poleceń AMDGPU wokół poleceń Vulkan, a także nadaje nazwy debugowania zasobów.\nJeśli ta opcja jest włączona, powinieneś włączyć diagnostykę awarii.\nPrzydatne dla programów takich jak RenderDoc.</translation>
</message> </message>
<message> <message>
<source>Guest Debug Markers:\nInserts any debug markers the game itself has added to the command buffer.\nIf you have this enabled, you should enable Crash Diagnostics.\nUseful for programs like RenderDoc.</source> <source>Guest Debug Markers:\nInserts any debug markers the game itself has added to the command buffer.\nIf you have this enabled, you should enable Crash Diagnostics.\nUseful for programs like RenderDoc.</source>
<translation type="unfinished">Guest Debug Markers:\nInserts any debug markers the game itself has added to the command buffer.\nIf you have this enabled, you should enable Crash Diagnostics.\nUseful for programs like RenderDoc.</translation> <translation>Znaczniki debugowania gościa:\nWstawia wszystkie znaczniki debugowania, które gra dodała do buforu poleceń.\nJeśli ta opcja jest włączona, powinieneś włączyć diagnostykę awarii.\nPrzydatne dla programów takich jak RenderDoc.</translation>
</message> </message>
<message> <message>
<source>Save Data Path:\nThe folder where game save data will be saved.</source> <source>Save Data Path:\nThe folder where game save data will be saved.</source>
<translation type="unfinished">Save Data Path:\nThe folder where game save data will be saved.</translation> <translation>Ścieżka zapisu danych:\nFolder, w którym zapisywane będą dane gry.</translation>
</message> </message>
<message> <message>
<source>Browse:\nBrowse for a folder to set as the save data path.</source> <source>Browse:\nBrowse for a folder to set as the save data path.</source>
<translation type="unfinished">Browse:\nBrowse for a folder to set as the save data path.</translation> <translation>Przeglądaj:\nPrzeglądaj folder, aby ustawić ścieżkę zapisywania danych.</translation>
</message> </message>
<message> <message>
<source>Release</source> <source>Release</source>
<translation type="unfinished">Release</translation> <translation>Wersja stablina</translation>
</message> </message>
<message> <message>
<source>Nightly</source> <source>Nightly</source>
<translation type="unfinished">Nightly</translation> <translation>Wersja rozwojowa</translation>
</message> </message>
<message> <message>
<source>Set the volume of the background music.</source> <source>Set the volume of the background music.</source>
<translation type="unfinished">Set the volume of the background music.</translation> <translation>Wybierz poziom głośności muzyki w tle.</translation>
</message> </message>
<message> <message>
<source>Enable Motion Controls</source> <source>Enable Motion Controls</source>
<translation type="unfinished">Enable Motion Controls</translation> <translation>Włącz sterowanie ruchem</translation>
</message> </message>
<message> <message>
<source>Save Data Path</source> <source>Save Data Path</source>
<translation type="unfinished">Save Data Path</translation> <translation>Ścieżka zapisanych danych</translation>
</message> </message>
<message> <message>
<source>Browse</source> <source>Browse</source>
@ -1745,15 +1745,15 @@
</message> </message>
<message> <message>
<source>async</source> <source>async</source>
<translation type="unfinished">async</translation> <translation>asynchroniczny</translation>
</message> </message>
<message> <message>
<source>sync</source> <source>sync</source>
<translation type="unfinished">sync</translation> <translation>synchroniczny</translation>
</message> </message>
<message> <message>
<source>Auto Select</source> <source>Auto Select</source>
<translation type="unfinished">Auto Select</translation> <translation>Wybór automatyczny</translation>
</message> </message>
<message> <message>
<source>Directory to install games</source> <source>Directory to install games</source>
@ -1761,47 +1761,47 @@
</message> </message>
<message> <message>
<source>Directory to save data</source> <source>Directory to save data</source>
<translation type="unfinished">Directory to save data</translation> <translation>Katalog do zapisywania danych</translation>
</message> </message>
<message> <message>
<source>Video</source> <source>Video</source>
<translation type="unfinished">Video</translation> <translation>Wyświetlanie</translation>
</message> </message>
<message> <message>
<source>Display Mode</source> <source>Display Mode</source>
<translation type="unfinished">Display Mode</translation> <translation>Tryb wyświetlania</translation>
</message> </message>
<message> <message>
<source>Windowed</source> <source>Windowed</source>
<translation type="unfinished">Windowed</translation> <translation>Tryb okna</translation>
</message> </message>
<message> <message>
<source>Fullscreen</source> <source>Fullscreen</source>
<translation type="unfinished">Fullscreen</translation> <translation>Tryb pełnoekranowy</translation>
</message> </message>
<message> <message>
<source>Fullscreen (Borderless)</source> <source>Fullscreen (Borderless)</source>
<translation type="unfinished">Fullscreen (Borderless)</translation> <translation>Tryb pełnoekranowy (bez obramowania)</translation>
</message> </message>
<message> <message>
<source>Window Size</source> <source>Window Size</source>
<translation type="unfinished">Window Size</translation> <translation>Rozmiar okna</translation>
</message> </message>
<message> <message>
<source>W:</source> <source>W:</source>
<translation type="unfinished">W:</translation> <translation>Szerokość:</translation>
</message> </message>
<message> <message>
<source>H:</source> <source>H:</source>
<translation type="unfinished">H:</translation> <translation>Wysokość:</translation>
</message> </message>
<message> <message>
<source>Separate Log Files</source> <source>Separate Log Files</source>
<translation type="unfinished">Separate Log Files</translation> <translation>Oddzielne pliki dziennika</translation>
</message> </message>
<message> <message>
<source>Separate Log Files:\nWrites a separate logfile for each game.</source> <source>Separate Log Files:\nWrites a separate logfile for each game.</source>
<translation type="unfinished">Separate Log Files:\nWrites a separate logfile for each game.</translation> <translation>Oddzielne pliki dziennika:\nZapisuje oddzielny plik dziennika dla każdej gry.</translation>
</message> </message>
</context> </context>
<context> <context>

View File

@ -11,26 +11,26 @@
</message> </message>
<message> <message>
<source>shadPS4 is an experimental open-source emulator for the PlayStation 4.</source> <source>shadPS4 is an experimental open-source emulator for the PlayStation 4.</source>
<translation>shadPS4 é um emulador experimental de código-fonte aberto para o PlayStation 4.</translation> <translation>O shadPS4 é um emulador experimental de código-fonte aberto para o PlayStation 4.</translation>
</message> </message>
<message> <message>
<source>This software should not be used to play games you have not legally obtained.</source> <source>This software should not be used to play games you have not legally obtained.</source>
<translation>Este programa não deve ser usado para jogar jogos que tenham sido obtidos ilegalmente.</translation> <translation>Este programa não deve ser usado para executar jogos que tenham sido obtidos ilegalmente.</translation>
</message> </message>
</context> </context>
<context> <context>
<name>CheatsPatches</name> <name>CheatsPatches</name>
<message> <message>
<source>Cheats / Patches for </source> <source>Cheats / Patches for </source>
<translation>Cheats / Patches para </translation> <translation>Trapaças / Patches para </translation>
</message> </message>
<message> <message>
<source>Cheats/Patches are experimental.\nUse with caution.\n\nDownload cheats individually by selecting the repository and clicking the download button.\nIn the Patches tab, you can download all patches at once, choose which ones you want to use, and save your selection.\n\nSince we do not develop the Cheats/Patches,\nplease report issues to the cheat author.\n\nCreated a new cheat? Visit:\n</source> <source>Cheats/Patches are experimental.\nUse with caution.\n\nDownload cheats individually by selecting the repository and clicking the download button.\nIn the Patches tab, you can download all patches at once, choose which ones you want to use, and save your selection.\n\nSince we do not develop the Cheats/Patches,\nplease report issues to the cheat author.\n\nCreated a new cheat? Visit:\n</source>
<translation>Cheats/Patches são experimentais.\nUse com cautela.\n\nBaixe os cheats individualmente selecionando o repositório e clicando no botão de download.\nNa aba Patches, você pode baixar todos os Patches de uma vez, escolha qual deseja usar e salve a opção.\n\nComo não desenvolvemos os Cheats/Patches,\npor favor, reporte os problemas relacionados ao autor do cheat.\n\nCriou um novo cheat? Visite:\n</translation> <translation>As Trapaças/Patches são experimentais.\nUse com cautela.\n\nBaixe as trapaças individualmente selecionando o repositório e clicando no botão de baixar.\nNa aba Patches, você pode baixar todos os patches de uma vez, escolha qual deseja usar e salve a opção.\n\nComo não desenvolvemos as Trapaças/Patches,\npor favor, reporte os problemas relacionados ao autor da trapaça.\n\nCriou uma nova trapaça? Visite:\n</translation>
</message> </message>
<message> <message>
<source>No Image Available</source> <source>No Image Available</source>
<translation>Imagem Não Disponível</translation> <translation>Nenhuma Imagem Disponível</translation>
</message> </message>
<message> <message>
<source>Serial: </source> <source>Serial: </source>
@ -46,7 +46,7 @@
</message> </message>
<message> <message>
<source>Select Cheat File:</source> <source>Select Cheat File:</source>
<translation>Selecione o Arquivo de Cheat:</translation> <translation>Selecione o Arquivo de Trapaça:</translation>
</message> </message>
<message> <message>
<source>Repository:</source> <source>Repository:</source>
@ -54,7 +54,7 @@
</message> </message>
<message> <message>
<source>Download Cheats</source> <source>Download Cheats</source>
<translation>Baixar Cheats</translation> <translation>Baixar Trapaças</translation>
</message> </message>
<message> <message>
<source>Delete File</source> <source>Delete File</source>
@ -66,7 +66,7 @@
</message> </message>
<message> <message>
<source>You can delete the cheats you don&apos;t want after downloading them.</source> <source>You can delete the cheats you don&apos;t want after downloading them.</source>
<translation>Você pode excluir os cheats que não deseja após baixá-los.</translation> <translation>Você pode excluir as trapaças que não deseja após baixá-las.</translation>
</message> </message>
<message> <message>
<source>Do you want to delete the selected file?\n%1</source> <source>Do you want to delete the selected file?\n%1</source>
@ -86,7 +86,7 @@
</message> </message>
<message> <message>
<source>Cheats</source> <source>Cheats</source>
<translation>Cheats</translation> <translation>Trapaças</translation>
</message> </message>
<message> <message>
<source>Patches</source> <source>Patches</source>
@ -118,7 +118,7 @@
</message> </message>
<message> <message>
<source>Failed to parse XML: </source> <source>Failed to parse XML: </source>
<translation>Falha ao analisar XML: </translation> <translation>Falha ao analisar o XML: </translation>
</message> </message>
<message> <message>
<source>Success</source> <source>Success</source>
@ -154,19 +154,19 @@
</message> </message>
<message> <message>
<source>Cheats Not Found</source> <source>Cheats Not Found</source>
<translation>Cheats Não Encontrados</translation> <translation>Trapaças Não Encontradas</translation>
</message> </message>
<message> <message>
<source>No Cheats found for this game in this version of the selected repository,try another repository or a different version of the game.</source> <source>No Cheats found for this game in this version of the selected repository,try another repository or a different version of the game.</source>
<translation>Nenhum cheat encontrado para este jogo nesta versão do repositório selecionado, tente outro repositório ou uma versão diferente do jogo.</translation> <translation>Nenhuma trapaça encontrada para este jogo nesta versão do repositório selecionado, tente outro repositório ou uma versão diferente do jogo.</translation>
</message> </message>
<message> <message>
<source>Cheats Downloaded Successfully</source> <source>Cheats Downloaded Successfully</source>
<translation>Cheats Baixados com Sucesso</translation> <translation>Trapaças Baixadas com Sucesso</translation>
</message> </message>
<message> <message>
<source>You have successfully downloaded the cheats for this version of the game from the selected repository. You can try downloading from another repository, if it is available it will also be possible to use it by selecting the file from the list.</source> <source>You have successfully downloaded the cheats for this version of the game from the selected repository. You can try downloading from another repository, if it is available it will also be possible to use it by selecting the file from the list.</source>
<translation>Você baixou os cheats para esta versão do jogo do repositório selecionado com sucesso. É possível tentar baixar de outro repositório, se estiver disponível, também será possível utilizá-lo selecionando o arquivo da lista.</translation> <translation>Você baixou as trapaças para esta versão do jogo do repositório selecionado com sucesso. É possível tentar baixar de outro repositório, se estiver disponível, também será possível utilizá-lo selecionando o arquivo da lista.</translation>
</message> </message>
<message> <message>
<source>Failed to save:</source> <source>Failed to save:</source>
@ -182,11 +182,11 @@
</message> </message>
<message> <message>
<source>Patches Downloaded Successfully! All Patches available for all games have been downloaded, there is no need to download them individually for each game as happens in Cheats. If the patch does not appear, it may be that it does not exist for the specific serial and version of the game.</source> <source>Patches Downloaded Successfully! All Patches available for all games have been downloaded, there is no need to download them individually for each game as happens in Cheats. If the patch does not appear, it may be that it does not exist for the specific serial and version of the game.</source>
<translation>Patches Baixados com Sucesso! Todos os patches disponíveis para todos os jogos foram baixados, não é necessário baixá-los individualmente para cada jogo como acontece em Cheats. Se o patch não aparecer, pode ser que ele não exista para o serial e versão específicas do jogo.</translation> <translation>Patches Baixados com Sucesso! Todos os patches disponíveis para todos os jogos foram baixados, não é necessário baixá-los individualmente para cada jogo como acontece em Trapaças. Se o patch não aparecer, pode ser que ele não exista para o serial e versão específicas do jogo.</translation>
</message> </message>
<message> <message>
<source>Failed to parse JSON data from HTML.</source> <source>Failed to parse JSON data from HTML.</source>
<translation>Falha ao analisar dados JSON do HTML.</translation> <translation>Falha ao analisar os dados JSON do HTML.</translation>
</message> </message>
<message> <message>
<source>Failed to retrieve HTML page.</source> <source>Failed to retrieve HTML page.</source>
@ -206,7 +206,7 @@
</message> </message>
<message> <message>
<source>Incompatibility Notice</source> <source>Incompatibility Notice</source>
<translation>Aviso de incompatibilidade</translation> <translation>Aviso de Incompatibilidade</translation>
</message> </message>
<message> <message>
<source>Failed to open file:</source> <source>Failed to open file:</source>
@ -214,7 +214,7 @@
</message> </message>
<message> <message>
<source>XML ERROR:</source> <source>XML ERROR:</source>
<translation>ERRO de XML:</translation> <translation>ERRO DE XML:</translation>
</message> </message>
<message> <message>
<source>Failed to open files.json for writing</source> <source>Failed to open files.json for writing</source>
@ -238,7 +238,7 @@
</message> </message>
<message> <message>
<source>Can&apos;t apply cheats before the game is started</source> <source>Can&apos;t apply cheats before the game is started</source>
<translation>Não é possível aplicar cheats antes que o jogo comece.</translation> <translation>Não é possível aplicar trapaças antes de começar o jogo.</translation>
</message> </message>
<message> <message>
<source>Close</source> <source>Close</source>
@ -285,7 +285,7 @@
</message> </message>
<message> <message>
<source>Update Available</source> <source>Update Available</source>
<translation>Atualização disponível</translation> <translation>Atualização Disponível</translation>
</message> </message>
<message> <message>
<source>Update Channel</source> <source>Update Channel</source>
@ -309,7 +309,7 @@
</message> </message>
<message> <message>
<source>Check for Updates at Startup</source> <source>Check for Updates at Startup</source>
<translation>Verificar Atualizações ao Iniciar</translation> <translation>Verificar por Atualizações ao Iniciar</translation>
</message> </message>
<message> <message>
<source>Update</source> <source>Update</source>
@ -376,7 +376,7 @@
</message> </message>
<message> <message>
<source>Unable to open compatibility_data.json for writing.</source> <source>Unable to open compatibility_data.json for writing.</source>
<translation>Não foi possível abrir o compatibility_data.json para escrita.</translation> <translation>Não foi possível abrir o compatibility_data.json para gravação.</translation>
</message> </message>
<message> <message>
<source>Unknown</source> <source>Unknown</source>
@ -388,7 +388,7 @@
</message> </message>
<message> <message>
<source>Boots</source> <source>Boots</source>
<translation>Boot</translation> <translation>Inicia</translation>
</message> </message>
<message> <message>
<source>Menus</source> <source>Menus</source>
@ -487,7 +487,7 @@
</message> </message>
<message> <message>
<source>Face Buttons</source> <source>Face Buttons</source>
<translation>Botões de Face</translation> <translation>Botões de Ação</translation>
</message> </message>
<message> <message>
<source>Triangle / Y</source> <source>Triangle / Y</source>
@ -535,7 +535,7 @@
</message> </message>
<message> <message>
<source>Override Lightbar Color</source> <source>Override Lightbar Color</source>
<translation>Substituir cor da Lightbar</translation> <translation>Substituir Cor da Barra de Luz</translation>
</message> </message>
<message> <message>
<source>Override Color</source> <source>Override Color</source>
@ -631,7 +631,7 @@
</message> </message>
<message> <message>
<source>Never Played</source> <source>Never Played</source>
<translation>Nunca jogado</translation> <translation>Nunca Jogado</translation>
</message> </message>
<message> <message>
<source>h</source> <source>h</source>
@ -663,11 +663,11 @@
</message> </message>
<message> <message>
<source>Game has game-breaking glitches or unplayable performance</source> <source>Game has game-breaking glitches or unplayable performance</source>
<translation>O jogo tem falhas que interrompem o jogo ou desempenho injogável</translation> <translation>O jogo tem defeitos que interrompem o jogo ou desempenho injogável</translation>
</message> </message>
<message> <message>
<source>Game can be completed with playable performance and no major glitches</source> <source>Game can be completed with playable performance and no major glitches</source>
<translation>O jogo pode ser concluído com desempenho jogável e sem grandes falhas</translation> <translation>O jogo pode ser concluído com desempenho jogável e sem grandes defeitos</translation>
</message> </message>
<message> <message>
<source>Click to see details on github</source> <source>Click to see details on github</source>
@ -709,7 +709,7 @@
</message> </message>
<message> <message>
<source>Cheats / Patches</source> <source>Cheats / Patches</source>
<translation>Cheats / Patches</translation> <translation>Trapaças / Patches</translation>
</message> </message>
<message> <message>
<source>SFO Viewer</source> <source>SFO Viewer</source>
@ -761,19 +761,19 @@
</message> </message>
<message> <message>
<source>Delete...</source> <source>Delete...</source>
<translation>Deletar...</translation> <translation>Excluir...</translation>
</message> </message>
<message> <message>
<source>Delete Game</source> <source>Delete Game</source>
<translation>Deletar Jogo</translation> <translation>Excluir Jogo</translation>
</message> </message>
<message> <message>
<source>Delete Update</source> <source>Delete Update</source>
<translation>Deletar Atualização</translation> <translation>Excluir Atualização</translation>
</message> </message>
<message> <message>
<source>Delete DLC</source> <source>Delete DLC</source>
<translation>Deletar DLC</translation> <translation>Excluir DLC</translation>
</message> </message>
<message> <message>
<source>Compatibility...</source> <source>Compatibility...</source>
@ -825,7 +825,7 @@
</message> </message>
<message> <message>
<source>This game has no DLC to delete!</source> <source>This game has no DLC to delete!</source>
<translation>Este jogo não tem DLC para deletar!</translation> <translation>Este jogo não tem DLC para excluir!</translation>
</message> </message>
<message> <message>
<source>DLC</source> <source>DLC</source>
@ -833,11 +833,11 @@
</message> </message>
<message> <message>
<source>Delete %1</source> <source>Delete %1</source>
<translation>Deletar %1</translation> <translation>Excluir %1</translation>
</message> </message>
<message> <message>
<source>Are you sure you want to delete %1&apos;s %2 directory?</source> <source>Are you sure you want to delete %1&apos;s %2 directory?</source>
<translation>Tem certeza de que deseja excluir o diretório %2 de %1 ?</translation> <translation>Tem certeza de que deseja excluir o diretório %2 de %1?</translation>
</message> </message>
<message> <message>
<source>Open Update Folder</source> <source>Open Update Folder</source>
@ -849,7 +849,7 @@
</message> </message>
<message> <message>
<source>This game has no update folder to open!</source> <source>This game has no update folder to open!</source>
<translation>Este jogo não tem atualização para deletar!</translation> <translation>Este jogo não possui pasta de atualização para abrir!</translation>
</message> </message>
<message> <message>
<source>Failed to convert icon.</source> <source>Failed to convert icon.</source>
@ -857,7 +857,7 @@
</message> </message>
<message> <message>
<source>This game has no save data to delete!</source> <source>This game has no save data to delete!</source>
<translation>Este jogo não tem dados salvos para deletar!</translation> <translation>Este jogo não tem dados salvos para excluir!</translation>
</message> </message>
<message> <message>
<source>Save Data</source> <source>Save Data</source>
@ -880,11 +880,11 @@
</message> </message>
<message> <message>
<source>Install All Queued to Selected Folder</source> <source>Install All Queued to Selected Folder</source>
<translation>Instalar Todas da Fila para a Pasta Selecionada</translation> <translation>Instalar Tudo da Fila para a Pasta Selecionada</translation>
</message> </message>
<message> <message>
<source>Delete PKG File on Install</source> <source>Delete PKG File on Install</source>
<translation>Deletar PKG após instalação</translation> <translation>Excluir o PKG após a Instalação</translation>
</message> </message>
</context> </context>
<context> <context>
@ -923,7 +923,7 @@
</message> </message>
<message> <message>
<source>Open shadPS4 Folder</source> <source>Open shadPS4 Folder</source>
<translation>Abrir pasta shadPS4</translation> <translation>Abrir Pasta do shadPS4</translation>
</message> </message>
<message> <message>
<source>Exit</source> <source>Exit</source>
@ -979,11 +979,11 @@
</message> </message>
<message> <message>
<source>Download Cheats/Patches</source> <source>Download Cheats/Patches</source>
<translation>Baixar Cheats/Patches</translation> <translation>Baixar Trapaças/Patches</translation>
</message> </message>
<message> <message>
<source>Dump Game List</source> <source>Dump Game List</source>
<translation>Dumpar Lista de Jogos</translation> <translation>Exportar Lista de Jogos</translation>
</message> </message>
<message> <message>
<source>PKG Viewer</source> <source>PKG Viewer</source>
@ -1059,7 +1059,7 @@
</message> </message>
<message> <message>
<source>Download Cheats For All Installed Games</source> <source>Download Cheats For All Installed Games</source>
<translation>Baixar Cheats para Todos os Jogos Instalados</translation> <translation>Baixar Trapaças para Todos os Jogos Instalados</translation>
</message> </message>
<message> <message>
<source>Download Patches For All Games</source> <source>Download Patches For All Games</source>
@ -1071,7 +1071,7 @@
</message> </message>
<message> <message>
<source>You have downloaded cheats for all the games you have installed.</source> <source>You have downloaded cheats for all the games you have installed.</source>
<translation>Você baixou cheats para todos os jogos que instalou.</translation> <translation>Você baixou trapaças para todos os jogos que instalou.</translation>
</message> </message>
<message> <message>
<source>Patches Downloaded Successfully!</source> <source>Patches Downloaded Successfully!</source>
@ -1107,15 +1107,15 @@
</message> </message>
<message> <message>
<source>PKG and Game versions match: </source> <source>PKG and Game versions match: </source>
<translation>As versões do PKG e do Jogo são igual: </translation> <translation>As versões do PKG e do Jogo são iguais: </translation>
</message> </message>
<message> <message>
<source>Would you like to overwrite?</source> <source>Would you like to overwrite?</source>
<translation>Gostaria de substituir?</translation> <translation>Você gostaria de sobrescrever?</translation>
</message> </message>
<message> <message>
<source>PKG Version %1 is older than installed version: </source> <source>PKG Version %1 is older than installed version: </source>
<translation>Versão do PKG %1 é mais antiga do que a versão instalada: </translation> <translation>A Versão do PKG %1 é mais antiga do que a versão instalada: </translation>
</message> </message>
<message> <message>
<source>Game is installed: </source> <source>Game is installed: </source>
@ -1143,7 +1143,7 @@
</message> </message>
<message> <message>
<source>PKG ERROR</source> <source>PKG ERROR</source>
<translation>ERRO de PKG</translation> <translation>ERRO DE PKG</translation>
</message> </message>
<message> <message>
<source>Extracting PKG %1/%2</source> <source>Extracting PKG %1/%2</source>
@ -1194,7 +1194,7 @@
</message> </message>
<message> <message>
<source>PKG ERROR</source> <source>PKG ERROR</source>
<translation>ERRO de PKG</translation> <translation>ERRO DE PKG</translation>
</message> </message>
<message> <message>
<source>Name</source> <source>Name</source>
@ -1222,7 +1222,7 @@
</message> </message>
<message> <message>
<source>App Ver</source> <source>App Ver</source>
<translation>App Ver</translation> <translation>Versão do App</translation>
</message> </message>
<message> <message>
<source>FW</source> <source>FW</source>
@ -1238,7 +1238,7 @@
</message> </message>
<message> <message>
<source>Path</source> <source>Path</source>
<translation>Diretório</translation> <translation>Caminho</translation>
</message> </message>
<message> <message>
<source>File</source> <source>File</source>
@ -1381,7 +1381,7 @@
</message> </message>
<message> <message>
<source>Enable Shaders Dumping</source> <source>Enable Shaders Dumping</source>
<translation>Ativar Dumping de Shaders</translation> <translation>Ativar Exportação de Shaders</translation>
</message> </message>
<message> <message>
<source>Enable NULL GPU</source> <source>Enable NULL GPU</source>
@ -1413,7 +1413,7 @@
</message> </message>
<message> <message>
<source>Enable Debug Dumping</source> <source>Enable Debug Dumping</source>
<translation>Ativar Depuração de Dumping</translation> <translation>Ativar Exportação de Depuração</translation>
</message> </message>
<message> <message>
<source>Enable Vulkan Validation Layers</source> <source>Enable Vulkan Validation Layers</source>
@ -1453,7 +1453,7 @@
</message> </message>
<message> <message>
<source>Check for Updates at Startup</source> <source>Check for Updates at Startup</source>
<translation>Verificar Atualizações ao Iniciar</translation> <translation>Verificar por Atualizações ao Iniciar</translation>
</message> </message>
<message> <message>
<source>Always Show Changelog</source> <source>Always Show Changelog</source>
@ -1497,7 +1497,7 @@
</message> </message>
<message> <message>
<source>Update Compatibility Database On Startup</source> <source>Update Compatibility Database On Startup</source>
<translation>Atualizar Compatibilidade ao Inicializar</translation> <translation>Atualizar Base de Dados de Compatibilidade ao Inicializar</translation>
</message> </message>
<message> <message>
<source>Game Compatibility</source> <source>Game Compatibility</source>
@ -1537,15 +1537,15 @@
</message> </message>
<message> <message>
<source>Console Language:\nSets the language that the PS4 game uses.\nIt&apos;s recommended to set this to a language the game supports, which will vary by region.</source> <source>Console Language:\nSets the language that the PS4 game uses.\nIt&apos;s recommended to set this to a language the game supports, which will vary by region.</source>
<translation>Idioma do console:\nDefine o idioma usado pelo jogo do PS4.\nRecomenda-se configurá-lo para um idioma que o jogo suporte, o que pode variar conforme a região.</translation> <translation>Idioma do Console:\nDefine o idioma usado pelo jogo do PS4.\nRecomenda-se configurá-lo para um idioma que o jogo suporte, o que pode variar conforme a região.</translation>
</message> </message>
<message> <message>
<source>Emulator Language:\nSets the language of the emulator&apos;s user interface.</source> <source>Emulator Language:\nSets the language of the emulator&apos;s user interface.</source>
<translation>Idioma do emulador:\nDefine o idioma da interface do emulador.</translation> <translation>Idioma do Emulador:\nDefine o idioma da interface do emulador.</translation>
</message> </message>
<message> <message>
<source>Enable Separate Update Folder:\nEnables installing game updates into a separate folder for easy management.\nThis can be manually created by adding the extracted update to the game folder with the name &quot;CUSA00000-UPDATE&quot; where the CUSA ID matches the game&apos;s ID.</source> <source>Enable Separate Update Folder:\nEnables installing game updates into a separate folder for easy management.\nThis can be manually created by adding the extracted update to the game folder with the name &quot;CUSA00000-UPDATE&quot; where the CUSA ID matches the game&apos;s ID.</source>
<translation>Ativar pasta de atualização separada:\nPermite instalar atualizações de jogos em uma pasta separada para fácil gerenciamento.\nIsso pode ser manualmente criado adicionando a atualização extraída à pasta do jogo com o nome &quot;CUSA00000-UPDATE&quot; onde o ID do CUSA corresponde ao ID do jogo.</translation> <translation>Ativar Pasta de Atualização Separada:\nPermite instalar atualizações de jogos em uma pasta separada para fácil gerenciamento.\nIsso pode ser manualmente criado adicionando a atualização extraída à pasta do jogo com o nome &quot;CUSA00000-UPDATE&quot; onde o ID do CUSA corresponde ao ID do jogo.</translation>
</message> </message>
<message> <message>
<source>Show Splash Screen:\nShows the game&apos;s splash screen (a special image) while the game is starting.</source> <source>Show Splash Screen:\nShows the game&apos;s splash screen (a special image) while the game is starting.</source>
@ -1557,7 +1557,7 @@
</message> </message>
<message> <message>
<source>Username:\nSets the PS4&apos;s account username, which may be displayed by some games.</source> <source>Username:\nSets the PS4&apos;s account username, which may be displayed by some games.</source>
<translation>Nome de usuário:\nDefine o nome de usuário da conta PS4 que pode ser exibido por alguns jogos.</translation> <translation>Nome de usuário:\nDefine o nome de usuário da conta do PS4, que pode ser exibido por alguns jogos.</translation>
</message> </message>
<message> <message>
<source>Trophy Key:\nKey used to decrypt trophies. Must be obtained from your jailbroken console.\nMust contain only hex characters.</source> <source>Trophy Key:\nKey used to decrypt trophies. Must be obtained from your jailbroken console.\nMust contain only hex characters.</source>
@ -1565,7 +1565,7 @@
</message> </message>
<message> <message>
<source>Log Type:\nSets whether to synchronize the output of the log window for performance. May have adverse effects on emulation.</source> <source>Log Type:\nSets whether to synchronize the output of the log window for performance. May have adverse effects on emulation.</source>
<translation>Tipo de Registro:\nDetermina se a saída da janela de log deve ser sincronizada por motivos de desempenho. Pode impactar negativamente a emulação.</translation> <translation>Tipo de Registro:\nDetermina se a saída da janela de log deve ser sincronizada por motivos de desempenho. Pode impactar negativamente na emulação.</translation>
</message> </message>
<message> <message>
<source>Log Filter:\nFilters the log to only print specific information.\nExamples: &quot;Core:Trace&quot; &quot;Lib.Pad:Debug Common.Filesystem:Error&quot; &quot;*:Critical&quot;\nLevels: Trace, Debug, Info, Warning, Error, Critical - in this order, a specific level silences all levels preceding it in the list and logs every level after it.</source> <source>Log Filter:\nFilters the log to only print specific information.\nExamples: &quot;Core:Trace&quot; &quot;Lib.Pad:Debug Common.Filesystem:Error&quot; &quot;*:Critical&quot;\nLevels: Trace, Debug, Info, Warning, Error, Critical - in this order, a specific level silences all levels preceding it in the list and logs every level after it.</source>
@ -1601,7 +1601,7 @@
</message> </message>
<message> <message>
<source>Display Compatibility Data:\nDisplays game compatibility information in table view. Enable &quot;Update Compatibility On Startup&quot; to get up-to-date information.</source> <source>Display Compatibility Data:\nDisplays game compatibility information in table view. Enable &quot;Update Compatibility On Startup&quot; to get up-to-date information.</source>
<translation>Exibir Dados de Compatibilidade:\nExibe informações de compatibilidade dos jogos na visualização de tabela.\nAtivar &quot;Atualizar Compatibilidade ao Inicializar&quot; para obter informações atualizadas.</translation> <translation>Exibir Dados de Compatibilidade:\nExibe informações de compatibilidade dos jogos na visualização de tabela.\nAtive &quot;Atualizar Compatibilidade ao Inicializar&quot; para obter informações atualizadas.</translation>
</message> </message>
<message> <message>
<source>Update Compatibility On Startup:\nAutomatically update the compatibility database when shadPS4 starts.</source> <source>Update Compatibility On Startup:\nAutomatically update the compatibility database when shadPS4 starts.</source>
@ -1609,7 +1609,7 @@
</message> </message>
<message> <message>
<source>Update Compatibility Database:\nImmediately update the compatibility database.</source> <source>Update Compatibility Database:\nImmediately update the compatibility database.</source>
<translation>Atualizar Lista de Compatibilidade:\nAtualizar imediatamente o banco de dados de compatibilidade.</translation> <translation>Atualizar Lista de Compatibilidade:\nAtualiza imediatamente o banco de dados de compatibilidade.</translation>
</message> </message>
<message> <message>
<source>Never</source> <source>Never</source>
@ -1633,7 +1633,7 @@
</message> </message>
<message> <message>
<source>Touchpad Center</source> <source>Touchpad Center</source>
<translation>Touchpad Centro</translation> <translation>Centro do Touchpad</translation>
</message> </message>
<message> <message>
<source>None</source> <source>None</source>
@ -1653,7 +1653,7 @@
</message> </message>
<message> <message>
<source>Enable Shaders Dumping:\nFor the sake of technical debugging, saves the games shaders to a folder as they render.</source> <source>Enable Shaders Dumping:\nFor the sake of technical debugging, saves the games shaders to a folder as they render.</source>
<translation>Ativar Dumping de Shaders:\nArmazena os shaders do jogo em uma pasta durante a renderização para fins de depuração técnica.</translation> <translation>Ativar Exportação de Shaders:\nArmazena os shaders do jogo em uma pasta durante a renderização para fins de depuração técnica.</translation>
</message> </message>
<message> <message>
<source>Enable Null GPU:\nFor the sake of technical debugging, disables game rendering as if there were no graphics card.</source> <source>Enable Null GPU:\nFor the sake of technical debugging, disables game rendering as if there were no graphics card.</source>
@ -1677,7 +1677,7 @@
</message> </message>
<message> <message>
<source>Enable Debug Dumping:\nSaves the import and export symbols and file header information of the currently running PS4 program to a directory.</source> <source>Enable Debug Dumping:\nSaves the import and export symbols and file header information of the currently running PS4 program to a directory.</source>
<translation>Ativar Depuração de Dumping:\nArmazena os símbolos de importação, exportação e informações do cabeçalho do arquivo do programa PS4 atual em um diretório.</translation> <translation>Ativar Exportação de Depuração:\nArmazena os símbolos de importação, exportação e informações do cabeçalho do arquivo do programa PS4 atual em um diretório.</translation>
</message> </message>
<message> <message>
<source>Enable Vulkan Validation Layers:\nEnables a system that validates the state of the Vulkan renderer and logs information about its internal state.\nThis will reduce performance and likely change the behavior of emulation.</source> <source>Enable Vulkan Validation Layers:\nEnables a system that validates the state of the Vulkan renderer and logs information about its internal state.\nThis will reduce performance and likely change the behavior of emulation.</source>

View File

@ -7,7 +7,7 @@
<name>AboutDialog</name> <name>AboutDialog</name>
<message> <message>
<source>About shadPS4</source> <source>About shadPS4</source>
<translation type="unfinished">About shadPS4</translation> <translation>Despre shadPS4</translation>
</message> </message>
<message> <message>
<source>shadPS4 is an experimental open-source emulator for the PlayStation 4.</source> <source>shadPS4 is an experimental open-source emulator for the PlayStation 4.</source>
@ -584,7 +584,7 @@
</message> </message>
<message> <message>
<source>Directory to install DLC</source> <source>Directory to install DLC</source>
<translation type="unfinished">Directory to install DLC</translation> <translation>Director pentru a instala DLC</translation>
</message> </message>
</context> </context>
<context> <context>
@ -845,11 +845,11 @@
</message> </message>
<message> <message>
<source>Delete Save Data</source> <source>Delete Save Data</source>
<translation type="unfinished">Delete Save Data</translation> <translation>Șterge Salvare Date</translation>
</message> </message>
<message> <message>
<source>This game has no update folder to open!</source> <source>This game has no update folder to open!</source>
<translation type="unfinished">This game has no update folder to open!</translation> <translation>Acest joc nu are folderul de actualizări pentru a fi deschis!</translation>
</message> </message>
<message> <message>
<source>Failed to convert icon.</source> <source>Failed to convert icon.</source>
@ -1190,7 +1190,7 @@
<name>PKGViewer</name> <name>PKGViewer</name>
<message> <message>
<source>Open Folder</source> <source>Open Folder</source>
<translation type="unfinished">Open Folder</translation> <translation>Deschide Folder</translation>
</message> </message>
<message> <message>
<source>PKG ERROR</source> <source>PKG ERROR</source>

View File

@ -1765,43 +1765,43 @@
</message> </message>
<message> <message>
<source>Video</source> <source>Video</source>
<translation type="unfinished">Video</translation> <translation>Video</translation>
</message> </message>
<message> <message>
<source>Display Mode</source> <source>Display Mode</source>
<translation type="unfinished">Display Mode</translation> <translation>Mënyra e Shfaqjes</translation>
</message> </message>
<message> <message>
<source>Windowed</source> <source>Windowed</source>
<translation type="unfinished">Windowed</translation> <translation>Dritare</translation>
</message> </message>
<message> <message>
<source>Fullscreen</source> <source>Fullscreen</source>
<translation type="unfinished">Fullscreen</translation> <translation>Ekran plotë</translation>
</message> </message>
<message> <message>
<source>Fullscreen (Borderless)</source> <source>Fullscreen (Borderless)</source>
<translation type="unfinished">Fullscreen (Borderless)</translation> <translation>Ekran plotë (Pa kufij)</translation>
</message> </message>
<message> <message>
<source>Window Size</source> <source>Window Size</source>
<translation type="unfinished">Window Size</translation> <translation>Masa e Dritares</translation>
</message> </message>
<message> <message>
<source>W:</source> <source>W:</source>
<translation type="unfinished">W:</translation> <translation>Gjer:</translation>
</message> </message>
<message> <message>
<source>H:</source> <source>H:</source>
<translation type="unfinished">H:</translation> <translation>Lart:</translation>
</message> </message>
<message> <message>
<source>Separate Log Files</source> <source>Separate Log Files</source>
<translation type="unfinished">Separate Log Files</translation> <translation>Skedarë Ditarit Ndarë</translation>
</message> </message>
<message> <message>
<source>Separate Log Files:\nWrites a separate logfile for each game.</source> <source>Separate Log Files:\nWrites a separate logfile for each game.</source>
<translation type="unfinished">Separate Log Files:\nWrites a separate logfile for each game.</translation> <translation>Skedarë Ditarit Ndarë:\nShkruan një skedar ditarit veçuar për secilën lojë.</translation>
</message> </message>
</context> </context>
<context> <context>

View File

@ -1765,43 +1765,43 @@
</message> </message>
<message> <message>
<source>Video</source> <source>Video</source>
<translation type="unfinished">Video</translation> <translation>Video</translation>
</message> </message>
<message> <message>
<source>Display Mode</source> <source>Display Mode</source>
<translation type="unfinished">Display Mode</translation> <translation>Visningsläge</translation>
</message> </message>
<message> <message>
<source>Windowed</source> <source>Windowed</source>
<translation type="unfinished">Windowed</translation> <translation>Fönster</translation>
</message> </message>
<message> <message>
<source>Fullscreen</source> <source>Fullscreen</source>
<translation type="unfinished">Fullscreen</translation> <translation>Helskärm</translation>
</message> </message>
<message> <message>
<source>Fullscreen (Borderless)</source> <source>Fullscreen (Borderless)</source>
<translation type="unfinished">Fullscreen (Borderless)</translation> <translation>Helskärm (kantlöst)</translation>
</message> </message>
<message> <message>
<source>Window Size</source> <source>Window Size</source>
<translation type="unfinished">Window Size</translation> <translation>Fönsterstorlek</translation>
</message> </message>
<message> <message>
<source>W:</source> <source>W:</source>
<translation type="unfinished">W:</translation> <translation>B:</translation>
</message> </message>
<message> <message>
<source>H:</source> <source>H:</source>
<translation type="unfinished">H:</translation> <translation>H:</translation>
</message> </message>
<message> <message>
<source>Separate Log Files</source> <source>Separate Log Files</source>
<translation type="unfinished">Separate Log Files</translation> <translation>Separata loggfiler</translation>
</message> </message>
<message> <message>
<source>Separate Log Files:\nWrites a separate logfile for each game.</source> <source>Separate Log Files:\nWrites a separate logfile for each game.</source>
<translation type="unfinished">Separate Log Files:\nWrites a separate logfile for each game.</translation> <translation>Separata loggfiler:\nSkriver en separat loggfil för varje spel.</translation>
</message> </message>
</context> </context>
<context> <context>

View File

@ -1,27 +1,178 @@
// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project // SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later // SPDX-License-Identifier: GPL-2.0-or-later
#include <fstream>
#include <QCheckBox>
#include <QDockWidget>
#include <QMessageBox> #include <QMessageBox>
#include <cmrc/cmrc.hpp> #include <cmrc/cmrc.hpp>
#include <common/config.h>
#include "common/path_util.h" #include "common/path_util.h"
#include "main_window_themes.h"
#include "trophy_viewer.h" #include "trophy_viewer.h"
namespace fs = std::filesystem;
CMRC_DECLARE(res); CMRC_DECLARE(res);
// true: European format; false: American format
bool useEuropeanDateFormat = true;
void TrophyViewer::updateTrophyInfo() {
int total = 0;
int unlocked = 0;
// Cycles through each tab (table) of the QTabWidget
for (int i = 0; i < tabWidget->count(); i++) {
QTableWidget* table = qobject_cast<QTableWidget*>(tabWidget->widget(i));
if (table) {
total += table->rowCount();
for (int row = 0; row < table->rowCount(); ++row) {
QString cellText;
// The "Unlocked" column can be a widget or a simple item
QWidget* widget = table->cellWidget(row, 0);
if (widget) {
// Looks for the QLabel inside the widget (as defined in SetTableItem)
QLabel* label = widget->findChild<QLabel*>();
if (label) {
cellText = label->text();
}
} else {
QTableWidgetItem* item = table->item(row, 0);
if (item) {
cellText = item->text();
}
}
if (cellText == "unlocked")
unlocked++;
}
}
}
int progress = (total > 0) ? (unlocked * 100 / total) : 0;
trophyInfoLabel->setText(
QString(tr("Progress") + ": %1% (%2/%3)").arg(progress).arg(unlocked).arg(total));
}
void TrophyViewer::updateTableFilters() {
bool showEarned = showEarnedCheck->isChecked();
bool showNotEarned = showNotEarnedCheck->isChecked();
bool showHidden = showHiddenCheck->isChecked();
// Cycles through each tab of the QTabWidget
for (int i = 0; i < tabWidget->count(); ++i) {
QTableWidget* table = qobject_cast<QTableWidget*>(tabWidget->widget(i));
if (!table)
continue;
for (int row = 0; row < table->rowCount(); ++row) {
QString unlockedText;
// Gets the text of the "Unlocked" column (index 0)
QWidget* widget = table->cellWidget(row, 0);
if (widget) {
QLabel* label = widget->findChild<QLabel*>();
if (label)
unlockedText = label->text();
} else {
QTableWidgetItem* item = table->item(row, 0);
if (item)
unlockedText = item->text();
}
QString hiddenText;
// Gets the text of the "Hidden" column (index 7)
QWidget* hiddenWidget = table->cellWidget(row, 7);
if (hiddenWidget) {
QLabel* label = hiddenWidget->findChild<QLabel*>();
if (label)
hiddenText = label->text();
} else {
QTableWidgetItem* item = table->item(row, 7);
if (item)
hiddenText = item->text();
}
bool visible = true;
if (unlockedText == "unlocked" && !showEarned)
visible = false;
if (unlockedText == "locked" && !showNotEarned)
visible = false;
if (hiddenText.toLower() == "yes" && !showHidden)
visible = false;
table->setRowHidden(row, !visible);
}
}
}
TrophyViewer::TrophyViewer(QString trophyPath, QString gameTrpPath) : QMainWindow() { TrophyViewer::TrophyViewer(QString trophyPath, QString gameTrpPath) : QMainWindow() {
this->setWindowTitle(tr("Trophy Viewer")); this->setWindowTitle(tr("Trophy Viewer"));
this->setAttribute(Qt::WA_DeleteOnClose); this->setAttribute(Qt::WA_DeleteOnClose);
tabWidget = new QTabWidget(this); tabWidget = new QTabWidget(this);
auto lan = Config::getEmulatorLanguage();
if (lan == "en_US" || lan == "zh_CN" || lan == "zh_TW" || lan == "ja_JP" || lan == "ko_KR" ||
lan == "lt_LT" || lan == "nb_NO" || lan == "nl_NL") {
useEuropeanDateFormat = false;
}
gameTrpPath_ = gameTrpPath; gameTrpPath_ = gameTrpPath;
headers << "Unlocked" headers << "Unlocked"
<< "Trophy" << "Trophy"
<< "Name" << "Name"
<< "Description" << "Description"
<< "Time Unlocked"
<< "Type"
<< "ID" << "ID"
<< "Hidden" << "Hidden"
<< "Type"
<< "PID"; << "PID";
PopulateTrophyWidget(trophyPath); PopulateTrophyWidget(trophyPath);
QDockWidget* trophyInfoDock = new QDockWidget("", this);
QWidget* dockWidget = new QWidget(trophyInfoDock);
QVBoxLayout* dockLayout = new QVBoxLayout(dockWidget);
dockLayout->setAlignment(Qt::AlignTop);
trophyInfoLabel = new QLabel(tr("Progress") + ": 0% (0/0)", dockWidget);
trophyInfoLabel->setStyleSheet(
"font-weight: bold; font-size: 16px; color: white; background: #333; padding: 5px;");
dockLayout->addWidget(trophyInfoLabel);
// Creates QCheckBox to filter trophies
showEarnedCheck = new QCheckBox(tr("Show Earned Trophies"), dockWidget);
showNotEarnedCheck = new QCheckBox(tr("Show Not Earned Trophies"), dockWidget);
showHiddenCheck = new QCheckBox(tr("Show Hidden Trophies"), dockWidget);
// Defines the initial states (all checked)
showEarnedCheck->setChecked(true);
showNotEarnedCheck->setChecked(true);
showHiddenCheck->setChecked(false);
// Adds checkboxes to the layout
dockLayout->addWidget(showEarnedCheck);
dockLayout->addWidget(showNotEarnedCheck);
dockLayout->addWidget(showHiddenCheck);
dockWidget->setLayout(dockLayout);
trophyInfoDock->setWidget(dockWidget);
// Adds the dock to the left area
this->addDockWidget(Qt::LeftDockWidgetArea, trophyInfoDock);
// Connects checkbox signals to update trophy display
#if (QT_VERSION < QT_VERSION_CHECK(6, 7, 0))
connect(showEarnedCheck, &QCheckBox::stateChanged, this, &TrophyViewer::updateTableFilters);
connect(showNotEarnedCheck, &QCheckBox::stateChanged, this, &TrophyViewer::updateTableFilters);
connect(showHiddenCheck, &QCheckBox::stateChanged, this, &TrophyViewer::updateTableFilters);
#else
connect(showEarnedCheck, &QCheckBox::checkStateChanged, this,
&TrophyViewer::updateTableFilters);
connect(showNotEarnedCheck, &QCheckBox::checkStateChanged, this,
&TrophyViewer::updateTableFilters);
connect(showHiddenCheck, &QCheckBox::checkStateChanged, this,
&TrophyViewer::updateTableFilters);
#endif
updateTrophyInfo();
updateTableFilters();
} }
void TrophyViewer::PopulateTrophyWidget(QString title) { void TrophyViewer::PopulateTrophyWidget(QString title) {
@ -68,6 +219,7 @@ void TrophyViewer::PopulateTrophyWidget(QString title) {
QStringList trpPid; QStringList trpPid;
QStringList trophyNames; QStringList trophyNames;
QStringList trophyDetails; QStringList trophyDetails;
QStringList trpTimeUnlocked;
QString xmlPath = trpDir + "/Xml/TROP.XML"; QString xmlPath = trpDir + "/Xml/TROP.XML";
QFile file(xmlPath); QFile file(xmlPath);
@ -84,14 +236,35 @@ void TrophyViewer::PopulateTrophyWidget(QString title) {
trpHidden.append(reader.attributes().value("hidden").toString()); trpHidden.append(reader.attributes().value("hidden").toString());
trpType.append(reader.attributes().value("ttype").toString()); trpType.append(reader.attributes().value("ttype").toString());
trpPid.append(reader.attributes().value("pid").toString()); trpPid.append(reader.attributes().value("pid").toString());
if (reader.attributes().hasAttribute("unlockstate")) { if (reader.attributes().hasAttribute("unlockstate")) {
if (reader.attributes().value("unlockstate").toString() == "true") { if (reader.attributes().value("unlockstate").toString() == "true") {
trpUnlocked.append("unlocked"); trpUnlocked.append("unlocked");
} else { } else {
trpUnlocked.append("locked"); trpUnlocked.append("locked");
} }
if (reader.attributes().hasAttribute("timestamp")) {
QString ts = reader.attributes().value("timestamp").toString();
if (ts.length() > 10)
trpTimeUnlocked.append("unknown");
else {
bool ok;
qint64 timestampInt = ts.toLongLong(&ok);
if (ok) {
QDateTime dt = QDateTime::fromSecsSinceEpoch(timestampInt);
QString format = useEuropeanDateFormat ? "dd/MM/yyyy HH:mm:ss"
: "MM/dd/yyyy HH:mm:ss";
trpTimeUnlocked.append(dt.toString(format));
} else {
trpTimeUnlocked.append("unknown");
}
}
} else {
trpTimeUnlocked.append("");
}
} else { } else {
trpUnlocked.append("locked"); trpUnlocked.append("locked");
trpTimeUnlocked.append("");
} }
} }
@ -105,7 +278,7 @@ void TrophyViewer::PopulateTrophyWidget(QString title) {
} }
QTableWidget* tableWidget = new QTableWidget(this); QTableWidget* tableWidget = new QTableWidget(this);
tableWidget->setShowGrid(false); tableWidget->setShowGrid(false);
tableWidget->setColumnCount(8); tableWidget->setColumnCount(9);
tableWidget->setHorizontalHeaderLabels(headers); tableWidget->setHorizontalHeaderLabels(headers);
tableWidget->setSelectionBehavior(QAbstractItemView::SelectRows); tableWidget->setSelectionBehavior(QAbstractItemView::SelectRows);
tableWidget->setSelectionMode(QAbstractItemView::SingleSelection); tableWidget->setSelectionMode(QAbstractItemView::SingleSelection);
@ -113,6 +286,8 @@ void TrophyViewer::PopulateTrophyWidget(QString title) {
tableWidget->horizontalHeader()->setStretchLastSection(true); tableWidget->horizontalHeader()->setStretchLastSection(true);
tableWidget->verticalHeader()->setVisible(false); tableWidget->verticalHeader()->setVisible(false);
tableWidget->setRowCount(icons.size()); tableWidget->setRowCount(icons.size());
tableWidget->setSortingEnabled(true);
for (int row = 0; auto& icon : icons) { for (int row = 0; auto& icon : icons) {
QTableWidgetItem* item = new QTableWidgetItem(); QTableWidgetItem* item = new QTableWidgetItem();
item->setData(Qt::DecorationRole, icon); item->setData(Qt::DecorationRole, icon);
@ -122,15 +297,34 @@ void TrophyViewer::PopulateTrophyWidget(QString title) {
const std::string filename = GetTrpType(trpType[row].at(0)); const std::string filename = GetTrpType(trpType[row].at(0));
QTableWidgetItem* typeitem = new QTableWidgetItem(); QTableWidgetItem* typeitem = new QTableWidgetItem();
auto resource = cmrc::res::get_filesystem(); const auto CustomTrophy_Dir =
std::string resourceString = "Resources/" + filename; Common::FS::GetUserPath(Common::FS::PathType::CustomTrophy);
auto file = resource.open(resourceString); std::string customPath;
std::vector<char> imgdata(file.begin(), file.end());
QImage type_icon = QImage::fromData(imgdata).scaled(QSize(64, 64), Qt::KeepAspectRatio, if (fs::exists(CustomTrophy_Dir / filename)) {
Qt::SmoothTransformation); customPath = (CustomTrophy_Dir / filename).string();
}
std::vector<char> imgdata;
if (!customPath.empty()) {
std::ifstream file(customPath, std::ios::binary);
if (file) {
imgdata = std::vector<char>(std::istreambuf_iterator<char>(file),
std::istreambuf_iterator<char>());
}
} else {
auto resource = cmrc::res::get_filesystem();
std::string resourceString = "src/images/" + filename;
auto file = resource.open(resourceString);
imgdata = std::vector<char>(file.begin(), file.end());
}
QImage type_icon = QImage::fromData(imgdata).scaled(
QSize(100, 100), Qt::KeepAspectRatio, Qt::SmoothTransformation);
typeitem->setData(Qt::DecorationRole, type_icon); typeitem->setData(Qt::DecorationRole, type_icon);
typeitem->setFlags(typeitem->flags() & ~Qt::ItemIsEditable); typeitem->setFlags(typeitem->flags() & ~Qt::ItemIsEditable);
tableWidget->setItem(row, 6, typeitem); tableWidget->setItem(row, 5, typeitem);
std::string detailString = trophyDetails[row].toStdString(); std::string detailString = trophyDetails[row].toStdString();
std::size_t newline_pos = 0; std::size_t newline_pos = 0;
@ -143,46 +337,45 @@ void TrophyViewer::PopulateTrophyWidget(QString title) {
SetTableItem(tableWidget, row, 0, trpUnlocked[row]); SetTableItem(tableWidget, row, 0, trpUnlocked[row]);
SetTableItem(tableWidget, row, 2, trophyNames[row]); SetTableItem(tableWidget, row, 2, trophyNames[row]);
SetTableItem(tableWidget, row, 3, QString::fromStdString(detailString)); SetTableItem(tableWidget, row, 3, QString::fromStdString(detailString));
SetTableItem(tableWidget, row, 4, trpId[row]); SetTableItem(tableWidget, row, 4, trpTimeUnlocked[row]);
SetTableItem(tableWidget, row, 5, trpHidden[row]); SetTableItem(tableWidget, row, 6, trpId[row]);
SetTableItem(tableWidget, row, 7, trpPid[row]); SetTableItem(tableWidget, row, 7, trpHidden[row]);
SetTableItem(tableWidget, row, 8, trpPid[row]);
} }
tableWidget->verticalHeader()->resizeSection(row, icon.height()); tableWidget->verticalHeader()->resizeSection(row, icon.height());
row++; row++;
} }
tableWidget->horizontalHeader()->setSectionResizeMode(QHeaderView::ResizeToContents); tableWidget->horizontalHeader()->setSectionResizeMode(QHeaderView::ResizeToContents);
int width = 16; int width = 16;
for (int i = 0; i < 8; i++) { for (int i = 0; i < 9; i++) {
width += tableWidget->horizontalHeader()->sectionSize(i); width += tableWidget->horizontalHeader()->sectionSize(i);
} }
tableWidget->resize(width, 720); tableWidget->resize(width, 720);
tabWidget->addTab(tableWidget, tabWidget->addTab(tableWidget,
tabName.insert(6, " ").replace(0, 1, tabName.at(0).toUpper())); tabName.insert(6, " ").replace(0, 1, tabName.at(0).toUpper()));
this->resize(width + 20, 720);
this->showMaximized();
tableWidget->horizontalHeader()->setSectionResizeMode(3, QHeaderView::Fixed);
tableWidget->setColumnWidth(3, 650);
} }
this->setCentralWidget(tabWidget); this->setCentralWidget(tabWidget);
} }
void TrophyViewer::SetTableItem(QTableWidget* parent, int row, int column, QString str) { void TrophyViewer::SetTableItem(QTableWidget* parent, int row, int column, QString str) {
QWidget* widget = new QWidget(); QTableWidgetItem* item = new QTableWidgetItem(str);
QVBoxLayout* layout = new QVBoxLayout();
QLabel* label = new QLabel(str);
QTableWidgetItem* item = new QTableWidgetItem();
label->setWordWrap(true);
label->setStyleSheet("color: white; font-size: 15px; font-weight: bold;");
// Create shadow effect
QGraphicsDropShadowEffect* shadowEffect = new QGraphicsDropShadowEffect();
shadowEffect->setBlurRadius(5); // Set the blur radius of the shadow
shadowEffect->setColor(QColor(0, 0, 0, 160)); // Set the color and opacity of the shadow
shadowEffect->setOffset(2, 2); // Set the offset of the shadow
label->setGraphicsEffect(shadowEffect); // Apply shadow effect to the QLabel
layout->addWidget(label);
if (column != 1 && column != 2 && column != 3) if (column != 1 && column != 2 && column != 3)
layout->setAlignment(Qt::AlignCenter); item->setTextAlignment(Qt::AlignCenter);
widget->setLayout(layout); item->setFont(QFont("Arial", 12, QFont::Bold));
Theme theme = static_cast<Theme>(Config::getMainWindowTheme());
if (theme == Theme::Light) {
item->setForeground(QBrush(Qt::black));
} else {
item->setForeground(QBrush(Qt::white));
}
parent->setItem(row, column, item); parent->setItem(row, column, item);
parent->setCellWidget(row, column, widget);
} }

View File

@ -23,6 +23,10 @@ class TrophyViewer : public QMainWindow {
public: public:
explicit TrophyViewer(QString trophyPath, QString gameTrpPath); explicit TrophyViewer(QString trophyPath, QString gameTrpPath);
void updateTrophyInfo();
void updateTableFilters();
private: private:
void PopulateTrophyWidget(QString title); void PopulateTrophyWidget(QString title);
void SetTableItem(QTableWidget* parent, int row, int column, QString str); void SetTableItem(QTableWidget* parent, int row, int column, QString str);
@ -31,6 +35,10 @@ private:
QStringList headers; QStringList headers;
QString gameTrpPath_; QString gameTrpPath_;
TRP trp; TRP trp;
QLabel* trophyInfoLabel;
QCheckBox* showEarnedCheck;
QCheckBox* showNotEarnedCheck;
QCheckBox* showHiddenCheck;
std::string GetTrpType(const QChar trp_) { std::string GetTrpType(const QChar trp_) {
switch (trp_.toLatin1()) { switch (trp_.toLatin1()) {

View File

@ -134,13 +134,17 @@ void SDLInputEngine::Init() {
m_gyro_poll_rate = SDL_GetGamepadSensorDataRate(m_gamepad, SDL_SENSOR_GYRO); m_gyro_poll_rate = SDL_GetGamepadSensorDataRate(m_gamepad, SDL_SENSOR_GYRO);
LOG_INFO(Input, "Gyro initialized, poll rate: {}", m_gyro_poll_rate); LOG_INFO(Input, "Gyro initialized, poll rate: {}", m_gyro_poll_rate);
} else { } else {
LOG_ERROR(Input, "Failed to initialize gyro controls for gamepad"); LOG_ERROR(Input, "Failed to initialize gyro controls for gamepad, error: {}",
SDL_GetError());
SDL_SetGamepadSensorEnabled(m_gamepad, SDL_SENSOR_GYRO, false);
} }
if (SDL_SetGamepadSensorEnabled(m_gamepad, SDL_SENSOR_ACCEL, true)) { if (SDL_SetGamepadSensorEnabled(m_gamepad, SDL_SENSOR_ACCEL, true)) {
m_accel_poll_rate = SDL_GetGamepadSensorDataRate(m_gamepad, SDL_SENSOR_ACCEL); m_accel_poll_rate = SDL_GetGamepadSensorDataRate(m_gamepad, SDL_SENSOR_ACCEL);
LOG_INFO(Input, "Accel initialized, poll rate: {}", m_accel_poll_rate); LOG_INFO(Input, "Accel initialized, poll rate: {}", m_accel_poll_rate);
} else { } else {
LOG_ERROR(Input, "Failed to initialize accel controls for gamepad"); LOG_ERROR(Input, "Failed to initialize accel controls for gamepad, error: {}",
SDL_GetError());
SDL_SetGamepadSensorEnabled(m_gamepad, SDL_SENSOR_ACCEL, false);
} }
} }

View File

@ -27,8 +27,8 @@ public:
private: private:
SDL_Gamepad* m_gamepad = nullptr; SDL_Gamepad* m_gamepad = nullptr;
float m_gyro_poll_rate{}; float m_gyro_poll_rate = 0.0f;
float m_accel_poll_rate{}; float m_accel_poll_rate = 0.0f;
}; };
} // namespace Input } // namespace Input

View File

@ -27,7 +27,7 @@ void Translator::EmitScalarAlu(const GcnInst& inst) {
case Opcode::S_ADD_I32: case Opcode::S_ADD_I32:
return S_ADD_I32(inst); return S_ADD_I32(inst);
case Opcode::S_SUB_I32: case Opcode::S_SUB_I32:
return S_SUB_U32(inst); return S_SUB_I32(inst);
case Opcode::S_ADDC_U32: case Opcode::S_ADDC_U32:
return S_ADDC_U32(inst); return S_ADDC_U32(inst);
case Opcode::S_MIN_I32: case Opcode::S_MIN_I32:
@ -216,24 +216,52 @@ void Translator::EmitSOPK(const GcnInst& inst) {
void Translator::S_ADD_U32(const GcnInst& inst) { void Translator::S_ADD_U32(const GcnInst& inst) {
const IR::U32 src0{GetSrc(inst.src[0])}; const IR::U32 src0{GetSrc(inst.src[0])};
const IR::U32 src1{GetSrc(inst.src[1])}; const IR::U32 src1{GetSrc(inst.src[1])};
SetDst(inst.dst[0], ir.IAdd(src0, src1)); const IR::U32 result{ir.IAdd(src0, src1)};
// TODO: Carry out SetDst(inst.dst[0], result);
ir.SetScc(ir.Imm1(false));
// SCC = tmp >= 0x100000000ULL ? 1'1U : 1'0U;
// The above assumes tmp is a 64-bit value.
// It should be enough however to test that the truncated result is less than at least one
// of the operands. In unsigned addition the result is always bigger than both the operands,
// except in the case of overflow where the truncated result is less than both.
ir.SetScc(ir.ILessThan(result, src0, false));
} }
void Translator::S_SUB_U32(const GcnInst& inst) { void Translator::S_SUB_U32(const GcnInst& inst) {
const IR::U32 src0{GetSrc(inst.src[0])}; const IR::U32 src0{GetSrc(inst.src[0])};
const IR::U32 src1{GetSrc(inst.src[1])}; const IR::U32 src1{GetSrc(inst.src[1])};
SetDst(inst.dst[0], ir.ISub(src0, src1)); SetDst(inst.dst[0], ir.ISub(src0, src1));
// TODO: Carry out
ir.SetScc(ir.Imm1(false)); // SCC = S1.u > S0.u ? 1'1U : 1'0U;
ir.SetScc(ir.IGreaterThan(src1, src0, false));
} }
void Translator::S_ADD_I32(const GcnInst& inst) { void Translator::S_ADD_I32(const GcnInst& inst) {
const IR::U32 src0{GetSrc(inst.src[0])}; const IR::U32 src0{GetSrc(inst.src[0])};
const IR::U32 src1{GetSrc(inst.src[1])}; const IR::U32 src1{GetSrc(inst.src[1])};
SetDst(inst.dst[0], ir.IAdd(src0, src1)); const IR::U32 result{ir.IAdd(src0, src1)};
// TODO: Overflow flag SetDst(inst.dst[0], result);
// SCC = ((S0.u[31] == S1.u[31]) && (S0.u[31] != Result.u[31]));
const IR::U32 shift{ir.Imm32(31)};
const IR::U32 sign0{ir.ShiftRightLogical(src0, shift)};
const IR::U32 sign1{ir.ShiftRightLogical(src1, shift)};
const IR::U32 signr{ir.ShiftRightLogical(result, shift)};
ir.SetScc(ir.LogicalAnd(ir.IEqual(sign0, sign1), ir.INotEqual(sign0, signr)));
}
void Translator::S_SUB_I32(const GcnInst& inst) {
const IR::U32 src0{GetSrc(inst.src[0])};
const IR::U32 src1{GetSrc(inst.src[1])};
const IR::U32 result{ir.ISub(src0, src1)};
SetDst(inst.dst[0], result);
// SCC = ((S0.u[31] != S1.u[31]) && (S0.u[31] != tmp.u[31]));
const IR::U32 shift{ir.Imm32(31)};
const IR::U32 sign0{ir.ShiftRightLogical(src0, shift)};
const IR::U32 sign1{ir.ShiftRightLogical(src1, shift)};
const IR::U32 signr{ir.ShiftRightLogical(result, shift)};
ir.SetScc(ir.LogicalAnd(ir.INotEqual(sign0, sign1), ir.INotEqual(sign0, signr)));
} }
void Translator::S_ADDC_U32(const GcnInst& inst) { void Translator::S_ADDC_U32(const GcnInst& inst) {

View File

@ -81,6 +81,7 @@ public:
void S_ADD_U32(const GcnInst& inst); void S_ADD_U32(const GcnInst& inst);
void S_SUB_U32(const GcnInst& inst); void S_SUB_U32(const GcnInst& inst);
void S_ADD_I32(const GcnInst& inst); void S_ADD_I32(const GcnInst& inst);
void S_SUB_I32(const GcnInst& inst);
void S_ADDC_U32(const GcnInst& inst); void S_ADDC_U32(const GcnInst& inst);
void S_MIN_U32(bool is_signed, const GcnInst& inst); void S_MIN_U32(bool is_signed, const GcnInst& inst);
void S_MAX_U32(bool is_signed, const GcnInst& inst); void S_MAX_U32(bool is_signed, const GcnInst& inst);

View File

@ -104,7 +104,7 @@ static inline vk::Format PromoteFormatToDepth(vk::Format fmt) {
} else if (fmt == vk::Format::eR16Unorm) { } else if (fmt == vk::Format::eR16Unorm) {
return vk::Format::eD16Unorm; return vk::Format::eD16Unorm;
} }
UNREACHABLE(); UNREACHABLE_MSG("Unexpected depth format {}", vk::to_string(fmt));
} }
} // namespace Vulkan::LiverpoolToVK } // namespace Vulkan::LiverpoolToVK