9 static void fade_buf(SDL_Surface *screen, double amount)
12 unsigned char *buf = screen->pixels;
14 for (i = 0; i < screen->pitch * screen->h; i++)
15 buf[i] = (buf[i] < amount) ? 0 : buf[i] - amount;
18 static void clear_buf(SDL_Surface *screen)
21 unsigned int *buf = screen->pixels;
23 for (i = 0; i < screen->pitch * screen->h / 4; i++)
27 /* Return time in microseconds */
29 static unsigned long gettime(void)
33 static unsigned long start = 0;
35 clock_gettime(CLOCK_MONOTONIC, &tp);
37 ret = tp.tv_sec * 1000 * 1000;
38 ret += tp.tv_nsec / 1000;
46 static int poll_events(SDL_Surface **screen, struct camera *cam,
47 double *time_scale, double time)
49 static double time_scale_rate = 1;
52 *time_scale *= pow(time_scale_rate, time);
54 while (SDL_PollEvent(&event)) {
57 switch (event.key.keysym.sym) {
61 cam->speed.x = -CAM_SPEED;
64 cam->speed.x = CAM_SPEED;
67 cam->speed.y = -CAM_SPEED;
70 cam->speed.y = CAM_SPEED;
74 cam->zoom_rate = CAM_ZOOM_RATE;
78 cam->zoom_rate = 1 / CAM_ZOOM_RATE;
81 time_scale_rate = 1.5;
84 time_scale_rate = 1 / 1.5;
91 switch (event.key.keysym.sym) {
122 case SDL_VIDEORESIZE:
123 *screen = SDL_SetVideoMode(event.resize.w,
135 printf("\nExiting. Good bye!\n");
139 static void loop(SDL_Surface *screen, int num_of_planets, double total_mass,
142 struct planet *planet, *pl1, *pl2;
143 struct camera camera;
145 int framecount = 0, last_fps_time = 0;
146 int last_framecount = 0;
147 unsigned long long old_ticks, ticks;
148 double time = 0, last_fps = 0, time_scale = 1;
150 init_camera(&camera);
152 planet = malloc(sizeof(*planet));
154 create_planets(planet, num_of_planets, total_mass, range);
156 ticks = SDL_GetTicks();
160 list_for_each_entry(pl1, &planet->list, list) {
161 pl2 = list_to_planet(pl1->list.next);
162 list_for_each_entry_from(pl2, &planet->list, list) {
164 if (!gravitize_planets(pl1, pl2,
168 ptmp = list_to_planet(pl2->list.prev);
169 merge_planets(pl1, pl2);
173 move_planet(pl1, time * time_scale);
176 SDL_LockSurface(screen);
180 list_for_each_entry(pl1, &planet->list, list) {
181 draw_planet(screen, pl1, &camera);
185 SDL_UnlockSurface(screen);
189 move_camera(&camera, time);
191 if (poll_events(&screen, &camera, &time_scale, time))
196 time = (ticks - old_ticks) / 1000.0;
197 time = MIN(time, 0.02);
199 if (last_fps_time + 500 < ticks) {
200 last_framecount = framecount - last_framecount;
201 last_fps = last_framecount * 1000 /
202 (float)(ticks - last_fps_time);
203 last_framecount = framecount;
204 last_fps_time = ticks;
206 printf(" \rFrames/s: %.2f, Frame: %d, planets: %d"
207 ", scale %.2f, zoom %.2f",
208 last_fps, framecount++, planets, time_scale,
213 int main(int argc, char *argv[])
216 int flags = SDL_DOUBLEBUF | SDL_HWSURFACE | SDL_RESIZABLE;
217 int planets = 100, xres = 800, yres = 600;
218 double total_mass = 50000;
221 if (SDL_Init(SDL_INIT_VIDEO) != 0) {
222 fprintf(stderr, "Unable to initialize SDL: %s\n",
230 planets = atoi(argv[1]);
233 total_mass = atof(argv[2]);
236 range = atof(argv[3]);
238 screen = SDL_SetVideoMode(xres, yres, 32, flags);
239 if (screen == NULL) {
240 fprintf(stderr, "Unable to set video mode: %s\n",
245 SDL_WM_SetCaption(argv[0], NULL);
247 loop(screen, planets, total_mass, range);