Index: apps/plugins/rocklife.c =================================================================== --- apps/plugins/rocklife.c (revision 28196) +++ apps/plugins/rocklife.c (working copy) @@ -20,7 +20,7 @@ ****************************************************************************/ /* - * This is an implementatino of Conway's Game of Life + * This is an implementation of Conway's Game of Life * * from http://en.wikipedia.org/wiki/Conway's_Game_of_Life: * @@ -90,8 +90,9 @@ int generation = 0; int population = 0; int status_line = 0; +unsigned int s_vect[9] = {0, 0, 1, 1, 0, 0, 0, 0, 0}; +unsigned int b_vect[9] = {0, 0, 0, 1, 0, 0, 0, 0, 0}; - static inline bool is_valid_cell(int x, int y) { return (x >= 0 && x < GRID_W && y >= 0 && y < GRID_H); @@ -126,50 +127,391 @@ /*fill grid with pattern from file (viewer mode)*/ static bool load_cellfile(const char *file, char *pgrid){ - int fd; + int fd, px, py; fd = rb->open(file, O_RDONLY); if (fd<0) return false; init_grid(pgrid); - char c; - int nc, x, y, xmid, ymid; + char c, ext_c, header[30], *ext_s, lastchar; + char *marker; + int nc, x, y, cnt, xmid, ymid, w_off, h_off; bool comment; + char s_survival[10], s_birth[10]; + s_birth[0] = '\0'; + s_survival[0] = '\0'; + lastchar = ' '; + unsigned short int i; + i = 0; + cnt = 0; x=0; y=0; xmid = (GRID_W>>1) - 2; ymid = (GRID_H>>1) - 2; comment = false; + ext_s = rb->strrchr(file, '.'); /* Get the file extension */ + if (rb->strcasecmp(ext_s, ".cells") == 0) + ext_c = 'a'; + if (rb->strcasecmp(ext_s, ".l") == 0) + ext_c = 'b'; + if (rb->strcasecmp(ext_s, ".rle") == 0) + ext_c = 'b'; + if (rb->strcasecmp(ext_s, ".lif") == 0 + || rb->strcasecmp(ext_s, ".life") == 0) + ext_c = 'c'; + switch(ext_c) { /* handle different file types */ + case 'a': + while (true) { + nc = rb->read(fd, &c, 1); + if (nc <= 0) + break; - while (true) { - nc = rb->read(fd, &c, 1); - if (nc <= 0) + switch(c) { + case '!': + comment = true; + break; + case '.': + if (!comment) + x++; + break; + case 'O': + if (!comment) { + if (is_valid_cell(xmid + x, ymid + y)) + set_cell(xmid + x, ymid + y, pgrid); + x++; + } + break; + case '\n': + y++; + x=0; + comment = false; + break; + default: + break; + } + } + break; + case 'b': + while (true) { + nc = rb->read(fd, &c, 1); + if (nc <= 0) + break; + if (c == '#') { + while (c != '\n') { + nc = rb->read(fd, &c, 1); + if (nc <= 0) + break; + } + } + else if (c == '!') { /* Test for Life 1.05 type */ + header[0] = '\0'; + comment = true; + i = 0; + ext_c = 'l'; + break; + } + else if (c == 'x') { /* Test for RLE type */ + i = 0; + do { + nc = rb->read(fd, &c, 1); + if (nc <= 0) + break; + header[i] = c; + i++; + } while (c != '\n'); + header[i] = '\0'; + ext_c = 'r'; + break; + } + } + switch(ext_c) { + case 'r': + w_off = rb->atoi(rb->strtok_r(header, " ,=", &marker)) + / 2; + h_off = rb->atoi(rb->strtok_r(NULL, " ,=y\0\n\r", &marker)) / 2; + /* Read new rules if any */ + if (rb->strcmp(rb->strtok_r(NULL, " ,rule", + &marker), "=") == 0) { + for (i = 0; i < 9; i++) { + b_vect[i] = 0; + s_vect[i] = 0; + } + rb->strcpy(s_birth, rb->strtok_r(NULL, "B/", &marker)); + for (i = 0; s_birth[i] != '\0'; i++) { + b_vect[i] = s_birth[i] - '0'; + } + rb->strcpy(s_survival, rb->strtok_r(NULL, "S\n\r\0", &marker)); + for (i = 0; s_survival[i] != '\0'; i++) { + s_vect[i] = s_survival[i] - '0'; + } + /* format the contents of the arrays to vector form */ + for (i = 0; i < 9; i++) { + if (b_vect[8 - i] != 0) { + b_vect[b_vect[8 - i]] = 1; + b_vect[8 - i] = 0; + } + if (s_vect[8 - i] != 0) { + s_vect[s_vect[8 - i]] = 1; + s_vect[8 - i] = 0; + } + } + } + header[0] = '\0'; + while(true) { + nc = rb->read(fd, &c, 1); + if (nc <= 0) + break; + if (c == '!') + break; + else if (c == 'x' || c =='y' || c == 'z') + c = 'o'; + else if (!comment && c >= 48 && c <= 57) + cnt = cnt * 10 + (int) c - 48; + switch(c) { /* parse body chars */ + case 'b': + if (!comment) { + x++; + while (cnt > 1) { + cnt--; + x++; + } + cnt = 0; + } + break; + case 'o': + if (!comment) { + if (is_valid_cell(xmid - w_off + x, + ymid - h_off + y)) + set_cell(xmid - w_off + x, + ymid - h_off + y, pgrid); + x++; + while (cnt > 1) { + cnt--; + if (is_valid_cell(xmid - w_off + x, + ymid - h_off + y)) + set_cell(xmid - w_off + x, ymid - h_off + y, + pgrid); + x++; + } + cnt = 0; + } + break; + case '$': + if (!comment) { + y++; + x = 0; + } + if (lastchar >= 48 && lastchar <= 57) + cnt = 0; /* Ignore numbers that precede $ */ + break; + case '#': + comment = true; + break; + default: + break; + } + lastchar = c; + rb->yield(); + } break; - switch(c) { - case '!': - comment = true; - case '.': - if (!comment) - x++; - break; - case 'O': - if (!comment) { - if (is_valid_cell(xmid + x, ymid + y)) - set_cell(xmid + x, ymid + y, pgrid); - x++; + case 'l': + while (true) { + nc = rb->read(fd, &c, 1); + if (nc <= 0) + break; + if (!comment && c >= 48 && c <= 57) /* c is a number */ + cnt = cnt * 10 + (int) c - 48; + else { + switch(c) { + case '!': + comment = true; + break; + case '.': + if (!comment){ + x++; + while (cnt > 1) { + cnt--; + x++; + } + cnt = 0; + } + break; + case '*': + case 'O': + if (!comment) { + if (is_valid_cell(xmid / 10 + x, + ymid / 10 + y)) + set_cell(xmid / 10 + x, + ymid /10 + y, pgrid); + x++; + while (cnt > 1) { + cnt--; + if (is_valid_cell(xmid / 10 + x, + ymid / 10 + y)) + set_cell(xmid / 10 + x, + ymid / 10 + y, pgrid); + x++; + } + cnt = 0; + } + break; + case '\n': + if (!comment) { + y++; + x = 0; + } + cnt = 0; + comment = false; + break; + + default: + break; + } + } + lastchar = c; } break; - case '\n': - y++; - x=0; - comment = false; - break; default: break; } - } + case 'c': /* Life files */ + nc = rb->read(fd, &c, 1); + if (nc <= 0) + break; + i = 0; + while (c != '\n') { + nc = rb->read(fd, &c, 1); + if (nc <= 0) + break; + header[i] = c; + i++; + } + header[i] = '\0'; + if (!rb->strncmp(rb->strrchr(header, '.'), ".06", 3)) { + while (true) { + header[0] = '\0'; + i = 0; + do { + nc = rb->read(fd, &c, 1); + if (nc <= 0) + break; + header[i] = c; + i++; + } while (c != '\n'); + header[i] = '\0'; + x = rb->atoi(rb->strtok_r(header, " \n", &marker)); + y = rb->atoi(rb->strtok_r(NULL, " \n", &marker)); + if (is_valid_cell(x, y)) + set_cell(x, y, pgrid); + } + } + else rb->splash(HZ, "Life 1.05 loaded"); + if (header[0] == '#' && header[1] == 'P') { + px = rb->atoi(rb->strtok_r(header, " #P", &marker)); + py = rb->atoi(rb->strtok_r(NULL, " \n\r\0", &marker)); + } + while (true) { + nc = rb->read(fd, &c, 1); + if (nc <= 0) + break; + i = 0; + header[i] = '\0'; + if (c == 'x' || c == 'y' || c == 'z') + c = '*'; /* Treat all living states the same */ + switch(c) { + case '#': + comment = true; + break; + case 'P': + if (lastchar == '#') { + i = 0; + do { + nc = rb->read(fd, &c, 1); + if (nc <= 0) + break; + header[i] = c; + i++; + } while (c != '\n'); + header[i] = '\0'; + px = rb->atoi(rb->strtok_r(header, + " ", &marker)); + py = rb->atoi(rb->strtok_r(NULL, "y ,\n\r\0", + &marker)); + comment = false; + x = 0; + y = 0; + } + break; + /* Read rule information */ + case 'R': + if (lastchar == '#') { + /* clear birth/survival vectors */ + for (i = 0; i < 9; i++) { + b_vect[i] = 0; + s_vect[i] = 0; + } + i = 0; + do { + nc = rb->read(fd, &c, 1); + if (nc <= 0) + break; + header[i] = c; + i++; + } while (c != '\n'); + + header[i] = '\0'; + rb->strcpy(s_survival, rb->strtok_r(header, " /", + &marker)); + for (i = 0; s_survival[i] != '\0'; i++) { + s_vect[i] = s_survival[i] - '0'; + } + for (i = 0; i < 9; i++) { + s_vect[s_vect[i]] = 1; + s_vect[i] = 0; + } + rb->strcpy(s_birth, rb->strtok_r(NULL, " \n\r\0", + &marker)); + for (i = 0; s_birth[i] != '\0'; i++) { + b_vect[i] = s_birth[i] - '0'; + } + for (i = 0; i < 9; i++) { + b_vect[b_vect[i]] = 1; + b_vect[i] = 0; + } + } + break; + case '.': + if (!comment) + x++; + break; + case '*': + if (!comment) { + if (is_valid_cell(xmid + px + x, ymid + py + y)) + set_cell(xmid + px + x, + ymid + py + y, pgrid); + x++; + } + break; + case '\n': + if (!comment) { + y++; + x = 0; + } + comment = false; + break; + default: + break; + } + lastchar = c; + } + break; + + default: + rb->splash(HZ, "Unrecognized format"); + break; + } rb->close(fd); return true; } @@ -310,7 +652,11 @@ #if LCD_DEPTH > 1 rb->lcd_set_foreground( LCD_BLACK ); #endif - rb->lcd_putsf(0, 0, "g:%d p:%d", generation, population); + rb->lcd_putsf(0, 0, "g:%d p:%d B:%d%d%d%d%d%d%d%d%d S:%d%d%d%d%d%d%d%d%d", + generation, population, b_vect[0], b_vect[1], b_vect[2], + b_vect[3], b_vect[4], b_vect[5], b_vect[6], b_vect[7], + b_vect[8], s_vect[0], s_vect[1], s_vect[2], s_vect[3], + s_vect[4], s_vect[5], s_vect[6], s_vect[7], s_vect[8]); } rb->lcd_update(); } @@ -328,6 +674,8 @@ int empty_cells = 0; int alive_cells; bool result; + extern unsigned int s_vect[]; + extern unsigned int b_vect[]; /* count empty neighbour cells */ if(n[0]==0) empty_cells++; @@ -343,12 +691,12 @@ alive_cells = 8 - empty_cells; if (n[4]) { - /* If the cell is alive, it stays alive iff it has 2 or 3 alive neighbours */ - result = (alive_cells==2 || alive_cells==3); + /* Check result against survival vector */ + result = (bool) s_vect[alive_cells]; } else { - /* If the cell is dead, it gets alive iff it has 3 alive neighbours */ - result = (alive_cells==3); + /* If dead, check result against birth vector */ + result = (bool) b_vect[alive_cells]; } return result; @@ -535,7 +883,8 @@ /* show new generation */ rb->yield(); show_grid(pgrid); - button = pluginlib_getaction(0, plugin_contexts, ARRAYLEN(plugin_contexts)); + button = pluginlib_getaction(0, plugin_contexts, + ARRAYLEN(plugin_contexts)); switch(button) { case ROCKLIFE_PLAY_PAUSE: case ROCKLIFE_QUIT: Index: apps/plugins/viewers.config =================================================================== --- apps/plugins/viewers.config (revision 28196) +++ apps/plugins/viewers.config (working copy) @@ -59,6 +59,10 @@ colours,apps/text_editor,11 ssg,games/superdom,- cells,games/rocklife,- +l,games/rocklife,- +rle,games/rocklife,- +lif,games/rocklife,- +life,games/rocklife,- link,viewers/shortcuts_view,- *,viewers/shortcuts_append,- *,apps/md5sum,-