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