Freeciv-3.1
Loading...
Searching...
No Matches
mapimg.c
Go to the documentation of this file.
1/****************************************************************************
2 Freeciv - Copyright (C) 2010 - The Freeciv Team
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#ifdef HAVE_CONFIG_H
15#include <fc_config.h>
16#endif
17
18#include <stdarg.h>
19
20#ifdef HAVE_MAPIMG_MAGICKWAND
21#ifdef FREECIV_MWAND7
22 #include <MagickWand/MagickWand.h>
23#else /* FREECIV_MWAND7 */
24 #include <wand/MagickWand.h>
25#endif /* FREECIV_MWAND7 */
26#endif /* HAVE_MAPIMG_MAGICKWAND */
27
28/* utility */
29#include "astring.h"
30#include "bitvector.h"
31#include "fc_cmdline.h"
32#include "fcintl.h"
33#include "log.h"
34#include "mem.h"
35#include "string_vector.h"
36#include "timing.h"
37
38/* common */
39#include "calendar.h"
40#include "connection.h"
41#include "fc_types.h"
42#include "game.h"
43#include "map.h"
44#include "rgbcolor.h"
45#include "terrain.h"
46#include "tile.h"
47#include "version.h"
48#include "player.h"
49
50#include "mapimg.h"
51
52/* Some magick for ImageMagick - the interface has changed:
53 ImageMagick-6.6.2-0: PixelGetNextIteratorRow(..., unsigned long *)
54 ImageMagick-6.6.2-1: PixelGetNextIteratorRow(..., size_t *)
55 Theoretically, "unsigned long" and "size_t" are pretty much the same but
56 in practice the compiler will complain bitterly.
57 (from Gem-0.93 ImageMAGICK plugin) */
58#ifndef MagickLibInterface
59# define MagickLibInterface 0
60#endif
61#ifndef MagickLibVersion
62# define MagickLibVersion 0
63#endif
64
65/* This won't catch ImageMagick>=6.6.2-0.
66 Another workaround: compile with "-fpermissive" */
67#if (MagickLibInterface > 3) || (MagickLibVersion >= 0x662)
68# define magickwand_size_t size_t
69#else
70# define magickwand_size_t unsigned long
71#endif
72
73/* == image colors == */
81
82static const struct rgbcolor *imgcolor_special(enum img_special imgcolor);
83static const struct rgbcolor *imgcolor_player(int plr_id);
84static const struct rgbcolor
85 *imgcolor_terrain(const struct terrain *pterrain);
86
87/* == topologies == */
88#define TILE_SIZE 6
89#define NUM_PIXEL TILE_SIZE * TILE_SIZE
90
92
93struct tile_shape {
96};
97
98struct img;
99
100typedef bv_pixel (*plot_func)(const struct tile *ptile,
101 const struct player *pplayer,
102 bool knowledge);
103typedef void (*base_coor_func)(struct img *pimg, int *base_x, int *base_y,
104 int x, int y);
105
106/* (isometric) rectangular topology */
107static struct tile_shape tile_rect = {
108 .x = {
109 0, 1, 2, 3, 4, 5,
110 0, 1, 2, 3, 4, 5,
111 0, 1, 2, 3, 4, 5,
112 0, 1, 2, 3, 4, 5,
113 0, 1, 2, 3, 4, 5,
114 0, 1, 2, 3, 4, 5
115 },
116 .y = {
117 0, 0, 0, 0, 0, 0,
118 1, 1, 1, 1, 1, 1,
119 2, 2, 2, 2, 2, 2,
120 3, 3, 3, 3, 3, 3,
121 4, 4, 4, 4, 4, 4,
122 5, 5, 5, 5, 5, 5
123 }
124};
125
126static bv_pixel pixel_tile_rect(const struct tile *ptile,
127 const struct player *pplayer,
128 bool knowledge);
129static bv_pixel pixel_city_rect(const struct tile *ptile,
130 const struct player *pplayer,
131 bool knowledge);
132static bv_pixel pixel_unit_rect(const struct tile *ptile,
133 const struct player *pplayer,
134 bool knowledge);
135static bv_pixel pixel_fogofwar_rect(const struct tile *ptile,
136 const struct player *pplayer,
137 bool knowledge);
138static bv_pixel pixel_border_rect(const struct tile *ptile,
139 const struct player *pplayer,
140 bool knowledge);
141static void base_coor_rect(struct img *pimg, int *base_x, int *base_y,
142 int x, int y);
143
144/* hexa topology */
145static struct tile_shape tile_hexa = {
146 .x = {
147 2, 3,
148 1, 2, 3, 4,
149 0, 1, 2, 3, 4, 5,
150 0, 1, 2, 3, 4, 5,
151 0, 1, 2, 3, 4, 5,
152 0, 1, 2, 3, 4, 5,
153 1, 2, 3, 4,
154 2, 3,
155 },
156 .y = {
157 0, 0,
158 1, 1, 1, 1,
159 2, 2, 2, 2, 2, 2,
160 3, 3, 3, 3, 3, 3,
161 4, 4, 4, 4, 4, 4,
162 5, 5, 5, 5, 5, 5,
163 6, 6, 6, 6,
164 7, 7,
165 }
166};
167
168static bv_pixel pixel_tile_hexa(const struct tile *ptile,
169 const struct player *pplayer,
170 bool knowledge);
171static bv_pixel pixel_city_hexa(const struct tile *ptile,
172 const struct player *pplayer,
173 bool knowledge);
174static bv_pixel pixel_unit_hexa(const struct tile *ptile,
175 const struct player *pplayer,
176 bool knowledge);
177static bv_pixel pixel_fogofwar_hexa(const struct tile *ptile,
178 const struct player *pplayer,
179 bool knowledge);
180static bv_pixel pixel_border_hexa(const struct tile *ptile,
181 const struct player *pplayer,
182 bool knowledge);
183static void base_coor_hexa(struct img *pimg, int *base_x, int *base_y,
184 int x, int y);
185
186/* isometric hexa topology */
187static struct tile_shape tile_isohexa = {
188 .x = {
189 2, 3, 4, 5,
190 1, 2, 3, 4, 5, 6,
191 0, 1, 2, 3, 4, 5, 6, 7,
192 0, 1, 2, 3, 4, 5, 6, 7,
193 1, 2, 3, 4, 5, 6,
194 2, 3, 4, 5
195 },
196 .y = {
197 0, 0, 0, 0,
198 1, 1, 1, 1, 1, 1,
199 2, 2, 2, 2, 2, 2, 2, 2,
200 3, 3, 3, 3, 3, 3, 3, 3,
201 4, 4, 4, 4, 4, 4,
202 5, 5, 5, 5
203 }
204};
205
206static bv_pixel pixel_tile_isohexa(const struct tile *ptile,
207 const struct player *pplayer,
208 bool knowledge);
209static bv_pixel pixel_city_isohexa(const struct tile *ptile,
210 const struct player *pplayer,
211 bool knowledge);
212static bv_pixel pixel_unit_isohexa(const struct tile *ptile,
213 const struct player *pplayer,
214 bool knowledge);
215static bv_pixel pixel_fogofwar_isohexa(const struct tile *ptile,
216 const struct player *pplayer,
217 bool knowledge);
218static bv_pixel pixel_border_isohexa(const struct tile *ptile,
219 const struct player *pplayer,
220 bool knowledge);
221static void base_coor_isohexa(struct img *pimg, int *base_x, int *base_y,
222 int x, int y);
223
224/* == map images == */
225
226#define ARG_PLRBV "plrbv"
227#define ARG_PLRID "plrid"
228#define ARG_PLRNAME "plrname"
229
230/* mapimg definition */
231#define SPECENUM_NAME mapdef_arg
232#define SPECENUM_VALUE0 MAPDEF_FORMAT
233#define SPECENUM_VALUE0NAME "format"
234#define SPECENUM_VALUE1 MAPDEF_MAP
235#define SPECENUM_VALUE1NAME "map"
236#define SPECENUM_VALUE2 MAPDEF_PLRBV
237#define SPECENUM_VALUE2NAME ARG_PLRBV
238#define SPECENUM_VALUE3 MAPDEF_PLRID
239#define SPECENUM_VALUE3NAME ARG_PLRID
240#define SPECENUM_VALUE4 MAPDEF_PLRNAME
241#define SPECENUM_VALUE4NAME ARG_PLRNAME
242#define SPECENUM_VALUE5 MAPDEF_SHOW
243#define SPECENUM_VALUE5NAME "show"
244#define SPECENUM_VALUE6 MAPDEF_TURNS
245#define SPECENUM_VALUE6NAME "turns"
246#define SPECENUM_VALUE7 MAPDEF_ZOOM
247#define SPECENUM_VALUE7NAME "zoom"
248#define SPECENUM_COUNT MAPDEF_COUNT
249#include "specenum_gen.h"
250
251BV_DEFINE(bv_mapdef_arg, MAPDEF_COUNT);
252
253/* image format */
254#define SPECENUM_NAME imageformat
255#define SPECENUM_BITWISE
256#define SPECENUM_VALUE0 IMGFORMAT_GIF
257#define SPECENUM_VALUE0NAME "gif"
258#define SPECENUM_VALUE1 IMGFORMAT_PNG
259#define SPECENUM_VALUE1NAME "png"
260#define SPECENUM_VALUE2 IMGFORMAT_PPM
261#define SPECENUM_VALUE2NAME "ppm"
262#define SPECENUM_VALUE3 IMGFORMAT_JPG
263#define SPECENUM_VALUE3NAME "jpg"
264#include "specenum_gen.h"
265
266/* image format */
267#define SPECENUM_NAME imagetool
268#define SPECENUM_VALUE0 IMGTOOL_PPM
269#define SPECENUM_VALUE0NAME "ppm"
270#define SPECENUM_VALUE1 IMGTOOL_MAGICKWAND
271#define SPECENUM_VALUE1NAME "magick"
272#include "specenum_gen.h"
273
274/* player definitions */
275#define SPECENUM_NAME show_player
276#define SPECENUM_VALUE0 SHOW_NONE
277#define SPECENUM_VALUE0NAME "none"
278#define SPECENUM_VALUE1 SHOW_EACH
279#define SPECENUM_VALUE1NAME "each"
280#define SPECENUM_VALUE2 SHOW_HUMAN
281#define SPECENUM_VALUE2NAME "human"
282#define SPECENUM_VALUE3 SHOW_ALL
283#define SPECENUM_VALUE3NAME "all"
284/* should be identical to MAPDEF_PLRNAME */
285#define SPECENUM_VALUE4 SHOW_PLRNAME
286#define SPECENUM_VALUE4NAME ARG_PLRNAME
287/* should be identical to MAPDEF_PLRID */
288#define SPECENUM_VALUE5 SHOW_PLRID
289#define SPECENUM_VALUE5NAME ARG_PLRID
290/* should be identical to MAPDEF_PLRBV */
291#define SPECENUM_VALUE6 SHOW_PLRBV
292#define SPECENUM_VALUE6NAME ARG_PLRBV
293#include "specenum_gen.h"
294
295#undef ARG_PLRBV
296#undef ARG_PLRID
297#undef ARG_PLRNAME
298
299/* map definition status */
300#define SPECENUM_NAME mapimg_status
301#define SPECENUM_VALUE0 MAPIMG_STATUS_UNKNOWN
302#define SPECENUM_VALUE0NAME _("not checked")
303#define SPECENUM_VALUE1 MAPIMG_STATUS_OK
304#define SPECENUM_VALUE1NAME _("OK")
305#define SPECENUM_VALUE2 MAPIMG_STATUS_ERROR
306#define SPECENUM_VALUE2NAME _("error")
307#include "specenum_gen.h"
308
309#define MAX_LEN_MAPARG MAX_LEN_MAPDEF
310#define MAX_NUM_MAPIMG 10
311
312static bool mapimg_test(int id);
313static bool mapimg_define_arg(struct mapdef *pmapdef, enum mapdef_arg arg,
314 const char *val, bool check);
315static bool mapimg_def2str(struct mapdef *pmapdef, char *str, size_t str_len);
316static bool mapimg_checkplayers(struct mapdef *pmapdef, bool recheck);
317static char *mapimg_generate_name(struct mapdef *pmapdef);
318
319/* == map definition == */
320struct mapdef {
323 enum mapimg_status status;
324 enum imageformat format;
325 enum imagetool tool;
326 int zoom;
327 int turns;
328 bool layers[MAPIMG_LAYER_COUNT];
329 struct {
330 enum show_player show;
331 union {
332 char name[MAX_LEN_NAME]; /* used by SHOW_PLRNAME */
333 int id; /* used by SHOW_PLRID */
334 bv_player plrbv; /* used by SHOW_PLRBV */
335 };
336 bv_player checked_plrbv; /* player bitvector used for the image
337 * creation */
339
340 bv_mapdef_arg args;
342};
343
344static struct mapdef *mapdef_new(bool colortest);
345static void mapdef_destroy(struct mapdef *pmapdef);
346
347/* List of map definitions. */
348#define SPECLIST_TAG mapdef
349#define SPECLIST_TYPE struct mapdef
350#include "speclist.h"
351
352#define mapdef_list_iterate(mapdef_list, pmapdef) \
353 TYPED_LIST_ITERATE(struct mapdef, mapdef_list, pmapdef)
354#define mapdef_list_iterate_end \
355 LIST_ITERATE_END
356
357/* == images == */
358struct mapdef;
359
360/* Some lengths used for the images created by the magickwand toolkit. */
361#define IMG_BORDER_HEIGHT 5
362#define IMG_BORDER_WIDTH IMG_BORDER_HEIGHT
363#define IMG_SPACER_HEIGHT 5
364#define IMG_LINE_HEIGHT 5
365#define IMG_TEXT_HEIGHT 12
366
367struct img {
368 struct mapdef *def; /* map definition */
369 int turn; /* save turn */
371
372 /* topology definition */
380
381 struct {
382 int x;
383 int y;
384 } mapsize; /* map size */
385 struct {
386 int x;
387 int y;
388 } imgsize; /* image size */
389 const struct rgbcolor **map;
390};
391
392static struct img *img_new(struct mapdef *mapdef, int topo, int xsize, int ysize);
393static void img_destroy(struct img *pimg);
394static inline void img_set_pixel(struct img *pimg, const int mindex,
395 const struct rgbcolor *pcolor);
396static inline int img_index(const int x, const int y,
397 const struct img *pimg);
398static const char *img_playerstr(const struct player *pplayer);
399static void img_plot(struct img *pimg, int x, int y,
400 const struct rgbcolor *pcolor, const bv_pixel pixel);
401static void img_plot_tile(struct img *pimg, const struct tile *ptile,
402 const struct rgbcolor *pcolor, const bv_pixel pixel);
403static bool img_save(const struct img *pimg, const char *mapimgfile,
404 const char *path);
405static bool img_save_ppm(const struct img *pimg, const char *mapimgfile);
406#ifdef HAVE_MAPIMG_MAGICKWAND
407static bool img_save_magickwand(const struct img *pimg,
408 const char *mapimgfile);
409#endif /* HAVE_MAPIMG_MAGICKWAND */
410static bool img_filename(const char *mapimgfile, enum imageformat format,
411 char *filename, size_t filename_len);
412static void img_createmap(struct img *pimg);
413
414/* == image toolkits == */
415typedef bool (*img_save_func)(const struct img *pimg,
416 const char *mapimgfile);
417
418struct toolkit {
419 enum imagetool tool;
420 enum imageformat format_default;
423 const char *help;
424};
425
426#define GEN_TOOLKIT(_tool, _format_default, _formats, _save_func, _help) \
427 {_tool, _format_default, _formats, _save_func, _help},
428
429static struct toolkit img_toolkits[] = {
430 GEN_TOOLKIT(IMGTOOL_PPM, IMGFORMAT_PPM, IMGFORMAT_PPM,
432 N_("Standard ppm files"))
433#ifdef HAVE_MAPIMG_MAGICKWAND
434 GEN_TOOLKIT(IMGTOOL_MAGICKWAND, IMGFORMAT_GIF,
435 IMGFORMAT_GIF + IMGFORMAT_PNG + IMGFORMAT_PPM + IMGFORMAT_JPG,
436 img_save_magickwand,
437 N_("ImageMagick"))
438#endif /* HAVE_MAPIMG_MAGICKWAND */
439};
440
442
443#ifdef HAVE_MAPIMG_MAGICKWAND
444 #define MAPIMG_DEFAULT_IMGFORMAT IMGFORMAT_GIF
445 #define MAPIMG_DEFAULT_IMGTOOL IMGTOOL_MAGICKWAND
446#else
447 #define MAPIMG_DEFAULT_IMGFORMAT IMGFORMAT_PPM
448 #define MAPIMG_DEFAULT_IMGTOOL IMGTOOL_PPM
449#endif /* HAVE_MAPIMG_MAGICKWAND */
450
451static const struct toolkit *img_toolkit_get(enum imagetool tool);
452
453#define img_toolkit_iterate(_toolkit) \
454 { \
455 int _i; \
456 for (_i = 0; _i < img_toolkits_count; _i++) { \
457 const struct toolkit *_toolkit = &img_toolkits[_i];
458
459#define img_toolkit_iterate_end \
460 } \
461 }
462
463/* == logging == */
464#define MAX_LEN_ERRORBUF 1024
465
466static char error_buffer[MAX_LEN_ERRORBUF] = "\0";
467static void mapimg_log(const char *file, const char *function, int line,
468 const char *format, ...)
469 fc__attribute((__format__(__printf__, 4, 5)));
470#define MAPIMG_LOG(format, ...) \
471 mapimg_log(__FILE__, __FUNCTION__, __FC_LINE__, format, ## __VA_ARGS__)
472#define MAPIMG_ASSERT_RET_VAL(cond, expr) \
473 fc_assert_action(cond, MAPIMG_LOG(_("internal error")); return (expr))
474
475/* == additional functions == */
476
477static int bvplayers_count(const struct mapdef *pmapdef);
478static const char *bvplayers_str(const bv_player plrbv);
479
480/* == map images data == */
481static struct {
482 bool init;
483 struct mapdef_list *mapdef;
484
492} mapimg = { .init = FALSE };
493
494/*
495 * ==============================================
496 * map images (external functions)
497 * ==============================================
498 */
499
500/************************************************************************/
536
537/************************************************************************/
540void mapimg_reset(void)
541{
542 if (!mapimg_initialised()) {
543 return;
544 }
545
546 if (mapdef_list_size(mapimg.mapdef) > 0) {
547 mapdef_list_iterate(mapimg.mapdef, pmapdef) {
548 mapdef_list_remove(mapimg.mapdef, pmapdef);
549 mapdef_destroy(pmapdef);
551 }
552}
553
554/************************************************************************/
557void mapimg_free(void)
558{
559 if (!mapimg_initialised()) {
560 return;
561 }
562
563 mapimg_reset();
564 mapdef_list_destroy(mapimg.mapdef);
565
566 mapimg.init = FALSE;
567}
568
569/************************************************************************/
573{
574 if (!mapimg_initialised()) {
575 return 0;
576 }
577
578 return mapdef_list_size(mapimg.mapdef);
579}
580
581/************************************************************************/
584static const char *showname_help(enum show_player showplr)
585{
586 switch (showplr) {
587 case SHOW_NONE: return _("no players, only terrain");
588 case SHOW_EACH: return _("one image per player");
589 case SHOW_HUMAN: return _("one image per human player");
590 case SHOW_ALL: return _("all players on a single image");
591 case SHOW_PLRNAME: return _("just the player named with 'plrname'");
592 case SHOW_PLRID: return _("just the player specified with 'plrid'");
593 case SHOW_PLRBV: return _("one image per player in 'plrbv'");
594 }
595 fc_assert(0);
596 return "";
597}
598
599/************************************************************************/
602char *mapimg_help(const char *cmdname)
603{
604 enum imagetool tool;
605 enum show_player showplr;
606 enum mapimg_layer layer;
607 struct astring defaults[MAPDEF_COUNT];
608 struct astring str_format = ASTRING_INIT, str_showplr = ASTRING_INIT;
609 struct mapdef *pmapdef = mapdef_new(FALSE);
610 static struct astring help = ASTRING_INIT;
611
612 if (astr_len(&help) > 0) {
613 /* Help text was created already. */
614 return fc_strdup(astr_str(&help));
615 }
616
617 /* Possible 'format' settings (toolkit + format). */
618 for (tool = imagetool_begin(); tool != imagetool_end();
619 tool = imagetool_next(tool)) {
620 enum imageformat format;
621 const struct toolkit *toolkit = img_toolkit_get(tool);
622 const char *separator = "";
623
624 if (!toolkit) {
625 continue;
626 }
627
628 astr_add(&str_format, " - '%s': ", imagetool_name(tool));
629
630 for (format = imageformat_begin(); format != imageformat_end();
631 format = imageformat_next(format)) {
632 if (toolkit->formats & format) {
633 const char *name = imageformat_name(format);
634
635 if (name != NULL) {
636 astr_add(&str_format, "%s'%s'", separator, name);
637 separator = ", ";
638 }
639 }
640 }
641
642 if (tool != imagetool_max()) {
643 astr_add(&str_format, "\n");
644 }
645 }
646
647 /* Possible 'show' settings. */
648 for (showplr = show_player_begin(); showplr != show_player_end();
649 showplr = show_player_next(showplr)) {
650 const char *nameptr = show_player_name(showplr);
651
652 if (nameptr != NULL) {
653 char name[10];
654
655 fc_snprintf(name, sizeof(name), "'%s'", nameptr);
656 astr_add(&str_showplr, " - %-9s %s", name, showname_help(showplr));
657 if (showplr != show_player_max()) {
658 astr_add(&str_showplr, "\n");
659 }
660 }
661 }
662
663 /* Default values. */
664 astr_init(&defaults[MAPDEF_FORMAT]);
665 astr_set(&defaults[MAPDEF_FORMAT],
666 "(%s|%s)", imagetool_name(pmapdef->tool),
667 imageformat_name(pmapdef->format));
668 astr_init(&defaults[MAPDEF_SHOW]);
669 astr_set(&defaults[MAPDEF_SHOW],
670 "(%s)", show_player_name(pmapdef->player.show));
671 astr_init(&defaults[MAPDEF_TURNS]);
672 astr_set(&defaults[MAPDEF_TURNS], "(%d)", pmapdef->turns);
673 astr_init(&defaults[MAPDEF_ZOOM]);
674 astr_set(&defaults[MAPDEF_ZOOM], "(%d)", pmapdef->zoom);
675
676 astr_init(&defaults[MAPDEF_MAP]);
677 astr_set(&defaults[MAPDEF_MAP], "(");
678 for (layer = mapimg_layer_begin(); layer != mapimg_layer_end();
679 layer = mapimg_layer_next(layer)) {
680 if (pmapdef->layers[layer]) {
681 astr_add(&defaults[MAPDEF_MAP], "%c", mapimg_layer_name(layer)[0]);
682 }
683 }
684 astr_add(&defaults[MAPDEF_MAP], ")");
685
686 /* help text */
687 astr_set(&help,
688 /* TRANS: This is help for a server command, so keywords like
689 * "define" in the first column are server keywords that must not
690 * be translated. Do not translate keywords in single quotes, but
691 * strings in <angle brackets> should be translated. */
692 _("This command controls the creation of map images. Supported "
693 "arguments:\n"
694 " define <mapdef> - define a map image; returns numeric <id>\n"
695 " show <id>|all - list map image definitions or show a specific one\n"
696 " create <id>|all - manually save image(s) for current map state\n"
697 " delete <id>|all - delete map image definition(s)\n"
698 " colortest - create test image(s) showing all colors\n"
699 "\n"
700 "Multiple definitions can be active at once. "
701 "A definition <mapdef> consists of colon-separated options:\n"
702 "\n"
703 "option (default) description\n"
704 "\n"
705 "format=<[tool|]format> %-10s file format\n"
706 "show=<show> %-10s which players to show\n"
707 " plrname=<name> player name\n"
708 " plrid=<id> numeric player id\n"
709 " plrbv=<bit vector> see example; first char = id 0\n"
710 "turns=<turns> %-10s save image each <turns> turns\n"
711 " (0=no autosave, save with 'create')\n"
712 "zoom=<zoom> %-10s magnification factor (1-5)\n"
713 "map=<map> %-10s which map layers to draw\n"
714 "\n"
715 "<[tool|]format> = use image format <format>, optionally specifying "
716 "toolkit <tool>. The following toolkits and formats are compiled in:\n"
717 "%s\n"
718 "\n"
719 "<show> determines which players are represented and how many "
720 "images are saved by this definition:\n"
721 "%s\n"
722 "\n"
723 "<map> can contain one or more of the following layers:\n"
724 " - 'a' show area within borders of specified players\n"
725 " - 'b' show borders of specified players\n"
726 " - 'c' show cities of specified players\n"
727 " - 'f' show fog of war (single-player images only)\n"
728 " - 'k' show only player knowledge (single-player images only)\n"
729 " - 't' full display of terrain types\n"
730 " - 'u' show units of specified players\n"
731 "\n"
732 "Examples of <mapdef>:\n"
733 " 'zoom=1:map=tcub:show=all:format=ppm|ppm'\n"
734 " 'zoom=2:map=tcub:show=each:format=png'\n"
735 " 'zoom=1:map=tcub:show=plrname:plrname=Otto:format=gif'\n"
736 " 'zoom=3:map=cu:show=plrbv:plrbv=010011:format=jpg'\n"
737 " 'zoom=1:map=t:show=none:format=magick|jpg'"),
738 astr_str(&defaults[MAPDEF_FORMAT]), astr_str(&defaults[MAPDEF_SHOW]),
739 astr_str(&defaults[MAPDEF_TURNS]), astr_str(&defaults[MAPDEF_ZOOM]),
740 astr_str(&defaults[MAPDEF_MAP]),
741 astr_str(&str_format), astr_str(&str_showplr));
742
743 mapdef_destroy(pmapdef);
744 astr_free(&str_format);
745 astr_free(&str_showplr);
746 astr_free(&defaults[MAPDEF_FORMAT]);
747 astr_free(&defaults[MAPDEF_SHOW]);
748 astr_free(&defaults[MAPDEF_TURNS]);
749 astr_free(&defaults[MAPDEF_ZOOM]);
750 astr_free(&defaults[MAPDEF_MAP]);
751
752 return fc_strdup(astr_str(&help));
753}
754
755/************************************************************************/
758const char *mapimg_error(void)
759{
760 return error_buffer;
761}
762
763/************************************************************************/
766#define NUM_MAX_MAPARGS 10
767#define NUM_MAX_MAPOPTS 2
768bool mapimg_define(const char *maparg, bool check)
769{
770 struct mapdef *pmapdef = NULL;
771 char *mapargs[NUM_MAX_MAPARGS], *mapopts[NUM_MAX_MAPOPTS];
772 int nmapargs, nmapopts, i;
773 bool ret = TRUE;
774
776
777 if (maparg == NULL) {
778 MAPIMG_LOG(_("no map definition"));
779 return FALSE;
780 }
781
782 if (strlen(maparg) > MAX_LEN_MAPARG) {
783 /* too long map definition string */
784 MAPIMG_LOG(_("map definition string too long (max %d characters)"),
786 return FALSE;
787 }
788
789 if (mapimg_count() == MAX_NUM_MAPIMG) {
790 MAPIMG_LOG(_("maximum number of map definitions reached (%d)"),
792 return FALSE;
793 }
794
795 for (i = 0; i < mapimg_count(); i++) {
796 pmapdef = mapdef_list_get(mapimg.mapdef, i);
797 if (0 == fc_strcasecmp(pmapdef->maparg, maparg)) {
798 MAPIMG_LOG(_("duplicate of map image definition %d ('%s')"), i,
799 maparg);
800 return FALSE;
801 }
802 }
803
804 pmapdef = mapdef_new(FALSE);
805
806 /* get map options */
807 nmapargs = get_tokens(maparg, mapargs, NUM_MAX_MAPARGS, ":");
808
809 for (i = 0; i < nmapargs; i++) {
810 /* split map options into variable and value */
811 nmapopts = get_tokens(mapargs[i], mapopts, NUM_MAX_MAPOPTS, "=");
812
813 if (nmapopts == 2) {
814 enum mapdef_arg arg = mapdef_arg_by_name(mapopts[0], strcmp);
815 if (mapdef_arg_is_valid(arg)) {
816 /* If ret is FALSE an error message is set by mapimg_define_arg(). */
817 ret = mapimg_define_arg(pmapdef, arg, mapopts[1], check);
818 } else {
819 MAPIMG_LOG(_("unknown map option: '%s'"), mapargs[i]);
820 ret = FALSE;
821 }
822 } else {
823 MAPIMG_LOG(_("unknown map option: '%s'"), mapargs[i]);
824 ret = FALSE;
825 }
826
827 free_tokens(mapopts, nmapopts);
828
829 if (!ret) {
830 break;
831 }
832 }
833 free_tokens(mapargs, nmapargs);
834
835 /* sanity check */
836 switch (pmapdef->player.show) {
837 case SHOW_PLRNAME: /* display player given by name */
838 if (!BV_ISSET(pmapdef->args, MAPDEF_PLRNAME)) {
839 MAPIMG_LOG(_("'show=%s' but no player name 'plrname'"),
840 show_player_name(SHOW_PLRNAME));
841 ret = FALSE;
842 }
843 break;
844 case SHOW_PLRID: /* display player given by id */
845 if (!BV_ISSET(pmapdef->args, MAPDEF_PLRID)) {
846 MAPIMG_LOG(_("'show=%s' but no player id 'plrid'"),
847 show_player_name(SHOW_PLRID));
848 ret = FALSE;
849 }
850 break;
851 case SHOW_PLRBV: /* display players given by bitvector */
852 if (!BV_ISSET(pmapdef->args, MAPDEF_PLRBV)) {
853 MAPIMG_LOG(_("'show=%s' but no player bitvector 'plrbv'"),
854 show_player_name(SHOW_PLRBV));
855 ret = FALSE;
856 }
857 break;
858 case SHOW_NONE: /* no player on the map */
860 break;
861 case SHOW_ALL: /* show all players in one map */
863 break;
864 case SHOW_EACH: /* one map for each player */
865 case SHOW_HUMAN: /* one map for each human player */
866 /* A loop for each player will be called at the time the image is
867 * created. */
869 break;
870 }
871
872 if (ret && !check) {
873 /* save map string */
875
876 /* add map definiton */
877 mapdef_list_append(mapimg.mapdef, pmapdef);
878 } else {
879 mapdef_destroy(pmapdef);
880 }
881
882 return ret;
883}
884#undef NUM_MAX_MAPARGS
885#undef NUM_MAX_MAPOPTS
886
887/************************************************************************/
890#define NUM_MAX_FORMATARGS 2
891static bool mapimg_define_arg(struct mapdef *pmapdef, enum mapdef_arg arg,
892 const char *val, bool check)
893{
894 if (BV_ISSET(pmapdef->args, arg)) {
895 log_debug("Option '%s' for mapimg used more than once.",
896 mapdef_arg_name(arg));
897 }
898
899 /* This argument was used. */
900 BV_SET(pmapdef->args, arg);
901
902 switch (arg) {
903 case MAPDEF_FORMAT:
904 /* file format */
905 {
906 char *formatargs[NUM_MAX_FORMATARGS];
907 int nformatargs;
908 enum imageformat format;
909 enum imagetool tool;
910 bool error = TRUE;
911
912 /* get format options */
913 nformatargs = get_tokens(val, formatargs, NUM_MAX_FORMATARGS, "|");
914
915 if (nformatargs == 2) {
916 tool = imagetool_by_name(formatargs[0], strcmp);
917 format = imageformat_by_name(formatargs[1], strcmp);
918
919 if (imageformat_is_valid(format) && imagetool_is_valid(tool)) {
920 const struct toolkit *toolkit = img_toolkit_get(tool);
921
922 if (toolkit && (toolkit->formats & format)) {
923 pmapdef->tool = tool;
924 pmapdef->format = format;
925
926 error = FALSE;
927 }
928 }
929 } else {
930 /* Only one argument to format. */
931 tool = imagetool_by_name(formatargs[0], strcmp);
932 if (imagetool_is_valid(tool)) {
933 /* toolkit defined */
934 const struct toolkit *toolkit = img_toolkit_get(tool);
935
936 if (toolkit) {
937 pmapdef->tool = toolkit->tool;
938 pmapdef->format = toolkit->format_default;
939
940 error = FALSE;
941 }
942 } else {
943 format = imageformat_by_name(formatargs[0], strcmp);
944 if (imageformat_is_valid(format)) {
945 /* format defined */
947 if ((toolkit->formats & format)) {
948 pmapdef->tool = toolkit->tool;
949 pmapdef->format = toolkit->format_default;
950
951 error = FALSE;
952 break;
953 }
955 }
956 }
957 }
958
959 free_tokens(formatargs, nformatargs);
960
961 if (error) {
962 goto INVALID;
963 }
964 }
965 break;
966
967 case MAPDEF_MAP:
968 /* map definition */
969 {
970 int len = strlen(val), l;
971 enum mapimg_layer layer;
972 bool error;
973
974 for (layer = mapimg_layer_begin(); layer != mapimg_layer_end();
975 layer = mapimg_layer_next(layer)) {
976 pmapdef->layers[layer] = FALSE;
977 }
978
979 for (l = 0; l < len; l++) {
980 error = TRUE;
981 for (layer = mapimg_layer_begin(); layer != mapimg_layer_end();
982 layer = mapimg_layer_next(layer)) {
983 if (val[l] == mapimg_layer_name(layer)[0]) {
984 pmapdef->layers[layer] = TRUE;
985 error = FALSE;
986 break;
987 }
988 }
989
990 if (error) {
991 goto INVALID;
992 }
993 }
994 }
995 break;
996
997 case MAPDEF_PLRBV:
998 /* player definition - bitvector */
999 {
1000 int i;
1001
1002 if (strlen(val) < MAX_NUM_PLAYER_SLOTS + 1) {
1003 BV_CLR_ALL(pmapdef->player.plrbv);
1004 for (i = 0; i < strlen(val); i++) {
1005 if (!strchr("01", val[i])) {
1006 MAPIMG_LOG(_("invalid character in bitvector: '%c' (%s)"),
1007 val[i], val);
1008 return FALSE;
1009 } else if (val[i] == '1') {
1010 BV_SET(pmapdef->player.plrbv, i);
1011 }
1012 }
1013 } else {
1014 goto INVALID;
1015 }
1016 }
1017 break;
1018
1019 case MAPDEF_PLRID:
1020 /* player definition - player id; will be checked by mapimg_isvalid()
1021 * which calls mapimg_checkplayers() */
1022 {
1023 int plrid;
1024
1025 if (sscanf(val, "%d", &plrid) != 0) {
1026 if (plrid < 0 || plrid >= MAX_NUM_PLAYER_SLOTS) {
1027 MAPIMG_LOG(_("'plrid' should be between 0 and %d"),
1029 return FALSE;
1030 }
1031 pmapdef->player.id = plrid;
1032 } else {
1033 goto INVALID;
1034 }
1035 }
1036 break;
1037
1038 case MAPDEF_PLRNAME:
1039 /* player definition - player name; will be checked by mapimg_isvalid()
1040 * which calls mapimg_checkplayers() */
1041 {
1042 if (strlen(val) > sizeof(pmapdef->player.name)) {
1043 MAPIMG_LOG(_("player name too long: '%s' (max: %lu)"), val,
1044 (unsigned long) sizeof(pmapdef->player.name));
1045 return FALSE;
1046 } else {
1047 sz_strlcpy(pmapdef->player.name, val);
1048 }
1049 }
1050 break;
1051
1052 case MAPDEF_SHOW:
1053 /* player definition - basic definition */
1054 {
1055 enum show_player showplr;
1056
1057 showplr = show_player_by_name(val, strcmp);
1058 if (show_player_is_valid(showplr)) {
1059 pmapdef->player.show = showplr;
1060 } else {
1061 goto INVALID;
1062 }
1063 }
1064 break;
1065
1066 case MAPDEF_TURNS:
1067 /* save each <x> turns */
1068 {
1069 int turns;
1070
1071 if (sscanf(val, "%d", &turns) != 0) {
1072 if (turns < 0 || turns > 99) {
1073 MAPIMG_LOG(_("'turns' should be between 0 and 99"));
1074 return FALSE;
1075 } else {
1076 pmapdef->turns = turns;
1077 }
1078 } else {
1079 goto INVALID;
1080 }
1081 }
1082 break;
1083
1084 case MAPDEF_ZOOM:
1085 /* zoom factor */
1086 {
1087 int zoom;
1088
1089 if (sscanf(val, "%d", &zoom) != 0) {
1090 if (zoom < 1 || zoom > 5) {
1091 MAPIMG_LOG(_("'zoom' factor should be between 1 and 5"));
1092 return FALSE;
1093 } else {
1094 pmapdef->zoom = zoom;
1095 }
1096 } else {
1097 goto INVALID;
1098 }
1099 }
1100 break;
1101
1102 case MAPDEF_COUNT:
1103 fc_assert_ret_val(arg != MAPDEF_COUNT, FALSE);
1104 break;
1105 }
1106
1107 return TRUE;
1108
1109 INVALID:
1110 MAPIMG_LOG(_("invalid value for option '%s': '%s'"),
1111 mapdef_arg_name(arg), val);
1112 return FALSE;
1113}
1114#undef NUM_MAX_FORMATARGS
1115
1116/************************************************************************/
1120struct mapdef *mapimg_isvalid(int id)
1121{
1122 struct mapdef *pmapdef = NULL;
1123
1124 if (!mapimg_test(id)) {
1125 /* The error message is set in mapimg_test(). */
1126 return NULL;
1127 }
1128
1129 pmapdef = mapdef_list_get(mapimg.mapdef, id);
1130 mapimg_checkplayers(pmapdef, TRUE);
1131
1132 switch (pmapdef->status) {
1133 case MAPIMG_STATUS_UNKNOWN:
1134 MAPIMG_LOG(_("map definition not checked (game not started)"));
1135 return NULL;
1136 break;
1137 case MAPIMG_STATUS_ERROR:
1138 MAPIMG_LOG(_("map definition deactivated: %s"), pmapdef->error);
1139 return NULL;
1140 break;
1141 case MAPIMG_STATUS_OK:
1142 /* nothing */
1143 break;
1144 }
1145
1146 return pmapdef;
1147}
1148
1149/************************************************************************/
1153{
1154 static struct strvec *format_list = NULL;
1155
1156 if (NULL == format_list) {
1157 enum imagetool tool;
1158
1159 format_list = strvec_new();
1160
1161 for (tool = imagetool_begin(); tool != imagetool_end();
1162 tool = imagetool_next(tool)) {
1163 enum imageformat format;
1164 const struct toolkit *toolkit = img_toolkit_get(tool);
1165
1166 if (!toolkit) {
1167 continue;
1168 }
1169
1170 for (format = imageformat_begin(); format != imageformat_end();
1171 format = imageformat_next(format)) {
1172 if (toolkit->formats & format) {
1173 char str_format[64];
1174
1175 fc_snprintf(str_format, sizeof(str_format), "%s|%s",
1176 imagetool_name(tool), imageformat_name(format));
1177 strvec_append(format_list, str_format);
1178 }
1179 }
1180 }
1181 }
1182
1183 return format_list;
1184}
1185
1186/************************************************************************/
1190{
1191 static char default_format[64];
1192
1193 fc_snprintf(default_format, sizeof(default_format), "%s|%s",
1194 imagetool_name(MAPIMG_DEFAULT_IMGTOOL),
1195 imageformat_name(MAPIMG_DEFAULT_IMGFORMAT));
1196
1197 return default_format;
1198}
1199
1200/************************************************************************/
1203bool mapimg_delete(int id)
1204{
1205 struct mapdef *pmapdef = NULL;
1206
1207 if (!mapimg_test(id)) {
1208 /* The error message is set in mapimg_test(). */
1209 return FALSE;
1210 }
1211
1212 /* delete map definition */
1213 pmapdef = mapdef_list_get(mapimg.mapdef, id);
1214 mapdef_list_remove(mapimg.mapdef, pmapdef);
1215
1216 return TRUE;
1217}
1218
1219/************************************************************************/
1222bool mapimg_show(int id, char *str, size_t str_len, bool detail)
1223{
1224 struct mapdef *pmapdef = NULL;
1225
1226 if (!mapimg_test(id)) {
1227 /* The error message is set in mapimg_test(). */
1228 return FALSE;
1229 }
1230
1231 pmapdef = mapdef_list_get(mapimg.mapdef, id);
1232
1233 /* Clear string ... */
1234 fc_assert_ret_val(str_len > 0, FALSE);
1235 str[0] = '\0';
1236
1237 if (detail) {
1238 cat_snprintf(str, str_len, _("Detailed information for map image "
1239 "definition %d\n"), id);
1240 if (pmapdef->status == MAPIMG_STATUS_ERROR) {
1241 cat_snprintf(str, str_len, _(" - status: %s (%s)\n"),
1242 mapimg_status_name(pmapdef->status), pmapdef->error);
1243 } else {
1244 cat_snprintf(str, str_len, _(" - status: %s\n"),
1245 mapimg_status_name(pmapdef->status));
1246 }
1247 cat_snprintf(str, str_len, _(" - file name string: %s\n"),
1248 mapimg_generate_name(pmapdef));
1249 cat_snprintf(str, str_len, _(" - image toolkit: %s\n"),
1250 imagetool_name(pmapdef->tool));
1251 cat_snprintf(str, str_len, _(" - image format: %s\n"),
1252 imageformat_name(pmapdef->format));
1253 cat_snprintf(str, str_len, _(" - zoom factor: %d\n"),
1254 pmapdef->zoom);
1255 cat_snprintf(str, str_len, _(" - show area within borders: %s\n"),
1256 pmapdef->layers[MAPIMG_LAYER_AREA] ? _("yes") : _("no"));
1257 cat_snprintf(str, str_len, _(" - show borders: %s\n"),
1258 pmapdef->layers[MAPIMG_LAYER_BORDERS] ? _("yes") : _("no"));
1259 cat_snprintf(str, str_len, _(" - show cities: %s\n"),
1260 pmapdef->layers[MAPIMG_LAYER_CITIES] ? _("yes") : _("no"));
1261 cat_snprintf(str, str_len, _(" - show fog of war: %s\n"),
1262 pmapdef->layers[MAPIMG_LAYER_FOGOFWAR] ? _("yes") : _("no"));
1263 cat_snprintf(str, str_len, _(" - show player knowledge: %s\n"),
1264 pmapdef->layers[MAPIMG_LAYER_KNOWLEDGE] ? _("yes") : _("no"));
1265 cat_snprintf(str, str_len, _(" - show terrain: %s\n"),
1266 pmapdef->layers[MAPIMG_LAYER_TERRAIN] ? _("full") :_("basic"));
1267 cat_snprintf(str, str_len, _(" - show units: %s\n"),
1268 pmapdef->layers[MAPIMG_LAYER_UNITS] ? _("yes") : _("no"));
1269 cat_snprintf(str, str_len, _(" - players included: %s"),
1270 show_player_name(pmapdef->player.show));
1271 switch (pmapdef->player.show) {
1272 case SHOW_NONE:
1273 case SHOW_HUMAN:
1274 case SHOW_EACH:
1275 case SHOW_ALL:
1276 /* nothing */
1277 break;
1278 case SHOW_PLRNAME:
1279 cat_snprintf(str, str_len, _("\n - player name: %s"),
1280 pmapdef->player.name);
1281 break;
1282 case SHOW_PLRID:
1283 cat_snprintf(str, str_len, _("\n - player id: %d"),
1284 pmapdef->player.id);
1285 break;
1286 case SHOW_PLRBV:
1287 cat_snprintf(str, str_len, _("\n - players: %s"),
1288 bvplayers_str(pmapdef->player.plrbv));
1289 break;
1290 }
1291 } else {
1292 char str_def[MAX_LEN_MAPDEF];
1293 mapimg_def2str(pmapdef, str_def, sizeof(str_def));
1294 if (pmapdef->status == MAPIMG_STATUS_ERROR) {
1295 cat_snprintf(str, str_len, "'%s' (%s: %s)", str_def,
1296 mapimg_status_name(pmapdef->status), pmapdef->error);
1297 } else {
1298 cat_snprintf(str, str_len, "'%s' (%s)", str_def,
1299 mapimg_status_name(pmapdef->status));
1300 }
1301 }
1302
1303 return TRUE;
1304}
1305
1306/************************************************************************/
1310bool mapimg_id2str(int id, char *str, size_t str_len)
1311{
1312 struct mapdef *pmapdef = NULL;
1313
1314 if (!mapimg_test(id)) {
1315 /* The error message is set in mapimg_test(). */
1316 return FALSE;
1317 }
1318
1319 pmapdef = mapdef_list_get(mapimg.mapdef, id);
1320
1321 return mapimg_def2str(pmapdef, str, str_len);
1322}
1323
1324/************************************************************************/
1331bool mapimg_create(struct mapdef *pmapdef, bool force, const char *savename,
1332 const char *path)
1333{
1334 struct img *pimg;
1335 char mapimgfile[MAX_LEN_PATH];
1336 bool ret = TRUE;
1337#ifdef FREECIV_DEBUG
1338 struct timer *timer_cpu, *timer_user;
1339#endif
1340
1341 if (map_is_empty()) {
1342 MAPIMG_LOG(_("map not yet created"));
1343
1344 return FALSE;
1345 }
1346
1347 mapimg_checkplayers(pmapdef, FALSE);
1348
1349 if (pmapdef->status != MAPIMG_STATUS_OK) {
1350 MAPIMG_LOG(_("map definition not checked or error"));
1351 return FALSE;
1352 }
1353
1354 /* An image should be saved if:
1355 * - force is set to TRUE
1356 * - it is the first turn
1357 * - turns is set to a value not zero and the current turn can be devided
1358 * by this number */
1359 if (!force && game.info.turn != 1
1360 && !(pmapdef->turns != 0 && game.info.turn % pmapdef->turns == 0)) {
1361 return TRUE;
1362 }
1363
1364#ifdef FREECIV_DEBUG
1365 timer_cpu = timer_new(TIMER_CPU, TIMER_ACTIVE);
1366 timer_start(timer_cpu);
1367 timer_user = timer_new(TIMER_USER, TIMER_ACTIVE);
1368 timer_start(timer_user);
1369#endif /* FREECIV_DEBUG */
1370
1371 /* create map */
1372 switch (pmapdef->player.show) {
1373 case SHOW_PLRNAME: /* display player given by name */
1374 case SHOW_PLRID: /* display player given by id */
1375 case SHOW_NONE: /* no player one the map */
1376 case SHOW_ALL: /* show all players in one map */
1377 case SHOW_PLRBV: /* display player(s) given by bitvector */
1378 generate_save_name(savename, mapimgfile, sizeof(mapimgfile),
1379 mapimg_generate_name(pmapdef));
1380
1381 pimg = img_new(pmapdef, CURRENT_TOPOLOGY, wld.map.xsize, wld.map.ysize);
1382 img_createmap(pimg);
1383 if (!img_save(pimg, mapimgfile, path)) {
1384 ret = FALSE;
1385 }
1386 img_destroy(pimg);
1387 break;
1388 case SHOW_EACH: /* one map for each player */
1389 case SHOW_HUMAN: /* one map for each human player */
1390 players_iterate(pplayer) {
1391 if (!pplayer->is_alive || (pmapdef->player.show == SHOW_HUMAN
1392 && !is_human(pplayer))) {
1393 /* no map image for dead players
1394 * or AI players if only human players should be shown */
1395 continue;
1396 }
1397
1399 BV_SET(pmapdef->player.checked_plrbv, player_index(pplayer));
1400
1401 generate_save_name(savename, mapimgfile, sizeof(mapimgfile),
1402 mapimg_generate_name(pmapdef));
1403
1404 pimg = img_new(pmapdef, CURRENT_TOPOLOGY, wld.map.xsize, wld.map.ysize);
1405 img_createmap(pimg);
1406 if (!img_save(pimg, mapimgfile, path)) {
1407 ret = FALSE;
1408 }
1409 img_destroy(pimg);
1410
1411 if (!ret) {
1412 break;
1413 }
1415 break;
1416 }
1417
1418#ifdef FREECIV_DEBUG
1419 log_debug("Image generation time: %g seconds (%g apparent)",
1420 timer_read_seconds(timer_cpu),
1421 timer_read_seconds(timer_user));
1422
1423 timer_destroy(timer_cpu);
1424 timer_destroy(timer_user);
1425#endif /* FREECIV_DEBUG */
1426
1427 return ret;
1428}
1429
1430/************************************************************************/
1435bool mapimg_colortest(const char *savename, const char *path)
1436{
1437 struct img *pimg;
1438 const struct rgbcolor *pcolor;
1439 struct mapdef *pmapdef = mapdef_new(TRUE);
1440 char mapimgfile[MAX_LEN_PATH];
1441 bv_pixel pixel;
1442 int i, nat_x, nat_y;
1443 int max_playercolor = mapimg.mapimg_plrcolor_count();
1444 int max_terraincolor = terrain_count();
1445 bool ret = TRUE;
1446 enum imagetool tool;
1447
1448#define SIZE_X 16
1449#define SIZE_Y 5
1450
1451 pimg = img_new(pmapdef, 0, SIZE_X + 2,
1452 SIZE_Y * (max_playercolor / SIZE_X) + 2);
1453
1454 pixel = pimg->pixel_tile(NULL, NULL, FALSE);
1455
1457 for (i = 0; i < MAX(max_playercolor, max_terraincolor); i++) {
1458 nat_x = 1 + i % SIZE_X;
1459 nat_y = 1 + (i / SIZE_X) * SIZE_Y;
1460
1461 img_plot(pimg, nat_x, nat_y, pcolor, pixel);
1462 }
1463
1464 for (i = 0; i < MAX(max_playercolor, max_terraincolor); i++) {
1465 if (i >= max_playercolor) {
1466 break;
1467 }
1468
1469 nat_x = 1 + i % SIZE_X;
1470 nat_y = 2 + (i / SIZE_X) * SIZE_Y;
1471 pcolor = mapimg.mapimg_plrcolor_get(i);
1472
1473 img_plot(pimg, nat_x, nat_y, pcolor, pixel);
1474 }
1475
1477 for (i = 0; i < MAX(max_playercolor, max_terraincolor); i++) {
1478 nat_x = 1 + i % SIZE_X;
1479 nat_y = 3 + (i / SIZE_X) * SIZE_Y;
1480
1481 img_plot(pimg, nat_x, nat_y, pcolor, pixel);
1482 }
1483
1484 for (i = 0; i < MAX(max_playercolor, max_terraincolor); i++) {
1485 if (i >= max_terraincolor) {
1486 break;
1487 }
1488
1489 nat_x = 1 + i % SIZE_X;
1490 nat_y = 4 + (i / SIZE_X) * SIZE_Y;
1492
1493 img_plot(pimg, nat_x, nat_y, pcolor, pixel);
1494 }
1495
1496#undef SIZE_X
1497#undef SIZE_Y
1498
1499 for (tool = imagetool_begin(); tool != imagetool_end();
1500 tool = imagetool_next(tool)) {
1501 enum imageformat format;
1502 const struct toolkit *toolkit = img_toolkit_get(tool);
1503
1504 if (!toolkit) {
1505 continue;
1506 }
1507
1508 /* Set the toolkit. */
1509 pmapdef->tool = tool;
1510
1511 for (format = imageformat_begin(); format != imageformat_end();
1512 format = imageformat_next(format)) {
1513 if (toolkit->formats & format) {
1514 char buf[128];
1515 const char *tname = imagetool_name(tool);
1516
1517 /* Set the image format. */
1518 pmapdef->format = format;
1519
1520 if (tname != NULL) {
1521 fc_snprintf(buf, sizeof(buf), "colortest-%s", tname);
1522 } else {
1523 fc_snprintf(buf, sizeof(buf), "colortest");
1524 }
1525 /* filename for color test */
1526 generate_save_name(savename, mapimgfile, sizeof(mapimgfile), buf);
1527
1528 if (!img_save(pimg, mapimgfile, path)) {
1529 /* If one of the mapimg format/toolkit combination fail, return
1530 * FALSE, i.e. an error occurred. */
1531 ret = FALSE;
1532 }
1533 }
1534 }
1535 }
1536
1537 img_destroy(pimg);
1538 mapdef_destroy(pmapdef);
1539
1540 return ret;
1541}
1542
1543/*
1544 * ==============================================
1545 * map images (internal functions)
1546 * ==============================================
1547 */
1548
1549/************************************************************************/
1553{
1554 return mapimg.init;
1555}
1556
1557/************************************************************************/
1561static bool mapimg_test(int id)
1562{
1564
1565 if (id < 0 || id >= mapimg_count()) {
1566 MAPIMG_LOG(_("no map definition with id %d"), id);
1567 return FALSE;
1568 }
1569
1570 return TRUE;
1571}
1572
1573/************************************************************************/
1576static bool mapimg_def2str(struct mapdef *pmapdef, char *str, size_t str_len)
1577{
1578 enum mapimg_layer layer;
1579 char buf[MAPIMG_LAYER_COUNT + 1];
1580 int i;
1581
1582 if (pmapdef->status != MAPIMG_STATUS_OK) {
1583 MAPIMG_LOG(_("map definition not checked or error"));
1584 fc_strlcpy(str, pmapdef->maparg, str_len);
1585 return FALSE;
1586 }
1587
1588 str[0] = '\0';
1589 cat_snprintf(str, str_len, "format=%s|%s:",
1590 imagetool_name(pmapdef->tool),
1591 imageformat_name(pmapdef->format));
1592 cat_snprintf(str, str_len, "turns=%d:", pmapdef->turns);
1593
1594 i = 0;
1595 for (layer = mapimg_layer_begin(); layer != mapimg_layer_end();
1596 layer = mapimg_layer_next(layer)) {
1597 if (pmapdef->layers[layer]) {
1598 buf[i++] = mapimg_layer_name(layer)[0];
1599 }
1600 }
1601 buf[i++] = '\0';
1602 cat_snprintf(str, str_len, "map=%s:", buf);
1603
1604 switch (pmapdef->player.show) {
1605 case SHOW_NONE:
1606 case SHOW_EACH:
1607 case SHOW_HUMAN:
1608 case SHOW_ALL:
1609 cat_snprintf(str, str_len, "show=%s:",
1610 show_player_name(pmapdef->player.show));
1611 break;
1612 case SHOW_PLRBV:
1613 cat_snprintf(str, str_len, "show=%s:", show_player_name(SHOW_PLRBV));
1614 cat_snprintf(str, str_len, "plrbv=%s:",
1615 bvplayers_str(pmapdef->player.plrbv));
1616 break;
1617 case SHOW_PLRNAME:
1618 cat_snprintf(str, str_len, "show=%s:", show_player_name(SHOW_PLRNAME));
1619 cat_snprintf(str, str_len, "plrname=%s:", pmapdef->player.name);
1620 break;
1621 case SHOW_PLRID:
1622 cat_snprintf(str, str_len, "show=%s:", show_player_name(SHOW_PLRID));
1623 cat_snprintf(str, str_len, "plrid=%d:", pmapdef->player.id);
1624 break;
1625 }
1626 cat_snprintf(str, str_len, "zoom=%d", pmapdef->zoom);
1627
1628 return TRUE;
1629}
1630
1631/************************************************************************/
1636static bool mapimg_checkplayers(struct mapdef *pmapdef, bool recheck)
1637{
1638 struct player *pplayer;
1639 enum m_pre_result result;
1640
1641 if (!recheck && pmapdef->status == MAPIMG_STATUS_ERROR) {
1642 return FALSE;
1643 }
1644
1645 /* game started - generate / check bitvector for players */
1646 switch (pmapdef->player.show) {
1647 case SHOW_NONE:
1648 /* nothing */
1649 break;
1650 case SHOW_PLRBV:
1651 pmapdef->player.checked_plrbv = pmapdef->player.plrbv;
1652 break;
1653 case SHOW_EACH:
1654 case SHOW_HUMAN:
1655 /* A map for each player will be created in a loop. */
1657 break;
1658 case SHOW_ALL:
1660 break;
1661 case SHOW_PLRNAME:
1662 /* display players as requested in the map definition */
1664 pplayer = player_by_name_prefix(pmapdef->player.name, &result);
1665
1666 if (pplayer != NULL) {
1667 BV_SET(pmapdef->player.checked_plrbv, player_index(pplayer));
1668 } else {
1669 pmapdef->status = MAPIMG_STATUS_ERROR;
1670 /* Save the error message in map definition. */
1671 fc_snprintf(pmapdef->error, sizeof(pmapdef->error),
1672 _("unknown player name: '%s'"), pmapdef->player.name);
1673 MAPIMG_LOG("%s", pmapdef->error);
1674 return FALSE;
1675 }
1676 break;
1677 case SHOW_PLRID:
1678 /* display players as requested in the map definition */
1680 pplayer = player_by_number(pmapdef->player.id);
1681
1682 if (pplayer != NULL) {
1683 BV_SET(pmapdef->player.checked_plrbv, player_index(pplayer));
1684 } else {
1685 pmapdef->status = MAPIMG_STATUS_ERROR;
1686 /* Save the error message in map definition. */
1687 fc_snprintf(pmapdef->error, sizeof(pmapdef->error),
1688 _("invalid player id: %d"), pmapdef->player.id);
1689 MAPIMG_LOG("%s", pmapdef->error);
1690 return FALSE;
1691 }
1692 break;
1693 }
1694
1695 pmapdef->status = MAPIMG_STATUS_OK;
1696
1697 return TRUE;
1698}
1699
1700/************************************************************************/
1704static void mapimg_log(const char *file, const char *function, int line,
1705 const char *format, ...)
1706{
1707 va_list args;
1708
1709 va_start(args, format);
1710 fc_vsnprintf(error_buffer, sizeof(error_buffer), format, args);
1711 va_end(args);
1712
1713#ifdef FREECIV_DEBUG
1714 log_debug("In %s() [%s:%d]: %s", function, file, line, error_buffer);
1715#endif
1716}
1717
1718/************************************************************************/
1731static char *mapimg_generate_name(struct mapdef *pmapdef)
1732{
1733 static char mapstr[256];
1734 char str_show[MAX_NUM_PLAYER_SLOTS + 1];
1735 enum mapimg_layer layer;
1736 int i, count = 0, plr_id = -1;
1737
1738 switch (pmapdef->player.show) {
1739 case SHOW_NONE:
1740 /* no player on the map */
1741 sz_strlcpy(str_show, "none");
1742 break;
1743 case SHOW_ALL:
1744 /* show all players in one map */
1745 sz_strlcpy(str_show, "all");
1746 break;
1747 case SHOW_PLRBV:
1748 case SHOW_PLRNAME:
1749 case SHOW_PLRID:
1750 case SHOW_HUMAN:
1751 case SHOW_EACH:
1752 /* one map for each selected player; iterate over all possible player ids
1753 * to generate unique strings even if civil wars occur */
1754 for (i = 0; i < MAX_NUM_PLAYER_SLOTS; i++) {
1755 str_show[i] = BV_ISSET(pmapdef->player.checked_plrbv, i) ? '1' : '0';
1756 if (BV_ISSET(pmapdef->player.checked_plrbv, i)) {
1757 count++;
1758 plr_id = i;
1759 }
1760 }
1761 str_show[MAX_NUM_PLAYER_SLOTS] = '\0';
1762
1763 /* Return the option name if no player is selected or the player id if
1764 * there is only one player selected. */
1765 if (count == 0) {
1766 fc_snprintf(str_show, sizeof(str_show), "---%s",
1767 show_player_name(pmapdef->player.show));
1768 } else if (count == 1 && plr_id != -1) {
1769 fc_snprintf(str_show, sizeof(str_show), "%03d%s", plr_id,
1770 show_player_name(pmapdef->player.show));
1771 }
1772 break;
1773 }
1774
1775 fc_snprintf(mapstr, sizeof(mapstr), "M");
1776 for (layer = mapimg_layer_begin(); layer != mapimg_layer_end();
1777 layer = mapimg_layer_next(layer)) {
1778 if (pmapdef->layers[layer]) {
1779 const char *lname = mapimg_layer_name(layer);
1780
1781 if (lname != NULL) {
1782 cat_snprintf(mapstr, sizeof(mapstr), "%s", lname);
1783 } else {
1784 cat_snprintf(mapstr, sizeof(mapstr), "-");
1785 }
1786 } else {
1787 cat_snprintf(mapstr, sizeof(mapstr), "-");
1788 }
1789 }
1790 cat_snprintf(mapstr, sizeof(mapstr), "Z%dP%s", pmapdef->zoom, str_show);
1791
1792 return mapstr;
1793}
1794
1795/*
1796 * ==============================================
1797 * map definitions (internal functions)
1798 * ==============================================
1799 */
1800
1801/************************************************************************/
1804static struct mapdef *mapdef_new(bool colortest)
1805{
1806 struct mapdef *pmapdef;
1807
1808 pmapdef = fc_malloc(sizeof(*pmapdef));
1809
1810 /* default values */
1811 pmapdef->maparg[0] = '\0';
1812 pmapdef->error[0] = '\0';
1813 pmapdef->status = MAPIMG_STATUS_UNKNOWN;
1815 pmapdef->tool = MAPIMG_DEFAULT_IMGTOOL;
1816 pmapdef->zoom = 2;
1817 pmapdef->turns = 1;
1818 pmapdef->layers[MAPIMG_LAYER_TERRAIN] = FALSE;
1819 pmapdef->layers[MAPIMG_LAYER_CITIES] = TRUE;
1820 pmapdef->layers[MAPIMG_LAYER_UNITS] = TRUE;
1821 pmapdef->layers[MAPIMG_LAYER_BORDERS] = TRUE;
1822 pmapdef->layers[MAPIMG_LAYER_FOGOFWAR] = FALSE;
1823 pmapdef->layers[MAPIMG_LAYER_KNOWLEDGE] = TRUE;
1824 pmapdef->layers[MAPIMG_LAYER_AREA] = FALSE;
1825 pmapdef->player.show = SHOW_ALL;
1826 /* The union is not set at this point (player.id, player.name and
1827 * player.plrbv). */
1829 BV_CLR_ALL(pmapdef->args);
1830 pmapdef->colortest = colortest;
1831
1832 return pmapdef;
1833}
1834
1835/************************************************************************/
1838static void mapdef_destroy(struct mapdef *pmapdef)
1839{
1840 if (pmapdef == NULL) {
1841 return;
1842 }
1843
1844 free(pmapdef);
1845}
1846
1847/*
1848 * ==============================================
1849 * images (internal functions)
1850 * ==============================================
1851 */
1852
1853/************************************************************************/
1856static const struct toolkit *img_toolkit_get(enum imagetool tool)
1857{
1859 if (toolkit->tool == tool) {
1860 return toolkit;
1861 }
1863
1864 return NULL;
1865}
1866
1867/************************************************************************/
1870static struct img *img_new(struct mapdef *mapdef, int topo, int xsize, int ysize)
1871{
1872 struct img *pimg;
1873
1874 pimg = fc_malloc(sizeof(*pimg));
1875
1876 pimg->def = mapdef;
1877 pimg->turn = game.info.turn;
1878 fc_snprintf(pimg->title, sizeof(pimg->title),
1879 _("Turn: %4d - Year: %10s"), game.info.turn,
1880 calendar_text());
1881
1882 pimg->mapsize.x = xsize; /* x size of the map */
1883 pimg->mapsize.y = ysize; /* y size of the map */
1884
1885 pimg->imgsize.x = 0; /* x size of the map image */
1886 pimg->imgsize.y = 0; /* y size of the map image */
1887
1888 if (topo_has_flag(topo, TF_HEX)) {
1889 /* additional space for hex maps */
1890 pimg->imgsize.x += TILE_SIZE / 2;
1891 pimg->imgsize.y += TILE_SIZE / 2;
1892
1893 if (topo_has_flag(topo, TF_ISO)) {
1894 /* iso-hex */
1895 pimg->imgsize.x += (pimg->mapsize.x + pimg->mapsize.y / 2)
1896 * TILE_SIZE;
1897 pimg->imgsize.y += (pimg->mapsize.x + pimg->mapsize.y / 2)
1898 * TILE_SIZE;
1899
1900 /* magic for isohexa: change size if wrapping in only one direction */
1901 if ((topo_has_flag(topo, TF_WRAPX) && !topo_has_flag(topo, TF_WRAPY))
1902 || (!topo_has_flag(topo, TF_WRAPX) && topo_has_flag(topo, TF_WRAPY))) {
1903 pimg->imgsize.y += (pimg->mapsize.x - pimg->mapsize.y / 2) / 2
1904 * TILE_SIZE;
1905 }
1906
1907 pimg->tileshape = &tile_isohexa;
1908
1914
1916 } else {
1917 /* hex */
1918 pimg->imgsize.x += pimg->mapsize.x * TILE_SIZE;
1919 pimg->imgsize.y += pimg->mapsize.y * TILE_SIZE;
1920
1921 pimg->tileshape = &tile_hexa;
1922
1928
1929 pimg->base_coor = base_coor_hexa;
1930 }
1931 } else {
1932 if (topo_has_flag(topo, TF_ISO)) {
1933 /* isometric rectangular */
1934 pimg->imgsize.x += (pimg->mapsize.x + pimg->mapsize.y / 2) * TILE_SIZE;
1935 pimg->imgsize.y += (pimg->mapsize.x + pimg->mapsize.y / 2) * TILE_SIZE;
1936 } else {
1937 /* rectangular */
1938 pimg->imgsize.x += pimg->mapsize.x * TILE_SIZE;
1939 pimg->imgsize.y += pimg->mapsize.y * TILE_SIZE;
1940 }
1941
1942 pimg->tileshape = &tile_rect;
1943
1949
1950 pimg->base_coor = base_coor_rect;
1951 }
1952
1953 /* Here the map image is saved as an array of RGB color values. */
1954 pimg->map = fc_calloc(pimg->imgsize.x * pimg->imgsize.y,
1955 sizeof(*pimg->map));
1956 /* Initialise map. */
1957 memset(pimg->map, 0, pimg->imgsize.x * pimg->imgsize.y);
1958
1959 return pimg;
1960}
1961
1962/************************************************************************/
1965static void img_destroy(struct img *pimg)
1966{
1967 if (pimg != NULL) {
1968 /* do not free pimg->def */
1969 free(pimg->map);
1970 free(pimg);
1971 }
1972}
1973
1974/************************************************************************/
1977static inline void img_set_pixel(struct img *pimg, const int mindex,
1978 const struct rgbcolor *pcolor)
1979{
1980 if (mindex < 0 || mindex > pimg->imgsize.x * pimg->imgsize.y) {
1981 log_error("invalid index: 0 <= %d < %d", mindex,
1982 pimg->imgsize.x * pimg->imgsize.y);
1983 return;
1984 }
1985
1986 pimg->map[mindex] = pcolor;
1987}
1988
1989/************************************************************************/
1992static inline int img_index(const int x, const int y,
1993 const struct img *pimg)
1994{
1995 fc_assert_ret_val(x >= 0 && x < pimg->imgsize.x, -1);
1996 fc_assert_ret_val(y >= 0 && y < pimg->imgsize.y, -1);
1997
1998 return pimg->imgsize.x * y + x;
1999}
2000
2001/************************************************************************/
2005static void img_plot(struct img *pimg, int x, int y,
2006 const struct rgbcolor *pcolor, const bv_pixel pixel)
2007{
2008 int base_x, base_y, i, mindex;
2009
2010 if (!BV_ISSET_ANY(pixel)) {
2011 return;
2012 }
2013
2014 pimg->base_coor(pimg, &base_x, &base_y, x, y);
2015
2016 for (i = 0; i < NUM_PIXEL; i++) {
2017 if (BV_ISSET(pixel, i)) {
2018 mindex = img_index(base_x + pimg->tileshape->x[i],
2019 base_y + pimg->tileshape->y[i], pimg);
2020 img_set_pixel(pimg, mindex, pcolor);
2021 }
2022 }
2023}
2024
2025/************************************************************************/
2028static void img_plot_tile(struct img *pimg, const struct tile *ptile,
2029 const struct rgbcolor *pcolor, const bv_pixel pixel)
2030{
2031 int x, y;
2032
2033 index_to_map_pos(&x, &y, tile_index(ptile));
2034
2035 img_plot(pimg, x, y, pcolor, pixel);
2036}
2037
2038/************************************************************************/
2041static bool img_save(const struct img *pimg, const char *mapimgfile,
2042 const char *path)
2043{
2044 enum imagetool tool = pimg->def->tool;
2045 const struct toolkit *toolkit = img_toolkit_get(tool);
2046 char tmpname[600];
2047
2048 if (!toolkit) {
2049 MAPIMG_LOG(_("toolkit not defined"));
2050 return FALSE;
2051 }
2052
2053 if (!path_is_absolute(mapimgfile) && path != NULL && path[0] != '\0') {
2054 if (!make_dir(path)) {
2055 MAPIMG_LOG(_("can't create directory"));
2056 return FALSE;
2057 }
2058
2059 sz_strlcpy(tmpname, path);
2060 sz_strlcat(tmpname, "/");
2061 } else {
2062 tmpname[0] = '\0';
2063 }
2064
2065 sz_strlcat(tmpname, mapimgfile);
2066
2068
2069 return toolkit->img_save(pimg, tmpname);
2070}
2071
2072/************************************************************************/
2095#ifdef HAVE_MAPIMG_MAGICKWAND
2096#define SET_COLOR(str, pcolor) \
2097 fc_snprintf(str, sizeof(str), "rgb(%d,%d,%d)", \
2098 pcolor->r, pcolor->g, pcolor->b);
2099static bool img_save_magickwand(const struct img *pimg,
2100 const char *mapimgfile)
2101{
2102 const struct rgbcolor *pcolor = NULL;
2103 struct player *pplr_now = NULL, *pplr_only = NULL;
2104 bool ret = TRUE;
2105 char imagefile[MAX_LEN_PATH];
2106 char str_color[32], comment[2048] = "", title[258];
2107 magickwand_size_t img_width, img_height, map_width, map_height;
2108 int x, y, xxx, yyy, row, i, mindex, plrwidth, plroffset, textoffset;
2109 bool withplr = BV_ISSET_ANY(pimg->def->player.checked_plrbv);
2110
2111 if (!img_filename(mapimgfile, pimg->def->format, imagefile,
2112 sizeof(imagefile))) {
2113 MAPIMG_LOG(_("error generating the file name"));
2114 return FALSE;
2115 }
2116
2117 MagickWand *mw;
2118 PixelIterator *imw;
2119 PixelWand **pmw, *pw;
2120 DrawingWand *dw;
2121
2122 MagickWandGenesis();
2123
2124 mw = NewMagickWand();
2125 dw = NewDrawingWand();
2126 pw = NewPixelWand();
2127
2128 map_width = pimg->imgsize.x * pimg->def->zoom;
2129 map_height = pimg->imgsize.y * pimg->def->zoom;
2130
2131 img_width = map_width + 2 * IMG_BORDER_WIDTH;
2132 img_height = map_height + 2 * IMG_BORDER_HEIGHT + IMG_TEXT_HEIGHT
2133 + IMG_SPACER_HEIGHT + (withplr ? 2 * IMG_SPACER_HEIGHT : 0);
2134
2135 fc_snprintf(title, sizeof(title), "%s (%s)", pimg->title, mapimgfile);
2136
2137 SET_COLOR(str_color, imgcolor_special(IMGCOLOR_BACKGROUND));
2138 PixelSetColor(pw, str_color);
2139 MagickNewImage(mw, img_width, img_height, pw);
2140
2141 textoffset = 0;
2142 if (withplr) {
2143 if (bvplayers_count(pimg->def) == 1) {
2144 /* only one player */
2145 for (i = 0; i < player_slot_count(); i++) {
2146 if (BV_ISSET(pimg->def->player.checked_plrbv, i)) {
2147 pplr_only = player_by_number(i);
2148 break;
2149 }
2150 }
2151 }
2152
2153 if (pplr_only) {
2154 magickwand_size_t plr_color_square = IMG_TEXT_HEIGHT;
2155
2156 textoffset += IMG_TEXT_HEIGHT + IMG_BORDER_HEIGHT;
2157
2158 pcolor = imgcolor_player(player_index(pplr_only));
2159 SET_COLOR(str_color, pcolor);
2160
2161 /* Show the color of the selected player. */
2162 imw = NewPixelRegionIterator(mw, IMG_BORDER_WIDTH, IMG_BORDER_HEIGHT,
2164 /* y coordinate */
2165 for (y = 0; y < IMG_TEXT_HEIGHT; y++) {
2166 pmw = PixelGetNextIteratorRow(imw, &plr_color_square);
2167 /* x coordinate */
2168 for (x = 0; x < IMG_TEXT_HEIGHT; x++) {
2169 PixelSetColor(pmw[x], str_color);
2170 }
2171 PixelSyncIterator(imw);
2172 }
2173 DestroyPixelIterator(imw);
2174 }
2175
2176 /* Show a line displaying the colors of alive players */
2177 plrwidth = map_width / MIN(map_width, player_count());
2178 plroffset = (map_width - MIN(map_width, plrwidth * player_count())) / 2;
2179
2180 imw = NewPixelRegionIterator(mw, IMG_BORDER_WIDTH,
2182 + IMG_SPACER_HEIGHT, map_width,
2184 /* y coordinate */
2185 for (y = 0; y < IMG_LINE_HEIGHT; y++) {
2186 pmw = PixelGetNextIteratorRow(imw, &map_width);
2187
2188 /* x coordinate */
2189 for (x = plroffset; x < map_width; x++) {
2190 i = (x - plroffset) / plrwidth;
2191 pplr_now = player_by_number(i);
2192
2193 if (i > player_count() || pplr_now == NULL || !pplr_now->is_alive) {
2194 continue;
2195 }
2196
2197 if (BV_ISSET(pimg->def->player.checked_plrbv, i)) {
2198 /* The selected player is alive - display it. */
2200 SET_COLOR(str_color, pcolor);
2201 PixelSetColor(pmw[x], str_color);
2202 } else if (pplr_only != NULL) {
2203 /* Display the state between pplr_only and pplr_now:
2204 * - if allied:
2205 * - show each second pixel
2206 * - if pplr_now does shares map with pplr_onlyus:
2207 * - show every other line of pixels
2208 * This results in the following patterns (# = color):
2209 * ###### # # # ######
2210 * # # # # # #
2211 * ###### # # # ######
2212 * # # # # # #
2213 * shared allied shared vision
2214 * vision + allied */
2215 if ((pplayers_allied(pplr_now, pplr_only) && (x + y) % 2 == 0)
2216 || (y % 2 == 0 && gives_shared_vision(pplr_now, pplr_only))) {
2218 SET_COLOR(str_color, pcolor);
2219 PixelSetColor(pmw[x], str_color);
2220 }
2221 }
2222 }
2223 PixelSyncIterator(imw);
2224 }
2225 DestroyPixelIterator(imw);
2226 }
2227
2228 /* Display the image name. */
2229 SET_COLOR(str_color, imgcolor_special(IMGCOLOR_TEXT));
2230 PixelSetColor(pw, str_color);
2231 DrawSetFillColor(dw, pw);
2232 DrawSetFont(dw, "Times-New-Roman");
2233 DrawSetFontSize(dw, IMG_TEXT_HEIGHT);
2234 DrawAnnotation(dw, IMG_BORDER_WIDTH + textoffset,
2236 (unsigned char *)title);
2237 MagickDrawImage(mw, dw);
2238
2239 /* Display the map. */
2240 imw = NewPixelRegionIterator(mw, IMG_BORDER_WIDTH,
2243 + (withplr ? (IMG_LINE_HEIGHT + IMG_SPACER_HEIGHT)
2244 : 0), map_width, map_height);
2245 /* y coordinate */
2246 for (y = 0; y < pimg->imgsize.y; y++) {
2247 /* zoom for y */
2248 for (yyy = 0; yyy < pimg->def->zoom; yyy++) {
2249
2250 pmw = PixelGetNextIteratorRow(imw, &map_width);
2251
2252 /* x coordinate */
2253 for (x = 0; x < pimg->imgsize.x; x++) {
2254 mindex = img_index(x, y, pimg);
2255 pcolor = pimg->map[mindex];
2256
2257 if (pcolor != NULL) {
2258 SET_COLOR(str_color, pcolor);
2259
2260 /* zoom for x */
2261 for (xxx = 0; xxx < pimg->def->zoom; xxx++) {
2262 row = x * pimg->def->zoom + xxx;
2263 PixelSetColor(pmw[row], str_color);
2264 }
2265 }
2266 }
2267 PixelSyncIterator(imw);
2268 }
2269 }
2270 DestroyPixelIterator(imw);
2271
2272 cat_snprintf(comment, sizeof(comment), "map definition: %s\n",
2273 pimg->def->maparg);
2274 if (BV_ISSET_ANY(pimg->def->player.checked_plrbv)) {
2275 players_iterate(pplayer) {
2276 if (!BV_ISSET(pimg->def->player.checked_plrbv, player_index(pplayer))) {
2277 continue;
2278 }
2279
2280 cat_snprintf(comment, sizeof(comment), "%s\n", img_playerstr(pplayer));
2282 }
2283 MagickCommentImage(mw, comment);
2284
2285 if (!MagickWriteImage(mw, imagefile)) {
2286 MAPIMG_LOG(_("error saving map image '%s'"), imagefile);
2287 ret = FALSE;
2288 } else {
2289 log_verbose("Map image saved as '%s'.", imagefile);
2290 }
2291
2292 DestroyDrawingWand(dw);
2293 DestroyPixelWand(pw);
2294 DestroyMagickWand(mw);
2295
2296 MagickWandTerminus();
2297
2298 return ret;
2299}
2300#undef SET_COLOR
2301#endif /* HAVE_MAPIMG_MAGICKWAND */
2302
2303/************************************************************************/
2306static bool img_save_ppm(const struct img *pimg, const char *mapimgfile)
2307{
2308 char ppmname[MAX_LEN_PATH];
2309 FILE *fp;
2310 int x, y, xxx, yyy, mindex;
2311 const struct rgbcolor *pcolor;
2312
2313 if (pimg->def->format != IMGFORMAT_PPM) {
2314 MAPIMG_LOG(_("the ppm toolkit can only create images in the ppm "
2315 "format"));
2316 return FALSE;
2317 }
2318
2319 if (!img_filename(mapimgfile, IMGFORMAT_PPM, ppmname, sizeof(ppmname))) {
2320 MAPIMG_LOG(_("error generating the file name"));
2321 return FALSE;
2322 }
2323
2324 fp = fc_fopen(ppmname, "w");
2325 if (!fp) {
2326 MAPIMG_LOG(_("could not open file: %s"), ppmname);
2327 return FALSE;
2328 }
2329
2330 fprintf(fp, "P3\n");
2331 fprintf(fp, "# version:2\n");
2332 fprintf(fp, "# map definition: %s\n", pimg->def->maparg);
2333
2334 if (pimg->def->colortest) {
2335 fprintf(fp, "# color test\n");
2336 } else if (BV_ISSET_ANY(pimg->def->player.checked_plrbv)) {
2337 players_iterate(pplayer) {
2338 if (!BV_ISSET(pimg->def->player.checked_plrbv, player_index(pplayer))) {
2339 continue;
2340 }
2341
2342 fprintf(fp, "# %s\n", img_playerstr(pplayer));
2344 } else {
2345 fprintf(fp, "# no players\n");
2346 }
2347
2348 fprintf(fp, "%d %d\n", pimg->imgsize.x * pimg->def->zoom,
2349 pimg->imgsize.y * pimg->def->zoom);
2350 fprintf(fp, "255\n");
2351
2352 /* y coordinate */
2353 for (y = 0; y < pimg->imgsize.y; y++) {
2354 /* zoom for y */
2355 for (yyy = 0; yyy < pimg->def->zoom; yyy++) {
2356 /* x coordinate */
2357 for (x = 0; x < pimg->imgsize.x; x++) {
2358 mindex = img_index(x, y, pimg);
2359 pcolor = pimg->map[mindex];
2360
2361 /* zoom for x */
2362 for (xxx = 0; xxx < pimg->def->zoom; xxx++) {
2363 if (pcolor == NULL) {
2365 }
2366 fprintf(fp, "%d %d %d\n", pcolor->r, pcolor->g, pcolor->b);
2367 }
2368 }
2369 }
2370 }
2371
2372 log_verbose("Map image saved as '%s'.", ppmname);
2373 fclose(fp);
2374
2375 return TRUE;
2376}
2377
2378/************************************************************************/
2381static bool img_filename(const char *mapimgfile, enum imageformat format,
2382 char *filename, size_t filename_len)
2383{
2384 fc_assert_ret_val(imageformat_is_valid(format) , FALSE);
2385
2386 fc_snprintf(filename, filename_len, "%s.map.%s", mapimgfile,
2387 imageformat_name(format));
2388
2389 return TRUE;
2390}
2391
2392/************************************************************************/
2395static const char *img_playerstr(const struct player *pplayer)
2396{
2397 static char buf[512];
2398 const struct rgbcolor *pcolor = imgcolor_player(player_index(pplayer));
2399
2400 fc_snprintf(buf, sizeof(buf),
2401 "playerno:%d:color:(%3d, %3d, %3d):name:\"%s\"",
2402 player_number(pplayer), pcolor->r, pcolor->g, pcolor->b,
2403 player_name(pplayer));
2404
2405 return buf;
2406}
2407
2408/************************************************************************/
2412static void img_createmap(struct img *pimg)
2413{
2414 const struct rgbcolor *pcolor;
2415 bv_pixel pixel;
2416 int player_id;
2417 struct player *pplayer = NULL;
2418 struct player *plr_tile = NULL, *plr_city = NULL, *plr_unit = NULL;
2419 enum known_type tile_knowledge = TILE_UNKNOWN;
2420 struct terrain *pterrain = NULL;
2421 bool plr_knowledge = pimg->def->layers[MAPIMG_LAYER_KNOWLEDGE];
2422
2423 whole_map_iterate(&(wld.map), ptile) {
2424 if (bvplayers_count(pimg->def) == 1) {
2425 /* only one player; get player id for 'known' and 'fogofwar' */
2426 players_iterate(aplayer) {
2427 if (BV_ISSET(pimg->def->player.checked_plrbv,
2428 player_index(aplayer))) {
2429 pplayer = aplayer;
2430 tile_knowledge = mapimg.mapimg_tile_known(ptile, pplayer,
2431 plr_knowledge);
2432 break;
2433 }
2435 }
2436
2437 /* known tiles */
2438 if (plr_knowledge && pplayer != NULL && tile_knowledge == TILE_UNKNOWN) {
2439 /* plot nothing iff tile is not known */
2440 continue;
2441 }
2442
2443 /* terrain */
2444 pterrain = mapimg.mapimg_tile_terrain(ptile, pplayer, plr_knowledge);
2445 if (pimg->def->layers[MAPIMG_LAYER_TERRAIN]) {
2446 /* full terrain */
2447 pixel = pimg->pixel_tile(ptile, pplayer, plr_knowledge);
2448 pcolor = imgcolor_terrain(pterrain);
2449 img_plot_tile(pimg, ptile, pcolor, pixel);
2450 } else {
2451 /* basic terrain */
2452 pixel = pimg->pixel_tile(ptile, pplayer, plr_knowledge);
2453 if (is_ocean(pterrain)) {
2454 img_plot_tile(pimg, ptile, imgcolor_special(IMGCOLOR_OCEAN), pixel);
2455 } else {
2456 img_plot_tile(pimg, ptile, imgcolor_special(IMGCOLOR_GROUND), pixel);
2457 }
2458 }
2459
2460 /* (land) area within borders and borders */
2461 plr_tile = mapimg.mapimg_tile_owner(ptile, pplayer, plr_knowledge);
2462 if (game.info.borders > 0 && NULL != plr_tile) {
2463 player_id = player_index(plr_tile);
2464 if (pimg->def->layers[MAPIMG_LAYER_AREA] && !is_ocean(pterrain)
2465 && BV_ISSET(pimg->def->player.checked_plrbv, player_id)) {
2466 /* the tile is land and inside the players borders */
2467 pixel = pimg->pixel_tile(ptile, pplayer, plr_knowledge);
2468 pcolor = imgcolor_player(player_id);
2469 img_plot_tile(pimg, ptile, pcolor, pixel);
2470 } else if (pimg->def->layers[MAPIMG_LAYER_BORDERS]
2471 && (BV_ISSET(pimg->def->player.checked_plrbv, player_id)
2472 || (plr_knowledge && pplayer != NULL))) {
2473 /* plot borders if player is selected or view range of the one
2474 * displayed player */
2475 pixel = pimg->pixel_border(ptile, pplayer, plr_knowledge);
2476 pcolor = imgcolor_player(player_id);
2477 img_plot_tile(pimg, ptile, pcolor, pixel);
2478 }
2479 }
2480
2481 /* cities and units */
2482 plr_city = mapimg.mapimg_tile_city(ptile, pplayer, plr_knowledge);
2483 plr_unit = mapimg.mapimg_tile_unit(ptile, pplayer, plr_knowledge);
2484 if (pimg->def->layers[MAPIMG_LAYER_CITIES] && plr_city) {
2485 player_id = player_index(plr_city);
2486 if (BV_ISSET(pimg->def->player.checked_plrbv, player_id)
2487 || (plr_knowledge && pplayer != NULL)) {
2488 /* plot cities if player is selected or view range of the one
2489 * displayed player */
2490 pixel = pimg->pixel_city(ptile, pplayer, plr_knowledge);
2491 pcolor = imgcolor_player(player_id);
2492 img_plot_tile(pimg, ptile, pcolor, pixel);
2493 }
2494 } else if (pimg->def->layers[MAPIMG_LAYER_UNITS] && plr_unit) {
2495 player_id = player_index(plr_unit);
2496 if (BV_ISSET(pimg->def->player.checked_plrbv, player_id)
2497 || (plr_knowledge && pplayer != NULL)) {
2498 /* plot units if player is selected or view range of the one
2499 * displayed player */
2500 pixel = pimg->pixel_unit(ptile, pplayer, plr_knowledge);
2501 pcolor = imgcolor_player(player_id);
2502 img_plot_tile(pimg, ptile, pcolor, pixel);
2503 }
2504 }
2505
2506 /* fogofwar; if only 1 player is plotted */
2507 if (game.info.fogofwar && pimg->def->layers[MAPIMG_LAYER_FOGOFWAR]
2508 && pplayer != NULL
2509 && tile_knowledge == TILE_KNOWN_UNSEEN) {
2510 pixel = pimg->pixel_fogofwar(ptile, pplayer, plr_knowledge);
2511 pcolor = NULL;
2512 img_plot_tile(pimg, ptile, pcolor, pixel);
2513 }
2515}
2516
2517/*
2518 * ==============================================
2519 * topology (internal functions)
2520 * ==============================================
2521 * With these functions the pixels corresponding to the different elements
2522 * (tile, city, unit) for each map topology are defined.
2523 *
2524 * The bv_pixel_fogofwar_*() functions are special as they defines where
2525 * the color should be removed.
2526 *
2527 * The functions for a rectangular and an isometric rectangular topology
2528 * are identical.
2529 */
2530
2531/************************************************************************/
2539static bv_pixel pixel_tile_rect(const struct tile *ptile,
2540 const struct player *pplayer,
2541 bool knowledge)
2542{
2543 bv_pixel pixel;
2544
2545 BV_SET_ALL(pixel);
2546
2547 return pixel;
2548}
2549
2550/************************************************************************/
2558static bv_pixel pixel_city_rect(const struct tile *ptile,
2559 const struct player *pplayer,
2560 bool knowledge)
2561{
2562 bv_pixel pixel;
2563
2564 BV_CLR_ALL(pixel);
2565 BV_SET(pixel, 7);
2566 BV_SET(pixel, 8);
2567 BV_SET(pixel, 9);
2568 BV_SET(pixel, 10);
2569 BV_SET(pixel, 13);
2570 BV_SET(pixel, 14);
2571 BV_SET(pixel, 15);
2572 BV_SET(pixel, 16);
2573 BV_SET(pixel, 19);
2574 BV_SET(pixel, 20);
2575 BV_SET(pixel, 21);
2576 BV_SET(pixel, 22);
2577 BV_SET(pixel, 21);
2578 BV_SET(pixel, 25);
2579 BV_SET(pixel, 26);
2580 BV_SET(pixel, 27);
2581 BV_SET(pixel, 28);
2582
2583 return pixel;
2584}
2585
2586/************************************************************************/
2594static bv_pixel pixel_unit_rect(const struct tile *ptile,
2595 const struct player *pplayer,
2596 bool knowledge)
2597{
2598 bv_pixel pixel;
2599
2600 BV_CLR_ALL(pixel);
2601 BV_SET(pixel, 14);
2602 BV_SET(pixel, 15);
2603 BV_SET(pixel, 20);
2604 BV_SET(pixel, 21);
2605
2606 return pixel;
2607}
2608
2609/************************************************************************/
2617static bv_pixel pixel_fogofwar_rect(const struct tile *ptile,
2618 const struct player *pplayer,
2619 bool knowledge)
2620{
2621 bv_pixel pixel;
2622
2623 BV_CLR_ALL(pixel);
2624
2625 BV_SET(pixel, 0);
2626 BV_SET(pixel, 2);
2627 BV_SET(pixel, 4);
2628 BV_SET(pixel, 7);
2629 BV_SET(pixel, 9);
2630 BV_SET(pixel, 11);
2631 BV_SET(pixel, 12);
2632 BV_SET(pixel, 14);
2633 BV_SET(pixel, 16);
2634 BV_SET(pixel, 19);
2635 BV_SET(pixel, 21);
2636 BV_SET(pixel, 23);
2637 BV_SET(pixel, 24);
2638 BV_SET(pixel, 26);
2639 BV_SET(pixel, 28);
2640 BV_SET(pixel, 31);
2641 BV_SET(pixel, 33);
2642 BV_SET(pixel, 35);
2643
2644 return pixel;
2645}
2646
2647/************************************************************************/
2659static bv_pixel pixel_border_rect(const struct tile *ptile,
2660 const struct player *pplayer,
2661 bool knowledge)
2662{
2663 bv_pixel pixel;
2664 struct tile *pnext;
2665 struct player *owner;
2666
2667 BV_CLR_ALL(pixel);
2668
2669 fc_assert_ret_val(ptile != NULL, pixel);
2670
2671 if (NULL == ptile) {
2672 /* no tile */
2673 return pixel;
2674 }
2675
2676 owner = mapimg.mapimg_tile_owner(ptile, pplayer, knowledge);
2677 if (NULL == owner) {
2678 /* no border */
2679 return pixel;
2680 }
2681
2682 pnext = mapstep(&(wld.map), ptile, DIR8_NORTH);
2683 if (!pnext || (mapimg.mapimg_tile_known(pnext, pplayer,
2684 knowledge) != TILE_UNKNOWN
2685 && mapimg.mapimg_tile_owner(pnext, pplayer,
2686 knowledge) != owner)) {
2687 BV_SET(pixel, 0);
2688 BV_SET(pixel, 1);
2689 BV_SET(pixel, 2);
2690 BV_SET(pixel, 3);
2691 BV_SET(pixel, 4);
2692 BV_SET(pixel, 5);
2693 }
2694
2695 pnext = mapstep(&(wld.map), ptile, DIR8_EAST);
2696 if (!pnext || (mapimg.mapimg_tile_known(pnext, pplayer,
2697 knowledge) != TILE_UNKNOWN
2698 && mapimg.mapimg_tile_owner(pnext, pplayer,
2699 knowledge) != owner)) {
2700 BV_SET(pixel, 5);
2701 BV_SET(pixel, 11);
2702 BV_SET(pixel, 17);
2703 BV_SET(pixel, 23);
2704 BV_SET(pixel, 29);
2705 BV_SET(pixel, 35);
2706 }
2707
2708 pnext = mapstep(&(wld.map), ptile, DIR8_SOUTH);
2709 if (!pnext || (mapimg.mapimg_tile_known(pnext, pplayer,
2710 knowledge) != TILE_UNKNOWN
2711 && mapimg.mapimg_tile_owner(pnext, pplayer,
2712 knowledge) != owner)) {
2713 BV_SET(pixel, 30);
2714 BV_SET(pixel, 31);
2715 BV_SET(pixel, 32);
2716 BV_SET(pixel, 33);
2717 BV_SET(pixel, 34);
2718 BV_SET(pixel, 35);
2719 }
2720
2721 pnext = mapstep(&(wld.map), ptile, DIR8_WEST);
2722 if (!pnext || (mapimg.mapimg_tile_known(pnext, pplayer,
2723 knowledge) != TILE_UNKNOWN
2724 && mapimg.mapimg_tile_owner(pnext, pplayer,
2725 knowledge) != owner)) {
2726 BV_SET(pixel, 0);
2727 BV_SET(pixel, 6);
2728 BV_SET(pixel, 12);
2729 BV_SET(pixel, 18);
2730 BV_SET(pixel, 24);
2731 BV_SET(pixel, 30);
2732 }
2733
2734 return pixel;
2735}
2736
2737/************************************************************************/
2740static void base_coor_rect(struct img *pimg, int *base_x, int *base_y,
2741 int x, int y)
2742{
2743 *base_x = x * TILE_SIZE;
2744 *base_y = y * TILE_SIZE;
2745}
2746
2747/************************************************************************/
2757static bv_pixel pixel_tile_hexa(const struct tile *ptile,
2758 const struct player *pplayer,
2759 bool knowledge)
2760{
2761 bv_pixel pixel;
2762
2763 BV_SET_ALL(pixel);
2764
2765 return pixel;
2766}
2767
2768/************************************************************************/
2778static bv_pixel pixel_city_hexa(const struct tile *ptile,
2779 const struct player *pplayer,
2780 bool knowledge)
2781{
2782 bv_pixel pixel;
2783
2784 BV_CLR_ALL(pixel);
2785 BV_SET(pixel, 3);
2786 BV_SET(pixel, 4);
2787 BV_SET(pixel, 7);
2788 BV_SET(pixel, 8);
2789 BV_SET(pixel, 9);
2790 BV_SET(pixel, 10);
2791 BV_SET(pixel, 13);
2792 BV_SET(pixel, 14);
2793 BV_SET(pixel, 15);
2794 BV_SET(pixel, 16);
2795 BV_SET(pixel, 19);
2796 BV_SET(pixel, 20);
2797 BV_SET(pixel, 21);
2798 BV_SET(pixel, 22);
2799 BV_SET(pixel, 25);
2800 BV_SET(pixel, 26);
2801 BV_SET(pixel, 27);
2802 BV_SET(pixel, 28);
2803 BV_SET(pixel, 31);
2804 BV_SET(pixel, 32);
2805
2806 return pixel;
2807}
2808
2809/************************************************************************/
2819static bv_pixel pixel_unit_hexa(const struct tile *ptile,
2820 const struct player *pplayer,
2821 bool knowledge)
2822{
2823 bv_pixel pixel;
2824
2825 BV_CLR_ALL(pixel);
2826 BV_SET(pixel, 14);
2827 BV_SET(pixel, 15);
2828 BV_SET(pixel, 20);
2829 BV_SET(pixel, 21);
2830
2831 return pixel;
2832}
2833
2834/************************************************************************/
2844static bv_pixel pixel_fogofwar_hexa(const struct tile *ptile,
2845 const struct player *pplayer,
2846 bool knowledge)
2847{
2848 bv_pixel pixel;
2849
2850 BV_CLR_ALL(pixel);
2851 BV_SET(pixel, 0);
2852 BV_SET(pixel, 3);
2853 BV_SET(pixel, 5);
2854 BV_SET(pixel, 7);
2855 BV_SET(pixel, 9);
2856 BV_SET(pixel, 11);
2857 BV_SET(pixel, 13);
2858 BV_SET(pixel, 15);
2859 BV_SET(pixel, 17);
2860 BV_SET(pixel, 18);
2861 BV_SET(pixel, 20);
2862 BV_SET(pixel, 22);
2863 BV_SET(pixel, 24);
2864 BV_SET(pixel, 26);
2865 BV_SET(pixel, 28);
2866 BV_SET(pixel, 30);
2867 BV_SET(pixel, 32);
2868 BV_SET(pixel, 35);
2869
2870 return pixel;
2871}
2872
2873/************************************************************************/
2883static bv_pixel pixel_border_hexa(const struct tile *ptile,
2884 const struct player *pplayer,
2885 bool knowledge)
2886{
2887 bv_pixel pixel;
2888 struct tile *pnext;
2889 struct player *owner;
2890
2891 BV_CLR_ALL(pixel);
2892
2893 fc_assert_ret_val(ptile != NULL, pixel);
2894
2895 if (NULL == ptile) {
2896 /* no tile */
2897 return pixel;
2898 }
2899
2900 owner = mapimg.mapimg_tile_owner(ptile, pplayer, knowledge);
2901 if (NULL == owner) {
2902 /* no border */
2903 return pixel;
2904 }
2905
2906 pnext = mapstep(&(wld.map), ptile, DIR8_WEST);
2907 if (!pnext || (mapimg.mapimg_tile_known(pnext, pplayer,
2908 knowledge) != TILE_UNKNOWN
2909 && mapimg.mapimg_tile_owner(pnext, pplayer,
2910 knowledge) != owner)) {
2911 BV_SET(pixel, 0);
2912 BV_SET(pixel, 2);
2913 BV_SET(pixel, 6);
2914 }
2915
2916 /* not used: DIR8_NORTHWEST */
2917
2918 pnext = mapstep(&(wld.map), ptile, DIR8_NORTH);
2919 if (!pnext || (mapimg.mapimg_tile_known(pnext, pplayer,
2920 knowledge) != TILE_UNKNOWN
2921 && mapimg.mapimg_tile_owner(pnext, pplayer,
2922 knowledge) != owner)) {
2923 BV_SET(pixel, 1);
2924 BV_SET(pixel, 5);
2925 BV_SET(pixel, 11);
2926 }
2927
2928 pnext = mapstep(&(wld.map), ptile, DIR8_NORTHEAST);
2929 if (!pnext || (mapimg.mapimg_tile_known(pnext, pplayer,
2930 knowledge) != TILE_UNKNOWN
2931 && mapimg.mapimg_tile_owner(pnext, pplayer,
2932 knowledge) != owner)) {
2933 BV_SET(pixel, 11);
2934 BV_SET(pixel, 17);
2935 BV_SET(pixel, 23);
2936 BV_SET(pixel, 29);
2937 }
2938
2939 pnext = mapstep(&(wld.map), ptile, DIR8_EAST);
2940 if (!pnext || (mapimg.mapimg_tile_known(pnext, pplayer,
2941 knowledge) != TILE_UNKNOWN
2942 && mapimg.mapimg_tile_owner(pnext, pplayer,
2943 knowledge) != owner)) {
2944 BV_SET(pixel, 29);
2945 BV_SET(pixel, 33);
2946 BV_SET(pixel, 35);
2947 }
2948
2949 /* not used. DIR8_SOUTHEAST */
2950
2951 pnext = mapstep(&(wld.map), ptile, DIR8_SOUTH);
2952 if (!pnext || (mapimg.mapimg_tile_known(pnext, pplayer,
2953 knowledge) != TILE_UNKNOWN
2954 && mapimg.mapimg_tile_owner(pnext, pplayer,
2955 knowledge) != owner)) {
2956 BV_SET(pixel, 24);
2957 BV_SET(pixel, 30);
2958 BV_SET(pixel, 34);
2959 }
2960
2961 pnext = mapstep(&(wld.map), ptile, DIR8_SOUTHWEST);
2962 if (!pnext || (mapimg.mapimg_tile_known(pnext, pplayer,
2963 knowledge) != TILE_UNKNOWN
2964 && mapimg.mapimg_tile_owner(pnext, pplayer,
2965 knowledge) != owner)) {
2966 BV_SET(pixel, 6);
2967 BV_SET(pixel, 12);
2968 BV_SET(pixel, 18);
2969 BV_SET(pixel, 24);
2970 }
2971
2972 return pixel;
2973}
2974
2975/************************************************************************/
2978static void base_coor_hexa(struct img *pimg, int *base_x, int *base_y,
2979 int x, int y)
2980{
2981 int nat_x, nat_y;
2982 MAP_TO_NATIVE_POS(&nat_x, &nat_y, x, y);
2983
2984 *base_x = nat_x * TILE_SIZE + ((nat_y % 2) ? TILE_SIZE / 2 : 0);
2985 *base_y = nat_y * TILE_SIZE;
2986}
2987
2988/************************************************************************/
2996static bv_pixel pixel_tile_isohexa(const struct tile *ptile,
2997 const struct player *pplayer,
2998 bool knowledge)
2999{
3000 bv_pixel pixel;
3001
3002 BV_SET_ALL(pixel);
3003
3004 return pixel;
3005}
3006
3007/************************************************************************/
3015static bv_pixel pixel_city_isohexa(const struct tile *ptile,
3016 const struct player *pplayer,
3017 bool knowledge)
3018{
3019 bv_pixel pixel;
3020
3021 BV_CLR_ALL(pixel);
3022 BV_SET(pixel, 5);
3023 BV_SET(pixel, 6);
3024 BV_SET(pixel, 7);
3025 BV_SET(pixel, 8);
3026 BV_SET(pixel, 11);
3027 BV_SET(pixel, 12);
3028 BV_SET(pixel, 13);
3029 BV_SET(pixel, 14);
3030 BV_SET(pixel, 15);
3031 BV_SET(pixel, 16);
3032 BV_SET(pixel, 19);
3033 BV_SET(pixel, 20);
3034 BV_SET(pixel, 21);
3035 BV_SET(pixel, 22);
3036 BV_SET(pixel, 23);
3037 BV_SET(pixel, 24);
3038 BV_SET(pixel, 27);
3039 BV_SET(pixel, 28);
3040 BV_SET(pixel, 29);
3041 BV_SET(pixel, 30);
3042
3043 return pixel;
3044}
3045
3046/************************************************************************/
3054static bv_pixel pixel_unit_isohexa(const struct tile *ptile,
3055 const struct player *pplayer,
3056 bool knowledge)
3057{
3058 bv_pixel pixel;
3059
3060 BV_CLR_ALL(pixel);
3061 BV_SET(pixel, 13);
3062 BV_SET(pixel, 14);
3063 BV_SET(pixel, 21);
3064 BV_SET(pixel, 22);
3065
3066 return pixel;
3067}
3068
3069/************************************************************************/
3077static bv_pixel pixel_fogofwar_isohexa(const struct tile *ptile,
3078 const struct player *pplayer,
3079 bool knowledge)
3080{
3081 bv_pixel pixel;
3082
3083 BV_CLR_ALL(pixel);
3084 BV_SET(pixel, 0);
3085 BV_SET(pixel, 1);
3086 BV_SET(pixel, 4);
3087 BV_SET(pixel, 7);
3088 BV_SET(pixel, 8);
3089 BV_SET(pixel, 12);
3090 BV_SET(pixel, 13);
3091 BV_SET(pixel, 16);
3092 BV_SET(pixel, 17);
3093 BV_SET(pixel, 18);
3094 BV_SET(pixel, 19);
3095 BV_SET(pixel, 22);
3096 BV_SET(pixel, 23);
3097 BV_SET(pixel, 27);
3098 BV_SET(pixel, 28);
3099 BV_SET(pixel, 31);
3100 BV_SET(pixel, 34);
3101 BV_SET(pixel, 35);
3102
3103 return pixel;
3104}
3105
3106/************************************************************************/
3119static bv_pixel pixel_border_isohexa(const struct tile *ptile,
3120 const struct player *pplayer,
3121 bool knowledge)
3122{
3123 bv_pixel pixel;
3124 struct tile *pnext;
3125 struct player *owner;
3126
3127 BV_CLR_ALL(pixel);
3128
3129 fc_assert_ret_val(ptile != NULL, pixel);
3130
3131 if (NULL == ptile) {
3132 /* no tile */
3133 return pixel;
3134 }
3135
3136 owner = mapimg.mapimg_tile_owner(ptile, pplayer, knowledge);
3137 if (NULL == owner) {
3138 /* no border */
3139 return pixel;
3140 }
3141
3142 pnext = mapstep(&(wld.map), ptile, DIR8_NORTH);
3143 if (!pnext || (mapimg.mapimg_tile_known(pnext, pplayer,
3144 knowledge) != TILE_UNKNOWN
3145 && mapimg.mapimg_tile_owner(pnext, pplayer,
3146 knowledge) != owner)) {
3147 BV_SET(pixel, 0);
3148 BV_SET(pixel, 1);
3149 BV_SET(pixel, 2);
3150 BV_SET(pixel, 3);
3151 }
3152
3153 /* not used: DIR8_NORTHEAST */
3154
3155 pnext = mapstep(&(wld.map), ptile, DIR8_EAST);
3156 if (!pnext || (mapimg.mapimg_tile_known(pnext, pplayer,
3157 knowledge) != TILE_UNKNOWN
3158 && mapimg.mapimg_tile_owner(pnext, pplayer,
3159 knowledge) != owner)) {
3160 BV_SET(pixel, 3);
3161 BV_SET(pixel, 9);
3162 BV_SET(pixel, 17);
3163 }
3164
3165 pnext = mapstep(&(wld.map), ptile, DIR8_SOUTHEAST);
3166 if (!pnext || (mapimg.mapimg_tile_known(pnext, pplayer,
3167 knowledge) != TILE_UNKNOWN
3168 && mapimg.mapimg_tile_owner(pnext, pplayer,
3169 knowledge) != owner)) {
3170 BV_SET(pixel, 25);
3171 BV_SET(pixel, 31);
3172 BV_SET(pixel, 35);
3173 }
3174
3175 pnext = mapstep(&(wld.map), ptile, DIR8_SOUTH);
3176 if (!pnext || (mapimg.mapimg_tile_known(pnext, pplayer,
3177 knowledge) != TILE_UNKNOWN
3178 && mapimg.mapimg_tile_owner(pnext, pplayer,
3179 knowledge) != owner)) {
3180 BV_SET(pixel, 32);
3181 BV_SET(pixel, 33);
3182 BV_SET(pixel, 34);
3183 BV_SET(pixel, 35);
3184 }
3185
3186 /* not used: DIR8_SOUTHWEST */
3187
3188 pnext = mapstep(&(wld.map), ptile, DIR8_WEST);
3189 if (!pnext || (mapimg.mapimg_tile_known(pnext, pplayer,
3190 knowledge) != TILE_UNKNOWN
3191 && mapimg.mapimg_tile_owner(pnext, pplayer,
3192 knowledge) != owner)) {
3193 BV_SET(pixel, 18);
3194 BV_SET(pixel, 26);
3195 BV_SET(pixel, 32);
3196 }
3197
3198 pnext = mapstep(&(wld.map), ptile, DIR8_NORTHWEST);
3199 if (!pnext || (mapimg.mapimg_tile_known(pnext, pplayer,
3200 knowledge) != TILE_UNKNOWN
3201 && mapimg.mapimg_tile_owner(pnext, pplayer,
3202 knowledge) != owner)) {
3203 BV_SET(pixel, 0);
3204 BV_SET(pixel, 4);
3205 BV_SET(pixel, 10);
3206 }
3207
3208 return pixel;
3209}
3210
3211/************************************************************************/
3214static void base_coor_isohexa(struct img *pimg, int *base_x, int *base_y,
3215 int x, int y)
3216{
3217 /* magic for iso-hexa */
3218 y -= x / 2;
3219 y += (pimg->mapsize.x - 1)/2;
3220
3221 *base_x = x * TILE_SIZE;
3222 *base_y = y * TILE_SIZE + ((x % 2) ? 0 : TILE_SIZE / 2);
3223}
3224
3225/*
3226 * ==============================================
3227 * additional functions (internal functions)
3228 * ==============================================
3229 */
3230
3231/************************************************************************/
3234static const char *bvplayers_str(const bv_player plrbv)
3235{
3236 static char buf[MAX_NUM_PLAYER_SLOTS + 1];
3237 int i;
3238
3239 /* Don't print lots of unnecessary trailing zeroes */
3240 for (i = MAX_NUM_PLAYER_SLOTS-1; i >= 0; i--) {
3241 if (BV_ISSET(plrbv, i) || player_by_number(i)) {
3242 buf[i+1] = '\0';
3243 break;
3244 }
3245 }
3246
3247 for (; i >= 0; i--) {
3248 buf[i] = BV_ISSET(plrbv, i) ? '1' : '0';
3249 }
3250
3251 return buf;
3252}
3253
3254/************************************************************************/
3257static int bvplayers_count(const struct mapdef *pmapdef)
3258{
3259 int i, count = 0;
3260
3261 switch (pmapdef->player.show) {
3262 case SHOW_NONE: /* no player on the map */
3263 count = 0;
3264 break;
3265 case SHOW_HUMAN: /* one map for each human player */
3266 case SHOW_EACH: /* one map for each player */
3267 case SHOW_PLRNAME: /* the map of one selected player */
3268 case SHOW_PLRID:
3269 count = 1;
3270 break;
3271 case SHOW_PLRBV: /* map showing only players given by a bitvector */
3272 count = 0;
3273 for (i = 0; i < MAX_NUM_PLAYER_SLOTS; i++) {
3274 if (BV_ISSET(pmapdef->player.plrbv, i)) {
3275 count++;
3276 }
3277 }
3278 break;
3279 case SHOW_ALL: /* show all players in one map */
3280 count = player_count();
3281 break;
3282 }
3283
3284 return count;
3285}
3286
3287/*
3288 * ==============================================
3289 * image colors (internal functions)
3290 * ==============================================
3291 */
3292
3293/************************************************************************/
3296static const struct rgbcolor *imgcolor_special(enum img_special imgcolor)
3297{
3298 static struct rgbcolor rgb_special[] = {
3299 { 255, 0, 0, NULL}, /* IMGCOLOR_ERROR */
3300 /* FIXME: 'ocean' and 'ground' colors are also used in the overview; the
3301 * values are defined in colors.tilespec. */
3302 { 0, 0, 200, NULL}, /* IMGCOLOR_OCEAN */
3303 { 0, 200, 0, NULL}, /* IMGCOLOR_GROUND */
3304 { 0, 0, 0, NULL}, /* IMGCOLOR_BACKGROUND */
3305 { 255, 255, 255, NULL}, /* IMGCOLOR_TEXT */
3306 };
3307
3308 fc_assert_ret_val(imgcolor >= 0 && imgcolor < ARRAY_SIZE(rgb_special),
3309 &rgb_special[0]);
3310
3311 return &rgb_special[imgcolor];
3312}
3313
3314/************************************************************************/
3319static const struct rgbcolor *imgcolor_player(int plr_id)
3320{
3321 struct player *pplayer = player_by_number(plr_id);
3322
3324 fc_assert_ret_val(pplayer->rgb != NULL,
3326
3327 return pplayer->rgb;
3328}
3329
3330/************************************************************************/
3335static const struct rgbcolor
3336 *imgcolor_terrain(const struct terrain *pterrain)
3337{
3340
3341 return pterrain->rgb;
3342}
void astr_free(struct astring *astr)
Definition astring.c:153
void astr_set(struct astring *astr, const char *format,...)
Definition astring.c:267
void astr_init(struct astring *astr)
Definition astring.c:144
void astr_add(struct astring *astr, const char *format,...)
Definition astring.c:287
#define str
Definition astring.c:76
static size_t astr_len(const struct astring *astr) fc__attribute((nonnull(1)))
Definition astring.h:101
static const char * astr_str(const struct astring *astr) fc__attribute((nonnull(1)))
Definition astring.h:93
#define ASTRING_INIT
Definition astring.h:44
#define BV_SET_ALL(bv)
Definition bitvector.h:99
#define BV_DEFINE(name, bits)
Definition bitvector.h:132
#define BV_CLR_ALL(bv)
Definition bitvector.h:95
#define BV_SET(bv, bit)
Definition bitvector.h:81
#define BV_ISSET(bv, bit)
Definition bitvector.h:78
#define BV_ISSET_ANY(vec)
Definition bitvector.h:109
const char * calendar_text(void)
Definition calendar.c:141
struct canvas int int struct sprite bool int int fog_y struct canvas struct sprite struct color * pcolor
Definition canvas_g.h:57
void free_tokens(char **tokens, size_t ntokens)
Definition fc_cmdline.c:203
int get_tokens(const char *str, char **tokens, size_t num_tokens, const char *delimiterset)
Definition fc_cmdline.c:166
#define MAX_NUM_PLAYER_SLOTS
Definition fc_types.h:32
#define MAX_LEN_NAME
Definition fc_types.h:66
#define _(String)
Definition fcintl.h:67
#define N_(String)
Definition fcintl.h:69
struct civ_game game
Definition game.c:57
struct world wld
Definition game.c:58
int generate_save_name(const char *format, char *buf, int buflen, const char *reason)
Definition game.c:771
struct city * owner
Definition citydlg.c:219
const char * title
Definition repodlgs.c:1313
const char * name
Definition inputfile.c:127
#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_debug(message,...)
Definition log.h:115
#define log_error(message,...)
Definition log.h:103
#define nat_x
#define nat_y
struct tile * mapstep(const struct civ_map *nmap, const struct tile *ptile, enum direction8 dir)
Definition map.c:369
bool map_is_empty(void)
Definition map.c:149
#define CURRENT_TOPOLOGY
Definition map.h:42
#define topo_has_flag(topo, flag)
Definition map.h:44
#define MAP_TO_NATIVE_POS(pnat_x, pnat_y, map_x, map_y)
Definition map.h:166
#define whole_map_iterate(_map, _tile)
Definition map.h:539
#define whole_map_iterate_end
Definition map.h:548
#define index_to_map_pos(pmap_x, pmap_y, mindex)
Definition map.h:227
static bv_pixel pixel_fogofwar_hexa(const struct tile *ptile, const struct player *pplayer, bool knowledge)
Definition mapimg.c:2844
#define NUM_PIXEL
Definition mapimg.c:89
static int bvplayers_count(const struct mapdef *pmapdef)
Definition mapimg.c:3257
static bv_pixel pixel_fogofwar_rect(const struct tile *ptile, const struct player *pplayer, bool knowledge)
Definition mapimg.c:2617
#define MAPIMG_DEFAULT_IMGFORMAT
Definition mapimg.c:447
static char error_buffer[MAX_LEN_ERRORBUF]
Definition mapimg.c:466
#define NUM_MAX_MAPARGS
Definition mapimg.c:766
bool mapimg_id2str(int id, char *str, size_t str_len)
Definition mapimg.c:1310
#define SIZE_X
void mapimg_free(void)
Definition mapimg.c:557
#define MAX_LEN_ERRORBUF
Definition mapimg.c:464
#define IMG_TEXT_HEIGHT
Definition mapimg.c:365
mapimg_tile_player_func mapimg_tile_owner
Definition mapimg.c:487
static bool mapimg_test(int id)
Definition mapimg.c:1561
static struct @44 mapimg
bool(* img_save_func)(const struct img *pimg, const char *mapimgfile)
Definition mapimg.c:415
const char * mapimg_get_format_default(void)
Definition mapimg.c:1189
bool mapimg_initialised(void)
Definition mapimg.c:1552
static bool mapimg_def2str(struct mapdef *pmapdef, char *str, size_t str_len)
Definition mapimg.c:1576
static void base_coor_hexa(struct img *pimg, int *base_x, int *base_y, int x, int y)
Definition mapimg.c:2978
bool mapimg_colortest(const char *savename, const char *path)
Definition mapimg.c:1435
#define img_toolkit_iterate(_toolkit)
Definition mapimg.c:453
#define magickwand_size_t
Definition mapimg.c:70
static bv_pixel pixel_city_rect(const struct tile *ptile, const struct player *pplayer, bool knowledge)
Definition mapimg.c:2558
struct mapdef * mapimg_isvalid(int id)
Definition mapimg.c:1120
static bv_pixel pixel_border_hexa(const struct tile *ptile, const struct player *pplayer, bool knowledge)
Definition mapimg.c:2883
mapimg_tile_terrain_func mapimg_tile_terrain
Definition mapimg.c:486
bool init
Definition mapimg.c:482
mapimg_tile_player_func mapimg_tile_city
Definition mapimg.c:488
static struct mapdef * mapdef_new(bool colortest)
Definition mapimg.c:1804
static bool img_save_ppm(const struct img *pimg, const char *mapimgfile)
Definition mapimg.c:2306
static void img_destroy(struct img *pimg)
Definition mapimg.c:1965
#define IMG_BORDER_HEIGHT
Definition mapimg.c:361
#define IMG_SPACER_HEIGHT
Definition mapimg.c:363
static struct img * img_new(struct mapdef *mapdef, int topo, int xsize, int ysize)
Definition mapimg.c:1870
bv_pixel(* plot_func)(const struct tile *ptile, const struct player *pplayer, bool knowledge)
Definition mapimg.c:100
mapimg_tile_player_func mapimg_tile_unit
Definition mapimg.c:489
#define TILE_SIZE
Definition mapimg.c:88
static void img_plot(struct img *pimg, int x, int y, const struct rgbcolor *pcolor, const bv_pixel pixel)
Definition mapimg.c:2005
static bool img_filename(const char *mapimgfile, enum imageformat format, char *filename, size_t filename_len)
Definition mapimg.c:2381
static const struct rgbcolor * imgcolor_terrain(const struct terrain *pterrain)
Definition mapimg.c:3336
static void img_createmap(struct img *pimg)
Definition mapimg.c:2412
static const char * showname_help(enum show_player showplr)
Definition mapimg.c:584
static void mapimg_log(const char *file, const char *function, int line, const char *format,...) fc__attribute((__format__(__printf__
Definition mapimg.c:1704
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)
Definition mapimg.c:505
static bv_pixel pixel_border_rect(const struct tile *ptile, const struct player *pplayer, bool knowledge)
Definition mapimg.c:2659
#define mapdef_list_iterate_end
Definition mapimg.c:354
static int img_index(const int x, const int y, const struct img *pimg)
Definition mapimg.c:1992
static struct tile_shape tile_rect
Definition mapimg.c:107
#define MAX_NUM_MAPIMG
Definition mapimg.c:310
const struct strvec * mapimg_get_format_list(void)
Definition mapimg.c:1152
mapimg_tile_known_func mapimg_tile_known
Definition mapimg.c:485
static bool img_save(const struct img *pimg, const char *mapimgfile, const char *path)
Definition mapimg.c:2041
static bv_pixel pixel_city_hexa(const struct tile *ptile, const struct player *pplayer, bool knowledge)
Definition mapimg.c:2778
static bv_pixel pixel_fogofwar_isohexa(const struct tile *ptile, const struct player *pplayer, bool knowledge)
Definition mapimg.c:3077
void(* base_coor_func)(struct img *pimg, int *base_x, int *base_y, int x, int y)
Definition mapimg.c:103
#define img_toolkit_iterate_end
Definition mapimg.c:459
mapimg_plrcolor_get_func mapimg_plrcolor_get
Definition mapimg.c:491
static bv_pixel pixel_tile_isohexa(const struct tile *ptile, const struct player *pplayer, bool knowledge)
Definition mapimg.c:2996
mapimg_plrcolor_count_func mapimg_plrcolor_count
Definition mapimg.c:490
bool mapimg_define(const char *maparg, bool check)
Definition mapimg.c:768
bool mapimg_delete(int id)
Definition mapimg.c:1203
static const struct rgbcolor * imgcolor_player(int plr_id)
Definition mapimg.c:3319
#define MAPIMG_DEFAULT_IMGTOOL
Definition mapimg.c:448
int mapimg_count(void)
Definition mapimg.c:572
#define SIZE_Y
#define MAPIMG_LOG(format,...)
Definition mapimg.c:470
#define NUM_MAX_MAPOPTS
Definition mapimg.c:767
#define IMG_BORDER_WIDTH
Definition mapimg.c:362
static bv_pixel pixel_tile_hexa(const struct tile *ptile, const struct player *pplayer, bool knowledge)
Definition mapimg.c:2757
static bv_pixel pixel_city_isohexa(const struct tile *ptile, const struct player *pplayer, bool knowledge)
Definition mapimg.c:3015
img_special
Definition mapimg.c:74
@ IMGCOLOR_OCEAN
Definition mapimg.c:76
@ IMGCOLOR_BACKGROUND
Definition mapimg.c:78
@ IMGCOLOR_TEXT
Definition mapimg.c:79
@ IMGCOLOR_GROUND
Definition mapimg.c:77
@ IMGCOLOR_ERROR
Definition mapimg.c:75
static void base_coor_rect(struct img *pimg, int *base_x, int *base_y, int x, int y)
Definition mapimg.c:2740
static struct tile_shape tile_hexa
Definition mapimg.c:145
#define MAPIMG_ASSERT_RET_VAL(cond, expr)
Definition mapimg.c:472
static char * mapimg_generate_name(struct mapdef *pmapdef)
Definition mapimg.c:1731
static bv_pixel pixel_unit_rect(const struct tile *ptile, const struct player *pplayer, bool knowledge)
Definition mapimg.c:2594
static bv_pixel pixel_unit_hexa(const struct tile *ptile, const struct player *pplayer, bool knowledge)
Definition mapimg.c:2819
static void img_plot_tile(struct img *pimg, const struct tile *ptile, const struct rgbcolor *pcolor, const bv_pixel pixel)
Definition mapimg.c:2028
static void base_coor_isohexa(struct img *pimg, int *base_x, int *base_y, int x, int y)
Definition mapimg.c:3214
static const int img_toolkits_count
Definition mapimg.c:441
static void mapdef_destroy(struct mapdef *pmapdef)
Definition mapimg.c:1838
bool mapimg_create(struct mapdef *pmapdef, bool force, const char *savename, const char *path)
Definition mapimg.c:1331
#define IMG_LINE_HEIGHT
Definition mapimg.c:364
static const struct rgbcolor * imgcolor_special(enum img_special imgcolor)
Definition mapimg.c:3296
static bv_pixel pixel_border_isohexa(const struct tile *ptile, const struct player *pplayer, bool knowledge)
Definition mapimg.c:3119
#define mapdef_list_iterate(mapdef_list, pmapdef)
Definition mapimg.c:352
#define MAX_LEN_MAPARG
Definition mapimg.c:309
const char * mapimg_error(void)
Definition mapimg.c:758
#define GEN_TOOLKIT(_tool, _format_default, _formats, _save_func, _help)
Definition mapimg.c:426
static const char * img_playerstr(const struct player *pplayer)
Definition mapimg.c:2395
static struct tile_shape tile_isohexa
Definition mapimg.c:187
void mapimg_reset(void)
Definition mapimg.c:540
bool mapimg_show(int id, char *str, size_t str_len, bool detail)
Definition mapimg.c:1222
static bool mapimg_define_arg(struct mapdef *pmapdef, enum mapdef_arg arg, const char *val, bool check)
Definition mapimg.c:891
static bool mapimg_checkplayers(struct mapdef *pmapdef, bool recheck)
Definition mapimg.c:1636
static const struct toolkit * img_toolkit_get(enum imagetool tool)
Definition mapimg.c:1856
static bv_pixel pixel_unit_isohexa(const struct tile *ptile, const struct player *pplayer, bool knowledge)
Definition mapimg.c:3054
static void img_set_pixel(struct img *pimg, const int mindex, const struct rgbcolor *pcolor)
Definition mapimg.c:1977
static bv_pixel pixel_tile_rect(const struct tile *ptile, const struct player *pplayer, bool knowledge)
Definition mapimg.c:2539
static struct toolkit img_toolkits[]
Definition mapimg.c:429
#define NUM_MAX_FORMATARGS
Definition mapimg.c:890
char * mapimg_help(const char *cmdname)
Definition mapimg.c:602
static const char * bvplayers_str(const bv_player plrbv)
Definition mapimg.c:3234
#define MAX_LEN_MAPDEF
Definition mapimg.h:65
struct rgbcolor *(* mapimg_plrcolor_get_func)(int)
Definition mapimg.h:104
int(* mapimg_plrcolor_count_func)(void)
Definition mapimg.h:103
enum known_type(* mapimg_tile_known_func)(const struct tile *ptile, const struct player *pplayer, bool knowledge)
Definition mapimg.h:91
struct terrain *(* mapimg_tile_terrain_func)(const struct tile *ptile, const struct player *pplayer, bool knowledge)
Definition mapimg.h:95
struct player *(* mapimg_tile_player_func)(const struct tile *ptile, const struct player *pplayer, bool knowledge)
Definition mapimg.h:99
#define fc_calloc(n, esz)
Definition mem.h:38
#define fc_strdup(str)
Definition mem.h:43
#define fc_malloc(sz)
Definition mem.h:34
int len
Definition packhand.c:125
struct player * player_by_name_prefix(const char *name, enum m_pre_result *result)
Definition player.c:911
struct player * player_by_number(const int player_id)
Definition player.c:840
int player_count(void)
Definition player.c:808
int player_slot_count(void)
Definition player.c:411
int player_number(const struct player *pplayer)
Definition player.c:828
const char * player_name(const struct player *pplayer)
Definition player.c:886
int player_index(const struct player *pplayer)
Definition player.c:820
bool pplayers_allied(const struct player *pplayer, const struct player *pplayer2)
Definition player.c:1381
bool gives_shared_vision(const struct player *me, const struct player *them)
Definition player.c:1461
#define players_iterate_end
Definition player.h:535
#define players_iterate(_pplayer)
Definition player.h:530
#define is_human(plr)
Definition player.h:233
bool make_dir(const char *pathname)
Definition shared.c:1772
bool path_is_absolute(const char *filename)
Definition shared.c:1873
#define ARRAY_SIZE(x)
Definition shared.h:85
#define MIN(x, y)
Definition shared.h:55
#define MAX(x, y)
Definition shared.h:54
#define MAX_LEN_PATH
Definition shared.h:32
m_pre_result
Definition shared.h:207
void strvec_append(struct strvec *psv, const char *string)
struct strvec * strvec_new(void)
struct packet_game_info info
Definition game.h:89
int xsize
Definition map_types.h:77
int ysize
Definition map_types.h:77
Definition mapimg.c:367
struct mapdef * def
Definition mapimg.c:368
struct tile_shape * tileshape
Definition mapimg.c:373
base_coor_func base_coor
Definition mapimg.c:379
struct img::@49 imgsize
plot_func pixel_tile
Definition mapimg.c:374
int y
Definition mapimg.c:383
plot_func pixel_city
Definition mapimg.c:375
int x
Definition mapimg.c:382
char title[MAX_LEN_MAPDEF]
Definition mapimg.c:370
const struct rgbcolor ** map
Definition mapimg.c:389
int turn
Definition mapimg.c:369
plot_func pixel_fogofwar
Definition mapimg.c:377
plot_func pixel_border
Definition mapimg.c:378
plot_func pixel_unit
Definition mapimg.c:376
struct img::@48 mapsize
enum mapimg_status status
Definition mapimg.c:323
char error[MAX_LEN_MAPDEF]
Definition mapimg.c:322
int zoom
Definition mapimg.c:326
bv_player checked_plrbv
Definition mapimg.c:336
bv_player plrbv
Definition mapimg.c:334
bv_mapdef_arg args
Definition mapimg.c:340
enum imageformat format
Definition mapimg.c:324
int id
Definition mapimg.c:333
int turns
Definition mapimg.c:327
enum show_player show
Definition mapimg.c:330
bool colortest
Definition mapimg.c:341
struct mapdef::@45 player
enum imagetool tool
Definition mapimg.c:325
bool layers[MAPIMG_LAYER_COUNT]
Definition mapimg.c:328
char name[MAX_LEN_NAME]
Definition mapimg.c:332
char maparg[MAX_LEN_MAPARG]
Definition mapimg.c:321
enum borders_mode borders
bool is_alive
Definition player.h:268
struct rgbcolor * rgb
Definition player.h:308
struct rgbcolor * rgb
Definition terrain.h:247
int y[NUM_PIXEL]
Definition mapimg.c:95
int x[NUM_PIXEL]
Definition mapimg.c:94
Definition tile.h:49
Definition timing.c:81
const img_save_func img_save
Definition mapimg.c:422
enum imagetool tool
Definition mapimg.c:419
const char * help
Definition mapimg.c:423
int formats
Definition mapimg.c:421
enum imageformat format_default
Definition mapimg.c:420
struct civ_map map
int fc_snprintf(char *str, size_t n, const char *format,...)
Definition support.c:969
size_t fc_strlcpy(char *dest, const char *src, size_t n)
Definition support.c:787
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:995
int fc_vsnprintf(char *str, size_t n, const char *format, va_list ap)
Definition support.c:896
FILE * fc_fopen(const char *filename, const char *opentype)
Definition support.c:506
#define sz_strlcpy(dest, src)
Definition support.h:167
#define fc__attribute(x)
Definition support.h:89
#define TRUE
Definition support.h:46
#define FALSE
Definition support.h:47
#define bool
Definition support.h:61
#define sz_strlcat(dest, src)
Definition support.h:168
Terrain_type_id terrain_count(void)
Definition terrain.c:106
struct terrain * terrain_by_number(const Terrain_type_id type)
Definition terrain.c:144
#define is_ocean(pterrain)
Definition terrain.h:287
#define tile_index(_pt_)
Definition tile.h:87
known_type
Definition tile.h:34
@ TILE_KNOWN_UNSEEN
Definition tile.h:36
@ TILE_UNKNOWN
Definition tile.h:35
struct timer * timer_new(enum timer_timetype type, enum timer_use use)
Definition timing.c:157
void timer_destroy(struct timer *t)
Definition timing.c:191
void timer_start(struct timer *t)
Definition timing.c:224
double timer_read_seconds(struct timer *t)
Definition timing.c:344
@ TIMER_ACTIVE
Definition timing.h:45
@ TIMER_CPU
Definition timing.h:40
@ TIMER_USER
Definition timing.h:41