diff --git a/ArcFormats/RPM/ArcARC.cs b/ArcFormats/RPM/ArcARC.cs
index 67be4eb1..f694d474 100644
--- a/ArcFormats/RPM/ArcARC.cs
+++ b/ArcFormats/RPM/ArcARC.cs
@@ -44,11 +44,13 @@ namespace GameRes.Formats.Rpm
{
public string Keyword;
public int NameLength;
+ public int IndexOffset;
- public EncryptionScheme (string key, int name_length = 32)
+ public EncryptionScheme (string key, int name_length = 32, int index_offset = 8)
{
Keyword = key;
NameLength = name_length;
+ IndexOffset = index_offset;
}
}
@@ -82,22 +84,26 @@ namespace GameRes.Formats.Rpm
}
/// Minimum entry length across all possible archive schemes.
- const int MinEntryLength = 0x24;
+ const int MinEntryLength = 0x1C;
// largest size should be first
- static readonly int[] PossibleNameSizes = new[] { 0x20, 0x18 };
+ static readonly int[] PossibleNameSizes = new[] { 0x20, 0x18, 0x10 };
public override ArcFile TryOpen (ArcView file)
{
int count = file.View.ReadInt32 (0);
- if (!IsSaneCount (count) || 8 + count * MinEntryLength >= file.MaxOffset)
- return null;
- uint is_compressed = file.View.ReadUInt32 (4);
- if (is_compressed > 1) // should be either 0 or 1
+ if (!IsSaneCount (count) || 4 + count * MinEntryLength >= file.MaxOffset)
return null;
- var index_reader = new ArcIndexReader (file, count, is_compressed != 0);
- var scheme = index_reader.GuessScheme (8, PossibleNameSizes);
+ uint is_compressed = 1;
+ var index_reader = new ArcIndexReader (file, count);
+ var scheme = index_reader.GuessScheme (4, PossibleNameSizes);
+ if (null == scheme)
+ {
+ is_compressed = file.View.ReadUInt32 (4);
+ if (is_compressed <= 1) // should be either 0 or 1
+ scheme = index_reader.GuessScheme (8, PossibleNameSizes);
+ }
// additional checks to avoid dialog popup on false positives
if (null == scheme && KnownSchemes.Count > 0 && file.Name.HasExtension (".arc"))
{
@@ -114,7 +120,7 @@ namespace GameRes.Formats.Rpm
&& VFS.IsPathEqualsToFileName (file.Name, "instdata.arc"))
scheme = new EncryptionScheme ("inst", scheme.NameLength);
- var dir = index_reader.ReadIndex (8, scheme);
+ var dir = index_reader.ReadIndex (scheme, scheme.IndexOffset > 4 ? is_compressed != 0 : true);
if (null == dir)
return null;
return new ArcFile (file, this, dir);
@@ -161,17 +167,16 @@ namespace GameRes.Formats.Rpm
{
ArcView m_file;
int m_count;
- bool m_is_compressed;
- public ArcIndexReader (ArcView file, int count, bool is_compressed)
+ public ArcIndexReader (ArcView file, int count)
{
m_file = file;
m_count = count;
- m_is_compressed = is_compressed;
}
- public List ReadIndex (long offset, EncryptionScheme scheme)
+ public List ReadIndex (EncryptionScheme scheme, bool is_compressed)
{
+ long offset = scheme.IndexOffset;
int index_size = m_count * (scheme.NameLength + 12);
var index = m_file.View.ReadBytes (offset, (uint)index_size);
if (index.Length != index_size)
@@ -192,7 +197,7 @@ namespace GameRes.Formats.Rpm
entry.UnpackedSize = LittleEndian.ToUInt32 (index, index_offset);
entry.Size = LittleEndian.ToUInt32 (index, index_offset+4);
entry.Offset = LittleEndian.ToUInt32 (index, index_offset+8);
- entry.IsPacked = m_is_compressed;
+ entry.IsPacked = is_compressed;
if (0 != entry.Size)
{
if (entry.Offset < data_offset || !entry.CheckPlacement (m_file.MaxOffset))
@@ -247,7 +252,7 @@ namespace GameRes.Formats.Rpm
key[(second_match+i) % key_length] = sym;
}
if (i == key_length)
- return new EncryptionScheme (Encoding.ASCII.GetString (key), name_length);
+ return new EncryptionScheme (Encoding.ASCII.GetString (key), name_length, index_offset);
}
return null;
}
diff --git a/ArcFormats/RPM/ArcZENOS.cs b/ArcFormats/RPM/ArcZENOS.cs
deleted file mode 100644
index 5fde034d..00000000
--- a/ArcFormats/RPM/ArcZENOS.cs
+++ /dev/null
@@ -1,56 +0,0 @@
-//! \file ArcZENOS.cs
-//! \date 2017 Nov 21
-//! \brief Zenos resource archive format.
-//
-// Copyright (C) 2017 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
-// deal in the Software without restriction, including without limitation the
-// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
-// sell copies of the Software, and to permit persons to whom the Software is
-// furnished to do so, subject to the following conditions:
-//
-// The above copyright notice and this permission notice shall be included in
-// all copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
-// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
-// IN THE SOFTWARE.
-//
-
-using System.ComponentModel.Composition;
-
-namespace GameRes.Formats.Rpm
-{
- [Export(typeof(ArchiveFormat))]
- public class ZenosOpener : ArcOpener
- {
- public override string Tag { get { return "ARC/ZENOS"; } }
- public override string Description { get { return "Zenos resource archive"; } }
- public override uint Signature { get { return 0; } }
- public override bool IsHierarchic { get { return false; } }
- public override bool CanWrite { get { return false; } }
-
- public override ArcFile TryOpen (ArcView file)
- {
- int count = file.View.ReadInt32 (0);
- if (!IsSaneCount (count) || 4 + count * 0x1C >= file.MaxOffset)
- return null;
-
- var index_reader = new ArcIndexReader (file, count, true);
-// var scheme = new EncryptionScheme ("haku", 0x10);
- var scheme = index_reader.GuessScheme (4, new int[] { 0x10 });
- if (null == scheme)
- return null;
- var dir = index_reader.ReadIndex (4, scheme);
- if (null == dir)
- return null;
- return new ArcFile (file, this, dir);
- }
- }
-}