aboutsummaryrefslogtreecommitdiffstats
path: root/gg_elife/src/elife_evas_smart.c
diff options
context:
space:
mode:
Diffstat (limited to 'gg_elife/src/elife_evas_smart.c')
-rw-r--r--gg_elife/src/elife_evas_smart.c558
1 files changed, 0 insertions, 558 deletions
diff --git a/gg_elife/src/elife_evas_smart.c b/gg_elife/src/elife_evas_smart.c
deleted file mode 100644
index acbd9a2..0000000
--- a/gg_elife/src/elife_evas_smart.c
+++ /dev/null
@@ -1,558 +0,0 @@
-/*
- * elife - Game of life / Living graphic
- */
-
-/*
- * Copyright (c) 2012 Laurent Ghigonis <laurent@p1sec.com>
- *
- * Permission to use, copy, modify, and distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
- * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
- * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
- * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- */
-
-#include <stdlib.h>
-#include <err.h>
-
-#include "elife_evas_smart.h"
-
-#ifdef HAVE_GLOUGLOU
-#include <libglouglou.h>
-#endif
-
-#define NCELL_X 100
-#define NCELL_Y 100
-#define INJECT_PROBA 40
-#define INITCELL_PROBA 7
-#define CONWAY_GROW_DIE 600
-#define DEBUG 0
-
-#define MIN(a,b) (((a)<(b))?(a):(b))
-#define CELL_GET(grid, x, y) &(grid->cells[(y*grid->w) + x])
-
-typedef struct lifepattern_s {
- const int w;
- const int h;
- const char *pat;
-} lifepattern_s;
-
-enum lifepattern_t {
- ELIFE_PAT_BEEHIVE = 0,
- ELIFE_PAT_BOAT = 1,
- ELIFE_PAT_SHIP = 2,
- ELIFE_PAT_LOAF = 3,
- ELIFE_PAT_QUEENBEE = 4,
- ELIFE_PAT_GLIDER = 5,
- ELIFE_PAT_LWSS = 6,
-};
-#define PATTERN_COUNT 7
-
-lifepattern_s lifepatterns[] = {
- [ELIFE_PAT_BEEHIVE] = {3, 4, "010101101010"},
- [ELIFE_PAT_BOAT] = {3, 3, "010101011"},
- [ELIFE_PAT_SHIP] = {3, 3, "110101011"},
- [ELIFE_PAT_LOAF] = {4, 4, "0110100101010010"},
- [ELIFE_PAT_QUEENBEE] = {4, 7, "1100001000010001000100101100"},
- [ELIFE_PAT_GLIDER] = {3, 3, "010011101"},
- [ELIFE_PAT_LWSS] = {5, 4, "10010000011000101111"},
-};
-
-enum lifemode {
- ELIFE_MODE_CONWAY,
- ELIFE_MODE_CONWAY_GROW,
- ELIFE_MODE_LORAN_CIVILISATION,
-};
-
-struct cell {
- int age, newage;
- u_int32_t forced_color;
- int x, y;
- int r, g, b;
-};
-
-struct grid {
- Evas_Object *container;
- struct cell *cells;
- Evas_Object *image;
- int *mem;
- int w, h;
- int pix_w, pix_h;
- int cell_pix_w, cell_pix_h;
- int age;
- enum lifemode mode;
-#ifdef HAVE_GLOUGLOU
- struct gg_client *ggcli;
- struct event_base *ev_base;
-#endif
-};
-
-static struct grid *grid_new(Evas_Object *container,
- int w, int h, enum lifemode mode);
-static void grid_del(struct grid *grid);
-static int grid_evolution(struct grid *grid);
-static void grid_inject_pattern(struct grid *grid, u_int32_t color);
-static int grid_redraw(struct grid *grid, int w, int h);
-static int cell_neighbours_count(struct cell *cell, struct grid *grid);
-static void cell_redraw(struct cell *c, struct grid *g);
-static void grid_mouse_down(void *data, Evas *evas, Evas_Object *child,
- void *event_info);
-
-Evas_Object *elife_smart_new(Evas *e);
-static void elife_on_refresh(void *data, Evas_Object *o,
- void *event_info);
-static Evas_Object *elife_object_new(Evas *evas);
-static Evas_Smart *_elife_object_smart_get(void);
-static void _elife_object_del(Evas_Object *o);
-static void _elife_object_move(Evas_Object *o,
- Evas_Coord x, Evas_Coord y);
-static void _elife_object_resize(Evas_Object *o,
- Evas_Coord w, Evas_Coord h);
-/* Not implemented
-static void _elife_object_show(Evas_Object *o);
-static void _elife_object_hide(Evas_Object *o);
-static void _elife_object_color_set(Evas_Object *o, int r, int g, int b, int a);
-static void _elife_object_clip_set(Evas_Object *o, Evas_Object *clip);
-static void _elife_object_clip_unset(Evas_Object *o);
-*/
-void *xmalloc(size_t size);
-
-static struct {
- Evas_Smart_Class klass;
-} elife_evas_smart_g = {
- .klass = {
- .name = "elife_object",
- .version = EVAS_SMART_CLASS_VERSION,
- .add = NULL,
- .del = _elife_object_del,
- .move = _elife_object_move,
- .resize = _elife_object_resize,
- .show = NULL,
- .hide = NULL,
- .color_set = NULL,
- .clip_set = NULL,
- .clip_unset = NULL,
- .calculate = NULL,
- .member_add = NULL,
- .member_del = NULL,
- .parent = NULL,
- .callbacks = NULL,
- .interfaces = NULL,
- .data = NULL,
- },
-#define _G elife_evas_smart_g
-};
-
-#ifdef HAVE_GLOUGLOU
-int
-gg_packet(struct gg_client *cli, struct gg_packet *pkt)
-{
- struct grid *grid;
- u_int32_t color;
-
- grid = cli->usrdata;
- switch(pkt->type) {
- case PACKET_FORK: color=0xff0000; break;
- case PACKET_EXEC: color=0x00ff00; break;
- case PACKET_EXIT: color=0x0000ff; break;
- default: return 0;
- }
- grid_inject_pattern(grid, color);
-
- return 0;
-}
-#endif
-
-static struct grid *
-grid_new(Evas_Object *container, int w, int h, enum lifemode mode)
-{
- struct grid *g;
- struct cell *cell;
- Evas_Object *o;
- int i, j;
-
- g = xmalloc(sizeof(struct grid));
- g->container = container;
- o = evas_object_image_filled_add(evas_object_evas_get(container));
- if (!o)
- err(1, "Cannot create image for grid");
- evas_object_image_alpha_set(o, EINA_FALSE);
- evas_object_image_smooth_scale_set(o, EINA_FALSE);
- evas_object_data_set(o, "grid", g);
- evas_object_event_callback_add(o, EVAS_CALLBACK_MOUSE_DOWN,
- grid_mouse_down, g);
- evas_object_smart_member_add(o, container);
- evas_object_show(o);
- g->image = o;
- g->mem = NULL;
- g->w = w;
- g->h = h;
- g->age = 0;
- g->mode = mode;
- g->cells = xmalloc(sizeof(struct cell) * w * h);
- for (j=0; j<h; j++) {
- for (i=0; i<w; i++) {
- cell = CELL_GET(g, i, j);
- cell->x = i;
- cell->y = j;
- cell->r = 0;
- cell->g = 0;
- cell->b = 0;
- cell->forced_color = 0x000000;
- cell->age = !(rand() % INITCELL_PROBA);
- }
- }
-
-#ifdef HAVE_GLOUGLOU
- g->ev_base = event_base_new();
- g->ggcli = gg_client_connect(g->ev_base, "127.0.0.1", GLOUGLOU_ANALY_DEFAULT_PORT,
- NULL, gg_packet, g);
-#endif
-
- return g;
-}
-
-static void
-grid_del(struct grid *grid)
-{
-#ifdef HAVE_GLOUGLOU
- gg_client_disconnect(grid->ggcli);
-#endif
- free(grid->cells);
- free(grid->mem);
- free(grid);
-}
-
-static int
-grid_evolution(struct grid *grid)
-{
- struct cell *cell;
- int i, j;
- int neighbours;
-
- for (j=0; j<grid->h; j++) {
- for (i=0; i<grid->w; i++) {
- cell = CELL_GET(grid, i, j);
- neighbours = cell_neighbours_count(cell, grid);
- switch (grid->mode) {
- case ELIFE_MODE_CONWAY:
- if (cell->age == 0 && neighbours == 3)
- cell->newage = 1;
- else if (cell->age > 0 && (neighbours == 2 || neighbours == 3))
- cell->newage = cell->age;
- else
- cell->newage = 0;
- break;
- case ELIFE_MODE_CONWAY_GROW:
- if (cell->age == 0 && neighbours == 3)
- cell->newage = 1;
- else if (cell->age > 0 && (neighbours == 2 || neighbours == 3))
- if (cell->age > CONWAY_GROW_DIE)
- cell->newage = 0;
- else
- cell->newage = cell->age + 1;
- else
- cell->newage = 0;
- break;
- case ELIFE_MODE_LORAN_CIVILISATION:
- if (neighbours == 4 || neighbours < 2)
- cell->newage = 0;
- else if (neighbours > 2 && neighbours != 5)
- cell->newage = cell->age + 1;
- else if (neighbours == 2 && cell->age > 1)
- cell->newage = 0;
- else
- cell->newage = cell->age;
- if (cell->age > 100)
- cell->newage = 0;
- break;
- }
- if (cell->newage == 0 && cell->forced_color)
- cell->forced_color = 0;
- if (DEBUG)
- printf("evolution: %d %d n %d age %d newage %d\n", i, j,
- neighbours, cell->age, cell->newage);
- }
- }
-
-#ifdef HAVE_GLOUGLOU
- event_base_loop(grid->ev_base, EVLOOP_NONBLOCK);
-#else
- if (rand() % INJECT_PROBA == 0)
- grid_inject_pattern(grid, 0);
-#endif
-
- for (j=0; j<grid->h; j++) {
- for (i=0; i<grid->w; i++) {
- cell = CELL_GET(grid, i, j);
- cell->age = cell->newage;
- cell_redraw(cell, grid);
- }
- }
- evas_object_image_pixels_dirty_set(grid->image, EINA_TRUE);
-
- grid->age++;
-}
-
-static void
-grid_inject_pattern(struct grid *grid, u_int32_t color)
-{
- struct cell *cell;
- enum lifepattern_t npat;
- lifepattern_s *pat;
- int x, y, cx, cy;
- int i, j;
- int age;
-
- npat = rand() % PATTERN_COUNT;
- if (DEBUG)
- printf("grid_inject_pattern: %d\n", npat);
- pat = &lifepatterns[npat];
- x = rand() % (grid->w - pat->w);
- y = rand() % (grid->h - pat->h);
- for (j=0; j<pat->h; j++) {
- for (i=0; i<pat->w; i++) {
- cx = x + i;
- cy = y + j;
- if (cx >= grid->w || cy >= grid->h)
- continue;
- cell = CELL_GET(grid, cx, cy);
- age = (pat->pat[pat->w*j + i] - '0') * 27;
- if (age != 0)
- cell->newage = age;
- cell->forced_color = color;
- cell->age = cell->newage;
- // cell_redraw(cell, grid);
- }
- }
-}
-
-static int
-grid_redraw(struct grid *grid, int w, int h)
-{
- struct cell *cell;
- int i,j;
- Evas_Object *o;
-
- grid->cell_pix_w = w / grid->w;
- grid->cell_pix_h = h / grid->h;
- grid->pix_w = (w / grid->w) * grid->w;
- grid->pix_h = (h / grid->h) * grid->h;
- if (DEBUG)
- printf("redraw: container %d %d cell %d %d\n", w, h, grid->cell_pix_w, grid->cell_pix_h);
-
- evas_object_image_fill_set(grid->image, 0, 0, grid->pix_w, grid->pix_h);
- evas_object_image_size_set (grid->image, grid->pix_w, grid->pix_h);
- evas_object_resize(grid->image, w, h);
- /* XXX could be optimized to avoid flickering on resize */
- if (grid->mem)
- free(grid->mem);
- grid->mem = calloc(w * h, sizeof(int));
- if (!grid->mem)
- err(1, "could not calloc grid->mem");
- evas_object_image_data_set(grid->image, (void *) grid->mem);
- for (j=0; j<grid->h; j++) {
- for (i=0; i<grid->w; i++) {
- cell = CELL_GET(grid, i, j);
- cell_redraw(cell, grid);
- }
- }
-}
-
-static int
-cell_neighbours_count(struct cell *cell, struct grid *grid)
-{
- struct cell *ncell;
- int m, n, cx, cy;
- int count;
-
- count = 0;
- for (n=-1; n<=1; n++) {
- for (m=-1; m<=1; m++) {
- if (m == 0 && n == 0)
- continue;
- cx = cell->x + m;
- cy = cell->y + n;
- if (cx < 0 || cx >= grid->w || cy < 0 || cy >= grid->h)
- continue;
- ncell = CELL_GET(grid, cx, cy);
- if (ncell->age > 0)
- count++;
- }
- }
-
- return count;
-}
-
-static void
-cell_redraw(struct cell *c, struct grid *grid)
-{
- u_int8_t r, g, b, a;
- int x, y, w, h;
- int i, j;
- int color;
-
- if (c->forced_color && c->age > 0) {
- r = (c->forced_color & 0xff0000) >> 16;
- g = (c->forced_color & 0xff00) >> 8;
- b = (c->forced_color & 0xff);
- } else if (c->age < 100) {
- r = (c->age > 0) ? 128 : 0;
- g = (c->age > 0) ? (33 + c->age * 7) : 0;
- b = 0;
- } else if (c->age < CONWAY_GROW_DIE - 50) {
- r = 128 - c->age;
- g = 255 - c->age;
- b = (c->age - 100) * 2;
- } else {
- r = 255;
- g = (c->age % 2) * 255;
- b = 255;
- }
- a = 255;
- if (r == c->r && g == c->g && b == c->b)
- return;
- c->r = r;
- c->g = g;
- c->b = b;
-
- x = c->x * grid->cell_pix_w;
- y = c->y * grid->cell_pix_h;
- w = grid->cell_pix_w;
- h = grid->cell_pix_h;
- for (j=y; j<y+h; j++) {
- for (i=x; i<x+w; i++) {
- color = 0xff000000 + (r << 16) + (g << 8) + (b);
- grid->mem[j*grid->pix_w + i] = color;
- }
- }
-}
-
-static void
-grid_mouse_down(void *data,
- Evas *evas,
- Evas_Object *child,
- void *event_info)
-{
- Evas_Coord x, y, w, h;
- Evas_Event_Mouse_Up *evt = event_info;
- struct grid *grid;
-
- grid = data;
- grid_inject_pattern(grid, 0);
-}
-
-Evas_Object *
-elife_smart_new(Evas *e)
-{
- return elife_object_new(e);
-}
-
-static void
-elife_on_refresh(void *data, Evas_Object *o, void *event_info)
-{
- Evas_Coord x, y, w, h;
- Evas_Object *child;
- struct grid *grid;
-
- grid = evas_object_data_get(o, "grid");
-
- grid_evolution(grid);
-}
-
-static Evas_Object *
-elife_object_new(Evas *evas)
-{
- Evas_Object *elife_object;
- struct grid *grid;
-
- elife_object = evas_object_smart_add(evas,
- _elife_object_smart_get());
- grid = grid_new(elife_object, NCELL_X, NCELL_Y, ELIFE_MODE_CONWAY_GROW);
- evas_object_data_set(elife_object, "grid", grid);
- evas_object_smart_callback_add(elife_object,
- "refresh",
- elife_on_refresh,
- NULL);
-
- return elife_object;
-}
-
-static Evas_Smart *
-_elife_object_smart_get(void)
-{
- static Evas_Smart *smart = NULL;
-
- if (smart)
- return smart;
-
- smart = evas_smart_class_new(&_G.klass);
- return smart;
-}
-
-static void
-_elife_object_del(Evas_Object *o)
-{
- Evas_Object *child;
- struct grid *grid;
- Eina_List *list;
-
- list = evas_object_smart_members_get(o);
- EINA_LIST_FREE(list, child) {
- evas_object_smart_member_del(child);
- evas_object_del(child);
- }
- grid = evas_object_data_del(o, "grid");
- grid_del(grid);
-}
-
-static void
-_elife_object_move(Evas_Object *o, Evas_Coord x, Evas_Coord y)
-{
- Evas_Coord orig_x, orig_y, dx, dy;
- Eina_List *lst;
- Evas_Object *child;
- void *data;
-
- if (DEBUG)
- printf("oject_move: %d %d\n", x, y);
- evas_object_geometry_get(o, &orig_x, &orig_y, NULL, NULL);
- dx = x - orig_x;
- dy = y - orig_y;
-
- lst = evas_object_smart_members_get(o);
- EINA_LIST_FREE(lst, data) {
- child = data;
- evas_object_geometry_get(child, &orig_x, &orig_y, NULL, NULL);
- evas_object_move(child, orig_x + dx, orig_y + dy);
- }
-}
-
-static void
-_elife_object_resize(Evas_Object *o, Evas_Coord w, Evas_Coord h)
-{
- struct grid *grid;
-
- if (DEBUG)
- printf("oject_resize: %d %d\n", w, h);
- grid = evas_object_data_get(o, "grid");
- grid_redraw(grid, w, h);
-}
-
-void *
-xmalloc(size_t size)
-{
- void *x;
-
- x = malloc(size);
- if (!x)
- err(1, "Error: failed to allocate %d", size);
- return x;
-}
-