Beispiel #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);
        }
Beispiel #2
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;
                    }
                }
            }
        }
Beispiel #3
0
        public ScenarioDatEntry(DuplicatableStream data, uint FilesOffset)
        {
            Offset               = data.ReadUInt32().SwapEndian();
            FilesizeCompressed   = data.ReadUInt32().SwapEndian();
            FilesizeUncompressed = data.ReadUInt32().SwapEndian();

            if (FilesizeCompressed > 0)
            {
                DataStream = new PartialStream(data, Offset + FilesOffset, FilesizeCompressed);
            }
            else
            {
                DataStream = null;
            }
        }
Beispiel #4
0
        public SHBP(DuplicatableStream duplicatableStream, EndianUtils.Endianness e = EndianUtils.Endianness.BigEndian)
        {
            using (DuplicatableStream s = duplicatableStream.Duplicate()) {
                uint magic = s.ReadUInt32(EndianUtils.Endianness.LittleEndian);
                if (magic != 0x50424853)
                {
                    throw new Exception("wrong magic");
                }

                uint count = s.ReadUInt32(e);
                Hashes = new List <uint>((int)count);
                for (uint i = 0; i < count; ++i)
                {
                    Hashes.Add(s.ReadUInt32(e));
                }
            }
        }
Beispiel #5
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);
 }
Beispiel #6
0
        private bool LoadFile(DuplicatableStream inputStream, EndianUtils.Endianness?endianParam, TextUtils.GameTextEncoding encoding)
        {
            DuplicatableStream stream = inputStream.Duplicate();

            stream.Position = 0;
            EndianUtils.Endianness endian;
            if (endianParam == null)
            {
                uint magic = stream.ReadUInt32().FromEndian(EndianUtils.Endianness.BigEndian);
                if (magic == 0x53453320)
                {
                    endian = EndianUtils.Endianness.BigEndian;
                }
                else if (magic == 0x20334553)
                {
                    endian = EndianUtils.Endianness.LittleEndian;
                }
                else
                {
                    Console.WriteLine("Invalid magic: " + magic);
                    return(false);
                }
            }
            else
            {
                endian = endianParam.Value;
                uint magic = stream.ReadUInt32(endian);
                if (magic != 0x53453320)
                {
                    Console.WriteLine("Invalid magic: " + magic);
                    return(false);
                }
            }

            this.Endian = endian;

            uint lengthOfFilenameSection = stream.ReadUInt32(endian);            // probably?
            uint startOfFilenameSection  = stream.ReadUInt32(endian);            // probably?

            DataBegin = stream.ReadUInt32(endian);

            stream.Position = startOfFilenameSection;
            uint magicOfFilenameSection = stream.ReadUInt32(endian);

            FileCount = stream.ReadUInt32(endian);
            Filenames = new List <string>((int)FileCount);
            for (uint i = 0; i < FileCount; ++i)
            {
                Filenames.Add(stream.ReadSizedString(48, encoding).TrimNull());
            }

            Data = stream;

            return(true);
        }
Beispiel #7
0
        public EndianUtils.Endianness Endian;         // not actually a field in the header, at least not here -- might be the first byte?

        public NubHeader(DuplicatableStream stream, EndianUtils.Endianness?endian)
        {
            Magic = stream.ReadUInt64(EndianUtils.Endianness.LittleEndian);

            EndianUtils.Endianness suspectedEndian;
            if (Magic == 0x10200)
            {
                suspectedEndian = EndianUtils.Endianness.BigEndian;
            }
            else if (Magic == 0x10201)
            {
                suspectedEndian = EndianUtils.Endianness.LittleEndian;
            }
            else
            {
                throw new Exception("unexpected magic in NUB");
            }

            EndianUtils.Endianness e = endian ?? suspectedEndian;
            Fileid         = stream.ReadUInt32(e);     // or something like that? seems unique per archive in each game
            EntryCount     = stream.ReadUInt32(e);
            StartOfFiles   = stream.ReadUInt32(e);
            FilesSize      = stream.ReadUInt32(e);
            StartOfEntries = stream.ReadUInt32(e);
            StartOfHeaders = stream.ReadUInt32(e);

            Endian = e;
        }
