bunch of stuff.

This commit is contained in:
morkt
2023-08-24 01:33:50 +04:00
parent ea096c52ef
commit 77fde27d26
119 changed files with 11078 additions and 619 deletions

View File

@@ -28,6 +28,9 @@ using System.Collections.Generic;
using System.ComponentModel.Composition;
using System.IO;
// [960920][Petit] Trouble Outsiders
// [980220][Euphony Production] Happening Journey
namespace GameRes.Formats.ArchAngel
{
[Export(typeof(ArchiveFormat))]
@@ -44,7 +47,7 @@ namespace GameRes.Formats.ArchAngel
ContainedFormats = new[] { "CB" };
}
static readonly string[] DefaultSections = { "image", "script", null };
static readonly string[] DefaultSections = { "image", "script", "" };
public override ArcFile TryOpen (ArcView file)
{
@@ -54,13 +57,7 @@ namespace GameRes.Formats.ArchAngel
int file_count = file.View.ReadInt16 (0);
if (!IsSaneCount (file_count))
return null;
uint index_pos = 2;
var size_table = new uint[file_count];
for (int i = 0; i < file_count; ++i)
{
size_table[i] = file.View.ReadUInt32 (index_pos);
index_pos += 4;
}
long index_pos = 2 + 4 * file_count;
var section_table = new SortedDictionary<int, uint>();
uint min_offset = (uint)file.MaxOffset;
while (index_pos + 6 <= min_offset)
@@ -76,26 +73,34 @@ namespace GameRes.Formats.ArchAngel
}
var dir = new List<Entry> (file_count);
int section_num = 0;
Func<string> get_type;
if (section_table.Count == DefaultSections.Length)
get_type = () => DefaultSections[section_num];
else
get_type = () => section_num > 0 ? "image" : "";
foreach (var section in section_table)
{
int i = section.Key;
uint base_offset = section.Value;
do
{
uint size = size_table[i];
var entry = new PackedEntry {
Name = string.Format ("{0}-{1:D6}", section_num, i),
Offset = base_offset,
Size = size,
};
if (!entry.CheckPlacement (file.MaxOffset))
return null;
if (section_num < DefaultSections.Length && DefaultSections[section_num] != null)
entry.Type = DefaultSections[section_num];
if ("script" == entry.Type)
entry.IsPacked = true;
dir.Add (entry);
base_offset += size;
uint size = file.View.ReadUInt32 (2 + i * 4);
if (size > 0)
{
var entry = new PackedEntry
{
Name = string.Format("{0}-{1:D6}", section_num, i),
Type = get_type(),
Offset = base_offset,
Size = size,
};
if (!entry.CheckPlacement(file.MaxOffset))
return null;
if ("script" == entry.Type)
entry.IsPacked = true;
dir.Add(entry);
base_offset += size;
}
++i;
}
while (i < file_count && !section_table.ContainsKey (i));

View File

@@ -85,6 +85,14 @@ namespace GameRes.Formats.Seraphim
{
input = arc.File.CreateStream (entry.Offset+4, entry.Size-4);
return new ZLibStream (input.AsStream, CompressionMode.Decompress);
/*
using (var compr = new ZLibStream (input.AsStream, CompressionMode.Decompress))
using (var bin = new BinaryStream (compr, entry.Name))
{
var data = LzDecompress (bin);
return new BinMemoryStream (data, entry.Name);
}
*/
}
input = arc.File.CreateStream (entry.Offset, entry.Size);
if (signature < 4 || 0 != (signature & 0xFF000000))
@@ -141,4 +149,72 @@ namespace GameRes.Formats.Seraphim
return data;
}
}
[Export(typeof(ArchiveFormat))]
public class Scn95Opener : ArchiveFormat
{
public override string Tag { get { return "SCN/ARCH"; } }
public override string Description { get { return "Archangel engine scripts archive"; } }
public override uint Signature { get { return 0; } }
public override bool IsHierarchic { get { return false; } }
public override bool CanWrite { get { return false; } }
public Scn95Opener ()
{
Extensions = new[] { "dat" };
}
public override ArcFile TryOpen (ArcView file)
{
if (!VFS.IsPathEqualsToFileName (file.Name, "SCNPAC.DAT"))
return null;
uint offset = file.View.ReadUInt32 (0);
int count = (int)offset / 4;
if (offset >= file.MaxOffset || !IsSaneCount (count))
return null;
int index_offset = 4;
var dir = new List<Entry> (count);
for (int i = 0; i < count; ++i)
{
uint size = file.View.ReadUInt32 (index_offset);
if (0 == size)
return null;
var entry = new Entry {
Name = i.ToString ("D5"),
Type = "script",
Offset = offset + 4,
Size = size,
};
if (!entry.CheckPlacement (file.MaxOffset))
return null;
dir.Add (entry);
offset += size;
index_offset += 4;
}
return new ArcFile (file, this, dir);
}
public override Stream OpenEntry (ArcFile arc, Entry entry)
{
IBinaryStream input = arc.File.CreateStream (entry.Offset, entry.Size);
if (input.Signature < 4 || 0 != (input.Signature & 0xFF000000))
{
return input.AsStream;
}
try
{
var data = ScnOpener.LzDecompress (input);
return new BinMemoryStream (data, entry.Name);
}
catch
{
return arc.File.CreateStream (entry.Offset, entry.Size);
}
finally
{
input.Dispose();
}
}
}
}

View File

@@ -120,6 +120,8 @@ namespace GameRes.Formats.Seraphim
List<Entry> ReadIndex (ArcView file, long index_offset, long max_offset)
{
if (index_offset >= max_offset)
return null;
int base_count = file.View.ReadInt32 (index_offset);
int file_count = file.View.ReadInt32 (index_offset + 4);
index_offset += 8;
@@ -220,7 +222,9 @@ namespace GameRes.Formats.Seraphim
{
uint width = input.ReadUInt16();
uint height = input.ReadUInt16();
if (width > 0x4100 || 0 == width || 0 == height || width * height * 3 + 4 != input.Length)
uint plane_size = width * height;
uint total_size = (uint)(input.Length - 4);
if (width > 0x4100 || 0 == width || 0 == height || (total_size % plane_size) != 0)
{
input.Position = 0;
return new ImageFormatDecoder (input);

View File

@@ -47,7 +47,7 @@ namespace GameRes.Formats.Seraphim
Extensions = new string[] { "dat" };
}
static readonly Regex VoiceRe = new Regex (@"^Voice\d\.dat$", RegexOptions.IgnoreCase);
static readonly Regex VoiceRe = new Regex (@"^Voice(?:\d|pac)\.dat$", RegexOptions.IgnoreCase);
public override ArcFile TryOpen (ArcView file)
{

View File

@@ -47,12 +47,15 @@ namespace GameRes.Formats.Seraphim
public SeraphCfImage ()
{
Extensions = new string[] { "cts" };
Signatures = new [] { 0x4643u, 0x024643u, 0x044643u, 0x074643u, 0x094643u, 0x144643u, 0u };
Extensions = new [] { "cts" };
}
public override ImageMetaData ReadMetaData (IBinaryStream stream)
{
var header = stream.ReadHeader (0x10);
if ('C' != header[0] || 'F' != header[1] || 0 != header[3])
return null;
int packed_size = header.ToInt32 (12);
if (packed_size <= 0 || packed_size > stream.Length-0x10)
return null;