bitmask.h 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146
  1. /*
  2. Bitmask 1.7 - A pixel-perfect collision detection library.
  3. Copyright (C) 2002-2005 Ulf Ekstrom except for the bitcount
  4. function which is copyright (C) Donald W. Gillies, 1992.
  5. This library is free software; you can redistribute it and/or
  6. modify it under the terms of the GNU Library General Public
  7. License as published by the Free Software Foundation; either
  8. version 2 of the License, or (at your option) any later version.
  9. This library is distributed in the hope that it will be useful,
  10. but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  12. Library General Public License for more details.
  13. You should have received a copy of the GNU Library General Public
  14. License along with this library; if not, write to the Free
  15. Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  16. */
  17. #ifndef BITMASK_H
  18. #define BITMASK_H
  19. #ifdef __cplusplus
  20. extern "C" {
  21. #endif
  22. #include <limits.h>
  23. /* Define INLINE for different compilers. If your compiler does not
  24. support inlining then there might be a performance hit in
  25. bitmask_overlap_area().
  26. */
  27. #ifndef INLINE
  28. # ifdef __GNUC__
  29. # define INLINE inline
  30. # else
  31. # ifdef _MSC_VER
  32. # define INLINE __inline
  33. # else
  34. # define INLINE
  35. # endif
  36. # endif
  37. #endif
  38. #define BITMASK_W unsigned long int
  39. #define BITMASK_W_LEN (sizeof(BITMASK_W)*CHAR_BIT)
  40. #define BITMASK_W_MASK (BITMASK_W_LEN - 1)
  41. #define BITMASK_N(n) ((BITMASK_W)1 << (n))
  42. typedef struct bitmask
  43. {
  44. int w,h;
  45. BITMASK_W bits[1];
  46. } bitmask_t;
  47. /* Creates a bitmask of width w and height h, where
  48. w and h must both be greater than or equal to 0.
  49. The mask is automatically cleared when created.
  50. */
  51. bitmask_t *bitmask_create(int w, int h);
  52. /* Frees all the memory allocated by bitmask_create for m. */
  53. void bitmask_free(bitmask_t *m);
  54. /* Clears all bits in the mask */
  55. void bitmask_clear(bitmask_t *m);
  56. /* Sets all bits in the mask */
  57. void bitmask_fill(bitmask_t *m);
  58. /* Flips all bits in the mask */
  59. void bitmask_invert(bitmask_t *m);
  60. /* Counts the bits in the mask */
  61. unsigned int bitmask_count(bitmask_t *m);
  62. /* Returns nonzero if the bit at (x,y) is set. Coordinates start at
  63. (0,0) */
  64. static INLINE int bitmask_getbit(const bitmask_t *m, int x, int y)
  65. {
  66. return (m->bits[x/BITMASK_W_LEN*m->h + y] & BITMASK_N(x & BITMASK_W_MASK)) != 0;
  67. }
  68. /* Sets the bit at (x,y) */
  69. static INLINE void bitmask_setbit(bitmask_t *m, int x, int y)
  70. {
  71. m->bits[x/BITMASK_W_LEN*m->h + y] |= BITMASK_N(x & BITMASK_W_MASK);
  72. }
  73. /* Clears the bit at (x,y) */
  74. static INLINE void bitmask_clearbit(bitmask_t *m, int x, int y)
  75. {
  76. m->bits[x/BITMASK_W_LEN*m->h + y] &= ~BITMASK_N(x & BITMASK_W_MASK);
  77. }
  78. /* Returns nonzero if the masks overlap with the given offset.
  79. The overlap tests uses the following offsets (which may be negative):
  80. +----+----------..
  81. |A | yoffset
  82. | +-+----------..
  83. +--|B
  84. |xoffset
  85. | |
  86. : :
  87. */
  88. int bitmask_overlap(const bitmask_t *a, const bitmask_t *b, int xoffset, int yoffset);
  89. /* Like bitmask_overlap(), but will also give a point of intersection.
  90. x and y are given in the coordinates of mask a, and are untouched
  91. if there is no overlap. */
  92. int bitmask_overlap_pos(const bitmask_t *a, const bitmask_t *b,
  93. int xoffset, int yoffset, int *x, int *y);
  94. /* Returns the number of overlapping 'pixels' */
  95. int bitmask_overlap_area(const bitmask_t *a, const bitmask_t *b, int xoffset, int yoffset);
  96. /* Fills a mask with the overlap of two other masks. A bitwise AND. */
  97. void bitmask_overlap_mask (const bitmask_t *a, const bitmask_t *b, bitmask_t *c, int xoffset, int yoffset);
  98. /* Draws mask b onto mask a (bitwise OR). Can be used to compose large
  99. (game background?) mask from several submasks, which may speed up
  100. the testing. */
  101. void bitmask_draw(bitmask_t *a, const bitmask_t *b, int xoffset, int yoffset);
  102. void bitmask_erase(bitmask_t *a, const bitmask_t *b, int xoffset, int yoffset);
  103. /* Return a new scaled bitmask, with dimensions w*h. The quality of the
  104. scaling may not be perfect for all circumstances, but it should
  105. be reasonable. If either w or h is 0 a clear 1x1 mask is returned. */
  106. bitmask_t *bitmask_scale(const bitmask_t *m, int w, int h);
  107. /* Convolve b into a, drawing the output into o, shifted by offset. If offset
  108. * is 0, then the (x,y) bit will be set if and only if
  109. * bitmask_overlap(a, b, x - b->w - 1, y - b->h - 1) returns true.
  110. *
  111. * Modifies bits o[xoffset ... xoffset + a->w + b->w - 1)
  112. * [yoffset ... yoffset + a->h + b->h - 1). */
  113. void bitmask_convolve(const bitmask_t *a, const bitmask_t *b, bitmask_t *o, int xoffset, int yoffset);
  114. #ifdef __cplusplus
  115. } /* End of extern "C" { */
  116. #endif
  117. #endif