Freeciv-3.3: /fast/freeciv/nightly/main/common/mapimg.c Source File

Freeciv-3.3

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