예제 #1
0
 private void RegisterValueTypes(XContainer root, OpcodeLookup lookup)
 {
     foreach (XElement element in root.Element("valueTypes").Descendants("type"))
     {
         string name = XMLUtil.GetStringAttribute(element, "name");
         var opcode = (ushort) XMLUtil.GetNumericAttribute(element, "opcode");
         int size = XMLUtil.GetNumericAttribute(element, "size");
         bool quoted = XMLUtil.GetBoolAttribute(element, "quoted", false);
         string tag = XMLUtil.GetStringAttribute(element, "tag", null);
         var valueType = new ScriptValueType(name, opcode, size, quoted, tag);
         lookup.RegisterValueType(valueType);
     }
 }
예제 #2
0
		private uint GetValue(ScriptExpression expression, ScriptValueType type)
		{
			//var valBytes = new byte[4];
			uint newVal = 0;
			byte[] valBytes = new byte[4];

			switch(type.Size)
			{
				case 1:
					valBytes[0] = 0;
					valBytes[1] = 0;
					valBytes[2] = 0;
					valBytes[3] = (byte)(expression.Value);
					break;
				case 2:
					valBytes[0] = 0;
					valBytes[1] = 0;
					valBytes[2] = (byte)(expression.Value);
					valBytes[3] = (byte)(expression.Value >> 8);
					break;
				default:
				case 4:
					valBytes[0] = (byte)(expression.Value);
					valBytes[1] = (byte)(expression.Value >> 8);
					valBytes[2] = (byte)(expression.Value >> 16);
					valBytes[3] = (byte)(expression.Value >> 24);
					break;
			}

			newVal = BitConverter.ToUInt32(valBytes, 0);

			return newVal >> (32 - (type.Size * 8));
			//return expression.Value >> (32 - (type.Size*8));
		}
        private void GenerateCode(ScriptExpression expression, IndentedTextWriter output)
        {
            int  firstIndentedArg = int.MaxValue;
            bool isFunctionCall   = false;

            if (expression.Type == ScriptExpressionType.Expression)
            {
                ScriptValueType type = _opcodes.GetTypeInfo((ushort)expression.ReturnType);
                if (type.Name == "function_name")
                {
                    isFunctionCall = true;

                    if (!_nextFunctionIsScript)
                    {
                        ScriptFunctionInfo info = _opcodes.GetFunctionInfo(expression.Opcode);
                        if (info != null)
                        {
                            if (info.Name.StartsWith("begin"))
                            {
                                firstIndentedArg = 0;
                                if (expression.LineNumber > 0 && !_onNewLine)
                                {
                                    output.Indent++;
                                    output.WriteLine();
                                }
                            }
                            else if (info.Name == "if")
                            {
                                firstIndentedArg = 1;
                            }
                        }
                    }
                    if (expression.LineNumber > 0)
                    {
                        output.Write("(");
                    }
                }
            }

            bool wroteAnything = HandleExpression(expression, output);
            int  startIndent   = output.Indent;

            int currentArg           = 0;
            ScriptExpression sibling = expression.Next;

            while (sibling != null)
            {
                if (wroteAnything)
                {
                    if (currentArg == firstIndentedArg)
                    {
                        output.Indent++;
                    }
                    if (currentArg >= firstIndentedArg || output.Indent != startIndent)
                    {
                        output.WriteLine();
                        _onNewLine = true;
                    }
                    else
                    {
                        output.Write(" ");
                    }
                }

                wroteAnything = HandleExpression(sibling, output);
                sibling       = sibling.Next;
                currentArg++;
            }

            if (isFunctionCall && expression.LineNumber > 0)
            {
                if (output.Indent != startIndent)
                {
                    output.Indent = startIndent;
                    if (wroteAnything)
                    {
                        output.WriteLine();
                    }
                    output.Write(")");
                    _onNewLine = true;
                }
                else
                {
                    output.Write(")");
                }
            }
        }
