#define _POSIX_C_SOURCE 200809L #include "consts.h" #include "gravity.h" #include "mechanics.h" #include "objects.h" #include "vec_utils.h" #include #include #include #include #include #include #include #include #include int center_x_text(const char *text, int width, int size) { return (width - MeasureText(text, size)) / 2; } static inline int center_y_text(int height, int size) { return (height - size) / 2; } long long timespec_diff_ns(struct timespec end, struct timespec start) { return (end.tv_sec - start.tv_sec) * 1000000000LL + (end.tv_nsec - start.tv_nsec); } void *physics(void *args) { universe_t *uni = (universe_t *)args; struct timespec ot, ct; while (true) { clock_gettime(CLOCK_MONOTONIC, &ct); gravity(uni); mechanics(uni); ot = ct; long long elapsed = timespec_diff_ns(ct, ot); long long remaining = TIMESTEP / simx - elapsed; if (remaining > 0) { long long sleep_time = remaining * 9 / 10; struct timespec sleep_time_spec = {0, sleep_time}; thrd_sleep(&sleep_time_spec, NULL); } do { clock_gettime(CLOCK_MONOTONIC, &ct); } while (timespec_diff_ns(ct, ot) < TIMESTEP / simx); } } int main(void) { float v_scale = 1; Vector2 canvas_offset = {0, 0}; pthread_t physics_thread; const char *welcome_text = "Welcome to Fucked Physics!"; universe_t universe = {0, NULL}; universe.bodies = malloc(1024 * sizeof(mass_body_t)); universe.num_bodies = 3; universe.bodies[0] = (mass_body_t){10000000000000.0f, 1000, {-0, 0}, {0, 0}, 200}; universe.bodies[1] = (mass_body_t){100000000.0f, 0.1, {-10000.1, 0}, {0, -0.2}, 50}; universe.bodies[2] = (mass_body_t){100000000.0f, 0.1, {10000, 0}, {0, -0.2}, 50}; SetConfigFlags(FLAG_WINDOW_RESIZABLE); InitWindow(800, 450, "Fucked Physics"); SetTargetFPS(120); pthread_create(&physics_thread, NULL, physics, (void *)&universe); while (!WindowShouldClose()) { int key_pressed = 0; do { key_pressed = GetKeyPressed(); switch (key_pressed) { case KEY_I: if (v_scale >= 0.1) { v_scale += 0.1; } else { v_scale += 0.01; } break; case KEY_O: if (v_scale > 0.1) { v_scale -= 0.1; } else if (v_scale > 0.01) { v_scale -= 0.01; } break; case KEY_LEFT: canvas_offset.x += 100; break; case KEY_RIGHT: canvas_offset.x -= 100; break; case KEY_UP: canvas_offset.y += 100; break; case KEY_DOWN: canvas_offset.y -= 100; break; } } while (key_pressed != 0); if (IsMouseButtonPressed(MOUSE_LEFT_BUTTON) || IsMouseButtonDown(MOUSE_RIGHT_BUTTON)) { Vector2 mouse_pos = vec2_scale( transform_to_center(vec2_scale(GetMousePosition(), -1)), -1); mouse_pos = vec2_scale(mouse_pos, 1 / v_scale); universe.bodies[universe.num_bodies] = (mass_body_t){100000.0f, 0.1, mouse_pos, {0, 0}, 10}; universe.num_bodies++; } if (canvas_offset.x + GetRenderWidth() * 0.5 / v_scale > GetRenderWidth() * 50) { canvas_offset.x = -GetRenderWidth() * 0.5 / v_scale + GetRenderWidth() * 50; } else if (canvas_offset.x - GetRenderWidth() * 0.5 / v_scale < -GetRenderWidth() * 50) { canvas_offset.x = GetRenderWidth() * 0.5 / v_scale - GetRenderWidth() * 50; } if (canvas_offset.y + GetRenderHeight() * 0.5 / v_scale > GetRenderHeight() * 50) { canvas_offset.y = -GetRenderHeight() * 0.5 / v_scale + GetRenderHeight() * 50; } else if (canvas_offset.y - GetRenderHeight() * 0.5 / v_scale < -GetRenderHeight() * 50) { canvas_offset.y = GetRenderHeight() * 0.5 / v_scale - GetRenderHeight() * 50; } BeginDrawing(); ClearBackground(RAYWHITE); for (unsigned int i = 0; i < universe.num_bodies; i++) { Vector2 scaled_offset = vec2_scale(canvas_offset, v_scale); Vector2 body_position = vec2_scale(universe.bodies[i].position, v_scale); body_position = vec2_sum(body_position, scaled_offset); DrawCircleV(transform_to_center(body_position), universe.bodies[i].draw_radius * v_scale, (Color){((256 / universe.num_bodies) * i) % 256 / 2, 255 * (i % 2) / 2, 255 * (i % 2) * (i % 3) / 2, 255}); } DrawText(welcome_text, center_x_text(welcome_text, GetRenderWidth(), 20), center_y_text(GetRenderHeight(), 20), 20, BLACK); EndDrawing(); } CloseWindow(); return EXIT_SUCCESS; }