Пример #1
0
        public override Stream GetSinglePlane(Stream inputStream, uint depthlevel)
        {
            if (Mipmaps > 1)
            {
                throw new Exception("Don't know how to deal with volume textures with mipmaps.");
            }
            if (!(Format == TextureFormat.DXT1a || Format == TextureFormat.DXT1b || Format == TextureFormat.DXT5a || Format == TextureFormat.DXT5b))
            {
                throw new Exception("Volume textures only implemented for DXT formats.");
            }

            // Format reference: https://www.khronos.org/registry/OpenGL/extensions/NV/NV_texture_compression_vtc.txt
            uint bytecount        = GetByteCountSingleDepthPlane(0);
            uint group            = depthlevel / 4u;
            uint texInGroupBefore = depthlevel % 4u;
            uint texInGroupAfter  = 3u - texInGroupBefore;

            // special handling for last group if depth not divisible by 4
            uint nonDivisiblePlanesAtEnd = Depth % 4;
            uint groupCount = Util.Align(Depth, 4u) / 4;

            if (nonDivisiblePlanesAtEnd != 0 && group == (groupCount - 1u))
            {
                texInGroupAfter = (nonDivisiblePlanesAtEnd - texInGroupBefore) - 1u;
            }

            uint bytesPerTexLine;

            switch (Format)
            {
            case TextureFormat.DXT1a:
            case TextureFormat.DXT1b:
                bytesPerTexLine = 8;
                break;

            case TextureFormat.DXT5a:
            case TextureFormat.DXT5b:
                bytesPerTexLine = 16;
                break;

            default:
                throw new Exception("Unexpected format during volume texture plane fetching: " + Format + ".");
            }

            // skip to correct group
            inputStream.DiscardBytes(group * bytecount * 4u);

            // copy texture
            MemoryStream s = new MemoryStream((int)bytecount);

            for (uint i = 0; i < bytecount; i += bytesPerTexLine)
            {
                inputStream.DiscardBytes(texInGroupBefore * bytesPerTexLine);
                Util.CopyStream(inputStream, s, bytesPerTexLine);
                inputStream.DiscardBytes(texInGroupAfter * bytesPerTexLine);
            }
            return(s);
        }
Пример #2
0
        public Stream GetSinglePlane_DepthBeforeMip(Stream inputStream, uint depthlevel)
        {
            Stream s = new MemoryStream();

            for (int i = 0; i < Mipmaps; ++i)
            {
                uint bytecount           = GetByteCountSingleDepthPlane(i);
                uint planesBeforeCurrent = depthlevel;
                uint planesAfterCurrent  = Depth - depthlevel - 1;
                inputStream.DiscardBytes(planesBeforeCurrent * bytecount);
                Util.CopyStream(inputStream, s, bytecount);
                inputStream.DiscardBytes(planesAfterCurrent * bytecount);
            }
            return(s);
        }
Пример #3
0
 public static void ReadAlign(this Stream s, long alignment)
 {
     while (s.Position % alignment != 0)
     {
         s.DiscardBytes(1);
     }
 }
Пример #4
0
 public static void ReadAlign(this Stream s, long alignment, long offset = 0)
 {
     while ((s.Position - offset) % alignment != 0)
     {
         s.DiscardBytes(1);
     }
 }
Пример #5
0
        public g1tTexture(Stream stream, EndianUtils.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 == EndianUtils.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.DXT1a; BitPerPixel = 4; break;

            case 0x08: Format = Textures.TextureFormat.DXT5; BitPerPixel = 8; break;

            case 0x12: Format = Textures.TextureFormat.DXT5; BitPerPixel = 8; break;                     // swizzled from vita

            case 0x5B: Format = Textures.TextureFormat.DXT5; BitPerPixel = 8; break;                     // unsure what the difference to 0x08 is

            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);
        }
