예제 #1
0
        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);
        }
예제 #2
0
        public CanDecompressAnswer CanDecompress(DuplicatableStream stream)
        {
            long pos = stream.Position;
            CanDecompressAnswer answer = stream.ReadAscii(4) == "TLZC" ? CanDecompressAnswer.Yes : CanDecompressAnswer.No;

            stream.Position = pos;
            return(answer);
        }
예제 #3
0
        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;
                    }
                }
            }
        }
예제 #4
0
 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);
 }
예제 #5
0
        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;
        }