duckstation

duckstation, but archived from the revision just before upstream changed it to a proprietary software project, this version is the libre one
git clone https://git.neptards.moe/u3shit/duckstation.git
Log | Files | Refs | README | LICENSE

system.h (15956B)


      1 // SPDX-FileCopyrightText: 2019-2024 Connor McLaughlin <stenzek@gmail.com>
      2 // SPDX-License-Identifier: (GPL-3.0 OR CC-BY-NC-ND-4.0)
      3 
      4 #pragma once
      5 
      6 #include "settings.h"
      7 #include "types.h"
      8 
      9 #include "util/image.h"
     10 
     11 #include <memory>
     12 #include <optional>
     13 #include <string>
     14 
     15 class ByteStream;
     16 class CDImage;
     17 class Error;
     18 class SmallStringBase;
     19 class StateWrapper;
     20 class SocketMultiplexer;
     21 
     22 enum class GPUVSyncMode : u8;
     23 
     24 class Controller;
     25 
     26 struct CheatCode;
     27 class CheatList;
     28 
     29 class GPUTexture;
     30 class MediaCapture;
     31 
     32 namespace BIOS {
     33 struct ImageInfo;
     34 } // namespace BIOS
     35 
     36 namespace GameDatabase {
     37 struct Entry;
     38 }
     39 
     40 struct SystemBootParameters
     41 {
     42   SystemBootParameters();
     43   SystemBootParameters(const SystemBootParameters&);
     44   SystemBootParameters(SystemBootParameters&&);
     45   SystemBootParameters(std::string filename_);
     46   ~SystemBootParameters();
     47 
     48   std::string filename;
     49   std::string save_state;
     50   std::string override_exe;
     51   std::optional<bool> override_fast_boot;
     52   std::optional<bool> override_fullscreen;
     53   std::optional<bool> override_start_paused;
     54   u32 media_playlist_index = 0;
     55   bool load_image_to_ram = false;
     56   bool force_software_renderer = false;
     57   bool disable_achievements_hardcore_mode = false;
     58   bool start_media_capture = false;
     59 };
     60 
     61 struct SaveStateInfo
     62 {
     63   std::string path;
     64   std::time_t timestamp;
     65   s32 slot;
     66   bool global;
     67 };
     68 
     69 struct ExtendedSaveStateInfo
     70 {
     71   std::string title;
     72   std::string serial;
     73   std::string media_path;
     74   std::time_t timestamp;
     75 
     76   RGBA8Image screenshot;
     77 };
     78 
     79 namespace System {
     80 
     81 enum : s32
     82 {
     83   PER_GAME_SAVE_STATE_SLOTS = 10,
     84   GLOBAL_SAVE_STATE_SLOTS = 10
     85 };
     86 
     87 enum : TickCount
     88 {
     89   MASTER_CLOCK = 44100 * 0x300 // 33868800Hz or 33.8688MHz, also used as CPU clock
     90 };
     91 
     92 enum class State
     93 {
     94   Shutdown,
     95   Starting,
     96   Running,
     97   Paused,
     98   Stopping,
     99 };
    100 
    101 enum class BootMode
    102 {
    103   None,
    104   FullBoot,
    105   FastBoot,
    106   BootEXE,
    107   BootPSF,
    108 };
    109 
    110 using GameHash = u64;
    111 
    112 extern TickCount g_ticks_per_second;
    113 
    114 /// Returns true if the filename is a PlayStation executable we can inject.
    115 bool IsExeFileName(std::string_view path);
    116 
    117 /// Returns true if the filename is a Portable Sound Format file we can uncompress/load.
    118 bool IsPsfFileName(std::string_view path);
    119 
    120 /// Returns true if the filename is one we can load.
    121 bool IsLoadableFilename(std::string_view path);
    122 
    123 /// Returns true if the filename is a save state.
    124 bool IsSaveStateFilename(std::string_view path);
    125 
    126 /// Returns the preferred console type for a disc.
    127 ConsoleRegion GetConsoleRegionForDiscRegion(DiscRegion region);
    128 
    129 std::string GetExecutableNameForImage(CDImage* cdi, bool strip_subdirectories);
    130 bool ReadExecutableFromImage(CDImage* cdi, std::string* out_executable_name, std::vector<u8>* out_executable_data);
    131 
    132 std::string GetGameHashId(GameHash hash);
    133 bool GetGameDetailsFromImage(CDImage* cdi, std::string* out_id, GameHash* out_hash);
    134 GameHash GetGameHashFromFile(const char* path);
    135 DiscRegion GetRegionForSerial(const std::string_view serial);
    136 DiscRegion GetRegionFromSystemArea(CDImage* cdi);
    137 DiscRegion GetRegionForImage(CDImage* cdi);
    138 DiscRegion GetRegionForExe(const char* path);
    139 DiscRegion GetRegionForPsf(const char* path);
    140 
    141 /// Returns the path for the game settings ini file for the specified serial.
    142 std::string GetGameSettingsPath(std::string_view game_serial);
    143 
    144 /// Returns the path for the input profile ini file with the specified name (may not exist).
    145 std::string GetInputProfilePath(std::string_view name);
    146 
    147 State GetState();
    148 void SetState(State new_state);
    149 bool IsRunning();
    150 bool IsPaused();
    151 bool IsShutdown();
    152 bool IsValid();
    153 bool IsValidOrInitializing();
    154 bool IsExecuting();
    155 
    156 bool IsStartupCancelled();
    157 void CancelPendingStartup();
    158 void InterruptExecution();
    159 
    160 ConsoleRegion GetRegion();
    161 DiscRegion GetDiscRegion();
    162 bool IsPALRegion();
    163 
    164 ALWAYS_INLINE TickCount GetTicksPerSecond()
    165 {
    166   return g_ticks_per_second;
    167 }
    168 
    169 ALWAYS_INLINE_RELEASE TickCount ScaleTicksToOverclock(TickCount ticks)
    170 {
    171   if (!g_settings.cpu_overclock_active)
    172     return ticks;
    173 
    174   return static_cast<TickCount>(((static_cast<u64>(static_cast<u32>(ticks)) * g_settings.cpu_overclock_numerator) +
    175                                  (g_settings.cpu_overclock_denominator - 1)) /
    176                                 g_settings.cpu_overclock_denominator);
    177 }
    178 
    179 ALWAYS_INLINE_RELEASE TickCount UnscaleTicksToOverclock(TickCount ticks, TickCount* remainder)
    180 {
    181   if (!g_settings.cpu_overclock_active)
    182     return ticks;
    183 
    184   const u64 num =
    185     (static_cast<u32>(ticks) * static_cast<u64>(g_settings.cpu_overclock_denominator)) + static_cast<u32>(*remainder);
    186   const TickCount t = static_cast<u32>(num / g_settings.cpu_overclock_numerator);
    187   *remainder = static_cast<u32>(num % g_settings.cpu_overclock_numerator);
    188   return t;
    189 }
    190 
    191 TickCount GetMaxSliceTicks();
    192 void UpdateOverclock();
    193 
    194 GlobalTicks GetGlobalTickCounter();
    195 u32 GetFrameNumber();
    196 u32 GetInternalFrameNumber();
    197 void IncrementInternalFrameNumber();
    198 void FrameDone();
    199 
    200 const std::string& GetDiscPath();
    201 const std::string& GetGameSerial();
    202 const std::string& GetGameTitle();
    203 const std::string& GetExeOverride();
    204 const GameDatabase::Entry* GetGameDatabaseEntry();
    205 GameHash GetGameHash();
    206 bool IsRunningUnknownGame();
    207 BootMode GetBootMode();
    208 
    209 /// Returns the time elapsed in the current play session.
    210 u64 GetSessionPlayedTime();
    211 
    212 const BIOS::ImageInfo* GetBIOSImageInfo();
    213 
    214 static constexpr u32 NUM_FRAME_TIME_SAMPLES = 150;
    215 using FrameTimeHistory = std::array<float, NUM_FRAME_TIME_SAMPLES>;
    216 
    217 float GetFPS();
    218 float GetVPS();
    219 float GetEmulationSpeed();
    220 float GetAverageFrameTime();
    221 float GetMinimumFrameTime();
    222 float GetMaximumFrameTime();
    223 float GetThrottleFrequency();
    224 float GetCPUThreadUsage();
    225 float GetCPUThreadAverageTime();
    226 float GetSWThreadUsage();
    227 float GetSWThreadAverageTime();
    228 float GetGPUUsage();
    229 float GetGPUAverageTime();
    230 const FrameTimeHistory& GetFrameTimeHistory();
    231 u32 GetFrameTimeHistoryPos();
    232 void FormatLatencyStats(SmallStringBase& str);
    233 
    234 /// Loads global settings (i.e. EmuConfig).
    235 void LoadSettings(bool display_osd_messages);
    236 void SetDefaultSettings(SettingsInterface& si);
    237 
    238 /// Reloads settings, and applies any changes present.
    239 void ApplySettings(bool display_osd_messages);
    240 
    241 /// Reloads game specific settings, and applys any changes present.
    242 bool ReloadGameSettings(bool display_osd_messages);
    243 
    244 /// Reloads input sources.
    245 void ReloadInputSources();
    246 
    247 /// Reloads input bindings.
    248 void ReloadInputBindings();
    249 
    250 /// Reloads only controller settings.
    251 void UpdateControllerSettings();
    252 
    253 bool BootSystem(SystemBootParameters parameters, Error* error);
    254 void PauseSystem(bool paused);
    255 void ResetSystem();
    256 
    257 /// Loads state from the specified path.
    258 bool LoadState(const char* path, Error* error, bool save_undo_state);
    259 bool SaveState(const char* path, Error* error, bool backup_existing_save);
    260 bool SaveResumeState(Error* error);
    261 
    262 /// Runs the VM until the CPU execution is canceled.
    263 void Execute();
    264 
    265 void SingleStepCPU();
    266 
    267 /// Sets target emulation speed.
    268 float GetTargetSpeed();
    269 float GetAudioNominalRate();
    270 
    271 /// Adjusts the throttle frequency, i.e. how many times we should sleep per second.
    272 void SetThrottleFrequency(float frequency);
    273 
    274 // Access controllers for simulating input.
    275 Controller* GetController(u32 slot);
    276 void UpdateMemoryCardTypes();
    277 bool HasMemoryCard(u32 slot);
    278 bool IsSavingMemoryCards();
    279 
    280 /// Swaps memory cards in slot 1/2.
    281 void SwapMemoryCards();
    282 
    283 /// Dumps RAM to a file.
    284 bool DumpRAM(const char* filename);
    285 
    286 /// Dumps video RAM to a file.
    287 bool DumpVRAM(const char* filename);
    288 
    289 /// Dumps sound RAM to a file.
    290 bool DumpSPURAM(const char* filename);
    291 
    292 bool HasMedia();
    293 std::string GetMediaFileName();
    294 bool InsertMedia(const char* path);
    295 void RemoveMedia();
    296 
    297 /// Returns true if this is a multi-subimage image (e.g. m3u).
    298 bool HasMediaSubImages();
    299 
    300 /// Returns the number of entries in the media/disc playlist.
    301 u32 GetMediaSubImageCount();
    302 
    303 /// Returns the current image from the media/disc playlist.
    304 u32 GetMediaSubImageIndex();
    305 
    306 /// Returns the index of the specified path in the playlist, or UINT32_MAX if it does not exist.
    307 u32 GetMediaSubImageIndexForTitle(std::string_view title);
    308 
    309 /// Returns the path to the specified playlist index.
    310 std::string GetMediaSubImageTitle(u32 index);
    311 
    312 /// Switches to the specified media/disc playlist index.
    313 bool SwitchMediaSubImage(u32 index);
    314 
    315 /// Returns true if there is currently a cheat list.
    316 bool HasCheatList();
    317 
    318 /// Accesses the current cheat list.
    319 CheatList* GetCheatList();
    320 
    321 /// Applies a single cheat code.
    322 void ApplyCheatCode(const CheatCode& code);
    323 
    324 /// Sets or clears the provided cheat list, applying every frame.
    325 void SetCheatList(std::unique_ptr<CheatList> cheats);
    326 
    327 /// Updates throttler.
    328 void UpdateSpeedLimiterState();
    329 
    330 /// Toggles fast forward state.
    331 bool IsFastForwardEnabled();
    332 void SetFastForwardEnabled(bool enabled);
    333 
    334 /// Toggles turbo state.
    335 bool IsTurboEnabled();
    336 void SetTurboEnabled(bool enabled);
    337 
    338 /// Toggles rewind state.
    339 bool IsRewinding();
    340 void SetRewindState(bool enabled);
    341 
    342 void DoFrameStep();
    343 void DoToggleCheats();
    344 
    345 /// Returns the path to a save state file. Specifying an index of -1 is the "resume" save state.
    346 std::string GetGameSaveStateFileName(std::string_view serial, s32 slot);
    347 
    348 /// Returns the path to a save state file. Specifying an index of -1 is the "resume" save state.
    349 std::string GetGlobalSaveStateFileName(s32 slot);
    350 
    351 /// Returns the most recent resume save state.
    352 std::string GetMostRecentResumeSaveStatePath();
    353 
    354 /// Returns the path to the cheat file for the specified game title.
    355 std::string GetCheatFileName();
    356 
    357 /// Powers off the system, optionally saving the resume state.
    358 void ShutdownSystem(bool save_resume_state);
    359 
    360 /// Returns true if an undo load state exists.
    361 bool CanUndoLoadState();
    362 
    363 /// Returns save state info for the undo slot, if present.
    364 std::optional<ExtendedSaveStateInfo> GetUndoSaveStateInfo();
    365 
    366 /// Undoes a load state, i.e. restores the state prior to the load.
    367 bool UndoLoadState();
    368 
    369 /// Returns a list of save states for the specified game code.
    370 std::vector<SaveStateInfo> GetAvailableSaveStates(const char* serial);
    371 
    372 /// Returns save state info if present. If serial is null or empty, assumes global state.
    373 std::optional<SaveStateInfo> GetSaveStateInfo(const char* serial, s32 slot);
    374 
    375 /// Returns save state info from opened save state stream.
    376 std::optional<ExtendedSaveStateInfo> GetExtendedSaveStateInfo(const char* path);
    377 
    378 /// Deletes save states for the specified game code. If resume is set, the resume state is deleted too.
    379 void DeleteSaveStates(const char* serial, bool resume);
    380 
    381 /// Returns the path to the memory card for the specified game, considering game settings.
    382 std::string GetGameMemoryCardPath(std::string_view serial, std::string_view path, u32 slot,
    383                                   MemoryCardType* out_type = nullptr);
    384 
    385 /// Returns intended output volume considering fast forwarding.
    386 s32 GetAudioOutputVolume();
    387 void UpdateVolume();
    388 
    389 /// Saves a screenshot to the specified file. If no file name is provided, one will be generated automatically.
    390 bool SaveScreenshot(const char* filename = nullptr, DisplayScreenshotMode mode = g_settings.display_screenshot_mode,
    391                     DisplayScreenshotFormat format = g_settings.display_screenshot_format,
    392                     u8 quality = g_settings.display_screenshot_quality, bool compress_on_thread = true);
    393 
    394 #ifndef __ANDROID__
    395 
    396 /// Returns the path that a new media capture would be saved to by default. Safe to call from any thread.
    397 std::string GetNewMediaCapturePath(const std::string_view title, const std::string_view container);
    398 
    399 /// Current media capture (if active).
    400 MediaCapture* GetMediaCapture();
    401 
    402 /// Media capture (video and/or audio). If no path is provided, one will be generated automatically.
    403 bool StartMediaCapture(std::string path = {});
    404 bool StartMediaCapture(std::string path, bool capture_video, bool capture_audio);
    405 void StopMediaCapture();
    406 
    407 #endif
    408 
    409 /// Loads the cheat list for the current game title from the user directory.
    410 bool LoadCheatList();
    411 
    412 /// Loads the cheat list for the current game code from the built-in code database.
    413 bool LoadCheatListFromDatabase();
    414 
    415 /// Saves the current cheat list to the game title's file.
    416 bool SaveCheatList();
    417 
    418 /// Deletes the cheat list, if present.
    419 bool DeleteCheatList();
    420 
    421 /// Removes all cheats from the cheat list.
    422 void ClearCheatList(bool save_to_file);
    423 
    424 /// Enables/disabled the specified cheat code.
    425 void SetCheatCodeState(u32 index, bool enabled);
    426 
    427 /// Immediately applies the specified cheat code.
    428 void ApplyCheatCode(u32 index);
    429 
    430 /// Toggle Widescreen Hack and Aspect Ratio
    431 void ToggleWidescreen();
    432 
    433 /// Returns true if fast forwarding or slow motion is currently active.
    434 bool IsRunningAtNonStandardSpeed();
    435 
    436 /// Returns true if vsync should be used.
    437 GPUVSyncMode GetEffectiveVSyncMode();
    438 bool ShouldAllowPresentThrottle();
    439 
    440 /// Quick switch between software and hardware rendering.
    441 void ToggleSoftwareRendering();
    442 
    443 /// Resizes the render window to the display size, with an optional scale.
    444 /// If the scale is set to 0, the internal resolution will be used, otherwise it is treated as a multiplier to 1x.
    445 void RequestDisplaySize(float scale = 0.0f);
    446 
    447 /// Call when host display size changes, use with "match display" aspect ratio setting.
    448 void HostDisplayResized();
    449 
    450 /// Renders the display.
    451 bool PresentDisplay(bool skip_present, bool explicit_present);
    452 void InvalidateDisplay();
    453 
    454 //////////////////////////////////////////////////////////////////////////
    455 // Memory Save States (Rewind and Runahead)
    456 //////////////////////////////////////////////////////////////////////////
    457 void CalculateRewindMemoryUsage(u32 num_saves, u32 resolution_scale, u64* ram_usage, u64* vram_usage);
    458 void ClearMemorySaveStates();
    459 void SetRunaheadReplayFlag();
    460 
    461 /// Shared socket multiplexer, used by PINE/GDB/etc.
    462 SocketMultiplexer* GetSocketMultiplexer();
    463 void ReleaseSocketMultiplexer();
    464 
    465 /// Called when rich presence changes.
    466 void UpdateRichPresence(bool update_session_time);
    467 
    468 namespace Internal {
    469 /// Performs mandatory hardware checks.
    470 bool PerformEarlyHardwareChecks(Error* error);
    471 
    472 /// Called on process startup, as early as possible.
    473 bool ProcessStartup(Error* error);
    474 
    475 /// Called on process shutdown.
    476 void ProcessShutdown();
    477 
    478 /// Called on CPU thread initialization.
    479 bool CPUThreadInitialize(Error* error);
    480 
    481 /// Called on CPU thread shutdown.
    482 void CPUThreadShutdown();
    483 
    484 /// Polls input, updates subsystems which are present while paused/inactive.
    485 void IdlePollUpdate();
    486 } // namespace Internal
    487 
    488 } // namespace System
    489 
    490 namespace Host {
    491 /// Called with the settings lock held, when system settings are being loaded (should load input sources, etc).
    492 void LoadSettings(SettingsInterface& si, std::unique_lock<std::mutex>& lock);
    493 
    494 /// Called after settings are updated.
    495 void CheckForSettingsChanges(const Settings& old_settings);
    496 
    497 /// Called when the VM is starting initialization, but has not been completed yet.
    498 void OnSystemStarting();
    499 
    500 /// Called when the VM is created.
    501 void OnSystemStarted();
    502 
    503 /// Called when the VM is shut down or destroyed.
    504 void OnSystemDestroyed();
    505 
    506 /// Called when the VM is paused.
    507 void OnSystemPaused();
    508 
    509 /// Called when the VM is resumed after being paused.
    510 void OnSystemResumed();
    511 
    512 /// Called when the pause state changes, or fullscreen UI opens.
    513 void OnIdleStateChanged();
    514 
    515 /// Called when performance metrics are updated, approximately once a second.
    516 void OnPerformanceCountersUpdated();
    517 
    518 /// Provided by the host; called when the running executable changes.
    519 void OnGameChanged(const std::string& disc_path, const std::string& game_serial, const std::string& game_name);
    520 
    521 /// Called when media capture starts/stops.
    522 void OnMediaCaptureStarted();
    523 void OnMediaCaptureStopped();
    524 
    525 /// Provided by the host; called once per frame at guest vsync.
    526 void PumpMessagesOnCPUThread();
    527 
    528 /// Requests a specific display window size.
    529 void RequestResizeHostDisplay(s32 width, s32 height);
    530 
    531 /// Requests shut down of the current virtual machine.
    532 void RequestSystemShutdown(bool allow_confirm, bool save_state);
    533 } // namespace Host