mirror of
https://github.com/AdAstra-LD/DS-Pokemon-Rom-Editor.git
synced 2026-05-10 22:21:05 -05:00
336 lines
16 KiB
C#
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;
|
|
}
|
|
}
|
|
}
|