From 270058d56cac1744f4f95139716d471f8c8c54d8 Mon Sep 17 00:00:00 2001 From: morkt Date: Sun, 23 Sep 2018 03:55:18 +0400 Subject: [PATCH] (ALF): support non-compressed index. --- ArcFormats/Eushully/ArcALF.cs | 98 ++++++++++++++++++++++------------- 1 file changed, 61 insertions(+), 37 deletions(-) diff --git a/ArcFormats/Eushully/ArcALF.cs b/ArcFormats/Eushully/ArcALF.cs index c3ed0907..233c4cf1 100644 --- a/ArcFormats/Eushully/ArcALF.cs +++ b/ArcFormats/Eushully/ArcALF.cs @@ -2,7 +2,7 @@ //! \date Sun Sep 20 13:58:52 2015 //! \brief Eushully and its subsidiaries resource archives. // -// Copyright (C) 2015 by morkt +// Copyright (C) 2015-2018 by morkt // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to @@ -41,6 +41,11 @@ namespace GameRes.Formats.Eushully public override bool IsHierarchic { get { return false; } } public override bool CanWrite { get { return false; } } + public AlfOpener () + { + ContainedFormats = new[] { "AGF", "WAV", "AOG/SYS3", "SCR" }; + } + static string[] IndexNames = new string[] { "sys4ini.bin", "sys3ini.bin" }; public override ArcFile TryOpen (ArcView file) @@ -67,47 +72,30 @@ namespace GameRes.Formats.Eushully List ReadIndex (string ini_file, string arc_name) { if (null == LastAccessedIndex - || !LastAccessedIndex.Item1.Equals (ini_file, StringComparison.InvariantCultureIgnoreCase)) + || !LastAccessedIndex.Item1.Equals (ini_file, StringComparison.OrdinalIgnoreCase)) { LastAccessedIndex = null; using (var ini = VFS.OpenView (ini_file)) { - if (!ini.View.AsciiEqual (0, "S4IC") && !ini.View.AsciiEqual (0, "S3IC")) - return null; - uint packed_size = ini.View.ReadUInt32 (0x134); - using (var packed = ini.CreateStream (0x138, packed_size)) - using (var unpacked = new LzssStream (packed)) - using (var index = new BinaryReader (unpacked)) + IBinaryStream index; + if (ini.View.AsciiEqual (0, "S4IC") || ini.View.AsciiEqual (0, "S3IC")) { - int arc_count = index.ReadInt32(); - var name_buf = new byte[0x100]; - var file_table = new Dictionary> (arc_count, StringComparer.InvariantCultureIgnoreCase); - var arc_list = new List> (arc_count); - for (int i = 0; i < arc_count; ++i) - { - index.Read (name_buf, 0, name_buf.Length); - var file_list = new List(); - file_table.Add (Binary.GetCString (name_buf, 0, name_buf.Length), file_list); - arc_list.Add (file_list); - } - int file_count = index.ReadInt32(); - for (int i = 0; i < file_count; ++i) - { - index.Read (name_buf, 0, 0x40); - int arc_id = index.ReadInt32(); - if (arc_id < 0 || arc_id >= arc_list.Count) - return null; - index.ReadInt32(); // file number - uint offset = index.ReadUInt32(); - uint size = index.ReadUInt32(); - var name = Binary.GetCString (name_buf, 0, 0x40); - if ("@" == name) - continue; - var entry = FormatCatalog.Instance.Create (name); - entry.Offset = offset; - entry.Size = size; - arc_list[arc_id].Add (entry); - } + uint packed_size = ini.View.ReadUInt32 (0x134); + var packed = ini.CreateStream (0x138, packed_size); + var unpacked = new LzssStream (packed); + index = new BinaryStream (unpacked, ini_file); + } + else if (ini.View.AsciiEqual (0, "S3IN")) + { + index = ini.CreateStream (0x12C); + } + else + return null; + using (index) + { + var file_table = ReadSysIni (index); + if (null == file_table) + return null; LastAccessedIndex = Tuple.Create (ini_file, file_table); } } @@ -116,5 +104,41 @@ namespace GameRes.Formats.Eushully LastAccessedIndex.Item2.TryGetValue (arc_name, out dir); return dir; } + + internal Dictionary> ReadSysIni (IBinaryStream index) + { + int arc_count = index.ReadInt32(); + if (!IsSaneCount (arc_count)) + return null; + var file_table = new Dictionary> (arc_count, StringComparer.OrdinalIgnoreCase); + var arc_list = new List[arc_count]; + for (int i = 0; i < arc_count; ++i) + { + var name = index.ReadCString (0x100); + var file_list = new List(); + file_table.Add (name, file_list); + arc_list[i] = file_list; + } + int file_count = index.ReadInt32(); + if (!IsSaneCount (file_count)) + return null; + for (int i = 0; i < file_count; ++i) + { + var name = index.ReadCString (0x40); + int arc_id = index.ReadInt32(); + if (arc_id < 0 || arc_id >= arc_list.Length) + return null; + index.ReadInt32(); // file number + uint offset = index.ReadUInt32(); + uint size = index.ReadUInt32(); + if ("@" == name) + continue; + var entry = Create (name); + entry.Offset = offset; + entry.Size = size; + arc_list[arc_id].Add (entry); + } + return file_table; + } } }