Add skin import from .3dst (3DS Texture file)

This commit is contained in:
miku-666
2022-09-24 12:06:41 +02:00
parent 88d5804b7f
commit d24853e3cf
7 changed files with 1072 additions and 917 deletions

View File

@@ -54,7 +54,7 @@ namespace Ohana3DS_Rebirth.Ohana
{
int x = tileOrder[pixel] % 8;
int y = (tileOrder[pixel] - x) / 8;
long outputOffset = ((tX * 8) + x + (((tY * 8 + y)) * width)) * 4;
long outputOffset = ((tX * 8) + x + ((tY * 8 + y) * width)) * 4;
Buffer.BlockCopy(data, (int)dataOffset, output, (int)outputOffset, 3);
output[outputOffset + 3] = 0xff;
@@ -310,7 +310,7 @@ namespace Ohana3DS_Rebirth.Ohana
break;
}
return TextureUtils.getBitmap(output.ToArray(), width, height);
return TextureUtils.ToBitmap(output, width, height);
}
/// <summary>
@@ -321,7 +321,7 @@ namespace Ohana3DS_Rebirth.Ohana
/// <returns></returns>
public static byte[] encode(Bitmap img, RenderBase.OTextureFormat format)
{
byte[] data = TextureUtils.getArray(img);
byte[] data = TextureUtils.ToArray(img);
byte[] output = new byte[data.Length];
uint outputOffset = 0;

View File

@@ -13,7 +13,7 @@ namespace Ohana3DS_Rebirth.Ohana
/// <param name="width">Width of the Texture</param>
/// <param name="height">Height of the Texture</param>
/// <returns></returns>
public static Bitmap getBitmap(byte[] array, int width, int height)
public static Bitmap ToBitmap(byte[] array, int width, int height)
{
Bitmap img = new Bitmap(width, height, PixelFormat.Format32bppArgb);
BitmapData imgData = img.LockBits(new Rectangle(0, 0, img.Width, img.Height), ImageLockMode.WriteOnly, PixelFormat.Format32bppArgb);
@@ -27,7 +27,7 @@ namespace Ohana3DS_Rebirth.Ohana
/// </summary>
/// <param name="img">The Bitmap</param>
/// <returns></returns>
public static byte[] getArray(Bitmap img)
public static byte[] ToArray(Bitmap img)
{
BitmapData imgData = img.LockBits(new Rectangle(0, 0, img.Width, img.Height), ImageLockMode.ReadOnly, PixelFormat.Format32bppArgb);
byte[] array = new byte[imgData.Stride * img.Height];

View File

@@ -0,0 +1,110 @@
using Ohana3DS_Rebirth.Ohana;
using System;
using System.Drawing;
using System.IO;
using System.Text;
namespace PckStudio.Classes.Utils
{
internal class _3DSUtil
{
private static string ReadString(Stream stream, int len)
{
var buffer = new byte[len];
stream.Read(buffer, 0, len);
return Encoding.ASCII.GetString(buffer);
}
private static int ReadInt32(Stream stream)
{
var buffer = new byte[4];
stream.Read(buffer, 0, 4);
return BitConverter.ToInt32(buffer, 0);
}
public static int CalcBufferSize(RenderBase.OTextureFormat fmt, int w, int h)
{
switch (fmt)
{
case RenderBase.OTextureFormat.rgba8:
return w * h * 4;
case RenderBase.OTextureFormat.rgb8:
return w * h * 3;
case RenderBase.OTextureFormat.rgba5551:
case RenderBase.OTextureFormat.rgb565:
case RenderBase.OTextureFormat.rgba4:
case RenderBase.OTextureFormat.la8:
case RenderBase.OTextureFormat.hilo8:
return w * h * 2;
case RenderBase.OTextureFormat.l8:
case RenderBase.OTextureFormat.a8:
case RenderBase.OTextureFormat.la4:
case RenderBase.OTextureFormat.etc1a4:
return w * h;
case RenderBase.OTextureFormat.l4:
case RenderBase.OTextureFormat.a4:
case RenderBase.OTextureFormat.etc1:
return w * h >> 1;
default:
throw new InvalidDataException("Invalid texture format on BCH!");
}
}
public static Image GetImageFrom3DST(Stream stream)
{
if (ReadString(stream, 4) == "3DST")
{
int offset = 32;
stream.Seek(8L, SeekOrigin.Begin);
RenderBase.OTextureFormat otextureFormat = ReadInt32(stream) switch
{
0 => RenderBase.OTextureFormat.rgba8,
1 => RenderBase.OTextureFormat.rgb8,
2 => RenderBase.OTextureFormat.rgba5551,
3 => RenderBase.OTextureFormat.rgb8,
4 => RenderBase.OTextureFormat.rgba4,
9 => RenderBase.OTextureFormat.la4,
_ => RenderBase.OTextureFormat.dontCare,
};
int width = ReadInt32(stream);
int height = ReadInt32(stream);
int bufferSize = CalcBufferSize(otextureFormat, width, height);
stream.Seek(offset, SeekOrigin.Begin);
byte[] buffer = new byte[bufferSize];
stream.Read(buffer, 0, bufferSize);
var img = TextureCodec.decode(buffer, width, height, otextureFormat);
img.RotateFlip(RotateFlipType.RotateNoneFlipY);
return img;
}
return null;
}
public static void SetImageTo3DST(Stream stream, Image source, RenderBase.OTextureFormat format = RenderBase.OTextureFormat.rgba8)
{
throw new NotImplementedException();
//if (ReadString(stream, 4) == "3DST")
//{
// int offset = 32;
// stream.Seek(8L, SeekOrigin.Begin);
// RenderBase.OTextureFormat otextureFormat = ReadInt32(stream) switch
// {
// 0 => RenderBase.OTextureFormat.rgba8,
// 1 => RenderBase.OTextureFormat.rgb8,
// 2 => RenderBase.OTextureFormat.rgba5551,
// 3 => RenderBase.OTextureFormat.rgb8,
// 4 => RenderBase.OTextureFormat.rgba4,
// 9 => RenderBase.OTextureFormat.la4,
// _ => RenderBase.OTextureFormat.dontCare,
// };
// int width = ReadInt32(stream);
// int height = ReadInt32(stream);
// int bufferSize = CalcBufferSize(otextureFormat, width, height);
// stream.Seek(offset, SeekOrigin.Begin);
// byte[] buffer = new byte[bufferSize];
// stream.Read(buffer, 0, bufferSize);
// var img = TextureCodec.decode(buffer, width, height, otextureFormat);
// img.RotateFlip(RotateFlipType.RotateNoneFlipY);
//}
}
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -2927,5 +2927,28 @@ namespace PckStudio
}
}
}
private void importSkinfrom3dstFileToolStripMenuItem_Click(object sender, EventArgs e)
{
OpenFileDialog openFileDialog = new OpenFileDialog();
openFileDialog.DefaultExt = ".3dst";
openFileDialog.Filter = "3DS Texture|*.3dst";
if (openFileDialog.ShowDialog() == DialogResult.OK)
{
using (var fs = File.OpenRead(openFileDialog.FileName))
{
var img = _3DSUtil.GetImageFrom3DST(fs);
PCKFile.FileData file = new PCKFile.FileData("3dst_import.png", PCKFile.FileData.FileType.SkinFile);
file.properties.Add(("DISPLAYNAME", Path.GetFileNameWithoutExtension(openFileDialog.FileName)));
using (var ms = new MemoryStream())
{
img.Save(ms, ImageFormat.Png);
file.SetData(ms.ToArray());
}
currentPCK.Files.Add(file);
BuildMainTreeView();
}
}
}
}
}

