/// <summary>Read the resource identifier.</summary> /// <param name="reader"></param> /// <param name="version"></param> /// <param name="type"></param> public ResourceId(BinaryReader reader, ResourceMapVersion version, ResourceType?type = null) { Version = version; if (version == ResourceMapVersion.Sci0) { short a = reader.ReadInt16(); int b = reader.ReadInt32(); if (type.HasValue) { throw new InvalidDataException(); } FullType = (ResourceType)(a >> 11); Id = a & 2047; Offset = b & ~(~0 << 26); Page = (b >> 26) & 63; if (a == -1 && b == -1) { FullType = ResourceType.End; } } else if (version == ResourceMapVersion.Sci1 || version == ResourceMapVersion.Sci2) { FullType = type.Value; Id = reader.ReadUInt16(); int b = reader.ReadInt32(); Offset = b & ~(~0 << 28); Page = (b >> 28) & 15; } else { throw new NotImplementedException(); } }
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(); }