summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/core/hle/kernel/hle_ipc.cpp7
-rw-r--r--src/core/hle/kernel/hle_ipc.h8
-rw-r--r--src/core/hle/kernel/server_session.cpp2
-rw-r--r--src/core/hle/service/vi/vi.cpp2
-rw-r--r--src/video_core/engines/shader_bytecode.h20
-rw-r--r--src/video_core/renderer_opengl/gl_rasterizer.cpp8
-rw-r--r--src/video_core/renderer_opengl/gl_rasterizer.h3
-rw-r--r--src/video_core/renderer_opengl/gl_shader_cache.cpp117
-rw-r--r--src/video_core/renderer_opengl/gl_shader_cache.h14
-rw-r--r--src/video_core/renderer_opengl/gl_shader_disk_cache.cpp8
-rw-r--r--src/video_core/renderer_opengl/gl_shader_disk_cache.h7
-rw-r--r--src/video_core/renderer_opengl/renderer_opengl.cpp6
-rw-r--r--src/video_core/renderer_opengl/renderer_opengl.h3
-rw-r--r--src/video_core/shader/decode/arithmetic.cpp3
-rw-r--r--src/video_core/shader/decode/arithmetic_half.cpp1
-rw-r--r--src/video_core/shader/decode/arithmetic_half_immediate.cpp3
-rw-r--r--src/video_core/shader/decode/arithmetic_immediate.cpp2
-rw-r--r--src/video_core/shader/decode/arithmetic_integer_immediate.cpp2
-rw-r--r--src/video_core/shader/decode/bfe.cpp2
-rw-r--r--src/video_core/shader/decode/bfi.cpp2
-rw-r--r--src/video_core/shader/decode/ffma.cpp2
-rw-r--r--src/video_core/shader/decode/float_set.cpp2
-rw-r--r--src/video_core/shader/decode/float_set_predicate.cpp2
-rw-r--r--src/video_core/shader/decode/half_set.cpp3
-rw-r--r--src/video_core/shader/decode/half_set_predicate.cpp2
-rw-r--r--src/video_core/shader/decode/integer_set.cpp3
-rw-r--r--src/video_core/shader/decode/integer_set_predicate.cpp2
-rw-r--r--src/video_core/shader/decode/memory.cpp82
-rw-r--r--src/video_core/shader/decode/other.cpp1
-rw-r--r--src/video_core/shader/decode/predicate_set_predicate.cpp2
-rw-r--r--src/video_core/shader/decode/predicate_set_register.cpp2
-rw-r--r--src/video_core/shader/decode/register_set_predicate.cpp2
-rw-r--r--src/video_core/shader/decode/shift.cpp2
-rw-r--r--src/video_core/shader/decode/video.cpp2
-rw-r--r--src/video_core/shader/shader_ir.cpp4
-rw-r--r--src/video_core/shader/shader_ir.h8
-rw-r--r--src/yuzu/CMakeLists.txt4
-rw-r--r--src/yuzu/applets/error.cpp6
-rw-r--r--src/yuzu/applets/software_keyboard.cpp23
-rw-r--r--src/yuzu/applets/software_keyboard.h1
-rw-r--r--src/yuzu/bootmanager.cpp18
-rw-r--r--src/yuzu/configuration/config.cpp73
-rw-r--r--src/yuzu/configuration/config.h3
-rw-r--r--src/yuzu/configuration/configure_dialog.cpp3
-rw-r--r--src/yuzu/configuration/configure_hotkeys.cpp38
-rw-r--r--src/yuzu/configuration/configure_hotkeys.h6
-rw-r--r--src/yuzu/main.cpp260
-rw-r--r--src/yuzu/util/sequence_dialog/sequence_dialog.cpp13
48 files changed, 467 insertions, 322 deletions
diff --git a/src/core/hle/kernel/hle_ipc.cpp b/src/core/hle/kernel/hle_ipc.cpp
index 42d9dd844..f3da525d6 100644
--- a/src/core/hle/kernel/hle_ipc.cpp
+++ b/src/core/hle/kernel/hle_ipc.cpp
@@ -43,7 +43,7 @@ void SessionRequestHandler::ClientDisconnected(const SharedPtr<ServerSession>& s
}
SharedPtr<WritableEvent> HLERequestContext::SleepClientThread(
- SharedPtr<Thread> thread, const std::string& reason, u64 timeout, WakeupCallback&& callback,
+ const std::string& reason, u64 timeout, WakeupCallback&& callback,
SharedPtr<WritableEvent> writable_event) {
// Put the client thread to sleep until the wait event is signaled or the timeout expires.
thread->SetWakeupCallback([context = *this, callback](
@@ -76,8 +76,9 @@ SharedPtr<WritableEvent> HLERequestContext::SleepClientThread(
return writable_event;
}
-HLERequestContext::HLERequestContext(SharedPtr<Kernel::ServerSession> server_session)
- : server_session(std::move(server_session)) {
+HLERequestContext::HLERequestContext(SharedPtr<Kernel::ServerSession> server_session,
+ SharedPtr<Thread> thread)
+ : server_session(std::move(server_session)), thread(std::move(thread)) {
cmd_buf[0] = 0;
}
diff --git a/src/core/hle/kernel/hle_ipc.h b/src/core/hle/kernel/hle_ipc.h
index 2bdd9f02c..ccf5e56aa 100644
--- a/src/core/hle/kernel/hle_ipc.h
+++ b/src/core/hle/kernel/hle_ipc.h
@@ -97,7 +97,7 @@ protected:
*/
class HLERequestContext {
public:
- explicit HLERequestContext(SharedPtr<ServerSession> session);
+ explicit HLERequestContext(SharedPtr<ServerSession> session, SharedPtr<Thread> thread);
~HLERequestContext();
/// Returns a pointer to the IPC command buffer for this request.
@@ -119,7 +119,6 @@ public:
/**
* Puts the specified guest thread to sleep until the returned event is signaled or until the
* specified timeout expires.
- * @param thread Thread to be put to sleep.
* @param reason Reason for pausing the thread, to be used for debugging purposes.
* @param timeout Timeout in nanoseconds after which the thread will be awoken and the callback
* invoked with a Timeout reason.
@@ -130,8 +129,8 @@ public:
* created.
* @returns Event that when signaled will resume the thread and call the callback function.
*/
- SharedPtr<WritableEvent> SleepClientThread(SharedPtr<Thread> thread, const std::string& reason,
- u64 timeout, WakeupCallback&& callback,
+ SharedPtr<WritableEvent> SleepClientThread(const std::string& reason, u64 timeout,
+ WakeupCallback&& callback,
SharedPtr<WritableEvent> writable_event = nullptr);
/// Populates this context with data from the requesting process/thread.
@@ -268,6 +267,7 @@ private:
std::array<u32, IPC::COMMAND_BUFFER_LENGTH> cmd_buf;
SharedPtr<Kernel::ServerSession> server_session;
+ SharedPtr<Thread> thread;
// TODO(yuriks): Check common usage of this and optimize size accordingly
boost::container::small_vector<SharedPtr<Object>, 8> move_objects;
boost::container::small_vector<SharedPtr<Object>, 8> copy_objects;
diff --git a/src/core/hle/kernel/server_session.cpp b/src/core/hle/kernel/server_session.cpp
index 696a82cd9..30b2bfb5a 100644
--- a/src/core/hle/kernel/server_session.cpp
+++ b/src/core/hle/kernel/server_session.cpp
@@ -130,7 +130,7 @@ ResultCode ServerSession::HandleSyncRequest(SharedPtr<Thread> thread) {
// The ServerSession received a sync request, this means that there's new data available
// from its ClientSession, so wake up any threads that may be waiting on a svcReplyAndReceive or
// similar.
- Kernel::HLERequestContext context(this);
+ Kernel::HLERequestContext context(this, thread);
u32* cmd_buf = (u32*)Memory::GetPointer(thread->GetTLSAddress());
context.PopulateFromIncomingCommandBuffer(kernel.CurrentProcess()->GetHandleTable(), cmd_buf);
diff --git a/src/core/hle/service/vi/vi.cpp b/src/core/hle/service/vi/vi.cpp
index 4e17249a9..f1fa6ccd1 100644
--- a/src/core/hle/service/vi/vi.cpp
+++ b/src/core/hle/service/vi/vi.cpp
@@ -556,7 +556,7 @@ private:
} else {
// Wait the current thread until a buffer becomes available
ctx.SleepClientThread(
- Kernel::GetCurrentThread(), "IHOSBinderDriver::DequeueBuffer", -1,
+ "IHOSBinderDriver::DequeueBuffer", -1,
[=](Kernel::SharedPtr<Kernel::Thread> thread, Kernel::HLERequestContext& ctx,
Kernel::ThreadWakeupReason reason) {
// Repeat TransactParcel DequeueBuffer when a buffer is available
diff --git a/src/video_core/engines/shader_bytecode.h b/src/video_core/engines/shader_bytecode.h
index 7bbc556da..e83f25fa1 100644
--- a/src/video_core/engines/shader_bytecode.h
+++ b/src/video_core/engines/shader_bytecode.h
@@ -530,6 +530,11 @@ union Instruction {
BitField<48, 16, u64> opcode;
union {
+ BitField<8, 8, Register> gpr;
+ BitField<20, 24, s64> offset;
+ } gmem;
+
+ union {
BitField<20, 16, u64> imm20_16;
BitField<20, 19, u64> imm20_19;
BitField<20, 32, s64> imm20_32;
@@ -812,13 +817,11 @@ union Instruction {
union {
BitField<48, 3, UniformType> type;
BitField<46, 2, u64> cache_mode;
- BitField<20, 24, s64> immediate_offset;
} ldg;
union {
BitField<48, 3, UniformType> type;
BitField<46, 2, u64> cache_mode;
- BitField<20, 24, s64> immediate_offset;
} stg;
union {
@@ -828,6 +831,11 @@ union Instruction {
} al2p;
union {
+ BitField<53, 3, UniformType> type;
+ BitField<52, 1, u64> extended;
+ } generic;
+
+ union {
BitField<0, 3, u64> pred0;
BitField<3, 3, u64> pred3;
BitField<7, 1, u64> abs_a;
@@ -1387,10 +1395,12 @@ public:
LD_L,
LD_S,
LD_C,
+ LD, // Load from generic memory
+ LDG, // Load from global memory
ST_A,
ST_L,
ST_S,
- LDG, // Load from global memory
+ ST, // Store in generic memory
STG, // Store in global memory
AL2P, // Transforms attribute memory into physical memory
TEX,
@@ -1658,10 +1668,12 @@ private:
INST("1110111101001---", Id::LD_S, Type::Memory, "LD_S"),
INST("1110111101000---", Id::LD_L, Type::Memory, "LD_L"),
INST("1110111110010---", Id::LD_C, Type::Memory, "LD_C"),
+ INST("100-------------", Id::LD, Type::Memory, "LD"),
+ INST("1110111011010---", Id::LDG, Type::Memory, "LDG"),
INST("1110111111110---", Id::ST_A, Type::Memory, "ST_A"),
INST("1110111101011---", Id::ST_S, Type::Memory, "ST_S"),
INST("1110111101010---", Id::ST_L, Type::Memory, "ST_L"),
- INST("1110111011010---", Id::LDG, Type::Memory, "LDG"),
+ INST("101-------------", Id::ST, Type::Memory, "ST"),
INST("1110111011011---", Id::STG, Type::Memory, "STG"),
INST("1110111110100---", Id::AL2P, Type::Memory, "AL2P"),
INST("110000----111---", Id::TEX, Type::Texture, "TEX"),
diff --git a/src/video_core/renderer_opengl/gl_rasterizer.cpp b/src/video_core/renderer_opengl/gl_rasterizer.cpp
index dbd8049f5..f9b6dfeea 100644
--- a/src/video_core/renderer_opengl/gl_rasterizer.cpp
+++ b/src/video_core/renderer_opengl/gl_rasterizer.cpp
@@ -98,9 +98,11 @@ struct FramebufferCacheKey {
}
};
-RasterizerOpenGL::RasterizerOpenGL(Core::System& system, ScreenInfo& info)
- : res_cache{*this}, shader_cache{*this, system, device}, global_cache{*this}, system{system},
- screen_info{info}, buffer_cache(*this, STREAM_BUFFER_SIZE) {
+RasterizerOpenGL::RasterizerOpenGL(Core::System& system, Core::Frontend::EmuWindow& emu_window,
+ ScreenInfo& info)
+ : res_cache{*this}, shader_cache{*this, system, emu_window, device},
+ global_cache{*this}, system{system}, screen_info{info},
+ buffer_cache(*this, STREAM_BUFFER_SIZE) {
OpenGLState::ApplyDefaultState();
shader_program_manager = std::make_unique<GLShader::ProgramManager>();
diff --git a/src/video_core/renderer_opengl/gl_rasterizer.h b/src/video_core/renderer_opengl/gl_rasterizer.h
index 71b9c5ead..d78094138 100644
--- a/src/video_core/renderer_opengl/gl_rasterizer.h
+++ b/src/video_core/renderer_opengl/gl_rasterizer.h
@@ -48,7 +48,8 @@ struct FramebufferCacheKey;
class RasterizerOpenGL : public VideoCore::RasterizerInterface {
public:
- explicit RasterizerOpenGL(Core::System& system, ScreenInfo& info);
+ explicit RasterizerOpenGL(Core::System& system, Core::Frontend::EmuWindow& emu_window,
+ ScreenInfo& info);
~RasterizerOpenGL() override;
void DrawArrays() override;
diff --git a/src/video_core/renderer_opengl/gl_shader_cache.cpp b/src/video_core/renderer_opengl/gl_shader_cache.cpp
index f700dc89a..7ee1c99c0 100644
--- a/src/video_core/renderer_opengl/gl_shader_cache.cpp
+++ b/src/video_core/renderer_opengl/gl_shader_cache.cpp
@@ -2,10 +2,14 @@
// Licensed under GPLv2 or any later version
// Refer to the license.txt file included.
+#include <mutex>
+#include <thread>
#include <boost/functional/hash.hpp>
#include "common/assert.h"
#include "common/hash.h"
+#include "common/scope_exit.h"
#include "core/core.h"
+#include "core/frontend/emu_window.h"
#include "video_core/engines/maxwell_3d.h"
#include "video_core/memory_manager.h"
#include "video_core/renderer_opengl/gl_rasterizer.h"
@@ -344,8 +348,8 @@ ShaderDiskCacheUsage CachedShader::GetUsage(GLenum primitive_mode,
}
ShaderCacheOpenGL::ShaderCacheOpenGL(RasterizerOpenGL& rasterizer, Core::System& system,
- const Device& device)
- : RasterizerCache{rasterizer}, device{device}, disk_cache{system} {}
+ Core::Frontend::EmuWindow& emu_window, const Device& device)
+ : RasterizerCache{rasterizer}, emu_window{emu_window}, device{device}, disk_cache{system} {}
void ShaderCacheOpenGL::LoadDiskCache(const std::atomic_bool& stop_loading,
const VideoCore::DiskResourceLoadCallback& callback) {
@@ -353,62 +357,107 @@ void ShaderCacheOpenGL::LoadDiskCache(const std::atomic_bool& stop_loading,
if (!transferable) {
return;
}
- const auto [raws, usages] = *transferable;
+ const auto [raws, shader_usages] = *transferable;
auto [decompiled, dumps] = disk_cache.LoadPrecompiled();
const auto supported_formats{GetSupportedFormats()};
- const auto unspecialized{
+ const auto unspecialized_shaders{
GenerateUnspecializedShaders(stop_loading, callback, raws, decompiled)};
- if (stop_loading)
+ if (stop_loading) {
return;
+ }
// Track if precompiled cache was altered during loading to know if we have to serialize the
// virtual precompiled cache file back to the hard drive
bool precompiled_cache_altered = false;
- // Build shaders
- if (callback)
- callback(VideoCore::LoadCallbackStage::Build, 0, usages.size());
- for (std::size_t i = 0; i < usages.size(); ++i) {
- if (stop_loading)
- return;
+ // Inform the frontend about shader build initialization
+ if (callback) {
+ callback(VideoCore::LoadCallbackStage::Build, 0, shader_usages.size());
+ }
- const auto& usage{usages[i]};
- LOG_INFO(Render_OpenGL, "Building shader {:016x} ({} of {})", usage.unique_identifier,
- i + 1, usages.size());
+ std::mutex mutex;
+ std::size_t built_shaders = 0; // It doesn't have be atomic since it's used behind a mutex
+ std::atomic_bool compilation_failed = false;
- const auto& unspec{unspecialized.at(usage.unique_identifier)};
- const auto dump_it = dumps.find(usage);
+ const auto Worker = [&](Core::Frontend::GraphicsContext* context, std::size_t begin,
+ std::size_t end, const std::vector<ShaderDiskCacheUsage>& shader_usages,
+ const ShaderDumpsMap& dumps) {
+ context->MakeCurrent();
+ SCOPE_EXIT({ return context->DoneCurrent(); });
- CachedProgram shader;
- if (dump_it != dumps.end()) {
- // If the shader is dumped, attempt to load it with
- shader = GeneratePrecompiledProgram(dump_it->second, supported_formats);
+ for (std::size_t i = begin; i < end; ++i) {
+ if (stop_loading || compilation_failed) {
+ return;
+ }
+ const auto& usage{shader_usages[i]};
+ LOG_INFO(Render_OpenGL, "Building shader {:016x} (index {} of {})",
+ usage.unique_identifier, i, shader_usages.size());
+
+ const auto& unspecialized{unspecialized_shaders.at(usage.unique_identifier)};
+ const auto dump{dumps.find(usage)};
+
+ CachedProgram shader;
+ if (dump != dumps.end()) {
+ // If the shader is dumped, attempt to load it with
+ shader = GeneratePrecompiledProgram(dump->second, supported_formats);
+ if (!shader) {
+ compilation_failed = true;
+ return;
+ }
+ }
if (!shader) {
- // Invalidate the precompiled cache if a shader dumped shader was rejected
- disk_cache.InvalidatePrecompiled();
- precompiled_cache_altered = true;
- dumps.clear();
+ shader = SpecializeShader(unspecialized.code, unspecialized.entries,
+ unspecialized.program_type, usage.bindings,
+ usage.primitive, true);
}
+
+ std::scoped_lock lock(mutex);
+ if (callback) {
+ callback(VideoCore::LoadCallbackStage::Build, ++built_shaders,
+ shader_usages.size());
+ }
+
+ precompiled_programs.emplace(usage, std::move(shader));
}
- if (!shader) {
- shader = SpecializeShader(unspec.code, unspec.entries, unspec.program_type,
- usage.bindings, usage.primitive, true);
- }
- precompiled_programs.insert({usage, std::move(shader)});
+ };
+
+ const auto num_workers{static_cast<std::size_t>(std::thread::hardware_concurrency() + 1)};
+ const std::size_t bucket_size{shader_usages.size() / num_workers};
+ std::vector<std::unique_ptr<Core::Frontend::GraphicsContext>> contexts(num_workers);
+ std::vector<std::thread> threads(num_workers);
+ for (std::size_t i = 0; i < num_workers; ++i) {
+ const bool is_last_worker = i + 1 == num_workers;
+ const std::size_t start{bucket_size * i};
+ const std::size_t end{is_last_worker ? shader_usages.size() : start + bucket_size};
+
+ // On some platforms the shared context has to be created from the GUI thread
+ contexts[i] = emu_window.CreateSharedContext();
+ threads[i] = std::thread(Worker, contexts[i].get(), start, end, shader_usages, dumps);
+ }
+ for (auto& thread : threads) {
+ thread.join();
+ }
- if (callback)
- callback(VideoCore::LoadCallbackStage::Build, i + 1, usages.size());
+ if (compilation_failed) {
+ // Invalidate the precompiled cache if a shader dumped shader was rejected
+ disk_cache.InvalidatePrecompiled();
+ dumps.clear();
+ precompiled_cache_altered = true;
+ return;
+ }
+ if (stop_loading) {
+ return;
}
// TODO(Rodrigo): Do state tracking for transferable shaders and do a dummy draw before
// precompiling them
- for (std::size_t i = 0; i < usages.size(); ++i) {
- const auto& usage{usages[i]};
+ for (std::size_t i = 0; i < shader_usages.size(); ++i) {
+ const auto& usage{shader_usages[i]};
if (dumps.find(usage) == dumps.end()) {
- const auto& program = precompiled_programs.at(usage);
+ const auto& program{precompiled_programs.at(usage)};
disk_cache.SaveDump(usage, program->handle);
precompiled_cache_altered = true;
}
diff --git a/src/video_core/renderer_opengl/gl_shader_cache.h b/src/video_core/renderer_opengl/gl_shader_cache.h
index 31b979987..64e5a5594 100644
--- a/src/video_core/renderer_opengl/gl_shader_cache.h
+++ b/src/video_core/renderer_opengl/gl_shader_cache.h
@@ -22,7 +22,11 @@
namespace Core {
class System;
-} // namespace Core
+}
+
+namespace Core::Frontend {
+class EmuWindow;
+}
namespace OpenGL {
@@ -111,7 +115,7 @@ private:
class ShaderCacheOpenGL final : public RasterizerCache<Shader> {
public:
explicit ShaderCacheOpenGL(RasterizerOpenGL& rasterizer, Core::System& system,
- const Device& device);
+ Core::Frontend::EmuWindow& emu_window, const Device& device);
/// Loads disk cache for the current game
void LoadDiskCache(const std::atomic_bool& stop_loading,
@@ -133,13 +137,13 @@ private:
CachedProgram GeneratePrecompiledProgram(const ShaderDiskCacheDump& dump,
const std::set<GLenum>& supported_formats);
+ Core::Frontend::EmuWindow& emu_window;
const Device& device;
-
- std::array<Shader, Maxwell::MaxShaderProgram> last_shaders;
-
ShaderDiskCacheOpenGL disk_cache;
+
PrecompiledShaders precompiled_shaders;
PrecompiledPrograms precompiled_programs;
+ std::array<Shader, Maxwell::MaxShaderProgram> last_shaders;
};
} // namespace OpenGL
diff --git a/src/video_core/renderer_opengl/gl_shader_disk_cache.cpp b/src/video_core/renderer_opengl/gl_shader_disk_cache.cpp
index fba9c594a..ee4a45ca2 100644
--- a/src/video_core/renderer_opengl/gl_shader_disk_cache.cpp
+++ b/src/video_core/renderer_opengl/gl_shader_disk_cache.cpp
@@ -183,8 +183,7 @@ ShaderDiskCacheOpenGL::LoadTransferable() {
return {{raws, usages}};
}
-std::pair<std::unordered_map<u64, ShaderDiskCacheDecompiled>,
- std::unordered_map<ShaderDiskCacheUsage, ShaderDiskCacheDump>>
+std::pair<std::unordered_map<u64, ShaderDiskCacheDecompiled>, ShaderDumpsMap>
ShaderDiskCacheOpenGL::LoadPrecompiled() {
if (!IsUsable())
return {};
@@ -208,8 +207,7 @@ ShaderDiskCacheOpenGL::LoadPrecompiled() {
return *result;
}
-std::optional<std::pair<std::unordered_map<u64, ShaderDiskCacheDecompiled>,
- std::unordered_map<ShaderDiskCacheUsage, ShaderDiskCacheDump>>>
+std::optional<std::pair<std::unordered_map<u64, ShaderDiskCacheDecompiled>, ShaderDumpsMap>>
ShaderDiskCacheOpenGL::LoadPrecompiledFile(FileUtil::IOFile& file) {
// Read compressed file from disk and decompress to virtual precompiled cache file
std::vector<u8> compressed(file.GetSize());
@@ -230,7 +228,7 @@ ShaderDiskCacheOpenGL::LoadPrecompiledFile(FileUtil::IOFile& file) {
}
std::unordered_map<u64, ShaderDiskCacheDecompiled> decompiled;
- std::unordered_map<ShaderDiskCacheUsage, ShaderDiskCacheDump> dumps;
+ ShaderDumpsMap dumps;
while (precompiled_cache_virtual_file_offset < precompiled_cache_virtual_file.GetSize()) {
PrecompiledEntryKind kind{};
if (!LoadObjectFromPrecompiled(kind)) {
diff --git a/src/video_core/renderer_opengl/gl_shader_disk_cache.h b/src/video_core/renderer_opengl/gl_shader_disk_cache.h
index 2da0a4a23..ecd72ba58 100644
--- a/src/video_core/renderer_opengl/gl_shader_disk_cache.h
+++ b/src/video_core/renderer_opengl/gl_shader_disk_cache.h
@@ -33,6 +33,11 @@ namespace OpenGL {
using ProgramCode = std::vector<u64>;
using Maxwell = Tegra::Engines::Maxwell3D::Regs;
+struct ShaderDiskCacheUsage;
+struct ShaderDiskCacheDump;
+
+using ShaderDumpsMap = std::unordered_map<ShaderDiskCacheUsage, ShaderDiskCacheDump>;
+
/// Allocated bindings used by an OpenGL shader program
struct BaseBindings {
u32 cbuf{};
@@ -294,4 +299,4 @@ private:
bool tried_to_load{};
};
-} // namespace OpenGL \ No newline at end of file
+} // namespace OpenGL
diff --git a/src/video_core/renderer_opengl/renderer_opengl.cpp b/src/video_core/renderer_opengl/renderer_opengl.cpp
index d69cba9c3..3451d321d 100644
--- a/src/video_core/renderer_opengl/renderer_opengl.cpp
+++ b/src/video_core/renderer_opengl/renderer_opengl.cpp
@@ -97,8 +97,8 @@ static std::array<GLfloat, 3 * 2> MakeOrthographicMatrix(const float width, cons
return matrix;
}
-RendererOpenGL::RendererOpenGL(Core::Frontend::EmuWindow& window, Core::System& system)
- : VideoCore::RendererBase{window}, system{system} {}
+RendererOpenGL::RendererOpenGL(Core::Frontend::EmuWindow& emu_window, Core::System& system)
+ : VideoCore::RendererBase{emu_window}, emu_window{emu_window}, system{system} {}
RendererOpenGL::~RendererOpenGL() = default;
@@ -265,7 +265,7 @@ void RendererOpenGL::CreateRasterizer() {
}
// Initialize sRGB Usage
OpenGLState::ClearsRGBUsed();
- rasterizer = std::make_unique<RasterizerOpenGL>(system, screen_info);
+ rasterizer = std::make_unique<RasterizerOpenGL>(system, emu_window, screen_info);
}
void RendererOpenGL::ConfigureFramebufferTexture(TextureInfo& texture,
diff --git a/src/video_core/renderer_opengl/renderer_opengl.h b/src/video_core/renderer_opengl/renderer_opengl.h
index 6cbf9d2cb..4aebf2321 100644
--- a/src/video_core/renderer_opengl/renderer_opengl.h
+++ b/src/video_core/renderer_opengl/renderer_opengl.h
@@ -45,7 +45,7 @@ struct ScreenInfo {
class RendererOpenGL : public VideoCore::RendererBase {
public:
- explicit RendererOpenGL(Core::Frontend::EmuWindow& window, Core::System& system);
+ explicit RendererOpenGL(Core::Frontend::EmuWindow& emu_window, Core::System& system);
~RendererOpenGL() override;
/// Swap buffers (render frame)
@@ -77,6 +77,7 @@ private:
void LoadColorToActiveGLTexture(u8 color_r, u8 color_g, u8 color_b, u8 color_a,
const TextureInfo& texture);
+ Core::Frontend::EmuWindow& emu_window;
Core::System& system;
OpenGLState state;
diff --git a/src/video_core/shader/decode/arithmetic.cpp b/src/video_core/shader/decode/arithmetic.cpp
index 3190e2d7c..b4859bc1e 100644
--- a/src/video_core/shader/decode/arithmetic.cpp
+++ b/src/video_core/shader/decode/arithmetic.cpp
@@ -4,6 +4,7 @@
#include "common/assert.h"
#include "common/common_types.h"
+#include "common/logging/log.h"
#include "video_core/engines/shader_bytecode.h"
#include "video_core/shader/shader_ir.h"
@@ -152,4 +153,4 @@ u32 ShaderIR::DecodeArithmetic(NodeBlock& bb, u32 pc) {
return pc;
}
-} // namespace VideoCommon::Shader \ No newline at end of file
+} // namespace VideoCommon::Shader
diff --git a/src/video_core/shader/decode/arithmetic_half.cpp b/src/video_core/shader/decode/arithmetic_half.cpp
index 2098c1170..3a29c4a46 100644
--- a/src/video_core/shader/decode/arithmetic_half.cpp
+++ b/src/video_core/shader/decode/arithmetic_half.cpp
@@ -4,6 +4,7 @@
#include "common/assert.h"
#include "common/common_types.h"
+#include "common/logging/log.h"
#include "video_core/engines/shader_bytecode.h"
#include "video_core/shader/shader_ir.h"
diff --git a/src/video_core/shader/decode/arithmetic_half_immediate.cpp b/src/video_core/shader/decode/arithmetic_half_immediate.cpp
index fbcd35b18..5341e460f 100644
--- a/src/video_core/shader/decode/arithmetic_half_immediate.cpp
+++ b/src/video_core/shader/decode/arithmetic_half_immediate.cpp
@@ -4,6 +4,7 @@
#include "common/assert.h"
#include "common/common_types.h"
+#include "common/logging/log.h"
#include "video_core/engines/shader_bytecode.h"
#include "video_core/shader/shader_ir.h"
@@ -47,4 +48,4 @@ u32 ShaderIR::DecodeArithmeticHalfImmediate(NodeBlock& bb, u32 pc) {
return pc;
}
-} // namespace VideoCommon::Shader \ No newline at end of file
+} // namespace VideoCommon::Shader
diff --git a/src/video_core/shader/decode/arithmetic_immediate.cpp b/src/video_core/shader/decode/arithmetic_immediate.cpp
index 0d139c0d2..3095f2fd4 100644
--- a/src/video_core/shader/decode/arithmetic_immediate.cpp
+++ b/src/video_core/shader/decode/arithmetic_immediate.cpp
@@ -49,4 +49,4 @@ u32 ShaderIR::DecodeArithmeticImmediate(NodeBlock& bb, u32 pc) {
return pc;
}
-} // namespace VideoCommon::Shader \ No newline at end of file
+} // namespace VideoCommon::Shader
diff --git a/src/video_core/shader/decode/arithmetic_integer_immediate.cpp b/src/video_core/shader/decode/arithmetic_integer_immediate.cpp
index 3ed5ccc5a..679ac0d4e 100644
--- a/src/video_core/shader/decode/arithmetic_integer_immediate.cpp
+++ b/src/video_core/shader/decode/arithmetic_integer_immediate.cpp
@@ -93,4 +93,4 @@ void ShaderIR::WriteLogicOperation(NodeBlock& bb, Register dest, LogicOperation
}
}
-} // namespace VideoCommon::Shader \ No newline at end of file
+} // namespace VideoCommon::Shader
diff --git a/src/video_core/shader/decode/bfe.cpp b/src/video_core/shader/decode/bfe.cpp
index 6a95dc928..1ae192c6a 100644
--- a/src/video_core/shader/decode/bfe.cpp
+++ b/src/video_core/shader/decode/bfe.cpp
@@ -46,4 +46,4 @@ u32 ShaderIR::DecodeBfe(NodeBlock& bb, u32 pc) {
return pc;
}
-} // namespace VideoCommon::Shader \ No newline at end of file
+} // namespace VideoCommon::Shader
diff --git a/src/video_core/shader/decode/bfi.cpp b/src/video_core/shader/decode/bfi.cpp
index 601d66f1f..0b12a0d08 100644
--- a/src/video_core/shader/decode/bfi.cpp
+++ b/src/video_core/shader/decode/bfi.cpp
@@ -38,4 +38,4 @@ u32 ShaderIR::DecodeBfi(NodeBlock& bb, u32 pc) {
return pc;
}
-} // namespace VideoCommon::Shader \ No newline at end of file
+} // namespace VideoCommon::Shader
diff --git a/src/video_core/shader/decode/ffma.cpp b/src/video_core/shader/decode/ffma.cpp
index 0559cc8de..a1d04c6e5 100644
--- a/src/video_core/shader/decode/ffma.cpp
+++ b/src/video_core/shader/decode/ffma.cpp
@@ -56,4 +56,4 @@ u32 ShaderIR::DecodeFfma(NodeBlock& bb, u32 pc) {
return pc;
}
-} // namespace VideoCommon::Shader \ No newline at end of file
+} // namespace VideoCommon::Shader
diff --git a/src/video_core/shader/decode/float_set.cpp b/src/video_core/shader/decode/float_set.cpp
index 1bd6755dd..cc522f1de 100644
--- a/src/video_core/shader/decode/float_set.cpp
+++ b/src/video_core/shader/decode/float_set.cpp
@@ -55,4 +55,4 @@ u32 ShaderIR::DecodeFloatSet(NodeBlock& bb, u32 pc) {
return pc;
}
-} // namespace VideoCommon::Shader \ No newline at end of file
+} // namespace VideoCommon::Shader
diff --git a/src/video_core/shader/decode/float_set_predicate.cpp b/src/video_core/shader/decode/float_set_predicate.cpp
index 9285b8d05..9d2322a1d 100644
--- a/src/video_core/shader/decode/float_set_predicate.cpp
+++ b/src/video_core/shader/decode/float_set_predicate.cpp
@@ -53,4 +53,4 @@ u32 ShaderIR::DecodeFloatSetPredicate(NodeBlock& bb, u32 pc) {
return pc;
}
-} // namespace VideoCommon::Shader \ No newline at end of file
+} // namespace VideoCommon::Shader
diff --git a/src/video_core/shader/decode/half_set.cpp b/src/video_core/shader/decode/half_set.cpp
index 1dd94bf9d..755f2ec44 100644
--- a/src/video_core/shader/decode/half_set.cpp
+++ b/src/video_core/shader/decode/half_set.cpp
@@ -6,6 +6,7 @@
#include "common/assert.h"
#include "common/common_types.h"
+#include "common/logging/log.h"
#include "video_core/engines/shader_bytecode.h"
#include "video_core/shader/shader_ir.h"
@@ -64,4 +65,4 @@ u32 ShaderIR::DecodeHalfSet(NodeBlock& bb, u32 pc) {
return pc;
}
-} // namespace VideoCommon::Shader \ No newline at end of file
+} // namespace VideoCommon::Shader
diff --git a/src/video_core/shader/decode/half_set_predicate.cpp b/src/video_core/shader/decode/half_set_predicate.cpp
index 6e59eb650..fba44d714 100644
--- a/src/video_core/shader/decode/half_set_predicate.cpp
+++ b/src/video_core/shader/decode/half_set_predicate.cpp
@@ -59,4 +59,4 @@ u32 ShaderIR::DecodeHalfSetPredicate(NodeBlock& bb, u32 pc) {
return pc;
}
-} // namespace VideoCommon::Shader \ No newline at end of file
+} // namespace VideoCommon::Shader
diff --git a/src/video_core/shader/decode/integer_set.cpp b/src/video_core/shader/decode/integer_set.cpp
index a3bf17eba..a4cdaf74d 100644
--- a/src/video_core/shader/decode/integer_set.cpp
+++ b/src/video_core/shader/decode/integer_set.cpp
@@ -2,7 +2,6 @@
// Licensed under GPLv2 or any later version
// Refer to the license.txt file included.
-#include "common/assert.h"
#include "common/common_types.h"
#include "video_core/engines/shader_bytecode.h"
#include "video_core/shader/shader_ir.h"
@@ -47,4 +46,4 @@ u32 ShaderIR::DecodeIntegerSet(NodeBlock& bb, u32 pc) {
return pc;
}
-} // namespace VideoCommon::Shader \ No newline at end of file
+} // namespace VideoCommon::Shader
diff --git a/src/video_core/shader/decode/integer_set_predicate.cpp b/src/video_core/shader/decode/integer_set_predicate.cpp
index aad836d24..a6a1fb632 100644
--- a/src/video_core/shader/decode/integer_set_predicate.cpp
+++ b/src/video_core/shader/decode/integer_set_predicate.cpp
@@ -50,4 +50,4 @@ u32 ShaderIR::DecodeIntegerSetPredicate(NodeBlock& bb, u32 pc) {
return pc;
}
-} // namespace VideoCommon::Shader \ No newline at end of file
+} // namespace VideoCommon::Shader
diff --git a/src/video_core/shader/decode/memory.cpp b/src/video_core/shader/decode/memory.cpp
index 165c2b41b..e6a010a7d 100644
--- a/src/video_core/shader/decode/memory.cpp
+++ b/src/video_core/shader/decode/memory.cpp
@@ -146,12 +146,25 @@ u32 ShaderIR::DecodeMemory(NodeBlock& bb, u32 pc) {
}
break;
}
+ case OpCode::Id::LD:
case OpCode::Id::LDG: {
+ const auto type = [instr, &opcode]() -> Tegra::Shader::UniformType {
+ switch (opcode->get().GetId()) {
+ case OpCode::Id::LD:
+ UNIMPLEMENTED_IF_MSG(!instr.generic.extended, "Unextended LD is not implemented");
+ return instr.generic.type;
+ case OpCode::Id::LDG:
+ return instr.ldg.type;
+ default:
+ UNREACHABLE();
+ return {};
+ }
+ }();
+
const auto [real_address_base, base_address, descriptor] =
- TrackAndGetGlobalMemory(bb, GetRegister(instr.gpr8),
- static_cast<u32>(instr.ldg.immediate_offset.Value()), false);
+ TrackAndGetGlobalMemory(bb, instr, false);
- const u32 count = GetUniformTypeElementsCount(instr.ldg.type);
+ const u32 count = GetUniformTypeElementsCount(type);
for (u32 i = 0; i < count; ++i) {
const Node it_offset = Immediate(i * 4);
const Node real_address =
@@ -165,28 +178,6 @@ u32 ShaderIR::DecodeMemory(NodeBlock& bb, u32 pc) {
}
break;
}
- case OpCode::Id::STG: {
- const auto [real_address_base, base_address, descriptor] =
- TrackAndGetGlobalMemory(bb, GetRegister(instr.gpr8),
- static_cast<u32>(instr.stg.immediate_offset.Value()), true);
-
- // Encode in temporary registers like this: real_base_address, {registers_to_be_written...}
- SetTemporal(bb, 0, real_address_base);
-
- const u32 count = GetUniformTypeElementsCount(instr.stg.type);
- for (u32 i = 0; i < count; ++i) {
- SetTemporal(bb, i + 1, GetRegister(instr.gpr0.Value() + i));
- }
- for (u32 i = 0; i < count; ++i) {
- const Node it_offset = Immediate(i * 4);
- const Node real_address =
- Operation(OperationCode::UAdd, NO_PRECISE, real_address_base, it_offset);
- const Node gmem = StoreNode(GmemNode(real_address, base_address, descriptor));
-
- bb.push_back(Operation(OperationCode::Assign, gmem, GetTemporal(i + 1)));
- }
- break;
- }
case OpCode::Id::ST_A: {
UNIMPLEMENTED_IF_MSG(instr.gpr8.Value() != Register::ZeroIndex,
"Indirect attribute loads are not supported");
@@ -242,6 +233,41 @@ u32 ShaderIR::DecodeMemory(NodeBlock& bb, u32 pc) {
}
break;
}
+ case OpCode::Id::ST:
+ case OpCode::Id::STG: {
+ const auto type = [instr, &opcode]() -> Tegra::Shader::UniformType {
+ switch (opcode->get().GetId()) {
+ case OpCode::Id::ST:
+ UNIMPLEMENTED_IF_MSG(!instr.generic.extended, "Unextended ST is not implemented");
+ return instr.generic.type;
+ case OpCode::Id::STG:
+ return instr.stg.type;
+ default:
+ UNREACHABLE();
+ return {};
+ }
+ }();
+
+ const auto [real_address_base, base_address, descriptor] =
+ TrackAndGetGlobalMemory(bb, instr, true);
+
+ // Encode in temporary registers like this: real_base_address, {registers_to_be_written...}
+ SetTemporal(bb, 0, real_address_base);
+
+ const u32 count = GetUniformTypeElementsCount(type);
+ for (u32 i = 0; i < count; ++i) {
+ SetTemporal(bb, i + 1, GetRegister(instr.gpr0.Value() + i));
+ }
+ for (u32 i = 0; i < count; ++i) {
+ const Node it_offset = Immediate(i * 4);
+ const Node real_address =
+ Operation(OperationCode::UAdd, NO_PRECISE, real_address_base, it_offset);
+ const Node gmem = StoreNode(GmemNode(real_address, base_address, descriptor));
+
+ bb.push_back(Operation(OperationCode::Assign, gmem, GetTemporal(i + 1)));
+ }
+ break;
+ }
case OpCode::Id::AL2P: {
// Ignore al2p.direction since we don't care about it.
@@ -265,9 +291,11 @@ u32 ShaderIR::DecodeMemory(NodeBlock& bb, u32 pc) {
}
std::tuple<Node, Node, GlobalMemoryBase> ShaderIR::TrackAndGetGlobalMemory(NodeBlock& bb,
- Node addr_register,
- u32 immediate_offset,
+ Instruction instr,
bool is_write) {
+ const auto addr_register{GetRegister(instr.gmem.gpr)};
+ const auto immediate_offset{static_cast<u32>(instr.gmem.offset)};
+
const Node base_address{
TrackCbuf(addr_register, global_code, static_cast<s64>(global_code.size()))};
const auto cbuf = std::get_if<CbufNode>(base_address);
diff --git a/src/video_core/shader/decode/other.cpp b/src/video_core/shader/decode/other.cpp
index fa17c45b5..ca7af72e1 100644
--- a/src/video_core/shader/decode/other.cpp
+++ b/src/video_core/shader/decode/other.cpp
@@ -4,6 +4,7 @@
#include "common/assert.h"
#include "common/common_types.h"
+#include "common/logging/log.h"
#include "video_core/engines/shader_bytecode.h"
#include "video_core/shader/shader_ir.h"
diff --git a/src/video_core/shader/decode/predicate_set_predicate.cpp b/src/video_core/shader/decode/predicate_set_predicate.cpp
index 83c61680e..71844c42b 100644
--- a/src/video_core/shader/decode/predicate_set_predicate.cpp
+++ b/src/video_core/shader/decode/predicate_set_predicate.cpp
@@ -64,4 +64,4 @@ u32 ShaderIR::DecodePredicateSetPredicate(NodeBlock& bb, u32 pc) {
return pc;
}
-} // namespace VideoCommon::Shader \ No newline at end of file
+} // namespace VideoCommon::Shader
diff --git a/src/video_core/shader/decode/predicate_set_register.cpp b/src/video_core/shader/decode/predicate_set_register.cpp
index d0495995d..387491bd3 100644
--- a/src/video_core/shader/decode/predicate_set_register.cpp
+++ b/src/video_core/shader/decode/predicate_set_register.cpp
@@ -43,4 +43,4 @@ u32 ShaderIR::DecodePredicateSetRegister(NodeBlock& bb, u32 pc) {
return pc;
}
-} // namespace VideoCommon::Shader \ No newline at end of file
+} // namespace VideoCommon::Shader
diff --git a/src/video_core/shader/decode/register_set_predicate.cpp b/src/video_core/shader/decode/register_set_predicate.cpp
index f070e8912..f8659e48e 100644
--- a/src/video_core/shader/decode/register_set_predicate.cpp
+++ b/src/video_core/shader/decode/register_set_predicate.cpp
@@ -48,4 +48,4 @@ u32 ShaderIR::DecodeRegisterSetPredicate(NodeBlock& bb, u32 pc) {
return pc;
}
-} // namespace VideoCommon::Shader \ No newline at end of file
+} // namespace VideoCommon::Shader
diff --git a/src/video_core/shader/decode/shift.cpp b/src/video_core/shader/decode/shift.cpp
index 951e85f44..44ae87ece 100644
--- a/src/video_core/shader/decode/shift.cpp
+++ b/src/video_core/shader/decode/shift.cpp
@@ -52,4 +52,4 @@ u32 ShaderIR::DecodeShift(NodeBlock& bb, u32 pc) {
return pc;
}
-} // namespace VideoCommon::Shader \ No newline at end of file
+} // namespace VideoCommon::Shader
diff --git a/src/video_core/shader/decode/video.cpp b/src/video_core/shader/decode/video.cpp
index 956c01d9b..cb9ab72b1 100644
--- a/src/video_core/shader/decode/video.cpp
+++ b/src/video_core/shader/decode/video.cpp
@@ -108,4 +108,4 @@ Node ShaderIR::GetVideoOperand(Node op, bool is_chunk, bool is_signed,
}
}
-} // namespace VideoCommon::Shader \ No newline at end of file
+} // namespace VideoCommon::Shader
diff --git a/src/video_core/shader/shader_ir.cpp b/src/video_core/shader/shader_ir.cpp
index 153ad1fd0..8a6ee5cf5 100644
--- a/src/video_core/shader/shader_ir.cpp
+++ b/src/video_core/shader/shader_ir.cpp
@@ -39,8 +39,8 @@ Node ShaderIR::Conditional(Node condition, std::vector<Node>&& code) {
return StoreNode(ConditionalNode(condition, std::move(code)));
}
-Node ShaderIR::Comment(const std::string& text) {
- return StoreNode(CommentNode(text));
+Node ShaderIR::Comment(std::string text) {
+ return StoreNode(CommentNode(std::move(text)));
}
Node ShaderIR::Immediate(u32 value) {
diff --git a/src/video_core/shader/shader_ir.h b/src/video_core/shader/shader_ir.h
index 0bf124252..35f72bddb 100644
--- a/src/video_core/shader/shader_ir.h
+++ b/src/video_core/shader/shader_ir.h
@@ -663,7 +663,7 @@ private:
/// Creates a conditional node
Node Conditional(Node condition, std::vector<Node>&& code);
/// Creates a commentary
- Node Comment(const std::string& text);
+ Node Comment(std::string text);
/// Creates an u32 immediate
Node Immediate(u32 value);
/// Creates a s32 immediate
@@ -818,10 +818,8 @@ private:
std::pair<Node, s64> TrackRegister(const GprNode* tracked, const NodeBlock& code,
s64 cursor) const;
- std::tuple<Node, Node, GlobalMemoryBase> TrackAndGetGlobalMemory(NodeBlock& bb,
- Node addr_register,
- u32 immediate_offset,
- bool is_write);
+ std::tuple<Node, Node, GlobalMemoryBase> TrackAndGetGlobalMemory(
+ NodeBlock& bb, Tegra::Shader::Instruction instr, bool is_write);
template <typename... T>
Node Operation(OperationCode code, const T*... operands) {
diff --git a/src/yuzu/CMakeLists.txt b/src/yuzu/CMakeLists.txt
index 7e883991a..3ea7b55d0 100644
--- a/src/yuzu/CMakeLists.txt
+++ b/src/yuzu/CMakeLists.txt
@@ -155,6 +155,10 @@ target_compile_definitions(yuzu PRIVATE
# Use QStringBuilder for string concatenation to reduce
# the overall number of temporary strings created.
-DQT_USE_QSTRINGBUILDER
+
+ # Disable implicit conversions from/to C strings
+ -DQT_NO_CAST_FROM_ASCII
+ -DQT_NO_CAST_TO_ASCII
)
if (YUZU_ENABLE_COMPATIBILITY_REPORTING)
diff --git a/src/yuzu/applets/error.cpp b/src/yuzu/applets/error.cpp
index 106dde9e2..08ed57355 100644
--- a/src/yuzu/applets/error.cpp
+++ b/src/yuzu/applets/error.cpp
@@ -29,11 +29,13 @@ void QtErrorDisplay::ShowError(ResultCode error, std::function<void()> finished)
void QtErrorDisplay::ShowErrorWithTimestamp(ResultCode error, std::chrono::seconds time,
std::function<void()> finished) const {
this->callback = std::move(finished);
+
+ const QDateTime date_time = QDateTime::fromSecsSinceEpoch(time.count());
emit MainWindowDisplayError(
tr("An error occured on %1 at %2.\nPlease try again or contact the "
"developer of the software.\n\nError Code: %3-%4 (0x%5)")
- .arg(QDateTime::fromSecsSinceEpoch(time.count()).toString("dddd, MMMM d, yyyy"))
- .arg(QDateTime::fromSecsSinceEpoch(time.count()).toString("h:mm:ss A"))
+ .arg(date_time.toString(QStringLiteral("dddd, MMMM d, yyyy")))
+ .arg(date_time.toString(QStringLiteral("h:mm:ss A")))
.arg(static_cast<u32>(error.module.Value()) + 2000, 4, 10, QChar::fromLatin1('0'))
.arg(error.description, 4, 10, QChar::fromLatin1('0'))
.arg(error.raw, 8, 16, QChar::fromLatin1('0')));
diff --git a/src/yuzu/applets/software_keyboard.cpp b/src/yuzu/applets/software_keyboard.cpp
index f3eb29b25..5223ec977 100644
--- a/src/yuzu/applets/software_keyboard.cpp
+++ b/src/yuzu/applets/software_keyboard.cpp
@@ -18,23 +18,30 @@ QtSoftwareKeyboardValidator::QtSoftwareKeyboardValidator(
: parameters(std::move(parameters)) {}
QValidator::State QtSoftwareKeyboardValidator::validate(QString& input, int& pos) const {
- if (input.size() > parameters.max_length)
+ if (input.size() > static_cast<s64>(parameters.max_length)) {
return Invalid;
- if (parameters.disable_space && input.contains(' '))
+ }
+ if (parameters.disable_space && input.contains(QLatin1Char{' '})) {
return Invalid;
- if (parameters.disable_address && input.contains('@'))
+ }
+ if (parameters.disable_address && input.contains(QLatin1Char{'@'})) {
return Invalid;
- if (parameters.disable_percent && input.contains('%'))
+ }
+ if (parameters.disable_percent && input.contains(QLatin1Char{'%'})) {
return Invalid;
- if (parameters.disable_slash && (input.contains('/') || input.contains('\\')))
+ }
+ if (parameters.disable_slash &&
+ (input.contains(QLatin1Char{'/'}) || input.contains(QLatin1Char{'\\'}))) {
return Invalid;
+ }
if (parameters.disable_number &&
std::any_of(input.begin(), input.end(), [](QChar c) { return c.isDigit(); })) {
return Invalid;
}
- if (parameters.disable_download_code &&
- std::any_of(input.begin(), input.end(), [](QChar c) { return c == 'O' || c == 'I'; })) {
+ if (parameters.disable_download_code && std::any_of(input.begin(), input.end(), [](QChar c) {
+ return c == QLatin1Char{'O'} || c == QLatin1Char{'I'};
+ })) {
return Invalid;
}
@@ -142,7 +149,7 @@ void QtSoftwareKeyboard::SendTextCheckDialog(std::u16string error_message,
void QtSoftwareKeyboard::MainWindowFinishedText(std::optional<std::u16string> text) {
// Acquire the HLE mutex
std::lock_guard lock{HLE::g_hle_lock};
- text_output(text);
+ text_output(std::move(text));
}
void QtSoftwareKeyboard::MainWindowFinishedCheckDialog() {
diff --git a/src/yuzu/applets/software_keyboard.h b/src/yuzu/applets/software_keyboard.h
index c63720ba4..78c5a042b 100644
--- a/src/yuzu/applets/software_keyboard.h
+++ b/src/yuzu/applets/software_keyboard.h
@@ -6,7 +6,6 @@
#include <QDialog>
#include <QValidator>
-#include "common/assert.h"
#include "core/frontend/applets/software_keyboard.h"
class GMainWindow;
diff --git a/src/yuzu/bootmanager.cpp b/src/yuzu/bootmanager.cpp
index c2783d684..eeee603d1 100644
--- a/src/yuzu/bootmanager.cpp
+++ b/src/yuzu/bootmanager.cpp
@@ -91,25 +91,25 @@ void EmuThread::run() {
class GGLContext : public Core::Frontend::GraphicsContext {
public:
- explicit GGLContext(QOpenGLContext* shared_context)
- : context{std::make_unique<QOpenGLContext>(shared_context)} {
- surface.setFormat(shared_context->format());
- surface.create();
+ explicit GGLContext(QOpenGLContext* shared_context) : shared_context{shared_context} {
+ context.setFormat(shared_context->format());
+ context.setShareContext(shared_context);
+ context.create();
}
void MakeCurrent() override {
- context->makeCurrent(&surface);
+ context.makeCurrent(shared_context->surface());
}
void DoneCurrent() override {
- context->doneCurrent();
+ context.doneCurrent();
}
void SwapBuffers() override {}
private:
- std::unique_ptr<QOpenGLContext> context;
- QOffscreenSurface surface;
+ QOpenGLContext* shared_context;
+ QOpenGLContext context;
};
// This class overrides paintEvent and resizeEvent to prevent the GUI thread from stealing GL
@@ -358,7 +358,7 @@ void GRenderWindow::OnClientAreaResized(unsigned width, unsigned height) {
}
std::unique_ptr<Core::Frontend::GraphicsContext> GRenderWindow::CreateSharedContext() const {
- return std::make_unique<GGLContext>(shared_context.get());
+ return std::make_unique<GGLContext>(context.get());
}
void GRenderWindow::InitRenderTarget() {
diff --git a/src/yuzu/configuration/config.cpp b/src/yuzu/configuration/config.cpp
index d28826c67..db27da23e 100644
--- a/src/yuzu/configuration/config.cpp
+++ b/src/yuzu/configuration/config.cpp
@@ -11,6 +11,7 @@
#include "core/hle/service/hid/controllers/npad.h"
#include "input_common/main.h"
#include "yuzu/configuration/config.h"
+#include "yuzu/ui_settings.h"
Config::Config() {
// TODO: Don't hardcode the path; let the frontend decide where to put the config files.
@@ -206,25 +207,28 @@ const std::array<int, Settings::NativeKeyboard::NumKeyboardMods> Config::default
};
// This shouldn't have anything except static initializers (no functions). So
-// QKeySequnce(...).toString() is NOT ALLOWED HERE.
+// QKeySequence(...).toString() is NOT ALLOWED HERE.
// This must be in alphabetical order according to action name as it must have the same order as
// UISetting::values.shortcuts, which is alphabetically ordered.
-const std::array<UISettings::Shortcut, 15> Config::default_hotkeys{
- {{"Capture Screenshot", "Main Window", {"Ctrl+P", Qt::ApplicationShortcut}},
- {"Continue/Pause Emulation", "Main Window", {"F4", Qt::WindowShortcut}},
- {"Decrease Speed Limit", "Main Window", {"-", Qt::ApplicationShortcut}},
- {"Exit yuzu", "Main Window", {"Ctrl+Q", Qt::WindowShortcut}},
- {"Exit Fullscreen", "Main Window", {"Esc", Qt::WindowShortcut}},
- {"Fullscreen", "Main Window", {"F11", Qt::WindowShortcut}},
- {"Increase Speed Limit", "Main Window", {"+", Qt::ApplicationShortcut}},
- {"Load Amiibo", "Main Window", {"F2", Qt::ApplicationShortcut}},
- {"Load File", "Main Window", {"Ctrl+O", Qt::WindowShortcut}},
- {"Restart Emulation", "Main Window", {"F6", Qt::WindowShortcut}},
- {"Stop Emulation", "Main Window", {"F5", Qt::WindowShortcut}},
- {"Toggle Filter Bar", "Main Window", {"Ctrl+F", Qt::WindowShortcut}},
- {"Toggle Speed Limit", "Main Window", {"Ctrl+Z", Qt::ApplicationShortcut}},
- {"Toggle Status Bar", "Main Window", {"Ctrl+S", Qt::WindowShortcut}},
- {"Change Docked Mode", "Main Window", {"F10", Qt::ApplicationShortcut}}}};
+// clang-format off
+const std::array<UISettings::Shortcut, 15> default_hotkeys{{
+ {QStringLiteral("Capture Screenshot"), QStringLiteral("Main Window"), {QStringLiteral("Ctrl+P"), Qt::ApplicationShortcut}},
+ {QStringLiteral("Continue/Pause Emulation"), QStringLiteral("Main Window"), {QStringLiteral("F4"), Qt::WindowShortcut}},
+ {QStringLiteral("Decrease Speed Limit"), QStringLiteral("Main Window"), {QStringLiteral("-"), Qt::ApplicationShortcut}},
+ {QStringLiteral("Exit yuzu"), QStringLiteral("Main Window"), {QStringLiteral("Ctrl+Q"), Qt::WindowShortcut}},
+ {QStringLiteral("Exit Fullscreen"), QStringLiteral("Main Window"), {QStringLiteral("Esc"), Qt::WindowShortcut}},
+ {QStringLiteral("Fullscreen"), QStringLiteral("Main Window"), {QStringLiteral("F11"), Qt::WindowShortcut}},
+ {QStringLiteral("Increase Speed Limit"), QStringLiteral("Main Window"), {QStringLiteral("+"), Qt::ApplicationShortcut}},
+ {QStringLiteral("Load Amiibo"), QStringLiteral("Main Window"), {QStringLiteral("F2"), Qt::ApplicationShortcut}},
+ {QStringLiteral("Load File"), QStringLiteral("Main Window"), {QStringLiteral("Ctrl+O"), Qt::WindowShortcut}},
+ {QStringLiteral("Restart Emulation"), QStringLiteral("Main Window"), {QStringLiteral("F6"), Qt::WindowShortcut}},
+ {QStringLiteral("Stop Emulation"), QStringLiteral("Main Window"), {QStringLiteral("F5"), Qt::WindowShortcut}},
+ {QStringLiteral("Toggle Filter Bar"), QStringLiteral("Main Window"), {QStringLiteral("Ctrl+F"), Qt::WindowShortcut}},
+ {QStringLiteral("Toggle Speed Limit"), QStringLiteral("Main Window"), {QStringLiteral("Ctrl+Z"), Qt::ApplicationShortcut}},
+ {QStringLiteral("Toggle Status Bar"), QStringLiteral("Main Window"), {QStringLiteral("Ctrl+S"), Qt::WindowShortcut}},
+ {QStringLiteral("Change Docked Mode"), QStringLiteral("Main Window"), {QStringLiteral("F10"), Qt::ApplicationShortcut}},
+}};
+// clang-format on
void Config::ReadPlayerValues() {
for (std::size_t p = 0; p < Settings::values.players.size(); ++p) {
@@ -370,14 +374,21 @@ void Config::ReadMouseValues() {
}
void Config::ReadTouchscreenValues() {
- Settings::values.touchscreen.enabled = ReadSetting("touchscreen_enabled", true).toBool();
+ Settings::values.touchscreen.enabled =
+ ReadSetting(QStringLiteral("touchscreen_enabled"), true).toBool();
Settings::values.touchscreen.device =
- ReadSetting("touchscreen_device", "engine:emu_window").toString().toStdString();
+ ReadSetting(QStringLiteral("touchscreen_device"), QStringLiteral("engine:emu_window"))
+ .toString()
+ .toStdString();
- Settings::values.touchscreen.finger = ReadSetting("touchscreen_finger", 0).toUInt();
- Settings::values.touchscreen.rotation_angle = ReadSetting("touchscreen_angle", 0).toUInt();
- Settings::values.touchscreen.diameter_x = ReadSetting("touchscreen_diameter_x", 15).toUInt();
- Settings::values.touchscreen.diameter_y = ReadSetting("touchscreen_diameter_y", 15).toUInt();
+ Settings::values.touchscreen.finger =
+ ReadSetting(QStringLiteral("touchscreen_finger"), 0).toUInt();
+ Settings::values.touchscreen.rotation_angle =
+ ReadSetting(QStringLiteral("touchscreen_angle"), 0).toUInt();
+ Settings::values.touchscreen.diameter_x =
+ ReadSetting(QStringLiteral("touchscreen_diameter_x"), 15).toUInt();
+ Settings::values.touchscreen.diameter_y =
+ ReadSetting(QStringLiteral("touchscreen_diameter_y"), 15).toUInt();
}
void Config::ApplyDefaultProfileIfInputInvalid() {
@@ -541,8 +552,8 @@ void Config::ReadRendererValues() {
void Config::ReadShortcutValues() {
qt_config->beginGroup(QStringLiteral("Shortcuts"));
- for (auto [name, group, shortcut] : default_hotkeys) {
- auto [keyseq, context] = shortcut;
+ for (const auto& [name, group, shortcut] : default_hotkeys) {
+ const auto& [keyseq, context] = shortcut;
qt_config->beginGroup(group);
qt_config->beginGroup(name);
UISettings::values.shortcuts.push_back(
@@ -591,7 +602,8 @@ void Config::ReadUIValues() {
qt_config->beginGroup(QStringLiteral("UI"));
UISettings::values.theme =
- ReadSetting(QStringLiteral("theme"), UISettings::themes[0].second).toString();
+ ReadSetting(QStringLiteral("theme"), QString::fromUtf8(UISettings::themes[0].second))
+ .toString();
UISettings::values.enable_discord_presence =
ReadSetting(QStringLiteral("enable_discord_presence"), true).toBool();
UISettings::values.screenshot_resolution_factor =
@@ -626,7 +638,7 @@ void Config::ReadUIValues() {
}
void Config::ReadUIGamelistValues() {
- qt_config->beginGroup("UIGameList");
+ qt_config->beginGroup(QStringLiteral("UIGameList"));
UISettings::values.show_unknown = ReadSetting(QStringLiteral("show_unknown"), true).toBool();
UISettings::values.show_add_ons = ReadSetting(QStringLiteral("show_add_ons"), true).toBool();
@@ -723,7 +735,7 @@ void Config::SavePlayerValues() {
}
void Config::SaveDebugValues() {
- WriteSetting("debug_pad_enabled", Settings::values.debug_pad_enabled, false);
+ WriteSetting(QStringLiteral("debug_pad_enabled"), Settings::values.debug_pad_enabled, false);
for (int i = 0; i < Settings::NativeButton::NumButtons; ++i) {
const std::string default_param = InputCommon::GenerateKeyboardParam(default_buttons[i]);
WriteSetting(QStringLiteral("debug_pad_") +
@@ -924,7 +936,7 @@ void Config::SaveShortcutValues() {
// Lengths of UISettings::values.shortcuts & default_hotkeys are same.
// However, their ordering must also be the same.
for (std::size_t i = 0; i < default_hotkeys.size(); i++) {
- const auto [name, group, shortcut] = UISettings::values.shortcuts[i];
+ const auto& [name, group, shortcut] = UISettings::values.shortcuts[i];
const auto& default_hotkey = default_hotkeys[i].shortcut;
qt_config->beginGroup(group);
@@ -961,7 +973,8 @@ void Config::SaveSystemValues() {
void Config::SaveUIValues() {
qt_config->beginGroup(QStringLiteral("UI"));
- WriteSetting(QStringLiteral("theme"), UISettings::values.theme, UISettings::themes[0].second);
+ WriteSetting(QStringLiteral("theme"), UISettings::values.theme,
+ QString::fromUtf8(UISettings::themes[0].second));
WriteSetting(QStringLiteral("enable_discord_presence"),
UISettings::values.enable_discord_presence, true);
WriteSetting(QStringLiteral("screenshot_resolution_factor"),
diff --git a/src/yuzu/configuration/config.h b/src/yuzu/configuration/config.h
index b62a480ee..6b523ecdd 100644
--- a/src/yuzu/configuration/config.h
+++ b/src/yuzu/configuration/config.h
@@ -9,7 +9,6 @@
#include <string>
#include <QVariant>
#include "core/settings.h"
-#include "yuzu/ui_settings.h"
class QSettings;
@@ -82,8 +81,6 @@ private:
void WriteSetting(const QString& name, const QVariant& value);
void WriteSetting(const QString& name, const QVariant& value, const QVariant& default_value);
- static const std::array<UISettings::Shortcut, 15> default_hotkeys;
-
std::unique_ptr<QSettings> qt_config;
std::string qt_config_loc;
};
diff --git a/src/yuzu/configuration/configure_dialog.cpp b/src/yuzu/configuration/configure_dialog.cpp
index 32c05b797..8086f9d6b 100644
--- a/src/yuzu/configuration/configure_dialog.cpp
+++ b/src/yuzu/configuration/configure_dialog.cpp
@@ -25,9 +25,6 @@ ConfigureDialog::ConfigureDialog(QWidget* parent, HotkeyRegistry& registry)
adjustSize();
ui->selectorList->setCurrentRow(0);
-
- // Synchronise lists upon initialisation
- ui->hotkeysTab->EmitHotkeysChanged();
}
ConfigureDialog::~ConfigureDialog() = default;
diff --git a/src/yuzu/configuration/configure_hotkeys.cpp b/src/yuzu/configuration/configure_hotkeys.cpp
index a7a8752e5..9fb970c21 100644
--- a/src/yuzu/configuration/configure_hotkeys.cpp
+++ b/src/yuzu/configuration/configure_hotkeys.cpp
@@ -31,22 +31,6 @@ ConfigureHotkeys::ConfigureHotkeys(QWidget* parent)
ConfigureHotkeys::~ConfigureHotkeys() = default;
-void ConfigureHotkeys::EmitHotkeysChanged() {
- emit HotkeysChanged(GetUsedKeyList());
-}
-
-QList<QKeySequence> ConfigureHotkeys::GetUsedKeyList() const {
- QList<QKeySequence> list;
- for (int r = 0; r < model->rowCount(); r++) {
- const QStandardItem* parent = model->item(r, 0);
- for (int r2 = 0; r2 < parent->rowCount(); r2++) {
- const QStandardItem* keyseq = parent->child(r2, 1);
- list << QKeySequence::fromString(keyseq->text(), QKeySequence::NativeText);
- }
- }
- return list;
-}
-
void ConfigureHotkeys::Populate(const HotkeyRegistry& registry) {
for (const auto& group : registry.hotkey_groups) {
auto* parent_item = new QStandardItem(group.first);
@@ -83,16 +67,29 @@ void ConfigureHotkeys::Configure(QModelIndex index) {
}
if (IsUsedKey(key_sequence) && key_sequence != QKeySequence(previous_key.toString())) {
- QMessageBox::critical(this, tr("Error in inputted key"),
- tr("You're using a key that's already bound."));
+ QMessageBox::warning(this, tr("Conflicting Key Sequence"),
+ tr("The entered key sequence is already assigned to another hotkey."));
} else {
model->setData(index, key_sequence.toString(QKeySequence::NativeText));
- EmitHotkeysChanged();
}
}
bool ConfigureHotkeys::IsUsedKey(QKeySequence key_sequence) const {
- return GetUsedKeyList().contains(key_sequence);
+ for (int r = 0; r < model->rowCount(); r++) {
+ const QStandardItem* const parent = model->item(r, 0);
+
+ for (int r2 = 0; r2 < parent->rowCount(); r2++) {
+ const QStandardItem* const key_seq_item = parent->child(r2, 1);
+ const auto key_seq_str = key_seq_item->text();
+ const auto key_seq = QKeySequence::fromString(key_seq_str, QKeySequence::NativeText);
+
+ if (key_sequence == key_seq) {
+ return true;
+ }
+ }
+ }
+
+ return false;
}
void ConfigureHotkeys::applyConfiguration(HotkeyRegistry& registry) {
@@ -114,7 +111,6 @@ void ConfigureHotkeys::applyConfiguration(HotkeyRegistry& registry) {
}
registry.SaveHotkeys();
- Settings::Apply();
}
void ConfigureHotkeys::retranslateUi() {
diff --git a/src/yuzu/configuration/configure_hotkeys.h b/src/yuzu/configuration/configure_hotkeys.h
index 73fb8a175..e77d73c35 100644
--- a/src/yuzu/configuration/configure_hotkeys.h
+++ b/src/yuzu/configuration/configure_hotkeys.h
@@ -24,8 +24,6 @@ public:
void applyConfiguration(HotkeyRegistry& registry);
void retranslateUi();
- void EmitHotkeysChanged();
-
/**
* Populates the hotkey list widget using data from the provided registry.
* Called everytime the Configure dialog is opened.
@@ -33,13 +31,9 @@ public:
*/
void Populate(const HotkeyRegistry& registry);
-signals:
- void HotkeysChanged(QList<QKeySequence> new_key_list);
-
private:
void Configure(QModelIndex index);
bool IsUsedKey(QKeySequence key_sequence) const;
- QList<QKeySequence> GetUsedKeyList() const;
std::unique_ptr<Ui::ConfigureHotkeys> ui;
diff --git a/src/yuzu/main.cpp b/src/yuzu/main.cpp
index a59abf6e8..cef2cc1ae 100644
--- a/src/yuzu/main.cpp
+++ b/src/yuzu/main.cpp
@@ -281,7 +281,7 @@ void GMainWindow::SoftwareKeyboardInvokeCheckDialog(std::u16string error_message
void GMainWindow::WebBrowserOpenPage(std::string_view filename, std::string_view additional_args) {
NXInputWebEngineView web_browser_view(this);
- // Scope to contain the QProgressDialog for initalization
+ // Scope to contain the QProgressDialog for initialization
{
QProgressDialog progress(this);
progress.setMinimumDuration(200);
@@ -301,7 +301,7 @@ void GMainWindow::WebBrowserOpenPage(std::string_view filename, std::string_view
QWebEngineScript nx_shim;
nx_shim.setSourceCode(GetNXShimInjectionScript());
nx_shim.setWorldId(QWebEngineScript::MainWorld);
- nx_shim.setName("nx_inject.js");
+ nx_shim.setName(QStringLiteral("nx_inject.js"));
nx_shim.setInjectionPoint(QWebEngineScript::DocumentCreation);
nx_shim.setRunsOnSubFrames(true);
web_browser_view.page()->profile()->scripts()->insert(nx_shim);
@@ -347,7 +347,7 @@ void GMainWindow::WebBrowserOpenPage(std::string_view filename, std::string_view
const auto fire_js_keypress = [&web_browser_view](u32 key_code) {
web_browser_view.page()->runJavaScript(
QStringLiteral("document.dispatchEvent(new KeyboardEvent('keydown', {'key': %1}));")
- .arg(QString::fromStdString(std::to_string(key_code))));
+ .arg(key_code));
};
QMessageBox::information(
@@ -468,7 +468,7 @@ void GMainWindow::InitializeWidgets() {
statusBar()->addPermanentWidget(label, 0);
}
statusBar()->setVisible(true);
- setStyleSheet("QStatusBar::item{border: none;}");
+ setStyleSheet(QStringLiteral("QStatusBar::item{border: none;}"));
}
void GMainWindow::InitializeDebugWidgets() {
@@ -518,58 +518,67 @@ void GMainWindow::InitializeRecentFileMenuActions() {
void GMainWindow::InitializeHotkeys() {
hotkey_registry.LoadHotkeys();
- ui.action_Load_File->setShortcut(hotkey_registry.GetKeySequence("Main Window", "Load File"));
+ const QString main_window = QStringLiteral("Main Window");
+ const QString load_file = QStringLiteral("Load File");
+ const QString exit_yuzu = QStringLiteral("Exit yuzu");
+ const QString stop_emulation = QStringLiteral("Stop Emulation");
+ const QString toggle_filter_bar = QStringLiteral("Toggle Filter Bar");
+ const QString toggle_status_bar = QStringLiteral("Toggle Status Bar");
+ const QString fullscreen = QStringLiteral("Fullscreen");
+
+ ui.action_Load_File->setShortcut(hotkey_registry.GetKeySequence(main_window, load_file));
ui.action_Load_File->setShortcutContext(
- hotkey_registry.GetShortcutContext("Main Window", "Load File"));
+ hotkey_registry.GetShortcutContext(main_window, load_file));
- ui.action_Exit->setShortcut(hotkey_registry.GetKeySequence("Main Window", "Exit yuzu"));
- ui.action_Exit->setShortcutContext(
- hotkey_registry.GetShortcutContext("Main Window", "Exit yuzu"));
+ ui.action_Exit->setShortcut(hotkey_registry.GetKeySequence(main_window, exit_yuzu));
+ ui.action_Exit->setShortcutContext(hotkey_registry.GetShortcutContext(main_window, exit_yuzu));
- ui.action_Stop->setShortcut(hotkey_registry.GetKeySequence("Main Window", "Stop Emulation"));
+ ui.action_Stop->setShortcut(hotkey_registry.GetKeySequence(main_window, stop_emulation));
ui.action_Stop->setShortcutContext(
- hotkey_registry.GetShortcutContext("Main Window", "Stop Emulation"));
+ hotkey_registry.GetShortcutContext(main_window, stop_emulation));
ui.action_Show_Filter_Bar->setShortcut(
- hotkey_registry.GetKeySequence("Main Window", "Toggle Filter Bar"));
+ hotkey_registry.GetKeySequence(main_window, toggle_filter_bar));
ui.action_Show_Filter_Bar->setShortcutContext(
- hotkey_registry.GetShortcutContext("Main Window", "Toggle Filter Bar"));
+ hotkey_registry.GetShortcutContext(main_window, toggle_filter_bar));
ui.action_Show_Status_Bar->setShortcut(
- hotkey_registry.GetKeySequence("Main Window", "Toggle Status Bar"));
+ hotkey_registry.GetKeySequence(main_window, toggle_status_bar));
ui.action_Show_Status_Bar->setShortcutContext(
- hotkey_registry.GetShortcutContext("Main Window", "Toggle Status Bar"));
-
- connect(hotkey_registry.GetHotkey("Main Window", "Load File", this), &QShortcut::activated,
- this, &GMainWindow::OnMenuLoadFile);
- connect(hotkey_registry.GetHotkey("Main Window", "Continue/Pause Emulation", this),
- &QShortcut::activated, this, [&] {
- if (emulation_running) {
- if (emu_thread->IsRunning()) {
- OnPauseGame();
- } else {
- OnStartGame();
- }
+ hotkey_registry.GetShortcutContext(main_window, toggle_status_bar));
+
+ connect(hotkey_registry.GetHotkey(main_window, QStringLiteral("Load File"), this),
+ &QShortcut::activated, this, &GMainWindow::OnMenuLoadFile);
+ connect(
+ hotkey_registry.GetHotkey(main_window, QStringLiteral("Continue/Pause Emulation"), this),
+ &QShortcut::activated, this, [&] {
+ if (emulation_running) {
+ if (emu_thread->IsRunning()) {
+ OnPauseGame();
+ } else {
+ OnStartGame();
}
- });
- connect(hotkey_registry.GetHotkey("Main Window", "Restart Emulation", this),
+ }
+ });
+ connect(hotkey_registry.GetHotkey(main_window, QStringLiteral("Restart Emulation"), this),
&QShortcut::activated, this, [this] {
- if (!Core::System::GetInstance().IsPoweredOn())
+ if (!Core::System::GetInstance().IsPoweredOn()) {
return;
- BootGame(QString(game_path));
+ }
+ BootGame(game_path);
});
- connect(hotkey_registry.GetHotkey("Main Window", "Fullscreen", render_window),
+ connect(hotkey_registry.GetHotkey(main_window, fullscreen, render_window),
&QShortcut::activated, ui.action_Fullscreen, &QAction::trigger);
- connect(hotkey_registry.GetHotkey("Main Window", "Fullscreen", render_window),
+ connect(hotkey_registry.GetHotkey(main_window, fullscreen, render_window),
&QShortcut::activatedAmbiguously, ui.action_Fullscreen, &QAction::trigger);
- connect(hotkey_registry.GetHotkey("Main Window", "Exit Fullscreen", this),
+ connect(hotkey_registry.GetHotkey(main_window, QStringLiteral("Exit Fullscreen"), this),
&QShortcut::activated, this, [&] {
if (emulation_running) {
ui.action_Fullscreen->setChecked(false);
ToggleFullscreen();
}
});
- connect(hotkey_registry.GetHotkey("Main Window", "Toggle Speed Limit", this),
+ connect(hotkey_registry.GetHotkey(main_window, QStringLiteral("Toggle Speed Limit"), this),
&QShortcut::activated, this, [&] {
Settings::values.use_frame_limit = !Settings::values.use_frame_limit;
UpdateStatusBar();
@@ -578,33 +587,33 @@ void GMainWindow::InitializeHotkeys() {
// MSVC occurs and we make it a requirement (see:
// https://developercommunity.visualstudio.com/content/problem/93922/constexprs-are-trying-to-be-captured-in-lambda-fun.html)
static constexpr u16 SPEED_LIMIT_STEP = 5;
- connect(hotkey_registry.GetHotkey("Main Window", "Increase Speed Limit", this),
+ connect(hotkey_registry.GetHotkey(main_window, QStringLiteral("Increase Speed Limit"), this),
&QShortcut::activated, this, [&] {
if (Settings::values.frame_limit < 9999 - SPEED_LIMIT_STEP) {
Settings::values.frame_limit += SPEED_LIMIT_STEP;
UpdateStatusBar();
}
});
- connect(hotkey_registry.GetHotkey("Main Window", "Decrease Speed Limit", this),
+ connect(hotkey_registry.GetHotkey(main_window, QStringLiteral("Decrease Speed Limit"), this),
&QShortcut::activated, this, [&] {
if (Settings::values.frame_limit > SPEED_LIMIT_STEP) {
Settings::values.frame_limit -= SPEED_LIMIT_STEP;
UpdateStatusBar();
}
});
- connect(hotkey_registry.GetHotkey("Main Window", "Load Amiibo", this), &QShortcut::activated,
- this, [&] {
+ connect(hotkey_registry.GetHotkey(main_window, QStringLiteral("Load Amiibo"), this),
+ &QShortcut::activated, this, [&] {
if (ui.action_Load_Amiibo->isEnabled()) {
OnLoadAmiibo();
}
});
- connect(hotkey_registry.GetHotkey("Main Window", "Capture Screenshot", this),
+ connect(hotkey_registry.GetHotkey(main_window, QStringLiteral("Capture Screenshot"), this),
&QShortcut::activated, this, [&] {
if (emu_thread->IsRunning()) {
OnCaptureScreenshot();
}
});
- connect(hotkey_registry.GetHotkey("Main Window", "Change Docked Mode", this),
+ connect(hotkey_registry.GetHotkey(main_window, QStringLiteral("Change Docked Mode"), this),
&QShortcut::activated, this, [&] {
Settings::values.use_docked_mode = !Settings::values.use_docked_mode;
OnDockedModeChanged(!Settings::values.use_docked_mode,
@@ -705,7 +714,9 @@ void GMainWindow::ConnectMenuEvents() {
// Fullscreen
ui.action_Fullscreen->setShortcut(
- hotkey_registry.GetHotkey("Main Window", "Fullscreen", this)->key());
+ hotkey_registry
+ .GetHotkey(QStringLiteral("Main Window"), QStringLiteral("Fullscreen"), this)
+ ->key());
connect(ui.action_Fullscreen, &QAction::triggered, this, &GMainWindow::ToggleFullscreen);
// Movie
@@ -742,25 +753,33 @@ void GMainWindow::OnDisplayTitleBars(bool show) {
QStringList GMainWindow::GetUnsupportedGLExtensions() {
QStringList unsupported_ext;
- if (!GLAD_GL_ARB_direct_state_access)
- unsupported_ext.append("ARB_direct_state_access");
- if (!GLAD_GL_ARB_vertex_type_10f_11f_11f_rev)
- unsupported_ext.append("ARB_vertex_type_10f_11f_11f_rev");
- if (!GLAD_GL_ARB_texture_mirror_clamp_to_edge)
- unsupported_ext.append("ARB_texture_mirror_clamp_to_edge");
- if (!GLAD_GL_ARB_multi_bind)
- unsupported_ext.append("ARB_multi_bind");
+ if (!GLAD_GL_ARB_direct_state_access) {
+ unsupported_ext.append(QStringLiteral("ARB_direct_state_access"));
+ }
+ if (!GLAD_GL_ARB_vertex_type_10f_11f_11f_rev) {
+ unsupported_ext.append(QStringLiteral("ARB_vertex_type_10f_11f_11f_rev"));
+ }
+ if (!GLAD_GL_ARB_texture_mirror_clamp_to_edge) {
+ unsupported_ext.append(QStringLiteral("ARB_texture_mirror_clamp_to_edge"));
+ }
+ if (!GLAD_GL_ARB_multi_bind) {
+ unsupported_ext.append(QStringLiteral("ARB_multi_bind"));
+ }
// Extensions required to support some texture formats.
- if (!GLAD_GL_EXT_texture_compression_s3tc)
- unsupported_ext.append("EXT_texture_compression_s3tc");
- if (!GLAD_GL_ARB_texture_compression_rgtc)
- unsupported_ext.append("ARB_texture_compression_rgtc");
- if (!GLAD_GL_ARB_depth_buffer_float)
- unsupported_ext.append("ARB_depth_buffer_float");
-
- for (const QString& ext : unsupported_ext)
+ if (!GLAD_GL_EXT_texture_compression_s3tc) {
+ unsupported_ext.append(QStringLiteral("EXT_texture_compression_s3tc"));
+ }
+ if (!GLAD_GL_ARB_texture_compression_rgtc) {
+ unsupported_ext.append(QStringLiteral("ARB_texture_compression_rgtc"));
+ }
+ if (!GLAD_GL_ARB_depth_buffer_float) {
+ unsupported_ext.append(QStringLiteral("ARB_depth_buffer_float"));
+ }
+
+ for (const QString& ext : unsupported_ext) {
LOG_CRITICAL(Frontend, "Unsupported GL extension: {}", ext.toStdString());
+ }
return unsupported_ext;
}
@@ -782,13 +801,13 @@ bool GMainWindow::LoadROM(const QString& filename) {
}
}
- QStringList unsupported_gl_extensions = GetUnsupportedGLExtensions();
+ const QStringList unsupported_gl_extensions = GetUnsupportedGLExtensions();
if (!unsupported_gl_extensions.empty()) {
QMessageBox::critical(this, tr("Error while initializing OpenGL Core!"),
tr("Your GPU may not support one or more required OpenGL"
"extensions. Please ensure you have the latest graphics "
"driver.<br><br>Unsupported extensions:<br>") +
- unsupported_gl_extensions.join("<br>"));
+ unsupported_gl_extensions.join(QStringLiteral("<br>")));
return false;
}
@@ -1007,7 +1026,7 @@ void GMainWindow::UpdateRecentFiles() {
std::min(UISettings::values.recent_files.size(), max_recent_files_item);
for (int i = 0; i < num_recent_files; i++) {
- const QString text = QString("&%1. %2").arg(i + 1).arg(
+ const QString text = QStringLiteral("&%1. %2").arg(i + 1).arg(
QFileInfo(UISettings::values.recent_files[i]).fileName());
actions_recent_files[i]->setText(text);
actions_recent_files[i]->setData(UISettings::values.recent_files[i]);
@@ -1029,10 +1048,10 @@ void GMainWindow::OnGameListLoadFile(QString game_path) {
void GMainWindow::OnGameListOpenFolder(u64 program_id, GameListOpenTarget target) {
std::string path;
- std::string open_target;
+ QString open_target;
switch (target) {
case GameListOpenTarget::SaveData: {
- open_target = "Save Data";
+ open_target = tr("Save Data");
const std::string nand_dir = FileUtil::GetUserPath(FileUtil::UserPath::NANDDir);
ASSERT(program_id != 0);
@@ -1069,7 +1088,7 @@ void GMainWindow::OnGameListOpenFolder(u64 program_id, GameListOpenTarget target
break;
}
case GameListOpenTarget::ModData: {
- open_target = "Mod Data";
+ open_target = tr("Mod Data");
const auto load_dir = FileUtil::GetUserPath(FileUtil::UserPath::LoadDir);
path = fmt::format("{}{:016X}", load_dir, program_id);
break;
@@ -1079,27 +1098,26 @@ void GMainWindow::OnGameListOpenFolder(u64 program_id, GameListOpenTarget target
}
const QString qpath = QString::fromStdString(path);
-
const QDir dir(qpath);
if (!dir.exists()) {
- QMessageBox::warning(this,
- tr("Error Opening %1 Folder").arg(QString::fromStdString(open_target)),
+ QMessageBox::warning(this, tr("Error Opening %1 Folder").arg(open_target),
tr("Folder does not exist!"));
return;
}
- LOG_INFO(Frontend, "Opening {} path for program_id={:016x}", open_target, program_id);
+ LOG_INFO(Frontend, "Opening {} path for program_id={:016x}", open_target.toStdString(),
+ program_id);
QDesktopServices::openUrl(QUrl::fromLocalFile(qpath));
}
void GMainWindow::OnTransferableShaderCacheOpenFile(u64 program_id) {
ASSERT(program_id != 0);
+ const QString shader_dir =
+ QString::fromStdString(FileUtil::GetUserPath(FileUtil::UserPath::ShaderDir));
const QString tranferable_shader_cache_folder_path =
- QString::fromStdString(FileUtil::GetUserPath(FileUtil::UserPath::ShaderDir)) + "opengl" +
- DIR_SEP + "transferable";
-
+ shader_dir + QStringLiteral("opengl") + QDir::separator() + QStringLiteral("transferable");
const QString transferable_shader_cache_file_path =
- tranferable_shader_cache_folder_path + DIR_SEP +
+ tranferable_shader_cache_folder_path + QDir::separator() +
QString::fromStdString(fmt::format("{:016X}.bin", program_id));
if (!QFile::exists(transferable_shader_cache_file_path)) {
@@ -1216,20 +1234,21 @@ void GMainWindow::OnGameListDumpRomFS(u64 program_id, const std::string& game_pa
return;
}
- bool ok;
+ bool ok = false;
+ const QStringList selections{tr("Full"), tr("Skeleton")};
const auto res = QInputDialog::getItem(
this, tr("Select RomFS Dump Mode"),
tr("Please select the how you would like the RomFS dumped.<br>Full will copy all of the "
"files into the new directory while <br>skeleton will only create the directory "
"structure."),
- {"Full", "Skeleton"}, 0, false, &ok);
+ selections, 0, false, &ok);
if (!ok) {
failed();
vfs->DeleteDirectory(path);
return;
}
- const auto full = res == "Full";
+ const auto full = res == selections.constFirst();
const auto entry_size = CalculateRomFSEntrySize(extracted, full);
QProgressDialog progress(tr("Extracting RomFS..."), tr("Cancel"), 0,
@@ -1259,10 +1278,11 @@ void GMainWindow::OnGameListNavigateToGamedbEntry(u64 program_id,
const auto it = FindMatchingCompatibilityEntry(compatibility_list, program_id);
QString directory;
- if (it != compatibility_list.end())
+ if (it != compatibility_list.end()) {
directory = it->second.second;
+ }
- QDesktopServices::openUrl(QUrl("https://yuzu-emu.org/game/" + directory));
+ QDesktopServices::openUrl(QUrl(QStringLiteral("https://yuzu-emu.org/game/") + directory));
}
void GMainWindow::OnGameListOpenPerGameProperties(const std::string& file) {
@@ -1293,7 +1313,9 @@ void GMainWindow::OnGameListOpenPerGameProperties(const std::string& file) {
void GMainWindow::OnMenuLoadFile() {
const QString extensions =
- QString("*.").append(GameList::supported_file_extensions.join(" *.")).append(" main");
+ QStringLiteral("*.")
+ .append(GameList::supported_file_extensions.join(QStringLiteral(" *.")))
+ .append(QStringLiteral(" main"));
const QString file_filter = tr("Switch Executable (%1);;All Files (*.*)",
"%1 is an identifier for the Switch executable file extensions.")
.arg(extensions);
@@ -1317,9 +1339,9 @@ void GMainWindow::OnMenuLoadFolder() {
}
const QDir dir{dir_path};
- const QStringList matching_main = dir.entryList(QStringList("main"), QDir::Files);
+ const QStringList matching_main = dir.entryList({QStringLiteral("main")}, QDir::Files);
if (matching_main.size() == 1) {
- BootGame(dir.path() + DIR_SEP + matching_main[0]);
+ BootGame(dir.path() + QDir::separator() + matching_main[0]);
} else {
QMessageBox::warning(this, tr("Invalid Directory Selected"),
tr("The directory you have selected does not contain a 'main' file."));
@@ -1391,11 +1413,10 @@ void GMainWindow::OnMenuInstallToNAND() {
QMessageBox::Yes;
};
- if (filename.endsWith("xci", Qt::CaseInsensitive) ||
- filename.endsWith("nsp", Qt::CaseInsensitive)) {
-
+ if (filename.endsWith(QStringLiteral("xci"), Qt::CaseInsensitive) ||
+ filename.endsWith(QStringLiteral("nsp"), Qt::CaseInsensitive)) {
std::shared_ptr<FileSys::NSP> nsp;
- if (filename.endsWith("nsp", Qt::CaseInsensitive)) {
+ if (filename.endsWith(QStringLiteral("nsp"), Qt::CaseInsensitive)) {
nsp = std::make_shared<FileSys::NSP>(
vfs->OpenFile(filename.toStdString(), FileSys::Mode::Read));
if (nsp->IsExtractedType())
@@ -1690,9 +1711,9 @@ void GMainWindow::OnConfigure() {
}
void GMainWindow::OnLoadAmiibo() {
- const QString extensions{"*.bin"};
+ const QString extensions{QStringLiteral("*.bin")};
const QString file_filter = tr("Amiibo File (%1);; All Files (*.*)").arg(extensions);
- const QString filename = QFileDialog::getOpenFileName(this, tr("Load Amiibo"), "", file_filter);
+ const QString filename = QFileDialog::getOpenFileName(this, tr("Load Amiibo"), {}, file_filter);
if (filename.isEmpty()) {
return;
@@ -1754,7 +1775,7 @@ void GMainWindow::OnCaptureScreenshot() {
QFileDialog png_dialog(this, tr("Capture Screenshot"), UISettings::values.screenshot_path,
tr("PNG Image (*.png)"));
png_dialog.setAcceptMode(QFileDialog::AcceptSave);
- png_dialog.setDefaultSuffix("png");
+ png_dialog.setDefaultSuffix(QStringLiteral("png"));
if (png_dialog.exec()) {
const QString path = png_dialog.selectedFiles().first();
if (!path.isEmpty()) {
@@ -1817,17 +1838,17 @@ void GMainWindow::OnCoreError(Core::System::ResultStatus result, std::string det
"data, or other bugs.");
switch (result) {
case Core::System::ResultStatus::ErrorSystemFiles: {
- QString message = "yuzu was unable to locate a Switch system archive";
+ QString message = tr("yuzu was unable to locate a Switch system archive");
if (!details.empty()) {
- message.append(tr(": %1. ").arg(details.c_str()));
+ message.append(tr(": %1. ").arg(QString::fromStdString(details)));
} else {
- message.append(". ");
+ message.append(tr(". "));
}
message.append(common_message);
answer = QMessageBox::question(this, tr("System Archive Not Found"), message,
QMessageBox::Yes | QMessageBox::No, QMessageBox::No);
- status_message = "System Archive Missing";
+ status_message = tr("System Archive Missing");
break;
}
@@ -1836,7 +1857,7 @@ void GMainWindow::OnCoreError(Core::System::ResultStatus result, std::string det
message.append(common_message);
answer = QMessageBox::question(this, tr("Shared Fonts Not Found"), message,
QMessageBox::Yes | QMessageBox::No, QMessageBox::No);
- status_message = "Shared Font Missing";
+ status_message = tr("Shared Font Missing");
break;
}
@@ -1852,7 +1873,7 @@ void GMainWindow::OnCoreError(Core::System::ResultStatus result, std::string det
"Continuing emulation may result in crashes, corrupted save data, or other "
"bugs."),
QMessageBox::Yes | QMessageBox::No, QMessageBox::No);
- status_message = "Fatal Error encountered";
+ status_message = tr("Fatal Error encountered");
break;
}
@@ -1903,18 +1924,19 @@ void GMainWindow::OnReinitializeKeys(ReinitializeKeyBehavior behavior) {
};
QString errors;
-
- if (!pdm.HasFuses())
+ if (!pdm.HasFuses()) {
errors += tr("- Missing fuses - Cannot derive SBK\n");
- if (!pdm.HasBoot0())
+ }
+ if (!pdm.HasBoot0()) {
errors += tr("- Missing BOOT0 - Cannot derive master keys\n");
- if (!pdm.HasPackage2())
+ }
+ if (!pdm.HasPackage2()) {
errors += tr("- Missing BCPKG2-1-Normal-Main - Cannot derive general keys\n");
- if (!pdm.HasProdInfo())
+ }
+ if (!pdm.HasProdInfo()) {
errors += tr("- Missing PRODINFO - Cannot derive title keys\n");
-
+ }
if (!errors.isEmpty()) {
-
QMessageBox::warning(
this, tr("Warning Missing Derivation Components"),
tr("The following are missing from your configuration that may hinder key "
@@ -1964,13 +1986,15 @@ std::optional<u64> GMainWindow::SelectRomFSDumpTarget(const FileSys::ContentProv
std::vector<u64> romfs_tids;
romfs_tids.push_back(program_id);
- for (const auto& entry : dlc_match)
+ for (const auto& entry : dlc_match) {
romfs_tids.push_back(entry.title_id);
+ }
if (romfs_tids.size() > 1) {
- QStringList list{"Base"};
- for (std::size_t i = 1; i < romfs_tids.size(); ++i)
+ QStringList list{QStringLiteral("Base")};
+ for (std::size_t i = 1; i < romfs_tids.size(); ++i) {
list.push_back(QStringLiteral("DLC %1").arg(romfs_tids[i] & 0x7FF));
+ }
bool ok;
const auto res = QInputDialog::getItem(
@@ -2082,26 +2106,32 @@ void GMainWindow::filterBarSetChecked(bool state) {
}
void GMainWindow::UpdateUITheme() {
+ const QString default_icons = QStringLiteral(":/icons/default");
+ const QString& current_theme = UISettings::values.theme;
+ const bool is_default_theme = current_theme == QString::fromUtf8(UISettings::themes[0].second);
QStringList theme_paths(default_theme_paths);
- if (UISettings::values.theme != UISettings::themes[0].second &&
- !UISettings::values.theme.isEmpty()) {
- const QString theme_uri(":" + UISettings::values.theme + "/style.qss");
+
+ if (is_default_theme || current_theme.isEmpty()) {
+ qApp->setStyleSheet({});
+ setStyleSheet({});
+ theme_paths.append(default_icons);
+ QIcon::setThemeName(default_icons);
+ } else {
+ const QString theme_uri(QLatin1Char{':'} + current_theme + QStringLiteral("/style.qss"));
QFile f(theme_uri);
if (f.open(QFile::ReadOnly | QFile::Text)) {
QTextStream ts(&f);
qApp->setStyleSheet(ts.readAll());
- GMainWindow::setStyleSheet(ts.readAll());
+ setStyleSheet(ts.readAll());
} else {
LOG_ERROR(Frontend, "Unable to set style, stylesheet file not found");
}
- theme_paths.append(QStringList{":/icons/default", ":/icons/" + UISettings::values.theme});
- QIcon::setThemeName(":/icons/" + UISettings::values.theme);
- } else {
- qApp->setStyleSheet("");
- GMainWindow::setStyleSheet("");
- theme_paths.append(QStringList{":/icons/default"});
- QIcon::setThemeName(":/icons/default");
+
+ const QString theme_name = QStringLiteral(":/icons/") + current_theme;
+ theme_paths.append({default_icons, theme_name});
+ QIcon::setThemeName(theme_name);
}
+
QIcon::setThemeSearchPaths(theme_paths);
emit UpdateThemedIcons();
}
@@ -2129,8 +2159,8 @@ int main(int argc, char* argv[]) {
SCOPE_EXIT({ MicroProfileShutdown(); });
// Init settings params
- QCoreApplication::setOrganizationName("yuzu team");
- QCoreApplication::setApplicationName("yuzu");
+ QCoreApplication::setOrganizationName(QStringLiteral("yuzu team"));
+ QCoreApplication::setApplicationName(QStringLiteral("yuzu"));
// Enables the core to make the qt created contexts current on std::threads
QCoreApplication::setAttribute(Qt::AA_DontCheckOpenGLContextThreadAffinity);
diff --git a/src/yuzu/util/sequence_dialog/sequence_dialog.cpp b/src/yuzu/util/sequence_dialog/sequence_dialog.cpp
index d3edf6ec3..bb5f74ec4 100644
--- a/src/yuzu/util/sequence_dialog/sequence_dialog.cpp
+++ b/src/yuzu/util/sequence_dialog/sequence_dialog.cpp
@@ -9,16 +9,19 @@
SequenceDialog::SequenceDialog(QWidget* parent) : QDialog(parent) {
setWindowTitle(tr("Enter a hotkey"));
- auto* layout = new QVBoxLayout(this);
+ setWindowFlags(windowFlags() & ~Qt::WindowContextHelpButtonHint);
+
key_sequence = new QKeySequenceEdit;
- layout->addWidget(key_sequence);
- auto* buttons =
- new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel, Qt::Horizontal);
+
+ auto* const buttons = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel);
buttons->setCenterButtons(true);
+
+ auto* const layout = new QVBoxLayout(this);
+ layout->addWidget(key_sequence);
layout->addWidget(buttons);
+
connect(buttons, &QDialogButtonBox::accepted, this, &QDialog::accept);
connect(buttons, &QDialogButtonBox::rejected, this, &QDialog::reject);
- setWindowFlags(windowFlags() & ~Qt::WindowContextHelpButtonHint);
}
SequenceDialog::~SequenceDialog() = default;