mirror of
https://github.com/shadps4-emu/shadPS4.git
synced 2025-08-04 08:22:32 +00:00
Merge remote-tracking branch 'upstream/main'
This commit is contained in:
commit
d0238e18db
@ -47,9 +47,15 @@ else()
|
||||
message(FATAL_ERROR "Unsupported CPU architecture: ${BASE_ARCHITECTURE}")
|
||||
endif()
|
||||
|
||||
if (APPLE AND ARCHITECTURE STREQUAL "x86_64")
|
||||
if (APPLE AND ARCHITECTURE STREQUAL "x86_64" AND CMAKE_SYSTEM_PROCESSOR STREQUAL "arm64")
|
||||
# Exclude ARM homebrew path to avoid conflicts when cross compiling.
|
||||
list(APPEND CMAKE_IGNORE_PREFIX_PATH "/opt/homebrew")
|
||||
|
||||
# Need to reconfigure pkg-config to use the right architecture library paths.
|
||||
# It's not ideal to override these but otherwise the build breaks just by having pkg-config installed.
|
||||
set(ENV{PKG_CONFIG_DIR} "")
|
||||
set(ENV{PKG_CONFIG_LIBDIR} "${CMAKE_SYSROOT}/usr/lib/pkgconfig:${CMAKE_SYSROOT}/usr/share/pkgconfig:${CMAKE_SYSROOT}/usr/local/lib/pkgconfig:${CMAKE_SYSROOT}/usr/local/share/pkgconfig")
|
||||
set(ENV{PKG_CONFIG_SYSROOT_DIR} ${CMAKE_SYSROOT})
|
||||
endif()
|
||||
|
||||
# This function should be passed a list of all files in a target. It will automatically generate file groups
|
||||
@ -103,6 +109,7 @@ find_package(Boost 1.84.0 CONFIG)
|
||||
find_package(FFmpeg 5.1.2 MODULE)
|
||||
find_package(fmt 10.2.0 CONFIG)
|
||||
find_package(glslang 14.2.0 CONFIG)
|
||||
find_package(half 1.12.0 MODULE)
|
||||
find_package(magic_enum 0.9.6 CONFIG)
|
||||
find_package(RenderDoc 1.6.0 MODULE)
|
||||
find_package(SDL3 3.1.2 CONFIG)
|
||||
@ -432,6 +439,8 @@ set(COMMON src/common/logging/backend.cpp
|
||||
src/common/version.h
|
||||
src/common/ntapi.h
|
||||
src/common/ntapi.cpp
|
||||
src/common/number_utils.h
|
||||
src/common/number_utils.cpp
|
||||
src/common/memory_patcher.h
|
||||
src/common/memory_patcher.cpp
|
||||
src/common/scm_rev.cpp
|
||||
@ -771,7 +780,7 @@ endif()
|
||||
|
||||
create_target_directory_groups(shadps4)
|
||||
|
||||
target_link_libraries(shadps4 PRIVATE magic_enum::magic_enum fmt::fmt toml11::toml11 tsl::robin_map xbyak::xbyak Tracy::TracyClient RenderDoc::API FFmpeg::ffmpeg Dear_ImGui gcn)
|
||||
target_link_libraries(shadps4 PRIVATE magic_enum::magic_enum fmt::fmt toml11::toml11 tsl::robin_map xbyak::xbyak Tracy::TracyClient RenderDoc::API FFmpeg::ffmpeg Dear_ImGui gcn half::half)
|
||||
target_link_libraries(shadps4 PRIVATE Boost::headers GPUOpen::VulkanMemoryAllocator sirit Vulkan::Headers xxHash::xxhash Zydis::Zydis glslang::SPIRV glslang::glslang SDL3::SDL3 pugixml::pugixml)
|
||||
|
||||
target_compile_definitions(shadps4 PRIVATE IMGUI_USER_CONFIG="imgui/imgui_config.h")
|
||||
@ -794,9 +803,6 @@ if (APPLE)
|
||||
|
||||
# Replacement for std::chrono::time_zone
|
||||
target_link_libraries(shadps4 PRIVATE date::date-tz)
|
||||
|
||||
# Half float conversions for F16C patches
|
||||
target_link_libraries(shadps4 PRIVATE half)
|
||||
endif()
|
||||
|
||||
if (NOT ENABLE_QT_GUI)
|
||||
|
28
cmake/Findhalf.cmake
Normal file
28
cmake/Findhalf.cmake
Normal file
@ -0,0 +1,28 @@
|
||||
# SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project
|
||||
# SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
find_path(half_INCLUDE_DIR NAMES half.hpp PATH_SUFFIXES half)
|
||||
|
||||
if (half_INCLUDE_DIR)
|
||||
file(STRINGS "${half_INCLUDE_DIR}/half.hpp" _ver_line
|
||||
REGEX "^// Version [0-9.]+$"
|
||||
LIMIT_COUNT 1
|
||||
)
|
||||
string(REGEX MATCH "[0-9.]+" half_VERSION "${_ver_line}")
|
||||
unset(_ver_line)
|
||||
endif()
|
||||
|
||||
include(FindPackageHandleStandardArgs)
|
||||
find_package_handle_standard_args(half
|
||||
REQUIRED_VARS half_INCLUDE_DIR
|
||||
VERSION_VAR half_VERSION
|
||||
)
|
||||
|
||||
if (half_FOUND AND NOT TARGET half::half)
|
||||
add_library(half::half INTERFACE IMPORTED)
|
||||
set_target_properties(half::half PROPERTIES
|
||||
INTERFACE_INCLUDE_DIRECTORIES "${half_INCLUDE_DIR}"
|
||||
)
|
||||
endif()
|
||||
|
||||
mark_as_advanced(half_INCLUDE_DIR)
|
7
externals/CMakeLists.txt
vendored
7
externals/CMakeLists.txt
vendored
@ -141,11 +141,14 @@ if (WIN32)
|
||||
target_compile_options(sirit PUBLIC "-Wno-error=unused-command-line-argument")
|
||||
endif()
|
||||
|
||||
if (APPLE)
|
||||
# half
|
||||
# half
|
||||
if (NOT TARGET half::half)
|
||||
add_library(half INTERFACE)
|
||||
target_include_directories(half INTERFACE half/include)
|
||||
add_library(half::half ALIAS half)
|
||||
endif()
|
||||
|
||||
if (APPLE)
|
||||
# date
|
||||
if (NOT TARGET date::date-tz)
|
||||
option(BUILD_TZ_LIB "" ON)
|
||||
|
@ -81,7 +81,9 @@
|
||||
#pragma pack(1)
|
||||
template <std::size_t Position, std::size_t Bits, typename T>
|
||||
struct BitField {
|
||||
private:
|
||||
|
||||
using Type = T;
|
||||
|
||||
// UnderlyingType is T for non-enum types and the underlying type of T if
|
||||
// T is an enumeration. Note that T is wrapped within an enable_if in the
|
||||
// former case to workaround compile errors which arise when using
|
||||
@ -92,7 +94,6 @@ private:
|
||||
// We store the value as the unsigned type to avoid undefined behaviour on value shifting
|
||||
using StorageType = std::make_unsigned_t<UnderlyingType>;
|
||||
|
||||
public:
|
||||
/// Constants to allow limited introspection of fields if needed
|
||||
static constexpr std::size_t position = Position;
|
||||
static constexpr std::size_t bits = Bits;
|
||||
|
161
src/common/number_utils.cpp
Normal file
161
src/common/number_utils.cpp
Normal file
@ -0,0 +1,161 @@
|
||||
// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
#include <array>
|
||||
#include <half.hpp>
|
||||
|
||||
#include "common/number_utils.h"
|
||||
#include "video_core/amdgpu/pixel_format.h"
|
||||
#include "video_core/amdgpu/types.h"
|
||||
|
||||
#define UF11_EXPONENT_SHIFT 6
|
||||
#define UF10_EXPONENT_SHIFT 5
|
||||
|
||||
#define RGB9E5_MANTISSA_BITS 9
|
||||
#define RGB9E5_EXP_BIAS 1
|
||||
|
||||
#define F32_INFINITY 0x7f800000
|
||||
|
||||
namespace NumberUtils {
|
||||
|
||||
float Uf11ToF32(u16 val) {
|
||||
union {
|
||||
float f;
|
||||
u32 ui;
|
||||
} f32;
|
||||
|
||||
int exponent = (val & 0x07c0) >> UF11_EXPONENT_SHIFT;
|
||||
int mantissa = (val & 0x003f);
|
||||
|
||||
f32.f = 0.0;
|
||||
|
||||
if (exponent == 0) {
|
||||
if (mantissa != 0) {
|
||||
const float scale = 1.0 / (1 << 20);
|
||||
f32.f = scale * mantissa;
|
||||
}
|
||||
} else if (exponent == 31) {
|
||||
f32.ui = F32_INFINITY | mantissa;
|
||||
} else {
|
||||
float scale, decimal;
|
||||
exponent -= 15;
|
||||
if (exponent < 0) {
|
||||
scale = 1.0f / (1 << -exponent);
|
||||
} else {
|
||||
scale = (float)(1 << exponent);
|
||||
}
|
||||
decimal = 1.0f + (float)mantissa / 64;
|
||||
f32.f = scale * decimal;
|
||||
}
|
||||
|
||||
return f32.f;
|
||||
}
|
||||
|
||||
float Uf10ToF32(u16 val) {
|
||||
union {
|
||||
float f;
|
||||
u32 ui;
|
||||
} f32;
|
||||
|
||||
int exponent = (val & 0x03e0) >> UF10_EXPONENT_SHIFT;
|
||||
int mantissa = (val & 0x001f);
|
||||
|
||||
f32.f = 0.0;
|
||||
|
||||
if (exponent == 0) {
|
||||
if (mantissa != 0) {
|
||||
const float scale = 1.0 / (1 << 19);
|
||||
f32.f = scale * mantissa;
|
||||
}
|
||||
} else if (exponent == 31) {
|
||||
f32.ui = F32_INFINITY | mantissa;
|
||||
} else {
|
||||
float scale, decimal;
|
||||
exponent -= 15;
|
||||
if (exponent < 0) {
|
||||
scale = 1.0f / (1 << -exponent);
|
||||
} else {
|
||||
scale = (float)(1 << exponent);
|
||||
}
|
||||
decimal = 1.0f + (float)mantissa / 32;
|
||||
f32.f = scale * decimal;
|
||||
}
|
||||
|
||||
return f32.f;
|
||||
}
|
||||
|
||||
float Uf16ToF32(u16 val) {
|
||||
return half_float::half_cast<float>(reinterpret_cast<half_float::half&>(val));
|
||||
}
|
||||
|
||||
float U2ToUnorm(u8 val) {
|
||||
static constexpr auto c = 1.0f / 3.0f;
|
||||
return float(val * c);
|
||||
}
|
||||
|
||||
float S2ToSnorm(s8 val) {
|
||||
static constexpr auto c = 1.0f / 1.0f;
|
||||
return float(val * c);
|
||||
}
|
||||
|
||||
float U4ToUnorm(u8 val) {
|
||||
static constexpr auto c = 1.0f / 15.0f;
|
||||
return float(val * c);
|
||||
}
|
||||
|
||||
float S4ToSnorm(s8 val) {
|
||||
static constexpr auto c = 1.0f / 7.0f;
|
||||
return float(val * c);
|
||||
}
|
||||
|
||||
float U5ToUnorm(u8 val) {
|
||||
static constexpr auto c = 1.0f / 31.0f;
|
||||
return float(val * c);
|
||||
}
|
||||
|
||||
float S5ToSnorm(s8 val) {
|
||||
static constexpr auto c = 1.0f / 15.0f;
|
||||
return float(val * c);
|
||||
}
|
||||
|
||||
float U6ToUnorm(u8 val) {
|
||||
static constexpr auto c = 1.0f / 63.0f;
|
||||
return float(val * c);
|
||||
}
|
||||
|
||||
float S6ToSnorm(s8 val) {
|
||||
static constexpr auto c = 1.0f / 31.0f;
|
||||
return float(val * c);
|
||||
}
|
||||
|
||||
float U8ToUnorm(u8 val) {
|
||||
static constexpr auto c = 1.0f / 255.0f;
|
||||
return float(val * c);
|
||||
}
|
||||
|
||||
float S8ToSnorm(s8 val) {
|
||||
static constexpr auto c = 1.0f / 127.0f;
|
||||
return float(val * c);
|
||||
}
|
||||
|
||||
float U10ToUnorm(u16 val) {
|
||||
static constexpr auto c = 1.0f / 1023.0f;
|
||||
return float(val * c);
|
||||
}
|
||||
|
||||
float S10ToSnorm(s16 val) {
|
||||
static constexpr auto c = 1.0f / 511.0f;
|
||||
return float(val * c);
|
||||
}
|
||||
|
||||
float U16ToUnorm(u16 val) {
|
||||
static constexpr auto c = 1.0f / 65535.0f;
|
||||
return float(val * c);
|
||||
}
|
||||
|
||||
float S16ToSnorm(s16 val) {
|
||||
static constexpr auto c = 1.0f / 32767.0f;
|
||||
return float(val * c);
|
||||
}
|
||||
|
||||
} // namespace NumberUtils
|
28
src/common/number_utils.h
Normal file
28
src/common/number_utils.h
Normal file
@ -0,0 +1,28 @@
|
||||
// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "common/types.h"
|
||||
|
||||
namespace NumberUtils {
|
||||
|
||||
float Uf11ToF32(u16 val);
|
||||
float Uf10ToF32(u16 val);
|
||||
float Uf16ToF32(u16 val);
|
||||
float U2ToUnorm(u8 val);
|
||||
float S2ToSnorm(s8 val);
|
||||
float U4ToUnorm(u8 val);
|
||||
float S4ToSnorm(s8 val);
|
||||
float U5ToUnorm(u8 val);
|
||||
float S5ToSnorm(s8 val);
|
||||
float U6ToUnorm(u8 val);
|
||||
float S6ToSnorm(s8 val);
|
||||
float U8ToUnorm(u8 val);
|
||||
float S8ToSnorm(s8 val);
|
||||
float U10ToUnorm(u16 val);
|
||||
float S10ToSnorm(s16 val);
|
||||
float U16ToUnorm(u16 val);
|
||||
float S16ToSnorm(s16 val);
|
||||
|
||||
} // namespace NumberUtils
|
@ -102,6 +102,10 @@ void DebugStateImpl::RequestFrameDump(s32 count) {
|
||||
gnm_frame_dump_request_count = count;
|
||||
frame_dump_list.clear();
|
||||
frame_dump_list.resize(count);
|
||||
const auto f = gnm_frame_count.load() + 1;
|
||||
for (size_t i = 0; i < count; ++i) {
|
||||
frame_dump_list[i].frame_id = f + i;
|
||||
}
|
||||
waiting_submit_pause = true;
|
||||
}
|
||||
|
||||
@ -139,7 +143,7 @@ void DebugStateImpl::PushQueueDump(QueueDump dump) {
|
||||
}
|
||||
|
||||
void DebugStateImpl::PushRegsDump(uintptr_t base_addr, uintptr_t header_addr,
|
||||
const AmdGpu::Liverpool::Regs& regs) {
|
||||
const AmdGpu::Liverpool::Regs& regs, bool is_compute) {
|
||||
std::scoped_lock lock{frame_dump_list_mutex};
|
||||
const auto it = waiting_reg_dumps.find(header_addr);
|
||||
if (it == waiting_reg_dumps.end()) {
|
||||
@ -150,15 +154,24 @@ void DebugStateImpl::PushRegsDump(uintptr_t base_addr, uintptr_t header_addr,
|
||||
waiting_reg_dumps_dbg.erase(waiting_reg_dumps_dbg.find(header_addr));
|
||||
auto& dump = frame.regs[header_addr - base_addr];
|
||||
dump.regs = regs;
|
||||
for (int i = 0; i < RegDump::MaxShaderStages; i++) {
|
||||
if (regs.stage_enable.IsStageEnabled(i)) {
|
||||
auto stage = regs.ProgramForStage(i);
|
||||
if (stage->address_lo != 0) {
|
||||
auto code = stage->Code();
|
||||
dump.stages[i] = ShaderDump{
|
||||
.user_data = *stage,
|
||||
.code = std::vector<u32>{code.begin(), code.end()},
|
||||
};
|
||||
if (is_compute) {
|
||||
dump.is_compute = true;
|
||||
const auto& cs = dump.regs.cs_program;
|
||||
dump.cs_data = ComputerShaderDump{
|
||||
.cs_program = cs,
|
||||
.code = std::vector<u32>{cs.Code().begin(), cs.Code().end()},
|
||||
};
|
||||
} else {
|
||||
for (int i = 0; i < RegDump::MaxShaderStages; i++) {
|
||||
if (regs.stage_enable.IsStageEnabled(i)) {
|
||||
auto stage = regs.ProgramForStage(i);
|
||||
if (stage->address_lo != 0) {
|
||||
auto code = stage->Code();
|
||||
dump.stages[i] = ShaderDump{
|
||||
.user_data = *stage,
|
||||
.code = std::vector<u32>{code.begin(), code.end()},
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -36,9 +36,9 @@ class FrameGraph;
|
||||
namespace DebugStateType {
|
||||
|
||||
enum class QueueType {
|
||||
acb,
|
||||
dcb,
|
||||
ccb,
|
||||
dcb = 0,
|
||||
ccb = 1,
|
||||
acb = 2,
|
||||
};
|
||||
|
||||
struct QueueDump {
|
||||
@ -54,13 +54,21 @@ struct ShaderDump {
|
||||
std::vector<u32> code{};
|
||||
};
|
||||
|
||||
struct ComputerShaderDump {
|
||||
Vulkan::Liverpool::ComputeProgram cs_program{};
|
||||
std::vector<u32> code{};
|
||||
};
|
||||
|
||||
struct RegDump {
|
||||
bool is_compute{false};
|
||||
static constexpr size_t MaxShaderStages = 5;
|
||||
Vulkan::Liverpool::Regs regs{};
|
||||
std::array<ShaderDump, MaxShaderStages> stages{};
|
||||
ComputerShaderDump cs_data{};
|
||||
};
|
||||
|
||||
struct FrameDump {
|
||||
u32 frame_id;
|
||||
std::vector<QueueDump> queues;
|
||||
std::unordered_map<uintptr_t, RegDump> regs; // address -> reg dump
|
||||
};
|
||||
@ -143,7 +151,7 @@ public:
|
||||
void PushQueueDump(QueueDump dump);
|
||||
|
||||
void PushRegsDump(uintptr_t base_addr, uintptr_t header_addr,
|
||||
const AmdGpu::Liverpool::Regs& regs);
|
||||
const AmdGpu::Liverpool::Regs& regs, bool is_compute = false);
|
||||
};
|
||||
} // namespace DebugStateType
|
||||
|
||||
|
8
src/core/devtools/help.txt
Normal file
8
src/core/devtools/help.txt
Normal file
@ -0,0 +1,8 @@
|
||||
// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
R"(
|
||||
* If you hold shift, you can move the window without docking it.
|
||||
* You don't need to close every window you open. When a parent window is closed, all its children will be closed too.
|
||||
* If you want to inspect or compare more than 1 frame dump without undocking, there's a option to keep showing opened popups even when in hide/minimize the frame dump window.
|
||||
* To use the disassembly viewer, you need to set up a cli to use a external disassembler and use "{src}" as a placeholder for the source code file, e.g. dis.exe --some-opt "{src}"
|
||||
)"
|
@ -31,6 +31,12 @@ static float debug_popup_timing = 3.0f;
|
||||
|
||||
static bool just_opened_options = false;
|
||||
|
||||
// clang-format off
|
||||
static std::string help_text =
|
||||
#include "help.txt"
|
||||
;
|
||||
// clang-format on
|
||||
|
||||
void L::DrawMenuBar() {
|
||||
const auto& ctx = *GImGui;
|
||||
const auto& io = ctx.IO;
|
||||
@ -38,6 +44,7 @@ void L::DrawMenuBar() {
|
||||
auto isSystemPaused = DebugState.IsGuestThreadsPaused();
|
||||
|
||||
bool open_popup_options = false;
|
||||
bool open_popup_help = false;
|
||||
|
||||
if (BeginMainMenuBar()) {
|
||||
if (BeginMenu("Options")) {
|
||||
@ -60,6 +67,7 @@ void L::DrawMenuBar() {
|
||||
ImGui::EndMenu();
|
||||
}
|
||||
open_popup_options = MenuItem("Options");
|
||||
open_popup_help = MenuItem("Help & Tips");
|
||||
ImGui::EndMenu();
|
||||
}
|
||||
EndMainMenuBar();
|
||||
@ -84,6 +92,9 @@ void L::DrawMenuBar() {
|
||||
OpenPopup("GPU Tools Options");
|
||||
just_opened_options = true;
|
||||
}
|
||||
if (open_popup_help) {
|
||||
OpenPopup("HelpTips");
|
||||
}
|
||||
}
|
||||
|
||||
void L::DrawAdvanced() {
|
||||
@ -154,25 +165,49 @@ void L::DrawAdvanced() {
|
||||
if (BeginPopupModal("GPU Tools Options", &close_popup_options,
|
||||
ImGuiWindowFlags_AlwaysAutoResize | ImGuiWindowFlags_NoSavedSettings)) {
|
||||
static char disassembly_cli[512];
|
||||
static bool frame_dump_render_on_collapse;
|
||||
|
||||
if (just_opened_options) {
|
||||
just_opened_options = false;
|
||||
auto s = Options.disassembly_cli.copy(disassembly_cli, sizeof(disassembly_cli) - 1);
|
||||
disassembly_cli[s] = '\0';
|
||||
frame_dump_render_on_collapse = Options.frame_dump_render_on_collapse;
|
||||
}
|
||||
|
||||
InputText("Shader disassembler: ", disassembly_cli, sizeof(disassembly_cli));
|
||||
if (IsItemHovered()) {
|
||||
SetTooltip(R"(Command to disassemble shaders. Example "dis.exe" --raw "{src}")");
|
||||
}
|
||||
Checkbox("Show frame dump popups even when collapsed", &frame_dump_render_on_collapse);
|
||||
if (IsItemHovered()) {
|
||||
SetTooltip("When a frame dump is collapsed, it will keep\n"
|
||||
"showing all opened popups related to it");
|
||||
}
|
||||
|
||||
if (Button("Save")) {
|
||||
Options.disassembly_cli = disassembly_cli;
|
||||
Options.frame_dump_render_on_collapse = frame_dump_render_on_collapse;
|
||||
SaveIniSettingsToDisk(io.IniFilename);
|
||||
CloseCurrentPopup();
|
||||
}
|
||||
EndPopup();
|
||||
}
|
||||
|
||||
if (BeginPopup("HelpTips", ImGuiWindowFlags_AlwaysAutoResize |
|
||||
ImGuiWindowFlags_NoSavedSettings | ImGuiWindowFlags_NoMove)) {
|
||||
CentralizeWindow();
|
||||
|
||||
PushStyleVar(ImGuiStyleVar_WindowPadding, ImVec2{10.0f});
|
||||
PushTextWrapPos(600.0f);
|
||||
|
||||
const char* begin = help_text.data();
|
||||
TextUnformatted(begin, begin + help_text.size());
|
||||
|
||||
PopTextWrapPos();
|
||||
PopStyleVar();
|
||||
|
||||
EndPopup();
|
||||
}
|
||||
}
|
||||
|
||||
void L::DrawSimple() {
|
||||
|
@ -11,14 +11,20 @@ TOptions Options;
|
||||
|
||||
void LoadOptionsConfig(const char* line) {
|
||||
char str[512];
|
||||
int i;
|
||||
if (sscanf(line, "disassembly_cli=%511[^\n]", str) == 1) {
|
||||
Options.disassembly_cli = str;
|
||||
return;
|
||||
}
|
||||
if (sscanf(line, "frame_dump_render_on_collapse=%d", &i) == 1) {
|
||||
Options.frame_dump_render_on_collapse = i != 0;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
void SerializeOptionsConfig(ImGuiTextBuffer* buf) {
|
||||
buf->appendf("disassembly_cli=%s\n", Options.disassembly_cli.c_str());
|
||||
buf->appendf("frame_dump_render_on_collapse=%d\n", Options.frame_dump_render_on_collapse);
|
||||
}
|
||||
|
||||
} // namespace Core::Devtools
|
||||
|
@ -10,7 +10,8 @@ struct ImGuiTextBuffer;
|
||||
namespace Core::Devtools {
|
||||
|
||||
struct TOptions {
|
||||
std::string disassembly_cli;
|
||||
std::string disassembly_cli{};
|
||||
bool frame_dump_render_on_collapse{false};
|
||||
};
|
||||
|
||||
extern TOptions Options;
|
||||
|
@ -1173,7 +1173,7 @@ CmdListViewer::CmdListViewer(DebugStateType::FrameDump* _frame_dump,
|
||||
}
|
||||
}
|
||||
|
||||
void CmdListViewer::Draw() {
|
||||
void CmdListViewer::Draw(bool only_batches_view) {
|
||||
const auto& ctx = *GetCurrentContext();
|
||||
|
||||
if (batch_view.open) {
|
||||
@ -1188,6 +1188,10 @@ void CmdListViewer::Draw() {
|
||||
++it;
|
||||
}
|
||||
|
||||
if (only_batches_view) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (cmdb_view.Open) {
|
||||
MemoryEditor::Sizes s;
|
||||
cmdb_view.CalcSizes(s, cmdb_size, cmdb_addr);
|
||||
@ -1228,7 +1232,7 @@ void CmdListViewer::Draw() {
|
||||
Text("size : %04llX", cmdb_size);
|
||||
Separator();
|
||||
|
||||
if (TreeNode("Batches")) {
|
||||
{
|
||||
int tree_depth = 0;
|
||||
int tree_depth_show = 0;
|
||||
|
||||
@ -1283,9 +1287,10 @@ void CmdListViewer::Draw() {
|
||||
auto const* pm4_hdr =
|
||||
reinterpret_cast<PM4Header const*>(cmdb_addr + batch.start_addr);
|
||||
|
||||
bool ignore_header = false;
|
||||
char batch_hdr[128];
|
||||
if (batch.type == static_cast<AmdGpu::PM4ItOpcode>(0xFF)) {
|
||||
snprintf(batch_hdr, sizeof(batch_hdr), "State batch");
|
||||
ignore_header = true;
|
||||
} else if (!batch.marker.empty()) {
|
||||
snprintf(batch_hdr, sizeof(batch_hdr), "%08llX: batch-%03d %s | %s",
|
||||
cmdb_addr + batch.start_addr, batch.id,
|
||||
@ -1309,22 +1314,35 @@ void CmdListViewer::Draw() {
|
||||
auto data = frame_dump->regs.at(batch.command_addr);
|
||||
if (GetIO().KeyShift) {
|
||||
auto& pop = extra_batch_view.emplace_back();
|
||||
pop.SetData(data, batch_id);
|
||||
pop.SetData(data, name, batch_id);
|
||||
pop.open = true;
|
||||
} else {
|
||||
batch_view.SetData(data, batch_id);
|
||||
batch_view.open = true;
|
||||
if (batch_view.open &&
|
||||
this->last_selected_batch == static_cast<int>(batch_id)) {
|
||||
batch_view.open = false;
|
||||
} else {
|
||||
this->last_selected_batch = static_cast<int>(batch_id);
|
||||
batch_view.SetData(data, name, batch_id);
|
||||
if (!batch_view.open || !batch_view.moved) {
|
||||
batch_view.open = true;
|
||||
const auto pos = GetItemRectMax() + ImVec2{5.0f, 0.0f};
|
||||
batch_view.SetPos(pos);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
bool show_batch_content = true;
|
||||
|
||||
if (group_batches) {
|
||||
if (group_batches && !ignore_header) {
|
||||
show_batch_content =
|
||||
CollapsingHeader(batch_hdr, ImGuiTreeNodeFlags_AllowOverlap);
|
||||
SameLine(GetContentRegionAvail().x - 40.0f);
|
||||
if (Button("->", {40.0f, 0.0f})) {
|
||||
const char* text =
|
||||
last_selected_batch == static_cast<int>(batch_id) && batch_view.open ? "X"
|
||||
: "->";
|
||||
if (Button(text, {40.0f, 0.0f})) {
|
||||
open_batch_view();
|
||||
}
|
||||
}
|
||||
@ -1332,7 +1350,7 @@ void CmdListViewer::Draw() {
|
||||
if (show_batch_content) {
|
||||
auto processed_size = 0ull;
|
||||
auto bb = ctx.LastItemData.Rect;
|
||||
if (group_batches) {
|
||||
if (group_batches && !ignore_header) {
|
||||
Indent();
|
||||
}
|
||||
auto const batch_sz = batch.end_addr - batch.start_addr;
|
||||
@ -1354,7 +1372,12 @@ void CmdListViewer::Draw() {
|
||||
if (!group_batches) {
|
||||
if (IsDrawCall(op)) {
|
||||
SameLine(GetContentRegionAvail().x - 40.0f);
|
||||
if (Button("->", {40.0f, 0.0f})) {
|
||||
const char* text =
|
||||
last_selected_batch == static_cast<int>(batch_id) &&
|
||||
batch_view.open
|
||||
? "X"
|
||||
: "->";
|
||||
if (Button(text, {40.0f, 0.0f})) {
|
||||
open_batch_view();
|
||||
}
|
||||
}
|
||||
@ -1426,7 +1449,7 @@ void CmdListViewer::Draw() {
|
||||
processed_size += processed_len;
|
||||
}
|
||||
|
||||
if (group_batches) {
|
||||
if (group_batches && !ignore_header) {
|
||||
Unindent();
|
||||
};
|
||||
bb = {{0.0f, bb.Max.y}, ctx.LastItemData.Rect.Max};
|
||||
@ -1450,8 +1473,6 @@ void CmdListViewer::Draw() {
|
||||
PopID();
|
||||
|
||||
highlight_batch = current_highlight_batch;
|
||||
|
||||
TreePop();
|
||||
}
|
||||
}
|
||||
EndChild();
|
||||
|
@ -53,6 +53,8 @@ class CmdListViewer {
|
||||
u32 highlight_batch{~0u};
|
||||
|
||||
RegView batch_view;
|
||||
int last_selected_batch{-1};
|
||||
|
||||
std::vector<RegView> extra_batch_view;
|
||||
|
||||
static void OnNop(AmdGpu::PM4Type3Header const* header, u32 const* body);
|
||||
@ -68,7 +70,7 @@ public:
|
||||
explicit CmdListViewer(DebugStateType::FrameDump* frame_dump, const std::vector<u32>& cmd_list,
|
||||
uintptr_t base_addr = 0, std::string name = "");
|
||||
|
||||
void Draw();
|
||||
void Draw(bool only_batches_view = false);
|
||||
};
|
||||
|
||||
} // namespace Core::Devtools::Widget
|
||||
|
@ -4,15 +4,16 @@
|
||||
#pragma once
|
||||
|
||||
#include <string>
|
||||
#include <type_traits>
|
||||
#include <variant>
|
||||
|
||||
#include <magic_enum.hpp>
|
||||
|
||||
#include "common/bit_field.h"
|
||||
#include "common/types.h"
|
||||
#include "video_core/amdgpu/pm4_opcodes.h"
|
||||
|
||||
namespace Core::Devtools::Widget {
|
||||
|
||||
/*
|
||||
* Generic PM4 header
|
||||
*/
|
||||
@ -57,16 +58,24 @@ void DrawRow(const char* text, const char* fmt, Args... args) {
|
||||
ImGui::TextUnformatted(buf);
|
||||
}
|
||||
|
||||
template <typename T, typename V = u32>
|
||||
void DrawEnumRow(const char* text, T value) {
|
||||
DrawRow(text, "%X (%s)", V(value), magic_enum::enum_name(value).data());
|
||||
template <typename T>
|
||||
void DrawValueRow(const char* text, T value) {
|
||||
if constexpr (std::is_enum_v<T>) {
|
||||
return DrawRow(text, "%X (%s)", value, magic_enum::enum_name(value).data());
|
||||
} else if constexpr (std::is_integral_v<T>) {
|
||||
return DrawRow(text, "%X", value);
|
||||
} else if constexpr (std::is_base_of_v<BitField<T::position, T::bits, typename T::Type>, T>) {
|
||||
return DrawValueRow(text, value.Value());
|
||||
} else {
|
||||
static_assert(false, "Unsupported type");
|
||||
}
|
||||
}
|
||||
|
||||
template <typename V, typename... Extra>
|
||||
void DrawMultipleRow(const char* text, const char* fmt, V arg, Extra&&... extra_args) {
|
||||
DrawRow(text, fmt, arg);
|
||||
void DrawValueRowList(const char* text, V arg, Extra&&... extra_args) {
|
||||
DrawValueRow(text, arg);
|
||||
if constexpr (sizeof...(extra_args) > 0) {
|
||||
DrawMultipleRow(std::forward<Extra>(extra_args)...);
|
||||
DrawValueRowList(std::forward<Extra>(extra_args)...);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -7,6 +7,7 @@
|
||||
#include <magic_enum.hpp>
|
||||
|
||||
#include "common/io_file.h"
|
||||
#include "core/devtools/options.h"
|
||||
#include "frame_dump.h"
|
||||
#include "imgui_internal.h"
|
||||
#include "imgui_memory_editor.h"
|
||||
@ -45,11 +46,14 @@ FrameDumpViewer::FrameDumpViewer(const FrameDump& _frame_dump)
|
||||
selected_submit_num = 0;
|
||||
selected_queue_num2 = 0;
|
||||
|
||||
has_queue_type.fill(false);
|
||||
cmd_list_viewer.reserve(frame_dump->queues.size());
|
||||
for (const auto& cmd : frame_dump->queues) {
|
||||
const auto fname =
|
||||
fmt::format("{}_{}_{:02}_{:02}", id, magic_enum::enum_name(selected_queue_type),
|
||||
selected_submit_num, selected_queue_num2);
|
||||
if (!cmd.data.empty()) {
|
||||
has_queue_type[static_cast<s32>(cmd.type)] = true;
|
||||
}
|
||||
const auto fname = fmt::format("F{} {}_{:02}_{:02}", frame_dump->frame_id,
|
||||
magic_enum::enum_name(cmd.type), cmd.submit_num, cmd.num2);
|
||||
cmd_list_viewer.emplace_back(frame_dump.get(), cmd.data, cmd.base_addr, fname);
|
||||
if (cmd.type == QueueType::dcb && cmd.submit_num == 0 && cmd.num2 == 0) {
|
||||
selected_cmd = static_cast<s32>(cmd_list_viewer.size() - 1);
|
||||
@ -64,9 +68,28 @@ void FrameDumpViewer::Draw() {
|
||||
return;
|
||||
}
|
||||
|
||||
const auto try_select = [&, this] {
|
||||
const auto it = std::ranges::find_if(frame_dump->queues, [&](const auto& cmd) {
|
||||
return cmd.type == selected_queue_type &&
|
||||
(selected_submit_num == -1 || cmd.submit_num == selected_submit_num) &&
|
||||
(selected_queue_num2 == -1 || cmd.num2 == selected_queue_num2);
|
||||
});
|
||||
if (it != frame_dump->queues.end()) {
|
||||
selected_cmd = static_cast<s32>(std::distance(frame_dump->queues.begin(), it));
|
||||
selected_submit_num = static_cast<s32>(frame_dump->queues[selected_cmd].submit_num);
|
||||
selected_queue_num2 = static_cast<s32>(frame_dump->queues[selected_cmd].num2);
|
||||
}
|
||||
};
|
||||
|
||||
bool is_showing = Options.frame_dump_render_on_collapse;
|
||||
bool is_collapsed = true;
|
||||
|
||||
char name[32];
|
||||
snprintf(name, sizeof(name), "Frame #%d dump", id);
|
||||
snprintf(name, sizeof(name), "Frame #%d dump", frame_dump->frame_id);
|
||||
if (Begin(name, &is_open, ImGuiWindowFlags_NoSavedSettings)) {
|
||||
is_showing = true;
|
||||
is_collapsed = false;
|
||||
|
||||
if (IsWindowAppearing()) {
|
||||
auto window = GetCurrentWindow();
|
||||
static ImGuiID dock_id = ImHashStr("FrameDumpDock");
|
||||
@ -79,12 +102,15 @@ void FrameDumpViewer::Draw() {
|
||||
if (BeginCombo("##select_queue_type", magic_enum::enum_name(selected_queue_type).data(),
|
||||
ImGuiComboFlags_WidthFitPreview)) {
|
||||
bool selected = false;
|
||||
#define COMBO(x) C_V(magic_enum::enum_name(x).data(), x, selected_queue_type, selected)
|
||||
COMBO(QueueType::acb)
|
||||
#define COMBO(x) \
|
||||
if (has_queue_type[static_cast<s32>(x)]) \
|
||||
C_V(magic_enum::enum_name(x).data(), x, selected_queue_type, selected)
|
||||
COMBO(QueueType::dcb);
|
||||
COMBO(QueueType::ccb);
|
||||
COMBO(QueueType::acb);
|
||||
if (selected) {
|
||||
selected_submit_num = selected_queue_num2 = -1;
|
||||
try_select();
|
||||
}
|
||||
EndCombo();
|
||||
}
|
||||
@ -111,9 +137,9 @@ void FrameDumpViewer::Draw() {
|
||||
SameLine();
|
||||
if (BeginCombo("##select_submit_num", small_int_to_str(selected_submit_num).data(),
|
||||
ImGuiComboFlags_WidthFitPreview)) {
|
||||
std::array<bool, 32> available_submits{};
|
||||
std::array<bool, 32> available_submits{false};
|
||||
for (const auto& cmd : frame_dump->queues) {
|
||||
if (cmd.type == selected_queue_type) {
|
||||
if (cmd.type == selected_queue_type && !cmd.data.empty()) {
|
||||
available_submits[cmd.submit_num] = true;
|
||||
}
|
||||
}
|
||||
@ -128,6 +154,7 @@ void FrameDumpViewer::Draw() {
|
||||
}
|
||||
if (selected) {
|
||||
selected_queue_num2 = -1;
|
||||
try_select();
|
||||
}
|
||||
EndCombo();
|
||||
}
|
||||
@ -136,9 +163,10 @@ void FrameDumpViewer::Draw() {
|
||||
SameLine();
|
||||
if (BeginCombo("##select_queue_num2", small_int_to_str(selected_queue_num2).data(),
|
||||
ImGuiComboFlags_WidthFitPreview)) {
|
||||
std::array<bool, 32> available_queues{};
|
||||
std::array<bool, 32> available_queues{false};
|
||||
for (const auto& cmd : frame_dump->queues) {
|
||||
if (cmd.type == selected_queue_type && cmd.submit_num == selected_submit_num) {
|
||||
if (cmd.type == selected_queue_type && cmd.submit_num == selected_submit_num &&
|
||||
!cmd.data.empty()) {
|
||||
available_queues[cmd.num2] = true;
|
||||
}
|
||||
}
|
||||
@ -152,21 +180,14 @@ void FrameDumpViewer::Draw() {
|
||||
}
|
||||
}
|
||||
if (selected) {
|
||||
const auto it = std::ranges::find_if(frame_dump->queues, [&](const auto& cmd) {
|
||||
return cmd.type == selected_queue_type &&
|
||||
cmd.submit_num == selected_submit_num && cmd.num2 == selected_queue_num2;
|
||||
});
|
||||
if (it != frame_dump->queues.end()) {
|
||||
selected_cmd = static_cast<s32>(std::distance(frame_dump->queues.begin(), it));
|
||||
}
|
||||
try_select();
|
||||
}
|
||||
EndCombo();
|
||||
}
|
||||
EndGroup();
|
||||
|
||||
if (selected_cmd != -1) {
|
||||
cmd_list_viewer[selected_cmd].Draw();
|
||||
}
|
||||
}
|
||||
if (is_showing && selected_cmd != -1) {
|
||||
cmd_list_viewer[selected_cmd].Draw(is_collapsed);
|
||||
}
|
||||
End();
|
||||
}
|
||||
|
@ -20,6 +20,7 @@ class FrameDumpViewer {
|
||||
int id;
|
||||
|
||||
std::vector<CmdListViewer> cmd_list_viewer;
|
||||
std::array<bool, 3> has_queue_type;
|
||||
|
||||
DebugStateType::QueueType selected_queue_type;
|
||||
s32 selected_submit_num;
|
||||
|
@ -9,6 +9,7 @@
|
||||
|
||||
#include "cmd_list.h"
|
||||
#include "common.h"
|
||||
#include "imgui/imgui_std.h"
|
||||
|
||||
using namespace ImGui;
|
||||
using magic_enum::enum_name;
|
||||
@ -21,13 +22,13 @@ void RegPopup::DrawColorBuffer(const AmdGpu::Liverpool::ColorBuffer& buffer) {
|
||||
|
||||
// clang-format off
|
||||
|
||||
DrawMultipleRow(
|
||||
"BASE_ADDR", "%X", buffer.base_address,
|
||||
"PITCH.TILE_MAX", "%X", buffer.pitch.tile_max,
|
||||
"PITCH.FMASK_TILE_MAX", "%X", buffer.pitch.fmask_tile_max,
|
||||
"SLICE.TILE_MAX", "%X", buffer.slice.tile_max,
|
||||
"VIEW.SLICE_START", "%X", buffer.view.slice_start,
|
||||
"VIEW.SLICE_MAX", "%X", buffer.view.slice_max
|
||||
DrawValueRowList(
|
||||
"BASE_ADDR", buffer.base_address,
|
||||
"PITCH.TILE_MAX", buffer.pitch.tile_max,
|
||||
"PITCH.FMASK_TILE_MAX", buffer.pitch.fmask_tile_max,
|
||||
"SLICE.TILE_MAX", buffer.slice.tile_max,
|
||||
"VIEW.SLICE_START", buffer.view.slice_start,
|
||||
"VIEW.SLICE_MAX", buffer.view.slice_max
|
||||
);
|
||||
|
||||
TableNextRow();
|
||||
@ -49,31 +50,25 @@ void RegPopup::DrawColorBuffer(const AmdGpu::Liverpool::ColorBuffer& buffer) {
|
||||
}
|
||||
|
||||
TableNextRow();
|
||||
DrawMultipleRow(
|
||||
"CMASK_BASE_EXT", "%X", buffer.cmask_base_address,
|
||||
"FMASK_BASE_EXT", "%X", buffer.fmask_base_address,
|
||||
"FMASK_SLICE.TILE_MAX", "%X", buffer.fmask_slice.tile_max,
|
||||
"CLEAR_WORD0", "%X", buffer.clear_word0,
|
||||
"CLEAR_WORD1", "%X", buffer.clear_word1
|
||||
DrawValueRowList(
|
||||
"CMASK_BASE_EXT", buffer.cmask_base_address,
|
||||
"FMASK_BASE_EXT", buffer.fmask_base_address,
|
||||
"FMASK_SLICE.TILE_MAX", buffer.fmask_slice.tile_max,
|
||||
"CLEAR_WORD0", buffer.clear_word0,
|
||||
"CLEAR_WORD1", buffer.clear_word1,
|
||||
"Pitch()", buffer.Pitch(),
|
||||
"Height()", buffer.Height(),
|
||||
"Address()", buffer.Address(),
|
||||
"CmaskAddress", buffer.CmaskAddress(),
|
||||
"FmaskAddress", buffer.FmaskAddress(),
|
||||
"NumSamples()", buffer.NumSamples(),
|
||||
"NumSlices()", buffer.NumSlices(),
|
||||
"GetColorSliceSize()", buffer.GetColorSliceSize(),
|
||||
"GetTilingMode()", buffer.GetTilingMode(),
|
||||
"IsTiled()", buffer.IsTiled(),
|
||||
"NumFormat()", buffer.NumFormat()
|
||||
);
|
||||
|
||||
DrawMultipleRow(
|
||||
"Pitch()", "%X", buffer.Pitch(),
|
||||
"Height()", "%X", buffer.Height(),
|
||||
"Address()", "%X", buffer.Address(),
|
||||
"CmaskAddress", "%X", buffer.CmaskAddress(),
|
||||
"FmaskAddress", "%X", buffer.FmaskAddress(),
|
||||
"NumSamples()", "%X", buffer.NumSamples(),
|
||||
"NumSlices()", "%X", buffer.NumSlices(),
|
||||
"GetColorSliceSize()", "%X", buffer.GetColorSliceSize()
|
||||
);
|
||||
|
||||
auto tiling_mode = buffer.GetTilingMode();
|
||||
auto num_format = buffer.NumFormat();
|
||||
DrawEnumRow("GetTilingMode()", tiling_mode);
|
||||
DrawRow("IsTiled()", "%X", buffer.IsTiled());
|
||||
DrawEnumRow("NumFormat()", num_format);
|
||||
|
||||
// clang-format on
|
||||
|
||||
EndTable();
|
||||
@ -89,37 +84,34 @@ void RegPopup::DrawDepthBuffer(const DepthBuffer& depth_data) {
|
||||
TableNextRow();
|
||||
|
||||
// clang-format off
|
||||
DrawEnumRow("Z_INFO.FORMAT", depth_buffer.z_info.format.Value());
|
||||
DrawMultipleRow(
|
||||
"Z_INFO.NUM_SAMPLES", "%X", depth_buffer.z_info.num_samples,
|
||||
"Z_INFO.TILE_SPLIT", "%X", depth_buffer.z_info.tile_split,
|
||||
"Z_INFO.TILE_MODE_INDEX", "%X", depth_buffer.z_info.tile_mode_index,
|
||||
"Z_INFO.DECOMPRESS_ON_N_ZPLANES", "%X", depth_buffer.z_info.decompress_on_n_zplanes,
|
||||
"Z_INFO.ALLOW_EXPCLEAR", "%X", depth_buffer.z_info.allow_expclear,
|
||||
"Z_INFO.READ_SIZE", "%X", depth_buffer.z_info.read_size,
|
||||
"Z_INFO.TILE_SURFACE_EN", "%X", depth_buffer.z_info.tile_surface_en,
|
||||
"Z_INFO.CLEAR_DISALLOWED", "%X", depth_buffer.z_info.clear_disallowed,
|
||||
"Z_INFO.ZRANGE_PRECISION", "%X", depth_buffer.z_info.zrange_precision
|
||||
);
|
||||
|
||||
DrawEnumRow("STENCIL_INFO.FORMAT", depth_buffer.stencil_info.format.Value());
|
||||
|
||||
DrawMultipleRow(
|
||||
"Z_READ_BASE", "%X", depth_buffer.z_read_base,
|
||||
"STENCIL_READ_BASE", "%X", depth_buffer.stencil_read_base,
|
||||
"Z_WRITE_BASE", "%X", depth_buffer.z_write_base,
|
||||
"STENCIL_WRITE_BASE", "%X", depth_buffer.stencil_write_base,
|
||||
"DEPTH_SIZE.PITCH_TILE_MAX", "%X", depth_buffer.depth_size.pitch_tile_max,
|
||||
"DEPTH_SIZE.HEIGHT_TILE_MAX", "%X", depth_buffer.depth_size.height_tile_max,
|
||||
"DEPTH_SLICE.TILE_MAX", "%X", depth_buffer.depth_slice.tile_max,
|
||||
"Pitch()", "%X", depth_buffer.Pitch(),
|
||||
"Height()", "%X", depth_buffer.Height(),
|
||||
"Address()", "%X", depth_buffer.Address(),
|
||||
"NumSamples()", "%X", depth_buffer.NumSamples(),
|
||||
"NumBits()", "%X", depth_buffer.NumBits(),
|
||||
"GetDepthSliceSize()", "%X", depth_buffer.GetDepthSliceSize()
|
||||
DrawValueRowList(
|
||||
"Z_INFO.FORMAT", depth_buffer.z_info.format,
|
||||
"Z_INFO.NUM_SAMPLES", depth_buffer.z_info.num_samples,
|
||||
"Z_INFO.TILE_SPLIT", depth_buffer.z_info.tile_split,
|
||||
"Z_INFO.TILE_MODE_INDEX", depth_buffer.z_info.tile_mode_index,
|
||||
"Z_INFO.DECOMPRESS_ON_N_ZPLANES", depth_buffer.z_info.decompress_on_n_zplanes,
|
||||
"Z_INFO.ALLOW_EXPCLEAR", depth_buffer.z_info.allow_expclear,
|
||||
"Z_INFO.READ_SIZE", depth_buffer.z_info.read_size,
|
||||
"Z_INFO.TILE_SURFACE_EN", depth_buffer.z_info.tile_surface_en,
|
||||
"Z_INFO.CLEAR_DISALLOWED", depth_buffer.z_info.clear_disallowed,
|
||||
"Z_INFO.ZRANGE_PRECISION", depth_buffer.z_info.zrange_precision,
|
||||
"STENCIL_INFO.FORMAT", depth_buffer.stencil_info.format,
|
||||
"Z_READ_BASE", depth_buffer.z_read_base,
|
||||
"STENCIL_READ_BASE", depth_buffer.stencil_read_base,
|
||||
"Z_WRITE_BASE", depth_buffer.z_write_base,
|
||||
"STENCIL_WRITE_BASE", depth_buffer.stencil_write_base,
|
||||
"DEPTH_SIZE.PITCH_TILE_MAX", depth_buffer.depth_size.pitch_tile_max,
|
||||
"DEPTH_SIZE.HEIGHT_TILE_MAX", depth_buffer.depth_size.height_tile_max,
|
||||
"DEPTH_SLICE.TILE_MAX", depth_buffer.depth_slice.tile_max,
|
||||
"Pitch()", depth_buffer.Pitch(),
|
||||
"Height()", depth_buffer.Height(),
|
||||
"Address()", depth_buffer.Address(),
|
||||
"NumSamples()", depth_buffer.NumSamples(),
|
||||
"NumBits()", depth_buffer.NumBits(),
|
||||
"GetDepthSliceSize()", depth_buffer.GetDepthSliceSize()
|
||||
);
|
||||
// clang-format on
|
||||
|
||||
EndTable();
|
||||
}
|
||||
SeparatorText("Depth control");
|
||||
@ -127,19 +119,17 @@ void RegPopup::DrawDepthBuffer(const DepthBuffer& depth_data) {
|
||||
TableNextRow();
|
||||
|
||||
// clang-format off
|
||||
DrawMultipleRow(
|
||||
"STENCIL_ENABLE", "%X", depth_control.stencil_enable,
|
||||
"DEPTH_ENABLE", "%X", depth_control.depth_enable,
|
||||
"DEPTH_WRITE_ENABLE", "%X", depth_control.depth_write_enable,
|
||||
"DEPTH_BOUNDS_ENABLE", "%X", depth_control.depth_bounds_enable
|
||||
);
|
||||
DrawEnumRow("DEPTH_FUNC", depth_control.depth_func.Value());
|
||||
DrawRow("BACKFACE_ENABLE", "%X", depth_control.backface_enable);
|
||||
DrawEnumRow("STENCIL_FUNC", depth_control.stencil_ref_func.Value());
|
||||
DrawEnumRow("STENCIL_FUNC_BF", depth_control.stencil_bf_func.Value());
|
||||
DrawMultipleRow(
|
||||
"ENABLE_COLOR_WRITES_ON_DEPTH_FAIL", "%X", depth_control.enable_color_writes_on_depth_fail,
|
||||
"DISABLE_COLOR_WRITES_ON_DEPTH_PASS", "%X", depth_control.disable_color_writes_on_depth_pass
|
||||
DrawValueRowList(
|
||||
"STENCIL_ENABLE", depth_control.stencil_enable,
|
||||
"DEPTH_ENABLE", depth_control.depth_enable,
|
||||
"DEPTH_WRITE_ENABLE", depth_control.depth_write_enable,
|
||||
"DEPTH_BOUNDS_ENABLE", depth_control.depth_bounds_enable,
|
||||
"DEPTH_FUNC", depth_control.depth_func,
|
||||
"BACKFACE_ENABLE", depth_control.backface_enable,
|
||||
"STENCIL_FUNC", depth_control.stencil_ref_func,
|
||||
"STENCIL_FUNC_BF", depth_control.stencil_bf_func,
|
||||
"ENABLE_COLOR_WRITES_ON_DEPTH_FAIL", depth_control.enable_color_writes_on_depth_fail,
|
||||
"DISABLE_COLOR_WRITES_ON_DEPTH_PASS", depth_control.disable_color_writes_on_depth_pass
|
||||
);
|
||||
// clang-format on
|
||||
|
||||
@ -152,24 +142,45 @@ RegPopup::RegPopup() {
|
||||
id = unique_id++;
|
||||
}
|
||||
|
||||
void RegPopup::SetData(AmdGpu::Liverpool::ColorBuffer color_buffer, u32 batch_id, u32 cb_id) {
|
||||
void RegPopup::SetData(const std::string& base_title, AmdGpu::Liverpool::ColorBuffer color_buffer,
|
||||
u32 cb_id) {
|
||||
this->data = color_buffer;
|
||||
this->title = fmt::format("Batch #{} CB #{}", batch_id, cb_id);
|
||||
this->title = fmt::format("{}/CB #{}", base_title, cb_id);
|
||||
}
|
||||
|
||||
void RegPopup::SetData(AmdGpu::Liverpool::DepthBuffer depth_buffer,
|
||||
AmdGpu::Liverpool::DepthControl depth_control, u32 batch_id) {
|
||||
void RegPopup::SetData(const std::string& base_title, AmdGpu::Liverpool::DepthBuffer depth_buffer,
|
||||
AmdGpu::Liverpool::DepthControl depth_control) {
|
||||
this->data = std::make_tuple(depth_buffer, depth_control);
|
||||
this->title = fmt::format("Batch #{} Depth", batch_id);
|
||||
this->title = fmt::format("{}/Depth", base_title);
|
||||
}
|
||||
|
||||
void RegPopup::SetPos(ImVec2 pos, bool auto_resize) {
|
||||
char name[128];
|
||||
snprintf(name, sizeof(name), "%s###reg_popup_%d", title.c_str(), id);
|
||||
Begin(name, &open, flags);
|
||||
SetWindowPos(pos);
|
||||
if (auto_resize) {
|
||||
if (std::holds_alternative<AmdGpu::Liverpool::ColorBuffer>(data)) {
|
||||
SetWindowSize({365.0f, 520.0f});
|
||||
KeepWindowInside();
|
||||
} else if (std::holds_alternative<DepthBuffer>(data)) {
|
||||
SetWindowSize({404.0f, 543.0f});
|
||||
KeepWindowInside();
|
||||
}
|
||||
}
|
||||
last_pos = GetWindowPos();
|
||||
moved = false;
|
||||
End();
|
||||
}
|
||||
|
||||
void RegPopup::Draw() {
|
||||
|
||||
char name[128];
|
||||
snprintf(name, sizeof(name), "%s###reg_popup_%d", title.c_str(), id);
|
||||
if (Begin(name, &open, flags)) {
|
||||
if (GetWindowPos() != last_pos) {
|
||||
moved = true;
|
||||
}
|
||||
|
||||
SetNextWindowSize({250.0f, 300.0f}, ImGuiCond_FirstUseEver);
|
||||
if (Begin(name, &open, ImGuiWindowFlags_NoSavedSettings)) {
|
||||
if (const auto* buffer = std::get_if<AmdGpu::Liverpool::ColorBuffer>(&data)) {
|
||||
DrawColorBuffer(*buffer);
|
||||
} else if (const auto* depth_data = std::get_if<DepthBuffer>(&data)) {
|
||||
@ -178,5 +189,4 @@ void RegPopup::Draw() {
|
||||
}
|
||||
End();
|
||||
}
|
||||
|
||||
} // namespace Core::Devtools::Widget
|
||||
|
@ -5,6 +5,8 @@
|
||||
|
||||
#include <variant>
|
||||
|
||||
#include <imgui.h>
|
||||
|
||||
#include "common/types.h"
|
||||
#include "video_core/renderer_vulkan/liverpool_to_vk.h"
|
||||
|
||||
@ -12,25 +14,31 @@ namespace Core::Devtools::Widget {
|
||||
|
||||
class RegPopup {
|
||||
int id;
|
||||
ImGuiWindowFlags flags{ImGuiWindowFlags_NoSavedSettings};
|
||||
|
||||
using DepthBuffer = std::tuple<AmdGpu::Liverpool::DepthBuffer, AmdGpu::Liverpool::DepthControl>;
|
||||
|
||||
ImVec2 last_pos;
|
||||
std::variant<AmdGpu::Liverpool::ColorBuffer, DepthBuffer> data;
|
||||
std::string title{};
|
||||
|
||||
void DrawColorBuffer(const AmdGpu::Liverpool::ColorBuffer& buffer);
|
||||
static void DrawColorBuffer(const AmdGpu::Liverpool::ColorBuffer& buffer);
|
||||
|
||||
void DrawDepthBuffer(const DepthBuffer& depth_data);
|
||||
static void DrawDepthBuffer(const DepthBuffer& depth_data);
|
||||
|
||||
public:
|
||||
bool open = false;
|
||||
bool moved = false;
|
||||
|
||||
RegPopup();
|
||||
|
||||
void SetData(AmdGpu::Liverpool::ColorBuffer color_buffer, u32 batch_id, u32 cb_id);
|
||||
void SetData(const std::string& base_title, AmdGpu::Liverpool::ColorBuffer color_buffer,
|
||||
u32 cb_id);
|
||||
|
||||
void SetData(AmdGpu::Liverpool::DepthBuffer depth_buffer,
|
||||
AmdGpu::Liverpool::DepthControl depth_control, u32 batch_id);
|
||||
void SetData(const std::string& base_title, AmdGpu::Liverpool::DepthBuffer depth_buffer,
|
||||
AmdGpu::Liverpool::DepthControl depth_control);
|
||||
|
||||
void SetPos(ImVec2 pos, bool auto_resize = false);
|
||||
|
||||
void Draw();
|
||||
};
|
||||
|
@ -11,6 +11,7 @@
|
||||
#include "common.h"
|
||||
#include "common/io_file.h"
|
||||
#include "core/devtools/options.h"
|
||||
#include "imgui/imgui_std.h"
|
||||
#include "imgui_internal.h"
|
||||
#include "reg_view.h"
|
||||
|
||||
@ -22,6 +23,8 @@
|
||||
using namespace ImGui;
|
||||
using magic_enum::enum_name;
|
||||
|
||||
constexpr auto depth_id = 0xF3;
|
||||
|
||||
static std::optional<std::string> exec_cli(const char* cli) {
|
||||
std::array<char, 64> buffer{};
|
||||
std::string output;
|
||||
@ -40,7 +43,16 @@ static std::optional<std::string> exec_cli(const char* cli) {
|
||||
namespace Core::Devtools::Widget {
|
||||
|
||||
void RegView::ProcessShader(int shader_id) {
|
||||
auto shader = data.stages[shader_id];
|
||||
std::vector<u32> shader_code;
|
||||
Vulkan::Liverpool::UserData user_data;
|
||||
if (data.is_compute) {
|
||||
shader_code = data.cs_data.code;
|
||||
user_data = data.cs_data.cs_program.user_data;
|
||||
} else {
|
||||
const auto& s = data.stages[shader_id];
|
||||
shader_code = s.code;
|
||||
user_data = s.user_data.user_data;
|
||||
}
|
||||
|
||||
std::string shader_dis;
|
||||
|
||||
@ -57,7 +69,7 @@ void RegView::ProcessShader(int shader_id) {
|
||||
} else {
|
||||
cli.replace(pos, src_arg.size(), "\"" + bin_path.string() + "\"");
|
||||
Common::FS::IOFile file(bin_path, Common::FS::FileAccessMode::Write);
|
||||
file.Write(shader.code);
|
||||
file.Write(shader_code);
|
||||
file.Close();
|
||||
|
||||
auto result = exec_cli(cli.c_str());
|
||||
@ -73,8 +85,9 @@ void RegView::ProcessShader(int shader_id) {
|
||||
MemoryEditor hex_view;
|
||||
hex_view.Open = true;
|
||||
hex_view.ReadOnly = true;
|
||||
hex_view.Cols = 16;
|
||||
hex_view.Cols = 8;
|
||||
hex_view.OptShowAscii = false;
|
||||
hex_view.OptShowOptions = false;
|
||||
|
||||
TextEditor dis_view;
|
||||
dis_view.SetPalette(TextEditor::GetDarkPalette());
|
||||
@ -84,7 +97,7 @@ void RegView::ProcessShader(int shader_id) {
|
||||
ShaderCache cache{
|
||||
.hex_view = hex_view,
|
||||
.dis_view = dis_view,
|
||||
.user_data = shader.user_data.user_data,
|
||||
.user_data = user_data,
|
||||
};
|
||||
shader_decomp.emplace(shader_id, std::move(cache));
|
||||
}
|
||||
@ -95,34 +108,64 @@ void RegView::SelectShader(int id) {
|
||||
}
|
||||
}
|
||||
|
||||
void RegView::DrawRegs() {
|
||||
void RegView::DrawComputeRegs() {
|
||||
const auto& cs = data.cs_data.cs_program;
|
||||
|
||||
if (BeginTable("CREGS", 2, ImGuiTableFlags_Borders)) {
|
||||
TableNextRow();
|
||||
|
||||
// clang-format off
|
||||
DrawValueRowList(
|
||||
"DISPATCH_INITIATOR", cs.dispatch_initiator,
|
||||
"DIM_X", cs.dim_x,
|
||||
"DIM_Y", cs.dim_y,
|
||||
"DIM_Z", cs.dim_z,
|
||||
"START_X", cs.start_x,
|
||||
"START_Y", cs.start_y,
|
||||
"START_Z", cs.start_z,
|
||||
"NUM_THREAD_X.FULL", cs.num_thread_x.full,
|
||||
"NUM_THREAD_X.PARTIAL", cs.num_thread_x.partial,
|
||||
"NUM_THREAD_Y.FULL", cs.num_thread_y.full,
|
||||
"NUM_THREAD_Y.PARTIAL", cs.num_thread_y.partial,
|
||||
"NUM_THREAD_Z.FULL", cs.num_thread_z.full,
|
||||
"NUM_THREAD_Z.PARTIAL", cs.num_thread_z.partial,
|
||||
"MAX_WAVE_ID", cs.max_wave_id,
|
||||
"SETTINGS.NUM_VGPRS", cs.settings.num_vgprs,
|
||||
"SETTINGS.NUM_SGPRS", cs.settings.num_sgprs,
|
||||
"SETTINGS.NUM_USER_REGS", cs.settings.num_user_regs,
|
||||
"SETTINGS.TGID_ENABLE", cs.settings.tgid_enable,
|
||||
"SETTINGS.LDS_DWORDS", cs.settings.lds_dwords,
|
||||
"RESOURCE_LIMITS", cs.resource_limits
|
||||
);
|
||||
// clang-format on
|
||||
|
||||
EndTable();
|
||||
}
|
||||
}
|
||||
|
||||
void RegView::DrawGraphicsRegs() {
|
||||
const auto& regs = data.regs;
|
||||
|
||||
if (BeginTable("REGS", 2, ImGuiTableFlags_Borders)) {
|
||||
TableNextRow();
|
||||
|
||||
auto& s = regs.screen_scissor;
|
||||
DrawRow("Scissor", "(%d, %d, %d, %d)", s.top_left_x, s.top_left_y, s.bottom_right_x,
|
||||
s.bottom_right_y);
|
||||
|
||||
auto cc_mode = regs.color_control.mode.Value();
|
||||
DrawRow("Color control", "%X (%s)", cc_mode, enum_name(cc_mode).data());
|
||||
DrawValueRow("Primitive type", regs.primitive_type);
|
||||
|
||||
const auto open_new_popup = [&](int cb, auto... args) {
|
||||
const auto pos = GetItemRectMax() + ImVec2(5.0f, 0.0f);
|
||||
if (GetIO().KeyShift) {
|
||||
auto& pop = extra_reg_popup.emplace_back();
|
||||
pop.SetData(args...);
|
||||
pop.SetData(title, args...);
|
||||
pop.open = true;
|
||||
pop.SetPos(pos, true);
|
||||
} else if (last_selected_cb == cb && default_reg_popup.open) {
|
||||
default_reg_popup.open = false;
|
||||
} else {
|
||||
last_selected_cb = cb;
|
||||
default_reg_popup.SetData(args...);
|
||||
if (!default_reg_popup.open) {
|
||||
default_reg_popup.SetData(title, args...);
|
||||
if (!default_reg_popup.open || !default_reg_popup.moved) {
|
||||
default_reg_popup.open = true;
|
||||
auto popup_pos =
|
||||
GetCurrentContext()->LastItemData.Rect.Max + ImVec2(5.0f, 0.0f);
|
||||
SetNextWindowPos(popup_pos, ImGuiCond_Always);
|
||||
default_reg_popup.Draw();
|
||||
default_reg_popup.SetPos(pos, true);
|
||||
}
|
||||
}
|
||||
};
|
||||
@ -142,7 +185,7 @@ void RegView::DrawRegs() {
|
||||
} else {
|
||||
const char* text = last_selected_cb == cb && default_reg_popup.open ? "x" : "->";
|
||||
if (SmallButton(text)) {
|
||||
open_new_popup(cb, buffer, batch_id, cb);
|
||||
open_new_popup(cb, buffer, cb);
|
||||
}
|
||||
}
|
||||
|
||||
@ -156,13 +199,30 @@ void RegView::DrawRegs() {
|
||||
if (regs.depth_buffer.Address() == 0 || !regs.depth_control.depth_enable) {
|
||||
TextUnformatted("N/A");
|
||||
} else {
|
||||
constexpr auto depth_id = 0xF3;
|
||||
const char* text = last_selected_cb == depth_id && default_reg_popup.open ? "x" : "->";
|
||||
if (SmallButton(text)) {
|
||||
open_new_popup(depth_id, regs.depth_buffer, regs.depth_control, batch_id);
|
||||
open_new_popup(depth_id, regs.depth_buffer, regs.depth_control);
|
||||
}
|
||||
}
|
||||
|
||||
auto& s = regs.screen_scissor;
|
||||
DrawRow("Scissor", "(%d, %d, %d, %d)", s.top_left_x, s.top_left_y, s.bottom_right_x,
|
||||
s.bottom_right_y);
|
||||
|
||||
DrawValueRow("Color control", regs.color_control.mode);
|
||||
|
||||
DrawRow("Primitive restart", "%X (IDX: %X)", regs.enable_primitive_restart & 1,
|
||||
regs.primitive_restart_index);
|
||||
// clang-format off
|
||||
DrawValueRowList(
|
||||
"Polygon mode", regs.polygon_control.PolyMode(),
|
||||
"Cull mode", regs.polygon_control.CullingMode(),
|
||||
"Clip Space", regs.clipper_control.clip_space,
|
||||
"Front face", regs.polygon_control.front_face,
|
||||
"Num Samples", regs.aa_config.NumSamples()
|
||||
);
|
||||
// clang-format on
|
||||
|
||||
EndTable();
|
||||
}
|
||||
}
|
||||
@ -172,9 +232,9 @@ RegView::RegView() {
|
||||
id = unique_id++;
|
||||
|
||||
char name[128];
|
||||
snprintf(name, sizeof(name), "BatchView###reg_dump_%d", id);
|
||||
snprintf(name, sizeof(name), "###reg_dump_%d", id);
|
||||
SetNextWindowPos({400.0f, 200.0f});
|
||||
SetNextWindowSize({450.0f, 500.0f});
|
||||
SetNextWindowSize({290.0f, 435.0f});
|
||||
ImGuiID root_dock_id;
|
||||
Begin(name);
|
||||
{
|
||||
@ -188,7 +248,7 @@ RegView::RegView() {
|
||||
ImGuiID up1, down1;
|
||||
|
||||
DockBuilderRemoveNodeChildNodes(root_dock_id);
|
||||
DockBuilderSplitNode(root_dock_id, ImGuiDir_Up, 0.2f, &up1, &down1);
|
||||
DockBuilderSplitNode(root_dock_id, ImGuiDir_Up, 0.19f, &up1, &down1);
|
||||
|
||||
snprintf(name, sizeof(name), "User data###reg_dump_%d/user_data", id);
|
||||
DockBuilderDockWindow(name, up1);
|
||||
@ -202,35 +262,68 @@ RegView::RegView() {
|
||||
DockBuilderFinish(root_dock_id);
|
||||
}
|
||||
|
||||
void RegView::SetData(DebugStateType::RegDump data, u32 batch_id) {
|
||||
this->data = std::move(data);
|
||||
void RegView::SetData(DebugStateType::RegDump _data, const std::string& base_title, u32 batch_id) {
|
||||
this->data = std::move(_data);
|
||||
this->batch_id = batch_id;
|
||||
this->title = fmt::format("{}/Batch {}", base_title, batch_id);
|
||||
// clear cache
|
||||
selected_shader = -1;
|
||||
shader_decomp.clear();
|
||||
default_reg_popup.open = false;
|
||||
if (data.is_compute) {
|
||||
selected_shader = -2;
|
||||
last_selected_cb = -1;
|
||||
default_reg_popup.open = false;
|
||||
ProcessShader(-2);
|
||||
} else {
|
||||
const auto& regs = data.regs;
|
||||
if (selected_shader >= 0 && !regs.stage_enable.IsStageEnabled(selected_shader)) {
|
||||
selected_shader = -1;
|
||||
}
|
||||
if (default_reg_popup.open) {
|
||||
default_reg_popup.open = false;
|
||||
if (last_selected_cb == depth_id) {
|
||||
const auto& has_depth =
|
||||
regs.depth_buffer.Address() != 0 && regs.depth_control.depth_enable;
|
||||
if (has_depth) {
|
||||
default_reg_popup.SetData(title, regs.depth_buffer, regs.depth_control);
|
||||
default_reg_popup.open = true;
|
||||
}
|
||||
} else if (last_selected_cb >= 0 &&
|
||||
last_selected_cb < AmdGpu::Liverpool::NumColorBuffers) {
|
||||
const auto& buffer = regs.color_buffers[last_selected_cb];
|
||||
const bool has_cb = buffer && regs.color_target_mask.GetMask(last_selected_cb);
|
||||
if (has_cb) {
|
||||
default_reg_popup.SetData(title, buffer, last_selected_cb);
|
||||
default_reg_popup.open = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
extra_reg_popup.clear();
|
||||
}
|
||||
|
||||
void RegView::Draw() {
|
||||
|
||||
void RegView::SetPos(ImVec2 pos) {
|
||||
char name[128];
|
||||
snprintf(name, sizeof(name), "BatchView %u###reg_dump_%d", batch_id, id);
|
||||
snprintf(name, sizeof(name), "%s###reg_dump_%d", title.c_str(), id);
|
||||
Begin(name, &open, ImGuiWindowFlags_MenuBar);
|
||||
SetWindowPos(pos);
|
||||
KeepWindowInside();
|
||||
last_pos = GetWindowPos();
|
||||
moved = false;
|
||||
End();
|
||||
}
|
||||
|
||||
void RegView::Draw() {
|
||||
char name[128];
|
||||
snprintf(name, sizeof(name), "%s###reg_dump_%d", title.c_str(), id);
|
||||
|
||||
if (Begin(name, &open, ImGuiWindowFlags_MenuBar)) {
|
||||
if (GetWindowPos() != last_pos) {
|
||||
moved = true;
|
||||
}
|
||||
|
||||
const char* names[] = {"vs", "ps", "gs", "es", "hs", "ls"};
|
||||
|
||||
if (BeginMenuBar()) {
|
||||
if (BeginMenu("Stage")) {
|
||||
for (int i = 0; i < DebugStateType::RegDump::MaxShaderStages; i++) {
|
||||
if (data.regs.stage_enable.IsStageEnabled(i)) {
|
||||
bool selected = selected_shader == i;
|
||||
if (Selectable(names[i], &selected)) {
|
||||
SelectShader(i);
|
||||
}
|
||||
}
|
||||
}
|
||||
ImGui::EndMenu();
|
||||
}
|
||||
if (BeginMenu("Windows")) {
|
||||
Checkbox("Registers", &show_registers);
|
||||
Checkbox("User data", &show_user_data);
|
||||
@ -240,11 +333,31 @@ void RegView::Draw() {
|
||||
EndMenuBar();
|
||||
}
|
||||
|
||||
char dock_name[64];
|
||||
snprintf(dock_name, sizeof(dock_name), "BatchView###reg_dump_%d/dock_space", id);
|
||||
auto root_dock_id = ImHashStr(dock_name);
|
||||
DockSpace(root_dock_id);
|
||||
if (!data.is_compute &&
|
||||
BeginChild("STAGES", {},
|
||||
ImGuiChildFlags_AlwaysAutoResize | ImGuiChildFlags_AutoResizeY)) {
|
||||
for (int i = 0; i < DebugStateType::RegDump::MaxShaderStages; i++) {
|
||||
if (data.regs.stage_enable.IsStageEnabled(i)) {
|
||||
const bool selected = selected_shader == i;
|
||||
if (selected) {
|
||||
PushStyleColor(ImGuiCol_Button, ImVec4{1.0f, 0.7f, 0.7f, 1.0f});
|
||||
}
|
||||
if (Button(names[i], {40.0f, 40.0f})) {
|
||||
SelectShader(i);
|
||||
}
|
||||
if (selected) {
|
||||
PopStyleColor();
|
||||
}
|
||||
}
|
||||
SameLine();
|
||||
}
|
||||
EndChild();
|
||||
}
|
||||
}
|
||||
char dock_name[64];
|
||||
snprintf(dock_name, sizeof(dock_name), "BatchView###reg_dump_%d/dock_space", id);
|
||||
auto root_dock_id = ImHashStr(dock_name);
|
||||
DockSpace(root_dock_id);
|
||||
End();
|
||||
|
||||
auto get_shader = [&]() -> ShaderCache* {
|
||||
@ -257,10 +370,11 @@ void RegView::Draw() {
|
||||
|
||||
if (show_user_data) {
|
||||
snprintf(name, sizeof(name), "User data###reg_dump_%d/user_data", id);
|
||||
if (Begin(name, &show_user_data)) {
|
||||
|
||||
if (Begin(name, &show_user_data, ImGuiWindowFlags_NoScrollbar)) {
|
||||
auto shader = get_shader();
|
||||
if (!shader) {
|
||||
Text("Select a stage");
|
||||
Text("Stage not selected");
|
||||
} else {
|
||||
shader->hex_view.DrawContents(shader->user_data.data(), shader->user_data.size());
|
||||
}
|
||||
@ -273,7 +387,7 @@ void RegView::Draw() {
|
||||
if (Begin(name, &show_disassembly)) {
|
||||
auto shader = get_shader();
|
||||
if (!shader) {
|
||||
Text("Select a stage");
|
||||
Text("Stage not selected");
|
||||
} else {
|
||||
shader->dis_view.Render("Disassembly", GetContentRegionAvail());
|
||||
}
|
||||
@ -284,7 +398,11 @@ void RegView::Draw() {
|
||||
if (show_registers) {
|
||||
snprintf(name, sizeof(name), "Regs###reg_dump_%d/regs", id);
|
||||
if (Begin(name, &show_registers)) {
|
||||
DrawRegs();
|
||||
if (data.is_compute) {
|
||||
DrawComputeRegs();
|
||||
} else {
|
||||
DrawGraphicsRegs();
|
||||
}
|
||||
}
|
||||
End();
|
||||
}
|
||||
|
@ -18,8 +18,10 @@ struct ShaderCache {
|
||||
class RegView {
|
||||
int id;
|
||||
|
||||
std::string title;
|
||||
DebugStateType::RegDump data;
|
||||
u32 batch_id{~0u};
|
||||
ImVec2 last_pos;
|
||||
|
||||
std::unordered_map<int, ShaderCache> shader_decomp;
|
||||
int selected_shader{-1};
|
||||
@ -35,14 +37,19 @@ class RegView {
|
||||
|
||||
void SelectShader(int shader_id);
|
||||
|
||||
void DrawRegs();
|
||||
void DrawComputeRegs();
|
||||
|
||||
void DrawGraphicsRegs();
|
||||
|
||||
public:
|
||||
bool open = false;
|
||||
bool moved = false;
|
||||
|
||||
RegView();
|
||||
|
||||
void SetData(DebugStateType::RegDump data, u32 batch_id);
|
||||
void SetData(DebugStateType::RegDump data, const std::string& base_title, u32 batch_id);
|
||||
|
||||
void SetPos(ImVec2 pos);
|
||||
|
||||
void Draw();
|
||||
};
|
||||
|
@ -3,6 +3,7 @@
|
||||
|
||||
#include <zlib-ng.h>
|
||||
#include "common/io_file.h"
|
||||
#include "common/logging/formatter.h"
|
||||
#include "core/file_format/pkg.h"
|
||||
#include "core/file_format/pkg_type.h"
|
||||
|
||||
@ -349,7 +350,8 @@ bool PKG::Extract(const std::filesystem::path& filepath, const std::filesystem::
|
||||
auto parent_path = extract_path.parent_path();
|
||||
auto title_id = GetTitleID();
|
||||
|
||||
if (parent_path.filename() != title_id) {
|
||||
if (parent_path.filename() != title_id &&
|
||||
!fmt::UTF(extract_path.u8string()).data.ends_with("-UPDATE")) {
|
||||
extractPaths[ndinode_counter] = parent_path / title_id;
|
||||
} else {
|
||||
// DLCs path has different structure
|
||||
|
@ -28,16 +28,11 @@ void MntPoints::UnmountAll() {
|
||||
m_mnt_pairs.clear();
|
||||
}
|
||||
|
||||
std::filesystem::path MntPoints::GetHostPath(std::string_view guest_directory, bool* is_read_only) {
|
||||
std::filesystem::path MntPoints::GetHostPath(std::string_view path, bool* is_read_only) {
|
||||
// Evil games like Turok2 pass double slashes e.g /app0//game.kpf
|
||||
std::string corrected_path(guest_directory);
|
||||
size_t pos = corrected_path.find("//");
|
||||
while (pos != std::string::npos) {
|
||||
corrected_path.replace(pos, 2, "/");
|
||||
pos = corrected_path.find("//", pos + 1);
|
||||
}
|
||||
const auto normalized_path = std::filesystem::path(path).lexically_normal().string();
|
||||
|
||||
const MntPair* mount = GetMount(corrected_path);
|
||||
const MntPair* mount = GetMount(normalized_path);
|
||||
if (!mount) {
|
||||
return "";
|
||||
}
|
||||
@ -47,80 +42,88 @@ std::filesystem::path MntPoints::GetHostPath(std::string_view guest_directory, b
|
||||
}
|
||||
|
||||
// Nothing to do if getting the mount itself.
|
||||
if (corrected_path == mount->mount) {
|
||||
if (normalized_path == mount->mount) {
|
||||
return mount->host_path;
|
||||
}
|
||||
|
||||
// Remove device (e.g /app0) from path to retrieve relative path.
|
||||
pos = mount->mount.size() + 1;
|
||||
const auto rel_path = std::string_view(corrected_path).substr(pos);
|
||||
const auto rel_path = std::string_view{normalized_path}.substr(mount->mount.size() + 1);
|
||||
std::filesystem::path host_path = mount->host_path / rel_path;
|
||||
|
||||
std::filesystem::path patch_path = mount->host_path;
|
||||
patch_path += "-UPDATE";
|
||||
if (corrected_path.starts_with("/app0/") && std::filesystem::exists(patch_path / rel_path)) {
|
||||
host_path = patch_path / rel_path;
|
||||
patch_path /= rel_path;
|
||||
|
||||
if ((normalized_path.starts_with("/app0") || normalized_path.starts_with("/hostapp")) &&
|
||||
std::filesystem::exists(patch_path)) {
|
||||
return patch_path;
|
||||
}
|
||||
|
||||
if (!NeedsCaseInsensitiveSearch) {
|
||||
return host_path;
|
||||
}
|
||||
|
||||
// If the path does not exist attempt to verify this.
|
||||
// Retrieve parent path until we find one that exists.
|
||||
std::scoped_lock lk{m_mutex};
|
||||
path_parts.clear();
|
||||
auto current_path = host_path;
|
||||
while (!std::filesystem::exists(current_path)) {
|
||||
// We have probably cached this if it's a folder.
|
||||
if (auto it = path_cache.find(current_path); it != path_cache.end()) {
|
||||
current_path = it->second;
|
||||
break;
|
||||
const auto search = [&](const auto host_path) {
|
||||
// If the path does not exist attempt to verify this.
|
||||
// Retrieve parent path until we find one that exists.
|
||||
std::scoped_lock lk{m_mutex};
|
||||
path_parts.clear();
|
||||
auto current_path = host_path;
|
||||
while (!std::filesystem::exists(current_path)) {
|
||||
// We have probably cached this if it's a folder.
|
||||
if (auto it = path_cache.find(current_path); it != path_cache.end()) {
|
||||
current_path = it->second;
|
||||
break;
|
||||
}
|
||||
path_parts.emplace_back(current_path.filename());
|
||||
current_path = current_path.parent_path();
|
||||
}
|
||||
path_parts.emplace_back(current_path.filename());
|
||||
current_path = current_path.parent_path();
|
||||
}
|
||||
|
||||
// We have found an anchor. Traverse parts we recoded and see if they
|
||||
// exist in filesystem but in different case.
|
||||
auto guest_path = current_path;
|
||||
while (!path_parts.empty()) {
|
||||
const auto part = path_parts.back();
|
||||
const auto add_match = [&](const auto& host_part) {
|
||||
current_path /= host_part;
|
||||
guest_path /= part;
|
||||
path_cache[guest_path] = current_path;
|
||||
path_parts.pop_back();
|
||||
};
|
||||
|
||||
// Can happen when the mismatch is in upper folder.
|
||||
if (std::filesystem::exists(current_path / part)) {
|
||||
add_match(part);
|
||||
continue;
|
||||
}
|
||||
const auto part_low = Common::ToLower(part.string());
|
||||
bool found_match = false;
|
||||
for (const auto& path : std::filesystem::directory_iterator(current_path)) {
|
||||
const auto candidate = path.path().filename();
|
||||
const auto filename = Common::ToLower(candidate.string());
|
||||
// Check if a filename matches in case insensitive manner.
|
||||
if (filename != part_low) {
|
||||
// We have found an anchor. Traverse parts we recoded and see if they
|
||||
// exist in filesystem but in different case.
|
||||
auto guest_path = current_path;
|
||||
while (!path_parts.empty()) {
|
||||
const auto part = path_parts.back();
|
||||
const auto add_match = [&](const auto& host_part) {
|
||||
current_path /= host_part;
|
||||
guest_path /= part;
|
||||
path_cache[guest_path] = current_path;
|
||||
path_parts.pop_back();
|
||||
};
|
||||
// Can happen when the mismatch is in upper folder.
|
||||
if (std::filesystem::exists(current_path / part)) {
|
||||
add_match(part);
|
||||
continue;
|
||||
}
|
||||
// We found a match, record the actual path in the cache.
|
||||
add_match(candidate);
|
||||
found_match = true;
|
||||
break;
|
||||
}
|
||||
if (!found_match) {
|
||||
// Opening the guest path will surely fail but at least gives
|
||||
// a better error message than the empty path.
|
||||
return host_path;
|
||||
const auto part_low = Common::ToLower(part.string());
|
||||
bool found_match = false;
|
||||
for (const auto& path : std::filesystem::directory_iterator(current_path)) {
|
||||
const auto candidate = path.path().filename();
|
||||
const auto filename = Common::ToLower(candidate.string());
|
||||
// Check if a filename matches in case insensitive manner.
|
||||
if (filename != part_low) {
|
||||
continue;
|
||||
}
|
||||
// We found a match, record the actual path in the cache.
|
||||
add_match(candidate);
|
||||
found_match = true;
|
||||
break;
|
||||
}
|
||||
if (!found_match) {
|
||||
return std::optional<std::filesystem::path>({});
|
||||
}
|
||||
}
|
||||
return std::optional<std::filesystem::path>(current_path);
|
||||
};
|
||||
|
||||
if (const auto path = search(patch_path)) {
|
||||
return *path;
|
||||
}
|
||||
if (const auto path = search(host_path)) {
|
||||
return *path;
|
||||
}
|
||||
|
||||
// The path was found.
|
||||
return current_path;
|
||||
// Opening the guest path will surely fail but at least gives
|
||||
// a better error message than the empty path.
|
||||
return host_path;
|
||||
}
|
||||
|
||||
int HandleTable::CreateHandle() {
|
||||
|
@ -112,7 +112,7 @@ AvPlayer::AvPlayer(const SceAvPlayerInitData& data)
|
||||
m_state(std::make_unique<AvPlayerState>(m_init_data)) {}
|
||||
|
||||
s32 AvPlayer::PostInit(const SceAvPlayerPostInitData& data) {
|
||||
m_post_init_data = data;
|
||||
m_state->PostInit(data);
|
||||
return ORBIS_OK;
|
||||
}
|
||||
|
||||
|
@ -56,7 +56,6 @@ private:
|
||||
|
||||
SceAvPlayerInitData m_init_data{};
|
||||
SceAvPlayerInitData m_init_data_original{};
|
||||
SceAvPlayerPostInitData m_post_init_data{};
|
||||
std::mutex m_file_io_mutex{};
|
||||
|
||||
std::atomic_bool m_has_source{};
|
||||
|
@ -37,7 +37,8 @@ namespace Libraries::AvPlayer {
|
||||
|
||||
using namespace Kernel;
|
||||
|
||||
AvPlayerSource::AvPlayerSource(AvPlayerStateCallback& state) : m_state(state) {}
|
||||
AvPlayerSource::AvPlayerSource(AvPlayerStateCallback& state, bool use_vdec2)
|
||||
: m_state(state), m_use_vdec2(use_vdec2) {}
|
||||
|
||||
AvPlayerSource::~AvPlayerSource() {
|
||||
Stop();
|
||||
@ -129,18 +130,25 @@ bool AvPlayerSource::GetStreamInfo(u32 stream_index, SceAvPlayerStreamInfo& info
|
||||
LOG_WARNING(Lib_AvPlayer, "Stream {} language is unknown", stream_index);
|
||||
}
|
||||
switch (info.type) {
|
||||
case SCE_AVPLAYER_VIDEO:
|
||||
case SCE_AVPLAYER_VIDEO: {
|
||||
LOG_INFO(Lib_AvPlayer, "Stream {} is a video stream.", stream_index);
|
||||
info.details.video.aspect_ratio =
|
||||
f32(p_stream->codecpar->width) / p_stream->codecpar->height;
|
||||
info.details.video.width = Common::AlignUp(u32(p_stream->codecpar->width), 16);
|
||||
info.details.video.height = Common::AlignUp(u32(p_stream->codecpar->height), 16);
|
||||
auto width = u32(p_stream->codecpar->width);
|
||||
auto height = u32(p_stream->codecpar->height);
|
||||
if (!m_use_vdec2) {
|
||||
width = Common::AlignUp(width, 16);
|
||||
height = Common::AlignUp(height, 16);
|
||||
}
|
||||
info.details.video.width = width;
|
||||
info.details.video.height = height;
|
||||
if (p_lang_node != nullptr) {
|
||||
std::memcpy(info.details.video.language_code, p_lang_node->value,
|
||||
std::min(strlen(p_lang_node->value), size_t(3)));
|
||||
}
|
||||
break;
|
||||
case SCE_AVPLAYER_AUDIO:
|
||||
}
|
||||
case SCE_AVPLAYER_AUDIO: {
|
||||
LOG_INFO(Lib_AvPlayer, "Stream {} is an audio stream.", stream_index);
|
||||
info.details.audio.channel_count = p_stream->codecpar->ch_layout.nb_channels;
|
||||
info.details.audio.sample_rate = p_stream->codecpar->sample_rate;
|
||||
@ -150,7 +158,8 @@ bool AvPlayerSource::GetStreamInfo(u32 stream_index, SceAvPlayerStreamInfo& info
|
||||
std::min(strlen(p_lang_node->value), size_t(3)));
|
||||
}
|
||||
break;
|
||||
case SCE_AVPLAYER_TIMEDTEXT:
|
||||
}
|
||||
case SCE_AVPLAYER_TIMEDTEXT: {
|
||||
LOG_WARNING(Lib_AvPlayer, "Stream {} is a timedtext stream.", stream_index);
|
||||
info.details.subs.font_size = 12;
|
||||
info.details.subs.text_size = 12;
|
||||
@ -159,10 +168,12 @@ bool AvPlayerSource::GetStreamInfo(u32 stream_index, SceAvPlayerStreamInfo& info
|
||||
std::min(strlen(p_lang_node->value), size_t(3)));
|
||||
}
|
||||
break;
|
||||
default:
|
||||
}
|
||||
default: {
|
||||
LOG_ERROR(Lib_AvPlayer, "Stream {} type is unknown: {}.", stream_index, info.type);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -189,8 +200,12 @@ bool AvPlayerSource::EnableStream(u32 stream_index) {
|
||||
LOG_ERROR(Lib_AvPlayer, "Could not open avcodec for video stream {}.", stream_index);
|
||||
return false;
|
||||
}
|
||||
const auto width = Common::AlignUp(u32(m_video_codec_context->width), 16);
|
||||
const auto height = Common::AlignUp(u32(m_video_codec_context->height), 16);
|
||||
auto width = u32(m_video_codec_context->width);
|
||||
auto height = u32(m_video_codec_context->height);
|
||||
if (!m_use_vdec2) {
|
||||
width = Common::AlignUp(width, 16);
|
||||
height = Common::AlignUp(height, 16);
|
||||
}
|
||||
const auto size = (width * height * 3) / 2;
|
||||
for (u64 index = 0; index < m_num_output_video_framebuffers; ++index) {
|
||||
m_video_buffers.Push(FrameBuffer(m_memory_replacement, 0x100, size));
|
||||
@ -316,7 +331,7 @@ bool AvPlayerSource::GetVideoData(SceAvPlayerFrameInfoEx& video_info) {
|
||||
|
||||
auto frame = m_video_frames.Pop();
|
||||
if (!frame.has_value()) {
|
||||
LOG_WARNING(Lib_AvPlayer, "Could get video frame. EOF reached.");
|
||||
LOG_TRACE(Lib_AvPlayer, "Could get video frame. EOF reached.");
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -351,7 +366,7 @@ bool AvPlayerSource::GetAudioData(SceAvPlayerFrameInfo& audio_info) {
|
||||
|
||||
auto frame = m_audio_frames.Pop();
|
||||
if (!frame.has_value()) {
|
||||
LOG_WARNING(Lib_AvPlayer, "Could get audio frame. EOF reached.");
|
||||
LOG_TRACE(Lib_AvPlayer, "Could get audio frame. EOF reached.");
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -537,9 +552,13 @@ AvPlayerSource::AVFramePtr AvPlayerSource::ConvertVideoFrame(const AVFrame& fram
|
||||
return nv12_frame;
|
||||
}
|
||||
|
||||
static void CopyNV12Data(u8* dst, const AVFrame& src) {
|
||||
const auto width = Common::AlignUp(u32(src.width), 16);
|
||||
const auto height = Common::AlignUp(u32(src.height), 16);
|
||||
static void CopyNV12Data(u8* dst, const AVFrame& src, bool use_vdec2) {
|
||||
auto width = u32(src.width);
|
||||
auto height = u32(src.height);
|
||||
if (!use_vdec2) {
|
||||
width = Common::AlignUp(width, 16);
|
||||
height = Common::AlignUp(height, 16);
|
||||
}
|
||||
|
||||
if (src.width == width) {
|
||||
std::memcpy(dst, src.data[0], src.width * src.height);
|
||||
@ -561,7 +580,7 @@ Frame AvPlayerSource::PrepareVideoFrame(FrameBuffer buffer, const AVFrame& frame
|
||||
ASSERT(frame.format == AV_PIX_FMT_NV12);
|
||||
|
||||
auto p_buffer = buffer.GetBuffer();
|
||||
CopyNV12Data(p_buffer, frame);
|
||||
CopyNV12Data(p_buffer, frame, m_use_vdec2);
|
||||
|
||||
const auto pkt_dts = u64(frame.pkt_dts) * 1000;
|
||||
const auto stream = m_avformat_context->streams[m_video_stream_index.value()];
|
||||
@ -570,8 +589,12 @@ Frame AvPlayerSource::PrepareVideoFrame(FrameBuffer buffer, const AVFrame& frame
|
||||
const auto num = time_base.num;
|
||||
const auto timestamp = (num != 0 && den > 1) ? (pkt_dts * num) / den : pkt_dts;
|
||||
|
||||
const auto width = Common::AlignUp(u32(frame.width), 16);
|
||||
const auto height = Common::AlignUp(u32(frame.height), 16);
|
||||
auto width = u32(frame.width);
|
||||
auto height = u32(frame.height);
|
||||
if (!m_use_vdec2) {
|
||||
width = Common::AlignUp(width, 16);
|
||||
height = Common::AlignUp(height, 16);
|
||||
}
|
||||
|
||||
return Frame{
|
||||
.buffer = std::move(buffer),
|
||||
@ -583,8 +606,8 @@ Frame AvPlayerSource::PrepareVideoFrame(FrameBuffer buffer, const AVFrame& frame
|
||||
{
|
||||
.video =
|
||||
{
|
||||
.width = u32(width),
|
||||
.height = u32(height),
|
||||
.width = width,
|
||||
.height = height,
|
||||
.aspect_ratio = AVRationalToF32(frame.sample_aspect_ratio),
|
||||
.crop_left_offset = u32(frame.crop_left),
|
||||
.crop_right_offset = u32(frame.crop_right + (width - frame.width)),
|
||||
|
@ -120,7 +120,7 @@ private:
|
||||
|
||||
class AvPlayerSource {
|
||||
public:
|
||||
AvPlayerSource(AvPlayerStateCallback& state);
|
||||
AvPlayerSource(AvPlayerStateCallback& state, bool use_vdec2);
|
||||
~AvPlayerSource();
|
||||
|
||||
bool Init(const SceAvPlayerInitData& init_data, std::string_view path);
|
||||
@ -168,6 +168,7 @@ private:
|
||||
Frame PrepareVideoFrame(FrameBuffer buffer, const AVFrame& frame);
|
||||
|
||||
AvPlayerStateCallback& m_state;
|
||||
bool m_use_vdec2 = false;
|
||||
|
||||
SceAvPlayerMemAllocator m_memory_replacement{};
|
||||
u32 m_num_output_video_framebuffers{};
|
||||
|
@ -130,6 +130,10 @@ AvPlayerState::~AvPlayerState() {
|
||||
m_event_queue.Clear();
|
||||
}
|
||||
|
||||
void AvPlayerState::PostInit(const SceAvPlayerPostInitData& post_init_data) {
|
||||
m_post_init_data = post_init_data;
|
||||
}
|
||||
|
||||
// Called inside GAME thread
|
||||
bool AvPlayerState::AddSource(std::string_view path, SceAvPlayerSourceType source_type) {
|
||||
if (path.empty()) {
|
||||
@ -144,7 +148,9 @@ bool AvPlayerState::AddSource(std::string_view path, SceAvPlayerSourceType sourc
|
||||
return false;
|
||||
}
|
||||
|
||||
m_up_source = std::make_unique<AvPlayerSource>(*this);
|
||||
m_up_source = std::make_unique<AvPlayerSource>(
|
||||
*this, m_post_init_data.video_decoder_init.decoderType.video_type ==
|
||||
SCE_AVPLAYER_VIDEO_DECODER_TYPE_SOFTWARE2);
|
||||
if (!m_up_source->Init(m_init_data, path)) {
|
||||
SetState(AvState::Error);
|
||||
m_up_source.reset();
|
||||
|
@ -24,6 +24,7 @@ public:
|
||||
AvPlayerState(const SceAvPlayerInitData& init_data);
|
||||
~AvPlayerState();
|
||||
|
||||
void PostInit(const SceAvPlayerPostInitData& post_init_data);
|
||||
bool AddSource(std::string_view filename, SceAvPlayerSourceType source_type);
|
||||
s32 GetStreamCount();
|
||||
bool GetStreamInfo(u32 stream_index, SceAvPlayerStreamInfo& info);
|
||||
@ -68,6 +69,7 @@ private:
|
||||
std::unique_ptr<AvPlayerSource> m_up_source;
|
||||
|
||||
SceAvPlayerInitData m_init_data{};
|
||||
SceAvPlayerPostInitData m_post_init_data{};
|
||||
SceAvPlayerEventReplacement m_event_replacement{};
|
||||
bool m_auto_start{};
|
||||
u8 m_default_language[4]{};
|
||||
|
@ -245,7 +245,7 @@ void ImeDialogUi::Draw() {
|
||||
window_size = {500.0f, 150.0f};
|
||||
}
|
||||
|
||||
CentralizeWindow();
|
||||
CentralizeNextWindow();
|
||||
SetNextWindowSize(window_size);
|
||||
SetNextWindowCollapsed(false);
|
||||
|
||||
|
@ -438,6 +438,7 @@ constexpr int ORBIS_USER_SERVICE_ERROR_BUFFER_TOO_SHORT = 0x8096000A;
|
||||
|
||||
// SystemService library
|
||||
constexpr int ORBIS_SYSTEM_SERVICE_ERROR_PARAMETER = 0x80A10003;
|
||||
constexpr int ORBIS_SYSTEM_SERVICE_ERROR_NO_EVENT = 0x80A10004;
|
||||
|
||||
// NpTrophy library
|
||||
constexpr int ORBIS_NP_TROPHY_ERROR_UNKNOWN = 0x80551600;
|
||||
|
@ -987,8 +987,12 @@ int PS4_SYSV_ABI sceNpGetNpReachabilityState() {
|
||||
}
|
||||
|
||||
int PS4_SYSV_ABI sceNpGetOnlineId(s32 userId, OrbisNpOnlineId* onlineId) {
|
||||
LOG_DEBUG(Lib_NpManager, "called returned sign out");
|
||||
return ORBIS_NP_ERROR_SIGNED_OUT;
|
||||
LOG_DEBUG(Lib_NpManager, "userId {}", userId);
|
||||
std::string name = Config::getUserName();
|
||||
// Fill the unused stuffs to 0
|
||||
memset(onlineId, 0, sizeof(*onlineId));
|
||||
strcpy(onlineId->data, name.c_str());
|
||||
return ORBIS_OK;
|
||||
}
|
||||
|
||||
int PS4_SYSV_ABI sceNpGetParentalControlInfo() {
|
||||
|
@ -1942,9 +1942,12 @@ int PS4_SYSV_ABI sceSystemServiceRaiseExceptionLocalProcess() {
|
||||
return ORBIS_OK;
|
||||
}
|
||||
|
||||
int PS4_SYSV_ABI sceSystemServiceReceiveEvent() {
|
||||
LOG_ERROR(Lib_SystemService, "(STUBBED) called");
|
||||
return ORBIS_OK;
|
||||
s32 PS4_SYSV_ABI sceSystemServiceReceiveEvent(OrbisSystemServiceEvent* event) {
|
||||
LOG_ERROR(Lib_SystemService, "(STUBBED) called, event type = {:#x}", (int)event->eventType);
|
||||
if (event == nullptr) {
|
||||
return ORBIS_SYSTEM_SERVICE_ERROR_PARAMETER;
|
||||
}
|
||||
return ORBIS_SYSTEM_SERVICE_ERROR_NO_EVENT;
|
||||
}
|
||||
|
||||
int PS4_SYSV_ABI sceSystemServiceReenableMusicPlayer() {
|
||||
|
@ -87,6 +87,32 @@ enum OrbisSystemParamLanguage {
|
||||
ORBIS_SYSTEM_PARAM_LANG_INDONESIAN = 29
|
||||
};
|
||||
|
||||
enum OrbisSystemServiceEventType {
|
||||
ORBIS_SYSTEM_SERVICE_EVENT_INVALID = -1,
|
||||
ORBIS_SYSTEM_SERVICE_EVENT_ON_RESUME = 0x10000000,
|
||||
ORBIS_SYSTEM_SERVICE_EVENT_GAME_LIVE_STREAMING_STATUS_UPDATE = 0x10000001,
|
||||
ORBIS_SYSTEM_SERVICE_EVENT_SESSION_INVITATION = 0x10000002,
|
||||
ORBIS_SYSTEM_SERVICE_EVENT_ENTITLEMENT_UPDATE = 0x10000003,
|
||||
ORBIS_SYSTEM_SERVICE_EVENT_GAME_CUSTOM_DATA = 0x10000004,
|
||||
ORBIS_SYSTEM_SERVICE_EVENT_DISPLAY_SAFE_AREA_UPDATE = 0x10000005,
|
||||
ORBIS_SYSTEM_SERVICE_EVENT_URL_OPEN = 0x10000006,
|
||||
ORBIS_SYSTEM_SERVICE_EVENT_LAUNCH_APP = 0x10000007,
|
||||
ORBIS_SYSTEM_SERVICE_EVENT_APP_LAUNCH_LINK = 0x10000008,
|
||||
ORBIS_SYSTEM_SERVICE_EVENT_ADDCONTENT_INSTALL = 0x10000009,
|
||||
ORBIS_SYSTEM_SERVICE_EVENT_RESET_VR_POSITION = 0x1000000a,
|
||||
ORBIS_SYSTEM_SERVICE_EVENT_JOIN_EVENT = 0x1000000b,
|
||||
ORBIS_SYSTEM_SERVICE_EVENT_PLAYGO_LOCUS_UPDATE = 0x1000000c,
|
||||
ORBIS_SYSTEM_SERVICE_EVENT_PLAY_TOGETHER_HOST = 0x1000000d,
|
||||
ORBIS_SYSTEM_SERVICE_EVENT_SERVICE_ENTITLEMENT_UPDATE = 0x1000000e,
|
||||
ORBIS_SYSTEM_SERVICE_EVENT_EYE_TO_EYE_DISTANCE_UPDATE = 0x1000000f,
|
||||
ORBIS_SYSTEM_SERVICE_EVENT_JOIN_MATCH_EVENT = 0x10000010,
|
||||
ORBIS_SYSTEM_SERVICE_EVENT_PLAY_TOGETHER_HOST_A = 0x10000011,
|
||||
ORBIS_SYSTEM_SERVICE_EVENT_WEBBROWSER_CLOSED = 0x10000012,
|
||||
ORBIS_SYSTEM_SERVICE_EVENT_CONTROLLER_SETTINGS_CLOSED = 0x10000013,
|
||||
ORBIS_SYSTEM_SERVICE_EVENT_JOIN_TEAM_ON_TEAM_MATCH_EVENT = 0x10000014,
|
||||
ORBIS_SYSTEM_SERVICE_EVENT_OPEN_SHARE_MENU = 0x30000000
|
||||
};
|
||||
|
||||
struct OrbisSystemServiceStatus {
|
||||
s32 eventNum;
|
||||
bool isSystemUiOverlaid;
|
||||
@ -102,6 +128,41 @@ struct OrbisSystemServiceDisplaySafeAreaInfo {
|
||||
uint8_t reserved[128];
|
||||
};
|
||||
|
||||
struct OrbisSystemServiceEvent {
|
||||
OrbisSystemServiceEventType eventType;
|
||||
union {
|
||||
char param[8192];
|
||||
struct {
|
||||
char source[1024];
|
||||
char url[4096];
|
||||
} urlOpen;
|
||||
struct {
|
||||
u32 size;
|
||||
u8 arg[8188];
|
||||
} launchApp;
|
||||
struct {
|
||||
u32 size;
|
||||
u8 arg[2020];
|
||||
} appLaunchLink;
|
||||
struct {
|
||||
s32 userId;
|
||||
char eventId[37];
|
||||
char bootArgument[7169];
|
||||
} joinEvent;
|
||||
struct {
|
||||
s32 userId;
|
||||
u32 npServiceLabel;
|
||||
u8 reserved[8184];
|
||||
} serviceEntitlementUpdate;
|
||||
struct {
|
||||
s32 userId;
|
||||
u32 npServiceLabel;
|
||||
u8 reserved[8184];
|
||||
} unifiedEntitlementUpdate;
|
||||
u8 reserved[8192];
|
||||
};
|
||||
};
|
||||
|
||||
bool IsSplashVisible();
|
||||
|
||||
int PS4_SYSV_ABI sceAppMessagingClearEventFlag();
|
||||
@ -480,7 +541,7 @@ s32 PS4_SYSV_ABI sceSystemServiceParamGetInt(int param_id, int* value);
|
||||
int PS4_SYSV_ABI sceSystemServiceParamGetString();
|
||||
int PS4_SYSV_ABI sceSystemServicePowerTick();
|
||||
int PS4_SYSV_ABI sceSystemServiceRaiseExceptionLocalProcess();
|
||||
int PS4_SYSV_ABI sceSystemServiceReceiveEvent();
|
||||
s32 PS4_SYSV_ABI sceSystemServiceReceiveEvent(OrbisSystemServiceEvent* event);
|
||||
int PS4_SYSV_ABI sceSystemServiceReenableMusicPlayer();
|
||||
int PS4_SYSV_ABI sceSystemServiceRegisterDaemon();
|
||||
int PS4_SYSV_ABI sceSystemServiceReleaseFb0();
|
||||
|
@ -100,6 +100,12 @@ Emulator::~Emulator() {
|
||||
}
|
||||
|
||||
void Emulator::Run(const std::filesystem::path& file) {
|
||||
|
||||
// Use the eboot from the separated updates folder if it's there
|
||||
std::filesystem::path game_patch_folder = file.parent_path().concat("-UPDATE");
|
||||
bool use_game_patch = std::filesystem::exists(game_patch_folder / "sce_sys");
|
||||
std::filesystem::path eboot_path = use_game_patch ? game_patch_folder / file.filename() : file;
|
||||
|
||||
// Applications expect to be run from /app0 so mount the file's parent path as app0.
|
||||
auto* mnt = Common::Singleton<Core::FileSys::MntPoints>::Instance();
|
||||
mnt->Mount(file.parent_path(), "/app0");
|
||||
@ -114,10 +120,7 @@ void Emulator::Run(const std::filesystem::path& file) {
|
||||
std::string app_version;
|
||||
u32 fw_version;
|
||||
|
||||
std::filesystem::path game_patch_folder = file.parent_path().concat("-UPDATE");
|
||||
bool use_game_patch = std::filesystem::exists(game_patch_folder / "sce_sys");
|
||||
std::filesystem::path sce_sys_folder =
|
||||
use_game_patch ? game_patch_folder / "sce_sys" : file.parent_path() / "sce_sys";
|
||||
std::filesystem::path sce_sys_folder = eboot_path.parent_path() / "sce_sys";
|
||||
if (std::filesystem::is_directory(sce_sys_folder)) {
|
||||
for (const auto& entry : std::filesystem::directory_iterator(sce_sys_folder)) {
|
||||
if (entry.path().filename() == "param.sfo") {
|
||||
@ -132,7 +135,7 @@ void Emulator::Run(const std::filesystem::path& file) {
|
||||
Common::FS::GetUserPath(Common::FS::PathType::MetaDataDir) / id / "TrophyFiles";
|
||||
if (!std::filesystem::exists(trophyDir)) {
|
||||
TRP trp;
|
||||
if (!trp.Extract(file.parent_path(), id)) {
|
||||
if (!trp.Extract(eboot_path.parent_path(), id)) {
|
||||
LOG_ERROR(Loader, "Couldn't extract trophies");
|
||||
}
|
||||
}
|
||||
@ -221,17 +224,23 @@ void Emulator::Run(const std::filesystem::path& file) {
|
||||
Libraries::InitHLELibs(&linker->GetHLESymbols());
|
||||
|
||||
// Load the module with the linker
|
||||
linker->LoadModule(file);
|
||||
linker->LoadModule(eboot_path);
|
||||
|
||||
// check if we have system modules to load
|
||||
LoadSystemModules(file);
|
||||
LoadSystemModules(eboot_path);
|
||||
|
||||
// Load all prx from game's sce_module folder
|
||||
std::filesystem::path sce_module_folder = file.parent_path() / "sce_module";
|
||||
if (std::filesystem::is_directory(sce_module_folder)) {
|
||||
for (const auto& entry : std::filesystem::directory_iterator(sce_module_folder)) {
|
||||
LOG_INFO(Loader, "Loading {}", fmt::UTF(entry.path().u8string()));
|
||||
linker->LoadModule(entry.path());
|
||||
std::filesystem::path module_path = entry.path();
|
||||
std::filesystem::path update_module_path =
|
||||
eboot_path.parent_path() / "sce_module" / entry.path().filename();
|
||||
if (std::filesystem::exists(update_module_path) && use_game_patch) {
|
||||
module_path = update_module_path;
|
||||
}
|
||||
LOG_INFO(Loader, "Loading {}", fmt::UTF(module_path.u8string()));
|
||||
linker->LoadModule(module_path);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -31,7 +31,7 @@ inline void CentralizeNextWindow() {
|
||||
}
|
||||
|
||||
inline void CentralizeWindow() {
|
||||
const auto display_size = GetIO().DisplaySize;
|
||||
const auto display_size = GetIO().DisplaySize - GetCurrentWindowRead()->SizeFull;
|
||||
SetWindowPos(display_size / 2.0f);
|
||||
}
|
||||
|
||||
@ -41,7 +41,7 @@ inline void KeepWindowInside(ImVec2 display_size = GetIO().DisplaySize) {
|
||||
SetWindowPos(ImMax(cur_pos, ImVec2(0.0f, 0.0f)));
|
||||
return;
|
||||
}
|
||||
const auto cur_size = GetWindowSize();
|
||||
const auto cur_size = GetCurrentWindowRead()->SizeFull;
|
||||
const auto bottom_right = cur_pos + cur_size;
|
||||
if (bottom_right.x > display_size.x || bottom_right.y > display_size.y) {
|
||||
const auto max_pos = display_size - cur_size;
|
||||
|
@ -26,8 +26,8 @@ public:
|
||||
GameInfo game;
|
||||
game.path = filePath;
|
||||
std::filesystem::path sce_folder_path = filePath / "sce_sys" / "param.sfo";
|
||||
std::filesystem::path game_update_path =
|
||||
std::filesystem::path(filePath.string() + "-UPDATE");
|
||||
std::filesystem::path game_update_path = filePath;
|
||||
game_update_path += "-UPDATE";
|
||||
if (std::filesystem::exists(game_update_path / "sce_sys" / "param.sfo")) {
|
||||
sce_folder_path = game_update_path / "sce_sys" / "param.sfo";
|
||||
}
|
||||
|
@ -290,19 +290,21 @@ public:
|
||||
|
||||
if (selected == deleteGame || selected == deleteUpdate || selected == deleteDLC) {
|
||||
bool error = false;
|
||||
QString folder_path, game_update_path;
|
||||
QString folder_path, game_update_path, dlc_path;
|
||||
Common::FS::PathToQString(folder_path, m_games[itemID].path);
|
||||
Common::FS::PathToQString(game_update_path, m_games[itemID].path.concat("-UPDATE"));
|
||||
Common::FS::PathToQString(
|
||||
dlc_path, Config::getAddonInstallDir() /
|
||||
Common::FS::PathFromQString(folder_path).parent_path().filename());
|
||||
QString message_type = tr("Game");
|
||||
|
||||
if (selected == deleteUpdate) {
|
||||
if (!Config::getSeparateUpdateEnabled()) {
|
||||
QMessageBox::critical(
|
||||
nullptr, tr("Error"),
|
||||
QString(tr("This feature requires the 'Enable Separate Update Folder' "
|
||||
"config option "
|
||||
"to work. If you want to use this feature, please enable it.")));
|
||||
QMessageBox::critical(nullptr, tr("Error"),
|
||||
QString(tr("requiresEnableSeparateUpdateFolder_MSG")));
|
||||
error = true;
|
||||
} else if (!std::filesystem::exists(m_games[itemID].path.concat("-UPDATE"))) {
|
||||
} else if (!std::filesystem::exists(
|
||||
Common::FS::PathFromQString(game_update_path))) {
|
||||
QMessageBox::critical(nullptr, tr("Error"),
|
||||
QString(tr("This game has no update to delete!")));
|
||||
error = true;
|
||||
@ -311,15 +313,12 @@ public:
|
||||
message_type = tr("Update");
|
||||
}
|
||||
} else if (selected == deleteDLC) {
|
||||
std::filesystem::path addon_path =
|
||||
Config::getAddonInstallDir() /
|
||||
Common::FS::PathFromQString(folder_path).parent_path().filename();
|
||||
if (!std::filesystem::exists(addon_path)) {
|
||||
if (!std::filesystem::exists(Common::FS::PathFromQString(dlc_path))) {
|
||||
QMessageBox::critical(nullptr, tr("Error"),
|
||||
QString(tr("This game has no DLC to delete!")));
|
||||
error = true;
|
||||
} else {
|
||||
folder_path = QString::fromStdString(addon_path.string());
|
||||
folder_path = dlc_path;
|
||||
message_type = tr("DLC");
|
||||
}
|
||||
}
|
||||
|
@ -678,13 +678,10 @@ void MainWindow::InstallDragDropPkg(std::filesystem::path file, int pkgNum, int
|
||||
auto game_install_dir = ids.getSelectedDirectory();
|
||||
auto game_folder_path = game_install_dir / pkg.GetTitleID();
|
||||
QString pkgType = QString::fromStdString(pkg.GetPkgFlags());
|
||||
bool use_game_update = pkgType.contains("Patch") && Config::getSeparateUpdateEnabled();
|
||||
bool use_game_update = pkgType.contains("PATCH") && Config::getSeparateUpdateEnabled();
|
||||
auto game_update_path = use_game_update
|
||||
? game_install_dir / (std::string(pkg.GetTitleID()) + "-UPDATE")
|
||||
: game_folder_path;
|
||||
if (!std::filesystem::exists(game_update_path)) {
|
||||
std::filesystem::create_directory(game_update_path);
|
||||
}
|
||||
QString gameDirPath;
|
||||
Common::FS::PathToQString(gameDirPath, game_folder_path);
|
||||
QDir game_dir(gameDirPath);
|
||||
@ -792,8 +789,6 @@ void MainWindow::InstallDragDropPkg(std::filesystem::path file, int pkgNum, int
|
||||
}
|
||||
}
|
||||
} else {
|
||||
QString gameDirPath;
|
||||
Common::FS::PathToQString(gameDirPath, game_folder_path);
|
||||
msgBox.setText(QString(tr("Game already installed") + "\n" + gameDirPath + "\n" +
|
||||
tr("Would you like to overwrite?")));
|
||||
msgBox.setStandardButtons(QMessageBox::Yes | QMessageBox::No);
|
||||
|
@ -127,15 +127,15 @@ SettingsDialog::SettingsDialog(std::span<const QString> physical_devices, QWidge
|
||||
connect(ui->fullscreenCheckBox, &QCheckBox::stateChanged, this,
|
||||
[](int val) { Config::setFullscreenMode(val); });
|
||||
|
||||
connect(ui->separateUpdatesCheckBox, &QCheckBox::stateChanged, this,
|
||||
[](int val) { Config::setSeparateUpdateEnabled(val); });
|
||||
|
||||
connect(ui->showSplashCheckBox, &QCheckBox::stateChanged, this,
|
||||
[](int val) { Config::setShowSplash(val); });
|
||||
|
||||
connect(ui->ps4proCheckBox, &QCheckBox::stateChanged, this,
|
||||
[](int val) { Config::setNeoMode(val); });
|
||||
|
||||
connect(ui->separateUpdatesCheckBox, &QCheckBox::stateChanged, this,
|
||||
[](int val) { Config::setSeparateUpdateEnabled(val); });
|
||||
|
||||
connect(ui->logTypeComboBox, &QComboBox::currentTextChanged, this,
|
||||
[](const QString& text) { Config::setLogType(text.toStdString()); });
|
||||
|
||||
@ -270,10 +270,10 @@ SettingsDialog::SettingsDialog(std::span<const QString> physical_devices, QWidge
|
||||
ui->consoleLanguageGroupBox->installEventFilter(this);
|
||||
ui->emulatorLanguageGroupBox->installEventFilter(this);
|
||||
ui->fullscreenCheckBox->installEventFilter(this);
|
||||
ui->separateUpdatesCheckBox->installEventFilter(this);
|
||||
ui->showSplashCheckBox->installEventFilter(this);
|
||||
ui->ps4proCheckBox->installEventFilter(this);
|
||||
ui->discordRPCCheckbox->installEventFilter(this);
|
||||
ui->separateUpdatesCheckBox->installEventFilter(this);
|
||||
ui->userName->installEventFilter(this);
|
||||
ui->logTypeGroupBox->installEventFilter(this);
|
||||
ui->logFilter->installEventFilter(this);
|
||||
@ -327,12 +327,12 @@ void SettingsDialog::LoadValuesFromConfig() {
|
||||
ui->BGMVolumeSlider->setValue((Config::getBGMvolume()));
|
||||
ui->discordRPCCheckbox->setChecked(Config::getEnableDiscordRPC());
|
||||
ui->fullscreenCheckBox->setChecked(Config::isFullscreenMode());
|
||||
ui->separateUpdatesCheckBox->setChecked(Config::getSeparateUpdateEnabled());
|
||||
ui->showSplashCheckBox->setChecked(Config::showSplash());
|
||||
ui->ps4proCheckBox->setChecked(Config::isNeoMode());
|
||||
ui->logTypeComboBox->setCurrentText(QString::fromStdString(Config::getLogType()));
|
||||
ui->logFilterLineEdit->setText(QString::fromStdString(Config::getLogFilter()));
|
||||
ui->userNameLineEdit->setText(QString::fromStdString(Config::getUserName()));
|
||||
ui->separateUpdatesCheckBox->setChecked(Config::getSeparateUpdateEnabled());
|
||||
|
||||
ui->debugDump->setChecked(Config::debugDump());
|
||||
ui->vkValidationCheckBox->setChecked(Config::vkValidationEnabled());
|
||||
@ -436,14 +436,14 @@ void SettingsDialog::updateNoteTextEdit(const QString& elementName) {
|
||||
text = tr("emulatorLanguageGroupBox");
|
||||
} else if (elementName == "fullscreenCheckBox") {
|
||||
text = tr("fullscreenCheckBox");
|
||||
} else if (elementName == "separateUpdatesCheckBox") {
|
||||
text = tr("separateUpdatesCheckBox");
|
||||
} else if (elementName == "showSplashCheckBox") {
|
||||
text = tr("showSplashCheckBox");
|
||||
} else if (elementName == "ps4proCheckBox") {
|
||||
text = tr("ps4proCheckBox");
|
||||
} else if (elementName == "discordRPCCheckbox") {
|
||||
text = tr("discordRPCCheckbox");
|
||||
} else if (elementName == "separateUpdatesCheckBox") {
|
||||
text = tr("separateUpdatesCheckBox");
|
||||
} else if (elementName == "userName") {
|
||||
text = tr("userName");
|
||||
} else if (elementName == "logTypeGroupBox") {
|
||||
|
@ -12,7 +12,7 @@
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>854</width>
|
||||
<height>630</height>
|
||||
<height>660</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="sizePolicy">
|
||||
|
@ -140,6 +140,26 @@
|
||||
<source>Copy All</source>
|
||||
<translation>نسخ الكل</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui_context_menus.h" line="72"/>
|
||||
<source>Delete...</source>
|
||||
<translation>Delete...</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui_context_menus.h" line="73"/>
|
||||
<source>Delete Game</source>
|
||||
<translation>Delete Game</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui_context_menus.h" line="74"/>
|
||||
<source>Delete Update</source>
|
||||
<translation>Delete Update</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui_context_menus.h" line="75"/>
|
||||
<source>Delete DLC</source>
|
||||
<translation>Delete DLC</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui_context_menus.h" line="195"/>
|
||||
<source>Shortcut creation</source>
|
||||
@ -165,6 +185,46 @@
|
||||
<source>Install PKG</source>
|
||||
<translation>PKG تثبيت</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui_context_menus.h" line="299"/>
|
||||
<source>Game</source>
|
||||
<translation>Game</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui_context_menus.h" line="305"/>
|
||||
<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>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui_context_menus.h" line="312"/>
|
||||
<source>This game has no update to delete!</source>
|
||||
<translation>This game has no update to delete!</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui_context_menus.h" line="316"/>
|
||||
<source>Update</source>
|
||||
<translation>Update</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui_context_menus.h" line="321"/>
|
||||
<source>This game has no DLC to delete!</source>
|
||||
<translation>This game has no DLC to delete!</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui_context_menus.h" line="325"/>
|
||||
<source>DLC</source>
|
||||
<translation>DLC</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui_context_menus.h" line="332"/>
|
||||
<source>Delete %1</source>
|
||||
<translation>Delete %1</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui_context_menus.h" line="333"/>
|
||||
<source>Are you sure you want to delete %1's %2 directory?</source>
|
||||
<translation>Are you sure you want to delete %1's %2 directory?</translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>MainWindow</name>
|
||||
@ -417,6 +477,11 @@
|
||||
<source>Enable Fullscreen</source>
|
||||
<translation>تمكين ملء الشاشة</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../settings_dialog.ui" line="140"/>
|
||||
<source>Enable Separate Update Folder</source>
|
||||
<translation>Enable Separate Update Folder</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../settings_dialog.ui" line="129"/>
|
||||
<source>Show Splash</source>
|
||||
@ -1056,6 +1121,11 @@
|
||||
<source>fullscreenCheckBox</source>
|
||||
<translation>تمكين وضع ملء الشاشة:\nيجعل نافذة اللعبة تنتقل تلقائيًا إلى وضع ملء الشاشة.\nيمكن التبديل بالضغط على المفتاح F11.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../settings_dialog.cpp" line="293"/>
|
||||
<source>separateUpdatesCheckBox</source>
|
||||
<translation>Enable Separate Update Folder:\nEnables installing game updates into a separate folder for easy management.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../settings_dialog.cpp" line="295"/>
|
||||
<source>showSplashCheckBox</source>
|
||||
|
@ -140,6 +140,26 @@
|
||||
<source>Copy All</source>
|
||||
<translation>Copy All</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui_context_menus.h" line="72"/>
|
||||
<source>Delete...</source>
|
||||
<translation>Delete...</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui_context_menus.h" line="73"/>
|
||||
<source>Delete Game</source>
|
||||
<translation>Delete Game</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui_context_menus.h" line="74"/>
|
||||
<source>Delete Update</source>
|
||||
<translation>Delete Update</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui_context_menus.h" line="75"/>
|
||||
<source>Delete DLC</source>
|
||||
<translation>Delete DLC</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui_context_menus.h" line="195"/>
|
||||
<source>Shortcut creation</source>
|
||||
@ -165,6 +185,46 @@
|
||||
<source>Install PKG</source>
|
||||
<translation>Install PKG</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui_context_menus.h" line="299"/>
|
||||
<source>Game</source>
|
||||
<translation>Game</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui_context_menus.h" line="305"/>
|
||||
<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>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui_context_menus.h" line="312"/>
|
||||
<source>This game has no update to delete!</source>
|
||||
<translation>This game has no update to delete!</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui_context_menus.h" line="316"/>
|
||||
<source>Update</source>
|
||||
<translation>Update</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui_context_menus.h" line="321"/>
|
||||
<source>This game has no DLC to delete!</source>
|
||||
<translation>This game has no DLC to delete!</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui_context_menus.h" line="325"/>
|
||||
<source>DLC</source>
|
||||
<translation>DLC</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui_context_menus.h" line="332"/>
|
||||
<source>Delete %1</source>
|
||||
<translation>Delete %1</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui_context_menus.h" line="333"/>
|
||||
<source>Are you sure you want to delete %1's %2 directory?</source>
|
||||
<translation>Are you sure you want to delete %1's %2 directory?</translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>MainWindow</name>
|
||||
@ -417,6 +477,11 @@
|
||||
<source>Enable Fullscreen</source>
|
||||
<translation>Enable Fullscreen</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../settings_dialog.ui" line="140"/>
|
||||
<source>Enable Separate Update Folder</source>
|
||||
<translation>Enable Separate Update Folder</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../settings_dialog.ui" line="129"/>
|
||||
<source>Show Splash</source>
|
||||
@ -1056,6 +1121,11 @@
|
||||
<source>fullscreenCheckBox</source>
|
||||
<translation>Aktiver fuld skærm:\nSætter automatisk spilvinduet i fuld skærm.\nDette kan skiftes ved at trykke på F11-tasten.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../settings_dialog.cpp" line="293"/>
|
||||
<source>separateUpdatesCheckBox</source>
|
||||
<translation>Enable Separate Update Folder:\nEnables installing game updates into a separate folder for easy management.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../settings_dialog.cpp" line="295"/>
|
||||
<source>showSplashCheckBox</source>
|
||||
|
@ -140,6 +140,26 @@
|
||||
<source>Copy All</source>
|
||||
<translation>Alles kopieren</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui_context_menus.h" line="72"/>
|
||||
<source>Delete...</source>
|
||||
<translation>Delete...</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui_context_menus.h" line="73"/>
|
||||
<source>Delete Game</source>
|
||||
<translation>Delete Game</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui_context_menus.h" line="74"/>
|
||||
<source>Delete Update</source>
|
||||
<translation>Delete Update</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui_context_menus.h" line="75"/>
|
||||
<source>Delete DLC</source>
|
||||
<translation>Delete DLC</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui_context_menus.h" line="195"/>
|
||||
<source>Shortcut creation</source>
|
||||
@ -165,6 +185,46 @@
|
||||
<source>Install PKG</source>
|
||||
<translation>PKG installieren</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui_context_menus.h" line="299"/>
|
||||
<source>Game</source>
|
||||
<translation>Game</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui_context_menus.h" line="305"/>
|
||||
<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>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui_context_menus.h" line="312"/>
|
||||
<source>This game has no update to delete!</source>
|
||||
<translation>This game has no update to delete!</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui_context_menus.h" line="316"/>
|
||||
<source>Update</source>
|
||||
<translation>Update</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui_context_menus.h" line="321"/>
|
||||
<source>This game has no DLC to delete!</source>
|
||||
<translation>This game has no DLC to delete!</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui_context_menus.h" line="325"/>
|
||||
<source>DLC</source>
|
||||
<translation>DLC</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui_context_menus.h" line="332"/>
|
||||
<source>Delete %1</source>
|
||||
<translation>Delete %1</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui_context_menus.h" line="333"/>
|
||||
<source>Are you sure you want to delete %1's %2 directory?</source>
|
||||
<translation>Are you sure you want to delete %1's %2 directory?</translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>MainWindow</name>
|
||||
@ -417,6 +477,11 @@
|
||||
<source>Enable Fullscreen</source>
|
||||
<translation>Vollbild aktivieren</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../settings_dialog.ui" line="140"/>
|
||||
<source>Enable Separate Update Folder</source>
|
||||
<translation>Enable Separate Update Folder</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../settings_dialog.ui" line="129"/>
|
||||
<source>Show Splash</source>
|
||||
@ -1056,6 +1121,11 @@
|
||||
<source>fullscreenCheckBox</source>
|
||||
<translation>Vollbildmodus aktivieren:\nSchaltet das Spielfenster automatisch in den Vollbildmodus.\nKann durch Drücken der F11-Taste umgeschaltet werden.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../settings_dialog.cpp" line="293"/>
|
||||
<source>separateUpdatesCheckBox</source>
|
||||
<translation>Enable Separate Update Folder:\nEnables installing game updates into a separate folder for easy management.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../settings_dialog.cpp" line="295"/>
|
||||
<source>showSplashCheckBox</source>
|
||||
|
@ -140,6 +140,26 @@
|
||||
<source>Copy All</source>
|
||||
<translation>Copy All</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui_context_menus.h" line="72"/>
|
||||
<source>Delete...</source>
|
||||
<translation>Delete...</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui_context_menus.h" line="73"/>
|
||||
<source>Delete Game</source>
|
||||
<translation>Delete Game</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui_context_menus.h" line="74"/>
|
||||
<source>Delete Update</source>
|
||||
<translation>Delete Update</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui_context_menus.h" line="75"/>
|
||||
<source>Delete DLC</source>
|
||||
<translation>Delete DLC</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui_context_menus.h" line="195"/>
|
||||
<source>Shortcut creation</source>
|
||||
@ -165,6 +185,46 @@
|
||||
<source>Install PKG</source>
|
||||
<translation>Install PKG</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui_context_menus.h" line="299"/>
|
||||
<source>Game</source>
|
||||
<translation>Game</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui_context_menus.h" line="305"/>
|
||||
<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>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui_context_menus.h" line="312"/>
|
||||
<source>This game has no update to delete!</source>
|
||||
<translation>This game has no update to delete!</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui_context_menus.h" line="316"/>
|
||||
<source>Update</source>
|
||||
<translation>Update</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui_context_menus.h" line="321"/>
|
||||
<source>This game has no DLC to delete!</source>
|
||||
<translation>This game has no DLC to delete!</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui_context_menus.h" line="325"/>
|
||||
<source>DLC</source>
|
||||
<translation>DLC</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui_context_menus.h" line="332"/>
|
||||
<source>Delete %1</source>
|
||||
<translation>Delete %1</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui_context_menus.h" line="333"/>
|
||||
<source>Are you sure you want to delete %1's %2 directory?</source>
|
||||
<translation>Are you sure you want to delete %1's %2 directory?</translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>MainWindow</name>
|
||||
@ -417,6 +477,11 @@
|
||||
<source>Enable Fullscreen</source>
|
||||
<translation>Enable Fullscreen</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../settings_dialog.ui" line="140"/>
|
||||
<source>Enable Separate Update Folder</source>
|
||||
<translation>Enable Separate Update Folder</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../settings_dialog.ui" line="129"/>
|
||||
<source>Show Splash</source>
|
||||
@ -1056,6 +1121,11 @@
|
||||
<source>fullscreenCheckBox</source>
|
||||
<translation>Ενεργοποίηση Πλήρους Οθόνης:\nΑυτόματα μετατρέπει το παράθυρο του παιχνιδιού σε λειτουργία πλήρους οθόνης.\nΜπορεί να ενεργοποιηθεί/απενεργοποιηθεί πατώντας το πλήκτρο F11.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../settings_dialog.cpp" line="293"/>
|
||||
<source>separateUpdatesCheckBox</source>
|
||||
<translation>Enable Separate Update Folder:\nEnables installing game updates into a separate folder for easy management.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../settings_dialog.cpp" line="295"/>
|
||||
<source>showSplashCheckBox</source>
|
||||
|
@ -140,6 +140,26 @@
|
||||
<source>Copy All</source>
|
||||
<translation>Copy All</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui_context_menus.h" line="72"/>
|
||||
<source>Delete...</source>
|
||||
<translation>Delete...</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui_context_menus.h" line="73"/>
|
||||
<source>Delete Game</source>
|
||||
<translation>Delete Game</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui_context_menus.h" line="74"/>
|
||||
<source>Delete Update</source>
|
||||
<translation>Delete Update</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui_context_menus.h" line="75"/>
|
||||
<source>Delete DLC</source>
|
||||
<translation>Delete DLC</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui_context_menus.h" line="195"/>
|
||||
<source>Shortcut creation</source>
|
||||
@ -165,6 +185,46 @@
|
||||
<source>Install PKG</source>
|
||||
<translation>Install PKG</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui_context_menus.h" line="299"/>
|
||||
<source>Game</source>
|
||||
<translation>Game</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui_context_menus.h" line="305"/>
|
||||
<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>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui_context_menus.h" line="312"/>
|
||||
<source>This game has no update to delete!</source>
|
||||
<translation>This game has no update to delete!</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui_context_menus.h" line="316"/>
|
||||
<source>Update</source>
|
||||
<translation>Update</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui_context_menus.h" line="321"/>
|
||||
<source>This game has no DLC to delete!</source>
|
||||
<translation>This game has no DLC to delete!</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui_context_menus.h" line="325"/>
|
||||
<source>DLC</source>
|
||||
<translation>DLC</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui_context_menus.h" line="332"/>
|
||||
<source>Delete %1</source>
|
||||
<translation>Delete %1</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui_context_menus.h" line="333"/>
|
||||
<source>Are you sure you want to delete %1's %2 directory?</source>
|
||||
<translation>Are you sure you want to delete %1's %2 directory?</translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>MainWindow</name>
|
||||
@ -417,6 +477,11 @@
|
||||
<source>Enable Fullscreen</source>
|
||||
<translation>Enable Fullscreen</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../settings_dialog.ui" line="140"/>
|
||||
<source>Enable Separate Update Folder</source>
|
||||
<translation>Enable Separate Update Folder</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../settings_dialog.ui" line="129"/>
|
||||
<source>Show Splash</source>
|
||||
@ -1056,6 +1121,11 @@
|
||||
<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>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../settings_dialog.cpp" line="293"/>
|
||||
<source>separateUpdatesCheckBox</source>
|
||||
<translation>Enable Separate Update Folder:\nEnables installing game updates into a separate folder for easy management.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../settings_dialog.cpp" line="295"/>
|
||||
<source>showSplashCheckBox</source>
|
||||
|
@ -140,6 +140,26 @@
|
||||
<source>Copy All</source>
|
||||
<translation>Copiar todo</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui_context_menus.h" line="72"/>
|
||||
<source>Delete...</source>
|
||||
<translation>Delete...</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui_context_menus.h" line="73"/>
|
||||
<source>Delete Game</source>
|
||||
<translation>Delete Game</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui_context_menus.h" line="74"/>
|
||||
<source>Delete Update</source>
|
||||
<translation>Delete Update</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui_context_menus.h" line="75"/>
|
||||
<source>Delete DLC</source>
|
||||
<translation>Delete DLC</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui_context_menus.h" line="195"/>
|
||||
<source>Shortcut creation</source>
|
||||
@ -165,6 +185,46 @@
|
||||
<source>Install PKG</source>
|
||||
<translation>Instalar PKG</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui_context_menus.h" line="299"/>
|
||||
<source>Game</source>
|
||||
<translation>Game</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui_context_menus.h" line="305"/>
|
||||
<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>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui_context_menus.h" line="312"/>
|
||||
<source>This game has no update to delete!</source>
|
||||
<translation>This game has no update to delete!</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui_context_menus.h" line="316"/>
|
||||
<source>Update</source>
|
||||
<translation>Update</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui_context_menus.h" line="321"/>
|
||||
<source>This game has no DLC to delete!</source>
|
||||
<translation>This game has no DLC to delete!</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui_context_menus.h" line="325"/>
|
||||
<source>DLC</source>
|
||||
<translation>DLC</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui_context_menus.h" line="332"/>
|
||||
<source>Delete %1</source>
|
||||
<translation>Delete %1</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui_context_menus.h" line="333"/>
|
||||
<source>Are you sure you want to delete %1's %2 directory?</source>
|
||||
<translation>Are you sure you want to delete %1's %2 directory?</translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>MainWindow</name>
|
||||
@ -417,6 +477,11 @@
|
||||
<source>Enable Fullscreen</source>
|
||||
<translation>Habilitar pantalla completa</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../settings_dialog.ui" line="140"/>
|
||||
<source>Enable Separate Update Folder</source>
|
||||
<translation>Enable Separate Update Folder</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../settings_dialog.ui" line="129"/>
|
||||
<source>Show Splash</source>
|
||||
@ -1056,6 +1121,11 @@
|
||||
<source>fullscreenCheckBox</source>
|
||||
<translation>Habilitar Pantalla Completa:\nColoca automáticamente la ventana del juego en modo de pantalla completa.\nEsto se puede alternar presionando la tecla F11.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../settings_dialog.cpp" line="293"/>
|
||||
<source>separateUpdatesCheckBox</source>
|
||||
<translation>Enable Separate Update Folder:\nEnables installing game updates into a separate folder for easy management.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../settings_dialog.cpp" line="295"/>
|
||||
<source>showSplashCheckBox</source>
|
||||
|
@ -140,6 +140,26 @@
|
||||
<source>Copy All</source>
|
||||
<translation>کپی کردن تمامی مقادیر</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui_context_menus.h" line="72"/>
|
||||
<source>Delete...</source>
|
||||
<translation>Delete...</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui_context_menus.h" line="73"/>
|
||||
<source>Delete Game</source>
|
||||
<translation>Delete Game</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui_context_menus.h" line="74"/>
|
||||
<source>Delete Update</source>
|
||||
<translation>Delete Update</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui_context_menus.h" line="75"/>
|
||||
<source>Delete DLC</source>
|
||||
<translation>Delete DLC</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui_context_menus.h" line="173"/>
|
||||
<source>Shortcut creation</source>
|
||||
@ -165,6 +185,46 @@
|
||||
<source>Install PKG</source>
|
||||
<translation>نصب PKG</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui_context_menus.h" line="299"/>
|
||||
<source>Game</source>
|
||||
<translation>Game</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui_context_menus.h" line="305"/>
|
||||
<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>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui_context_menus.h" line="312"/>
|
||||
<source>This game has no update to delete!</source>
|
||||
<translation>This game has no update to delete!</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui_context_menus.h" line="316"/>
|
||||
<source>Update</source>
|
||||
<translation>Update</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui_context_menus.h" line="321"/>
|
||||
<source>This game has no DLC to delete!</source>
|
||||
<translation>This game has no DLC to delete!</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui_context_menus.h" line="325"/>
|
||||
<source>DLC</source>
|
||||
<translation>DLC</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui_context_menus.h" line="332"/>
|
||||
<source>Delete %1</source>
|
||||
<translation>Delete %1</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui_context_menus.h" line="333"/>
|
||||
<source>Are you sure you want to delete %1's %2 directory?</source>
|
||||
<translation>Are you sure you want to delete %1's %2 directory?</translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>MainWindow</name>
|
||||
@ -417,6 +477,11 @@
|
||||
<source>Enable Fullscreen</source>
|
||||
<translation>تمام صفحه</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../settings_dialog.ui" line="140"/>
|
||||
<source>Enable Separate Update Folder</source>
|
||||
<translation>Enable Separate Update Folder</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../settings_dialog.ui" line="129"/>
|
||||
<source>Show Splash</source>
|
||||
@ -1056,6 +1121,11 @@
|
||||
<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>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../settings_dialog.cpp" line="293"/>
|
||||
<source>separateUpdatesCheckBox</source>
|
||||
<translation>Enable Separate Update Folder:\nEnables installing game updates into a separate folder for easy management.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../settings_dialog.cpp" line="295"/>
|
||||
<source>showSplashCheckBox</source>
|
||||
|
@ -140,6 +140,26 @@
|
||||
<source>Copy All</source>
|
||||
<translation>Copy All</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui_context_menus.h" line="72"/>
|
||||
<source>Delete...</source>
|
||||
<translation>Delete...</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui_context_menus.h" line="73"/>
|
||||
<source>Delete Game</source>
|
||||
<translation>Delete Game</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui_context_menus.h" line="74"/>
|
||||
<source>Delete Update</source>
|
||||
<translation>Delete Update</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui_context_menus.h" line="75"/>
|
||||
<source>Delete DLC</source>
|
||||
<translation>Delete DLC</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui_context_menus.h" line="195"/>
|
||||
<source>Shortcut creation</source>
|
||||
@ -165,6 +185,46 @@
|
||||
<source>Install PKG</source>
|
||||
<translation>Install PKG</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui_context_menus.h" line="299"/>
|
||||
<source>Game</source>
|
||||
<translation>Game</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui_context_menus.h" line="305"/>
|
||||
<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>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui_context_menus.h" line="312"/>
|
||||
<source>This game has no update to delete!</source>
|
||||
<translation>This game has no update to delete!</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui_context_menus.h" line="316"/>
|
||||
<source>Update</source>
|
||||
<translation>Update</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui_context_menus.h" line="321"/>
|
||||
<source>This game has no DLC to delete!</source>
|
||||
<translation>This game has no DLC to delete!</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui_context_menus.h" line="325"/>
|
||||
<source>DLC</source>
|
||||
<translation>DLC</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui_context_menus.h" line="332"/>
|
||||
<source>Delete %1</source>
|
||||
<translation>Delete %1</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui_context_menus.h" line="333"/>
|
||||
<source>Are you sure you want to delete %1's %2 directory?</source>
|
||||
<translation>Are you sure you want to delete %1's %2 directory?</translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>MainWindow</name>
|
||||
@ -417,6 +477,11 @@
|
||||
<source>Enable Fullscreen</source>
|
||||
<translation>Enable Fullscreen</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../settings_dialog.ui" line="140"/>
|
||||
<source>Enable Separate Update Folder</source>
|
||||
<translation>Enable Separate Update Folder</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../settings_dialog.ui" line="129"/>
|
||||
<source>Show Splash</source>
|
||||
@ -1056,6 +1121,11 @@
|
||||
<source>fullscreenCheckBox</source>
|
||||
<translation>Ota Täysikokoisuus käyttöön:\nSiirtää pelin ikkunan automaattisesti täysikokoiseen tilaan.\nTätä voidaan vaihtaa painamalla F11-näppäintä.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../settings_dialog.cpp" line="293"/>
|
||||
<source>separateUpdatesCheckBox</source>
|
||||
<translation>Enable Separate Update Folder:\nEnables installing game updates into a separate folder for easy management.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../settings_dialog.cpp" line="295"/>
|
||||
<source>showSplashCheckBox</source>
|
||||
|
@ -140,6 +140,26 @@
|
||||
<source>Copy All</source>
|
||||
<translation>Copier tout</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui_context_menus.h" line="72"/>
|
||||
<source>Delete...</source>
|
||||
<translation>Delete...</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui_context_menus.h" line="73"/>
|
||||
<source>Delete Game</source>
|
||||
<translation>Delete Game</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui_context_menus.h" line="74"/>
|
||||
<source>Delete Update</source>
|
||||
<translation>Delete Update</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui_context_menus.h" line="75"/>
|
||||
<source>Delete DLC</source>
|
||||
<translation>Delete DLC</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui_context_menus.h" line="195"/>
|
||||
<source>Shortcut creation</source>
|
||||
@ -165,6 +185,46 @@
|
||||
<source>Install PKG</source>
|
||||
<translation>Installer un PKG</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui_context_menus.h" line="299"/>
|
||||
<source>Game</source>
|
||||
<translation>Game</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui_context_menus.h" line="305"/>
|
||||
<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>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui_context_menus.h" line="312"/>
|
||||
<source>This game has no update to delete!</source>
|
||||
<translation>This game has no update to delete!</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui_context_menus.h" line="316"/>
|
||||
<source>Update</source>
|
||||
<translation>Update</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui_context_menus.h" line="321"/>
|
||||
<source>This game has no DLC to delete!</source>
|
||||
<translation>This game has no DLC to delete!</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui_context_menus.h" line="325"/>
|
||||
<source>DLC</source>
|
||||
<translation>DLC</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui_context_menus.h" line="332"/>
|
||||
<source>Delete %1</source>
|
||||
<translation>Delete %1</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui_context_menus.h" line="333"/>
|
||||
<source>Are you sure you want to delete %1's %2 directory?</source>
|
||||
<translation>Are you sure you want to delete %1's %2 directory?</translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>MainWindow</name>
|
||||
@ -417,6 +477,11 @@
|
||||
<source>Enable Fullscreen</source>
|
||||
<translation>Plein écran</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../settings_dialog.ui" line="140"/>
|
||||
<source>Enable Separate Update Folder</source>
|
||||
<translation>Enable Separate Update Folder</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../settings_dialog.ui" line="129"/>
|
||||
<source>Show Splash</source>
|
||||
@ -1056,6 +1121,11 @@
|
||||
<source>fullscreenCheckBox</source>
|
||||
<translation>Activer le mode plein écran:\nMet automatiquement la fenêtre du jeu en mode plein écran.\nCela peut être activé en appuyant sur la touche F11.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../settings_dialog.cpp" line="293"/>
|
||||
<source>separateUpdatesCheckBox</source>
|
||||
<translation>Enable Separate Update Folder:\nEnables installing game updates into a separate folder for easy management.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../settings_dialog.cpp" line="295"/>
|
||||
<source>showSplashCheckBox</source>
|
||||
|
@ -140,6 +140,26 @@
|
||||
<source>Copy All</source>
|
||||
<translation>Összes Másolása</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui_context_menus.h" line="72"/>
|
||||
<source>Delete...</source>
|
||||
<translation>Delete...</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui_context_menus.h" line="73"/>
|
||||
<source>Delete Game</source>
|
||||
<translation>Delete Game</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui_context_menus.h" line="74"/>
|
||||
<source>Delete Update</source>
|
||||
<translation>Delete Update</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui_context_menus.h" line="75"/>
|
||||
<source>Delete DLC</source>
|
||||
<translation>Delete DLC</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui_context_menus.h" line="173"/>
|
||||
<source>Shortcut creation</source>
|
||||
@ -165,6 +185,46 @@
|
||||
<source>Install PKG</source>
|
||||
<translation>PKG telepítése</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui_context_menus.h" line="299"/>
|
||||
<source>Game</source>
|
||||
<translation>Game</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui_context_menus.h" line="305"/>
|
||||
<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>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui_context_menus.h" line="312"/>
|
||||
<source>This game has no update to delete!</source>
|
||||
<translation>This game has no update to delete!</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui_context_menus.h" line="316"/>
|
||||
<source>Update</source>
|
||||
<translation>Update</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui_context_menus.h" line="321"/>
|
||||
<source>This game has no DLC to delete!</source>
|
||||
<translation>This game has no DLC to delete!</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui_context_menus.h" line="325"/>
|
||||
<source>DLC</source>
|
||||
<translation>DLC</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui_context_menus.h" line="332"/>
|
||||
<source>Delete %1</source>
|
||||
<translation>Delete %1</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui_context_menus.h" line="333"/>
|
||||
<source>Are you sure you want to delete %1's %2 directory?</source>
|
||||
<translation>Are you sure you want to delete %1's %2 directory?</translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>MainWindow</name>
|
||||
@ -417,6 +477,11 @@
|
||||
<source>Enable Fullscreen</source>
|
||||
<translation>Teljesképernyő Engedélyezése</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../settings_dialog.ui" line="140"/>
|
||||
<source>Enable Separate Update Folder</source>
|
||||
<translation>Enable Separate Update Folder</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../settings_dialog.ui" line="129"/>
|
||||
<source>Show Splash</source>
|
||||
@ -1056,6 +1121,11 @@
|
||||
<source>fullscreenCheckBox</source>
|
||||
<translation>Teljes képernyő engedélyezése:\nAutomatikusan teljes képernyőre állítja a játék ablakát.\nEz a F11 billentyű megnyomásával kapcsolható ki/be.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../settings_dialog.cpp" line="293"/>
|
||||
<source>separateUpdatesCheckBox</source>
|
||||
<translation>Enable Separate Update Folder:\nEnables installing game updates into a separate folder for easy management.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../settings_dialog.cpp" line="295"/>
|
||||
<source>showSplashCheckBox</source>
|
||||
|
@ -140,6 +140,26 @@
|
||||
<source>Copy All</source>
|
||||
<translation>Copy All</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui_context_menus.h" line="72"/>
|
||||
<source>Delete...</source>
|
||||
<translation>Delete...</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui_context_menus.h" line="73"/>
|
||||
<source>Delete Game</source>
|
||||
<translation>Delete Game</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui_context_menus.h" line="74"/>
|
||||
<source>Delete Update</source>
|
||||
<translation>Delete Update</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui_context_menus.h" line="75"/>
|
||||
<source>Delete DLC</source>
|
||||
<translation>Delete DLC</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui_context_menus.h" line="195"/>
|
||||
<source>Shortcut creation</source>
|
||||
@ -165,6 +185,46 @@
|
||||
<source>Install PKG</source>
|
||||
<translation>Install PKG</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui_context_menus.h" line="299"/>
|
||||
<source>Game</source>
|
||||
<translation>Game</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui_context_menus.h" line="305"/>
|
||||
<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>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui_context_menus.h" line="312"/>
|
||||
<source>This game has no update to delete!</source>
|
||||
<translation>This game has no update to delete!</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui_context_menus.h" line="316"/>
|
||||
<source>Update</source>
|
||||
<translation>Update</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui_context_menus.h" line="321"/>
|
||||
<source>This game has no DLC to delete!</source>
|
||||
<translation>This game has no DLC to delete!</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui_context_menus.h" line="325"/>
|
||||
<source>DLC</source>
|
||||
<translation>DLC</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui_context_menus.h" line="332"/>
|
||||
<source>Delete %1</source>
|
||||
<translation>Delete %1</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui_context_menus.h" line="333"/>
|
||||
<source>Are you sure you want to delete %1's %2 directory?</source>
|
||||
<translation>Are you sure you want to delete %1's %2 directory?</translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>MainWindow</name>
|
||||
@ -417,6 +477,11 @@
|
||||
<source>Enable Fullscreen</source>
|
||||
<translation>Enable Fullscreen</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../settings_dialog.ui" line="140"/>
|
||||
<source>Enable Separate Update Folder</source>
|
||||
<translation>Enable Separate Update Folder</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../settings_dialog.ui" line="129"/>
|
||||
<source>Show Splash</source>
|
||||
@ -1056,6 +1121,11 @@
|
||||
<source>fullscreenCheckBox</source>
|
||||
<translation>Aktifkan Mode Layar Penuh:\nSecara otomatis menempatkan jendela permainan dalam mode layar penuh.\nIni dapat dinonaktifkan dengan menekan tombol F11.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../settings_dialog.cpp" line="293"/>
|
||||
<source>separateUpdatesCheckBox</source>
|
||||
<translation>Enable Separate Update Folder:\nEnables installing game updates into a separate folder for easy management.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../settings_dialog.cpp" line="295"/>
|
||||
<source>showSplashCheckBox</source>
|
||||
|
@ -140,6 +140,26 @@
|
||||
<source>Copy All</source>
|
||||
<translation>Copia Tutto</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui_context_menus.h" line="72"/>
|
||||
<source>Delete...</source>
|
||||
<translation>Delete...</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui_context_menus.h" line="73"/>
|
||||
<source>Delete Game</source>
|
||||
<translation>Delete Game</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui_context_menus.h" line="74"/>
|
||||
<source>Delete Update</source>
|
||||
<translation>Delete Update</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui_context_menus.h" line="75"/>
|
||||
<source>Delete DLC</source>
|
||||
<translation>Delete DLC</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui_context_menus.h" line="195"/>
|
||||
<source>Shortcut creation</source>
|
||||
@ -165,6 +185,46 @@
|
||||
<source>Install PKG</source>
|
||||
<translation>Installa PKG</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui_context_menus.h" line="299"/>
|
||||
<source>Game</source>
|
||||
<translation>Game</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui_context_menus.h" line="305"/>
|
||||
<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>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui_context_menus.h" line="312"/>
|
||||
<source>This game has no update to delete!</source>
|
||||
<translation>This game has no update to delete!</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui_context_menus.h" line="316"/>
|
||||
<source>Update</source>
|
||||
<translation>Update</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui_context_menus.h" line="321"/>
|
||||
<source>This game has no DLC to delete!</source>
|
||||
<translation>This game has no DLC to delete!</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui_context_menus.h" line="325"/>
|
||||
<source>DLC</source>
|
||||
<translation>DLC</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui_context_menus.h" line="332"/>
|
||||
<source>Delete %1</source>
|
||||
<translation>Delete %1</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui_context_menus.h" line="333"/>
|
||||
<source>Are you sure you want to delete %1's %2 directory?</source>
|
||||
<translation>Are you sure you want to delete %1's %2 directory?</translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>MainWindow</name>
|
||||
@ -417,6 +477,11 @@
|
||||
<source>Enable Fullscreen</source>
|
||||
<translation>Abilita Schermo Intero</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../settings_dialog.ui" line="140"/>
|
||||
<source>Enable Separate Update Folder</source>
|
||||
<translation>Enable Separate Update Folder</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../settings_dialog.ui" line="129"/>
|
||||
<source>Show Splash</source>
|
||||
@ -1056,6 +1121,11 @@
|
||||
<source>fullscreenCheckBox</source>
|
||||
<translation>Abilita Schermo Intero:\nMetti automaticamente la finestra di gioco in modalità schermo intero.\nQuesto può essere disattivato premendo il tasto F11.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../settings_dialog.cpp" line="293"/>
|
||||
<source>separateUpdatesCheckBox</source>
|
||||
<translation>Enable Separate Update Folder:\nEnables installing game updates into a separate folder for easy management.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../settings_dialog.cpp" line="295"/>
|
||||
<source>showSplashCheckBox</source>
|
||||
|
@ -140,6 +140,26 @@
|
||||
<source>Copy All</source>
|
||||
<translation>すべてコピー</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui_context_menus.h" line="72"/>
|
||||
<source>Delete...</source>
|
||||
<translation>Delete...</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui_context_menus.h" line="73"/>
|
||||
<source>Delete Game</source>
|
||||
<translation>Delete Game</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui_context_menus.h" line="74"/>
|
||||
<source>Delete Update</source>
|
||||
<translation>Delete Update</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui_context_menus.h" line="75"/>
|
||||
<source>Delete DLC</source>
|
||||
<translation>Delete DLC</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui_context_menus.h" line="195"/>
|
||||
<source>Shortcut creation</source>
|
||||
@ -165,6 +185,46 @@
|
||||
<source>Install PKG</source>
|
||||
<translation>PKGをインストール</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui_context_menus.h" line="299"/>
|
||||
<source>Game</source>
|
||||
<translation>Game</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui_context_menus.h" line="305"/>
|
||||
<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>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui_context_menus.h" line="312"/>
|
||||
<source>This game has no update to delete!</source>
|
||||
<translation>This game has no update to delete!</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui_context_menus.h" line="316"/>
|
||||
<source>Update</source>
|
||||
<translation>Update</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui_context_menus.h" line="321"/>
|
||||
<source>This game has no DLC to delete!</source>
|
||||
<translation>This game has no DLC to delete!</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui_context_menus.h" line="325"/>
|
||||
<source>DLC</source>
|
||||
<translation>DLC</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui_context_menus.h" line="332"/>
|
||||
<source>Delete %1</source>
|
||||
<translation>Delete %1</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui_context_menus.h" line="333"/>
|
||||
<source>Are you sure you want to delete %1's %2 directory?</source>
|
||||
<translation>Are you sure you want to delete %1's %2 directory?</translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>MainWindow</name>
|
||||
@ -417,6 +477,11 @@
|
||||
<source>Enable Fullscreen</source>
|
||||
<translation>フルスクリーンを有効にする</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../settings_dialog.ui" line="140"/>
|
||||
<source>Enable Separate Update Folder</source>
|
||||
<translation>Enable Separate Update Folder</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../settings_dialog.ui" line="129"/>
|
||||
<source>Show Splash</source>
|
||||
@ -1056,6 +1121,11 @@
|
||||
<source>fullscreenCheckBox</source>
|
||||
<translation>全画面モードを有効にする:\nゲームウィンドウを自動的に全画面モードにします。\nF11キーを押すことで切り替えることができます。</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../settings_dialog.cpp" line="293"/>
|
||||
<source>separateUpdatesCheckBox</source>
|
||||
<translation>Enable Separate Update Folder:\nEnables installing game updates into a separate folder for easy management.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../settings_dialog.cpp" line="295"/>
|
||||
<source>showSplashCheckBox</source>
|
||||
|
@ -140,6 +140,26 @@
|
||||
<source>Copy All</source>
|
||||
<translation>Copy All</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui_context_menus.h" line="72"/>
|
||||
<source>Delete...</source>
|
||||
<translation>Delete...</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui_context_menus.h" line="73"/>
|
||||
<source>Delete Game</source>
|
||||
<translation>Delete Game</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui_context_menus.h" line="74"/>
|
||||
<source>Delete Update</source>
|
||||
<translation>Delete Update</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui_context_menus.h" line="75"/>
|
||||
<source>Delete DLC</source>
|
||||
<translation>Delete DLC</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui_context_menus.h" line="195"/>
|
||||
<source>Shortcut creation</source>
|
||||
@ -165,6 +185,46 @@
|
||||
<source>Install PKG</source>
|
||||
<translation>Install PKG</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui_context_menus.h" line="299"/>
|
||||
<source>Game</source>
|
||||
<translation>Game</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui_context_menus.h" line="305"/>
|
||||
<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>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui_context_menus.h" line="312"/>
|
||||
<source>This game has no update to delete!</source>
|
||||
<translation>This game has no update to delete!</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui_context_menus.h" line="316"/>
|
||||
<source>Update</source>
|
||||
<translation>Update</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui_context_menus.h" line="321"/>
|
||||
<source>This game has no DLC to delete!</source>
|
||||
<translation>This game has no DLC to delete!</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui_context_menus.h" line="325"/>
|
||||
<source>DLC</source>
|
||||
<translation>DLC</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui_context_menus.h" line="332"/>
|
||||
<source>Delete %1</source>
|
||||
<translation>Delete %1</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui_context_menus.h" line="333"/>
|
||||
<source>Are you sure you want to delete %1's %2 directory?</source>
|
||||
<translation>Are you sure you want to delete %1's %2 directory?</translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>MainWindow</name>
|
||||
@ -417,6 +477,11 @@
|
||||
<source>Enable Fullscreen</source>
|
||||
<translation>Enable Fullscreen</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../settings_dialog.ui" line="140"/>
|
||||
<source>Enable Separate Update Folder</source>
|
||||
<translation>Enable Separate Update Folder</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../settings_dialog.ui" line="129"/>
|
||||
<source>Show Splash</source>
|
||||
@ -1056,6 +1121,11 @@
|
||||
<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>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../settings_dialog.cpp" line="293"/>
|
||||
<source>separateUpdatesCheckBox</source>
|
||||
<translation>Enable Separate Update Folder:\nEnables installing game updates into a separate folder for easy management.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../settings_dialog.cpp" line="295"/>
|
||||
<source>showSplashCheckBox</source>
|
||||
|
@ -140,6 +140,26 @@
|
||||
<source>Copy All</source>
|
||||
<translation>Copy All</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui_context_menus.h" line="72"/>
|
||||
<source>Delete...</source>
|
||||
<translation>Delete...</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui_context_menus.h" line="73"/>
|
||||
<source>Delete Game</source>
|
||||
<translation>Delete Game</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui_context_menus.h" line="74"/>
|
||||
<source>Delete Update</source>
|
||||
<translation>Delete Update</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui_context_menus.h" line="75"/>
|
||||
<source>Delete DLC</source>
|
||||
<translation>Delete DLC</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui_context_menus.h" line="195"/>
|
||||
<source>Shortcut creation</source>
|
||||
@ -165,6 +185,46 @@
|
||||
<source>Install PKG</source>
|
||||
<translation>Install PKG</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui_context_menus.h" line="299"/>
|
||||
<source>Game</source>
|
||||
<translation>Game</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui_context_menus.h" line="305"/>
|
||||
<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>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui_context_menus.h" line="312"/>
|
||||
<source>This game has no update to delete!</source>
|
||||
<translation>This game has no update to delete!</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui_context_menus.h" line="316"/>
|
||||
<source>Update</source>
|
||||
<translation>Update</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui_context_menus.h" line="321"/>
|
||||
<source>This game has no DLC to delete!</source>
|
||||
<translation>This game has no DLC to delete!</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui_context_menus.h" line="325"/>
|
||||
<source>DLC</source>
|
||||
<translation>DLC</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui_context_menus.h" line="332"/>
|
||||
<source>Delete %1</source>
|
||||
<translation>Delete %1</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui_context_menus.h" line="333"/>
|
||||
<source>Are you sure you want to delete %1's %2 directory?</source>
|
||||
<translation>Are you sure you want to delete %1's %2 directory?</translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>MainWindow</name>
|
||||
@ -417,6 +477,11 @@
|
||||
<source>Enable Fullscreen</source>
|
||||
<translation>Enable Fullscreen</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../settings_dialog.ui" line="140"/>
|
||||
<source>Enable Separate Update Folder</source>
|
||||
<translation>Enable Separate Update Folder</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../settings_dialog.ui" line="129"/>
|
||||
<source>Show Splash</source>
|
||||
@ -1056,6 +1121,11 @@
|
||||
<source>fullscreenCheckBox</source>
|
||||
<translation>Įjungti visą ekraną:\nAutomatiškai perjungia žaidimo langą į viso ekrano režimą.\nTai galima išjungti paspaudus F11 klavišą.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../settings_dialog.cpp" line="293"/>
|
||||
<source>separateUpdatesCheckBox</source>
|
||||
<translation>Enable Separate Update Folder:\nEnables installing game updates into a separate folder for easy management.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../settings_dialog.cpp" line="295"/>
|
||||
<source>showSplashCheckBox</source>
|
||||
|
@ -140,6 +140,26 @@
|
||||
<source>Copy All</source>
|
||||
<translation>Copy All</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui_context_menus.h" line="72"/>
|
||||
<source>Delete...</source>
|
||||
<translation>Delete...</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui_context_menus.h" line="73"/>
|
||||
<source>Delete Game</source>
|
||||
<translation>Delete Game</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui_context_menus.h" line="74"/>
|
||||
<source>Delete Update</source>
|
||||
<translation>Delete Update</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui_context_menus.h" line="75"/>
|
||||
<source>Delete DLC</source>
|
||||
<translation>Delete DLC</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui_context_menus.h" line="195"/>
|
||||
<source>Shortcut creation</source>
|
||||
@ -165,6 +185,46 @@
|
||||
<source>Install PKG</source>
|
||||
<translation>Install PKG</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui_context_menus.h" line="299"/>
|
||||
<source>Game</source>
|
||||
<translation>Game</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui_context_menus.h" line="305"/>
|
||||
<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>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui_context_menus.h" line="312"/>
|
||||
<source>This game has no update to delete!</source>
|
||||
<translation>This game has no update to delete!</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui_context_menus.h" line="316"/>
|
||||
<source>Update</source>
|
||||
<translation>Update</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui_context_menus.h" line="321"/>
|
||||
<source>This game has no DLC to delete!</source>
|
||||
<translation>This game has no DLC to delete!</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui_context_menus.h" line="325"/>
|
||||
<source>DLC</source>
|
||||
<translation>DLC</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui_context_menus.h" line="332"/>
|
||||
<source>Delete %1</source>
|
||||
<translation>Delete %1</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui_context_menus.h" line="333"/>
|
||||
<source>Are you sure you want to delete %1's %2 directory?</source>
|
||||
<translation>Are you sure you want to delete %1's %2 directory?</translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>MainWindow</name>
|
||||
@ -417,6 +477,11 @@
|
||||
<source>Enable Fullscreen</source>
|
||||
<translation>Enable Fullscreen</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../settings_dialog.ui" line="140"/>
|
||||
<source>Enable Separate Update Folder</source>
|
||||
<translation>Enable Separate Update Folder</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../settings_dialog.ui" line="129"/>
|
||||
<source>Show Splash</source>
|
||||
@ -1056,6 +1121,11 @@
|
||||
<source>fullscreenCheckBox</source>
|
||||
<translation>Aktiver fullskjerm:\nSetter automatisk spillvinduet i fullskjermmodus.\nDette kan slås av ved å trykke på F11-tasten.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../settings_dialog.cpp" line="293"/>
|
||||
<source>separateUpdatesCheckBox</source>
|
||||
<translation>Enable Separate Update Folder:\nEnables installing game updates into a separate folder for easy management.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../settings_dialog.cpp" line="295"/>
|
||||
<source>showSplashCheckBox</source>
|
||||
|
@ -140,6 +140,26 @@
|
||||
<source>Copy All</source>
|
||||
<translation>Copy All</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui_context_menus.h" line="72"/>
|
||||
<source>Delete...</source>
|
||||
<translation>Delete...</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui_context_menus.h" line="73"/>
|
||||
<source>Delete Game</source>
|
||||
<translation>Delete Game</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui_context_menus.h" line="74"/>
|
||||
<source>Delete Update</source>
|
||||
<translation>Delete Update</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui_context_menus.h" line="75"/>
|
||||
<source>Delete DLC</source>
|
||||
<translation>Delete DLC</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui_context_menus.h" line="195"/>
|
||||
<source>Shortcut creation</source>
|
||||
@ -165,6 +185,46 @@
|
||||
<source>Install PKG</source>
|
||||
<translation>Install PKG</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui_context_menus.h" line="299"/>
|
||||
<source>Game</source>
|
||||
<translation>Game</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui_context_menus.h" line="305"/>
|
||||
<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>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui_context_menus.h" line="312"/>
|
||||
<source>This game has no update to delete!</source>
|
||||
<translation>This game has no update to delete!</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui_context_menus.h" line="316"/>
|
||||
<source>Update</source>
|
||||
<translation>Update</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui_context_menus.h" line="321"/>
|
||||
<source>This game has no DLC to delete!</source>
|
||||
<translation>This game has no DLC to delete!</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui_context_menus.h" line="325"/>
|
||||
<source>DLC</source>
|
||||
<translation>DLC</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui_context_menus.h" line="332"/>
|
||||
<source>Delete %1</source>
|
||||
<translation>Delete %1</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui_context_menus.h" line="333"/>
|
||||
<source>Are you sure you want to delete %1's %2 directory?</source>
|
||||
<translation>Are you sure you want to delete %1's %2 directory?</translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>MainWindow</name>
|
||||
@ -417,6 +477,11 @@
|
||||
<source>Enable Fullscreen</source>
|
||||
<translation>Enable Fullscreen</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../settings_dialog.ui" line="140"/>
|
||||
<source>Enable Separate Update Folder</source>
|
||||
<translation>Enable Separate Update Folder</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../settings_dialog.ui" line="129"/>
|
||||
<source>Show Splash</source>
|
||||
@ -1056,6 +1121,11 @@
|
||||
<source>fullscreenCheckBox</source>
|
||||
<translation>Volledig scherm inschakelen:\nZet het gamevenster automatisch in de volledig scherm modus.\nDit kan worden omgeschakeld door op de F11-toets te drukken.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../settings_dialog.cpp" line="293"/>
|
||||
<source>separateUpdatesCheckBox</source>
|
||||
<translation>Enable Separate Update Folder:\nEnables installing game updates into a separate folder for easy management.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../settings_dialog.cpp" line="295"/>
|
||||
<source>showSplashCheckBox</source>
|
||||
|
@ -140,6 +140,26 @@
|
||||
<source>Copy All</source>
|
||||
<translation>Kopiuj wszystko</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui_context_menus.h" line="72"/>
|
||||
<source>Delete...</source>
|
||||
<translation>Delete...</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui_context_menus.h" line="73"/>
|
||||
<source>Delete Game</source>
|
||||
<translation>Delete Game</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui_context_menus.h" line="74"/>
|
||||
<source>Delete Update</source>
|
||||
<translation>Delete Update</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui_context_menus.h" line="75"/>
|
||||
<source>Delete DLC</source>
|
||||
<translation>Delete DLC</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui_context_menus.h" line="195"/>
|
||||
<source>Shortcut creation</source>
|
||||
@ -165,6 +185,46 @@
|
||||
<source>Install PKG</source>
|
||||
<translation>Zainstaluj PKG</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui_context_menus.h" line="299"/>
|
||||
<source>Game</source>
|
||||
<translation>Game</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui_context_menus.h" line="305"/>
|
||||
<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>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui_context_menus.h" line="312"/>
|
||||
<source>This game has no update to delete!</source>
|
||||
<translation>This game has no update to delete!</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui_context_menus.h" line="316"/>
|
||||
<source>Update</source>
|
||||
<translation>Update</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui_context_menus.h" line="321"/>
|
||||
<source>This game has no DLC to delete!</source>
|
||||
<translation>This game has no DLC to delete!</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui_context_menus.h" line="325"/>
|
||||
<source>DLC</source>
|
||||
<translation>DLC</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui_context_menus.h" line="332"/>
|
||||
<source>Delete %1</source>
|
||||
<translation>Delete %1</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui_context_menus.h" line="333"/>
|
||||
<source>Are you sure you want to delete %1's %2 directory?</source>
|
||||
<translation>Are you sure you want to delete %1's %2 directory?</translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>MainWindow</name>
|
||||
@ -417,6 +477,11 @@
|
||||
<source>Enable Fullscreen</source>
|
||||
<translation>Włącz pełny ekran</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../settings_dialog.ui" line="140"/>
|
||||
<source>Enable Separate Update Folder</source>
|
||||
<translation>Enable Separate Update Folder</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../settings_dialog.ui" line="129"/>
|
||||
<source>Show Splash</source>
|
||||
@ -1056,6 +1121,11 @@
|
||||
<source>fullscreenCheckBox</source>
|
||||
<translation>Włącz tryb pełnoekranowy:\nAutomatycznie przełącza okno gry w tryb pełnoekranowy.\nMożna to wyłączyć naciskając klawisz F11.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../settings_dialog.cpp" line="293"/>
|
||||
<source>separateUpdatesCheckBox</source>
|
||||
<translation>Enable Separate Update Folder:\nEnables installing game updates into a separate folder for easy management.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../settings_dialog.cpp" line="295"/>
|
||||
<source>showSplashCheckBox</source>
|
||||
|
@ -140,6 +140,26 @@
|
||||
<source>Copy All</source>
|
||||
<translation>Copiar Tudo</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui_context_menus.h" line="72"/>
|
||||
<source>Delete...</source>
|
||||
<translation>Deletar...</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui_context_menus.h" line="73"/>
|
||||
<source>Delete Game</source>
|
||||
<translation>Deletar Jogo</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui_context_menus.h" line="74"/>
|
||||
<source>Delete Update</source>
|
||||
<translation>Deletar Atualização</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui_context_menus.h" line="75"/>
|
||||
<source>Delete DLC</source>
|
||||
<translation>Deletar DLC</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui_context_menus.h" line="195"/>
|
||||
<source>Shortcut creation</source>
|
||||
@ -165,6 +185,46 @@
|
||||
<source>Install PKG</source>
|
||||
<translation>Instalar PKG</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui_context_menus.h" line="299"/>
|
||||
<source>Game</source>
|
||||
<translation>Jogo</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui_context_menus.h" line="305"/>
|
||||
<source>requiresEnableSeparateUpdateFolder_MSG</source>
|
||||
<translation>Este recurso requer a opção de configuração 'Habilitar Pasta de Atualização Separada' para funcionar. Se você quiser usar este recurso, habilite-o.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui_context_menus.h" line="312"/>
|
||||
<source>This game has no update to delete!</source>
|
||||
<translation>Este jogo não tem atualização para excluir!</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui_context_menus.h" line="316"/>
|
||||
<source>Update</source>
|
||||
<translation>Atualização</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui_context_menus.h" line="321"/>
|
||||
<source>This game has no DLC to delete!</source>
|
||||
<translation>Este jogo não tem DLC para excluir!</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui_context_menus.h" line="325"/>
|
||||
<source>DLC</source>
|
||||
<translation>DLC</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui_context_menus.h" line="332"/>
|
||||
<source>Delete %1</source>
|
||||
<translation>Deletar %1</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui_context_menus.h" line="333"/>
|
||||
<source>Are you sure you want to delete %1's %2 directory?</source>
|
||||
<translation>Tem certeza de que deseja excluir o diretório %2 de %1 ?</translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>MainWindow</name>
|
||||
@ -417,6 +477,11 @@
|
||||
<source>Enable Fullscreen</source>
|
||||
<translation>Ativar Tela Cheia</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../settings_dialog.ui" line="140"/>
|
||||
<source>Enable Separate Update Folder</source>
|
||||
<translation>Habilitar pasta de atualização separada</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../settings_dialog.ui" line="129"/>
|
||||
<source>Show Splash</source>
|
||||
@ -1056,6 +1121,11 @@
|
||||
<source>fullscreenCheckBox</source>
|
||||
<translation>Ativar Tela Cheia:\nMove automaticamente a janela do jogo para o modo tela cheia.\nIsso pode ser alterado pressionando a tecla F11.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../settings_dialog.cpp" line="293"/>
|
||||
<source>separateUpdatesCheckBox</source>
|
||||
<translation>Habilitar pasta de atualização separada:\nPermite instalar atualizações de jogos em uma pasta separada para fácil gerenciamento.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../settings_dialog.cpp" line="295"/>
|
||||
<source>showSplashCheckBox</source>
|
||||
|
@ -140,6 +140,26 @@
|
||||
<source>Copy All</source>
|
||||
<translation>Copy All</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui_context_menus.h" line="72"/>
|
||||
<source>Delete...</source>
|
||||
<translation>Delete...</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui_context_menus.h" line="73"/>
|
||||
<source>Delete Game</source>
|
||||
<translation>Delete Game</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui_context_menus.h" line="74"/>
|
||||
<source>Delete Update</source>
|
||||
<translation>Delete Update</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui_context_menus.h" line="75"/>
|
||||
<source>Delete DLC</source>
|
||||
<translation>Delete DLC</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui_context_menus.h" line="195"/>
|
||||
<source>Shortcut creation</source>
|
||||
@ -165,6 +185,46 @@
|
||||
<source>Install PKG</source>
|
||||
<translation>Install PKG</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui_context_menus.h" line="299"/>
|
||||
<source>Game</source>
|
||||
<translation>Game</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui_context_menus.h" line="305"/>
|
||||
<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>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui_context_menus.h" line="312"/>
|
||||
<source>This game has no update to delete!</source>
|
||||
<translation>This game has no update to delete!</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui_context_menus.h" line="316"/>
|
||||
<source>Update</source>
|
||||
<translation>Update</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui_context_menus.h" line="321"/>
|
||||
<source>This game has no DLC to delete!</source>
|
||||
<translation>This game has no DLC to delete!</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui_context_menus.h" line="325"/>
|
||||
<source>DLC</source>
|
||||
<translation>DLC</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui_context_menus.h" line="332"/>
|
||||
<source>Delete %1</source>
|
||||
<translation>Delete %1</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui_context_menus.h" line="333"/>
|
||||
<source>Are you sure you want to delete %1's %2 directory?</source>
|
||||
<translation>Are you sure you want to delete %1's %2 directory?</translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>MainWindow</name>
|
||||
@ -417,6 +477,11 @@
|
||||
<source>Enable Fullscreen</source>
|
||||
<translation>Enable Fullscreen</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../settings_dialog.ui" line="140"/>
|
||||
<source>Enable Separate Update Folder</source>
|
||||
<translation>Enable Separate Update Folder</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../settings_dialog.ui" line="129"/>
|
||||
<source>Show Splash</source>
|
||||
@ -1056,6 +1121,11 @@
|
||||
<source>fullscreenCheckBox</source>
|
||||
<translation>Activează modul pe ecran complet:\nPune automat fereastra jocului în modul pe ecran complet.\nAceasta poate fi dezactivată apăsând tasta F11.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../settings_dialog.cpp" line="293"/>
|
||||
<source>separateUpdatesCheckBox</source>
|
||||
<translation>Enable Separate Update Folder:\nEnables installing game updates into a separate folder for easy management.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../settings_dialog.cpp" line="295"/>
|
||||
<source>showSplashCheckBox</source>
|
||||
|
@ -62,7 +62,7 @@
|
||||
<message>
|
||||
<location filename="../install_dir_select.cpp" line="37"/>
|
||||
<source>Select which directory you want to install to.</source>
|
||||
<translation>Select which directory you want to install to.</translation>
|
||||
<translation>Выберите папку, в которую вы хотите установить.</translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
@ -140,6 +140,26 @@
|
||||
<source>Copy All</source>
|
||||
<translation>Копировать все</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui_context_menus.h" line="72"/>
|
||||
<source>Delete...</source>
|
||||
<translation>Удаление...</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui_context_menus.h" line="73"/>
|
||||
<source>Delete Game</source>
|
||||
<translation>Удалить игру</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui_context_menus.h" line="74"/>
|
||||
<source>Delete Update</source>
|
||||
<translation>Удалить обновление</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui_context_menus.h" line="75"/>
|
||||
<source>Delete DLC</source>
|
||||
<translation>Удалить DLC</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui_context_menus.h" line="195"/>
|
||||
<source>Shortcut creation</source>
|
||||
@ -165,6 +185,46 @@
|
||||
<source>Install PKG</source>
|
||||
<translation>Установить PKG</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui_context_menus.h" line="299"/>
|
||||
<source>Game</source>
|
||||
<translation>Игры</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui_context_menus.h" line="305"/>
|
||||
<source>requiresEnableSeparateUpdateFolder_MSG</source>
|
||||
<translation>Эта функция требует включения настройки 'Отдельная папка обновлений'. Если вы хотите использовать эту функцию, пожалуйста включите её.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui_context_menus.h" line="312"/>
|
||||
<source>This game has no update to delete!</source>
|
||||
<translation>У этой игры нет обновлений для удаления!</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui_context_menus.h" line="316"/>
|
||||
<source>Update</source>
|
||||
<translation>Обновления</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui_context_menus.h" line="321"/>
|
||||
<source>This game has no DLC to delete!</source>
|
||||
<translation>У этой игры нет DLC для удаления!</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui_context_menus.h" line="325"/>
|
||||
<source>DLC</source>
|
||||
<translation>DLC</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui_context_menus.h" line="332"/>
|
||||
<source>Delete %1</source>
|
||||
<translation>Удалить %1</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui_context_menus.h" line="333"/>
|
||||
<source>Are you sure you want to delete %1's %2 directory?</source>
|
||||
<translation>Вы уверены, что хотите удалить папку %2 %1?</translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>MainWindow</name>
|
||||
@ -417,6 +477,11 @@
|
||||
<source>Enable Fullscreen</source>
|
||||
<translation>Полноэкранный режим</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../settings_dialog.ui" line="140"/>
|
||||
<source>Enable Separate Update Folder</source>
|
||||
<translation>Отдельная папка обновлений</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../settings_dialog.ui" line="129"/>
|
||||
<source>Show Splash</source>
|
||||
@ -460,17 +525,17 @@
|
||||
<message>
|
||||
<location filename="../settings_dialog.ui" line="611"/>
|
||||
<source>Cursor</source>
|
||||
<translation>Курсор</translation>
|
||||
<translation>Курсор мыши</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../settings_dialog.ui" line="635"/>
|
||||
<source>Hide Cursor</source>
|
||||
<translation>Скрыть курсор</translation>
|
||||
<translation>Скрывать курсор</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../settings_dialog.ui" line="668"/>
|
||||
<source>Hide Cursor Idle Timeout</source>
|
||||
<translation>Тайм-аут скрытия курсора при неактивности</translation>
|
||||
<translation>Тайм-аут скрытия курсора при бездействии</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../settings_dialog.ui" line="767"/>
|
||||
@ -575,7 +640,7 @@
|
||||
<message>
|
||||
<location filename="../settings_dialog.ui" line="286"/>
|
||||
<source>Check for Updates at Startup</source>
|
||||
<translation>Проверка обновлений при запуске</translation>
|
||||
<translation>Проверка при запуске</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../settings_dialog.ui" line="313"/>
|
||||
@ -590,12 +655,12 @@
|
||||
<message>
|
||||
<location filename="../settings_dialog.ui" line="354"/>
|
||||
<source>GUI Settings</source>
|
||||
<translation>Настройки интерфейса</translation>
|
||||
<translation>Интерфейс</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../settings_dialog.ui" line="375"/>
|
||||
<source>Play title music</source>
|
||||
<translation>Воспроизведение заглавной музыки</translation>
|
||||
<translation>Играть заглавную музыку</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../settings_dialog.ui" line="394"/>
|
||||
@ -1056,6 +1121,11 @@
|
||||
<source>fullscreenCheckBox</source>
|
||||
<translation>Полноэкранный режим:\nАвтоматически переводит игровое окно в полноэкранный режим.\nВы можете отключить это, нажав клавишу F11.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../settings_dialog.cpp" line="293"/>
|
||||
<source>separateUpdatesCheckBox</source>
|
||||
<translation>Отдельная папка обновлений:\nПозволяет устанавливать обновления игры в отдельную папку для удобства.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../settings_dialog.cpp" line="295"/>
|
||||
<source>showSplashCheckBox</source>
|
||||
@ -1094,22 +1164,22 @@
|
||||
<message>
|
||||
<location filename="../settings_dialog.cpp" line="306"/>
|
||||
<source>GUIgroupBox</source>
|
||||
<translation>Воспроизведение заглавной музыки:\nЕсли игра это поддерживает, включает воспроизведение специальной музыки при выборе игры в интерфейсе.</translation>
|
||||
<translation>Играть заглавную музыку:\nВключает воспроизведение специальной музыки при выборе игры в списке, если она это поддерживает.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../settings_dialog.cpp" line="450"/>
|
||||
<source>hideCursorGroupBox</source>
|
||||
<translation>Скрыть курсор:\nВыберите, когда курсор исчезнет:\nНикогда: Вы всегда будете видеть мышь.\nНеактивный: Yстановите время, через которое она исчезнет после бездействия.\nВсегда: вы никогда не увидите мышь.</translation>
|
||||
<translation>Скрывать курсор:\nВыберите, когда курсор исчезнет:\nНикогда: Вы всегда будете видеть мышь.\nПри бездействии: Установите время, через которое курсор исчезнет при бездействии.\nВсегда: Вы никогда не будете видеть мышь.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../settings_dialog.cpp" line="452"/>
|
||||
<source>idleTimeoutGroupBox</source>
|
||||
<translation>Установите время, через которое курсор исчезнет после бездействия.</translation>
|
||||
<translation>Установите время, через которое курсор исчезнет при бездействии.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../settings_dialog.cpp" line="454"/>
|
||||
<source>backButtonBehaviorGroupBox</source>
|
||||
<translation>Поведение кнопки «Назад»:\nУстанавливает кнопку «Назад» на контроллере для имитации нажатия в указанной позиции на сенсорной панели PS4.</translation>
|
||||
<translation>Поведение кнопки «Назад»:\nНастраивает кнопку «Назад» контроллера на эмуляцию нажатия на указанную область на сенсорной панели контроллера PS4.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../settings_dialog.cpp" line="70"/>
|
||||
@ -1119,7 +1189,7 @@
|
||||
<message>
|
||||
<location filename="../settings_dialog.cpp" line="71"/>
|
||||
<source>Idle</source>
|
||||
<translation>Неактивный</translation>
|
||||
<translation>При бездействии</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../settings_dialog.cpp" line="72"/>
|
||||
@ -1129,17 +1199,17 @@
|
||||
<message>
|
||||
<location filename="../settings_dialog.cpp" line="101"/>
|
||||
<source>Touchpad Left</source>
|
||||
<translation>Тачпад Слева</translation>
|
||||
<translation>Тачпад слева</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../settings_dialog.cpp" line="102"/>
|
||||
<source>Touchpad Right</source>
|
||||
<translation>Тачпад Справа</translation>
|
||||
<translation>Тачпад справа</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../settings_dialog.cpp" line="103"/>
|
||||
<source>Touchpad Center</source>
|
||||
<translation>Центр Тачпада</translation>
|
||||
<translation>Центр тачпада</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../settings_dialog.cpp" line="104"/>
|
||||
@ -1252,7 +1322,7 @@
|
||||
<message>
|
||||
<location filename="../game_list_frame.cpp" line="38"/>
|
||||
<source>Play Time</source>
|
||||
<translation>Время Игры</translation>
|
||||
<translation>Времени в игре</translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
@ -1330,7 +1400,7 @@
|
||||
<message>
|
||||
<location filename="../check_update.cpp" line="198"/>
|
||||
<source>Check for Updates at Startup</source>
|
||||
<translation>Проверка обновлений при запуске</translation>
|
||||
<translation>Проверка при запуске</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../check_update.cpp" line="199"/>
|
||||
|
@ -140,6 +140,26 @@
|
||||
<source>Copy All</source>
|
||||
<translation>Kopjo të Gjitha</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui_context_menus.h" line="72"/>
|
||||
<source>Delete...</source>
|
||||
<translation>Delete...</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui_context_menus.h" line="73"/>
|
||||
<source>Delete Game</source>
|
||||
<translation>Delete Game</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui_context_menus.h" line="74"/>
|
||||
<source>Delete Update</source>
|
||||
<translation>Delete Update</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui_context_menus.h" line="75"/>
|
||||
<source>Delete DLC</source>
|
||||
<translation>Delete DLC</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui_context_menus.h" line="195"/>
|
||||
<source>Shortcut creation</source>
|
||||
@ -165,6 +185,46 @@
|
||||
<source>Install PKG</source>
|
||||
<translation>Instalo PKG</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui_context_menus.h" line="299"/>
|
||||
<source>Game</source>
|
||||
<translation>Game</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui_context_menus.h" line="305"/>
|
||||
<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>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui_context_menus.h" line="312"/>
|
||||
<source>This game has no update to delete!</source>
|
||||
<translation>This game has no update to delete!</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui_context_menus.h" line="316"/>
|
||||
<source>Update</source>
|
||||
<translation>Update</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui_context_menus.h" line="321"/>
|
||||
<source>This game has no DLC to delete!</source>
|
||||
<translation>This game has no DLC to delete!</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui_context_menus.h" line="325"/>
|
||||
<source>DLC</source>
|
||||
<translation>DLC</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui_context_menus.h" line="332"/>
|
||||
<source>Delete %1</source>
|
||||
<translation>Delete %1</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui_context_menus.h" line="333"/>
|
||||
<source>Are you sure you want to delete %1's %2 directory?</source>
|
||||
<translation>Are you sure you want to delete %1's %2 directory?</translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>MainWindow</name>
|
||||
@ -417,6 +477,11 @@
|
||||
<source>Enable Fullscreen</source>
|
||||
<translation>Aktivizo Ekranin e plotë</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../settings_dialog.ui" line="140"/>
|
||||
<source>Enable Separate Update Folder</source>
|
||||
<translation>Enable Separate Update Folder</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../settings_dialog.ui" line="129"/>
|
||||
<source>Show Splash</source>
|
||||
@ -1056,6 +1121,11 @@
|
||||
<source>fullscreenCheckBox</source>
|
||||
<translation>Aktivizo ekranin e plotë:\nVendos automatikisht dritaren e lojës në mënyrën e ekranit të plotë.\nKjo mund të aktivizohet duke shtypur tastin F11.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../settings_dialog.cpp" line="293"/>
|
||||
<source>separateUpdatesCheckBox</source>
|
||||
<translation>Enable Separate Update Folder:\nEnables installing game updates into a separate folder for easy management.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../settings_dialog.cpp" line="295"/>
|
||||
<source>showSplashCheckBox</source>
|
||||
@ -1383,4 +1453,4 @@
|
||||
<translation>Krijimi i skedarit skript të përditësimit dështoi</translation>
|
||||
</message>
|
||||
</context>
|
||||
</TS>
|
||||
</TS>
|
@ -140,6 +140,26 @@
|
||||
<source>Copy All</source>
|
||||
<translation>Tümünü Kopyala</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui_context_menus.h" line="72"/>
|
||||
<source>Delete...</source>
|
||||
<translation>Delete...</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui_context_menus.h" line="73"/>
|
||||
<source>Delete Game</source>
|
||||
<translation>Delete Game</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui_context_menus.h" line="74"/>
|
||||
<source>Delete Update</source>
|
||||
<translation>Delete Update</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui_context_menus.h" line="75"/>
|
||||
<source>Delete DLC</source>
|
||||
<translation>Delete DLC</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui_context_menus.h" line="195"/>
|
||||
<source>Shortcut creation</source>
|
||||
@ -165,6 +185,46 @@
|
||||
<source>Install PKG</source>
|
||||
<translation>PKG Yükle</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui_context_menus.h" line="299"/>
|
||||
<source>Game</source>
|
||||
<translation>Game</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui_context_menus.h" line="305"/>
|
||||
<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>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui_context_menus.h" line="312"/>
|
||||
<source>This game has no update to delete!</source>
|
||||
<translation>This game has no update to delete!</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui_context_menus.h" line="316"/>
|
||||
<source>Update</source>
|
||||
<translation>Update</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui_context_menus.h" line="321"/>
|
||||
<source>This game has no DLC to delete!</source>
|
||||
<translation>This game has no DLC to delete!</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui_context_menus.h" line="325"/>
|
||||
<source>DLC</source>
|
||||
<translation>DLC</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui_context_menus.h" line="332"/>
|
||||
<source>Delete %1</source>
|
||||
<translation>Delete %1</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui_context_menus.h" line="333"/>
|
||||
<source>Are you sure you want to delete %1's %2 directory?</source>
|
||||
<translation>Are you sure you want to delete %1's %2 directory?</translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>MainWindow</name>
|
||||
@ -417,6 +477,11 @@
|
||||
<source>Enable Fullscreen</source>
|
||||
<translation>Tam Ekranı Etkinleştir</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../settings_dialog.ui" line="140"/>
|
||||
<source>Enable Separate Update Folder</source>
|
||||
<translation>Enable Separate Update Folder</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../settings_dialog.ui" line="129"/>
|
||||
<source>Show Splash</source>
|
||||
@ -1056,6 +1121,11 @@
|
||||
<source>fullscreenCheckBox</source>
|
||||
<translation>Tam Ekranı Etkinleştir:\nOyun penceresini otomatik olarak tam ekran moduna alır.\nBu, F11 tuşuna basarak geçiş yapılabilir.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../settings_dialog.cpp" line="293"/>
|
||||
<source>separateUpdatesCheckBox</source>
|
||||
<translation>Enable Separate Update Folder:\nEnables installing game updates into a separate folder for easy management.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../settings_dialog.cpp" line="295"/>
|
||||
<source>showSplashCheckBox</source>
|
||||
|
@ -140,6 +140,26 @@
|
||||
<source>Copy All</source>
|
||||
<translation>Copy All</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui_context_menus.h" line="72"/>
|
||||
<source>Delete...</source>
|
||||
<translation>Delete...</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui_context_menus.h" line="73"/>
|
||||
<source>Delete Game</source>
|
||||
<translation>Delete Game</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui_context_menus.h" line="74"/>
|
||||
<source>Delete Update</source>
|
||||
<translation>Delete Update</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui_context_menus.h" line="75"/>
|
||||
<source>Delete DLC</source>
|
||||
<translation>Delete DLC</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui_context_menus.h" line="195"/>
|
||||
<source>Shortcut creation</source>
|
||||
@ -165,6 +185,46 @@
|
||||
<source>Install PKG</source>
|
||||
<translation>Install PKG</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui_context_menus.h" line="299"/>
|
||||
<source>Game</source>
|
||||
<translation>Game</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui_context_menus.h" line="305"/>
|
||||
<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>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui_context_menus.h" line="312"/>
|
||||
<source>This game has no update to delete!</source>
|
||||
<translation>This game has no update to delete!</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui_context_menus.h" line="316"/>
|
||||
<source>Update</source>
|
||||
<translation>Update</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui_context_menus.h" line="321"/>
|
||||
<source>This game has no DLC to delete!</source>
|
||||
<translation>This game has no DLC to delete!</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui_context_menus.h" line="325"/>
|
||||
<source>DLC</source>
|
||||
<translation>DLC</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui_context_menus.h" line="332"/>
|
||||
<source>Delete %1</source>
|
||||
<translation>Delete %1</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui_context_menus.h" line="333"/>
|
||||
<source>Are you sure you want to delete %1's %2 directory?</source>
|
||||
<translation>Are you sure you want to delete %1's %2 directory?</translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>MainWindow</name>
|
||||
@ -417,6 +477,11 @@
|
||||
<source>Enable Fullscreen</source>
|
||||
<translation>Enable Fullscreen</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../settings_dialog.ui" line="140"/>
|
||||
<source>Enable Separate Update Folder</source>
|
||||
<translation>Enable Separate Update Folder</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../settings_dialog.ui" line="129"/>
|
||||
<source>Show Splash</source>
|
||||
@ -1056,6 +1121,11 @@
|
||||
<source>fullscreenCheckBox</source>
|
||||
<translation>Bật chế độ toàn màn hình:\nTự động đặt cửa sổ trò chơi ở chế độ toàn màn hình.\nĐiều này có thể bị vô hiệu hóa bằng cách nhấn phím F11.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../settings_dialog.cpp" line="293"/>
|
||||
<source>separateUpdatesCheckBox</source>
|
||||
<translation>Enable Separate Update Folder:\nEnables installing game updates into a separate folder for easy management.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../settings_dialog.cpp" line="295"/>
|
||||
<source>showSplashCheckBox</source>
|
||||
|
@ -140,6 +140,26 @@
|
||||
<source>Copy All</source>
|
||||
<translation>复制全部</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui_context_menus.h" line="72"/>
|
||||
<source>Delete...</source>
|
||||
<translation>Delete...</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui_context_menus.h" line="73"/>
|
||||
<source>Delete Game</source>
|
||||
<translation>Delete Game</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui_context_menus.h" line="74"/>
|
||||
<source>Delete Update</source>
|
||||
<translation>Delete Update</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui_context_menus.h" line="75"/>
|
||||
<source>Delete DLC</source>
|
||||
<translation>Delete DLC</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui_context_menus.h" line="195"/>
|
||||
<source>Shortcut creation</source>
|
||||
@ -165,6 +185,46 @@
|
||||
<source>Install PKG</source>
|
||||
<translation>安装 PKG</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui_context_menus.h" line="299"/>
|
||||
<source>Game</source>
|
||||
<translation>Game</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui_context_menus.h" line="305"/>
|
||||
<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>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui_context_menus.h" line="312"/>
|
||||
<source>This game has no update to delete!</source>
|
||||
<translation>This game has no update to delete!</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui_context_menus.h" line="316"/>
|
||||
<source>Update</source>
|
||||
<translation>Update</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui_context_menus.h" line="321"/>
|
||||
<source>This game has no DLC to delete!</source>
|
||||
<translation>This game has no DLC to delete!</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui_context_menus.h" line="325"/>
|
||||
<source>DLC</source>
|
||||
<translation>DLC</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui_context_menus.h" line="332"/>
|
||||
<source>Delete %1</source>
|
||||
<translation>Delete %1</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui_context_menus.h" line="333"/>
|
||||
<source>Are you sure you want to delete %1's %2 directory?</source>
|
||||
<translation>Are you sure you want to delete %1's %2 directory?</translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>MainWindow</name>
|
||||
@ -417,6 +477,11 @@
|
||||
<source>Enable Fullscreen</source>
|
||||
<translation>启用全屏</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../settings_dialog.ui" line="140"/>
|
||||
<source>Enable Separate Update Folder</source>
|
||||
<translation>Enable Separate Update Folder</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../settings_dialog.ui" line="129"/>
|
||||
<source>Show Splash</source>
|
||||
@ -1056,6 +1121,11 @@
|
||||
<source>fullscreenCheckBox</source>
|
||||
<translation>启用全屏模式:\n自动将游戏窗口设置为全屏模式。\n您可以按 F11 键禁用此选项。</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../settings_dialog.cpp" line="293"/>
|
||||
<source>separateUpdatesCheckBox</source>
|
||||
<translation>Enable Separate Update Folder:\nEnables installing game updates into a separate folder for easy management.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../settings_dialog.cpp" line="295"/>
|
||||
<source>showSplashCheckBox</source>
|
||||
|
@ -140,6 +140,26 @@
|
||||
<source>Copy All</source>
|
||||
<translation>Copy All</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui_context_menus.h" line="72"/>
|
||||
<source>Delete...</source>
|
||||
<translation>Delete...</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui_context_menus.h" line="73"/>
|
||||
<source>Delete Game</source>
|
||||
<translation>Delete Game</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui_context_menus.h" line="74"/>
|
||||
<source>Delete Update</source>
|
||||
<translation>Delete Update</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui_context_menus.h" line="75"/>
|
||||
<source>Delete DLC</source>
|
||||
<translation>Delete DLC</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui_context_menus.h" line="195"/>
|
||||
<source>Shortcut creation</source>
|
||||
@ -165,6 +185,46 @@
|
||||
<source>Install PKG</source>
|
||||
<translation>Install PKG</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui_context_menus.h" line="299"/>
|
||||
<source>Game</source>
|
||||
<translation>Game</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui_context_menus.h" line="305"/>
|
||||
<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>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui_context_menus.h" line="312"/>
|
||||
<source>This game has no update to delete!</source>
|
||||
<translation>This game has no update to delete!</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui_context_menus.h" line="316"/>
|
||||
<source>Update</source>
|
||||
<translation>Update</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui_context_menus.h" line="321"/>
|
||||
<source>This game has no DLC to delete!</source>
|
||||
<translation>This game has no DLC to delete!</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui_context_menus.h" line="325"/>
|
||||
<source>DLC</source>
|
||||
<translation>DLC</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui_context_menus.h" line="332"/>
|
||||
<source>Delete %1</source>
|
||||
<translation>Delete %1</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui_context_menus.h" line="333"/>
|
||||
<source>Are you sure you want to delete %1's %2 directory?</source>
|
||||
<translation>Are you sure you want to delete %1's %2 directory?</translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>MainWindow</name>
|
||||
@ -417,6 +477,11 @@
|
||||
<source>Enable Fullscreen</source>
|
||||
<translation>Enable Fullscreen</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../settings_dialog.ui" line="140"/>
|
||||
<source>Enable Separate Update Folder</source>
|
||||
<translation>Enable Separate Update Folder</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../settings_dialog.ui" line="129"/>
|
||||
<source>Show Splash</source>
|
||||
@ -1056,6 +1121,11 @@
|
||||
<source>fullscreenCheckBox</source>
|
||||
<translation>啟用全螢幕:\n自動將遊戲視窗設置為全螢幕模式。\n可以按F11鍵進行切換。</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../settings_dialog.cpp" line="293"/>
|
||||
<source>separateUpdatesCheckBox</source>
|
||||
<translation>Enable Separate Update Folder:\nEnables installing game updates into a separate folder for easy management.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../settings_dialog.cpp" line="295"/>
|
||||
<source>showSplashCheckBox</source>
|
||||
|
@ -446,7 +446,8 @@ Liverpool::Task Liverpool::ProcessGraphics(std::span<const u32> dcb, std::span<c
|
||||
regs.cs_program.dim_z = dispatch_direct->dim_z;
|
||||
regs.cs_program.dispatch_initiator = dispatch_direct->dispatch_initiator;
|
||||
if (DebugState.DumpingCurrentReg()) {
|
||||
DebugState.PushRegsDump(base_addr, reinterpret_cast<uintptr_t>(header), regs);
|
||||
DebugState.PushRegsDump(base_addr, reinterpret_cast<uintptr_t>(header), regs,
|
||||
true);
|
||||
}
|
||||
if (rasterizer && (regs.cs_program.dispatch_initiator & 1)) {
|
||||
const auto cmd_address = reinterpret_cast<const void*>(header);
|
||||
@ -463,7 +464,8 @@ Liverpool::Task Liverpool::ProcessGraphics(std::span<const u32> dcb, std::span<c
|
||||
const auto ib_address = mapped_queues[GfxQueueId].indirect_args_addr;
|
||||
const auto size = sizeof(PM4CmdDispatchIndirect::GroupDimensions);
|
||||
if (DebugState.DumpingCurrentReg()) {
|
||||
DebugState.PushRegsDump(base_addr, reinterpret_cast<uintptr_t>(header), regs);
|
||||
DebugState.PushRegsDump(base_addr, reinterpret_cast<uintptr_t>(header), regs,
|
||||
true);
|
||||
}
|
||||
if (rasterizer && (regs.cs_program.dispatch_initiator & 1)) {
|
||||
const auto cmd_address = reinterpret_cast<const void*>(header);
|
||||
@ -645,7 +647,7 @@ Liverpool::Task Liverpool::ProcessCompute(std::span<const u32> acb, int vqid) {
|
||||
regs.cs_program.dim_z = dispatch_direct->dim_z;
|
||||
regs.cs_program.dispatch_initiator = dispatch_direct->dispatch_initiator;
|
||||
if (DebugState.DumpingCurrentReg()) {
|
||||
DebugState.PushRegsDump(base_addr, reinterpret_cast<uintptr_t>(header), regs);
|
||||
DebugState.PushRegsDump(base_addr, reinterpret_cast<uintptr_t>(header), regs, true);
|
||||
}
|
||||
if (rasterizer && (regs.cs_program.dispatch_initiator & 1)) {
|
||||
const auto cmd_address = reinterpret_cast<const void*>(header);
|
||||
|
@ -144,10 +144,10 @@ static constexpr std::array component_bits = {
|
||||
std::array{8, 8, 0, 0}, // 3 Format8_8
|
||||
std::array{32, 0, 0, 0}, // 4 Format32
|
||||
std::array{16, 16, 0, 0}, // 5 Format16_16
|
||||
std::array{10, 11, 11, 0}, // 6 Format10_11_11
|
||||
std::array{11, 11, 10, 0}, // 7 Format11_11_10
|
||||
std::array{10, 10, 10, 2}, // 8 Format10_10_10_2
|
||||
std::array{2, 10, 10, 10}, // 9 Format2_10_10_10
|
||||
std::array{11, 11, 10, 0}, // 6 Format10_11_11
|
||||
std::array{10, 11, 11, 0}, // 7 Format11_11_10
|
||||
std::array{2, 10, 10, 10}, // 8 Format10_10_10_2
|
||||
std::array{10, 10, 10, 2}, // 9 Format2_10_10_10
|
||||
std::array{8, 8, 8, 8}, // 10 Format8_8_8_8
|
||||
std::array{32, 32, 0, 0}, // 11 Format32_32
|
||||
std::array{16, 16, 16, 16}, // 12 Format16_16_16_16
|
||||
@ -155,12 +155,12 @@ static constexpr std::array component_bits = {
|
||||
std::array{32, 32, 32, 32}, // 14 Format32_32_32_32
|
||||
std::array{0, 0, 0, 0}, // 15
|
||||
std::array{5, 6, 5, 0}, // 16 Format5_6_5
|
||||
std::array{1, 5, 5, 5}, // 17 Format1_5_5_5
|
||||
std::array{5, 5, 5, 1}, // 18 Format5_5_5_1
|
||||
std::array{5, 5, 5, 1}, // 17 Format1_5_5_5
|
||||
std::array{1, 5, 5, 5}, // 18 Format5_5_5_1
|
||||
std::array{4, 4, 4, 4}, // 19 Format4_4_4_4
|
||||
std::array{8, 24, 0, 0}, // 20 Format8_24
|
||||
std::array{24, 8, 0, 0}, // 21 Format24_8
|
||||
std::array{24, 8, 0, 0}, // 22 FormatX24_8_32
|
||||
std::array{24, 8, 0, 0}, // 20 Format8_24
|
||||
std::array{8, 24, 0, 0}, // 21 Format24_8
|
||||
std::array{8, 24, 0, 0}, // 22 FormatX24_8_32
|
||||
std::array{0, 0, 0, 0}, // 23
|
||||
std::array{0, 0, 0, 0}, // 24
|
||||
std::array{0, 0, 0, 0}, // 25
|
||||
@ -197,10 +197,10 @@ static constexpr std::array component_offset = {
|
||||
std::array{0, 8, -1, -1}, // 3 Format8_8
|
||||
std::array{0, -1, -1, -1}, // 4 Format32
|
||||
std::array{0, 16, -1, -1}, // 5 Format16_16
|
||||
std::array{0, 10, 21, -1}, // 6 Format10_11_11
|
||||
std::array{0, 11, 22, -1}, // 7 Format11_11_10
|
||||
std::array{0, 10, 20, 30}, // 8 Format10_10_10_2
|
||||
std::array{0, 2, 12, 22}, // 9 Format2_10_10_10
|
||||
std::array{0, 11, 22, -1}, // 6 Format10_11_11
|
||||
std::array{0, 10, 21, -1}, // 7 Format11_11_10
|
||||
std::array{0, 2, 12, 22}, // 8 Format10_10_10_2
|
||||
std::array{0, 10, 20, 30}, // 9 Format2_10_10_10
|
||||
std::array{0, 8, 16, 24}, // 10 Format8_8_8_8
|
||||
std::array{0, 32, -1, -1}, // 11 Format32_32
|
||||
std::array{0, 16, 32, 48}, // 12 Format16_16_16_16
|
||||
@ -208,12 +208,12 @@ static constexpr std::array component_offset = {
|
||||
std::array{0, 32, 64, 96}, // 14 Format32_32_32_32
|
||||
std::array{-1, -1, -1, -1}, // 15
|
||||
std::array{0, 5, 11, -1}, // 16 Format5_6_5
|
||||
std::array{0, 1, 6, 11}, // 17 Format1_5_5_5
|
||||
std::array{0, 5, 10, 15}, // 18 Format5_5_5_1
|
||||
std::array{0, 5, 10, 15}, // 17 Format1_5_5_5
|
||||
std::array{0, 1, 6, 11}, // 18 Format5_5_5_1
|
||||
std::array{0, 4, 8, 12}, // 19 Format4_4_4_4
|
||||
std::array{0, 8, -1, -1}, // 20 Format8_24
|
||||
std::array{0, 24, -1, -1}, // 21 Format24_8
|
||||
std::array{0, 24, -1, -1}, // 22 FormatX24_8_32
|
||||
std::array{0, 24, -1, -1}, // 20 Format8_24
|
||||
std::array{0, 8, -1, -1}, // 21 Format24_8
|
||||
std::array{0, 8, -1, -1}, // 22 FormatX24_8_32
|
||||
std::array{-1, -1, -1, -1}, // 23
|
||||
std::array{-1, -1, -1, -1}, // 24
|
||||
std::array{-1, -1, -1, -1}, // 25
|
||||
|
@ -2,11 +2,15 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
#include "common/assert.h"
|
||||
#include "common/number_utils.h"
|
||||
#include "video_core/amdgpu/pixel_format.h"
|
||||
#include "video_core/renderer_vulkan/liverpool_to_vk.h"
|
||||
|
||||
#include <magic_enum.hpp>
|
||||
|
||||
#define INVALID_NUMBER_FORMAT_COMBO \
|
||||
LOG_ERROR(Render_Vulkan, "Unsupported number type {} for format {}", number_type, format);
|
||||
|
||||
namespace Vulkan::LiverpoolToVK {
|
||||
|
||||
using DepthBuffer = Liverpool::DepthBuffer;
|
||||
@ -725,55 +729,362 @@ void EmitQuadToTriangleListIndices(u8* out_ptr, u32 num_vertices) {
|
||||
}
|
||||
}
|
||||
|
||||
static constexpr float U8ToUnorm(u8 v) {
|
||||
static constexpr auto c = 1.0f / 255.0f;
|
||||
return float(v * c);
|
||||
}
|
||||
|
||||
vk::ClearValue ColorBufferClearValue(const AmdGpu::Liverpool::ColorBuffer& color_buffer) {
|
||||
const auto comp_swap = color_buffer.info.comp_swap.Value();
|
||||
ASSERT_MSG(comp_swap == Liverpool::ColorBuffer::SwapMode::Standard ||
|
||||
comp_swap == Liverpool::ColorBuffer::SwapMode::Alternate,
|
||||
"Unsupported component swap mode {}", static_cast<u32>(comp_swap));
|
||||
|
||||
const bool comp_swap_alt = comp_swap == Liverpool::ColorBuffer::SwapMode::Alternate;
|
||||
const auto format = color_buffer.info.format.Value();
|
||||
const auto number_type = color_buffer.info.number_type.Value();
|
||||
|
||||
const auto& c0 = color_buffer.clear_word0;
|
||||
const auto& c1 = color_buffer.clear_word1;
|
||||
const auto num_bits = AmdGpu::NumBits(color_buffer.info.format);
|
||||
const auto num_components = AmdGpu::NumComponents(format);
|
||||
|
||||
const bool comp_swap_alt =
|
||||
comp_swap == AmdGpu::Liverpool::ColorBuffer::SwapMode::Alternate ||
|
||||
comp_swap == AmdGpu::Liverpool::ColorBuffer::SwapMode::AlternateReverse;
|
||||
const bool comp_swap_reverse =
|
||||
comp_swap == AmdGpu::Liverpool::ColorBuffer::SwapMode::StandardReverse ||
|
||||
comp_swap == AmdGpu::Liverpool::ColorBuffer::SwapMode::AlternateReverse;
|
||||
|
||||
vk::ClearColorValue color{};
|
||||
switch (color_buffer.info.number_type) {
|
||||
case AmdGpu::NumberFormat::Snorm:
|
||||
[[fallthrough]];
|
||||
case AmdGpu::NumberFormat::SnormNz:
|
||||
[[fallthrough]];
|
||||
case AmdGpu::NumberFormat::Unorm:
|
||||
[[fallthrough]];
|
||||
case AmdGpu::NumberFormat::Srgb: {
|
||||
switch (num_bits) {
|
||||
case 32: {
|
||||
color.float32 = std::array{
|
||||
U8ToUnorm((c0 >> (comp_swap_alt ? 16 : 0)) & 0xff),
|
||||
U8ToUnorm((c0 >> 8) & 0xff),
|
||||
U8ToUnorm((c0 >> (comp_swap_alt ? 0 : 16)) & 0xff),
|
||||
U8ToUnorm((c0 >> 24) & 0xff),
|
||||
};
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
LOG_ERROR(Render_Vulkan, "Missing clear color conversion for bits {}", num_bits);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
switch (number_type) {
|
||||
case AmdGpu::NumberFormat::Uint:
|
||||
case AmdGpu::NumberFormat::Sint:
|
||||
color.uint32[3] = 1;
|
||||
break;
|
||||
default:
|
||||
color.float32[3] = 1.0f;
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
LOG_ERROR(Render_Vulkan, "Missing clear color conversion for type {}",
|
||||
color_buffer.info.number_type.Value());
|
||||
|
||||
switch (format) {
|
||||
case AmdGpu::DataFormat::Format8:
|
||||
switch (number_type) {
|
||||
case AmdGpu::NumberFormat::Unorm:
|
||||
case AmdGpu::NumberFormat::Srgb: // Should we handle gamma correction here?
|
||||
color.float32[0] = NumberUtils::U8ToUnorm(c0 & 0xff);
|
||||
break;
|
||||
break;
|
||||
case AmdGpu::NumberFormat::Snorm:
|
||||
case AmdGpu::NumberFormat::SnormNz:
|
||||
color.float32[0] = NumberUtils::S8ToSnorm(c0 & 0xff);
|
||||
break;
|
||||
case AmdGpu::NumberFormat::Uint:
|
||||
case AmdGpu::NumberFormat::Sint:
|
||||
color.uint32[0] = c0;
|
||||
break;
|
||||
default:
|
||||
INVALID_NUMBER_FORMAT_COMBO;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case AmdGpu::DataFormat::Format16:
|
||||
switch (number_type) {
|
||||
case AmdGpu::NumberFormat::Unorm:
|
||||
color.float32[0] = NumberUtils::U16ToUnorm(c0 & 0xffff);
|
||||
break;
|
||||
case AmdGpu::NumberFormat::Snorm:
|
||||
case AmdGpu::NumberFormat::SnormNz:
|
||||
color.float32[0] = NumberUtils::S16ToSnorm(c0 & 0xffff);
|
||||
break;
|
||||
case AmdGpu::NumberFormat::Uint:
|
||||
case AmdGpu::NumberFormat::Sint:
|
||||
color.uint32[0] = c0;
|
||||
break;
|
||||
case AmdGpu::NumberFormat::Float:
|
||||
color.float32[0] = NumberUtils::Uf16ToF32(c0 & 0xffff);
|
||||
break;
|
||||
default:
|
||||
INVALID_NUMBER_FORMAT_COMBO;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case AmdGpu::DataFormat::Format8_8:
|
||||
switch (number_type) {
|
||||
case AmdGpu::NumberFormat::Unorm:
|
||||
case AmdGpu::NumberFormat::Srgb: // Should we handle gamma correction here?
|
||||
color.float32[0] = NumberUtils::U8ToUnorm(c0 & 0xff);
|
||||
color.float32[1] = NumberUtils::U8ToUnorm((c0 >> 8) & 0xff);
|
||||
break;
|
||||
case AmdGpu::NumberFormat::Snorm:
|
||||
case AmdGpu::NumberFormat::SnormNz:
|
||||
color.float32[0] = NumberUtils::S8ToSnorm(c0 & 0xff);
|
||||
color.float32[1] = NumberUtils::S8ToSnorm((c0 >> 8) & 0xff);
|
||||
break;
|
||||
case AmdGpu::NumberFormat::Uint:
|
||||
case AmdGpu::NumberFormat::Sint:
|
||||
color.uint32[0] = c0 & 0xff;
|
||||
color.uint32[1] = (c0 >> 8) & 0xff;
|
||||
break;
|
||||
default:
|
||||
INVALID_NUMBER_FORMAT_COMBO;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case AmdGpu::DataFormat::Format32:
|
||||
switch (number_type) {
|
||||
case AmdGpu::NumberFormat::Uint:
|
||||
case AmdGpu::NumberFormat::Sint:
|
||||
color.uint32[0] = c0;
|
||||
break;
|
||||
case AmdGpu::NumberFormat::Float:
|
||||
color.float32[0] = *(reinterpret_cast<const float*>(&c0));
|
||||
break;
|
||||
default:
|
||||
INVALID_NUMBER_FORMAT_COMBO;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case AmdGpu::DataFormat::Format16_16:
|
||||
switch (number_type) {
|
||||
case AmdGpu::NumberFormat::Unorm:
|
||||
color.float32[0] = NumberUtils::U16ToUnorm(c0 & 0xffff);
|
||||
color.float32[1] = NumberUtils::U16ToUnorm((c0 >> 16) & 0xffff);
|
||||
break;
|
||||
case AmdGpu::NumberFormat::Snorm:
|
||||
case AmdGpu::NumberFormat::SnormNz:
|
||||
color.float32[0] = NumberUtils::S16ToSnorm(c0 & 0xffff);
|
||||
color.float32[1] = NumberUtils::S16ToSnorm((c0 >> 16) & 0xffff);
|
||||
break;
|
||||
case AmdGpu::NumberFormat::Uint:
|
||||
case AmdGpu::NumberFormat::Sint:
|
||||
color.uint32[0] = c0 & 0xffff;
|
||||
color.uint32[1] = (c0 >> 16) & 0xffff;
|
||||
break;
|
||||
case AmdGpu::NumberFormat::Float:
|
||||
color.float32[0] = NumberUtils::Uf16ToF32(c0 & 0xffff);
|
||||
color.float32[1] = NumberUtils::Uf16ToF32((c0 >> 16) & 0xffff);
|
||||
break;
|
||||
default:
|
||||
INVALID_NUMBER_FORMAT_COMBO;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case AmdGpu::DataFormat::Format10_11_11:
|
||||
color.float32[0] = NumberUtils::Uf11ToF32(c0 & 0x7ff);
|
||||
color.float32[1] = NumberUtils::Uf11ToF32((c0 >> 11) & 0x7ff);
|
||||
color.float32[2] = NumberUtils::Uf10ToF32((c0 >> 22) & 0x3ff);
|
||||
break;
|
||||
case AmdGpu::DataFormat::Format11_11_10:
|
||||
color.float32[0] = NumberUtils::Uf10ToF32(c0 & 0x3ff);
|
||||
color.float32[1] = NumberUtils::Uf11ToF32((c0 >> 10) & 0x7ff);
|
||||
color.float32[2] = NumberUtils::Uf11ToF32((c0 >> 21) & 0x7ff);
|
||||
break;
|
||||
case AmdGpu::DataFormat::Format5_9_9_9: {
|
||||
int exponent;
|
||||
union {
|
||||
float f;
|
||||
u32 u;
|
||||
} scale;
|
||||
|
||||
exponent = (c0 >> 27) - 10;
|
||||
scale.u = (exponent + 127) << 23;
|
||||
|
||||
color.float32[0] = (c0 & 0x1ff) * scale.f;
|
||||
color.float32[1] = ((c0 >> 9) & 0x1ff) * scale.f;
|
||||
color.float32[2] = ((c0 >> 18) & 0x1ff) * scale.f;
|
||||
break;
|
||||
}
|
||||
case AmdGpu::DataFormat::Format10_10_10_2:
|
||||
switch (number_type) {
|
||||
case AmdGpu::NumberFormat::Unorm:
|
||||
color.float32[0] = NumberUtils::U2ToUnorm(c0 & 0x3);
|
||||
color.float32[1] = NumberUtils::U10ToUnorm((c0 >> 2) & 0x3ff);
|
||||
color.float32[2] = NumberUtils::U10ToUnorm((c0 >> 12) & 0x3ff);
|
||||
color.float32[3] = NumberUtils::U10ToUnorm(c0 >> 22);
|
||||
break;
|
||||
case AmdGpu::NumberFormat::Snorm:
|
||||
case AmdGpu::NumberFormat::SnormNz:
|
||||
color.float32[0] = NumberUtils::S2ToSnorm(c0 & 0x3);
|
||||
color.float32[1] = NumberUtils::S10ToSnorm((c0 >> 2) & 0x3ff);
|
||||
color.float32[2] = NumberUtils::S10ToSnorm((c0 >> 12) & 0x3ff);
|
||||
color.float32[3] = NumberUtils::S2ToSnorm(c0 >> 22);
|
||||
break;
|
||||
case AmdGpu::NumberFormat::Uint:
|
||||
case AmdGpu::NumberFormat::Sint:
|
||||
color.uint32[0] = c0 & 0x3;
|
||||
color.uint32[1] = (c0 >> 2) & 0x3ff;
|
||||
color.uint32[2] = (c0 >> 12) & 0x3ff;
|
||||
color.uint32[3] = c0 >> 22;
|
||||
break;
|
||||
default:
|
||||
INVALID_NUMBER_FORMAT_COMBO;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case AmdGpu::DataFormat::Format2_10_10_10:
|
||||
switch (number_type) {
|
||||
case AmdGpu::NumberFormat::Unorm:
|
||||
color.float32[0] = NumberUtils::U10ToUnorm(c0 & 0x3ff);
|
||||
color.float32[1] = NumberUtils::U10ToUnorm((c0 >> 10) & 0x3ff);
|
||||
color.float32[2] = NumberUtils::U10ToUnorm((c0 >> 20) & 0x3ff);
|
||||
color.float32[3] = NumberUtils::U2ToUnorm(c0 >> 30);
|
||||
break;
|
||||
case AmdGpu::NumberFormat::Snorm:
|
||||
case AmdGpu::NumberFormat::SnormNz:
|
||||
color.float32[0] = NumberUtils::S10ToSnorm(c0 & 0x3ff);
|
||||
color.float32[1] = NumberUtils::S10ToSnorm((c0 >> 10) & 0x3ff);
|
||||
color.float32[2] = NumberUtils::S10ToSnorm((c0 >> 20) & 0x3ff);
|
||||
color.float32[3] = NumberUtils::S2ToSnorm(c0 >> 30);
|
||||
break;
|
||||
case AmdGpu::NumberFormat::Uint:
|
||||
case AmdGpu::NumberFormat::Sint:
|
||||
color.uint32[0] = c0 & 0x3ff;
|
||||
color.uint32[1] = (c0 >> 10) & 0x3ff;
|
||||
color.uint32[2] = (c0 >> 20) & 0x3ff;
|
||||
color.uint32[3] = c0 >> 30;
|
||||
break;
|
||||
default:
|
||||
INVALID_NUMBER_FORMAT_COMBO;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case AmdGpu::DataFormat::Format8_8_8_8:
|
||||
switch (number_type) {
|
||||
case AmdGpu::NumberFormat::Unorm:
|
||||
case AmdGpu::NumberFormat::Srgb: // Should we handle gamma correction here?
|
||||
color.float32[0] = NumberUtils::U8ToUnorm(c0 & 0xff);
|
||||
color.float32[1] = NumberUtils::U8ToUnorm((c0 >> 8) & 0xff);
|
||||
color.float32[2] = NumberUtils::U8ToUnorm((c0 >> 16) & 0xff);
|
||||
color.float32[3] = NumberUtils::U8ToUnorm(c0 >> 24);
|
||||
break;
|
||||
case AmdGpu::NumberFormat::Snorm:
|
||||
case AmdGpu::NumberFormat::SnormNz:
|
||||
color.float32[0] = NumberUtils::S8ToSnorm(c0 & 0xff);
|
||||
color.float32[1] = NumberUtils::S8ToSnorm((c0 >> 8) & 0xff);
|
||||
color.float32[2] = NumberUtils::S8ToSnorm((c0 >> 16) & 0xff);
|
||||
color.float32[3] = NumberUtils::S8ToSnorm(c0 >> 24);
|
||||
break;
|
||||
case AmdGpu::NumberFormat::Uint:
|
||||
case AmdGpu::NumberFormat::Sint:
|
||||
color.uint32[0] = c0 & 0xff;
|
||||
color.uint32[1] = (c0 >> 8) & 0xff;
|
||||
color.uint32[2] = (c0 >> 16) & 0xff;
|
||||
color.uint32[3] = c0 >> 24;
|
||||
break;
|
||||
default:
|
||||
INVALID_NUMBER_FORMAT_COMBO;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case AmdGpu::DataFormat::Format32_32:
|
||||
switch (number_type) {
|
||||
case AmdGpu::NumberFormat::Uint:
|
||||
case AmdGpu::NumberFormat::Sint:
|
||||
color.uint32[0] = c0;
|
||||
color.uint32[1] = c1;
|
||||
break;
|
||||
case AmdGpu::NumberFormat::Float:
|
||||
color.float32[0] = *(reinterpret_cast<const float*>(&c0));
|
||||
color.float32[1] = *(reinterpret_cast<const float*>(&c1));
|
||||
break;
|
||||
default:
|
||||
INVALID_NUMBER_FORMAT_COMBO;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case AmdGpu::DataFormat::Format16_16_16_16:
|
||||
switch (number_type) {
|
||||
case AmdGpu::NumberFormat::Unorm:
|
||||
color.float32[0] = NumberUtils::U16ToUnorm(c0 & 0xffff);
|
||||
color.float32[1] = NumberUtils::U16ToUnorm((c0 >> 16) & 0xffff);
|
||||
color.float32[2] = NumberUtils::U16ToUnorm(c1 & 0xffff);
|
||||
color.float32[3] = NumberUtils::U16ToUnorm((c1 >> 16) & 0xffff);
|
||||
break;
|
||||
case AmdGpu::NumberFormat::Snorm:
|
||||
case AmdGpu::NumberFormat::SnormNz:
|
||||
color.float32[0] = NumberUtils::S16ToSnorm(c0 & 0xffff);
|
||||
color.float32[1] = NumberUtils::S16ToSnorm((c0 >> 16) & 0xffff);
|
||||
color.float32[2] = NumberUtils::S16ToSnorm(c1 & 0xffff);
|
||||
color.float32[3] = NumberUtils::S16ToSnorm((c1 >> 16) & 0xffff);
|
||||
break;
|
||||
case AmdGpu::NumberFormat::Uint:
|
||||
case AmdGpu::NumberFormat::Sint:
|
||||
color.uint32[0] = c0 & 0xffff;
|
||||
color.uint32[1] = (c0 >> 16) & 0xffff;
|
||||
color.uint32[2] = c1 & 0xffff;
|
||||
color.uint32[3] = (c1 >> 16) & 0xffff;
|
||||
break;
|
||||
case AmdGpu::NumberFormat::Float:
|
||||
color.float32[0] = NumberUtils::Uf16ToF32(c0 & 0xffff);
|
||||
color.float32[1] = NumberUtils::Uf16ToF32((c0 >> 16) & 0xffff);
|
||||
color.float32[2] = NumberUtils::Uf16ToF32(c1 & 0xffff);
|
||||
color.float32[3] = NumberUtils::Uf16ToF32((c1 >> 16) & 0xffff);
|
||||
break;
|
||||
default:
|
||||
INVALID_NUMBER_FORMAT_COMBO;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case AmdGpu::DataFormat::Format32_32_32_32:
|
||||
switch (number_type) {
|
||||
case AmdGpu::NumberFormat::Uint:
|
||||
case AmdGpu::NumberFormat::Sint:
|
||||
color.uint32[0] = c0;
|
||||
color.uint32[1] = c0;
|
||||
color.uint32[2] = c0;
|
||||
color.uint32[3] = c1;
|
||||
break;
|
||||
case AmdGpu::NumberFormat::Float:
|
||||
color.float32[0] = *(reinterpret_cast<const float*>(&c0));
|
||||
color.float32[1] = *(reinterpret_cast<const float*>(&c0));
|
||||
color.float32[2] = *(reinterpret_cast<const float*>(&c0));
|
||||
color.float32[3] = *(reinterpret_cast<const float*>(&c1));
|
||||
break;
|
||||
default:
|
||||
INVALID_NUMBER_FORMAT_COMBO;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case AmdGpu::DataFormat::Format5_6_5:
|
||||
color.float32[0] = NumberUtils::U5ToUnorm(c0 & 0x1f);
|
||||
color.float32[1] = NumberUtils::U6ToUnorm((c0 >> 5) & 0x3f);
|
||||
color.float32[2] = NumberUtils::U5ToUnorm(c0 >> 11);
|
||||
break;
|
||||
case AmdGpu::DataFormat::Format1_5_5_5:
|
||||
color.float32[0] = NumberUtils::U5ToUnorm(c0 & 0x1f);
|
||||
color.float32[1] = NumberUtils::U5ToUnorm((c0 >> 5) & 0x1f);
|
||||
color.float32[2] = NumberUtils::U5ToUnorm((c0 >> 10) & 0x1f);
|
||||
color.float32[3] = (c0 >> 15) ? 1.0f : 0.0f;
|
||||
break;
|
||||
case AmdGpu::DataFormat::Format5_5_5_1:
|
||||
color.float32[0] = (c0 & 0x1) ? 1.0f : 0.0f;
|
||||
color.float32[1] = NumberUtils::U5ToUnorm((c0 >> 1) & 0x1f);
|
||||
color.float32[2] = NumberUtils::U5ToUnorm((c0 >> 6) & 0x1f);
|
||||
color.float32[3] = NumberUtils::U5ToUnorm((c0 >> 11) & 0x1f);
|
||||
break;
|
||||
case AmdGpu::DataFormat::Format4_4_4_4:
|
||||
color.float32[0] = NumberUtils::U4ToUnorm(c0 & 0xf);
|
||||
color.float32[1] = NumberUtils::U4ToUnorm((c0 >> 4) & 0xf);
|
||||
color.float32[2] = NumberUtils::U4ToUnorm((c0 >> 8) & 0xf);
|
||||
color.float32[3] = NumberUtils::U4ToUnorm(c0 >> 12);
|
||||
break;
|
||||
default:
|
||||
LOG_ERROR(Render_Vulkan, "Unsupported color buffer format: {}", format);
|
||||
break;
|
||||
}
|
||||
|
||||
if (num_components == 1) {
|
||||
if (comp_swap != Liverpool::ColorBuffer::SwapMode::Standard) {
|
||||
color.float32[static_cast<int>(comp_swap)] = color.float32[0];
|
||||
color.float32[0] = 0.0f;
|
||||
}
|
||||
} else {
|
||||
if (comp_swap_alt && num_components == 4) {
|
||||
std::swap(color.float32[0], color.float32[2]);
|
||||
}
|
||||
|
||||
if (comp_swap_reverse) {
|
||||
std::reverse(std::begin(color.float32), std::begin(color.float32) + num_components);
|
||||
}
|
||||
|
||||
if (comp_swap_alt && num_components != 4) {
|
||||
color.float32[3] = color.float32[num_components - 1];
|
||||
color.float32[num_components - 1] = 0.0f;
|
||||
}
|
||||
}
|
||||
|
||||
return {.color = color};
|
||||
}
|
||||
|
||||
|
@ -329,6 +329,11 @@ bool ImageInfo::IsMipOf(const ImageInfo& info) const {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Ensure that address matches too.
|
||||
if ((info.guest_address + info.mips_layout[mip].offset) != guest_address) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -237,6 +237,16 @@ ImageId TextureCache::FindImage(const ImageInfo& info, FindFlags flags) {
|
||||
}
|
||||
}
|
||||
|
||||
if (image_id) {
|
||||
Image& image_resoved = slot_images[image_id];
|
||||
|
||||
if (image_resoved.info.resources < info.resources) {
|
||||
// The image was clearly picked up wrong.
|
||||
FreeImage(image_id);
|
||||
image_id = {};
|
||||
LOG_WARNING(Render_Vulkan, "Image overlap resolve failed");
|
||||
}
|
||||
}
|
||||
// Create and register a new image
|
||||
if (!image_id) {
|
||||
image_id = slot_images.insert(instance, scheduler, info);
|
||||
|
Loading…
Reference in New Issue
Block a user