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);
38 m_slots[i]->installEventFilter(this);
39 connect(m_slots[i], &QAbstractButton::clicked, this, [this, i]() { triggerState(i); });
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_Escape:
68 close();
69 break;
70 default:
71 return false;
72 }
73 column %= 3;
74 row %= 9;
75 m_currentFocus = column + row;
76 m_slots[m_currentFocus]->setFocus();
77 return true;
78 }
79 return false;
80}
81
82void LoadSaveState::loadState(int slot) {
83 GBAThread* thread = m_controller->thread();
84 VFile* vf = GBAGetState(thread->gba, thread->stateDir, slot, false);
85 if (!vf) {
86 return;
87 }
88 VFileDevice vdev(vf);
89 QImage stateImage;
90 stateImage.load(&vdev, "PNG");
91 if (!stateImage.isNull()) {
92 QPixmap statePixmap;
93 statePixmap.convertFromImage(stateImage);
94 m_slots[slot]->setIcon(statePixmap);
95 m_slots[slot]->setText(QString());
96 } else {
97 m_slots[slot]->setText(tr("Slot %1").arg(slot + 1));
98 }
99 m_slots[slot]->setShortcut(QString::number(slot + 1));
100}
101
102void LoadSaveState::triggerState(int slot) {
103 if (m_mode == LoadSave::SAVE) {
104 m_controller->saveState(slot);
105 } else {
106 m_controller->loadState(slot);
107 }
108 close();
109}
110
111void LoadSaveState::closeEvent(QCloseEvent* event) {
112 emit closed();
113 QWidget::closeEvent(event);
114}