Ejemplo n.º 1
0
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;
  }
}
Ejemplo n.º 2
0
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);
  }
}
Ejemplo n.º 3
0
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);
  }
}
Ejemplo n.º 4
0
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);

}
Ejemplo n.º 5
0
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]);
}