internal View(AssetLoader loader) : base(loader) { using (BinaryReader reader = loader.Reader) { // 8-byte header var count = reader.ReadByte(); var flags = reader.ReadByte(); // Bit 0x80 means palette is set bool isCompressed = (flags & 0x40) == 0; ushort mirroredFlags = reader.ReadUInt16(); Unknowns.ReadInt16s(reader, 1); ushort paletteOffset = reader.ReadUInt16(); if (paletteOffset != 0 && paletteOffset != 0x100) { throw new NotImplementedException(); } for (int index = 0; index < count; index++) { reader.BaseStream.Position = 8 + index * 2; var animation = FindAnimation(loader, reader.ReadUInt16()); GroupsMutable.Add(new ViewGroup(animation, (mirroredFlags & (1 << index)) != 0)); } } }
internal ModelDetailLevel(ModelMesh mesh, int index, AssetLoader loader, int dataOffset, ArrayBackedList <byte> bufferData) : base(mesh, index, loader) { var reader = loader.Reader; Mesh = mesh; const int indexSize = 2; Threshold = reader.ReadInt32(); Unknowns.ReadInt16s(reader, IsDS1 ? 1 : 2); if (IsDS1) { reader.RequireZeroes(2); } IndexCount = reader.ReadInt32(); IndexDataOffset = reader.ReadInt32() + dataOffset; int indexDataSize = reader.ReadInt32(); if (indexDataSize != IndexCount * indexSize) { throw new InvalidDataException("Index data size doesn't match the expected value from the index count."); } reader.RequireZeroes(4 * 3); BufferIndexOffset = bufferData.Count; long reset = reader.BaseStream.Position; reader.BaseStream.Position = IndexDataOffset; bufferData.AddRange(reader, IndexCount * indexSize); reader.BaseStream.Position = reset; }
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); } } }
internal Message(AssetLoader loader) : base(loader) { using (BinaryReader reader = loader.Reader) { Version = (MessageVersion)reader.ReadInt32(); int fileLength, addonOffset = -1; int count; Codex <MessageItem> items = new Codex <MessageItem>(); Items = items; switch (MajorVersion) { case 3: fileLength = reader.ReadUInt16() + 6; count = reader.ReadUInt16(); break; case 4: addonOffset = reader.ReadUInt16() + 6; Unknowns.ReadInt16s(reader, 1); count = reader.ReadUInt16(); break; case 5: addonOffset = reader.ReadInt32() + 6; count = reader.ReadUInt16(); break; default: throw new NotImplementedException("Unimplemented version " + Version); } for (int index = 0; index < count; index++) { MessageItem item = new MessageItem(this, index, loader); items.Add(item); AddChild(item); } foreach (MessageItem item in items) { item.ReadText(reader); } if (addonOffset >= 0) { reader.BaseStream.Position = addonOffset; foreach (MessageItem item in items) { item.ReadAddOn(reader); } } } }
internal BiffArchiveRecord(BiffArchive archive, int index, AssetLoader loader) : base(archive, index) { BinaryReader reader = loader.Reader; Id = reader.ReadInt32(); Offset = reader.ReadUInt32(); Size = reader.ReadInt32(); Type = (BiffArchiveRecordType)reader.ReadUInt16(); Unknowns.ReadInt16s(reader, 1); }
internal ModelBoneUnknown(FolderAsset bonesFolder, int index, AssetLoader loader) : base(bonesFolder, index, loader) { var reader = loader.Reader; Unknowns.ReadSingles(reader, 3); reader.Require(IsDS1 ? 0xFFFFFFFFu : 0xFF000000u); Unknowns.ReadSingles(reader, 3); Unknowns.ReadInt16s(reader, 2); Unknowns.ReadSingles(reader, 3); Unknowns.ReadInt16s(reader, 2); reader.RequireZeroes(4 * 4); }
internal Picture(AssetLoader loader) : base(loader) { BinaryReader reader = loader.Reader; ushort check = reader.ReadUInt16(); Codex <PictureInstruction> instructions = new Codex <PictureInstruction>(); Codex <PictureCel> cels = new Codex <PictureCel>(); if (check == 0x0E) // VGA picture { int celCount = reader.ReadUInt16(); Unknowns.ReadInt16s(reader, 1); // 0x2A int paletteOffset = reader.ReadInt32(); Dimensions = new Vector2i(reader.ReadUInt16(), reader.ReadUInt16()); reader.BaseStream.Position = paletteOffset; Palette = new Palette(loader); AddChild(Palette); for (int celIndex = 0; celIndex < celCount; celIndex++) { PictureCel cel = new PictureCel(this, celIndex, loader); cels.Add(cel); AddChild(cel); instructions.Add(new PictureInstruction.DrawCel(cel)); } } else { Dimensions = new Vector2i(320, 190); reader.BaseStream.Seek(-2, SeekOrigin.Current); byte[] data = reader.ReadBytes(checked ((int)reader.BaseStream.Length)); Stream stream = new MemoryStream(data, false); PicturePatternFlags patternFlags = PicturePatternFlags.None; byte patternNumber = 0; while (true) { PictureInstruction instruction = PictureInstruction.ReadInstruction(stream, ref patternFlags, ref patternNumber); instructions.Add(instruction); if (instruction.IsQuit) { break; } } } Cels = cels; Instructions = instructions; }
internal ModelMaterialParameter(ModelMaterial material, int materialIndex, int index, AssetLoader loader) : base(material, index, loader) { var reader = loader.Reader; Material = material; MaterialIndex = materialIndex; Value = reader.ReadStringzAtUInt32(Encoding); Name = reader.ReadStringzAtUInt32(Encoding); Unknowns.ReadSingles(reader, 2); Unknowns.ReadInt16s(reader, 1); // Always 257? reader.RequireZeroes(2); reader.RequireZeroes(12); }
internal ParameterDefinition(AssetLoader loader) : base(loader) { var reader = loader.Reader; loader.Expect(loader.CheckedShortLength); loader.Expect((ushort)0x30); // Offset of rows Unknowns.ReadInt16s(reader, 1); // 1-4 int rowCount = reader.ReadUInt16(); loader.Expect((ushort)0xB0); // Size in bytes of a row Name = reader.ReadStringz(32, EncodingShiftJis); loader.Expect((ushort)0); loader.Expect((ushort)0x68); for (int index = 0; index < rowCount; index++) { new ParameterDefinitionRow(this, index, loader); } }
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)); } }
internal ViewAnimation(View view, AssetLoader loader) : base(loader) { BinaryReader reader = loader.Reader; View = view; var cells = new Codex <ViewCell>(); Cells = cells; DataOffset = (ushort)reader.BaseStream.Position; var count = reader.ReadUInt16(); Unknowns.ReadInt16s(reader, 1); for (int index = 0; index < count; index++) { reader.BaseStream.Position = DataOffset + 4 + index * 2; cells.Add(view.FindCell(loader, reader.ReadUInt16())); } }
internal Group(Module module, uint contentSize, uint label, ModuleGroupType groupType) : base(module.Manager, "") { BinaryReader reader = module.Reader; ContentSize = contentSize; LabelUInt32 = label; GroupType = groupType; var timeStampDay = reader.ReadByte(); // One-based day in the month. var timeStampMonth = reader.ReadByte(); TimeStamp = new DateTime(2002, 12, 1).AddMonths(timeStampMonth); int currentMonth = TimeStamp.Month; if (timeStampDay == 0) { throw new InvalidDataException(); } TimeStamp = TimeStamp.AddDays(timeStampDay - 1); if (TimeStamp.Month != currentMonth) { throw new InvalidDataException(); } //.AddDays(timeStampDay); Unknowns.ReadInt16s(reader, 1); Version = reader.ReadUInt16(); Unknowns.ReadInt16s(reader, 1); ContentOffset = reader.BaseStream.Position; reader.BaseStream.Seek(ContentSize, SeekOrigin.Current); Name = GroupType + " " + LabelValue; }
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); } } }