Freeciv21
Develop your civilization from humble roots to a global empire
mapimg.cpp
Go to the documentation of this file.
1 /*
2 Copyright (c) 1996-2020 Freeciv21 and Freeciv contributors. This file is
3  /\/\ part of Freeciv21. Freeciv21 is free software: you can
4  \_\ _..._ redistribute it and/or modify it under the terms of the
5  (" )(_..._) GNU General Public License as published by the Free
6  ^^ // \\ Software Foundation, either version 3 of the License,
7  or (at your option) any later version. You should have
8 received a copy of the GNU General Public License along with Freeciv21.
9  If not, see https://www.gnu.org/licenses/.
10  */
11 
12 #include <cstdarg>
13 
14 // utility
15 #include "bitvector.h"
16 #include "fcintl.h"
17 #include "log.h"
18 #include "timing.h"
19 
20 // common
21 #include "calendar.h"
22 #include "fc_types.h"
23 #include "game.h"
24 #include "map.h"
25 #include "player.h"
26 #include "rgbcolor.h"
27 #include "terrain.h"
28 #include "tile.h"
29 
30 #include "mapimg.h"
31 
32 // Qt
33 #include <QImage>
34 #include <QImageWriter>
35 #include <QPainter>
36 
37 // == image colors ==
44 };
45 
46 static const struct rgbcolor *imgcolor_special(enum img_special imgcolor);
47 static const struct rgbcolor *imgcolor_player(int plr_id);
48 static const struct rgbcolor *
49 imgcolor_terrain(const struct terrain *pterrain);
50 
51 // == topologies ==
52 #define TILE_SIZE 6
53 #define NUM_PIXEL TILE_SIZE *TILE_SIZE
54 
55 BV_DEFINE(bv_pixel, NUM_PIXEL);
56 
57 struct tile_shape {
58  int x[NUM_PIXEL];
59  int y[NUM_PIXEL];
60 };
61 
62 struct img;
63 
64 typedef bv_pixel (*plot_func)(const struct tile *ptile,
65  const struct player *pplayer, bool knowledge);
66 typedef void (*base_coor_func)(struct img *pimg, int *base_x, int *base_y,
67  int x, int y);
68 
69 // (isometric) rectangular topology
70 static struct tile_shape tile_rect = {
71  .x = {0, 1, 2, 3, 4, 5, 0, 1, 2, 3, 4, 5, 0, 1, 2, 3, 4, 5,
72  0, 1, 2, 3, 4, 5, 0, 1, 2, 3, 4, 5, 0, 1, 2, 3, 4, 5},
73  .y = {0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2,
74  3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 5, 5, 5, 5, 5, 5}};
75 
76 static bv_pixel pixel_tile_rect(const struct tile *ptile,
77  const struct player *pplayer,
78  bool knowledge);
79 static bv_pixel pixel_city_rect(const struct tile *ptile,
80  const struct player *pplayer,
81  bool knowledge);
82 static bv_pixel pixel_unit_rect(const struct tile *ptile,
83  const struct player *pplayer,
84  bool knowledge);
85 static bv_pixel pixel_fogofwar_rect(const struct tile *ptile,
86  const struct player *pplayer,
87  bool knowledge);
88 static bv_pixel pixel_border_rect(const struct tile *ptile,
89  const struct player *pplayer,
90  bool knowledge);
91 static void base_coor_rect(struct img *pimg, int *base_x, int *base_y, int x,
92  int y);
93 
94 // hexa topology
95 static struct tile_shape tile_hexa = {
96  .x =
97  {
98  2, 3, 1, 2, 3, 4, 0, 1, 2, 3, 4, 5, 0, 1, 2, 3, 4, 5,
99  0, 1, 2, 3, 4, 5, 0, 1, 2, 3, 4, 5, 1, 2, 3, 4, 2, 3,
100  },
101  .y = {
102  0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3,
103  4, 4, 4, 4, 4, 4, 5, 5, 5, 5, 5, 5, 6, 6, 6, 6, 7, 7,
104  }};
105 
106 static bv_pixel pixel_tile_hexa(const struct tile *ptile,
107  const struct player *pplayer,
108  bool knowledge);
109 static bv_pixel pixel_city_hexa(const struct tile *ptile,
110  const struct player *pplayer,
111  bool knowledge);
112 static bv_pixel pixel_unit_hexa(const struct tile *ptile,
113  const struct player *pplayer,
114  bool knowledge);
115 static bv_pixel pixel_fogofwar_hexa(const struct tile *ptile,
116  const struct player *pplayer,
117  bool knowledge);
118 static bv_pixel pixel_border_hexa(const struct tile *ptile,
119  const struct player *pplayer,
120  bool knowledge);
121 static void base_coor_hexa(struct img *pimg, int *base_x, int *base_y, int x,
122  int y);
123 
124 // isometric hexa topology
125 static struct tile_shape tile_isohexa = {
126  .x = {2, 3, 4, 5, 1, 2, 3, 4, 5, 6, 0, 1, 2, 3, 4, 5, 6, 7,
127  0, 1, 2, 3, 4, 5, 6, 7, 1, 2, 3, 4, 5, 6, 2, 3, 4, 5},
128  .y = {0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2,
129  3, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 5, 5, 5, 5}};
130 
131 static bv_pixel pixel_tile_isohexa(const struct tile *ptile,
132  const struct player *pplayer,
133  bool knowledge);
134 static bv_pixel pixel_city_isohexa(const struct tile *ptile,
135  const struct player *pplayer,
136  bool knowledge);
137 static bv_pixel pixel_unit_isohexa(const struct tile *ptile,
138  const struct player *pplayer,
139  bool knowledge);
140 static bv_pixel pixel_fogofwar_isohexa(const struct tile *ptile,
141  const struct player *pplayer,
142  bool knowledge);
143 static bv_pixel pixel_border_isohexa(const struct tile *ptile,
144  const struct player *pplayer,
145  bool knowledge);
146 static void base_coor_isohexa(struct img *pimg, int *base_x, int *base_y,
147  int x, int y);
148 
149 // == map images ==
150 
151 #define ARG_PLRBV "plrbv"
152 #define ARG_PLRID "plrid"
153 #define ARG_PLRNAME "plrname"
154 
155 // mapimg definition
156 #define SPECENUM_NAME mapdef_arg
157 #define SPECENUM_VALUE0 MAPDEF_FORMAT
158 #define SPECENUM_VALUE0NAME "format"
159 #define SPECENUM_VALUE1 MAPDEF_MAP
160 #define SPECENUM_VALUE1NAME "map"
161 #define SPECENUM_VALUE2 MAPDEF_PLRBV
162 #define SPECENUM_VALUE2NAME ARG_PLRBV
163 #define SPECENUM_VALUE3 MAPDEF_PLRID
164 #define SPECENUM_VALUE3NAME ARG_PLRID
165 #define SPECENUM_VALUE4 MAPDEF_PLRNAME
166 #define SPECENUM_VALUE4NAME ARG_PLRNAME
167 #define SPECENUM_VALUE5 MAPDEF_SHOW
168 #define SPECENUM_VALUE5NAME "show"
169 #define SPECENUM_VALUE6 MAPDEF_TURNS
170 #define SPECENUM_VALUE6NAME "turns"
171 #define SPECENUM_VALUE7 MAPDEF_ZOOM
172 #define SPECENUM_VALUE7NAME "zoom"
173 #define SPECENUM_COUNT MAPDEF_COUNT
174 #include "specenum_gen.h"
175 
176 BV_DEFINE(bv_mapdef_arg, MAPDEF_COUNT);
177 
178 // player definitions
179 #define SPECENUM_NAME show_player
180 #define SPECENUM_VALUE0 SHOW_NONE
181 #define SPECENUM_VALUE0NAME "none"
182 #define SPECENUM_VALUE1 SHOW_EACH
183 #define SPECENUM_VALUE1NAME "each"
184 #define SPECENUM_VALUE2 SHOW_HUMAN
185 #define SPECENUM_VALUE2NAME "human"
186 #define SPECENUM_VALUE3 SHOW_ALL
187 #define SPECENUM_VALUE3NAME "all"
188 // should be identical to MAPDEF_PLRNAME
189 #define SPECENUM_VALUE4 SHOW_PLRNAME
190 #define SPECENUM_VALUE4NAME ARG_PLRNAME
191 // should be identical to MAPDEF_PLRID
192 #define SPECENUM_VALUE5 SHOW_PLRID
193 #define SPECENUM_VALUE5NAME ARG_PLRID
194 // should be identical to MAPDEF_PLRBV
195 #define SPECENUM_VALUE6 SHOW_PLRBV
196 #define SPECENUM_VALUE6NAME ARG_PLRBV
197 #include "specenum_gen.h"
198 
199 #undef ARG_PLRBV
200 #undef ARG_PLRID
201 #undef ARG_PLRNAME
202 
203 // map definition status
204 #define SPECENUM_NAME mapimg_status
205 #define SPECENUM_VALUE0 MAPIMG_STATUS_UNKNOWN
206 #define SPECENUM_VALUE0NAME _("not checked")
207 #define SPECENUM_VALUE1 MAPIMG_STATUS_OK
208 #define SPECENUM_VALUE1NAME _("OK")
209 #define SPECENUM_VALUE2 MAPIMG_STATUS_ERROR
210 #define SPECENUM_VALUE2NAME _("error")
211 #include "specenum_gen.h"
212 
213 #define MAX_LEN_MAPARG MAX_LEN_MAPDEF
214 #define MAX_NUM_MAPIMG 10
215 
216 const static auto MAPIMG_DEFAULT_IMGFORMAT = QByteArrayLiteral("png");
217 
218 static inline bool mapimg_initialised();
219 static bool mapimg_test(int id);
220 static bool mapimg_define_arg(struct mapdef *pmapdef, enum mapdef_arg arg,
221  const char *val, bool check);
222 static bool mapimg_def2str(struct mapdef *pmapdef, char *str,
223  size_t str_len);
224 static bool mapimg_checkplayers(struct mapdef *pmapdef, bool recheck);
225 static char *mapimg_generate_name(struct mapdef *pmapdef);
226 
227 // == map definition ==
228 struct mapdef {
231  enum mapimg_status status;
232  QByteArray format;
233  int zoom;
234  int turns;
235  bool layers[MAPIMG_LAYER_COUNT];
236  struct {
237  enum show_player show;
238  union {
239  char name[MAX_LEN_NAME]; // used by SHOW_PLRNAME
240  int id; // used by SHOW_PLRID
241  bv_player plrbv; // used by SHOW_PLRBV
242  };
243  bv_player checked_plrbv; /* player bitvector used for the image
244  * creation */
246 
247  bv_mapdef_arg args;
248  bool colortest;
249 };
250 
251 static struct mapdef *mapdef_new(bool colortest);
252 static void mapdef_destroy(struct mapdef *pmapdef);
253 
254 // List of map definitions.
255 #define SPECLIST_TAG mapdef
256 #define SPECLIST_TYPE struct mapdef
257 #include "speclist.h"
258 
259 #define mapdef_list_iterate(mapdef_list, pmapdef) \
260  TYPED_LIST_ITERATE(struct mapdef, mapdef_list, pmapdef)
261 #define mapdef_list_iterate_end LIST_ITERATE_END
262 
263 // == images ==
264 struct mapdef;
265 
266 struct img {
267  struct mapdef *def; // map definition
268  int turn; // save turn
270 
271  // topology definition
279 
280  struct {
281  int x;
282  int y;
283  } mapsize; // map size
284  struct {
285  int x;
286  int y;
287  } imgsize; // image size
288  const struct rgbcolor **map;
289 };
290 
291 static struct img *img_new(struct mapdef *mapdef, int topo, int xsize,
292  int ysize);
293 static void img_destroy(struct img *pimg);
294 static inline void img_set_pixel(struct img *pimg, const int mindex,
295  const struct rgbcolor *pcolor);
296 static inline int img_index(const int x, const int y,
297  const struct img *pimg);
298 static void img_plot(struct img *pimg, int x, int y,
299  const struct rgbcolor *pcolor, const bv_pixel pixel);
300 static void img_plot_tile(struct img *pimg, const struct tile *ptile,
301  const struct rgbcolor *pcolor,
302  const bv_pixel pixel);
303 static bool img_save(const struct img *pimg, const char *mapimgfile,
304  const char *path);
305 static bool img_filename(const char *mapimgfile, const QByteArray &format,
306  char *filename, size_t filename_len);
307 static void img_createmap(struct img *pimg);
308 
309 // == logging ==
310 #define MAX_LEN_ERRORBUF 1024
311 
312 static char error_buffer[MAX_LEN_ERRORBUF] = "\0";
313 static void mapimg_log(const char *file, const char *function, int line,
314  const char *format, ...)
315  fc__attribute((__format__(__printf__, 4, 5)));
316 #define MAPIMG_LOG(format, ...) \
317  mapimg_log(__FILE__, __FUNCTION__, __FC_LINE__, format, ##__VA_ARGS__)
318 #define MAPIMG_ASSERT_RET_VAL(cond, expr) \
319  fc_assert_action(cond, MAPIMG_LOG(_("internal error")); return (expr))
320 
321 // == additional functions ==
322 
323 static int bvplayers_count(const struct mapdef *pmapdef);
324 static const char *bvplayers_str(const bv_player &plrbv);
325 
326 // == map images data ==
327 static struct {
328  bool init;
329  struct mapdef_list *mapdef;
330 
338 } mapimg = {.init = false};
339 
340 /*
341  * ==============================================
342  * map images (external functions)
343  * ==============================================
344  */
345 
358 {
359  if (mapimg_initialised()) {
360  return;
361  }
362 
363  mapimg.mapdef = mapdef_list_new();
364 
365  fc_assert_ret(mapimg_tile_known != nullptr);
366  mapimg.mapimg_tile_known = mapimg_tile_known;
368  mapimg.mapimg_tile_terrain = mapimg_tile_terrain;
369  fc_assert_ret(mapimg_tile_owner != nullptr);
370  mapimg.mapimg_tile_owner = mapimg_tile_owner;
371  fc_assert_ret(mapimg_tile_city != nullptr);
372  mapimg.mapimg_tile_city = mapimg_tile_city;
373  fc_assert_ret(mapimg_tile_unit != nullptr);
374  mapimg.mapimg_tile_unit = mapimg_tile_unit;
376  mapimg.mapimg_plrcolor_count = mapimg_plrcolor_count;
378  mapimg.mapimg_plrcolor_get = mapimg_plrcolor_get;
379 
380  mapimg.init = true;
381 }
382 
387 {
388  if (!mapimg_initialised()) {
389  return;
390  }
391 
392  if (mapdef_list_size(mapimg.mapdef) > 0) {
393  mapdef_list_iterate(mapimg.mapdef, pmapdef)
394  {
395  mapdef_list_remove(mapimg.mapdef, pmapdef);
396  mapdef_destroy(pmapdef);
397  }
399  }
400 }
401 
406 {
407  if (!mapimg_initialised()) {
408  return;
409  }
410 
411  mapimg_reset();
412  mapdef_list_destroy(mapimg.mapdef);
413 
414  mapimg.init = false;
415 }
416 
421 {
422  if (!mapimg_initialised()) {
423  return 0;
424  }
425 
426  return mapdef_list_size(mapimg.mapdef);
427 }
428 
432 static const char *showname_help(enum show_player showplr)
433 {
434  switch (showplr) {
435  case SHOW_NONE:
436  return _("no players, only terrain");
437  case SHOW_EACH:
438  return _("one image per player");
439  case SHOW_HUMAN:
440  return _("one image per human player");
441  case SHOW_ALL:
442  return _("all players on a single image");
443  case SHOW_PLRNAME:
444  return _("just the player named with 'plrname'");
445  case SHOW_PLRID:
446  return _("just the player specified with 'plrid'");
447  case SHOW_PLRBV:
448  return _("one image per player in 'plrbv'");
449  }
450  fc_assert(0);
451  return "";
452 }
453 
457 char *mapimg_help(const char *cmdname)
458 {
459  Q_UNUSED(cmdname)
460  enum show_player showplr;
461  enum mapimg_layer layer;
462  QString defaults[MAPDEF_COUNT];
463  QString str_showplr, help;
464  struct mapdef *pmapdef;
465 
466  if (help.length() > 0) {
467  // Help text was created already.
468  return fc_strdup(qUtf8Printable(help));
469  }
470  pmapdef = mapdef_new(false);
471 
472  auto str_format =
473  QImageWriter::supportedImageFormats().join(QByteArrayLiteral(", "));
474 
475  // Possible 'show' settings.
476  for (showplr = show_player_begin(); showplr != show_player_end();
477  showplr = show_player_next(showplr)) {
478  const char *nameptr = show_player_name(showplr);
479 
480  if (nameptr != nullptr) {
481  char name[10];
482 
483  fc_snprintf(name, sizeof(name), "'%s'", nameptr);
484  str_showplr += QStringLiteral(" - %1 %2")
485  .arg(name, -9)
486  .arg(showname_help(showplr));
487  if (showplr != show_player_max()) {
488  str_showplr += QStringLiteral("\n");
489  }
490  }
491  }
492 
493  // Default values.
494  defaults[MAPDEF_FORMAT] =
495  QStringLiteral("(%2)").arg(QString(MAPIMG_DEFAULT_IMGFORMAT));
496  defaults[MAPDEF_SHOW] =
497  QStringLiteral("(%1)").arg(show_player_name(pmapdef->player.show));
498  defaults[MAPDEF_TURNS] =
499  QStringLiteral("(%1)").arg(QString::number(pmapdef->turns));
500  defaults[MAPDEF_ZOOM] = QStringLiteral("(%1)").arg(pmapdef->zoom);
501  defaults[MAPDEF_MAP] = QStringLiteral("(");
502  for (layer = mapimg_layer_begin(); layer != mapimg_layer_end();
503  layer = mapimg_layer_next(layer)) {
504  if (pmapdef->layers[layer]) {
505  defaults[MAPDEF_MAP] +=
506  QStringLiteral("%1").arg(mapimg_layer_name(layer)[0]);
507  }
508  }
509  defaults[MAPDEF_MAP] += QLatin1String(")");
510 
511  // help text
512  help =
513  QString(
514  /* TRANS: This is help for a server command, so keywords like
515  * "define" in the first column are server keywords that must not
516  * be translated. Do not translate keywords in single quotes, but
517  * strings in <angle brackets> should be translated. */
518  _("This command controls the creation of map images. Supported "
519  "arguments:\n"
520  " define <mapdef> - define a map image; returns numeric <id>\n"
521  " show <id>|all - list map image definitions or show a "
522  "specific "
523  "one\n"
524  " create <id>|all - manually save image(s) for current map "
525  "state\n"
526  " delete <id>|all - delete map image definition(s)\n"
527  " colortest - create test image(s) showing all colors\n"
528  "\n"
529  "Multiple definitions can be active at once. "
530  "A definition <mapdef> consists of colon-separated options:\n"
531  "\n"
532  "option (default) description\n"
533  "\n"
534  "format=<format> %1 file format\n"
535  "show=<show> %2 which players to show\n"
536  " plrname=<name> player name\n"
537  " plrid=<id> numeric player id\n"
538  " plrbv=<bit vector> see example; first char = "
539  "id "
540  "0\n"
541  "turns=<turns> %3 save image each <turns> turns\n"
542  " (0=no autosave, save with "
543  "'create')\n"
544  "zoom=<zoom> %4 magnification factor (1-5)\n"
545  "map=<map> %5 which map layers to draw\n"
546  "\n"
547  "<format> = use image format <format>. The following formats "
548  "are available:\n"
549  "%6\n"
550  "\n"
551  "<show> determines which players are represented and how many "
552  "images are saved by this definition:\n"
553  "%7\n"
554  "\n"
555  "<map> can contain one or more of the following layers:\n"
556  " - 'a' show area within borders of specified players\n"
557  " - 'b' show borders of specified players\n"
558  " - 'c' show cities of specified players\n"
559  " - 'f' show fog of war (single-player images only)\n"
560  " - 'k' show only player knowledge (single-player images only)\n"
561  " - 't' full display of terrain types\n"
562  " - 'u' show units of specified players\n"
563  "\n"
564  "Examples of <mapdef>:\n"
565  " 'zoom=1:map=tcub:show=all:format=png'\n"
566  " 'zoom=2:map=tcub:show=each:format=png'\n"
567  " 'zoom=1:map=tcub:show=plrname:plrname=Otto:format=bmp'\n"
568  " 'zoom=3:map=cu:show=plrbv:plrbv=010011:format=jpg'\n"
569  " 'zoom=1:map=t:show=none:format=jpg'"))
570  .arg(defaults[MAPDEF_FORMAT], -10)
571  .arg(defaults[MAPDEF_SHOW], -10)
572  .arg(defaults[MAPDEF_TURNS], -10)
573  .arg(defaults[MAPDEF_ZOOM], -10)
574  .arg(defaults[MAPDEF_MAP])
575  .arg(str_format, str_showplr);
576 
577  mapdef_destroy(pmapdef);
578 
579  return fc_strdup(qUtf8Printable(help));
580 }
581 
585 const char *mapimg_error() { return error_buffer; }
586 
590 bool mapimg_define(const char *maparg, bool check)
591 {
592  struct mapdef *pmapdef = nullptr;
593  QStringList mapargs, mapopts;
594  int i;
595  bool ret = true;
596 
598 
599  if (maparg == nullptr) {
600  MAPIMG_LOG(_("no map definition"));
601  return false;
602  }
603 
604  if (strlen(maparg) > MAX_LEN_MAPARG) {
605  // too long map definition string
606  MAPIMG_LOG(_("map definition string too long (max %d characters)"),
608  return false;
609  }
610 
611  if (mapimg_count() == MAX_NUM_MAPIMG) {
612  MAPIMG_LOG(_("maximum number of map definitions reached (%d)"),
614  return false;
615  }
616 
617  for (i = 0; i < mapimg_count(); i++) {
618  pmapdef = mapdef_list_get(mapimg.mapdef, i);
619  if (0 == fc_strcasecmp(pmapdef->maparg, maparg)) {
620  MAPIMG_LOG(_("duplicate of map image definition %d ('%s')"), i,
621  maparg);
622  return false;
623  }
624  }
625 
626  pmapdef = mapdef_new(false);
627 
628  // get map options
629  mapargs = QString(maparg).split(QStringLiteral(":"));
630 
631  for (const auto &str : qAsConst(mapargs)) {
632  // split map options into variable and value
633  mapopts = str.split(QStringLiteral("="));
634 
635  if (mapopts.count() == 2) {
636  enum mapdef_arg arg =
637  mapdef_arg_by_name(qUtf8Printable(mapopts.at(0)), strcmp);
638  if (mapdef_arg_is_valid(arg)) {
639  // If ret is FALSE an error message is set by mapimg_define_arg().
640  ret = mapimg_define_arg(pmapdef, arg, qUtf8Printable(mapopts.at(1)),
641  check);
642  } else {
643  MAPIMG_LOG(_("unknown map option: '%s'"), qUtf8Printable(str));
644  ret = false;
645  }
646  } else {
647  MAPIMG_LOG(_("unknown map option: '%s'"), qUtf8Printable(str));
648  ret = false;
649  }
650 
651  if (!ret) {
652  break;
653  }
654  }
655 
656  // sanity check
657  switch (pmapdef->player.show) {
658  case SHOW_PLRNAME: // display player given by name
659  if (!BV_ISSET(pmapdef->args, MAPDEF_PLRNAME)) {
660  MAPIMG_LOG(_("'show=%s' but no player name 'plrname'"),
661  show_player_name(SHOW_PLRNAME));
662  ret = false;
663  }
664  break;
665  case SHOW_PLRID: // display player given by id
666  if (!BV_ISSET(pmapdef->args, MAPDEF_PLRID)) {
667  MAPIMG_LOG(_("'show=%s' but no player id 'plrid'"),
668  show_player_name(SHOW_PLRID));
669  ret = false;
670  }
671  break;
672  case SHOW_PLRBV: // display players given by bitvector
673  if (!BV_ISSET(pmapdef->args, MAPDEF_PLRBV)) {
674  MAPIMG_LOG(_("'show=%s' but no player bitvector 'plrbv'"),
675  show_player_name(SHOW_PLRBV));
676  ret = false;
677  }
678  break;
679  case SHOW_NONE: // no player on the map
680  BV_CLR_ALL(pmapdef->player.checked_plrbv);
681  break;
682  case SHOW_ALL: // show all players in one map
683  BV_SET_ALL(pmapdef->player.checked_plrbv);
684  break;
685  case SHOW_EACH: // one map for each player
686  case SHOW_HUMAN: // one map for each human player
687  /* A loop for each player will be called at the time the image is
688  * created. */
689  BV_CLR_ALL(pmapdef->player.checked_plrbv);
690  break;
691  }
692 
693  if (ret && !check) {
694  // save map string
696 
697  // add map definiton
698  mapdef_list_append(mapimg.mapdef, pmapdef);
699  } else {
700  mapdef_destroy(pmapdef);
701  }
702 
703  return ret;
704 }
705 #undef NUM_MAX_MAPARGS
706 #undef NUM_MAX_MAPOPTS
707 
711 static bool mapimg_define_arg(struct mapdef *pmapdef, enum mapdef_arg arg,
712  const char *val, bool check)
713 {
714  Q_UNUSED(check)
715  if (BV_ISSET(pmapdef->args, arg)) {
716  log_debug("Option '%s' for mapimg used more than once.",
717  mapdef_arg_name(arg));
718  }
719 
720  // This argument was used.
721  BV_SET(pmapdef->args, arg);
722 
723  switch (arg) {
724  case MAPDEF_FORMAT:
725  // file format
726  if (QImageWriter::supportedImageFormats().contains(val)) {
727  pmapdef->format = val;
728  } else {
729  pmapdef->format = MAPIMG_DEFAULT_IMGFORMAT;
730  }
731  break;
732 
733  case MAPDEF_MAP:
734  // map definition
735  {
736  int len = qstrlen(val), l;
737  enum mapimg_layer layer;
738  bool error;
739 
740  for (layer = mapimg_layer_begin(); layer != mapimg_layer_end();
741  layer = mapimg_layer_next(layer)) {
742  pmapdef->layers[layer] = false;
743  }
744 
745  for (l = 0; l < len; l++) {
746  error = true;
747  for (layer = mapimg_layer_begin(); layer != mapimg_layer_end();
748  layer = mapimg_layer_next(layer)) {
749  if (val[l] == mapimg_layer_name(layer)[0]) {
750  pmapdef->layers[layer] = true;
751  error = false;
752  break;
753  }
754  }
755 
756  if (error) {
757  goto INVALID;
758  }
759  }
760  }
761  break;
762 
763  case MAPDEF_PLRBV:
764  // player definition - bitvector
765  {
766  int i;
767 
768  if (strlen(val) < MAX_NUM_PLAYER_SLOTS + 1) {
769  BV_CLR_ALL(pmapdef->player.plrbv);
770  for (i = 0; i < qstrlen(val); i++) {
771  if (!strchr("01", val[i])) {
772  MAPIMG_LOG(_("invalid character in bitvector: '%c' (%s)"),
773  val[i], val);
774  return false;
775  } else if (val[i] == '1') {
776  BV_SET(pmapdef->player.plrbv, i);
777  }
778  }
779  } else {
780  goto INVALID;
781  }
782  }
783  break;
784 
785  case MAPDEF_PLRID:
786  /* player definition - player id; will be checked by mapimg_isvalid()
787  * which calls mapimg_checkplayers() */
788  {
789  int plrid;
790 
791  if (sscanf(val, "%d", &plrid) != 0) {
792  if (plrid < 0 || plrid >= MAX_NUM_PLAYER_SLOTS) {
793  MAPIMG_LOG(_("'plrid' should be between 0 and %d"),
795  return false;
796  }
797  pmapdef->player.id = plrid;
798  } else {
799  goto INVALID;
800  }
801  }
802  break;
803 
804  case MAPDEF_PLRNAME:
805  /* player definition - player name; will be checked by mapimg_isvalid()
806  * which calls mapimg_checkplayers() */
807  {
808  if (strlen(val) > sizeof(pmapdef->player.name)) {
809  MAPIMG_LOG(_("player name too long: '%s' (max: %lu)"), val,
810  (unsigned long) sizeof(pmapdef->player.name));
811  return false;
812  } else {
813  sz_strlcpy(pmapdef->player.name, val);
814  }
815  }
816  break;
817 
818  case MAPDEF_SHOW:
819  // player definition - basic definition
820  {
821  enum show_player showplr;
822 
823  showplr = show_player_by_name(val, strcmp);
824  if (show_player_is_valid(showplr)) {
825  pmapdef->player.show = showplr;
826  } else {
827  goto INVALID;
828  }
829  }
830  break;
831 
832  case MAPDEF_TURNS:
833  // save each <x> turns
834  {
835  int turns;
836 
837  if (sscanf(val, "%d", &turns) != 0) {
838  if (turns < 0 || turns > 99) {
839  MAPIMG_LOG(_("'turns' should be between 0 and 99"));
840  return false;
841  } else {
842  pmapdef->turns = turns;
843  }
844  } else {
845  goto INVALID;
846  }
847  }
848  break;
849 
850  case MAPDEF_ZOOM:
851  // zoom factor
852  {
853  int zoom;
854 
855  if (sscanf(val, "%d", &zoom) != 0) {
856  if (zoom < 1 || zoom > 5) {
857  MAPIMG_LOG(_("'zoom' factor should be between 1 and 5"));
858  return false;
859  } else {
860  pmapdef->zoom = zoom;
861  }
862  } else {
863  goto INVALID;
864  }
865  }
866  break;
867 
868  case MAPDEF_COUNT:
869  fc_assert_ret_val(arg != MAPDEF_COUNT, false);
870  break;
871  }
872 
873  return true;
874 
875 INVALID:
876  MAPIMG_LOG(_("invalid value for option '%s': '%s'"), mapdef_arg_name(arg),
877  val);
878  return false;
879 }
880 #undef NUM_MAX_FORMATARGS
881 
886 struct mapdef *mapimg_isvalid(int id)
887 {
888  struct mapdef *pmapdef = nullptr;
889 
890  if (!mapimg_test(id)) {
891  // The error message is set in mapimg_test().
892  return nullptr;
893  }
894 
895  pmapdef = mapdef_list_get(mapimg.mapdef, id);
896  mapimg_checkplayers(pmapdef, true);
897 
898  switch (pmapdef->status) {
899  case MAPIMG_STATUS_UNKNOWN:
900  MAPIMG_LOG(_("map definition not checked (game not started)"));
901  return nullptr;
902  break;
903  case MAPIMG_STATUS_ERROR:
904  MAPIMG_LOG(_("map definition deactivated: %s"), pmapdef->error);
905  return nullptr;
906  break;
907  case MAPIMG_STATUS_OK:
908  // nothing
909  break;
910  }
911 
912  return pmapdef;
913 }
914 
918 bool mapimg_delete(int id)
919 {
920  struct mapdef *pmapdef = nullptr;
921 
922  if (!mapimg_test(id)) {
923  // The error message is set in mapimg_test().
924  return false;
925  }
926 
927  // delete map definition
928  pmapdef = mapdef_list_get(mapimg.mapdef, id);
929  mapdef_list_remove(mapimg.mapdef, pmapdef);
930 
931  return true;
932 }
933 
937 bool mapimg_show(int id, char *str, size_t str_len, bool detail)
938 {
939  struct mapdef *pmapdef = nullptr;
940 
941  if (!mapimg_test(id)) {
942  // The error message is set in mapimg_test().
943  return false;
944  }
945 
946  pmapdef = mapdef_list_get(mapimg.mapdef, id);
947 
948  // Clear string ...
949  fc_assert_ret_val(str_len > 0, false);
950  str[0] = '\0';
951 
952  if (detail) {
953  cat_snprintf(str, str_len,
954  _("Detailed information for map image "
955  "definition %d\n"),
956  id);
957  if (pmapdef->status == MAPIMG_STATUS_ERROR) {
958  cat_snprintf(str, str_len,
959  _(" - status: %s (%s)\n"),
960  mapimg_status_name(pmapdef->status), pmapdef->error);
961  } else {
962  cat_snprintf(str, str_len, _(" - status: %s\n"),
963  mapimg_status_name(pmapdef->status));
964  }
965  cat_snprintf(str, str_len, _(" - file name string: %s\n"),
966  mapimg_generate_name(pmapdef));
967  cat_snprintf(str, str_len, _(" - image format: %s\n"),
968  MAPIMG_DEFAULT_IMGFORMAT.data());
969  cat_snprintf(str, str_len, _(" - zoom factor: %d\n"),
970  pmapdef->zoom);
971  cat_snprintf(str, str_len, _(" - show area within borders: %s\n"),
972  pmapdef->layers[MAPIMG_LAYER_AREA] ? _("yes") : _("no"));
973  cat_snprintf(str, str_len, _(" - show borders: %s\n"),
974  pmapdef->layers[MAPIMG_LAYER_BORDERS] ? _("yes") : _("no"));
975  cat_snprintf(str, str_len, _(" - show cities: %s\n"),
976  pmapdef->layers[MAPIMG_LAYER_CITIES] ? _("yes") : _("no"));
977  cat_snprintf(str, str_len, _(" - show fog of war: %s\n"),
978  pmapdef->layers[MAPIMG_LAYER_FOGOFWAR] ? _("yes")
979  : _("no"));
980  cat_snprintf(str, str_len, _(" - show player knowledge: %s\n"),
981  pmapdef->layers[MAPIMG_LAYER_KNOWLEDGE] ? _("yes")
982  : _("no"));
983  cat_snprintf(str, str_len, _(" - show terrain: %s\n"),
984  pmapdef->layers[MAPIMG_LAYER_TERRAIN] ? _("full")
985  : _("basic"));
986  cat_snprintf(str, str_len, _(" - show units: %s\n"),
987  pmapdef->layers[MAPIMG_LAYER_UNITS] ? _("yes") : _("no"));
988  cat_snprintf(str, str_len, _(" - players included: %s"),
989  show_player_name(pmapdef->player.show));
990  switch (pmapdef->player.show) {
991  case SHOW_NONE:
992  case SHOW_HUMAN:
993  case SHOW_EACH:
994  case SHOW_ALL:
995  // nothing
996  break;
997  case SHOW_PLRNAME:
998  cat_snprintf(str, str_len, _("\n - player name: %s"),
999  pmapdef->player.name);
1000  break;
1001  case SHOW_PLRID:
1002  cat_snprintf(str, str_len, _("\n - player id: %d"),
1003  pmapdef->player.id);
1004  break;
1005  case SHOW_PLRBV:
1006  cat_snprintf(str, str_len, _("\n - players: %s"),
1007  bvplayers_str(pmapdef->player.plrbv));
1008  break;
1009  }
1010  } else {
1011  char str_def[MAX_LEN_MAPDEF];
1012  mapimg_def2str(pmapdef, str_def, sizeof(str_def));
1013  if (pmapdef->status == MAPIMG_STATUS_ERROR) {
1014  cat_snprintf(str, str_len, "'%s' (%s: %s)", str_def,
1015  mapimg_status_name(pmapdef->status), pmapdef->error);
1016  } else {
1017  cat_snprintf(str, str_len, "'%s' (%s)", str_def,
1018  mapimg_status_name(pmapdef->status));
1019  }
1020  }
1021 
1022  return true;
1023 }
1024 
1029 bool mapimg_id2str(int id, char *str, size_t str_len)
1030 {
1031  struct mapdef *pmapdef = nullptr;
1032 
1033  if (!mapimg_test(id)) {
1034  // The error message is set in mapimg_test().
1035  return false;
1036  }
1037 
1038  pmapdef = mapdef_list_get(mapimg.mapdef, id);
1039 
1040  return mapimg_def2str(pmapdef, str, str_len);
1041 }
1042 
1050 bool mapimg_create(struct mapdef *pmapdef, bool force, const char *savename,
1051  const char *path)
1052 {
1053  struct img *pimg;
1054  char mapimgfile[MAX_LEN_PATH];
1055  bool ret = true;
1056 #ifdef FREECIV_DEBUG
1057  civtimer *timer_cpu, *timer_user;
1058 #endif
1059 
1060  if (map_is_empty()) {
1061  MAPIMG_LOG(_("map not yet created"));
1062 
1063  return false;
1064  }
1065 
1066  mapimg_checkplayers(pmapdef, false);
1067 
1068  if (pmapdef->status != MAPIMG_STATUS_OK) {
1069  MAPIMG_LOG(_("map definition not checked or error"));
1070  return false;
1071  }
1072 
1073  /* An image should be saved if:
1074  * - force is set to TRUE
1075  * - it is the first turn
1076  * - turns is set to a value not zero and the current turn can be devided
1077  * by this number */
1078  if (!force && game.info.turn != 1
1079  && !(pmapdef->turns != 0 && game.info.turn % pmapdef->turns == 0)) {
1080  return true;
1081  }
1082 
1083 #ifdef FREECIV_DEBUG
1084  timer_cpu = timer_new(TIMER_CPU, TIMER_ACTIVE);
1085  timer_start(timer_cpu);
1086  timer_user = timer_new(TIMER_USER, TIMER_ACTIVE);
1087  timer_start(timer_user);
1088 #endif // FREECIV_DEBUG
1089 
1090  // create map
1091  switch (pmapdef->player.show) {
1092  case SHOW_PLRNAME: // display player given by name
1093  case SHOW_PLRID: // display player given by id
1094  case SHOW_NONE: // no player one the map
1095  case SHOW_ALL: // show all players in one map
1096  case SHOW_PLRBV: // display player(s) given by bitvector
1097  generate_save_name(savename, mapimgfile, sizeof(mapimgfile),
1098  mapimg_generate_name(pmapdef));
1099 
1100  pimg = img_new(pmapdef, CURRENT_TOPOLOGY, wld.map.xsize, wld.map.ysize);
1101  img_createmap(pimg);
1102  if (!img_save(pimg, mapimgfile, path)) {
1103  ret = false;
1104  }
1105  img_destroy(pimg);
1106  break;
1107  case SHOW_EACH: // one map for each player
1108  case SHOW_HUMAN: // one map for each human player
1109  players_iterate(pplayer)
1110  {
1111  if (!pplayer->is_alive
1112  || (pmapdef->player.show == SHOW_HUMAN && !is_human(pplayer))) {
1113  /* no map image for dead players
1114  * or AI players if only human players should be shown */
1115  continue;
1116  }
1117 
1118  BV_CLR_ALL(pmapdef->player.checked_plrbv);
1119  BV_SET(pmapdef->player.checked_plrbv, player_index(pplayer));
1120 
1121  generate_save_name(savename, mapimgfile, sizeof(mapimgfile),
1122  mapimg_generate_name(pmapdef));
1123 
1124  pimg =
1126  img_createmap(pimg);
1127  if (!img_save(pimg, mapimgfile, path)) {
1128  ret = false;
1129  }
1130  img_destroy(pimg);
1131 
1132  if (!ret) {
1133  break;
1134  }
1135  }
1137  break;
1138  }
1139 
1140 #ifdef FREECIV_DEBUG
1141  log_debug("Image generation time: %g seconds (%g apparent)",
1142  timer_read_seconds(timer_cpu), timer_read_seconds(timer_user));
1143 
1144  timer_destroy(timer_cpu);
1145  timer_destroy(timer_user);
1146 #endif // FREECIV_DEBUG
1147 
1148  return ret;
1149 }
1150 
1156 bool mapimg_colortest(const char *savename, const char *path)
1157 {
1158  struct img *pimg;
1159  const struct rgbcolor *pcolor;
1160  struct mapdef *pmapdef = mapdef_new(true);
1161  char mapimgfile[MAX_LEN_PATH];
1162  bv_pixel pixel;
1163  int i, nat_x, nat_y;
1164  int max_playercolor = mapimg.mapimg_plrcolor_count();
1165  int max_terraincolor = terrain_count();
1166  bool ret = true;
1167 
1168 #define SIZE_X 16
1169 #define SIZE_Y 5
1170 
1171  pimg = img_new(pmapdef, 0, SIZE_X + 2,
1172  SIZE_Y * (max_playercolor / SIZE_X) + 2);
1173 
1174  pixel = pimg->pixel_tile(nullptr, nullptr, false);
1175 
1176  pcolor = imgcolor_special(IMGCOLOR_OCEAN);
1177  for (i = 0; i < MAX(max_playercolor, max_terraincolor); i++) {
1178  nat_x = 1 + i % SIZE_X;
1179  nat_y = 1 + (i / SIZE_X) * SIZE_Y;
1180 
1181  img_plot(pimg, nat_x, nat_y, pcolor, pixel);
1182  }
1183 
1184  for (i = 0; i < MAX(max_playercolor, max_terraincolor); i++) {
1185  if (i >= max_playercolor) {
1186  break;
1187  }
1188 
1189  nat_x = 1 + i % SIZE_X;
1190  nat_y = 2 + (i / SIZE_X) * SIZE_Y;
1191  pcolor = mapimg.mapimg_plrcolor_get(i);
1192 
1193  img_plot(pimg, nat_x, nat_y, pcolor, pixel);
1194  }
1195 
1197  for (i = 0; i < MAX(max_playercolor, max_terraincolor); i++) {
1198  nat_x = 1 + i % SIZE_X;
1199  nat_y = 3 + (i / SIZE_X) * SIZE_Y;
1200 
1201  img_plot(pimg, nat_x, nat_y, pcolor, pixel);
1202  }
1203 
1204  for (i = 0; i < MAX(max_playercolor, max_terraincolor); i++) {
1205  if (i >= max_terraincolor) {
1206  break;
1207  }
1208 
1209  nat_x = 1 + i % SIZE_X;
1210  nat_y = 4 + (i / SIZE_X) * SIZE_Y;
1211  pcolor = imgcolor_terrain(terrain_by_number(i));
1212 
1213  img_plot(pimg, nat_x, nat_y, pcolor, pixel);
1214  }
1215 
1216 #undef SIZE_X
1217 #undef SIZE_Y
1218 
1219  for (const auto &format : QImageWriter::supportedImageFormats()) {
1220  char buf[128];
1221 
1222  // Set the image format.
1223  pmapdef->format = format;
1224 
1225  fc_snprintf(buf, sizeof(buf), "colortest");
1226  // filename for color test
1227  generate_save_name(savename, mapimgfile, sizeof(mapimgfile), buf);
1228 
1229  if (!img_save(pimg, mapimgfile, path)) {
1230  /* If one of the mapimg format/toolkit combination fail, return
1231  * FALSE, i.e. an error occurred. */
1232  ret = false;
1233  }
1234  }
1235 
1236  img_destroy(pimg);
1237  mapdef_destroy(pmapdef);
1238 
1239  return ret;
1240 }
1241 
1242 /*
1243  * ==============================================
1244  * map images (internal functions)
1245  * ==============================================
1246  */
1247 
1251 static inline bool mapimg_initialised() { return mapimg.init; }
1252 
1257 static bool mapimg_test(int id)
1258 {
1260 
1261  if (id < 0 || id >= mapimg_count()) {
1262  MAPIMG_LOG(_("no map definition with id %d"), id);
1263  return false;
1264  }
1265 
1266  return true;
1267 }
1268 
1272 static bool mapimg_def2str(struct mapdef *pmapdef, char *str, size_t str_len)
1273 {
1274  enum mapimg_layer layer;
1275  char buf[MAPIMG_LAYER_COUNT + 1];
1276  int i;
1277 
1278  if (pmapdef->status != MAPIMG_STATUS_OK) {
1279  MAPIMG_LOG(_("map definition not checked or error"));
1280  fc_strlcpy(str, pmapdef->maparg, str_len);
1281  return false;
1282  }
1283 
1284  str[0] = '\0';
1285  cat_snprintf(str, str_len, "format=%s:", pmapdef->format.data());
1286  cat_snprintf(str, str_len, "turns=%d:", pmapdef->turns);
1287 
1288  i = 0;
1289  for (layer = mapimg_layer_begin(); layer != mapimg_layer_end();
1290  layer = mapimg_layer_next(layer)) {
1291  if (pmapdef->layers[layer]) {
1292  buf[i++] = mapimg_layer_name(layer)[0];
1293  }
1294  }
1295  buf[i++] = '\0';
1296  cat_snprintf(str, str_len, "map=%s:", buf);
1297 
1298  switch (pmapdef->player.show) {
1299  case SHOW_NONE:
1300  case SHOW_EACH:
1301  case SHOW_HUMAN:
1302  case SHOW_ALL:
1303  cat_snprintf(str, str_len,
1304  "show=%s:", show_player_name(pmapdef->player.show));
1305  break;
1306  case SHOW_PLRBV:
1307  cat_snprintf(str, str_len, "show=%s:", show_player_name(SHOW_PLRBV));
1308  cat_snprintf(str, str_len,
1309  "plrbv=%s:", bvplayers_str(pmapdef->player.plrbv));
1310  break;
1311  case SHOW_PLRNAME:
1312  cat_snprintf(str, str_len, "show=%s:", show_player_name(SHOW_PLRNAME));
1313  cat_snprintf(str, str_len, "plrname=%s:", pmapdef->player.name);
1314  break;
1315  case SHOW_PLRID:
1316  cat_snprintf(str, str_len, "show=%s:", show_player_name(SHOW_PLRID));
1317  cat_snprintf(str, str_len, "plrid=%d:", pmapdef->player.id);
1318  break;
1319  }
1320  cat_snprintf(str, str_len, "zoom=%d", pmapdef->zoom);
1321 
1322  return true;
1323 }
1324 
1330 static bool mapimg_checkplayers(struct mapdef *pmapdef, bool recheck)
1331 {
1332  struct player *pplayer;
1333  enum m_pre_result result;
1334 
1335  if (!recheck && pmapdef->status == MAPIMG_STATUS_ERROR) {
1336  return false;
1337  }
1338 
1339  /* game started - generate / check bitvector for players */
1340  switch (pmapdef->player.show) {
1341  case SHOW_NONE:
1342  // nothing
1343  break;
1344  case SHOW_PLRBV:
1345  pmapdef->player.checked_plrbv = pmapdef->player.plrbv;
1346  break;
1347  case SHOW_EACH:
1348  case SHOW_HUMAN:
1349  // A map for each player will be created in a loop.
1350  BV_CLR_ALL(pmapdef->player.checked_plrbv);
1351  break;
1352  case SHOW_ALL:
1353  BV_SET_ALL(pmapdef->player.checked_plrbv);
1354  break;
1355  case SHOW_PLRNAME:
1356  // display players as requested in the map definition
1357  BV_CLR_ALL(pmapdef->player.checked_plrbv);
1358  pplayer = player_by_name_prefix(pmapdef->player.name, &result);
1359 
1360  if (pplayer != nullptr) {
1361  BV_SET(pmapdef->player.checked_plrbv, player_index(pplayer));
1362  } else {
1363  pmapdef->status = MAPIMG_STATUS_ERROR;
1364  // Save the error message in map definition.
1365  fc_snprintf(pmapdef->error, sizeof(pmapdef->error),
1366  _("unknown player name: '%s'"), pmapdef->player.name);
1367  MAPIMG_LOG("%s", pmapdef->error);
1368  return false;
1369  }
1370  break;
1371  case SHOW_PLRID:
1372  // display players as requested in the map definition
1373  BV_CLR_ALL(pmapdef->player.checked_plrbv);
1374  pplayer = player_by_number(pmapdef->player.id);
1375 
1376  if (pplayer != nullptr) {
1377  BV_SET(pmapdef->player.checked_plrbv, player_index(pplayer));
1378  } else {
1379  pmapdef->status = MAPIMG_STATUS_ERROR;
1380  // Save the error message in map definition.
1381  fc_snprintf(pmapdef->error, sizeof(pmapdef->error),
1382  _("invalid player id: %d"), pmapdef->player.id);
1383  MAPIMG_LOG("%s", pmapdef->error);
1384  return false;
1385  }
1386  break;
1387  }
1388 
1389  pmapdef->status = MAPIMG_STATUS_OK;
1390 
1391  return true;
1392 }
1393 
1398 static void mapimg_log(const char *file, const char *function, int line,
1399  const char *format, ...)
1400 {
1401  va_list args;
1402 
1403  va_start(args, format);
1404  fc_vsnprintf(error_buffer, sizeof(error_buffer), format, args);
1405  va_end(args);
1406 
1407 #ifdef FREECIV_DEBUG
1408  log_debug("In %s() [%s:%d]: %s", function, file, line, error_buffer);
1409 #endif
1410 }
1411 
1424 static char *mapimg_generate_name(struct mapdef *pmapdef)
1425 {
1426  static char mapstr[256];
1427  char str_show[MAX_NUM_PLAYER_SLOTS + 1];
1428  enum mapimg_layer layer;
1429  int i, count = 0, plr_id = -1;
1430 
1431  switch (pmapdef->player.show) {
1432  case SHOW_NONE:
1433  // no player on the map
1434  sz_strlcpy(str_show, "none");
1435  break;
1436  case SHOW_ALL:
1437  // show all players in one map
1438  sz_strlcpy(str_show, "all");
1439  break;
1440  case SHOW_PLRBV:
1441  case SHOW_PLRNAME:
1442  case SHOW_PLRID:
1443  case SHOW_HUMAN:
1444  case SHOW_EACH:
1445  /* one map for each selected player; iterate over all possible player ids
1446  * to generate unique strings even if civil wars occur */
1447  for (i = 0; i < MAX_NUM_PLAYER_SLOTS; i++) {
1448  str_show[i] = BV_ISSET(pmapdef->player.checked_plrbv, i) ? '1' : '0';
1449  if (BV_ISSET(pmapdef->player.checked_plrbv, i)) {
1450  count++;
1451  plr_id = i;
1452  }
1453  }
1454  str_show[MAX_NUM_PLAYER_SLOTS] = '\0';
1455 
1456  /* Return the option name if no player is selected or the player id if
1457  * there is only one player selected. */
1458  if (count == 0) {
1459  fc_snprintf(str_show, sizeof(str_show), "---%s",
1460  show_player_name(pmapdef->player.show));
1461  } else if (count == 1 && plr_id != -1) {
1462  fc_snprintf(str_show, sizeof(str_show), "%03d%s", plr_id,
1463  show_player_name(pmapdef->player.show));
1464  }
1465  break;
1466  }
1467 
1468  fc_snprintf(mapstr, sizeof(mapstr), "M");
1469  for (layer = mapimg_layer_begin(); layer != mapimg_layer_end();
1470  layer = mapimg_layer_next(layer)) {
1471  if (pmapdef->layers[layer]) {
1472  const char *lname = mapimg_layer_name(layer);
1473 
1474  if (lname != nullptr) {
1475  cat_snprintf(mapstr, sizeof(mapstr), "%s", lname);
1476  } else {
1477  cat_snprintf(mapstr, sizeof(mapstr), "-");
1478  }
1479  } else {
1480  cat_snprintf(mapstr, sizeof(mapstr), "-");
1481  }
1482  }
1483  cat_snprintf(mapstr, sizeof(mapstr), "Z%dP%s", pmapdef->zoom, str_show);
1484 
1485  return mapstr;
1486 }
1487 
1488 /*
1489  * ==============================================
1490  * map definitions (internal functions)
1491  * ==============================================
1492  */
1493 
1497 static struct mapdef *mapdef_new(bool colortest)
1498 {
1499  auto *pmapdef = new mapdef;
1500 
1501  // default values
1502  pmapdef->maparg[0] = '\0';
1503  pmapdef->error[0] = '\0';
1504  pmapdef->status = MAPIMG_STATUS_UNKNOWN;
1505  pmapdef->format = MAPIMG_DEFAULT_IMGFORMAT;
1506  pmapdef->zoom = 2;
1507  pmapdef->turns = 1;
1508  pmapdef->layers[MAPIMG_LAYER_TERRAIN] = false;
1509  pmapdef->layers[MAPIMG_LAYER_CITIES] = true;
1510  pmapdef->layers[MAPIMG_LAYER_UNITS] = true;
1511  pmapdef->layers[MAPIMG_LAYER_BORDERS] = true;
1512  pmapdef->layers[MAPIMG_LAYER_FOGOFWAR] = false;
1513  pmapdef->layers[MAPIMG_LAYER_KNOWLEDGE] = true;
1514  pmapdef->layers[MAPIMG_LAYER_AREA] = false;
1515  pmapdef->player.show = SHOW_ALL;
1516  /* The union is not set at this point (player.id, player.name and
1517  * player.plrbv). */
1518  BV_CLR_ALL(pmapdef->player.checked_plrbv);
1519  BV_CLR_ALL(pmapdef->args);
1520  pmapdef->colortest = colortest;
1521 
1522  return pmapdef;
1523 }
1524 
1528 static void mapdef_destroy(struct mapdef *pmapdef)
1529 {
1530  if (pmapdef == nullptr) {
1531  return;
1532  }
1533 
1534  delete pmapdef;
1535 }
1536 
1537 /*
1538  * ==============================================
1539  * images (internal functions)
1540  * ==============================================
1541  */
1542 
1546 static struct img *img_new(struct mapdef *mapdef, int topo, int xsize,
1547  int ysize)
1548 {
1549  auto *pimg = new img;
1550 
1551  pimg->def = mapdef;
1552  pimg->turn = game.info.turn;
1553  fc_snprintf(pimg->title, sizeof(pimg->title), _("Turn: %4d - Year: %10s"),
1554  game.info.turn, calendar_text());
1555 
1556  pimg->mapsize.x = xsize; // x size of the map
1557  pimg->mapsize.y = ysize; // y size of the map
1558 
1559  pimg->imgsize.x = 0; // x size of the map image
1560  pimg->imgsize.y = 0; // y size of the map image
1561 
1562  if (topo_has_flag(topo, TF_HEX)) {
1563  // additional space for hex maps
1564  pimg->imgsize.x += TILE_SIZE / 2;
1565  pimg->imgsize.y += TILE_SIZE / 2;
1566 
1567  if (topo_has_flag(topo, TF_ISO)) {
1568  // iso-hex
1569  pimg->imgsize.x += (pimg->mapsize.x + pimg->mapsize.y / 2) * TILE_SIZE;
1570  pimg->imgsize.y += (pimg->mapsize.x + pimg->mapsize.y / 2) * TILE_SIZE;
1571 
1572  // magic for isohexa: change size if wrapping in only one direction
1573  if ((topo_has_flag(topo, TF_WRAPX) && !topo_has_flag(topo, TF_WRAPY))
1574  || (!topo_has_flag(topo, TF_WRAPX)
1575  && topo_has_flag(topo, TF_WRAPY))) {
1576  pimg->imgsize.y +=
1577  (pimg->mapsize.x - pimg->mapsize.y / 2) / 2 * TILE_SIZE;
1578  }
1579 
1580  pimg->tileshape = &tile_isohexa;
1581 
1587 
1588  pimg->base_coor = base_coor_isohexa;
1589  } else {
1590  // hex
1591  pimg->imgsize.x += pimg->mapsize.x * TILE_SIZE;
1592  pimg->imgsize.y += pimg->mapsize.y * TILE_SIZE;
1593 
1594  pimg->tileshape = &tile_hexa;
1595 
1596  pimg->pixel_tile = pixel_tile_hexa;
1597  pimg->pixel_city = pixel_city_hexa;
1598  pimg->pixel_unit = pixel_unit_hexa;
1601 
1602  pimg->base_coor = base_coor_hexa;
1603  }
1604  } else {
1605  if (topo_has_flag(topo, TF_ISO)) {
1606  // isometric rectangular
1607  pimg->imgsize.x += (pimg->mapsize.x + pimg->mapsize.y / 2) * TILE_SIZE;
1608  pimg->imgsize.y += (pimg->mapsize.x + pimg->mapsize.y / 2) * TILE_SIZE;
1609  } else {
1610  // rectangular
1611  pimg->imgsize.x += pimg->mapsize.x * TILE_SIZE;
1612  pimg->imgsize.y += pimg->mapsize.y * TILE_SIZE;
1613  }
1614 
1615  pimg->tileshape = &tile_rect;
1616 
1617  pimg->pixel_tile = pixel_tile_rect;
1618  pimg->pixel_city = pixel_city_rect;
1619  pimg->pixel_unit = pixel_unit_rect;
1622 
1623  pimg->base_coor = base_coor_rect;
1624  }
1625 
1626  // Here the map image is saved as an array of RGB color values.
1627  pimg->map = new const rgbcolor *[pimg->imgsize.x * pimg->imgsize.y]();
1628  // Initialise map.
1629  memset(pimg->map, 0, pimg->imgsize.x * pimg->imgsize.y);
1630 
1631  return pimg;
1632 }
1633 
1637 static void img_destroy(struct img *pimg)
1638 {
1639  if (pimg != nullptr) {
1640  // do not free pimg->def
1641  delete[] pimg->map;
1642  delete pimg;
1643  pimg = nullptr;
1644  }
1645 }
1646 
1650 static inline void img_set_pixel(struct img *pimg, const int mindex,
1651  const struct rgbcolor *pcolor)
1652 {
1653  if (mindex < 0 || mindex > pimg->imgsize.x * pimg->imgsize.y) {
1654  qCritical("invalid index: 0 <= %d < %d", mindex,
1655  pimg->imgsize.x * pimg->imgsize.y);
1656  return;
1657  }
1658 
1659  pimg->map[mindex] = pcolor;
1660 }
1661 
1665 static inline int img_index(const int x, const int y, const struct img *pimg)
1666 {
1667  fc_assert_ret_val(x >= 0 && x < pimg->imgsize.x, 0);
1668  fc_assert_ret_val(y >= 0 && y < pimg->imgsize.y, 0);
1669 
1670  return pimg->imgsize.x * y + x;
1671 }
1672 
1677 static void img_plot(struct img *pimg, int x, int y,
1678  const struct rgbcolor *pcolor, const bv_pixel pixel)
1679 {
1680  int base_x, base_y, i, mindex;
1681 
1682  if (!BV_ISSET_ANY(pixel)) {
1683  return;
1684  }
1685 
1686  pimg->base_coor(pimg, &base_x, &base_y, x, y);
1687 
1688  for (i = 0; i < NUM_PIXEL; i++) {
1689  if (BV_ISSET(pixel, i)) {
1690  mindex = img_index(base_x + pimg->tileshape->x[i],
1691  base_y + pimg->tileshape->y[i], pimg);
1692  img_set_pixel(pimg, mindex, pcolor);
1693  }
1694  }
1695 }
1696 
1700 static void img_plot_tile(struct img *pimg, const struct tile *ptile,
1701  const struct rgbcolor *pcolor,
1702  const bv_pixel pixel)
1703 {
1704  int x, y;
1705 
1706  index_to_map_pos(&x, &y, tile_index(ptile));
1707 
1708  img_plot(pimg, x, y, pcolor, pixel);
1709 }
1710 
1714 static bool img_save(const struct img *pimg, const char *mapimgfile,
1715  const char *path)
1716 {
1717  char tmpname[600];
1718 
1719  if (!QFileInfo(mapimgfile).isAbsolute() && path != nullptr) {
1720  make_dir(path);
1721 
1722  sz_strlcpy(tmpname, path);
1723  if (tmpname[0] != '\0') {
1724  sz_strlcat(tmpname, "/");
1725  }
1726  } else {
1727  tmpname[0] = '\0';
1728  }
1729 
1730  sz_strlcat(tmpname, mapimgfile);
1731 
1732  char pngname[MAX_LEN_PATH];
1733 
1734  if (!img_filename(mapimgfile, pimg->def->format, pngname,
1735  sizeof(pngname))) {
1736  MAPIMG_LOG(_("error generating the file name"));
1737  return false;
1738  }
1739 
1740  QImage image(pimg->imgsize.x * pimg->def->zoom,
1741  pimg->imgsize.y * pimg->def->zoom, QImage::Format_ARGB32);
1742  if (image.isNull()) {
1743  MAPIMG_LOG(_("could not allocate memory for image"));
1744  return false;
1745  }
1746 
1747  if (pimg->def->colortest) {
1748  image.setText(QStringLiteral("Description"),
1749  QStringLiteral("color test"));
1750  } else if (BV_ISSET_ANY(pimg->def->player.checked_plrbv)) {
1751  players_iterate(pplayer)
1752  {
1753  if (!BV_ISSET(pimg->def->player.checked_plrbv,
1754  player_index(pplayer))) {
1755  continue;
1756  }
1757 
1758  const auto pcolor = imgcolor_player(player_index(pplayer));
1759 
1760  image.setText(
1761  QStringLiteral("Player %1 color").arg(player_number(pplayer)),
1762  QStringLiteral("(%1, %2, %3)")
1763  .arg(pcolor->r)
1764  .arg(pcolor->g)
1765  .arg(pcolor->b));
1766  image.setText(
1767  QStringLiteral("Player %1 name").arg(player_number(pplayer)),
1768  player_name(pplayer));
1769  }
1771  }
1772 
1773  image.setDevicePixelRatio(pimg->def->zoom);
1774  image.fill(Qt::transparent);
1775 
1776  QPainter p;
1777  p.begin(&image);
1778 
1779  // Iterate over tiles
1780  for (int y = 0; y < pimg->imgsize.y; y++) {
1781  for (int x = 0; x < pimg->imgsize.x; x++) {
1782  if (const auto pcolor = pimg->map[img_index(x, y, pimg)]; pcolor) {
1783  p.fillRect(x, y, 1, 1, QColor(pcolor->r, pcolor->g, pcolor->b));
1784  }
1785  }
1786  }
1787 
1788  p.end();
1789 
1790  image.save(pngname);
1791  qDebug("Map image saved as '%s'.", pngname);
1792 
1793  return true;
1794 }
1795 
1799 static bool img_filename(const char *mapimgfile, const QByteArray &format,
1800  char *filename, size_t filename_len)
1801 {
1802  fc_snprintf(filename, filename_len, "%s.map.%s", mapimgfile,
1803  format.data());
1804 
1805  return true;
1806 }
1807 
1812 static void img_createmap(struct img *pimg)
1813 {
1814  const struct rgbcolor *pcolor;
1815  bv_pixel pixel;
1816  int player_id;
1817  struct player *pplayer = nullptr;
1818  struct player *plr_tile = nullptr, *plr_city = nullptr,
1819  *plr_unit = nullptr;
1820  enum known_type tile_knowledge = TILE_UNKNOWN;
1821  struct terrain *pterrain = nullptr;
1822  bool plr_knowledge = pimg->def->layers[MAPIMG_LAYER_KNOWLEDGE];
1823 
1824  whole_map_iterate(&(wld.map), ptile)
1825  {
1826  if (bvplayers_count(pimg->def) == 1) {
1827  // only one player; get player id for 'known' and 'fogofwar'
1828  players_iterate(aplayer)
1829  {
1830  if (BV_ISSET(pimg->def->player.checked_plrbv,
1831  player_index(aplayer))) {
1832  pplayer = aplayer;
1833  tile_knowledge =
1834  mapimg.mapimg_tile_known(ptile, pplayer, plr_knowledge);
1835  break;
1836  }
1837  }
1839  }
1840 
1841  // known tiles
1842  if (plr_knowledge && pplayer != nullptr
1843  && tile_knowledge == TILE_UNKNOWN) {
1844  // plot nothing iff tile is not known
1845  continue;
1846  }
1847 
1848  // terrain
1849  pterrain = mapimg.mapimg_tile_terrain(ptile, pplayer, plr_knowledge);
1850  if (pimg->def->layers[MAPIMG_LAYER_TERRAIN]) {
1851  // full terrain
1852  pixel = pimg->pixel_tile(ptile, pplayer, plr_knowledge);
1853  pcolor = imgcolor_terrain(pterrain);
1854  img_plot_tile(pimg, ptile, pcolor, pixel);
1855  } else {
1856  // basic terrain
1857  pixel = pimg->pixel_tile(ptile, pplayer, plr_knowledge);
1858  if (is_ocean(pterrain)) {
1859  img_plot_tile(pimg, ptile, imgcolor_special(IMGCOLOR_OCEAN), pixel);
1860  } else {
1861  img_plot_tile(pimg, ptile, imgcolor_special(IMGCOLOR_GROUND), pixel);
1862  }
1863  }
1864 
1865  // (land) area within borders and borders
1866  plr_tile = mapimg.mapimg_tile_owner(ptile, pplayer, plr_knowledge);
1867  if (game.info.borders > 0 && nullptr != plr_tile) {
1868  player_id = player_index(plr_tile);
1869  if (pimg->def->layers[MAPIMG_LAYER_AREA] && !is_ocean(pterrain)
1870  && BV_ISSET(pimg->def->player.checked_plrbv, player_id)) {
1871  // the tile is land and inside the players borders
1872  pixel = pimg->pixel_tile(ptile, pplayer, plr_knowledge);
1873  pcolor = imgcolor_player(player_id);
1874  img_plot_tile(pimg, ptile, pcolor, pixel);
1875  } else if (pimg->def->layers[MAPIMG_LAYER_BORDERS]
1876  && (BV_ISSET(pimg->def->player.checked_plrbv, player_id)
1877  || (plr_knowledge && pplayer != nullptr))) {
1878  /* plot borders if player is selected or view range of the one
1879  * displayed player */
1880  pixel = pimg->pixel_border(ptile, pplayer, plr_knowledge);
1881  pcolor = imgcolor_player(player_id);
1882  img_plot_tile(pimg, ptile, pcolor, pixel);
1883  }
1884  }
1885 
1886  // cities and units
1887  plr_city = mapimg.mapimg_tile_city(ptile, pplayer, plr_knowledge);
1888  plr_unit = mapimg.mapimg_tile_unit(ptile, pplayer, plr_knowledge);
1889  if (pimg->def->layers[MAPIMG_LAYER_CITIES] && plr_city) {
1890  player_id = player_index(plr_city);
1891  if (BV_ISSET(pimg->def->player.checked_plrbv, player_id)
1892  || (plr_knowledge && pplayer != nullptr)) {
1893  /* plot cities if player is selected or view range of the one
1894  * displayed player */
1895  pixel = pimg->pixel_city(ptile, pplayer, plr_knowledge);
1896  pcolor = imgcolor_player(player_id);
1897  img_plot_tile(pimg, ptile, pcolor, pixel);
1898  }
1899  } else if (pimg->def->layers[MAPIMG_LAYER_UNITS] && plr_unit) {
1900  player_id = player_index(plr_unit);
1901  if (BV_ISSET(pimg->def->player.checked_plrbv, player_id)
1902  || (plr_knowledge && pplayer != nullptr)) {
1903  /* plot units if player is selected or view range of the one
1904  * displayed player */
1905  pixel = pimg->pixel_unit(ptile, pplayer, plr_knowledge);
1906  pcolor = imgcolor_player(player_id);
1907  img_plot_tile(pimg, ptile, pcolor, pixel);
1908  }
1909  }
1910 
1911  // fogofwar; if only 1 player is plotted
1912  if (game.info.fogofwar && pimg->def->layers[MAPIMG_LAYER_FOGOFWAR]
1913  && pplayer != nullptr && tile_knowledge == TILE_KNOWN_UNSEEN) {
1914  pixel = pimg->pixel_fogofwar(ptile, pplayer, plr_knowledge);
1915  pcolor = nullptr;
1916  img_plot_tile(pimg, ptile, pcolor, pixel);
1917  }
1918  }
1920 }
1921 
1922 /*
1923  * ==============================================
1924  * topology (internal functions)
1925  * ==============================================
1926  * With these functions the pixels corresponding to the different elements
1927  * (tile, city, unit) for each map topology are defined.
1928  *
1929  * The bv_pixel_fogofwar_*() functions are special as they defines where
1930  * the color should be removed.
1931  *
1932  * The functions for a rectangular and an isometric rectangular topology
1933  * are identical.
1934  */
1935 
1944 static bv_pixel pixel_tile_rect(const struct tile *ptile,
1945  const struct player *pplayer, bool knowledge)
1946 {
1947  Q_UNUSED(ptile)
1948  Q_UNUSED(pplayer)
1949  Q_UNUSED(knowledge)
1950  bv_pixel pixel;
1951 
1952  BV_SET_ALL(pixel);
1953 
1954  return pixel;
1955 }
1956 
1965 static bv_pixel pixel_city_rect(const struct tile *ptile,
1966  const struct player *pplayer, bool knowledge)
1967 {
1968  Q_UNUSED(ptile)
1969  Q_UNUSED(pplayer)
1970  Q_UNUSED(knowledge)
1971  bv_pixel pixel;
1972 
1973  BV_CLR_ALL(pixel);
1974  BV_SET(pixel, 7);
1975  BV_SET(pixel, 8);
1976  BV_SET(pixel, 9);
1977  BV_SET(pixel, 10);
1978  BV_SET(pixel, 13);
1979  BV_SET(pixel, 14);
1980  BV_SET(pixel, 15);
1981  BV_SET(pixel, 16);
1982  BV_SET(pixel, 19);
1983  BV_SET(pixel, 20);
1984  BV_SET(pixel, 21);
1985  BV_SET(pixel, 22);
1986  BV_SET(pixel, 21);
1987  BV_SET(pixel, 25);
1988  BV_SET(pixel, 26);
1989  BV_SET(pixel, 27);
1990  BV_SET(pixel, 28);
1991 
1992  return pixel;
1993 }
1994 
2003 static bv_pixel pixel_unit_rect(const struct tile *ptile,
2004  const struct player *pplayer, bool knowledge)
2005 {
2006  Q_UNUSED(ptile)
2007  Q_UNUSED(pplayer)
2008  Q_UNUSED(knowledge)
2009  bv_pixel pixel;
2010 
2011  BV_CLR_ALL(pixel);
2012  BV_SET(pixel, 14);
2013  BV_SET(pixel, 15);
2014  BV_SET(pixel, 20);
2015  BV_SET(pixel, 21);
2016 
2017  return pixel;
2018 }
2019 
2028 static bv_pixel pixel_fogofwar_rect(const struct tile *ptile,
2029  const struct player *pplayer,
2030  bool knowledge)
2031 {
2032  Q_UNUSED(ptile)
2033  Q_UNUSED(pplayer)
2034  Q_UNUSED(knowledge)
2035  bv_pixel pixel;
2036 
2037  BV_CLR_ALL(pixel);
2038 
2039  BV_SET(pixel, 0);
2040  BV_SET(pixel, 2);
2041  BV_SET(pixel, 4);
2042  BV_SET(pixel, 7);
2043  BV_SET(pixel, 9);
2044  BV_SET(pixel, 11);
2045  BV_SET(pixel, 12);
2046  BV_SET(pixel, 14);
2047  BV_SET(pixel, 16);
2048  BV_SET(pixel, 19);
2049  BV_SET(pixel, 21);
2050  BV_SET(pixel, 23);
2051  BV_SET(pixel, 24);
2052  BV_SET(pixel, 26);
2053  BV_SET(pixel, 28);
2054  BV_SET(pixel, 31);
2055  BV_SET(pixel, 33);
2056  BV_SET(pixel, 35);
2057 
2058  return pixel;
2059 }
2060 
2073 static bv_pixel pixel_border_rect(const struct tile *ptile,
2074  const struct player *pplayer,
2075  bool knowledge)
2076 {
2077  bv_pixel pixel;
2078  struct tile *pnext;
2079  struct player *owner;
2080 
2081  BV_CLR_ALL(pixel);
2082 
2083  fc_assert_ret_val(ptile != nullptr, pixel);
2084 
2085  owner = mapimg.mapimg_tile_owner(ptile, pplayer, knowledge);
2086  if (nullptr == owner) {
2087  // no border
2088  return pixel;
2089  }
2090 
2091  pnext = mapstep(&(wld.map), ptile, DIR8_NORTH);
2092  if (!pnext
2093  || (mapimg.mapimg_tile_known(pnext, pplayer, knowledge) != TILE_UNKNOWN
2094  && mapimg.mapimg_tile_owner(pnext, pplayer, knowledge) != owner)) {
2095  BV_SET(pixel, 0);
2096  BV_SET(pixel, 1);
2097  BV_SET(pixel, 2);
2098  BV_SET(pixel, 3);
2099  BV_SET(pixel, 4);
2100  BV_SET(pixel, 5);
2101  }
2102 
2103  pnext = mapstep(&(wld.map), ptile, DIR8_EAST);
2104  if (!pnext
2105  || (mapimg.mapimg_tile_known(pnext, pplayer, knowledge) != TILE_UNKNOWN
2106  && mapimg.mapimg_tile_owner(pnext, pplayer, knowledge) != owner)) {
2107  BV_SET(pixel, 5);
2108  BV_SET(pixel, 11);
2109  BV_SET(pixel, 17);
2110  BV_SET(pixel, 23);
2111  BV_SET(pixel, 29);
2112  BV_SET(pixel, 35);
2113  }
2114 
2115  pnext = mapstep(&(wld.map), ptile, DIR8_SOUTH);
2116  if (!pnext
2117  || (mapimg.mapimg_tile_known(pnext, pplayer, knowledge) != TILE_UNKNOWN
2118  && mapimg.mapimg_tile_owner(pnext, pplayer, knowledge) != owner)) {
2119  BV_SET(pixel, 30);
2120  BV_SET(pixel, 31);
2121  BV_SET(pixel, 32);
2122  BV_SET(pixel, 33);
2123  BV_SET(pixel, 34);
2124  BV_SET(pixel, 35);
2125  }
2126 
2127  pnext = mapstep(&(wld.map), ptile, DIR8_WEST);
2128  if (!pnext
2129  || (mapimg.mapimg_tile_known(pnext, pplayer, knowledge) != TILE_UNKNOWN
2130  && mapimg.mapimg_tile_owner(pnext, pplayer, knowledge) != owner)) {
2131  BV_SET(pixel, 0);
2132  BV_SET(pixel, 6);
2133  BV_SET(pixel, 12);
2134  BV_SET(pixel, 18);
2135  BV_SET(pixel, 24);
2136  BV_SET(pixel, 30);
2137  }
2138 
2139  return pixel;
2140 }
2141 
2145 static void base_coor_rect(struct img *pimg, int *base_x, int *base_y, int x,
2146  int y)
2147 {
2148  Q_UNUSED(pimg)
2149  *base_x = x * TILE_SIZE;
2150  *base_y = y * TILE_SIZE;
2151 }
2152 
2163 static bv_pixel pixel_tile_hexa(const struct tile *ptile,
2164  const struct player *pplayer, bool knowledge)
2165 {
2166  Q_UNUSED(ptile)
2167  Q_UNUSED(pplayer)
2168  Q_UNUSED(knowledge)
2169  bv_pixel pixel;
2170 
2171  BV_SET_ALL(pixel);
2172 
2173  return pixel;
2174 }
2175 
2186 static bv_pixel pixel_city_hexa(const struct tile *ptile,
2187  const struct player *pplayer, bool knowledge)
2188 {
2189  Q_UNUSED(ptile)
2190  Q_UNUSED(pplayer)
2191  Q_UNUSED(knowledge)
2192  bv_pixel pixel;
2193 
2194  BV_CLR_ALL(pixel);
2195  BV_SET(pixel, 3);
2196  BV_SET(pixel, 4);
2197  BV_SET(pixel, 7);
2198  BV_SET(pixel, 8);
2199  BV_SET(pixel, 9);
2200  BV_SET(pixel, 10);
2201  BV_SET(pixel, 13);
2202  BV_SET(pixel, 14);
2203  BV_SET(pixel, 15);
2204  BV_SET(pixel, 16);
2205  BV_SET(pixel, 19);
2206  BV_SET(pixel, 20);
2207  BV_SET(pixel, 21);
2208  BV_SET(pixel, 22);
2209  BV_SET(pixel, 25);
2210  BV_SET(pixel, 26);
2211  BV_SET(pixel, 27);
2212  BV_SET(pixel, 28);
2213  BV_SET(pixel, 31);
2214  BV_SET(pixel, 32);
2215 
2216  return pixel;
2217 }
2218 
2229 static bv_pixel pixel_unit_hexa(const struct tile *ptile,
2230  const struct player *pplayer, bool knowledge)
2231 {
2232  Q_UNUSED(ptile)
2233  Q_UNUSED(pplayer)
2234  Q_UNUSED(knowledge)
2235  bv_pixel pixel;
2236 
2237  BV_CLR_ALL(pixel);
2238  BV_SET(pixel, 14);
2239  BV_SET(pixel, 15);
2240  BV_SET(pixel, 20);
2241  BV_SET(pixel, 21);
2242 
2243  return pixel;
2244 }
2245 
2256 static bv_pixel pixel_fogofwar_hexa(const struct tile *ptile,
2257  const struct player *pplayer,
2258  bool knowledge)
2259 {
2260  Q_UNUSED(ptile)
2261  Q_UNUSED(pplayer)
2262  Q_UNUSED(knowledge)
2263  bv_pixel pixel;
2264 
2265  BV_CLR_ALL(pixel);
2266  BV_SET(pixel, 0);
2267  BV_SET(pixel, 3);
2268  BV_SET(pixel, 5);
2269  BV_SET(pixel, 7);
2270  BV_SET(pixel, 9);
2271  BV_SET(pixel, 11);
2272  BV_SET(pixel, 13);
2273  BV_SET(pixel, 15);
2274  BV_SET(pixel, 17);
2275  BV_SET(pixel, 18);
2276  BV_SET(pixel, 20);
2277  BV_SET(pixel, 22);
2278  BV_SET(pixel, 24);
2279  BV_SET(pixel, 26);
2280  BV_SET(pixel, 28);
2281  BV_SET(pixel, 30);
2282  BV_SET(pixel, 32);
2283  BV_SET(pixel, 35);
2284 
2285  return pixel;
2286 }
2287 
2298 static bv_pixel pixel_border_hexa(const struct tile *ptile,
2299  const struct player *pplayer,
2300  bool knowledge)
2301 {
2302  bv_pixel pixel;
2303  struct tile *pnext;
2304  struct player *owner;
2305 
2306  BV_CLR_ALL(pixel);
2307 
2308  fc_assert_ret_val(ptile != nullptr, pixel);
2309 
2310  owner = mapimg.mapimg_tile_owner(ptile, pplayer, knowledge);
2311  if (nullptr == owner) {
2312  // no border
2313  return pixel;
2314  }
2315 
2316  pnext = mapstep(&(wld.map), ptile, DIR8_WEST);
2317  if (!pnext
2318  || (mapimg.mapimg_tile_known(pnext, pplayer, knowledge) != TILE_UNKNOWN
2319  && mapimg.mapimg_tile_owner(pnext, pplayer, knowledge) != owner)) {
2320  BV_SET(pixel, 0);
2321  BV_SET(pixel, 2);
2322  BV_SET(pixel, 6);
2323  }
2324 
2325  // not used: DIR8_NORTHWEST
2326 
2327  pnext = mapstep(&(wld.map), ptile, DIR8_NORTH);
2328  if (!pnext
2329  || (mapimg.mapimg_tile_known(pnext, pplayer, knowledge) != TILE_UNKNOWN
2330  && mapimg.mapimg_tile_owner(pnext, pplayer, knowledge) != owner)) {
2331  BV_SET(pixel, 1);
2332  BV_SET(pixel, 5);
2333  BV_SET(pixel, 11);
2334  }
2335 
2336  pnext = mapstep(&(wld.map), ptile, DIR8_NORTHEAST);
2337  if (!pnext
2338  || (mapimg.mapimg_tile_known(pnext, pplayer, knowledge) != TILE_UNKNOWN
2339  && mapimg.mapimg_tile_owner(pnext, pplayer, knowledge) != owner)) {
2340  BV_SET(pixel, 11);
2341  BV_SET(pixel, 17);
2342  BV_SET(pixel, 23);
2343  BV_SET(pixel, 29);
2344  }
2345 
2346  pnext = mapstep(&(wld.map), ptile, DIR8_EAST);
2347  if (!pnext
2348  || (mapimg.mapimg_tile_known(pnext, pplayer, knowledge) != TILE_UNKNOWN
2349  && mapimg.mapimg_tile_owner(pnext, pplayer, knowledge) != owner)) {
2350  BV_SET(pixel, 29);
2351  BV_SET(pixel, 33);
2352  BV_SET(pixel, 35);
2353  }
2354 
2355  // not used. DIR8_SOUTHEAST
2356 
2357  pnext = mapstep(&(wld.map), ptile, DIR8_SOUTH);
2358  if (!pnext
2359  || (mapimg.mapimg_tile_known(pnext, pplayer, knowledge) != TILE_UNKNOWN
2360  && mapimg.mapimg_tile_owner(pnext, pplayer, knowledge) != owner)) {
2361  BV_SET(pixel, 24);
2362  BV_SET(pixel, 30);
2363  BV_SET(pixel, 34);
2364  }
2365 
2366  pnext = mapstep(&(wld.map), ptile, DIR8_SOUTHWEST);
2367  if (!pnext
2368  || (mapimg.mapimg_tile_known(pnext, pplayer, knowledge) != TILE_UNKNOWN
2369  && mapimg.mapimg_tile_owner(pnext, pplayer, knowledge) != owner)) {
2370  BV_SET(pixel, 6);
2371  BV_SET(pixel, 12);
2372  BV_SET(pixel, 18);
2373  BV_SET(pixel, 24);
2374  }
2375 
2376  return pixel;
2377 }
2378 
2382 static void base_coor_hexa(struct img *pimg, int *base_x, int *base_y, int x,
2383  int y)
2384 {
2385  Q_UNUSED(pimg)
2386  int nat_x, nat_y;
2387  MAP_TO_NATIVE_POS(&nat_x, &nat_y, x, y);
2388 
2389  *base_x = nat_x * TILE_SIZE + ((nat_y % 2) ? TILE_SIZE / 2 : 0);
2390  *base_y = nat_y * TILE_SIZE;
2391 }
2392 
2401 static bv_pixel pixel_tile_isohexa(const struct tile *ptile,
2402  const struct player *pplayer,
2403  bool knowledge)
2404 {
2405  Q_UNUSED(ptile)
2406  Q_UNUSED(pplayer)
2407  Q_UNUSED(knowledge)
2408  bv_pixel pixel;
2409 
2410  BV_SET_ALL(pixel);
2411 
2412  return pixel;
2413 }
2414 
2423 static bv_pixel pixel_city_isohexa(const struct tile *ptile,
2424  const struct player *pplayer,
2425  bool knowledge)
2426 {
2427  Q_UNUSED(ptile)
2428  Q_UNUSED(pplayer)
2429  Q_UNUSED(knowledge)
2430  bv_pixel pixel;
2431 
2432  BV_CLR_ALL(pixel);
2433  BV_SET(pixel, 5);
2434  BV_SET(pixel, 6);
2435  BV_SET(pixel, 7);
2436  BV_SET(pixel, 8);
2437  BV_SET(pixel, 11);
2438  BV_SET(pixel, 12);
2439  BV_SET(pixel, 13);
2440  BV_SET(pixel, 14);
2441  BV_SET(pixel, 15);
2442  BV_SET(pixel, 16);
2443  BV_SET(pixel, 19);
2444  BV_SET(pixel, 20);
2445  BV_SET(pixel, 21);
2446  BV_SET(pixel, 22);
2447  BV_SET(pixel, 23);
2448  BV_SET(pixel, 24);
2449  BV_SET(pixel, 27);
2450  BV_SET(pixel, 28);
2451  BV_SET(pixel, 29);
2452  BV_SET(pixel, 30);
2453 
2454  return pixel;
2455 }
2456 
2465 static bv_pixel pixel_unit_isohexa(const struct tile *ptile,
2466  const struct player *pplayer,
2467  bool knowledge)
2468 {
2469  Q_UNUSED(ptile)
2470  Q_UNUSED(pplayer)
2471  Q_UNUSED(knowledge)
2472  bv_pixel pixel;
2473 
2474  BV_CLR_ALL(pixel);
2475  BV_SET(pixel, 13);
2476  BV_SET(pixel, 14);
2477  BV_SET(pixel, 21);
2478  BV_SET(pixel, 22);
2479 
2480  return pixel;
2481 }
2482 
2491 static bv_pixel pixel_fogofwar_isohexa(const struct tile *ptile,
2492  const struct player *pplayer,
2493  bool knowledge)
2494 {
2495  Q_UNUSED(ptile)
2496  Q_UNUSED(pplayer)
2497  Q_UNUSED(knowledge)
2498 
2499  bv_pixel pixel;
2500 
2501  BV_CLR_ALL(pixel);
2502  BV_SET(pixel, 0);
2503  BV_SET(pixel, 1);
2504  BV_SET(pixel, 4);
2505  BV_SET(pixel, 7);
2506  BV_SET(pixel, 8);
2507  BV_SET(pixel, 12);
2508  BV_SET(pixel, 13);
2509  BV_SET(pixel, 16);
2510  BV_SET(pixel, 17);
2511  BV_SET(pixel, 18);
2512  BV_SET(pixel, 19);
2513  BV_SET(pixel, 22);
2514  BV_SET(pixel, 23);
2515  BV_SET(pixel, 27);
2516  BV_SET(pixel, 28);
2517  BV_SET(pixel, 31);
2518  BV_SET(pixel, 34);
2519  BV_SET(pixel, 35);
2520 
2521  return pixel;
2522 }
2523 
2537 static bv_pixel pixel_border_isohexa(const struct tile *ptile,
2538  const struct player *pplayer,
2539  bool knowledge)
2540 {
2541  bv_pixel pixel;
2542  struct tile *pnext;
2543  struct player *owner;
2544 
2545  BV_CLR_ALL(pixel);
2546 
2547  fc_assert_ret_val(ptile != nullptr, pixel);
2548 
2549  owner = mapimg.mapimg_tile_owner(ptile, pplayer, knowledge);
2550  if (nullptr == owner) {
2551  // no border
2552  return pixel;
2553  }
2554 
2555  pnext = mapstep(&(wld.map), ptile, DIR8_NORTH);
2556  if (!pnext
2557  || (mapimg.mapimg_tile_known(pnext, pplayer, knowledge) != TILE_UNKNOWN
2558  && mapimg.mapimg_tile_owner(pnext, pplayer, knowledge) != owner)) {
2559  BV_SET(pixel, 0);
2560  BV_SET(pixel, 1);
2561  BV_SET(pixel, 2);
2562  BV_SET(pixel, 3);
2563  }
2564 
2565  // not used: DIR8_NORTHEAST
2566 
2567  pnext = mapstep(&(wld.map), ptile, DIR8_EAST);
2568  if (!pnext
2569  || (mapimg.mapimg_tile_known(pnext, pplayer, knowledge) != TILE_UNKNOWN
2570  && mapimg.mapimg_tile_owner(pnext, pplayer, knowledge) != owner)) {
2571  BV_SET(pixel, 3);
2572  BV_SET(pixel, 9);
2573  BV_SET(pixel, 17);
2574  }
2575 
2576  pnext = mapstep(&(wld.map), ptile, DIR8_SOUTHEAST);
2577  if (!pnext
2578  || (mapimg.mapimg_tile_known(pnext, pplayer, knowledge) != TILE_UNKNOWN
2579  && mapimg.mapimg_tile_owner(pnext, pplayer, knowledge) != owner)) {
2580  BV_SET(pixel, 25);
2581  BV_SET(pixel, 31);
2582  BV_SET(pixel, 35);
2583  }
2584 
2585  pnext = mapstep(&(wld.map), ptile, DIR8_SOUTH);
2586  if (!pnext
2587  || (mapimg.mapimg_tile_known(pnext, pplayer, knowledge) != TILE_UNKNOWN
2588  && mapimg.mapimg_tile_owner(pnext, pplayer, knowledge) != owner)) {
2589  BV_SET(pixel, 32);
2590  BV_SET(pixel, 33);
2591  BV_SET(pixel, 34);
2592  BV_SET(pixel, 35);
2593  }
2594 
2595  // not used: DIR8_SOUTHWEST
2596 
2597  pnext = mapstep(&(wld.map), ptile, DIR8_WEST);
2598  if (!pnext
2599  || (mapimg.mapimg_tile_known(pnext, pplayer, knowledge) != TILE_UNKNOWN
2600  && mapimg.mapimg_tile_owner(pnext, pplayer, knowledge) != owner)) {
2601  BV_SET(pixel, 18);
2602  BV_SET(pixel, 26);
2603  BV_SET(pixel, 32);
2604  }
2605 
2606  pnext = mapstep(&(wld.map), ptile, DIR8_NORTHWEST);
2607  if (!pnext
2608  || (mapimg.mapimg_tile_known(pnext, pplayer, knowledge) != TILE_UNKNOWN
2609  && mapimg.mapimg_tile_owner(pnext, pplayer, knowledge) != owner)) {
2610  BV_SET(pixel, 0);
2611  BV_SET(pixel, 4);
2612  BV_SET(pixel, 10);
2613  }
2614 
2615  return pixel;
2616 }
2617 
2621 static void base_coor_isohexa(struct img *pimg, int *base_x, int *base_y,
2622  int x, int y)
2623 {
2624  // magic for iso-hexa
2625  y -= x / 2;
2626  y += (pimg->mapsize.x - 1) / 2;
2627 
2628  *base_x = x * TILE_SIZE;
2629  *base_y = y * TILE_SIZE + ((x % 2) ? 0 : TILE_SIZE / 2);
2630 }
2631 
2632 /*
2633  * ==============================================
2634  * additional functions (internal functions)
2635  * ==============================================
2636  */
2637 
2641 static const char *bvplayers_str(const bv_player &plrbv)
2642 {
2643  static char buf[MAX_NUM_PLAYER_SLOTS + 1];
2644  int i;
2645 
2646  // Don't print lots of unnecessary trailing zeroes
2647  for (i = MAX_NUM_PLAYER_SLOTS - 1; i >= 0; i--) {
2648  if (BV_ISSET(plrbv, i) || player_by_number(i)) {
2649  buf[i + 1] = '\0';
2650  break;
2651  }
2652  }
2653 
2654  for (; i >= 0; i--) {
2655  buf[i] = BV_ISSET(plrbv, i) ? '1' : '0';
2656  }
2657 
2658  return buf;
2659 }
2660 
2664 static int bvplayers_count(const struct mapdef *pmapdef)
2665 {
2666  int i, count = 0;
2667 
2668  switch (pmapdef->player.show) {
2669  case SHOW_NONE: // no player on the map
2670  count = 0;
2671  break;
2672  case SHOW_HUMAN: // one map for each human player
2673  case SHOW_EACH: // one map for each player
2674  case SHOW_PLRNAME: // the map of one selected player
2675  case SHOW_PLRID:
2676  count = 1;
2677  break;
2678  case SHOW_PLRBV: // map showing only players given by a bitvector
2679  count = 0;
2680  for (i = 0; i < MAX_NUM_PLAYER_SLOTS; i++) {
2681  if (BV_ISSET(pmapdef->player.plrbv, i)) {
2682  count++;
2683  }
2684  }
2685  break;
2686  case SHOW_ALL: // show all players in one map
2687  count = player_count();
2688  break;
2689  }
2690 
2691  return count;
2692 }
2693 
2694 /*
2695  * ==============================================
2696  * image colors (internal functions)
2697  * ==============================================
2698  */
2699 
2703 static const struct rgbcolor *imgcolor_special(enum img_special imgcolor)
2704 {
2705  static struct rgbcolor rgb_special[] = {
2706  {255, 0, 0}, // IMGCOLOR_ERROR
2707  /* FIXME: 'ocean' and 'ground' colors are also used in the overview;
2708  * the values are defined in colors.tilespec. */
2709  {0, 0, 200}, // IMGCOLOR_OCEAN
2710  {0, 200, 0}, // IMGCOLOR_GROUND
2711  {0, 0, 0}, // IMGCOLOR_BACKGROUND
2712  {255, 255, 255}, // IMGCOLOR_TEXT
2713  };
2714 
2715  fc_assert_ret_val(imgcolor >= 0 && imgcolor < ARRAY_SIZE(rgb_special),
2716  &rgb_special[0]);
2717 
2718  return &rgb_special[imgcolor];
2719 }
2720 
2726 static const struct rgbcolor *imgcolor_player(int plr_id)
2727 {
2728  struct player *pplayer = player_by_number(plr_id);
2729 
2730  fc_assert_ret_val(pplayer != nullptr, imgcolor_special(IMGCOLOR_ERROR));
2731  fc_assert_ret_val(pplayer->rgb != nullptr,
2733 
2734  return pplayer->rgb;
2735 }
2736 
2742 static const struct rgbcolor *
2743 imgcolor_terrain(const struct terrain *pterrain)
2744 {
2745  fc_assert_ret_val(pterrain != nullptr, imgcolor_special(IMGCOLOR_ERROR));
2746  fc_assert_ret_val(pterrain->rgb != nullptr,
2748 
2749  return pterrain->rgb;
2750 }
#define BV_SET_ALL(bv)
Definition: bitvector.h:66
#define BV_CLR_ALL(bv)
Definition: bitvector.h:62
#define BV_SET(bv, bit)
Definition: bitvector.h:44
bool BV_ISSET(const BV &bv, int bit)
Definition: bitvector.h:37
#define BV_ISSET_ANY(vec)
Definition: bitvector.h:76
const char * calendar_text()
Produce a statically allocated textual representation of the current calendar time.
Definition: calendar.cpp:137
#define MAX_NUM_PLAYER_SLOTS
Definition: fc_types.h:24
#define MAX_LEN_NAME
Definition: fc_types.h:61
#define _(String)
Definition: fcintl.h:50
struct civ_game game
Definition: game.cpp:47
struct world wld
Definition: game.cpp:48
int generate_save_name(const char *format, char *buf, int buflen, const char *reason)
Generate a default save file name and place it in the provided buffer.
Definition: game.cpp:756
const char * name
Definition: inputfile.cpp:118
#define fc_assert_ret(condition)
Definition: log.h:112
#define fc_assert(condition)
Definition: log.h:89
#define fc_assert_ret_val(condition, val)
Definition: log.h:114
#define log_debug(message,...)
Definition: log.h:65
#define nat_x
#define nat_y
bool map_is_empty()
Returns TRUE if we are at a stage of the game where the map has not yet been generated/loaded.
Definition: map.cpp:124
struct tile * mapstep(const struct civ_map *nmap, const struct tile *ptile, enum direction8 dir)
Step from the given tile in the given direction.
Definition: map.cpp:342
#define CURRENT_TOPOLOGY
Definition: map.h:34
#define topo_has_flag(topo, flag)
Definition: map.h:36
#define MAP_TO_NATIVE_POS(pnat_x, pnat_y, map_x, map_y)
Definition: map.h:123
#define whole_map_iterate(_map, _tile)
Definition: map.h:473
#define whole_map_iterate_end
Definition: map.h:480
#define index_to_map_pos(pmap_x, pmap_y, mindex)
Definition: map.h:164
static bv_pixel pixel_fogofwar_hexa(const struct tile *ptile, const struct player *pplayer, bool knowledge)
Definition: mapimg.cpp:2256
#define NUM_PIXEL
Definition: mapimg.cpp:53
static int bvplayers_count(const struct mapdef *pmapdef)
Return the number of players defined in a map image definition.
Definition: mapimg.cpp:2664
static bv_pixel pixel_fogofwar_rect(const struct tile *ptile, const struct player *pplayer, bool knowledge)
0 – 2 – 4 – – 7 – 9 – 11 12 – 14 – 16 – – 19 – 21 – 23 24 – 26 – 28 – – 31 – 33 – 35
Definition: mapimg.cpp:2028
static const auto MAPIMG_DEFAULT_IMGFORMAT
Definition: mapimg.cpp:216
static char error_buffer[MAX_LEN_ERRORBUF]
Definition: mapimg.cpp:312
bool mapimg_id2str(int id, char *str, size_t str_len)
Return the map image definition 'id' as a mapdef string.
Definition: mapimg.cpp:1029
static struct @42 mapimg
#define SIZE_X
void mapimg_reset()
Reset the map image subsystem.
Definition: mapimg.cpp:386
#define MAX_LEN_ERRORBUF
Definition: mapimg.cpp:310
mapimg_tile_player_func mapimg_tile_owner
Definition: mapimg.cpp:333
static bool mapimg_test(int id)
Check if the map image subsystem is initialised and the given ID is valid.
Definition: mapimg.cpp:1257
static bool mapimg_def2str(struct mapdef *pmapdef, char *str, size_t str_len)
Return a mapdef string for the map image definition given by 'pmapdef'.
Definition: mapimg.cpp:1272
static void base_coor_hexa(struct img *pimg, int *base_x, int *base_y, int x, int y)
Base coordinates for the tiles on a hexa topology,.
Definition: mapimg.cpp:2382
bool mapimg_colortest(const char *savename, const char *path)
Create images which shows all map colors (playercolor, terrain colors).
Definition: mapimg.cpp:1156
static bv_pixel pixel_city_rect(const struct tile *ptile, const struct player *pplayer, bool knowledge)
Definition: mapimg.cpp:1965
BV_DEFINE(bv_pixel, NUM_PIXEL)
static bv_pixel pixel_border_hexa(const struct tile *ptile, const struct player *pplayer, bool knowledge)
[W] 0 1 [N] 2 – – 5 6 – – – – 11 [SW] 12 – – – – 17 [NE] 18 – – – – 23 24 – – – – 29 30 – – 33 [S] 34...
Definition: mapimg.cpp:2298
mapimg_tile_terrain_func mapimg_tile_terrain
Definition: mapimg.cpp:332
int mapimg_count()
Return the number of map image definitions.
Definition: mapimg.cpp:420
bool init
Definition: mapimg.cpp:328
mapimg_tile_player_func mapimg_tile_city
Definition: mapimg.cpp:334
static struct mapdef * mapdef_new(bool colortest)
Create a new map image definition with default values.
Definition: mapimg.cpp:1497
static void img_destroy(struct img *pimg)
Destroy a image.
Definition: mapimg.cpp:1637
static struct img * img_new(struct mapdef *mapdef, int topo, int xsize, int ysize)
Create a new image.
Definition: mapimg.cpp:1546
bv_pixel(* plot_func)(const struct tile *ptile, const struct player *pplayer, bool knowledge)
Definition: mapimg.cpp:64
mapimg_tile_player_func mapimg_tile_unit
Definition: mapimg.cpp:335
#define TILE_SIZE
Definition: mapimg.cpp:52
static bool img_filename(const char *mapimgfile, const QByteArray &format, char *filename, size_t filename_len)
Generate the final filename.
Definition: mapimg.cpp:1799
static void img_plot(struct img *pimg, int x, int y, const struct rgbcolor *pcolor, const bv_pixel pixel)
Plot one tile at (x,y).
Definition: mapimg.cpp:1677
static const char * showname_help(enum show_player showplr)
Describe the 'show' settings.
Definition: mapimg.cpp:432
static const struct rgbcolor * imgcolor_terrain(const struct terrain *pterrain)
Return rgbcolor for terrain.
Definition: mapimg.cpp:2743
static void img_createmap(struct img *pimg)
Create the map considering the options (terrain, player(s), cities, units, borders,...
Definition: mapimg.cpp:1812
const char * mapimg_error()
Returns the last error.
Definition: mapimg.cpp:585
static bool mapimg_initialised()
Check if the map image subsustem is initialised.
Definition: mapimg.cpp:1251
struct mapdef * mapimg_isvalid(int id)
Check if a map image definition is valid.
Definition: mapimg.cpp:886
void mapimg_init(mapimg_tile_known_func mapimg_tile_known, mapimg_tile_terrain_func mapimg_tile_terrain, mapimg_tile_player_func mapimg_tile_owner, mapimg_tile_player_func mapimg_tile_city, mapimg_tile_player_func mapimg_tile_unit, mapimg_plrcolor_count_func mapimg_plrcolor_count, mapimg_plrcolor_get_func mapimg_plrcolor_get)
Initialisation of the map image subsystem.
Definition: mapimg.cpp:351
static void mapimg_log(const char *file, const char *function, int line, const char *format,...) fc__attribute((__format__(__printf__
Edit the error_buffer.
Definition: mapimg.cpp:1398
static bv_pixel pixel_border_rect(const struct tile *ptile, const struct player *pplayer, bool knowledge)
Definition: mapimg.cpp:2073
#define mapdef_list_iterate_end
Definition: mapimg.cpp:261
static int img_index(const int x, const int y, const struct img *pimg)
Get the index for an (x,y) image coordinate.
Definition: mapimg.cpp:1665
static struct tile_shape tile_rect
Definition: mapimg.cpp:70
#define MAX_NUM_MAPIMG
Definition: mapimg.cpp:214
mapimg_tile_known_func mapimg_tile_known
Definition: mapimg.cpp:331
static bool img_save(const struct img *pimg, const char *mapimgfile, const char *path)
Save an image.
Definition: mapimg.cpp:1714
static bv_pixel pixel_city_hexa(const struct tile *ptile, const struct player *pplayer, bool knowledge)
Definition: mapimg.cpp:2186
static bv_pixel pixel_fogofwar_isohexa(const struct tile *ptile, const struct player *pplayer, bool knowledge)
Definition: mapimg.cpp:2491
void(* base_coor_func)(struct img *pimg, int *base_x, int *base_y, int x, int y)
Definition: mapimg.cpp:66
void mapimg_free()
Free all memory allocated by the map image subsystem.
Definition: mapimg.cpp:405
mapimg_plrcolor_get_func mapimg_plrcolor_get
Definition: mapimg.cpp:337
static bv_pixel pixel_tile_isohexa(const struct tile *ptile, const struct player *pplayer, bool knowledge)
Definition: mapimg.cpp:2401
mapimg_plrcolor_count_func mapimg_plrcolor_count
Definition: mapimg.cpp:336
bool mapimg_define(const char *maparg, bool check)
Define on map image.
Definition: mapimg.cpp:590
bool mapimg_delete(int id)
Delete a map image definition.
Definition: mapimg.cpp:918
static const struct rgbcolor * imgcolor_player(int plr_id)
Return rgbcolor for player.
Definition: mapimg.cpp:2726
#define SIZE_Y
#define MAPIMG_LOG(format,...)
Definition: mapimg.cpp:316
static const char * bvplayers_str(const bv_player &plrbv)
Convert the player bitvector to a string.
Definition: mapimg.cpp:2641
static bv_pixel pixel_tile_hexa(const struct tile *ptile, const struct player *pplayer, bool knowledge)
Definition: mapimg.cpp:2163
static bv_pixel pixel_city_isohexa(const struct tile *ptile, const struct player *pplayer, bool knowledge)
Definition: mapimg.cpp:2423
img_special
Definition: mapimg.cpp:38
@ IMGCOLOR_OCEAN
Definition: mapimg.cpp:40
@ IMGCOLOR_BACKGROUND
Definition: mapimg.cpp:42
@ IMGCOLOR_TEXT
Definition: mapimg.cpp:43
@ IMGCOLOR_GROUND
Definition: mapimg.cpp:41
@ IMGCOLOR_ERROR
Definition: mapimg.cpp:39
static void base_coor_rect(struct img *pimg, int *base_x, int *base_y, int x, int y)
Base coordinates for the tiles on a (isometric) rectange topology,.
Definition: mapimg.cpp:2145
static struct tile_shape tile_hexa
Definition: mapimg.cpp:95
#define MAPIMG_ASSERT_RET_VAL(cond, expr)
Definition: mapimg.cpp:318
static char * mapimg_generate_name(struct mapdef *pmapdef)
Generate an identifier for a map image.
Definition: mapimg.cpp:1424
struct mapdef_list * mapdef
Definition: mapimg.cpp:329
static bv_pixel pixel_unit_rect(const struct tile *ptile, const struct player *pplayer, bool knowledge)
Definition: mapimg.cpp:2003
char * mapimg_help(const char *cmdname)
Return a help string for the 'mapimg' command.
Definition: mapimg.cpp:457
static bv_pixel pixel_unit_hexa(const struct tile *ptile, const struct player *pplayer, bool knowledge)
Definition: mapimg.cpp:2229
static void img_plot_tile(struct img *pimg, const struct tile *ptile, const struct rgbcolor *pcolor, const bv_pixel pixel)
Plot one tile.
Definition: mapimg.cpp:1700
static void base_coor_isohexa(struct img *pimg, int *base_x, int *base_y, int x, int y)
Base coordinates for the tiles on a isometric hexa topology,.
Definition: mapimg.cpp:2621
static void mapdef_destroy(struct mapdef *pmapdef)
Destroy a map image definition.
Definition: mapimg.cpp:1528
bool mapimg_create(struct mapdef *pmapdef, bool force, const char *savename, const char *path)
Create the requested map image.
Definition: mapimg.cpp:1050
static const struct rgbcolor * imgcolor_special(enum img_special imgcolor)
Return rgbcolor for img_special.
Definition: mapimg.cpp:2703
static bv_pixel pixel_border_isohexa(const struct tile *ptile, const struct player *pplayer, bool knowledge)
Definition: mapimg.cpp:2537
#define mapdef_list_iterate(mapdef_list, pmapdef)
Definition: mapimg.cpp:259
#define MAX_LEN_MAPARG
Definition: mapimg.cpp:213
static struct tile_shape tile_isohexa
Definition: mapimg.cpp:125
bool mapimg_show(int id, char *str, size_t str_len, bool detail)
Show a map image definition.
Definition: mapimg.cpp:937
static bool mapimg_define_arg(struct mapdef *pmapdef, enum mapdef_arg arg, const char *val, bool check)
Helper function for mapimg_define().
Definition: mapimg.cpp:711
static bool mapimg_checkplayers(struct mapdef *pmapdef, bool recheck)
Check the player selection.
Definition: mapimg.cpp:1330
static bv_pixel pixel_unit_isohexa(const struct tile *ptile, const struct player *pplayer, bool knowledge)
Definition: mapimg.cpp:2465
static void img_set_pixel(struct img *pimg, const int mindex, const struct rgbcolor *pcolor)
Set the color of one pixel.
Definition: mapimg.cpp:1650
static bv_pixel pixel_tile_rect(const struct tile *ptile, const struct player *pplayer, bool knowledge)
0 1 2 3 3 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35
Definition: mapimg.cpp:1944
int(* mapimg_plrcolor_count_func)()
Definition: mapimg.h:84
#define MAX_LEN_MAPDEF
Definition: mapimg.h:52
struct player *(* mapimg_tile_player_func)(const struct tile *ptile, const struct player *pplayer, bool knowledge)
Definition: mapimg.h:81
enum known_type(* mapimg_tile_known_func)(const struct tile *ptile, const struct player *pplayer, bool knowledge)
Definition: mapimg.h:77
struct rgbcolor *(* mapimg_plrcolor_get_func)(int)
Definition: mapimg.h:85
struct terrain *(* mapimg_tile_terrain_func)(const struct tile *ptile, const struct player *pplayer, bool knowledge)
Definition: mapimg.h:79
int len
Definition: packhand.cpp:127
struct player * player_by_number(const int player_id)
Return struct player pointer for the given player index.
Definition: player.cpp:768
int player_number(const struct player *pplayer)
Return the player index/number/id.
Definition: player.cpp:756
struct player * player_by_name_prefix(const char *name, enum m_pre_result *result)
Find player by its name prefix.
Definition: player.cpp:841
int player_count()
Return the number of players.
Definition: player.cpp:739
int player_index(const struct player *pplayer)
Return the player index.
Definition: player.cpp:748
const char * player_name(const struct player *pplayer)
Return the leader name of the player.
Definition: player.cpp:816
#define players_iterate_end
Definition: player.h:520
#define players_iterate(_pplayer)
Definition: player.h:514
#define is_human(plr)
Definition: player.h:226
bool make_dir(const QString &pathname)
If the directory "pathname" does not exist, recursively create all directories until it does.
Definition: shared.cpp:1115
#define ARRAY_SIZE(x)
Definition: shared.h:79
#define MAX(x, y)
Definition: shared.h:48
#define MAX_LEN_PATH
Definition: shared.h:28
m_pre_result
Definition: shared.h:152
struct packet_game_info info
Definition: game.h:80
int xsize
Definition: map_types.h:73
int ysize
Definition: map_types.h:73
Definition: mapimg.cpp:266
struct img::@47 imgsize
struct mapdef * def
Definition: mapimg.cpp:267
struct tile_shape * tileshape
Definition: mapimg.cpp:272
base_coor_func base_coor
Definition: mapimg.cpp:278
plot_func pixel_tile
Definition: mapimg.cpp:273
int y
Definition: mapimg.cpp:282
plot_func pixel_city
Definition: mapimg.cpp:274
int x
Definition: mapimg.cpp:281
char title[MAX_LEN_MAPDEF]
Definition: mapimg.cpp:269
const struct rgbcolor ** map
Definition: mapimg.cpp:288
int turn
Definition: mapimg.cpp:268
struct img::@46 mapsize
plot_func pixel_fogofwar
Definition: mapimg.cpp:276
plot_func pixel_border
Definition: mapimg.cpp:277
plot_func pixel_unit
Definition: mapimg.cpp:275
enum mapimg_status status
Definition: mapimg.cpp:231
char error[MAX_LEN_MAPDEF]
Definition: mapimg.cpp:230
int zoom
Definition: mapimg.cpp:233
bv_player checked_plrbv
Definition: mapimg.cpp:243
bv_player plrbv
Definition: mapimg.cpp:241
bv_mapdef_arg args
Definition: mapimg.cpp:247
QByteArray format
Definition: mapimg.cpp:232
int id
Definition: mapimg.cpp:240
int turns
Definition: mapimg.cpp:234
enum show_player show
Definition: mapimg.cpp:237
struct mapdef::@43 player
bool colortest
Definition: mapimg.cpp:248
bool layers[MAPIMG_LAYER_COUNT]
Definition: mapimg.cpp:235
char name[MAX_LEN_NAME]
Definition: mapimg.cpp:239
char maparg[MAX_LEN_MAPARG]
Definition: mapimg.cpp:229
Definition: player.h:231
bool is_alive
Definition: player.h:250
struct rgbcolor * rgb
Definition: player.h:293
struct rgbcolor * rgb
Definition: terrain.h:240
int y[NUM_PIXEL]
Definition: mapimg.cpp:59
int x[NUM_PIXEL]
Definition: mapimg.cpp:58
Definition: tile.h:42
struct civ_map map
Definition: world_object.h:21
int fc_snprintf(char *str, size_t n, const char *format,...)
See also fc_utf8_snprintf_trunc(), fc_utf8_snprintf_rep().
Definition: support.cpp:537
size_t fc_strlcpy(char *dest, const char *src, size_t n)
fc_strlcpy() provides utf-8 version of (non-standard) function strlcpy() It is intended as more user-...
Definition: support.cpp:412
int fc_strcasecmp(const char *str0, const char *str1)
Compare strings like strcmp(), but ignoring case.
Definition: support.cpp:89
int cat_snprintf(char *str, size_t n, const char *format,...)
cat_snprintf is like a combination of fc_snprintf and fc_strlcat; it does snprintf to the end of an e...
Definition: support.cpp:564
int fc_vsnprintf(char *str, size_t n, const char *format, va_list ap)
Definition: support.cpp:512
#define sz_strlcpy(dest, src)
Definition: support.h:140
int fc__attribute((nonnull(1, 3)))
#define fc_strdup(str)
Definition: support.h:111
#define sz_strlcat(dest, src)
Definition: support.h:142
Terrain_type_id terrain_count()
Return the number of terrains.
Definition: terrain.cpp:93
struct terrain * terrain_by_number(const Terrain_type_id type)
Return the terrain for the given terrain index.
Definition: terrain.cpp:128
#define is_ocean(pterrain)
Definition: terrain.h:276
#define tile_index(_pt_)
Definition: tile.h:70
known_type
Definition: tile.h:28
@ TILE_KNOWN_UNSEEN
Definition: tile.h:30
@ TILE_UNKNOWN
Definition: tile.h:29
void timer_destroy(civtimer *t)
Deletes timer.
Definition: timing.cpp:66
double timer_read_seconds(civtimer *t)
Read value from timer.
Definition: timing.cpp:137
civtimer * timer_new(enum timer_timetype type, enum timer_use use)
Allocate a new timer with specified "type" and "use".
Definition: timing.cpp:43
void timer_start(civtimer *t)
Start timing, adding to previous accumulated time if timer has not been cleared.
Definition: timing.cpp:95
@ TIMER_ACTIVE
Definition: timing.h:25
@ TIMER_CPU
Definition: timing.h:20
@ TIMER_USER
Definition: timing.h:21