Пример #1
0
 /// <summary>
 /// 取一个变量作右值
 /// </summary>
 /// <param name="varName">变量名</param>
 /// <param name="vsm">关于哪个调用堆栈做动作</param>
 /// <returns>变量的引用</returns>
 public object Fetch(string varName, StackMachine vsm)
 {
     // 处理局部变量
     if (varName.StartsWith("$"))
     {
         // 非函数调用
         if (this.GameState(vsm) != StackMachineState.FunctionCalling)
         {
             return(this.Symbols.SceneCtxDao.Fetch(ResourceManager.GetInstance().GetScene(vsm.EBP.ScriptName), varName.Replace("$", String.Empty)));
         }
         // 函数调用
         var funFrame = vsm.ESP.BindingFunction;
         return(funFrame.Symbols[varName.Replace("$", String.Empty)]);
     }
     // 处理全局变量
     if (varName.StartsWith("&"))
     {
         return(this.Symbols.GlobalCtxDao.GlobalFetch(varName.Replace("&", String.Empty)));
     }
     // 处理持久化变量
     if (varName.StartsWith("%"))
     {
         return(PersistContextDAO.Fetch(varName.Replace("%", String.Empty)));
     }
     return(null);
 }
Пример #2
0
 /// <summary>
 /// 获取某个变量关于一个栈机所在的上下文
 /// </summary>
 /// <param name="varName">变量名</param>
 /// <param name="vsm">栈机实例</param>
 /// <returns>该变量所在的上下文对象</returns>
 public EvaluatableContext GetContext(string varName, StackMachine vsm)
 {
     // 处理局部变量
     if (varName.StartsWith("$"))
     {
         // 非函数调用
         if (this.GameState(vsm) != StackMachineState.FunctionCalling)
         {
             return(this.Symbols.SceneCtxDao.FindSceneContext(vsm.EBP.ScriptName));
         }
         // 函数调用
         var funFrame = vsm.ESP.BindingFunction;
         return(new SimpleContext(funFrame.Symbols));
     }
     // 处理全局变量
     if (SymbolTable.IsSwitchExpression(varName))
     {
         return(this.Symbols.GlobalCtxDao.GlobalSwitchList);
     }
     else if (varName.StartsWith("&"))
     {
         return(this.Symbols.GlobalCtxDao.GlobalSymbolTable);
     }
     // 处理持久化变量
     if (varName.StartsWith("%"))
     {
         return(PersistContextDAO.PersistenceContext);
     }
     return(null);
 }
Пример #3
0
 /// <summary>
 /// 左值运算一个变量
 /// </summary>
 /// <param name="varname">变量名</param>
 /// <param name="valuePolish">右值逆波兰式</param>
 /// <param name="vsm">关于哪个调用堆栈做动作</param>
 public void Assignment(string varname, string valuePolish, StackMachine vsm)
 {
     // 处理局部变量
     if (varname.StartsWith("$"))
     {
         // 非函数调用
         if (this.GameState(vsm) != StackMachineState.FunctionCalling)
         {
             this.Symbols.SceneCtxDao.Assign(vsm.EBP.ScriptName, varname.Replace("$", String.Empty), PolishEvaluator.Evaluate(valuePolish, vsm));
         }
         // 函数调用
         else
         {
             var functionFrame = vsm.ESP.BindingFunction;
             functionFrame.Symbols[varname.Replace("$", String.Empty)] = PolishEvaluator.Evaluate(valuePolish, vsm);
         }
     }
     // 处理全局变量
     else if (varname.StartsWith("&"))
     {
         this.Symbols.GlobalCtxDao.GlobalAssign(varname.Replace("&", String.Empty), PolishEvaluator.Evaluate(valuePolish, vsm));
     }
     // 处理持久化变量
     else if (varname.StartsWith("%"))
     {
         PersistContextDAO.Assign(varname.Replace("%", String.Empty), PolishEvaluator.Evaluate(valuePolish, vsm));
     }
 }
Пример #4
0
        public bool IsCompliant(X509Certificate2 cert, IPolicyExpression expression)
        {
            if (m_compiler == null)
            {
                throw new InvalidOperationException("Compiler cannot be null");
            }

            StackMachine    executionEngine = new StackMachine();
            IList <IOpCode> opcodes         = m_compiler.Compile(cert, expression);
            var             compliant       = executionEngine.Evaluate(opcodes);

            return(compliant);
        }
Пример #5
0
        /// <summary>
        /// 立即结束本次调用
        /// </summary>
        /// <param name="svm">要作用的调用堆栈</param>
        public void ExitCall(StackMachine svm)
        {
            // 弹调用堆栈
            var consumed = svm.Consume();

            // 弹出的是主堆栈上的场景
            if (svm == this.CallStack && consumed.State == StackMachineState.Interpreting)
            {
                // 恢复到上一个并行栈帧的状态
                this.BackTraceParallel();
                // 关闭当前的信号量订阅者
                SemaphoreDispatcher.UnregisterSemaphoreService();
            }
        }
