early-access version 4116

This commit is contained in:
pineappleEA 2024-02-05 22:01:58 +01:00
parent 3882b7c96c
commit a38db34934
8 changed files with 77 additions and 61 deletions

View file

@ -1,7 +1,7 @@
yuzu emulator early access yuzu emulator early access
============= =============
This is the source code for early-access 4115. This is the source code for early-access 4116.
## Legal Notice ## Legal Notice

View file

@ -11,3 +11,4 @@ type = QT
file_filter = ../../src/android/app/src/main/res/values-<lang>/strings.xml file_filter = ../../src/android/app/src/main/res/values-<lang>/strings.xml
source_file = ../../src/android/app/src/main/res/values/strings.xml source_file = ../../src/android/app/src/main/res/values/strings.xml
type = ANDROID type = ANDROID
lang_map = ja_JP:ja, ko_KR:ko, pt_BR:pt-rBR, pt_PT:pt-rPT, ru_RU:ru, vi_VN:vi, zh_CN:zh-rCN, zh_TW:zh-rTW

View file

@ -186,68 +186,68 @@ static_assert(std::is_trivially_destructible_v<PhysicalAddress>);
static_assert(std::is_trivially_destructible_v<VirtualAddress>); static_assert(std::is_trivially_destructible_v<VirtualAddress>);
static_assert(std::is_trivially_destructible_v<ProcessAddress>); static_assert(std::is_trivially_destructible_v<ProcessAddress>);
static_assert(Null<uint64_t> == 0); static_assert(Null<uint64_t> == 0U);
static_assert(Null<PhysicalAddress> == Null<uint64_t>); static_assert(Null<PhysicalAddress> == Null<uint64_t>);
static_assert(Null<VirtualAddress> == Null<uint64_t>); static_assert(Null<VirtualAddress> == Null<uint64_t>);
static_assert(Null<ProcessAddress> == Null<uint64_t>); static_assert(Null<ProcessAddress> == Null<uint64_t>);
// Constructor/assignment validations. // Constructor/assignment validations.
static_assert([] { static_assert([] {
const PhysicalAddress a(5); const PhysicalAddress a(5U);
PhysicalAddress b(a); PhysicalAddress b(a);
return b; return b;
}() == PhysicalAddress(5)); }() == PhysicalAddress(5U));
static_assert([] { static_assert([] {
const PhysicalAddress a(5); const PhysicalAddress a(5U);
PhysicalAddress b(10); PhysicalAddress b(10U);
b = a; b = a;
return b; return b;
}() == PhysicalAddress(5)); }() == PhysicalAddress(5U));
// Arithmetic validations. // Arithmetic validations.
static_assert(PhysicalAddress(10) + 5 == PhysicalAddress(15)); static_assert(PhysicalAddress(10U) + 5U == PhysicalAddress(15U));
static_assert(PhysicalAddress(10) - 5 == PhysicalAddress(5)); static_assert(PhysicalAddress(10U) - 5U == PhysicalAddress(5U));
static_assert([] { static_assert([] {
PhysicalAddress v(10); PhysicalAddress v(10U);
v += 5; v += 5U;
return v; return v;
}() == PhysicalAddress(15)); }() == PhysicalAddress(15U));
static_assert([] { static_assert([] {
PhysicalAddress v(10); PhysicalAddress v(10U);
v -= 5; v -= 5U;
return v; return v;
}() == PhysicalAddress(5)); }() == PhysicalAddress(5U));
static_assert(PhysicalAddress(10)++ == PhysicalAddress(10)); static_assert(PhysicalAddress(10U)++ == PhysicalAddress(10U));
static_assert(++PhysicalAddress(10) == PhysicalAddress(11)); static_assert(++PhysicalAddress(10U) == PhysicalAddress(11U));
static_assert(PhysicalAddress(10)-- == PhysicalAddress(10)); static_assert(PhysicalAddress(10U)-- == PhysicalAddress(10U));
static_assert(--PhysicalAddress(10) == PhysicalAddress(9)); static_assert(--PhysicalAddress(10U) == PhysicalAddress(9U));
// Logical validations. // Logical validations.
static_assert((PhysicalAddress(0b11111111) >> 1) == 0b01111111); static_assert((PhysicalAddress(0b11111111U) >> 1) == 0b01111111U);
static_assert((PhysicalAddress(0b10101010) >> 1) == 0b01010101); static_assert((PhysicalAddress(0b10101010U) >> 1) == 0b01010101U);
static_assert((PhysicalAddress(0b11111111) << 1) == 0b111111110); static_assert((PhysicalAddress(0b11111111U) << 1) == 0b111111110U);
static_assert((PhysicalAddress(0b01010101) << 1) == 0b10101010); static_assert((PhysicalAddress(0b01010101U) << 1) == 0b10101010U);
static_assert((PhysicalAddress(0b11111111) & 0b01010101) == 0b01010101); static_assert((PhysicalAddress(0b11111111U) & 0b01010101U) == 0b01010101U);
static_assert((PhysicalAddress(0b11111111) & 0b10101010) == 0b10101010); static_assert((PhysicalAddress(0b11111111U) & 0b10101010U) == 0b10101010U);
static_assert((PhysicalAddress(0b01010101) & 0b10101010) == 0b00000000); static_assert((PhysicalAddress(0b01010101U) & 0b10101010U) == 0b00000000U);
static_assert((PhysicalAddress(0b00000000) | 0b01010101) == 0b01010101); static_assert((PhysicalAddress(0b00000000U) | 0b01010101U) == 0b01010101U);
static_assert((PhysicalAddress(0b11111111) | 0b01010101) == 0b11111111); static_assert((PhysicalAddress(0b11111111U) | 0b01010101U) == 0b11111111U);
static_assert((PhysicalAddress(0b10101010) | 0b01010101) == 0b11111111); static_assert((PhysicalAddress(0b10101010U) | 0b01010101U) == 0b11111111U);
// Comparisons. // Comparisons.
static_assert(PhysicalAddress(0) == PhysicalAddress(0)); static_assert(PhysicalAddress(0U) == PhysicalAddress(0U));
static_assert(PhysicalAddress(0) != PhysicalAddress(1)); static_assert(PhysicalAddress(0U) != PhysicalAddress(1U));
static_assert(PhysicalAddress(0) < PhysicalAddress(1)); static_assert(PhysicalAddress(0U) < PhysicalAddress(1U));
static_assert(PhysicalAddress(0) <= PhysicalAddress(1)); static_assert(PhysicalAddress(0U) <= PhysicalAddress(1U));
static_assert(PhysicalAddress(1) > PhysicalAddress(0)); static_assert(PhysicalAddress(1U) > PhysicalAddress(0U));
static_assert(PhysicalAddress(1) >= PhysicalAddress(0)); static_assert(PhysicalAddress(1U) >= PhysicalAddress(0U));
static_assert(!(PhysicalAddress(0) == PhysicalAddress(1))); static_assert(!(PhysicalAddress(0U) == PhysicalAddress(1U)));
static_assert(!(PhysicalAddress(0) != PhysicalAddress(0))); static_assert(!(PhysicalAddress(0U) != PhysicalAddress(0U)));
static_assert(!(PhysicalAddress(1) < PhysicalAddress(0))); static_assert(!(PhysicalAddress(1U) < PhysicalAddress(0U)));
static_assert(!(PhysicalAddress(1) <= PhysicalAddress(0))); static_assert(!(PhysicalAddress(1U) <= PhysicalAddress(0U)));
static_assert(!(PhysicalAddress(0) > PhysicalAddress(1))); static_assert(!(PhysicalAddress(0U) > PhysicalAddress(1U)));
static_assert(!(PhysicalAddress(0) >= PhysicalAddress(1))); static_assert(!(PhysicalAddress(0U) >= PhysicalAddress(1U)));
} // namespace Common } // namespace Common

