#include #include #define width 512 #define height 512 static uint8_t field[width * height]; static uint8_t nextField[width * height]; static uint8_t pixels[width * height * 4]; static uint8_t rand8(void); static int countNeighbours(int x, int y); EXPORT(getWidth) int get_width(void) { return width; } EXPORT(getHeight) int get_height(void) { return height; } EXPORT(getPixels) uint8_t* get_pixels(void) { return pixels; } EXPORT(step) void step(void) { for (int y = 0; y < height; y++) { for (int x = 0; x < width; x++) { int count = countNeighbours(x, y); uint8_t currentCell = field[x + y * width]; int nextCell = currentCell; if (currentCell && count < 2) nextCell = 0; else if (currentCell && count > 3) nextCell = 0; else if (!currentCell && count == 3) nextCell = 1; nextField[x + y * width] = nextCell; } } for (int i = 0; i < width * height; i++) { field[i] = nextField[i]; uint8_t px = field[i]; if (px) { pixels[(i << 2) + 0] = 0; pixels[(i << 2) + 1] = 0; pixels[(i << 2) + 2] = 0; } else { pixels[(i << 2) + 0] = 255; pixels[(i << 2) + 1] = 255; pixels[(i << 2) + 2] = 255; } pixels[(i << 2) + 3] = 255; } } static int countNeighbours(int x, int y) { int count = 0; for (int i = -1; i <= 1; i++) { for (int j = -1; j <= 1; j++) { if (i == 0 && j == 0) continue; int xx = (x + i + width) % width; int yy = (y + j + height) % height; if (field[xx + yy * width]) { count++; } } } return count; } /** Random generator implementation from https://stackoverflow.com/a/16761955 */ #define STATE_BYTES 7 #define MULT 0x13B /* for STATE_BYTES==6 only */ #define MULT_LO (MULT & 255) #define MULT_HI (MULT & 256) static uint8_t rand_state[STATE_BYTES] = { 0x87, 0xdd, 0xdc, 0x10, 0x35, 0xbc, 0x5c }; static uint8_t rand8(void) { static uint16_t c = 0x42; static uint32_t i = 0; uint16_t t; uint8_t x; x = rand_state[i]; t = (uint16_t)x * MULT_LO + c; c = t >> 8; #if MULT_HI c += x; #endif x = t & 255; rand_state[i] = x; if (++i >= sizeof(rand_state)) i = 0; return x; } EXPORT(initField) void init_field(uint32_t randomSeed) { *((uint32_t*)&rand_state[STATE_BYTES - sizeof(uint32_t)]) = randomSeed; // Voodoo for (int i = 0; i < width * height; i++) { field[i] = rand8() & 1; } }