Merge branch 'shadps4-emu:main' into gcc-ci

This commit is contained in:
tomboylover93 2025-01-02 13:42:56 -03:00 committed by GitHub
commit bddecc55b8
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
50 changed files with 1082 additions and 724 deletions

View File

@ -66,7 +66,7 @@ void RegPopup::DrawColorBuffer(const AmdGpu::Liverpool::ColorBuffer& buffer) {
"GetColorSliceSize()", buffer.GetColorSliceSize(), "GetColorSliceSize()", buffer.GetColorSliceSize(),
"GetTilingMode()", buffer.GetTilingMode(), "GetTilingMode()", buffer.GetTilingMode(),
"IsTiled()", buffer.IsTiled(), "IsTiled()", buffer.IsTiled(),
"NumFormat()", buffer.NumFormat() "NumFormat()", buffer.GetNumberFmt()
); );
// clang-format on // clang-format on

View File

@ -3,13 +3,13 @@
#include <memory> #include <memory>
#include <mutex> #include <mutex>
#include <shared_mutex> #include <stop_token>
#include <thread>
#include <magic_enum/magic_enum.hpp> #include <magic_enum/magic_enum.hpp>
#include "common/assert.h" #include "common/assert.h"
#include "common/config.h" #include "common/config.h"
#include "common/logging/log.h" #include "common/logging/log.h"
#include "common/polyfill_thread.h"
#include "common/thread.h" #include "common/thread.h"
#include "core/libraries/audio/audioout.h" #include "core/libraries/audio/audioout.h"
#include "core/libraries/audio/audioout_backend.h" #include "core/libraries/audio/audioout_backend.h"
@ -18,7 +18,7 @@
namespace Libraries::AudioOut { namespace Libraries::AudioOut {
std::shared_mutex ports_mutex; std::mutex port_open_mutex{};
std::array<PortOut, SCE_AUDIO_OUT_NUM_PORTS> ports_out{}; std::array<PortOut, SCE_AUDIO_OUT_NUM_PORTS> ports_out{};
static std::unique_ptr<AudioOutBackend> audio; static std::unique_ptr<AudioOutBackend> audio;
@ -93,17 +93,20 @@ int PS4_SYSV_ABI sceAudioOutClose(s32 handle) {
return ORBIS_AUDIO_OUT_ERROR_INVALID_PORT; return ORBIS_AUDIO_OUT_ERROR_INVALID_PORT;
} }
std::scoped_lock lock(ports_mutex); std::unique_lock open_lock{port_open_mutex};
auto& port = ports_out.at(handle - 1); auto& port = ports_out.at(handle - 1);
if (!port.impl) { {
return ORBIS_AUDIO_OUT_ERROR_INVALID_PORT; std::unique_lock lock{port.mutex};
if (!port.IsOpen()) {
return ORBIS_AUDIO_OUT_ERROR_INVALID_PORT;
}
std::free(port.output_buffer);
port.output_buffer = nullptr;
port.output_ready = false;
port.impl = nullptr;
} }
// Stop outside of port lock scope to prevent deadlocks.
port.output_thread.Stop(); port.output_thread.Stop();
std::free(port.output_buffer);
port.output_buffer = nullptr;
port.output_ready = false;
port.impl = nullptr;
return ORBIS_OK; return ORBIS_OK;
} }
@ -172,35 +175,34 @@ int PS4_SYSV_ABI sceAudioOutGetPortState(s32 handle, OrbisAudioOutPortState* sta
return ORBIS_AUDIO_OUT_ERROR_INVALID_PORT; return ORBIS_AUDIO_OUT_ERROR_INVALID_PORT;
} }
std::scoped_lock lock(ports_mutex); auto& port = ports_out.at(handle - 1);
const auto& port = ports_out.at(handle - 1); {
if (!port.impl) { std::unique_lock lock{port.mutex};
return ORBIS_AUDIO_OUT_ERROR_INVALID_PORT; if (!port.IsOpen()) {
return ORBIS_AUDIO_OUT_ERROR_INVALID_PORT;
}
switch (port.type) {
case OrbisAudioOutPort::Main:
case OrbisAudioOutPort::Bgm:
case OrbisAudioOutPort::Voice:
state->output = 1;
state->channel = port.format_info.num_channels > 2 ? 2 : port.format_info.num_channels;
break;
case OrbisAudioOutPort::Personal:
case OrbisAudioOutPort::Padspk:
state->output = 4;
state->channel = 1;
break;
case OrbisAudioOutPort::Aux:
state->output = 0;
state->channel = 0;
break;
default:
UNREACHABLE();
}
state->rerouteCounter = 0;
state->volume = 127;
} }
state->rerouteCounter = 0;
state->volume = 127;
switch (port.type) {
case OrbisAudioOutPort::Main:
case OrbisAudioOutPort::Bgm:
case OrbisAudioOutPort::Voice:
state->output = 1;
state->channel = port.format_info.num_channels > 2 ? 2 : port.format_info.num_channels;
break;
case OrbisAudioOutPort::Personal:
case OrbisAudioOutPort::Padspk:
state->output = 4;
state->channel = 1;
break;
case OrbisAudioOutPort::Aux:
state->output = 0;
state->channel = 0;
break;
default:
UNREACHABLE();
}
return ORBIS_OK; return ORBIS_OK;
} }
@ -279,15 +281,16 @@ static void AudioOutputThread(PortOut* port, const std::stop_token& stop) {
while (true) { while (true) {
timer.Start(); timer.Start();
{ {
std::unique_lock lock{port->output_mutex}; std::unique_lock lock{port->mutex};
Common::CondvarWait(port->output_cv, lock, stop, [&] { return port->output_ready; }); if (port->output_cv.wait(lock, stop, [&] { return port->output_ready; })) {
if (stop.stop_requested()) { port->impl->Output(port->output_buffer);
break; port->output_ready = false;
} }
port->impl->Output(port->output_buffer);
port->output_ready = false;
} }
port->output_cv.notify_one(); port->output_cv.notify_one();
if (stop.stop_requested()) {
break;
}
timer.End(); timer.End();
} }
} }
@ -332,27 +335,30 @@ s32 PS4_SYSV_ABI sceAudioOutOpen(UserService::OrbisUserServiceUserId user_id,
return ORBIS_AUDIO_OUT_ERROR_INVALID_FORMAT; return ORBIS_AUDIO_OUT_ERROR_INVALID_FORMAT;
} }
std::scoped_lock lock{ports_mutex}; std::unique_lock open_lock{port_open_mutex};
const auto port = const auto port =
std::ranges::find_if(ports_out, [&](const PortOut& p) { return p.impl == nullptr; }); std::ranges::find_if(ports_out, [&](const PortOut& p) { return !p.IsOpen(); });
if (port == ports_out.end()) { if (port == ports_out.end()) {
LOG_ERROR(Lib_AudioOut, "Audio ports are full"); LOG_ERROR(Lib_AudioOut, "Audio ports are full");
return ORBIS_AUDIO_OUT_ERROR_PORT_FULL; return ORBIS_AUDIO_OUT_ERROR_PORT_FULL;
} }
port->type = port_type; {
port->format_info = GetFormatInfo(format); std::unique_lock port_lock(port->mutex);
port->sample_rate = sample_rate;
port->buffer_frames = length;
port->volume.fill(SCE_AUDIO_OUT_VOLUME_0DB);
port->impl = audio->Open(*port); port->type = port_type;
port->format_info = GetFormatInfo(format);
port->sample_rate = sample_rate;
port->buffer_frames = length;
port->volume.fill(SCE_AUDIO_OUT_VOLUME_0DB);
port->output_buffer = std::malloc(port->BufferSize()); port->impl = audio->Open(*port);
port->output_ready = false;
port->output_thread.Run(
[port](const std::stop_token& stop) { AudioOutputThread(&*port, stop); });
port->output_buffer = std::malloc(port->BufferSize());
port->output_ready = false;
port->output_thread.Run(
[port](const std::stop_token& stop) { AudioOutputThread(&*port, stop); });
}
return std::distance(ports_out.begin(), port) + 1; return std::distance(ports_out.begin(), port) + 1;
} }
@ -367,14 +373,13 @@ s32 PS4_SYSV_ABI sceAudioOutOutput(s32 handle, void* ptr) {
} }
auto& port = ports_out.at(handle - 1); auto& port = ports_out.at(handle - 1);
if (!port.impl) {
return ORBIS_AUDIO_OUT_ERROR_INVALID_PORT;
}
{ {
std::unique_lock lock{port.output_mutex}; std::unique_lock lock{port.mutex};
if (!port.IsOpen()) {
return ORBIS_AUDIO_OUT_ERROR_INVALID_PORT;
}
port.output_cv.wait(lock, [&] { return !port.output_ready; }); port.output_cv.wait(lock, [&] { return !port.output_ready; });
if (ptr != nullptr) { if (ptr != nullptr && port.IsOpen()) {
std::memcpy(port.output_buffer, ptr, port.BufferSize()); std::memcpy(port.output_buffer, ptr, port.BufferSize());
port.output_ready = true; port.output_ready = true;
} }
@ -488,19 +493,19 @@ s32 PS4_SYSV_ABI sceAudioOutSetVolume(s32 handle, s32 flag, s32* vol) {
return ORBIS_AUDIO_OUT_ERROR_INVALID_PORT; return ORBIS_AUDIO_OUT_ERROR_INVALID_PORT;
} }
std::scoped_lock lock(ports_mutex);
auto& port = ports_out.at(handle - 1); auto& port = ports_out.at(handle - 1);
if (!port.impl) { {
return ORBIS_AUDIO_OUT_ERROR_INVALID_PORT; std::unique_lock lock{port.mutex};
} if (!port.IsOpen()) {
return ORBIS_AUDIO_OUT_ERROR_INVALID_PORT;
for (int i = 0; i < port.format_info.num_channels; i++, flag >>= 1u) {
if (flag & 0x1u) {
port.volume[i] = vol[i];
} }
for (int i = 0; i < port.format_info.num_channels; i++, flag >>= 1u) {
if (flag & 0x1u) {
port.volume[i] = vol[i];
}
}
port.impl->SetVolume(port.volume);
} }
port.impl->SetVolume(port.volume);
return ORBIS_OK; return ORBIS_OK;
} }

View File

@ -3,7 +3,9 @@
#pragma once #pragma once
#include <condition_variable>
#include <memory> #include <memory>
#include <mutex>
#include "common/bit_field.h" #include "common/bit_field.h"
#include "core/libraries/kernel/threads.h" #include "core/libraries/kernel/threads.h"
@ -74,10 +76,10 @@ struct AudioFormatInfo {
}; };
struct PortOut { struct PortOut {
std::mutex mutex;
std::unique_ptr<PortBackend> impl{}; std::unique_ptr<PortBackend> impl{};
void* output_buffer; void* output_buffer;
std::mutex output_mutex;
std::condition_variable_any output_cv; std::condition_variable_any output_cv;
bool output_ready; bool output_ready;
Kernel::Thread output_thread{}; Kernel::Thread output_thread{};
@ -88,6 +90,10 @@ struct PortOut {
u32 buffer_frames; u32 buffer_frames;
std::array<s32, 8> volume; std::array<s32, 8> volume;
[[nodiscard]] bool IsOpen() const {
return impl != nullptr;
}
[[nodiscard]] u32 BufferSize() const { [[nodiscard]] u32 BufferSize() const {
return buffer_frames * format_info.FrameSize(); return buffer_frames * format_info.FrameSize();
} }

View File

@ -14,7 +14,7 @@ namespace Libraries::AudioOut {
class SDLPortBackend : public PortBackend { class SDLPortBackend : public PortBackend {
public: public:
explicit SDLPortBackend(const PortOut& port) explicit SDLPortBackend(const PortOut& port)
: frame_size(port.format_info.FrameSize()), buffer_size(port.BufferSize()) { : frame_size(port.format_info.FrameSize()), guest_buffer_size(port.BufferSize()) {
// We want the latency for delivering frames out to be as small as possible, // We want the latency for delivering frames out to be as small as possible,
// so set the sample frames hint to the number of frames per buffer. // so set the sample frames hint to the number of frames per buffer.
const auto samples_num_str = std::to_string(port.buffer_frames); const auto samples_num_str = std::to_string(port.buffer_frames);
@ -33,7 +33,7 @@ public:
LOG_ERROR(Lib_AudioOut, "Failed to create SDL audio stream: {}", SDL_GetError()); LOG_ERROR(Lib_AudioOut, "Failed to create SDL audio stream: {}", SDL_GetError());
return; return;
} }
queue_threshold = CalculateQueueThreshold(); CalculateQueueThreshold();
if (!SDL_SetAudioStreamInputChannelMap(stream, port.format_info.channel_layout.data(), if (!SDL_SetAudioStreamInputChannelMap(stream, port.format_info.channel_layout.data(),
port.format_info.num_channels)) { port.format_info.num_channels)) {
LOG_ERROR(Lib_AudioOut, "Failed to configure SDL audio stream channel map: {}", LOG_ERROR(Lib_AudioOut, "Failed to configure SDL audio stream channel map: {}",
@ -71,9 +71,9 @@ public:
queue_threshold); queue_threshold);
SDL_ClearAudioStream(stream); SDL_ClearAudioStream(stream);
// Recalculate the threshold in case this happened because of a device change. // Recalculate the threshold in case this happened because of a device change.
queue_threshold = CalculateQueueThreshold(); CalculateQueueThreshold();
} }
if (!SDL_PutAudioStreamData(stream, ptr, static_cast<int>(buffer_size))) { if (!SDL_PutAudioStreamData(stream, ptr, static_cast<int>(guest_buffer_size))) {
LOG_ERROR(Lib_AudioOut, "Failed to output to SDL audio stream: {}", SDL_GetError()); LOG_ERROR(Lib_AudioOut, "Failed to output to SDL audio stream: {}", SDL_GetError());
} }
} }
@ -91,7 +91,7 @@ public:
} }
private: private:
[[nodiscard]] u32 CalculateQueueThreshold() const { void CalculateQueueThreshold() {
SDL_AudioSpec discard; SDL_AudioSpec discard;
int sdl_buffer_frames; int sdl_buffer_frames;
if (!SDL_GetAudioDeviceFormat(SDL_GetAudioStreamDevice(stream), &discard, if (!SDL_GetAudioDeviceFormat(SDL_GetAudioStreamDevice(stream), &discard,
@ -100,13 +100,22 @@ private:
SDL_GetError()); SDL_GetError());
sdl_buffer_frames = 0; sdl_buffer_frames = 0;
} }
return std::max<u32>(buffer_size, sdl_buffer_frames * frame_size) * 4; const auto sdl_buffer_size = sdl_buffer_frames * frame_size;
const auto new_threshold = std::max(guest_buffer_size, sdl_buffer_size) * 4;
if (host_buffer_size != sdl_buffer_size || queue_threshold != new_threshold) {
host_buffer_size = sdl_buffer_size;
queue_threshold = new_threshold;
LOG_INFO(Lib_AudioOut,
"SDL audio buffers: guest = {} bytes, host = {} bytes, threshold = {} bytes",
guest_buffer_size, host_buffer_size, queue_threshold);
}
} }
u32 frame_size; u32 frame_size;
u32 buffer_size; u32 guest_buffer_size;
u32 queue_threshold; u32 host_buffer_size{};
SDL_AudioStream* stream; u32 queue_threshold{};
SDL_AudioStream* stream{};
}; };
std::unique_ptr<PortBackend> SDLAudioOut::Open(PortOut& port) { std::unique_ptr<PortBackend> SDLAudioOut::Open(PortOut& port) {

View File

@ -55,6 +55,9 @@ public:
stop.request_stop(); stop.request_stop();
Join(); Join();
} }
thread = nullptr;
func = nullptr;
stop = std::stop_source{};
} }
static void* PS4_SYSV_ABI RunWrapper(void* arg) { static void* PS4_SYSV_ABI RunWrapper(void* arg) {

View File

@ -2,6 +2,7 @@
// SPDX-License-Identifier: GPL-2.0-or-later // SPDX-License-Identifier: GPL-2.0-or-later
#include <span> #include <span>
#include <thread>
#include <vector> #include <vector>
#include <core/libraries/system/msgdialog_ui.h> #include <core/libraries/system/msgdialog_ui.h>
@ -1139,10 +1140,6 @@ Error PS4_SYSV_ABI sceSaveDataGetSaveDataMemory2(OrbisSaveDataMemoryGet2* getPar
LOG_INFO(Lib_SaveData, "called without save memory initialized"); LOG_INFO(Lib_SaveData, "called without save memory initialized");
return Error::MEMORY_NOT_READY; return Error::MEMORY_NOT_READY;
} }
if (SaveMemory::IsSaving()) {
LOG_TRACE(Lib_SaveData, "called while saving");
return Error::BUSY_FOR_SAVING;
}
LOG_DEBUG(Lib_SaveData, "called"); LOG_DEBUG(Lib_SaveData, "called");
auto data = getParam->data; auto data = getParam->data;
if (data != nullptr) { if (data != nullptr) {
@ -1502,8 +1499,14 @@ Error PS4_SYSV_ABI sceSaveDataSetSaveDataMemory2(const OrbisSaveDataMemorySet2*
return Error::MEMORY_NOT_READY; return Error::MEMORY_NOT_READY;
} }
if (SaveMemory::IsSaving()) { if (SaveMemory::IsSaving()) {
LOG_TRACE(Lib_SaveData, "called while saving"); int count = 0;
return Error::BUSY_FOR_SAVING; while (++count < 100 && SaveMemory::IsSaving()) { // try for more 10 seconds
std::this_thread::sleep_for(chrono::milliseconds(100));
}
if (SaveMemory::IsSaving()) {
LOG_TRACE(Lib_SaveData, "called while saving");
return Error::BUSY_FOR_SAVING;
}
} }
LOG_DEBUG(Lib_SaveData, "called"); LOG_DEBUG(Lib_SaveData, "called");
auto data = setParam->data; auto data = setParam->data;
@ -1584,8 +1587,8 @@ Error PS4_SYSV_ABI sceSaveDataSetupSaveDataMemory2(const OrbisSaveDataMemorySetu
} else { } else {
SaveMemory::SetIcon(nullptr, 0); SaveMemory::SetIcon(nullptr, 0);
} }
SaveMemory::TriggerSaveWithoutEvent();
} }
SaveMemory::TriggerSaveWithoutEvent();
if (g_fw_ver >= ElfInfo::FW_45 && result != nullptr) { if (g_fw_ver >= ElfInfo::FW_45 && result != nullptr) {
result->existedMemorySize = existed_size; result->existedMemorySize = existed_size;
} }

