#pragma once #include "VFS.h" #include "DbgCommand.h" enum class system_type { ps3, psv, // Experimental //psp, // Hypothetical }; // Current process type extern system_type g_system; enum class frame_type; struct EmuCallbacks { std::function)> call_after; std::function process_events; std::function exit; std::function send_dbg_command; std::function()> get_kb_handler; std::function()> get_mouse_handler; std::function()> get_pad_handler; std::function(frame_type, int, int)> get_gs_frame; std::function()> get_gs_render; std::function()> get_audio; std::function()> get_msg_dialog; std::function()> get_save_dialog; }; enum Status : u32 { Running, Paused, Stopped, Ready, }; // Emulation Stopped exception event class EmulationStopped {}; class Emulator final { atomic_t m_status; EmuCallbacks m_cb; atomic_t m_pause_start_time; // set when paused atomic_t m_pause_amend_time; // increased when resumed u32 m_cpu_thr_stop; std::string m_path; std::string m_elf_path; std::string m_title_id; std::string m_title; public: Emulator(); void SetCallbacks(EmuCallbacks&& cb) { m_cb = std::move(cb); } const auto& GetCallbacks() const { return m_cb; } void SendDbgCommand(DbgCommand cmd, class cpu_thread* thread = nullptr) { if (m_cb.send_dbg_command) m_cb.send_dbg_command(cmd, thread); } // 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_status = Running; } void Init(); void SetPath(const std::string& path, const std::string& elf_path = {}); const std::string& GetPath() const { return m_elf_path; } const std::string& GetTitleID() const { return m_title_id; } const std::string& GetTitle() const { return m_title; } u64 GetPauseTime() { return m_pause_amend_time; } void SetCPUThreadStop(u32 addr) { m_cpu_thr_stop = addr; } u32 GetCPUThreadStop() const { return m_cpu_thr_stop; } bool BootGame(const std::string& path, bool direct = false); static std::string GetGameDir(); static std::string GetLibDir(); void Load(); void Run(); bool Pause(); void Resume(); void Stop(); bool IsRunning() const { return m_status == Running; } bool IsPaused() const { return m_status == Paused; } bool IsStopped() const { return m_status == Stopped; } bool IsReady() const { return m_status == Ready; } }; extern Emulator Emu; #define CHECK_EMU_STATUS if (Emu.IsStopped()) throw EmulationStopped{}