Freeciv-3.2: /fast/freeciv/nightly/S3_2/common/mapimg.c Source File

Freeciv-3.2

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
776 MAPIMG_ASSERT_RET_VAL(mapimg_initialised(), FALSE);
777
778 if (maparg == NULL) {
779 MAPIMG_LOG(_("no map definition"));
780 return FALSE;
781 }
782
783 if (strlen(maparg) > MAX_LEN_MAPARG) {
784 /* too long map definition string */
785 MAPIMG_LOG(_("map definition string too long (max %d characters)"),
786 MAX_LEN_MAPARG);
787 return FALSE;
788 }
789
790 if (mapimg_count() == MAX_NUM_MAPIMG) {
791 MAPIMG_LOG(_("maximum number of map definitions reached (%d)"),
792 MAX_NUM_MAPIMG);
793 return FALSE;
794 }
795
796 for (i = 0; i < mapimg_count(); i++) {
797 pmapdef = mapdef_list_get(mapimg.mapdef, i);
798 if (0 == fc_strcasecmp(pmapdef->maparg, maparg)) {
799 MAPIMG_LOG(_("duplicate of map image definition %d ('%s')"), i,
800 maparg);
801 return FALSE;
802 }
803 }
804
805 pmapdef = mapdef_new(FALSE);
806
807 /* get map options */
808 nmapargs = get_tokens(maparg, mapargs, NUM_MAX_MAPARGS, ":");
809
810 for (i = 0; i < nmapargs; i++) {
811 /* split map options into variable and value */
812 nmapopts = get_tokens(mapargs[i], mapopts, NUM_MAX_MAPOPTS, "=");
813
814 if (nmapopts == 2) {
815 enum mapdef_arg arg = mapdef_arg_by_name(mapopts[0], strcmp);
816 if (mapdef_arg_is_valid(arg)) {
817 /* If ret is FALSE an error message is set by mapimg_define_arg(). */
818 ret = mapimg_define_arg(pmapdef, arg, mapopts[1], check);
819 } else {
820 MAPIMG_LOG(_("unknown map option: '%s'"), mapargs[i]);
821 ret = FALSE;
822 }
823 } else {
824 MAPIMG_LOG(_("unknown map option: '%s'"), mapargs[i]);
825 ret = FALSE;
826 }
827
828 free_tokens(mapopts, nmapopts);
829
830 if (!ret) {
831 break;
832 }
833 }
834 free_tokens(mapargs, nmapargs);
835
836 /* sanity check */
837 switch (pmapdef->player.show) {
838 case SHOW_PLRNAME: /* display player given by name */
839 if (!BV_ISSET(pmapdef->args, MAPDEF_PLRNAME)) {
840 MAPIMG_LOG(_("'show=%s' but no player name 'plrname'"),
841 show_player_name(SHOW_PLRNAME));
842 ret = FALSE;
843 }
844 break;
845 case SHOW_PLRID: /* display player given by id */
846 if (!BV_ISSET(pmapdef->args, MAPDEF_PLRID)) {
847 MAPIMG_LOG(_("'show=%s' but no player id 'plrid'"),
848 show_player_name(SHOW_PLRID));
849 ret = FALSE;
850 }
851 break;
852 case SHOW_PLRBV: /* display players given by bitvector */
853 if (!BV_ISSET(pmapdef->args, MAPDEF_PLRBV)) {
854 MAPIMG_LOG(_("'show=%s' but no player bitvector 'plrbv'"),
855 show_player_name(SHOW_PLRBV));
856 ret = FALSE;
857 }
858 break;
859 case SHOW_NONE: /* no player on the map */
860 BV_CLR_ALL(pmapdef->player.checked_plrbv);
861 break;
862 case SHOW_ALL: /* show all players in one map */
863 BV_SET_ALL(pmapdef->player.checked_plrbv);
864 break;
865 case SHOW_EACH: /* one map for each player */
866 case SHOW_HUMAN: /* one map for each human player */
867 /* A loop for each player will be called at the time the image is
868 * created. */
869 BV_CLR_ALL(pmapdef->player.checked_plrbv);
870 break;
871 }
872
873 if (ret && !check) {
874 /* save map string */
875 fc_strlcpy(pmapdef->maparg, maparg, MAX_LEN_MAPARG);
876
877 /* add map definiton */
878 mapdef_list_append(mapimg.mapdef, pmapdef);
879 } else {
880 mapdef_destroy(pmapdef);
881 }
882
883 return ret;
884}
885#undef NUM_MAX_MAPARGS
886#undef NUM_MAX_MAPOPTS
887
888/************************************************************************/
891#define NUM_MAX_FORMATARGS 2
892 static bool mapimg_define_arg(struct mapdef *pmapdef, enum mapdef_arg arg,
893 const char *val, bool check)
894{
895 if (BV_ISSET(pmapdef->args, arg)) {
896 log_debug("Option '%s' for mapimg used more than once.",
897 mapdef_arg_name(arg));
898 }
899
900 /* This argument was used. */
901 BV_SET(pmapdef->args, arg);
902
903 switch (arg) {
904 case MAPDEF_FORMAT:
905 /* file format */
906 {
907 char *formatargs[NUM_MAX_FORMATARGS];
908 int nformatargs;
909 enum imageformat format;
910 enum imagetool tool;
911 bool error = TRUE;
912
913 /* get format options */
914 nformatargs = get_tokens(val, formatargs, NUM_MAX_FORMATARGS, "|");
915
916 if (nformatargs == 2) {
917 tool = imagetool_by_name(formatargs[0], strcmp);
918 format = imageformat_by_name(formatargs[1], strcmp);
919
920 if (imageformat_is_valid(format) && imagetool_is_valid(tool)) {
921 const struct toolkit *toolkit = img_toolkit_get(tool);
922
923 if (toolkit && (toolkit->formats & format)) {
924 pmapdef->tool = tool;
925 pmapdef->format = format;
926
927 error = FALSE;
928 }
929 }
930 } else {
931 /* Only one argument to format. */
932 tool = imagetool_by_name(formatargs[0], strcmp);
933 if (imagetool_is_valid(tool)) {
934 /* toolkit defined */
935 const struct toolkit *toolkit = img_toolkit_get(tool);
936
937 if (toolkit) {
938 pmapdef->tool = toolkit->tool;
939 pmapdef->format = toolkit->format_default;
940
941 error = FALSE;
942 }
943 } else {
944 format = imageformat_by_name(formatargs[0], strcmp);
945 if (imageformat_is_valid(format)) {
946 /* format defined */
947 img_toolkit_iterate(toolkit) {
948 if ((toolkit->formats & format)) {
949 pmapdef->tool = toolkit->tool;
950 pmapdef->format = toolkit->format_default;
951
952 error = FALSE;
953 break;
954 }
955 } img_toolkit_iterate_end;
956 }
957 }
958 }
959
960 free_tokens(formatargs, nformatargs);
961
962 if (error) {
963 goto INVALID;
964 }
965 }
966 break;
967
968 case MAPDEF_MAP:
969 /* map definition */
970 {
971 int len = strlen(val), l;
972 enum mapimg_layer layer;
973 bool error;
974
975 for (layer = mapimg_layer_begin(); layer != mapimg_layer_end();
976 layer = mapimg_layer_next(layer)) {
977 pmapdef->layers[layer] = FALSE;
978 }
979
980 for (l = 0; l < len; l++) {
981 error = TRUE;
982 for (layer = mapimg_layer_begin(); layer != mapimg_layer_end();
983 layer = mapimg_layer_next(layer)) {
984 if (val[l] == mapimg_layer_name(layer)[0]) {
985 pmapdef->layers[layer] = TRUE;
986 error = FALSE;
987 break;
988 }
989 }
990
991 if (error) {
992 goto INVALID;
993 }
994 }
995 }
996 break;
997
998 case MAPDEF_PLRBV:
999 /* player definition - bitvector */
1000 {
1001 int i;
1002
1003 if (strlen(val) < MAX_NUM_PLAYER_SLOTS + 1) {
1004 BV_CLR_ALL(pmapdef->player.plrbv);
1005 for (i = 0; i < strlen(val); i++) {
1006 if (!strchr("01", val[i])) {
1007 MAPIMG_LOG(_("invalid character in bitvector: '%c' (%s)"),
1008 val[i], val);
1009 return FALSE;
1010 } else if (val[i] == '1') {
1011 BV_SET(pmapdef->player.plrbv, i);
1012 }
1013 }
1014 } else {
1015 goto INVALID;
1016 }
1017 }
1018 break;
1019
1020 case MAPDEF_PLRID:
1021 /* player definition - player id; will be checked by mapimg_isvalid()
1022 * which calls mapimg_checkplayers() */
1023 {
1024 int plrid;
1025
1026 if (sscanf(val, "%d", &plrid) != 0) {
1027 if (plrid < 0 || plrid >= MAX_NUM_PLAYER_SLOTS) {
1028 MAPIMG_LOG(_("'plrid' should be between 0 and %d"),
1029 MAX_NUM_PLAYER_SLOTS-1);
1030 return FALSE;
1031 }
1032 pmapdef->player.id = plrid;
1033 } else {
1034 goto INVALID;
1035 }
1036 }
1037 break;
1038
1039 case MAPDEF_PLRNAME:
1040 /* player definition - player name; will be checked by mapimg_isvalid()
1041 * which calls mapimg_checkplayers() */
1042 {
1043 if (strlen(val) > sizeof(pmapdef->player.name)) {
1044 MAPIMG_LOG(_("player name too long: '%s' (max: %lu)"), val,
1045 (unsigned long) sizeof(pmapdef->player.name));
1046 return FALSE;
1047 } else {
1048 sz_strlcpy(pmapdef->player.name, val);
1049 }
1050 }
1051 break;
1052
1053 case MAPDEF_SHOW:
1054 /* player definition - basic definition */
1055 {
1056 enum show_player showplr;
1057
1058 showplr = show_player_by_name(val, strcmp);
1059 if (show_player_is_valid(showplr)) {
1060 pmapdef->player.show = showplr;
1061 } else {
1062 goto INVALID;
1063 }
1064 }
1065 break;
1066
1067 case MAPDEF_TURNS:
1068 /* save each <x> turns */
1069 {
1070 int turns;
1071
1072 if (sscanf(val, "%d", &turns) != 0) {
1073 if (turns < 0 || turns > 99) {
1074 MAPIMG_LOG(_("'turns' should be between 0 and 99"));
1075 return FALSE;
1076 } else {
1077 pmapdef->turns = turns;
1078 }
1079 } else {
1080 goto INVALID;
1081 }
1082 }
1083 break;
1084
1085 case MAPDEF_ZOOM:
1086 /* zoom factor */
1087 {
1088 int zoom;
1089
1090 if (sscanf(val, "%d", &zoom) != 0) {
1091 if (zoom < 1 || zoom > 5) {
1092 MAPIMG_LOG(_("'zoom' factor should be between 1 and 5"));
1093 return FALSE;
1094 } else {
1095 pmapdef->zoom = zoom;
1096 }
1097 } else {
1098 goto INVALID;
1099 }
1100 }
1101 break;
1102
1103 case MAPDEF_COUNT:
1104 fc_assert_ret_val(arg != MAPDEF_COUNT, FALSE);
1105 break;
1106 }
1107
1108 return TRUE;
1109
1110 INVALID:
1111 MAPIMG_LOG(_("invalid value for option '%s': '%s'"),
1112 mapdef_arg_name(arg), val);
1113 return FALSE;
1114}
1115#undef NUM_MAX_FORMATARGS
1116
1117/************************************************************************/
1121 struct mapdef *mapimg_isvalid(int id)
1122{
1123 struct mapdef *pmapdef = NULL;
1124
1125 if (!mapimg_test(id)) {
1126 /* The error message is set in mapimg_test(). */
1127 return NULL;
1128 }
1129
1130 pmapdef = mapdef_list_get(mapimg.mapdef, id);
1131 mapimg_checkplayers(pmapdef, TRUE);
1132
1133 switch (pmapdef->status) {
1134 case MAPIMG_STATUS_UNKNOWN:
1135 MAPIMG_LOG(_("map definition not checked (game not started)"));
1136 return NULL;
1137 break;
1138 case MAPIMG_STATUS_ERROR:
1139 MAPIMG_LOG(_("map definition deactivated: %s"), pmapdef->error);
1140 return NULL;
1141 break;
1142 case MAPIMG_STATUS_OK:
1143 /* nothing */
1144 break;
1145 }
1146
1147 return pmapdef;
1148}
1149
1150/************************************************************************/
1153 const struct strvec *mapimg_get_format_list(void)
1154{
1155 static struct strvec *format_list = NULL;
1156
1157 if (NULL == format_list) {
1158 enum imagetool tool;
1159
1160 format_list = strvec_new();
1161
1162 for (tool = imagetool_begin(); tool != imagetool_end();
1163 tool = imagetool_next(tool)) {
1164 enum imageformat format;
1165 const struct toolkit *toolkit = img_toolkit_get(tool);
1166
1167 if (!toolkit) {
1168 continue;
1169 }
1170
1171 for (format = imageformat_begin(); format != imageformat_end();
1172 format = imageformat_next(format)) {
1173 if (toolkit->formats & format) {
1174 char str_format[64];
1175
1176 fc_snprintf(str_format, sizeof(str_format), "%s|%s",
1177 imagetool_name(tool), imageformat_name(format));
1178 strvec_append(format_list, str_format);
1179 }
1180 }
1181 }
1182 }
1183
1184 return format_list;
1185}
1186
1187/************************************************************************/
1190 const char *mapimg_get_format_default(void)
1191{
1192 static char default_format[64];
1193
1194 fc_snprintf(default_format, sizeof(default_format), "%s|%s",
1195 imagetool_name(MAPIMG_DEFAULT_IMGTOOL),
1196 imageformat_name(MAPIMG_DEFAULT_IMGFORMAT));
1197
1198 return default_format;
1199}
1200
1201/************************************************************************/
1204 bool mapimg_delete(int id)
1205{
1206 struct mapdef *pmapdef = NULL;
1207
1208 if (!mapimg_test(id)) {
1209 /* The error message is set in mapimg_test(). */
1210 return FALSE;
1211 }
1212
1213 /* delete map definition */
1214 pmapdef = mapdef_list_get(mapimg.mapdef, id);
1215 mapdef_list_remove(mapimg.mapdef, pmapdef);
1216
1217 return TRUE;
1218}
1219
1220/************************************************************************/
1223 bool mapimg_show(int id, char *str, size_t str_len, bool detail)
1224{
1225 struct mapdef *pmapdef = NULL;
1226
1227 if (!mapimg_test(id)) {
1228 /* The error message is set in mapimg_test(). */
1229 return FALSE;
1230 }
1231
1232 pmapdef = mapdef_list_get(mapimg.mapdef, id);
1233
1234 /* Clear string ... */
1235 fc_assert_ret_val(str_len > 0, FALSE);
1236 str[0] = '\0';
1237
1238 if (detail) {
1239 cat_snprintf(str, str_len, _("Detailed information for map image "
1240 "definition %d\n"), id);
1241 if (pmapdef->status == MAPIMG_STATUS_ERROR) {
1242 cat_snprintf(str, str_len, _(" - status: %s (%s)\n"),
1243 mapimg_status_name(pmapdef->status), pmapdef->error);
1244 } else {
1245 cat_snprintf(str, str_len, _(" - status: %s\n"),
1246 mapimg_status_name(pmapdef->status));
1247 }
1248 cat_snprintf(str, str_len, _(" - file name string: %s\n"),
1249 mapimg_generate_name(pmapdef));
1250 cat_snprintf(str, str_len, _(" - image toolkit: %s\n"),
1251 imagetool_name(pmapdef->tool));
1252 cat_snprintf(str, str_len, _(" - image format: %s\n"),
1253 imageformat_name(pmapdef->format));
1254 cat_snprintf(str, str_len, _(" - zoom factor: %d\n"),
1255 pmapdef->zoom);
1256 cat_snprintf(str, str_len, _(" - show area within borders: %s\n"),
1257 pmapdef->layers[MAPIMG_LAYER_AREA] ? _("yes") : _("no"));
1258 cat_snprintf(str, str_len, _(" - show borders: %s\n"),
1259 pmapdef->layers[MAPIMG_LAYER_BORDERS] ? _("yes") : _("no"));
1260 cat_snprintf(str, str_len, _(" - show cities: %s\n"),
1261 pmapdef->layers[MAPIMG_LAYER_CITIES] ? _("yes") : _("no"));
1262 cat_snprintf(str, str_len, _(" - show fog of war: %s\n"),
1263 pmapdef->layers[MAPIMG_LAYER_FOGOFWAR] ? _("yes") : _("no"));
1264 cat_snprintf(str, str_len, _(" - show player knowledge: %s\n"),
1265 pmapdef->layers[MAPIMG_LAYER_KNOWLEDGE] ? _("yes") : _("no"));
1266 cat_snprintf(str, str_len, _(" - show terrain: %s\n"),
1267 pmapdef->layers[MAPIMG_LAYER_TERRAIN] ? _("full") :_("basic"));
1268 cat_snprintf(str, str_len, _(" - show units: %s\n"),
1269 pmapdef->layers[MAPIMG_LAYER_UNITS] ? _("yes") : _("no"));
1270 cat_snprintf(str, str_len, _(" - players included: %s"),
1271 show_player_name(pmapdef->player.show));
1272 switch (pmapdef->player.show) {
1273 case SHOW_NONE:
1274 case SHOW_HUMAN:
1275 case SHOW_EACH:
1276 case SHOW_ALL:
1277 /* nothing */
1278 break;
1279 case SHOW_PLRNAME:
1280 cat_snprintf(str, str_len, _("\n - player name: %s"),
1281 pmapdef->player.name);
1282 break;
1283 case SHOW_PLRID:
1284 cat_snprintf(str, str_len, _("\n - player id: %d"),
1285 pmapdef->player.id);
1286 break;
1287 case SHOW_PLRBV:
1288 cat_snprintf(str, str_len, _("\n - players: %s"),
1289 bvplayers_str(pmapdef->player.plrbv));
1290 break;
1291 }
1292 } else {
1293 char str_def[MAX_LEN_MAPDEF];
1294 mapimg_def2str(pmapdef, str_def, sizeof(str_def));
1295 if (pmapdef->status == MAPIMG_STATUS_ERROR) {
1296 cat_snprintf(str, str_len, "'%s' (%s: %s)", str_def,
1297 mapimg_status_name(pmapdef->status), pmapdef->error);
1298 } else {
1299 cat_snprintf(str, str_len, "'%s' (%s)", str_def,
1300 mapimg_status_name(pmapdef->status));
1301 }
1302 }
1303
1304 return TRUE;
1305}
1306
1307/************************************************************************/
1311 bool mapimg_id2str(int id, char *str, size_t str_len)
1312{
1313 struct mapdef *pmapdef = NULL;
1314
1315 if (!mapimg_test(id)) {
1316 /* The error message is set in mapimg_test(). */
1317 return FALSE;
1318 }
1319
1320 pmapdef = mapdef_list_get(mapimg.mapdef, id);
1321
1322 return mapimg_def2str(pmapdef, str, str_len);
1323}
1324
1325/************************************************************************/
1332 bool mapimg_create(struct mapdef *pmapdef, bool force, const char *savename,
1333 const char *path)
1334{
1335 struct img *pimg;
1336 char mapimgfile[MAX_LEN_PATH];
1337 bool ret = TRUE;
1338#ifdef FREECIV_DEBUG
1339 struct timer *timer_cpu, *timer_user;
1340#endif
1341
1342 if (map_is_empty()) {
1343 MAPIMG_LOG(_("map not yet created"));
1344
1345 return FALSE;
1346 }
1347
1348 mapimg_checkplayers(pmapdef, FALSE);
1349
1350 if (pmapdef->status != MAPIMG_STATUS_OK) {
1351 MAPIMG_LOG(_("map definition not checked or error"));
1352 return FALSE;
1353 }
1354
1355 /* An image should be saved if:
1356 * - force is set to TRUE
1357 * - it is the first turn
1358 * - turns is set to a value not zero and the current turn can be devided
1359 * by this number */
1360 if (!force && game.info.turn != 1
1361 && !(pmapdef->turns != 0 && game.info.turn % pmapdef->turns == 0)) {
1362 return TRUE;
1363 }
1364
1365#ifdef FREECIV_DEBUG
1366 timer_cpu = timer_new(TIMER_CPU, TIMER_ACTIVE, "mapimg cpu");
1367 timer_start(timer_cpu);
1368 timer_user = timer_new(TIMER_USER, TIMER_ACTIVE, "mapimg user");
1369 timer_start(timer_user);
1370#endif /* FREECIV_DEBUG */
1371
1372 /* Create map */
1373 switch (pmapdef->player.show) {
1374 case SHOW_PLRNAME: /* display player given by name */
1375 case SHOW_PLRID: /* display player given by id */
1376 case SHOW_NONE: /* no player one the map */
1377 case SHOW_ALL: /* show all players in one map */
1378 case SHOW_PLRBV: /* display player(s) given by bitvector */
1379 generate_save_name(savename, mapimgfile, sizeof(mapimgfile),
1380 mapimg_generate_name(pmapdef));
1381
1382 pimg = img_new(pmapdef, CURRENT_TOPOLOGY, CURRENT_WRAP,
1383 wld.map.xsize, wld.map.ysize);
1384 img_createmap(pimg);
1385 if (!img_save(pimg, mapimgfile, path)) {
1386 ret = FALSE;
1387 }
1388 img_destroy(pimg);
1389 break;
1390 case SHOW_EACH: /* one map for each player */
1391 case SHOW_HUMAN: /* one map for each human player */
1392 players_iterate(pplayer) {
1393 if (!pplayer->is_alive || (pmapdef->player.show == SHOW_HUMAN
1394 && !is_human(pplayer))) {
1395 /* no map image for dead players
1396 * or AI players if only human players should be shown */
1397 continue;
1398 }
1399
1400 BV_CLR_ALL(pmapdef->player.checked_plrbv);
1401 BV_SET(pmapdef->player.checked_plrbv, player_index(pplayer));
1402
1403 generate_save_name(savename, mapimgfile, sizeof(mapimgfile),
1404 mapimg_generate_name(pmapdef));
1405
1406 pimg = img_new(pmapdef, CURRENT_TOPOLOGY, CURRENT_WRAP,
1407 wld.map.xsize, wld.map.ysize);
1408 img_createmap(pimg);
1409 if (!img_save(pimg, mapimgfile, path)) {
1410 ret = FALSE;
1411 }
1412 img_destroy(pimg);
1413
1414 if (!ret) {
1415 break;
1416 }
1417 } players_iterate_end;
1418 break;
1419 }
1420
1421#ifdef FREECIV_DEBUG
1422 log_debug("Image generation time: %g seconds (%g apparent)",
1423 timer_read_seconds(timer_cpu),
1424 timer_read_seconds(timer_user));
1425
1426 timer_destroy(timer_cpu);
1427 timer_destroy(timer_user);
1428#endif /* FREECIV_DEBUG */
1429
1430 return ret;
1431}
1432
1433/************************************************************************/
1438 bool mapimg_colortest(const char *savename, const char *path)
1439{
1440 struct img *pimg;
1441 const struct rgbcolor *pcolor;
1442 struct mapdef *pmapdef = mapdef_new(TRUE);
1443 char mapimgfile[MAX_LEN_PATH];
1444 bv_pixel pixel;
1445 int i, nat_x, nat_y;
1446 int max_playercolor = mapimg.mapimg_plrcolor_count();
1447 int max_terraincolor = terrain_count();
1448 bool ret = TRUE;
1449 enum imagetool tool;
1450
1451#define SIZE_X 16
1452#define SIZE_Y 5
1453
1454 pimg = img_new(pmapdef, 0, 0, SIZE_X + 2,
1455 SIZE_Y * (max_playercolor / SIZE_X) + 2);
1456
1457 pixel = pimg->pixel_tile(NULL, NULL, FALSE);
1458
1459 pcolor = imgcolor_special(IMGCOLOR_OCEAN);
1460 for (i = 0; i < MAX(max_playercolor, max_terraincolor); i++) {
1461 nat_x = 1 + i % SIZE_X;
1462 nat_y = 1 + (i / SIZE_X) * SIZE_Y;
1463
1464 img_plot(pimg, nat_x, nat_y, pcolor, pixel);
1465 }
1466
1467 for (i = 0; i < MAX(max_playercolor, max_terraincolor); i++) {
1468 if (i >= max_playercolor) {
1469 break;
1470 }
1471
1472 nat_x = 1 + i % SIZE_X;
1473 nat_y = 2 + (i / SIZE_X) * SIZE_Y;
1474 pcolor = mapimg.mapimg_plrcolor_get(i);
1475
1476 img_plot(pimg, nat_x, nat_y, pcolor, pixel);
1477 }
1478
1479 pcolor = imgcolor_special(IMGCOLOR_GROUND);
1480 for (i = 0; i < MAX(max_playercolor, max_terraincolor); i++) {
1481 nat_x = 1 + i % SIZE_X;
1482 nat_y = 3 + (i / SIZE_X) * SIZE_Y;
1483
1484 img_plot(pimg, nat_x, nat_y, pcolor, pixel);
1485 }
1486
1487 for (i = 0; i < MAX(max_playercolor, max_terraincolor); i++) {
1488 if (i >= max_terraincolor) {
1489 break;
1490 }
1491
1492 nat_x = 1 + i % SIZE_X;
1493 nat_y = 4 + (i / SIZE_X) * SIZE_Y;
1494 pcolor = imgcolor_terrain(terrain_by_number(i));
1495
1496 img_plot(pimg, nat_x, nat_y, pcolor, pixel);
1497 }
1498
1499#undef SIZE_X
1500#undef SIZE_Y
1501
1502 for (tool = imagetool_begin(); tool != imagetool_end();
1503 tool = imagetool_next(tool)) {
1504 enum imageformat format;
1505 const struct toolkit *toolkit = img_toolkit_get(tool);
1506
1507 if (!toolkit) {
1508 continue;
1509 }
1510
1511 /* Set the toolkit. */
1512 pmapdef->tool = tool;
1513
1514 for (format = imageformat_begin(); format != imageformat_end();
1515 format = imageformat_next(format)) {
1516 if (toolkit->formats & format) {
1517 char buf[128];
1518 const char *tname = imagetool_name(tool);
1519
1520 /* Set the image format. */
1521 pmapdef->format = format;
1522
1523 if (tname != NULL) {
1524 fc_snprintf(buf, sizeof(buf), "colortest-%s", tname);
1525 } else {
1526 fc_snprintf(buf, sizeof(buf), "colortest");
1527 }
1528 /* filename for color test */
1529 generate_save_name(savename, mapimgfile, sizeof(mapimgfile), buf);
1530
1531 if (!img_save(pimg, mapimgfile, path)) {
1532 /* If one of the mapimg format/toolkit combination fail, return
1533 * FALSE, i.e. an error occurred. */
1534 ret = FALSE;
1535 }
1536 }
1537 }
1538 }
1539
1540 img_destroy(pimg);
1541 mapdef_destroy(pmapdef);
1542
1543 return ret;
1544}
1545
1546/*
1547 * ==============================================
1548 * map images (internal functions)
1549 * ==============================================
1550 */
1551
1552/************************************************************************/
1555 bool mapimg_initialised(void)
1556{
1557 return mapimg.init;
1558}
1559
1560/************************************************************************/
1564 static bool mapimg_test(int id)
1565{
1566 MAPIMG_ASSERT_RET_VAL(mapimg_initialised(), FALSE);
1567
1568 if (id < 0 || id >= mapimg_count()) {
1569 MAPIMG_LOG(_("no map definition with id %d"), id);
1570 return FALSE;
1571 }
1572
1573 return TRUE;
1574}
1575
1576/************************************************************************/
1579 static bool mapimg_def2str(struct mapdef *pmapdef, char *str, size_t str_len)
1580{
1581 enum mapimg_layer layer;
1582 char buf[MAPIMG_LAYER_COUNT + 1];
1583 int i;
1584
1585 if (pmapdef->status != MAPIMG_STATUS_OK) {
1586 MAPIMG_LOG(_("map definition not checked or error"));
1587 fc_strlcpy(str, pmapdef->maparg, str_len);
1588 return FALSE;
1589 }
1590
1591 str[0] = '\0';
1592 cat_snprintf(str, str_len, "format=%s|%s:",
1593 imagetool_name(pmapdef->tool),
1594 imageformat_name(pmapdef->format));
1595 cat_snprintf(str, str_len, "turns=%d:", pmapdef->turns);
1596
1597 i = 0;
1598 for (layer = mapimg_layer_begin(); layer != mapimg_layer_end();
1599 layer = mapimg_layer_next(layer)) {
1600 if (pmapdef->layers[layer]) {
1601 buf[i++] = mapimg_layer_name(layer)[0];
1602 }
1603 }
1604 buf[i++] = '\0';
1605 cat_snprintf(str, str_len, "map=%s:", buf);
1606
1607 switch (pmapdef->player.show) {
1608 case SHOW_NONE:
1609 case SHOW_EACH:
1610 case SHOW_HUMAN:
1611 case SHOW_ALL:
1612 cat_snprintf(str, str_len, "show=%s:",
1613 show_player_name(pmapdef->player.show));
1614 break;
1615 case SHOW_PLRBV:
1616 cat_snprintf(str, str_len, "show=%s:", show_player_name(SHOW_PLRBV));
1617 cat_snprintf(str, str_len, "plrbv=%s:",
1618 bvplayers_str(pmapdef->player.plrbv));
1619 break;
1620 case SHOW_PLRNAME:
1621 cat_snprintf(str, str_len, "show=%s:", show_player_name(SHOW_PLRNAME));
1622 cat_snprintf(str, str_len, "plrname=%s:", pmapdef->player.name);
1623 break;
1624 case SHOW_PLRID:
1625 cat_snprintf(str, str_len, "show=%s:", show_player_name(SHOW_PLRID));
1626 cat_snprintf(str, str_len, "plrid=%d:", pmapdef->player.id);
1627 break;
1628 }
1629 cat_snprintf(str, str_len, "zoom=%d", pmapdef->zoom);
1630
1631 return TRUE;
1632}
1633
1634/************************************************************************/
1639 static bool mapimg_checkplayers(struct mapdef *pmapdef, bool recheck)
1640{
1641 struct player *pplayer;
1642 enum m_pre_result result;
1643
1644 if (!recheck && pmapdef->status == MAPIMG_STATUS_ERROR) {
1645 return FALSE;
1646 }
1647
1648 /* game started - generate / check bitvector for players */
1649 switch (pmapdef->player.show) {
1650 case SHOW_NONE:
1651 /* nothing */
1652 break;
1653 case SHOW_PLRBV:
1654 pmapdef->player.checked_plrbv = pmapdef->player.plrbv;
1655 break;
1656 case SHOW_EACH:
1657 case SHOW_HUMAN:
1658 /* A map for each player will be created in a loop. */
1659 BV_CLR_ALL(pmapdef->player.checked_plrbv);
1660 break;
1661 case SHOW_ALL:
1662 BV_SET_ALL(pmapdef->player.checked_plrbv);
1663 break;
1664 case SHOW_PLRNAME:
1665 /* display players as requested in the map definition */
1666 BV_CLR_ALL(pmapdef->player.checked_plrbv);
1667 pplayer = player_by_name_prefix(pmapdef->player.name, &result);
1668
1669 if (pplayer != NULL) {
1670 BV_SET(pmapdef->player.checked_plrbv, player_index(pplayer));
1671 } else {
1672 pmapdef->status = MAPIMG_STATUS_ERROR;
1673 /* Save the error message in map definition. */
1674 fc_snprintf(pmapdef->error, sizeof(pmapdef->error),
1675 _("unknown player name: '%s'"), pmapdef->player.name);
1676 MAPIMG_LOG("%s", pmapdef->error);
1677 return FALSE;
1678 }
1679 break;
1680 case SHOW_PLRID:
1681 /* display players as requested in the map definition */
1682 BV_CLR_ALL(pmapdef->player.checked_plrbv);
1683 pplayer = player_by_number(pmapdef->player.id);
1684
1685 if (pplayer != NULL) {
1686 BV_SET(pmapdef->player.checked_plrbv, player_index(pplayer));
1687 } else {
1688 pmapdef->status = MAPIMG_STATUS_ERROR;
1689 /* Save the error message in map definition. */
1690 fc_snprintf(pmapdef->error, sizeof(pmapdef->error),
1691 _("invalid player id: %d"), pmapdef->player.id);
1692 MAPIMG_LOG("%s", pmapdef->error);
1693 return FALSE;
1694 }
1695 break;
1696 }
1697
1698 pmapdef->status = MAPIMG_STATUS_OK;
1699
1700 return TRUE;
1701}
1702
1703/************************************************************************/
1707 static void mapimg_log(const char *file, const char *function, int line,
1708 const char *format, ...)
1709{
1710 va_list args;
1711
1712 va_start(args, format);
1713 fc_vsnprintf(error_buffer, sizeof(error_buffer), format, args);
1714 va_end(args);
1715
1716#ifdef FREECIV_DEBUG
1717 log_debug("In %s() [%s:%d]: %s", function, file, line, error_buffer);
1718#endif
1719}
1720
1721/************************************************************************/
1734 static char *mapimg_generate_name(struct mapdef *pmapdef)
1735{
1736 static char mapstr[256];
1737 char str_show[MAX_NUM_PLAYER_SLOTS + 1];
1738 enum mapimg_layer layer;
1739 int i, count = 0, plr_id = -1;
1740
1741 switch (pmapdef->player.show) {
1742 case SHOW_NONE:
1743 /* no player on the map */
1744 sz_strlcpy(str_show, "none");
1745 break;
1746 case SHOW_ALL:
1747 /* show all players in one map */
1748 sz_strlcpy(str_show, "all");
1749 break;
1750 case SHOW_PLRBV:
1751 case SHOW_PLRNAME:
1752 case SHOW_PLRID:
1753 case SHOW_HUMAN:
1754 case SHOW_EACH:
1755 /* one map for each selected player; iterate over all possible player ids
1756 * to generate unique strings even if civil wars occur */
1757 for (i = 0; i < MAX_NUM_PLAYER_SLOTS; i++) {
1758 str_show[i] = BV_ISSET(pmapdef->player.checked_plrbv, i) ? '1' : '0';
1759 if (BV_ISSET(pmapdef->player.checked_plrbv, i)) {
1760 count++;
1761 plr_id = i;
1762 }
1763 }
1764 str_show[MAX_NUM_PLAYER_SLOTS] = '\0';
1765
1766 /* Return the option name if no player is selected or the player id if
1767 * there is only one player selected. */
1768 if (count == 0) {
1769 fc_snprintf(str_show, sizeof(str_show), "---%s",
1770 show_player_name(pmapdef->player.show));
1771 } else if (count == 1 && plr_id != -1) {
1772 fc_snprintf(str_show, sizeof(str_show), "%03d%s", plr_id,
1773 show_player_name(pmapdef->player.show));
1774 }
1775 break;
1776 }
1777
1778 fc_snprintf(mapstr, sizeof(mapstr), "M");
1779 for (layer = mapimg_layer_begin(); layer != mapimg_layer_end();
1780 layer = mapimg_layer_next(layer)) {
1781 if (pmapdef->layers[layer]) {
1782 const char *lname = mapimg_layer_name(layer);
1783
1784 if (lname != NULL) {
1785 cat_snprintf(mapstr, sizeof(mapstr), "%s", lname);
1786 } else {
1787 cat_snprintf(mapstr, sizeof(mapstr), "-");
1788 }
1789 } else {
1790 cat_snprintf(mapstr, sizeof(mapstr), "-");
1791 }
1792 }
1793 cat_snprintf(mapstr, sizeof(mapstr), "Z%dP%s", pmapdef->zoom, str_show);
1794
1795 return mapstr;
1796}
1797
1798/*
1799 * ==============================================
1800 * map definitions (internal functions)
1801 * ==============================================
1802 */
1803
1804/************************************************************************/
1807 static struct mapdef *mapdef_new(bool colortest)
1808{
1809 struct mapdef *pmapdef;
1810
1811 pmapdef = fc_malloc(sizeof(*pmapdef));
1812
1813 /* default values */
1814 pmapdef->maparg[0] = '\0';
1815 pmapdef->error[0] = '\0';
1816 pmapdef->status = MAPIMG_STATUS_UNKNOWN;
1817 pmapdef->format = MAPIMG_DEFAULT_IMGFORMAT;
1818 pmapdef->tool = MAPIMG_DEFAULT_IMGTOOL;
1819 pmapdef->zoom = 2;
1820 pmapdef->turns = 1;
1821 pmapdef->layers[MAPIMG_LAYER_TERRAIN] = FALSE;
1822 pmapdef->layers[MAPIMG_LAYER_CITIES] = TRUE;
1823 pmapdef->layers[MAPIMG_LAYER_UNITS] = TRUE;
1824 pmapdef->layers[MAPIMG_LAYER_BORDERS] = TRUE;
1825 pmapdef->layers[MAPIMG_LAYER_FOGOFWAR] = FALSE;
1826 pmapdef->layers[MAPIMG_LAYER_KNOWLEDGE] = TRUE;
1827 pmapdef->layers[MAPIMG_LAYER_AREA] = FALSE;
1828 pmapdef->player.show = SHOW_ALL;
1829 /* The union is not set at this point (player.id, player.name and
1830 * player.plrbv). */
1831 BV_CLR_ALL(pmapdef->player.checked_plrbv);
1832 BV_CLR_ALL(pmapdef->args);
1833 pmapdef->colortest = colortest;
1834
1835 return pmapdef;
1836}
1837
1838/************************************************************************/
1841 static void mapdef_destroy(struct mapdef *pmapdef)
1842{
1843 if (pmapdef == NULL) {
1844 return;
1845 }
1846
1847 free(pmapdef);
1848}
1849
1850/*
1851 * ==============================================
1852 * images (internal functions)
1853 * ==============================================
1854 */
1855
1856/************************************************************************/
1859 static const struct toolkit *img_toolkit_get(enum imagetool tool)
1860{
1861 img_toolkit_iterate(toolkit) {
1862 if (toolkit->tool == tool) {
1863 return toolkit;
1864 }
1865 } img_toolkit_iterate_end;
1866
1867 return NULL;
1868}
1869
1870/************************************************************************/
1873 static struct img *img_new(struct mapdef *mapdef, int topo, int wrap,
1874 int xsize, int ysize)
1875{
1876 struct img *pimg;
1877
1878 pimg = fc_malloc(sizeof(*pimg));
1879
1880 pimg->def = mapdef;
1881 pimg->turn = game.info.turn;
1882 fc_snprintf(pimg->title, sizeof(pimg->title),
1883 _("Turn: %4d - Year: %10s"), game.info.turn,
1884 calendar_text());
1885
1886 pimg->mapsize.x = xsize; /* x size of the map */
1887 pimg->mapsize.y = ysize; /* y size of the map */
1888
1889 pimg->imgsize.x = 0; /* x size of the map image */
1890 pimg->imgsize.y = 0; /* y size of the map image */
1891
1892 if (topo_has_flag(topo, TF_HEX)) {
1893 /* additional space for hex maps */
1894 pimg->imgsize.x += TILE_SIZE / 2;
1895 pimg->imgsize.y += TILE_SIZE / 2;
1896
1897 if (topo_has_flag(topo, TF_ISO)) {
1898 /* iso-hex */
1899 pimg->imgsize.x += (pimg->mapsize.x + pimg->mapsize.y / 2)
1900 * TILE_SIZE;
1901 pimg->imgsize.y += (pimg->mapsize.x + pimg->mapsize.y / 2)
1902 * TILE_SIZE;
1903
1904 /* magic for isohexa: change size if wrapping in only one direction */
1905 if ((wrap_has_flag(wrap, WRAP_X) && !wrap_has_flag(wrap, WRAP_Y))
1906 || (!wrap_has_flag(wrap, WRAP_X) && wrap_has_flag(wrap, WRAP_Y))) {
1907 pimg->imgsize.y += (pimg->mapsize.x - pimg->mapsize.y / 2) / 2
1908 * TILE_SIZE;
1909 }
1910
1911 pimg->tileshape = &tile_isohexa;
1912
1913 pimg->pixel_tile = pixel_tile_isohexa;
1914 pimg->pixel_city = pixel_city_isohexa;
1915 pimg->pixel_unit = pixel_unit_isohexa;
1916 pimg->pixel_fogofwar = pixel_fogofwar_isohexa;
1917 pimg->pixel_border = pixel_border_isohexa;
1918
1919 pimg->base_coor = base_coor_isohexa;
1920 } else {
1921 /* hex */
1922 pimg->imgsize.x += pimg->mapsize.x * TILE_SIZE;
1923 pimg->imgsize.y += pimg->mapsize.y * TILE_SIZE;
1924
1925 pimg->tileshape = &tile_hexa;
1926
1927 pimg->pixel_tile = pixel_tile_hexa;
1928 pimg->pixel_city = pixel_city_hexa;
1929 pimg->pixel_unit = pixel_unit_hexa;
1930 pimg->pixel_fogofwar = pixel_fogofwar_hexa;
1931 pimg->pixel_border = pixel_border_hexa;
1932
1933 pimg->base_coor = base_coor_hexa;
1934 }
1935 } else {
1936 if (topo_has_flag(topo, TF_ISO)) {
1937 /* isometric rectangular */
1938 pimg->imgsize.x += (pimg->mapsize.x + pimg->mapsize.y / 2) * TILE_SIZE;
1939 pimg->imgsize.y += (pimg->mapsize.x + pimg->mapsize.y / 2) * TILE_SIZE;
1940 } else {
1941 /* rectangular */
1942 pimg->imgsize.x += pimg->mapsize.x * TILE_SIZE;
1943 pimg->imgsize.y += pimg->mapsize.y * TILE_SIZE;
1944 }
1945
1946 pimg->tileshape = &tile_rect;
1947
1948 pimg->pixel_tile = pixel_tile_rect;
1949 pimg->pixel_city = pixel_city_rect;
1950 pimg->pixel_unit = pixel_unit_rect;
1951 pimg->pixel_fogofwar = pixel_fogofwar_rect;
1952 pimg->pixel_border = pixel_border_rect;
1953
1954 pimg->base_coor = base_coor_rect;
1955 }
1956
1957 /* Here the map image is saved as an array of RGB color values. */
1958 pimg->map = fc_calloc(pimg->imgsize.x * pimg->imgsize.y,
1959 sizeof(*pimg->map));
1960 /* Initialise map. */
1961 memset(pimg->map, 0, pimg->imgsize.x * pimg->imgsize.y);
1962
1963 return pimg;
1964}
1965
1966/************************************************************************/
1969 static void img_destroy(struct img *pimg)
1970{
1971 if (pimg != NULL) {
1972 /* do not free pimg->def */
1973 free(pimg->map);
1974 free(pimg);
1975 }
1976}
1977
1978/************************************************************************/
1981 static inline void img_set_pixel(struct img *pimg, const int mindex,
1982 const struct rgbcolor *pcolor)
1983{
1984 if (mindex < 0 || mindex > pimg->imgsize.x * pimg->imgsize.y) {
1985 log_error("invalid index: 0 <= %d < %d", mindex,
1986 pimg->imgsize.x * pimg->imgsize.y);
1987 return;
1988 }
1989
1990 pimg->map[mindex] = pcolor;
1991}
1992
1993/************************************************************************/
1996 static inline int img_index(const int x, const int y,
1997 const struct img *pimg)
1998{
1999 fc_assert_ret_val(x >= 0 && x < pimg-> imgsize.x, -1);
2000 fc_assert_ret_val(y >= 0 && y < pimg-> imgsize.y, -1);
2001
2002 return pimg->imgsize.x * y + x;
2003}
2004
2005/************************************************************************/
2009 static void img_plot(struct img *pimg, int x, int y,
2010 const struct rgbcolor *pcolor, const bv_pixel pixel)
2011{
2012 int base_x, base_y, i, mindex;
2013
2014 if (!BV_ISSET_ANY(pixel)) {
2015 return;
2016 }
2017
2018 pimg->base_coor(pimg, &base_x, &base_y, x, y);
2019
2020 for (i = 0; i < NUM_PIXEL; i++) {
2021 if (BV_ISSET(pixel, i)) {
2022 mindex = img_index(base_x + pimg->tileshape->x[i],
2023 base_y + pimg->tileshape->y[i], pimg);
2024 img_set_pixel(pimg, mindex, pcolor);
2025 }
2026 }
2027}
2028
2029/************************************************************************/
2032 static void img_plot_tile(struct img *pimg, const struct tile *ptile,
2033 const struct rgbcolor *pcolor, const bv_pixel pixel)
2034{
2035 int x, y;
2036
2037 index_to_map_pos(&x, &y, tile_index(ptile));
2038
2039 img_plot(pimg, x, y, pcolor, pixel);
2040}
2041
2042/************************************************************************/
2045 static bool img_save(const struct img *pimg, const char *mapimgfile,
2046 const char *path)
2047{
2048 enum imagetool tool = pimg->def->tool;
2049 const struct toolkit *toolkit = img_toolkit_get(tool);
2050 char tmpname[600];
2051
2052 if (!toolkit) {
2053 MAPIMG_LOG(_("toolkit not defined"));
2054 return FALSE;
2055 }
2056
2057 if (!path_is_absolute(mapimgfile) && path != NULL && path[0] != '\0') {
2058 if (!make_dir(path)) {
2059 MAPIMG_LOG(_("can't create directory"));
2060 return FALSE;
2061 }
2062
2063 sz_strlcpy(tmpname, path);
2064 sz_strlcat(tmpname, "/");
2065 } else {
2066 tmpname[0] = '\0';
2067 }
2068
2069 sz_strlcat(tmpname, mapimgfile);
2070
2071 MAPIMG_ASSERT_RET_VAL(toolkit->img_save, FALSE);
2072
2073 return toolkit->img_save(pimg, tmpname);
2074}
2075
2076/************************************************************************/
2099#ifdef HAVE_MAPIMG_MAGICKWAND
2100#define SET_COLOR(str, pcolor) \
2101 fc_snprintf(str, sizeof(str), "rgb(%d,%d,%d)", \
2102 pcolor->r, pcolor->g, pcolor->b);
2103static bool img_save_magickwand(const struct img *pimg,
2104 const char *mapimgfile)
2105{
2106 const struct rgbcolor *pcolor = NULL;
2107 struct player *pplr_now = NULL, *pplr_only = NULL;
2108 bool ret = TRUE;
2109 char imagefile[MAX_LEN_PATH];
2110 char str_color[32], comment[2048] = "", title[258];
2111 magickwand_size_t img_width, img_height, map_width, map_height;
2112 int x, y, xxx, yyy, row, i, mindex, plrwidth, plroffset, textoffset;
2113 bool withplr = BV_ISSET_ANY(pimg->def->player.checked_plrbv);
2114
2115 if (!img_filename(mapimgfile, pimg->def->format, imagefile,
2116 sizeof(imagefile))) {
2117 MAPIMG_LOG(_("error generating the file name"));
2118 return FALSE;
2119 }
2120
2121 MagickWand *mw;
2122 PixelIterator *imw;
2123 PixelWand **pmw, *pw;
2124 DrawingWand *dw;
2125
2126 MagickWandGenesis();
2127
2128 mw = NewMagickWand();
2129 dw = NewDrawingWand();
2130 pw = NewPixelWand();
2131
2132 map_width = pimg->imgsize.x * pimg->def->zoom;
2133 map_height = pimg->imgsize.y * pimg->def->zoom;
2134
2135 img_width = map_width + 2 * IMG_BORDER_WIDTH;
2136 img_height = map_height + 2 * IMG_BORDER_HEIGHT + IMG_TEXT_HEIGHT
2137 + IMG_SPACER_HEIGHT + (withplr ? 2 * IMG_SPACER_HEIGHT : 0);
2138
2139 fc_snprintf(title, sizeof(title), "%s (%s)", pimg->title, mapimgfile);
2140
2141 SET_COLOR(str_color, imgcolor_special(IMGCOLOR_BACKGROUND));
2142 PixelSetColor(pw, str_color);
2143 MagickNewImage(mw, img_width, img_height, pw);
2144
2145 textoffset = 0;
2146 if (withplr) {
2147 if (bvplayers_count(pimg->def) == 1) {
2148 /* only one player */
2149 for (i = 0; i < player_slot_count(); i++) {
2150 if (BV_ISSET(pimg->def->player.checked_plrbv, i)) {
2151 pplr_only = player_by_number(i);
2152 break;
2153 }
2154 }
2155 }
2156
2157 if (pplr_only) {
2158 magickwand_size_t plr_color_square = IMG_TEXT_HEIGHT;
2159
2160 textoffset += IMG_TEXT_HEIGHT + IMG_BORDER_HEIGHT;
2161
2162 pcolor = imgcolor_player(player_index(pplr_only));
2163 SET_COLOR(str_color, pcolor);
2164
2165 /* Show the color of the selected player. */
2166 imw = NewPixelRegionIterator(mw, IMG_BORDER_WIDTH, IMG_BORDER_HEIGHT,
2167 IMG_TEXT_HEIGHT, IMG_TEXT_HEIGHT);
2168 /* y coordinate */
2169 for (y = 0; y < IMG_TEXT_HEIGHT; y++) {
2170 pmw = PixelGetNextIteratorRow(imw, &plr_color_square);
2171 /* x coordinate */
2172 for (x = 0; x < IMG_TEXT_HEIGHT; x++) {
2173 PixelSetColor(pmw[x], str_color);
2174 }
2175 PixelSyncIterator(imw);
2176 }
2177 DestroyPixelIterator(imw);
2178 }
2179
2180 /* Show a line displaying the colors of alive players */
2181 plrwidth = map_width / MIN(map_width, player_count());
2182 plroffset = (map_width - MIN(map_width, plrwidth * player_count())) / 2;
2183
2184 imw = NewPixelRegionIterator(mw, IMG_BORDER_WIDTH,
2185 IMG_BORDER_HEIGHT + IMG_TEXT_HEIGHT
2186 + IMG_SPACER_HEIGHT, map_width,
2187 IMG_LINE_HEIGHT);
2188 /* y coordinate */
2189 for (y = 0; y < IMG_LINE_HEIGHT; y++) {
2190 pmw = PixelGetNextIteratorRow(imw, &map_width);
2191
2192 /* x coordinate */
2193 for (x = plroffset; x < map_width; x++) {
2194 i = (x - plroffset) / plrwidth;
2195 pplr_now = player_by_number(i);
2196
2197 if (i > player_count() || pplr_now == NULL || !pplr_now->is_alive) {
2198 continue;
2199 }
2200
2201 if (BV_ISSET(pimg->def->player.checked_plrbv, i)) {
2202 /* The selected player is alive - display it. */
2203 pcolor = imgcolor_player(i);
2204 SET_COLOR(str_color, pcolor);
2205 PixelSetColor(pmw[x], str_color);
2206 } else if (pplr_only != NULL) {
2207 /* Display the state between pplr_only and pplr_now:
2208 * - if allied:
2209 * - show each second pixel
2210 * - if pplr_now does shares map with pplr_onlyus:
2211 * - show every other line of pixels
2212 * This results in the following patterns (# = color):
2213 * ###### # # # ######
2214 * # # # # # #
2215 * ###### # # # ######
2216 * # # # # # #
2217 * shared allied shared vision
2218 * vision + allied */
2219 if ((pplayers_allied(pplr_now, pplr_only) && (x + y) % 2 == 0)
2220 || (y % 2 == 0 && gives_shared_vision(pplr_now, pplr_only))) {
2221 pcolor = imgcolor_player(i);
2222 SET_COLOR(str_color, pcolor);
2223 PixelSetColor(pmw[x], str_color);
2224 }
2225 }
2226 }
2227 PixelSyncIterator(imw);
2228 }
2229 DestroyPixelIterator(imw);
2230 }
2231
2232 /* Display the image name. */
2233 SET_COLOR(str_color, imgcolor_special(IMGCOLOR_TEXT));
2234 PixelSetColor(pw, str_color);
2235 DrawSetFillColor(dw, pw);
2236 DrawSetFont(dw, "Times-New-Roman");
2237 DrawSetFontSize(dw, IMG_TEXT_HEIGHT);
2238 DrawAnnotation(dw, IMG_BORDER_WIDTH + textoffset,
2239 IMG_TEXT_HEIGHT + IMG_BORDER_HEIGHT,
2240 (unsigned char *)title);
2241 MagickDrawImage(mw, dw);
2242
2243 /* Display the map. */
2244 imw = NewPixelRegionIterator(mw, IMG_BORDER_WIDTH,
2245 IMG_BORDER_HEIGHT + IMG_TEXT_HEIGHT
2246 + IMG_SPACER_HEIGHT
2247 + (withplr ? (IMG_LINE_HEIGHT + IMG_SPACER_HEIGHT)
2248 : 0), map_width, map_height);
2249 /* y coordinate */
2250 for (y = 0; y < pimg->imgsize.y; y++) {
2251 /* zoom for y */
2252 for (yyy = 0; yyy < pimg->def->zoom; yyy++) {
2253
2254 pmw = PixelGetNextIteratorRow(imw, &map_width);
2255
2256 /* x coordinate */
2257 for (x = 0; x < pimg->imgsize.x; x++) {
2258 mindex = img_index(x, y, pimg);
2259 pcolor = pimg->map[mindex];
2260
2261 if (pcolor != NULL) {
2262 SET_COLOR(str_color, pcolor);
2263
2264 /* zoom for x */
2265 for (xxx = 0; xxx < pimg->def->zoom; xxx++) {
2266 row = x * pimg->def->zoom + xxx;
2267 PixelSetColor(pmw[row], str_color);
2268 }
2269 }
2270 }
2271 PixelSyncIterator(imw);
2272 }
2273 }
2274 DestroyPixelIterator(imw);
2275
2276 cat_snprintf(comment, sizeof(comment), "map definition: %s\n",
2277 pimg->def->maparg);
2278 if (BV_ISSET_ANY(pimg->def->player.checked_plrbv)) {
2279 players_iterate(pplayer) {
2280 if (!BV_ISSET(pimg->def->player.checked_plrbv, player_index(pplayer))) {
2281 continue;
2282 }
2283
2284 cat_snprintf(comment, sizeof(comment), "%s\n", img_playerstr(pplayer));
2285 } players_iterate_end;
2286 }
2287 MagickCommentImage(mw, comment);
2288
2289 if (!MagickWriteImage(mw, imagefile)) {
2290 MAPIMG_LOG(_("error saving map image '%s'"), imagefile);
2291 ret = FALSE;
2292 } else {
2293 log_verbose("Map image saved as '%s'.", imagefile);
2294 }
2295
2296 DestroyDrawingWand(dw);
2297 DestroyPixelWand(pw);
2298 DestroyMagickWand(mw);
2299
2300 MagickWandTerminus();
2301
2302 return ret;
2303}
2304#undef SET_COLOR
2305#endif /* HAVE_MAPIMG_MAGICKWAND */
2306
2307/************************************************************************/
2310 static bool img_save_ppm(const struct img *pimg, const char *mapimgfile)
2311{
2312 char ppmname[MAX_LEN_PATH];
2313 FILE *fp;
2314 int x, y, xxx, yyy, mindex;
2315 const struct rgbcolor *pcolor;
2316
2317 if (pimg->def->format != IMGFORMAT_PPM) {
2318 MAPIMG_LOG(_("the ppm toolkit can only create images in the ppm "
2319 "format"));
2320 return FALSE;
2321 }
2322
2323 if (!img_filename(mapimgfile, IMGFORMAT_PPM, ppmname, sizeof(ppmname))) {
2324 MAPIMG_LOG(_("error generating the file name"));
2325 return FALSE;
2326 }
2327
2328 fp = fc_fopen(ppmname, "w");
2329 if (!fp) {
2330 MAPIMG_LOG(_("could not open file: %s"), ppmname);
2331 return FALSE;
2332 }
2333
2334 fprintf(fp, "P3\n");
2335 fprintf(fp, "# version:2\n");
2336 fprintf(fp, "# map definition: %s\n", pimg->def->maparg);
2337
2338 if (pimg->def->colortest) {
2339 fprintf(fp, "# color test\n");
2340 } else if (BV_ISSET_ANY(pimg->def->player.checked_plrbv)) {
2341 players_iterate(pplayer) {
2342 if (!BV_ISSET(pimg->def->player.checked_plrbv, player_index(pplayer))) {
2343 continue;
2344 }
2345
2346 fprintf(fp, "# %s\n", img_playerstr(pplayer));
2347 } players_iterate_end;
2348 } else {
2349 fprintf(fp, "# no players\n");
2350 }
2351
2352 fprintf(fp, "%d %d\n", pimg->imgsize.x * pimg->def->zoom,
2353 pimg->imgsize.y * pimg->def->zoom);
2354 fprintf(fp, "255\n");
2355
2356 /* y coordinate */
2357 for (y = 0; y < pimg->imgsize.y; y++) {
2358 /* zoom for y */
2359 for (yyy = 0; yyy < pimg->def->zoom; yyy++) {
2360 /* x coordinate */
2361 for (x = 0; x < pimg->imgsize.x; x++) {
2362 mindex = img_index(x, y, pimg);
2363 pcolor = pimg->map[mindex];
2364
2365 /* zoom for x */
2366 for (xxx = 0; xxx < pimg->def->zoom; xxx++) {
2367 if (pcolor == NULL) {
2368 pcolor = imgcolor_special(IMGCOLOR_BACKGROUND);
2369 }
2370 fprintf(fp, "%d %d %d\n", pcolor->r, pcolor->g, pcolor->b);
2371 }
2372 }
2373 }
2374 }
2375
2376 log_verbose("Map image saved as '%s'.", ppmname);
2377 fclose(fp);
2378
2379 return TRUE;
2380}
2381
2382/************************************************************************/
2385 static bool img_filename(const char *mapimgfile, enum imageformat format,
2386 char *filename, size_t filename_len)
2387{
2388 fc_assert_ret_val(imageformat_is_valid(format) , FALSE);
2389
2390 fc_snprintf(filename, filename_len, "%s.map.%s", mapimgfile,
2391 imageformat_name(format));
2392
2393 return TRUE;
2394}
2395
2396/************************************************************************/
2399 static const char *img_playerstr(const struct player *pplayer)
2400{
2401 static char buf[512];
2402 const struct rgbcolor *pcolor = imgcolor_player(player_index(pplayer));
2403
2404 fc_snprintf(buf, sizeof(buf),
2405 "playerno:%d:color:(%3d, %3d, %3d):name:\"%s\"",
2406 player_number(pplayer), pcolor->r, pcolor->g, pcolor->b,
2407 player_name(pplayer));
2408
2409 return buf;
2410}
2411
2412/************************************************************************/
2416 static void img_createmap(struct img *pimg)
2417{
2418 const struct rgbcolor *pcolor;
2419 bv_pixel pixel;
2420 int player_id;
2421 struct player *pplayer = NULL;
2422 struct player *plr_tile = NULL, *plr_city = NULL, *plr_unit = NULL;
2423 enum known_type tile_knowledge = TILE_UNKNOWN;
2424 struct terrain *pterrain = NULL;
2425 bool plr_knowledge = pimg->def->layers[MAPIMG_LAYER_KNOWLEDGE];
2426
2427 whole_map_iterate(&(wld.map), ptile) {
2428 if (bvplayers_count(pimg->def) == 1) {
2429 /* only one player; get player id for 'known' and 'fogofwar' */
2430 players_iterate(aplayer) {
2431 if (BV_ISSET(pimg->def->player.checked_plrbv,
2432 player_index(aplayer))) {
2433 pplayer = aplayer;
2434 tile_knowledge = mapimg.mapimg_tile_known(ptile, pplayer,
2435 plr_knowledge);
2436 break;
2437 }
2438 } players_iterate_end;
2439 }
2440
2441 /* known tiles */
2442 if (plr_knowledge && pplayer != NULL && tile_knowledge == TILE_UNKNOWN) {
2443 /* plot nothing iff tile is not known */
2444 continue;
2445 }
2446
2447 /* terrain */
2448 pterrain = mapimg.mapimg_tile_terrain(ptile, pplayer, plr_knowledge);
2449 if (pimg->def->layers[MAPIMG_LAYER_TERRAIN]) {
2450 /* full terrain */
2451 pixel = pimg->pixel_tile(ptile, pplayer, plr_knowledge);
2452 pcolor = imgcolor_terrain(pterrain);
2453 img_plot_tile(pimg, ptile, pcolor, pixel);
2454 } else {
2455 /* basic terrain */
2456 pixel = pimg->pixel_tile(ptile, pplayer, plr_knowledge);
2457 if (is_ocean(pterrain)) {
2458 img_plot_tile(pimg, ptile, imgcolor_special(IMGCOLOR_OCEAN), pixel);
2459 } else {
2460 img_plot_tile(pimg, ptile, imgcolor_special(IMGCOLOR_GROUND), pixel);
2461 }
2462 }
2463
2464 /* (land) area within borders and borders */
2465 plr_tile = mapimg.mapimg_tile_owner(ptile, pplayer, plr_knowledge);
2466 if (game.info.borders > 0 && NULL != plr_tile) {
2467 player_id = player_index(plr_tile);
2468 if (pimg->def->layers[MAPIMG_LAYER_AREA] && !is_ocean(pterrain)
2469 && BV_ISSET(pimg->def->player.checked_plrbv, player_id)) {
2470 /* the tile is land and inside the players borders */
2471 pixel = pimg->pixel_tile(ptile, pplayer, plr_knowledge);
2472 pcolor = imgcolor_player(player_id);
2473 img_plot_tile(pimg, ptile, pcolor, pixel);
2474 } else if (pimg->def->layers[MAPIMG_LAYER_BORDERS]
2475 && (BV_ISSET(pimg->def->player.checked_plrbv, player_id)
2476 || (plr_knowledge && pplayer != NULL))) {
2477 /* plot borders if player is selected or view range of the one
2478 * displayed player */
2479 pixel = pimg->pixel_border(ptile, pplayer, plr_knowledge);
2480 pcolor = imgcolor_player(player_id);
2481 img_plot_tile(pimg, ptile, pcolor, pixel);
2482 }
2483 }
2484
2485 /* cities and units */
2486 plr_city = mapimg.mapimg_tile_city(ptile, pplayer, plr_knowledge);
2487 plr_unit = mapimg.mapimg_tile_unit(ptile, pplayer, plr_knowledge);
2488 if (pimg->def->layers[MAPIMG_LAYER_CITIES] && plr_city) {
2489 player_id = player_index(plr_city);
2490 if (BV_ISSET(pimg->def->player.checked_plrbv, player_id)
2491 || (plr_knowledge && pplayer != NULL)) {
2492 /* plot cities if player is selected or view range of the one
2493 * displayed player */
2494 pixel = pimg->pixel_city(ptile, pplayer, plr_knowledge);
2495 pcolor = imgcolor_player(player_id);
2496 img_plot_tile(pimg, ptile, pcolor, pixel);
2497 }
2498 } else if (pimg->def->layers[MAPIMG_LAYER_UNITS] && plr_unit) {
2499 player_id = player_index(plr_unit);
2500 if (BV_ISSET(pimg->def->player.checked_plrbv, player_id)
2501 || (plr_knowledge && pplayer != NULL)) {
2502 /* plot units if player is selected or view range of the one
2503 * displayed player */
2504 pixel = pimg->pixel_unit(ptile, pplayer, plr_knowledge);
2505 pcolor = imgcolor_player(player_id);
2506 img_plot_tile(pimg, ptile, pcolor, pixel);
2507 }
2508 }
2509
2510 /* fogofwar; if only 1 player is plotted */
2511 if (game.info.fogofwar && pimg->def->layers[MAPIMG_LAYER_FOGOFWAR]
2512 && pplayer != NULL
2513 && tile_knowledge == TILE_KNOWN_UNSEEN) {
2514 pixel = pimg->pixel_fogofwar(ptile, pplayer, plr_knowledge);
2515 pcolor = NULL;
2516 img_plot_tile(pimg, ptile, pcolor, pixel);
2517 }
2518 } whole_map_iterate_end;
2519}
2520
2521/*
2522 * ==============================================
2523 * topology (internal functions)
2524 * ==============================================
2525 * With these functions the pixels corresponding to the different elements
2526 * (tile, city, unit) for each map topology are defined.
2527 *
2528 * The bv_pixel_fogofwar_*() functions are special as they defines where
2529 * the color should be removed.
2530 *
2531 * The functions for a rectangular and an isometric rectangular topology
2532 * are identical.
2533 */
2534
2535/************************************************************************/
2543 static bv_pixel pixel_tile_rect(const struct tile *ptile,
2544 const struct player *pplayer,
2545 bool knowledge)
2546{
2547 bv_pixel pixel;
2548
2549 BV_SET_ALL(pixel);
2550
2551 return pixel;
2552}
2553
2554/************************************************************************/
2562 static bv_pixel pixel_city_rect(const struct tile *ptile,
2563 const struct player *pplayer,
2564 bool knowledge)
2565{
2566 bv_pixel pixel;
2567
2568 BV_CLR_ALL(pixel);
2569 BV_SET(pixel, 7);
2570 BV_SET(pixel, 8);
2571 BV_SET(pixel, 9);
2572 BV_SET(pixel, 10);
2573 BV_SET(pixel, 13);
2574 BV_SET(pixel, 14);
2575 BV_SET(pixel, 15);
2576 BV_SET(pixel, 16);
2577 BV_SET(pixel, 19);
2578 BV_SET(pixel, 20);
2579 BV_SET(pixel, 21);
2580 BV_SET(pixel, 22);
2581 BV_SET(pixel, 21);
2582 BV_SET(pixel, 25);
2583 BV_SET(pixel, 26);
2584 BV_SET(pixel, 27);
2585 BV_SET(pixel, 28);
2586
2587 return pixel;
2588}
2589
2590/************************************************************************/
2598 static bv_pixel pixel_unit_rect(const struct tile *ptile,
2599 const struct player *pplayer,
2600 bool knowledge)
2601{
2602 bv_pixel pixel;
2603
2604 BV_CLR_ALL(pixel);
2605 BV_SET(pixel, 14);
2606 BV_SET(pixel, 15);
2607 BV_SET(pixel, 20);
2608 BV_SET(pixel, 21);
2609
2610 return pixel;
2611}
2612
2613/************************************************************************/
2621 static bv_pixel pixel_fogofwar_rect(const struct tile *ptile,
2622 const struct player *pplayer,
2623 bool knowledge)
2624{
2625 bv_pixel pixel;
2626
2627 BV_CLR_ALL(pixel);
2628
2629 BV_SET(pixel, 0);
2630 BV_SET(pixel, 2);
2631 BV_SET(pixel, 4);
2632 BV_SET(pixel, 7);
2633 BV_SET(pixel, 9);
2634 BV_SET(pixel, 11);
2635 BV_SET(pixel, 12);
2636 BV_SET(pixel, 14);
2637 BV_SET(pixel, 16);
2638 BV_SET(pixel, 19);
2639 BV_SET(pixel, 21);
2640 BV_SET(pixel, 23);
2641 BV_SET(pixel, 24);
2642 BV_SET(pixel, 26);
2643 BV_SET(pixel, 28);
2644 BV_SET(pixel, 31);
2645 BV_SET(pixel, 33);
2646 BV_SET(pixel, 35);
2647
2648 return pixel;
2649}
2650
2651/************************************************************************/
2663 static bv_pixel pixel_border_rect(const struct tile *ptile,
2664 const struct player *pplayer,
2665 bool knowledge)
2666{
2667 bv_pixel pixel;
2668 struct tile *pnext;
2669 struct player *owner;
2670
2671 BV_CLR_ALL(pixel);
2672
2673 fc_assert_ret_val(ptile != NULL, pixel);
2674
2675 if (NULL == ptile) {
2676 /* no tile */
2677 return pixel;
2678 }
2679
2680 owner = mapimg.mapimg_tile_owner(ptile, pplayer, knowledge);
2681 if (NULL == owner) {
2682 /* no border */
2683 return pixel;
2684 }
2685
2686 pnext = mapstep(&(wld.map), ptile, DIR8_NORTH);
2687 if (!pnext || (mapimg.mapimg_tile_known(pnext, pplayer,
2688 knowledge) != TILE_UNKNOWN
2689 && mapimg.mapimg_tile_owner(pnext, pplayer,
2690 knowledge) != owner)) {
2691 BV_SET(pixel, 0);
2692 BV_SET(pixel, 1);
2693 BV_SET(pixel, 2);
2694 BV_SET(pixel, 3);
2695 BV_SET(pixel, 4);
2696 BV_SET(pixel, 5);
2697 }
2698
2699 pnext = mapstep(&(wld.map), ptile, DIR8_EAST);
2700 if (!pnext || (mapimg.mapimg_tile_known(pnext, pplayer,
2701 knowledge) != TILE_UNKNOWN
2702 && mapimg.mapimg_tile_owner(pnext, pplayer,
2703 knowledge) != owner)) {
2704 BV_SET(pixel, 5);
2705 BV_SET(pixel, 11);
2706 BV_SET(pixel, 17);
2707 BV_SET(pixel, 23);
2708 BV_SET(pixel, 29);
2709 BV_SET(pixel, 35);
2710 }
2711
2712 pnext = mapstep(&(wld.map), ptile, DIR8_SOUTH);
2713 if (!pnext || (mapimg.mapimg_tile_known(pnext, pplayer,
2714 knowledge) != TILE_UNKNOWN
2715 && mapimg.mapimg_tile_owner(pnext, pplayer,
2716 knowledge) != owner)) {
2717 BV_SET(pixel, 30);
2718 BV_SET(pixel, 31);
2719 BV_SET(pixel, 32);
2720 BV_SET(pixel, 33);
2721 BV_SET(pixel, 34);
2722 BV_SET(pixel, 35);
2723 }
2724
2725 pnext = mapstep(&(wld.map), ptile, DIR8_WEST);
2726 if (!pnext || (mapimg.mapimg_tile_known(pnext, pplayer,
2727 knowledge) != TILE_UNKNOWN
2728 && mapimg.mapimg_tile_owner(pnext, pplayer,
2729 knowledge) != owner)) {
2730 BV_SET(pixel, 0);
2731 BV_SET(pixel, 6);
2732 BV_SET(pixel, 12);
2733 BV_SET(pixel, 18);
2734 BV_SET(pixel, 24);
2735 BV_SET(pixel, 30);
2736 }
2737
2738 return pixel;
2739}
2740
2741/************************************************************************/
2744 static void base_coor_rect(struct img *pimg, int *base_x, int *base_y,
2745 int x, int y)
2746{
2747 *base_x = x * TILE_SIZE;
2748 *base_y = y * TILE_SIZE;
2749}
2750
2751/************************************************************************/
2761 static bv_pixel pixel_tile_hexa(const struct tile *ptile,
2762 const struct player *pplayer,
2763 bool knowledge)
2764{
2765 bv_pixel pixel;
2766
2767 BV_SET_ALL(pixel);
2768
2769 return pixel;
2770}
2771
2772/************************************************************************/
2782 static bv_pixel pixel_city_hexa(const struct tile *ptile,
2783 const struct player *pplayer,
2784 bool knowledge)
2785{
2786 bv_pixel pixel;
2787
2788 BV_CLR_ALL(pixel);
2789 BV_SET(pixel, 3);
2790 BV_SET(pixel, 4);
2791 BV_SET(pixel, 7);
2792 BV_SET(pixel, 8);
2793 BV_SET(pixel, 9);
2794 BV_SET(pixel, 10);
2795 BV_SET(pixel, 13);
2796 BV_SET(pixel, 14);
2797 BV_SET(pixel, 15);
2798 BV_SET(pixel, 16);
2799 BV_SET(pixel, 19);
2800 BV_SET(pixel, 20);
2801 BV_SET(pixel, 21);
2802 BV_SET(pixel, 22);
2803 BV_SET(pixel, 25);
2804 BV_SET(pixel, 26);
2805 BV_SET(pixel, 27);
2806 BV_SET(pixel, 28);
2807 BV_SET(pixel, 31);
2808 BV_SET(pixel, 32);
2809
2810 return pixel;
2811}
2812
2813/************************************************************************/
2823 static bv_pixel pixel_unit_hexa(const struct tile *ptile,
2824 const struct player *pplayer,
2825 bool knowledge)
2826{
2827 bv_pixel pixel;
2828
2829 BV_CLR_ALL(pixel);
2830 BV_SET(pixel, 14);
2831 BV_SET(pixel, 15);
2832 BV_SET(pixel, 20);
2833 BV_SET(pixel, 21);
2834
2835 return pixel;
2836}
2837
2838/************************************************************************/
2848 static bv_pixel pixel_fogofwar_hexa(const struct tile *ptile,
2849 const struct player *pplayer,
2850 bool knowledge)
2851{
2852 bv_pixel pixel;
2853
2854 BV_CLR_ALL(pixel);
2855 BV_SET(pixel, 0);
2856 BV_SET(pixel, 3);
2857 BV_SET(pixel, 5);
2858 BV_SET(pixel, 7);
2859 BV_SET(pixel, 9);
2860 BV_SET(pixel, 11);
2861 BV_SET(pixel, 13);
2862 BV_SET(pixel, 15);
2863 BV_SET(pixel, 17);
2864 BV_SET(pixel, 18);
2865 BV_SET(pixel, 20);
2866 BV_SET(pixel, 22);
2867 BV_SET(pixel, 24);
2868 BV_SET(pixel, 26);
2869 BV_SET(pixel, 28);
2870 BV_SET(pixel, 30);
2871 BV_SET(pixel, 32);
2872 BV_SET(pixel, 35);
2873
2874 return pixel;
2875}
2876
2877/************************************************************************/
2887 static bv_pixel pixel_border_hexa(const struct tile *ptile,
2888 const struct player *pplayer,
2889 bool knowledge)
2890{
2891 bv_pixel pixel;
2892 struct tile *pnext;
2893 struct player *owner;
2894
2895 BV_CLR_ALL(pixel);
2896
2897 fc_assert_ret_val(ptile != NULL, pixel);
2898
2899 if (NULL == ptile) {
2900 /* no tile */
2901 return pixel;
2902 }
2903
2904 owner = mapimg.mapimg_tile_owner(ptile, pplayer, knowledge);
2905 if (NULL == owner) {
2906 /* no border */
2907 return pixel;
2908 }
2909
2910 pnext = mapstep(&(wld.map), ptile, DIR8_WEST);
2911 if (!pnext || (mapimg.mapimg_tile_known(pnext, pplayer,
2912 knowledge) != TILE_UNKNOWN
2913 && mapimg.mapimg_tile_owner(pnext, pplayer,
2914 knowledge) != owner)) {
2915 BV_SET(pixel, 0);
2916 BV_SET(pixel, 2);
2917 BV_SET(pixel, 6);
2918 }
2919
2920 /* not used: DIR8_NORTHWEST */
2921
2922 pnext = mapstep(&(wld.map), ptile, DIR8_NORTH);
2923 if (!pnext || (mapimg.mapimg_tile_known(pnext, pplayer,
2924 knowledge) != TILE_UNKNOWN
2925 && mapimg.mapimg_tile_owner(pnext, pplayer,
2926 knowledge) != owner)) {
2927 BV_SET(pixel, 1);
2928 BV_SET(pixel, 5);
2929 BV_SET(pixel, 11);
2930 }
2931
2932 pnext = mapstep(&(wld.map), ptile, DIR8_NORTHEAST);
2933 if (!pnext || (mapimg.mapimg_tile_known(pnext, pplayer,
2934 knowledge) != TILE_UNKNOWN
2935 && mapimg.mapimg_tile_owner(pnext, pplayer,
2936 knowledge) != owner)) {
2937 BV_SET(pixel, 11);
2938 BV_SET(pixel, 17);
2939 BV_SET(pixel, 23);
2940 BV_SET(pixel, 29);
2941 }
2942
2943 pnext = mapstep(&(wld.map), ptile, DIR8_EAST);
2944 if (!pnext || (mapimg.mapimg_tile_known(pnext, pplayer,
2945 knowledge) != TILE_UNKNOWN
2946 && mapimg.mapimg_tile_owner(pnext, pplayer,
2947 knowledge) != owner)) {
2948 BV_SET(pixel, 29);
2949 BV_SET(pixel, 33);
2950 BV_SET(pixel, 35);
2951 }
2952
2953 /* not used. DIR8_SOUTHEAST */
2954
2955 pnext = mapstep(&(wld.map), ptile, DIR8_SOUTH);
2956 if (!pnext || (mapimg.mapimg_tile_known(pnext, pplayer,
2957 knowledge) != TILE_UNKNOWN
2958 && mapimg.mapimg_tile_owner(pnext, pplayer,
2959 knowledge) != owner)) {
2960 BV_SET(pixel, 24);
2961 BV_SET(pixel, 30);
2962 BV_SET(pixel, 34);
2963 }
2964
2965 pnext = mapstep(&(wld.map), ptile, DIR8_SOUTHWEST);
2966 if (!pnext || (mapimg.mapimg_tile_known(pnext, pplayer,
2967 knowledge) != TILE_UNKNOWN
2968 && mapimg.mapimg_tile_owner(pnext, pplayer,
2969 knowledge) != owner)) {
2970 BV_SET(pixel, 6);
2971 BV_SET(pixel, 12);
2972 BV_SET(pixel, 18);
2973 BV_SET(pixel, 24);
2974 }
2975
2976 return pixel;
2977}
2978
2979/************************************************************************/
2982 static void base_coor_hexa(struct img *pimg, int *base_x, int *base_y,
2983 int x, int y)
2984{
2985 int nat_x, nat_y;
2986 MAP_TO_NATIVE_POS(&nat_x, &nat_y, x, y);
2987
2988 *base_x = nat_x * TILE_SIZE + ((nat_y % 2) ? TILE_SIZE / 2 : 0);
2989 *base_y = nat_y * TILE_SIZE;
2990}
2991
2992/************************************************************************/
3000 static bv_pixel pixel_tile_isohexa(const struct tile *ptile,
3001 const struct player *pplayer,
3002 bool knowledge)
3003{
3004 bv_pixel pixel;
3005
3006 BV_SET_ALL(pixel);
3007
3008 return pixel;
3009}
3010
3011/************************************************************************/
3019 static bv_pixel pixel_city_isohexa(const struct tile *ptile,
3020 const struct player *pplayer,
3021 bool knowledge)
3022{
3023 bv_pixel pixel;
3024
3025 BV_CLR_ALL(pixel);
3026 BV_SET(pixel, 5);
3027 BV_SET(pixel, 6);
3028 BV_SET(pixel, 7);
3029 BV_SET(pixel, 8);
3030 BV_SET(pixel, 11);
3031 BV_SET(pixel, 12);
3032 BV_SET(pixel, 13);
3033 BV_SET(pixel, 14);
3034 BV_SET(pixel, 15);
3035 BV_SET(pixel, 16);
3036 BV_SET(pixel, 19);
3037 BV_SET(pixel, 20);
3038 BV_SET(pixel, 21);
3039 BV_SET(pixel, 22);
3040 BV_SET(pixel, 23);
3041 BV_SET(pixel, 24);
3042 BV_SET(pixel, 27);
3043 BV_SET(pixel, 28);
3044 BV_SET(pixel, 29);
3045 BV_SET(pixel, 30);
3046
3047 return pixel;
3048}
3049
3050/************************************************************************/
3058 static bv_pixel pixel_unit_isohexa(const struct tile *ptile,
3059 const struct player *pplayer,
3060 bool knowledge)
3061{
3062 bv_pixel pixel;
3063
3064 BV_CLR_ALL(pixel);
3065 BV_SET(pixel, 13);
3066 BV_SET(pixel, 14);
3067 BV_SET(pixel, 21);
3068 BV_SET(pixel, 22);
3069
3070 return pixel;
3071}
3072
3073/************************************************************************/
3081 static bv_pixel pixel_fogofwar_isohexa(const struct tile *ptile,
3082 const struct player *pplayer,
3083 bool knowledge)
3084{
3085 bv_pixel pixel;
3086
3087 BV_CLR_ALL(pixel);
3088 BV_SET(pixel, 0);
3089 BV_SET(pixel, 1);
3090 BV_SET(pixel, 4);
3091 BV_SET(pixel, 7);
3092 BV_SET(pixel, 8);
3093 BV_SET(pixel, 12);
3094 BV_SET(pixel, 13);
3095 BV_SET(pixel, 16);
3096 BV_SET(pixel, 17);
3097 BV_SET(pixel, 18);
3098 BV_SET(pixel, 19);
3099 BV_SET(pixel, 22);
3100 BV_SET(pixel, 23);
3101 BV_SET(pixel, 27);
3102 BV_SET(pixel, 28);
3103 BV_SET(pixel, 31);
3104 BV_SET(pixel, 34);
3105 BV_SET(pixel, 35);
3106
3107 return pixel;
3108}
3109
3110/************************************************************************/
3123 static bv_pixel pixel_border_isohexa(const struct tile *ptile,
3124 const struct player *pplayer,
3125 bool knowledge)
3126{
3127 bv_pixel pixel;
3128 struct tile *pnext;
3129 struct player *owner;
3130
3131 BV_CLR_ALL(pixel);
3132
3133 fc_assert_ret_val(ptile != NULL, pixel);
3134
3135 if (NULL == ptile) {
3136 /* no tile */
3137 return pixel;
3138 }
3139
3140 owner = mapimg.mapimg_tile_owner(ptile, pplayer, knowledge);
3141 if (NULL == owner) {
3142 /* no border */
3143 return pixel;
3144 }
3145
3146 pnext = mapstep(&(wld.map), ptile, DIR8_NORTH);
3147 if (!pnext || (mapimg.mapimg_tile_known(pnext, pplayer,
3148 knowledge) != TILE_UNKNOWN
3149 && mapimg.mapimg_tile_owner(pnext, pplayer,
3150 knowledge) != owner)) {
3151 BV_SET(pixel, 0);
3152 BV_SET(pixel, 1);
3153 BV_SET(pixel, 2);
3154 BV_SET(pixel, 3);
3155 }
3156
3157 /* not used: DIR8_NORTHEAST */
3158
3159 pnext = mapstep(&(wld.map), ptile, DIR8_EAST);
3160 if (!pnext || (mapimg.mapimg_tile_known(pnext, pplayer,
3161 knowledge) != TILE_UNKNOWN
3162 && mapimg.mapimg_tile_owner(pnext, pplayer,
3163 knowledge) != owner)) {
3164 BV_SET(pixel, 3);
3165 BV_SET(pixel, 9);
3166 BV_SET(pixel, 17);
3167 }
3168
3169 pnext = mapstep(&(wld.map), ptile, DIR8_SOUTHEAST);
3170 if (!pnext || (mapimg.mapimg_tile_known(pnext, pplayer,
3171 knowledge) != TILE_UNKNOWN
3172 && mapimg.mapimg_tile_owner(pnext, pplayer,
3173 knowledge) != owner)) {
3174 BV_SET(pixel, 25);
3175 BV_SET(pixel, 31);
3176 BV_SET(pixel, 35);
3177 }
3178
3179 pnext = mapstep(&(wld.map), ptile, DIR8_SOUTH);
3180 if (!pnext || (mapimg.mapimg_tile_known(pnext, pplayer,
3181 knowledge) != TILE_UNKNOWN
3182 && mapimg.mapimg_tile_owner(pnext, pplayer,
3183 knowledge) != owner)) {
3184 BV_SET(pixel, 32);
3185 BV_SET(pixel, 33);
3186 BV_SET(pixel, 34);
3187 BV_SET(pixel, 35);
3188 }
3189
3190 /* not used: DIR8_SOUTHWEST */
3191
3192 pnext = mapstep(&(wld.map), ptile, DIR8_WEST);
3193 if (!pnext || (mapimg.mapimg_tile_known(pnext, pplayer,
3194 knowledge) != TILE_UNKNOWN
3195 && mapimg.mapimg_tile_owner(pnext, pplayer,
3196 knowledge) != owner)) {
3197 BV_SET(pixel, 18);
3198 BV_SET(pixel, 26);
3199 BV_SET(pixel, 32);
3200 }
3201
3202 pnext = mapstep(&(wld.map), ptile, DIR8_NORTHWEST);
3203 if (!pnext || (mapimg.mapimg_tile_known(pnext, pplayer,
3204 knowledge) != TILE_UNKNOWN
3205 && mapimg.mapimg_tile_owner(pnext, pplayer,
3206 knowledge) != owner)) {
3207 BV_SET(pixel, 0);
3208 BV_SET(pixel, 4);
3209 BV_SET(pixel, 10);
3210 }
3211
3212 return pixel;
3213}
3214
3215/************************************************************************/
3218 static void base_coor_isohexa(struct img *pimg, int *base_x, int *base_y,
3219 int x, int y)
3220{
3221 /* magic for iso-hexa */
3222 y -= x / 2;
3223 y += (pimg->mapsize.x - 1)/2;
3224
3225 *base_x = x * TILE_SIZE;
3226 *base_y = y * TILE_SIZE + ((x % 2) ? 0 : TILE_SIZE / 2);
3227}
3228
3229/*
3230 * ==============================================
3231 * additional functions (internal functions)
3232 * ==============================================
3233 */
3234
3235/************************************************************************/
3238 static const char *bvplayers_str(const bv_player plrbv)
3239{
3240 static char buf[MAX_NUM_PLAYER_SLOTS + 1];
3241 int i;
3242
3243 /* Don't print lots of unnecessary trailing zeroes */
3244 for (i = MAX_NUM_PLAYER_SLOTS-1; i >= 0; i--) {
3245 if (BV_ISSET(plrbv, i) || player_by_number(i)) {
3246 buf[i+1] = '\0';
3247 break;
3248 }
3249 }
3250
3251 for (; i >= 0; i--) {
3252 buf[i] = BV_ISSET(plrbv, i) ? '1' : '0';
3253 }
3254
3255 return buf;
3256}
3257
3258/************************************************************************/
3261 static int bvplayers_count(const struct mapdef *pmapdef)
3262{
3263 int i, count = 0;
3264
3265 switch (pmapdef->player.show) {
3266 case SHOW_NONE: /* no player on the map */
3267 count = 0;
3268 break;
3269 case SHOW_HUMAN: /* one map for each human player */
3270 case SHOW_EACH: /* one map for each player */
3271 case SHOW_PLRNAME: /* the map of one selected player */
3272 case SHOW_PLRID:
3273 count = 1;
3274 break;
3275 case SHOW_PLRBV: /* map showing only players given by a bitvector */
3276 count = 0;
3277 for (i = 0; i < MAX_NUM_PLAYER_SLOTS; i++) {
3278 if (BV_ISSET(pmapdef->player.plrbv, i)) {
3279 count++;
3280 }
3281 }
3282 break;
3283 case SHOW_ALL: /* show all players in one map */
3284 count = player_count();
3285 break;
3286 }
3287
3288 return count;
3289}
3290
3291/*
3292 * ==============================================
3293 * image colors (internal functions)
3294 * ==============================================
3295 */
3296
3297/************************************************************************/
3300 static const struct rgbcolor *imgcolor_special(enum img_special imgcolor)
3301{
3302 static struct rgbcolor rgb_special[] = {
3303 { 255, 0, 0, NULL}, /* IMGCOLOR_ERROR */
3304 /* FIXME: 'ocean' and 'ground' colors are also used in the overview; the
3305 * values are defined in colors.tilespec. */
3306 { 0, 0, 200, NULL}, /* IMGCOLOR_OCEAN */
3307 { 0, 200, 0, NULL}, /* IMGCOLOR_GROUND */
3308 { 0, 0, 0, NULL}, /* IMGCOLOR_BACKGROUND */
3309 { 255, 255, 255, NULL}, /* IMGCOLOR_TEXT */
3310 };
3311
3312 fc_assert_ret_val(imgcolor >= 0 && imgcolor < ARRAY_SIZE(rgb_special),
3313 &rgb_special[0]);
3314
3315 return &rgb_special[imgcolor];
3316}
3317
3318/************************************************************************/
3323 static const struct rgbcolor *imgcolor_player(int plr_id)
3324{
3325 struct player *pplayer = player_by_number(plr_id);
3326
3327 fc_assert_ret_val(pplayer != NULL, imgcolor_special(IMGCOLOR_ERROR));
3328 fc_assert_ret_val(pplayer->rgb != NULL,
3329 imgcolor_special(IMGCOLOR_ERROR));
3330
3331 return pplayer->rgb;
3332}
3333
3334/************************************************************************/
3339static const struct rgbcolor
3340 *imgcolor_terrain(const struct terrain *pterrain)
3341{
3342 fc_assert_ret_val(pterrain != NULL, imgcolor_special(IMGCOLOR_ERROR));
3343 fc_assert_ret_val(pterrain->rgb != NULL, imgcolor_special(IMGCOLOR_ERROR));
3344
3345 return pterrain->rgb;
3346}
astr_free
void astr_free(struct astring *astr)
Definition astring.c:153
astr_set
void astr_set(struct astring *astr, const char *format,...)
Definition astring.c:267
astr_init
void astr_init(struct astring *astr)
Definition astring.c:144
astr_add
void astr_add(struct astring *astr, const char *format,...)
Definition astring.c:287
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:62
wld
struct world wld
Definition game.c:63
generate_save_name
int generate_save_name(const char *format, char *buf, int buflen, const char *reason)
Definition game.c:789
game.h
owner
struct city * owner
Definition citydlg.c:220
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:371
map_is_empty
bool map_is_empty(void)
Definition map.c:149
map.h
CURRENT_TOPOLOGY
#define CURRENT_TOPOLOGY
Definition map.h:44
topo_has_flag
#define topo_has_flag(topo, flag)
Definition map.h:47
MAP_TO_NATIVE_POS
#define MAP_TO_NATIVE_POS(pnat_x, pnat_y, map_x, map_y)
Definition map.h:172
CURRENT_WRAP
#define CURRENT_WRAP
Definition map.h:45
wrap_has_flag
#define wrap_has_flag(wrap, flag)
Definition map.h:50
whole_map_iterate
#define whole_map_iterate(_map, _tile)
Definition map.h:545
whole_map_iterate_end
#define whole_map_iterate_end
Definition map.h:554
index_to_map_pos
#define index_to_map_pos(pmap_x, pmap_y, mindex)
Definition map.h:233
pixel_fogofwar_hexa
static bv_pixel pixel_fogofwar_hexa(const struct tile *ptile, const struct player *pplayer, bool knowledge)
Definition mapimg.c:2848
NUM_PIXEL
#define NUM_PIXEL
Definition mapimg.c:89
bvplayers_count
static int bvplayers_count(const struct mapdef *pmapdef)
Definition mapimg.c:3261
pixel_fogofwar_rect
static bv_pixel pixel_fogofwar_rect(const struct tile *ptile, const struct player *pplayer, bool knowledge)
Definition mapimg.c:2621
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:1311
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:1564
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:1190
mapimg_initialised
bool mapimg_initialised(void)
Definition mapimg.c:1555
mapimg_def2str
static bool mapimg_def2str(struct mapdef *pmapdef, char *str, size_t str_len)
Definition mapimg.c:1579
base_coor_hexa
static void base_coor_hexa(struct img *pimg, int *base_x, int *base_y, int x, int y)
Definition mapimg.c:2982
mapimg_colortest
bool mapimg_colortest(const char *savename, const char *path)
Definition mapimg.c:1438
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:1873
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:2562
mapimg_isvalid
struct mapdef * mapimg_isvalid(int id)
Definition mapimg.c:1121
pixel_border_hexa
static bv_pixel pixel_border_hexa(const struct tile *ptile, const struct player *pplayer, bool knowledge)
Definition mapimg.c:2887
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:1807
img_save_ppm
static bool img_save_ppm(const struct img *pimg, const char *mapimgfile)
Definition mapimg.c:2310
img_destroy
static void img_destroy(struct img *pimg)
Definition mapimg.c:1969
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:2009
img_filename
static bool img_filename(const char *mapimgfile, enum imageformat format, char *filename, size_t filename_len)
Definition mapimg.c:2385
imgcolor_terrain
static const struct rgbcolor * imgcolor_terrain(const struct terrain *pterrain)
Definition mapimg.c:3340
img_createmap
static void img_createmap(struct img *pimg)
Definition mapimg.c:2416
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:1707
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:2663
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:1996
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:1153
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:2045
pixel_city_hexa
static bv_pixel pixel_city_hexa(const struct tile *ptile, const struct player *pplayer, bool knowledge)
Definition mapimg.c:2782
pixel_fogofwar_isohexa
static bv_pixel pixel_fogofwar_isohexa(const struct tile *ptile, const struct player *pplayer, bool knowledge)
Definition mapimg.c:3081
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:3000
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:1204
imgcolor_player
static const struct rgbcolor * imgcolor_player(int plr_id)
Definition mapimg.c:3323
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:2761
pixel_city_isohexa
static bv_pixel pixel_city_isohexa(const struct tile *ptile, const struct player *pplayer, bool knowledge)
Definition mapimg.c:3019
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:2744
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:1734
pixel_unit_rect
static bv_pixel pixel_unit_rect(const struct tile *ptile, const struct player *pplayer, bool knowledge)
Definition mapimg.c:2598
pixel_unit_hexa
static bv_pixel pixel_unit_hexa(const struct tile *ptile, const struct player *pplayer, bool knowledge)
Definition mapimg.c:2823
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:2032
base_coor_isohexa
static void base_coor_isohexa(struct img *pimg, int *base_x, int *base_y, int x, int y)
Definition mapimg.c:3218
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:1841
mapimg_create
bool mapimg_create(struct mapdef *pmapdef, bool force, const char *savename, const char *path)
Definition mapimg.c:1332
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:3300
pixel_border_isohexa
static bv_pixel pixel_border_isohexa(const struct tile *ptile, const struct player *pplayer, bool knowledge)
Definition mapimg.c:3123
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:2399
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:1223
mapimg_define_arg
static bool mapimg_define_arg(struct mapdef *pmapdef, enum mapdef_arg arg, const char *val, bool check)
Definition mapimg.c:892
mapimg_checkplayers
static bool mapimg_checkplayers(struct mapdef *pmapdef, bool recheck)
Definition mapimg.c:1639
img_toolkit_get
static const struct toolkit * img_toolkit_get(enum imagetool tool)
Definition mapimg.c:1859
pixel_unit_isohexa
static bv_pixel pixel_unit_isohexa(const struct tile *ptile, const struct player *pplayer, bool knowledge)
Definition mapimg.c:3058
img_set_pixel
static void img_set_pixel(struct img *pimg, const int mindex, const struct rgbcolor *pcolor)
Definition mapimg.c:1981
pixel_tile_rect
static bv_pixel pixel_tile_rect(const struct tile *ptile, const struct player *pplayer, bool knowledge)
Definition mapimg.c:2543
img_toolkits
static struct toolkit img_toolkits[]
Definition mapimg.c:430
NUM_MAX_FORMATARGS
#define NUM_MAX_FORMATARGS
Definition mapimg.c:891
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:3238
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:1405
gives_shared_vision
bool gives_shared_vision(const struct player *me, const struct player *them)
Definition player.c:1485
player.h
players_iterate_end
#define players_iterate_end
Definition player.h:537
players_iterate
#define players_iterate(_pplayer)
Definition player.h:532
is_human
#define is_human(plr)
Definition player.h:229
rgbcolor.h
make_dir
bool make_dir(const char *pathname)
Definition shared.c:1779
path_is_absolute
bool path_is_absolute(const char *filename)
Definition shared.c:1880
ARRAY_SIZE
#define ARRAY_SIZE(x)
Definition shared.h:85
MIN
#define MIN(x, y)
Definition shared.h:55
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:207
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:278
strvec_new
struct strvec * strvec_new(void)
Definition string_vector.c:58
string_vector.h
astring
Definition astring.h:36
civ_game::info
struct packet_game_info info
Definition game.h:89
civ_map::xsize
int xsize
Definition map_types.h:78
civ_map::ysize
int ysize
Definition map_types.h:78
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:130
packet_game_info::turn
int turn
Definition packets_gen.h:241
packet_game_info::fogofwar
bool fogofwar
Definition packets_gen.h:150
player
Definition player.h:247
player::is_alive
bool is_alive
Definition player.h:266
player::rgb
struct rgbcolor * rgb
Definition player.h:310
rgbcolor
Definition rgbcolor.h:33
strvec
Definition string_vector.c:29
terrain
Definition terrain.h:182
terrain::rgb
struct rgbcolor * rgb
Definition terrain.h:261
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:974
fc_strlcpy
size_t fc_strlcpy(char *dest, const char *src, size_t n)
Definition support.c:791
fc_strcasecmp
int fc_strcasecmp(const char *str0, const char *str1)
Definition support.c:189
cat_snprintf
int cat_snprintf(char *str, size_t n, const char *format,...)
Definition support.c:1000
fc_vsnprintf
int fc_vsnprintf(char *str, size_t n, const char *format, va_list ap)
Definition support.c:900
fc_fopen
FILE * fc_fopen(const char *filename, const char *opentype)
Definition support.c:507
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:301
tile.h
tile_index
#define tile_index(_pt_)
Definition tile.h:88
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