Esempio n. 1
0
        internal void Read(BinaryReader reader)
        {
            reader.BaseStream.Position = Offset + 12;
            Unknowns.ReadInt32s(reader, 1);
            Unknowns.ReadInt16s(reader, 2);
            Unknowns.ReadInt32s(reader, 1);

            if (Format != null)
            {
                int length = DataLength;

                if (Format.Header != null)
                {
                    Header  = new MissionTableHeader(this, Format.Header, reader);
                    length -= Format.Header.Size;
                }

                if (length % Format.Row.Size != 0)
                {
                    throw new InvalidDataException();
                }
                int count = length / Format.Row.Size;
                for (int index = 0; index < count; index++)
                {
                    new MissionRow(this, Format.Row, reader);
                }
            }
        }
Esempio n. 2
0
        internal PictureCel(Picture picture, int celIndex, AssetLoader loader)
            : base(loader)
        {
            Name = "Cel " + celIndex;
            BinaryReader reader = loader.Reader;

            reader.BaseStream.Position = 0x0E + celIndex * 0x2A;
            Vector2i dimensions = new Vector2i(reader.ReadUInt16(), reader.ReadUInt16());

            Displacement = new Vector2i(reader.ReadUInt16(), reader.ReadUInt16());
            MaskIndex    = reader.ReadByte();
            loader.ExpectZeroes(1, 3);
            Unknowns.ReadInt32s(reader, 2, "Data offsets?");
            loader.ExpectZeroes(4, 1);
            int dataOffset = reader.ReadInt32();

            loader.ExpectZeroes(4, 2);
            Priority = reader.ReadUInt16();
            Offset   = new Vector2i(reader.ReadUInt16(), reader.ReadUInt16()) * 2;
            if (Offset.Y > 0)
            {
                Offset = new Vector2i(Offset.X, Offset.Y * 6 / 5);
            }

            reader.BaseStream.Position = dataOffset;
            int[] indices = reader.ReadBytesAsInt32(dimensions.Product);

            Setup(picture.Palette.PaletteAsset, dimensions.X, dimensions.Y, indices);
        }
Esempio n. 3
0
            internal Point(Table table, int index, AssetLoader loader)
                : base(table, index)
            {
                BinaryReader reader = loader.Reader;
                long         start  = reader.BaseStream.Position;

                loader.Expect(HeaderLength);
                loader.ExpectZeroes(4, 1);            // Probably type, always zero.
                loader.Expect(index);                 // Zero-based index of the row with this type.
                Subtype  = reader.ReadInt32();
                Position = new Vector3f(reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle());
                Rotation = Angle3.Degrees(reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle());
                int unknown1Offset = reader.ReadInt32();                 // Offset to Unknown1 from start of row.
                int unknown2Offset = reader.ReadInt32();                 // Offset to Unknown2 from start of row (Unknown1Offset + 4).
                int unknown3Offset = reader.ReadInt32();                 // Offset to Unknown3 from start of row, or 0 if none (Unknown2Offset + 4).
                int unknown4Offset = reader.ReadInt32();                 // Offset to Unknown3 from start of row (Unknown2Offset + 4 or Unknown3Offset + 12).

                loader.ExpectZeroes(4, 1);
                Name = reader.ReadStringz(EncodingShiftJis);

                reader.BaseStream.Position = start + unknown1Offset;
                loader.ExpectZeroes(4, 2);                 // Unknown1 and Unknown2
                if (unknown3Offset != 0)
                {
                    Unknowns.ReadSingles(reader, 3);
                }
                Unknowns.ReadInt32s(reader, 1);                 // -1 or values like 1002000 for events.

                var errors = loader.Errors;
            }
