Skip to content

Commit

Permalink
Implemented an early version of the NDS Chunk Texture plugin for Kukkii.
Browse files Browse the repository at this point in the history
  • Loading branch information
IcySon55 committed Jun 30, 2017
1 parent 4ee0df1 commit df7f969
Show file tree
Hide file tree
Showing 4 changed files with 236 additions and 0 deletions.
129 changes: 129 additions & 0 deletions image_nintendo/CHNKTEX.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,129 @@
using System.Collections.Generic;
using System.Drawing;
using System.Drawing.Imaging;
using System.IO;
using System.Linq;
using Kuriimu.IO;

namespace image_nintendo
{
class CHNKTEX
{
private const int WidthMultiplier = 4;
private const int HeightMultiplier = 32;
private const int MinHeight = 8;

public TXIF Txif { get; set; }
public List<Color> Palette = new List<Color>();
public List<byte> Map;
public List<byte> Tiles;

public List<Bitmap> Bitmaps = new List<Bitmap>();

public CHNKTEX(Stream input)
{
using (var br = new BinaryReaderX(input))
{
while (br.BaseStream.Position < br.BaseStream.Length)
{
var chunk = br.ReadStruct<CHNK>();
var section = br.ReadString(4);

if (section == "TXIF")
Txif = br.ReadStruct<TXIF>();
else if (section == "TXIM")
ReadTXIM(chunk, br);
else if (section == "TX4I")
ReadTX4I(chunk, br);
else if (section == "TXPL")
ReadTXPL(chunk, br);
}

Bitmaps.Add(BuildBitmap());
}
}

public void ReadTXIM(CHNK chunk, BinaryReaderX br)
{
if (chunk.DecompressedSize > 0)
Map = Kuriimu.Compression.LZ11.Decompress(new MemoryStream(br.ReadBytes(br.ReadInt32()))).ToList();
else
Map = br.ReadBytes(br.ReadInt32()).ToList();
}

public void ReadTX4I(CHNK chunk, BinaryReaderX br)
{
if (chunk.DecompressedSize > 0)
Tiles = Kuriimu.Compression.LZ11.Decompress(new MemoryStream(br.ReadBytes(br.ReadInt32()))).ToList();
else
Tiles = br.ReadBytes(br.ReadInt32()).ToList();
}

public void ReadTXPL(CHNK chunk, BinaryReaderX br)
{
byte[] paletteBytes;
if (chunk.DecompressedSize > 0)
paletteBytes = Kuriimu.Compression.LZ11.Decompress(new MemoryStream(br.ReadBytes(br.ReadInt32())));
else
paletteBytes = br.ReadBytes(br.ReadInt32());

var brp = new BinaryReader(new MemoryStream(paletteBytes));

//var palette = new Bitmap(160, 260, PixelFormat.Format32bppRgb);
//var gfx = Graphics.FromImage(palette);

//int x = 0, y = 0;
int a = 255, r = 255, g = 255, b = 255;
while (brp.BaseStream.Position < brp.BaseStream.Length)
{
var s = brp.ReadUInt16();

b = (s >> 10) * 33 / 4;
g = ((s & 0x3FF) >> 5) * 33 / 4;
r = (s & 0x1F) * 33 / 4;

var color = Color.FromArgb(a, r, g, b);
Palette.Add(color);

// Draw to the palette
//gfx.FillRectangle(new SolidBrush(color), x, y, 10, 10);
//x += 10;
//if (x % palette.Width == 0)
//{
// x = 0;
// y += 10;
//}
}
}

public Bitmap BuildBitmap()
{
var image = new Bitmap(Txif.Width, Txif.Height, PixelFormat.Format32bppRgb);
var gfxI = Graphics.FromImage(image);

int x = 0, y = 0;
for (var i = 0; i < image.Width * image.Height; i++)
{
if ((y * image.Width + x) < Map.Count && Map[y * image.Width + x] < Palette.Count)
image.SetPixel(x, y, Palette[Map[y * image.Width + x]]);

x++;
if (x % image.Width == 0)
{
x = 0;
y++;
}
}

return image;
}

public void Save(Stream output)
{
using (var bw = new BinaryWriterX(output))
{
// TODO: Save
}
}
}
}
67 changes: 67 additions & 0 deletions image_nintendo/ChnkTexAdapter.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
using System.Collections.Generic;
using System.Drawing;
using System.IO;
using System.Linq;
using Kuriimu.Kontract;
using Kuriimu.IO;

namespace image_nintendo
{
public class ChnkTexAdapter : IImageAdapter
{
private CHNKTEX _tex = null;
private List<BitmapInfo> _bitmaps;

#region Properties

// Information
public string Name => "CHNKTEX";
public string Description => "NDS Chunk Texture";
public string Extension => "*.tex";
public string About => "This is the NDS Chunk Texture image adapter for Kukkii.";

// Feature Support
public bool FileHasExtendedProperties => false;
public bool CanSave => false;

public FileInfo FileInfo { get; set; }

#endregion

public bool Identify(string filename)
{
using (var br = new BinaryReaderX(File.OpenRead(filename)))
{
if (br.BaseStream.Length < 4) return false;
return br.ReadString(4) == "CHNK";
}
}

public void Load(string filename)
{
FileInfo = new FileInfo(filename);

if (FileInfo.Exists)
{
_tex = new CHNKTEX(FileInfo.OpenRead());
_bitmaps = _tex.Bitmaps.Select(b => new ChnkTexBitmapInfo { Bitmap = b, Format= ChnkTexFormat.BGR555 }).ToList<BitmapInfo>();
}
}

public void Save(string filename = "")
{
if (filename.Trim() != string.Empty)
FileInfo = new FileInfo(filename);

//if (_bitmaps.Count >= 1)
// _tex.Txif.Format = ((TximBitmapInfo)_bitmaps[0]).Format;
_tex.Bitmaps = _bitmaps.Select(b => b.Bitmap).ToList();
_tex.Save(FileInfo.Create());
}

// Bitmaps
public IList<BitmapInfo> Bitmaps => _bitmaps;

public bool ShowProperties(Icon icon) => false;
}
}
37 changes: 37 additions & 0 deletions image_nintendo/ChnkTexSupport.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
using System.ComponentModel;
using System.Runtime.InteropServices;
using Kuriimu.Kontract;

namespace image_nintendo
{
public enum ChnkTexFormat : byte
{
BGR555
}

[StructLayout(LayoutKind.Sequential, Pack = 1)]
class CHNK
{
public Magic Magic;
public int DecompressedSize;
}

[StructLayout(LayoutKind.Sequential, Pack = 1)]
public class TXIF
{
public int ChunkSize;
public int Unk1;
public int ImageSize;
public int MapSize;
public int PaletteSize;
public short Width;
public short Height;
public int Unk5;
}

public sealed class ChnkTexBitmapInfo : BitmapInfo
{
[Category("Properties")]
public ChnkTexFormat Format { get; set; }
}
}
3 changes: 3 additions & 0 deletions image_nintendo/image_nintendo.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,9 @@
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="SMDH.cs" />
<Compile Include="SmdhAdapter.cs" />
<Compile Include="CHNKTEX.cs" />
<Compile Include="ChnkTexAdapter.cs" />
<Compile Include="ChnkTexSupport.cs" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\Cetera\Cetera.csproj">
Expand Down

0 comments on commit df7f969

Please sign in to comment.