}/* 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 */
}/* 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 */
/* * 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 */
}/* z_check_unicode */ /* * z_encode_text, encode a ZSCII string for use in a dictionary. * * zargs[0] = address of text buffer * zargs[1] = length of ASCII string * zargs[2] = offset of ASCII string within the text buffer * zargs[3] = address to store encoded text in * * This is a V5+ opcode and therefore the dictionary resolution must be * three 16bit words. * */ internal static void z_encode_text() { int i; load_string((zword)(Process.zargs[0] + Process.zargs[2]), Process.zargs[1]); encode_text(0x05); for (i = 0; i < resolution; i++) { FastMem.storew((zword)(Process.zargs[3] + 2 * i), encoded[i]); } }/* z_encode_text */
}/* z_pop_stack */ /* * z_pull, pop a value off... * * a) ...the game or a user stack and store it (V6) * * zargs[0] = address of user stack (optional) * * b) ...the game stack and write it to a variable (other than V6) * * zargs[0] = variable to write value to * */ internal static void z_pull() { zword value; if (main.h_version != ZMachine.V6) /* not a V6 game, pop stack and write */ { value = main.stack[main.sp++]; if (Process.zargs[0] == 0) { main.stack[main.sp] = value; } else if (Process.zargs[0] < 16) { // *(fp - Process.zargs[0]) = value; main.stack[main.fp - Process.zargs[0]] = value; } else { zword addr = (zword)(main.h_globals + 2 * (Process.zargs[0] - 16)); FastMem.SET_WORD(addr, value); } } else /* it's V6, but is there a user stack? */ { if (Process.zargc == 1) /* it's a user stack */ { zword size; zword addr = Process.zargs[0]; FastMem.LOW_WORD(addr, out size); size++; FastMem.storew(addr, size); addr += (zword)(2 * size); FastMem.LOW_WORD(addr, out value); } else { value = main.stack[main.sp++]; // value = *sp++; /* it's the game stack */ } Process.store(value); } }/* z_pull */
}/* z_read_char */ /* * z_read_mouse, write the current mouse status into a table. * * zargs[0] = address of table * */ internal static void z_read_mouse() { zword btn; /* Read the mouse position, the last menu click * and which buttons are down */ btn = os_.read_mouse(); main.hx_mouse_y = main.mouse_y; main.hx_mouse_x = main.mouse_x; FastMem.storew((zword)(Process.zargs[0] + 0), main.hx_mouse_y); FastMem.storew((zword)(Process.zargs[0] + 2), main.hx_mouse_x); FastMem.storew((zword)(Process.zargs[0] + 4), btn); /* mouse button bits */ FastMem.storew((zword)(Process.zargs[0] + 6), main.menu_selected); /* menu selection */ }/* z_read_mouse */
}/* z_push */ /* * z_push_stack, push a value onto a user stack then branch if successful. * * zargs[0] = value to push onto the stack * zargs[1] = address of user stack * */ internal static void z_push_stack() { zword size; zword addr = Process.zargs[1]; FastMem.LOW_WORD(addr, out size); if (size != 0) { FastMem.storew((zword)(addr + 2 * size), Process.zargs[0]); size--; FastMem.storew(addr, size); } Process.branch(size > 0); // TODO I think that's what's expected here }/* z_push_stack */
}/* z_pop */ /* * z_pop_stack, pop n values off the game or user stack and discard them. * * zargs[0] = number of values to discard * zargs[1] = address of user stack (optional) * */ internal static void z_pop_stack() { if (Process.zargc == 2) /* it's a user stack */ { zword size; zword addr = Process.zargs[1]; FastMem.LOW_WORD(addr, out size); size += Process.zargs[0]; FastMem.storew(addr, size); } else { main.sp += Process.zargs[0]; /* it's the game stack */ } }/* z_pop_stack */
}/* memory_new_line */ /* * memory_word * * Redirect a string of characters to the memory of the Z-machine. * */ internal static void memory_word(zword[] s) { zword size; zword addr; zword c; int pos = 0; if (main.h_version == ZMachine.V6) { int width = os_.string_width(s); if (redirect[depth].xsize != 0xffff) { if (redirect[depth].width + width > redirect[depth].xsize) { if (s[pos] == ' ' || s[pos] == CharCodes.ZC_INDENT || s[pos] == CharCodes.ZC_GAP) { width = os_.string_width(s, ++pos); } memory_new_line(); } } redirect[depth].width += (zword)width; } addr = redirect[depth].table; FastMem.LOW_WORD(addr, out size); addr += 2; while ((c = s[pos++]) != 0) { FastMem.storeb((zword)(addr + (size++)), Text.translate_to_zscii(c)); } FastMem.storew(redirect[depth].table, size); }/* memory_word */
}/* z_storeb */ /* * z_storew, write a word into a table of words. * * zargs[0] = address of table * zargs[1] = index of table entry * zargs[2] = value to be written * */ internal static void z_storew() { FastMem.storew((zword)(Process.zargs[0] + 2 * Process.zargs[1]), Process.zargs[2]); }/* z_storew */