From f7edafe7752c7545deb43e2b253735b7abd4b7cd Mon Sep 17 00:00:00 2001 From: EliteTK Date: Mon, 17 Nov 2014 00:42:00 +0000 Subject: xcb_gol.c: xcb_gol_macro.c: new --- xcb_gol_macro.c | 186 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 186 insertions(+) create mode 100644 xcb_gol_macro.c (limited to 'xcb_gol_macro.c') diff --git a/xcb_gol_macro.c b/xcb_gol_macro.c new file mode 100644 index 0000000..2f8f2af --- /dev/null +++ b/xcb_gol_macro.c @@ -0,0 +1,186 @@ +/* + * Copyright (C) 2014 Tomasz Kramkowski + * + * This program is free software. It is licensed under version 3 of the + * GNU General Public License. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see [http://www.gnu.org/licenses/]. + */ +#include +#include +#include +#include +#include +#include + +#define BOARD_WIDTH 500 +#define BOARD_HEIGHT 500 + +#define PIXEL 1 + +#define WIDTH (BOARD_WIDTH * PIXEL) +#define HEIGHT (BOARD_HEIGHT * PIXEL) + +#define GOL_CLAMP(pos, max) ((pos) < 0 ? (pos) + (max) : (pos) % (max)) +#define GOL_CLAMPX(gol, pos) (GOL_CLAMP((pos), (gol)->width)) +#define GOL_CLAMPY(gol, pos) (GOL_CLAMP((pos), (gol)->height)) +#define GOL_RESOLVE_F(gol, x, y) ((gol)->buffers[(gol)->front][(GOL_CLAMPX(gol, x))\ + + (GOL_CLAMPY(gol, y)) * (gol)->width]) +#define GOL_RESOLVE_B(gol, x, y) ((gol)->buffers[!(gol)->front][(GOL_CLAMPX(gol, x))\ + + (GOL_CLAMPY(gol, y)) * (gol)->width]) + +typedef struct gol_t { + uint32_t width, height; + bool *buffers[2]; + uint8_t front; +} Gol; + +Gol *gol_new(unsigned const int width, unsigned const int height) +{ + Gol *gol = malloc(sizeof(Gol)); + gol->width = width; + gol->height = height; + gol->front = 0; + gol->buffers[0] = malloc(width * height * sizeof(bool)); + gol->buffers[1] = malloc(width * height * sizeof(bool)); + return gol; +} + +void gol_del(Gol *gol) +{ + free(gol->buffers[0]); + free(gol->buffers[1]); + free(gol); +} + +void gol_random(Gol *const gol, unsigned const int seed) +{ + srand(seed); + for (uint32_t i = 0; i < gol->width * gol->height; i++) + gol->buffers[gol->front][i] = rand() < 0.5 * ((double)RAND_MAX + 1.0); +} + +static uint32_t gol_clamp(const uint32_t pos, const uint32_t max) { + return pos < 0 ? pos + max : pos % max; +} + +static uint32_t gol_resolve_f(const Gol *const gol, + +static uint8_t gol_neighbours(Gol *const gol, const uint32_t x, const uint32_t y) +{ + uint8_t neighbours = 0; + for (int8_t dx = -1; dx <= 1; dx++) + for (int8_t dy = -1; dy <= 1; dy++) + if (!(dx == 0 && dy == 0) && GOL_RESOLVE_F(gol, x + dx, y + dy)) + neighbours++; + return neighbours; +} + +void gol_simulate(Gol *const gol) +{ + for (uint32_t x = 0; x < gol->width; x++) + for (uint32_t y = 0; y < gol->height; y++) { + uint8_t neighbours = gol_neighbours(gol, x, y); + if (GOL_RESOLVE_F(gol, x, y)){ + if (neighbours < 2) + GOL_RESOLVE_B(gol, x, y) = 0; + else if (neighbours <= 3) + GOL_RESOLVE_B(gol, x, y) = 1; + else + GOL_RESOLVE_B(gol, x, y) = 0; + } else { + if (neighbours == 3) + GOL_RESOLVE_B(gol, x, y) = 1; + else + GOL_RESOLVE_B(gol, x, y) = 0; + } + } + + gol->front = !gol->front; +} + +int main(int argc, char **argv) +{ + xcb_connection_t *connection = xcb_connect(NULL, NULL); + + xcb_screen_t *screen = xcb_setup_roots_iterator(xcb_get_setup(connection)).data; + + uint32_t mask = XCB_CW_BACK_PIXEL; + uint32_t values[] = {screen->black_pixel}; + + xcb_drawable_t window = xcb_generate_id(connection); + xcb_create_window(connection, + 24, + window, + screen->root, + 0, 0, + WIDTH, HEIGHT, + 1, + XCB_WINDOW_CLASS_INPUT_OUTPUT, + screen->root_visual, + mask, values); + + xcb_pixmap_t pixmap = xcb_generate_id(connection); + xcb_create_pixmap(connection, + 24, + pixmap, + window, + WIDTH, HEIGHT); + + uint8_t *img = malloc(WIDTH * HEIGHT * 4); + xcb_image_t *image = xcb_image_create(WIDTH, HEIGHT, + XCB_IMAGE_FORMAT_Z_PIXMAP, + 8, 24, 32, + 0, + XCB_IMAGE_ORDER_MSB_FIRST, + XCB_IMAGE_ORDER_LSB_FIRST, + img, + WIDTH * HEIGHT * 4, + img); + + mask = XCB_GC_FOREGROUND | XCB_GC_BACKGROUND; + values[0] = screen->black_pixel; + values[1] = 0xFFFFFF; + + xcb_gcontext_t gc = xcb_generate_id(connection); + xcb_create_gc(connection, + gc, + pixmap, + mask, values); + + xcb_image_put(connection, pixmap, gc, image, 0, 0, 0); + + xcb_map_window(connection, window); + xcb_flush(connection); + + uint8_t value = 0; + + uint32_t *limg; + + Gol *gol = gol_new(BOARD_WIDTH, BOARD_HEIGHT); + gol_random(gol, time(NULL)); + + while (1) { + limg = (uint32_t *)image->data; + + for (int i = 0; i < BOARD_WIDTH * BOARD_HEIGHT; i++) + *(limg++) = gol->buffers[gol->front][i] ? 0x00FFFF00 : 0x00000000; + + xcb_image_put(connection, pixmap, gc, image, 0, 0, 0); + + xcb_copy_area(connection, + pixmap, + window, + gc, + 0, 0, + 0, 0, + WIDTH, HEIGHT); + xcb_flush(connection); + value++; + + gol_simulate(gol); + } + return 0; +} + -- cgit v1.2.3-54-g00ecf