all repos — mgba @ 1ac4a716cc6d0d5ec7ec3733116d28d45049b5fd

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_tileStatus{}
 23	, m_tileCache(controller->tileCache())
 24	, m_paletteId(0)
 25{
 26	m_ui.setupUi(this);
 27
 28	m_ui.preview->setDimensions(QSize(8, 8));
 29	m_updateTimer.setSingleShot(true);
 30	m_updateTimer.setInterval(1);
 31	connect(&m_updateTimer, SIGNAL(timeout()), this, SLOT(updateTiles()));
 32
 33	const QFont font = QFontDatabase::systemFont(QFontDatabase::FixedFont);
 34
 35	m_ui.tileId->setFont(font);
 36	m_ui.address->setFont(font);
 37
 38	connect(m_controller, SIGNAL(frameAvailable(const uint32_t*)), &m_updateTimer, SLOT(start()));
 39	connect(m_controller, SIGNAL(gameStopped(mCoreThread*)), this, SLOT(close()));
 40	connect(m_ui.tiles, SIGNAL(indexPressed(int)), this, SLOT(selectIndex(int)));
 41	connect(m_ui.paletteId, SIGNAL(valueChanged(int)), this, SLOT(updatePalette(int)));
 42	connect(m_ui.palette256, &QAbstractButton::toggled, [this]() {
 43		updateTiles(true);
 44	});
 45	connect(m_ui.magnification, static_cast<void (QSpinBox::*)(int)>(&QSpinBox::valueChanged), [this]() {
 46		updateTiles(true);
 47	});
 48}
 49
 50void TileView::selectIndex(int index) {
 51	const uint16_t* data;
 52	m_ui.tileId->setText(QString::number(index));
 53	if (m_ui.palette256->isChecked()) {
 54		m_ui.address->setText(tr("0x%0").arg(index * 64 | BASE_VRAM, 8, 16, QChar('0')));
 55		if (index < 1024) {
 56			data = mTileCacheGetTile(m_tileCache.get(), index, 0);
 57		} else {
 58			data = mTileCacheGetTile(m_tileCache.get(), index, 1);
 59		}
 60	} else {
 61		m_ui.address->setText(tr("0x%0").arg(index * 32 | BASE_VRAM, 8, 16, QChar('0')));
 62		if (index < 2048) {
 63			data = mTileCacheGetTile(m_tileCache.get(), index, m_paletteId);
 64		} else {
 65			data = mTileCacheGetTile(m_tileCache.get(), index, m_paletteId + 16);
 66		}
 67	}
 68	for (int i = 0; i < 64; ++i) {
 69		m_ui.preview->setColor(i, data[i]);
 70	}
 71	m_ui.preview->update();
 72}
 73
 74void TileView::updateTiles(bool force) {
 75	if (!m_controller->thread() || !m_controller->thread()->core) {
 76		return;
 77	}
 78
 79	switch (m_controller->platform()) {
 80#ifdef M_CORE_GBA
 81	case PLATFORM_GBA:
 82		updateTilesGBA(force);
 83		break;
 84#endif
 85#ifdef M_CORE_GB
 86	case PLATFORM_GB:
 87		updateTilesGB(force);
 88		break;
 89#endif
 90	default:
 91		return;
 92	}
 93}
 94
 95#ifdef M_CORE_GBA
 96void TileView::updateTilesGBA(bool force) {
 97	if (m_ui.palette256->isChecked()) {
 98		m_ui.tiles->setTileCount(1536);
 99		mTileCacheSetPalette(m_tileCache.get(), 1);
100		for (int i = 0; i < 1024; ++i) {
101			const uint16_t* data = mTileCacheGetTileIfDirty(m_tileCache.get(), &m_tileStatus[32 * i], i, 0);
102			if (data) {
103				m_ui.tiles->setTile(i, data);
104			} else if (force) {
105				m_ui.tiles->setTile(i, mTileCacheGetTile(m_tileCache.get(), i, 0));
106			}
107		}
108		for (int i = 1024; i < 1536; ++i) {
109			const uint16_t* data = mTileCacheGetTileIfDirty(m_tileCache.get(), &m_tileStatus[32 * i], i, 1);
110			if (data) {
111				m_ui.tiles->setTile(i, data);
112			} else if (force) {
113				m_ui.tiles->setTile(i, mTileCacheGetTile(m_tileCache.get(), i, 1));
114			}
115		}
116	} else {
117		m_ui.tiles->setTileCount(3072);
118		mTileCacheSetPalette(m_tileCache.get(), 0);
119		for (int i = 0; i < 2048; ++i) {
120			const uint16_t* data = mTileCacheGetTileIfDirty(m_tileCache.get(), &m_tileStatus[32 * i], i, m_paletteId);
121			if (data) {
122				m_ui.tiles->setTile(i, data);
123			} else if (force) {
124				m_ui.tiles->setTile(i, mTileCacheGetTile(m_tileCache.get(), i, m_paletteId));
125			}
126		}
127		for (int i = 2048; i < 3072; ++i) {
128			const uint16_t* data = mTileCacheGetTileIfDirty(m_tileCache.get(), &m_tileStatus[32 * i], i, m_paletteId + 16);
129			if (data) {
130				m_ui.tiles->setTile(i, data);
131			} else if (force) {
132				m_ui.tiles->setTile(i, mTileCacheGetTile(m_tileCache.get(), i, m_paletteId + 16));
133			}
134		}
135	}
136}
137#endif
138
139#ifdef M_CORE_GB
140void TileView::updateTilesGB(bool force) {
141	m_ui.tiles->setTileCount(1024);
142	mTileCacheSetPalette(m_tileCache.get(), 0);
143	for (int i = 0; i < 1024; ++i) {
144		const uint16_t* data = mTileCacheGetTileIfDirty(m_tileCache.get(), &m_tileStatus[16 * i], i, m_paletteId);
145		if (data) {
146			m_ui.tiles->setTile(i, data);
147		} else if (force) {
148			m_ui.tiles->setTile(i, mTileCacheGetTile(m_tileCache.get(), i, m_paletteId));
149		}
150	}
151}
152#endif
153
154void TileView::updatePalette(int palette) {
155	m_paletteId = palette;
156	updateTiles(true);
157}
158
159void TileView::resizeEvent(QResizeEvent*) {
160	updateTiles(true);
161}
162
163void TileView::showEvent(QShowEvent*) {
164	updateTiles(true);
165}