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; +}  | 
