Esempio n. 1
0
        /// <summary>
        /// Ends a thread on the ScriptMachine.
        /// </summary>
        /// <param name="Args">A ScriptArguments instance.</param>
        public static void EndThread(ref ScriptArguments Args)
        {
            SCMThread Thread = Args.GetThread();

            Thread.WakeCounter = -1;
            Thread.Finished    = true;
        }
Esempio n. 2
0
        /// <summary>
        /// Starts a new thread on the ScriptMachine.
        /// </summary>
        /// <param name="Args">A ScriptArguments instance.</param>
        public static void StartThread(ref ScriptArguments Args)
        {
            Args.GetVM().StartThread((uint)Args.GetIntParameter(0), false);
            var       Threads = Args.GetVM().GetThreads();
            SCMThread Thread  = Threads[Threads.Count - 1];

            var Locals = Thread.Locals.ToArray();

            // Copy arguments to locals
            for (var i = 1u; i < Args.GetParameters().Count; ++i)
            {
                if (Args[i].Type == SCMType.EndOfArgList)
                {
                    break;
                }

                /**reinterpret_cast<ScriptInt*>(Thread.Locals.ToArray() +
                 *  sizeof(int) * (i - 1)) = args[i].integerValue();*/
                byte[] SrcInt = BitConverter.GetBytes(Args[i].IntegerValue());
                Array.Copy(SrcInt, 0, Locals, sizeof(int) * (i - 1), SrcInt.Length - 1);
                Thread.Locals.AddRange(Locals);
            }
        }
Esempio n. 3
0
        /// <summary>
        /// Starts a thread on this ScriptMachine instance.
        /// </summary>
        /// <param name="StartAddress">The address to start executing from.</param>
        /// <param name="Mission">Is this a mission thread?</param>
        public void StartThread(uint StartAddress, bool Mission)
        {
            SCMThread Thread = new SCMThread();

            for (int i = 0; i < SCM_THREAD_LOCAL_SIZE * SCM_VARIABLE_SIZE; ++i)
            {
                Thread.Locals[i] = (char)0;
            }

            Thread.Name               = "THREAD";
            Thread.ConditionResult    = false;
            Thread.ConditionCount     = 0;
            Thread.ConditionAND       = false;
            Thread.ProgramCounter     = StartAddress;
            Thread.BaseAddress        = StartAddress; /* Indicates where negative jumps should jump from */
            Thread.WakeCounter        = 0;
            Thread.IsMission          = Mission;
            Thread.Finished           = false;
            Thread.StackDepth         = 0;
            Thread.DeathOrArrestCheck = true;
            Thread.WastedOrBusted     = false;
            Thread.AllowWaitSkip      = false;
            activeThreads.Add(Thread);
        }
Esempio n. 4
0
 public ScriptArguments(List <SCMOpcodeParameter> P, SCMThread T, ScriptMachine M)
 {
     parameters = P;
     thread     = T;
     machine    = M;
 }
Esempio n. 5
0
        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);