예제 #1
0
/* Read the header bytes of the given solution file. flags receives
 * the option bytes (bytes 5-6). extra receives any bytes in the
 * header that this code doesn't recognize.
 */
static int readsolutionheader(fileinfo *file, int ruleset, int *flags,
			      int *extrasize, unsigned char *extra)
{
    uint32_t		sig;
    uint16_t		f;
    uint8_t		n;

    if (!filereadint32(file, &sig, "not a valid solution file"))
	return FALSE;
    if (sig != CSSIG)
	return fileerr(file, "not a valid solution file");
    if (!filereadint8(file, &n, "not a valid solution file"))
	return FALSE;
    if (n != ruleset)
	return fileerr(file, "solution file is for a different ruleset"
			     " than the level set file");
    if (!filereadint16(file, &f, "not a valid solution file"))
	return FALSE;
    *flags = (int)f;

    if (!filereadint8(file, &n, "not a valid solution file"))
	return FALSE;
    *extrasize = n;
    if (n)
	if (!fileread(file, extra, *extrasize, "not a valid solution file"))
	    return FALSE;

    return TRUE;
}
예제 #2
0
파일: fileread.c 프로젝트: BR903/cgames
/* Read the puzzle file corresponding to series, and the corresponding
 * solutions in the answer file, until at least level maps have been
 * successfully parsed, or the end is reached. The files are opened if
 * they have not been already. No files are opened if the requested
 * level has already been loaded into memory.
 */
int readlevelinseries(gameseries *series, int level)
{
    int	n;

    if (level < 0)
	return FALSE;
    if (series->count > level)
	return TRUE;

    if (!series->allmapsread) {
	if (!series->mapfp) {
	    currentfilename = series->filename;
	    series->mapfp = openfileindir(datadir, series->filename, "r");
	    if (!series->mapfp)
		return fileerr(NULL);
	    if (!readseriesheader(series))
		return fileerr("file contains no maps");
	    if (*savedir) {
		series->answerfp = openfileindir(savedir, 
						 series->filename, "r");
		if (series->answerfp) {
		    savedirchecked = TRUE;
		    series->answersreadonly = TRUE;
		}
	    } else
		series->answerfp = NULL;
	}
	while (!series->allmapsread && series->count <= level) {
	    while (series->count >= series->allocated) {
		n = series->allocated ? series->allocated * 2 : 16;
		if (!(series->games = realloc(series->games,
					      n * sizeof *series->games)))
		    memerrexit();
		memset(series->games + series->allocated, 0,
		       (n - series->allocated) * sizeof *series->games);
		series->allocated = n;
	    }
	    if (readlevelmap(series->mapfp, series->games + series->count)) {
		series->games[series->count].seriesname = series->name;
		if (!series->allanswersread)
		    readanswers(series->answerfp,
				series->games + series->count);
		++series->count;
	    }
	    if (feof(series->mapfp)) {
		fclose(series->mapfp);
		series->mapfp = NULL;
		series->allmapsread = TRUE;
	    }
	    if (series->answerfp && feof(series->answerfp))
		series->allanswersread = TRUE;
	}
    }
    return series->count > level;
}
예제 #3
0
파일: fileread.c 프로젝트: BR903/cgames
/* Add data not explicitly defined in the file's representation.
 * Neighboring WALL cells are "joined" so that they can be drawn in
 * outline, and every cell that is "inside" is given a FLOOR. Finally,
 * invisible WALLs are added around the outer edge (so as to insure
 * that the player is not allowed to leave the map and go walking
 * through the heap).
 */
