From 666564d9ec8076e3997fb7a9294298c39b44d01f Mon Sep 17 00:00:00 2001 From: Cameron Reikes Date: Wed, 14 Dec 2022 21:35:08 -0800 Subject: [PATCH] Collision fixes, queue refactor to prevent mistake --- buildsettings.h | 8 ++++---- flight.rdbg | Bin 2480 -> 1825 bytes gamestate.c | 45 ++++++++++++++++++++++++--------------------- queue.h | 19 +++++++++++++------ 4 files changed, 41 insertions(+), 31 deletions(-) diff --git a/buildsettings.h b/buildsettings.h index 0af037c..24696cf 100644 --- a/buildsettings.h +++ b/buildsettings.h @@ -16,15 +16,15 @@ #define PROFILING // #define DEBUG_RENDERING -// #define DEBUG_WORLD +#define DEBUG_WORLD #define UNLOCK_ALL -// #define TIME_BETWEEN_WORLD_SAVE 1000000.0f -#define TIME_BETWEEN_WORLD_SAVE 1.0f +#define TIME_BETWEEN_WORLD_SAVE 1000000.0f +// #define TIME_BETWEEN_WORLD_SAVE 1.0f // #define INFINITE_RESOURCES #define DEBUG_TOOLS #define CHIPMUNK_INTEGRITY_CHECK // #define FAT_THRUSTERS -// #define NO_GRAVITY +#define NO_GRAVITY // #define NO_SUNS #else diff --git a/flight.rdbg b/flight.rdbg index a7738f477179133c1e1e028b5be80d1df10bad6e..21735e3f8b6dee1eb4253306bef79f21dfbe1104 100644 GIT binary patch delta 64 zcmdlWypV50H7ld<1`saX9L6rm$jCUkkVBaZEXVx}h)nqC(4LzRZU{Y;OQ5@B$bW9 zv|6iMjcWC*R@wPY&Qtm9u0$e2eVn8vWW|cjS)`la$W7&T3&4AC)W@jL5+oV&v5=gN zHULkn3pnw0lL$0syuSuu-M+RQ)NFTLtGD;hVconVp~QRbody, (pos)); } -static const cpShapeFilter BOXES_FILTER = {CP_NO_GROUP, BOXES, BOXES}; -static const cpShapeFilter NOT_BOXES_FILTER = {CP_NO_GROUP, CP_ALL_CATEGORIES & (~BOXES), CP_ALL_CATEGORIES}; -#define PLAYER_SHAPE_FILTER cpShapeFilterNew(CP_NO_GROUP, PLAYERS, CP_ALL_CATEGORIES) +// IMPORTANT: all shapes must exist in one of these categories, as by default chipmunk assigns an object +// to be in every category. Which is bad because that doesn't make sense for entities +enum +{ + DEFAULT = 1 << 0, + BOXES = 1 << 1, +}; +static const cpShapeFilter FILTER_ONLY_BOXES = {CP_NO_GROUP, BOXES, BOXES}; +static const cpShapeFilter FILTER_BOXES = {CP_NO_GROUP, DEFAULT | BOXES, CP_ALL_CATEGORIES}; +static const cpShapeFilter FILTER_DEFAULT = {CP_NO_GROUP, DEFAULT, CP_ALL_CATEGORIES}; +#define PLAYER_FILTER FILTER_DEFAULT // size is (1/2 the width, 1/2 the height) void create_rectangle_shape(GameState *gs, Entity *e, Entity *parent, cpVect pos, cpVect size, double mass) @@ -567,7 +569,7 @@ void create_rectangle_shape(GameState *gs, Entity *e, Entity *parent, cpVect pos cpShapeSetUserData(e->shape, (void *)e); cpShapeSetMass(e->shape, mass); cpSpaceAddShape(gs->space, e->shape); - cpShapeSetFilter(e->shape, NOT_BOXES_FILTER); + cpShapeSetFilter(e->shape, FILTER_DEFAULT); } void create_circle_shape(GameState *gs, Entity *e, double radius) { @@ -577,7 +579,7 @@ void create_circle_shape(GameState *gs, Entity *e, double radius) cpShapeSetMass(e->shape, ORB_MASS); cpShapeSetUserData(e->shape, (void *)e); cpSpaceAddShape(gs->space, e->shape); - cpShapeSetFilter(e->shape, NOT_BOXES_FILTER); + cpShapeSetFilter(e->shape, FILTER_DEFAULT); } void create_player(Player *player) @@ -620,7 +622,7 @@ void create_player_entity(GameState *gs, Entity *e) e->no_save_to_disk = true; create_body(gs, e); create_rectangle_shape(gs, e, e, (cpVect){0}, cpvmult(PLAYER_SIZE, 0.5), PLAYER_MASS); - cpShapeSetFilter(e->shape, PLAYER_SHAPE_FILTER); + cpShapeSetFilter(e->shape, PLAYER_FILTER); } void box_add_to_boxes(GameState *gs, Entity *grid, Entity *box_to_add) @@ -646,7 +648,7 @@ void box_create(GameState *gs, Entity *new_box, Entity *grid, cpVect pos) create_rectangle_shape(gs, new_box, grid, pos, (cpVect){halfbox, halfbox}, 1.0); - cpShapeSetFilter(new_box->shape, BOXES_FILTER); + cpShapeSetFilter(new_box->shape, FILTER_BOXES); box_add_to_boxes(gs, grid, new_box); } @@ -1385,8 +1387,8 @@ SerMaybeFailure ser_entity(SerState *ser, GameState *gs, Entity *e) else { create_rectangle_shape(gs, e, parent, shape_pos, e->shape_size, shape_mass); - cpShapeSetFilter(e->shape, filter); } + cpShapeSetFilter(e->shape, filter); } } @@ -2306,7 +2308,7 @@ void create_initial_world(GameState *gs) create_orb(gs, orb); \ entity_set_pos(orb, pos); \ } - for(int x = -10; x > -1000; x -= 20) + for (int x = -10; x > -1000; x -= 20) { ORB_AT(cpv(x, 0.0)); } @@ -2317,6 +2319,7 @@ void create_initial_world(GameState *gs) create_hard_shell_station(gs, (cpVect){-7000.0, 200.0}, BoxMerge); #else Log("Creating debug world\n"); + // pos, mass, radius create_bomb_station(gs, (cpVect){-5.0, 0.0}, BoxExplosive); create_bomb_station(gs, (cpVect){0.0, 5.0}, BoxGyroscope); @@ -2519,7 +2522,7 @@ void process(struct GameState *gs, double dt) if (seat_maybe_in == NULL) // not in any seat { cpPointQueryInfo query_info = {0}; - cpShape *result = cpSpacePointQueryNearest(gs->space, (world_hand_pos), 0.1, BOXES_FILTER, &query_info); + cpShape *result = cpSpacePointQueryNearest(gs->space, (world_hand_pos), 0.1, FILTER_ONLY_BOXES, &query_info); if (result != NULL) { Entity *potential_seat = cp_shape_entity(result); @@ -2595,7 +2598,7 @@ void process(struct GameState *gs, double dt) if (seat_inside_of == NULL) { - cpShapeSetFilter(p->shape, PLAYER_SHAPE_FILTER); + cpShapeSetFilter(p->shape, PLAYER_FILTER); cpBodyApplyForceAtWorldPoint(p->body, (cpvmult(movement_this_tick, PLAYER_JETPACK_FORCE)), cpBodyGetPosition(p->body)); cpBodySetTorque(p->body, rotation_this_tick * PLAYER_JETPACK_TORQUE); p->damage += cpvlength(movement_this_tick) * dt * PLAYER_JETPACK_SPICE_PER_SECOND; @@ -3034,7 +3037,7 @@ void process(struct GameState *gs, double dt) .rotation = entity_rotation(cur_box), // subtract a little from the panel size so that boxes just at the boundary of the panel // aren't (sometimes cloaked)/(sometimes not) from floating point imprecision - .size = cpv(CLOAKING_PANEL_SIZE - 0.03, CLOAKING_PANEL_SIZE - 0.03), + .size = cpv(CLOAKING_PANEL_SIZE / 2.0 - 0.03, CLOAKING_PANEL_SIZE / 2.0 - 0.03), }); QUEUE_ITER(&query_result, QueryResult, res) { diff --git a/queue.h b/queue.h index c9bb3db..ab04241 100644 --- a/queue.h +++ b/queue.h @@ -17,7 +17,7 @@ typedef struct QueueElementHeader typedef struct Queue { char *data; - size_t data_length; // must be a multiple of sizeof(QueueElementHeader) + element_size + size_t max_elements; size_t element_size; QueueElementHeader *next; } Queue; @@ -25,7 +25,10 @@ typedef struct Queue #define QUEUE_SIZE_FOR_ELEMENTS(element_size, max_elements) ((sizeof(QueueElementHeader) + element_size) * max_elements) // oldest to newest -#define QUEUE_ITER(q_ptr, type, cur) for (QueueElementHeader *cur_header = (q_ptr)->next; cur_header != NULL; cur_header = cur_header->next) for(type *cur = (type*)cur_header->data; cur != NULL; cur = NULL) +#define QUEUE_ITER(q_ptr, type, cur) \ + for (QueueElementHeader *cur_header = (q_ptr)->next; cur_header != NULL; cur_header = cur_header->next) \ + for (type *cur = (type *)cur_header->data; cur != NULL; cur = NULL) +size_t queue_data_length(Queue *q); void queue_init(Queue *q, size_t element_size, char *data, size_t data_length); void queue_clear(Queue *q); void *queue_push_element(Queue *q); @@ -34,26 +37,30 @@ void *queue_pop_element(Queue *q); void *queue_most_recent_element(Queue *q); #ifdef QUEUE_IMPL +size_t queue_data_length(Queue *q) +{ + return QUEUE_SIZE_FOR_ELEMENTS(q->element_size, q->max_elements); +} void queue_init(Queue *q, size_t element_size, char *data, size_t data_length) { + QUEUE_ASSERT(data_length % (sizeof(QueueElementHeader) + element_size) == 0); q->data = data; - q->data_length = data_length; q->element_size = element_size; - QUEUE_ASSERT(data_length % (sizeof(QueueElementHeader) + element_size) == 0); + q->max_elements = data_length / (sizeof(QueueElementHeader) + element_size); } void queue_clear(Queue *q) { QUEUE_ASSERT(q->data != NULL); - for (size_t i = 0; i < q->data_length; i++) + for (size_t i = 0; i < queue_data_length(q); i++) { q->data[i] = 0; } q->next = NULL; } -#define QUEUE_ELEM_ITER(cur) for (QueueElementHeader *cur = (QueueElementHeader *)q->data; (char *)cur < q->data + q->data_length; cur = (QueueElementHeader*)((char*)cur + (sizeof(QueueElementHeader) + q->element_size))) +#define QUEUE_ELEM_ITER(cur) for (QueueElementHeader *cur = (QueueElementHeader *)q->data; (char *)cur < q->data + queue_data_length(q); cur = (QueueElementHeader *)((char *)cur + (sizeof(QueueElementHeader) + q->element_size))) // you push an element, get the return value, cast it to your type, and fill it with data. It's that easy! // if it's null the queue is out of space