mirror of https://github.com/PCSX2/pcsx2.git
Qt: Deduplicate interface code and reduce core coupling
This enables more code sharing between interfaces in the future (e.g. nogui, gsrunner, etc). Eventually I'll move everything in Frontend/ to its own project. - VMManager now no longer depends on anything in Frontend. - Moved INISettingsInterface out of Frontend. - Log settings can now be overridden per-game (if you really want to).. - Hotkeys get their own file.
This commit is contained in:
parent
c96f1d28e6
commit
6810a9d593
|
@ -309,23 +309,17 @@ void MainWindow::connectSignals()
|
|||
SettingWidgetBinder::BindWidgetToBoolSetting(nullptr, m_ui.actionViewStatusBarVerbose, "UI", "VerboseStatusBar", false);
|
||||
|
||||
SettingWidgetBinder::BindWidgetToBoolSetting(nullptr, m_ui.actionEnableSystemConsole, "Logging", "EnableSystemConsole", false);
|
||||
connect(m_ui.actionEnableSystemConsole, &QAction::triggered, this, &MainWindow::onLoggingOptionChanged);
|
||||
#ifndef PCSX2_DEVBUILD
|
||||
SettingWidgetBinder::BindWidgetToBoolSetting(nullptr, m_ui.actionEnableVerboseLogging, "Logging", "EnableVerbose", false);
|
||||
connect(m_ui.actionEnableVerboseLogging, &QAction::triggered, this, &MainWindow::onLoggingOptionChanged);
|
||||
#else
|
||||
// Dev builds always have verbose logging.
|
||||
m_ui.actionEnableVerboseLogging->setChecked(true);
|
||||
m_ui.actionEnableVerboseLogging->setEnabled(false);
|
||||
#endif
|
||||
SettingWidgetBinder::BindWidgetToBoolSetting(nullptr, m_ui.actionEnableEEConsoleLogging, "Logging", "EnableEEConsole", true);
|
||||
connect(m_ui.actionEnableEEConsoleLogging, &QAction::triggered, this, &MainWindow::onLoggingOptionChanged);
|
||||
SettingWidgetBinder::BindWidgetToBoolSetting(nullptr, m_ui.actionEnableIOPConsoleLogging, "Logging", "EnableIOPConsole", true);
|
||||
connect(m_ui.actionEnableIOPConsoleLogging, &QAction::triggered, this, &MainWindow::onLoggingOptionChanged);
|
||||
SettingWidgetBinder::BindWidgetToBoolSetting(nullptr, m_ui.actionEnableFileLogging, "Logging", "EnableFileLogging", false);
|
||||
connect(m_ui.actionEnableFileLogging, &QAction::triggered, this, &MainWindow::onLoggingOptionChanged);
|
||||
SettingWidgetBinder::BindWidgetToBoolSetting(nullptr, m_ui.actionEnableLogTimestamps, "Logging", "EnableTimestamps", true);
|
||||
connect(m_ui.actionEnableLogTimestamps, &QAction::triggered, this, &MainWindow::onLoggingOptionChanged);
|
||||
SettingWidgetBinder::BindWidgetToBoolSetting(nullptr, m_ui.actionEnableCDVDVerboseReads, "EmuCore", "CdvdVerboseReads", false);
|
||||
SettingWidgetBinder::BindWidgetToBoolSetting(nullptr, m_ui.actionSaveBlockDump, "EmuCore", "CdvdDumpBlocks", false);
|
||||
connect(m_ui.actionSaveBlockDump, &QAction::toggled, this, &MainWindow::onBlockDumpActionToggled);
|
||||
|
@ -337,9 +331,7 @@ void MainWindow::connectSignals()
|
|||
connect(m_ui.actionInputRecPlay, &QAction::triggered, this, &MainWindow::onInputRecPlayActionTriggered);
|
||||
connect(m_ui.actionInputRecStop, &QAction::triggered, this, &MainWindow::onInputRecStopActionTriggered);
|
||||
SettingWidgetBinder::BindWidgetToBoolSetting(nullptr, m_ui.actionInputRecConsoleLogs, "Logging", "EnableInputRecordingLogs", false);
|
||||
connect(m_ui.actionInputRecConsoleLogs, &QAction::triggered, this, &MainWindow::onLoggingOptionChanged);
|
||||
SettingWidgetBinder::BindWidgetToBoolSetting(nullptr, m_ui.actionInputRecControllerLogs, "Logging", "EnableControllerLogs", false);
|
||||
connect(m_ui.actionInputRecControllerLogs, &QAction::triggered, this, &MainWindow::onLoggingOptionChanged);
|
||||
|
||||
// These need to be queued connections to stop crashing due to menus opening/closing and switching focus.
|
||||
connect(m_game_list_widget, &GameListWidget::refreshProgress, this, &MainWindow::onGameListRefreshProgress);
|
||||
|
@ -1509,11 +1501,6 @@ void MainWindow::updateTheme()
|
|||
m_game_list_widget->refreshImages();
|
||||
}
|
||||
|
||||
void MainWindow::onLoggingOptionChanged()
|
||||
{
|
||||
Host::UpdateLogging(QtHost::InNoGUIMode());
|
||||
}
|
||||
|
||||
void MainWindow::onInputRecNewActionTriggered()
|
||||
{
|
||||
const bool wasPaused = s_vm_paused;
|
||||
|
|
|
@ -149,7 +149,6 @@ private Q_SLOTS:
|
|||
void onCheckForUpdatesActionTriggered();
|
||||
void onToolsOpenDataDirectoryTriggered();
|
||||
void updateTheme();
|
||||
void onLoggingOptionChanged();
|
||||
void onScreenshotActionTriggered();
|
||||
void onSaveGSDumpActionTriggered();
|
||||
void onBlockDumpActionToggled(bool checked);
|
||||
|
|
|
@ -37,13 +37,13 @@
|
|||
#include "pcsx2/Frontend/GameList.h"
|
||||
#include "pcsx2/Frontend/InputManager.h"
|
||||
#include "pcsx2/Frontend/ImGuiManager.h"
|
||||
#include "pcsx2/Frontend/INISettingsInterface.h"
|
||||
#include "pcsx2/Frontend/LogSink.h"
|
||||
#include "pcsx2/GS.h"
|
||||
#include "pcsx2/GS/GS.h"
|
||||
#include "pcsx2/GSDumpReplayer.h"
|
||||
#include "pcsx2/HostDisplay.h"
|
||||
#include "pcsx2/HostSettings.h"
|
||||
#include "pcsx2/INISettingsInterface.h"
|
||||
#include "pcsx2/PAD/Host/PAD.h"
|
||||
#include "pcsx2/PerformanceMetrics.h"
|
||||
#include "pcsx2/VMManager.h"
|
||||
|
@ -230,14 +230,11 @@ void EmuThread::startVM(std::shared_ptr<VMBootParameters> boot_params)
|
|||
|
||||
pxAssertRel(!VMManager::HasValidVM(), "VM is shut down");
|
||||
|
||||
// Only initialize fullscreen/render-to-main when we're not running big picture.
|
||||
if (!m_run_fullscreen_ui)
|
||||
loadOurInitialSettings();
|
||||
|
||||
// Determine whether to start fullscreen or not.
|
||||
if (boot_params->fullscreen.has_value())
|
||||
m_is_fullscreen = boot_params->fullscreen.value();
|
||||
|
||||
emit onVMStarting();
|
||||
else
|
||||
m_is_fullscreen = Host::GetBaseBoolSettingValue("UI", "StartFullscreen", false);
|
||||
|
||||
if (!VMManager::Initialize(*boot_params))
|
||||
return;
|
||||
|
@ -359,26 +356,19 @@ void EmuThread::saveStateToSlot(qint32 slot)
|
|||
|
||||
void EmuThread::run()
|
||||
{
|
||||
Threading::SetNameOfCurrentThread("EmuThread");
|
||||
PerformanceMetrics::SetCPUThread(Threading::ThreadHandle::GetForCallingThread());
|
||||
// Qt-specific initialization.
|
||||
m_event_loop = new QEventLoop();
|
||||
m_started_semaphore.release();
|
||||
connectSignals();
|
||||
|
||||
// neither of these should ever fail.
|
||||
if (!VMManager::Internal::InitializeGlobals() || !VMManager::Internal::InitializeMemory())
|
||||
pxFailRel("Failed to allocate memory map");
|
||||
|
||||
// We want settings loaded so we choose the correct renderer for big picture mode.
|
||||
// This also sorts out input sources.
|
||||
loadOurSettings();
|
||||
loadOurInitialSettings();
|
||||
VMManager::LoadSettings();
|
||||
// Common host initialization (VM setup, etc).
|
||||
CommonHost::CPUThreadInitialize();
|
||||
|
||||
// Start background polling because the VM won't do it for us.
|
||||
createBackgroundControllerPollTimer();
|
||||
startBackgroundControllerPollTimer();
|
||||
connectSignals();
|
||||
|
||||
// Main CPU thread loop.
|
||||
while (!m_shutdown_flag.load())
|
||||
{
|
||||
if (!VMManager::HasValidVM())
|
||||
|
@ -390,13 +380,12 @@ void EmuThread::run()
|
|||
executeVM();
|
||||
}
|
||||
|
||||
// Teardown in reverse order.
|
||||
stopBackgroundControllerPollTimer();
|
||||
destroyBackgroundControllerPollTimer();
|
||||
InputManager::CloseSources();
|
||||
VMManager::WaitForSaveStateFlush();
|
||||
VMManager::Internal::ReleaseMemory();
|
||||
VMManager::Internal::ReleaseGlobals();
|
||||
PerformanceMetrics::SetCPUThread(Threading::ThreadHandle());
|
||||
CommonHost::CPUThreadShutdown();
|
||||
|
||||
// Move back to the UI thread, since we're no longer running.
|
||||
moveToThread(m_ui_thread);
|
||||
deleteLater();
|
||||
}
|
||||
|
@ -410,6 +399,7 @@ void EmuThread::destroyVM()
|
|||
m_last_internal_height = 0;
|
||||
m_was_paused_by_focus_loss = false;
|
||||
VMManager::Shutdown(m_save_state_on_shutdown);
|
||||
m_save_state_on_shutdown = false;
|
||||
}
|
||||
|
||||
void EmuThread::executeVM()
|
||||
|
@ -540,7 +530,6 @@ void EmuThread::applySettings()
|
|||
return;
|
||||
}
|
||||
|
||||
checkForSettingChanges();
|
||||
VMManager::ApplySettings();
|
||||
}
|
||||
|
||||
|
@ -553,11 +542,7 @@ void EmuThread::reloadGameSettings()
|
|||
}
|
||||
|
||||
// this will skip applying settings when they're not active
|
||||
if (VMManager::ReloadGameSettings())
|
||||
{
|
||||
// none of these settings below are per-game.. for now. but in case they are in the future.
|
||||
checkForSettingChanges();
|
||||
}
|
||||
VMManager::ReloadGameSettings();
|
||||
}
|
||||
|
||||
void EmuThread::updateEmuFolders()
|
||||
|
@ -571,26 +556,24 @@ void EmuThread::updateEmuFolders()
|
|||
Host::Internal::UpdateEmuFolders();
|
||||
}
|
||||
|
||||
void EmuThread::loadOurSettings()
|
||||
{
|
||||
m_verbose_status = Host::GetBaseBoolSettingValue("UI", "VerboseStatusBar", false);
|
||||
m_pause_on_focus_loss = Host::GetBaseBoolSettingValue("UI", "PauseOnFocusLoss", false);
|
||||
}
|
||||
|
||||
void EmuThread::connectSignals()
|
||||
{
|
||||
connect(qApp, &QGuiApplication::applicationStateChanged, this, &EmuThread::onApplicationStateChanged);
|
||||
}
|
||||
|
||||
void EmuThread::loadOurInitialSettings()
|
||||
void EmuThread::loadSettings(SettingsInterface& si, std::unique_lock<std::mutex>& lock)
|
||||
{
|
||||
m_is_fullscreen = Host::GetBaseBoolSettingValue("UI", "StartFullscreen", false);
|
||||
m_is_rendering_to_main = shouldRenderToMain();
|
||||
m_is_surfaceless = false;
|
||||
m_save_state_on_shutdown = false;
|
||||
m_verbose_status = si.GetBoolValue("UI", "VerboseStatusBar", false);
|
||||
m_pause_on_focus_loss = si.GetBoolValue("UI", "PauseOnFocusLoss", false);
|
||||
}
|
||||
|
||||
void EmuThread::checkForSettingChanges()
|
||||
void Host::LoadSettings(SettingsInterface& si, std::unique_lock<std::mutex>& lock)
|
||||
{
|
||||
CommonHost::LoadSettings(si, lock);
|
||||
g_emu_thread->loadSettings(si, lock);
|
||||
}
|
||||
|
||||
void EmuThread::checkForSettingChanges(const Pcsx2Config& old_config)
|
||||
{
|
||||
QMetaObject::invokeMethod(g_main_window, &MainWindow::checkForSettingChanges, Qt::QueuedConnection);
|
||||
|
||||
|
@ -605,12 +588,13 @@ void EmuThread::checkForSettingChanges()
|
|||
}
|
||||
}
|
||||
|
||||
const bool last_verbose_status = m_verbose_status;
|
||||
updatePerformanceMetrics(true);
|
||||
}
|
||||
|
||||
loadOurSettings();
|
||||
|
||||
if (m_verbose_status != last_verbose_status)
|
||||
updatePerformanceMetrics(true);
|
||||
void Host::CheckForSettingsChanges(const Pcsx2Config& old_config)
|
||||
{
|
||||
CommonHost::CheckForSettingsChanges(old_config);
|
||||
g_emu_thread->checkForSettingChanges(old_config);
|
||||
}
|
||||
|
||||
bool EmuThread::shouldRenderToMain() const
|
||||
|
@ -855,6 +839,8 @@ void EmuThread::updateDisplay()
|
|||
bool EmuThread::acquireHostDisplay(HostDisplay::RenderAPI api)
|
||||
{
|
||||
pxAssertRel(!g_host_display, "Host display does not exist on create");
|
||||
m_is_rendering_to_main = shouldRenderToMain();
|
||||
m_is_surfaceless = false;
|
||||
|
||||
g_host_display = HostDisplay::CreateDisplayForAPI(api);
|
||||
if (!g_host_display)
|
||||
|
@ -967,29 +953,35 @@ void Host::UpdateHostDisplay()
|
|||
|
||||
void Host::OnVMStarting()
|
||||
{
|
||||
CommonHost::OnVMStarting();
|
||||
g_emu_thread->stopBackgroundControllerPollTimer();
|
||||
emit g_emu_thread->onVMStarting();
|
||||
}
|
||||
|
||||
void Host::OnVMStarted()
|
||||
{
|
||||
CommonHost::OnVMStarted();
|
||||
emit g_emu_thread->onVMStarted();
|
||||
}
|
||||
|
||||
void Host::OnVMDestroyed()
|
||||
{
|
||||
CommonHost::OnVMDestroyed();
|
||||
emit g_emu_thread->onVMStopped();
|
||||
g_emu_thread->startBackgroundControllerPollTimer();
|
||||
}
|
||||
|
||||
void Host::OnVMPaused()
|
||||
{
|
||||
CommonHost::OnVMPaused();
|
||||
g_emu_thread->startBackgroundControllerPollTimer();
|
||||
emit g_emu_thread->onVMPaused();
|
||||
}
|
||||
|
||||
void Host::OnVMResumed()
|
||||
{
|
||||
CommonHost::OnVMResumed();
|
||||
|
||||
// exit the event loop when we eventually return
|
||||
g_emu_thread->getEventLoop()->quit();
|
||||
g_emu_thread->stopBackgroundControllerPollTimer();
|
||||
|
@ -1001,11 +993,10 @@ void Host::OnVMResumed()
|
|||
emit g_emu_thread->onVMResumed();
|
||||
}
|
||||
|
||||
void Host::OnGameChanged(const std::string& disc_path, const std::string& game_serial, const std::string& game_name,
|
||||
u32 game_crc)
|
||||
void Host::OnGameChanged(const std::string& disc_path, const std::string& game_serial, const std::string& game_name, u32 game_crc)
|
||||
{
|
||||
emit g_emu_thread->onGameChanged(QString::fromStdString(disc_path), QString::fromStdString(game_serial),
|
||||
QString::fromStdString(game_name), game_crc);
|
||||
CommonHost::OnGameChanged(disc_path, game_serial, game_name, game_crc);
|
||||
emit g_emu_thread->onGameChanged(QString::fromStdString(disc_path), QString::fromStdString(game_serial), QString::fromStdString(game_name), game_crc);
|
||||
}
|
||||
|
||||
void EmuThread::updatePerformanceMetrics(bool force)
|
||||
|
@ -1117,9 +1108,10 @@ void Host::OnSaveStateSaved(const std::string_view& filename)
|
|||
emit g_emu_thread->onSaveStateSaved(QtUtils::StringViewToQString(filename));
|
||||
}
|
||||
|
||||
void Host::PumpMessagesOnCPUThread()
|
||||
void Host::CPUThreadVSync()
|
||||
{
|
||||
g_emu_thread->getEventLoop()->processEvents(QEventLoop::AllEvents);
|
||||
CommonHost::CPUThreadVSync();
|
||||
}
|
||||
|
||||
void Host::RunOnCPUThread(std::function<void()> function, bool block /* = false */)
|
||||
|
@ -1211,15 +1203,13 @@ bool QtHost::InitializeConfig()
|
|||
SaveSettings();
|
||||
}
|
||||
|
||||
CommonHost::SetBlockSystemConsole(QtHost::InNoGUIMode());
|
||||
CommonHost::LoadStartupSettings();
|
||||
Host::UpdateLogging(QtHost::InNoGUIMode());
|
||||
return true;
|
||||
}
|
||||
|
||||
void Host::SetDefaultUISettings(SettingsInterface& si)
|
||||
{
|
||||
Host::SetDefaultLoggingSettings(si);
|
||||
|
||||
si.SetBoolValue("UI", "InhibitScreensaver", true);
|
||||
si.SetBoolValue("UI", "ConfirmShutdown", true);
|
||||
si.SetBoolValue("UI", "StartPaused", false);
|
||||
|
@ -1472,7 +1462,7 @@ void QtHost::HookSignals()
|
|||
|
||||
void QtHost::PrintCommandLineVersion()
|
||||
{
|
||||
Host::InitializeEarlyConsole();
|
||||
CommonHost::InitializeEarlyConsole();
|
||||
std::fprintf(stderr, "%s\n", (GetAppNameAndVersion() + GetAppConfigSuffix()).toUtf8().constData());
|
||||
std::fprintf(stderr, "https://pcsx2.net/\n");
|
||||
std::fprintf(stderr, "\n");
|
||||
|
@ -1592,7 +1582,7 @@ bool QtHost::ParseCommandLineOptions(int argc, char* argv[], std::shared_ptr<VMB
|
|||
}
|
||||
else if (CHECK_ARG("-earlyconsolelog"))
|
||||
{
|
||||
Host::InitializeEarlyConsole();
|
||||
CommonHost::InitializeEarlyConsole();
|
||||
continue;
|
||||
}
|
||||
else if (CHECK_ARG("-bigpicture"))
|
||||
|
@ -1607,7 +1597,7 @@ bool QtHost::ParseCommandLineOptions(int argc, char* argv[], std::shared_ptr<VMB
|
|||
}
|
||||
else if (argv[i][0] == '-')
|
||||
{
|
||||
Host::InitializeEarlyConsole();
|
||||
CommonHost::InitializeEarlyConsole();
|
||||
std::fprintf(stderr, "Unknown parameter: '%s'", argv[i]);
|
||||
return false;
|
||||
}
|
||||
|
@ -1626,7 +1616,7 @@ bool QtHost::ParseCommandLineOptions(int argc, char* argv[], std::shared_ptr<VMB
|
|||
// or disc, we don't want to actually start.
|
||||
if (autoboot && !autoboot->source_type.has_value() && autoboot->filename.empty() && autoboot->elf_override.empty())
|
||||
{
|
||||
Host::InitializeEarlyConsole();
|
||||
CommonHost::InitializeEarlyConsole();
|
||||
Console.Warning("Skipping autoboot due to no boot parameters.");
|
||||
autoboot.reset();
|
||||
}
|
||||
|
|
|
@ -80,6 +80,8 @@ public:
|
|||
|
||||
public Q_SLOTS:
|
||||
bool confirmMessage(const QString& title, const QString& message);
|
||||
void loadSettings(SettingsInterface& si, std::unique_lock<std::mutex>& lock);
|
||||
void checkForSettingChanges(const Pcsx2Config& old_config);
|
||||
void startFullscreenUI(bool fullscreen);
|
||||
void stopFullscreenUI();
|
||||
void startVM(std::shared_ptr<VMBootParameters> boot_params);
|
||||
|
@ -161,14 +163,11 @@ private:
|
|||
|
||||
void destroyVM();
|
||||
void executeVM();
|
||||
void checkForSettingChanges();
|
||||
bool shouldRenderToMain() const;
|
||||
|
||||
void createBackgroundControllerPollTimer();
|
||||
void destroyBackgroundControllerPollTimer();
|
||||
void connectSignals();
|
||||
void loadOurSettings();
|
||||
void loadOurInitialSettings();
|
||||
|
||||
private Q_SLOTS:
|
||||
void stopInThread();
|
||||
|
|
|
@ -22,7 +22,7 @@
|
|||
#include "Settings/HotkeySettingsWidget.h"
|
||||
|
||||
#include "pcsx2/Frontend/CommonHost.h"
|
||||
#include "pcsx2/Frontend/INISettingsInterface.h"
|
||||
#include "pcsx2/INISettingsInterface.h"
|
||||
#include "pcsx2/PAD/Host/PAD.h"
|
||||
#include "pcsx2/Sio.h"
|
||||
#include "pcsx2/VMManager.h"
|
||||
|
|
|
@ -24,13 +24,13 @@
|
|||
#include "common/StringUtil.h"
|
||||
|
||||
#include "pcsx2/HostSettings.h"
|
||||
#include "pcsx2/INISettingsInterface.h"
|
||||
|
||||
#include "DEV9SettingsWidget.h"
|
||||
#include "QtHost.h"
|
||||
#include "QtUtils.h"
|
||||
#include "SettingWidgetBinder.h"
|
||||
#include "SettingsDialog.h"
|
||||
#include "Frontend/INISettingsInterface.h"
|
||||
|
||||
#include "HddCreateQt.h"
|
||||
|
||||
|
|
|
@ -19,9 +19,9 @@
|
|||
#include "common/Path.h"
|
||||
#include "common/StringUtil.h"
|
||||
|
||||
#include "pcsx2/HostSettings.h"
|
||||
#include "pcsx2/Frontend/GameList.h"
|
||||
#include "pcsx2/Frontend/INISettingsInterface.h"
|
||||
#include "pcsx2/HostSettings.h"
|
||||
#include "pcsx2/INISettingsInterface.h"
|
||||
|
||||
#include "MainWindow.h"
|
||||
#include "QtHost.h"
|
||||
|
|
|
@ -1064,16 +1064,17 @@ endif()
|
|||
if(PCSX2_CORE)
|
||||
list(APPEND pcsx2FrontendSources
|
||||
Frontend/CommonHost.cpp
|
||||
Frontend/CommonHotkeys.cpp
|
||||
Frontend/FullscreenUI.cpp
|
||||
Frontend/GameList.cpp
|
||||
Frontend/HostSettings.cpp
|
||||
Frontend/ImGuiFullscreen.cpp
|
||||
Frontend/INISettingsInterface.cpp
|
||||
Frontend/InputManager.cpp
|
||||
Frontend/InputSource.cpp
|
||||
Frontend/LayeredSettingsInterface.cpp
|
||||
Frontend/LogSink.cpp
|
||||
GSDumpReplayer.cpp
|
||||
INISettingsInterface.cpp
|
||||
VMManager.cpp
|
||||
)
|
||||
list(APPEND pcsx2FrontendHeaders
|
||||
|
@ -1081,13 +1082,13 @@ if(PCSX2_CORE)
|
|||
Frontend/FullscreenUI.h
|
||||
Frontend/GameList.h
|
||||
Frontend/ImGuiFullscreen.h
|
||||
Frontend/INISettingsInterface.h
|
||||
Frontend/InputManager.h
|
||||
Frontend/InputSource.h
|
||||
Frontend/LayeredSettingsInterface.h
|
||||
Frontend/LogSink.h
|
||||
GSDumpReplayer.h
|
||||
HostSettings.h
|
||||
INISettingsInterface.h
|
||||
VMManager.h)
|
||||
endif()
|
||||
|
||||
|
|
|
@ -18,14 +18,21 @@
|
|||
#include "common/CrashHandler.h"
|
||||
#include "common/FileSystem.h"
|
||||
#include "common/Path.h"
|
||||
#include "common/Threading.h"
|
||||
#include "Frontend/CommonHost.h"
|
||||
#include "Frontend/FullscreenUI.h"
|
||||
#include "Frontend/GameList.h"
|
||||
#include "Frontend/LayeredSettingsInterface.h"
|
||||
#include "Frontend/InputManager.h"
|
||||
#include "Frontend/LogSink.h"
|
||||
#include "GS.h"
|
||||
#include "GS/Renderers/HW/GSTextureReplacements.h"
|
||||
#include "Host.h"
|
||||
#include "HostSettings.h"
|
||||
#include "IconsFontAwesome5.h"
|
||||
#include "MemoryCardFile.h"
|
||||
#include "PAD/Host/PAD.h"
|
||||
#include "PerformanceMetrics.h"
|
||||
#include "Sio.h"
|
||||
#include "VMManager.h"
|
||||
|
||||
|
@ -175,6 +182,7 @@ void CommonHost::LoadStartupSettings()
|
|||
SettingsInterface* bsi = Host::Internal::GetBaseSettingsLayer();
|
||||
EmuFolders::LoadConfig(*bsi);
|
||||
EmuFolders::EnsureFoldersExist();
|
||||
UpdateLogging(*bsi);
|
||||
}
|
||||
|
||||
void CommonHost::SetDefaultSettings(SettingsInterface& si, bool folders, bool core, bool controllers, bool hotkeys, bool ui)
|
||||
|
@ -199,5 +207,106 @@ void CommonHost::SetDefaultSettings(SettingsInterface& si, bool folders, bool co
|
|||
|
||||
void CommonHost::SetCommonDefaultSettings(SettingsInterface& si)
|
||||
{
|
||||
// Nothing here yet.
|
||||
SetDefaultLoggingSettings(si);
|
||||
}
|
||||
|
||||
void CommonHost::CPUThreadInitialize()
|
||||
{
|
||||
Threading::SetNameOfCurrentThread("CPU Thread");
|
||||
PerformanceMetrics::SetCPUThread(Threading::ThreadHandle::GetForCallingThread());
|
||||
|
||||
// neither of these should ever fail.
|
||||
if (!VMManager::Internal::InitializeGlobals() || !VMManager::Internal::InitializeMemory())
|
||||
pxFailRel("Failed to allocate memory map");
|
||||
|
||||
// We want settings loaded so we choose the correct renderer for big picture mode.
|
||||
// This also sorts out input sources.
|
||||
VMManager::LoadSettings();
|
||||
}
|
||||
|
||||
void CommonHost::CPUThreadShutdown()
|
||||
{
|
||||
InputManager::CloseSources();
|
||||
VMManager::WaitForSaveStateFlush();
|
||||
VMManager::Internal::ReleaseMemory();
|
||||
VMManager::Internal::ReleaseGlobals();
|
||||
PerformanceMetrics::SetCPUThread(Threading::ThreadHandle());
|
||||
}
|
||||
|
||||
void CommonHost::LoadSettings(SettingsInterface& si, std::unique_lock<std::mutex>& lock)
|
||||
{
|
||||
SettingsInterface* binding_si = Host::GetSettingsInterfaceForBindings();
|
||||
InputManager::ReloadSources(si, lock);
|
||||
InputManager::ReloadBindings(si, *binding_si);
|
||||
UpdateLogging(si);
|
||||
}
|
||||
|
||||
void CommonHost::CheckForSettingsChanges(const Pcsx2Config& old_config)
|
||||
{
|
||||
// Nothing yet.
|
||||
}
|
||||
|
||||
void CommonHost::OnVMStarting()
|
||||
{
|
||||
CommonHost::Internal::ResetVMHotkeyState();
|
||||
}
|
||||
|
||||
void CommonHost::OnVMStarted()
|
||||
{
|
||||
FullscreenUI::OnVMStarted();
|
||||
}
|
||||
|
||||
void CommonHost::OnVMDestroyed()
|
||||
{
|
||||
FullscreenUI::OnVMDestroyed();
|
||||
}
|
||||
|
||||
void CommonHost::OnVMPaused()
|
||||
{
|
||||
InputManager::PauseVibration();
|
||||
FullscreenUI::OnVMPaused();
|
||||
}
|
||||
|
||||
void CommonHost::OnVMResumed()
|
||||
{
|
||||
FullscreenUI::OnVMResumed();
|
||||
}
|
||||
|
||||
void CommonHost::OnGameChanged(const std::string& disc_path, const std::string& game_serial, const std::string& game_name, u32 game_crc)
|
||||
{
|
||||
if (FullscreenUI::IsInitialized())
|
||||
{
|
||||
GetMTGS().RunOnGSThread([disc_path, game_serial, game_name, game_crc]() {
|
||||
FullscreenUI::OnRunningGameChanged(std::move(disc_path), std::move(game_serial), std::move(game_name), game_crc);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
void CommonHost::CPUThreadVSync()
|
||||
{
|
||||
InputManager::PollSources();
|
||||
}
|
||||
|
||||
bool Host::GetSerialAndCRCForFilename(const char* filename, std::string* serial, u32* crc)
|
||||
{
|
||||
{
|
||||
auto lock = GameList::GetLock();
|
||||
if (const GameList::Entry* entry = GameList::GetEntryForPath(filename); entry)
|
||||
{
|
||||
*serial = entry->serial;
|
||||
*crc = entry->crc;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
// Just scan it.. hopefully it'll come back okay.
|
||||
GameList::Entry temp_entry;
|
||||
if (GameList::PopulateEntryFromPath(filename, &temp_entry))
|
||||
{
|
||||
*serial = std::move(temp_entry.serial);
|
||||
*crc = temp_entry.crc;
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
|
|
@ -19,6 +19,8 @@
|
|||
#include <string>
|
||||
#include <mutex>
|
||||
|
||||
#include "Config.h"
|
||||
|
||||
class SettingsInterface;
|
||||
|
||||
namespace Host
|
||||
|
@ -40,4 +42,43 @@ namespace CommonHost
|
|||
|
||||
/// Sets default settings for the specified categories.
|
||||
void SetDefaultSettings(SettingsInterface& si, bool folders, bool core, bool controllers, bool hotkeys, bool ui);
|
||||
|
||||
/// Initializes common host state, called on the CPU thread.
|
||||
void CPUThreadInitialize();
|
||||
|
||||
/// Cleans up common host state, called on the CPU thread.
|
||||
void CPUThreadShutdown();
|
||||
|
||||
/// Loads common host settings (including input bindings).
|
||||
void LoadSettings(SettingsInterface& si, std::unique_lock<std::mutex>& lock);
|
||||
|
||||
/// Called after settings are updated.
|
||||
void CheckForSettingsChanges(const Pcsx2Config& old_config);
|
||||
|
||||
/// 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();
|
||||
|
||||
/// 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 CPUThreadVSync();
|
||||
|
||||
namespace Internal
|
||||
{
|
||||
/// Resets any state for hotkey-related VMs, called on VM startup.
|
||||
void ResetVMHotkeyState();
|
||||
} // namespace Internal
|
||||
} // namespace CommonHost
|
||||
|
|
|
@ -0,0 +1,240 @@
|
|||
/* 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/>.
|
||||
*/
|
||||
|
||||
#include "PrecompiledHeader.h"
|
||||
#include "common/Assertions.h"
|
||||
#include "common/FileSystem.h"
|
||||
#include "common/Path.h"
|
||||
#include "Frontend/CommonHost.h"
|
||||
#include "Frontend/FullscreenUI.h"
|
||||
#include "Frontend/InputManager.h"
|
||||
#include "GS.h"
|
||||
#include "Host.h"
|
||||
#include "IconsFontAwesome5.h"
|
||||
#include "Recording/InputRecordingControls.h"
|
||||
#include "VMManager.h"
|
||||
|
||||
static s32 s_current_save_slot = 1;
|
||||
static std::optional<LimiterModeType> s_limiter_mode_prior_to_hold_interaction;
|
||||
|
||||
void CommonHost::Internal::ResetVMHotkeyState()
|
||||
{
|
||||
s_current_save_slot = 1;
|
||||
s_limiter_mode_prior_to_hold_interaction.reset();
|
||||
}
|
||||
|
||||
static void HotkeyAdjustTargetSpeed(double delta)
|
||||
{
|
||||
EmuConfig.Framerate.NominalScalar = EmuConfig.GS.LimitScalar + delta;
|
||||
VMManager::SetLimiterMode(LimiterModeType::Nominal);
|
||||
gsUpdateFrequency(EmuConfig);
|
||||
GetMTGS().SetVSync(EmuConfig.GetEffectiveVsyncMode());
|
||||
Host::AddIconOSDMessage("SpeedChanged", ICON_FA_CLOCK,
|
||||
fmt::format("Target speed set to {:.0f}%.", std::round(EmuConfig.Framerate.NominalScalar * 100.0)), 5.0f);
|
||||
}
|
||||
|
||||
static constexpr s32 CYCLE_SAVE_STATE_SLOTS = 10;
|
||||
|
||||
static void HotkeyCycleSaveSlot(s32 delta)
|
||||
{
|
||||
// 1..10
|
||||
s_current_save_slot = ((s_current_save_slot - 1) + delta);
|
||||
if (s_current_save_slot < 0)
|
||||
s_current_save_slot = CYCLE_SAVE_STATE_SLOTS;
|
||||
else
|
||||
s_current_save_slot = (s_current_save_slot % CYCLE_SAVE_STATE_SLOTS) + 1;
|
||||
|
||||
const u32 crc = VMManager::GetGameCRC();
|
||||
const std::string serial(VMManager::GetGameSerial());
|
||||
const std::string filename(VMManager::GetSaveStateFileName(serial.c_str(), crc, s_current_save_slot));
|
||||
FILESYSTEM_STAT_DATA sd;
|
||||
if (!filename.empty() && FileSystem::StatFile(filename.c_str(), &sd))
|
||||
{
|
||||
char date_buf[128] = {};
|
||||
#ifdef _WIN32
|
||||
ctime_s(date_buf, std::size(date_buf), &sd.ModificationTime);
|
||||
#else
|
||||
ctime_r(&sd.ModificationTime, date_buf);
|
||||
#endif
|
||||
|
||||
// remove terminating \n
|
||||
size_t len = std::strlen(date_buf);
|
||||
if (len > 0 && date_buf[len - 1] == '\n')
|
||||
date_buf[len - 1] = 0;
|
||||
|
||||
Host::AddIconOSDMessage(
|
||||
"CycleSaveSlot", ICON_FA_SEARCH, fmt::format("Save slot {} selected (last save: {}).", s_current_save_slot, date_buf), 5.0f);
|
||||
}
|
||||
else
|
||||
{
|
||||
Host::AddIconOSDMessage(
|
||||
"CycleSaveSlot", ICON_FA_SEARCH, fmt::format("Save slot {} selected (no save yet).", s_current_save_slot), 5.0f);
|
||||
}
|
||||
}
|
||||
|
||||
static void HotkeyLoadStateSlot(s32 slot)
|
||||
{
|
||||
const u32 crc = VMManager::GetGameCRC();
|
||||
if (crc == 0)
|
||||
{
|
||||
Host::AddIconOSDMessage(
|
||||
"LoadStateFromSlot", ICON_FA_EXCLAMATION_TRIANGLE, "Cannot load state from a slot without a game running.", 10.0f);
|
||||
return;
|
||||
}
|
||||
|
||||
const std::string serial(VMManager::GetGameSerial());
|
||||
if (!VMManager::HasSaveStateInSlot(serial.c_str(), crc, slot))
|
||||
{
|
||||
Host::AddIconOSDMessage("LoadStateFromSlot", ICON_FA_EXCLAMATION_TRIANGLE, fmt::format("No save state found in slot {}.", slot));
|
||||
return;
|
||||
}
|
||||
|
||||
VMManager::LoadStateFromSlot(slot);
|
||||
}
|
||||
|
||||
static void HotkeySaveStateSlot(s32 slot)
|
||||
{
|
||||
if (VMManager::GetGameCRC() == 0)
|
||||
{
|
||||
Host::AddIconOSDMessage(
|
||||
"SaveStateToSlot", ICON_FA_EXCLAMATION_TRIANGLE, "Cannot save state to a slot without a game running.", 10.0f);
|
||||
return;
|
||||
}
|
||||
|
||||
VMManager::SaveStateToSlot(slot);
|
||||
}
|
||||
|
||||
BEGIN_HOTKEY_LIST(g_common_hotkeys)
|
||||
DEFINE_HOTKEY("OpenPauseMenu", "System", "Open Pause Menu", [](s32 pressed) {
|
||||
if (!pressed && VMManager::HasValidVM())
|
||||
FullscreenUI::OpenPauseMenu();
|
||||
})
|
||||
DEFINE_HOTKEY("TogglePause", "System", "Toggle Pause", [](s32 pressed) {
|
||||
if (!pressed && VMManager::HasValidVM())
|
||||
VMManager::SetPaused(VMManager::GetState() != VMState::Paused);
|
||||
})
|
||||
DEFINE_HOTKEY("ToggleFullscreen", "System", "Toggle Fullscreen", [](s32 pressed) {
|
||||
if (!pressed)
|
||||
Host::SetFullscreen(!Host::IsFullscreen());
|
||||
})
|
||||
DEFINE_HOTKEY("ToggleFrameLimit", "System", "Toggle Frame Limit", [](s32 pressed) {
|
||||
if (!pressed && VMManager::HasValidVM())
|
||||
{
|
||||
VMManager::SetLimiterMode(
|
||||
(EmuConfig.LimiterMode != LimiterModeType::Unlimited) ? LimiterModeType::Unlimited : LimiterModeType::Nominal);
|
||||
}
|
||||
})
|
||||
DEFINE_HOTKEY("ToggleTurbo", "System", "Toggle Turbo", [](s32 pressed) {
|
||||
if (!pressed && VMManager::HasValidVM())
|
||||
{
|
||||
VMManager::SetLimiterMode((EmuConfig.LimiterMode != LimiterModeType::Turbo) ? LimiterModeType::Turbo : LimiterModeType::Nominal);
|
||||
}
|
||||
})
|
||||
DEFINE_HOTKEY("ToggleSlowMotion", "System", "Toggle Slow Motion", [](s32 pressed) {
|
||||
if (!pressed && VMManager::HasValidVM())
|
||||
{
|
||||
VMManager::SetLimiterMode((EmuConfig.LimiterMode != LimiterModeType::Slomo) ? LimiterModeType::Slomo : LimiterModeType::Nominal);
|
||||
}
|
||||
})
|
||||
DEFINE_HOTKEY("HoldTurbo", "System", "Turbo (Hold)", [](s32 pressed) {
|
||||
if (!VMManager::HasValidVM())
|
||||
return;
|
||||
if (pressed > 0 && !s_limiter_mode_prior_to_hold_interaction.has_value())
|
||||
{
|
||||
s_limiter_mode_prior_to_hold_interaction = VMManager::GetLimiterMode();
|
||||
VMManager::SetLimiterMode((s_limiter_mode_prior_to_hold_interaction.value() != LimiterModeType::Turbo) ? LimiterModeType::Turbo :
|
||||
LimiterModeType::Nominal);
|
||||
}
|
||||
else if (pressed >= 0 && s_limiter_mode_prior_to_hold_interaction.has_value())
|
||||
{
|
||||
VMManager::SetLimiterMode(s_limiter_mode_prior_to_hold_interaction.value());
|
||||
s_limiter_mode_prior_to_hold_interaction.reset();
|
||||
}
|
||||
})
|
||||
DEFINE_HOTKEY("IncreaseSpeed", "System", "Increase Target Speed", [](s32 pressed) {
|
||||
if (!pressed)
|
||||
HotkeyAdjustTargetSpeed(0.1);
|
||||
})
|
||||
DEFINE_HOTKEY("DecreaseSpeed", "System", "Decrease Target Speed", [](s32 pressed) {
|
||||
if (!pressed)
|
||||
HotkeyAdjustTargetSpeed(-0.1);
|
||||
})
|
||||
DEFINE_HOTKEY("FrameAdvance", "System", "Frame Advance", [](s32 pressed) {
|
||||
if (!pressed && VMManager::HasValidVM())
|
||||
VMManager::FrameAdvance(1);
|
||||
})
|
||||
DEFINE_HOTKEY("ShutdownVM", "System", "Shut Down Virtual Machine", [](s32 pressed) {
|
||||
if (!pressed && VMManager::HasValidVM())
|
||||
Host::RequestVMShutdown(true, true, EmuConfig.SaveStateOnShutdown);
|
||||
})
|
||||
DEFINE_HOTKEY("ResetVM", "System", "Reset Virtual Machine", [](s32 pressed) {
|
||||
if (!pressed && VMManager::HasValidVM())
|
||||
VMManager::Reset();
|
||||
})
|
||||
DEFINE_HOTKEY("InputRecToggleMode", "System", "Toggle Input Recording Mode", [](s32 pressed) {
|
||||
if (!pressed && VMManager::HasValidVM())
|
||||
g_InputRecordingControls.RecordModeToggle();
|
||||
})
|
||||
|
||||
DEFINE_HOTKEY("PreviousSaveStateSlot", "Save States", "Select Previous Save Slot", [](s32 pressed) {
|
||||
if (!pressed && VMManager::HasValidVM())
|
||||
HotkeyCycleSaveSlot(-1);
|
||||
})
|
||||
DEFINE_HOTKEY("NextSaveStateSlot", "Save States", "Select Next Save Slot", [](s32 pressed) {
|
||||
if (!pressed && VMManager::HasValidVM())
|
||||
HotkeyCycleSaveSlot(1);
|
||||
})
|
||||
DEFINE_HOTKEY("SaveStateToSlot", "Save States", "Save State To Selected Slot", [](s32 pressed) {
|
||||
if (!pressed && VMManager::HasValidVM())
|
||||
VMManager::SaveStateToSlot(s_current_save_slot);
|
||||
})
|
||||
DEFINE_HOTKEY("LoadStateFromSlot", "Save States", "Load State From Selected Slot", [](s32 pressed) {
|
||||
if (!pressed && VMManager::HasValidVM())
|
||||
HotkeyLoadStateSlot(s_current_save_slot);
|
||||
})
|
||||
|
||||
#define DEFINE_HOTKEY_SAVESTATE_X(slotnum) \
|
||||
DEFINE_HOTKEY("SaveStateToSlot" #slotnum, "Save States", "Save State To Slot " #slotnum, [](s32 pressed) { \
|
||||
if (!pressed) \
|
||||
HotkeySaveStateSlot(slotnum); \
|
||||
})
|
||||
#define DEFINE_HOTKEY_LOADSTATE_X(slotnum) \
|
||||
DEFINE_HOTKEY("LoadStateFromSlot" #slotnum, "Save States", "Load State From Slot " #slotnum, [](s32 pressed) { \
|
||||
if (!pressed) \
|
||||
HotkeyLoadStateSlot(slotnum); \
|
||||
})
|
||||
DEFINE_HOTKEY_SAVESTATE_X(1)
|
||||
DEFINE_HOTKEY_LOADSTATE_X(1)
|
||||
DEFINE_HOTKEY_SAVESTATE_X(2)
|
||||
DEFINE_HOTKEY_LOADSTATE_X(2)
|
||||
DEFINE_HOTKEY_SAVESTATE_X(3)
|
||||
DEFINE_HOTKEY_LOADSTATE_X(3)
|
||||
DEFINE_HOTKEY_SAVESTATE_X(4)
|
||||
DEFINE_HOTKEY_LOADSTATE_X(4)
|
||||
DEFINE_HOTKEY_SAVESTATE_X(5)
|
||||
DEFINE_HOTKEY_LOADSTATE_X(5)
|
||||
DEFINE_HOTKEY_SAVESTATE_X(6)
|
||||
DEFINE_HOTKEY_LOADSTATE_X(6)
|
||||
DEFINE_HOTKEY_SAVESTATE_X(7)
|
||||
DEFINE_HOTKEY_LOADSTATE_X(7)
|
||||
DEFINE_HOTKEY_SAVESTATE_X(8)
|
||||
DEFINE_HOTKEY_LOADSTATE_X(8)
|
||||
DEFINE_HOTKEY_SAVESTATE_X(9)
|
||||
DEFINE_HOTKEY_LOADSTATE_X(9)
|
||||
DEFINE_HOTKEY_SAVESTATE_X(10)
|
||||
DEFINE_HOTKEY_LOADSTATE_X(10)
|
||||
#undef DEFINE_HOTKEY_SAVESTATE_X
|
||||
#undef DEFINE_HOTKEY_LOADSTATE_X
|
||||
END_HOTKEY_LIST()
|
|
@ -20,7 +20,6 @@
|
|||
#include "Frontend/FullscreenUI.h"
|
||||
#include "Frontend/ImGuiManager.h"
|
||||
#include "Frontend/ImGuiFullscreen.h"
|
||||
#include "Frontend/INISettingsInterface.h"
|
||||
#include "Frontend/InputManager.h"
|
||||
#include "Frontend/GameList.h"
|
||||
#include "IconsFontAwesome5.h"
|
||||
|
@ -40,6 +39,7 @@
|
|||
#include "Host.h"
|
||||
#include "HostDisplay.h"
|
||||
#include "HostSettings.h"
|
||||
#include "INISettingsInterface.h"
|
||||
#include "MemoryCardFile.h"
|
||||
#include "PAD/Host/PAD.h"
|
||||
#include "ps2/BiosTools.h"
|
||||
|
@ -855,7 +855,7 @@ void FullscreenUI::DoChangeDiscFromFile()
|
|||
auto callback = [](const std::string& path) {
|
||||
if (!path.empty())
|
||||
{
|
||||
if (!GameList::IsScannableFilename(path))
|
||||
if (!VMManager::IsDiscFileName(path))
|
||||
{
|
||||
ShowToast({}, fmt::format("{} is not a valid disc image.", FileSystem::GetDisplayNameFromPath(path)));
|
||||
}
|
||||
|
|
|
@ -46,6 +46,8 @@ namespace GameList
|
|||
{
|
||||
using CacheMap = std::unordered_map<std::string, GameList::Entry>;
|
||||
|
||||
static bool IsScannableFilename(const std::string_view& path);
|
||||
|
||||
static Entry* GetMutableEntryForPath(const char* path);
|
||||
|
||||
static bool GetElfListEntry(const std::string& path, GameList::Entry* entry);
|
||||
|
@ -119,15 +121,7 @@ const char* GameList::EntryCompatibilityRatingToString(CompatibilityRating ratin
|
|||
|
||||
bool GameList::IsScannableFilename(const std::string_view& path)
|
||||
{
|
||||
static const char* extensions[] = {".iso", ".mdf", ".nrg", ".bin", ".img", ".gz", ".cso", ".chd", ".elf", ".irx"};
|
||||
|
||||
for (const char* test_extension : extensions)
|
||||
{
|
||||
if (StringUtil::EndsWithNoCase(path, test_extension))
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
return VMManager::IsDiscFileName(path) || VMManager::IsElfFileName(path);
|
||||
}
|
||||
|
||||
void GameList::FillBootParametersForEntry(VMBootParameters* params, const Entry* entry)
|
||||
|
|
|
@ -100,8 +100,6 @@ namespace GameList
|
|||
const char* RegionToString(Region region);
|
||||
const char* EntryCompatibilityRatingToString(CompatibilityRating rating);
|
||||
|
||||
bool IsScannableFilename(const std::string_view& path);
|
||||
|
||||
/// Fills in boot parameters (iso or elf) based on the game list entry.
|
||||
void FillBootParametersForEntry(VMBootParameters* params, const Entry* entry);
|
||||
|
||||
|
|
|
@ -134,7 +134,7 @@ static std::array<std::unique_ptr<InputSource>, static_cast<u32>(InputSourceType
|
|||
// ------------------------------------------------------------------------
|
||||
// Hotkeys
|
||||
// ------------------------------------------------------------------------
|
||||
static const HotkeyInfo* const s_hotkey_list[] = {g_host_hotkeys, g_vm_manager_hotkeys, g_gs_hotkeys};
|
||||
static const HotkeyInfo* const s_hotkey_list[] = {g_common_hotkeys, g_gs_hotkeys, g_host_hotkeys};
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
// Tracking host mouse movement and turning into relative events
|
||||
|
|
|
@ -131,7 +131,7 @@ struct HotkeyInfo
|
|||
} \
|
||||
;
|
||||
|
||||
DECLARE_HOTKEY_LIST(g_vm_manager_hotkeys);
|
||||
DECLARE_HOTKEY_LIST(g_common_hotkeys);
|
||||
DECLARE_HOTKEY_LIST(g_gs_hotkeys);
|
||||
DECLARE_HOTKEY_LIST(g_host_hotkeys);
|
||||
|
||||
|
|
|
@ -66,6 +66,7 @@ static const char s_console_colors[][ConsoleColors_Count] = {
|
|||
};
|
||||
#undef CC
|
||||
|
||||
static bool s_block_system_console = false;
|
||||
static Common::Timer::Value s_log_start_timestamp = Common::Timer::GetCurrentValue();
|
||||
static bool s_log_timestamps = false;
|
||||
static std::mutex s_log_mutex;
|
||||
|
@ -364,31 +365,36 @@ static void UpdateLoggingSinks(bool system_console, bool file_log)
|
|||
Console_SetActiveHandler(ConsoleWriter_Null);
|
||||
}
|
||||
|
||||
void Host::InitializeEarlyConsole()
|
||||
void CommonHost::SetBlockSystemConsole(bool block)
|
||||
{
|
||||
s_block_system_console = block;
|
||||
}
|
||||
|
||||
void CommonHost::InitializeEarlyConsole()
|
||||
{
|
||||
UpdateLoggingSinks(true, false);
|
||||
}
|
||||
|
||||
void Host::UpdateLogging(bool disable_system_console)
|
||||
void CommonHost::UpdateLogging(SettingsInterface& si)
|
||||
{
|
||||
const bool system_console_enabled = !disable_system_console && Host::GetBaseBoolSettingValue("Logging", "EnableSystemConsole", false);
|
||||
const bool file_logging_enabled = Host::GetBaseBoolSettingValue("Logging", "EnableFileLogging", false);
|
||||
const bool system_console_enabled = !s_block_system_console && si.GetBoolValue("Logging", "EnableSystemConsole", false);
|
||||
const bool file_logging_enabled = si.GetBoolValue("Logging", "EnableFileLogging", false);
|
||||
|
||||
s_log_timestamps = Host::GetBaseBoolSettingValue("Logging", "EnableTimestamps", true);
|
||||
s_log_timestamps = si.GetBoolValue("Logging", "EnableTimestamps", true);
|
||||
|
||||
const bool any_logging_sinks = system_console_enabled || file_logging_enabled;
|
||||
DevConWriterEnabled = any_logging_sinks && (IsDevBuild || Host::GetBaseBoolSettingValue("Logging", "EnableVerbose", false));
|
||||
SysConsole.eeConsole.Enabled = any_logging_sinks && Host::GetBaseBoolSettingValue("Logging", "EnableEEConsole", false);
|
||||
SysConsole.iopConsole.Enabled = any_logging_sinks && Host::GetBaseBoolSettingValue("Logging", "EnableIOPConsole", false);
|
||||
DevConWriterEnabled = any_logging_sinks && (IsDevBuild || si.GetBoolValue("Logging", "EnableVerbose", false));
|
||||
SysConsole.eeConsole.Enabled = any_logging_sinks && si.GetBoolValue("Logging", "EnableEEConsole", false);
|
||||
SysConsole.iopConsole.Enabled = any_logging_sinks && si.GetBoolValue("Logging", "EnableIOPConsole", false);
|
||||
|
||||
// Input Recording Logs
|
||||
SysConsole.recordingConsole.Enabled = any_logging_sinks && Host::GetBaseBoolSettingValue("Logging", "EnableInputRecordingLogs", true);
|
||||
SysConsole.controlInfo.Enabled = any_logging_sinks && Host::GetBaseBoolSettingValue("Logging", "EnableControllerLogs", false);
|
||||
SysConsole.recordingConsole.Enabled = any_logging_sinks && si.GetBoolValue("Logging", "EnableInputRecordingLogs", true);
|
||||
SysConsole.controlInfo.Enabled = any_logging_sinks && si.GetBoolValue("Logging", "EnableControllerLogs", false);
|
||||
|
||||
UpdateLoggingSinks(system_console_enabled, file_logging_enabled);
|
||||
}
|
||||
|
||||
void Host::SetDefaultLoggingSettings(SettingsInterface& si)
|
||||
void CommonHost::SetDefaultLoggingSettings(SettingsInterface& si)
|
||||
{
|
||||
si.SetBoolValue("Logging", "EnableSystemConsole", false);
|
||||
si.SetBoolValue("Logging", "EnableFileLogging", false);
|
||||
|
|
|
@ -17,10 +17,13 @@
|
|||
|
||||
class SettingsInterface;
|
||||
|
||||
namespace Host
|
||||
namespace CommonHost
|
||||
{
|
||||
/// Prevents the system console from being displayed.
|
||||
void SetBlockSystemConsole(bool block);
|
||||
|
||||
/// Updates the Console handler based on the current configuration.
|
||||
void UpdateLogging(bool disable_system_console);
|
||||
void UpdateLogging(SettingsInterface& si);
|
||||
|
||||
/// Initializes early console logging (for printing command line arguments).
|
||||
void InitializeEarlyConsole();
|
||||
|
|
|
@ -39,6 +39,7 @@
|
|||
#include "GSDumpReplayer.h"
|
||||
#include "HostDisplay.h"
|
||||
#include "HostSettings.h"
|
||||
#include "INISettingsInterface.h"
|
||||
#include "IopBios.h"
|
||||
#include "MTVU.h"
|
||||
#include "MemoryCardFile.h"
|
||||
|
@ -56,10 +57,6 @@
|
|||
#include "DebugTools/MIPSAnalyst.h"
|
||||
#include "DebugTools/SymbolMap.h"
|
||||
|
||||
#include "Frontend/FullscreenUI.h"
|
||||
#include "Frontend/INISettingsInterface.h"
|
||||
#include "Frontend/InputManager.h"
|
||||
#include "Frontend/GameList.h"
|
||||
#include "IconsFontAwesome5.h"
|
||||
|
||||
#include "common/emitter/tools.h"
|
||||
|
@ -135,10 +132,8 @@ static std::vector<u8> s_no_interlacing_cheats_data;
|
|||
static bool s_no_interlacing_cheats_loaded = false;
|
||||
static s32 s_active_widescreen_patches = 0;
|
||||
static u32 s_active_no_interlacing_patches = 0;
|
||||
static s32 s_current_save_slot = 1;
|
||||
static u32 s_frame_advance_count = 0;
|
||||
static u32 s_mxcsr_saved;
|
||||
static std::optional<LimiterModeType> s_limiter_mode_prior_to_hold_interaction;
|
||||
static bool s_gs_open_on_initialize = false;
|
||||
|
||||
bool VMManager::PerformEarlyHardwareChecks(const char** error)
|
||||
|
@ -193,7 +188,6 @@ void VMManager::SetState(VMState state)
|
|||
if (THREAD_VU1)
|
||||
vu1Thread.WaitVU();
|
||||
GetMTGS().WaitGS(false);
|
||||
InputManager::PauseVibration();
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -203,15 +197,9 @@ void VMManager::SetState(VMState state)
|
|||
|
||||
SPU2SetOutputPaused(state == VMState::Paused);
|
||||
if (state == VMState::Paused)
|
||||
{
|
||||
Host::OnVMPaused();
|
||||
FullscreenUI::OnVMPaused();
|
||||
}
|
||||
else
|
||||
{
|
||||
Host::OnVMResumed();
|
||||
FullscreenUI::OnVMResumed();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -319,12 +307,10 @@ void VMManager::LoadSettings()
|
|||
{
|
||||
std::unique_lock<std::mutex> lock = Host::GetSettingsLock();
|
||||
SettingsInterface* si = Host::GetSettingsInterface();
|
||||
SettingsInterface* binding_si = Host::GetSettingsInterfaceForBindings();
|
||||
SettingsLoadWrapper slw(*si);
|
||||
EmuConfig.LoadSave(slw);
|
||||
PAD::LoadConfig(*binding_si);
|
||||
InputManager::ReloadSources(*si, lock);
|
||||
InputManager::ReloadBindings(*si, *binding_si);
|
||||
PAD::LoadConfig(*si);
|
||||
Host::LoadSettings(*si, lock);
|
||||
|
||||
// Remove any user-specified hacks in the config (we don't want stale/conflicting values when it's globally disabled).
|
||||
EmuConfig.GS.MaskUserHacks();
|
||||
|
@ -703,12 +689,6 @@ void VMManager::UpdateRunningGame(bool resetting, bool game_starting)
|
|||
GetMTGS().SendGameCRC(new_crc);
|
||||
|
||||
Host::OnGameChanged(s_disc_path, s_game_serial, s_game_name, s_game_crc);
|
||||
if (FullscreenUI::IsInitialized())
|
||||
{
|
||||
GetMTGS().RunOnGSThread([disc_path = s_disc_path, game_serial = s_game_serial, game_name = s_game_name, game_crc = s_game_crc]() {
|
||||
FullscreenUI::OnRunningGameChanged(std::move(disc_path), std::move(game_serial), std::move(game_name), game_crc);
|
||||
});
|
||||
}
|
||||
|
||||
#if 0
|
||||
// TODO: Enable this when the debugger is added to Qt, and it's active. Otherwise, this is just a waste of time.
|
||||
|
@ -992,7 +972,6 @@ bool VMManager::Initialize(VMBootParameters boot_params)
|
|||
Console.WriteLn("VM subsystems initialized in %.2f ms", init_timer.GetTimeMilliseconds());
|
||||
s_state.store(VMState::Paused, std::memory_order_release);
|
||||
Host::OnVMStarted();
|
||||
FullscreenUI::OnVMStarted();
|
||||
|
||||
UpdateRunningGame(true, false);
|
||||
|
||||
|
@ -1055,7 +1034,6 @@ void VMManager::Shutdown(bool save_resume_state)
|
|||
s_active_game_fixes = 0;
|
||||
s_active_widescreen_patches = 0;
|
||||
s_active_no_interlacing_patches = 0;
|
||||
s_limiter_mode_prior_to_hold_interaction.reset();
|
||||
|
||||
UpdateGameSettingsLayer();
|
||||
|
||||
|
@ -1094,7 +1072,6 @@ void VMManager::Shutdown(bool save_resume_state)
|
|||
|
||||
s_state.store(VMState::Shutdown, std::memory_order_release);
|
||||
Host::OnVMDestroyed();
|
||||
FullscreenUI::OnVMDestroyed();
|
||||
}
|
||||
|
||||
void VMManager::Reset()
|
||||
|
@ -1104,7 +1081,6 @@ void VMManager::Reset()
|
|||
s_active_game_fixes = 0;
|
||||
s_active_widescreen_patches = 0;
|
||||
s_active_no_interlacing_patches = 0;
|
||||
s_limiter_mode_prior_to_hold_interaction.reset();
|
||||
|
||||
SysClearExecutionCache();
|
||||
memBindConditionalHandlers();
|
||||
|
@ -1138,22 +1114,10 @@ std::string VMManager::GetSaveStateFileName(const char* filename, s32 slot)
|
|||
pxAssertRel(!HasValidVM(), "Should not have a VM when calling the non-gamelist GetSaveStateFileName()");
|
||||
|
||||
std::string ret;
|
||||
|
||||
// try the game list first, but this won't work if we're in batch mode
|
||||
auto lock = GameList::GetLock();
|
||||
if (const GameList::Entry* entry = GameList::GetEntryForPath(filename); entry)
|
||||
{
|
||||
ret = GetSaveStateFileName(entry->serial.c_str(), entry->crc, slot);
|
||||
}
|
||||
else
|
||||
{
|
||||
// just scan it.. hopefully it'll come back okay
|
||||
GameList::Entry temp_entry;
|
||||
if (GameList::PopulateEntryFromPath(filename, &temp_entry))
|
||||
{
|
||||
ret = GetSaveStateFileName(temp_entry.serial.c_str(), temp_entry.crc, slot);
|
||||
}
|
||||
}
|
||||
std::string serial;
|
||||
u32 crc;
|
||||
if (Host::GetSerialAndCRCForFilename(filename, &serial, &crc))
|
||||
ret = GetSaveStateFileName(serial.c_str(), crc, slot);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
@ -1409,9 +1373,22 @@ bool VMManager::IsSaveStateFileName(const std::string_view& path)
|
|||
return StringUtil::EndsWithNoCase(path, ".p2s");
|
||||
}
|
||||
|
||||
bool VMManager::IsDiscFileName(const std::string_view& path)
|
||||
{
|
||||
static const char* extensions[] = {".iso", ".bin", ".img", ".gz", ".cso", ".chd"};
|
||||
|
||||
for (const char* test_extension : extensions)
|
||||
{
|
||||
if (StringUtil::EndsWithNoCase(path, test_extension))
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool VMManager::IsLoadableFileName(const std::string_view& path)
|
||||
{
|
||||
return IsElfFileName(path) || IsGSDumpFileName(path) || IsBlockDumpFileName(path) || GameList::IsScannableFilename(path);
|
||||
return IsDiscFileName(path) || IsElfFileName(path) || IsGSDumpFileName(path) || IsBlockDumpFileName(path);
|
||||
}
|
||||
|
||||
void VMManager::Execute()
|
||||
|
@ -1482,8 +1459,7 @@ void VMManager::Internal::VSyncOnCPUThread()
|
|||
}
|
||||
}
|
||||
|
||||
Host::PumpMessagesOnCPUThread();
|
||||
InputManager::PollSources();
|
||||
Host::CPUThreadVSync();
|
||||
}
|
||||
|
||||
void VMManager::CheckForCPUConfigChanges(const Pcsx2Config& old_config)
|
||||
|
@ -1681,6 +1657,8 @@ void VMManager::CheckForConfigChanges(const Pcsx2Config& old_config)
|
|||
// and we don't update its config when we start the VM.
|
||||
if (HasValidVM() || GetMTGS().IsOpen())
|
||||
CheckForGSConfigChanges(old_config);
|
||||
|
||||
Host::CheckForSettingsChanges(old_config);
|
||||
}
|
||||
|
||||
void VMManager::ApplySettings()
|
||||
|
@ -1808,204 +1786,6 @@ void VMManager::WarnAboutUnsafeSettings()
|
|||
}
|
||||
}
|
||||
|
||||
static void HotkeyAdjustTargetSpeed(double delta)
|
||||
{
|
||||
EmuConfig.Framerate.NominalScalar = EmuConfig.GS.LimitScalar + delta;
|
||||
VMManager::SetLimiterMode(LimiterModeType::Nominal);
|
||||
gsUpdateFrequency(EmuConfig);
|
||||
GetMTGS().SetVSync(EmuConfig.GetEffectiveVsyncMode());
|
||||
Host::AddIconOSDMessage("SpeedChanged", ICON_FA_CLOCK, fmt::format("Target speed set to {:.0f}%.", std::round(EmuConfig.Framerate.NominalScalar * 100.0)), 5.0f);
|
||||
}
|
||||
|
||||
static constexpr s32 CYCLE_SAVE_STATE_SLOTS = 10;
|
||||
|
||||
static void HotkeyCycleSaveSlot(s32 delta)
|
||||
{
|
||||
// 1..10
|
||||
s_current_save_slot = ((s_current_save_slot - 1) + delta);
|
||||
if (s_current_save_slot < 0)
|
||||
s_current_save_slot = CYCLE_SAVE_STATE_SLOTS;
|
||||
else
|
||||
s_current_save_slot = (s_current_save_slot % CYCLE_SAVE_STATE_SLOTS) + 1;
|
||||
|
||||
const std::string filename(VMManager::GetSaveStateFileName(s_game_serial.c_str(), s_game_crc, s_current_save_slot));
|
||||
FILESYSTEM_STAT_DATA sd;
|
||||
if (!filename.empty() && FileSystem::StatFile(filename.c_str(), &sd))
|
||||
{
|
||||
char date_buf[128] = {};
|
||||
#ifdef _WIN32
|
||||
ctime_s(date_buf, std::size(date_buf), &sd.ModificationTime);
|
||||
#else
|
||||
ctime_r(&sd.ModificationTime, date_buf);
|
||||
#endif
|
||||
|
||||
// remove terminating \n
|
||||
size_t len = std::strlen(date_buf);
|
||||
if (len > 0 && date_buf[len - 1] == '\n')
|
||||
date_buf[len - 1] = 0;
|
||||
|
||||
Host::AddIconOSDMessage("CycleSaveSlot", ICON_FA_SEARCH, fmt::format("Save slot {} selected (last save: {}).", s_current_save_slot, date_buf), 5.0f);
|
||||
}
|
||||
else
|
||||
{
|
||||
Host::AddIconOSDMessage("CycleSaveSlot", ICON_FA_SEARCH, fmt::format("Save slot {} selected (no save yet).", s_current_save_slot), 5.0f);
|
||||
}
|
||||
}
|
||||
|
||||
static void HotkeyLoadStateSlot(s32 slot)
|
||||
{
|
||||
if (s_game_crc == 0)
|
||||
{
|
||||
Host::AddIconOSDMessage("LoadStateFromSlot", ICON_FA_EXCLAMATION_TRIANGLE, "Cannot load state from a slot without a game running.", 10.0f);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!VMManager::HasSaveStateInSlot(s_game_serial.c_str(), s_game_crc, slot))
|
||||
{
|
||||
Host::AddIconOSDMessage("LoadStateFromSlot", ICON_FA_EXCLAMATION_TRIANGLE, fmt::format("No save state found in slot {}.", slot));
|
||||
return;
|
||||
}
|
||||
|
||||
VMManager::LoadStateFromSlot(slot);
|
||||
}
|
||||
|
||||
static void HotkeySaveStateSlot(s32 slot)
|
||||
{
|
||||
if (s_game_crc == 0)
|
||||
{
|
||||
Host::AddIconOSDMessage("SaveStateToSlot", ICON_FA_EXCLAMATION_TRIANGLE, "Cannot save state to a slot without a game running.", 10.0f);
|
||||
return;
|
||||
}
|
||||
|
||||
VMManager::SaveStateToSlot(slot);
|
||||
}
|
||||
|
||||
BEGIN_HOTKEY_LIST(g_vm_manager_hotkeys)
|
||||
DEFINE_HOTKEY("OpenPauseMenu", "System", "Open Pause Menu", [](s32 pressed) {
|
||||
if (!pressed && VMManager::HasValidVM())
|
||||
FullscreenUI::OpenPauseMenu();
|
||||
})
|
||||
DEFINE_HOTKEY("TogglePause", "System", "Toggle Pause", [](s32 pressed) {
|
||||
if (!pressed && VMManager::HasValidVM())
|
||||
VMManager::SetPaused(VMManager::GetState() != VMState::Paused);
|
||||
})
|
||||
DEFINE_HOTKEY("ToggleFullscreen", "System", "Toggle Fullscreen", [](s32 pressed) {
|
||||
if (!pressed)
|
||||
Host::SetFullscreen(!Host::IsFullscreen());
|
||||
})
|
||||
DEFINE_HOTKEY("ToggleFrameLimit", "System", "Toggle Frame Limit", [](s32 pressed) {
|
||||
if (!pressed && VMManager::HasValidVM())
|
||||
{
|
||||
VMManager::SetLimiterMode((EmuConfig.LimiterMode != LimiterModeType::Unlimited) ?
|
||||
LimiterModeType::Unlimited :
|
||||
LimiterModeType::Nominal);
|
||||
}
|
||||
})
|
||||
DEFINE_HOTKEY("ToggleTurbo", "System", "Toggle Turbo", [](s32 pressed) {
|
||||
if (!pressed && VMManager::HasValidVM())
|
||||
{
|
||||
VMManager::SetLimiterMode((EmuConfig.LimiterMode != LimiterModeType::Turbo) ?
|
||||
LimiterModeType::Turbo :
|
||||
LimiterModeType::Nominal);
|
||||
}
|
||||
})
|
||||
DEFINE_HOTKEY("ToggleSlowMotion", "System", "Toggle Slow Motion", [](s32 pressed) {
|
||||
if (!pressed && VMManager::HasValidVM())
|
||||
{
|
||||
VMManager::SetLimiterMode((EmuConfig.LimiterMode != LimiterModeType::Slomo) ?
|
||||
LimiterModeType::Slomo :
|
||||
LimiterModeType::Nominal);
|
||||
}
|
||||
})
|
||||
DEFINE_HOTKEY("HoldTurbo", "System", "Turbo (Hold)", [](s32 pressed) {
|
||||
if (!VMManager::HasValidVM())
|
||||
return;
|
||||
if (pressed > 0 && !s_limiter_mode_prior_to_hold_interaction.has_value())
|
||||
{
|
||||
s_limiter_mode_prior_to_hold_interaction = VMManager::GetLimiterMode();
|
||||
VMManager::SetLimiterMode((s_limiter_mode_prior_to_hold_interaction.value() != LimiterModeType::Turbo) ?
|
||||
LimiterModeType::Turbo :
|
||||
LimiterModeType::Nominal);
|
||||
}
|
||||
else if (pressed >= 0 && s_limiter_mode_prior_to_hold_interaction.has_value())
|
||||
{
|
||||
VMManager::SetLimiterMode(s_limiter_mode_prior_to_hold_interaction.value());
|
||||
s_limiter_mode_prior_to_hold_interaction.reset();
|
||||
}
|
||||
})
|
||||
DEFINE_HOTKEY("IncreaseSpeed", "System", "Increase Target Speed", [](s32 pressed) {
|
||||
if (!pressed)
|
||||
HotkeyAdjustTargetSpeed(0.1);
|
||||
})
|
||||
DEFINE_HOTKEY("DecreaseSpeed", "System", "Decrease Target Speed", [](s32 pressed) {
|
||||
if (!pressed)
|
||||
HotkeyAdjustTargetSpeed(-0.1);
|
||||
})
|
||||
DEFINE_HOTKEY("FrameAdvance", "System", "Frame Advance", [](s32 pressed) {
|
||||
if (!pressed && VMManager::HasValidVM())
|
||||
VMManager::FrameAdvance(1);
|
||||
})
|
||||
DEFINE_HOTKEY("ShutdownVM", "System", "Shut Down Virtual Machine", [](s32 pressed) {
|
||||
if (!pressed && VMManager::HasValidVM())
|
||||
Host::RequestVMShutdown(true, true, EmuConfig.SaveStateOnShutdown);
|
||||
})
|
||||
DEFINE_HOTKEY("ResetVM", "System", "Reset Virtual Machine", [](s32 pressed) {
|
||||
if (!pressed && VMManager::HasValidVM())
|
||||
VMManager::Reset();
|
||||
})
|
||||
DEFINE_HOTKEY("InputRecToggleMode", "System", "Toggle Input Recording Mode", [](s32 pressed) {
|
||||
if (!pressed && VMManager::HasValidVM())
|
||||
g_InputRecordingControls.RecordModeToggle();
|
||||
})
|
||||
|
||||
DEFINE_HOTKEY("PreviousSaveStateSlot", "Save States", "Select Previous Save Slot", [](s32 pressed) {
|
||||
if (!pressed && VMManager::HasValidVM())
|
||||
HotkeyCycleSaveSlot(-1);
|
||||
})
|
||||
DEFINE_HOTKEY("NextSaveStateSlot", "Save States", "Select Next Save Slot", [](s32 pressed) {
|
||||
if (!pressed && VMManager::HasValidVM())
|
||||
HotkeyCycleSaveSlot(1);
|
||||
})
|
||||
DEFINE_HOTKEY("SaveStateToSlot", "Save States", "Save State To Selected Slot", [](s32 pressed) {
|
||||
if (!pressed && VMManager::HasValidVM())
|
||||
VMManager::SaveStateToSlot(s_current_save_slot);
|
||||
})
|
||||
DEFINE_HOTKEY("LoadStateFromSlot", "Save States", "Load State From Selected Slot", [](s32 pressed) {
|
||||
if (!pressed && VMManager::HasValidVM())
|
||||
HotkeyLoadStateSlot(s_current_save_slot);
|
||||
})
|
||||
|
||||
#define DEFINE_HOTKEY_SAVESTATE_X(slotnum) DEFINE_HOTKEY("SaveStateToSlot" #slotnum, \
|
||||
"Save States", "Save State To Slot " #slotnum, [](s32 pressed) { if (!pressed) HotkeySaveStateSlot(slotnum); })
|
||||
#define DEFINE_HOTKEY_LOADSTATE_X(slotnum) DEFINE_HOTKEY("LoadStateFromSlot" #slotnum, \
|
||||
"Save States", "Load State From Slot " #slotnum, [](s32 pressed) { \
|
||||
if (!pressed) \
|
||||
HotkeyLoadStateSlot(slotnum); \
|
||||
})
|
||||
DEFINE_HOTKEY_SAVESTATE_X(1)
|
||||
DEFINE_HOTKEY_LOADSTATE_X(1)
|
||||
DEFINE_HOTKEY_SAVESTATE_X(2)
|
||||
DEFINE_HOTKEY_LOADSTATE_X(2)
|
||||
DEFINE_HOTKEY_SAVESTATE_X(3)
|
||||
DEFINE_HOTKEY_LOADSTATE_X(3)
|
||||
DEFINE_HOTKEY_SAVESTATE_X(4)
|
||||
DEFINE_HOTKEY_LOADSTATE_X(4)
|
||||
DEFINE_HOTKEY_SAVESTATE_X(5)
|
||||
DEFINE_HOTKEY_LOADSTATE_X(5)
|
||||
DEFINE_HOTKEY_SAVESTATE_X(6)
|
||||
DEFINE_HOTKEY_LOADSTATE_X(6)
|
||||
DEFINE_HOTKEY_SAVESTATE_X(7)
|
||||
DEFINE_HOTKEY_LOADSTATE_X(7)
|
||||
DEFINE_HOTKEY_SAVESTATE_X(8)
|
||||
DEFINE_HOTKEY_LOADSTATE_X(8)
|
||||
DEFINE_HOTKEY_SAVESTATE_X(9)
|
||||
DEFINE_HOTKEY_LOADSTATE_X(9)
|
||||
DEFINE_HOTKEY_SAVESTATE_X(10)
|
||||
DEFINE_HOTKEY_LOADSTATE_X(10)
|
||||
#undef DEFINE_HOTKEY_SAVESTATE_X
|
||||
#undef DEFINE_HOTKEY_LOADSTATE_X
|
||||
END_HOTKEY_LIST()
|
||||
|
||||
#ifdef _WIN32
|
||||
|
||||
#include "common/RedtapeWindows.h"
|
||||
|
|
|
@ -152,6 +152,9 @@ namespace VMManager
|
|||
/// Returns true if the specified path is a save state.
|
||||
bool IsSaveStateFileName(const std::string_view& path);
|
||||
|
||||
/// Returns true if the specified path is a disc image.
|
||||
bool IsDiscFileName(const std::string_view& path);
|
||||
|
||||
/// Returns true if the specified path is a disc/elf/etc.
|
||||
bool IsLoadableFileName(const std::string_view& path);
|
||||
|
||||
|
@ -198,6 +201,12 @@ namespace VMManager
|
|||
|
||||
namespace Host
|
||||
{
|
||||
/// Called with the settings lock held, when system settings are being loaded (should load input sources, etc).
|
||||
void LoadSettings(SettingsInterface& si, std::unique_lock<std::mutex>& lock);
|
||||
|
||||
/// Called after settings are updated.
|
||||
void CheckForSettingsChanges(const Pcsx2Config& old_config);
|
||||
|
||||
/// Called when the VM is starting initialization, but has not been completed yet.
|
||||
void OnVMStarting();
|
||||
|
||||
|
@ -216,6 +225,10 @@ namespace Host
|
|||
/// Called when performance metrics are updated, approximately once a second.
|
||||
void OnPerformanceMetricsUpdated();
|
||||
|
||||
/// Looks up the serial and CRC for a game in the most efficient manner possible.
|
||||
/// Implemented in the host because it may have a game list cache.
|
||||
bool GetSerialAndCRCForFilename(const char* filename, std::string* serial, u32* crc);
|
||||
|
||||
/// Called when a save state is loading, before the file is processed.
|
||||
void OnSaveStateLoading(const std::string_view& filename);
|
||||
|
||||
|
@ -230,7 +243,7 @@ namespace Host
|
|||
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();
|
||||
void CPUThreadVSync();
|
||||
|
||||
/// Provided by the host; called when a state is saved, and the frontend should invalidate its save state cache.
|
||||
void InvalidateSaveStateCache();
|
||||
|
|
|
@ -187,6 +187,7 @@
|
|||
<ClCompile Include="DEV9\net.cpp" />
|
||||
<ClCompile Include="DEV9\Win32\tap-win32.cpp" />
|
||||
<ClCompile Include="Frontend\CommonHost.cpp" />
|
||||
<ClCompile Include="Frontend\CommonHotkeys.cpp" />
|
||||
<ClCompile Include="Frontend\D3D11HostDisplay.cpp" />
|
||||
<ClCompile Include="Frontend\D3D12HostDisplay.cpp" />
|
||||
<ClCompile Include="Frontend\FullscreenUI.cpp" />
|
||||
|
@ -197,7 +198,7 @@
|
|||
<ClCompile Include="Frontend\imgui_impl_dx12.cpp" />
|
||||
<ClCompile Include="Frontend\imgui_impl_opengl3.cpp" />
|
||||
<ClCompile Include="Frontend\imgui_impl_vulkan.cpp" />
|
||||
<ClCompile Include="Frontend\INISettingsInterface.cpp" />
|
||||
<ClCompile Include="INISettingsInterface.cpp" />
|
||||
<ClCompile Include="Frontend\InputManager.cpp" />
|
||||
<ClCompile Include="Frontend\InputSource.cpp" />
|
||||
<ClCompile Include="Frontend\LayeredSettingsInterface.cpp" />
|
||||
|
@ -520,7 +521,7 @@
|
|||
<ClInclude Include="Frontend\imgui_impl_dx12.h" />
|
||||
<ClInclude Include="Frontend\imgui_impl_opengl3.h" />
|
||||
<ClInclude Include="Frontend\imgui_impl_vulkan.h" />
|
||||
<ClInclude Include="Frontend\INISettingsInterface.h" />
|
||||
<ClInclude Include="INISettingsInterface.h" />
|
||||
<ClInclude Include="Frontend\InputManager.h" />
|
||||
<ClInclude Include="Frontend\InputSource.h" />
|
||||
<ClInclude Include="Frontend\LayeredSettingsInterface.h" />
|
||||
|
@ -817,4 +818,4 @@
|
|||
</ItemGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
<ImportGroup Label="ExtensionTargets" />
|
||||
</Project>
|
||||
</Project>
|
||||
|
|
|
@ -1172,7 +1172,7 @@
|
|||
<ClCompile Include="Frontend\GameList.cpp">
|
||||
<Filter>Host</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="Frontend\INISettingsInterface.cpp">
|
||||
<ClCompile Include="INISettingsInterface.cpp">
|
||||
<Filter>Host</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="Frontend\InputManager.cpp">
|
||||
|
@ -1284,6 +1284,9 @@
|
|||
<ClCompile Include="Frontend\CommonHost.cpp">
|
||||
<Filter>Host</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="Frontend\CommonHotkeys.cpp">
|
||||
<Filter>Host</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="Patch.h">
|
||||
|
@ -2037,7 +2040,7 @@
|
|||
<ClInclude Include="Frontend\GameList.h">
|
||||
<Filter>Host</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="Frontend\INISettingsInterface.h">
|
||||
<ClInclude Include="INISettingsInterface.h">
|
||||
<Filter>Host</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="Frontend\InputManager.h">
|
||||
|
|
Loading…
Reference in New Issue