예제 #4
0
 public void RegisterValueType(ScriptValueType type)
 {
     _typeLookupByName[type.Name]     = type;
     _typeLookupByOpcode[type.Opcode] = type;
 }
        private bool GenerateExpressionCode(ScriptExpression expression, IndentedTextWriter output)
        {
            if (expression.LineNumber == 0)
            {
                return(false);
            }

            _onNewLine = false;
            ScriptValueType type       = _opcodes.GetTypeInfo((ushort)expression.ReturnType);
            ScriptValueType actualType = type;

            if (type.Name != "function_name")
            {
                // Check if a typecast is occurring
                actualType = _opcodes.GetTypeInfo(expression.Opcode);

                if (actualType.Quoted)
                {
                    if (expression.Value != 0xFFFFFFFF)
                    {
                        output.Write("\"{0}\"", expression.StringValue);
                    }
                    else
                    {
                        output.Write("none");
                    }
                    return(true);
                }
            }

            uint value = GetValue(expression, type);

            switch (type.Name)
            {
            case "void":
                return(false);

            case "boolean":
                if (value > 0)
                {
                    output.Write("true");
                }
                else
                {
                    output.Write("false");
                }
                break;

            case "short":
            case "long":
                // Signed integer
                output.Write((int)value);
                break;

            case "real":
                // Eww
                var floatBytes = new byte[4];
                floatBytes[0] = (byte)(value & 0xFF);
                floatBytes[1] = (byte)((value >> 8) & 0xFF);
                floatBytes[2] = (byte)((value >> 16) & 0xFF);
                floatBytes[3] = (byte)((value >> 24) & 0xFF);
                output.Write(BitConverter.ToSingle(floatBytes, 0));
                break;

            case "function_name":
                if (_nextFunctionIsScript)
                {
                    output.Write(expression.StringValue);                             // halo online seems weird in that the "opcode" value that is actually a script index in this case is greater than the number of scripts
                    //output.Write(_scripts.Scripts[expression.Opcode].Name);
                    _nextFunctionIsScript = false;
                }
                else
                {
                    ScriptFunctionInfo info = _opcodes.GetFunctionInfo(expression.Opcode);
                    if (info == null)
                    {
                        output.Write("unknown_" + expression.Opcode.ToString("X") + "(" + expression.StringValue + ")");                          //throw new InvalidOperationException("Unrecognized function opcode 0x" + expression.Opcode.ToString("X"));
                    }
                    else
                    {
                        output.Write(info.Name);
                    }
                }
                break;

            case "unit_seat_mapping":
                // This isn't the technical way of doing this,
                // but since seat mapping names aren't stored anywhere,
                // it would be tricky to resolve them unless we just use an index for now
                if (expression.Value != 0xFFFFFFFF)
                {
                    output.Write(expression.Value & 0xFFFF);
                }
                else
                {
                    output.Write("none");
                }
                break;

            default:
                string enumValue = actualType.GetEnumValue(value);
                if (enumValue != null)
                {
                    output.Write(enumValue);
                }
                else if (expression.Value == 0xFFFFFFFF)
                {
                    output.Write("none");
                }
                else
                {
                    enumValue = expression.StringValue;
                    if (enumValue != null)
                    {
                        output.Write(enumValue);
                    }
                    else
                    {
                        output.Write("0x{0:X}", value);
                    }
                }
                break;
            }
            return(true);
        }
예제 #6
0
		public void RegisterValueType(ScriptValueType type)
		{
			_typeLookupByName[type.Name] = type;
			_typeLookupByOpcode[type.Opcode] = type;
		}
예제 #7
0
        private void GenerateCode(ScriptExpression expression, IndentedTextWriter output, bool firstrun = false)
        {
            int  firstIndentedArg = int.MaxValue;
            bool isFunctionCall   = false;

            if (expression.Type == ScriptExpressionType.Expression || expression.Type == ScriptExpressionType.Expression4)
            {
                ScriptValueType type = _opcodes.GetTypeInfo((ushort)expression.ReturnType);
                if (type.Name == "function_name")
                {
                    isFunctionCall = true;

                    if (!_nextFunctionIsScript)
                    {
                        ScriptFunctionInfo info = _opcodes.GetFunctionInfo(expression.Opcode);
                        if (info != null)
                        {
                            if (info.Name.StartsWith("begin"))
                            {
                                firstIndentedArg = 0;
                                if (expression.LineNumber > 0 && !_onNewLine)
                                {
                                    output.Indent++;
                                    output.WriteLine();
                                }
                            }
                            else if (info.Name == "if")
                            {
                                firstIndentedArg = 1;
                            }
                        }
                    }
                    if (expression.LineNumber > 0)
                    {
                        output.Write("(");
                    }
                }
            }



            bool wroteAnything = wroteAnything = HandleExpression(expression, output);
            int  startIndent   = output.Indent;

            int currentArg = 0;

            if (_h4 && firstrun)
            {
                firstIndentedArg = 0;
                currentArg       = 1;
                _h4 = false;
            }

            ScriptExpression sibling = expression.Next;

            while (sibling != null)
            {
                if (wroteAnything && !_nextExpressionIsVar)
                {
                    if (currentArg == firstIndentedArg)
                    {
                        output.Indent++;
                    }
                    if (currentArg >= firstIndentedArg)
                    {
                        output.WriteLine();
                        _onNewLine = true;
                    }
                    else if (output.Indent != startIndent)
                    {
                        output.WriteLine();
                        _onNewLine = true;
                    }
                    else
                    {
                        output.Write(" ");
                    }
                }

                if (!_nextExpressionIsVar)
                {
                    wroteAnything = HandleExpression(sibling, output);
                }
                else if ((_nextExpressionIsVar && sibling.Opcode != 0xFFFF))
                {
                    if (!_varTypeWritten)
                    {
                        ScriptValueType type = _opcodes.GetTypeInfo((ushort)sibling.ReturnType);
                        output.Write(type.Name + " var_" + localVarCounter.ToString() + " ");
                        _varTypeWritten = true;
                    }

                    wroteAnything = HandleExpression(sibling, output);
                }

                sibling = sibling.Next;
                currentArg++;
            }

            if (isFunctionCall && expression.LineNumber > 0)
            {
                if (output.Indent != startIndent)
                {
                    output.Indent = startIndent;
                    if (wroteAnything)
                    {
                        output.WriteLine();
                    }
                    output.Write(")");
                    _onNewLine = true;
                }
                else
                {
                    output.Write(")");
                }
            }
        }