Esempio n. 4
0
        internal TextureArchiveRecord(TextureArchive archive, BinaryReader reader, ByteOrder order)
            : base(archive, "")
        {
            Offset = reader.ReadInt32(order);
            Size   = reader.ReadInt32(order);

            if (Archive.Platform == DSPlatform.PS3)
            {
                int format = reader.ReadInt16(order);
                Id            = reader.ReadInt16(order);
                Ps3Dimensions = new Vector2i(reader.ReadUInt16(order), reader.ReadUInt16(order));

                switch (format)
                {
                case 0: Ps3Format = Glare.Graphics.Formats.DXT1; break;

                case 0x0500: Ps3Format = Glare.Graphics.Formats.DXT5; break;

                case 0x0900: Ps3Format = Glare.Graphics.Formats.Vector4nb; break;

                default: throw new NotSupportedException(string.Format("PS3 format 0x{0:X4} (dimensions {1}, data size {2}) is not known.", format, Ps3Dimensions, Size));
                }

                Unknowns.ReadInt32s(reader, 1);
                reader.RequireZeroes(4);
            }
            else
            {
                Id = reader.ReadInt32(order);
            }

            Name = reader.ReadStringzAtUInt32(order, Alexandria.Engines.DarkSouls.Archive.ShiftJis);
            reader.RequireZeroes(4);
        }
Esempio n. 5
0
        internal MCGTable3(MCG mcg, int index, AssetLoader loader)
            : base(mcg, index)
        {
            var reader = loader.Reader;

            int count = reader.ReadInt32();

            Position = reader.ReadVector3f();
            Table1U1 = mcg.GetTable1Slice(count, reader.ReadInt32());
            Table1U2 = mcg.GetTable1Slice(count, reader.ReadInt32());
            Unknowns.ReadInt32s(reader, 2);
        }
Esempio n. 6
0
        internal MCPTable2(MCP mcp, int index, AssetLoader loader)
            : base(mcp, index)
        {
            var reader = loader.Reader;

            Unknowns.ReadInt32s(reader, 1);
            loader.Expect(index);

            int count1  = reader.ReadInt32();
            int offset1 = reader.ReadInt32();

            Table1U1 = mcp.GetTable1Slice(count1, offset1);

            Box = loader.ReadCheckedAbsoluteBox3f();
        }
Esempio n. 7
0
            internal Model(Table table, int index, AssetLoader loader)
                : base(table, index)
            {
                BinaryReader reader = loader.Reader;

                loader.Expect(HeaderLength);
                Type  = (ModelType)reader.ReadInt32();
                Index = reader.ReadInt32();

                int contentSize = reader.ReadInt32();                 // Size from start to end of Name

                Unknowns.ReadInt32s(reader, 1);
                loader.ExpectZeroes(4, 3);

                Name = reader.ReadStringz(EncodingShiftJis);
                Path = reader.ReadStringz(EncodingShiftJis);
            }
Esempio n. 8
0
        internal ModelMesh(FolderAsset folder, int index, AssetLoader loader)
            : base(folder, index, loader)
        {
            var reader = loader.Reader;

            Unknowns.ReadInt32s(reader, 1);             // 1?
            MaterialIndex = reader.ReadInt32();
            reader.RequireZeroes(4 * 2);
            Unknowns.ReadInt32s(reader, 1);             // 0 or 1, seems to be material-related but is not transparency; second seems bones-related
            int boneCount = reader.ReadInt32();

            reader.RequireZeroes(4 * 1);
            int boneIndicesOffset = reader.ReadInt32();

            PartCount = reader.ReadInt32();
            int partIndicesOffset = reader.ReadInt32();

            reader.Require(1);
            int indexOffset = reader.ReadInt32();

            long reset = reader.BaseStream.Position;

            reader.BaseStream.Position = boneIndicesOffset;
            var bones = new Codex <ModelBone>();

            Bones = bones;
            for (int i = 0; i < boneCount; i++)
            {
                bones.Add(Model.Bones[reader.ReadInt32()]);
            }

            // Read the part indices.
            reader.BaseStream.Position = partIndicesOffset;
            int partStart = PartStartIndex;

            for (int i = 0; i < PartCount; i++)
            {
                reader.Require(i + partStart);
            }

            reader.BaseStream.Position = indexOffset;
            reader.Require(Index);

            reader.BaseStream.Position = reset;
        }
