private bool LoadFile( Stream stream ) { string magic = stream.ReadAscii( 4 ); switch ( magic ) { case "G1TG": Endian = Util.Endianness.BigEndian; break; case "GT1G": Endian = Util.Endianness.LittleEndian; break; default: throw new Exception( "Not a g1t file!" ); } uint version = stream.ReadUInt32().FromEndian( Endian ); switch ( version ) { case 0x30303530: break; case 0x30303630: break; default: throw new Exception( "Unsupported g1t version!" ); } uint fileSize = stream.ReadUInt32().FromEndian( Endian ); uint headerSize = stream.ReadUInt32().FromEndian( Endian ); uint numberTextures = stream.ReadUInt32().FromEndian( Endian ); uint unknown = stream.ReadUInt32().FromEndian( Endian ); stream.Position = headerSize; uint bytesUnknownData = stream.ReadUInt32().FromEndian( Endian ); stream.Position = headerSize + bytesUnknownData; Textures = new List<g1tTexture>( (int)numberTextures ); for ( uint i = 0; i < numberTextures; ++i ) { var g = new g1tTexture( stream, Endian ); Textures.Add( g ); } return true; }
public TOVNPCL(Stream stream, Util.Endianness endian, Util.Bitness bits) { if (!LoadFile(stream, endian, bits)) { throw new Exception("Loading TOVNPCL failed!"); } }
public T8BTXTMM(Stream stream, Util.Endianness endian) { if (!LoadFile(stream, endian)) { throw new Exception("Loading T8BTXTMM failed!"); } }
private bool LoadFile(DuplicatableStream headerStream, DuplicatableStream contentStream) { DuplicatableStream infile = headerStream.Duplicate(); contentFile = contentStream.Duplicate(); infile.Seek(0x00, SeekOrigin.Begin); string magic = infile.ReadAscii(4); if (magic != "FPS4") { Console.WriteLine("Not an FPS4 file!"); return(false); } Endian = Util.Endianness.BigEndian; FileCount = infile.ReadUInt32().FromEndian(Endian); HeaderSize = infile.ReadUInt32().FromEndian(Endian); // if header seems huge then we probably have assumed the wrong endianness if (HeaderSize > 0xFFFF) { Endian = Util.Endianness.LittleEndian; FileCount = FileCount.ToEndian(Util.Endianness.BigEndian).FromEndian(Endian); HeaderSize = HeaderSize.ToEndian(Util.Endianness.BigEndian).FromEndian(Endian); } FirstFileStart = infile.ReadUInt32().FromEndian(Endian); EntrySize = infile.ReadUInt16().FromEndian(Endian); ContentBitmask = new ContentInfo(infile.ReadUInt16().FromEndian(Endian)); Unknown2 = infile.ReadUInt32().FromEndian(Endian); ArchiveNameLocation = infile.ReadUInt32().FromEndian(Endian); infile.Position = ArchiveNameLocation; if (ArchiveNameLocation > 0) { ArchiveName = infile.ReadShiftJisNullterm(); } Alignment = FirstFileStart; Console.WriteLine("Content Bitmask: 0x" + ContentBitmask.Value.ToString("X4")); if (ContentBitmask.HasUnknownDataTypes) { Console.WriteLine("WARNING: Bitmask identifies unknown data types, data interpretation will probably be incorrect."); } Files = new List <FileInfo>((int)FileCount); for (uint i = 0; i < FileCount; ++i) { infile.Position = HeaderSize + (i * EntrySize); Files.Add(new FileInfo(infile, i, ContentBitmask, Endian, Util.GameTextEncoding.ASCII)); } FileLocationMultiplier = CalculateFileLocationMultiplier(); ShouldGuessFilesizeFromNextFile = !ContentBitmask.ContainsFileSizes && !ContentBitmask.ContainsSectorSizes && CalculateIsLinear(); infile.Dispose(); return(true); }
public SkitCondition(System.IO.Stream stream, Util.Endianness endian) { Type = (SkitConditionType)stream.ReadUInt16().FromEndian(endian); MathOp = stream.ReadUInt16().FromEndian(endian); Value1 = (int)stream.ReadUInt32().FromEndian(endian); Value2 = (int)stream.ReadUInt32().FromEndian(endian); Value3 = (int)stream.ReadUInt32().FromEndian(endian); }
private bool LoadFile(Stream stream, Util.Endianness endian, Util.Bitness bits) { string magic = stream.ReadAscii(8); uint fileSize = stream.ReadUInt32().FromEndian(endian); uint skitInfoCount = stream.ReadUInt32().FromEndian(endian); uint skitInfoOffset = stream.ReadUInt32().FromEndian(endian); uint conditionForwarderCount = stream.ReadUInt32().FromEndian(endian); uint conditionForwarderOffset = stream.ReadUInt32().FromEndian(endian); uint conditionCount = stream.ReadUInt32().FromEndian(endian); uint conditionOffset = stream.ReadUInt32().FromEndian(endian); uint uCount4 = stream.ReadUInt32().FromEndian(endian); uint uOffset4 = stream.ReadUInt32().FromEndian(endian); uint uCount5 = stream.ReadUInt32().FromEndian(endian); uint uOffset5 = stream.ReadUInt32().FromEndian(endian); uint refStringStart = stream.ReadUInt32().FromEndian(endian); SkitInfoList = new List <SkitInfo>((int)skitInfoCount); stream.Position = skitInfoOffset; for (uint i = 0; i < skitInfoCount; ++i) { SkitInfo s = new SkitInfo(stream, refStringStart, endian, bits); SkitInfoList.Add(s); } SkitConditionForwarderList = new List <SkitConditionForwarder>((int)conditionForwarderCount); stream.Position = conditionForwarderOffset; for (uint i = 0; i < conditionForwarderCount; ++i) { var s = new SkitConditionForwarder(stream, endian, bits); SkitConditionForwarderList.Add(s); } SkitConditionList = new List <SkitCondition>((int)conditionCount); stream.Position = conditionOffset; for (uint i = 0; i < conditionCount; ++i) { var s = new SkitCondition(stream, endian); SkitConditionList.Add(s); } UnknownSkitData4List = new List <UnknownSkitData4>((int)uCount4); stream.Position = uOffset4; for (uint i = 0; i < uCount4; ++i) { var s = new UnknownSkitData4(stream, endian, bits); UnknownSkitData4List.Add(s); } UnknownSkitData5List = new List <UnknownSkitData5>((int)uCount5); stream.Position = uOffset5; for (uint i = 0; i < uCount5; ++i) { var s = new UnknownSkitData5(stream, endian, bits); UnknownSkitData5List.Add(s); } return(true); }
public ScenarioFile(String filename, Util.GameTextEncoding encoding, Util.Endianness endian, Util.Bitness bits) { using (Stream stream = new System.IO.FileStream(filename, FileMode.Open, FileAccess.Read, FileShare.Read)) { if (!LoadFile(stream, encoding, endian, bits)) { throw new Exception("Loading ScenarioFile failed!"); } } }
// NPC dialogue definition files, I think? public TOVNPCT(String filename, Util.Endianness endian, Util.Bitness bits) { using (Stream stream = new System.IO.FileStream(filename, FileMode.Open, System.IO.FileAccess.Read)) { if (!LoadFile(stream, endian, bits)) { throw new Exception("Loading TOVNPCT failed!"); } } }
public TSSFile(string filename, Util.GameTextEncoding encoding, Util.Endianness endian) { using (Stream stream = new FileStream(filename, FileMode.Open, FileAccess.Read)) { if (!LoadFile(stream, encoding, endian)) { throw new Exception("Loading TSSFile failed!"); } } }
public SCFOMBIN(String filename, Util.Endianness endian, Util.GameTextEncoding encoding, uint textPointerLocationDiff = 0x1888) { using (Stream stream = new System.IO.FileStream(filename, FileMode.Open)) { if (!LoadFile(stream, endian, encoding, textPointerLocationDiff)) { throw new Exception("Loading SCFOMBIN failed!"); } } }
public COOKDAT(String filename, Util.Endianness endian) { using (Stream stream = new System.IO.FileStream(filename, FileMode.Open, FileAccess.Read)) { if (!LoadFile(stream, endian)) { throw new Exception("Loading COOKDAT failed!"); } } }
public Unknown0x20byteAreaB(System.IO.Stream stream, uint refStringStart, Util.Endianness endian) { UnknownFloats = new float[4]; for (int i = 0; i < UnknownFloats.Length; ++i) { UnknownFloats[i] = stream.ReadUInt32().FromEndian(endian).UIntToFloat(); } UnknownByte = (byte)stream.ReadByte(); stream.DiscardBytes(0x0F); }
public ShopDefinition(System.IO.Stream stream, Util.Endianness endian, Util.Bitness bits) { InGameID = stream.ReadUInt32().FromEndian(endian); StringDicID = stream.ReadUInt32().FromEndian(endian); stream.ReadUInt32().FromEndian(endian); // second instance of string dic id? stream.ReadUInt32().FromEndian(endian); // always empty? OnTrigger = stream.ReadUInt32().FromEndian(endian); ChangeToShop = stream.ReadUInt32().FromEndian(endian); stream.DiscardBytes(4 + bits.NumberOfBytes()); // always empty? }
private bool LoadFile(string headerFilename, string contentFilename = null) { try { infile = new FileStream(headerFilename, FileMode.Open); if (contentFilename != null) { contentFile = new FileStream(contentFilename, FileMode.Open); } else { contentFile = infile; } } catch (Exception) { Console.WriteLine("ERROR: can't open " + headerFilename); return(false); } infile.Seek(0x00, SeekOrigin.Begin); string magic = infile.ReadAscii(4); if (magic != "FPS4") { Console.WriteLine("Not an FPS4 file!"); return(false); } Endian = Util.Endianness.BigEndian; FileCount = infile.ReadUInt32().FromEndian(Endian); HeaderSize = infile.ReadUInt32().FromEndian(Endian); // if header seems huge then we probably have assumed the wrong endianness if (HeaderSize > 0xFFFF) { Endian = Util.Endianness.LittleEndian; FileCount = FileCount.ToEndian(Util.Endianness.BigEndian).FromEndian(Endian); HeaderSize = HeaderSize.ToEndian(Util.Endianness.BigEndian).FromEndian(Endian); } FirstFileStart = infile.ReadUInt32().FromEndian(Endian); EntrySize = infile.ReadUInt16().FromEndian(Endian); ContentBitmask = infile.ReadUInt16().FromEndian(Endian); Unknown2 = infile.ReadUInt32().FromEndian(Endian); ArchiveNameLocation = infile.ReadUInt32().FromEndian(Endian); infile.Position = ArchiveNameLocation; if (ArchiveNameLocation > 0) { ArchiveName = infile.ReadShiftJisNullterm(); } Alignment = FirstFileStart; Console.WriteLine("Content Bitmask: 0x" + ContentBitmask.ToString("X4")); return(true); }
public NpcFileReference(System.IO.Stream stream, uint refStringStart, Util.Endianness endian, Util.Bitness bits) { ulong refStringLocation1 = stream.ReadUInt(bits, endian); ulong refStringLocation2 = stream.ReadUInt(bits, endian); Filesize = stream.ReadUInt32().FromEndian(endian); stream.ReadUInt32(); Map = stream.ReadAsciiNulltermFromLocationAndReset((long)(refStringStart + refStringLocation1)); Filename = stream.ReadAsciiNulltermFromLocationAndReset((long)(refStringStart + refStringLocation2)); }
public TSSHeader(Stream Header, Util.Endianness endian) { Magic = Header.ReadUInt32().SwapEndian(); CodeStart = Header.ReadUInt32().FromEndian(endian); CodeLength = Header.ReadUInt32().FromEndian(endian); TextStart = Header.ReadUInt32().FromEndian(endian); EntryCodeStart = Header.ReadUInt32().FromEndian(endian); EntryPointerEnd = Header.ReadUInt32().FromEndian(endian); TextLength = Header.ReadUInt32().FromEndian(endian); SectorSize = Header.ReadUInt32().FromEndian(endian); }
public g1tTexture(Stream stream, Util.Endianness endian) { Mipmaps = (byte)stream.ReadByte(); byte format = (byte)stream.ReadByte(); byte dimensions = (byte)stream.ReadByte(); byte unknown4 = (byte)stream.ReadByte(); byte unknown5 = (byte)stream.ReadByte(); byte unknown6 = (byte)stream.ReadByte(); byte unknown7 = (byte)stream.ReadByte(); byte unknown8 = (byte)stream.ReadByte(); if (endian == Util.Endianness.LittleEndian) { Mipmaps = Mipmaps.SwapEndian4Bits(); dimensions = dimensions.SwapEndian4Bits(); unknown4 = unknown4.SwapEndian4Bits(); unknown5 = unknown5.SwapEndian4Bits(); unknown6 = unknown6.SwapEndian4Bits(); unknown7 = unknown7.SwapEndian4Bits(); unknown8 = unknown8.SwapEndian4Bits(); } if (unknown8 == 0x01) { stream.DiscardBytes(0x0C); } switch (format) { case 0x00: Format = Textures.TextureFormat.ABGR; BitPerPixel = 32; break; case 0x01: Format = Textures.TextureFormat.RGBA; BitPerPixel = 32; break; case 0x06: Format = Textures.TextureFormat.DXT1; BitPerPixel = 4; break; case 0x08: Format = Textures.TextureFormat.DXT5; BitPerPixel = 8; break; default: throw new Exception(String.Format("g1t: Unknown Format ({0:X2})", format)); } Width = (uint)(1 << (dimensions >> 4)); Height = (uint)(1 << (dimensions & 0x0F)); uint highestMipmapSize = (Width * Height * BitPerPixel) / 8; long textureSize = highestMipmapSize; for (int i = 0; i < Mipmaps - 1; ++i) { textureSize += highestMipmapSize / (4 << (i * 2)); } Data = new byte[textureSize]; stream.Read(Data, 0, Data.Length); }
public ShopItem(System.IO.Stream stream, Util.Endianness endian) { Data = new uint[56 / 4]; for (int i = 0; i < Data.Length; ++i) { Data[i] = stream.ReadUInt32().FromEndian(endian); } ShopID = Data[1]; ItemID = Data[5]; }
public Title(System.IO.Stream stream, Util.Endianness endian) { ID = stream.ReadUInt32().FromEndian(endian); NameStringDicID = stream.ReadUInt32().FromEndian(endian); DescStringDicID = stream.ReadUInt32().FromEndian(endian); Character = stream.ReadUInt32().FromEndian(endian); CostumeString = stream.ReadAscii(0x10).TrimNull(); BunnyGuildPointsMaybe = stream.ReadUInt32().FromEndian(endian); stream.DiscardBytes(0xC); }
public Unknown0x80byteArea(System.IO.Stream stream, uint refStringStart, Util.Endianness endian) { UnknownUInt = stream.ReadUInt32().FromEndian(endian); stream.DiscardBytes(4); UnknownByte1 = (byte)stream.ReadByte(); UnknownByte2 = (byte)stream.ReadByte(); stream.DiscardBytes(2); UnknownFloat1 = stream.ReadUInt32().FromEndian(endian).UIntToFloat(); UnknownFloat2 = stream.ReadUInt32().FromEndian(endian).UIntToFloat(); stream.DiscardBytes(0x6C); }
public StrategyOption(System.IO.Stream stream, uint refStringStart, Util.Endianness endian, Util.Bitness bits) { uint entrySize = stream.ReadUInt32().FromEndian(endian); Category = stream.ReadUInt32().FromEndian(endian); InGameID = stream.ReadUInt32().FromEndian(endian); ulong refStringLocation = stream.ReadUInt(bits, endian); NameStringDicID = stream.ReadUInt32().FromEndian(endian); DescStringDicID = stream.ReadUInt32().FromEndian(endian); Characters = stream.ReadUInt32().FromEndian(endian); ID = stream.ReadUInt32().FromEndian(endian); RefString = stream.ReadAsciiNulltermFromLocationAndReset((long)(refStringStart + refStringLocation)); }
private bool LoadFile(Stream stream, Util.Endianness endian) { string magic = stream.ReadAscii(8); uint blockCount = stream.ReadUInt32().FromEndian(endian); uint refStringStart = stream.ReadUInt32().FromEndian(endian); Blocks = new List <T8BTVABlock>((int)blockCount); for (uint i = 0; i < blockCount; ++i) { Blocks.Add(new T8BTVABlock(stream, refStringStart, endian)); } return(true); }
public Location(System.IO.Stream stream, Util.Endianness endian) { uint[] Data = new uint[0x74 / 4]; // + 0x20*4 strings, + 4*4 StringDicIDs for (int i = 0; i < Data.Length; ++i) { Data[i] = stream.ReadUInt32().FromEndian(endian); } LocationID = Data[0]; DefaultStringDicID = Data[1]; Unused2 = Data[2]; Category = Data[3]; DescStringDicIDs = new uint[4]; for (int i = 0; i < 4; ++i) { DescStringDicIDs[i] = Data[5 + i]; } ShopsOrEnemyGroups = new uint[16]; for (int i = 0; i < 16; ++i) { ShopsOrEnemyGroups[i] = Data[9 + i]; } // Data[26 ~ 28] appear to be references to event triggers for when an area advances to its next 'state' // Data[25] is always 0, which makes sense as the initial state of a location should not have a required trigger ChangeEventTriggers = new uint[4]; for (int i = 0; i < 4; ++i) { ChangeEventTriggers[i] = Data[25 + i]; } long pos = stream.Position; RefStrings = new string[4]; for (int i = 0; i < 4; ++i) { RefStrings[i] = stream.ReadAsciiNullterm(); stream.Position = pos + 0x20 * (i + 1); } stream.Position = pos + 0x20 * 4; NameStringDicIDs = new uint[4]; for (int i = 0; i < 4; ++i) { NameStringDicIDs[i] = stream.ReadUInt32().FromEndian(endian); } }
public MapTile(System.IO.Stream stream, Util.Endianness endian) { RoomType = stream.ReadUInt32().FromEndian(endian); FloorExitDiff = (int)stream.ReadUInt32().FromEndian(endian); EnemyGroup = stream.ReadUInt32().FromEndian(endian); FramesToMove = stream.ReadUInt32().FromEndian(endian); RegularTreasure = stream.ReadUInt32().FromEndian(endian); SpecialTreasure = stream.ReadUInt32().FromEndian(endian); MoveUpAllowed = stream.ReadUInt32().FromEndian(endian); MoveDownAllowed = stream.ReadUInt32().FromEndian(endian); MoveLeftAllowed = stream.ReadUInt32().FromEndian(endian); MoveRightAllowed = stream.ReadUInt32().FromEndian(endian); }
private bool LoadFile(Stream stream, Util.Endianness endian) { string magic = stream.ReadAscii(8); uint unknown = stream.ReadUInt32().FromEndian(endian); uint recipeCount = stream.ReadUInt32().FromEndian(endian); RecipeList = new List <Recipe>((int)recipeCount); for (uint i = 0; i < recipeCount; ++i) { Recipe r = new Recipe(stream, endian); RecipeList.Add(r); } return(true); }
private bool LoadFile(Stream stream, Util.Endianness endian, Util.Bitness bits) { string magic = stream.ReadAscii(8); uint entryCount = stream.ReadUInt32().FromEndian(endian); uint refStringStart = stream.ReadUInt32().FromEndian(endian); GradeShopEntryList = new List <GradeShopEntry>((int)entryCount); for (uint i = 0; i < entryCount; ++i) { GradeShopEntry e = new GradeShopEntry(stream, refStringStart, endian, bits); GradeShopEntryList.Add(e); } return(true); }
private bool LoadFile(Stream stream, Util.Endianness endian, Util.Bitness bits) { string magic = stream.ReadAscii(8); uint infoCount = stream.ReadUInt32().FromEndian(endian); uint refStringStart = stream.ReadUInt32().FromEndian(endian); TreasureInfoList = new List <TreasureInfo>((int)infoCount); for (uint i = 0; i < infoCount; ++i) { TreasureInfo ti = new TreasureInfo(stream, refStringStart, endian, bits); TreasureInfoList.Add(ti); } return(true); }
private bool LoadFile(Stream stream, Util.Endianness endian, Util.Bitness bits) { string magic = stream.ReadAscii(8); uint floorInfoCount = stream.ReadUInt32().FromEndian(endian); uint refStringStart = stream.ReadUInt32().FromEndian(endian); FloorList = new List <FloorInfo>((int)floorInfoCount); for (uint i = 0; i < floorInfoCount; ++i) { FloorInfo fi = new FloorInfo(stream, refStringStart, endian, bits); FloorList.Add(fi); } return(true); }
private bool LoadFile(Stream stream, Util.Endianness endian) { string magic = stream.ReadAscii(8); uint unknown = stream.ReadUInt32().FromEndian(endian); uint titleCount = stream.ReadUInt32().FromEndian(endian); TitleList = new List <Title>((int)titleCount); for (uint i = 0; i < titleCount; ++i) { Title t = new Title(stream, endian); TitleList.Add(t); } return(true); }
public SynopsisEntry(System.IO.Stream stream, Util.Endianness endian) { ID = stream.ReadUInt32().FromEndian(endian); StoryIdMin = stream.ReadUInt32().FromEndian(endian); StoryIdMax = stream.ReadUInt32().FromEndian(endian); NameStringDicId = stream.ReadUInt32().FromEndian(endian); TextStringDicId = stream.ReadUInt32().FromEndian(endian); stream.DiscardBytes(0xC); long pos = stream.Position; RefString1 = stream.ReadAsciiNullterm(); stream.Position = pos + 0x10; RefString2 = stream.ReadAsciiNullterm(); stream.Position = pos + 0x20; }
public EncounterGroup(System.IO.Stream stream, uint refStringStart, Util.Endianness endian, Util.Bitness bits) { uint entryLength = stream.ReadUInt32().FromEndian(endian); ID = stream.ReadUInt32().FromEndian(endian); StringDicID = stream.ReadUInt32().FromEndian(endian); InGameID = stream.ReadUInt32().FromEndian(endian); ulong refLoc = stream.ReadUInt(bits, endian); EnemyGroupIDs = new uint[10]; for (int i = 0; i < 10; ++i) { EnemyGroupIDs[i] = stream.ReadUInt32().FromEndian(endian); } RefString = stream.ReadAsciiNulltermFromLocationAndReset((long)(refStringStart + refLoc)); }
private bool LoadFile( System.IO.Stream stream ) { // not entirely sure if this is actually type information? Type = stream.ReadUInt32(); if ( Type <= 0xFFFF ) { Endian = Util.Endianness.LittleEndian; } else { Endian = Util.Endianness.BigEndian; Type = Type.SwapEndian(); } bool ToZ; switch ( Type ) { case 0x08: ToZ = false; break; case 0x100: ToZ = true; break; default: System.Console.WriteLine( "Unknown SDB file type!" ); return false; } if ( ToZ ) { // seems to always be 0x0C uint unknown = stream.ReadUInt32().FromEndian( Endian ); } uint textAmount = stream.ReadUInt32().FromEndian( Endian ); if ( ToZ ) { uint otherDataAmount = stream.ReadUInt32().FromEndian( Endian ); OtherData = new List<uint>( (int)otherDataAmount ); for ( uint i = 0; i < otherDataAmount; ++i ) { OtherData.Add( stream.ReadUInt32().FromEndian( Endian ) ); } uint textOffset = stream.ReadUInt32().FromEndian( Endian ); } TextList = new List<SDBEntry>( (int)textAmount ); for ( uint i = 0; i < textAmount; ++i ) { SDBEntry x = new SDBEntry(); x.PointerIDString = (uint)stream.Position + stream.ReadUInt32().FromEndian( Endian ); x.PointerText = (uint)stream.Position + stream.ReadUInt32().FromEndian( Endian ); TextList.Add( x ); } for ( int i = 0; i < TextList.Count; ++i ) { SDBEntry x = TextList[i]; stream.Position = x.PointerIDString; x.IDString = stream.ReadUTF8Nullterm(); stream.Position = x.PointerText; x.Text = stream.ReadUTF8Nullterm(); } return true; }
private bool Load( System.IO.FileStream stream ) { CreationTime = stream.ReadUInt64(); FileHashArrayOffset = stream.ReadUInt32(); // This should always be 0x20, so we can use it to detect endianness if ( FileHashArrayOffset <= 0xFFFF ) { Endian = Util.Endianness.LittleEndian; } else { Endian = Util.Endianness.BigEndian; CreationTime = CreationTime.SwapEndian(); FileHashArrayOffset = FileHashArrayOffset.SwapEndian(); } // We adjust the offsets to be from file start rather than from position, makes them easier to seek to. FileHashArrayOffset += (uint)stream.Position - 4; FileHashArraySize = stream.ReadUInt32().FromEndian( Endian ); VirtualHashArrayOffset = (uint)stream.Position; VirtualHashArrayOffset += stream.ReadUInt32().FromEndian( Endian ); VirtualHashArraySize = stream.ReadUInt32().FromEndian( Endian ); FileArrayOffset = (uint)stream.Position; FileArrayOffset += stream.ReadUInt32().FromEndian( Endian ); FileArraySize = stream.ReadUInt32().FromEndian( Endian ); VirtualPackArrayOffset = (uint)stream.Position; VirtualPackArrayOffset += stream.ReadUInt32().FromEndian( Endian ); VirtualPackArraySize = stream.ReadUInt32().FromEndian( Endian ); // Hashes stream.Position = FileHashArrayOffset; FileHashArray = new List<TOFHDBhash>( (int)FileHashArraySize ); for ( UInt32 i = 0; i < FileHashArraySize; i++ ) { FileHashArray.Add( new TOFHDBhash() { Key = stream.ReadUInt32().FromEndian( Endian ), Value = stream.ReadUInt32().FromEndian( Endian ), } ); } // Files stream.Position = FileArrayOffset; FileArray = new List<TOFHDBfile>( (int)FileArraySize ); for ( UInt32 i = 0; i < FileArraySize; i++ ) { FileArray.Add( new TOFHDBfile() { Filesize = stream.ReadUInt64().FromEndian( Endian ), CompressedSize = stream.ReadUInt64().FromEndian( Endian ), Offset = stream.ReadUInt64().FromEndian( Endian ), Hash = stream.ReadUInt32().FromEndian( Endian ), Extension = stream.ReadAscii( 0x0A ).TrimNull(), Unknown = stream.ReadUInt16().FromEndian( Endian ), } ); } return true; }
private bool LoadFile( string headerFilename, string contentFilename = null ) { try { infile = new FileStream( headerFilename, FileMode.Open ); if ( contentFilename != null ) { contentFile = new FileStream( contentFilename, FileMode.Open ); } else { contentFile = infile; } } catch ( Exception ) { Console.WriteLine( "ERROR: can't open " + headerFilename ); return false; } infile.Seek( 0x00, SeekOrigin.Begin ); string magic = infile.ReadAscii( 4 ); if ( magic != "FPS4" ) { Console.WriteLine( "Not an FPS4 file!" ); return false; } Endian = Util.Endianness.BigEndian; FileCount = infile.ReadUInt32().FromEndian( Endian ); HeaderSize = infile.ReadUInt32().FromEndian( Endian ); // if header seems huge then we probably have assumed the wrong endianness if ( HeaderSize > 0xFFFF ) { Endian = Util.Endianness.LittleEndian; FileCount = FileCount.ToEndian( Util.Endianness.BigEndian ).FromEndian( Endian ); HeaderSize = HeaderSize.ToEndian( Util.Endianness.BigEndian ).FromEndian( Endian ); } FirstFileStart = infile.ReadUInt32().FromEndian( Endian ); EntrySize = infile.ReadUInt16().FromEndian( Endian ); ContentBitmask = infile.ReadUInt16().FromEndian( Endian ); Unknown2 = infile.ReadUInt32().FromEndian( Endian ); ArchiveNameLocation = infile.ReadUInt32().FromEndian( Endian ); infile.Position = ArchiveNameLocation; if ( ArchiveNameLocation > 0 ) { ArchiveName = infile.ReadShiftJisNullterm(); } Alignment = FirstFileStart; Console.WriteLine( "Content Bitmask: 0x" + ContentBitmask.ToString( "X4" ) ); return true; }