Пример #1
0
        }/* memory_word */

        /*
         * memory_close
         *
         * End of output redirection.
         *
         */

        internal static void MemoryClose()
        {
            if (depth >= 0)
            {
                if (redirect[depth].XSize != 0xffff)
                {
                    MemoryNewline();
                }

                if (Main.h_version == ZMachine.V6)
                {
                    Main.h_line_width = (redirect[depth].XSize != 0xffff) ?
                                        redirect[depth].Total : redirect[depth].Width;

                    FastMem.SetWord(ZMachine.H_LINE_WIDTH, Main.h_line_width);
                }

                if (depth == 0)
                {
                    Main.ostream_memory = false;
                }

                depth--;
            }
        }/* memory_close */
Пример #2
0
        /*
         * memory_open
         *
         * Begin output redirection to the memory of the Z-machine.
         *
         */

        internal static void MemoryOpen(zword table, zword xsize, bool buffering)
        {
            if (++depth < MAX_NESTING)
            {
                if (!buffering)
                {
                    xsize = 0xffff;
                }
                if (buffering && (short)xsize <= 0)
                {
                    xsize = Screen.GetMaxWidth((zword)(-(short)xsize));
                }

                FastMem.StoreW(table, 0);

                redirect[depth].Table = table;
                redirect[depth].Width = 0;
                redirect[depth].Total = 0;
                redirect[depth].XSize = xsize;

                Main.ostream_memory = true;
            }
            else
            {
                Err.RuntimeError(ErrorCodes.ERR_STR3_NESTING);
            }
        }/* memory_open */
Пример #3
0
        } /* z_copy_table */

        /*
         * z_loadb, store a value from a table of bytes.
         *
         *	zargs[0] = address of table
         *	zargs[1] = index of table entry to store
         *
         */
        internal static void ZLoadB()
        {
            zword addr = (zword)(Process.zargs[0] + Process.zargs[1]);

            FastMem.LowByte(addr, out byte value);
            Process.Store(value);
        } /* z_loadb */
Пример #4
0
        } /* z_loadb */

        /*
         * z_loadw, store a value from a table of words.
         *
         *	zargs[0] = address of table
         *	zargs[1] = index of table entry to store
         *
         */

        internal static void ZLoadW()
        {
            zword addr = (zword)(Process.zargs[0] + 2 * Process.zargs[1]);

            FastMem.LowWord(addr, out ushort value);
            Process.Store(value);
        } /* z_loadw */
Пример #5
0
        }/* z_piracy */

        /*
         * main
         *
         * Prepare and run the game.
         *
         */

        public static int MainFunc(string[] args)
        {
            if (os_.process_arguments(args))
            {
                Buffer.init_buffer();

                Err.init_err();

                FastMem.init_memory();

                Process.init_process();

                Sound.init_sound();

                Text.init_text();

                os_.init_screen();

                FastMem.init_undo();

                FastMem.z_restart();

                os_.game_started(); // New function; Called to allow the screen to know info about the game

                Process.interpret();

                FastMem.reset_memory();

                os_.reset_screen();
            }
            return(0);
        }/* main */
Пример #6
0
        /*
         * z_copy_table, copy a table or fill it with zeroes.
         *
         *	zargs[0] = address of table
         *  zargs[1] = destination address or 0 for fill
         *	zargs[2] = size of table
         *
         * Note: Copying is safe even when source and destination overlap; but
         *       if zargs[1] is negative the table _must_ be copied forwards.
         *
         */

        internal static void ZCopyTable()
        {
            zword addr;
            zword size = Process.zargs[2];
            zbyte value;
            int   i;

            if (Process.zargs[1] == 0)                                          /* zero table */
            {
                for (i = 0; i < size; i++)
                {
                    FastMem.StoreB((zword)(Process.zargs[0] + i), 0);
                }
            }
            else if ((short)size < 0 || Process.zargs[0] > Process.zargs[1])    /* copy forwards */
            {
                for (i = 0; i < (((short)size < 0) ? -(short)size : size); i++)
                {
                    addr = (zword)(Process.zargs[0] + i);
                    FastMem.LowByte(addr, out value);
                    FastMem.StoreB((zword)(Process.zargs[1] + i), value);
                }
            }
            else                                                                /* copy backwards */
            {
                for (i = size - 1; i >= 0; i--)
                {
                    addr = (zword)(Process.zargs[0] + i);
                    FastMem.LowByte(addr, out value);
                    FastMem.StoreB((zword)(Process.zargs[1] + i), value);
                }
            }
        } /* z_copy_table */
