diff --git a/ArcFormats/ArcFormats.csproj b/ArcFormats/ArcFormats.csproj
index 20182007..a8ade86c 100644
--- a/ArcFormats/ArcFormats.csproj
+++ b/ArcFormats/ArcFormats.csproj
@@ -108,6 +108,7 @@
+
@@ -119,6 +120,7 @@
+
@@ -164,6 +166,7 @@
+
@@ -189,6 +192,7 @@
+
diff --git a/ArcFormats/ArcPCK.cs b/ArcFormats/ArcPCK.cs
new file mode 100644
index 00000000..fe8bd5a1
--- /dev/null
+++ b/ArcFormats/ArcPCK.cs
@@ -0,0 +1,87 @@
+//! \file ArcPCK.cs
+//! \date Thu Jun 11 12:58:00 2015
+//! \brief Crowd engine resource archive.
+//
+// Copyright (C) 2015 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.Utility;
+
+namespace GameRes.Formats.Crowd
+{
+ [Export(typeof(ArchiveFormat))]
+ public class PckOpener : ArchiveFormat
+ {
+ public override string Tag { get { return "PCK"; } }
+ public override string Description { get { return "Crowd engine resource archive"; } }
+ public override uint Signature { get { return 0; } }
+ public override bool IsHierarchic { get { return false; } }
+ public override bool CanCreate { get { return false; } }
+
+ public override ArcFile TryOpen (ArcView file)
+ {
+ int count = file.View.ReadInt32 (0);
+ if (count <= 0 || count > 0xfffff)
+ return null;
+ long index_offset = 4;
+ uint index_size = (uint)(0xc * count);
+ if (index_size > file.View.Reserve (index_offset, index_size))
+ return null;
+ var dir = new List();
+ for (int i = 0; i < count; ++i)
+ {
+ var entry = new Entry {
+ Offset = file.View.ReadUInt32 (index_offset+4),
+ Size = file.View.ReadUInt32 (index_offset+8)
+ };
+ if (entry.Offset < index_size || !entry.CheckPlacement (file.MaxOffset))
+ return null;
+ dir.Add (entry);
+ index_offset += 12;
+ }
+ byte[] name_buf = new byte[260];
+ foreach (var entry in dir)
+ {
+ uint max_len = Math.Min (260u, file.View.Reserve (index_offset, 260));
+ uint n;
+ for (n = 0; n < max_len; ++n)
+ {
+ byte b = file.View.ReadByte (index_offset+n);
+ if (0 == b)
+ break;
+ name_buf[n] = b;
+ }
+ if (0 == n || max_len == n)
+ return null;
+ entry.Name = Encodings.cp932.GetString (name_buf, 0, (int)n);
+ entry.Type = FormatCatalog.Instance.GetTypeFromName (entry.Name);
+ index_offset += n+1;
+ }
+ return new ArcFile (file, this, dir);
+ }
+ }
+}
+
+
diff --git a/ArcFormats/AudioEOG.cs b/ArcFormats/AudioEOG.cs
new file mode 100644
index 00000000..97423550
--- /dev/null
+++ b/ArcFormats/AudioEOG.cs
@@ -0,0 +1,58 @@
+//! \file AudioEOG.cs
+//! \date Thu Jun 11 12:46:35 2015
+//! \brief Crowd engine audio file.
+//
+// Copyright (C) 2015 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.Crowd
+{
+ [Export(typeof(AudioFormat))]
+ public class EogAudio : OggAudio
+ {
+ public override string Tag { get { return "EOG"; } }
+ public override string Description { get { return "Crowd engine audio format (Ogg/Vorbis)"; } }
+ public override uint Signature { get { return 0x004D5243; } } // 'CRM'
+
+ public override SoundInput TryOpen (Stream file)
+ {
+ var ogg = new StreamRegion (file, 8);
+ try
+ {
+ return new OggInput (ogg);
+ }
+ catch
+ {
+ ogg.Dispose();
+ throw;
+ }
+ }
+
+ public override void Write (SoundInput source, Stream output)
+ {
+ throw new System.NotImplementedException ("EogFormat.Write not implemenented");
+ }
+ }
+}
diff --git a/ArcFormats/ImageCWP.cs b/ArcFormats/ImageCWP.cs
new file mode 100644
index 00000000..9e9ee13b
--- /dev/null
+++ b/ArcFormats/ImageCWP.cs
@@ -0,0 +1,112 @@
+//! \file ImageCWP.cs
+//! \date Thu Jun 11 13:43:41 2015
+//! \brief Crowd engine image format.
+//
+// Copyright (C) 2015 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;
+using System.IO;
+using System.Windows.Media;
+using System.Windows.Media.Imaging;
+using GameRes.Utility;
+
+namespace GameRes.Formats.Crowd
+{
+ [Export(typeof(ImageFormat))]
+ public class CwpFormat : ImageFormat
+ {
+ public override string Tag { get { return "CWP"; } }
+ public override string Description { get { return "Crowd engine image format"; } }
+ public override uint Signature { get { return 0x50445743; } } // 'CWDP'
+
+ public override ImageMetaData ReadMetaData (Stream stream)
+ {
+ using (var input = new ArcView.Reader (stream))
+ {
+ input.ReadInt32();
+ uint width = Binary.BigEndian (input.ReadUInt32());
+ uint height = Binary.BigEndian (input.ReadUInt32());
+ if (0 == width || 0 == height)
+ return null;
+ int bpp = input.ReadByte();
+ int color_type = input.ReadByte();
+ switch (color_type)
+ {
+ case 2: bpp *= 3; break;
+ case 4: bpp *= 2; break;
+ case 6: bpp *= 4; break;
+ case 3:
+ case 0: break;
+ default: return null;
+ }
+ return new ImageMetaData
+ {
+ Width = width,
+ Height = height,
+ BPP = bpp,
+ };
+ }
+ }
+
+ public override ImageData Read (Stream stream, ImageMetaData info)
+ {
+ var header = new byte[0x15];
+ using (var mem = new MemoryStream((int)(0x14 + stream.Length + 12)))
+ using (var png = new BinaryWriter (mem))
+ {
+ png.Write (0x474E5089u); // png header
+ png.Write (0x0A1A0A0Du);
+ png.Write (0x0D000000u);
+ png.Write (0x52444849u); // 'IHDR'
+ stream.Position = 4;
+ stream.Read (header, 0, header.Length);
+ png.Write (header, 0, header.Length);
+ png.Write (0x54414449u); // 'IDAT'
+ stream.CopyTo (mem);
+ header[1] = 0;
+ header[2] = 0;
+ header[3] = 0;
+ LittleEndian.Pack (0x444E4549, header, 4);
+ LittleEndian.Pack (0x826042AE, header, 8);
+ png.Write (header, 1, 11);
+ mem.Position = 0;
+ var decoder = new PngBitmapDecoder (mem, BitmapCreateOptions.None, BitmapCacheOption.OnLoad);
+ BitmapSource frame = decoder.Frames[0];
+ var pixels = new byte[info.Width*info.Height*4];
+ frame.CopyPixels (pixels, (int)info.Width*4, 0);
+ for (int i = 0; i < pixels.Length; i += 4)
+ {
+ byte t = pixels[i];
+ pixels[i] = pixels[i+2];
+ pixels[i+2] = t;
+ }
+ return ImageData.Create (info, PixelFormats.Bgr32, null, pixels);
+ }
+ }
+
+ public override void Write (Stream file, ImageData image)
+ {
+ throw new System.NotImplementedException ("CwpFormat.Write not implemented");
+ }
+ }
+}
+
diff --git a/ArcFormats/ImageZBM.cs b/ArcFormats/ImageZBM.cs
new file mode 100644
index 00000000..2c32aa62
--- /dev/null
+++ b/ArcFormats/ImageZBM.cs
@@ -0,0 +1,88 @@
+//! \file ImageZBM.cs
+//! \date Thu Jun 11 16:24:09 2015
+//! \brief LZ-compressed bitmap format.
+//
+// Copyright (C) 2015 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.Runtime.InteropServices;
+using GameRes.Utility;
+
+namespace GameRes.Formats.Crowd
+{
+ [Export(typeof(ImageFormat))]
+ public class ZbmFormat : BmpFormat
+ {
+ public override string Tag { get { return "ZBM"; } }
+ public override string Description { get { return "LZ-compressed bitmap"; } }
+ public override uint Signature { get { return 0x44445A53u; } } // 'SZDD'
+
+ public override ImageMetaData ReadMetaData (Stream stream)
+ {
+ stream.Position = 0x0e;
+ using (var lz = new LzssReader (stream, 100, 54)) // extract BMP header
+ {
+ lz.FrameSize = 0x1000;
+ lz.FrameFill = 0x20;
+ lz.FrameInitPos = 0x1000 - 0x10;
+ lz.Unpack();
+ var header = lz.Data;
+ for (int i = 0; i < 54; ++i)
+ header[i] ^= 0xff;
+ using (var bmp = new MemoryStream (header))
+ return base.ReadMetaData (bmp);
+ }
+ }
+
+ public override ImageData Read (Stream stream, ImageMetaData info)
+ {
+ if (stream.Length > int.MaxValue)
+ throw new FileSizeException();
+ var header = new byte[14];
+ if (header.Length != stream.Read (header, 0, header.Length))
+ throw new InvalidFormatException();
+ int data_length = LittleEndian.ToInt32 (header, 10);
+ int input_length = (int)(stream.Length-stream.Position);
+ using (var lz = new LzssReader (stream, input_length, data_length))
+ {
+ lz.FrameSize = 0x1000;
+ lz.FrameFill = 0x20;
+ lz.FrameInitPos = 0x1000 - 0x10;
+ lz.Unpack();
+ var data = lz.Data;
+ int count = Math.Min (100, data.Length);
+ for (int i = 0; i < count; ++i)
+ data[i] ^= 0xff;
+ using (var bmp = new MemoryStream (data))
+ return base.Read (bmp, info);
+ }
+ }
+
+ public override void Write (Stream file, ImageData image)
+ {
+ throw new NotImplementedException ("ZbmFormat.Write not implemented");
+ }
+ }
+}
diff --git a/ArcFormats/Properties/AssemblyInfo.cs b/ArcFormats/Properties/AssemblyInfo.cs
index 01fec10d..efc8db15 100644
--- a/ArcFormats/Properties/AssemblyInfo.cs
+++ b/ArcFormats/Properties/AssemblyInfo.cs
@@ -32,5 +32,5 @@ using System.Runtime.InteropServices;
// You can specify all the values or you can default the Build and Revision Numbers
// by using the '*' as shown below:
// [assembly: AssemblyVersion("1.0.*")]
-[assembly: AssemblyVersion ("1.0.6.59")]
-[assembly: AssemblyFileVersion ("1.0.6.59")]
+[assembly: AssemblyVersion ("1.0.6.61")]
+[assembly: AssemblyFileVersion ("1.0.6.61")]