#include #include #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); } int redraw_screen(struct gol_board *state, SDL_Surface *screen, struct viewport viewport); 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 = 10, .max_x = 0, .min_x = 0, .max_y = 0, .min_y = 0 }; SDL_Window *window = NULL; 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 struct viewport viewport = {0, 0, 4}; SDL_Event e; 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); } window = SDL_CreateWindow("SDL Tutorial", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, 640, 480, SDL_WINDOW_SHOWN); if (!window) { quit(1); } screen = SDL_GetWindowSurface(window); if (!screen) { quit(1); } SDL_UpdateWindowSurface(window); while (!finished) { while (SDL_PollEvent(&e) != 0) { if (e.type == SDL_QUIT) { finished = 1; } else if (e.type == SDL_KEYDOWN) { switch (e.key.keysym.sym) { case SDLK_q: case SDLK_x: finished = 1; break; case SDLK_PLUS: case SDLK_EQUALS: if (viewport.zoom_level != MAX_ZOOM_LEVEL) viewport.zoom_level++; redraw = 1; break; case SDLK_MINUS: case SDLK_UNDERSCORE: 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 = 0; redraw_screen(&state, screen, viewport); SDL_UpdateWindowSurface(window); } } SDL_DestroyWindow(window); quit(0); } int redraw_screen(struct gol_board *state, SDL_Surface *screen, struct viewport viewport) { SDL_Rect rect; int i, j, ppc; char is_live; ppc = ZOOM_LEVELS[viewport.zoom_level]; SDL_FillRect(screen, NULL, SDL_MapRGB(screen->format, 255, 255, 255)); 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 - viewport.origin_x) * ppc), ((j - viewport.origin_y) * ppc), ppc, ppc }; SDL_FillRect(screen, &rect, SDL_MapRGB(screen->format, 0, 0, 0)); } } } 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; }