コード例 #1
0
ファイル: EngineWrapper.cs プロジェクト: ChicagoDave/FyreXaml
        /// <summary>
        /// Assume we're running a command and have save game data.
        /// </summary>
        /// <param name="gameFile"></param>
        /// <param name="saveFile"></param>
        /// <param name="command"></param>
        public EngineWrapper(byte[] gameFile, byte[] saveFile, string command)
        {
            if (gameFile == null)
                throw new Exception("Missing game data.");

            if (saveFile == null)
                throw new Exception("Missing required save file.");

            if (command == "")
                throw new Exception("Missing command.");

            MemoryStream gameData = new MemoryStream(gameFile);
            saveFileData = new MemoryStream(saveFile);

            vm = new Engine(gameData, saveFileData);

            wrapperState = VMWrapperState.LoadGame;
            if (command == "restore.current.game")
            {
                requestType = VMRequestType.NoCommand;
            }
            else
            {
                requestType = VMRequestType.ExecuteCommand;
            }

            // save the user's command for later
            saveCommand = command;

            Run();
        }
コード例 #2
0
ファイル: FyreVMService.cs プロジェクト: ChicagoDave/FyreXaml
        public async Task LoadGame(Page page) {

            this.page = page;

            StorageFile gameFile = await Package.Current.InstalledLocation.GetFileAsync(@"Game\shadow-w8.ulx");
            byte[] gameFileData = await ReadFromFile(gameFile);
            Stream gameStream = new MemoryStream(gameFileData);

            vm = new Engine(gameStream);

            Run();
        }
コード例 #3
0
ファイル: EngineWrapper.cs プロジェクト: ChicagoDave/Zifmia
        /// <summary>
        /// Load the game and return data.
        /// </summary>
        /// <param name="gameFile"></param>
        public EngineWrapper(byte[] gameFile)
        {
            if (gameFile == null)
                throw new Exception("Missing game file.");

            MemoryStream gameData = new MemoryStream(gameFile);

            vm = new Engine(gameData);

            requestType = VMRequestType.StartGame;
            wrapperState = VMWrapperState.LoadGame;

            Run();
        }
コード例 #4
0
ファイル: Veneer.cs プロジェクト: ChicagoDave/FyreXaml
            /// <summary>
            /// Intercepts a routine call if its address has previously been registered.
            /// </summary>
            /// <param name="e">The <see cref="Engine"/> attempting to call the routine.</param>
            /// <param name="address">The address of the routine.</param>
            /// <param name="args">The routine's arguments.</param>
            /// <param name="result">The routine's return value.</param>
            /// <returns><see langword="true"/> if the call was intercepted.</returns>
            /// <exception cref="IndexOutOfRangeException">
            /// <paramref name="address"/> matches a registered veneer routine, but
            /// <paramref name="args"/> is too short for that routine.
            /// </exception>
            public bool InterceptCall(Engine e, uint address, uint[] args, out uint result)
            {
                if (address != 0)
                {
                    if (address == zregion_fn)
                    {
                        result = Z__Region(e, args[0]);
                        return true;
                    }

                    if (address == cp_tab_fn)
                    {
                        result = CP__Tab(e, args[0], args[1]);
                        return true;
                    }

                    if (address == oc_cl_fn)
                    {
                        result = OC__Cl(e, args[0], args[1]);
                        return true;
                    }

                    if (address == ra_pr_fn)
                    {
                        result = RA__Pr(e, args[0], args[1]);
                        return true;
                    }

                    if (address == rt_chldw_fn)
                    {
                        result = RT__ChLDW(e, args[0], args[1]);
                        return true;
                    }

                    if (address == unsigned_compare_fn)
                    {
                        result = (uint)args[0].CompareTo(args[1]);
                        return true;
                    }

                    if (address == rl_pr_fn)
                    {
                        result = RL__Pr(e, args[0], args[1]);
                        return true;
                    }

                    if (address == rv_pr_fn)
                    {
                        result = RV__Pr(e, args[0], args[1]);
                        return true;
                    }

                    if (address == op_pr_fn)
                    {
                        result = OP__Pr(e, args[0], args[1]);
                        return true;
                    }

                    if (address == rt_chstw_fn)
                    {
                        result = RT__ChSTW(e, args[0], args[1], args[2]);
                        return true;
                    }

                    if (address == rt_chldb_fn)
                    {
                        result = RT__ChLDB(e, args[0], args[1]);
                        return true;
                    }

                    if (address == meta_class_fn)
                    {
                        result = Meta__class(e, args[0]);
                        return true;
                    }
                }

                result = 0;
                return false;
            }
