all repos — mgba @ 02419521335e8f58add9446f2a8fa6016d4f79bc

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 "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_paletteId(0)
 23{
 24	m_ui.setupUi(this);
 25	GBAVideoTileCacheInit(&m_tileCache);
 26
 27	m_ui.preview->setDimensions(QSize(8, 8));
 28	m_updateTimer.setSingleShot(true);
 29	m_updateTimer.setInterval(1);
 30	connect(&m_updateTimer, SIGNAL(timeout()), this, SLOT(updateTiles()));
 31
 32	const QFont font = QFontDatabase::systemFont(QFontDatabase::FixedFont);
 33
 34	m_ui.tileId->setFont(font);
 35	m_ui.address->setFont(font);
 36
 37	connect(m_controller, SIGNAL(frameAvailable(const uint32_t*)), &m_updateTimer, SLOT(start()));
 38	connect(m_controller, SIGNAL(gameStopped(mCoreThread*)), this, SLOT(close()));
 39	connect(m_ui.tiles, SIGNAL(indexPressed(int)), this, SLOT(selectIndex(int)));
 40	connect(m_ui.paletteId, SIGNAL(valueChanged(int)), this, SLOT(updatePalette(int)));
 41	connect(m_ui.palette256, &QAbstractButton::toggled, [this]() {
 42		updateTiles(true);
 43	});
 44	connect(m_ui.magnification, static_cast<void (QSpinBox::*)(int)>(&QSpinBox::valueChanged), [this]() {
 45		updateTiles(true);
 46	});
 47}
 48
 49TileView::~TileView() {
 50	if (m_controller->isLoaded() && m_controller->thread() && m_controller->thread()->core) {
 51		GBA* gba = static_cast<GBA*>(m_controller->thread()->core->board);
 52		gba->video.renderer->cache = nullptr;
 53	}
 54
 55	GBAVideoTileCacheDeinit(&m_tileCache);
 56}
 57
 58void TileView::selectIndex(int index) {
 59	const uint16_t* data;
 60	m_ui.tileId->setText(QString::number(index));
 61	if (m_ui.palette256->isChecked()) {
 62		m_ui.address->setText(tr("0x%0").arg(index * 64 | BASE_VRAM, 8, 16, QChar('0')));
 63		if (index < 1024) {
 64			data = GBAVideoTileCacheGetTile256(&m_tileCache, index, 0);
 65		} else {
 66			data = GBAVideoTileCacheGetTile256(&m_tileCache, index, 1);
 67		}
 68	} else {
 69		m_ui.address->setText(tr("0x%0").arg(index * 32 | BASE_VRAM, 8, 16, QChar('0')));
 70		if (index < 2048) {
 71			data = GBAVideoTileCacheGetTile16(&m_tileCache, index, m_paletteId);
 72		} else {
 73			data = GBAVideoTileCacheGetTile16(&m_tileCache, index, m_paletteId + 16);
 74		}
 75	}
 76	for (int i = 0; i < 64; ++i) {
 77		m_ui.preview->setColor(i, data[i]);
 78	}
 79	m_ui.preview->update();
 80}
 81
 82void TileView::updateTiles(bool force) {
 83	if (!m_controller->thread() || !m_controller->thread()->core) {
 84		return;
 85	}
 86
 87	GBA* gba = static_cast<GBA*>(m_controller->thread()->core->board);
 88	GBAVideoTileCacheAssociate(&m_tileCache, &gba->video);
 89
 90	if (m_ui.palette256->isChecked()) {
 91		m_ui.tiles->setTileCount(1536);
 92		for (int i = 0; i < 1024; ++i) {
 93			const uint16_t* data = GBAVideoTileCacheGetTile256IfDirty(&m_tileCache, i, 0);
 94			if (data) {
 95				m_ui.tiles->setTile(i, data);
 96			} else if (force) {
 97				m_ui.tiles->setTile(i, GBAVideoTileCacheGetTile256(&m_tileCache, i, 0));
 98			}
 99		}
100		for (int i = 1024; i < 1536; ++i) {
101			const uint16_t* data = GBAVideoTileCacheGetTile256IfDirty(&m_tileCache, i, 1);
102			if (data) {
103				m_ui.tiles->setTile(i, data);
104			} else if (force) {
105				m_ui.tiles->setTile(i, GBAVideoTileCacheGetTile256(&m_tileCache, i, 1));
106			}
107		}
108	} else {
109		m_ui.tiles->setTileCount(3072);
110		for (int i = 0; i < 2048; ++i) {
111			const uint16_t* data = GBAVideoTileCacheGetTile16IfDirty(&m_tileCache, i, m_paletteId);
112			if (data) {
113				m_ui.tiles->setTile(i, data);
114			} else if (force) {
115				m_ui.tiles->setTile(i, GBAVideoTileCacheGetTile16(&m_tileCache, i, m_paletteId));
116			}
117		}
118		for (int i = 2048; i < 3072; ++i) {
119			const uint16_t* data = GBAVideoTileCacheGetTile16IfDirty(&m_tileCache, i, m_paletteId + 16);
120			if (data) {
121				m_ui.tiles->setTile(i, data);
122			} else if (force) {
123				m_ui.tiles->setTile(i, GBAVideoTileCacheGetTile16(&m_tileCache, i, m_paletteId + 16));
124			}
125		}
126	}
127}
128
129void TileView::updatePalette(int palette) {
130	m_paletteId = palette;
131	updateTiles(true);
132}
133
134void TileView::resizeEvent(QResizeEvent*) {
135	updateTiles(true);
136}
137
138void TileView::showEvent(QShowEvent*) {
139	updateTiles(true);
140}