diff --git a/Makefile b/Makefile index 5dbc0b0..fc33db0 100755 --- a/Makefile +++ b/Makefile @@ -73,7 +73,7 @@ SEM = 0.0.1 COM != git rev-parse --short HEAD VER = $(SEM)-$(COM) -COMPILER_FLAGS = $(includeflag) $(QFLAGS) -MD $(WARNING_FLAGS) -DVER=\"$(VER)\" -DINFO=\"$(INFO)\" -c $< -o $@ +COMPILER_FLAGS = $(includeflag) $(QFLAGS) -MD $(WARNING_FLAGS) -DCP_USE_DOUBLES=0 -DVER=\"$(VER)\" -DINFO=\"$(INFO)\" -c $< -o $@ LIBPATH = -L$(BIN) diff --git a/source/engine/2dphysics.c b/source/engine/2dphysics.c index 5c607d2..e728139 100644 --- a/source/engine/2dphysics.c +++ b/source/engine/2dphysics.c @@ -10,6 +10,7 @@ #include #include #include "stb_ds.h" +#include #include "script.h" @@ -158,40 +159,19 @@ void phys2d_dbgdrawcircle(struct phys2d_circle *circle) phys2d_dbgdrawcpcirc((cpCircleShape *)circle->shape.shape); } - -/*********** SEGMENT2D **************/ - -struct phys2d_segment *Make2DSegment(int go) +void phys2d_applycircle(struct phys2d_circle *circle) { - struct phys2d_segment *new = malloc(sizeof(struct phys2d_segment)); + struct gameobject *go = id2go(circle->shape.go); - new->thickness = 1.f; - new->a[0] = 0.f; - new->a[1] = 0.f; - new->b[0] = 0.f; - new->b[1] = 0.f; + float radius = circle->radius * go->scale; + float s = go->scale; + cpVect offset = { circle->offset.x * s, circle->offset.y * s }; - new->shape.shape = cpSpaceAddShape(space, cpSegmentShapeNew(id2go(go)->body, cpvzero, cpvzero, new->thickness)); - new->shape.debugdraw = phys2d_dbgdrawseg; - init_phys2dshape(&new->shape, go, new); - - return new; + cpCircleShapeSetRadius(circle->shape.shape, radius); + cpCircleShapeSetOffset(circle->shape.shape, offset); + //cpBodySetMoment(go->body, cpMomentForCircle(go->mass, 0, radius, offset)); } -void phys2d_segdel(struct phys2d_segment *seg) -{ - phys2d_shape_del(&seg->shape); -} - -void segment_gui(struct phys2d_segment *seg) -{ - nuke_property_float2("a", 0.f, seg->a, 1.f, 0.01f, 0.01f); - nuke_property_float2("b", 0.f, seg->b, 1.f, 0.01f, 0.01f); - - phys2d_applyseg(seg); -} - - /************* BOX2D ************/ struct phys2d_box *Make2DBox(int go) @@ -230,209 +210,18 @@ void phys2d_applybox(struct phys2d_box *box) { float s = id2go(box->shape.go)->scale; cpTransform T = { 0 }; - T.a = s; - T.d = s; + T.a = s * cos(box->rotation); + T.b = -sin(box->rotation); + T.c = sin(box->rotation); + T.d = s * cos(box->rotation); T.tx = box->offset[0] * s; T.ty = box->offset[1] * s; float hh = box->h / 2.f; float hw = box->w / 2.f; - cpVect verts[4] = - { { -hw, -hh }, { hw, -hh }, { hw, hh }, { -hw, hh } }; + cpVect verts[4] = { { -hw, -hh }, { hw, -hh }, { hw, hh }, { -hw, hh } }; cpPolyShapeSetVerts(box->shape.shape, 4, verts, T); cpPolyShapeSetRadius(box->shape.shape, box->r); } - -/************** POLYGON ************/ - -struct phys2d_poly *Make2DPoly(int go) -{ - struct phys2d_poly *new = malloc(sizeof(struct phys2d_poly)); - - new->n = 0; - new->points = NULL; - new->radius = 0.f; - - cpTransform T = { 0 }; - new->shape.shape = cpSpaceAddShape(space, cpPolyShapeNew(id2go(go)->body, 0, NULL, T, new->radius)); - init_phys2dshape(&new->shape, go, new); - new->shape.debugdraw = phys2d_dbgdrawpoly; - phys2d_applypoly(new); - - return new; -} - -void phys2d_polydel(struct phys2d_poly *poly) -{ - phys2d_shape_del(&poly->shape); -} - -void phys2d_polyaddvert(struct phys2d_poly *poly) -{ - poly->n++; - float *oldpoints = poly->points; - poly->points = calloc(2 * poly->n, sizeof(float)); - memcpy(poly->points, oldpoints, sizeof(float) * 2 * (poly->n - 1)); - free(oldpoints); -} - -void poly_gui(struct phys2d_poly *poly) -{ - - if (nuke_btn("Add Poly Vertex")) phys2d_polyaddvert(poly); - - for (int i = 0; i < poly->n; i++) { - nuke_property_float2("#P", 0.f, &poly->points[i*2], 1.f, 0.1f, 0.1f); - } - - nuke_property_float("Radius", 0.01f, &poly->radius, 1000.f, 1.f, 0.1f); - - phys2d_applypoly(poly); -} - - - -/****************** EDGE 2D**************/ - -struct phys2d_edge *Make2DEdge(int go) -{ - struct phys2d_edge *new = malloc(sizeof(struct phys2d_edge)); - - new->n = 2; - new->points = calloc(2 * 2, sizeof(float)); - new->thickness = 0.f; - new->shapes = malloc(sizeof(cpShape *)); - - new->shapes[0] = cpSpaceAddShape(space, cpSegmentShapeNew(id2go(go)->body, cpvzero, cpvzero, new->thickness)); - new->shape.go = go; - phys2d_edgeshapeapply(&new->shape, new->shapes[0]); - - phys2d_applyedge(new); - - return new; -} - -void phys2d_edgedel(struct phys2d_edge *edge) -{ - phys2d_shape_del(&edge->shape); -} - -void phys2d_edgeshapeapply(struct phys2d_shape *mshape, cpShape * shape) -{ - cpShapeSetFriction(shape, id2go(mshape->go)->f); - cpShapeSetElasticity(shape, id2go(mshape->go)->e); -} - -void phys2d_edgeaddvert(struct phys2d_edge *edge) -{ - edge->n++; - float *oldp = edge->points; - edge->points = calloc(edge->n * 2, sizeof(float)); - memcpy(edge->points, oldp, sizeof(float) * 2 * (edge->n - 1)); - - cpShape **oldshapes = edge->shapes; - edge->shapes = malloc(sizeof(cpShape *) * (edge->n - 1)); - memcpy(edge->shapes, oldshapes, sizeof(cpShape *) * (edge->n - 2)); - cpVect a = - { edge->points[(edge->n - 2) * 2], - edge->points[(edge->n - 2) * 2 + 1] }; - cpVect b = - { edge->points[(edge->n - 1) * 2], - edge->points[(edge->n - 1) * 2 + 1] }; - edge->shapes[edge->n - 2] = cpSpaceAddShape(space, cpSegmentShapeNew(id2go(edge->shape.go)->body, a, b, edge->thickness)); - phys2d_edgeshapeapply(&edge->shape, edge->shapes[edge->n - 2]); - - free(oldp); - free(oldshapes); -} - -void edge_gui(struct phys2d_edge *edge) -{ - if (nuke_btn("Add Edge Vertex")) phys2d_edgeaddvert(edge); - - for (int i = 0; i < edge->n; i++) - nuke_property_float2("E", 0.f, &edge->points[i*2], 1.f, 0.01f, 0.01f); - - nuke_property_float("Thickness", 0.01f, &edge->thickness, 1.f, 0.01f, 0.01f); - - phys2d_applyedge(edge); -} - - - -void phys2d_applycircle(struct phys2d_circle *circle) -{ - struct gameobject *go = id2go(circle->shape.go); - - float radius = circle->radius * go->scale; - float s = go->scale; - cpVect offset = { circle->offset.x * s, circle->offset.y * s }; - - cpCircleShapeSetRadius(circle->shape.shape, radius); - cpCircleShapeSetOffset(circle->shape.shape, offset); - cpBodySetMoment(go->body, cpMomentForCircle(go->mass, 0, radius, offset)); -} - -void phys2d_applyseg(struct phys2d_segment *seg) -{ - float s = id2go(seg->shape.go)->scale; - cpVect a = { seg->a[0] * s, seg->a[1] * s }; - cpVect b = { seg->b[0] * s, seg->b[1] * s }; - cpSegmentShapeSetEndpoints(seg->shape.shape, a, b); - cpSegmentShapeSetRadius(seg->shape.shape, seg->thickness * s); -} - - - -void phys2d_applypoly(struct phys2d_poly *poly) -{ - cpVect verts[poly->n]; - - for (int i = 0; i < poly->n; i++) { - verts[i].x = poly->points[i * 2]; - verts[i].y = poly->points[i * 2 + 1]; - } - - CP_CONVEX_HULL(poly->n, verts, hullCount, hullVerts); - - float s = id2go(poly->shape.go)->scale; - cpTransform T = { 0 }; - T.a = s; - T.d = s; - - cpPolyShapeSetVerts(poly->shape.shape, hullCount, hullVerts, T); - cpPolyShapeSetRadius(poly->shape.shape, poly->radius); -} - -void phys2d_applyedge(struct phys2d_edge *edge) -{ - float s = id2go(edge->shape.go)->scale; - - for (int i = 0; i < edge->n - 1; i++) { - cpVect a = - { edge->points[i * 2] * s, edge->points[i * 2 + 1] * s }; - cpVect b = - { edge->points[i * 2 + 2] * s, edge->points[i * 2 + 3] * s }; - cpSegmentShapeSetEndpoints(edge->shapes[i], a, b); - cpSegmentShapeSetRadius(edge->shapes[i], edge->thickness); - } -} - - - -void phys2d_dbgdrawseg(struct phys2d_segment *seg) -{ - cpVect p = cpBodyGetPosition(cpShapeGetBody(seg->shape.shape)); - cpVect a = cpSegmentShapeGetA(seg->shape.shape); - cpVect b = cpSegmentShapeGetB(seg->shape.shape); - - float angle = cpBodyGetAngle(cpShapeGetBody(seg->shape.shape)); - float ad = sqrt(pow(a.x, 2.f) + pow(a.y, 2.f)); - float bd = sqrt(pow(b.x, 2.f) + pow(b.y, 2.f)); - float aa = atan2(a.y, a.x) + angle; - float ba = atan2(b.y, b.x) + angle; - draw_line(ad * cos(aa) + p.x, ad * sin(aa) + p.y, bd * cos(ba) + p.x, bd * sin(ba) + p.y, shape_color(seg->shape.shape)); -} - void phys2d_dbgdrawbox(struct phys2d_box *box) { int n = cpPolyShapeGetCount(box->shape.shape); @@ -450,22 +239,70 @@ void phys2d_dbgdrawbox(struct phys2d_box *box) draw_poly(points, n, shape_color(box->shape.shape)); } +/************** POLYGON ************/ +struct phys2d_poly *Make2DPoly(int go) +{ + struct phys2d_poly *new = malloc(sizeof(struct phys2d_poly)); + + arrsetlen(new->points, 0); + new->radius = 0.f; + + new->shape.shape = cpSpaceAddShape(space, cpPolyShapeNewRaw(id2go(go)->body, 0, new->points, new->radius)); + new->shape.debugdraw = phys2d_dbgdrawpoly; + init_phys2dshape(&new->shape, go, new); + return new; +} + +void phys2d_polydel(struct phys2d_poly *poly) +{ + arrfree(poly->points); + phys2d_shape_del(&poly->shape); +} + +void phys2d_polyaddvert(struct phys2d_poly *poly) +{ + arrput(poly->points, cpvzero); +} + +void poly_gui(struct phys2d_poly *poly) +{ +} + +void phys2d_poly_setverts(struct phys2d_poly *poly, cpVect *verts) +{ + arrfree(poly->points); + poly->points = verts; + phys2d_applypoly(poly); +} + +void phys2d_applypoly(struct phys2d_poly *poly) +{ + if (arrlen(poly->points) <= 0) return; + float s = id2go(poly->shape.go)->scale; + cpTransform T = { 0 }; + T.a = s; + T.d = s; + + cpPolyShapeSetVerts(poly->shape.shape, arrlen(poly->points), poly->points, T); + cpPolyShapeSetRadius(poly->shape.shape, poly->radius); +} void phys2d_dbgdrawpoly(struct phys2d_poly *poly) { float *color = shape_color(poly->shape.shape); + int n = arrlen(poly->points); cpVect b = cpBodyGetPosition(cpShapeGetBody(poly->shape.shape)); float angle = cpBodyGetAngle(cpShapeGetBody(poly->shape.shape)); float s = id2go(poly->shape.go)->scale; - for (int i = 0; i < poly->n; i++) { - float d = sqrt(pow(poly->points[i * 2] * s, 2.f) + pow(poly->points[i * 2 + 1] * s, 2.f)); - float a = atan2(poly->points[i * 2 + 1], poly->points[i * 2]) + angle; + for (int i = 0; i < n; i++) { + float d = sqrt(pow(poly->points[i * 2].x * s, 2.f) + pow(poly->points[i * 2].y* s, 2.f)); + float a = atan2(poly->points[i * 2].y, poly->points[i * 2].x) + angle; draw_point(b.x + d * cos(a), b.y + d * sin(a), 3, color); } - if (poly->n >= 3) { + if (arrlen(poly->points) >= 3) { int n = cpPolyShapeGetCount(poly->shape.shape); float points[n * 2]; @@ -481,32 +318,111 @@ void phys2d_dbgdrawpoly(struct phys2d_poly *poly) } } +/****************** EDGE 2D**************/ + +struct phys2d_edge *Make2DEdge(int go) +{ + struct phys2d_edge *new = malloc(sizeof(struct phys2d_edge)); + new->points = NULL; + arrsetlen(new->points, 0); + new->thickness = 0.f; + new->shapes = NULL; + arrsetlen(new->shapes, 0); + new->shape.go = go; + new->shape.data = new; + new->shape.debugdraw = phys2d_dbgdrawedge; + phys2d_applyedge(new); + + return new; +} + +void phys2d_edgedel(struct phys2d_edge *edge) +{ + phys2d_shape_del(&edge->shape); +} + +void phys2d_edgeaddvert(struct phys2d_edge *edge) +{ + arrput(edge->points, cpvzero); + if (arrlen(edge->points) > 1) + arrput(edge->shapes, cpSpaceAddShape(space, cpSegmentShapeNew(id2go(edge->shape.go)->body, cpvzero, cpvzero, edge->thickness))); + + phys2d_applyedge(edge); +} + +void phys2d_edge_rmvert(struct phys2d_edge *edge, int index) +{ + assert(arrlen(edge->points) > index && index >= 0); + + arrdel(edge->points, index); + cpSegmentShapeSetEndpoints(edge->shapes[index-1], edge->points[index-1], edge->points[index]); + cpSpaceRemoveShape(space, edge->shapes[index-1]); + arrdel(edge->shapes, index-1); + + phys2d_applyedge(edge); +} + +phys2d_edge_setvert(struct phys2d_edge *edge, int index, cpVect val) +{ + assert(arrlen(edge->points) > index && index >= 0); + edge->points[index] = val; + + phys2d_applyedge(edge); +} + +void phys2d_applyedge(struct phys2d_edge *edge) +{ + float s = id2go(edge->shape.go)->scale; + + for (int i = 0; i < arrlen(edge->shapes); i++) { + cpVect a = edge->points[i]; + cpVect b = edge->points[i+1]; + a.x *= s; + a.y *= s; + b.x *= s; + b.y *= s; + cpSegmentShapeSetEndpoints(edge->shapes[i], a, b); + cpSegmentShapeSetRadius(edge->shapes[i], edge->thickness); + cpShapeSetUserData(edge->shapes[i], &edge->shape); + cpShapeSetCollisionType(edge->shapes[i], edge->shape.go); + cpShapeSetFriction(edge->shapes[i], id2go(edge->shape.go)->f); + cpShapeSetElasticity(edge->shapes[i], id2go(edge->shape.go)->e); + } + + cpSpaceReindexShapesForBody(space, id2go(edge->shape.go)->body); +} void phys2d_dbgdrawedge(struct phys2d_edge *edge) { - float *color =shape_color(edge->shape.shape); + edge->draws++; + if (edge->draws > 1) { + if (edge->draws >= arrlen(edge->shapes)) + edge->draws = 0; - cpVect p = cpBodyGetPosition(cpShapeGetBody(edge->shape.shape)); + return; + } + + if (arrlen(edge->shapes) < 1) return; + + cpVect p = cpBodyGetPosition(cpShapeGetBody(edge->shapes[0])); float s = id2go(edge->shape.go)->scale; - float angle = cpBodyGetAngle(cpShapeGetBody(edge->shape.shape)); + float angle = cpBodyGetAngle(cpShapeGetBody(edge->shapes[0])); - for (int i = 0; i < edge->n; i++) { - float d = sqrt(pow(edge->points[i * 2] * s, 2.f) + pow(edge->points[i * 2 + 1] * s, 2.f)); - float a = atan2(edge->points[i * 2 + 1], edge->points[i * 2]) + angle; - draw_point(p.x + d * cos(a), p.y + d * sin(a), 3, color); + cpVect drawpoints[arrlen(edge->points)]; + + for (int i = 0; i < arrlen(edge->points); i++) { + float d = sqrt(pow(edge->points[i].x*s, 2.f) + pow(edge->points[i].y*s, 2.f)); + float a = atan2(edge->points[i].y, edge->points[i].x) + angle; + drawpoints[i].x = p.x + d*cos(a); + drawpoints[i].y = p.y + d*sin(a); } - for (int i = 0; i < edge->n - 1; i++) { - cpVect a = cpSegmentShapeGetA(edge->shapes[i]); - cpVect b = cpSegmentShapeGetB(edge->shapes[i]); - float ad = sqrt(pow(a.x, 2.f) + pow(a.y, 2.f)); - float bd = sqrt(pow(b.x, 2.f) + pow(b.y, 2.f)); - float aa = atan2(a.y, a.x) + angle; - float ba = atan2(b.y, b.x) + angle; - draw_line(ad * cos(aa) + p.x, ad * sin(aa) + p.y, bd * cos(ba) + p.x, bd * sin(ba) + p.y, color); - } + draw_edge(drawpoints, arrlen(edge->points), trigger_color); + draw_points(drawpoints, arrlen(edge->points), 2, kinematic_color); } + +/************ COLLIDER ****************/ void shape_enabled(struct phys2d_shape *shape, int enabled) { if (enabled) diff --git a/source/engine/2dphysics.h b/source/engine/2dphysics.h index d23f068..9e62b09 100644 --- a/source/engine/2dphysics.h +++ b/source/engine/2dphysics.h @@ -23,12 +23,14 @@ struct phys2d_shape { void (*debugdraw)(void *data); }; +/* Circles are the fastest collier type */ struct phys2d_circle { float radius; cpVect offset; struct phys2d_shape shape; }; +/* A single segment */ struct phys2d_segment { float a[2]; float b[2]; @@ -36,27 +38,31 @@ struct phys2d_segment { struct phys2d_shape shape; }; +/* A convex polygon; defined as the convex hull around the given set of points */ +struct phys2d_poly { + cpVect *points; + float radius; + struct phys2d_shape shape; +}; + +/* A box shape; a type of a polygon collider */ struct phys2d_box { float w; float h; float offset[2]; + float rotation; float r; struct phys2d_shape shape; }; +/* An edge with no volume. Cannot collide with each other. Join to make levels. */ struct phys2d_edge { - int n; - float *points; + cpVect *points; float thickness; cpShape **shapes; + int closed; /* True if the first and last points should be connected */ struct phys2d_shape shape; -}; - -struct phys2d_poly { - int n; - float *points; - float radius; - struct phys2d_shape shape; + int draws; }; struct phys2d_circle *Make2DCircle(int go); @@ -65,12 +71,6 @@ void phys2d_applycircle(struct phys2d_circle *circle); void phys2d_dbgdrawcircle(struct phys2d_circle *circle); void circle_gui(struct phys2d_circle *circle); -struct phys2d_segment *Make2DSegment(int go); -void phys2d_segdel(struct phys2d_segment *seg); -void phys2d_applyseg(struct phys2d_segment *seg); -void phys2d_dbgdrawseg(struct phys2d_segment *seg); -void segment_gui(struct phys2d_segment *seg); - struct phys2d_box *Make2DBox(int go); void phys2d_boxdel(struct phys2d_box *box); void phys2d_applybox(struct phys2d_box *box); @@ -82,14 +82,15 @@ void phys2d_polydel(struct phys2d_poly *poly); void phys2d_applypoly(struct phys2d_poly *poly); void phys2d_dbgdrawpoly(struct phys2d_poly *poly); void phys2d_polyaddvert(struct phys2d_poly *poly); +void phys2d_poly_setverts(struct phys2d_poly *poly, cpVect *verts); void poly_gui(struct phys2d_poly *poly); struct phys2d_edge *Make2DEdge(int go); void phys2d_edgedel(struct phys2d_edge *edge); void phys2d_applyedge(struct phys2d_edge *edge); -void phys2d_edgeshapeapply(struct phys2d_shape *mshape, cpShape * shape); void phys2d_dbgdrawedge(struct phys2d_edge *edge); void phys2d_edgeaddvert(struct phys2d_edge *edge); +void phys2d_edge_rmvert(struct phys2d_edge *edge, int index); void edge_gui(struct phys2d_edge *edge); diff --git a/source/engine/debug/debug.h b/source/engine/debug/debug.h index 53ee327..5181597 100644 --- a/source/engine/debug/debug.h +++ b/source/engine/debug/debug.h @@ -1,6 +1,8 @@ #ifndef DEBUG_GUI_H #define DEBUG_GUI_H +#define static_assert(pred) switch(0){case 0:case pred:;} + extern unsigned long long triCount; void resetTriangles(); diff --git a/source/engine/debug/debugdraw.c b/source/engine/debug/debugdraw.c index 406bf6f..ce63d64 100644 --- a/source/engine/debug/debugdraw.c +++ b/source/engine/debug/debugdraw.c @@ -4,6 +4,10 @@ #include "shader.h" #include "log.h" +#include +#include "debug.h" + +#include "stb_ds.h" static uint32_t circleVBO; static uint32_t circleVAO; @@ -59,9 +63,20 @@ void draw_line(int x1, int y1, int x2, int y2, float *color) draw_poly(verts, 2, color); } -void draw_edge(float *points, int n, float *color) +void draw_edge(cpVect *points, int n, float *color) { - draw_poly(points, n, color); + static_assert(sizeof(cpVect) == 2*sizeof(float)); + + shader_use(rectShader); + shader_setvec3(rectShader, "linecolor", color); + glBindBuffer(GL_ARRAY_BUFFER, rectVBO); + glBufferData(GL_ARRAY_BUFFER, sizeof(float) * n * 2, points, GL_DYNAMIC_DRAW); + glBindVertexArray(rectVAO); + glEnableVertexAttribArray(0); + glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 0, NULL); + + shader_setfloat(rectShader, "alpha", 1.f); + glDrawArrays(GL_LINE_STRIP, 0, n); } void draw_circle(int x, int y, float radius, int pixels, float *color, int fill) @@ -120,6 +135,12 @@ void draw_point(int x, int y, float r, float *color) draw_circle(x, y, r, r, color, 0); } +void draw_points(struct cpVect *points, int n, float size, float *color) +{ + for (int i = 0; i < n; i++) + draw_point(points[i].x, points[i].y, size, color); +} + void draw_poly(float *points, int n, float *color) { shader_use(rectShader); @@ -138,6 +159,17 @@ void draw_poly(float *points, int n, float *color) glDrawArrays(GL_LINE_LOOP, 0, n); } +void draw_polyvec(cpVect *points, int n, float *color) +{ + float drawvec[n*2]; + for (int i = 0; i < n; i++) { + drawvec[i*2] = points[i].x; + drawvec[i*2+1] = points[i].y; + } + + draw_poly(drawvec, n, color); +} + void debugdraw_flush() { diff --git a/source/engine/debug/debugdraw.h b/source/engine/debug/debugdraw.h index 589d451..2004ece 100644 --- a/source/engine/debug/debugdraw.h +++ b/source/engine/debug/debugdraw.h @@ -1,15 +1,19 @@ #ifndef DEBUGDRAW_H #define DEBUGDRAW_H +struct cpVect; + void debugdraw_init(); void draw_line(int x1, int y1, int x2, int y2, float *color); -void draw_edge(float *points, int n, float *color); +void draw_edge(struct cpVect *points, int n, float *color); +void draw_points(struct cpVect *points, int n, float size, float *color); void draw_circle(int x, int y, float radius, int pixels, float *color, int fill); void draw_grid(int width, int span); void draw_rect(int x, int y, int w, int h, float *color); void draw_point(int x, int y, float r, float *color); void draw_poly(float *points, int n, float *color); + void debugdraw_flush(); /* This is called once per frame to draw all queued elements */ diff --git a/source/engine/engine.c b/source/engine/engine.c index 4e61a44..14f32c9 100644 --- a/source/engine/engine.c +++ b/source/engine/engine.c @@ -64,5 +64,5 @@ void engine_init() phys2d_init(); YughInfo("Starting sound ..."); - sound_init(); + //sound_init(); } diff --git a/source/engine/ffi.c b/source/engine/ffi.c index 0064dac..519ee6c 100644 --- a/source/engine/ffi.c +++ b/source/engine/ffi.c @@ -21,6 +21,12 @@ #include "music.h" #include "level.h" +void duk_dump_stack(duk_context *duk) +{ + duk_push_context_dump(duk); + YughInfo("DUK STACK\n%s", duk_to_string(duk, -1)); +} + struct color duk2color(duk_context *duk, int p) { struct color color; @@ -37,6 +43,8 @@ struct color duk2color(duk_context *duk, int p) cpVect duk2vec2(duk_context *duk, int p) { cpVect pos; + if (p < 0) p = duk_get_top_index(duk) + p + 1; + duk_get_prop_index(duk, p, 0); pos.x = duk_to_number(duk, -1); duk_get_prop_index(duk, p, 1); @@ -125,7 +133,6 @@ duk_ret_t duk_cmd(duk_context *duk) { case 0: duk_push_int(duk, script_dofile(duk_to_string(duk, 1))); return 1; - break; case 1: set_pawn(duk_get_heapptr(duk, 1)); @@ -270,12 +277,21 @@ duk_ret_t duk_cmd(duk_context *duk) { case 36: id2go(duk_to_int(duk, 1))->scale = duk_to_number(duk, 2); + cpSpaceReindexShapesForBody(space, id2go(duk_to_int(duk, 1))->body); return 0; case 37: if (!id2sprite(duk_to_int(duk, 1))) return 0; vec2float(duk2vec2(duk, 2), id2sprite(duk_to_int(duk, 1))->pos); break; + + case 38: + duk_push_string(duk, slurp_text(duk_to_string(duk, 1))); + return 1; + + case 39: + duk_push_int(duk, slurp_write(duk_to_string(duk, 1), duk_to_string(duk, 2))); + return 1; } return 0; @@ -331,6 +347,7 @@ duk_ret_t duk_sys_cmd(duk_context *duk) { case 1: sim_start(); + cpSpaceReindexStatic(space); break; case 2: @@ -410,7 +427,6 @@ duk_ret_t duk_set_body(duk_context *duk) { switch (cmd) { case 0: gameobject_setangle(go, duk_to_number(duk, 2)); - cpSpaceReindexShapesForBody(space, go->body); break; case 1: @@ -419,7 +435,6 @@ duk_ret_t duk_set_body(duk_context *duk) { case 2: cpBodySetPosition(go->body, duk2vec2(duk, 2)); - cpSpaceReindexShapesForBody(space, go->body); break; case 3: @@ -452,6 +467,8 @@ duk_ret_t duk_set_body(duk_context *duk) { } + cpSpaceReindexShapesForBody(space, go->body); + return 0; } @@ -543,20 +560,26 @@ duk_ret_t duk_cmd_box2d(duk_context *duk) { int cmd = duk_to_int(duk, 0); struct phys2d_box *box = duk_to_pointer(duk, 1); - cpVect arg = duk2vec2(duk, 2); + cpVect arg; if (!box) return 0; switch(cmd) { case 0: + arg = duk2vec2(duk, 2); box->w = arg.x; box->h = arg.y; break; case 1: + arg = duk2vec2(duk, 2); box->offset[0] = arg.x; box->offset[1] = arg.y; break; + + case 2: + box->rotation = duk_to_number(duk, 2); + break; } phys2d_applybox(box); @@ -603,6 +626,54 @@ duk_ret_t duk_cmd_circle2d(duk_context *duk) return 0; } +duk_ret_t duk_make_poly2d(duk_context *duk) +{ + int go = duk_to_int(duk, 0); + struct phys2d_poly *poly = Make2DPoly(go); + + YughInfo("Making polygon."); + + return 0; +} + +duk_ret_t duk_cmd_poly2d(duk_context *duk) +{ + +} + +duk_ret_t duk_make_edge2d(duk_context *duk) +{ + int go = duk_to_int(duk, 0); + struct phys2d_edge *edge = Make2DEdge(go); + + int arridx = 1; + + int n = duk_get_length(duk, arridx); + cpVect points[n]; + + for (int i = 0; i < n; i++) { + duk_get_prop_index(duk, arridx, i); + + points[i] = duk2vec2(duk, -1); + + phys2d_edgeaddvert(edge); + phys2d_edge_setvert(edge, i, points[i]); + } + + int idx = duk_push_object(duk); + duk_push_pointer(duk, &edge->shape); + duk_put_prop_string(duk, idx, "id"); + duk_push_pointer(duk, edge); + duk_put_prop_string(duk, idx, "shape"); + + return 1; +} + +duk_ret_t duk_cmd_edge2d(duk_context *duk) +{ + +} + /* These are anims for controlling properties on an object */ duk_ret_t duk_anim(duk_context *duk) { void *prop = duk_get_heapptr(duk, 0); @@ -663,6 +734,10 @@ void ffi_load() DUK_FUNC(cmd_box2d, DUK_VARARGS); DUK_FUNC(make_circle2d, 3); DUK_FUNC(cmd_circle2d, DUK_VARARGS); + DUK_FUNC(make_poly2d, 2); + DUK_FUNC(cmd_poly2d, DUK_VARARGS); + DUK_FUNC(make_edge2d, 3); + DUK_FUNC(cmd_edge2d, DUK_VARARGS); DUK_FUNC(make_timer, 3); DUK_FUNC(cmd, DUK_VARARGS); diff --git a/source/engine/font.c b/source/engine/font.c index e169d8c..1e11245 100644 --- a/source/engine/font.c +++ b/source/engine/font.c @@ -54,6 +54,16 @@ unsigned char *slurp_text(const char *filename) { return buf; } +int slurp_write(const char *txt, const char *filename) +{ + FILE *f = fopen(filename, "w"); + if (!f) return 1; + + fputs(txt, f); + fclose(f); + return 0; +} + void font_init(struct shader *textshader) { shader = textshader; diff --git a/source/engine/font.h b/source/engine/font.h index ece091d..96526b5 100644 --- a/source/engine/font.h +++ b/source/engine/font.h @@ -34,4 +34,6 @@ void renderText(const char *text, mfloat_t pos[2], float scale, mfloat_t color[3 unsigned char *slurp_file(const char *filename); unsigned char *slurp_text(const char *filename); +int slurp_write(const char *txt, const char *filename); + #endif diff --git a/source/engine/sound/mix.c b/source/engine/sound/mix.c index afa8bb1..c2f2ed8 100644 --- a/source/engine/sound/mix.c +++ b/source/engine/sound/mix.c @@ -6,6 +6,8 @@ #include #include "log.h" +#include + static struct bus bus[256]; static int first = 0; /* First bus available */ //static struct bus *first_on = NULL; @@ -35,10 +37,8 @@ void mixer_init() { } struct bus *first_free_bus(struct dsp_filter in) { - if (!initted) { - YughError("Tried to use a mixing bus without calling mixer_init()."); - return NULL; - } + if (!initted) return; + assert(initted); if (first == -1) return NULL; int ret = first;