view shipbitmaps.c @ 3:5a977ccbc7a9 default tip

Empty changelog
author darius
date Sat, 06 Dec 1997 05:41:29 +0000
parents
children
line wrap: on
line source

/* $Id: shipbitmaps.c,v 1.1.1.1 1997/12/06 05:41:30 darius Exp $ */

/* with this file, now the user can define and develop new ship bitmap
   sets ('albums') more easily.

     The user need only create a file in the proper directory with the
proper name with the proper format.  The directory is specified by the
shipBitmapPath resource in the .xtrekrc.  Its default is
/usr/games/lib/netrek.  The name of the file is "R%d.C%d" where the
first integer is the race number and the second is the ship class
number.

  The format of the file is: 3 4-byte integers in network byte order.
The first is the number of views in the file (this field is currently
ignored but should have the value 16).  The second integer is the
width and the third is the height.  Then follows raw bitmap data.  I
don't know what the format is, but it's basically a binary version of
the X bitmap file format.  Translate those hex numbers to raw bytes
and you have it.  I can tell you that each line is padded to 8 bits.

*/

#include <stdio.h>
#ifndef AMIGA
#include <sys/param.h>
#include <netinet/in.h>
#endif
#include <errno.h>

#ifdef m_flags
 /* appears under HPUX */
#undef m_flags
#endif

#include "Wlib.h"
#include "defs.h"
#include "struct.h"
#include "data.h"
#include "gameconf.h"

#ifdef NOSHIPBITMAPS
#include "bitmaps_CASB.h"
#else
#include "bitmaps_NEW.h"
#ifdef HOCKEY
#include "puck.h"
#endif /*HOCKEY*/
#endif

static int
get_ship_width(team, shipn)
    int     team, shipn;
{
#ifndef NOSHIPBITMAPS
    if (shipn == ATT && paradise)
	return att_width;
    switch (team) {
    case 0:
	switch (shipn) {
#ifdef HOCKEY
	case PUCK:
            return puck_width;
#endif /*HOCKEY*/
	case SCOUT:
	    return fed_scout_width;
	case DESTROYER:
	    return fed_destroyer_width;
	case CRUISER:
	    return fed_cruiser_width;
	case BATTLESHIP:
	    return fed_battleship_width;
	case ASSAULT:
	    return fed_assault_width;
	case STARBASE:
	    return fed_starbase_width;
	case JUMPSHIP:
	    return fed_jumpship_width;
	case FLAGSHIP:
	    return fed_galaxy_width;
	case GALAXY:
	    return fed_galaxy_width;
	case WARBASE:
	    return fed_warbase_width;
	case LIGHTCRUISER:
	    return fed_lightcruiser_width;
	case CARRIER:
	    return fed_carrier_height;
	case UTILITY:
	    return fed_utility_width;
	case PATROL:
	    return fed_patrol_width;
	}
    case 1:
	switch (shipn) {
#ifdef HOCKEY
	case PUCK:
            return puck_width;
#endif /*HOCKEY*/
	case SCOUT:
	    return rom_scout_width;
	case DESTROYER:
	    return rom_destroyer_width;
	case CRUISER:
	    return rom_cruiser_width;
	case BATTLESHIP:
	    return rom_battleship_width;
	case ASSAULT:
	    return rom_assault_width;
	case STARBASE:
	    return rom_starbase_width;
	case JUMPSHIP:
	    return rom_jumpship_width;
	case FLAGSHIP:
	    return rom_galaxy_width;
	case GALAXY:
	    return rom_galaxy_width;
	case WARBASE:
	    return rom_warbase_width;
	case LIGHTCRUISER:
	    return rom_lightcruiser_width;
	case CARRIER:
	    return rom_carrier_height;
	case UTILITY:
	    return rom_utility_width;
	case PATROL:
	    return rom_patrol_width;
	}
    case 2:
	switch (shipn) {
#ifdef HOCKEY
	case PUCK:
            return puck_width;
#endif /*HOCKEY*/
	case SCOUT:
	    return kli_scout_width;
	case DESTROYER:
	    return kli_destroyer_width;
	case CRUISER:
	    return kli_cruiser_width;
	case BATTLESHIP:
	    return kli_battleship_width;
	case ASSAULT:
	    return kli_assault_width;
	case STARBASE:
	    return kli_starbase_width;
	case JUMPSHIP:
	    return kli_jumpship_width;
	case FLAGSHIP:
	    return kli_galaxy_width;
	case GALAXY:
	    return kli_galaxy_width;
	case WARBASE:
	    return kli_warbase_width;
	case LIGHTCRUISER:
	    return kli_lightcruiser_width;
	case CARRIER:
	    return kli_carrier_height;
	case UTILITY:
	    return kli_utility_width;
	case PATROL:
	    return kli_patrol_width;
	}
    case 3:
	switch (shipn) {
#ifdef HOCKEY
	case PUCK:
            return puck_width;
#endif /*HOCKEY*/
	case SCOUT:
	    return ori_scout_width;
	case DESTROYER:
	    return ori_destroyer_width;
	case CRUISER:
	    return ori_cruiser_width;
	case BATTLESHIP:
	    return ori_battleship_width;
	case ASSAULT:
	    return ori_assault_width;
	case STARBASE:
	    return ori_starbase_width;
	case JUMPSHIP:
	    return ori_jumpship_width;
	case FLAGSHIP:
	    return ori_galaxy_width;
	case GALAXY:
	    return ori_galaxy_width;
	case WARBASE:
	    return ori_warbase_width;
	case LIGHTCRUISER:
	    return ori_lightcruiser_width;
	case CARRIER:
	    return ori_carrier_height;
	case UTILITY:
	    return ori_utility_width;
	case PATROL:
	    return ori_patrol_width;
	}
    case -1:
	switch (shipn) {
#ifdef HOCKEY
	case PUCK:
	    return puck_width;
#endif /*HOCKEY*/
	case SCOUT:
	    return ind_scout_width;
	case DESTROYER:
	    return ind_destroyer_width;
	case CRUISER:
	    return ind_cruiser_width;
	case BATTLESHIP:
	    return ind_battleship_width;
	case ASSAULT:
	    return ind_assault_width;
	case STARBASE:
	    return ind_starbase_width;
	case JUMPSHIP:
	    return ind_starbase_width;
	case FLAGSHIP:
	    return ind_galaxy_width;
	case GALAXY:
	    return ind_galaxy_width;
	case WARBASE:
	    return ind_starbase_width;
	case LIGHTCRUISER:
	    return ind_lightcruiser_width;
	case CARRIER:
	    return ind_carrier_height;
	case UTILITY:
	    return ind_utility_width;
	case PATROL:
	    return ind_patrol_width;
	}
    }
#endif				/* NOSHIPBITMAPS */
    return 20;
}


