public MemoryStream ConvertTag(string FileName) { //Open Tag and create a memeory stream// FileInfo fi_FileInfo = new FileInfo(FileName); FileStream fs_File = fi_FileInfo.Open(FileMode.Open, FileAccess.Read); byte[] inFileHeader = new byte[0x40]; fs_File.Read(inFileHeader, 0, 0x40); byte[] inFileBuffer = new byte[fs_File.Length - 0x40]; fs_File.Read(inFileBuffer, 0, inFileBuffer.Length); fs_File.Close(); MemoryStream ms_inFile = new MemoryStream(inFileBuffer, 0, inFileBuffer.Length); //Create a memory stream for output tag// byte[] outFileBuffer = new byte[inFileBuffer.Length]; MemoryStream ms_outFile = new MemoryStream(outFileBuffer, 0, outFileBuffer.Length); //Get the TagClass and open the MTSFReader// uint TagClass = CompUtil.GetUInt(inFileHeader, 0x24); MTSFReader mr; mr = new MTSFReader(); mr.MTSFRead("Core.Compiler.TAG_CONVERSION_SET.MTSF"); TSFReader STSF = new TSFReader(); STSF.TSF(ref mr, TagClass); //Now Convert the tag From ce to prom// Converter Convert = new Converter(); Convert.TagStruct(ref STSF, ref ms_inFile, ref ms_outFile, 1, STSF.GetUName()); ms_inFile.Close(); return(ms_outFile); }
public void TagStruct(ref TSFReader sr, ref MemoryStream FI, ref MemoryStream FO, uint Count, ushort uName) { long MapPosSave; TabReplace += (char)TabByte; Name = sr.GetUName(); Size = sr.GetSOC(); TagBuff = new byte[Size * Count]; FI.Read(TagBuff, 0, TagBuff.Length); long StructPosition = FO.Position; FO.Write(TagBuff, 0, TagBuff.Length); uint StartOfStruct = sr.Position; uint sc = 0; bool ExitStruct = false; do { do { sr.Read(); switch (sr.GetCMD()) { case TSFReader.TSFStruct: // 0xA0: //Struct #region Structure uint ChildCount = CompUtil.GetUInt(TagBuff, (uint)(sr.GetOIP()) + (sc * Size)); if (sr.GetUName() == 0xffff) { ChildCount = 0; CompUtil.PutUInt(ref TagBuff, (uint)(sr.GetOIP()) + (sc * Size), 0); } if (ChildCount != 0) { Converter Child = new Converter(); Child.TagStruct(ref sr, ref FI, ref FO, ChildCount, sr.GetUName()); } else { sr.SeekAheadTo(0xA7, sr.GetUName()); } break; #endregion case TSFReader.TSFBSPTagRef: // 0xA8: //BSPTagRef case TSFReader.TSFTagRef: // 0xA1: //TagRef #region TagRef int StringSize = (int)CompUtil.GetUInt(TagBuff, (uint)(sr.GetOIP() + (sc * Size)) + 0x08); if (StringSize != 0) { byte[] tmpstr = new byte[StringSize + 1]; FI.Read(tmpstr, 0, tmpstr.Length); FO.Write(tmpstr, 0, tmpstr.Length); } break; #endregion case TSFReader.TSFInternalRaw: // 0xA3: //InternalRaw #region InternalRaw uint RawSize = CompUtil.GetUInt(TagBuff, (uint)(sr.GetOIP() + (sc * Size))); byte[] tmp = new byte[RawSize]; FI.Read(tmp, 0, tmp.Length); FO.Write(tmp, 0, tmp.Length); tmp = null; break; #endregion case TSFReader.TSFIntSwap: #region IntSwap uint is_Offset = (uint)sr.GetOIP(); CompUtil.SwapInt(ref TagBuff, is_Offset + (sc * Size)); break; #endregion case TSFReader.TSFIntSwapRange: #region IntSwapRange uint StartOffset = (uint)sr.GetOIP(); uint EndOffset = (uint)sr.GetUName(); for (uint i = StartOffset; i < EndOffset; i += 4) { CompUtil.SwapInt(ref TagBuff, i + (sc * Size)); } break; #endregion case TSFReader.TSFLongSwap: #region ShortSwap uint Offset = (uint)sr.GetOIP(); CompUtil.SwapShort(ref TagBuff, Offset + (sc * Size)); break; #endregion case TSFReader.TSFLongSwapRange: #region ShortSwapRange uint lsr_StartOffset = (uint)sr.GetOIP(); uint lsr_EndOffset = (uint)sr.GetUName(); for (uint i = lsr_StartOffset; i < lsr_EndOffset; i += 2) { CompUtil.SwapShort(ref TagBuff, i + (sc * Size)); } break; #endregion case TSFReader.TSFBitmapRaw: // 0xA9: //Bitmapraw #region BitmapRaw /* * uint BitMapStructCount; * uint BitMapStructOffset; * uint TiffSize=0; * byte[] tmpBMS; * long sv = 0; * #region grenbitmap * if(Info.IndexItems[Info.CurrentIndex].RawTypeID != 0) * { * //Trace.WriteLine("extern ce bitmap: " + Prometheus.Core.Compiler.Decompiler.CurrentTagName); * CeBitmapIndex.Read(br); * //meta header for bitmaps for extern ce files is actually in the bitmaps.map file * //so we need to get the header from there. * * //fix the index offset, it doesn't use magic * int bitmap_hdr_offset = (int)CeBitmapIndex.Locator[Info.IndexItems[Info.CurrentIndex].MetaOffset + Info.TagMagic].offset; * Info.BitmapsFile.Position = bitmap_hdr_offset; * TagBuff = br.ReadBytes(TagBuff.Length); * PutUInt(ref TagBuff,0x54,0); * //get bitmap header(s) offset/count * BitMapStructCount=GetUInt(TagBuff,0x60); * BitMapStructOffset=GetUInt(TagBuff,0x64); * * //copy bitmap header(s) from CE shared to output tag * br.BaseStream.Position += (BitMapStructOffset-Size); * tmpBMS = new byte[BitMapStructCount * 0x30]; * tmpBMS = br.ReadBytes(tmpBMS.Length); * * GetUInt(TagBuff,0x1C,ref TiffSize); * * bw.BaseStream.Position = 0; * bw.Write(TagBuff); * bw.BaseStream.Position += (BitMapStructOffset-Size); * //bw.Write(tmpBMS); * //FO.Write(tmpBMS, (int)FO.Position, tmpBMS.Length); * * //skip over TIFF area in output tag * GetUInt(TagBuff,0x1C,ref TiffSize); * byte[] TiffBuffer = new byte[TiffSize]; * bw.Write(TiffBuffer); * //FO.Write(TiffBuffer,0,TiffBuffer.Length); * * //copy bitmap data from CE shared to output tag * uint accum = (uint)bw.BaseStream.Position; * for(int i = 0;i<BitMapStructCount;i++) * { * uint BitMapDataOffset = GetUInt(tmpBMS,(uint)(0x18 + (i * 0x30))); * uint BitMapDataSize = GetUInt(tmpBMS,(uint)(0x1C + (i * 0x30))); * uint CurrentSize = GetUInt(TagBuff,(uint)0x30); * PutUInt(ref TagBuff,0x30,CurrentSize + BitMapDataSize); * byte[] tmpBitmapData = new byte[BitMapDataSize]; * tmpBitmapData = br.ReadBytes((int)BitMapDataSize); * bw.Write(tmpBitmapData); * PutUInt(ref tmpBMS,(uint)(0x18 + (i * 0x30)), accum); * accum += BitMapDataSize; * } * * //go to the image header offsets * //bw.BaseStream.Position = TagBuff.Length + TiffSize + * bw.BaseStream.Position += 0x40; * bw.Write(tmpBMS); * long eof = bw.BaseStream.Position; * * //fix the offsets * bw.BaseStream.Position = 0x74; * bw.Write(accum); * bw.BaseStream.Position = eof; * * fuckThisShitHack = true; * //FO.Write(tmpBitmapData, (int)FO.Position, tmpBitmapData.Length); * } * else * { * GetUInt(TagBuff,0x1C,ref TiffSize); * byte[] TiffBuffer = new byte[TiffSize]; * FO.Write(TiffBuffer,0,TiffBuffer.Length); * BitMapStructCount=GetUInt(TagBuff,0x60); * BitMapStructOffset=GetUInt(TagBuff,0x64) - Info.MapMagic; * sv = fs.Position; * fs.Seek((long)BitMapStructOffset,SeekOrigin.Begin); * tmpBMS = new byte[BitMapStructCount * 0x30]; * fs.Read(tmpBMS,0,tmpBMS.Length); * * for(int i = 0;i<BitMapStructCount;i++) * { * uint BitMapDataOffset = GetUInt(tmpBMS,(uint)(0x18 + (i * 0x30))); * uint BitMapDataSize = GetUInt(tmpBMS,(uint)(0x1C + (i * 0x30))); * uint CurrentSize = GetUInt(TagBuff,(uint)0x30); * PutUInt(ref TagBuff,0x30,CurrentSize + BitMapDataSize); * byte[] tmpBitmapData = new byte[BitMapDataSize]; * switch (Info.MapVersion) * { * case 5: * fs.Seek((long)BitMapDataOffset,SeekOrigin.Begin); * fs.Read(tmpBitmapData,0,tmpBitmapData.Length); * FO.Write(tmpBitmapData,0,tmpBitmapData.Length); * break; * case 7: * Info.BitmapsFile.Seek((long)BitMapDataOffset,SeekOrigin.Begin); * Info.BitmapsFile.Read(tmpBitmapData,0,tmpBitmapData.Length); * FO.Write(tmpBitmapData,0,tmpBitmapData.Length); * break; * case 0x261: * if (Info.IndexItems[Info.CurrentIndex].RawTypeID == 0) * { * fs.Seek((long)BitMapDataOffset,SeekOrigin.Begin); * fs.Read(tmpBitmapData,0,tmpBitmapData.Length); * FO.Write(tmpBitmapData,0,tmpBitmapData.Length); * } * else * { * //CE_Bitmap_File CEBF = new CE_Bitmap_File(); * //CEBF.HDR.Read(ref Info.BitmapsFile); * //uint Current_offset = CEBF.Locator[Info.IndexItems[Info.CurrentIndex].MetaOffset].offset; * } * break; * } * } * fs.Seek(sv,SeekOrigin.Begin); * } * #endregion */ break; #endregion case TSFReader.TSFSoundData: // 0xAA: //SoundData #region SoundData /* * uint DataSizeOffset = sr.GetOIP(); * uint NormalDataOffset = sr.GetUName(); * uint SndDataSize = GetUInt(TagBuff,(uint)(DataSizeOffset + (sc * Size))); * uint TrueOffset = GetUInt(TagBuff,(uint)(NormalDataOffset + 4 + (sc * Size))); * byte[] SoundData = new byte[SndDataSize]; * switch (Info.MapVersion) * { * case 5: * long fssv = fs.Position; * fs.Seek((long)TrueOffset,SeekOrigin.Begin); * fs.Read(SoundData,0,SoundData.Length); * fs.Seek(fssv,SeekOrigin.Begin); * FO.Write(SoundData,0,SoundData.Length); * break; * case 7: * Info.SoundsFile.Seek(TrueOffset,System.IO.SeekOrigin.Begin); * Info.SoundsFile.Read(SoundData,0,SoundData.Length); * FO.Write(SoundData,0,SoundData.Length); * SoundData = null; * break; * } */ break; #endregion case TSFReader.TSFRawXModelData: // 0xB0: //XModelData #region XModelData /* * uint XTrueVerticesSize = (GetUInt(TagBuff,88 + (sc * Size))) * 32; * uint XTrueIndicesSize =(((GetUInt(TagBuff,72 + (sc * Size))) / 3) + 1 ) * 6; * uint XNewIndicesDataSize = (GetUInt(TagBuff,72 + (sc * Size)) / 3) + 1; * uint XTrueVerticesOffset = GetUInt(TagBuff,100 + (sc * Size)) - Info.MapMagic; * uint XSaveMapFilePos = (uint)fs.Position;//MapFile.Position; * byte[] XModelHeader = new byte[16]; * fs.Seek((long)XTrueVerticesOffset,System.IO.SeekOrigin.Begin); * fs.Read(XModelHeader,0,XModelHeader.Length); * fs.Seek(XSaveMapFilePos,System.IO.SeekOrigin.Begin); * XTrueVerticesOffset = GetUInt(XModelHeader,4) - Info.MapMagic; * * XSaveMapFilePos = (uint)fs.Position; * byte[] RawXModelBuffer = new byte[XTrueVerticesSize]; * fs.Seek((long)XTrueVerticesOffset,System.IO.SeekOrigin.Begin); * fs.Read(RawXModelBuffer,0,(int)XTrueVerticesSize); * FO.Write(RawXModelBuffer,0,(int)XTrueVerticesSize); * * byte[] XTestBuffer = new byte[6]; * uint XTrueIndicesOffset = GetUInt(TagBuff, 80+ (sc * Size)) - Info.MapMagic; * RawXModelBuffer = new byte[XTrueIndicesSize]; * fs.Seek((long)XTrueIndicesOffset,System.IO.SeekOrigin.Begin); * fs.Read(XModelHeader,0,XModelHeader.Length); * XTrueIndicesOffset = GetUInt(XModelHeader,0x04) - Info.MapMagic; * fs.Seek((long)XTrueIndicesOffset,System.IO.SeekOrigin.Begin); * fs.Read(RawXModelBuffer,0,RawXModelBuffer.Length); * FO.Write(RawXModelBuffer,0,RawXModelBuffer.Length); * fs.Read(XTestBuffer,0,6); * if (XTestBuffer[4] == 0xff) * { * FO.Write(XTestBuffer,0,6); * XTrueIndicesSize += 6; * } */ break; #endregion case TSFReader.TSFModelData: // 0xAB: //Modeldata #region ModelData /* * long SaveMapFilePos = (uint)fs.Position; * uint TrueVerticesSize = (GetUInt(TagBuff,(uint)(88 + (sc * Size)))) * 68; * uint TrueIndicesSize =(((GetUInt(TagBuff,(uint)(72 + (sc * Size)))) / 3) + 1 ) * 6; * uint NewIndicesDataSize = (GetUInt(TagBuff,(uint)(72 + (sc * Size))) / 3) + 1; * uint TrueVerticesOffset = GetUInt(TagBuff,(uint)(100+ (sc * Size))) + Info.VerticesOffset; //80 * uint TrueIndicesOffset = GetUInt(TagBuff,(uint)(80+ (sc * Size))) + Info.IndicesOffset; //100 * //PutUInt(ref TagBuff,GetUInt(TagBuff,(uint)(88 + (i * Size))),(uint)(32 +(i * Size))); * //PutUInt(ref TagBuff,NewIndicesDataSize,(uint)(56 + (i * Size))); * uint CurrentStructSize = (uint)TagBuff.Length; * byte[] RawModelBuffer = new byte[TrueVerticesSize]; * fs.Seek((long)TrueVerticesOffset,System.IO.SeekOrigin.Begin); * fs.Read(RawModelBuffer,0,RawModelBuffer.Length); * FO.Write(RawModelBuffer,0,RawModelBuffer.Length); * * RawModelBuffer = new byte[TrueIndicesSize]; * fs.Seek((long)TrueIndicesOffset,System.IO.SeekOrigin.Begin); * fs.Read(RawModelBuffer,0,RawModelBuffer.Length); * FO.Write(RawModelBuffer,0,RawModelBuffer.Length); * fs.Seek(fs.Position,System.IO.SeekOrigin.Begin); * byte[] TestBuffer = new byte[6]; * fs.Read(TestBuffer,0,6); * if (TestBuffer[4] == 0xff) * { * //PutUInt(StructBuffer,GetUInt(StructBuffer,56 + (StructSize * cc)) + 1,56 + (StructSize * cc)); * FO.Write(TestBuffer,0,TestBuffer.Length); * TrueIndicesSize += 6; * } * fs.Seek(SaveMapFilePos,SeekOrigin.Begin); */ break; #endregion case TSFReader.TSFBSPModel: // 0xAC: //BSPMODEL #region BSPModel uint VOOffset = 0xB4; uint LOOffset = 0xC8; uint UnCompVertsSize = CompUtil.GetUInt(TagBuff, VOOffset + (sc * Size)) * 56; uint CompVertsSize = CompUtil.GetUInt(TagBuff, VOOffset + (sc * Size)) * 32; uint UnCompLMUVSize = CompUtil.GetUInt(TagBuff, LOOffset + (sc * Size)) * 20; uint CompLMUVSize = CompUtil.GetUInt(TagBuff, LOOffset + (sc * Size)) * 8; byte[] ba_UnCompVerts = new byte[UnCompVertsSize]; byte[] ba_CompVerts = new byte[CompVertsSize]; byte[] ba_UnCompLMUV = new byte[UnCompLMUVSize]; byte[] ba_CompLMUV = new byte[CompLMUVSize]; FI.Read(ba_UnCompVerts, 0, ba_UnCompVerts.Length); FI.Read(ba_UnCompLMUV, 0, ba_UnCompLMUV.Length); FI.Read(ba_CompVerts, 0, ba_CompVerts.Length); FI.Read(ba_CompLMUV, 0, ba_CompLMUV.Length); FO.Write(ba_UnCompVerts, 0, ba_UnCompVerts.Length); FO.Write(ba_UnCompLMUV, 0, ba_UnCompLMUV.Length); FO.Write(ba_CompVerts, 0, ba_CompVerts.Length); FO.Write(ba_CompLMUV, 0, ba_CompLMUV.Length); break; #endregion case TSFReader.TSFResource: // 0xAD: //Resource #region Resource /* * ushort BitmapSoundFlag = GetUShort(TagBuff,0x00 + (sc * Size)); * ushort Index = GetUShort(TagBuff,0x02 + (sc * Size)); * ushort ID1 = GetUShort(TagBuff,0x04 + (sc * Size)); * ushort ID2 = GetUShort(TagBuff,0x06 + (sc * Size)); * MapPosSave = fs.Position; * uint Offset = Info.IndexItems[ID1].OffsetToString; /// fileData.stringOffset.UInt - Info.MapMagic; * fs.Seek((long)Offset,SeekOrigin.Begin); * byte[] rscstr = new byte[256]; * fs.Read(rscstr,0,rscstr.Length); * fs.Seek(MapPosSave,SeekOrigin.Begin); * uint rscsize = 0; * do * { * rscsize +=1; * }while (rscstr[rscsize] != 0); * byte[] rscOutString = new byte[rscsize + 1]; * uint rsccount = 0; * do * { * rscOutString[rsccount] = rscstr[rsccount]; * rsccount +=1; * }while (rsccount != rscsize); * PutUShort(ref TagBuff,(uint)(0x06 + (sc * Size)),(ushort)(rscOutString.Length - 1)); * FO.Write(rscOutString,0,rscOutString.Length); */ break; #endregion case TSFReader.TSFEnd: // 0xA7: //End #region StructEnd if (sr.GetOIP() == Name) { ExitStruct = true; } else { ExitStruct = false; } break; #endregion } }while(ExitStruct == false); if (Count != 0) { sc += 1; if (sc != Count) { sr.Seek(StartOfStruct); ExitStruct = false; } } }while (sc != Count); long tmpPosSave = FO.Position; FO.Seek(StructPosition, SeekOrigin.Begin); FO.Write(TagBuff, 0, TagBuff.Length); FO.Seek(tmpPosSave, SeekOrigin.Begin); }
public void Load(ref FileStream FI) { MapHeader = new H1_MapHeader(); //IndexHeader = new H1_Index_Header(); MapHeader.Load(ref FI); switch (MapHeader.Map_Version) { case 0x05: IndexHeader = new IndexHeaderBase.XIndexHeader(); break; case 0x07: case 0x261: IndexHeader = new IndexHeaderBase.IndexHeader(); break; } FI.Seek(MapHeader.Offset_To_Index, System.IO.SeekOrigin.Begin); IndexHeader.Load(ref FI); uint StartOfTags = (uint)FI.Position;//MapHeader.Offset_To_Index + 36 + 4; Map_Magic = IndexHeader.IndexMagic - StartOfTags; //FI.Seek(StartOfTags,System.IO.SeekOrigin.Begin); IndexItems = new h1_Tag_Index_Item[IndexHeader.TagCount]; IndexItemStringList = new string[IndexHeader.TagCount]; uint BSPCount = 0; for (int ind = 0; ind < IndexHeader.TagCount; ind += 1) { IndexItems[ind] = new h1_Tag_Index_Item(); IndexItems[ind].Load(ref FI); if (IndexItems[ind].Type1 == 0x73627370) //Test for BSP tags { uint MapFileSavePos = (uint)FI.Position; //Seek to Scnr FI.Seek(IndexItems[0].MetaOffset, System.IO.SeekOrigin.Begin); //Read SCNR header byte[] SCNRHeader = new byte[1456]; FI.Read(SCNRHeader, 0, SCNRHeader.Length); //uint BSPSectionChunkCount = BitConverter.ToUInt32(SCNRHeader,1444); uint BSPSectionOffset = BitConverter.ToUInt32(SCNRHeader, 1444 + 4) - Map_Magic; byte[] BSPInfo = new byte[32]; FI.Seek(BSPSectionOffset + (32 * BSPCount), System.IO.SeekOrigin.Begin); FI.Read(BSPInfo, 0, BSPInfo.Length); IndexItems[ind].MetaOffset = BitConverter.ToUInt32(BSPInfo, 0); IndexItems[ind].MetaMagic = BitConverter.ToUInt32(BSPInfo, 8) - IndexItems[ind].MetaOffset; FI.Seek(IndexItems[ind].MetaOffset, SeekOrigin.Begin); byte[] tmpBSPNormalHeader = new byte[0x18]; FI.Read(tmpBSPNormalHeader, 0, 0x18); IndexItems[ind].MetaOffset = BitConverter.ToUInt32(tmpBSPNormalHeader, 0) - IndexItems[ind].MetaMagic; IndexItems[ind].OffsetToString = IndexItems[ind].OffsetToString - Map_Magic;//BitConverter.ToUInt32(BSPInfo,20) - Map_Magic;//IndexItems[ind].OffsetToString - Map_Magic; BSPCount += 1; FI.Seek(MapFileSavePos, System.IO.SeekOrigin.Begin); } else { IndexItems[ind].MetaOffset = IndexItems[ind].MetaOffset - Map_Magic; IndexItems[ind].OffsetToString = IndexItems[ind].OffsetToString - Map_Magic; IndexItems[ind].MetaMagic = Map_Magic; } } FilenameTable = new Hashtable((int)IndexHeader.TagCount); for (int strs = 0; strs < IndexHeader.TagCount; strs += 1) { TSFReader STSF = new TSFReader(); STSF.TSF(ref mr, IndexItems[strs].Type1); IndexItemStringList[strs] = CompUtil.StringLoader(ref FI, IndexItems[strs].OffsetToString) + STSF.Name; STSF = null; FilenameTable.Add(IndexItemStringList[strs], strs); } }
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] + @"\"; } } MTSFReader mr; mr = new MTSFReader(); mr.MTSFRead("Core.Compiler.HALO_PC_SET.MTSF"); TSFReader STSF = new TSFReader(); STSF.TSF(ref mr, CompUtil.RevUInt(HaloMap.IndexItems[index].Type1)); //string ExtName = STSF.Name; //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; Struct.StructInfo TagInfo = new Struct.StructInfo(); TagInfo.MapMagic = HaloMap.Map_Magic; TagInfo.MapVersion = HaloMap.MapHeader.Map_Version; TagInfo.SoundsFile = fsSound; TagInfo.BitmapsFile = fsBitmap; TagInfo.IndexItems = HaloMap.IndexItems; TagInfo.TagMagic = HaloMap.IndexItems[index].MetaMagic; TagInfo.IndicesOffset = HaloMap.IndexHeader.Index_Offset; TagInfo.VerticesOffset = HaloMap.IndexHeader.Verts_Offset; TagInfo.CurrentIndex = (uint)index; TagInfo.TagHeaderSize = 0x40; // Create a new struct processor Struct MainStruct = new Struct(); string[] Tags = null; MainStruct.DoProcessStruct(ref STSF, ref fsin, ref msout, 1, STSF.GetUName(), ref TagInfo, ref Tags, ref Tags); //******FIX ME ******// Structure2 MainStruct = new Structure2(); //******FIX ME ******// 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 = HaloMap.IndexItems[index].Type1; tag_hdr.TagClass1 = HaloMap.IndexItems[index].Type2; tag_hdr.TagClass2 = HaloMap.IndexItems[index].Type3; tag_hdr.GameVersion = 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); m_OutputArchive.AddFile(HaloMap.IndexItemStringList[index], GetSubArray(msout.GetBuffer(), 0, (int)msout.Position - 12)); } msout.Close(); fsBitmap.Close(); fsSound.Close(); }
public void DoProcessMeta(ref TSFReader sr, MemoryStream FI, ref FileStream FO, ref FileStream VertsFile, ref FileStream IndFile, ref FileStream BSPFile, uint Count, string[] IndexStrings, StructInfo Info) { TabReplace += (char)TabByte; Name = sr.GetUName(); //CMD[2]; Size = sr.GetSOC(); TagBuff = new byte[Size * Count]; FI.Read(TagBuff, 0, TagBuff.Length); //FixIntPosition(ref FO); long StructPosition = FO.Position; FO.Write(TagBuff, 0, TagBuff.Length); uint StartOfStruct = sr.Position; uint sc = 0; bool ExitStruct = false; do { do { //InLine = sr.Read(); //CMD = InLine.Replace(TabReplace,"").ToLower().Trim().Split(new char[]{' '},256); sr.Read(); switch (sr.GetCMD()) { case TSFReader.TSFStruct: // "struct": uint ChildCount = GetUInt(TagBuff, (uint)(sr.GetOIP() + (sc * Size))); if (ChildCount != 0) { PCMeta Child = new PCMeta(); PutUInt(ref TagBuff, (uint)(sr.GetOIP() + 4 + (sc * Size)), (uint)(FO.Position + Info.TagMagic)); Child.DoProcessMeta(ref sr, FI, ref FO, ref VertsFile, ref IndFile, ref BSPFile, ChildCount, IndexStrings, Info); FixIntPosition(ref FO); } else { sr.SeekAheadTo(0xA7, sr.GetUName()); //sr.SeekAheadTo("end " + CMD[2]); //sr.Seek(sr.Position + 1); } break; case TSFReader.TSFBSPTagRef: // "bspstagref": case TSFReader.TSFTagRef: // "tagref": uint tStringSize = 0; GetUInt(TagBuff, (uint)(sr.GetOIP() + (sc * Size)) + 0x08, ref tStringSize); if (tStringSize != 0x00) { PutUInt(ref TagBuff, (uint)(sr.GetOIP() + (sc * Size)) + 0x04, 0x00000000); PutUInt(ref TagBuff, (uint)(sr.GetOIP() + (sc * Size)) + 0x08, 0x00000000); uint TagClass = GetUInt(TagBuff, (uint)(sr.GetOIP() + (sc * Size))); string TagClassString = GetTagClassRev(BitConverter.GetBytes(TagClass), 0); byte[] tmpStr = new byte[tStringSize + 1]; FI.Read(tmpStr, 0, tmpStr.Length); string tag = ReadString(tmpStr, 0); int t = 0; //string[] test; bool con = false; do { string[] test = Info.Items[t].NameString.Split(new char[] { '.' }, 256); //IndexStrings[t].Split(new char[]{'.'},256); string testClass = GetTagClassRev(BitConverter.GetBytes(Info.Items[t].TagClass1), 0); if (testClass == TagClassString && test[0] == tag) { con = true; } else { t += 1; } }while (con == false); // testClass != TagClass); PutUInt(ref TagBuff, (uint)(sr.GetOIP() + (sc * Size)) + 0x04, Info.Items[t].StringOffset); PutUShort(ref TagBuff, (uint)(sr.GetOIP() + (sc * Size)) + 0x0C, (ushort)Info.Items[t].IndexID1); PutUShort(ref TagBuff, (uint)(sr.GetOIP() + (sc * Size)) + 0x0E, (ushort)Info.Items[t].IndexID2); if (Name == 0x0468) { uint SaveTagMagic = Info.TagMagic; byte[] BspHeader = new byte[0x18]; PutUInt(ref TagBuff, 0x00 + (sc * Size), (uint)(0x800 + BSPFile.Position)); uint CurrentPosition = (uint)BSPFile.Position; Info.CurrentOffset = (uint)BSPFile.Position; MTSFReader mr = new MTSFReader(); mr.MTSFRead("Core.Compiler.HALO_PC_SET.MTSF"); TSFReader tmpSTSF = new TSFReader(); //SwapInt(TagClasses,0); tmpSTSF.TSF(ref mr, 0x70736273); // 73627370); //MAG tmpsr = new MAG(Info.StructurePath + "sbsp.mag"); //FileInfo BspMetaFile_info = new FileInfo(Info.TagsPath + tag + "." + tmpSTSF.Name); //FileStream BspMetaFile; //BspMetaFile = BspMetaFile_info.Open(FileMode.Open,FileAccess.Read); //BspMetaFile.Seek(0x40,SeekOrigin.Begin); TagFileName tfnTAG = new TagFileName(tag + "." + tmpSTSF.Name, MapfileVersion.HALOPC); TagBase tbTAG = new TagBase(); tbTAG.LoadTagBuffer(tfnTAG); string[] gh; int tt = -1; do { tt += 1; }while((tag + "." + tmpSTSF.Name) != Info.Items[tt].NameString); uint BSPFileSize = (0x800 - ((uint)(Info.Items[tt].MetaSize) % 0x800)); BSPFileSize += (uint)(Info.Items[tt].MetaSize); uint tmpMagic = (uint)(0x41B40000 - BSPFileSize); Info.TagMagic = tmpMagic; PutUInt(ref TagBuff, 0x08 + (sc * Size), tmpMagic); PutUInt(ref BspHeader, 0x00 + (sc * Size), 0x18 + tmpMagic); PutUInt(ref BspHeader, 0x14 + (sc * Size), 0x73627370); BSPFile.Write(BspHeader, 0, BspHeader.Length); PCMeta BspMeta = new PCMeta(); BspMeta.DoProcessMeta(ref tmpSTSF, tbTAG.Stream, ref BSPFile, ref VertsFile, ref IndFile, ref BSPFile, 1, IndexStrings, Info); FixIntPosition2K(ref BSPFile); PutUInt(ref TagBuff, 0x04 + (sc * Size), (uint)(CurrentPosition + BSPFile.Position)); //BspMetaFile.Close(); tbTAG = null; Info.TagMagic = SaveTagMagic; int a = 0; } } break; case TSFReader.TSFInternalRaw: // "internalraw": uint RawSize = GetUInt(TagBuff, (uint)(sr.GetOIP() + (sc * Size))); //Compile Mag.Map if (RawSize == 0) { break; } uint RawOffset = GetUInt(TagBuff, (uint)(sr.GetOIP() + 0x0c + (sc * Size))); //Tag Text PutUInt(ref TagBuff, (uint)(sr.GetOIP()) + 0x0c + (sc * Size), ((uint)FO.Position + Info.TagMagic)); byte[] tmp = new byte[RawSize]; FI.Read(tmp, 0, tmp.Length); FO.Write(tmp, 0, tmp.Length); FixIntPosition(ref FO); tmp = null; break; case TSFReader.TSFBitmapRaw: // "bitmapraw": uint TiffSize = 0; GetUInt(TagBuff, 0x1C, ref TiffSize); byte[] TiffBuffer = new byte[TiffSize]; FI.Read(TiffBuffer, 0, TiffBuffer.Length); uint BitmapSize = GetUInt(TagBuff, 0x30); TiffBuffer = new byte[BitmapSize]; FI.Read(TiffBuffer, 0, TiffBuffer.Length); TiffBuffer = null; break; case TSFReader.TSFModelData: // "modeldata": long SaveMapFilePos = (uint)FI.Position; uint TrueVerticesSize = (GetUInt(TagBuff, (uint)(88 + (sc * Size)))) * 68; uint TrueIndicesSize = (((GetUInt(TagBuff, (uint)(72 + (sc * Size)))) / 3) + 1) * 6; uint NewIndicesDataSize = (GetUInt(TagBuff, (uint)(72 + (sc * Size))) / 3) + 1; byte[] RawModelBuffer = new byte[TrueVerticesSize]; FI.Read(RawModelBuffer, 0, RawModelBuffer.Length); PutUInt(ref TagBuff, (uint)(0x64 + (sc * Size)), (uint)VertsFile.Position); PutUInt(ref TagBuff, (uint)(0x4C + (sc * Size)), (uint)IndFile.Position); PutUInt(ref TagBuff, (uint)(0x50 + (sc * Size)), (uint)IndFile.Position); VertsFile.Write(RawModelBuffer, 0, RawModelBuffer.Length); RawModelBuffer = new byte[TrueIndicesSize]; FI.Read(RawModelBuffer, 0, RawModelBuffer.Length); IndFile.Write(RawModelBuffer, 0, RawModelBuffer.Length); byte[] TestBuffer = new byte[6]; FI.Read(TestBuffer, 0, 6); if (TestBuffer[4] == 0xff) { IndFile.Write(TestBuffer, 0, TestBuffer.Length); } else { FI.Seek(FI.Position - 6, SeekOrigin.Begin); } FixIntPosition(ref IndFile); break; case TSFReader.TSFBSPModel: // "bspmodel": uint UnCompressedVerts = sr.GetOIP(); uint CompressedVerts = sr.GetSOC(); uint UnCompressedVertsOffset = sr.GetOIP(); //uint VertsOffset = GetUInt(TagBuff,CompressedVerts); uint TrueVertCount = GetUInt(TagBuff, 180 + (sc * Size)); uint TrueLightMapDataCount = GetUInt(TagBuff, 200 + (sc * Size)); uint UnCompressedLightMapData = (TrueLightMapDataCount * 20); uint CompressedLightMapData = (TrueLightMapDataCount * 8); UnCompressedVerts = (TrueVertCount * 56); CompressedVerts = (TrueVertCount * 32); byte[] BspVertsUnCompressed = new byte[UnCompressedVerts]; FI.Read(BspVertsUnCompressed, 0, BspVertsUnCompressed.Length); PutUInt(ref TagBuff, 0xe4 + (sc * Size), (uint)(FO.Position + Info.TagMagic)); FO.Write(BspVertsUnCompressed, 0, BspVertsUnCompressed.Length); //byte[] BspVertsCompressed = new byte[CompressedVerts]; byte[] BspLightMapDataUnCompressed = new byte[UnCompressedLightMapData]; FI.Read(BspLightMapDataUnCompressed, 0, BspLightMapDataUnCompressed.Length); FO.Write(BspLightMapDataUnCompressed, 0, BspLightMapDataUnCompressed.Length); //byte[] BspLightMapDataCompressed = new byte[CompressedLightMapData]; //viper told me to skip past compressed data as a quick fix to // the crash problem - Grenadiac FI.Seek(CompressedVerts, SeekOrigin.Current); //gren added this FI.Seek(CompressedLightMapData, SeekOrigin.Current); //gren added this break; case TSFReader.TSFResource: // "resources": ushort rStringSize = GetUShort(TagBuff, 0x06 + (sc * Size)); if (rStringSize != 0x00) { uint TagClassFlag = GetUShort(TagBuff, 0x00 + (sc * Size)); string TagClassString = ""; switch (TagClassFlag) { case 0x00: TagClassString = "bitm"; break; case 0x01: TagClassString = "snd!"; break; } //MAG tmpMR = new MAG(Info.StructurePath + TagClassString.Trim() + ".mag"); byte[] tmpStr = new byte[rStringSize + 1]; FI.Read(tmpStr, 0, tmpStr.Length); string tag = ReadString(tmpStr, 0); //tmpMR.Seek(0); int t = 0; //string[] test; bool con = false; do { string[] test = Info.Items[t].GetString().Split(new char[] { '.' }, 256); //IndexStrings[t].Split(new char[]{'.'},256); string testClass = GetTagClassRev(BitConverter.GetBytes(Info.Items[t].TagClass1), 0); if (testClass == TagClassString && test[0] == tag) { con = true; } else { t += 1; } }while (con == false); PutUShort(ref TagBuff, (uint)(0x04 + (sc * Size)), (ushort)Info.Items[t].IndexID1); PutUShort(ref TagBuff, (uint)(0x06 + (sc * Size)), (ushort)Info.Items[t].IndexID2); } break; case TSFReader.TSFSoundData: // "sounddata": uint sRawSize = GetUInt(TagBuff, (uint)(sr.GetOIP() + (sc * Size))); uint sRawOffset = GetUInt(TagBuff, (uint)(sr.GetUName() + (sc * Size))); byte[] stmp = new byte[sRawSize]; FI.Read(stmp, 0, stmp.Length); stmp = null; break; case TSFReader.TSFEnd: // "end": if (sr.GetOIP() == Name) { ExitStruct = true; } else { ExitStruct = false; } break; } }while(ExitStruct == false); if (Count != 0) { sc += 1; if (sc != Count) { sr.Seek(StartOfStruct); ExitStruct = false; } } }while(sc != Count); long tmpPosSave = FO.Position; FO.Seek(StructPosition, SeekOrigin.Begin); FO.Write(TagBuff, 0, TagBuff.Length); FO.Seek(tmpPosSave, SeekOrigin.Begin); }
public static void Build() { TagFileName scenario_tag = ProjectManager.ScenarioTagFileName; //IndexBuilder IndexBuild = new IndexBuilder(); Compiler_Gren.DependencyBuilder IndexBuild = new Compiler_Gren.DependencyBuilder(); //FileInfo TagFile_info = new FileInfo(scenario_tag.RelativePath); string BasFolder = Application.StartupPath + @"\Extracted Tags\"; string StructFolder = Application.StartupPath + @"\Tag Structures\PcHalo\"; //string MapsFolder = Application.StartupPath + @"\Maps\"; if (true) { //Create the index table //lbCurTag.Text = "Building Index Table...."; Application.DoEvents(); //string[] IndexList = IndexBuild.BuildIndex(scenario_tag.RelativePath, BasFolder, StructFolder); string[] IndexList = IndexBuild.BuildIndex(scenario_tag); HaloPCMAP.HaloPC NewMap = new HaloPCMAP.HaloPC(); NewMap.PCIndexHeader.Create((uint)IndexList.Length); NewMap.PCIndexHeader.IndexMagic = 0x40440028; uint StringTableSize = 0; //Fixing index items ushort gt = 0xE174; //lbCurTag.Text = "Building Index Table Items...."; Application.DoEvents(); for (int sc = 0; sc < IndexList.Length; sc++) { //FileInfo TagFile2_info = new FileInfo(BasFolder + IndexList[sc]); //FileStream TagFile2; //TagFile2 = TagFile2_info.Open(FileMode.Open,FileAccess.Read); //byte[] tmp = new byte[0x40]; //TagFile2.Read(tmp,0x00,tmp.Length); //TagFile2.Close(); TagFileName tfnTAG = new TagFileName(IndexList[sc], MapfileVersion.HALOPC); TagBase tbTAG = new TagBase(); tbTAG.LoadTagBuffer(tfnTAG); //uint TagClass1 = BitConverter.ToUInt32(tmp,0x24); //uint TagClass2 = BitConverter.ToUInt32(tmp,0x28); //uint TagClass3 = BitConverter.ToUInt32(tmp,0x2C); NewMap.PCIndexHeader.IndexItems[sc].Create(); NewMap.PCIndexHeader.IndexItems[sc].TagClass1 = SwapUInt(tbTAG.Header.TagClass0); // TagClass1; NewMap.PCIndexHeader.IndexItems[sc].TagClass2 = SwapUInt(tbTAG.Header.TagClass1); // TagClass2; NewMap.PCIndexHeader.IndexItems[sc].TagClass3 = SwapUInt(tbTAG.Header.TagClass2); // TagClass3; NewMap.PCIndexHeader.IndexItems[sc].IndexID1 = (ushort)sc; NewMap.PCIndexHeader.IndexItems[sc].IndexID2 = gt; NewMap.PCIndexHeader.IndexItems[sc].NameString = IndexList[sc]; if (tbTAG.Header.TagClass0 == 0x70736273 || tbTAG.Header.TagClass0 == 0x73627370) { NewMap.PCIndexHeader.IndexItems[sc].MetaSize = IndexBuild.BSPSizes[0]; } else { NewMap.PCIndexHeader.IndexItems[sc].MetaSize = 0; } if (tbTAG.Header.TagClass0 == 0x7274656d || tbTAG.Header.TagClass0 == 0x6d657472)// 6d657472) { gt += 2; } else { gt += 1; } string[] RemoveExt = IndexList[sc].Split(new char[] { '.' }, 256); NewMap.PCIndexHeader.IndexItems[sc].String = new byte[RemoveExt[0].Length + 1]; HaloPCMAP.StringToByteArray(ref NewMap.PCIndexHeader.IndexItems[sc].String, RemoveExt[0]); StringTableSize += (uint)(IndexList[sc].Length + 1); tbTAG = null; } //Creating the temp files for map building FileInfo VertsFile_info = new FileInfo(Application.StartupPath + "TempVerts.Map"); FileStream VertsFile; VertsFile = VertsFile_info.Open(FileMode.Create, FileAccess.ReadWrite); FileInfo IndicesFile_info = new FileInfo(Application.StartupPath + "TempIndices.Map"); FileStream IndicesFile; IndicesFile = IndicesFile_info.Open(FileMode.Create, FileAccess.ReadWrite); FileInfo MetaFile_info = new FileInfo(Application.StartupPath + "TempMeta.map"); FileStream MetaFile; MetaFile = MetaFile_info.Open(FileMode.Create, FileAccess.ReadWrite); FileInfo BSPFile_info = new FileInfo(Application.StartupPath + "TempBSP.map"); FileStream BSPFile; BSPFile = BSPFile_info.Open(FileMode.Create, FileAccess.ReadWrite); //lbCurTag.Text = "Writeing Index Table...."; Application.DoEvents(); //writing the index table the temp files for (int sc = 0; sc < NewMap.PCIndexHeader.IndexItems.Length; sc++) { NewMap.PCIndexHeader.IndexItems[sc].Write(ref MetaFile); } //Rewriting index items to temp file to fix string offsets. //lbCurTag.Text = "Rewriteing Index Table...."; Application.DoEvents(); for (int sc = 0; sc < NewMap.PCIndexHeader.IndexItems.Length; sc++) { NewMap.PCIndexHeader.IndexItems[sc].StringOffset = (uint)MetaFile.Position + NewMap.PCIndexHeader.IndexMagic; MetaFile.Write(NewMap.PCIndexHeader.IndexItems[sc].String, 0, NewMap.PCIndexHeader.IndexItems[sc].String.Length); } //save MetaFile position to return for meta writing. long TmpPosSave = MetaFile.Position; //lbCurTag.Text = "Writing Index Table with Srtring Offsets...."; Application.DoEvents(); for (int sc = 0; sc < NewMap.PCIndexHeader.IndexItems.Length; sc++) { MetaFile.Seek(NewMap.PCIndexHeader.IndexItems[sc].Position, SeekOrigin.Begin); NewMap.PCIndexHeader.IndexItems[sc].Write(ref MetaFile); } //restore position for meta writing MetaFile.Seek(TmpPosSave, SeekOrigin.Begin); //Add info to the Meta info struct PCMeta.StructInfo Info = new PCMeta.StructInfo(); Info.MapMagic = NewMap.PCIndexHeader.IndexMagic; Info.TagMagic = NewMap.PCIndexHeader.IndexMagic; Info.StructurePath = StructFolder; Info.TagsPath = BasFolder; Info.Items = NewMap.PCIndexHeader.IndexItems; //Starts processing meta and writing it to the meta file //lbCurTag.Text = "Adding Tags to map...."; Application.DoEvents(); for (int sc = 0; sc < NewMap.PCIndexHeader.IndexItems.Length; sc++) { if (NewMap.PCIndexHeader.IndexItems[sc].TagClass1 != 0x70736273) // 70736273) { PCMeta Meta = new PCMeta(); //FileInfo Tag_info = new FileInfo(BasFolder + IndexList[sc]); //FileStream Tag; //Tag = Tag_info.Open(FileMode.Open,FileAccess.Read); //byte[] head = new byte[0x40]; //Tag.Read(head,0,head.Length); TagFileName tfnTAG = new TagFileName(IndexList[sc], MapfileVersion.HALOPC); TagBase tbTAG = new TagBase(); tbTAG.LoadTagBuffer(tfnTAG); //string Class = Meta.GetTagClass(head,0x24); //MAG sr = new MAG(StructFolder + Class.Trim() + ".mag"); //sr.Seek(1); MTSFReader mr = new MTSFReader(); mr.MTSFRead("Core.Compiler.HALO_PC_SET.MTSF"); TSFReader STSF = new TSFReader(); //SwapInt(TagClasses,0); STSF.TSF(ref mr, tbTAG.Header.TagClass0); HaloPCMAP.FixIntPosition(ref MetaFile); Info.CurrentOffset = (uint)MetaFile.Position; NewMap.PCIndexHeader.IndexItems[sc].MetaOffset = (uint)(MetaFile.Position + NewMap.PCIndexHeader.IndexMagic); Meta.DoProcessMeta(ref STSF, tbTAG.Stream, ref MetaFile, ref VertsFile, ref IndicesFile, ref BSPFile, 1, IndexList, Info); tbTAG = null; //Tag.Flush(); //Tag.Close(); } } //Create a new map header //lbCurTag.Text = "Creating New Map...."; Application.DoEvents(); NewMap.PCHeader.Create(); string[] tmpName = scenario_tag.RelativePath.Split(new char[] { '\\' }, 256); tmpName = tmpName[tmpName.Length - 1].Split(new char[] { '.' }, 256); NewMap.PCHeader.MapName = tmpName[0];//otf.FileName.Split(new char[]{'/'},256 //"Cool"; //NewMap.PCHeader.Write(ref HeadFile); //Rewrite indextable of meta offsets //lbCurTag.Text = "Fixing Meta Offsets in Index Table...."; Application.DoEvents(); TmpPosSave = MetaFile.Position; for (int sc = 0; sc < NewMap.PCIndexHeader.IndexItems.Length; sc++) { MetaFile.Seek(NewMap.PCIndexHeader.IndexItems[sc].Position, SeekOrigin.Begin); NewMap.PCIndexHeader.IndexItems[sc].Write(ref MetaFile); } MetaFile.Seek(TmpPosSave, SeekOrigin.Begin); //Create the new map file to begin construction of the new map. FileInfo Map_info = new FileInfo(Application.StartupPath + NewMap.PCHeader.MapName + ".Map"); FileStream Map; Map = Map_info.Open(FileMode.Create, FileAccess.ReadWrite); //lbCurTag.Text = "Copying Data to new map file...."; Application.DoEvents(); //Write the header to the new map file NewMap.PCHeader.Write(ref Map); //Flush the tmp BSPFile to get FileSize. BSPFile.Flush(); uint BSPFileSize = (uint)BSPFile.Length; //Seek to the begining of the tmp bsp file BSPFile.Seek(0, SeekOrigin.Begin); //Copy the Tmp bsp file to the new map file for (int bc = 0; bc < BSPFileSize; bc += 4) { byte[] copy = new byte[4]; BSPFile.Read(copy, 0, copy.Length); Map.Write(copy, 0, copy.Length); } //Flush the Temp verts file to get File size; VertsFile.Flush(); uint VertsFileSize = (uint)VertsFile.Length; //Put Current Map Position in the indexheader, this sets the position of the verts in the map. NewMap.PCIndexHeader.VertsOffset = (uint)Map.Position; //seek to begining of the Verts file for coping to the new map file VertsFile.Seek(0, SeekOrigin.Begin); //Copy the verts to the map file for (int bc = 0; bc < VertsFileSize; bc += 4) { byte[] copy = new byte[4]; VertsFile.Read(copy, 0, copy.Length); Map.Write(copy, 0, copy.Length); } //Flush Indeices file to get size IndicesFile.Flush(); uint IndicesFileSize = (uint)IndicesFile.Length; //Put the Scnr index ID in the IndexHeader, you can move the scnr any were as long as you set this to the currect ID. NewMap.PCIndexHeader.ScnrID = (uint)((NewMap.PCIndexHeader.IndexItems[0].IndexID2 << 16) + NewMap.PCIndexHeader.IndexItems[0].IndexID1); //ajust the IndicesOffset with verts offset and map position NewMap.PCIndexHeader.IndicesOffset = (uint)Map.Position - NewMap.PCIndexHeader.VertsOffset; NewMap.PCIndexHeader.ModelAreaSize = VertsFileSize + IndicesFileSize; //Seek to begining of IndicesFile for coping IndicesFile.Seek(0, SeekOrigin.Begin); //Copy Indices to new map file for (int bc = 0; bc < IndicesFileSize; bc += 4) { byte[] copy = new byte[4]; IndicesFile.Read(copy, 0, copy.Length); Map.Write(copy, 0, copy.Length); } //put the Current map position in the header so we know where the index header will be NewMap.PCHeader.IndexOffset = (uint)Map.Position; //Now we write the Index header to the map. NewMap.PCIndexHeader.Write(ref Map); //Flush the temp meta file so we can get the size. MetaFile.Flush(); uint MetaFileSize = (uint)MetaFile.Length; //seek to the begining of the temp meta file for coping to the new map file MetaFile.Seek(0, SeekOrigin.Begin); //Copy the meta file to the new map file. for (int bc = 0; bc < MetaFileSize; bc += 4) { byte[] copy = new byte[4]; MetaFile.Read(copy, 0, copy.Length); Map.Write(copy, 0, copy.Length); } //Now we fix the map version map size and rewrite it to the map. Map.Flush(); NewMap.PCHeader.MapVersion = 0x07; NewMap.PCHeader.MapSize = (uint)Map.Length; NewMap.PCHeader.MetaSize = MetaFileSize + 0x28; Map.Seek(NewMap.PCHeader.Position, SeekOrigin.Begin); NewMap.PCHeader.Write(ref Map); //Now close the files and delete the temp files. VertsFile.Close(); IndicesFile.Close(); MetaFile.Flush(); MetaFile.Close(); BSPFile.Close(); Map.Close(); //FileStream TagFile; //TagFile = Tag } }
public void DoProcessMeta(ref TSFReader sr, MemoryStream FI, ref FileStream FO, ref FileStream BSPFile, uint Count, string[] IndexStrings, StructInfo Info, ref XBoxHaloMap.sXBoxHalo XBoxMap, ref IndexBuilder IndexBuild) { TabReplace += (char)TabByte; Name = sr.GetUName(); Size = sr.GetSOC(); TagBuff = new byte[Size * Count]; FI.Read(TagBuff, 0, TagBuff.Length); long StructPosition = FO.Position; FO.Write(TagBuff, 0, TagBuff.Length); uint StartOfStruct = sr.Position; uint sc = 0; bool ExitStruct = false; do { do { sr.Read(); switch (sr.GetCMD()) { case TSFReader.TSFStruct: // "struct": #region Structure uint ChildCount = CompUtil.GetUInt(TagBuff, (uint)(sr.GetOIP() + (sc * Size))); if (ChildCount != 0) { XBoxMeta Child = new XBoxMeta(); CompUtil.PutUInt(ref TagBuff, (uint)(sr.GetOIP() + 4 + (sc * Size)), (uint)(FO.Position + Info.TagMagic)); Child.DoProcessMeta(ref sr, FI, ref FO, ref BSPFile, ChildCount, IndexStrings, Info, ref XBoxMap, ref IndexBuild); CompUtil.FixIntPosition(ref FO); } else { sr.SeekAheadTo(0xA7, sr.GetUName()); //sr.SeekAheadTo("end " + CMD[2]); //sr.Seek(sr.Position + 1); } break; #endregion case TSFReader.TSFBSPTagRef: // "bspstagref": case TSFReader.TSFTagRef: // "tagref": #region TagRefernce uint tStringSize = 0; CompUtil.GetUInt(TagBuff, (uint)(sr.GetOIP() + (sc * Size)) + 0x08, ref tStringSize); if (tStringSize != 0x00) { CompUtil.PutUInt(ref TagBuff, (uint)(sr.GetOIP() + (sc * Size)) + 0x04, 0x00000000); CompUtil.PutUInt(ref TagBuff, (uint)(sr.GetOIP() + (sc * Size)) + 0x08, 0x00000000); uint TagClass = CompUtil.GetUInt(TagBuff, (uint)(sr.GetOIP() + (sc * Size))); string TagClassString = CompUtil.GetTagClassRev(BitConverter.GetBytes(TagClass), 0); byte[] tmpStr = new byte[tStringSize + 1]; FI.Read(tmpStr, 0, tmpStr.Length); string tag = CompUtil.ReadString(tmpStr, 0); int t = 0; //string[] test; bool con = false; do { string[] test = Info.Items[t].NameString.Split(new char[] { '.' }, 256); //IndexStrings[t].Split(new char[]{'.'},256); string testClass = CompUtil.GetTagClassRev(BitConverter.GetBytes(Info.Items[t].TagClass1), 0); if (testClass == TagClassString && test[0] == tag) { con = true; } else { t += 1; } }while (con == false); // testClass != TagClass); CompUtil.SwapInt(ref TagBuff, (uint)(sr.GetOIP() + (sc * Size)) + 0x00); CompUtil.PutUInt(ref TagBuff, (uint)(sr.GetOIP() + (sc * Size)) + 0x04, Info.Items[t].StringOffset); CompUtil.PutUShort(ref TagBuff, (uint)(sr.GetOIP() + (sc * Size)) + 0x0C, (ushort)Info.Items[t].IndexID1); CompUtil.PutUShort(ref TagBuff, (uint)(sr.GetOIP() + (sc * Size)) + 0x0E, (ushort)Info.Items[t].IndexID2); if (Name == 0x0468) { uint SaveTagMagic = Info.TagMagic; byte[] BspHeader = new byte[0x18]; CompUtil.PutUInt(ref TagBuff, 0x00 + (sc * Size), (uint)(0x800 + BSPFile.Position)); uint CurrentPosition = (uint)BSPFile.Position; Info.CurrentOffset = (uint)BSPFile.Position; MTSFReader mr = new MTSFReader(); mr.MTSFRead("Core.Compiler.HALO_PC_SET.MTSF"); TSFReader tmpSTSF = new TSFReader(); //SwapInt(TagClasses,0); tmpSTSF.TSF(ref mr, 0x70736273); // 73627370); //MAG tmpsr = new MAG(Info.StructurePath + "sbsp.mag"); //FileInfo BspMetaFile_info = new FileInfo(Info.TagsPath + tag + "." + tmpSTSF.Name); //FileStream BspMetaFile; //BspMetaFile = BspMetaFile_info.Open(FileMode.Open,FileAccess.Read); //BspMetaFile.Seek(0x40,SeekOrigin.Begin); Trace.WriteLine(tag + ".sbsp" + " Hello I'm your bsp"); TagFileName tfnTAG = new TagFileName(tag + "." + tmpSTSF.Name, MapfileVersion.XHALO1); TagBase tbTAG = new TagBase(); tbTAG.LoadTagBuffer(tfnTAG); string[] gh; int tt = -1; do { tt += 1; }while((tag + "." + tmpSTSF.Name) != Info.Items[tt].NameString); uint BSPFileSize = (0x800 - ((uint)(Info.Items[tt].MetaSize) % 0x800)); BSPFileSize += (uint)(Info.Items[tt].MetaSize); uint tmpMagic = (uint)(0x819a5800 - BSPFileSize); Info.TagMagic = tmpMagic; CompUtil.PutUInt(ref TagBuff, 0x08 + (sc * Size), tmpMagic); //IndexBuild.XBoxMapData.XBSPVerts.Finish(); uint CompoundSize = (uint)IndexBuild.XBoxMapData.XBSPVerts.VIndirectOffsets.Length + (uint)IndexBuild.XBoxMapData.XBSPVerts.LIndirectOffsets.Length + (uint)IndexBuild.XBoxMapData.XBSPVerts.ModelData.Length; CompUtil.PutUInt(ref BspHeader, 0x00 + (sc * Size), 0x18 + CompoundSize + tmpMagic); CompUtil.PutUInt(ref BspHeader, 0x04 + (sc * Size), IndexBuild.XBoxMapData.XBSPVerts.DataCount); CompUtil.PutUInt(ref BspHeader, 0x08 + (sc * Size), 0x18 + tmpMagic); CompUtil.PutUInt(ref BspHeader, 0x0C + (sc * Size), IndexBuild.XBoxMapData.XBSPVerts.DataCount); CompUtil.PutUInt(ref BspHeader, 0x10 + (sc * Size), (uint)((IndexBuild.XBoxMapData.XBSPVerts.VIndirectOffsets.Length + 0x18) + tmpMagic)); CompUtil.PutUInt(ref BspHeader, 0x14 + (sc * Size), 0x73627370); long BSPHeaderPos = BSPFile.Position; BSPFile.Write(BspHeader, 0, BspHeader.Length); //IndexBuild.XBoxMapData.XBSPVerts.FixOffsets((uint)BSPFile.Position + (uint)IndexBuild.XBoxMapData.XBSPVerts.VIndirectOffsets.Length + (uint)IndexBuild.XBoxMapData.XBSPVerts.LIndirectOffsets.Length,Info.TagMagic); long savepos = BSPFile.Position; BSPFile.Write(IndexBuild.XBoxMapData.XBSPVerts.VIndirectOffsets, 0, IndexBuild.XBoxMapData.XBSPVerts.VIndirectOffsets.Length); BSPFile.Write(IndexBuild.XBoxMapData.XBSPVerts.LIndirectOffsets, 0, IndexBuild.XBoxMapData.XBSPVerts.LIndirectOffsets.Length); CompUtil.Fix0x20Position(ref BSPFile); IndexBuild.XBoxMapData.XBSPVerts.FixOffsets((uint)BSPFile.Position, Info.TagMagic); BSPFile.Seek(savepos, SeekOrigin.Begin); IndexBuild.XBoxMapData.XBSPVerts.VLMapOffset = (uint)BSPFile.Position + (uint)IndexBuild.XBoxMapData.XBSPVerts.VIndirectOffsets.Length; BSPFile.Write(IndexBuild.XBoxMapData.XBSPVerts.VIndirectOffsets, 0, IndexBuild.XBoxMapData.XBSPVerts.VIndirectOffsets.Length); IndexBuild.XBoxMapData.XBSPVerts.ILMapOffset = (uint)BSPFile.Position + (uint)IndexBuild.XBoxMapData.XBSPVerts.LIndirectOffsets.Length; BSPFile.Write(IndexBuild.XBoxMapData.XBSPVerts.LIndirectOffsets, 0, IndexBuild.XBoxMapData.XBSPVerts.LIndirectOffsets.Length); CompUtil.Fix0x20Position(ref BSPFile); BSPFile.Write(IndexBuild.XBoxMapData.XBSPVerts.ModelData, 0, IndexBuild.XBoxMapData.XBSPVerts.ModelData.Length); long BSPSavPos = BSPFile.Position; CompUtil.PutUInt(ref BspHeader, 0x00, (uint)(BSPFile.Position + tmpMagic)); BSPFile.Seek(BSPHeaderPos, SeekOrigin.Begin); BSPFile.Write(BspHeader, 0, BspHeader.Length); BSPFile.Seek(BSPSavPos, SeekOrigin.Begin); XBoxMeta BspMeta = new XBoxMeta(); BspMeta.DoProcessMeta(ref tmpSTSF, tbTAG.Stream, ref BSPFile, ref BSPFile, 1, IndexStrings, Info, ref XBoxMap, ref IndexBuild); CompUtil.FixIntPosition2K(ref BSPFile); CompUtil.PutUInt(ref TagBuff, 0x04 + (sc * Size), (uint)(CurrentPosition + BSPFile.Position)); //BspMetaFile.Close(); tbTAG = null; Info.TagMagic = SaveTagMagic; int a = 0; } } break; #endregion case TSFReader.TSFInternalRaw: // "internalraw": #region InternalRaw uint RawSize = CompUtil.GetUInt(TagBuff, (uint)(sr.GetOIP() + (sc * Size))); //Compile Mag.Map if (RawSize == 0) { break; } uint RawOffset = CompUtil.GetUInt(TagBuff, (uint)(sr.GetOIP() + 0x0c + (sc * Size))); //Tag Text CompUtil.PutUInt(ref TagBuff, (uint)(sr.GetOIP()) + 0x0c + (sc * Size), ((uint)FO.Position + Info.TagMagic)); byte[] tmp = new byte[RawSize]; FI.Read(tmp, 0, tmp.Length); FO.Write(tmp, 0, tmp.Length); CompUtil.FixIntPosition(ref FO); tmp = null; break; #endregion case TSFReader.TSFBitmapRaw: // "bitmapraw": #region BitmapRaw MemoryStream BMD; uint TiffSize = 0; CompUtil.GetUInt(TagBuff, 0x1C, ref TiffSize); byte[] TiffBuffer = new byte[TiffSize]; FI.Read(TiffBuffer, 0, TiffBuffer.Length); uint BitmapSize = CompUtil.GetUInt(TagBuff, 0x30); TiffBuffer = new byte[BitmapSize]; FI.Read(TiffBuffer, 0, TiffBuffer.Length); BMD = new MemoryStream(TiffBuffer); uint BitMapStructCount = CompUtil.GetUInt(TagBuff, 0x60); uint BitMapStructOffset = CompUtil.GetUInt(TagBuff, 0x64); byte[] tmpBMS = new byte[BitMapStructCount * 0x30]; long sv = FI.Position; FI.Seek((long)BitMapStructOffset, SeekOrigin.Begin); FI.Read(tmpBMS, 0, tmpBMS.Length); for (int i = 0; i < BitMapStructCount; i++) { uint BitMapDataSize = CompUtil.GetUInt(tmpBMS, (uint)(0x1C + (i * 0x30))); uint svBmPos = (uint)BSPFile.Position + 0x800; CompUtil.PutUInt(ref tmpBMS, (uint)(0x18 + (i * 0x30)), (uint)svBmPos); byte[] tmpBuff = new byte[BitMapDataSize]; BMD.Read(tmpBuff, 0, tmpBuff.Length); BSPFile.Write(tmpBuff, 0, tmpBuff.Length); CompUtil.Fix0x100Position(ref BSPFile); svBmPos += BitMapDataSize; } FI.Seek((long)BitMapStructOffset, SeekOrigin.Begin); FI.Write(tmpBMS, 0, tmpBMS.Length); FI.Seek(sv, SeekOrigin.Begin); //BSPFile.Write(TiffBuffer,0,TiffBuffer.Length); //Fix0x100Position(ref BSPFile); TiffBuffer = null; break; #endregion case TSFReader.TSFRawXModelData: // "XBoxModelData": #region XModelData uint XTrueVerticesSize = (CompUtil.GetUInt(TagBuff, 88 + (sc * Size))) * 32; uint XTrueIndicesSize = (((CompUtil.GetUInt(TagBuff, 72 + (sc * Size))) / 3) + 1) * 6; uint XNewIndicesDataSize = (CompUtil.GetUInt(TagBuff, 72 + (sc * Size)) / 3) + 1; uint XTrueVerticesOffset = CompUtil.GetUInt(TagBuff, 100 + (sc * Size)) - Info.MapMagic; uint XSaveMapFilePos = (uint)FI.Position; //MapFile.Position; byte[] XModelHeader = new byte[16]; //uint XTrueVerticesOffset = GetUInt(TagBuff,100 + (sc * Size)) - Info.MapMagic; CompUtil.PutUInt(ref TagBuff, 100 + (sc * Size), XBoxMap.IndirectVerts + Info.MapMagic); //uint XTrueIndicesOffset = GetUInt(TagBuff, 80+ (sc * Size)) - Info.MapMagic; CompUtil.PutUInt(ref TagBuff, 80 + (sc * Size), XBoxMap.IndirectIndices + Info.MapMagic); XBoxMap.IndirectVerts += 0x0c; XBoxMap.IndirectIndices += 0x0c; CompUtil.PutUInt(ref TagBuff, 0x4c + (sc * Size), IndexBuild.XBoxMapData.XIndices.GetOffset()); byte[] RawXModelBuffer = new byte[XTrueVerticesSize]; FI.Read(RawXModelBuffer, 0, (int)XTrueVerticesSize); byte[] XTestBuffer = new byte[6]; RawXModelBuffer = new byte[XTrueIndicesSize]; FI.Read(RawXModelBuffer, 0, RawXModelBuffer.Length); FI.Read(XTestBuffer, 0, 6); if (XTestBuffer[4] == 0xff) { XTrueIndicesSize += 6; } else { FI.Seek(FI.Position - 6, SeekOrigin.Begin); } break; #endregion case TSFReader.TSFBSPModel: // "bspmodel": #region BspModel uint UnCompressedVerts = sr.GetOIP(); uint CompressedVerts = sr.GetSOC(); uint UnCompressedVertsOffset = sr.GetOIP(); //uint VertsOffset = GetUInt(TagBuff,CompressedVerts); uint TrueVertCount = CompUtil.GetUInt(TagBuff, 180 + (sc * Size)); uint TrueLightMapDataCount = CompUtil.GetUInt(TagBuff, 200 + (sc * Size)); uint UnCompressedLightMapData = (TrueLightMapDataCount * 20); uint CompressedLightMapData = (TrueLightMapDataCount * 8); UnCompressedVerts = (TrueVertCount * 56); CompressedVerts = (TrueVertCount * 32); byte[] BspVertsUnCompressed = new byte[UnCompressedVerts]; FI.Read(BspVertsUnCompressed, 0, BspVertsUnCompressed.Length); //PutUInt(ref TagBuff,0xe4 + (sc * Size),(uint)(FO.Position + Info.TagMagic)); //FO.Write(BspVertsUnCompressed,0,BspVertsUnCompressed.Length); //byte[] BspVertsCompressed = new byte[CompressedVerts]; byte[] BspLightMapDataUnCompressed = new byte[UnCompressedLightMapData]; FI.Read(BspLightMapDataUnCompressed, 0, BspLightMapDataUnCompressed.Length); //FO.Write(BspLightMapDataUnCompressed,0,BspLightMapDataUnCompressed.Length); //byte[] BspLightMapDataCompressed = new byte[CompressedLightMapData]; uint PotLuck = IndexBuild.XBoxMapData.XBSPVerts.CurrentOffset; // + 0x800; uint VOOffset = 0xB4; uint LOOffset = 0xC8; IndexBuild.XBoxMapData.XBSPVerts.VLMapOffset -= 0x0c; CompUtil.PutUInt(ref TagBuff, VOOffset + 0x0c + (sc * Size), (uint)(IndexBuild.XBoxMapData.XBSPVerts.VLMapOffset + Info.TagMagic)); IndexBuild.XBoxMapData.XBSPVerts.ILMapOffset -= 0x0c; CompUtil.PutUInt(ref TagBuff, LOOffset + 0x0c + (sc * Size), (uint)(IndexBuild.XBoxMapData.XBSPVerts.ILMapOffset + Info.TagMagic)); PotLuck += 0x0c; IndexBuild.XBoxMapData.XBSPVerts.CurrentOffset = PotLuck; CompUtil.PutUInt(ref TagBuff, 0xF8 + (sc * Size), IndexBuild.XBoxMapData.XBSPVerts.GetVOffset()); //viper told me to skip past compressed data as a quick fix to // the crash problem - Grenadiac FI.Seek(CompressedVerts, SeekOrigin.Current); //gren added this FI.Seek(CompressedLightMapData, SeekOrigin.Current); //gren added this break; #endregion case TSFReader.TSFResource: // "resources": #region Resources ushort rStringSize = CompUtil.GetUShort(TagBuff, 0x06 + (sc * Size)); if (rStringSize != 0x00) { uint TagClassFlag = CompUtil.GetUShort(TagBuff, 0x00 + (sc * Size)); uint TagResouceIndex = CompUtil.GetUShort(TagBuff, 0x02 + (sc * Size)); string TagClassString = ""; switch (TagClassFlag) { case 0x00: TagClassString = "bitm"; break; case 0x01: TagClassString = "snd!"; break; } //MAG tmpMR = new MAG(Info.StructurePath + TagClassString.Trim() + ".mag"); byte[] tmpStr = new byte[rStringSize + 1]; FI.Read(tmpStr, 0, tmpStr.Length); string tag = CompUtil.ReadString(tmpStr, 0); Trace.WriteLine(tag + "." + TagClassString + " PRIndex" + Convert.ToString(TagResouceIndex, 10)); //tmpMR.Seek(0); int t = 0; //string[] test; bool con = false; do { string[] test = Info.Items[t].GetString().Split(new char[] { '.' }, 256); //IndexStrings[t].Split(new char[]{'.'},256); string testClass = CompUtil.GetTagClass(BitConverter.GetBytes(Info.Items[t].TagClass1), 0); if (testClass == TagClassString && test[0] == tag) { con = true; } else { t += 1; } }while (con == false); CompUtil.PutUShort(ref TagBuff, (uint)(0x04 + (sc * Size)), (ushort)Info.Items[t].IndexID1); CompUtil.PutUShort(ref TagBuff, (uint)(0x06 + (sc * Size)), (ushort)Info.Items[t].IndexID2); } break; #endregion case TSFReader.TSFSoundData: // "sounddata": #region SoundData uint sRawSize = CompUtil.GetUInt(TagBuff, (uint)(sr.GetOIP() + (sc * Size))); uint sRawOffset = CompUtil.GetUInt(TagBuff, (uint)(sr.GetUName() + 4 + (sc * Size))); byte[] stmp = new byte[sRawSize]; uint svSndPos = (uint)BSPFile.Position + 0x800; CompUtil.PutUInt(ref TagBuff, (uint)(sr.GetUName() + 4 + (sc * Size)), svSndPos); FI.Read(stmp, 0, stmp.Length); BSPFile.Write(stmp, 0, stmp.Length); CompUtil.Fix0x100Position(ref BSPFile); stmp = null; break; #endregion case TSFReader.TSFEnd: // "end": #region EndStructure if (sr.GetOIP() == Name) { ExitStruct = true; } else { ExitStruct = false; } break; #endregion } }while(ExitStruct == false); if (Count != 0) { sc += 1; if (sc != Count) { sr.Seek(StartOfStruct); ExitStruct = false; } } }while(sc != Count); long tmpPosSave = FO.Position; FO.Seek(StructPosition, SeekOrigin.Begin); FO.Write(TagBuff, 0, TagBuff.Length); FO.Seek(tmpPosSave, SeekOrigin.Begin); }
public static void Build() { TagFileName scenario_tag = ProjectManager.ScenarioTagFileName; //new TagFileName(@"levels\test\beavercreek\beavercreek.scenario",MapfileVersion.XHALO1); IndexBuilder IndexBuild = new IndexBuilder(); string BasFolder = Application.StartupPath + @"\Extracted Tags\"; string StructFolder = Application.StartupPath + @"\Tag Structures\PcHalo\"; if (true) { //Create the index table Application.DoEvents(); string[] IndexList = IndexBuild.BuildIndex(scenario_tag.RelativePath, BasFolder, StructFolder, MapfileVersion.XHALO1); XBoxHaloMap.sXBoxHalo NewMap = new XBoxHaloMap.sXBoxHalo(); NewMap.XBoxIndexHeader.Create((uint)IndexList.Length); NewMap.XBoxIndexHeader.IndexMagic = 0x803a6024; //0x40440028; uint StringTableSize = 0; //Fixing index items ushort gt = 0xE174; Application.DoEvents(); for (int sc = 0; sc < IndexList.Length; sc++) { TagFileName tfnTAG = new TagFileName(IndexList[sc], MapfileVersion.XHALO1); TagBase tbTAG = new TagBase(); tbTAG.LoadTagBuffer(tfnTAG); NewMap.XBoxIndexHeader.IndexItems[sc].Create(); NewMap.XBoxIndexHeader.IndexItems[sc].TagClass1 = CompUtil.SwapUInt(tbTAG.Header.TagClass0); NewMap.XBoxIndexHeader.IndexItems[sc].TagClass2 = CompUtil.SwapUInt(tbTAG.Header.TagClass1); NewMap.XBoxIndexHeader.IndexItems[sc].TagClass3 = CompUtil.SwapUInt(tbTAG.Header.TagClass2); NewMap.XBoxIndexHeader.IndexItems[sc].IndexID1 = (ushort)sc; NewMap.XBoxIndexHeader.IndexItems[sc].IndexID2 = gt; NewMap.XBoxIndexHeader.IndexItems[sc].NameString = IndexList[sc]; if (tbTAG.Header.TagClass0 == 0x70736273 || tbTAG.Header.TagClass0 == 0x73627370) { NewMap.XBoxIndexHeader.IndexItems[sc].MetaSize = IndexBuild.BSPSizes[0]; } else { NewMap.XBoxIndexHeader.IndexItems[sc].MetaSize = 0; } if (tbTAG.Header.TagClass0 == 0x7274656d || tbTAG.Header.TagClass0 == 0x6d657472) // 6d657472) { gt += 2; } else { gt += 1; } string[] RemoveExt = IndexList[sc].Split(new char[] { '.' }, 256); NewMap.XBoxIndexHeader.IndexItems[sc].String = new byte[RemoveExt[0].Length + 1]; HaloPCMAP.StringToByteArray(ref NewMap.XBoxIndexHeader.IndexItems[sc].String, RemoveExt[0]); StringTableSize += (uint)(IndexList[sc].Length + 1); tbTAG = null; } //Creating the temp files for map building FileInfo MetaFile_info = new FileInfo(Application.StartupPath + "TempMeta.map"); FileStream MetaFile; MetaFile = MetaFile_info.Open(FileMode.Create, FileAccess.ReadWrite); FileInfo BSPFile_info = new FileInfo(Application.StartupPath + "TempBSP.map"); FileStream BSPFile; BSPFile = BSPFile_info.Open(FileMode.Create, FileAccess.ReadWrite); Application.DoEvents(); //writing the index table the temp files for (int sc = 0; sc < NewMap.XBoxIndexHeader.IndexItems.Length; sc++) { NewMap.XBoxIndexHeader.IndexItems[sc].Write(ref MetaFile); } //Rewriting index items to temp file to fix string offsets. Application.DoEvents(); for (int sc = 0; sc < NewMap.XBoxIndexHeader.IndexItems.Length; sc++) { NewMap.XBoxIndexHeader.IndexItems[sc].StringOffset = (uint)MetaFile.Position + NewMap.XBoxIndexHeader.IndexMagic; MetaFile.Write(NewMap.XBoxIndexHeader.IndexItems[sc].String, 0, NewMap.XBoxIndexHeader.IndexItems[sc].String.Length); } CompUtil.FixIntPosition(ref MetaFile); //save MetaFile position to return for meta writing. long TmpPosSave = MetaFile.Position; Application.DoEvents(); for (int sc = 0; sc < NewMap.XBoxIndexHeader.IndexItems.Length; sc++) { MetaFile.Seek(NewMap.XBoxIndexHeader.IndexItems[sc].Position, SeekOrigin.Begin); NewMap.XBoxIndexHeader.IndexItems[sc].Write(ref MetaFile); } //restore position for meta writing #region ModelData MetaFile.Seek(TmpPosSave, SeekOrigin.Begin); NewMap.XBoxIndexHeader.VertsOffset = (uint)MetaFile.Position + NewMap.XBoxIndexHeader.IndexMagic; NewMap.XBoxIndexHeader.ModelCount1 = (uint)IndexBuild.XBoxMapData.XVerts.ModelCount; NewMap.IndirectVerts = (uint)MetaFile.Position; IndexBuild.XBoxMapData.XVerts.FixOffsets((uint)MetaFile.Position, NewMap.XBoxIndexHeader.IndexMagic); MetaFile.Write(IndexBuild.XBoxMapData.XVerts.IndirectOffsets, 0, IndexBuild.XBoxMapData.XVerts.IndirectOffsets.Length); MetaFile.Write(IndexBuild.XBoxMapData.XVerts.Verts, 0, IndexBuild.XBoxMapData.XVerts.Verts.Length); NewMap.XBoxIndexHeader.ModelCount2 = (uint)IndexBuild.XBoxMapData.XIndices.ModelCount; NewMap.XBoxIndexHeader.IndicesOffset = (uint)MetaFile.Position + NewMap.XBoxIndexHeader.IndexMagic; NewMap.IndirectIndices = (uint)MetaFile.Position; IndexBuild.XBoxMapData.XIndices.FixOffsets((uint)MetaFile.Position, NewMap.XBoxIndexHeader.IndexMagic); MetaFile.Write(IndexBuild.XBoxMapData.XIndices.IndirectOffsets, 0, IndexBuild.XBoxMapData.XIndices.IndirectOffsets.Length); MetaFile.Write(IndexBuild.XBoxMapData.XIndices.Verts, 0, IndexBuild.XBoxMapData.XIndices.Verts.Length); #endregion //Add info to the Meta info struct XBoxMeta.StructInfo Info = new XBoxMeta.StructInfo(); Info.MapMagic = NewMap.XBoxIndexHeader.IndexMagic; Info.TagMagic = NewMap.XBoxIndexHeader.IndexMagic; Info.StructurePath = StructFolder; Info.TagsPath = BasFolder; Info.Items = NewMap.XBoxIndexHeader.IndexItems; //Starts processing meta and writing it to the meta file Application.DoEvents(); for (int sc = 0; sc < NewMap.XBoxIndexHeader.IndexItems.Length; sc++) { if (NewMap.XBoxIndexHeader.IndexItems[sc].TagClass1 != 0x70736273) // 70736273) { XBoxMeta Meta = new XBoxMeta(); Trace.WriteLine("Meta Processor: " + IndexList[sc]); TagFileName tfnTAG = new TagFileName(IndexList[sc], MapfileVersion.XHALO1); TagBase tbTAG = new TagBase(); tbTAG.LoadTagBuffer(tfnTAG); MTSFReader mr = new MTSFReader(); mr.MTSFRead("Core.Compiler.HALO_PC_SET.MTSF"); TSFReader STSF = new TSFReader(); STSF.TSF(ref mr, tbTAG.Header.TagClass0); HaloPCMAP.FixIntPosition(ref MetaFile); Info.CurrentOffset = (uint)MetaFile.Position; NewMap.XBoxIndexHeader.IndexItems[sc].MetaOffset = (uint)(MetaFile.Position + NewMap.XBoxIndexHeader.IndexMagic); Meta.DoProcessMeta(ref STSF, tbTAG.Stream, ref MetaFile, ref BSPFile, 1, IndexList, Info, ref NewMap, ref IndexBuild); tbTAG = null; } } //Create a new map header Application.DoEvents(); NewMap.XBoxHeader.Create(); string[] tmpName = scenario_tag.RelativePath.Split(new char[] { '\\' }, 256); tmpName = tmpName[tmpName.Length - 1].Split(new char[] { '.' }, 256); NewMap.XBoxHeader.MapName = tmpName[0]; //otf.FileName.Split(new char[]{'/'},256 //"Cool"; //Rewrite indextable of meta offsets Application.DoEvents(); TmpPosSave = MetaFile.Position; for (int sc = 0; sc < NewMap.XBoxIndexHeader.IndexItems.Length; sc++) { MetaFile.Seek(NewMap.XBoxIndexHeader.IndexItems[sc].Position, SeekOrigin.Begin); NewMap.XBoxIndexHeader.IndexItems[sc].Write(ref MetaFile); } MetaFile.Seek(TmpPosSave, SeekOrigin.Begin); //Create the new map file to begin construction of the new map. FileInfo Map_info = new FileInfo(Application.StartupPath + NewMap.XBoxHeader.MapName + ".Map"); FileStream Map; Map = Map_info.Open(FileMode.Create, FileAccess.ReadWrite); Application.DoEvents(); //Write the header to the new map file NewMap.XBoxHeader.Write(ref Map); //Flush the tmp BSPFile to get FileSize. CompUtil.FixIntPosition2K(ref BSPFile); BSPFile.Flush(); uint BSPFileSize = (uint)BSPFile.Length; //Seek to the begining of the tmp bsp file BSPFile.Seek(0, SeekOrigin.Begin); //Copy the Tmp bsp file to the new map file for (int bc = 0; bc < BSPFileSize; bc += 0x800) { byte[] copy = new byte[0x800]; BSPFile.Read(copy, 0, copy.Length); Map.Write(copy, 0, copy.Length); } //Put the Scnr index ID in the IndexHeader, you can move the scnr any were as long as you set this to the currect ID. NewMap.XBoxIndexHeader.ScnrID = (uint)((NewMap.XBoxIndexHeader.IndexItems[0].IndexID2 << 16) + NewMap.XBoxIndexHeader.IndexItems[0].IndexID1); //put the Current map position in the header so we know where the index header will be NewMap.XBoxHeader.IndexOffset = (uint)Map.Position; //Now we write the Index header to the map. NewMap.XBoxIndexHeader.Write(ref Map); //Flush the temp meta file so we can get the size. MetaFile.Flush(); uint MetaFileSize = (uint)MetaFile.Length; //seek to the begining of the temp meta file for coping to the new map file MetaFile.Seek(0, SeekOrigin.Begin); //Copy the meta file to the new map file. for (int bc = 0; bc < MetaFileSize; bc += 0x800) { byte[] copy = new byte[0x800]; MetaFile.Read(copy, 0, copy.Length); Map.Write(copy, 0, copy.Length); } //Now we fix the map version map size and rewrite it to the map. Map.Flush(); NewMap.XBoxHeader.MapVersion = 0x05; NewMap.XBoxHeader.MapSize = (uint)Map.Length; NewMap.XBoxHeader.MetaSize = MetaFileSize + 0x24; Map.Seek(NewMap.XBoxHeader.Position, SeekOrigin.Begin); NewMap.XBoxHeader.Write(ref Map); //Now close the files and delete the temp files. MetaFile.Flush(); MetaFile.Close(); File.Delete(MetaFile.Name); BSPFile.Close(); File.Delete(BSPFile.Name); Map.Close(); } }
public void DoProcessStruct(ref TSFReader sr, ref FileStream fs, ref MemoryStream FO, uint Count, ushort uName, ref StructInfo Info, ref string[] TagList, ref string[] StringList) { long MapPosSave; TabReplace += (char)TabByte; //string InLine;// = sr.ReadLine(); //InLine = sr.ReadLine(); //string[] CMD = LastInline.Replace(TabReplace,"").ToLower().Trim().Split(new char[]{' '},256); Name = sr.GetUName(); Size = sr.GetSOC(); TagBuff = new byte[Size * Count]; fs.Read(TagBuff, 0, TagBuff.Length); //FixPos(ref fs); long StructPosition = FO.Position; FO.Write(TagBuff, 0, TagBuff.Length); uint StartOfStruct = sr.Position; uint sc = 0; bool ExitStruct = false; bool fuckThisShitHack = false; BinaryReader br = new BinaryReader(Info.BitmapsFile); BinaryWriter bw = new BinaryWriter(FO); do { do { //InLine = "TEST";// sr.Read(); //sr.Read//sr.cTSF[sr.Position].CMD; //CMD = InLine.Replace(TabReplace,"").ToLower().Trim().Split(new char[]{' '},256); sr.Read(); switch (sr.GetCMD()) { case TSFReader.TSFStruct: // 0xA0: //Struct #region Structure //if(fuckThisShitHack) // break; uint ChildCount = GetUInt(TagBuff, (uint)(sr.GetOIP()) + (sc * Size)); if (sr.GetUName() == 0xffff) { ChildCount = 0; PutUInt(ref TagBuff, (uint)(sr.GetOIP()) + (sc * Size), 0); } if (ChildCount != 0) { uint CSOffset = GetUInt(TagBuff, (uint)(sr.GetOIP()) + 4 + (sc * Size)) - Info.TagMagic; Struct Child = new Struct(); fs.Seek((long)CSOffset, SeekOrigin.Begin); PutUInt(ref TagBuff, (uint)(sr.GetOIP() + 4 + (sc * Size)), (uint)FO.Position - Info.TagHeaderSize); Child.DoProcessStruct(ref sr, ref fs, ref FO, ChildCount, sr.GetUName(), ref Info, ref TagList, ref StringList); } else { sr.SeekAheadTo(0xA7, sr.GetUName()); //sr.Seek(sr.Position + 1); } break; #endregion case TSFReader.TSFBSPTagRef: // 0xA8: //BSPTagRef case TSFReader.TSFTagRef: // 0xA1: //TagRef #region TagRef uint StringOffset = GetUInt(TagBuff, (uint)(sr.GetOIP() + (sc * Size)) + 0x04) - Info.MapMagic; ushort TagIndex = GetUShort(TagBuff, (uint)(sr.GetOIP() + (sc * Size)) + 0x0C); if (GetUInt(TagBuff, (uint)(sr.GetOIP() + (sc * Size)) + 0x04) != 0) { //Info.IndexItems[TagIndex].tagClass[0].Char.CopyTo(TagBuff,(long)(Val(CMD[1]) + (sc * Size))); PutUInt(ref TagBuff, (sr.GetOIP() + (sc * Size)), Info.IndexItems[TagIndex].Type1); //.fileData.tagClass[0].UInt); SwapInt(ref TagBuff, (sr.GetOIP() + (sc * Size))); MapPosSave = fs.Position; fs.Seek((long)StringOffset, SeekOrigin.Begin); byte[] tmpstr = new byte[256]; fs.Read(tmpstr, 0, tmpstr.Length); fs.Seek(MapPosSave, SeekOrigin.Begin); uint size = 0; do { size += 1; }while (tmpstr[size] != 0); byte[] OutString = new byte[size + 1]; uint count = 0; do { OutString[count] = tmpstr[count]; count += 1; }while (count != size); PutUInt(ref TagBuff, (uint)((sr.GetOIP() + (sc * Size)) + 0x04), (uint)FO.Position - Info.TagHeaderSize); PutUInt(ref TagBuff, (uint)((sr.GetOIP() + (sc * Size)) + 0x08), (uint)OutString.Length - 1); PutUInt(ref TagBuff, (uint)((sr.GetOIP() + (sc * Size)) + 0x0C), (uint)0xffffffff); FO.Write(OutString, 0, OutString.Length); } break; #endregion case TSFReader.TSFInternalRaw: // 0xA3: //InternalRaw #region InternalRaw uint RawSize = GetUInt(TagBuff, (uint)(sr.GetOIP() + (sc * Size))); uint RawOffset = GetUInt(TagBuff, (uint)(sr.GetOIP() + 0x0c + (sc * Size))) - Info.TagMagic; fs.Seek((long)RawOffset, SeekOrigin.Begin); byte[] tmp = new byte[RawSize]; //PutUInt(ref TagBuff,(uint)(Val(CMD[2]) + (sc * Size)),(uint)(FO.Position)); fs.Read(tmp, 0, tmp.Length); FixPos(ref fs); FO.Write(tmp, 0, tmp.Length); tmp = null; break; #endregion case TSFReader.TSFBitmapRaw: // 0xA9: //Bitmapraw #region BitmapRaw uint BitMapStructCount; uint BitMapStructOffset; uint TiffSize = 0; byte[] tmpBMS; long sv = 0; #region grenbitmap if (Info.IndexItems[Info.CurrentIndex].RawTypeID != 0) { //Trace.WriteLine("extern ce bitmap: " + Prometheus.Core.Compiler.Decompiler.CurrentTagName); CeBitmapIndex.Read(br); //meta header for bitmaps for extern ce files is actually in the bitmaps.map file //so we need to get the header from there. //fix the index offset, it doesn't use magic int bitmap_hdr_offset = (int)CeBitmapIndex.Locator[Info.IndexItems[Info.CurrentIndex].MetaOffset + Info.TagMagic].offset; Info.BitmapsFile.Position = bitmap_hdr_offset; TagBuff = br.ReadBytes(TagBuff.Length); PutUInt(ref TagBuff, 0x54, 0); //get bitmap header(s) offset/count BitMapStructCount = GetUInt(TagBuff, 0x60); BitMapStructOffset = GetUInt(TagBuff, 0x64); //copy bitmap header(s) from CE shared to output tag br.BaseStream.Position += (BitMapStructOffset - Size); tmpBMS = new byte[BitMapStructCount * 0x30]; tmpBMS = br.ReadBytes(tmpBMS.Length); GetUInt(TagBuff, 0x1C, ref TiffSize); bw.BaseStream.Position = 0; bw.Write(TagBuff); bw.BaseStream.Position += (BitMapStructOffset - Size); //bw.Write(tmpBMS); //FO.Write(tmpBMS, (int)FO.Position, tmpBMS.Length); //skip over TIFF area in output tag GetUInt(TagBuff, 0x1C, ref TiffSize); byte[] TiffBuffer = new byte[TiffSize]; bw.Write(TiffBuffer); //FO.Write(TiffBuffer,0,TiffBuffer.Length); //copy bitmap data from CE shared to output tag uint accum = (uint)bw.BaseStream.Position; for (int i = 0; i < BitMapStructCount; i++) { uint BitMapDataOffset = GetUInt(tmpBMS, (uint)(0x18 + (i * 0x30))); uint BitMapDataSize = GetUInt(tmpBMS, (uint)(0x1C + (i * 0x30))); uint CurrentSize = GetUInt(TagBuff, (uint)0x30); PutUInt(ref TagBuff, 0x30, CurrentSize + BitMapDataSize); byte[] tmpBitmapData = new byte[BitMapDataSize]; tmpBitmapData = br.ReadBytes((int)BitMapDataSize); bw.Write(tmpBitmapData); PutUInt(ref tmpBMS, (uint)(0x18 + (i * 0x30)), accum); accum += BitMapDataSize; } //go to the image header offsets //bw.BaseStream.Position = TagBuff.Length + TiffSize + bw.BaseStream.Position += 0x40; bw.Write(tmpBMS); long eof = bw.BaseStream.Position; //fix the offsets bw.BaseStream.Position = 0x74; bw.Write(accum); bw.BaseStream.Position = eof; fuckThisShitHack = true; //FO.Write(tmpBitmapData, (int)FO.Position, tmpBitmapData.Length); } else { GetUInt(TagBuff, 0x1C, ref TiffSize); byte[] TiffBuffer = new byte[TiffSize]; FO.Write(TiffBuffer, 0, TiffBuffer.Length); BitMapStructCount = GetUInt(TagBuff, 0x60); BitMapStructOffset = GetUInt(TagBuff, 0x64) - Info.MapMagic; sv = fs.Position; fs.Seek((long)BitMapStructOffset, SeekOrigin.Begin); tmpBMS = new byte[BitMapStructCount * 0x30]; fs.Read(tmpBMS, 0, tmpBMS.Length); for (int i = 0; i < BitMapStructCount; i++) { uint BitMapDataOffset = GetUInt(tmpBMS, (uint)(0x18 + (i * 0x30))); uint BitMapDataSize = GetUInt(tmpBMS, (uint)(0x1C + (i * 0x30))); uint CurrentSize = GetUInt(TagBuff, (uint)0x30); PutUInt(ref TagBuff, 0x30, CurrentSize + BitMapDataSize); byte[] tmpBitmapData = new byte[BitMapDataSize]; switch (Info.MapVersion) { case 5: fs.Seek((long)BitMapDataOffset, SeekOrigin.Begin); fs.Read(tmpBitmapData, 0, tmpBitmapData.Length); FO.Write(tmpBitmapData, 0, tmpBitmapData.Length); break; case 7: Info.BitmapsFile.Seek((long)BitMapDataOffset, SeekOrigin.Begin); Info.BitmapsFile.Read(tmpBitmapData, 0, tmpBitmapData.Length); FO.Write(tmpBitmapData, 0, tmpBitmapData.Length); break; case 0x261: if (Info.IndexItems[Info.CurrentIndex].RawTypeID == 0) { fs.Seek((long)BitMapDataOffset, SeekOrigin.Begin); fs.Read(tmpBitmapData, 0, tmpBitmapData.Length); FO.Write(tmpBitmapData, 0, tmpBitmapData.Length); } else { //CE_Bitmap_File CEBF = new CE_Bitmap_File(); //CEBF.HDR.Read(ref Info.BitmapsFile); //uint Current_offset = CEBF.Locator[Info.IndexItems[Info.CurrentIndex].MetaOffset].offset; } break; } } fs.Seek(sv, SeekOrigin.Begin); } #endregion break; #endregion case TSFReader.TSFSoundData: // 0xAA: //SoundData #region SoundData uint DataSizeOffset = sr.GetOIP(); uint NormalDataOffset = sr.GetUName(); uint SndDataSize = GetUInt(TagBuff, (uint)(DataSizeOffset + (sc * Size))); uint TrueOffset = GetUInt(TagBuff, (uint)(NormalDataOffset + 4 + (sc * Size))); byte[] SoundData = new byte[SndDataSize]; switch (Info.MapVersion) { case 5: long fssv = fs.Position; fs.Seek((long)TrueOffset, SeekOrigin.Begin); fs.Read(SoundData, 0, SoundData.Length); fs.Seek(fssv, SeekOrigin.Begin); FO.Write(SoundData, 0, SoundData.Length); break; case 7: Info.SoundsFile.Seek(TrueOffset, System.IO.SeekOrigin.Begin); Info.SoundsFile.Read(SoundData, 0, SoundData.Length); FO.Write(SoundData, 0, SoundData.Length); SoundData = null; break; } break; #endregion case TSFReader.TSFRawXModelData: // 0xB0: //XModelData #region XModelData uint XTrueVerticesSize = (GetUInt(TagBuff, 88 + (sc * Size))) * 32; uint XTrueIndicesSize = (((GetUInt(TagBuff, 72 + (sc * Size))) / 3) + 1) * 6; uint XNewIndicesDataSize = (GetUInt(TagBuff, 72 + (sc * Size)) / 3) + 1; uint XTrueVerticesOffset = GetUInt(TagBuff, 100 + (sc * Size)) - Info.MapMagic; uint XSaveMapFilePos = (uint)fs.Position; //MapFile.Position; byte[] XModelHeader = new byte[16]; fs.Seek((long)XTrueVerticesOffset, System.IO.SeekOrigin.Begin); fs.Read(XModelHeader, 0, XModelHeader.Length); fs.Seek(XSaveMapFilePos, System.IO.SeekOrigin.Begin); XTrueVerticesOffset = GetUInt(XModelHeader, 4) - Info.MapMagic; XSaveMapFilePos = (uint)fs.Position; byte[] RawXModelBuffer = new byte[XTrueVerticesSize]; fs.Seek((long)XTrueVerticesOffset, System.IO.SeekOrigin.Begin); fs.Read(RawXModelBuffer, 0, (int)XTrueVerticesSize); FO.Write(RawXModelBuffer, 0, (int)XTrueVerticesSize); byte[] XTestBuffer = new byte[6]; uint XTrueIndicesOffset = GetUInt(TagBuff, 80 + (sc * Size)) - Info.MapMagic; RawXModelBuffer = new byte[XTrueIndicesSize]; fs.Seek((long)XTrueIndicesOffset, System.IO.SeekOrigin.Begin); fs.Read(XModelHeader, 0, XModelHeader.Length); XTrueIndicesOffset = GetUInt(XModelHeader, 0x04) - Info.MapMagic; fs.Seek((long)XTrueIndicesOffset, System.IO.SeekOrigin.Begin); fs.Read(RawXModelBuffer, 0, RawXModelBuffer.Length); FO.Write(RawXModelBuffer, 0, RawXModelBuffer.Length); fs.Read(XTestBuffer, 0, 6); if (XTestBuffer[4] == 0xff) { FO.Write(XTestBuffer, 0, 6); XTrueIndicesSize += 6; } break; #endregion case TSFReader.TSFModelData: // 0xAB: //Modeldata #region ModelData long SaveMapFilePos = (uint)fs.Position; uint TrueVerticesSize = (GetUInt(TagBuff, (uint)(88 + (sc * Size)))) * 68; uint TrueIndicesSize = (((GetUInt(TagBuff, (uint)(72 + (sc * Size)))) / 3) + 1) * 6; uint NewIndicesDataSize = (GetUInt(TagBuff, (uint)(72 + (sc * Size))) / 3) + 1; uint TrueVerticesOffset = GetUInt(TagBuff, (uint)(100 + (sc * Size))) + Info.VerticesOffset; //80 uint TrueIndicesOffset = GetUInt(TagBuff, (uint)(80 + (sc * Size))) + Info.IndicesOffset; //100 //PutUInt(ref TagBuff,GetUInt(TagBuff,(uint)(88 + (i * Size))),(uint)(32 +(i * Size))); //PutUInt(ref TagBuff,NewIndicesDataSize,(uint)(56 + (i * Size))); uint CurrentStructSize = (uint)TagBuff.Length; byte[] RawModelBuffer = new byte[TrueVerticesSize]; fs.Seek((long)TrueVerticesOffset, System.IO.SeekOrigin.Begin); fs.Read(RawModelBuffer, 0, RawModelBuffer.Length); FO.Write(RawModelBuffer, 0, RawModelBuffer.Length); RawModelBuffer = new byte[TrueIndicesSize]; fs.Seek((long)TrueIndicesOffset, System.IO.SeekOrigin.Begin); fs.Read(RawModelBuffer, 0, RawModelBuffer.Length); FO.Write(RawModelBuffer, 0, RawModelBuffer.Length); fs.Seek(fs.Position, System.IO.SeekOrigin.Begin); byte[] TestBuffer = new byte[6]; fs.Read(TestBuffer, 0, 6); if (TestBuffer[4] == 0xff) { //PutUInt(StructBuffer,GetUInt(StructBuffer,56 + (StructSize * cc)) + 1,56 + (StructSize * cc)); FO.Write(TestBuffer, 0, TestBuffer.Length); TrueIndicesSize += 6; } fs.Seek(SaveMapFilePos, SeekOrigin.Begin); break; #endregion case TSFReader.TSFBSPModel: // 0xAC: //BSPMODEL #region BSPModel uint VOOffset = 0xB4; uint LOOffset = 0xC8; s_TrueOffset VertsTrueOffset = new s_TrueOffset(); s_TrueOffset LMUVTrueOffset = new s_TrueOffset(); VertsTrueOffset.Read(TagBuff, VOOffset + (sc * Size), Info.TagMagic, ref fs); LMUVTrueOffset.Read(TagBuff, LOOffset + (sc * Size), Info.TagMagic, ref fs); uint UnCompVertsSize = VertsTrueOffset.Count * 56; uint CompVertsSize = VertsTrueOffset.Count * 32; uint UnCompLMUVSize = LMUVTrueOffset.Count * 20; uint CompLMUVSize = LMUVTrueOffset.Count * 8; byte[] ba_UnCompVerts = new byte[UnCompVertsSize]; byte[] ba_CompVerts = new byte[CompVertsSize]; byte[] ba_UnCompLMUV = new byte[UnCompLMUVSize]; byte[] ba_CompLMUV = new byte[CompLMUVSize]; switch (Info.MapVersion) { case 5: long Sav_F_Pos = fs.Position; fs.Seek((long)VertsTrueOffset.TrueOffset, SeekOrigin.Begin); fs.Read(ba_CompVerts, 0, ba_CompVerts.Length); fs.Seek((long)LMUVTrueOffset.TrueOffset, SeekOrigin.Begin); fs.Read(ba_CompLMUV, 0, ba_CompLMUV.Length); fs.Seek(Sav_F_Pos, SeekOrigin.Begin); break; case 7: case 0x261: fs.Read(ba_UnCompVerts, 0, ba_UnCompVerts.Length); fs.Read(ba_UnCompLMUV, 0, ba_UnCompLMUV.Length); break; } cs_UnCompVerts[] UnCompVertsBuff = new cs_UnCompVerts[VertsTrueOffset.Count]; cs_CompVerts[] CompVertsBuff = new cs_CompVerts[VertsTrueOffset.Count]; cs_UnCompLMUV[] UnCompLMUV = new cs_UnCompLMUV[LMUVTrueOffset.Count]; cs_CompLMUV[] CompLMUV = new cs_CompLMUV[LMUVTrueOffset.Count]; for (int vl = 0; vl < VertsTrueOffset.Count; vl++) { CompVertsBuff[vl] = new cs_CompVerts(); UnCompVertsBuff[vl] = new cs_UnCompVerts(); switch (Info.MapVersion) { case 5: CompVertsBuff[vl].Read(ba_CompVerts, (uint)vl); break; case 7: case 0x261: UnCompVertsBuff[vl].Read(ba_UnCompVerts, (uint)vl); break; } } switch (Info.MapVersion) { case 5: DeCompressVerts(CompVertsBuff, ref UnCompVertsBuff); break; case 7: case 0x261: CompressVerts(UnCompVertsBuff, ref CompVertsBuff); break; } for (int i = 0; i < VertsTrueOffset.Count; i++) { switch (Info.MapVersion) { case 5: UnCompVertsBuff[i].Write(ref ba_UnCompVerts, (uint)i); break; case 7: case 0x261: CompVertsBuff[i].Write(ref ba_CompVerts, (uint)i); break; } } for (int i = 0; i < LMUVTrueOffset.Count; i++) { CompLMUV[i] = new cs_CompLMUV(); UnCompLMUV[i] = new cs_UnCompLMUV(); switch (Info.MapVersion) { case 5: CompLMUV[i].Read(ba_CompLMUV, (uint)i); break; case 7: case 0x261: UnCompLMUV[i].Read(ba_UnCompLMUV, (uint)i); break; } } switch (Info.MapVersion) { case 5: DeCompressLMUV(CompLMUV, ref UnCompLMUV); break; case 7: case 0x261: CompressLMUV(UnCompLMUV, ref CompLMUV); break; } for (int i = 0; i < LMUVTrueOffset.Count; i++) { switch (Info.MapVersion) { case 5: UnCompLMUV[i].Write(ref ba_UnCompLMUV, (uint)i); break; case 7: case 0x261: CompLMUV[i].Write(ref ba_CompLMUV, (uint)i); break; } } PutUInt(ref TagBuff, 0xd8 + (sc * Size), (uint)ba_UnCompVerts.Length); FO.Write(ba_UnCompVerts, 0, ba_UnCompVerts.Length); FO.Write(ba_UnCompLMUV, 0, ba_UnCompLMUV.Length); FO.Write(ba_CompVerts, 0, ba_CompVerts.Length); FO.Write(ba_CompLMUV, 0, ba_CompLMUV.Length); break; #endregion case TSFReader.TSFResource: // 0xAD: //Resource #region Resource ushort BitmapSoundFlag = GetUShort(TagBuff, 0x00 + (sc * Size)); ushort Index = GetUShort(TagBuff, 0x02 + (sc * Size)); ushort ID1 = GetUShort(TagBuff, 0x04 + (sc * Size)); ushort ID2 = GetUShort(TagBuff, 0x06 + (sc * Size)); MapPosSave = fs.Position; uint Offset = Info.IndexItems[ID1].OffsetToString; /// fileData.stringOffset.UInt - Info.MapMagic; fs.Seek((long)Offset, SeekOrigin.Begin); byte[] rscstr = new byte[256]; fs.Read(rscstr, 0, rscstr.Length); fs.Seek(MapPosSave, SeekOrigin.Begin); uint rscsize = 0; do { rscsize += 1; }while (rscstr[rscsize] != 0); byte[] rscOutString = new byte[rscsize + 1]; uint rsccount = 0; do { rscOutString[rsccount] = rscstr[rsccount]; rsccount += 1; }while (rsccount != rscsize); PutUShort(ref TagBuff, (uint)(0x06 + (sc * Size)), (ushort)(rscOutString.Length - 1)); FO.Write(rscOutString, 0, rscOutString.Length); break; #endregion case TSFReader.TSFEnd: // 0xA7: //End #region StructEnd if (sr.GetOIP() == Name) { ExitStruct = true; } else { ExitStruct = false; } break; #endregion } }while(ExitStruct == false); if (Count != 0) { sc += 1; if (sc != Count) { sr.Seek(StartOfStruct); ExitStruct = false; } } }while (sc != Count); long tmpPosSave = FO.Position; FO.Seek(StructPosition, SeekOrigin.Begin); FO.Write(TagBuff, 0, TagBuff.Length); FO.Seek(tmpPosSave, SeekOrigin.Begin); }