Files
ReverseEngineeringTools/HogsOfWarTools/Unity/Assets/PmgFile.cs
T

86 lines
2.5 KiB
C#
Raw Normal View History

2025-05-13 03:10:33 +03:00
using System.Collections.Generic;
using System;
using System.Runtime.InteropServices;
public class PmgFile {
[Serializable]
[StructLayout(LayoutKind.Sequential, Pack = 1)]
public class PmgBlock {
[Serializable]
[StructLayout(LayoutKind.Sequential, Pack = 1)]
public struct Vertex {
public short height; // height sample
public short lighting; // <= 255
}
[Serializable]
[StructLayout(LayoutKind.Sequential, Pack = 1)]
public struct Tile {
[Flags]
public enum Transform : byte {
FlipX = 1,
Rotate90 = 2,
Rotate180 = 4
}
public enum Slip : byte {
Full = 0,
Bottom = 1,
Left = 2,
Top = 3,
Right = 4,
BottomRight = 5,
BottomLeft = 6,
TopLeft = 7,
TopRight = 8
}
public short Field0; // always 0 -> obsolete xOffset?
public short Field1; // always 0 -> obsolete yOffset?
public short Field2; // always 0 -> obsolete zOffset?
public char Type;
public Slip slip;
public short Field3;
public Transform RotationFlip;
public int TextureIndex;
public char Field4;
}
public short xOffset; // -16384 ~ 16384
public short yOffset; // unreliable?
public short zOffset; // -16384 ~ 16384
public short Field0;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 25)]
public Vertex[] vertices;
public int Field1;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 16)]
public Tile[] tiles;
}
public PmgBlock[] Blocks;
public static PmgFile Parse(byte[] data) {
PmgFile result = new PmgFile();
var blockSize = Marshal.SizeOf(typeof(PmgBlock));
int blockCount = data.Length / blockSize;
var handle = GCHandle.Alloc(data, GCHandleType.Pinned);
var ptr = handle.AddrOfPinnedObject();
List<PmgBlock> blocks = new List<PmgBlock>();
for (int Block = 0; Block < blockCount; Block++) {
blocks.Add(Marshal.PtrToStructure<PmgBlock>(ptr));
ptr += blockSize;
}
handle.Free();
result.Blocks = blocks.ToArray();
return result;
}
}