View File

@ -10,327 +10,327 @@
namespace Libraries::Usbd { namespace Libraries::Usbd {
int PS4_SYSV_ABI sceUsbdAllocTransfer() { int PS4_SYSV_ABI sceUsbdAllocTransfer() {
LOG_ERROR(Lib_Usbd, "(STUBBED)called"); LOG_ERROR(Lib_Usbd, "(STUBBED) called");
return ORBIS_OK; return ORBIS_OK;
} }
int PS4_SYSV_ABI sceUsbdAttachKernelDriver() { int PS4_SYSV_ABI sceUsbdAttachKernelDriver() {
LOG_ERROR(Lib_Usbd, "(STUBBED)called"); LOG_ERROR(Lib_Usbd, "(STUBBED) called");
return ORBIS_OK; return ORBIS_OK;
} }
int PS4_SYSV_ABI sceUsbdBulkTransfer() { int PS4_SYSV_ABI sceUsbdBulkTransfer() {
LOG_ERROR(Lib_Usbd, "(STUBBED)called"); LOG_ERROR(Lib_Usbd, "(STUBBED) called");
return ORBIS_OK; return ORBIS_OK;
} }
int PS4_SYSV_ABI sceUsbdCancelTransfer() { int PS4_SYSV_ABI sceUsbdCancelTransfer() {
LOG_ERROR(Lib_Usbd, "(STUBBED)called"); LOG_ERROR(Lib_Usbd, "(STUBBED) called");
return ORBIS_OK; return ORBIS_OK;
} }
int PS4_SYSV_ABI sceUsbdCheckConnected() { int PS4_SYSV_ABI sceUsbdCheckConnected() {
LOG_ERROR(Lib_Usbd, "(STUBBED)called"); LOG_ERROR(Lib_Usbd, "(STUBBED) called");
return ORBIS_OK; return ORBIS_OK;
} }
int PS4_SYSV_ABI sceUsbdClaimInterface() { int PS4_SYSV_ABI sceUsbdClaimInterface() {
LOG_ERROR(Lib_Usbd, "(STUBBED)called"); LOG_ERROR(Lib_Usbd, "(STUBBED) called");
return ORBIS_OK; return ORBIS_OK;
} }
int PS4_SYSV_ABI sceUsbdClearHalt() { int PS4_SYSV_ABI sceUsbdClearHalt() {
LOG_ERROR(Lib_Usbd, "(STUBBED)called"); LOG_ERROR(Lib_Usbd, "(STUBBED) called");
return ORBIS_OK; return ORBIS_OK;
} }
int PS4_SYSV_ABI sceUsbdClose() { int PS4_SYSV_ABI sceUsbdClose() {
LOG_ERROR(Lib_Usbd, "(STUBBED)called"); LOG_ERROR(Lib_Usbd, "(STUBBED) called");
return ORBIS_OK; return ORBIS_OK;
} }
int PS4_SYSV_ABI sceUsbdControlTransfer() { int PS4_SYSV_ABI sceUsbdControlTransfer() {
LOG_ERROR(Lib_Usbd, "(STUBBED)called"); LOG_ERROR(Lib_Usbd, "(STUBBED) called");
return ORBIS_OK; return ORBIS_OK;
} }
int PS4_SYSV_ABI sceUsbdControlTransferGetData() { int PS4_SYSV_ABI sceUsbdControlTransferGetData() {
LOG_ERROR(Lib_Usbd, "(STUBBED)called"); LOG_ERROR(Lib_Usbd, "(STUBBED) called");
return ORBIS_OK; return ORBIS_OK;
} }
int PS4_SYSV_ABI sceUsbdControlTransferGetSetup() { int PS4_SYSV_ABI sceUsbdControlTransferGetSetup() {
LOG_ERROR(Lib_Usbd, "(STUBBED)called"); LOG_ERROR(Lib_Usbd, "(STUBBED) called");
return ORBIS_OK; return ORBIS_OK;
} }
int PS4_SYSV_ABI sceUsbdDetachKernelDriver() { int PS4_SYSV_ABI sceUsbdDetachKernelDriver() {
LOG_ERROR(Lib_Usbd, "(STUBBED)called"); LOG_ERROR(Lib_Usbd, "(STUBBED) called");
return ORBIS_OK; return ORBIS_OK;
} }
int PS4_SYSV_ABI sceUsbdEventHandlerActive() { int PS4_SYSV_ABI sceUsbdEventHandlerActive() {
LOG_ERROR(Lib_Usbd, "(STUBBED)called"); LOG_ERROR(Lib_Usbd, "(STUBBED) called");
return ORBIS_OK; return ORBIS_OK;
} }
int PS4_SYSV_ABI sceUsbdEventHandlingOk() { int PS4_SYSV_ABI sceUsbdEventHandlingOk() {
LOG_ERROR(Lib_Usbd, "(STUBBED)called"); LOG_ERROR(Lib_Usbd, "(STUBBED) called");
return ORBIS_OK; return ORBIS_OK;
} }
int PS4_SYSV_ABI sceUsbdExit() { int PS4_SYSV_ABI sceUsbdExit() {
LOG_ERROR(Lib_Usbd, "(STUBBED)called"); LOG_ERROR(Lib_Usbd, "(STUBBED) called");
return ORBIS_OK; return ORBIS_OK;
} }
int PS4_SYSV_ABI sceUsbdFillBulkTransfer() { int PS4_SYSV_ABI sceUsbdFillBulkTransfer() {
LOG_ERROR(Lib_Usbd, "(STUBBED)called"); LOG_ERROR(Lib_Usbd, "(STUBBED) called");
return ORBIS_OK; return ORBIS_OK;
} }
int PS4_SYSV_ABI sceUsbdFillControlSetup() { int PS4_SYSV_ABI sceUsbdFillControlSetup() {
LOG_ERROR(Lib_Usbd, "(STUBBED)called"); LOG_ERROR(Lib_Usbd, "(STUBBED) called");
return ORBIS_OK; return ORBIS_OK;
} }
int PS4_SYSV_ABI sceUsbdFillControlTransfer() { int PS4_SYSV_ABI sceUsbdFillControlTransfer() {
LOG_ERROR(Lib_Usbd, "(STUBBED)called"); LOG_ERROR(Lib_Usbd, "(STUBBED) called");
return ORBIS_OK; return ORBIS_OK;
} }
int PS4_SYSV_ABI sceUsbdFillInterruptTransfer() { int PS4_SYSV_ABI sceUsbdFillInterruptTransfer() {
LOG_ERROR(Lib_Usbd, "(STUBBED)called"); LOG_ERROR(Lib_Usbd, "(STUBBED) called");
return ORBIS_OK; return ORBIS_OK;
} }
int PS4_SYSV_ABI sceUsbdFillIsoTransfer() { int PS4_SYSV_ABI sceUsbdFillIsoTransfer() {
LOG_ERROR(Lib_Usbd, "(STUBBED)called"); LOG_ERROR(Lib_Usbd, "(STUBBED) called");
return ORBIS_OK; return ORBIS_OK;
} }
int PS4_SYSV_ABI sceUsbdFreeConfigDescriptor() { int PS4_SYSV_ABI sceUsbdFreeConfigDescriptor() {
LOG_ERROR(Lib_Usbd, "(STUBBED)called"); LOG_ERROR(Lib_Usbd, "(STUBBED) called");
return ORBIS_OK; return ORBIS_OK;
} }
int PS4_SYSV_ABI sceUsbdFreeDeviceList() { int PS4_SYSV_ABI sceUsbdFreeDeviceList() {
LOG_ERROR(Lib_Usbd, "(STUBBED)called"); LOG_ERROR(Lib_Usbd, "(STUBBED) called");
return ORBIS_OK; return ORBIS_OK;
} }
int PS4_SYSV_ABI sceUsbdFreeTransfer() { int PS4_SYSV_ABI sceUsbdFreeTransfer() {
LOG_ERROR(Lib_Usbd, "(STUBBED)called"); LOG_ERROR(Lib_Usbd, "(STUBBED) called");
return ORBIS_OK; return ORBIS_OK;
} }
int PS4_SYSV_ABI sceUsbdGetActiveConfigDescriptor() { int PS4_SYSV_ABI sceUsbdGetActiveConfigDescriptor() {
LOG_ERROR(Lib_Usbd, "(STUBBED)called"); LOG_ERROR(Lib_Usbd, "(STUBBED) called");
return ORBIS_OK; return ORBIS_OK;
} }
int PS4_SYSV_ABI sceUsbdGetBusNumber() { int PS4_SYSV_ABI sceUsbdGetBusNumber() {
LOG_ERROR(Lib_Usbd, "(STUBBED)called"); LOG_ERROR(Lib_Usbd, "(STUBBED) called");
return ORBIS_OK; return ORBIS_OK;
} }
int PS4_SYSV_ABI sceUsbdGetConfigDescriptor() { int PS4_SYSV_ABI sceUsbdGetConfigDescriptor() {
LOG_ERROR(Lib_Usbd, "(STUBBED)called"); LOG_ERROR(Lib_Usbd, "(STUBBED) called");
return ORBIS_OK; return ORBIS_OK;
} }
int PS4_SYSV_ABI sceUsbdGetConfigDescriptorByValue() { int PS4_SYSV_ABI sceUsbdGetConfigDescriptorByValue() {
LOG_ERROR(Lib_Usbd, "(STUBBED)called"); LOG_ERROR(Lib_Usbd, "(STUBBED) called");
return ORBIS_OK; return ORBIS_OK;
} }
int PS4_SYSV_ABI sceUsbdGetConfiguration() { int PS4_SYSV_ABI sceUsbdGetConfiguration() {
LOG_ERROR(Lib_Usbd, "(STUBBED)called"); LOG_ERROR(Lib_Usbd, "(STUBBED) called");
return ORBIS_OK; return ORBIS_OK;
} }
int PS4_SYSV_ABI sceUsbdGetDescriptor() { int PS4_SYSV_ABI sceUsbdGetDescriptor() {
LOG_ERROR(Lib_Usbd, "(STUBBED)called"); LOG_ERROR(Lib_Usbd, "(STUBBED) called");
return ORBIS_OK; return ORBIS_OK;
} }
int PS4_SYSV_ABI sceUsbdGetDevice() { int PS4_SYSV_ABI sceUsbdGetDevice() {
LOG_ERROR(Lib_Usbd, "(STUBBED)called"); LOG_ERROR(Lib_Usbd, "(STUBBED) called");
return ORBIS_OK; return ORBIS_OK;
} }
int PS4_SYSV_ABI sceUsbdGetDeviceAddress() { int PS4_SYSV_ABI sceUsbdGetDeviceAddress() {
LOG_ERROR(Lib_Usbd, "(STUBBED)called"); LOG_ERROR(Lib_Usbd, "(STUBBED) called");
return ORBIS_OK; return ORBIS_OK;
} }
int PS4_SYSV_ABI sceUsbdGetDeviceDescriptor() { int PS4_SYSV_ABI sceUsbdGetDeviceDescriptor() {
LOG_ERROR(Lib_Usbd, "(STUBBED)called"); LOG_ERROR(Lib_Usbd, "(STUBBED) called");
return ORBIS_OK; return ORBIS_OK;
} }
int PS4_SYSV_ABI sceUsbdGetDeviceList() { int PS4_SYSV_ABI sceUsbdGetDeviceList() {
LOG_ERROR(Lib_Usbd, "(STUBBED)called"); LOG_ERROR(Lib_Usbd, "(STUBBED) called");
return ORBIS_OK; return ORBIS_OK;
} }
int PS4_SYSV_ABI sceUsbdGetDeviceSpeed() { int PS4_SYSV_ABI sceUsbdGetDeviceSpeed() {
LOG_ERROR(Lib_Usbd, "(STUBBED)called"); LOG_ERROR(Lib_Usbd, "(STUBBED) called");
return ORBIS_OK; return ORBIS_OK;
} }
int PS4_SYSV_ABI sceUsbdGetIsoPacketBuffer() { int PS4_SYSV_ABI sceUsbdGetIsoPacketBuffer() {
LOG_ERROR(Lib_Usbd, "(STUBBED)called"); LOG_ERROR(Lib_Usbd, "(STUBBED) called");
return ORBIS_OK; return ORBIS_OK;
} }
int PS4_SYSV_ABI sceUsbdGetMaxIsoPacketSize() { int PS4_SYSV_ABI sceUsbdGetMaxIsoPacketSize() {
LOG_ERROR(Lib_Usbd, "(STUBBED)called"); LOG_ERROR(Lib_Usbd, "(STUBBED) called");
return ORBIS_OK; return ORBIS_OK;
} }
int PS4_SYSV_ABI sceUsbdGetMaxPacketSize() { int PS4_SYSV_ABI sceUsbdGetMaxPacketSize() {
LOG_ERROR(Lib_Usbd, "(STUBBED)called"); LOG_ERROR(Lib_Usbd, "(STUBBED) called");
return ORBIS_OK; return ORBIS_OK;
} }
int PS4_SYSV_ABI sceUsbdGetStringDescriptor() { int PS4_SYSV_ABI sceUsbdGetStringDescriptor() {
LOG_ERROR(Lib_Usbd, "(STUBBED)called"); LOG_ERROR(Lib_Usbd, "(STUBBED) called");
return ORBIS_OK; return ORBIS_OK;
} }
int PS4_SYSV_ABI sceUsbdGetStringDescriptorAscii() { int PS4_SYSV_ABI sceUsbdGetStringDescriptorAscii() {
LOG_ERROR(Lib_Usbd, "(STUBBED)called"); LOG_ERROR(Lib_Usbd, "(STUBBED) called");
return ORBIS_OK; return ORBIS_OK;
} }
int PS4_SYSV_ABI sceUsbdHandleEvents() { int PS4_SYSV_ABI sceUsbdHandleEvents() {
LOG_ERROR(Lib_Usbd, "(STUBBED)called"); LOG_ERROR(Lib_Usbd, "(STUBBED) called");
return ORBIS_OK; return ORBIS_OK;
} }
int PS4_SYSV_ABI sceUsbdHandleEventsLocked() { int PS4_SYSV_ABI sceUsbdHandleEventsLocked() {
LOG_ERROR(Lib_Usbd, "(STUBBED)called"); LOG_ERROR(Lib_Usbd, "(STUBBED) called");
return ORBIS_OK; return ORBIS_OK;
} }
int PS4_SYSV_ABI sceUsbdHandleEventsTimeout() { int PS4_SYSV_ABI sceUsbdHandleEventsTimeout() {
LOG_ERROR(Lib_Usbd, "(STUBBED)called"); LOG_DEBUG(Lib_Usbd, "(STUBBED) called");
return ORBIS_OK; return ORBIS_OK;
} }
int PS4_SYSV_ABI sceUsbdInit() { int PS4_SYSV_ABI sceUsbdInit() {
LOG_ERROR(Lib_Usbd, "(STUBBED)called"); LOG_ERROR(Lib_Usbd, "(STUBBED) called");
return 0x80240005; // Skip return 0x80240005; // Skip
} }
int PS4_SYSV_ABI sceUsbdInterruptTransfer() { int PS4_SYSV_ABI sceUsbdInterruptTransfer() {
LOG_ERROR(Lib_Usbd, "(STUBBED)called"); LOG_ERROR(Lib_Usbd, "(STUBBED) called");
return ORBIS_OK; return ORBIS_OK;
} }
int PS4_SYSV_ABI sceUsbdKernelDriverActive() { int PS4_SYSV_ABI sceUsbdKernelDriverActive() {
LOG_ERROR(Lib_Usbd, "(STUBBED)called"); LOG_ERROR(Lib_Usbd, "(STUBBED) called");
return ORBIS_OK; return ORBIS_OK;
} }
int PS4_SYSV_ABI sceUsbdLockEvents() { int PS4_SYSV_ABI sceUsbdLockEvents() {
LOG_ERROR(Lib_Usbd, "(STUBBED)called"); LOG_ERROR(Lib_Usbd, "(STUBBED) called");
return ORBIS_OK; return ORBIS_OK;
} }
int PS4_SYSV_ABI sceUsbdLockEventWaiters() { int PS4_SYSV_ABI sceUsbdLockEventWaiters() {
LOG_ERROR(Lib_Usbd, "(STUBBED)called"); LOG_ERROR(Lib_Usbd, "(STUBBED) called");
return ORBIS_OK; return ORBIS_OK;
} }
int PS4_SYSV_ABI sceUsbdOpen() { int PS4_SYSV_ABI sceUsbdOpen() {
LOG_ERROR(Lib_Usbd, "(STUBBED)called"); LOG_ERROR(Lib_Usbd, "(STUBBED) called");
return ORBIS_OK; return ORBIS_OK;
} }
int PS4_SYSV_ABI sceUsbdOpenDeviceWithVidPid() { int PS4_SYSV_ABI sceUsbdOpenDeviceWithVidPid() {
LOG_ERROR(Lib_Usbd, "(STUBBED)called"); LOG_ERROR(Lib_Usbd, "(STUBBED) called");
return ORBIS_OK; return ORBIS_OK;
} }
int PS4_SYSV_ABI sceUsbdRefDevice() { int PS4_SYSV_ABI sceUsbdRefDevice() {
LOG_ERROR(Lib_Usbd, "(STUBBED)called"); LOG_ERROR(Lib_Usbd, "(STUBBED) called");
return ORBIS_OK; return ORBIS_OK;
} }
int PS4_SYSV_ABI sceUsbdReleaseInterface() { int PS4_SYSV_ABI sceUsbdReleaseInterface() {
LOG_ERROR(Lib_Usbd, "(STUBBED)called"); LOG_ERROR(Lib_Usbd, "(STUBBED) called");
return ORBIS_OK; return ORBIS_OK;
} }
int PS4_SYSV_ABI sceUsbdResetDevice() { int PS4_SYSV_ABI sceUsbdResetDevice() {
LOG_ERROR(Lib_Usbd, "(STUBBED)called"); LOG_ERROR(Lib_Usbd, "(STUBBED) called");
return ORBIS_OK; return ORBIS_OK;
} }
int PS4_SYSV_ABI sceUsbdSetConfiguration() { int PS4_SYSV_ABI sceUsbdSetConfiguration() {
LOG_ERROR(Lib_Usbd, "(STUBBED)called"); LOG_ERROR(Lib_Usbd, "(STUBBED) called");
return ORBIS_OK; return ORBIS_OK;
} }
int PS4_SYSV_ABI sceUsbdSetInterfaceAltSetting() { int PS4_SYSV_ABI sceUsbdSetInterfaceAltSetting() {
LOG_ERROR(Lib_Usbd, "(STUBBED)called"); LOG_ERROR(Lib_Usbd, "(STUBBED) called");
return ORBIS_OK; return ORBIS_OK;
} }
int PS4_SYSV_ABI sceUsbdSetIsoPacketLengths() { int PS4_SYSV_ABI sceUsbdSetIsoPacketLengths() {
LOG_ERROR(Lib_Usbd, "(STUBBED)called"); LOG_ERROR(Lib_Usbd, "(STUBBED) called");
return ORBIS_OK; return ORBIS_OK;
} }
int PS4_SYSV_ABI sceUsbdSubmitTransfer() { int PS4_SYSV_ABI sceUsbdSubmitTransfer() {
LOG_ERROR(Lib_Usbd, "(STUBBED)called"); LOG_ERROR(Lib_Usbd, "(STUBBED) called");
return ORBIS_OK; return ORBIS_OK;
} }
int PS4_SYSV_ABI sceUsbdTryLockEvents() { int PS4_SYSV_ABI sceUsbdTryLockEvents() {
LOG_ERROR(Lib_Usbd, "(STUBBED)called"); LOG_ERROR(Lib_Usbd, "(STUBBED) called");
return ORBIS_OK; return ORBIS_OK;
} }
int PS4_SYSV_ABI sceUsbdUnlockEvents() { int PS4_SYSV_ABI sceUsbdUnlockEvents() {
LOG_ERROR(Lib_Usbd, "(STUBBED)called"); LOG_ERROR(Lib_Usbd, "(STUBBED) called");
return ORBIS_OK; return ORBIS_OK;
} }
int PS4_SYSV_ABI sceUsbdUnlockEventWaiters() { int PS4_SYSV_ABI sceUsbdUnlockEventWaiters() {
LOG_ERROR(Lib_Usbd, "(STUBBED)called"); LOG_ERROR(Lib_Usbd, "(STUBBED) called");
return ORBIS_OK; return ORBIS_OK;
} }
int PS4_SYSV_ABI sceUsbdUnrefDevice() { int PS4_SYSV_ABI sceUsbdUnrefDevice() {
LOG_ERROR(Lib_Usbd, "(STUBBED)called"); LOG_ERROR(Lib_Usbd, "(STUBBED) called");
return ORBIS_OK; return ORBIS_OK;
} }
int PS4_SYSV_ABI sceUsbdWaitForEvent() { int PS4_SYSV_ABI sceUsbdWaitForEvent() {
LOG_ERROR(Lib_Usbd, "(STUBBED)called"); LOG_ERROR(Lib_Usbd, "(STUBBED) called");
return ORBIS_OK; return ORBIS_OK;
} }
int PS4_SYSV_ABI Func_65F6EF33E38FFF50() { int PS4_SYSV_ABI Func_65F6EF33E38FFF50() {
LOG_ERROR(Lib_Usbd, "(STUBBED)called"); LOG_ERROR(Lib_Usbd, "(STUBBED) called");
return ORBIS_OK; return ORBIS_OK;
} }
int PS4_SYSV_ABI Func_97F056BAD90AADE7() { int PS4_SYSV_ABI Func_97F056BAD90AADE7() {
LOG_ERROR(Lib_Usbd, "(STUBBED)called"); LOG_ERROR(Lib_Usbd, "(STUBBED) called");
return ORBIS_OK; return ORBIS_OK;
} }
int PS4_SYSV_ABI Func_C55104A33B35B264() { int PS4_SYSV_ABI Func_C55104A33B35B264() {
LOG_ERROR(Lib_Usbd, "(STUBBED)called"); LOG_ERROR(Lib_Usbd, "(STUBBED) called");
return ORBIS_OK; return ORBIS_OK;
} }
int PS4_SYSV_ABI Func_D56B43060720B1E0() { int PS4_SYSV_ABI Func_D56B43060720B1E0() {
LOG_ERROR(Lib_Usbd, "(STUBBED)called"); LOG_ERROR(Lib_Usbd, "(STUBBED) called");
return ORBIS_OK; return ORBIS_OK;
} }

View File

@ -213,6 +213,8 @@ SettingsDialog::SettingsDialog(std::span<const QString> physical_devices,
ui->showSplashCheckBox->installEventFilter(this); ui->showSplashCheckBox->installEventFilter(this);
ui->discordRPCCheckbox->installEventFilter(this); ui->discordRPCCheckbox->installEventFilter(this);
ui->userName->installEventFilter(this); ui->userName->installEventFilter(this);
ui->label_Trophy->installEventFilter(this);
ui->trophyKeyLineEdit->installEventFilter(this);
ui->logTypeGroupBox->installEventFilter(this); ui->logTypeGroupBox->installEventFilter(this);
ui->logFilter->installEventFilter(this); ui->logFilter->installEventFilter(this);
#ifdef ENABLE_UPDATER #ifdef ENABLE_UPDATER
@ -307,6 +309,9 @@ void SettingsDialog::LoadValuesFromConfig() {
QString::fromStdString(toml::find_or<std::string>(data, "General", "logFilter", ""))); QString::fromStdString(toml::find_or<std::string>(data, "General", "logFilter", "")));
ui->userNameLineEdit->setText( ui->userNameLineEdit->setText(
QString::fromStdString(toml::find_or<std::string>(data, "General", "userName", "shadPS4"))); QString::fromStdString(toml::find_or<std::string>(data, "General", "userName", "shadPS4")));
ui->trophyKeyLineEdit->setText(
QString::fromStdString(toml::find_or<std::string>(data, "Keys", "TrophyKey", "")));
ui->trophyKeyLineEdit->setEchoMode(QLineEdit::Password);
ui->debugDump->setChecked(toml::find_or<bool>(data, "Debug", "DebugDump", false)); ui->debugDump->setChecked(toml::find_or<bool>(data, "Debug", "DebugDump", false));
ui->vkValidationCheckBox->setChecked(toml::find_or<bool>(data, "Vulkan", "validation", false)); ui->vkValidationCheckBox->setChecked(toml::find_or<bool>(data, "Vulkan", "validation", false));
ui->vkSyncValidationCheckBox->setChecked( ui->vkSyncValidationCheckBox->setChecked(
@ -419,6 +424,10 @@ void SettingsDialog::updateNoteTextEdit(const QString& elementName) {
text = tr("discordRPCCheckbox"); text = tr("discordRPCCheckbox");
} else if (elementName == "userName") { } else if (elementName == "userName") {
text = tr("userName"); text = tr("userName");
} else if (elementName == "label_Trophy") {
text = tr("TrophyKey");
} else if (elementName == "trophyKeyLineEdit") {
text = tr("TrophyKey");
} else if (elementName == "logTypeGroupBox") { } else if (elementName == "logTypeGroupBox") {
text = tr("logTypeGroupBox"); text = tr("logTypeGroupBox");
} else if (elementName == "logFilter") { } else if (elementName == "logFilter") {
@ -529,6 +538,7 @@ void SettingsDialog::UpdateSettings() {
Config::setLogType(ui->logTypeComboBox->currentText().toStdString()); Config::setLogType(ui->logTypeComboBox->currentText().toStdString());
Config::setLogFilter(ui->logFilterLineEdit->text().toStdString()); Config::setLogFilter(ui->logFilterLineEdit->text().toStdString());
Config::setUserName(ui->userNameLineEdit->text().toStdString()); Config::setUserName(ui->userNameLineEdit->text().toStdString());
Config::setTrophyKey(ui->trophyKeyLineEdit->text().toStdString());
Config::setCursorState(ui->hideCursorComboBox->currentIndex()); Config::setCursorState(ui->hideCursorComboBox->currentIndex());
Config::setCursorHideTimeout(ui->idleTimeoutSpinBox->value()); Config::setCursorHideTimeout(ui->idleTimeoutSpinBox->value());
Config::setGpuId(ui->graphicsAdapterBox->currentIndex() - 1); Config::setGpuId(ui->graphicsAdapterBox->currentIndex() - 1);

View File

@ -11,8 +11,8 @@
<rect> <rect>
<x>0</x> <x>0</x>
<y>0</y> <y>0</y>
<width>950</width> <width>970</width>
<height>780</height> <height>670</height>
</rect> </rect>
</property> </property>
<property name="sizePolicy"> <property name="sizePolicy">
@ -67,8 +67,8 @@
<rect> <rect>
<x>0</x> <x>0</x>
<y>0</y> <y>0</y>
<width>822</width> <width>946</width>
<height>487</height> <height>536</height>
</rect> </rect>
</property> </property>
<layout class="QVBoxLayout" name="generalTabVLayout" stretch="0"> <layout class="QVBoxLayout" name="generalTabVLayout" stretch="0">
@ -77,87 +77,7 @@
<property name="bottomMargin"> <property name="bottomMargin">
<number>0</number> <number>0</number>
</property> </property>
<item row="0" column="2"> <item row="1" column="0">
<layout class="QVBoxLayout" name="loggerTabLayoutRight">
<item>
<widget class="QGroupBox" name="loggerGroupBox">
<property name="title">
<string>Logger</string>
</property>
<layout class="QVBoxLayout" name="loggerLayout">
<item>
<widget class="QWidget" name="LogTypeWidget" native="true">
<layout class="QVBoxLayout" name="LogTypeLayout">
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item>
<widget class="QGroupBox" name="logTypeGroupBox">
<property name="title">
<string>Log Type</string>
</property>
<layout class="QVBoxLayout" name="logTypeBoxLayout">
<item>
<widget class="QComboBox" name="logTypeComboBox">
<item>
<property name="text">
<string>async</string>
</property>
</item>
<item>
<property name="text">
<string>sync</string>
</property>
</item>
</widget>
</item>
</layout>
</widget>
</item>
</layout>
</widget>
</item>
<item>
<layout class="QVBoxLayout" name="vLayoutLogFilter">
<property name="spacing">
<number>6</number>
</property>
<property name="leftMargin">
<number>0</number>
</property>
<item>
<layout class="QHBoxLayout" name="hLayoutLogFilter">
<item>
<widget class="QGroupBox" name="logFilter">
<property name="title">
<string>Log Filter</string>
</property>
<layout class="QVBoxLayout" name="logFilterLayout">
<item>
<widget class="QLineEdit" name="logFilterLineEdit"/>
</item>
</layout>
</widget>
</item>
</layout>
</item>
</layout>
</item>
</layout>
</widget>
</item>
</layout>
</item>
<item row="0" column="0">
<layout class="QVBoxLayout" name="systemTabLayoutLeft"> <layout class="QVBoxLayout" name="systemTabLayoutLeft">
<item> <item>
<widget class="QGroupBox" name="SystemSettings"> <widget class="QGroupBox" name="SystemSettings">
@ -194,7 +114,7 @@
</item> </item>
</layout> </layout>
</item> </item>
<item row="0" column="1"> <item row="0" column="0">
<layout class="QVBoxLayout" name="emulatorTabLayoutMiddle"> <layout class="QVBoxLayout" name="emulatorTabLayoutMiddle">
<item> <item>
<widget class="QGroupBox" name="emulatorSettingsGroupBox"> <widget class="QGroupBox" name="emulatorSettingsGroupBox">
@ -268,10 +188,10 @@
</item> </item>
</layout> </layout>
</item> </item>
<item row="1" column="0"> <item row="1" column="2">
<layout class="QVBoxLayout" name="updaterTabLayoutLeft"> <layout class="QVBoxLayout" name="updaterTabLayoutLeft">
<property name="spacing"> <property name="spacing">
<number>-1</number> <number>6</number>
</property> </property>
<property name="sizeConstraint"> <property name="sizeConstraint">
<enum>QLayout::SizeConstraint::SetDefaultConstraint</enum> <enum>QLayout::SizeConstraint::SetDefaultConstraint</enum>
@ -436,138 +356,8 @@
</layout> </layout>
</item> </item>
<item row="1" column="1"> <item row="1" column="1">
<layout class="QVBoxLayout" name="GUITabLayoutMiddle" stretch="0">
<item alignment="Qt::AlignmentFlag::AlignTop">
<widget class="QGroupBox" name="GUIgroupBox">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>0</width>
<height>0</height>
</size>
</property>
<property name="title">
<string>GUI Settings</string>
</property>
<layout class="QVBoxLayout" name="GUILayout">
<property name="topMargin">
<number>1</number>
</property>
<property name="bottomMargin">
<number>11</number>
</property>
<item>
<widget class="QCheckBox" name="disableTrophycheckBox">
<property name="text">
<string>Disable Trophy Pop-ups</string>
</property>
</widget>
</item>
<item>
<widget class="QCheckBox" name="playBGMCheckBox">
<property name="sizePolicy">
<sizepolicy hsizetype="Minimum" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>Play title music</string>
</property>
</widget>
</item>
<item>
<layout class="QVBoxLayout" name="GUIMusicLayout">
<property name="topMargin">
<number>1</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item>
<spacer name="GUIverticalSpacer_3">
<property name="orientation">
<enum>Qt::Orientation::Vertical</enum>
</property>
<property name="sizeType">
<enum>QSizePolicy::Policy::Fixed</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>13</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QLabel" name="label">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="maximumSize">
<size>
<width>16777215</width>
<height>16777215</height>
</size>
</property>
<property name="text">
<string>Volume</string>
</property>
</widget>
</item>
<item>
<widget class="QSlider" name="BGMVolumeSlider">
<property name="toolTip">
<string>Set the volume of the background music.</string>
</property>
<property name="maximum">
<number>100</number>
</property>
<property name="singleStep">
<number>10</number>
</property>
<property name="pageStep">
<number>20</number>
</property>
<property name="value">
<number>50</number>
</property>
<property name="orientation">
<enum>Qt::Orientation::Horizontal</enum>
</property>
<property name="invertedAppearance">
<bool>false</bool>
</property>
<property name="invertedControls">
<bool>false</bool>
</property>
<property name="tickPosition">
<enum>QSlider::TickPosition::NoTicks</enum>
</property>
<property name="tickInterval">
<number>10</number>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</widget>
</item>
</layout>
</item>
<item row="1" column="2">
<layout class="QVBoxLayout" name="CompatTabLayoutRight" stretch="0"> <layout class="QVBoxLayout" name="CompatTabLayoutRight" stretch="0">
<item alignment="Qt::AlignmentFlag::AlignTop"> <item>
<widget class="QGroupBox" name="CompatgroupBox"> <widget class="QGroupBox" name="CompatgroupBox">
<property name="sizePolicy"> <property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Preferred"> <sizepolicy hsizetype="Preferred" vsizetype="Preferred">
@ -638,6 +428,160 @@
</item> </item>
</layout> </layout>
</item> </item>
<item row="0" column="1">
<layout class="QVBoxLayout" name="GUITabLayoutMiddle" stretch="0">
<item>
<widget class="QGroupBox" name="GUIgroupBox">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>0</width>
<height>0</height>
</size>
</property>
<property name="title">
<string>GUI Settings</string>
</property>
<layout class="QVBoxLayout" name="GUILayout">
<property name="topMargin">
<number>1</number>
</property>
<property name="bottomMargin">
<number>11</number>
</property>
<item>
<widget class="QCheckBox" name="playBGMCheckBox">
<property name="sizePolicy">
<sizepolicy hsizetype="Minimum" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>Play title music</string>
</property>
</widget>
</item>
<item>
<layout class="QVBoxLayout" name="GUIMusicLayout">
<property name="topMargin">
<number>1</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item>
<widget class="QLabel" name="label_Volume">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="maximumSize">
<size>
<width>16777215</width>
<height>16777215</height>
</size>
</property>
<property name="text">
<string>Volume</string>
</property>
</widget>
</item>
<item>
<widget class="QSlider" name="BGMVolumeSlider">
<property name="toolTip">
<string>Set the volume of the background music.</string>
</property>
<property name="maximum">
<number>100</number>
</property>
<property name="singleStep">
<number>10</number>
</property>
<property name="pageStep">
<number>20</number>
</property>
<property name="value">
<number>50</number>
</property>
<property name="orientation">
<enum>Qt::Orientation::Horizontal</enum>
</property>
<property name="invertedAppearance">
<bool>false</bool>
</property>
<property name="invertedControls">
<bool>false</bool>
</property>
<property name="tickPosition">
<enum>QSlider::TickPosition::NoTicks</enum>
</property>
<property name="tickInterval">
<number>10</number>
</property>
</widget>
</item>
<item>
<layout class="QVBoxLayout" name="vLayoutTrophy">
<property name="spacing">
<number>6</number>
</property>
<property name="leftMargin">
<number>0</number>
</property>
<item>
<layout class="QHBoxLayout" name="hLayoutTrophy">
<item>
<widget class="QGroupBox" name="trophyGroupBox">
<property name="title">
<string>Trophy</string>
</property>
<layout class="QVBoxLayout" name="userNameLayout">
<item>
<widget class="QCheckBox" name="disableTrophycheckBox">
<property name="text">
<string>Disable Trophy Pop-ups</string>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="label_Trophy">
<property name="text">
<string>Trophy Key</string>
</property>
</widget>
</item>
<item>
<widget class="QLineEdit" name="trophyKeyLineEdit">
<property name="minimumSize">
<size>
<width>0</width>
<height>0</height>
</size>
</property>
</widget>
</item>
</layout>
</widget>
</item>
</layout>
</item>
</layout>
</item>
</layout>
</item>
</layout>
</widget>
</item>
</layout>
</item>
</layout> </layout>
</item> </item>
</layout> </layout>
@ -655,8 +599,8 @@
<rect> <rect>
<x>0</x> <x>0</x>
<y>0</y> <y>0</y>
<width>396</width> <width>926</width>
<height>222</height> <height>536</height>
</rect> </rect>
</property> </property>
<layout class="QVBoxLayout" name="inputTabVLayout" stretch="0,0"> <layout class="QVBoxLayout" name="inputTabVLayout" stretch="0,0">
@ -946,8 +890,8 @@
<rect> <rect>
<x>0</x> <x>0</x>
<y>0</y> <y>0</y>
<width>536</width> <width>926</width>
<height>192</height> <height>536</height>
</rect> </rect>
</property> </property>
<layout class="QVBoxLayout" name="graphicsTabVLayout" stretch="0,0"> <layout class="QVBoxLayout" name="graphicsTabVLayout" stretch="0,0">
@ -1197,8 +1141,8 @@
<rect> <rect>
<x>0</x> <x>0</x>
<y>0</y> <y>0</y>
<width>146</width> <width>926</width>
<height>215</height> <height>536</height>
</rect> </rect>
</property> </property>
<layout class="QVBoxLayout" name="pathsTabLayout" stretch="0"> <layout class="QVBoxLayout" name="pathsTabLayout" stretch="0">
@ -1211,18 +1155,25 @@
</property> </property>
<layout class="QVBoxLayout" name="verticalLayout"> <layout class="QVBoxLayout" name="verticalLayout">
<item> <item>
<widget class="QPushButton" name="removeFolderButton"> <layout class="QHBoxLayout" name="horizontalLayout">
<property name="text"> <property name="topMargin">
<string>Remove</string> <number>0</number>
</property> </property>
</widget> <item>
</item> <widget class="QPushButton" name="addFolderButton">
<item> <property name="text">
<widget class="QPushButton" name="addFolderButton"> <string>Add...</string>
<property name="text"> </property>
<string>Add...</string> </widget>
</property> </item>
</widget> <item>
<widget class="QPushButton" name="removeFolderButton">
<property name="text">
<string>Remove</string>
</property>
</widget>
</item>
</layout>
</item> </item>
<item> <item>
<widget class="QListWidget" name="gameFoldersListWidget"/> <widget class="QListWidget" name="gameFoldersListWidget"/>
@ -1263,71 +1214,145 @@
<rect> <rect>
<x>0</x> <x>0</x>
<y>0</y> <y>0</y>
<width>288</width> <width>926</width>
<height>163</height> <height>536</height>
</rect> </rect>
</property> </property>
<layout class="QVBoxLayout" name="debugTabVLayout" stretch="0,1"> <layout class="QVBoxLayout" name="debugTabVLayout" stretch="0,1">
<item> <item>
<layout class="QHBoxLayout" name="debugTabHLayout" stretch="1"> <layout class="QHBoxLayout" name="horizontalLayout_4">
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<item> <item>
<widget class="QGroupBox" name="debugTabGroupBox"> <layout class="QHBoxLayout" name="debugTabHLayout" stretch="1">
<property name="enabled"> <item>
<bool>true</bool> <widget class="QGroupBox" name="debugTabGroupBox">
</property> <property name="enabled">
<property name="title"> <bool>true</bool>
<string>General</string> </property>
</property> <property name="title">
<property name="alignment"> <string>General</string>
<set>Qt::AlignmentFlag::AlignLeading|Qt::AlignmentFlag::AlignLeft|Qt::AlignmentFlag::AlignTop</set> </property>
</property> <property name="alignment">
<layout class="QVBoxLayout" name="debugTabLayout"> <set>Qt::AlignmentFlag::AlignLeading|Qt::AlignmentFlag::AlignLeft|Qt::AlignmentFlag::AlignTop</set>
<item alignment="Qt::AlignmentFlag::AlignTop"> </property>
<widget class="QCheckBox" name="debugDump"> <layout class="QVBoxLayout" name="debugTabLayout">
<property name="text"> <item>
<string>Enable Debug Dumping</string> <widget class="QCheckBox" name="debugDump">
</property> <property name="text">
</widget> <string>Enable Debug Dumping</string>
</item> </property>
<item> </widget>
<spacer name="verticalSpacer"> </item>
<property name="orientation"> <item>
<enum>Qt::Orientation::Vertical</enum> <widget class="QCheckBox" name="vkValidationCheckBox">
</property> <property name="text">
<property name="sizeType"> <string>Enable Vulkan Validation Layers</string>
<enum>QSizePolicy::Policy::MinimumExpanding</enum> </property>
</property> </widget>
<property name="sizeHint" stdset="0"> </item>
<size> <item>
<width>0</width> <widget class="QCheckBox" name="vkSyncValidationCheckBox">
<height>0</height> <property name="text">
</size> <string>Enable Vulkan Synchronization Validation</string>
</property> </property>
</spacer> </widget>
</item> </item>
<item> <item>
<widget class="QCheckBox" name="vkValidationCheckBox"> <widget class="QCheckBox" name="rdocCheckBox">
<property name="text"> <property name="text">
<string>Enable Vulkan Validation Layers</string> <string>Enable RenderDoc Debugging</string>
</property> </property>
</widget> </widget>
</item> </item>
<item> </layout>
<widget class="QCheckBox" name="vkSyncValidationCheckBox"> </widget>
<property name="text"> </item>
<string>Enable Vulkan Synchronization Validation</string> </layout>
</property> </item>
</widget> <item>
</item> <layout class="QVBoxLayout" name="loggerTabLayoutRight">
<item> <item>
<widget class="QCheckBox" name="rdocCheckBox"> <widget class="QGroupBox" name="loggerGroupBox">
<property name="text"> <property name="title">
<string>Enable RenderDoc Debugging</string> <string>Logger</string>
</property> </property>
</widget> <layout class="QVBoxLayout" name="loggerLayout">
</item> <item>
</layout> <widget class="QWidget" name="LogTypeWidget" native="true">
</widget> <layout class="QVBoxLayout" name="LogTypeLayout">
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item>
<widget class="QGroupBox" name="logTypeGroupBox">
<property name="title">
<string>Log Type</string>
</property>
<layout class="QVBoxLayout" name="logTypeBoxLayout">
<item>
<widget class="QComboBox" name="logTypeComboBox">
<item>
<property name="text">
<string>async</string>
</property>
</item>
<item>
<property name="text">
<string>sync</string>
</property>
</item>
</widget>
</item>
</layout>
</widget>
</item>
</layout>
</widget>
</item>
<item>
<layout class="QVBoxLayout" name="vLayoutLogFilter">
<property name="spacing">
<number>6</number>
</property>
<property name="leftMargin">
<number>0</number>
</property>
<item>
<layout class="QHBoxLayout" name="hLayoutLogFilter">
<item>
<widget class="QGroupBox" name="logFilter">
<property name="title">
<string>Log Filter</string>
</property>
<layout class="QVBoxLayout" name="logFilterLayout">
<item>
<widget class="QLineEdit" name="logFilterLineEdit"/>
</item>
</layout>
</widget>
</item>
</layout>
</item>
</layout>
</item>
</layout>
</widget>
</item>
</layout>
</item> </item>
</layout> </layout>
</item> </item>

View File

@ -537,6 +537,16 @@
<source>Username</source> <source>Username</source>
<translation>اسم المستخدم</translation> <translation>اسم المستخدم</translation>
</message> </message>
<message>
<location filename="../settings_dialog.ui"/>
<source>Trophy Key</source>
<translation>Trophy Key</translation>
</message>
<message>
<location filename="../settings_dialog.ui"/>
<source>Trophy</source>
<translation>Trophy</translation>
</message>
<message> <message>
<location filename="../settings_dialog.ui" line="178"/> <location filename="../settings_dialog.ui" line="178"/>
<source>Logger</source> <source>Logger</source>
@ -1236,6 +1246,11 @@
<source>userName</source> <source>userName</source>
<translation>اسم المستخدم:\nيضبط اسم حساب PS4، الذي قد يتم عرضه في بعض الألعاب.</translation> <translation>اسم المستخدم:\nيضبط اسم حساب PS4، الذي قد يتم عرضه في بعض الألعاب.</translation>
</message> </message>
<message>
<location filename="../settings_dialog.cpp"/>
<source>TrophyKey</source>
<translation>Trophy Key:\nKey used to decrypt trophies. Must be obtained from your jailbroken console.\nMust contain only hex characters.</translation>
</message>
<message> <message>
<location filename="../settings_dialog.cpp" line="301"/> <location filename="../settings_dialog.cpp" line="301"/>
<source>logTypeGroupBox</source> <source>logTypeGroupBox</source>

View File

@ -537,6 +537,16 @@
<source>Username</source> <source>Username</source>
<translation>Username</translation> <translation>Username</translation>
</message> </message>
<message>
<location filename="../settings_dialog.ui"/>
<source>Trophy Key</source>
<translation>Trophy Key</translation>
</message>
<message>
<location filename="../settings_dialog.ui"/>
<source>Trophy</source>
<translation>Trophy</translation>
</message>
<message> <message>
<location filename="../settings_dialog.ui" line="178"/> <location filename="../settings_dialog.ui" line="178"/>
<source>Logger</source> <source>Logger</source>
@ -1236,6 +1246,11 @@
<source>userName</source> <source>userName</source>
<translation>Brugernavn:\nIndstiller PS4-kontoens navn, som kan blive vist i nogle spil.</translation> <translation>Brugernavn:\nIndstiller PS4-kontoens navn, som kan blive vist i nogle spil.</translation>
</message> </message>
<message>
<location filename="../settings_dialog.cpp"/>
<source>TrophyKey</source>
<translation>Trophy Key:\nKey used to decrypt trophies. Must be obtained from your jailbroken console.\nMust contain only hex characters.</translation>
</message>
<message> <message>
<location filename="../settings_dialog.cpp" line="301"/> <location filename="../settings_dialog.cpp" line="301"/>
<source>logTypeGroupBox</source> <source>logTypeGroupBox</source>

View File

@ -537,6 +537,16 @@
<source>Username</source> <source>Username</source>
<translation>Benutzername</translation> <translation>Benutzername</translation>
</message> </message>
<message>
<location filename="../settings_dialog.ui"/>
<source>Trophy Key</source>
<translation>Trophy Key</translation>
</message>
<message>
<location filename="../settings_dialog.ui"/>
<source>Trophy</source>
<translation>Trophy</translation>
</message>
<message> <message>
<location filename="../settings_dialog.ui" line="178"/> <location filename="../settings_dialog.ui" line="178"/>
<source>Logger</source> <source>Logger</source>
@ -1236,6 +1246,11 @@
<source>userName</source> <source>userName</source>
<translation>Benutzername:\nLegt den Namen des PS4-Kontos fest, der in einigen Spielen angezeigt werden kann.</translation> <translation>Benutzername:\nLegt den Namen des PS4-Kontos fest, der in einigen Spielen angezeigt werden kann.</translation>
</message> </message>
<message>
<location filename="../settings_dialog.cpp"/>
<source>TrophyKey</source>
<translation>Trophy Key:\nKey used to decrypt trophies. Must be obtained from your jailbroken console.\nMust contain only hex characters.</translation>
</message>
<message> <message>
<location filename="../settings_dialog.cpp" line="301"/> <location filename="../settings_dialog.cpp" line="301"/>
<source>logTypeGroupBox</source> <source>logTypeGroupBox</source>

View File

@ -537,6 +537,16 @@
<source>Username</source> <source>Username</source>
<translation>Username</translation> <translation>Username</translation>
</message> </message>
<message>
<location filename="../settings_dialog.ui"/>
<source>Trophy Key</source>
<translation>Trophy Key</translation>
</message>
<message>
<location filename="../settings_dialog.ui"/>
<source>Trophy</source>
<translation>Trophy</translation>
</message>
<message> <message>
<location filename="../settings_dialog.ui" line="178"/> <location filename="../settings_dialog.ui" line="178"/>
<source>Logger</source> <source>Logger</source>
@ -1236,6 +1246,11 @@
<source>userName</source> <source>userName</source>
<translation>Όνομα Χρήστη:\nΟρίζει το όνομα του λογαριασμού PS4, το οποίο μπορεί να εμφανιστεί σε ορισμένα παιχνίδια.</translation> <translation>Όνομα Χρήστη:\nΟρίζει το όνομα του λογαριασμού PS4, το οποίο μπορεί να εμφανιστεί σε ορισμένα παιχνίδια.</translation>
</message> </message>
<message>
<location filename="../settings_dialog.cpp"/>
<source>TrophyKey</source>
<translation>Trophy Key:\nKey used to decrypt trophies. Must be obtained from your jailbroken console.\nMust contain only hex characters.</translation>
</message>
<message> <message>
<location filename="../settings_dialog.cpp" line="301"/> <location filename="../settings_dialog.cpp" line="301"/>
<source>logTypeGroupBox</source> <source>logTypeGroupBox</source>

View File

@ -537,6 +537,16 @@
<source>Username</source> <source>Username</source>
<translation>Username</translation> <translation>Username</translation>
</message> </message>
<message>
<location filename="../settings_dialog.ui"/>
<source>Trophy Key</source>
<translation>Trophy Key</translation>
</message>
<message>
<location filename="../settings_dialog.ui"/>
<source>Trophy</source>
<translation>Trophy</translation>
</message>
<message> <message>
<location filename="../settings_dialog.ui" line="178"/> <location filename="../settings_dialog.ui" line="178"/>
<source>Logger</source> <source>Logger</source>
@ -1236,6 +1246,11 @@
<source>userName</source> <source>userName</source>
<translation>Username:\nSets the PS4's account username, which may be displayed by some games.</translation> <translation>Username:\nSets the PS4's account username, which may be displayed by some games.</translation>
</message> </message>
<message>
<location filename="../settings_dialog.cpp"/>
<source>TrophyKey</source>
<translation>Trophy Key:\nKey used to decrypt trophies. Must be obtained from your jailbroken console.\nMust contain only hex characters.</translation>
</message>
<message> <message>
<location filename="../settings_dialog.cpp" line="301"/> <location filename="../settings_dialog.cpp" line="301"/>
<source>logTypeGroupBox</source> <source>logTypeGroupBox</source>

View File

@ -537,6 +537,16 @@
<source>Username</source> <source>Username</source>
<translation>Nombre de usuario</translation> <translation>Nombre de usuario</translation>
</message> </message>
<message>
<location filename="../settings_dialog.ui"/>
<source>Trophy Key</source>
<translation>Trophy Key</translation>
</message>
<message>
<location filename="../settings_dialog.ui"/>
<source>Trophy</source>
<translation>Trophy</translation>
</message>
<message> <message>
<location filename="../settings_dialog.ui" line="178"/> <location filename="../settings_dialog.ui" line="178"/>
<source>Logger</source> <source>Logger</source>
@ -1236,6 +1246,11 @@
<source>userName</source> <source>userName</source>
<translation>Nombre de Usuario:\nEstablece el nombre de usuario de la cuenta de PS4, que puede ser mostrado por algunos juegos.</translation> <translation>Nombre de Usuario:\nEstablece el nombre de usuario de la cuenta de PS4, que puede ser mostrado por algunos juegos.</translation>
</message> </message>
<message>
<location filename="../settings_dialog.cpp"/>
<source>TrophyKey</source>
<translation>Trophy Key:\nKey used to decrypt trophies. Must be obtained from your jailbroken console.\nMust contain only hex characters.</translation>
</message>
<message> <message>
<location filename="../settings_dialog.cpp" line="301"/> <location filename="../settings_dialog.cpp" line="301"/>
<source>logTypeGroupBox</source> <source>logTypeGroupBox</source>

View File

@ -537,6 +537,16 @@
<source>Username</source> <source>Username</source>
<translation>نام کاربری</translation> <translation>نام کاربری</translation>
</message> </message>
<message>
<location filename="../settings_dialog.ui"/>
<source>Trophy Key</source>
<translation>Trophy Key</translation>
</message>
<message>
<location filename="../settings_dialog.ui"/>
<source>Trophy</source>
<translation>Trophy</translation>
</message>
<message> <message>
<location filename="../settings_dialog.ui" line="178"/> <location filename="../settings_dialog.ui" line="178"/>
<source>Logger</source> <source>Logger</source>
@ -1236,6 +1246,11 @@
<source>userName</source> <source>userName</source>
<translation>نام کاربری:\ام کاربری حساب PS4 را تنظیم میکند که ممکن است توسط برخی بازیها نمایش داده شود.</translation> <translation>نام کاربری:\ام کاربری حساب PS4 را تنظیم میکند که ممکن است توسط برخی بازیها نمایش داده شود.</translation>
</message> </message>
<message>
<location filename="../settings_dialog.cpp"/>
<source>TrophyKey</source>
<translation>Trophy Key:\nKey used to decrypt trophies. Must be obtained from your jailbroken console.\nMust contain only hex characters.</translation>
</message>
<message> <message>
<location filename="../settings_dialog.cpp" line="301"/> <location filename="../settings_dialog.cpp" line="301"/>
<source>logTypeGroupBox</source> <source>logTypeGroupBox</source>

View File

@ -537,6 +537,16 @@
<source>Username</source> <source>Username</source>
<translation>Username</translation> <translation>Username</translation>
</message> </message>
<message>
<location filename="../settings_dialog.ui"/>
<source>Trophy Key</source>
<translation>Trophy Key</translation>
</message>
<message>
<location filename="../settings_dialog.ui"/>
<source>Trophy</source>
<translation>Trophy</translation>
</message>
<message> <message>
<location filename="../settings_dialog.ui" line="178"/> <location filename="../settings_dialog.ui" line="178"/>
<source>Logger</source> <source>Logger</source>
@ -1236,6 +1246,11 @@
<source>userName</source> <source>userName</source>
<translation>Käyttäjänimi:\nAsettaa PS4-tilin käyttäjänimen, joka voi näkyä joissakin peleissä.</translation> <translation>Käyttäjänimi:\nAsettaa PS4-tilin käyttäjänimen, joka voi näkyä joissakin peleissä.</translation>
</message> </message>
<message>
<location filename="../settings_dialog.cpp"/>
<source>TrophyKey</source>
<translation>Trophy Key:\nKey used to decrypt trophies. Must be obtained from your jailbroken console.\nMust contain only hex characters.</translation>
</message>
<message> <message>
<location filename="../settings_dialog.cpp" line="301"/> <location filename="../settings_dialog.cpp" line="301"/>
<source>logTypeGroupBox</source> <source>logTypeGroupBox</source>

View File

@ -537,6 +537,16 @@
<source>Username</source> <source>Username</source>
<translation>Nom d'utilisateur</translation> <translation>Nom d'utilisateur</translation>
</message> </message>
<message>
<location filename="../settings_dialog.ui"/>
<source>Trophy Key</source>
<translation>Trophy Key</translation>
</message>
<message>
<location filename="../settings_dialog.ui"/>
<source>Trophy</source>
<translation>Trophy</translation>
</message>
<message> <message>
<location filename="../settings_dialog.ui" line="178"/> <location filename="../settings_dialog.ui" line="178"/>
<source>Logger</source> <source>Logger</source>
@ -1236,6 +1246,11 @@
<source>userName</source> <source>userName</source>
<translation>Nom d'utilisateur:\nDéfinit le nom d'utilisateur du compte PS4, qui peut être affiché par certains jeux.</translation> <translation>Nom d'utilisateur:\nDéfinit le nom d'utilisateur du compte PS4, qui peut être affiché par certains jeux.</translation>
</message> </message>
<message>
<location filename="../settings_dialog.cpp"/>
<source>TrophyKey</source>
<translation>Trophy Key:\nKey used to decrypt trophies. Must be obtained from your jailbroken console.\nMust contain only hex characters.</translation>
</message>
<message> <message>
<location filename="../settings_dialog.cpp" line="301"/> <location filename="../settings_dialog.cpp" line="301"/>
<source>logTypeGroupBox</source> <source>logTypeGroupBox</source>

View File

@ -537,6 +537,16 @@
<source>Username</source> <source>Username</source>
<translation>Felhasználónév</translation> <translation>Felhasználónév</translation>
</message> </message>
<message>
<location filename="../settings_dialog.ui"/>
<source>Trophy Key</source>
<translation>Trophy Key</translation>
</message>
<message>
<location filename="../settings_dialog.ui"/>
<source>Trophy</source>
<translation>Trophy</translation>
</message>
<message> <message>
<location filename="../settings_dialog.ui" line="178"/> <location filename="../settings_dialog.ui" line="178"/>
<source>Logger</source> <source>Logger</source>
@ -1236,6 +1246,11 @@
<source>userName</source> <source>userName</source>
<translation>Felhasználónév:\nBeállítja a PS4 fiók felhasználónevét, amelyet egyes játékok megjeleníthetnek.</translation> <translation>Felhasználónév:\nBeállítja a PS4 fiók felhasználónevét, amelyet egyes játékok megjeleníthetnek.</translation>
</message> </message>
<message>
<location filename="../settings_dialog.cpp"/>
<source>TrophyKey</source>
<translation>Trophy Key:\nKey used to decrypt trophies. Must be obtained from your jailbroken console.\nMust contain only hex characters.</translation>
</message>
<message> <message>
<location filename="../settings_dialog.cpp" line="301"/> <location filename="../settings_dialog.cpp" line="301"/>
<source>logTypeGroupBox</source> <source>logTypeGroupBox</source>

View File

@ -537,6 +537,16 @@
<source>Username</source> <source>Username</source>
<translation>Username</translation> <translation>Username</translation>
</message> </message>
<message>
<location filename="../settings_dialog.ui"/>
<source>Trophy Key</source>
<translation>Trophy Key</translation>
</message>
<message>
<location filename="../settings_dialog.ui"/>
<source>Trophy</source>
<translation>Trophy</translation>
</message>
<message> <message>
<location filename="../settings_dialog.ui" line="178"/> <location filename="../settings_dialog.ui" line="178"/>
<source>Logger</source> <source>Logger</source>
@ -1236,6 +1246,11 @@
<source>userName</source> <source>userName</source>
<translation>Nama Pengguna:\nMenetapkan nama pengguna akun PS4, yang mungkin ditampilkan oleh beberapa permainan.</translation> <translation>Nama Pengguna:\nMenetapkan nama pengguna akun PS4, yang mungkin ditampilkan oleh beberapa permainan.</translation>
</message> </message>
<message>
<location filename="../settings_dialog.cpp"/>
<source>TrophyKey</source>
<translation>Trophy Key:\nKey used to decrypt trophies. Must be obtained from your jailbroken console.\nMust contain only hex characters.</translation>
</message>
<message> <message>
<location filename="../settings_dialog.cpp" line="301"/> <location filename="../settings_dialog.cpp" line="301"/>
<source>logTypeGroupBox</source> <source>logTypeGroupBox</source>

View File

@ -537,6 +537,16 @@
<source>Username</source> <source>Username</source>
<translation>Nome Utente</translation> <translation>Nome Utente</translation>
</message> </message>
<message>
<location filename="../settings_dialog.ui"/>
<source>Trophy Key</source>
<translation>Trophy Key</translation>
</message>
<message>
<location filename="../settings_dialog.ui"/>
<source>Trophy</source>
<translation>Trophy</translation>
</message>
<message> <message>
<location filename="../settings_dialog.ui" line="178"/> <location filename="../settings_dialog.ui" line="178"/>
<source>Logger</source> <source>Logger</source>
@ -1236,6 +1246,11 @@
<source>userName</source> <source>userName</source>
<translation>Nome Utente:\nImposta il nome utente dell'account PS4, che potrebbe essere visualizzato da alcuni giochi.</translation> <translation>Nome Utente:\nImposta il nome utente dell'account PS4, che potrebbe essere visualizzato da alcuni giochi.</translation>
</message> </message>
<message>
<location filename="../settings_dialog.cpp"/>
<source>TrophyKey</source>
<translation>Trophy Key:\nKey used to decrypt trophies. Must be obtained from your jailbroken console.\nMust contain only hex characters.</translation>
</message>
<message> <message>
<location filename="../settings_dialog.cpp" line="301"/> <location filename="../settings_dialog.cpp" line="301"/>
<source>logTypeGroupBox</source> <source>logTypeGroupBox</source>

View File

@ -537,6 +537,16 @@
<source>Username</source> <source>Username</source>
<translation></translation> <translation></translation>
</message> </message>
<message>
<location filename="../settings_dialog.ui"/>
<source>Trophy Key</source>
<translation>Trophy Key</translation>
</message>
<message>
<location filename="../settings_dialog.ui"/>
<source>Trophy</source>
<translation>Trophy</translation>
</message>
<message> <message>
<location filename="../settings_dialog.ui" line="178"/> <location filename="../settings_dialog.ui" line="178"/>
<source>Logger</source> <source>Logger</source>
@ -1236,6 +1246,11 @@
<source>userName</source> <source>userName</source>
<translation>:\nPS4のアカウントユーザー名を設定します</translation> <translation>:\nPS4のアカウントユーザー名を設定します</translation>
</message> </message>
<message>
<location filename="../settings_dialog.cpp"/>
<source>TrophyKey</source>
<translation>Trophy Key:\nKey used to decrypt trophies. Must be obtained from your jailbroken console.\nMust contain only hex characters.</translation>
</message>
<message> <message>
<location filename="../settings_dialog.cpp" line="301"/> <location filename="../settings_dialog.cpp" line="301"/>
<source>logTypeGroupBox</source> <source>logTypeGroupBox</source>

View File

@ -537,6 +537,16 @@
<source>Username</source> <source>Username</source>
<translation>Username</translation> <translation>Username</translation>
</message> </message>
<message>
<location filename="../settings_dialog.ui"/>
<source>Trophy Key</source>
<translation>Trophy Key</translation>
</message>
<message>
<location filename="../settings_dialog.ui"/>
<source>Trophy</source>
<translation>Trophy</translation>
</message>
<message> <message>
<location filename="../settings_dialog.ui" line="178"/> <location filename="../settings_dialog.ui" line="178"/>
<source>Logger</source> <source>Logger</source>
@ -1236,6 +1246,11 @@
<source>userName</source> <source>userName</source>
<translation>Username:\nSets the PS4's account username, which may be displayed by some games.</translation> <translation>Username:\nSets the PS4's account username, which may be displayed by some games.</translation>
</message> </message>
<message>
<location filename="../settings_dialog.cpp"/>
<source>TrophyKey</source>
<translation>Trophy Key:\nKey used to decrypt trophies. Must be obtained from your jailbroken console.\nMust contain only hex characters.</translation>
</message>
<message> <message>
<location filename="../settings_dialog.cpp" line="301"/> <location filename="../settings_dialog.cpp" line="301"/>
<source>logTypeGroupBox</source> <source>logTypeGroupBox</source>

View File

@ -537,6 +537,16 @@
<source>Username</source> <source>Username</source>
<translation>Username</translation> <translation>Username</translation>
</message> </message>
<message>
<location filename="../settings_dialog.ui"/>
<source>Trophy Key</source>
<translation>Trophy Key</translation>
</message>
<message>
<location filename="../settings_dialog.ui"/>
<source>Trophy</source>
<translation>Trophy</translation>
</message>
<message> <message>
<location filename="../settings_dialog.ui" line="178"/> <location filename="../settings_dialog.ui" line="178"/>
<source>Logger</source> <source>Logger</source>
@ -1236,6 +1246,11 @@
<source>userName</source> <source>userName</source>
<translation>Vartotojo vardas:\nNustato PS4 paskyros vartotojo vardą, kuris gali būti rodomas kai kuriuose žaidimuose.</translation> <translation>Vartotojo vardas:\nNustato PS4 paskyros vartotojo vardą, kuris gali būti rodomas kai kuriuose žaidimuose.</translation>
</message> </message>
<message>
<location filename="../settings_dialog.cpp"/>
<source>TrophyKey</source>
<translation>Trophy Key:\nKey used to decrypt trophies. Must be obtained from your jailbroken console.\nMust contain only hex characters.</translation>
</message>
<message> <message>
<location filename="../settings_dialog.cpp" line="301"/> <location filename="../settings_dialog.cpp" line="301"/>
<source>logTypeGroupBox</source> <source>logTypeGroupBox</source>

View File

@ -537,6 +537,16 @@
<source>Username</source> <source>Username</source>
<translation>Brukernavn</translation> <translation>Brukernavn</translation>
</message> </message>
<message>
<location filename="../settings_dialog.ui"/>
<source>Trophy Key</source>
<translation>Trophy Key</translation>
</message>
<message>
<location filename="../settings_dialog.ui"/>
<source>Trophy</source>
<translation>Trophy</translation>
</message>
<message> <message>
<location filename="../settings_dialog.ui" line="178"/> <location filename="../settings_dialog.ui" line="178"/>
<source>Logger</source> <source>Logger</source>
@ -1236,6 +1246,11 @@
<source>userName</source> <source>userName</source>
<translation>Brukernavn:\nAngir brukernavnet for PS4-kontoen, som kan vises av enkelte spill.</translation> <translation>Brukernavn:\nAngir brukernavnet for PS4-kontoen, som kan vises av enkelte spill.</translation>
</message> </message>
<message>
<location filename="../settings_dialog.cpp"/>
<source>TrophyKey</source>
<translation>Trophy Key:\nKey used to decrypt trophies. Must be obtained from your jailbroken console.\nMust contain only hex characters.</translation>
</message>
<message> <message>
<location filename="../settings_dialog.cpp" line="301"/> <location filename="../settings_dialog.cpp" line="301"/>
<source>logTypeGroupBox</source> <source>logTypeGroupBox</source>

View File

@ -537,6 +537,16 @@
<source>Username</source> <source>Username</source>
<translation>Username</translation> <translation>Username</translation>
</message> </message>
<message>
<location filename="../settings_dialog.ui"/>
<source>Trophy Key</source>
<translation>Trophy Key</translation>
</message>
<message>
<location filename="../settings_dialog.ui"/>
<source>Trophy</source>
<translation>Trophy</translation>
</message>
<message> <message>
<location filename="../settings_dialog.ui" line="178"/> <location filename="../settings_dialog.ui" line="178"/>
<source>Logger</source> <source>Logger</source>
@ -1236,6 +1246,11 @@
<source>userName</source> <source>userName</source>
<translation>Gebruikersnaam:\nStelt de gebruikersnaam van het PS4-account in, die door sommige games kan worden weergegeven.</translation> <translation>Gebruikersnaam:\nStelt de gebruikersnaam van het PS4-account in, die door sommige games kan worden weergegeven.</translation>
</message> </message>
<message>
<location filename="../settings_dialog.cpp"/>
<source>TrophyKey</source>
<translation>Trophy Key:\nKey used to decrypt trophies. Must be obtained from your jailbroken console.\nMust contain only hex characters.</translation>
</message>
<message> <message>
<location filename="../settings_dialog.cpp" line="301"/> <location filename="../settings_dialog.cpp" line="301"/>
<source>logTypeGroupBox</source> <source>logTypeGroupBox</source>

View File

@ -537,6 +537,16 @@
<source>Username</source> <source>Username</source>
<translation>Nazwa użytkownika</translation> <translation>Nazwa użytkownika</translation>
</message> </message>
<message>
<location filename="../settings_dialog.ui"/>
<source>Trophy Key</source>
<translation>Trophy Key</translation>
</message>
<message>
<location filename="../settings_dialog.ui"/>
<source>Trophy</source>
<translation>Trophy</translation>
</message>
<message> <message>
<location filename="../settings_dialog.ui" line="178"/> <location filename="../settings_dialog.ui" line="178"/>
<source>Logger</source> <source>Logger</source>
@ -1236,6 +1246,11 @@
<source>userName</source> <source>userName</source>
<translation>Nazwa użytkownika:\nUstala nazwę użytkownika konta PS4, która może być wyświetlana w niektórych grach.</translation> <translation>Nazwa użytkownika:\nUstala nazwę użytkownika konta PS4, która może być wyświetlana w niektórych grach.</translation>
</message> </message>
<message>
<location filename="../settings_dialog.cpp"/>
<source>TrophyKey</source>
<translation>Trophy Key:\nKey used to decrypt trophies. Must be obtained from your jailbroken console.\nMust contain only hex characters.</translation>
</message>
<message> <message>
<location filename="../settings_dialog.cpp" line="301"/> <location filename="../settings_dialog.cpp" line="301"/>
<source>logTypeGroupBox</source> <source>logTypeGroupBox</source>

View File

@ -537,6 +537,16 @@
<source>Username</source> <source>Username</source>
<translation>Nome de usuário</translation> <translation>Nome de usuário</translation>
</message> </message>
<message>
<location filename="../settings_dialog.ui"/>
<source>Trophy Key</source>
<translation>Trophy Key</translation>
</message>
<message>
<location filename="../settings_dialog.ui"/>
<source>Trophy</source>
<translation>Troféus</translation>
</message>
<message> <message>
<location filename="../settings_dialog.ui" line="178"/> <location filename="../settings_dialog.ui" line="178"/>
<source>Logger</source> <source>Logger</source>
@ -1236,6 +1246,11 @@
<source>userName</source> <source>userName</source>
<translation>Nome de usuário:\nDefine o nome de usuário da conta PS4 que pode ser exibido por alguns jogos.</translation> <translation>Nome de usuário:\nDefine o nome de usuário da conta PS4 que pode ser exibido por alguns jogos.</translation>
</message> </message>
<message>
<location filename="../settings_dialog.cpp"/>
<source>TrophyKey</source>
<translation>Trophy Key:\nKey used to decrypt trophies. Must be obtained from your jailbroken console.\nMust contain only hex characters.</translation>
</message>
<message> <message>
<location filename="../settings_dialog.cpp" line="301"/> <location filename="../settings_dialog.cpp" line="301"/>
<source>logTypeGroupBox</source> <source>logTypeGroupBox</source>

View File

@ -537,6 +537,16 @@
<source>Username</source> <source>Username</source>
<translation>Username</translation> <translation>Username</translation>
</message> </message>
<message>
<location filename="../settings_dialog.ui"/>
<source>Trophy Key</source>
<translation>Trophy Key</translation>
</message>
<message>
<location filename="../settings_dialog.ui"/>
<source>Trophy</source>
<translation>Trophy</translation>
</message>
<message> <message>
<location filename="../settings_dialog.ui" line="178"/> <location filename="../settings_dialog.ui" line="178"/>
<source>Logger</source> <source>Logger</source>
@ -1236,6 +1246,11 @@
<source>userName</source> <source>userName</source>
<translation>Nume utilizator:\nSetează numele de utilizator al contului PS4, care poate fi afișat de unele jocuri.</translation> <translation>Nume utilizator:\nSetează numele de utilizator al contului PS4, care poate fi afișat de unele jocuri.</translation>
</message> </message>
<message>
<location filename="../settings_dialog.cpp"/>
<source>TrophyKey</source>
<translation>Trophy Key:\nKey used to decrypt trophies. Must be obtained from your jailbroken console.\nMust contain only hex characters.</translation>
</message>
<message> <message>
<location filename="../settings_dialog.cpp" line="301"/> <location filename="../settings_dialog.cpp" line="301"/>
<source>logTypeGroupBox</source> <source>logTypeGroupBox</source>

View File

@ -537,6 +537,16 @@
<source>Username</source> <source>Username</source>
<translation>Имя пользователя</translation> <translation>Имя пользователя</translation>
</message> </message>
<message>
<location filename="../settings_dialog.ui"/>
<source>Trophy Key</source>
<translation>Trophy Key</translation>
</message>
<message>
<location filename="../settings_dialog.ui"/>
<source>Trophy</source>
<translation>Trophy</translation>
</message>
<message> <message>
<location filename="../settings_dialog.ui" line="178"/> <location filename="../settings_dialog.ui" line="178"/>
<source>Logger</source> <source>Logger</source>
@ -1236,6 +1246,11 @@
<source>userName</source> <source>userName</source>
<translation>Имя пользователя:\nУстановите имя пользователя аккаунта PS4. Это может отображаться в некоторых играх.</translation> <translation>Имя пользователя:\nУстановите имя пользователя аккаунта PS4. Это может отображаться в некоторых играх.</translation>
</message> </message>
<message>
<location filename="../settings_dialog.cpp"/>
<source>TrophyKey</source>
<translation>Trophy Key:\nKey used to decrypt trophies. Must be obtained from your jailbroken console.\nMust contain only hex characters.</translation>
</message>
<message> <message>
<location filename="../settings_dialog.cpp" line="301"/> <location filename="../settings_dialog.cpp" line="301"/>
<source>logTypeGroupBox</source> <source>logTypeGroupBox</source>

View File

@ -537,6 +537,16 @@
<source>Username</source> <source>Username</source>
<translation>Përdoruesi</translation> <translation>Përdoruesi</translation>
</message> </message>
<message>
<location filename="../settings_dialog.ui"/>
<source>Trophy Key</source>
<translation>Trophy Key</translation>
</message>
<message>
<location filename="../settings_dialog.ui"/>
<source>Trophy</source>
<translation>Trophy</translation>
</message>
<message> <message>
<location filename="../settings_dialog.ui" line="178"/> <location filename="../settings_dialog.ui" line="178"/>
<source>Logger</source> <source>Logger</source>
@ -1236,6 +1246,11 @@
<source>userName</source> <source>userName</source>
<translation>Përdoruesi:\nPërcakton emrin e përdoruesit llogarisë PS4, i cili mund shfaqet nga disa lojra.</translation> <translation>Përdoruesi:\nPërcakton emrin e përdoruesit llogarisë PS4, i cili mund shfaqet nga disa lojra.</translation>
</message> </message>
<message>
<location filename="../settings_dialog.cpp"/>
<source>TrophyKey</source>
<translation>Trophy Key:\nKey used to decrypt trophies. Must be obtained from your jailbroken console.\nMust contain only hex characters.</translation>
</message>
<message> <message>
<location filename="../settings_dialog.cpp" line="301"/> <location filename="../settings_dialog.cpp" line="301"/>
<source>logTypeGroupBox</source> <source>logTypeGroupBox</source>

View File

@ -537,6 +537,16 @@
<source>Username</source> <source>Username</source>
<translation>Kullanıcı Adı</translation> <translation>Kullanıcı Adı</translation>
</message> </message>
<message>
<location filename="../settings_dialog.ui"/>
<source>Trophy Key</source>
<translation>Trophy Key</translation>
</message>
<message>
<location filename="../settings_dialog.ui"/>
<source>Trophy</source>
<translation>Trophy</translation>
</message>
<message> <message>
<location filename="../settings_dialog.ui" line="178"/> <location filename="../settings_dialog.ui" line="178"/>
<source>Logger</source> <source>Logger</source>
@ -1236,6 +1246,11 @@
<source>userName</source> <source>userName</source>
<translation>Kullanıcı Adı:\nBazı oyunlar tarafından gösterilebilen PS4 hesabının kullanıcı adını ayarlar.</translation> <translation>Kullanıcı Adı:\nBazı oyunlar tarafından gösterilebilen PS4 hesabının kullanıcı adını ayarlar.</translation>
</message> </message>
<message>
<location filename="../settings_dialog.cpp"/>
<source>TrophyKey</source>
<translation>Trophy Key:\nKey used to decrypt trophies. Must be obtained from your jailbroken console.\nMust contain only hex characters.</translation>
</message>
<message> <message>
<location filename="../settings_dialog.cpp" line="301"/> <location filename="../settings_dialog.cpp" line="301"/>
<source>logTypeGroupBox</source> <source>logTypeGroupBox</source>

View File

@ -537,6 +537,16 @@
<source>Username</source> <source>Username</source>
<translation>Ім'я користувача</translation> <translation>Ім'я користувача</translation>
</message> </message>
<message>
<location filename="../settings_dialog.ui"/>
<source>Trophy Key</source>
<translation>Trophy Key</translation>
</message>
<message>
<location filename="../settings_dialog.ui"/>
<source>Trophy</source>
<translation>Trophy</translation>
</message>
<message> <message>
<location filename="../settings_dialog.ui" line="178"/> <location filename="../settings_dialog.ui" line="178"/>
<source>Logger</source> <source>Logger</source>
@ -1236,6 +1246,11 @@
<source>userName</source> <source>userName</source>
<translation>Ім'я користувача:\nВстановіть ім'я користувача акаунта PS4. Це може відображатися в деяких іграх.</translation> <translation>Ім'я користувача:\nВстановіть ім'я користувача акаунта PS4. Це може відображатися в деяких іграх.</translation>
</message> </message>
<message>
<location filename="../settings_dialog.cpp"/>
<source>TrophyKey</source>
<translation>Trophy Key:\nKey used to decrypt trophies. Must be obtained from your jailbroken console.\nMust contain only hex characters.</translation>
</message>
<message> <message>
<location filename="../settings_dialog.cpp" line="301"/> <location filename="../settings_dialog.cpp" line="301"/>
<source>logTypeGroupBox</source> <source>logTypeGroupBox</source>

View File

@ -537,6 +537,16 @@
<source>Username</source> <source>Username</source>
<translation>Username</translation> <translation>Username</translation>
</message> </message>
<message>
<location filename="../settings_dialog.ui"/>
<source>Trophy Key</source>
<translation>Trophy Key</translation>
</message>
<message>
<location filename="../settings_dialog.ui"/>
<source>Trophy</source>
<translation>Trophy</translation>
</message>
<message> <message>
<location filename="../settings_dialog.ui" line="178"/> <location filename="../settings_dialog.ui" line="178"/>
<source>Logger</source> <source>Logger</source>
@ -1236,6 +1246,11 @@
<source>userName</source> <source>userName</source>
<translation>Tên người dùng:\nChọn tên người dùng của tài khoản PS4, thể đưc một số trò chơi hiển thị.</translation> <translation>Tên người dùng:\nChọn tên người dùng của tài khoản PS4, thể đưc một số trò chơi hiển thị.</translation>
</message> </message>
<message>
<location filename="../settings_dialog.cpp"/>
<source>TrophyKey</source>
<translation>Trophy Key:\nKey used to decrypt trophies. Must be obtained from your jailbroken console.\nMust contain only hex characters.</translation>
</message>
<message> <message>
<location filename="../settings_dialog.cpp" line="301"/> <location filename="../settings_dialog.cpp" line="301"/>
<source>logTypeGroupBox</source> <source>logTypeGroupBox</source>

View File

@ -537,6 +537,16 @@
<source>Username</source> <source>Username</source>
<translation></translation> <translation></translation>
</message> </message>
<message>
<location filename="../settings_dialog.ui"/>
<source>Trophy Key</source>
<translation>Trophy Key</translation>
</message>
<message>
<location filename="../settings_dialog.ui"/>
<source>Trophy</source>
<translation>Trophy</translation>
</message>
<message> <message>
<location filename="../settings_dialog.ui" line="178"/> <location filename="../settings_dialog.ui" line="178"/>
<source>Logger</source> <source>Logger</source>
@ -1236,6 +1246,11 @@
<source>userName</source> <source>userName</source>
<translation>\n设置 PS4 </translation> <translation>\n设置 PS4 </translation>
</message> </message>
<message>
<location filename="../settings_dialog.cpp"/>
<source>TrophyKey</source>
<translation>Trophy Key:\nKey used to decrypt trophies. Must be obtained from your jailbroken console.\nMust contain only hex characters.</translation>
</message>
<message> <message>
<location filename="../settings_dialog.cpp" line="301"/> <location filename="../settings_dialog.cpp" line="301"/>
<source>logTypeGroupBox</source> <source>logTypeGroupBox</source>

View File

@ -537,6 +537,16 @@
<source>Username</source> <source>Username</source>
<translation>Username</translation> <translation>Username</translation>
</message> </message>
<message>
<location filename="../settings_dialog.ui"/>
<source>Trophy Key</source>
<translation>Trophy Key</translation>
</message>
<message>
<location filename="../settings_dialog.ui"/>
<source>Trophy</source>
<translation>Trophy</translation>
</message>
<message> <message>
<location filename="../settings_dialog.ui" line="178"/> <location filename="../settings_dialog.ui" line="178"/>
<source>Logger</source> <source>Logger</source>
@ -1236,6 +1246,11 @@
<source>userName</source> <source>userName</source>
<translation>:\n設定PS4帳號的用戶名</translation> <translation>:\n設定PS4帳號的用戶名</translation>
</message> </message>
<message>
<location filename="../settings_dialog.cpp"/>
<source>TrophyKey</source>
<translation>Trophy Key:\nKey used to decrypt trophies. Must be obtained from your jailbroken console.\nMust contain only hex characters.</translation>
</message>
<message> <message>
<location filename="../settings_dialog.cpp" line="301"/> <location filename="../settings_dialog.cpp" line="301"/>
<source>logTypeGroupBox</source> <source>logTypeGroupBox</source>

View File

@ -889,11 +889,11 @@ struct Liverpool {
return !info.linear_general; return !info.linear_general;
} }
[[nodiscard]] DataFormat DataFormat() const { [[nodiscard]] DataFormat GetDataFmt() const {
return RemapDataFormat(info.format); return RemapDataFormat(info.format);
} }
[[nodiscard]] NumberFormat NumFormat() const { [[nodiscard]] NumberFormat GetNumberFmt() const {
// There is a small difference between T# and CB number types, account for it. // There is a small difference between T# and CB number types, account for it.
return RemapNumberFormat(info.number_type == NumberFormat::SnormNz return RemapNumberFormat(info.number_type == NumberFormat::SnormNz
? NumberFormat::Srgb ? NumberFormat::Srgb

View File

@ -79,21 +79,23 @@ inline NumberFormat RemapNumberFormat(const NumberFormat format) {
inline CompMapping RemapComponents(const DataFormat format, const CompMapping components) { inline CompMapping RemapComponents(const DataFormat format, const CompMapping components) {
switch (format) { switch (format) {
case DataFormat::Format11_11_10: case DataFormat::Format11_11_10: {
return { CompMapping result;
.r = components.b, result.r = components.b;
.g = components.g, result.g = components.g;
.b = components.r, result.b = components.r;
.a = components.a, result.a = components.a;
}; return result;
}
case DataFormat::Format10_10_10_2: case DataFormat::Format10_10_10_2:
case DataFormat::Format5_5_5_1: case DataFormat::Format5_5_5_1: {
return { CompMapping result;
.r = components.a, result.r = components.a;
.g = components.b, result.g = components.b;
.b = components.g, result.b = components.g;
.a = components.r, result.a = components.r;
}; return result;
}
default: default:
return components; return components;
} }

View File

@ -54,18 +54,10 @@ BufferCache::BufferCache(const Vulkan::Instance& instance_, Vulkan::Scheduler& s
BufferCache::~BufferCache() = default; BufferCache::~BufferCache() = default;
void BufferCache::InvalidateMemory(VAddr device_addr, u64 size) { void BufferCache::InvalidateMemory(VAddr device_addr, u64 size) {
std::scoped_lock lk{mutex};
const bool is_tracked = IsRegionRegistered(device_addr, size); const bool is_tracked = IsRegionRegistered(device_addr, size);
if (!is_tracked) { if (is_tracked) {
return; // Mark the page as CPU modified to stop tracking writes.
}
// Mark the page as CPU modified to stop tracking writes.
SCOPE_EXIT {
memory_tracker.MarkRegionAsCpuModified(device_addr, size); memory_tracker.MarkRegionAsCpuModified(device_addr, size);
};
if (!memory_tracker.IsRegionGpuModified(device_addr, size)) {
// Page has not been modified by the GPU, nothing to do.
return;
} }
} }
@ -346,6 +338,7 @@ bool BufferCache::IsRegionRegistered(VAddr addr, size_t size) {
++page; ++page;
continue; continue;
} }
std::shared_lock lk{mutex};
Buffer& buffer = slot_buffers[buffer_id]; Buffer& buffer = slot_buffers[buffer_id];
const VAddr buf_start_addr = buffer.CpuAddr(); const VAddr buf_start_addr = buffer.CpuAddr();
const VAddr buf_end_addr = buf_start_addr + buffer.SizeBytes(); const VAddr buf_end_addr = buf_start_addr + buffer.SizeBytes();
@ -496,8 +489,11 @@ BufferId BufferCache::CreateBuffer(VAddr device_addr, u32 wanted_size) {
wanted_size = static_cast<u32>(device_addr_end - device_addr); wanted_size = static_cast<u32>(device_addr_end - device_addr);
const OverlapResult overlap = ResolveOverlaps(device_addr, wanted_size); const OverlapResult overlap = ResolveOverlaps(device_addr, wanted_size);
const u32 size = static_cast<u32>(overlap.end - overlap.begin); const u32 size = static_cast<u32>(overlap.end - overlap.begin);
const BufferId new_buffer_id = slot_buffers.insert( const BufferId new_buffer_id = [&] {
instance, scheduler, MemoryUsage::DeviceLocal, overlap.begin, AllFlags, size); std::scoped_lock lk{mutex};
return slot_buffers.insert(instance, scheduler, MemoryUsage::DeviceLocal, overlap.begin,
AllFlags, size);
}();
auto& new_buffer = slot_buffers[new_buffer_id]; auto& new_buffer = slot_buffers[new_buffer_id];
const size_t size_bytes = new_buffer.SizeBytes(); const size_t size_bytes = new_buffer.SizeBytes();
const auto cmdbuf = scheduler.CommandBuffer(); const auto cmdbuf = scheduler.CommandBuffer();
@ -537,10 +533,8 @@ void BufferCache::ChangeRegister(BufferId buffer_id) {
void BufferCache::SynchronizeBuffer(Buffer& buffer, VAddr device_addr, u32 size, void BufferCache::SynchronizeBuffer(Buffer& buffer, VAddr device_addr, u32 size,
bool is_texel_buffer) { bool is_texel_buffer) {
std::scoped_lock lk{mutex};
boost::container::small_vector<vk::BufferCopy, 4> copies; boost::container::small_vector<vk::BufferCopy, 4> copies;
u64 total_size_bytes = 0; u64 total_size_bytes = 0;
u64 largest_copy = 0;
VAddr buffer_start = buffer.CpuAddr(); VAddr buffer_start = buffer.CpuAddr();
memory_tracker.ForEachUploadRange(device_addr, size, [&](u64 device_addr_out, u64 range_size) { memory_tracker.ForEachUploadRange(device_addr, size, [&](u64 device_addr_out, u64 range_size) {
copies.push_back(vk::BufferCopy{ copies.push_back(vk::BufferCopy{
@ -549,7 +543,6 @@ void BufferCache::SynchronizeBuffer(Buffer& buffer, VAddr device_addr, u32 size,
.size = range_size, .size = range_size,
}); });
total_size_bytes += range_size; total_size_bytes += range_size;
largest_copy = std::max(largest_copy, range_size);
}); });
SCOPE_EXIT { SCOPE_EXIT {
if (is_texel_buffer) { if (is_texel_buffer) {

View File

@ -3,7 +3,7 @@
#pragma once #pragma once
#include <mutex> #include <shared_mutex>
#include <boost/container/small_vector.hpp> #include <boost/container/small_vector.hpp>
#include <boost/icl/interval_map.hpp> #include <boost/icl/interval_map.hpp>
#include <tsl/robin_map.h> #include <tsl/robin_map.h>
@ -157,7 +157,7 @@ private:
StreamBuffer staging_buffer; StreamBuffer staging_buffer;
StreamBuffer stream_buffer; StreamBuffer stream_buffer;
Buffer gds_buffer; Buffer gds_buffer;
std::mutex mutex; std::shared_mutex mutex;
Common::SlotVector<Buffer> slot_buffers; Common::SlotVector<Buffer> slot_buffers;
RangeSet gpu_modified_ranges; RangeSet gpu_modified_ranges;
vk::BufferView null_buffer_view; vk::BufferView null_buffer_view;

View File

@ -15,13 +15,8 @@ namespace VideoCore {
class MemoryTracker { class MemoryTracker {
public: public:
static constexpr size_t MAX_CPU_PAGE_BITS = 40; static constexpr size_t MAX_CPU_PAGE_BITS = 40;
static constexpr size_t HIGHER_PAGE_BITS = 22;
static constexpr size_t HIGHER_PAGE_SIZE = 1ULL << HIGHER_PAGE_BITS;
static constexpr size_t HIGHER_PAGE_MASK = HIGHER_PAGE_SIZE - 1ULL;
static constexpr size_t NUM_HIGH_PAGES = 1ULL << (MAX_CPU_PAGE_BITS - HIGHER_PAGE_BITS); static constexpr size_t NUM_HIGH_PAGES = 1ULL << (MAX_CPU_PAGE_BITS - HIGHER_PAGE_BITS);
static constexpr size_t MANAGER_POOL_SIZE = 32; static constexpr size_t MANAGER_POOL_SIZE = 32;
static constexpr size_t WORDS_STACK_NEEDED = HIGHER_PAGE_SIZE / BYTES_PER_WORD;
using Manager = WordManager<WORDS_STACK_NEEDED>;
public: public:
explicit MemoryTracker(PageManager* tracker_) : tracker{tracker_} {} explicit MemoryTracker(PageManager* tracker_) : tracker{tracker_} {}
@ -30,7 +25,7 @@ public:
/// Returns true if a region has been modified from the CPU /// Returns true if a region has been modified from the CPU
[[nodiscard]] bool IsRegionCpuModified(VAddr query_cpu_addr, u64 query_size) noexcept { [[nodiscard]] bool IsRegionCpuModified(VAddr query_cpu_addr, u64 query_size) noexcept {
return IteratePages<true>( return IteratePages<true>(
query_cpu_addr, query_size, [](Manager* manager, u64 offset, size_t size) { query_cpu_addr, query_size, [](RegionManager* manager, u64 offset, size_t size) {
return manager->template IsRegionModified<Type::CPU>(offset, size); return manager->template IsRegionModified<Type::CPU>(offset, size);
}); });
} }
@ -38,52 +33,34 @@ public:
/// Returns true if a region has been modified from the GPU /// Returns true if a region has been modified from the GPU
[[nodiscard]] bool IsRegionGpuModified(VAddr query_cpu_addr, u64 query_size) noexcept { [[nodiscard]] bool IsRegionGpuModified(VAddr query_cpu_addr, u64 query_size) noexcept {
return IteratePages<false>( return IteratePages<false>(
query_cpu_addr, query_size, [](Manager* manager, u64 offset, size_t size) { query_cpu_addr, query_size, [](RegionManager* manager, u64 offset, size_t size) {
return manager->template IsRegionModified<Type::GPU>(offset, size); return manager->template IsRegionModified<Type::GPU>(offset, size);
}); });
} }
/// Mark region as CPU modified, notifying the device_tracker about this change /// Mark region as CPU modified, notifying the device_tracker about this change
void MarkRegionAsCpuModified(VAddr dirty_cpu_addr, u64 query_size) { void MarkRegionAsCpuModified(VAddr dirty_cpu_addr, u64 query_size) {
IteratePages<true>(dirty_cpu_addr, query_size, IteratePages<false>(dirty_cpu_addr, query_size,
[](Manager* manager, u64 offset, size_t size) { [](RegionManager* manager, u64 offset, size_t size) {
manager->template ChangeRegionState<Type::CPU, true>( manager->template ChangeRegionState<Type::CPU, true>(
manager->GetCpuAddr() + offset, size); manager->GetCpuAddr() + offset, size);
}); });
}
/// Unmark region as CPU modified, notifying the device_tracker about this change
void UnmarkRegionAsCpuModified(VAddr dirty_cpu_addr, u64 query_size) {
IteratePages<true>(dirty_cpu_addr, query_size,
[](Manager* manager, u64 offset, size_t size) {
manager->template ChangeRegionState<Type::CPU, false>(
manager->GetCpuAddr() + offset, size);
});
} }
/// Mark region as modified from the host GPU /// Mark region as modified from the host GPU
void MarkRegionAsGpuModified(VAddr dirty_cpu_addr, u64 query_size) noexcept { void MarkRegionAsGpuModified(VAddr dirty_cpu_addr, u64 query_size) noexcept {
IteratePages<true>(dirty_cpu_addr, query_size, IteratePages<false>(dirty_cpu_addr, query_size,
[](Manager* manager, u64 offset, size_t size) { [](RegionManager* manager, u64 offset, size_t size) {
manager->template ChangeRegionState<Type::GPU, true>( manager->template ChangeRegionState<Type::GPU, true>(
manager->GetCpuAddr() + offset, size); manager->GetCpuAddr() + offset, size);
}); });
}
/// Unmark region as modified from the host GPU
void UnmarkRegionAsGpuModified(VAddr dirty_cpu_addr, u64 query_size) noexcept {
IteratePages<true>(dirty_cpu_addr, query_size,
[](Manager* manager, u64 offset, size_t size) {
manager->template ChangeRegionState<Type::GPU, false>(
manager->GetCpuAddr() + offset, size);
});
} }
/// Call 'func' for each CPU modified range and unmark those pages as CPU modified /// Call 'func' for each CPU modified range and unmark those pages as CPU modified
template <typename Func> template <typename Func>
void ForEachUploadRange(VAddr query_cpu_range, u64 query_size, Func&& func) { void ForEachUploadRange(VAddr query_cpu_range, u64 query_size, Func&& func) {
IteratePages<true>(query_cpu_range, query_size, IteratePages<true>(query_cpu_range, query_size,
[&func](Manager* manager, u64 offset, size_t size) { [&func](RegionManager* manager, u64 offset, size_t size) {
manager->template ForEachModifiedRange<Type::CPU, true>( manager->template ForEachModifiedRange<Type::CPU, true>(
manager->GetCpuAddr() + offset, size, func); manager->GetCpuAddr() + offset, size, func);
}); });
@ -93,7 +70,7 @@ public:
template <bool clear, typename Func> template <bool clear, typename Func>
void ForEachDownloadRange(VAddr query_cpu_range, u64 query_size, Func&& func) { void ForEachDownloadRange(VAddr query_cpu_range, u64 query_size, Func&& func) {
IteratePages<false>(query_cpu_range, query_size, IteratePages<false>(query_cpu_range, query_size,
[&func](Manager* manager, u64 offset, size_t size) { [&func](RegionManager* manager, u64 offset, size_t size) {
if constexpr (clear) { if constexpr (clear) {
manager->template ForEachModifiedRange<Type::GPU, true>( manager->template ForEachModifiedRange<Type::GPU, true>(
manager->GetCpuAddr() + offset, size, func); manager->GetCpuAddr() + offset, size, func);
@ -114,7 +91,7 @@ private:
*/ */
template <bool create_region_on_fail, typename Func> template <bool create_region_on_fail, typename Func>
bool IteratePages(VAddr cpu_address, size_t size, Func&& func) { bool IteratePages(VAddr cpu_address, size_t size, Func&& func) {
using FuncReturn = typename std::invoke_result<Func, Manager*, u64, size_t>::type; using FuncReturn = typename std::invoke_result<Func, RegionManager*, u64, size_t>::type;
static constexpr bool BOOL_BREAK = std::is_same_v<FuncReturn, bool>; static constexpr bool BOOL_BREAK = std::is_same_v<FuncReturn, bool>;
std::size_t remaining_size{size}; std::size_t remaining_size{size};
std::size_t page_index{cpu_address >> HIGHER_PAGE_BITS}; std::size_t page_index{cpu_address >> HIGHER_PAGE_BITS};
@ -155,7 +132,7 @@ private:
manager_pool.emplace_back(); manager_pool.emplace_back();
auto& last_pool = manager_pool.back(); auto& last_pool = manager_pool.back();
for (size_t i = 0; i < MANAGER_POOL_SIZE; i++) { for (size_t i = 0; i < MANAGER_POOL_SIZE; i++) {
std::construct_at(&last_pool[i], tracker, 0, HIGHER_PAGE_SIZE); std::construct_at(&last_pool[i], tracker, 0);
free_managers.push_back(&last_pool[i]); free_managers.push_back(&last_pool[i]);
} }
} }
@ -167,9 +144,9 @@ private:
} }
PageManager* tracker; PageManager* tracker;
std::deque<std::array<Manager, MANAGER_POOL_SIZE>> manager_pool; std::deque<std::array<RegionManager, MANAGER_POOL_SIZE>> manager_pool;
std::vector<Manager*> free_managers; std::vector<RegionManager*> free_managers;
std::array<Manager*, NUM_HIGH_PAGES> top_tier{}; std::array<RegionManager*, NUM_HIGH_PAGES> top_tier{};
}; };
} // namespace VideoCore } // namespace VideoCore

View File

@ -3,10 +3,12 @@
#pragma once #pragma once
#include <algorithm> #include <array>
#include <mutex>
#include <span> #include <span>
#include <utility> #include <utility>
#include "common/div_ceil.h"
#include "common/spin_lock.h"
#include "common/types.h" #include "common/types.h"
#include "video_core/page_manager.h" #include "video_core/page_manager.h"
@ -16,135 +18,32 @@ constexpr u64 PAGES_PER_WORD = 64;
constexpr u64 BYTES_PER_PAGE = 4_KB; constexpr u64 BYTES_PER_PAGE = 4_KB;
constexpr u64 BYTES_PER_WORD = PAGES_PER_WORD * BYTES_PER_PAGE; constexpr u64 BYTES_PER_WORD = PAGES_PER_WORD * BYTES_PER_PAGE;
constexpr u64 HIGHER_PAGE_BITS = 22;
constexpr u64 HIGHER_PAGE_SIZE = 1ULL << HIGHER_PAGE_BITS;
constexpr u64 HIGHER_PAGE_MASK = HIGHER_PAGE_SIZE - 1ULL;
constexpr u64 NUM_REGION_WORDS = HIGHER_PAGE_SIZE / BYTES_PER_WORD;
enum class Type { enum class Type {
CPU, CPU,
GPU, GPU,
Untracked, Untracked,
}; };
/// Vector tracking modified pages tightly packed with small vector optimization using WordsArray = std::array<u64, NUM_REGION_WORDS>;
template <size_t stack_words = 1>
struct WordsArray {
/// Returns the pointer to the words state
[[nodiscard]] const u64* Pointer(bool is_short) const noexcept {
return is_short ? stack.data() : heap;
}
/// Returns the pointer to the words state /**
[[nodiscard]] u64* Pointer(bool is_short) noexcept { * Allows tracking CPU and GPU modification of pages in a contigious 4MB virtual address region.
return is_short ? stack.data() : heap; * Information is stored in bitsets for spacial locality and fast update of single pages.
} */
class RegionManager {
std::array<u64, stack_words> stack{}; ///< Small buffers storage
u64* heap; ///< Not-small buffers pointer to the storage
};
template <size_t stack_words = 1>
struct Words {
explicit Words() = default;
explicit Words(u64 size_bytes_) : size_bytes{size_bytes_} {
num_words = Common::DivCeil(size_bytes, BYTES_PER_WORD);
if (IsShort()) {
cpu.stack.fill(~u64{0});
gpu.stack.fill(0);
untracked.stack.fill(~u64{0});
} else {
// Share allocation between CPU and GPU pages and set their default values
u64* const alloc = new u64[num_words * 3];
cpu.heap = alloc;
gpu.heap = alloc + num_words;
untracked.heap = alloc + num_words * 2;
std::fill_n(cpu.heap, num_words, ~u64{0});
std::fill_n(gpu.heap, num_words, 0);
std::fill_n(untracked.heap, num_words, ~u64{0});
}
// Clean up tailing bits
const u64 last_word_size = size_bytes % BYTES_PER_WORD;
const u64 last_local_page = Common::DivCeil(last_word_size, BYTES_PER_PAGE);
const u64 shift = (PAGES_PER_WORD - last_local_page) % PAGES_PER_WORD;
const u64 last_word = (~u64{0} << shift) >> shift;
cpu.Pointer(IsShort())[NumWords() - 1] = last_word;
untracked.Pointer(IsShort())[NumWords() - 1] = last_word;
}
~Words() {
Release();
}
Words& operator=(Words&& rhs) noexcept {
Release();
size_bytes = rhs.size_bytes;
num_words = rhs.num_words;
cpu = rhs.cpu;
gpu = rhs.gpu;
untracked = rhs.untracked;
rhs.cpu.heap = nullptr;
return *this;
}
Words(Words&& rhs) noexcept
: size_bytes{rhs.size_bytes}, num_words{rhs.num_words}, cpu{rhs.cpu}, gpu{rhs.gpu},
untracked{rhs.untracked} {
rhs.cpu.heap = nullptr;
}
Words& operator=(const Words&) = delete;
Words(const Words&) = delete;
/// Returns true when the buffer fits in the small vector optimization
[[nodiscard]] bool IsShort() const noexcept {
return num_words <= stack_words;
}
/// Returns the number of words of the buffer
[[nodiscard]] size_t NumWords() const noexcept {
return num_words;
}
/// Release buffer resources
void Release() {
if (!IsShort()) {
// CPU written words is the base for the heap allocation
delete[] cpu.heap;
}
}
template <Type type>
std::span<u64> Span() noexcept {
if constexpr (type == Type::CPU) {
return std::span<u64>(cpu.Pointer(IsShort()), num_words);
} else if constexpr (type == Type::GPU) {
return std::span<u64>(gpu.Pointer(IsShort()), num_words);
} else if constexpr (type == Type::Untracked) {
return std::span<u64>(untracked.Pointer(IsShort()), num_words);
}
}
template <Type type>
std::span<const u64> Span() const noexcept {
if constexpr (type == Type::CPU) {
return std::span<const u64>(cpu.Pointer(IsShort()), num_words);
} else if constexpr (type == Type::GPU) {
return std::span<const u64>(gpu.Pointer(IsShort()), num_words);
} else if constexpr (type == Type::Untracked) {
return std::span<const u64>(untracked.Pointer(IsShort()), num_words);
}
}
u64 size_bytes = 0;
size_t num_words = 0;
WordsArray<stack_words> cpu;
WordsArray<stack_words> gpu;
WordsArray<stack_words> untracked;
};
template <size_t stack_words = 1>
class WordManager {
public: public:
explicit WordManager(PageManager* tracker_, VAddr cpu_addr_, u64 size_bytes) explicit RegionManager(PageManager* tracker_, VAddr cpu_addr_)
: tracker{tracker_}, cpu_addr{cpu_addr_}, words{size_bytes} {} : tracker{tracker_}, cpu_addr{cpu_addr_} {
cpu.fill(~u64{0});
explicit WordManager() = default; gpu.fill(0);
untracked.fill(~u64{0});
}
explicit RegionManager() = default;
void SetCpuAddress(VAddr new_cpu_addr) { void SetCpuAddress(VAddr new_cpu_addr) {
cpu_addr = new_cpu_addr; cpu_addr = new_cpu_addr;
@ -175,12 +74,12 @@ public:
static constexpr bool BOOL_BREAK = std::is_same_v<FuncReturn, bool>; static constexpr bool BOOL_BREAK = std::is_same_v<FuncReturn, bool>;
const size_t start = static_cast<size_t>(std::max<s64>(static_cast<s64>(offset), 0LL)); const size_t start = static_cast<size_t>(std::max<s64>(static_cast<s64>(offset), 0LL));
const size_t end = static_cast<size_t>(std::max<s64>(static_cast<s64>(offset + size), 0LL)); const size_t end = static_cast<size_t>(std::max<s64>(static_cast<s64>(offset + size), 0LL));
if (start >= SizeBytes() || end <= start) { if (start >= HIGHER_PAGE_SIZE || end <= start) {
return; return;
} }
auto [start_word, start_page] = GetWordPage(start); auto [start_word, start_page] = GetWordPage(start);
auto [end_word, end_page] = GetWordPage(end + BYTES_PER_PAGE - 1ULL); auto [end_word, end_page] = GetWordPage(end + BYTES_PER_PAGE - 1ULL);
const size_t num_words = NumWords(); constexpr size_t num_words = NUM_REGION_WORDS;
start_word = std::min(start_word, num_words); start_word = std::min(start_word, num_words);
end_word = std::min(end_word, num_words); end_word = std::min(end_word, num_words);
const size_t diff = end_word - start_word; const size_t diff = end_word - start_word;
@ -225,21 +124,21 @@ public:
*/ */
template <Type type, bool enable> template <Type type, bool enable>
void ChangeRegionState(u64 dirty_addr, u64 size) noexcept(type == Type::GPU) { void ChangeRegionState(u64 dirty_addr, u64 size) noexcept(type == Type::GPU) {
std::span<u64> state_words = words.template Span<type>(); std::scoped_lock lk{lock};
[[maybe_unused]] std::span<u64> untracked_words = words.template Span<Type::Untracked>(); std::span<u64> state_words = Span<type>();
IterateWords(dirty_addr - cpu_addr, size, [&](size_t index, u64 mask) { IterateWords(dirty_addr - cpu_addr, size, [&](size_t index, u64 mask) {
if constexpr (type == Type::CPU) { if constexpr (type == Type::CPU) {
NotifyPageTracker<!enable>(index, untracked_words[index], mask); UpdateProtection<!enable>(index, untracked[index], mask);
} }
if constexpr (enable) { if constexpr (enable) {
state_words[index] |= mask; state_words[index] |= mask;
if constexpr (type == Type::CPU) { if constexpr (type == Type::CPU) {
untracked_words[index] |= mask; untracked[index] |= mask;
} }
} else { } else {
state_words[index] &= ~mask; state_words[index] &= ~mask;
if constexpr (type == Type::CPU) { if constexpr (type == Type::CPU) {
untracked_words[index] &= ~mask; untracked[index] &= ~mask;
} }
} }
}); });
@ -255,10 +154,10 @@ public:
*/ */
template <Type type, bool clear, typename Func> template <Type type, bool clear, typename Func>
void ForEachModifiedRange(VAddr query_cpu_range, s64 size, Func&& func) { void ForEachModifiedRange(VAddr query_cpu_range, s64 size, Func&& func) {
std::scoped_lock lk{lock};
static_assert(type != Type::Untracked); static_assert(type != Type::Untracked);
std::span<u64> state_words = words.template Span<type>(); std::span<u64> state_words = Span<type>();
[[maybe_unused]] std::span<u64> untracked_words = words.template Span<Type::Untracked>();
const size_t offset = query_cpu_range - cpu_addr; const size_t offset = query_cpu_range - cpu_addr;
bool pending = false; bool pending = false;
size_t pending_offset{}; size_t pending_offset{};
@ -269,16 +168,16 @@ public:
}; };
IterateWords(offset, size, [&](size_t index, u64 mask) { IterateWords(offset, size, [&](size_t index, u64 mask) {
if constexpr (type == Type::GPU) { if constexpr (type == Type::GPU) {
mask &= ~untracked_words[index]; mask &= ~untracked[index];
} }
const u64 word = state_words[index] & mask; const u64 word = state_words[index] & mask;
if constexpr (clear) { if constexpr (clear) {
if constexpr (type == Type::CPU) { if constexpr (type == Type::CPU) {
NotifyPageTracker<true>(index, untracked_words[index], mask); UpdateProtection<true>(index, untracked[index], mask);
} }
state_words[index] &= ~mask; state_words[index] &= ~mask;
if constexpr (type == Type::CPU) { if constexpr (type == Type::CPU) {
untracked_words[index] &= ~mask; untracked[index] &= ~mask;
} }
} }
const size_t base_offset = index * PAGES_PER_WORD; const size_t base_offset = index * PAGES_PER_WORD;
@ -315,13 +214,11 @@ public:
[[nodiscard]] bool IsRegionModified(u64 offset, u64 size) const noexcept { [[nodiscard]] bool IsRegionModified(u64 offset, u64 size) const noexcept {
static_assert(type != Type::Untracked); static_assert(type != Type::Untracked);
const std::span<const u64> state_words = words.template Span<type>(); const std::span<const u64> state_words = Span<type>();
[[maybe_unused]] const std::span<const u64> untracked_words =
words.template Span<Type::Untracked>();
bool result = false; bool result = false;
IterateWords(offset, size, [&](size_t index, u64 mask) { IterateWords(offset, size, [&](size_t index, u64 mask) {
if constexpr (type == Type::GPU) { if constexpr (type == Type::GPU) {
mask &= ~untracked_words[index]; mask &= ~untracked[index];
} }
const u64 word = state_words[index] & mask; const u64 word = state_words[index] & mask;
if (word != 0) { if (word != 0) {
@ -333,44 +230,7 @@ public:
return result; return result;
} }
/// Returns the number of words of the manager
[[nodiscard]] size_t NumWords() const noexcept {
return words.NumWords();
}
/// Returns the size in bytes of the manager
[[nodiscard]] u64 SizeBytes() const noexcept {
return words.size_bytes;
}
/// Returns true when the buffer fits in the small vector optimization
[[nodiscard]] bool IsShort() const noexcept {
return words.IsShort();
}
private: private:
template <Type type>
u64* Array() noexcept {
if constexpr (type == Type::CPU) {
return words.cpu.Pointer(IsShort());
} else if constexpr (type == Type::GPU) {
return words.gpu.Pointer(IsShort());
} else if constexpr (type == Type::Untracked) {
return words.untracked.Pointer(IsShort());
}
}
template <Type type>
const u64* Array() const noexcept {
if constexpr (type == Type::CPU) {
return words.cpu.Pointer(IsShort());
} else if constexpr (type == Type::GPU) {
return words.gpu.Pointer(IsShort());
} else if constexpr (type == Type::Untracked) {
return words.untracked.Pointer(IsShort());
}
}
/** /**
* Notify tracker about changes in the CPU tracking state of a word in the buffer * Notify tracker about changes in the CPU tracking state of a word in the buffer
* *
@ -381,7 +241,7 @@ private:
* @tparam add_to_tracker True when the tracker should start tracking the new pages * @tparam add_to_tracker True when the tracker should start tracking the new pages
*/ */
template <bool add_to_tracker> template <bool add_to_tracker>
void NotifyPageTracker(u64 word_index, u64 current_bits, u64 new_bits) const { void UpdateProtection(u64 word_index, u64 current_bits, u64 new_bits) const {
u64 changed_bits = (add_to_tracker ? current_bits : ~current_bits) & new_bits; u64 changed_bits = (add_to_tracker ? current_bits : ~current_bits) & new_bits;
VAddr addr = cpu_addr + word_index * BYTES_PER_WORD; VAddr addr = cpu_addr + word_index * BYTES_PER_WORD;
IteratePages(changed_bits, [&](size_t offset, size_t size) { IteratePages(changed_bits, [&](size_t offset, size_t size) {
@ -390,9 +250,34 @@ private:
}); });
} }
template <Type type>
std::span<u64> Span() noexcept {
if constexpr (type == Type::CPU) {
return cpu;
} else if constexpr (type == Type::GPU) {
return gpu;
} else if constexpr (type == Type::Untracked) {
return untracked;
}
}
template <Type type>
std::span<const u64> Span() const noexcept {
if constexpr (type == Type::CPU) {
return cpu;
} else if constexpr (type == Type::GPU) {
return gpu;
} else if constexpr (type == Type::Untracked) {
return untracked;
}
}
Common::SpinLock lock;
PageManager* tracker; PageManager* tracker;
VAddr cpu_addr = 0; VAddr cpu_addr = 0;
Words<stack_words> words; WordsArray cpu;
WordsArray gpu;
WordsArray untracked;
}; };
} // namespace VideoCore } // namespace VideoCore

View File

@ -39,6 +39,15 @@ public:
return &(*first_level_map[l1_page])[l2_page]; return &(*first_level_map[l1_page])[l2_page];
} }
[[nodiscard]] const Entry* find(size_t page) const {
const size_t l1_page = page >> SecondLevelBits;
const size_t l2_page = page & (NumEntriesPerL1Page - 1);
if (!first_level_map[l1_page]) {
return nullptr;
}
return &(*first_level_map[l1_page])[l2_page];
}
[[nodiscard]] const Entry& operator[](size_t page) const { [[nodiscard]] const Entry& operator[](size_t page) const {
const size_t l1_page = page >> SecondLevelBits; const size_t l1_page = page >> SecondLevelBits;
const size_t l2_page = page & (NumEntriesPerL1Page - 1); const size_t l2_page = page & (NumEntriesPerL1Page - 1);

View File

@ -185,7 +185,7 @@ void PageManager::OnGpuUnmap(VAddr address, size_t size) {
void PageManager::UpdatePagesCachedCount(VAddr addr, u64 size, s32 delta) { void PageManager::UpdatePagesCachedCount(VAddr addr, u64 size, s32 delta) {
static constexpr u64 PageShift = 12; static constexpr u64 PageShift = 12;
std::scoped_lock lk{mutex}; std::scoped_lock lk{lock};
const u64 num_pages = ((addr + size - 1) >> PageShift) - (addr >> PageShift) + 1; const u64 num_pages = ((addr + size - 1) >> PageShift) - (addr >> PageShift) + 1;
const u64 page_start = addr >> PageShift; const u64 page_start = addr >> PageShift;
const u64 page_end = page_start + num_pages; const u64 page_end = page_start + num_pages;

View File

@ -4,8 +4,8 @@
#pragma once #pragma once
#include <memory> #include <memory>
#include <mutex>
#include <boost/icl/interval_map.hpp> #include <boost/icl/interval_map.hpp>
#include "common/spin_lock.h"
#include "common/types.h" #include "common/types.h"
namespace Vulkan { namespace Vulkan {
@ -35,8 +35,8 @@ private:
struct Impl; struct Impl;
std::unique_ptr<Impl> impl; std::unique_ptr<Impl> impl;
Vulkan::Rasterizer* rasterizer; Vulkan::Rasterizer* rasterizer;
std::mutex mutex;
boost::icl::interval_map<VAddr, s32> cached_pages; boost::icl::interval_map<VAddr, s32> cached_pages;
Common::SpinLock lock;
}; };
} // namespace VideoCore } // namespace VideoCore

View File

@ -691,16 +691,40 @@ std::span<const SurfaceFormatInfo> SurfaceFormats() {
return formats; return formats;
} }
// Table 8.13 Data and Image Formats [Sea Islands Series Instruction Set Architecture]
static const size_t amd_gpu_data_format_bit_size = 6; // All values are under 64
static const size_t amd_gpu_number_format_bit_size = 4; // All values are under 16
static size_t GetSurfaceFormatTableIndex(AmdGpu::DataFormat data_format,
AmdGpu::NumberFormat num_format) {
DEBUG_ASSERT(data_format < 1 << amd_gpu_data_format_bit_size);
DEBUG_ASSERT(num_format < 1 << amd_gpu_number_format_bit_size);
size_t result = static_cast<size_t>(num_format) |
(static_cast<size_t>(data_format) << amd_gpu_number_format_bit_size);
return result;
}
static auto surface_format_table = []() constexpr {
std::array<vk::Format, 1 << amd_gpu_data_format_bit_size * 1 << amd_gpu_number_format_bit_size>
result;
for (auto& entry : result) {
entry = vk::Format::eUndefined;
}
for (const auto& supported_format : SurfaceFormats()) {
result[GetSurfaceFormatTableIndex(supported_format.data_format,
supported_format.number_format)] =
supported_format.vk_format;
}
return result;
}();
vk::Format SurfaceFormat(AmdGpu::DataFormat data_format, AmdGpu::NumberFormat num_format) { vk::Format SurfaceFormat(AmdGpu::DataFormat data_format, AmdGpu::NumberFormat num_format) {
const auto& formats = SurfaceFormats(); vk::Format result = surface_format_table[GetSurfaceFormatTableIndex(data_format, num_format)];
const auto format = bool found =
std::find_if(formats.begin(), formats.end(), [&](const SurfaceFormatInfo& format_info) { result != vk::Format::eUndefined || data_format == AmdGpu::DataFormat::FormatInvalid;
return format_info.data_format == data_format && ASSERT_MSG(found, "Unknown data_format={} and num_format={}", static_cast<u32>(data_format),
format_info.number_format == num_format; static_cast<u32>(num_format));
}); return result;
ASSERT_MSG(format != formats.end(), "Unknown data_format={} and num_format={}",
static_cast<u32>(data_format), static_cast<u32>(num_format));
return format->vk_format;
} }
static constexpr DepthFormatInfo CreateDepthFormatInfo( static constexpr DepthFormatInfo CreateDepthFormatInfo(
@ -746,8 +770,8 @@ vk::Format DepthFormat(DepthBuffer::ZFormat z_format, DepthBuffer::StencilFormat
vk::ClearValue ColorBufferClearValue(const AmdGpu::Liverpool::ColorBuffer& color_buffer) { vk::ClearValue ColorBufferClearValue(const AmdGpu::Liverpool::ColorBuffer& color_buffer) {
const auto comp_swizzle = color_buffer.Swizzle(); const auto comp_swizzle = color_buffer.Swizzle();
const auto format = color_buffer.DataFormat(); const auto format = color_buffer.GetDataFmt();
const auto number_type = color_buffer.NumFormat(); const auto number_type = color_buffer.GetNumberFmt();
const auto& c0 = color_buffer.clear_word0; const auto& c0 = color_buffer.clear_word0;
const auto& c1 = color_buffer.clear_word1; const auto& c1 = color_buffer.clear_word1;

View File

@ -328,8 +328,8 @@ bool PipelineCache::RefreshGraphicsKey() {
} }
key.color_formats[remapped_cb] = key.color_formats[remapped_cb] =
LiverpoolToVK::SurfaceFormat(col_buf.DataFormat(), col_buf.NumFormat()); LiverpoolToVK::SurfaceFormat(col_buf.GetDataFmt(), col_buf.GetNumberFmt());
key.color_num_formats[remapped_cb] = col_buf.NumFormat(); key.color_num_formats[remapped_cb] = col_buf.GetNumberFmt();
key.color_swizzles[remapped_cb] = col_buf.Swizzle(); key.color_swizzles[remapped_cb] = col_buf.Swizzle();
} }

View File

@ -265,9 +265,9 @@ ImageInfo::ImageInfo(const AmdGpu::Liverpool::ColorBuffer& buffer,
const AmdGpu::Liverpool::CbDbExtent& hint /*= {}*/) noexcept { const AmdGpu::Liverpool::CbDbExtent& hint /*= {}*/) noexcept {
props.is_tiled = buffer.IsTiled(); props.is_tiled = buffer.IsTiled();
tiling_mode = buffer.GetTilingMode(); tiling_mode = buffer.GetTilingMode();
pixel_format = LiverpoolToVK::SurfaceFormat(buffer.DataFormat(), buffer.NumFormat()); pixel_format = LiverpoolToVK::SurfaceFormat(buffer.GetDataFmt(), buffer.GetNumberFmt());
num_samples = buffer.NumSamples(); num_samples = buffer.NumSamples();
num_bits = NumBits(buffer.DataFormat()); num_bits = NumBits(buffer.GetDataFmt());
type = vk::ImageType::e2D; type = vk::ImageType::e2D;
size.width = hint.Valid() ? hint.width : buffer.Pitch(); size.width = hint.Valid() ? hint.width : buffer.Pitch();
size.height = hint.Valid() ? hint.height : buffer.Height(); size.height = hint.Valid() ? hint.height : buffer.Height();

View File

@ -76,7 +76,8 @@ ImageViewInfo::ImageViewInfo(const AmdGpu::Liverpool::ColorBuffer& col_buffer) n
range.base.layer = col_buffer.view.slice_start; range.base.layer = col_buffer.view.slice_start;
range.extent.layers = col_buffer.NumSlices() - range.base.layer; range.extent.layers = col_buffer.NumSlices() - range.base.layer;
type = range.extent.layers > 1 ? vk::ImageViewType::e2DArray : vk::ImageViewType::e2D; type = range.extent.layers > 1 ? vk::ImageViewType::e2DArray : vk::ImageViewType::e2D;
format = Vulkan::LiverpoolToVK::SurfaceFormat(col_buffer.DataFormat(), col_buffer.NumFormat()); format =
Vulkan::LiverpoolToVK::SurfaceFormat(col_buffer.GetDataFmt(), col_buffer.GetNumberFmt());
} }
ImageViewInfo::ImageViewInfo(const AmdGpu::Liverpool::DepthBuffer& depth_buffer, ImageViewInfo::ImageViewInfo(const AmdGpu::Liverpool::DepthBuffer& depth_buffer,

View File

@ -32,6 +32,7 @@ static vk::Format DemoteImageFormatForDetiling(vk::Format format) {
case vk::Format::eR5G5B5A1UnormPack16: case vk::Format::eR5G5B5A1UnormPack16:
case vk::Format::eR8G8Unorm: case vk::Format::eR8G8Unorm:
case vk::Format::eR16Sfloat: case vk::Format::eR16Sfloat:
case vk::Format::eR16Uint:
case vk::Format::eR16Unorm: case vk::Format::eR16Unorm:
case vk::Format::eD16Unorm: case vk::Format::eD16Unorm:
return vk::Format::eR8G8Uint; return vk::Format::eR8G8Uint;