2016-09-06 00:12:56 +01:00
|
|
|
#include "mainwindow.h"
|
2016-08-23 00:54:10 +01:00
|
|
|
#include "settingsdialog.h"
|
2016-07-26 15:20:18 +01:00
|
|
|
|
2016-07-01 05:21:58 +03:00
|
|
|
#include "openglwindow.h"
|
2016-07-26 15:20:18 +01:00
|
|
|
|
2016-07-26 15:06:37 +01:00
|
|
|
#include <QDateTime>
|
2016-07-26 15:20:18 +01:00
|
|
|
#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-26 15:20:18 +01:00
|
|
|
|
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-23 00:54:10 +01:00
|
|
|
#include "PreferenceDefs.h"
|
2016-07-26 15:20:18 +01:00
|
|
|
|
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
|
|
|
|
|
|
|
|
|
|
|
setupSaveLoadStateSlots();
|
2016-09-06 00:12:56 +01:00
|
|
|
}
|
|
|
|
|
2016-06-26 23:42:21 -04:00
|
|
|
MainWindow::~MainWindow()
|
|
|
|
{
|
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;
|
|
|
|
}
|
2016-06-26 23:42:21 -04:00
|
|
|
delete ui;
|
|
|
|
}
|
|
|
|
|
|
|
|
void MainWindow::showEvent(QShowEvent* event)
|
|
|
|
{
|
|
|
|
QMainWindow::showEvent(event);
|
|
|
|
initEmu();
|
|
|
|
}
|
|
|
|
|
2016-07-26 15:20:18 +01:00
|
|
|
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));
|
|
|
|
|
|
|
|
createStatusBar();
|
2016-07-26 15:20:18 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
void MainWindow::setOpenGlPanelSize()
|
2016-09-06 00:12:56 +01:00
|
|
|
{
|
2016-07-01 05:21:58 +03:00
|
|
|
openGLWindow_resized();
|
2016-07-26 15:20:18 +01:00
|
|
|
}
|
|
|
|
|
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()
|
2016-07-26 15:20:18 +01:00
|
|
|
{
|
|
|
|
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();
|
2016-07-26 15:20:18 +01:00
|
|
|
|
|
|
|
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());
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void MainWindow::on_actionStart_Game_triggered()
|
|
|
|
{
|
|
|
|
|
|
|
|
if (g_virtualMachine != nullptr)
|
|
|
|
{
|
2016-07-26 15:06:37 +01:00
|
|
|
try
|
|
|
|
{
|
|
|
|
g_virtualMachine->Pause();
|
|
|
|
g_virtualMachine->Reset();
|
|
|
|
g_virtualMachine->m_ee->m_os->BootFromCDROM();
|
|
|
|
g_virtualMachine->Resume();
|
|
|
|
setOpenGlPanelSize();
|
|
|
|
setupSaveLoadStateSlots();
|
|
|
|
} catch( const std::exception& e) {
|
|
|
|
QMessageBox messageBox;
|
|
|
|
messageBox.critical(0,"Error",e.what());
|
|
|
|
messageBox.show();
|
|
|
|
}
|
2016-07-26 15:20:18 +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();
|
|
|
|
setOpenGlPanelSize();
|
|
|
|
setupSaveLoadStateSlots();
|
|
|
|
} catch( const std::exception& e) {
|
|
|
|
QMessageBox messageBox;
|
|
|
|
messageBox.critical(0,"Error",e.what());
|
|
|
|
messageBox.show();
|
|
|
|
}
|
2016-07-26 15:20:18 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
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());
|
|
|
|
|
|
|
|
statusBar()->addWidget(fpsLabel);
|
|
|
|
statusBar()->addWidget(dcLabel);
|
|
|
|
|
|
|
|
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::on_actionSettings_triggered()
|
|
|
|
{
|
|
|
|
SettingsDialog sd;
|
|
|
|
sd.exec();
|
|
|
|
setupSoundHandler();
|
|
|
|
CAppConfig::GetInstance().Save();
|
|
|
|
}
|
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());
|
|
|
|
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);
|
|
|
|
}
|