static int improvemap(gamesetup *game)
{
    cell       *map;
    yx		initpos;
    int 	y, x;

    initpos = 0;
    map = game->map;
    for (y = 0 ; y < game->ysize ; ++y, map += XSIZE) {
	for (x = 0 ; x < game->xsize ; ++x) {
	    if (map[x] & WALL)
		continue;
	    map[x] |= FLOOR;
	    if (map[x] & PLAYER) {
		if (initpos)
		    return fileerr("multiple players in map");
		initpos = &map[x] - game->map;
	    }
	}
    }
    if (!initpos)
	return fileerr("no player in map");

    pullflooring(game->map, 0);

    map = game->map;
    for (y = 1, map += XSIZE ; y < game->ysize - 1 ; ++y, map += XSIZE) {
	for (x = 1 ; x < game->xsize - 1 ; ++x) {
	    if (!(map[x] & WALL))
		continue;
	    if (map[x + XSIZE] & WALL)
		map[x + XSIZE] |= EXTENDNORTH;
	    if (map[x - XSIZE] & WALL)
		map[x - XSIZE] |= EXTENDSOUTH;
	    if (map[x + 1] & WALL)
		map[x + 1] |= EXTENDWEST;
	    if (map[x - 1] & WALL)
		map[x - 1] |= EXTENDEAST;
	}
    }

    map = game->map;
    memset(map, WALL, game->xsize);
    for (y = 1, map += XSIZE ; y < game->ysize - 1 ; ++y, map += XSIZE)
	map[0] = map[game->xsize - 1] = WALL;
    memset(map, WALL, game->xsize);

    return TRUE;
}
예제 #4
0
파일: readpnm.c 프로젝트: he110world/junk
static int readppmascrow(fileinfo *file, imageinfo *image)
{
    uchar      *rline, *gline, *bline;
    int		r, g, b;
    int		y, x;

    y = image->height - image->ypos;
    if (y <= 0)
	return 0;
    if (y > squaresize)
	y = squaresize;
    rline = image->buf[0];
    gline = image->buf[1];
    bline = image->buf[2];
    while (y--) {
	for (x = 0 ; x < image->width ; ++x) {
	    if (fscanf(file->fp, "%d %d %d", &r, &g, &b) < 3) {
		fileerr(file);
		return -1;
	    }
	    rline[x] = r;
	    gline[x] = g;
	    bline[x] = b;
	}
	rline += image->width;
	gline += image->width;
	bline += image->width;
    }
    return 1;
}
예제 #5
0
파일: readpnm.c 프로젝트: he110world/junk
static int readppmrawrow(fileinfo *file, imageinfo *image)
{
    uchar      *rline, *gline, *bline;
    int		r, g, b;
    int		y, x;

    y = image->height - image->ypos;
    if (y <= 0)
	return 0;
    if (y > squaresize)
	y = squaresize;
    rline = image->buf[0];
    gline = image->buf[1];
    bline = image->buf[2];
    while (y--) {
	for (x = 0 ; x < image->width ; ++x) {
	    if ((r = fgetc(file->fp)) == EOF || (g = fgetc(file->fp)) == EOF
					     || (b = fgetc(file->fp)) == EOF) {
		fileerr(file);
		return -1;
	    }
	    rline[x] = r;
	    gline[x] = g;
	    bline[x] = b;
	}
	rline += image->width;
	gline += image->width;
	bline += image->width;
    }
    return 1;
}
예제 #6
0
파일: readpnm.c 프로젝트: he110world/junk
static int readpgmrawrow(fileinfo *file, imageinfo *image)
{
    int	y;

    y = image->height - image->ypos;
    if (y <= 0)
	return 0;
    if (y > squaresize)
	y = squaresize;
    if ((int)fread(image->buf[0], image->width, y, file->fp) != y) {
	fileerr(file);
	return -1;
    }
    return 1;
}
예제 #7
0
파일: readpnm.c 프로젝트: he110world/junk
static int readpgmascrow(fileinfo *file, imageinfo *image)
{
    uchar      *line;
    int		pixel;
    int		y, x;

    y = image->height - image->ypos;
    if (y <= 0)
	return 0;
    if (y > squaresize)
	y = squaresize;
    for (line = image->buf[0] ; y ; --y, line += image->width) {
	for (x = 0 ; x < image->width ; ++x) {
	    if (fscanf(file->fp, "%d", &pixel) < 1) {
		fileerr(file);
		return -1;
	    }
	    line[x] = pixel;
	}
    }
    return 1;
}
예제 #8
0
파일: readpnm.c 프로젝트: he110world/junk
static int readpbmrawrow(fileinfo *file, imageinfo *image)
{
    uchar      *line;
    int		byte;
    int		y, x, w;

    y = image->height - image->ypos;
    if (y <= 0)
	return 0;
    if (y > squaresize)
	y = squaresize;
    for (line = image->buf[0] ; y ; --y, line += image->width) {
	for (x = 0 ; x < image->width ; x += 8) {
	    if ((byte = fgetc(file->fp)) == EOF) {
		fileerr(file);
		return -1;
	    }
	    byte ^= 255;
	    for (w = 0 ; w < 8 && x + w < image->width ; ++w, byte <<= 1)
		line[x + w] = byte & 128 ? 1 : 0;
	}
    }
    return 1;
}
예제 #9
0
파일: fileread.c 프로젝트: BR903/cgames
/* Read a single map from the current position of fp and use it to
 * initialize the given gamesetup structure. Maps in the file are
 * separated by blank lines and/or lines beginning with a semicolon,
 * equal sign, or single quote. A semicolon appearing inside a line
 * in a map causes the remainder of the line to be ignored.
 */
