Since I already received about 5 PMs regarding how to implement the stuff I explained rather detailed, here is some code.
When parsing the MCNK chunk, set your Holes field, which is a byte array, like this:
Code:
// McnkHeader* mcnk = ...;
_flags = mcnk->Flags;
Holes = _flags.HasFlag(McnkHeaderFlags.HighResHoleMap) ? mcnk->HighResHoles : TransformToHighRes(mcnk->Holes);
Code:
private static byte[] TransformToHighRes(ushort holes)
{
var ret = new byte[8];
for (int i = 0; i < 8; i++)
{
for (int j = 0; j < 8; j++)
{
int holeIdxL = (i/2)*4 + (j/2);
if (((holes >> holeIdxL) & 1) == 1)
ret[i] |= (byte)(1 << j);
}
}
return ret;
}
And finally you check for holes like:
Code:
public bool HasHole(int col, int row)
{
return ((Holes[row] >> col) & 1) == 1;
}
By the way, this is my MCNK header struct and the flags enum:
Code:
[Flags]
private enum McnkHeaderFlags : uint
{
HighResHoleMap = 0x10000
}
private struct McnkHeader
{
public McnkHeaderFlags Flags;
public int X;
public int Y;
int nLayers;
int nDoodadRefs;
uint offMcvt; // 0x14
uint offMcnr; // 0x18
int offMcly;
int offMcrf;
int offMcal;
int sizeAlpha;
int offMcsh;
int sizeShadow;
int areaId;
int nMapObjRefs;
public ushort Holes;
ushort HolesAlign;
unsafe fixed short lowQualityTexturingMap [8];
int predTex;
int noEffectDoodad;
int offMcse;
int nSoundEmitters;
int offMclq;
int sizeLiquid;
public Vector3 Position;
int offMccv;
unsafe fixed int pad[2];
public byte[] HighResHoles { get { return BitConverter.GetBytes(offMcvt + ((ulong)offMcnr << 32)); } } // 0x14
}
For C++, it's as easy as declaring (offMsvt+offMcnr)|HighResHoles as a union. Didn't want to add FieldOffset for every field here.