using System; namespace NW4RTools { public struct GXIndexedVertex { public int Position; public int Normal; public int[] Colors; public int[] TexCoords; public void LoadFrom(InputStream ins, VertexSettings vs) { if (vs.PNMatrixIndexExists) throw new NotImplementedException(); if (vs.TexCoordMatrixIndexExists[0]) throw new NotImplementedException(); // won't bother with the rest switch (vs.PositionDesc) { case VertexSettings.DescType.Direct: throw new NotImplementedException(); case VertexSettings.DescType.None: throw new NotImplementedException(); case VertexSettings.DescType.Index8: Position = ins.ReadByte(); if (Position == 0xFF) Position = -1; break; case VertexSettings.DescType.Index16: Position = ins.ReadUInt16(); if (Position == 0xFFFF) Position = -1; break; } // not sure how to detect NBT3 yet switch (vs.NormalDesc) { case VertexSettings.DescType.Direct: throw new NotImplementedException(); case VertexSettings.DescType.None: Normal = -1; break; case VertexSettings.DescType.Index8: Normal = ins.ReadByte(); if (Normal == 0xFF) Normal = -1; break; case VertexSettings.DescType.Index16: Normal = ins.ReadUInt16(); if (Normal == 0xFFFF) Normal = -1; break; } Colors = new int[2]; for (int i = 0; i < 2; i++) { switch (vs.ColorDesc[i]) { case VertexSettings.DescType.Direct: throw new NotImplementedException(); case VertexSettings.DescType.None: Colors[i] = -1; break; case VertexSettings.DescType.Index8: Colors[i] = ins.ReadByte(); if (Colors[i] == 0xFF) Colors[i] = -1; break; case VertexSettings.DescType.Index16: Colors[i] = ins.ReadUInt16(); if (Colors[i] == 0xFFFF) Colors[i] = -1; break; } } TexCoords = new int[8]; for (int i = 0; i < 8; i++) { switch (vs.TexCoordDesc[i]) { case VertexSettings.DescType.Direct: throw new NotImplementedException(); case VertexSettings.DescType.None: TexCoords[i] = -1; break; case VertexSettings.DescType.Index8: TexCoords[i] = ins.ReadByte(); if (TexCoords[i] == 0xFF) TexCoords[i] = -1; break; case VertexSettings.DescType.Index16: TexCoords[i] = ins.ReadUInt16(); if (TexCoords[i] == 0xFFFF) TexCoords[i] = -1; break; } } } } public class VertexSettings { public enum DescType { None, Direct, Index8, Index16 } public enum CompCount { Position2 = 0, Position3 = 1, Normal3 = 0, NBT = 1, NBT3 = 2, Color3 = 0, Color4 = 1, TexCoord1 = 0, TexCoord2 = 1 } public enum CompType { UInt8 = 0, Int8 = 1, UInt16 = 2, Int16 = 3, Float32 = 4 } public enum CompClrType { RGB565 = 0, RGB8 = 1, RGBX8 = 2, RGBA4 = 3, RGBA6 = 4, RGBA8 = 5 } public bool PNMatrixIndexExists; public bool[] TexCoordMatrixIndexExists; public DescType PositionDesc, NormalDesc; public DescType[] ColorDesc, TexCoordDesc; public CompCount PositionCount, NormalCount; public CompCount[] ColorCount, TexCoordCount; public CompType PositionFormat, NormalFormat; public CompClrType[] ColorFormat; public CompType[] TexCoordFormat; public byte PositionFrac; public byte[] TexCoordFrac; public VertexSettings() { TexCoordMatrixIndexExists = new bool[8]; ColorDesc = new DescType[2]; TexCoordDesc = new DescType[8]; ColorCount = new CompCount[2]; TexCoordCount = new CompCount[8]; ColorFormat = new CompClrType[2]; TexCoordFormat = new CompType[8]; TexCoordFrac = new byte[8]; } public void SetDesc(UInt32 val1, UInt32 val2) { PNMatrixIndexExists = ((val1 & 1) != 0); for (int i = 0; i < 8; i++) TexCoordMatrixIndexExists[i] = ((val1 & (2 << i)) != 0); PositionDesc = (DescType)((val1 & 0x600) >> 9); NormalDesc = (DescType)((val1 & 0x1800) >> 11); ColorDesc[0] = (DescType)((val1 & 0x6000) >> 13); ColorDesc[1] = (DescType)((val1 & 0x18000) >> 15); for (int i = 0; i < 8; i++) TexCoordDesc[i] = (DescType)((val2 & (3 << (i * 2))) >> (i * 2)); } public void SetAttrFmt(UInt32 val1, UInt32 val2, UInt32 val3) { PositionCount = (CompCount)(val1 & 1); PositionFormat = (CompType)((val1 & 0xE) >> 3); PositionFrac = (byte)((val1 & 0x1F0) >> 4); // note: this field is special bool IsNormalSet = ((val1 & 0x200) != 0); bool UseNormalIndex3 = ((val1 & 0x80000000) != 0); NormalCount = IsNormalSet ? (UseNormalIndex3 ? CompCount.NBT3 : CompCount.NBT) : CompCount.Normal3; NormalFormat = (CompType)((val1 & 0x1C00) >> 10); ColorCount[0] = (CompCount)((val1 & 0x2000) >> 13); ColorFormat[0] = (CompClrType)((val1 & 0x1C000) >> 14); ColorCount[1] = (CompCount)((val1 & 0x20000) >> 17); ColorFormat[1] = (CompClrType)((val1 & 0x1C0000) >> 18); TexCoordCount[0] = (CompCount)((val1 & 0x200000) >> 21); TexCoordFormat[0] = (CompType)((val1 & 0x1C00000) >> 22); TexCoordFrac[0] = (byte)((val1 & 0x3E000000) >> 25); // set in various cases, see libogc gx.c for info bool ByteDequant = ((val1 & 0x40000000) != 0); TexCoordCount[1] = (CompCount)(val2 & 0x1); TexCoordFormat[1] = (CompType)((val2 & 0xE) >> 1); TexCoordFrac[1] = (byte)((val2 & 0x1F0) >> 4); TexCoordCount[2] = (CompCount)((val2 & 0x200) >> 9); TexCoordFormat[2] = (CompType)((val2 & 0x1C00) >> 10); TexCoordFrac[2] = (byte)((val2 & 0x3E000) >> 13); TexCoordCount[3] = (CompCount)((val2 & 0x40000) >> 18); TexCoordFormat[3] = (CompType)((val2 & 0x380000) >> 19); TexCoordFrac[3] = (byte)((val2 & 0x3E000000) >> 22); TexCoordCount[4] = (CompCount)((val2 & 0x8000000) >> 27); TexCoordFormat[4] = (CompType)((val2 & 0x70000000) >> 28); TexCoordFrac[4] = (byte)(val3 & 0x1F); TexCoordCount[5] = (CompCount)((val3 & 0x20) >> 5); TexCoordFormat[5] = (CompType)((val3 & 0x1C0) >> 6); TexCoordFrac[5] = (byte)((val3 & 0x3E00) >> 9); TexCoordCount[6] = (CompCount)((val3 & 0x4000) >> 14); TexCoordFormat[6] = (CompType)((val3 & 0x38000) >> 15); TexCoordFrac[6] = (byte)((val3 & 0x7C0000) >> 18); TexCoordCount[7] = (CompCount)((val3 & 0x800000) >> 23); TexCoordFormat[7] = (CompType)((val3 & 0x7000000) >> 24); TexCoordFrac[7] = (byte)((val3 & 0xF8000000) >> 27); } } }