main.c: line 232 // OLD // imageformat = '\0'; // NEW // imageformat = 'P'; keyin.c: line 359 // OLD // free_loadscript(); // NEW // //free_loadscript(); [DMG: allow partial scripts to be written without clearing script buffer] keyin.c: // OLD // case 'i': imageformat='\0'; getinputwstring("Imageformat for saving patterns: A R D P (default= automatic): "); // NEW // case 'i': imageformat='P'; // DMG: old default of '\0' often resulted in #D-format files, // which are much less likely to be readable by other Life software. getinputwstring("Imageformat for saving patterns: A R D P (default=P): "); defs.h: // OLD // #define MARK '*' /* on_cell character */ // NEW // #define MARK '*' /* on_cell characters */ #define MARK2 'o' // DMG: allow other common ON characters #define MARK3 'O' #define MARK4 '%' lifeconv.c: lines 21-22 become new lines 21-32 [not really relevant, separate from Xlife] // OLD // #define MARK '*' #define SPACE '.' // NEW // #define MARK '*' #define MARK2 'o' #define MARK3 'O' #define MARK4 '%' // 'x', 'X', '1', '2', 'a', 'b', etc. are also sometimes used as ON markers, // but reading these as such will often result in nonworking patterns -- // because they mark, e.g., alternate locations for rotors, or other subtleties #define SPACE '.' // don't need the following, since we always write '.' when saving patterns, // and on input we read anything that isn't MARK|MARK2/3/4 as an OFF cell. //#define SPACE2 ' ' //#define SPACE3 ',' file.c: line 481 // OLD // linect = 0; // NEW // linect = -1; // DMG: don't count header as first line of pattern file.c: line 530 // OLD // linect=0; // NEW // linect = -1; // DMG: don't count header as first line of pattern file.c: line 592 // OLD // if (*cp == MARK) if (*cp == MARK || *cp == MARK2 || *cp == MARK3 || *cp == MARK4) file.c: new lines 538-550, after "case 'M'" and two closing curly braces... // NEW // else if (buf[0]=='x') // DMG: also allow standard RLE with no #M header { if (buf[1]=='=' || (buf[1]==' ' && buf[2]=='=')) { loadmode = M_RUNLENGT; xoff = yoff = 0; colct = 0; linect = -1; // DMG: don't count header as first line of pattern // DMG: don't parse the header for now; we don't care about width and height // -- later, should look for h= and v= tags to allow changing pattern centers } } file.c: might need to add "case '\r'" to handle Windows-style files -- though actually it appears to work fine without it, probably because \r always comes at the very end of the line anyway. Added "i=0; n=0;" so that extraneous characters now reset the column and repeat count. Not that this case is too likely to be an issue: people don't seem to write nonstandard RLE very often. // OLD // case ' ': case '\n': case '\t': break; default: *cp = '!'; cp--; // NEW // case ' ': case '\n': case '\r': case '\t': break; default: i=0; n=0; *cp = '!'; cp--; file.c: lines 88-95 become new lines 88-98 // OLD // char *addlifeext(char *buf) { int len=strlen(buf); if(strcmp(buf+len-5,".life")){ return(".life"); } return(""); } // NEW // char *addlifeext(char *buf) { int len=strlen(buf); // DMG: allow "rle" and "lif" extensions for reading and writing, if typed in manually // -- eventually, should add a sticky preference for a default extension if((strcmp(buf+len-5,".life") != 0) && (strcmp(buf+len-4,".lif") != 0) && (strcmp(buf+len-4,".rle") != 0)) return(".life"); return(""); } file.c: don't count comment lines as pattern lines // NEW // case 'C': buf[COMMLEN-1]='\0'; (void) strcpy(comments[numcomments],buf+2); comments[numcomments][strlen(comments[numcomments])-1]='\0'; if (numcomments <= MAXCOMMENTS-2) numcomments++; // DMG: TODO: check MAXCOMMENTS, COMMLEN for reasonable lengths // -- and don't count interleaved comment lines as pattern lines: linect--; // this should work OK because linect will be reset whenever a // pattern header line comes along. It's an ugly hack though. // TODO: refactor to do linect++ only when it's actually wanted... break; case 'r': { int i, k; k=0; for(i=2;buf[i];i++) if (buf[i] > ' ') break; if (buf[i]) { for(;(buf[i]>='0')&&(buf[i]<'0'+10);i++) k|=(1<<(buf[i]-'0')); live=k; k=0; if(buf[i]=='/') { for(i++;(buf[i]>='0')&&(buf[i]<'0'+10);i++) k|=(1<<(buf[i]-'0')); born=k; } gentab(); } linect--; // DMG: don't count a rule line as a pattern line