Пример #6
0
        private bool LoadFile(Stream stream, EndianUtils.Endianness?endianParam, TextUtils.GameTextEncoding encoding)
        {
            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().FromEndian(endian);
                if (magic != 0x53453320)
                {
                    Console.WriteLine("Invalid magic: " + magic);
                    return(false);
                }
            }

            stream.DiscardBytes(8);               // unknown
            DataBegin = stream.ReadUInt32().FromEndian(endian);
            stream.DiscardBytes(4);               // unknown
            FileCount = stream.ReadUInt32().FromEndian(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);
        }
Пример #7
0
        private bool LoadFile( Stream stream, uint textPointerLocationDiff )
        {
            string magic = stream.ReadAscii( 8 );
            uint alwaysSame = stream.ReadUInt32().SwapEndian();
            uint filesize = stream.ReadUInt32().SwapEndian();

            uint lengthSection1 = stream.ReadUInt32().SwapEndian();

            stream.Position = 0x50;
            int textPointerDiffDiff = (int)stream.ReadUInt32().SwapEndian();
            stream.Position = 0x20;
            uint textStart = stream.ReadUInt32().SwapEndian();
            int textPointerDiff = (int)stream.ReadUInt32().SwapEndian() - textPointerDiffDiff;

            EntryList = new List<ScenarioFileEntry>();

            // i wonder what the actual logic behind this is...
            uint textPointersLocation = ( lengthSection1 + 0x80 ).Align( 0x10 ) + textPointerLocationDiff;
            // + 0x1888; // + 0x1B4C // diff of 2C4 // Actually this isn't constant, dammit.

            if ( textStart != textPointersLocation ) {
                stream.Position = textPointersLocation;

                while ( true ) {
                    long loc = stream.Position;
                    stream.DiscardBytes( 8 );
                    uint[] ptrs = new uint[4];
                    ptrs[0] = stream.ReadUInt32().SwapEndian();
                    ptrs[1] = stream.ReadUInt32().SwapEndian();
                    ptrs[2] = stream.ReadUInt32().SwapEndian();
                    ptrs[3] = stream.ReadUInt32().SwapEndian();

                    if ( stream.Position > textStart ) { break; }
                    if ( ptrs.Any( x => x == 0 ) ) { break; }
                    if ( ptrs.Any( x => x + textPointerDiff < textStart ) ) { break; }
                    if ( ptrs.Any( x => x + textPointerDiff >= filesize ) ) { break; }

                    var s = new ScenarioFileEntry();
                    s.Pointer = (uint)loc;
                    stream.Position = ptrs[0] + textPointerDiff;
                    s.JpName = stream.ReadShiftJisNullterm();
                    stream.Position = ptrs[1] + textPointerDiff;
                    s.JpText = stream.ReadShiftJisNullterm();
                    stream.Position = ptrs[2] + textPointerDiff;
                    s.EnName = stream.ReadShiftJisNullterm();
                    stream.Position = ptrs[3] + textPointerDiff;
                    s.EnText = stream.ReadShiftJisNullterm();
                    EntryList.Add( s );

                    stream.Position = loc + 0x18;
                }
            }

            return true;
        }
