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 "CoreController.h"
9#include "GBAApp.h"
10
11#include <QFontDatabase>
12#include <QTimer>
13
14#ifdef M_CORE_GB
15#include <mgba/internal/gb/gb.h>
16#endif
17
18using namespace QGBA;
19
20TileView::TileView(std::shared_ptr<CoreController> controller, QWidget* parent)
21 : AssetView(controller, parent)
22 , m_controller(controller)
23{
24 m_ui.setupUi(this);
25 m_ui.tile->setController(controller);
26
27 connect(m_ui.tiles, &TilePainter::indexPressed, m_ui.tile, &AssetTile::selectIndex);
28 connect(m_ui.tiles, &TilePainter::needsRedraw, this, [this]() {
29 updateTiles(true);
30 });
31 connect(m_ui.paletteId, static_cast<void (QSpinBox::*)(int)>(&QSpinBox::valueChanged), this, &TileView::updatePalette);
32
33 switch (m_controller->platform()) {
34#ifdef M_CORE_GBA
35 case PLATFORM_GBA:
36 m_ui.tile->setBoundary(2048, 0, 2);
37 break;
38#endif
39#ifdef M_CORE_GB
40 case PLATFORM_GB:
41 m_ui.palette256->setEnabled(false);
42 m_ui.tile->setBoundary(1024, 0, 0);
43 break;
44#endif
45 default:
46 return;
47 }
48
49 connect(m_ui.palette256, &QAbstractButton::toggled, [this](bool selected) {
50 if (selected) {
51 m_ui.paletteId->setValue(0);
52 }
53 switch (m_controller->platform()) {
54#ifdef M_CORE_GBA
55 case PLATFORM_GBA:
56 m_ui.tile->setBoundary(2048 >> selected, selected, selected + 2);
57 break;
58#endif
59#ifdef M_CORE_GB
60 case PLATFORM_GB:
61 return;
62#endif
63 default:
64 break;
65 }
66 updateTiles(true);
67 });
68 connect(m_ui.magnification, static_cast<void (QSpinBox::*)(int)>(&QSpinBox::valueChanged), [this](int mag) {
69 if (!m_ui.tileFit->isChecked()) {
70 m_ui.tiles->setMinimumSize(mag * 8 * m_ui.tilesPerRow->value(), m_ui.tiles->minimumSize().height());
71 }
72 updateTiles(true);
73 });
74
75 connect(m_ui.tilesPerRow, static_cast<void (QSpinBox::*)(int)>(&QSpinBox::valueChanged), [this](int count) {
76 m_ui.tiles->setMinimumSize(m_ui.magnification->value() * 8 * count, m_ui.tiles->minimumSize().height());
77 updateTiles(true);
78 });
79
80 connect(m_ui.tileFit, &QAbstractButton::toggled, [this](bool selected) {
81 if (!selected) {
82 m_ui.tiles->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
83 m_ui.tiles->setMinimumSize(m_ui.magnification->value() * 8 * m_ui.tilesPerRow->value(), m_ui.tiles->minimumSize().height());
84 } else {
85 m_ui.tiles->setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::Fixed);
86 }
87 updateTiles(true);
88 });
89
90 connect(m_ui.exportButton, &QAbstractButton::clicked, this, &TileView::exportTiles);
91}
92
93#ifdef M_CORE_GBA
94void TileView::updateTilesGBA(bool force) {
95 if (m_ui.palette256->isChecked()) {
96 m_ui.tiles->setTileCount(1536);
97 mTileCache* cache = mTileCacheSetGetPointer(&m_cacheSet->tiles, 1);
98 for (int i = 0; i < 1024; ++i) {
99 const color_t* data = mTileCacheGetTileIfDirty(cache, &m_tileStatus[16 * i], i, 0);
100 if (data) {
101 m_ui.tiles->setTile(i, data);
102 } else if (force) {
103 m_ui.tiles->setTile(i, mTileCacheGetTile(cache, i, 0));
104 }
105 }
106 cache = mTileCacheSetGetPointer(&m_cacheSet->tiles, 3);
107 for (int i = 1024; i < 1536; ++i) {
108 const color_t* data = mTileCacheGetTileIfDirty(cache, &m_tileStatus[16 * i], i - 1024, 0);
109 if (data) {
110 m_ui.tiles->setTile(i, data);
111 } else if (force) {
112 m_ui.tiles->setTile(i, mTileCacheGetTile(cache, i - 1024, 0));
113 }
114 }
115 } else {
116 mTileCache* cache = mTileCacheSetGetPointer(&m_cacheSet->tiles, 0);
117 m_ui.tiles->setTileCount(3072);
118 for (int i = 0; i < 2048; ++i) {
119 const color_t* data = mTileCacheGetTileIfDirty(cache, &m_tileStatus[16 * i], i, m_paletteId);
120 if (data) {
121 m_ui.tiles->setTile(i, data);
122 } else if (force) {
123 m_ui.tiles->setTile(i, mTileCacheGetTile(cache, i, m_paletteId));
124 }
125 }
126 cache = mTileCacheSetGetPointer(&m_cacheSet->tiles, 2);
127 for (int i = 2048; i < 3072; ++i) {
128 const color_t* data = mTileCacheGetTileIfDirty(cache, &m_tileStatus[16 * i], i - 2048, m_paletteId);
129 if (data) {
130 m_ui.tiles->setTile(i, data);
131 } else if (force) {
132 m_ui.tiles->setTile(i, mTileCacheGetTile(cache, i - 2048, m_paletteId));
133 }
134 }
135 }
136}
137#endif
138
139#ifdef M_CORE_GB
140void TileView::updateTilesGB(bool force) {
141 const GB* gb = static_cast<const GB*>(m_controller->thread()->core->board);
142 int count = gb->model >= GB_MODEL_CGB ? 1024 : 512;
143 m_ui.tiles->setTileCount(count);
144 mTileCache* cache = mTileCacheSetGetPointer(&m_cacheSet->tiles, 0);
145 for (int i = 0; i < count; ++i) {
146 const color_t* data = mTileCacheGetTileIfDirty(cache, &m_tileStatus[8 * i], i, m_paletteId);
147 if (data) {
148 m_ui.tiles->setTile(i, data);
149 } else if (force) {
150 m_ui.tiles->setTile(i, mTileCacheGetTile(cache, i, m_paletteId));
151 }
152 }
153}
154#endif
155
156void TileView::updatePalette(int palette) {
157 m_paletteId = palette;
158 m_ui.tile->setPalette(palette);
159 updateTiles(true);
160}
161
162void TileView::exportTiles() {
163 QString filename = GBAApp::app()->getSaveFileName(this, tr("Export tiles"),
164 tr("Portable Network Graphics (*.png)"));
165 CoreController::Interrupter interrupter(m_controller);
166 updateTiles(false);
167 QPixmap pixmap(m_ui.tiles->backing());
168 pixmap.save(filename, "PNG");
169}