all repos — mgba @ d52be5b3d9e4e22f3d3ba5183093580d120e9253

mGBA Game Boy Advance Emulator

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

  1#include "LoadSaveState.h"
  2
  3#include "GameController.h"
  4#include "VFileDevice.h"
  5
  6#include <QKeyEvent>
  7
  8extern "C" {
  9#include "gba-serialize.h"
 10#include "gba-video.h"
 11}
 12
 13using namespace QGBA;
 14
 15LoadSaveState::LoadSaveState(GameController* controller, QWidget* parent)
 16	: QWidget(parent)
 17	, m_controller(controller)
 18	, m_currentFocus(0)
 19{
 20	m_ui.setupUi(this);
 21
 22	QImage currentImage(reinterpret_cast<const uchar*>(controller->drawContext()), VIDEO_HORIZONTAL_PIXELS, VIDEO_VERTICAL_PIXELS, 1024, QImage::Format_RGB32);
 23	m_currentImage.convertFromImage(currentImage.rgbSwapped());
 24
 25	m_slots[0] = m_ui.state1;
 26	m_slots[1] = m_ui.state2;
 27	m_slots[2] = m_ui.state3;
 28	m_slots[3] = m_ui.state4;
 29	m_slots[4] = m_ui.state5;
 30	m_slots[5] = m_ui.state6;
 31	m_slots[6] = m_ui.state7;
 32	m_slots[7] = m_ui.state8;
 33	m_slots[8] = m_ui.state9;
 34
 35	int i;
 36	for (i = 0; i < NUM_SLOTS; ++i) {
 37		loadState(i + 1);
 38		m_slots[i]->installEventFilter(this);
 39		connect(m_slots[i], &QAbstractButton::clicked, this, [this, i]() { triggerState(i + 1); });
 40	}
 41}
 42
 43void LoadSaveState::setMode(LoadSave mode) {
 44	m_mode = mode;
 45	QString text = mode == LoadSave::LOAD ? tr("Load State") : tr("SaveState");
 46	setWindowTitle(text);
 47	m_ui.lsLabel->setText(text);
 48}
 49
 50bool LoadSaveState::eventFilter(QObject*, QEvent* event) {
 51	if (event->type() == QEvent::KeyPress) {
 52		int column = m_currentFocus % 3;
 53		int row = m_currentFocus - column;
 54		switch (static_cast<QKeyEvent*>(event)->key()) {
 55		case Qt::Key_Up:
 56			row += 6;
 57			break;
 58		case Qt::Key_Down:
 59			row += 3;
 60			break;
 61		case Qt::Key_Left:
 62			column += 2;
 63			break;
 64		case Qt::Key_Right:
 65			column += 1;
 66			break;
 67		case Qt::Key_1:
 68		case Qt::Key_2:
 69		case Qt::Key_3:
 70		case Qt::Key_4:
 71		case Qt::Key_5:
 72		case Qt::Key_6:
 73		case Qt::Key_7:
 74		case Qt::Key_8:
 75		case Qt::Key_9:
 76			triggerState(static_cast<QKeyEvent*>(event)->key() - Qt::Key_1 + 1);
 77			break;
 78		case Qt::Key_Escape:
 79			close();
 80			break;
 81		default:
 82			return false;
 83		}
 84		column %= 3;
 85		row %= 9;
 86		m_currentFocus = column + row;
 87		m_slots[m_currentFocus]->setFocus();
 88		return true;
 89	}
 90	return false;
 91}
 92
 93void LoadSaveState::loadState(int slot) {
 94	GBAThread* thread = m_controller->thread();
 95	VFile* vf = GBAGetState(thread->gba, thread->stateDir, slot, false);
 96	if (!vf) {
 97		m_slots[slot - 1]->setText(tr("Empty"));
 98		return;
 99	}
100	VFileDevice vdev(vf);
101	QImage stateImage;
102	stateImage.load(&vdev, "PNG");
103	if (!stateImage.isNull()) {
104		QPixmap statePixmap;
105		statePixmap.convertFromImage(stateImage);
106		m_slots[slot - 1]->setIcon(statePixmap);
107		m_slots[slot - 1]->setText(QString());
108	} else {
109		m_slots[slot - 1]->setText(tr("Slot %1").arg(slot));
110	}
111}
112
113void LoadSaveState::triggerState(int slot) {
114	if (m_mode == LoadSave::SAVE) {
115		m_controller->saveState(slot);
116	} else {
117		m_controller->loadState(slot);
118	}
119	close();
120}
121
122void LoadSaveState::closeEvent(QCloseEvent* event) {
123	emit closed();
124	QWidget::closeEvent(event);
125}