Пример #7
0
        }/* memory_open */

        /*
         * memory_new_line
         *
         * Redirect a newline to the memory of the Z-machine.
         *
         */

        internal static void memory_new_line()
        {
            zword size;
            zword addr;

            redirect[depth].total += redirect[depth].width;
            redirect[depth].width  = 0;

            addr = redirect[depth].table;

            FastMem.LOW_WORD(addr, out size);
            addr += 2;

            if (redirect[depth].xsize != 0xffff)
            {
                redirect[depth].table = (zword)(addr + size);
                size = 0;
            }
            else
            {
                FastMem.storeb((zword)(addr + (size++)), 13);
            }

            FastMem.storew(redirect[depth].table, size);
        }/* memory_new_line */
Пример #8
0
        /*
         * memory_open
         *
         * Begin output redirection to the memory of the Z-machine.
         *
         */

        internal static void memory_open(zword table, zword xsize, bool buffering)
        {
            if (++depth < MAX_NESTING)
            {
                if (!buffering)
                {
                    xsize = 0xffff;
                }
                if (buffering && (short)xsize <= 0)
                {
                    xsize = Screen.get_max_width((zword)(-(short)xsize));
                }

                FastMem.storew(table, 0);

                redirect[depth].table = table;
                redirect[depth].width = 0;
                redirect[depth].total = 0;
                redirect[depth].xsize = xsize;

                main.ostream_memory = true;
            }
            else
            {
                Err.runtime_error(ErrorCodes.ERR_STR3_NESTING);
            }
        }/* memory_open */
Пример #9
0
        }/* memory_word */

        /*
         * memory_close
         *
         * End of output redirection.
         *
         */

        internal static void memory_close()
        {
            if (depth >= 0)
            {
                if (redirect[depth].xsize != 0xffff)
                {
                    memory_new_line();
                }

                if (main.h_version == ZMachine.V6)
                {
                    main.h_line_width = (redirect[depth].xsize != 0xffff) ?
                                        redirect[depth].total : redirect[depth].width;

                    FastMem.SET_WORD(ZMachine.H_LINE_WIDTH, main.h_line_width);
                }

                if (depth == 0)
                {
                    main.ostream_memory = false;
                }

                depth--;
            }
        }/* memory_close */
Пример #10
0
        }/* hot_key_seed */

        /*
         * hot_key_undo
         *
         * ...allows user to undo the previous turn.
         *
         */

        internal static bool hot_key_undo()
        {
            Text.print_string("Undo one turn\n");

            if (FastMem.restore_undo() > 0)
            {
                if (main.h_version >= ZMachine.V5) /* for V5+ games we must */
                {
                    Process.store(2);              /* store 2 (for success) */
                    return(true);                  /* and abort the input   */
                }

                if (main.h_version <= ZMachine.V3) /* for V3- games we must */
                {
                    Screen.z_show_status();        /* draw the status line  */
                    return(false);                 /* and continue input    */
                }
            }
            else
            {
                Text.print_string("No more undo information available.\n");
            }

            return(false);
        }/* hot_key_undo */
Пример #11
0
        public static void Undo()
        {
            if (Main.cwin == 0)
            {
                if (FastMem.RestoreUndo() > 0)
                {
                    OS.ResetScreen();
                    //OS.DisplayString("One Move Undone...\n>");

                    if (Main.h_version >= ZMachine.V5)
                    {                     /* for V5+ games we must */
                        Process.Store(2); /* store 2 (for success) */
                        return;
                    }

                    if (Main.h_version <= ZMachine.V3)
                    {                         /* for V3- games we must */
                        Screen.ZShowStatus(); /* draw the status line  */
                        return;
                    }

                    OS.DisplayString("\nOne move undone...\n>");
                }
            }
        }