View File

@@ -229,6 +229,12 @@
<data name="importSkinToolStripMenuItem.Text" xml:space="preserve">
<value>Import Skin</value>
</data>
<data name="importSkinfrom3dstFileToolStripMenuItem.Size" type="System.Drawing.Size, System.Drawing">
<value>228, 22</value>
</data>
<data name="importSkinfrom3dstFileToolStripMenuItem.Text" xml:space="preserve">
<value>Import Skin (from .3dst file)</value>
</data>
<data name="importExtractedSkinsFolderToolStripMenuItem.Image" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>
iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAALGPC/xhBQAAAAlwSFlzAAAO
@@ -454,7 +460,7 @@
<value>Generate MipMap Texture</value>
</data>
<data name="contextMenuPCKEntries.Size" type="System.Drawing.Size, System.Drawing">
<value>211, 290</value>
<value>211, 268</value>
</data>
<data name="&gt;&gt;contextMenuPCKEntries.Name" xml:space="preserve">
<value>contextMenuPCKEntries</value>
@@ -648,7 +654,7 @@
</value>
</data>
<data name="advancedMetaAddingToolStripMenuItem.Size" type="System.Drawing.Size, System.Drawing">
<value>176, 22</value>
<value>180, 22</value>
</data>
<data name="advancedMetaAddingToolStripMenuItem.Text" xml:space="preserve">
<value>Advanced Bulk</value>
@@ -674,7 +680,7 @@
</value>
</data>
<data name="convertToBedrockToolStripMenuItem.Size" type="System.Drawing.Size, System.Drawing">
<value>176, 22</value>
<value>180, 22</value>
</data>
<data name="convertToBedrockToolStripMenuItem.Text" xml:space="preserve">
<value>Convert to Bedrock</value>
@@ -29499,7 +29505,7 @@
<value>True</value>
</data>
<data name="metroLabel2.Location" type="System.Drawing.Point, System.Drawing">
<value>213, 119</value>
<value>288, 119</value>
</data>
<data name="metroLabel2.Size" type="System.Drawing.Size, System.Drawing">
<value>0, 0</value>
@@ -29571,7 +29577,7 @@
<value>False</value>
</data>
<data name="entryTypeTextBox.Location" type="System.Drawing.Point, System.Drawing">
<value>208, 119</value>
<value>283, 119</value>
</data>
<data name="entryTypeTextBox.Size" type="System.Drawing.Size, System.Drawing">
<value>186, 23</value>
@@ -29616,7 +29622,7 @@
<value>False</value>
</data>
<data name="entryDataTextBox.Location" type="System.Drawing.Point, System.Drawing">
<value>208, 151</value>
<value>283, 151</value>
</data>
<data name="entryDataTextBox.Size" type="System.Drawing.Size, System.Drawing">
<value>186, 23</value>
@@ -29640,7 +29646,7 @@
<value>Bottom, Right</value>
</data>
<data name="buttonEdit.Location" type="System.Drawing.Point, System.Drawing">
<value>208, 180</value>
<value>283, 180</value>
</data>
<data name="buttonEdit.Size" type="System.Drawing.Size, System.Drawing">
<value>186, 60</value>
@@ -29673,7 +29679,7 @@
<value>True</value>
</data>
<data name="metroLabel1.Location" type="System.Drawing.Point, System.Drawing">
<value>213, 68</value>
<value>288, 68</value>
</data>
<data name="metroLabel1.Size" type="System.Drawing.Size, System.Drawing">
<value>0, 0</value>
@@ -29700,7 +29706,7 @@
<value>3, 3, 3, 3</value>
</data>
<data name="MetaTab.Size" type="System.Drawing.Size, System.Drawing">
<value>588, 240</value>
<value>663, 240</value>
</data>
<data name="MetaTab.TabIndex" type="System.Int32, mscorlib">
<value>0</value>
@@ -29721,10 +29727,10 @@
<value>0</value>
</data>
<data name="PropertiesTabControl.Location" type="System.Drawing.Point, System.Drawing">
<value>413, 277</value>
<value>338, 277</value>
</data>
<data name="PropertiesTabControl.Size" type="System.Drawing.Size, System.Drawing">
<value>596, 282</value>
<value>671, 282</value>
</data>
<data name="PropertiesTabControl.TabIndex" type="System.Int32, mscorlib">
<value>11</value>
@@ -29793,7 +29799,7 @@
<value>0</value>
</data>
<data name="treeViewMain.Size" type="System.Drawing.Size, System.Drawing">
<value>405, 501</value>
<value>330, 501</value>
</data>
<data name="treeViewMain.TabIndex" type="System.Int32, mscorlib">
<value>10</value>
@@ -29820,7 +29826,7 @@
<value>NoControl</value>
</data>
<data name="pictureBoxImagePreview.Location" type="System.Drawing.Point, System.Drawing">
<value>413, 50</value>
<value>345, 50</value>
</data>
<data name="pictureBoxImagePreview.Size" type="System.Drawing.Size, System.Drawing">
<value>231, 218</value>
@@ -32496,6 +32502,12 @@
<data name="&gt;&gt;importSkinToolStripMenuItem.Type" xml:space="preserve">
<value>System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</data>
<data name="&gt;&gt;importSkinfrom3dstFileToolStripMenuItem.Name" xml:space="preserve">
<value>importSkinfrom3dstFileToolStripMenuItem</value>
</data>
<data name="&gt;&gt;importSkinfrom3dstFileToolStripMenuItem.Type" xml:space="preserve">
<value>System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</data>
<data name="&gt;&gt;importExtractedSkinsFolderToolStripMenuItem.Name" xml:space="preserve">
<value>importExtractedSkinsFolderToolStripMenuItem</value>
</data>
@@ -32634,6 +32646,12 @@
<data name="&gt;&gt;viewFileInfoToolStripMenuItem.Type" xml:space="preserve">
<value>System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</data>
<data name="&gt;&gt;generateMipMapTextureToolStripMenuItem.Name" xml:space="preserve">
<value>generateMipMapTextureToolStripMenuItem</value>
</data>
<data name="&gt;&gt;generateMipMapTextureToolStripMenuItem.Type" xml:space="preserve">
<value>System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</data>
<data name="&gt;&gt;fileToolStripMenuItem.Name" xml:space="preserve">
<value>fileToolStripMenuItem</value>
</data>
@@ -32904,12 +32922,6 @@
<data name="&gt;&gt;imageList.Type" xml:space="preserve">
<value>System.Windows.Forms.ImageList, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</data>
<data name="&gt;&gt;generateMipMapTextureToolStripMenuItem.Name" xml:space="preserve">
<value>generateMipMapTextureToolStripMenuItem</value>
</data>
<data name="&gt;&gt;generateMipMapTextureToolStripMenuItem.Type" xml:space="preserve">
<value>System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</data>
<data name="&gt;&gt;$this.Name" xml:space="preserve">
<value>MainForm</value>
</data>

