From f3bd61a5d9512451a8a19886d1bb25ee769c3472 Mon Sep 17 00:00:00 2001
From: giroletm <112472361+giroletm@users.noreply.github.com>
Date: Sun, 2 Jul 2023 13:57:06 +0200
Subject: [PATCH] Legacy PVR & Sprite packing
- Legacy PVR files can now be saved
- Sprite packing no longer leaves a ton of empty space
---
.gitignore | 397 ++++++++++++++++++++
ABStudio/FileFormats/PVR/PVRFile.cs | 162 +++++++-
ABStudio/FileFormats/ZSTREAM/ZSTREAMFile.cs | 2 +-
ABStudio/Forms/SpritesheetEditor.cs | 56 ++-
ABStudio/Libs/StbRectPackSharp/Packer.cs | 2 +-
LICENSE | 2 +-
6 files changed, 601 insertions(+), 20 deletions(-)
create mode 100644 .gitignore
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..1be4e55
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,397 @@
+## Ignore Visual Studio temporary files, build results, and
+## files generated by popular Visual Studio add-ons.
+##
+## Get latest from https://github.com/github/gitignore/blob/main/VisualStudio.gitignore
+
+# User-specific files
+*.rsuser
+*.suo
+*.userosscache
+*.sln.docstates
+
+# User-specific files (MonoDevelop/Xamarin Studio)
+*.userprefs
+
+# Mono auto generated files
+mono_crash.*
+
+# Build results
+[Dd]ebug/
+[Dd]ebugPublic/
+[Rr]elease/
+[Rr]eleases/
+x64/
+x86/
+[Ww][Ii][Nn]32/
+[Aa][Rr][Mm]/
+[Aa][Rr][Mm]64/
+bld/
+[Bb]in/
+[Oo]bj/
+[Ll]og/
+[Ll]ogs/
+
+# Visual Studio 2015/2017 cache/options directory
+.vs/
+# Uncomment if you have tasks that create the project's static files in wwwroot
+#wwwroot/
+
+# Visual Studio 2017 auto generated files
+Generated\ Files/
+
+# MSTest test Results
+[Tt]est[Rr]esult*/
+[Bb]uild[Ll]og.*
+
+# NUnit
+*.VisualState.xml
+TestResult.xml
+nunit-*.xml
+
+# Build Results of an ATL Project
+[Dd]ebugPS/
+[Rr]eleasePS/
+dlldata.c
+
+# Benchmark Results
+BenchmarkDotNet.Artifacts/
+
+# .NET Core
+project.lock.json
+project.fragment.lock.json
+artifacts/
+
+# ASP.NET Scaffolding
+ScaffoldingReadMe.txt
+
+# StyleCop
+StyleCopReport.xml
+
+# Files built by Visual Studio
+*_i.c
+*_p.c
+*_h.h
+*.ilk
+*.meta
+*.obj
+*.iobj
+*.pch
+*.pdb
+*.ipdb
+*.pgc
+*.pgd
+*.rsp
+*.sbr
+*.tlb
+*.tli
+*.tlh
+*.tmp
+*.tmp_proj
+*_wpftmp.csproj
+*.log
+*.tlog
+*.vspscc
+*.vssscc
+.builds
+*.pidb
+*.svclog
+*.scc
+
+# Chutzpah Test files
+_Chutzpah*
+
+# Visual C++ cache files
+ipch/
+*.aps
+*.ncb
+*.opendb
+*.opensdf
+*.sdf
+*.cachefile
+*.VC.db
+*.VC.VC.opendb
+
+# Visual Studio profiler
+*.psess
+*.vsp
+*.vspx
+*.sap
+
+# Visual Studio Trace Files
+*.e2e
+
+# TFS 2012 Local Workspace
+$tf/
+
+# Guidance Automation Toolkit
+*.gpState
+
+# ReSharper is a .NET coding add-in
+_ReSharper*/
+*.[Rr]e[Ss]harper
+*.DotSettings.user
+
+# TeamCity is a build add-in
+_TeamCity*
+
+# DotCover is a Code Coverage Tool
+*.dotCover
+
+# AxoCover is a Code Coverage Tool
+.axoCover/*
+!.axoCover/settings.json
+
+# Coverlet is a free, cross platform Code Coverage Tool
+coverage*.json
+coverage*.xml
+coverage*.info
+
+# Visual Studio code coverage results
+*.coverage
+*.coveragexml
+
+# NCrunch
+_NCrunch_*
+.*crunch*.local.xml
+nCrunchTemp_*
+
+# MightyMoose
+*.mm.*
+AutoTest.Net/
+
+# Web workbench (sass)
+.sass-cache/
+
+# Installshield output folder
+[Ee]xpress/
+
+# DocProject is a documentation generator add-in
+DocProject/buildhelp/
+DocProject/Help/*.HxT
+DocProject/Help/*.HxC
+DocProject/Help/*.hhc
+DocProject/Help/*.hhk
+DocProject/Help/*.hhp
+DocProject/Help/Html2
+DocProject/Help/html
+
+# Click-Once directory
+publish/
+
+# Publish Web Output
+*.[Pp]ublish.xml
+*.azurePubxml
+# Note: Comment the next line if you want to checkin your web deploy settings,
+# but database connection strings (with potential passwords) will be unencrypted
+*.pubxml
+*.publishproj
+
+# Microsoft Azure Web App publish settings. Comment the next line if you want to
+# checkin your Azure Web App publish settings, but sensitive information contained
+# in these scripts will be unencrypted
+PublishScripts/
+
+# NuGet Packages
+*.nupkg
+# NuGet Symbol Packages
+*.snupkg
+# The packages folder can be ignored because of Package Restore
+**/[Pp]ackages/*
+# except build/, which is used as an MSBuild target.
+!**/[Pp]ackages/build/
+# Uncomment if necessary however generally it will be regenerated when needed
+#!**/[Pp]ackages/repositories.config
+# NuGet v3's project.json files produces more ignorable files
+*.nuget.props
+*.nuget.targets
+
+# Microsoft Azure Build Output
+csx/
+*.build.csdef
+
+# Microsoft Azure Emulator
+ecf/
+rcf/
+
+# Windows Store app package directories and files
+AppPackages/
+BundleArtifacts/
+Package.StoreAssociation.xml
+_pkginfo.txt
+*.appx
+*.appxbundle
+*.appxupload
+
+# Visual Studio cache files
+# files ending in .cache can be ignored
+*.[Cc]ache
+# but keep track of directories ending in .cache
+!?*.[Cc]ache/
+
+# Others
+ClientBin/
+~$*
+*~
+*.dbmdl
+*.dbproj.schemaview
+*.jfm
+*.pfx
+*.publishsettings
+orleans.codegen.cs
+
+# Including strong name files can present a security risk
+# (https://github.com/github/gitignore/pull/2483#issue-259490424)
+#*.snk
+
+# Since there are multiple workflows, uncomment next line to ignore bower_components
+# (https://github.com/github/gitignore/pull/1529#issuecomment-104372622)
+#bower_components/
+
+# RIA/Silverlight projects
+Generated_Code/
+
+# Backup & report files from converting an old project file
+# to a newer Visual Studio version. Backup files are not needed,
+# because we have git ;-)
+_UpgradeReport_Files/
+Backup*/
+UpgradeLog*.XML
+UpgradeLog*.htm
+ServiceFabricBackup/
+*.rptproj.bak
+
+# SQL Server files
+*.mdf
+*.ldf
+*.ndf
+
+# Business Intelligence projects
+*.rdl.data
+*.bim.layout
+*.bim_*.settings
+*.rptproj.rsuser
+*- [Bb]ackup.rdl
+*- [Bb]ackup ([0-9]).rdl
+*- [Bb]ackup ([0-9][0-9]).rdl
+
+# Microsoft Fakes
+FakesAssemblies/
+
+# GhostDoc plugin setting file
+*.GhostDoc.xml
+
+# Node.js Tools for Visual Studio
+.ntvs_analysis.dat
+node_modules/
+
+# Visual Studio 6 build log
+*.plg
+
+# Visual Studio 6 workspace options file
+*.opt
+
+# Visual Studio 6 auto-generated workspace file (contains which files were open etc.)
+*.vbw
+
+# Visual Studio 6 auto-generated project file (contains which files were open etc.)
+*.vbp
+
+# Visual Studio 6 workspace and project file (working project files containing files to include in project)
+*.dsw
+*.dsp
+
+# Visual Studio 6 technical files
+*.ncb
+*.aps
+
+# Visual Studio LightSwitch build output
+**/*.HTMLClient/GeneratedArtifacts
+**/*.DesktopClient/GeneratedArtifacts
+**/*.DesktopClient/ModelManifest.xml
+**/*.Server/GeneratedArtifacts
+**/*.Server/ModelManifest.xml
+_Pvt_Extensions
+
+# Paket dependency manager
+.paket/paket.exe
+paket-files/
+
+# FAKE - F# Make
+.fake/
+
+# CodeRush personal settings
+.cr/personal
+
+# Python Tools for Visual Studio (PTVS)
+__pycache__/
+*.pyc
+
+# Cake - Uncomment if you are using it
+# tools/**
+# !tools/packages.config
+
+# Tabs Studio
+*.tss
+
+# Telerik's JustMock configuration file
+*.jmconfig
+
+# BizTalk build output
+*.btp.cs
+*.btm.cs
+*.odx.cs
+*.xsd.cs
+
+# OpenCover UI analysis results
+OpenCover/
+
+# Azure Stream Analytics local run output
+ASALocalRun/
+
+# MSBuild Binary and Structured Log
+*.binlog
+
+# NVidia Nsight GPU debugger configuration file
+*.nvuser
+
+# MFractors (Xamarin productivity tool) working folder
+.mfractor/
+
+# Local History for Visual Studio
+.localhistory/
+
+# Visual Studio History (VSHistory) files
+.vshistory/
+
+# BeatPulse healthcheck temp database
+healthchecksdb
+
+# Backup folder for Package Reference Convert tool in Visual Studio 2017
+MigrationBackup/
+
+# Ionide (cross platform F# VS Code tools) working folder
+.ionide/
+
+# Fody - auto-generated XML schema
+FodyWeavers.xsd
+
+# VS Code files for those working on multiple tools
+.vscode/*
+!.vscode/settings.json
+!.vscode/tasks.json
+!.vscode/launch.json
+!.vscode/extensions.json
+*.code-workspace
+
+# Local History for Visual Studio Code
+.history/
+
+# Windows Installer files from build outputs
+*.cab
+*.msi
+*.msix
+*.msm
+*.msp
+
+# JetBrains Rider
+*.sln.iml
diff --git a/ABStudio/FileFormats/PVR/PVRFile.cs b/ABStudio/FileFormats/PVR/PVRFile.cs
index fcf7434..86c4b74 100644
--- a/ABStudio/FileFormats/PVR/PVRFile.cs
+++ b/ABStudio/FileFormats/PVR/PVRFile.cs
@@ -13,11 +13,15 @@ namespace ABStudio.FileFormats.PVR
public class PVRFile
{
private IntPtr tex = IntPtr.Zero;
+ public bool isLegacy = false;
public PVRFile(string filename) : this(File.ReadAllBytes(filename)) { }
public PVRFile(byte[] pvrData)
{
+ if (pvrData[0] == 0x34 && pvrData[1] == 0 && pvrData[2] == 0 && pvrData[3] == 0)
+ isLegacy = true;
+
IntPtr dataPtr = Marshal.AllocHGlobal(pvrData.Length);
Marshal.Copy(pvrData, 0, dataPtr, pvrData.Length);
@@ -85,12 +89,23 @@ public PVRFile(Bitmap bmp, string format="r4g4b4a4")
PVRTexLib.PVRTexLibDestroyTexture(tex);
}
- public string GetFormat()
+ public ulong GetFormat()
{
if (ReferenceEquals(tex, null))
- return "";
+ return 0xFFFFFFFF;
- ulong val = PVRTexLib.PVRTexLibGetTexturePixelFormat(tex);
+ IntPtr header = PVRTexLib.PVRTexLibGetTextureHeader(tex);
+ if (ReferenceEquals(header, null))
+ return 0xFFFFFFFF;
+
+ return PVRTexLib.PVRTexLibGetTexturePixelFormat(header);
+ }
+
+ public string GetFormatStr()
+ {
+ ulong val = GetFormat();
+ if (val == 0xFFFFFFFF)
+ return "";
return FormatULongToString(val);
}
@@ -176,20 +191,155 @@ private IntPtr Transcode(ulong format)
public void Save(string filename)
{
- if (!PVRTexLib.PVRTexLibSaveTextureToFile(tex, filename))
- throw new Exception("Couldn't save PVR file.");
+ File.WriteAllBytes(filename, Save());
}
public byte[] Save()
{
string fn = System.IO.Path.GetTempFileName();
- Save(fn);
+ if (!PVRTexLib.PVRTexLibSaveTextureToFile(tex, fn))
+ throw new Exception("Couldn't save PVR file.");
byte[] bytes = File.ReadAllBytes(fn);
File.Delete(fn);
+ int metaSize = bytes[0x30] | (bytes[0x31] << 8) | (bytes[0x32] << 16) | (bytes[0x33] << 24);
+ bytes = bytes.Take(0x34).Concat(bytes.Skip(0x34 + metaSize)).ToArray();
+ bytes[0x30] = 0;
+ bytes[0x31] = 0;
+ bytes[0x32] = 0;
+ bytes[0x33] = 0;
+
+ if(isLegacy)
+ {
+ byte[] newHeader = new byte[0x34];
+
+ newHeader[0] = 0x34;
+ newHeader[1] = 0;
+ newHeader[2] = 0;
+ newHeader[3] = 0;
+
+ uint height = (uint)(bytes[0x18] | (bytes[0x19] << 8) | (bytes[0x19] << 16) | (bytes[0x19] << 24));
+ newHeader[4] = bytes[0x18];
+ newHeader[5] = bytes[0x19];
+ newHeader[6] = bytes[0x1A];
+ newHeader[7] = bytes[0x1B];
+
+ uint width = (uint)(bytes[0x1C] | (bytes[0x1D] << 8) | (bytes[0x1E] << 16) | (bytes[0x1F] << 24));
+ newHeader[8] = bytes[0x1C];
+ newHeader[9] = bytes[0x1D];
+ newHeader[0xA] = bytes[0x1E];
+ newHeader[0xB] = bytes[0x1F];
+
+ uint mipmapCount = (uint)(bytes[0x2C] | (bytes[0x2D] << 8) | (bytes[0x2E] << 16) | (bytes[0x2F] << 24)) - 1;
+ newHeader[0xC] = (byte)(mipmapCount & 0xFF);
+ newHeader[0xD] = (byte)((mipmapCount >> 8) & 0xFF);
+ newHeader[0xE] = (byte)((mipmapCount >> 16) & 0xFF);
+ newHeader[0xF] = (byte)((mipmapCount >> 24) & 0xFF);
+
+ ulong currFormat = GetFormat();
+ string currFormatStr = FormatULongToString(currFormat);
+
+ ulong rgba4444 = FormatStringToULong("r4g4b4a4");
+ ulong rgba8888 = FormatStringToULong("r8g8b8a8");
+ ulong rgb565 = FormatStringToULong("r5g6b5\00");
+
+ if (currFormat == rgba4444)
+ newHeader[0x10] = 0x10;
+ else if (currFormat == rgba8888)
+ newHeader[0x10] = 0x12;
+ else if (currFormat == rgb565)
+ newHeader[0x10] = 0x13;
+ else
+ throw new Exception("PVR Legacy: unsupported format \"" + currFormatStr + "\".");
+
+ newHeader[0x11] = 0;
+ if (mipmapCount > 0)
+ newHeader[0x11] |= 1;
+ if (currFormatStr.Contains('a'))
+ newHeader[0x11] |= 0x80;
+
+ newHeader[0x12] = 0;
+ newHeader[0x13] = 0;
+
+ uint bpp = PVRTexLib.PVRTexLibGetFormatBitsPerPixel(currFormat);
+ uint surfSize = (width * height) * (bpp / 8U);
+
+ newHeader[0x14] = (byte)(surfSize & 0xFF);
+ newHeader[0x15] = (byte)((surfSize >> 8) & 0xFF);
+ newHeader[0x16] = (byte)((surfSize >> 16) & 0xFF);
+ newHeader[0x17] = (byte)((surfSize >> 24) & 0xFF);
+
+ newHeader[0x18] = (byte)(bpp & 0xFF);
+ newHeader[0x19] = (byte)((bpp >> 8) & 0xFF);
+ newHeader[0x1A] = (byte)((bpp >> 16) & 0xFF);
+ newHeader[0x1B] = (byte)((bpp >> 24) & 0xFF);
+
+ uint rMask = 0;
+ uint gMask = 0;
+ uint bMask = 0;
+ uint aMask = 0;
+
+ if (currFormat == rgba4444)
+ {
+ rMask = 0xF000;
+ gMask = 0x0F00;
+ bMask = 0x00F0;
+ aMask = 0x000F;
+ }
+ else if (currFormat == rgba8888)
+ {
+ rMask = 0xFF000000;
+ gMask = 0x00FF0000;
+ bMask = 0x0000FF00;
+ aMask = 0x000000FF;
+ }
+ else if (currFormat == rgb565)
+ {
+ rMask = 0xF800;
+ gMask = 0x07E0;
+ bMask = 0x001F;
+ aMask = 0x0000;
+ }
+ else
+ throw new Exception("PVR Legacy: unsupported format \"" + currFormatStr + "\".");
+
+ newHeader[0x1C] = (byte)(rMask & 0xFF);
+ newHeader[0x1D] = (byte)((rMask >> 8) & 0xFF);
+ newHeader[0x1E] = (byte)((rMask >> 16) & 0xFF);
+ newHeader[0x1F] = (byte)((rMask >> 24) & 0xFF);
+
+ newHeader[0x20] = (byte)(gMask & 0xFF);
+ newHeader[0x21] = (byte)((gMask >> 8) & 0xFF);
+ newHeader[0x22] = (byte)((gMask >> 16) & 0xFF);
+ newHeader[0x23] = (byte)((gMask >> 24) & 0xFF);
+
+ newHeader[0x24] = (byte)(bMask & 0xFF);
+ newHeader[0x25] = (byte)((bMask >> 8) & 0xFF);
+ newHeader[0x26] = (byte)((bMask >> 16) & 0xFF);
+ newHeader[0x27] = (byte)((bMask >> 24) & 0xFF);
+
+ newHeader[0x28] = (byte)(aMask & 0xFF);
+ newHeader[0x29] = (byte)((aMask >> 8) & 0xFF);
+ newHeader[0x2A] = (byte)((aMask >> 16) & 0xFF);
+ newHeader[0x2B] = (byte)((aMask >> 24) & 0xFF);
+
+ newHeader[0x2C] = (byte)0x50;
+ newHeader[0x2D] = (byte)0x56;
+ newHeader[0x2E] = (byte)0x52;
+ newHeader[0x2F] = (byte)0x21;
+
+ newHeader[0x30] = bytes[0x24];
+ newHeader[0x31] = bytes[0x25];
+ newHeader[0x32] = bytes[0x26];
+ newHeader[0x33] = bytes[0x27];
+
+ for (int i = 0; i < 0x34; i++)
+ bytes[i] = newHeader[i];
+ }
+
return bytes;
}
diff --git a/ABStudio/FileFormats/ZSTREAM/ZSTREAMFile.cs b/ABStudio/FileFormats/ZSTREAM/ZSTREAMFile.cs
index b11d686..102c5c6 100644
--- a/ABStudio/FileFormats/ZSTREAM/ZSTREAMFile.cs
+++ b/ABStudio/FileFormats/ZSTREAM/ZSTREAMFile.cs
@@ -392,7 +392,7 @@ public void SaveBitmap(Bitmap bmp, string path)
Bitmap subbmp = bmp.Clone(new Rectangle(pInfo.x, pInfo.y, pInfo.w, pInfo.h), bmp.PixelFormat);
PVRFile pvr = new PVRFile(subbmp, fmt);
- byte[] asData = pvr.Save().Skip(0x44).ToArray();
+ byte[] asData = pvr.Save().Skip(0x34).ToArray();
byte[] header = new byte[0x28];
subbmp.Dispose();
diff --git a/ABStudio/Forms/SpritesheetEditor.cs b/ABStudio/Forms/SpritesheetEditor.cs
index 27b4a74..54d2bf5 100644
--- a/ABStudio/Forms/SpritesheetEditor.cs
+++ b/ABStudio/Forms/SpritesheetEditor.cs
@@ -31,6 +31,8 @@ public partial class SpritesheetEditor : Form
private object SelectedObj => spritesheetPictureBox.SelectedSRect;
private DATFile.SpriteData.Sprite SelectedSprite => spritesheetPictureBox.GetSRectLinkedObject(SelectedObj) as DATFile.SpriteData.Sprite;
+ private bool legacyPVR = false;
+
#region Extensions management
private static readonly string[] supportedPicExt = new string[] { "pvr", "png", "jpg", "gif", "bmp", "tiff" };
@@ -180,6 +182,7 @@ private bool SaveSpritesheet()
if (ext == ".pvr")
{
PVRFile pvr = new PVRFile(spritesheet);
+ pvr.isLegacy = this.legacyPVR;
pvr.Save(fname);
}
else if(ext == ".stream")
@@ -236,14 +239,25 @@ private void importSpritesFolderToolStripMenuItem_Click(object sender, EventArgs
Packer.PackRectForce(ref packer, bmp.Width + 4, bmp.Height + 4, bmp);
}
- if (maf.ChosenAnswer == 1)
- data.sprites.Clear();
+ int left = int.MaxValue;
+ int top = int.MaxValue;
+ int right = int.MinValue;
+ int bottom = int.MinValue;
Bitmap full = new Bitmap(packer.Width, packer.Height);
using (Graphics g = Graphics.FromImage(full))
{
foreach (PackerRectangle rect in packer.PackRectangles)
{
+ if (rect.X < left)
+ left = rect.X;
+ if (rect.Y < top)
+ top = rect.Y;
+ if ((rect.X + rect.Width) > right)
+ right = rect.X + rect.Width;
+ if ((rect.Y + rect.Height) > bottom)
+ bottom = rect.Y + rect.Height;
+
Bitmap bmp = rect.Data as Bitmap;
Rectangle mainRect = new Rectangle(rect.X + 2, rect.Y + 2, bmp.Width, bmp.Height);
g.DrawImage(bmp, mainRect, new Rectangle(0, 0, bmp.Width, bmp.Height), GraphicsUnit.Pixel);
@@ -253,25 +267,43 @@ private void importSpritesFolderToolStripMenuItem_Click(object sender, EventArgs
g.DrawImage(bmp, new Rectangle(rect.X+2, rect.Y+1, bmp.Width, 1), new Rectangle(0, 0, bmp.Width, 1), GraphicsUnit.Pixel);
g.DrawImage(bmp, new Rectangle(rect.X+2, rect.Y+bmp.Height+2, bmp.Width, 1), new Rectangle(0, bmp.Height-1, bmp.Width, 1), GraphicsUnit.Pixel);
+ }
+ }
+
+ full = full.Clone(new Rectangle(left, top, right - left, bottom - top), full.PixelFormat);
+
+ if (full.Width > 2048 || full.Height > 2048)
+ {
+ MessageBox.Show("Couldn't fit your sprites in a 2048x2048 spritesheet", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
+ return;
+ }
- if (maf.ChosenAnswer != 2)
- {
- DATFile.SpriteData.Sprite sprite = new DATFile.SpriteData.Sprite();
- sprite.name = names[bmps.IndexOf(bmp)];
- sprite.rect = mainRect;
- sprite.orig = new Point(sprite.rect.Width / 2, sprite.rect.Height / 2);
+ if (maf.ChosenAnswer == 1)
+ data.sprites.Clear();
+
+ if (maf.ChosenAnswer != 2)
+ {
+ foreach (PackerRectangle rect in packer.PackRectangles)
+ {
+ DATFile.SpriteData.Sprite sprite = new DATFile.SpriteData.Sprite();
+
+ Bitmap bmp = rect.Data as Bitmap;
- data.sprites.Add(sprite);
- }
+ sprite.name = names[bmps.IndexOf(rect.Data as Bitmap)];
+ sprite.rect = new Rectangle(rect.X + 2 - left, rect.Y + 2 - top, bmp.Width, bmp.Height);
+ sprite.orig = new Point(sprite.rect.Width / 2, sprite.rect.Height / 2);
+
+ data.sprites.Add(sprite);
}
}
+
spritesheet = full;
spritesheetPictureBox.Image = spritesheet;
RefreshRects();
RefreshZoom();
- filenameTextBox.Text = "-- IMPORTED SPRITE FOLDER, REPLACE THIS --";
+ filenameTextBox.Text = Path.GetFileName(dialog.ResultPath) + ".png";
}
}
}
@@ -368,6 +400,7 @@ private void LoadBitmap(string path=null)
path = null;
bool hasSpecifiedPath = path != null;
+ legacyPVR = false;
if (data.filenames.Count <= 0 && !hasSpecifiedPath)
{
@@ -380,6 +413,7 @@ private void LoadBitmap(string path=null)
if(ext == ".pvr")
{
PVRFile pvr = new PVRFile(fullPath);
+ legacyPVR = pvr.isLegacy;
spritesheet = pvr.AsBitmap();
}
else if(fullPath.EndsWith(".stream") || ext == ".zstream")
diff --git a/ABStudio/Libs/StbRectPackSharp/Packer.cs b/ABStudio/Libs/StbRectPackSharp/Packer.cs
index 01e90e7..54fd65e 100644
--- a/ABStudio/Libs/StbRectPackSharp/Packer.cs
+++ b/ABStudio/Libs/StbRectPackSharp/Packer.cs
@@ -122,7 +122,7 @@ public static PackerRectangle PackRectForce(ref Packer packer, int width, int he
// Double the size of the packer until the new rectangle will fit
while (pr == null)
{
- Packer newPacker = new Packer(packer.Width + 256, packer.Height + 256);
+ Packer newPacker = new Packer(packer.Width + 128, packer.Height + 128);
// Place existing rectangles
foreach (PackerRectangle existingRect in packer.PackRectangles)
diff --git a/LICENSE b/LICENSE
index f288702..60f217e 100644
--- a/LICENSE
+++ b/LICENSE
@@ -1,7 +1,7 @@
GNU GENERAL PUBLIC LICENSE
Version 3, 29 June 2007
- Copyright (C) 2007 Free Software Foundation, Inc.
+ Copyright (C) 2023 RSM & Contributors
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.