/* 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 #include #include #include #ifdef M_CORE_GB #include #endif using namespace QGBA; TileView::TileView(std::shared_ptr controller, QWidget* parent) : AssetView(controller, parent) , m_controller(controller) { m_ui.setupUi(this); m_ui.tile->setController(controller); connect(m_ui.tiles, &TilePainter::indexPressed, m_ui.tile, &AssetTile::selectIndex); connect(m_ui.tiles, &TilePainter::needsRedraw, this, [this]() { updateTiles(true); }); connect(m_ui.paletteId, static_cast(&QSpinBox::valueChanged), this, &TileView::updatePalette); switch (m_controller->platform()) { #ifdef M_CORE_GBA case PLATFORM_GBA: m_ui.tile->setBoundary(2048, 0, 2); break; #endif #ifdef M_CORE_GB case PLATFORM_GB: m_ui.palette256->setEnabled(false); m_ui.tile->setBoundary(1024, 0, 0); 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 PLATFORM_GBA: m_ui.tile->setBoundary(2048 >> selected, selected, selected + 2); break; #endif #ifdef M_CORE_GB case PLATFORM_GB: return; #endif default: break; } updateTiles(true); }); connect(m_ui.magnification, static_cast(&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(&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()) { m_ui.tiles->setTileCount(1536); mTileCache* cache = mTileCacheSetGetPointer(&m_cacheSet->tiles, 1); for (int i = 0; i < 1024; ++i) { const color_t* 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)); } } cache = mTileCacheSetGetPointer(&m_cacheSet->tiles, 3); for (int i = 1024; i < 1536; ++i) { const color_t* data = mTileCacheGetTileIfDirty(cache, &m_tileStatus[16 * i], i - 1024, 0); if (data) { m_ui.tiles->setTile(i, data); } else if (force) { m_ui.tiles->setTile(i, mTileCacheGetTile(cache, i - 1024, 0)); } } } else { mTileCache* cache = mTileCacheSetGetPointer(&m_cacheSet->tiles, 0); m_ui.tiles->setTileCount(3072); for (int i = 0; i < 2048; ++i) { const color_t* 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)); } } cache = mTileCacheSetGetPointer(&m_cacheSet->tiles, 2); for (int i = 2048; i < 3072; ++i) { const color_t* data = mTileCacheGetTileIfDirty(cache, &m_tileStatus[16 * i], i - 2048, m_paletteId); if (data) { m_ui.tiles->setTile(i, data); } else if (force) { m_ui.tiles->setTile(i, mTileCacheGetTile(cache, i - 2048, m_paletteId)); } } } } #endif #ifdef M_CORE_GB void TileView::updateTilesGB(bool force) { const GB* gb = static_cast(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 color_t* 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); QPixmap pixmap(); 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()); }