I'll push a formatting guide at some point. There may still be outstanding changes, but please feel free to resolve those as you arrive a them. To the best of my knowledge, there is no changes to the actual code content, but the formatter does have the occasional bug. If you run into an issue, please fix it!
230 lines
6.4 KiB
C
230 lines
6.4 KiB
C
/* $NHDT-Date: 1431192774 2015/05/09 17:32:54 $ $NHDT-Branch: master $:$NHDT-Revision: 1.5 $ */
|
|
/* $Date: 2002/03/17 20:02:47 $ $Revision: 1.2 $ */
|
|
|
|
/*
|
|
* Convert the given input files into an output file that is expected
|
|
* by nethack.
|
|
*
|
|
* Assumptions:
|
|
* + Two dimensional byte arrays are in row order and are not padded
|
|
* between rows (x11_colormap[][]).
|
|
*/
|
|
#include "hack.h" /* for MAX_GLYPH */
|
|
#include "tile.h"
|
|
#include "tile2x11.h" /* x11 output file header structure */
|
|
|
|
#define OUTNAME "x11tiles" /* output file name */
|
|
/* #define PRINT_COLORMAP */ /* define to print the colormap */
|
|
|
|
x11_header header;
|
|
unsigned char tile_bytes[TILE_X * TILE_Y * (MAX_GLYPH + TILES_PER_ROW)];
|
|
unsigned char *curr_tb = tile_bytes;
|
|
unsigned char x11_colormap[MAXCOLORMAPSIZE][3];
|
|
|
|
/* Look up the given pixel and return its colormap index. */
|
|
static unsigned char
|
|
pix_to_colormap(pix)
|
|
pixel pix;
|
|
{
|
|
unsigned i;
|
|
|
|
for (i = 0; i < header.ncolors; i++) {
|
|
if (pix.r == ColorMap[CM_RED][i] && pix.g == ColorMap[CM_GREEN][i]
|
|
&& pix.b == ColorMap[CM_BLUE][i])
|
|
break;
|
|
}
|
|
|
|
if (i == header.ncolors) {
|
|
Fprintf(stderr, "can't find color: [%u,%u,%u]\n", pix.r, pix.g,
|
|
pix.b);
|
|
exit(1);
|
|
}
|
|
return (unsigned char) (i & 0xFF);
|
|
}
|
|
|
|
/* Convert the tiles in the file to our format of bytes. */
|
|
static unsigned long
|
|
convert_tiles(tb_ptr, total)
|
|
unsigned char **tb_ptr; /* pointer to a tile byte pointer */
|
|
unsigned long total; /* total tiles so far */
|
|
{
|
|
unsigned char *tb = *tb_ptr;
|
|
unsigned long count = 0;
|
|
pixel tile[TILE_Y][TILE_X];
|
|
int x, y;
|
|
|
|
while (read_text_tile(tile)) {
|
|
count++;
|
|
total++;
|
|
for (y = 0; y < TILE_Y; y++) {
|
|
for (x = 0; x < TILE_X; x++)
|
|
tb[x] = pix_to_colormap(tile[y][x]);
|
|
tb += TILE_X * header.per_row;
|
|
}
|
|
|
|
/* repoint at the upper-left corner of the next tile */
|
|
*tb_ptr += TILE_X;
|
|
if (header.per_row == 1 || (total % header.per_row) == 0)
|
|
*tb_ptr += TILE_X * (TILE_Y - 1) * header.per_row;
|
|
tb = *tb_ptr;
|
|
}
|
|
|
|
return count;
|
|
}
|
|
|
|
/* Merge the current text colormap (ColorMap) with ours (x11_colormap). */
|
|
static void
|
|
merge_text_colormap()
|
|
{
|
|
unsigned i, j;
|
|
|
|
for (i = 0; i < (unsigned) colorsinmap; i++) {
|
|
for (j = 0; j < header.ncolors; j++)
|
|
if (x11_colormap[j][CM_RED] == ColorMap[CM_RED][i]
|
|
&& x11_colormap[j][CM_GREEN] == ColorMap[CM_GREEN][i]
|
|
&& x11_colormap[j][CM_BLUE] == ColorMap[CM_BLUE][i])
|
|
break;
|
|
|
|
if (j >= MAXCOLORMAPSIZE) {
|
|
Fprintf(stderr, "colormap overflow\n");
|
|
exit(1);
|
|
}
|
|
|
|
if (j == header.ncolors) { /* couldn't find it */
|
|
#ifdef PRINT_COLORMAP
|
|
printf("color %2d: %3d %3d %3d\n", header.ncolors,
|
|
ColorMap[CM_RED][i], ColorMap[CM_GREEN][i],
|
|
ColorMap[CM_BLUE][i]);
|
|
#endif
|
|
|
|
x11_colormap[j][CM_RED] = ColorMap[CM_RED][i];
|
|
x11_colormap[j][CM_GREEN] = ColorMap[CM_GREEN][i];
|
|
x11_colormap[j][CM_BLUE] = ColorMap[CM_BLUE][i];
|
|
header.ncolors++;
|
|
}
|
|
}
|
|
}
|
|
|
|
/* Open the given file, read & merge the colormap, convert the tiles. */
|
|
static void
|
|
process_file(fname)
|
|
char *fname;
|
|
{
|
|
unsigned long count;
|
|
|
|
if (!fopen_text_file(fname, RDTMODE)) {
|
|
Fprintf(stderr, "can't open file \"%s\"\n", fname);
|
|
exit(1);
|
|
}
|
|
merge_text_colormap();
|
|
count = convert_tiles(&curr_tb, header.ntiles);
|
|
Fprintf(stderr, "%s: %lu tiles\n", fname, count);
|
|
header.ntiles += count;
|
|
fclose_text_file();
|
|
}
|
|
|
|
#ifdef USE_XPM
|
|
static int
|
|
xpm_write(fp)
|
|
FILE *fp;
|
|
{
|
|
int i, j, n;
|
|
|
|
if (header.ncolors > 64) {
|
|
Fprintf(stderr, "Sorry, only configured for up to 64 colors\n");
|
|
exit(1);
|
|
/* All you need to do is add more char per color - below */
|
|
}
|
|
|
|
Fprintf(fp, "/* XPM */\n");
|
|
Fprintf(fp, "static char* nhtiles[] = {\n");
|
|
Fprintf(fp, "\"%lu %lu %lu %d\",\n", header.tile_width * header.per_row,
|
|
(header.tile_height * header.ntiles) / header.per_row,
|
|
header.ncolors, 1 /* char per color */);
|
|
for (i = 0; i < header.ncolors; i++)
|
|
Fprintf(fp, "\"%c c #%02x%02x%02x\",\n",
|
|
i + '0', /* just one char per color */
|
|
x11_colormap[i][0], x11_colormap[i][1], x11_colormap[i][2]);
|
|
|
|
n = 0;
|
|
for (i = 0; i < (header.tile_height * header.ntiles) / header.per_row;
|
|
i++) {
|
|
Fprintf(fp, "\"");
|
|
for (j = 0; j < header.tile_width * header.per_row; j++) {
|
|
/* just one char per color */
|
|
fputc(tile_bytes[n++] + '0', fp);
|
|
}
|
|
|
|
Fprintf(fp, "\",\n");
|
|
}
|
|
|
|
return fprintf(fp, "};\n") >= 0;
|
|
}
|
|
#endif /* USE_XPM */
|
|
|
|
int
|
|
main(argc, argv)
|
|
int argc;
|
|
char **argv;
|
|
{
|
|
FILE *fp;
|
|
int i;
|
|
|
|
header.version = 2; /* version 1 had no per_row field */
|
|
header.ncolors = 0;
|
|
header.tile_width = TILE_X;
|
|
header.tile_height = TILE_Y;
|
|
header.ntiles = 0; /* updated as we read in files */
|
|
header.per_row = TILES_PER_ROW;
|
|
|
|
if (argc == 1) {
|
|
Fprintf(stderr, "usage: %s txt_file1 [txt_file2 ...]\n", argv[0]);
|
|
exit(1);
|
|
}
|
|
|
|
fp = fopen(OUTNAME, "w");
|
|
if (!fp) {
|
|
Fprintf(stderr, "can't open output file\n");
|
|
exit(1);
|
|
}
|
|
|
|
/* don't leave garbage at end of partial row */
|
|
(void) memset((genericptr_t) tile_bytes, 0, sizeof(tile_bytes));
|
|
|
|
for (i = 1; i < argc; i++)
|
|
process_file(argv[i]);
|
|
Fprintf(stderr, "Total tiles: %ld\n", header.ntiles);
|
|
|
|
/* round size up to the end of the row */
|
|
if ((header.ntiles % header.per_row) != 0) {
|
|
header.ntiles += header.per_row - (header.ntiles % header.per_row);
|
|
}
|
|
|
|
#ifdef USE_XPM
|
|
if (xpm_write(fp) == 0) {
|
|
Fprintf(stderr, "can't write XPM file\n");
|
|
exit(1);
|
|
}
|
|
#else
|
|
if (fwrite((char *) &header, sizeof(x11_header), 1, fp) == 0) {
|
|
Fprintf(stderr, "can't open output header\n");
|
|
exit(1);
|
|
}
|
|
|
|
if (fwrite((char *) x11_colormap, 1, header.ncolors * 3, fp) == 0) {
|
|
Fprintf(stderr, "can't write output colormap\n");
|
|
exit(1);
|
|
}
|
|
|
|
if (fwrite((char *) tile_bytes, 1,
|
|
(int) header.ntiles * header.tile_width * header.tile_height,
|
|
fp) == 0) {
|
|
Fprintf(stderr, "can't write tile bytes\n");
|
|
exit(1);
|
|
}
|
|
#endif
|
|
|
|
fclose(fp);
|
|
return 0;
|
|
}
|