2015-05-24 06:55:12 +02:00
|
|
|
// Copyright 2008 Dolphin Emulator Project
|
2021-07-05 03:22:19 +02:00
|
|
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
2008-12-08 04:46:09 +00:00
|
|
|
|
2008-10-16 22:06:06 +00:00
|
|
|
// Core
|
2008-12-08 04:46:09 +00:00
|
|
|
|
2008-10-16 22:06:06 +00:00
|
|
|
// The external interface to the emulator core. Plus some extras.
|
|
|
|
// This is another part of the emu that needs cleaning - Core.cpp really has
|
|
|
|
// too much random junk inside.
|
2008-12-08 04:46:09 +00:00
|
|
|
|
2014-02-10 13:54:46 -05:00
|
|
|
#pragma once
|
2008-12-08 04:46:09 +00:00
|
|
|
|
2016-05-12 01:18:30 +00:00
|
|
|
#include <functional>
|
2017-05-27 15:43:40 +02:00
|
|
|
#include <memory>
|
2008-07-12 17:40:22 +00:00
|
|
|
#include <string>
|
2019-07-03 18:41:43 -04:00
|
|
|
#include <string_view>
|
2008-12-08 04:46:09 +00:00
|
|
|
|
2014-02-17 05:18:15 -05:00
|
|
|
#include "Common/CommonTypes.h"
|
2008-12-08 04:46:09 +00:00
|
|
|
|
2017-05-27 15:43:40 +02:00
|
|
|
struct BootParameters;
|
2018-10-03 23:03:22 +10:00
|
|
|
struct WindowSystemInfo;
|
2017-05-27 15:43:40 +02:00
|
|
|
|
2008-07-12 17:40:22 +00:00
|
|
|
namespace Core
|
|
|
|
{
|
2023-03-07 04:02:48 +01:00
|
|
|
class System;
|
|
|
|
|
2015-12-16 00:10:47 +01:00
|
|
|
bool GetIsThrottlerTempDisabled();
|
|
|
|
void SetIsThrottlerTempDisabled(bool disable);
|
2013-03-18 20:41:45 -04:00
|
|
|
|
2020-12-31 14:03:20 +02:00
|
|
|
// Returns the latest emulation speed (1 is full speed) (swings a lot)
|
|
|
|
double GetActualEmulationSpeed();
|
|
|
|
|
|
|
|
void Callback_FramePresented(double actual_emulation_speed = 1.0);
|
2023-03-07 04:02:48 +01:00
|
|
|
void Callback_NewField(Core::System& system);
|
2008-12-08 04:46:09 +00:00
|
|
|
|
2017-02-06 01:13:04 -05:00
|
|
|
enum class State
|
2011-03-15 23:09:12 +00:00
|
|
|
{
|
2017-02-05 07:39:58 -05:00
|
|
|
Uninitialized,
|
|
|
|
Paused,
|
|
|
|
Running,
|
2017-07-01 14:08:58 -07:00
|
|
|
Stopping,
|
|
|
|
Starting,
|
2011-03-15 23:09:12 +00:00
|
|
|
};
|
2009-01-18 01:45:53 +00:00
|
|
|
|
2020-03-30 17:24:42 +04:00
|
|
|
// Console type values based on:
|
|
|
|
// - YAGCD 4.2.1.1.2
|
|
|
|
// - OSInit (GameCube ELF from Finding Nemo)
|
|
|
|
// - OSReportInfo (Wii ELF from Rayman Raving Rabbids)
|
|
|
|
enum class ConsoleType : u32
|
|
|
|
{
|
|
|
|
// 0x0XXXXXXX Retail units - Gamecube
|
|
|
|
HW1 = 1,
|
|
|
|
HW2 = 2,
|
|
|
|
LatestProductionBoard = 3,
|
|
|
|
Reserved = 4,
|
|
|
|
|
|
|
|
// 0x0XXXXXXX Retail units - Wii
|
|
|
|
PreProductionBoard0 = 0x10, // Pre-production board 0
|
|
|
|
PreProductionBoard1 = 0x11, // Pre-production board 1
|
|
|
|
PreProductionBoard2_1 = 0x12, // Pre-production board 2-1
|
|
|
|
PreProductionBoard2_2 = 0x20, // Pre-production board 2-2
|
|
|
|
RVL_Retail1 = 0x21,
|
|
|
|
RVL_Retail2 = 0x22,
|
|
|
|
RVL_Retail3 = 0x23,
|
|
|
|
RVA1 = 0x100, // Revolution Arcade
|
|
|
|
|
|
|
|
// 0x1XXXXXXX Devkits - Gamecube
|
|
|
|
// Emulators
|
|
|
|
MacEmulator = 0x10000000, // Mac Emulator
|
|
|
|
PcEmulator = 0x10000001, // PC Emulator
|
|
|
|
|
|
|
|
// Embedded PowerPC series
|
|
|
|
Arthur = 0x10000002, // EPPC Arthur
|
|
|
|
Minnow = 0x10000003, // EPPC Minnow
|
|
|
|
|
|
|
|
// Development HW
|
|
|
|
// Version = (console_type & 0x0fffffff) - 3
|
|
|
|
FirstDevkit = 0x10000004,
|
|
|
|
SecondDevkit = 0x10000005,
|
|
|
|
LatestDevkit = 0x10000006,
|
|
|
|
ReservedDevkit = 0x10000007,
|
|
|
|
|
|
|
|
// 0x1XXXXXXX Devkits - Wii
|
|
|
|
RevolutionEmulator = 0x10000008, // Revolution Emulator
|
|
|
|
NDEV1_0 = 0x10000010, // NDEV 1.0
|
|
|
|
NDEV1_1 = 0x10000011, // NDEV 1.1
|
|
|
|
NDEV1_2 = 0x10000012, // NDEV 1.2
|
|
|
|
NDEV2_0 = 0x10000020, // NDEV 2.0
|
|
|
|
NDEV2_1 = 0x10000021, // NDEV 2.1
|
|
|
|
|
|
|
|
// 0x2XXXXXXX TDEV-based emulation HW
|
|
|
|
// Version = (console_type & 0x0fffffff) - 3
|
|
|
|
HW2TDEVSystem = 0x20000005,
|
|
|
|
LatestTDEVSystem = 0x20000006,
|
|
|
|
ReservedTDEVSystem = 0x20000007,
|
|
|
|
};
|
|
|
|
|
2024-03-22 00:43:04 -07:00
|
|
|
// This is an RAII alternative to using PauseAndLock. If constructed from the host thread, the CPU
|
|
|
|
// thread is paused, and the current thread temporarily becomes the CPU thread. If constructed from
|
|
|
|
// the CPU thread, nothing special happens. This should only be constructed on the CPU thread or the
|
|
|
|
// host thread.
|
2023-02-12 11:07:11 +01:00
|
|
|
//
|
|
|
|
// Some functions use a parameter of this type to indicate that the function should only be called
|
|
|
|
// from the CPU thread. If the parameter is a pointer, the function has a fallback for being called
|
|
|
|
// from the wrong thread (with the argument being set to nullptr).
|
|
|
|
class CPUThreadGuard final
|
|
|
|
{
|
|
|
|
public:
|
2023-03-08 01:58:05 +01:00
|
|
|
explicit CPUThreadGuard(Core::System& system);
|
2023-02-12 11:07:11 +01:00
|
|
|
~CPUThreadGuard();
|
|
|
|
|
|
|
|
CPUThreadGuard(const CPUThreadGuard&) = delete;
|
|
|
|
CPUThreadGuard(CPUThreadGuard&&) = delete;
|
|
|
|
CPUThreadGuard& operator=(const CPUThreadGuard&) = delete;
|
|
|
|
CPUThreadGuard& operator=(CPUThreadGuard&&) = delete;
|
|
|
|
|
2023-03-12 18:48:23 +01:00
|
|
|
Core::System& GetSystem() const { return m_system; }
|
|
|
|
|
2023-02-12 11:07:11 +01:00
|
|
|
private:
|
2023-03-08 01:58:05 +01:00
|
|
|
Core::System& m_system;
|
2023-02-12 11:07:11 +01:00
|
|
|
const bool m_was_cpu_thread;
|
|
|
|
bool m_was_unpaused = false;
|
|
|
|
};
|
|
|
|
|
2024-01-05 04:45:41 +01:00
|
|
|
bool Init(Core::System& system, std::unique_ptr<BootParameters> boot, const WindowSystemInfo& wsi);
|
2024-03-18 01:35:42 -07:00
|
|
|
void Stop(Core::System& system);
|
|
|
|
void Shutdown(Core::System& system);
|
2010-06-06 03:52:11 +00:00
|
|
|
|
2015-06-06 01:41:26 -04:00
|
|
|
void DeclareAsCPUThread();
|
|
|
|
void UndeclareAsCPUThread();
|
2020-04-25 00:26:51 +02:00
|
|
|
void DeclareAsGPUThread();
|
|
|
|
void UndeclareAsGPUThread();
|
2023-06-02 18:00:51 +02:00
|
|
|
void DeclareAsHostThread();
|
|
|
|
void UndeclareAsHostThread();
|
2015-06-06 01:41:26 -04:00
|
|
|
|
2019-07-03 18:41:43 -04:00
|
|
|
std::string StopMessage(bool main_thread, std::string_view message);
|
2010-07-16 14:14:57 +00:00
|
|
|
|
2024-04-08 20:33:55 -07:00
|
|
|
bool IsRunning(Core::System& system);
|
2024-06-02 15:10:25 +02:00
|
|
|
bool IsRunningOrStarting(Core::System& system);
|
|
|
|
bool IsCPUThread(); // this tells us whether we are the CPU thread.
|
2011-12-30 20:16:12 -08:00
|
|
|
bool IsGPUThread();
|
2023-06-02 18:00:51 +02:00
|
|
|
bool IsHostThread();
|
2011-12-30 20:16:12 -08:00
|
|
|
|
2017-04-03 13:30:58 -04:00
|
|
|
bool WantsDeterminism();
|
|
|
|
|
2016-05-12 09:17:17 +00:00
|
|
|
// [NOT THREADSAFE] For use by Host only
|
2024-06-13 19:58:18 -04:00
|
|
|
void SetState(Core::System& system, State state, bool report_state_change = true,
|
|
|
|
bool initial_execution_state = false);
|
2024-03-28 11:35:13 -07:00
|
|
|
State GetState(Core::System& system);
|
2009-02-22 21:16:12 +00:00
|
|
|
|
2020-08-06 21:57:12 +02:00
|
|
|
void SaveScreenShot();
|
|
|
|
void SaveScreenShot(std::string_view name);
|
2011-03-15 23:09:12 +00:00
|
|
|
|
|
|
|
// This displays messages in a user-visible way.
|
2019-07-28 22:46:08 -04:00
|
|
|
void DisplayMessage(std::string message, int time_in_ms);
|
2013-10-29 01:23:17 -04:00
|
|
|
|
2015-06-06 01:20:51 -04:00
|
|
|
void FrameUpdateOnCPUThread();
|
2024-03-18 01:35:42 -07:00
|
|
|
void OnFrameEnd(Core::System& system);
|
2015-06-06 01:20:51 -04:00
|
|
|
|
2019-06-29 18:18:24 +10:00
|
|
|
// Run a function on the CPU thread, asynchronously.
|
|
|
|
// This is only valid to call from the host thread, since it uses PauseAndLock() internally.
|
2024-03-22 00:24:26 -07:00
|
|
|
void RunOnCPUThread(Core::System& system, std::function<void()> function, bool wait_for_completion);
|
2019-06-29 18:18:24 +10:00
|
|
|
|
2014-06-20 02:43:57 +02:00
|
|
|
// for calling back into UI code without introducing a dependency on it in core
|
2017-09-04 10:57:42 -07:00
|
|
|
using StateChangedCallbackFunc = std::function<void(Core::State)>;
|
2020-12-31 14:03:20 +02:00
|
|
|
// Returns a handle
|
|
|
|
int AddOnStateChangedCallback(StateChangedCallbackFunc callback);
|
|
|
|
// Also invalidates the handle
|
|
|
|
bool RemoveOnStateChangedCallback(int* handle);
|
|
|
|
void CallOnStateChangedCallbacks(Core::State state);
|
2014-06-20 02:43:57 +02:00
|
|
|
|
2016-05-12 09:17:17 +00:00
|
|
|
// Run on the Host thread when the factors change. [NOT THREADSAFE]
|
2024-03-18 01:35:42 -07:00
|
|
|
void UpdateWantDeterminism(Core::System& system, bool initial = false);
|
2014-09-06 17:26:40 -04:00
|
|
|
|
2016-05-12 01:18:30 +00:00
|
|
|
// Queue an arbitrary function to asynchronously run once on the Host thread later.
|
|
|
|
// Threadsafe. Can be called by any thread, including the Host itself.
|
|
|
|
// Jobs will be executed in RELATIVE order. If you queue 2 jobs from the same thread
|
|
|
|
// then they will be executed in the order they were queued; however, there is no
|
|
|
|
// global order guarantee across threads - jobs from other threads may execute in
|
|
|
|
// between.
|
|
|
|
// NOTE: Make sure the jobs check the global state instead of assuming everything is
|
|
|
|
// still the same as when the job was queued.
|
|
|
|
// NOTE: Jobs that are not set to run during stop will be discarded instead.
|
2024-03-18 01:35:42 -07:00
|
|
|
void QueueHostJob(std::function<void(Core::System&)> job, bool run_during_stop = false);
|
2016-05-12 01:18:30 +00:00
|
|
|
|
|
|
|
// Should be called periodically by the Host to run pending jobs.
|
2018-05-28 13:03:29 -04:00
|
|
|
// WMUserJobDispatch will be sent when something is added to the queue.
|
2024-03-18 01:35:42 -07:00
|
|
|
void HostDispatchJobs(Core::System& system);
|
2016-05-12 01:18:30 +00:00
|
|
|
|
2024-03-28 11:35:13 -07:00
|
|
|
void DoFrameStep(Core::System& system);
|
2017-07-01 13:17:18 -07:00
|
|
|
|
2021-05-09 13:28:04 +03:00
|
|
|
void UpdateInputGate(bool require_focus, bool require_full_focus = false);
|
2019-11-06 15:59:36 -06:00
|
|
|
|
2024-03-18 01:35:42 -07:00
|
|
|
void UpdateTitle(Core::System& system);
|
2023-01-21 00:44:25 +01:00
|
|
|
|
2018-10-03 23:03:22 +10:00
|
|
|
} // namespace Core
|