Index: apps/plugins/rocklife.c =================================================================== --- apps/plugins/rocklife.c (revision 27931) +++ apps/plugins/rocklife.c (working copy) @@ -58,6 +58,10 @@ * - nicer colours for pixels with respect to age * - editor for start patterns * - probably tons of speed-up opportunities + * - The header may also contain parameters for setting + * new rule sets. Implement engine with fillable + * parameters to allow more general automata and parse + * extra tokens */ #include "plugin.h" @@ -126,50 +130,305 @@ /*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, i, xmid, ymid, w_off, h_off; bool comment; + lastchar = ' '; + 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) { + 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': /* These come in two varieties */ nc = rb->read(fd, &c, 1); - if (nc <= 0) - break; - - switch(c) { - case '!': + if (c == '#') { 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++; + while (c != '\n') { + nc = rb->read(fd, &c, 1); + if (nc <= 0) + break; } + comment = false; + nc = rb->read(fd, &c, 1); + } + if (c == 'x') { /* test for RLE type of file */ + while (c != '\n') { + nc = rb->read(fd, &c, 1); + if (nc <= 0) + break; + header[i] = c; + i++; + } + header[i] = '\0'; + w_off = rb->atoi(rb->strtok_r(header, " ,=y\n\r", &marker)) + / 2; + h_off = rb->atoi(rb->strtok_r(NULL, " ,=y\n\r", &marker)) / 2; + + while(true) { + nc = rb->read(fd, &c, 1); + if (nc <= 0) + break; + if (c == '!') + break; + if (c == 'x' || c =='y') + c = 'o'; + else if (!comment && c >= 48 && c <= 57) + cnt = cnt * 10 + (int) c - 48; + else { + 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; + } + } + } + } + else if (c == '!') { /* LIF 1.05 type */ + comment = true; + 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 'c': /* Life files */ + nc = rb->read(fd, &c, 1); + if (nc <=0) break; - case '\n': - y++; - x=0; - comment = false; - break; - default: - 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] = ' '; + while (c != '\n') { + nc = rb->read(fd, &c, 1); + if (nc <= 0) + break; + header[i] = c; + i++; + } + 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; + if (c == 'x' || c == 'y') + 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, " \n\r\0", + &marker)); + comment = false; + x = 0; + y = 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; } Index: apps/plugins/viewers.config =================================================================== --- apps/plugins/viewers.config (revision 27931) +++ 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,-