diff options
Diffstat (limited to 'pygame/bitmask.h')
-rwxr-xr-x | pygame/bitmask.h | 138 |
1 files changed, 138 insertions, 0 deletions
diff --git a/pygame/bitmask.h b/pygame/bitmask.h new file mode 100755 index 0000000..9e4dcbf --- /dev/null +++ b/pygame/bitmask.h @@ -0,0 +1,138 @@ +/* + Bitmask 1.7 - A pixel-perfect collision detection library. + + Copyright (C) 2002-2005 Ulf Ekstrom except for the bitcount + function which is copyright (C) Donald W. Gillies, 1992. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with this library; if not, write to the Free + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ +#ifndef BITMASK_H +#define BITMASK_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include <limits.h> +/* Define INLINE for different compilers. If your compiler does not + support inlining then there might be a performance hit in + bitmask_overlap_area(). +*/ +#ifndef INLINE +# ifdef __GNUC__ +# define INLINE inline +# else +# ifdef _MSC_VER +# define INLINE __inline +# else +# define INLINE +# endif +# endif +#endif + +#define BITMASK_W unsigned long int +#define BITMASK_W_LEN (sizeof(BITMASK_W)*CHAR_BIT) +#define BITMASK_W_MASK (BITMASK_W_LEN - 1) +#define BITMASK_N(n) ((BITMASK_W)1 << (n)) + +typedef struct bitmask +{ + int w,h; + BITMASK_W bits[1]; +} bitmask_t; + +/* Creates a bitmask of width w and height h, where + w and h must both be greater than 0. + The mask is automatically cleared when created. + */ +bitmask_t *bitmask_create(int w, int h); + +/* Frees all the memory allocated by bitmask_create for m. */ +void bitmask_free(bitmask_t *m); + +/* Clears all bits in the mask */ +void bitmask_clear(bitmask_t *m); + +/* Sets all bits in the mask */ +void bitmask_fill(bitmask_t *m); + +/* Flips all bits in the mask */ +void bitmask_invert(bitmask_t *m); + +/* Counts the bits in the mask */ +unsigned int bitmask_count(bitmask_t *m); + +/* Returns nonzero if the bit at (x,y) is set. Coordinates start at + (0,0) */ +static INLINE int bitmask_getbit(const bitmask_t *m, int x, int y) +{ + return (m->bits[x/BITMASK_W_LEN*m->h + y] & BITMASK_N(x & BITMASK_W_MASK)) != 0; +} + +/* Sets the bit at (x,y) */ +static INLINE void bitmask_setbit(bitmask_t *m, int x, int y) +{ + m->bits[x/BITMASK_W_LEN*m->h + y] |= BITMASK_N(x & BITMASK_W_MASK); +} + +/* Clears the bit at (x,y) */ +static INLINE void bitmask_clearbit(bitmask_t *m, int x, int y) +{ + m->bits[x/BITMASK_W_LEN*m->h + y] &= ~BITMASK_N(x & BITMASK_W_MASK); +} + +/* Returns nonzero if the masks overlap with the given offset. + The overlap tests uses the following offsets (which may be negative): + + +----+----------.. + |A | yoffset + | +-+----------.. + +--|B + |xoffset + | | + : : +*/ +int bitmask_overlap(const bitmask_t *a, const bitmask_t *b, int xoffset, int yoffset); + +/* Like bitmask_overlap(), but will also give a point of intersection. + x and y are given in the coordinates of mask a, and are untouched + if there is no overlap. */ +int bitmask_overlap_pos(const bitmask_t *a, const bitmask_t *b, + int xoffset, int yoffset, int *x, int *y); + +/* Returns the number of overlapping 'pixels' */ +int bitmask_overlap_area(const bitmask_t *a, const bitmask_t *b, int xoffset, int yoffset); + +/* Fills a mask with the overlap of two other masks. A bitwise AND. */ +void bitmask_overlap_mask (const bitmask_t *a, const bitmask_t *b, bitmask_t *c, int xoffset, int yoffset); + +/* Draws mask b onto mask a (bitwise OR). Can be used to compose large + (game background?) mask from several submasks, which may speed up + the testing. */ + +void bitmask_draw(bitmask_t *a, const bitmask_t *b, int xoffset, int yoffset); + +void bitmask_erase(bitmask_t *a, const bitmask_t *b, int xoffset, int yoffset); + +/* Return a new scaled bitmask, with dimensions w*h. The quality of the + scaling may not be perfect for all circumstances, but it should + be reasonable. If either w or h is 0 a clear 1x1 mask is returned. */ +bitmask_t *bitmask_scale(const bitmask_t *m, int w, int h); + +#ifdef __cplusplus +} /* End of extern "C" { */ +#endif + +#endif |