public static string ConvertComparisonToString(STSCInstructions.InstructionIf.Comparison comparison) { string left = comparison.Left.ToString(); string right = comparison.Right.ToString(); if (comparison.Left > 2048) { left = $"0x{comparison.Left:X}"; } if (comparison.Right > 2048) { right = $"0x{comparison.Right:X}"; } if (comparison.Operator != ComparisonOperators.NotZero && comparison.Operator != ComparisonOperators.Zero) { return($"{left} {ComparisonOperatorStrings[(int) comparison.Operator]} {right}"); } return($"{left} {ComparisonOperatorStrings[(int) comparison.Operator]}"); }
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]; } } } }); }