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
138 GameController::Interrupter interrupter(m_controller);
139 QFileDialog* dialog = GBAApp::app()->getSaveFileDialog(this, tr("Export palette"),
140 tr("Windows PAL (*.pal);;Adobe Color Table (*.act)"));
141 if (!dialog->exec()) {
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 return;
149 }
150 QString filter = dialog->selectedNameFilter();
151 if (filter.contains("*.pal")) {
152 exportPaletteRIFF(vf, length, &static_cast<GBA*>(m_controller->thread()->core->board)->video.palette[start]);
153 } else if (filter.contains("*.act")) {
154 exportPaletteACT(vf, length, &static_cast<GBA*>(m_controller->thread()->core->board)->video.palette[start]);
155 }
156 vf->close(vf);
157}