btmux/autom4te.cache/
btmux/doc/.svn/
btmux/event/.svn/
btmux/game/.svn/
btmux/game/bin/.svn/
btmux/game/data/.svn/
btmux/game/logs/.svn/
btmux/game/maps/
btmux/game/maps/.svn/
btmux/game/maps/.svn/prop-base/
btmux/game/maps/.svn/props/
btmux/game/maps/.svn/text-base/
btmux/game/maps/.svn/wcprops/
btmux/game/mechs/
btmux/game/mechs/.svn/
btmux/game/mechs/.svn/prop-base/
btmux/game/mechs/.svn/props/
btmux/game/mechs/.svn/text-base/
btmux/game/mechs/.svn/wcprops/
btmux/game/text/.svn/
btmux/include/.svn/
btmux/misc/
btmux/misc/.svn/
btmux/misc/.svn/prop-base/
btmux/misc/.svn/props/
btmux/misc/.svn/text-base/
btmux/misc/.svn/wcprops/
btmux/python/
btmux/python/.svn/
btmux/python/.svn/prop-base/
btmux/python/.svn/props/
btmux/python/.svn/text-base/
btmux/python/.svn/wcprops/
btmux/src/.svn/prop-base/
btmux/src/.svn/props/
btmux/src/.svn/text-base/
btmux/src/.svn/wcprops/
btmux/src/hcode/.svn/
btmux/src/hcode/btech/
btmux/src/hcode/btech/.svn/
btmux/src/hcode/btech/.svn/prop-base/
btmux/src/hcode/btech/.svn/props/
btmux/src/hcode/btech/.svn/text-base/
btmux/src/hcode/btech/.svn/wcprops/
btmux/src/hcode/include/.svn/
/*
 * $Id: map.bits.c,v 1.1.1.1 2005/01/11 21:18:07 kstevens Exp $
 *
 * Author: Markus Stenberg <fingon@iki.fi>
 *
 *  Copyright (c) 1996 Markus Stenberg
 *       All rights reserved
 *
 * Created: Tue Oct 22 16:32:09 1996 fingon
 * Last modified: Fri Jun 12 23:10:43 1998 fingon
 *
 */

#include "mech.h"
#include "create.h"

#define CHELO(a,b,c,d) if ((tmp=fread(a,b,c,d)) != c) { fprintf (stderr, "Error loading mapdynamic for #%d - couldn't find enough entries! (found: %d, should: %d)\n", map->mynum, tmp, c); fflush(stderr); exit(1); }
#define CHESA(a,b,c,d) if ((tmp=fwrite(a,b,c,d)) != c) { fprintf (stderr, "Error writing mapdynamic for #%d - couldn't find enough entries! (found: %d, should: %d)\n", map->mynum, tmp, c); fflush(stderr); exit(1); }

#define realnum(x)          ((x) / 4 + ((x) % 4 ? 1 : 0))
#define boffs(x)            (2 * ((x) % 4))
#define boffsbit(x,n)       ((1<<boffs(x))*n)
#define btsetbit(arr,x,y,n)   \
create_if_neccessary(arr,map,y);arr[y][realnum(x)] |= boffsbit(x,n)
#define btunsetbit(arr,x,y,n) if (arr[y]) arr[y][realnum(x)] &= ~(boffsbit(x,n))
#define btissetbit(arr,x,y,n) (arr[y][realnum(x)] & boffsbit(x,n))

#define BIT_MINE   1
#define BIT_HANGAR 2

/* Main idea: By using 2 bits / hex in external array, we can _fast_
   figure out if a certain hex has mines / hangars or not. Downside is
   keeping the table up to date. */

static void create_if_neccessary(unsigned char **foo, MAP * map, int y)
{
    int xs = map->map_width;

    if (!foo[y])
	Create(foo[y], unsigned char, realnum(xs));
}

/* All the nasty bits on the map ;) */
void map_load_bits(FILE * f, MAP * map)
{
    int xs = map->map_width;
    int ys = map->map_height;
    unsigned char **foo;
    int tmp, i;

    Create(foo, unsigned char *, ys);
    CHELO(foo, sizeof(unsigned char *), ys, f);

    for (i = 0; i < ys; i++)
	if (foo[i]) {
	    Create(foo[i], unsigned char, realnum(xs));
	    CHELO(foo[i], sizeof(unsigned char), realnum(xs), f);
	}
}

