src/platform/qt/TileView.cpp (view raw)
1/* Copyright (c) 2013-2016 Jeffrey Pfau
2 *
3 * This Source Code Form is subject to the terms of the Mozilla Public
4 * License, v. 2.0. If a copy of the MPL was not distributed with this
5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
6#include "TileView.h"
7
8#include "GBAApp.h"
9
10#include <QFontDatabase>
11#include <QTimer>
12
13extern "C" {
14#include "gba/gba.h"
15}
16
17using namespace QGBA;
18
19TileView::TileView(GameController* controller, QWidget* parent)
20 : QWidget(parent)
21 , m_controller(controller)
22 , m_tileStatus{}
23 , m_tileCache(controller->tileCache())
24 , m_paletteId(0)
25{
26 m_ui.setupUi(this);
27 m_ui.tile->setController(controller);
28
29 m_updateTimer.setSingleShot(true);
30 m_updateTimer.setInterval(1);
31 connect(&m_updateTimer, SIGNAL(timeout()), this, SLOT(updateTiles()));
32
33 connect(m_controller, SIGNAL(frameAvailable(const uint32_t*)), &m_updateTimer, SLOT(start()));
34 connect(m_controller, SIGNAL(gameStopped(mCoreThread*)), this, SLOT(close()));
35 connect(m_ui.tiles, SIGNAL(indexPressed(int)), m_ui.tile, SLOT(selectIndex(int)));
36 connect(m_ui.paletteId, SIGNAL(valueChanged(int)), this, SLOT(updatePalette(int)));
37
38 int max = 1024;
39 int boundary = 1024;
40 switch (m_controller->platform()) {
41#ifdef M_CORE_GBA
42 case PLATFORM_GBA:
43 max = 3072;
44 boundary = 2048;
45 break;
46#endif
47#ifdef M_CORE_GB
48 case PLATFORM_GB:
49 max = 1024;
50 boundary = 1024;
51 m_ui.palette256->setEnabled(false);
52 break;
53#endif
54 default:
55 return;
56 }
57 m_ui.tile->setPaletteSet(0, boundary, max);
58
59 connect(m_ui.palette256, &QAbstractButton::toggled, [this](bool selected) {
60 if (selected) {
61 m_ui.paletteId->setValue(0);
62 }
63 int max = 1024;
64 int boundary = 1024;
65 switch (m_controller->platform()) {
66#ifdef M_CORE_GBA
67 case PLATFORM_GBA:
68 max = 3072 >> selected;
69 boundary = 2048 >> selected;
70 break;
71#endif
72#ifdef M_CORE_GB
73 case PLATFORM_GB:
74 return;
75#endif
76 default:
77 break;
78 }
79 m_ui.tile->setPaletteSet(selected, boundary, max);
80 updateTiles(true);
81 });
82 connect(m_ui.magnification, static_cast<void (QSpinBox::*)(int)>(&QSpinBox::valueChanged), [this]() {
83 updateTiles(true);
84 });
85}
86
87void TileView::updateTiles(bool force) {
88 if (!m_controller->thread() || !m_controller->thread()->core) {
89 return;
90 }
91
92 switch (m_controller->platform()) {
93#ifdef M_CORE_GBA
94 case PLATFORM_GBA:
95 updateTilesGBA(force);
96 break;
97#endif
98#ifdef M_CORE_GB
99 case PLATFORM_GB:
100 updateTilesGB(force);
101 break;
102#endif
103 default:
104 return;
105 }
106}
107
108#ifdef M_CORE_GBA
109void TileView::updateTilesGBA(bool force) {
110 if (m_ui.palette256->isChecked()) {
111 m_ui.tiles->setTileCount(1536);
112 mTileCacheSetPalette(m_tileCache.get(), 1);
113 for (int i = 0; i < 1024; ++i) {
114 const uint16_t* data = mTileCacheGetTileIfDirty(m_tileCache.get(), &m_tileStatus[32 * i], i, 0);
115 if (data) {
116 m_ui.tiles->setTile(i, data);
117 } else if (force) {
118 m_ui.tiles->setTile(i, mTileCacheGetTile(m_tileCache.get(), i, 0));
119 }
120 }
121 for (int i = 1024; i < 1536; ++i) {
122 const uint16_t* data = mTileCacheGetTileIfDirty(m_tileCache.get(), &m_tileStatus[32 * i], i, 1);
123 if (data) {
124 m_ui.tiles->setTile(i, data);
125 } else if (force) {
126 m_ui.tiles->setTile(i, mTileCacheGetTile(m_tileCache.get(), i, 1));
127 }
128 }
129 } else {
130 m_ui.tiles->setTileCount(3072);
131 mTileCacheSetPalette(m_tileCache.get(), 0);
132 for (int i = 0; i < 2048; ++i) {
133 const uint16_t* data = mTileCacheGetTileIfDirty(m_tileCache.get(), &m_tileStatus[32 * i], i, m_paletteId);
134 if (data) {
135 m_ui.tiles->setTile(i, data);
136 } else if (force) {
137 m_ui.tiles->setTile(i, mTileCacheGetTile(m_tileCache.get(), i, m_paletteId));
138 }
139 }
140 for (int i = 2048; i < 3072; ++i) {
141 const uint16_t* data = mTileCacheGetTileIfDirty(m_tileCache.get(), &m_tileStatus[32 * i], i, m_paletteId + 16);
142 if (data) {
143 m_ui.tiles->setTile(i, data);
144 } else if (force) {
145 m_ui.tiles->setTile(i, mTileCacheGetTile(m_tileCache.get(), i, m_paletteId + 16));
146 }
147 }
148 }
149}
150#endif
151
152#ifdef M_CORE_GB
153void TileView::updateTilesGB(bool force) {
154 m_ui.tiles->setTileCount(1024);
155 mTileCacheSetPalette(m_tileCache.get(), 0);
156 for (int i = 0; i < 1024; ++i) {
157 const uint16_t* data = mTileCacheGetTileIfDirty(m_tileCache.get(), &m_tileStatus[16 * i], i, m_paletteId);
158 if (data) {
159 m_ui.tiles->setTile(i, data);
160 } else if (force) {
161 m_ui.tiles->setTile(i, mTileCacheGetTile(m_tileCache.get(), i, m_paletteId));
162 }
163 }
164}
165#endif
166
167void TileView::updatePalette(int palette) {
168 m_paletteId = palette;
169 m_ui.tile->setPalette(palette);
170 updateTiles(true);
171}
172
173void TileView::resizeEvent(QResizeEvent*) {
174 updateTiles(true);
175}
176
177void TileView::showEvent(QShowEvent*) {
178 updateTiles(true);
179}