mirror of https://github.com/PCSX2/pcsx2.git
Qt: Implement start disc
This commit is contained in:
parent
92aea38230
commit
5391b529b6
|
@ -497,18 +497,18 @@ void EmuThread::switchRenderer(GSRendererType renderer)
|
|||
GetMTGS().SwitchRenderer(renderer);
|
||||
}
|
||||
|
||||
void EmuThread::changeDisc(const QString& path)
|
||||
void EmuThread::changeDisc(CDVD_SourceType source, const QString& path)
|
||||
{
|
||||
if (!isOnEmuThread())
|
||||
{
|
||||
QMetaObject::invokeMethod(this, "changeDisc", Qt::QueuedConnection, Q_ARG(const QString&, path));
|
||||
QMetaObject::invokeMethod(this, "changeDisc", Qt::QueuedConnection, Q_ARG(CDVD_SourceType, source), Q_ARG(const QString&, path));
|
||||
return;
|
||||
}
|
||||
|
||||
if (!VMManager::HasValidVM())
|
||||
return;
|
||||
|
||||
VMManager::ChangeDisc(path.toStdString());
|
||||
VMManager::ChangeDisc(source, path.toStdString());
|
||||
}
|
||||
|
||||
void EmuThread::reloadPatches()
|
||||
|
|
|
@ -30,6 +30,8 @@
|
|||
class DisplayWidget;
|
||||
struct VMBootParameters;
|
||||
|
||||
enum class CDVD_SourceType : uint8_t;
|
||||
|
||||
class EmuThread : public QThread
|
||||
{
|
||||
Q_OBJECT
|
||||
|
@ -74,7 +76,7 @@ public Q_SLOTS:
|
|||
void updateEmuFolders();
|
||||
void toggleSoftwareRendering();
|
||||
void switchRenderer(GSRendererType renderer);
|
||||
void changeDisc(const QString& path);
|
||||
void changeDisc(CDVD_SourceType source, const QString& path);
|
||||
void reloadPatches();
|
||||
void reloadInputSources();
|
||||
void reloadInputBindings();
|
||||
|
|
|
@ -18,6 +18,7 @@
|
|||
#include <QtCore/QDateTime>
|
||||
#include <QtGui/QCloseEvent>
|
||||
#include <QtWidgets/QFileDialog>
|
||||
#include <QtWidgets/QInputDialog>
|
||||
#include <QtWidgets/QMessageBox>
|
||||
#include <QtWidgets/QProgressBar>
|
||||
#include <QtWidgets/QStyle>
|
||||
|
@ -28,6 +29,7 @@
|
|||
#include "common/FileSystem.h"
|
||||
|
||||
#include "pcsx2/CDVD/CDVDaccess.h"
|
||||
#include "pcsx2/CDVD/CDVDdiscReader.h"
|
||||
#include "pcsx2/Frontend/GameList.h"
|
||||
#include "pcsx2/Frontend/LogSink.h"
|
||||
#include "pcsx2/GSDumpReplayer.h"
|
||||
|
@ -53,7 +55,7 @@
|
|||
#include "Tools/InputRecording/NewInputRecordingDlg.h"
|
||||
|
||||
|
||||
static constexpr char DISC_IMAGE_FILTER[] =
|
||||
static constexpr char OPEN_FILE_FILTER[] =
|
||||
QT_TRANSLATE_NOOP("MainWindow", "All File Types (*.bin *.iso *.cue *.chd *.cso *.gz *.elf *.irx *.m3u *.gs *.gs.xz *.gs.zst *.dump);;"
|
||||
"Single-Track Raw Images (*.bin *.iso);;"
|
||||
"Cue Sheets (*.cue);;"
|
||||
|
@ -66,6 +68,15 @@ static constexpr char DISC_IMAGE_FILTER[] =
|
|||
"GS Dumps (*.gs *.gs.xz *.gs.zst);;"
|
||||
"Block Dumps (*.dump)");
|
||||
|
||||
static constexpr char DISC_IMAGE_FILTER[] =
|
||||
QT_TRANSLATE_NOOP("MainWindow", "All File Types (*.bin *.iso *.cue *.chd *.cso *.gz *.dump);;"
|
||||
"Single-Track Raw Images (*.bin *.iso);;"
|
||||
"Cue Sheets (*.cue);;"
|
||||
"MAME CHD Images (*.chd);;"
|
||||
"CSO Images (*.cso);;"
|
||||
"GZ Images (*.gz);;"
|
||||
"Block Dumps (*.dump)");
|
||||
|
||||
#ifdef __APPLE__
|
||||
const char* MainWindow::DEFAULT_THEME_NAME = "";
|
||||
#else
|
||||
|
@ -100,10 +111,10 @@ void MainWindow::initialize()
|
|||
setStyleFromSettings();
|
||||
setIconThemeFromStyle();
|
||||
#ifdef __APPLE__
|
||||
CocoaTools::AddThemeChangeHandler(this, [](void* ctx){
|
||||
CocoaTools::AddThemeChangeHandler(this, [](void* ctx) {
|
||||
// This handler is called *before* the style change has propagated far enough for Qt to see it
|
||||
// Use RunOnUIThread to delay until it has
|
||||
QtHost::RunOnUIThread([ctx = static_cast<MainWindow*>(ctx)]{
|
||||
QtHost::RunOnUIThread([ctx = static_cast<MainWindow*>(ctx)] {
|
||||
ctx->setStyleFromSettings(); // Qt won't notice the style change without us touching the palette in some way
|
||||
ctx->setIconThemeFromStyle();
|
||||
});
|
||||
|
@ -190,6 +201,7 @@ void MainWindow::setupAdditionalUi()
|
|||
void MainWindow::connectSignals()
|
||||
{
|
||||
connect(m_ui.actionStartFile, &QAction::triggered, this, &MainWindow::onStartFileActionTriggered);
|
||||
connect(m_ui.actionStartDisc, &QAction::triggered, this, &MainWindow::onStartDiscActionTriggered);
|
||||
connect(m_ui.actionStartBios, &QAction::triggered, this, &MainWindow::onStartBIOSActionTriggered);
|
||||
connect(m_ui.actionChangeDisc, &QAction::triggered, [this] { m_ui.menuChangeDisc->exec(QCursor::pos()); });
|
||||
connect(m_ui.actionChangeDiscFromFile, &QAction::triggered, this, &MainWindow::onChangeDiscFromFileActionTriggered);
|
||||
|
@ -281,7 +293,7 @@ void MainWindow::connectSignals()
|
|||
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);
|
||||
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);
|
||||
|
@ -691,8 +703,7 @@ void MainWindow::updateEmulationActions(bool starting, bool running)
|
|||
|
||||
void MainWindow::updateStatusBarWidgetVisibility()
|
||||
{
|
||||
auto Update = [this](QWidget* widget, bool visible, int stretch)
|
||||
{
|
||||
auto Update = [this](QWidget* widget, bool visible, int stretch) {
|
||||
if (widget->isVisible())
|
||||
{
|
||||
m_ui.statusBar->removeWidget(widget);
|
||||
|
@ -985,7 +996,13 @@ void MainWindow::onGameListEntryActivated()
|
|||
if (s_vm_valid)
|
||||
{
|
||||
// change disc on double click
|
||||
doDiscChange(QString::fromStdString(entry->path));
|
||||
if (!entry->IsDisc())
|
||||
{
|
||||
QMessageBox::critical(this, tr("Error"), tr("You must select a disc to change discs."));
|
||||
return;
|
||||
}
|
||||
|
||||
doDiscChange(CDVD_SourceType::Iso, QString::fromStdString(entry->path));
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -1056,11 +1073,11 @@ void MainWindow::onGameListEntryContextMenuRequested(const QPoint& point)
|
|||
menu.addSeparator();
|
||||
populateLoadStateMenu(&menu, QString::fromStdString(entry->path), QString::fromStdString(entry->serial), entry->crc);
|
||||
}
|
||||
else
|
||||
else if (entry->IsDisc())
|
||||
{
|
||||
action = menu.addAction(tr("Change Disc"));
|
||||
connect(action, &QAction::triggered, [this, entry]() {
|
||||
g_emu_thread->changeDisc(QString::fromStdString(entry->path));
|
||||
g_emu_thread->changeDisc(CDVD_SourceType::Iso, QString::fromStdString(entry->path));
|
||||
switchToEmulationView();
|
||||
});
|
||||
QtUtils::MarkActionAsDefault(action);
|
||||
|
@ -1077,12 +1094,20 @@ void MainWindow::onGameListEntryContextMenuRequested(const QPoint& point)
|
|||
|
||||
void MainWindow::onStartFileActionTriggered()
|
||||
{
|
||||
QString path =
|
||||
QDir::toNativeSeparators(QFileDialog::getOpenFileName(this, tr("Select Disc Image"), QString(), tr(DISC_IMAGE_FILTER), nullptr));
|
||||
const QString path(QDir::toNativeSeparators(QFileDialog::getOpenFileName(this, tr("Start File"), QString(), tr(OPEN_FILE_FILTER), nullptr)));
|
||||
if (path.isEmpty())
|
||||
return;
|
||||
|
||||
doStartDisc(path);
|
||||
doStartFile(std::nullopt, path);
|
||||
}
|
||||
|
||||
void MainWindow::onStartDiscActionTriggered()
|
||||
{
|
||||
QString path(getDiscDevicePath(tr("Start Disc")));
|
||||
if (path.isEmpty())
|
||||
return;
|
||||
|
||||
doStartFile(CDVD_SourceType::Disc, path);
|
||||
}
|
||||
|
||||
void MainWindow::onStartBIOSActionTriggered()
|
||||
|
@ -1098,7 +1123,7 @@ void MainWindow::onChangeDiscFromFileActionTriggered()
|
|||
if (filename.isEmpty())
|
||||
return;
|
||||
|
||||
g_emu_thread->changeDisc(filename);
|
||||
g_emu_thread->changeDisc(CDVD_SourceType::Iso, filename);
|
||||
}
|
||||
|
||||
void MainWindow::onChangeDiscFromGameListActionTriggered()
|
||||
|
@ -1109,7 +1134,11 @@ void MainWindow::onChangeDiscFromGameListActionTriggered()
|
|||
|
||||
void MainWindow::onChangeDiscFromDeviceActionTriggered()
|
||||
{
|
||||
// TODO
|
||||
QString path(getDiscDevicePath(tr("Change Disc")));
|
||||
if (path.isEmpty())
|
||||
return;
|
||||
|
||||
g_emu_thread->changeDisc(CDVD_SourceType::Disc, path);
|
||||
}
|
||||
|
||||
void MainWindow::onChangeDiscMenuAboutToShow()
|
||||
|
@ -1526,7 +1555,7 @@ void MainWindow::dropEvent(QDropEvent* event)
|
|||
const std::string filename_str(filename.toStdString());
|
||||
if (VMManager::IsSaveStateFileName(filename_str))
|
||||
{
|
||||
// can't load a save state without a current VM
|
||||
// can't load a save state without a current VM
|
||||
if (s_vm_valid)
|
||||
{
|
||||
event->acceptProposedAction();
|
||||
|
@ -1542,10 +1571,10 @@ void MainWindow::dropEvent(QDropEvent* event)
|
|||
// if we're already running, do a disc change, otherwise start
|
||||
event->acceptProposedAction();
|
||||
if (s_vm_valid)
|
||||
doDiscChange(filename);
|
||||
doDiscChange(CDVD_SourceType::Iso, filename);
|
||||
else
|
||||
doStartDisc(filename);
|
||||
}
|
||||
doStartFile(CDVD_SourceType::Iso, filename);
|
||||
}
|
||||
}
|
||||
|
||||
DisplayWidget* MainWindow::createDisplay(bool fullscreen, bool render_to_main)
|
||||
|
@ -1802,7 +1831,7 @@ void MainWindow::destroyDisplay()
|
|||
setCentralWidget(m_game_list_widget);
|
||||
m_game_list_widget->setVisible(true);
|
||||
m_game_list_widget->setFocus();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void MainWindow::focusDisplayWidget()
|
||||
|
@ -1943,6 +1972,44 @@ void MainWindow::doControllerSettings(ControllerSettingsDialog::Category categor
|
|||
dlg->setCategory(category);
|
||||
}
|
||||
|
||||
QString MainWindow::getDiscDevicePath(const QString& title)
|
||||
{
|
||||
QString ret;
|
||||
|
||||
const std::vector<std::string> devices(GetOpticalDriveList());
|
||||
if (devices.empty())
|
||||
{
|
||||
QMessageBox::critical(this, title,
|
||||
tr("Could not find any CD/DVD-ROM devices. Please ensure you have a drive connected and "
|
||||
"sufficient permissions to access it."));
|
||||
return ret;
|
||||
}
|
||||
|
||||
// if there's only one, select it automatically
|
||||
if (devices.size() == 1)
|
||||
{
|
||||
ret = QString::fromStdString(devices.front());
|
||||
return ret;
|
||||
}
|
||||
|
||||
QStringList input_options;
|
||||
for (const std::string& name : devices)
|
||||
input_options.append(QString::fromStdString(name));
|
||||
|
||||
QInputDialog input_dialog(this);
|
||||
input_dialog.setWindowTitle(title);
|
||||
input_dialog.setLabelText(tr("Select disc drive:"));
|
||||
input_dialog.setInputMode(QInputDialog::TextInput);
|
||||
input_dialog.setOptions(QInputDialog::UseListViewForComboBoxItems);
|
||||
input_dialog.setComboBoxEditable(false);
|
||||
input_dialog.setComboBoxItems(std::move(input_options));
|
||||
if (input_dialog.exec() == 0)
|
||||
return ret;
|
||||
|
||||
ret = input_dialog.textValue();
|
||||
return ret;
|
||||
}
|
||||
|
||||
void MainWindow::startGameListEntry(const GameList::Entry* entry, std::optional<s32> save_slot, std::optional<bool> fast_boot)
|
||||
{
|
||||
std::shared_ptr<VMBootParameters> params = std::make_shared<VMBootParameters>();
|
||||
|
@ -2066,7 +2133,7 @@ void MainWindow::loadSaveStateFile(const QString& filename, const QString& state
|
|||
if (s_vm_valid)
|
||||
{
|
||||
if (!filename.isEmpty() && m_current_disc_path != filename)
|
||||
g_emu_thread->changeDisc(m_current_disc_path);
|
||||
g_emu_thread->changeDisc(CDVD_SourceType::Iso, m_current_disc_path);
|
||||
g_emu_thread->loadState(state_filename);
|
||||
}
|
||||
else
|
||||
|
@ -2185,12 +2252,13 @@ void MainWindow::updateSaveStateMenus(const QString& filename, const QString& se
|
|||
populateSaveStateMenu(m_ui.menuSaveState, serial, crc);
|
||||
}
|
||||
|
||||
void MainWindow::doStartDisc(const QString& path)
|
||||
void MainWindow::doStartFile(std::optional<CDVD_SourceType> source, const QString& path)
|
||||
{
|
||||
if (s_vm_valid)
|
||||
return;
|
||||
|
||||
std::shared_ptr<VMBootParameters> params = std::make_shared<VMBootParameters>();
|
||||
params->source_type = source;
|
||||
params->filename = path.toStdString();
|
||||
|
||||
// we might still be saving a resume state...
|
||||
|
@ -2207,7 +2275,7 @@ void MainWindow::doStartDisc(const QString& path)
|
|||
g_emu_thread->startVM(std::move(params));
|
||||
}
|
||||
|
||||
void MainWindow::doDiscChange(const QString& path)
|
||||
void MainWindow::doDiscChange(CDVD_SourceType source, const QString& path)
|
||||
{
|
||||
bool reset_system = false;
|
||||
if (!m_was_disc_change_request)
|
||||
|
@ -2221,7 +2289,7 @@ void MainWindow::doDiscChange(const QString& path)
|
|||
|
||||
switchToEmulationView();
|
||||
|
||||
g_emu_thread->changeDisc(path);
|
||||
g_emu_thread->changeDisc(source, path);
|
||||
if (reset_system)
|
||||
g_emu_thread->resetVM();
|
||||
}
|
||||
|
@ -2248,7 +2316,7 @@ MainWindow::VMLock MainWindow::pauseAndLockVM()
|
|||
MainWindow::VMLock::VMLock(QWidget* dialog_parent, bool was_paused, bool was_fullscreen)
|
||||
: m_dialog_parent(dialog_parent)
|
||||
, m_was_paused(was_paused)
|
||||
, m_was_fullscreen(was_fullscreen)
|
||||
, m_was_fullscreen(was_fullscreen)
|
||||
{
|
||||
}
|
||||
|
||||
|
|
|
@ -39,6 +39,8 @@ namespace GameList
|
|||
struct Entry;
|
||||
}
|
||||
|
||||
enum class CDVD_SourceType : uint8_t;
|
||||
|
||||
class MainWindow final : public QMainWindow
|
||||
{
|
||||
Q_OBJECT
|
||||
|
@ -111,6 +113,7 @@ private Q_SLOTS:
|
|||
void onGameListEntryContextMenuRequested(const QPoint& point);
|
||||
|
||||
void onStartFileActionTriggered();
|
||||
void onStartDiscActionTriggered();
|
||||
void onStartBIOSActionTriggered();
|
||||
void onChangeDiscFromFileActionTriggered();
|
||||
void onChangeDiscFromGameListActionTriggered();
|
||||
|
@ -202,6 +205,8 @@ private:
|
|||
ControllerSettingsDialog* getControllerSettingsDialog();
|
||||
void doControllerSettings(ControllerSettingsDialog::Category category = ControllerSettingsDialog::Category::Count);
|
||||
|
||||
QString getDiscDevicePath(const QString& title);
|
||||
|
||||
void startGameListEntry(const GameList::Entry* entry, std::optional<s32> save_slot = std::nullopt,
|
||||
std::optional<bool> fast_boot = std::nullopt);
|
||||
void setGameListEntryCoverImage(const GameList::Entry* entry);
|
||||
|
@ -212,8 +217,8 @@ private:
|
|||
void populateLoadStateMenu(QMenu* menu, const QString& filename, const QString& serial, quint32 crc);
|
||||
void populateSaveStateMenu(QMenu* menu, const QString& serial, quint32 crc);
|
||||
void updateSaveStateMenus(const QString& filename, const QString& serial, quint32 crc);
|
||||
void doStartDisc(const QString& path);
|
||||
void doDiscChange(const QString& path);
|
||||
void doStartFile(std::optional<CDVD_SourceType> source, const QString& path);
|
||||
void doDiscChange(CDVD_SourceType source, const QString& path);
|
||||
|
||||
Ui::MainWindow m_ui;
|
||||
|
||||
|
|
|
@ -85,6 +85,7 @@ bool QtHost::Initialize()
|
|||
qRegisterMetaType<std::shared_ptr<VMBootParameters>>();
|
||||
qRegisterMetaType<GSRendererType>();
|
||||
qRegisterMetaType<InputBindingKey>();
|
||||
qRegisterMetaType<CDVD_SourceType>();
|
||||
qRegisterMetaType<const GameList::Entry*>();
|
||||
|
||||
if (!InitializeConfig())
|
||||
|
|
|
@ -29,11 +29,14 @@ class SettingsInterface;
|
|||
|
||||
class EmuThread;
|
||||
|
||||
enum class CDVD_SourceType : uint8_t;
|
||||
|
||||
Q_DECLARE_METATYPE(std::shared_ptr<VMBootParameters>);
|
||||
Q_DECLARE_METATYPE(std::optional<bool>);
|
||||
Q_DECLARE_METATYPE(std::function<void()>);
|
||||
Q_DECLARE_METATYPE(GSRendererType);
|
||||
Q_DECLARE_METATYPE(InputBindingKey);
|
||||
Q_DECLARE_METATYPE(CDVD_SourceType);
|
||||
|
||||
namespace QtHost
|
||||
{
|
||||
|
|
|
@ -91,6 +91,8 @@ namespace GameList
|
|||
u32 crc = 0;
|
||||
|
||||
CompatibilityRating compatibility_rating = CompatibilityRating::Unknown;
|
||||
|
||||
__fi bool IsDisc() const { return (type == EntryType::PS1Disc || type == EntryType::PS2Disc); }
|
||||
};
|
||||
|
||||
const char* EntryTypeToString(EntryType type);
|
||||
|
|
|
@ -1294,15 +1294,15 @@ void VMManager::FrameAdvance(u32 num_frames /*= 1*/)
|
|||
SetState(VMState::Running);
|
||||
}
|
||||
|
||||
bool VMManager::ChangeDisc(std::string path)
|
||||
bool VMManager::ChangeDisc(CDVD_SourceType source, std::string path)
|
||||
{
|
||||
std::string old_path(CDVDsys_GetFile(CDVD_SourceType::Iso));
|
||||
CDVD_SourceType old_type = CDVDsys_GetSourceType();
|
||||
const CDVD_SourceType old_type = CDVDsys_GetSourceType();
|
||||
const std::string old_path(CDVDsys_GetFile(old_type));
|
||||
|
||||
const std::string display_name(path.empty() ? std::string() : FileSystem::GetDisplayNameFromPath(path));
|
||||
CDVDsys_ChangeSource(path.empty() ? CDVD_SourceType::NoDisc : CDVD_SourceType::Iso);
|
||||
const std::string display_name((source != CDVD_SourceType::Iso) ? path : FileSystem::GetDisplayNameFromPath(path));
|
||||
CDVDsys_ChangeSource(source);
|
||||
if (!path.empty())
|
||||
CDVDsys_SetFile(CDVD_SourceType::Iso, std::move(path));
|
||||
CDVDsys_SetFile(source, std::move(path));
|
||||
|
||||
const bool result = DoCDVDopen();
|
||||
if (result)
|
||||
|
|
|
@ -135,7 +135,7 @@ namespace VMManager
|
|||
|
||||
/// 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);
|
||||
bool ChangeDisc(CDVD_SourceType source, std::string path);
|
||||
|
||||
/// Returns true if the specified path is an ELF.
|
||||
bool IsElfFileName(const std::string_view& path);
|
||||
|
|
Loading…
Reference in New Issue