Beispiel #8
0
        public iPck(DuplicatableStream duplicatableStream, EndianUtils.Endianness e = EndianUtils.Endianness.BigEndian)
        {
            using (DuplicatableStream s = duplicatableStream.Duplicate()) {
                uint magic = s.ReadUInt32(EndianUtils.Endianness.LittleEndian);
                if (magic != 0x6b635069)
                {
                    throw new Exception("wrong magic");
                }

                uint count        = s.ReadUInt32(e);
                uint offsetsStart = s.ReadUInt32(e);
                uint dataStart    = s.ReadUInt32(e);

                s.Position = offsetsStart;
                uint[] offsets = s.ReadUInt32Array(count, e);

                s.Position = dataStart;
                long dataEnd = s.Length - dataStart;
                Data = new List <byte[]>((int)count);
                for (uint i = 0; i < count; ++i)
                {
                    long start = offsets[i];
                    if (start == 0xffffffffu)
                    {
                        Data.Add(null);
                    }
                    else
                    {
                        long end = FindFileEnd(offsets, i, dataEnd);
                        long len = end - start;
                        s.Position = dataStart + start;
                        Data.Add(s.ReadUInt8Array(len));
                    }
                }
            }
        }
Beispiel #9
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;
        }
Beispiel #10
0
 public Dol(DuplicatableStream stream)
 {
     Stream          = stream.Duplicate();
     Stream.Position = 0;
     FileOffsets     = new List <uint>(18);
     LoadingAddress  = new List <uint>(18);
     SectionSizes    = new List <uint>(18);
     for (int i = 0; i < 18; ++i)
     {
         FileOffsets.Add(Stream.ReadUInt32().FromEndian(EndianUtils.Endianness.BigEndian));
     }
     for (int i = 0; i < 18; ++i)
     {
         LoadingAddress.Add(Stream.ReadUInt32().FromEndian(EndianUtils.Endianness.BigEndian));
     }
     for (int i = 0; i < 18; ++i)
     {
         SectionSizes.Add(Stream.ReadUInt32().FromEndian(EndianUtils.Endianness.BigEndian));
     }
     BssAddress = Stream.ReadUInt32().FromEndian(EndianUtils.Endianness.BigEndian);
     BssSize    = Stream.ReadUInt32().FromEndian(EndianUtils.Endianness.BigEndian);
     EntryPoint = Stream.ReadUInt32().FromEndian(EndianUtils.Endianness.BigEndian);
 }
