Esempio n. 1
0
static Mask *ase_file_read_mask_chunk(FILE *f)
{
  int c, u, v, byte;
  Mask *mask;
  // Read chunk data
  int x = fgetw(f);
  int y = fgetw(f);
  int w = fgetw(f);
  int h = fgetw(f);

  ase_file_read_padding(f, 8);
  std::string name = ase_file_read_string(f);

  mask = new Mask();
  mask->setName(name.c_str());
  mask->replace(x, y, w, h);

  // Read image data
  for (v=0; v<h; v++)
    for (u=0; u<(w+7)/8; u++) {
      byte = fgetc(f);
      for (c=0; c<8; c++)
        image_putpixel(mask->getBitmap(), u*8+c, v, byte & (1<<(7-c)));
    }

  return mask;
}
Esempio n. 2
0
/* rle_tga_read16:
 *  Helper for reading 16 bit RLE data from TGA files.
 */
static void rle_tga_read16(uint32_t* address, int w, FILE *f)
{
  unsigned int value;
  uint32_t color;
  int count;
  int c = 0;

  do {
    count = fgetc(f);
    if (count & 0x80) {
      count = (count & 0x7F) + 1;
      c += count;
      value = fgetw(f);
      color = _rgba(_rgb_scale_5[((value >> 10) & 0x1F)],
                    _rgb_scale_5[((value >> 5) & 0x1F)],
                    _rgb_scale_5[(value & 0x1F)], 255);

      while (count--)
        *(address++) = color;
    }
    else {
      count++;
      c += count;
      while (count--) {
        value = fgetw(f);
        color = _rgba(_rgb_scale_5[((value >> 10) & 0x1F)],
                      _rgb_scale_5[((value >> 5) & 0x1F)],
                      _rgb_scale_5[(value & 0x1F)], 255);
        *(address++) = color;
      }
    }
  } while (c < w);
Esempio n. 3
0
static void ase_file_read_frame_header(FILE *f, ASE_FrameHeader *frame_header)
{
  frame_header->size = fgetl(f);
  frame_header->magic = fgetw(f);
  frame_header->chunks = fgetw(f);
  frame_header->duration = fgetw(f);
  ase_file_read_padding(f, 6);
}
Esempio n. 4
0
/**
 * Prepis programu wordcount z C++ do C zo zadania.
 */
int main(void)
{

	htab_t *t=htab_init(HTAB_SIZE);
	if(!t)
	{
		fprintf(stderr, "[wordcount]\t-htable was not allocated\n");
		return EXIT_FAILURE;
	}
	
	char word[WORD_LIMIT+1]={0};

	
	while(fgetw(word, WORD_LIMIT, stdin)!=EOF)
	{
		if(!htab_lookup(t, word))
		{
			fprintf(stderr, "[wordcount]\t-[htab_lookup] allocation fail\n");
			htab_free(t);
			return EXIT_FAILURE;
		}
	}


	htab_foreach(t, &print_items);
	
	//htab_statistics(t); /// vypis statistiky udajov tabulky
	
	htab_free(t);
	return EXIT_SUCCESS;
}
Esempio n. 5
0
static Palette *ase_file_read_color2_chunk(FILE *f, Sprite *sprite, int frame)
{
  int i, c, r, g, b, packets, skip, size;
  Palette* pal = new Palette(*sprite->getPalette(frame));
  pal->setFrame(frame);

  packets = fgetw(f);   // Number of packets
  skip = 0;

  // Read all packets
  for (i=0; i<packets; i++) {
    skip += fgetc(f);
    size = fgetc(f);
    if (!size) size = 256;

    for (c=skip; c<skip+size; c++) {
      r = fgetc(f);
      g = fgetc(f);
      b = fgetc(f);
      pal->setEntry(c, _rgba(r, g, b, 255));
    }
  }

  return pal;
}
Esempio n. 6
0
static bool ase_file_read_header(FILE *f, ASE_Header *header)
{
  header->pos = ftell(f);

  header->size  = fgetl(f);
  header->magic = fgetw(f);
  if (header->magic != ASE_FILE_MAGIC)
    return false;

  header->frames     = fgetw(f);
  header->width      = fgetw(f);
  header->height     = fgetw(f);
  header->depth      = fgetw(f);
  header->flags      = fgetl(f);
  header->speed      = fgetw(f);
  header->next       = fgetl(f);
  header->frit       = fgetl(f);
  header->transparent_index = fgetc(f);
  header->ignore[0]  = fgetc(f);
  header->ignore[1]  = fgetc(f);
  header->ignore[2]  = fgetc(f);
  header->ncolors    = fgetw(f);
  if (header->ncolors == 0)     // 0 means 256 (old .ase files)
    header->ncolors = 256;

  fseek(f, header->pos+128, SEEK_SET);
  return true;
}
Esempio n. 7
0
unsigned char z80readblock(FILE* file, char* buf) {
	unsigned char tmp;
	int adr;
	adr = fgetw(file);		// compressed size
	tmp = fgetc(file);		// page num
	if (adr == 0xffff) {
		fread(buf, 0x4000, 1, file);
	} else {
		z80uncompress(file, buf, 0x4000);
	}
	return tmp;
}
Esempio n. 8
0
static std::string ase_file_read_string(FILE *f)
{
  int length = fgetw(f);
  if (length == EOF)
    return "";

  std::string string;
  string.reserve(length+1);

  for (int c=0; c<length; c++)
    string.push_back(fgetc(f));

  return string;
}
Esempio n. 9
0
t_stat sim_load (FILE *fileref, char *cptr, char *fnam, int flag)
{
int32 origin, csum, zerocnt, count, word, i;

if ((*cptr != 0) || (flag != 0)) return SCPE_ARG;
for (zerocnt = 1;; zerocnt = -10) {                     /* block loop */
    for (;; zerocnt++) {                                /* skip 0's */
        if ((count = fgetc (fileref)) == EOF) return SCPE_OK;
        else if (count) break;
        else if (zerocnt == 0) return SCPE_OK;
        }
    if (fgetc (fileref) == EOF) return SCPE_FMT;
    if ((origin = fgetw (fileref)) < 0) return SCPE_FMT;
    csum = origin;                                      /* seed checksum */
    for (i = 0; i < count; i++) {                       /* get data words */
        if ((word = fgetw (fileref)) < 0) return SCPE_FMT;
        WritePW (origin, word);
        origin = origin + 1;
        csum = csum + word;
        }
    if ((word = fgetw (fileref)) < 0) return SCPE_FMT;
    if ((word ^ csum) & DMASK) return SCPE_CSUM;
    }
}
Esempio n. 10
0
static Layer *ase_file_read_layer_chunk(FILE *f, Sprite *sprite, Layer **previous_layer, int *current_level)
{
  std::string name;
  Layer *layer = NULL;
  /* read chunk data */
  int flags;
  int layer_type;
  int child_level;

  flags = fgetw(f);
  layer_type = fgetw(f);
  child_level = fgetw(f);
  fgetw(f);                     // default width
  fgetw(f);                     // default height
  fgetw(f);                     // blend mode

  ase_file_read_padding(f, 4);
  name = ase_file_read_string(f);

  /* image layer */
  if (layer_type == 0) {
    layer = new LayerImage(sprite);
  }
  /* layer set */
  else if (layer_type == 1) {
    layer = new LayerFolder(sprite);
  }

  if (layer) {
    // flags
    layer->setFlags(flags);

    // name
    layer->setName(name.c_str());

    // child level...
    if (child_level == *current_level)
      (*previous_layer)->get_parent()->add_layer(layer);
    else if (child_level > *current_level)
      static_cast<LayerFolder*>(*previous_layer)->add_layer(layer);
    else if (child_level < *current_level)
      (*previous_layer)->get_parent()->get_parent()->add_layer(layer);

    *previous_layer = layer;
    *current_level = child_level;
  }

  return layer;
}
Esempio n. 11
0
/*
 * Read words from stdin and print number of occurrences
 * @param	argc	number of arguments
 * @param	argv	arguments
 * @return	success code
 *
 */
int main(int argc, char* argv[])
{
	// This size is used, because it is enought for entire book (tested on Alice's Adventures in Wonderland and Pride and Prejudice)
	// and average number is between 0.5-2 - is used more than half and is average not more than 2 items
	htab_t* htab = htab_init(7000);
	htab_listitem* item;
	
	char word[128];
	while(fgetw(word, 127,stdin) != EOF)
	{
		item = htab_lookup(htab,word);
		item->data++;
	}

	htab_foreach(htab, &print_word);
	
	//htab_statistics(htab);

	htab_free(htab);

	return 0;
}
Esempio n. 12
0
__editor_maybe_static int load_board_direct(struct board *cur_board,
 FILE *fp, int data_size, int savegame, int version)
{
  int num_robots, num_scrolls, num_sensors, num_robots_active;
  int overlay_mode, size, board_width, board_height, i;
  int viewport_x, viewport_y, viewport_width, viewport_height;
  int truncated = 0;

  struct robot *cur_robot;
  struct scroll *cur_scroll;
  struct sensor *cur_sensor;

  char *test_buffer;

  int board_location = ftell(fp);

  cur_board->num_robots = 0;
  cur_board->num_robots_allocated = 0;
  cur_board->num_robots_active = 0;
  cur_board->num_scrolls = 0;
  cur_board->num_scrolls_allocated = 0;
  cur_board->num_sensors = 0;
  cur_board->num_sensors_allocated = 0;
  cur_board->robot_list = NULL;
  cur_board->robot_list_name_sorted = NULL;
  cur_board->sensor_list = NULL;
  cur_board->scroll_list = NULL;

  // Initialize some fields that may no longer be loaded
  // from the board file itself..

  cur_board->last_key = '?';
  cur_board->num_input = 0;
  cur_board->input_size = 0;
  cur_board->input_string[0] = 0;
  cur_board->player_last_dir = 0x10;
  cur_board->bottom_mesg[0] = 0;
  cur_board->b_mesg_timer = 0;
  cur_board->lazwall_start = 7;
  cur_board->b_mesg_row = 24;
  cur_board->b_mesg_col = -1;
  cur_board->scroll_x = 0;
  cur_board->scroll_y = 0;
  cur_board->locked_x = -1;
  cur_board->locked_y = -1;
  cur_board->volume = 255;
  cur_board->volume_inc = 0;
  cur_board->volume_target = 255;

  // board_mode, unused
  if(fgetc(fp) == EOF)
  {
    val_error(WORLD_BOARD_MISSING, board_location);
    return VAL_MISSING;
  }

  overlay_mode = fgetc(fp);

  if(!overlay_mode)
  {
    int overlay_width;
    int overlay_height;

    overlay_mode = fgetc(fp);
    overlay_width = fgetw(fp);
    overlay_height = fgetw(fp);

    size = overlay_width * overlay_height;

    if((size < 1) || (size > MAX_BOARD_SIZE))
      goto err_invalid;

    cur_board->overlay = cmalloc(size);
    cur_board->overlay_color = cmalloc(size);

    if(load_RLE2_plane(cur_board->overlay, fp, size))
      goto err_freeoverlay;

    test_buffer = cmalloc(1024);
    free(test_buffer);

    // Skip sizes
    if(fseek(fp, 4, SEEK_CUR) ||
     load_RLE2_plane(cur_board->overlay_color, fp, size))
      goto err_freeoverlay;

    test_buffer = cmalloc(1024);
    free(test_buffer);
  }
  else
  {
    overlay_mode = 0;
    // Undo that last get
    fseek(fp, -1, SEEK_CUR);
  }

  cur_board->overlay_mode = overlay_mode;

  board_width = fgetw(fp);
  board_height = fgetw(fp);
  cur_board->board_width = board_width;
  cur_board->board_height = board_height;

  size = board_width * board_height;

  if((size < 1) || (size > MAX_BOARD_SIZE))
    goto err_freeoverlay;

  cur_board->level_id = cmalloc(size);
  cur_board->level_color = cmalloc(size);
  cur_board->level_param = cmalloc(size);
  cur_board->level_under_id = cmalloc(size);
  cur_board->level_under_color = cmalloc(size);
  cur_board->level_under_param = cmalloc(size);

  if(load_RLE2_plane(cur_board->level_id, fp, size))
    goto err_freeboard;

  if(fseek(fp, 4, SEEK_CUR) ||
   load_RLE2_plane(cur_board->level_color, fp, size))
    goto err_freeboard;

  if(fseek(fp, 4, SEEK_CUR) ||
   load_RLE2_plane(cur_board->level_param, fp, size))
    goto err_freeboard;

  if(fseek(fp, 4, SEEK_CUR) ||
   load_RLE2_plane(cur_board->level_under_id, fp, size))
    goto err_freeboard;

  if(fseek(fp, 4, SEEK_CUR) ||
   load_RLE2_plane(cur_board->level_under_color, fp, size))
    goto err_freeboard;

  if(fseek(fp, 4, SEEK_CUR) ||
   load_RLE2_plane(cur_board->level_under_param, fp, size))
    goto err_freeboard;

  // Load board parameters

  if(version < 0x0253)
  {
    fread(cur_board->mod_playing, LEGACY_MOD_FILENAME_MAX, 1, fp);
    cur_board->mod_playing[LEGACY_MOD_FILENAME_MAX] = 0;
  }
  else
  {
    size_t len = fgetw(fp);
    if(len >= MAX_PATH)
      len = MAX_PATH - 1;

    fread(cur_board->mod_playing, len, 1, fp);
    cur_board->mod_playing[len] = 0;
  }

  viewport_x = fgetc(fp);
  viewport_y = fgetc(fp);
  viewport_width = fgetc(fp);
  viewport_height = fgetc(fp);

  if(
   (viewport_x < 0) || (viewport_x > 79) ||
   (viewport_y < 0) || (viewport_y > 24) ||
   (viewport_width < 1) || (viewport_width > 80) ||
   (viewport_height < 1) || (viewport_height > 25))
    goto err_invalid;

  cur_board->viewport_x = viewport_x;
  cur_board->viewport_y = viewport_y;
  cur_board->viewport_width = viewport_width;
  cur_board->viewport_height = viewport_height;
  cur_board->can_shoot = fgetc(fp);
  cur_board->can_bomb = fgetc(fp);
  cur_board->fire_burn_brown = fgetc(fp);
  cur_board->fire_burn_space = fgetc(fp);
  cur_board->fire_burn_fakes = fgetc(fp);
  cur_board->fire_burn_trees = fgetc(fp);
  cur_board->explosions_leave = fgetc(fp);
  cur_board->save_mode = fgetc(fp);
  cur_board->forest_becomes = fgetc(fp);
  cur_board->collect_bombs = fgetc(fp);
  cur_board->fire_burns = fgetc(fp);

  for(i = 0; i < 4; i++)
  {
    cur_board->board_dir[i] = fgetc(fp);
  }

  cur_board->restart_if_zapped = fgetc(fp);
  cur_board->time_limit = fgetw(fp);

  if(version < 0x0253)
  {
    cur_board->last_key = fgetc(fp);
    cur_board->num_input = fgetw(fp);
    cur_board->input_size = fgetc(fp);

    fread(cur_board->input_string, LEGACY_INPUT_STRING_MAX + 1, 1, fp);
    cur_board->input_string[LEGACY_INPUT_STRING_MAX] = 0;

    cur_board->player_last_dir = fgetc(fp);

    fread(cur_board->bottom_mesg, LEGACY_BOTTOM_MESG_MAX + 1, 1, fp);
    cur_board->bottom_mesg[LEGACY_BOTTOM_MESG_MAX] = 0;

    cur_board->b_mesg_timer = fgetc(fp);
    cur_board->lazwall_start = fgetc(fp);
    cur_board->b_mesg_row = fgetc(fp);
    cur_board->b_mesg_col = (signed char)fgetc(fp);
    cur_board->scroll_x = (signed short)fgetw(fp);
    cur_board->scroll_y = (signed short)fgetw(fp);
    cur_board->locked_x = (signed short)fgetw(fp);
    cur_board->locked_y = (signed short)fgetw(fp);
  }
  else if(savegame)
  {
    size_t len;

    cur_board->last_key = fgetc(fp);
    cur_board->num_input = fgetw(fp);
    cur_board->input_size = fgetw(fp);

    len = fgetw(fp);
    if(len >= ROBOT_MAX_TR)
      len = ROBOT_MAX_TR - 1;

    fread(cur_board->input_string, len, 1, fp);
    cur_board->input_string[len] = 0;

    cur_board->player_last_dir = fgetc(fp);

    len = fgetw(fp);
    if(len >= ROBOT_MAX_TR)
      len = ROBOT_MAX_TR - 1;

    fread(cur_board->bottom_mesg, len, 1, fp);
    cur_board->bottom_mesg[len] = 0;

    cur_board->b_mesg_timer = fgetc(fp);
    cur_board->lazwall_start = fgetc(fp);
    cur_board->b_mesg_row = fgetc(fp);
    cur_board->b_mesg_col = (signed char)fgetc(fp);
    cur_board->scroll_x = (signed short)fgetw(fp);
    cur_board->scroll_y = (signed short)fgetw(fp);
    cur_board->locked_x = (signed short)fgetw(fp);
    cur_board->locked_y = (signed short)fgetw(fp);
  }

  cur_board->player_ns_locked = fgetc(fp);
  cur_board->player_ew_locked = fgetc(fp);
  cur_board->player_attack_locked = fgetc(fp);

  if(version < 0x0253 || savegame)
  {
    cur_board->volume = fgetc(fp);
    cur_board->volume_inc = fgetc(fp);
    cur_board->volume_target = fgetc(fp);
  }


  /***************/
  /* Load robots */
  /***************/
  num_robots = fgetc(fp);
  num_robots_active = 0;

  if(num_robots == EOF)
    truncated = 1;

  // EOF/crazy value check
  if((num_robots < 0) || (num_robots > 255) || (num_robots > size))
    goto board_scan;

  cur_board->robot_list = ccalloc(num_robots + 1, sizeof(struct robot *));
  // Also allocate for name sorted list
  cur_board->robot_list_name_sorted =
   ccalloc(num_robots, sizeof(struct robot *));

  // Any null objects being placed will later be optimized out

  if(num_robots)
  {
    for(i = 1; i <= num_robots; i++)
    {
      // Make sure there's robots to load here
      int length_check = fgetw(fp);
      fseek(fp, -2, SEEK_CUR);
      if(length_check < 0)
      {
        // Send off the error and then tell validation to shut up for now
        val_error(WORLD_ROBOT_MISSING, ftell(fp));
        set_validation_suppression(1);
        truncated = 1;
      }

      cur_robot = load_robot_allocate(fp, savegame, version);
      if(cur_robot->used)
      {
        cur_board->robot_list[i] = cur_robot;
        cur_board->robot_list_name_sorted[num_robots_active] = cur_robot;
        num_robots_active++;
      }
      else
      {
        // We don't need no null robot
        clear_robot(cur_robot);
        cur_board->robot_list[i] = NULL;
      }
    }
  }

  set_validation_suppression(-1);

  if(num_robots_active > 0)
  {
    if(num_robots_active != num_robots)
    {
      cur_board->robot_list_name_sorted =
       crealloc(cur_board->robot_list_name_sorted,
       sizeof(struct robot *) * num_robots_active);
    }
    qsort(cur_board->robot_list_name_sorted, num_robots_active,
     sizeof(struct robot *), cmp_robots);
  }
  else
  {
    free(cur_board->robot_list_name_sorted);
    cur_board->robot_list_name_sorted = NULL;
  }

  cur_board->num_robots = num_robots;
  cur_board->num_robots_allocated = num_robots;
  cur_board->num_robots_active = num_robots_active;


  /****************/
  /* Load scrolls */
  /****************/
  num_scrolls = fgetc(fp);

  if(num_scrolls == EOF)
    truncated = 1;

  if((num_scrolls < 0) || (num_scrolls > 255) || (num_robots + num_scrolls > size))
    goto board_scan;

  cur_board->scroll_list = ccalloc(num_scrolls + 1, sizeof(struct scroll *));

  if(num_scrolls)
  {
    for(i = 1; i <= num_scrolls; i++)
    {
      cur_scroll = load_scroll_allocate(fp);
      if(cur_scroll->used)
        cur_board->scroll_list[i] = cur_scroll;
      else
        clear_scroll(cur_scroll);
    }
  }

  cur_board->num_scrolls = num_scrolls;
  cur_board->num_scrolls_allocated = num_scrolls;


  /****************/
  /* Load sensors */
  /****************/
  num_sensors = fgetc(fp);

  if(num_sensors == EOF)
    truncated = 1;

  if((num_sensors < 0) || (num_sensors > 255) ||
   (num_scrolls + num_sensors + num_robots > size))
    goto board_scan;

  cur_board->sensor_list = ccalloc(num_sensors + 1, sizeof(struct sensor *));

  if(num_sensors)
  {
    for(i = 1; i <= num_sensors; i++)
    {
      cur_sensor = load_sensor_allocate(fp);
      if(cur_sensor->used)
        cur_board->sensor_list[i] = cur_sensor;
      else
        clear_sensor(cur_sensor);
    }
  }

  cur_board->num_sensors = num_sensors;
  cur_board->num_sensors_allocated = num_sensors;


board_scan:
  // Now do a board scan to make sure there aren't more than the data told us.
  {
    int robot_count = 0, scroll_count = 0, sensor_count = 0;
    char err_mesg[80] = { 0 };

    for(i = 0; i < (board_width * board_height); i++)
    {
      if(cur_board->level_id[i] > 127)
        cur_board->level_id[i] = CUSTOM_BLOCK;

      if(cur_board->level_under_id[i] > 127)
        cur_board->level_under_id[i] = CUSTOM_FLOOR;

      switch(cur_board->level_id[i])
      {
        case ROBOT:
        case ROBOT_PUSHABLE:
        {
          robot_count++;
          if(robot_count > cur_board->num_robots)
          {
            cur_board->level_id[i] = CUSTOM_BLOCK;
            cur_board->level_param[i] = 'R';
            cur_board->level_color[i] = 0xCF;
          }
          break;
        }
        case SIGN:
        case SCROLL:
        {
          scroll_count++;
          if(scroll_count > cur_board->num_scrolls)
          {
            cur_board->level_id[i] = CUSTOM_BLOCK;
            cur_board->level_param[i] = 'S';
            cur_board->level_color[i] = 0xCF;
          }
        }
        case SENSOR:
        {
          // Wait, I forgot.  Nobody cares about sensors.
          //sensor_count++;
          if(sensor_count > cur_board->num_sensors)
          {
            cur_board->level_id[i] = CUSTOM_FLOOR;
            cur_board->level_param[i] = 'S';
            cur_board->level_color[i] = 0xDF;
          }
        }
      }
    }
    if(robot_count > cur_board->num_robots)
    {
      snprintf(err_mesg, 80, "Board @ %Xh: found %i robots; expected %i",
       board_location, robot_count, cur_board->num_robots);
      error(err_mesg, 1, 8, 0);
    }
    if(scroll_count > cur_board->num_scrolls)
    {
      snprintf(err_mesg, 80, "Board @ %Xh: found %i scrolls/signs; expected %i",
       board_location, scroll_count, cur_board->num_scrolls);
      error(err_mesg, 1, 8, 0);
    }
    // This won't be reached but I'll leave it anyway.
    if(sensor_count > cur_board->num_sensors)
    {
      snprintf(err_mesg, 80, "Board @ %Xh: found %i sensors; expected %i",
       board_location, sensor_count, cur_board->num_sensors);
      error(err_mesg, 1, 8, 0);
    }
    if(err_mesg[0])
      error("Any extra robots/scrolls/signs were replaced", 1, 8, 0);

  }

  if(truncated == 1)
    val_error(WORLD_BOARD_TRUNCATED_SAFE, board_location);

  return VAL_SUCCESS;

err_freeboard:
  free(cur_board->level_id);
  free(cur_board->level_color);
  free(cur_board->level_param);
  free(cur_board->level_under_id);
  free(cur_board->level_under_color);
  free(cur_board->level_under_param);

err_freeoverlay:
  if(overlay_mode)
  {
    free(cur_board->overlay);
    free(cur_board->overlay_color);
  }

err_invalid:
  val_error(WORLD_BOARD_CORRUPT, board_location);
  return VAL_INVALID;
}
Esempio n. 13
0
static Cel *ase_file_read_cel_chunk(FILE *f, Sprite *sprite, int frame,
                                    PixelFormat pixelFormat,
                                    FileOp *fop, ASE_Header *header, size_t chunk_end)
{
  /* read chunk data */
  int layer_index = fgetw(f);
  int x = ((short)fgetw(f));
  int y = ((short)fgetw(f));
  int opacity = fgetc(f);
  int cel_type = fgetw(f);
  Layer* layer;

  ase_file_read_padding(f, 7);

  layer = sprite->indexToLayer(layer_index);
  if (!layer) {
    fop_error(fop, "Frame %d didn't found layer with index %d\n",
              frame, layer_index);
    return NULL;
  }
  if (!layer->is_image()) {
    fop_error(fop, "Invalid .ase file (frame %d in layer %d which does not contain images\n",
              frame, layer_index);
    return NULL;
  }

  // Create the new frame.
  UniquePtr<Cel> cel(new Cel(frame, 0));
  cel->setPosition(x, y);
  cel->setOpacity(opacity);

  switch (cel_type) {

    case ASE_FILE_RAW_CEL: {
      // Read width and height
      int w = fgetw(f);
      int h = fgetw(f);

      if (w > 0 && h > 0) {
        Image* image = Image::create(pixelFormat, w, h);

        // Read pixel data
        switch (image->getPixelFormat()) {

          case IMAGE_RGB:
            read_raw_image<RgbTraits>(f, image, fop, header);
            break;

          case IMAGE_GRAYSCALE:
            read_raw_image<GrayscaleTraits>(f, image, fop, header);
            break;

          case IMAGE_INDEXED:
            read_raw_image<IndexedTraits>(f, image, fop, header);
            break;
        }

        cel->setImage(sprite->getStock()->addImage(image));
      }
      break;
    }

    case ASE_FILE_LINK_CEL: {
      // Read link position
      int link_frame = fgetw(f);
      Cel* link = static_cast<LayerImage*>(layer)->getCel(link_frame);

      if (link) {
        // Create a copy of the linked cel (avoid using links cel)
        Image* image = Image::createCopy(sprite->getStock()->getImage(link->getImage()));
        cel->setImage(sprite->getStock()->addImage(image));
      }
      else {
        // Linked cel doesn't found
        return NULL;
      }
      break;
    }

    case ASE_FILE_COMPRESSED_CEL: {
      // Read width and height
      int w = fgetw(f);
      int h = fgetw(f);

      if (w > 0 && h > 0) {
        Image* image = Image::create(pixelFormat, w, h);

        // Try to read pixel data
        try {
          switch (image->getPixelFormat()) {

            case IMAGE_RGB:
              read_compressed_image<RgbTraits>(f, image, chunk_end, fop, header);
              break;

            case IMAGE_GRAYSCALE:
              read_compressed_image<GrayscaleTraits>(f, image, chunk_end, fop, header);
              break;

            case IMAGE_INDEXED:
              read_compressed_image<IndexedTraits>(f, image, chunk_end, fop, header);
              break;
          }
        }
        // OK, in case of error we can show the problem, but continue
        // loading more cels.
        catch (const std::exception& e) {
          fop_error(fop, e.what());
        }

        cel->setImage(sprite->getStock()->addImage(image));
      }
      break;
    }

  }

  Cel* newCel = cel.release();
  static_cast<LayerImage*>(layer)->addCel(newCel);
  return newCel;
}
Esempio n. 14
0
bool AseFormat::onLoad(FileOp *fop)
{
  Sprite *sprite = NULL;
  ASE_Header header;
  ASE_FrameHeader frame_header;
  int current_level;
  int frame_pos;
  int chunk_pos;
  int chunk_size;
  int chunk_type;
  int c, frame;

  FileHandle f(fop->filename.c_str(), "rb");
  if (!f)
    return false;

  if (!ase_file_read_header(f, &header)) {
    fop_error(fop, "Error reading header\n");
    return false;
  }

  // Create the new sprite
  sprite = new Sprite(header.depth == 32 ? IMAGE_RGB:
                      header.depth == 16 ? IMAGE_GRAYSCALE: IMAGE_INDEXED,
                      header.width, header.height, header.ncolors);
  if (!sprite) {
    fop_error(fop, "Error creating sprite with file spec\n");
    return false;
  }

  // Set frames and speed
  sprite->setTotalFrames(header.frames);
  sprite->setDurationForAllFrames(header.speed);

  // Set transparent entry
  sprite->setTransparentColor(header.transparent_index);

  // Prepare variables for layer chunks
  Layer* last_layer = sprite->getFolder();
  current_level = -1;

  /* read frame by frame to end-of-file */
  for (frame=0; frame<sprite->getTotalFrames(); frame++) {
    /* start frame position */
    frame_pos = ftell(f);
    fop_progress(fop, (float)frame_pos / (float)header.size);

    /* read frame header */
    ase_file_read_frame_header(f, &frame_header);

    /* correct frame type */
    if (frame_header.magic == ASE_FILE_FRAME_MAGIC) {
      /* use frame-duration field? */
      if (frame_header.duration > 0)
        sprite->setFrameDuration(frame, frame_header.duration);

      /* read chunks */
      for (c=0; c<frame_header.chunks; c++) {
        /* start chunk position */
        chunk_pos = ftell(f);
        fop_progress(fop, (float)chunk_pos / (float)header.size);

        /* read chunk information */
        chunk_size = fgetl(f);
        chunk_type = fgetw(f);

        switch (chunk_type) {

          /* only for 8 bpp images */
          case ASE_FILE_CHUNK_FLI_COLOR:
          case ASE_FILE_CHUNK_FLI_COLOR2:
            /* fop_error(fop, "Color chunk\n"); */

            if (sprite->getPixelFormat() == IMAGE_INDEXED) {
              Palette *prev_pal = sprite->getPalette(frame);
              Palette *pal =
                chunk_type == ASE_FILE_CHUNK_FLI_COLOR ?
                ase_file_read_color_chunk(f, sprite, frame):
                ase_file_read_color2_chunk(f, sprite, frame);

              if (prev_pal->countDiff(pal, NULL, NULL) > 0) {
                sprite->setPalette(pal, true);
              }

              delete pal;
            }
            else
              fop_error(fop, "Warning: was found a color chunk in non-8bpp file\n");
            break;

          case ASE_FILE_CHUNK_LAYER: {
            /* fop_error(fop, "Layer chunk\n"); */

            ase_file_read_layer_chunk(f, sprite,
                                      &last_layer,
                                      &current_level);
            break;
          }

          case ASE_FILE_CHUNK_CEL: {
            /* fop_error(fop, "Cel chunk\n"); */

            ase_file_read_cel_chunk(f, sprite, frame,
                                    sprite->getPixelFormat(), fop, &header,
                                    chunk_pos+chunk_size);
            break;
          }

          case ASE_FILE_CHUNK_MASK: {
            Mask *mask;

            /* fop_error(fop, "Mask chunk\n"); */

            mask = ase_file_read_mask_chunk(f);
            if (mask)
              delete mask;      // TODO add the mask in some place?
            else
              fop_error(fop, "Warning: error loading a mask chunk\n");

            break;
          }

          case ASE_FILE_CHUNK_PATH:
            /* fop_error(fop, "Path chunk\n"); */
            break;

          default:
            fop_error(fop, "Warning: Unsupported chunk type %d (skipping)\n", chunk_type);
            break;
        }

        /* skip chunk size */
        fseek(f, chunk_pos+chunk_size, SEEK_SET);
      }
    }

    /* skip frame size */
    fseek(f, frame_pos+frame_header.size, SEEK_SET);

    /* just one frame? */
    if (fop->oneframe)
      break;

    if (fop_is_stop(fop))
      break;
  }

  fop->document = new Document(sprite);

  if (ferror(f)) {
    fop_error(fop, "Error reading file.\n");
    return false;
  }
  else {
    return true;
  }
}
Esempio n. 15
0
int loadZ80_f(Computer* comp, FILE* file) {
	int btm;
	int err = ERR_OK;
	unsigned char tmp,tmp2,reg,lst;
	unsigned short adr, twrd;
//	CPU* cpu = comp->cpu;
	char pageBuf[0xc000];
	z80v1Header hd;
	comp->p7FFD = 0x10;
	comp->pEFF7 = 0x00;
	memSetBank(comp->mem,0x00,MEM_ROM,1,MEM_16K,NULL,NULL,NULL);
	memSetBank(comp->mem,0xc0,MEM_RAM,0,MEM_16K,NULL,NULL,NULL);
	comp->vid->curscr = 5;

	fread((char*)&hd, sizeof(z80v1Header), 1, file);
	if (hd.flag12 == 0xff) hd.flag12 = 0x01;	// Because of compatibility, if byte 12 is 255, it has to be regarded as being 1.

	comp->cpu->af = (hd.a << 8) | hd.f;
	comp->cpu->bc = (hd.b << 8) | hd.c;
	comp->cpu->de = (hd.d << 8) | hd.e;
	comp->cpu->hl = (hd.h << 8) | hd.l;
	comp->cpu->af_ = (hd._a << 8) | hd._f;
	comp->cpu->bc_ = (hd._b << 8) | hd._c;
	comp->cpu->de_ = (hd._d << 8) | hd._e;
	comp->cpu->hl_ = (hd._h << 8) | hd._l;
	comp->cpu->pc = (hd.pch << 8) | hd.pcl;
	comp->cpu->sp = (hd.sph << 8) | hd.spl;
	comp->cpu->ix = (hd.ixh << 8) | hd.ixl;
	comp->cpu->iy = (hd.iyh << 8) | hd.iyl;
	comp->cpu->i = hd.i;
	comp->cpu->r7 = (hd.flag12 & 1) ? 0x80 : 0;
	comp->cpu->r = (hd.r7 & 0x7f) | comp->cpu->r7;
	comp->cpu->imode = hd.flag29 & 3;
	comp->cpu->iff1 = hd.iff1;
	comp->cpu->iff2 = hd.iff2;
	comp->cpu->inten = Z80_NMI | (hd.iff1 ? Z80_INT : 0);
	comp->vid->brdcol = (hd.flag12 >> 1) & 7;
	comp->vid->nextbrd = comp->vid->brdcol;
// unsupported things list
	if (hd.flag12 & 0x10) printf("...flag 12.bit 4.Basic SamRom switched in\n");
	if (hd.flag29 & 0x04) printf("...flag 29.bit 2.Issue 2 emulation\n");
	if (hd.flag29 & 0x08) printf("...flag 29.bit 3.Double interrupt frequency\n");
// continued
	if (comp->cpu->pc == 0) {
		adr = fgetw(file);
		twrd = fgetw(file);
		comp->cpu->pc = twrd;
		lst = fgetc(file);			// 34: HW mode
		tmp = fgetc(file);			// 35: 7FFD last out
		comp->hw->out(comp, 0x7ffd, tmp, 0);
		tmp = fgetc(file);			// 36: skip (IF1)
		tmp = fgetc(file);			// 37: skip (flags) TODO
		reg = fgetc(file);			// 38: last out to fffd
		for (tmp2 = 0; tmp2 < 16; tmp2++) {	// AY regs
			tmp = fgetc(file);
			tsOut(comp->ts, 0xfffd, tmp2);
			tsOut(comp->ts, 0xbffd, tmp);
		}
		comp->hw->out(comp, 0xfffd, reg, 0);

		if (adr > 23) {
printf(".z80 version 3\n");
			if (lst < 16) printf("Hardware: %s\n",v3hardware[lst]);
			switch (lst) {
				case 0:
				case 1:
				case 2: lst = 1; break;		// 48K
				case 4:
				case 5:
				case 6:
				case 9: lst = 2; break;		// 128K
				case 10: lst = 3; break;	// 256K
				default: lst = 0; break;	// undef
			}
			fseek(file, adr-23, SEEK_CUR);		// skip all other bytes
		} else {
printf(".z80 version 2\n");
			if (lst < 16) printf("Hardware: %s\n",v2hardware[lst]);
			switch (lst) {
				case 0:
				case 1: lst = 1; break;
				case 3:
				case 4:
				case 9: lst = 2; break;		// 128K
				case 10: lst = 3; break;	// 256K
				default: lst = 0; break;	// undef
			}
		}
		switch (lst) {
			case 1:
				btm = 1;
				do {
					tmp = z80readblock(file,pageBuf);
					switch (tmp) {
						case 4: memPutData(comp->mem,MEM_RAM,2,MEM_16K,pageBuf); break;
						case 5: memPutData(comp->mem,MEM_RAM,0,MEM_16K,pageBuf); break;
						case 8: memPutData(comp->mem,MEM_RAM,5,MEM_16K,pageBuf); break;
						default: btm = 0; break;
					}
				} while (btm && !feof(file));
				break;
			case 2:
				btm = 1;
				do {
					tmp = z80readblock(file,pageBuf);
					if ((tmp > 2) && (tmp < 11)) {
						memPutData(comp->mem,MEM_RAM,tmp-3,MEM_16K,pageBuf);
					} else {
						btm = 0;
					}
				} while (btm && !feof(file));
				break;
			case 3:
				btm = 1;
				do {
					tmp = z80readblock(file,pageBuf);
					if ((tmp > 2) && (tmp < 19)) {
						memPutData(comp->mem,MEM_RAM,tmp-3,MEM_16K,pageBuf);
					} else {
						btm = 0;
					}
				} while (btm && !feof(file));
				break;
			default:
				printf("Hardware mode not supported. reset\n");
				compReset(comp, RES_DEFAULT);
				err = ERR_Z80_HW;
				break;
		}
	} else {			// version 1
printf(".z80 version 1\n");
		if (hd.flag12 & 0x20) {
			printf("data is compressed\n");
			z80uncompress(file,pageBuf,0xc000);
			memPutData(comp->mem,MEM_RAM,5,MEM_16K,pageBuf);
			memPutData(comp->mem,MEM_RAM,2,MEM_16K,pageBuf + MEM_16K);
			memPutData(comp->mem,MEM_RAM,0,MEM_16K,pageBuf + MEM_32K);
		} else {
			printf("data is not compressed\n");
			fread(pageBuf, 0x4000, 1, file);
			memPutData(comp->mem,MEM_RAM,5,MEM_16K,pageBuf);
			fread(pageBuf, 0x4000, 1, file);
			memPutData(comp->mem,MEM_RAM,2,MEM_16K,pageBuf);
			fread(pageBuf, 0x4000, 1, file);
			memPutData(comp->mem,MEM_RAM,0,MEM_16K,pageBuf);
		}
	}
	tsReset(comp->ts);
	return err;
}
Esempio n. 16
0
/* This is a lot like try_load_world but much more thorough, and doesn't
 * pass data through or leave a file open.  This needs to be done before
 * any data is ever loaded, so that Megazeux can cleanly abort if there
 * is an issue.
 */
enum val_result validate_world_file(const char *filename,
 int savegame, int *end_of_global_offset, int decrypt_attempted)
{
  enum val_result result = VAL_SUCCESS;

  FILE *f;
  char magic[15];
  int num_boards;
  int board_name_offset;
  int v, i;

  /* TEST 1:  Make sure it's a readable file */
  if(!(f = val_fopen(filename)))
  {
    val_error(FILE_DOES_NOT_EXIST, 0);
    result = VAL_MISSING;
    goto err_out;
  }

  /* TEST 2:  Is it a save file? */
  if(savegame)
  {
    int screen_mode, num_counters, num_strings, len;

    if(fread(magic, 5, 1, f) != 1)
      goto err_invalid;

    v = save_magic(magic);
    if(!v)
      goto err_invalid;

    else if (v > WORLD_VERSION)
    {
      val_error(SAVE_VERSION_TOO_RECENT, v);
      result = VAL_VERSION;
      goto err_close;
    }
    else if (v < WORLD_VERSION)
    {
      val_error(SAVE_VERSION_OLD, v);
      result = VAL_VERSION;
      goto err_close;
    }

    /* TEST 3:  Check for truncation, savegame style, hope this
     * doesn't explode :erm:
     */
    if(
     fseek(f, 8, SEEK_SET) ||
     fseek(f, WORLD_BLOCK_1_SIZE, SEEK_CUR) ||
     fseek(f, 71, SEEK_CUR) ||
     fseek(f, (len = fgetw(f)), SEEK_CUR) ||
     (len < 0) ||
     fseek(f, WORLD_BLOCK_2_SIZE, SEEK_CUR) ||
     fseek(f, 24, SEEK_CUR))
    {
      debug("pre-counters\n");
      goto err_invalid;
    }

    //do counters - vvvvnnnn(name)
    num_counters = fgetd(f);
    if(num_counters < 0)
    {
      debug("counter num\n");
      goto err_invalid;
    }

    for(i = 0; i < num_counters; i++)
    {
      if(
       fseek(f, 4, SEEK_CUR) || //value
       fseek(f, (len = fgetd(f)), SEEK_CUR) ||
       (len < 0))
      {
        debug("counters\n");
        goto err_invalid;
      }
    }

    //do strings-   nnnnllll(name)(value)
    num_strings = fgetd(f);
    if(num_strings < 0)
    {
      debug("string num\n");
      goto err_invalid;
    }

    for(i = 0; i < num_strings; i++)
    {
      int name_length = fgetd(f);
      int value_length = fgetd(f);
      if(
       (name_length < 0) ||
       (value_length < 0) ||
       fseek(f, name_length, SEEK_CUR) ||
       fseek(f, value_length, SEEK_CUR))
      {
        debug("strings\n");
        goto err_invalid;
      }
    }

    if(
     fseek(f, 4612, SEEK_CUR) || //sprites
     fseek(f, 12, SEEK_CUR) || //misc
     fseek(f, fgetw(f), SEEK_CUR) || //fread_open
     fseek(f, 4, SEEK_CUR) || //fread_pos
     fseek(f, fgetw(f), SEEK_CUR) || //fwrite_open
     fseek(f, 4, SEEK_CUR)) //fwrite_pos
    {
      debug("post strings\n");
      goto err_invalid;
    }

    screen_mode = fgetw(f);
    if((screen_mode > 3) || (screen_mode > 1 &&
     fseek(f, 768, SEEK_CUR))) //smzx palette
    {
      debug("smzx palette\n");
      goto err_invalid;
    }

    if(
     fseek(f, 4, SEEK_CUR) || //commands
     ((len = fgetd(f)) < 0) || //vlayer size
     fseek(f, 4, SEEK_CUR) || // width & height
     fseek(f, len, SEEK_CUR) || //chars
     fseek(f, len, SEEK_CUR)) //colors
    {
      debug("vlayer\n");
      goto err_invalid;
    }

    /* now we should be at the global robot pointer! */
  }

  else /* !savegame */
  {
    int protection_method;

    /* TEST 3:  Check for truncation */
    if(fseek(f, WORLD_GLOBAL_OFFSET_OFFSET, SEEK_SET))
      goto err_invalid;

    fseek(f, BOARD_NAME_SIZE, SEEK_SET);

    /* TEST 4:  If we think it's locked, try to decrypt it. */
    protection_method = fgetc(f);
    if(protection_method > 0)
    {
      if(protection_method > 3)
        goto err_invalid;

      if(decrypt_attempted) // In the unlikely event that this will happen again
        goto err_invalid;

      val_error(WORLD_PASSWORD_PROTECTED, 0);

      if(!confirm(NULL, "Would you like to decrypt it?"))
      {
        result = VAL_NEED_UNLOCK;
        goto err_close;
      }
      else
      {
        val_error(WORLD_LOCKED, 0);
        result = VAL_ABORTED;
        goto err_close;
      }
    }

    /* TEST 5:  Make sure the magic is awwrightttt~ */
    fread(magic, 1, 3, f);

    v = world_magic(magic);
    if(v == 0)
      goto err_invalid;

    else if (v < 0x0205)
    {
      val_error(WORLD_FILE_VERSION_OLD, v);
      result = VAL_VERSION;
      goto err_close;
    }
    else if (v > WORLD_VERSION)
    {
      val_error(WORLD_FILE_VERSION_TOO_RECENT, v);
      result = VAL_VERSION;
      goto err_close;
    }

    /* TEST 6:  Attempt to eliminate invalid files by
     * testing the palette for impossible values.
     */
    fseek(f, WORLD_GLOBAL_OFFSET_OFFSET - 48, SEEK_SET);
    for(i = 0; i<48; i++)
    {
      int val = fgetc(f);
      if((val < 0) || (val > 63))
        goto err_invalid;
    }

    /* now we should be at the global robot pointer! */
  }

  /* TEST 7:  Either branch should be at the global robot pointer now.
   * Test for valid SFX structure, if applicable, and board information.
   */
  fseek(f, 4, SEEK_CUR);

  // Do the sfx
  num_boards = fgetc(f);
  if(num_boards == 0)
  {
    int sfx_size = fgetw(f);
    int sfx_off = ftell(f);

    for (i = 0; i < NUM_SFX; i++)
    {
      if(fseek(f, fgetc(f), SEEK_CUR))
        break;
    }

    if((i != NUM_SFX) || ((ftell(f) - sfx_off) != sfx_size))
      goto err_invalid;

    num_boards = fgetc(f);
  }
  if(num_boards == 0)
    goto err_invalid;

  board_name_offset = ftell(f);

  //Make sure board name and pointer data exists
  if(
   fseek(f, num_boards * BOARD_NAME_SIZE, SEEK_CUR) ||
   fseek(f, num_boards * 8, SEEK_CUR) ||
   ((ftell(f) - board_name_offset) != num_boards * (BOARD_NAME_SIZE + 8)))
    goto err_invalid;

  /* If any of the pointers are less than this pos we probably
   * aren't dealing with a valid world, but it's not our job
   * to figure that out right now, so we'll pass it back.
   */
  if(end_of_global_offset)
    *end_of_global_offset = ftell(f);

  //todo: maybe have a complete fail when N number of pointers fail?

  goto err_close;

err_invalid:
  result = VAL_INVALID;
  if(savegame)
    val_error(SAVE_FILE_INVALID, 0);
  else
    val_error(WORLD_FILE_INVALID, 0);
err_close:
  fclose(f);
err_out:
  return result;
}
Esempio n. 17
0
void help_system(struct world *mzx_world)
{
  char file[13], file2[13], label[13];
  int where, offs, size, t1, t2;
  enum cursor_mode_types old_cmode;
  FILE *fp;

  fp = mzx_world->help_file;
  if(!fp)
    return;

  old_cmode = get_cursor_mode();

  rewind(fp);
  t1 = fgetw(fp);
  fseek(fp, t1 * 21 + 4 + get_context() * 12, SEEK_SET);

  // At proper context info
  where = fgetd(fp);    // Where file to load is
  size = fgetd(fp);     // Size of file to load
  offs = fgetd(fp);     // Offset within file of link

  // Jump to file
  fseek(fp, where, SEEK_SET);
  // Read it in
  fread(help, 1, size, fp);
  // Display it
  cursor_off();

labelled:
  help_display(mzx_world, help, offs, file, label);

  // File?
  if(file[0])
  {
    // Yep. Search for file.
    fseek(fp, 2, SEEK_SET);
    for(t2 = 0; t2 < t1; t2++)
    {
      fread(file2, 1, 13, fp);
      if(!strcmp(file, file2))
        break;
      fseek(fp, 8, SEEK_CUR);
    }

    if(t2 < t1)
    {
      // Found file.
      where = fgetd(fp);
      size = fgetd(fp);
      fseek(fp, where, SEEK_SET);
      fread(help, 1, size, fp);

      // Search for label
      for(t2 = 0; t2 < size; t2++)
      {
        if(help[t2] != 255)
          continue;
        if(help[t2 + 1] != ':')
          continue;
        if(!strcmp(help + t2 + 3, label))
          break; // Found label!
      }

      if(t2 < size)
      {
        // Found label. t2 is offset.
        offs = t2;
        goto labelled;
      }
    }
  }

  set_cursor_mode(old_cmode);
}
Esempio n. 18
0
__editor_maybe_static void load_board_direct(struct board *cur_board,
 FILE *fp, int savegame, int version)
{
  int num_robots, num_scrolls, num_sensors, num_robots_active;
  int overlay_mode, size, board_width, board_height, i;

  struct robot *cur_robot;
  struct scroll *cur_scroll;
  struct sensor *cur_sensor;

  char *test_buffer;

  // Initialize some fields that may no longer be loaded
  // from the board file itself..

  cur_board->last_key = '?';
  cur_board->num_input = 0;
  cur_board->input_size = 0;
  cur_board->input_string[0] = 0;
  cur_board->player_last_dir = 0x10;
  cur_board->bottom_mesg[0] = 0;
  cur_board->b_mesg_timer = 0;
  cur_board->lazwall_start = 7;
  cur_board->b_mesg_row = 24;
  cur_board->b_mesg_col = -1;
  cur_board->scroll_x = 0;
  cur_board->scroll_y = 0;
  cur_board->locked_x = -1;
  cur_board->locked_y = -1;
  cur_board->volume = 255;
  cur_board->volume_inc = 0;
  cur_board->volume_target = 255;

  // board_mode, unused
  fgetc(fp);

  overlay_mode = fgetc(fp);

  if(!overlay_mode)
  {
    int overlay_width;
    int overlay_height;

    overlay_mode = fgetc(fp);
    overlay_width = fgetw(fp);
    overlay_height = fgetw(fp);

    size = overlay_width * overlay_height;

    cur_board->overlay = cmalloc(size);
    cur_board->overlay_color = cmalloc(size);

    load_RLE2_plane(cur_board->overlay, fp, size);
    test_buffer = cmalloc(1024);
    free(test_buffer);

    // Skip sizes
    fseek(fp, 4, SEEK_CUR);
    load_RLE2_plane(cur_board->overlay_color, fp, size);
    test_buffer = cmalloc(1024);
    free(test_buffer);
  }
  else
  {
    overlay_mode = 0;
    // Undo that last get
    fseek(fp, -1, SEEK_CUR);
  }

  cur_board->overlay_mode = overlay_mode;

  board_width = fgetw(fp);
  board_height = fgetw(fp);
  cur_board->board_width = board_width;
  cur_board->board_height = board_height;

  size = board_width * board_height;

  cur_board->level_id = cmalloc(size);
  cur_board->level_color = cmalloc(size);
  cur_board->level_param = cmalloc(size);
  cur_board->level_under_id = cmalloc(size);
  cur_board->level_under_color = cmalloc(size);
  cur_board->level_under_param = cmalloc(size);

  load_RLE2_plane(cur_board->level_id, fp, size);
  fseek(fp, 4, SEEK_CUR);
  load_RLE2_plane(cur_board->level_color, fp, size);
  fseek(fp, 4, SEEK_CUR);
  load_RLE2_plane(cur_board->level_param, fp, size);
  fseek(fp, 4, SEEK_CUR);
  load_RLE2_plane(cur_board->level_under_id, fp, size);
  fseek(fp, 4, SEEK_CUR);
  load_RLE2_plane(cur_board->level_under_color, fp, size);
  fseek(fp, 4, SEEK_CUR);
  load_RLE2_plane(cur_board->level_under_param, fp, size);

  // Load board parameters

  if(version < 0x0253)
  {
    fread(cur_board->mod_playing, LEGACY_MOD_FILENAME_MAX, 1, fp);
    cur_board->mod_playing[LEGACY_MOD_FILENAME_MAX] = 0;
  }
  else
  {
    size_t len = fgetw(fp);
    if(len >= MAX_PATH)
      len = MAX_PATH - 1;

    fread(cur_board->mod_playing, len, 1, fp);
    cur_board->mod_playing[len] = 0;
  }

  cur_board->viewport_x = fgetc(fp);
  cur_board->viewport_y = fgetc(fp);
  cur_board->viewport_width = fgetc(fp);
  cur_board->viewport_height = fgetc(fp);
  cur_board->can_shoot = fgetc(fp);
  cur_board->can_bomb = fgetc(fp);
  cur_board->fire_burn_brown = fgetc(fp);
  cur_board->fire_burn_space = fgetc(fp);
  cur_board->fire_burn_fakes = fgetc(fp);
  cur_board->fire_burn_trees = fgetc(fp);
  cur_board->explosions_leave = fgetc(fp);
  cur_board->save_mode = fgetc(fp);
  cur_board->forest_becomes = fgetc(fp);
  cur_board->collect_bombs = fgetc(fp);
  cur_board->fire_burns = fgetc(fp);

  for(i = 0; i < 4; i++)
  {
    cur_board->board_dir[i] = fgetc(fp);
  }

  cur_board->restart_if_zapped = fgetc(fp);
  cur_board->time_limit = fgetw(fp);

  if(version < 0x0253)
  {
    cur_board->last_key = fgetc(fp);
    cur_board->num_input = fgetw(fp);
    cur_board->input_size = fgetc(fp);

    fread(cur_board->input_string, LEGACY_INPUT_STRING_MAX + 1, 1, fp);
    cur_board->input_string[LEGACY_INPUT_STRING_MAX] = 0;

    cur_board->player_last_dir = fgetc(fp);

    fread(cur_board->bottom_mesg, LEGACY_BOTTOM_MESG_MAX + 1, 1, fp);
    cur_board->bottom_mesg[LEGACY_BOTTOM_MESG_MAX] = 0;

    cur_board->b_mesg_timer = fgetc(fp);
    cur_board->lazwall_start = fgetc(fp);
    cur_board->b_mesg_row = fgetc(fp);
    cur_board->b_mesg_col = (signed char)fgetc(fp);
    cur_board->scroll_x = (signed short)fgetw(fp);
    cur_board->scroll_y = (signed short)fgetw(fp);
    cur_board->locked_x = (signed short)fgetw(fp);
    cur_board->locked_y = (signed short)fgetw(fp);
  }
  else if(savegame)
  {
    size_t len;

    cur_board->last_key = fgetc(fp);
    cur_board->num_input = fgetw(fp);
    cur_board->input_size = fgetw(fp);

    len = fgetw(fp);
    if(len >= ROBOT_MAX_TR)
      len = ROBOT_MAX_TR - 1;

    fread(cur_board->input_string, len, 1, fp);
    cur_board->input_string[len] = 0;

    cur_board->player_last_dir = fgetc(fp);

    len = fgetw(fp);
    if(len >= ROBOT_MAX_TR)
      len = ROBOT_MAX_TR - 1;

    fread(cur_board->bottom_mesg, len, 1, fp);
    cur_board->bottom_mesg[len] = 0;

    cur_board->b_mesg_timer = fgetc(fp);
    cur_board->lazwall_start = fgetc(fp);
    cur_board->b_mesg_row = fgetc(fp);
    cur_board->b_mesg_col = (signed char)fgetc(fp);
    cur_board->scroll_x = (signed short)fgetw(fp);
    cur_board->scroll_y = (signed short)fgetw(fp);
    cur_board->locked_x = (signed short)fgetw(fp);
    cur_board->locked_y = (signed short)fgetw(fp);
  }

  cur_board->player_ns_locked = fgetc(fp);
  cur_board->player_ew_locked = fgetc(fp);
  cur_board->player_attack_locked = fgetc(fp);

  if(version < 0x0253 || savegame)
  {
    cur_board->volume = fgetc(fp);
    cur_board->volume_inc = fgetc(fp);
    cur_board->volume_target = fgetc(fp);
  }

  // Load robots
  num_robots = fgetc(fp);
  num_robots_active = 0;

  cur_board->robot_list = ccalloc(num_robots + 1, sizeof(struct robot *));
  // Also allocate for name sorted list
  cur_board->robot_list_name_sorted =
   ccalloc(num_robots, sizeof(struct robot *));

  // Any null objects being placed will later be optimized out

  if(num_robots)
  {
    for(i = 1; i <= num_robots; i++)
    {
      cur_robot = load_robot_allocate(fp, savegame, version);
      if(cur_robot->used)
      {
        cur_board->robot_list[i] = cur_robot;
        cur_board->robot_list_name_sorted[num_robots_active] = cur_robot;
        num_robots_active++;
      }
      else
      {
        // We don't need no null robot
        clear_robot(cur_robot);
        cur_board->robot_list[i] = NULL;
      }
    }
  }

  if(num_robots_active)
  {
    if(num_robots_active != num_robots)
    {
      cur_board->robot_list_name_sorted =
       crealloc(cur_board->robot_list_name_sorted,
       sizeof(struct robot *) * num_robots_active);
    }
    qsort(cur_board->robot_list_name_sorted, num_robots_active,
     sizeof(struct robot *), cmp_robots);
  }
  else
  {
    free(cur_board->robot_list_name_sorted);
    cur_board->robot_list_name_sorted = NULL;
  }

  cur_board->num_robots = num_robots;
  cur_board->num_robots_allocated = num_robots;
  cur_board->num_robots_active = num_robots_active;

  // Load scrolls
  num_scrolls = fgetc(fp);
  cur_board->scroll_list = ccalloc(num_scrolls + 1, sizeof(struct scroll *));

  if(num_scrolls)
  {
    for(i = 1; i <= num_scrolls; i++)
    {
      cur_scroll = load_scroll_allocate(fp);
      if(cur_scroll->used)
        cur_board->scroll_list[i] = cur_scroll;
      else
        clear_scroll(cur_scroll);
    }
  }

  cur_board->num_scrolls = num_scrolls;
  cur_board->num_scrolls_allocated = num_scrolls;

  // Load sensors
  num_sensors = fgetc(fp);
  cur_board->sensor_list = ccalloc(num_sensors + 1, sizeof(struct sensor *));

  if(num_sensors)
  {
    for(i = 1; i <= num_sensors; i++)
    {
      cur_sensor = load_sensor_allocate(fp);
      if(cur_sensor->used)
        cur_board->sensor_list[i] = cur_sensor;
      else
        clear_sensor(cur_sensor);
    }
  }

  cur_board->num_sensors = num_sensors;
  cur_board->num_sensors_allocated = num_sensors;
}
bool CMapLoaderGalaxy::loadMap(CMap &Map, Uint8 level)
{
    // Get the MAPHEAD Location from within the Exe File or an external file
    std::vector<char> mapHeadContainer;
    const std::string &path = gKeenFiles.gameDir;

    // Set Map position and some flags for the freshly loaded level
    Map.gotoPos(0,0);
    Map.setLevel(level);
    Map.isSecret = false;
    Map.mNumFuses = 0;

    // In case no external file was read, let's use data from the embedded data
    byte *Maphead = gKeenFiles.exeFile.getRawData() + getMapheadOffset();

    // In case there is an external file read it into the container and replace the pointer
    const std::string mapHeadFilename = gKeenFiles.mapheadFilename;
    std::ifstream MapHeadFile;

    if(OpenGameFileR(MapHeadFile, getResourceFilename(mapHeadFilename,path,true,false), std::ios::binary))
    {
        // get length of file:
        MapHeadFile.seekg (0, std::ios::end);
        unsigned int length = MapHeadFile.tellg();
        MapHeadFile.seekg (0, std::ios::beg);
        mapHeadContainer.resize(length);
        MapHeadFile.read(&mapHeadContainer[0],length*sizeof(char));
        Maphead = reinterpret_cast<byte*>(&mapHeadContainer[0]);
    }

    word magic_word;
    longword level_offset;

    // Get the magic number of the level data from MAPHEAD Located in the EXE-File.
    // This is used for the decompression.
    magic_word = READWORD(Maphead);

    // Get location of the level data from MAPHEAD Located in the EXE-File.
    Maphead += level*sizeof(longword);
    level_offset = READLONGWORD(Maphead);

    // Open the Gamemaps file
    std::string gamemapfile = gKeenFiles.gamemapsFilename;

    std::ifstream MapFile;
    if(OpenGameFileR(MapFile, getResourceFilename(gamemapfile,path,true,false), std::ios::binary))
    {
        if(level_offset == 0 && mapHeadContainer.empty())
        {
            MapFile.close();
            gLogging.textOut("This Level doesn't exist in GameMaps");
            return false;
        }

        // Then jump to that location and read the level map data
        MapFile.seekg (level_offset, std::ios::beg);

        int headbegin;

        // Get the level plane header
        if(gotoNextSignature(MapFile))
        {
            /*
            *			  Plane Offsets:  Long[3]   Offset within GAMEMAPS to the start of the plane.  The first offset is for the background plane, the
            *                           second for the foreground plane, and the third for the info plane (see below).
            *			  Plane Lengths:  Word[3]   Length (in bytes) of the compressed plane data.  The first length is for the background plane, the
            *                           second for the foreground plane, and the third for the info plane (see below).
            *			  Width:          Word      Level width (in tiles).
            *			  Height:         Word      Level height (in tiles).  Together with Width, this can be used to calculate the uncompressed
            *										size of plane data, by multiplying Width by Height and multiplying the result by sizeof(Word).
            *			  Name:           Byte[16]  Null-terminated string specifying the name of the level.  This name is used only by TED5, not by Keen.
            *			  Signature:      Byte[4]   Marks the end of the Level Header.  Always "!ID!".
            */
            int jumpback = 3*sizeof(longword) + 3*sizeof(word) +
                           2*sizeof(word) + 16*sizeof(byte) + 4*sizeof(byte);

            headbegin = static_cast<int>(MapFile.tellg()) - jumpback;
        }
        else
        {
            MapFile.clear();
            headbegin =  level_offset;
        }

        MapFile.seekg( headbegin, std::ios_base::beg);

        // Get the header of level data
        longword Plane_Offset[3];
        longword Plane_Length[3];
        word Width, Height;
        char name[17];

        // Get the plane offsets
        Plane_Offset[0] = fgetl(MapFile);
        Plane_Offset[1] = fgetl(MapFile);
        Plane_Offset[2] = fgetl(MapFile);

        // Get the dimensions of the level
        Plane_Length[0] = fgetw(MapFile);
        Plane_Length[1] = fgetw(MapFile);
        Plane_Length[2] = fgetw(MapFile);

        Width = fgetw(MapFile);
        Height = fgetw(MapFile);


        if(Width>1024 || Height>1024)
        {
            gLogging.textOut("Sorry, but I cannot uncompress this map and must give up."
                             "Please report this to the developers and send that version to them in order to fix it.<br>" );
            return false;
        }


        for(int c=0 ; c<16 ; c++)
        {
            name[c] = MapFile.get();
        }
        name[16] = '\0';

        // Get and check the signature
        gLogging.textOut("Loading the Level \"" + static_cast<std::string>(name) + "\" (Level No. "+ itoa(level) + ")<br>" );
        Map.setLevelName(name);

        mLevelName = name;

        // Then decompress the level data using rlew and carmack
        gLogging.textOut("Decompressing the Map...<br>" );

        // Start with the Background
        Map.createEmptyDataPlane(0, Width, Height);
        Map.createEmptyDataPlane(1, Width, Height);
        Map.createEmptyDataPlane(2, Width, Height);

        unpackPlaneData(MapFile, Map, 0, Plane_Offset[0], Plane_Length[0], magic_word);
        unpackPlaneData(MapFile, Map, 1, Plane_Offset[1], Plane_Length[1], magic_word);
        unpackPlaneData(MapFile, Map, 2, Plane_Offset[2], Plane_Length[2], magic_word);


        Map.collectBlockersCoordiantes();
        MapFile.close();

        // Now that we have all the 3 planes (Background, Foreground, Foes) unpacked...
        // We only will show the first two of them in the screen, because the Foes one
        // is the one which will be used for spawning the foes (Keen, platforms, enemies, etc.)
        spawnFoes(Map);
    }
    else
    {
        return false;
    }


    // Set Scrollbuffer
    Map.drawAll();
    gVideoDriver.updateScrollBuffer(Map.m_scrollx, Map.m_scrolly);

    return true;
}
Esempio n. 20
0
/* loads a COL file (Animator and Animator Pro format) */
Palette *load_col_file(const char *filename)
{
#if (MAKE_VERSION(4, 2, 1) >= MAKE_VERSION(ALLEGRO_VERSION,             \
                                           ALLEGRO_SUB_VERSION,         \
                                           ALLEGRO_WIP_VERSION))
  int size = file_size(filename);
