259 lines
7.7 KiB
C++
259 lines
7.7 KiB
C++
/* Copyright (c) 2013-2016 Jeffrey Pfau
|
|
*
|
|
* This Source Code Form is subject to the terms of the Mozilla Public
|
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
|
#include "TileView.h"
|
|
|
|
#include "CoreController.h"
|
|
#include "GBAApp.h"
|
|
|
|
#include <QAction>
|
|
#include <QClipboard>
|
|
#include <QTimer>
|
|
|
|
#ifdef M_CORE_GB
|
|
#include <mgba/internal/gb/gb.h>
|
|
#endif
|
|
|
|
using namespace QGBA;
|
|
|
|
TileView::TileView(std::shared_ptr<CoreController> controller, QWidget* parent)
|
|
: AssetView(controller, parent)
|
|
, m_controller(controller)
|
|
{
|
|
m_ui.setupUi(this);
|
|
m_ui.tile->setController(controller);
|
|
|
|
connect(m_ui.tiles, &TilePainter::indexPressed, this, [this](int index) {
|
|
if (m_ui.tilesObj->isChecked()) {
|
|
switch (m_controller->platform()) {
|
|
#ifdef M_CORE_GBA
|
|
case mPLATFORM_GBA:
|
|
index += 2048 >> m_ui.palette256->isChecked();
|
|
break;
|
|
#endif
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
m_ui.tile->selectIndex(index);
|
|
});
|
|
connect(m_ui.tiles, &TilePainter::needsRedraw, this, [this]() {
|
|
updateTiles(true);
|
|
});
|
|
connect(m_ui.tilesSelector, qOverload<QAbstractButton*>(&QButtonGroup::buttonClicked), this, [this]() {
|
|
updateTiles(true);
|
|
});
|
|
connect(m_ui.paletteId, static_cast<void (QSpinBox::*)(int)>(&QSpinBox::valueChanged), this, &TileView::updatePalette);
|
|
|
|
switch (m_controller->platform()) {
|
|
#ifdef M_CORE_GBA
|
|
case mPLATFORM_GBA:
|
|
m_ui.tile->setBoundary(2048, 0, 2);
|
|
m_ui.tile->setMaxTile(3072);
|
|
break;
|
|
#endif
|
|
#ifdef M_CORE_GB
|
|
case mPLATFORM_GB:
|
|
m_ui.tilesBg->setEnabled(false);
|
|
m_ui.tilesObj->setEnabled(false);
|
|
m_ui.tilesBoth->setEnabled(false);
|
|
m_ui.palette256->setEnabled(false);
|
|
m_ui.tile->setBoundary(1024, 0, 0);
|
|
m_ui.tile->setMaxTile(512);
|
|
break;
|
|
#endif
|
|
default:
|
|
return;
|
|
}
|
|
|
|
connect(m_ui.palette256, &QAbstractButton::toggled, [this](bool selected) {
|
|
if (selected) {
|
|
m_ui.paletteId->setValue(0);
|
|
}
|
|
switch (m_controller->platform()) {
|
|
#ifdef M_CORE_GBA
|
|
case mPLATFORM_GBA:
|
|
m_ui.tile->setBoundary(2048 >> selected, selected, selected + 2);
|
|
m_ui.tile->setMaxTile(3072 >> selected);
|
|
break;
|
|
#endif
|
|
#ifdef M_CORE_GB
|
|
case mPLATFORM_GB:
|
|
return;
|
|
#endif
|
|
default:
|
|
break;
|
|
}
|
|
updateTiles(true);
|
|
});
|
|
connect(m_ui.magnification, static_cast<void (QSpinBox::*)(int)>(&QSpinBox::valueChanged), [this](int mag) {
|
|
if (!m_ui.tileFit->isChecked()) {
|
|
m_ui.tiles->setMinimumSize(mag * 8 * m_ui.tilesPerRow->value(), m_ui.tiles->minimumSize().height());
|
|
}
|
|
updateTiles(true);
|
|
});
|
|
|
|
connect(m_ui.tilesPerRow, static_cast<void (QSpinBox::*)(int)>(&QSpinBox::valueChanged), [this](int count) {
|
|
m_ui.tiles->setMinimumSize(m_ui.magnification->value() * 8 * count, m_ui.tiles->minimumSize().height());
|
|
updateTiles(true);
|
|
});
|
|
|
|
connect(m_ui.tileFit, &QAbstractButton::toggled, [this](bool selected) {
|
|
if (!selected) {
|
|
m_ui.tiles->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
|
|
m_ui.tiles->setMinimumSize(m_ui.magnification->value() * 8 * m_ui.tilesPerRow->value(), m_ui.tiles->minimumSize().height());
|
|
} else {
|
|
m_ui.tiles->setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::Fixed);
|
|
}
|
|
updateTiles(true);
|
|
});
|
|
|
|
connect(m_ui.exportAll, &QAbstractButton::clicked, this, &TileView::exportTiles);
|
|
connect(m_ui.exportOne, &QAbstractButton::clicked, this, &TileView::exportTile);
|
|
connect(m_ui.copyAll, &QAbstractButton::clicked, this, &TileView::copyTiles);
|
|
connect(m_ui.copyOne, &QAbstractButton::clicked, this, &TileView::copyTile);
|
|
|
|
QAction* exportAll = new QAction(this);
|
|
exportAll->setShortcut(QKeySequence::Save);
|
|
connect(exportAll, &QAction::triggered, this, &TileView::exportTiles);
|
|
addAction(exportAll);
|
|
|
|
QAction* copyOne = new QAction(this);
|
|
copyOne->setShortcut(QKeySequence::Copy);
|
|
connect(copyOne, &QAction::triggered, this, &TileView::copyTile);
|
|
addAction(copyOne);
|
|
}
|
|
|
|
#ifdef M_CORE_GBA
|
|
void TileView::updateTilesGBA(bool force) {
|
|
if (m_ui.palette256->isChecked()) {
|
|
if (m_ui.tilesBg->isChecked()) {
|
|
m_ui.tiles->setTileCount(1024);
|
|
} else if (m_ui.tilesObj->isChecked()) {
|
|
m_ui.tiles->setTileCount(512);
|
|
} else {
|
|
m_ui.tiles->setTileCount(1536);
|
|
}
|
|
mTileCache* cache;
|
|
int objOffset = 1024;
|
|
if (!m_ui.tilesObj->isChecked()) {
|
|
objOffset = 0;
|
|
cache = mTileCacheSetGetPointer(&m_cacheSet->tiles, 1);
|
|
for (int i = 0; i < 1024; ++i) {
|
|
const mColor* data = mTileCacheGetTileIfDirty(cache, &m_tileStatus[16 * i], i, 0);
|
|
if (data) {
|
|
m_ui.tiles->setTile(i, data);
|
|
} else if (force) {
|
|
m_ui.tiles->setTile(i, mTileCacheGetTile(cache, i, 0));
|
|
}
|
|
}
|
|
}
|
|
if (!m_ui.tilesBg->isChecked()) {
|
|
cache = mTileCacheSetGetPointer(&m_cacheSet->tiles, 3);
|
|
for (int i = 1024; i < 1536; ++i) {
|
|
const mColor* data = mTileCacheGetTileIfDirty(cache, &m_tileStatus[16 * i], i - 1024, 0);
|
|
if (data) {
|
|
m_ui.tiles->setTile(i - objOffset, data);
|
|
} else if (force) {
|
|
m_ui.tiles->setTile(i - objOffset, mTileCacheGetTile(cache, i - 1024, 0));
|
|
}
|
|
}
|
|
}
|
|
} else {
|
|
if (m_ui.tilesBg->isChecked()) {
|
|
m_ui.tiles->setTileCount(2048);
|
|
} else if (m_ui.tilesObj->isChecked()) {
|
|
m_ui.tiles->setTileCount(1024);
|
|
} else {
|
|
m_ui.tiles->setTileCount(3072);
|
|
}
|
|
mTileCache* cache;
|
|
int objOffset = 2048;
|
|
if (!m_ui.tilesObj->isChecked()) {
|
|
objOffset = 0;
|
|
cache = mTileCacheSetGetPointer(&m_cacheSet->tiles, 0);
|
|
for (int i = 0; i < 2048; ++i) {
|
|
const mColor* data = mTileCacheGetTileIfDirty(cache, &m_tileStatus[16 * i], i, m_paletteId);
|
|
if (data) {
|
|
m_ui.tiles->setTile(i, data);
|
|
} else if (force) {
|
|
m_ui.tiles->setTile(i, mTileCacheGetTile(cache, i, m_paletteId));
|
|
}
|
|
}
|
|
}
|
|
if (!m_ui.tilesBg->isChecked()) {
|
|
cache = mTileCacheSetGetPointer(&m_cacheSet->tiles, 2);
|
|
for (int i = 2048; i < 3072; ++i) {
|
|
const mColor* data = mTileCacheGetTileIfDirty(cache, &m_tileStatus[16 * i], i - 2048, m_paletteId);
|
|
if (data) {
|
|
m_ui.tiles->setTile(i - objOffset, data);
|
|
} else if (force) {
|
|
m_ui.tiles->setTile(i - objOffset, mTileCacheGetTile(cache, i - 2048, m_paletteId));
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
#endif
|
|
|
|
#ifdef M_CORE_GB
|
|
void TileView::updateTilesGB(bool force) {
|
|
const GB* gb = static_cast<const GB*>(m_controller->thread()->core->board);
|
|
int count = gb->model >= GB_MODEL_CGB ? 1024 : 512;
|
|
m_ui.tiles->setTileCount(count);
|
|
mTileCache* cache = mTileCacheSetGetPointer(&m_cacheSet->tiles, 0);
|
|
for (int i = 0; i < count; ++i) {
|
|
const mColor* data = mTileCacheGetTileIfDirty(cache, &m_tileStatus[8 * i], i, m_paletteId);
|
|
if (data) {
|
|
m_ui.tiles->setTile(i, data);
|
|
} else if (force) {
|
|
m_ui.tiles->setTile(i, mTileCacheGetTile(cache, i, m_paletteId));
|
|
}
|
|
}
|
|
}
|
|
#endif
|
|
|
|
void TileView::updatePalette(int palette) {
|
|
m_paletteId = palette;
|
|
m_ui.tile->setPalette(palette);
|
|
updateTiles(true);
|
|
}
|
|
|
|
void TileView::exportTiles() {
|
|
QString filename = GBAApp::app()->getSaveFileName(this, tr("Export tiles"),
|
|
tr("Portable Network Graphics (*.png)"));
|
|
if (filename.isNull()) {
|
|
return;
|
|
}
|
|
CoreController::Interrupter interrupter(m_controller);
|
|
updateTiles(false);
|
|
QPixmap pixmap(m_ui.tiles->backing());
|
|
pixmap.save(filename, "PNG");
|
|
}
|
|
|
|
void TileView::exportTile() {
|
|
QString filename = GBAApp::app()->getSaveFileName(this, tr("Export tile"),
|
|
tr("Portable Network Graphics (*.png)"));
|
|
if (filename.isNull()) {
|
|
return;
|
|
}
|
|
CoreController::Interrupter interrupter(m_controller);
|
|
updateTiles(false);
|
|
QImage image(m_ui.tile->activeTile());
|
|
image.save(filename, "PNG");
|
|
}
|
|
|
|
void TileView::copyTiles() {
|
|
CoreController::Interrupter interrupter(m_controller);
|
|
updateTiles(false);
|
|
GBAApp::app()->clipboard()->setPixmap(m_ui.tiles->backing());
|
|
}
|
|
|
|
void TileView::copyTile() {
|
|
CoreController::Interrupter interrupter(m_controller);
|
|
updateTiles(false);
|
|
GBAApp::app()->clipboard()->setImage(m_ui.tile->activeTile());
|
|
}
|