Esempio n. 9
0
        internal ParameterTable(AssetLoader loader)
            : base(loader)
        {
            var reader             = loader.Reader;
            int stringsOffset      = reader.ReadInt32();
            int firstRowDataOffset = reader.ReadUInt16();

            Unknowns.ReadInt16s(reader, 2);
            int rowCount = reader.ReadUInt16();

            Name = reader.ReadStringz(0x20, Encoding.ASCII);
            Unknowns.ReadInt32s(reader, 1);

            // Read in the row headers.
            RowInfo[] rows = new RowInfo[rowCount];
            for (int index = 0; index < rowCount; index++)
            {
                rows[index].Read(reader);
            }

            // Read in the rows.
            for (int index = 0; index < rowCount; index++)
            {
                loader.Position = rows[index].DataOffset;
                int next = index < rows.Length - 1 ? rows[index + 1].DataOffset : stringsOffset;
                ParameterTableRow item = ParameterTableRow.ReadRow(this, index, loader, next);
                item.Id = rows[index].Id;

                if (loader.Position != next)
                {
                    loader.AddError(rows[index].DataOffset, "Row {0} of the table did not read the correct amount; position should be {1}, but is {2}.", index, next, loader.Position);
                }
            }

            // Read in the row names.
            for (int index = 0; index < rowCount; index++)
            {
                loader.Position = rows[index].NameOffset;
                ((ParameterTableRow)Children[index]).Name = reader.ReadStringz(EncodingShiftJis).Trim();                //((index < rows.Length - 1 ? rows[index + 1].NameOffset : loader.ShortLength) - rows[index].NameOffset - 1, EncodingShiftJis));
            }
        }
Esempio n. 10
0
        internal ModelBone(FolderAsset folder, int index, AssetLoader loader)
            : base(folder, index, loader)
        {
            var reader = loader.Reader;

            Position             = reader.ReadVector3f();
            Name                 = reader.ReadStringzAtUInt32(Encoding);
            Angle                = Angle3.Radians(reader.ReadVector3f());
            parentIndex          = reader.ReadInt16();
            firstChildIndex      = reader.ReadInt16();
            Scale                = reader.ReadVector3f();
            nextSiblingIndex     = reader.ReadInt16();
            previousSiblingIndex = reader.ReadInt16();
            var min = reader.ReadVector3f();

            Unknowns.ReadInt32s(reader, 1);             // 0 or 1
            var max = reader.ReadVector3f();

            Bounds = new Box3f(min, max);
            reader.RequireZeroes(4 * 13);
        }
Esempio n. 11
0
        internal ModelMaterial(FolderAsset parent, int index, AssetLoader loader)
            : base(parent, index, loader)
        {
            var reader = loader.Reader;

            Name           = reader.ReadStringzAtUInt32(Encoding);
            ShaderName     = reader.ReadStringzAtUInt32(Encoding);
            ParameterCount = reader.ReadInt32();
            int parameterStartIndex = reader.ReadInt32();

            Unknowns.ReadInt32s(reader, 1);
            if (IsDS2)
            {
                Unknowns.ReadInt32s(reader, 1);
            }
            reader.RequireZeroes(4 * (IsDS1 ? 3 : 2));

            if (parameterStartIndex != ParameterStartIndex)
            {
                throw new InvalidDataException("Parameter start index is not valid.");
            }
        }
Esempio n. 12
0
        internal MCGTable2(MCG mcg, int index, AssetLoader loader)
            : base(mcg, index)
        {
            var reader = loader.Reader;

            Unknowns.ReadInt32s(reader, 1);

            int count1  = reader.ReadInt32();
            int offset1 = reader.ReadInt32();

            Table1U1 = mcg.GetTable1Slice(count1, offset1);

            Unknowns.ReadInt32s(reader, 1);

            int count2  = reader.ReadInt32();
            int offset2 = reader.ReadInt32();

            Table1U2 = mcg.GetTable1Slice(count2, offset2);

            Unknowns.ReadInt32s(reader, 2);

            Unknowns.ReadSingles(reader, 1);
        }
