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 CanDecompressAnswer CanDecompress(DuplicatableStream stream) { long pos = stream.Position; CanDecompressAnswer answer = stream.ReadAscii(4) == "TLZC" ? CanDecompressAnswer.Yes : CanDecompressAnswer.No; stream.Position = pos; return(answer); }
public void PrintData(EndianUtils.Endianness endian, Dictionary <uint, TSS.TSSEntry> inGameDic, List <ItemDat.ItemDatSingle> itemDataSorted, T8BTEMST.T8BTEMST enemies) { using (DuplicatableStream stream = Stream.Duplicate()) { stream.ReadUInt32().FromEndian(endian); // ? stream.ReadUInt32().FromEndian(endian); // ? stream.ReadUInt32Array(9, endian); stream.ReadUInt32().FromEndian(endian); // play time in frames, assuming 60 frames = 1 second stream.ReadUInt32().FromEndian(endian); // gald stream.DiscardBytes(4); // ? uint[] itemCounts = stream.ReadUInt32Array(3072, endian); uint[] itemBookBitfields = stream.ReadUInt32Array(3072 / 32, endian); stream.DiscardBytes(4); // ? stream.ReadUInt32Array(4, endian); // control modes for the four active party slots stream.ReadUInt32Array(3, endian); // strategies assigned to dpad directions stream.DiscardBytes(0x40); // ?? for (int i = 0; i < 8; ++i) { // custom strategy names // game seems to read these till null byte so this could totally be abused to buffer overflow... stream.ReadAscii(0x40); } stream.DiscardBytes(0xA84D0 - 0xA7360); // ? uint[] monsterBookBitfieldsScanned = stream.ReadUInt32Array(0x48 / 4, endian); stream.DiscardBytes(0xA8680 - 0xA8518); // ? uint[] monsterBookBitfieldsSeen = stream.ReadUInt32Array(0x48 / 4, endian); stream.DiscardBytes(0xA8928 - 0xA86C8); // ? uint collectorsBookIndex = 0; foreach (var item in itemDataSorted) { uint i = item.Data[(int)ItemDat.ItemData.ID]; if (item.Data[(int)ItemDat.ItemData.InCollectorsBook] > 0) { bool haveItem = ((itemBookBitfields[i / 32] >> (int)(i % 32)) & 1) > 0; Console.WriteLine((haveItem ? "Y" : "N") + (collectorsBookIndex) + ": " + inGameDic[item.NamePointer].StringEngOrJpn); ++collectorsBookIndex; } } uint monsterBookIndex = 0; foreach (var enemy in enemies.EnemyList) { uint i = enemy.InGameID; if (enemy.InMonsterBook > 0) { bool haveSeen = ((monsterBookBitfieldsSeen[i / 32] >> (int)(i % 32)) & 1) > 0; bool haveScanned = ((monsterBookBitfieldsScanned[i / 32] >> (int)(i % 32)) & 1) > 0; Console.WriteLine((haveSeen ? "Y" : "N") + (haveScanned ? "Y" : "N") + (monsterBookIndex) + ": " + inGameDic[enemy.NameStringDicID].StringEngOrJpn); ++monsterBookIndex; } } } }
public TrophyTrpFile(DuplicatableStream stream, EndianUtils.Endianness endian) { Filename = stream.ReadAscii(0x20).TrimNull(); Unknown1 = stream.ReadUInt32().FromEndian(endian); Start = stream.ReadUInt32().FromEndian(endian); Unknown3 = stream.ReadUInt32().FromEndian(endian); Length = stream.ReadUInt32().FromEndian(endian); Unknown5 = stream.ReadUInt32().FromEndian(endian); Unknown6 = stream.ReadUInt32().FromEndian(endian); Unknown7 = stream.ReadUInt32().FromEndian(endian); Unknown8 = stream.ReadUInt32().FromEndian(endian); }
public SPKD(DuplicatableStream duplicatableStream, EndianUtils.Endianness e = EndianUtils.Endianness.BigEndian) { Stream = duplicatableStream.Duplicate(); Stream.Position = 4; uint fileCount = Stream.ReadUInt32(e); Stream.Position = 12; uint dataStart = Stream.ReadUInt32(e); Files = new List <SpkdFileData>((int)fileCount); Stream.Position = dataStart; for (uint i = 0; i < fileCount; ++i) { var f = new SpkdFileData(); f.Name = Stream.ReadAscii(16).TrimNull(); f.Unknown = Stream.ReadUInt32(e); f.FileStart0 = Stream.ReadUInt32(e); f.FileStart1 = Stream.ReadUInt32(e); f.FileStart2 = Stream.ReadUInt32(e); Files.Add(f); } LastFileEnd = (uint)Stream.Length; }