X-Git-Url: https://git.verplant.org/?a=blobdiff_plain;f=src%2Fbitmask.cpp;h=65500903bf0823988a6405b2492000c3e99445de;hb=72f573a5e7226d35c8b2b5def07848178b2f046c;hp=65c927a4093bc0198de7f6db549051e11f8ab283;hpb=5d84559cf5a5a13570aa7a071a7c1040196067af;p=supertux.git diff --git a/src/bitmask.cpp b/src/bitmask.cpp index 65c927a40..65500903b 100644 --- a/src/bitmask.cpp +++ b/src/bitmask.cpp @@ -23,8 +23,9 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -#include -#include +#include +#include +#include #include "bitmask.h" #define MIN(a,b) ((a) < (b) ? (a) : (b)) @@ -46,6 +47,8 @@ bitmask *bitmask_create(int w, int h) return temp; } +/* (C) Tobias Glaesser , 2004. + This function isn't available in the original bitmask library. */ bitmask *bitmask_create_SDL(SDL_Surface* surf) { bitmask* pbitmask = bitmask_create(surf->w, surf->h); @@ -56,7 +59,7 @@ bitmask *bitmask_create_SDL(SDL_Surface* surf) if(surf->format->BytesPerPixel != 4) //This function only works for true-color surfaces with an alpha channel return 0; - + fmt = surf->format; for(h = 0; h <= surf->h; ++h) { @@ -81,6 +84,16 @@ void bitmask_free(bitmask *m) free(m); } +void bitmask_clear(bitmask *m) +{ + memset(m->bits,0,m->h*((m->w - 1)/BITW_LEN + 1)*sizeof(BITW)); +} + +void bitmask_fill(bitmask *m) +{ + memset(m->bits,255,m->h*((m->w - 1)/BITW_LEN + 1)*sizeof(BITW)); +} + int bitmask_overlap(const bitmask *a,const bitmask *b,int xoffset, int yoffset) { BITW *a_entry,*a_end; @@ -184,24 +197,26 @@ int bitmask_overlap_pos(const bitmask *a,const bitmask *b,int xoffset, int yoffs BITW *a_entry,*a_end; BITW *b_entry; BITW *ap,*bp; - int shift,rshift,i,astripes,bstripes; + int shift,rshift,i,astripes,bstripes,xbase; if ((xoffset >= a->w) || (yoffset >= a->h) || (yoffset <= - b->h)) return 0; if (xoffset >= 0) { + xbase = xoffset/BITW_LEN; /* first stripe from mask a */ if (yoffset >= 0) { - a_entry = a->bits + a->h*(xoffset/BITW_LEN) + yoffset; + a_entry = a->bits + a->h*xbase + yoffset; a_end = a_entry + MIN(b->h,a->h - yoffset); b_entry = b->bits; } else { - a_entry = a->bits + a->h*(xoffset/BITW_LEN); + a_entry = a->bits + a->h*xbase; a_end = a_entry + MIN(b->h + yoffset,a->h); b_entry = b->bits - yoffset; + yoffset = 0; /* relied on below */ } shift = xoffset & BITW_MASK; if (shift) @@ -216,8 +231,8 @@ int bitmask_overlap_pos(const bitmask *a,const bitmask *b,int xoffset, int yoffs for (ap = a_entry,bp = b_entry;ap < a_end;ap++,bp++) if (*ap & (*bp << shift)) { - *y = (ap - a->bits) % a->h; - *x = ((ap - a->bits) / a->h)*BITW_LEN + firstsetbit(*ap & (*bp << shift)); + *y = ap - a_entry + yoffset; + *x = (xbase + i)*BITW_LEN + firstsetbit(*ap & (*bp << shift)); return 1; } a_entry += a->h; @@ -225,8 +240,8 @@ int bitmask_overlap_pos(const bitmask *a,const bitmask *b,int xoffset, int yoffs for (ap = a_entry,bp = b_entry;ap < a_end;ap++,bp++) if (*ap & (*bp >> rshift)) { - *y = (ap - a->bits) % a->h; - *x = ((ap - a->bits) / a->h)*BITW_LEN + firstsetbit(*ap & (*bp >> rshift)); + *y = ap - a_entry + yoffset; + *x = (xbase + i + 1)*BITW_LEN + firstsetbit(*ap & (*bp >> rshift)); return 1; } b_entry += b->h; @@ -234,8 +249,8 @@ int bitmask_overlap_pos(const bitmask *a,const bitmask *b,int xoffset, int yoffs for (ap = a_entry,bp = b_entry;ap < a_end;ap++,bp++) if (*ap & (*bp << shift)) { - *y = (ap - a->bits) % a->h; - *x = ((ap - a->bits) / a->h)*BITW_LEN + firstsetbit(*ap & (*bp << shift)); + *y = ap - a_entry + yoffset; + *x = (xbase + astripes)*BITW_LEN + firstsetbit(*ap & (*bp << shift)); return 1; } return 0; @@ -247,8 +262,8 @@ int bitmask_overlap_pos(const bitmask *a,const bitmask *b,int xoffset, int yoffs for (ap = a_entry,bp = b_entry;ap < a_end;ap++,bp++) if (*ap & (*bp << shift)) { - *y = (ap - a->bits) % a->h; - *x = ((ap - a->bits) / a->h)*BITW_LEN + firstsetbit(*ap & (*bp << shift)); + *y = ap - a_entry + yoffset; + *x = (xbase + i)*BITW_LEN + firstsetbit(*ap & (*bp << shift)); return 1; } a_entry += a->h; @@ -256,8 +271,8 @@ int bitmask_overlap_pos(const bitmask *a,const bitmask *b,int xoffset, int yoffs for (ap = a_entry,bp = b_entry;ap < a_end;ap++,bp++) if (*ap & (*bp >> rshift)) { - *y = (ap - a->bits) % a->h; - *x = ((ap - a->bits) / a->h)*BITW_LEN + firstsetbit(*ap & (*bp >> rshift)); + *y = ap - a_entry + yoffset; + *x = (xbase + i + 1)*BITW_LEN + firstsetbit(*ap & (*bp >> rshift)); return 1; } b_entry += b->h; @@ -265,7 +280,8 @@ int bitmask_overlap_pos(const bitmask *a,const bitmask *b,int xoffset, int yoffs return 0; } } - else /* xoffset is a multiple of the stripe width, and the above routines won't work. */ + else /* xoffset is a multiple of the stripe width, and the above routines + won't work. This way is also slightly faster. */ { astripes = (MIN(b->w,a->w - xoffset) - 1)/BITW_LEN + 1; for (i=0;ibits) % a->h; - *x = ((ap - a->bits) / a->h)*BITW_LEN + firstsetbit(*ap & *bp); + *y = ap - a_entry + yoffset; + *x = (xbase + i)*BITW_LEN + firstsetbit(*ap & *bp); return 1; } } @@ -299,20 +315,34 @@ int bitmask_overlap_pos(const bitmask *a,const bitmask *b,int xoffset, int yoffs } } - - -/* (C) Donald W. Gillies, 1992. All rights reserved. You may reuse - this bitcount() function anywhere you please as long as you retain - this Copyright Notice. */ static INLINE int bitcount(unsigned long n) { - register unsigned long tmp; - return (tmp = (n) - (((n) >> 1) & 033333333333) - (((n) >> 2) & 011111111111),\ - tmp = ((tmp + (tmp >> 3)) & 030707070707), \ - tmp = (tmp + (tmp >> 6)), \ - tmp = (tmp + (tmp >> 12) + (tmp >> 24)) & 077); + if (BITW_LEN == 32) + { + /* (C) Donald W. Gillies, 1992. All rights reserved. You may reuse + this bitcount() function anywhere you please as long as you retain + this Copyright Notice. */ + register unsigned long tmp; + return (tmp = (n) - (((n) >> 1) & 033333333333) - + (((n) >> 2) & 011111111111), + tmp = ((tmp + (tmp >> 3)) & 030707070707), + tmp = (tmp + (tmp >> 6)), + tmp = (tmp + (tmp >> 12) + (tmp >> 24)) & 077); + /* End of Donald W. Gillies bitcount code */ + } + else + { + /* Handle non-32 bit case the slow way */ + int nbits = 0; + while (n) + { + if (n & 1) + nbits++; + n = n >> 1; + } + return nbits; + } } -/* End of Donald W. Gillies bitcount code */ int bitmask_overlap_area(const bitmask *a,const bitmask *b,int xoffset, int yoffset) @@ -474,7 +504,8 @@ void bitmask_draw(bitmask *a,bitmask *b,int xoffset, int yoffset) } else { - /* 'Swapping' arguments to be able to almost reuse the code above */ + /* 'Swapping' arguments to be able to almost reuse the code above, + should be taken care of by the compiler efficiently. */ swap = a; a = b; b = swap;