diff --git a/CSharp/Plugins/UniversalEditor.Plugins.FileSystem/DataFormats/FileSystem/TerminalReality/POD/PODDataFormat.cs b/CSharp/Plugins/UniversalEditor.Plugins.FileSystem/DataFormats/FileSystem/TerminalReality/POD/PODDataFormat.cs
new file mode 100644
index 00000000..fca2e0d4
--- /dev/null
+++ b/CSharp/Plugins/UniversalEditor.Plugins.FileSystem/DataFormats/FileSystem/TerminalReality/POD/PODDataFormat.cs
@@ -0,0 +1,210 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using UniversalEditor.IO;
+using UniversalEditor.ObjectModels.FileSystem;
+
+namespace UniversalEditor.DataFormats.FileSystem.TerminalReality.POD
+{
+ public class PODDataFormat : DataFormat
+ {
+ private static DataFormatReference _dfr = null;
+ public override DataFormatReference MakeReference()
+ {
+ if (_dfr == null)
+ {
+ _dfr = base.MakeReference();
+ _dfr.Capabilities.Add(typeof(FileSystemObjectModel), DataFormatCapabilities.All);
+ _dfr.ExportOptions.Add(new CustomOptionChoice("FormatVersion", "Format &version: ", true, new CustomOptionFieldChoice[]
+ {
+ new CustomOptionFieldChoice("POD1", PODVersion.POD1, true),
+ new CustomOptionFieldChoice("POD2", PODVersion.POD2)
+ }));
+ _dfr.ExportOptions.Add(new CustomOptionText("ArchiveName", "Archive &name: "));
+ _dfr.Filters.Add("Terminal Reality POD archive", new string[] { "*.pod" });
+ _dfr.Sources.Add("http://wiki.xentax.com/index.php?title=PODArchive1");
+ _dfr.Sources.Add("http://wiki.xentax.com/index.php?title=PODArchive2");
+ }
+ return _dfr;
+ }
+
+ private PODVersion mvarFormatVersion = PODVersion.POD1;
+ public PODVersion FormatVersion { get { return mvarFormatVersion; } set { mvarFormatVersion = value; } }
+
+ private string mvarArchiveName = String.Empty;
+ public string ArchiveName { get { return mvarArchiveName; } set { mvarArchiveName = value; } }
+
+ protected override void LoadInternal(ref ObjectModel objectModel)
+ {
+ FileSystemObjectModel fsom = (objectModel as FileSystemObjectModel);
+ if (fsom == null) throw new ObjectModelNotSupportedException();
+
+ Reader reader = base.Accessor.Reader;
+ string signatureV2 = reader.ReadFixedLengthString(4);
+ if (signatureV2 == "POD2")
+ {
+ mvarFormatVersion = PODVersion.POD2;
+ }
+ else
+ {
+ base.Accessor.Seek(-4, SeekOrigin.Current);
+ }
+
+ if (mvarFormatVersion == PODVersion.POD2)
+ {
+ uint unknown1 = reader.ReadUInt32();
+ }
+
+ mvarArchiveName = reader.ReadFixedLengthString(80);
+ mvarArchiveName = mvarArchiveName.TrimNull();
+ uint fileCount = reader.ReadUInt32();
+ uint trailCount = 0;
+
+ if (mvarFormatVersion == PODVersion.POD2)
+ {
+ trailCount = reader.ReadUInt32();
+ }
+
+ switch (mvarFormatVersion)
+ {
+ case PODVersion.POD1:
+ {
+ for (uint i = 0; i < fileCount; i++)
+ {
+ string fileName = reader.ReadFixedLengthString(32);
+ fileName = fileName.TrimNull();
+
+ uint length = reader.ReadUInt32();
+ uint offset = reader.ReadUInt32();
+
+ File file = fsom.AddFile(fileName);
+ file.Size = length;
+ file.Properties.Add("reader", reader);
+ file.Properties.Add("length", length);
+ file.Properties.Add("offset", offset);
+ file.DataRequest += file_DataRequest;
+ }
+ break;
+ }
+ case PODVersion.POD2:
+ {
+ uint[] lengths = new uint[fileCount];
+ uint[] offsets = new uint[fileCount];
+
+ for (uint i = 0; i < fileCount; i++)
+ {
+ // from start of filename directory
+ uint filenameOffset = reader.ReadUInt32();
+
+ lengths[i] = reader.ReadUInt32();
+ offsets[i] = reader.ReadUInt32();
+ ulong unknown = reader.ReadUInt64();
+ }
+ for (uint i = 0; i < fileCount; i++)
+ {
+ string fileName = reader.ReadNullTerminatedString();
+
+ File file = fsom.AddFile(fileName);
+ file.Size = lengths[i];
+ file.Properties.Add("reader", reader);
+ file.Properties.Add("length", lengths[i]);
+ file.Properties.Add("offset", offsets[i]);
+ file.DataRequest += file_DataRequest;
+ }
+ break;
+ }
+ }
+ }
+
+ private void file_DataRequest(object sender, DataRequestEventArgs e)
+ {
+ File file = (sender as File);
+ Reader reader = (Reader)file.Properties["reader"];
+ uint length = (uint)file.Properties["length"];
+ uint offset = (uint)file.Properties["offset"];
+
+ reader.Accessor.Seek(offset, SeekOrigin.Begin);
+ byte[] data = reader.ReadBytes(length);
+ e.Data = data;
+ }
+
+ protected override void SaveInternal(ObjectModel objectModel)
+ {
+ FileSystemObjectModel fsom = (objectModel as FileSystemObjectModel);
+ if (fsom == null) throw new ObjectModelNotSupportedException();
+
+ Writer writer = base.Accessor.Writer;
+ if (mvarFormatVersion == PODVersion.POD2)
+ {
+ writer.WriteFixedLengthString("POD2");
+ writer.WriteUInt32(0);
+ }
+ writer.WriteFixedLengthString(mvarArchiveName, 80);
+
+ File[] files = fsom.GetAllFiles();
+ writer.WriteUInt32((uint)files.Length);
+
+ if (mvarFormatVersion == PODVersion.POD2)
+ {
+ writer.WriteUInt32(0); // trail count
+ }
+
+ switch (mvarFormatVersion)
+ {
+ case PODVersion.POD1:
+ {
+ uint offset = (uint)(base.Accessor.Position + (40 * files.Length));
+
+ foreach (File file in files)
+ {
+ writer.WriteFixedLengthString(file.Name, 32);
+ uint length = (uint)file.Size;
+ writer.WriteUInt32(length);
+ writer.WriteUInt32(offset);
+ offset += length;
+ }
+
+ foreach (File file in files)
+ {
+ writer.WriteBytes(file.GetDataAsByteArray());
+ }
+ break;
+ }
+ case PODVersion.POD2:
+ {
+ uint fileNameDirectoryStart = (uint)base.Accessor.Position;
+ fileNameDirectoryStart += (uint)(20 * files.Length);
+
+ uint fileNameOffset = fileNameDirectoryStart;
+ uint offset = fileNameDirectoryStart;
+ for (uint i = 0; i < files.Length; i++)
+ {
+ offset += (uint)(files[i].Name.Length + 1);
+ }
+ for (uint i = 0; i < files.Length; i++)
+ {
+ // from start of filename directory
+ writer.WriteUInt32(fileNameOffset);
+ uint length = (uint)(files[i].Size);
+ writer.WriteUInt32(length);
+ writer.WriteUInt32(offset);
+ writer.WriteUInt64(0); // unknown
+ fileNameOffset += (uint)(files[i].Name.Length + 1);
+ offset += length;
+ }
+ for (uint i = 0; i < files.Length; i++)
+ {
+ writer.WriteNullTerminatedString(files[i].Name);
+ }
+ for (uint i = 0; i < files.Length; i++)
+ {
+ writer.WriteBytes(files[i].GetDataAsByteArray());
+ }
+ writer.Flush();
+ break;
+ }
+ }
+ }
+ }
+}
diff --git a/CSharp/Plugins/UniversalEditor.Plugins.FileSystem/DataFormats/FileSystem/TerminalReality/POD/PODVersion.cs b/CSharp/Plugins/UniversalEditor.Plugins.FileSystem/DataFormats/FileSystem/TerminalReality/POD/PODVersion.cs
new file mode 100644
index 00000000..88b05058
--- /dev/null
+++ b/CSharp/Plugins/UniversalEditor.Plugins.FileSystem/DataFormats/FileSystem/TerminalReality/POD/PODVersion.cs
@@ -0,0 +1,13 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+
+namespace UniversalEditor.DataFormats.FileSystem.TerminalReality.POD
+{
+ public enum PODVersion
+ {
+ POD1,
+ POD2
+ }
+}
diff --git a/CSharp/Plugins/UniversalEditor.Plugins.FileSystem/UniversalEditor.Plugins.FileSystem.csproj b/CSharp/Plugins/UniversalEditor.Plugins.FileSystem/UniversalEditor.Plugins.FileSystem.csproj
index 8536a5f6..ff390d2c 100644
--- a/CSharp/Plugins/UniversalEditor.Plugins.FileSystem/UniversalEditor.Plugins.FileSystem.csproj
+++ b/CSharp/Plugins/UniversalEditor.Plugins.FileSystem/UniversalEditor.Plugins.FileSystem.csproj
@@ -146,6 +146,8 @@
+
+