View File

@@ -17,7 +17,7 @@
<ApplicationVersion>1.0.0.%2a</ApplicationVersion>
<UseApplicationTrust>false</UseApplicationTrust>
<BootstrapperEnabled>true</BootstrapperEnabled>
<DisableFody Condition="'$(Configuration)' == 'Debug'">true</DisableFody>
<DisableFody Condition="'$(Configuration)' == 'Debug'">true</DisableFody>
</PropertyGroup>
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
@@ -152,6 +152,7 @@
<Compile Include="Classes\IO\Sounds\SoundIO.cs" />
<Compile Include="Classes\IO\Sounds\Sounds.cs" />
<Compile Include="Classes\Models\DefaultModels\Steve64x64Model.cs" />
<Compile Include="Classes\Utils\3DS\3DSUtil.cs" />
<Compile Include="Classes\Utils\ARC\ARCUtil.cs" />
<Compile Include="Classes\Utils\SkinANIM.cs" />
<Compile Include="Classes\FileTypes\PCKProperties.cs" />
@@ -682,7 +683,7 @@
<ItemGroup>
<PackageReference Include="Costura.Fody">
<Version>5.8.0-alpha0098</Version>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
<IncludeAssets>compile; runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
<PrivateAssets>all</PrivateAssets>
</PackageReference>
<PackageReference Include="DiscordRichPresence">