Esempio n. 13
0
            internal Event(Table table, int index, AssetLoader loader, int next)
                : base(table, index)
            {
                BinaryReader reader = loader.Reader;
                long         start  = loader.Position;

                loader.Expect(HeaderLength);
                Unknowns.ReadInt32s(reader, 1);
                Type  = reader.ReadInt32();
                Index = reader.ReadInt32();
                int offseta = reader.ReadInt32();
                int offsetb = reader.ReadInt32();

                if (offsetb != offseta + 0x10)
                {
                    loader.AddError(start, "{0} index {1} does not have a normal offset A/B", GetType().Name, index);
                }
                loader.ExpectZeroes(4, 1);
                Name = reader.ReadStringz(EncodingShiftJis);

                loader.Position = start + offseta;
                Unknowns.ReadInt32s(reader, 4);
                Unknowns.ReadInt32s(reader, (next - (int)loader.Position) / 4);
            }
Esempio n. 14
0
            internal Part(Table table, int index, AssetLoader loader, int next)
                : base(table, index)
            {
                BinaryReader reader = loader.Reader;
                long         start  = reader.BaseStream.Position;

                loader.Expect(HeaderLength);
                Type = (ModelType)reader.ReadInt32();
                Unknowns.ReadInt32s(reader, 1);
                Index = reader.ReadInt32();
                int pathOffset = reader.ReadInt32();

                Position = reader.ReadVector3f();
                Rotation = Angle3.Degrees(reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle());
                Scale    = reader.ReadVector3f();
                Unknowns.ReadInt32s(reader, 8);
                int offset1 = reader.ReadInt32();
                int offset2 = reader.ReadInt32();

                if (offset1 + 0x18 != offset2)
                {
                    loader.AddError(start, "Offset2 is not correct.");
                }
                loader.ExpectZeroes(4, 1);
                Name = reader.ReadStringz(EncodingShiftJis);
                Path = reader.ReadStringz(EncodingShiftJis);

                loader.Position = start + offset1;
                Unknowns.ReadInt32s(reader, 6, "Offset1s");

                if (loader.Position > next || (next - loader.Position) / 4 > 64)
                {
                }

                Unknowns.ReadInt32s(reader, (int)(next - loader.Position) / 4, "Offset2s");
            }
Esempio n. 15
0
        internal ArchiveRecord(Archive archive, int index, BinaryReader reader, int recordHeaderSize)
            : base(archive, "")
        {
            archive.records.Add(this);
            Index = index;

            switch (archive.Variant)
            {
            case ArchiveVariant.V3:
                reader.Require(0x40);
                Size   = reader.ReadInt32();
                Offset = reader.ReadInt32();
                Id     = reader.ReadInt32();
                Name   = reader.ReadStringzAtUInt32(Archive.ShiftJis);
                int size2 = reader.ReadInt32();
                if (Size != size2)
                {
                    throw new Exception();
                }
                fixedUncompressedSize = Size;
                break;

            case ArchiveVariant.V4:
                Compression = reader.ReadInt32();                         // 2 or 3 - compression?
                reader.ReadMatch(-1);
                Size = reader.ReadInt64();
                if (recordHeaderSize == 0x1C)
                {
                    Offset = reader.ReadInt64();
                    Name   = reader.ReadStringzAtUInt32(Archive.ShiftJis);
                }
                else
                {
                    fixedUncompressedSize = reader.ReadInt64();
                    Offset = reader.ReadUInt32();
                    Unknowns.ReadInt32s(reader, 1);
                    // 'Compression' = 2, Unknown = 0, Encoding = UTF8
                    Name = reader.ReadStringzAtUInt32(Archive.ShiftJis);
                }
                Id = DarkSouls.Archive.HashFilename(Name);
                break;

            case ArchiveVariant.V5:
                Id     = reader.ReadInt32();
                Size   = reader.ReadInt32();
                Offset = reader.ReadInt32();
                reader.RequireZeroes(4);                         // NameOffset, but zero?

                string foundName;
                if (!Archive.KnownFiles.TryGetValue(Id, out foundName))
                {
                    Name = string.Format("#{0:X}", Id);
                }
                else
                {
                    Name = foundName;
                }
                break;

            default:
                throw new NotImplementedException();
            }

            MoveIntoPath(Name);
        }
