view src/mkpalette.cc @ 80:2f1ecc1c5f72

Huge cleanup -- move some global variables into a struct.
author Matti Hamalainen <ccr@tnsp.org>
date Mon, 26 Sep 2011 17:39:49 +0300
parents 2badfa44a37a
children f05330267c66
line wrap: on
line source

/*
 *        mkpalette.cc
 *        Generate palette files from lump PLAYPAL.
 *        AYM 1998-12-29
 */


/*
This file is part of Yadex.

Yadex incorporates code from DEU 5.21 that was put in the public domain in
1994 by Raphaël Quinet and Brendon Wyber.

The rest of Yadex is Copyright © 1997-2003 André Majorel and others.

This program is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software
Foundation; either version 2 of the License, or (at your option) any later
version.

This program is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.

You should have received a copy of the GNU General Public License along with
this program; if not, write to the Free Software Foundation, Inc., 59 Temple
Place, Suite 330, Boston, MA 02111-1307, USA.
*/


#include "yadex.h"
#include "mkpalette.h"
#include "gfx.h"
#include "rgb.h"
#include "wadfile.h"
#include "wads.h"


static int palette_read_from_wad(int playpalnum, u8 **dpal)
{
    const char *lump_name = "PLAYPAL";

    MDirPtr dir = FindMasterDir(cfg.MasterDir, lump_name);
    if (dir == NULL)
    {
        warn("%s: lump not found\n", lump_name);
        return 1;
    }

    int playpal_count = dir->dir.size / (3 * DOOM_COLOURS);
    if (playpalnum < 0 || playpalnum >= playpal_count)
    {
        warn("playpalnum %d out of range (0-%d), using #0 instead\n",
             playpalnum, playpal_count - 1);
        playpalnum = 0;
    }

    *dpal = (u8 *) GetMemory(3 * DOOM_COLOURS);
    if (*dpal == NULL)
    {
        err("Could not allocate memory for the palette entry");
        return -1;
    }
    
    const Wad_file *wf = dir->wadfile;

    wf->seek(dir->dir.start + (long) playpalnum * 3 * DOOM_COLOURS);
    if (wf->error())
    {
        err("%s: seek error", lump_name);
        return -2;
    }

    wf->read_bytes(*dpal, 3 * DOOM_COLOURS);
    if (wf->error())
    {
        err("%s: read error", lump_name);
        return -3;
    }

    return 0;
}

static FILE *palette_open_outfile(const char *filename, const char *mode)
{
    FILE *f = fopen(filename, mode);
    if (f == NULL)
        warn("%s: %s\n", filename, strerror(errno));
    return f;
}

static void palette_cleanup(FILE *outfile, u8 *dpal, int *rc)
{
    FreeMemory(dpal);
    if (outfile != NULL)
    {
        if (fclose(outfile))
            *rc = 1;
    }
}

/*
 *        make_gimp_palette
 *        Generate a Gimp palette file for the <playpalnum>th
 *        palette in the PLAYPAL entry.
 *        Return 0 on success, non-zero on failure.
 */
int make_gimp_palette(int playpalnum, const char *filename)
{
    int rc = 0;
    u8 *dpal = NULL;
    FILE *outfile = NULL;

    if ((rc = palette_read_from_wad(playpalnum, &dpal)) != 0)
        goto byebye;

    if ((outfile = palette_open_outfile(filename, "w")) == NULL)
    {
        rc = -1;
        goto byebye;
    }
        
    fprintf(outfile,
            "GIMP Palette\n" "# Generated by Yadex %s\n", yadex_version);

    for (size_t n = 0; n < DOOM_COLOURS; n++)
        fprintf(outfile,
                "%3d %3d %3d  Index = %d (%02Xh)   RGB = %d, %d, %d\n",
                dpal[3 * n], dpal[3 * n + 1], dpal[3 * n + 2], n, n,
                dpal[3 * n], dpal[3 * n + 1], dpal[3 * n + 2]);

byebye:
    palette_cleanup(outfile, dpal, &rc);
    return rc;
}


/*
 *        make_palette_ppm
 *        Generate a 256 x 128 raw PPM image showing all the
 *        colours in the palette.
 *        Return 0 on success, non-zero on failure.
 */
int make_palette_ppm(int playpalnum, const char *filename)
{
    int rc = 0;
    u8 *dpal = NULL;
    FILE *outfile = NULL;
    const int width = 128;
    const int height = 128;
    const int columns = 16;
    int rect_w = width / columns;
    int rect_h = height / (DOOM_COLOURS / columns);

    if ((rc = palette_read_from_wad(playpalnum, &dpal)) != 0)
        goto byebye;

    if ((outfile = palette_open_outfile(filename, "wb")) == NULL)
    {
        rc = -1;
        goto byebye;
    }
    
    fputs("P6", outfile);
    fnewline(outfile);
    fprintf(outfile, "# Generated by Yadex %s", yadex_version);
    fnewline(outfile);
    fprintf(outfile, "%d %d", width, height);
    fnewline(outfile);
    fputs("255\n", outfile);        // Always \n (must be a single character)

    for (size_t n = 0; n < DOOM_COLOURS; n += columns)
        for (int subrow = 0; subrow < rect_h; subrow++)
            for (int c = 0; c < columns; c++)
                for (int subcol = 0; subcol < rect_w; subcol++)
                {
                    if (subrow == 0 && subcol == 0)
                    {
                        putc(0, outfile);
                        putc(0, outfile);
                        putc(0, outfile);
                    }
                    else
                    {
                        putc(dpal[3 * (n + c)], outfile);
                        putc(dpal[3 * (n + c) + 1], outfile);
                        putc(dpal[3 * (n + c) + 2], outfile);
                    }
                }

byebye:
    palette_cleanup(outfile, dpal, &rc);
    return rc;
}


/*
 *        make_palette_ppm_2
 *        Make a wide PPM containing all the colours in the palette
 */

int make_palette_ppm_2(int playpalnum, const char *filename)
{
    int rc = 0;
    u8 *dpal = NULL;
    FILE *outfile = NULL;
    const int width = DOOM_COLOURS;
    const int height = DOOM_COLOURS;

    if ((rc = palette_read_from_wad(playpalnum, &dpal)) != 0)
        goto byebye;

    if ((outfile = palette_open_outfile(filename, "wb")) == NULL)
    {
        rc = -1;
        goto byebye;
    }
    
    fputs("P6", outfile);
    fnewline(outfile);
    fprintf(outfile, "# Generated by Yadex %s", yadex_version);
    fnewline(outfile);
    fprintf(outfile, "%d %d", width, height);
    fnewline(outfile);
    fputs("255\n", outfile);        // Always \n (must be a single character)

    for (int l = 0; l < height; l++)
        for (int c = 0; c < width; c++)
        {
            putc(dpal[3 * ((c + l) % DOOM_COLOURS)], outfile);
            putc(dpal[3 * ((c + l) % DOOM_COLOURS) + 1], outfile);
            putc(dpal[3 * ((c + l) % DOOM_COLOURS) + 2], outfile);
        }

byebye:
    palette_cleanup(outfile, dpal, &rc);
    return rc;
}