all repos — mgba @ 2f0501d3c476e234859d2c6063636bb03a92bea3

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	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}