changeset 274:cc2ebbd38ba6

Added 'mapstats' utility.
author Matti Hamalainen <ccr@tnsp.org>
date Sat, 16 Jun 2007 10:54:02 +0000
parents 832db3e10cca
children 68fd7fba64ef
files Makefile.gen mapstats.c
diffstat 2 files changed, 177 insertions(+), 3 deletions(-) [+]
line wrap: on
line diff
--- a/Makefile.gen	Mon Jun 11 12:27:47 2007 +0000
+++ b/Makefile.gen	Sat Jun 16 10:54:02 2007 +0000
@@ -23,10 +23,11 @@
 MAP2PPM_BIN=$(BINPATH)map2ppm$(EXEEXT)
 MAP3D_BIN=$(BINPATH)map3d$(EXEEXT)
 COMBINE_BIN=$(BINPATH)combine$(EXEEXT)
+MAPSTATS_BIN=$(BINPATH)mapstats$(EXEEXT)
 
-TARGETS=$(MKMAP_BIN) $(COLORMAP_BIN) $(MKSPECIAL_BIN)	\
-	$(MKBCMAP_BIN) $(DIFFMAP_BIN)	$(MAP2PPM_BIN)	\
-	$(MKLOC_BIN) $(MAP3D_BIN) $(COMBINE_BIN)	\
+TARGETS=$(MKMAP_BIN) $(COLORMAP_BIN) $(MKSPECIAL_BIN) $(MKBCMAP_BIN)	\
+	$(DIFFMAP_BIN)	$(MAP2PPM_BIN) $(MKLOC_BIN) $(MAP3D_BIN)	\
+	$(COMBINE_BIN) $(MAPSTATS_BIN)	\
 	votk.html lanzia.html
 
 MAPFILES=tooltip.js votk.html votk.map	\
@@ -70,6 +71,9 @@
 $(COMBINE_BIN): combine.c maputils.o th_util.o th_args.o th_string.o
 	$(COMP) -o $@ $+ $(LDFLAGS)
 
+$(MAPSTATS_BIN): mapstats.c maputils.o th_util.o th_args.o th_string.o
+	$(COMP) -o $@ $+ $(LDFLAGS)
+
 %.png: %.map $(MAP2PPM_BIN)
 	$(MAP2PPM_BIN) -O $< | pnmscale 5 | pnmtopng -compression=9 > $@
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mapstats.c	Sat Jun 16 10:54:02 2007 +0000
@@ -0,0 +1,170 @@
+/*
+ * Calculate terrain type (and other) statistics from ASCII map
+ * Programmed by Matti 'ccr' Hämäläinen (Ggr Pupunen)
+ * (C) Copyright 2007 Tecnic Software productions (TNSP)
+ */
+#include "maputils.h"
+#include "th_args.h"
+#include "th_string.h"
+
+
+char	*srcFilename = NULL,
+	*destFilename = NULL;
+
+BOOL	optUseOldFormat = FALSE,
+	optInputIsDiff = FALSE;
+
+	
+/* Arguments
+ */
+optarg_t optList[] = {
+	{ 0, '?', "help",	"Show this help", OPT_NONE },
+	{ 1, 'v', "verbose",	"Be more verbose", OPT_NONE },
+	{ 2, 'q', "quiet",	"Be quiet", OPT_NONE },
+	{ 3, 'd', "input-diff",	"Input is a diff", OPT_NONE },
+	{ 4, 'O', "old-format",	"Input using old symbols/colors", OPT_NONE },
+	{ 5, 'o', "output",	"Output filename", OPT_ARGREQ },
+};
+
+const int optListN = (sizeof(optList) / sizeof(optarg_t));
+
+
+void argShowHelp(void)
+{
+	th_args_help(stderr, optList, optListN, th_prog_name,
+	"[options] <input mapfile>");
+}
+
+
+BOOL argHandleOpt(const int optN, char *optArg, char *currArg)
+{
+	switch (optN) {
+	case 0:
+		argShowHelp();
+		exit(0);
+		break;
+
+	case 1:
+		th_verbosityLevel++;
+		break;
+	
+	case 2:
+		th_verbosityLevel = -1;
+		break;
+	
+	case 3:
+		optInputIsDiff = TRUE;
+		THMSG(2, "Input is a 'diff', handling it as such.\n");
+		break;
+		
+	case 4:
+		optUseOldFormat = TRUE;
+		THMSG(2, "Input is using old map symbols/colors.\n");
+		break;
+	
+	case 5:
+		destFilename = optArg;
+		THMSG(2, "Output file set to '%s'.\n", destFilename);
+		break;
+	
+	default:
+		THERR("Unknown option '%s'.\n", currArg);
+		return FALSE;
+	}
+	
+	return TRUE;
+}
+
+
+BOOL argHandleFile(char *currArg)
+{
+	if (!srcFilename)
+		srcFilename = currArg;
+	else {
+		THERR("Too many input map files specified!\n");
+		return FALSE;
+	}
+
+	return TRUE;
+}
+
+
+/* Main program
+ */
+int main(int argc, char *argv[])
+{
+	FILE *outFile;
+	mapblock_t *map;
+	int x, y;
+	char *d;
+	ulint_t statTotal, statUnknown, statPieces[nmapPieces];
+
+	/* Initialize */
+	th_init("mapstats", "ASCII map statistics generator", "0.1", NULL, NULL);
+	th_verbosityLevel = 1;
+	
+	/* Parse arguments */
+	if (!th_args_process(argc, argv, optList, optListN,
+		argHandleOpt, argHandleFile, TRUE))
+		exit(1);
+	
+	if (srcFilename == NULL) {
+		THERR("Nothing to do. (try --help)\n");
+		exit(0);
+	}
+	
+	/* Read input file */
+	THMSG(1, "Reading map file '%s'\n", srcFilename);
+	
+	if ((map = parseFile(srcFilename, optInputIsDiff)) == NULL) {
+		THERR("Error reading map file '%s'!\n",
+			srcFilename);
+		exit(1);
+	}
+	
+	THMSG(1, "Analyzing %dx%d area ...\n",
+		map->w, map->h);
+	
+	th_memset(statPieces, 0, sizeof(statPieces));
+	statTotal = statUnknown = 0;
+	
+	d = map->d;
+	for (y = 0; y < map->h; y++)
+	for (x = 0; x < map->w; x++) {
+		int c;
+		if ((c = mcGet(*d, optUseOldFormat)) >= 0) {
+			statPieces[c]++;
+		} else {
+			statUnknown++;
+		}
+		statTotal++;
+		d++;
+	}
+	
+	/* Open output file */
+	if (destFilename == NULL)
+		outFile = stdout;
+	else if ((outFile = fopen(destFilename, "wb")) == NULL) {
+		THERR("Error opening output file '%s'!\n",
+			destFilename);
+		exit(1);
+	}
+	
+	for (x = 0; x < nmapPieces; x++) {
+		fprintf(outFile, " %-20s [%c]: %6ld (%1.3f%%)\n",
+			mapPieces[x].desc,
+			mapPieces[x].symbol,
+			statPieces[x],
+			(statPieces[x] * 100.0f / statTotal));
+	}
+	
+	fprintf(outFile, " %ld total, %ld unknown.\n",
+		statTotal, statUnknown);
+
+	fclose(outFile);
+	
+	THMSG(1, "Done.\n");
+	
+	exit(0);
+	return 0;
+}