void map_save_bits(FILE * f, MAP * map, mapobj * obj)
{
    int tmp;
    int i, j, c, tc = 0;
    unsigned char **foo;
    int xs = map->map_width;
    int ys = map->map_height;
    unsigned char tmpb;

#define outbyte(a) tmpb=(a);fwrite(&tmpb, 1, 1, f);
    foo = (unsigned char **) ((void *) obj->datai);
    /* First, we clean up our act */
    for (i = 0; i < ys; i++) {
	c = 0;
	if (foo[i]) {
	    for (j = 0; j < realnum(xs); j++)
		if (foo[i][j])
		    c++;
	    if (!c) {
		free((void *) foo[i]);
		foo[i] = NULL;
	    } else
		tc += c;
	}
    }
    if (!tc) {
	/* We don't want to save worthless shit */
	/* On other hand, cleaning us out of memory would take too
	   much trouble compared to the worth. Therefore, during next
	   cleanup (reboot), this structure does a disappearance act. */
	return;
    }
    outbyte(TYPE_BITS + 1);
    CHESA(foo, sizeof(unsigned char *), ys, f);

    for (i = 0; i < ys; i++)
	if (foo[i])
	    CHESA(foo[i], sizeof(unsigned char), realnum(xs), f);
}

/* Okay, now we got code to load / save the bits.. but what will we do with
   them? */

/* Nasty stuff starts here ;) */

static unsigned char **grab_us_an_array(MAP * map)
{
    unsigned char **foo;
    mapobj foob;
    int ys = map->map_height;

    if (!map->mapobj[TYPE_BITS]) {
	Create(foo, unsigned char *, ys);

	foob.datai = (int) ((void *) foo);
	add_mapobj(map, &map->mapobj[TYPE_BITS], &foob, 0);
    } else
	foo = (unsigned char **) ((void *) map->mapobj[TYPE_BITS]->datai);
    return foo;
}

void set_hex_enterable(MAP * map, int x, int y)
{
    unsigned char **foo;

    foo = grab_us_an_array(map);
    btsetbit(foo, x, y, BIT_HANGAR);
}

void set_hex_mine(MAP * map, int x, int y)
{
    unsigned char **foo;

    foo = grab_us_an_array(map);
    btsetbit(foo, x, y, BIT_MINE);
}

void unset_hex_enterable(MAP * map, int x, int y)
{
    unsigned char **foo;

    foo = grab_us_an_array(map);
    btunsetbit(foo, x, y, BIT_HANGAR);
}

void unset_hex_mine(MAP * map, int x, int y)
{
    unsigned char **foo;

    foo = grab_us_an_array(map);
    btunsetbit(foo, x, y, BIT_MINE);
}

int is_mine_hex(MAP * map, int x, int y)
{
    unsigned char **foo;

    if (!map)
	return 0;
    if (!map->mapobj[TYPE_BITS])
	return 0;
    foo = grab_us_an_array(map);
    if (!foo[y])
	return 0;
    return (btissetbit(foo, x, y, BIT_MINE));
}

int is_hangar_hex(MAP * map, int x, int y)
{
    unsigned char **foo;

    if (!map)
	return 0;
    if (!map->mapobj[TYPE_BITS])
	return 0;
    foo = grab_us_an_array(map);
    if (!foo[y])
	return 0;
    return (btissetbit(foo, x, y, BIT_HANGAR));
}

void clear_hex_bits(MAP * map, int bits)
{
    int xs = map->map_width;
    int ys = map->map_height;
    int i, j;
    unsigned char **foo;

    if (!map->mapobj[TYPE_BITS])
	return;
    foo = grab_us_an_array(map);
    for (i = 0; i < ys; i++)
	if (foo[i])
	    for (j = 0; j < xs; j++) {
		switch (bits) {
		case 1:
		case 2:
		    if (btissetbit(foo, j, i, bits))
			btunsetbit(foo, j, i, bits);
		    break;
		case 0:
		    if (btissetbit(foo, j, i, 1))
			btunsetbit(foo, j, i, 1);
		    if (btissetbit(foo, j, i, 2))
			btunsetbit(foo, j, i, 2);
		    break;
		}
	    }
}

int bit_size(MAP * map)
{
    int xs = map->map_width;
    int ys = map->map_height;
    int i, s = 0;
    unsigned char **foo;

    if (!map->mapobj[TYPE_BITS])
	return 0;
    foo = grab_us_an_array(map);
    for (i = 0; i < ys; i++)
	if (foo[i])
	    s += realnum(xs);
    return s;
}