all repos — mgba @ 40c3fc63ccad3ab59b6b37399cd6fe8ea1de3f3e

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