X-Git-Url: https://jasonwoof.com/gitweb/?p=vor.git;a=blobdiff_plain;f=shape.c;h=75424ef9ed104e9468e7306e21a0df264b113dba;hp=9d0501c24485ae6539af2c340b2daf1efee38fc6;hb=2b5dd5bc0eb1739dd744de6f565d0f3a7ae02c95;hpb=8193e09e49bc571f9c61e6e3adf45010271c08d5 diff --git a/shape.c b/shape.c index 9d0501c..75424ef 100644 --- a/shape.c +++ b/shape.c @@ -1,4 +1,5 @@ #include +#include "common.h" #include "shape.h" void @@ -6,16 +7,17 @@ get_shape(SDL_Surface *img, struct shape *s) { int x, y; uint16_t *px, transp; - uint32_t bits; + uint32_t bits, bit, *p; if(img->format->BytesPerPixel != 2) { fprintf(stderr, "get_shape(): not a 16-bit image!\n"); exit(1); } + s->area = 0; s->w = img->w; s->h = img->h; - s->mw = ((img->w+31)>>5) * img->h; - s->mask = malloc(4*s->mw); + s->mw = ((img->w+31)>>5); + s->mask = malloc(4*s->mw*s->h); if(!s->mask) { fprintf(stderr, "can't malloc bitmask"); exit(1); @@ -24,27 +26,73 @@ get_shape(SDL_Surface *img, struct shape *s) SDL_LockSurface(img); px = img->pixels; transp = img->format->colorkey; - bits = 0; + p = s->mask; for(y=0; yh; y++) { + bit = 0; for(x=0; xw; x++) { - if(*px++ != transp) bits |= 1; - if(x == img->w-1 || !(x+1)%32) { - *(s->mask++) = bits; - bits = 0; - } else bits = bits << 1; + if(!bit) { bits = 0; bit = 0x80000000; } + if(*px++ != transp) { bits |= bit; s->area++; } + bit >>= 1; + if(!bit || x == img->w - 1) { *(p++) = bits; } } px = (uint16_t *) ((uint8_t *) px + img->pitch - 2*img->w); } SDL_UnlockSurface(img); } -#ifndef max -#define max(a, b) ((a) > (b) ? (a) : (b)) -#endif +int +line_collide(int xov, struct shape *r, uint32_t *rbits, struct shape *s, uint32_t *sbits) +{ + int lshift, n, i, ret = 0; + uint32_t lbits; + struct shape *st; + uint32_t *bt; + + + if(xov < 0) { + st = r; r = s; s = st; + bt = rbits; rbits = sbits; sbits = bt; + xov = -xov; + } + + + lshift = (r->w - xov) & 31; + rbits += (r->w - xov) >> 5; + n = (xov + 31) >> 5; + for(i=0; i> (32 - lshift); + if(lbits & *sbits++) ret = 1; + } + lbits = *rbits << lshift; + if(lbits & *sbits) ret = 1; + + return ret; +} + +int +mask_collide(int xov, int yov, struct shape *r, struct shape *s) +{ + int y, ry, sy; + uint32_t *rbits, *sbits; + + if(yov > 0) { + ry = r->h - yov; sy = 0; + rbits = r->mask + (r->h - yov) * r->mw; + sbits = s->mask; + } else { + ry = 0; sy = s->h + yov; + rbits = r->mask; + sbits = s->mask + (s->h + yov) * s->mw; + } -#ifndef min -#define min(a, b) ((a) < (b) ? (a) : (b)) -#endif + for(y=0; ymw; sbits += s->mw; + } + + return 0; +} int collide(int xdiff, int ydiff, struct shape *r, struct shape *s) @@ -52,12 +100,22 @@ collide(int xdiff, int ydiff, struct shape *r, struct shape *s) int xov, yov; if(xdiff >= 0) xov = max(min(r->w-xdiff, s->w), 0); - else xov = -max(min(s->w+xdiff, r->w), 0); + else xov = min(-min(s->w+xdiff, r->w), 0); if(ydiff >= 0) yov = max(min(r->h-ydiff, s->h), 0); - else yov = -max(min(s->h+ydiff, r->h), 0); + else yov = min(-min(s->h+ydiff, r->h), 0); - if(xov == 0 && yov == 0) return 0; + if(xov == 0 || yov == 0) return 0; // bboxes hit? + else return mask_collide(xov, yov, r, s); +} - return 0; +int +pixel_collide(unsigned int xoff, unsigned int yoff, struct shape *r) +{ + uint32_t pmask; + + if(xoff >= r->w || yoff >= r->h) return 0; + + pmask = 0x80000000 >> (xoff&0x1f); + return r->mask[(yoff*r->mw) + (xoff>>5)] & pmask; }