Пример #8
0
        public Stream GetSinglePlane_MipBeforeDepth(Stream inputStream, uint depthlevel)
        {
            Stream s = new MemoryStream();
            uint   planesBeforeCurrent = depthlevel;
            uint   planesAfterCurrent  = Depth - depthlevel - 1;
            uint   sum = 0u;

            for (int i = 0; i < Mipmaps; ++i)
            {
                uint bytecount = GetByteCountSingleDepthPlane(i);
                sum += bytecount;
            }
            if (Format == TextureFormat.DXT1a || Format == TextureFormat.DXT1b || Format == TextureFormat.DXT5a || Format == TextureFormat.DXT5b)
            {
                // this feels stupid??
                sum = Util.Align(sum, 0x80u);
            }
            inputStream.DiscardBytes(planesBeforeCurrent * sum);
            Util.CopyStream(inputStream, s, sum);
            inputStream.DiscardBytes(planesAfterCurrent * sum);
            return(s);
        }
        private static void ReadStringsInBlocks(List <MainDolString> output, IRomMapper dol, Stream stream, long pos, int byteSizeTotal, int blockSize, int stringsPerBlock, bool keepInvalid)
        {
            stream.Position = pos;
            int count = byteSizeTotal / blockSize;

            long[]   positions        = new long[stringsPerBlock];
            uint[]   ramAddresses     = new uint[stringsPerBlock];
            uint[]   romAddresses     = new uint[stringsPerBlock];
            string[] strings          = new string[stringsPerBlock];
            uint[]   stringByteCounts = new uint[stringsPerBlock];
            for (int i = 0; i < count; ++i)
            {
                for (int j = 0; j < stringsPerBlock; ++j)
                {
                    positions[j]    = stream.Position;
                    ramAddresses[j] = stream.ReadUInt32().FromEndian(EndianUtils.Endianness.BigEndian);
                }
                stream.DiscardBytes((uint)(blockSize - 4 * stringsPerBlock));
                bool isValid = false;
                for (int j = 0; j < stringsPerBlock; ++j)
                {
                    if (ramAddresses[j] == 0)
                    {
                        romAddresses[j]     = 0;
                        strings[j]          = null;
                        stringByteCounts[j] = 0;
                    }
                    else
                    {
                        romAddresses[j] = dol.MapRamToRom(ramAddresses[j]);

                        long tmp = stream.Position;
                        stream.Position = romAddresses[j];
                        string s         = stream.ReadNulltermString(TextUtils.GameTextEncoding.ShiftJIS);
                        uint   bytesRead = (uint)(stream.Position - romAddresses[j]);
                        stream.Position = tmp;

                        strings[j]          = s;
                        stringByteCounts[j] = bytesRead;
                        isValid             = true;
                    }
                }
                if (isValid || keepInvalid)
                {
                    for (int j = 0; j < stringsPerBlock; ++j)
                    {
                        output.Add(new MainDolString((uint)positions[j], romAddresses[j], strings[j], stringByteCounts[j]));
                    }
                }
            }
        }
Пример #10
0
        private bool LoadFile(Stream stream, Util.Endianness endian, Util.GameTextEncoding encoding)
        {
            string magic = stream.ReadAscii(4);

            if (magic != "SE3 ")
            {
                return(false);
            }

            stream.DiscardBytes(8);               // unknown
            DataBegin = stream.ReadUInt32().FromEndian(endian);
            stream.DiscardBytes(4);               // unknown
            FileCount = stream.ReadUInt32().FromEndian(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);
        }
Пример #11
0
        private bool LoadFile( Stream stream )
        {
            string magic = stream.ReadAscii( 8 );
            uint entrySize = stream.ReadUInt32().SwapEndian();
            uint synopsisCount = stream.ReadUInt32().SwapEndian();
            uint unknown = stream.ReadUInt32().SwapEndian();
            stream.DiscardBytes( 0xC );

            SynopsisList = new List<SynopsisEntry>( (int)synopsisCount );
            for ( uint i = 0; i < synopsisCount; ++i ) {
                SynopsisEntry l = new SynopsisEntry( stream );
                SynopsisList.Add( l );
            }

            return true;
        }
Пример #12
0
        private bool LoadFile(Stream stream, EndianUtils.Endianness endian)
        {
            string magic      = stream.ReadAscii(8);
            uint   unknown1   = stream.ReadUInt32().FromEndian(endian);
            uint   entryCount = stream.ReadUInt32().FromEndian(endian);
            uint   unknown2   = stream.ReadUInt32().FromEndian(endian);

            stream.DiscardBytes(12);

            BattleBookEntryList = new List <BattleBookEntry>((int)entryCount);
            for (uint i = 0; i < entryCount; ++i)
            {
                BattleBookEntry e = new BattleBookEntry(stream, endian);
                BattleBookEntryList.Add(e);
            }

            return(true);
        }
