diff options
Diffstat (limited to '03-wolfrand')
-rw-r--r-- | 03-wolfrand/Makefile | 29 | ||||
-rw-r--r-- | 03-wolfrand/screenshot.gif | bin | 0 -> 244161 bytes | |||
-rw-r--r-- | 03-wolfrand/src/main.c | 180 |
3 files changed, 209 insertions, 0 deletions
diff --git a/03-wolfrand/Makefile b/03-wolfrand/Makefile new file mode 100644 index 0000000..b96ec55 --- /dev/null +++ b/03-wolfrand/Makefile @@ -0,0 +1,29 @@ +CFLAGS+=-Wall -O2 $(shell pkg-config --cflags allegro-5 allegro_primitives-5 libsodium) +CFLAGSDEBUG=-Wall -ggdb3 -O0 -DDEBUG $(shell pkg-config --cflags allegro-5 allegro_primitives-5) +LDFLAGS+=-Wall -O2 $(shell pkg-config --libs allegro-5 allegro_primitives-5 libsodium) +LDFLAGSDEBUG=-Wall -ggdb3 -O0 -DDEBUG $(shell pkg-config --libs allegro-5 allegro_primitives-5) +SRCDIR=./src +OBJDIR=./build +SRC=$(wildcard $(SRCDIR)/*.c) +OBJ=$(patsubst $(SRCDIR)%.c,$(OBJDIR)%.o,$(SRC)) +BIN=wolfrand + +all: $(OBJ) + $(CC) $(LDFLAGS) -o $(BIN) $^ + +$(OBJ): | $(OBJDIR) + +$(OBJDIR)/%.o: $(SRCDIR)/%.c + $(CC) $(CFLAGS) -c -o $@ $< + +$(OBJDIR): + mkdir -p $(OBJDIR) + +clean: + rm -rf $(OBJDIR) $(BIN) + +debug: CFLAGS=$(CFLAGSDEBUG) +debug: LDFLAGS=$(LDFLAGSDEBUG) +debug: all + +new: clean all diff --git a/03-wolfrand/screenshot.gif b/03-wolfrand/screenshot.gif Binary files differnew file mode 100644 index 0000000..36a3b73 --- /dev/null +++ b/03-wolfrand/screenshot.gif diff --git a/03-wolfrand/src/main.c b/03-wolfrand/src/main.c new file mode 100644 index 0000000..5bf9578 --- /dev/null +++ b/03-wolfrand/src/main.c @@ -0,0 +1,180 @@ +#include <stdlib.h> +#include <stdbool.h> +#include <stdio.h> +#include <string.h> + +#include <allegro5/allegro5.h> +#include <allegro5/allegro_primitives.h> + +#include <sodium.h> + +#define DISP_WIDTH 640 +#define DISP_HEIGHT 480 + +#define FPS 3.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)) ); +} + +static void bit_toggle(uint8_t *bline, unsigned off) +{ + bline[off / 8] = (bline[off / 8] ^ (0x01 << (off % 8)) ); +} + +int main(int argc, char **argv) +{ + int rval = 0; + + uint8_t bits[DISP_HEIGHT][DISP_WIDTH / 8]; + + uint8_t automaton = 0; + unsigned x, y; + + bool pause = 0; + + ALLEGRO_DISPLAY* d = NULL; + ALLEGRO_TIMER* t = NULL; + ALLEGRO_EVENT_QUEUE* eq = NULL; + ALLEGRO_EVENT e; + + + DO_INIT(sodium_init() >= 0, "sodium"); + + 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); + + al_clear_to_color(al_map_rgb(0, 0, 0)); + + 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: + pause = !pause; + printf("%s\n", pause ? "pause" : "play"); + break; + + default: + break; + + } + + break; + + case ALLEGRO_EVENT_TIMER: + + if (pause) + break; + + /* seed bits */ + + memset(bits[1], 0, (DISP_HEIGHT - 1) * DISP_WIDTH / 8); + + for (x = 1; x < DISP_WIDTH - 1; x++) { + if (randombytes_random() < 0x80000000) + bit_toggle(bits[0], x); + } + + /* propagate */ + + 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); + } + } + } + + /* draw frame */ + + al_clear_to_color(al_map_rgb(0, 0, 0)); + + for (y = 0; y < DISP_HEIGHT; y++) { + for (x = 0; x < DISP_WIDTH; x++) { + if (bit_get(bits[y], x)) { + al_draw_filled_rectangle( + (float)x, (float)y, + (float)(x + 1), (float)(y + 1), + al_map_rgb(255, 255, 255) + ); + } + } + } + + al_flip_display(); + } + } + + +done: + + if (d) + al_destroy_display(d); + if (t) + al_destroy_timer(t); + if (eq) + al_destroy_event_queue(eq); + + return rval; +} |