summaryrefslogtreecommitdiff
path: root/examples/particles.c
blob: 37a77a5ed9e164b2f53146f5f9024a0835b1e8ad (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
#include "../graphics.c"

typedef struct {
  f64 x;
  f64 y;
  f64 vx;
  f64 vy;
} Entity;

typedef struct {
  i64    time;
  i64    num_entities;
  Entity entities[10 * 1024 * 1024];
} World;

World    world      = {0};
vec3_f32 background = { .0f, .0f, .08f };
i64      time_0;

void update_and_render_frame(void) {
  p_handle_events();

  i64 time_elapsed  = p_time() - time_0;
  time_0           += time_elapsed;

  if (g_platform.key_pressed[BUTTON_LEFT]) {
    i64 n = world.num_entities++;

    world.entities[n] = (Entity) {
      .x =   (f64) g_platform.cursor_x - (f64) g_platform.frame_width  / 2,
      .y = -((f64) g_platform.cursor_y - (f64) g_platform.frame_height / 2),
    };
  }

  if (time_elapsed > 0) {
    if (g_platform.key_down[BUTTON_RIGHT]) {
      for (i64 n = 0; n < time_elapsed; ++n)
        world.entities[world.num_entities + n] = (Entity) {
          .x =   (f64) g_platform.cursor_x - (f64) g_platform.frame_width  / 2,
          .y = -((f64) g_platform.cursor_y - (f64) g_platform.frame_height / 2),
        };

      world.num_entities += time_elapsed;
    }

    for (i64 n = 0; n < world.num_entities; ++n) {
      Entity *e = &world.entities[n];

      for (i64 k = 0; k < n; ++k) {
        Entity *u = &world.entities[k];

        f64 dx = e->x - u->x;
        f64 dy = e->y - u->y;
        f64 d = dx * dx + dy * dy;
        if (d < 1000.) continue;

        f64 r = sqrt(d);
        dx /= r;
        dy /= r;

        f64 a = (1. / d) * time_elapsed;

        if (d < 5000.)
          a = -a;

        e->vx -= dx * a;
        e->vy -= dy * a;
        u->vx += dx * a;
        u->vy += dy * a;
      }
    }

    for (i64 n = 0; n < world.num_entities; ++n) {
      Entity *e = &world.entities[n];

      e->x += e->vx * time_elapsed;
      e->y += e->vy * time_elapsed;

      f64 z = (M_PI * 2.0) * (rand() % 10000) * .0001;
      e->vx += .0001 * cos(z);
      e->vy += .0001 * sin(z);
    }

    world.time += time_elapsed;
  }

  for (i32 j = 0; j < g_platform.frame_height; ++j)
    for (i32 i = 0; i < g_platform.frame_width; ++i)
      g_platform.pixels[j * g_platform.frame_width + i] = background;

  for (i64 n = 0; n < world.num_entities; ++n) {
    Entity *e = &world.entities[n];

    i32 x = g_platform.frame_width  / 2 + (i32) floor(e->x + .5);
    i32 y = g_platform.frame_height / 2 - (i32) floor(e->y + .5);

    for (i32 j = y - 10; j <= y + 10; ++j) {
      if (j < 0 || j >= g_platform.frame_height) continue;
      for (i32 i = x - 10; i <= x + 10; ++i) {
        if (i < 0 || i >= g_platform.frame_width) continue;
        if ((i - x) * (i - x) + (j - y) * (j - y) > 100) continue;
        f64 v = (e->vx * e->vx + e->vy * e->vy) * 8.;
        g_platform.pixels[j * g_platform.frame_width + i] = (vec3_f32) { -.2 + v * 2., .1 + v * .7,  1. - v };
      }
    }
  }

  p_render_frame();
}

i32 main(i32 argc, c8 **argv) {
  (void) argc;
  (void) argv;

  g_platform = (Platform) {
    .title        = "Gravity",
    .frame_width  = 960,
    .frame_height = 720,
  };

  time_0 = p_time();

  srand(p_time());

  p_event_loop();

  return 0;
}