Пример #12
0
        }/* translate_to_zscii */

        /*
         * alphabet
         *
         * Return a character from one of the three character sets.
         *
         */

        private static zword Alphabet(int set, int index)
        {
            if (Main.h_version > ZMachine.V1 && set == 2 && index == 1)
            {
                return(0x0D);            /* always newline */
            }
            if (Main.h_alphabet != 0)
            {   /* game uses its own alphabet */
                zword addr = (zword)(Main.h_alphabet + 26 * set + index);
                FastMem.LowByte(addr, out zbyte c);
                return(TranslateFromZscii(c));
            }
            else                        /* game uses default alphabet */

            if (set == 0)
            {
                return((zword)('a' + index));
            }
            else if (set == 1)
            {
                return((zword)('A' + index));
            }
            else if (Main.h_version == ZMachine.V1)
            {
                return(_alphabet[index]);
            }
            else
            {
                return(_alphabet[index]);
            }
        }/* alphabet */
Пример #13
0
        }/* first_property */

        /*
         * next_property
         *
         * Calculate the address of the next property in a property list.
         *
         */

        static zword next_property(zword prop_addr)
        {
            zbyte value;

            /* Load the current property id */

            FastMem.LOW_BYTE(prop_addr, out value);
            prop_addr++;

            /* Calculate the length of this property */

            if (main.h_version <= ZMachine.V3)
            {
                value >>= 5;
            }
            else if (!((value & 0x80) > 0))
            {
                value >>= 6;
            }
            else
            {
                FastMem.LOW_BYTE(prop_addr, out value);
                value &= 0x3f;

                if (value == 0)
                {
                    value = 64;                 /* demanded by Spec 1.0 */
                }
            }

            /* Add property length to current property pointer */

            return((zword)(prop_addr + value + 1));
        }/* next_property */
Пример #14
0
        }/* z_get_prop_addr */

        /*
         * z_get_prop_len, store the length of an object property.
         *
         *  Process.zargs[0] = address of property to be examined
         *
         */

        internal static void z_get_prop_len()
        {
            zword addr;
            zbyte value;

            /* Back up the property pointer to the property id */

            addr = (zword)(Process.zargs[0] - 1);
            FastMem.LOW_BYTE(addr, out value);

            /* Calculate length of property */

            if (main.h_version <= ZMachine.V3)
            {
                value = (zbyte)((value >> 5) + 1);
            }
            else if (!((value & 0x80) > 0))
            {
                value = (zbyte)((value >> 6) + 1);
            }
            else
            {
                value &= 0x3f;

                if (value == 0)
                {
                    value = 64;                 /* demanded by Spec 1.0 */
                }
            }

            /* Store length of property */

            Process.store(value);
        }/* z_get_prop_len */
Пример #15
0
        }/* z_get_sibling */

        /*
         * z_insert_obj, make an object the first child of another object.
         *
         *	Process.zargs[0] = object to be moved
         *	Process.zargs[1] = destination object
         *
         */

        internal static void ZInsertObj()
        {
            zword obj1 = Process.zargs[0];
            zword obj2 = Process.zargs[1];
            zword obj1_addr;
            zword obj2_addr;

            /* If we are monitoring object movements display a short note */

            if (Main.option_object_movement == true)
            {
                Stream.StreamMssgOn();
                Text.PrintString("@move_obj ");
                Text.PrintObject(obj1);
                Text.PrintString(" ");
                Text.PrintObject(obj2);
                Stream.StreamMssgOff();
            }

            if (obj1 == 0)
            {
                Err.RuntimeError(ErrorCodes.ERR_MOVE_OBJECT_0);
                return;
            }

            if (obj2 == 0)
            {
                Err.RuntimeError(ErrorCodes.ERR_MOVE_OBJECT_TO_0);
                return;
            }

            /* Get addresses of both objects */
            obj1_addr = ObjectAddress(obj1);
            obj2_addr = ObjectAddress(obj2);

            /* Remove object 1 from current parent */
            UnlinkObject(obj1);

            /* Make object 1 first child of object 2 */
            if (Main.h_version <= ZMachine.V3)
            {
                obj1_addr += O1_PARENT;
                FastMem.SetByte(obj1_addr, (zbyte)obj2);
                obj2_addr += O1_CHILD;
                FastMem.LowByte(obj2_addr, out byte child);
                FastMem.SetByte(obj2_addr, (zbyte)obj1);
                obj1_addr += (zword)(O1_SIBLING - O1_PARENT);
                FastMem.SetByte(obj1_addr, child);
            }
            else
            {
                obj1_addr += O4_PARENT;
                FastMem.SetWord(obj1_addr, obj2);
                obj2_addr += O4_CHILD;
                FastMem.LowWord(obj2_addr, out ushort child);
                FastMem.SetWord(obj2_addr, obj1);
                obj1_addr += (zword)(O4_SIBLING - O4_PARENT);
                FastMem.SetWord(obj1_addr, child);
            }
        }/* z_insert_obj */
