private void ExportTranslationMenuItem_Click(object sender, RoutedEventArgs e) { if (ScriptListBox.SelectedIndex == -1) { return; } var file = ScriptArchive.FileEntries[ScriptListBox.SelectedIndex]; var sfd = new SaveFileDialog { Filter = GenerateFilters(false), FileName = Path.GetFileNameWithoutExtension(file.FileName) }; if (sfd.ShowDialog() == true) { // Gets the index of the filetype int index = TranslationSTSCHandler.FileTypes.ToList().FindIndex(t => sfd.FileName.Contains(t.TypeExtension)); var script = new STSCFile(); using (var stream = ScriptArchive.GetFileStream(file.FileName)) script.Load(stream); File.WriteAllText(sfd.FileName, TranslationSTSCHandler.ExportTranslation(index, script, ScriptDB, App.StringProcess), new UTF8Encoding(true)); } }
public static void ImportTranslation(int fileTypeIndex, STSCFile script, string data, bool useKey = true) { var fileType = FileTypes[fileTypeIndex]; var lines = fileType.ImportTranslation(data); if (useKey) { for (int i = 0; i < lines.Length; ++i) { // Skip untranslated lines if (string.IsNullOrEmpty(lines[i].Translation)) { continue; } foreach (var instruction in script.Instructions) { setSTSCLine(lines[i], instruction, false); } } } else { int lastInstIndex = 0; for (int i = 0; i < lines.Length; ++i) { for (int instIndex = lastInstIndex; instIndex < script.Instructions.Count; ++instIndex) { if (setSTSCLine(lines[i], script.Instructions[instIndex], true)) { lastInstIndex = instIndex + 1; break; } } } } }
public static string ExportTranslation(int fileTypeIndex, STSCFile script, STSCFileDatabase database) { var lines = new List <TranslationLine>(); var fileType = FileTypes[fileTypeIndex]; // The ID of who is currently speaking byte titleID = 0xFF; // Loop through all the instructions foreach (var instruction in script.Instructions) { switch (instruction.Name) { case "MesTitle": titleID = instruction.GetArgument <byte>(0); break; case "Mes": // Get name of the character from string name = titleID == 0xFF ? "None" : database.Characters.FirstOrDefault(t => t.ID == titleID)?.FriendlyName; // Add Entry to file lines.Add(new TranslationLine("Message", name, instruction.GetArgument <string>(4), "")); break; case "SetChoice": lines.Add(new TranslationLine("Choice", "", instruction.GetArgument <string>(1), "")); break; case "MapPlace": lines.Add(new TranslationLine("MapMarker", "", instruction.GetArgument <string>(1), "")); break; default: continue; } } return(fileType.ExportTranslation(lines.ToArray())); }
public static void ConvertSingleInstructionToText(STSCFile file, int instructionPointer, Dictionary <string, int> labels, List <int> scopeEnds, List <int> lines, List <string> strings, ref int address, ref int currentIndent) { var instruction = file.Instructions[instructionPointer]; if (scopeEnds.Count != 0 && scopeEnds.Last() == address) { --currentIndent; strings.Add($"{new string(' ', currentIndent * 4)}}}"); scopeEnds.RemoveAt(scopeEnds.Count - 1); } // TODO int address2 = address; if (labels.Any(t => t.Value == address2)) { strings.Add($"#label {labels.FirstOrDefault(t => t.Value == address2).Key}"); } if (instruction.Name == "if") { lines.Add(strings.Count); var ifInstruction = instruction as STSCInstructions.InstructionIf; string[] comps = ifInstruction.Comparisons .Select((comparison, index) => ConvertComparisonToString(comparison)).ToArray(); strings.Add($"{new string(' ', currentIndent * 4)}if ({string.Join(" && ", comps)})"); strings.Add($"{new string(' ', currentIndent * 4)}{{"); ++currentIndent; scopeEnds.Add(ifInstruction.GetArgument <int>(0)); } else { string[] argString = instruction.Arguments.Select((arg, index) => { if (instruction.ArgTypes[index] == STSCInstructions.ArgumentType.AT_CodePointer) { int jumpAddress = instruction.GetArgument <int>(index); string labelName = $"LABEL_{jumpAddress:X4}"; // Change Label name if its been used as a function if (instruction.Name == STSCInstructions.DALRRInstructions[0x1A].Name) { labelName = $"SUB_{jumpAddress:X4}"; } if (!labels.ContainsKey(labelName)) { labels.Add(labelName, jumpAddress); if (file.FindIndex(jumpAddress) < instructionPointer) { PlaceLine(file, strings, lines, jumpAddress, $"#label {labelName}"); } } return(labelName); } return(ConvertArgumentToString(instruction, index)); }).ToArray(); // Macros if (instruction.Name == STSCInstructions.DALRRInstructions[0x52].Name) { argString[0] = STSCMacros.DALRRCharacterNames[int.Parse(argString[0])] ?? argString[0]; } lines.Add(strings.Count); strings.Add($"{new string(' ', currentIndent * 4)}{instruction.Name}({string.Join(", ", argString)})"); } }
public static void ConvertToObject(STSCFile file, string[] text) { var labels = new Dictionary <string, int>(); var scopes = new List <int>(); int scopeID = 0; int address = 0x3C; for (int i = 0; i < text.Length; ++i) { string line = text[i]; if (string.IsNullOrEmpty(line.Replace(" ", ""))) { continue; } // Gets the first character of the line excluding spaces char c = line.Replace(" ", "")[0]; if (c == '#') { if (line.StartsWith("#label")) { labels.Add(line.Substring(7), address); } if (line.StartsWith("#scriptID")) { file.ScriptID = uint.Parse(ProcessLiterals(line.Substring(10))); } if (line.StartsWith("#scriptName")) { file.ScriptName = line.Substring(12); } continue; } if (c == '{') { continue; } if (c == '}') { labels.Add(scopes.Last().ToString(), address); scopes.RemoveAt(scopes.Count - 1); continue; } var code = ParseCodeLine(line); var baseInstruction = STSCInstructions.DALRRInstructions.FirstOrDefault(t => t?.Name == code[0]); if (baseInstruction == null) { Console.WriteLine("Error: Could not find any instructions for \"{0}\"! Please check line {1} in the source file.", code[0], i); Console.ReadKey(true); return; } if (baseInstruction.Name == "if") { var baseIf = baseInstruction as STSCInstructions.InstructionIf; var instruction = new STSCInstructions.InstructionIf(); instruction.Arguments.Add(scopeID.ToString()); scopes.Add(scopeID++); var comStrs = code[1].Split(new [] { "&&" }, StringSplitOptions.RemoveEmptyEntries); foreach (string s in comStrs) { foreach (string cmpstr in ComparisonOperatorStrings) { if (s.Contains(cmpstr)) { var split = s.Split(new[] { cmpstr }, StringSplitOptions.RemoveEmptyEntries); var cmp = new STSCInstructions.InstructionIf.Comparison( uint.Parse(ProcessLiterals(split[0])), (ComparisonOperators)Array.IndexOf(ComparisonOperatorStrings, cmpstr), uint.Parse(ProcessLiterals(split[1]))); instruction.Comparisons.Add(cmp); break; } } } file.Instructions.Add(instruction); address += instruction.GetInstructionSize(); } else if (baseInstruction.Name == "switch") { var baseSwitch = baseInstruction as STSCInstructions.InstructionSwitch; var instruction = new STSCInstructions.InstructionSwitch(baseSwitch.Name, null); uint unknown = (uint)int.Parse(code[1]); ushort amount = ushort.Parse(code[2]); bool endFlag = bool.Parse(code[3]); instruction.ArgTypes = new STSCInstructions.ArgumentType[amount * 2 + 3]; instruction.ArgTypes[0] = STSCInstructions.ArgumentType.AT_DataReference; instruction.Arguments.Add(unknown); instruction.ArgTypes[1] = STSCInstructions.ArgumentType.AT_Int16; instruction.Arguments.Add(amount); instruction.ArgTypes[2] = STSCInstructions.ArgumentType.AT_Bool; instruction.Arguments.Add(endFlag); for (int ii = 0; ii < amount; ++ii) { // case instruction.ArgTypes[ii * 2 + 3 + 0] = STSCInstructions.ArgumentType.AT_Int32; instruction.Arguments.Add(int.Parse(ProcessLiterals(code[ii * 2 + 4 + 0]))); // location instruction.ArgTypes[ii * 2 + 3 + 1] = STSCInstructions.ArgumentType.AT_CodePointer; instruction.Arguments.Add(code[ii * 2 + 4 + 1]); } file.Instructions.Add(instruction); address += instruction.GetInstructionSize(); } else { var instruction = (STSCInstructions.Instruction)Activator.CreateInstance(baseInstruction.GetType(), baseInstruction.Name, baseInstruction.ArgTypes); if (baseInstruction.ArgTypes != null) { for (int ii = 0; ii < instruction.ArgTypes.Length; ++ii) { AddArgument(instruction, instruction.ArgTypes[ii], code[ii + 1]); } } file.Instructions.Add(instruction); address += instruction.GetInstructionSize(); } } file.Instructions.ForEach(t => { if (t.ArgTypes != null) { for (int i = 0; i < t.ArgTypes.Length; ++i) { if (t.ArgTypes[i] == STSCInstructions.ArgumentType.AT_CodePointer && t.Arguments[i].GetType() == typeof(string)) { t.Arguments[i] = labels[t.Arguments[i] as string]; } } } }); }
// Constructors public STSCDisassembleException(STSCFile script, string reason) : base(string.Format( "Failed to disassemble the script file {0}. {1}", script.ScriptName, reason)) { }
public static string ExportTranslation(int fileTypeIndex, STSCFile script, STSCFileDatabase database, StringProcessor processor = null) { var fileType = FileTypes[fileTypeIndex]; return(fileType.ExportTranslation(ExportTranslationLines(script, database, processor))); }