mirror of
https://github.com/crskycode/GARbro.git
synced 2025-01-11 12:39:16 +08:00
implemented ADVEngine 'arc' archives and GPS images.
This commit is contained in:
parent
77f5693016
commit
4ee3511075
116
ArcFormats/Abel/ArcARC.cs
Normal file
116
ArcFormats/Abel/ArcARC.cs
Normal file
@ -0,0 +1,116 @@
|
||||
//! \file ArcARC.cs
|
||||
//! \date Sat Feb 20 13:02:18 2016
|
||||
//! \brief Archive format used by Abel subsidiaries.
|
||||
//
|
||||
// Copyright (C) 2016 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;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel.Composition;
|
||||
using System.IO;
|
||||
using GameRes.Compression;
|
||||
using GameRes.Utility;
|
||||
|
||||
namespace GameRes.Formats.Abel
|
||||
{
|
||||
[Export(typeof(ArchiveFormat))]
|
||||
public class ArcOpener : ArchiveFormat
|
||||
{
|
||||
public override string Tag { get { return "ARC/ADVENGINE"; } }
|
||||
public override string Description { get { return "ADVEngine resource archive"; } }
|
||||
public override uint Signature { get { return 0x00637261; } } // 'arc'
|
||||
public override bool IsHierarchic { get { return false; } }
|
||||
public override bool CanCreate { get { return false; } }
|
||||
|
||||
public ArcOpener ()
|
||||
{
|
||||
Extensions = new string[] { "" };
|
||||
}
|
||||
|
||||
const int IndexEntrySize = 0x26;
|
||||
|
||||
public override ArcFile TryOpen (ArcView file)
|
||||
{
|
||||
int count = file.View.ReadInt32 (8);
|
||||
if (!IsSaneCount (count))
|
||||
return null;
|
||||
uint base_offset = file.View.ReadUInt32 (0xC);
|
||||
if (base_offset <= 0x18 || base_offset >= file.MaxOffset)
|
||||
return null;
|
||||
uint packed_size = file.View.ReadUInt32 (0x10);
|
||||
int index_size = file.View.ReadInt32 (0x14);
|
||||
if (packed_size > file.MaxOffset || index_size / IndexEntrySize != count)
|
||||
return null;
|
||||
var name_buffer = new byte[30];
|
||||
using (var packed = file.CreateStream (0x18, packed_size))
|
||||
using (var lzss = new LzssStream (packed))
|
||||
using (var index = new ArcView.Reader (lzss))
|
||||
{
|
||||
var dir = new List<Entry> (count);
|
||||
for (int i = 0; i < count; ++i)
|
||||
{
|
||||
if (name_buffer.Length != index.Read (name_buffer, 0, name_buffer.Length))
|
||||
return null;
|
||||
var name = Binary.GetCString (name_buffer, 0, name_buffer.Length);
|
||||
var entry = FormatCatalog.Instance.Create<Entry> (name);
|
||||
if (name.EndsWith (".acd", StringComparison.InvariantCultureIgnoreCase))
|
||||
entry.Type = "script";
|
||||
entry.Offset = index.ReadUInt32() + base_offset;
|
||||
entry.Size = index.ReadUInt32();
|
||||
if (!entry.CheckPlacement (file.MaxOffset))
|
||||
return null;
|
||||
dir.Add (entry);
|
||||
}
|
||||
return new ArcFile (file, this, dir);
|
||||
}
|
||||
}
|
||||
|
||||
public override Stream OpenEntry (ArcFile arc, Entry entry)
|
||||
{
|
||||
if (entry.Size > 12 && entry.Name.EndsWith (".cmp", StringComparison.InvariantCultureIgnoreCase)
|
||||
&& arc.File.View.AsciiEqual (entry.Offset, "CMP\0"))
|
||||
return OpenCmpEntry (arc, entry);
|
||||
if (entry.Size > 8 && entry.Name.EndsWith (".acd", StringComparison.InvariantCultureIgnoreCase)
|
||||
&& arc.File.View.AsciiEqual (entry.Offset, "ACD\0"))
|
||||
return OpenAcdEntry (arc, entry);
|
||||
return base.OpenEntry (arc, entry);
|
||||
}
|
||||
|
||||
Stream OpenAcdEntry (ArcFile arc, Entry entry)
|
||||
{
|
||||
var data = arc.File.View.ReadBytes (entry.Offset, entry.Size);
|
||||
for (int i = 8; i < data.Length; ++i)
|
||||
{
|
||||
data[i] = (byte)(0xFF - data[i]);
|
||||
}
|
||||
return new MemoryStream (data);
|
||||
}
|
||||
|
||||
Stream OpenCmpEntry (ArcFile arc, Entry entry)
|
||||
{
|
||||
uint offset = arc.File.View.ReadUInt32 (entry.Offset+8);
|
||||
if (offset >= entry.Size)
|
||||
return base.OpenEntry (arc, entry);
|
||||
return arc.File.CreateStream (entry.Offset+offset, entry.Size-offset);
|
||||
}
|
||||
}
|
||||
}
|
137
ArcFormats/Abel/ImageGPS.cs
Normal file
137
ArcFormats/Abel/ImageGPS.cs
Normal file
@ -0,0 +1,137 @@
|
||||
//! \file ImageGPS.cs
|
||||
//! \date Sat Feb 20 14:13:10 2016
|
||||
//! \brief ADVEngine compressed bitmap.
|
||||
//
|
||||
// Copyright (C) 2016 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;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel.Composition;
|
||||
using System.IO;
|
||||
using GameRes.Compression;
|
||||
using GameRes.Utility;
|
||||
|
||||
namespace GameRes.Formats.Abel
|
||||
{
|
||||
internal class GpsMetaData : ImageMetaData
|
||||
{
|
||||
public byte Compression;
|
||||
public int PackedSize;
|
||||
public int UnpackedSize;
|
||||
}
|
||||
|
||||
[Export(typeof(ImageFormat))]
|
||||
public class GpsFormat : BmpFormat
|
||||
{
|
||||
public override string Tag { get { return "GPS"; } }
|
||||
public override string Description { get { return "ADVEngine compressed bitmap"; } }
|
||||
public override uint Signature { get { return 0x535047; } } // 'GPS'
|
||||
|
||||
public GpsFormat ()
|
||||
{
|
||||
Extensions = new string[] { "gps", "cmp" };
|
||||
}
|
||||
|
||||
public override ImageMetaData ReadMetaData (Stream stream)
|
||||
{
|
||||
var header = new byte[0x29];
|
||||
if (header.Length != stream.Read (header, 0, header.Length))
|
||||
return null;
|
||||
var gps = new GpsMetaData
|
||||
{
|
||||
Width = LittleEndian.ToUInt32 (header, 0x19),
|
||||
Height = LittleEndian.ToUInt32 (header, 0x1D),
|
||||
Compression = header[0x10],
|
||||
UnpackedSize = LittleEndian.ToInt32 (header, 0x11),
|
||||
PackedSize = LittleEndian.ToInt32 (header, 0x15),
|
||||
};
|
||||
// read BMP header
|
||||
using (var input = OpenGpsStream (stream, gps.Compression, 0x54))
|
||||
{
|
||||
var bmp_info = base.ReadMetaData (input);
|
||||
if (null == bmp_info)
|
||||
return null;
|
||||
gps.BPP = bmp_info.BPP;
|
||||
return gps;
|
||||
}
|
||||
}
|
||||
|
||||
public override ImageData Read (Stream stream, ImageMetaData info)
|
||||
{
|
||||
var gps = (GpsMetaData)info;
|
||||
stream.Position = 0x29;
|
||||
using (var input = OpenGpsStream (stream, gps.Compression, gps.UnpackedSize))
|
||||
return base.Read (input, info);
|
||||
}
|
||||
|
||||
public override void Write (Stream file, ImageData image)
|
||||
{
|
||||
throw new System.NotImplementedException ("GpsFormat.Write not implemented");
|
||||
}
|
||||
|
||||
Stream OpenGpsStream (Stream input, byte compression, int unpacked_size)
|
||||
{
|
||||
if (0 == compression)
|
||||
return new StreamRegion (input, 0x29, true);
|
||||
else if (1 == compression)
|
||||
return OpenRLEStream (input, unpacked_size);
|
||||
else if (2 == compression)
|
||||
return new LzssStream (input, LzssMode.Decompress, true);
|
||||
else if (3 == compression)
|
||||
{
|
||||
using (var lzss = new LzssStream (input, LzssMode.Decompress, true))
|
||||
return OpenRLEStream (lzss, unpacked_size);
|
||||
}
|
||||
else
|
||||
throw new InvalidFormatException();
|
||||
}
|
||||
|
||||
Stream OpenRLEStream (Stream input, int output_size)
|
||||
{
|
||||
var output = new byte[output_size];
|
||||
UnpackRLE (input, output);
|
||||
return new MemoryStream (output);
|
||||
}
|
||||
|
||||
void UnpackRLE (Stream input, byte[] output)
|
||||
{
|
||||
int dst = 0;
|
||||
while (dst < output.Length)
|
||||
{
|
||||
int count = Math.Min (3, output.Length-dst);
|
||||
count = input.Read (output, dst, count);
|
||||
if (count < 3)
|
||||
break;
|
||||
count = input.ReadByte();
|
||||
if (-1 == count)
|
||||
break;
|
||||
dst += 3;
|
||||
if (count > 1)
|
||||
{
|
||||
count = Math.Min ((count-1) * 3, output.Length-dst);
|
||||
Binary.CopyOverlapped (output, dst-3, dst, count);
|
||||
dst += count;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -62,8 +62,11 @@
|
||||
<Reference Include="WindowsBase" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="Abel\ArcARC.cs" />
|
||||
<Compile Include="Abel\ImageGPS.cs" />
|
||||
<Compile Include="Actgs\ArcDAT.cs" />
|
||||
<Compile Include="ArcCG.cs" />
|
||||
<Compile Include="ImageLZ.cs" />
|
||||
<Compile Include="NitroPlus\ArcNPK.cs" />
|
||||
<Compile Include="Softpal\ArcPAC.cs" />
|
||||
<Compile Include="Softpal\AudioBGM.cs" />
|
||||
@ -251,6 +254,7 @@
|
||||
<Compile Include="ShiinaRio\ArcS25.cs" />
|
||||
<Compile Include="ArcSAF.cs" />
|
||||
<Compile Include="BlackCyc\ArcVPK.cs" />
|
||||
<Compile Include="Will\ArcPNA.cs" />
|
||||
<Compile Include="Will\ArcPulltop.cs" />
|
||||
<Compile Include="Xuse\ArcBIN.cs" />
|
||||
<Compile Include="Xuse\ArcGD.cs" />
|
||||
|
@ -81,6 +81,7 @@ Okaa-san ga Ippai!<br/>
|
||||
</td></tr>
|
||||
<tr class="odd"><td>*.pak</td><td><tt>HyPack</tt></td><td>Yes</td><td>Kogado</td><td>Symphonic Rain</td></tr>
|
||||
<tr><td>*+*.lst</td><td>-</td><td>No</td><td rowspan="2">Nexton LikeC</td><td rowspan="2">
|
||||
Injoku Shinryuu Club<br/>
|
||||
Moon.<br/>
|
||||
Ryoujoku Famiresu Choukyou Menu<br/>
|
||||
Ryoujoku Idol Mesu Dorei<br/>
|
||||
@ -148,9 +149,13 @@ Kyrie ~Blood Royal 3~<br/>
|
||||
Shiosai no Himei<br/>
|
||||
</td></tr>
|
||||
<tr class="odd"><td>*.gcp</td><td><tt>CMP1</tt></td><td>No</td></tr>
|
||||
<tr><td>*.pd</td><td><tt>PackOnly</tt><br/><tt>PackPlus</tt><br/><tt>FlyingShinePDFile</tt></td><td>Yes</td><td>Flying Shine</td><td>Cross†Channel</td></tr>
|
||||
<tr><td>*.pd</td><td><tt>PackOnly</tt><br/><tt>PackPlus</tt><br/><tt>FlyingShinePDFile</tt></td><td>Yes</td><td>Flying Shine</td><td>
|
||||
Akarui Mirai ~Wet And Messy 2nd time~<br/>
|
||||
Cross†Channel<br/>
|
||||
Crime Rhyme<br/>
|
||||
</td></tr>
|
||||
<tr class="odd"><td>*.rpa</td><td><tt>RPA-3.0</tt></td><td>Yes</td><td>Ren'Py</td><td>Katawa Shoujo</td></tr>
|
||||
<tr><td>*.arc</td><td>-</td><td>Yes</td><td rowspan="2">Will</td><td rowspan="2">
|
||||
<tr><td>*.arc</td><td>-</td><td>Yes</td><td rowspan="3">Will</td><td rowspan="3">
|
||||
Cynthia ~Sincerely to You~<br/>
|
||||
Folklore Jam<br/>
|
||||
I/O<br/>
|
||||
@ -163,6 +168,7 @@ Tsuma Youji 2<br/>
|
||||
Yume Miru Kusuri<br/>
|
||||
</td></tr>
|
||||
<tr><td>*.wip<br/>*.msk<br/>*.mos</td><td><tt>WIPF</tt></td><td>No</td></tr>
|
||||
<tr><td>*.pna</td><td><tt>PNAP</tt></td><td>No</td></tr>
|
||||
<tr class="odd"><td>*.xfl</td><td><tt>LB</tt></td><td>Yes</td><td rowspan="3">Liar-soft</td><td rowspan="3">
|
||||
Angel Bullet<br/>
|
||||
Fairytale Requiem<br/>
|
||||
@ -176,6 +182,7 @@ Altered Pink ~Tokumu Sentai Duel Ranger~<br/>
|
||||
Aozora Gakko no Sensei-kun<br/>
|
||||
Cafe Sourire<br/>
|
||||
Coμ<br/>
|
||||
Crime Rhyme series<br/>
|
||||
Damegane<br/>
|
||||
Distance<br/>
|
||||
Fate/stay night<br/>
|
||||
@ -186,6 +193,7 @@ Hanafubuki ~Sennen no Koi o Shimashita~<br/>
|
||||
Haruiro ☆ Communication ♪<br/>
|
||||
Hime to Majin to Koi Suru Tamashii<br/>
|
||||
Imouto Style<br/>
|
||||
Inaho no Mirai</br>
|
||||
Mayoeru Futari to Sekai no Subete<br/>
|
||||
Natsupochi<br/>
|
||||
Nidaime wa ☆ Mahou Shoujo<br/>
|
||||
@ -337,6 +345,7 @@ Trouble @ Spiral!<br/>
|
||||
<tr class="odd"><td>*.epa</td><td><tt>EP</tt></td><td>No</td></tr>
|
||||
<tr><td>*.arc</td><td><tt>MAI</tt></td><td>No</td><td rowspan="2">Matsuri Kikaku</td><td rowspan="2">
|
||||
Chikan Sharyou Nigousha<br/>
|
||||
Hime Musha<br/>
|
||||
Warusa<br/>
|
||||
</td></tr>
|
||||
<tr><td>*.ami<br/>*.cmp<br/></td><td><tt>AM</tt><br/><tt>CM</tt></td><td>No</td></tr>
|
||||
@ -684,6 +693,10 @@ Unity Marriage ~Futari no Hanayome~<br/>
|
||||
<tr><td>*.npk</td><td><tt>NPK2</tt></td><td>No</td><td>Nitro+</td><td>
|
||||
Tokyo Necro<br/>
|
||||
</td></tr>
|
||||
<tr class="odd"><td>*</td><td><tt>arc</tt></td><td>No</td><td rowspan="2">ADVEngine</td><td rowspan="2">
|
||||
Thanatos no Koi ~In Ane Otouto Soukan~<br/>
|
||||
</td></tr>
|
||||
<tr class="odd"><td>*.gps</td><td><tt>GPS</tt></td><td>No</td></tr>
|
||||
</table>
|
||||
<p><a name="note-1" class="footnote">1</a> Non-encrypted only</p>
|
||||
</body>
|
||||
|
Loading…
x
Reference in New Issue
Block a user