コード例 #5
0
ファイル: Output.cs プロジェクト: ChicagoDave/Zifmia
 protected void EmitChar(Engine e, uint ch)
 {
     if (e.outputSystem == IOSystem.Filter)
     {
         e.PerformCall(e.filterAddress, new uint[] { ch },
             GLULX_STUB_RESUME_HUFFSTR, e.printingDigit, e.pc);
     }
     else
     {
         e.SendCharToOutput(ch);
     }
 }
コード例 #6
0
ファイル: Output.cs プロジェクト: ChicagoDave/Zifmia
 /// <summary>
 /// Returns the non-branch node that will handle the next string action.
 /// </summary>
 /// <param name="e">The <see cref="Engine"/> that is printing.</param>
 /// <returns>A non-branch string node.</returns>
 /// <remarks>When called on a branch node, this will consume one or
 /// more compressed string bits.</remarks>
 public virtual StrNode GetHandlingNode(Engine e)
 {
     return this;
 }
コード例 #7
0
ファイル: Output.cs プロジェクト: ChicagoDave/Zifmia
 public override void HandleNextChar(Engine e)
 {
     e.PrintIndirect(
         dblIndirect ? e.image.ReadInt32(address) : address,
         argCount, argsAt);
 }
コード例 #8
0
ファイル: Output.cs プロジェクト: ChicagoDave/Zifmia
 public override void HandleNextChar(Engine e)
 {
     if (e.NextCompressedStringBit() == true)
         right.HandleNextChar(e);
     else
         left.HandleNextChar(e);
 }
コード例 #9
0
ファイル: Veneer.cs プロジェクト: ChicagoDave/FyreXaml
 // finds the location of an object ("parent()" function)
 private uint Parent(Engine e, uint obj)
 {
     return e.image.ReadInt32(obj + 1 + num_attr_bytes + 12);
 }
コード例 #10
0
ファイル: Veneer.cs プロジェクト: ChicagoDave/FyreXaml
            // determines whether an object provides a given property ("provides" operator)
            private uint OP__Pr(Engine e, uint obj, uint id)
            {
                switch (Z__Region(e, obj))
                {
                    case 3:
                        if (id == indiv_prop_start + PRINT_PROP ||
                            id == indiv_prop_start + PRINT_TO_ARRAY_PROP)
                            return 1;
                        else
                            return 0;

                    case 2:
                        if (id == indiv_prop_start + CALL_PROP)
                            return 1;
                        else
                            return 0;

                    case 1:
                        if (id >= indiv_prop_start && id < indiv_prop_start + 8)
                            if (Parent(e, obj) == class_mc)
                                return 1;

                        if (RA__Pr(e, obj, id) != 0)
                            return 1;
                        else
                            return 0;

                    default:
                        return 0;
                }
            }
コード例 #11
0
ファイル: Veneer.cs プロジェクト: ChicagoDave/FyreXaml
            // determines whether an object is a member of a given class ("ofclass" operator)
            private uint OC__Cl(Engine e, uint obj, uint cla)
            {
                switch (Z__Region(e, obj))
                {
                    case 3:
                        return (uint)(cla == string_mc ? 1 : 0);

                    case 2:
                        return (uint)(cla == routine_mc ? 1 : 0);

                    case 1:
                        if (cla == class_mc)
                        {
                            if (Parent(e, obj) == class_mc)
                                return 1;
                            if (obj == class_mc || obj == string_mc ||
                                obj == routine_mc || obj == object_mc)
                                return 1;
                            return 0;
                        }

                        if (cla == object_mc)
                        {
                            if (Parent(e, obj) == class_mc)
                                return 0;
                            if (obj == class_mc || obj == string_mc ||
                                obj == routine_mc || obj == object_mc)
                                return 0;
                            return 1;
                        }

                        if (cla == string_mc || cla == routine_mc)
                            return 0;

                        if (Parent(e, cla) != class_mc)
                        {
                            e.NestedCall(rt_err_fn, ofclass_err, cla, 0xFFFFFFFF);
                            return 0;
                        }

                        uint inlist = RA__Pr(e, obj, 2);
                        if (inlist == 0)
                            return 0;

                        uint inlistlen = RL__Pr(e, obj, 2) / 4;
                        for (uint jx = 0; jx < inlistlen; jx++)
                            if (e.image.ReadInt32(inlist + jx * 4) == cla)
                                return 1;

                        return 0;

                    default:
                        return 0;
                }
            }
