all repos — mgba @ 4cb243f15c011264e3b4e84100f6e4a050c4a623

mGBA Game Boy Advance Emulator

src/platform/qt/PaletteView.cpp (view raw)

  1/* Copyright (c) 2013-2015 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 "PaletteView.h"
  7
  8#include "GBAApp.h"
  9#include "LogController.h"
 10#include "VFileDevice.h"
 11
 12#include <QFileDialog>
 13#include <QFontDatabase>
 14
 15extern "C" {
 16#include "core/core.h"
 17#include "util/export.h"
 18#ifdef M_CORE_GA
 19#include "gba/gba.h"
 20#endif
 21#ifdef M_CORE_GB
 22#include "gb/gb.h"
 23#endif
 24#include "util/vfs.h"
 25}
 26
 27using namespace QGBA;
 28
 29PaletteView::PaletteView(GameController* controller, QWidget* parent)
 30	: QWidget(parent)
 31	, m_controller(controller)
 32{
 33	m_ui.setupUi(this);
 34
 35	connect(m_controller, SIGNAL(frameAvailable(const uint32_t*)), this, SLOT(updatePalette()));
 36	m_ui.bgGrid->setDimensions(QSize(16, 16));
 37	m_ui.objGrid->setDimensions(QSize(16, 16));
 38	int count = 256;
 39#ifdef M_CORE_GB
 40	if (controller->platform() == PLATFORM_GB) {
 41		m_ui.bgGrid->setDimensions(QSize(4, 8));
 42		m_ui.objGrid->setDimensions(QSize(4, 8));
 43		m_ui.bgGrid->setSize(24);
 44		m_ui.objGrid->setSize(24);
 45		count = 32;
 46	}
 47#endif
 48	m_ui.selected->setSize(64);
 49	m_ui.selected->setDimensions(QSize(1, 1));
 50	updatePalette();
 51
 52	const QFont font = QFontDatabase::systemFont(QFontDatabase::FixedFont);
 53
 54	m_ui.hexcode->setFont(font);
 55	m_ui.value->setFont(font);
 56	m_ui.index->setFont(font);
 57	m_ui.r->setFont(font);
 58	m_ui.g->setFont(font);
 59	m_ui.b->setFont(font);
 60
 61	connect(m_ui.bgGrid, SIGNAL(indexPressed(int)), this, SLOT(selectIndex(int)));
 62	connect(m_ui.objGrid, &Swatch::indexPressed, [this, count] (int index) { selectIndex(index + count); });
 63	connect(m_ui.exportBG, &QAbstractButton::clicked, [this, count] () { exportPalette(0, count); });
 64	connect(m_ui.exportOBJ, &QAbstractButton::clicked, [this, count] () { exportPalette(count, count); });
 65
 66	connect(controller, SIGNAL(gameStopped(mCoreThread*)), this, SLOT(close()));
 67}
 68
 69void PaletteView::updatePalette() {
 70	if (!m_controller->thread() || !m_controller->thread()->core) {
 71		return;
 72	}
 73	const uint16_t* palette;
 74	size_t count;
 75	switch (m_controller->platform()) {
 76#ifdef M_CORE_GBA
 77	case PLATFORM_GBA:
 78		palette = static_cast<GBA*>(m_controller->thread()->core->board)->video.palette;
 79		count = 256;
 80		break;
 81#endif
 82#ifdef M_CORE_GB
 83	case PLATFORM_GB:
 84		palette = static_cast<GB*>(m_controller->thread()->core->board)->video.palette;
 85		count = 32;
 86		break;
 87#endif
 88	default:
 89		return;
 90	}
 91	for (int i = 0; i < count; ++i) {
 92		m_ui.bgGrid->setColor(i, palette[i]);
 93		m_ui.objGrid->setColor(i, palette[i + count]);
 94	}
 95	m_ui.bgGrid->update();
 96	m_ui.objGrid->update();
 97}
 98
 99void PaletteView::selectIndex(int index) {
100	const uint16_t* palette;
101	switch (m_controller->platform()) {
102#ifdef M_CORE_GBA
103	case PLATFORM_GBA:
104		palette = static_cast<GBA*>(m_controller->thread()->core->board)->video.palette;
105		break;
106#endif
107#ifdef M_CORE_GB
108	case PLATFORM_GB:
109		palette = static_cast<GB*>(m_controller->thread()->core->board)->video.palette;
110		break;
111#endif
112	default:
113		return;
114	}
115	uint16_t color = palette[index];
116	m_ui.selected->setColor(0, color);
117	uint32_t r = M_R5(color);
118	uint32_t g = M_G5(color);
119	uint32_t b = M_B5(color);
120	uint32_t hexcode = (r << 19) | (g << 11) | (b << 3);
121	hexcode |= (hexcode >> 5) & 0x070707;
122	m_ui.hexcode->setText(tr("#%0").arg(hexcode, 6, 16, QChar('0')));
123	m_ui.value->setText(tr("0x%0").arg(color, 4, 16, QChar('0')));
124	m_ui.index->setText(tr("%0").arg(index, 3, 10, QChar('0')));
125	m_ui.r->setText(tr("0x%0 (%1)").arg(r, 2, 16, QChar('0')).arg(r, 2, 10, QChar('0')));
126	m_ui.g->setText(tr("0x%0 (%1)").arg(g, 2, 16, QChar('0')).arg(g, 2, 10, QChar('0')));
127	m_ui.b->setText(tr("0x%0 (%1)").arg(b, 2, 16, QChar('0')).arg(b, 2, 10, QChar('0')));
128}
129
130void PaletteView::exportPalette(int start, int length) {
131	if (start >= 512) {
132		return;
133	}
134	if (start + length > 512) {
135		length = 512 - start;
136	}
137	m_controller->threadInterrupt();
138	QFileDialog* dialog = GBAApp::app()->getSaveFileDialog(this, tr("Export palette"),
139	                                                       tr("Windows PAL (*.pal);;Adobe Color Table (*.act)"));
140	if (!dialog->exec()) {
141		m_controller->threadContinue();
142		return;
143	}
144	QString filename = dialog->selectedFiles()[0];
145	VFile* vf = VFileDevice::open(filename, O_WRONLY | O_CREAT | O_TRUNC);
146	if (!vf) {
147		LOG(QT, ERROR) << tr("Failed to open output palette file: %1").arg(filename);
148		m_controller->threadContinue();
149		return;
150	}
151	QString filter = dialog->selectedNameFilter();
152	if (filter.contains("*.pal")) {
153		exportPaletteRIFF(vf, length, &static_cast<GBA*>(m_controller->thread()->core->board)->video.palette[start]);
154	} else if (filter.contains("*.act")) {
155		exportPaletteACT(vf, length, &static_cast<GBA*>(m_controller->thread()->core->board)->video.palette[start]);
156	}
157	vf->close(vf);
158	m_controller->threadContinue();
159}