Пример #6
0
        static void Main(string[] args)
        {
            var main_code_text = File.ReadAllText(args[2]);

            //Console.WriteLine(main_code_text.GetHashCode());
            Console.WriteLine("-------------------------------------------------");
            Console.WriteLine("Сode received in the Gonozov's language: ");
            Console.WriteLine("- - - - - - - - - - - - - - - - - - - - - - - - -");
            Console.WriteLine(main_code_text);
            Console.WriteLine("-------------------------------------------------");

            VariableTable <Function> globalFuncTable = new VariableTable <Function>();

            PrecedenceBasedRegexTokenizer tokenizer = new PrecedenceBasedRegexTokenizer();
            PrecedenceBasedRPNParser      parser    = new PrecedenceBasedRPNParser(ref globalFuncTable);
            TriadsOptimizer triadsOptimizer         = new TriadsOptimizer();
            StackMachine    stackMachine            = new StackMachine(globalFuncTable);


            var tokenSeqence = tokenizer.Tokenize(main_code_text).ToList();

            foreach (var token in tokenSeqence)
            {
                Console.Write(token.ToString() + " , ");
            }
            Console.WriteLine("\n-------------------------------------------------");

            var parseSequence = parser.Parse(tokenSeqence);

            foreach (var result in parseSequence)
            {
                Console.Write(result.ToString() + " , ");
            }
            Console.WriteLine("\n-------------------------------------------------");

            globalFuncTable.Print();

            //parseSequence = triadsOptimizer.Optimize(parseSequence);

            //Console.WriteLine("\n-------------------------------------------------");

            //foreach (var result in parseSequence)
            //{
            //    Console.Write(result.ToString() + " , ");
            //}

            //Console.WriteLine("\n-------------------------------------------------");

            stackMachine.Execute(parseSequence);
        }
Пример #7
0
        /// <summary>
        /// 取下一动作指令并暂存当前执行的动作
        /// </summary>
        /// <param name="vsm">关于哪个调用堆栈做动作</param>
        /// <returns>动作实例</returns>
        public SceneAction MoveNext(StackMachine vsm)
        {
            SceneAction fetched = this.FetchNextInstruction(vsm);

            if (fetched != null && vsm.ESP.State == StackMachineState.Interpreting)
            {
                this.DashingPureSa = fetched.Clone(true);
                if (this.DashingPureSa.Type == SActionType.act_dialog ||
                    this.DashingPureSa.Type == SActionType.act_branch)
                {
                    RollbackManager.SteadyForward(false, this.DashingPureSa, this.Musics, this.Backlogs);
                }
            }
            return(fetched);
        }
Пример #8
0
        /// <summary>
        /// 调度一个信号处理机
        /// </summary>
        /// <param name="selphine">信号量</param>
        /// <param name="shandler">处理机</param>
        public static void Schedule(YuriSemaphore selphine, SemaphoreHandler shandler)
        {
            if (!SemaphoreDispatcher.EnableDispatcher)
            {
                return;
            }
            switch (shandler.Type)
            {
            case SemaphoreHandlerType.ScheduleOnce:
                var handleFunc = selphine.Activated ? shandler.ActivateFunc : shandler.DeActivateFunc;
                if (handleFunc == null)
                {
                    return;
                }
                ParallelExecutor pExec = new ParallelExecutor()
                {
                    Scenario = handleFunc.ParentSceneName
                };
                DispatcherTimer dt = new DispatcherTimer
                {
                    Interval = TimeSpan.FromTicks((long)GlobalConfigContext.DirectorTimerInterval)
                };
                dt.Tick         += Director.RunMana.ParallelHandler;
                pExec.Dispatcher = dt;
                var pvm = new StackMachine();
                pvm.SetMachineName("SemaphoreVM#" + handleFunc.GlobalName);
                pvm.Submit(handleFunc, new List <object>());
                pExec.Executor = pvm;
                ParallelDispatcherArgsPackage pdap = new ParallelDispatcherArgsPackage()
                {
                    Index          = -1,
                    Render         = new UpdateRender(pvm),
                    BindingSF      = handleFunc,
                    IsSemaphore    = true,
                    SemaphoreStack = pvm
                };
                dt.Tag = pdap;
                shandler.Dispatcher = dt;
                dt.Start();
                break;

            case SemaphoreHandlerType.ScheduleForever:
                throw new NotImplementedException();

            case SemaphoreHandlerType.ScheduleWhenActivated:
                throw new NotImplementedException();
            }
        }
