/// <summary> /// Nope = no operation. /// Opcode: 0000 /// </summary> /// <param name="Args">An instance of ScriptArguments.</param> public static void Nope(ScriptArguments Args) { //DO NOTHING! HURRAY! }
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);