early-access version 3775
This commit is contained in:
parent
6bb3815b76
commit
13b2314b1e
@ -1,7 +1,7 @@
|
|||||||
yuzu emulator early access
|
yuzu emulator early access
|
||||||
=============
|
=============
|
||||||
|
|
||||||
This is the source code for early-access 3774.
|
This is the source code for early-access 3775.
|
||||||
|
|
||||||
## Legal Notice
|
## Legal Notice
|
||||||
|
|
||||||
|
@ -261,10 +261,8 @@ void GDBStub::ExecuteCommand(std::string_view packet, std::vector<DebuggerAction
|
|||||||
const size_t addr{static_cast<size_t>(strtoll(command.data(), nullptr, 16))};
|
const size_t addr{static_cast<size_t>(strtoll(command.data(), nullptr, 16))};
|
||||||
const size_t size{static_cast<size_t>(strtoll(command.data() + sep, nullptr, 16))};
|
const size_t size{static_cast<size_t>(strtoll(command.data() + sep, nullptr, 16))};
|
||||||
|
|
||||||
if (system.ApplicationMemory().IsValidVirtualAddressRange(addr, size)) {
|
std::vector<u8> mem(size);
|
||||||
std::vector<u8> mem(size);
|
if (system.ApplicationMemory().ReadBlock(addr, mem.data(), size)) {
|
||||||
system.ApplicationMemory().ReadBlock(addr, mem.data(), size);
|
|
||||||
|
|
||||||
SendReply(Common::HexToString(mem));
|
SendReply(Common::HexToString(mem));
|
||||||
} else {
|
} else {
|
||||||
SendReply(GDB_STUB_REPLY_ERR);
|
SendReply(GDB_STUB_REPLY_ERR);
|
||||||
@ -281,8 +279,7 @@ void GDBStub::ExecuteCommand(std::string_view packet, std::vector<DebuggerAction
|
|||||||
const auto mem_substr{std::string_view(command).substr(mem_sep)};
|
const auto mem_substr{std::string_view(command).substr(mem_sep)};
|
||||||
const auto mem{Common::HexStringToVector(mem_substr, false)};
|
const auto mem{Common::HexStringToVector(mem_substr, false)};
|
||||||
|
|
||||||
if (system.ApplicationMemory().IsValidVirtualAddressRange(addr, size)) {
|
if (system.ApplicationMemory().WriteBlock(addr, mem.data(), size)) {
|
||||||
system.ApplicationMemory().WriteBlock(addr, mem.data(), size);
|
|
||||||
system.InvalidateCpuInstructionCacheRange(addr, size);
|
system.InvalidateCpuInstructionCacheRange(addr, size);
|
||||||
SendReply(GDB_STUB_REPLY_OK);
|
SendReply(GDB_STUB_REPLY_OK);
|
||||||
} else {
|
} else {
|
||||||
|
@ -8,6 +8,7 @@
|
|||||||
#include "core/hle/kernel/k_process.h"
|
#include "core/hle/kernel/k_process.h"
|
||||||
#include "core/hle/kernel/k_server_session.h"
|
#include "core/hle/kernel/k_server_session.h"
|
||||||
#include "core/hle/kernel/svc.h"
|
#include "core/hle/kernel/svc.h"
|
||||||
|
#include "core/hle/kernel/svc_results.h"
|
||||||
|
|
||||||
namespace Kernel::Svc {
|
namespace Kernel::Svc {
|
||||||
|
|
||||||
@ -49,14 +50,10 @@ Result ReplyAndReceive(Core::System& system, s32* out_index, uint64_t handles_ad
|
|||||||
|
|
||||||
// Copy user handles.
|
// Copy user handles.
|
||||||
if (num_handles > 0) {
|
if (num_handles > 0) {
|
||||||
// Ensure we can try to get the handles.
|
|
||||||
R_UNLESS(GetCurrentMemory(kernel).IsValidVirtualAddressRange(
|
|
||||||
handles_addr, static_cast<u64>(sizeof(Handle) * num_handles)),
|
|
||||||
ResultInvalidPointer);
|
|
||||||
|
|
||||||
// Get the handles.
|
// Get the handles.
|
||||||
GetCurrentMemory(kernel).ReadBlock(handles_addr, handles.data(),
|
R_UNLESS(GetCurrentMemory(kernel).ReadBlock(handles_addr, handles.data(),
|
||||||
sizeof(Handle) * num_handles);
|
sizeof(Handle) * num_handles),
|
||||||
|
ResultInvalidPointer);
|
||||||
|
|
||||||
// Convert the handles to objects.
|
// Convert the handles to objects.
|
||||||
R_UNLESS(handle_table.GetMultipleObjects<KSynchronizationObject>(
|
R_UNLESS(handle_table.GetMultipleObjects<KSynchronizationObject>(
|
||||||
|
@ -7,6 +7,7 @@
|
|||||||
#include "core/hle/kernel/k_process.h"
|
#include "core/hle/kernel/k_process.h"
|
||||||
#include "core/hle/kernel/k_readable_event.h"
|
#include "core/hle/kernel/k_readable_event.h"
|
||||||
#include "core/hle/kernel/svc.h"
|
#include "core/hle/kernel/svc.h"
|
||||||
|
#include "core/hle/kernel/svc_results.h"
|
||||||
|
|
||||||
namespace Kernel::Svc {
|
namespace Kernel::Svc {
|
||||||
|
|
||||||
@ -64,14 +65,10 @@ Result WaitSynchronization(Core::System& system, int32_t* out_index, u64 user_ha
|
|||||||
|
|
||||||
// Copy user handles.
|
// Copy user handles.
|
||||||
if (num_handles > 0) {
|
if (num_handles > 0) {
|
||||||
// Ensure we can try to get the handles.
|
|
||||||
R_UNLESS(GetCurrentMemory(kernel).IsValidVirtualAddressRange(
|
|
||||||
user_handles, static_cast<u64>(sizeof(Handle) * num_handles)),
|
|
||||||
ResultInvalidPointer);
|
|
||||||
|
|
||||||
// Get the handles.
|
// Get the handles.
|
||||||
GetCurrentMemory(kernel).ReadBlock(user_handles, handles.data(),
|
R_UNLESS(GetCurrentMemory(kernel).ReadBlock(user_handles, handles.data(),
|
||||||
sizeof(Handle) * num_handles);
|
sizeof(Handle) * num_handles),
|
||||||
|
ResultInvalidPointer);
|
||||||
|
|
||||||
// Convert the handles to objects.
|
// Convert the handles to objects.
|
||||||
R_UNLESS(handle_table.GetMultipleObjects<KSynchronizationObject>(
|
R_UNLESS(handle_table.GetMultipleObjects<KSynchronizationObject>(
|
||||||
|
@ -496,8 +496,9 @@ public:
|
|||||||
void LoadIdTokenCache(HLERequestContext& ctx) {
|
void LoadIdTokenCache(HLERequestContext& ctx) {
|
||||||
LOG_WARNING(Service_ACC, "(STUBBED) called");
|
LOG_WARNING(Service_ACC, "(STUBBED) called");
|
||||||
|
|
||||||
IPC::ResponseBuilder rb{ctx, 2};
|
IPC::ResponseBuilder rb{ctx, 3};
|
||||||
rb.Push(ResultSuccess);
|
rb.Push(ResultSuccess);
|
||||||
|
rb.Push(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
@ -2,13 +2,48 @@
|
|||||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
|
||||||
#include "core/hle/service/glue/ectx.h"
|
#include "core/hle/service/glue/ectx.h"
|
||||||
|
#include "core/hle/service/ipc_helpers.h"
|
||||||
|
|
||||||
namespace Service::Glue {
|
namespace Service::Glue {
|
||||||
|
|
||||||
|
// This is nn::err::context::IContextRegistrar
|
||||||
|
class IContextRegistrar : public ServiceFramework<IContextRegistrar> {
|
||||||
|
public:
|
||||||
|
IContextRegistrar(Core::System& system_) : ServiceFramework{system_, "IContextRegistrar"} {
|
||||||
|
// clang-format off
|
||||||
|
static const FunctionInfo functions[] = {
|
||||||
|
{0, &IContextRegistrar::Complete, "Complete"},
|
||||||
|
};
|
||||||
|
// clang-format on
|
||||||
|
|
||||||
|
RegisterHandlers(functions);
|
||||||
|
}
|
||||||
|
|
||||||
|
~IContextRegistrar() override = default;
|
||||||
|
|
||||||
|
private:
|
||||||
|
void Complete(HLERequestContext& ctx) {
|
||||||
|
struct InputParameters {
|
||||||
|
u32 unk;
|
||||||
|
};
|
||||||
|
struct OutputParameters {
|
||||||
|
u32 unk;
|
||||||
|
};
|
||||||
|
|
||||||
|
IPC::RequestParser rp{ctx};
|
||||||
|
[[maybe_unused]] auto input = rp.PopRaw<InputParameters>();
|
||||||
|
[[maybe_unused]] auto value = ctx.ReadBuffer();
|
||||||
|
|
||||||
|
IPC::ResponseBuilder rb{ctx, 3};
|
||||||
|
rb.Push(ResultSuccess);
|
||||||
|
rb.Push(0);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
ECTX_AW::ECTX_AW(Core::System& system_) : ServiceFramework{system_, "ectx:aw"} {
|
ECTX_AW::ECTX_AW(Core::System& system_) : ServiceFramework{system_, "ectx:aw"} {
|
||||||
// clang-format off
|
// clang-format off
|
||||||
static const FunctionInfo functions[] = {
|
static const FunctionInfo functions[] = {
|
||||||
{0, nullptr, "CreateContextRegistrar"},
|
{0, &ECTX_AW::CreateContextRegistrar, "CreateContextRegistrar"},
|
||||||
{1, nullptr, "CommitContext"},
|
{1, nullptr, "CommitContext"},
|
||||||
};
|
};
|
||||||
// clang-format on
|
// clang-format on
|
||||||
@ -18,4 +53,10 @@ ECTX_AW::ECTX_AW(Core::System& system_) : ServiceFramework{system_, "ectx:aw"} {
|
|||||||
|
|
||||||
ECTX_AW::~ECTX_AW() = default;
|
ECTX_AW::~ECTX_AW() = default;
|
||||||
|
|
||||||
|
void ECTX_AW::CreateContextRegistrar(HLERequestContext& ctx) {
|
||||||
|
IPC::ResponseBuilder rb{ctx, 2, 0, 1};
|
||||||
|
rb.Push(ResultSuccess);
|
||||||
|
rb.PushIpcInterface<IContextRegistrar>(std::make_shared<IContextRegistrar>(system));
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace Service::Glue
|
} // namespace Service::Glue
|
||||||
|
@ -15,6 +15,9 @@ class ECTX_AW final : public ServiceFramework<ECTX_AW> {
|
|||||||
public:
|
public:
|
||||||
explicit ECTX_AW(Core::System& system_);
|
explicit ECTX_AW(Core::System& system_);
|
||||||
~ECTX_AW() override;
|
~ECTX_AW() override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
void CreateContextRegistrar(HLERequestContext& ctx);
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace Service::Glue
|
} // namespace Service::Glue
|
||||||
|
@ -559,7 +559,7 @@ std::pair<s32, Errno> BSD::PollImpl(std::vector<u8>& write_buffer, std::span<con
|
|||||||
|
|
||||||
const std::optional<FileDescriptor>& descriptor = file_descriptors[pollfd.fd];
|
const std::optional<FileDescriptor>& descriptor = file_descriptors[pollfd.fd];
|
||||||
if (!descriptor) {
|
if (!descriptor) {
|
||||||
LOG_ERROR(Service, "File descriptor handle={} is not allocated", pollfd.fd);
|
LOG_TRACE(Service, "File descriptor handle={} is not allocated", pollfd.fd);
|
||||||
pollfd.revents = PollEvents::Nval;
|
pollfd.revents = PollEvents::Nval;
|
||||||
return {0, Errno::SUCCESS};
|
return {0, Errno::SUCCESS};
|
||||||
}
|
}
|
||||||
|
@ -24,7 +24,7 @@ NSD::NSD(Core::System& system_, const char* name) : ServiceFramework{system_, na
|
|||||||
static const FunctionInfo functions[] = {
|
static const FunctionInfo functions[] = {
|
||||||
{5, nullptr, "GetSettingUrl"},
|
{5, nullptr, "GetSettingUrl"},
|
||||||
{10, nullptr, "GetSettingName"},
|
{10, nullptr, "GetSettingName"},
|
||||||
{11, nullptr, "GetEnvironmentIdentifier"},
|
{11, &NSD::GetEnvironmentIdentifier, "GetEnvironmentIdentifier"},
|
||||||
{12, nullptr, "GetDeviceId"},
|
{12, nullptr, "GetDeviceId"},
|
||||||
{13, nullptr, "DeleteSettings"},
|
{13, nullptr, "DeleteSettings"},
|
||||||
{14, nullptr, "ImportSettings"},
|
{14, nullptr, "ImportSettings"},
|
||||||
@ -103,6 +103,14 @@ void NSD::ResolveEx(HLERequestContext& ctx) {
|
|||||||
rb.Push(ResultSuccess);
|
rb.Push(ResultSuccess);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void NSD::GetEnvironmentIdentifier(HLERequestContext& ctx) {
|
||||||
|
const std::string environment_identifier = "lp1";
|
||||||
|
ctx.WriteBuffer(environment_identifier);
|
||||||
|
|
||||||
|
IPC::ResponseBuilder rb{ctx, 2};
|
||||||
|
rb.Push(ResultSuccess);
|
||||||
|
}
|
||||||
|
|
||||||
void NSD::GetApplicationServerEnvironmentType(HLERequestContext& ctx) {
|
void NSD::GetApplicationServerEnvironmentType(HLERequestContext& ctx) {
|
||||||
IPC::ResponseBuilder rb{ctx, 3};
|
IPC::ResponseBuilder rb{ctx, 3};
|
||||||
rb.Push(ResultSuccess);
|
rb.Push(ResultSuccess);
|
||||||
|
@ -19,6 +19,7 @@ public:
|
|||||||
private:
|
private:
|
||||||
void Resolve(HLERequestContext& ctx);
|
void Resolve(HLERequestContext& ctx);
|
||||||
void ResolveEx(HLERequestContext& ctx);
|
void ResolveEx(HLERequestContext& ctx);
|
||||||
|
void GetEnvironmentIdentifier(HLERequestContext& ctx);
|
||||||
void GetApplicationServerEnvironmentType(HLERequestContext& ctx);
|
void GetApplicationServerEnvironmentType(HLERequestContext& ctx);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -24,7 +24,7 @@ SFDNSRES::SFDNSRES(Core::System& system_) : ServiceFramework{system_, "sfdnsres"
|
|||||||
{2, &SFDNSRES::GetHostByNameRequest, "GetHostByNameRequest"},
|
{2, &SFDNSRES::GetHostByNameRequest, "GetHostByNameRequest"},
|
||||||
{3, nullptr, "GetHostByAddrRequest"},
|
{3, nullptr, "GetHostByAddrRequest"},
|
||||||
{4, nullptr, "GetHostStringErrorRequest"},
|
{4, nullptr, "GetHostStringErrorRequest"},
|
||||||
{5, nullptr, "GetGaiStringErrorRequest"},
|
{5, &SFDNSRES::GetGaiStringErrorRequest, "GetGaiStringErrorRequest"},
|
||||||
{6, &SFDNSRES::GetAddrInfoRequest, "GetAddrInfoRequest"},
|
{6, &SFDNSRES::GetAddrInfoRequest, "GetAddrInfoRequest"},
|
||||||
{7, nullptr, "GetNameInfoRequest"},
|
{7, nullptr, "GetNameInfoRequest"},
|
||||||
{8, nullptr, "RequestCancelHandleRequest"},
|
{8, nullptr, "RequestCancelHandleRequest"},
|
||||||
@ -300,6 +300,20 @@ void SFDNSRES::GetAddrInfoRequest(HLERequestContext& ctx) {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SFDNSRES::GetGaiStringErrorRequest(HLERequestContext& ctx) {
|
||||||
|
struct InputParameters {
|
||||||
|
GetAddrInfoError gai_errno;
|
||||||
|
};
|
||||||
|
IPC::RequestParser rp{ctx};
|
||||||
|
auto input = rp.PopRaw<InputParameters>();
|
||||||
|
|
||||||
|
const std::string result = Translate(input.gai_errno);
|
||||||
|
ctx.WriteBuffer(result);
|
||||||
|
|
||||||
|
IPC::ResponseBuilder rb{ctx, 2};
|
||||||
|
rb.Push(ResultSuccess);
|
||||||
|
}
|
||||||
|
|
||||||
void SFDNSRES::GetAddrInfoRequestWithOptions(HLERequestContext& ctx) {
|
void SFDNSRES::GetAddrInfoRequestWithOptions(HLERequestContext& ctx) {
|
||||||
// Additional options are ignored
|
// Additional options are ignored
|
||||||
auto [data_size, emu_gai_err] = GetAddrInfoRequestImpl(ctx);
|
auto [data_size, emu_gai_err] = GetAddrInfoRequestImpl(ctx);
|
||||||
|
@ -18,6 +18,7 @@ public:
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
void GetHostByNameRequest(HLERequestContext& ctx);
|
void GetHostByNameRequest(HLERequestContext& ctx);
|
||||||
|
void GetGaiStringErrorRequest(HLERequestContext& ctx);
|
||||||
void GetHostByNameRequestWithOptions(HLERequestContext& ctx);
|
void GetHostByNameRequestWithOptions(HLERequestContext& ctx);
|
||||||
void GetAddrInfoRequest(HLERequestContext& ctx);
|
void GetAddrInfoRequest(HLERequestContext& ctx);
|
||||||
void GetAddrInfoRequestWithOptions(HLERequestContext& ctx);
|
void GetAddrInfoRequestWithOptions(HLERequestContext& ctx);
|
||||||
|
@ -81,6 +81,44 @@ GetAddrInfoError Translate(Network::GetAddrInfoError error) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const char* Translate(GetAddrInfoError error) {
|
||||||
|
// https://android.googlesource.com/platform/bionic/+/085543106/libc/dns/net/getaddrinfo.c#254
|
||||||
|
switch (error) {
|
||||||
|
case GetAddrInfoError::SUCCESS:
|
||||||
|
return "Success";
|
||||||
|
case GetAddrInfoError::ADDRFAMILY:
|
||||||
|
return "Address family for hostname not supported";
|
||||||
|
case GetAddrInfoError::AGAIN:
|
||||||
|
return "Temporary failure in name resolution";
|
||||||
|
case GetAddrInfoError::BADFLAGS:
|
||||||
|
return "Invalid value for ai_flags";
|
||||||
|
case GetAddrInfoError::FAIL:
|
||||||
|
return "Non-recoverable failure in name resolution";
|
||||||
|
case GetAddrInfoError::FAMILY:
|
||||||
|
return "ai_family not supported";
|
||||||
|
case GetAddrInfoError::MEMORY:
|
||||||
|
return "Memory allocation failure";
|
||||||
|
case GetAddrInfoError::NODATA:
|
||||||
|
return "No address associated with hostname";
|
||||||
|
case GetAddrInfoError::NONAME:
|
||||||
|
return "hostname nor servname provided, or not known";
|
||||||
|
case GetAddrInfoError::SERVICE:
|
||||||
|
return "servname not supported for ai_socktype";
|
||||||
|
case GetAddrInfoError::SOCKTYPE:
|
||||||
|
return "ai_socktype not supported";
|
||||||
|
case GetAddrInfoError::SYSTEM:
|
||||||
|
return "System error returned in errno";
|
||||||
|
case GetAddrInfoError::BADHINTS:
|
||||||
|
return "Invalid value for hints";
|
||||||
|
case GetAddrInfoError::PROTOCOL:
|
||||||
|
return "Resolved protocol is unknown";
|
||||||
|
case GetAddrInfoError::OVERFLOW_:
|
||||||
|
return "Argument buffer overflow";
|
||||||
|
default:
|
||||||
|
return "Unknown error";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Network::Domain Translate(Domain domain) {
|
Network::Domain Translate(Domain domain) {
|
||||||
switch (domain) {
|
switch (domain) {
|
||||||
case Domain::Unspecified:
|
case Domain::Unspecified:
|
||||||
|
@ -20,6 +20,9 @@ std::pair<s32, Errno> Translate(std::pair<s32, Network::Errno> value);
|
|||||||
/// Translate abstract getaddrinfo error to guest getaddrinfo error
|
/// Translate abstract getaddrinfo error to guest getaddrinfo error
|
||||||
GetAddrInfoError Translate(Network::GetAddrInfoError value);
|
GetAddrInfoError Translate(Network::GetAddrInfoError value);
|
||||||
|
|
||||||
|
/// Translate guest error to string
|
||||||
|
const char* Translate(GetAddrInfoError value);
|
||||||
|
|
||||||
/// Translate guest domain to abstract domain
|
/// Translate guest domain to abstract domain
|
||||||
Network::Domain Translate(Domain domain);
|
Network::Domain Translate(Domain domain);
|
||||||
|
|
||||||
|
@ -183,13 +183,13 @@ struct Memory::Impl {
|
|||||||
return string;
|
return string;
|
||||||
}
|
}
|
||||||
|
|
||||||
void WalkBlock(const Kernel::KProcess& process, const Common::ProcessAddress addr,
|
bool WalkBlock(const Common::ProcessAddress addr, const std::size_t size, auto on_unmapped,
|
||||||
const std::size_t size, auto on_unmapped, auto on_memory, auto on_rasterizer,
|
auto on_memory, auto on_rasterizer, auto increment) {
|
||||||
auto increment) {
|
const auto& page_table = system.ApplicationProcess()->GetPageTable().PageTableImpl();
|
||||||
const auto& page_table = process.GetPageTable().PageTableImpl();
|
|
||||||
std::size_t remaining_size = size;
|
std::size_t remaining_size = size;
|
||||||
std::size_t page_index = addr >> YUZU_PAGEBITS;
|
std::size_t page_index = addr >> YUZU_PAGEBITS;
|
||||||
std::size_t page_offset = addr & YUZU_PAGEMASK;
|
std::size_t page_offset = addr & YUZU_PAGEMASK;
|
||||||
|
bool user_accessible = true;
|
||||||
|
|
||||||
while (remaining_size) {
|
while (remaining_size) {
|
||||||
const std::size_t copy_amount =
|
const std::size_t copy_amount =
|
||||||
@ -200,6 +200,7 @@ struct Memory::Impl {
|
|||||||
const auto [pointer, type] = page_table.pointers[page_index].PointerType();
|
const auto [pointer, type] = page_table.pointers[page_index].PointerType();
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case Common::PageType::Unmapped: {
|
case Common::PageType::Unmapped: {
|
||||||
|
user_accessible = false;
|
||||||
on_unmapped(copy_amount, current_vaddr);
|
on_unmapped(copy_amount, current_vaddr);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -228,13 +229,15 @@ struct Memory::Impl {
|
|||||||
increment(copy_amount);
|
increment(copy_amount);
|
||||||
remaining_size -= copy_amount;
|
remaining_size -= copy_amount;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return user_accessible;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <bool UNSAFE>
|
template <bool UNSAFE>
|
||||||
void ReadBlockImpl(const Kernel::KProcess& process, const Common::ProcessAddress src_addr,
|
bool ReadBlockImpl(const Common::ProcessAddress src_addr, void* dest_buffer,
|
||||||
void* dest_buffer, const std::size_t size) {
|
const std::size_t size) {
|
||||||
WalkBlock(
|
return WalkBlock(
|
||||||
process, src_addr, size,
|
src_addr, size,
|
||||||
[src_addr, size, &dest_buffer](const std::size_t copy_amount,
|
[src_addr, size, &dest_buffer](const std::size_t copy_amount,
|
||||||
const Common::ProcessAddress current_vaddr) {
|
const Common::ProcessAddress current_vaddr) {
|
||||||
LOG_ERROR(HW_Memory,
|
LOG_ERROR(HW_Memory,
|
||||||
@ -257,14 +260,14 @@ struct Memory::Impl {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
void ReadBlock(const Common::ProcessAddress src_addr, void* dest_buffer,
|
bool ReadBlock(const Common::ProcessAddress src_addr, void* dest_buffer,
|
||||||
const std::size_t size) {
|
const std::size_t size) {
|
||||||
ReadBlockImpl<false>(*system.ApplicationProcess(), src_addr, dest_buffer, size);
|
return ReadBlockImpl<false>(src_addr, dest_buffer, size);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ReadBlockUnsafe(const Common::ProcessAddress src_addr, void* dest_buffer,
|
bool ReadBlockUnsafe(const Common::ProcessAddress src_addr, void* dest_buffer,
|
||||||
const std::size_t size) {
|
const std::size_t size) {
|
||||||
ReadBlockImpl<true>(*system.ApplicationProcess(), src_addr, dest_buffer, size);
|
return ReadBlockImpl<true>(src_addr, dest_buffer, size);
|
||||||
}
|
}
|
||||||
|
|
||||||
const u8* GetSpan(const VAddr src_addr, const std::size_t size) const {
|
const u8* GetSpan(const VAddr src_addr, const std::size_t size) const {
|
||||||
@ -284,10 +287,10 @@ struct Memory::Impl {
|
|||||||
}
|
}
|
||||||
|
|
||||||
template <bool UNSAFE>
|
template <bool UNSAFE>
|
||||||
void WriteBlockImpl(const Kernel::KProcess& process, const Common::ProcessAddress dest_addr,
|
bool WriteBlockImpl(const Common::ProcessAddress dest_addr, const void* src_buffer,
|
||||||
const void* src_buffer, const std::size_t size) {
|
const std::size_t size) {
|
||||||
WalkBlock(
|
return WalkBlock(
|
||||||
process, dest_addr, size,
|
dest_addr, size,
|
||||||
[dest_addr, size](const std::size_t copy_amount,
|
[dest_addr, size](const std::size_t copy_amount,
|
||||||
const Common::ProcessAddress current_vaddr) {
|
const Common::ProcessAddress current_vaddr) {
|
||||||
LOG_ERROR(HW_Memory,
|
LOG_ERROR(HW_Memory,
|
||||||
@ -309,20 +312,19 @@ struct Memory::Impl {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
void WriteBlock(const Common::ProcessAddress dest_addr, const void* src_buffer,
|
bool WriteBlock(const Common::ProcessAddress dest_addr, const void* src_buffer,
|
||||||
const std::size_t size) {
|
const std::size_t size) {
|
||||||
WriteBlockImpl<false>(*system.ApplicationProcess(), dest_addr, src_buffer, size);
|
return WriteBlockImpl<false>(dest_addr, src_buffer, size);
|
||||||
}
|
}
|
||||||
|
|
||||||
void WriteBlockUnsafe(const Common::ProcessAddress dest_addr, const void* src_buffer,
|
bool WriteBlockUnsafe(const Common::ProcessAddress dest_addr, const void* src_buffer,
|
||||||
const std::size_t size) {
|
const std::size_t size) {
|
||||||
WriteBlockImpl<true>(*system.ApplicationProcess(), dest_addr, src_buffer, size);
|
return WriteBlockImpl<true>(dest_addr, src_buffer, size);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ZeroBlock(const Kernel::KProcess& process, const Common::ProcessAddress dest_addr,
|
bool ZeroBlock(const Common::ProcessAddress dest_addr, const std::size_t size) {
|
||||||
const std::size_t size) {
|
return WalkBlock(
|
||||||
WalkBlock(
|
dest_addr, size,
|
||||||
process, dest_addr, size,
|
|
||||||
[dest_addr, size](const std::size_t copy_amount,
|
[dest_addr, size](const std::size_t copy_amount,
|
||||||
const Common::ProcessAddress current_vaddr) {
|
const Common::ProcessAddress current_vaddr) {
|
||||||
LOG_ERROR(HW_Memory,
|
LOG_ERROR(HW_Memory,
|
||||||
@ -340,23 +342,23 @@ struct Memory::Impl {
|
|||||||
[](const std::size_t copy_amount) {});
|
[](const std::size_t copy_amount) {});
|
||||||
}
|
}
|
||||||
|
|
||||||
void CopyBlock(const Kernel::KProcess& process, Common::ProcessAddress dest_addr,
|
bool CopyBlock(Common::ProcessAddress dest_addr, Common::ProcessAddress src_addr,
|
||||||
Common::ProcessAddress src_addr, const std::size_t size) {
|
const std::size_t size) {
|
||||||
WalkBlock(
|
return WalkBlock(
|
||||||
process, dest_addr, size,
|
dest_addr, size,
|
||||||
[&](const std::size_t copy_amount, const Common::ProcessAddress current_vaddr) {
|
[&](const std::size_t copy_amount, const Common::ProcessAddress current_vaddr) {
|
||||||
LOG_ERROR(HW_Memory,
|
LOG_ERROR(HW_Memory,
|
||||||
"Unmapped CopyBlock @ 0x{:016X} (start address = 0x{:016X}, size = {})",
|
"Unmapped CopyBlock @ 0x{:016X} (start address = 0x{:016X}, size = {})",
|
||||||
GetInteger(current_vaddr), GetInteger(src_addr), size);
|
GetInteger(current_vaddr), GetInteger(src_addr), size);
|
||||||
ZeroBlock(process, dest_addr, copy_amount);
|
ZeroBlock(dest_addr, copy_amount);
|
||||||
},
|
},
|
||||||
[&](const std::size_t copy_amount, const u8* const src_ptr) {
|
[&](const std::size_t copy_amount, const u8* const src_ptr) {
|
||||||
WriteBlockImpl<false>(process, dest_addr, src_ptr, copy_amount);
|
WriteBlockImpl<false>(dest_addr, src_ptr, copy_amount);
|
||||||
},
|
},
|
||||||
[&](const Common::ProcessAddress current_vaddr, const std::size_t copy_amount,
|
[&](const Common::ProcessAddress current_vaddr, const std::size_t copy_amount,
|
||||||
u8* const host_ptr) {
|
u8* const host_ptr) {
|
||||||
HandleRasterizerDownload(GetInteger(current_vaddr), copy_amount);
|
HandleRasterizerDownload(GetInteger(current_vaddr), copy_amount);
|
||||||
WriteBlockImpl<false>(process, dest_addr, host_ptr, copy_amount);
|
WriteBlockImpl<false>(dest_addr, host_ptr, copy_amount);
|
||||||
},
|
},
|
||||||
[&](const std::size_t copy_amount) {
|
[&](const std::size_t copy_amount) {
|
||||||
dest_addr += copy_amount;
|
dest_addr += copy_amount;
|
||||||
@ -365,13 +367,13 @@ struct Memory::Impl {
|
|||||||
}
|
}
|
||||||
|
|
||||||
template <typename Callback>
|
template <typename Callback>
|
||||||
Result PerformCacheOperation(const Kernel::KProcess& process, Common::ProcessAddress dest_addr,
|
Result PerformCacheOperation(Common::ProcessAddress dest_addr, std::size_t size,
|
||||||
std::size_t size, Callback&& cb) {
|
Callback&& cb) {
|
||||||
class InvalidMemoryException : public std::exception {};
|
class InvalidMemoryException : public std::exception {};
|
||||||
|
|
||||||
try {
|
try {
|
||||||
WalkBlock(
|
WalkBlock(
|
||||||
process, dest_addr, size,
|
dest_addr, size,
|
||||||
[&](const std::size_t block_size, const Common::ProcessAddress current_vaddr) {
|
[&](const std::size_t block_size, const Common::ProcessAddress current_vaddr) {
|
||||||
LOG_ERROR(HW_Memory, "Unmapped cache maintenance @ {:#018X}",
|
LOG_ERROR(HW_Memory, "Unmapped cache maintenance @ {:#018X}",
|
||||||
GetInteger(current_vaddr));
|
GetInteger(current_vaddr));
|
||||||
@ -388,37 +390,34 @@ struct Memory::Impl {
|
|||||||
return ResultSuccess;
|
return ResultSuccess;
|
||||||
}
|
}
|
||||||
|
|
||||||
Result InvalidateDataCache(const Kernel::KProcess& process, Common::ProcessAddress dest_addr,
|
Result InvalidateDataCache(Common::ProcessAddress dest_addr, std::size_t size) {
|
||||||
std::size_t size) {
|
|
||||||
auto on_rasterizer = [&](const Common::ProcessAddress current_vaddr,
|
auto on_rasterizer = [&](const Common::ProcessAddress current_vaddr,
|
||||||
const std::size_t block_size) {
|
const std::size_t block_size) {
|
||||||
// dc ivac: Invalidate to point of coherency
|
// dc ivac: Invalidate to point of coherency
|
||||||
// GPU flush -> CPU invalidate
|
// GPU flush -> CPU invalidate
|
||||||
HandleRasterizerDownload(GetInteger(current_vaddr), block_size);
|
HandleRasterizerDownload(GetInteger(current_vaddr), block_size);
|
||||||
};
|
};
|
||||||
return PerformCacheOperation(process, dest_addr, size, on_rasterizer);
|
return PerformCacheOperation(dest_addr, size, on_rasterizer);
|
||||||
}
|
}
|
||||||
|
|
||||||
Result StoreDataCache(const Kernel::KProcess& process, Common::ProcessAddress dest_addr,
|
Result StoreDataCache(Common::ProcessAddress dest_addr, std::size_t size) {
|
||||||
std::size_t size) {
|
|
||||||
auto on_rasterizer = [&](const Common::ProcessAddress current_vaddr,
|
auto on_rasterizer = [&](const Common::ProcessAddress current_vaddr,
|
||||||
const std::size_t block_size) {
|
const std::size_t block_size) {
|
||||||
// dc cvac: Store to point of coherency
|
// dc cvac: Store to point of coherency
|
||||||
// CPU flush -> GPU invalidate
|
// CPU flush -> GPU invalidate
|
||||||
system.GPU().InvalidateRegion(GetInteger(current_vaddr), block_size);
|
system.GPU().InvalidateRegion(GetInteger(current_vaddr), block_size);
|
||||||
};
|
};
|
||||||
return PerformCacheOperation(process, dest_addr, size, on_rasterizer);
|
return PerformCacheOperation(dest_addr, size, on_rasterizer);
|
||||||
}
|
}
|
||||||
|
|
||||||
Result FlushDataCache(const Kernel::KProcess& process, Common::ProcessAddress dest_addr,
|
Result FlushDataCache(Common::ProcessAddress dest_addr, std::size_t size) {
|
||||||
std::size_t size) {
|
|
||||||
auto on_rasterizer = [&](const Common::ProcessAddress current_vaddr,
|
auto on_rasterizer = [&](const Common::ProcessAddress current_vaddr,
|
||||||
const std::size_t block_size) {
|
const std::size_t block_size) {
|
||||||
// dc civac: Store to point of coherency, and invalidate from cache
|
// dc civac: Store to point of coherency, and invalidate from cache
|
||||||
// CPU flush -> GPU invalidate
|
// CPU flush -> GPU invalidate
|
||||||
system.GPU().InvalidateRegion(GetInteger(current_vaddr), block_size);
|
system.GPU().InvalidateRegion(GetInteger(current_vaddr), block_size);
|
||||||
};
|
};
|
||||||
return PerformCacheOperation(process, dest_addr, size, on_rasterizer);
|
return PerformCacheOperation(dest_addr, size, on_rasterizer);
|
||||||
}
|
}
|
||||||
|
|
||||||
void MarkRegionDebug(u64 vaddr, u64 size, bool debug) {
|
void MarkRegionDebug(u64 vaddr, u64 size, bool debug) {
|
||||||
@ -903,14 +902,14 @@ std::string Memory::ReadCString(Common::ProcessAddress vaddr, std::size_t max_le
|
|||||||
return impl->ReadCString(vaddr, max_length);
|
return impl->ReadCString(vaddr, max_length);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Memory::ReadBlock(const Common::ProcessAddress src_addr, void* dest_buffer,
|
bool Memory::ReadBlock(const Common::ProcessAddress src_addr, void* dest_buffer,
|
||||||
const std::size_t size) {
|
const std::size_t size) {
|
||||||
impl->ReadBlock(src_addr, dest_buffer, size);
|
return impl->ReadBlock(src_addr, dest_buffer, size);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Memory::ReadBlockUnsafe(const Common::ProcessAddress src_addr, void* dest_buffer,
|
bool Memory::ReadBlockUnsafe(const Common::ProcessAddress src_addr, void* dest_buffer,
|
||||||
const std::size_t size) {
|
const std::size_t size) {
|
||||||
impl->ReadBlockUnsafe(src_addr, dest_buffer, size);
|
return impl->ReadBlockUnsafe(src_addr, dest_buffer, size);
|
||||||
}
|
}
|
||||||
|
|
||||||
const u8* Memory::GetSpan(const VAddr src_addr, const std::size_t size) const {
|
const u8* Memory::GetSpan(const VAddr src_addr, const std::size_t size) const {
|
||||||
@ -921,23 +920,23 @@ u8* Memory::GetSpan(const VAddr src_addr, const std::size_t size) {
|
|||||||
return impl->GetSpan(src_addr, size);
|
return impl->GetSpan(src_addr, size);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Memory::WriteBlock(const Common::ProcessAddress dest_addr, const void* src_buffer,
|
bool Memory::WriteBlock(const Common::ProcessAddress dest_addr, const void* src_buffer,
|
||||||
const std::size_t size) {
|
const std::size_t size) {
|
||||||
impl->WriteBlock(dest_addr, src_buffer, size);
|
return impl->WriteBlock(dest_addr, src_buffer, size);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Memory::WriteBlockUnsafe(const Common::ProcessAddress dest_addr, const void* src_buffer,
|
bool Memory::WriteBlockUnsafe(const Common::ProcessAddress dest_addr, const void* src_buffer,
|
||||||
const std::size_t size) {
|
const std::size_t size) {
|
||||||
impl->WriteBlockUnsafe(dest_addr, src_buffer, size);
|
return impl->WriteBlockUnsafe(dest_addr, src_buffer, size);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Memory::CopyBlock(Common::ProcessAddress dest_addr, Common::ProcessAddress src_addr,
|
bool Memory::CopyBlock(Common::ProcessAddress dest_addr, Common::ProcessAddress src_addr,
|
||||||
const std::size_t size) {
|
const std::size_t size) {
|
||||||
impl->CopyBlock(*system.ApplicationProcess(), dest_addr, src_addr, size);
|
return impl->CopyBlock(dest_addr, src_addr, size);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Memory::ZeroBlock(Common::ProcessAddress dest_addr, const std::size_t size) {
|
bool Memory::ZeroBlock(Common::ProcessAddress dest_addr, const std::size_t size) {
|
||||||
impl->ZeroBlock(*system.ApplicationProcess(), dest_addr, size);
|
return impl->ZeroBlock(dest_addr, size);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Memory::SetGPUDirtyManagers(std::span<Core::GPUDirtyMemoryManager> managers) {
|
void Memory::SetGPUDirtyManagers(std::span<Core::GPUDirtyMemoryManager> managers) {
|
||||||
@ -945,15 +944,15 @@ void Memory::SetGPUDirtyManagers(std::span<Core::GPUDirtyMemoryManager> managers
|
|||||||
}
|
}
|
||||||
|
|
||||||
Result Memory::InvalidateDataCache(Common::ProcessAddress dest_addr, const std::size_t size) {
|
Result Memory::InvalidateDataCache(Common::ProcessAddress dest_addr, const std::size_t size) {
|
||||||
return impl->InvalidateDataCache(*system.ApplicationProcess(), dest_addr, size);
|
return impl->InvalidateDataCache(dest_addr, size);
|
||||||
}
|
}
|
||||||
|
|
||||||
Result Memory::StoreDataCache(Common::ProcessAddress dest_addr, const std::size_t size) {
|
Result Memory::StoreDataCache(Common::ProcessAddress dest_addr, const std::size_t size) {
|
||||||
return impl->StoreDataCache(*system.ApplicationProcess(), dest_addr, size);
|
return impl->StoreDataCache(dest_addr, size);
|
||||||
}
|
}
|
||||||
|
|
||||||
Result Memory::FlushDataCache(Common::ProcessAddress dest_addr, const std::size_t size) {
|
Result Memory::FlushDataCache(Common::ProcessAddress dest_addr, const std::size_t size) {
|
||||||
return impl->FlushDataCache(*system.ApplicationProcess(), dest_addr, size);
|
return impl->FlushDataCache(dest_addr, size);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Memory::RasterizerMarkRegionCached(Common::ProcessAddress vaddr, u64 size, bool cached) {
|
void Memory::RasterizerMarkRegionCached(Common::ProcessAddress vaddr, u64 size, bool cached) {
|
||||||
|
@ -24,7 +24,6 @@ class GPUDirtyMemoryManager;
|
|||||||
} // namespace Core
|
} // namespace Core
|
||||||
|
|
||||||
namespace Kernel {
|
namespace Kernel {
|
||||||
class PhysicalMemory;
|
|
||||||
class KProcess;
|
class KProcess;
|
||||||
} // namespace Kernel
|
} // namespace Kernel
|
||||||
|
|
||||||
@ -330,7 +329,7 @@ public:
|
|||||||
* @post The range [dest_buffer, size) contains the read bytes from the
|
* @post The range [dest_buffer, size) contains the read bytes from the
|
||||||
* current process' address space.
|
* current process' address space.
|
||||||
*/
|
*/
|
||||||
void ReadBlock(Common::ProcessAddress src_addr, void* dest_buffer, std::size_t size);
|
bool ReadBlock(Common::ProcessAddress src_addr, void* dest_buffer, std::size_t size);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Reads a contiguous block of bytes from the current process' address space.
|
* Reads a contiguous block of bytes from the current process' address space.
|
||||||
@ -349,7 +348,7 @@ public:
|
|||||||
* @post The range [dest_buffer, size) contains the read bytes from the
|
* @post The range [dest_buffer, size) contains the read bytes from the
|
||||||
* current process' address space.
|
* current process' address space.
|
||||||
*/
|
*/
|
||||||
void ReadBlockUnsafe(Common::ProcessAddress src_addr, void* dest_buffer, std::size_t size);
|
bool ReadBlockUnsafe(Common::ProcessAddress src_addr, void* dest_buffer, std::size_t size);
|
||||||
|
|
||||||
const u8* GetSpan(const VAddr src_addr, const std::size_t size) const;
|
const u8* GetSpan(const VAddr src_addr, const std::size_t size) const;
|
||||||
u8* GetSpan(const VAddr src_addr, const std::size_t size);
|
u8* GetSpan(const VAddr src_addr, const std::size_t size);
|
||||||
@ -373,7 +372,7 @@ public:
|
|||||||
* and will mark that region as invalidated to caches that the active
|
* and will mark that region as invalidated to caches that the active
|
||||||
* graphics backend may be maintaining over the course of execution.
|
* graphics backend may be maintaining over the course of execution.
|
||||||
*/
|
*/
|
||||||
void WriteBlock(Common::ProcessAddress dest_addr, const void* src_buffer, std::size_t size);
|
bool WriteBlock(Common::ProcessAddress dest_addr, const void* src_buffer, std::size_t size);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Writes a range of bytes into the current process' address space at the specified
|
* Writes a range of bytes into the current process' address space at the specified
|
||||||
@ -391,7 +390,7 @@ public:
|
|||||||
* will be ignored and an error will be logged.
|
* will be ignored and an error will be logged.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
void WriteBlockUnsafe(Common::ProcessAddress dest_addr, const void* src_buffer,
|
bool WriteBlockUnsafe(Common::ProcessAddress dest_addr, const void* src_buffer,
|
||||||
std::size_t size);
|
std::size_t size);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -405,7 +404,7 @@ public:
|
|||||||
* @post The range [dest_addr, size) within the process' address space contains the
|
* @post The range [dest_addr, size) within the process' address space contains the
|
||||||
* same data within the range [src_addr, size).
|
* same data within the range [src_addr, size).
|
||||||
*/
|
*/
|
||||||
void CopyBlock(Common::ProcessAddress dest_addr, Common::ProcessAddress src_addr,
|
bool CopyBlock(Common::ProcessAddress dest_addr, Common::ProcessAddress src_addr,
|
||||||
std::size_t size);
|
std::size_t size);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -418,7 +417,7 @@ public:
|
|||||||
* @post The range [dest_addr, size) within the process' address space contains the
|
* @post The range [dest_addr, size) within the process' address space contains the
|
||||||
* value 0.
|
* value 0.
|
||||||
*/
|
*/
|
||||||
void ZeroBlock(Common::ProcessAddress dest_addr, std::size_t size);
|
bool ZeroBlock(Common::ProcessAddress dest_addr, std::size_t size);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Invalidates a range of bytes within the current process' address space at the specified
|
* Invalidates a range of bytes within the current process' address space at the specified
|
||||||
|
@ -8,6 +8,7 @@
|
|||||||
#include "common/fs/fs.h"
|
#include "common/fs/fs.h"
|
||||||
#include "common/fs/path_util.h"
|
#include "common/fs/path_util.h"
|
||||||
#include "common/settings.h"
|
#include "common/settings.h"
|
||||||
|
#include "common/settings_common.h"
|
||||||
#include "core/core.h"
|
#include "core/core.h"
|
||||||
#include "core/hle/service/acc/profile_manager.h"
|
#include "core/hle/service/acc/profile_manager.h"
|
||||||
#include "core/hle/service/hid/controllers/npad.h"
|
#include "core/hle/service/hid/controllers/npad.h"
|
||||||
@ -725,11 +726,21 @@ void Config::ReadMultiplayerValues() {
|
|||||||
qt_config->endGroup();
|
qt_config->endGroup();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Config::ReadNetworkValues() {
|
||||||
|
qt_config->beginGroup(
|
||||||
|
QString::fromUtf8(Settings::TranslateCategory(Settings::Category::Network)));
|
||||||
|
|
||||||
|
ReadCategory(Settings::Category::Network);
|
||||||
|
|
||||||
|
qt_config->endGroup();
|
||||||
|
}
|
||||||
|
|
||||||
void Config::ReadValues() {
|
void Config::ReadValues() {
|
||||||
if (global) {
|
if (global) {
|
||||||
ReadDataStorageValues();
|
ReadDataStorageValues();
|
||||||
ReadDebuggingValues();
|
ReadDebuggingValues();
|
||||||
ReadDisabledAddOnValues();
|
ReadDisabledAddOnValues();
|
||||||
|
ReadNetworkValues();
|
||||||
ReadServiceValues();
|
ReadServiceValues();
|
||||||
ReadUIValues();
|
ReadUIValues();
|
||||||
ReadWebServiceValues();
|
ReadWebServiceValues();
|
||||||
|
@ -98,6 +98,7 @@ private:
|
|||||||
void ReadUILayoutValues();
|
void ReadUILayoutValues();
|
||||||
void ReadWebServiceValues();
|
void ReadWebServiceValues();
|
||||||
void ReadMultiplayerValues();
|
void ReadMultiplayerValues();
|
||||||
|
void ReadNetworkValues();
|
||||||
|
|
||||||
void SaveValues();
|
void SaveValues();
|
||||||
void SavePlayerValue(std::size_t player_index);
|
void SavePlayerValue(std::size_t player_index);
|
||||||
|
@ -23,7 +23,7 @@
|
|||||||
#include <QLineEdit>
|
#include <QLineEdit>
|
||||||
#include <QObject>
|
#include <QObject>
|
||||||
#include <QPushButton>
|
#include <QPushButton>
|
||||||
#include <QRegExp>
|
#include <QRegularExpression>
|
||||||
#include <QSizePolicy>
|
#include <QSizePolicy>
|
||||||
#include <QSlider>
|
#include <QSlider>
|
||||||
#include <QSpinBox>
|
#include <QSpinBox>
|
||||||
@ -295,8 +295,8 @@ QWidget* Widget::CreateHexEdit(std::function<std::string()>& serializer,
|
|||||||
return QString::fromStdString(fmt::format("{:08x}", std::stoul(input)));
|
return QString::fromStdString(fmt::format("{:08x}", std::stoul(input)));
|
||||||
};
|
};
|
||||||
|
|
||||||
QRegExpValidator* regex =
|
QRegularExpressionValidator* regex = new QRegularExpressionValidator(
|
||||||
new QRegExpValidator{QRegExp{QStringLiteral("^[0-9a-fA-F]{0,8}$")}, line_edit};
|
QRegularExpression{QStringLiteral("^[0-9a-fA-F]{0,8}$")}, line_edit);
|
||||||
|
|
||||||
const QString default_val = to_hex(setting.ToString());
|
const QString default_val = to_hex(setting.ToString());
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user