예제 #8
0
 private uint GetValue(ScriptExpression expression, ScriptValueType type)
 {
     return expression.Value >> (32 - (type.Size*8));
 }
예제 #9
0
        /// <summary>
        /// The decompiler generates a literal (expression) on an expression.
        /// </summary>
        /// <param name="output">The output.</param>
        /// <param name="expression">The expression.</param>
        /// <param name="newLine">Indicates whether the expressions of the branch start on a new line.</param>
        /// <returns>Returns true if code was generated.</returns>
        private bool GenerateExpression(IndentedTextWriter output, ScriptExpression expression, bool newLine)
        {
            ScriptValueType type       = _opcodes.GetTypeInfo(expression.ReturnType);
            ScriptValueType actualType = type;

            // Check if a typecast is occurring
            if (expression.Opcode != 0xFFFF)
            {
                actualType = _opcodes.GetTypeInfo(expression.Opcode);

                // Simply write the string for quoted expressions.
                if (actualType.Quoted)
                {
                    // Don't quote the keyword none.
                    if (expression.Value.IsNull || expression.StringValue == "none")
                    {
                        output.Write("none");
                    }
                    else
                    {
                        output.Write("\"{0}\"", ScriptStringHelpers.Escape(expression.StringValue));
                    }
                    return(false);
                }
            }

            uint value = GetValue(expression, actualType);

            byte[] val = BitConverter.GetBytes(value);
            string text;


            switch (actualType.Name)
            {
            case "void":
                text = "";
                break;

            case "ai_command_script":
            case "script":
                short index = BitConverter.ToInt16(val, 0);
                text = _scripts.Scripts[index].Name;
                break;

            case "boolean":
                text = BitConverter.ToBoolean(val, 0) ? "true" : "false";
                break;

            case "short":
                text = BitConverter.ToInt16(val, 0).ToString();
                break;

            case "long":
                // Signed integer
                int signed = (int)value;
                text = signed.ToString();
                break;

            case "real":
                float fl = BitConverter.ToSingle(val, 0);
                text = fl.ToString("0.0#######", CultureInfo.InvariantCulture);
                break;

            case "ai_line":
                text = expression.StringValue == "" ? "\"\"" : expression.StringValue;
                break;

            case "unit_seat_mapping":
                text = expression.Value.IsNull ? "none" : expression.StringValue;
                break;

            default:
                if (expression.Value.IsNull)
                {
                    text = "none";
                }
                else if (actualType.IsEnum)
                {
                    string enumValue = actualType.GetEnumValue(value);
                    if (enumValue != null)
                    {
                        text = enumValue;
                    }
                    else
                    {
                        throw new NotImplementedException("Unknown Enum Value.");
                    }
                }
                else
                {
                    //throw new NotImplementedException($"Unhandled Return Type: \"{actualType.Name}\".");
                    text = expression.StringValue;
                }

                break;
            }

            output.Write(text);
            HandleNewLine(output, newLine);
            return(false);
        }
예제 #10
0
 private uint GetValue(ScriptExpression expression, ScriptValueType type)
 {
     return(expression.Value >> (32 - (type.Size * 8)));
 }