/* 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];
}
示例#2
0
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());
}