Пример #16
0
        }/* z_piracy */

        /*
         * main
         *
         * Prepare and run the game.
         *
         */

        public static int MainFunc(ReadOnlySpan <string> args)
        {
            if (OS.ProcessArguments(args))
            {
                Buffer.InitBuffer();

                Err.InitErr();

                FastMem.InitMemory();

                Process.InitProcess();

                Sound.InitSound();

                Text.InitText();

                OS.InitScreen();

                FastMem.InitUndo();

                FastMem.ZRestart();

                OS.GameStarted(); // New function; Called to allow the screen to know info about the game

                Process.Interpret();

                FastMem.ResetMemory();

                //OS.ResetScreen();
            }
            return(0);
        }/* main */
Пример #17
0
        }/* load_all_operands */

        /*
         * interpret
         *
         * Z-code interpreter main loop
         *
         */

        internal static void interpret()
        {
            do
            {
                zbyte opcode;

                FastMem.CODE_BYTE(out opcode);

                DebugState.Output("CODE: {0} -> {1:X}", FastMem.pcp - 1, opcode);

                if (main.abort_game_loop == true)
                {
                    main.abort_game_loop = false;
                    return;
                }

                zargc = 0;
                if (opcode < 0x80)
                {                       /* 2OP opcodes */
                    load_operand((zbyte)((opcode & 0x40) > 0 ? 2 : 1));
                    load_operand((zbyte)((opcode & 0x20) > 0 ? 2 : 1));

                    private_invoke(var_opcodes[opcode & 0x1f], "2OP", (opcode & 0x1f), opcode);
                }
                else if (opcode < 0xb0)
                {               /* 1OP opcodes */
                    load_operand((zbyte)(opcode >> 4));

                    private_invoke(op1_opcodes[opcode & 0x0f], "1OP", (opcode & 0x0f), opcode);
                }
                else if (opcode < 0xc0)
                {               /* 0OP opcodes */
                    private_invoke(op0_opcodes[opcode - 0xb0], "0OP", (opcode - 0xb0), opcode);
                }
                else
                {                               /* VAR opcodes */
                    zbyte specifier1;
                    zbyte specifier2;

                    if (opcode == 0xec || opcode == 0xfa)
                    {                                      /* opcodes 0xec */
                        FastMem.CODE_BYTE(out specifier1); /* and 0xfa are */
                        FastMem.CODE_BYTE(out specifier2); /* call opcodes */
                        load_all_operands(specifier1);     /* with up to 8 */
                        load_all_operands(specifier2);     /* arguments    */
                    }
                    else
                    {
                        FastMem.CODE_BYTE(out specifier1);
                        load_all_operands(specifier1);
                    }

                    private_invoke(var_opcodes[opcode - 0xc0], "VAR", (opcode - 0xc0), opcode);
                }

                os_.tick();
            } while (finished == 0);

            finished--;
        }/* interpret */
