Ejemplo n.º 1
0
static void
read_level_dir (const char *dirname)
{
  DIR *dir;
  struct dirent* de;
  int n = 0;

  dmsg (D_FILE | D_SECTION, "reading level list from %s", dirname);

  dir = opendir (dirname);
  if (!dir) {
    dperror ("opendir");
    emsg (_("cannot open directory %s"), dirname);
  }

  while ((de = readdir (dir)))
    if (select_file_lvl (de)) {
      char *filename;
      a_level tmp_lvl;

      if (level_list_size >= level_list_max) {
	level_list_max += 32;
	XREALLOC_ARRAY (level_list, level_list_max);
      }

      filename = xmalloc (strlen (dirname) + 1 + strlen (de->d_name) + 1);
      sprintf (filename, "%s/%s", dirname, de->d_name);
      level_list[level_list_size].name = filename;

      dmsg (D_FILE, "loading header from %s", filename);
      lvl_load_file (filename, &tmp_lvl, false);
      level_list[level_list_size].wrapped =
	(tmp_lvl.tile_width_wrap != DONT_WRAP
	 && tmp_lvl.tile_height_wrap != DONT_WRAP);
      lvl_free (&tmp_lvl);

      ++level_list_size;
    }

  closedir (dir);
  dmsg (D_FILE, "... %d files", n);
}
Ejemplo n.º 2
0
static void
trigger_explosion_at_time (a_square_index idx, long orig_time)
{
  int state;
  bool propagated;

  /* We don't trigger explosions in the future.  */
  assert (explo_time >= orig_time);

  state = compute_explosion_state (orig_time);

  /* Maybe we need to propagate this explosion.  Note that STATE may
     happen to be negative, meaning the explosion vanished; we still
     try propagate.  */
  if (state <= EXPLOSION_TRIGGER_NEIGHBORS) {
    propagate_to_neighbors_maybe (idx, orig_time);
    propagated = true;
  } else {
    propagated = false;
  }

  /* Insert the explosion into the list of active explosions
     only if it's active...  */
  if (state >= 0) {
    if (explo_list_max <= explo_list_first_unused) {
      explo_list_max += 64;
      XREALLOC_ARRAY (explo_list, explo_list_max);
    }

    explo_list[explo_list_first_unused].orig_time = orig_time;
    explo_list[explo_list_first_unused].idx = idx;
    explo_list[explo_list_first_unused].neighb_done = propagated;
    ++explo_list_first_unused;

    /* Update level rendering information.  */
    square_explo_state[idx] = state;
    square_explo_type[idx] = rand () % NBR_EXPLOSION_KINDS;
  }
}
Ejemplo n.º 3
0
Lisp_Object
unparesseuxify_doc_string (int fd, EMACS_INT position,
                           Ibyte *name_nonreloc, Lisp_Object name_reloc,
			   int standard_doc_file)
{
  Ibyte buf[512 * 32 + 1];
  Ibyte *buffer = buf;
  int buffer_size = sizeof (buf) - 1;
  Ibyte *from, *to;
  REGISTER Ibyte *p = buffer;
  Lisp_Object return_me;
  Lisp_Object fdstream = Qnil, instream = Qnil;
  struct gcpro gcpro1, gcpro2;

  GCPRO2 (fdstream, instream);

  if (0 > lseek (fd, position, 0))
    {
      if (name_nonreloc)
	name_reloc = build_istring (name_nonreloc);
      return_me = list3 (build_msg_string
			 ("Position out of range in doc string file"),
			  name_reloc, make_fixnum (position));
      goto done;
    }

  fdstream = make_filedesc_input_stream (fd, 0, -1, 0, NULL);
  Lstream_set_buffering (XLSTREAM (fdstream), LSTREAM_UNBUFFERED, 0);
  instream =
    make_coding_input_stream
      /* Major trouble if we are too clever when reading byte-code
	 instructions!

	 #### We should have a way of handling escape-quoted elc files
	 (i.e. files with non-ASCII/Latin-1 chars in them).  Currently this
	 is "solved" in bytecomp.el by never inserting lazy references in
	 such files. */
      (XLSTREAM (fdstream), standard_doc_file ? Qescape_quoted : Qbinary,
       CODING_DECODE, 0);
  Lstream_set_buffering (XLSTREAM (instream), LSTREAM_UNBUFFERED, 0);
  
  /* Read the doc string into a buffer.
     Use the fixed buffer BUF if it is big enough; otherwise allocate one.
     We store the buffer in use in BUFFER and its size in BUFFER_SIZE.  */

  while (1)
    {
      int space_left = buffer_size - (p - buffer);
      int nread;

      /* Switch to a bigger buffer if we need one.  */
      if (space_left == 0)
	{
          Ibyte *old_buffer = buffer;
	  buffer_size *= 2;

	  if (buffer == buf)
	    {
	      buffer = xnew_ibytes (buffer_size + 1);
	      memcpy (buffer, old_buffer, p - old_buffer);
	    }
	  else
            XREALLOC_ARRAY (buffer, Ibyte, buffer_size + 1);
          p += buffer - old_buffer;
	  space_left = buffer_size - (p - buffer);
	}

      /* Don't read too much at one go.  */
      if (space_left > 1024 * 8)
	space_left = 1024 * 8;
      nread = Lstream_read (XLSTREAM (instream), p, space_left);
      if (nread < 0)
	{
	  return_me = list1 (build_msg_string
			     ("Read error on documentation file"));
	  goto done;
	}
      p[nread] = 0;
      if (!nread)
	break;
      {
	Ibyte *p1 = qxestrchr (p, '\037'); /* End of doc string marker */
	if (p1)
	  {
	    *p1 = 0;
	    p = p1;
	    break;
	  }
      }
      p += nread;
    }

  /* Scan the text and remove quoting with ^A (char code 1).
     ^A^A becomes ^A, ^A0 becomes a null char, and ^A_ becomes a ^_.  */
  from = to = buffer;
  while (from < p)
    {
      if (*from != 1 /*^A*/)
	*to++ = *from++;
      else
	{
	  int c = *(++from);

	  from++;
          switch (c)
            {
            case 1:   *to++ =  c;     break;
            case '0': *to++ = '\0';   break;
            case '_': *to++ = '\037'; break;
            default:
              return_me = list2 (build_msg_string
	("Invalid data in documentation file -- ^A followed by weird code"),
                                 make_fixnum (c));
              goto done;
            }
	}
    }

  return_me = make_string (buffer, to - buffer);

 done:
  if (!NILP (instream))
    {
      Lstream_delete (XLSTREAM (instream));
      Lstream_delete (XLSTREAM (fdstream));
    }
  UNGCPRO;
  if (buffer != buf) /* We must have allocated buffer above */
    xfree (buffer);
  return return_me;
}