#pragma once #include "util/types.hpp" #include "util/atomic.hpp" #include #include #include #include u64 get_system_time(); u64 get_guest_system_time(); enum class localized_string_id; enum class video_renderer; enum class system_state { running, paused, stopped, ready, }; enum class game_boot_result : u32 { no_errors, generic_error, nothing_to_boot, wrong_disc_location, invalid_file_or_folder, install_failed, decryption_error, file_creation_error, firmware_missing, unsupported_disc_type }; struct EmuCallbacks { std::function)> call_after; std::function on_run; // (start_playtime) continuing or going ingame, so start the clock std::function on_pause; std::function on_resume; std::function on_stop; std::function on_ready; std::function on_missing_fw; std::function)> try_to_quit; // (force_quit, on_exit) Try to close RPCS3 std::function handle_taskbar_progress; // (type, value) type: 0 for reset, 1 for increment, 2 for set_limit std::function init_kb_handler; std::function init_mouse_handler; std::function init_pad_handler; std::function()> get_gs_frame; std::function init_gs_render; std::function()> get_audio; std::function()> get_msg_dialog; std::function()> get_osk_dialog; std::function()> get_save_dialog; std::function()> get_trophy_notification_dialog; std::function get_localized_string; std::function get_localized_u32string; }; class Emulator final { atomic_t m_state{system_state::stopped}; EmuCallbacks m_cb; atomic_t m_pause_start_time{0}; // set when paused atomic_t m_pause_amend_time{0}; // increased when resumed video_renderer m_default_renderer; std::string m_default_graphics_adapter; std::string m_config_override_path; std::string m_path; std::string m_path_old; std::string m_title_id; std::string m_title; std::string m_app_version; std::string m_cat; std::string m_dir; std::string m_sfo_dir; std::string m_game_dir{"PS3_GAME"}; std::string m_usr{"00000001"}; u32 m_usrid{1}; bool m_force_global_config = false; // This flag should be adjusted before each Stop() or each BootGame() and similar because: // 1. It forces an application to boot immediately by calling Run() in Load(). // 2. It signifies that we don't want to exit on Stop(), for example if we want to transition to another application. bool m_force_boot = false; bool m_has_gui = true; public: Emulator() = default; void SetCallbacks(EmuCallbacks&& cb) { m_cb = std::move(cb); } const auto& GetCallbacks() const { return m_cb; } // Call from the GUI thread void CallAfter(std::function&& func) const { return m_cb.call_after(std::move(func)); } /** Set emulator mode to running unconditionnaly. * Required to execute various part (PPUInterpreter, memory manager...) outside of rpcs3. */ void SetTestMode() { m_state = system_state::running; } void Init(); std::vector argv; std::vector envp; std::vector data; std::vector klic; std::string disc; std::string hdd1; const std::string& GetBoot() const { return m_path; } const std::string& GetTitleID() const { return m_title_id; } const std::string& GetTitle() const { return m_title; } const std::string GetTitleAndTitleID() const { return m_title + (m_title_id.empty() ? "" : " [" + m_title_id + "]"); } const std::string& GetAppVersion() const { return m_app_version; } const std::string& GetCat() const { return m_cat; } const std::string& GetDir() const { return m_dir; } const std::string& GetSfoDir() const { return m_sfo_dir; } // String for GUI dialogs. const std::string& GetUsr() const { return m_usr; } // u32 for cell. const u32 GetUsrId() const { return m_usrid; } const bool SetUsr(const std::string& user); const std::string GetBackgroundPicturePath() const; u64 GetPauseTime() { return m_pause_amend_time; } std::string PPUCache() const; game_boot_result BootGame(const std::string& path, const std::string& title_id = "", bool direct = false, bool add_only = false, bool force_global_config = false); bool BootRsxCapture(const std::string& path); bool InstallPkg(const std::string& path); #ifdef _WIN32 static std::string GetExeDir(); #endif static std::string GetEmuDir(); static std::string GetHddDir(); static std::string GetHdd1Dir(); static std::string GetCacheDir(); static std::string GetSfoDirFromGamePath(const std::string& game_path, const std::string& user, const std::string& title_id = ""); static std::string GetCustomConfigDir(); static std::string GetCustomConfigPath(const std::string& title_id, bool get_deprecated_path = false); static std::string GetCustomInputConfigDir(const std::string& title_id); static std::string GetCustomInputConfigPath(const std::string& title_id); void SetForceBoot(bool force_boot); game_boot_result Load(const std::string& title_id = "", bool add_only = false, bool force_global_config = false, bool is_disc_patch = false); void Run(bool start_playtime); bool Pause(); void Resume(); void Stop(bool restart = false); void Restart() { Stop(true); } bool Quit(bool force_quit); bool IsRunning() const { return m_state == system_state::running; } bool IsPaused() const { return m_state == system_state::paused; } bool IsStopped() const { return m_state == system_state::stopped; } bool IsReady() const { return m_state == system_state::ready; } auto GetStatus() const { return m_state.load(); } bool HasGui() const { return m_has_gui; } void SetHasGui(bool has_gui) { m_has_gui = has_gui; } void SetDefaultRenderer(video_renderer renderer) { m_default_renderer = renderer; } void SetDefaultGraphicsAdapter(std::string adapter) { m_default_graphics_adapter = std::move(adapter); } void SetConfigOverride(std::string path) { m_config_override_path = std::move(path); } std::string GetFormattedTitle(double fps) const; u32 GetMaxThreads() const; void ConfigureLogs(); void ConfigurePPUCache(); private: void LimitCacheSize(); }; extern Emulator Emu; extern bool g_use_rtm; extern u64 g_rtm_tx_limit1; extern u64 g_rtm_tx_limit2;