fix the rebase
This commit is contained in:
parent
d9973ff674
commit
993819f29f
|
|
@ -40,6 +40,7 @@
|
||||||
#include "core/hle/service/am/frontend/applets.h"
|
#include "core/hle/service/am/frontend/applets.h"
|
||||||
#include "core/hle/service/am/process_creation.h"
|
#include "core/hle/service/am/process_creation.h"
|
||||||
#include "core/hle/service/apm/apm_controller.h"
|
#include "core/hle/service/apm/apm_controller.h"
|
||||||
|
#include "core/hle/service/dmnt/cheat_process_manager.h"
|
||||||
#include "core/hle/service/filesystem/filesystem.h"
|
#include "core/hle/service/filesystem/filesystem.h"
|
||||||
#include "core/hle/service/glue/glue_manager.h"
|
#include "core/hle/service/glue/glue_manager.h"
|
||||||
#include "core/hle/service/glue/time/static.h"
|
#include "core/hle/service/glue/time/static.h"
|
||||||
|
|
@ -54,7 +55,6 @@
|
||||||
#include "core/internal_network/network.h"
|
#include "core/internal_network/network.h"
|
||||||
#include "core/loader/loader.h"
|
#include "core/loader/loader.h"
|
||||||
#include "core/memory.h"
|
#include "core/memory.h"
|
||||||
#include "core/memory/cheat_engine.h"
|
|
||||||
#include "core/perf_stats.h"
|
#include "core/perf_stats.h"
|
||||||
#include "core/reporter.h"
|
#include "core/reporter.h"
|
||||||
#include "core/tools/freezer.h"
|
#include "core/tools/freezer.h"
|
||||||
|
|
@ -277,8 +277,17 @@ struct System::Impl {
|
||||||
audio_core.emplace(system);
|
audio_core.emplace(system);
|
||||||
|
|
||||||
service_manager = std::make_shared<Service::SM::ServiceManager>(kernel);
|
service_manager = std::make_shared<Service::SM::ServiceManager>(kernel);
|
||||||
|
|
||||||
|
// Create cheat_manager BEFORE services, as DMNT::LoopProcess needs it
|
||||||
|
cheat_manager = std::make_unique<Service::DMNT::CheatProcessManager>(system);
|
||||||
|
|
||||||
services.emplace(service_manager, system, stop_event.get_token());
|
services.emplace(service_manager, system, stop_event.get_token());
|
||||||
|
|
||||||
|
// Apply any pending cheats that were registered before cheat_manager was initialized
|
||||||
|
if (pending_cheats.has_pending) {
|
||||||
|
ApplyPendingCheats(system);
|
||||||
|
}
|
||||||
|
|
||||||
is_powered_on = true;
|
is_powered_on = true;
|
||||||
exit_locked = false;
|
exit_locked = false;
|
||||||
exit_requested = false;
|
exit_requested = false;
|
||||||
|
|
@ -339,11 +348,6 @@ struct System::Impl {
|
||||||
return init_result;
|
return init_result;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Initialize cheat engine
|
|
||||||
if (cheat_engine) {
|
|
||||||
cheat_engine->Initialize();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Register with applet manager
|
// Register with applet manager
|
||||||
// All threads are started, begin main process execution, now that we're in the clear
|
// All threads are started, begin main process execution, now that we're in the clear
|
||||||
applet_manager.CreateAndInsertByFrontendAppletParameters(std::move(process), params);
|
applet_manager.CreateAndInsertByFrontendAppletParameters(std::move(process), params);
|
||||||
|
|
@ -404,7 +408,6 @@ struct System::Impl {
|
||||||
services.reset();
|
services.reset();
|
||||||
service_manager.reset();
|
service_manager.reset();
|
||||||
fs_controller.Reset();
|
fs_controller.Reset();
|
||||||
cheat_engine.reset();
|
|
||||||
core_timing.ClearPendingEvents();
|
core_timing.ClearPendingEvents();
|
||||||
app_loader.reset();
|
app_loader.reset();
|
||||||
audio_core.reset();
|
audio_core.reset();
|
||||||
|
|
@ -465,7 +468,6 @@ struct System::Impl {
|
||||||
Core::SpeedLimiter speed_limiter;
|
Core::SpeedLimiter speed_limiter;
|
||||||
ExecuteProgramCallback execute_program_callback;
|
ExecuteProgramCallback execute_program_callback;
|
||||||
ExitCallback exit_callback;
|
ExitCallback exit_callback;
|
||||||
|
|
||||||
std::optional<Service::Services> services;
|
std::optional<Service::Services> services;
|
||||||
std::optional<Core::Debugger> debugger;
|
std::optional<Core::Debugger> debugger;
|
||||||
std::optional<Service::KernelHelpers::ServiceContext> general_channel_context;
|
std::optional<Service::KernelHelpers::ServiceContext> general_channel_context;
|
||||||
|
|
@ -474,7 +476,6 @@ struct System::Impl {
|
||||||
std::optional<Tegra::Host1x::Host1x> host1x_core;
|
std::optional<Tegra::Host1x::Host1x> host1x_core;
|
||||||
std::optional<Core::DeviceMemory> device_memory;
|
std::optional<Core::DeviceMemory> device_memory;
|
||||||
std::optional<AudioCore::AudioCore> audio_core;
|
std::optional<AudioCore::AudioCore> audio_core;
|
||||||
std::optional<Memory::CheatEngine> cheat_engine;
|
|
||||||
std::optional<Tools::Freezer> memory_freezer;
|
std::optional<Tools::Freezer> memory_freezer;
|
||||||
std::optional<Tools::RenderdocAPI> renderdoc_api;
|
std::optional<Tools::RenderdocAPI> renderdoc_api;
|
||||||
|
|
||||||
|
|
@ -494,6 +495,17 @@ struct System::Impl {
|
||||||
std::unique_ptr<Tegra::GPU> gpu_core;
|
std::unique_ptr<Tegra::GPU> gpu_core;
|
||||||
std::stop_source stop_event;
|
std::stop_source stop_event;
|
||||||
|
|
||||||
|
/// Cheat Manager (DMNT)
|
||||||
|
std::unique_ptr<Service::DMNT::CheatProcessManager> cheat_manager;
|
||||||
|
/// Pending cheats to register after cheat_manager is initialized
|
||||||
|
struct PendingCheats {
|
||||||
|
std::vector<Service::DMNT::CheatEntry> list;
|
||||||
|
std::array<u8, 32> build_id{};
|
||||||
|
u64 main_region_begin{};
|
||||||
|
u64 main_region_size{};
|
||||||
|
bool has_pending{false};
|
||||||
|
} pending_cheats;
|
||||||
|
|
||||||
mutable std::mutex suspend_guard;
|
mutable std::mutex suspend_guard;
|
||||||
std::mutex general_channel_mutex;
|
std::mutex general_channel_mutex;
|
||||||
std::atomic_bool is_paused{};
|
std::atomic_bool is_paused{};
|
||||||
|
|
@ -511,6 +523,61 @@ struct System::Impl {
|
||||||
general_channel_event.emplace(*general_channel_context);
|
general_channel_event.emplace(*general_channel_context);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ApplyPendingCheats(System& system) {
|
||||||
|
if (!pending_cheats.has_pending || !cheat_manager) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
LOG_DEBUG(Core, "Applying {} pending cheats", pending_cheats.list.size());
|
||||||
|
|
||||||
|
const auto result = cheat_manager->AttachToApplicationProcess(
|
||||||
|
pending_cheats.build_id, pending_cheats.main_region_begin,
|
||||||
|
pending_cheats.main_region_size);
|
||||||
|
|
||||||
|
if (result.IsError()) {
|
||||||
|
LOG_WARNING(Core, "Failed to attach cheat process: result={}", result.raw);
|
||||||
|
pending_cheats = {};
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
LOG_DEBUG(Core, "Cheat process attached successfully");
|
||||||
|
|
||||||
|
for (const auto& entry : pending_cheats.list) {
|
||||||
|
if (entry.cheat_id == 0 && entry.definition.num_opcodes != 0) {
|
||||||
|
LOG_DEBUG(Core, "Setting master cheat '{}' with {} opcodes",
|
||||||
|
entry.definition.readable_name.data(), entry.definition.num_opcodes);
|
||||||
|
const auto set_result = cheat_manager->SetMasterCheat(entry.definition);
|
||||||
|
if (set_result.IsError()) {
|
||||||
|
LOG_WARNING(Core, "Failed to set master cheat: result={}", set_result.raw);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add normal cheats (cheat_id != 0)
|
||||||
|
for (const auto& entry : pending_cheats.list) {
|
||||||
|
if (entry.cheat_id == 0 || entry.definition.num_opcodes == 0) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
u32 assigned_id = 0;
|
||||||
|
LOG_DEBUG(Core, "Adding cheat '{}' (enabled={}, {} opcodes)",
|
||||||
|
entry.definition.readable_name.data(), entry.enabled,
|
||||||
|
entry.definition.num_opcodes);
|
||||||
|
const auto add_result = cheat_manager->AddCheat(assigned_id, entry.enabled,
|
||||||
|
entry.definition);
|
||||||
|
if (add_result.IsError()) {
|
||||||
|
LOG_WARNING(Core,
|
||||||
|
"Failed to add cheat (original_id={} enabled={} name='{}'): result={}",
|
||||||
|
entry.cheat_id, entry.enabled,
|
||||||
|
entry.definition.readable_name.data(), add_result.raw);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Clear pending cheats
|
||||||
|
pending_cheats = {};
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
System::System() : impl{std::make_unique<Impl>(*this)} {}
|
System::System() : impl{std::make_unique<Impl>(*this)} {}
|
||||||
|
|
@ -748,11 +815,61 @@ FileSys::VirtualFilesystem System::GetFilesystem() const {
|
||||||
return impl->virtual_filesystem;
|
return impl->virtual_filesystem;
|
||||||
}
|
}
|
||||||
|
|
||||||
void System::RegisterCheatList(const std::vector<Memory::CheatEntry>& list,
|
void System::RegisterCheatList(const std::vector<Service::DMNT::CheatEntry>& list,
|
||||||
const std::array<u8, 32>& build_id, u64 main_region_begin,
|
const std::array<u8, 32>& build_id, u64 main_region_begin,
|
||||||
u64 main_region_size) {
|
u64 main_region_size) {
|
||||||
impl->cheat_engine.emplace(*this, list, build_id);
|
// If cheat_manager is not yet initialized, cache the cheats for later
|
||||||
impl->cheat_engine->SetMainMemoryParameters(main_region_begin, main_region_size);
|
if (!impl->cheat_manager) {
|
||||||
|
impl->pending_cheats.list = list;
|
||||||
|
impl->pending_cheats.build_id = build_id;
|
||||||
|
impl->pending_cheats.main_region_begin = main_region_begin;
|
||||||
|
impl->pending_cheats.main_region_size = main_region_size;
|
||||||
|
impl->pending_cheats.has_pending = true;
|
||||||
|
LOG_INFO(Core, "Cached {} cheats for later registration", list.size());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Attach cheat process to the current application process
|
||||||
|
const auto result = impl->cheat_manager->AttachToApplicationProcess(build_id, main_region_begin,
|
||||||
|
main_region_size);
|
||||||
|
if (result.IsError()) {
|
||||||
|
LOG_WARNING(Core, "Failed to attach cheat process: result={}", result.raw);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Empty list: nothing more to do
|
||||||
|
if (list.empty()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set master cheat if present (cheat_id == 0)
|
||||||
|
for (const auto& entry : list) {
|
||||||
|
if (entry.cheat_id == 0 && entry.definition.num_opcodes != 0) {
|
||||||
|
const auto set_result = impl->cheat_manager->SetMasterCheat(entry.definition);
|
||||||
|
if (set_result.IsError()) {
|
||||||
|
LOG_WARNING(Core, "Failed to set master cheat: result={}", set_result.raw);
|
||||||
|
}
|
||||||
|
// Only one master cheat allowed
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add normal cheats (cheat_id != 0)
|
||||||
|
for (const auto& entry : list) {
|
||||||
|
if (entry.cheat_id == 0 || entry.definition.num_opcodes == 0) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
u32 assigned_id = 0;
|
||||||
|
const auto add_result = impl->cheat_manager->AddCheat(assigned_id, entry.enabled,
|
||||||
|
entry.definition);
|
||||||
|
if (add_result.IsError()) {
|
||||||
|
LOG_WARNING(Core,
|
||||||
|
"Failed to add cheat (original_id={} enabled={} name='{}'): result={}",
|
||||||
|
entry.cheat_id, entry.enabled,
|
||||||
|
entry.definition.readable_name.data(), add_result.raw);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void System::SetFrontendAppletSet(Service::AM::Frontend::FrontendAppletSet&& set) {
|
void System::SetFrontendAppletSet(Service::AM::Frontend::FrontendAppletSet&& set) {
|
||||||
|
|
@ -896,6 +1013,14 @@ Tools::RenderdocAPI& System::GetRenderdocAPI() {
|
||||||
return *impl->renderdoc_api;
|
return *impl->renderdoc_api;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Service::DMNT::CheatProcessManager& System::GetCheatManager() {
|
||||||
|
return *impl->cheat_manager;
|
||||||
|
}
|
||||||
|
|
||||||
|
const Service::DMNT::CheatProcessManager& System::GetCheatManager() const {
|
||||||
|
return *impl->cheat_manager;
|
||||||
|
}
|
||||||
|
|
||||||
void System::RunServer(std::unique_ptr<Service::ServerManager>&& server_manager) {
|
void System::RunServer(std::unique_ptr<Service::ServerManager>&& server_manager) {
|
||||||
return impl->kernel.RunServer(std::move(server_manager));
|
return impl->kernel.RunServer(std::move(server_manager));
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -90,15 +90,15 @@ std::optional<std::vector<Service::DMNT::CheatEntry>> ReadCheatFileFromFolder(
|
||||||
const auto file = base_path->GetFile(fmt::format("{}.txt", build_id));
|
const auto file = base_path->GetFile(fmt::format("{}.txt", build_id));
|
||||||
|
|
||||||
if (file == nullptr) {
|
if (file == nullptr) {
|
||||||
LOG_INFO(Common_Filesystem, "No cheats file found for title_id={:016X}, build_id={}",
|
LOG_DEBUG(Common_Filesystem, "No cheats file found for title_id={:016X}, build_id={}",
|
||||||
title_id, build_id);
|
title_id, build_id);
|
||||||
return std::nullopt;
|
return std::nullopt;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<u8> data(file->GetSize());
|
std::vector<u8> data(file->GetSize());
|
||||||
if (file->Read(data.data(), data.size()) != data.size()) {
|
if (file->Read(data.data(), data.size()) != data.size()) {
|
||||||
LOG_INFO(Common_Filesystem, "Failed to read cheats file for title_id={:016X}, build_id={}",
|
LOG_WARNING(Common_Filesystem, "Failed to read cheats file for title_id={:016X}, build_id={}",
|
||||||
title_id, build_id);
|
title_id, build_id);
|
||||||
return std::nullopt;
|
return std::nullopt;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -661,7 +661,8 @@ std::vector<Patch> PatchManager::GetPatches(VirtualFile update_raw, const BuildI
|
||||||
.parent_name = ""});
|
.parent_name = ""});
|
||||||
|
|
||||||
// Add individual cheats as sub-entries if we have a build_id
|
// Add individual cheats as sub-entries if we have a build_id
|
||||||
if (has_cheats && has_build_id && !mod_disabled) {
|
// Always show cheats even if mod folder is disabled, so users can enable individual cheats
|
||||||
|
if (has_cheats && has_build_id) {
|
||||||
// Try to read cheat file (uppercase first, then lowercase)
|
// Try to read cheat file (uppercase first, then lowercase)
|
||||||
std::optional<std::vector<Service::DMNT::CheatEntry>> cheat_entries;
|
std::optional<std::vector<Service::DMNT::CheatEntry>> cheat_entries;
|
||||||
if (auto res = ReadCheatFileFromFolder(title_id, build_id, cheats_dir, true)) {
|
if (auto res = ReadCheatFileFromFolder(title_id, build_id, cheats_dir, true)) {
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue