clld.c | 185 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++--------------------
test-ppx | 56 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 221 insertions(+), 20 deletions(-)
diff --git a/clld.c b/clld.c
index 6d6d3a0..5a9372e 100644
--- a/clld.c
+++ b/clld.c
@@ -16,7 +16,7 @@
#define max(a, b) (abs(a-b)+(a+b))/2
#define min(a, b) -max(-a, -b)
-enum {THM, AABB};
+enum {THM, AABB, PPX };
/* Collision type */
int colltype = -1;
@@ -74,8 +74,8 @@ int main(int argc, char **argv) {
double d1;
double d2;
- /* Heightmap, used in Tile Heightmap collision. */
- uint8_t *heightmap;
+ /* Bitmask used in Per Pixel, and Tile Heightmap collision. */
+ uint8_t **bitmask;
/* X axis collision. */
unsigned int clx : 1;
@@ -120,10 +120,34 @@ int main(int argc, char **argv) {
tmp.w = atoi(strtok(buf, ","));
tmp.h = atoi(strtok(NULL, "\n"));
/*
- * Initialize heightmap.
+ * Initialize y axis of bitmask.
+ * If Tile Heightmap is used, Initialize it using the width.
*/
- if (colltype == THM && coll)
- tmp.heightmap = malloc(sizeof(uint8_t *)*tmp.w);
+ if (colltype == THM || colltype == PPX)
+ tmp.bitmask = (colltype == PPX) ? malloc(sizeof(uint8_t *)*tmp.h) : malloc(sizeof(uint8_t *)*tmp.w);
+ /* Initialize x axis of bitmask. */
+ if (colltype == PPX)
+ for(unsigned int i = 0; i<tmp.h; i++)
+ tmp.bitmask[i] = malloc(sizeof(uint8_t)*tmp.w);
+ /* Get Per Pixel data. */
+ if (colltype == PPX) {
+ for (unsigned int j = 0; j<tmp.h; j++) {
+ buf = NULL;
+ size_t newidth = getline(&buf, &size, stdin);
+ /*
+ * Format is:
+ *
+ * 000111000... Until bit w-1.
+ * .
+ * .
+ *
+ * Until bit h-1.
+ */
+ tmp.w = (newidth >= tmp.w) ? tmp.w : newidth;
+ for (unsigned int i = 0; i <tmp.w; i++)
+ tmp.bitmask[j][i] = buf[i] - '0';
+ }
+ }
/* Get Tile Heightmap data. */
if (colltype == THM && coll) {
/* Get vertical flip flag */
@@ -142,25 +166,36 @@ int main(int argc, char **argv) {
for (unsigned int i = 0; i <tmp.w; i++) {
char *tmptok = strtok((i == 0) ? buf : NULL,",");
tmptok = (tmptok == NULL) ? strtok(NULL,"\n") : tmptok;
- tmp.heightmap[i] = (uint8_t *)((atoi(tmptok) <= tmp.h) ? atoi(tmptok) : tmp.h);
+ tmp.bitmask[i] = (uint8_t *)((atoi(tmptok) <= tmp.h) ? atoi(tmptok) : tmp.h);
hmpeak = (atoi(tmptok)+1 >= hmpeak) ? atoi(tmptok)+1 : hmpeak;
}
}
/*
- * Copy width, and height to either
- * the Cursor, or the Floor.
+ * Copy width, height, and bitmask over
+ * to either the Cursor, or the Floor.
*/
(coll) ? (floor.w = tmp.w) : (cursor.w = tmp.w);
(coll) ? (floor.h = tmp.h) : (cursor.h = tmp.h);
- if (coll)
- floor.heightmap = tmp.heightmap;
+ (coll) ? (floor.bitmask = tmp.bitmask) : (cursor.bitmask = tmp.bitmask);
/* Debugging stuff. */
if (verbose >= 1) {
if (colltype == THM && coll)
for (unsigned int i = 0; i<floor.h; i++)
- printf((i < floor.h-1 && i % 16 != 0 || i == 0) ? "%u, " : ("%u\n"), floor.heightmap[i]);
+ printf((i < floor.h-1 && i % 16 != 0 || i == 0) ? "%u, " : ("%u\n"), floor.bitmask[i]);
+
+
+ if (colltype == PPX) {
+ for (unsigned int j = 0; j<((coll) ? floor.h : cursor.h); j++) {
+ for (unsigned int i = 0; i<((coll) ? floor.w : cursor.w); i++)
+ if((coll) ? floor.bitmask[j][i] : cursor.bitmask[j][i])
+ printf("%u", (coll) ? floor.bitmask[j][i] : cursor.bitmask[j][i]);
+ else
+ printf(" ");
+ printf("\n");
+ }
+ }
}
@@ -209,6 +244,113 @@ int main(int argc, char **argv) {
cursor.yvel = atof(strtok(NULL, "\n"));
}
+ /* Per Pixel Collision. */
+ if(colltype == PPX && coll) {
+ if (!flt) {
+ cursor.a1 = cursor.pos.x;
+ cursor.a2 = cursor.pos.x+cursor.w;
+ cursor.b1 = cursor.pos.y;
+ cursor.b2 = cursor.pos.y+cursor.h;
+ floor.a1 = floor.pos.x;
+ floor.a2 = floor.pos.x+floor.w;
+ floor.b1 = floor.pos.y;
+ floor.b2 = floor.pos.y+floor.h;
+
+ cursor.clx = ((cursor.a2 > floor.a1-(int)cursor.xvel-1 && cursor.b2 > floor.b1) && (cursor.a1 < floor.a2-(int)cursor.xvel+1 && cursor.b1 < floor.b2)) ? 1 : 0;
+ cursor.cly = ((cursor.b2 > floor.b1-(int)cursor.yvel-1 && cursor.a2 > floor.a1) && (cursor.b1 < floor.b2-(int)cursor.yvel+1 && cursor.a1 < floor.a2)) ? 1 : 0;
+ cursor.gnded = 0;
+
+ if (cursor.clx || cursor.cly) {
+ int rw1 = (cursor.a2-cursor.a1)/2, rh1 = (cursor.b2-cursor.b1)/2;
+ int rw2 = (floor.a2-floor.a1)/2, rh2 = (floor.b2-floor.b1)/2;
+ uint8_t t = 0, b = 0, l = 0, r = 0;
+ int olxab = min(cursor.a2, floor.a2)-max(cursor.a1, floor.a1);
+ int olyab = min(cursor.b2, floor.b2)-max(cursor.b1, floor.b1);
+ int olxl = cursor.a2-floor.a1;
+ int olxr = floor.a2-cursor.a1;
+ int olyt = cursor.b2-floor.b1;
+ int olyb = floor.b2-cursor.b1;
+ t = (cursor.b2 > rh2 && olyt <= floor.h+1) ? 1 : 0;
+ b = (cursor.b1 > rh2 && olyb <= floor.h+1) ? 1 : 0;
+ l = (cursor.a2 > rw2 && olxl <= floor.w+1) ? 1 : 0;
+ r = (cursor.a1 > rw2 && olxr <= floor.w+1) ? 1 : 0;
+ if (t && b && cursor.xvel == 0) {
+ t = (cursor.yvel > 0) ? 1 : 0;
+ b = (cursor.yvel < 0) ? 1 : 0;
+ }
+ if (l && r && cursor.yvel == 0) {
+ l = (cursor.xvel > 0) ? 1 : 0;
+ r = (cursor.xvel < 0) ? 1 : 0;
+ }
+
+ int x = (l) ? olxl-1 : (r ? olxr-1 : -1);
+ int y = (t) ? olyt-1 : (b ? olyb-1 : -1);
+ /* X coordinate of overlap between the Cursor, and Floor. */
+ /*if (cursor.a2 > floor.a1-(int)cursor.xvel-1)
+ else if (cursor.a1 < floor.a2-(int)cursor.xvel+1)
+ olx = cursor.a1-(floor.a2-(int)cursor.xvel+1);*/
+ /*int olw = (cursor.a1+rw1)-(floor.a1+rw2);*/
+
+ /* Y coordinate of overlap between the Cursor, and Floor. */
+ /*if (cursor.b2 > floor.b1-(int)cursor.yvel-1)
+ oly = cursor.b2-(floor.b1-(int)cursor.yvel-1);
+ else if (cursor.b1 < floor.b2-(int)cursor.yvel+1)
+ oly = cursor.b1-(floor.b2-(int)cursor.yvel+1);*/
+ /*int olh = (cursor.b1+rh1)-(floor.b1+rh2);*/
+
+ printf(
+ "olxab: %i, olyab: %i\n"
+ "olxl: %i, olyt: %i\n"
+ "olxr: %i, olyb: %i\n"
+ "cursor.a2: %i, cursor.b2: %i\n"
+ "floor.a2: %i, floor.b2: %i\n"
+ "x: %i, y: %i\n"
+ "min(cursor.b2, floor.b2)-max(cursor.b1, floor.b1): %i\n"
+ "min(cursor.b2, floor.b2): %i\n"
+ "max(cursor.b1, floor.b1): %i\n"
+ "t: %u, b: %u, l: %u, r: %u\n"
+ , olxab, olyab
+ , olxl, olyt
+ , olxr, olyb
+ , cursor.a2, cursor.b2
+ , floor.a2, floor.b2
+ , x, y
+ , min(cursor.b2, floor.b2)-max(cursor.b1, floor.b1)
+ , min(cursor.b2, floor.b2)
+ , max(cursor.b1, floor.b1)
+ , t, b, l, r);
+ if((x >= 0 && x < floor.w) && (y >= 0 && y <= floor.h))
+ for (y; y<floor.h; y++) {
+ for (x; x < floor.w; x++) {
+ /*printf(
+ "cursor.pos.x+x1: %i, cursor.pos.y+y1: %i\n"
+ "floor.pos.x+x2: %i, floor.pos.y+y2: %i\n"
+ "\n"
+ , cursor.pos.x+x1, cursor.pos.y+y1
+ , floor.pos.x+x2, floor.pos.y+y2);*/
+ if (cursor.bitmask[y][x] && floor.bitmask[y][x])
+ printf(
+ "Collision at: cursor (%i, %i)\n"
+ " floor (%i, %i)\n"
+ , cursor.a2-x, cursor.b2-y
+ , floor.a2-x, floor.b2-y);
+ }
+ }
+ }
+ printf("%u, %u\n%u\n%i, %i\n%07.06f, %07.06f\n", cursor.clx, cursor.cly, cursor.gnded, cursor.pos.x, cursor.pos.y, cursor.xvel, cursor.yvel);
+
+ } else {
+ cursor.c1 = cursor.pos.fx;
+ cursor.c2 = cursor.pos.fx+cursor.w;
+ cursor.d1 = cursor.pos.fy;
+ cursor.d2 = cursor.pos.fy+cursor.h;
+ floor.c1 = floor.pos.fx;
+ floor.c2 = floor.pos.fx+floor.w;
+ floor.d1 = floor.pos.fy;
+ floor.d2 = floor.pos.fy+floor.h;
+ }
+ }
+
/* Tile Heightmap Collision. */
if (colltype == THM && coll) {
if (!flt) {
@@ -229,9 +371,9 @@ int main(int argc, char **argv) {
if (cursor.clx) {
if (cursor.a2-floor.a1 < 0 || cursor.a2-floor.a1 > floor.w) {
/* Is the Cursor coming from the left? */
- if (cursor.a2 > floor.a1-(int)cursor.xvel-1 && floor.b2-cursor.b2 < (int)floor.heightmap[0] && !floor.flp && cursor.xvel > 0)
+ if (cursor.a2 > floor.a1-(int)cursor.xvel-1 && floor.b2-cursor.b2 < (int)floor.bitmask[0] && !floor.flp && cursor.xvel > 0)
cursor.pos.x = (floor.pos.x-(int)cursor.xvel)-cursor.w-1;
- else if (cursor.a1 < (floor.a2-cursor.w)-(int)cursor.xvel+1 && floor.b2-cursor.b2 < (int)floor.heightmap[floor.w-1] && !floor.flp && cursor.xvel < 0)
+ else if (cursor.a1 < (floor.a2-cursor.w)-(int)cursor.xvel+1 && floor.b2-cursor.b2 < (int)floor.bitmask[floor.w-1] && !floor.flp && cursor.xvel < 0)
cursor.pos.x = (floor.a2-cursor.w)-(int)cursor.xvel+1;
/* Is the Cursor coming from the right? */
if (cursor.a1 < (floor.a2-cursor.w)-(int)cursor.xvel+1 && cursor.b1-floor.b1 < 0 && floor.flp && cursor.xvel < 0)
@@ -244,7 +386,7 @@ int main(int argc, char **argv) {
if (cursor.cly) {
if (cursor.a2-floor.a1 < floor.w) {
cursor.yvel = 0;
- newy = (int)floor.heightmap[cursor.a2-floor.a1];
+ newy = (int)floor.bitmask[cursor.a2-floor.a1];
/* Is the Floor, really a floor? */
if (cursor.b2 > (floor.b2-hmpeak)-(int)cursor.yvel && floor.b2-cursor.b2 >= 0 && !floor.flp)
cursor.pos.y = ((floor.b2-cursor.h)-newy)-(int)cursor.yvel;
@@ -288,9 +430,9 @@ int main(int argc, char **argv) {
if (cursor.clx) {
if (cursor.c2-floor.c1 < -1 || cursor.c2-floor.c1 > floor.w) {
/* Is the Cursor coming from the left? */
- if (cursor.c2 > floor.c1-cursor.xvel-1 && floor.d2-cursor.d2 < (int)floor.heightmap[0] && !floor.flp && cursor.xvel > 0)
+ if (cursor.c2 > floor.c1-cursor.xvel-1 && floor.d2-cursor.d2 < (int)floor.bitmask[0] && !floor.flp && cursor.xvel > 0)
cursor.pos.fx = (floor.pos.x-cursor.xvel)-cursor.w-1;
- else if (cursor.c1 < (floor.c2-cursor.w)-cursor.xvel+1 && floor.d2-cursor.d2 < (int)floor.heightmap[floor.w-1] && !floor.flp && cursor.xvel < 0)
+ else if (cursor.c1 < (floor.c2-cursor.w)-cursor.xvel+1 && floor.d2-cursor.d2 < (int)floor.bitmask[floor.w-1] && !floor.flp && cursor.xvel < 0)
cursor.pos.fx = (floor.c2-cursor.w)-cursor.xvel+1;
/* Is the Cursor coming from the right? */
if (cursor.c1 < (floor.c2-cursor.w)-cursor.xvel+1 && cursor.d1-floor.d1 < 0 && floor.flp && cursor.xvel < 0)
@@ -303,7 +445,7 @@ int main(int argc, char **argv) {
if (cursor.cly) {
if (cursor.c2-floor.c1 < floor.w) {
cursor.yvel = 0;
- newy = (int)floor.heightmap[(int)cursor.c2-(int)floor.c1];
+ newy = (int)floor.bitmask[(int)cursor.c2-(int)floor.c1];
/* Is the Floor, really a floor? */
if (cursor.d2 > (floor.d2-hmpeak)-cursor.yvel && floor.d2-cursor.d2 >= 0 && !floor.flp)
cursor.pos.fy = ((floor.d2-cursor.h)-newy)-cursor.yvel;
@@ -406,8 +548,11 @@ int main(int argc, char **argv) {
uint8_t a = 0;
unsigned int i = 0;
free(buf);
- if(colltype == THM) {
- free(floor.heightmap);
+ if(colltype == THM || colltype == PPX) {
+ while (!a && colltype == PPX)
+ (i<tmp.h) ? (free(tmp.bitmask[i]), ++i) : (a=1);
+ free(cursor.bitmask);
+ free(floor.bitmask);
}
fflush(stdout);
diff --git a/test-ppx b/test-ppx
new file mode 100644
index 0000000..dca0772
--- /dev/null
+++ b/test-ppx
@@ -0,0 +1,56 @@
+2
+18, 34
+000000000000000000
+000000000000110000
+000000000001010000
+000000000010010000
+000000000010010000
+000000000010010000
+000000001111110000
+000000010000010000
+000000100000010000
+000001000000010000
+000001000000010000
+000010000000010000
+000010000000010000
+000001000000010000
+000001000000010000
+000000100000010000
+000000111111110000
+000000100000010000
+000001000111010000
+000001000101010000
+000001000101010000
+000001000111010000
+000001000101010000
+000001001001010000
+000001001101010000
+000000100111010000
+000000100000010000
+000000100000010000
+000000111111110000
+000000001001000000
+000000001111000000
+000000011001000000
+000000010001000000
+000000011111000000
+1, 2
+0, 0
+16, 16
+0000000000000001
+0000000000000011
+0000000000000101
+0000000000001001
+0000000000010001
+0000000000100001
+0000000001000001
+0000000010000001
+0000000100000001
+0000001000000001
+0000010000000001
+0000100000000001
+0001000000000001
+0010000000000001
+0100000000000001
+1111111111111111
+4, 5