public void DumpChunkOffs() { for (int i = 0; i < HeaderOffsets.Length; ++i) { var l = HeaderOffsets[i]; var p = *(SectionHeader *)GMFile.PtrFromOffset(this, l); Console.Error.WriteLine(p.MagicString() + ": " + l.ToString("X8") + "-" + (l + p.Size).ToString("X8") + " (" + p.Size.ToString("X8") + ")"); } }
// EXTN: SectionCountOffset<Extension> // { // STRG* // STRG* // STRG* // CountOffsetList<T> // { // STRG* // } // STRG* // STRG* // int32 02 00 00 00 // // CountOffsetList<T> // { // // 01 // STRG** (1) // int32 10 04 00 00 (offset?) // STRG* (1) // int32 01 00 00 00 // int32 0C 00 00 00 // int32 02 00 00 00 // // // 02 // STRG* // int32 00 00 00 00 // STRG* // int32 02 00 00 00 // int32 0C 00 00 00 // int32 02 00 00 00 // } // // STRG* // int32 00 00 00 00 // int32[4] 66 82 4C A8 69 1E 7C 85 5B 70 AC 11 67 C0 D2 D5 // WTF? hash? // } static void Import(ImportOptions opt) { var file = Path.GetFullPath(opt.File); if (!File.Exists(file)) { throw new FileNotFoundException("Project file not found", file); } var baseDir = Path.GetDirectoryName(file) + Path.DirectorySeparatorChar; JsonData projFile = JsonMapper.ToObject(File.OpenText(file)); GMFile f = Deserialize.ReadFile(baseDir, projFile); File.WriteAllBytes(Path.GetFullPath(opt.OutputFile), WriteFile(baseDir, projFile, f)); }
static void Export(ExportOptions eo) { var file = Path.GetFullPath(String.IsNullOrEmpty(eo.File) ? DATA_WIN : eo.File); try // see #m17 { int i = Console.CursorLeft; i = i-- + 1; } catch { eo.NoPrecProg = true; } if (Directory.Exists(file) && !File.Exists(file)) { file += Path.DirectorySeparatorChar + DATA_WIN; } if (!File.Exists(file)) { throw new ParserException("File \"" + file + "\" not found."); } var od = (String.IsNullOrEmpty(eo.OutputDirectory) ? Path.GetDirectoryName(file) : eo.OutputDirectory) + Path.DirectorySeparatorChar; using (var f = GMFile.GetFile(file)) { #region defaults if (!(eo.Disassemble || eo.String || eo.Variables || eo.Functions || eo.Audio || eo.Background || eo.Decompile || eo.Font || eo.General || eo.Object || eo.Options || eo.Path || eo.Room || eo.Script || eo.Sound || eo.Sprite || eo.Texture || eo.TPag || eo.ExportToProject || eo.Any || eo.DumpUnknownChunks)) { eo.Any = true; } if (eo.ExportToProject) { eo.Disassemble = eo.String = eo.Variables = eo.Functions = false; eo.Audio = eo.Background = eo.Decompile = eo.Font = eo.General = eo.Object = eo.Options = eo.Path = eo.Room = eo.Script = eo.Sound = eo.Sprite = eo.Texture = eo.TPag = eo.DumpUnknownChunks = true; } if (eo.Any) { eo.Disassemble = false; eo.Audio = eo.Background = eo.Decompile = eo.Font = eo.General = eo.Object = eo.Options = eo.Path = eo.Room = eo.Script = eo.Sound = eo.Sprite = eo.Texture = eo.TPag = eo.String = eo.Variables = eo.Functions = eo.DumpUnknownChunks = true; } #endregion // --- #region GEN8 if (eo.General) { if (!eo.Quiet) { Console.WriteLine("Exporting manifest file..."); } File.WriteAllText(od + "general.json", JsonMapper.ToJson(Serialize.SerializeGeneral(f.General))); } #endregion #region OPTN if (eo.Options) { if (!eo.Quiet) { Console.WriteLine("Exporting options..."); } File.WriteAllText(od + "options.json", JsonMapper.ToJson(Serialize.SerializeOptions(f.Options))); } #endregion #region STRG if (eo.String && f.Strings != null) { if (!eo.Quiet) { Console.WriteLine("Dumping strings..."); } File.WriteAllText(od + "strings.json", JsonMapper.ToJson(Serialize.SerializeStrings(f))); } #endregion #region VARI if (eo.Variables && f.RefData.Variables != null) { if (!eo.Quiet) { Console.WriteLine("Dumping variables..."); } File.WriteAllText(od + "variables.json", JsonMapper.ToJson(Serialize.SerializeVars(f))); } #endregion #region FUNC if (eo.Functions && f.RefData.Functions != null) { if (!eo.Quiet) { Console.WriteLine("Dumping functions..."); } File.WriteAllText(od + "functions.json", JsonMapper.ToJson(Serialize.SerializeFuncs(f))); } #endregion int cl = 0, ct = 0; #region TXTR if (eo.Texture && f.Textures != null) { if (!eo.Quiet) { Console.Write("Exporting texture sheets... "); if (!eo.NoPrecProg) { cl = Console.CursorLeft; ct = Console.CursorTop; } } if (!Directory.Exists(od + DIR_TEX)) { Directory.CreateDirectory(od + DIR_TEX); } for (int i = 0; i < f.Textures.Length; i++) { if (!eo.Quiet && !eo.NoPrecProg) { Console.SetCursorPosition(cl, ct); Console.WriteLine(O_PAREN + (i + 1) + SLASH + f.Textures.Length + C_PAREN); } File.WriteAllBytes(od + DIR_TEX + i + EXT_PNG, f.Textures[i].PngData); } } #endregion #region AUDO if (eo.Audio && f.Audio != null) { if (!eo.Quiet) { Console.Write("Exporting audio files... "); if (!eo.NoPrecProg) { cl = Console.CursorLeft; ct = Console.CursorTop; } } var infoTable = new Dictionary <int, SoundInfo>(); foreach (var s in f.Sound) { if ((s.IsEmbedded || s.IsCompressed) && s.AudioID != -1) { infoTable[s.AudioID] = s; } } if (!Directory.Exists(od + DIR_WAV)) { Directory.CreateDirectory(od + DIR_WAV); } for (int i = 0; i < f.Audio.Length; i++) { if (!eo.Quiet && !eo.NoPrecProg) { Console.SetCursorPosition(cl, ct); Console.WriteLine(O_PAREN + (i + 1) + SLASH + f.Audio.Length + C_PAREN); } File.WriteAllBytes(od + DIR_WAV + infoTable[i].Name + SR.EXT_WAV, f.Audio[i].Wave); } } #endregion #region CODE if (eo.Decompile && f.Code != null) { if (!eo.Quiet) { Console.Write("Decompiling code... "); if (!eo.NoPrecProg) { cl = Console.CursorLeft; ct = Console.CursorTop; } } if (!Directory.Exists(od + DIR_CODE)) { Directory.CreateDirectory(od + DIR_CODE); } for (int i = 0; i < f.Code.Length; i++) { if (!eo.Quiet && !eo.NoPrecProg) { Console.SetCursorPosition(cl, ct); Console.WriteLine(O_PAREN + (i + 1) + SLASH + f.Code.Length + C_PAREN); } try { File.WriteAllText(od + DIR_CODE + f.Code[i].Name + EXT_GML_LSP, Decompiler.DecompileCode(f, i, eo.AbsoluteAddresses)); } catch (Exception e) { Console.Error.WriteLine($"Error: Failed to decompile {f.Code[i].Name}, ignoring..."); } } } if (eo.Disassemble && f.Code != null) { if (!eo.Quiet) { Console.Write("Disassembling bytecode... "); if (!eo.NoPrecProg) { cl = Console.CursorLeft; ct = Console.CursorTop; } } if (!Directory.Exists(od + DIR_CODE)) { Directory.CreateDirectory(od + DIR_CODE); } for (int i = 0; i < f.Code.Length; i++) { if (!eo.Quiet && !eo.NoPrecProg) { Console.SetCursorPosition(cl, ct); Console.WriteLine(O_PAREN + (i + 1) + SLASH + f.Code.Length + C_PAREN); } File.WriteAllText(od + DIR_CODE + f.Code[i].Name + EXT_GML_ASM, Disassembler.DisplayInstructions(f, i, eo.AbsoluteAddresses)); } } #endregion #region SCPT if (eo.Script && f.Scripts != null && f.Code != null) { if (!eo.Quiet) { Console.Write("Exporting scripts... "); if (!eo.NoPrecProg) { cl = Console.CursorLeft; ct = Console.CursorTop; } } if (!Directory.Exists(od + DIR_SCR)) { Directory.CreateDirectory(od + DIR_SCR); } for (int i = 0; i < f.Scripts.Length; i++) { if (!eo.Quiet && !eo.NoPrecProg) { Console.SetCursorPosition(cl, ct); Console.WriteLine(O_PAREN + (i + 1) + SLASH + f.Scripts.Length + C_PAREN); } File.WriteAllText(od + DIR_SCR + f.Scripts[i].Name + EXT_JSON, JsonMapper.ToJson(Serialize.SerializeScript(f.Scripts[i], f.Code))); } } #endregion #region TPAG if (eo.TPag && f.TexturePages != null) { if (!eo.Quiet) { Console.Write("Exporting texture maps... "); if (!eo.NoPrecProg) { cl = Console.CursorLeft; ct = Console.CursorTop; } } if (!Directory.Exists(od + DIR_TXP)) { Directory.CreateDirectory(od + DIR_TXP); } for (int i = 0; i < f.TexturePages.Length; i++) { Console.SetCursorPosition(cl, ct); Console.WriteLine(O_PAREN + (i + 1) + SLASH + f.TexturePages.Length + C_PAREN); File.WriteAllText(od + DIR_TXP + i + EXT_JSON, JsonMapper.ToJson(Serialize.SerializeTPag(f.TexturePages[i]))); } } #endregion #region SPRT if (eo.Sprite && f.Sprites != null) { if (!eo.Quiet) { Console.Write("Exporting sprites... "); if (!eo.NoPrecProg) { cl = Console.CursorLeft; ct = Console.CursorTop; } } if (!Directory.Exists(od + DIR_SPR)) { Directory.CreateDirectory(od + DIR_SPR); } for (int i = 0; i < f.Sprites.Length; i++) { if (!eo.Quiet && !eo.NoPrecProg) { Console.SetCursorPosition(cl, ct); Console.WriteLine(O_PAREN + (i + 1) + SLASH + f.Sprites.Length + C_PAREN); } File.WriteAllText(od + DIR_SPR + f.Sprites[i].Name + EXT_JSON, JsonMapper.ToJson(Serialize.SerializeSprite(f.Sprites[i]))); } } #endregion #region SOND if (eo.Sound && f.Sound != null) { if (!eo.Quiet) { Console.Write("Exporting sounds... "); if (!eo.NoPrecProg) { cl = Console.CursorLeft; ct = Console.CursorTop; } } if (!Directory.Exists(od + DIR_SND)) { Directory.CreateDirectory(od + DIR_SND); } for (int i = 0; i < f.Sound.Length; i++) { if (!eo.Quiet && !eo.NoPrecProg) { Console.SetCursorPosition(cl, ct); Console.WriteLine(O_PAREN + (i + 1) + SLASH + f.Sound.Length + C_PAREN); } File.WriteAllText(od + DIR_SND + f.Sound[i].Name + EXT_JSON, JsonMapper.ToJson(Serialize.SerializeSound(f.Sound[i]))); } } #endregion #region OBJT if (eo.Object && f.Objects != null && f.Sprites != null) { if (!eo.Quiet) { Console.Write("Exporting objects... "); if (!eo.NoPrecProg) { cl = Console.CursorLeft; ct = Console.CursorTop; } } if (!Directory.Exists(od + DIR_OBJ)) { Directory.CreateDirectory(od + DIR_OBJ); } for (int i = 0; i < f.Objects.Length; i++) { if (!eo.Quiet && !eo.NoPrecProg) { Console.SetCursorPosition(cl, ct); Console.WriteLine(O_PAREN + (i + 1) + SLASH + f.Objects.Length + C_PAREN); } File.WriteAllText(od + DIR_OBJ + f.Objects[i].Name + EXT_JSON, JsonMapper.ToJson(Serialize.SerializeObj(f.Objects[i], f.Sprites, f.Objects))); } } #endregion #region BGND if (eo.Background && f.Backgrounds != null) { if (!eo.Quiet) { Console.Write("Exporting backgrounds... "); if (!eo.NoPrecProg) { cl = Console.CursorLeft; ct = Console.CursorTop; } } if (!Directory.Exists(od + DIR_BG)) { Directory.CreateDirectory(od + DIR_BG); } for (int i = 0; i < f.Backgrounds.Length; i++) { if (!eo.Quiet && !eo.NoPrecProg) { Console.SetCursorPosition(cl, ct); Console.WriteLine(O_PAREN + (i + 1) + SLASH + f.Backgrounds.Length + C_PAREN); } File.WriteAllText(od + DIR_BG + f.Backgrounds[i].Name + EXT_JSON, JsonMapper.ToJson(Serialize.SerializeBg(f.Backgrounds[i]))); } } #endregion #region ROOM if (eo.Room && f.Rooms != null) { if (!eo.Quiet) { Console.Write("Exporting rooms... "); if (!eo.NoPrecProg) { cl = Console.CursorLeft; ct = Console.CursorTop; } } if (!Directory.Exists(od + DIR_ROOM)) { Directory.CreateDirectory(od + DIR_ROOM); } for (int i = 0; i < f.Rooms.Length; i++) { if (!eo.Quiet && !eo.NoPrecProg) { Console.SetCursorPosition(cl, ct); Console.WriteLine(O_PAREN + (i + 1) + SLASH + f.Rooms.Length + C_PAREN); } File.WriteAllText(od + DIR_ROOM + f.Rooms[i].Name + EXT_JSON, JsonMapper.ToJson(Serialize.SerializeRoom(f.Rooms[i], f.Backgrounds, f.Objects))); } } #endregion #region FONT if (eo.Background && f.Fonts != null) { if (!eo.Quiet) { Console.Write("Exporting fonts... "); if (!eo.NoPrecProg) { cl = Console.CursorLeft; ct = Console.CursorTop; } } if (!Directory.Exists(od + DIR_FNT)) { Directory.CreateDirectory(od + DIR_FNT); } for (int i = 0; i < f.Fonts.Length; i++) { if (!eo.Quiet && !eo.NoPrecProg) { Console.SetCursorPosition(cl, ct); Console.WriteLine(O_PAREN + (i + 1) + SLASH + f.Fonts.Length + C_PAREN); } File.WriteAllText(od + DIR_FNT + f.Fonts[i].CodeName + EXT_JSON, JsonMapper.ToJson(Serialize.SerializeFont(f.Fonts[i]))); } } #endregion #region PATH if (eo.Path && f.Paths != null) { if (!eo.Quiet) { Console.Write("Exporting paths... "); if (!eo.NoPrecProg) { cl = Console.CursorLeft; ct = Console.CursorTop; } } if (!Directory.Exists(od + DIR_PATH)) { Directory.CreateDirectory(od + DIR_PATH); } for (int i = 0; i < f.Paths.Length; i++) { if (!eo.Quiet && !eo.NoPrecProg) { Console.SetCursorPosition(cl, ct); Console.WriteLine(O_PAREN + (i + 1) + SLASH + f.Paths.Length + C_PAREN); } File.WriteAllText(od + DIR_PATH + f.Paths[i].Name + EXT_JSON, JsonMapper.ToJson(Serialize.SerializePath(f.Paths[i]))); } } #endregion List <IntPtr> chunks = new List <IntPtr>(6); if (eo.DumpUnknownChunks || eo.DumpAllChunks) { Action <IntPtr> DumpUnk = _unk => { var unk = (SectionUnknown *)_unk; if (unk->IsEmpty() && !eo.DumpEmptyChunks) { return; } if (!eo.Quiet) { Console.WriteLine($"Dumping {unk->Header.MagicString()} chunk..."); } byte[] buf = new byte[unk->Header.Size]; uint * src = &unk->Unknown; ILHacks.Cpblk <byte>((void *)src, buf, 0, buf.Length); File.WriteAllBytes(od + unk->Header.MagicString() + EXT_BIN, buf); }; var c = f.Content; chunks.Add((IntPtr)c.Extensions); chunks.Add((IntPtr)c.AudioGroup); chunks.Add((IntPtr)c.Shaders); chunks.Add((IntPtr)c.Timelines); chunks.Add((IntPtr)c.DataFiles); chunks.Add((IntPtr)c.GNAL_Unk); if (eo.DumpAllChunks) { chunks.Add((IntPtr)c.General); chunks.Add((IntPtr)c.Options); chunks.Add((IntPtr)c.Sounds); chunks.Add((IntPtr)c.Sprites); chunks.Add((IntPtr)c.Backgrounds); chunks.Add((IntPtr)c.Paths); chunks.Add((IntPtr)c.Scripts); chunks.Add((IntPtr)c.Fonts); chunks.Add((IntPtr)c.Objects); chunks.Add((IntPtr)c.Rooms); chunks.Add((IntPtr)c.TexturePages); chunks.Add((IntPtr)c.Code); chunks.Add((IntPtr)c.Strings); chunks.Add((IntPtr)c.Textures); chunks.Add((IntPtr)c.Audio); chunks.Add((IntPtr)c.Functions); chunks.Add((IntPtr)c.Variables); } chunks = chunks.Where(cc => cc != IntPtr.Zero && !((SectionUnknown *)cc)->IsEmpty()).ToList(); for (int i = 0; i < chunks.Count; i++) { DumpUnk(chunks[i]); } } if (eo.ExportToProject) { if (!eo.Quiet) { Console.WriteLine("Emitting project file..."); } File.WriteAllText(od + f.General.Name + EXT_JSON, JsonMapper.ToJson(Serialize.SerializeProject(f, chunks))); } } }
static void Export(ExportOptions eo) { var file = Path.GetFullPath(String.IsNullOrEmpty(eo.File) ? DATA_WIN : eo.File); try // see #17 { int i = Console.CursorLeft; i = i-- + 1; } catch { eo.NoPrecProg = true; } if (Directory.Exists(file) && !File.Exists(file)) { file += Path.DirectorySeparatorChar + DATA_WIN; } if (!File.Exists(file)) { throw new ParserException("File \"" + file + "\" not found."); } var od = (String.IsNullOrEmpty(eo.OutputDirectory) ? Path.GetDirectoryName(file) : eo.OutputDirectory) + Path.DirectorySeparatorChar; if (!Directory.Exists(od)) { Directory.CreateDirectory(od); } using (var f = GMFile.GetFile(file)) { #region defaults if (!(eo.Disassemble || eo.String || eo.Variables || eo.Functions || eo.Audio || eo.Background || eo.Decompile || eo.Font || eo.General || eo.Object || eo.Options || eo.Path || eo.Room || eo.Script || eo.Sound || eo.Sprite || eo.Texture || eo.TPag || eo.AudioGroups || eo.Shader || eo.ExportToProject || eo.Any || eo.DumpUnknownChunks || eo.DumpEmptyChunks || eo.DumpAllChunks)) { eo.Any = true; } if (eo.ExportToProject) { eo.Disassemble = eo.String = eo.Variables = eo.Functions = eo.Audio = eo.Background = eo.Font = eo.General = eo.Object = eo.Options = eo.Path = eo.Room = eo.Script = eo.Sound = eo.Sprite = eo.Texture = eo.TPag = eo.AudioGroups = eo.Shader = eo.DumpUnknownChunks = true; } if (eo.Any) { eo.Disassemble = false; eo.Audio = eo.Background = eo.Decompile = eo.Font = eo.General = eo.Object = eo.Options = eo.Path = eo.Room = eo.Script = eo.Sound = eo.Sprite = eo.Texture = eo.TPag = eo.String = eo.Variables = eo.Functions = eo.DumpUnknownChunks = eo.AudioGroups = eo.Shader = true; } #endregion eos = eo; quiet = eo.Quiet; nopp = eo.NoPrecProg; // --- #region GEN8 if (eo.General && f.Content.General != null) { WriteLine("Exporting manifest file..."); File.WriteAllText(od + "general.json", JsonMapper.ToJson(Serialize.SerializeGeneral(f.General))); } #endregion #region OPTN if (eo.Options && f.Content.Options != null) { WriteLine("Exporting options..."); File.WriteAllText(od + "options.json", JsonMapper.ToJson(Serialize.SerializeOptions(f.Options))); } #endregion #region STRG if (eo.String && f.Strings != null) { WriteLine("Dumping strings..."); File.WriteAllText(od + "strings.json", JsonMapper.ToJson(Serialize.SerializeStrings(f))); } #endregion #region VARI if (eo.Variables && f.RefData.Variables != null) { WriteLine("Dumping variables..."); File.WriteAllText(od + "variables.json", JsonMapper.ToJson(Serialize.SerializeVars(f))); } #endregion #region FUNC if (eo.Functions && f.RefData.Functions != null) { WriteLine("Dumping functions..."); File.WriteAllText(od + "functions.json", JsonMapper.ToJson(Serialize.SerializeFuncs(f))); } #endregion int cl = 0, ct = 0; #region AGRP if (eo.AudioGroups && f.AudioGroups != null) { WriteLine("Dumping audio groups..."); File.WriteAllText(od + "audiogroups.json", JsonMapper.ToJson(Serialize.SerializeAudioGroups(f))); } if (eo.DetachedAgrp && f.AudioGroups != null) { WriteLine("Dumping audio from detached audio groups..."); for (int i = 1; i < f.AudioGroups.Length; ++i) { WrAndGetC(DASH_ + f.AudioGroups[i] + O_PAREN + i + SLASH + f.AudioGroups.Length + C_PAREN + SPACE_S, out cl, out ct); var agrpfn = Path.GetDirectoryName(file) + Path.DirectorySeparatorChar + AGRPF + i + D_DAT; if (!File.Exists(agrpfn)) { Console.Error.WriteLine("Eep: file '" + agrpfn + "' doesn't exist, skipping..."); continue; } var infoTable = new Dictionary <int, SoundInfo>(); for (uint iii = 0; iii < f.Sound.Length; ++iii) { var s = f.Sound[iii]; if ((s.IsEmbedded || s.IsCompressed) && s.AudioID != -1 && s.GroupID == i) { infoTable[s.AudioID] = s; } } var odgrp = od + DIR_AGRP + f.AudioGroups[i]; if (!Directory.Exists(odgrp)) { Directory.CreateDirectory(odgrp); } using (var af = GMFile.GetFile(agrpfn)) { for (int j = 0; j < af.Audio.Length; ++j) { SetCAndWr(cl, ct, O_PAREN + (j + 1) + SLASH + (af.Audio.Length - 1) + C_PAREN); File.WriteAllBytes(odgrp + Path.DirectorySeparatorChar + infoTable[j].Name + SR.EXT_WAV, af.Audio[j].Wave); } } Console.WriteLine(); } f.AudioGroups.Clear(); } #endregion #region TXTR MemoryStream[] txtrStreams = null; Bitmap [] txtrBitmaps = null; if (eo.Texture && f.Textures != null) { txtrStreams = new MemoryStream[f.Textures.Length]; txtrBitmaps = new Bitmap [f.Textures.Length]; WrAndGetC("Exporting texture sheets... ", out cl, out ct); if (!Directory.Exists(od + DIR_TEX)) { Directory.CreateDirectory(od + DIR_TEX); } for (int i = 0; i < f.Textures.Length; i++) { if (f.Textures[i].PngData == null) { continue; } using (var ms = new MemoryStream(f.Textures[i].PngData)) { txtrBitmaps[i] = new Bitmap(txtrStreams[i] = ms); } SetCAndWr(cl, ct, O_PAREN + (i + 1) + SLASH + f.Textures.Length + C_PAREN); File.WriteAllBytes(od + DIR_TEX + i + EXT_PNG, f.Textures[i].PngData); } Console.WriteLine(); f.Textures.Clear(); } #endregion #region AUDO if (eo.Audio && f.Audio != null) { WrAndGetC("Exporting audio files... ", out cl, out ct); var infoTable = new Dictionary <int, SoundInfo>(); foreach (var s in f.Sound) { if ((s.IsEmbedded || s.IsCompressed) && s.AudioID != -1 && s.GroupID == 0) // not from audiogroup$n.dat { infoTable[s.AudioID] = s; } } if (!Directory.Exists(od + DIR_WAV)) { Directory.CreateDirectory(od + DIR_WAV); } for (int i = 0; i < f.Audio.Length; i++) { SetCAndWr(cl, ct, O_PAREN + (i + 1) + SLASH + f.Audio.Length + C_PAREN); File.WriteAllBytes(od + DIR_WAV + infoTable[i].Name + SR.EXT_WAV, f.Audio[i].Wave); } Console.WriteLine(); f.Audio.Clear(); } #endregion #region CODE if (eo.Decompile && f.Code != null) { WrAndGetC("Decompiling code... ", out cl, out ct); if (!Directory.Exists(od + DIR_CODE)) { Directory.CreateDirectory(od + DIR_CODE); } for (int i = 0; i < f.Code.Length; i++) { SetCAndWr(cl, ct, O_PAREN + (i + 1) + SLASH + f.Code.Length + C_PAREN); try { File.WriteAllText(od + DIR_CODE + f.Code[i].Name + EXT_GML_LSP, Decompiler.DecompileCode(f, i, eo.AbsoluteAddresses)); } catch (Exception e) { Console.Error.WriteLine($"Error: Failed to decompile {f.Code[i].Name}, ignoring..."); #if DEBUG Console.Error.WriteLine(e); #endif } } Console.WriteLine(); } if (eo.Disassemble && f.Code != null) { WrAndGetC("Disassembling bytecode... ", out cl, out ct); if (!Directory.Exists(od + DIR_CODE)) { Directory.CreateDirectory(od + DIR_CODE); } for (int i = 0; i < f.Code.Length; i++) { SetCAndWr(cl, ct, O_PAREN + (i + 1) + SLASH + f.Code.Length + C_PAREN); File.WriteAllText(od + DIR_CODE + f.Code[i].Name + EXT_GML_ASM, Disassembler.DisplayInstructions(f, i, eo.AbsoluteAddresses)); /* * // Dump binary code to separate files. Useful for debugging de-/re-assembly/de-/re-compilation. * BinBuffer bb = new BinBuffer(); * for (uint j = 0; j < f.Code[i].Instructions.Length; j++) * { * var instr = f.Code[i].Instructions[j]; * var isize = DisasmExt.Size(instr, f.General.BytecodeVersion)*4; * * bb.Write((IntPtr)instr, (int)isize); * } * bb.Position = 0; * File.WriteAllBytes(od + DIR_CODE + f.Code[i].Name + EXT_BIN, bb.ReadBytes(bb.Size)); */ } Console.WriteLine(); } if (f.Code != null) { f.Code.Clear(); } #endregion #region SCPT if (eo.Script && f.Scripts != null && f.Code != null) { WrAndGetC("Exporting scripts... ", out cl, out ct); if (!Directory.Exists(od + DIR_SCR)) { Directory.CreateDirectory(od + DIR_SCR); } for (int i = 0; i < f.Scripts.Length; i++) { SetCAndWr(cl, ct, O_PAREN + (i + 1) + SLASH + f.Scripts.Length + C_PAREN); File.WriteAllText(od + DIR_SCR + f.Scripts[i].Name + EXT_JSON, JsonMapper.ToJson(Serialize.SerializeScript(f.Scripts[i], f.Code))); } Console.WriteLine(); f.Scripts.Clear(); } #endregion #region TPAG Bitmap[] tpagBitmaps = null; if (eo.TPag && f.TexturePages != null) { tpagBitmaps = new Bitmap[f.TexturePages.Length]; WrAndGetC("Exporting texture maps... ", out cl, out ct); if (!Directory.Exists(od + DIR_TXP)) { Directory.CreateDirectory(od + DIR_TXP); } for (int i = 0; i < f.TexturePages.Length; i++) { SetCAndWr(cl, ct, O_PAREN + (i + 1) + SLASH + f.TexturePages.Length + C_PAREN); var tpag = f.TexturePages[i]; File.WriteAllText(od + DIR_TXP + i + EXT_JSON, JsonMapper.ToJson(Serialize.SerializeTPag(tpag))); var bc = txtrBitmaps[tpag.SpritesheetId] .Clone(new GDIRectangle(tpag.Source.X, tpag.Source.Y, tpag.Source.Width, tpag.Source.Height), PixelFormat.DontCare); tpagBitmaps[i] = bc; if (eo.DumpTPagPNGs) { bc.Save(od + DIR_TXP + i + EXT_PNG); } } Console.WriteLine(); f.TexturePages.Clear(); } #endregion #region SPRT if (eo.Sprite && f.Sprites != null) { WrAndGetC("Exporting sprites... ", out cl, out ct); if (!Directory.Exists(od + DIR_SPR)) { Directory.CreateDirectory(od + DIR_SPR); } for (int i = 0; i < f.Sprites.Length; i++) { SetCAndWr(cl, ct, O_PAREN + (i + 1) + SLASH + f.Sprites.Length + C_PAREN); File.WriteAllText(od + DIR_SPR + f.Sprites[i].Name + EXT_JSON, JsonMapper.ToJson(Serialize.SerializeSprite(f.Sprites[i]))); if (eo.DumpSpritePNGs) { for (int j = 0; j < f.Sprites[i].TextureIndices.Length; ++j) { uint id = f.Sprites[i].TextureIndices[j]; tpagBitmaps[id].Save(od + DIR_SPR + f.Sprites[i].Name + UNDERSCORE + j + EXT_PNG); } } } Console.WriteLine(); f.Sprites.Clear(); } #endregion #region SOND if (eo.Sound && f.Sound != null) { WrAndGetC("Exporting sounds... ", out cl, out ct); if (!Directory.Exists(od + DIR_SND)) { Directory.CreateDirectory(od + DIR_SND); } for (int i = 0; i < f.Sound.Length; i++) { SetCAndWr(cl, ct, O_PAREN + (i + 1) + SLASH + f.Sound.Length + C_PAREN); File.WriteAllText(od + DIR_SND + f.Sound[i].Name + EXT_JSON, JsonMapper.ToJson(Serialize.SerializeSound(f.Sound[i]))); } Console.WriteLine(); f.Sound.Clear(); } #endregion #region OBJT if (eo.Object && f.Objects != null && f.Sprites != null) { WrAndGetC("Exporting objects... ", out cl, out ct); if (!Directory.Exists(od + DIR_OBJ)) { Directory.CreateDirectory(od + DIR_OBJ); } for (int i = 0; i < f.Objects.Length; i++) { SetCAndWr(cl, ct, O_PAREN + (i + 1) + SLASH + f.Objects.Length + C_PAREN); File.WriteAllText(od + DIR_OBJ + f.Objects[i].Name + EXT_JSON, JsonMapper.ToJson(Serialize.SerializeObj(f.Objects[i], f.Sprites, f.Objects))); } Console.WriteLine(); } #endregion #region BGND if (eo.Background && f.Backgrounds != null) { WrAndGetC("Exporting backgrounds... ", out cl, out ct); if (!Directory.Exists(od + DIR_BG)) { Directory.CreateDirectory(od + DIR_BG); } for (int i = 0; i < f.Backgrounds.Length; i++) { SetCAndWr(cl, ct, O_PAREN + (i + 1) + SLASH + f.Backgrounds.Length + C_PAREN); File.WriteAllText(od + DIR_BG + f.Backgrounds[i].Name + EXT_JSON, JsonMapper.ToJson(Serialize.SerializeBg(f.Backgrounds[i]))); } Console.WriteLine(); } #endregion #region ROOM if (eo.Room && f.Rooms != null) { WrAndGetC("Exporting rooms... ", out cl, out ct); if (!Directory.Exists(od + DIR_ROOM)) { Directory.CreateDirectory(od + DIR_ROOM); } for (int i = 0; i < f.Rooms.Length; i++) { SetCAndWr(cl, ct, O_PAREN + (i + 1) + SLASH + f.Rooms.Length + C_PAREN); File.WriteAllText(od + DIR_ROOM + f.Rooms[i].Name + EXT_JSON, JsonMapper.ToJson(Serialize.SerializeRoom(f.Rooms[i], f.Backgrounds, f.Objects))); } Console.WriteLine(); } if (f.Backgrounds != null) { f.Backgrounds.Clear(); } if (f.Objects != null) { f.Objects.Clear(); } if (f.Rooms != null) { f.Rooms.Clear(); } #endregion #region FONT if (eo.Font && f.Fonts != null) { WrAndGetC("Exporting fonts... ", out cl, out ct); if (!Directory.Exists(od + DIR_FNT)) { Directory.CreateDirectory(od + DIR_FNT); } for (int i = 0; i < f.Fonts.Length; i++) { SetCAndWr(cl, ct, O_PAREN + (i + 1) + SLASH + f.Fonts.Length + C_PAREN); File.WriteAllText(od + DIR_FNT + f.Fonts[i].CodeName + EXT_JSON, JsonMapper.ToJson(Serialize.SerializeFont(f.Fonts[i]))); } Console.WriteLine(); f.Fonts.Clear(); } #endregion #region PATH if (eo.Path && f.Paths != null) { WrAndGetC("Exporting paths... ", out cl, out ct); if (!Directory.Exists(od + DIR_PATH)) { Directory.CreateDirectory(od + DIR_PATH); } for (int i = 0; i < f.Paths.Length; i++) { SetCAndWr(cl, ct, O_PAREN + (i + 1) + SLASH + f.Paths.Length + C_PAREN); File.WriteAllText(od + DIR_PATH + f.Paths[i].Name + EXT_JSON, JsonMapper.ToJson(Serialize.SerializePath(f.Paths[i]))); } Console.WriteLine(); f.Paths.Clear(); } #endregion #region SHDR if (eo.Shader && f.Shaders != null) { WrAndGetC("Exporting shaders... ", out cl, out ct); if (!Directory.Exists(od + DIR_SHDR)) { Directory.CreateDirectory(od + DIR_SHDR); } for (int i = 0; i < f.Shaders.Length; i++) { SetCAndWr(cl, ct, O_PAREN + (i + 1) + SLASH + f.Shaders.Length + C_PAREN); File.WriteAllText(od + DIR_SHDR + f.Shaders[i].Name + EXT_JSON, JsonMapper.ToJson(Serialize.SerializeShader(f.Shaders[i]))); } Console.WriteLine(); } #endregion List <IntPtr> chunks = null; if (eo.DumpUnknownChunks || eo.DumpAllChunks) { chunks = new List <IntPtr>(6); Action <IntPtr> DumpUnk = _unk => { var unk = (SectionUnknown *)_unk; if (unk == null || (unk->IsEmpty() && !eo.DumpEmptyChunks)) { return; } WriteLine($"Dumping {unk->Header.MagicString()} chunk..."); var len = unk->Header.Size; byte[] buf = new byte[len]; uint * src = &unk->Unknown; if (len != 0) { ILHacks.Cpblk <byte>((void *)src, buf, 0, (int)len); } File.WriteAllBytes(od + unk->Header.MagicString() + EXT_BIN, buf); }; var c = f.Content; if (eo.DumpAllChunks) { chunks.AddRange(c.Chunks.Values); } // TODO: how to filter out unknowns? for (int i = 0; i < chunks.Count; i++) { DumpUnk(chunks[i]); } } if (eo.ExportToProject) { WriteLine("Emitting project file..."); File.WriteAllText(od + f.General.Name + EXT_JSON, JsonMapper.ToJson(Serialize.SerializeProject(f, eo, chunks))); } if (tpagBitmaps != null) { for (int i = 0; i < tpagBitmaps.Length; ++i) { tpagBitmaps[i].Dispose(); } } if (txtrStreams != null) { for (int i = 0; i < txtrStreams.Length; ++i) { txtrBitmaps[i].Dispose(); txtrStreams[i].Dispose(); } } } }
public static byte[] WriteFile(string baseDir, JsonData projFile, GMFile f) { Console.WriteLine($"Preparing strings..."); var stringsChunkBuilder = new StringsChunkBuilder(); stringsChunkBuilder.AddStrings(f.Strings); var texpChunk = new BBData(new BinBuffer(), new int[0]); Console.WriteLine($"Preparing textures..."); int[] texPagOffsets = SectionWriter.WriteTexturePages(texpChunk, f.TexturePages); var codeChunk = new BBData(new BinBuffer(), new int[0]); Console.WriteLine($"Preparing code..."); var codeChunkStringOffsetOffsets = Assembler.WriteCodes(codeChunk, f, stringsChunkBuilder); var offsets = new int[0]; BBData writer = new BBData(new BinBuffer(), offsets); writer.Buffer.Write(SectionHeaders.Form); writer.Buffer.Write(0); var stringOffsetOffsets = new List <int>(); int stringsDataPosition = 0; var texpOffsetOffsets = new List <int>(); int texpChunkPosition = 0; var codeOffsetOffsets = new List <int>(); int codeChunkPosition = 0; foreach (SectionHeaders chunkId in f.ChunkOrder) { Console.WriteLine($"Writing {chunkId}..."); BBData chunk = new BBData(new BinBuffer(), new int[0]); int[] chunkStringOffsetOffsets = null; int[] chunkTexpOffsetOffsets = null; int[] chunkCodeOffsetOffsets = null; switch (chunkId) { case SectionHeaders.General: chunkStringOffsetOffsets = SectionWriter.WriteGeneral(chunk, f.General, f.Rooms, stringsChunkBuilder); break; case SectionHeaders.Options: chunkStringOffsetOffsets = SectionWriter.WriteOptions(chunk, f.Options, stringsChunkBuilder); break; case SectionHeaders.Sounds: chunkStringOffsetOffsets = SectionWriter.WriteSounds(chunk, f.Sound, stringsChunkBuilder, f.AudioGroups); break; case SectionHeaders.AudioGroup: chunkStringOffsetOffsets = SectionWriter.WriteAudioGroups(chunk, f.AudioGroups, stringsChunkBuilder); break; case SectionHeaders.Sprites: SectionWriter.WriteSprites(chunk, f.Sprites, stringsChunkBuilder, texPagOffsets, out chunkStringOffsetOffsets, out chunkTexpOffsetOffsets); break; case SectionHeaders.Backgrounds: SectionWriter.WriteBackgrounds(chunk, f.Backgrounds, stringsChunkBuilder, texPagOffsets, out chunkStringOffsetOffsets, out chunkTexpOffsetOffsets); break; case SectionHeaders.Paths: chunkStringOffsetOffsets = SectionWriter.WritePaths(chunk, f.Paths, stringsChunkBuilder); break; case SectionHeaders.Scripts: chunkStringOffsetOffsets = SectionWriter.WriteScripts(chunk, f.Scripts, stringsChunkBuilder); break; case SectionHeaders.Fonts: SectionWriter.WriteFonts(chunk, f.Fonts, stringsChunkBuilder, texPagOffsets, out chunkStringOffsetOffsets, out chunkTexpOffsetOffsets); break; case SectionHeaders.Objects: chunkStringOffsetOffsets = SectionWriter.WriteObjects(chunk, f.Objects, stringsChunkBuilder); break; case SectionHeaders.Rooms: chunkStringOffsetOffsets = SectionWriter.WriteRooms(chunk, f.Rooms, stringsChunkBuilder); break; case SectionHeaders.TexturePage: chunk = texpChunk; texpChunkPosition = writer.Buffer.Position + 8; break; case SectionHeaders.Code: chunk = codeChunk; chunkStringOffsetOffsets = codeChunkStringOffsetOffsets; codeChunkPosition = writer.Buffer.Position + 8; break; case SectionHeaders.Variables: if (f.VariableExtra != null) { foreach (var e in f.VariableExtra) { chunk.Buffer.Write(e); } } SectionWriter.WriteRefDefs(chunk, f.RefData.Variables, stringsChunkBuilder, f.General.IsOldBCVersion, false, out chunkStringOffsetOffsets, out chunkCodeOffsetOffsets); break; case SectionHeaders.Functions: SectionWriter.WriteRefDefs(chunk, f.RefData.Functions, stringsChunkBuilder, f.General.IsOldBCVersion, true, out chunkStringOffsetOffsets, out chunkCodeOffsetOffsets); chunkStringOffsetOffsets = chunkStringOffsetOffsets.Concat(SectionWriter.WriteFunctionLocals(chunk, f.FunctionLocals, stringsChunkBuilder)).ToArray(); break; case SectionHeaders.Strings: var stringOffsets = stringsChunkBuilder.WriteStringsChunk(chunk); stringsDataPosition = writer.Buffer.Position + stringOffsets[0] + 12; // for Textures chunk up next SectionWriter.Pad(chunk, 0x80, writer.Buffer.Position + 8); break; case SectionHeaders.Textures: SectionWriter.WriteTextures(chunk, f.Textures); break; case SectionHeaders.Audio: SectionWriter.WriteAudio(chunk, f.Audio, writer.Buffer.Position); break; case SectionHeaders.Shaders: chunkStringOffsetOffsets = SectionWriter.WriteShaders(chunk, f.Shaders, stringsChunkBuilder); break; default: var chunkName = chunkId.ToChunkName(); Console.Error.WriteLine($"Note: Don't know how to handle {chunkName}"); string chunkFile = null; if (projFile.Has("chunks") && projFile["chunks"].IsArray) { foreach (JsonData jd in projFile["chunks"]) { if (jd.IsString) { if (Path.GetFileNameWithoutExtension((string)jd) == chunkName) { chunkFile = (string)jd; break; } } } } BinBuffer chunkData; if (chunkFile == null) { Console.Error.WriteLine($"Note: Chunk {chunkName} was not dumped, assuming it's empty"); chunkData = new BinBuffer(); } else { Console.Error.WriteLine($"Note: Loading {chunkName} from dump"); try { chunkData = new BinBuffer(File.ReadAllBytes(Path.Combine(baseDir, chunkFile))); } catch (Exception e) { Console.Error.WriteLine($"Error loading {chunkName}, using empty"); Console.Error.WriteLine(e); chunkData = new BinBuffer(); } } chunk = new BBData(chunkData, new int[0]); break; } if (chunkStringOffsetOffsets != null) { foreach (var offset in chunkStringOffsetOffsets) { stringOffsetOffsets.Add(offset + writer.Buffer.Position); } } chunkStringOffsetOffsets = null; if (chunkTexpOffsetOffsets != null) { foreach (var offset in chunkTexpOffsetOffsets) { texpOffsetOffsets.Add(offset + writer.Buffer.Position); } } chunkTexpOffsetOffsets = null; if (chunkCodeOffsetOffsets != null) { foreach (var offset in chunkCodeOffsetOffsets) { codeOffsetOffsets.Add(offset + writer.Buffer.Position); } } chunkCodeOffsetOffsets = null; SectionWriter.WriteChunk(writer, chunkId, chunk); } writer.Buffer.Position = 4; writer.Buffer.Write(writer.Buffer.Size - 8); writer.Buffer.Position = writer.Buffer.Size; foreach (var stringOffset in stringOffsetOffsets) { writer.Buffer.Position = stringOffset; var o = writer.Buffer.ReadInt32(); //bb.Position -= sizeof(int); writer.Buffer.Write(o + stringsDataPosition); } foreach (var texpOffset in texpOffsetOffsets) { writer.Buffer.Position = texpOffset; var o = writer.Buffer.ReadInt32(); //bb.Position -= sizeof(int); writer.Buffer.Write(o + texpChunkPosition); } foreach (var codeOffset in codeOffsetOffsets) { writer.Buffer.Position = codeOffset; var o = writer.Buffer.ReadInt32(); //bb.Position -= sizeof(int); writer.Buffer.Write(o + codeChunkPosition); } writer.Buffer.Position = 0; return(writer.Buffer.ReadBytes(writer.Buffer.Size)); }
static void Export(ExportOptions eo) { var file = Path.GetFullPath(String.IsNullOrEmpty(eo.File) ? DATA_WIN : eo.File); if (Directory.Exists(file) && !File.Exists(file)) { file += Path.DirectorySeparatorChar + DATA_WIN; } if (!File.Exists(file)) { throw new ParserException("File \"" + file + "\" not found."); } var od = (String.IsNullOrEmpty(eo.OutputDirectory) ? Path.GetDirectoryName(file) : eo.OutputDirectory) + Path.DirectorySeparatorChar; using (var f = GMFile.GetFile(file)) { #region defaults if (!(eo.Disassemble || eo.String || eo.Variables || eo.Functions || eo.Audio || eo.Background || eo.Decompile || eo.Font || eo.General || eo.Object || eo.Options || eo.Path || eo.Room || eo.Script || eo.Sound || eo.Sprite || eo.Texture || eo.TPag || eo.ExportToProject || eo.Any)) { eo.Any = true; } if (eo.ExportToProject) { eo.Disassemble = eo.String = eo.Variables = eo.Functions = false; eo.Audio = eo.Background = eo.Decompile = eo.Font = eo.General = eo.Object = eo.Options = eo.Path = eo.Room = eo.Script = eo.Sound = eo.Sprite = eo.Texture = eo.TPag = true; } if (eo.Any) { eo.Disassemble = false; eo.Audio = eo.Background = eo.Decompile = eo.Font = eo.General = eo.Object = eo.Options = eo.Path = eo.Room = eo.Script = eo.Sound = eo.Sprite = eo.Texture = eo.TPag = eo.String = eo.Variables = eo.Functions = true; } #endregion // --- #region GEN8 if (eo.General) { Console.WriteLine("Exporting manifest file..."); File.WriteAllText(od + "general.json", JsonMapper.ToJson(Serialize.SerializeGeneral(f.General))); } #endregion #region OPTN if (eo.Options) { Console.WriteLine("Exporting options..."); File.WriteAllText(od + "options.json", JsonMapper.ToJson(Serialize.SerializeOptions(f.Options))); } #endregion #region STRG if (eo.String) { Console.WriteLine("Dumping strings..."); File.WriteAllText(od + "strings.json", JsonMapper.ToJson(Serialize.SerializeStrings(f))); } #endregion #region VARI if (eo.Variables) { Console.WriteLine("Dumping variables..."); File.WriteAllText(od + "variables.json", JsonMapper.ToJson(Serialize.SerializeVars(f))); } #endregion #region FUNC if (eo.Functions) { Console.WriteLine("Dumping functions..."); File.WriteAllText(od + "functions.json", JsonMapper.ToJson(Serialize.SerializeFuncs(f))); } #endregion #region TXTR if (eo.Texture) { Console.Write("Exporting texture sheets... "); var cl = Console.CursorLeft; var ct = Console.CursorTop; if (!Directory.Exists(od + DIR_TEX)) { Directory.CreateDirectory(od + DIR_TEX); } for (int i = 0; i < f.Textures.Length; i++) { Console.SetCursorPosition(cl, ct); Console.WriteLine(O_PAREN + (i + 1) + SLASH + f.Textures.Length + C_PAREN); File.WriteAllBytes(od + DIR_TEX + i + EXT_PNG, f.Textures[i].PngData); } } #endregion #region AUDO if (eo.Audio) { Console.Write("Exporting audio files... "); var cl = Console.CursorLeft; var ct = Console.CursorTop; var infoTable = new Dictionary <int, SoundInfo>(); foreach (var s in f.Sound) { if ((s.IsEmbedded || s.IsCompressed) && s.AudioId != -1) { infoTable[s.AudioId] = s; } } if (!Directory.Exists(od + DIR_WAV)) { Directory.CreateDirectory(od + DIR_WAV); } for (int i = 0; i < f.Audio.Length; i++) { Console.SetCursorPosition(cl, ct); Console.WriteLine(O_PAREN + (i + 1) + SLASH + f.Audio.Length + C_PAREN); File.WriteAllBytes(od + DIR_WAV + infoTable[i].Name + SR.EXT_WAV, f.Audio[i].Wave); } } #endregion #region CODE if (eo.Decompile) { Console.Write("Decompiling code... "); var cl = Console.CursorLeft; var ct = Console.CursorTop; if (!Directory.Exists(od + DIR_CODE)) { Directory.CreateDirectory(od + DIR_CODE); } for (int i = 0; i < f.Code.Length; i++) { Console.SetCursorPosition(cl, ct); Console.WriteLine(O_PAREN + (i + 1) + SLASH + f.Code.Length + C_PAREN); File.WriteAllText(od + DIR_CODE + f.Code[i].Name + EXT_GML_LSP, Decompiler.DecompileCode(f, i, eo.AbsoluteAddresses)); } } if (eo.Disassemble) { Console.Write("Disassembling bytecode... "); var cl = Console.CursorLeft; var ct = Console.CursorTop; if (!Directory.Exists(od + DIR_CODE)) { Directory.CreateDirectory(od + DIR_CODE); } for (int i = 0; i < f.Code.Length; i++) { Console.SetCursorPosition(cl, ct); Console.WriteLine(O_PAREN + (i + 1) + SLASH + f.Code.Length + C_PAREN); File.WriteAllText(od + DIR_CODE + f.Code[i].Name + EXT_GML_ASM, Disassembler.DisplayInstructions(f, i, eo.AbsoluteAddresses)); } } #endregion #region SCPT if (eo.Script) { Console.Write("Exporting scripts... "); var cl = Console.CursorLeft; var ct = Console.CursorTop; if (!Directory.Exists(od + DIR_SCR)) { Directory.CreateDirectory(od + DIR_SCR); } for (int i = 0; i < f.Scripts.Length; i++) { Console.SetCursorPosition(cl, ct); Console.WriteLine(O_PAREN + (i + 1) + SLASH + f.Scripts.Length + C_PAREN); File.WriteAllText(od + DIR_SCR + f.Scripts[i].Name + EXT_JSON, JsonMapper.ToJson(Serialize.SerializeScript(f.Scripts[i], f.Code))); } } #endregion #region TPAG if (eo.TPag) { Console.Write("Exporting texture maps... "); var cl = Console.CursorLeft; var ct = Console.CursorTop; if (!Directory.Exists(od + DIR_TXP)) { Directory.CreateDirectory(od + DIR_TXP); } for (int i = 0; i < f.TexturePages.Length; i++) { Console.SetCursorPosition(cl, ct); Console.WriteLine(O_PAREN + (i + 1) + SLASH + f.TexturePages.Length + C_PAREN); File.WriteAllText(od + DIR_TXP + i + EXT_JSON, JsonMapper.ToJson(Serialize.SerializeTPag(f.TexturePages[i]))); } } #endregion #region SPRT if (eo.Sprite) { Console.Write("Exporting sprites... "); var cl = Console.CursorLeft; var ct = Console.CursorTop; if (!Directory.Exists(od + DIR_SPR)) { Directory.CreateDirectory(od + DIR_SPR); } for (int i = 0; i < f.Sprites.Length; i++) { Console.SetCursorPosition(cl, ct); Console.WriteLine(O_PAREN + (i + 1) + SLASH + f.Sprites.Length + C_PAREN); File.WriteAllText(od + DIR_SPR + f.Sprites[i].Name + EXT_JSON, JsonMapper.ToJson(Serialize.SerializeSprite(f.Sprites[i]))); } } #endregion #region SOND if (eo.Sound) { Console.Write("Exporting sounds... "); var cl = Console.CursorLeft; var ct = Console.CursorTop; if (!Directory.Exists(od + DIR_SND)) { Directory.CreateDirectory(od + DIR_SND); } for (int i = 0; i < f.Sound.Length; i++) { Console.SetCursorPosition(cl, ct); Console.WriteLine(O_PAREN + (i + 1) + SLASH + f.Sound.Length + C_PAREN); File.WriteAllText(od + DIR_SND + f.Sound[i].Name + EXT_JSON, JsonMapper.ToJson(Serialize.SerializeSound(f.Sound[i]))); } } #endregion #region OBJT if (eo.Object) { Console.Write("Exporting objects... "); var cl = Console.CursorLeft; var ct = Console.CursorTop; if (!Directory.Exists(od + DIR_OBJ)) { Directory.CreateDirectory(od + DIR_OBJ); } for (int i = 0; i < f.Objects.Length; i++) { Console.SetCursorPosition(cl, ct); Console.WriteLine(O_PAREN + (i + 1) + SLASH + f.Objects.Length + C_PAREN); File.WriteAllText(od + DIR_OBJ + f.Objects[i].Name + EXT_JSON, JsonMapper.ToJson(Serialize.SerializeObj(f.Objects[i], f.Sprites, f.Objects))); } } #endregion #region BGND if (eo.Background) { Console.Write("Exporting backgrounds... "); var cl = Console.CursorLeft; var ct = Console.CursorTop; if (!Directory.Exists(od + DIR_BG)) { Directory.CreateDirectory(od + DIR_BG); } for (int i = 0; i < f.Backgrounds.Length; i++) { Console.SetCursorPosition(cl, ct); Console.WriteLine(O_PAREN + (i + 1) + SLASH + f.Backgrounds.Length + C_PAREN); File.WriteAllText(od + DIR_BG + f.Backgrounds[i].Name + EXT_JSON, JsonMapper.ToJson(Serialize.SerializeBg(f.Backgrounds[i]))); } } #endregion #region ROOM if (eo.Room) { Console.Write("Exporting rooms... "); var cl = Console.CursorLeft; var ct = Console.CursorTop; if (!Directory.Exists(od + DIR_ROOM)) { Directory.CreateDirectory(od + DIR_ROOM); } for (int i = 0; i < f.Rooms.Length; i++) { Console.SetCursorPosition(cl, ct); Console.WriteLine(O_PAREN + (i + 1) + SLASH + f.Rooms.Length + C_PAREN); File.WriteAllText(od + DIR_ROOM + f.Rooms[i].Name + EXT_JSON, JsonMapper.ToJson(Serialize.SerializeRoom(f.Rooms[i], f.Backgrounds, f.Objects))); } } #endregion #region FONT if (eo.Background) { Console.Write("Exporting fonts... "); var cl = Console.CursorLeft; var ct = Console.CursorTop; if (!Directory.Exists(od + DIR_FNT)) { Directory.CreateDirectory(od + DIR_FNT); } for (int i = 0; i < f.Fonts.Length; i++) { Console.SetCursorPosition(cl, ct); Console.WriteLine(O_PAREN + (i + 1) + SLASH + f.Fonts.Length + C_PAREN); File.WriteAllText(od + DIR_FNT + f.Fonts[i].CodeName + EXT_JSON, JsonMapper.ToJson(Serialize.SerializeFont(f.Fonts[i]))); } } #endregion #region PATH if (eo.Path) { Console.Write("Exporting paths... "); var cl = Console.CursorLeft; var ct = Console.CursorTop; if (!Directory.Exists(od + DIR_PATH)) { Directory.CreateDirectory(od + DIR_PATH); } for (int i = 0; i < f.Paths.Length; i++) { Console.SetCursorPosition(cl, ct); Console.WriteLine(O_PAREN + (i + 1) + SLASH + f.Paths.Length + C_PAREN); File.WriteAllText(od + DIR_PATH + f.Paths[i].Name + EXT_JSON, JsonMapper.ToJson(Serialize.SerializePath(f.Paths[i]))); } } #endregion if (eo.ExportToProject) { Console.WriteLine("Emitting project file..."); File.WriteAllText(od + f.General.Name + EXT_JSON, JsonMapper.ToJson(Serialize.SerializeProject(f))); } } }