1 /* 2 * XLife Copyright 1989 Jon Bennett jb7m+@andrew.cmu.edu, jcrb@cs.cmu.edu 3 * 4 * Permission to use, copy, modify, distribute, and sell this software and its 5 * documentation for any purpose is hereby granted without fee, provided that 6 * the above copyright notice appear in all copies and that both that 7 * copyright notice and this permission notice appear in supporting 8 * documentation, and that the name of the copyright holders not be used in 9 * advertising or publicity pertaining to distribution of the software without 10 * specific, written prior permission. The copyright holders make no 11 * representations about the suitability of this software for any purpose. It 12 * is provided "as is" without express or implied warranty. 13 * 14 * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, 15 * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO 16 * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR 17 * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, 18 * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER 19 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 20 * PERFORMANCE OF THIS SOFTWARE. 21 */ 22 23 /* 24 A lot of modifications were added at 2001, 2011-14 by Vladimir Lidovski vol.litwr@gmail.com 25 (C) This version of XLife may be used under the same conditions as mentioned above 26 $Id: defs.h 278 2014-01-13 18:19:40Z litwr $ 27 */ 28 29 #ifdef __GNUCC__ 30 ; /* bogus semi-colon to appease the GNU god */ 31 #endif /* __GNUCC__ */ 32 #include <stdio.h> 33 #include <X11/Xos.h> 34 #include <X11/Xlib.h> 35 #include <X11/Xutil.h> 36 #include <X11/cursorfont.h> 37 #include <X11/keysym.h> 38 #include <X11/keysymdef.h> 39 #include <sys/time.h> 40 #include <string.h> 41 #include "common.h" 42 43 /*#define SMALLFONT*/ 44 #ifndef SMALLFONT 45 #define NORMALFONT "9x15" 46 #define FONTHEIGHT 15 47 #define FONTWIDTH 9 48 #else 49 #define NORMALFONT "8x13" 50 #define FONTHEIGHT 13 51 #define FONTWIDTH 8 52 #endif 53 54 #ifndef VFREQ 55 #define VFREQ 0 56 #endif 57 58 #define MAXSCALE 6 /* 1:64 */ 59 #define MINSCALE -10 /* 1024:1 */ 60 61 #define BORDERWIDTH 2 62 63 #define INPUTXOFF 2 64 #define INPUTH 20 65 #define INPUTYOFF FONTHEIGHT 66 #define INPUTLEN 125 67 #define INPUTTEXTLEN (INPUTLEN - INPUTFROMLEN) 68 69 #define COORDXOFF 2 70 #define COORDYOFF FONTHEIGHT 71 #define COORDW 200 72 73 #define STATEOFF 4 74 75 /* mouse coordinates to life-universe coordinates */ 76 #define SCALE(x) shr((x), scale) 77 #define RSCALE(x) shl((int)(x), scale) 78 #define XPOS(x) ((u32bits)(SCALE(x) + xpos)) 79 #define YPOS(y) ((u32bits)(SCALE(y) + ypos)) 80 81 /* life-universe coordinates to mouse coordinates */ 82 #define RXPOS(x) RSCALE((x) - xpos) 83 #define RYPOS(y) RSCALE((y) - ypos) 84 85 /* mouse coordinates to cell coords (relative to top left of screen) */ 86 #define MOUSE2CELL(n) ((n) & shl(0xffffffff, scale)) 87 88 /* this magic number is roughly halfway through the range of unsigned long */ 89 /* it must be multiple of 256 for the scaling */ 90 /* it must be multiple of 8 for the torus mode */ 91 #define STARTX 2147483648U 92 #define STARTY 2147483648U 93 94 /* the program's run states */ 95 #define STOP 0x1 /* single-stepping */ 96 #define HIDE 0x2 /* evolving, no per-generation display */ 97 #define RUN 0x4 /* evolving with per-generation display */ 98 99 /* time-delays for generation evolution */ 100 #define DELAY_FAST 0 101 #define DELAY_MED 250 102 #define DELAY_SLOW 500 103 #define DELAY_INCREMENT 10 104 105 #define DEADTIME 10 /* nuke a tile when it's been dead this long */ 106 107 #define PATCH_LOG "new.transitions" 108 109 #define LOADEXT ".l" 110 111 #define TRUE 1 112 #define FALSE 0 113 114 /* 115 * If you don't want n-state capability, define this to 1 in the Makefile 116 * to save some storage and reduce the program size. 117 */ 118 #define STATEBITS 8 119 #define MAXSTATES (1<<STATEBITS) 120 #define BADSTATE 0xff /* out-of-band cell-state value */ 121 122 int is_state(char); /* is char a valid state indicator? */ 123 int stoi(char); /* state character to int */ 124 char itos(int); /* int to state character */ 125 126 #if STATEBITS <= 8 127 typedef u8bits cell_t; /* allows 256 states per cell */ 128 #elif STATEBITS <= 16 129 typedef u16bits cell_t; /* allows 65536 states per cell */ 130 #else 131 typedef u32bits cell_t; /* are you serious? */ 132 #endif 133 134 #define PATNAMESIZ 256 /* It's an arbitrary limit, but probably enough */ 135 136 typedef struct lq { 137 unsigned long loadtime; 138 char patname[PATNAMESIZ]; 139 int relpath; 140 coord_t hotx, hoty; 141 int rxx, rxy, ryx, ryy; 142 struct lq *next; 143 } LoadReq; 144 145 typedef struct {int xi; int yi;} offsets; 146 147 /* definitions for geometric transformations */ 148 149 /* Get around "%" bogosity, and compute mod *correctly*. */ 150 #define mod(m,n) (((m)>=0)?((m)%(n)):((n)-1-(-(m)+(n)-1)%(n))) 151 152 #define max(x, y) ((x) > (y) ? (x) : (y)) 153 #define min(x, y) ((x) > (y) ? (y) : (x)) 154 #define abs(x) ((x) > 0 ? (x) : (-(x))) 155 #define sgn(x) (((x) > 0) ? 1 : ((x) < 0) ? -1 : 0) 156 #define shr(x, n) ((n) < 0 ? ((x) << -(n)) : ((x) >> (n))) 157 #define shl(x, n) ((n) < 0 ? ((x) >> -(n)) : ((x) << (n))) 158 159 /* compute coordinate transform for rotations */ 160 /* yes, macros are equivalent, but this makes the meaning clearer (maybe) */ 161 #define tx(x,y,rxx,rxy) ((rxx)*(x)+(rxy)*(y)) 162 #define ty(x,y,ryx,ryy) ((ryx)*(x)+(ryy)*(y)) 163 #define Tx(x, y) (tx(x,y,txx,txy)+loadx) 164 #define Ty(x, y) (ty(x,y,tyx,tyy)+loady) 165 #define TX(x, y) (Tx(x,y)-xpos) 166 #define TY(x, y) (Ty(x,y)-ypos) 167 168 #ifdef SVR4 169 #define srandom(n) srand48(n) 170 #define random() lrand48() 171 #endif 172 173 /* tile.c */ /* don't change BOXSIZE! */ 174 #define BOXSIZE 8 175 176 typedef union { 177 struct twostate_t { 178 u32bits live1, live2, olive1, olive2; 179 u32bits on[BOXSIZE]; 180 } twostate; /* 48 bytes */ 181 struct nstate_t { 182 union { 183 u32bits live[BOXSIZE][2]; 184 cell_t cell[BOXSIZE][BOXSIZE]; 185 }; 186 union { 187 u32bits l[8]; //0,1 - up; 2,3 - down 188 cell_t c[4][BOXSIZE]; //0 - up, 1 - down, 2 - left, 3 - right 189 }; 190 } nstate; /* 64+32=96 bytes (assuming char-sized cells) */ 191 struct pstate_t { 192 union { 193 u32bits live[BOXSIZE][2]; 194 cell_t cell[BOXSIZE][BOXSIZE]; 195 }; 196 cell_t ocell[BOXSIZE][BOXSIZE]; 197 union { 198 u32bits l[8]; //0,1 - up; 2,3 - down 199 cell_t c[4][BOXSIZE]; //0 - up, 1 - down, 2 - left, 3 - right 200 }; 201 } pstate; /* 128+32=160 bytes (assuming char-sized cells) */ 202 struct gstate_t { 203 union { 204 u32bits live[BOXSIZE][2]; 205 u16bits slive[BOXSIZE][4]; 206 cell_t cell[BOXSIZE][BOXSIZE]; 207 }; 208 u32bits on[BOXSIZE]; 209 } gstate; /* 64+32=96 bytes (assuming char-sized cells) */ 210 } cellbox; 211 212 typedef struct tile_t { 213 coord_t x, y; 214 short dead, nochg, nochgcp; 215 struct tile_t *up, *dn, *lf, *rt, *fore, *next, *hfore, *hnext; 216 /* MUST be last in the structure or our dynamic allocation will fail */ 217 cellbox cells; 218 } tile; 219 220 /* 221 * A `pattern' is a linked list of tiles with its own context globals. 222 * The universe may contain multiple patterns; they are overlayed on 223 * the screen, but can be manipulated independently and evolve independently. 224 */ 225 #ifndef HASHBITS 226 #define HASHBITS 20 227 #endif 228 #define HASHSIZE (1 << HASHBITS) 229 //#define HASH(x,y,HXM,HXS,HYM) (shl((((x)%65521)&HXM),HXS) + ((((y)%65537) >> 3)&HYM)) 230 #define HASH(x,y,HXM,HXS,HYM) (shl(((x)&HXM),HXS) + (((y) >> 3)&HYM)) 231 typedef struct { 232 tile *tiles; /* head of the cell list */ 233 cellcount_t tilecount; /* count of boxes */ 234 cellcount_t chgcount; /* count of changes */ 235 unsigned long generations; /* context generation number */ 236 u32bits osc1, osc2, osc3, osc4, osc5; /* for oscillator check */ 237 //cellcount_t population; /* cellcount total */ 238 cellcount_t cellcount[MAXSTATES]; /* count of cells */ 239 tile *hashlist[HASHSIZE]; /* hash list */ 240 unsigned hxm, hym; /* hash coeff */ 241 int hxs; 242 coord_t xmax, xmin, ymax, ymin; 243 unsigned cellmass; 244 char *pattern_name; 245 } pattern; 246 247 /* file_misc.c */ 248 void name_file(void); 249 void comment(void); 250 251 /* gentab.c */ 252 void gentab(void), gentab2(void), gentab3(void), gentab4(void), genatab4(void), genatab5(void); 253 254 /* help.c */ 255 void help(void); 256 void pseudocolor_msg(void); 257 void redraw_help(void); 258 void viewvars(void); 259 void redraw_viewvars(void); 260 void view_comments(void); 261 int redraw_comments(void); 262 void view_slashinfo(void); 263 void redraw_slashinfo(void); 264 265 /* key.c */ 266 void getxstring(void); 267 void cursorshow(Window, int, int, GC); 268 void set_transition(void); 269 void test_transition(void); 270 void announce_and_wait(int); 271 cell_t patch_transition(cell_t, cell_t, cell_t, cell_t, cell_t); 272 cell_t patch_transition8(cell_t, cell_t, cell_t, cell_t, cell_t, cell_t, cell_t, cell_t, cell_t); 273 void wait_activity(int); 274 275 /* main.c */ 276 void DoKeyIn(char*); 277 int DoKeySymIn(KeySym); 278 void Motion(void), DoResize(void), DoExpose(Window); 279 void Button(void), Release(void); 280 void ResizeLW(int); 281 void alloc_states(unsigned, unsigned); 282 void redraw_lifew(void); 283 void fixpatterntopology(void); 284 void make_delay(long, long); 285 int rules_changed(void); 286 void set_active_rules(char*, int); 287 extern coord_t savex, savey; 288 289 /* tentative.c */ 290 void boxpattern(int); 291 int comparepatterns(pattern*, pattern*); 292 void copy_tentative(void); 293 void copypattern(pattern*, pattern*); 294 void flipload(void); 295 void make_tentative(coord_t, coord_t, coord_t, coord_t); 296 void moveload(void); 297 void prep_tentative(void); 298 void turnload(void); 299 300 /* tile.c declarations are in tile.h */ 301 302 /* utils.c */ 303 void announce(const char*); 304 void announce_and_delay(const char*); 305 void benchmark(void); 306 void fatal(const char*); 307 void drawcell(coord_t, coord_t, cell_t); 308 void drawpivot(void); 309 void drawbox(coord_t, coord_t, coord_t, coord_t, int); 310 void erasebox(coord_t, coord_t, coord_t, coord_t); 311 unsigned long mstime(void); 312 void showcoord(const int); 313 void showrules(void); 314 void randomize(void); 315 void settimeout(unsigned long); 316 void color_button(int, int, int); 317 void setcolor(int, unsigned long, unsigned long); 318 void entercolor(unsigned long, unsigned long); 319 void set_paintcolor(void); 320 void showstates(void); 321 322 /* UNIX interface */ 323 #define SYSERR strerror(errno) 324 325 /* X I/O state information */ 326 extern Display *disp; 327 extern Window rootw, mainw, lifew, helpw, inputw, coordw, rulew, statew, loadw; 328 extern int screen; 329 extern unsigned long fcolor, bcolor; 330 extern XEvent event; 331 extern XFontStruct *nfont, *cfont; 332 extern GC ntextgc, itextgc, cellgc[], xorgc, invgc; 333 extern KeySym ks; 334 335 #define INPBUFLEN 255 336 extern char inpbuf[]; 337 extern int minbuflen; 338 extern int numcomments; 339 #define MAXCOMMENTS 512 340 #define MAXCOMMENTLINELEN 192 341 extern char comments[][MAXCOMMENTLINELEN]; 342 extern char keybuf[16]; 343 extern u32bits lookup4[]; 344 extern u16bits *lookup2, tab6[]; 345 extern u8bits *lookup, tab4[]; 346 extern char fname[]; 347 extern char colorfile[]; 348 349 extern unsigned maxstates, statescols; 350 extern coord_t xpos, ypos; /* coords of upper left corner of viewport */ 351 extern coord_t xorigin, yorigin; /* virtual origin */ 352 extern coord_t lastx, lasty; /* last coord pair displayed on status line */ 353 extern coord_t loadx, loady; /* location to load new points */ 354 extern coord_t iloadx, iloady; /* initial location of load points */ 355 extern int txx, txy, tyx, tyy; /* transform for tentative points */ 356 357 extern int dispboxes, dispchanges, dispcoord, dispspeed; 358 extern int scale; 359 extern u32bits born; 360 extern u32bits live; 361 362 extern int width, maxwidth, height, inputlength, state, paintcolor; 363 extern struct timeval timeout; 364 extern char active_rules[], saved_rules[]; 365 extern char saveformat, scriptformat; 366 367 #define MAXCHANGE 8192 368 #define EXTRACOLORS 14 369 #define MAXCOLORS (MAXSTATES + EXTRACOLORS) 370 extern cellcount_t chgpoints[MAXCOLORS], chgrects[MAXCOLORS]; 371 extern XPoint points[MAXCOLORS][MAXCHANGE]; 372 extern XRectangle rects[MAXCOLORS][MAXCHANGE]; 373 374 /* cell.c */ 375 int getcell(cellbox*, const int, const int); 376 void setcell(cellbox*, const int, const int, const int); 377 void displaybox(u32bits, u32bits, cellbox*); 378 void trdisplaybox(u32bits, u32bits, cellbox*); 379 void displaybox_nofb(u32bits, u32bits, cellbox*); 380 void trdisplaybox_nofb(u32bits, u32bits, cellbox*); 381 void trdrawbox(coord_t, coord_t, coord_t, coord_t, int); 382 extern int pseudopaint[2][2]; 383 384 /* collect.c */ 385 void collect(char*, int); 386 387 /* generate.c */ 388 void generate(pattern*); 389 void newrules(void); 390 char *readrules(const char*); 391 char *parse_rule(char*); 392 void make_transition(int, int, int, int, int, int, int); 393 void make_transition8(int, int, int, int, int, int, int, int, int, int, int); 394 char *parse_rule(char*); 395 int file_rules(char*); 396 397 /* isave.c */ 398 void savestructured(pattern*, FILE*); 399 extern char matchlibfile[]; 400 401 #define FOR_CELLS(pp, pt, dx, dy) for (pt=(pp)->tiles;pt;pt=pt->next) \ 402 if (!pt->dead) \ 403 for (dx=0;dx<BOXSIZE;dx++) \ 404 for (dy=0;dy<BOXSIZE;dy++) 405 extern int oldp; 406 407 #define MAXDIRS 128 408 extern char *dirs[]; 409 410 #define VALENCE_DRIVEN 0 /* based on neighborhood count (live, born), moore, rotate8 */ 411 #define TABLE_DRIVEN 1 /* based on transition table (trans), vonNeumann, rotate4(reflect) or nosymmetries */ 412 #define PAYOFF_DRIVEN 2 /* based on payoff matrix (payoffs) */ 413 #define GEN_DRIVEN 4 /* based on moore, rotate8 */ 414 #define TAB8_DRIVEN 8 /* based on transition table (trans), moore, rotate8 */ 415 416 extern unsigned delay, hideperiod, randomseed, eo_comments, speed, rulew_len, runcounter; 417 extern char stashed[], topology, outcome[], topologyinfo[], pathtorules[]; 418 extern int convmode, wireframe, dispmesh, oscillators, tilesize, ev_mode, pivot, 419 limits, helpw_mode, pseudocolor, historymode, palettemod, nosymm, passive, 420 rotate4reflect, aloadmode, truehistory, save_dispboxes, save_dispchanges; 421 extern coord_t x_min_limit, x_max_limit, y_min_limit, y_max_limit; 422 extern float rnd_density; 423 424 #define chk_limits(x,y) (((limits&1) == 0\ 425 || (x) >= x_min_limit && (x) < x_max_limit)\ 426 && ((limits&2) == 0\ 427 || (y) >= y_min_limit && (y) < y_max_limit)) 428 429 #define RULESNAMELEN 80 430 431 extern char curdir[], inidir[]; 432 extern cell_t *trans; 433 #define ztrans ((cell_t(*)[maxstates][maxstates][maxstates][maxstates])trans) 434 #define btrans ((cell_t(*)[maxstates][maxstates][maxstates][maxstates][maxstates][maxstates][maxstates][maxstates])trans) 435 extern XColor cellcolor[], exact; 436 extern XGCValues xgcv; 437 438 #if VFREQ != 0 439 extern struct timeval prev_vsync; 440 #endif 441 442