Пример #18
0
        }/* z_print_char */

        /*
         * z_print_form, print a formatted table.
         *
         *	zargs[0] = address of formatted table to be printed
         *
         */

        internal static void z_print_form()
        {
            zword count;
            zword addr = Process.zargs[0];

            bool first = true;

            for (;;)
            {
                FastMem.LOW_WORD(addr, out count);
                addr += 2;

                if (count == 0)
                {
                    break;
                }

                if (!first)
                {
                    Buffer.new_line();
                }

                while (count-- > 0)
                {
                    zbyte c;

                    FastMem.LOW_BYTE(addr, out c);
                    addr++;

                    Buffer.print_char(translate_from_zscii(c));
                }

                first = false;
            }
        }/* z_print_form */
Пример #19
0
        }/* translate_to_zscii */

        /*
         * alphabet
         *
         * Return a character from one of the three character sets.
         *
         */

        static zword alphabet(int set, int index)
        {
            if (main.h_version > ZMachine.V1 && set == 2 && index == 1)
            {
                return(0x0D);           /* always newline */
            }
            if (main.h_alphabet != 0)   /* game uses its own alphabet */

            {
                zbyte c;

                zword addr = (zword)(main.h_alphabet + 26 * set + index);
                FastMem.LOW_BYTE(addr, out c);

                return(translate_from_zscii(c));
            }
            else                        /* game uses default alphabet */

            if (set == 0)
            {
                return((zword)('a' + index));
            }
            else if (set == 1)
            {
                return((zword)('A' + index));
            }
            else if (main.h_version == ZMachine.V1)
            {
                return(" 0123456789.,!?_#'\"/\\<-:()"[index]);
            }
            else
            {
                return(" ^0123456789.,!?_#'\"/\\-:()"[index]);
            }
        }/* alphabet */
Пример #20
0
        }/* find_resolution */

        /*
         * load_string
         *
         * Copy a ZSCII string from the memory to the global "decoded" string.
         *
         */

        internal static void load_string(zword addr, zword length)
        {
            int i = 0;

            if (resolution == 0)
            {
                find_resolution();
            }

            while (i < 3 * resolution)
            {
                if (i < length)
                {
                    zbyte c;

                    FastMem.LOW_BYTE(addr, out c);
                    addr++;

                    decoded[i++] = Text.translate_from_zscii(c);
                }
                else
                {
                    decoded[i++] = 0;
                }
            }
        }/* load_string */
Пример #21
0
        }/* lookup_text */

        /*
         * tokenise_text
         *
         * Translate a single word to a token and append it to the token
         * buffer. Every token consists of the address of the dictionary
         * entry, the length of the word and the offset of the word from
         * the start of the text buffer. Unknown words cause empty slots
         * if the flag is set (such that the text can be scanned several
         * times with different dictionaries); otherwise they are zero.
         *
         */

        static void tokenise_text(zword text, zword length, zword from, zword parse, zword dct, bool flag)
        {
            zword addr;
            zbyte token_max, token_count;

            FastMem.LOW_BYTE(parse, out token_max);
            parse++;
            FastMem.LOW_BYTE(parse, out token_count);

            if (token_count < token_max)        /* sufficient space left for token? */

            {
                FastMem.storeb(parse++, (zbyte)(token_count + 1));

                load_string((zword)(text + from), length);

                addr = lookup_text(0x05, dct);

                if (addr != 0 || !flag)
                {
                    parse += (zword)(4 * token_count); // Will parse get updated properly?

                    FastMem.storew((zword)(parse + 0), addr);
                    FastMem.storeb((zword)(parse + 2), (zbyte)length);
                    FastMem.storeb((zword)(parse + 3), (zbyte)from);
                }
            }
        }/* tokenise_text */
Пример #22
0
        }/* find_resolution */

        /*
         * load_string
         *
         * Copy a ZSCII string from the memory to the global "decoded" string.
         *
         */

        internal static void LoadString(zword addr, zword length)
        {
            if (Decoded is null)
            {
                ThrowHelper.ThrowInvalidOperationException("Decoded not initialized");
            }

            int i = 0;

            if (Resolution == 0)
            {
                FindResolution();
            }

            while (i < 3 * Resolution)
            {
                if (i < length)
                {
                    FastMem.LowByte(addr, out zbyte c);
                    addr++;

                    Decoded[i++] = Text.TranslateFromZscii(c);
                }
                else
                {
                    Decoded[i++] = 0;
                }
            }
        }/* load_string */
