star-sim

Barnes-Hut gravity simulation.
git clone git://git.amin.space/star-sim.git
Log | Files | Refs | README | LICENSE

commit 1fda0881eb5d297cb202289501b27734f7151ac6
parent 0ac5616992d1fd7b57126b531072ef2c89e5dce7
Author: amin <dev@aminmesbah.com>
Date:   Sun, 30 Jul 2017 00:56:06 +0000

Move sim state related code out of platform layer.

The `SimState` struct encapsulates all the state information necessary
for updating and rendering. The platform layer just needs to declare a
`SimState` and call various functions on it. It doesn't need to know
about stars or quadtrees or any other simulated entity.

FossilOrigin-Name: 86127fbe437d62ad2ddda4bef66a97f2e909d43b847148fc33dd7fd82b4e04d3
Diffstat:
Msrc/platform_sdl.c | 24+++++++-----------------
Msrc/star_garden.c | 104++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-----------------
Msrc/star_garden.h | 16++++++++++++----
3 files changed, 101 insertions(+), 43 deletions(-)

diff --git a/src/platform_sdl.c b/src/platform_sdl.c @@ -188,20 +188,9 @@ int main(void) uint64_t lag = 0; uint64_t previous_ms = (SDL_GetPerformanceCounter() * SECOND) / SDL_GetPerformanceFrequency(); - struct Star stars[NUM_STARS]; - for (int i = 0; i < NUM_STARS; ++i) - { - stars[i].x = rand() % dimension.width; - stars[i].y = rand() % dimension.height; - stars[i].angle = ((float)rand()/(float)(RAND_MAX)) * 2 * M_PI; - stars[i].speed = 0; - stars[i].mass = 5; - stars[i].size = star_calc_size(stars[i].mass); - stars[i].color = COLOR_WHITE; - //printf("%f, %f, %f\n", stars[i].angle, stars[i].speed, stars[i].mass); - } - struct QuadTree *qt = quad_tree_init(); + struct SimState sim_state; + sim_init(&sim_state, dimension.width, dimension.height); while (running) { @@ -222,7 +211,8 @@ int main(void) dimension = sdl_get_window_dimension(window); struct OffscreenBuffer buffer; - // these pointers are now aliased + // WARNING: these pointers are aliased until the end of the + // loop buffer.memory = global_back_buffer.memory; buffer.width = global_back_buffer.width; buffer.height = global_back_buffer.height; @@ -236,7 +226,7 @@ int main(void) { while (lag >= MS_PER_UPDATE) { - update(buffer.width, buffer.height, stars, NUM_STARS, qt); + sim_update(&sim_state, buffer.width, buffer.height); //printf("\t%" PRIu64 ", %f\n", lag, MS_PER_UPDATE); lag -= MS_PER_UPDATE; } @@ -247,7 +237,7 @@ int main(void) clear_screen(&global_back_buffer, COLOR_BACKGROUND); } - render(&buffer, lag/SECOND, stars, NUM_STARS, qt); + sim_render(&buffer, lag/SECOND, &sim_state); sdl_update_window(renderer, &global_back_buffer); if (elapsed_ms <= MS_PER_FRAME) { @@ -255,7 +245,7 @@ int main(void) } } - quad_tree_free(qt); + sim_cleanup(&sim_state); } else { diff --git a/src/star_garden.c b/src/star_garden.c @@ -5,12 +5,40 @@ bool BRUTE_FORCE = false; bool RENDER_GRID = false; bool RENDER_TRAILS = false; -void update(int field_width, - int field_height, - struct Star stars[], - int num_stars, - struct QuadTree *qt) + +void sim_init(struct SimState *sim_state, int field_width, int field_height) { + if (!sim_state) + { + // TODO: handle invalid pointer error + return; + } + + sim_state->num_stars = NUM_STARS; + for (int i = 0; i < sim_state->num_stars; ++i) + { + struct Star *star = &sim_state->stars[i]; + star->x = rand() % field_width; + star->y = rand() % field_height; + star->angle = ((float)rand()/(float)(RAND_MAX)) * 2 * M_PI; + star->speed = 0; + star->mass = 5; + star->size = star_calc_size(star->mass); + star->color = COLOR_WHITE; + //printf("%f, %f, %f\n", star->angle, star->speed, star->mass); + } + sim_state->qt = quad_tree_init(); +} + + +void sim_update(struct SimState *sim_state, int field_width, int field_height) +{ + if (!sim_state) + { + // TODO: handle invalid pointer error + return; + } + // TODO: either limit the bounds of the simulation, or base these values on // the smallest bounding rectangle int center_x = field_width / 2; @@ -18,6 +46,10 @@ void update(int field_width, int dist_x = field_width / 2; int dist_y = field_height / 2; + int num_stars = sim_state->num_stars; + struct Star *stars = sim_state->stars; + struct QuadTree *qt = sim_state->qt; + if (BRUTE_FORCE) { for (int i = 0; i < num_stars; ++i) @@ -62,19 +94,23 @@ void update(int field_width, } -void render( - struct OffscreenBuffer *buffer, - float dt, - struct Star stars[], - int num_stars, - struct QuadTree *qt) +void sim_render(struct OffscreenBuffer *buffer, float dt, struct SimState *sim_state) { + if (!buffer || !sim_state) + { + // TODO: handle invalid pointer error + return; + } + + int num_stars = sim_state->num_stars; + struct Star *stars = sim_state->stars; + struct QuadTree *qt = sim_state->qt; //printf("%f\n", dt); if (BRUTE_FORCE) { for (int i = 0; i < num_stars; ++i) { - set_pixel( + sim_set_pixel( buffer, stars[i].x + (sinf(stars[i].angle) * stars[i].speed) * dt, stars[i].y - (cosf(stars[i].angle) * stars[i].speed) * dt, @@ -85,7 +121,7 @@ void render( { for (int i = 0; i < num_stars; ++i) { - set_pixel( + sim_set_pixel( buffer, stars[i].x + (sinf(stars[i].angle) * stars[i].speed) * dt, stars[i].y - (cosf(stars[i].angle) * stars[i].speed) * dt, @@ -95,13 +131,19 @@ void render( if (RENDER_GRID) { - draw_grid(buffer, qt->root, COLOR_GREEN); + sim_render_grid(buffer, qt->root, COLOR_GREEN); } } -void set_pixel(struct OffscreenBuffer *buffer, uint32_t x, uint32_t y, uint32_t color) +void sim_set_pixel(struct OffscreenBuffer *buffer, uint32_t x, uint32_t y, uint32_t color) { + if (!buffer) + { + // TODO: handle invalid pointer error + return; + } + /* Origin is (0, 0) on the upper left. * To go one pixel right, increment by 32 bits. * To go one pixel down, increment by (buffer.width * 32) bits. @@ -116,27 +158,45 @@ void set_pixel(struct OffscreenBuffer *buffer, uint32_t x, uint32_t y, uint32_t } -void draw_grid(struct OffscreenBuffer *buffer, struct QuadTreeNode *node, uint32_t color) +void sim_render_grid(struct OffscreenBuffer *buffer, struct QuadTreeNode *node, uint32_t color) { + if (!buffer) + { + // TODO: handle invalid pointer error + return; + } + if (node && node->ne && node->nw && node->sw && node->se) { for (int x = (node->cell->center_x - node->cell->distance_x); x <= (node->cell->center_x + node->cell->distance_x); ++x) { - set_pixel(buffer, x, node->cell->center_y, color); + sim_set_pixel(buffer, x, node->cell->center_y, color); } for (int y = (node->cell->center_y - node->cell->distance_y); y <= (node->cell->center_y + node->cell->distance_y); ++y) { - set_pixel(buffer, node->cell->center_x, y, color); + sim_set_pixel(buffer, node->cell->center_x, y, color); } - draw_grid(buffer, node->ne, color); - draw_grid(buffer, node->nw, color); - draw_grid(buffer, node->sw, color); - draw_grid(buffer, node->se, color); + sim_render_grid(buffer, node->ne, color); + sim_render_grid(buffer, node->nw, color); + sim_render_grid(buffer, node->sw, color); + sim_render_grid(buffer, node->se, color); } } + + +void sim_cleanup(struct SimState *sim_state) +{ + if (!sim_state) + { + // TODO: handle invalid pointer error + return; + } + + quad_tree_free(sim_state->qt); +} diff --git a/src/star_garden.h b/src/star_garden.h @@ -56,6 +56,12 @@ typedef enum color_t NUM_COLORS, } color_t; +struct SimState +{ + struct Star stars[NUM_STARS]; + struct QuadTree *qt; + int num_stars; +}; struct OffscreenBuffer { @@ -66,10 +72,12 @@ struct OffscreenBuffer unsigned int pitch; }; -void update(int buffer_width, int buffer_height, struct Star stars[], int num_stars, struct QuadTree *qt); -void render(struct OffscreenBuffer *buffer, float dt, struct Star stars[], int num_stars, struct QuadTree *qt); -void set_pixel(struct OffscreenBuffer *buffer, uint32_t x, uint32_t y, uint32_t color); -void draw_grid(struct OffscreenBuffer *buffer, struct QuadTreeNode *node, uint32_t color); +void sim_init(struct SimState *sim_state, int field_width, int field_height); +void sim_update(struct SimState *sim_state, int field_width, int field_height); +void sim_render(struct OffscreenBuffer *buffer, float dt, struct SimState *sim_state); +void sim_set_pixel(struct OffscreenBuffer *buffer, uint32_t x, uint32_t y, uint32_t color); +void sim_render_grid(struct OffscreenBuffer *buffer, struct QuadTreeNode *node, uint32_t color); +void sim_cleanup(struct SimState *sim_state); #define STAR_GARDEN_H #endif