diff options
Diffstat (limited to 'gg_elife/src/elife_evas_smart.c')
-rw-r--r-- | gg_elife/src/elife_evas_smart.c | 558 |
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; -} - |