View file

@ -47,12 +47,23 @@ StandardVmCallbacks::StandardVmCallbacks(System& system_, const CheatProcessMeta
StandardVmCallbacks::~StandardVmCallbacks() = default; StandardVmCallbacks::~StandardVmCallbacks() = default;
void StandardVmCallbacks::MemoryRead(VAddr address, void* data, u64 size) { void StandardVmCallbacks::MemoryReadUnsafe(VAddr address, void* data, u64 size) {
system.ApplicationMemory().ReadBlock(SanitizeAddress(address), data, size); // Return zero on invalid address
if (!IsAddressInRange(address) || !system.ApplicationMemory().IsValidVirtualAddress(address)) {
std::memset(data, 0, size);
return;
}
system.ApplicationMemory().ReadBlock(address, data, size);
} }
void StandardVmCallbacks::MemoryWrite(VAddr address, const void* data, u64 size) { void StandardVmCallbacks::MemoryWriteUnsafe(VAddr address, const void* data, u64 size) {
system.ApplicationMemory().WriteBlock(SanitizeAddress(address), data, size); // Skip invalid memory write address
if (!IsAddressInRange(address) || !system.ApplicationMemory().IsValidVirtualAddress(address)) {
return;
}
system.ApplicationMemory().WriteBlock(address, data, size);
} }
u64 StandardVmCallbacks::HidKeysDown() { u64 StandardVmCallbacks::HidKeysDown() {
@ -82,7 +93,7 @@ void StandardVmCallbacks::CommandLog(std::string_view data) {
data.back() == '\n' ? data.substr(0, data.size() - 1) : data); data.back() == '\n' ? data.substr(0, data.size() - 1) : data);
} }
VAddr StandardVmCallbacks::SanitizeAddress(VAddr in) const { bool StandardVmCallbacks::IsAddressInRange(VAddr in) const {
if ((in < metadata.main_nso_extents.base || if ((in < metadata.main_nso_extents.base ||
in >= metadata.main_nso_extents.base + metadata.main_nso_extents.size) && in >= metadata.main_nso_extents.base + metadata.main_nso_extents.size) &&
(in < metadata.heap_extents.base || (in < metadata.heap_extents.base ||
@ -97,10 +108,10 @@ VAddr StandardVmCallbacks::SanitizeAddress(VAddr in) const {
"the cheat may be incorrect. However, this may be normal early in execution if " "the cheat may be incorrect. However, this may be normal early in execution if "
"the game has not properly set up yet.", "the game has not properly set up yet.",
in); in);
return 0; ///< Invalid addresses will hard crash return false; ///< Invalid addresses will hard crash
} }
return in; return true;
} }
CheatParser::~CheatParser() = default; CheatParser::~CheatParser() = default;

View file

@ -27,14 +27,14 @@ public:
StandardVmCallbacks(System& system_, const CheatProcessMetadata& metadata_); StandardVmCallbacks(System& system_, const CheatProcessMetadata& metadata_);
~StandardVmCallbacks() override; ~StandardVmCallbacks() override;
void MemoryRead(VAddr address, void* data, u64 size) override; void MemoryReadUnsafe(VAddr address, void* data, u64 size) override;
void MemoryWrite(VAddr address, const void* data, u64 size) override; void MemoryWriteUnsafe(VAddr address, const void* data, u64 size) override;
u64 HidKeysDown() override; u64 HidKeysDown() override;
void DebugLog(u8 id, u64 value) override; void DebugLog(u8 id, u64 value) override;
void CommandLog(std::string_view data) override; void CommandLog(std::string_view data) override;
private: private:
VAddr SanitizeAddress(VAddr address) const; bool IsAddressInRange(VAddr address) const;
const CheatProcessMetadata& metadata; const CheatProcessMetadata& metadata;
Core::System& system; Core::System& system;

View file

@ -773,7 +773,7 @@ void DmntCheatVm::Execute(const CheatProcessMetadata& metadata) {
case 2: case 2:
case 4: case 4:
case 8: case 8:
callbacks->MemoryWrite(dst_address, &dst_value, store_static->bit_width); callbacks->MemoryWriteUnsafe(dst_address, &dst_value, store_static->bit_width);
break; break;
} }
} else if (auto begin_cond = std::get_if<BeginConditionalOpcode>(&cur_opcode.opcode)) { } else if (auto begin_cond = std::get_if<BeginConditionalOpcode>(&cur_opcode.opcode)) {
@ -786,7 +786,7 @@ void DmntCheatVm::Execute(const CheatProcessMetadata& metadata) {
case 2: case 2:
case 4: case 4:
case 8: case 8:
callbacks->MemoryRead(src_address, &src_value, begin_cond->bit_width); callbacks->MemoryReadUnsafe(src_address, &src_value, begin_cond->bit_width);
break; break;
} }
// Check against condition. // Check against condition.
@ -857,8 +857,8 @@ void DmntCheatVm::Execute(const CheatProcessMetadata& metadata) {
case 2: case 2:
case 4: case 4:
case 8: case 8:
callbacks->MemoryRead(src_address, &registers[ldr_memory->reg_index], callbacks->MemoryReadUnsafe(src_address, &registers[ldr_memory->reg_index],
ldr_memory->bit_width); ldr_memory->bit_width);
break; break;
} }
} else if (auto str_static = std::get_if<StoreStaticToAddressOpcode>(&cur_opcode.opcode)) { } else if (auto str_static = std::get_if<StoreStaticToAddressOpcode>(&cur_opcode.opcode)) {
@ -874,7 +874,7 @@ void DmntCheatVm::Execute(const CheatProcessMetadata& metadata) {
case 2: case 2:
case 4: case 4:
case 8: case 8:
callbacks->MemoryWrite(dst_address, &dst_value, str_static->bit_width); callbacks->MemoryWriteUnsafe(dst_address, &dst_value, str_static->bit_width);
break; break;
} }
// Increment register if relevant. // Increment register if relevant.
@ -1032,7 +1032,7 @@ void DmntCheatVm::Execute(const CheatProcessMetadata& metadata) {
case 2: case 2:
case 4: case 4:
case 8: case 8:
callbacks->MemoryWrite(dst_address, &dst_value, str_register->bit_width); callbacks->MemoryWriteUnsafe(dst_address, &dst_value, str_register->bit_width);
break; break;
} }
@ -1111,7 +1111,8 @@ void DmntCheatVm::Execute(const CheatProcessMetadata& metadata) {
case 2: case 2:
case 4: case 4:
case 8: case 8:
callbacks->MemoryRead(cond_address, &cond_value, begin_reg_cond->bit_width); callbacks->MemoryReadUnsafe(cond_address, &cond_value,
begin_reg_cond->bit_width);
break; break;
} }
} }
@ -1253,7 +1254,7 @@ void DmntCheatVm::Execute(const CheatProcessMetadata& metadata) {
case 2: case 2:
case 4: case 4:
case 8: case 8:
callbacks->MemoryRead(val_address, &log_value, debug_log->bit_width); callbacks->MemoryReadUnsafe(val_address, &log_value, debug_log->bit_width);
break; break;
} }
} }

