Add SMDH (Icon) class

This commit is contained in:
Kurt
2015-07-07 21:24:58 -07:00
parent 3046124182
commit e64f4425d5
2 changed files with 189 additions and 0 deletions

188
pk3DS/3DS/SMDH.cs Normal file
View File

@@ -0,0 +1,188 @@
using System;
using System.Drawing;
using System.IO;
using System.Text;
namespace CTR
{
// System Menu Data Header
class SMDH
{
public uint Magic;
public ushort Version;
public ushort Reserved2;
public ApplicationInfo[] AppInfo = new ApplicationInfo[16];
public ApplicationSettings AppSettings;
public ulong Reserved8;
public SmallIcon SmallIcon;
public LargeIcon LargeIcon;
public SMDH(byte[] data)
{
Read(new BinaryReader(new MemoryStream(data)));
}
public SMDH(string path)
{
Read(new BinaryReader(File.OpenRead(path)));
}
public void Read(BinaryReader br)
{
// Check to see if the first 4 bytes (magic) is valid.
if (br.BaseStream.Length != 0x36C0 || (Magic = br.ReadUInt32()) != 0x48444D53)
return; // Abort
Version = br.ReadUInt16();
Reserved2 = br.ReadUInt16();
for (int i = 0; i < 16; i++)
AppInfo[i] = new ApplicationInfo(br);
AppSettings = new ApplicationSettings(br);
Reserved8 = br.ReadUInt64();
SmallIcon = new SmallIcon(br);
LargeIcon = new LargeIcon(br);
}
public byte[] Write()
{
using (var ms = new MemoryStream())
using (var bw = new BinaryWriter(ms))
{
bw.Write(Magic);
bw.Write(Version);
bw.Write(Reserved2);
for (int i = 0; i < 16; i++) AppInfo[i].Write(bw);
AppSettings.Write(bw);
bw.Write(Reserved8);
SmallIcon.Write(bw);
LargeIcon.Write(bw);
return ms.ToArray();
}
}
}
// Thanks to Gericom for EveryFileExplorer's SMDH.cs as a basis for the object code (and AppSettings enumeration)
class ApplicationInfo
{
public String ShortDescription; //0x80
public String LongDescription; //0x100
public String Publisher; //0x80
public ApplicationInfo(BinaryReader br)
{
ShortDescription = Encoding.Unicode.GetString(br.ReadBytes(0x80)).TrimEnd('\0');
LongDescription = Encoding.Unicode.GetString(br.ReadBytes(0x100)).TrimEnd('\0');
Publisher = Encoding.Unicode.GetString(br.ReadBytes(0x80)).TrimEnd('\0');
}
public void Write(BinaryWriter bw)
{
bw.Write(Encoding.Unicode.GetBytes(ShortDescription.PadRight(64, '\0')));
bw.Write(Encoding.Unicode.GetBytes(LongDescription.PadRight(64, '\0')));
bw.Write(Encoding.Unicode.GetBytes(Publisher.PadRight(64, '\0')));
}
}
class ApplicationSettings
{
public byte[] GameRatings; //0x10
public RegionLockoutFlags RegionLockout;
public UInt32 MatchMakerID;
public UInt64 MatchMakerBITID;
public AppSettingsFlags Flags;
public UInt16 EULAVersion;
public UInt16 Reserved;
public Single AnimationDefaultFrame;
public UInt32 StreetPassID;
public enum RegionLockoutFlags : uint
{
Japan = 0x01,
NorthAmerica = 0x02,
Europe = 0x04,
Australia = 0x08,
China = 0x10,
Korea = 0x20,
Taiwan = 0x40
}
public enum AppSettingsFlags : uint
{
Visible = 1,
AutoBoot = 2,
Allow3D = 4,
ReqAcceptEULA = 8,
AutoSaveOnExit = 16,
UsesExtendedBanner = 32,
ReqRegionGameRating = 64,
UsesSaveData = 128,
RecordUsage = 256,
DisableSDSaveBackup = 512
}
public ApplicationSettings(BinaryReader br)
{
GameRatings = br.ReadBytes(0x10);
RegionLockout = (RegionLockoutFlags)br.ReadUInt32();
MatchMakerID = br.ReadUInt32();
MatchMakerBITID = br.ReadUInt64();
Flags = (AppSettingsFlags)br.ReadUInt32();
EULAVersion = br.ReadUInt16();
Reserved = br.ReadUInt16();
AnimationDefaultFrame = br.ReadSingle();
StreetPassID = br.ReadUInt32();
}
public void Write(BinaryWriter bw)
{
bw.Write(GameRatings, 0, 0x10);
bw.Write((uint)RegionLockout);
bw.Write(MatchMakerID);
bw.Write(MatchMakerBITID);
bw.Write((uint)Flags);
bw.Write(EULAVersion);
bw.Write(Reserved);
bw.Write(AnimationDefaultFrame);
bw.Write(StreetPassID);
}
}
class SmallIcon // 24x24
{
public Bitmap Icon;
public byte[] Bytes;
public SmallIcon(BinaryReader br)
{
Bytes = br.ReadBytes(0x480);
Icon = BCLIM.getIMG(24, 24, Bytes, 0x5);
}
public void Write(BinaryWriter bw)
{
bw.Write(Bytes);
}
public bool ChangeIcon(Bitmap img)
{
if (img.Width != Icon.Width || img.Height != Icon.Height) return false;
Icon = img;
Bytes = BCLIM.getPixelData(Icon, 0x5);
return true;
}
}
class LargeIcon // 48x48
{
public Bitmap Icon;
public byte[] Bytes;
public LargeIcon(BinaryReader br)
{
Bytes = br.ReadBytes(0x2000);
Icon = BCLIM.getIMG(48, 48, Bytes, 0x5);
}
public void Write(BinaryWriter bw)
{
bw.Write(Bytes);
Bytes = BCLIM.getPixelData(Icon, 0x5);
}
public bool ChangeIcon(Bitmap img)
{
if (img.Width != Icon.Width || img.Height != Icon.Height) return false;
Icon = img;
Bytes = BCLIM.getPixelData(Icon, 0x5);
return true;
}
}
}

View File

@@ -54,6 +54,7 @@
<Compile Include="3DS\DARC.cs" />
<Compile Include="3DS\ETC1.cs" />
<Compile Include="3DS\Exheader.cs" />
<Compile Include="3DS\SMDH.cs" />
<Compile Include="3DS\LZSS.cs" />
<Compile Include="3DS\mini.cs" />
<Compile Include="3DS\NCCH.cs" />