]> git.itanic.dy.fi Git - sdl-planets/blob - main.c
Add support for zooming the camera
[sdl-planets] / main.c
1 #include <SDL.h>
2 #include <unistd.h>
3 #include <stdio.h>
4
5 #include "random.h"
6 #include "planet.h"
7
8 static void fade_buf(SDL_Surface *screen, double amount)
9 {
10         int i;
11         unsigned char *buf = screen->pixels;
12
13         for (i = 0; i < screen->pitch * screen->h; i++)
14                 buf[i] = (buf[i] < amount) ? 0 : buf[i] - amount;
15 }
16
17 static void clear_buf(SDL_Surface *screen)
18 {
19         int i;
20         unsigned int *buf = screen->pixels;
21
22         for (i = 0; i < screen->pitch * screen->h / 4; i++)
23                 buf[i] = 0;
24 }
25
26 static void loop(SDL_Surface *screen, int num_of_planets)
27 {
28         struct planet *planet, *pl1, *pl2;
29         struct camera camera;
30         SDL_Event event;
31         int i, planets;
32         int old_ticks, ticks, framecount = 0, last_fps_time = 0;
33         int last_framecount = 0;
34         double time = 0, last_fps = 0;
35
36         init_camera(&camera);
37
38         planet = malloc(sizeof(*planet));
39         init_planet(screen, planet);
40
41         for (i = 1; i < num_of_planets; i++) {
42                 struct planet *new_planet;
43                 new_planet = malloc(sizeof(*planet));
44                 init_planet(screen, new_planet);
45                 list_add(&new_planet->list, &planet->list);
46         }
47
48         ticks = SDL_GetTicks();
49         while (1) {
50                 planets = 0;
51
52                 list_for_each_entry(pl1, &planet->list, list) {
53                         pl2 = list_to_planet(pl1->list.next);
54                         list_for_each_entry_from(pl2, &planet->list, list) {
55                                 struct planet *ptmp;
56                                 if (!gravitize_planets(pl1, pl2, time))
57                                         continue;
58
59                                 ptmp = list_to_planet(pl2->list.prev);
60                                 merge_planets(pl1, pl2);
61                                 pl2 = ptmp;
62                         }
63
64                         move_planet(pl1, time);
65                 }
66
67                 SDL_LockSurface(screen);
68
69                 clear_buf(screen);
70
71                 list_for_each_entry(pl1, &planet->list, list) {
72                         draw_planet(screen, pl1, &camera);
73                         planets++;
74                 }
75
76                 SDL_UnlockSurface(screen);
77
78                 SDL_Flip(screen);
79
80                 move_camera(&camera, time);
81
82                 while (SDL_PollEvent(&event)) {
83                         switch (event.type) {
84                         case SDL_KEYDOWN:
85                                 switch (event.key.keysym.sym) {
86                                 case SDLK_ESCAPE:
87                                         printf("\nExiting. Good bye!\n");
88                                         return;
89                                 case SDLK_LEFT:
90                                         camera.speed.x = -CAM_SPEED;
91                                         break;
92                                 case SDLK_RIGHT:
93                                         camera.speed.x = CAM_SPEED;
94                                         break;
95                                 case SDLK_UP:
96                                         camera.speed.y = -CAM_SPEED;
97                                         break;
98                                 case SDLK_DOWN:
99                                         camera.speed.y = CAM_SPEED;
100                                         break;
101                                 case SDLK_PLUS:
102                                         camera.zoom_rate = CAM_ZOOM_RATE;
103                                         break;
104                                 case SDLK_MINUS:
105                                         camera.zoom_rate = 1 / CAM_ZOOM_RATE;
106                                         break;
107                                 default:
108                                         break;
109                                 }
110                                 break;
111                         case SDL_KEYUP:
112                                 switch (event.key.keysym.sym) {
113                                 case SDLK_ESCAPE:
114                                         printf("\nExiting. Good bye!\n");
115                                         return;
116                                 case SDLK_LEFT:
117                                         camera.speed.x = 0;
118                                         break;
119                                 case SDLK_RIGHT:
120                                         camera.speed.x = 0;
121                                         break;
122                                 case SDLK_UP:
123                                         camera.speed.y = 0;
124                                         break;
125                                 case SDLK_DOWN:
126                                         camera.speed.y = 0;
127                                         break;
128                                 case SDLK_PLUS:
129                                         camera.zoom_rate = 1;
130                                         break;
131                                 case SDLK_MINUS:
132                                         camera.zoom_rate = 1;
133                                         break;
134                                 default:
135                                         break;
136                                 }
137                                 break;
138                         case SDL_VIDEORESIZE:
139                                 screen = SDL_SetVideoMode(event.resize.w,
140                                                           event.resize.h,
141                                                           32,
142                                                           screen->flags);
143                                 break;
144                         }
145                 }
146
147                 old_ticks = ticks;
148                 ticks = SDL_GetTicks();
149                 time = (ticks - old_ticks) / 1000.0;
150
151                 if (last_fps_time + 500 < ticks) {
152                         last_framecount = framecount - last_framecount;
153                         last_fps = last_framecount * 1000 /
154                                 (float)(ticks - last_fps_time);
155                         last_framecount = framecount;
156                         last_fps_time = ticks;
157                 }
158                 printf("  \rFrames/s: %.2f, Frame: %d, planets: %d",
159                        last_fps, framecount++, planets);
160         }
161 }
162
163 int main(int argc, char *argv[])
164 {
165         SDL_Surface *screen;
166         int flags = SDL_DOUBLEBUF | SDL_HWSURFACE | SDL_RESIZABLE;
167         int planets = 100, xres = 800, yres = 600;
168
169         if (SDL_Init(SDL_INIT_VIDEO) != 0) {
170                 fprintf(stderr, "Unable to initialize SDL: %s\n",
171                         SDL_GetError());
172
173                 return 1;
174         }
175         atexit(SDL_Quit);
176
177         if (argc >= 2)
178                 planets = atoi(argv[1]);
179
180         if (argc >= 3)
181                 xres = atoi(argv[2]);
182
183         if (argc >= 4)
184                 yres = atoi(argv[3]);
185
186         screen = SDL_SetVideoMode(xres, yres, 32, flags);
187         if (screen == NULL) {
188                 fprintf(stderr, "Unable to set video mode: %s\n",
189                         SDL_GetError());
190                 return 2;
191         }
192
193         loop(screen, planets);
194
195         return 0;
196 }
197