Skip to content

Commit 4188bcf

Browse files
committed
add some grid functionality and refactor
1 parent 3eefa4e commit 4188bcf

File tree

8 files changed

+570
-477
lines changed

8 files changed

+570
-477
lines changed

build.sh

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,4 +2,7 @@
22

33
set -xe
44

5-
gcc -o main main.c -I/usr/include/SDL2 -lSDL2 -lSDL2_ttf -lm -Wall -Wextra -g
5+
gcc \
6+
-o main \
7+
main.c grid.c common.c particle.c \
8+
-I/usr/include/SDL2 -lSDL2 -lSDL2_ttf -lm -Wall -Wextra -g -O3

common.c

Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
#include "common.h"
2+
3+
4+
int sdl_setup(SDL_Window **w, SDL_Renderer **r, TTF_Font **f)
5+
{
6+
if (SDL_Init(SDL_INIT_EVERYTHING) != 0)
7+
{
8+
fprintf(stderr, "SDL_Init failed: %s\n", SDL_GetError());
9+
return 1;
10+
}
11+
12+
*w = SDL_CreateWindow("SDL2 test",
13+
SDL_WINDOWPOS_CENTERED,
14+
SDL_WINDOWPOS_CENTERED,
15+
SCREEN_W, SCREEN_H,
16+
SDL_WINDOW_RESIZABLE);
17+
18+
if (!*w)
19+
{
20+
fprintf(stderr, "SDL_CreateWindow failed: %s\n", SDL_GetError());
21+
return 1;
22+
}
23+
24+
if (TTF_Init() != 0) {
25+
fprintf(stderr, "TTF_Init failed: %s\n", TTF_GetError());
26+
SDL_Quit();
27+
return 1;
28+
}
29+
30+
*r = SDL_CreateRenderer(*w, -1, SDL_RENDERER_ACCELERATED);
31+
if (!*r)
32+
{
33+
fprintf(stderr, "SDL_CreateRenderer failed: %s\n", SDL_GetError());
34+
return 1;
35+
}
36+
37+
*f = TTF_OpenFont("/usr/share/fonts/truetype/noto/NotoSansMono-Regular.ttf", 24);
38+
if (!*f) {
39+
fprintf(stderr, "TTF_OpenFont failed: %s\n", TTF_GetError());
40+
SDL_DestroyRenderer(*r);
41+
SDL_DestroyWindow(*w);
42+
TTF_Quit();
43+
SDL_Quit();
44+
return 1;
45+
}
46+
return 0;
47+
}
48+
49+
void sdl_cleanup(SDL_Window **w, SDL_Renderer **r, TTF_Font **f)
50+
{
51+
TTF_CloseFont(*f);
52+
SDL_DestroyRenderer(*r);
53+
SDL_DestroyWindow(*w);
54+
TTF_Quit();
55+
SDL_Quit();
56+
}
57+
58+
void draw_stats(SDL_Renderer *r, float dt, int particle_count, TTF_Font *font) {
59+
SDL_Color white = {255, 255, 255, 255};
60+
char stats_text[64];
61+
float fps = 1.0f / dt;
62+
snprintf(stats_text, sizeof(stats_text), "Particles: %d, FPS: %.2f", particle_count, fps);
63+
64+
SDL_Surface* text_surface = TTF_RenderText_Solid(font, stats_text, white);
65+
SDL_Texture* text_texture = SDL_CreateTextureFromSurface(r, text_surface);
66+
SDL_Rect text_rect = {10, 10, text_surface->w, text_surface->h};
67+
SDL_RenderCopy(r, text_texture, NULL, &text_rect);
68+
SDL_FreeSurface(text_surface);
69+
SDL_DestroyTexture(text_texture);
70+
}
71+
72+
uint f_randi(uint index) {
73+
index = (index << 13) ^ index;
74+
return ((index * (index * index * 15731 + 789221) + 1376312589) & 0x7fffffff);
75+
}

common.h

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
#ifndef _COMMON_
2+
#define _COMMON_
3+
#include <SDL2/SDL.h>
4+
#include <SDL2/SDL_ttf.h>
5+
6+
#define SCREEN_W 800
7+
#define SCREEN_H 600
8+
9+
#define MIN_RADIUS 8
10+
#define MAX_RADIUS 8
11+
12+
typedef struct Vec2 {
13+
float x, y;
14+
} Vec2;
15+
16+
int sdl_setup(SDL_Window **w, SDL_Renderer **r, TTF_Font **f);
17+
void sdl_cleanup(SDL_Window **w, SDL_Renderer **r, TTF_Font **f);
18+
void draw_stats(SDL_Renderer *r, float dt, int particle_count, TTF_Font *font);
19+
uint f_randi(uint index);
20+
21+
#endif //_COMMON_

grid.c