Beispiel #11
0
        // initialize from existing CPK
        public CpkBuilder(DuplicatableStream stream, Endianness endian = Endianness.BigEndian)
        {
            // should start with CPK and some unknown header bytes
            long cpkHeaderOffset = stream.Position;
            uint cpkMagic        = stream.ReadUInt32(Endianness.LittleEndian);

            if (cpkMagic != 0x204B5043)
            {
                throw new Exception("wrong CPK magic");
            }

            UnknownCpkHeaderBytes = stream.ReadBytes(12);

            // main UTF table should follow
            MainUtfTable = new UtfBuilder(stream, endian);
            if (MainUtfTable.Rows.Count != 1)
            {
                throw new Exception("wrong rowcount in main UTF table");
            }

            UnknownPostCpkHeaderBytes = stream.ReadBytes(4);
            while (stream.ReadByte() == 0)
            {
                ;
            }
            stream.Position = stream.Position - 1;
            CopyrightText   = stream.ReadBytes(stream.Position.Align(0x800, cpkHeaderOffset) - stream.Position);           // or something

            ulong tocOffset = (ulong)MainUtfTable.Rows[0].Cells[MainUtfTable.FindColumnIndex("TocOffset")].Data;

            //ulong tocSize = (ulong)MainUtfTable.Rows[0].Cells[MainUtfTable.FindColumnIndex("TocSize")].Data;
            if (tocOffset != 0)
            {
                stream.Position = cpkHeaderOffset + (long)tocOffset;
                uint magic = stream.ReadUInt32(Endianness.LittleEndian);
                if (magic != 0x20434F54)
                {
                    throw new Exception("wrong TOC magic");
                }
                UnknownTocHeaderBytes = stream.ReadBytes(12);
                TocUtfTable           = new UtfBuilder(stream, endian);
            }

            ulong itocOffset = (ulong)MainUtfTable.Rows[0].Cells[MainUtfTable.FindColumnIndex("ItocOffset")].Data;

            //ulong itocSize = (ulong)MainUtfTable.Rows[0].Cells[MainUtfTable.FindColumnIndex("ItocSize")].Data;
            if (itocOffset != 0)
            {
                stream.Position = cpkHeaderOffset + (long)itocOffset;
                uint magic = stream.ReadUInt32(Endianness.LittleEndian);
                if (magic != 0x434F5449)
                {
                    throw new Exception("wrong ITOC magic");
                }
                UnknownItocHeaderBytes = stream.ReadBytes(12);
                ItocUtfTable           = new UtfBuilder(stream, endian);
            }

            ulong etocOffset = (ulong)MainUtfTable.Rows[0].Cells[MainUtfTable.FindColumnIndex("EtocOffset")].Data;

            //ulong etocSize = (ulong)MainUtfTable.Rows[0].Cells[MainUtfTable.FindColumnIndex("EtocSize")].Data;
            if (etocOffset != 0)
            {
                stream.Position = cpkHeaderOffset + (long)etocOffset;
                uint magic = stream.ReadUInt32(Endianness.LittleEndian);
                if (magic != 0x434F5445)
                {
                    throw new Exception("wrong ETOC magic");
                }
                UnknownEtocHeaderBytes = stream.ReadBytes(12);
                EtocUtfTable           = new UtfBuilder(stream, endian);
            }

            ulong gtocOffset = (ulong)MainUtfTable.Rows[0].Cells[MainUtfTable.FindColumnIndex("GtocOffset")].Data;

            //ulong gtocSize = (ulong)MainUtfTable.Rows[0].Cells[MainUtfTable.FindColumnIndex("GtocSize")].Data;
            if (gtocOffset != 0)
            {
                // haven't actually seen this, but would make sense...
                stream.Position = cpkHeaderOffset + (long)gtocOffset;
                uint magic = stream.ReadUInt32(Endianness.LittleEndian);
                if (magic != 0x434F5447)
                {
                    throw new Exception("wrong GTOC magic");
                }
                UnknownGtocHeaderBytes = stream.ReadBytes(12);
                GtocUtfTable           = new UtfBuilder(stream, endian);
            }

            ulong contentOffset = (ulong)MainUtfTable.Rows[0].Cells[MainUtfTable.FindColumnIndex("ContentOffset")].Data;
            //ulong contentSize = (ulong)MainUtfTable.Rows[0].Cells[MainUtfTable.FindColumnIndex("ContentSize")].Data;
            uint fileCount = (uint)MainUtfTable.Rows[0].Cells[MainUtfTable.FindColumnIndex("Files")].Data;

            if (TocUtfTable == null || TocUtfTable.Rows.Count != fileCount)
            {
                throw new Exception("invalid TOC?");
            }

            Files = new List <CpkFile>((int)fileCount);
            int  columnDirName     = TocUtfTable.FindColumnIndex("DirName");
            int  columnFileName    = TocUtfTable.FindColumnIndex("FileName");
            int  columnFileSize    = TocUtfTable.FindColumnIndex("FileSize");
            int  columnExtractSize = TocUtfTable.FindColumnIndex("ExtractSize");
            int  columnFileOffset  = TocUtfTable.FindColumnIndex("FileOffset");
            int  columnFileIndexId = TocUtfTable.FindColumnIndex("ID");
            long baseFileOffset    = cpkHeaderOffset + ((contentOffset < tocOffset) ? (long)contentOffset : (long)tocOffset);

            for (int i = 0; i < (int)fileCount; ++i)
            {
                var f = new CpkFile();
                f.Directory = (string)TocUtfTable.Rows[i].Cells[columnDirName].Data;
                f.Name      = (string)TocUtfTable.Rows[i].Cells[columnFileName].Data;
                uint fileSize = (uint)TocUtfTable.Rows[i].Cells[columnFileSize].Data;
                f.DecompressedSize = (uint)TocUtfTable.Rows[i].Cells[columnExtractSize].Data;
                ulong fileOffset = (ulong)TocUtfTable.Rows[i].Cells[columnFileOffset].Data;
                f.FileStream = new HyoutaUtils.Streams.PartialStream(stream, baseFileOffset + (long)fileOffset, fileSize);
                f.ID         = (uint)TocUtfTable.Rows[i].Cells[columnFileIndexId].Data;
                Files.Add(f);
            }

            return;
        }