Пример #13
0
        private static List <string> ParseBookFunction(Stream s, long end, EndianUtils.Endianness e)
        {
            List <string> text        = new List <string>();
            short         dataCounter = s.ReadInt16(e);

            for (int i = 0; i < dataCounter; ++i)
            {
                s.DiscardBytes(0x26);
            }
            List <byte> sb           = new List <byte>();
            List <byte> contentbytes = new List <byte>();

            ReadString(s, sb, contentbytes);
            string str = Encoding.UTF8.GetString(sb.ToArray());

            text.AddRange(str.Split(new string[] { "\\n" }, StringSplitOptions.None));
            return(text);
        }
Пример #14
0
        private bool LoadFile(Stream stream)
        {
            string magic         = stream.ReadAscii(8);
            uint   entrySize     = stream.ReadUInt32().SwapEndian();
            uint   synopsisCount = stream.ReadUInt32().SwapEndian();
            uint   unknown       = stream.ReadUInt32().SwapEndian();

            stream.DiscardBytes(0xC);

            SynopsisList = new List <SynopsisEntry>((int)synopsisCount);
            for (uint i = 0; i < synopsisCount; ++i)
            {
                SynopsisEntry l = new SynopsisEntry(stream);
                SynopsisList.Add(l);
            }

            return(true);
        }
Пример #15
0
        private bool LoadFile(Stream stream, EndianUtils.Endianness endian)
        {
            string magic = stream.ReadAscii(8);

            if (magic != "SYNPDAT\0")
            {
                throw new Exception("Invalid magic.");
            }
            uint entrySize     = stream.ReadUInt32().FromEndian(endian);
            uint synopsisCount = stream.ReadUInt32().FromEndian(endian);
            uint unknown       = stream.ReadUInt32().FromEndian(endian);

            stream.DiscardBytes(0xC);

            SynopsisList = new List <SynopsisEntry>((int)synopsisCount);
            for (uint i = 0; i < synopsisCount; ++i)
            {
                SynopsisEntry l = new SynopsisEntry(stream, endian);
                SynopsisList.Add(l);
            }

            return(true);
        }
Пример #16
0
        private bool LoadFile(Stream stream, EndianUtils.Endianness endian, TextUtils.GameTextEncoding encoding, uint textPointerLocationDiff)
        {
            string magic      = stream.ReadAscii(8);
            uint   alwaysSame = stream.ReadUInt32().FromEndian(endian);
            uint   filesize   = stream.ReadUInt32().FromEndian(endian);

            uint lengthSection1 = stream.ReadUInt32().FromEndian(endian);

            stream.Position = 0x50;
            int textPointerDiffDiff = (int)stream.ReadUInt32().FromEndian(endian);

            stream.Position = 0x20;
            uint textStart       = stream.ReadUInt32().FromEndian(endian);
            int  textPointerDiff = (int)stream.ReadUInt32().FromEndian(endian) - textPointerDiffDiff;

            EntryList = new List <ScenarioFileEntry>();

            // i wonder what the actual logic behind this is...
            uint textPointersLocation = (lengthSection1 + 0x80).Align(0x10) + textPointerLocationDiff;

            // + 0x1888; // + 0x1B4C // diff of 2C4 // Actually this isn't constant, dammit.

            if (textStart != textPointersLocation)
            {
                stream.Position = textPointersLocation;

                while (true)
                {
                    long loc = stream.Position;
                    stream.DiscardBytes(8);
                    uint[] ptrs = new uint[4];
                    ptrs[0] = stream.ReadUInt32().FromEndian(endian);
                    ptrs[1] = stream.ReadUInt32().FromEndian(endian);
                    ptrs[2] = stream.ReadUInt32().FromEndian(endian);
                    ptrs[3] = stream.ReadUInt32().FromEndian(endian);

                    if (stream.Position > textStart)
                    {
                        break;
                    }
                    if (ptrs.Any(x => x == 0))
                    {
                        break;
                    }
                    if (ptrs.Any(x => x + textPointerDiff < textStart))
                    {
                        break;
                    }
                    if (ptrs.Any(x => x + textPointerDiff >= filesize))
                    {
                        break;
                    }

                    var s = new ScenarioFileEntry();
                    s.Pointer = (uint)loc;
                    s.JpName  = stream.ReadNulltermStringFromLocationAndReset(ptrs[0] + textPointerDiff, encoding);
                    s.JpText  = stream.ReadNulltermStringFromLocationAndReset(ptrs[1] + textPointerDiff, encoding);
                    s.EnName  = stream.ReadNulltermStringFromLocationAndReset(ptrs[2] + textPointerDiff, encoding);
                    s.EnText  = stream.ReadNulltermStringFromLocationAndReset(ptrs[3] + textPointerDiff, encoding);
                    EntryList.Add(s);

                    stream.Position = loc + 0x18;
                }
            }

            return(true);
        }
