| 1 | using System; | 
 
 
 
 
 | 2 | using System.Collections.Generic; | 
 
 
 
 
 | 3 | using System.IO; | 
 
 
 
 
 | 4 | using System.Xml; | 
 
 
 
 
 | 5 |  | 
 
 
 
 
 | 6 | namespace Oni.Level | 
 
 
 
 
 | 7 | { | 
 
 
 
 
 | 8 | using Metadata; | 
 
 
 
 
 | 9 | using Xml; | 
 
 
 
 
 | 10 |  | 
 
 
 
 
 | 11 | partial class LevelImporter | 
 
 
 
 
 | 12 | { | 
 
 
 
 
 | 13 | private class Film | 
 
 
 
 
 | 14 | { | 
 
 
 
 
 | 15 | public string Name; | 
 
 
 
 
 | 16 | public Vector3 Position; | 
 
 
 
 
 | 17 | public float Facing; | 
 
 
 
 
 | 18 | public float DesiredFacing; | 
 
 
 
 
 | 19 | public float HeadFacing; | 
 
 
 
 
 | 20 | public float HeadPitch; | 
 
 
 
 
 | 21 | public readonly string[] Animations = new string[2]; | 
 
 
 
 
 | 22 | public int Length; | 
 
 
 
 
 | 23 | public readonly List<FilmFrame> Frames = new List<FilmFrame>(); | 
 
 
 
 
 | 24 | } | 
 
 
 
 
 | 25 |  | 
 
 
 
 
 | 26 | private class FilmFrame | 
 
 
 
 
 | 27 | { | 
 
 
 
 
 | 28 | public Vector2 MouseDelta; | 
 
 
 
 
 | 29 | public InstanceMetadata.FILMKeys Keys; | 
 
 
 
 
 | 30 | public uint Time; | 
 
 
 
 
 | 31 | } | 
 
 
 
 
 | 32 |  | 
 
 
 
 
 | 33 | private void ReadFilms(XmlReader xml, string basePath) | 
 
 
 
 
 | 34 | { | 
 
 
 
 
 | 35 | if (!xml.IsStartElement("Films") || xml.SkipEmpty()) | 
 
 
 
 
 | 36 | return; | 
 
 
 
 
 | 37 |  | 
 
 
 
 
 | 38 | xml.ReadStartElement("Films"); | 
 
 
 
 
 | 39 |  | 
 
 
 
 
 | 40 | while (xml.IsStartElement()) | 
 
 
 
 
 | 41 | { | 
 
 
 
 
 | 42 | xml.ReadStartElement("Import"); | 
 
 
 
 
 | 43 | string filePath = Path.Combine(basePath, xml.ReadElementContentAsString()); | 
 
 
 
 
 | 44 | xml.ReadEndElement(); | 
 
 
 
 
 | 45 |  | 
 
 
 
 
 | 46 | if (!File.Exists(filePath)) | 
 
 
 
 
 | 47 | { | 
 
 
 
 
 | 48 | error.WriteLine("Could not find file '{0}'", filePath); | 
 
 
 
 
 | 49 | continue; | 
 
 
 
 
 | 50 | } | 
 
 
 
 
 | 51 |  | 
 
 
 
 
 | 52 | string extension = Path.GetExtension(filePath); | 
 
 
 
 
 | 53 | string name = Path.GetFileNameWithoutExtension(filePath); | 
 
 
 
 
 | 54 |  | 
 
 
 
 
 | 55 | if (string.Equals(extension, ".oni", StringComparison.OrdinalIgnoreCase)) | 
 
 
 
 
 | 56 | { | 
 
 
 
 
 | 57 | var outputFilePath = Path.Combine(outputDirPath, name + ".oni"); | 
 
 
 
 
 | 58 |  | 
 
 
 
 
 | 59 | File.Copy(filePath, outputFilePath, true); | 
 
 
 
 
 | 60 | } | 
 
 
 
 
 | 61 | else if (string.Equals(extension, ".dat", StringComparison.OrdinalIgnoreCase)) | 
 
 
 
 
 | 62 | { | 
 
 
 
 
 | 63 | var film = ReadBinFilm(filePath); | 
 
 
 
 
 | 64 |  | 
 
 
 
 
 | 65 | var datWriter = new DatWriter(); | 
 
 
 
 
 | 66 | WriteDatFilm(datWriter, film); | 
 
 
 
 
 | 67 | datWriter.Write(outputDirPath); | 
 
 
 
 
 | 68 | } | 
 
 
 
 
 | 69 | else if (string.Equals(extension, ".xml", StringComparison.OrdinalIgnoreCase)) | 
 
 
 
 
 | 70 | { | 
 
 
 
 
 | 71 | var film = ReadXmlFilm(filePath); | 
 
 
 
 
 | 72 |  | 
 
 
 
 
 | 73 | var datWriter = new DatWriter(); | 
 
 
 
 
 | 74 | WriteDatFilm(datWriter, film); | 
 
 
 
 
 | 75 | datWriter.Write(outputDirPath); | 
 
 
 
 
 | 76 | } | 
 
 
 
 
 | 77 | else | 
 
 
 
 
 | 78 | { | 
 
 
 
 
 | 79 | error.WriteLine("Unsupported film file type {0}", extension); | 
 
 
 
 
 | 80 | } | 
 
 
 
 
 | 81 | } | 
 
 
 
 
 | 82 |  | 
 
 
 
 
 | 83 | xml.ReadEndElement(); | 
 
 
 
 
 | 84 | } | 
 
 
 
 
 | 85 |  | 
 
 
 
 
 | 86 | private static Film ReadBinFilm(string filePath) | 
 
 
 
 
 | 87 | { | 
 
 
 
 
 | 88 | string name = Path.GetFileNameWithoutExtension(filePath); | 
 
 
 
 
 | 89 |  | 
 
 
 
 
 | 90 | if (name.StartsWith("FILM", StringComparison.Ordinal)) | 
 
 
 
 
 | 91 | name = name.Substring(4); | 
 
 
 
 
 | 92 |  | 
 
 
 
 
 | 93 | var film = new Film(); | 
 
 
 
 
 | 94 | film.Name = name; | 
 
 
 
 
 | 95 |  | 
 
 
 
 
 | 96 | using (var reader = new BinaryReader(filePath, true)) | 
 
 
 
 
 | 97 | { | 
 
 
 
 
 | 98 | film.Animations[0] = reader.ReadString(128); | 
 
 
 
 
 | 99 | film.Animations[1] = reader.ReadString(128); | 
 
 
 
 
 | 100 | film.Position = reader.ReadVector3(); | 
 
 
 
 
 | 101 | film.Facing = reader.ReadSingle(); | 
 
 
 
 
 | 102 | film.DesiredFacing = reader.ReadSingle(); | 
 
 
 
 
 | 103 | film.HeadFacing = reader.ReadSingle(); | 
 
 
 
 
 | 104 | film.HeadPitch = reader.ReadSingle(); | 
 
 
 
 
 | 105 | film.Length = reader.ReadInt32(); | 
 
 
 
 
 | 106 | reader.Skip(28); | 
 
 
 
 
 | 107 | int numFrames = reader.ReadInt32(); | 
 
 
 
 
 | 108 | film.Frames.Capacity = numFrames; | 
 
 
 
 
 | 109 |  | 
 
 
 
 
 | 110 | for (int i = 0; i < numFrames; i++) | 
 
 
 
 
 | 111 | { | 
 
 
 
 
 | 112 | var frame = new FilmFrame(); | 
 
 
 
 
 | 113 | frame.MouseDelta = reader.ReadVector2(); | 
 
 
 
 
 | 114 | frame.Keys = (InstanceMetadata.FILMKeys)reader.ReadUInt64(); | 
 
 
 
 
 | 115 | frame.Time = reader.ReadUInt32(); | 
 
 
 
 
 | 116 | reader.Skip(4); | 
 
 
 
 
 | 117 | film.Frames.Add(frame); | 
 
 
 
 
 | 118 | } | 
 
 
 
 
 | 119 | } | 
 
 
 
 
 | 120 |  | 
 
 
 
 
 | 121 | return film; | 
 
 
 
 
 | 122 | } | 
 
 
 
 
 | 123 |  | 
 
 
 
 
 | 124 | private static Film ReadXmlFilm(string filePath) | 
 
 
 
 
 | 125 | { | 
 
 
 
 
 | 126 | string name = Path.GetFileNameWithoutExtension(filePath); | 
 
 
 
 
 | 127 |  | 
 
 
 
 
 | 128 | if (name.StartsWith("FILM", StringComparison.Ordinal)) | 
 
 
 
 
 | 129 | name = name.Substring(4); | 
 
 
 
 
 | 130 |  | 
 
 
 
 
 | 131 | var film = new Film(); | 
 
 
 
 
 | 132 | film.Name = name; | 
 
 
 
 
 | 133 |  | 
 
 
 
 
 | 134 | var settings = new XmlReaderSettings { | 
 
 
 
 
 | 135 | IgnoreWhitespace = true, | 
 
 
 
 
 | 136 | IgnoreProcessingInstructions = true, | 
 
 
 
 
 | 137 | IgnoreComments = true | 
 
 
 
 
 | 138 | }; | 
 
 
 
 
 | 139 |  | 
 
 
 
 
 | 140 | using (var xml = XmlReader.Create(filePath, settings)) | 
 
 
 
 
 | 141 | { | 
 
 
 
 
 | 142 | xml.ReadStartElement("Oni"); | 
 
 
 
 
 | 143 |  | 
 
 
 
 
 | 144 | name = xml.GetAttribute("Name"); | 
 
 
 
 
 | 145 |  | 
 
 
 
 
 | 146 | if (!string.IsNullOrEmpty(name)) | 
 
 
 
 
 | 147 | film.Name = name; | 
 
 
 
 
 | 148 |  | 
 
 
 
 
 | 149 | xml.ReadStartElement("FILM"); | 
 
 
 
 
 | 150 |  | 
 
 
 
 
 | 151 | film.Position = xml.ReadElementContentAsVector3("Position"); | 
 
 
 
 
 | 152 | film.Facing = xml.ReadElementContentAsFloat("Facing", ""); | 
 
 
 
 
 | 153 | film.DesiredFacing = xml.ReadElementContentAsFloat("DesiredFacing", ""); | 
 
 
 
 
 | 154 | film.HeadFacing = xml.ReadElementContentAsFloat("HeadFacing", ""); | 
 
 
 
 
 | 155 | film.HeadPitch = xml.ReadElementContentAsFloat("HeadPitch", ""); | 
 
 
 
 
 | 156 | film.Length = xml.ReadElementContentAsInt("FrameCount", ""); | 
 
 
 
 
 | 157 | xml.ReadStartElement("Animations"); | 
 
 
 
 
 | 158 | film.Animations[0] = xml.ReadElementContentAsString("Link", ""); | 
 
 
 
 
 | 159 | film.Animations[1] = xml.ReadElementContentAsString("Link", ""); | 
 
 
 
 
 | 160 | xml.ReadEndElement(); | 
 
 
 
 
 | 161 | xml.ReadStartElement("Frames"); | 
 
 
 
 
 | 162 |  | 
 
 
 
 
 | 163 | while (xml.IsStartElement()) | 
 
 
 
 
 | 164 | { | 
 
 
 
 
 | 165 | var frame = new FilmFrame(); | 
 
 
 
 
 | 166 |  | 
 
 
 
 
 | 167 | switch (xml.LocalName) | 
 
 
 
 
 | 168 | { | 
 
 
 
 
 | 169 | case "FILMFrame": | 
 
 
 
 
 | 170 | xml.ReadStartElement(); | 
 
 
 
 
 | 171 | frame.MouseDelta.X = xml.ReadElementContentAsFloat("MouseDeltaX", ""); | 
 
 
 
 
 | 172 | frame.MouseDelta.Y = xml.ReadElementContentAsFloat("MouseDeltaY", ""); | 
 
 
 
 
 | 173 | frame.Keys = xml.ReadElementContentAsEnum<InstanceMetadata.FILMKeys>("Keys"); | 
 
 
 
 
 | 174 | frame.Time = (uint)xml.ReadElementContentAsInt("Frame", ""); | 
 
 
 
 
 | 175 | xml.ReadEndElement(); | 
 
 
 
 
 | 176 | break; | 
 
 
 
 
 | 177 |  | 
 
 
 
 
 | 178 | case "Frame": | 
 
 
 
 
 | 179 | xml.ReadStartElement(); | 
 
 
 
 
 | 180 | while (xml.IsStartElement()) | 
 
 
 
 
 | 181 | { | 
 
 
 
 
 | 182 | switch (xml.LocalName) | 
 
 
 
 
 | 183 | { | 
 
 
 
 
 | 184 | case "Time": | 
 
 
 
 
 | 185 | frame.Time = (uint)xml.ReadElementContentAsInt(); | 
 
 
 
 
 | 186 | break; | 
 
 
 
 
 | 187 | case "MouseDelta": | 
 
 
 
 
 | 188 | frame.MouseDelta = xml.ReadElementContentAsVector2(); | 
 
 
 
 
 | 189 | break; | 
 
 
 
 
 | 190 | case "Keys": | 
 
 
 
 
 | 191 | frame.Keys = xml.ReadElementContentAsEnum<InstanceMetadata.FILMKeys>(); | 
 
 
 
 
 | 192 | break; | 
 
 
 
 
 | 193 | } | 
 
 
 
 
 | 194 | } | 
 
 
 
 
 | 195 | xml.ReadEndElement(); | 
 
 
 
 
 | 196 | break; | 
 
 
 
 
 | 197 | default: | 
 
 
 
 
 | 198 | xml.Skip(); | 
 
 
 
 
 | 199 | continue; | 
 
 
 
 
 | 200 | } | 
 
 
 
 
 | 201 |  | 
 
 
 
 
 | 202 | film.Frames.Add(frame); | 
 
 
 
 
 | 203 |  | 
 
 
 
 
 | 204 | } | 
 
 
 
 
 | 205 |  | 
 
 
 
 
 | 206 | xml.ReadEndElement(); | 
 
 
 
 
 | 207 | xml.ReadEndElement(); | 
 
 
 
 
 | 208 | } | 
 
 
 
 
 | 209 |  | 
 
 
 
 
 | 210 | return film; | 
 
 
 
 
 | 211 | } | 
 
 
 
 
 | 212 |  | 
 
 
 
 
 | 213 | private static void WriteDatFilm(DatWriter filmWriter, Film film) | 
 
 
 
 
 | 214 | { | 
 
 
 
 
 | 215 | var descriptor = filmWriter.CreateInstance(TemplateTag.FILM, film.Name); | 
 
 
 
 
 | 216 |  | 
 
 
 
 
 | 217 | var animations = new ImporterDescriptor[2]; | 
 
 
 
 
 | 218 |  | 
 
 
 
 
 | 219 | for (int i = 0; i < animations.Length; i++) | 
 
 
 
 
 | 220 | { | 
 
 
 
 
 | 221 | if (!string.IsNullOrEmpty(film.Animations[i])) | 
 
 
 
 
 | 222 | animations[i] = filmWriter.CreateInstance(TemplateTag.TRAM, film.Animations[i]); | 
 
 
 
 
 | 223 | } | 
 
 
 
 
 | 224 |  | 
 
 
 
 
 | 225 | using (var writer = descriptor.OpenWrite()) | 
 
 
 
 
 | 226 | { | 
 
 
 
 
 | 227 | writer.Write(film.Position); | 
 
 
 
 
 | 228 | writer.Write(film.Facing); | 
 
 
 
 
 | 229 | writer.Write(film.DesiredFacing); | 
 
 
 
 
 | 230 | writer.Write(film.HeadFacing); | 
 
 
 
 
 | 231 | writer.Write(film.HeadPitch); | 
 
 
 
 
 | 232 | writer.Write(film.Length); | 
 
 
 
 
 | 233 | writer.Write(animations); | 
 
 
 
 
 | 234 | writer.Skip(12); | 
 
 
 
 
 | 235 | writer.Write(film.Frames.Count); | 
 
 
 
 
 | 236 |  | 
 
 
 
 
 | 237 | foreach (var frame in film.Frames) | 
 
 
 
 
 | 238 | { | 
 
 
 
 
 | 239 | writer.Write(frame.MouseDelta); | 
 
 
 
 
 | 240 | writer.Write((ulong)frame.Keys); | 
 
 
 
 
 | 241 | writer.Write(frame.Time); | 
 
 
 
 
 | 242 | writer.Skip(4); | 
 
 
 
 
 | 243 | } | 
 
 
 
 
 | 244 | } | 
 
 
 
 
 | 245 | } | 
 
 
 
 
 | 246 | } | 
 
 
 
 
 | 247 | } |