public void Load(string adtFileName, string wdtFileName) { WdtFile = new WDT.WDT(); WdtFile.Load(wdtFileName); using (var reader = new BinaryReader(File.OpenRead(adtFileName))) { while (reader.BaseStream.Position < reader.BaseStream.Length) { var chunkName = new string(reader.ReadChars(4).Reverse().ToArray()); var chunkSize = reader.ReadInt32(); var chunkType = Type.GetType(chunkName); if (chunkType != null) { // If chunkType is an array, it can only be MCNK if (chunkType.IsArray) { MCNK[MCNK.Count(c => c != null)] = (MCNK)Activator.CreateInstance(typeof(MCNK), reader.ReadBytes(chunkSize), WdtFile); } else { GetType().GetProperty(chunkName)?.SetValue(this, Activator.CreateInstance(chunkType, reader.ReadBytes(chunkSize))); } } } } }
public MCAL(byte[] chunkBytes, MCNK parentChunk, WDT.WDT wdt) : base(chunkBytes) { AlphaMaps = new MCALAlphaMap[parentChunk.MCLY.Layers.Length]; for (int i = 0; i < parentChunk.MCLY.Layers.Length; i++) { AlphaMaps[i] = new MCALAlphaMap(this, parentChunk, wdt, i); } Close(); }
public byte[] GetChunkBytes(MCNK parentChunk, WDT.WDT wdt) { using (var stream = new MemoryStream()) { using (var writer = new BinaryWriter(stream)) { for (int i = 0; i < AlphaMaps.Length; i++) { AlphaMaps[i].Write(writer, parentChunk, wdt, i); } } return(stream.ToArray()); } }
public void Write(BinaryWriter writer, MCNK parentChunk, WDT.WDT wdt, int currentLayer) { if (parentChunk.MCLY.Layers[currentLayer].Flags.HasFlag(MCLYFlags.CompressedAlphaMap) && (wdt.MPHD.Flags.HasFlag(MPHDFlags.HasBigAlpha) || wdt.MPHD.Flags.HasFlag(MPHDFlags.MCALSize4096))) { // Compressed var positionInAlphaMap = 0; var tempAlphaMap = new byte[4096]; while (positionInAlphaMap < 4096) { var info = AlphaMap[positionInAlphaMap % 64, positionInAlphaMap / 64]; tempAlphaMap[positionInAlphaMap] = info; positionInAlphaMap += 1; var mode = (info & 0x80) >> 7; var count = info & 0x7F; // Copy mode if (mode == 0) { for (int j = 0; j < count - 1; j++) { tempAlphaMap[positionInAlphaMap + j] = AlphaMap[positionInAlphaMap % 64 + j, positionInAlphaMap / 64 + j]; } } else // Fill mode { var data = AlphaMap[positionInAlphaMap % 64, positionInAlphaMap / 64]; for (int j = 0; j < count; j++) { tempAlphaMap[positionInAlphaMap + j] = data; } } positionInAlphaMap += count; } writer.Write(tempAlphaMap); } else if (wdt.MPHD.Flags.HasFlag(MPHDFlags.HasBigAlpha) || wdt.MPHD.Flags.HasFlag(MPHDFlags.MCALSize4096)) { // Uncompressed (4096) for (int y = 0; y < 64; y++) { for (int x = 0; x < 64; x++) { writer.Write(AlphaMap[x, y]); } } } else { // Uncompressed (2048) - TODO build in FLAG_DO_NOT_FIX_ALPHA_MAP if (parentChunk.Flags.HasFlag(MCNKFlags.DoNotFixAlphaMap)) { for (int y = 0; y < 63; y++) { for (int x = 0; x < 63; x += 2) { var byte1 = AlphaMap[x, y]; var byte2 = AlphaMap[x + 1, y]; byte fullByte = 0; fullByte = (byte)(fullByte | byte1 << 4); fullByte = (byte)(fullByte | byte2); writer.Write(fullByte); } if (y == 62) { var byte1 = AlphaMap[] } } } else { for (int y = 0; y < 64; y++) { for (int x = 0; x < 64; x += 2) { var byte1 = AlphaMap[x, y]; var byte2 = AlphaMap[x + 1, y]; byte fullByte = 0; fullByte = (byte)(fullByte | byte1 << 4); fullByte = (byte)(fullByte | byte2); writer.Write(fullByte); } } } } }
public MCALAlphaMap(BinaryReader reader, MCNK parentChunk, WDT.WDT wdt, int currentLayer) { if (parentChunk.MCLY.Layers[currentLayer].Flags.HasFlag(MCLYFlags.CompressedAlphaMap) && (wdt.MPHD.Flags.HasFlag(MPHDFlags.HasBigAlpha) || wdt.MPHD.Flags.HasFlag(MPHDFlags.MCALSize4096))) { // Compressed var positionInAlphaMap = 0; var tempAlphaMap = new byte[4096]; while (positionInAlphaMap < 4096) { var info = reader.ReadByte(); var mode = (info & 0x80) >> 7; var count = info & 0x7F; // Copy mode if (mode == 0) { for (int j = 0; j < count; j++) { tempAlphaMap[positionInAlphaMap + j] = reader.ReadByte(); } } else // Fill mode { var data = reader.ReadByte(); for (int j = 0; j < count; j++) { tempAlphaMap[positionInAlphaMap + j] = data; } } positionInAlphaMap += count; } for (int y = 0; y < 64; y++) { for (int x = 0; x < 64; x++) { AlphaMap[x, y] = tempAlphaMap[x * 64 + y]; } } } else if (wdt.MPHD.Flags.HasFlag(MPHDFlags.HasBigAlpha) || wdt.MPHD.Flags.HasFlag(MPHDFlags.MCALSize4096)) { // Uncompressed (4096) for (int y = 0; y < 64; y++) { for (int x = 0; x < 64; x++) { AlphaMap[x, y] = reader.ReadByte(); } } } else { // Uncompressed (2048) - TODO: build in FLAG_DO_NOT_FIX_ALPHA_MAP for (int y = 0; y < 64; y++) { for (int x = 0; x < 64; x += 2) { var fullByte = reader.ReadByte(); byte lowBits = (byte)(fullByte & 0x0F); byte highBits = (byte)(fullByte >> 4); AlphaMap[x, y] = highBits; AlphaMap[x + 1, y] = lowBits; } } } }
public MCNK(byte[] chunkBytes, WDT.WDT wdt) : base(chunkBytes) { Flags = (MCNKFlags)ReadUInt32(); Index = this.ReadVector2UInt(); Layers = ReadUInt32(); NumberDoodadRefs = ReadUInt32(); OffsetMCVT = ReadUInt32(); OffsetMCNR = ReadUInt32(); OffsetMCLY = ReadUInt32(); OffsetMCRF = ReadUInt32(); OffsetMCAL = ReadUInt32(); SizeAlpha = ReadUInt32(); OffsetMCSH = ReadUInt32(); SizeShadow = ReadUInt32(); AreaId = ReadUInt32(); NumberMapObjectRefs = ReadUInt32(); Holes = ReadUInt16(); HolesPadding = ReadUInt16(); // Maybe change this to two longs like in https://bitbucket.org/mugadr_m/kotlin-wow/src/378f3fdec7fff325f52560fc2cce64c946cf57ab/editor/src/main/kotlin/ch/cromon/wow/io/files/map/wotlk/MapChunk.kt?at=master&fileviewer=file-view-default#MapChunk.kt-37 for (int i = 0; i < 16; i++) { ReallyLowQualityTextureingMap[i] = ReadByte(); } PredTex = ReadUInt32(); NumberEffectDoodads = ReadUInt32(); OffsetMCSE = ReadUInt32(); NumberSoundEmitters = ReadUInt32(); OffsetMCLQ = ReadUInt32(); SizeLiquid = ReadUInt32(); Position = this.ReadVector3Float(); OffsetMCCV = ReadUInt32(); Unused1 = ReadUInt32(); Unused2 = ReadUInt32(); if (OffsetMCVT > 0) { BaseStream.Position = OffsetMCVT; MCVT = new MCVT(ReadBytes((int)MCVT.ChunkSize)); } if (OffsetMCNR > 0) { BaseStream.Position = OffsetMCNR; MCNR = new MCNR(ReadBytes((int)MCNR.ChunkSize)); } if (OffsetMCLY > 0) { BaseStream.Position = OffsetMCLY; MCLY = new MCLY(ReadBytes((int)MCLY.ChunkSize)); } if (OffsetMCRF > 0) { BaseStream.Position = OffsetMCRF; MCRF = new MCRF(ReadBytes((int)MCRF.ChunkSize), this); } // TODO: && No WDT file? if (OffsetMCAL > 0 && wdt != null) { BaseStream.Position = OffsetMCAL; MCAL = new MCAL(ReadBytes((int)MCAL.ChunkSize), this, wdt); } if (OffsetMCSH > 0 && SizeShadow > 8 && Flags.HasFlag(MCNKFlags.HasMCSH)) { BaseStream.Position = OffsetMCSH; MCSH = new MCSH(ReadBytes((int)MCSH.ChunkSize)); } if (OffsetMCSE > 0 && NumberSoundEmitters > 0) { BaseStream.Position = OffsetMCSE; MCSE = new MCSE(ReadBytes((int)MCSE.ChunkSize), this); } if (OffsetMCLQ > 0 && SizeLiquid > 0) { BaseStream.Position = OffsetMCLQ; MCLQ = new MCLQ(ReadBytes((int)MCLQ.ChunkSize), this); } if (OffsetMCCV > 0) { BaseStream.Position = OffsetMCCV; MCCV = new MCCV(ReadBytes((int)MCCV.ChunkSize)); } Close(); }