static int
get_ship_height(team, shipn)
    int     team, shipn;
{
#ifndef NOSHIPBITMAPS
    if (shipn == ATT && paradise)
	return att_height;
    switch (team) {
    case 0:
	switch (shipn) {
#ifdef HOCKEY
	case PUCK:
	    return puck_height;
#endif /*HOCKEY*/
	case SCOUT:
	    return fed_scout_height;
	case DESTROYER:
	    return fed_destroyer_height;
	case CRUISER:
	    return fed_cruiser_height;
	case BATTLESHIP:
	    return fed_battleship_height;
	case ASSAULT:
	    return fed_assault_height;
	case STARBASE:
	    return fed_starbase_height;
	case JUMPSHIP:
	    return fed_jumpship_height;
	case FLAGSHIP:
	    return fed_galaxy_height;
	case GALAXY:
	    return fed_galaxy_height;
	case WARBASE:
	    return fed_warbase_height;
	case LIGHTCRUISER:
	    return fed_lightcruiser_height;
	case CARRIER:
	    return fed_carrier_height;
	case UTILITY:
	    return fed_utility_height;
	case PATROL:
	    return fed_patrol_height;
	}
    case 1:
	switch (shipn) {
#ifdef HOCKEY
	case PUCK:
	    return puck_height;
#endif /*HOCKEY*/
	case SCOUT:
	    return rom_scout_height;
	case DESTROYER:
	    return rom_destroyer_height;
	case CRUISER:
	    return rom_cruiser_height;
	case BATTLESHIP:
	    return rom_battleship_height;
	case ASSAULT:
	    return rom_assault_height;
	case STARBASE:
	    return rom_starbase_height;
	case JUMPSHIP:
	    return rom_jumpship_height;
	case FLAGSHIP:
	    return rom_galaxy_height;
	case GALAXY:
	    return rom_galaxy_height;
	case WARBASE:
	    return rom_warbase_height;
	case LIGHTCRUISER:
	    return rom_lightcruiser_height;
	case CARRIER:
	    return rom_carrier_height;
	case UTILITY:
	    return rom_utility_height;
	case PATROL:
	    return rom_patrol_height;
	}
    case 2:
	switch (shipn) {
#ifdef HOCKEY
	case PUCK:
	    return puck_height;
#endif /*HOCKEY*/
	case SCOUT:
	    return kli_scout_height;
	case DESTROYER:
	    return kli_destroyer_height;
	case CRUISER:
	    return kli_cruiser_height;
	case BATTLESHIP:
	    return kli_battleship_height;
	case ASSAULT:
	    return kli_assault_height;
	case STARBASE:
	    return kli_starbase_height;
	case JUMPSHIP:
	    return kli_jumpship_height;
	case FLAGSHIP:
	    return kli_galaxy_height;
	case GALAXY:
	    return kli_galaxy_height;
	case WARBASE:
	    return kli_warbase_height;
	case LIGHTCRUISER:
	    return kli_lightcruiser_height;
	case CARRIER:
	    return kli_carrier_height;
	case UTILITY:
	    return kli_utility_height;
	case PATROL:
	    return kli_patrol_height;
	}
    case 3:
	switch (shipn) {
#ifdef HOCKEY
	case PUCK:
	    return puck_height;
#endif /*HOCKEY*/
	case SCOUT:
	    return ori_scout_height;
	case DESTROYER:
	    return ori_destroyer_height;
	case CRUISER:
	    return ori_cruiser_height;
	case BATTLESHIP:
	    return ori_battleship_height;
	case ASSAULT:
	    return ori_assault_height;
	case STARBASE:
	    return ori_starbase_height;
	case JUMPSHIP:
	    return ori_jumpship_height;
	case FLAGSHIP:
	    return ori_galaxy_height;
	case GALAXY:
	    return ori_galaxy_height;
	case WARBASE:
	    return ori_warbase_height;
	case LIGHTCRUISER:
	    return ori_lightcruiser_height;
	case CARRIER:
	    return ori_carrier_height;
	case UTILITY:
	    return ori_utility_height;
	case PATROL:
	    return ori_patrol_height;
	}
    case -1:
	switch (shipn) {
#ifdef HOCKEY
	case PUCK:
	    return puck_height;
#endif /*HOCKEY*/
	case SCOUT:
	    return ind_scout_height;
	case DESTROYER:
	    return ind_destroyer_height;
	case CRUISER:
	    return ind_cruiser_height;
	case BATTLESHIP:
	    return ind_battleship_height;
	case ASSAULT:
	    return ind_assault_height;
	case STARBASE:
	    return ind_starbase_height;
	case JUMPSHIP:
	    return ind_starbase_height;
	case FLAGSHIP:
	    return ind_galaxy_height;
	case GALAXY:
	    return ind_galaxy_height;
	case WARBASE:
	    return ind_starbase_height;
	case LIGHTCRUISER:
	    return ind_lightcruiser_height;
	case CARRIER:
	    return ind_carrier_height;
	case UTILITY:
	    return ind_utility_height;
	case PATROL:
	    return ind_patrol_height;
	}
    }
#endif	/* NOSHIPBITMAPS */
    return 20;
}