Пример #9
0
        public void BasicTest()
        {
            var result = StackMachine.Solution("13 DUP 4 POP 5 DUP + DUP + -");

            result.Should().Be(7);

            result = StackMachine.Solution("DUP DUP");
            result.Should().Be(StackMachine.ErrorValue);

            result = StackMachine.Solution("14");
            result.Should().Be(14);

            result = StackMachine.Solution("14 DUP");
            result.Should().Be(14);

            result = StackMachine.Solution("14 POP");
            result.Should().Be(StackMachine.ErrorValue);

            result = StackMachine.Solution("14 6 +");
            result.Should().Be(20);

            result = StackMachine.Solution("4 14 -");
            result.Should().Be(10);

            result = StackMachine.Solution("POP");
            result.Should().Be(StackMachine.ErrorValue);

            result = StackMachine.Solution("DUP");
            result.Should().Be(StackMachine.ErrorValue);

            result = StackMachine.Solution("14 4 5 + +");
            result.Should().Be(23);

            result = StackMachine.Solution("1040000");
            result.Should().Be(1040000);

            result = StackMachine.Solution("1050000");
            result.Should().Be(StackMachine.ErrorValue);

            result = StackMachine.Solution("1040000 1000 +");
            result.Should().Be(1041000);

            result = StackMachine.Solution("1040000 10000 +");
            result.Should().Be(StackMachine.ErrorValue);

            result = StackMachine.Solution("1041000 1040000 -");
            result.Should().Be(StackMachine.ErrorValue);
        }
Пример #10
0
        /// <summary>
        /// 函数调用
        /// </summary>
        /// <param name="function">函数模板实例</param>
        /// <param name="args">参数列表</param>
        /// <param name="vsm">关于哪个调用堆栈做动作</param>
        public void CallFunction(SceneFunction function, List <object> args, StackMachine vsm)
        {
            LogUtils.LogLine(String.Format("Call Function: {0}", function.GlobalName),
                             "RuntimeManager", LogLevel.Important);
            // 为模板创建一个分支实例
            var callForker = function.Fork(true);

            vsm.Submit(callForker, args);
            // 处理参数传递
            var funcSymbols = callForker.Symbols;

            for (int i = 0; i < args.Count; i++)
            {
                funcSymbols[callForker.Param[i].Substring(1)] = args[i];
            }
        }
Пример #11
0
        static int Main(string[] args)
        {
            if (args.Length < 1)
            {
                Console.Error.WriteLine("No source code is provided!");
                return(1);
            }
            var name  = System.IO.Path.GetFileNameWithoutExtension(args[0]);
            var lines = System.IO.File.ReadAllLines(args[0]);
            var sm    = new StackMachine(name, Console.Out);

            foreach (var line in lines)
            {
                var command = ParseCommand(line);
                command.Generate(sm);
            }
            return(0);
        }
Пример #12
0
        static void Generate(string[] filePaths)
        {
            var sm = new StackMachine(
                Console.Out,
                filePaths
                .Select(f => System.IO.Path.GetFileNameWithoutExtension(f))
                .Where(n => n == "Sys")
                .Count() > 0);

            foreach (var filePath in filePaths)
            {
                sm.SetName(System.IO.Path.GetFileNameWithoutExtension(filePath));
                var lines = System.IO.File.ReadAllLines(filePath);
                foreach (var line in lines)
                {
                    var command = ParseCommand(line);
                    command.Generate(sm);
                }
            }
        }
Пример #13
0
        /// <summary>
        /// 构造场景的并行处理
        /// </summary>
        /// <param name="scene">需要构造的场景实例</param>
        public void ConstructParallel(Scene scene)
        {
            var execList = new List <ParallelExecutor>();

            if (scene.ParallellerContainer.Count > 0)
            {
                int counter = 0;
                foreach (var psf in scene.ParallellerContainer)
                {
                    ParallelExecutor pExec = new ParallelExecutor()
                    {
                        Scenario = scene.Scenario
                    };
                    DispatcherTimer dt = new DispatcherTimer
                    {
                        Interval = TimeSpan.FromTicks((long)GlobalConfigContext.DirectorTimerInterval)
                    };
                    dt.Tick         += this.ParallelHandler;
                    pExec.Dispatcher = dt;
                    var pvm = new StackMachine();
                    pvm.SetMachineName("VM#" + psf.GlobalName);
                    pvm.Submit(psf, new List <object>());
                    pExec.Executor = pvm;
                    ParallelDispatcherArgsPackage pdap = new ParallelDispatcherArgsPackage()
                    {
                        Index       = counter++,
                        Render      = new UpdateRender(pvm),
                        BindingSF   = psf,
                        IsSemaphore = false
                    };
                    dt.Tag = pdap;
                    dt.Start();
                    execList.Add(pExec);
                }
            }
            this.ParallelExecutorStack.Push(execList);
        }
Пример #14
0
 public void Generate(StackMachine machine)
 {
     machine.ToLabel(this);
 }
Пример #15
0
 public void Generate(StackMachine machine)
 {
     machine.Sub(this);
 }
Пример #16
0
 public void Generate(StackMachine machine)
 {
     machine.Push(this);
 }
Пример #17
0
 /// <summary>
 /// 获取当前调用堆栈顶部状态
 /// </summary>
 /// <param name="vsm">关于哪个调用堆栈做动作</param>
 /// <returns>栈顶状态</returns>
 public StackMachineState GameState(StackMachine vsm) => vsm.ESP?.State ?? StackMachineState.NOP;
Пример #18
0
 /// <summary>
 /// 向运行时环境发出中断
 /// </summary>
 /// <param name="vsm">要提交的调用堆栈</param>
 /// <param name="ntr">中断</param>
 public void SubmitInterrupt(StackMachine vsm, Interrupt ntr)
 {
     vsm.Submit(ntr);
 }
