struct theme_background_system *theme_background_system_read(struct section_file *file) { int i; struct theme_background_system *backgrounds = fc_malloc(sizeof(*backgrounds)); fc_assert_ret_val(ARRAY_SIZE(background_names) == BACKGROUND_LAST, NULL); for (i = 0; i < BACKGROUND_LAST; i++) { backgrounds->backgrounds[i] = themespec_gfx_filename(secfile_lookup_str(file, "backgrounds.%s", background_names[i])); } return backgrounds; }
/************************************************************************** INTERNAL. Returns TRUE for success. **************************************************************************/ static bool audio_play_tag(const char *tag, bool repeat) { const char *soundfile; const char *fullpath = NULL; if (!tag || strcmp(tag, "-") == 0) { return FALSE; } if (tagfile) { soundfile = secfile_lookup_str(tagfile, "files.%s", tag); if (NULL == soundfile) { log_verbose("No sound file for tag %s (file %s)", tag, soundfile); } else { fullpath = fileinfoname(get_data_dirs(), soundfile); if (!fullpath) { log_error("Cannot find audio file %s", soundfile); } } } return plugins[selected_plugin].play(tag, fullpath, repeat); }
/************************************************************************** Initialize audio system and autoselect a plugin **************************************************************************/ void audio_real_init(const char *const spec_name, const char *const prefered_plugin_name) { const char *filename; char *file_capstr; char us_capstr[] = "+soundspec"; if (strcmp(prefered_plugin_name, "none") == 0) { /* We explicitly choose none plugin, silently skip the code below */ freelog(LOG_VERBOSE, "Proceeding with sound support disabled."); tagfile = NULL; return; } if (num_plugins_used == 1) { /* We only have the dummy plugin, skip the code but issue an advertise */ freelog(LOG_NORMAL, _("No real audio plugin present.")); freelog(LOG_NORMAL, _("Proceeding with sound support disabled.")); freelog(LOG_NORMAL, _("For sound support, install SDL_mixer")); freelog(LOG_NORMAL, "http://www.libsdl.org/projects/SDL_mixer/index.html"); tagfile = NULL; return; } if (!spec_name) { freelog(LOG_FATAL, "No sound spec-file given!"); exit(EXIT_FAILURE); } freelog(LOG_VERBOSE, "Initializing sound using %s...", spec_name); filename = soundspec_fullname(spec_name); if (!filename) { freelog(LOG_ERROR, "Cannot find sound spec-file \"%s\".", spec_name); freelog(LOG_NORMAL, _("To get sound you need to download a sound set!")); freelog(LOG_NORMAL, _("Get sound sets from <%s>."), "ftp://ftp.freeciv.org/freeciv/contrib/audio/soundsets"); freelog(LOG_NORMAL, _("Proceeding with sound support disabled.")); tagfile = NULL; return; } if (!section_file_load(tagfile, filename)) { freelog(LOG_FATAL, _("Could not load sound spec-file: %s"), filename); exit(EXIT_FAILURE); } file_capstr = secfile_lookup_str(tagfile, "soundspec.options"); if (!has_capabilities(us_capstr, file_capstr)) { freelog(LOG_FATAL, "sound spec-file appears incompatible:"); freelog(LOG_FATAL, " file: \"%s\"", filename); freelog(LOG_FATAL, " file options: %s", file_capstr); freelog(LOG_FATAL, " supported options: %s", us_capstr); exit(EXIT_FAILURE); } if (!has_capabilities(file_capstr, us_capstr)) { freelog(LOG_FATAL, "sound spec-file claims required option(s)" " which we don't support:"); freelog(LOG_FATAL, " file: \"%s\"", filename); freelog(LOG_FATAL, " file options: %s", file_capstr); freelog(LOG_FATAL, " supported options: %s", us_capstr); exit(EXIT_FAILURE); } free((void *) filename); atexit(audio_shutdown); if (prefered_plugin_name[0] != '\0') { if (!audio_select_plugin(prefered_plugin_name)) freelog(LOG_NORMAL, _("Proceeding with sound support disabled.")); return; } #ifdef AUDIO_SDL if (audio_select_plugin("sdl")) return; #endif freelog(LOG_NORMAL, _("No real audio subsystem managed to initialize!")); freelog(LOG_NORMAL, _("Perhaps there is some misconfiguration or bad permissions.")); freelog(LOG_NORMAL, _("Proceeding with sound support disabled.")); }
/**************************************************************************** Called when the client first starts to allocate the default colors. Currently this must be called in ui_main, generally after UI initialization. ****************************************************************************/ struct color_system *color_system_read(struct section_file *file) { int i; struct color_system *colors = fc_malloc(sizeof(*colors)); fc_assert_ret_val(ARRAY_SIZE(color_names) == COLOR_LAST, NULL); for (i = 0; i < COLOR_LAST; i++) { if (!secfile_lookup_int(file, &colors->colors[i].r, "colors.%s0.r", color_names[i]) || !secfile_lookup_int(file, &colors->colors[i].g, "colors.%s0.g", color_names[i]) || !secfile_lookup_int(file, &colors->colors[i].b, "colors.%s0.b", color_names[i])) { log_error("Color %s: %s", color_names[i], secfile_error()); colors->colors[i].r = 0; colors->colors[i].g = 0; colors->colors[i].b = 0; } colors->colors[i].color = NULL; } for (i = 0; i < player_slot_count(); i++) { if (NULL == secfile_entry_lookup(file, "colors.player%d.r", i)) { break; } } colors->num_player_colors = MAX(i, 1); colors->player_colors = fc_malloc(colors->num_player_colors * sizeof(*colors->player_colors)); if (i == 0) { /* Use a simple fallback. */ log_error("Missing colors.player. See misc/colors.tilespec."); colors->player_colors[0].r = 128; colors->player_colors[0].g = 0; colors->player_colors[0].b = 0; colors->player_colors[0].color = NULL; } else { for (i = 0; i < colors->num_player_colors; i++) { struct rgbcolor *rgb = &colors->player_colors[i]; if (!secfile_lookup_int(file, &rgb->r, "colors.player%d.r", i) || !secfile_lookup_int(file, &rgb->g, "colors.player%d.g", i) || !secfile_lookup_int(file, &rgb->b, "colors.player%d.b", i)) { log_error("Player color %d: %s", i, secfile_error()); rgb->r = 0; rgb->g = 0; rgb->b = 0; } rgb->color = NULL; } } for (i = 0; i < ARRAY_SIZE(colors->terrain_colors); i++) { struct rgbcolor *rgb = &colors->terrain_colors[i]; rgb->r = rgb->g = rgb->b = 0; rgb->color = NULL; } colors->terrain_hash = terrain_color_hash_new(); for (i = 0; ; i++) { struct rgbcolor rgb; const char *key; if (!secfile_lookup_int(file, &rgb.r, "colors.tiles%d.r", i) || !secfile_lookup_int(file, &rgb.g, "colors.tiles%d.g", i) || !secfile_lookup_int(file, &rgb.b, "colors.tiles%d.b", i)) { break; } rgb.color = NULL; key = secfile_lookup_str(file, "colors.tiles%d.tag", i); if (NULL == key) { log_error("warning: tag for tiles %d: %s", i, secfile_error()); } else if (!terrain_color_hash_insert(colors->terrain_hash, key, &rgb)) { log_error("warning: already have a color for %s", key); } } return colors; }
/********************************************************************** Finds and reads the toplevel themespec file based on given name. Sets global variables, including tile sizes and full names for intro files. ***********************************************************************/ struct theme *theme_read_toplevel(const char *theme_name) { struct section_file *file; char *fname; int i; size_t num_spec_files; const char **spec_filenames; const char *file_capstr; bool duplicates_ok; struct theme *t = theme_new(); const char *langname; const char *filename, *c; fname = themespec_fullname(theme_name); if (!fname) { log_error("Can't find theme \"%s\".", theme_name); theme_free(t); return NULL; } log_verbose("themespec file is \"%s\".", fname); if (!(file = secfile_load(fname, TRUE))) { log_error("Could not open '%s':\n%s", fname, secfile_error()); FC_FREE(fname); theme_free(t); return NULL; } if (!check_themespec_capabilities(file, "themespec", THEMESPEC_CAPSTR, fname)) { secfile_destroy(file); FC_FREE(fname); theme_free(t); return NULL; } file_capstr = secfile_lookup_str(file, "themespec.options"); duplicates_ok = has_capabilities("+duplicates_ok", file_capstr); (void) secfile_entry_by_path(file, "themespec.name"); /* currently unused */ sz_strlcpy(t->name, theme_name); t->priority = secfile_lookup_int_default(file, 0, "themespec.priority"); langname = get_langname(); if (langname) { if (strstr(langname, "zh_CN") != NULL) { c = secfile_lookup_str(file, "themespec.font_file_zh_CN"); } else if (strstr(langname, "ja") != NULL) { c = secfile_lookup_str(file, "themespec.font_file_ja"); } else if (strstr(langname, "ko") != NULL) { c = secfile_lookup_str(file, "themespec.font_file_ko"); } else { c = secfile_lookup_str(file, "themespec.font_file"); } } else { c = secfile_lookup_str(file, "themespec.font_file"); } if ((filename = fileinfoname(get_data_dirs(), c))) { t->font_filename = fc_strdup(filename); } else { log_fatal("Could not open font: %s", c); secfile_destroy(file); FC_FREE(fname); theme_free(t); return NULL; } log_debug("theme font file %s", t->font_filename); t->default_font_size = secfile_lookup_int_default(file, 10, "themespec.default_font_size"); log_debug("theme default font size %d", t->default_font_size); spec_filenames = secfile_lookup_str_vec(file, &num_spec_files, "themespec.files"); if (NULL == spec_filenames || 0 == num_spec_files) { log_error("No theme graphics files specified in \"%s\"", fname); secfile_destroy(file); FC_FREE(fname); theme_free(t); return NULL; } fc_assert(t->sprite_hash == NULL); t->sprite_hash = small_sprite_hash_new(); for (i = 0; i < num_spec_files; i++) { struct specfile *sf = fc_malloc(sizeof(*sf)); log_debug("spec file %s", spec_filenames[i]); sf->big_sprite = NULL; filename = fileinfoname(get_data_dirs(), spec_filenames[i]); if (!filename) { log_error("Can't find spec file \"%s\".", spec_filenames[i]); secfile_destroy(file); FC_FREE(fname); theme_free(t); return NULL; } sf->file_name = fc_strdup(filename); scan_specfile(t, sf, duplicates_ok); specfile_list_prepend(t->specfiles, sf); } FC_FREE(spec_filenames); t->background_system = theme_background_system_read(file); t->color_system = theme_color_system_read(file); secfile_check_unused(file); secfile_destroy(file); log_verbose("finished reading \"%s\".", fname); FC_FREE(fname); return t; }