JasonWoof Got questions, comments, patches, etc.? Contact Jason Woofenden
By Jove, I think I've got it!
authorJoshua Grams <josh@qualdan.com>
Thu, 7 Apr 2005 11:49:28 +0000 (11:49 +0000)
committerJoshua Grams <josh@qualdan.com>
Thu, 7 Apr 2005 11:49:28 +0000 (11:49 +0000)
(proper collision detection, that is)

Makefile
debug.c
gfx.mk
main.c
shape.c

index bc7c6ad..504279a 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -51,9 +51,6 @@ main.o file.o: file.h
 vor: $(objects)
        $(CC) $(ldflags) -o $@ $^ $(LIBRARIES)
 
-pnmoutline: pnmoutline.c
-       $(CC) -lnetpbm -o $@ $<
-
 include gfx.mk
 
 clean:
diff --git a/debug.c b/debug.c
index 20ee5c2..3153bf3 100644 (file)
--- a/debug.c
+++ b/debug.c
@@ -23,3 +23,27 @@ printf_surface(SDL_Surface *s, char *name)
                printf("\tpitch = %d;\n", s->pitch);
        printf("};\n");
 }
+
+void
+printb(uint32_t n, int bits)
+{
+       int i;
+
+       for(i=0; i<bits; i++) {
+               if(n & 0x80000000) putchar('1'); else putchar('0');
+               n = n << 1;
+       }
+}
+
+void
+print_mask(struct shape *s)
+{
+       int i, j;
+
+       for(i=0; i<s->h; i++) {
+               for(j=0; j<s->mw-1; j++) printb(s->mask[s->mw*i+j], 32);
+               printb(s->mask[s->mw*i+j], s->w % 32);
+               putchar('\n');
+       }
+       putchar('\n');
+}
diff --git a/gfx.mk b/gfx.mk
index ec0202f..b670d4d 100644 (file)
--- a/gfx.mk
+++ b/gfx.mk
@@ -1,14 +1,10 @@
 
 
-data/sprites/ship.png: ship.pov pnmoutline gfx.mk
-       povray -GA -D +A +UA +W32 +H32 $< 2>/dev/null
-       pngtopnm ship.png >ship.pnm
-       ./pnmoutline <ship.pnm >data/sprites/ship.pnm
-       pnmtopng -transparent =white data/sprites/ship.pnm >$@
-       rm ship.png ship.pnm data/sprites/ship.pnm
+data/sprites/ship.png: ship.pov gfx.mk
+       povray -D +A +W32 +H32 +FN -O$@ $< 2>/dev/null
 
 data/indicators/life.png: ship.pov gfx.mk
-       povray -D +A +UA +W17 +H17 $< -O$@
+       povray -D +A +UA +W17 +H17 $< -O$@ 2>/dev/null
 
 data/sprites/rock%.png: rocks.pov gfx.mk
        povray -Irocks.pov -D +H52 +W52 +K`echo "$@" | grep -o '[0-9][0-9]'` +Fp -O$@.pnm 2>/dev/null
diff --git a/main.c b/main.c
index ad3ab56..1f2856f 100644 (file)
--- a/main.c
+++ b/main.c
@@ -570,7 +570,6 @@ init(int fullscreen) {
 
        // Load all our lovely rocks
        for(i = 0; i<NROCKS; i++) {
-
                snprintf(a,MAX_PATH_LEN,add_path("sprites/rock%02d.png"),i);
                NULLERROR(temp = IMG_Load(a));
                NULLERROR(surf_rock[i] = SDL_DisplayFormat(temp));
diff --git a/shape.c b/shape.c
index 92914cb..867610e 100644 (file)
--- a/shape.c
+++ b/shape.c
@@ -6,7 +6,7 @@ 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");
@@ -14,8 +14,8 @@ get_shape(SDL_Surface *img, struct shape *s)
        }
 
        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,14 +24,14 @@ 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; y<img->h; y++) {
+               bit = 0;
                for(x=0; x<img->w; 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;
+                       bit >>= 1;
+                       if(!bit || x == img->w - 1) { *(p++) = bits; }
                }
                px = (uint16_t *) ((uint8_t *) px + img->pitch - 2*img->w);
        }
@@ -46,6 +46,64 @@ get_shape(SDL_Surface *img, struct shape *s)
 #define min(a, b) ((a) < (b) ? (a) : (b))
 #endif
 
+#ifndef abs
+#define abs(a) ((a)<=0 ? -(a) : (a))
+#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<n-1; i++) {
+               lbits = *rbits++ << lshift;
+               lbits |= *rbits >> (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;
+       }
+
+       for(y=0; y<abs(yov); y++) {
+               if(line_collide(xov, r, rbits, s, sbits)) return 1;
+               rbits += r->mw; sbits += s->mw;
+       }
+
+       return 0;
+}
+
 int
 collide(int xdiff, int ydiff, struct shape *r, struct shape *s)
 {
@@ -58,5 +116,5 @@ collide(int xdiff, int ydiff, struct shape *r, struct shape *s)
        else yov = min(-min(s->h+ydiff, r->h), 0);
 
        if(xov == 0 || yov == 0) return 0;  // bboxes hit?
-       else return 1;
+       else return mask_collide(xov, yov, r, s);
 }