Skip to content
Browse files

more work on script decompiler

  • Loading branch information...
1 parent fcf3e79 commit 6db6f58e7e95571e0a2964c167db9d4490afcb71 @yole committed Oct 31, 2011
View
30 Gibbed.RED.FileFormats/Script/Instructions/FinalFunc.cs
@@ -8,8 +8,6 @@ public class FinalFunc: IInstruction
private readonly CompiledScriptsFile _scripts;
private ushort _opFlags;
private ushort _opTarget;
- private int _opFuncId;
- private int _opOperator;
public FinalFunc(CompiledScriptsFile scripts)
{
@@ -25,10 +23,10 @@ public int Deserialize(Stream input)
{
_opFlags = input.ReadValueU16();
_opTarget = input.ReadValueU16();
- _opFuncId = input.ReadValueEncodedS32();
- if (_opFuncId == -1)
+ OpFuncId = input.ReadValueEncodedS32();
+ if (OpFuncId == -1)
{
- _opOperator = input.ReadValueEncodedS32();
+ OpOperator = (OperatorCode) input.ReadValueEncodedS32();
}
return 8;
}
@@ -40,17 +38,33 @@ public void Serialize(ICodeWriter output)
public override string ToString()
{
- if (_opFuncId == -1)
+ if (OpFuncId == -1)
{
- var opName = ((OperatorCode)_opOperator).ToString();
+ var opName = OpOperator.ToString();
int value;
if (int.TryParse(opName, out value))
{
return "FinalFunc-UnknownOperator(" + _opFlags + "," + _opTarget + "," + opName + ")";
}
return "FinalFunc(" + _opFlags + "," + _opTarget + "," + opName + ")";
}
- return string.Format("FinalFunc({0},{1},{2})", _opFlags, _opTarget, _scripts.FuncDefs[_opFuncId].Name);
+ return string.Format("FinalFunc({0},{1},{2})", _opFlags, _opTarget, FunctionName);
}
+
+ public string FunctionName
+ {
+ get
+ {
+ var funcDef = _scripts.FuncDefs[OpFuncId];
+ if (funcDef.ContainingClass != null)
+ {
+ return funcDef.ContainingClass.Name + "::" + funcDef.Name;
+ }
+ return funcDef.Name;
+ }
+ }
+
+ public int OpFuncId { get; private set; }
+ public OperatorCode OpOperator { get; private set; }
}
}
View
11 Gibbed.RED.FileFormats/Script/Instructions/NameConst.cs
@@ -2,12 +2,11 @@
namespace Gibbed.RED.FileFormats.Script.Instructions
{
- class NameConst: IInstruction
+ public class NameConst: IInstruction
{
private readonly RawString[] _strings;
- private string _value;
- public NameConst(RawString[] strings)
+ internal NameConst(RawString[] strings)
{
_strings = strings;
}
@@ -20,7 +19,7 @@ public Opcode Opcode
public int Deserialize(Stream input)
{
int index = input.ReadValueEncodedS32();
- _value = _strings[index].Value;
+ Value = _strings[index].Value;
return 4;
}
@@ -31,7 +30,9 @@ public void Serialize(ICodeWriter output)
public override string ToString()
{
- return "NameConst('" + _value + "')";
+ return "NameConst('" + Value + "')";
}
+
+ public string Value { get; private set; }
}
}
View
7 Gibbed.RED.FileFormats/Script/Instructions/TypeMember.cs
@@ -38,7 +38,12 @@ public override string ToString()
{
return string.Format("{0}('{1}')", _opcode, MemberName);
}
- return string.Format("{0}('{1}', {2})", _opcode, MemberName, _scripts.TypeDefs[_opTypeId].Name);
+ return string.Format("{0}('{1}', {2})", _opcode, MemberName, TypeName);
+ }
+
+ public string TypeName
+ {
+ get { return _scripts.TypeDefs[_opTypeId].Name; }
}
public string MemberName
View
7 Gibbed.RED.FileFormats/Script/Instructions/TypeRef.cs
@@ -36,7 +36,12 @@ public override string ToString()
{
return _opcode + "(" + _scripts.Strings[_typeId].Value + ")";
}
- return _opcode + "(" + (_typeId == -1 ? "-1" :_scripts.TypeDefs[_typeId].Name) + ")";
+ return _opcode + "(" + TypeName + ")";
+ }
+
+ public string TypeName
+ {
+ get { return (_typeId == -1 ? "-1" :_scripts.TypeDefs[_typeId].Name); }
}
}
}
View
26 Gibbed.RED.FileFormats/Script/OperatorCode.cs
@@ -2,32 +2,32 @@
{
public enum OperatorCode
{
- OperatorIntAdd = 0,
- OperatorIntSubtract = 1,
- OperatorIntMultiply = 2,
- OperatorIntDivide = 3,
+ IntAdd = 0,
+ IntSubtract = 1,
+ IntMultiply = 2,
+ IntDivide = 3,
OperatorIntNeg = 4,
OperatorIntEqual = 8,
OperatorIntNotEqual = 9,
OperatorIntLess = 10,
OperatorIntLessEqual = 11,
OperatorIntGreater = 12,
OperatorIntGreaterEqual = 13,
- OperatorIntAssignAdd = 14,
- OperatorIntAssignSubtract = 15,
- OperatorStringAdd = 20,
- OperatorFloatAdd = 21,
- OperatorFloatSubtract = 22,
- OperatorFloatMultiply = 23,
- OperatorFloatDivide = 24,
+ IntAssignAdd = 14,
+ IntAssignSubtract = 15,
+ StringAdd = 20,
+ FloatAdd = 21,
+ FloatSubtract = 22,
+ FloatMultiply = 23,
+ FloatDivide = 24,
OperatorFloatEqual = 27,
OperatorFloatNotEqual = 28,
OperatorFloatLess = 29,
OperatorFloatLessEqual = 30,
OperatorFloatGreater = 31,
OperatorFloatGreaterEqual = 32,
- OperatorFloatAssignAdd = 33,
- OperatorFloatAssignSubtract = 34,
+ FloatAssignAdd = 33,
+ FloatAssignSubtract = 34,
OperatorBoolAnd = 57,
OperatorBoolOr = 58,
OperatorBoolNot = 59,
View
6 Gibbed.RED.ScriptDecompiler/Expression.cs
@@ -53,10 +53,12 @@ public class BinaryExpression: Expression
private readonly Expression _lhs;
private readonly Expression _rhs;
private readonly string _infix;
+ private readonly string _suffix;
- public BinaryExpression(int target, string infix, Expression lhs, Expression rhs)
+ public BinaryExpression(int target, string infix, string suffix, Expression lhs, Expression rhs)
{
_infix = infix;
+ _suffix = suffix;
_lhs = lhs;
_rhs = rhs;
}
@@ -68,7 +70,7 @@ public override bool Complete
public override string ToString()
{
- return _lhs + _infix + (_rhs != null ? _rhs.ToString() : "?");
+ return _lhs + _infix + (_rhs != null ? _rhs.ToString() : "?") + _suffix;
}
}
View
126 Gibbed.RED.ScriptDecompiler/FunctionDecompiler.cs
@@ -56,13 +56,13 @@ private Expression ReadNextExpression()
switch (currentInstruction.Opcode)
{
case Opcode.OP_Assign:
- return ReadBinaryExpession(target, " = ");
+ return ReadBinaryExpression(target, " = ", "");
case Opcode.OP_Context:
{
var context = (U16U16)currentInstruction;
if (context.Op0 == 0)
{
- return ReadBinaryExpession(target, ".");
+ return ReadBinaryExpression(target, ".", "");
}
}
break;
@@ -71,32 +71,50 @@ private Expression ReadNextExpression()
case Opcode.OP_VirtualFunc:
{
var virtualFunc = (VirtualFunc)currentInstruction;
- var args = new List<Expression>();
- bool incomplete = false;
- while (_func.Instructions[_currentIndex].Opcode != Opcode.OP_ParamEnd)
+ var args = ReadArgumentList();
+ return new CallStatement(virtualFunc.FunctionName, args);
+ }
+ case Opcode.OP_FinalFunc:
+ {
+ var finalFunc = (FinalFunc) currentInstruction;
+ if (finalFunc.OpFuncId != -1)
+ {
+ var args = ReadArgumentList();
+ return new CallStatement(finalFunc.FunctionName, args);
+ }
+ else
{
- var nextExpression = ReadNextExpression();
- args.Add(nextExpression);
- if (!nextExpression.Complete)
+ string opName = GetOperator(finalFunc.OpOperator);
+ if (opName != null)
{
- incomplete = true;
- break;
+ var expression = ReadBinaryExpression(target, " " + opName + " ", "");
+ if (CurrentInstruction.Opcode == Opcode.OP_ParamEnd)
+ {
+ _currentIndex++;
+ return expression;
+ }
}
}
- if (!incomplete)
- _currentIndex++; // skip paramEnd
- return new CallStatement(virtualFunc.FunctionName, args);
}
+ break;
case Opcode.OP_ObjectVar:
case Opcode.OP_ParamVar:
case Opcode.OP_LocalVar:
return new SimpleExpression(((TypeMember)currentInstruction).MemberName);
+ case Opcode.OP_StructMember:
+ return ReadUnaryExpression(target, "", "." + (((TypeMember) currentInstruction).MemberName));
+
case Opcode.OP_GetPlayer:
return new SimpleExpression("Player");
case Opcode.OP_GetHud:
return new SimpleExpression("Hud");
case Opcode.OP_GetGame:
return new SimpleExpression("Game");
+ case Opcode.OP_GetSound:
+ return new SimpleExpression("Sound");
+ case Opcode.OP_GetCamera:
+ return new SimpleExpression("Camera");
+
case Opcode.OP_BoolFalse:
return new SimpleExpression("false");
case Opcode.OP_BoolTrue:
@@ -105,29 +123,107 @@ private Expression ReadNextExpression()
return new SimpleExpression("0");
case Opcode.OP_IntOne:
return new SimpleExpression("1");
+ case Opcode.OP_Null:
+ return new SimpleExpression("null");
case Opcode.OP_FloatConst:
return new SimpleExpression(((FloatConst)currentInstruction).Value.ToString());
case Opcode.OP_StringConst:
return new SimpleExpression("\"" + ((StringConst)currentInstruction).Value + "\"");
+ case Opcode.OP_NameConst:
+ return new SimpleExpression("'" + ((NameConst)currentInstruction).Value + "'");
+
+ case Opcode.OP_ArrayClear:
+ return ReadUnaryExpression(target, "", ".Clear()");
case Opcode.OP_ArraySize:
return ReadUnaryExpression(target, "", ".Size");
+ case Opcode.OP_ArrayPushBack:
+ return ReadBinaryExpression(target, ".PushBack(", ")");
+ case Opcode.OP_ArrayElement:
+ return ReadBinaryExpression(target, "[", "]");
+
+ case Opcode.OP_DynamicCast:
+ return ReadUnaryExpression(target, "dynamic_cast<" + ((TypeRef) currentInstruction).TypeName + ">(", ")");
}
return new UnknownExpression(currentInstruction);
}
+ private List<Expression> ReadArgumentList()
+ {
+ var args = new List<Expression>();
+ bool incomplete = false;
+ while (CurrentInstruction.Opcode != Opcode.OP_ParamEnd)
+ {
+ if (CurrentInstruction.Opcode == Opcode.OP_Nop)
+ {
+ args.Add(new SimpleExpression("null"));
+ _currentIndex++;
+ continue;
+ }
+ var nextExpression = ReadNextExpression();
+ args.Add(nextExpression);
+ if (!nextExpression.Complete)
+ {
+ incomplete = true;
+ break;
+ }
+ }
+ if (!incomplete)
+ _currentIndex++; // skip paramEnd
+ return args;
+ }
+
+ private IInstruction CurrentInstruction
+ {
+ get { return _func.Instructions[_currentIndex]; }
+ }
+
private Expression ReadUnaryExpression(int target, string prefix, string suffix)
{
var operand = ReadNextExpression();
return new UnaryExpression(target, operand, prefix, suffix);
}
- private Expression ReadBinaryExpession(int target, string infix)
+ private Expression ReadBinaryExpression(int target, string infix, string suffix)
{
var lhs = ReadNextExpression();
var rhs = lhs.Complete ? ReadNextExpression() : null;
- return new BinaryExpression(target, infix, lhs, rhs);
+ return new BinaryExpression(target, infix, suffix, lhs, rhs);
+ }
+
+ private string GetOperator(OperatorCode code)
+ {
+ switch (code)
+ {
+ case OperatorCode.IntAdd:
+ case OperatorCode.FloatAdd:
+ case OperatorCode.StringAdd:
+ return "+";
+
+ case OperatorCode.IntSubtract:
+ case OperatorCode.FloatSubtract:
+ return "-";
+
+ case OperatorCode.IntMultiply:
+ case OperatorCode.FloatMultiply:
+ return "*";
+
+ case OperatorCode.IntDivide:
+ case OperatorCode.FloatDivide:
+ return "/";
+
+ case OperatorCode.IntAssignAdd:
+ case OperatorCode.FloatAssignAdd:
+ return "+=";
+
+ case OperatorCode.IntAssignSubtract:
+ case OperatorCode.FloatAssignSubtract:
+ return "-=";
+
+ default:
+ return null;
+ }
}
}
}

0 comments on commit 6db6f58

Please sign in to comment.
Something went wrong with that request. Please try again.