Template
86 lines
2.5 KiB
C#
86 lines
2.5 KiB
C#
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;
|
|
}
|
|
}
|