Mercurial > hg > batmud > maputils
view patchmap.c @ 945:81184d58133c aprilli2011
Sync.
author | Matti Hamalainen <ccr@tnsp.org> |
---|---|
date | Fri, 14 May 2010 11:18:20 +0000 |
parents | 304a50a9d51f |
children | 667ce752bfe3 |
line wrap: on
line source
/* * patchmap - Patch a map with given diff file * Programmed by Matti 'ccr' Hämäläinen (Ggr Pupunen) * (C) Copyright 2008 Tecnic Software productions (TNSP) */ #include "maputils.h" #include "th_util.h" #include "th_args.h" #include "th_string.h" #include <string.h> char *mapFilename = NULL, *patchFilename = NULL, *destFilename = NULL; BOOL optCheck = 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, 'c', "check", "Check non-patched blocks", OPT_NONE }, { 4, '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] <mapfile> <patchfile>"); } 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: optCheck = TRUE; THMSG(2, "Checking non-patched blocks for match.\n"); break; case 4: 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 (!mapFilename) mapFilename = currArg; else if (!patchFilename) patchFilename = currArg; else { THERR("Too many input map files specified!\n"); return FALSE; } return TRUE; } int main(int argc, char *argv[]) { mapblock_t *map, *patch; FILE *outFile; int x, y; unsigned char *s, *d; /* Initialize */ th_init("patchmap", "Patch a mapfile with a diff", "0.1", NULL, NULL); th_verbosityLevel = 1; /* Parse arguments */ if (!th_args_process(argc, argv, optList, optListN, argHandleOpt, argHandleFile, TRUE)) exit(1); if (mapFilename == NULL || patchFilename == NULL) { THERR("Nothing to do. (try --help)\n"); exit(0); } /* Read map and patch file */ if ((map = parseFile(mapFilename, FALSE)) == NULL) exit(2); if ((patch = parseFile(patchFilename, TRUE)) == NULL) exit(3); /* Check map and diff sizes */ if (optCheck && (map->w != patch->w || map->h != patch->h)) { THERR("Map and patch dimensions do not match (%d x %d [map] <-> %d x %d [patch])\n", map->w, map->h, patch->w, patch->h); exit(4); } /* Generate */ d = map->d; s = patch->d; for (y = 0; y < map->h; y++) for (x = 0; x < map->w; x++) { int i = (*s & 63); unsigned char c; if (*s == 0xfd) c = ' '; else if (i < nmapPieces) c = mapPieces[i].symbol; else { THERR("[%d,%d] invalid symbol index %d (%d) in patch\n", x+1, y+1, *s, i); exit(5); } if (*s < 64) { if (optCheck && *s != *d) { THERR("[%d,%d] mismatch %d != %d\n", x+1, y+1, *s, *d); } } else *d = c; s++; 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); } printBlock(outFile, map); fclose(outFile); exit(0); return 0; }