mirror of
https://github.com/shadps4-emu/shadPS4.git
synced 2025-08-04 08:22:32 +00:00
Adding stop button function to help with check update while running a game.
This commit is contained in:
parent
9424047214
commit
81369755e4
@ -102,6 +102,7 @@ Emulator::~Emulator() {
|
||||
}
|
||||
|
||||
void Emulator::Run(const std::filesystem::path& file, const std::vector<std::string> args) {
|
||||
is_running= true;
|
||||
const auto eboot_name = file.filename().string();
|
||||
auto game_folder = file.parent_path();
|
||||
if (const auto game_folder_name = game_folder.filename().string();
|
||||
@ -288,6 +289,27 @@ void Emulator::Run(const std::filesystem::path& file, const std::vector<std::str
|
||||
std::quick_exit(0);
|
||||
}
|
||||
|
||||
void Emulator::saveLastEbootPath(const std::string& path) {
|
||||
lastEbootPath = path;
|
||||
}
|
||||
|
||||
std::string Emulator::getLastEbootPath() const {
|
||||
return lastEbootPath;
|
||||
}
|
||||
|
||||
Emulator& Emulator::GetInstance() {
|
||||
static Emulator instance;
|
||||
return instance;
|
||||
}
|
||||
|
||||
void Emulator::StopEmulation() {
|
||||
if (!is_running)
|
||||
return;
|
||||
|
||||
is_running = false;
|
||||
LOG_INFO(Loader, "Stopping emulator...");
|
||||
}
|
||||
|
||||
void Emulator::LoadSystemModules(const std::string& game_serial) {
|
||||
constexpr std::array<SysModules, 11> ModulesToLoad{
|
||||
{{"libSceNgs2.sprx", &Libraries::Ngs2::RegisterlibSceNgs2},
|
||||
|
@ -5,6 +5,10 @@
|
||||
|
||||
#include <filesystem>
|
||||
#include <thread>
|
||||
#include "common/elf_info.h"
|
||||
#ifdef ENABLE_QT_GUI
|
||||
#include <QString>
|
||||
#endif
|
||||
|
||||
#include "common/singleton.h"
|
||||
#include "core/linker.h"
|
||||
@ -27,10 +31,17 @@ public:
|
||||
|
||||
void Run(const std::filesystem::path& file, const std::vector<std::string> args = {});
|
||||
void UpdatePlayTime(const std::string& serial);
|
||||
static Emulator& GetInstance();
|
||||
void StopEmulation();
|
||||
bool is_running = false;
|
||||
void saveLastEbootPath(const std::string& path);
|
||||
std::string getLastEbootPath() const;
|
||||
|
||||
private:
|
||||
void LoadSystemModules(const std::string& game_serial);
|
||||
|
||||
Common::ElfInfo game_info;
|
||||
std::string lastEbootPath;
|
||||
Core::MemoryManager* memory;
|
||||
Input::GameController* controller;
|
||||
Core::Linker* linker;
|
||||
|
@ -29,8 +29,8 @@
|
||||
|
||||
using namespace Common::FS;
|
||||
|
||||
CheckUpdate::CheckUpdate(const bool showMessage, QWidget* parent)
|
||||
: QDialog(parent), networkManager(new QNetworkAccessManager(this)) {
|
||||
CheckUpdate::CheckUpdate(MainWindow* mainWindow, bool showMessage, QWidget* parent)
|
||||
: QDialog(parent), networkManager(new QNetworkAccessManager(this)), m_mainWindow(mainWindow) {
|
||||
setWindowTitle(tr("Auto Updater"));
|
||||
setFixedSize(0, 0);
|
||||
CheckForUpdates(showMessage);
|
||||
@ -422,6 +422,13 @@ void CheckUpdate::DownloadUpdate(const QString& url) {
|
||||
}
|
||||
|
||||
void CheckUpdate::Install() {
|
||||
if (m_mainWindow && m_mainWindow->isGameRunning) {
|
||||
QMessageBox::warning(this, tr("Update Warning"),
|
||||
tr("A game is currently running. Please close the game to prevent "
|
||||
"save file corruption."));
|
||||
m_mainWindow->StopGameforUpdate(false);
|
||||
}
|
||||
|
||||
QString userPath;
|
||||
Common::FS::PathToQString(userPath, Common::FS::GetUserPath(Common::FS::PathType::UserDir));
|
||||
|
||||
|
@ -3,17 +3,20 @@
|
||||
|
||||
#ifndef CHECKUPDATE_H
|
||||
#define CHECKUPDATE_H
|
||||
#pragma once
|
||||
|
||||
#include <QCheckBox>
|
||||
#include <QDialog>
|
||||
#include <QNetworkAccessManager>
|
||||
#include <QPushButton>
|
||||
#include "main_window.h"
|
||||
|
||||
class CheckUpdate : public QDialog {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit CheckUpdate(const bool showMessage, QWidget* parent = nullptr);
|
||||
explicit CheckUpdate(MainWindow* mainWindow, bool showMessage, QWidget* parent = nullptr);
|
||||
CheckUpdate(const bool showMessage, QWidget* parent);
|
||||
~CheckUpdate();
|
||||
|
||||
private slots:
|
||||
@ -35,6 +38,7 @@ private:
|
||||
QString updateDownloadUrl;
|
||||
|
||||
QNetworkAccessManager* networkManager;
|
||||
MainWindow* m_mainWindow;
|
||||
};
|
||||
|
||||
#endif // CHECKUPDATE_H
|
||||
|
@ -1,10 +1,13 @@
|
||||
// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
#include <fstream>
|
||||
#include <iostream>
|
||||
#include <QDockWidget>
|
||||
#include <QKeyEvent>
|
||||
#include <QPlainTextEdit>
|
||||
#include <QProgressDialog>
|
||||
#include <SDL3/SDL_events.h>
|
||||
|
||||
#include "about_dialog.h"
|
||||
#include "cheats_patches.h"
|
||||
@ -30,6 +33,7 @@
|
||||
#ifdef ENABLE_DISCORD_RPC
|
||||
#include "common/discord_rpc_handler.h"
|
||||
#endif
|
||||
#include <SDL3/SDL_messagebox.h>
|
||||
|
||||
MainWindow::MainWindow(QWidget* parent) : QMainWindow(parent), ui(new Ui::MainWindow) {
|
||||
ui->setupUi(this);
|
||||
@ -222,12 +226,10 @@ void MainWindow::LoadGameLists() {
|
||||
|
||||
#ifdef ENABLE_UPDATER
|
||||
void MainWindow::CheckUpdateMain(bool checkSave) {
|
||||
if (checkSave) {
|
||||
if (!Config::autoUpdate()) {
|
||||
return;
|
||||
}
|
||||
if (checkSave && !Config::autoUpdate()) {
|
||||
return;
|
||||
}
|
||||
auto checkUpdate = new CheckUpdate(false);
|
||||
auto checkUpdate = new CheckUpdate(this, false, this);
|
||||
checkUpdate->exec();
|
||||
}
|
||||
#endif
|
||||
@ -276,6 +278,7 @@ void MainWindow::CreateConnects() {
|
||||
});
|
||||
|
||||
connect(ui->playButton, &QPushButton::clicked, this, &MainWindow::StartGame);
|
||||
connect(ui->stopButton, &QPushButton::clicked, this, &MainWindow::StopGame);
|
||||
connect(m_game_grid_frame.get(), &QTableWidget::cellDoubleClicked, this,
|
||||
&MainWindow::StartGame);
|
||||
connect(m_game_list_frame.get(), &QTableWidget::cellDoubleClicked, this,
|
||||
@ -335,7 +338,7 @@ void MainWindow::CreateConnects() {
|
||||
|
||||
#ifdef ENABLE_UPDATER
|
||||
connect(ui->updaterAct, &QAction::triggered, this, [this]() {
|
||||
auto checkUpdate = new CheckUpdate(true);
|
||||
auto checkUpdate = new CheckUpdate(this, false, this);
|
||||
checkUpdate->exec();
|
||||
});
|
||||
#endif
|
||||
@ -1151,6 +1154,10 @@ void MainWindow::HandleResize(QResizeEvent* event) {
|
||||
}
|
||||
}
|
||||
|
||||
std::string MainWindow::getLastEbootPath() {
|
||||
return std::string();
|
||||
}
|
||||
|
||||
void MainWindow::AddRecentFiles(QString filePath) {
|
||||
std::vector<std::string> vec = Config::getRecentFiles();
|
||||
if (!vec.empty()) {
|
||||
@ -1226,6 +1233,10 @@ void MainWindow::OnLanguageChanged(const std::string& locale) {
|
||||
LoadTranslation();
|
||||
}
|
||||
|
||||
static void ShowMessageBox(const std::string& title, const std::string& message) {
|
||||
SDL_ShowSimpleMessageBox(SDL_MESSAGEBOX_WARNING, title.c_str(), message.c_str(), NULL);
|
||||
}
|
||||
|
||||
bool MainWindow::eventFilter(QObject* obj, QEvent* event) {
|
||||
if (event->type() == QEvent::KeyPress) {
|
||||
QKeyEvent* keyEvent = static_cast<QKeyEvent*>(event);
|
||||
@ -1258,3 +1269,33 @@ void MainWindow::StartEmulator(std::filesystem::path path) {
|
||||
emulator_thread.detach();
|
||||
#endif
|
||||
}
|
||||
|
||||
void MainWindow::StopGameforUpdate(bool shouldRelaunch) {
|
||||
if (!isGameRunning) {
|
||||
return;
|
||||
}
|
||||
|
||||
Core::Emulator& emulator = Core::Emulator::GetInstance();
|
||||
emulator.StopEmulation();
|
||||
|
||||
SDL_Event quitEvent;
|
||||
quitEvent.type = SDL_EVENT_QUIT;
|
||||
SDL_PushEvent(&quitEvent);
|
||||
|
||||
isGameRunning = false;
|
||||
}
|
||||
|
||||
void MainWindow::StopGame() {
|
||||
if (!isGameRunning) {
|
||||
return;
|
||||
}
|
||||
|
||||
Core::Emulator& emulator = Core::Emulator::GetInstance();
|
||||
emulator.StopEmulation();
|
||||
|
||||
if (isGameRunning == true)
|
||||
;
|
||||
SDL_Event quitEvent;
|
||||
quitEvent.type = SDL_EVENT_QUIT + 1;
|
||||
SDL_PushEvent(&quitEvent);
|
||||
}
|
@ -38,6 +38,11 @@ public:
|
||||
void InstallDragDropPkg(std::filesystem::path file, int pkgNum, int nPkg);
|
||||
void InstallDirectory();
|
||||
void StartGame();
|
||||
void StopGameforUpdate(bool shouldRelaunch);
|
||||
void StopGame();
|
||||
std::string lastGamePath;
|
||||
std::string getLastEbootPath();
|
||||
bool isGameRunning = false;
|
||||
|
||||
private Q_SLOTS:
|
||||
void ConfigureGuiFromSettings();
|
||||
@ -65,6 +70,8 @@ private:
|
||||
void SetUiIcons(bool isWhite);
|
||||
void InstallPkg();
|
||||
void BootGame();
|
||||
bool stopButtonClicked = false;
|
||||
|
||||
void AddRecentFiles(QString filePath);
|
||||
void LoadTranslation();
|
||||
void PlayBackgroundMusic();
|
||||
@ -72,7 +79,6 @@ private:
|
||||
void StartEmulator(std::filesystem::path);
|
||||
bool isIconBlack = false;
|
||||
bool isTableList = true;
|
||||
bool isGameRunning = false;
|
||||
QActionGroup* m_icon_size_act_group = nullptr;
|
||||
QActionGroup* m_list_mode_act_group = nullptr;
|
||||
QActionGroup* m_theme_act_group = nullptr;
|
||||
@ -127,4 +133,5 @@ protected:
|
||||
std::filesystem::path last_install_dir = "";
|
||||
bool delete_file_on_install = false;
|
||||
bool use_for_all_queued = false;
|
||||
|
||||
};
|
||||
|
@ -6,6 +6,7 @@
|
||||
#include <QFileDialog>
|
||||
#include <QHoverEvent>
|
||||
#include <fmt/format.h>
|
||||
#include "main_window.h"
|
||||
|
||||
#include "common/config.h"
|
||||
#include "common/version.h"
|
||||
@ -167,9 +168,13 @@ SettingsDialog::SettingsDialog(std::span<const QString> physical_devices,
|
||||
}
|
||||
});
|
||||
|
||||
connect(ui->checkUpdateButton, &QPushButton::clicked, this, []() {
|
||||
auto checkUpdate = new CheckUpdate(true);
|
||||
checkUpdate->exec();
|
||||
connect(ui->checkUpdateButton, &QPushButton::clicked, this, [this, parent = (parent)]() {
|
||||
MainWindow* mainWindow = dynamic_cast<MainWindow*>(parent); // Use the captured 'parent'
|
||||
if (mainWindow) {
|
||||
auto checkUpdate =
|
||||
new CheckUpdate(mainWindow, true, this); // Pass MainWindow* and bool
|
||||
checkUpdate->exec();
|
||||
}
|
||||
});
|
||||
#else
|
||||
ui->updaterGroupBox->setVisible(false);
|
||||
|
@ -1,6 +1,13 @@
|
||||
// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
#include <chrono>
|
||||
#include <cstdlib>
|
||||
#include <fstream>
|
||||
#include <iostream>
|
||||
#include <thread>
|
||||
#include <sys/stat.h>
|
||||
|
||||
#include "SDL3/SDL_events.h"
|
||||
#include "SDL3/SDL_hints.h"
|
||||
#include "SDL3/SDL_init.h"
|
||||
@ -24,6 +31,12 @@
|
||||
#include "SDL3/SDL_metal.h"
|
||||
#endif
|
||||
|
||||
#ifdef _WIN32
|
||||
#include <windows.h>
|
||||
#else
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
|
||||
namespace Input {
|
||||
|
||||
using Libraries::Pad::OrbisPadButtonDataOffset;
|
||||
@ -392,11 +405,79 @@ void WindowSDL::WaitEvent() {
|
||||
case SDL_EVENT_QUIT:
|
||||
is_open = false;
|
||||
break;
|
||||
default:
|
||||
case SDL_EVENT_QUIT + 1:
|
||||
is_open = false;
|
||||
RelaunchEmulator();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void WindowSDL::RelaunchEmulator() {
|
||||
#ifdef _WIN32
|
||||
char emulatorPath[MAX_PATH];
|
||||
GetModuleFileNameA(nullptr, emulatorPath, MAX_PATH); // Get current executable path
|
||||
|
||||
std::string emulatorDir = std::string(emulatorPath);
|
||||
size_t pos = emulatorDir.find_last_of("\\/");
|
||||
if (pos != std::string::npos) {
|
||||
emulatorDir = emulatorDir.substr(0, pos); // Extract directory
|
||||
}
|
||||
|
||||
std::string scriptFileName = std::getenv("TEMP") + std::string("\\relaunch.ps1");
|
||||
std::ofstream scriptFile(scriptFileName);
|
||||
|
||||
if (scriptFile.is_open()) {
|
||||
scriptFile << "Start-Sleep -Seconds 2\n"
|
||||
<< "Start-Process -FilePath '" << emulatorPath
|
||||
<< "' -WorkingDirectory ([WildcardPattern]::Escape('" << emulatorDir << "'))\n";
|
||||
scriptFile.close();
|
||||
|
||||
// Execute PowerShell script
|
||||
std::string command =
|
||||
"powershell.exe -ExecutionPolicy Bypass -File \"" + scriptFileName + "\"";
|
||||
system(command.c_str());
|
||||
} else {
|
||||
std::cerr << "Failed to create relaunch script" << std::endl;
|
||||
}
|
||||
|
||||
#elif defined(__linux__) || defined(__APPLE__)
|
||||
char emulatorPath[1024];
|
||||
ssize_t count = readlink("/proc/self/exe", emulatorPath, sizeof(emulatorPath) - 1);
|
||||
if (count != -1) {
|
||||
emulatorPath[count] = '\0';
|
||||
} else {
|
||||
std::cerr << "Failed to get executable path" << std::endl;
|
||||
return;
|
||||
}
|
||||
|
||||
std::string emulatorDir = std::string(emulatorPath);
|
||||
size_t pos = emulatorDir.find_last_of("/");
|
||||
if (pos != std::string::npos) {
|
||||
emulatorDir = emulatorDir.substr(0, pos); // Extract directory
|
||||
}
|
||||
|
||||
std::string scriptFileName = "/tmp/relaunch.sh";
|
||||
std::ofstream scriptFile(scriptFileName);
|
||||
|
||||
if (scriptFile.is_open()) {
|
||||
scriptFile << "#!/bin/bash\n"
|
||||
<< "sleep 2\n"
|
||||
<< "cd '" << emulatorDir << "'\n"
|
||||
<< "./'" << emulatorPath + pos + 1 << "' &\n";
|
||||
scriptFile.close();
|
||||
|
||||
// Make script executable
|
||||
chmod(scriptFileName.c_str(), S_IRWXU);
|
||||
|
||||
// Execute bash script
|
||||
std::string command = "bash " + scriptFileName;
|
||||
system(command.c_str());
|
||||
} else {
|
||||
std::cerr << "Failed to create relaunch script" << std::endl;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void WindowSDL::InitTimers() {
|
||||
SDL_AddTimer(100, &PollController, controller);
|
||||
SDL_AddTimer(33, Input::MousePolling, (void*)controller);
|
||||
|
@ -88,6 +88,8 @@ public:
|
||||
}
|
||||
|
||||
void WaitEvent();
|
||||
void OnStopButtonClicked();
|
||||
void RelaunchEmulator();
|
||||
void InitTimers();
|
||||
|
||||
void RequestKeyboard();
|
||||
@ -106,6 +108,7 @@ private:
|
||||
SDL_Window* window{};
|
||||
bool is_shown{};
|
||||
bool is_open{true};
|
||||
bool stopButtonClicked = false;
|
||||
};
|
||||
|
||||
} // namespace Frontend
|
||||
|
Loading…
Reference in New Issue
Block a user