Beispiel #12
0
        public UtfBuilder(DuplicatableStream stream, Endianness endian = Endianness.BigEndian)
        {
            long utfHeaderOffset = stream.Position;
            uint utfMagic        = stream.ReadUInt32(Endianness.LittleEndian);

            if (utfMagic != 0x46545540)
            {
                throw new Exception("wrong UTF magic");
            }

            uint size = stream.ReadUInt32(endian);             // size of the whole UTF chunk minus the magic and this value itself

            // offsets are relative to here
            long offset = stream.Position;

            uint   rowsLocation                   = stream.ReadUInt32(endian);
            uint   stringTableLocation            = stream.ReadUInt32(endian);
            uint   dataTableLocation              = stream.ReadUInt32(endian);
            uint   tableNameLocationInStringTable = stream.ReadUInt32(endian);
            ushort colcount  = stream.ReadUInt16(endian);
            ushort rowwidth  = stream.ReadUInt16(endian);
            uint   rowcount  = stream.ReadUInt32(endian);
            string tableName = stream.ReadUTF8NulltermFromLocationAndReset(offset + stringTableLocation + tableNameLocationInStringTable);

            // utf_tab calls this the 'schema'
            List <ColumnData> columns = new List <ColumnData>(colcount);

            for (int i = 0; i < colcount; ++i)
            {
                ColumnData col = new ColumnData();
                col.Type = stream.ReadUInt8();
                uint stroffset = stream.ReadUInt32(endian);
                col.Name = stream.ReadUTF8NulltermFromLocationAndReset(offset + stringTableLocation + stroffset);

                if ((col.Type & utf_tab_sharp.UtfTab.COLUMN_STORAGE_MASK) == utf_tab_sharp.UtfTab.COLUMN_STORAGE_CONSTANT)
                {
                    switch (col.Type & utf_tab_sharp.UtfTab.COLUMN_TYPE_MASK)
                    {
                    case utf_tab_sharp.UtfTab.COLUMN_TYPE_STRING:
                        uint datastroffset = stream.ReadUInt32(endian);
                        col.Data = stream.ReadUTF8NulltermFromLocationAndReset(offset + stringTableLocation + datastroffset);
                        break;

                    case utf_tab_sharp.UtfTab.COLUMN_TYPE_8BYTE:
                        col.Data = stream.ReadUInt64(endian);
                        break;

                    case utf_tab_sharp.UtfTab.COLUMN_TYPE_DATA:
                        uint dataOffset = stream.ReadUInt32(endian);
                        uint dataSize   = stream.ReadUInt32(endian);
                        col.Data = stream.ReadBytesFromLocationAndReset(offset + dataTableLocation + dataOffset, dataSize);
                        break;

                    case utf_tab_sharp.UtfTab.COLUMN_TYPE_FLOAT:
                        col.Data = stream.ReadUInt32(endian).UIntToFloat();
                        break;

                    case utf_tab_sharp.UtfTab.COLUMN_TYPE_4BYTE2:
                    case utf_tab_sharp.UtfTab.COLUMN_TYPE_4BYTE:
                        col.Data = stream.ReadUInt32(endian);
                        break;

                    case utf_tab_sharp.UtfTab.COLUMN_TYPE_2BYTE2:
                    case utf_tab_sharp.UtfTab.COLUMN_TYPE_2BYTE:
                        col.Data = stream.ReadUInt16(endian);
                        break;

                    case utf_tab_sharp.UtfTab.COLUMN_TYPE_1BYTE2:
                    case utf_tab_sharp.UtfTab.COLUMN_TYPE_1BYTE:
                        col.Data = stream.ReadUInt8();
                        break;

                    default:
                        throw new Exception("unknown type for constant");
                    }
                }

                columns.Add(col);
            }

            List <RowData> rows = new List <RowData>((int)rowcount);

            for (long i = 0; i < rowcount; ++i)
            {
                stream.Position = offset + rowsLocation + (i * rowwidth);
                RowData row = new RowData();
                row.Cells = new List <CellData>();
                for (int j = 0; j < colcount; ++j)
                {
                    CellData cell = new CellData();
                    byte     type = columns[j].Type;
                    switch ((type & utf_tab_sharp.UtfTab.COLUMN_STORAGE_MASK))
                    {
                    case utf_tab_sharp.UtfTab.COLUMN_STORAGE_PERROW:
                        switch (type & utf_tab_sharp.UtfTab.COLUMN_TYPE_MASK)
                        {
                        case utf_tab_sharp.UtfTab.COLUMN_TYPE_STRING:
                            uint datastroffset = stream.ReadUInt32(endian);
                            cell.Data = stream.ReadUTF8NulltermFromLocationAndReset(offset + stringTableLocation + datastroffset);
                            break;

                        case utf_tab_sharp.UtfTab.COLUMN_TYPE_8BYTE:
                            cell.Data = stream.ReadUInt64(endian);
                            break;

                        case utf_tab_sharp.UtfTab.COLUMN_TYPE_DATA:
                            uint dataOffset = stream.ReadUInt32(endian);
                            uint dataSize   = stream.ReadUInt32(endian);
                            cell.Data = stream.ReadBytesFromLocationAndReset(offset + dataTableLocation + dataOffset, dataSize);
                            break;

                        case utf_tab_sharp.UtfTab.COLUMN_TYPE_FLOAT:
                            cell.Data = stream.ReadUInt32(endian).UIntToFloat();
                            break;

                        case utf_tab_sharp.UtfTab.COLUMN_TYPE_4BYTE2:
                        case utf_tab_sharp.UtfTab.COLUMN_TYPE_4BYTE:
                            cell.Data = stream.ReadUInt32(endian);
                            break;

                        case utf_tab_sharp.UtfTab.COLUMN_TYPE_2BYTE2:
                        case utf_tab_sharp.UtfTab.COLUMN_TYPE_2BYTE:
                            cell.Data = stream.ReadUInt16(endian);
                            break;

                        case utf_tab_sharp.UtfTab.COLUMN_TYPE_1BYTE2:
                        case utf_tab_sharp.UtfTab.COLUMN_TYPE_1BYTE:
                            cell.Data = stream.ReadUInt8();
                            break;

                        default:
                            throw new Exception("unknown type for value");
                        }
                        break;

                    case utf_tab_sharp.UtfTab.COLUMN_STORAGE_CONSTANT:
                        cell.Data = columns[j].Data;
                        break;

                    case utf_tab_sharp.UtfTab.COLUMN_STORAGE_ZERO:
                        switch (type & utf_tab_sharp.UtfTab.COLUMN_TYPE_MASK)
                        {
                        case utf_tab_sharp.UtfTab.COLUMN_TYPE_STRING:
                            cell.Data = "";
                            break;

                        case utf_tab_sharp.UtfTab.COLUMN_TYPE_8BYTE:
                            cell.Data = (ulong)0;
                            break;

                        case utf_tab_sharp.UtfTab.COLUMN_TYPE_DATA:
                            cell.Data = new byte[0];
                            break;

                        case utf_tab_sharp.UtfTab.COLUMN_TYPE_FLOAT:
                            cell.Data = 0.0f;
                            break;

                        case utf_tab_sharp.UtfTab.COLUMN_TYPE_4BYTE2:
                        case utf_tab_sharp.UtfTab.COLUMN_TYPE_4BYTE:
                            cell.Data = (uint)0;
                            break;

                        case utf_tab_sharp.UtfTab.COLUMN_TYPE_2BYTE2:
                        case utf_tab_sharp.UtfTab.COLUMN_TYPE_2BYTE:
                            cell.Data = (ushort)0;
                            break;

                        case utf_tab_sharp.UtfTab.COLUMN_TYPE_1BYTE2:
                        case utf_tab_sharp.UtfTab.COLUMN_TYPE_1BYTE:
                            cell.Data = (byte)0;
                            break;

                        default:
                            throw new Exception("unknown type for value");
                        }
                        break;

                    default:
                        throw new Exception("unknown storage for value");
                    }
                    row.Cells.Add(cell);
                }
                rows.Add(row);
            }

            Name    = tableName;
            Columns = columns;
            Rows    = rows;

            stream.Position = utfHeaderOffset + ((long)8) + ((long)size);

            return;
        }
