/// <summary> /// Loads a font package from the given file. /// </summary> /// <returns>0 = success, 1 = bad header version, 2 = font count is zero</returns> public int Load(string filename) { FileStream fs = new FileStream(filename, FileMode.Open); BinaryReader br = new BinaryReader(fs); ms = new MemoryStream(br.ReadBytes((int)br.BaseStream.Length)); fs.Close(); br = new BinaryReader(ms); br.BaseStream.Position = 0; //Make sure this is a font package var fileMagic = br.ReadUInt32(); if (fileMagic != 0xC0000003) { ms.Close(); br.Close(); return(1); } int fontCount = br.ReadInt32(); if (fontCount <= 0) { ms.Close(); br.Close(); return(2); } maxFontCount = 16; //check to see if package belongs to Halo 4 var maxcounthack = br.ReadInt32(); if (maxcounthack == 1048) { maxFontCount = 64; } //get the font headers info br.BaseStream.Position -= 4; for (int i = 0; i < maxFontCount; i++) { FontEntries.Add(new FontHeaderInfo() { offset = br.ReadInt32(), size = br.ReadInt32(), startBlock = br.ReadInt16(), blockCount = br.ReadInt16() }); } //read engine ordering for (int i = 0; i < maxFontCount; i++) { OrderList.Add(br.ReadInt32()); } int headerTableOffset = br.ReadInt32(); int headerTableSize = br.ReadInt32(); BlockRangesOffset = br.ReadInt32(); int blockCount = br.ReadInt32(); br.BaseStream.Position = BlockRangesOffset; for (int i = 0; i < blockCount; i++) { var startchar = br.ReadUInt16(); var startfont = br.ReadInt16(); var endchar = br.ReadUInt16(); var endfont = br.ReadInt16(); charDatum start = new charDatum() { characterCode = startchar, fontIndex = startfont }; charDatum end = new charDatum() { characterCode = endchar, fontIndex = endfont }; BlockRange range = new BlockRange() { startIndex = start, endIndex = end }; BlockRanges.Add(range); } //read data blocks //set position for hax to check for h4b br.BaseStream.Position = 0x8000; ChunkSize = 0x8000; if (maxFontCount == 64 & br.ReadInt16() != 8) //blocks seem to have a short value of 8 as some header or version { ChunkSize = 0xC000; } for (int i = 0; i < blockCount; i++) { Block dataBlock = new Block(); dataBlock.Read(br, ChunkSize + (i * ChunkSize)); Blocks.Add(dataBlock); } //read font headers and find its characters for (int i = 0; i < fontCount; i++) { var tempfont = new PackageFont(); br.BaseStream.Position = FontEntries[i].offset; tempfont.ReadHeader(br); for (int bl = FontEntries[i].startBlock; bl < (FontEntries[i].startBlock + FontEntries[i].blockCount); bl++) { for (int ch = 0; ch < Blocks[bl].charCount; ch++) { if (Blocks[bl].charTable[ch].index.fontIndex == i) { var tempchar = new FontCharacter(Blocks[bl].charTable[ch].index.characterCode, Blocks[bl].charData[ch]); tempfont.Characters.Add(tempchar); } } } Fonts.Add(tempfont); } br.Close(); ms.Close(); return(0); }
private int LoadFile(string filename) { List <int> CharacterPointers = new List <int>(); List <CharacterData> CharacterEntries = new List <CharacterData>(); List <int> kernlist = new List <int>(); FileStream fs = new FileStream(filename, FileMode.Open); BinaryReader br = new BinaryReader(fs); ms = new MemoryStream(br.ReadBytes((int)br.BaseStream.Length)); fs.Close(); br = new BinaryReader(ms); br.BaseStream.Position = 0x200; //Make sure this is a font file var fileMagic = br.ReadUInt32(); if (fileMagic != 0xF0000001) { ms.Close(); br.Close(); return(1); } PackageFont tempfont = new PackageFont(); tempfont.Name = filename.Substring(filename.LastIndexOf("\\") + 1); tempfont.HeaderVersion = (int)fileMagic; tempfont.ReadH2Header(br); br.BaseStream.Position = 0x3AC; int unk7 = br.ReadInt32(); int unk8 = br.ReadInt32(); int characterdataoffset = 0x40400 + (tempfont.CharacterCount * 0x10); //read characters for (int i = 0; i < tempfont.CharacterCount; i++) { CharacterData tempchar = new CharacterData(); tempchar.Read(br, 0x40400 + (i * 0x10), true); br.BaseStream.Position = tempchar.OffsetH2; tempchar.compressedData = br.ReadBytes(tempchar.dataSize); CharacterEntries.Add(tempchar); } //read character indexes and match things up for (int i = 0; i < 65536; i++) { br.BaseStream.Position = 0x400 + (i * 4); int charindex = br.ReadInt32(); FontCharacter tempfchar = new FontCharacter((ushort)i, CharacterEntries[charindex]); if (CharacterPointers.Contains(charindex)) { tempfchar.isdupe = true; } else { CharacterPointers.Add(charindex); } tempfont.Characters.Add(tempfchar); tempfchar = null; } tempfont.H2File = filename; Fonts.Add(tempfont); br.Close(); ms.Close(); return(0); }