/// <summary> /// Divides the value stored in the local variable by the specified float value. /// </summary> /// <param name="Args">A ScriptArguments instance.</param> public static void DivFloatLVarByVal(ref ScriptArguments Args) { SCMOpcodeParameter FirstParam = Args[0]; FirstParam.Real /= Args[1].Real; Args[0] = FirstParam; //This should work, in theory. }
/// <summary> /// Divides the value stored in the local variable by the specified integer value. /// </summary> /// <param name="Args">A ScriptArguments instance.</param> public static void DivIntLVarByVal(ref ScriptArguments Args) { SCMOpcodeParameter FirstParam = Args[0]; FirstParam.Integer += Args[1].Integer; Args[0] = FirstParam; //This should work, in theory. }
/// <summary> /// Multiplies the value stored in the global variable by the specified float value. /// </summary> /// <param name="Args">A ScriptArguments instance.</param> public static void MultFloatVarByVal(ref ScriptArguments Args) { SCMOpcodeParameter FirstParam = Args[0]; FirstParam.GlobalReal *= Args[1].Real; Args[0] = FirstParam; //This should work, in theory. }
/// <summary> /// Multiplies the value stored in the global variable by the specified integer value. /// </summary> /// <param name="Args">A ScriptArguments instance.</param> public static void MultIntVarByVal(ref ScriptArguments Args) { SCMOpcodeParameter FirstParam = Args[0]; FirstParam.GlobalInteger *= Args[1].Integer; Args[0] = FirstParam; //This should work, in theory. }
/// <summary> /// Increases the value stored in the local variable by the specified float value. /// </summary> /// <param name="Args">A ScriptArguments instance.</param> public static void AddValToFloatLVar(ref ScriptArguments Args) { SCMOpcodeParameter FirstParam = Args[0]; FirstParam.GlobalReal += Args[1].Real; Args[0] = FirstParam; //This should work, in theory. }
/// <summary> /// Assigns the value of arg1 to arg2. /// </summary> /// <param name="Args">A ScriptArguments instance.</param> public static void FloatLeftDivisionAssignment(ref ScriptArguments Args) { var Params = Args.GetParameters(); SCMOpcodeParameter FirstParam = Params[0]; FirstParam.Real /= Args[0].Real; Params[0] = FirstParam; }
/// <summary> /// Assigns the value of arg1 to arg2. /// </summary> /// <param name="Args">A ScriptArguments instance.</param> public static void IntLeftDivisionAssignment(ref ScriptArguments Args) { var Params = Args.GetParameters(); SCMOpcodeParameter FirstParam = Params[0]; FirstParam.Integer /= Args[0].Integer; Params[0] = FirstParam; }
/// <summary> /// Assigns the value of arg1 to arg2. /// </summary> /// <param name="Args">A ScriptArguments instance.</param> public static void FloatRightMultiplicationAssignment(ref ScriptArguments Args) { var Params = Args.GetParameters(); SCMOpcodeParameter SecondParam = Params[1]; SecondParam.Real *= Args[0].Real; Params[1] = SecondParam; }
/// <summary> /// Assigns the value of arg1 to arg2. /// </summary> /// <param name="Args">A ScriptArguments instance.</param> public static void IntRightSubtractionAssignment(ref ScriptArguments Args) { var Params = Args.GetParameters(); SCMOpcodeParameter SecondParam = Params[1]; SecondParam.Integer -= Args[0].Integer; Params[1] = SecondParam; }
/// <summary> /// Assigns the value of arg1 to arg2. /// </summary> /// <param name="Args">A ScriptArguments instance.</param> public static void FloatRightDivisionAssignment(ref ScriptArguments Args) { var Params = Args.GetParameters(); SCMOpcodeParameter SecondParam = Params[1]; //I'm assuming the assignment happens right to left here, as that is default for C++. SecondParam.Real /= Args[0].Real; Params[1] = SecondParam; }
/// <summary> /// Assigns the value of arg1 to arg2. /// </summary> /// <param name="Args">A ScriptArguments instance.</param> public static void IntRightAssignment(ref ScriptArguments Args) { var Params = Args.GetParameters(); SCMOpcodeParameter SecondParam = Params[1]; //I'm assuming the assignment happens right to left here, as that is default for C++. SecondParam.Integer = Args[0].Integer; Params[1] = SecondParam; }
/// <summary> /// Checks if the floating-point value stored in the global variable is /// greater than the floating-point value stored in the global variable. /// </summary> /// <param name="Args">A ScriptArguments instance.</param> /// <returns></returns> public static bool IsFloatVarGreaterThanFloatVar(ref ScriptArguments Args) { SCMOpcodeParameter FirstParam = Args[0]; if (Args[1].Integer > FirstParam.GlobalInteger) { return(true); } return(false); }
/// <summary> // Checks if the floating-point number is greater than the value stored in the local variable. /// </summary> /// <param name="Args">A ScriptArguments instance.</param> /// <returns>True if greater than, false otherwise.</returns> public static bool IsNumberGreaterThanFloatLVar(ref ScriptArguments Args) { SCMOpcodeParameter FirstParam = Args[0]; if (Args[1].Real > FirstParam.Real) { return(true); } return(false); }
/// <summary> /// Checks if the integer value stored in the local variable is greater than the integer number. /// </summary> /// <param name="Args">A ScriptArguments instance.</param> /// <returns></returns> public static bool IsIntLVarGreaterThanNumber(ref ScriptArguments Args) { SCMOpcodeParameter FirstParam = Args[0]; if (FirstParam.Integer > Args[1].Integer) { return(true); } return(false); }
/// <summary> /// Sets the value of a global variable to a specified integer. /// </summary> /// <param name="Args">A ScriptArguments instance.</param> public static void SetVarInt(ref ScriptArguments Args) { /*var Params = Args.GetParameters(); * SCMOpcodeParameter SecondParam = Params[1]; * * //I'm assuming the assignment happens right to left here, as that is default for C++. * SecondParam.Integer = Args[0].Integer; * Params[1] = SecondParam;*/ SCMOpcodeParameter FirstParam = Args[0]; FirstParam.GlobalInteger = Args[1].Integer; Args[0] = FirstParam; //This should work, in theory. }
private void ExecuteThread(SCMThread Thread, int MSPassed) { ///TODO: Fully implement this. /*auto player = state->world->getPlayer(); * * if (player) * {*/ if (Thread.IsMission && Thread.DeathOrArrestCheck /*&& * (player->isWasted() || player->isBusted())*/) { Thread.WastedOrBusted = true; Thread.StackDepth = 0; Thread.ProgramCounter = Thread.Calls[(int)Thread.StackDepth]; } //} // There is 02a1 opcode that is used only during "Kingdom Come", which // basically acts like a wait command, but waiting time can be skipped // by pressing 'X'? PS2 button if (Thread.AllowWaitSkip /*&& getState()->input[0].pressed(GameInputState::Jump)*/) { Thread.WakeCounter = 0; Thread.AllowWaitSkip = false; } if (Thread.WakeCounter > 0) { Thread.WakeCounter = Math.Max(Thread.WakeCounter - MSPassed, 0); } if (Thread.WakeCounter > 0) { return; } while (Thread.WakeCounter == 0) { var PC = Thread.ProgramCounter; var Opcode = file.Read <ushort>(PC); bool IsNegatedConditional = ((Opcode & SCM_NEGATE_CONDITIONAL_MASK) == SCM_NEGATE_CONDITIONAL_MASK); Opcode = (ushort)(Opcode & ~SCM_NEGATE_CONDITIONAL_MASK); ScriptFunctionMeta FoundCode; if (!module.FindOpcode(Opcode, out FoundCode)) { throw new IllegalInstruction <Exception>(Opcode, PC, Thread.Name); } ScriptFunctionMeta Code = FoundCode; PC += sizeof(ushort); List <SCMOpcodeParameter> Parameters = new List <SCMOpcodeParameter>(); bool HasExtraParameters = Code.Arguments < 0; var RequiredParams = Math.Abs(Code.Arguments); for (int p = 0; p < RequiredParams || HasExtraParameters; ++p) { //byte was originally SCMByte ... might have to change to char. var type_r = file.Read <byte>(PC); var type = (SCMType)type_r; if (type_r > 42) { // for implicit strings, we need the byte we just read. type = SCMType.TString; } else { PC += sizeof(byte); } //TODO: Is this correct? //Parameters.push_back(SCMOpcodeParameter{ type, { 0} }); Parameters.Add(new SCMOpcodeParameter(type)); switch (type) { case SCMType.EndOfArgList: HasExtraParameters = false; break; case SCMType.TInt8: lock (Parameters) //Thread safety { SCMOpcodeParameter Param = Parameters.LastOrDefault(); Param.Integer = file.Read <byte>(PC); Parameters[Parameters.Count - 1] = Param; } PC += sizeof(byte); break; case SCMType.TInt16: lock (Parameters) //Thread safety { SCMOpcodeParameter Param = Parameters.LastOrDefault(); Param.Integer = file.Read <short>(PC); Parameters[Parameters.Count - 1] = Param; } PC += sizeof(byte) * 2; break; case SCMType.TGlobal: { var v = file.Read <ushort>(PC); lock (Parameters) //Thread safety { SCMOpcodeParameter Param = Parameters.LastOrDefault(); //TODO: This was originally GlobalData.data() + v... Param.GlobalPtr = (IntPtr)globalData.ToArray().Length + v * SCM_VARIABLE_SIZE; Parameters[Parameters.Count - 1] = Param; } if (v >= file.GlobalsSize) { Debug.WriteLine("ERROR: ScriptMachine.cs: Global out of bounds! " + v.ToString() + " " + file.GlobalsSize.ToString()); } PC += sizeof(byte) * 2; } break; case SCMType.TLocal: { var v = file.Read <ushort>(PC); lock (Parameters) { SCMOpcodeParameter Param = Parameters.LastOrDefault(); //Not sure if this is correct, was originally Locals.data() + v... Param.GlobalPtr = (IntPtr)Thread.Locals.ToArray().Length + v * SCM_VARIABLE_SIZE; Parameters[Parameters.Count - 1] = Param; } if (v >= SCM_THREAD_LOCAL_SIZE) { Debug.WriteLine("Scriptmachine.CS: Local out of bounds!"); } PC += sizeof(byte) * 2; } break; case SCMType.TInt32: lock (Parameters) //Thread safety { SCMOpcodeParameter Param = Parameters.LastOrDefault(); Param.Integer = file.Read <int>(PC); Parameters[Parameters.Count - 1] = Param; } PC += sizeof(byte) * 4; break; case SCMType.TString: lock (Parameters) //Thread safety { SCMOpcodeParameter Param = Parameters.LastOrDefault(); char[] Str = Param.Str.ToArray(); //Copy a string from the file data to the string. Array.Copy(file.Data.ToArray(), (int)PC, Str, 0, 8); Param.Str = new string(Str); Parameters[Parameters.Count - 1] = Param; } PC += sizeof(byte) * 8; break; case SCMType.TFloat16: lock (Parameters) //Thread safety { SCMOpcodeParameter Param = Parameters.LastOrDefault(); Param.Real = file.Read <short>(PC) / 16f; Parameters[Parameters.Count - 1] = Param; } PC += sizeof(byte) * 2; break; default: throw new UnknownType <Exception>((char)type, PC, Thread.Name); } ; ScriptArguments Sca = new ScriptArguments(Parameters, Thread, this);