Пример #23
0
        }/* hot_key_seed */

        /*
         * hot_key_undo
         *
         * ...allows user to undo the previous turn.
         *
         */

        public static bool HotkeyUndo()
        {
            Text.PrintString("Undo one turn\n");

            if (FastMem.RestoreUndo() > 0)
            {
                if (Main.h_version >= ZMachine.V5)
                {                     /* for V5+ games we must */
                    Process.Store(2); /* store 2 (for success) */
                    return(true);     /* and abort the input   */
                }

                if (Main.h_version <= ZMachine.V3)
                {                         /* for V3- games we must */
                    Screen.ZShowStatus(); /* draw the status line  */
                    return(false);        /* and continue input    */
                }
            }
            else
            {
                Text.PrintString("No more undo information available.\n");
            }

            return(false);
        }/* hot_key_undo */
Пример #24
0
        internal static void ScriptOpen()
        {
            unchecked { Main.h_flags &= (zword) ~ZMachine.SCRIPTING_FLAG; }

            if (Main.h_version >= ZMachine.V5 || !ScriptValid)
            {
                if (!OS.ReadFileName(out string?new_name, General.DEFAULT_SCRIPT_NAME, FileTypes.FILE_SCRIPT))
                {
                    goto done;
                }

                ScriptName = new_name;
            }

            if ((Sfp = new System.IO.StreamWriter(ScriptName, true)) != null)
            {
                Main.h_flags |= ZMachine.SCRIPTING_FLAG;

                ScriptValid         = true;
                Main.ostream_script = true;

                ScriptWidth = 0;

                Sfp.AutoFlush = true;
            }
            else
            {
                Text.PrintString("Cannot open file\n");
            }

done:

            FastMem.SetWord(ZMachine.H_FLAGS, Main.h_flags);
        }/* script_open */
Пример #25
0
        }/* z_print_num */

        /*
         * print_object
         *
         * Print an object description.
         *
         */

        internal static void print_object(zword object_var)
        {
            zword addr = CObject.object_name(object_var);
            zword code = 0x94a5;
            zbyte length;

            FastMem.LOW_BYTE(addr, out length);
            addr++;

            if (length != 0)
            {
                FastMem.LOW_WORD(addr, out code);
            }

            if (code == 0x94a5)         /* encoded text 0x94a5 == empty string */

            {
                print_string("object#");        /* supply a generic name */
                print_num(object_var);          /* for anonymous objects */
            }
            else
            {
                decode_text(string_type.LOW_STRING, addr);
            }
        }/* print_object */
Пример #26
0
        }/* script_open */

        /*
         * script_close
         *
         * Stop transscription.
         *
         */

        internal static void script_close()
        {
            main.h_flags &= (ushort)~ZMachine.SCRIPTING_FLAG;
            FastMem.SET_WORD(ZMachine.H_FLAGS, main.h_flags);

            sfp.Close();
            main.ostream_script = false;
        }/* script_close */
Пример #27
0
        }/* script_open */

        /*
         * script_close
         *
         * Stop transscription.
         *
         */

        internal static void ScriptClose()
        {
            unchecked { Main.h_flags &= (ushort)~ZMachine.SCRIPTING_FLAG; }
            FastMem.SetWord(ZMachine.H_FLAGS, Main.h_flags);

            Sfp?.Close();
            Main.ostream_script = false;
        }/* script_close */
