mirror of https://github.com/mgba-emu/mgba.git
Qt: Handle a game crash without crashing
This commit is contained in:
parent
802e4b8720
commit
9aed9754d0
1
CHANGES
1
CHANGES
|
@ -12,6 +12,7 @@ Bugfixes:
|
|||
Misc:
|
||||
- Qt: Disable sync to video by default
|
||||
- GBA: Exit cleanly on FATAL if the port supports it
|
||||
- Qt: Handle a game crash without crashing
|
||||
|
||||
0.1.0: (2014-12-13)
|
||||
- Initial release
|
||||
|
|
|
@ -73,7 +73,12 @@ GameController::GameController(QObject* parent)
|
|||
|
||||
m_threadContext.logHandler = [] (GBAThread* context, enum GBALogLevel level, const char* format, va_list args) {
|
||||
GameController* controller = static_cast<GameController*>(context->userData);
|
||||
if (!(controller->m_logLevels & level)) {
|
||||
if (level == GBA_LOG_FATAL) {
|
||||
MutexLock(&controller->m_threadContext.stateMutex);
|
||||
controller->m_threadContext.state = THREAD_EXITING;
|
||||
MutexUnlock(&controller->m_threadContext.stateMutex);
|
||||
QMetaObject::invokeMethod(controller, "crashGame", Q_ARG(const QString&, QString().vsprintf(format, args)));
|
||||
} else if (!(controller->m_logLevels & level)) {
|
||||
return;
|
||||
}
|
||||
controller->postLog(level, QString().vsprintf(format, args));
|
||||
|
@ -207,6 +212,11 @@ void GameController::closeGame() {
|
|||
emit gameStopped(&m_threadContext);
|
||||
}
|
||||
|
||||
void GameController::crashGame(const QString& crashMessage) {
|
||||
closeGame();
|
||||
emit gameCrashed(crashMessage);
|
||||
}
|
||||
|
||||
bool GameController::isPaused() {
|
||||
if (!m_gameOpen) {
|
||||
return false;
|
||||
|
|
|
@ -64,6 +64,7 @@ signals:
|
|||
void gameStopped(GBAThread*);
|
||||
void gamePaused(GBAThread*);
|
||||
void gameUnpaused(GBAThread*);
|
||||
void gameCrashed(const QString& errorMessage);
|
||||
void stateLoaded(GBAThread*);
|
||||
|
||||
void postLog(int level, const QString& log);
|
||||
|
@ -94,8 +95,10 @@ public slots:
|
|||
void enableLogLevel(int);
|
||||
void disableLogLevel(int);
|
||||
|
||||
#ifdef BUILD_SDL
|
||||
private slots:
|
||||
void crashGame(const QString& crashMessage);
|
||||
|
||||
#ifdef BUILD_SDL
|
||||
void testSDLEvents();
|
||||
|
||||
private:
|
||||
|
|
|
@ -9,6 +9,7 @@
|
|||
#include <QKeyEvent>
|
||||
#include <QKeySequence>
|
||||
#include <QMenuBar>
|
||||
#include <QMessageBox>
|
||||
#include <QStackedLayout>
|
||||
|
||||
#include "ConfigController.h"
|
||||
|
@ -74,6 +75,7 @@ Window::Window(ConfigController* config, QWidget* parent)
|
|||
connect(m_controller, SIGNAL(gameUnpaused(GBAThread*)), m_display, SLOT(unpauseDrawing()));
|
||||
connect(m_controller, SIGNAL(postLog(int, const QString&)), m_logView, SLOT(postLog(int, const QString&)));
|
||||
connect(m_controller, SIGNAL(frameAvailable(const uint32_t*)), this, SLOT(recordFrame()));
|
||||
connect(m_controller, SIGNAL(gameCrashed(const QString&)), this, SLOT(gameCrashed(const QString&)));
|
||||
connect(m_logView, SIGNAL(levelsSet(int)), m_controller, SLOT(setLogLevel(int)));
|
||||
connect(m_logView, SIGNAL(levelsEnabled(int)), m_controller, SLOT(enableLogLevel(int)));
|
||||
connect(m_logView, SIGNAL(levelsDisabled(int)), m_controller, SLOT(disableLogLevel(int)));
|
||||
|
@ -325,6 +327,14 @@ void Window::gameStopped() {
|
|||
m_fpsTimer.stop();
|
||||
}
|
||||
|
||||
void Window::gameCrashed(const QString& errorMessage) {
|
||||
QMessageBox* crash = new QMessageBox(QMessageBox::Critical, tr("Crash"),
|
||||
tr("The game has crashed with the following error:\n\n%1").arg(errorMessage),
|
||||
QMessageBox::Ok, this, Qt::Sheet);
|
||||
crash->setAttribute(Qt::WA_DeleteOnClose);
|
||||
crash->show();
|
||||
}
|
||||
|
||||
void Window::redoLogo() {
|
||||
if (m_controller->isLoaded()) {
|
||||
return;
|
||||
|
|
|
@ -87,6 +87,7 @@ protected:
|
|||
private slots:
|
||||
void gameStarted(GBAThread*);
|
||||
void gameStopped();
|
||||
void gameCrashed(const QString&);
|
||||
void redoLogo();
|
||||
|
||||
void recordFrame();
|
||||
|
|
Loading…
Reference in New Issue