all repos — mgba @ 78e4083a562a1ce34a29dee8ecdb315401c9fb1a

mGBA Game Boy Advance Emulator

src/platform/qt/AssetView.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 "AssetView.h"
 7
 8#include <QTimer>
 9
10#include <mgba/core/tile-cache.h>
11
12using namespace QGBA;
13
14AssetView::AssetView(GameController* controller, QWidget* parent)
15	: QWidget(parent)
16	, m_controller(controller)
17	, m_tileCache(controller->tileCache())
18{
19	m_updateTimer.setSingleShot(true);
20	m_updateTimer.setInterval(1);
21	connect(&m_updateTimer, SIGNAL(timeout()), this, SLOT(updateTiles()));
22
23	connect(m_controller, SIGNAL(frameAvailable(const uint32_t*)), &m_updateTimer, SLOT(start()));
24	connect(m_controller, SIGNAL(gameStopped(mCoreThread*)), this, SLOT(close()));
25	connect(m_controller, SIGNAL(gameStopped(mCoreThread*)), &m_updateTimer, SLOT(stop()));
26}
27
28void AssetView::updateTiles(bool force) {
29	if (!m_controller->isLoaded()) {
30		return;
31	}
32
33	switch (m_controller->platform()) {
34#ifdef M_CORE_GBA
35	case PLATFORM_GBA:
36		updateTilesGBA(force);
37		break;
38#endif
39#ifdef M_CORE_GB
40	case PLATFORM_GB:
41		updateTilesGB(force);
42		break;
43#endif
44	default:
45		return;
46	}
47}
48
49void AssetView::resizeEvent(QResizeEvent*) {
50	updateTiles(true);
51}
52
53void AssetView::showEvent(QShowEvent*) {
54	updateTiles(true);
55}
56
57void AssetView::compositeTile(unsigned tileId, void* buffer, size_t stride, size_t x, size_t y, int depth) {
58	const uint8_t* tile = mTileCacheGetRawTile(m_tileCache.get(), tileId);
59	uint8_t* pixels = static_cast<uint8_t*>(buffer);
60	size_t base = stride * y + x;
61	switch (depth) {
62	case 2:
63		for (size_t i = 0; i < 8; ++i) {
64			uint8_t tileDataLower = tile[i * 2];
65			uint8_t tileDataUpper = tile[i * 2 + 1];
66			uint8_t pixel;
67			pixel = ((tileDataUpper & 128) >> 6) | ((tileDataLower & 128) >> 7);
68			pixels[base + i * stride] = pixel;
69			pixel = ((tileDataUpper & 64) >> 5) | ((tileDataLower & 64) >> 6);
70			pixels[base + i * stride + 1] = pixel;
71			pixel = ((tileDataUpper & 32) >> 4) | ((tileDataLower & 32) >> 5);
72			pixels[base + i * stride + 2] = pixel;
73			pixel = ((tileDataUpper & 16) >> 3) | ((tileDataLower & 16) >> 4);
74			pixels[base + i * stride + 3] = pixel;
75			pixel = ((tileDataUpper & 8) >> 2) | ((tileDataLower & 8) >> 3);
76			pixels[base + i * stride + 4] = pixel;
77			pixel = ((tileDataUpper & 4) >> 1) | ((tileDataLower & 4) >> 2);
78			pixels[base + i * stride + 5] = pixel;
79			pixel = (tileDataUpper & 2) | ((tileDataLower & 2) >> 1);
80			pixels[base + i * stride + 6] = pixel;
81			pixel = ((tileDataUpper & 1) << 1) | (tileDataLower & 1);
82			pixels[base + i * stride + 7] = pixel;
83		}
84		break;
85	case 4:
86		for (size_t j = 0; j < 8; ++j) {
87			for (size_t i = 0; i < 4; ++i) {
88				pixels[base + j * stride + i * 2] =  tile[j * 4 + i] & 0xF;
89				pixels[base + j * stride + i * 2 + 1] =  tile[j * 4 + i] >> 4;
90			}
91		}
92		break;
93	case 8:
94		for (size_t i = 0; i < 8; ++i) {
95			memcpy(&pixels[base + i * stride], &tile[i * 8], 8);
96		}
97		break;
98	}
99}