]> git.friedersdorff.com Git - max/gol.git/blob - gol.c
First working implementation
[max/gol.git] / gol.c
1 #include <SDL2/SDL.h>
2 #include <stdio.h>
3 #include "array.h"
4 #include "tick.h"
5
6 const int ZOOM_LEVELS[10] = {1, 2, 3, 5, 8, 12, 20, 30};
7 const unsigned int MAX_ZOOM_LEVEL = 7;
8
9 struct viewport {
10         int origin_x;
11         int origin_y;
12         int zoom_level;
13 };
14
15 void quit(int e_st)
16 {
17         SDL_Quit();
18         exit(e_st);
19 }
20
21 int redraw_screen(struct gol_board *state, SDL_Surface *screen, struct viewport viewport);
22
23 int handle_mousedown(struct gol_board *state, struct viewport viewport, SDL_Event e);
24
25 int main(int argc, char* args[])
26 {
27         struct gol_board state = {
28                 .live_cells = NULL,
29                 .n = 0,
30                 .size = 10,
31                 .max_x = 0,
32                 .min_x = 0,
33                 .max_y = 0,
34                 .min_y = 0
35         };
36         SDL_Window *window = NULL;
37         SDL_Surface *screen = NULL;
38
39         char finished = 0;
40         char tick = 0;
41         char redraw = 1;
42
43         // The coordinates of the cell to draw in the bottom left corner of the
44         // canvas
45         struct viewport viewport = {0, 0, 4};
46
47         SDL_Event e;
48
49         state.live_cells = malloc(10 * sizeof(int_least32_t));
50         if (!state.live_cells) {
51                 return 1;
52         }
53
54         gol_vivify(&state, 10, 10);
55         
56         if (SDL_Init(SDL_INIT_EVERYTHING) < 0) {
57                 quit(1);
58         }
59
60         window = SDL_CreateWindow("SDL Tutorial",
61                                   SDL_WINDOWPOS_UNDEFINED,
62                                   SDL_WINDOWPOS_UNDEFINED,
63                                   640,
64                                   480,
65                                   SDL_WINDOW_SHOWN);
66         if (!window) {
67                 quit(1);
68         }
69
70         screen = SDL_GetWindowSurface(window);
71         if (!screen) {
72                 quit(1);
73         }
74         SDL_UpdateWindowSurface(window);
75
76         while (!finished) {
77                 while (SDL_PollEvent(&e) != 0) {
78                         if (e.type == SDL_QUIT) {
79                                 finished = 1;
80                         } else if (e.type == SDL_KEYDOWN) {
81                                 switch (e.key.keysym.sym) {
82                                 case SDLK_q:
83                                 case SDLK_x:
84                                         finished = 1;
85                                         break;
86                                 case SDLK_PLUS:
87                                 case SDLK_EQUALS:
88                                         if (viewport.zoom_level != MAX_ZOOM_LEVEL)
89                                                 viewport.zoom_level++;
90                                         redraw = 1;
91                                         break;
92                                 case SDLK_MINUS:
93                                 case SDLK_UNDERSCORE:
94                                         if (viewport.zoom_level != 0)
95                                                 viewport.zoom_level--;
96                                         redraw = 1;
97                                         break;
98                                 case SDLK_SPACE:
99                                         tick = 1;
100                                 default:
101                                         break;
102                                 }
103                         } else if (e.type == SDL_MOUSEBUTTONDOWN) {
104                                 handle_mousedown(&state, viewport, e);
105                                 redraw = 1;
106                         }
107                 }
108                 if (tick) {
109                         tick = 0;
110                         gol_tick(&state);
111                         redraw = 1;
112                 }
113                 if (redraw) {
114                         redraw = 0;
115                         redraw_screen(&state, screen, viewport);
116                         SDL_UpdateWindowSurface(window);
117                 }
118         }
119
120         SDL_DestroyWindow(window);
121         quit(0);
122 }
123
124
125 int redraw_screen(struct gol_board *state, SDL_Surface *screen,
126         struct viewport viewport)
127 {
128         SDL_Rect rect;
129         int i, j, ppc;
130         char is_live;
131
132         ppc = ZOOM_LEVELS[viewport.zoom_level];
133
134         SDL_FillRect(screen, NULL, SDL_MapRGB(screen->format, 255, 255, 255));
135
136         for (i = viewport.origin_x;
137              i < (screen->w/ppc) + viewport.origin_x;
138              ++i) {
139                 for (j = viewport.origin_y;
140                      j < (screen->h/ppc) + viewport.origin_y;
141                      ++j) {
142                         if (gol_is_live(state, i, j, &is_live) && is_live) {
143                                 rect = (SDL_Rect) {
144                                         ((i - viewport.origin_x) * ppc),
145                                         ((j - viewport.origin_y) * ppc),
146                                         ppc,
147                                         ppc
148                                 };
149                                 SDL_FillRect(screen, &rect,
150                                         SDL_MapRGB(screen->format, 0, 0, 0));
151                         }
152                 }
153         }
154         return 0;
155 }
156
157 int handle_mousedown(struct gol_board *state, struct viewport viewport, SDL_Event e)
158 {
159         int x, y;
160         char is_live;
161         x = e.button.x/ZOOM_LEVELS[viewport.zoom_level] - viewport.origin_x;
162         y = e.button.y/ZOOM_LEVELS[viewport.zoom_level] - viewport.origin_y;
163
164         gol_is_live(state, x, y, &is_live);
165         if (!is_live)
166                 gol_vivify(state, x, y);
167
168         return 1;
169 }