diff --git a/.vscode/settings.json b/.vscode/settings.json index 7059129..989c230 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -52,6 +52,8 @@ "xtr1common": "c", "xtree": "c", "stdint.h": "c", - "ipsettings.h": "c" + "ipsettings.h": "c", + "cpvect.h": "c", + "miniaudio.h": "c" } } \ No newline at end of file diff --git a/Flight.vcxproj b/Flight.vcxproj index 068e088..8645300 100644 --- a/Flight.vcxproj +++ b/Flight.vcxproj @@ -144,6 +144,7 @@ true $(ProjectDir)\thirdparty\enet\include;$(ProjectDir)\thirdparty\Chipmunk2D\include\chipmunk;$(ProjectDir)\thirdparty;$(ProjectDir)\thirdparty\Chipmunk2D\include;$(ProjectDir)\thirdparty\minilzo;$(ProjectDir)\thirdparty\opus\include true + MultiThreaded Console diff --git a/Flight.vcxproj.user b/Flight.vcxproj.user index b0274e8..a8c5a48 100644 --- a/Flight.vcxproj.user +++ b/Flight.vcxproj.user @@ -4,8 +4,7 @@ false - - + --host WindowsLocalDebugger diff --git a/build_msvc.bat b/build_msvc.bat index 7528060..6e185f7 100644 --- a/build_msvc.bat +++ b/build_msvc.bat @@ -3,10 +3,11 @@ @REM what all the compile flags mean: https://learn.microsoft.com/en-us/cpp/build/reference/compiler-options-listed-by-category?view=msvc-170 -set OPUSLIB=%~dp0\thirdparty\opus\win32\VS2015\x64\Release\opus.lib +set OPUSLIB=%~dp0thirdparty\opus\win32\VS2015\x64\Release\opus.lib -WHERE %OPUSLIB% -IF %ERRORLEVEL% NEQ 0 ECHO ERROR Couldn't find %OPUSLIB% compile opus by opening the visual studio project in win32\VS2015 and building the release setting +if not exist %OPUSLIB% ( + ECHO ERROR Couldn't find %OPUSLIB% compile opus by opening the visual studio project in win32\VS2015 and building the release setting +) setlocal enabledelayedexpansion enableextensions pushd thirdparty\Chipmunk2D\src diff --git a/debugdraw.c b/debugdraw.c index ee4e101..47607ff 100644 --- a/debugdraw.c +++ b/debugdraw.c @@ -48,7 +48,7 @@ void dbg_drawall() case rect: { V2 center = commands[i].center; - V2 upper_left = V2add(center, (V2){.x = -size / 2.0, .y = -size / 2.0}); + V2 upper_left = cpvadd(center, (V2){.x = -size / 2.0, .y = -size / 2.0}); sgp_draw_filled_rect((float)upper_left.x, (float)upper_left.y, (float)size, (float)size); break; } diff --git a/gamestate.c b/gamestate.c index 33c78dc..4f5ca7e 100644 --- a/gamestate.c +++ b/gamestate.c @@ -30,16 +30,6 @@ void __flight_assert(bool cond, const char *file, int line, const char *cond_str } } -static V2 cp_to_v2(cpVect v) -{ - return (V2){.x = (float)v.x, .y = (float)v.y}; -} - -static cpVect v2_to_cp(V2 v) -{ - return cpv(v.x, v.y); -} - bool is_burning(Entity *missile) { assert(missile->is_missile); @@ -212,7 +202,7 @@ V2 entity_vel(GameState *gs, Entity *e) if (e->is_player) return player_vel(gs, e); if (e->body != NULL) - return cp_to_v2(cpBodyGetVelocity(e->body)); + return (cpBodyGetVelocity(e->body)); if (e->is_explosion) return e->explosion_vel; assert(false); @@ -229,29 +219,29 @@ static void on_missile_shape(cpShape *shape, cpContactPointSet *points, void *da GameState *gs = entitys_gamestate(launcher); assert(other->is_box || other->is_player || other->is_missile); - V2 to = V2sub(entity_pos(other), entity_pos(launcher)); + V2 to = cpvsub(entity_pos(other), entity_pos(launcher)); bool should_attack = true; if (other->is_box && box_grid(other) == box_grid(launcher)) should_attack = false; if (other->owning_squad == launcher->owning_squad) should_attack = false; - if (should_attack && V2length(to) < nearest_dist) + if (should_attack && cpvlength(to) < nearest_dist) { target_found = true; - nearest_dist = V2length(to); + nearest_dist = cpvlength(to); // lookahead by their velocity - V2 rel_velocity = V2sub(entity_vel(gs, other), entity_vel(gs, launcher)); - double dist = V2dist(entity_pos(other), entity_pos(launcher)); + V2 rel_velocity = cpvsub(entity_vel(gs, other), entity_vel(gs, launcher)); + double dist = cpvdist(entity_pos(other), entity_pos(launcher)); double time_of_travel = sqrt((2.0 * dist) / (MISSILE_BURN_FORCE / MISSILE_MASS)); - V2 other_future_pos = V2add(entity_pos(other), V2scale(rel_velocity, time_of_travel)); + V2 other_future_pos = cpvadd(entity_pos(other), cpvmult(rel_velocity, time_of_travel)); - V2 adjusted_to = V2sub(other_future_pos, entity_pos(launcher)); + V2 adjusted_to = cpvsub(other_future_pos, entity_pos(launcher)); - to_face = V2angle(adjusted_to); + to_face = cpvangle(adjusted_to); } } @@ -259,7 +249,7 @@ LauncherTarget missile_launcher_target(GameState *gs, Entity *launcher) { to_face = 0.0; cpBody *tmp = cpBodyNew(0.0, 0.0); - cpBodySetPosition(tmp, v2_to_cp(entity_pos(launcher))); + cpBodySetPosition(tmp, (entity_pos(launcher))); cpShape *circle = cpCircleShapeNew(tmp, MISSILE_RANGE, cpv(0, 0)); nearest_dist = INFINITY; @@ -389,10 +379,10 @@ V2 player_vel(GameState *gs, Entity *player) { if (potential_seat != NULL) { - return cp_to_v2(cpBodyGetVelocity(get_entity(gs, potential_seat->shape_parent_entity)->body)); + return (cpBodyGetVelocity(get_entity(gs, potential_seat->shape_parent_entity)->body)); } } - return cp_to_v2(cpBodyGetVelocity(player->body)); + return (cpBodyGetVelocity(player->body)); } void grid_create(GameState *gs, Entity *e) @@ -401,6 +391,7 @@ void grid_create(GameState *gs, Entity *e) create_body(gs, e); } + void entity_set_rotation(Entity *e, double rot) { assert(e->body != NULL); @@ -411,7 +402,7 @@ void entity_set_pos(Entity *e, V2 pos) { assert(e->is_grid); assert(e->body != NULL); - cpBodySetPosition(e->body, v2_to_cp(pos)); + cpBodySetPosition(e->body, (pos)); } // size is (1/2 the width, 1/2 the height) @@ -462,7 +453,7 @@ void create_player(Player *player) void create_missile(GameState *gs, Entity *e) { create_body(gs, e); - create_rectangle_shape(gs, e, e, (V2){0}, V2scale(MISSILE_COLLIDER_SIZE, 0.5), PLAYER_MASS); + create_rectangle_shape(gs, e, e, (V2){0}, cpvmult(MISSILE_COLLIDER_SIZE, 0.5), PLAYER_MASS); e->is_missile = true; } @@ -471,7 +462,7 @@ void create_player_entity(GameState *gs, Entity *e) e->is_player = true; e->no_save_to_disk = true; create_body(gs, e); - create_rectangle_shape(gs, e, e, (V2){0}, V2scale(PLAYER_SIZE, 0.5), PLAYER_MASS); + create_rectangle_shape(gs, e, e, (V2){0}, cpvmult(PLAYER_SIZE, 0.5), PLAYER_MASS); cpShapeSetFilter(e->shape, PLAYER_SHAPE_FILTER); } @@ -508,7 +499,7 @@ V2 box_compass_vector(Entity *box) assert(box->is_box); V2 to_return = (V2){.x = 1.0, .y = 0.0}; - to_return = V2rotate(to_return, rotangle(box->compass_rotation)); + to_return = cpvspin(to_return, rotangle(box->compass_rotation)); return to_return; } @@ -593,15 +584,15 @@ static void grid_correct_for_holes(GameState *gs, struct Entity *grid) // @Robust @Speed faster method, not O(N^2), of getting the box // in the direction currently needed V2 compass_vect = box_compass_vector(N); - if (N->box_type == BoxMerge && N->wants_disconnect && V2equal(compass_vect, dir, 0.01)) + if (N->box_type == BoxMerge && N->wants_disconnect && cpvnear(compass_vect, dir, 0.01)) { } else { - V2 wanted_local_pos = V2add(cur_local_pos, V2scale(dir, BOX_SIZE)); + V2 wanted_local_pos = cpvadd(cur_local_pos, cpvmult(dir, BOX_SIZE)); BOXES_ITER(gs, cur, grid) { - if (V2equal(entity_shape_pos(cur), wanted_local_pos, 0.01)) + if (cpvnear(entity_shape_pos(cur), wanted_local_pos, 0.01)) { box_in_direction = get_id(gs, cur); break; @@ -611,7 +602,7 @@ static void grid_correct_for_holes(GameState *gs, struct Entity *grid) Entity *newbox = get_entity(gs, box_in_direction); - if (newbox != NULL && newbox->box_type == BoxMerge && newbox->wants_disconnect && V2equal(V2scale(box_compass_vector(newbox), -1.0), dir, 0.01)) + if (newbox != NULL && newbox->box_type == BoxMerge && newbox->wants_disconnect && cpvnear(cpvmult(box_compass_vector(newbox), -1.0), dir, 0.01)) { newbox = NULL; } @@ -667,7 +658,7 @@ static void grid_correct_for_holes(GameState *gs, struct Entity *grid) cur = next; } - cpBodySetVelocity(new_grid->body, cpBodyGetVelocityAtWorldPoint(grid->body, v2_to_cp(grid_com(new_grid)))); + cpBodySetVelocity(new_grid->body, cpBodyGetVelocityAtWorldPoint(grid->body, (grid_com(new_grid)))); cpBodySetAngularVelocity(new_grid->body, entity_angular_velocity(grid)); } } @@ -705,7 +696,7 @@ static void on_damage(cpArbiter *arb, cpSpace *space, cpDataPointer userData) for (int i = 0; i < count; i++) { cpVect collision_point = getPointFunc(arb, i); - V2 local_collision_point = cp_to_v2(cpBodyWorldToLocal(missile->body, collision_point)); + V2 local_collision_point = (cpBodyWorldToLocal(missile->body, collision_point)); if (local_collision_point.x > MISSILE_COLLIDER_SIZE.x * 0.2) { missile->damage += MISSILE_DAMAGE_THRESHOLD * 2.0; @@ -717,7 +708,7 @@ static void on_damage(cpArbiter *arb, cpSpace *space, cpDataPointer userData) // if(entity_a->is_missile) {getPointFunc = cpArbiterGetPointA; // if(entity_b->is_missile) getPointFunc = cpArbiterGetPointB; - double damage = V2length(cp_to_v2(cpArbiterTotalImpulse(arb))) * COLLISION_DAMAGE_SCALING; + double damage = cpvlength((cpArbiterTotalImpulse(arb))) * COLLISION_DAMAGE_SCALING; if (entity_a->is_box && entity_a->box_type == BoxExplosive) entity_a->damage += 2.0 * EXPLOSION_DAMAGE_THRESHOLD; @@ -772,21 +763,21 @@ void destroy(GameState *gs) // center of mass, not the literal position V2 grid_com(Entity *grid) { - return cp_to_v2(cpBodyLocalToWorld(grid->body, cpBodyGetCenterOfGravity(grid->body))); + return (cpBodyLocalToWorld(grid->body, cpBodyGetCenterOfGravity(grid->body))); } V2 grid_vel(Entity *grid) { - return cp_to_v2(cpBodyGetVelocity(grid->body)); + return (cpBodyGetVelocity(grid->body)); } V2 grid_world_to_local(Entity *grid, V2 world) { - return cp_to_v2(cpBodyWorldToLocal(grid->body, v2_to_cp(world))); + return (cpBodyWorldToLocal(grid->body, (world))); } V2 grid_local_to_world(Entity *grid, V2 local) { assert(grid->is_grid); - return cp_to_v2(cpBodyLocalToWorld(grid->body, v2_to_cp(local))); + return (cpBodyLocalToWorld(grid->body, (local))); } // returned snapped position is in world coordinates V2 grid_snapped_box_pos(Entity *grid, V2 world) @@ -799,7 +790,7 @@ V2 grid_snapped_box_pos(Entity *grid, V2 world) local.x *= BOX_SIZE; local.y *= BOX_SIZE; - return cp_to_v2(cpBodyLocalToWorld(grid->body, v2_to_cp(local))); + return (cpBodyLocalToWorld(grid->body, (local))); } // for boxes does not include box's compass rotation @@ -826,7 +817,7 @@ Entity *box_grid(Entity *box) // in local space V2 entity_shape_pos(Entity *box) { - return cp_to_v2(cpShapeGetCenterOfGravity(box->shape)); + return (cpShapeGetCenterOfGravity(box->shape)); } double entity_shape_mass(Entity *box) { @@ -842,7 +833,7 @@ V2 entity_pos(Entity *e) { if (e->is_box) { - return V2add(entity_pos(box_grid(e)), V2rotate(entity_shape_pos(e), entity_rotation(box_grid(e)))); + return cpvadd(entity_pos(box_grid(e)), cpvspin(entity_shape_pos(e), entity_rotation(box_grid(e)))); } else if (e->is_explosion) { @@ -855,7 +846,7 @@ V2 entity_pos(Entity *e) else { assert(e->body != NULL); - return cp_to_v2(cpBodyGetPosition(e->body)); + return (cpBodyGetPosition(e->body)); } } @@ -869,16 +860,16 @@ struct BodyData void populate(cpBody *body, struct BodyData *data) { - data->pos = cp_to_v2(cpBodyGetPosition(body)); - data->vel = cp_to_v2(cpBodyGetVelocity(body)); + data->pos = (cpBodyGetPosition(body)); + data->vel = (cpBodyGetVelocity(body)); data->rotation = (float)cpBodyGetAngle(body); data->angular_velocity = (float)cpBodyGetAngularVelocity(body); } void update_from(cpBody *body, struct BodyData *data) { - cpBodySetPosition(body, v2_to_cp(data->pos)); - cpBodySetVelocity(body, v2_to_cp(data->vel)); + cpBodySetPosition(body, (data->pos)); + cpBodySetVelocity(body, (data->vel)); cpBodySetAngle(body, data->rotation); cpBodySetAngularVelocity(body, data->angular_velocity); } @@ -1403,7 +1394,7 @@ SerMaybeFailure ser_server_to_client(SerState *ser, ServerToClient *s) { bool this_box_in_range = ser->save_or_load_from_disk; this_box_in_range |= ser->for_player == NULL; - this_box_in_range |= (ser->for_player != NULL && V2distsqr(entity_pos(ser->for_player), entity_pos(cur_box)) < VISION_RADIUS * VISION_RADIUS); // only in vision radius + this_box_in_range |= (ser->for_player != NULL && cpvdistsq(entity_pos(ser->for_player), entity_pos(cur_box)) < VISION_RADIUS * VISION_RADIUS); // only in vision radius if (DONT_SEND_BECAUSE_CLOAKED(cur_box)) this_box_in_range = false; if (cur_box->always_visible) @@ -1687,7 +1678,7 @@ static void closest_point_callback_func(cpShape *shape, cpContactPointSet *point if (closest_to_point_in_radius_filter_func != NULL && !closest_to_point_in_radius_filter_func(e)) return; - double dist = V2length(cp_to_v2(cpvsub(points->points[0].pointA, points->points[0].pointB))); + double dist = cpvlength((cpvsub(points->points[0].pointA, points->points[0].pointB))); // double dist = -points->points[0].distance; if (dist > closest_to_point_in_radius_result_largest_dist) { @@ -1704,7 +1695,7 @@ Entity *closest_box_to_point_in_radius(struct GameState *gs, V2 point, double ra closest_to_point_in_radius_result_largest_dist = 0.0; closest_to_point_in_radius_filter_func = filter_func; cpBody *tmpbody = cpBodyNew(0.0, 0.0); - cpShape *circle = cpCircleShapeNew(tmpbody, radius, v2_to_cp(point)); + cpShape *circle = cpCircleShapeNew(tmpbody, radius, (point)); cpSpaceShapeQuery(gs->space, circle, closest_point_callback_func, NULL); cpShapeFree(circle); @@ -1738,16 +1729,16 @@ static void explosion_callback_func(cpShape *shape, cpContactPointSet *points, v cp_shape_entity(shape)->damage += cur_explosion_damage; Entity *parent = get_entity(gs, cp_shape_entity(shape)->shape_parent_entity); V2 from_pos = entity_pos(cp_shape_entity(shape)); - V2 impulse = V2scale(V2normalize(V2sub(from_pos, explosion_origin)), explosion_push_strength); + V2 impulse = cpvmult(cpvnormalize(cpvsub(from_pos, explosion_origin)), explosion_push_strength); assert(parent->body != NULL); - cpBodyApplyImpulseAtWorldPoint(parent->body, v2_to_cp(impulse), v2_to_cp(from_pos)); + cpBodyApplyImpulseAtWorldPoint(parent->body, (impulse), (from_pos)); } static void do_explosion(GameState *gs, Entity *explosion, double dt) { cpBody *tmpbody = cpBodyNew(0.0, 0.0); - cpShape *circle = cpCircleShapeNew(tmpbody, explosion->explosion_radius, v2_to_cp(explosion_origin)); + cpShape *circle = cpCircleShapeNew(tmpbody, explosion->explosion_radius, (explosion_origin)); cur_explosion_damage = dt * EXPLOSION_DAMAGE_PER_SEC; explosion_origin = explosion->explosion_pos; @@ -1764,7 +1755,7 @@ V2 box_facing_vector(Entity *box) V2 to_return = (V2){.x = 1.0, .y = 0.0}; to_return = box_compass_vector(box); - to_return = V2rotate(to_return, box_rotation(box)); + to_return = cpvspin(to_return, box_rotation(box)); return to_return; } @@ -1774,10 +1765,10 @@ enum CompassRotation facing_vector_to_compass(Entity *grid_to_transplant_to, Ent assert(grid_to_transplant_to->body != NULL); assert(grid_to_transplant_to->is_grid); - V2 local_to_from = grid_world_to_local(grid_facing_vector_from, V2add(entity_pos(grid_facing_vector_from), facing_vector)); + V2 local_to_from = grid_world_to_local(grid_facing_vector_from, cpvadd(entity_pos(grid_facing_vector_from), facing_vector)); Log("local %f %f\n", local_to_from.x, local_to_from.y); - V2 from_target = V2add(entity_pos(grid_to_transplant_to), facing_vector); + V2 from_target = cpvadd(entity_pos(grid_to_transplant_to), facing_vector); V2 local_target = grid_world_to_local(grid_to_transplant_to, from_target); V2 local_facing = local_target; @@ -1791,8 +1782,8 @@ enum CompassRotation facing_vector_to_compass(Entity *grid_to_transplant_to, Ent double smallest_dist = INFINITY; for (int i = 0; i < ARRLEN(dirs); i++) { - V2 point = V2rotate((V2){.x = 1.0}, rotangle(dirs[i])); - double dist = V2dist(point, local_facing); + V2 point = cpvspin((V2){.x = 1.0}, rotangle(dirs[i])); + double dist = cpvdist(point, local_facing); if (dist < smallest_dist) { smallest_dist = dist; @@ -1805,7 +1796,7 @@ enum CompassRotation facing_vector_to_compass(Entity *grid_to_transplant_to, Ent V2 thruster_force(Entity *box) { - return V2scale(box_facing_vector(box), -box->thrust * THRUSTER_FORCE); + return cpvmult(box_facing_vector(box), -box->thrust * THRUSTER_FORCE); } uint64_t tick(GameState *gs) @@ -1830,7 +1821,7 @@ V2 potentially_snap_hand_pos(GameState *gs, V2 world_hand_pos) V2 get_world_hand_pos(GameState *gs, InputFrame *input, Entity *player) { - return potentially_snap_hand_pos(gs, V2add(entity_pos(player), input->hand_pos)); + return potentially_snap_hand_pos(gs, cpvadd(entity_pos(player), input->hand_pos)); } bool batteries_have_capacity_for(GameState *gs, Entity *grid, double *energy_left_over, double energy_to_use) @@ -1903,12 +1894,12 @@ V2 sun_gravity_accel_for_entity(Entity *entity_with_gravity, Entity *sun) return (V2){0}; #else - if (V2length(V2sub(entity_pos(entity_with_gravity), entity_pos(sun))) > sun_dist_no_gravity(sun)) + if (cpvlength(cpvsub(entity_pos(entity_with_gravity), entity_pos(sun))) > sun_dist_no_gravity(sun)) return (V2){0}; - V2 rel_vector = V2sub(entity_pos(entity_with_gravity), entity_pos(sun)); + V2 rel_vector = cpvsub(entity_pos(entity_with_gravity), entity_pos(sun)); double mass = entity_mass(entity_with_gravity); assert(mass != 0.0); - double distance_sqr = V2lengthsqr(rel_vector); + double distance_sqr = cpvlengthsq(rel_vector); // return (GRAVITY_CONSTANT * (SUN_MASS * mass / (distance * distance))) / mass; // the mass divides out @@ -1920,15 +1911,15 @@ V2 sun_gravity_accel_for_entity(Entity *entity_with_gravity, Entity *sun) if (distance_sqr <= sun->sun_radius * 0.25) accel_magnitude = 0.0; } - V2 towards_sun = V2normalize(V2scale(rel_vector, -1.0)); - return V2scale(towards_sun, accel_magnitude); + V2 towards_sun = cpvnormalize(cpvmult(rel_vector, -1.0)); + return cpvmult(towards_sun, accel_magnitude); #endif // NO_GRAVITY } void entity_set_velocity(Entity *e, V2 vel) { if (e->body != NULL) - cpBodySetVelocity(e->body, v2_to_cp(vel)); + cpBodySetVelocity(e->body, (vel)); else if (e->is_sun) e->sun_vel = vel; else @@ -1941,20 +1932,20 @@ void entity_ensure_in_orbit(GameState *gs, Entity *e) SUNS_ITER(gs) { V2 gravity_accel = sun_gravity_accel_for_entity(e, i.sun); - if (V2length(gravity_accel) > 0.0) + if (cpvlength(gravity_accel) > 0.0) { - double dist = V2length(V2sub(entity_pos(e), entity_pos(i.sun))); - V2 orthogonal_to_gravity = V2normalize(V2rotate(gravity_accel, PI / 2.0)); - V2 wanted_vel = V2scale(orthogonal_to_gravity, sqrt(V2length(gravity_accel) * dist)); + double dist = cpvlength(cpvsub(entity_pos(e), entity_pos(i.sun))); + V2 orthogonal_to_gravity = cpvnormalize(cpvspin(gravity_accel, PI / 2.0)); + V2 wanted_vel = cpvmult(orthogonal_to_gravity, sqrt(cpvlength(gravity_accel) * dist)); - total_new_vel = cpvadd(total_new_vel, v2_to_cp(wanted_vel)); + total_new_vel = cpvadd(total_new_vel, (wanted_vel)); } } - entity_set_velocity(e, cp_to_v2(total_new_vel)); + entity_set_velocity(e, (total_new_vel)); - // cpVect pos = v2_to_cp(V2sub(entity_pos(e), SUN_POS)); + // cpVect pos = (cpvsub(entity_pos(e), SUN_POS)); // cpFloat r = cpvlength(pos); - // cpFloat v = cpfsqrt(sun_gravity_accel_at_point(cp_to_v2(pos), e) / r) / r; + // cpFloat v = cpfsqrt(sun_gravity_accel_at_point((pos), e) / r) / r; // cpBodySetVelocity(e->body, cpvmult(cpvperp(pos), v)); } @@ -1962,7 +1953,7 @@ V2 box_vel(Entity *box) { assert(box->is_box); Entity *grid = box_grid(box); - return cp_to_v2(cpBodyGetVelocityAtWorldPoint(grid->body, v2_to_cp(entity_pos(box)))); + return (cpBodyGetVelocityAtWorldPoint(grid->body, (entity_pos(box)))); } void create_bomb_station(GameState *gs, V2 pos, enum BoxType platonic_type) @@ -2078,7 +2069,7 @@ void create_initial_world(GameState *gs) Entity *grid = new_entity(gs); grid_create(gs, grid); - entity_set_pos(grid, V2add(from, V2rotate((V2){.x = -BOX_SIZE * 9.0}, theta))); + entity_set_pos(grid, cpvadd(from, cpvspin((V2){.x = -BOX_SIZE * 9.0}, theta))); cpBodySetAngle(grid->body, theta + PI); rot = Left; BOX_AT_TYPE(grid, ((V2){0.0, 0.0}), BoxMerge); @@ -2098,7 +2089,7 @@ void create_initial_world(GameState *gs) BOX_AT_TYPE(grid, ((V2){0.0, 0.0}), BoxMerge); rot = Up; BOX_AT_TYPE(grid, ((V2){0.0, BOX_SIZE}), BoxMerge); - cpBodySetVelocity(grid->body, v2_to_cp(V2rotate((V2){-0.4, 0.0}, theta))); + cpBodySetVelocity(grid->body, (cpvspin((V2){-0.4, 0.0}, theta))); entity_ensure_in_orbit(gs, grid); } @@ -2113,9 +2104,9 @@ void create_initial_world(GameState *gs) void exit_seat(GameState *gs, Entity *seat_in, Entity *p) { - V2 pilot_seat_exit_spot = V2add(entity_pos(seat_in), V2scale(box_facing_vector(seat_in), BOX_SIZE)); - cpBodySetPosition(p->body, v2_to_cp(pilot_seat_exit_spot)); - // cpBodySetVelocity(p->body, v2_to_cp(player_vel(gs, p))); + V2 pilot_seat_exit_spot = cpvadd(entity_pos(seat_in), cpvmult(box_facing_vector(seat_in), BOX_SIZE)); + cpBodySetPosition(p->body, (pilot_seat_exit_spot)); + // cpBodySetVelocity(p->body, (player_vel(gs, p))); cpBodySetVelocity(p->body, cpBodyGetVelocity(box_grid(seat_in)->body)); } @@ -2140,17 +2131,17 @@ void process(GameState *gs, double dt) Entity *other_sun = i.sun; if (other_sun != from_sun) { - accel = V2add(accel, sun_gravity_accel_for_entity(from_sun, other_sun)); + accel = cpvadd(accel, sun_gravity_accel_for_entity(from_sun, other_sun)); } } #ifndef NO_GRAVITY - from_sun->sun_vel = V2add(from_sun->sun_vel, V2scale(accel, dt)); - from_sun->sun_pos = V2add(from_sun->sun_pos, V2scale(from_sun->sun_vel, dt)); + from_sun->sun_vel = cpvadd(from_sun->sun_vel, cpvmult(accel, dt)); + from_sun->sun_pos = cpvadd(from_sun->sun_pos, cpvmult(from_sun->sun_vel, dt)); - if (V2length(from_sun->sun_pos) >= INSTANT_DEATH_DISTANCE_FROM_CENTER) + if (cpvlength(from_sun->sun_pos) >= INSTANT_DEATH_DISTANCE_FROM_CENTER) { - from_sun->sun_vel = V2scale(from_sun->sun_vel, -0.8); - from_sun->sun_pos = V2scale(V2normalize(from_sun->sun_pos), INSTANT_DEATH_DISTANCE_FROM_CENTER); + from_sun->sun_vel = cpvmult(from_sun->sun_vel, -0.8); + from_sun->sun_pos = cpvmult(cpvnormalize(from_sun->sun_pos), INSTANT_DEATH_DISTANCE_FROM_CENTER); } #endif } @@ -2226,7 +2217,7 @@ void process(GameState *gs, double dt) p->damage = 0.0; #endif // update gold win condition - if (V2length(V2sub(cp_to_v2(cpBodyGetPosition(p->body)), gs->goldpos)) < GOLD_COLLECT_RADIUS) + if (cpvlength(cpvsub((cpBodyGetPosition(p->body)), gs->goldpos)) < GOLD_COLLECT_RADIUS) { p->goldness += 0.1; p->damage = 0.0; @@ -2241,7 +2232,7 @@ void process(GameState *gs, double dt) if (seat_maybe_in == NULL) // not in any seat { cpPointQueryInfo query_info = {0}; - cpShape *result = cpSpacePointQueryNearest(gs->space, v2_to_cp(world_hand_pos), 0.1, cpShapeFilterNew(CP_NO_GROUP, CP_ALL_CATEGORIES, BOXES), &query_info); + cpShape *result = cpSpacePointQueryNearest(gs->space, (world_hand_pos), 0.1, cpShapeFilterNew(CP_NO_GROUP, CP_ALL_CATEGORIES, BOXES), &query_info); if (result != NULL) { Entity *potential_seat = cp_shape_entity(result); @@ -2290,9 +2281,9 @@ void process(GameState *gs, double dt) // no cheating by making movement bigger than length 1 V2 movement_this_tick = (V2){0}; double rotation_this_tick = 0.0; - if (V2length(player->input.movement) > 0.0) + if (cpvlength(player->input.movement) > 0.0) { - movement_this_tick = V2scale(V2normalize(player->input.movement), clamp(V2length(player->input.movement), 0.0, 1.0)); + movement_this_tick = cpvmult(cpvnormalize(player->input.movement), clamp(cpvlength(player->input.movement), 0.0, 1.0)); player->input.movement = (V2){0}; } if (fabs(player->input.rotation) > 0.0) @@ -2318,17 +2309,17 @@ void process(GameState *gs, double dt) if (seat_inside_of == NULL) { cpShapeSetFilter(p->shape, PLAYER_SHAPE_FILTER); - cpBodyApplyForceAtWorldPoint(p->body, v2_to_cp(V2scale(movement_this_tick, PLAYER_JETPACK_FORCE)), cpBodyGetPosition(p->body)); + cpBodyApplyForceAtWorldPoint(p->body, (cpvmult(movement_this_tick, PLAYER_JETPACK_FORCE)), cpBodyGetPosition(p->body)); cpBodySetTorque(p->body, rotation_this_tick * PLAYER_JETPACK_TORQUE); - p->damage += V2length(movement_this_tick) * dt * PLAYER_JETPACK_SPICE_PER_SECOND; + p->damage += cpvlength(movement_this_tick) * dt * PLAYER_JETPACK_SPICE_PER_SECOND; p->damage += fabs(rotation_this_tick) * dt * PLAYER_JETPACK_ROTATION_ENERGY_PER_SECOND; } else { assert(seat_inside_of->is_box); cpShapeSetFilter(p->shape, CP_SHAPE_FILTER_NONE); // no collisions while in a seat - cpBodySetPosition(p->body, v2_to_cp(entity_pos(seat_inside_of))); - cpBodySetVelocity(p->body, v2_to_cp(box_vel(seat_inside_of))); + cpBodySetPosition(p->body, (entity_pos(seat_inside_of))); + cpBodySetVelocity(p->body, (box_vel(seat_inside_of))); // share cloaking with box p->time_was_last_cloaked = seat_inside_of->time_was_last_cloaked; @@ -2340,16 +2331,16 @@ void process(GameState *gs, double dt) Entity *g = get_entity(gs, seat_inside_of->shape_parent_entity); V2 target_direction = {0}; - if (V2length(movement_this_tick) > 0.0) + if (cpvlength(movement_this_tick) > 0.0) { - target_direction = V2normalize(movement_this_tick); + target_direction = cpvnormalize(movement_this_tick); } BOXES_ITER(gs, cur, g) { if (cur->box_type == BoxThruster) { - double wanted_thrust = -V2dot(target_direction, box_facing_vector(cur)); + double wanted_thrust = -cpvdot(target_direction, box_facing_vector(cur)); wanted_thrust = clamp01(wanted_thrust); cur->wanted_thrust = wanted_thrust; } @@ -2372,7 +2363,7 @@ void process(GameState *gs, double dt) // @Robust sanitize this input so player can't build on any grid in the world Entity *target_grid = grid_to_build_on(gs, world_hand_pos); - cpShape *maybe_box_to_destroy = cpSpacePointQueryNearest(gs->space, v2_to_cp(world_build), 0.01, cpShapeFilterNew(CP_NO_GROUP, CP_ALL_CATEGORIES, BOXES), &info); + cpShape *maybe_box_to_destroy = cpSpacePointQueryNearest(gs->space, (world_build), 0.01, cpShapeFilterNew(CP_NO_GROUP, CP_ALL_CATEGORIES, BOXES), &info); if (maybe_box_to_destroy != NULL) { Entity *cur_box = cp_shape_entity(maybe_box_to_destroy); @@ -2395,7 +2386,7 @@ void process(GameState *gs, double dt) Entity *new_grid = new_entity(gs); grid_create(gs, new_grid); entity_set_pos(new_grid, world_build); - cpBodySetVelocity(new_grid->body, v2_to_cp(player_vel(gs, p))); + cpBodySetVelocity(new_grid->body, (player_vel(gs, p))); target_grid = new_grid; created_box_position = (V2){0}; } @@ -2435,7 +2426,7 @@ void process(GameState *gs, double dt) // instant death { - cpFloat dist_from_center = cpvlengthsq(v2_to_cp(entity_pos(e))); + cpFloat dist_from_center = cpvlengthsq((entity_pos(e))); if (e->body != NULL && dist_from_center > (INSTANT_DEATH_DISTANCE_FROM_CENTER * INSTANT_DEATH_DISTANCE_FROM_CENTER)) { bool platonic_found = false; @@ -2469,11 +2460,11 @@ void process(GameState *gs, double dt) { SUNS_ITER(gs) { - cpVect pos_rel_sun = v2_to_cp(V2sub(entity_pos(e), (entity_pos(i.sun)))); + cpVect pos_rel_sun = (cpvsub(entity_pos(e), (entity_pos(i.sun)))); cpFloat sqdist = cpvlengthsq(pos_rel_sun); if (!e->is_grid) // grids aren't damaged (this edge case sucks!) { - sqdist = cpvlengthsq(cpvsub(v2_to_cp(entity_pos(e)), v2_to_cp(entity_pos(i.sun)))); + sqdist = cpvlengthsq(cpvsub((entity_pos(e)), (entity_pos(i.sun)))); if (sqdist < (i.sun->sun_radius * i.sun->sun_radius)) { e->damage += 10.0 * dt; @@ -2484,8 +2475,8 @@ void process(GameState *gs, double dt) { V2 accel = sun_gravity_accel_for_entity(e, i.sun); V2 new_vel = entity_vel(gs, e); - new_vel = V2add(new_vel, V2scale(accel, dt)); - cpBodySetVelocity(e->body, v2_to_cp(new_vel)); + new_vel = cpvadd(new_vel, cpvmult(accel, dt)); + cpBodySetVelocity(e->body, (new_vel)); } } } @@ -2493,7 +2484,7 @@ void process(GameState *gs, double dt) if (e->is_explosion) { e->explosion_progress += dt; - e->explosion_pos = V2add(e->explosion_pos, V2scale(e->explosion_vel, dt)); + e->explosion_pos = cpvadd(e->explosion_pos, cpvmult(e->explosion_vel, dt)); do_explosion(gs, e, dt); if (e->explosion_progress >= EXPLOSION_TIME) { @@ -2506,14 +2497,14 @@ void process(GameState *gs, double dt) if (is_burning(e)) { e->time_burned_for += dt; - cpBodyApplyForceAtWorldPoint(e->body, v2_to_cp(V2rotate((V2){.x = MISSILE_BURN_FORCE, .y = 0.0}, entity_rotation(e))), v2_to_cp(entity_pos(e))); + cpBodyApplyForceAtWorldPoint(e->body, (cpvspin((V2){.x = MISSILE_BURN_FORCE, .y = 0.0}, entity_rotation(e))), (entity_pos(e))); } if (e->damage >= MISSILE_DAMAGE_THRESHOLD && e->time_burned_for >= MISSILE_ARM_TIME) { Entity *explosion = new_entity(gs); explosion->is_explosion = true; explosion->explosion_pos = entity_pos(e); - explosion->explosion_vel = cp_to_v2(cpBodyGetVelocity(e->body)); + explosion->explosion_vel = (cpBodyGetVelocity(e->body)); explosion->explosion_push_strength = MISSILE_EXPLOSION_PUSH; explosion->explosion_radius = MISSILE_EXPLOSION_RADIUS; entity_destroy(gs, e); @@ -2557,29 +2548,29 @@ void process(GameState *gs, double dt) Entity *other_grid = box_grid(other_merge); // the merges are near eachother, but are they facing eachother... - bool from_facing_other = V2dot(box_facing_vector(from_merge), V2normalize(V2sub(entity_pos(other_merge), entity_pos(from_merge)))) > 0.8; - bool other_facing_from = V2dot(box_facing_vector(other_merge), V2normalize(V2sub(entity_pos(from_merge), entity_pos(other_merge)))) > 0.8; + bool from_facing_other = cpvdot(box_facing_vector(from_merge), cpvnormalize(cpvsub(entity_pos(other_merge), entity_pos(from_merge)))) > 0.8; + bool other_facing_from = cpvdot(box_facing_vector(other_merge), cpvnormalize(cpvsub(entity_pos(from_merge), entity_pos(other_merge)))) > 0.8; // using this stuff to detect if when the other grid's boxes are snapped, they'll be snapped // to be next to the from merge box V2 actual_new_pos = grid_snapped_box_pos(from_grid, entity_pos(other_merge)); - V2 needed_new_pos = V2add(entity_pos(from_merge), V2scale(box_facing_vector(from_merge), BOX_SIZE)); - if (from_facing_other && other_facing_from && V2equal(needed_new_pos, actual_new_pos, 0.01)) + V2 needed_new_pos = cpvadd(entity_pos(from_merge), cpvmult(box_facing_vector(from_merge), BOX_SIZE)); + if (from_facing_other && other_facing_from && cpvnear(needed_new_pos, actual_new_pos, 0.01)) { // do the merge - V2 facing_vector_needed = V2scale(box_facing_vector(from_merge), -1.0); + V2 facing_vector_needed = cpvmult(box_facing_vector(from_merge), -1.0); V2 current_facing_vector = box_facing_vector(other_merge); - double angle_diff = V2anglediff(current_facing_vector, facing_vector_needed); + double angle_diff = cpvanglediff(current_facing_vector, facing_vector_needed); if (angle_diff == FLT_MIN) angle_diff = 0.0; assert(!isnan(angle_diff)); cpBodySetAngle(other_grid->body, cpBodyGetAngle(other_grid->body) + angle_diff); - V2 moved_because_angle_change = V2sub(needed_new_pos, entity_pos(other_merge)); - cpBodySetPosition(other_grid->body, v2_to_cp(V2add(entity_pos(other_grid), moved_because_angle_change))); + V2 moved_because_angle_change = cpvsub(needed_new_pos, entity_pos(other_merge)); + cpBodySetPosition(other_grid->body, (cpvadd(entity_pos(other_grid), moved_because_angle_change))); - // V2 snap_movement_vect = V2sub(actual_new_pos, entity_pos(other_merge)); + // V2 snap_movement_vect = cpvsub(actual_new_pos, entity_pos(other_merge)); V2 snap_movement_vect = (V2){0}; Entity *cur = get_entity(gs, other_grid->boxes); @@ -2591,7 +2582,7 @@ void process(GameState *gs, double dt) V2 world = entity_pos(cur); enum CompassRotation new_rotation = facing_vector_to_compass(from_grid, other_grid, box_facing_vector(cur)); cur->compass_rotation = new_rotation; - V2 new_cur_pos = grid_snapped_box_pos(from_grid, V2add(snap_movement_vect, world)); + V2 new_cur_pos = grid_snapped_box_pos(from_grid, cpvadd(snap_movement_vect, world)); box_create(gs, cur, from_grid, grid_world_to_local(from_grid, new_cur_pos)); // destroys next/prev fields on cur assert(box_grid(cur) == box_grid(from_merge)); cur = next; @@ -2617,10 +2608,10 @@ void process(GameState *gs, double dt) cur_box->sun_amount = 0.0; SUNS_ITER(gs) { - double new_sun = clamp01(fabs(V2dot(box_facing_vector(cur_box), V2normalize(V2sub(entity_pos(i.sun), entity_pos(cur_box)))))); + double new_sun = clamp01(fabs(cpvdot(box_facing_vector(cur_box), cpvnormalize(cpvsub(entity_pos(i.sun), entity_pos(cur_box)))))); // less sun the farther away you are! - new_sun *= lerp(1.0, 0.0, clamp01(V2length(V2sub(entity_pos(cur_box), entity_pos(i.sun))) / sun_dist_no_gravity(i.sun))); + new_sun *= lerp(1.0, 0.0, clamp01(cpvlength(cpvsub(entity_pos(cur_box), entity_pos(i.sun))) / sun_dist_no_gravity(i.sun))); cur_box->sun_amount += new_sun; } energy_to_add += cur_box->sun_amount * SOLAR_ENERGY_PER_SECOND * dt; @@ -2657,7 +2648,7 @@ void process(GameState *gs, double dt) double energy_unconsumed = batteries_use_energy(gs, grid, &non_battery_energy_left_over, energy_to_consume); cur_box->thrust = (1.0 - energy_unconsumed / energy_to_consume) * cur_box->wanted_thrust; if (cur_box->thrust >= 0.0) - cpBodyApplyForceAtWorldPoint(grid->body, v2_to_cp(thruster_force(cur_box)), v2_to_cp(entity_pos(cur_box))); + cpBodyApplyForceAtWorldPoint(grid->body, (thruster_force(cur_box)), (entity_pos(cur_box))); } } if (cur_box->box_type == BoxGyroscope) @@ -2696,7 +2687,7 @@ void process(GameState *gs, double dt) { cur_box->cloaking_power = lerp(cur_box->cloaking_power, 1.0, dt * 3.0); cpBody *tmp = cpBodyNew(0.0, 0.0); - cpBodySetPosition(tmp, v2_to_cp(entity_pos(cur_box))); + cpBodySetPosition(tmp, (entity_pos(cur_box))); cpBodySetAngle(tmp, 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 @@ -2724,9 +2715,9 @@ void process(GameState *gs, double dt) create_missile(gs, new_missile); new_missile->owning_squad = cur_box->owning_squad; // missiles have teams and attack eachother! double missile_spawn_dist = sqrt((BOX_SIZE / 2.0) * (BOX_SIZE / 2.0) * 2.0) + MISSILE_COLLIDER_SIZE.x / 2.0 + 0.1; - cpBodySetPosition(new_missile->body, v2_to_cp(V2add(entity_pos(cur_box), V2rotate((V2){.x = missile_spawn_dist, 0.0}, target.facing_angle)))); + cpBodySetPosition(new_missile->body, (cpvadd(entity_pos(cur_box), cpvspin((V2){.x = missile_spawn_dist, 0.0}, target.facing_angle)))); cpBodySetAngle(new_missile->body, target.facing_angle); - cpBodySetVelocity(new_missile->body, v2_to_cp(box_vel(cur_box))); + cpBodySetVelocity(new_missile->body, (box_vel(cur_box))); } } if (cur_box->box_type == BoxScanner) @@ -2748,9 +2739,9 @@ void process(GameState *gs, double dt) for (int i = 0; i < MAX_BOX_TYPES; i++) { V2 cur_pos = gs->platonic_positions[i]; - if (V2length(cur_pos) > 0.0) // zero is uninitialized, the platonic solid doesn't exist (probably) @Robust do better + if (cpvlength(cur_pos) > 0.0) // zero is uninitialized, the platonic solid doesn't exist (probably) @Robust do better { - double length_to_cur = V2dist(from_pos, cur_pos); + double length_to_cur = cpvdist(from_pos, cur_pos); if (length_to_cur < nearest_dist) { nearest_dist = length_to_cur; @@ -2760,7 +2751,7 @@ void process(GameState *gs, double dt) } if (nearest_dist < INFINITY) { - cur_box->platonic_nearest_direction = V2normalize(V2sub(nearest, from_pos)); + cur_box->platonic_nearest_direction = cpvnormalize(cpvsub(nearest, from_pos)); cur_box->platonic_detection_strength = fmax(0.1, 1.0 - fmin(1.0, nearest_dist / 100.0)); } else diff --git a/main.c b/main.c index 6442107..347c247 100644 --- a/main.c +++ b/main.c @@ -709,7 +709,7 @@ static void draw_color_rect_centered(V2 center, double size) static void draw_texture_rectangle_centered(V2 center, V2 width_height) { - V2 halfsize = V2scale(width_height, 0.5); + V2 halfsize = cpvmult(width_height, 0.5); draw_textured_rect(center.x - halfsize.x, center.y - halfsize.y, width_height.x, width_height.y); } static void draw_texture_centered(V2 center, double size) @@ -739,8 +739,8 @@ static void draw_circle(V2 point, double radius) .y = sin(progress * 2.0 * PI) * radius}); lines[i].b = V2point((V2){.x = cos(next_progress * 2.0 * PI) * radius, .y = sin(next_progress * 2.0 * PI) * radius}); - lines[i].a = V2point(V2add(pointV2(lines[i].a), point)); - lines[i].b = V2point(V2add(pointV2(lines[i].b), point)); + lines[i].a = V2point(cpvadd(pointV2(lines[i].a), point)); + lines[i].b = V2point(cpvadd(pointV2(lines[i].b), point)); } sgp_draw_lines(lines, POINTS); } @@ -768,20 +768,20 @@ static void setup_hueshift(enum Squad squad) static V2 screen_to_world(double width, double height, V2 screen) { V2 world = screen; - world = V2sub(world, (V2){.x = width / 2.0, .y = height / 2.0}); + world = cpvsub(world, (V2){.x = width / 2.0, .y = height / 2.0}); world.x /= zoom; world.y /= -zoom; - world = V2add(world, camera_pos); + world = cpvadd(world, camera_pos); return world; } static V2 world_to_screen(double width, double height, V2 world) { V2 screen = world; - screen = V2sub(screen, camera_pos); + screen = cpvsub(screen, camera_pos); screen.x *= zoom; screen.y *= -zoom; - screen = V2add(screen, (V2){.x = width / 2.0, .y = height / 2.0}); + screen = cpvadd(screen, (V2){.x = width / 2.0, .y = height / 2.0}); return screen; } @@ -918,9 +918,9 @@ static void ui(bool draw, double dt, double width, double height) double buttons_y = invite_y + size / 2.0; bool yes_hovered = - invited && V2dist(mouse_pos, (V2){yes_x, buttons_y}) < yes_size / 2.0; + invited && cpvdist(mouse_pos, (V2){yes_x, buttons_y}) < yes_size / 2.0; bool no_hovered = - invited && V2dist(mouse_pos, (V2){no_x, buttons_y}) < no_size / 2.0; + invited && cpvdist(mouse_pos, (V2){no_x, buttons_y}) < no_size / 2.0; yes_size = lerp(yes_size, yes_hovered ? 75.0 : 50.0, dt * 9.0); no_size = lerp(no_size, no_hovered ? 75.0 : 50.0, dt * 9.0); @@ -991,14 +991,14 @@ static void ui(bool draw, double dt, double width, double height) { V2 top_of_head = world_to_screen( width, height, - V2add(entity_pos(inviting), + cpvadd(entity_pos(inviting), (V2){.y = player_scaling * PLAYER_SIZE.y / 2.0})); - V2 pos = V2add(top_of_head, (V2){.y = -30.0}); - V2 to_mouse = V2sub(mouse_pos, + V2 pos = cpvadd(top_of_head, (V2){.y = -30.0}); + V2 to_mouse = cpvsub(mouse_pos, world_to_screen(width, height, entity_pos(inviting))); bool selecting_to_invite = - V2dot(V2normalize(to_mouse), (V2){0.0, -1.0}) > 0.5 && - V2length(to_mouse) > 15.0; + cpvdot(cpvnormalize(to_mouse), (V2){0.0, -1.0}) > 0.5 && + cpvlength(to_mouse) > 15.0; if (!mousedown[SAPP_MOUSEBUTTON_RIGHT]) { if (selecting_to_invite) @@ -1061,7 +1061,7 @@ static void ui(bool draw, double dt, double width, double height) target_pos.y = 200.0; target_rot = lerp(-PI / 3.0, PI / 3.0, flag_progress) + PI / 2.0; } - flag_pos[i] = V2lerp(flag_pos[i], target_pos, dt * 5.0); + flag_pos[i] = cpvlerp(flag_pos[i], target_pos, dt * 5.0); flag_rot[i] = lerp_angle(flag_rot[i], target_rot, dt * 5.0); } @@ -1108,7 +1108,7 @@ static void ui(bool draw, double dt, double width, double height) double size = 128.0; bool hovering = - V2dist(mouse_pos, flag_pos[i]) < size * 0.25 && this_squad_available; + cpvdist(mouse_pos, flag_pos[i]) < size * 0.25 && this_squad_available; if (!choosing_flags && hovering && build_pressed) { @@ -1354,7 +1354,7 @@ static void draw_dots(V2 camera_pos, double gap) V2 star = (V2){(float)x * gap, (float)y * gap}; star.x += hash11(star.x * 100.0 + star.y * 67.0) * gap; star.y += hash11(star.y * 93.0 + star.x * 53.0) * gap; - if (V2lengthsqr(V2sub(star, camera_pos)) > VISION_RADIUS * VISION_RADIUS) + if (cpvlengthsq(cpvsub(star, camera_pos)) > VISION_RADIUS * VISION_RADIUS) continue; sgp_draw_point((float)star.x, (float)star.y); @@ -1367,8 +1367,8 @@ static V2 get_global_hand_pos(V2 world_mouse_pos, bool *hand_at_arms_length) if (myentity() == NULL) return (V2){0}; - V2 global_hand_pos = V2sub(world_mouse_pos, entity_pos(myentity())); - double hand_len = V2length(global_hand_pos); + V2 global_hand_pos = cpvsub(world_mouse_pos, entity_pos(myentity())); + double hand_len = cpvlength(global_hand_pos); if (hand_len > MAX_HAND_REACH) { *hand_at_arms_length = true; @@ -1378,8 +1378,8 @@ static V2 get_global_hand_pos(V2 world_mouse_pos, bool *hand_at_arms_length) { *hand_at_arms_length = false; } - global_hand_pos = V2scale(V2normalize(global_hand_pos), hand_len); - global_hand_pos = V2add(global_hand_pos, entity_pos(myentity())); + global_hand_pos = cpvmult(cpvnormalize(global_hand_pos), hand_len); + global_hand_pos = cpvadd(global_hand_pos, entity_pos(myentity())); return global_hand_pos; } static void frame(void) @@ -1562,7 +1562,7 @@ static void frame(void) if (myentity() != NULL) { - local_hand_pos = V2sub(global_hand_pos, entity_pos(myentity())); + local_hand_pos = cpvsub(global_hand_pos, entity_pos(myentity())); } // process player interaction (squad invites) @@ -1570,7 +1570,7 @@ static void frame(void) ENTITIES_ITER(cur) { if (cur != myentity() && cur->is_player && - has_point(centered_at(entity_pos(cur), V2scale(PLAYER_SIZE, player_scaling)), world_mouse_pos)) + has_point(centered_at(entity_pos(cur), cpvmult(PLAYER_SIZE, player_scaling)), world_mouse_pos)) { maybe_inviting_this_player = get_id(&gs, cur); interact_pressed = false; @@ -1591,8 +1591,8 @@ static void frame(void) .x = (float)keydown[SAPP_KEYCODE_D] - (float)keydown[SAPP_KEYCODE_A], .y = (float)keydown[SAPP_KEYCODE_W] - (float)keydown[SAPP_KEYCODE_S], }; - if (V2length(input) > 0.0) - input = V2normalize(input); + if (cpvlength(input) > 0.0) + input = cpvnormalize(input); cur_input_frame.movement = input; cur_input_frame.rotation = (float)keydown[SAPP_KEYCODE_E] - (float)keydown[SAPP_KEYCODE_Q]; @@ -1745,7 +1745,7 @@ static void frame(void) #if 1 // space background transform_scope { - V2 scaled_camera_pos = V2scale( + V2 scaled_camera_pos = cpvmult( camera_pos, 0.0005); // this is how strong/weak the parallax is translate(-scaled_camera_pos.x, -scaled_camera_pos.y); set_color(WHITE); @@ -1762,7 +1762,7 @@ static void frame(void) } transform_scope { - V2 scaled_camera_pos = V2scale( + V2 scaled_camera_pos = cpvmult( camera_pos, 0.005); // this is how strong/weak the parallax is translate(-scaled_camera_pos.x, -scaled_camera_pos.y); set_color(WHITE); @@ -1782,14 +1782,14 @@ static void frame(void) #if 1 // parallaxed dots transform_scope { - V2 scaled_camera_pos = V2scale(camera_pos, 0.25); + V2 scaled_camera_pos = cpvmult(camera_pos, 0.25); translate(-scaled_camera_pos.x, -scaled_camera_pos.y); set_color(WHITE); draw_dots(scaled_camera_pos, 3.0); } transform_scope { - V2 scaled_camera_pos = V2scale(camera_pos, 0.5); + V2 scaled_camera_pos = cpvmult(camera_pos, 0.5); translate(-scaled_camera_pos.x, -scaled_camera_pos.y); set_color(WHITE); draw_dots(scaled_camera_pos, 2.0); @@ -1998,7 +1998,7 @@ static void frame(void) if (b->platonic_detection_strength > 0.0) { set_color(colhexcode(0xf2d75c)); - V2 to = V2add(entity_pos(b), V2scale(b->platonic_nearest_direction, b->platonic_detection_strength)); + V2 to = cpvadd(entity_pos(b), cpvmult(b->platonic_nearest_direction, b->platonic_detection_strength)); dbg_rect(to); dbg_rect(entity_pos(b)); draw_line(entity_pos(b).x, entity_pos(b).y, to.x, to.y); @@ -2043,7 +2043,7 @@ static void frame(void) setup_hueshift(e->owning_squad); sgp_set_image(0, image_player); draw_texture_rectangle_centered( - entity_pos(e), V2scale(PLAYER_SIZE, player_scaling)); + entity_pos(e), cpvmult(PLAYER_SIZE, player_scaling)); sgp_reset_image(0); } } diff --git a/server.c b/server.c index fe5c85a..573ba60 100644 --- a/server.c +++ b/server.c @@ -467,7 +467,7 @@ void server(void *info_raw) Entity *other_player_entity = get_entity(&gs, gs.players[other_player_index].entity); if (other_player_entity != NULL) { - double dist = V2dist(entity_pos(this_player_entity), entity_pos(other_player_entity)); + double dist = cpvdist(entity_pos(this_player_entity), entity_pos(other_player_entity)); double volume = lerp(1.0, 0.0, clamp01(dist / VOIP_DISTANCE_WHEN_CANT_HEAR)); if (volume > 0.01) { diff --git a/types.h b/types.h index 1a7877c..d667070 100644 --- a/types.h +++ b/types.h @@ -100,27 +100,25 @@ #include "ipsettings.h" // don't leak IP! #include "miniaudio.h" // @Robust BAD. using miniaudio mutex construct for server thread synchronization. AWFUL! +#include "cpVect.h" // offers vector functions and types for the structs // @Robust remove this include somehow, needed for sqrt and cos #include #include // tick is unsigned integer #include // logging on errors for functions + // defined in gamestate.c. Janky #ifndef assert #define assert(condition) __flight_assert(condition, __FILE__, __LINE__, #condition) #endif // including headers from headers bad + #ifndef CHIPMUNK_H typedef void cpSpace; typedef void cpBody; typedef void cpShape; -typedef struct cpVect -{ - double x, y; -} cpVect; - #endif #include "queue.h" @@ -492,7 +490,7 @@ typedef struct AABB double x, y, width, height; } AABB; -static AABB centered_at(V2 point, V2 size) +static inline AABB centered_at(V2 point, V2 size) { return (AABB){ .x = point.x - size.x / 2.0f, @@ -502,59 +500,19 @@ static AABB centered_at(V2 point, V2 size) }; } -static bool has_point(AABB aabb, V2 point) +static inline bool has_point(AABB aabb, V2 point) { return point.x > aabb.x && point.x < aabb.x + aabb.width && point.y > aabb.y && point.y < aabb.y + aabb.height; } -static V2 V2add(V2 a, V2 b) -{ - return (V2){ - .x = a.x + b.x, - .y = a.y + b.y, - }; -} - -static V2 V2scale(V2 a, double f) -{ - return (V2){ - .x = a.x * f, - .y = a.y * f, - }; -} - -static double V2lengthsqr(V2 v) -{ - return v.x * v.x + v.y * v.y; -} - -static double V2length(V2 v) -{ - return sqrt(V2lengthsqr(v)); -} - -static V2 V2normalize(V2 v) -{ - return V2scale(v, 1.0f / V2length(v)); -} - -static double V2dot(V2 a, V2 b) -{ - return a.x * b.x + a.y * b.y; -} - -static double V2projectvalue(V2 vec, V2 onto) -{ - double length_onto = V2length(onto); - return V2dot(vec, onto) / (length_onto * length_onto); -} - -static V2 V2project(V2 vec, V2 onto) +static inline double cpvprojectval(V2 vec, V2 onto) { - return V2scale(onto, V2projectvalue(vec, onto)); + double length_onto = cpvlength(onto); + return cpvdot(vec, onto) / (length_onto * length_onto); } -static V2 V2rotate(V2 vec, double theta) +// spins around by theta +static inline V2 cpvspin(V2 vec, double theta) { return (V2){ .x = vec.x * cos(theta) - vec.y * sin(theta), @@ -563,19 +521,11 @@ static V2 V2rotate(V2 vec, double theta) } // also known as atan2 -static double V2angle(V2 vec) +static inline double cpvangle(V2 vec) { return atan2(vec.y, vec.x); } -static V2 V2sub(V2 a, V2 b) -{ - return (V2){ - .x = a.x - b.x, - .y = a.y - b.y, - }; -} - static double sign(double f) { if (f >= 0.0f) @@ -584,26 +534,11 @@ static double sign(double f) return -1.0f; } -static bool V2equal(V2 a, V2 b, double eps) -{ - return V2length(V2sub(a, b)) < eps; -} - static inline double clamp01(double f) { return fmax(0.0f, fmin(f, 1.0f)); } -static double V2distsqr(V2 from, V2 to) -{ - return V2lengthsqr(V2sub(to, from)); -} - -static double V2dist(V2 from, V2 to) -{ - return sqrt(V2distsqr(from, to)); -} - static inline double clamp(double f, double minimum, double maximum) { if (f < minimum) @@ -613,92 +548,51 @@ static inline double clamp(double f, double minimum, double maximum) return f; } -static double V2anglediff(V2 a, V2 b) +static inline double cpvanglediff(V2 a, V2 b) { - double acos_input = V2dot(a, b) / (V2length(a) * V2length(b)); + double acos_input = cpvdot(a, b) / (cpvlength(a) * cpvlength(b)); acos_input = clamp(acos_input, -1.0f, 1.0f); assert(acos_input >= -1.0f && acos_input <= 1.0f); - return acos(acos_input) * sign(V2dot(a, b)); + return acos(acos_input) * sign(cpvdot(a, b)); } -static double fract(double f) +static inline double fract(double f) { return f - floor(f); } -static double lerp(double a, double b, double f) +static inline double lerp(double a, double b, double f) { return a * (1.0f - f) + (b * f); } -static double lerp_angle(double p_from, double p_to, double p_weight) +static inline double lerp_angle(double p_from, double p_to, double p_weight) { double difference = fmod(p_to - p_from, (float)TAU); double distance = fmod(2.0f * difference, (float)TAU) - difference; return p_from + distance * p_weight; } -static V2 V2floor(V2 p) +static inline V2 cpvfloor(V2 p) { return (V2){floor(p.x), floor(p.y)}; } -static V2 V2fract(V2 p) +static inline V2 cpvfract(V2 p) { return (V2){fract(p.x), fract(p.y)}; } -/* -double noise(V2 p) -{ - V2 id = V2floor(p); - V2 f = V2fract(p); - - V2 u = V2dot(f, f) * (3.0f - 2.0f * f); - - return mix(mix(random(id + V2(0.0, 0.0)), - random(id + V2(1.0, 0.0)), u.x), - mix(random(id + V2(0.0, 1.0)), - random(id + V2(1.0, 1.0)), u.x), - u.y); -} - -double fbm(V2 p) -{ - double f = 0.0; - double gat = 0.0; - - for (double octave = 0.; octave < 5.; ++octave) - { - double la = pow(2.0, octave); - double ga = pow(0.5, octave + 1.); - f += ga * noise(la * p); - gat += ga; - } - - f = f / gat; - - return f; -} -*/ - -static V2 V2lerp(V2 a, V2 b, double factor) -{ - V2 to_return = {0}; - to_return.x = lerp(a.x, b.x, factor); - to_return.y = lerp(a.y, b.y, factor); - - return to_return; -} // for random generation -static double hash11(double p) +static inline double hash11(double p) { p = fract(p * .1031f); p *= p + 33.33f; p *= p + p; return fract(p); } -static double deg2rad(double deg) + +static inline double deg2rad(double deg) { return (deg / 360.0f) * 2.0f * PI; }