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