Пример #17
0
        // some skit files reuse the same JP string in cases where the english text is different, this expands this to have a separate entry for each JP string
        public static (Stream newTssStream, SCS wscsnew) MultiplyOutSkitTss(DuplicatableStream stream, SCS wscsorig)
        {
            stream.Position = 0;
            Stream s          = stream.CopyToMemory();
            uint   magic      = s.ReadUInt32().FromEndian(EndianUtils.Endianness.BigEndian);
            uint   codeStart  = s.ReadUInt32().FromEndian(EndianUtils.Endianness.BigEndian);
            uint   unknown3   = s.ReadUInt32().FromEndian(EndianUtils.Endianness.BigEndian);
            uint   dataStart  = s.ReadUInt32().FromEndian(EndianUtils.Endianness.BigEndian);
            uint   unknown5   = s.ReadUInt32().FromEndian(EndianUtils.Endianness.BigEndian);
            uint   codeLength = s.ReadUInt32().FromEndian(EndianUtils.Endianness.BigEndian);
            uint   dataLength = s.ReadUInt32().FromEndian(EndianUtils.Endianness.BigEndian);
            uint   unknown8   = s.ReadUInt32().FromEndian(EndianUtils.Endianness.BigEndian);

            List <(long pos, int number, long len)> strings = new List <(long pos, int number, long len)>();

            s.Position = codeStart;
            while (s.Position < (codeStart + codeLength + 0xC - 1))
            {
                if (s.ReadUInt32().FromEndian(EndianUtils.Endianness.BigEndian) == 0x01000000)
                {
                    if (s.PeekUInt64().FromEndian(EndianUtils.Endianness.BigEndian) == 0x0E000008040C0004)
                    {
                        s.DiscardBytes(8);
                        uint offsetOfOffset = s.ReadUInt32().FromEndian(EndianUtils.Endianness.BigEndian);
                        long pos            = s.Position;
                        s.Position = dataStart + offsetOfOffset;
                        uint offset    = s.ReadUInt32().FromEndian(EndianUtils.Endianness.BigEndian);
                        long stringpos = dataStart + offset;
                        s.Position = stringpos;
                        string str = s.ReadNulltermString(TextUtils.GameTextEncoding.ShiftJIS);
                        // must have specific format
                        if (MatchesSkitFormat(str))
                        {
                            int num = SCS.DecodeNumber(str.Substring(4, str.Length - 5));
                            strings.Add((stringpos, num, str.Length));
                        }
                        s.Position = pos;
                    }
                }
            }

            SortedSet <int> reservedNumbers = new SortedSet <int>();

            for (int i = 0; i < wscsorig.Entries.Count; ++i)
            {
                reservedNumbers.Add(i);
            }
            foreach (var d in strings)
            {
                if (reservedNumbers.Contains(d.number))
                {
                    reservedNumbers.Remove(d.number);
                }
            }

            List <string> newscs = new List <string>(wscsorig.Entries);

            List <(int oldIdx, int newIdx)> idxs = new List <(int oldIdx, int newIdx)>();
            int currentIndex = 0;

            foreach (var d in strings)
            {
                while (reservedNumbers.Contains(currentIndex))
                {
                    ++currentIndex;
                }

                string numstr    = SCS.EncodeNumber(currentIndex);
                string resultstr = "\x1F(1," + numstr + ")";
                if (resultstr.Length > d.len)
                {
                    throw new Exception("don't know how to inject this");
                }
                s.Position = d.pos;
                s.WriteShiftJisNullterm(resultstr);
                PutString(newscs, wscsorig.Entries[d.number], currentIndex);
                ++currentIndex;
            }

            s.Position = 0;
            return(s, new SCS(newscs));
        }
