/* SCCS Id: @(#)txt2iff.c 3.2 95/07/28 */ /* Copyright (c) 1995 by Gregg Wonderly, Naperville, Illinois */ /* NetHack may be freely redistributed. See license for details. */ #include #include "config.h" #include "tile.h" #include #include #include #include #include #include #include #include #include #include #ifndef _DCC # include # include # include #endif void panic(const char *); void map_colors(void); int BestMatch(int, int, int); extern pixval ColorMap[3][MAXCOLORMAPSIZE]; extern int colorsinmap; /* * WARNING: * This program carries forth the assumption that the colormaps in all * of the .txt files are the same. This is a bug. */ struct { int Height; int Width; } IFFScreen; /* * We are using a hybrid form of our own design which we call a BMAP (for * bitmap) form. It is an ILBM with the bitmaps already deinterleaved, * completely uncompressed. * This speeds the loading of the images from the games point of view because it * does not have to deinterleave and uncompress them. */ #define ID_BMAP MAKE_ID( 'B', 'M', 'A', 'P' ) /* instead of ILBM */ #define ID_BMHD MAKE_ID( 'B', 'M', 'H', 'D' ) /* Same as ILBM */ #define ID_CAMG MAKE_ID( 'C', 'A', 'M', 'G' ) /* Same as ILBM */ #define ID_CMAP MAKE_ID( 'C', 'M', 'A', 'P' ) /* Same as ILBM */ #define ID_PDAT MAKE_ID( 'P', 'D', 'A', 'T' ) /* Extra data describing plane * size due to graphics.library * rounding requirements. */ #define ID_PLNE MAKE_ID( 'P', 'L', 'N', 'E' ) /* The planes of the image */ #ifndef _DCC extern #endif struct Library *IFFParseBase; int nplanes; /* BMHD from IFF documentation */ typedef struct { UWORD w, h; WORD x, y; UBYTE nPlanes; UBYTE masking; UBYTE compression; UBYTE reserved1; UWORD transparentColor; UBYTE xAspect, yAspect; WORD pageWidth, pageHeight; } BitMapHeader; typedef struct { UBYTE r, g, b; } AmiColorMap; pixel pixels[TILE_Y][TILE_X]; AmiColorMap *cmap; int findcolor( register pixel *pix ); void packwritebody( pixel (*tile)[TILE_X], char **planes, int tileno ); void error( char *str ) { fprintf( stderr, "ERROR: %s\n", str ); } /* * This array maps the image colors to the amiga's first 16 colors. The colors * are reordered to help with maintaining dripen settings. */ int colrmap[] = { 0, 6, 9, 15, 4, 10, 2, 3, 5, 11, 7, 13, 8, 1, 14, 12 }; /* How many tiles fit across and down. */ #define COLS 20 #define ROWS ((tiles + COLS-1) / COLS) main( int argc, char **argv ) { int colors; struct { long nplanes; long pbytes; long across; long down; long npics; long xsize; long ysize; } pdat; long pbytes; /* Bytes of data in a plane */ int i, cnt; BitMapHeader bmhd; struct IFFHandle *iff; long camg = HIRES|LACE; int tiles=0; char **planes; if(argc != 3){ fprintf(stderr, "Usage: %s source destination\n", argv[0]); exit(1); } #if defined(_DCC) || defined(__GNUC__) IFFParseBase = OpenLibrary( "iffparse.library", 0 ); if( !IFFParseBase ) { error( "unable to open iffparse.library" ); exit( 1 ); } #endif /* First, count the files in the file */ if( fopen_text_file( argv[1], "r" ) != TRUE ) { perror( argv[1] ); return( 1 ); } nplanes = 0; i = colorsinmap-1; /*IFFScreen.Colors - 1; */ while( i != 0 ) { nplanes++; i >>= 1; } planes = malloc( nplanes * sizeof( char * ) ); if( planes == 0 ) { error( "can not allocate planes pointer" ); exit( 1 ); } while( read_text_tile( pixels ) == TRUE ) ++tiles; fclose_text_file(); IFFScreen.Width = COLS * TILE_X; IFFScreen.Height = ROWS * TILE_Y; pbytes = (COLS * ROWS * TILE_X + 15) / 16 * 2 * TILE_Y; for( i = 0; i < nplanes; ++i ) { planes[ i ] = calloc( 1, pbytes ); if( planes[ i ] == 0 ) { error( "can not allocate planes pointer" ); exit( 1 ); } } /* Now, process it */ if( fopen_text_file( argv[1], "r" ) != TRUE ) { perror( argv[1] ); return( 1 ); } iff = AllocIFF(); if( !iff ) { error( "Can not allocate IFFHandle" ); return( 1 ); } iff->iff_Stream = Open( argv[2], MODE_NEWFILE ); if( !iff->iff_Stream ) { error( "Can not open output file" ); return( 1 ); } InitIFFasDOS( iff ); OpenIFF( iff, IFFF_WRITE ); PushChunk( iff, ID_BMAP, ID_FORM, IFFSIZE_UNKNOWN ); bmhd.w = IFFScreen.Width; bmhd.h = IFFScreen.Height; bmhd.x = 0; bmhd.y = 0; bmhd.nPlanes = nplanes; bmhd.masking = 0; bmhd.compression = 0; bmhd.reserved1 = 0; bmhd.transparentColor = 0; bmhd.xAspect = 100; bmhd.yAspect = 100; bmhd.pageWidth = TILE_X; bmhd.pageHeight = TILE_Y; PushChunk( iff, ID_BMAP, ID_BMHD, sizeof( bmhd ) ); WriteChunkBytes( iff, &bmhd, sizeof( bmhd ) ); PopChunk( iff ); PushChunk( iff, ID_BMAP, ID_CAMG, sizeof( camg ) ); WriteChunkBytes( iff, &camg, sizeof( camg ) ); PopChunk( iff ); /* We need to reorder the colors to get reasonable default pens but * we also need to know where some of the colors are - so go find out. */ map_colors(); cmap = malloc( (colors = (1L<iff_Stream ); FreeIFF( iff ); printf( "\n%d tiles converted\n", cnt ); #if defined(_DCC) || defined(__GNUC__) CloseLibrary( IFFParseBase ); #endif exit( 0 ); } findcolor( register pixel *pix ) { register int i; for( i = 0; i < MAXCOLORMAPSIZE; ++i ) { if( (pix->r == ColorMap[ CM_RED ][i] ) && (pix->g == ColorMap[ CM_GREEN ][i] ) && (pix->b == ColorMap[ CM_BLUE ][i] ) ) { return( i ); } } return( -1 ); } void packwritebody( pixel (*tile)[TILE_X], char **planes, int tileno ) { register int i, j, k, col; register char *buf; register int across, rowbytes, xoff, yoff; /* how many tiles fit across? */ across = COLS; /* How many bytes per pixel row */ rowbytes = ((IFFScreen.Width + 15)/16)*2; /* How many bytes to account for y distance in planes */ yoff = ((tileno / across) * TILE_Y) * rowbytes; /* How many bytes to account for x distance in planes */ xoff = (tileno % across) * (TILE_X/8); /* For each row... */ for( i = 0; i < TILE_Y; ++i ) { /* For each bitplane... */ for( k = 0; k < nplanes; ++k ) { const int mask = 1l< rate){ bestrate = rate; bestslot = x; } } #ifdef DBG printf("map (%d,%d,%d) -> %d (error=%d)\n",r,g,b,bestslot,bestrate); #endif return bestslot; } long * alloc( unsigned int n ) { long *ret = malloc( n ); if(!ret){ error("Can't allocate memory"); exit(1); } return( ret ); } void panic(const char *msg){ fprintf(stderr,"PANIC: %s\n",msg); exit(1); }