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