Just found a way to make ILSpy generate the byte and short casts. Net result, there are only 4 errors in the whole decompiled code, and the game worked after fixing just those 4 (and removing the Steam requirement). The side effect is that operators such as +=, which do work without casting in C#, are decompiled to something like "b = (byte)(b + 1)".
If anyone wants to try the same changes, open the ICSharpCode.Decompiler\ILAst\TypeAnalysis.cs in the ILSpy source, then change:
Code:
TypeReference DoInferTypeForExpression(ILExpression expr, TypeReference expectedType, bool forceInferChildren = false)
{
switch (expr.Code) {
#region Logical operators
to:
Code:
TypeReference DoInferTypeForExpression(ILExpression expr, TypeReference expectedType, bool forceInferChildren = false)
{
TypeReference tempType = null;
switch (expr.Code) {
#region Logical operators
About 250 lines below in the same method, change:
Code:
#region Arithmetic instructions
case ILCode.Not: // bitwise complement
case ILCode.Neg:
return InferTypeForExpression(expr.Arguments.Single(), expectedType);
case ILCode.Add:
return InferArgumentsInAddition(expr, null, expectedType);
case ILCode.Sub:
return InferArgumentsInSubtraction(expr, null, expectedType);
case ILCode.Mul:
case ILCode.Or:
case ILCode.And:
case ILCode.Xor:
return InferArgumentsInBinaryOperator(expr, null, expectedType);
case ILCode.Add_Ovf:
return InferArgumentsInAddition(expr, true, expectedType);
case ILCode.Sub_Ovf:
return InferArgumentsInSubtraction(expr, true, expectedType);
case ILCode.Mul_Ovf:
case ILCode.Div:
case ILCode.Rem:
return InferArgumentsInBinaryOperator(expr, true, expectedType);
case ILCode.Add_Ovf_Un:
return InferArgumentsInAddition(expr, false, expectedType);
case ILCode.Sub_Ovf_Un:
return InferArgumentsInSubtraction(expr, false, expectedType);
case ILCode.Mul_Ovf_Un:
case ILCode.Div_Un:
case ILCode.Rem_Un:
return InferArgumentsInBinaryOperator(expr, false, expectedType);
case ILCode.Shl:
to:
Code:
#region Arithmetic instructions
case ILCode.Not: // bitwise complement
case ILCode.Neg:
tempType = InferTypeForExpression(expr.Arguments.Single(), expectedType);
return (GetInformationAmount(tempType) == 16) ? typeSystem.Int32 : ((GetInformationAmount(tempType) == 8) ? typeSystem.Int32 : tempType);
case ILCode.Add:
tempType = InferArgumentsInAddition(expr, null, expectedType);
return (GetInformationAmount(tempType) == 16) ? typeSystem.Int32 : ((GetInformationAmount(tempType) == 8) ? typeSystem.Int32 : tempType);
case ILCode.Sub:
tempType = InferArgumentsInSubtraction(expr, null, expectedType);
return (GetInformationAmount(tempType) == 16) ? typeSystem.Int32 : ((GetInformationAmount(tempType) == 8) ? typeSystem.Int32 : tempType);
case ILCode.Mul:
case ILCode.Or:
case ILCode.And:
case ILCode.Xor:
tempType = InferArgumentsInBinaryOperator(expr, null, expectedType);
return (GetInformationAmount(tempType) == 16) ? typeSystem.Int32 : ((GetInformationAmount(tempType) == 8) ? typeSystem.Int32 : tempType);
case ILCode.Add_Ovf:
tempType = InferArgumentsInAddition(expr, true, expectedType);
return (GetInformationAmount(tempType) == 16) ? typeSystem.Int32 : ((GetInformationAmount(tempType) == 8) ? typeSystem.Int32 : tempType);
case ILCode.Sub_Ovf:
tempType = InferArgumentsInSubtraction(expr, true, expectedType);
return (GetInformationAmount(tempType) == 16) ? typeSystem.Int32 : ((GetInformationAmount(tempType) == 8) ? typeSystem.Int32 : tempType);
case ILCode.Mul_Ovf:
case ILCode.Div:
case ILCode.Rem:
tempType = InferArgumentsInBinaryOperator(expr, true, expectedType);
return (GetInformationAmount(tempType) == 16) ? typeSystem.Int32 : ((GetInformationAmount(tempType) == 8) ? typeSystem.Int32 : tempType);
case ILCode.Add_Ovf_Un:
tempType = InferArgumentsInAddition(expr, false, expectedType);
return (GetInformationAmount(tempType) == 16) ? typeSystem.Int32 : ((GetInformationAmount(tempType) == 8) ? typeSystem.Int32 : tempType);
case ILCode.Sub_Ovf_Un:
tempType = InferArgumentsInSubtraction(expr, false, expectedType);
return (GetInformationAmount(tempType) == 16) ? typeSystem.Int32 : ((GetInformationAmount(tempType) == 8) ? typeSystem.Int32 : tempType);
case ILCode.Mul_Ovf_Un:
case ILCode.Div_Un:
case ILCode.Rem_Un:
tempType = InferArgumentsInBinaryOperator(expr, false, expectedType);
return (GetInformationAmount(tempType) == 16) ? typeSystem.Int32 : ((GetInformationAmount(tempType) == 8) ? typeSystem.Int32 : tempType);
case ILCode.Shl: