/* parse the configuration file and prepare the data arrays needed by the rest of vultures * This function is the only one that should be called from outside */ void vultures_parse_tileconf(FILE *fp, struct gametiles **gt_ptr) { int i, j, tilenum, loadnum; int typeoffset[NUM_TILETYPES]; vultures_tile *tile; char messagebuf[512]; struct gametiles * gametiles; /* init the names for all types of tiles */ init_typenames(); init_floortilenames(); init_wallstylenames(); init_miscnames(); init_curnames(); init_objnames(); /* init TT_OBJECT and TT_OBJICON */ init_monnames(); /* init TT_MONSTER, TT_STATUE and TT_FIGURINE */ init_explnames();/* TT_EXPL */ vultures_typecount[TT_MISC] = MISCTILECOUNT; tilenames[TT_MISC] = (char**)miscnames; vultures_typecount[TT_CURSOR] = V_CURSOR_MAX; tilenames[TT_CURSOR] = (char**)cursornames; vultures_typecount[TT_WALL] = 0; tilenames[TT_WALL] = (char **)malloc(0); vultures_typecount[TT_FLOOR] = 0; tilenames[TT_FLOOR] = (char **)malloc(0); vultures_typecount[TT_EDGE] = 0; tilenames[TT_EDGE] = (char **)malloc(0); for (i = 0; i < NUM_TILETYPES; i++) { tmp_gametiles[i] = (tmp_tile *)malloc(vultures_typecount[i] * sizeof(tmp_tile)); memset(tmp_gametiles[i], 0, vultures_typecount[i] * sizeof(tmp_tile)); } /* tell the lexer about the input file and start the parser */ yyrestart(fp); yyparse(); /* the config has now been read and we know how many tiles of each type * there are, so offsets into the final tile array can be computed */ typeoffset[0] = 0; for (i = 1; i < NUM_TILETYPES; i++) typeoffset[i] = typeoffset[i-1] + vultures_typecount[i-1]; *gt_ptr = (struct gametiles *)malloc(GAMETILECOUNT * sizeof(struct gametiles)); gametiles = *gt_ptr; memset(gametiles, 0, GAMETILECOUNT * sizeof(struct gametiles)); /* build gametiles from the info in tmp_gametiles */ for (i = 0; i < NUM_TILETYPES; i++) { for (j = 0; j < vultures_typecount[i]; j++) { tilenum = typeoffset[i] + j; /* use given tile */ if (tmp_gametiles[i][j].filename && tmp_gametiles[i][j].ptr_type == -1 && tmp_gametiles[i][j].ptr_num == -1) { gametiles[tilenum].filename = strdup(tmp_gametiles[i][j].filename); gametiles[tilenum].ptr = -1; gametiles[tilenum].hs_x = tmp_gametiles[i][j].hs_x; gametiles[tilenum].hs_y = tmp_gametiles[i][j].hs_y; } /* redirect to another tile */ else if (tmp_gametiles[i][j].ptr_type != 0 || tmp_gametiles[i][j].ptr_num != 0) { gametiles[tilenum].filename = NULL; gametiles[tilenum].ptr = typeoffset[tmp_gametiles[i][j].ptr_type] + tmp_gametiles[i][j].ptr_num; gametiles[tilenum].hs_x = 0; gametiles[tilenum].hs_y = 0; } /* use default tile */ else if (!tmp_gametiles[i][j].filename && tmp_gametiles[i][j].ptr_type == 0 && tmp_gametiles[i][j].ptr_num == 0) { gametiles[tilenum].ptr = typeoffset[deftiles[i].ptr_type] + deftiles[i].ptr_num; gametiles[tilenum].hs_x = deftiles[i].hs_x; gametiles[tilenum].hs_y = deftiles[i].hs_y; } } } if (vultures_opts.debug) { /* validate all the tiles. this must be done in a separate loop as there may be * forward references which won't work until gametiles is fully initialized */ for (i = 0; i < NUM_TILETYPES; i++) { for (j = 0; j < vultures_typecount[i]; j++) { tilenum = typeoffset[i] + j; loadnum = tilenum; if (!gametiles[tilenum].filename && gametiles[tilenum].ptr != -1) loadnum = gametiles[tilenum].ptr; tile = vultures_load_tile(loadnum); if (!tile) { if (gametiles[tilenum].filename) snprintf(messagebuf, sizeof(messagebuf), "%s.%s: \"%s\" cannot be loaded", typenames[i], tilenames[i][j], gametiles[tilenum].filename); else snprintf(messagebuf, sizeof(messagebuf), "%s.%s: invalid redirection", typenames[i], tilenames[i][j]); if (iflags.window_inited == TRUE) pline(messagebuf); else printf("Tile config: %s\n", messagebuf); vultures_write_log(V_LOG_NOTE, __FILE__, __LINE__, "Tile config: %s\n", messagebuf); } else { SDL_FreeSurface(tile->graphic); free(tile); } } } } /* special fixup for V_MISC_PLAYER_INVIS: it does not have a tile image, * nor should it redirect as it is handled specially */ gametiles[V_MISC_PLAYER_INVIS].ptr = -1; /* free tilenames etc */ for (i = 0; i < NUM_TILETYPES; i++) { for (j = 0; j < vultures_typecount[i]; j++) { if (i != TT_MISC && i != TT_CURSOR) { if (tilenames[i][j]) free(tilenames[i][j]); tilenames[i][j] = NULL; } if (tmp_gametiles[i][j].filename) free(tmp_gametiles[i][j].filename); tmp_gametiles[i][j].filename = NULL; } free(tmp_gametiles[i]); } free(tilenames[TT_OBJECT]); free(tilenames[TT_MONSTER]); free(tilenames[TT_EXPL]); free(tilenames[TT_WALL]); free(tilenames[TT_FLOOR]); free(tilenames[TT_EDGE]); /* build wall arrays */ for (i = 0; i < V_WALL_STYLE_MAX; i++) { walls_full[i].west = tmp_wallstyles[i][0] + typeoffset[TT_WALL]; walls_full[i].north = tmp_wallstyles[i][1] + typeoffset[TT_WALL]; walls_full[i].south = tmp_wallstyles[i][2] + typeoffset[TT_WALL]; walls_full[i].east = tmp_wallstyles[i][3] + typeoffset[TT_WALL]; walls_half[i].west = tmp_wallstyles[i][4] + typeoffset[TT_WALL]; walls_half[i].north = tmp_wallstyles[i][5] + typeoffset[TT_WALL]; walls_half[i].south = tmp_wallstyles[i][6] + typeoffset[TT_WALL]; walls_half[i].east = tmp_wallstyles[i][7] + typeoffset[TT_WALL]; } for (i = 0; i < V_FLOOR_EDGE_MAX; i++) for (j = 0; j < 12; j++) flooredges[i].dir[j] = tmp_flooredges[i][j] + typeoffset[TT_EDGE]; for (i = 0; i < V_FLOOR_STYLE_MAX; i++) for (j = 0; j < (floorstyles[i].x * floorstyles[i].y); j++) floorstyles[i].array[j] = floorstyles[i].array[j] + typeoffset[TT_FLOOR]; }
static void vultures_sdl_error(char *file, int line, const char *what) { vultures_write_log(V_LOG_ERROR, file, line, "%s: %s\n", what, SDL_GetError()); }