view map2ppm.c @ 945:81184d58133c aprilli2011

Sync.
author Matti Hamalainen <ccr@tnsp.org>
date Fri, 14 May 2010 11:18:20 +0000
parents c80fb894df24
children 82469eecbae7
line wrap: on
line source

/*
 * Convert BatMUD ASCII map to PPM image file
 * Programmed by Matti 'ccr' Hämäläinen (Ggr Pupunen)
 * (C) Copyright 2006-2008 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,
        optUseANSI = FALSE,
        optCityFormat = FALSE;
int     optScale = 1;

    
/* 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 },
    { 6, 'A', "ansi-colors",    "Use ANSI colors", OPT_NONE },
    { 7, 'c', "city-format",    "Input is a city map", OPT_NONE },
    { 8, 's', "scale",          "Scale value (integer)", 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;
    
    case 6:
        optUseANSI = TRUE;
        THMSG(2, "Using ANSI colors.\n");
        break;
    
    case 7:
        optCityFormat = TRUE;
        THMSG(2, "Input is handled as a city map\n");
        break;

    case 8:
        optScale = atoi(optArg);
        if (optScale < 1 || optScale > 50) {
            THERR("Invalid scale value %d, must be 1 < x < 50.\n", optScale);
            return FALSE;
        }
        THMSG(2, "Output scaling set to %d.\n", optScale);
        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, xscale, yscale;
    size_t s;
    unsigned char *d;
    char str[64];

    /* Initialize */
    th_init("map2ppm", "ASCII map to PPM image converter", "0.4", NULL, NULL);
    th_verbosityLevel = 0;
    
    /* 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);
    }
    
    /* 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);
    }

    
    /* Write header for 24-bit PPM */
    THMSG(1, "Outputting 24-bit PPM image of %dx%d ...\n",
        map->w * optScale, map->h * optScale);
    
    snprintf(str, sizeof(str),
        "P6\n%d %d\n255\n",
        map->w * optScale, map->h * optScale);
    
    fputs(str, outFile);
    
    s = strlen(str);
    d = map->d;
    for (y = 0; y < map->h; y++) {
    for (yscale = 0; yscale < optScale; yscale++)
      for (x = 0; x < map->w; x++) {
        int qr, qg, qb, c;
        qr = 255; qg = qb = 0;
        c = (unsigned char) d[y * map->w + x];
        
        if (optInputIsDiff) {
            if (c < nmapPieces) {
                if (optUseANSI) {
                    qr = qg = qb = 255;
                } else {
                    c = c & 63;
                    qr = mapPieces[c].r;
                    qg = mapPieces[c].g;
                    qb = mapPieces[c].b;
                }
            }
        } else if (optUseANSI) {
            if ((c = mcGetColor(c, optUseOldFormat, optCityFormat)) >= 0) {
                qr = mapColors[c].r;
                qg = mapColors[c].g;
                qb = mapColors[c].b;
            }
        } else {
            if ((c = mcGet(c, optUseOldFormat, optCityFormat)) >= 0) {
                qr = mapPieces[c].r;
                qg = mapPieces[c].g;
                qb = mapPieces[c].b;
            }
        }
        
        for (xscale = 0; xscale < optScale; xscale++) {
            fputc(qr, outFile);
            fputc(qg, outFile);
            fputc(qb, outFile);
            s += 3;
        }
      }
    }
    
    fclose(outFile);
    
    THMSG(1, "Done. Image size %d bytes.\n", s);
    
    exit(0);
    return 0;
}