Пример #19
0
 public void Generate(StackMachine machine)
 {
     machine.Call(this);
 }
Пример #20
0
        public static MissonDefinition ReadMsnMission(string filename)
        {
            MissonDefinition mdef = new MissonDefinition();

            using (Bwd2Reader msn = new Bwd2Reader(filename))
            {
                msn.FindNext("WDEF");
                using (Bwd2Reader wdef = new Bwd2Reader(msn))
                {
                    wdef.FindNext("WRLD");
                    wdef.Position               += 30;
                    mdef.PaletteFilePath         = wdef.ReadCString(13);
                    mdef.LumaTableFilePath       = wdef.ReadCString(13);
                    mdef.XlucencyTableFilePath   = wdef.ReadCString(13);
                    mdef.ObjectiveFilePath       = wdef.ReadCString(13);
                    mdef.SkyTextureFilePath      = wdef.ReadCString(13);
                    mdef.ScroungeTextureFilePath = wdef.ReadCString(13);
                    mdef.SurfaceTextureFilePath  = wdef.ReadCString(13);
                    mdef.LevelMapFilePath        = wdef.ReadCString(13);
                    mdef.HzdFilePath             = wdef.ReadCString(13);
                }
                msn.FindNext("TDEF");
                List <float[, ]> heights = new List <float[, ]>();
                using (Bwd2Reader tdef = new Bwd2Reader(msn))
                {
                    tdef.FindNext("ZMAP");
                    byte   numUniqueTerrainPatches = tdef.ReadByte();
                    byte[] patchConfig             = tdef.ReadBytes(80 * 80);

                    tdef.FindNext("ZONE");
                    byte   unk             = tdef.ReadByte();
                    string terrainFilePath = tdef.ReadCString(13);

                    using (FastBinaryReader terr = VirtualFilesystem.Instance.GetFileStream(terrainFilePath))
                    {
                        for (int i = 0; i < numUniqueTerrainPatches; i++)
                        {
                            float[,] h = new float[129, 129];
                            for (int z = 0; z < 128; z++)
                            {
                                for (int x = 0; x < 128; x++)
                                {
                                    ushort tpoint = terr.ReadUInt16();
                                    float  height = (tpoint & 0xFFF) / 4096.0f;
                                    h[z, x] = height;
                                }
                            }

                            heights.Add(h);
                        }
                    }

                    Vector2 botLeft  = new Vector2(80, 80);
                    Vector2 topRight = new Vector2(0, 0);

                    float[,] defaultHeights = new float[129, 129];
                    for (int z = 0; z < 80; z++)
                    {
                        for (int x = 0; x < 80; x++)
                        {
                            byte patchIdx = patchConfig[z * 80 + x];
                            if (patchIdx == 0xFF)
                            {
                                //mdef.TerrainPatches[x, z] = new TerrainPatch(defaultTerrainData);
                            }
                            else
                            {
                                if (x < botLeft.x)
                                {
                                    botLeft.x = x;
                                }
                                if (z < botLeft.y)
                                {
                                    botLeft.y = z;
                                }
                                if (x > topRight.x)
                                {
                                    topRight.x = x;
                                }
                                if (z > topRight.y)
                                {
                                    topRight.y = z;
                                }

                                float[,] h = heights[patchIdx];
                                int rightPatchIdx = x == 79 ? 0xFF : patchConfig[z * 80 + x + 1];
                                float[,] rightHeights = rightPatchIdx == 0xFF ? defaultHeights : heights[rightPatchIdx];
                                for (int xx = 0; xx < 129; xx++)
                                {
                                    h[xx, 128] = rightHeights[xx, 0];
                                }

                                int bottomPatchIdx = z == 79 ? 0xFF : patchConfig[(z + 1) * 80 + x];
                                float[,] bottomHeights = bottomPatchIdx == 0xFF ? defaultHeights : heights[bottomPatchIdx];
                                for (int zz = 0; zz < 129; zz++)
                                {
                                    h[128, zz] = bottomHeights[0, zz];
                                }

                                int bottomRightPatchIdx = z == 79 || x == 79 ? 0xFF : patchConfig[(z + 1) * 80 + x + 1];
                                float[,] bottomRightHeights = bottomRightPatchIdx == 0xFF
                                    ? defaultHeights
                                    : heights[bottomRightPatchIdx];
                                h[128, 128] = bottomRightHeights[0, 0];

                                TerrainData tdata = CreateTerrainData();
                                tdata.SetHeights(0, 0, h);
                                mdef.TerrainPatches[x, z] = new TerrainPatch(tdata);
                            }
                        }
                    }
                    mdef.Middle = (topRight + botLeft) / 2.0f;
                }

                msn.FindNext("RDEF");
                using (Bwd2Reader rdef = new Bwd2Reader(msn))
                {
                    rdef.FindNext("RSEG");
                    while (rdef.Current != null && rdef.Current.Name != "EXIT")
                    {
                        uint segmentType       = rdef.ReadUInt32();
                        uint segmentPieceCount = rdef.ReadUInt32();
                        Road road = new Road
                        {
                            SegmentType  = (RoadSegmentType)segmentType,
                            RoadSegments = new RoadSegment[segmentPieceCount]
                        };

                        for (int i = 0; i < segmentPieceCount; i++)
                        {
                            RoadSegment roadSegment = new RoadSegment
                            {
                                Left  = new Vector3(rdef.ReadSingle(), rdef.ReadSingle(), rdef.ReadSingle()),
                                Right = new Vector3(rdef.ReadSingle(), rdef.ReadSingle(), rdef.ReadSingle())
                            };

                            Vector3 pos            = roadSegment.Left;
                            int     patchPosX      = (int)(pos.x / 640.0f);
                            int     patchPosZ      = (int)(pos.z / 640.0f);
                            float   localPositionX = (pos.x % 640) / 640.0f;
                            float   localPositionZ = (pos.z % 640) / 640.0f;
                            float   y =
                                mdef.TerrainPatches[patchPosX, patchPosZ].TerrainData.GetInterpolatedHeight(localPositionX,
                                                                                                            localPositionZ) + 0.1f;
                            pos.y            = y;
                            roadSegment.Left = pos;

                            pos            = roadSegment.Right;
                            patchPosX      = (int)(pos.x / 640.0f);
                            patchPosZ      = (int)(pos.z / 640.0f);
                            localPositionX = (pos.x % 640) / 640.0f;
                            localPositionZ = (pos.z % 640) / 640.0f;
                            y =
                                mdef.TerrainPatches[patchPosX, patchPosZ].TerrainData.GetInterpolatedHeight(localPositionX,
                                                                                                            localPositionZ) + 0.1f;
                            pos.y             = y;
                            roadSegment.Right = pos;

                            road.RoadSegments[i] = roadSegment;
                            //TODO: Figure out
                        }
                        mdef.Roads.Add(road);

                        rdef.Next();
                    }
                }

                msn.FindNext("ODEF");
                using (Bwd2Reader odef = new Bwd2Reader(msn))
                {
                    odef.FindNext("OBJ");
                    while (odef.Current.Name != "EXIT")
                    {
                        byte[]        rawlabel     = odef.ReadBytes(8);
                        int           labelhigh    = 0;
                        StringBuilder labelBuilder = new StringBuilder();
                        for (int i = 0; i < 8; i++)
                        {
                            byte v = rawlabel[i];
                            if (v > 0x7f)
                            {
                                labelhigh = (labelhigh << 1) | 0x01;
                            }
                            else
                            {
                                labelhigh = (labelhigh << 1) & 0xfe;
                            }
                            v = (byte)(v & 0x7f);
                            if (v != 0)
                            {
                                labelBuilder.Append((char)v);
                            }
                        }
                        string  label   = labelBuilder.ToString();
                        Vector3 right   = new Vector3(odef.ReadSingle(), odef.ReadSingle(), odef.ReadSingle());
                        Vector3 upwards = new Vector3(odef.ReadSingle(), odef.ReadSingle(), odef.ReadSingle());
                        Vector3 forward = new Vector3(odef.ReadSingle(), odef.ReadSingle(), odef.ReadSingle());
                        Vector3 pos     = new Vector3(odef.ReadSingle(), odef.ReadSingle(), odef.ReadSingle());

                        odef.Position += 36;
                        ClassId classId = (ClassId)odef.ReadUInt32();
                        ushort  flags   = odef.ReadUInt16();
                        ushort  teamId  = odef.ReadUInt16();

                        Vector3 localPosition = new Vector3(pos.x % 640, pos.y, pos.z % 640);
                        int     patchPosX     = (int)(pos.x / 640.0f);
                        int     patchPosZ     = (int)(pos.z / 640.0f);
                        mdef.TerrainPatches[patchPosX, patchPosZ].Objects.Add(new Odef
                        {
                            Label         = label,
                            Id            = labelhigh,
                            LocalPosition = localPosition,
                            ClassId       = classId,
                            TeamId        = teamId,
                            IsPlayer      = flags == 16,
                            LocalRotation = Quaternion.LookRotation(forward, upwards)
                        });

                        odef.Next();
                    }
                }

                msn.FindNext("LDEF");
                using (Bwd2Reader ldef = new Bwd2Reader(msn))
                {
                    ldef.FindNext("OBJ");
                    while (ldef.Current != null && ldef.Current.Name != "EXIT")
                    {
                        string label = ldef.ReadCString(8);
                        ldef.Position += 84;
                        ClassId classId = (ClassId)ldef.ReadUInt32();
                        ldef.ReadUInt32();
                        uint numStrings = ldef.ReadUInt32();

                        Vector3[] stringPositions = new Vector3[numStrings];
                        for (int i = 0; i < numStrings; i++)
                        {
                            Vector3 stringPos = new Vector3(ldef.ReadSingle(), ldef.ReadSingle(), ldef.ReadSingle());
                            stringPositions[i] = stringPos;
                        }

                        mdef.StringObjects.Add(new Ldef
                        {
                            Label           = label,
                            StringPositions = stringPositions
                        });

                        ldef.Next();
                    }
                }

                msn.FindNext("ADEF");
                using (Bwd2Reader adef = new Bwd2Reader(msn))
                {
                    adef.FindNext("FSM");
                    if (adef.Current != null && adef.Current.DataLength > 0)
                    {
                        mdef.FSM = new FSM();

                        mdef.FSM.ActionTable = new string[adef.ReadUInt32()];
                        for (int i = 0; i < mdef.FSM.ActionTable.Length; i++)
                        {
                            mdef.FSM.ActionTable[i] = adef.ReadCString(40);
                        }

                        uint numEntities = adef.ReadUInt32();
                        mdef.FSM.EntityTable = new FSMEntity[numEntities];

                        for (int i = 0; i < numEntities; i++)
                        {
                            string label    = adef.ReadCString(40);
                            byte[] rawlabel = adef.ReadBytes(8);

                            int           labelhigh    = 0;
                            StringBuilder labelBuilder = new StringBuilder();
                            for (int j = 0; j < 8; j++)
                            {
                                byte v = rawlabel[j];
                                if (v > 0x7f)
                                {
                                    labelhigh = (labelhigh << 1) | 0x01;
                                }
                                else
                                {
                                    labelhigh = (labelhigh << 1) & 0xfe;
                                }

                                v = (byte)(v & 0x7f);
                                if (v != 0)
                                {
                                    labelBuilder.Append((char)v);
                                }
                            }

                            mdef.FSM.EntityTable[i] = new FSMEntity
                            {
                                Label = label,
                                Value = labelBuilder.ToString(),
                                Id    = labelhigh
                            };
                        }

                        mdef.FSM.SoundClipTable = new string[adef.ReadUInt32()];
                        for (int i = 0; i < mdef.FSM.SoundClipTable.Length; i++)
                        {
                            mdef.FSM.SoundClipTable[i] = adef.ReadCString(40);
                        }

                        uint numPaths = adef.ReadUInt32();
                        mdef.FSM.Paths = new FSMPath[numPaths];
                        for (int i = 0; i < numPaths; i++)
                        {
                            string       name  = adef.ReadCString(40);
                            I76Vector3[] nodes = new I76Vector3[adef.ReadUInt32()];
                            for (int p = 0; p < nodes.Length; p++)
                            {
                                nodes[p] = new I76Vector3(adef.ReadSingle(), adef.ReadSingle(), adef.ReadSingle());
                            }

                            mdef.FSM.Paths[i] = new FSMPath
                            {
                                Name  = name,
                                Nodes = nodes
                            };
                        }

                        uint numMachines = adef.ReadUInt32();
                        mdef.FSM.StackMachines = new StackMachine[numMachines];
                        for (int i = 0; i < numMachines; i++)
                        {
                            long next = adef.Position + 168;

                            StackMachine machine = new StackMachine();
                            machine.StartAddress     = adef.ReadUInt32();
                            machine.InitialArguments = new int[adef.ReadUInt32()];

                            for (int j = 0; j < machine.InitialArguments.Length; j++)
                            {
                                machine.InitialArguments[j] = adef.ReadInt32();
                            }

                            adef.Position = next;

                            mdef.FSM.StackMachines[i] = machine;
                        }

                        mdef.FSM.Constants = new IntRef[adef.ReadUInt32()];
                        for (int i = 0; i < mdef.FSM.Constants.Length; i++)
                        {
                            mdef.FSM.Constants[i] = new IntRef(adef.ReadInt32());
                        }

                        mdef.FSM.ByteCode = new ByteCode[adef.ReadUInt32()];
                        for (int i = 0; i < mdef.FSM.ByteCode.Length; i++)
                        {
                            ByteCode byteCode = mdef.FSM.ByteCode[i] = new ByteCode();
                            byteCode.OpCode = (OpCode)adef.ReadUInt32();
                            byteCode.Value  = adef.ReadInt32();
                        }
                    }
                }
            }
            return(mdef);
        }
