VMManager: Introduce new manager functions

VMManager takes the place of all the core thread stuff for Qt.
This commit is contained in:
Connor McLaughlin 2021-12-08 21:14:55 +10:00 committed by refractionpcsx2
parent 14c9cfb310
commit 728e1ffdd0
6 changed files with 1563 additions and 2 deletions

View File

@ -222,7 +222,7 @@ static std::array<std::unique_ptr<InputSource>, static_cast<u32>(InputSourceType
// ------------------------------------------------------------------------
// Hotkeys
// ------------------------------------------------------------------------
static const HotkeyInfo* const s_hotkey_list[] = {g_vm_manager_hotkeys, g_host_hotkeys};
static const HotkeyInfo* const s_hotkey_list[] = {g_vm_manager_hotkeys, g_gs_hotkeys, g_host_hotkeys};
// ------------------------------------------------------------------------
// Binding Parsing

View File

@ -121,6 +121,7 @@ struct HotkeyInfo
#define END_HOTKEY_LIST() {nullptr, nullptr, nullptr, nullptr} };
DECLARE_HOTKEY_LIST(g_vm_manager_hotkeys);
DECLARE_HOTKEY_LIST(g_gs_hotkeys);
DECLARE_HOTKEY_LIST(g_host_hotkeys);
/// External input source class.

View File

@ -16,7 +16,6 @@
#include "PrecompiledHeader.h"
#include "Frontend/XInputSource.h"
#include "Frontend/InputManager.h"
#include "HostSettings.h"
#include "common/Assertions.h"
#include "common/StringUtil.h"
#include "common/Console.h"

View File

@ -39,6 +39,7 @@
#include "pcsx2/GS.h"
#ifdef PCSX2_CORE
#include "pcsx2/HostSettings.h"
#include "pcsx2/Frontend/InputManager.h"
#endif
#ifdef ENABLE_VULKAN
@ -1509,3 +1510,98 @@ void GSApp::SetConfig(const char* entry, int value)
SetConfig(entry, buff);
}
#ifdef PCSX2_CORE
static void HotkeyAdjustUpscaleMultiplier(s32 delta)
{
const u32 new_multiplier = static_cast<u32>(std::clamp(static_cast<s32>(EmuConfig.GS.UpscaleMultiplier) + delta, 1, 8));
Host::AddKeyedFormattedOSDMessage("UpscaleMultiplierChanged", 10.0f, "Upscale multiplier set to %ux.", new_multiplier);
EmuConfig.GS.UpscaleMultiplier = new_multiplier;
// this is pretty slow. we only really need to flush the TC and recompile shaders.
// TODO(Stenzek): Make it faster at some point in the future.
GetMTGS().ApplySettings();
}
static void HotkeyAdjustZoom(double delta)
{
const double new_zoom = std::clamp(EmuConfig.GS.Zoom + delta, 1.0, 200.0);
Host::AddKeyedFormattedOSDMessage("ZoomChanged", 10.0f, "Zoom set to %.1f%%.", new_zoom);
EmuConfig.GS.Zoom = new_zoom;
// no need to go through the full settings update for this
GetMTGS().RunOnGSThread([new_zoom]() { GSConfig.Zoom = new_zoom; });
}
BEGIN_HOTKEY_LIST(g_gs_hotkeys){
"ToggleSoftwareRendering", "Graphics", "Toggle Software Rendering", [](bool pressed) {
if (!pressed)
GetMTGS().ToggleSoftwareRendering();
}},
{"IncreaseUpscaleMultiplier", "Graphics", "Increase Upscale Multiplier", [](bool pressed) {
if (!pressed)
HotkeyAdjustUpscaleMultiplier(1);
}},
{"DecreaseUpscaleMultiplier", "Graphics", "Decrease Upscale Multiplier", [](bool pressed) {
if (!pressed)
HotkeyAdjustUpscaleMultiplier(-1);
}},
{"CycleAspectRatio", "Graphics", "Cycle Aspect Ratio", [](bool pressed) {
if (pressed)
return;
GetMTGS().RunOnGSThread([]() {
GSConfig.AspectRatio = static_cast<AspectRatioType>((static_cast<int>(GSConfig.AspectRatio) + 1) % static_cast<int>(AspectRatioType::MaxCount));
Host::AddKeyedFormattedOSDMessage("CycleAspectRatio", 10.0f, "Aspect ratio set to '%s'.", Pcsx2Config::GSOptions::AspectRatioNames[static_cast<int>(GSConfig.AspectRatio)]);
});
}},
{"CycleMipmapMode", "Graphics", "Cycle Hardware Mipmapping", [](bool pressed) {
if (pressed)
return;
static constexpr s32 CYCLE_COUNT = 4;
static constexpr std::array<const char*, CYCLE_COUNT> option_names = {{"Automatic", "Off", "Basic (Generated)", "Full (PS2)"}};
const HWMipmapLevel new_level = static_cast<HWMipmapLevel>(((static_cast<s32>(EmuConfig.GS.HWMipmap) + 2) % CYCLE_COUNT) - 1);
Host::AddKeyedFormattedOSDMessage("CycleMipmapMode", 10.0f, "Hardware mipmapping set to '%s'.", option_names[static_cast<s32>(new_level) + 1]);
EmuConfig.GS.HWMipmap = new_level;
GetMTGS().RunOnGSThread([new_level]() {
GSConfig.HWMipmap = new_level;
s_gs->PurgeTextureCache();
s_gs->PurgePool();
});
}},
{"CycleInterlaceMode", "Graphics", "Cycle Interlace Mode", [](bool pressed) {
if (pressed)
return;
static constexpr std::array<const char*, static_cast<int>(GSInterlaceMode::Count)> option_names = {{
"Off",
"Weave (Top Field First)",
"Weave (Bottom Field First)",
"Bob (Top Field First)",
"Bob (Bottom Field First)",
"Blend (Top Field First)",
"Blend (Bottom Field First)",
"Automatic",
}};
const GSInterlaceMode new_mode = static_cast<GSInterlaceMode>((static_cast<s32>(EmuConfig.GS.InterlaceMode) + 1) % static_cast<s32>(GSInterlaceMode::Count));
Host::AddKeyedFormattedOSDMessage("CycleMipmapMode", 10.0f, "Interlace mode set to '%s'.", option_names[static_cast<s32>(new_mode)]);
EmuConfig.GS.InterlaceMode = new_mode;
GetMTGS().RunOnGSThread([new_mode]() { GSConfig.InterlaceMode = new_mode; });
}},
{"ZoomIn", "Graphics", "Zoom In", [](bool pressed) {
if (!pressed)
HotkeyAdjustZoom(1.0);
}},
{"ZoomOut", "Graphics", "Zoom Out", [](bool pressed) {
if (!pressed)
HotkeyAdjustZoom(-1.0);
}},
END_HOTKEY_LIST()
#endif