Пример #18
0
        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 );
        }
Пример #19
0
        private bool LoadFile( Stream stream )
        {
            string magic = stream.ReadAscii( 8 );
            uint filesize = stream.ReadUInt32().SwapEndian();
            uint modelDefStart = stream.ReadUInt32().SwapEndian();
            uint modelDefCount = stream.ReadUInt32().SwapEndian();
            uint refStringStart = stream.ReadUInt32().SwapEndian();
            uint customStart = stream.ReadUInt32().SwapEndian();
            uint customCount = stream.ReadUInt32().SwapEndian();
            uint otherStart = stream.ReadUInt32().SwapEndian();
            uint otherCount = stream.ReadUInt32().SwapEndian();
            uint u20BsectionStart = stream.ReadUInt32().SwapEndian();
            uint u20BsectionCount = stream.ReadUInt32().SwapEndian();
            uint u80sectionStart = stream.ReadUInt32().SwapEndian();
            uint u80sectionCount = stream.ReadUInt32().SwapEndian();
            stream.DiscardBytes( 8 );

            ModelDefList = new List<CharacterModelDefinition>( (int)modelDefCount );
            stream.Position = modelDefStart;
            for ( uint i = 0; i < modelDefCount; ++i ) {
                ModelDefList.Add( new CharacterModelDefinition( stream, refStringStart ) );
            }

            ModelCustomList = new List<CustomModelAddition>( (int)customCount );
            stream.Position = customStart;
            for ( uint i = 0; i < customCount; ++i ) {
                ModelCustomList.Add( new CustomModelAddition( stream, refStringStart ) );
            }

            ModelOtherList = new List<OtherModelAddition>( (int)otherCount );
            stream.Position = otherStart;
            for ( uint i = 0; i < otherCount; ++i ) {
                ModelOtherList.Add( new OtherModelAddition( stream, refStringStart ) );
            }

            U20BList = new List<Unknown0x20byteAreaB>( (int)u20BsectionCount );
            stream.Position = u20BsectionStart;
            for ( uint i = 0; i < u20BsectionCount; ++i ) {
                U20BList.Add( new Unknown0x20byteAreaB( stream, refStringStart ) );
            }

            U80List = new List<Unknown0x80byteArea>( (int)u80sectionCount );
            stream.Position = u80sectionStart;
            for ( uint i = 0; i < u80sectionCount; ++i ) {
                U80List.Add( new Unknown0x80byteArea( stream, refStringStart ) );
            }

            foreach ( var model in ModelDefList ) {
                model.Custom = new CustomModelAddition[model.CustomCount];
                for ( int i = 0; i < model.Custom.Length; ++i ) {
                    model.Custom[i] = ModelCustomList[(int)model.CustomIndex + i];
                }
                model.Other = new OtherModelAddition[model.OtherCount];
                for ( int i = 0; i < model.Other.Length; ++i ) {
                    model.Other[i] = ModelOtherList[(int)model.OtherIndex + i];
                }
                model.Unknown0x20Area = new Unknown0x20byteAreaB[model.Unknown0x20AreaCount];
                for ( int i = 0; i < model.Unknown0x20Area.Length; ++i ) {
                    model.Unknown0x20Area[i] = U20BList[(int)model.Unknown0x20AreaIndex + i];
                }
                model.Unknown0x80Area = new Unknown0x80byteArea[model.Unknown0x80AreaCount];
                for ( int i = 0; i < model.Unknown0x80Area.Length; ++i ) {
                    model.Unknown0x80Area[i] = U80List[(int)model.Unknown0x80AreaIndex + i];
                }
            }

            return true;
        }
