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