(name);
+ entry.Offset = inx.View.ReadUInt32 (inx_offset+0x40);
+ entry.Size = inx.View.ReadUInt32 (inx_offset+0x44);
+ if (!entry.CheckPlacement (file.MaxOffset))
+ return null;
+ dir.Add (entry);
+ inx_offset += 0x48;
+ }
+ return new ArcFile (file, this, dir);
+ }
+ }
+ }
+}
diff --git a/ArcFormats/BlueGale/ImageZBM.cs b/ArcFormats/BlueGale/ImageZBM.cs
new file mode 100644
index 00000000..e936f297
--- /dev/null
+++ b/ArcFormats/BlueGale/ImageZBM.cs
@@ -0,0 +1,140 @@
+//! \file ImageZBM.cs
+//! \date Sun Jan 10 00:41:42 2016
+//! \brief BlueGale image format.
+//
+// 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 GameRes.Utility;
+using System;
+using System.ComponentModel.Composition;
+using System.IO;
+
+namespace GameRes.Formats.BlueGale
+{
+ internal class ZbmMetaData : ImageMetaData
+ {
+ public int UnpackedSize;
+ public int DataOffset;
+ }
+
+ [Export(typeof(ImageFormat))]
+ public class ZbmFormat : ImageFormat
+ {
+ public override string Tag { get { return "ZBM/BLUEGALE"; } }
+ public override string Description { get { return "BlueGale compressed image format"; } }
+ public override uint Signature { get { return 0x5F706D61; } } // 'amp_'
+
+ public ZbmFormat ()
+ {
+ Extensions = new string[] { "zbm" };
+ }
+
+ public override ImageMetaData ReadMetaData (Stream stream)
+ {
+ stream.Position = 4;
+ using (var reader = new ArcView.Reader (stream))
+ {
+ int version = reader.ReadInt16();
+ if (version != 1)
+ return null;
+ int unpacked_size = reader.ReadInt32();
+ int data_offset = reader.ReadInt32();
+ if (unpacked_size < 0x36 || data_offset < stream.Position)
+ return null;
+ var header = new byte[0x20];
+ stream.Position = data_offset;
+ Unpack (stream, header);
+ if ('B' != header[0] || 'M' != header[1])
+ return null;
+ return new ZbmMetaData
+ {
+ Width = LittleEndian.ToUInt32 (header, 0x12),
+ Height = LittleEndian.ToUInt32 (header, 0x16),
+ BPP = LittleEndian.ToInt16 (header, 0x1C),
+ UnpackedSize = unpacked_size,
+ DataOffset = data_offset,
+ };
+ }
+ }
+
+ public override ImageData Read (Stream stream, ImageMetaData info)
+ {
+ var meta = (ZbmMetaData)info;
+ var data = new byte[meta.UnpackedSize];
+ stream.Position = meta.DataOffset;
+ Unpack (stream, data);
+ using (var bmp = new MemoryStream (data))
+ return ImageFormat.Bmp.Read (bmp, info);
+ }
+
+ public override void Write (Stream file, ImageData image)
+ {
+ throw new System.NotImplementedException ("ZbmFormat.Write not implemented");
+ }
+
+ static void Unpack (Stream input, byte[] output)
+ {
+ using (var bits = new MsbBitStream (input, true))
+ {
+ bits.GetNextBit();
+ int dst = 0;
+ while (dst < output.Length)
+ {
+ int count = bits.GetBits (8);
+ if (-1 == count)
+ throw new EndOfStreamException();
+ if (count > 0x7F)
+ {
+ count &= 0x7F;
+ int offset = bits.GetBits (10);
+ if (-1 == offset)
+ throw new EndOfStreamException();
+ count = Math.Min (count & 0x7F, output.Length-dst);
+ Binary.CopyOverlapped (output, dst-offset, dst, count);
+ dst += count;
+ }
+ else
+ {
+ for (int i = 0 ; i < count && dst < output.Length; i++)
+ {
+ int v = bits.GetBits (8);
+ if (-1 == v)
+ throw new EndOfStreamException();
+ output[dst++] = (byte)v;
+ }
+ }
+ }
+ }
+ Decrypt (output);
+ }
+
+ static void Decrypt (byte[] data)
+ {
+ if (('B'^0xFF) == data[0] && ('M'^0xFF) == data[1])
+ {
+ int encrypted = Math.Min (100, data.Length);
+ for (int i = 0; i < encrypted; ++i)
+ data[i] ^= 0xFF;
+ }
+ }
+ }
+}
diff --git a/supported.html b/supported.html
index 5bb8fa03..261b7df4 100644
--- a/supported.html
+++ b/supported.html
@@ -43,7 +43,7 @@ Salmon Pink
Shisho-san to Issho
Sensei 2
Shoujo Settai
-Tsukushite Agechau 5
+Tsukushite Agechau series
| *.ggd | \xB9\xAA\xB3\xB3 \xAB\xAD\xAA\xBA \xB7\xB6\xB8\xB7 \xCD\xCA\xC9\xB8 | Yes |
*.gg1 *.gg2 *.gg3 *.gg0 | GGA00000 | No |
@@ -159,6 +159,7 @@ Yume Miru Kusuri
*.wip *.msk *.mos | WIPF | No |
| *.xfl | LB | Yes | Liar-soft |
Angel Bullet
+Fairytale Requiem
Sekien no Inganock
Shikkoku no Sharnoth
|
@@ -230,6 +231,7 @@ Nikutai Ten'i
*.dat *.arc | - M2TYPE | No | FFA System/G-SYS |
Dokusen Kango
Genecracer Saki
+Hazama no Tsuki
Hensai Keikaku
Himawari Oka Sougou Byouin e Youkoso
Inen no Yakata
@@ -281,9 +283,11 @@ Zansho Omimai Moushiagemasu
Jokyoushi wo Kurau
Nachtmusik
Nachtmusik Another
+Samayou Mitama ni Yasuragi no Toki wo
Time Trouble ~Marie ni Kubikkake~
|
| *.dat | - | No | Ail |
+Kyouhaku 2 ~Kizu ni Saku Hana Senketsu no Beni~
Ragna☆彡Science
Ma wo Jutaiseshi Otome no Kuetsu
|
@@ -338,6 +342,7 @@ Konneko
Natsu no Ame
Sakura Musubi
Santaful☆Summer
+Tonarizuma
Yatohime Zankikou
*.eri *.mio | Entis\x1a | No |
@@ -597,6 +602,12 @@ Wondering Repair!
| *.pac | - | No | Tmr-Hiro ADV System |
Hitozuma Sakunyuu Hyakkaten
|
+| *.snn+*.inx | - | No | BlueGale |
+Cafe Junkie
+Majidashi! Royale ~Finish wa Watashi no Naka de~
+MILK Junkies
+ |
+| *.zbm | amp_ | No |
Non-encrypted only