diff --git a/ArcFormats/ArcFormats.csproj b/ArcFormats/ArcFormats.csproj
index dfd3ab19..e58b2648 100644
--- a/ArcFormats/ArcFormats.csproj
+++ b/ArcFormats/ArcFormats.csproj
@@ -118,6 +118,8 @@
+
+
diff --git a/ArcFormats/Nejii/ArcCDT.cs b/ArcFormats/Nejii/ArcCDT.cs
new file mode 100644
index 00000000..bfc4a76c
--- /dev/null
+++ b/ArcFormats/Nejii/ArcCDT.cs
@@ -0,0 +1,84 @@
+//! \file ArcCDT.cs
+//! \date Tue Jan 24 06:03:48 2017
+//! \brief NEJII engine resource archive.
+//
+// Copyright (C) 2017 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.Collections.Generic;
+using System.ComponentModel.Composition;
+using System.IO;
+using GameRes.Compression;
+
+namespace GameRes.Formats.Nejii
+{
+ [Export(typeof(ArchiveFormat))]
+ public class CdtOpener : ArchiveFormat
+ {
+ public override string Tag { get { return "CDT"; } }
+ public override string Description { get { return "NEJII engine resource archive"; } }
+ public override uint Signature { get { return 0; } }
+ public override bool IsHierarchic { get { return false; } }
+ public override bool CanWrite { get { return false; } }
+
+ public CdtOpener ()
+ {
+ Extensions = new string[] { "cdt", "pdt", "vdt" };
+ }
+
+ public override ArcFile TryOpen (ArcView file)
+ {
+ if (file.MaxOffset <= 12 || !file.View.AsciiEqual (file.MaxOffset-12, "RK1\0"))
+ return null;
+ int count = file.View.ReadInt32 (file.MaxOffset-8);
+ if (!IsSaneCount (count))
+ return null;
+ uint index_offset = file.View.ReadUInt32 (file.MaxOffset-4);
+ if (index_offset >= file.MaxOffset)
+ return null;
+ var dir = new List (count);
+ for (int i = 0; i < count; ++i)
+ {
+ var name = file.View.ReadString (index_offset, 0x10);
+ index_offset += 0x10;
+ var entry = FormatCatalog.Instance.Create (name);
+ entry.Size = file.View.ReadUInt32 (index_offset);
+ entry.UnpackedSize = file.View.ReadUInt32 (index_offset+4);
+ entry.IsPacked = file.View.ReadInt32 (index_offset+8) != 0;
+ entry.Offset = file.View.ReadUInt32 (index_offset+12);
+ if (!entry.CheckPlacement (file.MaxOffset))
+ return null;
+ index_offset += 0x10;
+ dir.Add (entry);
+ }
+ return new ArcFile (file, this, dir);
+ }
+
+ public override Stream OpenEntry (ArcFile arc, Entry entry)
+ {
+ var pent = entry as PackedEntry;
+ Stream input = arc.File.CreateStream (entry.Offset, entry.Size);
+ if (null != pent && pent.IsPacked)
+ input = new LzssStream (input);
+ return input;
+ }
+ }
+}
diff --git a/ArcFormats/Nejii/ArcPCD.cs b/ArcFormats/Nejii/ArcPCD.cs
new file mode 100644
index 00000000..009c337f
--- /dev/null
+++ b/ArcFormats/Nejii/ArcPCD.cs
@@ -0,0 +1,102 @@
+//! \file ArcPCD.cs
+//! \date Tue Jan 24 06:49:35 2017
+//! \brief NEJII engine audio archive.
+//
+// Copyright (C) 2017 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;
+
+namespace GameRes.Formats.Nejii
+{
+ internal class PcdEntry : Entry
+ {
+ public byte[] WaveFormat;
+ }
+
+ [Export(typeof(ArchiveFormat))]
+ public class PcdOpener : ArchiveFormat
+ {
+ public override string Tag { get { return "PCD/NEJII"; } }
+ public override string Description { get { return "NEJII engine resource archive"; } }
+ public override uint Signature { get { return 0; } }
+ public override bool IsHierarchic { get { return false; } }
+ public override bool CanWrite { get { return false; } }
+
+ public override ArcFile TryOpen (ArcView file)
+ {
+ if (file.MaxOffset < 0x30 || !file.Name.EndsWith (".pcd", StringComparison.InvariantCultureIgnoreCase))
+ return null;
+ // check if first entry looks like WAVEFORMAT
+ ushort channels = file.View.ReadUInt16 (0x12);
+ if (0 == channels || channels > 2)
+ return null;
+ uint rate = file.View.ReadUInt32 (0x14);
+ uint bps = file.View.ReadUInt32 (0x18);
+ uint block_align = file.View.ReadUInt16 (0x1C);
+ if (block_align * rate != bps)
+ return null;
+ bps = file.View.ReadUInt16 (0x1E);
+ if (bps != 8 && bps != 16)
+ return null;
+
+ long offset = 0;
+ var dir = new List();
+ while (offset < file.MaxOffset)
+ {
+ var name = file.View.ReadString (offset, 0x10);
+ var entry = FormatCatalog.Instance.Create (name);
+ entry.WaveFormat = file.View.ReadBytes (offset+0x10, 0x10);
+ entry.Offset = offset + 0x20;
+ entry.Size = file.View.ReadUInt32 (entry.Offset) + 4;
+ if (!entry.CheckPlacement (file.MaxOffset))
+ return null;
+ dir.Add (entry);
+ offset = entry.Offset+entry.Size;
+ }
+ return new ArcFile (file, this, dir);
+ }
+
+ public override Stream OpenEntry (ArcFile arc, Entry entry)
+ {
+ var pent = (PcdEntry)entry;
+ using (var riff_mem = new MemoryStream (0x2C))
+ using (var riff = new BinaryWriter (riff_mem))
+ {
+ uint riff_size = entry.Size + 0x20;
+ riff.Write (AudioFormat.Wav.Signature);
+ riff.Write (riff_size);
+ riff.Write (0x45564157); // 'WAVE'
+ riff.Write (0x20746d66); // 'fmt '
+ riff.Write (0x10);
+ riff.Write (pent.WaveFormat);
+ riff.Write (0x61746164); // 'data'
+ riff.Flush();
+ var header = riff_mem.ToArray();
+ var pcm = arc.File.CreateStream (entry.Offset, entry.Size);
+ return new PrefixStream (header, pcm);
+ }
+ }
+ }
+}
diff --git a/supported.html b/supported.html
index a7cad9d8..00fb3f4b 100644
--- a/supported.html
+++ b/supported.html
@@ -301,6 +301,7 @@ Seirei Tenshou
Se-kirara
Sharin no Kuni, Himawari no Shoujo
Shokusai no Miyako
+Sis Koi
Smile Cubic!
Specialite!
Suiheisen made Nan Mile?
@@ -1361,6 +1362,10 @@ Mite Kudasaimasu?
*.dpm *.bin | DPMX | No | Hot Soup Processor |
femme fatale
|
+*.cdt *.pdt *.vdt | RK1 | No | NEJII |
+Kidou Houshinki
+ |
+| *.pcd | - | No |
Non-encrypted only