static int
get_ship_nviews(shipn)
    int     shipn;
{
    if (shipn == STARBASE ||
	shipn == WARBASE ||
	shipn == JUMPSHIP 
#ifdef HOCKEY
	|| shipn == PUCK
#endif /*HOCKEY*/
	)
	return 1;
    else
	return 16;
}

static unsigned char *
get_ship_bits(team, shipn, view)
    int     team, shipn;
    int     view;
{
#ifndef NOSHIPBITMAPS
    if (shipn == ATT && paradise) {
	if (view > 0)
	    view = 0;
	return att_bits[view];
    }
#endif
    if (view > 16)
	view = 0;
    switch (team) {
    case 0:
#ifndef NOSHIPBITMAPS
	switch (shipn) {
#ifdef HOCKEY
	case PUCK:
	    return puck_bits;
#endif /*HOCKEY*/
	case SCOUT:
	    return fed_scout_bits[view];
	case DESTROYER:
	    return fed_destroyer_bits[view];
	case CRUISER:
	    return fed_cruiser_bits[view];
	case BATTLESHIP:
	    return fed_battleship_bits[view];
	case ASSAULT:
	    return fed_assault_bits[view];
	case STARBASE:
	    return fed_starbase_bits;
	case JUMPSHIP:
	    return fed_jumpship_bits;
	case FLAGSHIP:
	    return fed_galaxy_bits[view];
	case GALAXY:
	    return fed_galaxy_bits[view];
	case WARBASE:
	    return fed_warbase_bits;
	case LIGHTCRUISER:
	    return fed_lightcruiser_bits[view];
	case CARRIER:
	    return fed_carrier_bits[view];
	case UTILITY:
	    return fed_utility_bits[view];
	case PATROL:
	    return fed_patrol_bits[view];
	}
#else
	if (get_ship_nviews(shipn) == 1)
	    return fed_starbase_bits;
	else
	    return fed_cruiser_bits[view];
#endif
    case 1:
#ifndef NOSHIPBITMAPS
	switch (shipn) {
#ifdef HOCKEY
	case PUCK:
	    return puck_bits;
#endif /*HOCKEY*/
	case SCOUT:
	    return rom_scout_bits[view];
	case DESTROYER:
	    return rom_destroyer_bits[view];
	case CRUISER:
	    return rom_cruiser_bits[view];
	case BATTLESHIP:
	    return rom_battleship_bits[view];
	case ASSAULT:
	    return rom_assault_bits[view];
	case STARBASE:
	    return rom_starbase_bits;
	case JUMPSHIP:
	    return rom_jumpship_bits;
	case FLAGSHIP:
	    return rom_galaxy_bits[view];
	case GALAXY:
	    return rom_galaxy_bits[view];
	case WARBASE:
	    return rom_warbase_bits;
	case LIGHTCRUISER:
	    return rom_lightcruiser_bits[view];
	case CARRIER:
	    return rom_carrier_bits[view];
	case UTILITY:
	    return rom_utility_bits[view];
	case PATROL:
	    return rom_patrol_bits[view];
	}
#else
	if (get_ship_nviews(shipn) == 1)
	    return rom_starbase_bits;
	else
	    return rom_cruiser_bits[view];
#endif
    case 2:
#ifndef NOSHIPBITMAPS
	switch (shipn) {
#ifdef HOCKEY
	case PUCK:
	    return puck_bits;
#endif /*HOCKEY*/
	case SCOUT:
	    return kli_scout_bits[view];
	case DESTROYER:
	    return kli_destroyer_bits[view];
	case CRUISER:
	    return kli_cruiser_bits[view];
	case BATTLESHIP:
	    return kli_battleship_bits[view];
	case ASSAULT:
	    return kli_assault_bits[view];
	case STARBASE:
	    return kli_starbase_bits;
	case JUMPSHIP:
	    return kli_jumpship_bits;
	case FLAGSHIP:
	    return kli_galaxy_bits[view];
	case GALAXY:
	    return kli_galaxy_bits[view];
	case WARBASE:
	    return kli_warbase_bits;
	case LIGHTCRUISER:
	    return kli_lightcruiser_bits[view];
	case CARRIER:
	    return kli_carrier_bits[view];
	case UTILITY:
	    return kli_utility_bits[view];
	case PATROL:
	    return kli_patrol_bits[view];
	}
#else
	if (get_ship_nviews(shipn) == 1)
	    return kli_starbase_bits;
	else
	    return kli_cruiser_bits[view];
#endif
    case 3:
#ifndef NOSHIPBITMAPS
	switch (shipn) {
#ifdef HOCKEY
	case PUCK:
	    return puck_bits;
#endif /*HOCKEY*/
	case SCOUT:
	    return ori_scout_bits[view];
	case DESTROYER:
	    return ori_destroyer_bits[view];
	case CRUISER:
	    return ori_cruiser_bits[view];
	case BATTLESHIP:
	    return ori_battleship_bits[view];
	case ASSAULT:
	    return ori_assault_bits[view];
	case STARBASE:
	    return ori_starbase_bits;
	case JUMPSHIP:
	    return ori_jumpship_bits;
	case FLAGSHIP:
	    return ori_galaxy_bits[view];
	case GALAXY:
	    return ori_galaxy_bits[view];
	case WARBASE:
	    return ori_warbase_bits;
	case LIGHTCRUISER:
	    return ori_lightcruiser_bits[view];
	case CARRIER:
	    return ori_carrier_bits[view];
	case UTILITY:
	    return ori_utility_bits[view];
	case PATROL:
	    return ori_patrol_bits[view];
	}
#else
	if (get_ship_nviews(shipn) == 1)
	    return ori_starbase_bits;
	else
	    return ori_cruiser_bits[view];
#endif
    case -1:
#ifndef NOSHIPBITMAPS
	switch (shipn) {
#ifdef HOCKEY
	case PUCK:
	    return puck_bits;
#endif /*HOCKEY*/
	case SCOUT:
	    return ind_scout_bits[view];
	case DESTROYER:
	    return ind_destroyer_bits[view];
	case CRUISER:
	    return ind_cruiser_bits[view];
	case BATTLESHIP:
	    return ind_battleship_bits[view];
	case ASSAULT:
	    return ind_assault_bits[view];
	case STARBASE:
	    return ind_starbase_bits;
	case JUMPSHIP:
	    return ind_starbase_bits;
	case FLAGSHIP:
	    return ind_galaxy_bits[view];
	case GALAXY:
	    return ind_galaxy_bits[view];
	case WARBASE:
	    return ind_starbase_bits;
	case LIGHTCRUISER:
	    return ind_lightcruiser_bits[view];
	case CARRIER:
	    return ind_carrier_bits[view];
	case UTILITY:
	    return ind_utility_bits[view];
	case PATROL:
	    return ind_patrol_bits[view];
	}
#else
	if (get_ship_nviews(shipn) == 1)
	    return fed_starbase_bits;
	else
	    return fed_cruiser_bits[view];
#endif
    }
    return fed_cruiser_bits[view];
}


