mirror of
https://github.com/crskycode/GARbro.git
synced 2024-12-24 20:04:13 +08:00
implemented older version of Tinkerbell archives.
This commit is contained in:
parent
17e8c7efca
commit
4585f78074
@ -203,13 +203,11 @@ namespace GameRes.Formats.Cyberworks
|
||||
entry_size = pent.UnpackedSize;
|
||||
}
|
||||
var barc = arc as BellArchive;
|
||||
if (null == barc)
|
||||
if (null == barc || entry.Type != "image" || entry_size < 5)
|
||||
return input;
|
||||
try
|
||||
{
|
||||
if ("image" == entry.Type && entry_size > 5)
|
||||
return DecryptImage (input, entry_size, barc.Scheme);
|
||||
return input;
|
||||
return DecryptImage (input, entry_size, barc.Scheme);
|
||||
}
|
||||
catch
|
||||
{
|
||||
@ -218,7 +216,7 @@ namespace GameRes.Formats.Cyberworks
|
||||
}
|
||||
}
|
||||
|
||||
Stream DecryptImage (Stream input, uint entry_size, AImageScheme scheme)
|
||||
protected virtual Stream DecryptImage (Stream input, uint entry_size, AImageScheme scheme)
|
||||
{
|
||||
byte[] header = null;
|
||||
byte type = (byte)input.ReadByte();
|
||||
@ -274,7 +272,7 @@ namespace GameRes.Formats.Cyberworks
|
||||
return v;
|
||||
}
|
||||
|
||||
AImageScheme QueryScheme (string arc_name)
|
||||
internal AImageScheme QueryScheme (string arc_name)
|
||||
{
|
||||
var title = FormatCatalog.Instance.LookupGame (arc_name);
|
||||
if (!string.IsNullOrEmpty (title) && KnownSchemes.ContainsKey (title))
|
||||
@ -335,4 +333,148 @@ namespace GameRes.Formats.Cyberworks
|
||||
{
|
||||
public AImageScheme Scheme;
|
||||
}
|
||||
|
||||
[Export(typeof(ArchiveFormat))]
|
||||
public class OldDatOpener : DatOpener
|
||||
{
|
||||
public override string Tag { get { return "ARC/Csystem"; } }
|
||||
public override string Description { get { return "TinkerBell resource archive"; } }
|
||||
public override uint Signature { get { return 0; } }
|
||||
public override bool IsHierarchic { get { return false; } }
|
||||
public override bool CanWrite { get { return false; } }
|
||||
|
||||
public OldDatOpener ()
|
||||
{
|
||||
Extensions = new string[] { "dat" };
|
||||
}
|
||||
|
||||
static readonly Regex s_arcname_re = new Regex (@"^Arc0(?<num>\d)\..*$", RegexOptions.IgnoreCase);
|
||||
|
||||
static readonly IDictionary<int, int> s_arcmap = new Dictionary<int, int>
|
||||
{
|
||||
{ 2, 0 }, { 3, 1 }, { 5, 4 }
|
||||
};
|
||||
|
||||
public override ArcFile TryOpen (ArcView file)
|
||||
{
|
||||
var arc_name = Path.GetFileName (file.Name);
|
||||
var match = s_arcname_re.Match (arc_name);
|
||||
if (!match.Success)
|
||||
return null;
|
||||
int num = match.Groups["num"].Value[0] - '0';
|
||||
int index_num;
|
||||
if (!s_arcmap.TryGetValue (num, out index_num))
|
||||
return null;
|
||||
|
||||
var toc_name_builder = new StringBuilder (arc_name);
|
||||
var num_pos = match.Groups["num"].Index;
|
||||
toc_name_builder.Remove (num_pos, match.Groups["num"].Length);
|
||||
toc_name_builder.Insert (num_pos, index_num);
|
||||
|
||||
var toc_name = toc_name_builder.ToString();
|
||||
toc_name = VFS.CombinePath (VFS.GetDirectoryName (file.Name), toc_name);
|
||||
var toc = ReadToc (toc_name);
|
||||
if (null == toc)
|
||||
return null;
|
||||
|
||||
bool has_images = false;
|
||||
var dir = new List<Entry>();
|
||||
using (var toc_stream = new MemoryStream (toc))
|
||||
using (var index = new StreamReader (toc_stream))
|
||||
{
|
||||
string line;
|
||||
while ((line = index.ReadLine()) != null)
|
||||
{
|
||||
var fields = line.Split (',');
|
||||
if (fields.Length != 5)
|
||||
return null;
|
||||
var name = Path.ChangeExtension (fields[0], fields[4]);
|
||||
string type = "";
|
||||
if ("b" == fields[4])
|
||||
{
|
||||
type = "image";
|
||||
has_images = true;
|
||||
}
|
||||
else if ("k" == fields[4] || "j" == fields[4])
|
||||
type = "audio";
|
||||
var entry = new PackedEntry
|
||||
{
|
||||
Name = name,
|
||||
Type = type,
|
||||
Offset = UInt32.Parse (fields[3]),
|
||||
Size = UInt32.Parse (fields[2]),
|
||||
UnpackedSize = UInt32.Parse (fields[1]),
|
||||
};
|
||||
if (!entry.CheckPlacement (file.MaxOffset))
|
||||
return null;
|
||||
entry.IsPacked = entry.UnpackedSize != entry.Size;
|
||||
dir.Add (entry);
|
||||
}
|
||||
}
|
||||
if (0 == dir.Count)
|
||||
return null;
|
||||
if (!has_images)
|
||||
return new ArcFile (file, this, dir);
|
||||
var scheme = QueryScheme (file.Name);
|
||||
return new BellArchive (file, this, dir, scheme);
|
||||
}
|
||||
|
||||
protected override Stream DecryptImage (Stream input, uint entry_size, AImageScheme scheme)
|
||||
{
|
||||
int id = input.ReadByte();
|
||||
if (id == scheme.Value2)
|
||||
{
|
||||
using (var reader = new AImageReader (input, scheme))
|
||||
{
|
||||
reader.Unpack();
|
||||
return TgaStream.Create (reader.Info, reader.Data, scheme.Flipped);
|
||||
}
|
||||
}
|
||||
if (input.CanSeek)
|
||||
{
|
||||
input.Position = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
var header = new byte[1] { (byte)id };
|
||||
input = new PrefixStream (header, input);
|
||||
}
|
||||
return input;
|
||||
}
|
||||
|
||||
byte[] ReadToc (string toc_name)
|
||||
{
|
||||
using (var toc_view = VFS.OpenView (toc_name))
|
||||
{
|
||||
if (toc_view.MaxOffset <= 8)
|
||||
return null;
|
||||
int unpacked_size = DecodeDecimal (toc_view, 0);
|
||||
if (unpacked_size <= 4 || unpacked_size > 0x1000000)
|
||||
return null;
|
||||
int packed_size = DecodeDecimal (toc_view, 4);
|
||||
if (packed_size > toc_view.MaxOffset - 8)
|
||||
return null;
|
||||
using (var toc_s = toc_view.CreateStream (8, (uint)packed_size))
|
||||
using (var lzss = new LzssStream (toc_s))
|
||||
{
|
||||
var toc = new byte[unpacked_size];
|
||||
if (toc.Length != lzss.Read (toc, 0, toc.Length))
|
||||
return null;
|
||||
return toc;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int DecodeDecimal (ArcView file, long offset)
|
||||
{
|
||||
int v = 0;
|
||||
for (int rank = 1000; rank != 0; rank /= 10)
|
||||
{
|
||||
int b = file.View.ReadByte (offset++);
|
||||
if (b != 0xFF)
|
||||
v += (b ^ 0x7F) * rank;
|
||||
}
|
||||
return v;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1088,6 +1088,7 @@ Cartagra<br/>
|
||||
Kara no Shoujo 2<br/>
|
||||
</td></td>
|
||||
<tr><td>data.NN<br/>ArcNN.dat</td><td>-</td><td>No</td><td>Cyberworks</td><td>
|
||||
Abunai Kankei<br/>
|
||||
Aneboku ~Onee-chan wa Bijin 3 Shimai~<br/>
|
||||
Aniyome Kyouka-san to Sono Haha Chikako-san<br/>
|
||||
Aru Kazoku no Kankeizu<br/>
|
||||
@ -1117,6 +1118,7 @@ Shukubo no Uzuki ~Hitozuma Miboujin no Nareta Karada to Amai Toiki~<br/>
|
||||
Volley Coaching!<br/>
|
||||
Yumekoi Tensei<br/>
|
||||
Zoku Etsuraku no Tane<br/>
|
||||
Zoku Kairaku Izonshou ~Sono Go no Ryouko-san~<br/>
|
||||
</td></tr>
|
||||
<tr class="odd"><td>*.bin</td><td><tt>OZ</tt></td><td>No</td><td>Patisserie</td><td>
|
||||
Ore no Tamanokoshi ni Notte Kure<br/>
|
||||
@ -1215,6 +1217,7 @@ Tsumi no Hikari Rendezvous<br/>
|
||||
</td></tr>
|
||||
<tr class="odd"><td>arc.dat</td><td>-</td><td>No</td><td rowspan="2">AdvSys3</td><td rowspan="2">
|
||||
Okami Tsuma ~Ryokan Baito de no Himitsu~<br/>
|
||||
Tain Shoukougun<br/>
|
||||
</td></tr>
|
||||
<tr class="odd last"><td>*.gwd</td><td><tt>GWD</tt></td><td>No</td></tr>
|
||||
</table>
|
||||
|
Loading…
x
Reference in New Issue
Block a user