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}