/* points at the beginning of the fed ship shapes.  Independent are
   at negative indices */
static struct ship_shape *all_ship_shapes = 0;

struct ship_shape *
shape_of_ship(team, shipclass)
    int     team, shipclass;
{
    if (team < -1 || team >= number_of_teams ||
	shipclass < 0 || shipclass >= nshiptypes)
	return &all_ship_shapes[-nshiptypes];
    return &all_ship_shapes[team * nshiptypes + shipclass];
}

void
clear_one_ship_shape(shp)
    struct ship_shape *shp;
{
    int     j;
    for (j = 0; j < shp->nviews; j++) {
	W_FreeBitmap(shp->bmap[j]);
    }
    shp->nviews = 0;
    free(shp->bmap);
    shp->bmap = 0;
    W_FreeBitmap(shp->shield);
    shp->shield = 0;
}

void
free_shipshapes()
{
    /* don't forget that IND offset */
    int     race, i;
    if (!all_ship_shapes)	/* if nothing there to begin with */
	return;
    for (race = -1; race < number_of_teams; race++) {
	for (i = 0; i < nshiptypes; i++) {
	    clear_one_ship_shape(shape_of_ship(race, i));
	}
    }
    free(all_ship_shapes - nshiptypes);
    all_ship_shapes = 0;
}