1275
pcsx2/VMManager.cpp Normal file

File diff suppressed because it is too large Load Diff

190
pcsx2/VMManager.h Normal file
View File

@ -0,0 +1,190 @@
/* PCSX2 - PS2 Emulator for PCs
* Copyright (C) 2002-2022 PCSX2 Dev Team
*
* PCSX2 is free software: you can redistribute it and/or modify it under the terms
* of the GNU Lesser General Public License as published by the Free Software Found-
* ation, either version 3 of the License, or (at your option) any later version.
*
* PCSX2 is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
* PURPOSE. See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with PCSX2.
* If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
#include <string>
#include <string_view>
#include <optional>
#include <wx/string.h>
#include "common/Pcsx2Defs.h"
#include <functional>
#include <optional>
#include <string>
#include <vector>
enum class CDVD_SourceType : uint8_t;
enum class VMState
{
Shutdown,
Initializing,
Running,
Paused,
Stopping,
};
struct VMBootParameters
{
std::string source;
std::string save_state;
CDVD_SourceType source_type;
std::string elf_override;
std::optional<bool> fast_boot;
std::optional<bool> fullscreen;
std::optional<bool> batch_mode;
};
namespace VMManager
{
/// Returns the current state of the VM.
VMState GetState();
/// Alters the current state of the VM.
void SetState(VMState state);
/// Returns true if there is an active virtual machine.
bool HasValidVM();
/// Returns the path of the disc currently running.
std::string GetDiscPath();
/// Returns the crc of the executable currently running.
u32 GetGameCRC();
/// Returns the serial of the disc/executable currently running.
std::string GetGameSerial();
/// Returns the name of the disc/executable currently running.
std::string GetGameName();
/// Reserves memory for the virtual machines.
bool InitializeMemory();
/// Completely releases all memory for the virtual machine.
void ReleaseMemory();
/// Initializes all system components.
bool Initialize(const VMBootParameters& boot_params);
/// Destroys all system components.
void Shutdown(bool allow_save_resume_state = true);
/// Resets all subsystems to a cold boot.
void Reset();
/// Runs the VM until the CPU execution is canceled.
void Execute();
/// Changes the pause state of the VM, resetting anything needed when unpausing.
void SetPaused(bool paused);
/// Reloads settings, and applies any changes present.
void ApplySettings();
/// Reloads game specific settings, and applys any changes present.
void ReloadGameSettings();
/// Reloads cheats/patches. If verbose is set, the number of patches loaded will be shown in the OSD.
void ReloadPatches(bool verbose);
/// Returns true if a resume save state should be saved/loaded.
bool ShouldSaveResumeState();
/// Returns the save state filename for the given game serial/crc.
std::string GetSaveStateFileName(const char* game_serial, u32 game_crc, s32 slot);
/// Returns true if there is a save state in the specified slot.
bool HasSaveStateInSlot(const char* game_serial, u32 game_crc, s32 slot);
/// Loads state from the specified file.
bool LoadState(const char* filename);
/// Loads state from the specified slot.
bool LoadStateFromSlot(s32 slot);
/// Saves state to the specified filename.
bool SaveState(const char* filename);
/// Saves state to the specified slot.
bool SaveStateToSlot(s32 slot);
/// Returns the current limiter mode.
LimiterModeType GetLimiterMode();
/// Updates the host vsync state, as well as timer frequencies. Call when the speed limiter is adjusted.
void SetLimiterMode(LimiterModeType type);
/// Changes the disc in the virtual CD/DVD drive. Passing an empty will remove any current disc.
/// Returns false if the new disc can't be opened.
bool ChangeDisc(std::string path);
/// Returns true if the specified path is an ELF.
bool IsElfFileName(const std::string& path);
/// Updates boot parameters for a given start filename. If it's an elf, it'll set elf_override, otherwise source.
void SetBootParametersForPath(const std::string& path, VMBootParameters* params);
/// Returns the path for the game settings ini file for the specified CRC.
std::string GetGameSettingsPath(u32 game_crc);
/// Resizes the render window to the display size, with an optional scale.
/// If the scale is set to 0, the internal resolution will be used, otherwise it is treated as a multiplier to 1x.
void RequestDisplaySize(float scale = 0.0f);
/// Internal callbacks, implemented in the emu core.
namespace Internal
{
const std::string& GetElfOverride();
bool IsExecutionInterrupted();
void GameStartingOnCPUThread();
void VSyncOnCPUThread();
}
} // namespace VMManager
namespace Host
{
/// Called when the VM is starting initialization, but has not been completed yet.
void OnVMStarting();
/// Called when the VM is created.
void OnVMStarted();
/// Called when the VM is shut down or destroyed.
void OnVMDestroyed();
/// Called when the VM is paused.
void OnVMPaused();
/// Called when the VM is resumed after being paused.
void OnVMResumed();
/// Provided by the host; called when the running executable changes.
void OnGameChanged(const std::string& disc_path, const std::string& game_serial, const std::string& game_name, u32 game_crc);
/// Provided by the host; called once per frame at guest vsync.
void PumpMessagesOnCPUThread();
/// Provided by the host; called when a state is saved, and the frontend should invalidate its save state cache.
void InvalidateSaveStateCache();
/// Requests a specific display window size.
void RequestResizeHostDisplay(s32 width, s32 height);
/// Safely executes a function on the VM thread.
void RunOnCPUThread(std::function<void()> function, bool block = false);
}