Add support for saving animated icons

Add support for exporting animated DSi icons as GIF using the
header-only gif.h library.
This commit is contained in:
Rayyan Ansari
2023-11-23 18:48:05 +00:00
parent 544fefa27f
commit 679c37ddce
6 changed files with 942 additions and 29 deletions

View File

@ -21,6 +21,8 @@
#include <QFileDialog>
#include "gif-h/gif.h"
#include "NDS.h"
#include "NDSCart.h"
#include "Platform.h"
@ -45,23 +47,24 @@ ROMInfoDialog::ROMInfoDialog(QWidget* parent) : QDialog(parent), ui(new Ui::ROMI
const NDSBanner* banner = NDS::NDSCartSlot->GetCart()->Banner();
const NDSHeader& header = NDS::NDSCartSlot->GetCart()->GetHeader();
u32 iconData[32 * 32];
ROMManager::ROMIcon(banner->Icon, banner->Palette, iconData);
iconImage = QImage(reinterpret_cast<unsigned char*>(iconData), 32, 32, QImage::Format_ARGB32).copy();
iconImage = QImage(reinterpret_cast<u8*>(iconData), 32, 32, QImage::Format_RGBA8888).copy();
ui->iconImage->setPixmap(QPixmap::fromImage(iconImage));
if (banner->Version == 0x103)
{
u32 animatedIconData[32 * 32 * 64] = {0};
ui->saveAnimatedIconButton->setEnabled(true);
ROMManager::AnimatedROMIcon(banner->DSiIcon, banner->DSiPalette, banner->DSiSequence, animatedIconData, animatedSequence);
for (int i = 0; i < 64; i++)
for (u32* image: animatedIconData)
{
if (animatedIconData[32 * 32 * i] == 0)
if (!image)
break;
animatedIconImages.push_back(QPixmap::fromImage(QImage(reinterpret_cast<unsigned char*>(&animatedIconData[32 * 32 * i]), 32, 32, QImage::Format_ARGB32).copy()));
animatedIconImages.push_back(QPixmap::fromImage(QImage(reinterpret_cast<u8*>(image), 32, 32, QImage::Format_RGBA8888).copy()));
}
iconTimeline = new QTimeLine(animatedSequence.size() / 60 * 1000, this);
iconTimeline->setFrameRange(0, animatedSequence.size() - 1);
iconTimeline->setLoopCount(0);
@ -139,6 +142,30 @@ void ROMInfoDialog::on_saveIconButton_clicked()
iconImage.save(filename, "PNG");
}
void ROMInfoDialog::on_saveAnimatedIconButton_clicked()
{
QString filename = QFileDialog::getSaveFileName(this,
"Save Animated Icon",
QString::fromStdString(Config::LastROMFolder),
"GIF Images (*.gif)");
if (filename.isEmpty())
return;
GifWriter writer;
// The GIF format only supports delays of 0.01 seconds, so 0.0166... (60fps)
// is rounded up to 0.02 (50fps)
GifBegin(&writer, filename.toStdString().c_str(), 32, 32, 2);
for (int i: animatedSequence)
{
if (animatedIconData[i] == 0)
break;
GifWriteFrame(&writer, reinterpret_cast<u8*>(animatedIconData[i]), 32, 32, 2);
}
GifEnd(&writer);
}
void ROMInfoDialog::iconSetFrame(int frame)
{
ui->dsiIconImage->setPixmap(animatedIconImages[animatedSequence[frame]]);