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