#else
  int size = file_size_ex(filename);
#endif
  int pro = (size == 768)? false: true; /* is Animator Pro format? */
  div_t d = div(size-8, 3);
  Palette *pal = NULL;
  int c, r, g, b;
  FILE *f;

  if (!(size) || (pro && d.rem)) /* invalid format */
    return NULL;

  f = fopen(filename, "rb");
  if (!f)
    return NULL;

  /* Animator format */
  if (!pro) {
    pal = new Palette(FrameNumber(0), 256);

    for (c=0; c<256; c++) {
      r = fgetc(f);
      g = fgetc(f);
      b = fgetc(f);
      if (ferror(f))
        break;

      pal->setEntry(c, _rgba(_rgb_scale_6[MID(0, r, 63)],
                             _rgb_scale_6[MID(0, g, 63)],
                             _rgb_scale_6[MID(0, b, 63)], 255));
    }
  }
  /* Animator Pro format */
  else {
    int magic, version;

    fgetl(f);                   /* skip file size */
    magic = fgetw(f);           /* file format identifier */
    version = fgetw(f);         /* version file */

    /* unknown format */
    if (magic != PROCOL_MAGIC_NUMBER || version != 0) {
      fclose(f);
      return NULL;
    }

    pal = new Palette(FrameNumber(0), MIN(d.quot, 256));

    for (c=0; c<pal->size(); c++) {
      r = fgetc(f);
      g = fgetc(f);
      b = fgetc(f);
      if (ferror(f))
        break;

      pal->setEntry(c, _rgba(MID(0, r, 255),
                             MID(0, g, 255),
                             MID(0, b, 255), 255));
    }
  }

  fclose(f);
  return pal;
}