50#define THEMESPEC_SDL2_CAPSTR "+Freeciv-2.6-sdl2-themespec duplicates_ok"
62#define SPEC_SDL2_CAPSTR "+Freeciv-3.1-sdl2-spec"
69#define THEMESPEC_SUFFIX ".themespec"
83#define SPECLIST_TAG specfile
84#define SPECLIST_TYPE struct specfile
87#define specfile_list_iterate(list, pitem) \
88 TYPED_LIST_ITERATE(struct specfile, list, pitem)
89#define specfile_list_iterate_end LIST_ITERATE_END
112#define SPECLIST_TAG small_sprite
113#define SPECLIST_TYPE struct small_sprite
116#define small_sprite_list_iterate(list, pitem) \
117 TYPED_LIST_ITERATE(struct small_sprite, list, pitem)
118#define small_sprite_list_iterate_end LIST_ITERATE_END
120#define SPECHASH_TAG small_sprite
121#define SPECHASH_IKEY_TYPE char *
122#define SPECHASH_IDATA_TYPE struct small_sprite *
123#define SPECHASH_IKEY_VAL genhash_str_val_func
124#define SPECHASH_IKEY_COMP genhash_str_comp_func
125#define SPECHASH_IKEY_COPY genhash_str_copy_func
126#define SPECHASH_IKEY_FREE genhash_str_free_func
128#define small_sprite_hash_iterate(hash, tag_name, pitem) \
129 TYPED_HASH_ITERATE(const char *, struct small_sprite *, hash, \
131#define small_sprite_hash_iterate_end HASH_ITERATE_END
202 static const char **themes = NULL;
219 themes[count] = NULL;
258 const char *us_capstr,
259 const char *filename)
263 if (NULL == file_capstr) {
264 log_debug(
"\"%s\": %s file doesn't have capability string",
270 log_debug(
"\"%s\": %s file appears incompatible:", filename, which);
271 log_debug(
" datafile options: %s", file_capstr);
272 log_debug(
" supported options: %s", us_capstr);
278 log_debug(
"\"%s\": %s file requires option(s)"
279 " that client doesn't support:", filename, which);
280 log_debug(
" datafile options: %s", file_capstr);
281 log_debug(
" supported options: %s", us_capstr);
318 if (ftheme != NULL) {
321 specfile_list_destroy(ftheme->
specfiles);
352 log_fatal(
_(
"No usable default theme found, aborting!"));
383 log_normal(
_(
"Loading theme \"%s\"."), theme_name);
406 "Failed to re-read the currently loaded theme.");
457 while ((gfx_fileext = *gfx_fileexts++)) {
458 const char *real_full_name;
459 char full_name[strlen(gfx_filename) + strlen(
".")
460 + strlen(gfx_fileext) + 1];
462 sprintf(full_name,
"%s.%s", gfx_filename, gfx_fileext);
464 log_debug(
"trying to load gfx file \"%s\".", real_full_name);
472 log_error(
"Could not load gfx file \"%s\".", gfx_filename);
483 const char *gfx_filename;
508 log_fatal(
"Could not load gfx file for the spec file \"%s\".",
529 struct section_list *sections;
549 if (NULL != sections) {
552 int x_top_left, y_top_left, dx, dy;
561 "%s.y_top_left", gridname)
580 "%s.tiles%d.column", gridname, j)
584 log_error(
"Small sprite \"%s.tiles%d\" invalid: %s",
596 x1 = x_top_left + (dx + pixel_border) * column;
597 y1 = y_top_left + (dy + pixel_border) * row;
613 if (!duplicates_ok) {
614 for (k = 0; k < num_tags; k++) {
615 if (!small_sprite_hash_insert(t->
sprite_hash, tags[k], ss)) {
616 log_error(
"warning: already have a sprite for \"%s\".",
621 for (k = 0; k < num_tags; k++) {
622 (void) small_sprite_hash_replace(t->
sprite_hash, tags[k], ss);
629 section_list_destroy(sections);
637 const char *filename;
642 "extra.sprites%d.tag", i))
644 "extra.sprites%d.file", i))) {
645 log_error(
"Small sprite \"extra.sprites%d\" invalid: %s",
663 if (!duplicates_ok) {
664 for (k = 0; k < num_tags; k++) {
665 if (!small_sprite_hash_insert(t->
sprite_hash, tags[k], ss)) {
666 log_error(
"warning: already have a sprite for \"%s\".", tags[k]);
670 for (k = 0; k < num_tags; k++) {
671 (void) small_sprite_hash_replace(t->
sprite_hash, tags[k], ss);
687 const char *gfx_current_fileext;
690 while ((gfx_current_fileext = *gfx_fileexts++)) {
691 const char *real_full_name;
693 fc_malloc(strlen(gfx_filename) + strlen(
".")
694 + strlen(gfx_current_fileext) + 1);
696 sprintf(full_name,
"%s.%s", gfx_filename, gfx_current_fileext);
699 if (real_full_name) {
704 log_fatal(
"Couldn't find a supported gfx file extension for \"%s\".",
721 size_t num_spec_files;
722 const char **spec_filenames;
723 const char *file_capstr;
726 const char *langname;
727 const char *filename, *c;
731 log_error(
"Can't find theme \"%s\".", theme_name);
766 if (langname != NULL && strstr(langname,
"zh_CN") != NULL) {
772 if (c == NULL && langname != NULL && strstr(langname,
"ja") != NULL) {
778 if (c == NULL && langname != NULL && strstr(langname,
"ko") != NULL) {
807 if (NULL == spec_filenames || 0 == num_spec_files) {
808 log_error(
"No theme graphics files specified in \"%s\"", fname);
818 for (i = 0; i < num_spec_files; i++) {
821 log_debug(
"spec file %s", spec_filenames[i]);
826 log_error(
"Can't find spec file \"%s\".", spec_filenames[i]);
875 log_fatal(
"Couldn't load gfx file \"%s\" for sprite '%s'.",
884 if (ss->
x < 0 || ss->
x + ss->
width > sf_w
885 || ss->
y < 0 || ss->
y + ss->
height > sf_h) {
886 log_error(
"Sprite '%s' in file \"%s\" isn't within the image!",
892 NULL, -1, -1, 1.0,
FALSE);
927#define SET_SPRITE(field, tag) \
929 t->sprites.field = theme_load_sprite(t, tag); \
930 fc_assert_exit_msg(NULL != t->sprites.field, \
931 "Sprite tag '%s' missing.", tag); \
935#define SET_SPRITE_ALT(field, tag, alt) \
937 t->sprites.field = theme_load_sprite(t, tag); \
938 if (!t->sprites.field) { \
939 t->sprites.field = theme_load_sprite(t, alt); \
941 fc_assert_exit_msg(NULL != t->sprites.field, \
942 "Sprite tag '%s' and alternate '%s' are " \
943 "both missing.", tag, alt); \
947#define SET_SPRITE_OPT(field, tag) \
948 t->sprites.field = theme_load_sprite(t, tag)
950#define SET_SPRITE_ALT_OPT(field, tag, alt) \
952 t->sprites.field = theme_lookup_sprite_tag_alt(t, LOG_VERBOSE, tag, alt,\
1004 const char *tag,
const char *alt,
1012 "attempt to lookup for %s \"%s\" before "
1013 "sprite_hash setup", what,
name);
1022 log_verbose(
"Using alternate graphic \"%s\" (instead of \"%s\") "
1023 "for %s \"%s\".", alt, tag, what,
name);
1027 log_base(
level,
"Don't have graphics tags \"%s\" or \"%s\" for %s \"%s\".",
1028 tag, alt, what,
name);
1036#define FULL_TILE_X_OFFSET ((t->normal_tile_width - t->full_tile_width) / 2)
1037#define FULL_TILE_Y_OFFSET (t->normal_tile_height - t->full_tile_height)
1039#define ADD_SPRITE(s, draw_fog, x_offset, y_offset) \
1040 (fc_assert(s != NULL), \
1042 sprs->foggable = (draw_fog && t->fogstyle == FOG_AUTO), \
1043 sprs->offset_x = x_offset, \
1044 sprs->offset_y = y_offset, \
1046#define ADD_SPRITE_SIMPLE(s) ADD_SPRITE(s, TRUE, 0, 0)
1047#define ADD_SPRITE_FULL(s) \
1048 ADD_SPRITE(s, TRUE, FULL_TILE_X_OFFSET, FULL_TILE_Y_OFFSET)
1057 while (ss->ref_count > 0) {
1090 if (sf->big_sprite) {
1092 sf->big_sprite = NULL;
1102 sprite_vector_free(&t->sprites.****);
struct canvas int int struct sprite * psprite
bool has_capabilities(const char *us, const char *them)
void generate_citydlg_dimensions(void)
enum client_states client_state(void)
static struct fc_sockaddr_list * list
void popdown_all_game_dialogs(void)
void get_sprite_dimensions(struct sprite *sprite, int *width, int *height)
void free_sprite(struct sprite *s)
struct sprite * load_gfxfile(const char *filename)
struct sprite * crop_sprite(struct sprite *source, int x, int y, int width, int height, struct sprite *mask, int mask_offset_x, int mask_offset_y, float scale, bool smooth)
const char ** gfx_fileextensions(void)
void tilespec_setup_city_gfx(void)
void tilespec_free_city_icons(void)
void tilespec_setup_theme(void)
void tilespec_free_city_gfx(void)
void tilespec_setup_city_icons(void)
void tilespec_free_theme(void)
#define fc_assert_ret(condition)
#define fc_assert_exit_msg(condition, message,...)
#define log_verbose(message,...)
#define fc_assert(condition)
#define fc_assert_ret_val(condition, val)
#define log_fatal(message,...)
#define fc_assert_action(condition, action)
#define log_debug(message,...)
#define log_normal(message,...)
#define log_base(level, message,...)
#define log_error(message,...)
#define fc_assert_ret_val_msg(condition, val, message,...)
void update_map_canvas_visible(void)
struct tile * get_center_tile_mapcanvas(void)
void center_tile_mapcanvas(const struct tile *ptile)
const struct tile * center_tile
#define fc_calloc(n, esz)
struct section_file * secfile_load(const char *filename, bool allow_duplicates)
const char * secfile_error(void)
const char * section_name(const struct section *psection)
void secfile_destroy(struct section_file *secfile)
void secfile_check_unused(const struct section_file *secfile)
bool secfile_lookup_int(const struct section_file *secfile, int *ival, const char *path,...)
struct section_list * secfile_sections_by_name_prefix(const struct section_file *secfile, const char *prefix)
const char ** secfile_lookup_str_vec(const struct section_file *secfile, size_t *dim, const char *path,...)
struct entry * secfile_entry_lookup(const struct section_file *secfile, const char *path,...)
const char * secfile_lookup_str(const struct section_file *secfile, const char *path,...)
int secfile_lookup_int_default(const struct section_file *secfile, int def, const char *path,...)
struct entry * secfile_entry_by_path(const struct section_file *secfile, const char *path)
#define section_list_iterate(seclist, psection)
#define section_list_iterate_end
struct setting_list * level[OLEVELS_NUM]
const char * fileinfoname(const struct strvec *dirs, const char *filename)
struct strvec * fileinfolist(const struct strvec *dirs, const char *suffix)
const char * setup_langname(void)
const struct strvec * get_data_dirs(void)
void strvec_destroy(struct strvec *psv)
size_t strvec_size(const struct strvec *psv)
#define strvec_iterate(psv, str)
#define strvec_iterate_end
struct sprite * big_sprite
struct theme_color_system * color_system
struct theme_background_system * background_system
struct specfile_list * specfiles
struct small_sprite_list * small_sprites
struct small_sprite_hash * sprite_hash
int fc_snprintf(char *str, size_t n, const char *format,...)
#define sz_strlcpy(dest, src)
struct theme_background_system * theme_background_system_read(struct section_file *file)
void theme_background_system_free(struct theme_background_system *backgrounds)
void theme_color_system_free(struct theme_color_system *colors)
struct theme_color_system * theme_color_system_read(struct section_file *file)
static struct sprite * theme_load_sprite(struct theme *t, const char *tag_name)
void theme_free(struct theme *ftheme)
static bool check_themespec_capabilities(struct section_file *file, const char *which, const char *us_capstr, const char *filename)
#define THEMESPEC_SDL2_CAPSTR
static struct sprite * load_gfx_file(const char *gfx_filename)
#define specfile_list_iterate_end
static void theme_unload_sprite(struct theme *t, const char *tag_name)
struct theme_color_system * theme_get_color_system(const struct theme *t)
const char * theme_font_filename(const struct theme *t)
char * themespec_gfx_filename(const char *gfx_filename)
#define specfile_list_iterate(list, pitem)
static void theme_finish_loading_sprites(struct theme *t)
static void theme_ensure_big_sprite(struct specfile *sf)
static void theme_lookup_sprite_tags(struct theme *t)
#define small_sprite_list_iterate_end
#define small_sprite_list_iterate(list, pitem)
static void theme_free_toplevel(struct theme *t)
static void scan_specfile(struct theme *t, struct specfile *sf, bool duplicates_ok)
void theme_free_sprites(struct theme *t)
void theme_load_sprites(struct theme *t)
const char ** get_theme_list(void)
struct theme_background_system * theme_get_background_system(const struct theme *t)
void themespec_try_read(const char *theme_name)
struct sprite * theme_lookup_sprite_tag_alt(struct theme *t, enum log_level level, const char *tag, const char *alt, const char *what, const char *name)
const char * theme_get_name(const struct theme *t)
struct theme * theme_read_toplevel(const char *theme_name)
#define small_sprite_hash_iterate(hash, tag_name, pitem)
int theme_default_font_size(const struct theme *t)
#define small_sprite_hash_iterate_end
void themespec_reread(const char *new_theme_name)
struct theme * active_theme
static char * themespec_fullname(const char *theme_name)
static void theme_unload_all_sprites(struct theme *t)
static struct theme * theme_new(void)
#define sprite_vector_iterate_end
#define sprite_vector_iterate(sprite_vec, psprite)