Freeciv-3.2
Loading...
Searching...
No Matches
tilespec.c
Go to the documentation of this file.
1/***********************************************************************
2 Freeciv - Copyright (C) 1996 - A Kjeldberg, L Gregersen, P Unold
3 This program is free software; you can redistribute it and/or modify
4 it under the terms of the GNU General Public License as published by
5 the Free Software Foundation; either version 2, or (at your option)
6 any later version.
7
8 This program is distributed in the hope that it will be useful,
9 but WITHOUT ANY WARRANTY; without even the implied warranty of
10 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 GNU General Public License for more details.
12***********************************************************************/
13
14/***********************************************************************
15 Functions for handling the tilespec files which describe
16 the files and contents of tilesets.
17 original author: David Pfitzner <dwp@mso.anu.edu.au>
18***********************************************************************/
19
20#ifdef HAVE_CONFIG_H
21#include <fc_config.h>
22#endif
23
24#include <stdio.h>
25#include <stdlib.h> /* exit */
26#include <stdarg.h>
27#include <string.h>
28
29/* utility */
30#include "astring.h"
31#include "bitvector.h"
32#include "capability.h"
33#include "deprecations.h"
34#include "fcintl.h"
35#include "log.h"
36#include "mem.h"
37#include "rand.h"
38#include "registry.h"
39#include "shared.h"
40#include "string_vector.h"
41#include "support.h"
42
43/* common */
44#include "base.h"
45#include "effects.h"
46#include "game.h" /* game.control.num_city_styles */
47#include "government.h"
48#include "map.h"
49#include "movement.h"
50#include "nation.h"
51#include "player.h"
52#include "road.h"
53#include "specialist.h"
54#include "unit.h"
55#include "unitlist.h"
56
57/* client/include */
58#include "dialogs_g.h"
59#include "graphics_g.h"
60#include "gui_main_g.h"
61#include "mapview_g.h" /* For update_map_canvas_visible */
62#include "menu_g.h"
63#include "themes_g.h"
64
65/* client */
66#include "citydlg_common.h" /* For generate_citydlg_dimensions() */
67#include "client_main.h"
68#include "climap.h" /* For client_tile_get_known() */
69#include "colors_common.h"
70#include "control.h" /* For fill_xxx */
71#include "editor.h"
72#include "goto.h"
73#include "helpdata.h"
74#include "options.h" /* For fill_xxx */
75#include "svgflag.h"
76#include "themes_common.h"
77
78#include "tilespec.h"
79
80#define TILESPEC_CAPSTR "+Freeciv-3.2-tilespec duplicates_ok"
81/*
82 * Tilespec capabilities acceptable to this program:
83 *
84 * +Freeciv-3.2-tilespec
85 * - basic format for Freeciv versions 3.2.x; required
86 *
87 * +Freeciv-tilespec-3.2-Devel-YYYY.MMM.DD
88 * - tilespec of the development version at the given date
89 *
90 * duplicates_ok
91 * - we can handle existence of duplicate tags (lattermost tag which
92 * appears is used; tilesets which have duplicates should specify
93 * "duplicates_ok")
94 */
95
96#define SPEC_CAPSTR "+Freeciv-3.2-spec"
97/*
98 * Individual spec file capabilities acceptable to this program:
99 *
100 * +Freeciv-3.2-spec
101 * - basic format for Freeciv versions 3.2.x; required
102 */
103
104#define TILESPEC_SUFFIX ".tilespec"
105#define TILE_SECTION_PREFIX "tile_"
106
107/* This the way directional indices are now encoded: */
108#define MAX_INDEX_CARDINAL 64
109#define MAX_INDEX_HALF 16
110#define MAX_INDEX_VALID 256
111
112#define NUM_TILES_HP_BAR 11
113#define NUM_TILES_DIGITS 10
114#define NUM_TILES_SELECT 4
115#define MAX_NUM_UPKEEP_SPRITES 10
116
117#define SPECENUM_NAME extrastyle_id
118#define SPECENUM_VALUE0 ESTYLE_ROAD_ALL_SEPARATE
119#define SPECENUM_VALUE0NAME "RoadAllSeparate"
120#define SPECENUM_VALUE1 ESTYLE_ROAD_PARITY_COMBINED
121#define SPECENUM_VALUE1NAME "RoadParityCombined"
122#define SPECENUM_VALUE2 ESTYLE_ROAD_ALL_COMBINED
123#define SPECENUM_VALUE2NAME "RoadAllCombined"
124#define SPECENUM_VALUE3 ESTYLE_RIVER
125#define SPECENUM_VALUE3NAME "River"
126#define SPECENUM_VALUE4 ESTYLE_SINGLE1
127#define SPECENUM_VALUE4NAME "Single1"
128#define SPECENUM_VALUE5 ESTYLE_SINGLE2
129#define SPECENUM_VALUE5NAME "Single2"
130#define SPECENUM_VALUE6 ESTYLE_3LAYER
131#define SPECENUM_VALUE6NAME "3Layer"
132#define SPECENUM_VALUE7 ESTYLE_CARDINALS
133#define SPECENUM_VALUE7NAME "Cardinals"
134#define SPECENUM_COUNT ESTYLE_COUNT
135#include "specenum_gen.h"
136
137/* This could be moved to common/map.h if there's more use for it. */
141static const char direction4letters[4] = "udrl";
142/* This must correspond to enum edge_type. */
143static const char edge_name[EDGE_COUNT][3] = {"ns", "we", "ud", "lr"};
144
145static const int DIR4_TO_DIR8[4] =
147
154
156 CELL_WHOLE, /* Entire tile */
157 CELL_CORNER /* Corner of tile */
159
166
168 bool init;
169
170 char *name;
171
172 int num_layers; /* 1 thru MAX_NUM_LAYERS. */
173#define MAX_NUM_LAYERS 3
174
178
179#define MAX_NUM_MATCH_WITH 8
182 int match_indices; /* 0 = no match_type, 1 = no match_with */
183
185
188 struct sprite **cells;
189
190 /* List of those sprites in 'cells' that are allocated by some other
191 * means than load_sprite() and thus are not freed by unload_all_sprites(). */
194
196
197 int blending; /* layer, 0 = none */
199 struct sprite *blend[4]; /* indexed by a direction4 */
200};
201
203 struct sprite *sprite;
204};
205
213
219
221 /* Each citizen type has up to MAX_NUM_CITIZEN_SPRITES different
222 * sprites, as defined by the tileset. */
223 int count;
225};
226
231
236
238 struct sprite
240 *treaty_thumb[2], /* 0=disagree, 1=agree */
241 *arrow[ARROW_LAST], /* 0=right arrow, 1=plus, 2=minus */
242
244
246
247 /* The panel sprites for showing tax % allocations. */
249 *dither_tile; /* Only used for isometric view */
250
251 struct {
252 struct sprite
257
261
262 struct {
263 struct sprite *icon[U_LAST][ACTIVITY_LAST];
266
269
272
274 struct {
275 int hot_x, hot_y;
276 struct sprite *frame[NUM_CURSOR_FRAMES];
278 struct {
280 struct sprite *nuke;
282 struct {
285 struct sprite
287 *vet_lev[MAX_VET_LEVELS],
294 *go_to, /* goto is a C keyword :-) */
305 *battlegroup[MAX_NUM_BATTLEGROUPS],
310 struct {
311 struct sprite
315 struct {
316 struct sprite
319 *size_tens[NUM_TILES_DIGITS],
320 *size_hundreds[NUM_TILES_DIGITS],
321 *tile_foodnum[NUM_TILES_DIGITS],
322 *tile_shieldnum[NUM_TILES_DIGITS],
323 *tile_tradenum[NUM_TILES_DIGITS];
324 struct city_sprite
329 struct sprite_vector worked_tile_overlay;
330 struct sprite_vector unworked_tile_overlay;
334 struct {
335 struct {
337 struct sprite *turns[NUM_TILES_DIGITS];
338 struct sprite *turns_tens[NUM_TILES_DIGITS];
339 struct sprite *turns_hundreds[NUM_TILES_DIGITS];
343 struct {
347 struct {
348 struct sprite
351 *darkness[MAX_INDEX_CARDINAL]; /* First unused */
352 } tx; /* Terrain extra */
353 struct {
354 struct sprite
358 union {
359 struct sprite *single;
360 struct sprite *cardinals[MAX_INDEX_CARDINAL];
361 struct {
362 struct sprite
366 } bmf;
367 struct {
368 struct sprite
369 /* For extrastyles ESTYLE_ROAD_ALL_SEPARATE and ESTYLE_ROAD_PARITY_COMBINED */
371 *corner[8]; /* Indexed by direction; only non-cardinal dirs used. */
372 union {
373 /* For ESTYLE_ROAD_ALL_SEPARATE */
374 struct sprite *dir[8]; /* All entries used */
375 /* ESTYLE_ROAD_PARITY_COMBINED */
376 struct {
377 struct sprite
378 *even[MAX_INDEX_HALF], /* First unused */
379 *odd[MAX_INDEX_HALF]; /* First unused */
380 } combo;
381 /* ESTYLE_ALL_SEPARATE */
382 struct sprite *total[MAX_INDEX_VALID];
383 struct river_sprites rivers;
384 } ru;
386 } u;
388 struct {
389 struct sprite
392 *worked[EDGE_COUNT],
395 *selected[EDGE_COUNT],
396 *coastline[EDGE_COUNT],
397 *borders[EDGE_COUNT][2];
399 struct {
400 struct sprite_vector overlays;
402 struct {
403 struct sprite *color; /* Generic background color */
404 struct sprite *graphic; /* Generic background graphic */
406 struct {
407 struct sprite *grid_borders[EDGE_COUNT][2];
408 struct sprite *color;
409 struct sprite *background;
411
413};
414
415struct specfile {
416 struct sprite *big_sprite;
417 char *file_name;
418};
419
420#define SPECLIST_TAG specfile
421#define SPECLIST_TYPE struct specfile
422#include "speclist.h"
423
424#define specfile_list_iterate(list, pitem) \
425 TYPED_LIST_ITERATE(struct specfile, list, pitem)
426#define specfile_list_iterate_end LIST_ITERATE_END
427
428/*
429 * Information about an individual sprite. All fields except 'sprite' are
430 * filled at the time of the scan of the specfile. 'Sprite' is
431 * set/cleared on demand in load_sprite()/unload_sprite().
432 */
433struct small_sprite {
434 int ref_count;
435
436 /* The sprite is in this file. */
437 char *file;
438
439 /* Or, the sprite is in this file at the location. */
440 struct specfile *sf;
441 int x, y, width, height;
442
443 /* A little more (optional) data. */
444 int hot_x, hot_y;
445
446 struct sprite *sprite;
447};
448
449/* 'struct small_sprite_list' and related functions. */
450#define SPECLIST_TAG small_sprite
451#define SPECLIST_TYPE struct small_sprite
452#include "speclist.h"
453#define small_sprite_list_iterate(list, pitem) \
454 TYPED_LIST_ITERATE(struct small_sprite, list, pitem)
455#define small_sprite_list_iterate_end LIST_ITERATE_END
456
457/* 'struct sprite_hash' and related functions. */
458#define SPECHASH_TAG sprite
459#define SPECHASH_ASTR_KEY_TYPE
460#define SPECHASH_IDATA_TYPE struct small_sprite *
461#include "spechash.h"
462#define sprite_hash_iterate(hash, tag_name, sprite) \
463 TYPED_HASH_ITERATE(const char *, struct small_sprite *, \
464 hash, tag_name, sprite)
465#define sprite_hash_iterate_end HASH_ITERATE_END
466
467/* 'struct drawing_hash' and related functions. */
468static void drawing_data_destroy(struct drawing_data *draw);
469
470#define SPECHASH_TAG drawing
471#define SPECHASH_CSTR_KEY_TYPE
472#define SPECHASH_IDATA_TYPE struct drawing_data *
473#define SPECHASH_IDATA_FREE drawing_data_destroy
474#include "spechash.h"
475
476#define SPECHASH_TAG estyle
477#define SPECHASH_ASTR_KEY_TYPE
478#define SPECHASH_ENUM_DATA_TYPE extrastyle_id
479#include "spechash.h"
480
481struct tileset {
482 char name[512];
486
487 char *summary;
489 float scale;
490
492
494
498
503
506
508
510
513
519
532
533#define NUM_CORNER_DIRS 4
534#define TILES_PER_CORNER 4
538
543
546
547 /* This hash table maps tilespec tags to struct small_sprites. */
549
550 /* This hash table maps terrain graphic strings to drawing data. */
552
554
556
558
560
562
565};
566
569
571
572static bool tileset_update = FALSE;
573
574static struct tileset *tileset_read_toplevel(const char *tileset_name,
575 bool verbose, int topology_id,
576 float scale);
577
578static int fill_unit_type_sprite_array(const struct tileset *t,
579 struct drawn_sprite *sprs,
580 const struct unit_type *putype,
581 enum unit_activity activity,
582 enum direction8 facing);
583static int fill_unit_sprite_array(const struct tileset *t,
584 struct drawn_sprite *sprs,
585 const struct unit *punit,
586 int stack, bool backdrop);
587static bool load_river_sprites(struct tileset *t,
588 struct river_sprites *store, const char *tag_pfx);
589
590static void tileset_setup_base(struct tileset *t,
591 const struct extra_type *pextra,
592 const char *tag);
593static void tileset_setup_road(struct tileset *t,
594 struct extra_type *pextra,
595 const char *tag);
596
597static bool is_extra_drawing_enabled(struct extra_type *pextra);
598
599static int fill_basic_road_sprite_array(const struct tileset *t,
600 struct drawn_sprite *sprs,
601 const struct extra_type *pextra);
602static int fill_basic_base_sprite_array(const struct tileset *t,
603 struct drawn_sprite *sprs,
604 const struct extra_type *pextra);
605
606static void tileset_player_free(struct tileset *t, int plrid);
607
608static void tileset_setup_specialist_type(struct tileset *t,
609 struct citizen_set *set,
611 const char *tag_group,
612 const char *set_name,
613 bool required);
615static void tileset_setup_citizen_types(struct tileset *t,
616 struct citizen_set *set,
617 const char *tag_group,
618 const char *set_name,
619 bool required);
620
621/************************************************************************/
624void tileset_error(enum log_level level, const char *tset_name,
625 const char *format, ...)
626{
627 char buf[2048];
628 va_list args;
629
630 va_start(args, format);
631 fc_vsnprintf(buf, sizeof(buf), format, args);
632 va_end(args);
633
634 log_base(level, "%s", buf);
635
636 if (level <= LOG_NORMAL) {
638
639 if (level == LOG_FATAL) {
641 }
642 }
643}
644
645/************************************************************************/
648static struct drawing_data *drawing_data_new(void)
649{
650 struct drawing_data *draw = fc_calloc(1, sizeof(*draw));
651
652 draw->name = NULL;
653
654 return draw;
655}
656
657/************************************************************************/
661{
662 int i;
663
665
666 if (draw->name != NULL) {
667 free(draw->name);
668 }
669 for (i = 0; i < 4; i++) {
670 if (draw->blend[i]) {
671 free_sprite(draw->blend[i]);
672 }
673 }
674 for (i = 0; i < draw->num_layers; i++) {
675 int vec_size = sprite_vector_size(&draw->layer[i].allocated);
676 int j;
677
678 for (j = 0; j < vec_size; j++) {
679 free_sprite(draw->layer[i].allocated.p[j]);
680 }
681
682 sprite_vector_free(&draw->layer[i].base);
683 sprite_vector_free(&draw->layer[i].allocated);
684 free(draw->layer[i].cells);
685 }
686 free(draw);
687}
688
689/************************************************************************/
692struct tileset *get_tileset(void)
693{
694 if (unscaled_tileset != NULL) {
695 return unscaled_tileset;
696 } else {
697 return tileset;
698 }
699}
700
701/************************************************************************/
704const char *tileset_basename(const struct tileset *t)
705{
706 return t->name;
707}
708
709/************************************************************************/
712bool tileset_is_isometric(const struct tileset *t)
713{
714 return t->type == TS_ISOMETRIC;
715}
716
717/************************************************************************/
721int tileset_hex_width(const struct tileset *t)
722{
723 return t->hex_width;
724}
725
726/************************************************************************/
730int tileset_hex_height(const struct tileset *t)
731{
732 return t->hex_height;
733}
734
735/************************************************************************/
753int tileset_tile_width(const struct tileset *t)
754{
755 return t->normal_tile_width;
756}
757
758/************************************************************************/
765int tileset_tile_height(const struct tileset *t)
766{
767 return t->normal_tile_height;
768}
769
770/************************************************************************/
777{
778 return t->full_tile_width;
779}
780
781/************************************************************************/
790{
791 return t->full_tile_height;
792}
793
794/************************************************************************/
797int tileset_unit_width(const struct tileset *t)
798{
799 return t->unit_tile_width;
800}
801
802/************************************************************************/
805int tileset_unit_height(const struct tileset *t)
806{
807 return t->unit_tile_height;
808}
809
810/************************************************************************/
813static int calculate_max_upkeep_height(const struct tileset *t)
814{
815 int i;
816 int max = 0;
817
818 for (i = 0; i < MAX_NUM_UPKEEP_SPRITES; i++) {
819 if (t->sprites.upkeep.unhappy[i] != NULL) {
820 int width, height;
821
822 /* TODO: We want only height, getting the width might waste CPU
823 * depending on gui-specific implementation. */
825
826 max = MAX(max, height);
827 }
828 }
829
831 for (i = 0; i < MAX_NUM_UPKEEP_SPRITES; i++) {
832 if (t->sprites.upkeep.output[o][i] != NULL) {
833 int width, height;
834
835 /* TODO: We want only height, getting the width might waste CPU
836 * depending on gui-specific implementation. */
838
839 max = MAX(max, height);
840 }
841 }
843
844 return max;
845}
846
847/************************************************************************/
850static int tileset_upkeep_height(const struct tileset *t)
851{
852 /* Return cached value */
853 return t->max_upkeep_height;
854}
855
856/************************************************************************/
866
867/************************************************************************/
878
879/************************************************************************/
883{
884 return t->unit_upkeep_offset_y;
885}
886
887/************************************************************************/
892{
894}
895
896/************************************************************************/
902{
903 return t->small_sprite_width;
904}
905
906/************************************************************************/
911{
912 return t->citybar_offset_y;
913}
914
915/************************************************************************/
920{
921 return t->tilelabel_offset_y;
922}
923
924/************************************************************************/
927float tileset_scale(const struct tileset *t)
928{
929 return tileset->scale;
930}
931
932/************************************************************************/
938{
939 return t->small_sprite_height;
940}
941
942/************************************************************************/
947const char *tileset_main_intro_filename(const struct tileset *t)
948{
949 return t->main_intro_filename;
950}
951
952/************************************************************************/
956{
957 return t->sprites.city.worked_tile_overlay.size;
958}
959
960/************************************************************************/
964{
965 return FOG_AUTO == t->fogstyle;
966}
967
968/************************************************************************/
971static struct tileset *tileset_new(void)
972{
973 struct tileset *t = fc_calloc(1, sizeof(*t));
974
977
978 return t;
979}
980
981/************************************************************************/
985static const char *dir_get_tileset_name(enum direction8 dir)
986{
987 switch (dir) {
988 case DIR8_NORTH:
989 return "n";
990 case DIR8_NORTHEAST:
991 return "ne";
992 case DIR8_EAST:
993 return "e";
994 case DIR8_SOUTHEAST:
995 return "se";
996 case DIR8_SOUTH:
997 return "s";
998 case DIR8_SOUTHWEST:
999 return "sw";
1000 case DIR8_WEST:
1001 return "w";
1002 case DIR8_NORTHWEST:
1003 return "nw";
1004 }
1005 log_error("Wrong direction8 variant: %d.", dir);
1006 return "";
1007}
1008
1009/************************************************************************/
1012static enum direction8 dir_by_tileset_name(const char *str)
1013{
1014 enum direction8 dir;
1015
1016 for (dir = direction8_begin();
1017 dir != direction8_end();
1018 dir = direction8_next(dir)) {
1019 if (strcmp(dir_get_tileset_name(dir), str) == 0) {
1020 return dir;
1021 }
1022 }
1023
1024 return direction8_invalid();
1025}
1026
1027/************************************************************************/
1030static bool is_valid_tileset_dir(const struct tileset *t,
1031 enum direction8 dir)
1032{
1033 if (t->hex_width > 0) {
1034 return dir != DIR8_NORTHEAST && dir != DIR8_SOUTHWEST;
1035 } else if (t->hex_height > 0) {
1036 return dir != DIR8_NORTHWEST && dir != DIR8_SOUTHEAST;
1037 } else {
1038 return TRUE;
1039 }
1040}
1041
1042/************************************************************************/
1048static bool is_cardinal_tileset_dir(const struct tileset *t,
1049 enum direction8 dir)
1050{
1051 if (t->hex_width > 0 || t->hex_height > 0) {
1052 return is_valid_tileset_dir(t, dir);
1053 } else {
1054 return (dir == DIR8_NORTH || dir == DIR8_EAST
1055 || dir == DIR8_SOUTH || dir == DIR8_WEST);
1056 }
1057}
1058
1059/************************************************************************/
1064{
1065 int idx;
1066
1067 if ((actual_topology & TF_HEX)
1068 && (actual_topology & TF_ISO)) {
1069 idx = TS_TOPO_ISOHEX;
1070 } else if (actual_topology & TF_ISO) {
1071 idx = TS_TOPO_SQUARE;
1072 } else if (actual_topology & TF_HEX) {
1073 idx = TS_TOPO_HEX;
1074 } else {
1075 idx = TS_TOPO_SQUARE;
1076 }
1077
1078 return idx;
1079}
1080
1081/************************************************************************/
1086{
1087 switch (idx) {
1088 case TS_TOPO_SQUARE:
1089 return TF_ISO;
1090 case TS_TOPO_HEX:
1091 return TF_HEX;
1092 case TS_TOPO_ISOHEX:
1093 return TF_HEX | TF_ISO;
1094 }
1095
1096 return 0;
1097}
1098
1099/************************************************************************/
1103const struct strvec *get_tileset_list(const struct option *poption)
1104{
1105 static struct strvec *tilesets[3] = { NULL, NULL, NULL };
1107 int idx;
1108
1109 idx = ts_topology_index(topo);
1110
1112
1113 if (tilesets[idx] == NULL) {
1114 /* Note: this means you must restart the client after installing a new
1115 tileset. */
1117
1118 tilesets[idx] = strvec_new();
1119 strvec_iterate(list, file) {
1120 struct tileset *t = tileset_read_toplevel(file, FALSE, topo, 1.0f);
1121
1122 if (t) {
1123 strvec_append(tilesets[idx], file);
1124 tileset_free(t);
1125 }
1128 }
1129
1130 return tilesets[idx];
1131}
1132
1133/************************************************************************/
1140static char *tilespec_fullname(const char *tileset_name)
1141{
1142 if (tileset_name) {
1144 const char *dname;
1145
1146 fc_snprintf(fname, sizeof(fname),
1147 "%s%s", tileset_name, TILESPEC_SUFFIX);
1148
1150
1151 if (dname) {
1152 return fc_strdup(dname);
1153 }
1154 }
1155
1156 return NULL;
1157}
1158
1159/************************************************************************/
1165 const char *which,
1166 const char *us_capstr,
1167 const char *filename,
1168 bool verbose)
1169{
1170 enum log_level level = verbose ? LOG_ERROR : LOG_DEBUG;
1171
1172 const char *file_capstr = secfile_lookup_str(file, "%s.options", which);
1173
1174 if (NULL == file_capstr) {
1175 log_base(level, "\"%s\": %s file doesn't have a capability string",
1176 filename, which);
1177 return FALSE;
1178 }
1180 log_base(level, "\"%s\": %s file appears incompatible:",
1181 filename, which);
1182 log_base(level, " datafile options: %s", file_capstr);
1183 log_base(level, " supported options: %s", us_capstr);
1184 return FALSE;
1185 }
1187 log_base(level, "\"%s\": %s file requires option(s) "
1188 "that client doesn't support:", filename, which);
1189 log_base(level, " datafile options: %s", file_capstr);
1190 log_base(level, " supported options: %s", us_capstr);
1191 return FALSE;
1192 }
1193
1194 return TRUE;
1195}
1196
1197/************************************************************************/
1202static void tileset_free_toplevel(struct tileset *t)
1203{
1204 int i, j;
1205
1206 if (t->main_intro_filename) {
1209 }
1210
1211 if (t->preferred_themes) {
1212 for (i = 0; i < t->num_preferred_themes; i++) {
1213 free(t->preferred_themes[i]);
1214 }
1217 }
1218 t->num_preferred_themes = 0;
1219
1220 if (t->tile_hash) {
1222 t->tile_hash = NULL; /* Helpful for sanity. */
1223 }
1224 if (t->estyle_hash) {
1226 t->estyle_hash = NULL;
1227 }
1228 for (i = 0; i < ESTYLE_COUNT; i++) {
1229 if (t->style_lists[i] != NULL) {
1231 t->style_lists[i] = NULL;
1232 }
1233 }
1234
1235 if (t->flagged_bases_list != NULL) {
1238 }
1239
1240 for (i = 0; i < MAX_NUM_LAYERS; i++) {
1241 struct tileset_layer *tslp = &t->layers[i];
1242
1243 if (tslp->match_types) {
1244 for (j = 0; j < tslp->match_count; j++) {
1245 free(tslp->match_types[j]);
1246 }
1247 free(tslp->match_types);
1248 tslp->match_types = NULL;
1249 }
1250 }
1251
1252 if (t->color_system) {
1254 t->color_system = NULL;
1255 }
1256
1257 if (t->summary != NULL) {
1258 free(t->summary);
1259 t->summary = NULL;
1260 }
1261 if (t->description != NULL) {
1262 free(t->description);
1263 t->description = NULL;
1264 }
1265 if (t->for_ruleset != NULL) {
1266 free(t->for_ruleset);
1267 t->for_ruleset = NULL;
1268 }
1269}
1270
1271/************************************************************************/
1274void tileset_free(struct tileset *t)
1275{
1276 int i;
1277
1280 for (i = 0; i < ARRAY_SIZE(t->sprites.player); i++) {
1282 }
1285 free(t);
1286}
1287
1288/************************************************************************/
1296bool tilespec_try_read(const char *tileset_name, bool verbose, int topo_id,
1297 bool global_default)
1298{
1299 bool original;
1300
1301 if (tileset_name == NULL
1303 topo_id, 1.0f))) {
1305
1306 original = FALSE;
1307 strvec_iterate(list, file) {
1308 struct tileset *t = tileset_read_toplevel(file, FALSE, topo_id, 1.0f);
1309
1310 if (t) {
1311 if (!tileset) {
1312 tileset = t;
1313 } else if (t->priority > tileset->priority
1314 || (topo_id >= 0
1317 tileset = t;
1318 } else {
1319 tileset_free(t);
1320 }
1321 }
1324
1325 if (tileset == NULL) {
1326 if (global_default) {
1327 tileset_error(LOG_FATAL, NULL, _("No usable default tileset found, aborting!"));
1328 }
1329
1330 return FALSE;
1331 }
1332
1333 log_verbose("Trying tileset \"%s\".", tileset->name);
1334 } else {
1335 original = TRUE;
1336 }
1338
1339 if (global_default) {
1341 }
1342
1343 return original;
1344}
1345
1346/************************************************************************/
1360 bool game_fully_initialized, float scale)
1361{
1362 int id;
1363 struct tile *center_tile;
1364 enum client_states state = client_state();
1366 char tileset_name[strlen(name) + 1], old_name[strlen(tileset->name) + 1];
1367 bool new_tileset_in_use;
1368 int ts_topo;
1369
1370 /* Make local copies since these values may be freed down below */
1372 sz_strlcpy(old_name, tileset->name);
1373
1374 log_normal(_("Loading tileset \"%s\"."), tileset_name);
1375
1376 /* Step 0: Record old data.
1377 *
1378 * We record the current mapcanvas center, etc.
1379 */
1381
1382 /* Step 1: Cleanup.
1383 *
1384 * Free old tileset or keep it in memory if we are loading the same
1385 * tileset with scaling and old one was not scaled.
1386 */
1387
1388 if (strcmp(tileset_name, old_name) == 0 && tileset->scale == 1.0f
1389 && scale != 1.0f) {
1390 if (unscaled_tileset) {
1392 }
1394 } else {
1396 }
1397
1398 /* Step 2: Read.
1399 *
1400 * We read in the new tileset. This should be pretty straightforward.
1401 */
1403 if (tileset != NULL) {
1405 } else {
1407
1408 if (!(tileset = tileset_read_toplevel(old_name, FALSE, -1, scale))) {
1409 log_fatal("Failed to re-read the currently loaded tileset.");
1411 }
1412 }
1416 }
1417
1421 } /* else we'll get round to it on PACKET_RULESET_GAME */
1422 players_iterate(pplayer) {
1423 tileset_player_init(tileset, pplayer);
1425 boot_help_texts(); /* "About Current Tileset" */
1426 }
1427
1428 /* Step 3: Setup
1429 *
1430 * This is a seriously sticky problem. On startup, we build a hash
1431 * from all the sprite data. Then, when we connect to a server, the
1432 * server sends us ruleset data a piece at a time and we use this data
1433 * to assemble the sprite structures. But if we change while connected
1434 * we have to reassemble all of these. This should just involve
1435 * calling tilespec_setup_*** on everything. But how do we tell what
1436 * "everything" is?
1437 *
1438 * The below code just does things straightforwardly, by setting up
1439 * each possible sprite again. Hopefully it catches everything, and
1440 * doesn't mess up too badly if we change tilesets while not connected
1441 * to a server.
1442 */
1443 if (!game.client.ruleset_ready) {
1444 /* The ruleset data is not sent until this point. */
1445 return new_tileset_in_use;
1446 }
1447
1449 == TOPO_INCOMP_HARD) {
1451 _("Map topology (%s) and tileset (%s) incompatible."),
1453 }
1454
1455 terrain_type_iterate(pterrain) {
1461 governments_iterate(gov) {
1464 extra_type_iterate(pextra) {
1467 nations_iterate(pnation) {
1470 improvement_iterate(pimprove) {
1479
1482 * sizeof(tileset->sprites.style_citizen_sets.sets[0]));
1483
1484 for (id = 0; id < game.control.num_city_styles; id++) {
1486 }
1487
1488 if (state < C_S_RUNNING) {
1489 /* Below redraws do not apply before this. */
1490 return new_tileset_in_use;
1491 }
1492
1493 /* Step 4: Draw.
1494 *
1495 * Do any necessary redraws.
1496 */
1499 can_slide = FALSE;
1501 /* update_map_canvas_visible forces a full redraw. Otherwise with fast
1502 * drawing we might not get one. Of course this is slower. */
1504 can_slide = TRUE;
1505
1506 return new_tileset_in_use;
1507}
1508
1509/************************************************************************/
1514{
1515 const char *tileset_name;
1516 enum client_states state = client_state();
1517
1518 if (state == C_S_RUNNING || state == C_S_OVER) {
1520
1521 /* Also iso map topology counts as 'square' tileset topology */
1522 if (opt != (wld.map.topology_id & (TF_ISO | TF_HEX))
1523 && (opt != 0 || ((wld.map.topology_id & TF_HEX) == TF_HEX))) {
1524 /* Changed option was not for current topology */
1525 return;
1526 }
1527 }
1528
1530
1531 fc_assert_ret(NULL != tileset_name && tileset_name[0] != '\0');
1534
1535 /* As it's going to be 'current' tileset, make it global default if
1536 * options saved. */
1538
1540 menus_init();
1541}
1542
1543/************************************************************************/
1550{
1552 tilespec_reread(tname, TRUE, 1.0f);
1554 menus_init();
1555}
1556
1557/************************************************************************/
1561static struct sprite *load_gfx_file(const char *gfx_filename, bool svgflag)
1562{
1563 const char **gfx_fileexts, *gfx_fileext;
1564 struct sprite *s;
1565
1566 if (svgflag) {
1568 } else {
1570 }
1571
1572 /* Try out all supported file extensions to find one that works. */
1573 while ((gfx_fileext = *gfx_fileexts++)) {
1574 const char *real_full_name;
1575 char full_name[strlen(gfx_filename) + strlen(".")
1576 + strlen(gfx_fileext) + 1];
1577
1580 log_debug("trying to load gfx file \"%s\".", real_full_name);
1582 svgflag && !strcmp("svg", gfx_fileext));
1583 if (s) {
1584 return s;
1585 }
1586 }
1587 }
1588
1589 log_error("Could not load gfx file \"%s\".", gfx_filename);
1590
1591 return NULL;
1592}
1593
1594/************************************************************************/
1597static void ensure_big_sprite(struct specfile *sf, const char *tset_name)
1598{
1599 struct section_file *file;
1600 const char *gfx_filename;
1601
1602 if (sf->big_sprite) {
1603 /* Looks like it's already loaded. */
1604 return;
1605 }
1606
1607 /* Otherwise load it. The big sprite will sometimes be freed and will have
1608 * to be reloaded, but most of the time it's just loaded once, the small
1609 * sprites are extracted, and then it's freed. */
1610 if (!(file = secfile_load(sf->file_name, TRUE))) {
1612 _("Could not open '%s':\n%s"), sf->file_name, secfile_error());
1613 }
1614
1615 if (!check_tilespec_capabilities(file, "spec",
1616 SPEC_CAPSTR, sf->file_name, TRUE)) {
1618 _("Specfile %s has incompatible capabilities"), sf->file_name);
1619 }
1620
1621 gfx_filename = secfile_lookup_str(file, "file.gfx");
1622
1624
1625 if (!sf->big_sprite) {
1627 _("Could not load gfx file for the spec file \"%s\"."),
1628 sf->file_name);
1629 }
1630 secfile_destroy(file);
1631}
1632
1633/************************************************************************/
1638static void scan_specfile(struct tileset *t, struct specfile *sf,
1639 bool duplicates_ok)
1640{
1641 struct section_file *file;
1642 struct section_list *sections;
1643 int i;
1644
1645 if (!(file = secfile_load(sf->file_name, TRUE))) {
1647 _("Could not open '%s':\n%s"), sf->file_name, secfile_error());
1648 }
1649 if (!check_tilespec_capabilities(file, "spec",
1650 SPEC_CAPSTR, sf->file_name, TRUE)) {
1652 _("Specfile %s has incompatible capabilities"), sf->file_name);
1653 }
1654
1655 /* Currently unused */
1656 secfile_entry_ignore(file, "info.artists");
1657
1658 /* Not used here */
1659 secfile_entry_ignore(file, "file.gfx");
1660
1661 if ((sections = secfile_sections_by_name_prefix(file, "grid_"))) {
1662 section_list_iterate(sections, psection) {
1663 int j, k;
1664 int x_top_left, y_top_left, dx, dy;
1665 int pixel_border_x;
1666 int pixel_border_y;
1667 const char *sec_name = section_name(psection);
1668
1669 pixel_border_x = secfile_lookup_int_default(file, 0, "%s.pixel_border",
1670 sec_name);
1671 pixel_border_y = secfile_lookup_int_default(file, pixel_border_x, "%s.pixel_border_y",
1672 sec_name);
1673 pixel_border_x = secfile_lookup_int_default(file, pixel_border_x, "%s.pixel_border_x",
1674 sec_name);
1675 if (!secfile_lookup_int(file, &x_top_left, "%s.x_top_left", sec_name)
1676 || !secfile_lookup_int(file, &y_top_left,
1677 "%s.y_top_left", sec_name)
1678 || !secfile_lookup_int(file, &dx, "%s.dx", sec_name)
1679 || !secfile_lookup_int(file, &dy, "%s.dy", sec_name)) {
1680 log_error("%s grid \"%s\" invalid: %s",
1682 continue;
1683 }
1684
1685 j = -1;
1686 while (NULL != secfile_entry_lookup(file, "%s.tiles%d.tag",
1687 sec_name, ++j)) {
1688 struct small_sprite *ss;
1689 int row, column;
1690 int xr, yb;
1691 const char **tags;
1692 size_t num_tags;
1693 int hot_x, hot_y;
1694
1695 if (!secfile_lookup_int(file, &row, "%s.tiles%d.row", sec_name, j)
1696 || !secfile_lookup_int(file, &column, "%s.tiles%d.column",
1697 sec_name, j)
1698 || !(tags = secfile_lookup_str_vec(file, &num_tags,
1699 "%s.tiles%d.tag",
1700 sec_name, j))) {
1701 log_error("%s small sprite \"%s.tiles%d\" invalid: %s",
1703 continue;
1704 }
1705 hot_x = secfile_lookup_int_default(file, 0, "%s.tiles%d.hot_x",
1706 sec_name, j);
1707 hot_y = secfile_lookup_int_default(file, 0, "%s.tiles%d.hot_y",
1708 sec_name, j);
1709
1710 /* There must be at least 1 because of the while(): */
1711 fc_assert_action(num_tags > 0, continue);
1712
1713 xr = x_top_left + (dx + pixel_border_x) * column;
1714 yb = y_top_left + (dy + pixel_border_y) * row;
1715
1716 ss = fc_malloc(sizeof(*ss));
1717 ss->ref_count = 0;
1718 ss->file = NULL;
1719 ss->x = xr;
1720 ss->y = yb;
1721 ss->width = dx;
1722 ss->height = dy;
1723 ss->sf = sf;
1724 ss->sprite = NULL;
1725 ss->hot_x = hot_x;
1726 ss->hot_y = hot_y;
1727
1729
1730 if (!duplicates_ok) {
1731 for (k = 0; k < num_tags; k++) {
1732 if (!sprite_hash_insert(t->sprite_hash, tags[k], ss)) {
1733 log_error("warning: %s already has a sprite for \"%s\".",
1734 tileset_name_get(t), tags[k]);
1735 }
1736 }
1737 } else {
1738 for (k = 0; k < num_tags; k++) {
1739 (void) sprite_hash_replace(t->sprite_hash, tags[k], ss);
1740 }
1741 }
1742
1743 free(tags);
1744 tags = NULL;
1745 }
1747 section_list_destroy(sections);
1748 }
1749
1750 /* Load "extra" sprites. Each sprite is one file. */
1751 i = -1;
1752 while (NULL != secfile_entry_lookup(file, "extra.sprites%d.tag", ++i)) {
1753 struct small_sprite *ss;
1754 const char **tags;
1755 const char *filename;
1756 size_t num_tags, k;
1757 int hot_x, hot_y;
1758
1759 if (!(tags = secfile_lookup_str_vec(file, &num_tags,
1760 "extra.sprites%d.tag", i))
1761 || !(filename = secfile_lookup_str(file,
1762 "extra.sprites%d.file", i))) {
1763 log_error("%s extra sprite \"extra.sprites%d\" invalid: %s",
1765 continue;
1766 }
1767 hot_x = secfile_lookup_int_default(file, 0, "extra.sprites%d.hot_x", i);
1768 hot_y = secfile_lookup_int_default(file, 0, "extra.sprites%d.hot_y", i);
1769
1770 ss = fc_malloc(sizeof(*ss));
1771 ss->ref_count = 0;
1772 ss->file = fc_strdup(filename);
1773 ss->sf = NULL;
1774 ss->sprite = NULL;
1775 ss->hot_x = hot_x;
1776 ss->hot_y = hot_y;
1777
1779
1780 if (!duplicates_ok) {
1781 for (k = 0; k < num_tags; k++) {
1782 if (!sprite_hash_insert(t->sprite_hash, tags[k], ss)) {
1783 log_error("warning: %s already have a sprite for \"%s\".",
1784 tileset_name_get(t), tags[k]);
1785 }
1786 }
1787 } else {
1788 for (k = 0; k < num_tags; k++) {
1789 (void) sprite_hash_replace(t->sprite_hash, tags[k], ss);
1790 }
1791 }
1792 free(tags);
1793 }
1794
1797}
1798
1799/************************************************************************/
1803static char *tilespec_gfx_filename(const char *gfx_filename,
1804 const char *tset_name)
1805{
1806 const char *gfx_current_fileext;
1807 const char **gfx_fileexts = gfx_fileextensions();
1808
1809 while ((gfx_current_fileext = *gfx_fileexts++)) {
1810 const char *real_full_name;
1811 char *full_name =
1814
1816
1818 free(full_name);
1819 if (real_full_name) {
1820 return fc_strdup(real_full_name);
1821 }
1822 }
1823
1825 _("Couldn't find a supported gfx file extension for \"%s\"."),
1826 gfx_filename);
1827
1828 return NULL;
1829}
1830
1831/************************************************************************/
1834static bool tileset_scan_single_list(struct tileset *t,
1835 const char *spec_filenames[],
1836 int num_spec_files, bool verbose,
1837 bool duplicates_ok)
1838{
1839 int i;
1840
1841 for (i = 0; i < num_spec_files; i++) {
1842 struct specfile *sf = fc_malloc(sizeof(*sf));
1843 const char *dname;
1844
1845 log_debug("spec file %s", spec_filenames[i]);
1846
1847 sf->big_sprite = NULL;
1849 if (!dname) {
1850 if (verbose) {
1851 log_error("Can't find spec file \"%s\".", spec_filenames[i]);
1852 }
1853
1854 return FALSE;
1855 }
1856 sf->file_name = fc_strdup(dname);
1858
1860 }
1861
1862 return TRUE;
1863}
1864
1865/************************************************************************/
1868static int check_sprite_type(const char *sprite_type, const char *tile_section)
1869{
1870 if (fc_strcasecmp(sprite_type, "corner") == 0) {
1871 return CELL_CORNER;
1872 }
1873 if (fc_strcasecmp(sprite_type, "single") == 0) {
1874 return CELL_WHOLE;
1875 }
1876 if (fc_strcasecmp(sprite_type, "whole") == 0) {
1877 return CELL_WHOLE;
1878 }
1879 log_error("[%s] unknown sprite_type \"%s\".", tile_section, sprite_type);
1880 return CELL_WHOLE;
1881}
1882
1883/************************************************************************/
1889static struct tileset *tileset_read_toplevel(const char *tileset_name,
1890 bool verbose, int topology_id,
1891 float scale)
1892{
1893 struct section_file *file;
1894 char *fname;
1895 const char *c;
1896 int i;
1897 size_t num_spec_files[SFILE_LAST];
1898 const char **spec_filenames[SFILE_LAST];
1899 size_t num_layers;
1900 const char **layer_order;
1901 size_t num_preferred_themes;
1902 struct section_list *sections = NULL;
1903 const char *file_capstr;
1904 bool duplicates_ok, is_hex;
1905 enum direction8 dir;
1906 struct tileset *t = NULL;
1907 const char *extraname;
1908 const char *tstr;
1909 int topo;
1910 bool svg;
1912 const char *type_name;
1913
1915
1916 if (fname == NULL) {
1917 if (verbose) {
1918 log_error("Can't find tileset \"%s\".", tileset_name);
1919 }
1920
1921 return NULL;
1922 }
1923 log_verbose("tilespec file is \"%s\".", fname);
1924
1925 if (!(file = secfile_load(fname, TRUE))) {
1926 log_error("Could not open '%s':\n%s", fname, secfile_error());
1927 free(fname);
1928 return NULL;
1929 }
1930
1931 if (!check_tilespec_capabilities(file, "tilespec",
1932 TILESPEC_CAPSTR, fname, verbose)) {
1933 secfile_destroy(file);
1934 free(fname);
1935 return NULL;
1936 }
1937
1938 t = tileset_new();
1939 t->scale = scale;
1940 file_capstr = secfile_lookup_str(file, "%s.options", "tilespec");
1942 && has_capabilities("+duplicates_ok", file_capstr));
1943
1944 tstr = secfile_lookup_str(file, "tilespec.name");
1945 /* Tileset name found */
1947 tstr = secfile_lookup_str_default(file, "", "tilespec.version");
1948 if (tstr[0] != '\0') {
1949 /* Tileset version found */
1950 sz_strlcpy(t->version, tstr);
1951 } else {
1952 /* No version information */
1953 t->version[0] = '\0';
1954 }
1955
1956 tstr = secfile_lookup_str_default(file, "", "tilespec.summary");
1957 if (tstr[0] != '\0') {
1958 int len;
1959
1960 /* Tileset summary found */
1961 len = strlen(tstr);
1962 t->summary = fc_malloc(len + 1);
1963 fc_strlcpy(t->summary, tstr, len + 1);
1964 } else {
1965 /* No summary */
1966 if (t->summary != NULL) {
1967 free(t->summary);
1968 t->summary = NULL;
1969 }
1970 }
1971
1972 tstr = secfile_lookup_str_default(file, "", "tilespec.description");
1973 if (tstr[0] != '\0') {
1974 int len;
1975
1976 /* Tileset description found */
1977 len = strlen(tstr);
1978 t->description = fc_malloc(len + 1);
1979 fc_strlcpy(t->description, tstr, len + 1);
1980 } else {
1981 /* No description */
1982 if (t->description != NULL) {
1983 free(t->description);
1984 t->description = NULL;
1985 }
1986 }
1987
1988 tstr = secfile_lookup_str_default(file, NULL, "tilespec.for_ruleset");
1989 if (tstr != NULL) {
1991 } else {
1992 t->for_ruleset = NULL;
1993 }
1994
1996 if (!secfile_lookup_int(file, &t->priority, "tilespec.priority")
1997 || !secfile_lookup_bool(file, &is_hex, "tilespec.is_hex")) {
1998 log_error("Tileset \"%s\" invalid: %s", t->name, secfile_error());
1999 goto ON_ERROR;
2000 }
2001
2002 tstr = secfile_lookup_str(file, "tilespec.type");
2003 if (tstr == NULL) {
2004 log_error("Tileset \"%s\": no tileset type", t->name);
2005 goto ON_ERROR;
2006 }
2007
2009 if (!ts_type_is_valid(t->type)) {
2010 log_error("Tileset \"%s\": unknown tileset type \"%s\"", t->name, tstr);
2011 goto ON_ERROR;
2012 }
2013
2014 if (t->type == TS_ISOMETRIC) {
2015 topo = TF_ISO;
2016 } else {
2017 topo = 0;
2018 }
2019
2020 /* Read hex-tileset information. */
2021 t->hex_width = t->hex_height = 0;
2022 if (is_hex) {
2023 int hex_side;
2024
2025 if (!secfile_lookup_int(file, &hex_side, "tilespec.hex_side")) {
2026 log_error("Tileset \"%s\" invalid: %s", t->name, secfile_error());
2027 goto ON_ERROR;
2028 }
2029 hex_side = hex_side * t->scale;
2030 if (t->type == TS_ISOMETRIC) {
2031 t->hex_width = hex_side;
2032 } else {
2033 t->hex_height = hex_side;
2034 }
2035
2036 topo |= TF_HEX;
2037
2038 /* Hex tilesets are drawn the same as isometric. */
2039 /* FIXME: There will be other legal values to be used with hex
2040 * tileset in the future, and this would just overwrite it. */
2041 t->type = TS_ISOMETRIC;
2042 }
2043
2044 if (topology_id >= 0) {
2045 if (((topology_id & TF_HEX) && topology_id != (topo & (TF_ISO | TF_HEX)))
2046 || (!(topology_id & TF_HEX) && (topo & TF_HEX))) {
2047 /* Not of requested topology */
2048 goto ON_ERROR;
2049 }
2050 }
2051
2053
2054 if (!is_view_supported(t->type)) {
2055 /* TRANS: "Overhead" or "Isometric" */
2056 log_normal(_("Client does not support %s tilesets."),
2057 _(ts_type_name(t->type)));
2058 log_normal(_("Using default tileset instead."));
2060 goto ON_ERROR;
2061 }
2062
2064
2065 /* Create arrays of valid and cardinal tileset dirs. These depend
2066 * entirely on the tileset, not the topology. They are also in clockwise
2067 * rotational ordering. */
2069 dir = DIR8_NORTH;
2070 do {
2071 if (is_valid_tileset_dir(t, dir)) {
2074 }
2075 if (is_cardinal_tileset_dir(t, dir)) {
2078 }
2079
2080 dir = dir_cw(dir);
2081 } while (dir != DIR8_NORTH);
2082
2083 fc_assert(t->num_valid_tileset_dirs % 2 == 0); /* Assumed elsewhere. */
2086
2088 "tilespec.normal_tile_width")
2090 "tilespec.normal_tile_height")) {
2091 log_error("Tileset \"%s\" invalid: %s", t->name, secfile_error());
2092 goto ON_ERROR;
2093 }
2095 /* Adjust width to be multiple of 8 */
2096 if (scale != 1.0f) {
2097 i = t->normal_tile_width;
2098 while (i % 8 != 0) {
2099 i++;
2100 }
2101 t->scale = (t->scale * i) / t->normal_tile_width;
2102 t->normal_tile_width = i;
2103 }
2105 if (t->type == TS_ISOMETRIC) {
2107 if (tileset_hex_height(t) > 0) {
2109 } else {
2110 t->full_tile_height = 3 * t->normal_tile_height / 2;
2111 }
2112 } else {
2115 }
2117 = secfile_lookup_int_default(file, t->full_tile_width, "tilespec.unit_width");
2119 = secfile_lookup_int_default(file, t->full_tile_height, "tilespec.unit_height");
2121 "tilespec.small_tile_width")
2123 "tilespec.small_tile_height")) {
2124 log_error("Tileset \"%s\" invalid: %s", t->name, secfile_error());
2125 goto ON_ERROR;
2126 }
2127 if (t->unit_tile_width != t->full_tile_width && t->scale != 1.0f) {
2129 }
2130 if (t->unit_tile_height != t->full_tile_height && t->scale != 1.0f) {
2132 }
2135 log_verbose("tile sizes %dx%d, %d%d unit, %d%d small",
2139
2140 tstr = secfile_lookup_str(file, "tilespec.fog_style");
2141 if (tstr == NULL) {
2142 log_error("Tileset \"%s\": no fog_style", t->name);
2143 goto ON_ERROR;
2144 }
2145
2147 if (!fog_style_is_valid(t->fogstyle)) {
2148 log_error("Tileset \"%s\": unknown fog_style \"%s\"", t->name, tstr);
2149 goto ON_ERROR;
2150 }
2151
2152 tstr = secfile_lookup_str(file, "tilespec.darkness_style");
2153 if (tstr == NULL) {
2154 log_error("Tileset \"%s\": no darkness_style", t->name);
2155 goto ON_ERROR;
2156 }
2157
2160 log_error("Tileset \"%s\": unknown darkness_style \"%s\"", t->name, tstr);
2161 goto ON_ERROR;
2162 }
2163
2165 && (t->type == TS_OVERHEAD || t->hex_width > 0 || t->hex_height > 0)) {
2166 log_error("Invalid darkness style set in tileset \"%s\".", t->name);
2167 goto ON_ERROR;
2168 }
2169
2171 "tilespec.unit_flag_offset_x")
2173 "tilespec.unit_flag_offset_y")
2175 "tilespec.city_flag_offset_x")
2177 "tilespec.city_flag_offset_y")
2178 || !secfile_lookup_int(file, &t->unit_offset_x,
2179 "tilespec.unit_offset_x")
2180 || !secfile_lookup_int(file, &t->unit_offset_y,
2181 "tilespec.unit_offset_y")
2183 "tilespec.activity_offset_x")
2185 "tilespec.activity_offset_y")
2186 || !secfile_lookup_int(file, &t->select_offset_x,
2187 "tilespec.select_offset_x")
2188 || !secfile_lookup_int(file, &t->select_offset_y,
2189 "tilespec.select_offset_y")
2191 "tilespec.stack_size_offset_x")
2193 "tilespec.stack_size_offset_y")
2194 || !secfile_lookup_int(file, &t->city_offset_x,
2195 "tilespec.city_offset_x")
2196 || !secfile_lookup_int(file, &t->city_offset_y,
2197 "tilespec.city_offset_y")
2199 "tilespec.city_size_offset_x")
2201 "tilespec.city_size_offset_y")
2203 "tilespec.citybar_offset_y")
2205 "tilespec.tilelabel_offset_y")
2207 "tilespec.occupied_offset_x")
2209 "tilespec.occupied_offset_y")) {
2210 log_error("Tileset \"%s\" invalid: %s", t->name, secfile_error());
2211 goto ON_ERROR;
2212 }
2213
2215 "tilespec.unit_upkeep_offset_y");
2217 "tilespec.unit_upkeep_small_offset_y");
2218 t->svg_height = secfile_lookup_int_default(file, 44, "tilespec.svg_height");
2219
2230 t->unit_offset_x = t->scale * t->unit_offset_x;
2231 t->unit_offset_y = t->scale * t->unit_offset_y;
2234 t->city_offset_x = t->scale * t->city_offset_x;
2235 t->city_offset_y = t->scale * t->city_offset_y;
2240 t->svg_height *= t->scale;
2241
2242 if (t->scale != 1.0f
2245 }
2246 if (t->scale != 1.0f
2249 }
2250
2252 "tilespec.unit_default_orientation");
2253 if (!c) {
2254 /* This is valid, but tileset must specify icon for every unit */
2256 } else {
2257 dir = dir_by_tileset_name(c);
2258
2259 if (!direction8_is_valid(dir)) {
2261 _("Unknown unit_default_orientation \"%s\""), c);
2262 goto ON_ERROR;
2263 } else {
2264 /* Default orientation is allowed to not be a valid one for the
2265 * tileset */
2266 t->unit_default_orientation = dir;
2267 }
2268 }
2269
2270 c = secfile_lookup_str(file, "tilespec.main_intro_file");
2272 log_debug("intro file %s", t->main_intro_filename);
2273
2274 /* Layer order */
2275 num_layers = 0;
2276 layer_order = secfile_lookup_str_vec(file, &num_layers,
2277 "tilespec.layer_order");
2278 if (layer_order != NULL) {
2279 for (i = 0; i < num_layers; i++) {
2280 int j;
2283
2284 /* Check for wrong layer names. */
2285 if (!mapview_layer_is_valid(layer)) {
2286 log_error("layer_order: Invalid layer \"%s\" in %s",
2288 goto ON_ERROR;
2289 }
2290 /* Check for duplicates. */
2291 for (j = 0; j < i; j++) {
2292 if (t->layer_order[j] == layer) {
2293 log_error("layer_order: Duplicate layer \"%s\" in %s",
2295 goto ON_ERROR;
2296 }
2297 }
2298 t->layer_order[i] = layer;
2299 }
2300
2301 /* Now check that all layers are present. Doing it now allows for a more
2302 * comprehensive error message. */
2303 for (i = 0; i < LAYER_COUNT; i++) {
2304 int j;
2305 bool found = FALSE;
2306
2307 for (j = 0; j < num_layers; j++) {
2308 if (i == t->layer_order[j]) {
2309 found = TRUE;
2310 break;
2311 }
2312 }
2313 if (!found) {
2314 log_error("layer_order: Missing layer \"%s\" in %s",
2316 goto ON_ERROR;
2317 }
2318 }
2319
2321 } else {
2322 /* There is no layer_order tag in the specfile -> use the default */
2323 for (i = 0; i < LAYER_COUNT; i++) {
2324 t->layer_order[i] = i;
2325 }
2326 }
2327
2328 /* Terrain layer info. */
2329 for (i = 0; i < MAX_NUM_LAYERS; i++) {
2330 struct tileset_layer *tslp = &t->layers[i];
2331 int j, k;
2332
2333 tslp->match_types =
2334 (char **) secfile_lookup_str_vec(file, &tslp->match_count,
2335 "layer%d.match_types", i);
2336 for (j = 0; j < tslp->match_count; j++) {
2337 tslp->match_types[j] = fc_strdup(tslp->match_types[j]);
2338
2339 for (k = 0; k < j; k++) {
2340 if (tslp->match_types[k][0] == tslp->match_types[j][0]) {
2342 _("[layer%d] match_types: \"%s\" initial "
2343 "('%c') is not unique."),
2344 i, tslp->match_types[j], tslp->match_types[j][0]);
2345 /* FIXME: Returns NULL. */
2346 }
2347 }
2348 }
2349 }
2350
2351 /* Tile drawing info. */
2353 if (NULL == sections || 0 == section_list_size(sections)) {
2355 _("No [%s] sections present."),
2357 goto ON_ERROR;
2358 }
2359
2360 fc_assert(t->tile_hash == NULL);
2362
2363 section_list_iterate(sections, psection) {
2364 const char *sec_name = section_name(psection);
2366 const char *sprite_type;
2367 int l;
2368 const char *terrain_name;
2369
2370 terrain_name = secfile_lookup_str(file, "%s.tag", sec_name);
2371
2372 if (terrain_name != NULL) {
2373 draw->name = fc_strdup(terrain_name);
2374 } else {
2375 tileset_error(LOG_ERROR, _("No terrain tag given in section [%s] in %s."),
2378 goto ON_ERROR;
2379 }
2380
2381 draw->blending = secfile_lookup_int_default(file, 0, "%s.blend_layer",
2382 sec_name);
2383 draw->blending = CLIP(0, draw->blending, MAX_NUM_LAYERS);
2384
2385 draw->is_reversed = secfile_lookup_bool_default(file, FALSE,
2386 "%s.is_reversed",
2387 sec_name);
2388 draw->num_layers = secfile_lookup_int_default(file, 0, "%s.num_layers",
2389 sec_name);
2390 draw->num_layers = CLIP(1, draw->num_layers, MAX_NUM_LAYERS);
2391
2392 for (l = 0; l < draw->num_layers; l++) {
2393 struct drawing_layer *dlp = &draw->layer[l];
2394 struct tileset_layer *tslp = &t->layers[l];
2395 const char *match_type;
2396 const char **match_with;
2397 size_t count;
2398
2399 dlp->is_tall
2400 = secfile_lookup_bool_default(file, FALSE, "%s.layer%d_is_tall",
2401 sec_name, l);
2402 dlp->offset_x
2403 = secfile_lookup_int_default(file, 0, "%s.layer%d_offset_x",
2404 sec_name, l);
2405 dlp->offset_y
2406 = secfile_lookup_int_default(file, 0, "%s.layer%d_offset_y",
2407 sec_name, l);
2408 dlp->offset_x = ceil(t->scale * dlp->offset_x);
2409 dlp->offset_y = ceil(t->scale * dlp->offset_y);
2410
2412 "%s.layer%d_match_type",
2413 sec_name, l);
2414 if (match_type) {
2415 int j;
2416
2417 /* Determine our match_type. */
2418 for (j = 0; j < tslp->match_count; j++) {
2419 if (fc_strcasecmp(tslp->match_types[j], match_type) == 0) {
2420 break;
2421 }
2422 }
2423 if (j >= tslp->match_count) {
2424 log_error("[%s] invalid match_type \"%s\" in %s.",
2426 } else {
2427 dlp->match_index[dlp->match_indices++] = j;
2428 }
2429 }
2430
2431 match_with = secfile_lookup_str_vec(file, &count,
2432 "%s.layer%d_match_with",
2433 sec_name, l);
2434 if (match_with) {
2435 int j, k;
2436
2437 if (count > MAX_NUM_MATCH_WITH) {
2438 log_error("[%s] match_with has too many types (%d, max %d) in %s",
2439 sec_name, (int) count, MAX_NUM_MATCH_WITH,
2440 tileset_name_get(t));
2441 count = MAX_NUM_MATCH_WITH;
2442 }
2443
2444 if (1 < dlp->match_indices) {
2445 log_error("[%s] previous match_with ignored in %s.",
2447 dlp->match_indices = 1;
2448 } else if (1 > dlp->match_indices) {
2449 log_error("[%s] missing match_type, using \"%s\" in %s.",
2450 sec_name, tslp->match_types[0], tileset_name_get(t));
2451 dlp->match_index[0] = 0;
2452 dlp->match_indices = 1;
2453 }
2454
2455 for (k = 0; k < count; k++) {
2456 for (j = 0; j < tslp->match_count; j++) {
2457 if (fc_strcasecmp(tslp->match_types[j], match_with[k]) == 0) {
2458 break;
2459 }
2460 }
2461 if (j >= tslp->match_count) {
2462 log_error("[%s] layer%d_match_with: invalid \"%s\".",
2463 sec_name, l, match_with[k]);
2464 } else if (1 < count) {
2465 int m;
2466
2467 for (m = 0; m < dlp->match_indices; m++) {
2468 if (dlp->match_index[m] == j) {
2469 log_error("[%s] layer%d_match_with: duplicate \"%s\" in %s.",
2471 break;
2472 }
2473 }
2474 if (m >= dlp->match_indices) {
2475 dlp->match_index[dlp->match_indices++] = j;
2476 }
2477 } else {
2478 dlp->match_index[dlp->match_indices++] = j;
2479 }
2480 }
2482 match_with = NULL;
2483 }
2484
2485 /* Check match_indices */
2486 switch (dlp->match_indices) {
2487 case 0:
2488 case 1:
2489 dlp->match_style = MATCH_NONE;
2490 break;
2491 case 2:
2492 if (dlp->match_index[0] == dlp->match_index[1] ) {
2493 dlp->match_style = MATCH_SAME;
2494 } else {
2495 dlp->match_style = MATCH_PAIR;
2496 }
2497 break;
2498 default:
2499 dlp->match_style = MATCH_FULL;
2500 break;
2501 };
2502
2504 = secfile_lookup_str_default(file, "whole", "%s.layer%d_sprite_type",
2505 sec_name, l);
2506 dlp->sprite_type = check_sprite_type(sprite_type, sec_name);
2507
2508 switch (dlp->sprite_type) {
2509 case CELL_WHOLE:
2510 /* OK, no problem */
2511 break;
2512 case CELL_CORNER:
2513 if (dlp->is_tall
2514 || dlp->offset_x > 0
2515 || dlp->offset_y > 0) {
2516 log_error("[%s] layer %d: you cannot have tall terrain or\n"
2517 "a sprite offset with a cell-based drawing method in %s.",
2519 dlp->is_tall = FALSE;
2520 dlp->offset_x = dlp->offset_y = 0;
2521 }
2522 break;
2523 };
2524 }
2525
2526 if (!drawing_hash_insert(t->tile_hash, draw->name, draw)) {
2527 log_error("warning: multiple tile sections containing terrain tag \"%s\" in %s.",
2528 draw->name, tileset_name_get(t));
2529 goto ON_ERROR;
2530 }
2532 section_list_destroy(sections);
2533 sections = NULL;
2534
2536
2537 for (i = 0; i < ESTYLE_COUNT; i++) {
2539 }
2541
2542 for (i = 0; (extraname = secfile_lookup_str_default(file, NULL,
2543 "extras.styles%d.name",
2544 i)); i++) {
2545 const char *style_name;
2546 enum extrastyle_id style;
2547
2548 style_name = secfile_lookup_str_default(file, "Single1",
2549 "extras.styles%d.style", i);
2551 if (!extrastyle_id_is_valid(style)) {
2552 log_error("Unknown extra style \"%s\" for extra \"%s\" in %s.",
2554 goto ON_ERROR;
2555 }
2556
2557 if (!estyle_hash_insert(t->estyle_hash, extraname, style)) {
2558 log_error("warning: duplicate extrastyle entry [%s] in %s.",
2560 goto ON_ERROR;
2561 }
2562 }
2563
2565
2568 "tilespec.files");
2569
2570 if (svg) {
2572 type_name = "svg";
2573
2574 /* Avoid "unused entry" warning about the other list */
2575 secfile_entry_ignore_by_path(file, "tilespec.files_pixel");
2576 } else {
2578 type_name = "pixel";
2579
2580 /* Avoid "unused entry" warning about the other list */
2581 secfile_entry_ignore_by_path(file, "tilespec.files_svg");
2582 }
2583
2586 "tilespec.files_%s", type_name);
2589 log_error("No tile graphics files specified in \"%s\" for %s mode.",
2590 type_name, fname);
2591 goto ON_ERROR;
2592 }
2593
2594 fc_assert(t->sprite_hash == NULL);
2596
2599 verbose, duplicates_ok)) {
2600 goto ON_ERROR;
2601 }
2602
2605 verbose, duplicates_ok)) {
2606 goto ON_ERROR;
2607 }
2608
2611
2613
2614 /* FIXME: remove this hack. */
2615 t->preferred_themes =
2616 (char **) secfile_lookup_str_vec(file, &num_preferred_themes,
2617 "tilespec.preferred_themes");
2618 if (num_preferred_themes <= 0) {
2619 t->preferred_themes =
2620 (char **) secfile_lookup_str_vec(file, &num_preferred_themes,
2621 "tilespec.prefered_themes");
2622 if (num_preferred_themes > 0) {
2623 log_deprecation("Entry tilespec.prefered_themes in tilespec."
2624 " Use correct spelling tilespec.preferred_themes instead");
2625 }
2626 }
2627 t->num_preferred_themes = num_preferred_themes;
2628 for (i = 0; i < t->num_preferred_themes; i++) {
2630 }
2631
2633 secfile_destroy(file);
2634 log_verbose("finished reading \"%s\".", fname);
2635 free(fname);
2636
2637 return t;
2638
2639ON_ERROR:
2640 secfile_destroy(file);
2641 free(fname);
2642 tileset_free(t);
2643
2644 if (NULL != sections) {
2645 section_list_destroy(sections);
2646 }
2647
2648 return NULL;
2649}
2650
2651/************************************************************************/
2654static const char *citizen_rule_name(enum citizen_category citizen)
2655{
2656 /* These strings are used in reading the tileset. Do not
2657 * translate. */
2658 switch (citizen) {
2659 case CITIZEN_HAPPY:
2660 return "happy";
2661 case CITIZEN_CONTENT:
2662 return "content";
2663 case CITIZEN_UNHAPPY:
2664 return "unhappy";
2665 case CITIZEN_ANGRY:
2666 return "angry";
2667 default:
2668 break;
2669 }
2670 log_error("Unknown citizen type: %d.", (int) citizen);
2671 return NULL;
2672}
2673
2674/************************************************************************/
2679static const char *cardinal_index_str(const struct tileset *t, int idx)
2680{
2681 static char c[64];
2682 int i;
2683
2684 c[0] = '\0';
2685 for (i = 0; i < t->num_cardinal_tileset_dirs; i++) {
2686 int value = (idx >> i) & 1;
2687
2688 cat_snprintf(c, sizeof(c), "%s%d",
2690 }
2691
2692 return c;
2693}
2694
2695/************************************************************************/
2699static char *valid_index_str(const struct tileset *t, int idx)
2700{
2701 static char c[64];
2702 int i;
2703
2704 c[0] = '\0';
2705 for (i = 0; i < t->num_valid_tileset_dirs; i++) {
2706 int value = (idx >> i) & 1;
2707
2708 cat_snprintf(c, sizeof(c), "%s%d",
2710 }
2711
2712 return c;
2713}
2714
2715/************************************************************************/
2722static struct sprite *load_sprite(struct tileset *t, const char *tag_name,
2723 bool scale, bool smooth, bool svgflag)
2724{
2725 struct small_sprite *ss;
2726 float sprite_scale = 1.0f;
2727
2728 log_debug("load_sprite(tag='%s')", tag_name);
2729 /* Lookup information about where the sprite is found. */
2731 return NULL;
2732 }
2733
2734 fc_assert(ss->ref_count >= 0);
2735
2736 if (!ss->sprite) {
2737 /* If the sprite hasn't been loaded already, then load it. */
2738 fc_assert(ss->ref_count == 0);
2739
2740 if (ss->file) {
2741 int w, h;
2742 struct sprite *s;
2743
2744 if (scale) {
2745 s = load_gfx_file(ss->file, svgflag);
2746
2747 if (s != NULL) {
2748 get_sprite_dimensions(s, &w, &h);
2749 ss->sprite = crop_sprite(s, 0, 0, w,
2750 h, NULL, -1, -1, t->scale, smooth);
2751 free_sprite(s);
2752 }
2753 } else {
2754 ss->sprite = load_gfx_file(ss->file, svgflag);
2755 }
2756
2757 if (!ss->sprite) {
2759 _("Couldn't load gfx file \"%s\" for sprite '%s'."),
2760 ss->file, tag_name);
2761 }
2762 } else {
2763 int sf_w, sf_h;
2764
2766 get_sprite_dimensions(ss->sf->big_sprite, &sf_w, &sf_h);
2767 if (ss->x < 0 || ss->x + ss->width > sf_w
2768 || ss->y < 0 || ss->y + ss->height > sf_h) {
2770 _("Sprite '%s' in file \"%s\" isn't within the image!"),
2771 tag_name, ss->sf->file_name);
2772 return NULL;
2773 }
2774 if (scale) {
2775 sprite_scale = t->scale;
2776 }
2777 ss->sprite = crop_sprite(ss->sf->big_sprite, ss->x, ss->y, ss->width,
2778 ss->height, NULL, -1, -1, sprite_scale,
2779 smooth);
2780 }
2781 }
2782
2783 /* Track the reference count so we know when to free the sprite. */
2784 ss->ref_count++;
2785
2786 return ss->sprite;
2787}
2788
2789/************************************************************************/
2792static struct sprite *create_plr_sprite(struct color *pcolor)
2793{
2794 struct sprite *sprite;
2795
2797
2800
2801 return sprite;
2802}
2803
2804/************************************************************************/
2808static void unload_sprite(struct tileset *t, const char *tag_name)
2809{
2810 struct small_sprite *ss;
2811
2814 fc_assert_ret(ss->ref_count >= 1);
2815 fc_assert_ret(ss->sprite);
2816
2817 ss->ref_count--;
2818
2819 if (ss->ref_count == 0) {
2820 /* Nobody's using the sprite anymore, so we should free it. We know
2821 * where to find it if we need it again. */
2822 log_debug("freeing sprite '%s'.", tag_name);
2823 free_sprite(ss->sprite);
2824 ss->sprite = NULL;
2825 }
2826}
2827
2828/************************************************************************/
2832static bool sprite_exists(const struct tileset *t, const char *tag_name)
2833{
2834 /* Lookup information about where the sprite is found. */
2836}
2837
2838/* Not very safe, but convenient: */
2839#define SET_SPRITE(field, tag) \
2840 do { \
2841 t->sprites.field = load_sprite(t, tag, TRUE, TRUE, FALSE); \
2842 if (t->sprites.field == NULL) { \
2843 tileset_error(LOG_FATAL, tileset_name_get(t), \
2844 _("Sprite for tag '%s' missing."), tag); \
2845 } \
2846 } while (FALSE)
2847
2848
2849#define SET_SPRITE_NOTSMOOTH(field, tag) \
2850 do { \
2851 t->sprites.field = load_sprite(t, tag, TRUE, FALSE, FALSE); \
2852 if (t->sprites.field == NULL) { \
2853 tileset_error(LOG_FATAL, tileset_name_get(t), \
2854 _("Sprite for tag '%s' missing."), tag); \
2855 } \
2856 } while (FALSE)
2857
2858#define SET_SPRITE_UNSCALED(field, tag) \
2859 do { \
2860 t->sprites.field = load_sprite(t, tag, FALSE, FALSE, FALSE); \
2861 if (t->sprites.field == NULL) { \
2862 tileset_error(LOG_FATAL, tileset_name_get(t), \
2863 _("Sprite for tag '%s' missing."), tag); \
2864 } \
2865 } while (FALSE)
2866
2867/* Sets sprites.field to tag or (if tag isn't available) to alt */
2868#define SET_SPRITE_ALT(field, tag, alt) \
2869 do { \
2870 t->sprites.field = load_sprite(t, tag, TRUE, TRUE, FALSE); \
2871 if (!t->sprites.field) { \
2872 t->sprites.field = load_sprite(t, alt, TRUE, TRUE, FALSE); \
2873 } \
2874 if (t->sprites.field == NULL) { \
2875 tileset_error(LOG_FATAL, tileset_name_get(t), \
2876 _("Sprite for tags '%s' and alternate '%s' are " \
2877 "both missing."), tag, alt); \
2878 } \
2879 } while (FALSE)
2880
2881/* Sets sprites.field to tag, or NULL if not available */
2882#define SET_SPRITE_OPT(field, tag) \
2883 t->sprites.field = load_sprite(t, tag, TRUE, TRUE, FALSE)
2884
2885#define SET_SPRITE_ALT_OPT(field, tag, alt) \
2886 do { \
2887 t->sprites.field = tiles_lookup_sprite_tag_alt(t, LOG_VERBOSE, tag, alt, \
2888 NULL, "sprite", #field, \
2889 TRUE); \
2890 } while (FALSE)
2891
2892/************************************************************************/
2901
2902/************************************************************************/
2906 struct citizen_set *set,
2908 const char *tag_group,
2909 const char *set_name,
2910 bool required)
2911{
2912 /* Load the specialist sprite graphics. */
2913 char buffer[512];
2914 int j;
2915 struct specialist *spe = specialist_by_number(id);
2916 const char *tag = spe->graphic_str;
2917 const char *graphic_alt = spe->graphic_alt;
2918
2919 for (j = 0; j < MAX_NUM_CITIZEN_SPRITES; j++) {
2920 /* Try tag name + index number */
2921 if (tag_group != NULL) {
2922 fc_snprintf(buffer, sizeof(buffer), "%s.%s_%d", tag_group, tag, j);
2923 } else {
2924 fc_snprintf(buffer, sizeof(buffer), "%s_%d", tag, j);
2925 }
2926 set->specialist[id].sprite[j] = load_sprite(t, buffer,
2927 FALSE, FALSE, FALSE);
2928
2929 /* Break if no more index specific sprites are defined */
2930 if (!set->specialist[id].sprite[j]) {
2931 break;
2932 }
2933 }
2934
2935 if (j == 0) {
2936 /* Try non-indexed */
2937 set->specialist[id].sprite[j] = load_sprite(t, tag,
2938 FALSE, FALSE, FALSE);
2939
2940 if (set->specialist[id].sprite[j]) {
2941 j = 1;
2942 }
2943 }
2944
2945 if (j == 0) {
2946 /* Try the alt tag */
2947 for (j = 0; j < MAX_NUM_CITIZEN_SPRITES; j++) {
2948 /* Try alt tag name + index number */
2949 if (tag_group != NULL) {
2950 fc_snprintf(buffer, sizeof(buffer), "%s.%s_%d", tag_group, graphic_alt, j);
2951 } else {
2952 fc_snprintf(buffer, sizeof(buffer), "%s_%d", graphic_alt, j);
2953 }
2954 set->specialist[id].sprite[j] = load_sprite(t, buffer,
2955 FALSE, FALSE, FALSE);
2956
2957 /* Break if no more index specific sprites are defined */
2958 if (!set->specialist[id].sprite[j]) {
2959 break;
2960 }
2961 }
2962 }
2963
2964 if (j == 0) {
2965 /* Try alt tag non-indexed */
2967 FALSE, FALSE, FALSE);
2968
2969 if (set->specialist[id].sprite[j]) {
2970 j = 1;
2971 }
2972 }
2973
2974 set->specialist[id].count = j;
2975
2976 /* Still nothing? Give up. */
2977 if (j == 0 && required) {
2978 /* TRANS: First %s is a graphics tag of the specialist, second one
2979 * is a citizen set name; 'citizen_graphic' from styles.ruleset */
2981 _("No graphics for specialist \"%s\" in %s."),
2982 tag, set_name);
2983 }
2984}
2985
2986/************************************************************************/
2990{
2992 "default set", TRUE);
2993}
2994
2995/************************************************************************/
2999 struct citizen_set *set,
3000 const char *tag_group,
3001 const char *set_name,
3002 bool required)
3003{
3004 int i, j;
3005 char buffer[512];
3006
3007 /* Load the citizen sprite graphics, no specialist. */
3008 for (i = 0; i < CITIZEN_LAST; i++) {
3009 const char *name = citizen_rule_name(i);
3010
3011 for (j = 0; j < MAX_NUM_CITIZEN_SPRITES; j++) {
3012 if (tag_group != NULL) {
3013 fc_snprintf(buffer, sizeof(buffer), "citizen.%s.%s_%d", tag_group, name, j);
3014 } else {
3015 fc_snprintf(buffer, sizeof(buffer), "citizen.%s_%d", name, j);
3016 }
3017 set->citizen[i].sprite[j] = load_sprite(t, buffer, FALSE, FALSE, FALSE);
3018 if (!set->citizen[i].sprite[j]) {
3019 break;
3020 }
3021 }
3022 set->citizen[i].count = j;
3023 if (j == 0 && required) {
3024 /* TRANS: First %s is type of the citizen ("happy" ... "angry"), second one
3025 * is a citizen set name; 'citizen_graphic' from styles.ruleset */
3027 _("No graphics for citizen \"%s\" in %s."),
3028 name, set_name);
3029 }
3030 }
3031}
3032
3033/************************************************************************/
3039static struct sprite *get_city_sprite(const struct city_sprite *city_sprite,
3040 const struct city *pcity)
3041{
3042 /* Get style and match the best tile based on city size */
3043 int style = style_of_city(pcity);
3044 int num_thresholds;
3046 int img_index;
3047
3049
3052
3053 if (num_thresholds == 0) {
3054 return NULL;
3055 }
3056
3057 /* Get the sprite with the index defined by the effects. */
3058 img_index = pcity->client.city_image;
3059 if (img_index == -100) {
3060 /* Server doesn't know right value as this is from old savegame.
3061 * Guess here based on *client* side information as was done in
3062 * versions where information was not saved to savegame - this should
3063 * give us right answer of what city looked like by the time it was
3064 * put under FoW. */
3066 }
3068
3069 return thresholds[img_index].sprite;
3070}
3071
3072/************************************************************************/
3075static int load_city_thresholds_sprites(struct tileset *t, const char *tag,
3076 char *graphic, char *graphic_alt,
3078{
3079 char buffer[128];
3080 char *gfx_in_use = graphic;
3081 int num_thresholds = 0;
3082 struct sprite *sprite;
3083 int size;
3084
3085 *thresholds = NULL;
3086
3087 for (size = 0; size < MAX_CITY_SIZE; size++) {
3088 fc_snprintf(buffer, sizeof(buffer), "%s_%s_%d",
3089 gfx_in_use, tag, size);
3090 if ((sprite = load_sprite(t, buffer, TRUE, TRUE, FALSE))) {
3093 (*thresholds)[num_thresholds - 1].sprite = sprite;
3094 } else if (size == 0) {
3095 if (gfx_in_use == graphic) {
3096 /* Try again with graphic_alt. */
3097 size--;
3098 gfx_in_use = graphic_alt;
3099 } else {
3100 /* Don't load any others if the 0 element isn't there. */
3101 break;
3102 }
3103 }
3104 }
3105
3106 return num_thresholds;
3107}
3108
3109/************************************************************************/
3116static struct city_sprite *load_city_sprite(struct tileset *t,
3117 const char *tag)
3118{
3119 struct city_sprite *city_sprite = fc_malloc(sizeof(*city_sprite));
3120 int style;
3121
3122 /* Store number of styles we have allocated memory for.
3123 * game.control.num_city_styles might change if client disconnects from
3124 * server and connects new one. */
3127 * sizeof(*city_sprite->styles));
3128
3129 for (style = 0; style < city_sprite->num_styles; style++) {
3131 load_city_thresholds_sprites(t, tag, city_styles[style].graphic,
3132 city_styles[style].graphic_alt,
3134 }
3135
3136 return city_sprite;
3137}
3138
3139/************************************************************************/
3145{
3146 int style;
3147
3148 if (!city_sprite) {
3149 return;
3150 }
3151 for (style = 0; style < city_sprite->num_styles; style++) {
3152 if (city_sprite->styles[style].land_thresholds) {
3154 }
3155 }
3158}
3159
3160/************************************************************************/
3165{
3166 char buffer[512], buffer2[512];
3167 const int W = t->normal_tile_width, H = t->normal_tile_height;
3168 int i, j, f;
3169
3171
3172 SET_SPRITE_UNSCALED(treaty_thumb[0], "treaty.disagree_thumb_down");
3173 SET_SPRITE_UNSCALED(treaty_thumb[1], "treaty.agree_thumb_up");
3174
3175 for (j = 0; j < INDICATOR_COUNT; j++) {
3176 const char *names[] = {"science_bulb", "warming_sun", "cooling_flake"};
3177
3178 for (i = 0; i < NUM_TILES_PROGRESS; i++) {
3179 fc_snprintf(buffer, sizeof(buffer), "s.%s_%d", names[j], i);
3180 SET_SPRITE_UNSCALED(indicator[j][i], buffer);
3181 }
3182 }
3183
3184 SET_SPRITE(arrow[ARROW_RIGHT], "s.right_arrow");
3185 SET_SPRITE(arrow[ARROW_PLUS], "s.plus");
3186 SET_SPRITE(arrow[ARROW_MINUS], "s.minus");
3187 if (t->type == TS_ISOMETRIC) {
3188 SET_SPRITE(dither_tile, "t.dither_tile");
3189 }
3190
3192 SET_SPRITE_NOTSMOOTH(mask.tile, "mask.tile");
3193 } else {
3194 SET_SPRITE(mask.tile, "mask.tile");
3195 }
3196 SET_SPRITE(mask.worked_tile, "mask.worked_tile");
3197 SET_SPRITE(mask.unworked_tile, "mask.unworked_tile");
3198
3199 SET_SPRITE_UNSCALED(tax_luxury, "s.tax_luxury");
3200 SET_SPRITE_UNSCALED(tax_science, "s.tax_science");
3201 SET_SPRITE_UNSCALED(tax_gold, "s.tax_gold");
3202
3204
3205 for (i = 0; i < SPACESHIP_COUNT; i++) {
3206 const char *names[SPACESHIP_COUNT]
3207 = {"solar_panels", "life_support", "habitation",
3208 "structural", "fuel", "propulsion", "exhaust"};
3209
3210 fc_snprintf(buffer, sizeof(buffer), "spaceship.%s", names[i]);
3211 SET_SPRITE(spaceship[i], buffer);
3212 }
3213
3214 for (i = 0; i < CURSOR_LAST; i++) {
3215 const char *names[CURSOR_LAST] =
3216 {"goto", "patrol", "paradrop", "teleport", "nuke", "select",
3217 "invalid", "attack", "edit_paint", "edit_add", "wait"};
3218
3219 for (f = 0; f < NUM_CURSOR_FRAMES; f++) {
3220 struct small_sprite *ss;
3221
3222 fc_assert(ARRAY_SIZE(names) == CURSOR_LAST);
3223 fc_snprintf(buffer, sizeof(buffer), "cursor.%s%d", names[i], f);
3224 SET_SPRITE(cursor[i].frame[f], buffer);
3225
3226 if (sprite_hash_lookup(t->sprite_hash, buffer, &ss)) {
3227 t->sprites.cursor[i].hot_x = ss->hot_x;
3228 t->sprites.cursor[i].hot_y = ss->hot_y;
3229 }
3230 }
3231 }
3232
3233 for (i = 0; i < ICON_COUNT; i++) {
3234 const char *names[ICON_COUNT] = {"freeciv", "citydlg"};
3235
3236 fc_snprintf(buffer, sizeof(buffer), "icon.%s", names[i]);
3237 SET_SPRITE(icon[i], buffer);
3238 }
3239
3240 for (i = 0; i < E_COUNT; i++) {
3241 const char *tag = get_event_tag(i);
3242
3243 SET_SPRITE(events[i], tag);
3244 }
3245
3246 SET_SPRITE(explode.nuke, "explode.nuke");
3247
3249 for (i = 0; ; i++) {
3250 struct sprite *sprite;
3251
3252 fc_snprintf(buffer, sizeof(buffer), "explode.unit_%d", i);
3253 sprite = load_sprite(t, buffer, TRUE, TRUE, FALSE);
3254 if (!sprite) {
3255 break;
3256 }
3258 }
3259
3260 SET_SPRITE(unit.auto_attack, "unit.auto_attack");
3261 SET_SPRITE(unit.auto_settler, "unit.auto_settler");
3262 SET_SPRITE(unit.auto_explore, "unit.auto_explore");
3263 SET_SPRITE(unit.fortified, "unit.fortified");
3264 SET_SPRITE(unit.fortifying, "unit.fortifying");
3265 SET_SPRITE(unit.go_to, "unit.goto");
3266 SET_SPRITE(unit.cultivate, "unit.cultivate");
3267 SET_SPRITE(unit.plant, "unit.plant");
3268 SET_SPRITE(unit.pillage, "unit.pillage");
3269 SET_SPRITE(unit.sentry, "unit.sentry");
3270 SET_SPRITE(unit.convert, "unit.convert");
3271 t->sprites.unit.stack = fc_malloc(sizeof(struct sprite *));
3272 t->sprites.unit.num_stack_sprites = 1;
3273 SET_SPRITE(unit.stack[0], "unit.stack");
3274 t->sprites.unit.no_more_stack_sprites = FALSE;
3275 SET_SPRITE(unit.loaded, "unit.loaded");
3276 SET_SPRITE(unit.transform, "unit.transform");
3277 SET_SPRITE(unit.connect, "unit.connect");
3278 SET_SPRITE(unit.patrol, "unit.patrol");
3279 for (i = 0; i < MAX_NUM_BATTLEGROUPS; i++) {
3280 fc_snprintf(buffer, sizeof(buffer), "unit.battlegroup_%d", i);
3281 fc_snprintf(buffer2, sizeof(buffer2), "city.size_%d", i + 1);
3284 }
3285 SET_SPRITE(unit.lowfuel, "unit.lowfuel");
3286 SET_SPRITE(unit.tired, "unit.tired");
3287
3288 SET_SPRITE_OPT(unit.action_decision_want, "unit.action_decision_want");
3289
3290 for (i = 0; i < NUM_TILES_HP_BAR; i++) {
3291 fc_snprintf(buffer, sizeof(buffer), "unit.hp_%d", i*10);
3292 SET_SPRITE(unit.hp_bar[i], buffer);
3293 }
3294
3295 for (i = 0; i < MAX_VET_LEVELS; i++) {
3296 /* Veteran level sprites are optional. For instance "green" units
3297 * usually have no special graphic. */
3298 fc_snprintf(buffer, sizeof(buffer), "unit.vet_%d", i);
3299 t->sprites.unit.vet_lev[i] = load_sprite(t, buffer, TRUE, TRUE, FALSE);
3300 }
3301
3302 t->sprites.unit.select[0] = NULL;
3303 if (sprite_exists(t, "unit.select0")) {
3304 for (i = 0; i < NUM_TILES_SELECT; i++) {
3305 fc_snprintf(buffer, sizeof(buffer), "unit.select%d", i);
3306 SET_SPRITE(unit.select[i], buffer);
3307 }
3308 }
3309
3310 SET_SPRITE(citybar.shields, "citybar.shields");
3311 SET_SPRITE(citybar.food, "citybar.food");
3312 SET_SPRITE(citybar.trade, "citybar.trade");
3313 SET_SPRITE(citybar.occupied, "citybar.occupied");
3314 SET_SPRITE(citybar.background, "citybar.background");
3316 for (i = 0; ; i++) {
3317 struct sprite *sprite;
3318
3319 fc_snprintf(buffer, sizeof(buffer), "citybar.occupancy_%d", i);
3320 sprite = load_sprite(t, buffer, TRUE, TRUE, FALSE);
3321 if (!sprite) {
3322 break;
3323 }
3325 }
3326 if (t->sprites.citybar.occupancy.size < 2) {
3328 _("Missing necessary citybar.occupancy_N sprites."));
3329 }
3330
3331#define SET_EDITOR_SPRITE(x) SET_SPRITE(editor.x, "editor." #x)
3332 SET_EDITOR_SPRITE(erase);
3333 SET_EDITOR_SPRITE(brush);
3334 SET_EDITOR_SPRITE(copy);
3335 SET_EDITOR_SPRITE(paste);
3336 SET_EDITOR_SPRITE(copypaste);
3339 SET_EDITOR_SPRITE(terrain_resource);
3340 SET_EDITOR_SPRITE(terrain_special);
3344 SET_EDITOR_SPRITE(territory);
3345 SET_EDITOR_SPRITE(properties);
3347 SET_EDITOR_SPRITE(military_base);
3348#undef SET_EDITOR_SPRITE
3349
3350 SET_SPRITE(city.disorder, "city.disorder");
3351
3352 /* Fallbacks for goto path turn numbers:
3353 * path.step_%d, path.exhausted_mp_%d
3354 * --> path.turns_%d
3355 * --> city.size_%d */
3356#define SET_GOTO_TURN_SPRITE(state, state_name, factor, factor_name) \
3357 fc_snprintf(buffer, sizeof(buffer), "path." state_name "_%d" #factor, i); \
3358 SET_SPRITE_OPT(path.s[state].turns ## factor_name [i], buffer); \
3359 if (t->sprites.path.s[state].turns ## factor_name [i] == NULL) { \
3360 t->sprites.path.s[state].turns ## factor_name [i] = \
3361 t->sprites.path.s[GTS_MP_LEFT].turns ## factor_name [i]; \
3362 }
3363
3364 for (i = 0; i < NUM_TILES_DIGITS; i++) {
3365 fc_snprintf(buffer, sizeof(buffer), "city.size_%d", i);
3366 SET_SPRITE(city.size[i], buffer);
3367 fc_snprintf(buffer2, sizeof(buffer2), "path.turns_%d", i);
3368 SET_SPRITE_ALT(path.s[GTS_MP_LEFT].turns[i], buffer2, buffer);
3370 SET_GOTO_TURN_SPRITE(GTS_EXHAUSTED_MP, "exhausted_mp",,);
3371
3372 fc_snprintf(buffer, sizeof(buffer), "city.size_%d0", i);
3373 SET_SPRITE(city.size_tens[i], buffer);
3374 fc_snprintf(buffer2, sizeof(buffer2), "path.turns_%d0", i);
3375 SET_SPRITE_ALT(path.s[GTS_MP_LEFT].turns_tens[i], buffer2, buffer);
3377 SET_GOTO_TURN_SPRITE(GTS_EXHAUSTED_MP, "exhausted_mp", 0, _tens);
3378
3379 fc_snprintf(buffer, sizeof(buffer), "city.size_%d00", i);
3380 SET_SPRITE_OPT(city.size_hundreds[i], buffer);
3381 fc_snprintf(buffer2, sizeof(buffer2), "path.turns_%d00", i);
3382 SET_SPRITE_ALT_OPT(path.s[GTS_MP_LEFT].turns_hundreds[i], buffer2,
3383 buffer);
3385 SET_GOTO_TURN_SPRITE(GTS_EXHAUSTED_MP, "exhausted_mp", 00, _hundreds);
3386
3387 fc_snprintf(buffer, sizeof(buffer), "city.t_food_%d", i);
3388 SET_SPRITE(city.tile_foodnum[i], buffer);
3389 fc_snprintf(buffer, sizeof(buffer), "city.t_shields_%d", i);
3390 SET_SPRITE(city.tile_shieldnum[i], buffer);
3391 fc_snprintf(buffer, sizeof(buffer), "city.t_trade_%d", i);
3392 SET_SPRITE(city.tile_tradenum[i], buffer);
3393 }
3394#undef SET_GOTO_TURN_SPRITE
3395
3396 /* Must have at least one upkeep sprite per output type (and unhappy) */
3397 /* The rest are optional; we copy the previous sprite for unspecified ones */
3398 fc_strlcpy(buffer, "upkeep.unhappy", sizeof(buffer));
3399 SET_SPRITE(upkeep.unhappy[0], buffer);
3400 for (i = 1; i < MAX_NUM_UPKEEP_SPRITES; i++) {
3401 fc_snprintf(buffer2, sizeof(buffer2), "upkeep.unhappy%d", i+1);
3402 if (sprite_exists(t, buffer2)) {
3403 SET_SPRITE(upkeep.unhappy[i], buffer2);
3404 fc_strlcpy(buffer, buffer2, sizeof(buffer));
3405 } else {
3406 SET_SPRITE(upkeep.unhappy[i], buffer);
3407 }
3408 }
3410 fc_snprintf(buffer, sizeof(buffer),
3411 "upkeep.%s", get_output_identifier(o));
3412 SET_SPRITE_OPT(upkeep.output[o][0], buffer);
3413 for (i = 1; i < MAX_NUM_UPKEEP_SPRITES; i++) {
3414 fc_snprintf(buffer2, sizeof(buffer2),
3415 "upkeep.%s%d", get_output_identifier(o), i+1);
3416 if (sprite_exists(t, buffer2)) {
3417 SET_SPRITE(upkeep.output[o][i], buffer2);
3418 fc_strlcpy(buffer, buffer2, sizeof(buffer));
3419 } else {
3420 /* Optional, as maybe the upkeep 1 sprite didn't exist either */
3421 SET_SPRITE_OPT(upkeep.output[o][i], buffer);
3422 }
3423 }
3425
3427
3428 SET_SPRITE(user.attention, "user.attention");
3429 SET_SPRITE(user.infratile, "user.infratile");
3430
3431 SET_SPRITE_OPT(path.s[GTS_MP_LEFT].specific, "path.normal");
3432 SET_SPRITE_OPT(path.s[GTS_EXHAUSTED_MP].specific, "path.exhausted_mp");
3433 SET_SPRITE_OPT(path.s[GTS_TURN_STEP].specific, "path.step");
3434 SET_SPRITE(path.waypoint, "path.waypoint");
3435
3436 SET_SPRITE_NOTSMOOTH(tx.fog, "tx.fog");
3437
3439 for (i = 0; ; i++) {
3440 struct sprite *sprite;
3441
3442 fc_snprintf(buffer, sizeof(buffer), "colors.overlay_%d", i);
3443 sprite = load_sprite(t, buffer, TRUE, TRUE, FALSE);
3444 if (!sprite) {
3445 break;
3446 }
3448 }
3449 if (i == 0) {
3451 _("Missing overlay-color sprite colors.overlay_0."));
3452 }
3453
3454 /* Chop up and build the overlay graphics. */
3459 for (i = 0; i < sprite_vector_size(&t->sprites.colors.overlays); i++) {
3460 struct sprite *color, *color_mask;
3461 struct sprite *worked, *unworked;
3462
3464 color_mask = crop_sprite(color, 0, 0, W, H, t->sprites.mask.tile, 0, 0,
3465 1.0f, FALSE);
3466 worked = crop_sprite(color_mask, 0, 0, W, H,
3467 t->sprites.mask.worked_tile, 0, 0, 1.0f, FALSE);
3468 unworked = crop_sprite(color_mask, 0, 0, W, H,
3469 t->sprites.mask.unworked_tile, 0, 0, 1.0f, FALSE);
3471 t->sprites.city.worked_tile_overlay.p[i] = worked;
3473 }
3474
3475
3476 {
3477 SET_SPRITE(grid.unavailable, "grid.unavailable");
3478 SET_SPRITE_OPT(grid.nonnative, "grid.nonnative");
3479
3480 for (i = 0; i < EDGE_COUNT; i++) {
3481 int be;
3482
3483 if (i == EDGE_UD && t->hex_width == 0) {
3484 continue;
3485 } else if (i == EDGE_LR && t->hex_height == 0) {
3486 continue;
3487 }
3488
3489 fc_snprintf(buffer, sizeof(buffer), "grid.main.%s", edge_name[i]);
3490 SET_SPRITE(grid.main[i], buffer);
3491
3492 fc_snprintf(buffer, sizeof(buffer), "grid.city.%s", edge_name[i]);
3493 SET_SPRITE(grid.city[i], buffer);
3494
3495 fc_snprintf(buffer, sizeof(buffer), "grid.worked.%s", edge_name[i]);
3496 SET_SPRITE(grid.worked[i], buffer);
3497
3498 fc_snprintf(buffer, sizeof(buffer), "grid.selected.%s", edge_name[i]);
3499 SET_SPRITE(grid.selected[i], buffer);
3500
3501 fc_snprintf(buffer, sizeof(buffer), "grid.coastline.%s", edge_name[i]);
3502 SET_SPRITE(grid.coastline[i], buffer);
3503
3504 for (be = 0; be < 2; be++) {
3505 fc_snprintf(buffer, sizeof(buffer), "grid.borders.%c",
3506 edge_name[i][be]);
3507 SET_SPRITE(grid.borders[i][be], buffer);
3508 }
3509 }
3510 }
3511
3512 switch (t->darkness_style) {
3513 case DARKNESS_NONE:
3514 /* Nothing. */
3515 break;
3516 case DARKNESS_ISORECT:
3517 {
3518 /* Isometric: take a single tx.darkness tile and split it into 4. */
3519 struct sprite *darkness = load_sprite(t, "tx.darkness",
3520 TRUE, FALSE, FALSE);
3521 const int ntw = t->normal_tile_width, nth = t->normal_tile_height;
3522 int offsets[4][2] = {{ntw / 2, 0}, {0, nth / 2}, {ntw / 2, nth / 2}, {0, 0}};
3523
3524 if (!darkness) {
3526 _("Sprite tx.darkness missing."));
3527 }
3528 for (i = 0; i < 4; i++) {
3529 t->sprites.tx.darkness[i] = crop_sprite(darkness, offsets[i][0],
3530 offsets[i][1], ntw / 2,
3531 nth / 2, NULL, 0, 0, 1.0f,
3532 FALSE);
3533 }
3534 }
3535 break;
3537 for (i = 0; i < t->num_cardinal_tileset_dirs; i++) {
3538 enum direction8 dir = t->cardinal_tileset_dirs[i];
3539
3540 fc_snprintf(buffer, sizeof(buffer), "tx.darkness_%s",
3542 SET_SPRITE_NOTSMOOTH(tx.darkness[i], buffer);
3543 }
3544 break;
3545 case DARKNESS_CARD_FULL:
3546 for (i = 1; i < t->num_index_cardinal; i++) {
3547 fc_snprintf(buffer, sizeof(buffer), "tx.darkness_%s",
3548 cardinal_index_str(t, i));
3549 SET_SPRITE_NOTSMOOTH(tx.darkness[i], buffer);
3550 }
3551 break;
3552 case DARKNESS_CORNER:
3554 81 * sizeof(*t->sprites.tx.fullfog));
3555 for (i = 0; i < 81; i++) {
3556 /* Unknown, fog, known. */
3557 char ids[] = {'u', 'f', 'k'};
3558 char buf[512] = "t.fog";
3559 int values[4], vi, k = i;
3560
3561 for (vi = 0; vi < 4; vi++) {
3562 values[vi] = k % 3;
3563 k /= 3;
3564
3565 cat_snprintf(buf, sizeof(buf), "_%c", ids[values[vi]]);
3566 }
3567 fc_assert(k == 0);
3568
3570 }
3571 break;
3572 };
3573
3574 /* no other place to initialize these variables */
3577}
3578
3579/************************************************************************/
3582static bool load_river_sprites(struct tileset *t,
3583 struct river_sprites *store, const char *tag_pfx)
3584{
3585 int i;
3586 char buffer[512];
3587
3588 for (i = 0; i < t->num_index_cardinal; i++) {
3589 fc_snprintf(buffer, sizeof(buffer), "%s_s_%s",
3591 store->spec[i] = load_sprite(t, buffer, TRUE, TRUE, FALSE);
3592 if (store->spec[i] == NULL) {
3593 return FALSE;
3594 }
3595 }
3596
3597 for (i = 0; i < t->num_cardinal_tileset_dirs; i++) {
3598 fc_snprintf(buffer, sizeof(buffer), "%s_outlet_%s",
3600 store->outlet[i] = load_sprite(t, buffer, TRUE, TRUE, FALSE);
3601 if (store->outlet[i] == NULL) {
3602 log_error("Missing \"%s\" for \"%s\".", buffer, tag_pfx);
3603 return FALSE;
3604 }
3605 }
3606
3607 return TRUE;
3608}
3609
3610/************************************************************************/
3617{
3619 if (sf->big_sprite) {
3620 free_sprite(sf->big_sprite);
3621 sf->big_sprite = NULL;
3622 }
3624}
3625
3626/************************************************************************/
3637
3638/************************************************************************/
3644 enum log_level level,
3645 const char *tag, const char *alt,
3646 const char *alt2,
3647 const char *what, const char *name,
3648 bool scale)
3649{
3650 struct sprite *sp;
3651
3652 /* (Should get sprite_hash before connection) */
3654 "attempt to lookup for %s \"%s\" before "
3655 "sprite_hash setup", what, name);
3656
3657 sp = load_sprite(t, tag, scale, TRUE, FALSE);
3658 if (sp) return sp;
3659
3660 sp = load_sprite(t, alt, scale, TRUE, FALSE);
3661 if (sp) {
3662 log_verbose("Using alternate graphic \"%s\" "
3663 "(instead of \"%s\") for %s \"%s\".",
3664 alt, tag, what, name);
3665 return sp;
3666 }
3667
3668 if (alt2 != NULL) {
3669 sp = load_sprite(t, alt2, scale, TRUE, FALSE);
3670 if (sp) {
3671 log_verbose("Using second alternate graphic \"%s\" "
3672 "(instead of \"%s\" or \"%s\") for %s \"%s\".",
3673 alt2, tag, alt, what, name);
3674 return sp;
3675 }
3676 }
3677
3679 _("Don't have graphics tags \"%s\" or \"%s\" for %s \"%s\"."),
3680 tag, alt, what, name);
3681
3682 return NULL;
3683}
3684
3685/************************************************************************/
3690 int uidx,
3691 const char *base_str,
3692 enum direction8 dir,
3693 enum unit_activity activity,
3694 bool has_icon)
3695{
3696 enum direction8 loaddir = dir;
3697 char buf[2048];
3698 const char *act_name = unit_activity_name(activity);
3699
3700 if (act_name == NULL) {
3701 /* gcc-9 thinks this is possible. */
3702 return FALSE;
3703 }
3704
3705 /*
3706 * There may be more orientations available in this tileset than are
3707 * needed, if an oriented unit set has been reused between tilesets.
3708 *
3709 * Don't bother loading unused ones, unless they might be used by
3710 * unit_default_orientation (logic here mirrors get_unittype_sprite()).
3711 */
3712 if (!(dir == t->unit_default_orientation && !has_icon)
3713 && !is_valid_tileset_dir(t, dir)) {
3714 /* Instead we copy a nearby valid dir's sprite, so we're not caught
3715 * out in case this tileset is used with an incompatible topology,
3716 * although it'll be ugly. */
3717 do {
3719 /* This loop _should_ terminate... */
3721 } while (!is_valid_tileset_dir(t, loaddir));
3722 }
3723
3724 fc_snprintf(buf, sizeof(buf), "%s_%s_%s", base_str,
3726
3727 /* We don't use _alt graphics here, as that could lead to loading
3728 * real icon gfx, but alternative orientation gfx. Tileset author
3729 * probably meant icon gfx to be used as fallback for all orientations */
3730 t->sprites.units.facing[uidx][dir][activity] = load_sprite(t, buf,
3731 TRUE, TRUE, FALSE);
3732
3733 if (activity == ACTIVITY_IDLE
3734 && t->sprites.units.facing[uidx][dir][activity] == NULL) {
3735 /* Backward compatibility: Set Idle sprite from tag with no activity defined. */
3736 fc_snprintf(buf, sizeof(buf), "%s_%s", base_str,
3738
3739 t->sprites.units.facing[uidx][dir][activity] = load_sprite(t, buf,
3740 TRUE, TRUE, FALSE);
3741 }
3742
3743 if (t->sprites.units.facing[uidx][dir][activity] != NULL) {
3744 return TRUE;
3745 }
3746
3747 return FALSE;
3748}
3749
3750/************************************************************************/
3754 int uidx,
3755 const char *tag)
3756{
3758
3759 activity_type_iterate(activity) {
3760 char buffer[2048];
3761
3762 fc_snprintf(buffer, sizeof(buffer), "%s_%s",
3763 tag, unit_activity_name(activity));
3764 t->sprites.units.icon[uidx][activity] = load_sprite(t, buffer,
3765 TRUE, TRUE, FALSE);
3766
3767 if (activity == ACTIVITY_IDLE
3768 && t->sprites.units.icon[uidx][activity] == NULL) {
3769 /* Backward compatibility: Set Idle sprite from tag with no activity defined. */
3770 t->sprites.units.icon[uidx][activity] = load_sprite(t, tag,
3771 TRUE, TRUE, FALSE);
3772 }
3774
3776
3777#define LOAD_FACING_SPRITE(dir) \
3778 if (!tileset_setup_unit_direction(t, uidx, tag, dir, activity, has_icon)) { \
3779 facing_sprites[activity] = FALSE; \
3780 }
3781
3782 activity_type_iterate(activity) {
3783 facing_sprites[activity] = TRUE;
3784
3793
3795
3797 /* Neither icon gfx or orientation sprites */
3798 return FALSE;
3799 }
3800
3801 return TRUE;
3802
3803#undef LOAD_FACING_SPRITE
3804}
3805
3806/************************************************************************/
3811{
3812 int uidx = utype_index(ut);
3813
3814 if (!tileset_setup_unit_type_from_tag(t, uidx, ut->graphic_str)
3815 && !tileset_setup_unit_type_from_tag(t, uidx, ut->graphic_alt)
3816 && !tileset_setup_unit_type_from_tag(t, uidx, ut->graphic_alt2)) {
3818 _("Missing %s unit sprite for tags \"%s\" and alternatives "
3819 "\"%s\" and \"%s\"."),
3820 utype_rule_name(ut), ut->graphic_str,
3821 ut->graphic_alt, ut->graphic_alt2);
3822 }
3823
3824 if (!t->sprites.units.icon[uidx][ACTIVITY_IDLE]) {
3827 _("Unit type %s has no unoriented sprite and "
3828 "tileset has no unit_default_orientation."),
3830 } else {
3831 /* We're guaranteed to have an oriented sprite corresponding to
3832 * unit_default_orientation, because tileset_setup_unit_type_from_tag()
3833 * checked for this. */
3835 != NULL);
3836 }
3837 }
3838}
3839
3840/************************************************************************/
3845 struct impr_type *pimprove)
3846{
3847 t->sprites.building[improvement_index(pimprove)]
3849 pimprove->graphic_alt, pimprove->graphic_alt2,
3850 "improvement",
3851 improvement_rule_name(pimprove), FALSE);
3852
3853 /* Should maybe do something if NULL, eg generic default? */
3854}
3855
3856/************************************************************************/
3861 struct advance *padvance)
3862{
3863 if (valid_advance(padvance)) {
3866 padvance->graphic_alt, NULL, "technology",
3868
3869 /* Should maybe do something if NULL, eg generic default? */
3870 } else {
3872 }
3873}
3874
3875/************************************************************************/
3880 struct extra_type *pextra)
3881{
3882 const int id = extra_index(pextra);
3883 enum extrastyle_id extrastyle;
3884
3885 if (!fc_strcasecmp(pextra->graphic_str, "none")) {
3886 /* Extra without graphics */
3888 } else {
3889 const char *tag;
3890
3891 tag = pextra->graphic_str;
3892 if (!estyle_hash_lookup(t->estyle_hash, tag, &extrastyle)) {
3893 tag = pextra->graphic_alt;
3894 if (!estyle_hash_lookup(t->estyle_hash, tag, &extrastyle)) {
3896 _("No extra style for \"%s\" or \"%s\"."),
3897 pextra->graphic_str,
3898 pextra->graphic_alt);
3899 } else {
3900 log_verbose("Using alternate graphic \"%s\" "
3901 "(instead of \"%s\") for extra \"%s\".",
3902 pextra->graphic_alt, pextra->graphic_str,
3903 extra_rule_name(pextra));
3904 }
3905 }
3906
3907 t->sprites.extras[id].extrastyle = extrastyle;
3908
3909 extra_type_list_append(t->style_lists[extrastyle], pextra);
3910
3911 if (extra_has_flag(pextra, EF_SHOW_FLAG)) {
3913 }
3914
3915 switch (extrastyle) {
3916 case ESTYLE_3LAYER:
3917 tileset_setup_base(t, pextra, tag);
3918 break;
3919
3923 case ESTYLE_RIVER:
3924 tileset_setup_road(t, pextra, tag);
3925 break;
3926
3927 case ESTYLE_SINGLE1:
3928 case ESTYLE_SINGLE2:
3929 SET_SPRITE(extras[id].u.single, tag);
3930 break;
3931
3932 case ESTYLE_CARDINALS:
3933 {
3934 int i;
3935 char buffer[512];
3936
3937 /* We use direction-specific irrigation and farmland graphics, if they
3938 * are available. If not, we just fall back to the basic irrigation
3939 * graphics. */
3940 for (i = 0; i < t->num_index_cardinal; i++) {
3941 fc_snprintf(buffer, sizeof(buffer), "%s_%s",
3942 tag, cardinal_index_str(t, i));
3943 t->sprites.extras[id].u.cardinals[i] = load_sprite(t, buffer,
3944 TRUE, TRUE, FALSE);
3945 if (!t->sprites.extras[id].u.cardinals[i]) {
3946 t->sprites.extras[id].u.cardinals[i] = load_sprite(t, tag,
3947 TRUE, TRUE, FALSE);
3948 }
3949 if (!t->sprites.extras[id].u.cardinals[i]) {
3951 _("No cardinal-style graphics \"%s*\" for "
3952 "extra \"%s\""),
3953 tag, extra_rule_name(pextra));
3954 }
3955 }
3956 }
3957 break;
3958 case ESTYLE_COUNT:
3959 break;
3960 }
3961 }
3962
3963 if (!fc_strcasecmp(pextra->activity_gfx, "none")) {
3965 } else {
3967 TRUE, TRUE, FALSE);
3968 if (t->sprites.extras[id].activity == NULL) {
3970 TRUE, TRUE, FALSE);
3971 }
3972 if (t->sprites.extras[id].activity == NULL) {
3974 TRUE, TRUE, FALSE);
3975 }
3976 if (t->sprites.extras[id].activity == NULL) {
3978 _("Missing %s building activity sprite for tags \"%s\" and alternatives \"%s\" and \"%s\"."),
3979 extra_rule_name(pextra), pextra->activity_gfx,
3980 pextra->act_gfx_alt, pextra->act_gfx_alt2);
3981 }
3982 }
3983
3984 if (!fc_strcasecmp(pextra->rmact_gfx, "none")) {
3985 t->sprites.extras[id].rmact = NULL;
3986 } else {
3987 t->sprites.extras[id].rmact = load_sprite(t, pextra->rmact_gfx,
3988 TRUE, TRUE, FALSE);
3989 if (t->sprites.extras[id].rmact == NULL) {
3991 TRUE, TRUE, FALSE);
3992 if (t->sprites.extras[id].rmact == NULL) {
3994 TRUE, TRUE, FALSE);
3995 if (t->sprites.extras[id].rmact == NULL) {
3997 _("Missing %s removal activity sprite for tags \"%s\" "
3998 "and alternatives \"%s\" and \"%s\"."),
3999 extra_rule_name(pextra), pextra->rmact_gfx,
4000 pextra->rmact_gfx_alt, pextra->rmact_gfx_alt2);
4001 }
4002 }
4003 }
4004 }
4005}
4006
4007/************************************************************************/
4011static void tileset_setup_road(struct tileset *t,
4012 struct extra_type *pextra,
4013 const char *tag)
4014{
4015 char full_tag_name[MAX_LEN_NAME + sizeof("_isolated")];
4016 const int id = extra_index(pextra);
4017 int i;
4018 enum extrastyle_id extrastyle = t->sprites.extras[id].extrastyle;
4019
4020 /* Isolated road graphics are used by ESTYLE_ROAD_ALL_SEPARATE and
4021 ESTYLE_ROAD_PARITY_COMBINED. */
4022 if (extrastyle == ESTYLE_ROAD_ALL_SEPARATE
4023 || extrastyle == ESTYLE_ROAD_PARITY_COMBINED) {
4025 "%s_isolated", tag);
4026
4027 SET_SPRITE(extras[id].u.road.isolated, full_tag_name);
4028 }
4029
4030 if (extrastyle == ESTYLE_ROAD_ALL_SEPARATE) {
4031 /* ESTYLE_ROAD_ALL_SEPARATE has just 8 additional sprites for each
4032 * road type: one going off in each direction. */
4033 for (i = 0; i < t->num_valid_tileset_dirs; i++) {
4034 enum direction8 dir = t->valid_tileset_dirs[i];
4035 const char *dir_name = dir_get_tileset_name(dir);
4036
4038 "%s_%s", tag, dir_name);
4039
4040 SET_SPRITE(extras[id].u.road.ru.dir[i], full_tag_name);
4041 }
4042 } else if (extrastyle == ESTYLE_ROAD_PARITY_COMBINED) {
4043 int num_index = 1 << (t->num_valid_tileset_dirs / 2), j;
4044
4045 /* ESTYLE_ROAD_PARITY_COMBINED has 32 additional sprites for each road
4046 * type: 16 each for cardinal and diagonal directions. Each set
4047 * of 16 provides a NSEW-indexed sprite to provide connectors for
4048 * all rails in the cardinal/diagonal directions. The 0 entry is
4049 * unused (the "isolated" sprite is used instead). */
4050
4051 for (i = 1; i < num_index; i++) {
4052 char c[64] = "", d[64] = "";
4053
4054 for (j = 0; j < t->num_valid_tileset_dirs / 2; j++) {
4055 int value = (i >> j) & 1;
4056
4057 cat_snprintf(c, sizeof(c), "%s%d",
4059 value);
4060 cat_snprintf(d, sizeof(d), "%s%d",
4062 value);
4063 }
4064
4066 "%s_c_%s", tag, c);
4067
4068 SET_SPRITE(extras[id].u.road.ru.combo.even[i], full_tag_name);
4069
4071 "%s_d_%s", tag, d);
4072
4073 SET_SPRITE(extras[id].u.road.ru.combo.odd[i], full_tag_name);
4074 }
4075 } else if (extrastyle == ESTYLE_ROAD_ALL_COMBINED) {
4076 /* ESTYLE_ROAD_ALL_COMBINED includes 256 sprites, one for every possibility.
4077 * Just go around clockwise, with all combinations. */
4078 for (i = 0; i < t->num_index_valid; i++) {
4079 char *idx_str = valid_index_str(t, i);
4080
4082 "%s_%s", tag, idx_str);
4083
4084 SET_SPRITE(extras[id].u.road.ru.total[i], full_tag_name);
4085 }
4086 } else if (extrastyle == ESTYLE_RIVER) {
4087 if (!load_river_sprites(t, &t->sprites.extras[id].u.road.ru.rivers, tag)) {
4089 _("No river-style graphics \"%s*\" for extra \"%s\""),
4090 tag, extra_rule_name(pextra));
4091 }
4092 } else {
4094 }
4095
4096 /* Corner road graphics are used by ESTYLE_ROAD_ALL_SEPARATE,
4097 * ESTYLE_ROAD_PARITY_COMBINED and ESTYLE_ROAD_ALL_COMBINED. */
4098 if (extrastyle == ESTYLE_ROAD_ALL_SEPARATE
4099 || extrastyle == ESTYLE_ROAD_PARITY_COMBINED
4100 || extrastyle == ESTYLE_ROAD_ALL_COMBINED) {
4101 for (i = 0; i < t->num_valid_tileset_dirs; i++) {
4102 enum direction8 dir = t->valid_tileset_dirs[i];
4103
4104 if (!is_cardinal_tileset_dir(t, dir)) {
4105 const char *dtn = dir_get_tileset_name(dir);
4106
4108 "%s_c_%s", pextra->graphic_str, dtn);
4109
4110 SET_SPRITE_OPT(extras[id].u.road.corner[dir], full_tag_name);
4111 }
4112 }
4113 }
4114}
4115
4116/************************************************************************/
4120static void tileset_setup_base(struct tileset *t,
4121 const struct extra_type *pextra,
4122 const char *tag)
4123{
4124 char full_tag_name[MAX_LEN_NAME + sizeof("_fg")];
4125 const int id = extra_index(pextra);
4126
4127 fc_assert_ret(id >= 0 && id < extra_count());
4128
4130 strcat(full_tag_name, "_bg");
4132 TRUE, TRUE, FALSE);
4133
4135 strcat(full_tag_name, "_mg");
4137 TRUE, TRUE, FALSE);
4138
4140 strcat(full_tag_name, "_fg");
4142 TRUE, TRUE, FALSE);
4143
4144 if (t->sprites.extras[id].u.bmf.background == NULL
4145 && t->sprites.extras[id].u.bmf.middleground == NULL
4146 && t->sprites.extras[id].u.bmf.foreground == NULL) {
4147 /* There was an extra style definition but no matching graphics */
4149 _("No graphics with tag \"%s_bg/mg/fg\" for extra \"%s\""),
4150 tag, extra_rule_name(pextra));
4151 }
4152}
4153
4154/************************************************************************/
4159 const struct terrain *pterrain)
4160{
4161 struct drawing_data *draw;
4162 struct sprite *sprite;
4163 char buffer[MAX_LEN_NAME + 20];
4164 int i, l;
4165
4166 if (!drawing_hash_lookup(t->tile_hash, pterrain->graphic_str, &draw)
4167 && !drawing_hash_lookup(t->tile_hash, pterrain->graphic_alt, &draw)
4168 && !drawing_hash_lookup(t->tile_hash, pterrain->graphic_alt2, &draw)) {
4170 _("Terrain \"%s\": no graphic tile \"%s\", \"%s\", or \"%s\"."),
4171 terrain_rule_name(pterrain), pterrain->graphic_str,
4172 pterrain->graphic_alt, pterrain->graphic_alt2);
4173 }
4174
4175 if (draw->init) {
4176 t->sprites.drawing[terrain_index(pterrain)] = draw;
4177 return;
4178 }
4179
4180 /* Set up each layer of the drawing. */
4181 for (l = 0; l < draw->num_layers; l++) {
4182 struct drawing_layer *dlp = &draw->layer[l];
4183 struct tileset_layer *tslp = &t->layers[l];
4184 sprite_vector_init(&dlp->base);
4185 sprite_vector_init(&dlp->allocated);
4186
4187 switch (dlp->sprite_type) {
4188 case CELL_WHOLE:
4189 switch (dlp->match_style) {
4190 case MATCH_NONE:
4191 /* Load whole sprites for this tile. */
4192 for (i = 0; ; i++) {
4193 fc_snprintf(buffer, sizeof(buffer), "t.l%d.%s%d",
4194 l, draw->name, i + 1);
4195 sprite = load_sprite(t, buffer, TRUE, FALSE, FALSE);
4196 if (!sprite) {
4197 break;
4198 }
4199 sprite_vector_reserve(&dlp->base, i + 1);
4200 dlp->base.p[i] = sprite;
4201 }
4202 /* Check for base sprite, allowing missing sprites above base */
4203 if (0 == i && 0 == l) {
4204 /* TRANS: 'base' means 'base of terrain gfx', not 'military base' */
4206 _("Missing base sprite for tag \"%s\"."), buffer);
4207 }
4208 break;
4209 case MATCH_SAME:
4210 /* Load 16 cardinally-matched sprites. */
4211 for (i = 0; i < t->num_index_cardinal; i++) {
4212 fc_snprintf(buffer, sizeof(buffer), "t.l%d.%s_%s",
4213 l, draw->name, cardinal_index_str(t, i));
4214 dlp->match[i]
4215 = tiles_lookup_sprite_tag_alt(t, LOG_FATAL, buffer, "",
4216 NULL, "matched terrain",
4217 terrain_rule_name(pterrain), TRUE);
4218 }
4219 break;
4220 case MATCH_PAIR:
4221 case MATCH_FULL:
4222 fc_assert(FALSE); /* Not yet defined */
4223 break;
4224 };
4225 break;
4226 case CELL_CORNER:
4227 {
4228 const int count = dlp->match_indices;
4229 int number = NUM_CORNER_DIRS;
4230
4231 switch (dlp->match_style) {
4232 case MATCH_NONE:
4233 /* Do nothing */
4234 break;
4235 case MATCH_PAIR:
4236 case MATCH_SAME:
4237 /* N directions (NSEW) * 3 dimensions of matching */
4238 fc_assert(count == 2);
4239 number = NUM_CORNER_DIRS * 2 * 2 * 2;
4240 break;
4241 case MATCH_FULL:
4242 default:
4243 /* N directions (NSEW) * 3 dimensions of matching */
4244 /* could use exp() or expi() here? */
4245 number = NUM_CORNER_DIRS * count * count * count;
4246 break;
4247 };
4248
4249 dlp->cells
4250 = fc_calloc(number, sizeof(*dlp->cells));
4251
4252 for (i = 0; i < number; i++) {
4253 enum direction4 dir = i % NUM_CORNER_DIRS;
4254 int value = i / NUM_CORNER_DIRS;
4255
4256 switch (dlp->match_style) {
4257 case MATCH_NONE:
4258 fc_snprintf(buffer, sizeof(buffer), "t.l%d.%s_cell_%c",
4259 l, draw->name, direction4letters[dir]);
4260 dlp->cells[i]
4261 = tiles_lookup_sprite_tag_alt(t, LOG_FATAL, buffer, "",
4262 NULL, "cell terrain",
4263 terrain_rule_name(pterrain), TRUE);
4264 break;
4265 case MATCH_SAME:
4266 fc_snprintf(buffer, sizeof(buffer), "t.l%d.%s_cell_%c%d%d%d",
4267 l, draw->name, direction4letters[dir],
4268 (value) & 1, (value >> 1) & 1, (value >> 2) & 1);
4269 dlp->cells[i]
4270 = tiles_lookup_sprite_tag_alt(t, LOG_FATAL, buffer, "",
4271 NULL, "same cell terrain",
4272 terrain_rule_name(pterrain), TRUE);
4273 break;
4274 case MATCH_PAIR:
4275 fc_snprintf(buffer, sizeof(buffer), "t.l%d.%s_cell_%c_%c_%c_%c",
4276 l, draw->name, direction4letters[dir],
4277 tslp->match_types[dlp->match_index[(value) & 1]][0],
4278 tslp->match_types[dlp->match_index[(value >> 1) & 1]][0],
4279 tslp->match_types[dlp->match_index[(value >> 2) & 1]][0]);
4280 dlp->cells[i]
4281 = tiles_lookup_sprite_tag_alt(t, LOG_FATAL, buffer, "",
4282 NULL, "cell pair terrain",
4283 terrain_rule_name(pterrain), TRUE);
4284 break;
4285 case MATCH_FULL:
4286 {
4287 int this = dlp->match_index[0];
4288 int n, s, e, w;
4289 int v1, v2, v3;
4290
4291 v1 = dlp->match_index[value % count];
4292 value /= count;
4293 v2 = dlp->match_index[value % count];
4294 value /= count;
4295 v3 = dlp->match_index[value % count];
4296
4297 fc_assert(v1 < count && v2 < count && v3 < count);
4298
4299 /* Assume merged cells. This should be a separate option. */
4300 switch (dir) {
4301 case DIR4_NORTH:
4302 s = this;
4303 w = v1;
4304 n = v2;
4305 e = v3;
4306 break;
4307 case DIR4_EAST:
4308 w = this;
4309 n = v1;
4310 e = v2;
4311 s = v3;
4312 break;
4313 case DIR4_SOUTH:
4314 n = this;
4315 e = v1;
4316 s = v2;
4317 w = v3;
4318 break;
4319 case DIR4_WEST:
4320 default: /* Avoid warnings */
4321 e = this;
4322 s = v1;
4323 w = v2;
4324 n = v3;
4325 break;
4326 };
4327
4328 /* Use first character of match_types,
4329 * already checked for uniqueness. */
4330 fc_snprintf(buffer, sizeof(buffer),
4331 "t.l%d.cellgroup_%c_%c_%c_%c", l,
4332 tslp->match_types[n][0], tslp->match_types[e][0],
4333 tslp->match_types[s][0], tslp->match_types[w][0]);
4334 sprite = load_sprite(t, buffer, TRUE, FALSE, FALSE);
4335
4336 if (sprite) {
4337 /* Crop the sprite to separate this cell. */
4338 int vec_size = sprite_vector_size(&dlp->allocated);
4339
4340 const int W = t->normal_tile_width;
4341 const int H = t->normal_tile_height;
4342 int x[4] = {W / 4, W / 4, 0, W / 2};
4343 int y[4] = {H / 2, 0, H / 4, H / 4};
4344 int xo[4] = {0, 0, -W / 2, W / 2};
4345 int yo[4] = {H / 2, -H / 2, 0, 0};
4346
4347 sprite = crop_sprite(sprite, x[dir], y[dir], W / 2, H / 2,
4348 t->sprites.mask.tile, xo[dir], yo[dir], 1.0f,
4349 FALSE);
4350 /* We allocated new sprite with crop_sprite. Store its
4351 * address so we can free it. */
4352 sprite_vector_reserve(&dlp->allocated, vec_size + 1);
4353 dlp->allocated.p[vec_size] = sprite;
4354 } else {
4355 log_error("Terrain graphics sprite for tag \"%s\" missing.", buffer);
4356 }
4357
4358 dlp->cells[i] = sprite;
4359 }
4360 break;
4361 };
4362 }
4363 }
4364 break;
4365 };
4366 }
4367
4368 /* Try an optional special name */
4369 fc_snprintf(buffer, sizeof(buffer), "t.blend.%s", draw->name);
4370 draw->blender
4372 NULL, "blend terrain",
4373 terrain_rule_name(pterrain), TRUE);
4374
4375 if (draw->blending > 0) {
4376 const int bl = draw->blending - 1;
4377
4378 if (NULL == draw->blender) {
4379 int li = 0;
4380
4381 /* Try an already loaded base */
4382 while (NULL == draw->blender
4383 && li < draw->blending
4384 && 0 < draw->layer[li].base.size) {
4385 draw->blender = draw->layer[li++].base.p[0];
4386 }
4387 }
4388
4389 if (NULL == draw->blender) {
4390 /* Try an unloaded base name */
4391 fc_snprintf(buffer, sizeof(buffer), "t.l%d.%s1", bl, draw->name);
4392 draw->blender
4393 = tiles_lookup_sprite_tag_alt(t, LOG_FATAL, buffer, "",
4394 NULL, "base (blend) terrain",
4395 terrain_rule_name(pterrain), TRUE);
4396 }
4397 }
4398
4399 if (NULL != draw->blender) {
4400 /* Set up blending sprites. This only works in iso-view! */
4401 const int W = t->normal_tile_width;
4402 const int H = t->normal_tile_height;
4403 const int offsets[4][2] = {
4404 {W / 2, 0}, {0, H / 2}, {W / 2, H / 2}, {0, 0}
4405 };
4406 enum direction4 dir = 0;
4407
4408 for (; dir < 4; dir++) {
4409 draw->blend[dir] = crop_sprite(draw->blender, offsets[dir][0],
4410 offsets[dir][1], W / 2, H / 2,
4411 t->sprites.dither_tile, 0, 0, 1.0f,
4412 FALSE);
4413 }
4414 }
4415
4416 draw->init = TRUE;
4417 t->sprites.drawing[terrain_index(pterrain)] = draw;
4418}
4419
4420/************************************************************************/
4425 struct government *gov)
4426{
4429 gov->graphic_alt, NULL, "government",
4431
4432 /* Should probably do something if NULL, eg generic default? */
4433}
4434
4435/************************************************************************/
4440 struct nation_type *nation)
4441{
4442 char *tags[] = {nation->flag_graphic_str,
4443 nation->flag_graphic_alt,
4444 "unknown", NULL};
4445 int i;
4446 struct sprite *flag = NULL, *shield = NULL;
4447 char buf[1024];
4449
4450 for (i = 0; tags[i] && !flag; i++) {
4451 fc_snprintf(buf, sizeof(buf), "f.%s", tags[i]);
4452 flag = load_sprite(t, buf, TRUE, TRUE, svgflag);
4453 }
4454 for (i = 0; tags[i] && !shield; i++) {
4455 fc_snprintf(buf, sizeof(buf), "f.shield.%s", tags[i]);
4456 shield = load_sprite(t, buf, TRUE, TRUE, svgflag);
4457 }
4458 if (!flag || !shield) {
4459 /* Should never get here because of the f.unknown fallback. */
4461 _("Nation %s: no national flag."), nation_rule_name(nation));
4462 }
4463
4465 t->sprites.nation_flag.p[nation_index(nation)] = flag;
4466
4468 t->sprites.nation_shield.p[nation_index(nation)] = shield;
4469}
4470
4471/************************************************************************/
4474struct sprite *get_city_flag_sprite(const struct tileset *t,
4475 const struct city *pcity)
4476{
4477 return get_nation_flag_sprite(t, nation_of_city(pcity));
4478}
4479
4480/************************************************************************/
4483static struct sprite *get_unit_nation_flag_sprite(const struct tileset *t,
4484 const struct unit *punit)
4485{
4486 struct nation_type *pnation = nation_of_unit(punit);
4487
4489 return t->sprites.nation_shield.p[nation_index(pnation)];
4490 } else {
4491 return t->sprites.nation_flag.p[nation_index(pnation)];
4492 }
4493}
4494
4495#define FULL_TILE_X_OFFSET ((t->normal_tile_width - t->full_tile_width) / 2)
4496#define FULL_TILE_Y_OFFSET (t->normal_tile_height - t->full_tile_height)
4497
4498#define ADD_SPRITE_SIZE(s, draw_fog, x_offset, y_offset, w_in, h_in) \
4499 (fc_assert(s != NULL), \
4500 sprs->sprite = s, \
4501 sprs->foggable = (draw_fog && t->fogstyle == FOG_AUTO), \
4502 sprs->offset_x = x_offset, \
4503 sprs->offset_y = y_offset, \
4504 sprs->w = w_in, \
4505 sprs->h = h_in, \
4506 sprs++)
4507#define ADD_SPRITE(s, draw_fog, x_offset, y_offset) \
4508 ADD_SPRITE_SIZE(s, draw_fog, x_offset, y_offset, 0, 0)
4509#define ADD_SPRITE_SIMPLE(s) ADD_SPRITE(s, TRUE, 0, 0)
4510#define ADD_SPRITE_FULL(s) \
4511 ADD_SPRITE(s, TRUE, FULL_TILE_X_OFFSET, FULL_TILE_Y_OFFSET)
4512
4513/************************************************************************/
4520static void build_tile_data(const struct tile *ptile,
4521 struct terrain *pterrain,
4522 struct terrain **tterrain_near,
4524{
4525 enum direction8 dir;
4526
4527 /* Loop over all adjacent tiles. We should have an iterator for this. */
4528 for (dir = 0; dir < 8; dir++) {
4529 struct tile *tile1 = mapstep(&(wld.map), ptile, dir);
4530
4533
4534 if (NULL != terrain1) {
4535 tterrain_near[dir] = terrain1;
4537 continue;
4538 }
4539 log_error("build_tile_data() tile (%d,%d) has no terrain!",
4540 TILE_XY(tile1));
4541 }
4542 /* At the edges of the (known) map, pretend the same terrain continued
4543 * past the edge of the map. */
4544 tterrain_near[dir] = pterrain;
4546 }
4547}
4548
4549/************************************************************************/
4552static int fill_unit_type_sprite_array(const struct tileset *t,
4553 struct drawn_sprite *sprs,
4554 const struct unit_type *putype,
4555 enum unit_activity activity,
4556 enum direction8 facing)
4557{
4558 struct drawn_sprite *save_sprs = sprs;
4559 struct sprite *uspr = get_unittype_sprite(t, putype, activity, facing);
4560
4564
4565 return sprs - save_sprs;
4566}
4567
4568/************************************************************************/
4571static int fill_unit_sprite_array(const struct tileset *t,
4572 struct drawn_sprite *sprs,
4573 const struct unit *punit,
4574 int stack, bool backdrop)
4575{
4576 struct drawn_sprite *save_sprs = sprs;
4577 int ihp;
4578 const struct unit_type *ptype = unit_type_get(punit);
4579
4580 if (backdrop) {
4585 } else {
4586 /* Taken care of in the LAYER_BACKGROUND. */
4587 }
4588 }
4589
4590 /* Add the sprite for the unit type. */
4593
4594 if (t->sprites.unit.loaded && unit_transported(punit)) {
4595 ADD_SPRITE_FULL(t->sprites.unit.loaded);
4596 }
4597
4598 if (punit->activity != ACTIVITY_IDLE) {
4599 struct sprite *s = NULL;
4600
4601 switch (punit->activity) {
4602 case ACTIVITY_MINE:
4603 if (punit->activity_target == NULL) {
4604 s = t->sprites.unit.plant;
4605 } else {
4607 }
4608 break;
4609 case ACTIVITY_PLANT:
4610 s = t->sprites.unit.plant;
4611 break;
4612 case ACTIVITY_IRRIGATE:
4613 if (punit->activity_target == NULL) {
4614 s = t->sprites.unit.cultivate;
4615 } else {
4617 }
4618 break;
4619 case ACTIVITY_CULTIVATE:
4620 s = t->sprites.unit.cultivate;
4621 break;
4622 case ACTIVITY_CLEAN:
4624 break;
4625 case ACTIVITY_PILLAGE:
4627 if (s == NULL) {
4628 s = t->sprites.unit.pillage;
4629 }
4630 break;
4631 case ACTIVITY_EXPLORE:
4632 /* Drawn below as the server side agent. */
4633 break;
4634 case ACTIVITY_FORTIFIED:
4635 s = t->sprites.unit.fortified;
4636 break;
4638 s = t->sprites.unit.fortifying;
4639 break;
4640 case ACTIVITY_SENTRY:
4641 s = t->sprites.unit.sentry;
4642 break;
4643 case ACTIVITY_GOTO:
4644 s = t->sprites.unit.go_to;
4645 break;
4646 case ACTIVITY_TRANSFORM:
4647 s = t->sprites.unit.transform;
4648 break;
4649 case ACTIVITY_BASE:
4650 case ACTIVITY_GEN_ROAD:
4652 break;
4653 case ACTIVITY_CONVERT:
4654 s = t->sprites.unit.convert;
4655 break;
4656 default:
4657 break;
4658 }
4659
4660 if (s != NULL) {
4663 }
4664 }
4665
4666 {
4667 struct sprite *s = NULL;
4668 int offset_x = 0;
4669 int offset_y = 0;
4670
4671 switch (punit->ssa_controller) {
4672 case SSA_NONE:
4673 break;
4674 case SSA_AUTOSETTLER:
4675 s = t->sprites.unit.auto_settler;
4676 break;
4677 case SSA_AUTOEXPLORE:
4678 s = t->sprites.unit.auto_explore;
4679 /* Specified as an activity in the tileset. */
4682 break;
4683 default:
4684 s = t->sprites.unit.auto_attack;
4685 break;
4686 }
4687
4688 if (s != NULL) {
4689 ADD_SPRITE(s, TRUE,
4692 }
4693 }
4694
4695 if (unit_has_orders(punit)) {
4696 if (punit->orders.repeat) {
4697 ADD_SPRITE_FULL(t->sprites.unit.patrol);
4698 } else if (punit->activity != ACTIVITY_IDLE) {
4699 ADD_SPRITE_SIMPLE(t->sprites.unit.connect);
4700 } else {
4701 ADD_SPRITE(t->sprites.unit.go_to, TRUE,
4704 }
4705 }
4706
4707 if (t->sprites.unit.action_decision_want != NULL
4709 ADD_SPRITE(t->sprites.unit.action_decision_want, TRUE,
4712 }
4713
4715 ADD_SPRITE_FULL(t->sprites.unit.battlegroup[punit->battlegroup]);
4716 }
4717
4718 if (t->sprites.unit.lowfuel
4719 && utype_fuel(ptype)
4720 && punit->fuel == 1
4721 && punit->moves_left <= 2 * SINGLE_MOVE) {
4722 /* Show a low-fuel graphic if the plane has 2 or fewer moves left. */
4723 ADD_SPRITE_FULL(t->sprites.unit.lowfuel);
4724 }
4725 if (t->sprites.unit.tired
4727 && ptype->move_rate > 0) {
4728 /* Show a "tired" graphic if the unit has fewer than one move
4729 * remaining, except for units for which it's full movement. */
4730 ADD_SPRITE_FULL(t->sprites.unit.tired);
4731 }
4732
4733 if (stack == 1 && punit->client.occupied) {
4734 ADD_SPRITE_FULL(t->sprites.unit.stack[0]);
4735 } else if (stack > 1) {
4737 && t->sprites.unit.num_stack_sprites >= stack) {
4738 ADD_SPRITE(t->sprites.unit.stack[stack - 1], FALSE,
4740 } else {
4741 ADD_SPRITE_FULL(t->sprites.unit.stack[0]);
4742 }
4743 }
4744
4745 if (t->sprites.unit.vet_lev[punit->veteran]) {
4747 }
4748
4749 ihp = ((NUM_TILES_HP_BAR-1)*punit->hp) / ptype->hp;
4750 ihp = CLIP(0, ihp, NUM_TILES_HP_BAR-1);
4751 ADD_SPRITE_FULL(t->sprites.unit.hp_bar[ihp]);
4752
4753 return sprs - save_sprs;
4754}
4755
4756/************************************************************************/
4759static int fill_road_corner_sprites(const struct tileset *t,
4760 const struct extra_type *pextra,
4761 struct drawn_sprite *sprs,
4762 bool road, bool *road_near,
4763 bool hider, bool *hider_near)
4764{
4765 struct drawn_sprite *saved_sprs = sprs;
4766 int i;
4767 int extra_idx = extra_index(pextra);
4768
4769 if (is_cardinal_only_road(pextra)) {
4770 return 0;
4771 }
4772
4773 /* Roads going diagonally adjacent to this tile need to be
4774 * partly drawn on this tile. */
4775
4776 /* Draw the corner sprite if:
4777 * - There is a diagonal road (not rail!) between two adjacent tiles.
4778 * - There is no diagonal road (not rail!) that intersects this road.
4779 * The logic is simple: roads are drawn underneath railrods, but are
4780 * not always covered by them (even in the corners!). But if a railroad
4781 * connects two tiles, only the railroad (no road) is drawn between
4782 * those tiles.
4783 */
4784 for (i = 0; i < t->num_valid_tileset_dirs; i++) {
4785 enum direction8 dir = t->valid_tileset_dirs[i];
4786
4787 if (!is_cardinal_tileset_dir(t, dir)) {
4788 /* Draw corner sprites for this non-cardinal direction. */
4789 int cw = (i + 1) % t->num_valid_tileset_dirs;
4790 int ccw
4792 enum direction8 cwdir = t->valid_tileset_dirs[cw];
4794
4795 if (t->sprites.extras[extra_idx].u.road.corner[dir]
4797 && !(hider_near[cwdir] && hider_near[ccwdir]))
4798 && !(road && road_near[dir] && !(hider && hider_near[dir]))) {
4800 }
4801 }
4802 }
4803
4804 return sprs - saved_sprs;
4805}
4806
4807/************************************************************************/
4810static int fill_road_sprite_array(const struct tileset *t,
4811 const struct extra_type *pextra,
4812 struct drawn_sprite *sprs,
4815 struct terrain *tterrain_near[8],
4816 const struct city *pcity)
4817{
4818 struct drawn_sprite *saved_sprs = sprs;
4819 bool road, road_near[8], hider, hider_near[8];
4820 bool land_near[8], hland_near[8];
4821 bool draw_road[8], draw_single_road;
4822 enum direction8 dir;
4823 int extra_idx = -1;
4824 bool cl = FALSE;
4825 enum extrastyle_id extrastyle;
4826 const struct road_type *proad = extra_road_get(pextra);
4827
4828 extra_idx = extra_index(pextra);
4829
4830 extrastyle = t->sprites.extras[extra_idx].extrastyle;
4831
4832 if (extra_has_flag(pextra, EF_CONNECT_LAND)) {
4833 cl = TRUE;
4834 } else {
4835 int i;
4836
4837 for (i = 0; i < 8; i++) {
4838 land_near[i] = FALSE;
4839 }
4840 }
4841
4842 /* Fill some data arrays. rail_near and road_near store whether road/rail
4843 * is present in the given direction. draw_rail and draw_road store
4844 * whether road/rail is to be drawn in that direction. draw_single_road
4845 * and draw_single_rail store whether we need an isolated road/rail to be
4846 * drawn. */
4848
4849 hider = FALSE;
4852 hider = TRUE;
4853 break;
4854 }
4856
4857 if (road && (!pcity || !gui_options.draw_cities) && !hider) {
4859 } else {
4861 }
4862
4863 for (dir = 0; dir < 8; dir++) {
4864 bool roads_exist;
4865
4866 /* Check if there is adjacent road/rail. */
4867 if (!is_cardinal_only_road(pextra)
4868 || is_cardinal_tileset_dir(t, dir)) {
4869 road_near[dir] = FALSE;
4870 extra_type_list_iterate(proad->integrators, iextra) {
4872 road_near[dir] = TRUE;
4873 break;
4874 }
4876 if (cl) {
4877 land_near[dir] = (tterrain_near[dir] != T_UNKNOWN
4879 }
4880 } else {
4881 road_near[dir] = FALSE;
4882 land_near[dir] = FALSE;
4883 }
4884
4885 /* Draw rail/road if there is a connection from this tile to the
4886 * adjacent tile. But don't draw road if there is also a rail
4887 * connection. */
4888 roads_exist = road && (road_near[dir] || land_near[dir]);
4889 draw_road[dir] = roads_exist;
4890 hider_near[dir] = FALSE;
4891 hland_near[dir] = tterrain_near[dir] != T_UNKNOWN
4894 bool hider_dir = FALSE;
4895 bool land_dir = FALSE;
4896
4898 || is_cardinal_tileset_dir(t, dir)) {
4900 hider_near[dir] = TRUE;
4901 hider_dir = TRUE;
4902 }
4903 if (hland_near[dir]
4906 land_dir = TRUE;
4907 }
4908 if (hider_dir || land_dir) {
4910 draw_road[dir] = FALSE;
4911 }
4912 }
4913 }
4915
4916 /* Don't draw an isolated road/rail if there's any connection.
4917 * draw_single_road would be true in the first place only if start tile has road,
4918 * so it will have road connection with any adjacent road tile. We check from real
4919 * existence of road (road_near[dir]) and not from whether road gets drawn (draw_road[dir])
4920 * as latter can be FALSE when road is simply hidden by another one, and we don't want to
4921 * draw single road in that case either. */
4922 if (draw_single_road && road_near[dir]) {
4924 }
4925 }
4926
4927 /* Draw road corners */
4928 sprs
4930
4931 if (extrastyle == ESTYLE_ROAD_ALL_SEPARATE) {
4932 /* With ESTYLE_ROAD_ALL_SEPARATE, we simply draw one road for every connection.
4933 * This means we only need a few sprites, but a lot of drawing is
4934 * necessary and it generally doesn't look very good. */
4935 int i;
4936
4937 /* First draw roads under rails. */
4938 if (road) {
4939 for (i = 0; i < t->num_valid_tileset_dirs; i++) {
4940 if (draw_road[t->valid_tileset_dirs[i]]) {
4942 }
4943 }
4944 }
4945 } else if (extrastyle == ESTYLE_ROAD_PARITY_COMBINED) {
4946 /* With ESTYLE_ROAD_PARITY_COMBINED, we draw one sprite for cardinal
4947 * road connections, one sprite for diagonal road connections.
4948 * This means we need about 4x more sprites than in style 0, but up to
4949 * 4x less drawing is needed. The drawing quality may also be
4950 * improved. */
4951
4952 /* First draw roads under rails. */
4953 if (road) {
4954 int road_even_tileno = 0, road_odd_tileno = 0, i;
4955
4956 for (i = 0; i < t->num_valid_tileset_dirs / 2; i++) {
4957 enum direction8 even = t->valid_tileset_dirs[2 * i];
4958 enum direction8 odd = t->valid_tileset_dirs[2 * i + 1];
4959
4960 if (draw_road[even]) {
4961 road_even_tileno |= 1 << i;
4962 }
4963 if (draw_road[odd]) {
4964 road_odd_tileno |= 1 << i;
4965 }
4966 }
4967
4968 /* Draw the cardinal/even roads first. */
4969 if (road_even_tileno != 0) {
4971 }
4972 if (road_odd_tileno != 0) {
4974 }
4975 }
4976 } else if (extrastyle == ESTYLE_ROAD_ALL_COMBINED) {
4977 /* RSTYLE_ALL_COMBINED is a very simple method that lets us simply retrieve
4978 * entire finished tiles, with a bitwise index of the presence of
4979 * roads in each direction. */
4980
4981 /* Draw roads first */
4982 if (road) {
4983 int road_tileno = 0, i;
4984
4985 for (i = 0; i < t->num_valid_tileset_dirs; i++) {
4987
4988 if (draw_road[vdir]) {
4989 road_tileno |= 1 << i;
4990 }
4991 }
4992
4993 if (road_tileno != 0 || draw_single_road) {
4995 }
4996 }
4997 } else {
4999 }
5000
5001 /* Draw isolated rail/road separately (ESTYLE_ROAD_ALL_SEPARATE and
5002 ESTYLE_ROAD_PARITY_COMBINED only). */
5003 if (extrastyle == ESTYLE_ROAD_ALL_SEPARATE
5004 || extrastyle == ESTYLE_ROAD_PARITY_COMBINED) {
5005 if (draw_single_road) {
5007 }
5008 }
5009
5010 return sprs - saved_sprs;
5011}
5012
5013/************************************************************************/
5022static int get_irrigation_index(const struct tileset *t,
5023 struct extra_type *pextra,
5025{
5026 int tileno = 0, i;
5027
5028 for (i = 0; i < t->num_cardinal_tileset_dirs; i++) {
5029 enum direction8 dir = t->cardinal_tileset_dirs[i];
5030
5031 if (BV_ISSET(textras_near[dir], extra_index(pextra))) {
5032 tileno |= 1 << i;
5033 }
5034 }
5035
5036 return tileno;
5037}
5038
5039/************************************************************************/
5042static int fill_irrigation_sprite_array(const struct tileset *t,
5043 struct drawn_sprite *sprs,
5046 const struct city *pcity)
5047{
5048 struct drawn_sprite *saved_sprs = sprs;
5049
5050 /* We don't draw the irrigation if there's a city (it just gets overdrawn
5051 * anyway, and ends up looking bad). */
5052 if (!(pcity && gui_options.draw_cities)) {
5054 if (is_extra_drawing_enabled(pextra)) {
5055 int eidx = extra_index(pextra);
5056
5057 if (BV_ISSET(textras, eidx)) {
5058 bool hidden = FALSE;
5059
5060 extra_type_list_iterate(pextra->hiders, phider) {
5062 hidden = TRUE;
5063 break;
5064 }
5066
5067 if (!hidden) {
5068 int idx = get_irrigation_index(t, pextra, textras_near);
5069
5071 }
5072 }
5073 }
5075 }
5076
5077 return sprs - saved_sprs;
5078}
5079
5080/************************************************************************/
5084static int fill_city_overlays_sprite_array(const struct tileset *t,
5085 struct drawn_sprite *sprs,
5086 const struct tile *ptile,
5087 const struct city *citymode)
5088{
5089 const struct city *pcity;
5090 const struct city *pwork;
5091 struct unit *psettler;
5092 struct drawn_sprite *saved_sprs = sprs;
5093 int city_x, city_y;
5094 const int NUM_CITY_COLORS = t->sprites.city.worked_tile_overlay.size;
5095
5096 if (NULL == ptile || TILE_UNKNOWN == client_tile_get_known(ptile)) {
5097 return 0;
5098 }
5099 pwork = tile_worked(ptile);
5100
5101 if (citymode) {
5102 pcity = citymode;
5103 } else {
5105 }
5106
5107 /* Below code does not work if pcity is invisible.
5108 * Make sure it is not. */
5109 fc_assert_ret_val(pcity == NULL || pcity->tile != NULL, 0);
5110 if (pcity && !pcity->tile) {
5111 pcity = NULL;
5112 }
5113
5114 if (pcity && city_base_to_city_map(&city_x, &city_y, pcity, ptile)) {
5115 /* FIXME: check elsewhere for valid tile (instead of above) */
5116
5117 if (!citymode && pcity->client.colored) {
5118 /* Add citymap overlay for a city. */
5119 int idx = pcity->client.color_index % NUM_CITY_COLORS;
5120
5121 if (NULL != pwork && pwork == pcity) {
5123 } else if (city_can_work_tile(pcity, ptile)) {
5125 }
5126 } else if (NULL != pwork && pwork == pcity
5128
5129 /* Add on the tile output sprites.
5130 * NOTE: To show correct output on end of turn
5131 * base_city_celebrating() must be used instead of city_celebrating()
5132 * mirroring the behavior of the server that does so in
5133 * city_tile_cache_update(). */
5134 bool celebrating = base_city_celebrating(pcity);
5135 int food = city_tile_output(pcity, ptile, celebrating, O_FOOD);
5136 int shields = city_tile_output(pcity, ptile, celebrating, O_SHIELD);
5137 int trade = city_tile_output(pcity, ptile, celebrating, O_TRADE);
5138
5139 const int ox = t->type == TS_ISOMETRIC ? t->normal_tile_width / 3 : 0;
5140 const int oy = t->type == TS_ISOMETRIC ? -t->normal_tile_height / 3 : 0;
5141
5142 food = CLIP(0, food / game.info.granularity, NUM_TILES_DIGITS - 1);
5143 shields = CLIP(0, shields / game.info.granularity, NUM_TILES_DIGITS - 1);
5144 trade = CLIP(0, trade / game.info.granularity, NUM_TILES_DIGITS - 1);
5145
5147 ADD_SPRITE(t->sprites.city.tile_shieldnum[shields], TRUE, ox, oy);
5149 }
5150 } else if (psettler && psettler->client.colored) {
5151 /* Add citymap overlay for a unit. */
5152 int idx = psettler->client.color_index % NUM_CITY_COLORS;
5153
5155 }
5156
5157 return sprs - saved_sprs;
5158}
5159
5160/************************************************************************/
5164static int fill_terrain_sprite_blending(const struct tileset *t,
5165 struct drawn_sprite *sprs,
5166 const struct tile *ptile,
5167 const struct terrain *pterrain,
5168 struct terrain **tterrain_near)
5169{
5170 struct drawn_sprite *saved_sprs = sprs;
5171 const int W = t->normal_tile_width, H = t->normal_tile_height;
5172 const int offsets[4][2] = {
5173 {W/2, 0}, {0, H / 2}, {W / 2, H / 2}, {0, 0}
5174 };
5175 enum direction4 dir = 0;
5176
5177 /*
5178 * We want to mark unknown tiles so that an unreal tile will be
5179 * given the same marking as our current tile - that way we won't
5180 * get the "unknown" dither along the edge of the map.
5181 */
5182 for (; dir < 4; dir++) {
5183 struct tile *tile1 = mapstep(&(wld.map), ptile, DIR4_TO_DIR8[dir]);
5184 struct terrain *other;
5185
5186 if (!tile1
5188 || pterrain == (other = tterrain_near[DIR4_TO_DIR8[dir]])
5189 || (0 == t->sprites.drawing[terrain_index(other)]->blending
5190 && NULL == t->sprites.drawing[terrain_index(other)]->blender)) {
5191 continue;
5192 }
5193
5195 offsets[dir][0], offsets[dir][1]);
5196 }
5197
5198 return sprs - saved_sprs;
5199}
5200
5201/************************************************************************/
5204static int fill_fog_sprite_array(const struct tileset *t,
5205 struct drawn_sprite *sprs,
5206 const struct tile *ptile,
5207 const struct tile_edge *pedge,
5208 const struct tile_corner *pcorner)
5209{
5210 struct drawn_sprite *saved_sprs = sprs;
5211
5213 && NULL != ptile
5215 /* With FOG_AUTO, fog is done this way. */
5217 }
5218
5221 int i, tileno = 0;
5222
5223 for (i = 3; i >= 0; i--) {
5224 const int unknown = 0, fogged = 1, known = 2;
5225 int value = -1;
5226
5227 if (!pcorner->tile[i]) {
5228 value = fogged;
5229 } else {
5230 switch (client_tile_get_known(pcorner->tile[i])) {
5231 case TILE_KNOWN_SEEN:
5232 value = known;
5233 break;
5234 case TILE_KNOWN_UNSEEN:
5235 value = fogged;
5236 break;
5237 case TILE_UNKNOWN:
5238 value = unknown;
5239 break;
5240 }
5241 }
5242 fc_assert(value >= 0 && value < 3);
5243
5244 tileno = tileno * 3 + value;
5245 }
5246
5247 if (t->sprites.tx.fullfog[tileno]) {
5249 }
5250 }
5251
5252 return sprs - saved_sprs;
5253}
5254
5255/************************************************************************/
5259 struct drawn_sprite *sprs,
5260 int l, /* layer_num */
5261 const struct tile *ptile,
5262 const struct terrain *pterrain,
5263 struct terrain **tterrain_near,
5264 struct drawing_data *draw)
5265{
5266 struct drawn_sprite *saved_sprs = sprs;
5267 struct drawing_layer *dlp = &draw->layer[l];
5268 int this = dlp->match_index[0];
5269 int that = dlp->match_index[1];
5270 int ox = dlp->offset_x;
5271 int oy = dlp->offset_y;
5272 int i;
5273
5274#define MATCH(dir) \
5275 (t->sprites.drawing[terrain_index(tterrain_near[(dir)])]->num_layers > l \
5276 ? t->sprites.drawing[terrain_index(tterrain_near[(dir)])]->layer[l].match_index[0] \
5277 : -1)
5278
5279 switch (dlp->sprite_type) {
5280 case CELL_WHOLE:
5281 {
5282 switch (dlp->match_style) {
5283 case MATCH_NONE:
5284 {
5285 int count = sprite_vector_size(&dlp->base);
5286
5287 if (count > 0) {
5288 /* Pseudo-random reproducible algorithm to pick a sprite. Use modulo
5289 * to limit the number to a handleable size [0..32000). */
5290 count = fc_randomly(tile_index(ptile) % 32000, count);
5291
5292 if (dlp->is_tall) {
5295 }
5296 ADD_SPRITE(dlp->base.p[count], TRUE, ox, oy);
5297 }
5298 break;
5299 }
5300 case MATCH_SAME:
5301 {
5302 int tileno = 0;
5303
5304 for (i = 0; i < t->num_cardinal_tileset_dirs; i++) {
5305 enum direction8 dir = t->cardinal_tileset_dirs[i];
5306
5307 if (MATCH(dir) == this) {
5308 tileno |= 1 << i;
5309 }
5310 }
5311
5312 if (dlp->is_tall) {
5315 }
5316 ADD_SPRITE(dlp->match[tileno], TRUE, ox, oy);
5317 break;
5318 }
5319 case MATCH_PAIR:
5320 case MATCH_FULL:
5321 fc_assert(FALSE); /* Not yet defined */
5322 break;
5323 };
5324 break;
5325 }
5326 case CELL_CORNER:
5327 {
5328 /* Divide the tile up into four rectangular cells. Each of these
5329 * cells covers one corner, and each is adjacent to 3 different
5330 * tiles. For each cell we pick a sprite based upon the adjacent
5331 * terrains at each of those tiles. Thus, we have 8 different sprites
5332 * for each of the 4 cells (32 sprites total).
5333 *
5334 * These arrays correspond to the direction4 ordering. */
5335 const int W = t->normal_tile_width;
5336 const int H = t->normal_tile_height;
5337 const int iso_offsets[4][2] = {
5338 {W / 4, 0}, {W / 4, H / 2}, {W / 2, H / 4}, {0, H / 4}
5339 };
5340 const int noniso_offsets[4][2] = {
5341 {0, 0}, {W / 2, H / 2}, {W / 2, 0}, {0, H / 2}
5342 };
5343
5344 /* Put corner cells */
5345 for (i = 0; i < NUM_CORNER_DIRS; i++) {
5346 const int count = dlp->match_indices;
5347 int array_index = 0;
5348 enum direction8 dir = dir_ccw(DIR4_TO_DIR8[i]);
5349 int x = (t->type == TS_ISOMETRIC ? iso_offsets[i][0] : noniso_offsets[i][0]);
5350 int y = (t->type == TS_ISOMETRIC ? iso_offsets[i][1] : noniso_offsets[i][1]);
5351 int m[3] = {MATCH(dir_ccw(dir)), MATCH(dir), MATCH(dir_cw(dir))};
5352 struct sprite *s;
5353
5354 /* Synthesize 4 dimensional array? */
5355 switch (dlp->match_style) {
5356 case MATCH_NONE:
5357 /* We have no need for matching, just plug the piece in place. */
5358 break;
5359 case MATCH_SAME:
5360 array_index = array_index * 2 + (m[2] != this);
5361 array_index = array_index * 2 + (m[1] != this);
5362 array_index = array_index * 2 + (m[0] != this);
5363 break;
5364 case MATCH_PAIR:
5365 array_index = array_index * 2 + (m[2] == that);
5366 array_index = array_index * 2 + (m[1] == that);
5367 array_index = array_index * 2 + (m[0] == that);
5368 break;
5369 case MATCH_FULL:
5370 default:
5371 if (count > 0) {
5372 int n[3];
5373 int j;
5374
5375 for (j = 0; j < 3; j++) {
5376 int k;
5377
5378 for (k = 0; k < count; k++) {
5379 n[j] = k; /* Default to last entry */
5380 if (m[j] == dlp->match_index[k]) {
5381 break;
5382 }
5383 }
5384 }
5385 array_index = array_index * count + n[2];
5386 array_index = array_index * count + n[1];
5387 array_index = array_index * count + n[0];
5388 }
5389 break;
5390 };
5391
5393
5394 s = dlp->cells[array_index];
5395 if (s) {
5396 ADD_SPRITE(s, TRUE, x, y);
5397 }
5398 }
5399 break;
5400 }
5401 };
5402#undef MATCH
5403
5404 return sprs - saved_sprs;
5405}
5406
5407/************************************************************************/
5412 struct drawn_sprite *sprs,
5413 const struct tile *ptile,
5414 struct terrain **tterrain_near)
5415{
5416 struct drawn_sprite *saved_sprs = sprs;
5417 int i, tileno;
5418 struct tile *adjc_tile;
5419
5420#define UNKNOWN(dir) \
5421 ((adjc_tile = mapstep(&(wld.map), ptile, (dir))) \
5422 && client_tile_get_known(adjc_tile) == TILE_UNKNOWN)
5423
5424 switch (t->darkness_style) {
5425 case DARKNESS_NONE:
5426 break;
5427 case DARKNESS_ISORECT:
5428 for (i = 0; i < 4; i++) {
5429 const int W = t->normal_tile_width, H = t->normal_tile_height;
5430 int offsets[4][2] = {{W / 2, 0}, {0, H / 2}, {W / 2, H / 2}, {0, 0}};
5431
5432 if (UNKNOWN(DIR4_TO_DIR8[i])) {
5434 offsets[i][0], offsets[i][1]);
5435 }
5436 }
5437 break;
5439 for (i = 0; i < t->num_cardinal_tileset_dirs; i++) {
5440 if (UNKNOWN(t->cardinal_tileset_dirs[i])) {
5442 }
5443 }
5444 break;
5445 case DARKNESS_CARD_FULL:
5446 /* We're looking to find the INDEX_NSEW for the directions that
5447 * are unknown. We want to mark unknown tiles so that an unreal
5448 * tile will be given the same marking as our current tile - that
5449 * way we won't get the "unknown" dither along the edge of the
5450 * map. */
5451 tileno = 0;
5452 for (i = 0; i < t->num_cardinal_tileset_dirs; i++) {
5453 if (UNKNOWN(t->cardinal_tileset_dirs[i])) {
5454 tileno |= 1 << i;
5455 }
5456 }
5457
5458 if (tileno != 0) {
5460 }
5461 break;
5462 case DARKNESS_CORNER:
5463 /* Handled separately. */
5464 break;
5465 };
5466#undef UNKNOWN
5467
5468 return sprs - saved_sprs;
5469}
5470
5471/************************************************************************/
5476 struct drawn_sprite *sprs,
5477 int layer_num,
5478 const struct tile *ptile,
5479 const struct terrain *pterrain,
5480 struct terrain **tterrain_near)
5481{
5482 struct sprite *sprite;
5483 struct drawn_sprite *saved_sprs = sprs;
5484 struct drawing_data *draw = t->sprites.drawing[terrain_index(pterrain)];
5485 const int l = (draw->is_reversed
5486 ? (draw->num_layers - layer_num - 1) : layer_num);
5487
5489
5490 /* Skip the normal drawing process. */
5491 /* FIXME: this should avoid calling load_sprite since it's slow and
5492 * increases the refcount without limit. */
5493 if (ptile->spec_sprite && (sprite = load_sprite(t, ptile->spec_sprite,
5494 TRUE, FALSE, FALSE))) {
5495 if (l == 0) {
5497 return 1;
5498 } else {
5499 return 0;
5500 }
5501 }
5502
5504 sprs += fill_terrain_sprite_array(t, sprs, l, ptile, pterrain, tterrain_near, draw);
5505
5506 if ((l + 1) == draw->blending) {
5507 sprs += fill_terrain_sprite_blending(t, sprs, ptile, pterrain, tterrain_near);
5508 }
5509 }
5510
5511 return sprs - saved_sprs;
5512}
5513
5514/************************************************************************/
5521{
5522 /* Display an outline for city-builder type units if they are selected,
5523 * and on a tile where a city can be built.
5524 * But suppress the outline if the unit has orders (likely it is in
5525 * transit to somewhere else and this will just slow down redraws). */
5532}
5533
5534/************************************************************************/
5537static int fill_grid_sprite_array(const struct tileset *t,
5538 struct drawn_sprite *sprs,
5539 const struct tile *ptile,
5540 const struct tile_edge *pedge,
5541 const struct tile_corner *pcorner,
5542 const struct unit *punit,
5543 const struct city *pcity,
5544 const struct city *citymode)
5545{
5546 struct drawn_sprite *saved_sprs = sprs;
5547
5548 if (pedge) {
5549 bool known[NUM_EDGE_TILES], city[NUM_EDGE_TILES];
5550 bool unit[NUM_EDGE_TILES], worked[NUM_EDGE_TILES];
5551 int i;
5552 struct unit_list *pfocus_units = get_units_in_focus();
5553
5554 for (i = 0; i < NUM_EDGE_TILES; i++) {
5555 int dummy_x, dummy_y;
5556 const struct tile *tile = pedge->tile[i];
5557 struct player *powner = tile ? tile_owner(tile) : NULL;
5558
5560 unit[i] = FALSE;
5561 if (tile && !citymode) {
5564 struct tile *utile = unit_tile(pfocus_unit);
5565 int radius = game.info.init_city_radius_sq
5567 NULL,
5568 &(const struct req_context) {
5569 .player = unit_owner(pfocus_unit),
5570 .tile = utile,
5571 },
5572 NULL,
5574 );
5575
5576 if (city_tile_to_city_map(&dummy_x, &dummy_y, radius,
5577 utile, tile)) {
5578 unit[i] = TRUE;
5579 break;
5580 }
5581 }
5583 }
5584 worked[i] = FALSE;
5585
5586 city[i] = (tile
5587 && (NULL == powner || NULL == client.conn.playing
5588 || powner == client.conn.playing)
5590 if (city[i]) {
5591 if (citymode) {
5592 /* In citymode, we only draw worked tiles for this city - other
5593 * tiles may be marked as unavailable. */
5594 worked[i] = (tile_worked(tile) == citymode);
5595 } else {
5596 worked[i] = (NULL != tile_worked(tile));
5597 }
5598 }
5599 }
5600
5601 if (mapdeco_is_highlight_set(pedge->tile[0])
5602 || mapdeco_is_highlight_set(pedge->tile[1])) {
5605 && pedge->tile[0] && pedge->tile[1]
5606 && known[0] && known[1]
5607 && (is_ocean_tile(pedge->tile[0])
5608 ^ is_ocean_tile(pedge->tile[1]))) {
5610 } else {
5612 if (worked[0] || worked[1]) {
5614 } else if (city[0] || city[1]) {
5616 } else if (known[0] || known[1]) {
5618 }
5619 }
5621 if (XOR(city[0], city[1])) {
5623 }
5624 if (XOR(unit[0], unit[1])) {
5626 }
5627 }
5628 }
5629
5632 && known[0]
5633 && known[1]) {
5634 struct player *owner0 = tile_owner(pedge->tile[0]);
5635 struct player *owner1 = tile_owner(pedge->tile[1]);
5636
5637 if (owner0 != owner1) {
5638 if (owner0) {
5639 int plrid = player_index(owner0);
5641 [pedge->type][0]);
5642 }
5643 if (owner1) {
5644 int plrid = player_index(owner1);
5646 [pedge->type][1]);
5647 }
5648 }
5649 }
5650 } else if (NULL != ptile && TILE_UNKNOWN != client_tile_get_known(ptile)) {
5651 int cx, cy;
5652
5653 if (citymode
5654 /* Test to ensure valid coordinates? */
5655 && city_base_to_city_map(&cx, &cy, citymode, ptile)
5656 && !client_city_can_work_tile(citymode, ptile)) {
5658 }
5659
5661 bool native = TRUE;
5662 struct unit_list *pfocus_units = get_units_in_focus();
5663
5665 if (!is_native_tile(unit_type_get(pfocus), ptile)) {
5666 native = FALSE;
5667 break;
5668 }
5670
5671 if (!native) {
5672 if (t->sprites.grid.nonnative != NULL) {
5674 } else {
5676 }
5677 }
5678 }
5679 }
5680
5681 return sprs - saved_sprs;
5682}
5683
5684/************************************************************************/
5687static int fill_goto_sprite_array(const struct tileset *t,
5688 struct drawn_sprite *sprs,
5689 const struct tile *ptile,
5690 const struct tile_edge *pedge,
5691 const struct tile_corner *pcorner)
5692{
5693 struct drawn_sprite *saved_sprs = sprs;
5694 struct sprite *sprite;
5695 bool warn = FALSE;
5696 enum goto_tile_state state;
5697 int length;
5698 bool waypoint;
5699
5700 if (goto_tile_state(ptile, &state, &length, &waypoint)) {
5701 if (length >= 0) {
5702 fc_assert(state >= 0);
5703 fc_assert(state < ARRAY_SIZE(t->sprites.path.s));
5704
5705 sprite = t->sprites.path.s[state].specific;
5706 if (sprite != NULL) {
5707 ADD_SPRITE(sprite, FALSE, 0, 0);
5708 }
5709
5710 sprite = t->sprites.path.s[state].turns[length % 10];
5712 if (length >= 10) {
5713 sprite = t->sprites.path.s[state].turns_tens[(length / 10) % 10];
5715 if (length >= 100) {
5716 sprite = t->sprites.path.s[state].turns_hundreds[(length / 100)
5717 % 10];
5718
5719 if (sprite != NULL) {
5721 if (length >= 1000) {
5722 warn = TRUE;
5723 }
5724 } else {
5725 warn = TRUE;
5726 }
5727 }
5728 }
5729 }
5730
5731 if (waypoint) {
5733 }
5734
5735 if (warn) {
5736 /* Warn only once by tileset. */
5737 static char last_reported[256] = "";
5738
5739 if (0 != strcmp(last_reported, t->name)) {
5740 log_normal(_("Tileset \"%s\" doesn't support long goto paths, "
5741 "such as %d. Path not displayed as expected."),
5742 t->name, length);
5744 }
5745 }
5746 }
5747
5748 return sprs - saved_sprs;
5749}
5750
5751/************************************************************************/
5755static bool is_extra_drawing_enabled(struct extra_type *pextra)
5756{
5757 bool no_disable = TRUE; /* Draw if matches no cause */
5758
5759 if (is_extra_caused_by(pextra, EC_IRRIGATION)) {
5761 return TRUE;
5762 }
5763 no_disable = FALSE;
5764 }
5765 if (is_extra_caused_by(pextra, EC_POLLUTION)
5766 || is_extra_caused_by(pextra, EC_FALLOUT)) {
5768 return TRUE;
5769 }
5770 no_disable = FALSE;
5771 }
5772 if (is_extra_caused_by(pextra, EC_MINE)) {
5773 if (gui_options.draw_mines) {
5774 return TRUE;
5775 }
5776 no_disable = FALSE;
5777 }
5778 if (is_extra_caused_by(pextra, EC_RESOURCE)) {
5780 return TRUE;
5781 }
5782 no_disable = FALSE;
5783 }
5784 if (is_extra_removed_by(pextra, ERM_ENTER)) {
5785 if (gui_options.draw_huts) {
5786 return TRUE;
5787 }
5788 no_disable = FALSE;
5789 }
5790 if (is_extra_caused_by(pextra, EC_BASE)) {
5792 return TRUE;
5793 }
5794 no_disable = FALSE;
5795 }
5796 if (is_extra_caused_by(pextra, EC_ROAD)) {
5797 if (gui_options.draw_paths) {
5798 return TRUE;
5799 }
5800 no_disable = FALSE;
5801 }
5802
5803 return no_disable;
5804}
5805
5806/************************************************************************/
5823 struct drawn_sprite *sprs, enum mapview_layer layer,
5824 const struct tile *ptile,
5825 const struct tile_edge *pedge,
5826 const struct tile_corner *pcorner,
5827 const struct unit *punit, const struct city *pcity,
5828 const struct city *citymode,
5829 const struct unit_type *putype)
5830{
5831 int tileno, dir;
5834 struct terrain *tterrain_near[8];
5835 struct terrain *pterrain = NULL;
5836 struct drawn_sprite *save_sprs = sprs;
5837 struct player *owner = NULL;
5838 /* Unit drawing is disabled when the view options are turned off,
5839 * but only where we're drawing on the mapview. */
5840 bool do_draw_unit = (punit && (gui_options.draw_units || !ptile
5842 && unit_is_in_focus(punit))));
5844 && (do_draw_unit
5845 || (pcity && gui_options.draw_cities)
5846 || (ptile && !gui_options.draw_terrain)));
5847
5848 if (citymode) {
5849 int count = 0, i, cx, cy;
5850 const struct tile *const *tiles = NULL;
5851 bool valid = FALSE;
5852
5853 if (ptile) {
5854 tiles = &ptile;
5855 count = 1;
5856 } else if (pcorner) {
5857 tiles = pcorner->tile;
5858 count = NUM_CORNER_TILES;
5859 } else if (pedge) {
5860 tiles = pedge->tile;
5861 count = NUM_EDGE_TILES;
5862 }
5863
5864 for (i = 0; i < count; i++) {
5865 if (tiles[i] && city_base_to_city_map(&cx, &cy, citymode, tiles[i])) {
5866 valid = TRUE;
5867 break;
5868 }
5869 }
5870 if (!valid) {
5871 return 0;
5872 }
5873 }
5874
5875 if (ptile && client_tile_get_known(ptile) != TILE_UNKNOWN) {
5876 textras = *tile_extras(ptile);
5877 pterrain = tile_terrain(ptile);
5878
5879 if (NULL != pterrain) {
5880 if (layer == LAYER_TERRAIN1
5881 || layer == LAYER_TERRAIN2
5882 || layer == LAYER_TERRAIN3
5883 || layer == LAYER_WATER
5884 || layer == LAYER_ROADS) {
5885 build_tile_data(ptile, pterrain, tterrain_near, textras_near);
5886 }
5887 } else {
5888 log_error("fill_sprite_array() tile (%d,%d) has no terrain!",
5889 TILE_XY(ptile));
5890 }
5891 } else {
5893 }
5894
5895 switch (layer) {
5896 case LAYER_BACKGROUND:
5897 /* Set up background color. */
5899 if (do_draw_unit) {
5901 } else if (pcity && gui_options.draw_cities) {
5902 owner = city_owner(pcity);
5903 }
5904 }
5905 if (owner) {
5907 } else if (ptile && !gui_options.draw_terrain) {
5909 }
5910 break;
5911
5912 case LAYER_TERRAIN1:
5913 if (NULL != pterrain && gui_options.draw_terrain && !solid_bg) {
5914 sprs += fill_terrain_sprite_layer(t, sprs, 0, ptile, pterrain, tterrain_near);
5915 }
5916 break;
5917
5918 case LAYER_DARKNESS:
5919 if (NULL != pterrain && gui_options.draw_terrain && !solid_bg) {
5921 }
5922 break;
5923
5924 case LAYER_TERRAIN2:
5925 if (NULL != pterrain && gui_options.draw_terrain && !solid_bg) {
5926 sprs += fill_terrain_sprite_layer(t, sprs, 1, ptile, pterrain, tterrain_near);
5927 }
5928 break;
5929
5930 case LAYER_TERRAIN3:
5931 if (NULL != pterrain && gui_options.draw_terrain && !solid_bg) {
5933 sprs += fill_terrain_sprite_layer(t, sprs, 2, ptile, pterrain, tterrain_near);
5934 }
5935 break;
5936
5937 case LAYER_WATER:
5938 if (NULL != pterrain) {
5940 && terrain_type_terrain_class(pterrain) == TC_OCEAN) {
5941 for (dir = 0; dir < t->num_cardinal_tileset_dirs; dir++) {
5942 int didx = t->cardinal_tileset_dirs[dir];
5943
5946 int idx = extra_index(priver);
5947
5948 if (BV_ISSET(textras_near[didx], idx)) {
5950 }
5951 }
5953 }
5954 }
5955
5957 pcity);
5958
5962 int idx = extra_index(priver);
5963
5964 if (BV_ISSET(textras, idx)) {
5965 int i;
5966
5967 /* Draw rivers on top of irrigation. */
5968 tileno = 0;
5969 for (i = 0; i < t->num_cardinal_tileset_dirs; i++) {
5971
5973 tileno |= 1 << i;
5974 } else {
5976
5977 if (proad != NULL) {
5978 extra_type_list_iterate(proad->integrators, iextra) {
5980 tileno |= 1 << i;
5981 }
5983 }
5984 }
5985 }
5986
5988 }
5989 }
5991 }
5992 }
5993 break;
5994
5995 case LAYER_ROADS:
5996 if (NULL != pterrain) {
5998 if (is_extra_drawing_enabled(pextra)) {
5999 sprs += fill_road_sprite_array(t, pextra, sprs,
6001 tterrain_near, pcity);
6002 }
6005 if (is_extra_drawing_enabled(pextra)) {
6006 sprs += fill_road_sprite_array(t, pextra, sprs,
6008 tterrain_near, pcity);
6009 }
6012 if (is_extra_drawing_enabled(pextra)) {
6013 sprs += fill_road_sprite_array(t, pextra, sprs,
6015 tterrain_near, pcity);
6016 }
6018 }
6019 break;
6020
6021 case LAYER_SPECIAL1:
6022 if (NULL != pterrain) {
6023 if (ptile) {
6025 if (tile_has_extra(ptile, pextra)
6026 && is_extra_drawing_enabled(pextra)
6027 && t->sprites.extras[extra_index(pextra)].u.bmf.background) {
6028 bool hidden = FALSE;
6029
6030 extra_type_list_iterate(pextra->hiders, phider) {
6032 hidden = TRUE;
6033 break;
6034 }
6036
6037 if (!hidden) {
6039 }
6040 }
6042 }
6043
6045 if (BV_ISSET(textras, extra_index(pextra))
6046 && is_extra_drawing_enabled(pextra)) {
6047 bool hidden = FALSE;
6048
6049 extra_type_list_iterate(pextra->hiders, phider) {
6051 hidden = TRUE;
6052 break;
6053 }
6055
6056 if (!hidden) {
6058 }
6059 }
6061 }
6062 break;
6063
6064 case LAYER_GRID1:
6065 if (t->type == TS_ISOMETRIC) {
6067 punit, pcity, citymode);
6068 }
6069 break;
6070
6071 case LAYER_CITY1:
6072 /* City. Some city sprites are drawn later. */
6073 if (pcity && gui_options.draw_cities) {
6075 struct sprite *spr = get_city_flag_sprite(t, pcity);
6076 struct area_rect flag_rect;
6077
6079
6083 flag_rect.w, flag_rect.h);
6084 }
6085 /* For iso-view the city.wall graphics include the full city, whereas
6086 * for non-iso view they are an overlay on top of the base city
6087 * graphic. */
6088 if (t->type == TS_OVERHEAD || pcity->client.walls <= 0) {
6092 }
6093 if (t->type == TS_ISOMETRIC && pcity->client.walls > 0) {
6094 struct city_sprite *cspr = t->sprites.city.wall[pcity->client.walls - 1];
6095 struct sprite *spr = NULL;
6096
6097 if (cspr != NULL) {
6098 spr = get_city_sprite(cspr, pcity);
6099 }
6100 if (spr == NULL) {
6102 if (cspr != NULL) {
6103 spr = get_city_sprite(cspr, pcity);
6104 }
6105 }
6106
6107 if (spr != NULL) {
6111 }
6112 }
6117 }
6118 if (t->type == TS_OVERHEAD && pcity->client.walls > 0) {
6119 struct city_sprite *cspr = t->sprites.city.wall[pcity->client.walls - 1];
6120 struct sprite *spr = NULL;
6121
6122 if (cspr != NULL) {
6123 spr = get_city_sprite(cspr, pcity);
6124 }
6125 if (spr == NULL) {
6127 if (cspr != NULL) {
6128 spr = get_city_sprite(cspr, pcity);
6129 }
6130 }
6131
6132 if (spr != NULL) {
6134 }
6135 }
6136 if (pcity->client.unhappy) {
6138 }
6139 }
6140 break;
6141
6142 case LAYER_SPECIAL2:
6143 if (NULL != pterrain) {
6144 if (ptile) {
6146 if (tile_has_extra(ptile, pextra)
6147 && is_extra_drawing_enabled(pextra)
6148 && t->sprites.extras[extra_index(pextra)].u.bmf.middleground) {
6149 bool hidden = FALSE;
6150
6151 extra_type_list_iterate(pextra->hiders, phider) {
6153 hidden = TRUE;
6154 break;
6155 }
6157
6158 if (!hidden) {
6160 }
6161 }
6163 }
6164
6166 if (BV_ISSET(textras, extra_index(pextra))
6167 && is_extra_drawing_enabled(pextra)) {
6168 bool hidden = FALSE;
6169
6170 extra_type_list_iterate(pextra->hiders, phider) {
6172 hidden = TRUE;
6173 break;
6174 }
6176
6177 if (!hidden) {
6179 }
6180 }
6182 }
6183 break;
6184
6185 case LAYER_UNIT:
6186 case LAYER_FOCUS_UNIT:
6187 if (do_draw_unit && XOR(layer == LAYER_UNIT, unit_is_in_focus(punit))) {
6188 int stack_count = ptile ? unit_list_size(ptile->units) : 0;
6189 bool backdrop = !pcity;
6190
6191 if (ptile && unit_is_in_focus(punit)
6192 && t->sprites.unit.select[0]) {
6193 /* Special case for drawing the selection rectangle. The blinking
6194 * unit is handled separately, inside get_drawable_unit(). */
6197 }
6198
6199 /* Load more stack number sprites if needed. no_more_stack_sprites guard
6200 * that we don't retry over and over again for every stack,
6201 * when it's not working. */
6202 if (t->sprites.unit.num_stack_sprites < stack_count
6203 && !t->sprites.unit.no_more_stack_sprites) {
6204 t->sprites.unit.stack = fc_realloc(t->sprites.unit.stack,
6205 stack_count * sizeof(struct sprite *));
6206
6207 while (t->sprites.unit.num_stack_sprites < stack_count
6208 && !t->sprites.unit.no_more_stack_sprites) {
6209 struct sprite *spr = load_gfxnumber(t->sprites.unit.num_stack_sprites + 1);
6210
6211 if (spr != NULL) {
6212 t->sprites.unit.stack[t->sprites.unit.num_stack_sprites++] = spr;
6213 } else {
6214 t->sprites.unit.no_more_stack_sprites = TRUE;
6215 t->sprites.unit.stack = fc_realloc(t->sprites.unit.stack,
6216 t->sprites.unit.num_stack_sprites * sizeof(struct sprite *));
6217 }
6218 }
6219 }
6220
6222 } else if (putype != NULL && layer == LAYER_UNIT) {
6223 /* Only the sprite for the unit type. */
6224 /* FIXME: Shouldn't this still get activity and orientation of
6225 * the actual unit? */
6228 }
6229 break;
6230
6231 case LAYER_SPECIAL3:
6232 if (NULL != pterrain) {
6233 if (ptile) {
6234 bool show_flag = FALSE;
6235 struct player *eowner = extra_owner(ptile);
6236
6238 if (is_extra_drawing_enabled(pextra)
6239 && tile_has_extra(ptile, pextra)
6240 && t->sprites.extras[extra_index(pextra)].u.bmf.foreground) {
6241 bool hidden = FALSE;
6242
6243 extra_type_list_iterate(pextra->hiders, phider) {
6245 hidden = TRUE;
6246 break;
6247 }
6249
6250 if (!hidden) {
6251 if (t->sprites.extras[extra_index(pextra)].u.bmf.foreground) {
6253 }
6254 }
6255 }
6257
6258 /* Show base flag. Not part of previous iteration as
6259 * "extras of ESTYLE_3_LAYER" != "bases" */
6260 if (eowner != NULL) {
6262 if (tile_has_extra(ptile, pextra)) {
6263 bool hidden = FALSE;
6264
6265 extra_type_list_iterate(pextra->hiders, phider) {
6267 hidden = TRUE;
6268 break;
6269 }
6271
6272 if (!hidden) {
6273 show_flag = TRUE;
6274 }
6275 }
6277
6278 if (show_flag) {
6282 }
6283 }
6284 }
6285 }
6286 break;
6287
6288 case LAYER_FOG:
6290 break;
6291
6292 case LAYER_CITY2:
6293 /* City size. Drawing this under fog makes it hard to read. */
6295 bool warn = FALSE;
6296 unsigned int size = city_size_get(pcity);
6297
6301 if (10 <= size) {
6303 % 10], FALSE,
6306 if (100 <= size) {
6307 struct sprite *sprite =
6308 t->sprites.city.size_hundreds[(size / 100) % 10];
6309
6310 if (NULL != sprite) {
6314 } else {
6315 warn = TRUE;
6316 }
6317 if (1000 <= size) {
6318 warn = TRUE;
6319 }
6320 }
6321 }
6322
6323 if (warn) {
6324 /* Warn only once by tileset. */
6325 static char last_reported[256] = "";
6326
6327 if (0 != strcmp(last_reported, t->name)) {
6328 log_normal(_("Tileset \"%s\" doesn't support big cities size, "
6329 "such as %d. Size not displayed as expected."),
6330 t->name, size);
6332 }
6333 }
6334 }
6335 break;
6336
6337 case LAYER_GRID2:
6338 if (t->type == TS_OVERHEAD) {
6340 punit, pcity, citymode);
6341 }
6342 break;
6343
6344 case LAYER_OVERLAYS:
6346 if (mapdeco_is_crosshair_set(ptile)) {
6348 }
6349 break;
6350
6351 case LAYER_CITYBAR:
6352 case LAYER_TILELABEL:
6353 /* Nothing. This is just a placeholder. */
6354 break;
6355
6356 case LAYER_GOTO:
6357 if (ptile && goto_is_active()) {
6359 }
6360 break;
6361
6362 case LAYER_WORKERTASK:
6363 if (citymode != NULL && ptile != NULL) {
6365 if (ptask->ptile == ptile) {
6366 switch (ptask->act) {
6367 case ACTIVITY_MINE:
6368 if (ptask->tgt == NULL) {
6369 ADD_SPRITE(t->sprites.unit.plant,
6372 } else {
6376 }
6377 break;
6378 case ACTIVITY_PLANT:
6379 ADD_SPRITE(t->sprites.unit.plant,
6382 break;
6383 case ACTIVITY_IRRIGATE:
6384 if (ptask->tgt == NULL) {
6385 ADD_SPRITE(t->sprites.unit.cultivate,
6388 } else {
6392 }
6393 break;
6394 case ACTIVITY_CULTIVATE:
6395 ADD_SPRITE(t->sprites.unit.cultivate,
6398 break;
6399 case ACTIVITY_GEN_ROAD:
6400 if (ptask->tgt != NULL) {
6404 }
6405 break;
6406 case ACTIVITY_TRANSFORM:
6407 ADD_SPRITE(t->sprites.unit.transform,
6410 break;
6411 case ACTIVITY_CLEAN:
6412 if (ptask->tgt != NULL) {
6416 }
6417 break;
6418 default:
6419 break;
6420 }
6421 }
6423 }
6424 break;
6425
6426 case LAYER_EDITOR:
6427 if (ptile && editor_is_active()) {
6428 if (editor_tile_is_selected(ptile)) {
6431 }
6432
6433 if (NULL != map_startpos_get(ptile)) {
6434 /* FIXME: Use a more representative sprite. */
6436 }
6437 }
6438 break;
6439
6440 case LAYER_INFRAWORK:
6441 if (ptile != NULL) {
6442 if (ptile->placing != NULL) {
6443 const int id = extra_index(ptile->placing);
6444
6445 if (t->sprites.extras[id].activity != NULL) {
6449 }
6450 }
6451 if (client_infratile() == ptile) {
6453 }
6454 }
6455 break;
6456
6457 case LAYER_COUNT:
6459 break;
6460 }
6461
6462 return sprs - save_sprs;
6463}
6464
6465/************************************************************************/
6469void tileset_setup_city_tiles(struct tileset *t, int style)
6470{
6471 const char *style_name = city_style_rule_name(style);
6472
6473 if (style == game.control.num_city_styles - 1) {
6474 int i;
6475
6476 /* Free old sprites */
6478
6479 for (i = 0; i < NUM_WALL_TYPES; i++) {
6481 t->sprites.city.wall[i] = NULL;
6482 }
6485
6487
6488 t->sprites.city.tile = load_city_sprite(t, "city");
6489
6490 for (i = 0; i < NUM_WALL_TYPES; i++) {
6491 char buffer[256];
6492
6493 fc_snprintf(buffer, sizeof(buffer), "bldg_%d", i);
6494 t->sprites.city.wall[i] = load_city_sprite(t, buffer);
6495 }
6496 t->sprites.city.single_wall = load_city_sprite(t, "wall");
6497
6498 t->sprites.city.occupied = load_city_sprite(t, "occupied");
6499 }
6500
6502 &t->sprites.style_citizen_sets.sets[style],
6503 city_styles[style].citizens_graphic,
6504 style_name, FALSE);
6507 &t->sprites.style_citizen_sets.sets[style],
6508 sp,
6509 city_styles[style].citizens_graphic,
6510 style_name, FALSE);
6512
6513 if (style == game.control.num_city_styles - 1) {
6514 for (style = 0; style < game.control.num_city_styles; style++) {
6515 if (t->sprites.city.tile->styles[style].land_num_thresholds == 0) {
6517 _("City style \"%s\": no city graphics."),
6518 city_style_rule_name(style));
6519 }
6520 if (t->sprites.city.occupied->styles[style].land_num_thresholds == 0) {
6522 _("City style \"%s\": no occupied graphics."),
6523 city_style_rule_name(style));
6524 }
6525 }
6526 }
6527}
6528
6529/************************************************************************/
6535{
6536 if (t->sprites.unit.select[0]) {
6537 return 0.1;
6538 } else {
6539 return 0.5;
6540 }
6541}
6542
6543/************************************************************************/
6548{
6549 focus_unit_state = 0;
6550}
6551
6552/************************************************************************/
6556{
6557 if (!t->sprites.unit.select[0]) {
6559 }
6560}
6561
6562/************************************************************************/
6567{
6569 if (t->sprites.unit.select[0]) {
6571 } else {
6572 focus_unit_state %= 2;
6573 }
6574}
6575
6576/************************************************************************/
6579struct unit *get_drawable_unit(const struct tileset *t,
6580 struct tile *ptile,
6581 const struct city *citymode)
6582{
6583 struct unit *punit = find_visible_unit(ptile);
6584
6585 if (punit == NULL) {
6586 return NULL;
6587 }
6588
6590 return NULL;
6591 }
6592
6594 || t->sprites.unit.select[0] || focus_unit_state == 0) {
6595 return punit;
6596 } else {
6597 return NULL;
6598 }
6599}
6600
6601/************************************************************************/
6605static void unload_all_sprites(struct tileset *t)
6606{
6607 if (t->sprite_hash) {
6609 while (ss->ref_count > 0) {
6611 }
6613 }
6614}
6615
6616/************************************************************************/
6620{
6621 int i;
6622
6623 log_debug("tileset_free_tiles()");
6624
6626
6628 t->sprites.city.tile = NULL;
6629
6630 for (i = 0; i < NUM_WALL_TYPES; i++) {
6632 t->sprites.city.wall[i] = NULL;
6633 }
6636
6639
6640 if (t->sprite_hash) {
6642 t->sprite_hash = NULL;
6643 }
6644
6645 if (t->sprites.style_citizen_sets.sets != NULL) {
6648 }
6649
6652 if (ss->file) {
6653 free(ss->file);
6654 }
6655 fc_assert(ss->sprite == NULL);
6656 free(ss);
6658
6661 free(sf->file_name);
6662 if (sf->big_sprite) {
6663 free_sprite(sf->big_sprite);
6664 sf->big_sprite = NULL;
6665 }
6666 free(sf);
6668
6673
6678
6679 if (t->sprites.tx.fullfog) {
6680 free(t->sprites.tx.fullfog);
6681 t->sprites.tx.fullfog = NULL;
6682 }
6683
6689
6690 /* Index 0 is 'occupied' or 'default' stack sprite */
6691 for (i = 1; i < t->sprites.unit.num_stack_sprites - 1; i++) {
6692 free_sprite(t->sprites.unit.stack[i]);
6693 }
6694 t->sprites.unit.num_stack_sprites = 0;
6695 if (t->sprites.unit.stack != NULL) {
6696 free(t->sprites.unit.stack);
6697 t->sprites.unit.stack = NULL;
6698 }
6699
6701}
6702
6703/************************************************************************/
6706struct sprite *get_spaceship_sprite(const struct tileset *t,
6707 enum spaceship_part part)
6708{
6709 return t->sprites.spaceship[part];
6710}
6711
6712/************************************************************************/
6715static inline const struct citizen_graphic *
6718{
6719 fc_assert_ret_val(set != NULL, NULL);
6720
6721 if (type < CITIZEN_SPECIALIST) {
6723 return &set->citizen[type];
6724 } else {
6726 return &set->specialist[type - CITIZEN_SPECIALIST];
6727 }
6728}
6729
6730/************************************************************************/
6737struct sprite *get_citizen_sprite(const struct tileset *t,
6739 int citizen_index,
6740 const struct city *pcity)
6741{
6742 const struct citizen_graphic *graphic = NULL;
6744
6745 if (pcity != NULL) {
6746 int style = style_of_city(pcity);
6747
6749
6751 type);
6752
6754 }
6755
6756 if (graphic == NULL || graphic->count == 0) {
6757 /* Fall back to default sprites */
6759 }
6760
6761 if (graphic->count == 0) {
6762 return NULL;
6763 }
6764
6765 return graphic->sprite[gfx_index % graphic->count];
6766}
6767
6768/************************************************************************/
6771struct sprite *get_nation_flag_sprite(const struct tileset *t,
6772 const struct nation_type *pnation)
6773{
6774 return t->sprites.nation_flag.p[nation_index(pnation)];
6775}
6776
6777/************************************************************************/
6781 const struct nation_type *pnation)
6782{
6783 return t->sprites.nation_shield.p[nation_index(pnation)];
6784}
6785
6786/************************************************************************/
6789struct sprite *get_tech_sprite(const struct tileset *t, Tech_type_id tech)
6790{
6791 fc_assert_ret_val(0 <= tech && tech < advance_count(), NULL);
6792 return t->sprites.tech[tech];
6793}
6794
6795/************************************************************************/
6798struct sprite *get_building_sprite(const struct tileset *t,
6799 const struct impr_type *pimprove)
6800{
6801 fc_assert_ret_val(NULL != pimprove, NULL);
6802 return t->sprites.building[improvement_index(pimprove)];
6803}
6804
6805/************************************************************************/
6808struct sprite *get_government_sprite(const struct tileset *t,
6809 const struct government *gov)
6810{
6811 fc_assert_ret_val(NULL != gov, NULL);
6812 return t->sprites.government[government_index(gov)];
6813}
6814
6815/************************************************************************/
6820struct sprite *get_unittype_sprite(const struct tileset *t,
6821 const struct unit_type *punittype,
6822 enum unit_activity activity,
6823 enum direction8 facing)
6824{
6825 int uidx = utype_index(punittype);
6826 bool icon = !direction8_is_valid(facing);
6827
6828 if (activity >= ACTIVITY_LAST) {
6829 activity = ACTIVITY_IDLE;
6830 }
6831
6833
6834 if (!direction8_is_valid(facing) || !is_valid_dir(facing)) {
6835 facing = t->unit_default_orientation;
6836 /* May not have been specified, but it only matters if we don't
6837 * turn out to have an icon sprite */
6838 }
6839
6840 if (t->sprites.units.icon[uidx][activity] != NULL
6841 && (icon || t->sprites.units.facing[uidx][facing][activity] == NULL)) {
6842 /* Has icon sprite, and we prefer to (or must) use it */
6843 return t->sprites.units.icon[uidx][activity];
6844 } else if (t->sprites.units.icon[uidx][ACTIVITY_IDLE] != NULL
6845 && (icon
6846 || t->sprites.units.facing[uidx][facing][ACTIVITY_IDLE] == NULL)) {
6847 /* Has icon sprite, and we prefer to (or must) use it */
6848 return t->sprites.units.icon[uidx][ACTIVITY_IDLE];
6849 } else {
6850 /* We should have a valid orientation by now. Failure to have either
6851 * an icon sprite or default orientation should have been caught at
6852 * tileset load. */
6854
6855 if (t->sprites.units.facing[uidx][facing][activity] == NULL) {
6856 return t->sprites.units.facing[uidx][facing][ACTIVITY_IDLE];
6857 }
6858
6859 return t->sprites.units.facing[uidx][facing][activity];
6860 }
6861}
6862
6863/************************************************************************/
6866struct sprite *get_sample_city_sprite(const struct tileset *t,
6867 int style_idx)
6868{
6869 int num_thresholds =
6870 t->sprites.city.tile->styles[style_idx].land_num_thresholds;
6871
6872 if (num_thresholds == 0) {
6873 return NULL;
6874 } else {
6875 return (t->sprites.city.tile->styles[style_idx]
6876 .land_thresholds[num_thresholds - 1].sprite);
6877 }
6878}
6879
6880/************************************************************************/
6883struct sprite *get_arrow_sprite(const struct tileset *t,
6884 enum arrow_type arrow)
6885{
6886 fc_assert_ret_val(arrow >= 0 && arrow < ARROW_LAST, NULL);
6887
6888 return t->sprites.arrow[arrow];
6889}
6890
6891/************************************************************************/
6895{
6896 switch (otype) {
6897 case O_SCIENCE:
6898 return t->sprites.tax_science;
6899 case O_GOLD:
6900 return t->sprites.tax_gold;
6901 case O_LUXURY:
6902 return t->sprites.tax_luxury;
6903 case O_TRADE:
6904 case O_FOOD:
6905 case O_SHIELD:
6906 case O_LAST:
6907 break;
6908 }
6909 return NULL;
6910}
6911
6912/************************************************************************/
6915struct sprite *get_event_sprite(const struct tileset *t, enum event_type event)
6916{
6917 return t->sprites.events[event];
6918}
6919
6920/************************************************************************/
6924struct sprite *get_treaty_thumb_sprite(const struct tileset *t, bool on_off)
6925{
6926 return t->sprites.treaty_thumb[on_off ? 1 : 0];
6927}
6928
6929/************************************************************************/
6934 tileset *t)
6935{
6936 return &t->sprites.explode.unit;
6937}
6938
6939/************************************************************************/
6945{
6946 return t->sprites.explode.nuke;
6947}
6948
6949/************************************************************************/
6952const struct citybar_sprites *get_citybar_sprites(const struct tileset *t)
6953{
6955 return &t->sprites.citybar;
6956 } else {
6957 return NULL;
6958 }
6959}
6960
6961/************************************************************************/
6964const struct editor_sprites *get_editor_sprites(const struct tileset *t)
6965{
6966 return &t->sprites.editor;
6967}
6968
6969/************************************************************************/
6975struct sprite *get_cursor_sprite(const struct tileset *t,
6976 enum cursor_type cursor,
6977 int *hot_x, int *hot_y, int frame)
6978{
6979 *hot_x = t->sprites.cursor[cursor].hot_x;
6980 *hot_y = t->sprites.cursor[cursor].hot_y;
6981
6982 return t->sprites.cursor[cursor].frame[frame];
6983}
6984
6985/************************************************************************/
6994struct sprite *get_icon_sprite(const struct tileset *t, enum icon_type icon)
6995{
6996 return t->sprites.icon[icon];
6997}
6998
6999/************************************************************************/
7006{
7007 return t->sprites.user.attention;
7008}
7009
7010/************************************************************************/
7014struct sprite *get_indicator_sprite(const struct tileset *t,
7015 enum indicator_type indicator,
7016 int idx)
7017{
7018 idx = CLIP(0, idx, NUM_TILES_PROGRESS - 1);
7019
7020 fc_assert_ret_val(indicator >= 0 && indicator < INDICATOR_COUNT, NULL);
7021
7022 return t->sprites.indicator[indicator][idx];
7023}
7024
7025/************************************************************************/
7032 const struct unit *punit,
7033 int happy_cost)
7034{
7035 const int unhappy = CLIP(0, happy_cost, MAX_NUM_UPKEEP_SPRITES+1);
7036
7037 if (unhappy > 0) {
7038 return t->sprites.upkeep.unhappy[unhappy - 1];
7039 } else {
7040 return NULL;
7041 }
7042}
7043
7044/************************************************************************/
7050struct sprite *get_unit_upkeep_sprite(const struct tileset *t,
7052 const struct unit *punit,
7053 const int *upkeep_cost)
7054{
7055 const int upkeep = CLIP(0, upkeep_cost[otype], MAX_NUM_UPKEEP_SPRITES + 1);
7056
7057 if (upkeep > 0) {
7058 return t->sprites.upkeep.output[otype][upkeep - 1];
7059 } else {
7060 return NULL;
7061 }
7062}
7063
7064/************************************************************************/
7068struct sprite *get_basic_fog_sprite(const struct tileset *t)
7069{
7070 return t->sprites.tx.fog;
7071}
7072
7073/************************************************************************/
7076struct color_system *get_color_system(const struct tileset *t)
7077{
7078 return t->color_system;
7079}
7080
7081/************************************************************************/
7085{
7086 char *default_theme_name = NULL;
7087 size_t default_theme_name_sz = 0;
7088 int i;
7089
7090 switch (get_gui_type()) {
7091 case GUI_GTK3_22:
7094 break;
7095 case GUI_GTK4:
7098 break;
7099 case GUI_SDL2:
7102 break;
7103 case GUI_SDL3:
7106 break;
7107 case GUI_STUB:
7108 case GUI_QT:
7109 case GUI_SDL:
7110 case GUI_WEB:
7111 case GUI_GTK2:
7112 case GUI_GTK3:
7113 break;
7114 }
7115
7117 /* Theme is not supported by this client. */
7118 return;
7119 }
7120
7121 for (i = 0; i < t->num_preferred_themes; i++) {
7124 log_debug("trying theme \"%s\".", t->preferred_themes[i]);
7125 if (load_theme(t->preferred_themes[i])) {
7128 return;
7129 }
7130 }
7131 }
7132 }
7133 log_verbose("The tileset doesn't specify preferred themes or none of its "
7134 "preferred themes can be used. Using system default.");
7136}
7137
7138/************************************************************************/
7141void tileset_init(struct tileset *t)
7142{
7143 int wi;
7144
7145 /* We currently have no city sprites loaded. */
7146 t->sprites.city.tile = NULL;
7147
7148 for (wi = 0; wi < NUM_WALL_TYPES; wi++) {
7149 t->sprites.city.wall[wi] = NULL;
7150 }
7152
7154
7155 t->sprites.background.color = NULL;
7156 t->sprites.background.graphic = NULL;
7157
7158 player_slots_iterate(pslot) {
7159 int edge, j, id = player_slot_index(pslot);
7160
7161 for (edge = 0; edge < EDGE_COUNT; edge++) {
7162 for (j = 0; j < 2; j++) {
7164 }
7165 }
7166
7167 t->sprites.player[id].color = NULL;
7170
7171 t->max_upkeep_height = 0;
7172}
7173
7174/************************************************************************/
7183 struct drawn_sprite *sprs,
7184 int layer,
7185 struct terrain *pterrain)
7186{
7187 struct drawn_sprite *save_sprs = sprs;
7188 struct drawing_data *draw = t->sprites.drawing[terrain_index(pterrain)];
7189
7190 struct terrain *tterrain_near[8];
7192
7193 struct tile dummy_tile; /* :( */
7194
7195 int i;
7196
7197
7198 memset(&dummy_tile, 0, sizeof(struct tile));
7199
7200 for (i = 0; i < 8; i++) {
7201 tterrain_near[i] = pterrain;
7203 }
7204
7205 i = draw->is_reversed ? draw->num_layers - layer - 1 : layer;
7207 pterrain, tterrain_near, draw);
7208
7209 return sprs - save_sprs;
7210}
7211
7212/************************************************************************/
7216 struct drawn_sprite *sprs,
7217 const struct extra_type *pextra)
7218{
7219 int idx = extra_index(pextra);
7220 struct drawn_sprite *saved_sprs = sprs;
7221
7222 switch (t->sprites.extras[idx].extrastyle) {
7223 case ESTYLE_SINGLE1:
7224 case ESTYLE_SINGLE2:
7226 break;
7227 case ESTYLE_CARDINALS:
7229 break;
7233 case ESTYLE_RIVER:
7234 return fill_basic_road_sprite_array(t, sprs, pextra);
7235 case ESTYLE_3LAYER:
7236 return fill_basic_base_sprite_array(t, sprs, pextra);
7237 case ESTYLE_COUNT:
7239 break;
7240 }
7241
7242 return sprs - saved_sprs;
7243}
7244
7245/************************************************************************/
7251 struct drawn_sprite *sprs,
7252 const struct extra_type *pextra)
7253{
7254 struct drawn_sprite *saved_sprs = sprs;
7255 int idx;
7256 int i;
7257 enum extrastyle_id extrastyle;
7258
7259 if (!t || !sprs || !pextra) {
7260 return 0;
7261 }
7262
7263 idx = extra_index(pextra);
7264
7265 if (!(0 <= idx && idx < game.control.num_extra_types)) {
7266 return 0;
7267 }
7268
7269 extrastyle = t->sprites.extras[idx].extrastyle;
7270
7271 if (extrastyle == ESTYLE_RIVER) {
7273 } else {
7274 for (i = 0; i < t->num_valid_tileset_dirs; i++) {
7275 if (!t->valid_tileset_dirs[i]) {
7276 continue;
7277 }
7278 if (extrastyle == ESTYLE_ROAD_ALL_SEPARATE) {
7280 } else if (extrastyle == ESTYLE_ROAD_PARITY_COMBINED) {
7281 if ((i % 2) == 0) {
7282 ADD_SPRITE_SIMPLE(t->sprites.extras[idx].u.road.ru.combo.even[1 << (i / 2)]);
7283 }
7284 } else if (extrastyle == ESTYLE_ROAD_ALL_COMBINED) {
7285 ADD_SPRITE_SIMPLE(t->sprites.extras[idx].u.road.ru.total[1 << i]);
7286 }
7287 }
7288 }
7289
7290 return sprs - saved_sprs;
7291}
7292
7293/************************************************************************/
7299 struct drawn_sprite *sprs,
7300 const struct extra_type *pextra)
7301{
7302 struct drawn_sprite *saved_sprs = sprs;
7303 int idx;
7304
7305 if (!t || !sprs || !pextra) {
7306 return 0;
7307 }
7308
7309 idx = extra_index(pextra);
7310
7311 if (!(0 <= idx && idx < game.control.num_extra_types)) {
7312 return 0;
7313 }
7314
7315#define ADD_SPRITE_IF_NOT_NULL(x) do {\
7316 if ((x) != NULL) {\
7317 ADD_SPRITE_FULL(x);\
7318 }\
7319} while (FALSE)
7320
7321 /* Corresponds to LAYER_SPECIAL{1,2,3} order. */
7325
7326#undef ADD_SPRITE_IF_NOT_NULL
7327
7328 return sprs - saved_sprs;
7329}
7330
7331/************************************************************************/
7334enum mapview_layer tileset_get_layer(const struct tileset *t, int n)
7335{
7337 return t->layer_order[n];
7338}
7339
7340/************************************************************************/
7344 enum layer_category cat)
7345{
7346 switch (layer) {
7347 case LAYER_BACKGROUND:
7348 case LAYER_TERRAIN1:
7349 case LAYER_DARKNESS:
7350 case LAYER_TERRAIN2:
7351 case LAYER_TERRAIN3:
7352 case LAYER_WATER:
7353 case LAYER_ROADS:
7354 case LAYER_SPECIAL1:
7355 case LAYER_SPECIAL2:
7356 case LAYER_SPECIAL3:
7358 case LAYER_CITY1:
7359 case LAYER_CITY2:
7360 return cat == LAYER_CATEGORY_CITY;
7361 case LAYER_UNIT:
7362 case LAYER_FOCUS_UNIT:
7363 return cat == LAYER_CATEGORY_UNIT;
7364 case LAYER_GRID1:
7365 case LAYER_FOG:
7366 case LAYER_GRID2:
7367 case LAYER_OVERLAYS:
7368 case LAYER_TILELABEL:
7369 case LAYER_CITYBAR:
7370 case LAYER_GOTO:
7371 case LAYER_WORKERTASK:
7372 case LAYER_EDITOR:
7373 case LAYER_INFRAWORK:
7374 return FALSE;
7375 case LAYER_COUNT:
7376 break; /* and fail below */
7377 }
7378
7379 fc_assert_msg(FALSE, "Unknown layer category: %d", cat);
7380 return FALSE;
7381}
7382
7383/************************************************************************/
7386void tileset_player_init(struct tileset *t, struct player *pplayer)
7387{
7388 int plrid, i, j;
7389 struct sprite *color;
7390
7391 fc_assert_ret(pplayer != NULL);
7392
7393 plrid = player_index(pplayer);
7394 fc_assert_ret(plrid >= 0);
7396
7397 /* Free all data before recreating it. */
7399
7400 if (player_has_color(pplayer)) {
7402 = create_plr_sprite(get_player_color(t, pplayer));
7403 } else {
7404 /* XXX: if player hasn't been assigned a color, perhaps there's no
7405 * point proceeding with an arbitrary color; this should only happen
7406 * in pregame. Probably blank sprites would be better. */
7407
7408 fc_assert_ret(t->sprites.background.color != NULL);
7409
7410 color = t->sprites.background.color;
7411 }
7412
7414 = crop_sprite(color, 0, 0,
7416 t->sprites.mask.tile, 0, 0, t->scale, FALSE);
7417
7418 for (i = 0; i < EDGE_COUNT; i++) {
7419 for (j = 0; j < 2; j++) {
7420 struct sprite *s;
7421
7422 if (color && t->sprites.grid.borders[i][j]) {
7423 s = crop_sprite(color, 0, 0,
7425 t->sprites.grid.borders[i][j], 0, 0, 1.0f, FALSE);
7426 } else {
7427 s = t->sprites.grid.borders[i][j];
7428 }
7429 t->sprites.player[plrid].grid_borders[i][j] = s;
7430 }
7431 }
7432}
7433
7434/************************************************************************/
7437static void tileset_player_free(struct tileset *t, int plrid)
7438{
7439 int i, j;
7440
7441 fc_assert_ret(plrid >= 0);
7443
7444 if (t->sprites.player[plrid].color) {
7447 }
7448 if (t->sprites.player[plrid].background) {
7451 }
7452
7453 for (i = 0; i < EDGE_COUNT; i++) {
7454 for (j = 0; j < 2; j++) {
7455 if (t->sprites.player[plrid].grid_borders[i][j]) {
7458 }
7459 }
7460 }
7461}
7462
7463/************************************************************************/
7467{
7468 /* Free all data before recreating it. */
7470
7471 /* Generate background color */
7472 t->sprites.background.color
7474
7475 /* Chop up and build the background graphics. */
7476 t->sprites.background.graphic
7477 = crop_sprite(t->sprites.background.color, 0, 0,
7479 t->sprites.mask.tile, 0, 0, t->scale, FALSE);
7480}
7481
7482/************************************************************************/
7486{
7487 if (t->sprites.background.color) {
7488 free_sprite(t->sprites.background.color);
7489 t->sprites.background.color = NULL;
7490 }
7491
7492 if (t->sprites.background.graphic) {
7493 free_sprite(t->sprites.background.graphic);
7494 t->sprites.background.graphic = NULL;
7495 }
7496}
7497
7498/************************************************************************/
7502{
7503 int i;
7504
7505 for (i = 0; i < ESTYLE_COUNT; i++) {
7506 if (t->style_lists[i] != NULL) {
7509 }
7510 }
7511
7512 if (t->flagged_bases_list != NULL) {
7515 }
7516
7517 if (t->sprites.style_citizen_sets.sets != NULL) {
7519 }
7520
7523 * sizeof(t->sprites.style_citizen_sets.sets[0]));
7524}
7525
7526/************************************************************************/
7530{
7531 return !tileset_update;
7532}
7533
7534/************************************************************************/
7537const char *tileset_name_get(struct tileset *t)
7538{
7539 return t->given_name;
7540}
7541
7542/************************************************************************/
7545const char *tileset_version(struct tileset *t)
7546{
7547 return t->version;
7548}
7549
7550/************************************************************************/
7553const char *tileset_summary(struct tileset *t)
7554{
7555 return t->summary;
7556}
7557
7558/************************************************************************/
7561const char *tileset_description(struct tileset *t)
7562{
7563 return t->description;
7564}
7565
7566/************************************************************************/
7570{
7571 return t->for_ruleset;
7572}
7573
7574/************************************************************************/
7578{
7579 return t->ts_topo_idx;
7580}
7581
7582/************************************************************************/
7586{
7587 return t->svg_height;
7588}
7589
7590/************************************************************************/
7593struct sprite *load_popup_sprite(const char *tag)
7594{
7595 return load_sprite(tileset, tag, TRUE, TRUE, FALSE);
7596}
7597
7598/************************************************************************/
7601void unload_popup_sprite(const char *tag)
7602{
7603 unload_sprite(tileset, tag);
7604}
#define str
Definition astring.c:76
#define n
Definition astring.c:77
#define BV_CLR_ALL(bv)
Definition bitvector.h:95
#define BV_ISSET(bv, bit)
Definition bitvector.h:78
struct canvas int int struct sprite int int int int height
Definition canvas_g.h:44
struct canvas int int int int struct sprite *sprite struct canvas struct color * pcolor
Definition canvas_g.h:56
struct canvas int int struct sprite int int offset_y
Definition canvas_g.h:44
struct canvas int int struct sprite int offset_x
Definition canvas_g.h:44
struct canvas int int struct sprite int int int width
Definition canvas_g.h:44
bool has_capabilities(const char *us, const char *them)
Definition capability.c:86
bool base_city_celebrating(const struct city *pcity)
Definition city.c:1637
const char * city_style_rule_name(const int style)
Definition city.c:1765
const char * get_output_identifier(Output_type_id output)
Definition city.c:619
bool city_can_be_built_here(const struct civ_map *nmap, const struct tile *ptile, const struct unit *punit, bool hut_test)
Definition city.c:1487
bool city_base_to_city_map(int *city_map_x, int *city_map_y, const struct city *const pcity, const struct tile *map_tile)
Definition city.c:281
bool city_tile_to_city_map(int *city_map_x, int *city_map_y, const int city_radius_sq, const struct tile *city_center, const struct tile *map_tile)
Definition city.c:264
static const struct city struct citystyle * city_styles
Definition city.c:84
int city_tile_output(const struct city *pcity, const struct tile *ptile, bool is_celebrating, Output_type_id otype)
Definition city.c:1283
bool city_can_work_tile(const struct city *pcity, const struct tile *ptile)
Definition city.c:1456
static citizens city_size_get(const struct city *pcity)
Definition city.h:569
citizen_category
Definition city.h:267
@ CITIZEN_LAST
Definition city.h:272
@ CITIZEN_SPECIALIST
Definition city.h:273
@ CITIZEN_ANGRY
Definition city.h:271
@ CITIZEN_HAPPY
Definition city.h:268
@ CITIZEN_CONTENT
Definition city.h:269
@ CITIZEN_UNHAPPY
Definition city.h:270
#define output_type_iterate(output)
Definition city.h:845
#define city_owner(_pcity_)
Definition city.h:563
#define MAX_CITY_SIZE
Definition city.h:106
#define output_type_iterate_end
Definition city.h:851
void generate_citydlg_dimensions(void)
int main(int argc, char *argv[])
Definition civserver.c:72
struct civclient client
enum client_states client_state(void)
client_states
Definition client_main.h:43
@ C_S_RUNNING
Definition client_main.h:47
@ C_S_OVER
Definition client_main.h:48
enum known_type client_tile_get_known(const struct tile *ptile)
Definition climap.c:36
bool client_city_can_work_tile(const struct city *pcity, const struct tile *ptile)
Definition climap.c:133
static struct fc_sockaddr_list * list
Definition clinet.c:102
void color_system_free(struct color_system *colors)
struct color * get_player_color(const struct tileset *t, const struct player *pplayer)
struct color_system * color_system_read(struct section_file *file)
struct color * ensure_color(struct rgbcolor *rgb)
bool player_has_color(const struct player *pplayer)
char * incite_cost
Definition comments.c:75
bool unit_is_in_focus(const struct unit *punit)
Definition control.c:388
bool should_ask_server_for_actions(const struct unit *punit)
Definition control.c:339
struct unit_list * get_units_in_focus(void)
Definition control.c:177
struct unit * find_visible_unit(struct tile *ptile)
Definition control.c:834
#define log_deprecation(message,...)
static void road(QVariant data1, QVariant data2)
Definition dialogs.cpp:3152
struct unit struct city struct unit struct tile struct extra_type const struct act_prob *act_probs int actor_unit_id struct unit struct unit int const struct action *paction show_tileset_error
Definition dialogs_g.h:84
struct unit struct city struct unit struct tile struct extra_type const struct act_prob *act_probs int actor_unit_id struct unit struct unit * punit
Definition dialogs_g.h:73
struct unit struct city struct unit struct tile struct extra_type const struct act_prob *act_probs int actor_unit_id struct unit struct unit int const struct action *paction bool const char * tset_name
Definition dialogs_g.h:85
int int id
Definition editgui_g.h:28
bool editor_is_active(void)
Definition editor.c:347
bool editor_tile_is_selected(const struct tile *ptile)
Definition editor.c:1118
int get_target_bonus_effects(struct effect_list *plist, const struct req_context *context, const struct player *other_player, enum effect_type effect_type)
Definition effects.c:748
int get_city_bonus(const struct city *pcity, enum effect_type effect_type)
Definition effects.c:846
enum event_type event
Definition events.c:81
const char * get_event_tag(enum event_type event)
Definition events.c:276
static struct @24 events[]
char * tag_name
Definition events.c:77
struct player * extra_owner(const struct tile *ptile)
Definition extras.c:1114
bool extra_has_flag(const struct extra_type *pextra, enum extra_flag_id flag)
Definition extras.c:861
static struct extra_type extras[MAX_EXTRA_TYPES]
Definition extras.c:31
const char * extra_rule_name(const struct extra_type *pextra)
Definition extras.c:203
bool is_extra_removed_by(const struct extra_type *pextra, enum extra_rmcause rmcause)
Definition extras.c:353
int extra_count(void)
Definition extras.c:153
#define extra_type_iterate(_p)
Definition extras.h:315
#define extra_type_list_iterate(extralist, pextra)
Definition extras.h:165
#define extra_type_iterate_end
Definition extras.h:321
#define is_extra_caused_by(e, c)
Definition extras.h:203
#define extra_index(_e_)
Definition extras.h:183
#define extra_type_list_iterate_end
Definition extras.h:167
#define extra_road_get(_e_)
Definition extras.h:191
#define MAX_VET_LEVELS
Definition fc_types.h:49
#define DIR8_MAGIC_MAX
Definition fc_types.h:471
#define MAX_NUM_ITEMS
Definition fc_types.h:40
int Tech_type_id
Definition fc_types.h:377
#define SP_MAX
Definition fc_types.h:409
int Specialist_type_id
Definition fc_types.h:375
#define MAX_NUM_PLAYER_SLOTS
Definition fc_types.h:32
#define MAX_EXTRA_TYPES
Definition fc_types.h:50
#define MAX_LEN_NAME
Definition fc_types.h:66
@ O_SHIELD
Definition fc_types.h:101
@ O_FOOD
Definition fc_types.h:101
@ O_TRADE
Definition fc_types.h:101
@ O_SCIENCE
Definition fc_types.h:101
@ O_LUXURY
Definition fc_types.h:101
@ O_GOLD
Definition fc_types.h:101
@ O_LAST
Definition fc_types.h:101
@ BORDERS_DISABLED
Definition fc_types.h:1037
enum output_type_id Output_type_id
Definition fc_types.h:378
#define _(String)
Definition fcintl.h:67
struct civ_game game
Definition game.c:62
struct world wld
Definition game.c:63
bool goto_is_active(void)
Definition goto.c:1059
goto_tile_state
Definition goto.h:25
@ GTS_EXHAUSTED_MP
Definition goto.h:28
@ GTS_MP_LEFT
Definition goto.h:27
@ GTS_TURN_STEP
Definition goto.h:26
@ GTS_COUNT
Definition goto.h:30
Government_type_id government_index(const struct government *pgovern)
Definition government.c:82
const char * government_rule_name(const struct government *pgovern)
Definition government.c:133
#define governments_iterate(NAME_pgov)
Definition government.h:124
#define G_LAST
Definition government.h:48
#define governments_iterate_end
Definition government.h:127
struct city * owner
Definition citydlg.c:226
bool is_view_supported(enum ts_type type)
Definition graphics.c:53
void tileset_type_set(enum ts_type type)
Definition graphics.c:67
enum gui_type get_gui_type(void)
Definition gui_main.c:2074
void tileset_changed(void)
Definition mapview.c:782
GType type
Definition repodlgs.c:1313
void free_sprite(struct sprite *s)
Definition sprite.c:278
struct sprite * create_sprite(int width, int height, struct color *pcolor)
Definition sprite.c:84
struct sprite * sprite_scale(struct sprite *src, int new_w, int new_h)
Definition sprite.c:291
struct sprite * load_gfxnumber(int num)
Definition sprite.c:526
struct sprite * load_gfxfile(const char *filename, bool svgflag)
Definition sprite.c:170
const char ** gfx_fileextensions(void)
Definition sprite.c:117
bool popup_theme_suggestion_dialog(const char *theme_name)
Definition theme_dlg.c:46
static bool load_theme
Definition theme_dlg.c:30
void gui_clear_theme(void)
Definition themes.c:72
void boot_help_texts(void)
Definition helpdata.c:768
const char * improvement_rule_name(const struct impr_type *pimprove)
Impr_type_id improvement_index(const struct impr_type *pimprove)
#define improvement_iterate_end
#define improvement_iterate(_p)
#define B_LAST
Definition improvement.h:42
const char * name
Definition inputfile.c:127
#define fc_assert_msg(condition, message,...)
Definition log.h:181
#define fc_assert_ret(condition)
Definition log.h:191
#define log_verbose(message,...)
Definition log.h:109
#define fc_assert(condition)
Definition log.h:176
#define fc_assert_ret_val(condition, val)
Definition log.h:194
#define log_fatal(message,...)
Definition log.h:100
#define fc_assert_action(condition, action)
Definition log.h:187
#define log_debug(message,...)
Definition log.h:115
#define log_normal(message,...)
Definition log.h:107
#define log_base(level, message,...)
Definition log.h:94
log_level
Definition log.h:28
@ LOG_ERROR
Definition log.h:30
@ LOG_DEBUG
Definition log.h:34
@ LOG_NORMAL
Definition log.h:32
@ LOG_FATAL
Definition log.h:29
@ LOG_VERBOSE
Definition log.h:33
#define log_error(message,...)
Definition log.h:103
#define fc_assert_ret_val_msg(condition, val, message,...)
Definition log.h:208
struct startpos * map_startpos_get(const struct tile *ptile)
Definition map.c:1892
enum direction8 dir_ccw(enum direction8 dir)
Definition map.c:1212
bool is_valid_dir(enum direction8 dir)
Definition map.c:1269
enum direction8 dir_cw(enum direction8 dir)
Definition map.c:1183
struct tile * mapstep(const struct civ_map *nmap, const struct tile *ptile, enum direction8 dir)
Definition map.c:371
static int img_index(const int x, const int y, const struct img *pimg)
Definition mapimg.c:1996
struct city * find_city_or_settler_near_tile(const struct tile *ptile, struct unit **punit)
void update_map_canvas_visible(void)
enum topo_comp_lvl tileset_map_topo_compatible(int topology_id, struct tileset *tset, int *tset_topo)
struct tile * get_center_tile_mapcanvas(void)
bool mapdeco_is_highlight_set(const struct tile *ptile)
#define NUM_CITY_COLORS
void center_tile_mapcanvas(const struct tile *ptile)
const struct tile * center_tile
struct tile * client_infratile(void)
const char * describe_topology(int topo)
bool can_slide
bool mapdeco_is_crosshair_set(const struct tile *ptile)
@ TOPO_INCOMP_HARD
#define H(x, y, z)
Definition md5.c:92
#define fc_calloc(n, esz)
Definition mem.h:38
#define fc_strdup(str)
Definition mem.h:43
#define fc_realloc(ptr, sz)
Definition mem.h:36
#define fc_malloc(sz)
Definition mem.h:34
void menus_init(void)
bool is_native_tile(const struct unit_type *punittype, const struct tile *ptile)
Definition movement.c:363
#define SINGLE_MOVE
Definition movement.h:26
const char * nation_rule_name(const struct nation_type *pnation)
Definition nation.c:138
Nation_type_id nation_count(void)
Definition nation.c:507
struct nation_type * nation_of_unit(const struct unit *punit)
Definition nation.c:463
struct nation_type * nation_of_player(const struct player *pplayer)
Definition nation.c:444
struct nation_type * nation_of_city(const struct city *pcity)
Definition nation.c:454
Nation_type_id nation_index(const struct nation_type *pnation)
Definition nation.c:498
#define nations_iterate_end
Definition nation.h:336
#define nations_iterate(NAME_pnation)
Definition nation.h:333
void option_set_default_ts(struct tileset *t)
Definition options.c:6607
const char * option_str_get(const struct option *poption)
Definition options.c:897
int option_get_cb_data(const struct option *poption)
Definition options.c:791
struct client_options gui_options
Definition options.c:72
int len
Definition packhand.c:127
bool player_in_city_map(const struct player *pplayer, const struct tile *ptile)
Definition player.c:1249
int player_slot_index(const struct player_slot *pslot)
Definition player.c:426
int player_index(const struct player *pplayer)
Definition player.c:829
#define players_iterate_end
Definition player.h:537
#define players_iterate(_pplayer)
Definition player.h:532
#define player_slots_iterate(_pslot)
Definition player.h:523
#define player_slots_iterate_end
Definition player.h:527
#define fc_randomly(_seed, _size)
Definition rand.h:73
struct section_file * secfile_load(const char *filename, bool allow_duplicates)
Definition registry.c:50
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,...)
bool secfile_lookup_bool_default(const struct section_file *secfile, bool def, const char *path,...)
int secfile_lookup_int_default(const struct section_file *secfile, int def, const char *path,...)
const char * secfile_lookup_str_default(const struct section_file *secfile, const char *def, const char *path,...)
bool secfile_lookup_bool(const struct section_file *secfile, bool *bval, const char *path,...)
#define section_list_iterate(seclist, psection)
#define secfile_entry_ignore(_sfile_, _fmt_,...)
#define section_list_iterate_end
#define secfile_entry_ignore_by_path(_sfile_, _path_)
bool is_cardinal_only_road(const struct extra_type *pextra)
Definition road.c:483
struct setting_list * level[OLEVELS_NUM]
Definition settings.c:190
const char * fileinfoname(const struct strvec *dirs, const char *filename)
Definition shared.c:1101
struct strvec * fileinfolist(const struct strvec *dirs, const char *suffix)
Definition shared.c:1027
const struct strvec * get_data_dirs(void)
Definition shared.c:893
#define CLIP(lower, current, upper)
Definition shared.h:57
#define ARRAY_SIZE(x)
Definition shared.h:85
#define MAX(x, y)
Definition shared.h:54
#define XOR(p, q)
Definition shared.h:71
struct specialist * specialist_by_number(const Specialist_type_id id)
Definition specialist.c:100
#define specialist_type_iterate_end
Definition specialist.h:79
#define specialist_type_iterate(sp)
Definition specialist.h:73
size_t size
Definition specvec.h:72
struct sprite int int int int struct sprite * mask
Definition sprite_g.h:32
struct sprite int int y
Definition sprite_g.h:31
struct sprite int int int int struct sprite int int float scale
Definition sprite_g.h:33
struct sprite int x
Definition sprite_g.h:31
crop_sprite
Definition sprite_g.h:30
struct sprite int int int int struct sprite int int float bool smooth get_sprite_dimensions
Definition sprite_g.h:36
static bool wall(char *str, bool check)
Definition stdinhand.c:1934
void strvec_destroy(struct strvec *psv)
void strvec_append(struct strvec *psv, const char *string)
struct strvec * strvec_new(void)
#define strvec_iterate(psv, str)
#define strvec_iterate_end
struct sprite * sprite[MAX_NUM_CITIZEN_SPRITES]
Definition tilespec.c:224
struct citizen_graphic citizen[CITIZEN_LAST]
Definition tilespec.c:228
struct citizen_graphic specialist[SP_MAX]
Definition tilespec.c:229
struct city_style_threshold * land_thresholds
Definition tilespec.c:209
struct city_sprite::@228 * styles
int land_num_thresholds
Definition tilespec.c:208
int num_styles
Definition tilespec.c:211
struct sprite * sprite
Definition tilespec.c:203
Definition city.h:320
int color_index
Definition city.h:470
bool occupied
Definition city.h:460
int walls
Definition city.h:461
citizens size
Definition city.h:332
unsigned char first_citizen_index
Definition city.h:483
struct tile * tile
Definition city.h:322
int city_image
Definition city.h:464
bool colored
Definition city.h:469
bool unhappy
Definition city.h:463
struct city::@17::@20 client
struct sprite_vector occupancy
Definition tilespec.h:337
struct rgbcolor * plr_bg_color
Definition game.h:103
struct packet_ruleset_control control
Definition game.h:83
struct packet_game_info info
Definition game.h:89
bool ruleset_ready
Definition game.h:119
struct civ_game::@31::@34 client
int topology_id
Definition map_types.h:72
struct connection conn
Definition client_main.h:96
bool draw_native
Definition options.h:215
bool draw_specials
Definition options.h:207
bool draw_city_output
Definition options.h:194
char gui_sdl3_default_theme_name[512]
Definition options.h:393
bool draw_mines
Definition options.h:205
bool draw_borders
Definition options.h:214
bool draw_fortress_airbase
Definition options.h:206
bool draw_unit_stack_size
Definition options.h:218
bool draw_irrigation
Definition options.h:204
bool draw_terrain
Definition options.h:201
bool draw_units
Definition options.h:211
int default_topology
Definition options.h:123
bool draw_fog_of_war
Definition options.h:213
bool draw_unit_shields
Definition options.h:217
char gui_sdl2_default_theme_name[512]
Definition options.h:380
bool draw_cities
Definition options.h:210
bool draw_map_grid
Definition options.h:195
bool draw_focus_unit
Definition options.h:212
bool draw_paths
Definition options.h:203
bool draw_city_outlines
Definition options.h:193
bool draw_coastline
Definition options.h:202
bool draw_full_citybar
Definition options.h:216
bool draw_pollution
Definition options.h:209
char gui_gtk4_default_theme_name[512]
Definition options.h:337
char gui_gtk3_22_default_theme_name[512]
Definition options.h:301
bool solid_color_behind_units
Definition options.h:149
Definition colors.h:21
bool established
Definition connection.h:140
struct player * playing
Definition connection.h:151
int match_index[1+MAX_NUM_MATCH_WITH]
Definition tilespec.c:181
enum match_style match_style
Definition tilespec.c:180
enum sprite_type sprite_type
Definition tilespec.c:184
struct sprite_vector allocated
Definition tilespec.c:192
struct sprite * match[MAX_INDEX_CARDINAL]
Definition tilespec.c:187
struct sprite_vector base
Definition tilespec.c:186
struct sprite ** cells
Definition tilespec.c:188
bool is_reversed
Definition tilespec.c:195
struct sprite * blend[4]
Definition tilespec.c:199
struct drawing_data::drawing_layer layer[MAX_NUM_LAYERS]
struct sprite * blender
Definition tilespec.c:198
char * name
Definition tilespec.c:170
char rmact_gfx[MAX_LEN_NAME]
Definition extras.h:102
char act_gfx_alt[MAX_LEN_NAME]
Definition extras.h:100
struct extra_type_list * hiders
Definition extras.h:144
char rmact_gfx_alt[MAX_LEN_NAME]
Definition extras.h:103
struct road_type * road
Definition extras.h:155
char rmact_gfx_alt2[MAX_LEN_NAME]
Definition extras.h:104
char graphic_alt[MAX_LEN_NAME]
Definition extras.h:98
char activity_gfx[MAX_LEN_NAME]
Definition extras.h:99
char act_gfx_alt2[MAX_LEN_NAME]
Definition extras.h:101
char graphic_str[MAX_LEN_NAME]
Definition extras.h:97
char graphic_alt[MAX_LEN_NAME]
Definition government.h:58
char graphic_str[MAX_LEN_NAME]
Definition government.h:57
char graphic_str[MAX_LEN_NAME]
Definition improvement.h:55
char graphic_alt2[MAX_LEN_NAME]
Definition improvement.h:57
char graphic_alt[MAX_LEN_NAME]
Definition improvement.h:56
struct named_sprites::@239::@245::@247::@248::@249 combo
struct sprite * graphic
Definition tilespec.c:404
struct sprite * tax_gold
Definition tilespec.c:248
struct sprite * government[G_LAST]
Definition tilespec.c:260
union named_sprites::@239::@245 u
struct sprite_vector nation_shield
Definition tilespec.c:268
struct citizen_set default_citizens
Definition tilespec.c:270
struct sprite * loaded
Definition tilespec.c:300
struct sprite * even[MAX_INDEX_HALF]
Definition tilespec.c:377
struct sprite * output[O_LAST][MAX_NUM_UPKEEP_SPRITES]
Definition tilespec.c:313
struct sprite ** stack
Definition tilespec.c:299
struct sprite * infratile
Definition tilespec.c:345
struct sprite * background
Definition tilespec.c:362
struct sprite * frame[NUM_CURSOR_FRAMES]
Definition tilespec.c:276
struct sprite * patrol
Definition tilespec.c:303
struct sprite * spaceship[SPACESHIP_COUNT]
Definition tilespec.c:273
struct named_sprites::@239 extras[MAX_EXTRA_TYPES]
struct named_sprites::@239::@245::@247 road
struct sprite * rmact
Definition tilespec.c:356
struct sprite * selected[EDGE_COUNT]
Definition tilespec.c:395
int num_stack_sprites
Definition tilespec.c:283
struct sprite * transform
Definition tilespec.c:301
struct named_sprites::@239::@245::@246 bmf
struct sprite * tile_shieldnum[NUM_TILES_DIGITS]
Definition tilespec.c:322
struct sprite ** fullfog
Definition tilespec.c:350
struct sprite_vector unworked_tile_overlay
Definition tilespec.c:330
enum extrastyle_id extrastyle
Definition tilespec.c:357
struct sprite * tile_foodnum[NUM_TILES_DIGITS]
Definition tilespec.c:321
struct sprite * turns[NUM_TILES_DIGITS]
Definition tilespec.c:337
struct sprite_vector nation_flag
Definition tilespec.c:267
struct named_sprites::@238 tx
struct sprite * nonnative
Definition tilespec.c:394
struct sprite * plant
Definition tilespec.c:296
bool no_more_stack_sprites
Definition tilespec.c:284
struct named_sprites::@229 mask
struct city_sprite * single_wall
Definition tilespec.c:326
struct sprite * indicator[INDICATOR_COUNT][NUM_TILES_PROGRESS]
Definition tilespec.c:238
struct sprite * borders[EDGE_COUNT][2]
Definition tilespec.c:397
struct named_sprites::@232 explode
struct sprite * size_tens[NUM_TILES_DIGITS]
Definition tilespec.c:319
struct city_sprite * tile
Definition tilespec.c:324
struct sprite * disorder
Definition tilespec.c:316
struct sprite * tile_tradenum[NUM_TILES_DIGITS]
Definition tilespec.c:323
struct sprite * unworked_tile
Definition tilespec.c:255
struct named_sprites::@236 path
struct named_sprites::@240 grid
struct sprite * waypoint
Definition tilespec.c:341
struct sprite * pillage
Definition tilespec.c:297
struct named_sprites::@241 colors
struct sprite * auto_settler
Definition tilespec.c:290
struct sprite * fortified
Definition tilespec.c:292
struct sprite * dither_tile
Definition tilespec.c:249
struct sprite * coastline[EDGE_COUNT]
Definition tilespec.c:396
struct sprite * tired
Definition tilespec.c:308
struct style_citizen_set style_citizen_sets
Definition tilespec.c:271
struct sprite * isolated
Definition tilespec.c:368
struct sprite * treaty_thumb[2]
Definition tilespec.c:240
struct sprite * sentry
Definition tilespec.c:298
struct sprite * tax_luxury
Definition tilespec.c:248
struct sprite_vector unit
Definition tilespec.c:279
struct sprite * building[B_LAST]
Definition tilespec.c:259
struct sprite * turns_hundreds[NUM_TILES_DIGITS]
Definition tilespec.c:339
struct sprite * total[MAX_INDEX_VALID]
Definition tilespec.c:382
struct sprite * action_decision_want
Definition tilespec.c:306
struct sprite * unhappy[MAX_NUM_UPKEEP_SPRITES]
Definition tilespec.c:311
struct named_sprites::@231 cursor[CURSOR_LAST]
struct sprite_vector worked_tile_overlay
Definition tilespec.c:329
struct sprite * corner[8]
Definition tilespec.c:371
struct sprite * darkness[MAX_INDEX_CARDINAL]
Definition tilespec.c:351
struct named_sprites::@235 city
struct sprite * tax_science
Definition tilespec.c:248
struct sprite * icon[ICON_COUNT]
Definition tilespec.c:243
struct sprite * specific
Definition tilespec.c:336
struct sprite * odd[MAX_INDEX_HALF]
Definition tilespec.c:379
struct named_sprites::@236::@244 s[GTS_COUNT]
struct sprite * color
Definition tilespec.c:403
union named_sprites::@239::@245::@247::@248 ru
struct sprite * unavailable
Definition tilespec.c:393
struct sprite * worked_tile
Definition tilespec.c:254
struct river_sprites rivers
Definition tilespec.c:383
struct named_sprites::@234 upkeep
struct drawing_data * drawing[MAX_NUM_ITEMS]
Definition tilespec.c:412
struct sprite * go_to
Definition tilespec.c:294
struct sprite * middleground
Definition tilespec.c:364
struct sprite * foreground
Definition tilespec.c:365
struct citybar_sprites citybar
Definition tilespec.c:332
struct sprite * auto_explore
Definition tilespec.c:291
struct sprite * turns_tens[NUM_TILES_DIGITS]
Definition tilespec.c:338
struct sprite * tech[A_LAST]
Definition tilespec.c:258
struct sprite * nuke
Definition tilespec.c:280
struct sprite * convert
Definition tilespec.c:304
struct sprite * worked[EDGE_COUNT]
Definition tilespec.c:392
struct sprite_vector overlays
Definition tilespec.c:400
struct named_sprites::@243 player[MAX_NUM_PLAYER_SLOTS]
struct editor_sprites editor
Definition tilespec.c:333
struct sprite * size_hundreds[NUM_TILES_DIGITS]
Definition tilespec.c:320
struct sprite * activity
Definition tilespec.c:354
struct sprite * size[NUM_TILES_DIGITS]
Definition tilespec.c:318
struct sprite * cardinals[MAX_INDEX_CARDINAL]
Definition tilespec.c:360
struct sprite * fortifying
Definition tilespec.c:293
struct sprite * main[EDGE_COUNT]
Definition tilespec.c:389
struct sprite * events[E_COUNT]
Definition tilespec.c:245
struct sprite * auto_attack
Definition tilespec.c:289
struct named_sprites::@230 units
struct city_sprite * wall[NUM_WALL_TYPES]
Definition tilespec.c:327
struct sprite * connect
Definition tilespec.c:302
struct sprite * fog
Definition tilespec.c:348
struct sprite * arrow[ARROW_LAST]
Definition tilespec.c:241
struct sprite * dir[8]
Definition tilespec.c:374
struct sprite * single
Definition tilespec.c:359
struct sprite * grid_borders[EDGE_COUNT][2]
Definition tilespec.c:407
struct named_sprites::@237 user
struct sprite * facing[U_LAST][DIR8_MAGIC_MAX][ACTIVITY_LAST]
Definition tilespec.c:264
struct sprite * attention
Definition tilespec.c:344
struct city_sprite * occupied
Definition tilespec.c:328
struct sprite * tile
Definition tilespec.c:252
struct sprite * cultivate
Definition tilespec.c:295
struct sprite * lowfuel
Definition tilespec.c:307
char flag_graphic_str[MAX_LEN_NAME]
Definition nation.h:103
char flag_graphic_alt[MAX_LEN_NAME]
Definition nation.h:104
enum borders_mode borders
Definition goto.c:52
struct sprite * spec[MAX_INDEX_CARDINAL]
Definition tilespec.c:215
struct sprite * outlet[MAX_INDEX_CARDINAL]
Definition tilespec.c:217
struct sprite * sprite
Definition themespec.c:109
char * file
Definition themespec.c:100
struct specfile * sf
Definition themespec.c:103
char * file_name
Definition themespec.c:80
struct sprite * big_sprite
Definition themespec.c:79
char graphic_alt[MAX_LEN_NAME]
Definition specialist.h:36
Definition map.c:41
struct citizen_set * sets
Definition tilespec.c:233
char graphic_alt2[MAX_LEN_NAME]
Definition terrain.h:189
char graphic_alt[MAX_LEN_NAME]
Definition terrain.h:188
char graphic_str[MAX_LEN_NAME]
Definition terrain.h:187
Definition tile.h:50
char * spec_sprite
Definition tile.h:66
struct unit_list * units
Definition tile.h:58
struct extra_type * placing
Definition tile.h:61
struct city * worked
Definition tile.h:59
char given_name[MAX_LEN_NAME]
Definition tilespec.c:483
int num_cardinal_tileset_dirs
Definition tilespec.c:535
int occupied_offset_x
Definition tilespec.c:528
int stack_size_offset_y
Definition tilespec.c:527
struct named_sprites sprites
Definition tilespec.c:555
int ts_topo_idx
Definition tilespec.c:497
int hex_height
Definition tilespec.c:496
enum fog_style fogstyle
Definition tilespec.c:511
int normal_tile_height
Definition tilespec.c:499
int unit_tile_width
Definition tilespec.c:501
int city_offset_y
Definition tilespec.c:517
char * main_intro_filename
Definition tilespec.c:507
enum ts_type type
Definition tilespec.c:495
int city_size_offset_x
Definition tilespec.c:518
int num_preferred_themes
Definition tilespec.c:563
char version[MAX_LEN_NAME]
Definition tilespec.c:484
int full_tile_height
Definition tilespec.c:500
int small_sprite_width
Definition tilespec.c:502
char ** preferred_themes
Definition tilespec.c:564
struct extra_type_list * flagged_bases_list
Definition tilespec.c:561
enum darkness_style darkness_style
Definition tilespec.c:512
int activity_offset_x
Definition tilespec.c:522
int citybar_offset_y
Definition tilespec.c:520
int normal_tile_width
Definition tilespec.c:499
float scale
Definition tilespec.c:489
int svg_height
Definition tilespec.c:505
int unit_tile_height
Definition tilespec.c:501
int hex_width
Definition tilespec.c:496
int select_offset_y
Definition tilespec.c:525
int city_flag_offset_x
Definition tilespec.c:515
int unit_flag_offset_x
Definition tilespec.c:514
int occupied_offset_y
Definition tilespec.c:529
char * description
Definition tilespec.c:488
int max_upkeep_height
Definition tilespec.c:504
int unit_flag_offset_y
Definition tilespec.c:514
int unit_upkeep_offset_y
Definition tilespec.c:530
struct estyle_hash * estyle_hash
Definition tilespec.c:553
char * for_ruleset
Definition tilespec.c:491
int activity_offset_y
Definition tilespec.c:523
int num_index_valid
Definition tilespec.c:536
int select_offset_x
Definition tilespec.c:524
int num_index_cardinal
Definition tilespec.c:536
int full_tile_width
Definition tilespec.c:500
struct small_sprite_list * small_sprites
Definition tilespec.c:545
struct extra_type_list * style_lists[ESTYLE_COUNT]
Definition tilespec.c:559
enum direction8 unit_default_orientation
Definition tilespec.c:509
struct tileset::tileset_layer layers[MAX_NUM_LAYERS]
int small_sprite_height
Definition tilespec.c:502
int city_size_offset_y
Definition tilespec.c:518
struct sprite_hash * sprite_hash
Definition tilespec.c:548
int unit_upkeep_small_offset_y
Definition tilespec.c:531
int unit_offset_x
Definition tilespec.c:516
int unit_offset_y
Definition tilespec.c:516
enum mapview_layer layer_order[LAYER_COUNT]
Definition tilespec.c:493
int city_offset_x
Definition tilespec.c:517
int priority
Definition tilespec.c:485
enum direction8 cardinal_tileset_dirs[8]
Definition tilespec.c:537
enum direction8 valid_tileset_dirs[8]
Definition tilespec.c:537
struct color_system * color_system
Definition tilespec.c:557
char * summary
Definition tilespec.c:487
char name[512]
Definition tilespec.c:482
int city_flag_offset_y
Definition tilespec.c:515
struct drawing_hash * tile_hash
Definition tilespec.c:551
int num_valid_tileset_dirs
Definition tilespec.c:535
int stack_size_offset_x
Definition tilespec.c:526
struct specfile_list * specfiles
Definition tilespec.c:544
int tilelabel_offset_y
Definition tilespec.c:521
Definition unit.h:137
struct unit::@80 orders
bool occupied
Definition unit.h:218
enum action_decision action_decision_want
Definition unit.h:201
int battlegroup
Definition unit.h:190
enum unit_activity activity
Definition unit.h:156
int moves_left
Definition unit.h:149
struct unit::@81::@83 client
int hp
Definition unit.h:150
int fuel
Definition unit.h:152
enum direction8 facing
Definition unit.h:141
struct extra_type * activity_target
Definition unit.h:163
bool repeat
Definition unit.h:195
int veteran
Definition unit.h:151
enum server_side_agent ssa_controller
Definition unit.h:171
struct civ_map map
int style_of_city(const struct city *pcity)
Definition style.c:202
int fc_snprintf(char *str, size_t n, const char *format,...)
Definition support.c:974
size_t fc_strlcpy(char *dest, const char *src, size_t n)
Definition support.c:791
int fc_strcasecmp(const char *str0, const char *str1)
Definition support.c:189
int cat_snprintf(char *str, size_t n, const char *format,...)
Definition support.c:1000
int fc_vsnprintf(char *str, size_t n, const char *format, va_list ap)
Definition support.c:900
#define sz_strlcpy(dest, src)
Definition support.h:195
#define TRUE
Definition support.h:46
#define FALSE
Definition support.h:47
const char ** ordered_gfx_fextensions(void)
Definition svgflag.c:53
void get_flag_dimensions(struct sprite *flag, struct area_rect *rect, int svg_height)
Definition svgflag.c:123
#define is_svg_flag_enabled()
Definition svgflag.h:30
struct advance * valid_advance(struct advance *padvance)
Definition tech.c:152
const char * advance_rule_name(const struct advance *padvance)
Definition tech.c:299
Tech_type_id advance_index(const struct advance *padvance)
Definition tech.c:89
static Tech_type_id advance_count(void)
Definition tech.h:170
#define advance_iterate(_p)
Definition tech.h:275
#define advance_iterate_end
Definition tech.h:276
#define A_LAST
Definition tech.h:45
Terrain_type_id terrain_index(const struct terrain *pterrain)
Definition terrain.c:138
const char * terrain_rule_name(const struct terrain *pterrain)
Definition terrain.c:247
enum terrain_class terrain_type_terrain_class(const struct terrain *pterrain)
Definition terrain.c:582
#define terrain_type_iterate(_p)
Definition terrain.h:373
#define T_UNKNOWN
Definition terrain.h:57
#define is_ocean_tile(ptile)
Definition terrain.h:303
#define terrain_type_iterate_end
Definition terrain.h:379
#define tile_index(_pt_)
Definition tile.h:88
#define tile_worked(_tile)
Definition tile.h:118
@ TILE_KNOWN_UNSEEN
Definition tile.h:37
@ TILE_UNKNOWN
Definition tile.h:36
@ TILE_KNOWN_SEEN
Definition tile.h:38
#define tile_terrain(_tile)
Definition tile.h:114
#define TILE_XY(ptile)
Definition tile.h:43
static const bv_extras * tile_extras(const struct tile *ptile)
Definition tile.h:124
#define tile_has_extra(ptile, pextra)
Definition tile.h:151
#define tile_owner(_tile)
Definition tile.h:96
static int fill_unit_type_sprite_array(const struct tileset *t, struct drawn_sprite *sprs, const struct unit_type *putype, enum unit_activity activity, enum direction8 facing)
Definition tilespec.c:4552
struct sprite * get_government_sprite(const struct tileset *t, const struct government *gov)
Definition tilespec.c:6808
void tileset_load_tiles(struct tileset *t)
Definition tilespec.c:3632
struct sprite * get_nuke_explode_sprite(const struct tileset *t)
Definition tilespec.c:6944
#define sprite_hash_iterate(hash, tag_name, sprite)
Definition tilespec.c:462
int tileset_hex_width(const struct tileset *t)
Definition tilespec.c:721
struct sprite * get_building_sprite(const struct tileset *t, const struct impr_type *pimprove)
Definition tilespec.c:6798
int tileset_unit_width(const struct tileset *t)
Definition tilespec.c:797
static int fill_goto_sprite_array(const struct tileset *t, struct drawn_sprite *sprs, const struct tile *ptile, const struct tile_edge *pedge, const struct tile_corner *pcorner)
Definition tilespec.c:5687
#define NUM_TILES_SELECT
Definition tilespec.c:114
struct unit * get_drawable_unit(const struct tileset *t, struct tile *ptile, const struct city *citymode)
Definition tilespec.c:6579
static int check_sprite_type(const char *sprite_type, const char *tile_section)
Definition tilespec.c:1868
struct sprite * get_attention_crosshair_sprite(const struct tileset *t)
Definition tilespec.c:7005
int tileset_unit_height(const struct tileset *t)
Definition tilespec.c:805
static struct tileset * tileset_new(void)
Definition tilespec.c:971
#define MAX_INDEX_VALID
Definition tilespec.c:110
void tileset_setup_unit_type(struct tileset *t, struct unit_type *ut)
Definition tilespec.c:3810
static bool check_tilespec_capabilities(struct section_file *file, const char *which, const char *us_capstr, const char *filename, bool verbose)
Definition tilespec.c:1164
int tileset_small_sprite_width(const struct tileset *t)
Definition tilespec.c:901
static struct sprite * load_gfx_file(const char *gfx_filename, bool svgflag)
Definition tilespec.c:1561
#define specfile_list_iterate_end
Definition tilespec.c:426
static struct sprite * create_plr_sprite(struct color *pcolor)
Definition tilespec.c:2792
int tileset_svg_flag_height(struct tileset *t)
Definition tilespec.c:7585
#define SPEC_CAPSTR
Definition tilespec.c:96
static struct sprite * get_unit_nation_flag_sprite(const struct tileset *t, const struct unit *punit)
Definition tilespec.c:4483
direction4
Definition tilespec.c:138
@ DIR4_EAST
Definition tilespec.c:139
@ DIR4_NORTH
Definition tilespec.c:139
@ DIR4_SOUTH
Definition tilespec.c:139
@ DIR4_WEST
Definition tilespec.c:139
struct tileset * get_tileset(void)
Definition tilespec.c:692
#define MAX_NUM_MATCH_WITH
Definition tilespec.c:179
static struct sprite * get_city_sprite(const struct city_sprite *city_sprite, const struct city *pcity)
Definition tilespec.c:3039
void tileset_setup_government(struct tileset *t, struct government *gov)
Definition tilespec.c:4424
#define sprite_hash_iterate_end
Definition tilespec.c:465
struct sprite * get_city_flag_sprite(const struct tileset *t, const struct city *pcity)
Definition tilespec.c:4474
void tileset_setup_specialist_type_default_set(struct tileset *t, Specialist_type_id id)
Definition tilespec.c:2895
static bool is_valid_tileset_dir(const struct tileset *t, enum direction8 dir)
Definition tilespec.c:1030
struct sprite * get_basic_fog_sprite(const struct tileset *t)
Definition tilespec.c:7068
static enum direction8 dir_by_tileset_name(const char *str)
Definition tilespec.c:1012
#define ADD_SPRITE_SIMPLE(s)
Definition tilespec.c:4509
static int fill_basic_road_sprite_array(const struct tileset *t, struct drawn_sprite *sprs, const struct extra_type *pextra)
Definition tilespec.c:7250
static int fill_unit_sprite_array(const struct tileset *t, struct drawn_sprite *sprs, const struct unit *punit, int stack, bool backdrop)
Definition tilespec.c:4571
int tileset_full_tile_height(const struct tileset *t)
Definition tilespec.c:789
bool tilespec_try_read(const char *tileset_name, bool verbose, int topo_id, bool global_default)
Definition tilespec.c:1296
static bool tileset_setup_unit_type_from_tag(struct tileset *t, int uidx, const char *tag)
Definition tilespec.c:3753
struct tileset * unscaled_tileset
Definition tilespec.c:568
static int fill_irrigation_sprite_array(const struct tileset *t, struct drawn_sprite *sprs, bv_extras textras, bv_extras *textras_near, const struct city *pcity)
Definition tilespec.c:5042
int fill_basic_extra_sprite_array(const struct tileset *t, struct drawn_sprite *sprs, const struct extra_type *pextra)
Definition tilespec.c:7215
#define specfile_list_iterate(list, pitem)
Definition tilespec.c:424
struct sprite * get_unit_upkeep_sprite(const struct tileset *t, Output_type_id otype, const struct unit *punit, const int *upkeep_cost)
Definition tilespec.c:7050
const char * tileset_main_intro_filename(const struct tileset *t)
Definition tilespec.c:947
void tileset_setup_tile_type(struct tileset *t, const struct terrain *pterrain)
Definition tilespec.c:4158
static const char direction4letters[4]
Definition tilespec.c:141
void tileset_player_init(struct tileset *t, struct player *pplayer)
Definition tilespec.c:7386
const struct strvec * get_tileset_list(const struct option *poption)
Definition tilespec.c:1103
int tileset_unit_layout_offset_y(const struct tileset *t)
Definition tilespec.c:882
int tileset_citybar_offset_y(const struct tileset *t)
Definition tilespec.c:910
#define MAX_NUM_UPKEEP_SPRITES
Definition tilespec.c:115
struct sprite * get_treaty_thumb_sprite(const struct tileset *t, bool on_off)
Definition tilespec.c:6924
bool unit_drawn_with_city_outline(const struct unit *punit, bool check_focus)
Definition tilespec.c:5520
#define MAX_INDEX_HALF
Definition tilespec.c:109
double get_focus_unit_toggle_timeout(const struct tileset *t)
Definition tilespec.c:6534
#define SET_SPRITE_ALT_OPT(field, tag, alt)
Definition tilespec.c:2885
static int calculate_max_upkeep_height(const struct tileset *t)
Definition tilespec.c:813
static int fill_fog_sprite_array(const struct tileset *t, struct drawn_sprite *sprs, const struct tile *ptile, const struct tile_edge *pedge, const struct tile_corner *pcorner)
Definition tilespec.c:5204
#define TILE_SECTION_PREFIX
Definition tilespec.c:105
static struct city_sprite * load_city_sprite(struct tileset *t, const char *tag)
Definition tilespec.c:3116
static char * valid_index_str(const struct tileset *t, int idx)
Definition tilespec.c:2699
void tileset_free_tiles(struct tileset *t)
Definition tilespec.c:6619
void tileset_setup_impr_type(struct tileset *t, struct impr_type *pimprove)
Definition tilespec.c:3844
static struct tileset * tileset_read_toplevel(const char *tileset_name, bool verbose, int topology_id, float scale)
Definition tilespec.c:1889
static bool sprite_exists(const struct tileset *t, const char *tag_name)
Definition tilespec.c:2832
const struct sprite_vector * get_unit_explode_animation(const struct tileset *t)
Definition tilespec.c:6933
#define TILESPEC_CAPSTR
Definition tilespec.c:80
static int load_city_thresholds_sprites(struct tileset *t, const char *tag, char *graphic, char *graphic_alt, struct city_style_threshold **thresholds)
Definition tilespec.c:3075
struct sprite * load_popup_sprite(const char *tag)
Definition tilespec.c:7593
static void unload_all_sprites(struct tileset *t)
Definition tilespec.c:6605
static const char * dir_get_tileset_name(enum direction8 dir)
Definition tilespec.c:985
#define SET_SPRITE_UNSCALED(field, tag)
Definition tilespec.c:2858
void tileset_background_init(struct tileset *t)
Definition tilespec.c:7466
void tileset_setup_tech_type(struct tileset *t, struct advance *padvance)
Definition tilespec.c:3860
static const int DIR4_TO_DIR8[4]
Definition tilespec.c:145
static int fill_terrain_sprite_layer(struct tileset *t, struct drawn_sprite *sprs, int layer_num, const struct tile *ptile, const struct terrain *pterrain, struct terrain **tterrain_near)
Definition tilespec.c:5475
static void unload_sprite(struct tileset *t, const char *tag_name)
Definition tilespec.c:2808
static void drawing_data_destroy(struct drawing_data *draw)
Definition tilespec.c:660
static int fill_terrain_sprite_darkness(struct tileset *t, struct drawn_sprite *sprs, const struct tile *ptile, struct terrain **tterrain_near)
Definition tilespec.c:5411
#define small_sprite_list_iterate_end
Definition tilespec.c:455
static struct drawing_data * drawing_data_new(void)
Definition tilespec.c:648
static void build_tile_data(const struct tile *ptile, struct terrain *pterrain, struct terrain **tterrain_near, bv_extras *textras_near)
Definition tilespec.c:4520
static void tileset_player_free(struct tileset *t, int plrid)
Definition tilespec.c:7437
float tileset_scale(const struct tileset *t)
Definition tilespec.c:927
#define UNKNOWN(dir)
int tileset_unit_with_small_upkeep_height(const struct tileset *t)
Definition tilespec.c:871
bool tileset_layer_in_category(enum mapview_layer layer, enum layer_category cat)
Definition tilespec.c:7343
static int fill_grid_sprite_array(const struct tileset *t, struct drawn_sprite *sprs, const struct tile *ptile, const struct tile_edge *pedge, const struct tile_corner *pcorner, const struct unit *punit, const struct city *pcity, const struct city *citymode)
Definition tilespec.c:5537
match_style
Definition tilespec.c:148
@ MATCH_SAME
Definition tilespec.c:150
@ MATCH_FULL
Definition tilespec.c:152
@ MATCH_PAIR
Definition tilespec.c:151
@ MATCH_NONE
Definition tilespec.c:149
#define small_sprite_list_iterate(list, pitem)
Definition tilespec.c:453
int tileset_num_city_colors(const struct tileset *t)
Definition tilespec.c:955
int index_ts_topology(int idx)
Definition tilespec.c:1085
#define NUM_TILES_HP_BAR
Definition tilespec.c:112
#define TILESPEC_SUFFIX
Definition tilespec.c:104
bool tileset_is_isometric(const struct tileset *t)
Definition tilespec.c:712
bool tileset_use_hard_coded_fog(const struct tileset *t)
Definition tilespec.c:963
void tileset_use_preferred_theme(const struct tileset *t)
Definition tilespec.c:7084
#define FULL_TILE_X_OFFSET
Definition tilespec.c:4495
sprite_type
Definition tilespec.c:155
@ CELL_CORNER
Definition tilespec.c:157
@ CELL_WHOLE
Definition tilespec.c:156
void tileset_setup_city_tiles(struct tileset *t, int style)
Definition tilespec.c:6469
struct sprite * get_nation_shield_sprite(const struct tileset *t, const struct nation_type *pnation)
Definition tilespec.c:6780
const char * tileset_description(struct tileset *t)
Definition tilespec.c:7561
#define SET_GOTO_TURN_SPRITE(state, state_name, factor, factor_name)
void tileset_background_free(struct tileset *t)
Definition tilespec.c:7485
#define MAX_NUM_LAYERS
Definition tilespec.c:173
int tileset_unit_layout_small_offset_y(const struct tileset *t)
Definition tilespec.c:891
struct sprite * get_event_sprite(const struct tileset *t, enum event_type event)
Definition tilespec.c:6915
void toggle_focus_unit_state(struct tileset *t)
Definition tilespec.c:6566
void tilespec_reread_frozen_refresh(const char *tname)
Definition tilespec.c:1549
int tileset_small_sprite_height(const struct tileset *t)
Definition tilespec.c:937
void tileset_free(struct tileset *t)
Definition tilespec.c:1274
static const char * cardinal_index_str(const struct tileset *t, int idx)
Definition tilespec.c:2679
#define NUM_TILES_DIGITS
Definition tilespec.c:113
void focus_unit_in_combat(struct tileset *t)
Definition tilespec.c:6555
static int tileset_upkeep_height(const struct tileset *t)
Definition tilespec.c:850
const char * tileset_summary(struct tileset *t)
Definition tilespec.c:7553
struct sprite * get_icon_sprite(const struct tileset *t, enum icon_type icon)
Definition tilespec.c:6994
static void ensure_big_sprite(struct specfile *sf, const char *tset_name)
Definition tilespec.c:1597
static bool tileset_update
Definition tilespec.c:572
#define FULL_TILE_Y_OFFSET
Definition tilespec.c:4496
struct sprite * get_indicator_sprite(const struct tileset *t, enum indicator_type indicator, int idx)
Definition tilespec.c:7014
struct sprite * get_sample_city_sprite(const struct tileset *t, int style_idx)
Definition tilespec.c:6866
#define ADD_SPRITE_FULL(s)
Definition tilespec.c:4510
void tileset_setup_extra(struct tileset *t, struct extra_type *pextra)
Definition tilespec.c:3879
int focus_unit_state
Definition tilespec.c:570
void tileset_init(struct tileset *t)
Definition tilespec.c:7141
static int fill_city_overlays_sprite_array(const struct tileset *t, struct drawn_sprite *sprs, const struct tile *ptile, const struct city *citymode)
Definition tilespec.c:5084
static char * tilespec_gfx_filename(const char *gfx_filename, const char *tset_name)
Definition tilespec.c:1803
const char * tileset_basename(const struct tileset *t)
Definition tilespec.c:704
int fill_basic_terrain_layer_sprite_array(struct tileset *t, struct drawn_sprite *sprs, int layer, struct terrain *pterrain)
Definition tilespec.c:7182
int tileset_tile_height(const struct tileset *t)
Definition tilespec.c:765
#define LOAD_FACING_SPRITE(dir)
#define SET_SPRITE_NOTSMOOTH(field, tag)
Definition tilespec.c:2849
static int fill_road_corner_sprites(const struct tileset *t, const struct extra_type *pextra, struct drawn_sprite *sprs, bool road, bool *road_near, bool hider, bool *hider_near)
Definition tilespec.c:4759
static bool is_extra_drawing_enabled(struct extra_type *pextra)
Definition tilespec.c:5755
struct sprite * get_spaceship_sprite(const struct tileset *t, enum spaceship_part part)
Definition tilespec.c:6706
int tileset_unit_with_upkeep_height(const struct tileset *t)
Definition tilespec.c:859
static void tileset_free_toplevel(struct tileset *t)
Definition tilespec.c:1202
static struct sprite * load_sprite(struct tileset *t, const char *tag_name, bool scale, bool smooth, bool svgflag)
Definition tilespec.c:2722
struct sprite * get_cursor_sprite(const struct tileset *t, enum cursor_type cursor, int *hot_x, int *hot_y, int frame)
Definition tilespec.c:6975
static const char edge_name[EDGE_COUNT][3]
Definition tilespec.c:143
struct color_system * get_color_system(const struct tileset *t)
Definition tilespec.c:7076
int tileset_hex_height(const struct tileset *t)
Definition tilespec.c:730
void reset_focus_unit_state(struct tileset *t)
Definition tilespec.c:6547
static const char * citizen_rule_name(enum citizen_category citizen)
Definition tilespec.c:2654
static void tileset_setup_citizen_types_default_set(struct tileset *t)
Definition tilespec.c:2989
bool tileset_is_fully_loaded(void)
Definition tilespec.c:7529
static int fill_terrain_sprite_blending(const struct tileset *t, struct drawn_sprite *sprs, const struct tile *ptile, const struct terrain *pterrain, struct terrain **tterrain_near)
Definition tilespec.c:5164
const struct citybar_sprites * get_citybar_sprites(const struct tileset *t)
Definition tilespec.c:6952
static bool is_cardinal_tileset_dir(const struct tileset *t, enum direction8 dir)
Definition tilespec.c:1048
void unload_popup_sprite(const char *tag)
Definition tilespec.c:7601
#define SET_SPRITE(field, tag)
Definition tilespec.c:2839
static void tileset_lookup_sprite_tags(struct tileset *t)
Definition tilespec.c:3164
struct sprite * get_arrow_sprite(const struct tileset *t, enum arrow_type arrow)
Definition tilespec.c:6883
struct sprite * get_unit_unhappy_sprite(const struct tileset *t, const struct unit *punit, int happy_cost)
Definition tilespec.c:7031
#define NUM_CORNER_DIRS
Definition tilespec.c:533
static int fill_basic_base_sprite_array(const struct tileset *t, struct drawn_sprite *sprs, const struct extra_type *pextra)
Definition tilespec.c:7298
static void tileset_setup_base(struct tileset *t, const struct extra_type *pextra, const char *tag)
Definition tilespec.c:4120
static int fill_road_sprite_array(const struct tileset *t, const struct extra_type *pextra, struct drawn_sprite *sprs, bv_extras textras, bv_extras *textras_near, struct terrain *tterrain_near[8], const struct city *pcity)
Definition tilespec.c:4810
void finish_loading_sprites(struct tileset *t)
Definition tilespec.c:3616
static bool tileset_scan_single_list(struct tileset *t, const char *spec_filenames[], int num_spec_files, bool verbose, bool duplicates_ok)
Definition tilespec.c:1834
struct sprite * tiles_lookup_sprite_tag_alt(struct tileset *t, enum log_level level, const char *tag, const char *alt, const char *alt2, const char *what, const char *name, bool scale)
Definition tilespec.c:3643
#define SET_EDITOR_SPRITE(x)
#define SET_SPRITE_ALT(field, tag, alt)
Definition tilespec.c:2868
#define SET_SPRITE_OPT(field, tag)
Definition tilespec.c:2882
void tilespec_reread_callback(struct option *poption)
Definition tilespec.c:1513
static void tileset_setup_specialist_type(struct tileset *t, struct citizen_set *set, Specialist_type_id id, const char *tag_group, const char *set_name, bool required)
Definition tilespec.c:2905
static bool load_river_sprites(struct tileset *t, struct river_sprites *store, const char *tag_pfx)
Definition tilespec.c:3582
const char * tileset_name_get(struct tileset *t)
Definition tilespec.c:7537
static char * tilespec_fullname(const char *tileset_name)
Definition tilespec.c:1140
static const struct citizen_graphic * get_citizen_graphic(const struct citizen_set *set, enum citizen_category type)
Definition tilespec.c:6716
int fill_sprite_array(struct tileset *t, struct drawn_sprite *sprs, enum mapview_layer layer, const struct tile *ptile, const struct tile_edge *pedge, const struct tile_corner *pcorner, const struct unit *punit, const struct city *pcity, const struct city *citymode, const struct unit_type *putype)
Definition tilespec.c:5822
#define ADD_SPRITE(s, draw_fog, x_offset, y_offset)
Definition tilespec.c:4507
int tileset_full_tile_width(const struct tileset *t)
Definition tilespec.c:776
struct sprite * get_tax_sprite(const struct tileset *t, Output_type_id otype)
Definition tilespec.c:6894
static bool tileset_setup_unit_direction(struct tileset *t, int uidx, const char *base_str, enum direction8 dir, enum unit_activity activity, bool has_icon)
Definition tilespec.c:3689
struct sprite * get_citizen_sprite(const struct tileset *t, enum citizen_category type, int citizen_index, const struct city *pcity)
Definition tilespec.c:6737
static int fill_terrain_sprite_array(struct tileset *t, struct drawn_sprite *sprs, int l, const struct tile *ptile, const struct terrain *pterrain, struct terrain **tterrain_near, struct drawing_data *draw)
Definition tilespec.c:5258
const char * tileset_version(struct tileset *t)
Definition tilespec.c:7545
static void free_city_sprite(struct city_sprite *city_sprite)
Definition tilespec.c:3144
static int ts_topology_index(int actual_topology)
Definition tilespec.c:1063
struct sprite * get_unittype_sprite(const struct tileset *t, const struct unit_type *punittype, enum unit_activity activity, enum direction8 facing)
Definition tilespec.c:6820
char * tileset_what_ruleset(struct tileset *t)
Definition tilespec.c:7569
struct sprite * get_nation_flag_sprite(const struct tileset *t, const struct nation_type *pnation)
Definition tilespec.c:6771
int tileset_tile_width(const struct tileset *t)
Definition tilespec.c:753
int tileset_tilelabel_offset_y(const struct tileset *t)
Definition tilespec.c:919
static void tileset_setup_citizen_types(struct tileset *t, struct citizen_set *set, const char *tag_group, const char *set_name, bool required)
Definition tilespec.c:2998
static void tileset_setup_road(struct tileset *t, struct extra_type *pextra, const char *tag)
Definition tilespec.c:4011
struct sprite * get_tech_sprite(const struct tileset *t, Tech_type_id tech)
Definition tilespec.c:6789
#define MATCH(dir)
static int get_irrigation_index(const struct tileset *t, struct extra_type *pextra, bv_extras *textras_near)
Definition tilespec.c:5022
#define MAX_INDEX_CARDINAL
Definition tilespec.c:108
#define ADD_SPRITE_SIZE(s, draw_fog, x_offset, y_offset, w_in, h_in)
Definition tilespec.c:4498
void tileset_error(enum log_level level, const char *tset_name, const char *format,...)
Definition tilespec.c:624
const struct editor_sprites * get_editor_sprites(const struct tileset *t)
Definition tilespec.c:6964
int tileset_topo_index(struct tileset *t)
Definition tilespec.c:7577
bool tilespec_reread(const char *new_tileset_name, bool game_fully_initialized, float scale)
Definition tilespec.c:1359
spec_file_types
Definition tilespec.c:160
@ SFILE_COMMON
Definition tilespec.c:161
@ SFILE_PIXEL
Definition tilespec.c:163
@ SFILE_LAST
Definition tilespec.c:164
@ SFILE_SVG
Definition tilespec.c:162
void tileset_setup_nation_flag(struct tileset *t, struct nation_type *nation)
Definition tilespec.c:4439
void tileset_ruleset_reset(struct tileset *t)
Definition tilespec.c:7501
#define ADD_SPRITE_IF_NOT_NULL(x)
static void scan_specfile(struct tileset *t, struct specfile *sf, bool duplicates_ok)
Definition tilespec.c:1638
enum mapview_layer tileset_get_layer(const struct tileset *t, int n)
Definition tilespec.c:7334
#define NUM_EDGE_TILES
Definition tilespec.h:99
#define NUM_CURSOR_FRAMES
Definition tilespec.h:304
indicator_type
Definition tilespec.h:306
@ INDICATOR_COUNT
Definition tilespec.h:310
arrow_type
Definition tilespec.h:200
@ ARROW_LAST
Definition tilespec.h:204
@ ARROW_MINUS
Definition tilespec.h:203
@ ARROW_RIGHT
Definition tilespec.h:201
@ ARROW_PLUS
Definition tilespec.h:202
#define TS_TOPO_ISOHEX
Definition tilespec.h:456
#define TERRAIN_LAYER_COUNT
Definition tilespec.h:174
#define sprite_vector_iterate_end
Definition tilespec.h:46
#define NUM_CORNER_TILES
Definition tilespec.h:106
#define NUM_TILES_PROGRESS
Definition tilespec.h:196
#define MAX_NUM_CITIZEN_SPRITES
Definition tilespec.h:198
#define TS_TOPO_HEX
Definition tilespec.h:455
#define TS_TOPO_SQUARE
Definition tilespec.h:454
layer_category
Definition tilespec.h:190
@ LAYER_CATEGORY_TILE
Definition tilespec.h:192
@ LAYER_CATEGORY_CITY
Definition tilespec.h:191
@ LAYER_CATEGORY_UNIT
Definition tilespec.h:193
icon_type
Definition tilespec.h:313
@ ICON_COUNT
Definition tilespec.h:316
@ EDGE_UD
Definition tilespec.h:93
@ EDGE_LR
Definition tilespec.h:94
@ EDGE_COUNT
Definition tilespec.h:95
spaceship_part
Definition tilespec.h:319
@ SPACESHIP_COUNT
Definition tilespec.h:327
#define NUM_WALL_TYPES
Definition tilespec.h:360
#define sprite_vector_iterate(sprite_vec, psprite)
Definition tilespec.h:44
cursor_type
Definition tilespec.h:288
@ CURSOR_LAST
Definition tilespec.h:300
bool unit_is_cityfounder(const struct unit *punit)
Definition unit.c:2649
bool unit_transported(const struct unit *pcargo)
Definition unit.c:2433
bool unit_has_orders(const struct unit *punit)
Definition unit.c:210
#define unit_tile(_pu)
Definition unit.h:396
#define BATTLEGROUP_NONE
Definition unit.h:189
#define unit_owner(_pu)
Definition unit.h:395
#define activity_type_iterate(_act_)
Definition unit.h:283
#define activity_type_iterate_end
Definition unit.h:288
#define MAX_NUM_BATTLEGROUPS
Definition unit.h:188
#define unit_list_iterate(unitlist, punit)
Definition unitlist.h:31
#define unit_list_iterate_end
Definition unitlist.h:33
const struct unit_type * unit_type_get(const struct unit *punit)
Definition unittype.c:123
const char * utype_rule_name(const struct unit_type *punittype)
Definition unittype.c:1578
Unit_type_id utype_index(const struct unit_type *punittype)
Definition unittype.c:91
#define utype_fuel(ptype)
Definition unittype.h:839
#define unit_type_iterate(_p)
Definition unittype.h:855
#define U_LAST
Definition unittype.h:40
#define unit_type_iterate_end
Definition unittype.h:862
#define worker_task_list_iterate(tasklist, ptask)
Definition workertask.h:33
#define worker_task_list_iterate_end
Definition workertask.h:35