Lines changed: 152 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,152 @@
1+
#include "grid.h"
2+
#include "particle.h"
3+
4+
Grid* grid_init()
5+
{
6+
Grid *g = (Grid*)malloc(sizeof(Grid));
7+
grid_get_tile_len(g, SCREEN_W, SCREEN_H, MAX_RADIUS);
8+
g->cols = (SCREEN_W / g->tile_len);
9+
g->rows = (SCREEN_H / g->tile_len);
10+
g->tiles = (Tile*)malloc(sizeof(Tile) * (g->rows * g->cols));
11+
for (int i = 0; i < g->rows; i++)
12+
{
13+
for (int j = 0; j < g->cols; j++)
14+
{
15+
int id = i * g->cols + j;
16+
17+
g->tiles->id = id;
18+
g->tiles[id].pos.x = j * g->tile_len;
19+
g->tiles[id].pos.y = i * g->tile_len;
20+
printf("id: %d, x: %d, y: %d\n", id, j*g->tile_len, i*g->tile_len);
21+
}
22+
}
23+
printf("rows: %d, cols: %d\n", g->rows, g->cols);
24+
return g;
25+
}
26+
27+
void grid_get_tile_len(Grid *g, int w, int h, int max_radius)
28+
{
29+
int size = max_radius;
30+
while ((w % size != 0 || h % size != 0) && (size < w && size < h))
31+
{
32+
size++;
33+
}
34+
g->tile_len = size;
35+
}
36+
37+
Tile* grid_get_tile_by_pos(Grid *g, int x, int y)
38+
{
39+
40+
int id = (g->cols - 1) * y + x;
41+
if (id == g->tiles->id)
42+
{
43+
return &g->tiles[id];
44+
}
45+
return NULL;
46+
}
47+
48+
void grid_free(Grid *g)
49+
{
50+
free(g->tiles);
51+
g->tiles = NULL;
52+
free(g);
53+
}
54+
55+
void grid_debug_draw(SDL_Renderer *r, Grid *g)
56+
{
57+
if (g == NULL) return;
58+
59+
SDL_SetRenderDrawColor(r, 255, 255, 255, 0);
60+
int x = g->tile_len;
61+
int y = g->tile_len;
62+
while (x < SCREEN_W)
63+
{
64+
SDL_RenderDrawLine(r, x, 0, x, SCREEN_H);
65+
x += g->tile_len;
66+
}
67+
while (y < SCREEN_H)
68+
{
69+
SDL_RenderDrawLine(r, 0, y, SCREEN_W, y);
70+
y += g->tile_len;
71+
}
72+
}
73+
74+
void tiles_check_collisions(Tile *t1, Tile *t2)
75+
{
76+
Particles p;
77+
particles_init(&p, 8);
78+
79+
for (size_t i = 0; i < t1->p->used; i++)
80+
{
81+
particles_add(&p, t1->p->array[i]);
82+
}
83+
84+
for (size_t i = 0; i < t2->p->used; i++)
85+
{
86+
particles_add(&p, t2->p->array[i]);
87+
}
88+
89+
particles_solve_collisions(&p);
90+
particles_free(&p);
91+
}
92+
93+
void grid_populate_tiles_with_particles(Grid *g, Particles *p)
94+
{
95+
for (size_t i = 0; i < p->used; i++)
96+
{
97+
Particle *check = &p->array[i];
98+
int x = check->current.x / (g->cols * g->tile_len);
99+
int y = check->current.y / (g->rows * g->tile_len);
100+
101+
Tile *t = grid_get_tile_by_pos(g, x, y);
102+
103+
if (!t->p->array)
104+
{
105+
particles_init(t->p, 4);
106+
}
107+
particles_add(t->p, *check);
108+
}
109+
}
110+
111+
/*
112+
-int grid_get_id_by_pos(Grid *g, int x, int y)
113+
-{
114+
- if (x < 0 || x >= SCREEN_W || y < 0 || y >= SCREEN_H) {
115+
- return -1;
116+
- }
117+
-
118+
- int colid = (int)(x / g->tile_len);
119+
- int rowid = (int)(y / g->tile_len);
120+
- int id = rowid * g->cols + colid;
121+
- printf("id: %d, x: %d, y: %d\n", id, x, y);
122+
- return id;
123+
-}
124+
*/
125+
126+
void grid_find_collisions(Grid *g)
127+
{
128+
for (int x = 0; x < g->cols; x++)
129+
{
130+
for (int y = 0; y < g->rows; x++)
131+
{
132+
Tile *t = grid_get_tile_by_pos(g, x, y);
133+
134+
int dx_min, dx_max = -1;
135+
int dy_min, dy_max = 1;
136+
137+
if (x == 0) dx_min = 0;
138+
if ((int)x == g->cols-1) dx_max = 0;
139+
140+
if (y == 0) dy_min = 0;
141+
if ((int)y == g->rows-1) dy_max = 0;
142+
143+
for (int dx = dx_min; dx <= dx_max; dx++)
144+
{
145+
for (int dy = dy_min; dy <= dy_max; dy++)
146+
{
147+
Tile *t2 = grid_get_tile_by_pos(g, x + dx, y + dy);
148+
}
149+
}
150+
}
151+
}
152+
}

grid.h

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
#ifndef _GRID_
2+
#define _GRID_
3+
4+
#include <stdint.h>
5+
#include "common.h"
6+
#include "particle.h"
7+
8+
typedef struct tile {
9+
int id;
10+
Vec2 pos;
11+
Particles *p;
12+
} Tile;
13+
14+
typedef struct {
15+
Tile *tiles;
16+
int tile_len;
17+
int rows, cols;
18+
} Grid;
19+
20+
Grid* grid_init();
21+
void grid_get_tile_len(Grid *g, int w, int h, int max_radius);
22+
Tile* grid_get_tile_by_pos(Grid *g, int x, int y);
23+
void tiles_check_collisions(Tile *t1, Tile *t2);
24+
void grid_find_collisions(Grid *g);
25+
void grid_debug_draw(SDL_Renderer *r, Grid *g);
26+
void grid_free(Grid *g);
27+
28+
#endif //_GRID_

0 commit comments

Comments
 (0)