mirror of
https://github.com/crskycode/GARbro.git
synced 2024-11-27 07:34:00 +08:00
implemented Cyberworks archives.
This commit is contained in:
parent
03d62b91d9
commit
55ba371949
@ -79,8 +79,14 @@
|
||||
<Compile Include="Cmvs\ArcPBZ.cs" />
|
||||
<Compile Include="Cmvs\AudioMV.cs" />
|
||||
<Compile Include="Cmvs\ImagePSB.cs" />
|
||||
<Compile Include="Cyberworks\ArcDAT.cs" />
|
||||
<Compile Include="Cyberworks\AudioTINK.cs" />
|
||||
<Compile Include="Bruns\AudioUM3.cs" />
|
||||
<Compile Include="Bruns\ImageEENC.cs" />
|
||||
<Compile Include="Cyberworks\ImageTINK.cs" />
|
||||
<Compile Include="Cyberworks\WidgetBELL.xaml.cs">
|
||||
<DependentUpon>WidgetBELL.xaml</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="LiveMaker\ArcVF.cs" />
|
||||
<Compile Include="ArcZIP.cs" />
|
||||
<Compile Include="AudioVOC.cs" />
|
||||
@ -561,6 +567,10 @@
|
||||
<SubType>Designer</SubType>
|
||||
<Generator>MSBuild:Compile</Generator>
|
||||
</Page>
|
||||
<Page Include="Cyberworks\WidgetBELL.xaml">
|
||||
<SubType>Designer</SubType>
|
||||
<Generator>MSBuild:Compile</Generator>
|
||||
</Page>
|
||||
<Page Include="DxLib\WidgetSCR.xaml">
|
||||
<SubType>Designer</SubType>
|
||||
<Generator>MSBuild:Compile</Generator>
|
||||
|
303
ArcFormats/Cyberworks/ArcDAT.cs
Normal file
303
ArcFormats/Cyberworks/ArcDAT.cs
Normal file
@ -0,0 +1,303 @@
|
||||
//! \file ArcDAT.cs
|
||||
//! \date Thu Jun 16 13:48:04 2016
|
||||
//! \brief Tinker Bell resource archive.
|
||||
//
|
||||
// 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 System.Text;
|
||||
using System.Text.RegularExpressions;
|
||||
using GameRes.Compression;
|
||||
using GameRes.Formats.Properties;
|
||||
using GameRes.Formats.Strings;
|
||||
using GameRes.Utility;
|
||||
|
||||
namespace GameRes.Formats.Cyberworks
|
||||
{
|
||||
internal class BellArchive : ArcFile
|
||||
{
|
||||
public readonly AImageScheme Scheme;
|
||||
|
||||
public BellArchive (ArcView arc, ArchiveFormat impl, ICollection<Entry> dir, AImageScheme scheme)
|
||||
: base (arc, impl, dir)
|
||||
{
|
||||
Scheme = scheme;
|
||||
}
|
||||
}
|
||||
|
||||
[Export(typeof(ArchiveFormat))]
|
||||
public class DatOpener : ArchiveFormat
|
||||
{
|
||||
public override string Tag { get { return "ARC/Cyberworks"; } }
|
||||
public override string Description { get { return "Cyberworks/TinkerBell resource archive"; } }
|
||||
public override uint Signature { get { return 0; } }
|
||||
public override bool IsHierarchic { get { return false; } }
|
||||
public override bool CanCreate { get { return false; } }
|
||||
|
||||
public DatOpener ()
|
||||
{
|
||||
Extensions = new string[] { "dat", "04", "05", "06" };
|
||||
}
|
||||
|
||||
static Regex s_arcname_re = new Regex (@"^.+0(?<id>(?<num>\d)(?<idx>[a-z])?)(?:|\..*)$", RegexOptions.IgnoreCase);
|
||||
|
||||
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;
|
||||
char num = match.Groups["num"].Value[0];
|
||||
if (num < '4' || num > '6')
|
||||
return null;
|
||||
int arc_idx = 0;
|
||||
if (match.Groups["idx"].Success)
|
||||
arc_idx = char.ToUpper (match.Groups["idx"].Value[0]) - '@';
|
||||
|
||||
var toc_name_builder = new StringBuilder (arc_name);
|
||||
var num_pos = match.Groups["id"].Index;
|
||||
toc_name_builder.Remove (num_pos, match.Groups["id"].Length);
|
||||
toc_name_builder.Insert (num_pos, num-'3');
|
||||
var toc_name = toc_name_builder.ToString();
|
||||
|
||||
toc_name = VFS.CombinePath (VFS.GetDirectoryName (file.Name), toc_name);
|
||||
byte[] toc;
|
||||
using (var toc_view = VFS.OpenView (toc_name))
|
||||
{
|
||||
if (toc_view.MaxOffset <= 0x10)
|
||||
return null;
|
||||
uint unpacked_size = DecodeDecimal (toc_view, 0);
|
||||
if (unpacked_size <= 4 || unpacked_size > 0x1000000)
|
||||
return null;
|
||||
uint packed_size = DecodeDecimal (toc_view, 8);
|
||||
if (packed_size > toc_view.MaxOffset)
|
||||
return null;
|
||||
toc = new byte[unpacked_size];
|
||||
using (var toc_s = toc_view.CreateStream (0x10, packed_size))
|
||||
using (var lzss = new LzssStream (toc_s))
|
||||
{
|
||||
if (toc.Length != lzss.Read (toc, 0, toc.Length))
|
||||
return null;
|
||||
}
|
||||
}
|
||||
int entry_size = LittleEndian.ToInt32 (toc, 0) + 4;
|
||||
if (entry_size < 0x16)
|
||||
return null;
|
||||
int count = toc.Length / entry_size;
|
||||
if (!IsSaneCount (count))
|
||||
return null;
|
||||
var type = new char[2];
|
||||
var dir = new List<Entry> (count);
|
||||
bool has_images = false;
|
||||
using (var input = new MemoryStream (toc))
|
||||
using (var index = new BinaryReader (input))
|
||||
{
|
||||
while (input.Position < input.Length)
|
||||
{
|
||||
entry_size = index.ReadInt32();
|
||||
if (entry_size <= 0)
|
||||
return null;
|
||||
var next_pos = index.BaseStream.Position + entry_size;
|
||||
uint id = index.ReadUInt32();
|
||||
var entry = new PackedEntry { Name = id.ToString ("D6") };
|
||||
entry.UnpackedSize = index.ReadUInt32();
|
||||
entry.Size = index.ReadUInt32();
|
||||
entry.IsPacked = entry.UnpackedSize != entry.Size;
|
||||
entry.Offset = index.ReadUInt32();
|
||||
type[0] = (char)index.ReadByte();
|
||||
type[1] = (char)index.ReadByte();
|
||||
int entry_idx = 0;
|
||||
if (entry_size >= 0x17)
|
||||
{
|
||||
index.ReadInt32();
|
||||
entry_idx = index.ReadByte();
|
||||
}
|
||||
if (entry_idx == arc_idx)
|
||||
{
|
||||
if (type[0] > 0x20 && type[0] < 0x7F)
|
||||
{
|
||||
string ext;
|
||||
if (type[1] > 0x20 && type[1] < 0x7F)
|
||||
ext = new string (type);
|
||||
else
|
||||
ext = new string (type[0], 1);
|
||||
if ("b0" == ext || "n0" == ext || "o0" == ext)
|
||||
{
|
||||
entry.Type = "image";
|
||||
has_images = true;
|
||||
}
|
||||
else if ("j0" == ext || "k0" == ext || "u0" == ext)
|
||||
entry.Type = "audio";
|
||||
entry.Name = Path.ChangeExtension (entry.Name, ext);
|
||||
}
|
||||
dir.Add (entry);
|
||||
}
|
||||
index.BaseStream.Position = next_pos;
|
||||
}
|
||||
}
|
||||
if (0 == dir.Count)
|
||||
return null;
|
||||
if (!has_images)
|
||||
return new ArcFile (file, this, dir);
|
||||
var options = Query<BellOptions> (arcStrings.ArcEncryptedNotice);
|
||||
return new BellArchive (file, this, dir, options.Scheme);
|
||||
}
|
||||
|
||||
public override Stream OpenEntry (ArcFile arc, Entry entry)
|
||||
{
|
||||
uint entry_size = entry.Size;
|
||||
Stream input = arc.File.CreateStream (entry.Offset, entry_size);
|
||||
var pent = entry as PackedEntry;
|
||||
if (null != pent && pent.IsPacked)
|
||||
{
|
||||
input = new LzssStream (input);
|
||||
entry_size = pent.UnpackedSize;
|
||||
}
|
||||
var barc = arc as BellArchive;
|
||||
if (null == barc)
|
||||
return input;
|
||||
try
|
||||
{
|
||||
if ("image" == entry.Type && entry_size > 5)
|
||||
return DecryptImage (input, entry_size, barc.Scheme);
|
||||
return input;
|
||||
}
|
||||
catch
|
||||
{
|
||||
input.Dispose();
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
Stream DecryptImage (Stream input, uint entry_size, AImageScheme scheme)
|
||||
{
|
||||
byte[] header = null;
|
||||
byte type = (byte)input.ReadByte();
|
||||
if ('c' == type || 'b' == type)
|
||||
{
|
||||
header = new byte[5];
|
||||
header[0] = type;
|
||||
input.Read (header, 1, 4);
|
||||
uint img_size = BigEndian.ToUInt32 (header, 1);
|
||||
if (entry_size - 5 == img_size)
|
||||
{
|
||||
if (input.CanSeek)
|
||||
input = new StreamRegion (input, 5, img_size);
|
||||
return input;
|
||||
}
|
||||
}
|
||||
else if (scheme != null && 'a' == type && entry_size > 21)
|
||||
{
|
||||
int id = input.ReadByte();
|
||||
if (id == scheme.Value2)
|
||||
{
|
||||
using (var seekable = new SeekableStream (input))
|
||||
using (var reader = new AImageReader (seekable, scheme))
|
||||
{
|
||||
reader.Unpack();
|
||||
return TgaStream.Create (reader.Info, reader.Data, scheme.Flipped);
|
||||
}
|
||||
}
|
||||
header = new byte[2] { type, (byte)id };
|
||||
}
|
||||
if (input.CanSeek)
|
||||
{
|
||||
input.Position = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (null == header)
|
||||
header = new byte[1] { type };
|
||||
input = new PrefixStream (header, input);
|
||||
}
|
||||
return input;
|
||||
}
|
||||
|
||||
uint DecodeDecimal (ArcView file, long offset)
|
||||
{
|
||||
uint v = 0;
|
||||
uint rank = 1;
|
||||
for (int i = 7; i >= 0; --i, rank *= 10)
|
||||
{
|
||||
uint b = file.View.ReadByte (offset+i);
|
||||
if (b != 0xFF)
|
||||
v += (b ^ 0x7F) * rank;
|
||||
}
|
||||
return v;
|
||||
}
|
||||
|
||||
public override ResourceOptions GetDefaultOptions ()
|
||||
{
|
||||
return new BellOptions { Scheme = GetScheme (Settings.Default.BELLTitle) };
|
||||
}
|
||||
|
||||
public override object GetAccessWidget ()
|
||||
{
|
||||
return new GUI.WidgetBELL();
|
||||
}
|
||||
|
||||
public static AImageScheme GetScheme (string title)
|
||||
{
|
||||
AImageScheme scheme = null;
|
||||
if (string.IsNullOrEmpty (title) || !KnownSchemes.TryGetValue (title, out scheme))
|
||||
return null;
|
||||
return scheme;
|
||||
}
|
||||
|
||||
public static Dictionary<string, AImageScheme> KnownSchemes = new Dictionary<string, AImageScheme>();
|
||||
|
||||
public override ResourceScheme Scheme
|
||||
{
|
||||
get { return new SchemeMap { KnownSchemes = KnownSchemes }; }
|
||||
set { KnownSchemes = ((SchemeMap)value).KnownSchemes; }
|
||||
}
|
||||
}
|
||||
|
||||
[Serializable]
|
||||
public class AImageScheme
|
||||
{
|
||||
public byte Value1;
|
||||
public byte Value2;
|
||||
public byte Value3;
|
||||
public byte[] HeaderOrder;
|
||||
public bool Flipped;
|
||||
|
||||
public AImageScheme ()
|
||||
{
|
||||
Flipped = true;
|
||||
}
|
||||
}
|
||||
|
||||
[Serializable]
|
||||
public class SchemeMap : ResourceScheme
|
||||
{
|
||||
public Dictionary<string, AImageScheme> KnownSchemes;
|
||||
}
|
||||
|
||||
public class BellOptions : ResourceOptions
|
||||
{
|
||||
public AImageScheme Scheme;
|
||||
}
|
||||
}
|
99
ArcFormats/Cyberworks/AudioTINK.cs
Normal file
99
ArcFormats/Cyberworks/AudioTINK.cs
Normal file
@ -0,0 +1,99 @@
|
||||
//! \file AudioTINK.cs
|
||||
//! \date Fri Jun 17 14:13:39 2016
|
||||
//! \brief Cyberworks encrypted OGG audio.
|
||||
//
|
||||
// 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 System.Text;
|
||||
using GameRes.Utility;
|
||||
|
||||
namespace GameRes.Formats.Cyberworks
|
||||
{
|
||||
[Serializable]
|
||||
public class TinkAudioScheme : ResourceScheme
|
||||
{
|
||||
public Dictionary<uint, byte[]> KnownKeys;
|
||||
}
|
||||
|
||||
[Export(typeof(AudioFormat))]
|
||||
public class TinkAudio : AudioFormat
|
||||
{
|
||||
public override string Tag { get { return "OGG/TINK"; } }
|
||||
public override string Description { get { return "Cyberworks encrypted OGG audio"; } }
|
||||
public override uint Signature { get { return 0x6B6E6954; } }
|
||||
|
||||
public TinkAudio ()
|
||||
{
|
||||
Signatures = new uint[] { 0x6B6E6954, 0x676E6F53, 0 }; // 'Tink', 'Song'
|
||||
Extensions = new string[] { "j0", "k0", "u0" };
|
||||
}
|
||||
|
||||
static Dictionary<uint, byte[]> KnownKeys = new Dictionary<uint, byte[]>();
|
||||
|
||||
public override ResourceScheme Scheme
|
||||
{
|
||||
get { return new TinkAudioScheme { KnownKeys = KnownKeys }; }
|
||||
set { KnownKeys = ((TinkAudioScheme)value).KnownKeys; }
|
||||
}
|
||||
|
||||
public override SoundInput TryOpen (Stream file)
|
||||
{
|
||||
var header = new byte[Math.Min (0xE1F, file.Length)];
|
||||
if (0x10 != file.Read (header, 0, 0x10))
|
||||
return null;
|
||||
var signature = LittleEndian.ToUInt32 (header, 0);
|
||||
byte[] key;
|
||||
if (!KnownKeys.TryGetValue (signature, out key))
|
||||
{
|
||||
signature = LittleEndian.ToUInt32 (header, 0xC);
|
||||
if (!KnownKeys.TryGetValue (signature, out key))
|
||||
return null;
|
||||
file.Read (header, 4, 0xC);
|
||||
}
|
||||
header[0] = (byte)'O';
|
||||
header[1] = (byte)'g';
|
||||
header[2] = (byte)'g';
|
||||
header[3] = (byte)'S';
|
||||
file.Read (header, 0x10, header.Length-0x10);
|
||||
int k = 0;
|
||||
for (int i = 4; i < header.Length; ++i)
|
||||
{
|
||||
header[i] ^= key[k++];
|
||||
if (k >= key.Length)
|
||||
k = 1;
|
||||
}
|
||||
Stream input;
|
||||
if (header.Length >= file.Length)
|
||||
input = new MemoryStream (header);
|
||||
else
|
||||
input = new PrefixStream (header, new StreamRegion (file, file.Position));
|
||||
var sound = OggAudio.Instance.TryOpen (input);
|
||||
if (sound != null && header.Length >= file.Length)
|
||||
file.Dispose();
|
||||
return sound;
|
||||
}
|
||||
}
|
||||
}
|
265
ArcFormats/Cyberworks/ImageTINK.cs
Normal file
265
ArcFormats/Cyberworks/ImageTINK.cs
Normal file
@ -0,0 +1,265 @@
|
||||
//! \file ImageTINK.cs
|
||||
//! \date Fri Jun 17 18:49:04 2016
|
||||
//! \brief Tinker Bell encrypted image file.
|
||||
//
|
||||
// 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.ComponentModel.Composition;
|
||||
using System.IO;
|
||||
|
||||
namespace GameRes.Formats.Cyberworks
|
||||
{
|
||||
public enum AImageHeader
|
||||
{
|
||||
Flags = 0,
|
||||
Field1 = 1,
|
||||
Field2 = 2,
|
||||
Height = 3,
|
||||
Width = 4,
|
||||
UnpackedSize = 5,
|
||||
AlphaSize = 6,
|
||||
BitsSize = 7,
|
||||
}
|
||||
|
||||
internal sealed class AImageReader : IDisposable
|
||||
{
|
||||
public readonly ImageMetaData Info = new ImageMetaData();
|
||||
|
||||
BinaryReader m_input;
|
||||
byte[] m_output;
|
||||
AImageScheme m_scheme;
|
||||
|
||||
public byte[] Data { get { return m_output; } }
|
||||
|
||||
public AImageReader (Stream input, AImageScheme scheme)
|
||||
{
|
||||
m_input = new ArcView.Reader (input);
|
||||
m_scheme = scheme;
|
||||
}
|
||||
|
||||
public void Unpack ()
|
||||
{
|
||||
var header = new int[m_scheme.HeaderOrder.Length];
|
||||
for (int i = 0; i < m_scheme.HeaderOrder.Length; ++i)
|
||||
{
|
||||
int b = GetInt();
|
||||
header[m_scheme.HeaderOrder[i]] = b;
|
||||
}
|
||||
Info.Width = (uint)header[4];
|
||||
Info.Height = (uint)header[3];
|
||||
if (0 == Info.Width || Info.Width >= 0x8000 || 0 == Info.Height || Info.Height >= 0x8000)
|
||||
throw new InvalidFormatException();
|
||||
int unpacked_size = header[5];
|
||||
if (unpacked_size <= 0)
|
||||
throw new InvalidFormatException();
|
||||
int flags = header[0];
|
||||
int bits_size = header[7];
|
||||
int data_offset = bits_size * 2;
|
||||
if (0 == flags)
|
||||
CopyV0 (unpacked_size);
|
||||
else if (2 == (flags & 6))
|
||||
UnpackV2 (bits_size, data_offset);
|
||||
else if (6 == (flags & 6))
|
||||
{
|
||||
if (0 == bits_size)
|
||||
CopyV6 (unpacked_size, header[6]);
|
||||
else
|
||||
UnpackV6 (bits_size, data_offset, data_offset + header[6]);
|
||||
}
|
||||
else
|
||||
throw new InvalidFormatException();
|
||||
}
|
||||
|
||||
void CopyV0 (int data_size)
|
||||
{
|
||||
int plane_size = (int)Info.Width * (int)Info.Height;
|
||||
if (plane_size == data_size)
|
||||
{
|
||||
Info.BPP = 8;
|
||||
m_output = m_input.ReadBytes (data_size);
|
||||
}
|
||||
else if (3 * plane_size == data_size)
|
||||
{
|
||||
Info.BPP = 24;
|
||||
m_output = m_input.ReadBytes (data_size);
|
||||
}
|
||||
else if (4 * plane_size == data_size)
|
||||
{
|
||||
Info.BPP = 32;
|
||||
m_output = m_input.ReadBytes (data_size);
|
||||
}
|
||||
else
|
||||
{
|
||||
Info.BPP = 24;
|
||||
int dst_stride = (int)Info.Width * 3;
|
||||
int src_stride = (dst_stride + 3) & ~3;
|
||||
if (src_stride * (int)Info.Height != data_size)
|
||||
throw new InvalidFormatException();
|
||||
m_output = new byte[dst_stride * (int)Info.Height];
|
||||
int dst = 0;
|
||||
for (uint y = 0; y < Info.Height; ++y)
|
||||
{
|
||||
m_input.Read (m_output, dst, dst_stride);
|
||||
dst += dst_stride;
|
||||
m_input.BaseStream.Seek (src_stride-dst_stride, SeekOrigin.Current);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void UnpackV2 (int offset1, int rgb_offset)
|
||||
{
|
||||
Info.BPP = 24;
|
||||
var rgb_map = m_input.ReadBytes (offset1);
|
||||
var alpha_map = m_input.ReadBytes (rgb_offset-offset1);
|
||||
int plane_size = (int)Info.Width * (int)Info.Height;
|
||||
m_output = new byte[plane_size * 3];
|
||||
|
||||
int bit = 1;
|
||||
int bit_src = 0;
|
||||
int dst = 0;
|
||||
for (int i = 0; i < plane_size; ++i)
|
||||
{
|
||||
if ((bit & alpha_map[bit_src]) == 0 && (bit & rgb_map[bit_src]) != 0)
|
||||
{
|
||||
m_input.Read (m_output, dst, 3);
|
||||
}
|
||||
dst += 3;
|
||||
if (0x80 == bit)
|
||||
{
|
||||
++bit_src;
|
||||
bit = 1;
|
||||
}
|
||||
else
|
||||
bit <<= 1;
|
||||
}
|
||||
}
|
||||
|
||||
void CopyV6 (int alpha_size, int rgb_size)
|
||||
{
|
||||
Info.BPP = 32;
|
||||
int plane_size = (int)Info.Width * (int)Info.Height;
|
||||
m_output = new byte[plane_size * 4];
|
||||
int stride = ((int)Info.Width * 3 + 3) & ~3;
|
||||
var line = new byte[stride];
|
||||
int dst = 3;
|
||||
for (uint y = 0; y < Info.Height; ++y)
|
||||
{
|
||||
m_input.Read (line, 0, stride);
|
||||
int src = 0;
|
||||
for (uint x = 0; x < Info.Width; ++x)
|
||||
{
|
||||
m_output[dst] = line[src];
|
||||
dst += 4;
|
||||
src += 3;
|
||||
}
|
||||
}
|
||||
dst = 0;
|
||||
for (uint y = 0; y < Info.Height; ++y)
|
||||
{
|
||||
m_input.Read (line, 0, stride);
|
||||
int src = 0;
|
||||
for (uint x = 0; x < Info.Width; ++x)
|
||||
{
|
||||
m_output[dst ] = line[src++];
|
||||
m_output[dst+1] = line[src++];
|
||||
m_output[dst+2] = line[src++];
|
||||
dst += 4;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void UnpackV6 (int offset1, int alpha_offset, int rgb_offset)
|
||||
{
|
||||
Info.BPP = 32;
|
||||
var rgb_map = m_input.ReadBytes (offset1);
|
||||
var alpha_map = m_input.ReadBytes (alpha_offset - offset1);
|
||||
var alpha = m_input.ReadBytes (rgb_offset - alpha_offset);
|
||||
int plane_size = (int)Info.Width * (int)Info.Height;
|
||||
m_output = new byte[plane_size * 4];
|
||||
|
||||
int bit = 1;
|
||||
int bit_src = 0;
|
||||
int alpha_src = 0;
|
||||
int dst = 0;
|
||||
for (int i = 0; i < plane_size; ++i)
|
||||
{
|
||||
bool has_alpha = (bit & alpha_map[bit_src]) != 0;
|
||||
if (has_alpha || (bit & rgb_map[bit_src]) != 0)
|
||||
{
|
||||
m_input.Read (m_output, dst, 3);
|
||||
if (has_alpha)
|
||||
{
|
||||
m_output[dst+3] = alpha[alpha_src];
|
||||
alpha_src += 3;
|
||||
}
|
||||
else
|
||||
m_output[dst+3] = 0xFF;
|
||||
}
|
||||
dst += 4;
|
||||
if (0x80 == bit)
|
||||
{
|
||||
++bit_src;
|
||||
bit = 1;
|
||||
}
|
||||
else
|
||||
bit <<= 1;
|
||||
}
|
||||
}
|
||||
|
||||
int GetInt ()
|
||||
{
|
||||
byte a = m_input.ReadByte();
|
||||
if (a == m_scheme.Value3)
|
||||
a = 0;
|
||||
int d = 0;
|
||||
int c = 0;
|
||||
for (;;)
|
||||
{
|
||||
byte a1 = m_input.ReadByte();
|
||||
if (a1 == m_scheme.Value2)
|
||||
break;
|
||||
if (a1 != m_scheme.Value1)
|
||||
{
|
||||
c = (a1 == m_scheme.Value3) ? 0 : a1;
|
||||
}
|
||||
else
|
||||
{
|
||||
++d;
|
||||
}
|
||||
}
|
||||
return a + (c + d * m_scheme.Value1) * m_scheme.Value1;
|
||||
}
|
||||
|
||||
#region IDisposable Members
|
||||
bool _disposed = false;
|
||||
public void Dispose ()
|
||||
{
|
||||
if (!_disposed)
|
||||
{
|
||||
m_input.Dispose();
|
||||
_disposed = true;
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
}
|
7
ArcFormats/Cyberworks/WidgetBELL.xaml
Normal file
7
ArcFormats/Cyberworks/WidgetBELL.xaml
Normal file
@ -0,0 +1,7 @@
|
||||
<StackPanel x:Class="GameRes.Formats.GUI.WidgetBELL"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:p="clr-namespace:GameRes.Formats.Properties">
|
||||
<ComboBox Name="Title" Width="250" ItemsSource="{Binding}"
|
||||
SelectedValue="{Binding Source={x:Static p:Settings.Default}, Path=BELLTitle, Mode=TwoWay}"/>
|
||||
</StackPanel>
|
22
ArcFormats/Cyberworks/WidgetBELL.xaml.cs
Normal file
22
ArcFormats/Cyberworks/WidgetBELL.xaml.cs
Normal file
@ -0,0 +1,22 @@
|
||||
using System.Linq;
|
||||
using System.Windows.Controls;
|
||||
using GameRes.Formats.Cyberworks;
|
||||
using GameRes.Formats.Strings;
|
||||
|
||||
namespace GameRes.Formats.GUI
|
||||
{
|
||||
/// <summary>
|
||||
/// Interaction logic for WidgetBELL.xaml
|
||||
/// </summary>
|
||||
public partial class WidgetBELL : StackPanel
|
||||
{
|
||||
public WidgetBELL()
|
||||
{
|
||||
InitializeComponent();
|
||||
var keys = new string[] { arcStrings.ArcIgnoreEncryption };
|
||||
Title.ItemsSource = keys.Concat (DatOpener.KnownSchemes.Keys.OrderBy (x => x));
|
||||
if (-1 == Title.SelectedIndex)
|
||||
Title.SelectedIndex = 0;
|
||||
}
|
||||
}
|
||||
}
|
12
ArcFormats/Properties/Settings.Designer.cs
generated
12
ArcFormats/Properties/Settings.Designer.cs
generated
@ -573,5 +573,17 @@ namespace GameRes.Formats.Properties {
|
||||
this["MGPKTitle"] = value;
|
||||
}
|
||||
}
|
||||
|
||||
[global::System.Configuration.UserScopedSettingAttribute()]
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
|
||||
[global::System.Configuration.DefaultSettingValueAttribute("")]
|
||||
public string BELLTitle {
|
||||
get {
|
||||
return ((string)(this["BELLTitle"]));
|
||||
}
|
||||
set {
|
||||
this["BELLTitle"] = value;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -140,5 +140,8 @@
|
||||
<Setting Name="MGPKTitle" Type="System.String" Scope="User">
|
||||
<Value Profile="(Default)" />
|
||||
</Setting>
|
||||
<Setting Name="BELLTitle" Type="System.String" Scope="User">
|
||||
<Value Profile="(Default)" />
|
||||
</Setting>
|
||||
</Settings>
|
||||
</SettingsFile>
|
@ -142,6 +142,9 @@
|
||||
<setting name="MGPKTitle" serializeAs="String">
|
||||
<value />
|
||||
</setting>
|
||||
<setting name="BELLTitle" serializeAs="String">
|
||||
<value />
|
||||
</setting>
|
||||
</GameRes.Formats.Properties.Settings>
|
||||
</userSettings>
|
||||
<startup><supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5"/></startup></configuration>
|
||||
|
@ -556,6 +556,7 @@ Sora no Iro, Mizu no Iro<br/>
|
||||
Thunder Claps!<br/>
|
||||
Tokumei Kyoushi Hitomi<br/>
|
||||
Toshiue Lesson ~Mama to Oba-san to Sensei to~<br/>
|
||||
Tutorial Summer<br/>
|
||||
</td></tr>
|
||||
<tr><td>*.iks</td><td><tt>NPSR</tt></td><td>No</td><td>X[iks]</td><td>Shikkan ~Hazukashimerareta Karada, Oreta Kokoro~</td></tr>
|
||||
<tr class="odd"><td>*.wbp</td><td><tt>ARCFORM3 WBUG</tt></td><td>No</td><td rowspan="4">Wild Bug</td><td rowspan="4">
|
||||
@ -932,6 +933,12 @@ Natsunone -Ring-<br/>
|
||||
Cartagra<br/>
|
||||
Kara no Shoujo 2<br/>
|
||||
</td></td>
|
||||
<tr><td>data.NN<br/>ArcNN.dat</td><td>-</td><td>No</td><td>TinkerBell</td><td>
|
||||
Hime Kami 1/2<br/>
|
||||
Oshioki ~Gakuen Reijou Kousei Keikaku~<br/>
|
||||
Ore Maou! ~Kudake Chitta Tamashii<br/>
|
||||
Zoku Etsuraku no Tane<br/>
|
||||
</td></tr>
|
||||
</table>
|
||||
<p><a name="note-1" class="footnote">1</a> Non-encrypted only</p>
|
||||
</body>
|
||||
|
Loading…
Reference in New Issue
Block a user