diff options
Diffstat (limited to 'src/core/core.cpp')
| -rw-r--r-- | src/core/core.cpp | 177 |
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()); |