Beispiel #13
0
        public override INode GetChildByIndex(long index)
        {
            if (index >= 0 && index < Entries.LongLength)
            {
                uint entryLoc = Entries[index];
                Stream.Position = entryLoc;
                uint type = Stream.ReadUInt32(Endian);

                switch (type)
                {
                // PC vesperia can't agree with itself whether this is endian-agnostic or not, the JP files have it swapped compared to the EN files...
                case 0x69733134:
                case 0x34317369: {
                    Stream.Position = entryLoc + 0x14;
                    uint length = Stream.ReadUInt32(Endian);
                    uint offset = Stream.ReadUInt32(Endian);
                    Stream.Position = entryLoc + 0xbc;
                    byte[] bnsfheader = Stream.ReadUInt8Array(0x30);

                    Stream.Position = Header.StartOfFiles + offset;
                    using (var ms = new MemoryStream()) {
                        ms.Write(bnsfheader);
                        StreamUtils.CopyStream(Stream, ms, length);
                        return(new NubFile(ms.CopyToByteArrayStreamAndDispose(), "bnsf"));
                    }
                }

                case 0x64737000: {
                    Stream.Position = entryLoc + 0x14;
                    uint length = Stream.ReadUInt32(Endian);
                    uint offset = Stream.ReadUInt32(Endian);
                    Stream.Position = entryLoc + 0xbc;
                    byte[] dspheader = Stream.ReadUInt8Array(0x60);

                    Stream.Position = Header.StartOfFiles + offset;
                    using (var ms = new MemoryStream()) {
                        ms.Write(dspheader);
                        StreamUtils.CopyStream(Stream, ms, length);
                        return(new NubFile(ms.CopyToByteArrayStreamAndDispose(), "dsp"));
                    }
                }

                case 0x61743300: {
                    Stream.Position = entryLoc;
                    byte[] at3header = Stream.ReadUInt8Array(0x100);

                    Stream.Position = entryLoc + 0x14;
                    uint length = Stream.ReadUInt32(Endian);
                    uint offset = Stream.ReadUInt32(Endian);
                    Stream.Position = Header.StartOfFiles + offset;

                    using (var ms = new MemoryStream()) {
                        ms.Write(at3header);
                        StreamUtils.CopyStream(Stream, ms, length);
                        return(new NubFile(ms.CopyToByteArrayStreamAndDispose(), "at3"));
                    }
                }

                case 0x76616700: {
                    Stream.Position = entryLoc;
                    byte[] vagheader = Stream.ReadUInt8Array(0xc0);

                    Stream.Position = entryLoc + 0x14;
                    uint length = Stream.ReadUInt32(Endian);
                    uint offset = Stream.ReadUInt32(Endian);
                    Stream.Position = Header.StartOfFiles + offset;

                    using (var ms = new MemoryStream()) {
                        if (Endian == EndianUtils.Endianness.LittleEndian)
                        {
                            // unclear if this needs to be all swapped or just a subset...
                            for (int i = 0; i < 0xc0; i += 4)
                            {
                                ms.WriteByte(vagheader[i + 3]);
                                ms.WriteByte(vagheader[i + 2]);
                                ms.WriteByte(vagheader[i + 1]);
                                ms.WriteByte(vagheader[i + 0]);
                            }
                        }
                        else
                        {
                            ms.Write(vagheader);
                        }
                        ms.WriteUInt64(0);
                        ms.WriteUInt64(0);
                        StreamUtils.CopyStream(Stream, ms, length);
                        return(new NubFile(ms.CopyToByteArrayStreamAndDispose(), "vag"));
                    }
                }

                default:
                    Console.WriteLine("Unimplemented nub subtype: 0x" + type.ToString("x8"));
                    return(null);
                }
            }
            return(null);
        }
