Merge branch 'main' into qt-style

This commit is contained in:
tomboylover93 2024-12-27 10:22:18 -03:00 committed by GitHub
commit f17867e4e7
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
135 changed files with 8742 additions and 5471 deletions

View File

@ -16,7 +16,7 @@ if (NOT CMAKE_BUILD_TYPE)
set(CMAKE_BUILD_TYPE Release) set(CMAKE_BUILD_TYPE Release)
endif() endif()
project(shadPS4) project(shadPS4 CXX C ASM)
# 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)
@ -392,7 +392,8 @@ set(USBD_LIB src/core/libraries/usbd/usbd.cpp
src/core/libraries/usbd/usbd.h src/core/libraries/usbd/usbd.h
) )
set(FIBER_LIB src/core/libraries/fiber/fiber.cpp set(FIBER_LIB src/core/libraries/fiber/fiber_context.s
src/core/libraries/fiber/fiber.cpp
src/core/libraries/fiber/fiber.h src/core/libraries/fiber/fiber.h
src/core/libraries/fiber/fiber_error.h src/core/libraries/fiber/fiber_error.h
) )
@ -630,6 +631,8 @@ set(SHADER_RECOMPILER src/shader_recompiler/exception.h
src/shader_recompiler/backend/spirv/emit_spirv_instructions.h src/shader_recompiler/backend/spirv/emit_spirv_instructions.h
src/shader_recompiler/backend/spirv/emit_spirv_integer.cpp src/shader_recompiler/backend/spirv/emit_spirv_integer.cpp
src/shader_recompiler/backend/spirv/emit_spirv_logical.cpp src/shader_recompiler/backend/spirv/emit_spirv_logical.cpp
src/shader_recompiler/backend/spirv/emit_spirv_quad_rect.cpp
src/shader_recompiler/backend/spirv/emit_spirv_quad_rect.h
src/shader_recompiler/backend/spirv/emit_spirv_select.cpp src/shader_recompiler/backend/spirv/emit_spirv_select.cpp
src/shader_recompiler/backend/spirv/emit_spirv_shared_memory.cpp src/shader_recompiler/backend/spirv/emit_spirv_shared_memory.cpp
src/shader_recompiler/backend/spirv/emit_spirv_special.cpp src/shader_recompiler/backend/spirv/emit_spirv_special.cpp

View File

@ -86,32 +86,32 @@ F12 | Trigger RenderDoc Capture
> [!NOTE] > [!NOTE]
> Xbox and DualShock controllers work out of the box. > Xbox and DualShock controllers work out of the box.
| Controller button | Keyboard equivelant | | Controller button | Keyboard equivelant | Mac alternative |
|-------------|-------------| |-------------|-------------|--------------|
LEFT AXIS UP | W | LEFT AXIS UP | W | |
LEFT AXIS DOWN | S | LEFT AXIS DOWN | S | |
LEFT AXIS LEFT | A | LEFT AXIS LEFT | A | |
LEFT AXIS RIGHT | D | LEFT AXIS RIGHT | D | |
RIGHT AXIS UP | I | RIGHT AXIS UP | I | |
RIGHT AXIS DOWN | K | RIGHT AXIS DOWN | K | |
RIGHT AXIS LEFT | J | RIGHT AXIS LEFT | J | |
RIGHT AXIS RIGHT | L | RIGHT AXIS RIGHT | L | |
TRIANGLE | Numpad 8 | TRIANGLE | Numpad 8 | C |
CIRCLE | Numpad 6 | CIRCLE | Numpad 6 | B |
CROSS | Numpad 2 | CROSS | Numpad 2 | N |
SQUARE | Numpad 4 | SQUARE | Numpad 4 | V |
PAD UP | UP | PAD UP | UP | |
PAD DOWN | DOWN | PAD DOWN | DOWN | |
PAD LEFT | LEFT | PAD LEFT | LEFT | |
PAD RIGHT | RIGHT | PAD RIGHT | RIGHT | |
OPTIONS | RETURN | OPTIONS | RETURN | |
BACK BUTTON / TOUCH PAD | SPACE | BACK BUTTON / TOUCH PAD | SPACE | |
L1 | Q | L1 | Q | |
R1 | U | R1 | U | |
L2 | E | L2 | E | |
R2 | O | R2 | O | |
L3 | X | L3 | X | |
R3 | M | R3 | M | |
# Main team # Main team

View File

@ -25,7 +25,7 @@ Once you are within the installer:
Beware, this requires you to create a Qt account. If you do not want to do this, please follow the MSYS2/MinGW compilation method instead. Beware, this requires you to create a Qt account. If you do not want to do this, please follow the MSYS2/MinGW compilation method instead.
1. Under the current, non beta version of Qt (at the time of writing 6.7.3), select the option `MSVC 2022 64-bit` or similar. 1. Under the current, non beta version of Qt (at the time of writing 6.7.3), select the option `MSVC 2022 64-bit` or similar, as well as `QT Multimedia`.
If you are on Windows on ARM / Qualcomm Snapdragon Elite X, select `MSVC 2022 ARM64` instead. If you are on Windows on ARM / Qualcomm Snapdragon Elite X, select `MSVC 2022 ARM64` instead.
Go through the installation normally. If you know what you are doing, you may unselect individual components that eat up too much disk space. Go through the installation normally. If you know what you are doing, you may unselect individual components that eat up too much disk space.
@ -64,7 +64,7 @@ Go through the Git for Windows installation as normal
Your shadps4.exe will be in `C:\path\to\source\Build\x64-Clang-Release\` Your shadps4.exe will be in `C:\path\to\source\Build\x64-Clang-Release\`
To automatically populate the necessary files to run shadPS4.exe, run in a command prompt or terminal: To automatically populate the necessary files to run shadPS4.exe, run in a command prompt or terminal:
`C:\Qt\6.7.3\msvc2022_64\bin\windeployqt.exe "C:\path\to\shadps4.exe"` `C:\Qt\6.7.3\msvc2022_64\bin\windeployqt6.exe "C:\path\to\shadps4.exe"`
(Change Qt path if you've installed it to non-default path) (Change Qt path if you've installed it to non-default path)
## Option 2: MSYS2/MinGW ## Option 2: MSYS2/MinGW

View File

@ -189,7 +189,11 @@ add_library(Dear_ImGui
target_include_directories(Dear_ImGui INTERFACE dear_imgui/) target_include_directories(Dear_ImGui INTERFACE dear_imgui/)
# Tracy # Tracy
if (CMAKE_BUILD_TYPE STREQUAL "Release")
option(TRACY_ENABLE "" OFF)
else()
option(TRACY_ENABLE "" ON) option(TRACY_ENABLE "" ON)
endif()
option(TRACY_NO_CRASH_HANDLER "" ON) # Otherwise texture cache exceptions will be treaten as a crash option(TRACY_NO_CRASH_HANDLER "" ON) # Otherwise texture cache exceptions will be treaten as a crash
option(TRACY_ON_DEMAND "" ON) option(TRACY_ON_DEMAND "" ON)
option(TRACY_NO_FRAME_IMAGE "" ON) option(TRACY_NO_FRAME_IMAGE "" ON)

View File

@ -14,7 +14,11 @@
#include <tracy/Tracy.hpp> #include <tracy/Tracy.hpp>
static inline bool IsProfilerConnected() { static inline bool IsProfilerConnected() {
#if TRACY_ENABLE
return tracy::GetProfiler().IsConnected(); return tracy::GetProfiler().IsConnected();
#else
return false;
#endif
} }
#define TRACY_GPU_ENABLED 0 #define TRACY_GPU_ENABLED 0

View File

@ -207,7 +207,7 @@ public:
return WriteSpan(string); return WriteSpan(string);
} }
static size_t WriteBytes(const std::filesystem::path path, std::span<const u8> data) { static size_t WriteBytes(const std::filesystem::path path, const auto& data) {
IOFile out(path, FileAccessMode::Write); IOFile out(path, FileAccessMode::Write);
return out.Write(data); return out.Write(data);
} }

View File

@ -8,7 +8,7 @@
namespace Common { namespace Common {
constexpr char VERSION[] = "0.4.1 WIP"; constexpr char VERSION[] = "0.5.1 WIP";
constexpr bool isRelease = false; constexpr bool isRelease = false;
} // namespace Common } // namespace Common

View File

@ -141,12 +141,9 @@ void Crypto::decryptEFSM(std::span<CryptoPP::byte, 16> NPcommID,
std::span<CryptoPP::byte, 16> efsmIv, std::span<CryptoPP::byte> ciphertext, std::span<CryptoPP::byte, 16> efsmIv, std::span<CryptoPP::byte> ciphertext,
std::span<CryptoPP::byte> decrypted) { std::span<CryptoPP::byte> decrypted) {
std::vector<CryptoPP::byte> TrophyKey = {0x21, 0xF4, 0x1A, 0x6B, 0xAD, 0x8A, 0x1D, 0x3E,
0xCA, 0x7A, 0xD5, 0x86, 0xC1, 0x01, 0xB7, 0xA9};
std::vector<CryptoPP::byte> TrophyIV = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; std::vector<CryptoPP::byte> TrophyIV = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
// step 1: Encrypt NPcommID // step 1: Encrypt NPcommID
CryptoPP::CBC_Mode<CryptoPP::AES>::Encryption encrypt; CryptoPP::CBC_Mode<CryptoPP::AES>::Encryption encrypt;
encrypt.SetKeyWithIV(TrophyKey.data(), TrophyKey.size(), TrophyIV.data());
std::vector<CryptoPP::byte> trpKey(16); std::vector<CryptoPP::byte> trpKey(16);

View File

@ -11,6 +11,7 @@
#include "libraries/kernel/time.h" #include "libraries/kernel/time.h"
#include "libraries/system/msgdialog.h" #include "libraries/system/msgdialog.h"
#include "video_core/amdgpu/pm4_cmds.h" #include "video_core/amdgpu/pm4_cmds.h"
#include "video_core/renderer_vulkan/vk_pipeline_cache.h"
using namespace DebugStateType; using namespace DebugStateType;
@ -168,8 +169,12 @@ void DebugStateImpl::PushRegsDump(uintptr_t base_addr, uintptr_t header_addr,
if ((*dump)->regs.stage_enable.IsStageEnabled(i)) { if ((*dump)->regs.stage_enable.IsStageEnabled(i)) {
auto stage = (*dump)->regs.ProgramForStage(i); auto stage = (*dump)->regs.ProgramForStage(i);
if (stage->address_lo != 0) { if (stage->address_lo != 0) {
const auto& info = AmdGpu::Liverpool::SearchBinaryInfo(stage->Address<u32*>());
auto code = stage->Code(); auto code = stage->Code();
(*dump)->stages[i] = PipelineShaderProgramDump{ (*dump)->stages[i] = PipelineShaderProgramDump{
.name = Vulkan::PipelineCache::GetShaderName(Shader::StageFromIndex(i),
info.shader_hash),
.hash = info.shader_hash,
.user_data = *stage, .user_data = *stage,
.code = std::vector<u32>{code.begin(), code.end()}, .code = std::vector<u32>{code.begin(), code.end()},
}; };
@ -191,7 +196,10 @@ void DebugStateImpl::PushRegsDumpCompute(uintptr_t base_addr, uintptr_t header_a
auto& cs = (*dump)->regs.cs_program; auto& cs = (*dump)->regs.cs_program;
cs = cs_state; cs = cs_state;
const auto& info = AmdGpu::Liverpool::SearchBinaryInfo(cs.Address<u32*>());
(*dump)->cs_data = PipelineComputerProgramDump{ (*dump)->cs_data = PipelineComputerProgramDump{
.name = Vulkan::PipelineCache::GetShaderName(Shader::Stage::Compute, info.shader_hash),
.hash = info.shader_hash,
.cs_program = cs, .cs_program = cs,
.code = std::vector<u32>{cs.Code().begin(), cs.Code().end()}, .code = std::vector<u32>{cs.Code().begin(), cs.Code().end()},
}; };

View File

@ -50,11 +50,15 @@ struct QueueDump {
}; };
struct PipelineShaderProgramDump { struct PipelineShaderProgramDump {
std::string name;
u64 hash;
Vulkan::Liverpool::ShaderProgram user_data{}; Vulkan::Liverpool::ShaderProgram user_data{};
std::vector<u32> code{}; std::vector<u32> code{};
}; };
struct PipelineComputerProgramDump { struct PipelineComputerProgramDump {
std::string name;
u64 hash;
Vulkan::Liverpool::ComputeProgram cs_program{}; Vulkan::Liverpool::ComputeProgram cs_program{};
std::vector<u32> code{}; std::vector<u32> code{};
}; };

View File

@ -1174,7 +1174,7 @@ CmdListViewer::CmdListViewer(DebugStateType::FrameDump* _frame_dump,
} }
} }
void CmdListViewer::Draw(bool only_batches_view) { void CmdListViewer::Draw(bool only_batches_view, CmdListFilter& filter) {
const auto& ctx = *GetCurrentContext(); const auto& ctx = *GetCurrentContext();
if (batch_view.open) { if (batch_view.open) {
@ -1285,6 +1285,41 @@ void CmdListViewer::Draw(bool only_batches_view) {
} }
auto& batch = std::get<BatchInfo>(event); auto& batch = std::get<BatchInfo>(event);
// filtering
{
bool remove = false;
if (filter.shader_name[0] != '\0') {
remove = true;
std::string_view shader_name{filter.shader_name};
const auto& data = frame_dump->regs.find(batch.command_addr);
if (data != frame_dump->regs.end()) {
DebugStateType::RegDump& dump = data->second;
if (dump.is_compute) {
if (dump.cs_data.name.contains(shader_name)) {
remove = false;
break;
}
} else {
for (int i = 0; i < DebugStateType::RegDump::MaxShaderStages; ++i) {
if (dump.regs.stage_enable.IsStageEnabled(i)) {
auto& stage = dump.stages[i];
if (stage.name.contains(shader_name)) {
remove = false;
break;
}
}
}
}
}
}
if (remove) {
continue;
}
}
auto const* pm4_hdr = auto const* pm4_hdr =
reinterpret_cast<PM4Header const*>(cmdb_addr + batch.start_addr); reinterpret_cast<PM4Header const*>(cmdb_addr + batch.start_addr);

View File

@ -35,6 +35,10 @@ void ParseDepthControl(u32 value, bool begin_table = true);
void ParseEqaa(u32 value, bool begin_table = true); void ParseEqaa(u32 value, bool begin_table = true);
void ParseZInfo(u32 value, bool begin_table = true); void ParseZInfo(u32 value, bool begin_table = true);
struct CmdListFilter {
char shader_name[128]{};
};
class CmdListViewer { class CmdListViewer {
DebugStateType::FrameDump* frame_dump; DebugStateType::FrameDump* frame_dump;
@ -70,7 +74,7 @@ public:
explicit CmdListViewer(DebugStateType::FrameDump* frame_dump, const std::vector<u32>& cmd_list, explicit CmdListViewer(DebugStateType::FrameDump* frame_dump, const std::vector<u32>& cmd_list,
uintptr_t base_addr = 0, std::string name = ""); uintptr_t base_addr = 0, std::string name = "");
void Draw(bool only_batches_view = false); void Draw(bool only_batches_view, CmdListFilter& filter);
}; };
} // namespace Core::Devtools::Widget } // namespace Core::Devtools::Widget

View File

@ -117,7 +117,7 @@ static bool IsDrawCall(AmdGpu::PM4ItOpcode opcode) {
inline std::optional<std::string> exec_cli(const char* cli) { inline std::optional<std::string> exec_cli(const char* cli) {
std::array<char, 64> buffer{}; std::array<char, 64> buffer{};
std::string output; std::string output;
const auto f = popen(cli, "rt"); const auto f = popen(cli, "r");
if (!f) { if (!f) {
pclose(f); pclose(f);
return {}; return {};

View File

@ -132,6 +132,15 @@ void FrameDumpViewer::Draw() {
} }
} }
EndDisabled(); EndDisabled();
SameLine();
if (BeginMenu("Filter")) {
TextUnformatted("Shader name");
SameLine();
InputText("##filter_shader", filter.shader_name, sizeof(filter.shader_name));
ImGui::EndMenu();
}
TextEx("Submit num"); TextEx("Submit num");
SameLine(); SameLine();
@ -187,7 +196,7 @@ void FrameDumpViewer::Draw() {
EndGroup(); EndGroup();
} }
if (is_showing && selected_cmd != -1) { if (is_showing && selected_cmd != -1) {
cmd_list_viewer[selected_cmd].Draw(is_collapsed); cmd_list_viewer[selected_cmd].Draw(is_collapsed, filter);
} }
End(); End();
} }

View File

@ -27,6 +27,8 @@ class FrameDumpViewer {
s32 selected_queue_num2; s32 selected_queue_num2;
s32 selected_cmd = -1; s32 selected_cmd = -1;
CmdListFilter filter;
public: public:
bool is_open = true; bool is_open = true;

View File

@ -19,6 +19,57 @@ constexpr float BAR_HEIGHT_MULT = 1.25f;
constexpr float FRAME_GRAPH_PADDING_Y = 3.0f; constexpr float FRAME_GRAPH_PADDING_Y = 3.0f;
constexpr static float FRAME_GRAPH_HEIGHT = 50.0f; constexpr static float FRAME_GRAPH_HEIGHT = 50.0f;
void FrameGraph::DrawFrameGraph() {
// Frame graph - inspired by
// https://asawicki.info/news_1758_an_idea_for_visualization_of_frame_times
const float full_width = GetContentRegionAvail().x;
auto pos = GetCursorScreenPos();
const ImVec2 size{full_width, FRAME_GRAPH_HEIGHT + FRAME_GRAPH_PADDING_Y * 2.0f};
ItemSize(size);
if (!ItemAdd({pos, pos + size}, GetID("FrameGraph"))) {
return;
}
float target_dt = 1.0f / (TARGET_FPS * (float)Config::vblankDiv());
float cur_pos_x = pos.x + full_width;
pos.y += FRAME_GRAPH_PADDING_Y;
const float final_pos_y = pos.y + FRAME_GRAPH_HEIGHT;
auto& draw_list = *GetWindowDrawList();
draw_list.AddRectFilled({pos.x, pos.y - FRAME_GRAPH_PADDING_Y},
{pos.x + full_width, final_pos_y + FRAME_GRAPH_PADDING_Y},
IM_COL32(0x33, 0x33, 0x33, 0xFF));
draw_list.PushClipRect({pos.x, pos.y}, {pos.x + full_width, final_pos_y}, true);
for (u32 i = 0; i < FRAME_BUFFER_SIZE; ++i) {
const auto& frame_info = frame_list[(DebugState.GetFrameNum() - i) % FRAME_BUFFER_SIZE];
const float dt_factor = target_dt / frame_info.delta;
const float width = std::ceil(BAR_WIDTH_MULT / dt_factor);
const float height =
std::min(std::log2(BAR_HEIGHT_MULT / dt_factor) / 3.0f, 1.0f) * FRAME_GRAPH_HEIGHT;
ImU32 color;
if (dt_factor >= 0.95f) { // BLUE
color = IM_COL32(0x33, 0x33, 0xFF, 0xFF);
} else if (dt_factor >= 0.5f) { // GREEN <> YELLOW
float t = 1.0f - (dt_factor - 0.5f) * 2.0f;
int r = (int)(0xFF * t);
color = IM_COL32(r, 0xFF, 0, 0xFF);
} else { // YELLOW <> RED
float t = dt_factor * 2.0f;
int g = (int)(0xFF * t);
color = IM_COL32(0xFF, g, 0, 0xFF);
}
draw_list.AddRectFilled({cur_pos_x - width, final_pos_y - height}, {cur_pos_x, final_pos_y},
color);
cur_pos_x -= width;
if (cur_pos_x < width) {
break;
}
}
draw_list.PopClipRect();
}
void FrameGraph::Draw() { void FrameGraph::Draw() {
if (!is_open) { if (!is_open) {
return; return;
@ -43,55 +94,9 @@ void FrameGraph::Draw() {
Text("Frame time: %.3f ms (%.1f FPS)", deltaTime, frameRate); Text("Frame time: %.3f ms (%.1f FPS)", deltaTime, frameRate);
Text("Flip frame: %d Gnm submit frame: %d", DebugState.flip_frame_count.load(), Text("Flip frame: %d Gnm submit frame: %d", DebugState.flip_frame_count.load(),
DebugState.gnm_frame_count.load()); DebugState.gnm_frame_count.load());
SeparatorText("Frame graph"); SeparatorText("Frame graph");
DrawFrameGraph();
const float full_width = GetContentRegionAvail().x;
// Frame graph - inspired by
// https://asawicki.info/news_1758_an_idea_for_visualization_of_frame_times
auto pos = GetCursorScreenPos();
const ImVec2 size{full_width, FRAME_GRAPH_HEIGHT + FRAME_GRAPH_PADDING_Y * 2.0f};
ItemSize(size);
if (!ItemAdd({pos, pos + size}, GetID("FrameGraph"))) {
return;
}
float target_dt = 1.0f / (TARGET_FPS * (float)Config::vblankDiv());
float cur_pos_x = pos.x + full_width;
pos.y += FRAME_GRAPH_PADDING_Y;
const float final_pos_y = pos.y + FRAME_GRAPH_HEIGHT;
draw_list.AddRectFilled({pos.x, pos.y - FRAME_GRAPH_PADDING_Y},
{pos.x + full_width, final_pos_y + FRAME_GRAPH_PADDING_Y},
IM_COL32(0x33, 0x33, 0x33, 0xFF));
draw_list.PushClipRect({pos.x, pos.y}, {pos.x + full_width, final_pos_y}, true);
for (u32 i = 0; i < FRAME_BUFFER_SIZE; ++i) {
const auto& frame_info = frame_list[(DebugState.GetFrameNum() - i) % FRAME_BUFFER_SIZE];
const float dt_factor = target_dt / frame_info.delta;
const float width = std::ceil(BAR_WIDTH_MULT / dt_factor);
const float height =
std::min(std::log2(BAR_HEIGHT_MULT / dt_factor) / 3.0f, 1.0f) * FRAME_GRAPH_HEIGHT;
ImU32 color;
if (dt_factor >= 0.95f) { // BLUE
color = IM_COL32(0x33, 0x33, 0xFF, 0xFF);
} else if (dt_factor >= 0.5f) { // GREEN <> YELLOW
float t = 1.0f - (dt_factor - 0.5f) * 2.0f;
int r = (int)(0xFF * t);
color = IM_COL32(r, 0xFF, 0, 0xFF);
} else { // YELLOW <> RED
float t = dt_factor * 2.0f;
int g = (int)(0xFF * t);
color = IM_COL32(0xFF, g, 0, 0xFF);
}
draw_list.AddRectFilled({cur_pos_x - width, final_pos_y - height},
{cur_pos_x, final_pos_y}, color);
cur_pos_x -= width;
if (cur_pos_x < width) {
break;
}
}
draw_list.PopClipRect();
} }
End(); End();
} }

View File

@ -16,6 +16,8 @@ class FrameGraph {
std::array<FrameInfo, FRAME_BUFFER_SIZE> frame_list{}; std::array<FrameInfo, FRAME_BUFFER_SIZE> frame_list{};
void DrawFrameGraph();
public: public:
bool is_open = true; bool is_open = true;

View File

@ -292,6 +292,17 @@ void RegView::Draw() {
EndMenuBar(); EndMenuBar();
} }
const char* shader_name = "_";
if (data.is_compute) {
shader_name = data.cs_data.name.c_str();
} else if (selected_shader >= 0) {
shader_name = data.stages[selected_shader].name.c_str();
}
TextUnformatted("Shader: ");
SameLine();
TextUnformatted(shader_name);
if (!data.is_compute && if (!data.is_compute &&
BeginChild("STAGES", {}, BeginChild("STAGES", {},
ImGuiChildFlags_AlwaysAutoResize | ImGuiChildFlags_AutoResizeY)) { ImGuiChildFlags_AlwaysAutoResize | ImGuiChildFlags_AutoResizeY)) {

View File

@ -112,6 +112,10 @@ bool ShaderList::Selection::DrawShader(DebugStateType::ShaderDump& value) {
ReloadShader(value); ReloadShader(value);
} }
} }
SameLine();
if (Button("Copy name")) {
SetClipboardText(value.name.c_str());
}
if (value.is_patched) { if (value.is_patched) {
if (BeginCombo("Shader type", showing_bin ? "SPIRV" : "GLSL", if (BeginCombo("Shader type", showing_bin ? "SPIRV" : "GLSL",
@ -229,9 +233,16 @@ void ShaderList::Draw() {
return; return;
} }
InputTextEx("##search_shader", "Search by name", search_box, sizeof(search_box), {},
ImGuiInputTextFlags_None);
auto width = GetContentRegionAvail().x; auto width = GetContentRegionAvail().x;
int i = 0; int i = 0;
for (const auto& shader : DebugState.shader_dump_list) { for (const auto& shader : DebugState.shader_dump_list) {
if (search_box[0] != '\0' && !shader.name.contains(search_box)) {
i++;
continue;
}
char name[128]; char name[128];
if (shader.is_patched) { if (shader.is_patched) {
snprintf(name, sizeof(name), "%s (PATCH ON)", shader.name.c_str()); snprintf(name, sizeof(name), "%s (PATCH ON)", shader.name.c_str());

View File

@ -31,6 +31,8 @@ class ShaderList {
std::vector<Selection> open_shaders{}; std::vector<Selection> open_shaders{};
char search_box[128]{};
public: public:
bool open = false; bool open = false;

View File

@ -145,8 +145,10 @@ int PS4_SYSV_ABI sceAppContentDownloadDataFormat() {
return ORBIS_OK; return ORBIS_OK;
} }
int PS4_SYSV_ABI sceAppContentDownloadDataGetAvailableSpaceKb() { int PS4_SYSV_ABI sceAppContentDownloadDataGetAvailableSpaceKb(OrbisAppContentMountPoint* mountPoint,
u64* availableSpaceKb) {
LOG_ERROR(Lib_AppContent, "(STUBBED) called"); LOG_ERROR(Lib_AppContent, "(STUBBED) called");
*availableSpaceKb = 1048576;
return ORBIS_OK; return ORBIS_OK;
} }
@ -294,9 +296,9 @@ int PS4_SYSV_ABI sceAppContentTemporaryDataFormat() {
} }
int PS4_SYSV_ABI sceAppContentTemporaryDataGetAvailableSpaceKb( int PS4_SYSV_ABI sceAppContentTemporaryDataGetAvailableSpaceKb(
const OrbisAppContentMountPoint* mountPoint, size_t* availableSpaceKb) { const OrbisAppContentMountPoint* mountPoint, u64* availableSpaceKb) {
LOG_ERROR(Lib_AppContent, "(STUBBED) called"); LOG_ERROR(Lib_AppContent, "(STUBBED) called");
*availableSpaceKb = 1073741824; *availableSpaceKb = 1048576;
return ORBIS_OK; return ORBIS_OK;
} }

View File

@ -84,7 +84,8 @@ int PS4_SYSV_ABI sceAppContentDownload0Shrink();
int PS4_SYSV_ABI sceAppContentDownload1Expand(); int PS4_SYSV_ABI sceAppContentDownload1Expand();
int PS4_SYSV_ABI sceAppContentDownload1Shrink(); int PS4_SYSV_ABI sceAppContentDownload1Shrink();
int PS4_SYSV_ABI sceAppContentDownloadDataFormat(); int PS4_SYSV_ABI sceAppContentDownloadDataFormat();
int PS4_SYSV_ABI sceAppContentDownloadDataGetAvailableSpaceKb(); int PS4_SYSV_ABI sceAppContentDownloadDataGetAvailableSpaceKb(OrbisAppContentMountPoint* mountPoint,
u64* availableSpaceKb);
int PS4_SYSV_ABI sceAppContentGetAddcontDownloadProgress(); int PS4_SYSV_ABI sceAppContentGetAddcontDownloadProgress();
int PS4_SYSV_ABI sceAppContentGetAddcontInfo(u32 service_label, int PS4_SYSV_ABI sceAppContentGetAddcontInfo(u32 service_label,
const OrbisNpUnifiedEntitlementLabel* entitlementLabel, const OrbisNpUnifiedEntitlementLabel* entitlementLabel,
@ -105,7 +106,7 @@ int PS4_SYSV_ABI sceAppContentSmallSharedDataMount();
int PS4_SYSV_ABI sceAppContentSmallSharedDataUnmount(); int PS4_SYSV_ABI sceAppContentSmallSharedDataUnmount();
int PS4_SYSV_ABI sceAppContentTemporaryDataFormat(); int PS4_SYSV_ABI sceAppContentTemporaryDataFormat();
int PS4_SYSV_ABI sceAppContentTemporaryDataGetAvailableSpaceKb( int PS4_SYSV_ABI sceAppContentTemporaryDataGetAvailableSpaceKb(
const OrbisAppContentMountPoint* mountPoint, size_t* availableSpaceKb); const OrbisAppContentMountPoint* mountPoint, u64* availableSpaceKb);
int PS4_SYSV_ABI sceAppContentTemporaryDataMount(); int PS4_SYSV_ABI sceAppContentTemporaryDataMount();
int PS4_SYSV_ABI sceAppContentTemporaryDataMount2(OrbisAppContentTemporaryDataOption option, int PS4_SYSV_ABI sceAppContentTemporaryDataMount2(OrbisAppContentTemporaryDataOption option,
OrbisAppContentMountPoint* mountPoint); OrbisAppContentMountPoint* mountPoint);

View File

@ -8,253 +8,455 @@
#include "core/libraries/libs.h" #include "core/libraries/libs.h"
#include "core/tls.h" #include "core/tls.h"
#ifdef _WIN64
#include <windows.h>
#endif
namespace Libraries::Fiber { namespace Libraries::Fiber {
static constexpr u64 kFiberSignature = 0x054ad954; static constexpr u32 kFiberSignature0 = 0xdef1649c;
static constexpr u32 kFiberSignature1 = 0xb37592a0;
static constexpr u32 kFiberOptSignature = 0xbb40e64d;
static constexpr u64 kFiberStackSignature = 0x7149f2ca7149f2ca;
static constexpr u64 kFiberStackSizeCheck = 0xdeadbeefdeadbeef;
thread_local SceFiber* gCurrentFiber = nullptr; static std::atomic<u32> context_size_check = false;
thread_local void* gFiberThread = nullptr;
void FiberEntry(void* param) { OrbisFiberContext* GetFiberContext() {
SceFiber* fiber = static_cast<SceFiber*>(param); return Core::GetTcbBase()->tcb_fiber;
u64 argRun = 0;
u64 argRet = 0;
gCurrentFiber = fiber;
if (fiber->pArgRun != nullptr) {
argRun = *fiber->pArgRun;
} }
Core::ExecuteGuest(fiber->entry, fiber->argOnInitialize, argRun); extern "C" s32 PS4_SYSV_ABI _sceFiberSetJmp(OrbisFiberContext* ctx) asm("_sceFiberSetJmp");
UNREACHABLE(); extern "C" s32 PS4_SYSV_ABI _sceFiberLongJmp(OrbisFiberContext* ctx) asm("_sceFiberLongJmp");
extern "C" void PS4_SYSV_ABI _sceFiberSwitchEntry(OrbisFiberData* data,
bool set_fpu) asm("_sceFiberSwitchEntry");
extern "C" void PS4_SYSV_ABI _sceFiberForceQuit(u64 ret) asm("_sceFiberForceQuit");
extern "C" void PS4_SYSV_ABI _sceFiberForceQuit(u64 ret) {
OrbisFiberContext* g_ctx = GetFiberContext();
g_ctx->return_val = ret;
_sceFiberLongJmp(g_ctx);
} }
s32 PS4_SYSV_ABI sceFiberInitialize(SceFiber* fiber, const char* name, SceFiberEntry entry, void PS4_SYSV_ABI _sceFiberCheckStackOverflow(OrbisFiberContext* ctx) {
u64 argOnInitialize, void* addrContext, u64 sizeContext, u64* stack_base = reinterpret_cast<u64*>(ctx->current_fiber->addr_context);
const SceFiberOptParam* optParam) { if (stack_base && *stack_base != kFiberStackSignature) {
LOG_INFO(Lib_Fiber, "called: name = {}", name); UNREACHABLE_MSG("Stack overflow detected in fiber.");
}
}
void PS4_SYSV_ABI _sceFiberSwitchToFiber(OrbisFiber* fiber, u64 arg_on_run_to,
OrbisFiberContext* ctx) {
OrbisFiberContext* fiber_ctx = fiber->context;
if (fiber_ctx) {
ctx->arg_on_run_to = arg_on_run_to;
_sceFiberLongJmp(fiber_ctx);
__builtin_trap();
}
OrbisFiberData data{};
if (ctx->prev_fiber) {
OrbisFiber* prev_fiber = ctx->prev_fiber;
ctx->prev_fiber = nullptr;
data.state = reinterpret_cast<u32*>(&prev_fiber->state);
} else {
data.state = nullptr;
}
data.entry = fiber->entry;
data.arg_on_initialize = fiber->arg_on_initialize;
data.arg_on_run_to = arg_on_run_to;
data.stack_addr =
reinterpret_cast<void*>(reinterpret_cast<u64>(fiber->addr_context) + fiber->size_context);
if (fiber->flags & FiberFlags::SetFpuRegs) {
data.fpucw = 0x037f;
data.mxcsr = 0x9fc0;
_sceFiberSwitchEntry(&data, true);
} else {
_sceFiberSwitchEntry(&data, false);
}
__builtin_trap();
}
void PS4_SYSV_ABI _sceFiberSwitch(OrbisFiber* cur_fiber, OrbisFiber* fiber, u64 arg_on_run_to,
OrbisFiberContext* ctx) {
ctx->prev_fiber = cur_fiber;
ctx->current_fiber = fiber;
if (fiber->addr_context == nullptr) {
ctx->prev_fiber = nullptr;
OrbisFiberData data{};
data.entry = fiber->entry;
data.arg_on_initialize = fiber->arg_on_initialize;
data.arg_on_run_to = arg_on_run_to;
data.stack_addr = reinterpret_cast<void*>(ctx->rsp & ~15);
data.state = reinterpret_cast<u32*>(&cur_fiber->state);
if (fiber->flags & FiberFlags::SetFpuRegs) {
data.fpucw = 0x037f;
data.mxcsr = 0x9fc0;
_sceFiberSwitchEntry(&data, true);
} else {
_sceFiberSwitchEntry(&data, false);
}
__builtin_trap();
}
_sceFiberSwitchToFiber(fiber, arg_on_run_to, ctx);
__builtin_trap();
}
void PS4_SYSV_ABI _sceFiberTerminate(OrbisFiber* fiber, u64 arg_on_return, OrbisFiberContext* ctx) {
ctx->arg_on_return = arg_on_return;
_sceFiberLongJmp(ctx);
__builtin_trap();
}
s32 PS4_SYSV_ABI sceFiberInitialize(OrbisFiber* fiber, const char* name, OrbisFiberEntry entry,
u64 arg_on_initialize, void* addr_context, u64 size_context,
const OrbisFiberOptParam* opt_param, u32 build_ver) {
if (!fiber || !name || !entry) { if (!fiber || !name || !entry) {
return ORBIS_FIBER_ERROR_NULL; return ORBIS_FIBER_ERROR_NULL;
} }
if ((u64)fiber & 7 || (u64)addr_context & 15) {
return ORBIS_FIBER_ERROR_ALIGNMENT;
}
if (opt_param && (u64)opt_param & 7) {
return ORBIS_FIBER_ERROR_ALIGNMENT;
}
if (size_context && size_context < ORBIS_FIBER_CONTEXT_MINIMUM_SIZE) {
return ORBIS_FIBER_ERROR_RANGE;
}
if (size_context & 15) {
return ORBIS_FIBER_ERROR_INVALID;
}
if (!addr_context && size_context) {
return ORBIS_FIBER_ERROR_INVALID;
}
if (addr_context && !size_context) {
return ORBIS_FIBER_ERROR_INVALID;
}
if (opt_param && opt_param->magic != kFiberOptSignature) {
return ORBIS_FIBER_ERROR_INVALID;
}
fiber->signature = kFiberSignature; u32 flags = FiberFlags::None;
if (build_ver >= 0x3500000) {
flags |= FiberFlags::SetFpuRegs;
}
if (context_size_check) {
flags |= FiberFlags::ContextSizeCheck;
}
fiber->entry = entry;
fiber->argOnInitialize = argOnInitialize;
fiber->argRun = 0;
fiber->pArgRun = &fiber->argRun;
fiber->argReturn = 0;
fiber->pArgReturn = &fiber->argReturn;
fiber->sizeContext = sizeContext;
fiber->state = FiberState::Init;
#ifdef _WIN64
fiber->handle = CreateFiber(sizeContext, FiberEntry, fiber);
#else
UNREACHABLE_MSG("Missing implementation");
#endif
strncpy(fiber->name, name, ORBIS_FIBER_MAX_NAME_LENGTH); strncpy(fiber->name, name, ORBIS_FIBER_MAX_NAME_LENGTH);
fiber->entry = entry;
fiber->arg_on_initialize = arg_on_initialize;
fiber->addr_context = addr_context;
fiber->size_context = size_context;
fiber->context = nullptr;
fiber->flags = flags;
/*
A low stack area is problematic, as we can easily
cause a stack overflow with our HLE.
*/
if (size_context && size_context <= 4096) {
LOG_WARNING(Lib_Fiber, "Fiber initialized with small stack area.");
}
fiber->magic_start = kFiberSignature0;
fiber->magic_end = kFiberSignature1;
if (addr_context != nullptr) {
fiber->context_start = addr_context;
fiber->context_end =
reinterpret_cast<void*>(reinterpret_cast<u64>(addr_context) + size_context);
/* Apply signature to start of stack */
*(u64*)addr_context = kFiberStackSignature;
if (flags & FiberFlags::ContextSizeCheck) {
u64* stack_start = reinterpret_cast<u64*>(fiber->context_start);
u64* stack_end = reinterpret_cast<u64*>(fiber->context_end);
u64* stack_ptr = stack_start + 1;
while (stack_ptr < stack_end) {
*stack_ptr++ = kFiberStackSizeCheck;
}
}
}
fiber->state = FiberState::Idle;
return ORBIS_OK; return ORBIS_OK;
} }
s32 PS4_SYSV_ABI sceFiberOptParamInitialize(SceFiberOptParam* optParam) { s32 PS4_SYSV_ABI sceFiberOptParamInitialize(OrbisFiberOptParam* opt_param) {
LOG_ERROR(Lib_Fiber, "called"); if (!opt_param) {
if (!optParam) {
return ORBIS_FIBER_ERROR_NULL; return ORBIS_FIBER_ERROR_NULL;
} }
if ((u64)opt_param & 7) {
return ORBIS_FIBER_ERROR_ALIGNMENT;
}
opt_param->magic = kFiberOptSignature;
return ORBIS_OK; return ORBIS_OK;
} }
s32 PS4_SYSV_ABI sceFiberFinalize(SceFiber* fiber) { s32 PS4_SYSV_ABI sceFiberFinalize(OrbisFiber* fiber) {
LOG_TRACE(Lib_Fiber, "called");
if (!fiber) { if (!fiber) {
return ORBIS_FIBER_ERROR_NULL; return ORBIS_FIBER_ERROR_NULL;
} }
if ((u64)fiber % 8 != 0) { if ((u64)fiber & 7) {
return ORBIS_FIBER_ERROR_ALIGNMENT; return ORBIS_FIBER_ERROR_ALIGNMENT;
} }
if (fiber->signature != kFiberSignature) { if (fiber->magic_start != kFiberSignature0 || fiber->magic_end != kFiberSignature1) {
return ORBIS_FIBER_ERROR_INVALID; return ORBIS_FIBER_ERROR_INVALID;
} }
if (fiber->state != FiberState::Run) {
FiberState expected = FiberState::Idle;
if (!fiber->state.compare_exchange_strong(expected, FiberState::Terminated)) {
return ORBIS_FIBER_ERROR_STATE; return ORBIS_FIBER_ERROR_STATE;
} }
fiber->signature = 0;
fiber->state = FiberState::None;
#ifdef _WIN64
DeleteFiber(fiber->handle);
#else
UNREACHABLE_MSG("Missing implementation");
#endif
return ORBIS_OK; return ORBIS_OK;
} }
s32 PS4_SYSV_ABI sceFiberRun(SceFiber* fiber, u64 argOnRunTo, u64* argOnReturn) { s32 PS4_SYSV_ABI sceFiberRun(OrbisFiber* fiber, u64 arg_on_run_to, u64* arg_on_return) {
LOG_TRACE(Lib_Fiber, "called");
if (!fiber) { if (!fiber) {
return ORBIS_FIBER_ERROR_NULL; return ORBIS_FIBER_ERROR_NULL;
} }
if ((u64)fiber % 8 != 0) { if ((u64)fiber & 7) {
return ORBIS_FIBER_ERROR_ALIGNMENT; return ORBIS_FIBER_ERROR_ALIGNMENT;
} }
if (fiber->signature != kFiberSignature) { if (fiber->magic_start != kFiberSignature0 || fiber->magic_end != kFiberSignature1) {
return ORBIS_FIBER_ERROR_INVALID; return ORBIS_FIBER_ERROR_INVALID;
} }
if (fiber->state == FiberState::Run) {
Core::Tcb* tcb = Core::GetTcbBase();
if (tcb->tcb_fiber) {
return ORBIS_FIBER_ERROR_PERMISSION;
}
FiberState expected = FiberState::Idle;
if (!fiber->state.compare_exchange_strong(expected, FiberState::Run)) {
return ORBIS_FIBER_ERROR_STATE; return ORBIS_FIBER_ERROR_STATE;
} }
if (gFiberThread == nullptr) { OrbisFiberContext ctx{};
#ifdef _WIN64 ctx.current_fiber = fiber;
gFiberThread = ConvertThreadToFiber(nullptr); ctx.prev_fiber = nullptr;
#else ctx.return_val = 0;
UNREACHABLE_MSG("Missing implementation");
#endif tcb->tcb_fiber = &ctx;
s32 jmp = _sceFiberSetJmp(&ctx);
if (!jmp) {
if (fiber->addr_context) {
_sceFiberSwitchToFiber(fiber, arg_on_run_to, &ctx);
__builtin_trap();
} }
gCurrentFiber = fiber; OrbisFiberData data{};
data.entry = fiber->entry;
if (fiber->pArgRun != nullptr) { data.arg_on_initialize = fiber->arg_on_initialize;
*fiber->pArgRun = argOnRunTo; data.arg_on_run_to = arg_on_run_to;
data.stack_addr = reinterpret_cast<void*>(ctx.rsp & ~15);
data.state = nullptr;
if (fiber->flags & FiberFlags::SetFpuRegs) {
data.fpucw = 0x037f;
data.mxcsr = 0x9fc0;
_sceFiberSwitchEntry(&data, true);
} else {
_sceFiberSwitchEntry(&data, false);
}
} }
fiber->pArgReturn = argOnReturn; OrbisFiber* cur_fiber = ctx.current_fiber;
fiber->state = FiberState::Run; ctx.current_fiber = nullptr;
#ifdef _WIN64 cur_fiber->state = FiberState::Idle;
SwitchToFiber(fiber->handle);
#else if (ctx.return_val != 0) {
UNREACHABLE_MSG("Missing implementation"); /* Fiber entry returned! This should never happen. */
#endif UNREACHABLE_MSG("Fiber entry function returned.");
}
if (arg_on_return) {
*arg_on_return = ctx.arg_on_return;
}
tcb->tcb_fiber = nullptr;
return ORBIS_OK; return ORBIS_OK;
} }
s32 PS4_SYSV_ABI sceFiberSwitch(SceFiber* fiber, u64 argOnRunTo, u64* argOnRun) { s32 PS4_SYSV_ABI sceFiberSwitch(OrbisFiber* fiber, u64 arg_on_run_to, u64* arg_on_run) {
LOG_TRACE(Lib_Fiber, "called");
if (!fiber) { if (!fiber) {
return ORBIS_FIBER_ERROR_NULL; return ORBIS_FIBER_ERROR_NULL;
} }
if ((u64)fiber % 8 != 0) { if ((u64)fiber & 7) {
return ORBIS_FIBER_ERROR_ALIGNMENT; return ORBIS_FIBER_ERROR_ALIGNMENT;
} }
if (fiber->signature != kFiberSignature) { if (fiber->magic_start != kFiberSignature0 || fiber->magic_end != kFiberSignature1) {
return ORBIS_FIBER_ERROR_INVALID; return ORBIS_FIBER_ERROR_INVALID;
} }
if (gCurrentFiber == nullptr) {
OrbisFiberContext* g_ctx = GetFiberContext();
if (!g_ctx) {
return ORBIS_FIBER_ERROR_PERMISSION; return ORBIS_FIBER_ERROR_PERMISSION;
} }
if (fiber->state == FiberState::Run) {
FiberState expected = FiberState::Idle;
if (!fiber->state.compare_exchange_strong(expected, FiberState::Run)) {
return ORBIS_FIBER_ERROR_STATE; return ORBIS_FIBER_ERROR_STATE;
} }
gCurrentFiber->state = FiberState::Suspend; OrbisFiber* cur_fiber = g_ctx->current_fiber;
if (cur_fiber->addr_context == nullptr) {
_sceFiberSwitch(cur_fiber, fiber, arg_on_run_to, g_ctx);
__builtin_trap();
}
// TODO: argOnRun OrbisFiberContext ctx{};
s32 jmp = _sceFiberSetJmp(&ctx);
if (!jmp) {
cur_fiber->context = &ctx;
_sceFiberCheckStackOverflow(g_ctx);
_sceFiberSwitch(cur_fiber, fiber, arg_on_run_to, g_ctx);
__builtin_trap();
}
*fiber->pArgRun = argOnRunTo; g_ctx = GetFiberContext();
fiber->state = FiberState::Run; if (g_ctx->prev_fiber) {
g_ctx->prev_fiber->state = FiberState::Idle;
g_ctx->prev_fiber = nullptr;
}
if (arg_on_run) {
*arg_on_run = g_ctx->arg_on_run_to;
}
gCurrentFiber = fiber;
#ifdef _WIN64
SwitchToFiber(fiber->handle);
#else
UNREACHABLE_MSG("Missing implementation");
#endif
return ORBIS_OK; return ORBIS_OK;
} }
s32 PS4_SYSV_ABI sceFiberGetSelf(SceFiber** fiber) { s32 PS4_SYSV_ABI sceFiberGetSelf(OrbisFiber** fiber) {
LOG_TRACE(Lib_Fiber, "called"); if (!fiber) {
if (!fiber || !gCurrentFiber) {
return ORBIS_FIBER_ERROR_NULL;
}
if (gCurrentFiber->signature != kFiberSignature) {
return ORBIS_FIBER_ERROR_PERMISSION;
}
*fiber = gCurrentFiber;
return ORBIS_OK;
}
s32 PS4_SYSV_ABI sceFiberReturnToThread(u64 argOnReturn, u64* argOnRun) {
LOG_TRACE(Lib_Fiber, "called");
if (gCurrentFiber->signature != kFiberSignature) {
return ORBIS_FIBER_ERROR_PERMISSION;
}
if (gCurrentFiber->pArgReturn != nullptr) {
*gCurrentFiber->pArgReturn = argOnReturn;
}
// TODO: argOnRun
gCurrentFiber->state = FiberState::Suspend;
gCurrentFiber = nullptr;
#ifdef _WIN64
SwitchToFiber(gFiberThread);
#else
UNREACHABLE_MSG("Missing implementation");
#endif
return ORBIS_OK;
}
s32 PS4_SYSV_ABI sceFiberGetInfo(SceFiber* fiber, SceFiberInfo* fiberInfo) {
LOG_INFO(Lib_Fiber, "called");
if (!fiber || !fiberInfo) {
return ORBIS_FIBER_ERROR_NULL; return ORBIS_FIBER_ERROR_NULL;
} }
fiberInfo->entry = fiber->entry; OrbisFiberContext* g_ctx = GetFiberContext();
fiberInfo->argOnInitialize = fiber->argOnInitialize; if (!g_ctx) {
fiberInfo->addrContext = nullptr; return ORBIS_FIBER_ERROR_PERMISSION;
fiberInfo->sizeContext = fiber->sizeContext; }
fiberInfo->sizeContextMargin = 0;
*fiber = g_ctx->current_fiber;
return ORBIS_OK;
}
s32 PS4_SYSV_ABI sceFiberReturnToThread(u64 arg_on_return, u64* arg_on_run) {
OrbisFiberContext* g_ctx = GetFiberContext();
if (!g_ctx) {
return ORBIS_FIBER_ERROR_PERMISSION;
}
OrbisFiber* cur_fiber = g_ctx->current_fiber;
if (cur_fiber->addr_context) {
OrbisFiberContext ctx{};
s32 jmp = _sceFiberSetJmp(&ctx);
if (jmp) {
g_ctx = GetFiberContext();
if (g_ctx->prev_fiber) {
g_ctx->prev_fiber->state = FiberState::Idle;
g_ctx->prev_fiber = nullptr;
}
if (arg_on_run) {
*arg_on_run = g_ctx->arg_on_run_to;
}
return ORBIS_OK;
}
cur_fiber->context = &ctx;
_sceFiberCheckStackOverflow(g_ctx);
}
_sceFiberTerminate(cur_fiber, arg_on_return, g_ctx);
__builtin_trap();
}
s32 PS4_SYSV_ABI sceFiberGetInfo(OrbisFiber* fiber, OrbisFiberInfo* fiber_info) {
if (!fiber || !fiber_info) {
return ORBIS_FIBER_ERROR_NULL;
}
if ((u64)fiber & 7 || (u64)fiber_info & 7) {
return ORBIS_FIBER_ERROR_ALIGNMENT;
}
if (fiber_info->size != sizeof(OrbisFiberInfo)) {
return ORBIS_FIBER_ERROR_INVALID;
}
if (fiber->magic_start != kFiberSignature0 || fiber->magic_end != kFiberSignature1) {
return ORBIS_FIBER_ERROR_INVALID;
}
fiber_info->entry = fiber->entry;
fiber_info->arg_on_initialize = fiber->arg_on_initialize;
fiber_info->addr_context = fiber->addr_context;
fiber_info->size_context = fiber->size_context;
strncpy(fiber_info->name, fiber->name, ORBIS_FIBER_MAX_NAME_LENGTH);
fiber_info->size_context_margin = -1;
if (fiber->flags & FiberFlags::ContextSizeCheck && fiber->addr_context != nullptr) {
u64 stack_margin = 0;
u64* stack_start = reinterpret_cast<u64*>(fiber->context_start);
u64* stack_end = reinterpret_cast<u64*>(fiber->context_end);
if (*stack_start == kFiberStackSignature) {
u64* stack_ptr = stack_start + 1;
while (stack_ptr < stack_end) {
if (*stack_ptr == kFiberStackSizeCheck) {
stack_ptr++;
}
}
stack_margin =
reinterpret_cast<u64>(stack_ptr) - reinterpret_cast<u64>(stack_start + 1);
}
fiber_info->size_context_margin = stack_margin;
}
strncpy(fiberInfo->name, fiber->name, ORBIS_FIBER_MAX_NAME_LENGTH);
return ORBIS_OK; return ORBIS_OK;
} }
s32 PS4_SYSV_ABI sceFiberStartContextSizeCheck(u32 flags) { s32 PS4_SYSV_ABI sceFiberStartContextSizeCheck(u32 flags) {
LOG_ERROR(Lib_Fiber, "called");
if (flags != 0) { if (flags != 0) {
return ORBIS_FIBER_ERROR_INVALID; return ORBIS_FIBER_ERROR_INVALID;
} }
u32 expected = 0;
if (!context_size_check.compare_exchange_strong(expected, 1u)) {
return ORBIS_FIBER_ERROR_STATE;
}
return ORBIS_OK; return ORBIS_OK;
} }
s32 PS4_SYSV_ABI sceFiberStopContextSizeCheck() { s32 PS4_SYSV_ABI sceFiberStopContextSizeCheck() {
LOG_ERROR(Lib_Fiber, "called"); u32 expected = 1;
if (!context_size_check.compare_exchange_strong(expected, 0u)) {
return ORBIS_FIBER_ERROR_STATE;
}
return ORBIS_OK; return ORBIS_OK;
} }
s32 PS4_SYSV_ABI sceFiberRename(SceFiber* fiber, const char* name) { s32 PS4_SYSV_ABI sceFiberRename(OrbisFiber* fiber, const char* name) {
LOG_INFO(Lib_Fiber, "called, name = {}", name);
if (!fiber || !name) { if (!fiber || !name) {
return ORBIS_FIBER_ERROR_NULL; return ORBIS_FIBER_ERROR_NULL;
} }
if ((u64)fiber % 8 != 0) { if ((u64)fiber & 7) {
return ORBIS_FIBER_ERROR_ALIGNMENT; return ORBIS_FIBER_ERROR_ALIGNMENT;
} }
if (fiber->magic_start != kFiberSignature0 || fiber->magic_end != kFiberSignature1) {
return ORBIS_FIBER_ERROR_INVALID;
}
strncpy(fiber->name, name, ORBIS_FIBER_MAX_NAME_LENGTH); strncpy(fiber->name, name, ORBIS_FIBER_MAX_NAME_LENGTH);
return ORBIS_OK; return ORBIS_OK;
@ -262,6 +464,7 @@ s32 PS4_SYSV_ABI sceFiberRename(SceFiber* fiber, const char* name) {
void RegisterlibSceFiber(Core::Loader::SymbolsResolver* sym) { void RegisterlibSceFiber(Core::Loader::SymbolsResolver* sym) {
LIB_FUNCTION("hVYD7Ou2pCQ", "libSceFiber", 1, "libSceFiber", 1, 1, sceFiberInitialize); LIB_FUNCTION("hVYD7Ou2pCQ", "libSceFiber", 1, "libSceFiber", 1, 1, sceFiberInitialize);
LIB_FUNCTION("7+OJIpko9RY", "libSceFiber", 1, "libSceFiber", 1, 1, sceFiberInitialize);
LIB_FUNCTION("asjUJJ+aa8s", "libSceFiber", 1, "libSceFiber", 1, 1, sceFiberOptParamInitialize); LIB_FUNCTION("asjUJJ+aa8s", "libSceFiber", 1, "libSceFiber", 1, 1, sceFiberOptParamInitialize);
LIB_FUNCTION("JeNX5F-NzQU", "libSceFiber", 1, "libSceFiber", 1, 1, sceFiberFinalize); LIB_FUNCTION("JeNX5F-NzQU", "libSceFiber", 1, "libSceFiber", 1, 1, sceFiberFinalize);

View File

@ -6,73 +6,113 @@
#include "common/assert.h" #include "common/assert.h"
#include "common/types.h" #include "common/types.h"
#include <atomic>
namespace Core::Loader { namespace Core::Loader {
class SymbolsResolver; class SymbolsResolver;
} }
namespace Libraries::Fiber { namespace Libraries::Fiber {
#define ORBIS_FIBER_MAX_NAME_LENGTH (31) #define ORBIS_FIBER_MAX_NAME_LENGTH (31)
#define ORBIS_FIBER_CONTEXT_MINIMUM_SIZE (512)
typedef void PS4_SYSV_ABI (*SceFiberEntry)(u64 argOnInitialize, u64 argOnRun); typedef void PS4_SYSV_ABI (*OrbisFiberEntry)(u64 arg_on_initialize, u64 arg_on_run);
enum FiberState : u32 { enum FiberState : u32 {
None = 0u, Run = 1u,
Init = 1u, Idle = 2u,
Run = 2u, Terminated = 3u,
Suspend = 3u,
}; };
struct SceFiber { enum FiberFlags : u32 {
u64 signature; None = 0x0,
FiberState state; NoUlobjmgr = 0x1,
SceFiberEntry entry; ContextSizeCheck = 0x10,
u64 argOnInitialize; SetFpuRegs = 0x100,
u64 argRun;
u64* pArgRun;
u64 argReturn;
u64* pArgReturn;
u64 sizeContext;
char name[ORBIS_FIBER_MAX_NAME_LENGTH];
void* handle;
}; };
static_assert(sizeof(SceFiber) <= 256);
struct SceFiberInfo { struct OrbisFiber;
u64 size;
SceFiberEntry entry; struct OrbisFiberContext {
u64 argOnInitialize; struct {
void* addrContext; u64 rax, rcx, rdx, rbx, rsp, rbp, r8, r9, r10, r11, r12, r13, r14, r15;
u64 sizeContext; u16 fpucw;
u32 mxcsr;
};
OrbisFiber* current_fiber;
OrbisFiber* prev_fiber;
u64 arg_on_run_to;
u64 arg_on_return;
u64 return_val;
};
struct OrbisFiberData {
OrbisFiberEntry entry;
u64 arg_on_initialize;
u64 arg_on_run_to;
void* stack_addr;
u32* state;
u16 fpucw;
s8 pad[2];
u32 mxcsr;
};
struct OrbisFiber {
u32 magic_start;
std::atomic<FiberState> state;
OrbisFiberEntry entry;
u64 arg_on_initialize;
void* addr_context;
u64 size_context;
char name[ORBIS_FIBER_MAX_NAME_LENGTH + 1]; char name[ORBIS_FIBER_MAX_NAME_LENGTH + 1];
u64 sizeContextMargin; OrbisFiberContext* context;
u32 flags;
void* context_start;
void* context_end;
u32 magic_end;
}; };
static_assert(sizeof(SceFiberInfo) <= 128); static_assert(sizeof(OrbisFiber) <= 256);
using SceFiberOptParam = void*; struct OrbisFiberInfo {
u64 size;
OrbisFiberEntry entry;
u64 arg_on_initialize;
void* addr_context;
u64 size_context;
char name[ORBIS_FIBER_MAX_NAME_LENGTH + 1];
u64 size_context_margin;
u8 pad[48];
};
static_assert(sizeof(OrbisFiberInfo) == 128);
s32 PS4_SYSV_ABI sceFiberInitialize(SceFiber* fiber, const char* name, SceFiberEntry entry, struct OrbisFiberOptParam {
u64 argOnInitialize, void* addrContext, u64 sizeContext, u32 magic;
const SceFiberOptParam* optParam); };
static_assert(sizeof(OrbisFiberOptParam) <= 128);
s32 PS4_SYSV_ABI sceFiberOptParamInitialize(SceFiberOptParam* optParam); s32 PS4_SYSV_ABI sceFiberInitialize(OrbisFiber* fiber, const char* name, OrbisFiberEntry entry,
u64 arg_on_initialize, void* addr_context, u64 size_context,
const OrbisFiberOptParam* opt_param, u32 build_version);
s32 PS4_SYSV_ABI sceFiberFinalize(SceFiber* fiber); s32 PS4_SYSV_ABI sceFiberOptParamInitialize(OrbisFiberOptParam* opt_param);
s32 PS4_SYSV_ABI sceFiberRun(SceFiber* fiber, u64 argOnRunTo, u64* argOnReturn); s32 PS4_SYSV_ABI sceFiberFinalize(OrbisFiber* fiber);
s32 PS4_SYSV_ABI sceFiberSwitch(SceFiber* fiber, u64 argOnRunTo, u64* argOnRun); s32 PS4_SYSV_ABI sceFiberRun(OrbisFiber* fiber, u64 arg_on_run_to, u64* arg_on_return);
s32 PS4_SYSV_ABI sceFiberGetSelf(SceFiber** fiber); s32 PS4_SYSV_ABI sceFiberSwitch(OrbisFiber* fiber, u64 arg_on_run_to, u64* arg_on_run);
s32 PS4_SYSV_ABI sceFiberReturnToThread(u64 argOnReturn, u64* argOnRun); s32 PS4_SYSV_ABI sceFiberGetSelf(OrbisFiber** fiber);
s32 PS4_SYSV_ABI sceFiberGetInfo(SceFiber* fiber, SceFiberInfo* fiberInfo); s32 PS4_SYSV_ABI sceFiberReturnToThread(u64 arg_on_return, u64* arg_on_run);
s32 PS4_SYSV_ABI sceFiberGetInfo(OrbisFiber* fiber, OrbisFiberInfo* fiber_info);
s32 PS4_SYSV_ABI sceFiberStartContextSizeCheck(u32 flags); s32 PS4_SYSV_ABI sceFiberStartContextSizeCheck(u32 flags);
s32 PS4_SYSV_ABI sceFiberStopContextSizeCheck(void); s32 PS4_SYSV_ABI sceFiberStopContextSizeCheck(void);
s32 PS4_SYSV_ABI sceFiberRename(SceFiber* fiber, const char* name); s32 PS4_SYSV_ABI sceFiberRename(OrbisFiber* fiber, const char* name);
void RegisterlibSceFiber(Core::Loader::SymbolsResolver* sym); void RegisterlibSceFiber(Core::Loader::SymbolsResolver* sym);
} // namespace Libraries::Fiber } // namespace Libraries::Fiber

View File

@ -0,0 +1,121 @@
# SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project
# SPDX-License-Identifier: GPL-2.0-or-later
.global _sceFiberSetJmp
_sceFiberSetJmp:
movq %rax, 0x0(%rdi)
movq (%rsp), %rdx
movq %rdx, 0x10(%rdi)
movq %rcx, 0x08(%rdi)
movq %rbx, 0x18(%rdi)
movq %rsp, 0x20(%rdi)
movq %rbp, 0x28(%rdi)
movq %r8, 0x30(%rdi)
movq %r9, 0x38(%rdi)
movq %r10, 0x40(%rdi)
movq %r11, 0x48(%rdi)
movq %r12, 0x50(%rdi)
movq %r13, 0x58(%rdi)
movq %r14, 0x60(%rdi)
movq %r15, 0x68(%rdi)
fnstcw 0x70(%rdi)
stmxcsr 0x72(%rdi)
xor %eax, %eax
ret
.global _sceFiberLongJmp
_sceFiberLongJmp:
# MXCSR = (MXCSR & 0x3f) ^ (ctx->mxcsr & ~0x3f)
stmxcsr -0x4(%rsp)
movl 0x72(%rdi), %eax
andl $0xffffffc0, %eax
movl -0x4(%rsp), %ecx
andl $0x3f, %ecx
xorl %eax, %ecx
movl %ecx, -0x4(%rsp)
ldmxcsr -0x4(%rsp)
movq 0x00(%rdi), %rax
movq 0x08(%rdi), %rcx
movq 0x10(%rdi), %rdx
movq 0x18(%rdi), %rbx
movq 0x20(%rdi), %rsp
movq 0x28(%rdi), %rbp
movq 0x30(%rdi), %r8
movq 0x38(%rdi), %r9
movq 0x40(%rdi), %r10
movq 0x48(%rdi), %r11
movq 0x50(%rdi), %r12
movq 0x58(%rdi), %r13
movq 0x60(%rdi), %r14
movq 0x68(%rdi), %r15
fldcw 0x70(%rdi)
# Make the jump and return 1
movq %rdx, 0x00(%rsp)
movl $0x1, %eax
ret
.global _sceFiberSwitchEntry
_sceFiberSwitchEntry:
mov %rdi, %r11
# Set stack address to provided stack
movq 0x18(%r11), %rsp
xorl %ebp, %ebp
movq 0x20(%r11), %r10 # data->state
# Set previous fiber state to Idle
test %r10, %r10
jz .clear_regs
movl $2, (%r10)
.clear_regs:
test %esi, %esi
jz .skip_fpu_regs
ldmxcsr 0x2c(%r11)
fldcw 0x28(%r11)
.skip_fpu_regs:
movq 0x08(%r11), %rdi # data->arg_on_initialize
movq 0x10(%r11), %rsi # data->arg_on_run_to
movq 0x00(%r11), %r11 # data->entry
xorl %eax, %eax
xorl %ebx, %ebx
xorl %ecx, %ecx
xorl %edx, %edx
xorq %r8, %r8
xorq %r9, %r9
xorq %r10, %r10
xorq %r12, %r12
xorq %r13, %r13
xorq %r14, %r14
xorq %r15, %r15
pxor %mm0, %mm0
pxor %mm1, %mm1
pxor %mm2, %mm2
pxor %mm3, %mm3
pxor %mm4, %mm4
pxor %mm5, %mm5
pxor %mm6, %mm6
pxor %mm7, %mm7
emms
vzeroall
# Call the fiber's entry function: entry(arg_on_initialize, arg_on_run_to)
call *%r11
# Fiber returned, not good
movl $1, %edi
call _sceFiberForceQuit
ret

View File

@ -1,6 +1,8 @@
// 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 <thread>
#include "common/assert.h" #include "common/assert.h"
#include "common/debug.h" #include "common/debug.h"
#include "common/logging/log.h" #include "common/logging/log.h"

View File

@ -90,7 +90,7 @@ public:
const auto start_time = std::chrono::high_resolution_clock::now(); const auto start_time = std::chrono::high_resolution_clock::now();
auto rel_time_ms = std::chrono::ceil<std::chrono::milliseconds>(rel_time); auto rel_time_ms = std::chrono::ceil<std::chrono::milliseconds>(rel_time);
while (rel_time_ms.count() > 0) { do {
u64 timeout_ms = static_cast<u64>(rel_time_ms.count()); u64 timeout_ms = static_cast<u64>(rel_time_ms.count());
u64 res = WaitForSingleObjectEx(sem, timeout_ms, true); u64 res = WaitForSingleObjectEx(sem, timeout_ms, true);
if (res == WAIT_OBJECT_0) { if (res == WAIT_OBJECT_0) {
@ -101,7 +101,7 @@ public:
} else { } else {
return false; return false;
} }
} } while (rel_time_ms.count() > 0);
return false; return false;
#elif defined(__APPLE__) #elif defined(__APPLE__)
@ -117,12 +117,9 @@ public:
bool try_acquire_until(const std::chrono::time_point<Clock, Duration>& abs_time) { bool try_acquire_until(const std::chrono::time_point<Clock, Duration>& abs_time) {
#ifdef _WIN64 #ifdef _WIN64
const auto start_time = Clock::now(); const auto start_time = Clock::now();
if (start_time >= abs_time) {
return false;
}
auto rel_time = std::chrono::ceil<std::chrono::milliseconds>(abs_time - start_time); auto rel_time = std::chrono::ceil<std::chrono::milliseconds>(abs_time - start_time);
while (rel_time.count() > 0) { do {
u64 timeout_ms = static_cast<u64>(rel_time.count()); u64 timeout_ms = static_cast<u64>(rel_time.count());
u64 res = WaitForSingleObjectEx(sem, timeout_ms, true); u64 res = WaitForSingleObjectEx(sem, timeout_ms, true);
if (res == WAIT_OBJECT_0) { if (res == WAIT_OBJECT_0) {
@ -133,7 +130,7 @@ public:
} else { } else {
return false; return false;
} }
} } while (rel_time.count() > 0);
return false; return false;
#elif defined(__APPLE__) #elif defined(__APPLE__)

View File

@ -22,7 +22,7 @@ void SigactionHandler(int signum, siginfo_t* inf, ucontext_t* raw_context) {
if (handler) { if (handler) {
auto ctx = Ucontext{}; auto ctx = Ucontext{};
#ifdef __APPLE__ #ifdef __APPLE__
auto& regs = raw_context->uc_mcontext->__ss; const auto& regs = raw_context->uc_mcontext->__ss;
ctx.uc_mcontext.mc_r8 = regs.__r8; ctx.uc_mcontext.mc_r8 = regs.__r8;
ctx.uc_mcontext.mc_r9 = regs.__r9; ctx.uc_mcontext.mc_r9 = regs.__r9;
ctx.uc_mcontext.mc_r10 = regs.__r10; ctx.uc_mcontext.mc_r10 = regs.__r10;
@ -42,7 +42,7 @@ void SigactionHandler(int signum, siginfo_t* inf, ucontext_t* raw_context) {
ctx.uc_mcontext.mc_fs = regs.__fs; ctx.uc_mcontext.mc_fs = regs.__fs;
ctx.uc_mcontext.mc_gs = regs.__gs; ctx.uc_mcontext.mc_gs = regs.__gs;
#else #else
auto& regs = raw_context->uc_mcontext.gregs; const auto& regs = raw_context->uc_mcontext.gregs;
ctx.uc_mcontext.mc_r8 = regs[REG_R8]; ctx.uc_mcontext.mc_r8 = regs[REG_R8];
ctx.uc_mcontext.mc_r9 = regs[REG_R9]; ctx.uc_mcontext.mc_r9 = regs[REG_R9];
ctx.uc_mcontext.mc_r10 = regs[REG_R10]; ctx.uc_mcontext.mc_r10 = regs[REG_R10];
@ -131,8 +131,12 @@ int PS4_SYSV_ABI sceKernelRaiseException(PthreadT thread, int signum) {
LOG_WARNING(Lib_Kernel, "Raising exception on thread '{}'", thread->name); LOG_WARNING(Lib_Kernel, "Raising exception on thread '{}'", thread->name);
ASSERT_MSG(signum == POSIX_SIGUSR1, "Attempting to raise non user defined signal!"); ASSERT_MSG(signum == POSIX_SIGUSR1, "Attempting to raise non user defined signal!");
#ifndef _WIN64 #ifndef _WIN64
pthread_t pthr = *reinterpret_cast<pthread_t*>(thread->native_thr.GetHandle()); const auto pthr = reinterpret_cast<pthread_t>(thread->native_thr.GetHandle());
pthread_kill(pthr, SIGUSR2); const auto ret = pthread_kill(pthr, SIGUSR2);
if (ret != 0) {
LOG_ERROR(Kernel, "Failed to send exception signal to thread '{}': {}", thread->name,
strerror(ret));
}
#else #else
USER_APC_OPTION option; USER_APC_OPTION option;
option.UserApcFlags = QueueUserApcFlagsSpecialUserApc; option.UserApcFlags = QueueUserApcFlagsSpecialUserApc;

View File

@ -53,6 +53,7 @@ Core::Tcb* TcbCtor(Pthread* thread, int initial) {
if (tcb) { if (tcb) {
tcb->tcb_thread = thread; tcb->tcb_thread = thread;
tcb->tcb_fiber = nullptr;
} }
return tcb; return tcb;
} }

View File

@ -11,6 +11,7 @@
#else #else
#include <csignal> #include <csignal>
#include <pthread.h> #include <pthread.h>
#include <unistd.h>
#endif #endif
namespace Core { namespace Core {

View File

@ -9,6 +9,10 @@ namespace Xbyak {
class CodeGenerator; class CodeGenerator;
} }
namespace Libraries::Fiber {
struct OrbisFiberContext;
}
namespace Core { namespace Core {
union DtvEntry { union DtvEntry {
@ -20,6 +24,7 @@ struct Tcb {
Tcb* tcb_self; Tcb* tcb_self;
DtvEntry* tcb_dtv; DtvEntry* tcb_dtv;
void* tcb_thread; void* tcb_thread;
::Libraries::Fiber::OrbisFiberContext* tcb_fiber;
}; };
#ifdef _WIN32 #ifdef _WIN32

View File

@ -15,6 +15,7 @@
#include <QNetworkRequest> #include <QNetworkRequest>
#include <QProcess> #include <QProcess>
#include <QPushButton> #include <QPushButton>
#include <QStandardPaths>
#include <QString> #include <QString>
#include <QStringList> #include <QStringList>
#include <QTextEdit> #include <QTextEdit>
@ -212,9 +213,9 @@ void CheckUpdate::setupUI(const QString& downloadUrl, const QString& latestDate,
// Don't show changelog button if: // Don't show changelog button if:
// The current version is a pre-release and the version to be downloaded is a release. // The current version is a pre-release and the version to be downloaded is a release.
bool current_isRelease = currentRev.startsWith('v', Qt::CaseInsensitive); bool current_isWIP = currentRev.endsWith("WIP", Qt::CaseInsensitive);
bool latest_isRelease = latestRev.startsWith('v', Qt::CaseInsensitive); bool latest_isWIP = latestRev.endsWith("WIP", Qt::CaseInsensitive);
if (!current_isRelease && latest_isRelease) { if (current_isWIP && !latest_isWIP) {
} else { } else {
QTextEdit* textField = new QTextEdit(this); QTextEdit* textField = new QTextEdit(this);
textField->setReadOnly(true); textField->setReadOnly(true);
@ -348,7 +349,9 @@ void CheckUpdate::DownloadUpdate(const QString& url) {
QString userPath; QString userPath;
Common::FS::PathToQString(userPath, Common::FS::GetUserPath(Common::FS::PathType::UserDir)); Common::FS::PathToQString(userPath, Common::FS::GetUserPath(Common::FS::PathType::UserDir));
#ifdef Q_OS_WIN #ifdef Q_OS_WIN
QString tempDownloadPath = QString(getenv("LOCALAPPDATA")) + "/Temp/temp_download_update"; QString tempDownloadPath =
QStandardPaths::writableLocation(QStandardPaths::AppDataLocation) +
"/Temp/temp_download_update";
#else #else
QString tempDownloadPath = userPath + "/temp_download_update"; QString tempDownloadPath = userPath + "/temp_download_update";
#endif #endif
@ -397,10 +400,11 @@ void CheckUpdate::Install() {
QString processCommand; QString processCommand;
#ifdef Q_OS_WIN #ifdef Q_OS_WIN
// On windows, overwrite tempDirPath with AppData/Local/Temp folder // On windows, overwrite tempDirPath with AppData/Roaming/shadps4/Temp folder
// due to PowerShell Expand-Archive not being able to handle correctly // due to PowerShell Expand-Archive not being able to handle correctly
// paths in square brackets (ie: ./[shadps4]) // paths in square brackets (ie: ./[shadps4])
tempDirPath = QString(getenv("LOCALAPPDATA")) + "/Temp/temp_download_update"; tempDirPath = QStandardPaths::writableLocation(QStandardPaths::AppDataLocation) +
"/Temp/temp_download_update";
// Windows Batch Script // Windows Batch Script
scriptFileName = tempDirPath + "/update.ps1"; scriptFileName = tempDirPath + "/update.ps1";
@ -536,6 +540,7 @@ void CheckUpdate::Install() {
QFile scriptFile(scriptFileName); QFile scriptFile(scriptFileName);
if (scriptFile.open(QIODevice::WriteOnly | QIODevice::Text)) { if (scriptFile.open(QIODevice::WriteOnly | QIODevice::Text)) {
QTextStream out(&scriptFile); QTextStream out(&scriptFile);
scriptFile.write("\xEF\xBB\xBF");
#ifdef Q_OS_WIN #ifdef Q_OS_WIN
out << scriptContent.arg(binaryStartingUpdate).arg(tempDirPath).arg(rootPath); out << scriptContent.arg(binaryStartingUpdate).arg(tempDirPath).arg(rootPath);
#endif #endif

View File

@ -18,7 +18,8 @@ CompatibilityInfoClass::CompatibilityInfoClass()
}; };
CompatibilityInfoClass::~CompatibilityInfoClass() = default; CompatibilityInfoClass::~CompatibilityInfoClass() = default;
void CompatibilityInfoClass::UpdateCompatibilityDatabase(QWidget* parent) { void CompatibilityInfoClass::UpdateCompatibilityDatabase(QWidget* parent, bool forced) {
if (!forced)
if (LoadCompatibilityFile()) if (LoadCompatibilityFile())
return; return;
@ -45,6 +46,7 @@ void CompatibilityInfoClass::UpdateCompatibilityDatabase(QWidget* parent) {
QMessageBox::critical(parent, tr("Error"), QMessageBox::critical(parent, tr("Error"),
tr("Unable to update compatibility data! Try again later.")); tr("Unable to update compatibility data! Try again later."));
// Try loading compatibility_file.json again // Try loading compatibility_file.json again
if (!forced)
LoadCompatibilityFile(); LoadCompatibilityFile();
return; return;
} }

View File

@ -84,7 +84,7 @@ public:
CompatibilityInfoClass(); CompatibilityInfoClass();
~CompatibilityInfoClass(); ~CompatibilityInfoClass();
void UpdateCompatibilityDatabase(QWidget* parent = nullptr); void UpdateCompatibilityDatabase(QWidget* parent = nullptr, bool forced = false);
bool LoadCompatibilityFile(); bool LoadCompatibilityFile();
CompatibilityEntry GetCompatibilityInfo(const std::string& serial); CompatibilityEntry GetCompatibilityInfo(const std::string& serial);
void ExtractCompatibilityInfo(QByteArray response); void ExtractCompatibilityInfo(QByteArray response);

View File

@ -3,9 +3,12 @@
#include "common/path_util.h" #include "common/path_util.h"
#include "game_grid_frame.h" #include "game_grid_frame.h"
#include "qt_gui/compatibility_info.h"
GameGridFrame::GameGridFrame(std::shared_ptr<GameInfoClass> game_info_get, QWidget* parent) GameGridFrame::GameGridFrame(std::shared_ptr<GameInfoClass> game_info_get,
: QTableWidget(parent), m_game_info(game_info_get) { std::shared_ptr<CompatibilityInfoClass> compat_info_get,
QWidget* parent)
: QTableWidget(parent), m_game_info(game_info_get), m_compat_info(compat_info_get) {
icon_size = Config::getIconSizeGrid(); icon_size = Config::getIconSizeGrid();
windowWidth = parent->width(); windowWidth = parent->width();
this->setShowGrid(false); this->setShowGrid(false);
@ -29,7 +32,7 @@ GameGridFrame::GameGridFrame(std::shared_ptr<GameInfoClass> game_info_get, QWidg
connect(this->horizontalScrollBar(), &QScrollBar::valueChanged, this, connect(this->horizontalScrollBar(), &QScrollBar::valueChanged, this,
&GameGridFrame::RefreshGridBackgroundImage); &GameGridFrame::RefreshGridBackgroundImage);
connect(this, &QTableWidget::customContextMenuRequested, this, [=, this](const QPoint& pos) { connect(this, &QTableWidget::customContextMenuRequested, this, [=, this](const QPoint& pos) {
m_gui_context_menus.RequestGameMenu(pos, m_game_info->m_games, this, false); m_gui_context_menus.RequestGameMenu(pos, m_game_info->m_games, m_compat_info, this, false);
}); });
} }

View File

@ -10,6 +10,7 @@
#include "game_info.h" #include "game_info.h"
#include "game_list_utils.h" #include "game_list_utils.h"
#include "gui_context_menus.h" #include "gui_context_menus.h"
#include "qt_gui/compatibility_info.h"
class GameGridFrame : public QTableWidget { class GameGridFrame : public QTableWidget {
Q_OBJECT Q_OBJECT
@ -29,11 +30,14 @@ private:
GameListUtils m_game_list_utils; GameListUtils m_game_list_utils;
GuiContextMenus m_gui_context_menus; GuiContextMenus m_gui_context_menus;
std::shared_ptr<GameInfoClass> m_game_info; std::shared_ptr<GameInfoClass> m_game_info;
std::shared_ptr<CompatibilityInfoClass> m_compat_info;
std::shared_ptr<QVector<GameInfo>> m_games_shared; std::shared_ptr<QVector<GameInfo>> m_games_shared;
bool validCellSelected = false; bool validCellSelected = false;
public: public:
explicit GameGridFrame(std::shared_ptr<GameInfoClass> game_info_get, QWidget* parent = nullptr); explicit GameGridFrame(std::shared_ptr<GameInfoClass> game_info_get,
std::shared_ptr<CompatibilityInfoClass> compat_info_get,
QWidget* parent = nullptr);
void PopulateGameGrid(QVector<GameInfo> m_games, bool fromSearch); void PopulateGameGrid(QVector<GameInfo> m_games, bool fromSearch);
bool IsValidCellSelected(); bool IsValidCellSelected();

View File

@ -2,6 +2,7 @@
// SPDX-License-Identifier: GPL-2.0-or-later // SPDX-License-Identifier: GPL-2.0-or-later
#include <QToolTip> #include <QToolTip>
#include "common/config.h"
#include "common/logging/log.h" #include "common/logging/log.h"
#include "common/path_util.h" #include "common/path_util.h"
#include "common/string_util.h" #include "common/string_util.h"
@ -72,7 +73,7 @@ GameListFrame::GameListFrame(std::shared_ptr<GameInfoClass> game_info_get,
}); });
connect(this, &QTableWidget::customContextMenuRequested, this, [=, this](const QPoint& pos) { connect(this, &QTableWidget::customContextMenuRequested, this, [=, this](const QPoint& pos) {
m_gui_context_menus.RequestGameMenu(pos, m_game_info->m_games, this, true); m_gui_context_menus.RequestGameMenu(pos, m_game_info->m_games, m_compat_info, this, true);
}); });
connect(this, &QTableWidget::cellClicked, this, [=, this](int row, int column) { connect(this, &QTableWidget::cellClicked, this, [=, this](int row, int column) {
@ -80,11 +81,6 @@ GameListFrame::GameListFrame(std::shared_ptr<GameInfoClass> game_info_get,
QDesktopServices::openUrl(QUrl(m_game_info->m_games[row].compatibility.url)); QDesktopServices::openUrl(QUrl(m_game_info->m_games[row].compatibility.url));
} }
}); });
// Do not show status column if it is not enabled
if (!Config::getCompatibilityEnabled()) {
this->setColumnHidden(2, true);
}
} }
void GameListFrame::onCurrentCellChanged(int currentRow, int currentColumn, int previousRow, void GameListFrame::onCurrentCellChanged(int currentRow, int currentColumn, int previousRow,
@ -108,6 +104,8 @@ void GameListFrame::PlayBackgroundMusic(QTableWidgetItem* item) {
} }
void GameListFrame::PopulateGameList() { void GameListFrame::PopulateGameList() {
// Do not show status column if it is not enabled
this->setColumnHidden(2, !Config::getCompatibilityEnabled());
this->setRowCount(m_game_info->m_games.size()); this->setRowCount(m_game_info->m_games.size());
ResizeIcons(icon_size); ResizeIcons(icon_size);
@ -241,7 +239,7 @@ void GameListFrame::SetCompatibilityItem(int row, int column, CompatibilityEntry
break; break;
case CompatibilityStatus::Nothing: case CompatibilityStatus::Nothing:
color = QStringLiteral("#212121"); color = QStringLiteral("#212121");
status_explanation = tr("Games does not initialize properly / crashes the emulator"); status_explanation = tr("Game does not initialize properly / crashes the emulator");
break; break;
case CompatibilityStatus::Boots: case CompatibilityStatus::Boots:
color = QStringLiteral("#828282"); color = QStringLiteral("#828282");

View File

@ -11,6 +11,9 @@
#include <QTreeWidgetItem> #include <QTreeWidgetItem>
#include "cheats_patches.h" #include "cheats_patches.h"
#include "common/config.h"
#include "common/version.h"
#include "compatibility_info.h"
#include "game_info.h" #include "game_info.h"
#include "trophy_viewer.h" #include "trophy_viewer.h"
@ -27,8 +30,9 @@
class GuiContextMenus : public QObject { class GuiContextMenus : public QObject {
Q_OBJECT Q_OBJECT
public: public:
void RequestGameMenu(const QPoint& pos, QVector<GameInfo> m_games, QTableWidget* widget, void RequestGameMenu(const QPoint& pos, QVector<GameInfo> m_games,
bool isList) { std::shared_ptr<CompatibilityInfoClass> m_compat_info,
QTableWidget* widget, bool isList) {
QPoint global_pos = widget->viewport()->mapToGlobal(pos); QPoint global_pos = widget->viewport()->mapToGlobal(pos);
int itemID = 0; int itemID = 0;
if (isList) { if (isList) {
@ -91,6 +95,21 @@ public:
menu.addMenu(deleteMenu); menu.addMenu(deleteMenu);
// Compatibility submenu.
QMenu* compatibilityMenu = new QMenu(tr("Compatibility..."), widget);
QAction* updateCompatibility = new QAction(tr("Update database"), widget);
QAction* viewCompatibilityReport = new QAction(tr("View report"), widget);
QAction* submitCompatibilityReport = new QAction(tr("Submit a report"), widget);
compatibilityMenu->addAction(updateCompatibility);
compatibilityMenu->addAction(viewCompatibilityReport);
compatibilityMenu->addAction(submitCompatibilityReport);
menu.addMenu(compatibilityMenu);
compatibilityMenu->setEnabled(Config::getCompatibilityEnabled());
viewCompatibilityReport->setEnabled(!m_games[itemID].compatibility.url.isEmpty());
// Show menu. // Show menu.
auto selected = menu.exec(global_pos); auto selected = menu.exec(global_pos);
if (!selected) { if (!selected) {
@ -268,11 +287,11 @@ public:
#endif #endif
QMessageBox::information( QMessageBox::information(
nullptr, tr("Shortcut creation"), nullptr, tr("Shortcut creation"),
QString(tr("Shortcut created successfully!\n %1")).arg(linkPath)); QString(tr("Shortcut created successfully!") + "\n%1").arg(linkPath));
} else { } else {
QMessageBox::critical( QMessageBox::critical(
nullptr, tr("Error"), nullptr, tr("Error"),
QString(tr("Error creating shortcut!\n %1")).arg(linkPath)); QString(tr("Error creating shortcut!") + "\n%1").arg(linkPath));
} }
} else { } else {
QMessageBox::critical(nullptr, tr("Error"), tr("Failed to convert icon.")); QMessageBox::critical(nullptr, tr("Error"), tr("Failed to convert icon."));
@ -286,11 +305,11 @@ public:
#endif #endif
QMessageBox::information( QMessageBox::information(
nullptr, tr("Shortcut creation"), nullptr, tr("Shortcut creation"),
QString(tr("Shortcut created successfully!\n %1")).arg(linkPath)); QString(tr("Shortcut created successfully!") + "\n%1").arg(linkPath));
} else { } else {
QMessageBox::critical( QMessageBox::critical(
nullptr, tr("Error"), nullptr, tr("Error"),
QString(tr("Error creating shortcut!\n %1")).arg(linkPath)); QString(tr("Error creating shortcut!") + "\n%1").arg(linkPath));
} }
} }
} }
@ -360,6 +379,31 @@ public:
} }
} }
} }
if (selected == updateCompatibility) {
m_compat_info->UpdateCompatibilityDatabase(widget, true);
}
if (selected == viewCompatibilityReport) {
if (!m_games[itemID].compatibility.url.isEmpty())
QDesktopServices::openUrl(QUrl(m_games[itemID].compatibility.url));
}
if (selected == submitCompatibilityReport) {
QUrl url = QUrl("https://github.com/shadps4-emu/shadps4-game-compatibility/issues/new");
QUrlQuery query;
query.addQueryItem("template", QString("game_compatibility.yml"));
query.addQueryItem(
"title", QString("%1 - %2").arg(QString::fromStdString(m_games[itemID].serial),
QString::fromStdString(m_games[itemID].name)));
query.addQueryItem("game-name", QString::fromStdString(m_games[itemID].name));
query.addQueryItem("game-code", QString::fromStdString(m_games[itemID].serial));
query.addQueryItem("game-version", QString::fromStdString(m_games[itemID].version));
query.addQueryItem("emulator-version", QString(Common::VERSION));
url.setQuery(query);
QDesktopServices::openUrl(url);
}
} }
int GetRowIndex(QTreeWidget* treeWidget, QTreeWidgetItem* item) { int GetRowIndex(QTreeWidget* treeWidget, QTreeWidgetItem* item) {

View File

@ -153,7 +153,7 @@ void MainWindow::CreateDockWindows() {
m_dock_widget.reset(new QDockWidget(tr("Game List"), this)); m_dock_widget.reset(new QDockWidget(tr("Game List"), this));
m_game_list_frame.reset(new GameListFrame(m_game_info, m_compat_info, this)); m_game_list_frame.reset(new GameListFrame(m_game_info, m_compat_info, this));
m_game_list_frame->setObjectName("gamelist"); m_game_list_frame->setObjectName("gamelist");
m_game_grid_frame.reset(new GameGridFrame(m_game_info, this)); m_game_grid_frame.reset(new GameGridFrame(m_game_info, m_compat_info, this));
m_game_grid_frame->setObjectName("gamegridlist"); m_game_grid_frame->setObjectName("gamegridlist");
m_elf_viewer.reset(new ElfViewer(this)); m_elf_viewer.reset(new ElfViewer(this));
m_elf_viewer->setObjectName("elflist"); m_elf_viewer->setObjectName("elflist");
@ -266,20 +266,26 @@ void MainWindow::CreateConnects() {
&MainWindow::StartGame); &MainWindow::StartGame);
connect(ui->configureAct, &QAction::triggered, this, [this]() { connect(ui->configureAct, &QAction::triggered, this, [this]() {
auto settingsDialog = new SettingsDialog(m_physical_devices, this); auto settingsDialog = new SettingsDialog(m_physical_devices, m_compat_info, this);
connect(settingsDialog, &SettingsDialog::LanguageChanged, this, connect(settingsDialog, &SettingsDialog::LanguageChanged, this,
&MainWindow::OnLanguageChanged); &MainWindow::OnLanguageChanged);
connect(settingsDialog, &SettingsDialog::CompatibilityChanged, this,
&MainWindow::RefreshGameTable);
settingsDialog->exec(); settingsDialog->exec();
}); });
connect(ui->settingsButton, &QPushButton::clicked, this, [this]() { connect(ui->settingsButton, &QPushButton::clicked, this, [this]() {
auto settingsDialog = new SettingsDialog(m_physical_devices, this); auto settingsDialog = new SettingsDialog(m_physical_devices, m_compat_info, this);
connect(settingsDialog, &SettingsDialog::LanguageChanged, this, connect(settingsDialog, &SettingsDialog::LanguageChanged, this,
&MainWindow::OnLanguageChanged); &MainWindow::OnLanguageChanged);
connect(settingsDialog, &SettingsDialog::CompatibilityChanged, this,
&MainWindow::RefreshGameTable);
settingsDialog->exec(); settingsDialog->exec();
}); });

View File

@ -6,6 +6,8 @@
#include <QHoverEvent> #include <QHoverEvent>
#include <common/version.h> #include <common/version.h>
#include "common/config.h"
#include "qt_gui/compatibility_info.h"
#ifdef ENABLE_DISCORD_RPC #ifdef ENABLE_DISCORD_RPC
#include "common/discord_rpc_handler.h" #include "common/discord_rpc_handler.h"
#endif #endif
@ -55,7 +57,9 @@ QStringList languageNames = {"Arabic",
const QVector<int> languageIndexes = {21, 23, 14, 6, 18, 1, 12, 22, 2, 4, 25, 24, 29, 5, 0, 9, const QVector<int> languageIndexes = {21, 23, 14, 6, 18, 1, 12, 22, 2, 4, 25, 24, 29, 5, 0, 9,
15, 16, 17, 7, 26, 8, 11, 20, 3, 13, 27, 10, 19, 30, 28}; 15, 16, 17, 7, 26, 8, 11, 20, 3, 13, 27, 10, 19, 30, 28};
SettingsDialog::SettingsDialog(std::span<const QString> physical_devices, QWidget* parent) SettingsDialog::SettingsDialog(std::span<const QString> physical_devices,
std::shared_ptr<CompatibilityInfoClass> m_compat_info,
QWidget* parent)
: QDialog(parent), ui(new Ui::SettingsDialog) { : QDialog(parent), ui(new Ui::SettingsDialog) {
ui->setupUi(this); ui->setupUi(this);
ui->tabWidgetSettings->setUsesScrollButtons(false); ui->tabWidgetSettings->setUsesScrollButtons(false);
@ -141,6 +145,16 @@ SettingsDialog::SettingsDialog(std::span<const QString> physical_devices, QWidge
ui->updaterGroupBox->setVisible(false); ui->updaterGroupBox->setVisible(false);
ui->GUIgroupBox->setMaximumSize(265, 16777215); ui->GUIgroupBox->setMaximumSize(265, 16777215);
#endif #endif
connect(ui->updateCompatibilityButton, &QPushButton::clicked, this,
[this, parent, m_compat_info]() {
m_compat_info->UpdateCompatibilityDatabase(this, true);
emit CompatibilityChanged();
});
connect(ui->enableCompatibilityCheckBox, &QCheckBox::stateChanged, this, [this](int state) {
Config::setCompatibilityEnabled(state);
emit CompatibilityChanged();
});
} }
// Input TAB // Input TAB
@ -197,6 +211,9 @@ SettingsDialog::SettingsDialog(std::span<const QString> physical_devices, QWidge
ui->GUIgroupBox->installEventFilter(this); ui->GUIgroupBox->installEventFilter(this);
ui->widgetComboBox->installEventFilter(this); ui->widgetComboBox->installEventFilter(this);
ui->disableTrophycheckBox->installEventFilter(this); ui->disableTrophycheckBox->installEventFilter(this);
ui->enableCompatibilityCheckBox->installEventFilter(this);
ui->checkCompatibilityOnStartupCheckBox->installEventFilter(this);
ui->updateCompatibilityButton->installEventFilter(this);
// Input // Input
ui->hideCursorGroupBox->installEventFilter(this); ui->hideCursorGroupBox->installEventFilter(this);
@ -291,6 +308,10 @@ void SettingsDialog::LoadValuesFromConfig() {
ui->vkSyncValidationCheckBox->setChecked( ui->vkSyncValidationCheckBox->setChecked(
toml::find_or<bool>(data, "Vulkan", "validation_sync", false)); toml::find_or<bool>(data, "Vulkan", "validation_sync", false));
ui->rdocCheckBox->setChecked(toml::find_or<bool>(data, "Vulkan", "rdocEnable", false)); ui->rdocCheckBox->setChecked(toml::find_or<bool>(data, "Vulkan", "rdocEnable", false));
ui->enableCompatibilityCheckBox->setChecked(
toml::find_or<bool>(data, "General", "compatibilityEnabled", false));
ui->checkCompatibilityOnStartupCheckBox->setChecked(
toml::find_or<bool>(data, "General", "checkCompatibilityOnStartup", false));
#ifdef ENABLE_UPDATER #ifdef ENABLE_UPDATER
ui->updateCheckBox->setChecked(toml::find_or<bool>(data, "General", "autoUpdate", false)); ui->updateCheckBox->setChecked(toml::find_or<bool>(data, "General", "autoUpdate", false));
@ -410,6 +431,12 @@ void SettingsDialog::updateNoteTextEdit(const QString& elementName) {
text = tr("widgetComboBox"); text = tr("widgetComboBox");
} else if (elementName == "disableTrophycheckBox") { } else if (elementName == "disableTrophycheckBox") {
text = tr("disableTrophycheckBox"); text = tr("disableTrophycheckBox");
} else if (elementName == "enableCompatibilityCheckBox") {
text = tr("enableCompatibilityCheckBox");
} else if (elementName == "checkCompatibilityOnStartupCheckBox") {
text = tr("checkCompatibilityOnStartupCheckBox");
} else if (elementName == "updateCompatibilityButton") {
text = tr("updateCompatibilityButton");
} }
// Input // Input
@ -524,6 +551,8 @@ void SettingsDialog::UpdateSettings() {
Config::setRdocEnabled(ui->rdocCheckBox->isChecked()); Config::setRdocEnabled(ui->rdocCheckBox->isChecked());
Config::setAutoUpdate(ui->updateCheckBox->isChecked()); Config::setAutoUpdate(ui->updateCheckBox->isChecked());
Config::setUpdateChannel(ui->updateComboBox->currentText().toStdString()); Config::setUpdateChannel(ui->updateComboBox->currentText().toStdString());
Config::setCompatibilityEnabled(ui->enableCompatibilityCheckBox->isChecked());
Config::setCheckCompatibilityOnStartup(ui->checkCompatibilityOnStartupCheckBox->isChecked());
#ifdef ENABLE_DISCORD_RPC #ifdef ENABLE_DISCORD_RPC
auto* rpc = Common::Singleton<DiscordRPCHandler::RPC>::Instance(); auto* rpc = Common::Singleton<DiscordRPCHandler::RPC>::Instance();

View File

@ -3,6 +3,7 @@
#pragma once #pragma once
#include <memory>
#include <span> #include <span>
#include <QDialog> #include <QDialog>
#include <QGroupBox> #include <QGroupBox>
@ -10,6 +11,7 @@
#include "common/config.h" #include "common/config.h"
#include "common/path_util.h" #include "common/path_util.h"
#include "qt_gui/compatibility_info.h"
namespace Ui { namespace Ui {
class SettingsDialog; class SettingsDialog;
@ -18,7 +20,9 @@ class SettingsDialog;
class SettingsDialog : public QDialog { class SettingsDialog : public QDialog {
Q_OBJECT Q_OBJECT
public: public:
explicit SettingsDialog(std::span<const QString> physical_devices, QWidget* parent = nullptr); explicit SettingsDialog(std::span<const QString> physical_devices,
std::shared_ptr<CompatibilityInfoClass> m_compat_info,
QWidget* parent = nullptr);
~SettingsDialog(); ~SettingsDialog();
bool eventFilter(QObject* obj, QEvent* event) override; bool eventFilter(QObject* obj, QEvent* event) override;
@ -28,6 +32,7 @@ public:
signals: signals:
void LanguageChanged(const std::string& locale); void LanguageChanged(const std::string& locale);
void CompatibilityChanged();
private: private:
void LoadValuesFromConfig(); void LoadValuesFromConfig();

View File

@ -11,7 +11,7 @@
<rect> <rect>
<x>0</x> <x>0</x>
<y>0</y> <y>0</y>
<width>854</width> <width>900</width>
<height>834</height> <height>834</height>
</rect> </rect>
</property> </property>
@ -42,20 +42,23 @@
</property> </property>
<layout class="QVBoxLayout" name="settingsDialogLayout"> <layout class="QVBoxLayout" name="settingsDialogLayout">
<item> <item>
<widget class="QScrollArea" name="scrollArea">
<property name="enabled">
<bool>true</bool>
</property>
<property name="frameShape">
<enum>QFrame::Shape::NoFrame</enum>
</property>
<property name="widgetResizable">
<bool>true</bool>
</property>
<widget class="QTabWidget" name="tabWidgetSettings"> <widget class="QTabWidget" name="tabWidgetSettings">
<property name="enabled"> <property name="enabled">
<bool>true</bool> <bool>true</bool>
</property> </property>
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="currentIndex">
<number>0</number>
</property>
<widget class="QScrollArea" name="generalTab">
<property name="widgetResizable">
<bool>true</bool>
</property>
<property name="geometry"> <property name="geometry">
<rect> <rect>
<x>0</x> <x>0</x>
@ -74,128 +77,26 @@
<number>0</number> <number>0</number>
</property> </property>
<widget class="QWidget" name="generalTab"> <widget class="QWidget" name="generalTab">
<attribute name="title">
<attribute name="title"> <attribute name="title">
<string>General</string> <string>General</string>
</attribute> </attribute>
<layout class="QVBoxLayout" name="generalTabVLayout" stretch="0,0"> <widget class="QWidget" name="generalTabContents">
<item> <property name="geometry">
<layout class="QHBoxLayout" name="generalTabHLayoutTop" stretch="1,1,1"> <rect>
<item> <x>0</x>
<layout class="QVBoxLayout" name="systemTabLayoutLeft"> <y>0</y>
<item> <width>822</width>
<widget class="QGroupBox" name="SystemSettings"> <height>487</height>
<property name="title"> </rect>
<string>System</string>
</property> </property>
<layout class="QVBoxLayout" name="emuSettingsLayout"> <layout class="QVBoxLayout" name="generalTabVLayout" stretch="0">
<item> <item>
<widget class="QGroupBox" name="consoleLanguageGroupBox"> <layout class="QGridLayout" name="gridLayout">
<property name="title"> <property name="bottomMargin">
<string>Console Language</string>
</property>
<layout class="QVBoxLayout" name="settingsLayout">
<item>
<widget class="QComboBox" name="consoleLanguageComboBox"/>
</item>
</layout>
</widget>
</item>
<item>
<widget class="QGroupBox" name="emulatorLanguageGroupBox">
<property name="title">
<string>Emulator Language</string>
</property>
<layout class="QVBoxLayout" name="langSettingsLayout">
<item>
<widget class="QComboBox" name="emulatorLanguageComboBox"/>
</item>
</layout>
</widget>
</item>
</layout>
</widget>
</item>
</layout>
</item>
<item>
<layout class="QVBoxLayout" name="emulatorTabLayoutMiddle">
<item>
<widget class="QGroupBox" name="emulatorSettingsGroupBox">
<property name="title">
<string>Emulator</string>
</property>
<layout class="QVBoxLayout" name="additionalSettingsVLayout">
<item>
<layout class="QVBoxLayout" name="emulatorverticalLayout">
<item>
<widget class="QCheckBox" name="fullscreenCheckBox">
<property name="text">
<string>Enable Fullscreen</string>
</property>
</widget>
</item>
<item>
<widget class="QCheckBox" name="separateUpdatesCheckBox">
<property name="text">
<string>Enable Separate Update Folder</string>
</property>
</widget>
</item>
<item>
<widget class="QCheckBox" name="showSplashCheckBox">
<property name="text">
<string>Show Splash</string>
</property>
</widget>
</item>
<item>
<widget class="QCheckBox" name="ps4proCheckBox">
<property name="text">
<string>Is PS4 Pro</string>
</property>
</widget>
</item>
<item>
<widget class="QCheckBox" name="discordRPCCheckbox">
<property name="text">
<string>Enable Discord Rich Presence</string>
</property>
</widget>
</item>
</layout>
</item>
<item>
<layout class="QVBoxLayout" name="vLayoutUserName">
<property name="spacing">
<number>6</number>
</property>
<property name="leftMargin">
<number>0</number> <number>0</number>
</property> </property>
<item> <item row="0" column="2">
<layout class="QHBoxLayout" name="hLayoutUserName">
<item>
<widget class="QGroupBox" name="userName">
<property name="title">
<string>Username</string>
</property>
<layout class="QVBoxLayout" name="userNameLayout">
<item>
<widget class="QLineEdit" name="userNameLineEdit"/>
</item>
</layout>
</widget>
</item>
</layout>
</item>
</layout>
</item>
</layout>
</widget>
</item>
</layout>
</item>
<item>
<layout class="QVBoxLayout" name="loggerTabLayoutRight"> <layout class="QVBoxLayout" name="loggerTabLayoutRight">
<item> <item>
<widget class="QGroupBox" name="loggerGroupBox"> <widget class="QGroupBox" name="loggerGroupBox">
@ -275,12 +176,129 @@
</item> </item>
</layout> </layout>
</item> </item>
<item row="0" column="0">
<layout class="QVBoxLayout" name="systemTabLayoutLeft">
<item>
<widget class="QGroupBox" name="SystemSettings">
<property name="title">
<string>System</string>
</property>
<layout class="QVBoxLayout" name="emuSettingsLayout">
<item>
<widget class="QGroupBox" name="consoleLanguageGroupBox">
<property name="title">
<string>Console Language</string>
</property>
<layout class="QVBoxLayout" name="settingsLayout">
<item>
<widget class="QComboBox" name="consoleLanguageComboBox"/>
</item>
</layout>
</widget>
</item>
<item>
<widget class="QGroupBox" name="emulatorLanguageGroupBox">
<property name="title">
<string>Emulator Language</string>
</property>
<layout class="QVBoxLayout" name="langSettingsLayout">
<item>
<widget class="QComboBox" name="emulatorLanguageComboBox"/>
</item>
</layout>
</widget>
</item>
</layout>
</widget>
</item>
</layout>
</item>
<item row="0" column="1">
<layout class="QVBoxLayout" name="emulatorTabLayoutMiddle">
<item>
<widget class="QGroupBox" name="emulatorSettingsGroupBox">
<property name="title">
<string>Emulator</string>
</property>
<layout class="QVBoxLayout" name="additionalSettingsVLayout">
<item>
<layout class="QVBoxLayout" name="emulatorverticalLayout">
<property name="spacing">
<number>10</number>
</property>
<item>
<widget class="QCheckBox" name="fullscreenCheckBox">
<property name="text">
<string>Enable Fullscreen</string>
</property>
</widget>
</item>
<item>
<widget class="QCheckBox" name="separateUpdatesCheckBox">
<property name="text">
<string>Enable Separate Update Folder</string>
</property>
</widget>
</item>
<item>
<widget class="QCheckBox" name="showSplashCheckBox">
<property name="text">
<string>Show Splash</string>
</property>
</widget>
</item>
<item>
<widget class="QCheckBox" name="ps4proCheckBox">
<property name="text">
<string>Is PS4 Pro</string>
</property>
</widget>
</item>
<item>
<widget class="QCheckBox" name="discordRPCCheckbox">
<property name="text">
<string>Enable Discord Rich Presence</string>
</property>
</widget>
</item>
</layout> </layout>
</item> </item>
<item> <item>
<layout class="QHBoxLayout" name="generalTabHLayout_2"> <layout class="QVBoxLayout" name="vLayoutUserName">
<property name="spacing">
<number>6</number>
</property>
<property name="leftMargin">
<number>0</number>
</property>
<item> <item>
<layout class="QHBoxLayout" name="hLayoutUserName">
<item>
<widget class="QGroupBox" name="userName">
<property name="title">
<string>Username</string>
</property>
<layout class="QVBoxLayout" name="userNameLayout">
<item>
<widget class="QLineEdit" name="userNameLineEdit"/>
</item>
</layout>
</widget>
</item>
</layout>
</item>
</layout>
</item>
</layout>
</widget>
</item>
</layout>
</item>
<item row="1" column="0">
<layout class="QVBoxLayout" name="updaterTabLayoutLeft"> <layout class="QVBoxLayout" name="updaterTabLayoutLeft">
<property name="spacing">
<number>-1</number>
</property>
<property name="sizeConstraint"> <property name="sizeConstraint">
<enum>QLayout::SizeConstraint::SetDefaultConstraint</enum> <enum>QLayout::SizeConstraint::SetDefaultConstraint</enum>
</property> </property>
@ -296,7 +314,7 @@
<property name="bottomMargin"> <property name="bottomMargin">
<number>0</number> <number>0</number>
</property> </property>
<item alignment="Qt::AlignmentFlag::AlignTop"> <item>
<widget class="QGroupBox" name="updaterGroupBox"> <widget class="QGroupBox" name="updaterGroupBox">
<property name="sizePolicy"> <property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="MinimumExpanding"> <sizepolicy hsizetype="Preferred" vsizetype="MinimumExpanding">
@ -306,7 +324,7 @@
</property> </property>
<property name="minimumSize"> <property name="minimumSize">
<size> <size>
<width>275</width> <width>0</width>
<height>0</height> <height>0</height>
</size> </size>
</property> </property>
@ -321,7 +339,7 @@
</property> </property>
<layout class="QVBoxLayout" name="UpdateLayout" stretch="0,0,0"> <layout class="QVBoxLayout" name="UpdateLayout" stretch="0,0,0">
<property name="spacing"> <property name="spacing">
<number>5</number> <number>10</number>
</property> </property>
<property name="topMargin"> <property name="topMargin">
<number>1</number> <number>1</number>
@ -343,7 +361,7 @@
<property name="minimumSize"> <property name="minimumSize">
<size> <size>
<width>0</width> <width>0</width>
<height>75</height> <height>0</height>
</size> </size>
</property> </property>
<property name="maximumSize"> <property name="maximumSize">
@ -404,8 +422,8 @@
</property> </property>
<property name="minimumSize"> <property name="minimumSize">
<size> <size>
<width>197</width> <width>0</width>
<height>28</height> <height>0</height>
</size> </size>
</property> </property>
<property name="maximumSize"> <property name="maximumSize">
@ -443,7 +461,7 @@
</item> </item>
</layout> </layout>
</item> </item>
<item> <item row="1" column="1">
<layout class="QVBoxLayout" name="GUITabLayoutMiddle" stretch="0"> <layout class="QVBoxLayout" name="GUITabLayoutMiddle" stretch="0">
<item alignment="Qt::AlignmentFlag::AlignTop"> <item alignment="Qt::AlignmentFlag::AlignTop">
<widget class="QGroupBox" name="GUIgroupBox"> <widget class="QGroupBox" name="GUIgroupBox">
@ -559,14 +577,6 @@
</property> </property>
</widget> </widget>
</item> </item>
<item>
<layout class="QVBoxLayout" name="GUIMusicLayout">
<property name="topMargin">
<number>1</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item> <item>
<widget class="QCheckBox" name="playBGMCheckBox"> <widget class="QCheckBox" name="playBGMCheckBox">
<property name="sizePolicy"> <property name="sizePolicy">
@ -581,7 +591,15 @@
</widget> </widget>
</item> </item>
<item> <item>
<spacer name="GUIverticalSpacer_2"> <layout class="QVBoxLayout" name="GUIMusicLayout">
<property name="topMargin">
<number>1</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item>
<spacer name="GUIverticalSpacer_3">
<property name="orientation"> <property name="orientation">
<enum>Qt::Orientation::Vertical</enum> <enum>Qt::Orientation::Vertical</enum>
</property> </property>
@ -591,7 +609,7 @@
<property name="sizeHint" stdset="0"> <property name="sizeHint" stdset="0">
<size> <size>
<width>20</width> <width>20</width>
<height>2</height> <height>13</height>
</size> </size>
</property> </property>
</spacer> </spacer>
@ -656,20 +674,76 @@
</item> </item>
</layout> </layout>
</item> </item>
<item> <item row="1" column="2">
<layout class="QVBoxLayout" name="EmptyTabLayoutRight"> <layout class="QVBoxLayout" name="CompatTabLayoutRight" stretch="0">
<item> <item alignment="Qt::AlignmentFlag::AlignTop">
<spacer name="emptyHorizontalSpacer"> <widget class="QGroupBox" name="CompatgroupBox">
<property name="orientation"> <property name="sizePolicy">
<enum>Qt::Orientation::Horizontal</enum> <sizepolicy hsizetype="Preferred" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property> </property>
<property name="sizeHint" stdset="0"> <property name="minimumSize">
<size> <size>
<width>40</width> <width>0</width>
<height>20</height> <height>0</height>
</size> </size>
</property> </property>
</spacer> <property name="title">
<string>Game Compatibility</string>
</property>
<layout class="QVBoxLayout" name="CompatLayout">
<property name="spacing">
<number>10</number>
</property>
<property name="topMargin">
<number>1</number>
</property>
<property name="bottomMargin">
<number>11</number>
</property>
<item>
<widget class="QCheckBox" name="enableCompatibilityCheckBox">
<property name="text">
<string>Display Compatibility Data</string>
</property>
</widget>
</item>
<item>
<widget class="QCheckBox" name="checkCompatibilityOnStartupCheckBox">
<property name="text">
<string>Update Compatibility Database On Startup</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="updateCompatibilityButton">
<property name="sizePolicy">
<sizepolicy hsizetype="MinimumExpanding" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>0</width>
<height>0</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>16777215</width>
<height>16777215</height>
</size>
</property>
<property name="text">
<string>Update Compatibility Database</string>
</property>
</widget>
</item>
</layout>
</widget>
</item> </item>
</layout> </layout>
</item> </item>
@ -677,10 +751,23 @@
</item> </item>
</layout> </layout>
</widget> </widget>
<widget class="QWidget" name="inputTab"> </widget>
<widget class="QScrollArea" name="inputTab">
<property name="widgetResizable">
<bool>true</bool>
</property>
<attribute name="title"> <attribute name="title">
<string>Input</string> <string>Input</string>
</attribute> </attribute>
<widget class="QWidget" name="inputTabContents">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>396</width>
<height>222</height>
</rect>
</property>
<layout class="QVBoxLayout" name="inputTabVLayout" stretch="0,0"> <layout class="QVBoxLayout" name="inputTabVLayout" stretch="0,0">
<item> <item>
<layout class="QHBoxLayout" name="inputTabHLayoutTop" stretch="1,1,1"> <layout class="QHBoxLayout" name="inputTabHLayoutTop" stretch="1,1,1">
@ -789,8 +876,8 @@
</property> </property>
<property name="minimumSize"> <property name="minimumSize">
<size> <size>
<width>80</width> <width>0</width>
<height>30</height> <height>0</height>
</size> </size>
</property> </property>
<property name="maximumSize"> <property name="maximumSize">
@ -876,7 +963,7 @@
</property> </property>
<property name="minimumSize"> <property name="minimumSize">
<size> <size>
<width>237</width> <width>0</width>
<height>0</height> <height>0</height>
</size> </size>
</property> </property>
@ -955,10 +1042,23 @@
</item> </item>
</layout> </layout>
</widget> </widget>
<widget class="QWidget" name="grphicsTab"> </widget>
<widget class="QScrollArea" name="graphicsTab">
<property name="widgetResizable">
<bool>true</bool>
</property>
<attribute name="title"> <attribute name="title">
<string>Graphics</string> <string>Graphics</string>
</attribute> </attribute>
<widget class="QWidget" name="graphicsTabLayout">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>536</width>
<height>192</height>
</rect>
</property>
<layout class="QVBoxLayout" name="graphicsTabVLayout" stretch="0,0"> <layout class="QVBoxLayout" name="graphicsTabVLayout" stretch="0,0">
<item> <item>
<layout class="QHBoxLayout" name="graphicsTabHLayout" stretch="1,1,1"> <layout class="QHBoxLayout" name="graphicsTabHLayout" stretch="1,1,1">
@ -1193,13 +1293,26 @@
</item> </item>
</layout> </layout>
</widget> </widget>
<widget class="QWidget" name="pathsTab"> </widget>
<widget class="QScrollArea" name="pathsTab">
<property name="widgetResizable">
<bool>true</bool>
</property>
<attribute name="title"> <attribute name="title">
<string>Paths</string> <string>Paths</string>
</attribute> </attribute>
<layout class="QVBoxLayout" name="inputTabVLayout" stretch="0"> <widget class="QWidget" name="pathsTabContents">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>146</width>
<height>215</height>
</rect>
</property>
<layout class="QVBoxLayout" name="pathsTabLayout" stretch="0">
<item> <item>
<layout class="QHBoxLayout" name="horizontalLayout_2"> <layout class="QHBoxLayout" name="pathsTabVLayout">
<item> <item>
<widget class="QGroupBox" name="gameFoldersGroupBox"> <widget class="QGroupBox" name="gameFoldersGroupBox">
<property name="title"> <property name="title">
@ -1242,10 +1355,23 @@
</item> </item>
</layout> </layout>
</widget> </widget>
<widget class="QWidget" name="debugTab"> </widget>
<widget class="QScrollArea" name="debugTab">
<property name="widgetResizable">
<bool>true</bool>
</property>
<attribute name="title"> <attribute name="title">
<string>Debug</string> <string>Debug</string>
</attribute> </attribute>
<widget class="QWidget" name="debugTabContents">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>288</width>
<height>163</height>
</rect>
</property>
<layout class="QVBoxLayout" name="debugTabVLayout" stretch="0,1"> <layout class="QVBoxLayout" name="debugTabVLayout" stretch="0,1">
<item> <item>
<layout class="QHBoxLayout" name="debugTabHLayout" stretch="1"> <layout class="QHBoxLayout" name="debugTabHLayout" stretch="1">

View File

@ -182,8 +182,8 @@
</message> </message>
<message> <message>
<location filename="../gui_context_menus.h" line="196"/> <location filename="../gui_context_menus.h" line="196"/>
<source>Shortcut created successfully!\n %1</source> <source>Shortcut created successfully!</source>
<translation>تم إنشاء الاختصار بنجاح!\n %1</translation> <translation>تم إنشاء الاختصار بنجاح!</translation>
</message> </message>
<message> <message>
<location filename="../gui_context_menus.h" line="199"/> <location filename="../gui_context_menus.h" line="199"/>
@ -192,8 +192,8 @@
</message> </message>
<message> <message>
<location filename="../gui_context_menus.h" line="200"/> <location filename="../gui_context_menus.h" line="200"/>
<source>Error creating shortcut!\n %1</source> <source>Error creating shortcut!</source>
<translation>!\n %1 خطأ في إنشاء الاختصار</translation> <translation>خطأ في إنشاء الاختصار</translation>
</message> </message>
<message> <message>
<location filename="../gui_context_menus.h" line="275"/> <location filename="../gui_context_menus.h" line="275"/>
@ -672,11 +672,36 @@
<source>GUI Settings</source> <source>GUI Settings</source>
<translation>إعدادات الواجهة</translation> <translation>إعدادات الواجهة</translation>
</message> </message>
<message>
<location filename="../settings_dialog.ui" line="475"/>
<source>Disable Trophy Pop-ups</source>
<translation>Disable Trophy Pop-ups</translation>
</message>
<message> <message>
<location filename="../settings_dialog.ui" line="375"/> <location filename="../settings_dialog.ui" line="375"/>
<source>Play title music</source> <source>Play title music</source>
<translation>تشغيل موسيقى العنوان</translation> <translation>تشغيل موسيقى العنوان</translation>
</message> </message>
<message>
<location filename="../settings_dialog.ui"/>
<source>Update Compatibility Database On Startup</source>
<translation>Update Compatibility Database On Startup</translation>
</message>
<message>
<location filename="../settings_dialog.ui"/>
<source>Game Compatibility</source>
<translation>Game Compatibility</translation>
</message>
<message>
<location filename="../settings_dialog.ui"/>
<source>Display Compatibility Data</source>
<translation>Display Compatibility Data</translation>
</message>
<message>
<location filename="../settings_dialog.ui"/>
<source>Update Compatibility Database</source>
<translation>Update Compatibility Database</translation>
</message>
<message> <message>
<location filename="../settings_dialog.ui" line="394"/> <location filename="../settings_dialog.ui" line="394"/>
<source>Volume</source> <source>Volume</source>
@ -1201,6 +1226,11 @@
<source>GUIgroupBox</source> <source>GUIgroupBox</source>
<translation>تشغيل موسيقى العنوان:\nإذا كانت اللعبة تدعم ذلك، قم بتمكين تشغيل موسيقى خاصة عند اختيار اللعبة في واجهة المستخدم.</translation> <translation>تشغيل موسيقى العنوان:\nإذا كانت اللعبة تدعم ذلك، قم بتمكين تشغيل موسيقى خاصة عند اختيار اللعبة في واجهة المستخدم.</translation>
</message> </message>
<message>
<location filename="../settings_dialog.cpp" line="267"/>
<source>disableTrophycheckBox</source>
<translation>Disable Trophy Pop-ups:\nDisable in-game trophy notifications. Trophy progress can still be tracked using the Trophy Viewer (right-click the game in the main window).</translation>
</message>
<message> <message>
<location filename="../settings_dialog.cpp" line="450"/> <location filename="../settings_dialog.cpp" line="450"/>
<source>hideCursorGroupBox</source> <source>hideCursorGroupBox</source>
@ -1216,6 +1246,21 @@
<source>backButtonBehaviorGroupBox</source> <source>backButtonBehaviorGroupBox</source>
<translation>سلوك زر العودة:\nيضبط زر العودة في وحدة التحكم ليحاكي الضغط على الموضع المحدد على لوحة اللمس في PS4.</translation> <translation>سلوك زر العودة:\nيضبط زر العودة في وحدة التحكم ليحاكي الضغط على الموضع المحدد على لوحة اللمس في PS4.</translation>
</message> </message>
<message>
<location filename="../settings_dialog.cpp"/>
<source>enableCompatibilityCheckBox</source>
<translation>Display Compatibility Data:\nDisplays game compatibility information in table view. Enable "Update Compatibility On Startup" to get up-to-date information.</translation>
</message>
<message>
<location filename="../settings_dialog.cpp"/>
<source>checkCompatibilityOnStartupCheckBox</source>
<translation>Update Compatibility On Startup:\nAutomatically update the compatibility database when shadPS4 starts.</translation>
</message>
<message>
<location filename="../settings_dialog.cpp"/>
<source>updateCompatibilityButton</source>
<translation>Update Compatibility Database:\nImmediately update the compatibility database.</translation>
</message>
<message> <message>
<location filename="../settings_dialog.cpp" line="70"/> <location filename="../settings_dialog.cpp" line="70"/>
<source>Never</source> <source>Never</source>
@ -1329,6 +1374,11 @@
<source>Serial</source> <source>Serial</source>
<translation>سيريال</translation> <translation>سيريال</translation>
</message> </message>
<message>
<location filename="../game_list_frame.cpp"/>
<source>Compatibility</source>
<translation>Compatibility</translation>
</message>
<message> <message>
<location filename="../game_list_frame.cpp" line="34"/> <location filename="../game_list_frame.cpp" line="34"/>
<source>Region</source> <source>Region</source>
@ -1364,6 +1414,36 @@
<source>Never Played</source> <source>Never Played</source>
<translation>Never Played</translation> <translation>Never Played</translation>
</message> </message>
<message>
<location filename="../game_list_frame.cpp"/>
<source>Compatibility is untested</source>
<translation>Compatibility is untested</translation>
</message>
<message>
<location filename="../game_list_frame.cpp"/>
<source>Game does not initialize properly / crashes the emulator</source>
<translation>Game does not initialize properly / crashes the emulator</translation>
</message>
<message>
<location filename="../game_list_frame.cpp"/>
<source>Game boots, but only displays a blank screen</source>
<translation>Game boots, but only displays a blank screen</translation>
</message>
<message>
<location filename="../game_list_frame.cpp"/>
<source>Game displays an image but does not go past the menu</source>
<translation>Game displays an image but does not go past the menu</translation>
</message>
<message>
<location filename="../game_list_frame.cpp"/>
<source>Game has game-breaking glitches or unplayable performance</source>
<translation>Game has game-breaking glitches or unplayable performance</translation>
</message>
<message>
<location filename="../game_list_frame.cpp"/>
<source>Game can be completed with playable performance and no major glitches</source>
<translation>Game can be completed with playable performance and no major glitches</translation>
</message>
</context> </context>
<context> <context>
<name>CheckUpdate</name> <name>CheckUpdate</name>

View File

@ -182,8 +182,8 @@
</message> </message>
<message> <message>
<location filename="../gui_context_menus.h" line="196"/> <location filename="../gui_context_menus.h" line="196"/>
<source>Shortcut created successfully!\n %1</source> <source>Shortcut created successfully!</source>
<translation>Shortcut created successfully!\n %1</translation> <translation>Shortcut created successfully!</translation>
</message> </message>
<message> <message>
<location filename="../gui_context_menus.h" line="199"/> <location filename="../gui_context_menus.h" line="199"/>
@ -192,8 +192,8 @@
</message> </message>
<message> <message>
<location filename="../gui_context_menus.h" line="200"/> <location filename="../gui_context_menus.h" line="200"/>
<source>Error creating shortcut!\n %1</source> <source>Error creating shortcut!</source>
<translation>Error creating shortcut!\n %1</translation> <translation>Error creating shortcut!</translation>
</message> </message>
<message> <message>
<location filename="../gui_context_menus.h" line="275"/> <location filename="../gui_context_menus.h" line="275"/>
@ -672,11 +672,36 @@
<source>GUI Settings</source> <source>GUI Settings</source>
<translation>GUI-Indstillinger</translation> <translation>GUI-Indstillinger</translation>
</message> </message>
<message>
<location filename="../settings_dialog.ui" line="475"/>
<source>Disable Trophy Pop-ups</source>
<translation>Disable Trophy Pop-ups</translation>
</message>
<message> <message>
<location filename="../settings_dialog.ui" line="375"/> <location filename="../settings_dialog.ui" line="375"/>
<source>Play title music</source> <source>Play title music</source>
<translation>Afspil titelsang</translation> <translation>Afspil titelsang</translation>
</message> </message>
<message>
<location filename="../settings_dialog.ui"/>
<source>Update Compatibility Database On Startup</source>
<translation>Update Compatibility Database On Startup</translation>
</message>
<message>
<location filename="../settings_dialog.ui"/>
<source>Game Compatibility</source>
<translation>Game Compatibility</translation>
</message>
<message>
<location filename="../settings_dialog.ui"/>
<source>Display Compatibility Data</source>
<translation>Display Compatibility Data</translation>
</message>
<message>
<location filename="../settings_dialog.ui"/>
<source>Update Compatibility Database</source>
<translation>Update Compatibility Database</translation>
</message>
<message> <message>
<location filename="../settings_dialog.ui" line="394"/> <location filename="../settings_dialog.ui" line="394"/>
<source>Volume</source> <source>Volume</source>
@ -1201,6 +1226,11 @@
<source>GUIgroupBox</source> <source>GUIgroupBox</source>
<translation>Titelsmusikafspilning:\nHvis spillet understøtter det, aktiver speciel musik, når spillet vælges i brugergrænsefladen.</translation> <translation>Titelsmusikafspilning:\nHvis spillet understøtter det, aktiver speciel musik, når spillet vælges i brugergrænsefladen.</translation>
</message> </message>
<message>
<location filename="../settings_dialog.cpp" line="267"/>
<source>disableTrophycheckBox</source>
<translation>Disable Trophy Pop-ups:\nDisable in-game trophy notifications. Trophy progress can still be tracked using the Trophy Viewer (right-click the game in the main window).</translation>
</message>
<message> <message>
<location filename="../settings_dialog.cpp" line="450"/> <location filename="../settings_dialog.cpp" line="450"/>
<source>hideCursorGroupBox</source> <source>hideCursorGroupBox</source>
@ -1216,6 +1246,21 @@
<source>backButtonBehaviorGroupBox</source> <source>backButtonBehaviorGroupBox</source>
<translation>Tilbageknap Adfærd:\nIndstiller controllerens tilbageknap til at efterligne tryk den angivne position PS4 berøringsflade.</translation> <translation>Tilbageknap Adfærd:\nIndstiller controllerens tilbageknap til at efterligne tryk den angivne position PS4 berøringsflade.</translation>
</message> </message>
<message>
<location filename="../settings_dialog.cpp"/>
<source>enableCompatibilityCheckBox</source>
<translation>Display Compatibility Data:\nDisplays game compatibility information in table view. Enable "Update Compatibility On Startup" to get up-to-date information.</translation>
</message>
<message>
<location filename="../settings_dialog.cpp"/>
<source>checkCompatibilityOnStartupCheckBox</source>
<translation>Update Compatibility On Startup:\nAutomatically update the compatibility database when shadPS4 starts.</translation>
</message>
<message>
<location filename="../settings_dialog.cpp"/>
<source>updateCompatibilityButton</source>
<translation>Update Compatibility Database:\nImmediately update the compatibility database.</translation>
</message>
<message> <message>
<location filename="../settings_dialog.cpp" line="70"/> <location filename="../settings_dialog.cpp" line="70"/>
<source>Never</source> <source>Never</source>
@ -1329,6 +1374,11 @@
<source>Serial</source> <source>Serial</source>
<translation>Seriel</translation> <translation>Seriel</translation>
</message> </message>
<message>
<location filename="../game_list_frame.cpp"/>
<source>Compatibility</source>
<translation>Compatibility</translation>
</message>
<message> <message>
<location filename="../game_list_frame.cpp" line="34"/> <location filename="../game_list_frame.cpp" line="34"/>
<source>Region</source> <source>Region</source>
@ -1364,6 +1414,36 @@
<source>Never Played</source> <source>Never Played</source>
<translation>Never Played</translation> <translation>Never Played</translation>
</message> </message>
<message>
<location filename="../game_list_frame.cpp"/>
<source>Compatibility is untested</source>
<translation>Compatibility is untested</translation>
</message>
<message>
<location filename="../game_list_frame.cpp"/>
<source>Game does not initialize properly / crashes the emulator</source>
<translation>Game does not initialize properly / crashes the emulator</translation>
</message>
<message>
<location filename="../game_list_frame.cpp"/>
<source>Game boots, but only displays a blank screen</source>
<translation>Game boots, but only displays a blank screen</translation>
</message>
<message>
<location filename="../game_list_frame.cpp"/>
<source>Game displays an image but does not go past the menu</source>
<translation>Game displays an image but does not go past the menu</translation>
</message>
<message>
<location filename="../game_list_frame.cpp"/>
<source>Game has game-breaking glitches or unplayable performance</source>
<translation>Game has game-breaking glitches or unplayable performance</translation>
</message>
<message>
<location filename="../game_list_frame.cpp"/>
<source>Game can be completed with playable performance and no major glitches</source>
<translation>Game can be completed with playable performance and no major glitches</translation>
</message>
</context> </context>
<context> <context>
<name>CheckUpdate</name> <name>CheckUpdate</name>

View File

@ -182,8 +182,8 @@
</message> </message>
<message> <message>
<location filename="../gui_context_menus.h" line="196"/> <location filename="../gui_context_menus.h" line="196"/>
<source>Shortcut created successfully!\n %1</source> <source>Shortcut created successfully!</source>
<translation>Verknüpfung erfolgreich erstellt!\n %1</translation> <translation>Verknüpfung erfolgreich erstellt!</translation>
</message> </message>
<message> <message>
<location filename="../gui_context_menus.h" line="199"/> <location filename="../gui_context_menus.h" line="199"/>
@ -192,8 +192,8 @@
</message> </message>
<message> <message>
<location filename="../gui_context_menus.h" line="200"/> <location filename="../gui_context_menus.h" line="200"/>
<source>Error creating shortcut!\n %1</source> <source>Error creating shortcut!</source>
<translation>Fehler beim Erstellen der Verknüpfung!\n %1</translation> <translation>Fehler beim Erstellen der Verknüpfung!</translation>
</message> </message>
<message> <message>
<location filename="../gui_context_menus.h" line="275"/> <location filename="../gui_context_menus.h" line="275"/>
@ -672,11 +672,36 @@
<source>GUI Settings</source> <source>GUI Settings</source>
<translation>GUI-Einstellungen</translation> <translation>GUI-Einstellungen</translation>
</message> </message>
<message>
<location filename="../settings_dialog.ui" line="475"/>
<source>Disable Trophy Pop-ups</source>
<translation>Disable Trophy Pop-ups</translation>
</message>
<message> <message>
<location filename="../settings_dialog.ui" line="375"/> <location filename="../settings_dialog.ui" line="375"/>
<source>Play title music</source> <source>Play title music</source>
<translation>Titelmusik abspielen</translation> <translation>Titelmusik abspielen</translation>
</message> </message>
<message>
<location filename="../settings_dialog.ui"/>
<source>Update Compatibility Database On Startup</source>
<translation>Update Compatibility Database On Startup</translation>
</message>
<message>
<location filename="../settings_dialog.ui"/>
<source>Game Compatibility</source>
<translation>Game Compatibility</translation>
</message>
<message>
<location filename="../settings_dialog.ui"/>
<source>Display Compatibility Data</source>
<translation>Display Compatibility Data</translation>
</message>
<message>
<location filename="../settings_dialog.ui"/>
<source>Update Compatibility Database</source>
<translation>Update Compatibility Database</translation>
</message>
<message> <message>
<location filename="../settings_dialog.ui" line="394"/> <location filename="../settings_dialog.ui" line="394"/>
<source>Volume</source> <source>Volume</source>
@ -1201,6 +1226,11 @@
<source>GUIgroupBox</source> <source>GUIgroupBox</source>
<translation>Wiedergabe der Titelmusik:\nWenn das Spiel dies unterstützt, wird beim Auswählen des Spiels in der Benutzeroberfläche spezielle Musik abgespielt.</translation> <translation>Wiedergabe der Titelmusik:\nWenn das Spiel dies unterstützt, wird beim Auswählen des Spiels in der Benutzeroberfläche spezielle Musik abgespielt.</translation>
</message> </message>
<message>
<location filename="../settings_dialog.cpp" line="267"/>
<source>disableTrophycheckBox</source>
<translation>Disable Trophy Pop-ups:\nDisable in-game trophy notifications. Trophy progress can still be tracked using the Trophy Viewer (right-click the game in the main window).</translation>
</message>
<message> <message>
<location filename="../settings_dialog.cpp" line="450"/> <location filename="../settings_dialog.cpp" line="450"/>
<source>hideCursorGroupBox</source> <source>hideCursorGroupBox</source>
@ -1216,6 +1246,21 @@
<source>backButtonBehaviorGroupBox</source> <source>backButtonBehaviorGroupBox</source>
<translation>Zurück-Button Verhalten:\nStellt die Zurück-Taste des Controllers so ein, dass sie das Antippen der angegebenen Position auf dem PS4-Touchpad emuliert.</translation> <translation>Zurück-Button Verhalten:\nStellt die Zurück-Taste des Controllers so ein, dass sie das Antippen der angegebenen Position auf dem PS4-Touchpad emuliert.</translation>
</message> </message>
<message>
<location filename="../settings_dialog.cpp"/>
<source>enableCompatibilityCheckBox</source>
<translation>Display Compatibility Data:\nDisplays game compatibility information in table view. Enable "Update Compatibility On Startup" to get up-to-date information.</translation>
</message>
<message>
<location filename="../settings_dialog.cpp"/>
<source>checkCompatibilityOnStartupCheckBox</source>
<translation>Update Compatibility On Startup:\nAutomatically update the compatibility database when shadPS4 starts.</translation>
</message>
<message>
<location filename="../settings_dialog.cpp"/>
<source>updateCompatibilityButton</source>
<translation>Update Compatibility Database:\nImmediately update the compatibility database.</translation>
</message>
<message> <message>
<location filename="../settings_dialog.cpp" line="70"/> <location filename="../settings_dialog.cpp" line="70"/>
<source>Never</source> <source>Never</source>
@ -1329,6 +1374,11 @@
<source>Serial</source> <source>Serial</source>
<translation>Seriennummer</translation> <translation>Seriennummer</translation>
</message> </message>
<message>
<location filename="../game_list_frame.cpp"/>
<source>Compatibility</source>
<translation>Compatibility</translation>
</message>
<message> <message>
<location filename="../game_list_frame.cpp" line="34"/> <location filename="../game_list_frame.cpp" line="34"/>
<source>Region</source> <source>Region</source>
@ -1364,6 +1414,36 @@
<source>Never Played</source> <source>Never Played</source>
<translation>Never Played</translation> <translation>Never Played</translation>
</message> </message>
<message>
<location filename="../game_list_frame.cpp"/>
<source>Compatibility is untested</source>
<translation>Compatibility is untested</translation>
</message>
<message>
<location filename="../game_list_frame.cpp"/>
<source>Game does not initialize properly / crashes the emulator</source>
<translation>Game does not initialize properly / crashes the emulator</translation>
</message>
<message>
<location filename="../game_list_frame.cpp"/>
<source>Game boots, but only displays a blank screen</source>
<translation>Game boots, but only displays a blank screen</translation>
</message>
<message>
<location filename="../game_list_frame.cpp"/>
<source>Game displays an image but does not go past the menu</source>
<translation>Game displays an image but does not go past the menu</translation>
</message>
<message>
<location filename="../game_list_frame.cpp"/>
<source>Game has game-breaking glitches or unplayable performance</source>
<translation>Game has game-breaking glitches or unplayable performance</translation>
</message>
<message>
<location filename="../game_list_frame.cpp"/>
<source>Game can be completed with playable performance and no major glitches</source>
<translation>Game can be completed with playable performance and no major glitches</translation>
</message>
</context> </context>
<context> <context>
<name>CheckUpdate</name> <name>CheckUpdate</name>

View File

@ -182,8 +182,8 @@
</message> </message>
<message> <message>
<location filename="../gui_context_menus.h" line="196"/> <location filename="../gui_context_menus.h" line="196"/>
<source>Shortcut created successfully!\n %1</source> <source>Shortcut created successfully!</source>
<translation>Shortcut created successfully!\n %1</translation> <translation>Shortcut created successfully!</translation>
</message> </message>
<message> <message>
<location filename="../gui_context_menus.h" line="199"/> <location filename="../gui_context_menus.h" line="199"/>
@ -192,8 +192,8 @@
</message> </message>
<message> <message>
<location filename="../gui_context_menus.h" line="200"/> <location filename="../gui_context_menus.h" line="200"/>
<source>Error creating shortcut!\n %1</source> <source>Error creating shortcut!</source>
<translation>Error creating shortcut!\n %1</translation> <translation>Error creating shortcut!</translation>
</message> </message>
<message> <message>
<location filename="../gui_context_menus.h" line="275"/> <location filename="../gui_context_menus.h" line="275"/>
@ -672,11 +672,36 @@
<source>GUI Settings</source> <source>GUI Settings</source>
<translation>Ρυθμίσεις GUI</translation> <translation>Ρυθμίσεις GUI</translation>
</message> </message>
<message>
<location filename="../settings_dialog.ui" line="475"/>
<source>Disable Trophy Pop-ups</source>
<translation>Disable Trophy Pop-ups</translation>
</message>
<message> <message>
<location filename="../settings_dialog.ui" line="375"/> <location filename="../settings_dialog.ui" line="375"/>
<source>Play title music</source> <source>Play title music</source>
<translation>Αναπαραγωγή μουσικής τίτλου</translation> <translation>Αναπαραγωγή μουσικής τίτλου</translation>
</message> </message>
<message>
<location filename="../settings_dialog.ui"/>
<source>Update Compatibility Database On Startup</source>
<translation>Update Compatibility Database On Startup</translation>
</message>
<message>
<location filename="../settings_dialog.ui"/>
<source>Game Compatibility</source>
<translation>Game Compatibility</translation>
</message>
<message>
<location filename="../settings_dialog.ui"/>
<source>Display Compatibility Data</source>
<translation>Display Compatibility Data</translation>
</message>
<message>
<location filename="../settings_dialog.ui"/>
<source>Update Compatibility Database</source>
<translation>Update Compatibility Database</translation>
</message>
<message> <message>
<location filename="../settings_dialog.ui" line="394"/> <location filename="../settings_dialog.ui" line="394"/>
<source>Volume</source> <source>Volume</source>
@ -1201,6 +1226,11 @@
<source>GUIgroupBox</source> <source>GUIgroupBox</source>
<translation>Αναπαραγωγή Μουσικής Τίτλων:\nΕάν το παιχνίδι το υποστηρίζει, ενεργοποιεί ειδική μουσική κατά την επιλογή του παιχνιδιού από τη διεπαφή χρήστη.</translation> <translation>Αναπαραγωγή Μουσικής Τίτλων:\nΕάν το παιχνίδι το υποστηρίζει, ενεργοποιεί ειδική μουσική κατά την επιλογή του παιχνιδιού από τη διεπαφή χρήστη.</translation>
</message> </message>
<message>
<location filename="../settings_dialog.cpp" line="267"/>
<source>disableTrophycheckBox</source>
<translation>Disable Trophy Pop-ups:\nDisable in-game trophy notifications. Trophy progress can still be tracked using the Trophy Viewer (right-click the game in the main window).</translation>
</message>
<message> <message>
<location filename="../settings_dialog.cpp" line="450"/> <location filename="../settings_dialog.cpp" line="450"/>
<source>hideCursorGroupBox</source> <source>hideCursorGroupBox</source>
@ -1216,6 +1246,21 @@
<source>backButtonBehaviorGroupBox</source> <source>backButtonBehaviorGroupBox</source>
<translation>Συμπεριφορά Κουμπιού Επιστροφής:\nΟρίζει το κουμπί επιστροφής του ελεγκτή να προσομοιώνει το πάτημα της καθορισμένης θέσης στην οθόνη αφής PS4.</translation> <translation>Συμπεριφορά Κουμπιού Επιστροφής:\nΟρίζει το κουμπί επιστροφής του ελεγκτή να προσομοιώνει το πάτημα της καθορισμένης θέσης στην οθόνη αφής PS4.</translation>
</message> </message>
<message>
<location filename="../settings_dialog.cpp"/>
<source>enableCompatibilityCheckBox</source>
<translation>Display Compatibility Data:\nDisplays game compatibility information in table view. Enable "Update Compatibility On Startup" to get up-to-date information.</translation>
</message>
<message>
<location filename="../settings_dialog.cpp"/>
<source>checkCompatibilityOnStartupCheckBox</source>
<translation>Update Compatibility On Startup:\nAutomatically update the compatibility database when shadPS4 starts.</translation>
</message>
<message>
<location filename="../settings_dialog.cpp"/>
<source>updateCompatibilityButton</source>
<translation>Update Compatibility Database:\nImmediately update the compatibility database.</translation>
</message>
<message> <message>
<location filename="../settings_dialog.cpp" line="70"/> <location filename="../settings_dialog.cpp" line="70"/>
<source>Never</source> <source>Never</source>
@ -1329,6 +1374,11 @@
<source>Serial</source> <source>Serial</source>
<translation>Σειριακός αριθμός</translation> <translation>Σειριακός αριθμός</translation>
</message> </message>
<message>
<location filename="../game_list_frame.cpp"/>
<source>Compatibility</source>
<translation>Compatibility</translation>
</message>
<message> <message>
<location filename="../game_list_frame.cpp" line="34"/> <location filename="../game_list_frame.cpp" line="34"/>
<source>Region</source> <source>Region</source>
@ -1364,6 +1414,36 @@
<source>Never Played</source> <source>Never Played</source>
<translation>Never Played</translation> <translation>Never Played</translation>
</message> </message>
<message>
<location filename="../game_list_frame.cpp"/>
<source>Compatibility is untested</source>
<translation>Compatibility is untested</translation>
</message>
<message>
<location filename="../game_list_frame.cpp"/>
<source>Game does not initialize properly / crashes the emulator</source>
<translation>Game does not initialize properly / crashes the emulator</translation>
</message>
<message>
<location filename="../game_list_frame.cpp"/>
<source>Game boots, but only displays a blank screen</source>
<translation>Game boots, but only displays a blank screen</translation>
</message>
<message>
<location filename="../game_list_frame.cpp"/>
<source>Game displays an image but does not go past the menu</source>
<translation>Game displays an image but does not go past the menu</translation>
</message>
<message>
<location filename="../game_list_frame.cpp"/>
<source>Game has game-breaking glitches or unplayable performance</source>
<translation>Game has game-breaking glitches or unplayable performance</translation>
</message>
<message>
<location filename="../game_list_frame.cpp"/>
<source>Game can be completed with playable performance and no major glitches</source>
<translation>Game can be completed with playable performance and no major glitches</translation>
</message>
</context> </context>
<context> <context>
<name>CheckUpdate</name> <name>CheckUpdate</name>

View File

@ -182,8 +182,8 @@
</message> </message>
<message> <message>
<location filename="../gui_context_menus.h" line="196"/> <location filename="../gui_context_menus.h" line="196"/>
<source>Shortcut created successfully!\n %1</source> <source>Shortcut created successfully!</source>
<translation>Shortcut created successfully!\n %1</translation> <translation>Shortcut created successfully!</translation>
</message> </message>
<message> <message>
<location filename="../gui_context_menus.h" line="199"/> <location filename="../gui_context_menus.h" line="199"/>
@ -192,8 +192,8 @@
</message> </message>
<message> <message>
<location filename="../gui_context_menus.h" line="200"/> <location filename="../gui_context_menus.h" line="200"/>
<source>Error creating shortcut!\n %1</source> <source>Error creating shortcut!</source>
<translation>Error creating shortcut!\n %1</translation> <translation>Error creating shortcut!</translation>
</message> </message>
<message> <message>
<location filename="../gui_context_menus.h" line="275"/> <location filename="../gui_context_menus.h" line="275"/>
@ -672,11 +672,36 @@
<source>GUI Settings</source> <source>GUI Settings</source>
<translation>GUI Settings</translation> <translation>GUI Settings</translation>
</message> </message>
<message>
<location filename="../settings_dialog.ui" line="475"/>
<source>Disable Trophy Pop-ups</source>
<translation>Disable Trophy Pop-ups</translation>
</message>
<message> <message>
<location filename="../settings_dialog.ui" line="375"/> <location filename="../settings_dialog.ui" line="375"/>
<source>Play title music</source> <source>Play title music</source>
<translation>Play title music</translation> <translation>Play title music</translation>
</message> </message>
<message>
<location filename="../settings_dialog.ui"/>
<source>Update Compatibility Database On Startup</source>
<translation>Update Compatibility Database On Startup</translation>
</message>
<message>
<location filename="../settings_dialog.ui"/>
<source>Game Compatibility</source>
<translation>Game Compatibility</translation>
</message>
<message>
<location filename="../settings_dialog.ui"/>
<source>Display Compatibility Data</source>
<translation>Display Compatibility Data</translation>
</message>
<message>
<location filename="../settings_dialog.ui"/>
<source>Update Compatibility Database</source>
<translation>Update Compatibility Database</translation>
</message>
<message> <message>
<location filename="../settings_dialog.ui" line="394"/> <location filename="../settings_dialog.ui" line="394"/>
<source>Volume</source> <source>Volume</source>
@ -1226,6 +1251,21 @@
<source>backButtonBehaviorGroupBox</source> <source>backButtonBehaviorGroupBox</source>
<translation>Back Button Behavior:\nSets the controller's back button to emulate tapping the specified position on the PS4 touchpad.</translation> <translation>Back Button Behavior:\nSets the controller's back button to emulate tapping the specified position on the PS4 touchpad.</translation>
</message> </message>
<message>
<location filename="../settings_dialog.cpp"/>
<source>enableCompatibilityCheckBox</source>
<translation>Display Compatibility Data:\nDisplays game compatibility information in table view. Enable "Update Compatibility On Startup" to get up-to-date information.</translation>
</message>
<message>
<location filename="../settings_dialog.cpp"/>
<source>checkCompatibilityOnStartupCheckBox</source>
<translation>Update Compatibility On Startup:\nAutomatically update the compatibility database when shadPS4 starts.</translation>
</message>
<message>
<location filename="../settings_dialog.cpp"/>
<source>updateCompatibilityButton</source>
<translation>Update Compatibility Database:\nImmediately update the compatibility database.</translation>
</message>
<message> <message>
<location filename="../settings_dialog.cpp" line="70"/> <location filename="../settings_dialog.cpp" line="70"/>
<source>Never</source> <source>Never</source>
@ -1339,6 +1379,11 @@
<source>Serial</source> <source>Serial</source>
<translation>Serial</translation> <translation>Serial</translation>
</message> </message>
<message>
<location filename="../game_list_frame.cpp"/>
<source>Compatibility</source>
<translation>Compatibility</translation>
</message>
<message> <message>
<location filename="../game_list_frame.cpp" line="34"/> <location filename="../game_list_frame.cpp" line="34"/>
<source>Region</source> <source>Region</source>
@ -1374,6 +1419,36 @@
<source>Never Played</source> <source>Never Played</source>
<translation>Never Played</translation> <translation>Never Played</translation>
</message> </message>
<message>
<location filename="../game_list_frame.cpp"/>
<source>Compatibility is untested</source>
<translation>Compatibility is untested</translation>
</message>
<message>
<location filename="../game_list_frame.cpp"/>
<source>Game does not initialize properly / crashes the emulator</source>
<translation>Game does not initialize properly / crashes the emulator</translation>
</message>
<message>
<location filename="../game_list_frame.cpp"/>
<source>Game boots, but only displays a blank screen</source>
<translation>Game boots, but only displays a blank screen</translation>
</message>
<message>
<location filename="../game_list_frame.cpp"/>
<source>Game displays an image but does not go past the menu</source>
<translation>Game displays an image but does not go past the menu</translation>
</message>
<message>
<location filename="../game_list_frame.cpp"/>
<source>Game has game-breaking glitches or unplayable performance</source>
<translation>Game has game-breaking glitches or unplayable performance</translation>
</message>
<message>
<location filename="../game_list_frame.cpp"/>
<source>Game can be completed with playable performance and no major glitches</source>
<translation>Game can be completed with playable performance and no major glitches</translation>
</message>
</context> </context>
<context> <context>
<name>CheckUpdate</name> <name>CheckUpdate</name>

View File

@ -182,8 +182,8 @@
</message> </message>
<message> <message>
<location filename="../gui_context_menus.h" line="196"/> <location filename="../gui_context_menus.h" line="196"/>
<source>Shortcut created successfully!\n %1</source> <source>Shortcut created successfully!</source>
<translation>¡Acceso directo creado con éxito!\n %1</translation> <translation>¡Acceso directo creado con éxito!</translation>
</message> </message>
<message> <message>
<location filename="../gui_context_menus.h" line="199"/> <location filename="../gui_context_menus.h" line="199"/>
@ -192,8 +192,8 @@
</message> </message>
<message> <message>
<location filename="../gui_context_menus.h" line="200"/> <location filename="../gui_context_menus.h" line="200"/>
<source>Error creating shortcut!\n %1</source> <source>Error creating shortcut!</source>
<translation>¡Error al crear el acceso directo!\n %1</translation> <translation>¡Error al crear el acceso directo!</translation>
</message> </message>
<message> <message>
<location filename="../gui_context_menus.h" line="275"/> <location filename="../gui_context_menus.h" line="275"/>
@ -672,11 +672,36 @@
<source>GUI Settings</source> <source>GUI Settings</source>
<translation>Configuraciones de la Interfaz</translation> <translation>Configuraciones de la Interfaz</translation>
</message> </message>
<message>
<location filename="../settings_dialog.ui" line="475"/>
<source>Disable Trophy Pop-ups</source>
<translation>Disable Trophy Pop-ups</translation>
</message>
<message> <message>
<location filename="../settings_dialog.ui" line="375"/> <location filename="../settings_dialog.ui" line="375"/>
<source>Play title music</source> <source>Play title music</source>
<translation>Reproducir la música de apertura</translation> <translation>Reproducir la música de apertura</translation>
</message> </message>
<message>
<location filename="../settings_dialog.ui"/>
<source>Update Compatibility Database On Startup</source>
<translation>Update Compatibility Database On Startup</translation>
</message>
<message>
<location filename="../settings_dialog.ui"/>
<source>Game Compatibility</source>
<translation>Game Compatibility</translation>
</message>
<message>
<location filename="../settings_dialog.ui"/>
<source>Display Compatibility Data</source>
<translation>Display Compatibility Data</translation>
</message>
<message>
<location filename="../settings_dialog.ui"/>
<source>Update Compatibility Database</source>
<translation>Update Compatibility Database</translation>
</message>
<message> <message>
<location filename="../settings_dialog.ui" line="394"/> <location filename="../settings_dialog.ui" line="394"/>
<source>Volume</source> <source>Volume</source>
@ -1201,6 +1226,11 @@
<source>GUIgroupBox</source> <source>GUIgroupBox</source>
<translation>Reproducir Música del Título:\nSi un juego lo admite, habilita la reproducción de música especial al seleccionar el juego en la interfaz gráfica.</translation> <translation>Reproducir Música del Título:\nSi un juego lo admite, habilita la reproducción de música especial al seleccionar el juego en la interfaz gráfica.</translation>
</message> </message>
<message>
<location filename="../settings_dialog.cpp" line="267"/>
<source>disableTrophycheckBox</source>
<translation>Disable Trophy Pop-ups:\nDisable in-game trophy notifications. Trophy progress can still be tracked using the Trophy Viewer (right-click the game in the main window).</translation>
</message>
<message> <message>
<location filename="../settings_dialog.cpp" line="450"/> <location filename="../settings_dialog.cpp" line="450"/>
<source>hideCursorGroupBox</source> <source>hideCursorGroupBox</source>
@ -1216,6 +1246,21 @@
<source>backButtonBehaviorGroupBox</source> <source>backButtonBehaviorGroupBox</source>
<translation>Comportamiento del Botón Atrás:\nEstablece el botón atrás del controlador para emular el toque en la posición especificada en el touchpad del PS4.</translation> <translation>Comportamiento del Botón Atrás:\nEstablece el botón atrás del controlador para emular el toque en la posición especificada en el touchpad del PS4.</translation>
</message> </message>
<message>
<location filename="../settings_dialog.cpp"/>
<source>enableCompatibilityCheckBox</source>
<translation>Display Compatibility Data:\nDisplays game compatibility information in table view. Enable "Update Compatibility On Startup" to get up-to-date information.</translation>
</message>
<message>
<location filename="../settings_dialog.cpp"/>
<source>checkCompatibilityOnStartupCheckBox</source>
<translation>Update Compatibility On Startup:\nAutomatically update the compatibility database when shadPS4 starts.</translation>
</message>
<message>
<location filename="../settings_dialog.cpp"/>
<source>updateCompatibilityButton</source>
<translation>Update Compatibility Database:\nImmediately update the compatibility database.</translation>
</message>
<message> <message>
<location filename="../settings_dialog.cpp" line="70"/> <location filename="../settings_dialog.cpp" line="70"/>
<source>Never</source> <source>Never</source>
@ -1329,6 +1374,11 @@
<source>Serial</source> <source>Serial</source>
<translation>Numero de serie</translation> <translation>Numero de serie</translation>
</message> </message>
<message>
<location filename="../game_list_frame.cpp"/>
<source>Compatibility</source>
<translation>Compatibility</translation>
</message>
<message> <message>
<location filename="../game_list_frame.cpp" line="34"/> <location filename="../game_list_frame.cpp" line="34"/>
<source>Region</source> <source>Region</source>
@ -1364,6 +1414,36 @@
<source>Never Played</source> <source>Never Played</source>
<translation>Never Played</translation> <translation>Never Played</translation>
</message> </message>
<message>
<location filename="../game_list_frame.cpp"/>
<source>Compatibility is untested</source>
<translation>Compatibility is untested</translation>
</message>
<message>
<location filename="../game_list_frame.cpp"/>
<source>Game does not initialize properly / crashes the emulator</source>
<translation>Game does not initialize properly / crashes the emulator</translation>
</message>
<message>
<location filename="../game_list_frame.cpp"/>
<source>Game boots, but only displays a blank screen</source>
<translation>Game boots, but only displays a blank screen</translation>
</message>
<message>
<location filename="../game_list_frame.cpp"/>
<source>Game displays an image but does not go past the menu</source>
<translation>Game displays an image but does not go past the menu</translation>
</message>
<message>
<location filename="../game_list_frame.cpp"/>
<source>Game has game-breaking glitches or unplayable performance</source>
<translation>Game has game-breaking glitches or unplayable performance</translation>
</message>
<message>
<location filename="../game_list_frame.cpp"/>
<source>Game can be completed with playable performance and no major glitches</source>
<translation>Game can be completed with playable performance and no major glitches</translation>
</message>
</context> </context>
<context> <context>
<name>CheckUpdate</name> <name>CheckUpdate</name>

View File

@ -62,7 +62,7 @@
<message> <message>
<location filename="../install_dir_select.cpp" line="37"/> <location filename="../install_dir_select.cpp" line="37"/>
<source>Select which directory you want to install to.</source> <source>Select which directory you want to install to.</source>
<translation>Select which directory you want to install to.</translation> <translation>محلی را که میخواهید در آن نصب شود، انتخاب کنید.</translation>
</message> </message>
</context> </context>
<context> <context>
@ -98,7 +98,7 @@
<message> <message>
<location filename="../gui_context_menus.h" line="39"/> <location filename="../gui_context_menus.h" line="39"/>
<source>Create Shortcut</source> <source>Create Shortcut</source>
<translation>ساخت شورتکات</translation> <translation>ایجاد میانبر</translation>
</message> </message>
<message> <message>
<location filename="../gui_context_menus.h" line="48"/> <location filename="../gui_context_menus.h" line="48"/>
@ -113,7 +113,7 @@
<message> <message>
<location filename="../gui_context_menus.h" line="42"/> <location filename="../gui_context_menus.h" line="42"/>
<source>Trophy Viewer</source> <source>Trophy Viewer</source>
<translation>مشاهده تروفی ها</translation> <translation>مشاهده جوایز</translation>
</message> </message>
<message> <message>
<location filename="../gui_context_menus.h" line="49"/> <location filename="../gui_context_menus.h" line="49"/>
@ -158,32 +158,32 @@
<message> <message>
<location filename="../gui_context_menus.h" line="72"/> <location filename="../gui_context_menus.h" line="72"/>
<source>Delete...</source> <source>Delete...</source>
<translation>Delete...</translation> <translation>حذف...</translation>
</message> </message>
<message> <message>
<location filename="../gui_context_menus.h" line="73"/> <location filename="../gui_context_menus.h" line="73"/>
<source>Delete Game</source> <source>Delete Game</source>
<translation>Delete Game</translation> <translation>حذف بازی</translation>
</message> </message>
<message> <message>
<location filename="../gui_context_menus.h" line="74"/> <location filename="../gui_context_menus.h" line="74"/>
<source>Delete Update</source> <source>Delete Update</source>
<translation>Delete Update</translation> <translation>حذف بهروزرسانی</translation>
</message> </message>
<message> <message>
<location filename="../gui_context_menus.h" line="75"/> <location filename="../gui_context_menus.h" line="75"/>
<source>Delete DLC</source> <source>Delete DLC</source>
<translation>Delete DLC</translation> <translation>حذف محتوای اضافی (DLC)</translation>
</message> </message>
<message> <message>
<location filename="../gui_context_menus.h" line="173"/> <location filename="../gui_context_menus.h" line="173"/>
<source>Shortcut creation</source> <source>Shortcut creation</source>
<translation>سازنده شورتکات</translation> <translation>ایجاد میانبر</translation>
</message> </message>
<message> <message>
<location filename="../gui_context_menus.h" line="174"/> <location filename="../gui_context_menus.h" line="174"/>
<source>Shortcut created successfully!\n %1</source> <source>Shortcut created successfully!</source>
<translation>شورتکات با موفقیت ساخته شد! \n %1</translation> <translation>میانبر با موفقیت ساخته شد!</translation>
</message> </message>
<message> <message>
<location filename="../gui_context_menus.h" line="177"/> <location filename="../gui_context_menus.h" line="177"/>
@ -192,8 +192,8 @@
</message> </message>
<message> <message>
<location filename="../gui_context_menus.h" line="178"/> <location filename="../gui_context_menus.h" line="178"/>
<source>Error creating shortcut!\n %1</source> <source>Error creating shortcut!</source>
<translation>مشکلی در هنگام ساخت شورتکات بوجود آمد!\n %1</translation> <translation>مشکلی در هنگام ساخت میانبر بوجود آمد!</translation>
</message> </message>
<message> <message>
<location filename="../gui_context_menus.h" line="253"/> <location filename="../gui_context_menus.h" line="253"/>
@ -203,27 +203,27 @@
<message> <message>
<location filename="../gui_context_menus.h" line="299"/> <location filename="../gui_context_menus.h" line="299"/>
<source>Game</source> <source>Game</source>
<translation>Game</translation> <translation>بازی</translation>
</message> </message>
<message> <message>
<location filename="../gui_context_menus.h" line="305"/> <location filename="../gui_context_menus.h" line="305"/>
<source>requiresEnableSeparateUpdateFolder_MSG</source> <source>requiresEnableSeparateUpdateFolder_MSG</source>
<translation>This feature requires the 'Enable Separate Update Folder' config option to work. If you want to use this feature, please enable it.</translation> <translation>این قابلیت نیازمند فعالسازی گزینه تنظیمات «ایجاد پوشه جداگانه برای بهروزرسانی» است. در صورت تمایل به استفاده از این قابلیت، لطفاً آن را فعال کنید.</translation>
</message> </message>
<message> <message>
<location filename="../gui_context_menus.h" line="312"/> <location filename="../gui_context_menus.h" line="312"/>
<source>This game has no update to delete!</source> <source>This game has no update to delete!</source>
<translation>This game has no update to delete!</translation> <translation>این بازی بهروزرسانیای برای حذف ندارد!</translation>
</message> </message>
<message> <message>
<location filename="../gui_context_menus.h" line="316"/> <location filename="../gui_context_menus.h" line="316"/>
<source>Update</source> <source>Update</source>
<translation>Update</translation> <translation>بهروزرسانی</translation>
</message> </message>
<message> <message>
<location filename="../gui_context_menus.h" line="321"/> <location filename="../gui_context_menus.h" line="321"/>
<source>This game has no DLC to delete!</source> <source>This game has no DLC to delete!</source>
<translation>This game has no DLC to delete!</translation> <translation>این بازی محتوای اضافی (DLC) برای حذف ندارد!</translation>
</message> </message>
<message> <message>
<location filename="../gui_context_menus.h" line="325"/> <location filename="../gui_context_menus.h" line="325"/>
@ -233,7 +233,7 @@
<message> <message>
<location filename="../gui_context_menus.h" line="332"/> <location filename="../gui_context_menus.h" line="332"/>
<source>Delete %1</source> <source>Delete %1</source>
<translation>Delete %1</translation> <translation>حذف %1</translation>
</message> </message>
<message> <message>
<location filename="../gui_context_menus.h" line="333"/> <location filename="../gui_context_menus.h" line="333"/>
@ -331,7 +331,7 @@
<message> <message>
<location filename="../main_window_ui.h" line="338"/> <location filename="../main_window_ui.h" line="338"/>
<source>List View</source> <source>List View</source>
<translation>لیستی</translation> <translation>نمایش لیست</translation>
</message> </message>
<message> <message>
<location filename="../main_window_ui.h" line="340"/> <location filename="../main_window_ui.h" line="340"/>
@ -341,7 +341,7 @@
<message> <message>
<location filename="../main_window_ui.h" line="341"/> <location filename="../main_window_ui.h" line="341"/>
<source>Elf Viewer</source> <source>Elf Viewer</source>
<translation>Elf Viewer</translation> <translation>مشاهده گر Elf</translation>
</message> </message>
<message> <message>
<location filename="../main_window_ui.h" line="343"/> <location filename="../main_window_ui.h" line="343"/>
@ -452,7 +452,7 @@
<message> <message>
<location filename="../trophy_viewer.cpp" line="8"/> <location filename="../trophy_viewer.cpp" line="8"/>
<source>Trophy Viewer</source> <source>Trophy Viewer</source>
<translation>تروفی ها</translation> <translation>مشاهده جوایز</translation>
</message> </message>
</context> </context>
<context> <context>
@ -495,7 +495,7 @@
<message> <message>
<location filename="../settings_dialog.ui" line="140"/> <location filename="../settings_dialog.ui" line="140"/>
<source>Enable Separate Update Folder</source> <source>Enable Separate Update Folder</source>
<translation>Enable Separate Update Folder</translation> <translation>فعالسازی پوشه جداگانه برای بهروزرسانی</translation>
</message> </message>
<message> <message>
<location filename="../settings_dialog.ui" line="129"/> <location filename="../settings_dialog.ui" line="129"/>
@ -555,7 +555,7 @@
<message> <message>
<location filename="../settings_dialog.ui" line="767"/> <location filename="../settings_dialog.ui" line="767"/>
<source>Controller</source> <source>Controller</source>
<translation>کنترل کننده</translation> <translation>دسته بازی</translation>
</message> </message>
<message> <message>
<location filename="../settings_dialog.ui" line="797"/> <location filename="../settings_dialog.ui" line="797"/>
@ -585,7 +585,7 @@
<message> <message>
<location filename="../settings_dialog.ui" line="405"/> <location filename="../settings_dialog.ui" line="405"/>
<source>Vblank Divider</source> <source>Vblank Divider</source>
<translation>Vblank Divider</translation> <translation>تقسیمکننده Vblank</translation>
</message> </message>
<message> <message>
<location filename="../settings_dialog.ui" line="453"/> <location filename="../settings_dialog.ui" line="453"/>
@ -595,7 +595,7 @@
<message> <message>
<location filename="../settings_dialog.ui" line="462"/> <location filename="../settings_dialog.ui" line="462"/>
<source>Enable Shaders Dumping</source> <source>Enable Shaders Dumping</source>
<translation>Shaders Dumping فعال کردن</translation> <translation>فعالسازی ذخیرهسازی شیدرها</translation>
</message> </message>
<message> <message>
<location filename="../settings_dialog.ui" line="469"/> <location filename="../settings_dialog.ui" line="469"/>
@ -625,7 +625,7 @@
<message> <message>
<location filename="../settings_dialog.ui" line="517"/> <location filename="../settings_dialog.ui" line="517"/>
<source>Debug</source> <source>Debug</source>
<translation>Debug</translation> <translation>دیباگ</translation>
</message> </message>
<message> <message>
<location filename="../settings_dialog.ui" line="537"/> <location filename="../settings_dialog.ui" line="537"/>
@ -650,33 +650,58 @@
<message> <message>
<location filename="../settings_dialog.ui" line="274"/> <location filename="../settings_dialog.ui" line="274"/>
<source>Update</source> <source>Update</source>
<translation>بروزرسانی</translation> <translation>بهروزرسانی</translation>
</message> </message>
<message> <message>
<location filename="../settings_dialog.ui" line="286"/> <location filename="../settings_dialog.ui" line="286"/>
<source>Check for Updates at Startup</source> <source>Check for Updates at Startup</source>
<translation>بررسی بروزرسانی هنگام شروع</translation> <translation>بررسی بهروزرسانیها در زمان راهاندازی</translation>
</message> </message>
<message> <message>
<location filename="../settings_dialog.ui" line="313"/> <location filename="../settings_dialog.ui" line="313"/>
<source>Update Channel</source> <source>Update Channel</source>
<translation>کانال بروزرسانی</translation> <translation>کانال بهروزرسانی</translation>
</message> </message>
<message> <message>
<location filename="../settings_dialog.ui" line="322"/> <location filename="../settings_dialog.ui" line="322"/>
<source>Check for Updates</source> <source>Check for Updates</source>
<translation>به روز رسانی را بررسی کنید</translation> <translation>بررسی بهروزرسانیها</translation>
</message> </message>
<message> <message>
<location filename="../settings_dialog.ui" line="354"/> <location filename="../settings_dialog.ui" line="354"/>
<source>GUI Settings</source> <source>GUI Settings</source>
<translation>تنظیمات رابط کاربری</translation> <translation>تنظیمات رابط کاربری</translation>
</message> </message>
<message>
<location filename="../settings_dialog.ui" line="475"/>
<source>Disable Trophy Pop-ups</source>
<translation>غیرفعال کردن نمایش جوایز</translation>
</message>
<message> <message>
<location filename="../settings_dialog.ui" line="375"/> <location filename="../settings_dialog.ui" line="375"/>
<source>Play title music</source> <source>Play title music</source>
<translation>پخش موسیقی عنوان</translation> <translation>پخش موسیقی عنوان</translation>
</message> </message>
<message>
<location filename="../settings_dialog.ui"/>
<source>Update Compatibility Database On Startup</source>
<translation>بهروزرسانی پایگاه داده سازگاری هنگام راهاندازی</translation>
</message>
<message>
<location filename="../settings_dialog.ui"/>
<source>Game Compatibility</source>
<translation>سازگاری بازی با سیستم</translation>
</message>
<message>
<location filename="../settings_dialog.ui"/>
<source>Display Compatibility Data</source>
<translation>نمایش دادههای سازگاری</translation>
</message>
<message>
<location filename="../settings_dialog.ui"/>
<source>Update Compatibility Database</source>
<translation>بهروزرسانی پایگاه داده سازگاری</translation>
</message>
<message> <message>
<location filename="../settings_dialog.ui" line="394"/> <location filename="../settings_dialog.ui" line="394"/>
<source>Volume</source> <source>Volume</source>
@ -841,7 +866,7 @@
<message> <message>
<location filename="../cheats_patches.cpp" line="44"/> <location filename="../cheats_patches.cpp" line="44"/>
<source>Cheats / Patches for </source> <source>Cheats / Patches for </source>
<translation>Cheats / Patches for ا</translation> <translation> چیت / پچ برای </translation>
</message> </message>
<message> <message>
<location filename="../cheats_patches.cpp" line="50"/> <location filename="../cheats_patches.cpp" line="50"/>
@ -861,7 +886,7 @@
<message> <message>
<location filename="../cheats_patches.cpp" line="83"/> <location filename="../cheats_patches.cpp" line="83"/>
<source>Version: </source> <source>Version: </source>
<translation>ورژن: </translation> <translation>نسخه: </translation>
</message> </message>
<message> <message>
<location filename="../cheats_patches.cpp" line="87"/> <location filename="../cheats_patches.cpp" line="87"/>
@ -886,7 +911,7 @@
<message> <message>
<location filename="../cheats_patches.cpp" line="155"/> <location filename="../cheats_patches.cpp" line="155"/>
<source>Delete File</source> <source>Delete File</source>
<translation>پاک کردن فایل</translation> <translation>حذف فایل</translation>
</message> </message>
<message> <message>
<location filename="../cheats_patches.cpp" line="169"/> <location filename="../cheats_patches.cpp" line="169"/>
@ -1149,27 +1174,27 @@
<message> <message>
<location filename="../settings_dialog.cpp" line="291"/> <location filename="../settings_dialog.cpp" line="291"/>
<source>emulatorLanguageGroupBox</source> <source>emulatorLanguageGroupBox</source>
<translation>Emulator Language:\nSets the language of the emulator's user interface.</translation> <translation>زبان شبیهساز:\nزبان رابط کاربری شبیهساز را انتخاب میکند.</translation>
</message> </message>
<message> <message>
<location filename="../settings_dialog.cpp" line="293"/> <location filename="../settings_dialog.cpp" line="293"/>
<source>fullscreenCheckBox</source> <source>fullscreenCheckBox</source>
<translation>Enable Full Screen:\nAutomatically puts the game window into full-screen mode.\nThis can be toggled by pressing the F11 key.</translation> <translation>فعالسازی تمام صفحه:\nپنجره بازی را بهطور خودکار به حالت تمام صفحه در میآورد.\nبرای تغییر این حالت میتوانید کلید F11 را فشار دهید.</translation>
</message> </message>
<message> <message>
<location filename="../settings_dialog.cpp" line="293"/> <location filename="../settings_dialog.cpp" line="293"/>
<source>separateUpdatesCheckBox</source> <source>separateUpdatesCheckBox</source>
<translation>Enable Separate Update Folder:\nEnables installing game updates into a separate folder for easy management.</translation> <translation>فعالسازی پوشه جداگانه برای بهروزرسانی:\nامکان نصب بهروزرسانیهای بازی در یک پوشه جداگانه برای مدیریت راحتتر را فراهم میکند.</translation>
</message> </message>
<message> <message>
<location filename="../settings_dialog.cpp" line="295"/> <location filename="../settings_dialog.cpp" line="295"/>
<source>showSplashCheckBox</source> <source>showSplashCheckBox</source>
<translation>Show Splash Screen:\nShows the game's splash screen (a special image) while the game is starting.</translation> <translation>نمایش صفحه شروع:\nصفحه شروع بازی (تصویری ویژه) را هنگام بارگذاری بازی نمایش میدهد.</translation>
</message> </message>
<message> <message>
<location filename="../settings_dialog.cpp" line="297"/> <location filename="../settings_dialog.cpp" line="297"/>
<source>ps4proCheckBox</source> <source>ps4proCheckBox</source>
<translation>Is PS4 Pro:\nMakes the emulator act as a PS4 PRO, which may enable special features in games that support it.</translation> <translation>حالت PS4 Pro:\nشبیهساز را بهعنوان PS4 Pro شبیهسازی میکند که ممکن است ویژگیهای ویژهای را در بازیهای پشتیبانیشده فعال کند.</translation>
</message> </message>
<message> <message>
<location filename="../settings_dialog.cpp" line="438"/> <location filename="../settings_dialog.cpp" line="438"/>
@ -1179,12 +1204,12 @@
<message> <message>
<location filename="../settings_dialog.cpp" line="299"/> <location filename="../settings_dialog.cpp" line="299"/>
<source>userName</source> <source>userName</source>
<translation>Username:\nSets the PS4's account username, which may be displayed by some games.</translation> <translation>نام کاربری:\ام کاربری حساب PS4 را تنظیم میکند که ممکن است توسط برخی بازیها نمایش داده شود.</translation>
</message> </message>
<message> <message>
<location filename="../settings_dialog.cpp" line="301"/> <location filename="../settings_dialog.cpp" line="301"/>
<source>logTypeGroupBox</source> <source>logTypeGroupBox</source>
<translation>Log Type:\nSets whether to synchronize the output of the log window for performance. May have adverse effects on emulation.</translation> <translation>نوع لاگ:\nتنظیم میکند که آیا خروجی پنجره لاگ برای بهبود عملکرد همگامسازی شود یا خیر. این ممکن است تأثیر منفی بر شبیهسازی داشته باشد.</translation>
</message> </message>
<message> <message>
<location filename="../settings_dialog.cpp" line="303"/> <location filename="../settings_dialog.cpp" line="303"/>
@ -1194,12 +1219,17 @@
<message> <message>
<location filename="../settings_dialog.cpp" line="305"/> <location filename="../settings_dialog.cpp" line="305"/>
<source>updaterGroupBox</source> <source>updaterGroupBox</source>
<translation>Update:\nRelease: Official versions released every month that may be very outdated, but are more reliable and tested.\nNightly: Development versions that have all the latest features and fixes, but may contain bugs and are less stable.</translation> <translation>بهروزرسانی:\nانتشار: نسخه‌های رسمی که هر ماه منتشر میشوند و ممکن است بسیار قدیمی باشند، اما پایدارتر و تست شدهتر هستند.\nشبانه: نسخه‌های توسعهای که شامل جدیدترین ویژگیها و اصلاحات هستند، اما ممکن است دارای اشکال باشند و کمتر پایدار باشند.</translation>
</message> </message>
<message> <message>
<location filename="../settings_dialog.cpp" line="306"/> <location filename="../settings_dialog.cpp" line="306"/>
<source>GUIgroupBox</source> <source>GUIgroupBox</source>
<translation>Play Title Music:\nIf a game supports it, enable playing special music when selecting the game in the GUI.</translation> <translation>پخش موسیقی عنوان:\nIدر صورتی که بازی از آن پشتیبانی کند، پخش موسیقی ویژه هنگام انتخاب بازی در رابط کاربری را فعال میکند.</translation>
</message>
<message>
<location filename="../settings_dialog.cpp" line="267"/>
<source>disableTrophycheckBox</source>
<translation>غیرفعال کردن نمایش جوایز:\nنمایش اعلانهای جوایز درون بازی را غیرفعال میکند. پیشرفت جوایز همچنان از طریق نمایشگر جوایز (کلیک راست روی بازی در پنجره اصلی) قابل پیگیری است..</translation>
</message> </message>
<message> <message>
<location filename="../settings_dialog.cpp" line="450"/> <location filename="../settings_dialog.cpp" line="450"/>
@ -1216,6 +1246,21 @@
<source>backButtonBehaviorGroupBox</source> <source>backButtonBehaviorGroupBox</source>
<translation>رفتار دکمه برگشت:\nدکمه برگشت کنترلر را طوری تنظیم می کند که ضربه زدن روی موقعیت مشخص شده روی صفحه لمسی PS4 را شبیه سازی کند.</translation> <translation>رفتار دکمه برگشت:\nدکمه برگشت کنترلر را طوری تنظیم می کند که ضربه زدن روی موقعیت مشخص شده روی صفحه لمسی PS4 را شبیه سازی کند.</translation>
</message> </message>
<message>
<location filename="../settings_dialog.cpp"/>
<source>enableCompatibilityCheckBox</source>
<translation>نمایش دادههای سازگاری:\nاطلاعات سازگاری بازی را به صورت جدول نمایش میدهد. برای دریافت اطلاعات بهروز، گزینه "به‌روزرسانی سازگاری هنگام راه‌اندازی" را فعال کنید.</translation>
</message>
<message>
<location filename="../settings_dialog.cpp"/>
<source>checkCompatibilityOnStartupCheckBox</source>
<translation>بهروزرسانی سازگاری هنگام راهاندازی:\هطور خودکار پایگاه داده سازگاری را هنگام راهاندازی ShadPS4 بهروزرسانی میکند.</translation>
</message>
<message>
<location filename="../settings_dialog.cpp"/>
<source>updateCompatibilityButton</source>
<translation>بهروزرسانی پایگاه داده سازگاری:\ایگاه داده سازگاری را بلافاصله بهروزرسانی میکند.</translation>
</message>
<message> <message>
<location filename="../settings_dialog.cpp" line="70"/> <location filename="../settings_dialog.cpp" line="70"/>
<source>Never</source> <source>Never</source>
@ -1234,7 +1279,7 @@
<message> <message>
<location filename="../settings_dialog.cpp" line="101"/> <location filename="../settings_dialog.cpp" line="101"/>
<source>Touchpad Left</source> <source>Touchpad Left</source>
<translation>پد لمسی سمت چپ</translation> <translation>صفحه لمسی سمت چپ</translation>
</message> </message>
<message> <message>
<location filename="../settings_dialog.cpp" line="102"/> <location filename="../settings_dialog.cpp" line="102"/>
@ -1244,7 +1289,7 @@
<message> <message>
<location filename="../settings_dialog.cpp" line="103"/> <location filename="../settings_dialog.cpp" line="103"/>
<source>Touchpad Center</source> <source>Touchpad Center</source>
<translation>مرکز تاچ پد</translation> <translation>مرکز صفحه لمسی</translation>
</message> </message>
<message> <message>
<location filename="../settings_dialog.cpp" line="104"/> <location filename="../settings_dialog.cpp" line="104"/>
@ -1254,22 +1299,22 @@
<message> <message>
<location filename="../settings_dialog.cpp" line="312"/> <location filename="../settings_dialog.cpp" line="312"/>
<source>graphicsAdapterGroupBox</source> <source>graphicsAdapterGroupBox</source>
<translation>Graphics Device:\nOn multiple GPU systems, select the GPU the emulator will use from the drop down list,\nor select "Auto Select" to automatically determine it.</translation> <translation>دستگاه گرافیکی:\nدر سیستمهای با چندین پردازنده گرافیکی، از فهرست کشویی، پردازنده گرافیکی که شبیهساز از آن استفاده میکند را انتخاب کنید، یا گزینه "انتخاب خودکار" را انتخاب کنید تا به طور خودکار تعیین شود.</translation>
</message> </message>
<message> <message>
<location filename="../settings_dialog.cpp" line="314"/> <location filename="../settings_dialog.cpp" line="314"/>
<source>resolutionLayout</source> <source>resolutionLayout</source>
<translation>Width/Height:\nSets the size of the emulator window at launch, which can be resized during gameplay.\nThis is different from the in-game resolution.</translation> <translation>عرض/ارتفاع:\nاندازه پنجره شبیهساز را در هنگام راهاندازی تنظیم میکند، که در حین بازی قابل تغییر اندازه است.\nاین با وضوح داخل بازی متفاوت است.</translation>
</message> </message>
<message> <message>
<location filename="../settings_dialog.cpp" line="318"/> <location filename="../settings_dialog.cpp" line="318"/>
<source>heightDivider</source> <source>heightDivider</source>
<translation>Vblank Divider:\nThe frame rate at which the emulator refreshes at is multiplied by this number. Changing this may have adverse effects, such as increasing the game speed, or breaking critical game functionality that does not expect this to change!</translation> <translation>تقسیمکننده Vblank:\nمیزان فریم ریت که شبیهساز با آن بهروزرسانی میشود، در این عدد ضرب میشود. تغییر این مقدار ممکن است تأثیرات منفی داشته باشد، مانند افزایش سرعت بازی یا خراب شدن عملکردهای حیاتی بازی که انتظار تغییر آن را ندارند!</translation>
</message> </message>
<message> <message>
<location filename="../settings_dialog.cpp" line="320"/> <location filename="../settings_dialog.cpp" line="320"/>
<source>dumpShadersCheckBox</source> <source>dumpShadersCheckBox</source>
<translation>Enable Shaders Dumping:\nFor the sake of technical debugging, saves the games shaders to a folder as they render.</translation> <translation>فعالسازی ذخیرهسازی شیدرها:\همنظور اشکالزدایی فنی، شیدرهای بازی را هنگام رندر شدن در یک پوشه ذخیره میکند.</translation>
</message> </message>
<message> <message>
<location filename="../settings_dialog.cpp" line="322"/> <location filename="../settings_dialog.cpp" line="322"/>
@ -1294,7 +1339,7 @@
<message> <message>
<location filename="../settings_dialog.cpp" line="329"/> <location filename="../settings_dialog.cpp" line="329"/>
<source>debugDump</source> <source>debugDump</source>
<translation>Enable Debug Dumping:\nSaves the import and export symbols and file header information of the currently running PS4 program to a directory.</translation> <translation>فعالسازی ذخیرهسازی دیباگ:\nنمادهای import و export و اطلاعات هدر فایل برنامه در حال اجرای PS4 را در یک پوشه ذخیره میکند.</translation>
</message> </message>
<message> <message>
<location filename="../settings_dialog.cpp" line="331"/> <location filename="../settings_dialog.cpp" line="331"/>
@ -1329,6 +1374,11 @@
<source>Serial</source> <source>Serial</source>
<translation>سریال</translation> <translation>سریال</translation>
</message> </message>
<message>
<location filename="../game_list_frame.cpp"/>
<source>Compatibility</source>
<translation>سازگاری</translation>
</message>
<message> <message>
<location filename="../game_list_frame.cpp" line="34"/> <location filename="../game_list_frame.cpp" line="34"/>
<source>Region</source> <source>Region</source>
@ -1337,7 +1387,7 @@
<message> <message>
<location filename="../game_list_frame.cpp" line="34"/> <location filename="../game_list_frame.cpp" line="34"/>
<source>Firmware</source> <source>Firmware</source>
<translation>فریمور</translation> <translation>فریمور</translation>
</message> </message>
<message> <message>
<location filename="../game_list_frame.cpp" line="35"/> <location filename="../game_list_frame.cpp" line="35"/>
@ -1362,7 +1412,37 @@
<message> <message>
<location filename="../game_list_frame.cpp" line="108"/> <location filename="../game_list_frame.cpp" line="108"/>
<source>Never Played</source> <source>Never Played</source>
<translation>Never Played</translation> <translation>هرگز بازی نشده</translation>
</message>
<message>
<location filename="../game_list_frame.cpp"/>
<source>Compatibility is untested</source>
<translation>سازگاری تست نشده است</translation>
</message>
<message>
<location filename="../game_list_frame.cpp"/>
<source>Game does not initialize properly / crashes the emulator</source>
<translation>بازی به درستی راهاندازی نمیشود / شبیهساز کرش میکند</translation>
</message>
<message>
<location filename="../game_list_frame.cpp"/>
<source>Game boots, but only displays a blank screen</source>
<translation>بازی اجرا میشود، اما فقط یک صفحه خالی نمایش داده میشود</translation>
</message>
<message>
<location filename="../game_list_frame.cpp"/>
<source>Game displays an image but does not go past the menu</source>
<translation>بازی تصویری نمایش میدهد، اما از منو فراتر نمیرود</translation>
</message>
<message>
<location filename="../game_list_frame.cpp"/>
<source>Game has game-breaking glitches or unplayable performance</source>
<translation>بازی دارای اشکالات بحرانی یا عملکرد غیرقابل بازی است</translation>
</message>
<message>
<location filename="../game_list_frame.cpp"/>
<source>Game can be completed with playable performance and no major glitches</source>
<translation>بازی با عملکرد قابل قبول و بدون اشکالات عمده قابل بازی است.</translation>
</message> </message>
</context> </context>
<context> <context>
@ -1370,7 +1450,7 @@
<message> <message>
<location filename="../check_update.cpp" line="34"/> <location filename="../check_update.cpp" line="34"/>
<source>Auto Updater</source> <source>Auto Updater</source>
<translation>به روز رسانی خودکار</translation> <translation>بهروزرسانی خودکار</translation>
</message> </message>
<message> <message>
<location filename="../check_update.cpp" line="51"/> <location filename="../check_update.cpp" line="51"/>
@ -1415,7 +1495,7 @@
<message> <message>
<location filename="../check_update.cpp" line="187"/> <location filename="../check_update.cpp" line="187"/>
<source>Update Channel</source> <source>Update Channel</source>
<translation>کانال بروزرسانی</translation> <translation>کانال بهروزرسانی</translation>
</message> </message>
<message> <message>
<location filename="../check_update.cpp" line="177"/> <location filename="../check_update.cpp" line="177"/>
@ -1440,7 +1520,7 @@
<message> <message>
<location filename="../check_update.cpp" line="198"/> <location filename="../check_update.cpp" line="198"/>
<source>Check for Updates at Startup</source> <source>Check for Updates at Startup</source>
<translation>بررسی بروزرسانی هنگام شروع</translation> <translation>بررسی بهروزرسانی هنگام شروع</translation>
</message> </message>
<message> <message>
<location filename="../check_update.cpp" line="199"/> <location filename="../check_update.cpp" line="199"/>

View File

@ -182,8 +182,8 @@
</message> </message>
<message> <message>
<location filename="../gui_context_menus.h" line="196"/> <location filename="../gui_context_menus.h" line="196"/>
<source>Shortcut created successfully!\n %1</source> <source>Shortcut created successfully!</source>
<translation>Shortcut created successfully!\n %1</translation> <translation>Shortcut created successfully!</translation>
</message> </message>
<message> <message>
<location filename="../gui_context_menus.h" line="199"/> <location filename="../gui_context_menus.h" line="199"/>
@ -192,8 +192,8 @@
</message> </message>
<message> <message>
<location filename="../gui_context_menus.h" line="200"/> <location filename="../gui_context_menus.h" line="200"/>
<source>Error creating shortcut!\n %1</source> <source>Error creating shortcut!</source>
<translation>Error creating shortcut!\n %1</translation> <translation>Error creating shortcut!</translation>
</message> </message>
<message> <message>
<location filename="../gui_context_menus.h" line="275"/> <location filename="../gui_context_menus.h" line="275"/>
@ -672,11 +672,36 @@
<source>GUI Settings</source> <source>GUI Settings</source>
<translation>GUI-Asetukset</translation> <translation>GUI-Asetukset</translation>
</message> </message>
<message>
<location filename="../settings_dialog.ui" line="475"/>
<source>Disable Trophy Pop-ups</source>
<translation>Disable Trophy Pop-ups</translation>
</message>
<message> <message>
<location filename="../settings_dialog.ui" line="375"/> <location filename="../settings_dialog.ui" line="375"/>
<source>Play title music</source> <source>Play title music</source>
<translation>Soita otsikkomusiikkia</translation> <translation>Soita otsikkomusiikkia</translation>
</message> </message>
<message>
<location filename="../settings_dialog.ui"/>
<source>Update Compatibility Database On Startup</source>
<translation>Update Compatibility Database On Startup</translation>
</message>
<message>
<location filename="../settings_dialog.ui"/>
<source>Game Compatibility</source>
<translation>Game Compatibility</translation>
</message>
<message>
<location filename="../settings_dialog.ui"/>
<source>Display Compatibility Data</source>
<translation>Display Compatibility Data</translation>
</message>
<message>
<location filename="../settings_dialog.ui"/>
<source>Update Compatibility Database</source>
<translation>Update Compatibility Database</translation>
</message>
<message> <message>
<location filename="../settings_dialog.ui" line="394"/> <location filename="../settings_dialog.ui" line="394"/>
<source>Volume</source> <source>Volume</source>
@ -1201,6 +1226,11 @@
<source>GUIgroupBox</source> <source>GUIgroupBox</source>
<translation>Soita Otsikkomusiikkia:\nJos peli tukee sitä, ota käyttöön erityisen musiikin soittaminen pelin valinnan yhteydessä käyttöliittymässä.</translation> <translation>Soita Otsikkomusiikkia:\nJos peli tukee sitä, ota käyttöön erityisen musiikin soittaminen pelin valinnan yhteydessä käyttöliittymässä.</translation>
</message> </message>
<message>
<location filename="../settings_dialog.cpp" line="267"/>
<source>disableTrophycheckBox</source>
<translation>Disable Trophy Pop-ups:\nDisable in-game trophy notifications. Trophy progress can still be tracked using the Trophy Viewer (right-click the game in the main window).</translation>
</message>
<message> <message>
<location filename="../settings_dialog.cpp" line="450"/> <location filename="../settings_dialog.cpp" line="450"/>
<source>hideCursorGroupBox</source> <source>hideCursorGroupBox</source>
@ -1216,6 +1246,21 @@
<source>backButtonBehaviorGroupBox</source> <source>backButtonBehaviorGroupBox</source>
<translation>Takaisin-napin käyttäytyminen:\nAsettaa ohjaimen takaisin-napin jäljittelemään kosketusta PS4:n kosketuslevyn määritettyyn kohtaan.</translation> <translation>Takaisin-napin käyttäytyminen:\nAsettaa ohjaimen takaisin-napin jäljittelemään kosketusta PS4:n kosketuslevyn määritettyyn kohtaan.</translation>
</message> </message>
<message>
<location filename="../settings_dialog.cpp"/>
<source>enableCompatibilityCheckBox</source>
<translation>Display Compatibility Data:\nDisplays game compatibility information in table view. Enable "Update Compatibility On Startup" to get up-to-date information.</translation>
</message>
<message>
<location filename="../settings_dialog.cpp"/>
<source>checkCompatibilityOnStartupCheckBox</source>
<translation>Update Compatibility On Startup:\nAutomatically update the compatibility database when shadPS4 starts.</translation>
</message>
<message>
<location filename="../settings_dialog.cpp"/>
<source>updateCompatibilityButton</source>
<translation>Update Compatibility Database:\nImmediately update the compatibility database.</translation>
</message>
<message> <message>
<location filename="../settings_dialog.cpp" line="70"/> <location filename="../settings_dialog.cpp" line="70"/>
<source>Never</source> <source>Never</source>
@ -1329,6 +1374,11 @@
<source>Serial</source> <source>Serial</source>
<translation>Sarjanumero</translation> <translation>Sarjanumero</translation>
</message> </message>
<message>
<location filename="../game_list_frame.cpp"/>
<source>Compatibility</source>
<translation>Compatibility</translation>
</message>
<message> <message>
<location filename="../game_list_frame.cpp" line="34"/> <location filename="../game_list_frame.cpp" line="34"/>
<source>Region</source> <source>Region</source>
@ -1364,6 +1414,36 @@
<source>Never Played</source> <source>Never Played</source>
<translation>Never Played</translation> <translation>Never Played</translation>
</message> </message>
<message>
<location filename="../game_list_frame.cpp"/>
<source>Compatibility is untested</source>
<translation>Compatibility is untested</translation>
</message>
<message>
<location filename="../game_list_frame.cpp"/>
<source>Game does not initialize properly / crashes the emulator</source>
<translation>Game does not initialize properly / crashes the emulator</translation>
</message>
<message>
<location filename="../game_list_frame.cpp"/>
<source>Game boots, but only displays a blank screen</source>
<translation>Game boots, but only displays a blank screen</translation>
</message>
<message>
<location filename="../game_list_frame.cpp"/>
<source>Game displays an image but does not go past the menu</source>
<translation>Game displays an image but does not go past the menu</translation>
</message>
<message>
<location filename="../game_list_frame.cpp"/>
<source>Game has game-breaking glitches or unplayable performance</source>
<translation>Game has game-breaking glitches or unplayable performance</translation>
</message>
<message>
<location filename="../game_list_frame.cpp"/>
<source>Game can be completed with playable performance and no major glitches</source>
<translation>Game can be completed with playable performance and no major glitches</translation>
</message>
</context> </context>
<context> <context>
<name>CheckUpdate</name> <name>CheckUpdate</name>

View File

@ -182,8 +182,8 @@
</message> </message>
<message> <message>
<location filename="../gui_context_menus.h" line="196"/> <location filename="../gui_context_menus.h" line="196"/>
<source>Shortcut created successfully!\n %1</source> <source>Shortcut created successfully!</source>
<translation>Raccourci créé avec succès !\n %1</translation> <translation>Raccourci créé avec succès !</translation>
</message> </message>
<message> <message>
<location filename="../gui_context_menus.h" line="199"/> <location filename="../gui_context_menus.h" line="199"/>
@ -192,8 +192,8 @@
</message> </message>
<message> <message>
<location filename="../gui_context_menus.h" line="200"/> <location filename="../gui_context_menus.h" line="200"/>
<source>Error creating shortcut!\n %1</source> <source>Error creating shortcut!</source>
<translation>Erreur lors de la création du raccourci !\n %1</translation> <translation>Erreur lors de la création du raccourci !</translation>
</message> </message>
<message> <message>
<location filename="../gui_context_menus.h" line="275"/> <location filename="../gui_context_menus.h" line="275"/>
@ -672,11 +672,36 @@
<source>GUI Settings</source> <source>GUI Settings</source>
<translation>Paramètres de l'interface</translation> <translation>Paramètres de l'interface</translation>
</message> </message>
<message>
<location filename="../settings_dialog.ui" line="475"/>
<source>Disable Trophy Pop-ups</source>
<translation>Disable Trophy Pop-ups</translation>
</message>
<message> <message>
<location filename="../settings_dialog.ui" line="375"/> <location filename="../settings_dialog.ui" line="375"/>
<source>Play title music</source> <source>Play title music</source>
<translation>Lire la musique du titre</translation> <translation>Lire la musique du titre</translation>
</message> </message>
<message>
<location filename="../settings_dialog.ui"/>
<source>Update Compatibility Database On Startup</source>
<translation>Update Compatibility Database On Startup</translation>
</message>
<message>
<location filename="../settings_dialog.ui"/>
<source>Game Compatibility</source>
<translation>Game Compatibility</translation>
</message>
<message>
<location filename="../settings_dialog.ui"/>
<source>Display Compatibility Data</source>
<translation>Display Compatibility Data</translation>
</message>
<message>
<location filename="../settings_dialog.ui"/>
<source>Update Compatibility Database</source>
<translation>Update Compatibility Database</translation>
</message>
<message> <message>
<location filename="../settings_dialog.ui" line="394"/> <location filename="../settings_dialog.ui" line="394"/>
<source>Volume</source> <source>Volume</source>
@ -1201,6 +1226,11 @@
<source>GUIgroupBox</source> <source>GUIgroupBox</source>
<translation>Jouer de la musique de titre:\nSi le jeu le prend en charge, cela active la musique spéciale lorsque vous sélectionnez le jeu dans l'interface utilisateur.</translation> <translation>Jouer de la musique de titre:\nSi le jeu le prend en charge, cela active la musique spéciale lorsque vous sélectionnez le jeu dans l'interface utilisateur.</translation>
</message> </message>
<message>
<location filename="../settings_dialog.cpp" line="267"/>
<source>disableTrophycheckBox</source>
<translation>Disable Trophy Pop-ups:\nDisable in-game trophy notifications. Trophy progress can still be tracked using the Trophy Viewer (right-click the game in the main window).</translation>
</message>
<message> <message>
<location filename="../settings_dialog.cpp" line="450"/> <location filename="../settings_dialog.cpp" line="450"/>
<source>hideCursorGroupBox</source> <source>hideCursorGroupBox</source>
@ -1216,6 +1246,21 @@
<source>backButtonBehaviorGroupBox</source> <source>backButtonBehaviorGroupBox</source>
<translation>Comportement du bouton retour:\nDéfinit le bouton de retour de la manette pour imiter le toucher de la position spécifiée sur le pavé tactile PS4.</translation> <translation>Comportement du bouton retour:\nDéfinit le bouton de retour de la manette pour imiter le toucher de la position spécifiée sur le pavé tactile PS4.</translation>
</message> </message>
<message>
<location filename="../settings_dialog.cpp"/>
<source>enableCompatibilityCheckBox</source>
<translation>Display Compatibility Data:\nDisplays game compatibility information in table view. Enable "Update Compatibility On Startup" to get up-to-date information.</translation>
</message>
<message>
<location filename="../settings_dialog.cpp"/>
<source>checkCompatibilityOnStartupCheckBox</source>
<translation>Update Compatibility On Startup:\nAutomatically update the compatibility database when shadPS4 starts.</translation>
</message>
<message>
<location filename="../settings_dialog.cpp"/>
<source>updateCompatibilityButton</source>
<translation>Update Compatibility Database:\nImmediately update the compatibility database.</translation>
</message>
<message> <message>
<location filename="../settings_dialog.cpp" line="70"/> <location filename="../settings_dialog.cpp" line="70"/>
<source>Never</source> <source>Never</source>
@ -1329,6 +1374,11 @@
<source>Serial</source> <source>Serial</source>
<translation>Série</translation> <translation>Série</translation>
</message> </message>
<message>
<location filename="../game_list_frame.cpp"/>
<source>Compatibility</source>
<translation>Compatibility</translation>
</message>
<message> <message>
<location filename="../game_list_frame.cpp" line="34"/> <location filename="../game_list_frame.cpp" line="34"/>
<source>Region</source> <source>Region</source>
@ -1364,6 +1414,36 @@
<source>Never Played</source> <source>Never Played</source>
<translation>Jamais joué</translation> <translation>Jamais joué</translation>
</message> </message>
<message>
<location filename="../game_list_frame.cpp"/>
<source>Compatibility is untested</source>
<translation>Compatibility is untested</translation>
</message>
<message>
<location filename="../game_list_frame.cpp"/>
<source>Game does not initialize properly / crashes the emulator</source>
<translation>Game does not initialize properly / crashes the emulator</translation>
</message>
<message>
<location filename="../game_list_frame.cpp"/>
<source>Game boots, but only displays a blank screen</source>
<translation>Game boots, but only displays a blank screen</translation>
</message>
<message>
<location filename="../game_list_frame.cpp"/>
<source>Game displays an image but does not go past the menu</source>
<translation>Game displays an image but does not go past the menu</translation>
</message>
<message>
<location filename="../game_list_frame.cpp"/>
<source>Game has game-breaking glitches or unplayable performance</source>
<translation>Game has game-breaking glitches or unplayable performance</translation>
</message>
<message>
<location filename="../game_list_frame.cpp"/>
<source>Game can be completed with playable performance and no major glitches</source>
<translation>Game can be completed with playable performance and no major glitches</translation>
</message>
</context> </context>
<context> <context>
<name>CheckUpdate</name> <name>CheckUpdate</name>

View File

@ -182,8 +182,8 @@
</message> </message>
<message> <message>
<location filename="../gui_context_menus.h" line="174"/> <location filename="../gui_context_menus.h" line="174"/>
<source>Shortcut created successfully!\n %1</source> <source>Shortcut created successfully!</source>
<translation>Parancsikon sikeresen létrehozva!\n %1</translation> <translation>Parancsikon sikeresen létrehozva!</translation>
</message> </message>
<message> <message>
<location filename="../gui_context_menus.h" line="177"/> <location filename="../gui_context_menus.h" line="177"/>
@ -192,8 +192,8 @@
</message> </message>
<message> <message>
<location filename="../gui_context_menus.h" line="178"/> <location filename="../gui_context_menus.h" line="178"/>
<source>Error creating shortcut!\n %1</source> <source>Error creating shortcut!</source>
<translation>Hiba a parancsikon létrehozásával!\n %1</translation> <translation>Hiba a parancsikon létrehozásával!</translation>
</message> </message>
<message> <message>
<location filename="../gui_context_menus.h" line="253"/> <location filename="../gui_context_menus.h" line="253"/>
@ -672,11 +672,36 @@
<source>GUI Settings</source> <source>GUI Settings</source>
<translation>GUI Beállítások</translation> <translation>GUI Beállítások</translation>
</message> </message>
<message>
<location filename="../settings_dialog.ui" line="475"/>
<source>Disable Trophy Pop-ups</source>
<translation>Disable Trophy Pop-ups</translation>
</message>
<message> <message>
<location filename="../settings_dialog.ui" line="375"/> <location filename="../settings_dialog.ui" line="375"/>
<source>Play title music</source> <source>Play title music</source>
<translation>Címzene lejátszása</translation> <translation>Címzene lejátszása</translation>
</message> </message>
<message>
<location filename="../settings_dialog.ui"/>
<source>Update Compatibility Database On Startup</source>
<translation>Update Compatibility Database On Startup</translation>
</message>
<message>
<location filename="../settings_dialog.ui"/>
<source>Game Compatibility</source>
<translation>Game Compatibility</translation>
</message>
<message>
<location filename="../settings_dialog.ui"/>
<source>Display Compatibility Data</source>
<translation>Display Compatibility Data</translation>
</message>
<message>
<location filename="../settings_dialog.ui"/>
<source>Update Compatibility Database</source>
<translation>Update Compatibility Database</translation>
</message>
<message> <message>
<location filename="../settings_dialog.ui" line="394"/> <location filename="../settings_dialog.ui" line="394"/>
<source>Volume</source> <source>Volume</source>
@ -1201,6 +1226,11 @@
<source>GUIgroupBox</source> <source>GUIgroupBox</source>
<translation>Játék címzene lejátszása:\nHa a játék támogatja, engedélyezze egy speciális zene lejátszását, amikor a játékot kiválasztja a GUI-ban.</translation> <translation>Játék címzene lejátszása:\nHa a játék támogatja, engedélyezze egy speciális zene lejátszását, amikor a játékot kiválasztja a GUI-ban.</translation>
</message> </message>
<message>
<location filename="../settings_dialog.cpp" line="267"/>
<source>disableTrophycheckBox</source>
<translation>Disable Trophy Pop-ups:\nDisable in-game trophy notifications. Trophy progress can still be tracked using the Trophy Viewer (right-click the game in the main window).</translation>
</message>
<message> <message>
<location filename="../settings_dialog.cpp" line="450"/> <location filename="../settings_dialog.cpp" line="450"/>
<source>hideCursorGroupBox</source> <source>hideCursorGroupBox</source>
@ -1216,6 +1246,21 @@
<source>backButtonBehaviorGroupBox</source> <source>backButtonBehaviorGroupBox</source>
<translation>Vissza gomb viselkedés:\nBeállítja a vezérlő vissza gombját, hogy utánozza a PS4 érintőpadján megadott pozíció megérintését.</translation> <translation>Vissza gomb viselkedés:\nBeállítja a vezérlő vissza gombját, hogy utánozza a PS4 érintőpadján megadott pozíció megérintését.</translation>
</message> </message>
<message>
<location filename="../settings_dialog.cpp"/>
<source>enableCompatibilityCheckBox</source>
<translation>Display Compatibility Data:\nDisplays game compatibility information in table view. Enable "Update Compatibility On Startup" to get up-to-date information.</translation>
</message>
<message>
<location filename="../settings_dialog.cpp"/>
<source>checkCompatibilityOnStartupCheckBox</source>
<translation>Update Compatibility On Startup:\nAutomatically update the compatibility database when shadPS4 starts.</translation>
</message>
<message>
<location filename="../settings_dialog.cpp"/>
<source>updateCompatibilityButton</source>
<translation>Update Compatibility Database:\nImmediately update the compatibility database.</translation>
</message>
<message> <message>
<location filename="../settings_dialog.cpp" line="70"/> <location filename="../settings_dialog.cpp" line="70"/>
<source>Never</source> <source>Never</source>
@ -1329,6 +1374,11 @@
<source>Serial</source> <source>Serial</source>
<translation>Sorozatszám</translation> <translation>Sorozatszám</translation>
</message> </message>
<message>
<location filename="../game_list_frame.cpp"/>
<source>Compatibility</source>
<translation>Compatibility</translation>
</message>
<message> <message>
<location filename="../game_list_frame.cpp" line="34"/> <location filename="../game_list_frame.cpp" line="34"/>
<source>Region</source> <source>Region</source>
@ -1364,6 +1414,36 @@
<source>Never Played</source> <source>Never Played</source>
<translation>Never Played</translation> <translation>Never Played</translation>
</message> </message>
<message>
<location filename="../game_list_frame.cpp"/>
<source>Compatibility is untested</source>
<translation>Compatibility is untested</translation>
</message>
<message>
<location filename="../game_list_frame.cpp"/>
<source>Game does not initialize properly / crashes the emulator</source>
<translation>Game does not initialize properly / crashes the emulator</translation>
</message>
<message>
<location filename="../game_list_frame.cpp"/>
<source>Game boots, but only displays a blank screen</source>
<translation>Game boots, but only displays a blank screen</translation>
</message>
<message>
<location filename="../game_list_frame.cpp"/>
<source>Game displays an image but does not go past the menu</source>
<translation>Game displays an image but does not go past the menu</translation>
</message>
<message>
<location filename="../game_list_frame.cpp"/>
<source>Game has game-breaking glitches or unplayable performance</source>
<translation>Game has game-breaking glitches or unplayable performance</translation>
</message>
<message>
<location filename="../game_list_frame.cpp"/>
<source>Game can be completed with playable performance and no major glitches</source>
<translation>Game can be completed with playable performance and no major glitches</translation>
</message>
</context> </context>
<context> <context>
<name>CheckUpdate</name> <name>CheckUpdate</name>

View File

@ -182,8 +182,8 @@
</message> </message>
<message> <message>
<location filename="../gui_context_menus.h" line="196"/> <location filename="../gui_context_menus.h" line="196"/>
<source>Shortcut created successfully!\n %1</source> <source>Shortcut created successfully!</source>
<translation>Shortcut created successfully!\n %1</translation> <translation>Shortcut created successfully!</translation>
</message> </message>
<message> <message>
<location filename="../gui_context_menus.h" line="199"/> <location filename="../gui_context_menus.h" line="199"/>
@ -192,8 +192,8 @@
</message> </message>
<message> <message>
<location filename="../gui_context_menus.h" line="200"/> <location filename="../gui_context_menus.h" line="200"/>
<source>Error creating shortcut!\n %1</source> <source>Error creating shortcut!</source>
<translation>Error creating shortcut!\n %1</translation> <translation>Error creating shortcut!</translation>
</message> </message>
<message> <message>
<location filename="../gui_context_menus.h" line="275"/> <location filename="../gui_context_menus.h" line="275"/>
@ -672,11 +672,36 @@
<source>GUI Settings</source> <source>GUI Settings</source>
<translation>Pengaturan GUI</translation> <translation>Pengaturan GUI</translation>
</message> </message>
<message>
<location filename="../settings_dialog.ui" line="475"/>
<source>Disable Trophy Pop-ups</source>
<translation>Disable Trophy Pop-ups</translation>
</message>
<message> <message>
<location filename="../settings_dialog.ui" line="375"/> <location filename="../settings_dialog.ui" line="375"/>
<source>Play title music</source> <source>Play title music</source>
<translation>Putar musik judul</translation> <translation>Putar musik judul</translation>
</message> </message>
<message>
<location filename="../settings_dialog.ui"/>
<source>Update Compatibility Database On Startup</source>
<translation>Update Compatibility Database On Startup</translation>
</message>
<message>
<location filename="../settings_dialog.ui"/>
<source>Game Compatibility</source>
<translation>Game Compatibility</translation>
</message>
<message>
<location filename="../settings_dialog.ui"/>
<source>Display Compatibility Data</source>
<translation>Display Compatibility Data</translation>
</message>
<message>
<location filename="../settings_dialog.ui"/>
<source>Update Compatibility Database</source>
<translation>Update Compatibility Database</translation>
</message>
<message> <message>
<location filename="../settings_dialog.ui" line="394"/> <location filename="../settings_dialog.ui" line="394"/>
<source>Volume</source> <source>Volume</source>
@ -1201,6 +1226,11 @@
<source>GUIgroupBox</source> <source>GUIgroupBox</source>
<translation>Putar Musik Judul Permainan:\nJika permainan mendukungnya, aktifkan pemutaran musik khusus saat memilih permainan di GUI.</translation> <translation>Putar Musik Judul Permainan:\nJika permainan mendukungnya, aktifkan pemutaran musik khusus saat memilih permainan di GUI.</translation>
</message> </message>
<message>
<location filename="../settings_dialog.cpp" line="267"/>
<source>disableTrophycheckBox</source>
<translation>Disable Trophy Pop-ups:\nDisable in-game trophy notifications. Trophy progress can still be tracked using the Trophy Viewer (right-click the game in the main window).</translation>
</message>
<message> <message>
<location filename="../settings_dialog.cpp" line="450"/> <location filename="../settings_dialog.cpp" line="450"/>
<source>hideCursorGroupBox</source> <source>hideCursorGroupBox</source>
@ -1216,6 +1246,21 @@
<source>backButtonBehaviorGroupBox</source> <source>backButtonBehaviorGroupBox</source>
<translation>Perilaku Tombol Kembali:\nMengatur tombol kembali pada pengontrol untuk meniru ketukan di posisi yang ditentukan di touchpad PS4.</translation> <translation>Perilaku Tombol Kembali:\nMengatur tombol kembali pada pengontrol untuk meniru ketukan di posisi yang ditentukan di touchpad PS4.</translation>
</message> </message>
<message>
<location filename="../settings_dialog.cpp"/>
<source>enableCompatibilityCheckBox</source>
<translation>Display Compatibility Data:\nDisplays game compatibility information in table view. Enable "Update Compatibility On Startup" to get up-to-date information.</translation>
</message>
<message>
<location filename="../settings_dialog.cpp"/>
<source>checkCompatibilityOnStartupCheckBox</source>
<translation>Update Compatibility On Startup:\nAutomatically update the compatibility database when shadPS4 starts.</translation>
</message>
<message>
<location filename="../settings_dialog.cpp"/>
<source>updateCompatibilityButton</source>
<translation>Update Compatibility Database:\nImmediately update the compatibility database.</translation>
</message>
<message> <message>
<location filename="../settings_dialog.cpp" line="70"/> <location filename="../settings_dialog.cpp" line="70"/>
<source>Never</source> <source>Never</source>
@ -1329,6 +1374,11 @@
<source>Serial</source> <source>Serial</source>
<translation>Serial</translation> <translation>Serial</translation>
</message> </message>
<message>
<location filename="../game_list_frame.cpp"/>
<source>Compatibility</source>
<translation>Compatibility</translation>
</message>
<message> <message>
<location filename="../game_list_frame.cpp" line="34"/> <location filename="../game_list_frame.cpp" line="34"/>
<source>Region</source> <source>Region</source>
@ -1364,6 +1414,36 @@
<source>Never Played</source> <source>Never Played</source>
<translation>Never Played</translation> <translation>Never Played</translation>
</message> </message>
<message>
<location filename="../game_list_frame.cpp"/>
<source>Compatibility is untested</source>
<translation>Compatibility is untested</translation>
</message>
<message>
<location filename="../game_list_frame.cpp"/>
<source>Game does not initialize properly / crashes the emulator</source>
<translation>Game does not initialize properly / crashes the emulator</translation>
</message>
<message>
<location filename="../game_list_frame.cpp"/>
<source>Game boots, but only displays a blank screen</source>
<translation>Game boots, but only displays a blank screen</translation>
</message>
<message>
<location filename="../game_list_frame.cpp"/>
<source>Game displays an image but does not go past the menu</source>
<translation>Game displays an image but does not go past the menu</translation>
</message>
<message>
<location filename="../game_list_frame.cpp"/>
<source>Game has game-breaking glitches or unplayable performance</source>
<translation>Game has game-breaking glitches or unplayable performance</translation>
</message>
<message>
<location filename="../game_list_frame.cpp"/>
<source>Game can be completed with playable performance and no major glitches</source>
<translation>Game can be completed with playable performance and no major glitches</translation>
</message>
</context> </context>
<context> <context>
<name>CheckUpdate</name> <name>CheckUpdate</name>

View File

@ -182,8 +182,8 @@
</message> </message>
<message> <message>
<location filename="../gui_context_menus.h" line="196"/> <location filename="../gui_context_menus.h" line="196"/>
<source>Shortcut created successfully!\n %1</source> <source>Shortcut created successfully!</source>
<translation>Scorciatoia creata con successo!\n %1</translation> <translation>Scorciatoia creata con successo!</translation>
</message> </message>
<message> <message>
<location filename="../gui_context_menus.h" line="199"/> <location filename="../gui_context_menus.h" line="199"/>
@ -192,8 +192,8 @@
</message> </message>
<message> <message>
<location filename="../gui_context_menus.h" line="200"/> <location filename="../gui_context_menus.h" line="200"/>
<source>Error creating shortcut!\n %1</source> <source>Error creating shortcut!</source>
<translation>Errore nella creazione della scorciatoia!\n %1</translation> <translation>Errore nella creazione della scorciatoia!</translation>
</message> </message>
<message> <message>
<location filename="../gui_context_menus.h" line="275"/> <location filename="../gui_context_menus.h" line="275"/>
@ -208,7 +208,7 @@
<message> <message>
<location filename="../gui_context_menus.h" line="305"/> <location filename="../gui_context_menus.h" line="305"/>
<source>requiresEnableSeparateUpdateFolder_MSG</source> <source>requiresEnableSeparateUpdateFolder_MSG</source>
<translation>This feature requires the 'Enable Separate Update Folder' config option to work. If you want to use this feature, please enable it.</translation> <translation>Questa feature richiede che venga attivata l'opzione "Abilita Cartella Aggiornamenti Separata" per poter funzionare, per favore abilitala.</translation>
</message> </message>
<message> <message>
<location filename="../gui_context_menus.h" line="312"/> <location filename="../gui_context_menus.h" line="312"/>
@ -495,7 +495,7 @@
<message> <message>
<location filename="../settings_dialog.ui" line="140"/> <location filename="../settings_dialog.ui" line="140"/>
<source>Enable Separate Update Folder</source> <source>Enable Separate Update Folder</source>
<translation>Abilità Cartella Aggiornamenti Separata</translation> <translation>Abilita Cartella Aggiornamenti Separata</translation>
</message> </message>
<message> <message>
<location filename="../settings_dialog.ui" line="129"/> <location filename="../settings_dialog.ui" line="129"/>
@ -672,11 +672,36 @@
<source>GUI Settings</source> <source>GUI Settings</source>
<translation>Impostazioni GUI</translation> <translation>Impostazioni GUI</translation>
</message> </message>
<message>
<location filename="../settings_dialog.ui" line="475"/>
<source>Disable Trophy Pop-ups</source>
<translation>Disabilita Notifica Trofei</translation>
</message>
<message> <message>
<location filename="../settings_dialog.ui" line="375"/> <location filename="../settings_dialog.ui" line="375"/>
<source>Play title music</source> <source>Play title music</source>
<translation>Riproduci musica del titolo</translation> <translation>Riproduci musica del titolo</translation>
</message> </message>
<message>
<location filename="../settings_dialog.ui"/>
<source>Update Compatibility Database On Startup</source>
<translation>Aggiorna Database Compatibilità all'Avvio</translation>
</message>
<message>
<location filename="../settings_dialog.ui"/>
<source>Game Compatibility</source>
<translation>Compatibilità Gioco</translation>
</message>
<message>
<location filename="../settings_dialog.ui"/>
<source>Display Compatibility Data</source>
<translation>Mostra Dati Compatibilità</translation>
</message>
<message>
<location filename="../settings_dialog.ui"/>
<source>Update Compatibility Database</source>
<translation>Aggiorna Database Compatibilità</translation>
</message>
<message> <message>
<location filename="../settings_dialog.ui" line="394"/> <location filename="../settings_dialog.ui" line="394"/>
<source>Volume</source> <source>Volume</source>
@ -1201,6 +1226,11 @@
<source>GUIgroupBox</source> <source>GUIgroupBox</source>
<translation>Riproduci Musica del Titolo:\nSe un gioco lo supporta, attiva la riproduzione di musica speciale quando selezioni il gioco nell'interfaccia grafica.</translation> <translation>Riproduci Musica del Titolo:\nSe un gioco lo supporta, attiva la riproduzione di musica speciale quando selezioni il gioco nell'interfaccia grafica.</translation>
</message> </message>
<message>
<location filename="../settings_dialog.cpp" line="267"/>
<source>disableTrophycheckBox</source>
<translation>Disable Trophy Pop-ups:\nDisable in-game trophy notifications. Trophy progress can still be tracked using the Trophy Viewer (right-click the game in the main window).</translation>
</message>
<message> <message>
<location filename="../settings_dialog.cpp" line="450"/> <location filename="../settings_dialog.cpp" line="450"/>
<source>hideCursorGroupBox</source> <source>hideCursorGroupBox</source>
@ -1216,6 +1246,21 @@
<source>backButtonBehaviorGroupBox</source> <source>backButtonBehaviorGroupBox</source>
<translation>Comportamento del pulsante Indietro:\nImposta il pulsante Indietro del controller per emulare il tocco sulla posizione specificata sul touchpad PS4.</translation> <translation>Comportamento del pulsante Indietro:\nImposta il pulsante Indietro del controller per emulare il tocco sulla posizione specificata sul touchpad PS4.</translation>
</message> </message>
<message>
<location filename="../settings_dialog.cpp"/>
<source>enableCompatibilityCheckBox</source>
<translation>Mostra Dati Compatibilità:\nMostra informazioni sulla compatibilità del gioco nella visualizzazione lista. Abilita "Aggiorna Compatiblità all'Avvio" per ottenere informazioni aggiornate.</translation>
</message>
<message>
<location filename="../settings_dialog.cpp"/>
<source>checkCompatibilityOnStartupCheckBox</source>
<translation>Aggiorna Compatibilità all'Avvio:\nAggiorna automaticamente il database della compatibilità quando si avvia shadps4.</translation>
</message>
<message>
<location filename="../settings_dialog.cpp"/>
<source>updateCompatibilityButton</source>
<translation>Aggiorna Database Compatibilità:\nAggiorna immediatamente il database di compatibilità.</translation>
</message>
<message> <message>
<location filename="../settings_dialog.cpp" line="70"/> <location filename="../settings_dialog.cpp" line="70"/>
<source>Never</source> <source>Never</source>
@ -1329,6 +1374,11 @@
<source>Serial</source> <source>Serial</source>
<translation>Seriale</translation> <translation>Seriale</translation>
</message> </message>
<message>
<location filename="../game_list_frame.cpp"/>
<source>Compatibility</source>
<translation>Compatibilità</translation>
</message>
<message> <message>
<location filename="../game_list_frame.cpp" line="34"/> <location filename="../game_list_frame.cpp" line="34"/>
<source>Region</source> <source>Region</source>
@ -1362,7 +1412,37 @@
<message> <message>
<location filename="../game_list_frame.cpp" line="108"/> <location filename="../game_list_frame.cpp" line="108"/>
<source>Never Played</source> <source>Never Played</source>
<translation>Never Played</translation> <translation>Mai Giocato</translation>
</message>
<message>
<location filename="../game_list_frame.cpp"/>
<source>Compatibility is untested</source>
<translation>Nessuna informazione sulla compatibilità</translation>
</message>
<message>
<location filename="../game_list_frame.cpp"/>
<source>Game does not initialize properly / crashes the emulator</source>
<translation>Il gioco non si avvia in modo corretto / forza chiusura dell'emulatore</translation>
</message>
<message>
<location filename="../game_list_frame.cpp"/>
<source>Game boots, but only displays a blank screen</source>
<translation>Il gioco si avvia, ma mostra solo una schermata nera</translation>
</message>
<message>
<location filename="../game_list_frame.cpp"/>
<source>Game displays an image but does not go past the menu</source>
<translation>Il gioco mostra immagini ma non va oltre il menu</translation>
</message>
<message>
<location filename="../game_list_frame.cpp"/>
<source>Game has game-breaking glitches or unplayable performance</source>
<translation>Il gioco ha problemi gravi di emulazione oppure framerate troppo basso</translation>
</message>
<message>
<location filename="../game_list_frame.cpp"/>
<source>Game can be completed with playable performance and no major glitches</source>
<translation>Il gioco può essere completato con buone prestazioni e senza problemi gravi</translation>
</message> </message>
</context> </context>
<context> <context>

View File

@ -182,8 +182,8 @@
</message> </message>
<message> <message>
<location filename="../gui_context_menus.h" line="196"/> <location filename="../gui_context_menus.h" line="196"/>
<source>Shortcut created successfully!\n %1</source> <source>Shortcut created successfully!</source>
<translation>!\n %1</translation> <translation>!</translation>
</message> </message>
<message> <message>
<location filename="../gui_context_menus.h" line="199"/> <location filename="../gui_context_menus.h" line="199"/>
@ -192,8 +192,8 @@
</message> </message>
<message> <message>
<location filename="../gui_context_menus.h" line="200"/> <location filename="../gui_context_menus.h" line="200"/>
<source>Error creating shortcut!\n %1</source> <source>Error creating shortcut!</source>
<translation>!\n %1</translation> <translation>!</translation>
</message> </message>
<message> <message>
<location filename="../gui_context_menus.h" line="275"/> <location filename="../gui_context_menus.h" line="275"/>
@ -672,11 +672,36 @@
<source>GUI Settings</source> <source>GUI Settings</source>
<translation>GUI設定</translation> <translation>GUI設定</translation>
</message> </message>
<message>
<location filename="../settings_dialog.ui" line="475"/>
<source>Disable Trophy Pop-ups</source>
<translation>Disable Trophy Pop-ups</translation>
</message>
<message> <message>
<location filename="../settings_dialog.ui" line="375"/> <location filename="../settings_dialog.ui" line="375"/>
<source>Play title music</source> <source>Play title music</source>
<translation></translation> <translation></translation>
</message> </message>
<message>
<location filename="../settings_dialog.ui"/>
<source>Update Compatibility Database On Startup</source>
<translation>Update Compatibility Database On Startup</translation>
</message>
<message>
<location filename="../settings_dialog.ui"/>
<source>Game Compatibility</source>
<translation>Game Compatibility</translation>
</message>
<message>
<location filename="../settings_dialog.ui"/>
<source>Display Compatibility Data</source>
<translation>Display Compatibility Data</translation>
</message>
<message>
<location filename="../settings_dialog.ui"/>
<source>Update Compatibility Database</source>
<translation>Update Compatibility Database</translation>
</message>
<message> <message>
<location filename="../settings_dialog.ui" line="394"/> <location filename="../settings_dialog.ui" line="394"/>
<source>Volume</source> <source>Volume</source>
@ -1201,6 +1226,11 @@
<source>GUIgroupBox</source> <source>GUIgroupBox</source>
<translation>:\nゲームがそれをサポートしている場合GUIでゲームを選択したときに特別な音楽を再生することを有効にします</translation> <translation>:\nゲームがそれをサポートしている場合GUIでゲームを選択したときに特別な音楽を再生することを有効にします</translation>
</message> </message>
<message>
<location filename="../settings_dialog.cpp" line="267"/>
<source>disableTrophycheckBox</source>
<translation>Disable Trophy Pop-ups:\nDisable in-game trophy notifications. Trophy progress can still be tracked using the Trophy Viewer (right-click the game in the main window).</translation>
</message>
<message> <message>
<location filename="../settings_dialog.cpp" line="450"/> <location filename="../settings_dialog.cpp" line="450"/>
<source>hideCursorGroupBox</source> <source>hideCursorGroupBox</source>
@ -1216,6 +1246,21 @@
<source>backButtonBehaviorGroupBox</source> <source>backButtonBehaviorGroupBox</source>
<translation>:\nコントローラーの戻るボタンをPS4のタッチパッドの指定された位置をタッチするように設定します</translation> <translation>:\nコントローラーの戻るボタンをPS4のタッチパッドの指定された位置をタッチするように設定します</translation>
</message> </message>
<message>
<location filename="../settings_dialog.cpp"/>
<source>enableCompatibilityCheckBox</source>
<translation>Display Compatibility Data:\nDisplays game compatibility information in table view. Enable "Update Compatibility On Startup" to get up-to-date information.</translation>
</message>
<message>
<location filename="../settings_dialog.cpp"/>
<source>checkCompatibilityOnStartupCheckBox</source>
<translation>Update Compatibility On Startup:\nAutomatically update the compatibility database when shadPS4 starts.</translation>
</message>
<message>
<location filename="../settings_dialog.cpp"/>
<source>updateCompatibilityButton</source>
<translation>Update Compatibility Database:\nImmediately update the compatibility database.</translation>
</message>
<message> <message>
<location filename="../settings_dialog.cpp" line="70"/> <location filename="../settings_dialog.cpp" line="70"/>
<source>Never</source> <source>Never</source>
@ -1329,6 +1374,11 @@
<source>Serial</source> <source>Serial</source>
<translation></translation> <translation></translation>
</message> </message>
<message>
<location filename="../game_list_frame.cpp"/>
<source>Compatibility</source>
<translation>Compatibility</translation>
</message>
<message> <message>
<location filename="../game_list_frame.cpp" line="34"/> <location filename="../game_list_frame.cpp" line="34"/>
<source>Region</source> <source>Region</source>
@ -1364,6 +1414,36 @@
<source>Never Played</source> <source>Never Played</source>
<translation>Never Played</translation> <translation>Never Played</translation>
</message> </message>
<message>
<location filename="../game_list_frame.cpp"/>
<source>Compatibility is untested</source>
<translation>Compatibility is untested</translation>
</message>
<message>
<location filename="../game_list_frame.cpp"/>
<source>Game does not initialize properly / crashes the emulator</source>
<translation>Game does not initialize properly / crashes the emulator</translation>
</message>
<message>
<location filename="../game_list_frame.cpp"/>
<source>Game boots, but only displays a blank screen</source>
<translation>Game boots, but only displays a blank screen</translation>
</message>
<message>
<location filename="../game_list_frame.cpp"/>
<source>Game displays an image but does not go past the menu</source>
<translation>Game displays an image but does not go past the menu</translation>
</message>
<message>
<location filename="../game_list_frame.cpp"/>
<source>Game has game-breaking glitches or unplayable performance</source>
<translation>Game has game-breaking glitches or unplayable performance</translation>
</message>
<message>
<location filename="../game_list_frame.cpp"/>
<source>Game can be completed with playable performance and no major glitches</source>
<translation>Game can be completed with playable performance and no major glitches</translation>
</message>
</context> </context>
<context> <context>
<name>CheckUpdate</name> <name>CheckUpdate</name>

View File

@ -182,8 +182,8 @@
</message> </message>
<message> <message>
<location filename="../gui_context_menus.h" line="196"/> <location filename="../gui_context_menus.h" line="196"/>
<source>Shortcut created successfully!\n %1</source> <source>Shortcut created successfully!</source>
<translation>Shortcut created successfully!\n %1</translation> <translation>Shortcut created successfully!</translation>
</message> </message>
<message> <message>
<location filename="../gui_context_menus.h" line="199"/> <location filename="../gui_context_menus.h" line="199"/>
@ -192,8 +192,8 @@
</message> </message>
<message> <message>
<location filename="../gui_context_menus.h" line="200"/> <location filename="../gui_context_menus.h" line="200"/>
<source>Error creating shortcut!\n %1</source> <source>Error creating shortcut!</source>
<translation>Error creating shortcut!\n %1</translation> <translation>Error creating shortcut!</translation>
</message> </message>
<message> <message>
<location filename="../gui_context_menus.h" line="275"/> <location filename="../gui_context_menus.h" line="275"/>
@ -672,11 +672,36 @@
<source>GUI Settings</source> <source>GUI Settings</source>
<translation>GUI Settings</translation> <translation>GUI Settings</translation>
</message> </message>
<message>
<location filename="../settings_dialog.ui" line="475"/>
<source>Disable Trophy Pop-ups</source>
<translation>Disable Trophy Pop-ups</translation>
</message>
<message> <message>
<location filename="../settings_dialog.ui" line="375"/> <location filename="../settings_dialog.ui" line="375"/>
<source>Play title music</source> <source>Play title music</source>
<translation>Play title music</translation> <translation>Play title music</translation>
</message> </message>
<message>
<location filename="../settings_dialog.ui"/>
<source>Update Compatibility Database On Startup</source>
<translation>Update Compatibility Database On Startup</translation>
</message>
<message>
<location filename="../settings_dialog.ui"/>
<source>Game Compatibility</source>
<translation>Game Compatibility</translation>
</message>
<message>
<location filename="../settings_dialog.ui"/>
<source>Display Compatibility Data</source>
<translation>Display Compatibility Data</translation>
</message>
<message>
<location filename="../settings_dialog.ui"/>
<source>Update Compatibility Database</source>
<translation>Update Compatibility Database</translation>
</message>
<message> <message>
<location filename="../settings_dialog.ui" line="394"/> <location filename="../settings_dialog.ui" line="394"/>
<source>Volume</source> <source>Volume</source>
@ -1201,6 +1226,11 @@
<source>GUIgroupBox</source> <source>GUIgroupBox</source>
<translation>Play Title Music:\nIf a game supports it, enable playing special music when selecting the game in the GUI.</translation> <translation>Play Title Music:\nIf a game supports it, enable playing special music when selecting the game in the GUI.</translation>
</message> </message>
<message>
<location filename="../settings_dialog.cpp" line="267"/>
<source>disableTrophycheckBox</source>
<translation>Disable Trophy Pop-ups:\nDisable in-game trophy notifications. Trophy progress can still be tracked using the Trophy Viewer (right-click the game in the main window).</translation>
</message>
<message> <message>
<location filename="../settings_dialog.cpp" line="450"/> <location filename="../settings_dialog.cpp" line="450"/>
<source>hideCursorGroupBox</source> <source>hideCursorGroupBox</source>
@ -1216,6 +1246,21 @@
<source>backButtonBehaviorGroupBox</source> <source>backButtonBehaviorGroupBox</source>
<translation>Back Button Behavior:\nSets the controller's back button to emulate tapping the specified position on the PS4 touchpad.</translation> <translation>Back Button Behavior:\nSets the controller's back button to emulate tapping the specified position on the PS4 touchpad.</translation>
</message> </message>
<message>
<location filename="../settings_dialog.cpp"/>
<source>enableCompatibilityCheckBox</source>
<translation>Display Compatibility Data:\nDisplays game compatibility information in table view. Enable "Update Compatibility On Startup" to get up-to-date information.</translation>
</message>
<message>
<location filename="../settings_dialog.cpp"/>
<source>checkCompatibilityOnStartupCheckBox</source>
<translation>Update Compatibility On Startup:\nAutomatically update the compatibility database when shadPS4 starts.</translation>
</message>
<message>
<location filename="../settings_dialog.cpp"/>
<source>updateCompatibilityButton</source>
<translation>Update Compatibility Database:\nImmediately update the compatibility database.</translation>
</message>
<message> <message>
<location filename="../settings_dialog.cpp" line="70"/> <location filename="../settings_dialog.cpp" line="70"/>
<source>Never</source> <source>Never</source>
@ -1329,6 +1374,11 @@
<source>Serial</source> <source>Serial</source>
<translation>Serial</translation> <translation>Serial</translation>
</message> </message>
<message>
<location filename="../game_list_frame.cpp"/>
<source>Compatibility</source>
<translation>Compatibility</translation>
</message>
<message> <message>
<location filename="../game_list_frame.cpp" line="34"/> <location filename="../game_list_frame.cpp" line="34"/>
<source>Region</source> <source>Region</source>
@ -1364,6 +1414,36 @@
<source>Never Played</source> <source>Never Played</source>
<translation>Never Played</translation> <translation>Never Played</translation>
</message> </message>
<message>
<location filename="../game_list_frame.cpp"/>
<source>Compatibility is untested</source>
<translation>Compatibility is untested</translation>
</message>
<message>
<location filename="../game_list_frame.cpp"/>
<source>Game does not initialize properly / crashes the emulator</source>
<translation>Game does not initialize properly / crashes the emulator</translation>
</message>
<message>
<location filename="../game_list_frame.cpp"/>
<source>Game boots, but only displays a blank screen</source>
<translation>Game boots, but only displays a blank screen</translation>
</message>
<message>
<location filename="../game_list_frame.cpp"/>
<source>Game displays an image but does not go past the menu</source>
<translation>Game displays an image but does not go past the menu</translation>
</message>
<message>
<location filename="../game_list_frame.cpp"/>
<source>Game has game-breaking glitches or unplayable performance</source>
<translation>Game has game-breaking glitches or unplayable performance</translation>
</message>
<message>
<location filename="../game_list_frame.cpp"/>
<source>Game can be completed with playable performance and no major glitches</source>
<translation>Game can be completed with playable performance and no major glitches</translation>
</message>
</context> </context>
<context> <context>
<name>CheckUpdate</name> <name>CheckUpdate</name>

View File

@ -182,8 +182,8 @@
</message> </message>
<message> <message>
<location filename="../gui_context_menus.h" line="196"/> <location filename="../gui_context_menus.h" line="196"/>
<source>Shortcut created successfully!\n %1</source> <source>Shortcut created successfully!</source>
<translation>Shortcut created successfully!\n %1</translation> <translation>Shortcut created successfully!</translation>
</message> </message>
<message> <message>
<location filename="../gui_context_menus.h" line="199"/> <location filename="../gui_context_menus.h" line="199"/>
@ -192,8 +192,8 @@
</message> </message>
<message> <message>
<location filename="../gui_context_menus.h" line="200"/> <location filename="../gui_context_menus.h" line="200"/>
<source>Error creating shortcut!\n %1</source> <source>Error creating shortcut!</source>
<translation>Error creating shortcut!\n %1</translation> <translation>Error creating shortcut!</translation>
</message> </message>
<message> <message>
<location filename="../gui_context_menus.h" line="275"/> <location filename="../gui_context_menus.h" line="275"/>
@ -672,11 +672,36 @@
<source>GUI Settings</source> <source>GUI Settings</source>
<translation>GUI Nustatymai</translation> <translation>GUI Nustatymai</translation>
</message> </message>
<message>
<location filename="../settings_dialog.ui" line="475"/>
<source>Disable Trophy Pop-ups</source>
<translation>Disable Trophy Pop-ups</translation>
</message>
<message> <message>
<location filename="../settings_dialog.ui" line="375"/> <location filename="../settings_dialog.ui" line="375"/>
<source>Play title music</source> <source>Play title music</source>
<translation>Groti antraštės muziką</translation> <translation>Groti antraštės muziką</translation>
</message> </message>
<message>
<location filename="../settings_dialog.ui"/>
<source>Update Compatibility Database On Startup</source>
<translation>Update Compatibility Database On Startup</translation>
</message>
<message>
<location filename="../settings_dialog.ui"/>
<source>Game Compatibility</source>
<translation>Game Compatibility</translation>
</message>
<message>
<location filename="../settings_dialog.ui"/>
<source>Display Compatibility Data</source>
<translation>Display Compatibility Data</translation>
</message>
<message>
<location filename="../settings_dialog.ui"/>
<source>Update Compatibility Database</source>
<translation>Update Compatibility Database</translation>
</message>
<message> <message>
<location filename="../settings_dialog.ui" line="394"/> <location filename="../settings_dialog.ui" line="394"/>
<source>Volume</source> <source>Volume</source>
@ -1201,6 +1226,11 @@
<source>GUIgroupBox</source> <source>GUIgroupBox</source>
<translation>Groti antraščių muziką:\nJei žaidimas tai palaiko, įjungia specialios muzikos grojimą, kai pasirinkite žaidimą GUI.</translation> <translation>Groti antraščių muziką:\nJei žaidimas tai palaiko, įjungia specialios muzikos grojimą, kai pasirinkite žaidimą GUI.</translation>
</message> </message>
<message>
<location filename="../settings_dialog.cpp" line="267"/>
<source>disableTrophycheckBox</source>
<translation>Disable Trophy Pop-ups:\nDisable in-game trophy notifications. Trophy progress can still be tracked using the Trophy Viewer (right-click the game in the main window).</translation>
</message>
<message> <message>
<location filename="../settings_dialog.cpp" line="450"/> <location filename="../settings_dialog.cpp" line="450"/>
<source>hideCursorGroupBox</source> <source>hideCursorGroupBox</source>
@ -1216,6 +1246,21 @@
<source>backButtonBehaviorGroupBox</source> <source>backButtonBehaviorGroupBox</source>
<translation>Atgal mygtuko elgesys:\nNustato valdiklio atgal mygtuką imituoti paspaudimą nurodytoje vietoje PS4 jutiklinėje plokštėje.</translation> <translation>Atgal mygtuko elgesys:\nNustato valdiklio atgal mygtuką imituoti paspaudimą nurodytoje vietoje PS4 jutiklinėje plokštėje.</translation>
</message> </message>
<message>
<location filename="../settings_dialog.cpp"/>
<source>enableCompatibilityCheckBox</source>
<translation>Display Compatibility Data:\nDisplays game compatibility information in table view. Enable "Update Compatibility On Startup" to get up-to-date information.</translation>
</message>
<message>
<location filename="../settings_dialog.cpp"/>
<source>checkCompatibilityOnStartupCheckBox</source>
<translation>Update Compatibility On Startup:\nAutomatically update the compatibility database when shadPS4 starts.</translation>
</message>
<message>
<location filename="../settings_dialog.cpp"/>
<source>updateCompatibilityButton</source>
<translation>Update Compatibility Database:\nImmediately update the compatibility database.</translation>
</message>
<message> <message>
<location filename="../settings_dialog.cpp" line="70"/> <location filename="../settings_dialog.cpp" line="70"/>
<source>Never</source> <source>Never</source>
@ -1329,6 +1374,11 @@
<source>Serial</source> <source>Serial</source>
<translation>Serijinis numeris</translation> <translation>Serijinis numeris</translation>
</message> </message>
<message>
<location filename="../game_list_frame.cpp"/>
<source>Compatibility</source>
<translation>Compatibility</translation>
</message>
<message> <message>
<location filename="../game_list_frame.cpp" line="34"/> <location filename="../game_list_frame.cpp" line="34"/>
<source>Region</source> <source>Region</source>
@ -1364,6 +1414,36 @@
<source>Never Played</source> <source>Never Played</source>
<translation>Never Played</translation> <translation>Never Played</translation>
</message> </message>
<message>
<location filename="../game_list_frame.cpp"/>
<source>Compatibility is untested</source>
<translation>Compatibility is untested</translation>
</message>
<message>
<location filename="../game_list_frame.cpp"/>
<source>Game does not initialize properly / crashes the emulator</source>
<translation>Game does not initialize properly / crashes the emulator</translation>
</message>
<message>
<location filename="../game_list_frame.cpp"/>
<source>Game boots, but only displays a blank screen</source>
<translation>Game boots, but only displays a blank screen</translation>
</message>
<message>
<location filename="../game_list_frame.cpp"/>
<source>Game displays an image but does not go past the menu</source>
<translation>Game displays an image but does not go past the menu</translation>
</message>
<message>
<location filename="../game_list_frame.cpp"/>
<source>Game has game-breaking glitches or unplayable performance</source>
<translation>Game has game-breaking glitches or unplayable performance</translation>
</message>
<message>
<location filename="../game_list_frame.cpp"/>
<source>Game can be completed with playable performance and no major glitches</source>
<translation>Game can be completed with playable performance and no major glitches</translation>
</message>
</context> </context>
<context> <context>
<name>CheckUpdate</name> <name>CheckUpdate</name>

View File

@ -182,8 +182,8 @@
</message> </message>
<message> <message>
<location filename="../gui_context_menus.h" line="196"/> <location filename="../gui_context_menus.h" line="196"/>
<source>Shortcut created successfully!\n %1</source> <source>Shortcut created successfully!</source>
<translation>Snarvei opprettet!\n %1</translation> <translation>Snarvei opprettet!</translation>
</message> </message>
<message> <message>
<location filename="../gui_context_menus.h" line="199"/> <location filename="../gui_context_menus.h" line="199"/>
@ -192,8 +192,8 @@
</message> </message>
<message> <message>
<location filename="../gui_context_menus.h" line="200"/> <location filename="../gui_context_menus.h" line="200"/>
<source>Error creating shortcut!\n %1</source> <source>Error creating shortcut!</source>
<translation>Feil ved opprettelse av snarvei!\n %1</translation> <translation>Feil ved opprettelse av snarvei!</translation>
</message> </message>
<message> <message>
<location filename="../gui_context_menus.h" line="275"/> <location filename="../gui_context_menus.h" line="275"/>
@ -672,11 +672,36 @@
<source>GUI Settings</source> <source>GUI Settings</source>
<translation>GUI-Innstillinger</translation> <translation>GUI-Innstillinger</translation>
</message> </message>
<message>
<location filename="../settings_dialog.ui" line="475"/>
<source>Disable Trophy Pop-ups</source>
<translation>Disable Trophy Pop-ups</translation>
</message>
<message> <message>
<location filename="../settings_dialog.ui" line="375"/> <location filename="../settings_dialog.ui" line="375"/>
<source>Play title music</source> <source>Play title music</source>
<translation>Spill tittelmusikk</translation> <translation>Spill tittelmusikk</translation>
</message> </message>
<message>
<location filename="../settings_dialog.ui"/>
<source>Update Compatibility Database On Startup</source>
<translation>Update Compatibility Database On Startup</translation>
</message>
<message>
<location filename="../settings_dialog.ui"/>
<source>Game Compatibility</source>
<translation>Game Compatibility</translation>
</message>
<message>
<location filename="../settings_dialog.ui"/>
<source>Display Compatibility Data</source>
<translation>Display Compatibility Data</translation>
</message>
<message>
<location filename="../settings_dialog.ui"/>
<source>Update Compatibility Database</source>
<translation>Update Compatibility Database</translation>
</message>
<message> <message>
<location filename="../settings_dialog.ui" line="394"/> <location filename="../settings_dialog.ui" line="394"/>
<source>Volume</source> <source>Volume</source>
@ -1201,6 +1226,11 @@
<source>GUIgroupBox</source> <source>GUIgroupBox</source>
<translation>Spille tittelmusikk:\nHvis et spill støtter det, aktiveres det spesiell musikk når du velger spillet i menyen.</translation> <translation>Spille tittelmusikk:\nHvis et spill støtter det, aktiveres det spesiell musikk når du velger spillet i menyen.</translation>
</message> </message>
<message>
<location filename="../settings_dialog.cpp" line="267"/>
<source>disableTrophycheckBox</source>
<translation>Disable Trophy Pop-ups:\nDisable in-game trophy notifications. Trophy progress can still be tracked using the Trophy Viewer (right-click the game in the main window).</translation>
</message>
<message> <message>
<location filename="../settings_dialog.cpp" line="450"/> <location filename="../settings_dialog.cpp" line="450"/>
<source>hideCursorGroupBox</source> <source>hideCursorGroupBox</source>
@ -1216,6 +1246,21 @@
<source>backButtonBehaviorGroupBox</source> <source>backButtonBehaviorGroupBox</source>
<translation>Atferd for tilbaketasten:\nSetter tilbaketasten kontrolleren til å imitere et trykk den angitte posisjonen PS4s berøringsplate.</translation> <translation>Atferd for tilbaketasten:\nSetter tilbaketasten kontrolleren til å imitere et trykk den angitte posisjonen PS4s berøringsplate.</translation>
</message> </message>
<message>
<location filename="../settings_dialog.cpp"/>
<source>enableCompatibilityCheckBox</source>
<translation>Display Compatibility Data:\nDisplays game compatibility information in table view. Enable "Update Compatibility On Startup" to get up-to-date information.</translation>
</message>
<message>
<location filename="../settings_dialog.cpp"/>
<source>checkCompatibilityOnStartupCheckBox</source>
<translation>Update Compatibility On Startup:\nAutomatically update the compatibility database when shadPS4 starts.</translation>
</message>
<message>
<location filename="../settings_dialog.cpp"/>
<source>updateCompatibilityButton</source>
<translation>Update Compatibility Database:\nImmediately update the compatibility database.</translation>
</message>
<message> <message>
<location filename="../settings_dialog.cpp" line="70"/> <location filename="../settings_dialog.cpp" line="70"/>
<source>Never</source> <source>Never</source>
@ -1329,6 +1374,11 @@
<source>Serial</source> <source>Serial</source>
<translation>Serienummer</translation> <translation>Serienummer</translation>
</message> </message>
<message>
<location filename="../game_list_frame.cpp"/>
<source>Compatibility</source>
<translation>Compatibility</translation>
</message>
<message> <message>
<location filename="../game_list_frame.cpp" line="34"/> <location filename="../game_list_frame.cpp" line="34"/>
<source>Region</source> <source>Region</source>
@ -1364,6 +1414,36 @@
<source>Never Played</source> <source>Never Played</source>
<translation>Never Played</translation> <translation>Never Played</translation>
</message> </message>
<message>
<location filename="../game_list_frame.cpp"/>
<source>Compatibility is untested</source>
<translation>Compatibility is untested</translation>
</message>
<message>
<location filename="../game_list_frame.cpp"/>
<source>Game does not initialize properly / crashes the emulator</source>
<translation>Game does not initialize properly / crashes the emulator</translation>
</message>
<message>
<location filename="../game_list_frame.cpp"/>
<source>Game boots, but only displays a blank screen</source>
<translation>Game boots, but only displays a blank screen</translation>
</message>
<message>
<location filename="../game_list_frame.cpp"/>
<source>Game displays an image but does not go past the menu</source>
<translation>Game displays an image but does not go past the menu</translation>
</message>
<message>
<location filename="../game_list_frame.cpp"/>
<source>Game has game-breaking glitches or unplayable performance</source>
<translation>Game has game-breaking glitches or unplayable performance</translation>
</message>
<message>
<location filename="../game_list_frame.cpp"/>
<source>Game can be completed with playable performance and no major glitches</source>
<translation>Game can be completed with playable performance and no major glitches</translation>
</message>
</context> </context>
<context> <context>
<name>CheckUpdate</name> <name>CheckUpdate</name>

View File

@ -182,8 +182,8 @@
</message> </message>
<message> <message>
<location filename="../gui_context_menus.h" line="196"/> <location filename="../gui_context_menus.h" line="196"/>
<source>Shortcut created successfully!\n %1</source> <source>Shortcut created successfully!</source>
<translation>Shortcut created successfully!\n %1</translation> <translation>Shortcut created successfully!</translation>
</message> </message>
<message> <message>
<location filename="../gui_context_menus.h" line="199"/> <location filename="../gui_context_menus.h" line="199"/>
@ -192,8 +192,8 @@
</message> </message>
<message> <message>
<location filename="../gui_context_menus.h" line="200"/> <location filename="../gui_context_menus.h" line="200"/>
<source>Error creating shortcut!\n %1</source> <source>Error creating shortcut!</source>
<translation>Error creating shortcut!\n %1</translation> <translation>Error creating shortcut!</translation>
</message> </message>
<message> <message>
<location filename="../gui_context_menus.h" line="275"/> <location filename="../gui_context_menus.h" line="275"/>
@ -672,11 +672,36 @@
<source>GUI Settings</source> <source>GUI Settings</source>
<translation>GUI-Instellingen</translation> <translation>GUI-Instellingen</translation>
</message> </message>
<message>
<location filename="../settings_dialog.ui" line="475"/>
<source>Disable Trophy Pop-ups</source>
<translation>Disable Trophy Pop-ups</translation>
</message>
<message> <message>
<location filename="../settings_dialog.ui" line="375"/> <location filename="../settings_dialog.ui" line="375"/>
<source>Play title music</source> <source>Play title music</source>
<translation>Titelmuziek afspelen</translation> <translation>Titelmuziek afspelen</translation>
</message> </message>
<message>
<location filename="../settings_dialog.ui"/>
<source>Update Compatibility Database On Startup</source>
<translation>Update Compatibility Database On Startup</translation>
</message>
<message>
<location filename="../settings_dialog.ui"/>
<source>Game Compatibility</source>
<translation>Game Compatibility</translation>
</message>
<message>
<location filename="../settings_dialog.ui"/>
<source>Display Compatibility Data</source>
<translation>Display Compatibility Data</translation>
</message>
<message>
<location filename="../settings_dialog.ui"/>
<source>Update Compatibility Database</source>
<translation>Update Compatibility Database</translation>
</message>
<message> <message>
<location filename="../settings_dialog.ui" line="394"/> <location filename="../settings_dialog.ui" line="394"/>
<source>Volume</source> <source>Volume</source>
@ -1201,6 +1226,11 @@
<source>GUIgroupBox</source> <source>GUIgroupBox</source>
<translation>Speel titelsong:\nAls een game dit ondersteunt, wordt speciale muziek afgespeeld wanneer je het spel in de GUI selecteert.</translation> <translation>Speel titelsong:\nAls een game dit ondersteunt, wordt speciale muziek afgespeeld wanneer je het spel in de GUI selecteert.</translation>
</message> </message>
<message>
<location filename="../settings_dialog.cpp" line="267"/>
<source>disableTrophycheckBox</source>
<translation>Disable Trophy Pop-ups:\nDisable in-game trophy notifications. Trophy progress can still be tracked using the Trophy Viewer (right-click the game in the main window).</translation>
</message>
<message> <message>
<location filename="../settings_dialog.cpp" line="450"/> <location filename="../settings_dialog.cpp" line="450"/>
<source>hideCursorGroupBox</source> <source>hideCursorGroupBox</source>
@ -1216,6 +1246,21 @@
<source>backButtonBehaviorGroupBox</source> <source>backButtonBehaviorGroupBox</source>
<translation>Gedrag van de terugknop:\nStelt de terugknop van de controller in om een aanraking op de opgegeven positie op de PS4-touchpad na te bootsen.</translation> <translation>Gedrag van de terugknop:\nStelt de terugknop van de controller in om een aanraking op de opgegeven positie op de PS4-touchpad na te bootsen.</translation>
</message> </message>
<message>
<location filename="../settings_dialog.cpp"/>
<source>enableCompatibilityCheckBox</source>
<translation>Display Compatibility Data:\nDisplays game compatibility information in table view. Enable "Update Compatibility On Startup" to get up-to-date information.</translation>
</message>
<message>
<location filename="../settings_dialog.cpp"/>
<source>checkCompatibilityOnStartupCheckBox</source>
<translation>Update Compatibility On Startup:\nAutomatically update the compatibility database when shadPS4 starts.</translation>
</message>
<message>
<location filename="../settings_dialog.cpp"/>
<source>updateCompatibilityButton</source>
<translation>Update Compatibility Database:\nImmediately update the compatibility database.</translation>
</message>
<message> <message>
<location filename="../settings_dialog.cpp" line="70"/> <location filename="../settings_dialog.cpp" line="70"/>
<source>Never</source> <source>Never</source>
@ -1329,6 +1374,11 @@
<source>Serial</source> <source>Serial</source>
<translation>Serienummer</translation> <translation>Serienummer</translation>
</message> </message>
<message>
<location filename="../game_list_frame.cpp"/>
<source>Compatibility</source>
<translation>Compatibility</translation>
</message>
<message> <message>
<location filename="../game_list_frame.cpp" line="34"/> <location filename="../game_list_frame.cpp" line="34"/>
<source>Region</source> <source>Region</source>
@ -1364,6 +1414,36 @@
<source>Never Played</source> <source>Never Played</source>
<translation>Never Played</translation> <translation>Never Played</translation>
</message> </message>
<message>
<location filename="../game_list_frame.cpp"/>
<source>Compatibility is untested</source>
<translation>Compatibility is untested</translation>
</message>
<message>
<location filename="../game_list_frame.cpp"/>
<source>Game does not initialize properly / crashes the emulator</source>
<translation>Game does not initialize properly / crashes the emulator</translation>
</message>
<message>
<location filename="../game_list_frame.cpp"/>
<source>Game boots, but only displays a blank screen</source>
<translation>Game boots, but only displays a blank screen</translation>
</message>
<message>
<location filename="../game_list_frame.cpp"/>
<source>Game displays an image but does not go past the menu</source>
<translation>Game displays an image but does not go past the menu</translation>
</message>
<message>
<location filename="../game_list_frame.cpp"/>
<source>Game has game-breaking glitches or unplayable performance</source>
<translation>Game has game-breaking glitches or unplayable performance</translation>
</message>
<message>
<location filename="../game_list_frame.cpp"/>
<source>Game can be completed with playable performance and no major glitches</source>
<translation>Game can be completed with playable performance and no major glitches</translation>
</message>
</context> </context>
<context> <context>
<name>CheckUpdate</name> <name>CheckUpdate</name>

View File

@ -182,8 +182,8 @@
</message> </message>
<message> <message>
<location filename="../gui_context_menus.h" line="196"/> <location filename="../gui_context_menus.h" line="196"/>
<source>Shortcut created successfully!\n %1</source> <source>Shortcut created successfully!</source>
<translation>Utworzenie skrótu zakończone pomyślnie!\n %1</translation> <translation>Utworzenie skrótu zakończone pomyślnie!</translation>
</message> </message>
<message> <message>
<location filename="../gui_context_menus.h" line="199"/> <location filename="../gui_context_menus.h" line="199"/>
@ -192,8 +192,8 @@
</message> </message>
<message> <message>
<location filename="../gui_context_menus.h" line="200"/> <location filename="../gui_context_menus.h" line="200"/>
<source>Error creating shortcut!\n %1</source> <source>Error creating shortcut!</source>
<translation>Utworzenie skrótu zakończone niepowodzeniem!\n %1</translation> <translation>Utworzenie skrótu zakończone niepowodzeniem!</translation>
</message> </message>
<message> <message>
<location filename="../gui_context_menus.h" line="275"/> <location filename="../gui_context_menus.h" line="275"/>
@ -672,11 +672,36 @@
<source>GUI Settings</source> <source>GUI Settings</source>
<translation>Ustawienia Interfejsu</translation> <translation>Ustawienia Interfejsu</translation>
</message> </message>
<message>
<location filename="../settings_dialog.ui" line="475"/>
<source>Disable Trophy Pop-ups</source>
<translation>Disable Trophy Pop-ups</translation>
</message>
<message> <message>
<location filename="../settings_dialog.ui" line="375"/> <location filename="../settings_dialog.ui" line="375"/>
<source>Play title music</source> <source>Play title music</source>
<translation>Odtwórz muzykę tytułową</translation> <translation>Odtwórz muzykę tytułową</translation>
</message> </message>
<message>
<location filename="../settings_dialog.ui"/>
<source>Update Compatibility Database On Startup</source>
<translation>Update Compatibility Database On Startup</translation>
</message>
<message>
<location filename="../settings_dialog.ui"/>
<source>Game Compatibility</source>
<translation>Game Compatibility</translation>
</message>
<message>
<location filename="../settings_dialog.ui"/>
<source>Display Compatibility Data</source>
<translation>Display Compatibility Data</translation>
</message>
<message>
<location filename="../settings_dialog.ui"/>
<source>Update Compatibility Database</source>
<translation>Update Compatibility Database</translation>
</message>
<message> <message>
<location filename="../settings_dialog.ui" line="394"/> <location filename="../settings_dialog.ui" line="394"/>
<source>Volume</source> <source>Volume</source>
@ -1201,6 +1226,11 @@
<source>GUIgroupBox</source> <source>GUIgroupBox</source>
<translation>Odtwórz muzykę tytułową:\nJeśli gra to obsługuje, aktywuje odtwarzanie specjalnej muzyki podczas wybierania gry w GUI.</translation> <translation>Odtwórz muzykę tytułową:\nJeśli gra to obsługuje, aktywuje odtwarzanie specjalnej muzyki podczas wybierania gry w GUI.</translation>
</message> </message>
<message>
<location filename="../settings_dialog.cpp" line="267"/>
<source>disableTrophycheckBox</source>
<translation>Disable Trophy Pop-ups:\nDisable in-game trophy notifications. Trophy progress can still be tracked using the Trophy Viewer (right-click the game in the main window).</translation>
</message>
<message> <message>
<location filename="../settings_dialog.cpp" line="450"/> <location filename="../settings_dialog.cpp" line="450"/>
<source>hideCursorGroupBox</source> <source>hideCursorGroupBox</source>
@ -1216,6 +1246,21 @@
<source>backButtonBehaviorGroupBox</source> <source>backButtonBehaviorGroupBox</source>
<translation>Zachowanie przycisku Wstecz:\nUstawia przycisk Wstecz kontrolera tak, aby emulował dotknięcie określonego miejsca na panelu dotykowym PS4.</translation> <translation>Zachowanie przycisku Wstecz:\nUstawia przycisk Wstecz kontrolera tak, aby emulował dotknięcie określonego miejsca na panelu dotykowym PS4.</translation>
</message> </message>
<message>
<location filename="../settings_dialog.cpp"/>
<source>enableCompatibilityCheckBox</source>
<translation>Display Compatibility Data:\nDisplays game compatibility information in table view. Enable "Update Compatibility On Startup" to get up-to-date information.</translation>
</message>
<message>
<location filename="../settings_dialog.cpp"/>
<source>checkCompatibilityOnStartupCheckBox</source>
<translation>Update Compatibility On Startup:\nAutomatically update the compatibility database when shadPS4 starts.</translation>
</message>
<message>
<location filename="../settings_dialog.cpp"/>
<source>updateCompatibilityButton</source>
<translation>Update Compatibility Database:\nImmediately update the compatibility database.</translation>
</message>
<message> <message>
<location filename="../settings_dialog.cpp" line="70"/> <location filename="../settings_dialog.cpp" line="70"/>
<source>Never</source> <source>Never</source>
@ -1329,6 +1374,11 @@
<source>Serial</source> <source>Serial</source>
<translation>Numer seryjny</translation> <translation>Numer seryjny</translation>
</message> </message>
<message>
<location filename="../game_list_frame.cpp"/>
<source>Compatibility</source>
<translation>Compatibility</translation>
</message>
<message> <message>
<location filename="../game_list_frame.cpp" line="34"/> <location filename="../game_list_frame.cpp" line="34"/>
<source>Region</source> <source>Region</source>
@ -1364,6 +1414,36 @@
<source>Never Played</source> <source>Never Played</source>
<translation>Never Played</translation> <translation>Never Played</translation>
</message> </message>
<message>
<location filename="../game_list_frame.cpp"/>
<source>Compatibility is untested</source>
<translation>Compatibility is untested</translation>
</message>
<message>
<location filename="../game_list_frame.cpp"/>
<source>Game does not initialize properly / crashes the emulator</source>
<translation>Game does not initialize properly / crashes the emulator</translation>
</message>
<message>
<location filename="../game_list_frame.cpp"/>
<source>Game boots, but only displays a blank screen</source>
<translation>Game boots, but only displays a blank screen</translation>
</message>
<message>
<location filename="../game_list_frame.cpp"/>
<source>Game displays an image but does not go past the menu</source>
<translation>Game displays an image but does not go past the menu</translation>
</message>
<message>
<location filename="../game_list_frame.cpp"/>
<source>Game has game-breaking glitches or unplayable performance</source>
<translation>Game has game-breaking glitches or unplayable performance</translation>
</message>
<message>
<location filename="../game_list_frame.cpp"/>
<source>Game can be completed with playable performance and no major glitches</source>
<translation>Game can be completed with playable performance and no major glitches</translation>
</message>
</context> </context>
<context> <context>
<name>CheckUpdate</name> <name>CheckUpdate</name>

View File

@ -182,8 +182,8 @@
</message> </message>
<message> <message>
<location filename="../gui_context_menus.h" line="196"/> <location filename="../gui_context_menus.h" line="196"/>
<source>Shortcut created successfully!\n %1</source> <source>Shortcut created successfully!</source>
<translation>Atalho criado com sucesso!\n %1</translation> <translation>Atalho criado com sucesso!</translation>
</message> </message>
<message> <message>
<location filename="../gui_context_menus.h" line="199"/> <location filename="../gui_context_menus.h" line="199"/>
@ -192,8 +192,8 @@
</message> </message>
<message> <message>
<location filename="../gui_context_menus.h" line="200"/> <location filename="../gui_context_menus.h" line="200"/>
<source>Error creating shortcut!\n %1</source> <source>Error creating shortcut!</source>
<translation>Erro ao criar atalho!\n %1</translation> <translation>Erro ao criar atalho!</translation>
</message> </message>
<message> <message>
<location filename="../gui_context_menus.h" line="275"/> <location filename="../gui_context_menus.h" line="275"/>
@ -672,11 +672,36 @@
<source>GUI Settings</source> <source>GUI Settings</source>
<translation>Configurações da Interface</translation> <translation>Configurações da Interface</translation>
</message> </message>
<message>
<location filename="../settings_dialog.ui" line="475"/>
<source>Disable Trophy Pop-ups</source>
<translation>Desabilitar Pop-ups dos Troféus</translation>
</message>
<message> <message>
<location filename="../settings_dialog.ui" line="375"/> <location filename="../settings_dialog.ui" line="375"/>
<source>Play title music</source> <source>Play title music</source>
<translation>Reproduzir música de abertura</translation> <translation>Reproduzir música de abertura</translation>
</message> </message>
<message>
<location filename="../settings_dialog.ui"/>
<source>Update Compatibility Database On Startup</source>
<translation>Atualizar Compatibilidade ao Inicializar</translation>
</message>
<message>
<location filename="../settings_dialog.ui"/>
<source>Game Compatibility</source>
<translation>Compatibilidade dos Jogos</translation>
</message>
<message>
<location filename="../settings_dialog.ui"/>
<source>Display Compatibility Data</source>
<translation>Exibir Dados de Compatibilidade</translation>
</message>
<message>
<location filename="../settings_dialog.ui"/>
<source>Update Compatibility Database</source>
<translation>Atualizar Lista de Compatibilidade</translation>
</message>
<message> <message>
<location filename="../settings_dialog.ui" line="394"/> <location filename="../settings_dialog.ui" line="394"/>
<source>Volume</source> <source>Volume</source>
@ -1201,6 +1226,11 @@
<source>GUIgroupBox</source> <source>GUIgroupBox</source>
<translation>Reproduzir música de abertura:\nSe o jogo suportar, ativa a reprodução de uma música especial ao selecionar o jogo na interface do menu.</translation> <translation>Reproduzir música de abertura:\nSe o jogo suportar, ativa a reprodução de uma música especial ao selecionar o jogo na interface do menu.</translation>
</message> </message>
<message>
<location filename="../settings_dialog.cpp" line="267"/>
<source>disableTrophycheckBox</source>
<translation>Desabilitar pop-ups dos troféus:\nDesabilite notificações de troféus no jogo. O progresso do troféu ainda pode ser rastreado usando o Trophy Viewer (clique com o botão direito do mouse no jogo na janela principal).</translation>
</message>
<message> <message>
<location filename="../settings_dialog.cpp" line="450"/> <location filename="../settings_dialog.cpp" line="450"/>
<source>hideCursorGroupBox</source> <source>hideCursorGroupBox</source>
@ -1216,6 +1246,21 @@
<source>backButtonBehaviorGroupBox</source> <source>backButtonBehaviorGroupBox</source>
<translation>Comportamento do botão Voltar:\nDefine o botão Voltar do controle para emular o toque na posição especificada no touchpad do PS4.</translation> <translation>Comportamento do botão Voltar:\nDefine o botão Voltar do controle para emular o toque na posição especificada no touchpad do PS4.</translation>
</message> </message>
<message>
<location filename="../settings_dialog.cpp"/>
<source>enableCompatibilityCheckBox</source>
<translation>Exibir Dados de Compatibilidade:\nExibe informações de compatibilidade dos jogos na janela principal.\nHabilitar "Atualizar Compatibilidade ao Inicializar" para obter informações atualizadas.</translation>
</message>
<message>
<location filename="../settings_dialog.cpp"/>
<source>checkCompatibilityOnStartupCheckBox</source>
<translation>Atualizar Compatibilidade ao inicializar:\nAtualiza automaticamente o banco de dados de compatibilidade quando o SHADPS4 é iniciado.</translation>
</message>
<message>
<location filename="../settings_dialog.cpp"/>
<source>updateCompatibilityButton</source>
<translation>Atualizar Lista de Compatibilidade:\nAtualizar imediatamente o banco de dados de compatibilidade.</translation>
</message>
<message> <message>
<location filename="../settings_dialog.cpp" line="70"/> <location filename="../settings_dialog.cpp" line="70"/>
<source>Never</source> <source>Never</source>
@ -1329,6 +1374,11 @@
<source>Serial</source> <source>Serial</source>
<translation>Serial</translation> <translation>Serial</translation>
</message> </message>
<message>
<location filename="../game_list_frame.cpp"/>
<source>Compatibility</source>
<translation>Compatibilidade</translation>
</message>
<message> <message>
<location filename="../game_list_frame.cpp" line="36"/> <location filename="../game_list_frame.cpp" line="36"/>
<source>Region</source> <source>Region</source>
@ -1364,6 +1414,36 @@
<source>Never Played</source> <source>Never Played</source>
<translation>Nunca jogado</translation> <translation>Nunca jogado</translation>
</message> </message>
<message>
<location filename="../game_list_frame.cpp"/>
<source>Compatibility is untested</source>
<translation>Compatibilidade não testada</translation>
</message>
<message>
<location filename="../game_list_frame.cpp"/>
<source>Game does not initialize properly / crashes the emulator</source>
<translation>Jogo não inicializa corretamente / trava o emulador</translation>
</message>
<message>
<location filename="../game_list_frame.cpp"/>
<source>Game boots, but only displays a blank screen</source>
<translation>O jogo inicializa, mas exibe apenas uma tela vazia</translation>
</message>
<message>
<location filename="../game_list_frame.cpp"/>
<source>Game displays an image but does not go past the menu</source>
<translation>Jogo exibe imagem mas não passa do menu</translation>
</message>
<message>
<location filename="../game_list_frame.cpp"/>
<source>Game has game-breaking glitches or unplayable performance</source>
<translation>O jogo tem falhas que interrompem o jogo ou desempenho injogável</translation>
</message>
<message>
<location filename="../game_list_frame.cpp"/>
<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>
</message>
</context> </context>
<context> <context>
<name>CheckUpdate</name> <name>CheckUpdate</name>

View File

@ -182,8 +182,8 @@
</message> </message>
<message> <message>
<location filename="../gui_context_menus.h" line="196"/> <location filename="../gui_context_menus.h" line="196"/>
<source>Shortcut created successfully!\n %1</source> <source>Shortcut created successfully!</source>
<translation>Shortcut created successfully!\n %1</translation> <translation>Shortcut created successfully!</translation>
</message> </message>
<message> <message>
<location filename="../gui_context_menus.h" line="199"/> <location filename="../gui_context_menus.h" line="199"/>
@ -192,8 +192,8 @@
</message> </message>
<message> <message>
<location filename="../gui_context_menus.h" line="200"/> <location filename="../gui_context_menus.h" line="200"/>
<source>Error creating shortcut!\n %1</source> <source>Error creating shortcut!</source>
<translation>Error creating shortcut!\n %1</translation> <translation>Error creating shortcut!</translation>
</message> </message>
<message> <message>
<location filename="../gui_context_menus.h" line="275"/> <location filename="../gui_context_menus.h" line="275"/>
@ -672,11 +672,36 @@
<source>GUI Settings</source> <source>GUI Settings</source>
<translation>Setări GUI</translation> <translation>Setări GUI</translation>
</message> </message>
<message>
<location filename="../settings_dialog.ui" line="475"/>
<source>Disable Trophy Pop-ups</source>
<translation>Disable Trophy Pop-ups</translation>
</message>
<message> <message>
<location filename="../settings_dialog.ui" line="375"/> <location filename="../settings_dialog.ui" line="375"/>
<source>Play title music</source> <source>Play title music</source>
<translation>Redă muzica titlului</translation> <translation>Redă muzica titlului</translation>
</message> </message>
<message>
<location filename="../settings_dialog.ui"/>
<source>Update Compatibility Database On Startup</source>
<translation>Update Compatibility Database On Startup</translation>
</message>
<message>
<location filename="../settings_dialog.ui"/>
<source>Game Compatibility</source>
<translation>Game Compatibility</translation>
</message>
<message>
<location filename="../settings_dialog.ui"/>
<source>Display Compatibility Data</source>
<translation>Display Compatibility Data</translation>
</message>
<message>
<location filename="../settings_dialog.ui"/>
<source>Update Compatibility Database</source>
<translation>Update Compatibility Database</translation>
</message>
<message> <message>
<location filename="../settings_dialog.ui" line="394"/> <location filename="../settings_dialog.ui" line="394"/>
<source>Volume</source> <source>Volume</source>
@ -1201,6 +1226,11 @@
<source>GUIgroupBox</source> <source>GUIgroupBox</source>
<translation>Redă muzica titlului:\nDacă un joc o suportă, activează redarea muzicii speciale când selectezi jocul în GUI.</translation> <translation>Redă muzica titlului:\nDacă un joc o suportă, activează redarea muzicii speciale când selectezi jocul în GUI.</translation>
</message> </message>
<message>
<location filename="../settings_dialog.cpp" line="267"/>
<source>disableTrophycheckBox</source>
<translation>Disable Trophy Pop-ups:\nDisable in-game trophy notifications. Trophy progress can still be tracked using the Trophy Viewer (right-click the game in the main window).</translation>
</message>
<message> <message>
<location filename="../settings_dialog.cpp" line="450"/> <location filename="../settings_dialog.cpp" line="450"/>
<source>hideCursorGroupBox</source> <source>hideCursorGroupBox</source>
@ -1216,6 +1246,21 @@
<source>backButtonBehaviorGroupBox</source> <source>backButtonBehaviorGroupBox</source>
<translation>Comportamentul butonului înapoi:\nSetează butonul înapoi al controlerului imite atingerea poziției specificate pe touchpad-ul PS4.</translation> <translation>Comportamentul butonului înapoi:\nSetează butonul înapoi al controlerului imite atingerea poziției specificate pe touchpad-ul PS4.</translation>
</message> </message>
<message>
<location filename="../settings_dialog.cpp"/>
<source>enableCompatibilityCheckBox</source>
<translation>Display Compatibility Data:\nDisplays game compatibility information in table view. Enable "Update Compatibility On Startup" to get up-to-date information.</translation>
</message>
<message>
<location filename="../settings_dialog.cpp"/>
<source>checkCompatibilityOnStartupCheckBox</source>
<translation>Update Compatibility On Startup:\nAutomatically update the compatibility database when shadPS4 starts.</translation>
</message>
<message>
<location filename="../settings_dialog.cpp"/>
<source>updateCompatibilityButton</source>
<translation>Update Compatibility Database:\nImmediately update the compatibility database.</translation>
</message>
<message> <message>
<location filename="../settings_dialog.cpp" line="70"/> <location filename="../settings_dialog.cpp" line="70"/>
<source>Never</source> <source>Never</source>
@ -1329,6 +1374,11 @@
<source>Serial</source> <source>Serial</source>
<translation>Serie</translation> <translation>Serie</translation>
</message> </message>
<message>
<location filename="../game_list_frame.cpp"/>
<source>Compatibility</source>
<translation>Compatibility</translation>
</message>
<message> <message>
<location filename="../game_list_frame.cpp" line="34"/> <location filename="../game_list_frame.cpp" line="34"/>
<source>Region</source> <source>Region</source>
@ -1364,6 +1414,36 @@
<source>Never Played</source> <source>Never Played</source>
<translation>Never Played</translation> <translation>Never Played</translation>
</message> </message>
<message>
<location filename="../game_list_frame.cpp"/>
<source>Compatibility is untested</source>
<translation>Compatibility is untested</translation>
</message>
<message>
<location filename="../game_list_frame.cpp"/>
<source>Game does not initialize properly / crashes the emulator</source>
<translation>Game does not initialize properly / crashes the emulator</translation>
</message>
<message>
<location filename="../game_list_frame.cpp"/>
<source>Game boots, but only displays a blank screen</source>
<translation>Game boots, but only displays a blank screen</translation>
</message>
<message>
<location filename="../game_list_frame.cpp"/>
<source>Game displays an image but does not go past the menu</source>
<translation>Game displays an image but does not go past the menu</translation>
</message>
<message>
<location filename="../game_list_frame.cpp"/>
<source>Game has game-breaking glitches or unplayable performance</source>
<translation>Game has game-breaking glitches or unplayable performance</translation>
</message>
<message>
<location filename="../game_list_frame.cpp"/>
<source>Game can be completed with playable performance and no major glitches</source>
<translation>Game can be completed with playable performance and no major glitches</translation>
</message>
</context> </context>
<context> <context>
<name>CheckUpdate</name> <name>CheckUpdate</name>

View File

@ -182,8 +182,8 @@
</message> </message>
<message> <message>
<location filename="../gui_context_menus.h" line="196"/> <location filename="../gui_context_menus.h" line="196"/>
<source>Shortcut created successfully!\n %1</source> <source>Shortcut created successfully!</source>
<translation>Ярлык создан успешно!\n %1</translation> <translation>Ярлык создан успешно!</translation>
</message> </message>
<message> <message>
<location filename="../gui_context_menus.h" line="199"/> <location filename="../gui_context_menus.h" line="199"/>
@ -192,8 +192,8 @@
</message> </message>
<message> <message>
<location filename="../gui_context_menus.h" line="200"/> <location filename="../gui_context_menus.h" line="200"/>
<source>Error creating shortcut!\n %1</source> <source>Error creating shortcut!</source>
<translation>Ошибка создания ярлыка!\n %1</translation> <translation>Ошибка создания ярлыка!</translation>
</message> </message>
<message> <message>
<location filename="../gui_context_menus.h" line="275"/> <location filename="../gui_context_menus.h" line="275"/>
@ -672,11 +672,36 @@
<source>GUI Settings</source> <source>GUI Settings</source>
<translation>Интерфейс</translation> <translation>Интерфейс</translation>
</message> </message>
<message>
<location filename="../settings_dialog.ui" line="475"/>
<source>Disable Trophy Pop-ups</source>
<translation>Disable Trophy Pop-ups</translation>
</message>
<message> <message>
<location filename="../settings_dialog.ui" line="375"/> <location filename="../settings_dialog.ui" line="375"/>
<source>Play title music</source> <source>Play title music</source>
<translation>Играть заглавную музыку</translation> <translation>Играть заглавную музыку</translation>
</message> </message>
<message>
<location filename="../settings_dialog.ui"/>
<source>Update Compatibility Database On Startup</source>
<translation>Update Compatibility Database On Startup</translation>
</message>
<message>
<location filename="../settings_dialog.ui"/>
<source>Game Compatibility</source>
<translation>Game Compatibility</translation>
</message>
<message>
<location filename="../settings_dialog.ui"/>
<source>Display Compatibility Data</source>
<translation>Display Compatibility Data</translation>
</message>
<message>
<location filename="../settings_dialog.ui"/>
<source>Update Compatibility Database</source>
<translation>Update Compatibility Database</translation>
</message>
<message> <message>
<location filename="../settings_dialog.ui" line="394"/> <location filename="../settings_dialog.ui" line="394"/>
<source>Volume</source> <source>Volume</source>
@ -1201,6 +1226,11 @@
<source>GUIgroupBox</source> <source>GUIgroupBox</source>
<translation>Играть заглавную музыку:\nВключает воспроизведение специальной музыки при выборе игры в списке, если она это поддерживает.</translation> <translation>Играть заглавную музыку:\nВключает воспроизведение специальной музыки при выборе игры в списке, если она это поддерживает.</translation>
</message> </message>
<message>
<location filename="../settings_dialog.cpp" line="267"/>
<source>disableTrophycheckBox</source>
<translation>Disable Trophy Pop-ups:\nDisable in-game trophy notifications. Trophy progress can still be tracked using the Trophy Viewer (right-click the game in the main window).</translation>
</message>
<message> <message>
<location filename="../settings_dialog.cpp" line="450"/> <location filename="../settings_dialog.cpp" line="450"/>
<source>hideCursorGroupBox</source> <source>hideCursorGroupBox</source>
@ -1216,6 +1246,21 @@
<source>backButtonBehaviorGroupBox</source> <source>backButtonBehaviorGroupBox</source>
<translation>Поведение кнопки «Назад»:\nНастраивает кнопку «Назад» контроллера на эмуляцию нажатия на указанную область на сенсорной панели контроллера PS4.</translation> <translation>Поведение кнопки «Назад»:\nНастраивает кнопку «Назад» контроллера на эмуляцию нажатия на указанную область на сенсорной панели контроллера PS4.</translation>
</message> </message>
<message>
<location filename="../settings_dialog.cpp"/>
<source>enableCompatibilityCheckBox</source>
<translation>Display Compatibility Data:\nDisplays game compatibility information in table view. Enable "Update Compatibility On Startup" to get up-to-date information.</translation>
</message>
<message>
<location filename="../settings_dialog.cpp"/>
<source>checkCompatibilityOnStartupCheckBox</source>
<translation>Update Compatibility On Startup:\nAutomatically update the compatibility database when shadPS4 starts.</translation>
</message>
<message>
<location filename="../settings_dialog.cpp"/>
<source>updateCompatibilityButton</source>
<translation>Update Compatibility Database:\nImmediately update the compatibility database.</translation>
</message>
<message> <message>
<location filename="../settings_dialog.cpp" line="70"/> <location filename="../settings_dialog.cpp" line="70"/>
<source>Never</source> <source>Never</source>
@ -1329,6 +1374,11 @@
<source>Serial</source> <source>Serial</source>
<translation>Серийный номер</translation> <translation>Серийный номер</translation>
</message> </message>
<message>
<location filename="../game_list_frame.cpp"/>
<source>Compatibility</source>
<translation>Compatibility</translation>
</message>
<message> <message>
<location filename="../game_list_frame.cpp" line="34"/> <location filename="../game_list_frame.cpp" line="34"/>
<source>Region</source> <source>Region</source>
@ -1364,6 +1414,36 @@
<source>Never Played</source> <source>Never Played</source>
<translation>Never Played</translation> <translation>Never Played</translation>
</message> </message>
<message>
<location filename="../game_list_frame.cpp"/>
<source>Compatibility is untested</source>
<translation>Compatibility is untested</translation>
</message>
<message>
<location filename="../game_list_frame.cpp"/>
<source>Game does not initialize properly / crashes the emulator</source>
<translation>Game does not initialize properly / crashes the emulator</translation>
</message>
<message>
<location filename="../game_list_frame.cpp"/>
<source>Game boots, but only displays a blank screen</source>
<translation>Game boots, but only displays a blank screen</translation>
</message>
<message>
<location filename="../game_list_frame.cpp"/>
<source>Game displays an image but does not go past the menu</source>
<translation>Game displays an image but does not go past the menu</translation>
</message>
<message>
<location filename="../game_list_frame.cpp"/>
<source>Game has game-breaking glitches or unplayable performance</source>
<translation>Game has game-breaking glitches or unplayable performance</translation>
</message>
<message>
<location filename="../game_list_frame.cpp"/>
<source>Game can be completed with playable performance and no major glitches</source>
<translation>Game can be completed with playable performance and no major glitches</translation>
</message>
</context> </context>
<context> <context>
<name>CheckUpdate</name> <name>CheckUpdate</name>

View File

@ -182,8 +182,8 @@
</message> </message>
<message> <message>
<location filename="../gui_context_menus.h" line="196"/> <location filename="../gui_context_menus.h" line="196"/>
<source>Shortcut created successfully!\n %1</source> <source>Shortcut created successfully!</source>
<translation>Shkurtorja u krijua me sukses!\n %1</translation> <translation>Shkurtorja u krijua me sukses!</translation>
</message> </message>
<message> <message>
<location filename="../gui_context_menus.h" line="199"/> <location filename="../gui_context_menus.h" line="199"/>
@ -192,8 +192,8 @@
</message> </message>
<message> <message>
<location filename="../gui_context_menus.h" line="200"/> <location filename="../gui_context_menus.h" line="200"/>
<source>Error creating shortcut!\n %1</source> <source>Error creating shortcut!</source>
<translation>Gabim krijimin e shkurtores!\n %1</translation> <translation>Gabim krijimin e shkurtores!</translation>
</message> </message>
<message> <message>
<location filename="../gui_context_menus.h" line="275"/> <location filename="../gui_context_menus.h" line="275"/>
@ -672,11 +672,36 @@
<source>GUI Settings</source> <source>GUI Settings</source>
<translation>Cilësimet e GUI</translation> <translation>Cilësimet e GUI</translation>
</message> </message>
<message>
<location filename="../settings_dialog.ui" line="475"/>
<source>Disable Trophy Pop-ups</source>
<translation>Çaktivizo njoftimet për Trofetë</translation>
</message>
<message> <message>
<location filename="../settings_dialog.ui" line="375"/> <location filename="../settings_dialog.ui" line="375"/>
<source>Play title music</source> <source>Play title music</source>
<translation>Luaj muzikën e titullit</translation> <translation>Luaj muzikën e titullit</translation>
</message> </message>
<message>
<location filename="../settings_dialog.ui"/>
<source>Update Compatibility Database On Startup</source>
<translation>Përditëso bazën e dhënave përputhshmërisë gjatë nisjes</translation>
</message>
<message>
<location filename="../settings_dialog.ui"/>
<source>Game Compatibility</source>
<translation>Përputhshmëria e lojës</translation>
</message>
<message>
<location filename="../settings_dialog.ui"/>
<source>Display Compatibility Data</source>
<translation>Shfaq dhënat e përputhshmërisë</translation>
</message>
<message>
<location filename="../settings_dialog.ui"/>
<source>Update Compatibility Database</source>
<translation>Përditëso bazën e dhënave përputhshmërisë</translation>
</message>
<message> <message>
<location filename="../settings_dialog.ui" line="394"/> <location filename="../settings_dialog.ui" line="394"/>
<source>Volume</source> <source>Volume</source>
@ -841,7 +866,7 @@
<message> <message>
<location filename="../cheats_patches.cpp" line="44"/> <location filename="../cheats_patches.cpp" line="44"/>
<source>Cheats / Patches for </source> <source>Cheats / Patches for </source>
<translation>Cheats / Patches for </translation> <translation>Mashtrime / Arna r </translation>
</message> </message>
<message> <message>
<location filename="../cheats_patches.cpp" line="50"/> <location filename="../cheats_patches.cpp" line="50"/>
@ -1159,7 +1184,7 @@
<message> <message>
<location filename="../settings_dialog.cpp" line="293"/> <location filename="../settings_dialog.cpp" line="293"/>
<source>separateUpdatesCheckBox</source> <source>separateUpdatesCheckBox</source>
<translation>Aktivizo dosjen e ndarë përditësimit:\nAktivizon instalimin e përditësimeve lojërave dosje veçanta për menaxhim lehtë.</translation> <translation>Aktivizo dosjen e ndarë përditësimit:\nAktivizon instalimin e përditësimeve lojërave dosje veçanta për menaxhim lehtë.\nKjo mund krijohet manualisht duke shtuar përditësimin e shpaketuar dosjen e lojës me emrin "CUSA00000-UPDATE" ku ID-ja CUSA përputhet me ID- e lojës.</translation>
</message> </message>
<message> <message>
<location filename="../settings_dialog.cpp" line="295"/> <location filename="../settings_dialog.cpp" line="295"/>
@ -1201,6 +1226,11 @@
<source>GUIgroupBox</source> <source>GUIgroupBox</source>
<translation>Luaj muzikën e titullit:\nNëse një lojë e mbështet, aktivizohet luajtja e muzikës veçantë kur zgjidhësh lojën GUI.</translation> <translation>Luaj muzikën e titullit:\nNëse një lojë e mbështet, aktivizohet luajtja e muzikës veçantë kur zgjidhësh lojën GUI.</translation>
</message> </message>
<message>
<location filename="../settings_dialog.cpp" line="267"/>
<source>disableTrophycheckBox</source>
<translation>Çaktivizo njoftimet për Trofetë:\nÇaktivizo njoftimet për trofetë gjatë lojës. Përparimi i trofeve mund ndiqet duke përdorur Shikuesin e Trofeve (kliko me djathtën mbi lojën dritaren kryesore).</translation>
</message>
<message> <message>
<location filename="../settings_dialog.cpp" line="450"/> <location filename="../settings_dialog.cpp" line="450"/>
<source>hideCursorGroupBox</source> <source>hideCursorGroupBox</source>
@ -1216,6 +1246,21 @@
<source>backButtonBehaviorGroupBox</source> <source>backButtonBehaviorGroupBox</source>
<translation>Sjellja e butonit mbrapa:\nLejon përcaktohet se cilën pjesë tastierës prekëse do imitojë një prekje butoni mprapa.</translation> <translation>Sjellja e butonit mbrapa:\nLejon përcaktohet se cilën pjesë tastierës prekëse do imitojë një prekje butoni mprapa.</translation>
</message> </message>
<message>
<location filename="../settings_dialog.cpp"/>
<source>enableCompatibilityCheckBox</source>
<translation>Shfaq dhënat e përputhshmërisë:\nShfaq informacionin e përputhshmërisë lojës formë tabele. Aktivizo 'Përditëso përputhshmërinë gjatë nisjes' për marrë informacion përditësuar.</translation>
</message>
<message>
<location filename="../settings_dialog.cpp"/>
<source>checkCompatibilityOnStartupCheckBox</source>
<translation>Përditëso përputhshmërinë gjatë nisjes:\nPërditëson automatikisht bazën e dhënave përputhshmërisë kur shadPS4 niset.</translation>
</message>
<message>
<location filename="../settings_dialog.cpp"/>
<source>updateCompatibilityButton</source>
<translation>Përditëso bazën e dhënave përputhshmërisë:\nPërditëso menjëherë bazën e dhënave përputhshmërisë.</translation>
</message>
<message> <message>
<location filename="../settings_dialog.cpp" line="70"/> <location filename="../settings_dialog.cpp" line="70"/>
<source>Never</source> <source>Never</source>
@ -1329,6 +1374,11 @@
<source>Serial</source> <source>Serial</source>
<translation>Seriku</translation> <translation>Seriku</translation>
</message> </message>
<message>
<location filename="../game_list_frame.cpp"/>
<source>Compatibility</source>
<translation>Përputhshmëria</translation>
</message>
<message> <message>
<location filename="../game_list_frame.cpp" line="34"/> <location filename="../game_list_frame.cpp" line="34"/>
<source>Region</source> <source>Region</source>
@ -1362,7 +1412,37 @@
<message> <message>
<location filename="../game_list_frame.cpp" line="108"/> <location filename="../game_list_frame.cpp" line="108"/>
<source>Never Played</source> <source>Never Played</source>
<translation>Never Played</translation> <translation>Nuk është luajtur kurrë</translation>
</message>
<message>
<location filename="../game_list_frame.cpp"/>
<source>Compatibility is untested</source>
<translation>Përputhshmëria nuk është e testuar</translation>
</message>
<message>
<location filename="../game_list_frame.cpp"/>
<source>Game does not initialize properly / crashes the emulator</source>
<translation>Loja nuk niset siç duhet / rrëzon emulatorin</translation>
</message>
<message>
<location filename="../game_list_frame.cpp"/>
<source>Game boots, but only displays a blank screen</source>
<translation>Loja niset, por shfaq vetëm një ekran zbrazët</translation>
</message>
<message>
<location filename="../game_list_frame.cpp"/>
<source>Game displays an image but does not go past the menu</source>
<translation>Loja shfaq një imazh, por nuk kalon përtej menysë</translation>
</message>
<message>
<location filename="../game_list_frame.cpp"/>
<source>Game has game-breaking glitches or unplayable performance</source>
<translation>Loja ka probleme kritike ose performancë papërshtatshme për lojë</translation>
</message>
<message>
<location filename="../game_list_frame.cpp"/>
<source>Game can be completed with playable performance and no major glitches</source>
<translation>Loja mund përfundohet me performancë luajtshme dhe pa probleme mëdha</translation>
</message> </message>
</context> </context>
<context> <context>

View File

@ -182,8 +182,8 @@
</message> </message>
<message> <message>
<location filename="../gui_context_menus.h" line="196"/> <location filename="../gui_context_menus.h" line="196"/>
<source>Shortcut created successfully!\n %1</source> <source>Shortcut created successfully!</source>
<translation>Kısayol başarıyla oluşturuldu!\n %1</translation> <translation>Kısayol başarıyla oluşturuldu!</translation>
</message> </message>
<message> <message>
<location filename="../gui_context_menus.h" line="199"/> <location filename="../gui_context_menus.h" line="199"/>
@ -192,8 +192,8 @@
</message> </message>
<message> <message>
<location filename="../gui_context_menus.h" line="200"/> <location filename="../gui_context_menus.h" line="200"/>
<source>Error creating shortcut!\n %1</source> <source>Error creating shortcut!</source>
<translation>Kısayol oluşturulurken hata oluştu!\n %1</translation> <translation>Kısayol oluşturulurken hata oluştu!</translation>
</message> </message>
<message> <message>
<location filename="../gui_context_menus.h" line="275"/> <location filename="../gui_context_menus.h" line="275"/>
@ -672,11 +672,36 @@
<source>GUI Settings</source> <source>GUI Settings</source>
<translation>GUI Ayarları</translation> <translation>GUI Ayarları</translation>
</message> </message>
<message>
<location filename="../settings_dialog.ui" line="475"/>
<source>Disable Trophy Pop-ups</source>
<translation>Disable Trophy Pop-ups</translation>
</message>
<message> <message>
<location filename="../settings_dialog.ui" line="375"/> <location filename="../settings_dialog.ui" line="375"/>
<source>Play title music</source> <source>Play title music</source>
<translation>Başlık müziğini çal</translation> <translation>Başlık müziğini çal</translation>
</message> </message>
<message>
<location filename="../settings_dialog.ui"/>
<source>Update Compatibility Database On Startup</source>
<translation>Update Compatibility Database On Startup</translation>
</message>
<message>
<location filename="../settings_dialog.ui"/>
<source>Game Compatibility</source>
<translation>Game Compatibility</translation>
</message>
<message>
<location filename="../settings_dialog.ui"/>
<source>Display Compatibility Data</source>
<translation>Display Compatibility Data</translation>
</message>
<message>
<location filename="../settings_dialog.ui"/>
<source>Update Compatibility Database</source>
<translation>Update Compatibility Database</translation>
</message>
<message> <message>
<location filename="../settings_dialog.ui" line="394"/> <location filename="../settings_dialog.ui" line="394"/>
<source>Volume</source> <source>Volume</source>
@ -1201,6 +1226,11 @@
<source>GUIgroupBox</source> <source>GUIgroupBox</source>
<translation>Başlık Müziklerini Çal:\nEğer bir oyun bunu destekliyorsa, GUI'de oyunu seçtiğinizde özel müziklerin çalmasını etkinleştirir.</translation> <translation>Başlık Müziklerini Çal:\nEğer bir oyun bunu destekliyorsa, GUI'de oyunu seçtiğinizde özel müziklerin çalmasını etkinleştirir.</translation>
</message> </message>
<message>
<location filename="../settings_dialog.cpp" line="267"/>
<source>disableTrophycheckBox</source>
<translation>Disable Trophy Pop-ups:\nDisable in-game trophy notifications. Trophy progress can still be tracked using the Trophy Viewer (right-click the game in the main window).</translation>
</message>
<message> <message>
<location filename="../settings_dialog.cpp" line="450"/> <location filename="../settings_dialog.cpp" line="450"/>
<source>hideCursorGroupBox</source> <source>hideCursorGroupBox</source>
@ -1216,6 +1246,21 @@
<source>backButtonBehaviorGroupBox</source> <source>backButtonBehaviorGroupBox</source>
<translation>Geri düğmesi davranışı:\nKontrol cihazındaki geri düğmesini, PS4'ün dokunmatik panelindeki belirlenen noktaya dokunmak için ayarlar.</translation> <translation>Geri düğmesi davranışı:\nKontrol cihazındaki geri düğmesini, PS4'ün dokunmatik panelindeki belirlenen noktaya dokunmak için ayarlar.</translation>
</message> </message>
<message>
<location filename="../settings_dialog.cpp"/>
<source>enableCompatibilityCheckBox</source>
<translation>Display Compatibility Data:\nDisplays game compatibility information in table view. Enable "Update Compatibility On Startup" to get up-to-date information.</translation>
</message>
<message>
<location filename="../settings_dialog.cpp"/>
<source>checkCompatibilityOnStartupCheckBox</source>
<translation>Update Compatibility On Startup:\nAutomatically update the compatibility database when shadPS4 starts.</translation>
</message>
<message>
<location filename="../settings_dialog.cpp"/>
<source>updateCompatibilityButton</source>
<translation>Update Compatibility Database:\nImmediately update the compatibility database.</translation>
</message>
<message> <message>
<location filename="../settings_dialog.cpp" line="70"/> <location filename="../settings_dialog.cpp" line="70"/>
<source>Never</source> <source>Never</source>
@ -1329,6 +1374,11 @@
<source>Serial</source> <source>Serial</source>
<translation>Seri Numarası</translation> <translation>Seri Numarası</translation>
</message> </message>
<message>
<location filename="../game_list_frame.cpp"/>
<source>Compatibility</source>
<translation>Compatibility</translation>
</message>
<message> <message>
<location filename="../game_list_frame.cpp" line="34"/> <location filename="../game_list_frame.cpp" line="34"/>
<source>Region</source> <source>Region</source>
@ -1364,6 +1414,36 @@
<source>Never Played</source> <source>Never Played</source>
<translation>Never Played</translation> <translation>Never Played</translation>
</message> </message>
<message>
<location filename="../game_list_frame.cpp"/>
<source>Compatibility is untested</source>
<translation>Compatibility is untested</translation>
</message>
<message>
<location filename="../game_list_frame.cpp"/>
<source>Game does not initialize properly / crashes the emulator</source>
<translation>Game does not initialize properly / crashes the emulator</translation>
</message>
<message>
<location filename="../game_list_frame.cpp"/>
<source>Game boots, but only displays a blank screen</source>
<translation>Game boots, but only displays a blank screen</translation>
</message>
<message>
<location filename="../game_list_frame.cpp"/>
<source>Game displays an image but does not go past the menu</source>
<translation>Game displays an image but does not go past the menu</translation>
</message>
<message>
<location filename="../game_list_frame.cpp"/>
<source>Game has game-breaking glitches or unplayable performance</source>
<translation>Game has game-breaking glitches or unplayable performance</translation>
</message>
<message>
<location filename="../game_list_frame.cpp"/>
<source>Game can be completed with playable performance and no major glitches</source>
<translation>Game can be completed with playable performance and no major glitches</translation>
</message>
</context> </context>
<context> <context>
<name>CheckUpdate</name> <name>CheckUpdate</name>

View File

@ -182,8 +182,8 @@
</message> </message>
<message> <message>
<location filename="../gui_context_menus.h" line="196"/> <location filename="../gui_context_menus.h" line="196"/>
<source>Shortcut created successfully!\n %1</source> <source>Shortcut created successfully!</source>
<translation>Ярлик створений успішно!\n %1</translation> <translation>Ярлик створений успішно!</translation>
</message> </message>
<message> <message>
<location filename="../gui_context_menus.h" line="199"/> <location filename="../gui_context_menus.h" line="199"/>
@ -192,8 +192,8 @@
</message> </message>
<message> <message>
<location filename="../gui_context_menus.h" line="200"/> <location filename="../gui_context_menus.h" line="200"/>
<source>Error creating shortcut!\n %1</source> <source>Error creating shortcut!</source>
<translation>Помилка при створенні ярлика!\n %1</translation> <translation>Помилка при створенні ярлика!</translation>
</message> </message>
<message> <message>
<location filename="../gui_context_menus.h" line="275"/> <location filename="../gui_context_menus.h" line="275"/>
@ -672,11 +672,36 @@
<source>GUI Settings</source> <source>GUI Settings</source>
<translation>Інтерфейс</translation> <translation>Інтерфейс</translation>
</message> </message>
<message>
<location filename="../settings_dialog.ui" line="475"/>
<source>Disable Trophy Pop-ups</source>
<translation>Disable Trophy Pop-ups</translation>
</message>
<message> <message>
<location filename="../settings_dialog.ui" line="375"/> <location filename="../settings_dialog.ui" line="375"/>
<source>Play title music</source> <source>Play title music</source>
<translation>Програвати заголовну музику</translation> <translation>Програвати заголовну музику</translation>
</message> </message>
<message>
<location filename="../settings_dialog.ui"/>
<source>Update Compatibility Database On Startup</source>
<translation>Update Compatibility Database On Startup</translation>
</message>
<message>
<location filename="../settings_dialog.ui"/>
<source>Game Compatibility</source>
<translation>Game Compatibility</translation>
</message>
<message>
<location filename="../settings_dialog.ui"/>
<source>Display Compatibility Data</source>
<translation>Display Compatibility Data</translation>
</message>
<message>
<location filename="../settings_dialog.ui"/>
<source>Update Compatibility Database</source>
<translation>Update Compatibility Database</translation>
</message>
<message> <message>
<location filename="../settings_dialog.ui" line="394"/> <location filename="../settings_dialog.ui" line="394"/>
<source>Volume</source> <source>Volume</source>
@ -1201,6 +1226,11 @@
<source>GUIgroupBox</source> <source>GUIgroupBox</source>
<translation>Грати заголовну музику:\nВмикає відтворення спеціальної музики під час вибору гри в списку, якщо вона це підтримує.</translation> <translation>Грати заголовну музику:\nВмикає відтворення спеціальної музики під час вибору гри в списку, якщо вона це підтримує.</translation>
</message> </message>
<message>
<location filename="../settings_dialog.cpp" line="267"/>
<source>disableTrophycheckBox</source>
<translation>Disable Trophy Pop-ups:\nDisable in-game trophy notifications. Trophy progress can still be tracked using the Trophy Viewer (right-click the game in the main window).</translation>
</message>
<message> <message>
<location filename="../settings_dialog.cpp" line="450"/> <location filename="../settings_dialog.cpp" line="450"/>
<source>hideCursorGroupBox</source> <source>hideCursorGroupBox</source>
@ -1216,6 +1246,21 @@
<source>backButtonBehaviorGroupBox</source> <source>backButtonBehaviorGroupBox</source>
<translation>Поведінка кнопки «Назад»:\nНалаштовує кнопку «Назад» контролера на емуляцію натискання на зазначену область на сенсорній панелі контролера PS4.</translation> <translation>Поведінка кнопки «Назад»:\nНалаштовує кнопку «Назад» контролера на емуляцію натискання на зазначену область на сенсорній панелі контролера PS4.</translation>
</message> </message>
<message>
<location filename="../settings_dialog.cpp"/>
<source>enableCompatibilityCheckBox</source>
<translation>Display Compatibility Data:\nDisplays game compatibility information in table view. Enable "Update Compatibility On Startup" to get up-to-date information.</translation>
</message>
<message>
<location filename="../settings_dialog.cpp"/>
<source>checkCompatibilityOnStartupCheckBox</source>
<translation>Update Compatibility On Startup:\nAutomatically update the compatibility database when shadPS4 starts.</translation>
</message>
<message>
<location filename="../settings_dialog.cpp"/>
<source>updateCompatibilityButton</source>
<translation>Update Compatibility Database:\nImmediately update the compatibility database.</translation>
</message>
<message> <message>
<location filename="../settings_dialog.cpp" line="70"/> <location filename="../settings_dialog.cpp" line="70"/>
<source>Never</source> <source>Never</source>
@ -1329,6 +1374,11 @@
<source>Serial</source> <source>Serial</source>
<translation>Серійний номер</translation> <translation>Серійний номер</translation>
</message> </message>
<message>
<location filename="../game_list_frame.cpp"/>
<source>Compatibility</source>
<translation>Compatibility</translation>
</message>
<message> <message>
<location filename="../game_list_frame.cpp" line="34"/> <location filename="../game_list_frame.cpp" line="34"/>
<source>Region</source> <source>Region</source>
@ -1364,6 +1414,36 @@
<source>Never Played</source> <source>Never Played</source>
<translation>Never Played</translation> <translation>Never Played</translation>
</message> </message>
<message>
<location filename="../game_list_frame.cpp"/>
<source>Compatibility is untested</source>
<translation>Compatibility is untested</translation>
</message>
<message>
<location filename="../game_list_frame.cpp"/>
<source>Game does not initialize properly / crashes the emulator</source>
<translation>Game does not initialize properly / crashes the emulator</translation>
</message>
<message>
<location filename="../game_list_frame.cpp"/>
<source>Game boots, but only displays a blank screen</source>
<translation>Game boots, but only displays a blank screen</translation>
</message>
<message>
<location filename="../game_list_frame.cpp"/>
<source>Game displays an image but does not go past the menu</source>
<translation>Game displays an image but does not go past the menu</translation>
</message>
<message>
<location filename="../game_list_frame.cpp"/>
<source>Game has game-breaking glitches or unplayable performance</source>
<translation>Game has game-breaking glitches or unplayable performance</translation>
</message>
<message>
<location filename="../game_list_frame.cpp"/>
<source>Game can be completed with playable performance and no major glitches</source>
<translation>Game can be completed with playable performance and no major glitches</translation>
</message>
</context> </context>
<context> <context>
<name>CheckUpdate</name> <name>CheckUpdate</name>

View File

@ -182,8 +182,8 @@
</message> </message>
<message> <message>
<location filename="../gui_context_menus.h" line="196"/> <location filename="../gui_context_menus.h" line="196"/>
<source>Shortcut created successfully!\n %1</source> <source>Shortcut created successfully!</source>
<translation>Shortcut created successfully!\n %1</translation> <translation>Shortcut created successfully!</translation>
</message> </message>
<message> <message>
<location filename="../gui_context_menus.h" line="199"/> <location filename="../gui_context_menus.h" line="199"/>
@ -192,8 +192,8 @@
</message> </message>
<message> <message>
<location filename="../gui_context_menus.h" line="200"/> <location filename="../gui_context_menus.h" line="200"/>
<source>Error creating shortcut!\n %1</source> <source>Error creating shortcut!</source>
<translation>Error creating shortcut!\n %1</translation> <translation>Error creating shortcut!</translation>
</message> </message>
<message> <message>
<location filename="../gui_context_menus.h" line="275"/> <location filename="../gui_context_menus.h" line="275"/>
@ -672,11 +672,36 @@
<source>GUI Settings</source> <source>GUI Settings</source>
<translation>Cài đt GUI</translation> <translation>Cài đt GUI</translation>
</message> </message>
<message>
<location filename="../settings_dialog.ui" line="475"/>
<source>Disable Trophy Pop-ups</source>
<translation>Disable Trophy Pop-ups</translation>
</message>
<message> <message>
<location filename="../settings_dialog.ui" line="375"/> <location filename="../settings_dialog.ui" line="375"/>
<source>Play title music</source> <source>Play title music</source>
<translation>Phát nhạc tiêu đ</translation> <translation>Phát nhạc tiêu đ</translation>
</message> </message>
<message>
<location filename="../settings_dialog.ui"/>
<source>Update Compatibility Database On Startup</source>
<translation>Update Compatibility Database On Startup</translation>
</message>
<message>
<location filename="../settings_dialog.ui"/>
<source>Game Compatibility</source>
<translation>Game Compatibility</translation>
</message>
<message>
<location filename="../settings_dialog.ui"/>
<source>Display Compatibility Data</source>
<translation>Display Compatibility Data</translation>
</message>
<message>
<location filename="../settings_dialog.ui"/>
<source>Update Compatibility Database</source>
<translation>Update Compatibility Database</translation>
</message>
<message> <message>
<location filename="../settings_dialog.ui" line="394"/> <location filename="../settings_dialog.ui" line="394"/>
<source>Volume</source> <source>Volume</source>
@ -1201,6 +1226,11 @@
<source>GUIgroupBox</source> <source>GUIgroupBox</source>
<translation>Phát nhạc tiêu đ trò chơi:\nNếu một trò chơi hỗ trợ điều này, hãy kích hoạt phát nhạc đc biệt khi bạn chọn trò chơi trong GUI.</translation> <translation>Phát nhạc tiêu đ trò chơi:\nNếu một trò chơi hỗ trợ điều này, hãy kích hoạt phát nhạc đc biệt khi bạn chọn trò chơi trong GUI.</translation>
</message> </message>
<message>
<location filename="../settings_dialog.cpp" line="267"/>
<source>disableTrophycheckBox</source>
<translation>Disable Trophy Pop-ups:\nDisable in-game trophy notifications. Trophy progress can still be tracked using the Trophy Viewer (right-click the game in the main window).</translation>
</message>
<message> <message>
<location filename="../settings_dialog.cpp" line="450"/> <location filename="../settings_dialog.cpp" line="450"/>
<source>hideCursorGroupBox</source> <source>hideCursorGroupBox</source>
@ -1216,6 +1246,21 @@
<source>backButtonBehaviorGroupBox</source> <source>backButtonBehaviorGroupBox</source>
<translation>Hành vi nút quay lại:\nĐặt nút quay lại của tay cầm đ phỏng việc chạm vào vị trí đã chỉ đnh trên touchpad của PS4.</translation> <translation>Hành vi nút quay lại:\nĐặt nút quay lại của tay cầm đ phỏng việc chạm vào vị trí đã chỉ đnh trên touchpad của PS4.</translation>
</message> </message>
<message>
<location filename="../settings_dialog.cpp"/>
<source>enableCompatibilityCheckBox</source>
<translation>Display Compatibility Data:\nDisplays game compatibility information in table view. Enable "Update Compatibility On Startup" to get up-to-date information.</translation>
</message>
<message>
<location filename="../settings_dialog.cpp"/>
<source>checkCompatibilityOnStartupCheckBox</source>
<translation>Update Compatibility On Startup:\nAutomatically update the compatibility database when shadPS4 starts.</translation>
</message>
<message>
<location filename="../settings_dialog.cpp"/>
<source>updateCompatibilityButton</source>
<translation>Update Compatibility Database:\nImmediately update the compatibility database.</translation>
</message>
<message> <message>
<location filename="../settings_dialog.cpp" line="70"/> <location filename="../settings_dialog.cpp" line="70"/>
<source>Never</source> <source>Never</source>
@ -1329,6 +1374,11 @@
<source>Serial</source> <source>Serial</source>
<translation>Số seri</translation> <translation>Số seri</translation>
</message> </message>
<message>
<location filename="../game_list_frame.cpp"/>
<source>Compatibility</source>
<translation>Compatibility</translation>
</message>
<message> <message>
<location filename="../game_list_frame.cpp" line="34"/> <location filename="../game_list_frame.cpp" line="34"/>
<source>Region</source> <source>Region</source>
@ -1364,6 +1414,36 @@
<source>Never Played</source> <source>Never Played</source>
<translation>Never Played</translation> <translation>Never Played</translation>
</message> </message>
<message>
<location filename="../game_list_frame.cpp"/>
<source>Compatibility is untested</source>
<translation>Compatibility is untested</translation>
</message>
<message>
<location filename="../game_list_frame.cpp"/>
<source>Game does not initialize properly / crashes the emulator</source>
<translation>Game does not initialize properly / crashes the emulator</translation>
</message>
<message>
<location filename="../game_list_frame.cpp"/>
<source>Game boots, but only displays a blank screen</source>
<translation>Game boots, but only displays a blank screen</translation>
</message>
<message>
<location filename="../game_list_frame.cpp"/>
<source>Game displays an image but does not go past the menu</source>
<translation>Game displays an image but does not go past the menu</translation>
</message>
<message>
<location filename="../game_list_frame.cpp"/>
<source>Game has game-breaking glitches or unplayable performance</source>
<translation>Game has game-breaking glitches or unplayable performance</translation>
</message>
<message>
<location filename="../game_list_frame.cpp"/>
<source>Game can be completed with playable performance and no major glitches</source>
<translation>Game can be completed with playable performance and no major glitches</translation>
</message>
</context> </context>
<context> <context>
<name>CheckUpdate</name> <name>CheckUpdate</name>

View File

@ -182,8 +182,8 @@
</message> </message>
<message> <message>
<location filename="../gui_context_menus.h" line="196"/> <location filename="../gui_context_menus.h" line="196"/>
<source>Shortcut created successfully!\n %1</source> <source>Shortcut created successfully!</source>
<translation>!\n %1</translation> <translation>!</translation>
</message> </message>
<message> <message>
<location filename="../gui_context_menus.h" line="199"/> <location filename="../gui_context_menus.h" line="199"/>
@ -192,8 +192,8 @@
</message> </message>
<message> <message>
<location filename="../gui_context_menus.h" line="200"/> <location filename="../gui_context_menus.h" line="200"/>
<source>Error creating shortcut!\n %1</source> <source>Error creating shortcut!</source>
<translation>!\n %1</translation> <translation>!</translation>
</message> </message>
<message> <message>
<location filename="../gui_context_menus.h" line="275"/> <location filename="../gui_context_menus.h" line="275"/>
@ -672,11 +672,36 @@
<source>GUI Settings</source> <source>GUI Settings</source>
<translation></translation> <translation></translation>
</message> </message>
<message>
<location filename="../settings_dialog.ui" line="475"/>
<source>Disable Trophy Pop-ups</source>
<translation>Disable Trophy Pop-ups</translation>
</message>
<message> <message>
<location filename="../settings_dialog.ui" line="375"/> <location filename="../settings_dialog.ui" line="375"/>
<source>Play title music</source> <source>Play title music</source>
<translation></translation> <translation></translation>
</message> </message>
<message>
<location filename="../settings_dialog.ui"/>
<source>Update Compatibility Database On Startup</source>
<translation>Update Compatibility Database On Startup</translation>
</message>
<message>
<location filename="../settings_dialog.ui"/>
<source>Game Compatibility</source>
<translation>Game Compatibility</translation>
</message>
<message>
<location filename="../settings_dialog.ui"/>
<source>Display Compatibility Data</source>
<translation>Display Compatibility Data</translation>
</message>
<message>
<location filename="../settings_dialog.ui"/>
<source>Update Compatibility Database</source>
<translation>Update Compatibility Database</translation>
</message>
<message> <message>
<location filename="../settings_dialog.ui" line="394"/> <location filename="../settings_dialog.ui" line="394"/>
<source>Volume</source> <source>Volume</source>
@ -1201,6 +1226,11 @@
<source>GUIgroupBox</source> <source>GUIgroupBox</source>
<translation>:\n如果游戏支持</translation> <translation>:\n如果游戏支持</translation>
</message> </message>
<message>
<location filename="../settings_dialog.cpp" line="267"/>
<source>disableTrophycheckBox</source>
<translation>Disable Trophy Pop-ups:\nDisable in-game trophy notifications. Trophy progress can still be tracked using the Trophy Viewer (right-click the game in the main window).</translation>
</message>
<message> <message>
<location filename="../settings_dialog.cpp" line="450"/> <location filename="../settings_dialog.cpp" line="450"/>
<source>hideCursorGroupBox</source> <source>hideCursorGroupBox</source>
@ -1216,6 +1246,21 @@
<source>backButtonBehaviorGroupBox</source> <source>backButtonBehaviorGroupBox</source>
<translation>:\n设置控制器的返回按钮以模拟在 PS4 </translation> <translation>:\n设置控制器的返回按钮以模拟在 PS4 </translation>
</message> </message>
<message>
<location filename="../settings_dialog.cpp"/>
<source>enableCompatibilityCheckBox</source>
<translation>Display Compatibility Data:\nDisplays game compatibility information in table view. Enable "Update Compatibility On Startup" to get up-to-date information.</translation>
</message>
<message>
<location filename="../settings_dialog.cpp"/>
<source>checkCompatibilityOnStartupCheckBox</source>
<translation>Update Compatibility On Startup:\nAutomatically update the compatibility database when shadPS4 starts.</translation>
</message>
<message>
<location filename="../settings_dialog.cpp"/>
<source>updateCompatibilityButton</source>
<translation>Update Compatibility Database:\nImmediately update the compatibility database.</translation>
</message>
<message> <message>
<location filename="../settings_dialog.cpp" line="70"/> <location filename="../settings_dialog.cpp" line="70"/>
<source>Never</source> <source>Never</source>
@ -1329,6 +1374,11 @@
<source>Serial</source> <source>Serial</source>
<translation></translation> <translation></translation>
</message> </message>
<message>
<location filename="../game_list_frame.cpp"/>
<source>Compatibility</source>
<translation>Compatibility</translation>
</message>
<message> <message>
<location filename="../game_list_frame.cpp" line="34"/> <location filename="../game_list_frame.cpp" line="34"/>
<source>Region</source> <source>Region</source>
@ -1364,6 +1414,36 @@
<source>Never Played</source> <source>Never Played</source>
<translation>Never Played</translation> <translation>Never Played</translation>
</message> </message>
<message>
<location filename="../game_list_frame.cpp"/>
<source>Compatibility is untested</source>
<translation>Compatibility is untested</translation>
</message>
<message>
<location filename="../game_list_frame.cpp"/>
<source>Game does not initialize properly / crashes the emulator</source>
<translation>Game does not initialize properly / crashes the emulator</translation>
</message>
<message>
<location filename="../game_list_frame.cpp"/>
<source>Game boots, but only displays a blank screen</source>
<translation>Game boots, but only displays a blank screen</translation>
</message>
<message>
<location filename="../game_list_frame.cpp"/>
<source>Game displays an image but does not go past the menu</source>
<translation>Game displays an image but does not go past the menu</translation>
</message>
<message>
<location filename="../game_list_frame.cpp"/>
<source>Game has game-breaking glitches or unplayable performance</source>
<translation>Game has game-breaking glitches or unplayable performance</translation>
</message>
<message>
<location filename="../game_list_frame.cpp"/>
<source>Game can be completed with playable performance and no major glitches</source>
<translation>Game can be completed with playable performance and no major glitches</translation>
</message>
</context> </context>
<context> <context>
<name>CheckUpdate</name> <name>CheckUpdate</name>

View File

@ -182,8 +182,8 @@
</message> </message>
<message> <message>
<location filename="../gui_context_menus.h" line="196"/> <location filename="../gui_context_menus.h" line="196"/>
<source>Shortcut created successfully!\n %1</source> <source>Shortcut created successfully!</source>
<translation>Shortcut created successfully!\n %1</translation> <translation>Shortcut created successfully!</translation>
</message> </message>
<message> <message>
<location filename="../gui_context_menus.h" line="199"/> <location filename="../gui_context_menus.h" line="199"/>
@ -192,8 +192,8 @@
</message> </message>
<message> <message>
<location filename="../gui_context_menus.h" line="200"/> <location filename="../gui_context_menus.h" line="200"/>
<source>Error creating shortcut!\n %1</source> <source>Error creating shortcut!</source>
<translation>Error creating shortcut!\n %1</translation> <translation>Error creating shortcut!</translation>
</message> </message>
<message> <message>
<location filename="../gui_context_menus.h" line="275"/> <location filename="../gui_context_menus.h" line="275"/>
@ -672,11 +672,36 @@
<source>GUI Settings</source> <source>GUI Settings</source>
<translation></translation> <translation></translation>
</message> </message>
<message>
<location filename="../settings_dialog.ui" line="475"/>
<source>Disable Trophy Pop-ups</source>
<translation>Disable Trophy Pop-ups</translation>
</message>
<message> <message>
<location filename="../settings_dialog.ui" line="375"/> <location filename="../settings_dialog.ui" line="375"/>
<source>Play title music</source> <source>Play title music</source>
<translation></translation> <translation></translation>
</message> </message>
<message>
<location filename="../settings_dialog.ui"/>
<source>Update Compatibility Database On Startup</source>
<translation>Update Compatibility Database On Startup</translation>
</message>
<message>
<location filename="../settings_dialog.ui"/>
<source>Game Compatibility</source>
<translation>Game Compatibility</translation>
</message>
<message>
<location filename="../settings_dialog.ui"/>
<source>Display Compatibility Data</source>
<translation>Display Compatibility Data</translation>
</message>
<message>
<location filename="../settings_dialog.ui"/>
<source>Update Compatibility Database</source>
<translation>Update Compatibility Database</translation>
</message>
<message> <message>
<location filename="../settings_dialog.ui" line="394"/> <location filename="../settings_dialog.ui" line="394"/>
<source>Volume</source> <source>Volume</source>
@ -1201,6 +1226,11 @@
<source>GUIgroupBox</source> <source>GUIgroupBox</source>
<translation>:\n如果遊戲支持GUI中選擇遊戲時播放特殊音樂</translation> <translation>:\n如果遊戲支持GUI中選擇遊戲時播放特殊音樂</translation>
</message> </message>
<message>
<location filename="../settings_dialog.cpp" line="267"/>
<source>disableTrophycheckBox</source>
<translation>Disable Trophy Pop-ups:\nDisable in-game trophy notifications. Trophy progress can still be tracked using the Trophy Viewer (right-click the game in the main window).</translation>
</message>
<message> <message>
<location filename="../settings_dialog.cpp" line="450"/> <location filename="../settings_dialog.cpp" line="450"/>
<source>hideCursorGroupBox</source> <source>hideCursorGroupBox</source>
@ -1216,6 +1246,21 @@
<source>backButtonBehaviorGroupBox</source> <source>backButtonBehaviorGroupBox</source>
<translation>:\n設定控制器的返回按鈕模擬在 PS4 </translation> <translation>:\n設定控制器的返回按鈕模擬在 PS4 </translation>
</message> </message>
<message>
<location filename="../settings_dialog.cpp"/>
<source>enableCompatibilityCheckBox</source>
<translation>Display Compatibility Data:\nDisplays game compatibility information in table view. Enable "Update Compatibility On Startup" to get up-to-date information.</translation>
</message>
<message>
<location filename="../settings_dialog.cpp"/>
<source>checkCompatibilityOnStartupCheckBox</source>
<translation>Update Compatibility On Startup:\nAutomatically update the compatibility database when shadPS4 starts.</translation>
</message>
<message>
<location filename="../settings_dialog.cpp"/>
<source>updateCompatibilityButton</source>
<translation>Update Compatibility Database:\nImmediately update the compatibility database.</translation>
</message>
<message> <message>
<location filename="../settings_dialog.cpp" line="70"/> <location filename="../settings_dialog.cpp" line="70"/>
<source>Never</source> <source>Never</source>
@ -1329,6 +1374,11 @@
<source>Serial</source> <source>Serial</source>
<translation></translation> <translation></translation>
</message> </message>
<message>
<location filename="../game_list_frame.cpp"/>
<source>Compatibility</source>
<translation>Compatibility</translation>
</message>
<message> <message>
<location filename="../game_list_frame.cpp" line="34"/> <location filename="../game_list_frame.cpp" line="34"/>
<source>Region</source> <source>Region</source>
@ -1364,6 +1414,36 @@
<source>Never Played</source> <source>Never Played</source>
<translation>Never Played</translation> <translation>Never Played</translation>
</message> </message>
<message>
<location filename="../game_list_frame.cpp"/>
<source>Compatibility is untested</source>
<translation>Compatibility is untested</translation>
</message>
<message>
<location filename="../game_list_frame.cpp"/>
<source>Game does not initialize properly / crashes the emulator</source>
<translation>Game does not initialize properly / crashes the emulator</translation>
</message>
<message>
<location filename="../game_list_frame.cpp"/>
<source>Game boots, but only displays a blank screen</source>
<translation>Game boots, but only displays a blank screen</translation>
</message>
<message>
<location filename="../game_list_frame.cpp"/>
<source>Game displays an image but does not go past the menu</source>
<translation>Game displays an image but does not go past the menu</translation>
</message>
<message>
<location filename="../game_list_frame.cpp"/>
<source>Game has game-breaking glitches or unplayable performance</source>
<translation>Game has game-breaking glitches or unplayable performance</translation>
</message>
<message>
<location filename="../game_list_frame.cpp"/>
<source>Game can be completed with playable performance and no major glitches</source>
<translation>Game can be completed with playable performance and no major glitches</translation>
</message>
</context> </context>
<context> <context>
<name>CheckUpdate</name> <name>CheckUpdate</name>

View File

@ -1,5 +1,6 @@
// 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 <span> #include <span>
#include <type_traits> #include <type_traits>
#include <utility> #include <utility>

View File

@ -168,22 +168,6 @@ Id EmitImageGatherDref(EmitContext& ctx, IR::Inst* inst, u32 handle, Id coords,
return texture.is_integer ? ctx.OpBitcast(ctx.F32[4], texels) : texels; return texture.is_integer ? ctx.OpBitcast(ctx.F32[4], texels) : texels;
} }
Id EmitImageFetch(EmitContext& ctx, IR::Inst* inst, u32 handle, Id coords, Id lod,
const IR::Value& offset, Id ms) {
const auto& texture = ctx.images[handle & 0xFFFF];
const Id image = ctx.OpLoad(texture.image_type, texture.id);
const Id result_type = texture.data_types->Get(4);
ImageOperands operands;
operands.AddOffset(ctx, offset);
operands.Add(spv::ImageOperandsMask::Lod, lod);
operands.Add(spv::ImageOperandsMask::Sample, ms);
const Id texel =
texture.is_storage
? ctx.OpImageRead(result_type, image, coords, operands.mask, operands.operands)
: ctx.OpImageFetch(result_type, image, coords, operands.mask, operands.operands);
return texture.is_integer ? ctx.OpBitcast(ctx.F32[4], texel) : texel;
}
Id EmitImageQueryDimensions(EmitContext& ctx, IR::Inst* inst, u32 handle, Id lod, bool has_mips) { Id EmitImageQueryDimensions(EmitContext& ctx, IR::Inst* inst, u32 handle, Id lod, bool has_mips) {
const auto& texture = ctx.images[handle & 0xFFFF]; const auto& texture = ctx.images[handle & 0xFFFF];
const Id image = ctx.OpLoad(texture.image_type, texture.id); const Id image = ctx.OpLoad(texture.image_type, texture.id);
@ -236,15 +220,34 @@ Id EmitImageGradient(EmitContext& ctx, IR::Inst* inst, u32 handle, Id coords, Id
return texture.is_integer ? ctx.OpBitcast(ctx.F32[4], sample) : sample; return texture.is_integer ? ctx.OpBitcast(ctx.F32[4], sample) : sample;
} }
Id EmitImageRead(EmitContext& ctx, IR::Inst* inst, const IR::Value& index, Id coords, Id lod) { Id EmitImageRead(EmitContext& ctx, IR::Inst* inst, u32 handle, Id coords, Id lod, Id ms) {
UNREACHABLE_MSG("SPIR-V Instruction");
}
void EmitImageWrite(EmitContext& ctx, IR::Inst* inst, u32 handle, Id coords, Id lod, Id color) {
const auto& texture = ctx.images[handle & 0xFFFF]; const auto& texture = ctx.images[handle & 0xFFFF];
const Id image = ctx.OpLoad(texture.image_type, texture.id); const Id image = ctx.OpLoad(texture.image_type, texture.id);
const Id color_type = texture.data_types->Get(4); const Id color_type = texture.data_types->Get(4);
ImageOperands operands; ImageOperands operands;
operands.Add(spv::ImageOperandsMask::Sample, ms);
Id texel;
if (!texture.is_storage) {
operands.Add(spv::ImageOperandsMask::Lod, lod);
texel = ctx.OpImageFetch(color_type, image, coords, operands.mask, operands.operands);
} else {
if (ctx.profile.supports_image_load_store_lod) {
operands.Add(spv::ImageOperandsMask::Lod, lod);
} else if (Sirit::ValidId(lod)) {
LOG_WARNING(Render, "Image read with LOD not supported by driver");
}
texel = ctx.OpImageRead(color_type, image, coords, operands.mask, operands.operands);
}
return !texture.is_integer ? ctx.OpBitcast(ctx.U32[4], texel) : texel;
}
void EmitImageWrite(EmitContext& ctx, IR::Inst* inst, u32 handle, Id coords, Id lod, Id ms,
Id color) {
const auto& texture = ctx.images[handle & 0xFFFF];
const Id image = ctx.OpLoad(texture.image_type, texture.id);
const Id color_type = texture.data_types->Get(4);
ImageOperands operands;
operands.Add(spv::ImageOperandsMask::Sample, ms);
if (ctx.profile.supports_image_load_store_lod) { if (ctx.profile.supports_image_load_store_lod) {
operands.Add(spv::ImageOperandsMask::Lod, lod); operands.Add(spv::ImageOperandsMask::Lod, lod);
} else if (Sirit::ValidId(lod)) { } else if (Sirit::ValidId(lod)) {

View File

@ -395,14 +395,13 @@ Id EmitImageGather(EmitContext& ctx, IR::Inst* inst, u32 handle, Id coords,
const IR::Value& offset); const IR::Value& offset);
Id EmitImageGatherDref(EmitContext& ctx, IR::Inst* inst, u32 handle, Id coords, Id EmitImageGatherDref(EmitContext& ctx, IR::Inst* inst, u32 handle, Id coords,
const IR::Value& offset, Id dref); const IR::Value& offset, Id dref);
Id EmitImageFetch(EmitContext& ctx, IR::Inst* inst, u32 handle, Id coords, Id lod,
const IR::Value& offset, Id ms);
Id EmitImageQueryDimensions(EmitContext& ctx, IR::Inst* inst, u32 handle, Id lod, bool skip_mips); Id EmitImageQueryDimensions(EmitContext& ctx, IR::Inst* inst, u32 handle, Id lod, bool skip_mips);
Id EmitImageQueryLod(EmitContext& ctx, IR::Inst* inst, u32 handle, Id coords); Id EmitImageQueryLod(EmitContext& ctx, IR::Inst* inst, u32 handle, Id coords);
Id EmitImageGradient(EmitContext& ctx, IR::Inst* inst, u32 handle, Id coords, Id derivatives_dx, Id EmitImageGradient(EmitContext& ctx, IR::Inst* inst, u32 handle, Id coords, Id derivatives_dx,
Id derivatives_dy, const IR::Value& offset, const IR::Value& lod_clamp); Id derivatives_dy, const IR::Value& offset, const IR::Value& lod_clamp);
Id EmitImageRead(EmitContext& ctx, IR::Inst* inst, const IR::Value& index, Id coords, Id lod); Id EmitImageRead(EmitContext& ctx, IR::Inst* inst, u32 handle, Id coords, Id lod, Id ms);
void EmitImageWrite(EmitContext& ctx, IR::Inst* inst, u32 handle, Id coords, Id lod, Id color); void EmitImageWrite(EmitContext& ctx, IR::Inst* inst, u32 handle, Id coords, Id lod, Id ms,
Id color);
Id EmitImageAtomicIAdd32(EmitContext& ctx, IR::Inst* inst, u32 handle, Id coords, Id value); Id EmitImageAtomicIAdd32(EmitContext& ctx, IR::Inst* inst, u32 handle, Id coords, Id value);
Id EmitImageAtomicSMin32(EmitContext& ctx, IR::Inst* inst, u32 handle, Id coords, Id value); Id EmitImageAtomicSMin32(EmitContext& ctx, IR::Inst* inst, u32 handle, Id coords, Id value);

View File

@ -0,0 +1,329 @@
// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
#include <sirit/sirit.h>
#include "shader_recompiler/backend/spirv/emit_spirv_quad_rect.h"
#include "shader_recompiler/runtime_info.h"
namespace Shader::Backend::SPIRV {
using Sirit::Id;
constexpr u32 SPIRV_VERSION_1_5 = 0x00010500;
struct QuadRectListEmitter : public Sirit::Module {
explicit QuadRectListEmitter(const FragmentRuntimeInfo& fs_info_)
: Sirit::Module{SPIRV_VERSION_1_5}, fs_info{fs_info_}, inputs{fs_info_.num_inputs},
outputs{fs_info_.num_inputs} {
void_id = TypeVoid();
bool_id = TypeBool();
float_id = TypeFloat(32);
uint_id = TypeUInt(32U);
int_id = TypeInt(32U, true);
bvec2_id = TypeVector(bool_id, 2);
vec2_id = TypeVector(float_id, 2);
vec3_id = TypeVector(float_id, 3);
vec4_id = TypeVector(float_id, 4);
float_one = Constant(float_id, 1.0f);
float_min_one = Constant(float_id, -1.0f);
int_zero = Constant(int_id, 0);
const Id float_arr{TypeArray(float_id, Constant(uint_id, 1U))};
gl_per_vertex_type = TypeStruct(vec4_id, float_id, float_arr, float_arr);
Decorate(gl_per_vertex_type, spv::Decoration::Block);
MemberDecorate(gl_per_vertex_type, 0U, spv::Decoration::BuiltIn,
static_cast<u32>(spv::BuiltIn::Position));
MemberDecorate(gl_per_vertex_type, 1U, spv::Decoration::BuiltIn,
static_cast<u32>(spv::BuiltIn::PointSize));
MemberDecorate(gl_per_vertex_type, 2U, spv::Decoration::BuiltIn,
static_cast<u32>(spv::BuiltIn::ClipDistance));
MemberDecorate(gl_per_vertex_type, 3U, spv::Decoration::BuiltIn,
static_cast<u32>(spv::BuiltIn::CullDistance));
}
/// Emits tessellation control shader for interpolating the 4th vertex of rectange primitive
void EmitRectListTCS() {
DefineEntry(spv::ExecutionModel::TessellationControl);
// Set passthrough tessellation factors
const Id output_float_id{TypePointer(spv::StorageClass::Output, float_id)};
for (int i = 0; i < 4; i++) {
const Id ptr{OpAccessChain(output_float_id, gl_tess_level_outer, Int(i))};
OpStore(ptr, float_one);
}
for (int i = 0; i < 2; i++) {
const Id ptr{OpAccessChain(output_float_id, gl_tess_level_inner, Int(i))};
OpStore(ptr, float_one);
}
const Id input_vec4{TypePointer(spv::StorageClass::Input, vec4_id)};
const Id output_vec4{TypePointer(spv::StorageClass::Output, vec4_id)};
// Emit interpolation block of the 4th vertex in rect.
// Load positions
std::array<Id, 3> pos;
for (int i = 0; i < 3; i++) {
pos[i] = OpLoad(vec4_id, OpAccessChain(input_vec4, gl_in, Int(i), int_zero));
}
std::array<Id, 3> point_coord_equal;
for (int i = 0; i < 3; i++) {
// point_coord_equal[i] = equal(gl_in[i].gl_Position.xy, gl_in[(i + 1) %
// 3].gl_Position.xy);
const Id pos_l_xy{OpVectorShuffle(vec2_id, pos[i], pos[i], 0, 1)};
const Id pos_r_xy{OpVectorShuffle(vec2_id, pos[(i + 1) % 3], pos[(i + 1) % 3], 0, 1)};
point_coord_equal[i] = OpFOrdEqual(bvec2_id, pos_l_xy, pos_r_xy);
}
std::array<Id, 3> bary_coord;
std::array<Id, 3> is_edge_vertex;
for (int i = 0; i < 3; i++) {
// bool xy_equal = point_coord_equal[i].x && point_coord_equal[(i + 2) % 3].y;
const Id xy_equal{
OpLogicalAnd(bool_id, OpCompositeExtract(bool_id, point_coord_equal[i], 0),
OpCompositeExtract(bool_id, point_coord_equal[(i + 2) % 3], 1))};
// bool yx_equal = point_coord_equal[i].y && point_coord_equal[(i + 2) % 3].x;
const Id yx_equal{
OpLogicalAnd(bool_id, OpCompositeExtract(bool_id, point_coord_equal[i], 1),
OpCompositeExtract(bool_id, point_coord_equal[(i + 2) % 3], 0))};
// bary_coord[i] = (xy_equal || yx_equal) ? -1.f : 1.f;
is_edge_vertex[i] = OpLogicalOr(bool_id, xy_equal, yx_equal);
bary_coord[i] = OpSelect(float_id, is_edge_vertex[i], float_min_one, float_one);
}
const auto interpolate = [&](Id v0, Id v1, Id v2) {
// return v0 * bary_coord.x + v1 * bary_coord.y + v2 * bary_coord.z;
const Id p0{OpVectorTimesScalar(vec4_id, v0, bary_coord[0])};
const Id p1{OpVectorTimesScalar(vec4_id, v1, bary_coord[1])};
const Id p2{OpVectorTimesScalar(vec4_id, v2, bary_coord[2])};
return OpFAdd(vec4_id, p0, OpFAdd(vec4_id, p1, p2));
};
// int vertex_index_id = is_edge_vertex[1] ? 1 : (is_edge_vertex[2] ? 2 : 0);
Id vertex_index{OpSelect(int_id, is_edge_vertex[2], Int(2), Int(0))};
vertex_index = OpSelect(int_id, is_edge_vertex[1], Int(1), vertex_index);
// int index = (vertex_index_id + gl_InvocationID) % 3;
const Id invocation_id{OpLoad(int_id, gl_invocation_id)};
const Id invocation_3{OpIEqual(bool_id, invocation_id, Int(3))};
const Id index{OpSMod(int_id, OpIAdd(int_id, vertex_index, invocation_id), Int(3))};
// gl_out[gl_InvocationID].gl_Position = gl_InvocationID == 3 ? pos3 :
// gl_in[index].gl_Position;
const Id pos3{interpolate(pos[0], pos[1], pos[2])};
const Id in_ptr{OpAccessChain(input_vec4, gl_in, index, Int(0))};
const Id position{OpSelect(vec4_id, invocation_3, pos3, OpLoad(vec4_id, in_ptr))};
OpStore(OpAccessChain(output_vec4, gl_out, invocation_id, Int(0)), position);
// Set attributes
for (int i = 0; i < inputs.size(); i++) {
// vec4 in_paramN3 = interpolate(bary_coord, in_paramN[0], in_paramN[1], in_paramN[2]);
const Id v0{OpLoad(vec4_id, OpAccessChain(input_vec4, inputs[i], Int(0)))};
const Id v1{OpLoad(vec4_id, OpAccessChain(input_vec4, inputs[i], Int(1)))};
const Id v2{OpLoad(vec4_id, OpAccessChain(input_vec4, inputs[i], Int(2)))};
const Id in_param3{interpolate(v0, v1, v2)};
// out_paramN[gl_InvocationID] = gl_InvocationID == 3 ? in_paramN3 : in_paramN[index];
const Id in_param{OpLoad(vec4_id, OpAccessChain(input_vec4, inputs[i], index))};
const Id out_param{OpSelect(vec4_id, invocation_3, in_param3, in_param)};
OpStore(OpAccessChain(output_vec4, outputs[i], invocation_id), out_param);
}
OpReturn();
OpFunctionEnd();
}
/// Emits a passthrough quad tessellation control shader that outputs 4 control points.
void EmitQuadListTCS() {
DefineEntry(spv::ExecutionModel::TessellationControl);
const Id array_type{TypeArray(int_id, Int(4))};
const Id values{ConstantComposite(array_type, Int(1), Int(2), Int(0), Int(3))};
const Id indices{AddLocalVariable(TypePointer(spv::StorageClass::Function, array_type),
spv::StorageClass::Function, values)};
// Set passthrough tessellation factors
const Id output_float{TypePointer(spv::StorageClass::Output, float_id)};
for (int i = 0; i < 4; i++) {
const Id ptr{OpAccessChain(output_float, gl_tess_level_outer, Int(i))};
OpStore(ptr, float_one);
}
for (int i = 0; i < 2; i++) {
const Id ptr{OpAccessChain(output_float, gl_tess_level_inner, Int(i))};
OpStore(ptr, float_one);
}
const Id input_vec4{TypePointer(spv::StorageClass::Input, vec4_id)};
const Id output_vec4{TypePointer(spv::StorageClass::Output, vec4_id)};
const Id func_int{TypePointer(spv::StorageClass::Function, int_id)};
const Id invocation_id{OpLoad(int_id, gl_invocation_id)};
const Id index{OpLoad(int_id, OpAccessChain(func_int, indices, invocation_id))};
// gl_out[gl_InvocationID].gl_Position = gl_in[gl_InvocationID].gl_Position;
const Id in_position{OpLoad(vec4_id, OpAccessChain(input_vec4, gl_in, index, Int(0)))};
OpStore(OpAccessChain(output_vec4, gl_out, invocation_id, Int(0)), in_position);
for (int i = 0; i < inputs.size(); i++) {
// out_paramN[gl_InvocationID] = in_paramN[gl_InvocationID];
const Id in_param{OpLoad(vec4_id, OpAccessChain(input_vec4, inputs[i], index))};
OpStore(OpAccessChain(output_vec4, outputs[i], invocation_id), in_param);
}
OpReturn();
OpFunctionEnd();
}
/// Emits a passthrough quad tessellation evaluation shader that outputs 4 control points.
void EmitPassthroughTES() {
DefineEntry(spv::ExecutionModel::TessellationEvaluation);
// const int index = int(gl_TessCoord.y) * 2 + int(gl_TessCoord.x);
const Id input_float{TypePointer(spv::StorageClass::Input, float_id)};
const Id tess_coord_x{OpLoad(float_id, OpAccessChain(input_float, gl_tess_coord, Int(0)))};
const Id tess_coord_y{OpLoad(float_id, OpAccessChain(input_float, gl_tess_coord, Int(1)))};
const Id index{OpIAdd(int_id, OpIMul(int_id, OpConvertFToS(int_id, tess_coord_y), Int(2)),
OpConvertFToS(int_id, tess_coord_x))};
// gl_Position = gl_in[index].gl_Position;
const Id input_vec4{TypePointer(spv::StorageClass::Input, vec4_id)};
const Id output_vec4{TypePointer(spv::StorageClass::Output, vec4_id)};
const Id position{OpLoad(vec4_id, OpAccessChain(input_vec4, gl_in, index, Int(0)))};
OpStore(OpAccessChain(output_vec4, gl_per_vertex, Int(0)), position);
// out_paramN = in_paramN[index];
for (int i = 0; i < inputs.size(); i++) {
const Id param{OpLoad(vec4_id, OpAccessChain(input_vec4, inputs[i], index))};
OpStore(outputs[i], param);
}
OpReturn();
OpFunctionEnd();
}
private:
Id Int(s32 value) {
return Constant(int_id, value);
}
Id AddInput(Id type) {
const Id input{AddGlobalVariable(TypePointer(spv::StorageClass::Input, type),
spv::StorageClass::Input)};
interfaces.push_back(input);
return input;
}
Id AddOutput(Id type) {
const Id output{AddGlobalVariable(TypePointer(spv::StorageClass::Output, type),
spv::StorageClass::Output)};
interfaces.push_back(output);
return output;
}
void DefineEntry(spv::ExecutionModel model) {
AddCapability(spv::Capability::Shader);
AddCapability(spv::Capability::Tessellation);
const Id void_function{TypeFunction(void_id)};
main = OpFunction(void_id, spv::FunctionControlMask::MaskNone, void_function);
if (model == spv::ExecutionModel::TessellationControl) {
AddExecutionMode(main, spv::ExecutionMode::OutputVertices, 4U);
} else {
AddExecutionMode(main, spv::ExecutionMode::Quads);
AddExecutionMode(main, spv::ExecutionMode::SpacingEqual);
AddExecutionMode(main, spv::ExecutionMode::VertexOrderCw);
}
DefineInputs(model);
DefineOutputs(model);
AddEntryPoint(model, main, "main", interfaces);
AddLabel(OpLabel());
}
void DefineOutputs(spv::ExecutionModel model) {
if (model == spv::ExecutionModel::TessellationControl) {
const Id gl_per_vertex_array{TypeArray(gl_per_vertex_type, Constant(uint_id, 4U))};
gl_out = AddOutput(gl_per_vertex_array);
const Id arr2_id{TypeArray(float_id, Constant(uint_id, 2U))};
gl_tess_level_inner = AddOutput(arr2_id);
Decorate(gl_tess_level_inner, spv::Decoration::BuiltIn, spv::BuiltIn::TessLevelInner);
Decorate(gl_tess_level_inner, spv::Decoration::Patch);
const Id arr4_id{TypeArray(float_id, Constant(uint_id, 4U))};
gl_tess_level_outer = AddOutput(arr4_id);
Decorate(gl_tess_level_outer, spv::Decoration::BuiltIn, spv::BuiltIn::TessLevelOuter);
Decorate(gl_tess_level_outer, spv::Decoration::Patch);
} else {
gl_per_vertex = AddOutput(gl_per_vertex_type);
}
for (int i = 0; i < fs_info.num_inputs; i++) {
outputs[i] = AddOutput(model == spv::ExecutionModel::TessellationControl
? TypeArray(vec4_id, Int(4))
: vec4_id);
Decorate(outputs[i], spv::Decoration::Location, fs_info.inputs[i].param_index);
}
}
void DefineInputs(spv::ExecutionModel model) {
if (model == spv::ExecutionModel::TessellationEvaluation) {
gl_tess_coord = AddInput(vec3_id);
Decorate(gl_tess_coord, spv::Decoration::BuiltIn, spv::BuiltIn::TessCoord);
} else {
gl_invocation_id = AddInput(int_id);
Decorate(gl_invocation_id, spv::Decoration::BuiltIn, spv::BuiltIn::InvocationId);
}
const Id gl_per_vertex_array{TypeArray(gl_per_vertex_type, Constant(uint_id, 32U))};
gl_in = AddInput(gl_per_vertex_array);
const Id float_arr{TypeArray(vec4_id, Int(32))};
for (int i = 0; i < fs_info.num_inputs; i++) {
inputs[i] = AddInput(float_arr);
Decorate(inputs[i], spv::Decoration::Location, fs_info.inputs[i].param_index);
}
}
private:
FragmentRuntimeInfo fs_info;
Id main;
Id void_id;
Id bool_id;
Id float_id;
Id uint_id;
Id int_id;
Id bvec2_id;
Id vec2_id;
Id vec3_id;
Id vec4_id;
Id float_one;
Id float_min_one;
Id int_zero;
Id gl_per_vertex_type;
Id gl_in;
union {
Id gl_out;
Id gl_per_vertex;
};
Id gl_tess_level_inner;
Id gl_tess_level_outer;
union {
Id gl_tess_coord;
Id gl_invocation_id;
};
std::vector<Id> inputs;
std::vector<Id> outputs;
std::vector<Id> interfaces;
};
std::vector<u32> EmitAuxilaryTessShader(AuxShaderType type, const FragmentRuntimeInfo& fs_info) {
QuadRectListEmitter ctx{fs_info};
switch (type) {
case AuxShaderType::RectListTCS:
ctx.EmitRectListTCS();
break;
case AuxShaderType::QuadListTCS:
ctx.EmitQuadListTCS();
break;
case AuxShaderType::PassthroughTES:
ctx.EmitPassthroughTES();
break;
}
return ctx.Assemble();
}
} // namespace Shader::Backend::SPIRV

View File

@ -0,0 +1,24 @@
// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
#pragma once
#include <vector>
#include "common/types.h"
namespace Shader {
struct FragmentRuntimeInfo;
}
namespace Shader::Backend::SPIRV {
enum class AuxShaderType : u32 {
RectListTCS,
QuadListTCS,
PassthroughTES,
};
[[nodiscard]] std::vector<u32> EmitAuxilaryTessShader(AuxShaderType type,
const FragmentRuntimeInfo& fs_info);
} // namespace Shader::Backend::SPIRV

View File

@ -772,7 +772,7 @@ Id ImageType(EmitContext& ctx, const ImageResource& desc, Id sampled_type) {
const auto image = desc.GetSharp(ctx.info); const auto image = desc.GetSharp(ctx.info);
const auto format = desc.is_atomic ? GetFormat(image) : spv::ImageFormat::Unknown; const auto format = desc.is_atomic ? GetFormat(image) : spv::ImageFormat::Unknown;
const auto type = image.GetBoundType(); const auto type = image.GetBoundType();
const u32 sampled = desc.is_storage ? 2 : 1; const u32 sampled = desc.IsStorage(image) ? 2 : 1;
switch (type) { switch (type) {
case AmdGpu::ImageType::Color1D: case AmdGpu::ImageType::Color1D:
return ctx.TypeImage(sampled_type, spv::Dim::Dim1D, false, false, false, sampled, format); return ctx.TypeImage(sampled_type, spv::Dim::Dim1D, false, false, false, sampled, format);
@ -800,6 +800,7 @@ void EmitContext::DefineImagesAndSamplers() {
const auto sharp = image_desc.GetSharp(info); const auto sharp = image_desc.GetSharp(info);
const auto nfmt = sharp.GetNumberFmt(); const auto nfmt = sharp.GetNumberFmt();
const bool is_integer = AmdGpu::IsInteger(nfmt); const bool is_integer = AmdGpu::IsInteger(nfmt);
const bool is_storage = image_desc.IsStorage(sharp);
const VectorIds& data_types = GetAttributeType(*this, nfmt); const VectorIds& data_types = GetAttributeType(*this, nfmt);
const Id sampled_type = data_types[1]; const Id sampled_type = data_types[1];
const Id image_type{ImageType(*this, image_desc, sampled_type)}; const Id image_type{ImageType(*this, image_desc, sampled_type)};
@ -811,11 +812,11 @@ void EmitContext::DefineImagesAndSamplers() {
images.push_back({ images.push_back({
.data_types = &data_types, .data_types = &data_types,
.id = id, .id = id,
.sampled_type = image_desc.is_storage ? sampled_type : TypeSampledImage(image_type), .sampled_type = is_storage ? sampled_type : TypeSampledImage(image_type),
.pointer_type = pointer_type, .pointer_type = pointer_type,
.image_type = image_type, .image_type = image_type,
.is_integer = is_integer, .is_integer = is_integer,
.is_storage = image_desc.is_storage, .is_storage = is_storage,
}); });
interfaces.push_back(id); interfaces.push_back(id);
} }

View File

@ -1,7 +1,9 @@
// 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 "shader_recompiler/frontend/translate/translate.h" #include "shader_recompiler/frontend/translate/translate.h"
#include "shader_recompiler/ir/reg.h" #include "shader_recompiler/ir/reg.h"
#include "shader_recompiler/profile.h"
#include "shader_recompiler/runtime_info.h" #include "shader_recompiler/runtime_info.h"
namespace Shader::Gcn { namespace Shader::Gcn {
@ -203,6 +205,7 @@ void Translator::DS_WRITE(int bit_size, bool is_signed, bool is_pair, bool strid
addr, ir.Imm32((u32(inst.control.ds.offset1) << 8u) + u32(inst.control.ds.offset0))); addr, ir.Imm32((u32(inst.control.ds.offset1) << 8u) + u32(inst.control.ds.offset0)));
ir.WriteShared(bit_size, ir.GetVectorReg(data0), addr0); ir.WriteShared(bit_size, ir.GetVectorReg(data0), addr0);
} }
emit_ds_read_barrier = true;
} }
void Translator::DS_SWIZZLE_B32(const GcnInst& inst) { void Translator::DS_SWIZZLE_B32(const GcnInst& inst) {
@ -219,6 +222,11 @@ void Translator::DS_SWIZZLE_B32(const GcnInst& inst) {
void Translator::DS_READ(int bit_size, bool is_signed, bool is_pair, bool stride64, void Translator::DS_READ(int bit_size, bool is_signed, bool is_pair, bool stride64,
const GcnInst& inst) { const GcnInst& inst) {
if (emit_ds_read_barrier && profile.needs_lds_barriers) {
ir.Barrier();
emit_ds_read_barrier = false;
}
const IR::U32 addr{ir.GetVectorReg(IR::VectorReg(inst.src[0].code))}; const IR::U32 addr{ir.GetVectorReg(IR::VectorReg(inst.src[0].code))};
IR::VectorReg dst_reg{inst.dst[0].code}; IR::VectorReg dst_reg{inst.dst[0].code};
if (is_pair) { if (is_pair) {

View File

@ -306,6 +306,7 @@ private:
const RuntimeInfo& runtime_info; const RuntimeInfo& runtime_info;
const Profile& profile; const Profile& profile;
bool opcode_missing = false; bool opcode_missing = false;
bool emit_ds_read_barrier = false;
}; };
void Translate(IR::Block* block, u32 block_base, std::span<const GcnInst> inst_list, Info& info, void Translate(IR::Block* block, u32 block_base, std::span<const GcnInst> inst_list, Info& info,

View File

@ -420,13 +420,13 @@ void Translator::IMAGE_LOAD(bool has_mip, const GcnInst& inst) {
IR::TextureInstInfo info{}; IR::TextureInstInfo info{};
info.has_lod.Assign(has_mip); info.has_lod.Assign(has_mip);
const IR::Value texel = ir.ImageFetch(handle, body, {}, {}, {}, info); const IR::Value texel = ir.ImageRead(handle, body, {}, {}, info);
for (u32 i = 0; i < 4; i++) { for (u32 i = 0; i < 4; i++) {
if (((mimg.dmask >> i) & 1) == 0) { if (((mimg.dmask >> i) & 1) == 0) {
continue; continue;
} }
IR::F32 value = IR::F32{ir.CompositeExtract(texel, i)}; IR::U32 value = IR::U32{ir.CompositeExtract(texel, i)};
ir.SetVectorReg(dest_reg++, value); ir.SetVectorReg(dest_reg++, value);
} }
} }
@ -454,7 +454,7 @@ void Translator::IMAGE_STORE(bool has_mip, const GcnInst& inst) {
comps.push_back(ir.GetVectorReg<IR::F32>(data_reg++)); comps.push_back(ir.GetVectorReg<IR::F32>(data_reg++));
} }
const IR::Value value = ir.CompositeConstruct(comps[0], comps[1], comps[2], comps[3]); const IR::Value value = ir.CompositeConstruct(comps[0], comps[1], comps[2], comps[3]);
ir.ImageWrite(handle, body, {}, value, info); ir.ImageWrite(handle, body, {}, {}, value, info);
} }
void Translator::IMAGE_GET_RESINFO(const GcnInst& inst) { void Translator::IMAGE_GET_RESINFO(const GcnInst& inst) {

View File

@ -49,11 +49,11 @@ struct BufferResource {
u8 instance_attrib{}; u8 instance_attrib{};
bool is_written{}; bool is_written{};
bool IsStorage(AmdGpu::Buffer buffer) const noexcept { [[nodiscard]] bool IsStorage(const AmdGpu::Buffer& buffer) const noexcept {
return buffer.GetSize() > MaxUboSize || is_written || is_gds_buffer; return buffer.GetSize() > MaxUboSize || is_written || is_gds_buffer;
} }
constexpr AmdGpu::Buffer GetSharp(const Info& info) const noexcept; [[nodiscard]] constexpr AmdGpu::Buffer GetSharp(const Info& info) const noexcept;
}; };
using BufferResourceList = boost::container::small_vector<BufferResource, 16>; using BufferResourceList = boost::container::small_vector<BufferResource, 16>;
@ -61,18 +61,24 @@ struct TextureBufferResource {
u32 sharp_idx; u32 sharp_idx;
bool is_written{}; bool is_written{};
constexpr AmdGpu::Buffer GetSharp(const Info& info) const noexcept; [[nodiscard]] constexpr AmdGpu::Buffer GetSharp(const Info& info) const noexcept;
}; };
using TextureBufferResourceList = boost::container::small_vector<TextureBufferResource, 16>; using TextureBufferResourceList = boost::container::small_vector<TextureBufferResource, 16>;
struct ImageResource { struct ImageResource {
u32 sharp_idx; u32 sharp_idx;
bool is_storage{};
bool is_depth{}; bool is_depth{};
bool is_atomic{}; bool is_atomic{};
bool is_array{}; bool is_array{};
bool is_read{};
bool is_written{};
constexpr AmdGpu::Image GetSharp(const Info& info) const noexcept; [[nodiscard]] bool IsStorage(const AmdGpu::Image& image) const noexcept {
// Need cube as storage when used with ImageRead.
return is_written || (is_read && image.GetBoundType() == AmdGpu::ImageType::Cube);
}
[[nodiscard]] constexpr AmdGpu::Image GetSharp(const Info& info) const noexcept;
}; };
using ImageResourceList = boost::container::small_vector<ImageResource, 16>; using ImageResourceList = boost::container::small_vector<ImageResource, 16>;

View File

@ -1630,11 +1630,6 @@ Value IREmitter::ImageGatherDref(const Value& handle, const Value& coords, const
return Inst(Opcode::ImageGatherDref, Flags{info}, handle, coords, offset, dref); return Inst(Opcode::ImageGatherDref, Flags{info}, handle, coords, offset, dref);
} }
Value IREmitter::ImageFetch(const Value& handle, const Value& coords, const U32& lod,
const Value& offset, const U32& multisampling, TextureInstInfo info) {
return Inst(Opcode::ImageFetch, Flags{info}, handle, coords, lod, offset, multisampling);
}
Value IREmitter::ImageQueryDimension(const Value& handle, const IR::U32& lod, Value IREmitter::ImageQueryDimension(const Value& handle, const IR::U32& lod,
const IR::U1& skip_mips) { const IR::U1& skip_mips) {
return Inst(Opcode::ImageQueryDimensions, handle, lod, skip_mips); return Inst(Opcode::ImageQueryDimensions, handle, lod, skip_mips);
@ -1657,13 +1652,13 @@ Value IREmitter::ImageGradient(const Value& handle, const Value& coords,
} }
Value IREmitter::ImageRead(const Value& handle, const Value& coords, const U32& lod, Value IREmitter::ImageRead(const Value& handle, const Value& coords, const U32& lod,
TextureInstInfo info) { const U32& multisampling, TextureInstInfo info) {
return Inst(Opcode::ImageRead, Flags{info}, handle, coords, lod); return Inst(Opcode::ImageRead, Flags{info}, handle, coords, lod, multisampling);
} }
void IREmitter::ImageWrite(const Value& handle, const Value& coords, const U32& lod, void IREmitter::ImageWrite(const Value& handle, const Value& coords, const U32& lod,
const Value& color, TextureInstInfo info) { const U32& multisampling, const Value& color, TextureInstInfo info) {
Inst(Opcode::ImageWrite, Flags{info}, handle, coords, lod, color); Inst(Opcode::ImageWrite, Flags{info}, handle, coords, lod, multisampling, color);
} }
// Debug print maps to SPIRV's NonSemantic DebugPrintf instruction // Debug print maps to SPIRV's NonSemantic DebugPrintf instruction

View File

@ -325,17 +325,14 @@ public:
TextureInstInfo info); TextureInstInfo info);
[[nodiscard]] Value ImageGatherDref(const Value& handle, const Value& coords, [[nodiscard]] Value ImageGatherDref(const Value& handle, const Value& coords,
const Value& offset, const F32& dref, TextureInstInfo info); const Value& offset, const F32& dref, TextureInstInfo info);
[[nodiscard]] Value ImageFetch(const Value& handle, const Value& coords, const U32& lod,
const Value& offset, const U32& multisampling,
TextureInstInfo info);
[[nodiscard]] Value ImageGradient(const Value& handle, const Value& coords, [[nodiscard]] Value ImageGradient(const Value& handle, const Value& coords,
const Value& derivatives_dx, const Value& derivatives_dy, const Value& derivatives_dx, const Value& derivatives_dy,
const Value& offset, const F32& lod_clamp, const Value& offset, const F32& lod_clamp,
TextureInstInfo info); TextureInstInfo info);
[[nodiscard]] Value ImageRead(const Value& handle, const Value& coords, const U32& lod, [[nodiscard]] Value ImageRead(const Value& handle, const Value& coords, const U32& lod,
TextureInstInfo info); const U32& multisampling, TextureInstInfo info);
void ImageWrite(const Value& handle, const Value& coords, const U32& lod, const Value& color, void ImageWrite(const Value& handle, const Value& coords, const U32& lod,
TextureInstInfo info); const U32& multisampling, const Value& color, TextureInstInfo info);
void EmitVertex(); void EmitVertex();
void EmitPrimitive(); void EmitPrimitive();

View File

@ -338,12 +338,11 @@ OPCODE(ImageSampleDrefImplicitLod, F32x4, Opaq
OPCODE(ImageSampleDrefExplicitLod, F32x4, Opaque, Opaque, F32, F32, Opaque, ) OPCODE(ImageSampleDrefExplicitLod, F32x4, Opaque, Opaque, F32, F32, Opaque, )
OPCODE(ImageGather, F32x4, Opaque, Opaque, Opaque, ) OPCODE(ImageGather, F32x4, Opaque, Opaque, Opaque, )
OPCODE(ImageGatherDref, F32x4, Opaque, Opaque, Opaque, F32, ) OPCODE(ImageGatherDref, F32x4, Opaque, Opaque, Opaque, F32, )
OPCODE(ImageFetch, F32x4, Opaque, Opaque, U32, Opaque, Opaque, )
OPCODE(ImageQueryDimensions, U32x4, Opaque, U32, U1, ) OPCODE(ImageQueryDimensions, U32x4, Opaque, U32, U1, )
OPCODE(ImageQueryLod, F32x4, Opaque, Opaque, ) OPCODE(ImageQueryLod, F32x4, Opaque, Opaque, )
OPCODE(ImageGradient, F32x4, Opaque, Opaque, Opaque, Opaque, Opaque, F32, ) OPCODE(ImageGradient, F32x4, Opaque, Opaque, Opaque, Opaque, Opaque, F32, )
OPCODE(ImageRead, U32x4, Opaque, Opaque, U32, ) OPCODE(ImageRead, U32x4, Opaque, Opaque, U32, U32, )
OPCODE(ImageWrite, Void, Opaque, Opaque, U32, U32x4, ) OPCODE(ImageWrite, Void, Opaque, Opaque, U32, U32, U32x4, )
// Image atomic operations // Image atomic operations
OPCODE(ImageAtomicIAdd32, U32, Opaque, Opaque, U32, ) OPCODE(ImageAtomicIAdd32, U32, Opaque, Opaque, U32, )

View File

@ -115,25 +115,16 @@ bool IsImageAtomicInstruction(const IR::Inst& inst) {
} }
} }
bool IsImageStorageInstruction(const IR::Inst& inst) {
switch (inst.GetOpcode()) {
case IR::Opcode::ImageWrite:
case IR::Opcode::ImageRead:
return true;
default:
return IsImageAtomicInstruction(inst);
}
}
bool IsImageInstruction(const IR::Inst& inst) { bool IsImageInstruction(const IR::Inst& inst) {
switch (inst.GetOpcode()) { switch (inst.GetOpcode()) {
case IR::Opcode::ImageFetch: case IR::Opcode::ImageRead:
case IR::Opcode::ImageWrite:
case IR::Opcode::ImageQueryDimensions: case IR::Opcode::ImageQueryDimensions:
case IR::Opcode::ImageQueryLod: case IR::Opcode::ImageQueryLod:
case IR::Opcode::ImageSampleRaw: case IR::Opcode::ImageSampleRaw:
return true; return true;
default: default:
return IsImageStorageInstruction(inst); return IsImageAtomicInstruction(inst);
} }
} }
@ -201,7 +192,8 @@ public:
return desc.sharp_idx == existing.sharp_idx; return desc.sharp_idx == existing.sharp_idx;
})}; })};
auto& image = image_resources[index]; auto& image = image_resources[index];
image.is_storage |= desc.is_storage; image.is_read |= desc.is_read;
image.is_written |= desc.is_written;
return index; return index;
} }
@ -429,9 +421,9 @@ void PatchTextureBufferInstruction(IR::Block& block, IR::Inst& inst, Info& info,
} }
IR::Value PatchCubeCoord(IR::IREmitter& ir, const IR::Value& s, const IR::Value& t, IR::Value PatchCubeCoord(IR::IREmitter& ir, const IR::Value& s, const IR::Value& t,
const IR::Value& z, bool is_storage, bool is_array) { const IR::Value& z, bool is_written, bool is_array) {
// When cubemap is written with imageStore it is treated like 2DArray. // When cubemap is written with imageStore it is treated like 2DArray.
if (is_storage) { if (is_written) {
return ir.CompositeConstruct(s, t, z); return ir.CompositeConstruct(s, t, z);
} }
@ -684,15 +676,16 @@ void PatchImageInstruction(IR::Block& block, IR::Inst& inst, Info& info, Descrip
image = AmdGpu::Image::Null(); image = AmdGpu::Image::Null();
} }
ASSERT(image.GetType() != AmdGpu::ImageType::Invalid); ASSERT(image.GetType() != AmdGpu::ImageType::Invalid);
const bool is_storage = IsImageStorageInstruction(inst); const bool is_read = inst.GetOpcode() == IR::Opcode::ImageRead;
const bool is_written = inst.GetOpcode() == IR::Opcode::ImageWrite;
// Patch image instruction if image is FMask. // Patch image instruction if image is FMask.
if (image.IsFmask()) { if (image.IsFmask()) {
ASSERT_MSG(!is_storage, "FMask storage instructions are not supported"); ASSERT_MSG(!is_written, "FMask storage instructions are not supported");
IR::IREmitter ir{block, IR::Block::InstructionList::s_iterator_to(inst)}; IR::IREmitter ir{block, IR::Block::InstructionList::s_iterator_to(inst)};
switch (inst.GetOpcode()) { switch (inst.GetOpcode()) {
case IR::Opcode::ImageFetch: case IR::Opcode::ImageRead:
case IR::Opcode::ImageSampleRaw: { case IR::Opcode::ImageSampleRaw: {
IR::F32 fmaskx = ir.BitCast<IR::F32>(ir.Imm32(0x76543210)); IR::F32 fmaskx = ir.BitCast<IR::F32>(ir.Imm32(0x76543210));
IR::F32 fmasky = ir.BitCast<IR::F32>(ir.Imm32(0xfedcba98)); IR::F32 fmasky = ir.BitCast<IR::F32>(ir.Imm32(0xfedcba98));
@ -721,10 +714,11 @@ void PatchImageInstruction(IR::Block& block, IR::Inst& inst, Info& info, Descrip
u32 image_binding = descriptors.Add(ImageResource{ u32 image_binding = descriptors.Add(ImageResource{
.sharp_idx = tsharp, .sharp_idx = tsharp,
.is_storage = is_storage,
.is_depth = bool(inst_info.is_depth), .is_depth = bool(inst_info.is_depth),
.is_atomic = IsImageAtomicInstruction(inst), .is_atomic = IsImageAtomicInstruction(inst),
.is_array = bool(inst_info.is_array), .is_array = bool(inst_info.is_array),
.is_read = is_read,
.is_written = is_written,
}); });
// Sample instructions must be resolved into a new instruction using address register data. // Sample instructions must be resolved into a new instruction using address register data.
@ -762,7 +756,7 @@ void PatchImageInstruction(IR::Block& block, IR::Inst& inst, Info& info, Descrip
case AmdGpu::ImageType::Color3D: // x, y, z, [lod] case AmdGpu::ImageType::Color3D: // x, y, z, [lod]
return {ir.CompositeConstruct(body->Arg(0), body->Arg(1), body->Arg(2)), body->Arg(3)}; return {ir.CompositeConstruct(body->Arg(0), body->Arg(1), body->Arg(2)), body->Arg(3)};
case AmdGpu::ImageType::Cube: // x, y, face, [lod] case AmdGpu::ImageType::Cube: // x, y, face, [lod]
return {PatchCubeCoord(ir, body->Arg(0), body->Arg(1), body->Arg(2), is_storage, return {PatchCubeCoord(ir, body->Arg(0), body->Arg(1), body->Arg(2), is_written,
inst_info.is_array), inst_info.is_array),
body->Arg(3)}; body->Arg(3)};
default: default:
@ -772,19 +766,20 @@ void PatchImageInstruction(IR::Block& block, IR::Inst& inst, Info& info, Descrip
inst.SetArg(1, coords); inst.SetArg(1, coords);
if (inst.GetOpcode() == IR::Opcode::ImageWrite) { if (inst.GetOpcode() == IR::Opcode::ImageWrite) {
inst.SetArg(3, SwizzleVector(ir, image, inst.Arg(3))); inst.SetArg(4, SwizzleVector(ir, image, inst.Arg(4)));
} }
if (inst_info.has_lod) { if (inst_info.has_lod) {
ASSERT(inst.GetOpcode() == IR::Opcode::ImageFetch || ASSERT(inst.GetOpcode() == IR::Opcode::ImageRead ||
inst.GetOpcode() == IR::Opcode::ImageRead ||
inst.GetOpcode() == IR::Opcode::ImageWrite); inst.GetOpcode() == IR::Opcode::ImageWrite);
ASSERT(image.GetType() != AmdGpu::ImageType::Color2DMsaa && ASSERT(image.GetType() != AmdGpu::ImageType::Color2DMsaa &&
image.GetType() != AmdGpu::ImageType::Color2DMsaaArray); image.GetType() != AmdGpu::ImageType::Color2DMsaaArray);
inst.SetArg(2, arg); inst.SetArg(2, arg);
} else if (image.GetType() == AmdGpu::ImageType::Color2DMsaa || } else if ((image.GetType() == AmdGpu::ImageType::Color2DMsaa ||
image.GetType() == AmdGpu::ImageType::Color2DMsaaArray) { image.GetType() == AmdGpu::ImageType::Color2DMsaaArray) &&
inst.SetArg(4, arg); (inst.GetOpcode() == IR::Opcode::ImageRead ||
inst.GetOpcode() == IR::Opcode::ImageWrite)) {
inst.SetArg(3, arg);
} }
} }

View File

@ -227,7 +227,7 @@ struct RuntimeInfo {
ComputeRuntimeInfo cs_info; ComputeRuntimeInfo cs_info;
}; };
RuntimeInfo(Stage stage_) { void Initialize(Stage stage_) {
memset(this, 0, sizeof(*this)); memset(this, 0, sizeof(*this));
stage = stage_; stage = stage_;
} }

View File

@ -39,10 +39,12 @@ struct TextureBufferSpecialization {
struct ImageSpecialization { struct ImageSpecialization {
AmdGpu::ImageType type = AmdGpu::ImageType::Color2D; AmdGpu::ImageType type = AmdGpu::ImageType::Color2D;
bool is_integer = false; bool is_integer = false;
bool is_storage = false;
u32 dst_select = 0; u32 dst_select = 0;
bool operator==(const ImageSpecialization& other) const { bool operator==(const ImageSpecialization& other) const {
return type == other.type && is_integer == other.is_integer && return type == other.type && is_integer == other.is_integer &&
is_storage == other.is_storage &&
(dst_select != 0 ? dst_select == other.dst_select : true); (dst_select != 0 ? dst_select == other.dst_select : true);
} }
}; };
@ -114,7 +116,8 @@ struct StageSpecialization {
[](auto& spec, const auto& desc, AmdGpu::Image sharp) { [](auto& spec, const auto& desc, AmdGpu::Image sharp) {
spec.type = sharp.GetBoundType(); spec.type = sharp.GetBoundType();
spec.is_integer = AmdGpu::IsInteger(sharp.GetNumberFmt()); spec.is_integer = AmdGpu::IsInteger(sharp.GetNumberFmt());
if (desc.is_storage) { spec.is_storage = desc.IsStorage(sharp);
if (spec.is_storage) {
spec.dst_select = sharp.DstSelect(); spec.dst_select = sharp.DstSelect();
} }
}); });

View File

@ -126,6 +126,7 @@ enum class TilingMode : u32 {
Display_MacroTiled = 0xAu, Display_MacroTiled = 0xAu,
Texture_MicroTiled = 0xDu, Texture_MicroTiled = 0xDu,
Texture_MacroTiled = 0xEu, Texture_MacroTiled = 0xEu,
Texture_Volume = 0x13u,
}; };
constexpr std::string_view NameOf(TilingMode type) { constexpr std::string_view NameOf(TilingMode type) {
@ -140,6 +141,8 @@ constexpr std::string_view NameOf(TilingMode type) {
return "Texture_MicroTiled"; return "Texture_MicroTiled";
case TilingMode::Texture_MacroTiled: case TilingMode::Texture_MacroTiled:
return "Texture_MacroTiled"; return "Texture_MacroTiled";
case TilingMode::Texture_Volume:
return "Texture_Volume";
default: default:
return "Unknown"; return "Unknown";
} }
@ -294,9 +297,6 @@ struct Image {
return tiling_index == 5 ? TilingMode::Texture_MicroTiled return tiling_index == 5 ? TilingMode::Texture_MicroTiled
: TilingMode::Depth_MacroTiled; : TilingMode::Depth_MacroTiled;
} }
if (tiling_index == 0x13) {
return TilingMode::Texture_MicroTiled;
}
return static_cast<TilingMode>(tiling_index); return static_cast<TilingMode>(tiling_index);
} }

View File

@ -238,32 +238,14 @@ u32 BufferCache::BindIndexBuffer(bool& is_indexed, u32 index_offset) {
// Emulate QuadList and Polygon primitive types with CPU made index buffer. // Emulate QuadList and Polygon primitive types with CPU made index buffer.
const auto& regs = liverpool->regs; const auto& regs = liverpool->regs;
if (!is_indexed) { if (!is_indexed) {
bool needs_index_buffer = false; if (regs.primitive_type != AmdGpu::PrimitiveType::Polygon) {
if (regs.primitive_type == AmdGpu::PrimitiveType::QuadList ||
regs.primitive_type == AmdGpu::PrimitiveType::Polygon) {
needs_index_buffer = true;
}
if (!needs_index_buffer) {
return regs.num_indices; return regs.num_indices;
} }
// Emit indices. // Emit indices.
const u32 index_size = 3 * regs.num_indices; const u32 index_size = 3 * regs.num_indices;
const auto [data, offset] = stream_buffer.Map(index_size); const auto [data, offset] = stream_buffer.Map(index_size);
switch (regs.primitive_type) {
case AmdGpu::PrimitiveType::QuadList:
Vulkan::LiverpoolToVK::EmitQuadToTriangleListIndices(data, regs.num_indices);
break;
case AmdGpu::PrimitiveType::Polygon:
Vulkan::LiverpoolToVK::EmitPolygonToTriangleListIndices(data, regs.num_indices); Vulkan::LiverpoolToVK::EmitPolygonToTriangleListIndices(data, regs.num_indices);
break;
default:
UNREACHABLE();
break;
}
stream_buffer.Commit(); stream_buffer.Commit();
// Bind index buffer. // Bind index buffer.
@ -282,31 +264,6 @@ u32 BufferCache::BindIndexBuffer(bool& is_indexed, u32 index_offset) {
VAddr index_address = regs.index_base_address.Address<VAddr>(); VAddr index_address = regs.index_base_address.Address<VAddr>();
index_address += index_offset * index_size; index_address += index_offset * index_size;
if (regs.primitive_type == AmdGpu::PrimitiveType::QuadList) {
// Convert indices.
const u32 new_index_size = regs.num_indices * index_size * 6 / 4;
const auto [data, offset] = stream_buffer.Map(new_index_size);
const auto index_ptr = reinterpret_cast<u8*>(index_address);
switch (index_type) {
case vk::IndexType::eUint16:
Vulkan::LiverpoolToVK::ConvertQuadToTriangleListIndices<u16>(data, index_ptr,
regs.num_indices);
break;
case vk::IndexType::eUint32:
Vulkan::LiverpoolToVK::ConvertQuadToTriangleListIndices<u32>(data, index_ptr,
regs.num_indices);
break;
default:
UNREACHABLE_MSG("Unsupported QuadList index type {}", vk::to_string(index_type));
break;
}
stream_buffer.Commit();
// Bind index buffer.
const auto cmdbuf = scheduler.CommandBuffer();
cmdbuf.bindIndexBuffer(stream_buffer.Handle(), offset, index_type);
return new_index_size / index_size;
}
if (regs.primitive_type == AmdGpu::PrimitiveType::Polygon) { if (regs.primitive_type == AmdGpu::PrimitiveType::Polygon) {
UNREACHABLE(); UNREACHABLE();
} }

View File

@ -7,6 +7,8 @@ set(SHADER_FILES
detile_m32x1.comp detile_m32x1.comp
detile_m32x2.comp detile_m32x2.comp
detile_m32x4.comp detile_m32x4.comp
detile_macro32x1.comp
detile_macro32x2.comp
fs_tri.vert fs_tri.vert
post_process.frag post_process.frag
) )

View File

@ -15,6 +15,7 @@ layout(std430, binding = 1) buffer output_buf {
layout(push_constant) uniform image_info { layout(push_constant) uniform image_info {
uint num_levels; uint num_levels;
uint pitch; uint pitch;
uint height;
uint sizes[14]; uint sizes[14];
} info; } info;

View File

@ -15,6 +15,7 @@ layout(std430, binding = 1) buffer output_buf {
layout(push_constant) uniform image_info { layout(push_constant) uniform image_info {
uint num_levels; uint num_levels;
uint pitch; uint pitch;
uint height;
uint sizes[14]; uint sizes[14];
} info; } info;

View File

@ -15,6 +15,7 @@ layout(std430, binding = 1) buffer output_buf {
layout(push_constant) uniform image_info { layout(push_constant) uniform image_info {
uint num_levels; uint num_levels;
uint pitch; uint pitch;
uint height;
uint sizes[14]; uint sizes[14];
} info; } info;

View File

@ -18,6 +18,7 @@ layout(std430, binding = 1) buffer output_buf {
layout(push_constant) uniform image_info { layout(push_constant) uniform image_info {
uint num_levels; uint num_levels;
uint pitch; uint pitch;
uint height;
uint sizes[14]; uint sizes[14];
} info; } info;

View File

@ -17,6 +17,7 @@ layout(std430, binding = 1) buffer output_buf {
layout(push_constant) uniform image_info { layout(push_constant) uniform image_info {
uint num_levels; uint num_levels;
uint pitch; uint pitch;
uint height;
uint sizes[14]; uint sizes[14];
} info; } info;

View File

@ -0,0 +1,90 @@
// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
#version 450
layout (local_size_x = 64, local_size_y = 1, local_size_z = 1) in;
layout(std430, binding = 0) buffer input_buf {
uint in_data[];
};
layout(std430, binding = 1) buffer output_buf {
uint out_data[];
};
layout(push_constant) uniform image_info {
uint num_levels;
uint pitch;
uint height;
uint c0;
uint c1;
} info;
// Each LUT is 64 bytes, so should fit into K$ given tiled slices locality
const uint lut_32bpp[][64] = {
{
0x00, 0x01, 0x04, 0x05, 0x40, 0x41, 0x44, 0x45,
0x02, 0x03, 0x06, 0x07, 0x42, 0x43, 0x46, 0x47,
0x10, 0x11, 0x14, 0x15, 0x50, 0x51, 0x54, 0x55,
0x12, 0x13, 0x16, 0x17, 0x52, 0x53, 0x56, 0x57,
0x80, 0x81, 0x84, 0x85, 0xc0, 0xc1, 0xc4, 0xc5,
0x82, 0x83, 0x86, 0x87, 0xc2, 0xc3, 0xc6, 0xc7,
0x90, 0x91, 0x94, 0x95, 0xd0, 0xd1, 0xd4, 0xd5,
0x92, 0x93, 0x96, 0x97, 0xd2, 0xd3, 0xd6, 0xd7,
},
{
0x08, 0x09, 0x0c, 0x0d, 0x48, 0x49, 0x4c, 0x4d,
0x0a, 0x0b, 0x0e, 0x0f, 0x4a, 0x4b, 0x4e, 0x4f,
0x18, 0x19, 0x1c, 0x1d, 0x58, 0x59, 0x5c, 0x5d,
0x1a, 0x1b, 0x1e, 0x1f, 0x5a, 0x5b, 0x5e, 0x5f,
0x88, 0x89, 0x8c, 0x8d, 0xc8, 0xc9, 0xcc, 0xcd,
0x8a, 0x8b, 0x8e, 0x8f, 0xca, 0xcb, 0xce, 0xcf,
0x98, 0x99, 0x9c, 0x9d, 0xd8, 0xd9, 0xdc, 0xdd,
0x9a, 0x9b, 0x9e, 0x9f, 0xda, 0xdb, 0xde, 0xdf,
},
{
0x20, 0x21, 0x24, 0x25, 0x60, 0x61, 0x64, 0x65,
0x22, 0x23, 0x26, 0x27, 0x62, 0x63, 0x66, 0x67,
0x30, 0x31, 0x34, 0x35, 0x70, 0x71, 0x74, 0x75,
0x32, 0x33, 0x36, 0x37, 0x72, 0x73, 0x76, 0x77,
0xa0, 0xa1, 0xa4, 0xa5, 0xe0, 0xe1, 0xe4, 0xe5,
0xa2, 0xa3, 0xa6, 0xa7, 0xe2, 0xe3, 0xe6, 0xe7,
0xb0, 0xb1, 0xb4, 0xb5, 0xf0, 0xf1, 0xf4, 0xf5,
0xb2, 0xb3, 0xb6, 0xb7, 0xf2, 0xf3, 0xf6, 0xf7,
},
{
0x28, 0x29, 0x2c, 0x2d, 0x68, 0x69, 0x6c, 0x6d,
0x2a, 0x2b, 0x2e, 0x2f, 0x6a, 0x6b, 0x6e, 0x6f,
0x38, 0x39, 0x3c, 0x3d, 0x78, 0x79, 0x7c, 0x7d,
0x3a, 0x3b, 0x3e, 0x3f, 0x7a, 0x7b, 0x7e, 0x7f,
0xa8, 0xa9, 0xac, 0xad, 0xe8, 0xe9, 0xec, 0xed,
0xaa, 0xab, 0xae, 0xaf, 0xea, 0xeb, 0xee, 0xef,
0xb8, 0xb9, 0xbc, 0xbd, 0xf8, 0xf9, 0xfc, 0xfd,
0xba, 0xbb, 0xbe, 0xbf, 0xfa, 0xfb, 0xfe, 0xff,
}
};
#define MICRO_TILE_DIM (8)
#define MICRO_TILE_SZ (1024)
#define TEXELS_PER_ELEMENT (1)
#define BPP (32)
void main() {
uint x = gl_GlobalInvocationID.x % info.pitch;
uint y = (gl_GlobalInvocationID.x / info.pitch) % info.height;
uint z = gl_GlobalInvocationID.x / (info.pitch * info.height);
uint col = bitfieldExtract(x, 0, 3);
uint row = bitfieldExtract(y, 0, 3);
uint lut = bitfieldExtract(z, 0, 2);
uint idx = lut_32bpp[lut][col + row * MICRO_TILE_DIM];
uint slice_offs = (z >> 2u) * info.c1 * MICRO_TILE_SZ;
uint tile_row = y / MICRO_TILE_DIM;
uint tile_column = x / MICRO_TILE_DIM;
uint tile_offs = ((tile_row * info.c0) + tile_column) * MICRO_TILE_SZ;
uint offs = slice_offs + tile_offs + (idx * BPP / 8);
uint p0 = in_data[offs >> 2u];
out_data[gl_GlobalInvocationID.x] = p0;
}

View File

@ -0,0 +1,91 @@
// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
#version 450
layout (local_size_x = 64, local_size_y = 1, local_size_z = 1) in;
layout(std430, binding = 0) buffer input_buf {
uint in_data[];
};
layout(std430, binding = 1) buffer output_buf {
uint out_data[];
};
layout(push_constant) uniform image_info {
uint num_levels;
uint pitch;
uint height;
uint c0;
uint c1;
} info;
const uint lut_64bpp[][64] = {
{
0x00, 0x01, 0x08, 0x09, 0x40, 0x41, 0x48, 0x49,
0x02, 0x03, 0x0a, 0x0b, 0x42, 0x43, 0x4a, 0x4b,
0x10, 0x11, 0x18, 0x19, 0x50, 0x51, 0x58, 0x59,
0x12, 0x13, 0x1a, 0x1b, 0x52, 0x53, 0x5a, 0x5b,
0x80, 0x81, 0x88, 0x89, 0xc0, 0xc1, 0xc8, 0xc9,
0x82, 0x83, 0x8a, 0x8b, 0xc2, 0xc3, 0xca, 0xcb,
0x90, 0x91, 0x98, 0x99, 0xd0, 0xd1, 0xd8, 0xd9,
0x92, 0x93, 0x9a, 0x9b, 0xd2, 0xd3, 0xda, 0xdb,
},
{
0x04, 0x05, 0x0c, 0x0d, 0x44, 0x45, 0x4c, 0x4d,
0x06, 0x07, 0x0e, 0x0f, 0x46, 0x47, 0x4e, 0x4f,
0x14, 0x15, 0x1c, 0x1d, 0x54, 0x55, 0x5c, 0x5d,
0x16, 0x17, 0x1e, 0x1f, 0x56, 0x57, 0x5e, 0x5f,
0x84, 0x85, 0x8c, 0x8d, 0xc4, 0xc5, 0xcc, 0xcd,
0x86, 0x87, 0x8e, 0x8f, 0xc6, 0xc7, 0xce, 0xcf,
0x94, 0x95, 0x9c, 0x9d, 0xd4, 0xd5, 0xdc, 0xdd,
0x96, 0x97, 0x9e, 0x9f, 0xd6, 0xd7, 0xde, 0xdf,
},
{
0x20, 0x21, 0x28, 0x29, 0x60, 0x61, 0x68, 0x69,
0x22, 0x23, 0x2a, 0x2b, 0x62, 0x63, 0x6a, 0x6b,
0x30, 0x31, 0x38, 0x39, 0x70, 0x71, 0x78, 0x79,
0x32, 0x33, 0x3a, 0x3b, 0x72, 0x73, 0x7a, 0x7b,
0xa0, 0xa1, 0xa8, 0xa9, 0xe0, 0xe1, 0xe8, 0xe9,
0xa2, 0xa3, 0xaa, 0xab, 0xe2, 0xe3, 0xea, 0xeb,
0xb0, 0xb1, 0xb8, 0xb9, 0xf0, 0xf1, 0xf8, 0xf9,
0xb2, 0xb3, 0xba, 0xbb, 0xf2, 0xf3, 0xfa, 0xfb,
},
{
0x24, 0x25, 0x2c, 0x2d, 0x64, 0x65, 0x6c, 0x6d,
0x26, 0x27, 0x2e, 0x2f, 0x66, 0x67, 0x6e, 0x6f,
0x34, 0x35, 0x3c, 0x3d, 0x74, 0x75, 0x7c, 0x7d,
0x36, 0x37, 0x3e, 0x3f, 0x76, 0x77, 0x7e, 0x7f,
0xa4, 0xa5, 0xac, 0xad, 0xe4, 0xe5, 0xec, 0xed,
0xa6, 0xa7, 0xae, 0xaf, 0xe6, 0xe7, 0xee, 0xef,
0xb4, 0xb5, 0xbc, 0xbd, 0xf4, 0xf5, 0xfc, 0xfd,
0xb6, 0xb7, 0xbe, 0xbf, 0xf6, 0xf7, 0xfe, 0xff,
},
};
#define MICRO_TILE_DIM (8)
#define MICRO_TILE_SZ (2048)
#define TEXELS_PER_ELEMENT (1)
#define BPP (64)
void main() {
uint x = gl_GlobalInvocationID.x % info.pitch;
uint y = (gl_GlobalInvocationID.x / info.pitch) % info.height;
uint z = gl_GlobalInvocationID.x / (info.pitch * info.height);
uint col = bitfieldExtract(x, 0, 3);
uint row = bitfieldExtract(y, 0, 3);
uint lut = bitfieldExtract(z, 0, 2);
uint idx = lut_64bpp[lut][col + row * MICRO_TILE_DIM];
uint slice_offs = (z >> 2u) * info.c1 * MICRO_TILE_SZ;
uint tile_row = y / MICRO_TILE_DIM;
uint tile_column = x / MICRO_TILE_DIM;
uint tile_offs = ((tile_row * info.c0) + tile_column) * MICRO_TILE_SZ;
uint offs = slice_offs + tile_offs + (idx * BPP / 8);
uint p0 = in_data[(offs >> 2) + 0];
uint p1 = in_data[(offs >> 2) + 1];
out_data[2 * gl_GlobalInvocationID.x + 0] = p0;
out_data[2 * gl_GlobalInvocationID.x + 1] = p1;
}

View File

@ -116,12 +116,12 @@ vk::PrimitiveTopology PrimitiveType(AmdGpu::PrimitiveType type) {
return vk::PrimitiveTopology::eTriangleStripWithAdjacency; return vk::PrimitiveTopology::eTriangleStripWithAdjacency;
case AmdGpu::PrimitiveType::PatchPrimitive: case AmdGpu::PrimitiveType::PatchPrimitive:
return vk::PrimitiveTopology::ePatchList; return vk::PrimitiveTopology::ePatchList;
case AmdGpu::PrimitiveType::QuadList:
case AmdGpu::PrimitiveType::Polygon: case AmdGpu::PrimitiveType::Polygon:
// Needs to generate index buffer on the fly. // Needs to generate index buffer on the fly.
return vk::PrimitiveTopology::eTriangleList; return vk::PrimitiveTopology::eTriangleList;
case AmdGpu::PrimitiveType::QuadList:
case AmdGpu::PrimitiveType::RectList: case AmdGpu::PrimitiveType::RectList:
return vk::PrimitiveTopology::eTriangleStrip; return vk::PrimitiveTopology::ePatchList;
default: default:
UNREACHABLE(); UNREACHABLE();
return vk::PrimitiveTopology::eTriangleList; return vk::PrimitiveTopology::eTriangleList;

View File

@ -70,34 +70,6 @@ vk::ClearValue ColorBufferClearValue(const AmdGpu::Liverpool::ColorBuffer& color
vk::SampleCountFlagBits NumSamples(u32 num_samples, vk::SampleCountFlags supported_flags); vk::SampleCountFlagBits NumSamples(u32 num_samples, vk::SampleCountFlags supported_flags);
static constexpr u16 NumVerticesPerQuad = 4;
inline void EmitQuadToTriangleListIndices(u8* out_ptr, u32 num_vertices) {
u16* out_data = reinterpret_cast<u16*>(out_ptr);
for (u16 i = 0; i < num_vertices; i += NumVerticesPerQuad) {
*out_data++ = i;
*out_data++ = i + 1;
*out_data++ = i + 2;
*out_data++ = i;
*out_data++ = i + 2;
*out_data++ = i + 3;
}
}
template <typename T>
void ConvertQuadToTriangleListIndices(u8* out_ptr, const u8* in_ptr, u32 num_vertices) {
T* out_data = reinterpret_cast<T*>(out_ptr);
const T* in_data = reinterpret_cast<const T*>(in_ptr);
for (u16 i = 0; i < num_vertices; i += NumVerticesPerQuad) {
*out_data++ = in_data[i];
*out_data++ = in_data[i + 1];
*out_data++ = in_data[i + 2];
*out_data++ = in_data[i];
*out_data++ = in_data[i + 2];
*out_data++ = in_data[i + 3];
}
}
inline void EmitPolygonToTriangleListIndices(u8* out_ptr, u32 num_vertices) { inline void EmitPolygonToTriangleListIndices(u8* out_ptr, u32 num_vertices) {
u16* out_data = reinterpret_cast<u16*>(out_ptr); u16* out_data = reinterpret_cast<u16*>(out_ptr);
for (u16 i = 1; i < num_vertices - 1; i++) { for (u16 i = 1; i < num_vertices - 1; i++) {

View File

@ -58,7 +58,8 @@ ComputePipeline::ComputePipeline(const Instance& instance_, Scheduler& scheduler
for (const auto& image : info->images) { for (const auto& image : info->images) {
bindings.push_back({ bindings.push_back({
.binding = binding++, .binding = binding++,
.descriptorType = image.is_storage ? vk::DescriptorType::eStorageImage .descriptorType = image.IsStorage(image.GetSharp(*info))
? vk::DescriptorType::eStorageImage
: vk::DescriptorType::eSampledImage, : vk::DescriptorType::eSampledImage,
.descriptorCount = 1, .descriptorCount = 1,
.stageFlags = vk::ShaderStageFlagBits::eCompute, .stageFlags = vk::ShaderStageFlagBits::eCompute,

View File

@ -7,23 +7,28 @@
#include <boost/container/static_vector.hpp> #include <boost/container/static_vector.hpp>
#include "common/assert.h" #include "common/assert.h"
#include "common/io_file.h"
#include "common/scope_exit.h" #include "common/scope_exit.h"
#include "shader_recompiler/backend/spirv/emit_spirv_quad_rect.h"
#include "shader_recompiler/frontend/fetch_shader.h"
#include "shader_recompiler/runtime_info.h" #include "shader_recompiler/runtime_info.h"
#include "video_core/amdgpu/resource.h" #include "video_core/amdgpu/resource.h"
#include "video_core/buffer_cache/buffer_cache.h" #include "video_core/buffer_cache/buffer_cache.h"
#include "video_core/renderer_vulkan/vk_graphics_pipeline.h" #include "video_core/renderer_vulkan/vk_graphics_pipeline.h"
#include "shader_recompiler/frontend/fetch_shader.h"
#include "video_core/renderer_vulkan/vk_instance.h" #include "video_core/renderer_vulkan/vk_instance.h"
#include "video_core/renderer_vulkan/vk_scheduler.h" #include "video_core/renderer_vulkan/vk_scheduler.h"
#include "video_core/renderer_vulkan/vk_shader_util.h"
#include "video_core/texture_cache/texture_cache.h" #include "video_core/texture_cache/texture_cache.h"
namespace Vulkan { namespace Vulkan {
GraphicsPipeline::GraphicsPipeline(const Instance& instance_, Scheduler& scheduler_, using Shader::Backend::SPIRV::AuxShaderType;
DescriptorHeap& desc_heap_, const GraphicsPipelineKey& key_,
vk::PipelineCache pipeline_cache, GraphicsPipeline::GraphicsPipeline(
const Instance& instance_, Scheduler& scheduler_, DescriptorHeap& desc_heap_,
const GraphicsPipelineKey& key_, vk::PipelineCache pipeline_cache,
std::span<const Shader::Info*, MaxShaderStages> infos, std::span<const Shader::Info*, MaxShaderStages> infos,
std::span<const Shader::RuntimeInfo, MaxShaderStages> runtime_infos,
std::optional<const Shader::Gcn::FetchShaderData> fetch_shader_, std::optional<const Shader::Gcn::FetchShaderData> fetch_shader_,
std::span<const vk::ShaderModule> modules) std::span<const vk::ShaderModule> modules)
: Pipeline{instance_, scheduler_, desc_heap_, pipeline_cache}, key{key_}, : Pipeline{instance_, scheduler_, desc_heap_, pipeline_cache}, key{key_},
@ -88,11 +93,6 @@ GraphicsPipeline::GraphicsPipeline(const Instance& instance_, Scheduler& schedul
.pVertexAttributeDescriptions = vertex_attributes.data(), .pVertexAttributeDescriptions = vertex_attributes.data(),
}; };
if (key.prim_type == AmdGpu::PrimitiveType::RectList && !IsEmbeddedVs()) {
LOG_WARNING(Render_Vulkan,
"Rectangle List primitive type is only supported for embedded VS");
}
auto prim_restart = key.enable_primitive_restart != 0; auto prim_restart = key.enable_primitive_restart != 0;
if (prim_restart && IsPrimitiveListTopology() && !instance.IsListRestartSupported()) { if (prim_restart && IsPrimitiveListTopology() && !instance.IsListRestartSupported()) {
LOG_WARNING(Render_Vulkan, LOG_WARNING(Render_Vulkan,
@ -106,9 +106,11 @@ GraphicsPipeline::GraphicsPipeline(const Instance& instance_, Scheduler& schedul
ASSERT_MSG(!prim_restart || key.primitive_restart_index == 0xFFFF || ASSERT_MSG(!prim_restart || key.primitive_restart_index == 0xFFFF ||
key.primitive_restart_index == 0xFFFFFFFF, key.primitive_restart_index == 0xFFFFFFFF,
"Primitive restart index other than -1 is not supported yet"); "Primitive restart index other than -1 is not supported yet");
const bool is_rect_list = key.prim_type == AmdGpu::PrimitiveType::RectList;
const bool is_quad_list = key.prim_type == AmdGpu::PrimitiveType::QuadList;
const auto& fs_info = runtime_infos[u32(Shader::LogicalStage::Fragment)].fs_info;
const vk::PipelineTessellationStateCreateInfo tessellation_state = { const vk::PipelineTessellationStateCreateInfo tessellation_state = {
.patchControlPoints = key.patch_control_points, .patchControlPoints = is_rect_list ? 3U : (is_quad_list ? 4U : key.patch_control_points),
}; };
const vk::PipelineRasterizationStateCreateInfo raster_state = { const vk::PipelineRasterizationStateCreateInfo raster_state = {
@ -121,7 +123,7 @@ GraphicsPipeline::GraphicsPipeline(const Instance& instance_, Scheduler& schedul
.frontFace = key.front_face == Liverpool::FrontFace::Clockwise .frontFace = key.front_face == Liverpool::FrontFace::Clockwise
? vk::FrontFace::eClockwise ? vk::FrontFace::eClockwise
: vk::FrontFace::eCounterClockwise, : vk::FrontFace::eCounterClockwise,
.depthBiasEnable = bool(key.depth_bias_enable), .depthBiasEnable = key.depth_bias_enable,
.lineWidth = 1.0f, .lineWidth = 1.0f,
}; };
@ -131,37 +133,24 @@ GraphicsPipeline::GraphicsPipeline(const Instance& instance_, Scheduler& schedul
.sampleShadingEnable = false, .sampleShadingEnable = false,
}; };
const vk::Viewport viewport = {
.x = 0.0f,
.y = 0.0f,
.width = 1.0f,
.height = 1.0f,
.minDepth = 0.0f,
.maxDepth = 1.0f,
};
const vk::Rect2D scissor = {
.offset = {0, 0},
.extent = {1, 1},
};
const vk::PipelineViewportDepthClipControlCreateInfoEXT clip_control = { const vk::PipelineViewportDepthClipControlCreateInfoEXT clip_control = {
.negativeOneToOne = key.clip_space == Liverpool::ClipSpace::MinusWToW, .negativeOneToOne = key.clip_space == Liverpool::ClipSpace::MinusWToW,
}; };
const vk::PipelineViewportStateCreateInfo viewport_info = { const vk::PipelineViewportStateCreateInfo viewport_info = {
.pNext = instance.IsDepthClipControlSupported() ? &clip_control : nullptr, .pNext = instance.IsDepthClipControlSupported() ? &clip_control : nullptr,
.viewportCount = 1,
.pViewports = &viewport,
.scissorCount = 1,
.pScissors = &scissor,
}; };
boost::container::static_vector<vk::DynamicState, 14> dynamic_states = { boost::container::static_vector<vk::DynamicState, 14> dynamic_states = {
vk::DynamicState::eViewport, vk::DynamicState::eScissor, vk::DynamicState::eViewportWithCountEXT,
vk::DynamicState::eBlendConstants, vk::DynamicState::eDepthBounds, vk::DynamicState::eScissorWithCountEXT,
vk::DynamicState::eDepthBias, vk::DynamicState::eStencilReference, vk::DynamicState::eBlendConstants,
vk::DynamicState::eStencilCompareMask, vk::DynamicState::eStencilWriteMask, vk::DynamicState::eDepthBounds,
vk::DynamicState::eDepthBias,
vk::DynamicState::eStencilReference,
vk::DynamicState::eStencilCompareMask,
vk::DynamicState::eStencilWriteMask,
vk::DynamicState::eStencilOpEXT,
}; };
if (instance.IsColorWriteEnableSupported()) { if (instance.IsColorWriteEnableSupported()) {
@ -180,31 +169,11 @@ GraphicsPipeline::GraphicsPipeline(const Instance& instance_, Scheduler& schedul
}; };
const vk::PipelineDepthStencilStateCreateInfo depth_info = { const vk::PipelineDepthStencilStateCreateInfo depth_info = {
.depthTestEnable = key.depth_stencil.depth_enable, .depthTestEnable = key.depth_test_enable,
.depthWriteEnable = key.depth_stencil.depth_write_enable, .depthWriteEnable = key.depth_write_enable,
.depthCompareOp = LiverpoolToVK::CompareOp(key.depth_stencil.depth_func), .depthCompareOp = key.depth_compare_op,
.depthBoundsTestEnable = key.depth_stencil.depth_bounds_enable, .depthBoundsTestEnable = key.depth_bounds_test_enable,
.stencilTestEnable = key.depth_stencil.stencil_enable, .stencilTestEnable = key.stencil_test_enable,
.front{
.failOp = LiverpoolToVK::StencilOp(key.stencil.stencil_fail_front),
.passOp = LiverpoolToVK::StencilOp(key.stencil.stencil_zpass_front),
.depthFailOp = LiverpoolToVK::StencilOp(key.stencil.stencil_zfail_front),
.compareOp = LiverpoolToVK::CompareOp(key.depth_stencil.stencil_ref_func),
},
.back{
.failOp = LiverpoolToVK::StencilOp(key.depth_stencil.backface_enable
? key.stencil.stencil_fail_back.Value()
: key.stencil.stencil_fail_front.Value()),
.passOp = LiverpoolToVK::StencilOp(key.depth_stencil.backface_enable
? key.stencil.stencil_zpass_back.Value()
: key.stencil.stencil_zpass_front.Value()),
.depthFailOp = LiverpoolToVK::StencilOp(key.depth_stencil.backface_enable
? key.stencil.stencil_zfail_back.Value()
: key.stencil.stencil_zfail_front.Value()),
.compareOp = LiverpoolToVK::CompareOp(key.depth_stencil.backface_enable
? key.depth_stencil.stencil_bf_func.Value()
: key.depth_stencil.stencil_ref_func.Value()),
},
}; };
boost::container::static_vector<vk::PipelineShaderStageCreateInfo, MaxShaderStages> boost::container::static_vector<vk::PipelineShaderStageCreateInfo, MaxShaderStages>
@ -232,6 +201,14 @@ GraphicsPipeline::GraphicsPipeline(const Instance& instance_, Scheduler& schedul
.module = modules[stage], .module = modules[stage],
.pName = "main", .pName = "main",
}); });
} else if (is_rect_list || is_quad_list) {
const auto type = is_quad_list ? AuxShaderType::QuadListTCS : AuxShaderType::RectListTCS;
auto tcs = Shader::Backend::SPIRV::EmitAuxilaryTessShader(type, fs_info);
shader_stages.emplace_back(vk::PipelineShaderStageCreateInfo{
.stage = vk::ShaderStageFlagBits::eTessellationControl,
.module = CompileSPV(tcs, instance.GetDevice()),
.pName = "main",
});
} }
stage = u32(Shader::LogicalStage::TessellationEval); stage = u32(Shader::LogicalStage::TessellationEval);
if (infos[stage]) { if (infos[stage]) {
@ -240,6 +217,14 @@ GraphicsPipeline::GraphicsPipeline(const Instance& instance_, Scheduler& schedul
.module = modules[stage], .module = modules[stage],
.pName = "main", .pName = "main",
}); });
} else if (is_rect_list || is_quad_list) {
auto tes =
Shader::Backend::SPIRV::EmitAuxilaryTessShader(AuxShaderType::PassthroughTES, fs_info);
shader_stages.emplace_back(vk::PipelineShaderStageCreateInfo{
.stage = vk::ShaderStageFlagBits::eTessellationEvaluation,
.module = CompileSPV(tes, instance.GetDevice()),
.pName = "main",
});
} }
stage = u32(Shader::LogicalStage::Fragment); stage = u32(Shader::LogicalStage::Fragment);
if (infos[stage]) { if (infos[stage]) {
@ -322,8 +307,7 @@ GraphicsPipeline::GraphicsPipeline(const Instance& instance_, Scheduler& schedul
.pStages = shader_stages.data(), .pStages = shader_stages.data(),
.pVertexInputState = !instance.IsVertexInputDynamicState() ? &vertex_input_info : nullptr, .pVertexInputState = !instance.IsVertexInputDynamicState() ? &vertex_input_info : nullptr,
.pInputAssemblyState = &input_assembly, .pInputAssemblyState = &input_assembly,
.pTessellationState = .pTessellationState = &tessellation_state,
stages[u32(Shader::LogicalStage::TessellationControl)] ? &tessellation_state : nullptr,
.pViewportState = &viewport_info, .pViewportState = &viewport_info,
.pRasterizationState = &raster_state, .pRasterizationState = &raster_state,
.pMultisampleState = &multisampling, .pMultisampleState = &multisampling,
@ -380,7 +364,8 @@ void GraphicsPipeline::BuildDescSetLayout() {
for (const auto& image : stage->images) { for (const auto& image : stage->images) {
bindings.push_back({ bindings.push_back({
.binding = binding++, .binding = binding++,
.descriptorType = image.is_storage ? vk::DescriptorType::eStorageImage .descriptorType = image.IsStorage(image.GetSharp(*stage))
? vk::DescriptorType::eStorageImage
: vk::DescriptorType::eSampledImage, : vk::DescriptorType::eSampledImage,
.descriptorCount = 1, .descriptorCount = 1,
.stageFlags = gp_stage_flags, .stageFlags = gp_stage_flags,

View File

@ -18,7 +18,7 @@ class TextureCache;
namespace Vulkan { namespace Vulkan {
static constexpr u32 MaxShaderStages = 5; static constexpr u32 MaxShaderStages = static_cast<u32>(Shader::LogicalStage::NumLogicalStages);
static constexpr u32 MaxVertexBufferCount = 32; static constexpr u32 MaxVertexBufferCount = 32;
class Instance; class Instance;
@ -36,11 +36,19 @@ struct GraphicsPipelineKey {
vk::Format depth_format; vk::Format depth_format;
vk::Format stencil_format; vk::Format stencil_format;
Liverpool::DepthControl depth_stencil; struct {
u32 depth_bias_enable; bool depth_test_enable : 1;
bool depth_write_enable : 1;
bool depth_bounds_test_enable : 1;
bool depth_bias_enable : 1;
bool stencil_test_enable : 1;
// Must be named to be zero-initialized.
u8 _unused : 3;
};
vk::CompareOp depth_compare_op;
u32 num_samples; u32 num_samples;
u32 mrt_mask; u32 mrt_mask;
Liverpool::StencilControl stencil;
AmdGpu::PrimitiveType prim_type; AmdGpu::PrimitiveType prim_type;
u32 enable_primitive_restart; u32 enable_primitive_restart;
u32 primitive_restart_index; u32 primitive_restart_index;
@ -64,6 +72,7 @@ public:
GraphicsPipeline(const Instance& instance, Scheduler& scheduler, DescriptorHeap& desc_heap, GraphicsPipeline(const Instance& instance, Scheduler& scheduler, DescriptorHeap& desc_heap,
const GraphicsPipelineKey& key, vk::PipelineCache pipeline_cache, const GraphicsPipelineKey& key, vk::PipelineCache pipeline_cache,
std::span<const Shader::Info*, MaxShaderStages> stages, std::span<const Shader::Info*, MaxShaderStages> stages,
std::span<const Shader::RuntimeInfo, MaxShaderStages> runtime_infos,
std::optional<const Shader::Gcn::FetchShaderData> fetch_shader, std::optional<const Shader::Gcn::FetchShaderData> fetch_shader,
std::span<const vk::ShaderModule> modules); std::span<const vk::ShaderModule> modules);
~GraphicsPipeline(); ~GraphicsPipeline();
@ -72,11 +81,6 @@ public:
return fetch_shader; return fetch_shader;
} }
bool IsEmbeddedVs() const noexcept {
static constexpr size_t EmbeddedVsHash = 0x9b2da5cf47f8c29f;
return key.stage_hashes[u32(Shader::LogicalStage::Vertex)] == EmbeddedVsHash;
}
auto GetWriteMasks() const { auto GetWriteMasks() const {
return key.write_masks; return key.write_masks;
} }

Some files were not shown because too many files have changed in this diff Show More