コード例 #12
0
ファイル: Veneer.cs プロジェクト: ChicagoDave/FyreXaml
 // determines the metaclass of a routine, string, or object ("metaclass()" function)
 private uint Meta__class(Engine e, uint obj)
 {
     switch (Z__Region(e, obj))
     {
         case 2:
             return routine_mc;
         case 3:
             return string_mc;
         case 1:
             if (Parent(e, obj) == class_mc)
                 return class_mc;
             if (obj == class_mc || obj == string_mc ||
                 obj == routine_mc || obj == object_mc)
                 return class_mc;
             return object_mc;
         default:
             return 0;
     }
 }
コード例 #13
0
ファイル: Veneer.cs プロジェクト: ChicagoDave/FyreXaml
            // finds an object's common property table
            private uint CP__Tab(Engine e, uint obj, uint id)
            {
                if (Z__Region(e, obj) != 1)
                {
                    e.NestedCall(rt_err_fn, 23, obj);
                    return 0;
                }

                uint otab = e.image.ReadInt32(obj + 16);
                if (otab == 0)
                    return 0;
                uint max = e.image.ReadInt32(otab);
                otab += 4;
                return e.PerformBinarySearch(id, 2, otab, 10, max, 0, SearchOptions.None);
            }
コード例 #14
0
ファイル: Veneer.cs プロジェクト: ChicagoDave/FyreXaml
            /// <summary>
            /// Registers a routine address or constant value, using the acceleration
            /// codes defined in the Glulx specification.
            /// </summary>
            /// <param name="e">The <see cref="Engine"/> for which the value is being set.</param>
            /// <param name="isParam"><see langword="true"/> to set a constant value;
            /// <b>false</b> to set a routine address.</param>
            /// <param name="slot">The routine or constant index to set.</param>
            /// <param name="value">The address of the routine or value of the constant.</param>
            /// <returns><see langword="true"/> if registration was successful.</returns>
            public bool SetSlotGlulx(Engine e, bool isParam, uint slot, uint value)
            {
                if (isParam && slot == 6)
                {
                    if (value != e.image.RamStart + SELF_OFFSET)
                        throw new ArgumentException("Unexpected value for acceleration parameter 6");
                    return true;
                }

                Dictionary<uint, VeneerSlot> dict = isParam ? paramSlotMap : funcSlotMap;
                VeneerSlot fyreSlot;
                if (dict.TryGetValue(slot, out fyreSlot))
                    return SetSlotFyre((uint)fyreSlot, value);
                else
                    return false;
            }
コード例 #15
0
ファイル: GlkWrapper.cs プロジェクト: ChicagoDave/FyreXaml
            public GlkMemoryUniStream(uint id, Engine engine, uint address, uint size)
                : base(id)
            {
                this.engine = engine;
                this.address = address;

                if (address != 0 && size != 0)
                    buffer = new uint[size];

                position = written = read = 0;
            }
コード例 #16
0
ファイル: GlkWrapper.cs プロジェクト: ChicagoDave/FyreXaml
 public GlkWindowStream(uint id, Engine engine)
     : base(id)
 {
     this.engine = engine;
 }
コード例 #17
0
ファイル: Veneer.cs プロジェクト: ChicagoDave/FyreXaml
            // finds the length of an object's property (".#" operator)
            private uint RL__Pr(Engine e, uint obj, uint id)
            {
                uint cla = 0;
                if ((id & 0xFFFF0000) != 0)
                {
                    cla = e.image.ReadInt32(classes_table + 4 * (id & 0xFFFF));
                    if (OC__Cl(e, obj, cla) == 0)
                        return 0;

                    id >>= 16;
                    obj = cla;
                }

                uint prop = CP__Tab(e, obj, id);
                if (prop == 0)
                    return 0;

                if (Parent(e, obj) == class_mc && cla == 0)
                    if (id < indiv_prop_start || id >= indiv_prop_start + 8)
                        return 0;

                if (e.image.ReadInt32(e.image.RamStart + SELF_OFFSET) != obj)
                {
                    int ix = (e.image.ReadByte(prop + 9) & 1);
                    if (ix != 0)
                        return 0;
                }

                return (uint)(4 * e.image.ReadInt16(prop + 2));
            }
