Web   ·   Wiki   ·   Activities   ·   Blog   ·   Lists   ·   Chat   ·   Meeting   ·   Bugs   ·   Git   ·   Translate   ·   Archive   ·   People   ·   Donate
summaryrefslogtreecommitdiffstats
path: root/pygame/bitmask.h
blob: 9e4dcbf4f15d288cafa83a3a1911c704bc2483f1 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
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