Пример #20
0
        private bool LoadFile(Stream stream)
        {
            string magic            = stream.ReadAscii(8);
            uint   filesize         = stream.ReadUInt32().SwapEndian();
            uint   modelDefStart    = stream.ReadUInt32().SwapEndian();
            uint   modelDefCount    = stream.ReadUInt32().SwapEndian();
            uint   refStringStart   = stream.ReadUInt32().SwapEndian();
            uint   customStart      = stream.ReadUInt32().SwapEndian();
            uint   customCount      = stream.ReadUInt32().SwapEndian();
            uint   otherStart       = stream.ReadUInt32().SwapEndian();
            uint   otherCount       = stream.ReadUInt32().SwapEndian();
            uint   u20BsectionStart = stream.ReadUInt32().SwapEndian();
            uint   u20BsectionCount = stream.ReadUInt32().SwapEndian();
            uint   u80sectionStart  = stream.ReadUInt32().SwapEndian();
            uint   u80sectionCount  = stream.ReadUInt32().SwapEndian();

            stream.DiscardBytes(8);

            ModelDefList    = new List <CharacterModelDefinition>((int)modelDefCount);
            stream.Position = modelDefStart;
            for (uint i = 0; i < modelDefCount; ++i)
            {
                ModelDefList.Add(new CharacterModelDefinition(stream, refStringStart));
            }

            ModelCustomList = new List <CustomModelAddition>((int)customCount);
            stream.Position = customStart;
            for (uint i = 0; i < customCount; ++i)
            {
                ModelCustomList.Add(new CustomModelAddition(stream, refStringStart));
            }

            ModelOtherList  = new List <OtherModelAddition>((int)otherCount);
            stream.Position = otherStart;
            for (uint i = 0; i < otherCount; ++i)
            {
                ModelOtherList.Add(new OtherModelAddition(stream, refStringStart));
            }

            U20BList        = new List <Unknown0x20byteAreaB>((int)u20BsectionCount);
            stream.Position = u20BsectionStart;
            for (uint i = 0; i < u20BsectionCount; ++i)
            {
                U20BList.Add(new Unknown0x20byteAreaB(stream, refStringStart));
            }

            U80List         = new List <Unknown0x80byteArea>((int)u80sectionCount);
            stream.Position = u80sectionStart;
            for (uint i = 0; i < u80sectionCount; ++i)
            {
                U80List.Add(new Unknown0x80byteArea(stream, refStringStart));
            }

            foreach (var model in ModelDefList)
            {
                model.Custom = new CustomModelAddition[model.CustomCount];
                for (int i = 0; i < model.Custom.Length; ++i)
                {
                    model.Custom[i] = ModelCustomList[(int)model.CustomIndex + i];
                }
                model.Other = new OtherModelAddition[model.OtherCount];
                for (int i = 0; i < model.Other.Length; ++i)
                {
                    model.Other[i] = ModelOtherList[(int)model.OtherIndex + i];
                }
                model.Unknown0x20Area = new Unknown0x20byteAreaB[model.Unknown0x20AreaCount];
                for (int i = 0; i < model.Unknown0x20Area.Length; ++i)
                {
                    model.Unknown0x20Area[i] = U20BList[(int)model.Unknown0x20AreaIndex + i];
                }
                model.Unknown0x80Area = new Unknown0x80byteArea[model.Unknown0x80AreaCount];
                for (int i = 0; i < model.Unknown0x80Area.Length; ++i)
                {
                    model.Unknown0x80Area[i] = U80List[(int)model.Unknown0x80AreaIndex + i];
                }
            }

            return(true);
        }