Пример #21
0
        public static FSM ReadMission(string filename)
        {
            using (var msn = new Bwd2Reader(new FileStream(filename, FileMode.Open)))
            {
                msn.FindNext("ADEF");
                using (var adef = new Bwd2Reader(msn))
                {
                    adef.FindNext("FSM");
                    var fsm = new FSM();

                    fsm.ActionTable = new string[adef.ReadUInt32()];
                    for (int i = 0; i < fsm.ActionTable.Length; i++)
                    {
                        fsm.ActionTable[i] = adef.ReadCString(40);
                    }

                    var numEntities = adef.ReadUInt32();
                    fsm.EntityTable = new List <FSMEntity>();
                    var uniqueValues = new Dictionary <string, int>();

                    for (int i = 0; i < numEntities; i++)
                    {
                        var label = adef.ReadCString(40);
                        var value = adef.ReadCString(8);

                        var valueIndex = 0;
                        if (uniqueValues.ContainsKey(value))
                        {
                            valueIndex = uniqueValues[value] + 1;
                        }
                        uniqueValues[value] = valueIndex;

                        var uniqueValue = value + "_" + valueIndex;

                        fsm.EntityTable.Add(new FSMEntity
                        {
                            Label       = label,
                            Value       = value,
                            UniqueValue = uniqueValue
                        });
                    }

                    fsm.SoundClipTable = new string[adef.ReadUInt32()];
                    for (int i = 0; i < fsm.SoundClipTable.Length; i++)
                    {
                        fsm.SoundClipTable[i] = adef.ReadCString(40);
                    }

                    var numPaths = adef.ReadUInt32();
                    fsm.Paths = new List <FSMPath>();
                    for (int i = 0; i < numPaths; i++)
                    {
                        var name  = adef.ReadCString(40);
                        var nodes = new I76Vector3[adef.ReadUInt32()];
                        for (int p = 0; p < nodes.Length; p++)
                        {
                            nodes[p] = new I76Vector3(adef.ReadSingle(), adef.ReadSingle(), adef.ReadSingle());
                        }
                        fsm.Paths.Add(new FSMPath
                        {
                            Name  = name,
                            Nodes = nodes
                        });
                    }

                    fsm.StackMachines = new List <StackMachine>();
                    var numMachines = adef.ReadUInt32();
                    for (int i = 0; i < numMachines; i++)
                    {
                        var next = adef.BaseStream.Position + 168;

                        var machine = new StackMachine();
                        machine.StartAddress     = adef.ReadUInt32();
                        machine.InitialArguments = new int[adef.ReadUInt32()];

                        for (int j = 0; j < machine.InitialArguments.Length; j++)
                        {
                            machine.InitialArguments[j] = adef.ReadInt32();
                        }
                        adef.BaseStream.Position = next;

                        fsm.StackMachines.Add(machine);
                    }

                    fsm.Constants = new int[adef.ReadUInt32()];
                    for (int i = 0; i < fsm.Constants.Length; i++)
                    {
                        fsm.Constants[i] = adef.ReadInt32();
                    }

                    fsm.ByteCode = new ByteCode[adef.ReadUInt32()];
                    for (int i = 0; i < fsm.ByteCode.Length; i++)
                    {
                        var byteCode = fsm.ByteCode[i] = new ByteCode();
                        byteCode.OpCode = (OpCode)adef.ReadUInt32();
                        byteCode.Value  = adef.ReadInt32();
                    }
                    return(fsm);
                }
            }
        }
