diff options
Diffstat (limited to 'wolfautomata/src')
-rw-r--r-- | wolfautomata/src/main.c | 162 |
1 files changed, 162 insertions, 0 deletions
diff --git a/wolfautomata/src/main.c b/wolfautomata/src/main.c new file mode 100644 index 0000000..d884280 --- /dev/null +++ b/wolfautomata/src/main.c @@ -0,0 +1,162 @@ +#include <stdlib.h> +#include <stdbool.h> +#include <stdio.h> +#include <string.h> + +#include <allegro5/allegro5.h> +#include <allegro5/allegro_primitives.h> + +#define DISP_WIDTH 960 +#define DISP_HEIGHT 480 + +#define FPS 60.0 + +#define DO_INIT(check, desc) \ + if (!(check)) { \ + fprintf(stderr, "err: can't initialise %s\n", desc); \ + rval = 1; \ + goto done; \ + } + +static bool bit_get(uint8_t *bline, unsigned off) +{ + return (bline[off / 8] >> (off % 8)) & 0x01; +} + +static void bit_set(uint8_t *bline, unsigned off) +{ + bline[off / 8] = (bline[off / 8] | (0x01 << (off % 8)) ); +} + +int main(int argc, char **argv) +{ + int rval = 0; + unsigned goframes; + + uint8_t bits[DISP_HEIGHT][DISP_WIDTH / 8]; + + uint8_t automaton = 0; + unsigned x, y; + + ALLEGRO_DISPLAY* d = NULL; + ALLEGRO_TIMER* t = NULL; + ALLEGRO_EVENT_QUEUE* eq = NULL; + ALLEGRO_EVENT e; + + DO_INIT(al_init(), "allegro"); + DO_INIT(al_init_primitives_addon(), "primitives"); + DO_INIT(al_install_keyboard(), "keyboard"); + + DO_INIT(t = al_create_timer(1.0 / FPS), "timer"); + DO_INIT(eq = al_create_event_queue(), "event queue"); + + al_set_new_display_option(ALLEGRO_SINGLE_BUFFER, 1, ALLEGRO_REQUIRE); + DO_INIT(d = al_create_display(DISP_WIDTH, DISP_HEIGHT), "display"); + + al_register_event_source(eq, al_get_keyboard_event_source()); + al_register_event_source(eq, al_get_display_event_source(d)); + al_register_event_source(eq, al_get_timer_event_source(t)); + + al_start_timer(t); + goframes = 0; + +reset: + + al_clear_to_color(al_map_rgb(0, 0, 0)); + memset(bits, 0, DISP_HEIGHT * DISP_WIDTH / 8); + + /* seed bit */ + bit_set(bits[0], DISP_WIDTH / 2); + + for (y = 0; y < DISP_HEIGHT - 1; y++) { + for (x = 1; x < DISP_WIDTH - 2; x++) { + if ( + bit_get(&automaton, + bit_get(bits[y], x + 2) + + bit_get(bits[y], x + 1) * 2 + + bit_get(bits[y], x) * 4 + ) + ) { + bit_set(bits[y + 1], x + 1); + } + } + } + + while(true) { + al_wait_for_event(eq, &e); + + switch (e.type) { + + case ALLEGRO_EVENT_DISPLAY_CLOSE: + goto done; + + case ALLEGRO_EVENT_KEY_DOWN: + switch(e.keyboard.keycode) { + + case ALLEGRO_KEY_UP: + automaton += 10; + printf("%d\n", automaton); + break; + + case ALLEGRO_KEY_DOWN: + automaton -= 10; + printf("%d\n", automaton); + break; + + case ALLEGRO_KEY_LEFT: + automaton -= 1; + printf("%d\n", automaton); + break; + + case ALLEGRO_KEY_RIGHT: + automaton += 1; + printf("%d\n", automaton); + break; + + case ALLEGRO_KEY_ENTER: + goframes = DISP_HEIGHT; + goto reset; + + default: + continue; + + } + + case ALLEGRO_EVENT_TIMER: + if (goframes == 0) { + al_flip_display(); + break; + } + + /* draw line */ + for (x = 0; x < DISP_WIDTH; x++) { + if (bit_get(bits[DISP_HEIGHT - goframes], x)) { + al_draw_filled_rectangle( + (float)x, (float)(DISP_HEIGHT - goframes), + (float)(x + 1), (float)(DISP_HEIGHT - goframes + 1), + al_map_rgb(255, 255, 255) + ); + } + } + + al_flip_display(); + + goframes--; + + if (goframes == 0) + puts("next"); + } + } + + +done: + + if (d) + al_destroy_display(d); + if (t) + al_destroy_timer(t); + if (eq) + al_destroy_event_queue(eq); + + return rval; +} |