uint16_t get_variable(uint8_t variable_number, bool keep_stack_index) { uint16_t result; if (variable_number == 0) { if (stack_words_from_active_routine == 0) { if (bool_equal(skip_active_routines_stack_check_warning, false)) i18n_translate_and_exit( libfizmo_module_name, i18n_libfizmo_NOT_ENOUGH_STACK_WORDS_FROM_LOCAL_ROUTINE_ON_STACK, -1); else return 0; } if (bool_equal(keep_stack_index, true)) result = z_stack_peek_word(); else { result = z_stack_pull_word(); stack_words_from_active_routine--; } return result; } else if (variable_number < 0x10) { if (variable_number > number_of_locals_active) i18n_translate_and_exit( libfizmo_module_name, i18n_libfizmo_TRYING_TO_STORE_VARIABLE_L_P0D_BUT_ONLY_P1D_VARIABLES_ACTIVE, -1, (long int)variable_number-1, (long int)number_of_locals_active); variable_number--; result = local_variable_storage_index[variable_number]; TRACE_LOG("Reading %x from L0%x.\n", result, variable_number); return result; } else { variable_number -= 0x10; result = load_word(active_z_story->global_variables+(variable_number*2)); TRACE_LOG("Reading %x from global variable G%02x.\n", result, variable_number); return result; } }
void process_set_cursor(int16_t y, int16_t x, int16_t window) { /* * From zmach06e.ps: * Flush the buffer and set the cursor for the given window (i.e., window * properties 4 and 5) at position (s, x). It is an error in V4-5 to use * this instruction when window 0 is selected. [Question: Is the window * operand optional or not?] Exception: The first argument can be negative. * If it is − 2 (and the second argument is 0), the screen cursor is turned * on. If it is − 1, it is turned off; the second argument is ignored in * that case. */ TRACE_LOG("Processing set cursor to %d, %d, %d.\n", y, x, window); if (ver == 6) { active_interface->set_cursor(x, y, window); } else { if (active_window_number == 1) { #ifndef DISABLE_BLOCKBUFFER if ( (ver >= 3) && (upper_window_buffer != NULL) && (x >= 1) && (y >= 1) ) set_blockbuf_cursor(upper_window_buffer, x-1, y-1); #endif // DISABLE_BLOCKBUFFER if ( (y >= upper_window_height) && (bool_equal(auto_adapt_upper_window, true)) ) { TRACE_LOG("Resizing upper window to %d lines for cursor movement.\n",y); #ifndef DISABLE_BLOCKBUFFER blockbuf_resize( upper_window_buffer, (int)active_interface->get_screen_width_in_characters(), (int)y); #endif // DISABLE_BLOCKBUFFER active_interface->split_window(y); upper_window_height = (int)y; } } active_interface->set_cursor(y, x, window); } }
void set_variable(uint8_t variable_number, uint16_t data, bool keep_stack_index) { if (variable_number == 0) { if (stack_words_from_active_routine == MAXIMUM_STACK_ENTRIES_PER_ROUTINE) i18n_translate_and_exit( libfizmo_module_name, i18n_libfizmo_MAXIMUM_NUMBER_OF_STACK_ENTRIES_PER_ROUTINE_P0D_EXCEEDED, -1, (long int)MAXIMUM_STACK_ENTRIES_PER_ROUTINE); if (bool_equal(keep_stack_index, true)) { z_stack_pull_word(); z_stack_push_word(data); } else { z_stack_push_word(data); stack_words_from_active_routine++; } } else if (variable_number < 0x10) { if (variable_number > number_of_locals_active) i18n_translate_and_exit( libfizmo_module_name, i18n_libfizmo_TRYING_TO_STORE_VARIABLE_L_P0D_BUT_ONLY_P1D_VARIABLES_ACTIVE, -1, (long int)variable_number-1, (long int)number_of_locals_active); variable_number--; TRACE_LOG("Storing %x in L0%x.\n", data, variable_number); local_variable_storage_index[variable_number] = data; } else { variable_number -= 0x10; TRACE_LOG("Setting global variable G%02x to %x.\n", variable_number, data); store_word( /*@-nullderef@*/ active_z_story->global_variables /*@-nullderef@*/ +(variable_number*2), data); } }
void opcode_pull(void) { uint16_t value = 0; uint16_t spare_slots; uint8_t *user_stack; TRACE_LOG("Opcode: PULL.\n"); if (ver == 6) (void)read_z_result_variable(); if ( (ver != 6) || (number_of_operands < 1) ) { if ( (stack_words_from_active_routine == 0) && (bool_equal(skip_active_routines_stack_check_warning, false)) ) { i18n_translate_and_exit( libfizmo_module_name, i18n_libfizmo_NOT_ENOUGH_STACK_WORDS_FROM_LOCAL_ROUTINE_ON_STACK, -1); } else { TRACE_LOG("Pulling to variable %x.\n", op[0]); value = z_stack_pull_word(); stack_words_from_active_routine--; } } else { user_stack = z_mem + (uint16_t)op[0]; spare_slots = load_word(user_stack); spare_slots++; value = load_word(user_stack + spare_slots); store_word(user_stack, spare_slots); } if (ver == 6) set_variable(z_res_var, value, true); else set_variable(op[0], value, true); }
void opcode_set_window(void) { TRACE_LOG("Opcode: SET_WINDOW\n"); TRACE_LOG("New window number: %d.\n", op[0]); if (op[0] == 1) { if ( (upper_window_height == 0) && (bool_equal(auto_open_upper_window, true)) ) { // Zokoban.z5 does set_window(1) without splitting the screen. //height = (int)(active_interface->get_screen_height() / 2); // -> If the height is larger than 1 or 2, the code above gives // a wrong cursor position after restoring "Lost Pig". TRACE_LOG("Opening upper window with 1 line for set_window.\n"); #ifndef DISABLE_BLOCKBUFFER blockbuf_resize( upper_window_buffer, (int)active_interface->get_screen_width_in_characters(), 1); #endif // DISABLE_BLOCKBUFFER active_interface->split_window((int16_t)1); upper_window_height = 1; } #ifndef DISABLE_BLOCKBUFFER if (active_window_number != 1) { set_blockbuf_cursor(upper_window_buffer, 0, 0); } #endif // DISABLE_BLOCKBUFFER } active_window_number = (int16_t)op[0]; active_interface->set_window((int16_t)op[0]); }