Play-/Source/ui_unix/mainwindow.cpp

399 lines
12 KiB
C++
Raw Normal View History

2016-09-06 00:12:56 +01:00
#include "mainwindow.h"
2016-08-23 00:54:10 +01:00
#include "settingsdialog.h"
2016-07-01 05:21:58 +03:00
#include "openglwindow.h"
2016-07-26 15:06:37 +01:00
#include <QDateTime>
#include <QFileDialog>
2016-08-23 00:54:10 +01:00
#include <QTimer>
2016-07-01 05:21:58 +03:00
#include <QWindow>
2016-07-26 15:06:37 +01:00
#include <QMessageBox>
2016-07-01 05:21:58 +03:00
#include "GSH_OpenGLQt.h"
2016-08-23 00:54:10 +01:00
#include "tools/PsfPlayer/Source/SH_OpenAL.h"
2016-07-26 15:06:37 +01:00
#include "DiskUtils.h"
#include "PathUtils.h"
2016-08-10 16:29:40 +01:00
#include <zlib.h>
#include <boost/version.hpp>
2016-07-26 15:06:37 +01:00
2016-08-23 00:54:10 +01:00
#include "PreferenceDefs.h"
2016-09-06 00:12:56 +01:00
#include "ui_mainwindow.h"
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
2016-07-01 05:21:58 +03:00
openglpanel = new OpenGLWindow;
QWidget * container = QWidget::createWindowContainer(openglpanel);
ui->gridLayout->addWidget(container);
connect(openglpanel, SIGNAL(heightChanged(int)), this, SLOT(openGLWindow_resized()));
connect(openglpanel, SIGNAL(widthChanged(int)), this, SLOT(openGLWindow_resized()));
connect(openglpanel, SIGNAL(keyUp(QKeyEvent*)), this, SLOT(keyReleaseEvent(QKeyEvent*)));
connect(openglpanel, SIGNAL(keyDown(QKeyEvent*)), this, SLOT(keyPressEvent(QKeyEvent*)));
2016-07-26 15:06:37 +01:00
2016-07-29 18:31:09 +01:00
connect(openglpanel, SIGNAL(focusOut(QFocusEvent*)), this, SLOT(focusOutEvent(QFocusEvent*)));
connect(openglpanel, SIGNAL(focusIn(QFocusEvent*)), this, SLOT(focusInEvent(QFocusEvent*)));
RegisterPreferences();
2016-07-29 18:31:09 +01:00
m_pauseFocusLost = CAppConfig::GetInstance().GetPreferenceBoolean(PREF_UI_PAUSEWHENFOCUSLOST);
2016-07-27 13:47:50 +01:00
UpdateUI();
2016-07-29 18:31:09 +01:00
2016-09-06 00:12:56 +01:00
}
MainWindow::~MainWindow()
{
2016-07-29 19:18:16 +01:00
CAppConfig::GetInstance().Save();
2016-08-23 00:58:47 +01:00
if (g_virtualMachine != nullptr)
{
g_virtualMachine->Pause();
g_virtualMachine->DestroyPadHandler();
g_virtualMachine->DestroyGSHandler();
g_virtualMachine->DestroySoundHandler();
g_virtualMachine->Destroy();
delete g_virtualMachine;
g_virtualMachine = nullptr;
}
delete ui;
}
void MainWindow::showEvent(QShowEvent* event)
{
QMainWindow::showEvent(event);
initEmu();
}
void MainWindow::initEmu(){
g_virtualMachine = new CPS2VM();
g_virtualMachine->Initialize();
2016-07-01 05:21:58 +03:00
g_virtualMachine->CreateGSHandler(CGSH_OpenGLQt::GetFactoryFunction(openglpanel));
2016-08-23 00:54:10 +01:00
setupSoundHandler();
2016-07-26 00:52:31 +01:00
g_virtualMachine->CreatePadHandler(CPH_HidUnix::GetFactoryFunction());
padhandler = static_cast<CPH_HidUnix*>(g_virtualMachine->GetPadHandler());
2016-08-23 00:54:10 +01:00
StatsManager = new CStatsManager();
g_virtualMachine->m_ee->m_gs->OnNewFrame.connect(boost::bind(&CStatsManager::OnNewFrame, StatsManager, _1));
g_virtualMachine->OnRunningStateChange.connect(boost::bind(&MainWindow::OnRunningStateChange, this));
2016-07-27 13:47:50 +01:00
g_virtualMachine->m_ee->m_os->OnExecutableChange.connect(boost::bind(&MainWindow::OnExecutableChange, this));
2016-08-23 00:54:10 +01:00
createStatusBar();
}
void MainWindow::setOpenGlPanelSize()
2016-09-06 00:12:56 +01:00
{
2016-07-01 05:21:58 +03:00
openGLWindow_resized();
}
2016-08-23 00:54:10 +01:00
void MainWindow::setupSoundHandler()
{
if(g_virtualMachine != nullptr){
bool audioEnabled = CAppConfig::GetInstance().GetPreferenceBoolean(PREFERENCE_AUDIO_ENABLEOUTPUT);
if(audioEnabled)
{
g_virtualMachine->CreateSoundHandler(&CSH_OpenAL::HandlerFactory);
}
else
{
g_virtualMachine->DestroySoundHandler();
}
}
}
2016-07-01 05:21:58 +03:00
void MainWindow::openGLWindow_resized()
{
if (g_virtualMachine != nullptr && g_virtualMachine->m_ee != nullptr && g_virtualMachine->m_ee->m_gs != nullptr )
{
2016-07-01 05:21:58 +03:00
GLint w = openglpanel->size().width(), h = openglpanel->size().height();
CGSHandler::PRESENTATION_PARAMS presentationParams;
presentationParams.mode = (CGSHandler::PRESENTATION_MODE)CAppConfig::GetInstance().GetPreferenceInteger(PREF_CGSHANDLER_PRESENTATION_MODE);
presentationParams.windowWidth = w;
presentationParams.windowHeight = h;
g_virtualMachine->m_ee->m_gs->SetPresentationParams(presentationParams);
g_virtualMachine->m_ee->m_gs->Flip();
}
}
void MainWindow::on_actionOpen_Game_triggered()
{
QFileDialog dialog(this);
dialog.setFileMode(QFileDialog::ExistingFile);
dialog.setNameFilter(tr("ISO/CSO/ISZ files (*.iso *cso *.isz)"));
if (dialog.exec())
{
auto fileName = dialog.selectedFiles().first();
CAppConfig::GetInstance().SetPreferenceString(PS2VM_CDROM0PATH, fileName.toStdString().c_str());
2016-07-03 20:55:03 +03:00
if (g_virtualMachine != nullptr)
2016-07-26 15:06:37 +01:00
{
2016-07-03 20:55:03 +03:00
try
{
g_virtualMachine->Pause();
g_virtualMachine->Reset();
g_virtualMachine->m_ee->m_os->BootFromCDROM();
g_virtualMachine->Resume();
} catch( const std::exception& e) {
QMessageBox messageBox;
messageBox.critical(0,"Error",e.what());
messageBox.show();
}
2016-07-26 15:06:37 +01:00
}
}
}
void MainWindow::on_actionBoot_ELF_triggered()
{
QFileDialog dialog(this);
dialog.setFileMode(QFileDialog::ExistingFile);
dialog.setNameFilter(tr("ELF files (*.elf)"));
if (dialog.exec())
{
if (g_virtualMachine != nullptr)
{
2016-07-26 15:06:37 +01:00
try
{
auto fileName = dialog.selectedFiles().first();
g_virtualMachine->Pause();
g_virtualMachine->Reset();
g_virtualMachine->m_ee->m_os->BootFromFile(fileName.toStdString().c_str());
g_virtualMachine->Resume();
} catch( const std::exception& e) {
QMessageBox messageBox;
messageBox.critical(0,"Error",e.what());
messageBox.show();
}
}
}
}
void MainWindow::on_actionExit_triggered()
{
2016-08-23 00:58:47 +01:00
close();
2016-09-06 00:12:56 +01:00
}
2016-07-26 00:52:31 +01:00
void MainWindow::keyPressEvent(QKeyEvent *event)
{
if (padhandler != nullptr)
padhandler->InputValueCallbackPressed(event->key());
}
void MainWindow::keyReleaseEvent(QKeyEvent *event)
{
if (padhandler != nullptr)
padhandler->InputValueCallbackReleased(event->key());
}
2016-08-23 00:54:10 +01:00
void MainWindow::createStatusBar()
{
fpsLabel = new QLabel(" fps:00 ");
fpsLabel->setAlignment(Qt::AlignHCenter);
fpsLabel->setMinimumSize(fpsLabel->sizeHint());
dcLabel = new QLabel(" dc:0000 ");
dcLabel->setAlignment(Qt::AlignHCenter);
dcLabel->setMinimumSize(dcLabel->sizeHint());
stateLabel = new QLabel(" Paused ");
stateLabel->setAlignment(Qt::AlignHCenter);
stateLabel->setMinimumSize(dcLabel->sizeHint());
statusBar()->addWidget(stateLabel);
2016-08-23 00:54:10 +01:00
statusBar()->addWidget(fpsLabel);
statusBar()->addWidget(dcLabel);
2016-08-23 00:54:10 +01:00
fpstimer = new QTimer(this);
connect(fpstimer, SIGNAL(timeout()), this, SLOT(setFPS()));
fpstimer->start(1000);
}
void MainWindow::setFPS()
{
int frames = StatsManager->GetFrames();
int drawCalls = StatsManager->GetDrawCalls();
int dcpf = (frames != 0) ? (drawCalls / frames) : 0;
//fprintf(stderr, "%d f/s, %d dc/f\n", frames, dcpf);
StatsManager->ClearStats();
fpsLabel->setText(QString(" fps: %1 ").arg(frames));
dcLabel->setText(QString(" dc: %1 ").arg(dcpf));
}
void MainWindow::OnRunningStateChange()
{
stateLabel->setText(g_virtualMachine->GetStatus() == CVirtualMachine::PAUSED ? "Paused" : "Running");
}
2016-08-23 00:54:10 +01:00
void MainWindow::on_actionSettings_triggered()
{
SettingsDialog sd;
sd.exec();
setupSoundHandler();
}
2016-07-26 15:06:37 +01:00
void MainWindow::setupSaveLoadStateSlots(){
bool enable = (g_virtualMachine != nullptr ? (g_virtualMachine->m_ee->m_os->GetELF() != nullptr) : false);
ui->menuSave_States->clear();
ui->menuLoad_States->clear();
for (int i=1; i <= 10; i++){
QString info = enable ? saveStateInfo(i) : "Empty";
QAction* saveaction = new QAction(this);
saveaction->setText(QString("Save Slot %1 - %2").arg(i).arg(info));
saveaction->setEnabled(enable);
saveaction->setProperty("stateSlot", i);
ui->menuSave_States->addAction(saveaction);
QAction* loadaction = new QAction(this);
loadaction->setText(QString("Load Slot %1 - %2").arg(i).arg(info));
loadaction->setEnabled(enable);
loadaction->setProperty("stateSlot", i);
ui->menuLoad_States->addAction(loadaction);
if (enable)
{
connect(saveaction, SIGNAL(triggered()), this, SLOT(saveState()));
connect(loadaction, SIGNAL(triggered()), this, SLOT(loadState()));
}
}
}
void MainWindow::saveState(){
Framework::PathUtils::EnsurePathExists(GetStateDirectoryPath());
int m_stateSlot = sender()->property("stateSlot").toInt();
g_virtualMachine->SaveState(GenerateStatePath(m_stateSlot).string().c_str());
2016-07-03 20:55:03 +03:00
2016-07-26 15:06:37 +01:00
QDateTime* dt = new QDateTime;
QString datetime = dt->currentDateTime().toString("hh:mm dd.MM.yyyy");
ui->menuSave_States->actions().at(m_stateSlot-1)->setText(QString("Save Slot %1 - %2").arg(m_stateSlot).arg(datetime));
ui->menuLoad_States->actions().at(m_stateSlot-1)->setText(QString("Load Slot %1 - %2").arg(m_stateSlot).arg(datetime));
}
void MainWindow::loadState(){
int m_stateSlot = sender()->property("stateSlot").toInt();
g_virtualMachine->LoadState(GenerateStatePath(m_stateSlot).string().c_str());
g_virtualMachine->Resume();
}
QString MainWindow::saveStateInfo(int m_stateSlot) {
QFileInfo file(GenerateStatePath(m_stateSlot).string().c_str());
if (file.exists() && file.isFile()) {
return file.created().toString("hh:mm dd.MM.yyyy");
} else {
return "Empty";
}
}
boost::filesystem::path MainWindow::GetStateDirectoryPath()
{
return CAppConfig::GetBasePath() / boost::filesystem::path("states/");
}
boost::filesystem::path MainWindow::GenerateStatePath(int m_stateSlot)
{
std::string stateFileName = std::string(g_virtualMachine->m_ee->m_os->GetExecutableName()) + ".st" + std::to_string(m_stateSlot) + ".zip";
return GetStateDirectoryPath() / boost::filesystem::path(stateFileName);
}
void MainWindow::on_actionPause_Resume_triggered()
{
if (g_virtualMachine != nullptr)
{
if (g_virtualMachine->GetStatus() == CVirtualMachine::PAUSED)
{
g_virtualMachine->Resume();
} else {
g_virtualMachine->Pause();
}
}
}
2016-07-26 00:22:08 +01:00
void MainWindow::closeEvent(QCloseEvent *event)
{
QMessageBox::StandardButton resBtn = QMessageBox::question(this, "Close Confirmation?",
tr("Are you sure you want to exit?\nHave you saved your progress?\n"),
QMessageBox::Yes | QMessageBox::No,
QMessageBox::Yes);
if (resBtn != QMessageBox::Yes) {
event->ignore();
} else {
event->accept();
}
}
2016-08-10 16:29:40 +01:00
void MainWindow::on_actionAbout_triggered()
{
QMessageBox messageBox;
messageBox.setIconPixmap(QPixmap(":/assets/app_icon.png"));
QString about("Version %1 (%2)\nQt v%3 - zlib v%4 - boost v%5");
QString ver("%1.%2.%3"), boostver,qtver;
boostver = ver.arg(BOOST_VERSION / 100000).arg(BOOST_VERSION / 100 % 1000).arg(BOOST_VERSION % 100);
messageBox.about(this, this->windowTitle(), about.arg(QString(PLAY_VERSION), __DATE__, QT_VERSION_STR, ZLIB_VERSION, boostver));
messageBox.show();
}
2016-07-27 13:47:50 +01:00
void MainWindow::OnExecutableChange()
{
UpdateUI();
}
void MainWindow::UpdateUI()
{
2016-07-29 18:31:09 +01:00
ui->actionPause_when_focus_is_lost->setChecked(m_pauseFocusLost);
2016-07-27 13:47:50 +01:00
setOpenGlPanelSize();
setupSaveLoadStateSlots();
}
void MainWindow::RegisterPreferences()
{
CAppConfig::GetInstance().RegisterPreferenceBoolean(PREFERENCE_AUDIO_ENABLEOUTPUT, true);
2016-07-29 18:31:09 +01:00
CAppConfig::GetInstance().RegisterPreferenceBoolean(PREF_UI_PAUSEWHENFOCUSLOST, true);
}
void MainWindow::focusOutEvent(QFocusEvent * event)
{
if (m_pauseFocusLost && g_virtualMachine->GetStatus() == CVirtualMachine::RUNNING)
{
if (!isActiveWindow() && !openglpanel->isActive())
{
if (g_virtualMachine != nullptr) {
g_virtualMachine->Pause();
m_deactivatePause = true;
}
}
}
}
void MainWindow::focusInEvent(QFocusEvent * event)
{
if (m_pauseFocusLost && g_virtualMachine->GetStatus() == CVirtualMachine::PAUSED)
{
if (m_deactivatePause && (isActiveWindow() || openglpanel->isActive())){
if (g_virtualMachine != nullptr)
{
g_virtualMachine->Resume();
m_deactivatePause = false;
}
}
}
}
void MainWindow::on_actionPause_when_focus_is_lost_triggered(bool checked)
{
m_pauseFocusLost = checked;
CAppConfig::GetInstance().SetPreferenceBoolean(PREF_UI_PAUSEWHENFOCUSLOST, m_pauseFocusLost);
}