Esempio n. 16
0
        internal Model(AssetLoader loader)
            : base(loader)
        {
            Asset        context = loader.Context;
            string       name    = loader.Name;
            BinaryReader reader  = loader.Reader;

            FolderAsset textureArchive = null;

            FolderAsset bonesFolder              = new FolderAsset(this, "Bones");
            FolderAsset materialsFolder          = new FolderAsset(this, "Materials");
            FolderAsset meshesFolder             = new FolderAsset(this, "Meshes");
            FolderAsset vertexDeclarationsFolder = new FolderAsset(this, "Vertex declarations");

            ArrayBackedList <byte> bufferData = new ArrayBackedList <byte>();

            if (context != null && context.Parent is FolderAsset)
            {
                // @"/map/m##_##_##_##/m*.flver.dcx" for DS1; textures are in the @"/map/m##/" folder.
                if (name.StartsWith(@"map/m"))
                {
                    string      folderName = name.Substring(4, 3);
                    FolderAsset maps       = (FolderAsset)context.Parent.Parent;
                    foreach (FolderAsset child in maps.Children)
                    {
                        if (child.Name == folderName)
                        {
                            textureArchive = child;
                            break;
                        }
                    }
                }
                else
                {
                    textureArchive = (FolderAsset)context.Parent;
                }
            }

#if Marking
            MarkingStream markingStream = loader.StartMarking(out reader);
#endif

            loader.ExpectMagic(Magic);
            char endian = (char)reader.ReadByte();

            switch (endian)
            {
            case 'L':
                ByteOrder = ByteOrder.LittleEndian;
                break;

            case 'B':
                reader    = loader.MakeBigEndian();
                ByteOrder = ByteOrder.BigEndian;
                break;

            default:
                throw new Exception();
            }

            using (reader) {
                // Read header.
                loader.Expect((byte)0);
                Version = (ModelVersion)reader.ReadInt32();
                if (Version != ModelVersion.DarkSouls && Version != ModelVersion.DarkSouls2)
                {
                    loader.AddError(loader.Position - 4, "Unknown model version " + VersionString + "; will try to load it anyway.");
                }
                int dataOffset = reader.ReadInt32();
                int dataSize   = reader.ReadInt32();
                if (((dataOffset + dataSize + 31) & ~31) != reader.BaseStream.Length)
                {
                    loader.AddError(loader.Position - 4, "Data size and offset aren't correct.");
                }

                int boneUnknownCount = reader.ReadInt32();
                int materialCount    = reader.ReadInt32();
                int boneCount        = reader.ReadInt32();

                int meshCount  = reader.ReadInt32();
                int meshCount2 = reader.ReadInt32();
                if (meshCount != meshCount2)
                {
                    loader.AddError(loader.Position - 4, "Mesh count 1 and 2 aren't the same.");
                }

                Bounds = new Box3f(reader.ReadVector3f(), reader.ReadVector3f());
                Unknowns.ReadInt32s(reader, 1);                 // Possible the non-degenerate triangle count. Seems related.
                int triangleCount = reader.ReadInt32();

                loader.Expect(IsDS1 ? 272 : 0x10010100);
                loader.Expect(IsDS1 ? 0 : 0xFFFF);

                int partCount = reader.ReadInt32();
                int vertexDeclarationCount = reader.ReadInt32();
                int materialParameterCount = reader.ReadInt32();
                loader.Expect(IsDS1 ? 0 : 0x1000000);
                loader.ExpectZeroes(4, 8);

                // Calculate offsets.
                long boneUnknownsOffset       = HeaderSize;
                long materialsOffset          = boneUnknownsOffset + boneUnknownCount * ModelBoneUnknown.DataSize;
                long bonesOffset              = materialsOffset + materialCount * ModelMaterial.DataSize;
                long meshesOffset             = bonesOffset + boneCount * ModelBone.DataSize;
                long detailLevelsOffset       = meshesOffset + meshCount * ModelMesh.DataSize;
                long meshVerticesOffset       = detailLevelsOffset + partCount * ModelDetailLevel.DataSize;
                long vertexDeclarationsOffset = meshVerticesOffset + meshCount * ModelMesh.DataSizeVertexHeader;
                long materialParametersOffset = vertexDeclarationsOffset + vertexDeclarationCount * ModelVertexDeclaration.DataSize;
                long postHeaderOffset         = materialParametersOffset + materialParameterCount * ModelMaterialParameter.DataSize;

                // BoneUnknowns
                ExpectedOffset(loader, boneUnknownsOffset, typeof(ModelBoneUnknown).Name);
                for (int index = 0; index < boneUnknownCount; index++)
                {
                    boneUnknowns.Add(new ModelBoneUnknown(bonesFolder, index, loader));
                }

                // Materials
                ExpectedOffset(loader, materialsOffset, typeof(ModelMaterial).Name);
                for (int index = 0; index < materialCount; index++)
                {
                    materials.Add(new ModelMaterial(materialsFolder, index, loader));
                }
                int expectedMaterialParameterCount = materialCount > 0 ? materials[materialCount - 1].ParameterEndIndex : 0;
                if (expectedMaterialParameterCount != materialParameterCount)
                {
                    loader.AddError(null, "Expected material parameter count {0} doesn't match actual count {1}.", expectedMaterialParameterCount, materialParameterCount);
                }

                // Bones
                ExpectedOffset(loader, bonesOffset, typeof(ModelBone).Name);
                for (int index = 0; index < boneCount; index++)
                {
                    bones.Add(new ModelBone(bonesFolder, index, loader));
                }

                // Meshes
                ExpectedOffset(loader, meshesOffset, typeof(ModelMesh).Name);
                for (int index = 0; index < meshCount; index++)
                {
                    meshes.Add(new ModelMesh(meshesFolder, index, loader));
                }
                int expectedPartCount = meshCount > 0 ? meshes[meshCount - 1].PartEndIndex : 0;
                if (expectedPartCount != partCount)
                {
                    throw new InvalidDataException("Expected part count doesn't match actual count.");
                }

                // Detail levels
                ExpectedOffset(loader, detailLevelsOffset, typeof(ModelDetailLevel).Name);
                foreach (ModelMesh mesh in meshes)
                {
                    mesh.ReadDetailLevels(loader, dataOffset, bufferData);
                    detailLevels.AddRange(mesh.DetailLevels);
                }

                // Mesh vertices
                ExpectedOffset(loader, meshVerticesOffset, typeof(ModelMesh).Name + " vertex header");
                foreach (ModelMesh mesh in meshes)
                {
                    mesh.ReadVertexHeaders(reader, dataOffset, bufferData);
                }

                // Vertex declarations
                ExpectedOffset(loader, vertexDeclarationsOffset, typeof(ModelVertexDeclaration).Name);
                for (int index = 0; index < vertexDeclarationCount; index++)
                {
                    vertexDeclarations.Add(new ModelVertexDeclaration(vertexDeclarationsFolder, index, loader));
                }

                // Material parameters
                ExpectedOffset(loader, materialParametersOffset, typeof(ModelMaterialParameter).Name);
                foreach (ModelMaterial material in materials)
                {
                    material.ReadParameters(loader, textureArchive);
                    materialParameters.AddRange(material.Parameters);
                }

                ExpectedOffset(loader, postHeaderOffset, "Post-header");

#if Marking
                if (markingStream != null)
                {
                    markingStream.Report(loader);
                }
#endif // Marking

#if SkippedChecks
                /*int vertexDataSize = 0, indexCount = 0, indexSize = 0, vertexCount = 0, expectedTriangleCount = 0, nondegenerateTriangleCount = 0;
                 * foreach (var mesh in Meshes) {
                 *      vertexDataSize += mesh.VertexCount * mesh.VertexSize;
                 *      vertexCount += mesh.VertexCount;
                 *      foreach (var part in mesh.Parts) {
                 *              indexCount += part.Indices.Length;
                 *              indexSize += part.Indices.Length * 2;
                 *              expectedTriangleCount += part.Indices.Length - 2;
                 *              for (int index = 0; index < part.Indices.Length - 2; index++) {
                 *                      if (part.Indices[index] != part.Indices[index + 1] && part.Indices[index + 1] != part.Indices[index + 2] && part.Indices[index] != part.Indices[index + 2])
                 *                              nondegenerateTriangleCount++;
                 *              }
                 *      }
                 * }
                 * if (Math.Abs(expectedTriangleCount - triangleCount) > partCount)
                 *      throw new InvalidDataException("Expected triangle count doesn't match the read value.");*/
#endif
            }

            Buffer = new GraphicsBuffer(bufferData.Count == 0 ? 1 : bufferData.Count);
            Buffer.Write(0, bufferData.Array, 0, bufferData.Count);
        }