Beispiel #14
0
        public TrophyTrp(HyoutaPluginBase.DuplicatableStream stream, EndianUtils.Endianness endian = EndianUtils.Endianness.BigEndian)
        {
            Stream = stream.Duplicate();
            Endian = endian;
            try {
                Stream.ReStart();
                Magic = Stream.ReadUInt32().FromEndian(EndianUtils.Endianness.LittleEndian);
                if (Magic != 0x004DA2DC)
                {
                    throw new Exception("invalid magic");
                }
                Unknown2 = Stream.ReadUInt32().FromEndian(endian);
                Unknown3 = Stream.ReadUInt32().FromEndian(endian);
                Filesize = Stream.ReadUInt32().FromEndian(endian);

                Filecount = Stream.ReadUInt32().FromEndian(endian);
                Unknown6  = Stream.ReadUInt32().FromEndian(endian);
                Unknown7  = Stream.ReadUInt32().FromEndian(endian);
                Unknown8  = Stream.ReadUInt32().FromEndian(endian);

                Unknown9  = Stream.ReadUInt32().FromEndian(endian);
                Unknown10 = Stream.ReadUInt32().FromEndian(endian);
                Unknown11 = Stream.ReadUInt32().FromEndian(endian);
                Unknown12 = Stream.ReadUInt32().FromEndian(endian);

                Unknown13 = Stream.ReadUInt32().FromEndian(endian);
                Unknown14 = Stream.ReadUInt32().FromEndian(endian);
                Unknown15 = Stream.ReadUInt32().FromEndian(endian);
                Unknown16 = Stream.ReadUInt32().FromEndian(endian);
            } finally {
                Stream.End();
            }
        }