View file

@ -266,8 +266,8 @@ public:
public: public:
virtual ~Callbacks(); virtual ~Callbacks();
virtual void MemoryRead(VAddr address, void* data, u64 size) = 0; virtual void MemoryReadUnsafe(VAddr address, void* data, u64 size) = 0;
virtual void MemoryWrite(VAddr address, const void* data, u64 size) = 0; virtual void MemoryWriteUnsafe(VAddr address, const void* data, u64 size) = 0;
virtual u64 HidKeysDown() = 0; virtual u64 HidKeysDown() = 0;

View file

@ -73,8 +73,11 @@ ConfigurePerGame::ConfigurePerGame(QWidget* parent, u64 title_id_, const std::st
ui->tabWidget->addTab(graphics_advanced_tab.get(), tr("Adv. Graphics")); ui->tabWidget->addTab(graphics_advanced_tab.get(), tr("Adv. Graphics"));
ui->tabWidget->addTab(audio_tab.get(), tr("Audio")); ui->tabWidget->addTab(audio_tab.get(), tr("Audio"));
ui->tabWidget->addTab(input_tab.get(), tr("Input Profiles")); ui->tabWidget->addTab(input_tab.get(), tr("Input Profiles"));
// Only show Linux tab on Unix // Only show Linux tab on Unix
linux_tab->setVisible(false);
#ifdef __unix__ #ifdef __unix__
linux_tab->setVisible(true);
ui->tabWidget->addTab(linux_tab.get(), tr("Linux")); ui->tabWidget->addTab(linux_tab.get(), tr("Linux"));
#endif #endif