all repos — mgba @ e8fe5684f7c751b0963a55a9382eb9710da838fb

mGBA Game Boy Advance Emulator

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}