/// <summary> /// Loads the texture layer information (MCLY) from the file and for each layer the corresponding AlphaData. /// </summary> private void LoadLayers() { mTexFile.Position = mOffset.OffsetTexStream + 4; byte[] chunkData = new byte[mTexFile.Read <uint>()]; mTexFile.Read(chunkData, 0, chunkData.Length); MemoryStream memStrm = new MemoryStream(chunkData); SeekChunk(memStrm, "YLCM"); mTexFile.Position = mOffset.OffsetTexStream + 8 + memStrm.Position + 4; uint size = mTexFile.Read <uint>(); mHeader.nLayers = (uint)(size / Marshal.SizeOf(typeof(MCLY))); for (uint i = 0; i < mHeader.nLayers; ++i) { MCLY layer = mTexFile.Read <MCLY>(); mLayers.Add(layer); } if (mHeader.nLayers > 1) { try { SeekChunk(memStrm, "LACM"); BinaryReader readr = new BinaryReader(memStrm); size = readr.ReadUInt32(); mTexFile.Position = mOffset.OffsetTexStream + 8 + memStrm.Position; } catch (Exception) { mHeader.nLayers = 1; } } LoadAlpha(); }
/// <summary> /// Loads the alphadata for each layer according to the flags. It also loads the hole bitmap and the shadows. /// </summary> private void LoadAlpha() { bool loadFixed = (mHeader.flags & 0x8000) != 0; if (Header.nLayers > 1) { uint alphaSize = mTexFile.Read <uint>(); byte[] alphaChunk = new byte[alphaSize]; mTexFile.Read(alphaChunk, 0, alphaChunk.Length); for (int j = 1; j < Header.nLayers; ++j) { if ((mLayers[j].flags & 0x200) != 0) { MCLY ly = mLayers[j]; byte[] alpha = decompressAlpha2(4096, ref ly.ofsMCAL, alphaChunk); for (int k = 0; k < 4096; ++k) { AlphaData[k * 4 + j - 1] = alpha[k]; } } else if ((mLayers[j].flags & 0x100) != 0) { MCLY ly = mLayers[j]; for (int k = 0; k < 4096; ++k) { AlphaData[k * 4 + j - 1] = alphaChunk[ly.ofsMCAL + k]; } } else { for (int k = 0; k < 4096; ++k) { AlphaData[k * 4 + j - 1] = 0; } } } } for (int i = 0; i < 64; ++i) { for (int j = 0; j < 64; ++j) { float x = i * ADTStaticData.HoleSize; float y = j * ADTStaticData.HoleSize; uint stepx = (uint)Math.Floor(x / ADTStaticData.HoleLen); uint stepy = (uint)Math.Floor(y / ADTStaticData.HoleLen); byte factor = (byte)((mHeader.holes & (ADTStaticData.HoleBitmap[stepx, stepy])) != 0 ? 0 : 1); int baseIndex = (i * 64 + j) * 4; byte remain = (byte)(255 - AlphaData[baseIndex] - AlphaData[baseIndex + 1] - AlphaData[baseIndex + 2]); AlphaData[(i * 64 + j) * 4 + 3] = (byte)(remain * factor); } } }