Пример #22
0
 /// <summary>
 /// 计算表达式的真值
 /// </summary>
 /// <param name="polish">表达式的逆波兰式</param>
 /// <param name="vsm">关于哪个调用堆栈做动作</param>
 /// <returns>表达式的真值</returns>
 public static bool EvaluateBoolean(string polish, StackMachine vsm)
 {
     return(Convert.ToBoolean(PolishEvaluator.Evaluate(polish, vsm)));
 }
Пример #23
0
 /// <summary>
 /// 修改主调用堆栈的引用
 /// </summary>
 /// <param name="vm">新的主调用堆栈</param>
 public void ResetCallstackObject(StackMachine vm)
 {
     this.CallStack = vm;
 }
Пример #24
0
        /// <summary>
        /// 在指定的调用堆栈上做递归寻指
        /// </summary>
        /// <param name="vsm">关于哪个调用堆栈做动作</param>
        /// <returns>动作实例</returns>
        private SceneAction FetchNextInstruction(StackMachine vsm)
        {
            // 调用栈已经为空时预备退出
            if (vsm.Count() == 0)
            {
                return(null);
            }
            // 取出当前要执行的指令
            if (vsm.ESP.State != StackMachineState.Interpreting &&
                vsm.ESP.State != StackMachineState.FunctionCalling)
            {
                return(null);
            }
            SceneAction ret = vsm.ESP.IP;

            // 如果没有下一指令就弹栈
            if (ret == null)
            {
                this.ExitCall(vsm);
                // 递归寻指
                return(this.FetchNextInstruction(vsm));
            }
            // 如果没有条件子句
            if (ret.CondPolish == String.Empty)
            {
                // 处理控制流程
                switch (ret.Type)
                {
                case SActionType.NOP:
                case SActionType.act_function:
                case SActionType.act_for:
                    // 优先进入trueRouting
                    if (ret.TrueRouting != null && ret.TrueRouting.Count > 0)
                    {
                        return(vsm.ESP.MircoStep(ret.TrueRouting[0]));
                    }
                    // falseRouting
                    if (ret.FalseRouting != null && ret.FalseRouting.Count > 0)
                    {
                        return(vsm.ESP.MircoStep(ret.FalseRouting[0]));
                    }
                    // next
                    return(vsm.ESP.MacroStep(ret));

                case SActionType.act_endfor:
                    // endfor直接跳过
                    return(vsm.ESP.MacroStep(ret));
                }
                // 移动下一指令指针,为下次处理做准备
                return(vsm.ESP.MacroStep(ret));
            }
            // 条件子句不为空时
            else
            {
                // 计算条件真值
                bool condBoolean = PolishEvaluator.EvaluateBoolean(ret.CondPolish, vsm);
                // 处理控制流程
                switch (ret.Type)
                {
                // IF语句
                case SActionType.act_if:
                    // 条件为真且有真分支
                    if (condBoolean == true && ret.TrueRouting != null && ret.TrueRouting.Count > 0)
                    {
                        // 移动下一指令指针,进入trueRouting
                        ret = vsm.ESP.MircoStep(ret.TrueRouting[0]);
                    }
                    // 条件为假且有假分支
                    else if (condBoolean == false && ret.FalseRouting != null && ret.FalseRouting.Count > 0)
                    {
                        // 移动下一指令指针,进入falseRouting
                        ret = vsm.ESP.MircoStep(ret.FalseRouting[0]);
                    }
                    // 没有执行的语句时,移动指令指针到next节点
                    else
                    {
                        // 跳过if语句
                        ret = vsm.ESP.MacroStep(ret);
                    }
                    // 返回当前要执行的指令实例
                    return(ret);

                // FOR语句
                case SActionType.act_for:
                    // 如果条件为真就进入真分支
                    if (condBoolean == true && ret.TrueRouting != null && ret.TrueRouting.Count > 0)
                    {
                        // 移动下一指令指针,进入trueRouting
                        ret = vsm.ESP.MircoStep(ret.TrueRouting[0]);
                    }
                    // 如果条件为假直接跳过for语句
                    else
                    {
                        // 跳过if语句
                        ret = vsm.ESP.MacroStep(ret);
                    }
                    // 返回当前要执行的指令实例
                    return(ret);

                // 除此以外,带了cond的语句,为真才执行
                default:
                    if (condBoolean == false)
                    {
                        // 跳过当前语句
                        ret = vsm.ESP.MacroStep(ret);
                    }
                    // 返回当前要执行的指令实例
                    return(ret);
                }
            }
        }
