public MtxFile(MtxSerializable mtxSerializable, MtxEncoding encoding) { this.encoding = encoding; Has64BitOffsets = mtxSerializable.Has64BitOffsets; Entries = mtxSerializable.Sheets.Select(x => x.Texts.Select(x2 => new XElement("text", x2.Nodes())) .ToList()) .ToList(); }
public MtxFile(IEnumerable <List <XElement> >?collection, MtxEncoding encoding, bool has64BitOffsets = false) { if (collection is not null) { Entries = new List <List <XElement> >(collection); } else { Entries = new List <List <XElement> >(); } this.encoding = encoding; Has64BitOffsets = has64BitOffsets; }
public void OnExecute() { // Don't execute if we are showing help. if (ShowHelp) { return; } MtxEncoding encoding = null; var version = Version ?? "auto"; if (version == "auto") { if (FntPath != null || FpdPath != null) { version = "1"; } else { version = "2"; } } if (version == "1") { if (FntPath != null) { if (!File.Exists(FntPath)) { Error(string.Format(ErrorMessages.FileDoesNotExist, FntPath)); return; } var fntFile = new FntFile(FntPath); encoding = new CharacterMapMtxEncoding(fntFile.Characters); } else if (FpdPath != null) { if (!File.Exists(FpdPath)) { Error(string.Format(ErrorMessages.FileDoesNotExist, FpdPath)); return; } var fpdFile = new FpdFile(FpdPath); encoding = new CharacterMapMtxEncoding(fpdFile.Characters); } else { Error(ErrorMessages.FntOrFpdOptionMustBeSet); return; } } else if (version == "2") { encoding = new Utf16MtxEncoding(); } foreach (var file in Files) { if (!File.Exists(file)) { Error(string.Format(ErrorMessages.FileDoesNotExist, file)); continue; } var format = Format ?? "auto"; if (format == "auto") { var extension = Path.GetExtension(file); if (extension.Equals(".mtx", StringComparison.OrdinalIgnoreCase)) { format = "json"; } else if (extension.Equals(".json", StringComparison.OrdinalIgnoreCase)) { format = "mtx"; } else { Error(string.Format(ErrorMessages.CouldNotDetermineOutputFormat, file)); continue; } } if (format == "json") { var outputFilename = Output ?? Path.ChangeExtension(file, ".json"); try { var mtxFile = new MtxFile(file, encoding); var mtxJson = new MtxJson { Has64BitOffsets = mtxFile.Has64BitOffsets, Entries = mtxFile.Entries, }; JsonFileSerializer.Serialize(outputFilename, mtxJson); } catch (Exception e) { Error(e.Message); } } else if (format == "mtx") { var outputFilename = Output ?? Path.ChangeExtension(file, ".mtx"); try { var mtxJson = JsonFileSerializer.Deserialize <MtxJson>(file); var mtxFile = new MtxFile(mtxJson.Entries, encoding, mtxJson.Has64BitOffsets ? true : Has64BitOffsets); mtxFile.Save(outputFilename); } catch (Exception e) { Error(e.Message); } } } }
public MtxFile(string path, MtxEncoding encoding) { this.encoding = encoding; using (var source = new FileStream(path, FileMode.Open, FileAccess.Read)) using (var reader = new BinaryReader(source, Encoding.Unicode)) { // The first 4 bytes in an MTX file tells us its expected file size. // This value is incorrect for MTX files in the 15th Anniversary translation. // Those files will be identified as being invalid. var length = reader.Peek(x => x.ReadInt32()); if (length != source.Length) { throw new FileFormatException(string.Format(Resources.InvalidMtxFile, path)); } Func <BinaryReader, int> ReadInt; int intSize; // MTX files used on Switch, PS4, Xbox One, and PC store their offsets as 64-bit integers // On all other platforms, they are stored as 32-bit integers. // We're going to test this by reading the bytes at 0x4 as a 32-bit integer to see if it returns 8. // If it doesn't, we'll read bytes at 0x8 as a 64-bit integer to see if it returns 16. // If it doesn't, then throw an error. // This MTX file uses 32-bit offsets if (reader.At(0x4, x => x.ReadInt32()) == 8) { Has64BitOffsets = false; intSize = 4; ReadInt = x => x.ReadInt32(); } // This MTX file uses 64-bit offsets else if (reader.At(0x8, x => x.ReadInt64()) == 16) { Has64BitOffsets = true; intSize = 8; ReadInt = x => (int)x.ReadInt64(); } // Not an MTX file else { throw new FileFormatException(string.Format(Resources.InvalidMtxFile, path)); } source.Position += intSize; var sectionsTablePosition = ReadInt(reader); var sectionsCount = (reader.Peek(ReadInt) - sectionsTablePosition) / intSize; Entries = new List <List <XElement> >(sectionsCount); var offsets = new Queue <int>(); for (var i = 0; i < sectionsCount; i++) { var stringsTablePosition = ReadInt(reader); var stringsCount = (reader.Peek(ReadInt) - stringsTablePosition) / intSize; // OK to do this even if it's the last entry Entries.Add(new List <XElement>(stringsCount)); } foreach (var section in Entries) { for (var i = 0; i < section.Capacity; i++) { offsets.Enqueue(ReadInt(reader)); } } foreach (var section in Entries) { for (var i = 0; i < section.Capacity; i++) { source.Position = offsets.Dequeue(); var s = encoding.Read(reader); section.Add(s); } } } }
public MtxFile(MtxEncoding encoding, bool has64BitOffsets = false) : this(null, encoding, has64BitOffsets) { }
public MtxFile(string path, MtxEncoding encoding) { this.encoding = encoding; using (var source = new FileStream(path, FileMode.Open, FileAccess.Read)) using (var reader = new BinaryReader(source, Encoding.Unicode)) { // The first 4 bytes in an MTX file tells us its expected file size. // This value is incorrect for MTX files in the 15th Anniversary translation. // Those files will be identified as being invalid. var length = reader.PeekInt32(); if (length != source.Length) { throw new IOException(string.Format(ErrorMessages.InvalidMtxFile, path)); } Func <int> ReadInt, PeekInt; int intSize; // In the Switch version of Puyo Puyo Tetris, offsets are stored as 64-bit integers // In all other versions, they are stored as 32-bit integers. // We're going to test this by reading bytes 4-8 as a 32-bit integer to see if it returns 8. // If it doesn't, we'll read bytes 8-16 as a 64-bit integer to see if it returns 16. // If it doesn't, then throw an error. source.Position += 4; var testInt32 = reader.PeekInt32(); source.Position -= 4; if (testInt32 == 8) { // This MTX file uses 32-bit offsets Has64BitOffsets = false; intSize = 4; ReadInt = reader.ReadInt32; PeekInt = reader.PeekInt32; } else { source.Position += 8; var testInt64 = reader.PeekInt64(); source.Position -= 8; if (testInt64 == 16) { // This MTX file uses 64-bit offsets Has64BitOffsets = true; intSize = 8; ReadInt = () => (int)reader.ReadInt64(); PeekInt = () => (int)reader.PeekInt64(); } else { throw new IOException(string.Format(ErrorMessages.InvalidMtxFile, path)); } } source.Position += intSize; var sectionsTablePosition = ReadInt(); var sectionsCount = (PeekInt() - sectionsTablePosition) / intSize; Entries = new List <List <string> >(sectionsCount); var offsets = new Queue <int>(); for (var i = 0; i < sectionsCount; i++) { var stringsTablePosition = ReadInt(); var stringsCount = (PeekInt() - stringsTablePosition) / intSize; // OK to do this even if it's the last entry Entries.Add(new List <string>(stringsCount)); } foreach (var section in Entries) { for (var i = 0; i < section.Capacity; i++) { offsets.Enqueue(ReadInt()); } } foreach (var section in Entries) { for (var i = 0; i < section.Capacity; i++) { source.Position = offsets.Dequeue(); var s = encoding.Read(reader); section.Add(s); } } } }