all repos — mgba @ f6a7fedb2813d070a07cd6da65e8ddd666cd41d1

mGBA Game Boy Advance Emulator

src/platform/qt/LoadSaveState.cpp (view raw)

  1/* Copyright (c) 2013-2014 Jeffrey Pfau
  2 *
  3 * This Source Code Form is subject to the terms of the Mozilla Public
  4 * License, v. 2.0. If a copy of the MPL was not distributed with this
  5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
  6#include "LoadSaveState.h"
  7
  8#include "GameController.h"
  9#include "VFileDevice.h"
 10
 11#include <QKeyEvent>
 12#include <QPainter>
 13
 14extern "C" {
 15#include "gba-serialize.h"
 16#include "gba-video.h"
 17}
 18
 19using namespace QGBA;
 20
 21LoadSaveState::LoadSaveState(GameController* controller, QWidget* parent)
 22	: QWidget(parent)
 23	, m_controller(controller)
 24	, m_currentFocus(0)
 25{
 26	m_ui.setupUi(this);
 27
 28	m_slots[0] = m_ui.state1;
 29	m_slots[1] = m_ui.state2;
 30	m_slots[2] = m_ui.state3;
 31	m_slots[3] = m_ui.state4;
 32	m_slots[4] = m_ui.state5;
 33	m_slots[5] = m_ui.state6;
 34	m_slots[6] = m_ui.state7;
 35	m_slots[7] = m_ui.state8;
 36	m_slots[8] = m_ui.state9;
 37
 38	int i;
 39	for (i = 0; i < NUM_SLOTS; ++i) {
 40		loadState(i + 1);
 41		m_slots[i]->installEventFilter(this);
 42		connect(m_slots[i], &QAbstractButton::clicked, this, [this, i]() { triggerState(i + 1); });
 43	}
 44}
 45
 46void LoadSaveState::setMode(LoadSave mode) {
 47	m_mode = mode;
 48	QString text = mode == LoadSave::LOAD ? tr("Load State") : tr("Save State");
 49	setWindowTitle(text);
 50	m_ui.lsLabel->setText(text);
 51}
 52
 53bool LoadSaveState::eventFilter(QObject* object, QEvent* event) {
 54	if (event->type() == QEvent::KeyPress) {
 55		int column = m_currentFocus % 3;
 56		int row = m_currentFocus - column;
 57		switch (static_cast<QKeyEvent*>(event)->key()) {
 58		case Qt::Key_Up:
 59			row += 6;
 60			break;
 61		case Qt::Key_Down:
 62			row += 3;
 63			break;
 64		case Qt::Key_Left:
 65			column += 2;
 66			break;
 67		case Qt::Key_Right:
 68			column += 1;
 69			break;
 70		case Qt::Key_1:
 71		case Qt::Key_2:
 72		case Qt::Key_3:
 73		case Qt::Key_4:
 74		case Qt::Key_5:
 75		case Qt::Key_6:
 76		case Qt::Key_7:
 77		case Qt::Key_8:
 78		case Qt::Key_9:
 79			triggerState(static_cast<QKeyEvent*>(event)->key() - Qt::Key_1 + 1);
 80			break;
 81		case Qt::Key_Escape:
 82			close();
 83			break;
 84		case Qt::Key_Enter:
 85		case Qt::Key_Return:
 86			triggerState(m_currentFocus + 1);
 87			break;
 88		default:
 89			return false;
 90		}
 91		column %= 3;
 92		row %= 9;
 93		m_currentFocus = column + row;
 94		m_slots[m_currentFocus]->setFocus();
 95		return true;
 96	}
 97	if (event->type() == QEvent::Enter) {
 98		int i;
 99		for (i = 0; i < 9; ++i) {
100			if (m_slots[i] == object) {
101				m_currentFocus = i;
102				m_slots[m_currentFocus]->setFocus();
103				return true;
104			}
105		}
106	}
107	return false;
108}
109
110void LoadSaveState::loadState(int slot) {
111	GBAThread* thread = m_controller->thread();
112	VFile* vf = GBAGetState(thread->gba, thread->stateDir, slot, false);
113	if (!vf) {
114		m_slots[slot - 1]->setText(tr("Empty"));
115		return;
116	}
117	VFileDevice vdev(vf);
118	QImage stateImage;
119	stateImage.load(&vdev, "PNG");
120	if (!stateImage.isNull()) {
121		QPixmap statePixmap;
122		statePixmap.convertFromImage(stateImage);
123		m_slots[slot - 1]->setIcon(statePixmap);
124		m_slots[slot - 1]->setText(QString());
125	} else {
126		m_slots[slot - 1]->setText(tr("Slot %1").arg(slot));
127	}
128}
129
130void LoadSaveState::triggerState(int slot) {
131	if (m_mode == LoadSave::SAVE) {
132		m_controller->saveState(slot);
133	} else {
134		m_controller->loadState(slot);
135	}
136	close();
137}
138
139void LoadSaveState::closeEvent(QCloseEvent* event) {
140	emit closed();
141	QWidget::closeEvent(event);
142}
143
144void LoadSaveState::showEvent(QShowEvent* event) {
145	m_slots[m_currentFocus]->setFocus();
146	QWidget::showEvent(event);
147}
148
149void LoadSaveState::paintEvent(QPaintEvent*) {
150	QPainter painter(this);
151	QRect full(QPoint(), size());
152	painter.drawPixmap(full, m_currentImage);
153	painter.fillRect(full, QColor(0, 0, 0, 128));
154}