/// <summary> /// The scan map for lay out. /// </summary> /// <param name="map">The map.</param> /// <param name="addexternalchunks">The addexternalchunks.</param> /// <returns></returns> /// <remarks></remarks> public MapLayout ScanMapForLayOut(Map map, bool addexternalchunks) { MapLayout layout = new MapLayout(); for (int x = 0; x < map.BSP.sbsp.Length; x++) { LayOutChunk l = new LayOutChunk(0); l.rawType = RawDataContainerType.BSPMeta; l.startoffset = map.BSP.sbsp[x].offset; l.endoffset = map.BSP.sbsp[x].offset + map.BSP.sbsp[x].size; l.size = map.BSP.sbsp[x].size; layout.chunks.Add(l); } LayOutChunk lo = new LayOutChunk(0); lo.rawType = RawDataContainerType.Header; lo.startoffset = 0; lo.size = 2048; lo.endoffset = lo.startoffset + lo.size; layout.chunks.Add(lo); if (map.HaloVersion == HaloVersionEnum.Halo2 || map.HaloVersion == HaloVersionEnum.Halo2Vista) { lo = new LayOutChunk(0); lo.rawType = RawDataContainerType.StringsIndex; lo.startoffset = map.MapHeader.offsetToStringIndex; lo.size = map.MapHeader.scriptReferenceCount * 4; lo.size += map.Functions.Padding(lo.size, 512); lo.endoffset = lo.startoffset + lo.size; layout.chunks.Add(lo); lo = new LayOutChunk(0); lo.rawType = RawDataContainerType.Strings1; lo.startoffset = map.MapHeader.offsetToStringNames1; lo.size = map.MapHeader.scriptReferenceCount * 128; lo.size += map.Functions.Padding(lo.size, 512); lo.endoffset = lo.startoffset + lo.size; layout.chunks.Add(lo); lo = new LayOutChunk(0); lo.rawType = RawDataContainerType.Strings2; lo.startoffset = map.MapHeader.offsetToStringNames2; lo.size = map.MapHeader.sizeOfScriptReference; lo.size += map.Functions.Padding(lo.size, 512); lo.endoffset = lo.startoffset + lo.size; layout.chunks.Add(lo); lo = new LayOutChunk(0); lo.rawType = RawDataContainerType.Crazy; lo.startoffset = map.MapHeader.offsetToCrazy; lo.size = map.MapHeader.sizeOfCrazy; lo.size += map.Functions.Padding(lo.size, 512); lo.endoffset = lo.startoffset + lo.size; layout.chunks.Add(lo); lo = new LayOutChunk(0); lo.rawType = RawDataContainerType.FileNamesIndex; lo.startoffset = map.MapHeader.offsetTofileIndex; lo.size = map.MapHeader.fileCount * 4; lo.size += map.Functions.Padding(lo.size, 512); lo.endoffset = lo.startoffset + lo.size; layout.chunks.Add(lo); } lo = new LayOutChunk(0); lo.rawType = RawDataContainerType.FileNames; lo.startoffset = map.MapHeader.offsetTofileNames; lo.size = map.MapHeader.fileNamesSize; if (map.HaloVersion == HaloVersionEnum.Halo2 || map.HaloVersion == HaloVersionEnum.Halo2Vista) { lo.size += map.Functions.Padding(lo.size, 512); } lo.endoffset = lo.startoffset + lo.size; layout.chunks.Add(lo); lo = new LayOutChunk(0); lo.rawType = RawDataContainerType.MetaIndex; lo.startoffset = map.MapHeader.indexOffset; if (map.HaloVersion == HaloVersionEnum.Halo2 || map.HaloVersion == HaloVersionEnum.Halo2Vista) { lo.size = map.MapHeader.metaStart; lo.size += map.Functions.Padding(lo.size, 512); // map.MapHeader.fileSize - map.MapHeader.indexOffset; } else { lo.size = map.MapHeader.offsetTofileNames - map.MapHeader.indexOffset; // map.MetaInfo.Offset[map.IndexHeader.metaCount - 1] + map.MetaInfo.Size[map.IndexHeader.metaCount-1]; } lo.endoffset = lo.startoffset + lo.size; layout.chunks.Add(lo); lo = new LayOutChunk(0); lo.rawType = RawDataContainerType.MetaData; lo.startoffset = map.MetaInfo.Offset[0]; // How can you adjust for padding past the end of the file??? lo.size = map.MapHeader.fileSize - lo.startoffset; if (map.HaloVersion == HaloVersionEnum.Halo2 || map.HaloVersion == HaloVersionEnum.Halo2Vista) { int padding = map.Functions.Padding(lo.startoffset + lo.size, 4096); lo.size += padding; } lo.endoffset = lo.startoffset + lo.size; layout.chunks.Add(lo); if (map.HaloVersion == HaloVersionEnum.Halo2 || map.HaloVersion == HaloVersionEnum.Halo2Vista) { for (int x = 0; x < map.Unicode.ut.Length; x++) { lo = new LayOutChunk(0); lo.rawType = RawDataContainerType.UnicodeNamesIndex; lo.startoffset = map.Unicode.ut[x].indexOffset; lo.size = map.Unicode.ut[x].count * 8; lo.size += map.Functions.Padding(lo.size, 512); lo.endoffset = lo.startoffset + lo.size; layout.chunks.Add(lo); lo = new LayOutChunk(0); lo.rawType = RawDataContainerType.UnicodeNames; lo.startoffset = map.Unicode.ut[x].tableOffset; lo.size = map.Unicode.ut[x].tableSize; lo.size += map.Functions.Padding(lo.size, 512); lo.endoffset = lo.startoffset + lo.size; layout.chunks.Add(lo); } } map.OpenMap(MapTypes.Internal); for (int x = 0; x < map.IndexHeader.metaCount; x++) { if (map.HaloVersion == HaloVersionEnum.Halo2 || map.HaloVersion == HaloVersionEnum.Halo2Vista) { if (map.MetaInfo.TagType[x] == "snd!" | map.MetaInfo.TagType[x] == "ltmp") { continue; } Application.DoEvents(); } Meta m = new Meta(map); m.offset = map.MetaInfo.Offset[x]; // checks if type has raw data m.rawType = map.Functions.ForMeta.CheckForRaw(map.MetaInfo.TagType[x]); if (m.rawType != RawDataContainerType.Empty) { m.raw = map.Functions.ForMeta.ReadRaw(x, true); LayOutChunk l = new LayOutChunk(map.MapHeader.fileSize); int tempint = layout.FindByType(m.rawType); if (tempint == -1) { l = new LayOutChunk(map.MapHeader.fileSize); l.rawType = m.rawType; layout.chunks.Add(l); tempint = layout.FindByType(m.rawType); } else { l = (LayOutChunk)layout.chunks[tempint]; } for (int y = 0; y < m.raw.rawChunks.Count; y++) { RawDataChunk r = m.raw.rawChunks[y]; if (r.offset == -1) { continue; } if (r.rawLocation == MapTypes.Internal) { RawInfoChunk tempr = new RawInfoChunk(); tempr.offset = (uint)r.offset; tempr.size = r.size; tempr.rawType = r.rawDataType; tempr.location = r.rawLocation; tempr.offsetOfPointer = m.offset + r.pointerMetaOffset; l.rawPieces.Add(tempr); } else if (addexternalchunks) { RawInfoChunk tempr = new RawInfoChunk(); tempr.offset = (uint)r.offset; tempr.size = r.size; tempr.rawType = r.rawDataType; tempr.location = r.rawLocation; tempr.offsetOfPointer = m.offset + r.pointerMetaOffset; l.rawPieces.Add(tempr); } if (r.offset < l.startoffset && r.rawLocation == MapTypes.Internal) { l.startoffset = r.offset; l.size = l.endoffset - l.startoffset; layout.chunks[tempint] = l; } if (r.offset + r.size > l.endoffset && r.rawLocation == MapTypes.Internal) { l.endoffset = r.offset + r.size; l.endoffset += map.Functions.Padding(l.endoffset, 512); l.size = l.endoffset - l.startoffset; layout.chunks[tempint] = l; } } } m = null; GC.WaitForPendingFinalizers(); // GC.Collect(); } map.CloseMap(); if (map.HaloVersion == HaloVersionEnum.Halo2 || map.HaloVersion == HaloVersionEnum.Halo2Vista) { lo = new LayOutChunk(0); LayOutChunk templo = (LayOutChunk)layout.chunks[layout.FindByType(RawDataContainerType.Model)]; lo.rawType = RawDataContainerType.Sound; lo.startoffset = 2048; lo.size = templo.startoffset - 2048; lo.size += map.Functions.Padding(lo.size, 512); lo.endoffset = lo.startoffset + lo.size; layout.chunks.Add(lo); } for (int y = 0; y < layout.chunks.Count; y++) { LayOutChunk l = (LayOutChunk)layout.chunks[y]; if (l.size == 0) { layout.chunks.RemoveAt(y); y--; } } layout.SortChunksByOffset(); layout.SortRawByOffset(); return layout; }
/// <summary> /// The scan map for lay out. /// </summary> /// <param name="map">The map.</param> /// <param name="addexternalchunks">The addexternalchunks.</param> /// <returns></returns> /// <remarks></remarks> public MapLayout ScanMapForLayOut(Map map, bool addexternalchunks) { MapLayout layout = new MapLayout(); for (int x = 0; x < map.BSP.sbsp.Length; x++) { LayOutChunk l = new LayOutChunk(0); l.rawType = RawDataContainerType.BSPMeta; l.startoffset = map.BSP.sbsp[x].offset; l.endoffset = map.BSP.sbsp[x].offset + map.BSP.sbsp[x].size; l.size = map.BSP.sbsp[x].size; layout.chunks.Add(l); } LayOutChunk lo = new LayOutChunk(0); lo.rawType = RawDataContainerType.Header; lo.startoffset = 0; lo.size = 2048; lo.endoffset = lo.startoffset + lo.size; layout.chunks.Add(lo); if (map.HaloVersion == HaloVersionEnum.Halo2 || map.HaloVersion == HaloVersionEnum.Halo2Vista) { lo = new LayOutChunk(0); lo.rawType = RawDataContainerType.StringsIndex; lo.startoffset = map.MapHeader.offsetToStringIndex; lo.size = map.MapHeader.scriptReferenceCount * 4; lo.size += map.Functions.Padding(lo.size, 512); lo.endoffset = lo.startoffset + lo.size; layout.chunks.Add(lo); lo = new LayOutChunk(0); lo.rawType = RawDataContainerType.Strings1; lo.startoffset = map.MapHeader.offsetToStringNames1; lo.size = map.MapHeader.scriptReferenceCount * 128; lo.size += map.Functions.Padding(lo.size, 512); lo.endoffset = lo.startoffset + lo.size; layout.chunks.Add(lo); lo = new LayOutChunk(0); lo.rawType = RawDataContainerType.Strings2; lo.startoffset = map.MapHeader.offsetToStringNames2; lo.size = map.MapHeader.sizeOfScriptReference; lo.size += map.Functions.Padding(lo.size, 512); lo.endoffset = lo.startoffset + lo.size; layout.chunks.Add(lo); lo = new LayOutChunk(0); lo.rawType = RawDataContainerType.Crazy; lo.startoffset = map.MapHeader.offsetToCrazy; lo.size = map.MapHeader.sizeOfCrazy; lo.size += map.Functions.Padding(lo.size, 512); lo.endoffset = lo.startoffset + lo.size; layout.chunks.Add(lo); lo = new LayOutChunk(0); lo.rawType = RawDataContainerType.FileNamesIndex; lo.startoffset = map.MapHeader.offsetTofileIndex; lo.size = map.MapHeader.fileCount * 4; lo.size += map.Functions.Padding(lo.size, 512); lo.endoffset = lo.startoffset + lo.size; layout.chunks.Add(lo); } lo = new LayOutChunk(0); lo.rawType = RawDataContainerType.FileNames; lo.startoffset = map.MapHeader.offsetTofileNames; lo.size = map.MapHeader.fileNamesSize; if (map.HaloVersion == HaloVersionEnum.Halo2 || map.HaloVersion == HaloVersionEnum.Halo2Vista) { lo.size += map.Functions.Padding(lo.size, 512); } lo.endoffset = lo.startoffset + lo.size; layout.chunks.Add(lo); lo = new LayOutChunk(0); lo.rawType = RawDataContainerType.MetaIndex; lo.startoffset = map.MapHeader.indexOffset; if (map.HaloVersion == HaloVersionEnum.Halo2 || map.HaloVersion == HaloVersionEnum.Halo2Vista) { lo.size = map.MapHeader.metaStart; lo.size += map.Functions.Padding(lo.size, 512); // map.MapHeader.fileSize - map.MapHeader.indexOffset; } else { lo.size = map.MapHeader.offsetTofileNames - map.MapHeader.indexOffset; // map.MetaInfo.Offset[map.IndexHeader.metaCount - 1] + map.MetaInfo.Size[map.IndexHeader.metaCount-1]; } lo.endoffset = lo.startoffset + lo.size; layout.chunks.Add(lo); lo = new LayOutChunk(0); lo.rawType = RawDataContainerType.MetaData; lo.startoffset = map.MetaInfo.Offset[0]; // How can you adjust for padding past the end of the file??? lo.size = map.MapHeader.fileSize - lo.startoffset; if (map.HaloVersion == HaloVersionEnum.Halo2 || map.HaloVersion == HaloVersionEnum.Halo2Vista) { int padding = map.Functions.Padding(lo.startoffset + lo.size, 4096); lo.size += padding; } lo.endoffset = lo.startoffset + lo.size; layout.chunks.Add(lo); if (map.HaloVersion == HaloVersionEnum.Halo2 || map.HaloVersion == HaloVersionEnum.Halo2Vista) { for (int x = 0; x < map.Unicode.ut.Length; x++) { lo = new LayOutChunk(0); lo.rawType = RawDataContainerType.UnicodeNamesIndex; lo.startoffset = map.Unicode.ut[x].indexOffset; lo.size = map.Unicode.ut[x].count * 8; lo.size += map.Functions.Padding(lo.size, 512); lo.endoffset = lo.startoffset + lo.size; layout.chunks.Add(lo); lo = new LayOutChunk(0); lo.rawType = RawDataContainerType.UnicodeNames; lo.startoffset = map.Unicode.ut[x].tableOffset; lo.size = map.Unicode.ut[x].tableSize; lo.size += map.Functions.Padding(lo.size, 512); lo.endoffset = lo.startoffset + lo.size; layout.chunks.Add(lo); } } map.OpenMap(MapTypes.Internal); for (int x = 0; x < map.IndexHeader.metaCount; x++) { if (map.HaloVersion == HaloVersionEnum.Halo2 || map.HaloVersion == HaloVersionEnum.Halo2Vista) { if (map.MetaInfo.TagType[x] == "snd!" | map.MetaInfo.TagType[x] == "ltmp") { continue; } Application.DoEvents(); } Meta m = new Meta(map); m.offset = map.MetaInfo.Offset[x]; // checks if type has raw data m.rawType = map.Functions.ForMeta.CheckForRaw(map.MetaInfo.TagType[x]); if (m.rawType != RawDataContainerType.Empty) { m.raw = map.Functions.ForMeta.ReadRaw(x, true); LayOutChunk l = new LayOutChunk(map.MapHeader.fileSize); int tempint = layout.FindByType(m.rawType); if (tempint == -1) { l = new LayOutChunk(map.MapHeader.fileSize); l.rawType = m.rawType; layout.chunks.Add(l); tempint = layout.FindByType(m.rawType); } else { l = (LayOutChunk)layout.chunks[tempint]; } for (int y = 0; y < m.raw.rawChunks.Count; y++) { RawDataChunk r = m.raw.rawChunks[y]; if (r.offset == -1) { continue; } if (r.rawLocation == MapTypes.Internal) { RawInfoChunk tempr = new RawInfoChunk(); tempr.offset = (uint)r.offset; tempr.size = r.size; tempr.rawType = r.rawDataType; tempr.location = r.rawLocation; tempr.offsetOfPointer = m.offset + r.pointerMetaOffset; l.rawPieces.Add(tempr); } else if (addexternalchunks) { RawInfoChunk tempr = new RawInfoChunk(); tempr.offset = (uint)r.offset; tempr.size = r.size; tempr.rawType = r.rawDataType; tempr.location = r.rawLocation; tempr.offsetOfPointer = m.offset + r.pointerMetaOffset; l.rawPieces.Add(tempr); } if (r.offset < l.startoffset && r.rawLocation == MapTypes.Internal) { l.startoffset = r.offset; l.size = l.endoffset - l.startoffset; layout.chunks[tempint] = l; } if (r.offset + r.size > l.endoffset && r.rawLocation == MapTypes.Internal) { l.endoffset = r.offset + r.size; l.endoffset += map.Functions.Padding(l.endoffset, 512); l.size = l.endoffset - l.startoffset; layout.chunks[tempint] = l; } } } m = null; GC.WaitForPendingFinalizers(); // GC.Collect(); } map.CloseMap(); if (map.HaloVersion == HaloVersionEnum.Halo2 || map.HaloVersion == HaloVersionEnum.Halo2Vista) { lo = new LayOutChunk(0); LayOutChunk templo = (LayOutChunk)layout.chunks[layout.FindByType(RawDataContainerType.Model)]; lo.rawType = RawDataContainerType.Sound; lo.startoffset = 2048; lo.size = templo.startoffset - 2048; lo.size += map.Functions.Padding(lo.size, 512); lo.endoffset = lo.startoffset + lo.size; layout.chunks.Add(lo); } for (int y = 0; y < layout.chunks.Count; y++) { LayOutChunk l = (LayOutChunk)layout.chunks[y]; if (l.size == 0) { layout.chunks.RemoveAt(y); y--; } } layout.SortChunksByOffset(); layout.SortRawByOffset(); return(layout); }