static int readlevelmap(FILE *fp, gamesetup *game)
{
    char	buf[256];
    char       *p, *q;
    int		badmap = FALSE;
    int		y, x, n, ch;

    game->name[0] = '\0';
    memset(game->map, EMPTY, sizeof game->map);
    game->xsize = 1;

    for (y = 1 ; y < MAXHEIGHT ; ++y) {
	ch = fgetc(fp);
	if (ch == EOF) {
	    if (y > 1)
		break;
	    else
		return FALSE;
	} else if (ch == '\n' || ch == ';' || ch == '=' || ch == '\'') {
	    if (y > 1) {
		ungetc(ch, fp);
		break;
	    }
	    --y;
	    if (ch == '\n')
		continue;
	    n = getnline(fp, buf, sizeof buf);
	    if (n < 0)
		return FALSE;
	    if (ch == ';' && *buf == ';') {
		for (x = 1 ; isspace(buf[x]) ; ++x) ;
		n -= x;
		if (n >= (int)(sizeof game->name))
		    n = sizeof game->name - 1;
		memcpy(game->name, buf + x, n);
		for (--n ; isspace(game->name[n]) ; --n) ;
		game->name[n + 1] = '\0';
	    }
	    continue;
	}
	buf[0] = ch;
	getnline(fp, buf + 1, sizeof buf - 1);
	if (badmap)
	    continue;
	x = 1;
	p = buf;
	for ( ; x < MAXWIDTH && *p && *p != '\n' && *p != ';' ; ++x, ++p) {
	    if (*p == '\t') {
		x |= 7;
		continue;
	    }
	    if (!(q = strchr(filecells, *p))) {
		fileerr("unrecognized character in level");
		badmap = TRUE;
		break;
	    }
	    game->map[y * XSIZE + x] = q - filecells;
	}
	if (game->xsize <= x) {
	    game->xsize = x + 1;
	    if (game->xsize > MAXWIDTH)
		break;
	}
    }

    game->ysize = y + 1;
    if (game->ysize > MAXHEIGHT || game->xsize > MAXWIDTH)
	return fileerr("ignoring map which exceeds maximum dimensions");

    if (!improvemap(game))
	return FALSE;

    game->boxcount = 0;
    game->goalcount = 0;
    game->storecount = 0;
    for (n = 0 ; n < game->ysize * XSIZE ; ++n) {
	if (game->map[n] & PLAYER)
	    game->start = n;
	else if (game->map[n] & BOX) {
	    ++game->boxcount;
	    if (game->map[n] & GOAL)
		++game->storecount;
	}
	if (game->map[n] & GOAL)
	    ++game->goalcount;
    }

    return TRUE;
}