public bool AsyncLoad(BinaryReader reader, ChunkInfo chunkInfo) { // chunkInfo.Offset points to right after the MCNK signature, the offsets in the header are relative to the signature tho var basePosition = chunkInfo.Offset - 4; reader.BaseStream.Position = chunkInfo.Offset; reader.ReadInt32(); mHeader = reader.Read<Mcnk>(); reader.BaseStream.Position = basePosition + mHeader.Mcvt; var signature = reader.ReadUInt32(); reader.ReadInt32(); if (signature != 0x4D435654) { Log.Error("Chunk is missing valid MCVT sub chunk"); return false; } LoadMcvt(reader); reader.BaseStream.Position = basePosition + mHeader.Mcnr; signature = reader.ReadUInt32(); reader.ReadInt32(); if (signature != 0x4D434E52) { Log.Error("Chunk is missing valid MCNR sub chunk"); return false; } LoadMcnr(reader); if(mHeader.Mcrf > 0) { reader.BaseStream.Position = basePosition + mHeader.Mcrf; signature = reader.ReadUInt32(); var chunkSize = reader.ReadInt32(); if (signature == 0x4D435246) LoadReferences(reader, chunkSize); } var hasMccv = false; if (mHeader.Mccv != 0) { reader.BaseStream.Position = basePosition + mHeader.Mccv; signature = reader.ReadUInt32(); reader.ReadInt32(); if (signature == 0x4D434356) { LoadMccv(reader); hasMccv = true; HasMccv = true; } } reader.BaseStream.Position = basePosition + mHeader.Mcly; signature = reader.ReadUInt32(); var size = reader.ReadInt32(); if (signature != 0x4D434C59) return false; LoadLayers(reader, size); if (mHeader.SizeAlpha > 8) { reader.BaseStream.Position = basePosition + mHeader.Mcal; signature = reader.ReadUInt32(); if (signature == 0x4D43414C) { reader.ReadInt32(); mAlphaCompressed = reader.ReadBytes(mHeader.SizeAlpha - 8); } } InitLayerData(); if(mHeader.SizeShadow > 8 && mHeader.Mcsh > 0) { reader.BaseStream.Position = basePosition + mHeader.Mcsh + 8; var curPtr = 0; for (var i = 0; i < 64; ++i) { for (var j = 0; j < 8; ++j) { byte mask = reader.ReadByte(); for (var k = 0; k < 8; ++k) { AlphaValues[curPtr] &= 0xFFFFFF00; AlphaValues[curPtr++] |= ((mask & (1 << k)) == 0) ? (byte)0xFF : (byte)0xCC; } } } } if(mHeader.Mclv > 0) { reader.BaseStream.Position = basePosition + mHeader.Mclv + 8; var colors = reader.ReadArray<uint>(145); for (var i = 0; i < 145; ++i) Vertices[i].AdditiveColor = colors[i]; } LoadHoles(); if (hasMccv == false) { for (var i = 0; i < 145; ++i) Vertices[i].Color = 0x7F7F7F7F; } if (mHeader.Mcrf > 0) LoadUnusedChunk(0x4D435246, basePosition + mHeader.Mcrf, (mHeader.NumDoodadRefs + mHeader.NumMapObjRefs) * 4, reader); if (mHeader.SizeShadow > 0) LoadUnusedChunk(0x4D435348, basePosition + mHeader.Mcsh, mHeader.SizeShadow, reader); if (mHeader.NumSoundEmitters > 0) LoadUnusedChunk(0x4D435345, basePosition + mHeader.Mcse, mHeader.NumSoundEmitters * 0x1C, reader); if (mHeader.SizeLiquid > 8) LoadUnusedChunk(0x4D434C51, basePosition + mHeader.Mclq, mHeader.SizeLiquid - 8, reader); if (mHeader.Mclv > 0) LoadUnusedChunk(0x4D434C56, basePosition + mHeader.Mclv, 0, reader); WorldFrame.Instance.MapManager.OnLoadProgress(); return true; }
public bool AsyncLoad(BinaryReader reader, ChunkInfo chunkInfo) { // chunkInfo.Offset points to right after the MCNK signature, the offsets in the header are relative to the signature tho var basePosition = chunkInfo.Offset - 4; reader.BaseStream.Position = chunkInfo.Offset; reader.ReadInt32(); mHeader = reader.Read <Mcnk>(); reader.BaseStream.Position = basePosition + mHeader.Mcvt; var signature = reader.ReadUInt32(); reader.ReadInt32(); if (signature != 0x4D435654) { Log.Error("Chunk is missing valid MCVT sub chunk"); return(false); } LoadMcvt(reader); reader.BaseStream.Position = basePosition + mHeader.Mcnr; signature = reader.ReadUInt32(); reader.ReadInt32(); if (signature != 0x4D434E52) { Log.Error("Chunk is missing valid MCNR sub chunk"); return(false); } LoadMcnr(reader); if (mHeader.Mcrf > 0) { reader.BaseStream.Position = basePosition + mHeader.Mcrf; signature = reader.ReadUInt32(); var chunkSize = reader.ReadInt32(); if (signature == 0x4D435246) { LoadReferences(reader, chunkSize); } } var hasMccv = false; if (mHeader.Mccv != 0) { reader.BaseStream.Position = basePosition + mHeader.Mccv; signature = reader.ReadUInt32(); reader.ReadInt32(); if (signature == 0x4D434356) { LoadMccv(reader); hasMccv = true; HasMccv = true; } } reader.BaseStream.Position = basePosition + mHeader.Mcly; signature = reader.ReadUInt32(); var size = reader.ReadInt32(); if (signature != 0x4D434C59) { return(false); } LoadLayers(reader, size); if (mHeader.SizeAlpha > 8) { reader.BaseStream.Position = basePosition + mHeader.Mcal; signature = reader.ReadUInt32(); if (signature == 0x4D43414C) { reader.ReadInt32(); mAlphaCompressed = reader.ReadBytes(mHeader.SizeAlpha - 8); } } InitLayerData(); if (mHeader.SizeShadow > 8 && mHeader.Mcsh > 0) { reader.BaseStream.Position = basePosition + mHeader.Mcsh + 8; var curPtr = 0; for (var i = 0; i < 64; ++i) { for (var j = 0; j < 8; ++j) { var mask = reader.ReadByte(); for (var k = 0; k < 8; ++k) { AlphaValues[curPtr] &= 0xFFFFFF00; AlphaValues[curPtr++] |= ((mask & (1 << k)) == 0) ? (byte)0xFF : (byte)0xCC; } } } } if (mHeader.Mclv > 0) { reader.BaseStream.Position = basePosition + mHeader.Mclv + 8; var colors = reader.ReadArray <uint>(145); for (var i = 0; i < 145; ++i) { Vertices[i].AdditiveColor = colors[i]; } } LoadHoles(); LoadGroundEffectLayers(); if (hasMccv == false) { for (var i = 0; i < 145; ++i) { Vertices[i].Color = 0x7F7F7F7F; } } if (mHeader.Mcrf > 0) { LoadUnusedChunk(0x4D435246, basePosition + mHeader.Mcrf, (mHeader.NumDoodadRefs + mHeader.NumMapObjRefs) * 4, reader); } if (mHeader.SizeShadow > 0) { LoadUnusedChunk(0x4D435348, basePosition + mHeader.Mcsh, mHeader.SizeShadow, reader); } LoadUnusedChunk(0x4D435345, basePosition + mHeader.Mcse, mHeader.NumSoundEmitters * 0x1C, reader); if (mHeader.SizeLiquid > 8) { LoadUnusedChunk(0x4D434C51, basePosition + mHeader.Mclq, mHeader.SizeLiquid - 8, reader); } if (mHeader.Mclv > 0) { LoadUnusedChunk(0x4D434C56, basePosition + mHeader.Mclv, 0, reader); } WorldFrame.Instance.MapManager.OnLoadProgress(); return(true); }