katherine 3 months ago
parent
commit
91333caa69
  1. 29
      05-brain/Makefile
  2. BIN
      05-brain/screenshot.png
  3. 226
      05-brain/src/main.c

29
05-brain/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=brain
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

BIN
05-brain/screenshot.png

After

Width: 772  |  Height: 772  |  Size: 5.6 KiB

226
05-brain/src/main.c

@ -0,0 +1,226 @@
#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 BUF_W 256
#define BUF_H 256
#define DISP_SCALE 3
#define SEED_BITS 4096
#define FPS 30.0
#define DO_INIT(check, desc) \
if (!(check)) { \
fprintf(stderr, "err: can't initialise %s\n", desc); \
rval = 1; \
goto done; \
}
int main(int argc, char **argv)
{
int rval = 0;
uint8_t bits1[BUF_H][BUF_W] = {0};
uint8_t bits2[BUF_H][BUF_W] = {0};
uint8_t framerate = 8;
unsigned goframes = 1;
unsigned x, y, sum;
bool pause = true;
bool mouse_down = false;
ALLEGRO_MOUSE_STATE ms;
ALLEGRO_DISPLAY *d = NULL;
ALLEGRO_BITMAP *b = 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(al_install_mouse(), "mouse");
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_SCALE * BUF_W, DISP_SCALE * BUF_H
), "display"
);
al_set_new_bitmap_flags(ALLEGRO_MEMORY_BITMAP);
DO_INIT(b = al_create_bitmap(BUF_W, BUF_H), "buffer");
al_register_event_source(eq, al_get_keyboard_event_source());
al_register_event_source(eq, al_get_mouse_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);
reset:
memset(bits1, 0, sizeof(bits1));
while(true) {
al_wait_for_event(eq, &e);
switch (e.type) {
case ALLEGRO_EVENT_DISPLAY_CLOSE:
goto done;
case ALLEGRO_EVENT_MOUSE_BUTTON_DOWN:
bits1[e.mouse.y / DISP_SCALE][e.mouse.x / DISP_SCALE] = 1;
mouse_down = true;
break;
case ALLEGRO_EVENT_MOUSE_BUTTON_UP:
mouse_down = false;
break;
case ALLEGRO_EVENT_KEY_DOWN:
switch(e.keyboard.keycode) {
case ALLEGRO_KEY_Q:
goto done;
case ALLEGRO_KEY_1:
framerate = (framerate == 1 ? 16 : framerate / 2);
printf("fps: %.1f\n", FPS / ((float)framerate) );
break;
case ALLEGRO_KEY_2:
memset(bits1, 0, sizeof(bits1));
for (x = 0; x < SEED_BITS; x++) {
bits1[randombytes_random() % BUF_H][randombytes_random() % BUF_W] = 1;
}
break;
case ALLEGRO_KEY_3:
goto reset;
case ALLEGRO_KEY_ENTER:
pause = !pause;
printf("%s\n", pause ? "pause" : "play");
break;
default:
break;
}
break;
case ALLEGRO_EVENT_TIMER:
if (mouse_down) {
al_get_mouse_state(&ms);
bits1[ms.y / DISP_SCALE][ms.x / DISP_SCALE] = 1;
}
/* step */
if (goframes) {
goframes--;
} else if (!pause) {
for (y = 0; y < BUF_H; y++) {
for (x = 0; x < BUF_W; x++) {
if (bits1[y][x] == 2) {
bits2[y][x] = 0;
continue;
}
if (bits1[y][x] == 1) {
bits2[y][x] = 2;
continue;
}
sum =
(1 == bits1[(y-1) % BUF_H][(x-1) % BUF_W])
+ (1 == bits1[(y-1) % BUF_H][ x ])
+ (1 == bits1[(y-1) % BUF_H][(x+1) % BUF_W])
+ (1 == bits1[ y ][(x-1) % BUF_W])
+ (1 == bits1[ y ][(x+1) % BUF_W])
+ (1 == bits1[(y+1) % BUF_H][(x-1) % BUF_W])
+ (1 == bits1[(y+1) % BUF_H][ x ])
+ (1 == bits1[(y+1) % BUF_H][(x+1) % BUF_W])
;
if (sum == 2)
bits2[y][x] = 1;
}
}
memcpy(bits1, bits2, sizeof(bits1));
goframes = framerate;
}
/* draw frame */
al_lock_bitmap(b, ALLEGRO_PIXEL_FORMAT_ANY, ALLEGRO_LOCK_WRITEONLY);
al_set_target_bitmap(b);
for (y = 0; y < BUF_H; y++) {
for (x = 0; x < BUF_W; x++) {
switch (bits1[y][x]) {
case 0:
al_put_pixel(x, y, al_map_rgb(0, 0, 0));
break;
case 1:
al_put_pixel(x, y, al_map_rgb(255, 255, 255));
break;
case 2:
al_put_pixel(x, y, al_map_rgb(255, 0, 0));
break;
}
}
}
al_unlock_bitmap(b);
al_set_target_backbuffer(d);
al_draw_scaled_bitmap(b,
0, 0, BUF_W, BUF_H,
0, 0, DISP_SCALE * BUF_W, DISP_SCALE * BUF_H,
0
);
al_flip_display();
}
}
done:
if (d)
al_destroy_display(d);
if (b)
al_destroy_bitmap(b);
if (t)
al_destroy_timer(t);
if (eq)
al_destroy_event_queue(eq);
return rval;
}
Loading…
Cancel
Save