private void CombinedExtractTag(int index) { FileStream fsBitmap = null; FileStream fsSound = null; FileStream fsShared = null; FileStream fsSinglePlayerShared = null; FileStream fsMainMenu = null; switch (m_MapVersion) { case MapfileVersion.HALOPC: case MapfileVersion.HALOCE: fsBitmap = OptionsManager.GetBitmapStream(m_MapVersion); fsSound = OptionsManager.GetSoundStream(m_MapVersion); break; case MapfileVersion.XHALO2: fsShared = OptionsManager.GetHalo2SharedStream(); fsSinglePlayerShared = OptionsManager.GetHalo2SinglePlayerSharedStream(); fsMainMenu = OptionsManager.GetHalo2MainMenuStream(); break; } string TagClass; if (m_MapVersion == MapfileVersion.XHALO2) { TagClass = GetTagClass(BitConverter.GetBytes(Halo2Map.IndexItem[index].TagType), 0); } else { TagClass = GetTagClass(BitConverter.GetBytes(HaloMap.IndexItems[index].Type1), 0); } if (TagClass == "<fx>") { TagClass = "FXFX"; } //byte[] TagHeaderBuffer = new byte[64]; //OptionsManager.GetGuerillaHeader(m_MapVersion, TagClass, TagHeaderBuffer); //Loading Tag Long name and seting the map version folder string MagfilePathRoot = OptionsManager.GetMagfilePath(m_MapVersion); string OutputPathRoot = OptionsManager.GetExtractPath(m_MapVersion); //Creating Directorys for extracted tags; string[] Directorys = new string[256]; string DirSep = @"\"; if (m_MapVersion == MapfileVersion.XHALO2) { Directorys = Halo2Map.StringTable.TagStrings[index].Split(DirSep.ToCharArray(), 256); } else { Directorys = HaloMap.IndexItemStringList[index].Split(DirSep.ToCharArray(), 256); } //Create tag directory if it doesn't exist uint Dircount = (uint)Directorys.Length - 1; string NewDirectoryStructure = ""; for (uint Count = 0; Count < Dircount; Count += 1) { if (Directory.Exists(OutputPathRoot + NewDirectoryStructure + Directorys[Count]) == false) { Directory.CreateDirectory(OutputPathRoot + NewDirectoryStructure + Directorys[Count]); NewDirectoryStructure += Directorys[Count] + @"\"; } else { NewDirectoryStructure += Directorys[Count] + @"\"; } } //Parse mag file string ProcessTagFile = TagClass.Trim() + ".mag"; StreamReader MagReader = new StreamReader(MagfilePathRoot + ProcessTagFile); string InLine = MagReader.ReadLine(); string TagExtension = InLine; byte TabByte = 0x09; string TabReplace = ""; TabReplace += (char)TabByte; string[] MagArray = new string[256]; int MagIndex = 0; do { InLine = MagReader.ReadLine(); MagArray[MagIndex] = InLine.Replace(TabReplace, "").ToLower().Trim(); MagIndex++; }while(MagReader.Peek() != -1); MagReader.Close(); //Create output tag stream/file FileInfo fiout; if (m_MapVersion == MapfileVersion.XHALO2) { string SplitChar = "."; string[] FixTagName = Halo2Map.StringTable.TagStrings[index].Split(SplitChar.ToCharArray(), 2); fiout = new FileInfo(OutputPathRoot + FixTagName[0] + "." + TagExtension.Trim()); } else { fiout = new FileInfo(OutputPathRoot + HaloMap.IndexItemStringList[index]); } MemoryStream msout = new MemoryStream(); //msout = fiout.Open(FileMode.Create,FileAccess.ReadWrite); //Grenadiac changed this to RW for archive hack //msout.Seek(0,System.IO.SeekOrigin.Begin); TagHeader.SeekToTagDataStart(ref msout); //msout.Write(TagHeaderBuffer,0,64); //Parse the meta and reformat output tag according to Magfile rules if (m_MapVersion == MapfileVersion.XHALO2) { // Create debug stream writer StreamWriter DebugFile; DebugFile = null;//new StreamWriter(Application.StartupPath + @"\TagDebug.txt"); byte[] TagTable = new byte[TagCount * 16]; fsin.Seek(Halo2Map.IndexHeader.OffsetToTags, System.IO.SeekOrigin.Begin); fsin.Read(TagTable, 0, TagTable.Length); Halo2Structure MainStruct = new Halo2Structure(); if (TagClass == "sbsp") { MainStruct.StructureCS((uint)MagIndex, Halo2Map.IndexItem[index].TagOffsetMagic, Halo2Map.IndexItem[index].TagMagic, MagArray, 1, fsin, msout, fsShared, 0, 0, Halo2Map.StringTable.StringBuffer, Halo2Map.StringTable.OffsetsBuffer, fsSinglePlayerShared, fsMainMenu, fsShared, Halo2Map.MapHeader.MetaStart, Halo2Map.MapHeader.FileSize, DebugFile, TagTable, Halo2Map.MapHeader.ScriptStringArray); } fsShared.Close(); fsSinglePlayerShared.Close(); fsMainMenu.Close(); } else { fsin.Seek(HaloMap.IndexItems[index].MetaOffset, System.IO.SeekOrigin.Begin); Structure2 MainStruct = new Structure2(); MainStruct.StructureCS(HaloMap.IndexItems[index].MetaOffset, (uint)MagIndex, HaloMap.IndexItems[index].MetaMagic, HaloMap.Map_Magic, MagArray, 1, fsin, msout, fsBitmap, fsSound, HaloMap.IndexHeader.Verts_Offset, HaloMap.IndexHeader.Index_Offset, HaloMap.MapHeader.Map_Version); fsBitmap.Close(); fsSound.Close(); } // Initialize and write out the PROM tag header TagHeader tag_hdr = new TagHeader(); tag_hdr.TagClass0 = TagClass; tag_hdr.GameVersion = (MapfileVersion)m_MapVersion; tag_hdr.TagSize = (int)msout.Position - TagHeader.PROM_HEADER_SIZE; tag_hdr.Write(ref msout); //Write out a zero-attachment header AttachmentHeader attach_hdr = new AttachmentHeader(); attach_hdr.Write(ref msout); if (m_OutputArchive != null) { m_OutputArchive.AddTagfileToArchive(HaloMap.IndexItemStringList[index], msout.GetBuffer(), (int)msout.Position); } msout.Close(); }
public void StructureCS(uint MetaOffset, uint MagIndex, uint OffsetMagic, uint MapMagic, string[] StructureArray, uint ChunkCount, FileStream MapFile, MemoryStream TagFile, FileStream BitmapFile, FileStream SoundFile, uint VerticesOffset, uint IndicesOffset, uint MapVersion) { TabReplace += (char)TabByte; uint StructSize; uint TestInc = 0; uint StructOffset; uint MapFilePosSave; uint ChildChunkCount; uint PrevSize = 0; uint BMAPtrigger = 0; uint NewIndexSize = 0; uint TagRefOffset = 0; uint TagRefStringOffset = 0; uint TagRefBufferOldSize = 0; uint TagRefBufferNewSize = 0; uint AfterStructChunkCount = 0; byte[] TagRefBuffer = new byte[0]; byte[] MapStringBuffer = new byte[1024]; byte[] RawAnimationsBuffer = new byte[0]; byte[] RawAnimationEditBuffer = new byte[0]; byte[] RawBuffer = new byte[0]; byte[] BSPVerticesData = new byte[0]; string TestHelpString; string TagRefString; string[] CMD = new string[256]; string[] TestString = new string[256]; string[] NewStructureArray = new string[256]; CMD = StructureArray[0].Split(new char[] { ' ' }, 256); StructSize = Val(CMD[3]); byte[] StructBuffer = new byte[StructSize * ChunkCount]; byte[] OffsetBuffer = new byte[StructSize * ChunkCount]; StructOffset = (uint)TagFile.Position; string StructureName = CMD[2]; MapFile.Read(StructBuffer, 0, (int)StructBuffer.Length); uint StructSavePos = (uint)MapFile.Position; StructBuffer.CopyTo(OffsetBuffer, 0); uint BufferSize = (uint)StructBuffer.Length; StructRef = 0; for (uint cc = 0; cc < ChunkCount; cc++) { for (uint ee = 0; ee < MagIndex; ee++) { CMD = StructureArray[ee].Split(new char[] { ' ' }, 256); switch (CMD[0]) { case "struct": if (CMD[2] != StructureName) { AfterStructChunkCount = GetUInt(OffsetBuffer, Val(CMD[1]) + (cc * StructSize)); if (AfterStructChunkCount != 0) { StructRef += 1; } do { TestString = StructureArray[TestInc + ee].Split(new char[] { ' ' }, 256); if (TestString.Length > 1) { TestHelpString = TestString[1]; } else { TestHelpString = ""; } TestInc += 1; }while (CMD[2] != TestHelpString); ee = ee + (TestInc - 1); TestInc = 0; } break; case "tagref": TagRefOffset = Val(CMD[1]); TagRefStringOffset = GetUInt(StructBuffer, (TagRefOffset + 4) + (StructSize * cc)); if (TagRefStringOffset != 0) { TagRefStringOffset = TagRefStringOffset - MapMagic; MapFilePosSave = (uint)MapFile.Position; MapFile.Seek((long)TagRefStringOffset, System.IO.SeekOrigin.Begin); MapFile.Read(MapStringBuffer, 0, 512); MapFile.Seek((long)MapFilePosSave, System.IO.SeekOrigin.Begin); TagRefString = ReadString(MapStringBuffer); TagRefStrings[TagRefIndex] = TagRefString; TagRefParentIndex[TagRefIndex] = StructRef; TagRefChunkCountIndex[TagRefIndex] = cc; TagRefIndex = TagRefIndex + 1; PutUInt(StructBuffer, (uint)TagRefString.Length, (TagRefOffset + 8) + (StructSize * cc)); PutUInt(StructBuffer, 0, (TagRefOffset + 4) + (StructSize * cc)); PutUInt(StructBuffer, 4294967295, (TagRefOffset + 12) + (StructSize * cc)); if (StructRef == 0) { TagRefBufferOldSize = (uint)TagRefBuffer.Length; TagRefBufferNewSize = TagRefBufferOldSize + (uint)TagRefString.Length + 1; Redim(ref TagRefBuffer, TagRefBufferOldSize, TagRefBufferNewSize); TagRefBuffer = AppendToByteArray(TagRefBuffer, TagRefString, TagRefBufferOldSize); } } break; case "vertices": uint UnCompressedVerts = Val(CMD[1]); uint CompressedVerts = Val(CMD[3]); long SaveFilePos = MapFile.Position; TagRefOffset = 0; TagRefStringOffset = GetUInt(StructBuffer, (TagRefOffset + 4) + (StructSize * cc)); if (TagRefStringOffset != 0) { TagRefStringOffset = TagRefStringOffset - MapMagic; MapFilePosSave = (uint)MapFile.Position; MapFile.Seek((long)TagRefStringOffset, System.IO.SeekOrigin.Begin); MapFile.Read(MapStringBuffer, 0, 512); MapFile.Seek((long)MapFilePosSave, System.IO.SeekOrigin.Begin); TagRefString = ReadString(MapStringBuffer); PutUInt(StructBuffer, (uint)TagRefString.Length, (TagRefOffset + 8) + (StructSize * cc)); PutUInt(StructBuffer, 0, (TagRefOffset + 4) + (StructSize * cc)); PutUInt(StructBuffer, 4294967295, (TagRefOffset + 12) + (StructSize * cc)); uint BSPVerticesDataOldSize = (uint)BSPVerticesData.Length; uint BSPVerticesDataNewSize = BSPVerticesDataOldSize + (uint)TagRefString.Length + 1; Redim(ref BSPVerticesData, BSPVerticesDataOldSize, BSPVerticesDataNewSize); BSPVerticesData = AppendToByteArray(BSPVerticesData, TagRefString, BSPVerticesDataOldSize); } uint TrueVertCount = GetUInt(StructBuffer, 180 + (StructSize * cc)); uint TrueLightMapDataCount = GetUInt(StructBuffer, 200 + (StructSize * cc)); uint UnCompressedLightMapData = (TrueLightMapDataCount * 20); uint CompressedLightMapData = (TrueLightMapDataCount * 8); UnCompressedVerts = (TrueVertCount * 56); CompressedVerts = (TrueVertCount * 32); PutUInt(StructBuffer, CompressedVerts + CompressedLightMapData, Val(CMD[3]) + (StructSize * cc)); byte[] BspVertsUnCompressed = new byte[UnCompressedVerts]; byte[] BspVertsCompressed = new byte[CompressedVerts]; byte[] BspLightMapDataUnCompressed = new byte[UnCompressedLightMapData]; byte[] BspLightMapDataCompressed = new byte[CompressedLightMapData]; MapFile.Read(BspVertsUnCompressed, 0, BspVertsUnCompressed.Length); MapFile.Read(BspLightMapDataUnCompressed, 0, BspLightMapDataUnCompressed.Length); //////////////////////////////////////////////////////////////////////// ///Now Compress the Verts and move them in to the compressed ByteArray// //////////////////////////////////////////////////////////////////////// Single[] Vectors = new Single[3]; Single[] UVs = new Single[2]; for (uint commov = 0; commov < TrueVertCount; commov += 1) { PutUInt(BspVertsCompressed, GetUInt(BspVertsUnCompressed, (4 * 0) + (56 * commov)), (4 * 0) + (32 * commov)); //Moving X PutUInt(BspVertsCompressed, GetUInt(BspVertsUnCompressed, (4 * 1) + (56 * commov)), (4 * 1) + (32 * commov)); //Moving Y PutUInt(BspVertsCompressed, GetUInt(BspVertsUnCompressed, (4 * 2) + (56 * commov)), (4 * 2) + (32 * commov)); //Moving Z Vectors[0] = BitConverter.ToSingle(BspVertsUnCompressed, (int)((4 * 3) + (56 * commov))); // Loading normals Vectors[1] = BitConverter.ToSingle(BspVertsUnCompressed, (int)((4 * 4) + (56 * commov))); Vectors[2] = BitConverter.ToSingle(BspVertsUnCompressed, (int)((4 * 5) + (56 * commov))); PutUInt(BspVertsCompressed, CompressVector(Vectors), (4 * 3) + (32 * commov)); // compressing normals Vectors[0] = BitConverter.ToSingle(BspVertsUnCompressed, (int)((4 * 6) + (56 * commov))); // Loading BiNormals Vectors[1] = BitConverter.ToSingle(BspVertsUnCompressed, (int)((4 * 7) + (56 * commov))); Vectors[2] = BitConverter.ToSingle(BspVertsUnCompressed, (int)((4 * 8) + (56 * commov))); PutUInt(BspVertsCompressed, CompressVector(Vectors), (4 * 4) + (32 * commov)); // compressing binormals Vectors[0] = BitConverter.ToSingle(BspVertsUnCompressed, (int)((4 * 9) + (56 * commov))); // Loading Tangents Vectors[1] = BitConverter.ToSingle(BspVertsUnCompressed, (int)((4 * 10) + (56 * commov))); Vectors[2] = BitConverter.ToSingle(BspVertsUnCompressed, (int)((4 * 11) + (56 * commov))); PutUInt(BspVertsCompressed, CompressVector(Vectors), (4 * 5) + (32 * commov)); // compressing tangents PutUInt(BspVertsCompressed, GetUInt(BspVertsUnCompressed, (4 * 12) + (56 * commov)), (4 * 6) + (32 * commov)); // moveing uvs PutUInt(BspVertsCompressed, GetUInt(BspVertsUnCompressed, (4 * 13) + (56 * commov)), (4 * 7) + (32 * commov)); } for (uint lcommov = 0; lcommov < TrueLightMapDataCount; lcommov += 1) { Vectors[0] = BitConverter.ToSingle(BspLightMapDataUnCompressed, (int)((4 * 0) + (20 * lcommov))); Vectors[1] = BitConverter.ToSingle(BspLightMapDataUnCompressed, (int)((4 * 1) + (20 * lcommov))); Vectors[2] = BitConverter.ToSingle(BspLightMapDataUnCompressed, (int)((4 * 2) + (20 * lcommov))); UVs[0] = BitConverter.ToSingle(BspLightMapDataUnCompressed, (int)((4 * 3) + (20 * lcommov))); UVs[1] = BitConverter.ToSingle(BspLightMapDataUnCompressed, (int)((4 * 4) + (20 * lcommov))); PutUInt(BspLightMapDataCompressed, CompressVector(Vectors), (4 * 0) + (8 * lcommov)); PutUShort(BspLightMapDataCompressed, (ushort)CompressFloatToShort(UVs[0]), (4 * 1) + (8 * lcommov)); PutUShort(BspLightMapDataCompressed, (ushort)CompressFloatToShort(UVs[1]), ((4 * 1) + (8 * lcommov) + 2)); } ////////////////////////////////////////////////////////////////////////////// ///Now Move all the Compressed and uncompressed data in to the output array/// ////////////////////////////////////////////////////////////////////////////// uint OldBspVertsSize = (uint)BSPVerticesData.Length; Redim(ref BSPVerticesData, (uint)BSPVerticesData.Length, (uint)BSPVerticesData.Length + (uint)BspVertsUnCompressed.Length); AppendByteArrayToByteArray(ref BSPVerticesData, BspVertsUnCompressed, OldBspVertsSize); OldBspVertsSize = (uint)BSPVerticesData.Length; Redim(ref BSPVerticesData, (uint)BSPVerticesData.Length, (uint)BSPVerticesData.Length + (uint)BspLightMapDataUnCompressed.Length); AppendByteArrayToByteArray(ref BSPVerticesData, BspLightMapDataUnCompressed, OldBspVertsSize); OldBspVertsSize = (uint)BSPVerticesData.Length; Redim(ref BSPVerticesData, (uint)BSPVerticesData.Length, (uint)BSPVerticesData.Length + (uint)BspVertsCompressed.Length); AppendByteArrayToByteArray(ref BSPVerticesData, BspVertsCompressed, OldBspVertsSize); OldBspVertsSize = (uint)BSPVerticesData.Length; Redim(ref BSPVerticesData, (uint)BSPVerticesData.Length, (uint)BSPVerticesData.Length + (uint)BspLightMapDataCompressed.Length); AppendByteArrayToByteArray(ref BSPVerticesData, BspLightMapDataCompressed, OldBspVertsSize); break; case "bitmapraw": if (BMAPtrigger != 1) { BMAPtrigger = 1; uint bmOffset; uint bmChunkCount; uint bmfOffset = 0; uint bmfSize = 0; uint TifSize; uint SavePos; uint TotalbmfSize = 0; TifSize = GetUInt(StructBuffer, 28); bmOffset = Val(CMD[1].Replace(TabReplace, "").ToLower().Trim()); bmChunkCount = GetUInt(StructBuffer, bmOffset); bmOffset = GetUInt(StructBuffer, bmOffset + 4) - MapMagic; SavePos = (uint)MapFile.Position; byte[] BitmapStructBuffer = new byte[48 * bmChunkCount]; MapFile.Seek(bmOffset, System.IO.SeekOrigin.Begin); MapFile.Read(BitmapStructBuffer, 0, 48 * (int)bmChunkCount); MapFile.Seek(SavePos, System.IO.SeekOrigin.Begin); bmfOffset = GetUInt(BitmapStructBuffer, 24); for (uint SpecCount = 0; SpecCount < bmChunkCount; SpecCount += 1) { bmfSize = GetUInt(BitmapStructBuffer, 28 + (48 * SpecCount)); TotalbmfSize = TotalbmfSize + bmfSize; } Redim(ref StructBuffer, BufferSize, BufferSize + TifSize + TotalbmfSize); switch (MapVersion) { case 5: SavePos = (uint)MapFile.Position; MapFile.Seek(bmfOffset, System.IO.SeekOrigin.Begin); MapFile.Read(StructBuffer, (int)(BufferSize + TifSize), (int)TotalbmfSize); MapFile.Seek(SavePos, System.IO.SeekOrigin.Begin); break; case 7: BitmapFile.Seek(bmfOffset, System.IO.SeekOrigin.Begin); BitmapFile.Read(StructBuffer, (int)(BufferSize + TifSize), (int)TotalbmfSize); break; case 0x261: SavePos = (uint)MapFile.Position; MapFile.Seek(bmfOffset, System.IO.SeekOrigin.Begin); MapFile.Read(StructBuffer, (int)(BufferSize + TifSize), (int)TotalbmfSize); MapFile.Seek(SavePos, System.IO.SeekOrigin.Begin); break; } BufferSize = BufferSize + TifSize + TotalbmfSize; PutUInt(StructBuffer, TotalbmfSize, 48); } break; case "addprevsize": if ((cc - 1) == 0xffffffff) { PutUInt(StructBuffer, 0, 24 + (StructSize * (cc))); } else { PrevSize = PrevSize + GetUInt(StructBuffer, 28 + (StructSize * (cc - 1))); PutUInt(StructBuffer, PrevSize, 24 + (StructSize * (cc))); } break; case "rawxmodeldata": uint XTrueVerticesSize = (GetUInt(StructBuffer, 88 + (StructSize * cc))) * 32; uint XTrueIndicesSize = (((GetUInt(StructBuffer, 72 + (StructSize * cc))) / 3) + 1) * 6; uint XNewIndicesDataSize = (GetUInt(StructBuffer, 72 + (StructSize * cc)) / 3) + 1; uint XTrueVerticesOffset = GetUInt(StructBuffer, 100 + (StructSize * cc)) - MapMagic; uint XSaveMapFilePos = (uint)MapFile.Position; byte[] XModelHeader = new byte[16]; MapFile.Seek((long)XTrueVerticesOffset, System.IO.SeekOrigin.Begin); MapFile.Read(XModelHeader, 0, XModelHeader.Length); MapFile.Seek(XSaveMapFilePos, System.IO.SeekOrigin.Begin); XTrueVerticesOffset = GetUInt(XModelHeader, 4) - MapMagic; //XTrueVerticesOffset = GetUInt(StructBuffer,XTrueVerticesOffset) - MapMagic; uint XTrueIndicesOffset = GetUInt(StructBuffer, 80 + (StructSize * cc)) - MapMagic; byte[] XTestBuffer = new byte[6]; PutUInt(StructBuffer, GetUInt(StructBuffer, 88 + (StructSize * cc)), 44 + (StructSize * cc)); PutUInt(StructBuffer, XNewIndicesDataSize, 56 + (StructSize * cc)); XSaveMapFilePos = (uint)MapFile.Position; uint XCurrentStructSize = (uint)StructBuffer.Length; byte[] RawXModelBuffer = new byte[XTrueVerticesSize]; Redim(ref StructBuffer, XCurrentStructSize, XCurrentStructSize + XTrueVerticesSize); MapFile.Seek((long)XTrueVerticesOffset, System.IO.SeekOrigin.Begin); MapFile.Read(RawXModelBuffer, 0, (int)XTrueVerticesSize); for (uint Xcopy = 0; Xcopy < XTrueVerticesSize; Xcopy += 32) { PutUInt(StructBuffer, GetUInt(RawXModelBuffer, Xcopy), Xcopy + XCurrentStructSize); SwapInt(StructBuffer, Xcopy + XCurrentStructSize); PutUInt(StructBuffer, GetUInt(RawXModelBuffer, Xcopy + 4), Xcopy + XCurrentStructSize + 4); SwapInt(StructBuffer, Xcopy + XCurrentStructSize + 4); PutUInt(StructBuffer, GetUInt(RawXModelBuffer, Xcopy + 8), Xcopy + XCurrentStructSize + 8); SwapInt(StructBuffer, Xcopy + XCurrentStructSize + 8); PutUInt(StructBuffer, GetUInt(RawXModelBuffer, Xcopy + 12), Xcopy + XCurrentStructSize + 12); SwapInt(StructBuffer, Xcopy + XCurrentStructSize + 12); PutUInt(StructBuffer, GetUInt(RawXModelBuffer, Xcopy + 16), Xcopy + XCurrentStructSize + 16); SwapInt(StructBuffer, Xcopy + XCurrentStructSize + 16); PutUInt(StructBuffer, GetUInt(RawXModelBuffer, Xcopy + 20), Xcopy + XCurrentStructSize + 20); SwapInt(StructBuffer, Xcopy + XCurrentStructSize + 20); PutUInt(StructBuffer, GetUInt(RawXModelBuffer, Xcopy + 24), Xcopy + XCurrentStructSize + 24); SwapLong(StructBuffer, Xcopy + XCurrentStructSize + 24); SwapLong(StructBuffer, Xcopy + XCurrentStructSize + 26); PutUInt(StructBuffer, GetUInt(RawXModelBuffer, Xcopy + 28), Xcopy + XCurrentStructSize + 28); //SwapLong(StructBuffer,Xcopy + XCurrentStructSize + 28); SwapLong(StructBuffer, Xcopy + XCurrentStructSize + 30); //SwapInt(StructBuffer,Xcopy + XCurrentStructSize + 24); //PutUInt(StructBuffer,GetUInt(RawXModelBuffer,Xcopy + 28),Xcopy + XCurrentStructSize + 28); //SwapInt(StructBuffer,Xcopy + XCurrentStructSize + 28); //ushort XTestushort = GetUShort(StructBuffer,Xcopy + XCurrentStructSize + 58); //if (XTestULong == 0) //{ // PutUShort(StructBuffer,XTestULong - 1,Xcopy + XCurrentStructSize + 58); //} //PutUInt(StructBuffer,GetUInt(RawXModelBuffer,Xcopy + 60),Xcopy + XCurrentStructSize + 60); //SwapInt(StructBuffer,Xcopy + XCurrentStructSize + 60); //PutUInt(StructBuffer,GetUInt(RawXModelBuffer,Xcopy + 64),Xcopy + XCurrentStructSize + 64); //SwapInt(StructBuffer,Xcopy + XCurrentStructSize + 64); } XCurrentStructSize = (uint)StructBuffer.Length; Redim(ref StructBuffer, XCurrentStructSize, XCurrentStructSize + XTrueIndicesSize); //+ TrueIndicesSize RawXModelBuffer = new byte[XTrueIndicesSize + 6]; MapFile.Seek((long)XTrueIndicesOffset, System.IO.SeekOrigin.Begin); MapFile.Read(XModelHeader, 0, XModelHeader.Length); XTrueIndicesOffset = GetUInt(XModelHeader, 4) - MapMagic; MapFile.Seek((long)XTrueIndicesOffset, System.IO.SeekOrigin.Begin); MapFile.Read(RawXModelBuffer, 0, RawXModelBuffer.Length); MapFile.Seek(MapFile.Position - 6, System.IO.SeekOrigin.Begin); MapFile.Read(XTestBuffer, 0, 6); if (XTestBuffer[4] == 0xff) { //CurrentStructSize = (uint)StructBuffer.Length; Redim(ref StructBuffer, XCurrentStructSize, XCurrentStructSize + XTrueIndicesSize + 6); //+ TrueIndicesSize PutUInt(StructBuffer, GetUInt(StructBuffer, 56 + (StructSize * cc)) + 1, 56 + (StructSize * cc)); XTrueIndicesSize += 6; } for (uint Xcopy = 0; Xcopy < XTrueIndicesSize; Xcopy += 2) { StructBuffer[Xcopy + XCurrentStructSize] = RawXModelBuffer[Xcopy + 1]; StructBuffer[Xcopy + XCurrentStructSize + 1] = RawXModelBuffer[Xcopy]; } break; case "rawmodeldata": uint TrueVerticesSize = (GetUInt(StructBuffer, 88 + (StructSize * cc))) * 68; uint TrueIndicesSize = (((GetUInt(StructBuffer, 72 + (StructSize * cc))) / 3) + 1) * 6; uint NewIndicesDataSize = (GetUInt(StructBuffer, 72 + (StructSize * cc)) / 3) + 1; uint TrueVerticesOffset = GetUInt(StructBuffer, 100 + (StructSize * cc)) + VerticesOffset; //80 uint TrueIndicesOffset = GetUInt(StructBuffer, 80 + (StructSize * cc)) + IndicesOffset; //100 byte[] TestBuffer = new byte[6]; PutUInt(StructBuffer, GetUInt(StructBuffer, 88 + (StructSize * cc)), 32 + (StructSize * cc)); PutUInt(StructBuffer, NewIndicesDataSize, 56 + (StructSize * cc)); uint SaveMapFilePos = (uint)MapFile.Position; uint CurrentStructSize = (uint)StructBuffer.Length; byte[] RawModelBuffer = new byte[TrueVerticesSize]; Redim(ref StructBuffer, CurrentStructSize, CurrentStructSize + TrueVerticesSize); //+ TrueIndicesSize MapFile.Seek((long)TrueVerticesOffset, System.IO.SeekOrigin.Begin); MapFile.Read(StructBuffer, (int)CurrentStructSize, (int)TrueVerticesSize); CurrentStructSize = (uint)StructBuffer.Length; Redim(ref StructBuffer, CurrentStructSize, CurrentStructSize + TrueIndicesSize); //+ TrueIndicesSize RawModelBuffer = new byte[TrueIndicesSize + 6]; MapFile.Seek((long)TrueIndicesOffset, System.IO.SeekOrigin.Begin); MapFile.Read(RawModelBuffer, 0, RawModelBuffer.Length); MapFile.Seek(MapFile.Position - 6, System.IO.SeekOrigin.Begin); MapFile.Read(TestBuffer, 0, 6); if (TestBuffer[4] == 0xff) { Redim(ref StructBuffer, CurrentStructSize, CurrentStructSize + TrueIndicesSize + 6); //+ TrueIndicesSize PutUInt(StructBuffer, GetUInt(StructBuffer, 56 + (StructSize * cc)) + 1, 56 + (StructSize * cc)); TrueIndicesSize += 6; } for (uint copy = 0; copy < TrueIndicesSize; copy += 1) { StructBuffer[copy + CurrentStructSize] = RawModelBuffer[copy]; } break; } } } //MapFile.Read(RawBuffer,0,RawBuffer.Length); long DStructOffsetSave = TagFile.Position; TagFile.Write(StructBuffer, 0, (int)StructBuffer.Length); TagFile.Write(TagRefBuffer, 0, TagRefBuffer.Length); TagFile.Write(RawBuffer, 0, RawBuffer.Length); //byte[] BSPVerticesData = new byte[SizeOfVerts]; //MapFile.Read(BSPVerticesData,0,BSPVerticesData.Length); TagFile.Write(BSPVerticesData, 0, BSPVerticesData.Length); //TagFile.Write(RawAnimationsBuffer,0,RawAnimationsBuffer.Length); BSPVerticesData = null; TagRefBuffer = new byte[0]; StructRef = 0; string StructType = "internal"; for (uint cc = 0; cc < ChunkCount; cc++) { for (uint dd = 0; dd < MagIndex; dd++) { CMD = StructureArray[dd].Split(new char[] { ' ' }, 256); switch (CMD[0]) { case "externalsnddata": uint DataSizeOffset = Val(CMD[1]); uint NormalDataOffset = Val(CMD[2]); uint SndDataSize = BitConverter.ToUInt32(OffsetBuffer, (int)(DataSizeOffset + (cc * StructSize))); uint TrueOffset = BitConverter.ToUInt32(OffsetBuffer, (int)(NormalDataOffset + 4 + (cc * StructSize))); byte[] SoundData = new byte[SndDataSize]; SoundFile.Seek(TrueOffset, System.IO.SeekOrigin.Begin); SoundFile.Read(SoundData, 0, SoundData.Length); TagFile.Write(SoundData, 0, SoundData.Length); SoundData = null; break; case "internalraw": uint RawSizeOffset = Val(CMD[1]); uint RawTrueOffset = Val(CMD[2]); uint TempMagic; if (CMD.Length == 4) { if (CMD[3] == "bsp") { TempMagic = OffsetMagic; } else { TempMagic = MapMagic; } } else { TempMagic = MapMagic; } uint RawDataSize = BitConverter.ToUInt32(OffsetBuffer, (int)(RawSizeOffset + (cc * StructSize))); uint RawDataTrueOffset = BitConverter.ToUInt32(OffsetBuffer, (int)(RawTrueOffset + 4 + (cc * StructSize))) - TempMagic; byte[] RawData = new byte[RawDataSize]; long FilePosSave = MapFile.Position; MapFile.Seek((long)RawDataTrueOffset, System.IO.SeekOrigin.Begin); MapFile.Read(RawData, 0, RawData.Length); TagFile.Write(RawData, 0, RawData.Length); MapFile.Seek(FilePosSave, System.IO.SeekOrigin.Begin); RawData = null; break; case "struct": if (CMD[2] != StructureName) { Structure2 ChildStruct; AfterStructChunkCount = GetUInt(OffsetBuffer, Val(CMD[1]) + (cc * StructSize)); long CurrentPosSave = TagFile.Position; uint CurentOffset = (GetUInt(OffsetBuffer, Val(CMD[1]) + (cc * StructSize) + 4) - MapMagic) - MetaOffset; PutUInt(StructBuffer, (uint)TagFile.Position - 64, Val(CMD[1]) + (cc * StructSize) + 8); PutUInt(StructBuffer, CurentOffset, Val(CMD[1]) + (cc * StructSize) + 4); TagFile.Seek(DStructOffsetSave, System.IO.SeekOrigin.Begin); TagFile.Write(StructBuffer, 0, StructBuffer.Length); TagFile.Seek(CurrentPosSave, System.IO.SeekOrigin.Begin); if (AfterStructChunkCount != 0) { StructRef += 1; } do { NewStructureArray[NewIndexSize] = StructureArray[dd + NewIndexSize]; TestString = StructureArray[dd + NewIndexSize].Split(new char[] { ' ' }, 256); NewIndexSize = NewIndexSize + 1; if (TestString.Length > 1) { TestHelpString = TestString[1]; } else { TestHelpString = ""; } }while (CMD[2] != TestHelpString); dd = dd + (NewIndexSize - 1); ChildChunkCount = 0; switch (CMD.Length) { case 6: uint Devided; uint Devidedby; Devided = GetUInt(OffsetBuffer, Val(CMD[5]) + (cc * StructSize)); Devidedby = Val(CMD[3]); ChildChunkCount = (Devided / Devidedby); StructType = "internal"; break; case 7: Devided = GetUInt(OffsetBuffer, Val(CMD[5]) + (cc * StructSize)); Devidedby = Val(CMD[3]); ChildChunkCount = (Devided / Devidedby); OffsetMagic = 0; StructType = CMD[6]; break; case 5: StructType = "internal"; ChildChunkCount = GetUInt(OffsetBuffer, Val(CMD[1]) + (cc * StructSize)); break; case 4: StructType = "internal"; ChildChunkCount = GetUInt(OffsetBuffer, Val(CMD[1]) + (cc * StructSize)); break; } MapFile.Seek(GetUInt(OffsetBuffer, Val(CMD[1]) + 4 + (cc * StructSize)) - OffsetMagic, System.IO.SeekOrigin.Begin); //PutUInt(StructBuffer,TrueMetaOffset,Val(CMD[1]) + 4 + (cc * StructSize)); if (ChildChunkCount != 0) { switch (StructType) { case "external": SoundFile.Seek(GetUInt(OffsetBuffer, Val(CMD[1]) + 4 + (cc * StructSize)) - OffsetMagic, System.IO.SeekOrigin.Begin); ChildStruct = new Structure2(); ChildStruct.StructureCS(MetaOffset, NewIndexSize, OffsetMagic, MapMagic, NewStructureArray, ChildChunkCount, SoundFile, TagFile, BitmapFile, SoundFile, VerticesOffset, IndicesOffset, MapVersion); ChildStruct = null; StructType = "internal"; break; case "internal": ChildStruct = new Structure2(); ChildStruct.StructureCS(MetaOffset, NewIndexSize, OffsetMagic, MapMagic, NewStructureArray, ChildChunkCount, MapFile, TagFile, BitmapFile, SoundFile, VerticesOffset, IndicesOffset, MapVersion); ChildStruct = null; break; } } for (uint TagHandler = 0; TagHandler < TagRefIndex; TagHandler += 1) { if (StructRef == TagRefParentIndex[TagHandler]) { if (StructRef != 0) { TagRefBufferOldSize = (uint)TagRefBuffer.Length; TagRefBufferNewSize = TagRefBufferOldSize + (uint)TagRefStrings[TagHandler].Length + 1; Redim(ref TagRefBuffer, TagRefBufferOldSize, TagRefBufferNewSize); TagRefBuffer = AppendToByteArray(TagRefBuffer, TagRefStrings[TagHandler], TagRefBufferOldSize); TagRefStrings[TagHandler] = ""; TagRefParentIndex[TagHandler] = 65535; } } } TagFile.Write(TagRefBuffer, 0, TagRefBuffer.Length); TagRefBuffer = new byte[0]; NewIndexSize = 0; } break; case "break": break; } } } StructBuffer = new byte[0]; OffsetBuffer = new byte[0]; }
private void ExtractTag(int index) { FileStream fsBitmap = OptionsManager.GetBitmapStream(m_MapVersion); FileStream fsSound = OptionsManager.GetSoundStream(m_MapVersion); string TagClass = GetTagClass(BitConverter.GetBytes(HaloMap.IndexItems[index].Type1), 0); //Loading Tag Long name and seting the map version folder string ProcessTagFile = TagClass.Trim() + ".mag"; string MagfilePathRoot = ""; string OutputPathRoot = ""; switch (m_MapVersion) { case MapfileVersion.HALOPC: MagfilePathRoot = Application.StartupPath + @"\Tag Structures\PcHalo\"; OutputPathRoot = Application.StartupPath + @"\Games\Pc\Halo\"; break; case MapfileVersion.HALOCE: MagfilePathRoot = Application.StartupPath + @"\Tag Structures\CeHalo\"; OutputPathRoot = Application.StartupPath + @"\Games\Pc\Halo\"; break; case MapfileVersion.XHALO1: MagfilePathRoot = Application.StartupPath + @"\Tag Structures\XHalo\"; OutputPathRoot = Application.StartupPath + @"\Games\Xbox\Halo\"; break; } //Creating Directorys for extracted tags; string[] Directorys = new string[256]; string DirSep = @"\"; Directorys = HaloMap.IndexItemStringList[index].Split(DirSep.ToCharArray(), 256); uint Dircount = (uint)Directorys.Length - 1; string NewDirectoryStructure = ""; for (uint Count = 0; Count < Dircount; Count += 1) { if (Directory.Exists(OutputPathRoot + NewDirectoryStructure + Directorys[Count]) == false) { Directory.CreateDirectory(OutputPathRoot + NewDirectoryStructure + Directorys[Count]); NewDirectoryStructure += Directorys[Count] + @"\"; } else { NewDirectoryStructure += Directorys[Count] + @"\"; } } StreamReader MagReader = new StreamReader(MagfilePathRoot + ProcessTagFile); string InLine = MagReader.ReadLine(); FileInfo fiout = new FileInfo(OutputPathRoot + HaloMap.IndexItemStringList[index]); MemoryStream msout = new MemoryStream(); //msout = fiout.Open(FileMode.Create,FileAccess.ReadWrite); //Grenadiac changed this to RW for archive hack TagHeader.SeekToTagDataStart(ref msout); fsin.Seek(HaloMap.IndexItems[index].MetaOffset, System.IO.SeekOrigin.Begin); byte TabByte = 0x09; string TabReplace = ""; TabReplace += (char)TabByte; string[] MagArray = new string[256]; int MagIndex = 0; do { InLine = MagReader.ReadLine(); //MagArray[Count] = InLine.Split(new char[]{' '},256); MagArray[MagIndex] = InLine.Replace(TabReplace, "").ToLower().Trim(); MagIndex = MagIndex + 1; }while (MagReader.Peek() != -1); MagReader.Close(); Structure2 MainStruct = new Structure2(); MainStruct.StructureCS(HaloMap.IndexItems[index].MetaOffset, (uint)MagIndex, HaloMap.IndexItems[index].MetaMagic, HaloMap.Map_Magic, MagArray, 1, fsin, msout, fsBitmap, fsSound, HaloMap.IndexHeader.Verts_Offset, HaloMap.IndexHeader.Index_Offset, HaloMap.MapHeader.Map_Version); //public void StructureCS(uint MetaOffset,uint MagIndex,uint OffsetMagic,uint MapMagic,string[] StructureArray,uint ChunkCount,FileStream MapFile,FileStream TagFile,FileStream BitmapFile,FileStream SoundFile,uint VerticesOffset,uint IndicesOffset,StreamWriter ObjFile,uint MapVersion) // Initialize and write out the PROM tag header TagHeader tag_hdr = new TagHeader(); tag_hdr.TagClass0 = TagClass; tag_hdr.GameVersion = (MapfileVersion)m_MapVersion; tag_hdr.TagSize = (int)msout.Position - TagHeader.PROM_HEADER_SIZE; tag_hdr.Write(ref msout); //Write out a zero-attachment header tag_hdr.SeekToAttachStart(ref msout); AttachmentHeader attach_hdr = new AttachmentHeader(); attach_hdr.Write(ref msout); //GRENADIAC HACK to put tagfile into archive if (m_OutputArchive != null) { m_OutputArchive.AddTagfileToArchive(HaloMap.IndexItemStringList[index], msout.GetBuffer(), (int)msout.Position); } msout.Close(); fsBitmap.Close(); fsSound.Close(); }