Compare commits
2 Commits
__refs_pul
...
__refs_pul
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
59f2282e70 | ||
|
|
c8ab8a52ef |
12
externals/glad/include/KHR/khrplatform.h
vendored
12
externals/glad/include/KHR/khrplatform.h
vendored
@@ -90,20 +90,12 @@
|
||||
* int arg2) KHRONOS_APIATTRIBUTES;
|
||||
*/
|
||||
|
||||
#if defined(__SCITECH_SNAP__) && !defined(KHRONOS_STATIC)
|
||||
# define KHRONOS_STATIC 1
|
||||
#endif
|
||||
|
||||
/*-------------------------------------------------------------------------
|
||||
* Definition of KHRONOS_APICALL
|
||||
*-------------------------------------------------------------------------
|
||||
* This precedes the return type of the function in the function prototype.
|
||||
*/
|
||||
#if defined(KHRONOS_STATIC)
|
||||
/* If the preprocessor constant KHRONOS_STATIC is defined, make the
|
||||
* header compatible with static linking. */
|
||||
# define KHRONOS_APICALL
|
||||
#elif defined(_WIN32)
|
||||
#if defined(_WIN32) && !defined(__SCITECH_SNAP__)
|
||||
# define KHRONOS_APICALL __declspec(dllimport)
|
||||
#elif defined (__SYMBIAN32__)
|
||||
# define KHRONOS_APICALL IMPORT_C
|
||||
@@ -119,7 +111,7 @@
|
||||
* This follows the return type of the function and precedes the function
|
||||
* name in the function prototype.
|
||||
*/
|
||||
#if defined(_WIN32) && !defined(_WIN32_WCE) && !defined(KHRONOS_STATIC)
|
||||
#if defined(_WIN32) && !defined(_WIN32_WCE) && !defined(__SCITECH_SNAP__)
|
||||
/* Win32 but not WinCE */
|
||||
# define KHRONOS_APIENTRY __stdcall
|
||||
#else
|
||||
|
||||
2388
externals/glad/include/glad/glad.h
vendored
2388
externals/glad/include/glad/glad.h
vendored
File diff suppressed because one or more lines are too long
1125
externals/glad/src/glad.c
vendored
1125
externals/glad/src/glad.c
vendored
File diff suppressed because one or more lines are too long
@@ -43,7 +43,7 @@ void SessionRequestHandler::ClientDisconnected(const SharedPtr<ServerSession>& s
|
||||
}
|
||||
|
||||
SharedPtr<WritableEvent> HLERequestContext::SleepClientThread(
|
||||
const std::string& reason, u64 timeout, WakeupCallback&& callback,
|
||||
SharedPtr<Thread> thread, 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,9 +76,8 @@ SharedPtr<WritableEvent> HLERequestContext::SleepClientThread(
|
||||
return writable_event;
|
||||
}
|
||||
|
||||
HLERequestContext::HLERequestContext(SharedPtr<Kernel::ServerSession> server_session,
|
||||
SharedPtr<Thread> thread)
|
||||
: server_session(std::move(server_session)), thread(std::move(thread)) {
|
||||
HLERequestContext::HLERequestContext(SharedPtr<Kernel::ServerSession> server_session)
|
||||
: server_session(std::move(server_session)) {
|
||||
cmd_buf[0] = 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -97,7 +97,7 @@ protected:
|
||||
*/
|
||||
class HLERequestContext {
|
||||
public:
|
||||
explicit HLERequestContext(SharedPtr<ServerSession> session, SharedPtr<Thread> thread);
|
||||
explicit HLERequestContext(SharedPtr<ServerSession> session);
|
||||
~HLERequestContext();
|
||||
|
||||
/// Returns a pointer to the IPC command buffer for this request.
|
||||
@@ -119,6 +119,7 @@ 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.
|
||||
@@ -129,8 +130,8 @@ public:
|
||||
* created.
|
||||
* @returns Event that when signaled will resume the thread and call the callback function.
|
||||
*/
|
||||
SharedPtr<WritableEvent> SleepClientThread(const std::string& reason, u64 timeout,
|
||||
WakeupCallback&& callback,
|
||||
SharedPtr<WritableEvent> SleepClientThread(SharedPtr<Thread> thread, const std::string& reason,
|
||||
u64 timeout, WakeupCallback&& callback,
|
||||
SharedPtr<WritableEvent> writable_event = nullptr);
|
||||
|
||||
/// Populates this context with data from the requesting process/thread.
|
||||
@@ -267,7 +268,6 @@ 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;
|
||||
|
||||
@@ -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, thread);
|
||||
Kernel::HLERequestContext context(this);
|
||||
u32* cmd_buf = (u32*)Memory::GetPointer(thread->GetTLSAddress());
|
||||
context.PopulateFromIncomingCommandBuffer(kernel.CurrentProcess()->GetHandleTable(), cmd_buf);
|
||||
|
||||
|
||||
@@ -556,7 +556,7 @@ private:
|
||||
} else {
|
||||
// Wait the current thread until a buffer becomes available
|
||||
ctx.SleepClientThread(
|
||||
"IHOSBinderDriver::DequeueBuffer", -1,
|
||||
Kernel::GetCurrentThread(), "IHOSBinderDriver::DequeueBuffer", -1,
|
||||
[=](Kernel::SharedPtr<Kernel::Thread> thread, Kernel::HLERequestContext& ctx,
|
||||
Kernel::ThreadWakeupReason reason) {
|
||||
// Repeat TransactParcel DequeueBuffer when a buffer is available
|
||||
|
||||
@@ -529,11 +529,6 @@ union Instruction {
|
||||
BitField<39, 8, Register> gpr39;
|
||||
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;
|
||||
@@ -817,11 +812,13 @@ 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 {
|
||||
@@ -830,11 +827,6 @@ union Instruction {
|
||||
BitField<20, 11, u64> address;
|
||||
} al2p;
|
||||
|
||||
union {
|
||||
BitField<53, 3, UniformType> type;
|
||||
BitField<52, 1, u64> extended;
|
||||
} generic;
|
||||
|
||||
union {
|
||||
BitField<0, 3, u64> pred0;
|
||||
BitField<3, 3, u64> pred3;
|
||||
@@ -1395,12 +1387,10 @@ public:
|
||||
LD_L,
|
||||
LD_S,
|
||||
LD_C,
|
||||
LD, // Load from generic memory
|
||||
LDG, // Load from global memory
|
||||
ST_A,
|
||||
ST_L,
|
||||
ST_S,
|
||||
ST, // Store in generic memory
|
||||
LDG, // Load from global memory
|
||||
STG, // Store in global memory
|
||||
AL2P, // Transforms attribute memory into physical memory
|
||||
TEX,
|
||||
@@ -1668,12 +1658,10 @@ 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("101-------------", Id::ST, Type::Memory, "ST"),
|
||||
INST("1110111011010---", Id::LDG, Type::Memory, "LDG"),
|
||||
INST("1110111011011---", Id::STG, Type::Memory, "STG"),
|
||||
INST("1110111110100---", Id::AL2P, Type::Memory, "AL2P"),
|
||||
INST("110000----111---", Id::TEX, Type::Texture, "TEX"),
|
||||
|
||||
@@ -146,25 +146,12 @@ 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, instr, false);
|
||||
TrackAndGetGlobalMemory(bb, GetRegister(instr.gpr8),
|
||||
static_cast<u32>(instr.ldg.immediate_offset.Value()), false);
|
||||
|
||||
const u32 count = GetUniformTypeElementsCount(type);
|
||||
const u32 count = GetUniformTypeElementsCount(instr.ldg.type);
|
||||
for (u32 i = 0; i < count; ++i) {
|
||||
const Node it_offset = Immediate(i * 4);
|
||||
const Node real_address =
|
||||
@@ -178,6 +165,28 @@ 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");
|
||||
@@ -233,41 +242,6 @@ 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.
|
||||
|
||||
@@ -291,11 +265,9 @@ u32 ShaderIR::DecodeMemory(NodeBlock& bb, u32 pc) {
|
||||
}
|
||||
|
||||
std::tuple<Node, Node, GlobalMemoryBase> ShaderIR::TrackAndGetGlobalMemory(NodeBlock& bb,
|
||||
Instruction instr,
|
||||
Node addr_register,
|
||||
u32 immediate_offset,
|
||||
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);
|
||||
|
||||
@@ -39,8 +39,8 @@ Node ShaderIR::Conditional(Node condition, std::vector<Node>&& code) {
|
||||
return StoreNode(ConditionalNode(condition, std::move(code)));
|
||||
}
|
||||
|
||||
Node ShaderIR::Comment(std::string text) {
|
||||
return StoreNode(CommentNode(std::move(text)));
|
||||
Node ShaderIR::Comment(const std::string& text) {
|
||||
return StoreNode(CommentNode(text));
|
||||
}
|
||||
|
||||
Node ShaderIR::Immediate(u32 value) {
|
||||
|
||||
@@ -663,7 +663,7 @@ private:
|
||||
/// Creates a conditional node
|
||||
Node Conditional(Node condition, std::vector<Node>&& code);
|
||||
/// Creates a commentary
|
||||
Node Comment(std::string text);
|
||||
Node Comment(const std::string& text);
|
||||
/// Creates an u32 immediate
|
||||
Node Immediate(u32 value);
|
||||
/// Creates a s32 immediate
|
||||
@@ -818,8 +818,10 @@ private:
|
||||
std::pair<Node, s64> TrackRegister(const GprNode* tracked, const NodeBlock& code,
|
||||
s64 cursor) const;
|
||||
|
||||
std::tuple<Node, Node, GlobalMemoryBase> TrackAndGetGlobalMemory(
|
||||
NodeBlock& bb, Tegra::Shader::Instruction instr, bool is_write);
|
||||
std::tuple<Node, Node, GlobalMemoryBase> TrackAndGetGlobalMemory(NodeBlock& bb,
|
||||
Node addr_register,
|
||||
u32 immediate_offset,
|
||||
bool is_write);
|
||||
|
||||
template <typename... T>
|
||||
Node Operation(OperationCode code, const T*... operands) {
|
||||
|
||||
@@ -155,10 +155,6 @@ 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)
|
||||
|
||||
@@ -29,13 +29,11 @@ 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(date_time.toString(QStringLiteral("dddd, MMMM d, yyyy")))
|
||||
.arg(date_time.toString(QStringLiteral("h:mm:ss A")))
|
||||
.arg(QDateTime::fromSecsSinceEpoch(time.count()).toString("dddd, MMMM d, yyyy"))
|
||||
.arg(QDateTime::fromSecsSinceEpoch(time.count()).toString("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')));
|
||||
|
||||
@@ -18,30 +18,23 @@ QtSoftwareKeyboardValidator::QtSoftwareKeyboardValidator(
|
||||
: parameters(std::move(parameters)) {}
|
||||
|
||||
QValidator::State QtSoftwareKeyboardValidator::validate(QString& input, int& pos) const {
|
||||
if (input.size() > static_cast<s64>(parameters.max_length)) {
|
||||
if (input.size() > parameters.max_length)
|
||||
return Invalid;
|
||||
}
|
||||
if (parameters.disable_space && input.contains(QLatin1Char{' '})) {
|
||||
if (parameters.disable_space && input.contains(' '))
|
||||
return Invalid;
|
||||
}
|
||||
if (parameters.disable_address && input.contains(QLatin1Char{'@'})) {
|
||||
if (parameters.disable_address && input.contains('@'))
|
||||
return Invalid;
|
||||
}
|
||||
if (parameters.disable_percent && input.contains(QLatin1Char{'%'})) {
|
||||
if (parameters.disable_percent && input.contains('%'))
|
||||
return Invalid;
|
||||
}
|
||||
if (parameters.disable_slash &&
|
||||
(input.contains(QLatin1Char{'/'}) || input.contains(QLatin1Char{'\\'}))) {
|
||||
if (parameters.disable_slash && (input.contains('/') || input.contains('\\')))
|
||||
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 == QLatin1Char{'O'} || c == QLatin1Char{'I'};
|
||||
})) {
|
||||
if (parameters.disable_download_code &&
|
||||
std::any_of(input.begin(), input.end(), [](QChar c) { return c == 'O' || c == 'I'; })) {
|
||||
return Invalid;
|
||||
}
|
||||
|
||||
@@ -149,7 +142,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(std::move(text));
|
||||
text_output(text);
|
||||
}
|
||||
|
||||
void QtSoftwareKeyboard::MainWindowFinishedCheckDialog() {
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
|
||||
#include <QDialog>
|
||||
#include <QValidator>
|
||||
#include "common/assert.h"
|
||||
#include "core/frontend/applets/software_keyboard.h"
|
||||
|
||||
class GMainWindow;
|
||||
|
||||
@@ -11,7 +11,6 @@
|
||||
#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.
|
||||
@@ -207,28 +206,25 @@ const std::array<int, Settings::NativeKeyboard::NumKeyboardMods> Config::default
|
||||
};
|
||||
|
||||
// This shouldn't have anything except static initializers (no functions). So
|
||||
// QKeySequence(...).toString() is NOT ALLOWED HERE.
|
||||
// QKeySequnce(...).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.
|
||||
// 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
|
||||
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}}}};
|
||||
|
||||
void Config::ReadPlayerValues() {
|
||||
for (std::size_t p = 0; p < Settings::values.players.size(); ++p) {
|
||||
@@ -374,21 +370,14 @@ void Config::ReadMouseValues() {
|
||||
}
|
||||
|
||||
void Config::ReadTouchscreenValues() {
|
||||
Settings::values.touchscreen.enabled =
|
||||
ReadSetting(QStringLiteral("touchscreen_enabled"), true).toBool();
|
||||
Settings::values.touchscreen.enabled = ReadSetting("touchscreen_enabled", true).toBool();
|
||||
Settings::values.touchscreen.device =
|
||||
ReadSetting(QStringLiteral("touchscreen_device"), QStringLiteral("engine:emu_window"))
|
||||
.toString()
|
||||
.toStdString();
|
||||
ReadSetting("touchscreen_device", "engine:emu_window").toString().toStdString();
|
||||
|
||||
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();
|
||||
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();
|
||||
}
|
||||
|
||||
void Config::ApplyDefaultProfileIfInputInvalid() {
|
||||
@@ -552,8 +541,8 @@ void Config::ReadRendererValues() {
|
||||
void Config::ReadShortcutValues() {
|
||||
qt_config->beginGroup(QStringLiteral("Shortcuts"));
|
||||
|
||||
for (const auto& [name, group, shortcut] : default_hotkeys) {
|
||||
const auto& [keyseq, context] = shortcut;
|
||||
for (auto [name, group, shortcut] : default_hotkeys) {
|
||||
auto [keyseq, context] = shortcut;
|
||||
qt_config->beginGroup(group);
|
||||
qt_config->beginGroup(name);
|
||||
UISettings::values.shortcuts.push_back(
|
||||
@@ -602,8 +591,7 @@ void Config::ReadUIValues() {
|
||||
qt_config->beginGroup(QStringLiteral("UI"));
|
||||
|
||||
UISettings::values.theme =
|
||||
ReadSetting(QStringLiteral("theme"), QString::fromUtf8(UISettings::themes[0].second))
|
||||
.toString();
|
||||
ReadSetting(QStringLiteral("theme"), UISettings::themes[0].second).toString();
|
||||
UISettings::values.enable_discord_presence =
|
||||
ReadSetting(QStringLiteral("enable_discord_presence"), true).toBool();
|
||||
UISettings::values.screenshot_resolution_factor =
|
||||
@@ -638,7 +626,7 @@ void Config::ReadUIValues() {
|
||||
}
|
||||
|
||||
void Config::ReadUIGamelistValues() {
|
||||
qt_config->beginGroup(QStringLiteral("UIGameList"));
|
||||
qt_config->beginGroup("UIGameList");
|
||||
|
||||
UISettings::values.show_unknown = ReadSetting(QStringLiteral("show_unknown"), true).toBool();
|
||||
UISettings::values.show_add_ons = ReadSetting(QStringLiteral("show_add_ons"), true).toBool();
|
||||
@@ -735,7 +723,7 @@ void Config::SavePlayerValues() {
|
||||
}
|
||||
|
||||
void Config::SaveDebugValues() {
|
||||
WriteSetting(QStringLiteral("debug_pad_enabled"), Settings::values.debug_pad_enabled, false);
|
||||
WriteSetting("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_") +
|
||||
@@ -936,7 +924,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);
|
||||
@@ -973,8 +961,7 @@ void Config::SaveSystemValues() {
|
||||
void Config::SaveUIValues() {
|
||||
qt_config->beginGroup(QStringLiteral("UI"));
|
||||
|
||||
WriteSetting(QStringLiteral("theme"), UISettings::values.theme,
|
||||
QString::fromUtf8(UISettings::themes[0].second));
|
||||
WriteSetting(QStringLiteral("theme"), UISettings::values.theme, UISettings::themes[0].second);
|
||||
WriteSetting(QStringLiteral("enable_discord_presence"),
|
||||
UISettings::values.enable_discord_presence, true);
|
||||
WriteSetting(QStringLiteral("screenshot_resolution_factor"),
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
#include <string>
|
||||
#include <QVariant>
|
||||
#include "core/settings.h"
|
||||
#include "yuzu/ui_settings.h"
|
||||
|
||||
class QSettings;
|
||||
|
||||
@@ -81,6 +82,8 @@ 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;
|
||||
};
|
||||
|
||||
@@ -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 initialization
|
||||
// Scope to contain the QProgressDialog for initalization
|
||||
{
|
||||
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(QStringLiteral("nx_inject.js"));
|
||||
nx_shim.setName("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(key_code));
|
||||
.arg(QString::fromStdString(std::to_string(key_code))));
|
||||
};
|
||||
|
||||
QMessageBox::information(
|
||||
@@ -468,7 +468,7 @@ void GMainWindow::InitializeWidgets() {
|
||||
statusBar()->addPermanentWidget(label, 0);
|
||||
}
|
||||
statusBar()->setVisible(true);
|
||||
setStyleSheet(QStringLiteral("QStatusBar::item{border: none;}"));
|
||||
setStyleSheet("QStatusBar::item{border: none;}");
|
||||
}
|
||||
|
||||
void GMainWindow::InitializeDebugWidgets() {
|
||||
@@ -518,67 +518,58 @@ void GMainWindow::InitializeRecentFileMenuActions() {
|
||||
void GMainWindow::InitializeHotkeys() {
|
||||
hotkey_registry.LoadHotkeys();
|
||||
|
||||
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->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));
|
||||
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", "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();
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
connect(hotkey_registry.GetHotkey(main_window, QStringLiteral("Restart Emulation"), this),
|
||||
&QShortcut::activated, this, [this] {
|
||||
if (!Core::System::GetInstance().IsPoweredOn()) {
|
||||
return;
|
||||
}
|
||||
BootGame(game_path);
|
||||
});
|
||||
connect(hotkey_registry.GetHotkey(main_window, fullscreen, render_window),
|
||||
connect(hotkey_registry.GetHotkey("Main Window", "Restart Emulation", this),
|
||||
&QShortcut::activated, this, [this] {
|
||||
if (!Core::System::GetInstance().IsPoweredOn())
|
||||
return;
|
||||
BootGame(QString(game_path));
|
||||
});
|
||||
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, QStringLiteral("Exit Fullscreen"), this),
|
||||
connect(hotkey_registry.GetHotkey("Main Window", "Exit Fullscreen", this),
|
||||
&QShortcut::activated, this, [&] {
|
||||
if (emulation_running) {
|
||||
ui.action_Fullscreen->setChecked(false);
|
||||
ToggleFullscreen();
|
||||
}
|
||||
});
|
||||
connect(hotkey_registry.GetHotkey(main_window, QStringLiteral("Toggle Speed Limit"), this),
|
||||
connect(hotkey_registry.GetHotkey("Main Window", "Toggle Speed Limit", this),
|
||||
&QShortcut::activated, this, [&] {
|
||||
Settings::values.use_frame_limit = !Settings::values.use_frame_limit;
|
||||
UpdateStatusBar();
|
||||
@@ -587,33 +578,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, QStringLiteral("Increase Speed Limit"), this),
|
||||
connect(hotkey_registry.GetHotkey("Main Window", "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, QStringLiteral("Decrease Speed Limit"), this),
|
||||
connect(hotkey_registry.GetHotkey("Main Window", "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, QStringLiteral("Load Amiibo"), this),
|
||||
&QShortcut::activated, this, [&] {
|
||||
connect(hotkey_registry.GetHotkey("Main Window", "Load Amiibo", this), &QShortcut::activated,
|
||||
this, [&] {
|
||||
if (ui.action_Load_Amiibo->isEnabled()) {
|
||||
OnLoadAmiibo();
|
||||
}
|
||||
});
|
||||
connect(hotkey_registry.GetHotkey(main_window, QStringLiteral("Capture Screenshot"), this),
|
||||
connect(hotkey_registry.GetHotkey("Main Window", "Capture Screenshot", this),
|
||||
&QShortcut::activated, this, [&] {
|
||||
if (emu_thread->IsRunning()) {
|
||||
OnCaptureScreenshot();
|
||||
}
|
||||
});
|
||||
connect(hotkey_registry.GetHotkey(main_window, QStringLiteral("Change Docked Mode"), this),
|
||||
connect(hotkey_registry.GetHotkey("Main Window", "Change Docked Mode", this),
|
||||
&QShortcut::activated, this, [&] {
|
||||
Settings::values.use_docked_mode = !Settings::values.use_docked_mode;
|
||||
OnDockedModeChanged(!Settings::values.use_docked_mode,
|
||||
@@ -714,9 +705,7 @@ void GMainWindow::ConnectMenuEvents() {
|
||||
|
||||
// Fullscreen
|
||||
ui.action_Fullscreen->setShortcut(
|
||||
hotkey_registry
|
||||
.GetHotkey(QStringLiteral("Main Window"), QStringLiteral("Fullscreen"), this)
|
||||
->key());
|
||||
hotkey_registry.GetHotkey("Main Window", "Fullscreen", this)->key());
|
||||
connect(ui.action_Fullscreen, &QAction::triggered, this, &GMainWindow::ToggleFullscreen);
|
||||
|
||||
// Movie
|
||||
@@ -753,33 +742,25 @@ void GMainWindow::OnDisplayTitleBars(bool show) {
|
||||
QStringList GMainWindow::GetUnsupportedGLExtensions() {
|
||||
QStringList unsupported_ext;
|
||||
|
||||
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"));
|
||||
}
|
||||
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");
|
||||
|
||||
// Extensions required to support some texture formats.
|
||||
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"));
|
||||
}
|
||||
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) {
|
||||
for (const QString& ext : unsupported_ext)
|
||||
LOG_CRITICAL(Frontend, "Unsupported GL extension: {}", ext.toStdString());
|
||||
}
|
||||
|
||||
return unsupported_ext;
|
||||
}
|
||||
@@ -801,13 +782,13 @@ bool GMainWindow::LoadROM(const QString& filename) {
|
||||
}
|
||||
}
|
||||
|
||||
const QStringList unsupported_gl_extensions = GetUnsupportedGLExtensions();
|
||||
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(QStringLiteral("<br>")));
|
||||
unsupported_gl_extensions.join("<br>"));
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -1026,7 +1007,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 = QStringLiteral("&%1. %2").arg(i + 1).arg(
|
||||
const QString text = QString("&%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]);
|
||||
@@ -1048,10 +1029,10 @@ void GMainWindow::OnGameListLoadFile(QString game_path) {
|
||||
|
||||
void GMainWindow::OnGameListOpenFolder(u64 program_id, GameListOpenTarget target) {
|
||||
std::string path;
|
||||
QString open_target;
|
||||
std::string open_target;
|
||||
switch (target) {
|
||||
case GameListOpenTarget::SaveData: {
|
||||
open_target = tr("Save Data");
|
||||
open_target = "Save Data";
|
||||
const std::string nand_dir = FileUtil::GetUserPath(FileUtil::UserPath::NANDDir);
|
||||
ASSERT(program_id != 0);
|
||||
|
||||
@@ -1088,7 +1069,7 @@ void GMainWindow::OnGameListOpenFolder(u64 program_id, GameListOpenTarget target
|
||||
break;
|
||||
}
|
||||
case GameListOpenTarget::ModData: {
|
||||
open_target = tr("Mod Data");
|
||||
open_target = "Mod Data";
|
||||
const auto load_dir = FileUtil::GetUserPath(FileUtil::UserPath::LoadDir);
|
||||
path = fmt::format("{}{:016X}", load_dir, program_id);
|
||||
break;
|
||||
@@ -1098,26 +1079,27 @@ 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(open_target),
|
||||
QMessageBox::warning(this,
|
||||
tr("Error Opening %1 Folder").arg(QString::fromStdString(open_target)),
|
||||
tr("Folder does not exist!"));
|
||||
return;
|
||||
}
|
||||
LOG_INFO(Frontend, "Opening {} path for program_id={:016x}", open_target.toStdString(),
|
||||
program_id);
|
||||
LOG_INFO(Frontend, "Opening {} path for program_id={:016x}", open_target, 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 =
|
||||
shader_dir + QStringLiteral("opengl") + QDir::separator() + QStringLiteral("transferable");
|
||||
QString::fromStdString(FileUtil::GetUserPath(FileUtil::UserPath::ShaderDir)) + "opengl" +
|
||||
DIR_SEP + "transferable";
|
||||
|
||||
const QString transferable_shader_cache_file_path =
|
||||
tranferable_shader_cache_folder_path + QDir::separator() +
|
||||
tranferable_shader_cache_folder_path + DIR_SEP +
|
||||
QString::fromStdString(fmt::format("{:016X}.bin", program_id));
|
||||
|
||||
if (!QFile::exists(transferable_shader_cache_file_path)) {
|
||||
@@ -1234,21 +1216,20 @@ void GMainWindow::OnGameListDumpRomFS(u64 program_id, const std::string& game_pa
|
||||
return;
|
||||
}
|
||||
|
||||
bool ok = false;
|
||||
const QStringList selections{tr("Full"), tr("Skeleton")};
|
||||
bool ok;
|
||||
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."),
|
||||
selections, 0, false, &ok);
|
||||
{"Full", "Skeleton"}, 0, false, &ok);
|
||||
if (!ok) {
|
||||
failed();
|
||||
vfs->DeleteDirectory(path);
|
||||
return;
|
||||
}
|
||||
|
||||
const auto full = res == selections.constFirst();
|
||||
const auto full = res == "Full";
|
||||
const auto entry_size = CalculateRomFSEntrySize(extracted, full);
|
||||
|
||||
QProgressDialog progress(tr("Extracting RomFS..."), tr("Cancel"), 0,
|
||||
@@ -1278,11 +1259,10 @@ 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(QStringLiteral("https://yuzu-emu.org/game/") + directory));
|
||||
QDesktopServices::openUrl(QUrl("https://yuzu-emu.org/game/" + directory));
|
||||
}
|
||||
|
||||
void GMainWindow::OnGameListOpenPerGameProperties(const std::string& file) {
|
||||
@@ -1313,9 +1293,7 @@ void GMainWindow::OnGameListOpenPerGameProperties(const std::string& file) {
|
||||
|
||||
void GMainWindow::OnMenuLoadFile() {
|
||||
const QString extensions =
|
||||
QStringLiteral("*.")
|
||||
.append(GameList::supported_file_extensions.join(QStringLiteral(" *.")))
|
||||
.append(QStringLiteral(" main"));
|
||||
QString("*.").append(GameList::supported_file_extensions.join(" *.")).append(" main");
|
||||
const QString file_filter = tr("Switch Executable (%1);;All Files (*.*)",
|
||||
"%1 is an identifier for the Switch executable file extensions.")
|
||||
.arg(extensions);
|
||||
@@ -1339,9 +1317,9 @@ void GMainWindow::OnMenuLoadFolder() {
|
||||
}
|
||||
|
||||
const QDir dir{dir_path};
|
||||
const QStringList matching_main = dir.entryList({QStringLiteral("main")}, QDir::Files);
|
||||
const QStringList matching_main = dir.entryList(QStringList("main"), QDir::Files);
|
||||
if (matching_main.size() == 1) {
|
||||
BootGame(dir.path() + QDir::separator() + matching_main[0]);
|
||||
BootGame(dir.path() + DIR_SEP + matching_main[0]);
|
||||
} else {
|
||||
QMessageBox::warning(this, tr("Invalid Directory Selected"),
|
||||
tr("The directory you have selected does not contain a 'main' file."));
|
||||
@@ -1413,10 +1391,11 @@ void GMainWindow::OnMenuInstallToNAND() {
|
||||
QMessageBox::Yes;
|
||||
};
|
||||
|
||||
if (filename.endsWith(QStringLiteral("xci"), Qt::CaseInsensitive) ||
|
||||
filename.endsWith(QStringLiteral("nsp"), Qt::CaseInsensitive)) {
|
||||
if (filename.endsWith("xci", Qt::CaseInsensitive) ||
|
||||
filename.endsWith("nsp", Qt::CaseInsensitive)) {
|
||||
|
||||
std::shared_ptr<FileSys::NSP> nsp;
|
||||
if (filename.endsWith(QStringLiteral("nsp"), Qt::CaseInsensitive)) {
|
||||
if (filename.endsWith("nsp", Qt::CaseInsensitive)) {
|
||||
nsp = std::make_shared<FileSys::NSP>(
|
||||
vfs->OpenFile(filename.toStdString(), FileSys::Mode::Read));
|
||||
if (nsp->IsExtractedType())
|
||||
@@ -1711,9 +1690,9 @@ void GMainWindow::OnConfigure() {
|
||||
}
|
||||
|
||||
void GMainWindow::OnLoadAmiibo() {
|
||||
const QString extensions{QStringLiteral("*.bin")};
|
||||
const QString extensions{"*.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;
|
||||
@@ -1775,7 +1754,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(QStringLiteral("png"));
|
||||
png_dialog.setDefaultSuffix("png");
|
||||
if (png_dialog.exec()) {
|
||||
const QString path = png_dialog.selectedFiles().first();
|
||||
if (!path.isEmpty()) {
|
||||
@@ -1838,17 +1817,17 @@ void GMainWindow::OnCoreError(Core::System::ResultStatus result, std::string det
|
||||
"data, or other bugs.");
|
||||
switch (result) {
|
||||
case Core::System::ResultStatus::ErrorSystemFiles: {
|
||||
QString message = tr("yuzu was unable to locate a Switch system archive");
|
||||
QString message = "yuzu was unable to locate a Switch system archive";
|
||||
if (!details.empty()) {
|
||||
message.append(tr(": %1. ").arg(QString::fromStdString(details)));
|
||||
message.append(tr(": %1. ").arg(details.c_str()));
|
||||
} else {
|
||||
message.append(tr(". "));
|
||||
message.append(". ");
|
||||
}
|
||||
message.append(common_message);
|
||||
|
||||
answer = QMessageBox::question(this, tr("System Archive Not Found"), message,
|
||||
QMessageBox::Yes | QMessageBox::No, QMessageBox::No);
|
||||
status_message = tr("System Archive Missing");
|
||||
status_message = "System Archive Missing";
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -1857,7 +1836,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 = tr("Shared Font Missing");
|
||||
status_message = "Shared Font Missing";
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -1873,7 +1852,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 = tr("Fatal Error encountered");
|
||||
status_message = "Fatal Error encountered";
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -1924,19 +1903,18 @@ 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 "
|
||||
@@ -1986,15 +1964,13 @@ 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{QStringLiteral("Base")};
|
||||
for (std::size_t i = 1; i < romfs_tids.size(); ++i) {
|
||||
QStringList list{"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(
|
||||
@@ -2106,32 +2082,26 @@ 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 (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"));
|
||||
if (UISettings::values.theme != UISettings::themes[0].second &&
|
||||
!UISettings::values.theme.isEmpty()) {
|
||||
const QString theme_uri(":" + UISettings::values.theme + "/style.qss");
|
||||
QFile f(theme_uri);
|
||||
if (f.open(QFile::ReadOnly | QFile::Text)) {
|
||||
QTextStream ts(&f);
|
||||
qApp->setStyleSheet(ts.readAll());
|
||||
setStyleSheet(ts.readAll());
|
||||
GMainWindow::setStyleSheet(ts.readAll());
|
||||
} else {
|
||||
LOG_ERROR(Frontend, "Unable to set style, stylesheet file not found");
|
||||
}
|
||||
|
||||
const QString theme_name = QStringLiteral(":/icons/") + current_theme;
|
||||
theme_paths.append({default_icons, theme_name});
|
||||
QIcon::setThemeName(theme_name);
|
||||
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");
|
||||
}
|
||||
|
||||
QIcon::setThemeSearchPaths(theme_paths);
|
||||
emit UpdateThemedIcons();
|
||||
}
|
||||
@@ -2159,8 +2129,8 @@ int main(int argc, char* argv[]) {
|
||||
SCOPE_EXIT({ MicroProfileShutdown(); });
|
||||
|
||||
// Init settings params
|
||||
QCoreApplication::setOrganizationName(QStringLiteral("yuzu team"));
|
||||
QCoreApplication::setApplicationName(QStringLiteral("yuzu"));
|
||||
QCoreApplication::setOrganizationName("yuzu team");
|
||||
QCoreApplication::setApplicationName("yuzu");
|
||||
|
||||
// Enables the core to make the qt created contexts current on std::threads
|
||||
QCoreApplication::setAttribute(Qt::AA_DontCheckOpenGLContextThreadAffinity);
|
||||
|
||||
Reference in New Issue
Block a user