DS-Pokemon-Rom-Editor/DS_Map/LibNDSFormats/NSBTA.cs
2020-10-06 22:57:27 +02:00

336 lines
16 KiB
C#

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Windows.Forms;
namespace MKDS_Course_Editor.NSBTA
{
public class NSBTA
{
public struct NSBTA_File
{
public header Header;
public struct header
{
public string ID;
public byte[] Magic;
public Int32 file_size;
public Int16 header_size;
public Int16 nSection;
public Int32[] Section_Offset;
}
public srt0 SRT0;
public struct srt0 //Scale Rotation and Translation
{
public string ID;
public Int32 Size;
//3D Info Structure
public byte dummy;
public byte num_objs;
public short section_size;
public UnknownBlock unknownBlock;
public Info infoBlock;
public string[] names;
public struct UnknownBlock
{
public short header_size;
public short section_size;
public int constant; // 0x017F
public short[] unknown1;
public short[] unknown2;
}
public struct Info
{
public short header_size;
public short data_size;
public info[] Data;
public struct info
{
public Int32 MAToffset;
}
}
}
public M_AT MAT;
public struct M_AT
{
public string ID;
public Int16 Unknown1;
public byte Unknown2;
public byte Unknown3;
//3D Info Structure
public byte dummy;
public byte num_objs;
public short section_size;
public UnknownBlock unknownBlock;
public Info infoBlock;
public string[] names;
public struct UnknownBlock
{
public short header_size;
public short section_size;
public int constant; // 0x017F
public short[] unknown1;
public short[] unknown2;
}
public struct Info
{
public short header_size;
public short data_size;
public info[] Data;
public struct info
{
public Int16[] frame;
public Int16[] var1;
public Int16[] var2;
public Int16[] var3;
public int[] frameStep;
}
}
}
public srtData[] SRTData;
public struct srtData
{
public decimal[] scaleS;
public decimal[] scaleT;
public decimal[] rotate;
public decimal[] translateS;
public decimal[] translateT;
}
}
public static NSBTA_File Read(string Filename)
{
EndianBinaryReader er = new EndianBinaryReader(File.OpenRead(Filename), Endianness.LittleEndian);
NSBTA_File ns = new NSBTA_File();
ns.Header.ID = er.ReadString(Encoding.ASCII, 4);
if (ns.Header.ID == "BTA0")
{
ns.Header.Magic = er.ReadBytes(4);
ns.Header.file_size = er.ReadInt32();
ns.Header.header_size = er.ReadInt16();
ns.Header.nSection = er.ReadInt16();
ns.Header.Section_Offset = new Int32[ns.Header.nSection];
for (int i = 0; i < ns.Header.nSection; i++)
{
ns.Header.Section_Offset[i] = er.ReadInt32();
}
ns.SRT0.ID = er.ReadString(Encoding.ASCII, 4);
if (ns.SRT0.ID == "SRT0")
{
ns.SRT0.Size = er.ReadInt32();
//3D Info Structure
ns.SRT0.dummy = er.ReadByte();
ns.SRT0.num_objs = er.ReadByte();
ns.SRT0.section_size = er.ReadInt16();
ns.SRT0.unknownBlock.header_size = er.ReadInt16();
ns.SRT0.unknownBlock.section_size = er.ReadInt16();
ns.SRT0.unknownBlock.constant = er.ReadInt32();
ns.SRT0.unknownBlock.unknown1 = new short[ns.SRT0.num_objs];
ns.SRT0.unknownBlock.unknown2 = new short[ns.SRT0.num_objs];
for (int i = 0; i < ns.SRT0.num_objs; i++)
{
ns.SRT0.unknownBlock.unknown1[i] = er.ReadInt16();
ns.SRT0.unknownBlock.unknown2[i] = er.ReadInt16();
}
ns.SRT0.infoBlock.header_size = er.ReadInt16();
ns.SRT0.infoBlock.data_size = er.ReadInt16();
ns.SRT0.infoBlock.Data = new NSBTA_File.srt0.Info.info[ns.SRT0.num_objs];
for (int i = 0; i < ns.SRT0.num_objs; i++)
{
ns.SRT0.infoBlock.Data[i].MAToffset = er.ReadInt32();
}
ns.SRT0.names = new string[ns.SRT0.num_objs];
for (int i = 0; i < ns.SRT0.num_objs; i++)
{
ns.SRT0.names[i] = er.ReadString(Encoding.ASCII, 16).Replace("\0", "");
}
ns.MAT.ID = er.ReadString(Encoding.ASCII, 4);
if (ns.MAT.ID == "M"+(char)0x00+"AT")
{
ns.MAT.Unknown1 = er.ReadInt16();
ns.MAT.Unknown2 = er.ReadByte();
ns.MAT.Unknown3 = er.ReadByte();
//3D Info Structure
ns.MAT.dummy = er.ReadByte();
ns.MAT.num_objs = er.ReadByte();
ns.MAT.section_size = er.ReadInt16();
ns.MAT.unknownBlock.header_size = er.ReadInt16();
ns.MAT.unknownBlock.section_size = er.ReadInt16();
ns.MAT.unknownBlock.constant = er.ReadInt32();
ns.MAT.unknownBlock.unknown1 = new short[ns.MAT.num_objs];
ns.MAT.unknownBlock.unknown2 = new short[ns.MAT.num_objs];
for (int i = 0; i < ns.MAT.num_objs; i++)
{
ns.MAT.unknownBlock.unknown1[i] = er.ReadInt16();
ns.MAT.unknownBlock.unknown2[i] = er.ReadInt16();
}
ns.MAT.infoBlock.header_size = er.ReadInt16();
ns.MAT.infoBlock.data_size = er.ReadInt16();
ns.MAT.infoBlock.Data = new NSBTA_File.M_AT.Info.info[ns.MAT.num_objs];
ns.SRTData = new NSBTA_File.srtData[ns.MAT.num_objs];
for (int i = 0; i < ns.MAT.num_objs; i++)
{
ns.MAT.infoBlock.Data[i].frame = new short[5];
ns.MAT.infoBlock.Data[i].var1 = new short[5];
ns.MAT.infoBlock.Data[i].var2 = new short[5];
ns.MAT.infoBlock.Data[i].var3 = new short[5];
ns.MAT.infoBlock.Data[i].frameStep = new int[5];
for (int j = 0; j < 5; j++)
{
ns.MAT.infoBlock.Data[i].frame[j] = er.ReadInt16();
ns.MAT.infoBlock.Data[i].var1[j] = (short)(er.ReadInt16() / 4096);
ns.MAT.infoBlock.Data[i].var2[j] = er.ReadInt16();
ns.MAT.infoBlock.Data[i].var3[j] = (short)(er.ReadInt16() / 4096);
}
if (ns.MAT.infoBlock.Data[i].var1[0] > 1)
{
ns.SRTData[i].scaleS = new decimal[1];
ns.SRTData[i].scaleS[0] = Math.Abs(ns.MAT.infoBlock.Data[i].var2[0] / 4096);
}
else
{
ns.SRTData[i].scaleS = new decimal[ns.MAT.infoBlock.Data[i].frame[0]];
}
if (ns.MAT.infoBlock.Data[i].var1[1] > 1)
{
ns.SRTData[i].scaleT = new decimal[1];
ns.SRTData[i].scaleT[0] = Math.Abs(ns.MAT.infoBlock.Data[i].var2[1] / 4096);
}
else
{
ns.SRTData[i].scaleT = new decimal[ns.MAT.infoBlock.Data[i].frame[1]];
}
if (ns.MAT.infoBlock.Data[i].var1[2] > 1)
{
ns.SRTData[i].rotate = new decimal[2];
ns.SRTData[i].rotate[0] = ns.MAT.infoBlock.Data[i].var2[2];
ns.SRTData[i].rotate[1] = ns.MAT.infoBlock.Data[i].var3[2];
}
else
{
ns.SRTData[i].rotate = new decimal[ns.MAT.infoBlock.Data[i].frame[2] * 2];
}
if (ns.MAT.infoBlock.Data[i].var1[3] > 1)
{
ns.SRTData[i].translateS = new decimal[1];
ns.SRTData[i].translateS[0] = Math.Abs(ns.MAT.infoBlock.Data[i].var2[3] / 4096);
}
else
{
ns.SRTData[i].translateS = new decimal[ns.MAT.infoBlock.Data[i].frame[3]];
ns.MAT.infoBlock.Data[i].frameStep[3] = Math.Abs(ns.MAT.infoBlock.Data[i].var1[3] >> 1);
}
if (ns.MAT.infoBlock.Data[i].var1[4] > 1)
{
ns.SRTData[i].translateT = new decimal[1];
ns.SRTData[i].translateT[0] = Math.Abs(ns.MAT.infoBlock.Data[i].var2[4] / 4096);
}
else
{
ns.SRTData[i].translateT = new decimal[ns.MAT.infoBlock.Data[i].frame[4]];
ns.MAT.infoBlock.Data[i].frameStep[4] = Math.Abs(ns.MAT.infoBlock.Data[i].var1[4] >> 1);
}
//ns.SRTData[i].scaleS = new decimal[ns.MAT.infoBlock.Data[i].var1[0] == 3 ? 1 : ns.MAT.infoBlock.Data[i].frame[0]];
//ns.SRTData[i].scaleT = new decimal[ns.MAT.infoBlock.Data[i].var1[1] == 3 ? 1 : ns.MAT.infoBlock.Data[i].frame[1]];
//ns.SRTData[i].rotate = new decimal[ns.MAT.infoBlock.Data[i].var1[2] == 2 ? ns.MAT.infoBlock.Data[i].var1[2] == 3 ? 2 : 1 : ns.MAT.infoBlock.Data[i].frame[2]];
//ns.SRTData[i].translateS = new decimal[ns.MAT.infoBlock.Data[i].var1[3] == 3 ? 1 : ns.MAT.infoBlock.Data[i].frame[3]];
//ns.SRTData[i].translateT = new decimal[ns.MAT.infoBlock.Data[i].var1[4] == 3 ? 1 : ns.MAT.infoBlock.Data[i].frame[4]];
}
ns.MAT.names = new string[ns.MAT.num_objs];
for (int i = 0; i < ns.MAT.num_objs; i++)
{
ns.MAT.names[i] = er.ReadString(Encoding.ASCII, 16).Replace("\0", "");
}
for (int i = 0; i < ns.MAT.num_objs; i++)
{
if (ns.SRTData[i].scaleS.Length != 1)
{
er.BaseStream.Position = ns.Header.Section_Offset[0] + ns.SRT0.section_size + ns.MAT.infoBlock.Data[i].var2[0] + 8;
for (int j = 0; j < ns.SRTData[i].scaleS.Length; j++)
{
ns.SRTData[i].scaleS[j] = (decimal)(er.ReadInt16() / 4096d);
}
}
if (ns.SRTData[i].scaleT.Length != 1)
{
er.BaseStream.Position = ns.Header.Section_Offset[0] + ns.SRT0.section_size + ns.MAT.infoBlock.Data[i].var2[1] + 8;
for (int j = 0; j < ns.SRTData[i].scaleT.Length; j++)
{
ns.SRTData[i].scaleT[j] = (decimal)(er.ReadInt16() / 4096d);
}
}
if (ns.SRTData[i].rotate.Length != 2)
{
er.BaseStream.Position = ns.Header.Section_Offset[0] + ns.SRT0.section_size + ns.MAT.infoBlock.Data[i].var2[2] + 8;
for (int j = 0; j < ns.SRTData[i].rotate.Length; j++)
{
ns.SRTData[i].rotate[j] = (decimal)(er.ReadInt16() / 4096d);
}
}
if (ns.SRTData[i].translateS.Length != 1)
{
er.BaseStream.Position = ns.Header.Section_Offset[0] + ns.SRT0.section_size + ns.MAT.infoBlock.Data[i].var2[3] + 8;
for (int j = 0; j < ns.SRTData[i].translateS.Length; j += (ns.MAT.infoBlock.Data[i].frameStep[3] == 0 ? 1 : ns.MAT.infoBlock.Data[i].frameStep[3]))
{
decimal value = (decimal)(er.ReadInt16() / 4096d);
for (int k = 0; k < (ns.MAT.infoBlock.Data[i].frameStep[3] == 0 ? 1 : ns.MAT.infoBlock.Data[i].frameStep[3]); k++)
{
ns.SRTData[i].translateS[j + k] = value;
}
}
}
if (ns.SRTData[i].translateT.Length != 1)
{
er.BaseStream.Position = ns.Header.Section_Offset[0] + ns.SRT0.section_size + ns.MAT.infoBlock.Data[i].var2[4] + 8;
for (int j = 0; j < ns.SRTData[i].translateT.Length; j +=( ns.MAT.infoBlock.Data[i].frameStep[4] == 0 ? 1 : ns.MAT.infoBlock.Data[i].frameStep[4]))
{
decimal value = (decimal)(er.ReadInt16() / 4096d);
for (int k = 0; k < (ns.MAT.infoBlock.Data[i].frameStep[4] == 0 ? 1 : ns.MAT.infoBlock.Data[i].frameStep[4]); k++)
{
ns.SRTData[i].translateT[j + k] = value;
}
}
}
}
}
else
{
MessageBox.Show("Error");
er.Close();
return ns;
}
}
else
{
MessageBox.Show("Error");
er.Close();
return ns;
}
}
else
{
MessageBox.Show("Error");
er.Close();
return ns;
}
er.Close();
return ns;
}
}
}