#include "array.h"
#include "tick.h"
+const int ZOOM_LEVELS[10] = {1, 2, 3, 5, 8, 12, 20, 30};
+const unsigned int MAX_ZOOM_LEVEL = 7;
+
+struct viewport {
+ int origin_x;
+ int origin_y;
+ int zoom_level;
+};
+
void quit(int e_st)
{
SDL_Quit();
exit(e_st);
}
-void simulate(struct gol_board *state, SDL_Surface *screen, SDL_Window *window);
+int redraw_screen(struct gol_board *state, SDL_Surface *screen, struct viewport viewport);
-int redraw_screen(struct gol_board *state, SDL_Surface *screen, int ppc,
- int origin_x, int origin_y);
+int handle_mousedown(struct gol_board *state, struct viewport viewport, SDL_Event e);
int main(int argc, char* args[])
{
struct gol_board state = {
.live_cells = NULL,
.n = 0,
- .size = 0,
+ .size = 10,
.max_x = 0,
.min_x = 0,
.max_y = 0,
SDL_Surface *screen = NULL;
char finished = 0;
+ char tick = 0;
char redraw = 1;
// The coordinates of the cell to draw in the bottom left corner of the
// canvas
- int origin_x = 0;
- int origin_y = 0;
-
- int ppc = 10;
+ struct viewport viewport = {0, 0, 4};
SDL_Event e;
- //state.live_cells = malloc(10 * sizeof(typeof(*state.live_cells)));
- //if (!state.live_cells) {
- // return 1;
- //}
+ state.live_cells = malloc(10 * sizeof(int_least32_t));
+ if (!state.live_cells) {
+ return 1;
+ }
+
+ gol_vivify(&state, 10, 10);
if (SDL_Init(SDL_INIT_EVERYTHING) < 0) {
quit(1);
SDL_WINDOWPOS_UNDEFINED,
SDL_WINDOWPOS_UNDEFINED,
640,
- 320,
+ 480,
SDL_WINDOW_SHOWN);
if (!window) {
quit(1);
break;
case SDLK_PLUS:
case SDLK_EQUALS:
- ppc *= 1.2;
+ if (viewport.zoom_level != MAX_ZOOM_LEVEL)
+ viewport.zoom_level++;
redraw = 1;
break;
case SDLK_MINUS:
case SDLK_UNDERSCORE:
- ppc /= 1.2;
+ if (viewport.zoom_level != 0)
+ viewport.zoom_level--;
redraw = 1;
break;
+ case SDLK_SPACE:
+ tick = 1;
default:
break;
}
+ } else if (e.type == SDL_MOUSEBUTTONDOWN) {
+ handle_mousedown(&state, viewport, e);
+ redraw = 1;
}
}
+ if (tick) {
+ tick = 0;
+ gol_tick(&state);
+ redraw = 1;
+ }
if (redraw) {
- redraw_screen(&state, screen, ppc, origin_x, origin_y);
+ redraw = 0;
+ redraw_screen(&state, screen, viewport);
+ SDL_UpdateWindowSurface(window);
}
}
- // Main loop
- // simulate(&state, screen, window);
-
-
SDL_DestroyWindow(window);
quit(0);
}
-void simulate(struct gol_board *state, SDL_Surface *screen, SDL_Window *window)
-{
- SDL_Rect cell;
- double ppc_x;
- double ppc_y;
- for (unsigned int i = 0; i < 1000; ++i) {
- printf("Generation %d\n", i);
- ppc_x = SCREEN_WIDTH/(state->max_x - state->min_x);
- ppc_y = SCREEN_HEIGHT/(state->max_y - state->min_y);
- for (unsigned int j = 0; j < state->n; j += 2) {
- printf("(%d, %d)\n", state->live_cells[j],
- state->live_cells[j + 1]);
-
- }
- printf("\n");
- if (!gol_tick(state)) {
- return;
- }
- SDL_UpdateWindowSurface(window);
- }
-}
-
int redraw_screen(struct gol_board *state, SDL_Surface *screen,
- int ppc, int origin_x, int origin_y)
+ struct viewport viewport)
{
SDL_Rect rect;
- int i, j;
+ int i, j, ppc;
+ char is_live;
+
+ ppc = ZOOM_LEVELS[viewport.zoom_level];
+
+ SDL_FillRect(screen, NULL, SDL_MapRGB(screen->format, 255, 255, 255));
- SDL_FillRect(screen, NULL, SDL_MapRGB(screen->format, 0xFF, 0xFF, 0xFF));
- for (i = origin_x; i < (screen->w/ppc) + origin_x; ++i) {
- for (j = origin_y; j < (screen->h/ppc) + origin_y; ++j) {
- if (gol_is_live(state, i, j)) {
+ for (i = viewport.origin_x;
+ i < (screen->w/ppc) + viewport.origin_x;
+ ++i) {
+ for (j = viewport.origin_y;
+ j < (screen->h/ppc) + viewport.origin_y;
+ ++j) {
+ if (gol_is_live(state, i, j, &is_live) && is_live) {
rect = (SDL_Rect) {
- ((i - origin_x) * ppc),
- ((j - origin_y) * ppc),
+ ((i - viewport.origin_x) * ppc),
+ ((j - viewport.origin_y) * ppc),
ppc,
ppc
};
}
}
}
+ return 0;
+}
+
+int handle_mousedown(struct gol_board *state, struct viewport viewport, SDL_Event e)
+{
+ int x, y;
+ char is_live;
+ x = e.button.x/ZOOM_LEVELS[viewport.zoom_level] - viewport.origin_x;
+ y = e.button.y/ZOOM_LEVELS[viewport.zoom_level] - viewport.origin_y;
+
+ gol_is_live(state, x, y, &is_live);
+ if (!is_live)
+ gol_vivify(state, x, y);
+
+ return 1;
}