void
slurp_ship_bitmaps()
{
    int     i, race, k;
    int     width, height, size = 0;
    int     nviews;		/* NYI */
    unsigned char *buf = 0, *buf2;
    char   *freeme;
    char   *mainbitmapdir, *bitmapdir;
    static char path[MAXPATHLEN];

    if (all_ship_shapes == 0) {
	all_ship_shapes = nshiptypes + (struct ship_shape *)
	    malloc(sizeof(*all_ship_shapes) * (number_of_teams + 1) * nshiptypes);
    }
    mainbitmapdir = stringDefault("shipBitmapPath",
#ifndef AMIGA			/* worked this way, sort of... was annoying. */
				  "/usr/games/lib/netrek"
#else
				  "netrek:graphics"
#endif				/* AMIGA */
	);
    mainbitmapdir = expandFilename(mainbitmapdir);

    for (race = -1 /* IND */ ; race < number_of_teams; race++) {
	freeme = NULL;
	/* you can now have a different bitmapDir for each race [BDyess] */
	sprintf(path, "shipBitmapPath.%d", race);
	if ((bitmapdir = getdefault(path)) == NULL)
	    bitmapdir = mainbitmapdir;
	else
	    bitmapdir = freeme = expandFilename((char *) strdup(bitmapdir));
	for (k = 0; k < nshiptypes; k++) {
	    struct ship_shape *curr_shape = shape_of_ship(race, k);
	    FILE   *fp;
	    sprintf(path, "%s/R%d.C%d", bitmapdir, race, k);

	    fp = fopen(path, "r");
	    if (fp == 0) {
		if (errno != ENOENT) {
		    fprintf(stderr, "Error accessing ship bitmap file %s:", path);
		    perror("");
		}
		nviews = get_ship_nviews(k, 0);
		width = get_ship_width(race, k, 0);
		height = get_ship_height(race, k, 0);
	    } else {
		fread(&nviews, sizeof(nviews), 1, fp);
		nviews = ntohl(nviews);
		fread(&width, sizeof(width), 1, fp);
		width = ntohl(width);
		fread(&height, sizeof(height), 1, fp);
		height = ntohl(height);
		if (nviews > get_ship_nviews(k, 0))
		    nviews = get_ship_nviews(k, 0);
		size = (width + 7) / 8 * height;
		buf = (unsigned char *) malloc(size);
	    }

	    curr_shape->nviews = nviews /* nviews */ ;
	    curr_shape->width = width;
	    curr_shape->height = height;
	    curr_shape->shield = W_MakeShieldBitmap(width, height, w);

	    curr_shape->bmap = (W_Icon *) malloc(sizeof(*curr_shape->bmap) *
						 nviews);

	    for (i = 0; i < nviews; i++) {
		if (fp) {
		    fread(buf, size, 1, fp);
		    curr_shape->bmap[i] =
			W_StoreBitmap(width, height, buf, w);
		} else {
		    buf2 = get_ship_bits(race, k, i);
		    curr_shape->bmap[i] =
			W_StoreBitmap(width, height, buf2, w);
		}

#if 0
		/* these widths and heights are not necessarily correct */
		if (fp)
		    buf2 = get_ship_bits(race, k, i, blk_altbits);
		else
		    buf2 = get_ship_bits(race, k, i, !blk_altbits);

		curr_shape->bmap[i + (blk_altbits ? 0 : nviews)] =
		    W_StoreBitmap(width, height, buf2, w);
#endif
	    }

	    if (fp) {
		free(buf);
		fclose(fp);
	    }
	}
	if (freeme)
	    free(freeme);
    }
}