Пример #28
0
        internal static void z_make_menu()
        {
            /* This opcode was only used for the Macintosh version of Journey.
             * It controls menus with numbers greater than 2 (menus 0, 1 and 2
             * are system menus). */

            if (Process.zargs[0] < 3)
            {
                Process.branch(false);
                return;
            }

            if (Process.zargs[1] != 0)
            {
                zword items;
                int   i;

                FastMem.LOW_WORD(Process.zargs[1], out items);

                for (i = 0; i < items; i++)
                {
                    zword item;
                    zbyte length;
                    zbyte c;
                    int   j;

                    FastMem.LOW_WORD(Process.zargs[1] + 2 + (2 * i), out item);
                    FastMem.LOW_BYTE(item, out length);

                    if (length > 31)
                    {
                        length = 31;
                    }
                    menu[length] = 0;

                    for (j = 0; j < length; j++)
                    {
                        FastMem.LOW_BYTE(item + j + 1, out c);
                        menu[j] = Text.translate_from_zscii(c);
                    }

                    if (i == 0)
                    {
                        os_.menu(ZMachine.MENU_NEW, Process.zargs[0], menu);
                    }
                    else
                    {
                        os_.menu(ZMachine.MENU_ADD, Process.zargs[0], menu);
                    }
                }
            }
            else
            {
                os_.menu(ZMachine.MENU_REMOVE, Process.zargs[0], new zword[0]);
            }

            Process.branch(true);
        }/* z_make_menu */
Пример #29
0
        }/* z_get_parent */

        /*
         * z_get_prop, store the value of an object property.
         *
         *	Process.zargs[0] = object
         *	Process.zargs[1] = number of property to be examined
         *
         */

        internal static void ZGetProp()
        {
            zword prop_addr;
            zword wprop_val;
            zbyte value;
            zbyte mask;

            if (Process.zargs[0] == 0)
            {
                Err.RuntimeError(ErrorCodes.ERR_GET_PROP_0);
                Process.Store(0);
                return;
            }

            /* Property id is in bottom five (six) bits */
            mask = (zbyte)((Main.h_version <= ZMachine.V3) ? 0x1f : 0x3f);

            /* Load address of first property */
            prop_addr = FirstProperty(Process.zargs[0]);

            /* Scan down the property list */
            for (; ;)
            {
                FastMem.LowByte(prop_addr, out value);
                if ((value & mask) <= Process.zargs[1])
                {
                    break;
                }
                prop_addr = NextProperty(prop_addr);
            }

            if ((value & mask) == Process.zargs[1])
            {   /* property found */
                /* Load property (byte or word sized) */
                prop_addr++;

                if ((Main.h_version <= ZMachine.V3 && !((value & 0xe0) > 0)) || (Main.h_version >= ZMachine.V4 && !((value & 0xc0) > 0)))
                {
                    FastMem.LowByte(prop_addr, out zbyte bprop_val);
                    wprop_val = bprop_val;
                }
                else
                {
                    FastMem.LowWord(prop_addr, out wprop_val);
                }
            }
            else
            {   /* property not found */
                /* Load default value */

                prop_addr = (zword)(Main.h_objects + 2 * (Process.zargs[1] - 1));
                FastMem.LowWord(prop_addr, out wprop_val);
            }

            /* Store the property value */
            Process.Store(wprop_val);
        }/* z_get_prop */
Пример #30
0
        /*
         * translate_from_zscii
         *
         * Map a ZSCII character into Unicode.
         *
         */

        internal static zword translate_from_zscii(zbyte c)
        {
            if (c == 0xfc)
            {
                return(CharCodes.ZC_MENU_CLICK);
            }
            if (c == 0xfd)
            {
                return(CharCodes.ZC_DOUBLE_CLICK);
            }
            if (c == 0xfe)
            {
                return(CharCodes.ZC_SINGLE_CLICK);
            }

            if (c >= 0x9b && main.story_id != Story.BEYOND_ZORK)
            {
                if (main.hx_unicode_table != 0)         /* game has its own Unicode table */

                {
                    zbyte N;

                    FastMem.LOW_BYTE(main.hx_unicode_table, out N);

                    if (c - 0x9b < N)
                    {
                        zword addr = (zword)(main.hx_unicode_table + 1 + 2 * (c - 0x9b));
                        zword unicode;

                        FastMem.LOW_WORD(addr, out unicode);

                        if (unicode < 0x20)
                        {
                            return('?');
                        }

                        return(unicode);
                    }
                    else
                    {
                        return('?');
                    }
                }
                else                            /* game uses standard set */

                if (c <= 0xdf)
                {
                    return(zscii_to_latin1[c - 0x9b]);
                }
                else
                {
                    return('?');
                }
            }

            return((zword)c);
        }/* translate_from_zscii */