aboutsummaryrefslogtreecommitdiff
path: root/src/core/core.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/core/core.cpp')
-rw-r--r--src/core/core.cpp177
1 files changed, 61 insertions, 116 deletions
diff --git a/src/core/core.cpp b/src/core/core.cpp
index bf97184f8f..aea2b2b060 100644
--- a/src/core/core.cpp
+++ b/src/core/core.cpp
@@ -112,11 +112,10 @@ struct System::Impl {
u64 program_id;
void Initialize(System& system) {
- device_memory = std::make_unique<Core::DeviceMemory>();
+ device_memory.emplace();
is_multicore = Settings::values.use_multi_core.GetValue();
- extended_memory_layout =
- Settings::values.memory_layout_mode.GetValue() != Settings::MemoryLayout::Memory_4Gb;
+ extended_memory_layout = Settings::values.memory_layout_mode.GetValue() != Settings::MemoryLayout::Memory_4Gb;
core_timing.SetMulticore(is_multicore);
core_timing.Initialize([&system]() { system.RegisterHostThread(); });
@@ -132,7 +131,7 @@ struct System::Impl {
// Create default implementations of applets if one is not provided.
frontend_applets.SetDefaultAppletsIfMissing();
- is_async_gpu = Settings::values.use_asynchronous_gpu_emulation.GetValue();
+ auto const is_async_gpu = Settings::values.use_asynchronous_gpu_emulation.GetValue();
kernel.SetMulticore(is_multicore);
cpu_manager.SetMulticore(is_multicore);
@@ -254,7 +253,7 @@ struct System::Impl {
}
void InitializeDebugger(System& system, u16 port) {
- debugger = std::make_unique<Debugger>(system, port);
+ debugger.emplace(system, port);
}
void InitializeKernel(System& system) {
@@ -268,24 +267,22 @@ struct System::Impl {
}
SystemResultStatus SetupForApplicationProcess(System& system, Frontend::EmuWindow& emu_window) {
- host1x_core = std::make_unique<Tegra::Host1x::Host1x>(system);
+ host1x_core.emplace(system);
gpu_core = VideoCore::CreateGPU(emu_window, system);
- if (!gpu_core) {
+ if (!gpu_core)
return SystemResultStatus::ErrorVideoCore;
- }
- audio_core = std::make_unique<AudioCore::AudioCore>(system);
+ audio_core.emplace(system);
service_manager = std::make_shared<Service::SM::ServiceManager>(kernel);
- services =
- std::make_unique<Service::Services>(service_manager, system, stop_event.get_token());
+ services.emplace(service_manager, system, stop_event.get_token());
is_powered_on = true;
exit_locked = false;
exit_requested = false;
if (Settings::values.enable_renderdoc_hotkey) {
- renderdoc_api = std::make_unique<Tools::RenderdocAPI>();
+ renderdoc_api.emplace();
}
LOG_DEBUG(Core, "Initialized OK");
@@ -303,16 +300,11 @@ struct System::Impl {
// Create the application process
Loader::ResultStatus load_result{};
std::vector<u8> control;
- auto process =
- Service::AM::CreateApplicationProcess(control, app_loader, load_result, system, file,
- params.program_id, params.program_index);
-
+ auto process = Service::AM::CreateApplicationProcess(control, app_loader, load_result, system, file, params.program_id, params.program_index);
if (load_result != Loader::ResultStatus::Success) {
LOG_CRITICAL(Core, "Failed to load ROM (Error {})!", load_result);
ShutdownMainProcess();
-
- return static_cast<SystemResultStatus>(
- static_cast<u32>(SystemResultStatus::ErrorLoader) + static_cast<u32>(load_result));
+ return SystemResultStatus(u32(SystemResultStatus::ErrorLoader) + u32(load_result));
}
if (!app_loader) {
@@ -337,8 +329,7 @@ struct System::Impl {
// Set up the rest of the system.
SystemResultStatus init_result{SetupForApplicationProcess(system, emu_window)};
if (init_result != SystemResultStatus::Success) {
- LOG_CRITICAL(Core, "Failed to initialize system (Error {})!",
- static_cast<int>(init_result));
+ LOG_CRITICAL(Core, "Failed to initialize system (Error {})!", int(init_result));
ShutdownMainProcess();
return init_result;
}
@@ -361,24 +352,19 @@ struct System::Impl {
}
}
- perf_stats = std::make_unique<PerfStats>(params.program_id);
+ perf_stats.emplace(params.program_id);
// Reset counters and set time origin to current frame
GetAndResetPerfStats();
perf_stats->BeginSystemFrame();
- std::string title_version;
- const FileSys::PatchManager pm(params.program_id, system.GetFileSystemController(),
- system.GetContentProvider());
- const auto metadata = pm.GetControlMetadata();
- if (metadata.first != nullptr) {
- title_version = metadata.first->GetVersionString();
- }
+ const FileSys::PatchManager pm(params.program_id, system.GetFileSystemController(), system.GetContentProvider());
+ auto const metadata = pm.GetControlMetadata();
+ std::string title_version = metadata.first != nullptr ? metadata.first->GetVersionString() : "";
if (app_loader->ReadProgramId(program_id) != Loader::ResultStatus::Success) {
LOG_ERROR(Core, "Failed to find program id for ROM");
}
-
GameSettings::LoadOverrides(program_id, gpu_core->Renderer());
if (auto room_member = Network::GetRoomMember().lock()) {
Network::GameInfo game_info;
@@ -387,9 +373,7 @@ struct System::Impl {
game_info.version = title_version;
room_member->SendGameInfo(game_info);
}
-
- status = SystemResultStatus::Success;
- return status;
+ return SystemResultStatus::Success;
}
void ShutdownMainProcess() {
@@ -448,112 +432,79 @@ struct System::Impl {
}
Loader::ResultStatus GetGameName(std::string& out) const {
- if (app_loader == nullptr)
- return Loader::ResultStatus::ErrorNotInitialized;
- return app_loader->ReadTitle(out);
- }
-
- void SetStatus(SystemResultStatus new_status, const char* details = nullptr) {
- status = new_status;
- if (details) {
- status_details = details;
- }
+ return app_loader ? app_loader->ReadTitle(out) : Loader::ResultStatus::ErrorNotInitialized;
}
PerfStatsResults GetAndResetPerfStats() {
return perf_stats->GetAndResetStats(core_timing.GetGlobalTimeUs());
}
- mutable std::mutex suspend_guard;
- std::atomic_bool is_paused{};
- std::atomic<bool> is_shutting_down{};
-
Timing::CoreTiming core_timing;
Kernel::KernelCore kernel;
/// RealVfsFilesystem instance
FileSys::VirtualFilesystem virtual_filesystem;
- /// ContentProviderUnion instance
- std::unique_ptr<FileSys::ContentProviderUnion> content_provider;
Service::FileSystem::FileSystemController fs_controller;
- /// AppLoader used to load the current executing application
- std::unique_ptr<Loader::AppLoader> app_loader;
- std::unique_ptr<Tegra::GPU> gpu_core;
- std::unique_ptr<Tegra::Host1x::Host1x> host1x_core;
- std::unique_ptr<Core::DeviceMemory> device_memory;
- std::unique_ptr<AudioCore::AudioCore> audio_core;
Core::HID::HIDCore hid_core;
-
CpuManager cpu_manager;
- std::atomic_bool is_powered_on{};
- bool exit_locked = false;
- bool exit_requested = false;
-
- bool nvdec_active{};
-
Reporter reporter;
- std::unique_ptr<Memory::CheatEngine> cheat_engine;
- std::unique_ptr<Tools::Freezer> memory_freezer;
- std::array<u8, 0x20> build_id{};
-
- std::unique_ptr<Tools::RenderdocAPI> renderdoc_api;
-
/// Applets
Service::AM::AppletManager applet_manager;
Service::AM::Frontend::FrontendAppletHolder frontend_applets;
-
/// APM (Performance) services
Service::APM::Controller apm_controller{core_timing};
-
/// Service State
Service::Glue::ARPManager arp_manager;
Service::Account::ProfileManager profile_manager;
-
- /// Service manager
- std::shared_ptr<Service::SM::ServiceManager> service_manager;
-
- /// Services
- std::unique_ptr<Service::Services> services;
-
/// Network instance
Network::NetworkInstance network_instance;
-
- /// Debugger
- std::unique_ptr<Core::Debugger> debugger;
-
- SystemResultStatus status = SystemResultStatus::Success;
- std::string status_details = "";
-
- std::unique_ptr<Core::PerfStats> perf_stats;
Core::SpeedLimiter speed_limiter;
-
- bool is_multicore{};
- bool is_async_gpu{};
- bool extended_memory_layout{};
-
ExecuteProgramCallback execute_program_callback;
ExitCallback exit_callback;
- std::stop_source stop_event;
- std::array<u64, Core::Hardware::NUM_CPU_CORES> dynarmic_ticks{};
+ std::optional<Service::Services> services;
+ std::optional<Core::Debugger> debugger;
+ std::optional<Service::KernelHelpers::ServiceContext> general_channel_context;
+ std::optional<Service::Event> general_channel_event;
+ std::optional<Core::PerfStats> perf_stats;
+ std::optional<Tegra::Host1x::Host1x> host1x_core;
+ std::optional<Core::DeviceMemory> device_memory;
+ std::optional<AudioCore::AudioCore> audio_core;
+ std::optional<Memory::CheatEngine> cheat_engine;
+ std::optional<Tools::Freezer> memory_freezer;
+ std::optional<Tools::RenderdocAPI> renderdoc_api;
+
+ std::array<Core::GPUDirtyMemoryManager, Core::Hardware::NUM_CPU_CORES> gpu_dirty_memory_managers;
+ std::vector<std::vector<u8>> user_channel;
+ std::vector<std::vector<u8>> general_channel;
- std::array<Core::GPUDirtyMemoryManager, Core::Hardware::NUM_CPU_CORES>
- gpu_dirty_memory_managers;
+ std::array<u64, Core::Hardware::NUM_CPU_CORES> dynarmic_ticks{};
+ std::array<u8, 0x20> build_id{};
- std::deque<std::vector<u8>> user_channel;
+ /// Service manager
+ std::shared_ptr<Service::SM::ServiceManager> service_manager;
+ /// ContentProviderUnion instance
+ std::unique_ptr<FileSys::ContentProviderUnion> content_provider;
+ /// AppLoader used to load the current executing application
+ std::unique_ptr<Loader::AppLoader> app_loader;
+ std::unique_ptr<Tegra::GPU> gpu_core;
+ std::stop_source stop_event;
+ mutable std::mutex suspend_guard;
std::mutex general_channel_mutex;
- std::deque<std::vector<u8>> general_channel;
- std::unique_ptr<Service::KernelHelpers::ServiceContext> general_channel_context; // lazy
- std::unique_ptr<Service::Event> general_channel_event; // lazy
- bool general_channel_initialized{false};
+ std::atomic_bool is_paused{};
+ std::atomic_bool is_shutting_down{};
+ std::atomic_bool is_powered_on{};
+ bool is_multicore : 1 = false;
+ bool extended_memory_layout : 1 = false;
+ bool exit_locked : 1 = false;
+ bool exit_requested : 1 = false;
+ bool nvdec_active : 1 = false;
void EnsureGeneralChannelInitialized(System& system) {
- if (general_channel_initialized) {
- return;
+ if (!general_channel_event) {
+ general_channel_context.emplace(system, "GeneralChannel");
+ general_channel_event.emplace(*general_channel_context);
}
- general_channel_context = std::make_unique<Service::KernelHelpers::ServiceContext>(system, "GeneralChannel");
- general_channel_event = std::make_unique<Service::Event>(*general_channel_context);
- general_channel_initialized = true;
}
};
@@ -776,14 +727,6 @@ Loader::ResultStatus System::GetGameName(std::string& out) const {
return impl->GetGameName(out);
}
-void System::SetStatus(SystemResultStatus new_status, const char* details) {
- impl->SetStatus(new_status, details);
-}
-
-const std::string& System::GetStatusDetails() const {
- return impl->status_details;
-}
-
Loader::AppLoader& System::GetAppLoader() {
return *impl->app_loader;
}
@@ -803,7 +746,7 @@ FileSys::VirtualFilesystem System::GetFilesystem() const {
void System::RegisterCheatList(const std::vector<Memory::CheatEntry>& list,
const std::array<u8, 32>& build_id, u64 main_region_begin,
u64 main_region_size) {
- impl->cheat_engine = std::make_unique<Memory::CheatEngine>(*this, list, build_id);
+ impl->cheat_engine.emplace(*this, list, build_id);
impl->cheat_engine->SetMainMemoryParameters(main_region_begin, main_region_size);
}
@@ -964,11 +907,13 @@ void System::ExecuteProgram(std::size_t program_index) {
}
}
-std::deque<std::vector<u8>>& System::GetUserChannel() {
+/// @brief Gets a reference to the user channel stack.
+/// It is used to transfer data between programs.
+std::vector<std::vector<u8>>& System::GetUserChannel() {
return impl->user_channel;
}
-std::deque<std::vector<u8>>& System::GetGeneralChannel() {
+std::vector<std::vector<u8>>& System::GetGeneralChannel() {
return impl->general_channel;
}
@@ -984,7 +929,7 @@ void System::PushGeneralChannelData(std::vector<u8>&& data) {
bool System::TryPopGeneralChannel(std::vector<u8>& out_data) {
std::scoped_lock lk{impl->general_channel_mutex};
- if (!impl->general_channel_initialized || impl->general_channel.empty()) {
+ if (!impl->general_channel_event || impl->general_channel.empty()) {
return false;
}
out_data = std::move(impl->general_channel.back());