Пример #1
0
        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();
        }
Пример #2
0
        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];
        }
Пример #3
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();
        }