Merge master
This commit is contained in:
+24
-16
@@ -2,8 +2,6 @@
|
||||
// Licensed under GPLv2 or any later version
|
||||
// Refer to the license.txt file included.
|
||||
|
||||
#include <exception>
|
||||
#include <memory>
|
||||
#include <stdexcept>
|
||||
#include <utility>
|
||||
#include <boost/serialization/array.hpp>
|
||||
@@ -16,6 +14,8 @@
|
||||
#include "core/arm/arm_interface.h"
|
||||
#include "core/arm/exclusive_monitor.h"
|
||||
#include "core/hle/service/cam/cam.h"
|
||||
#include "core/hle/service/hid/hid.h"
|
||||
#include "core/hle/service/ir/ir_user.h"
|
||||
#if CITRA_ARCH(x86_64) || CITRA_ARCH(arm64)
|
||||
#include "core/arm/dynarmic/arm_dynarmic.h"
|
||||
#endif
|
||||
@@ -35,9 +35,7 @@
|
||||
#include "core/hle/service/cam/cam.h"
|
||||
#include "core/hle/service/fs/archive.h"
|
||||
#include "core/hle/service/gsp/gsp.h"
|
||||
#include "core/hle/service/hid/hid.h"
|
||||
#include "core/hle/service/ir/ir_rst.h"
|
||||
#include "core/hle/service/ir/ir_user.h"
|
||||
#include "core/hle/service/mic/mic_u.h"
|
||||
#include "core/hle/service/plgldr/plgldr.h"
|
||||
#include "core/hle/service/service.h"
|
||||
@@ -48,6 +46,7 @@
|
||||
#include "core/loader/loader.h"
|
||||
#include "core/movie.h"
|
||||
#include "core/rpc/server.h"
|
||||
#include "core/telemetry_session.h"
|
||||
#include "network/network.h"
|
||||
#include "video_core/custom_textures/custom_tex_manager.h"
|
||||
#include "video_core/renderer_base.h"
|
||||
@@ -72,6 +71,8 @@ Core::Timing& Global() {
|
||||
return System::GetInstance().CoreTiming();
|
||||
}
|
||||
|
||||
System::System() : movie{*this} {}
|
||||
|
||||
System::~System() = default;
|
||||
|
||||
System::ResultStatus System::RunLoop(bool tight_loop) {
|
||||
@@ -85,7 +86,7 @@ System::ResultStatus System::RunLoop(bool tight_loop) {
|
||||
if (thread && running_core) {
|
||||
running_core->SaveContext(thread->context);
|
||||
}
|
||||
GDBStub::HandlePacket();
|
||||
GDBStub::HandlePacket(*this);
|
||||
|
||||
// If the loop is halted and we want to step, use a tiny (1) number of instructions to
|
||||
// execute. Otherwise, get out of the loop function.
|
||||
@@ -320,12 +321,12 @@ System::ResultStatus System::Load(Frontend::EmuWindow& emu_window, const std::st
|
||||
cheat_engine = std::make_unique<Cheats::CheatEngine>(title_id, *this);
|
||||
perf_stats = std::make_unique<PerfStats>(title_id);
|
||||
|
||||
if (Settings::values.dump_textures) {
|
||||
custom_tex_manager->PrepareDumping(title_id);
|
||||
}
|
||||
if (Settings::values.custom_textures) {
|
||||
custom_tex_manager->FindCustomTextures();
|
||||
}
|
||||
if (Settings::values.dump_textures) {
|
||||
custom_tex_manager->WriteConfig();
|
||||
}
|
||||
|
||||
status = ResultStatus::Success;
|
||||
m_emu_window = &emu_window;
|
||||
@@ -367,12 +368,13 @@ System::ResultStatus System::Init(Frontend::EmuWindow& emu_window,
|
||||
const Kernel::New3dsHwCapabilities& n3ds_hw_caps, u32 num_cores) {
|
||||
LOG_DEBUG(HW_Memory, "initialized OK");
|
||||
|
||||
memory = std::make_unique<Memory::MemorySystem>();
|
||||
memory = std::make_unique<Memory::MemorySystem>(*this);
|
||||
|
||||
timing = std::make_unique<Timing>(num_cores, Settings::values.cpu_clock_percentage.GetValue());
|
||||
|
||||
kernel = std::make_unique<Kernel::KernelSystem>(
|
||||
*memory, *timing, [this] { PrepareReschedule(); }, memory_mode, num_cores, n3ds_hw_caps);
|
||||
*memory, *timing, [this] { PrepareReschedule(); }, memory_mode, num_cores, n3ds_hw_caps,
|
||||
movie.GetOverrideInitTime());
|
||||
|
||||
exclusive_monitor = MakeExclusiveMonitor(*memory, num_cores);
|
||||
cpu_cores.reserve(num_cores);
|
||||
@@ -508,6 +510,14 @@ const VideoCore::CustomTexManager& System::CustomTexManager() const {
|
||||
return *custom_tex_manager;
|
||||
}
|
||||
|
||||
Core::Movie& System::Movie() {
|
||||
return movie;
|
||||
}
|
||||
|
||||
const Core::Movie& System::Movie() const {
|
||||
return movie;
|
||||
}
|
||||
|
||||
void System::RegisterMiiSelector(std::shared_ptr<Frontend::MiiSelector> mii_selector) {
|
||||
registered_mii_selector = std::move(mii_selector);
|
||||
}
|
||||
@@ -617,16 +627,14 @@ void System::ApplySettings() {
|
||||
if (VideoCore::g_renderer) {
|
||||
auto& settings = VideoCore::g_renderer->Settings();
|
||||
settings.bg_color_update_requested = true;
|
||||
settings.sampler_update_requested = true;
|
||||
settings.shader_update_requested = true;
|
||||
settings.texture_filter_update_requested = true;
|
||||
}
|
||||
|
||||
if (IsPoweredOn()) {
|
||||
CoreTiming().UpdateClockSpeed(Settings::values.cpu_clock_percentage.GetValue());
|
||||
Core::DSP().SetSink(Settings::values.output_type.GetValue(),
|
||||
Settings::values.output_device.GetValue());
|
||||
Core::DSP().EnableStretching(Settings::values.enable_audio_stretching.GetValue());
|
||||
dsp_core->SetSink(Settings::values.output_type.GetValue(),
|
||||
Settings::values.output_device.GetValue());
|
||||
dsp_core->EnableStretching(Settings::values.enable_audio_stretching.GetValue());
|
||||
|
||||
auto hid = Service::HID::GetModule(*this);
|
||||
if (hid) {
|
||||
@@ -704,7 +712,7 @@ void System::serialize(Archive& ar, const unsigned int file_version) {
|
||||
ar&* kernel.get();
|
||||
VideoCore::serialize(ar, file_version);
|
||||
if (file_version >= 1) {
|
||||
ar& Movie::GetInstance();
|
||||
ar& movie;
|
||||
}
|
||||
|
||||
// This needs to be set from somewhere - might as well be here!
|
||||
|
||||
+26
-10
@@ -10,18 +10,17 @@
|
||||
#include <string>
|
||||
#include <boost/serialization/version.hpp>
|
||||
#include "common/common_types.h"
|
||||
#include "core/frontend/applets/mii_selector.h"
|
||||
#include "core/frontend/applets/swkbd.h"
|
||||
#include "core/loader/loader.h"
|
||||
#include "core/memory.h"
|
||||
#include "core/arm/arm_interface.h"
|
||||
#include "core/movie.h"
|
||||
#include "core/perf_stats.h"
|
||||
#include "core/telemetry_session.h"
|
||||
|
||||
class ARM_Interface;
|
||||
|
||||
namespace Frontend {
|
||||
class EmuWindow;
|
||||
class ImageInterface;
|
||||
class MiiSelector;
|
||||
class SoftwareKeyboard;
|
||||
} // namespace Frontend
|
||||
|
||||
namespace Memory {
|
||||
@@ -47,7 +46,9 @@ class ArchiveManager;
|
||||
|
||||
namespace Kernel {
|
||||
class KernelSystem;
|
||||
}
|
||||
struct New3dsHwCapabilities;
|
||||
enum class MemoryMode : u8;
|
||||
} // namespace Kernel
|
||||
|
||||
namespace Cheats {
|
||||
class CheatEngine;
|
||||
@@ -62,8 +63,13 @@ class CustomTexManager;
|
||||
class RendererBase;
|
||||
} // namespace VideoCore
|
||||
|
||||
namespace Loader {
|
||||
class AppLoader;
|
||||
}
|
||||
|
||||
namespace Core {
|
||||
|
||||
class TelemetrySession;
|
||||
class ExclusiveMonitor;
|
||||
class Timing;
|
||||
|
||||
@@ -95,6 +101,7 @@ public:
|
||||
ErrorUnknown ///< Any other error
|
||||
};
|
||||
|
||||
explicit System();
|
||||
~System();
|
||||
|
||||
/**
|
||||
@@ -187,6 +194,10 @@ public:
|
||||
return *cpu_cores[core_id];
|
||||
};
|
||||
|
||||
[[nodiscard]] const ARM_Interface& GetCore(u32 core_id) const {
|
||||
return *cpu_cores[core_id];
|
||||
};
|
||||
|
||||
[[nodiscard]] u32 GetNumCores() const {
|
||||
return static_cast<u32>(cpu_cores.size());
|
||||
}
|
||||
@@ -258,6 +269,12 @@ public:
|
||||
/// Gets a const reference to the custom texture cache system
|
||||
[[nodiscard]] const VideoCore::CustomTexManager& CustomTexManager() const;
|
||||
|
||||
/// Gets a reference to the movie recorder
|
||||
[[nodiscard]] Core::Movie& Movie();
|
||||
|
||||
/// Gets a const reference to the movie recorder
|
||||
[[nodiscard]] const Core::Movie& Movie() const;
|
||||
|
||||
/// Video Dumper interface
|
||||
|
||||
void RegisterVideoDumper(std::shared_ptr<VideoDumper::Backend> video_dumper);
|
||||
@@ -373,6 +390,9 @@ private:
|
||||
std::shared_ptr<Frontend::MiiSelector> registered_mii_selector;
|
||||
std::shared_ptr<Frontend::SoftwareKeyboard> registered_swkbd;
|
||||
|
||||
/// Movie recorder
|
||||
Core::Movie movie;
|
||||
|
||||
/// Cheats manager
|
||||
std::unique_ptr<Cheats::CheatEngine> cheat_engine;
|
||||
|
||||
@@ -435,10 +455,6 @@ private:
|
||||
return System::GetInstance().GetNumCores();
|
||||
}
|
||||
|
||||
[[nodiscard]] inline AudioCore::DspInterface& DSP() {
|
||||
return System::GetInstance().DSP();
|
||||
}
|
||||
|
||||
} // namespace Core
|
||||
|
||||
BOOST_CLASS_VERSION(Core::System, 1)
|
||||
|
||||
@@ -12,8 +12,8 @@
|
||||
#include "common/common_types.h"
|
||||
#include "common/file_util.h"
|
||||
#include "common/swap.h"
|
||||
#include "core/core.h"
|
||||
#include "core/file_sys/romfs_reader.h"
|
||||
#include "core/loader/loader.h"
|
||||
|
||||
enum NCSDContentIndex { Main = 0, Manual = 1, DLP = 2, New3DSUpdate = 6, Update = 7 };
|
||||
|
||||
|
||||
@@ -36,7 +36,6 @@
|
||||
#include "core/gdbstub/gdbstub.h"
|
||||
#include "core/gdbstub/hio.h"
|
||||
#include "core/hle/kernel/process.h"
|
||||
#include "core/loader/loader.h"
|
||||
#include "core/memory.h"
|
||||
|
||||
namespace GDBStub {
|
||||
@@ -1035,7 +1034,7 @@ static void RemoveBreakpoint() {
|
||||
SendReply("OK");
|
||||
}
|
||||
|
||||
void HandlePacket() {
|
||||
void HandlePacket(Core::System& system) {
|
||||
if (!IsConnected()) {
|
||||
if (defer_start) {
|
||||
ToggleServer(true);
|
||||
@@ -1076,7 +1075,7 @@ void HandlePacket() {
|
||||
Continue();
|
||||
return;
|
||||
case 'F':
|
||||
HandleHioReply(command_buffer, command_length);
|
||||
HandleHioReply(system, command_buffer, command_length);
|
||||
break;
|
||||
case 'g':
|
||||
ReadRegisters();
|
||||
|
||||
@@ -10,6 +10,10 @@
|
||||
#include "common/common_types.h"
|
||||
#include "core/hle/kernel/thread.h"
|
||||
|
||||
namespace Core {
|
||||
class System;
|
||||
}
|
||||
|
||||
namespace GDBStub {
|
||||
|
||||
/// Breakpoint Method
|
||||
@@ -70,7 +74,7 @@ void Break(bool is_memory_break = false);
|
||||
bool IsMemoryBreak();
|
||||
|
||||
/// Read and handle packet from gdb client.
|
||||
void HandlePacket();
|
||||
void HandlePacket(Core::System& system);
|
||||
|
||||
/**
|
||||
* Get the nearest breakpoint of the specified type at the given address.
|
||||
|
||||
+11
-11
@@ -54,7 +54,7 @@ static void SendErrorReply(int error_code, int retval = -1) {
|
||||
SendReply(packet.data());
|
||||
}
|
||||
|
||||
void SetHioRequest(const VAddr addr) {
|
||||
void SetHioRequest(Core::System& system, const VAddr addr) {
|
||||
if (!IsServerEnabled()) {
|
||||
LOG_WARNING(Debug_GDBStub, "HIO requested but GDB stub is not running");
|
||||
return;
|
||||
@@ -69,15 +69,15 @@ void SetHioRequest(const VAddr addr) {
|
||||
LOG_INFO(Debug_GDBStub, "overwriting existing HIO request that was not sent yet");
|
||||
}
|
||||
|
||||
auto& memory = Core::System::GetInstance().Memory();
|
||||
const auto process = Core::System::GetInstance().Kernel().GetCurrentProcess();
|
||||
auto& memory = system.Memory();
|
||||
const auto process = system.Kernel().GetCurrentProcess();
|
||||
|
||||
if (!memory.IsValidVirtualAddress(*process, addr)) {
|
||||
LOG_WARNING(Debug_GDBStub, "Invalid address for HIO request");
|
||||
return;
|
||||
}
|
||||
|
||||
memory.ReadBlock(*process, addr, ¤t_hio_request, sizeof(PackedGdbHioRequest));
|
||||
memory.ReadBlock(addr, ¤t_hio_request, sizeof(PackedGdbHioRequest));
|
||||
|
||||
if (current_hio_request.magic != std::array{'G', 'D', 'B', '\0'}) {
|
||||
std::string_view bad_magic{
|
||||
@@ -105,10 +105,11 @@ void SetHioRequest(const VAddr addr) {
|
||||
Break();
|
||||
SetCpuHaltFlag(true);
|
||||
SetCpuStepFlag(false);
|
||||
Core::GetRunningCore().ClearInstructionCache();
|
||||
system.GetRunningCore().ClearInstructionCache();
|
||||
}
|
||||
|
||||
void HandleHioReply(const u8* const command_buffer, const u32 command_length) {
|
||||
void HandleHioReply(Core::System& system, const u8* const command_buffer,
|
||||
const u32 command_length) {
|
||||
if (!IsWaitingForHioReply()) {
|
||||
LOG_WARNING(Debug_GDBStub, "Got HIO reply but never sent a request");
|
||||
return;
|
||||
@@ -176,8 +177,8 @@ void HandleHioReply(const u8* const command_buffer, const u32 command_length) {
|
||||
current_hio_request.retval, current_hio_request.gdb_errno,
|
||||
current_hio_request.ctrl_c);
|
||||
|
||||
const auto process = Core::System::GetInstance().Kernel().GetCurrentProcess();
|
||||
auto& memory = Core::System::GetInstance().Memory();
|
||||
const auto process = system.Kernel().GetCurrentProcess();
|
||||
auto& memory = system.Memory();
|
||||
|
||||
// should have been checked when we first initialized the request,
|
||||
// but just double check again before we write to memory
|
||||
@@ -187,8 +188,7 @@ void HandleHioReply(const u8* const command_buffer, const u32 command_length) {
|
||||
return;
|
||||
}
|
||||
|
||||
memory.WriteBlock(*process, current_hio_request_addr, ¤t_hio_request,
|
||||
sizeof(PackedGdbHioRequest));
|
||||
memory.WriteBlock(current_hio_request_addr, ¤t_hio_request, sizeof(PackedGdbHioRequest));
|
||||
|
||||
current_hio_request = {};
|
||||
current_hio_request_addr = 0;
|
||||
@@ -197,7 +197,7 @@ void HandleHioReply(const u8* const command_buffer, const u32 command_length) {
|
||||
// Restore state from before the request came in
|
||||
SetCpuStepFlag(was_stepping);
|
||||
SetCpuHaltFlag(was_halted);
|
||||
Core::GetRunningCore().ClearInstructionCache();
|
||||
system.GetRunningCore().ClearInstructionCache();
|
||||
}
|
||||
|
||||
bool HandlePendingHioRequestPacket() {
|
||||
|
||||
@@ -6,6 +6,10 @@
|
||||
|
||||
#include "common/common_types.h"
|
||||
|
||||
namespace Core {
|
||||
class System;
|
||||
}
|
||||
|
||||
namespace GDBStub {
|
||||
|
||||
/**
|
||||
@@ -47,7 +51,7 @@ static_assert(sizeof(PackedGdbHioRequest) == 152,
|
||||
*
|
||||
* @param address The memory address of the \ref PackedGdbHioRequest.
|
||||
*/
|
||||
void SetHioRequest(const VAddr address);
|
||||
void SetHioRequest(Core::System& system, const VAddr address);
|
||||
|
||||
/**
|
||||
* If there is a pending HIO request, send it to the client.
|
||||
@@ -59,6 +63,6 @@ bool HandlePendingHioRequestPacket();
|
||||
/**
|
||||
* Process an HIO reply from the client.
|
||||
*/
|
||||
void HandleHioReply(const u8* const command_buffer, const u32 command_length);
|
||||
void HandleHioReply(Core::System& system, const u8* const command_buffer, const u32 command_length);
|
||||
|
||||
} // namespace GDBStub
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
|
||||
#include <algorithm>
|
||||
#include <vector>
|
||||
#include "common/archives.h"
|
||||
#include "common/assert.h"
|
||||
#include "common/common_types.h"
|
||||
#include "core/core.h"
|
||||
|
||||
@@ -25,13 +25,13 @@ namespace Kernel {
|
||||
KernelSystem::KernelSystem(Memory::MemorySystem& memory, Core::Timing& timing,
|
||||
std::function<void()> prepare_reschedule_callback,
|
||||
MemoryMode memory_mode, u32 num_cores,
|
||||
const New3dsHwCapabilities& n3ds_hw_caps)
|
||||
const New3dsHwCapabilities& n3ds_hw_caps, u64 override_init_time)
|
||||
: memory(memory), timing(timing),
|
||||
prepare_reschedule_callback(std::move(prepare_reschedule_callback)), memory_mode(memory_mode),
|
||||
n3ds_hw_caps(n3ds_hw_caps) {
|
||||
std::generate(memory_regions.begin(), memory_regions.end(),
|
||||
[] { return std::make_shared<MemoryRegionInfo>(); });
|
||||
MemoryInit(memory_mode, n3ds_hw_caps.memory_mode);
|
||||
MemoryInit(memory_mode, n3ds_hw_caps.memory_mode, override_init_time);
|
||||
|
||||
resource_limits = std::make_unique<ResourceLimitList>(*this);
|
||||
for (u32 core_id = 0; core_id < num_cores; ++core_id) {
|
||||
|
||||
@@ -134,7 +134,8 @@ class KernelSystem {
|
||||
public:
|
||||
explicit KernelSystem(Memory::MemorySystem& memory, Core::Timing& timing,
|
||||
std::function<void()> prepare_reschedule_callback, MemoryMode memory_mode,
|
||||
u32 num_cores, const New3dsHwCapabilities& n3ds_hw_caps);
|
||||
u32 num_cores, const New3dsHwCapabilities& n3ds_hw_caps,
|
||||
u64 override_init_time = 0);
|
||||
~KernelSystem();
|
||||
|
||||
using PortPair = std::pair<std::shared_ptr<ServerPort>, std::shared_ptr<ClientPort>>;
|
||||
@@ -330,7 +331,7 @@ public:
|
||||
Core::Timing& timing;
|
||||
|
||||
private:
|
||||
void MemoryInit(MemoryMode memory_mode, New3dsMemoryMode n3ds_mode);
|
||||
void MemoryInit(MemoryMode memory_mode, New3dsMemoryMode n3ds_mode, u64 override_init_time);
|
||||
|
||||
std::function<void()> prepare_reschedule_callback;
|
||||
|
||||
|
||||
@@ -37,7 +37,8 @@ static const u32 memory_region_sizes[8][3] = {
|
||||
{0x0B200000, 0x02E00000, 0x02000000}, // 7
|
||||
};
|
||||
|
||||
void KernelSystem::MemoryInit(MemoryMode memory_mode, New3dsMemoryMode n3ds_mode) {
|
||||
void KernelSystem::MemoryInit(MemoryMode memory_mode, New3dsMemoryMode n3ds_mode,
|
||||
u64 override_init_time) {
|
||||
const bool is_new_3ds = Settings::values.is_new_3ds.GetValue();
|
||||
u32 mem_type_index = static_cast<u32>(memory_mode);
|
||||
u32 reported_mem_type = static_cast<u32>(memory_mode);
|
||||
@@ -73,7 +74,7 @@ void KernelSystem::MemoryInit(MemoryMode memory_mode, New3dsMemoryMode n3ds_mode
|
||||
config_mem.sys_mem_alloc = memory_regions[1]->size;
|
||||
config_mem.base_mem_alloc = memory_regions[2]->size;
|
||||
|
||||
shared_page_handler = std::make_shared<SharedPage::Handler>(timing);
|
||||
shared_page_handler = std::make_shared<SharedPage::Handler>(timing, override_init_time);
|
||||
}
|
||||
|
||||
std::shared_ptr<MemoryRegionInfo> KernelSystem::GetMemoryRegion(MemoryRegion region) {
|
||||
|
||||
@@ -19,7 +19,8 @@ namespace boost::serialization {
|
||||
|
||||
template <class Archive>
|
||||
void load_construct_data(Archive& ar, SharedPage::Handler* t, const unsigned int) {
|
||||
::new (t) SharedPage::Handler(Core::System::GetInstance().CoreTiming());
|
||||
::new (t) SharedPage::Handler(Core::System::GetInstance().CoreTiming(),
|
||||
Core::System::GetInstance().Movie().GetOverrideInitTime());
|
||||
}
|
||||
template void load_construct_data<iarchive>(iarchive& ar, SharedPage::Handler* t,
|
||||
const unsigned int);
|
||||
@@ -28,8 +29,7 @@ template void load_construct_data<iarchive>(iarchive& ar, SharedPage::Handler* t
|
||||
|
||||
namespace SharedPage {
|
||||
|
||||
static std::chrono::seconds GetInitTime() {
|
||||
const u64 override_init_time = Core::Movie::GetInstance().GetOverrideInitTime();
|
||||
static std::chrono::seconds GetInitTime(u64 override_init_time) {
|
||||
if (override_init_time != 0) {
|
||||
// Override the clock init time with the one in the movie
|
||||
return std::chrono::seconds(override_init_time);
|
||||
@@ -62,7 +62,7 @@ static std::chrono::seconds GetInitTime() {
|
||||
}
|
||||
}
|
||||
|
||||
Handler::Handler(Core::Timing& timing) : timing(timing) {
|
||||
Handler::Handler(Core::Timing& timing, u64 override_init_time) : timing(timing) {
|
||||
std::memset(&shared_page, 0, sizeof(shared_page));
|
||||
|
||||
shared_page.running_hw = 0x1; // product
|
||||
@@ -76,7 +76,7 @@ Handler::Handler(Core::Timing& timing) : timing(timing) {
|
||||
shared_page.battery_state.is_adapter_connected.Assign(1);
|
||||
shared_page.battery_state.is_charging.Assign(1);
|
||||
|
||||
init_time = GetInitTime();
|
||||
init_time = GetInitTime(override_init_time);
|
||||
|
||||
using namespace std::placeholders;
|
||||
update_time_event = timing.RegisterEvent("SharedPage::UpdateTimeCallback",
|
||||
|
||||
@@ -86,7 +86,7 @@ static_assert(sizeof(SharedPageDef) == Memory::SHARED_PAGE_SIZE,
|
||||
|
||||
class Handler : public BackingMem {
|
||||
public:
|
||||
Handler(Core::Timing& timing);
|
||||
Handler(Core::Timing& timing, u64 override_init_time);
|
||||
|
||||
void SetMacAddress(const MacAddress&);
|
||||
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
#include <algorithm>
|
||||
#include <array>
|
||||
#include <fmt/format.h>
|
||||
#include "common/archives.h"
|
||||
#include "common/logging/log.h"
|
||||
#include "common/microprofile.h"
|
||||
#include "common/scm_rev.h"
|
||||
@@ -38,7 +39,6 @@
|
||||
#include "core/hle/lock.h"
|
||||
#include "core/hle/result.h"
|
||||
#include "core/hle/service/plgldr/plgldr.h"
|
||||
#include "core/hle/service/service.h"
|
||||
|
||||
namespace Kernel {
|
||||
|
||||
@@ -1128,7 +1128,7 @@ void SVC::OutputDebugString(VAddr address, s32 len) {
|
||||
}
|
||||
|
||||
if (len == 0) {
|
||||
GDBStub::SetHioRequest(address);
|
||||
GDBStub::SetHioRequest(system, address);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -1953,12 +1953,12 @@ ResultCode SVC::GetProcessList(s32* process_count, VAddr out_process_array,
|
||||
}
|
||||
|
||||
ResultCode SVC::InvalidateInstructionCacheRange(u32 addr, u32 size) {
|
||||
Core::GetRunningCore().InvalidateCacheRange(addr, size);
|
||||
system.GetRunningCore().InvalidateCacheRange(addr, size);
|
||||
return RESULT_SUCCESS;
|
||||
}
|
||||
|
||||
ResultCode SVC::InvalidateEntireInstructionCache() {
|
||||
Core::GetRunningCore().ClearInstructionCache();
|
||||
system.GetRunningCore().ClearInstructionCache();
|
||||
return RESULT_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
@@ -13,6 +13,7 @@
|
||||
#include <boost/serialization/split_member.hpp>
|
||||
#include "common/common_types.h"
|
||||
#include "common/memory_ref.h"
|
||||
#include "core/hle/kernel/memory.h"
|
||||
#include "core/hle/result.h"
|
||||
#include "core/memory.h"
|
||||
#include "core/mmio.h"
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
|
||||
#include "core/core.h"
|
||||
#include "core/hle/ipc_helpers.h"
|
||||
#include "core/hle/kernel/shared_memory.h"
|
||||
#include "core/hle/service/act/act.h"
|
||||
#include "core/hle/service/act/act_a.h"
|
||||
#include "core/hle/service/act/act_u.h"
|
||||
|
||||
@@ -2,6 +2,8 @@
|
||||
// Licensed under GPLv2 or any later version
|
||||
// Refer to the license.txt file included.
|
||||
|
||||
#include "common/archives.h"
|
||||
#include "common/file_util.h"
|
||||
#include "common/settings.h"
|
||||
#include "core/core.h"
|
||||
#include "core/frontend/input.h"
|
||||
|
||||
@@ -33,6 +33,8 @@
|
||||
#include "core/hle/service/service.h"
|
||||
#include "core/hw/aes/ccm.h"
|
||||
#include "core/hw/aes/key.h"
|
||||
#include "core/loader/loader.h"
|
||||
#include "core/telemetry_session.h"
|
||||
|
||||
SERVICE_CONSTRUCT_IMPL(Service::APT::Module)
|
||||
|
||||
|
||||
@@ -6,9 +6,9 @@
|
||||
#include <cstring>
|
||||
#include <ctime>
|
||||
#include <vector>
|
||||
#include "common/archives.h"
|
||||
#include "common/assert.h"
|
||||
#include "common/logging/log.h"
|
||||
#include "common/string_util.h"
|
||||
#include "core/core.h"
|
||||
#include "core/hle/ipc_helpers.h"
|
||||
#include "core/hle/result.h"
|
||||
|
||||
@@ -150,7 +150,7 @@ void Module::UpdatePadCallback(std::uintptr_t user_data, s64 cycles_late) {
|
||||
circle_pad_old_y.erase(circle_pad_old_y.begin());
|
||||
circle_pad_old_y.push_back(circle_pad_new_y);
|
||||
|
||||
Core::Movie::GetInstance().HandlePadAndCircleStatus(state, circle_pad_x, circle_pad_y);
|
||||
system.Movie().HandlePadAndCircleStatus(state, circle_pad_x, circle_pad_y);
|
||||
|
||||
const DirectionState direction = GetStickDirectionState(circle_pad_x, circle_pad_y);
|
||||
state.circle_up.Assign(direction.up);
|
||||
@@ -200,7 +200,7 @@ void Module::UpdatePadCallback(std::uintptr_t user_data, s64 cycles_late) {
|
||||
touch_entry.y = static_cast<u16>(y * Core::kScreenBottomHeight);
|
||||
touch_entry.valid.Assign(pressed ? 1 : 0);
|
||||
|
||||
Core::Movie::GetInstance().HandleTouchStatus(touch_entry);
|
||||
system.Movie().HandleTouchStatus(touch_entry);
|
||||
|
||||
// TODO(bunnei): We're not doing anything with offset 0xA8 + 0x18 of HID SharedMemory, which
|
||||
// supposedly is "Touch-screen entry, which contains the raw coordinate data prior to being
|
||||
@@ -246,7 +246,7 @@ void Module::UpdateAccelerometerCallback(std::uintptr_t user_data, s64 cycles_la
|
||||
accelerometer_entry.y = static_cast<s16>(accel.y);
|
||||
accelerometer_entry.z = static_cast<s16>(accel.z);
|
||||
|
||||
Core::Movie::GetInstance().HandleAccelerometerStatus(accelerometer_entry);
|
||||
system.Movie().HandleAccelerometerStatus(accelerometer_entry);
|
||||
|
||||
// Make up "raw" entry
|
||||
// TODO(wwylele):
|
||||
@@ -287,7 +287,7 @@ void Module::UpdateGyroscopeCallback(std::uintptr_t user_data, s64 cycles_late)
|
||||
gyroscope_entry.y = static_cast<s16>(gyro.y);
|
||||
gyroscope_entry.z = static_cast<s16>(gyro.z);
|
||||
|
||||
Core::Movie::GetInstance().HandleGyroscopeStatus(gyroscope_entry);
|
||||
system.Movie().HandleGyroscopeStatus(gyroscope_entry);
|
||||
|
||||
// Make up "raw" entry
|
||||
mem->gyroscope.raw_entry.x = gyroscope_entry.x;
|
||||
|
||||
@@ -31,6 +31,10 @@ namespace Core {
|
||||
class System;
|
||||
}
|
||||
|
||||
namespace IPC {
|
||||
class RequestParser;
|
||||
}
|
||||
|
||||
namespace Service::HTTP {
|
||||
|
||||
enum class RequestMethod : u8 {
|
||||
@@ -362,6 +366,37 @@ private:
|
||||
|
||||
void SetProxyDefault(Kernel::HLERequestContext& ctx);
|
||||
|
||||
/**
|
||||
* HTTP_C::ReceiveData service function
|
||||
* Inputs:
|
||||
* 1 : Context handle
|
||||
* 2 : Buffer size
|
||||
* 3 : (OutSize<<4) | 12
|
||||
* 4 : Output data pointer
|
||||
* Outputs:
|
||||
* 1 : Result of function, 0 on success, otherwise error code
|
||||
*/
|
||||
void ReceiveData(Kernel::HLERequestContext& ctx);
|
||||
|
||||
/**
|
||||
* HTTP_C::ReceiveDataTimeout service function
|
||||
* Inputs:
|
||||
* 1 : Context handle
|
||||
* 2 : Buffer size
|
||||
* 3-4 : u64 nanoseconds delay
|
||||
* 5 : (OutSize<<4) | 12
|
||||
* 6 : Output data pointer
|
||||
* Outputs:
|
||||
* 1 : Result of function, 0 on success, otherwise error code
|
||||
*/
|
||||
void ReceiveDataTimeout(Kernel::HLERequestContext& ctx);
|
||||
|
||||
/**
|
||||
* ReceiveDataImpl:
|
||||
* Implements ReceiveData and ReceiveDataTimeout service functions
|
||||
*/
|
||||
void ReceiveDataImpl(Kernel::HLERequestContext& ctx, bool timeout);
|
||||
|
||||
/**
|
||||
* HTTP_C::AddRequestHeader service function
|
||||
* Inputs:
|
||||
|
||||
@@ -5,8 +5,6 @@
|
||||
#include <fmt/format.h>
|
||||
#include "common/alignment.h"
|
||||
#include "common/settings.h"
|
||||
#include "common/string_util.h"
|
||||
#include "core/core.h"
|
||||
#include "core/core_timing.h"
|
||||
#include "core/hle/service/ir/extra_hid.h"
|
||||
#include "core/movie.h"
|
||||
@@ -65,7 +63,8 @@ enum class ResponseID : u8 {
|
||||
ReadCalibrationData = 0x11,
|
||||
};
|
||||
|
||||
ExtraHID::ExtraHID(SendFunc send_func, Core::Timing& timing) : IRDevice(send_func), timing(timing) {
|
||||
ExtraHID::ExtraHID(SendFunc send_func, Core::Timing& timing_, Core::Movie& movie_)
|
||||
: IRDevice(send_func), timing{timing_}, movie{movie_} {
|
||||
LoadInputDevices();
|
||||
|
||||
// The data below was retrieved from a New 3DS
|
||||
@@ -249,7 +248,7 @@ void ExtraHID::SendHIDStatus() {
|
||||
response.buttons.r_not_held.Assign(1);
|
||||
response.unknown = 0;
|
||||
|
||||
Core::Movie::GetInstance().HandleExtraHidResponse(response);
|
||||
movie.HandleExtraHidResponse(response);
|
||||
|
||||
std::vector<u8> response_buffer(sizeof(response));
|
||||
memcpy(response_buffer.data(), &response, sizeof(response));
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
namespace Core {
|
||||
struct TimingEventType;
|
||||
class Timing;
|
||||
class Movie;
|
||||
} // namespace Core
|
||||
|
||||
namespace Service::IR {
|
||||
@@ -43,7 +44,7 @@ static_assert(sizeof(ExtraHIDResponse) == 6, "HID status response has wrong size
|
||||
*/
|
||||
class ExtraHID final : public IRDevice {
|
||||
public:
|
||||
explicit ExtraHID(SendFunc send_func, Core::Timing& timing);
|
||||
explicit ExtraHID(SendFunc send_func, Core::Timing& timing, Core::Movie& movie);
|
||||
~ExtraHID();
|
||||
|
||||
void OnConnect() override;
|
||||
@@ -60,6 +61,7 @@ private:
|
||||
void LoadInputDevices();
|
||||
|
||||
Core::Timing& timing;
|
||||
Core::Movie& movie;
|
||||
u8 hid_period;
|
||||
Core::TimingEventType* hid_polling_callback_id;
|
||||
std::array<u8, 0x40> calibration_data;
|
||||
|
||||
@@ -83,7 +83,7 @@ void IR_RST::UpdateCallback(std::uintptr_t user_data, s64 cycles_late) {
|
||||
s16 c_stick_x = static_cast<s16>(c_stick_x_f * MAX_CSTICK_RADIUS);
|
||||
s16 c_stick_y = static_cast<s16>(c_stick_y_f * MAX_CSTICK_RADIUS);
|
||||
|
||||
Core::Movie::GetInstance().HandleIrRst(state, c_stick_x, c_stick_y);
|
||||
system.Movie().HandleIrRst(state, c_stick_x, c_stick_y);
|
||||
|
||||
if (!raw_c_stick) {
|
||||
const HID::DirectionState direction = HID::GetStickDirectionState(c_stick_x, c_stick_y);
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
#include <boost/serialization/shared_ptr.hpp>
|
||||
#include <boost/serialization/unique_ptr.hpp>
|
||||
#include <fmt/format.h>
|
||||
#include "common/string_util.h"
|
||||
#include "common/archives.h"
|
||||
#include "common/swap.h"
|
||||
#include "core/core.h"
|
||||
#include "core/hle/ipc_helpers.h"
|
||||
@@ -467,7 +467,7 @@ IR_USER::IR_USER(Core::System& system) : ServiceFramework("ir:USER", 1) {
|
||||
receive_event = system.Kernel().CreateEvent(ResetType::OneShot, "IR:ReceiveEvent");
|
||||
|
||||
extra_hid = std::make_unique<ExtraHID>([this](std::span<const u8> data) { PutToReceive(data); },
|
||||
system.CoreTiming());
|
||||
system.CoreTiming(), system.Movie());
|
||||
}
|
||||
|
||||
IR_USER::~IR_USER() {
|
||||
|
||||
@@ -7,13 +7,14 @@
|
||||
#include <boost/crc.hpp>
|
||||
#include <cryptopp/osrng.h>
|
||||
|
||||
#include "common/file_util.h"
|
||||
#include "common/logging/log.h"
|
||||
#include "common/string_util.h"
|
||||
#include "core/core.h"
|
||||
#include "core/hle/kernel/shared_page.h"
|
||||
#include "core/hle/service/nfc/amiibo_crypto.h"
|
||||
#include "core/hle/service/nfc/nfc_device.h"
|
||||
#include "core/hw/aes/key.h"
|
||||
#include "core/loader/loader.h"
|
||||
|
||||
SERVICE_CONSTRUCT_IMPL(Service::NFC::NfcDevice)
|
||||
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
#include "common/string_util.h"
|
||||
#include "core/core.h"
|
||||
#include "core/hle/ipc_helpers.h"
|
||||
#include "core/hle/kernel/event.h"
|
||||
#include "core/hle/service/nim/nim_u.h"
|
||||
|
||||
SERVICE_CONSTRUCT_IMPL(Service::NIM::NIM_U)
|
||||
|
||||
@@ -53,6 +53,7 @@
|
||||
#include "core/hle/service/sm/srv.h"
|
||||
#include "core/hle/service/soc/soc_u.h"
|
||||
#include "core/hle/service/ssl/ssl_c.h"
|
||||
#include "core/loader/loader.h"
|
||||
|
||||
namespace Service {
|
||||
|
||||
|
||||
@@ -14,7 +14,6 @@
|
||||
#include "common/file_util.h"
|
||||
#include "core/file_sys/romfs_reader.h"
|
||||
#include "core/hle/kernel/kernel.h"
|
||||
#include "core/hle/kernel/object.h"
|
||||
|
||||
namespace Kernel {
|
||||
struct AddressMapping;
|
||||
|
||||
@@ -27,6 +27,7 @@
|
||||
#include "core/loader/smdh.h"
|
||||
#include "core/memory.h"
|
||||
#include "core/system_titles.h"
|
||||
#include "core/telemetry_session.h"
|
||||
#include "network/network.h"
|
||||
|
||||
namespace Loader {
|
||||
|
||||
+25
-24
@@ -17,9 +17,7 @@
|
||||
#include "core/arm/arm_interface.h"
|
||||
#include "core/core.h"
|
||||
#include "core/global.h"
|
||||
#include "core/hle/kernel/memory.h"
|
||||
#include "core/hle/kernel/process.h"
|
||||
#include "core/hle/lock.h"
|
||||
#include "core/hle/service/plgldr/plgldr.h"
|
||||
#include "core/hw/hw.h"
|
||||
#include "core/memory.h"
|
||||
@@ -89,12 +87,13 @@ private:
|
||||
|
||||
class MemorySystem::Impl {
|
||||
public:
|
||||
// Visual Studio would try to allocate these on compile time if they are std::array, which would
|
||||
// exceed the memory limit.
|
||||
// Visual Studio would try to allocate these on compile time
|
||||
// if they are std::array which would exceed the memory limit.
|
||||
std::unique_ptr<u8[]> fcram = std::make_unique<u8[]>(Memory::FCRAM_N3DS_SIZE);
|
||||
std::unique_ptr<u8[]> vram = std::make_unique<u8[]>(Memory::VRAM_SIZE);
|
||||
std::unique_ptr<u8[]> n3ds_extra_ram = std::make_unique<u8[]>(Memory::N3DS_EXTRA_RAM_SIZE);
|
||||
|
||||
Core::System& system;
|
||||
std::shared_ptr<PageTable> current_page_table = nullptr;
|
||||
RasterizerCacheMarker cache_marker;
|
||||
std::vector<std::shared_ptr<PageTable>> page_table_list;
|
||||
@@ -106,7 +105,7 @@ public:
|
||||
std::shared_ptr<BackingMem> n3ds_extra_ram_mem;
|
||||
std::shared_ptr<BackingMem> dsp_mem;
|
||||
|
||||
Impl();
|
||||
Impl(Core::System& system_);
|
||||
|
||||
const u8* GetPtr(Region r) const {
|
||||
switch (r) {
|
||||
@@ -153,6 +152,10 @@ public:
|
||||
}
|
||||
}
|
||||
|
||||
u32 GetPC() const noexcept {
|
||||
return system.GetRunningCore().GetPC();
|
||||
}
|
||||
|
||||
/**
|
||||
* This function should only be called for virtual addreses with attribute `PageType::Special`.
|
||||
*/
|
||||
@@ -187,7 +190,7 @@ public:
|
||||
HW_Memory,
|
||||
"unmapped ReadBlock @ 0x{:08X} (start address = 0x{:08X}, size = {}) at PC "
|
||||
"0x{:08X}",
|
||||
current_vaddr, src_addr, size, Core::GetRunningCore().GetPC());
|
||||
current_vaddr, src_addr, size, GetPC());
|
||||
std::memset(dest_buffer, 0, copy_amount);
|
||||
break;
|
||||
}
|
||||
@@ -242,7 +245,7 @@ public:
|
||||
HW_Memory,
|
||||
"unmapped WriteBlock @ 0x{:08X} (start address = 0x{:08X}, size = {}) at PC "
|
||||
"0x{:08X}",
|
||||
current_vaddr, dest_addr, size, Core::GetRunningCore().GetPC());
|
||||
current_vaddr, dest_addr, size, GetPC());
|
||||
break;
|
||||
}
|
||||
case PageType::Memory: {
|
||||
@@ -345,13 +348,13 @@ private:
|
||||
friend class boost::serialization::access;
|
||||
};
|
||||
|
||||
MemorySystem::Impl::Impl()
|
||||
: fcram_mem(std::make_shared<BackingMemImpl<Region::FCRAM>>(*this)),
|
||||
MemorySystem::Impl::Impl(Core::System& system_)
|
||||
: system{system_}, fcram_mem(std::make_shared<BackingMemImpl<Region::FCRAM>>(*this)),
|
||||
vram_mem(std::make_shared<BackingMemImpl<Region::VRAM>>(*this)),
|
||||
n3ds_extra_ram_mem(std::make_shared<BackingMemImpl<Region::N3DS>>(*this)),
|
||||
dsp_mem(std::make_shared<BackingMemImpl<Region::DSP>>(*this)) {}
|
||||
|
||||
MemorySystem::MemorySystem() : impl(std::make_unique<Impl>()) {}
|
||||
MemorySystem::MemorySystem(Core::System& system) : impl(std::make_unique<Impl>(system)) {}
|
||||
MemorySystem::~MemorySystem() = default;
|
||||
|
||||
template <class Archive>
|
||||
@@ -467,7 +470,7 @@ T MemorySystem::Read(const VAddr vaddr) {
|
||||
switch (type) {
|
||||
case PageType::Unmapped:
|
||||
LOG_ERROR(HW_Memory, "unmapped Read{} @ 0x{:08X} at PC 0x{:08X}", sizeof(T) * 8, vaddr,
|
||||
Core::GetRunningCore().GetPC());
|
||||
impl->GetPC());
|
||||
return 0;
|
||||
case PageType::Memory:
|
||||
ASSERT_MSG(false, "Mapped memory page without a pointer @ {:08X}", vaddr);
|
||||
@@ -518,7 +521,7 @@ void MemorySystem::Write(const VAddr vaddr, const T data) {
|
||||
switch (type) {
|
||||
case PageType::Unmapped:
|
||||
LOG_ERROR(HW_Memory, "unmapped Write{} 0x{:08X} @ 0x{:08X} at PC 0x{:08X}",
|
||||
sizeof(data) * 8, (u32)data, vaddr, Core::GetRunningCore().GetPC());
|
||||
sizeof(data) * 8, (u32)data, vaddr, impl->GetPC());
|
||||
return;
|
||||
case PageType::Memory:
|
||||
ASSERT_MSG(false, "Mapped memory page without a pointer @ {:08X}", vaddr);
|
||||
@@ -550,7 +553,7 @@ bool MemorySystem::WriteExclusive(const VAddr vaddr, const T data, const T expec
|
||||
switch (type) {
|
||||
case PageType::Unmapped:
|
||||
LOG_ERROR(HW_Memory, "unmapped Write{} 0x{:08X} @ 0x{:08X} at PC 0x{:08X}",
|
||||
sizeof(data) * 8, (u32)data, vaddr, Core::GetRunningCore().GetPC());
|
||||
sizeof(data) * 8, static_cast<u32>(data), vaddr, impl->GetPC());
|
||||
return true;
|
||||
case PageType::Memory:
|
||||
ASSERT_MSG(false, "Mapped memory page without a pointer @ {:08X}", vaddr);
|
||||
@@ -606,8 +609,7 @@ u8* MemorySystem::GetPointer(const VAddr vaddr) {
|
||||
return GetPointerForRasterizerCache(vaddr);
|
||||
}
|
||||
|
||||
LOG_ERROR(HW_Memory, "unknown GetPointer @ 0x{:08x} at PC 0x{:08X}", vaddr,
|
||||
Core::GetRunningCore().GetPC());
|
||||
LOG_ERROR(HW_Memory, "unknown GetPointer @ 0x{:08x} at PC 0x{:08X}", vaddr, impl->GetPC());
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
@@ -663,7 +665,7 @@ MemoryRef MemorySystem::GetPhysicalRef(PAddr address) const {
|
||||
|
||||
if (area == memory_areas.end()) {
|
||||
LOG_ERROR(HW_Memory, "Unknown GetPhysicalPointer @ {:#08X} at PC {:#08X}", address,
|
||||
Core::GetRunningCore().GetPC());
|
||||
impl->GetPC());
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
@@ -693,8 +695,7 @@ MemoryRef MemorySystem::GetPhysicalRef(PAddr address) const {
|
||||
return {target_mem, offset_into_region};
|
||||
}
|
||||
|
||||
/// For a rasterizer-accessible PAddr, gets a list of all possible VAddr
|
||||
static std::vector<VAddr> PhysicalToVirtualAddressForRasterizer(PAddr addr) {
|
||||
std::vector<VAddr> MemorySystem::PhysicalToVirtualAddressForRasterizer(PAddr addr) {
|
||||
if (addr >= VRAM_PADDR && addr < VRAM_PADDR_END) {
|
||||
return {addr - VRAM_PADDR + VRAM_VADDR};
|
||||
}
|
||||
@@ -714,7 +715,7 @@ static std::vector<VAddr> PhysicalToVirtualAddressForRasterizer(PAddr addr) {
|
||||
// parts of the texture.
|
||||
LOG_ERROR(HW_Memory,
|
||||
"Trying to use invalid physical address for rasterizer: {:08X} at PC 0x{:08X}", addr,
|
||||
Core::GetRunningCore().GetPC());
|
||||
impl->GetPC());
|
||||
return {};
|
||||
}
|
||||
|
||||
@@ -729,7 +730,7 @@ void MemorySystem::RasterizerMarkRegionCached(PAddr start, u32 size, bool cached
|
||||
for (unsigned i = 0; i < num_pages; ++i, paddr += CITRA_PAGE_SIZE) {
|
||||
for (VAddr vaddr : PhysicalToVirtualAddressForRasterizer(paddr)) {
|
||||
impl->cache_marker.Mark(vaddr, cached);
|
||||
for (auto page_table : impl->page_table_list) {
|
||||
for (auto& page_table : impl->page_table_list) {
|
||||
PageType& page_type = page_table->attributes[vaddr >> CITRA_PAGE_BITS];
|
||||
|
||||
if (cached) {
|
||||
@@ -868,7 +869,7 @@ void MemorySystem::ReadBlock(const Kernel::Process& process, const VAddr src_add
|
||||
}
|
||||
|
||||
void MemorySystem::ReadBlock(VAddr src_addr, void* dest_buffer, std::size_t size) {
|
||||
const auto& process = *Core::System::GetInstance().Kernel().GetCurrentProcess();
|
||||
const auto& process = *impl->system.Kernel().GetCurrentProcess();
|
||||
return impl->ReadBlockImpl<false>(process, src_addr, dest_buffer, size);
|
||||
}
|
||||
|
||||
@@ -911,7 +912,7 @@ void MemorySystem::WriteBlock(const Kernel::Process& process, const VAddr dest_a
|
||||
|
||||
void MemorySystem::WriteBlock(const VAddr dest_addr, const void* src_buffer,
|
||||
const std::size_t size) {
|
||||
auto& process = *Core::System::GetInstance().Kernel().GetCurrentProcess();
|
||||
auto& process = *impl->system.Kernel().GetCurrentProcess();
|
||||
return impl->WriteBlockImpl<false>(process, dest_addr, src_buffer, size);
|
||||
}
|
||||
|
||||
@@ -934,7 +935,7 @@ void MemorySystem::ZeroBlock(const Kernel::Process& process, const VAddr dest_ad
|
||||
LOG_ERROR(HW_Memory,
|
||||
"unmapped ZeroBlock @ 0x{:08X} (start address = 0x{:08X}, size = {}) at PC "
|
||||
"0x{:08X}",
|
||||
current_vaddr, dest_addr, size, Core::GetRunningCore().GetPC());
|
||||
current_vaddr, dest_addr, size, impl->GetPC());
|
||||
break;
|
||||
}
|
||||
case PageType::Memory: {
|
||||
@@ -989,7 +990,7 @@ void MemorySystem::CopyBlock(const Kernel::Process& dest_process,
|
||||
LOG_ERROR(HW_Memory,
|
||||
"unmapped CopyBlock @ 0x{:08X} (start address = 0x{:08X}, size = {}) at PC "
|
||||
"0x{:08X}",
|
||||
current_vaddr, src_addr, size, Core::GetRunningCore().GetPC());
|
||||
current_vaddr, src_addr, size, impl->GetPC());
|
||||
ZeroBlock(dest_process, dest_addr, copy_amount);
|
||||
break;
|
||||
}
|
||||
|
||||
+9
-1
@@ -18,6 +18,10 @@ namespace Kernel {
|
||||
class Process;
|
||||
}
|
||||
|
||||
namespace Core {
|
||||
class System;
|
||||
}
|
||||
|
||||
namespace AudioCore {
|
||||
class DspInterface;
|
||||
}
|
||||
@@ -287,7 +291,7 @@ void RasterizerFlushVirtualRegion(VAddr start, u32 size, FlushMode mode);
|
||||
|
||||
class MemorySystem {
|
||||
public:
|
||||
MemorySystem();
|
||||
explicit MemorySystem(Core::System& system);
|
||||
~MemorySystem();
|
||||
|
||||
/**
|
||||
@@ -575,6 +579,9 @@ public:
|
||||
*/
|
||||
void RasterizerMarkRegionCached(PAddr start, u32 size, bool cached);
|
||||
|
||||
/// For a rasterizer-accessible PAddr, gets a list of all possible VAddr
|
||||
std::vector<VAddr> PhysicalToVirtualAddressForRasterizer(PAddr addr);
|
||||
|
||||
/// Gets a pointer to the memory region beginning at the specified physical address.
|
||||
u8* GetPhysicalPointer(PAddr address) const;
|
||||
|
||||
@@ -627,6 +634,7 @@ private:
|
||||
|
||||
void MapPages(PageTable& page_table, u32 base, u32 size, MemoryRef memory, PageType type);
|
||||
|
||||
private:
|
||||
class Impl;
|
||||
std::unique_ptr<Impl> impl;
|
||||
|
||||
|
||||
+7
-6
@@ -10,13 +10,11 @@
|
||||
#include <boost/optional.hpp>
|
||||
#include <cryptopp/hex.h>
|
||||
#include <cryptopp/osrng.h>
|
||||
#include <fmt/format.h>
|
||||
#include "common/archives.h"
|
||||
#include "common/bit_field.h"
|
||||
#include "common/common_types.h"
|
||||
#include "common/file_util.h"
|
||||
#include "common/logging/log.h"
|
||||
#include "common/scm_rev.h"
|
||||
#include "common/string_util.h"
|
||||
#include "common/swap.h"
|
||||
#include "common/timer.h"
|
||||
#include "core/core.h"
|
||||
@@ -24,12 +22,11 @@
|
||||
#include "core/hle/service/ir/extra_hid.h"
|
||||
#include "core/hle/service/ir/ir_rst.h"
|
||||
#include "core/hw/gpu.h"
|
||||
#include "core/loader/loader.h"
|
||||
#include "core/movie.h"
|
||||
|
||||
namespace Core {
|
||||
|
||||
/*static*/ Movie Movie::s_instance;
|
||||
|
||||
enum class ControllerStateType : u8 {
|
||||
PadAndCircle,
|
||||
Touch,
|
||||
@@ -146,6 +143,10 @@ static u64 GetInputCount(std::span<const u8> input) {
|
||||
return input_count;
|
||||
}
|
||||
|
||||
Movie::Movie(const Core::System& system_) : system{system_} {}
|
||||
|
||||
Movie::~Movie() = default;
|
||||
|
||||
template <class Archive>
|
||||
void Movie::serialize(Archive& ar, const unsigned int file_version) {
|
||||
// Only serialize what's needed to make savestates useful for TAS:
|
||||
@@ -565,7 +566,7 @@ void Movie::StartRecording(const std::string& movie_file, const std::string& aut
|
||||
|
||||
// Get program ID
|
||||
program_id = 0;
|
||||
Core::System::GetInstance().GetAppLoader().ReadProgramId(program_id);
|
||||
system.GetAppLoader().ReadProgramId(program_id);
|
||||
|
||||
LOG_INFO(Movie, "Enabling Movie recording, ID: {:016X}", id);
|
||||
}
|
||||
|
||||
+15
-11
@@ -23,25 +23,29 @@ union PadState;
|
||||
} // namespace Service
|
||||
|
||||
namespace Core {
|
||||
|
||||
class System;
|
||||
struct CTMHeader;
|
||||
struct ControllerState;
|
||||
|
||||
class Movie {
|
||||
public:
|
||||
enum class PlayMode { None, Recording, Playing, MovieFinished };
|
||||
enum class ValidationResult {
|
||||
enum class PlayMode : u32 {
|
||||
None,
|
||||
Recording,
|
||||
Playing,
|
||||
MovieFinished,
|
||||
};
|
||||
|
||||
enum class ValidationResult : u32 {
|
||||
OK,
|
||||
RevisionDismatch,
|
||||
InputCountDismatch,
|
||||
Invalid,
|
||||
};
|
||||
/**
|
||||
* Gets the instance of the Movie singleton class.
|
||||
* @returns Reference to the instance of the Movie singleton class.
|
||||
*/
|
||||
static Movie& GetInstance() {
|
||||
return s_instance;
|
||||
}
|
||||
|
||||
explicit Movie(const Core::System& system);
|
||||
~Movie();
|
||||
|
||||
void SetPlaybackCompletionCallback(std::function<void()> completion_callback);
|
||||
void StartPlayback(const std::string& movie_file);
|
||||
@@ -133,8 +137,6 @@ public:
|
||||
void SaveMovie();
|
||||
|
||||
private:
|
||||
static Movie s_instance;
|
||||
|
||||
void CheckInputEnd();
|
||||
|
||||
template <typename... Targs>
|
||||
@@ -159,6 +161,8 @@ private:
|
||||
ValidationResult ValidateHeader(const CTMHeader& header) const;
|
||||
ValidationResult ValidateInput(std::span<const u8> input, u64 expected_count) const;
|
||||
|
||||
private:
|
||||
const Core::System& system;
|
||||
PlayMode play_mode;
|
||||
|
||||
std::string record_movie_file;
|
||||
|
||||
+14
-10
@@ -3,11 +3,14 @@
|
||||
// Refer to the license.txt file included.
|
||||
|
||||
#include <chrono>
|
||||
#include <sstream>
|
||||
#include <cryptopp/hex.h>
|
||||
#include <fmt/format.h>
|
||||
#include "common/archives.h"
|
||||
#include "common/file_util.h"
|
||||
#include "common/logging/log.h"
|
||||
#include "common/scm_rev.h"
|
||||
#include "common/swap.h"
|
||||
#include "common/zstd_compression.h"
|
||||
#include "core/core.h"
|
||||
#include "core/movie.h"
|
||||
@@ -30,8 +33,7 @@ static_assert(sizeof(CSTHeader) == 256, "CSTHeader should be 256 bytes");
|
||||
|
||||
constexpr std::array<u8, 4> header_magic_bytes{{'C', 'S', 'T', 0x1B}};
|
||||
|
||||
static std::string GetSaveStatePath(u64 program_id, u32 slot) {
|
||||
const u64 movie_id = Movie::GetInstance().GetCurrentMovieID();
|
||||
static std::string GetSaveStatePath(u64 program_id, u64 movie_id, u32 slot) {
|
||||
if (movie_id) {
|
||||
return fmt::format("{}{:016X}.movie{:016X}.{:02d}.cst",
|
||||
FileUtil::GetUserPath(FileUtil::UserPath::StatesDir), program_id,
|
||||
@@ -43,8 +45,8 @@ static std::string GetSaveStatePath(u64 program_id, u32 slot) {
|
||||
}
|
||||
|
||||
static bool ValidateSaveState(const CSTHeader& header, SaveStateInfo& info, u64 program_id,
|
||||
u32 slot) {
|
||||
const auto path = GetSaveStatePath(program_id, slot);
|
||||
u64 movie_id, u32 slot) {
|
||||
const auto path = GetSaveStatePath(program_id, movie_id, slot);
|
||||
if (header.filetype != header_magic_bytes) {
|
||||
LOG_WARNING(Core, "Invalid save state file {}", path);
|
||||
return false;
|
||||
@@ -66,11 +68,11 @@ static bool ValidateSaveState(const CSTHeader& header, SaveStateInfo& info, u64
|
||||
return true;
|
||||
}
|
||||
|
||||
std::vector<SaveStateInfo> ListSaveStates(u64 program_id) {
|
||||
std::vector<SaveStateInfo> ListSaveStates(u64 program_id, u64 movie_id) {
|
||||
std::vector<SaveStateInfo> result;
|
||||
result.reserve(SaveStateSlotCount);
|
||||
for (u32 slot = 1; slot <= SaveStateSlotCount; ++slot) {
|
||||
const auto path = GetSaveStatePath(program_id, slot);
|
||||
const auto path = GetSaveStatePath(program_id, movie_id, slot);
|
||||
if (!FileUtil::Exists(path)) {
|
||||
continue;
|
||||
}
|
||||
@@ -92,7 +94,7 @@ std::vector<SaveStateInfo> ListSaveStates(u64 program_id) {
|
||||
LOG_ERROR(Core, "Could not read from file {}", path);
|
||||
continue;
|
||||
}
|
||||
if (!ValidateSaveState(header, info, program_id, slot)) {
|
||||
if (!ValidateSaveState(header, info, program_id, movie_id, slot)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -111,7 +113,8 @@ void System::SaveState(u32 slot) const {
|
||||
const auto data = std::span<const u8>{reinterpret_cast<const u8*>(str.data()), str.size()};
|
||||
auto buffer = Common::Compression::CompressDataZSTDDefault(data);
|
||||
|
||||
const auto path = GetSaveStatePath(title_id, slot);
|
||||
const u64 movie_id = movie.GetCurrentMovieID();
|
||||
const auto path = GetSaveStatePath(title_id, movie_id, slot);
|
||||
if (!FileUtil::CreateFullPath(path)) {
|
||||
throw std::runtime_error("Could not create path " + path);
|
||||
}
|
||||
@@ -143,7 +146,8 @@ void System::LoadState(u32 slot) {
|
||||
throw std::runtime_error("Unable to load while connected to multiplayer");
|
||||
}
|
||||
|
||||
const auto path = GetSaveStatePath(title_id, slot);
|
||||
const u64 movie_id = movie.GetCurrentMovieID();
|
||||
const auto path = GetSaveStatePath(title_id, movie_id, slot);
|
||||
|
||||
std::vector<u8> decompressed;
|
||||
{
|
||||
@@ -159,7 +163,7 @@ void System::LoadState(u32 slot) {
|
||||
|
||||
// validate header
|
||||
SaveStateInfo info;
|
||||
if (!ValidateSaveState(header, info, title_id, slot)) {
|
||||
if (!ValidateSaveState(header, info, title_id, movie_id, slot)) {
|
||||
throw std::runtime_error("Invalid savestate");
|
||||
}
|
||||
|
||||
|
||||
@@ -20,6 +20,6 @@ struct SaveStateInfo {
|
||||
|
||||
constexpr u32 SaveStateSlotCount = 10; // Maximum count of savestate slots
|
||||
|
||||
std::vector<SaveStateInfo> ListSaveStates(u64 program_id);
|
||||
std::vector<SaveStateInfo> ListSaveStates(u64 program_id, u64 movie_id);
|
||||
|
||||
} // namespace Core
|
||||
|
||||
@@ -11,6 +11,7 @@
|
||||
#include "common/scm_rev.h"
|
||||
#include "common/settings.h"
|
||||
#include "core/core.h"
|
||||
#include "core/loader/loader.h"
|
||||
#include "core/telemetry_session.h"
|
||||
#include "network/network_settings.h"
|
||||
|
||||
|
||||
Reference in New Issue
Block a user