コード例 #18
0
ファイル: Output.cs プロジェクト: ChicagoDave/Zifmia
 public override StrNode GetHandlingNode(Engine e)
 {
     if (e.NextCompressedStringBit() == true)
         return right.GetHandlingNode(e);
     else
         return left.GetHandlingNode(e);
 }
コード例 #19
0
ファイル: Veneer.cs プロジェクト: ChicagoDave/FyreXaml
            // performs bounds checking when reading from a byte array ("->" operator)
            private uint RT__ChLDB(Engine e, uint array, uint offset)
            {
                uint address = array + offset;
                if (address >= e.image.EndMem)
                    return e.NestedCall(rt_err_fn, 24);

                return e.image.ReadByte(address);
            }
コード例 #20
0
ファイル: Output.cs プロジェクト: ChicagoDave/Zifmia
 public override void HandleNextChar(Engine e)
 {
     e.DonePrinting();
 }
コード例 #21
0
ファイル: Veneer.cs プロジェクト: ChicagoDave/FyreXaml
 // performs bounds checking when reading from a word array ("-->" operator)
 private uint RT__ChLDW(Engine e, uint array, uint offset)
 {
     uint address = array + 4 * offset;
     if (address >= e.image.EndMem)
     {
         return e.NestedCall(rt_err_fn, 25);
     }
     return e.image.ReadInt32(address);
 }
コード例 #22
0
ファイル: Output.cs プロジェクト: ChicagoDave/Zifmia
 public override void HandleNextChar(Engine e)
 {
     if (e.outputSystem == IOSystem.Filter)
     {
         e.PushCallStub(
             new CallStub(GLULX_STUB_RESUME_HUFFSTR, e.printingDigit, e.pc, e.fp));
         e.pc = address;
         e.execMode = mode;
     }
     else
     {
         e.SendStringToOutput(str);
     }
 }
コード例 #23
0
ファイル: Veneer.cs プロジェクト: ChicagoDave/FyreXaml
 // performs bounds checking when writing to a word array ("-->" operator)
 private uint RT__ChSTW(Engine e, uint array, uint offset, uint val)
 {
     uint address = array + 4 * offset;
     if (address >= e.image.EndMem || address < e.image.RamStart)
     {
         return e.NestedCall(rt_err_fn, 27);
     }
     else
     {
         e.image.WriteInt32(address, val);
         return 0;
     }
 }
コード例 #24
0
ファイル: Output.cs プロジェクト: ChicagoDave/Zifmia
 /// <summary>
 /// Performs the action associated with this string node: printing
 /// a character or string, terminating output, or reading a bit and
 /// delegating to another node.
 /// </summary>
 /// <param name="e">The <see cref="Engine"/> that is printing.</param>
 /// <remarks>When called on a branch node, this will consume one or
 /// more compressed string bits.</remarks>
 public abstract void HandleNextChar(Engine e);
コード例 #25
0
ファイル: Veneer.cs プロジェクト: ChicagoDave/FyreXaml
            // reads the value of an object's property ("." operator)
            private uint RV__Pr(Engine e, uint obj, uint id)
            {
                uint addr = RA__Pr(e, obj, id);
                if (addr == 0)
                {
                    if (id > 0 && id < indiv_prop_start)
                        return e.image.ReadInt32(cpv_start + 4 * id);

                    e.NestedCall(rt_err_fn, readprop_err, obj, id);
                    return 0;
                }

                return e.image.ReadInt32(addr);
            }
コード例 #26
0
ファイル: Output.cs プロジェクト: ChicagoDave/Zifmia
 public override void HandleNextChar(Engine e)
 {
     EmitChar(e, ch);
 }
コード例 #27
0
ファイル: Veneer.cs プロジェクト: ChicagoDave/FyreXaml
            // distinguishes between strings, routines, and objects
            private uint Z__Region(Engine e, uint address)
            {
                if (address < 36 || address >= e.image.EndMem)
                    return 0;

                byte type = e.image.ReadByte(address);
                if (type >= 0xE0)
                    return 3;
                if (type >= 0xC0)
                    return 2;
                if (type >= 0x70 && type <= 0x7F && address >= e.image.RamStart)
                    return 1;

                return 0;
            }