| | |
| | |
| | |
| |
|
| | #pragma once |
| |
|
| | #include <atomic> |
| | #include <memory> |
| | #include <mutex> |
| | #include <string> |
| | #include <boost/optional.hpp> |
| | #include <boost/serialization/version.hpp> |
| | #include "common/common_types.h" |
| | #include "core/arm/arm_interface.h" |
| | #include "core/cheats/cheats.h" |
| | #include "core/hle/service/apt/applet_manager.h" |
| | #include "core/hle/service/plgldr/plgldr.h" |
| | #include "core/movie.h" |
| | #include "core/perf_stats.h" |
| |
|
| | namespace Frontend { |
| | class EmuWindow; |
| | class ImageInterface; |
| | class MiiSelector; |
| | class SoftwareKeyboard; |
| | } |
| |
|
| | namespace Memory { |
| | class MemorySystem; |
| | } |
| |
|
| | namespace AudioCore { |
| | class DspInterface; |
| | } |
| |
|
| | namespace Core::RPC { |
| | class Server; |
| | } |
| |
|
| | namespace Service { |
| | namespace SM { |
| | class ServiceManager; |
| | } |
| | namespace FS { |
| | class ArchiveManager; |
| | } |
| | } |
| |
|
| | namespace Kernel { |
| | class KernelSystem; |
| | struct New3dsHwCapabilities; |
| | enum class MemoryMode : u8; |
| | } |
| |
|
| | namespace VideoDumper { |
| | class Backend; |
| | } |
| |
|
| | namespace VideoCore { |
| | class CustomTexManager; |
| | class GPU; |
| | } |
| |
|
| | namespace Pica { |
| | class DebugContext; |
| | } |
| |
|
| | namespace Loader { |
| | class AppLoader; |
| | } |
| |
|
| | namespace Core { |
| |
|
| | class ARM_Interface; |
| | class TelemetrySession; |
| | class ExclusiveMonitor; |
| | class Timing; |
| |
|
| | class System { |
| | public: |
| | |
| | |
| | |
| | |
| | [[nodiscard]] static System& GetInstance() { |
| | return s_instance; |
| | } |
| |
|
| | |
| | enum class ResultStatus : u32 { |
| | Success, |
| | ErrorNotInitialized, |
| | ErrorGetLoader, |
| | ErrorSystemMode, |
| | ErrorLoader, |
| | ErrorLoader_ErrorEncrypted, |
| | ErrorLoader_ErrorInvalidFormat, |
| | |
| | ErrorLoader_ErrorGbaTitle, |
| | |
| | ErrorSystemFiles, |
| | ErrorSavestate, |
| | ShutdownRequested, |
| | ErrorUnknown |
| | }; |
| |
|
| | explicit System(); |
| | ~System(); |
| |
|
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | [[nodiscard]] ResultStatus RunLoop(bool tight_loop = true); |
| |
|
| | |
| | |
| | |
| | |
| | [[nodiscard]] ResultStatus SingleStep(); |
| |
|
| | |
| | void Shutdown(bool is_deserializing = false); |
| |
|
| | |
| | void Reset(); |
| |
|
| | enum class Signal : u32 { None, Shutdown, Reset, Save, Load }; |
| |
|
| | bool SendSignal(Signal signal, u32 param = 0); |
| |
|
| | |
| | void RequestReset(const std::string& chainload = "") { |
| | m_chainloadpath = chainload; |
| | SendSignal(Signal::Reset); |
| | } |
| |
|
| | |
| | void RequestShutdown() { |
| | SendSignal(Signal::Shutdown); |
| | } |
| |
|
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | [[nodiscard]] ResultStatus Load(Frontend::EmuWindow& emu_window, const std::string& filepath, |
| | Frontend::EmuWindow* secondary_window = {}); |
| |
|
| | |
| | |
| | |
| | |
| | |
| | [[nodiscard]] bool IsPoweredOn() const { |
| | return is_powered_on; |
| | } |
| |
|
| | |
| | |
| | |
| | |
| | [[nodiscard]] Core::TelemetrySession& TelemetrySession() const { |
| | return *telemetry_session; |
| | } |
| |
|
| | |
| | void PrepareReschedule(); |
| |
|
| | [[nodiscard]] PerfStats::Results GetAndResetPerfStats(); |
| |
|
| | [[nodiscard]] PerfStats::Results GetLastPerfStats(); |
| |
|
| | |
| | |
| | |
| | |
| |
|
| | [[nodiscard]] ARM_Interface& GetRunningCore() { |
| | return *running_core; |
| | }; |
| |
|
| | |
| | |
| | |
| | |
| | |
| |
|
| | [[nodiscard]] ARM_Interface& GetCore(u32 core_id) { |
| | 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()); |
| | } |
| |
|
| | void InvalidateCacheRange(u32 start_address, std::size_t length) { |
| | for (const auto& cpu : cpu_cores) { |
| | cpu->InvalidateCacheRange(start_address, length); |
| | } |
| | } |
| |
|
| | |
| | |
| | |
| | |
| | [[nodiscard]] AudioCore::DspInterface& DSP() { |
| | return *dsp_core; |
| | } |
| |
|
| | [[nodiscard]] VideoCore::GPU& GPU(); |
| |
|
| | |
| | |
| | |
| | |
| | [[nodiscard]] Service::SM::ServiceManager& ServiceManager(); |
| |
|
| | |
| | |
| | |
| | |
| | [[nodiscard]] const Service::SM::ServiceManager& ServiceManager() const; |
| |
|
| | |
| | [[nodiscard]] Service::FS::ArchiveManager& ArchiveManager(); |
| |
|
| | |
| | [[nodiscard]] const Service::FS::ArchiveManager& ArchiveManager() const; |
| |
|
| | |
| | [[nodiscard]] Kernel::KernelSystem& Kernel(); |
| |
|
| | |
| | [[nodiscard]] const Kernel::KernelSystem& Kernel() const; |
| |
|
| | |
| | [[nodiscard]] bool KernelRunning(); |
| |
|
| | |
| | [[nodiscard]] Timing& CoreTiming(); |
| |
|
| | |
| | [[nodiscard]] const Timing& CoreTiming() const; |
| |
|
| | |
| | [[nodiscard]] Memory::MemorySystem& Memory(); |
| |
|
| | |
| | [[nodiscard]] const Memory::MemorySystem& Memory() const; |
| |
|
| | |
| | [[nodiscard]] Cheats::CheatEngine& CheatEngine(); |
| |
|
| | |
| | [[nodiscard]] const Cheats::CheatEngine& CheatEngine() const; |
| |
|
| | |
| | [[nodiscard]] VideoCore::CustomTexManager& CustomTexManager(); |
| |
|
| | |
| | [[nodiscard]] const VideoCore::CustomTexManager& CustomTexManager() const; |
| |
|
| | |
| | [[nodiscard]] Core::Movie& Movie(); |
| |
|
| | |
| | [[nodiscard]] const Core::Movie& Movie() const; |
| |
|
| | |
| |
|
| | void RegisterVideoDumper(std::shared_ptr<VideoDumper::Backend> video_dumper); |
| |
|
| | [[nodiscard]] std::shared_ptr<VideoDumper::Backend> GetVideoDumper() const { |
| | return video_dumper; |
| | } |
| |
|
| | std::unique_ptr<PerfStats> perf_stats; |
| | FrameLimiter frame_limiter; |
| |
|
| | void SetStatus(ResultStatus new_status, const char* details = nullptr) { |
| | status = new_status; |
| | if (details) { |
| | status_details = details; |
| | } |
| | } |
| |
|
| | [[nodiscard]] const std::string& GetStatusDetails() const { |
| | return status_details; |
| | } |
| |
|
| | [[nodiscard]] Loader::AppLoader& GetAppLoader() const { |
| | return *app_loader; |
| | } |
| |
|
| | |
| |
|
| | void RegisterMiiSelector(std::shared_ptr<Frontend::MiiSelector> mii_selector); |
| |
|
| | void RegisterSoftwareKeyboard(std::shared_ptr<Frontend::SoftwareKeyboard> swkbd); |
| |
|
| | [[nodiscard]] std::shared_ptr<Frontend::MiiSelector> GetMiiSelector() const { |
| | return registered_mii_selector; |
| | } |
| |
|
| | [[nodiscard]] std::shared_ptr<Frontend::SoftwareKeyboard> GetSoftwareKeyboard() const { |
| | return registered_swkbd; |
| | } |
| |
|
| | |
| |
|
| | void RegisterImageInterface(std::shared_ptr<Frontend::ImageInterface> image_interface); |
| |
|
| | [[nodiscard]] std::shared_ptr<Frontend::ImageInterface> GetImageInterface() const { |
| | return registered_image_interface; |
| | } |
| |
|
| | |
| |
|
| | void RegisterMicPermissionCheck(const std::function<bool()>& permission_func) { |
| | mic_permission_func = permission_func; |
| | } |
| |
|
| | [[nodiscard]] bool HasMicPermission() { |
| | return !mic_permission_func || mic_permission_granted || |
| | (mic_permission_granted = mic_permission_func()); |
| | } |
| |
|
| | void SaveState(u32 slot) const; |
| |
|
| | void LoadState(u32 slot); |
| |
|
| | |
| | bool SetSelfDelete(const std::string& file) { |
| | if (m_filepath == file) { |
| | self_delete_pending = true; |
| | return true; |
| | } |
| | return false; |
| | } |
| |
|
| | |
| | void ApplySettings(); |
| |
|
| | private: |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | [[nodiscard]] ResultStatus Init(Frontend::EmuWindow& emu_window, |
| | Frontend::EmuWindow* secondary_window, |
| | Kernel::MemoryMode memory_mode, |
| | const Kernel::New3dsHwCapabilities& n3ds_hw_caps, |
| | u32 num_cores); |
| |
|
| | |
| | void Reschedule(); |
| |
|
| | |
| | std::unique_ptr<Loader::AppLoader> app_loader; |
| |
|
| | |
| | std::vector<std::shared_ptr<ARM_Interface>> cpu_cores; |
| | ARM_Interface* running_core = nullptr; |
| |
|
| | |
| | std::unique_ptr<AudioCore::DspInterface> dsp_core; |
| |
|
| | |
| | bool reschedule_pending{}; |
| |
|
| | |
| | std::unique_ptr<Core::TelemetrySession> telemetry_session; |
| |
|
| | std::unique_ptr<VideoCore::GPU> gpu; |
| |
|
| | |
| | std::unique_ptr<Service::SM::ServiceManager> service_manager; |
| |
|
| | |
| | std::shared_ptr<Frontend::MiiSelector> registered_mii_selector; |
| | std::shared_ptr<Frontend::SoftwareKeyboard> registered_swkbd; |
| |
|
| | |
| | Core::Movie movie; |
| |
|
| | |
| | Cheats::CheatEngine cheat_engine; |
| |
|
| | |
| | std::shared_ptr<VideoDumper::Backend> video_dumper; |
| |
|
| | |
| | std::unique_ptr<VideoCore::CustomTexManager> custom_tex_manager; |
| |
|
| | |
| | std::shared_ptr<Frontend::ImageInterface> registered_image_interface; |
| |
|
| | #ifdef ENABLE_SCRIPTING |
| | |
| | std::unique_ptr<RPC::Server> rpc_server; |
| | #endif |
| |
|
| | std::unique_ptr<Service::FS::ArchiveManager> archive_manager; |
| |
|
| | std::unique_ptr<Memory::MemorySystem> memory; |
| | std::unique_ptr<Kernel::KernelSystem> kernel; |
| | std::unique_ptr<Timing> timing; |
| |
|
| | std::unique_ptr<Core::ExclusiveMonitor> exclusive_monitor; |
| |
|
| | private: |
| | static System s_instance; |
| |
|
| | std::atomic_bool is_powered_on{}; |
| |
|
| | ResultStatus status = ResultStatus::Success; |
| | std::string status_details = ""; |
| | |
| | Frontend::EmuWindow* m_emu_window; |
| | Frontend::EmuWindow* m_secondary_window; |
| | std::string m_filepath; |
| | std::string m_chainloadpath; |
| | u64 title_id; |
| | bool self_delete_pending; |
| |
|
| | std::mutex signal_mutex; |
| | Signal current_signal; |
| | u32 signal_param; |
| |
|
| | std::function<bool()> mic_permission_func; |
| | bool mic_permission_granted = false; |
| |
|
| | boost::optional<Service::APT::DeliverArg> restore_deliver_arg; |
| | boost::optional<Service::PLGLDR::PLG_LDR::PluginLoaderContext> restore_plugin_context; |
| |
|
| | friend class boost::serialization::access; |
| | template <typename Archive> |
| | void serialize(Archive& ar, const unsigned int file_version); |
| | }; |
| |
|
| | [[nodiscard]] inline ARM_Interface& GetRunningCore() { |
| | return System::GetInstance().GetRunningCore(); |
| | } |
| |
|
| | [[nodiscard]] inline ARM_Interface& GetCore(u32 core_id) { |
| | return System::GetInstance().GetCore(core_id); |
| | } |
| |
|
| | [[nodiscard]] inline u32 GetNumCores() { |
| | return System::GetInstance().GetNumCores(); |
| | } |
| |
|
| | } |
| |
|
| | BOOST_CLASS_VERSION(Core::System, 1) |
| |
|