void
replace_shipshape(race, shiptype, nviews, width, height)
    int     race, shiptype, nviews, width, height;
{
    struct ship_shape *shp = shape_of_ship(race, shiptype);
    int     i;

    clear_one_ship_shape(shp);

    shp->nviews = nviews;
    shp->bmap = (W_Icon *) malloc(sizeof(*shp->bmap) * nviews);
    shp->width = width;
    shp->height = height;
    shp->shield = W_MakeShieldBitmap(width, height, w);
    for (i = 0; i < nviews; i++) {
	/* we really should check the files again. */
	shp->bmap[i] = W_StoreBitmap(get_ship_width(race, shiptype),
				     get_ship_height(race, shiptype),
				     get_ship_bits(race, shiptype, i, 0),
				     w);
#if 0
	shp->bmap[i + nviews] = W_StoreBitmap(get_ship_width(race, shiptype),
					    get_ship_height(race, shiptype),
					get_ship_bits(race, shiptype, i, 0),
					      w);
#endif
    }
}


void
replace_ship_bitmap(race, shiptype, view, bits)
    int     race, shiptype, view;
    unsigned char *bits;
{
    struct ship_shape *shp = shape_of_ship(race, shiptype);

    if (view >= shp->nviews) {
	fprintf(stderr, "race %d, ship class %d: view %d out of range (0..%d)\n",
		race, shiptype, view, shp->nviews - 1);
	return;
    }
    W_FreeBitmap(shp->bmap[view]);
    /* store the bitmaps into the auxiliary view */
    shp->bmap[view] = W_StoreBitmap(shp->width, shp->height, bits, w);
}