Esempio n. 17
0
        internal ResourceMap(AssetManager manager, AssetLoader loader)
            : base(manager, loader.Name)
        {
            var reader = loader.Reader;

            Path        = loader.Name;
            FileManager = loader.FileManager;
            Version     = DetectVersion(loader);

            Dictionary <ResourceType, FolderAsset> folders = new Dictionary <ResourceType, FolderAsset>();

            using (reader) {
                if (Version == ResourceMapVersion.Sci0)
                {
                    // Simple list of entries of type (short typeAndIndex, int offsetAndPage), terminated with a (-1, -1)
                    while (true)
                    {
                        ResourceId id = new ResourceId(reader, Version);

                        if (id.IsEnd)
                        {
                            break;
                        }
                        AddResource(id, folders);
                    }
                }
                else if (Version == ResourceMapVersion.Sci1)
                {
                    List <KeyValuePair <ResourceType, int> > types = new List <KeyValuePair <ResourceType, int> >();

                    while (true)
                    {
                        ResourceType type   = (ResourceType)reader.ReadByte();
                        int          offset = reader.ReadUInt16();

                        types.Add(new KeyValuePair <ResourceType, int>(type == ResourceType.End ? type : (ResourceType)((int)type & 0x7F), offset));
                        if (type == ResourceType.End)
                        {
                            break;
                        }
                    }

                    for (int typeIndex = 0; typeIndex < types.Count - 1; typeIndex++)
                    {
                        ResourceType type = types[typeIndex].Key;
                        int          end  = types[typeIndex + 1].Value;

                        while (reader.BaseStream.Position < end)
                        {
                            ResourceId id = new ResourceId(reader, Version, type);
                            AddResource(id, folders);
                        }
                    }
                }
                else if (Version == ResourceMapVersion.Sci2)
                {
                    List <KeyValuePair <ResourceType, int> > types = new List <KeyValuePair <ResourceType, int> >();

                    while (true)
                    {
                        ResourceType type   = (ResourceType)reader.ReadByte();
                        int          offset = reader.ReadUInt16();

                        types.Add(new KeyValuePair <ResourceType, int>(type, offset));
                        if (type == ResourceType.End)
                        {
                            break;
                        }
                    }

                    Unknowns.ReadInt32s(reader, 1, "Post offsets");

                    for (int typeIndex = 0; typeIndex < types.Count - 1; typeIndex++)
                    {
                        ResourceType type   = types[typeIndex].Key;
                        int          offset = types[typeIndex].Value;
                        int          end    = types[typeIndex + 1].Value;

                        if ((end - offset) % 6 != 0)
                        {
                            throw new InvalidDataException();
                        }
                        int count = (end - offset) / 6;
                        for (int index = 0; index < count; index++)
                        {
                            ResourceId id = new ResourceId(reader, Version, type);
                            AddResource(id, folders);
                        }
                    }
                }
                else
                {
                    throw new NotImplementedException();
                }
            }

            SortChildrenRecursively();
        }
