Files
korenkonder_PD_Tool/KKdMainLib/F2/Light.cs
T
2021-11-09 14:34:27 +03:00

906 lines
37 KiB
C#

using KKdBaseLib;
using KKdBaseLib.F2;
using KKdMainLib.IO;
namespace KKdMainLib.F2
{
public struct Light : System.IDisposable
{
private int i, i0;
private Stream s;
public bool IsX;
public CountPointer<LightStruct> LITs;
public void LITReader(string file)
{
IsX = false;
LITs = default;
byte[] litData = File.ReadAllBytes(file + ".lit");
Struct _LITC = litData.RSt(); litData = null;
if (_LITC.Header.Signature != 0x4354494C) return;
s = File.OpenReader(_LITC.Data);
s.IsBE = _LITC.Header.UseBigEndian;
s.RI32();
LITs = s.RCPE<LightStruct>();
if (LITs.C < 1) { s.C(); LITs.C = -1; return; }
s.PI64 = LITs.O - _LITC.Header.Length;
if (s.RI32() != 0)
{
s.PI64 = LITs.O - _LITC.Header.Length;
for (i = 0; i < LITs.C; i++)
LITs.E[i] = new LightStruct
{ C0 = s.RI32E(), O0 = s.RI32E() };
for (i = 0; i < LITs.C; i++)
{
s.PI64 = LITs.E[i].O0 - _LITC.Header.Length;
for (i0 = 0; i0 < LITs.E[i].C0; i0++)
{
ref LIT lit = ref LITs.E[i].E0[i0];
lit.Id = s.RI32E();
lit.Flags = (Flags)s.RI32E();
lit.Type = (Type )s.RI32E();
lit.Ambient .X = s.RF32E();
lit.Ambient .Y = s.RF32E();
lit.Ambient .Z = s.RF32E();
lit.Ambient .W = s.RF32E();
lit.Diffuse .X = s.RF32E();
lit.Diffuse .Y = s.RF32E();
lit.Diffuse .Z = s.RF32E();
lit.Diffuse .W = s.RF32E();
lit.Specular .X = s.RF32E();
lit.Specular .Y = s.RF32E();
lit.Specular .Z = s.RF32E();
lit.Specular .W = s.RF32E();
lit.Position .X = s.RF32E();
lit.Position .Y = s.RF32E();
lit.Position .Z = s.RF32E();
lit.ToneCurve.X = s.RF32E();
lit.ToneCurve.Y = s.RF32E();
lit.ToneCurve.Z = s.RF32E();
}
}
}
else
{
IsX = true;
s.PI64 = LITs.O;
for (i = 0; i < LITs.C; i++)
LITs.E[i] = new LightStruct
{ C0 = s.RI32E(), C1 = s.RI32E(), O0 = (int)s.RI64E(), O1 = (int)s.RI64E() };
for (i = 0; i < LITs.C; i++)
{
s.P = LITs.E[i].O0;
for (i0 = 0; i0 < LITs.E[i].C0; i0++)
{
ref LIT lit = ref LITs.E[i].E0[i0];
lit.Id = s.RI32E();
lit.Flags = (Flags)s.RI32E();
lit.Type = (Type )s.RI32E();
s.RI32();
long off = s.RI64();
lit.HasStr = s.RI64() != 0;
lit.Unk10 = s.RI32();
lit.Ambient .X = s.RF32E();
lit.Ambient .Y = s.RF32E();
lit.Ambient .Z = s.RF32E();
lit.Ambient .W = s.RF32E();
lit.Diffuse .X = s.RF32E();
lit.Diffuse .Y = s.RF32E();
lit.Diffuse .Z = s.RF32E();
lit.Diffuse .W = s.RF32E();
lit.Specular .X = s.RF32E();
lit.Specular .Y = s.RF32E();
lit.Specular .Z = s.RF32E();
lit.Specular .W = s.RF32E();
lit.Position .X = s.RF32E();
lit.Position .Y = s.RF32E();
lit.Position .Z = s.RF32E();
lit.Unk01 = s.RF32();
lit.Unk02 = s.RF32();
lit.Unk03 = s.RF32();
lit.Unk04 = s.RF32();
lit.Unk05.X = s.RF32();
lit.Unk05.Y = s.RF32();
lit.Unk05.Z = s.RF32();
lit.ToneCurve.X = s.RF32E();
lit.ToneCurve.Y = s.RF32E();
lit.ToneCurve.Z = s.RF32E();
lit.Unk = s.RF32();
lit.Unk06 = s.RF32();
lit.Unk07 = s.RF32();
lit.Unk08 = s.RF32();
lit.Str = off > 0 ? s.RaO(off).ToSJIS() : "";
}
s.P = LITs.E[i].O1;
for (i0 = 0; i0 < LITs.E[i].C1; i0++)
{
ref LITX lit = ref LITs.E[i].E1[i0];
lit.C = s.RI32E();
s.RI32E();
lit.O = (int)s.RI64E();
}
for (i0 = 0; i0 < LITs.E[i].C1; i0++)
{
ref LITX lit = ref LITs.E[i].E1[i0];
ref KeyValuePair<int, int>[] data = ref lit.E;
data = new KeyValuePair<int, int>[lit.C];
s.P = lit.O;
for (int i1 = 0; i1 < lit.C; i1++)
data[i1] = new KeyValuePair<int, int>(s.RI32E(), s.RI32E());
}
}
}
s.C();
}
public void LITWriter(string file)
{
if (LITs.E == null || LITs.C < 1) return;
if (file.EndsWith("_light"))
file = file.Substring(0, file.Length - 6);
s = File.OpenWriter();
s.IsBE = false;
s.Format = Format.F2;
ENRS e = default;
POF p = default;
p.Offsets = KKdList<long>.New;
if (!IsX)
{
s.W(0x02);
s.W(LITs.C);
s.W(0x50);
s.A(0x10);
int offset0 = 0x50 + (LITs.C * 0x08).A(0x10);
for (i = 0; i < LITs.C; i++)
{
s.W(LITs.E[i].C0 > 0 ? LITs.E[i].C0 : 0);
s.W(LITs.E[i].C0 > 0 ? offset0 : 0);
offset0 += (0x54 * (LITs.E[i].C0 > 0 ? LITs.E[i].C0 : 0)).A(0x10);
}
s.A(0x10);
for (i = 0; i < LITs.C; i++)
{
for (i0 = 0; i0 < LITs.E[i].C0; i0++)
{
ref LIT lit = ref LITs.E[i].E0[i0];
s.W( lit.Id );
s.W((int)lit.Flags);
s.W((int)lit.Type );
s.W(lit.Ambient .X);
s.W(lit.Ambient .Y);
s.W(lit.Ambient .Z);
s.W(lit.Ambient .W);
s.W(lit.Diffuse .X);
s.W(lit.Diffuse .Y);
s.W(lit.Diffuse .Z);
s.W(lit.Diffuse .W);
s.W(lit.Specular .X);
s.W(lit.Specular .Y);
s.W(lit.Specular .Z);
s.W(lit.Specular .W);
s.W(lit.Position .X);
s.W(lit.Position .Y);
s.W(lit.Position .Z);
s.W(lit.ToneCurve.X);
s.W(lit.ToneCurve.Y);
s.W(lit.ToneCurve.Z);
}
s.A(0x10);
}
int count = 0;
for (i = 0; i < LITs.C; i++)
if (LITs.E[i].C0 > 0)
count += LITs.E[i].C0;
e.Array = new ENRS.ENRSEntry[3];
e.Array[0] = new ENRS.ENRSEntry(0x00, 0x01, 0x10, 0x01);
e.Array[0].Sub[0] = new ENRS.ENRSEntry.SubENRSEntry(0x00, 0x03, ENRS.ENRSEntry.Type.DWORD);
e.Array[1] = new ENRS.ENRSEntry(0x10, 0x01, 0x08, LITs.C);
e.Array[1].Sub[0] = new ENRS.ENRSEntry.SubENRSEntry(0x00, 0x02, ENRS.ENRSEntry.Type.DWORD);
e.Array[2] = new ENRS.ENRSEntry((LITs.C * 0x08).A(0x10), 0x01, 0x54, count);
e.Array[2].Sub[0] = new ENRS.ENRSEntry.SubENRSEntry(0x00, 0x15, ENRS.ENRSEntry.Type.DWORD);
p.Offsets.Add(0x48);
for (i = 0; i < LITs.C; i++)
p.Offsets.Add(0x54 + 0x08 * i);
}
else
{
long offset0 = 0x50 + (LITs.C * 0x18).A(0x10);
long offset1 = offset0;
long offset2 = offset0 + 0x10;
for (i = 0; i < LITs.C; i++)
offset1 += LITs.E[i].C0 * 0x98;
offset1 = offset1.A(0x10);
long offset3 = offset1;
long offset4 = offset1 + 0x08;
for (i = 0; i < LITs.C; i++)
offset3 += LITs.E[i].C1 * 0x10;
offset3 = offset3.A(0x10);
long offset5 = offset3;
long offset6 = offset3;
for (i = 0; i < LITs.C; i++)
for (i0 = 0; i0 < LITs.E[i].C1; i0++)
offset6 += LITs.E[i].E1[i0].C * 0x08;
byte[][][] strdata = new byte[LITs.C][][];
for (i = 0; i < LITs.C; i++)
{
strdata[i] = new byte[LITs.E[i].C0][];
for (i0 = 0; i0 < LITs.E[i].C0; i0++)
{
ref LIT lit = ref LITs.E[i].E0[i0];
strdata[i][i0] = lit.HasStr && lit.Str != null && lit.Str != "" ? lit.Str.ToSJIS() : null;
}
}
s.W(0x02);
s.W(LITs.C);
s.W(0x50L);
s.A(0x10);
s.P = 0x50;
for (i = 0; i < LITs.C; i++)
{
s.W(LITs.E[i].C0 > 0 ? LITs.E[i].C0 : 0);
s.W(LITs.E[i].C1 > 0 ? LITs.E[i].C1 : 0);
s.W(LITs.E[i].C0 > 0 ? offset0 : 0);
s.W(LITs.E[i].C1 > 0 ? offset1 : 0);
offset0 += 0x98 * (LITs.E[i].C0 > 0 ? LITs.E[i].C0 : 0);
offset1 += 0x10 * (LITs.E[i].C1 > 0 ? LITs.E[i].C1 : 0);
}
s.A(0x10);
for (i = 0; i < LITs.C; i++)
for (i0 = 0; i0 < LITs.E[i].C0; i0++)
{
ref LIT lit = ref LITs.E[i].E0[i0];
s.W( lit.Id );
s.W((int)lit.Flags);
s.W((int)lit.Type );
s.W((int)0);
if (lit.HasStr && strdata[i][i0] != null && strdata[i][i0].Length > 0)
{ s.W(offset6); s.W((long)strdata[i][i0].HashMurmurHash(strdata[i][i0].Length));
offset6 += strdata[i][i0].Length + 1; }
else
{ s.W(0x00L); s.W((long)(lit.HasStr ? 0x0CAD3078 : 0)); }
s.W(lit.Unk10 );
s.W(lit.Ambient .X);
s.W(lit.Ambient .Y);
s.W(lit.Ambient .Z);
s.W(lit.Ambient .W);
s.W(lit.Diffuse .X);
s.W(lit.Diffuse .Y);
s.W(lit.Diffuse .Z);
s.W(lit.Diffuse .W);
s.W(lit.Specular .X);
s.W(lit.Specular .Y);
s.W(lit.Specular .Z);
s.W(lit.Specular .W);
s.W(lit.Position .X);
s.W(lit.Position .Y);
s.W(lit.Position .Z);
s.W(lit.Unk01 );
s.W(lit.Unk02 );
s.W(lit.Unk03 );
s.W(lit.Unk04 );
s.W(lit.Unk05.X );
s.W(lit.Unk05.Y );
s.W(lit.Unk05.Z );
s.W(lit.ToneCurve.X);
s.W(lit.ToneCurve.Y);
s.W(lit.ToneCurve.Z);
s.W(lit.Unk );
s.W(lit.Unk06 );
s.W(lit.Unk07 );
s.W(lit.Unk08 );
}
s.A(0x10);
for (i = 0; i < LITs.C; i++)
for (i0 = 0; i0 < LITs.E[i].C1; i0++)
{
ref LITX lit = ref LITs.E[i].E1[i0];
s.W(lit.C);
s.W((int)0);
s.W(offset5);
offset5 += lit.C * 0x08;
}
s.A(0x10);
for (i = 0; i < LITs.C; i++)
for (i0 = 0; i0 < LITs.E[i].C1; i0++)
{
ref LITX lit = ref LITs.E[i].E1[i0];
for (int i1 = 0; i1 < lit.C; i1++)
{
s.W(lit.E[i1].Key);
s.W(lit.E[i1].Value);
}
}
for (i = 0; i < LITs.C; i++)
for (i0 = 0; i0 < LITs.E[i].C0; i0++)
{
ref LIT lit = ref LITs.E[i].E0[i0];
if (lit.HasStr && strdata[i][i0] != null && strdata[i][i0].Length > 0)
{
s.W(strdata[i][i0]);
s.W((byte)0);
}
}
s.A(0x10);
bool sub = false;
for (i = 0; i < LITs.C; i++)
if (LITs.E[i].C1 > 0) { sub = true; break; }
int count = 0;
for (i = 0; i < LITs.C; i++)
if (LITs.E[i].C0 > 0)
count += LITs.E[i].C0;
e.Array = new ENRS.ENRSEntry[sub ? 5 : 3];
e.Array[0] = new ENRS.ENRSEntry(0x00, 0x02, 0x50, 0x01);
e.Array[0].Sub[0] = new ENRS.ENRSEntry.SubENRSEntry(0x00, 0x02, ENRS.ENRSEntry.Type.DWORD);
e.Array[0].Sub[1] = new ENRS.ENRSEntry.SubENRSEntry(0x00, 0x01, ENRS.ENRSEntry.Type.QWORD);
e.Array[1] = new ENRS.ENRSEntry(0x50, 0x02, 0x18, LITs.C);
e.Array[1].Sub[0] = new ENRS.ENRSEntry.SubENRSEntry(0x00, 0x02, ENRS.ENRSEntry.Type.DWORD);
e.Array[1].Sub[1] = new ENRS.ENRSEntry.SubENRSEntry(0x00, 0x02, ENRS.ENRSEntry.Type.QWORD);
e.Array[2] = new ENRS.ENRSEntry((LITs.C * 0x18).A(0x10), 0x03, 0x98, count);
e.Array[2].Sub[0] = new ENRS.ENRSEntry.SubENRSEntry(0x00, 0x03, ENRS.ENRSEntry.Type.DWORD);
e.Array[2].Sub[1] = new ENRS.ENRSEntry.SubENRSEntry(0x18, 0x0F, ENRS.ENRSEntry.Type.DWORD);
e.Array[2].Sub[2] = new ENRS.ENRSEntry.SubENRSEntry(0x20, 0x03, ENRS.ENRSEntry.Type.DWORD);
if (sub)
{
int sub_count = 0;
for (i = 0; i < LITs.C; i++)
if (LITs.E[i].C1 > 0)
sub_count += LITs.E[i].C1;
e.Array[3] = new ENRS.ENRSEntry((count * 0x98).A(0x10), 0x02, 0x10, sub_count);
e.Array[3].Sub[0] = new ENRS.ENRSEntry.SubENRSEntry(0x00, 0x01, ENRS.ENRSEntry.Type.DWORD);
e.Array[3].Sub[1] = new ENRS.ENRSEntry.SubENRSEntry(0x04, 0x01, ENRS.ENRSEntry.Type.QWORD);
e.Array[4] = new ENRS.ENRSEntry(sub_count * 0x10, 0x01, 0x08, LITs.E[0].E1[0].C);
e.Array[4].Sub[0] = new ENRS.ENRSEntry.SubENRSEntry(0x00, 0x02, ENRS.ENRSEntry.Type.DWORD);
}
p.Offsets.Add(0x08);
for (i = 0; i < LITs.C; i++)
{
if (LITs.E[i].C0 > 0)
p.Offsets.Add(0x58 + 0x18 * i);
if (LITs.E[i].C1 > 0)
p.Offsets.Add(0x60 + 0x18 * i);
}
for (i = 0; i < LITs.C; i++)
for (i0 = 0; i0 < LITs.E[i].C0; i0++)
{
ref LIT lit = ref LITs.E[i].E0[i0];
if (lit.HasStr && strdata[i][i0] != null && strdata[i][i0].Length > 0)
p.Offsets.Add(offset2);
offset2 += 0x98;
}
if (sub)
for (i = 0; i < LITs.C; i++)
for (i0 = 0; i0 < LITs.E[i].C1; i0++)
{
p.Offsets.Add(offset4);
offset4 += 0x10;
}
}
s.A(0x10, true);
byte[] data = s.ToArray(true);
Struct _LITC = default;
_LITC.Header.Signature = 0x4354494C;
_LITC.Header.DataSize = (uint)data.Length;
_LITC.Header.Length = 0x40;
_LITC.Header.Depth = 0;
_LITC.Header.SectionSize = (uint)data.Length;
_LITC.Header.Version = 0;
_LITC.Header.InnerSignature = 0x02;
_LITC.Header.UseBigEndian = false;
_LITC.Header.UseSectionSize = true;
_LITC.Header.Format = Format.F2;
_LITC.Data = data;
_LITC.ENRS = e;
_LITC.POF = p;
File.WriteAllBytes(file + ".lit", _LITC.W(IsX, true));
}
public void MsgPackReader(string file, bool json)
{
IsX = false;
LITs = default;
MsgPack msgPack = file.ReadMPAllAtOnce(json);
MsgPack light;
if ((light = msgPack["Light", true]).NotNull)
{
LITs.E = new LightStruct[light.Array.Length];
for (i = 0; i < LITs.C; i++)
{
ref LightStruct lit = ref LITs.E[i];
lit = default;
MsgPack l = light[i];
MsgPack l0;
if ((l0 = l["MainData", true]).IsNull)
continue;
lit.C0 = l0.Array.Length;
for (i0 = 0; i0 < lit.C0; i0++)
{
ref LIT lit0 = ref lit.E0[i0];
MsgPack l1 = l0[i0];
MsgPack temp;
if ((temp = l1["Id"]).Object != null)
lit0.Id = temp.RI32();
if ((temp = l1["Type"]).Object != null)
{
lit0.Flags |= Flags.Type;
lit0.Type = (Type)temp.RI32();
}
if ((temp = l1["Str"]).Object != null)
{
lit0.HasStr = true;
lit0.Str = temp.RS();
}
if ((temp = l1["Ambient"]).Object != null)
{
lit0.Flags |= Flags.Ambient;
lit0.Ambient.X = temp.RF32("R");
lit0.Ambient.Y = temp.RF32("G");
lit0.Ambient.Z = temp.RF32("B");
lit0.Ambient.W = temp.RF32("A");
}
if ((temp = l1["Diffuse"]).Object != null)
{
lit0.Flags |= Flags.Diffuse;
lit0.Diffuse.X = temp.RF32("R");
lit0.Diffuse.Y = temp.RF32("G");
lit0.Diffuse.Z = temp.RF32("B");
lit0.Diffuse.W = temp.RF32("A");
}
if ((temp = l1["Specular"]).Object != null)
{
lit0.Flags |= Flags.Specular;
lit0.Specular.X = temp.RF32("R");
lit0.Specular.Y = temp.RF32("G");
lit0.Specular.Z = temp.RF32("B");
lit0.Specular.W = temp.RF32("A");
}
if ((temp = l1["Position"]).Object != null)
{
lit0.Flags |= Flags.Position;
lit0.Position.X = temp.RF32("X");
lit0.Position.Y = temp.RF32("Y");
lit0.Position.Z = temp.RF32("Z");
}
if ((temp = l1["ToneCurve"]).Object != null)
{
lit0.Flags |= Flags.ToneCurve;
lit0.ToneCurve.X = temp.RF32("Begin" );
lit0.ToneCurve.Y = temp.RF32("End" );
lit0.ToneCurve.Z = temp.RF32("BlendRate");
}
}
}
}
else if ((light = msgPack["LightX", true]).NotNull)
{
IsX = true;
LITs.E = new LightStruct[light.Array.Length];
for (i = 0; i < LITs.C; i++)
{
ref LightStruct lit = ref LITs.E[i];
lit = default;
MsgPack l = light[i];
MsgPack l0;
if ((l0 = l["MainData", true]).IsNull)
continue;
lit.C0 = l0.Array.Length;
for (i0 = 0; i0 < lit.C0; i0++)
{
ref LIT lit0 = ref lit.E0[i0];
lit0 = default;
MsgPack l1;
if ((l1 = l0[i0]).IsNull)
continue;
MsgPack temp;
if ((temp = l1["Id"]).Object != null)
lit0.Id = temp.RI32();
if ((temp = l1["Flags"]).Object != null)
lit0.Flags = (Flags)temp.RI32();
if ((temp = l1["Type"]).Object != null)
lit0.Type = (Type)temp.RI32();
if ((temp = l1["Ambient"]).Object != null)
{
lit0.Ambient.X = temp.RF32("R");
lit0.Ambient.Y = temp.RF32("G");
lit0.Ambient.Z = temp.RF32("B");
lit0.Ambient.W = temp.RF32("A");
}
if ((temp = l1["Diffuse"]).Object != null)
{
lit0.Diffuse.X = temp.RF32("R");
lit0.Diffuse.Y = temp.RF32("G");
lit0.Diffuse.Z = temp.RF32("B");
lit0.Diffuse.W = temp.RF32("A");
}
if ((temp = l1["Specular"]).Object != null)
{
lit0.Specular.X = temp.RF32("R");
lit0.Specular.Y = temp.RF32("G");
lit0.Specular.Z = temp.RF32("B");
lit0.Specular.W = temp.RF32("A");
}
if ((temp = l1["Position"]).Object != null)
{
lit0.Position.X = temp.RF32("X");
lit0.Position.Y = temp.RF32("Y");
lit0.Position.Z = temp.RF32("Z");
}
if ((temp = l1["ToneCurve"]).Object != null)
lit0.ToneCurve.X = temp.RF32("Begin" );
lit0.ToneCurve.Y = temp.RF32("End" );
lit0.ToneCurve.Z = temp.RF32("BlendRate");
if ((temp = l1["Str"]).Object != null)
{
lit0.HasStr = true;
lit0.Str = temp.RS();
}
if ((temp = l1["Unk01"]).Object != null)
lit0.Unk01 = temp.RF32();
if ((temp = l1["Unk02"]).Object != null)
lit0.Unk02 = temp.RF32();
if ((temp = l1["Unk03"]).Object != null)
lit0.Unk03 = temp.RF32();
if ((temp = l1["Unk04"]).Object != null)
lit0.Unk04 = temp.RF32();
if ((temp = l1["Unk05"]).Object != null)
lit0.Unk05.X = temp.RF32("X");
lit0.Unk05.Y = temp.RF32("Y");
lit0.Unk05.Z = temp.RF32("Z");
if ((temp = l1["Unk06"]).Object != null)
lit0.Unk06 = temp.RF32();
if ((temp = l1["Unk07"]).Object != null)
lit0.Unk07 = temp.RF32();
if ((temp = l1["Unk08"]).Object != null)
lit0.Unk08 = temp.RF32();
if ((temp = l1["Unk10"]).Object != null)
lit0.Unk10 = temp.RI32();
if ((temp = l1["Unk"]).Object != null)
lit0.Unk = temp.RF32();
}
if ((l0 = l["SubData", true]).IsNull)
continue;
lit.C1 = l0.Array.Length;
for (i0 = 0; i0 < lit.C1; i0++)
{
ref LITX lit1 = ref lit.E1[i0];
lit1 = default;
MsgPack l1;
if ((l1 = l0[i0]).IsNull && l1.Array != null)
continue;
lit1.C = l1.Array.Length;
lit1.E = new KeyValuePair<int, int>[lit1.C];
for (int i1 = 0; i1 < lit1.C; i1++)
{
lit1.E[i1] = default;
MsgPack l2 = l1[i1];
MsgPack temp;
if ((temp = l2["Key"]).Object != null)
lit1.E[i1].Key = temp.RI32();
if ((temp = l2["Value"]).Object != null)
lit1.E[i1].Value = temp.RI32();
}
}
}
}
light.Dispose();
msgPack.Dispose();
}
public void MsgPackWriter(string file, bool json)
{
if (LITs.E == null || LITs.C < 1) return;
MsgPack light;
if (!IsX)
{
light = new MsgPack(LITs.C, "Light");
for (i = 0; i < LITs.C; i++)
{
ref LightStruct lit = ref LITs.E[i];
MsgPack l = MsgPack.New;
MsgPack l0 = new MsgPack(lit.C0, "MainData");
for (i0 = 0; i0 < lit.C0; i0++)
{
ref LIT lit0 = ref lit.E0[i0];
MsgPack l1 = MsgPack.New;
l1.Add("Id", lit0.Id);
if ((lit0.Flags & Flags.Type) != 0)
l1.Add("Type", (int)lit0.Type);
if ((lit0.Flags & Flags.Ambient) != 0)
l1.Add(new MsgPack("Ambient")
.Add("R", lit0.Ambient.X)
.Add("G", lit0.Ambient.Y)
.Add("B", lit0.Ambient.Z)
.Add("A", lit0.Ambient.W));
if ((lit0.Flags & Flags.Diffuse) != 0)
l1.Add(new MsgPack("Diffuse")
.Add("R", lit0.Diffuse.X)
.Add("G", lit0.Diffuse.Y)
.Add("B", lit0.Diffuse.Z)
.Add("A", lit0.Diffuse.W));
if ((lit0.Flags & Flags.Specular) != 0)
l1.Add(new MsgPack("Specular")
.Add("R", lit0.Specular.X)
.Add("G", lit0.Specular.Y)
.Add("B", lit0.Specular.Z)
.Add("A", lit0.Specular.W));
if ((lit0.Flags & Flags.Position) != 0)
l1.Add(new MsgPack("Position")
.Add("X", lit0.Position.X)
.Add("Y", lit0.Position.Y)
.Add("Z", lit0.Position.Z));
if ((lit0.Flags & Flags.ToneCurve) != 0)
l1.Add(new MsgPack("ToneCurve")
.Add("Begin" , lit0.ToneCurve.X)
.Add("End" , lit0.ToneCurve.Y)
.Add("BlendRate", lit0.ToneCurve.Z));
l0[i0] = l1;
}
l.Add(l0);
light[i] = l;
}
}
else
{
light = new MsgPack(LITs.C, "LightX");
for (i = 0; i < LITs.C; i++)
{
ref LightStruct lit = ref LITs.E[i];
MsgPack l = MsgPack.New;
MsgPack l0 = new MsgPack(lit.C0, "MainData");
for (i0 = 0; i0 < lit.C0; i0++)
{
ref LIT lit0 = ref lit.E0[i0];
MsgPack l1 = MsgPack.New;
l1.Add("Id", lit0.Id);
l1.Add("Flags", (int)lit0.Flags);
l1.Add("Type", (int)lit0.Type);
l1.Add(new MsgPack("Ambient")
.Add("R", lit0.Ambient.X)
.Add("G", lit0.Ambient.Y)
.Add("B", lit0.Ambient.Z)
.Add("A", lit0.Ambient.W));
l1.Add(new MsgPack("Diffuse")
.Add("R", lit0.Diffuse.X)
.Add("G", lit0.Diffuse.Y)
.Add("B", lit0.Diffuse.Z)
.Add("A", lit0.Diffuse.W));
l1.Add(new MsgPack("Specular")
.Add("R", lit0.Specular.X)
.Add("G", lit0.Specular.Y)
.Add("B", lit0.Specular.Z)
.Add("A", lit0.Specular.W));
l1.Add(new MsgPack("Position")
.Add("X", lit0.Position.X)
.Add("Y", lit0.Position.Y)
.Add("Z", lit0.Position.Z));
l1.Add(new MsgPack("ToneCurve")
.Add("Begin" , lit0.ToneCurve.X)
.Add("End" , lit0.ToneCurve.Y)
.Add("BlendRate", lit0.ToneCurve.Z));
if (lit0.HasStr)
l1.Add("Str", lit0.Str ?? "");
l1.Add("Unk01", lit0.Unk01);
l1.Add("Unk02", lit0.Unk02);
l1.Add("Unk03", lit0.Unk03);
l1.Add("Unk04", lit0.Unk04);
l1.Add(new MsgPack("Unk05")
.Add("X", lit0.Unk05.X)
.Add("Y", lit0.Unk05.Y)
.Add("Z", lit0.Unk05.Z));
l1.Add("Unk06", lit0.Unk06);
l1.Add("Unk07", lit0.Unk07);
l1.Add("Unk08", lit0.Unk08);
l1.Add("Unk10", lit0.Unk10);
l1.Add("Unk", lit0.Unk);
l0[i0] = l1;
}
l.Add(l0);
if (lit.C1 > 0)
{
l0 = new MsgPack(lit.C1, "SubData");
for (i0 = 0; i0 < lit.C1; i0++)
{
ref LITX lit1 = ref lit.E1[i0];
MsgPack l1 = new MsgPack(lit1.C);
for (int i1 = 0; i1 < lit1.C; i1++)
l1[i1] = MsgPack.New
.Add("Key" , lit1.E[i1].Key )
.Add("Value", lit1.E[i1].Value);
l0[i0] = l1;
}
l.Add(l0);
}
light[i] = l;
}
}
light.Write(false, true, file + "_light", json);
}
public void TXTWriter(string file)
{
i = 0;
if (LITs.C < 1) return;
s = File.OpenWriter();
s.WPSSJIS("Type,AmbientR,AmbientG,AmbientB,DiffuseR,DiffuseG,DiffuseB,SpecularR,SpecularG," +
"SpecularB,SpecularA,PosX,PosY,PosZ,ToneCurveBegin,ToneCurveEnd,ToneCurveBlendRate," +
(file.EndsWith("_chara") ? "コメント" : "ID") + "\n");
for (i0 = 0; i0 < LITs.E[i].C0; i0++)
s.W($"{LITs.E[i].E0[i0]},{i}\n");
File.WriteAllBytes($"{file}_light.txt", s.ToArray(true));
}
private bool disposed;
public void Dispose()
{ if (!disposed) { if (s != null) s.D(); s = null; LITs = default; IsX = false; disposed = true; } }
public struct LightStruct
{
public int C0 { get => E0 != null ? E0.Length : 0;
set => E0 = value > -1 ? new LIT[value] : null; }
public int O0;
public LIT[] E0;
public int C1 { get => E1 != null ? E1.Length : 0;
set => E1 = value > -1 ? new LITX[value] : default; }
public int O1;
public LITX[] E1;
public LIT this[int index]
{ get => E0 != null && index > -1 && index < E0.LongLength ? E0[index] : default;
set { if (E0 != null && index > -1 && index < E0.LongLength) E0[index] = value; } }
public LITX this[int index, bool x]
{ get => E1 != null && index > -1 && index < E1.LongLength ? E1[index] : default;
set { if (E1 != null && index > -1 && index < E1.LongLength) E1[index] = value; } }
public override string ToString() => C0 < 1 ? "No Entries" :
C0 == 1 ? E0[0].ToString() : "Count: " + C0;
}
public struct LIT
{
public int Id;
public Flags Flags;
public Type Type;
public string Str;
public bool HasStr;
public Vec4 Ambient;
public Vec4 Diffuse;
public Vec4 Specular;
public Vec3 Position;
public float Unk01;
public float Unk02;
public float Unk03;
public float Unk04;
public Vec3 Unk05;
public Vec3 ToneCurve;
public float Unk;
public float Unk06;
public float Unk07;
public float Unk08;
public int Unk10;
public override string ToString() => Flags == 0 ? ",,,,,,,,,,,,,,,," : $"{(Type)Type}," +
((Flags & Flags.Ambient ) != 0
? $"{Ambient .X.ToS(6)},{Ambient .Y.ToS(6)},{Ambient .Z.ToS(6)}," : ",,,") +
((Flags & Flags.Diffuse ) != 0
? $"{Diffuse .X.ToS(6)},{Diffuse .Y.ToS(6)},{Diffuse .Z.ToS(6)}," : ",,,") +
((Flags & Flags.Specular ) != 0
? $"{Specular .X.ToS(6)},{Specular .Y.ToS(6)},{Specular .Z.ToS(6)},{Specular .W.ToS(6)}," : ",,,,") +
((Flags & Flags.Position ) != 0
? $"{Position .X.ToS(6)},{Position .Y.ToS(6)},{Position .Z.ToS(6)}," : ",,,") +
((Flags & Flags.ToneCurve) != 0
? $"{ToneCurve.X.ToS(6)},{ToneCurve.Y.ToS(6)},{ToneCurve.Z.ToS(6)}" : ",,");
}
public enum Id : int
{
CHARA = 0x00,
STAGE = 0x01,
SUN = 0x02,
REFLECT = 0x03,
SHADOW = 0x04,
CHARA_COLOR = 0x05,
CHARA_F = 0x06,
PROJECTION = 0x07,
}
public enum Type : int
{
OFF = 0,
PARALLEL = 1,
POINT = 2,
SPOT = 3,
}
public enum Flags : int
{
Type = 0b00000000000000001,
Ambient = 0b00000000000000010,
Diffuse = 0b00000000000000100,
Specular = 0b00000000000001000,
Position = 0b00000000000010000,
ToneCurve = 0b00000001000000000,
}
}
public struct LITX
{
public int C;
public int O;
public KeyValuePair<int, int>[] E;
}
}