Пример #25
0
 public StackMachineTest()
 {
     _machine = new StackMachine();
 }
Пример #26
0
 public void Generate(StackMachine machine)
 {
     machine.IfGoto(this);
 }
Пример #27
0
 public void Generate(StackMachine machine)
 {
     machine.Function(this);
 }
Пример #28
0
 public void SetUp()
 {
     Machine = new StackMachine();
 }
Пример #29
0
 public void Generate(StackMachine machine)
 {
     machine.Return(this);
 }
Пример #30
0
 public void TearDown()
 {
     Machine = null;
 }
Пример #31
0
        /// <summary>
        /// 处理调用堆栈上的函数调用
        /// </summary>
        /// <param name="callFunc">函数的全局名字</param>
        /// <param name="signFunc">参数签名</param>
        /// <param name="vsm">关于哪个虚拟机做动作</param>
        public void FunctionCalling(string callFunc, string signFunc, StackMachine vsm)
        {
            if (signFunc != String.Empty && (!signFunc.StartsWith("(") || !signFunc.EndsWith(")")))
            {
                LogUtils.LogLine(String.Format("Ignored Function calling (sign not valid): {0} -> {1}", callFunc, signFunc),
                                 "Director", LogLevel.Error);
                return;
            }
            var callFuncItems = callFunc.Split('@');
            List <SceneFunction>        sceneFuncContainer;
            IEnumerable <SceneFunction> sceneFuncList;

            if (callFuncItems.Length > 1)
            {
                sceneFuncContainer = this.resMana.GetScene(callFuncItems[1]).FuncContainer;
                sceneFuncList      = from f in sceneFuncContainer where f.Callname == callFuncItems[0] select f;
            }
            else
            {
                sceneFuncContainer = this.resMana.GetScene(vsm.ESP.BindingSceneName).FuncContainer;
                sceneFuncList      = from f in sceneFuncContainer where f.Callname == callFunc select f;
                LogUtils.LogLine(String.Format("Function calling for current Scene (Scene not explicit): {0}", callFunc),
                                 "Director", LogLevel.Warning);
            }
            if (!sceneFuncList.Any())
            {
                LogUtils.LogLine(String.Format("Ignored Function calling (function not exist): {0}", callFunc),
                                 "Director", LogLevel.Error);
                return;
            }
            var sceneFunc = sceneFuncList.First();
            var signItem  = signFunc.Replace("(", String.Empty).Replace(")", String.Empty).Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries);

            if (sceneFunc.Param.Count != signItem.Length)
            {
                LogUtils.LogLine(String.Format("Ignored Function calling (in {0}, require args num: {1}, but actual:{2})", callFunc, sceneFunc.Param.Count, signItem.Length),
                                 "Director", LogLevel.Error);
                return;
            }
            // 处理参数列表
            var argsVec = new List <object>();

            foreach (var s in signItem)
            {
                string trimedPara = s.Trim();
                object varref;
                if (trimedPara.StartsWith("$") || trimedPara.StartsWith("&"))
                {
                    varref = Director.RunMana.Fetch(trimedPara, vsm);
                }
                else if (trimedPara.StartsWith("\"") && trimedPara.EndsWith("\""))
                {
                    varref = trimedPara;
                }
                else
                {
                    varref = Convert.ToDouble(trimedPara);
                }
                argsVec.Add(varref);
            }
            Director.RunMana.CallFunction(sceneFunc, argsVec, vsm);
        }
Пример #32
0
 public void Generate(StackMachine machine)
 {
 }