Esempio n. 18
0
 internal MCGTable1(MCG mcg, int index, AssetLoader loader)
     : base(mcg, index)
 {
     Unknowns.ReadInt32s(loader.Reader, 1);
 }
Esempio n. 19
0
        internal Rom(AssetLoader loader)
            : base(loader)
        {
            BinaryReader reader = Reader = loader.Reader;

            Codex <RomFile>   files   = new Codex <RomFile>();
            Codex <RomFolder> folders = new Codex <RomFolder>();

            Files   = files;
            Folders = folders;

            GameTitle = Reader.ReadStringz(12, Encoding.ASCII);
            GameCode  = Reader.ReadStringz(4, Encoding.ASCII);

            // Offset 0x10
            MakerCode    = Reader.ReadStringz(2, Encoding.ASCII);
            UnitCode     = reader.ReadByte();
            DeviceCode   = reader.ReadByte();
            CardSizeBase = reader.ReadByte();
            loader.ExpectZeroes(1, 7);
            Unknowns.ReadInt32s(reader, 1);             // Usually 0, Alice in Wonderland: 3

            // Offset 0x20
            PageSize = reader.ReadInt32();             // Usually (always?) 0x4000
            Unknowns.ReadInt16s(reader, 2);            // The Dark Spire: 0x800; Trauma Center: 0xF780 (-2176)
            loader.Expect(0x2000000);
            Unknowns.ReadInt32s(reader, 1);            // The Dark Spire: 0x9BEF8; Trauma Center: 0x1DC518

            // Offset 0x30
            Unknowns.ReadInt32s(reader, 1);             // Entry points? The Dark Spire: 0x152200; Trauma Center: 0x1E0600
            loader.Expect(0x2380000);
            loader.Expect(0x2380000);
            Unknowns.ReadInt16s(reader, 1);             // The Dark Spire: 0x6F28; Trauma Center: 0x6F24
            loader.Expect((short)0x2);

            // Offset 0x40
            int fileNameTableOffset = reader.ReadInt32();
            int fileNameTableSize   = reader.ReadInt32();
            int fileSizeTableOffset = reader.ReadInt32();
            int fileSizeTableSize   = reader.ReadInt32();

            // Offset 0x50
            Unknowns.ReadInt32s(reader, 2, "Offset and size");             // Used in The Dark Spire, zeroes in Trauma Center.
            loader.ExpectZeroes(4, 2);

            // Offset 0x60
            Unknowns.ReadInt32s(reader, 2);
            int iconAndTitleOffset = reader.ReadInt32();

            Unknowns.ReadInt32s(reader, 1);

            // Offset 0x70
            Unknowns.ReadInt32s(reader, 2);
            loader.ExpectZeroes(4, 2);

            // Offset 0x80
            DataLength = reader.ReadInt32();
            loader.Expect(PageSize);
            Unknowns.ReadInt32s(reader, 2);             // The Dark Spire: 0x4B68; 0 in Trauma Center.

            ReadIconAndTitle(iconAndTitleOffset);

            if (fileNameTableOffset > 0)
            {
                int folderNamesOffset = reader.ReadInt32At(fileNameTableOffset);
                reader.BaseStream.Position = fileNameTableOffset;
                int folderCount = folderNamesOffset / 8;
                for (int index = 0; index < folderCount; index++)
                {
                    folders.Add(new RomFolder(this, index, reader));
                }
                byte[] folderNames = reader.ReadBytes(fileNameTableSize - folderNamesOffset);

                reader.BaseStream.Position = fileSizeTableOffset;
                int fileCount = fileSizeTableSize / 8;
                for (int index = 0; index < fileCount; index++)
                {
                    files.Add(new RomFile(this, index, reader));
                }

                folders[0].Sort(this, "Root", folderNamesOffset, folderNames);

                FolderAsset orphanedFolders = null, orphanedFiles = null;

                foreach (RomFolder folder in folders)
                {
                    if (folder.Used)
                    {
                        continue;
                    }
                    if (orphanedFolders == null)
                    {
                        orphanedFolders = new FolderAsset(this, "Orphaned folder[s]");
                    }
                    folder.Sort(this, folder.Name, folderNamesOffset, folderNames);
                }

                foreach (RomFile file in files)
                {
                    if (file.Used)
                    {
                        continue;
                    }
                    if (orphanedFiles == null)
                    {
                        orphanedFiles = new FolderAsset(this, "Orphaned file[s]");
                    }
                    file.Sort(orphanedFiles, file.Name);
                }
            }
        }