home *** CD-ROM | disk | FTP | other *** search
- /*****
- *
- * File: cell.c
- *
- * Cellsim, cellular automata simulator
- *
- * General routines.
- *
- *****/
-
-
- #include "cell.h"
-
- /*
- *
- * Cellsim copyright 1989, 1990 by Chris Langton and Dave Hiebeler
- * (cgl@lanl.gov, hiebeler@heretic.lanl.gov)
- *
- * This package may be freely distributed, as long as you don't:
- * - remove this notice
- * - try to make money by doing so
- * - prevent others from copying it freely
- * - distribute modified versions without clearly documenting your changes
- * and notifying us
- *
- * Please contact either of the authors listed above if you have questions
- * or feel an exception to any of the above restrictions is in order.
- *
- * If you make changes to the code, or have suggestions for changes,
- * let us know! If we use your suggestion, you will receive full credit
- * of course.
- */
-
- /*****
- * Cellsim history:
- *
- * Cellsim was originally written on Apollo workstations by Chris Langton.
- *
- * Sun versions:
- *
- * - version 1.0
- * by C. Ferenbaugh and C. Langton
- * released 09/02/88
- *
- * - version 1.5
- * by Dave Hiebeler and C. Langton May - June 1989
- * released 07/03/89
- *
- * - version 2.0
- * by Dave Hiebeler and C. Langton July - August 1989
- * never officially released (unofficially released 09/08/89)
- *
- * - version 2.5
- * by Dave Hiebeler and C. Langton September '89 - February 1990
- * released 02/26/90
- *****/
-
-
-
- main(argc, argv)
- int argc;
- char **argv;
- {
- struct timeval tp;
- struct timezone *tzp;
-
- emergency_LT_save_ptr = emergency_LT_save;
- default_segv_func = (void_func_ptr) signal(SIGSEGV, emergency_LT_save_ptr);
- /* Seed the random-# generator based on current time in microseconds */
- tzp = NULL;
- gettimeofday(&tp, tzp);
- srandom((int) tp.tv_usec);
-
- remove_frame_args(&argc, argv);
- which(argv[0],argv0); /* look up full pathname of Cellsim */
- init_vars(); /* init various variables */
- set_params(argc, argv);
- switch (B) {
- case 64:
- case 128:
- CM_zoom = 6;
- break;
- case 256:
- CM_zoom = 3;
- break;
- case 512:
- CM_zoom = 1;
- break;
- }
- CM_panx = B/2;
- CM_pany = B/2;
- init_scr(); /* initialize screen and graphics */
- init_data(); /* initialize automaton data */
- clear_data(); /* clear out data */
- tclear(); /* clear the LT */
-
- statecount = (int *) malloc(S * sizeof(int));
- /* storage for state counters */
-
- display_image(); /* display (cleared) image */
-
- show_msg("Cellsim 2.5");
- command_loop();
-
- /* On termination, sockets are automatically closed,
- * pixrects destroyed, etc. */
- exit(0);
-
- } /* main */
-
-
-
- /*
- * Initialize misc. variables
- */
- init_vars()
- {
- char *tmp_str;
-
- parm1 = 0;
- parm2 = 0;
- use_FB = 0;
- use_Sun_disp = 1;
- auto_nhood_change = 1;
- auto_image_change = 1;
- blackwhite = 0;
- if ((tmp_str = getenv("IMAGE_DIR")) == NULL)
- sprintf(Image_dir, "%s", IMAGE_DIR);
- else
- sprintf(Image_dir, "%s", tmp_str);
- if ((tmp_str = getenv("TABLE_DIR")) == NULL)
- sprintf(Table_dir, "%s", TABLE_DIR);
- else
- sprintf(Table_dir, "%s", tmp_str);
- if ((tmp_str = getenv("FCN_DIR")) == NULL)
- sprintf(Fcn_dir, "%s", FCN_DIR);
- else
- sprintf(Fcn_dir, "%s", tmp_str);
- if ((tmp_str = getenv("CMAP_DIR")) == NULL)
- sprintf(Cmap_dir, "%s", CMAP_DIR);
- else
- sprintf(Cmap_dir, "%s", tmp_str);
- expand_fname(Image_dir, Image_dir);
- expand_fname(Table_dir, Table_dir);
- expand_fname(Fcn_dir, Fcn_dir);
- expand_fname(Cmap_dir, Cmap_dir);
- sprintf(CM_hostname, "%s", DEFAULT_CM_HOST);
- CM_port = CELLSIM_PORT;
- }
-
-
- /*
- * Set up the configuration (neighborhood, image-size, etc) based
- * on the command-line arguments.
- */
- set_params(argc, argv)
- int argc;
- char **argv;
- {
- int i, err, n, tmp;
- char *tmp_str, tmp_str2[80];
-
- for (i = 1; i < argc; i++) {
- switch (argv[i][0]) {
- case 'b':
- err = sscanf(&argv[i][1], "%d", &n);
- if (err != 1 || (n != 64 && n != 128 && n != 256 && n != 512))
- printf("Illegal value %s for b ignored\n", &argv[i][1]);
- else
- B = n;
- break;
- case 'B': /* run in black&white */
- blackwhite = 1;
- break;
- case 'm':
- NHOOD = NH_MOORE;
- set_states(&argv[i][1]);
- break;
- case 'M':
- NHOOD = NH_MARG;
- set_states(&argv[i][1]);
- break;
- case 'v':
- NHOOD = NH_VONN;
- set_states(&argv[i][1]);
- break;
- case 'l':
- NHOOD = NH_LIN;
- set_states(&argv[i][1]);
- break;
- case 'r':
- err = sscanf(&argv[i][1], "%d", &n);
- if (err != 1 || n <= 0 || n > 3)
- printf("Illegal value %s for R ignored\n", &argv[i][1]);
- else
- R = n;
- break;
- case 'H':
- strcpy(hostname, &argv[i][1]);
- break;
- case 'P':
- err = sscanf(&argv[i][1], "%d", &n);
- if (err != 1)
- printf("Illegal port number %s ignored\n", &argv[i][1]);
- else {
- portnum = n;
- SOCKET_INUSE = TRUE;
- }
- break;
- case 'p': /* Set CM port */
- err = sscanf(&argv[i][1], "%d", &n);
- if (err != 1)
- printf("Illegal port number %s ignored\n", &argv[i][1]);
- else
- CM_port = n;
- break;
- case 'C': /* Attach to the Connection Machine */
- if (argv[i][1] != '\0') {
- err = sscanf(&argv[i][1], "%s", tmp_str2);
- if (err == 1)
- strcpy(CM_hostname, tmp_str2);
- }
- break;
- default:
- printf("Unknown option '%s' (#%d) ignored\n", argv[i],i);
- break;
- } /* switch */
- } /* for i */
- if (S != 256) {
- if ((NHOOD == NH_MOORE || (NHOOD == NH_LIN && R == 3)) && S > 4) {
- printf("Maximum of 4 states allowed in given nhood\n");
- S = 4;
- }
- }
- BM1 = B - 1;
- BPL1 = B + 1;
- TBM1 = 2 * B - 1;
- BSQR = B * B;
- BBUF = BSQR + B;
- ASIZE = BBUF + B;
- ABASE = B;
- RCOUNT = B;
-
- if (NHOOD == NH_LIN) {
- ICBASE = BSQR;
- ICSIZE = B;
- DIM = 1;
- } else {
- ICBASE = B;
- ICSIZE = BSQR;
- DIM = 2;
- }
-
- L = (short) (log((double) S) / log((double) 2.0));
- AMASK = S - 1;
-
- switch (NHOOD) {
- case NH_VONN:
- set_params_v();
- break;
- case NH_MOORE:
- set_params_m();
- break;
- case NH_LIN:
- set_params_l();
- break;
- case NH_MARG:
- set_params_marg();
- break;
- }
-
- if (!function) {
- TSIZE = 1 << (L * N);
- ta = (State *)malloc(TSIZE);
- }
-
- if (SOCKET_INUSE)
- init_sock(hostname, portnum);
-
- saved_sx = B;
- saved_sy = B;
- saved_min_val = 0;
- saved_max_val = S-1;
-
- } /* set_params */
-
-
- /*
- * Set # of states
- */
- set_states(str)
- char *str;
- {
- int n, err;
- if (str[0] == 0)
- return;
- err = sscanf(str, "%d", &n);
- if (err != 1 || (n != 2 && n != 4 && n != 8 && n != 16 && n != 256)) {
- printf("Illegal value %s for S ignored\n", str);
- exit(1);
- }
- else
- S = n;
- if (n == 256)
- function = 1;
- else
- function = 0;
- }
-
-
- /********************************** USER PROCEDURES ************************/
- /*
- * Many of the procedures that may be called up from the control panel
- * are here. Exceptions are some SunView-specific routines in "cellscr.c",
- * and some Connection-Machine related routines in "cm_cellsim.c" (some
- * of the CM-routines are farther on in this file, as well).
- */
-
-
-
- set_proc()
- {
- if (invalid_set_pressed())
- return;
- if (setting_sequence)
- add_sequence(set_proc);
- set_just_pressed = 1;
- }
-
-
- step_proc( /* ARGS UNUSED */ )
- {
- int p, quit = FALSE;
-
- if (invalid_set_pressed())
- return;
- if (setting_sequence)
- add_sequence(step_proc);
- if (function && (!use_CM)) {
- if (update_function == NULL) {
- clear_msg();
- show_msg("No update-function loaded");
- return;
- }
- }
- p = 0;
- while (!quit) {
- if (use_CM) {
- CM_auto_step(1);
- CM_display_image();
- stime++;
- show_time(stime);
- }
- else {
- p = auto_step(1);
- display_image();
- }
- quit = !p;
- if (p)
- quit = undef(p);
- }
- }
-
-
- skip_proc()
- {
- int p, step;
-
- if (setting_sequence)
- add_sequence(skip_proc);
- if (function && (!use_CM)) {
- if (update_function == NULL) {
- clear_msg();
- show_msg("You have not loaded an update-function");
- return;
- }
- }
- clear_msg();
- if (set_pressed()) {
- if (get_num("Number of steps:", &step, 1, MAXINT, saved_skip))
- return;
- saved_skip = step;
- return;
- }
- else {
- if (saved_skip == INTUNDEF) {
- clear_msg();
- show_msg("Number of steps never set");
- return;
- }
- }
- p = 0;
- if (use_CM) {
- CM_auto_step(saved_skip);
- CM_display_image();
- stime += saved_skip;
- show_time(stime);
- }
- else {
- p = auto_step(saved_skip);
- display_image();
- }
- if (p) {
- clear_msg();
- show_msg("Undefined neighborhood");
- }
- }
-
-
- screenful_proc()
- {
- int p;
-
- clear_msg();
- if (invalid_set_pressed())
- return;
- if (NHOOD != NH_LIN) {
- show_msg("Not linear nhood");
- return;
- }
- if (setting_sequence)
- add_sequence(screenful_proc);
- if (use_CM) {
- CM_disp_interval = 1;
- CM_auto_screen(B);
- CM_display_image();
- stime += B;
- show_time(stime);
- return;
- }
- else
- p = auto_screen(1);
- display_image();
- if (p) {
- clear_msg();
- show_msg("Undefined neighborhood");
- }
- }
-
-
- zero_proc()
- {
- clear_msg();
- if (invalid_set_pressed())
- return;
- if (setting_sequence)
- add_sequence(zero_proc);
- stime = 0;
- show_time(stime);
- }
-
-
- clear_proc()
- {
- clear_msg();
- if (invalid_set_pressed())
- return;
- if (setting_sequence)
- add_sequence(clear_proc);
- iclear();
- }
-
-
- learn_proc()
- {
- clear_msg();
- if (invalid_set_pressed())
- return;
- if (setting_sequence)
- add_sequence(learn_proc);
- if (function) {
- clear_msg();
- show_msg("Learn is not available with");
- show_msg("256-state rules");
- return;
- }
- learn();
- }
-
-
-
- run_proc()
- {
- int go=TRUE;
-
- if (invalid_set_pressed())
- return;
- if (setting_sequence)
- add_sequence(run_proc);
- if (!use_CM) {
- generic_auto_run(MAXINT, 1);
- return;
- }
- def_CM_get_settings();
- CM_disp_interval = 1;
- CM_run_forever_proc();
- }
-
-
- run_local_proc()
- {
- if (invalid_set_pressed())
- return;
- if (setting_sequence)
- add_sequence(run_local_proc);
- local_run = 1;
- generic_auto_run(MAXINT, 1);
- local_run = 0;
- }
-
-
- step_local_proc()
- {
- if (invalid_set_pressed())
- return;
- if (setting_sequence)
- add_sequence(step_local_proc);
- local_run = 1;
- generic_auto_run(1, 1);
- local_run = 0;
- }
-
-
- skip_run_proc()
- {
- int d;
-
- clear_msg();
- if (setting_sequence)
- add_sequence(skip_run_proc);
- if (set_pressed()) {
- if (get_num("Display interval:", &d, 0, MAXINT,
- saved_display_interval))
- return;
- saved_display_interval = d;
- return;
- }
- if (saved_display_interval == INTUNDEF) {
- clear_msg();
- show_msg("display interval not set");
- return;
- }
- if (use_CM && (!use_Sun_disp)) {
- def_CM_get_settings();
- CM_disp_interval = saved_display_interval;
- CM_run_forever_proc();
- }
- else
- generic_auto_run(MAXINT, saved_display_interval);
- }
-
-
-
- bound_run_proc()
- {
- int b;
- clear_msg();
- if (setting_sequence)
- add_sequence(bound_run_proc);
- if (set_pressed()) {
- if (get_num("Number of steps:", &b, 1, MAXINT, saved_num_steps))
- return;
- saved_num_steps = b;
- return;
- }
- if (saved_num_steps == INTUNDEF) {
- clear_msg();
- show_msg("number of steps default");
- show_msg("was never set");
- return;
- }
- def_CM_get_settings();
- if (use_CM && (!use_Sun_disp)) {
- CM_disp_interval = 1;
- CM_auto_screen(saved_num_steps);
- stime += saved_num_steps;
- show_time(stime);
- }
- else
- generic_auto_run(saved_num_steps, 1);
- }
-
-
- sb_run_proc()
- {
- int d, b;
- clear_msg();
- if (setting_sequence)
- add_sequence(sb_run_proc);
- if (set_pressed()) {
- if (get_num("Display interval:", &d, 0, MAXINT,
- saved_display_interval))
- return;
- saved_display_interval = d;
- if (get_num("Number of steps:", &b, 1, MAXINT, saved_num_steps))
- return;
- saved_num_steps = b;
- return;
- }
- if (saved_num_steps == INTUNDEF) {
- clear_msg();
- show_msg("number of steps default");
- show_msg("was never set");
- return;
- }
- if (saved_display_interval == INTUNDEF) {
- clear_msg();
- show_msg("display interval not set");
- return;
- }
- def_CM_get_settings();
- if (use_CM && (!use_Sun_disp)) {
- CM_disp_interval = saved_display_interval;
- CM_auto_screen(saved_num_steps);
- CM_display_image();
- stime += saved_num_steps;
- show_time(stime);
- }
- else
- generic_auto_run(saved_num_steps, saved_display_interval);
- }
-
-
- generic_auto_run(bound, disp_int)
- int bound, disp_int;
- {
- int k, go = TRUE;
- int stoptime = stime + bound, step = (disp_int ? disp_int : 1);
-
- if ((NHOOD == NH_LIN) && (bound != MAXINT))
- stoptime = stime + bound*(B-1);
- if (function && (!use_CM)) {
- if (update_function == NULL) {
- clear_msg();
- show_msg("No update-function loaded");
- return;
- }
- }
- set_run_mode();
- k = 0;
- if (use_CM && (!local_run)) {
- while (go && stime < stoptime) {
- CM_auto_screen(step);
- stime += step;
- show_time(stime);
- if (disp_int)
- CM_display_image();
- go = !check_button();
- }
- }
- else {
- while (go && stime < stoptime) {
- k = auto_screen(step);
- if (disp_int)
- display_image();
- go = !check_button();
- if (k) {
- clear_msg();
- show_msg("Undefined neighborhood");
- unset_run_mode();
- break;
- }
- switch (stop_on_mode) {
- case NEVER:
- break;
- case NO_CHANGE:
- if (!compare_images()) {
- unset_run_mode();
- return;
- }
- break;
- case ALL_ZERO:
- if (array_is_empty()) {
- unset_run_mode();
- return;
- }
- break;
- }
- }
- }
- if (!disp_int) {
- if (use_CM)
- CM_display_image();
- else
- display_image();
- }
- unset_run_mode();
- }
-
-
- quick_random_proc()
- {
- int i;
-
- /* percentage is set so that all states (including 0) will
- * appear with equal probability */
- clear_msg();
- if (invalid_set_pressed())
- return;
- if (setting_sequence)
- add_sequence(quick_random_proc);
- for (i=0; i<B*B; i++)
- ca[i + ABASE] = random()%S;
- display_image();
- }
-
-
- general_random_proc()
- {
- if (setting_sequence)
- add_sequence(general_random_proc);
- if (set_pressed())
- general_random_set_proc();
- else
- general_random_generate_proc();
- }
-
-
- general_random_set_proc()
- {
- int ox, oy, sx, sy, percent, min_val, max_val, err, org, x, y, index;
- char tmp_str[80];
-
- clear_msg();
- if (get_2num("Origin of area: ", &ox, &oy, 0, B, 0, B, saved_ox, saved_oy))
- return;
- if (get_2num("Size of area: ", &sx, &sy, 0, B-ox, 0, B-oy,
- saved_sx, saved_sy))
- return;
- err = get_num("% of cells to change:", &percent, 0, 100, saved_density);
- if (err)
- return;
- if (get_2num("Min and max vals:", &min_val, &max_val, 0, S-1, 0, S-1,
- saved_min_val, saved_max_val))
- return;
- saved_ox = ox;
- saved_oy = oy;
- saved_sx = sx;
- saved_sy = sy;
- saved_density = percent;
- saved_min_val = min_val;
- saved_max_val = max_val;
- }
-
-
- general_random_generate_proc()
- {
- int ox, oy, sx, sy, percent, min_val, max_val, err, org, x, y, index;
-
- clear_msg();
- if ((saved_max_val == INTUNDEF) || (saved_ox == INTUNDEF)) {
- show_msg("Defaults never set, or cleared");
- show_msg("when configuration changed");
- return;
- }
- if (non_local)
- return;
- show_msg("Generating random image...");
- ox = saved_ox;
- oy = saved_oy;
- sx = saved_sx;
- sy = saved_sy;
- percent = saved_density;
- min_val = saved_min_val;
- max_val = saved_max_val;
- for (y=oy; y < oy+sy; y++)
- for (x=ox; x < ox+sx; x++) {
- if ((random()%100) < percent) {
- index = y*B + x + ABASE;
- ca[index] = (random()%(max_val - min_val + 1)) + min_val;
- }
- }
- show_msg("Done.");
- display_image();
- }
-
-
- sequence1_proc()
- {
- if (set_pressed())
- sequence_set_proc(1);
- else
- sequence_generate_proc(1);
- }
-
-
- sequence2_proc()
- {
- if (set_pressed())
- sequence_set_proc(2);
- else
- sequence_generate_proc(2);
- }
-
-
- sequence3_proc()
- {
- if (set_pressed())
- sequence_set_proc(3);
- else
- sequence_generate_proc(3);
- }
-
-
- sequence4_proc()
- {
- if (set_pressed())
- sequence_set_proc(4);
- else
- sequence_generate_proc(4);
- }
-
-
- sequence5_proc()
- {
- if (set_pressed())
- sequence_set_proc(5);
- else
- sequence_generate_proc(5);
- }
-
-
- sequence_set_proc(n)
- short n;
- {
- clear_msg();
- clear_sequence(n);
- if (setting_sequence) {
- show_msg("Invalid -- can't call set sequence");
- show_msg("within itself. Exiting sequence setting.");
- setting_sequence = 0;
- return;
- }
- setting_sequence = n;
- show_msg("Setting sequence. Click 'sequence'");
- show_msg("again when done");
- }
-
-
- sequence_generate_proc(n)
- short n;
- {
- int i;
-
- clear_msg();
- if (setting_sequence == n) {
- setting_sequence = 0;
- if (sequence_length[n-1] == 0) {
- show_msg("Sequence is empty, not saved");
- return;
- }
- show_msg("Sequence saved. Hit 'sequence'");
- show_msg("to activate your sequence");
- return;
- }
- if (sequence_length[n-1] == 0) {
- sprintf(buf1, "Sequence %d is empty", n);
- show_msg(buf1);
- return;
- }
- for (i=0; i < sequence_length[n-1]; i++)
- (*(sequence_array[n-1][i]))();
- clear_msg();
- sprintf(buf1,"Done executing sequence #%d",n);
- show_msg(buf1);
- sprintf(buf1, "of length %d", sequence_length[n-1]);
- show_msg(buf1);
- }
-
-
- horiz_line_proc()
- {
- if (invalid_set_pressed())
- return;
- if (setting_sequence)
- add_sequence(horiz_line_proc);
- drawing = HORIZ_LINE;
- clear_msg();
- show_msg("Click left button at one end");
- }
-
-
- vert_line_proc()
- {
- if (invalid_set_pressed())
- return;
- if (setting_sequence)
- add_sequence(vert_line_proc);
- drawing = VERT_LINE;
- clear_msg();
- show_msg("Click left button at one end");
- }
-
-
- arb_line_proc()
- {
- if (invalid_set_pressed())
- return;
- if (setting_sequence)
- add_sequence(arb_line_proc);
- drawing = ARB_LINE;
- clear_msg();
- show_msg("Click left button at start");
- show_msg("of line");
- }
-
-
- hollow_circ_proc()
- {
- if (invalid_set_pressed())
- return;
- if (setting_sequence)
- add_sequence(hollow_circ_proc);
- drawing = HOLLOW_CIRC;
- clear_msg();
- show_msg("Click left button at center");
- show_msg("of circle");
- }
-
-
- shaded_circ_proc()
- {
- int xinc, yinc;
-
- if (setting_sequence)
- add_sequence(shaded_circ_proc);
- if (set_pressed()) {
- clear_msg();
- if (get_2num("X and Y increment: ", &xinc, &yinc, 0, B-1, 0, B-1,
- saved_xinc, saved_yinc))
- return;
- saved_xinc = xinc;
- saved_yinc = yinc;
- return;
- }
- else {
- if ((saved_xinc == INTUNDEF) || (saved_yinc == INTUNDEF)) {
- clear_msg();
- show_msg("Parameters never set for");
- show_msg("shaded circle. Use 'set'.");
- return;
- }
- }
- drawing = SHADED_CIRC;
- clear_msg();
- show_msg("Click left button at center");
- show_msg("of circle");
- }
-
-
- chdir_proc()
- {
- char pathname[MAXPATHLEN];
-
- clear_msg();
- if (!getwd(pathname)) {
- show_msg("Unable to find current");
- show_msg("working directory");
- return;
- }
- get_msg("New directory:", buf1, BUFLEN, pathname);
- if (expand_fname(buf1, buf1))
- return;
- if (stat(buf1, &statbuf)) {
- clear_msg();
- show_msg("Error trying to set directory");
- return;
- }
- if (!((statbuf.st_mode) & S_IFDIR)) {
- clear_msg();
- show_msg("Not a directory");
- return;
- }
- chdir(buf1);
- strcpy(current_working_dir,buf1);
- show_msg("Current working directory is now");
- show_msg(buf1);
- }
-
- /**************** magnify routines *******************/
-
-
- magnify_proc()
- {
- int m, err;
- char str[BUFLEN];
-
- clear_msg();
- if (invalid_set_pressed())
- return;
- if (setting_sequence)
- add_sequence(magnify_proc);
- if (closeup) {
- show_msg("Not allowed in closeup mode");
- return;
- }
- sprintf(str, "Zoom factor (currently %d):", mag);
- err = get_num(str, &m, 1, (int) MAXSIZE / side, mag);
- if (err)
- return;
- set_mag(m);
- }
-
-
- zoom_in_proc()
- {
- int m = (int) MAXSIZE / side; /* maximum magnification */
-
- clear_msg();
- if (invalid_set_pressed())
- return;
- if (setting_sequence)
- add_sequence(zoom_in_proc);
- if (closeup) {
- clear_msg();
- show_msg("Can't use zoom in closeup");
- return;
- }
- if (mag < m) {
- mag++;
- set_mag(mag);
- }
- }
-
-
- zoom_out_proc()
- {
- clear_msg();
- if (invalid_set_pressed())
- return;
- if (setting_sequence)
- add_sequence(zoom_out_proc);
- if (closeup) {
- clear_msg();
- show_msg("Can't use zoom in closeup");
- return;
- }
- if (mag > 1) {
- mag--;
- set_mag(mag);
- }
- }
-
-
- zoom_proc()
- {
- int m = (int) MAXSIZE / side; /* maximum magnification */
-
- clear_msg();
- if (invalid_set_pressed())
- return;
- if (setting_sequence)
- add_sequence(zoom_proc);
- if (closeup) {
- clear_msg();
- show_msg("Can't use zoom in closeup");
- return;
- }
- if (mag < m)
- set_mag(m);
- else
- set_mag(1);
- }
-
-
- closeup_proc()
- {
- clear_msg();
- if (invalid_set_pressed())
- return;
- if (setting_sequence)
- add_sequence(closeup_proc);
- if (closeup = !closeup) {
- side = 32;
- saved_mag_factor = mag;
- mag = MAXSIZE / 32;
- if (NHOOD == NH_LIN) {
- xstart = (B - 32) / 2;
- ystart = B - 32;
- }
- else
- xstart = ystart = (B - 32) / 2;
- display_image();
- } else {
- side = B;
- mag = saved_mag_factor;
- xstart = ystart = 0;
- set_mag(mag);
- }
- }
-
-
- /********************** display routines ************************/
-
- shift_proc()
- {
- int n;
- char str[BUFLEN];
- clear_msg();
- sprintf(str, "Distance (currently %d):", shift_dist);
- if (get_num(str, &n, 1, B / 2, shift_dist))
- return;
- shift_dist = n;
- }
-
-
- right_proc()
- {
- hshift_data(shift_dist);
- display_image();
- }
-
-
- left_proc()
- {
- hshift_data(-shift_dist);
- display_image();
- }
-
-
- up_proc()
- {
- vshift_data(-shift_dist);
- display_image();
- }
-
-
- down_proc()
- {
- vshift_data(shift_dist);
- display_image();
- }
-
-
- /*********************** IMAGE ROUTINES ********************/
-
- isave_proc()
- {
- if (save_images_compressed == TRUE)
- isave_compressed();
- else
- isave();
- }
-
-
- isave()
- { /* save current image */
- State *ap;
- int dumpsize;
-
- clear_msg();
- if (invalid_set_pressed())
- return;
- if (setting_sequence)
- add_sequence(isave);
- get_msg("Save image file:", buf1, BUFLEN, saved_image_file);
- if (buf1[0] == NULL)
- return;
- if ((buf1[0] == '/') || (!strncmp(buf1, "./", 2)) || (!strncmp(buf1, "../", 3)) || (!save_in_image_dir))
- ;
- else {
- strcpy(buf2, buf1);
- sprintf(buf1, "%s/%s", Image_dir, buf2);
- }
- if (expand_fname(buf1, buf1))
- return;
- strcpy(saved_image_file,buf1);
- if ((fp = fopen(buf1, "r")) != NULL) {
- if (!confirm_overwrite()) {
- fclose(fp);
- return;
- }
- fclose(fp);
- }
- fp = fopen(saved_image_file, "w");
- if (fp == NULL) {
- clear_msg();
- show_msg("Unable to open file");
- show_msg(sys_errlist[errno]);
- return;
- }
- if (use_2D_always) {
- ap = ca + B;
- dumpsize = BSQR;
- }
- else {
- ap = ca + ICBASE;
- dumpsize = ICSIZE;
- }
- fwrite(ap, sizeof(*ap), dumpsize, fp);
- fclose(fp);
- sprintf(buf1, "%s saved",saved_image_file);
- show_msg(buf1);
- }
-
-
-
- isave_CAM6()
- { /* save image in CAM6 format */
- State *ap, *save_ap;
- unsigned char byteval;
- int i, j, plane;
-
- clear_msg();
- if (invalid_set_pressed())
- return;
- if (setting_sequence)
- add_sequence(isave_CAM6);
- if (B == 512) {
- clear_msg();
- show_msg("Can't save 512-size image");
- show_msg("in CAM format yet");
- return;
- }
- ap = ca + ICBASE;
- save_ap = ap;
- get_msg("Save CAM6 file:", buf1, BUFLEN, saved_image_file);
- if (buf1[0] == NULL)
- return;
- if ((buf1[0] == '/') || (!strncmp(buf1, "./", 2)) || (!strncmp(buf1, "../", 3)) || (!save_in_image_dir))
- ;
- else {
- strcpy(buf2, buf1);
- sprintf(buf1, "%s/%s", Image_dir, buf2);
- }
- if (expand_fname(buf1, buf1))
- return;
- strcpy(saved_image_file,buf1);
- if ((fp = fopen(buf1, "r")) != NULL) {
- if (!confirm_overwrite()) {
- fclose(fp);
- return;
- }
- }
- if (save_images_compressed == TRUE) {
- show_msg("Saving uncompressed -- can't");
- show_msg("save compressed CAM6 images yet");
- }
- fp = fopen(saved_image_file, "w");
- for (plane = 0; plane < L; plane++) {
- for (i=0; i < 65536; ) {
- byteval = 0;
- if (((i%256) >= B) || ((i / 256) >= B)) {
- putc(0, fp);
- i += 8;
- }
- else {
- for (j=0; j < 8; j++) {
- byteval = (byteval << 1) | ((ap[7-j] & (1<<plane)) >> plane);
- i++;
- }
- putc(byteval,fp);
- ap += 8;
- }
- }
- ap = save_ap;
- }
- fclose(fp);
- sprintf(buf1, "%s saved",saved_image_file);
- show_msg(buf1);
- }
-
-
- isave_compressed()
- { /* save current image */
- State *ap;
- int err;
- FILE *fp;
- int dumpsize;
-
- clear_msg();
- if (invalid_set_pressed())
- return;
- if (setting_sequence)
- add_sequence(isave_compressed);
- get_msg("Save image file:", buf1, BUFLEN, saved_image_file);
- if (buf1[0] == NULL)
- return;
- if ((buf1[0] == '/') || (!strncmp(buf1, "./", 2)) || (!strncmp(buf1, "../", 3)) || (!save_in_image_dir))
- ;
- else {
- strcpy(buf2, buf1);
- sprintf(buf1, "%s/%s", Image_dir, buf2);
- }
- if (expand_fname(buf1, buf1))
- return;
- if (strcmp(&buf1[strlen(buf1)-2],".Z"))
- strcat(buf1, ".Z");
- strcpy(saved_image_file,buf1);
- if ((fp = fopen(buf1, "r")) != NULL) {
- if (!confirm_overwrite()) {
- fclose(fp);
- return;
- }
- }
- sprintf(buf2,"compress > %s",saved_image_file);
- if ((fp = popen(buf2, "w")) == NULL) {
- show_msg("Error opening pipe");
- return;
- }
- if (use_2D_always) {
- ap = ca + B;
- dumpsize = BSQR;
- }
- else {
- ap = ca + ICBASE;
- dumpsize = ICSIZE;
- }
- fwrite(ap, sizeof(*ap), dumpsize, fp);
- err = pclose(fp);
- if (err) {
- sprintf(buf1,"pclose returned %d",err);
- show_msg(buf1);
- return;
- }
- sprintf(buf1, "%s saved",saved_image_file);
- show_msg(buf1);
- }
-
-
- isave_resize()
- { /* save image into file of different size */
- int s, dx, dy, err;
-
- clear_msg();
- if (invalid_set_pressed())
- return;
- if (setting_sequence)
- add_sequence(isave_resize);
- get_msg("Save image file:", buf1, BUFLEN, saved_image_file);
- if (buf1[0] == NULL)
- return;
- if ((buf1[0] == '/') || (!strncmp(buf1, "./", 2)) ||
- (!strncmp(buf1, "../", 3)) || (!save_in_image_dir))
- ;
- else {
- strcpy(buf2, buf1);
- sprintf(buf1, "%s/%s", Image_dir, buf2);
- }
- if (expand_fname(buf1, buf1))
- return;
- strcpy(saved_image_file,buf1);
- if ((fp = fopen(buf1, "r")) != NULL) {
- if (!confirm_overwrite()) {
- fclose(fp);
- return;
- }
- }
- if (save_images_compressed == TRUE) {
- show_msg("Saving uncompressed -- can't");
- show_msg("save/reside compressed yet");
- }
- fp = fopen(saved_image_file, "w");
- if (get_num("Side length:", &s, 1, 512, saved_side_length))
- return;
- saved_side_length = s;
- if (DIM == 1) {
- get_msg("X offset:", buf1, BUFLEN, saved_x_offset);
- strcpy(saved_x_offset,buf1);
- err = sscanf(buf1, "%d", &dx);
- } else {
- get_msg("X, Y offsets:", buf1, BUFLEN, saved_y_offset);
- strcpy(saved_y_offset,buf1);
- err = sscanf(buf1, "%d%d", &dx, &dy);
- }
- if (err != DIM && buf1[0] != NULL) {
- show_msg("Invalid entry");
- return;
- }
- if (buf1[0] == NULL)
- dx = dy = abs((B - s) / 2);
- save_resize_data(fp, s, dx, dy);
- fclose(fp);
- display_image();
-
- }
-
-
- iload()
- { /* load an image into ca */
- clear_msg();
- if (invalid_set_pressed())
- return;
- if (setting_sequence)
- add_sequence(iload);
- get_msg("Load image file:", buf1, BUFLEN, saved_image_file);
- if (buf1[0] == NULL)
- return;
- if (expand_fname(buf1, buf1))
- return;
- strcpy(saved_image_file,buf1);
- if (!strcmp(&buf1[strlen(buf1)-2],".Z")) {
- iload_compressed(buf1);
- return;
- }
- if (!(fp = fopen(buf1, "r"))) {
- sprintf(buf2,"%s/%s",Image_dir,buf1);
- if (!(fp = fopen(buf2, "r"))) {
- /* see if a compressed version is around */
- iload_compressed(buf1);
- return;
- }
- }
- if (auto_image_change)
- change_image_size_file(buf1);
- load_data(fp);
- fclose(fp);
- display_image();
-
- }
-
-
- iload_CAM6()
- { /* load image in CAM6 format */
- State *ap, *save_ap;
- unsigned char byteval;
- int i, j, plane;
-
- clear_msg();
- if (invalid_set_pressed())
- return;
- if (setting_sequence)
- add_sequence(iload_CAM6);
- ap = ca + ICBASE;
- save_ap = ap;
- for (i=0; i<BSQR; i++)
- ap[i] = 0;
- get_msg("Load CAM6 image file:", buf1, BUFLEN, saved_image_file);
- if (buf1[0] == NULL)
- return;
- if (expand_fname(buf1, buf1))
- return;
- strcpy(saved_image_file,buf1);
- if (!(fp = fopen(buf1, "r"))) {
- sprintf(buf2, "%s/%s", Image_dir, buf1);
- if (!(fp = fopen(buf2, "r"))) {
- /* see if a compressed version is around */
- iload_CAM6_compressed(buf1);
- return;
- }
- }
- if (auto_image_change)
- change_image_size_file(buf1);
- for (plane = 0; plane < L; plane++) {
- for (i=0; i < 65536; ) {
- byteval = 0;
- if (((i%256) >= B) || ((i / 256) >= B)) {
- (void) getc(fp);
- i += 8;
- }
- else {
- byteval = getc(fp);
- for (j=0; j < 8; j++) {
- ap[0] |= (byteval & 1) << plane;
- byteval >>= 1;
- i++;
- ap++;
- }
- }
- }
- ap = save_ap;
- }
- fclose(fp);
- display_image();
- }
-
-
- iload_CAM6_compressed(name)
- char *name;
- {
- clear_msg();
- show_msg("Couldn't find uncompressed CAM6 image,");
- show_msg("and can't load compressed CAM6 images yet");
- return;
- }
-
-
- iload_compressed(name)
- char *name;
- { /* load a compressed image into ca */
- int err;
-
- strcpy(buf1,name);
- if (buf1[0] == NULL)
- return;
- if (strcmp(&buf1[strlen(buf1)-2],".Z"))
- strcat(buf1,".Z");
- if (!stat(buf1,&statbuf)) {
- sprintf(buf2,"uncompress -c %s",buf1);
- if (!(fp = popen(buf2, "r"))) {
- show_msg("Error trying to open pipe");
- return;
- }
- }
- else {
- sprintf(buf2,"%s/%s",Image_dir,buf1);
- if (stat(buf2,&statbuf)) {
- show_msg("No such image file");
- return;
- }
- sprintf(buf2,"uncompress -c %s/%s",Image_dir,buf1);
- if (!(fp = popen(buf2,"r"))) {
- show_msg("Error trying to open pipe");
- return;
- }
- }
- if (auto_image_change)
- change_image_size_file(buf1);
- load_data(fp);
- err = pclose(fp);
- if (err) {
- sprintf(buf1,"pclose returned %d",err);
- show_msg(buf1);
- return;
- }
- display_image();
-
- }
-
-
- iload_resize()
- { /* load an image of different size */
- int s, dx, dy, err;
- char fname[80];
-
- clear_msg();
- if (invalid_set_pressed())
- return;
- if (setting_sequence)
- add_sequence(iload_resize);
- get_msg("Load image file:", buf1, BUFLEN, saved_image_file);
- if (buf1[0] == NULL)
- return;
- if (expand_fname(buf1, buf1))
- return;
- strcpy(fname,buf1);
- strcpy(saved_image_file,buf1);
- if (!(fp = fopen(buf1, "r"))) {
- sprintf(buf2,"%s/%s",Image_dir,buf1);
- if (!(fp = fopen(buf2,"r"))) {
- iload_resize_compressed(buf1);
- return;
- }
- }
- if (get_num("Side length:", &s, 1, 512, saved_side_length))
- return;
- saved_side_length = s;
- if (DIM == 1) {
- get_msg("X offset:", buf1, BUFLEN, saved_x_offset);
- strcpy(saved_x_offset,buf1);
- err = sscanf(buf1, "%d", &dx);
- } else {
- get_msg("X, Y offsets:", buf1, BUFLEN, saved_y_offset);
- strcpy(saved_y_offset,buf1);
- err = sscanf(buf1, "%d%d", &dx, &dy);
- }
- if (err != DIM && buf1[0] != NULL) {
- show_msg("Invalid entry");
- return;
- }
- if (buf1[0] == NULL)
- dx = dy = abs((B - s) / 2);
- load_resize_data(fp, s, dx, dy);
- fclose(fp);
- display_image();
-
- }
-
-
- iload_resize_compressed(name)
- char *name;
- { /* load an image of different size */
- int s, dx, dy, err;
- char fname[80];
-
- clear_msg();
- strcpy(buf1,name);
- if (buf1[0] == NULL)
- return;
- strcpy(fname,buf1);
- if (strcmp(&buf1[strlen(buf1)-2],".Z"))
- strcat(buf1,".Z");
- if (!stat(buf1,&statbuf)) {
- sprintf(buf2,"uncompress -c %s",buf1);
- if (!(fp = popen(buf2,"r"))) {
- show_msg("Error trying to open pipe");
- return;
- }
- }
- else {
- sprintf(buf2,"%s/%s",Image_dir,buf1);
- if (stat(buf2,&statbuf)) {
- show_msg("No such image file");
- return;
- }
- sprintf(buf2,"uncompress -c %s/%s",Image_dir,buf1);
- if (!(fp = popen(buf2,"r"))) {
- show_msg("Error trying to open pipe");
- return;
- }
- }
- if (get_num("Side length:", &s, 1, 512, saved_side_length))
- return;
- saved_side_length = s;
- if (DIM == 1) {
- get_msg("X offset:", buf1, BUFLEN, saved_x_offset);
- strcpy(saved_x_offset,buf1);
- err = sscanf(buf1, "%d", &dx);
- } else {
- get_msg("X, Y offsets:", buf1, BUFLEN, saved_y_offset);
- strcpy(saved_y_offset,buf1);
- err = sscanf(buf1, "%d%d", &dx, &dy);
- }
- if (err != DIM && buf1[0] != NULL) {
- show_msg("Invalid entry");
- return;
- }
- if (buf1[0] == NULL)
- dx = dy = abs((B - s) / 2);
- load_resize_data(fp, s, dx, dy);
- err = pclose(fp);
- if (err) {
- sprintf(buf1,"pclose returned %d",err);
- show_msg(buf1);
- }
- display_image();
-
- }
-
-
- ienter()
- { /* enter initial config. from keyboard */
- int i, l, base;
-
- clear_msg();
- if (setting_sequence)
- add_sequence(ienter);
- if (set_pressed()) {
- get_msg("Enter string:", buf1, BUFLEN, saved_ienter_str);
- strcpy(saved_ienter_str, buf1);
- return;
- }
- strcpy(buf1, saved_ienter_str);
- l = strlen(buf1);
- for (i = 0; i < l; i++)
- if (!is_state(buf1[i])) {
- show_msg("Invalid entry");
- return;
- }
- clear_data();
- base = ICBASE + (ICSIZE - l) / 2;
- if (DIM == 2)
- base -= B / 2;
- for (i = 0; i < l; i++)
- ca[base + i] = to_state(buf1[i]);
- display_image();
- }
-
-
- iclear()
- { /* clear current array ca */
- clear_msg();
- if (invalid_set_pressed())
- return;
- if (setting_sequence)
- add_sequence(iclear);
- clear_data();
- display_image();
- }
-
-
- iswap()
- { /* swap current and image arrays */
- clear_msg();
- if (invalid_set_pressed())
- return;
- if (setting_sequence)
- add_sequence(iswap);
- swap_data();
- display_image();
- }
-
-
- icopy()
- { /* copy current array to image array */
- clear_msg();
- if (invalid_set_pressed())
- return;
- if (setting_sequence)
- add_sequence(icopy);
- copy_data();
- clear_msg();
- show_msg("Image copied");
- }
-
-
- iinvert()
- { /* bitwise invert of current array */
- clear_msg();
- if (invalid_set_pressed())
- return;
- if (setting_sequence)
- add_sequence(iinvert);
- invert_data();
- display_image();
- }
-
-
- CM_load_image_proc()
- {
- char fname[128];
-
- clear_msg();
- if (invalid_set_pressed())
- return;
- if (setting_sequence)
- add_sequence(CM_load_image_proc);
- get_msg("Filename:", buf1, 128, saved_image_file);
- if (buf1[0] == 0)
- return;
- strcpy(saved_image_file, buf1);
- strcpy(fname, buf1);
- CM_load_image(fname);
- }
-
-
- CM_change_delay_proc()
- {
- int new_delay;
-
- clear_msg();
- if (invalid_set_pressed())
- return;
- if (setting_sequence)
- add_sequence(CM_change_delay_proc);
- if (get_num("New delay: ", &new_delay, 0, 1000000, CM_delay))
- return;
- CM_delay = new_delay;
- CM_send_delay();
- }
-
-
- CM_quick_random_proc()
- {
- clear_msg();
- if (invalid_set_pressed())
- return;
- if (setting_sequence)
- add_sequence(CM_quick_random_proc);
- CM_quick_random();
- }
-
-
- CM_general_random_proc()
- {
- clear_msg();
- if (set_pressed())
- CM_general_random_set_proc();
- else
- CM_general_random_generate_proc();
- }
-
-
- CM_general_random_set_proc()
- {
- if (setting_sequence)
- add_sequence(CM_general_random_set_proc);
- general_random_set_proc();
- }
-
-
- CM_general_random_generate_proc()
- {
- clear_msg();
- if (setting_sequence)
- add_sequence(CM_general_random_generate_proc);
- if ((saved_max_val == INTUNDEF) || (saved_ox == INTUNDEF)) {
- show_msg("Defaults never set, or cleared");
- show_msg("when configuration changed");
- return;
- }
- CM_general_random();
- }
-
-
-
-
-
- /***************** LOOKUP TABLE (LT) ROUTINES ********************/
-
-
-
- tsave_proc()
- {
- if (save_LT_compressed)
- tsave_compressed();
- else
- tsave();
- }
-
-
- tsave()
- { /* save a t-table */
- clear_msg();
- if (invalid_set_pressed())
- return;
- if (function) {
- show_msg("Can't save when using");
- show_msg("256 states.");
- return;
- }
- if (setting_sequence)
- add_sequence(tsave);
- get_msg("Save LT file:", buf1, BUFLEN, saved_rule_file);
- if (buf1[0] == NULL) {
- show_msg("");
- return;
- }
- if ((buf1[0] == '/') || (!strncmp(buf1, "./", 2)) || (!strncmp(buf1, "../", 3)) || (!save_in_LT_dir))
- ;
- else {
- strcpy(buf2, buf1);
- sprintf(buf1, "%s/%s", Table_dir, buf2);
- }
- if (expand_fname(buf1, buf1))
- return;
- strcpy(saved_rule_file, buf1);
- if ((fp = fopen(buf1, "r")) != NULL) {
- if (!confirm_overwrite()) {
- fclose(fp);
- return;
- }
- }
- fp = fopen(saved_rule_file, "w");
- if (fp == NULL) {
- clear_msg();
- show_msg("Unable to open file");
- show_msg(sys_errlist[errno]);
- return;
- }
- fwrite(ta, sizeof(*ta), TSIZE, fp);
- fclose(fp);
- show_rule(buf1);
- sprintf(buf1, "%s saved",saved_rule_file);
- show_msg(buf1);
- }
-
-
-
- tsave_compressed()
- { /* save a t-table compressed */
- int err;
-
- clear_msg();
- if (invalid_set_pressed())
- return;
- if (setting_sequence)
- add_sequence(tsave_compressed);
- get_msg("Save LT file:", buf1, BUFLEN, saved_rule_file);
- if (buf1[0] == NULL) {
- show_msg("");
- return;
- }
- if ((buf1[0] == '/') || (!strncmp(buf1, "./", 2)) || (!strncmp(buf1, "../", 3)) || (!save_in_LT_dir))
- ;
- else {
- strcpy(buf2, buf1);
- sprintf(buf1, "%s/%s", Table_dir, buf2);
- }
- if (expand_fname(buf1, buf1))
- return;
- if (strcmp(&buf1[strlen(buf1)-2],".Z"))
- strcat(buf1,".Z");
- strcpy(saved_rule_file, buf1);
- if ((fp = fopen(buf1, "r")) != NULL) {
- if (!confirm_overwrite()) {
- fclose(fp);
- return;
- }
- }
- fclose(fp);
- sprintf(buf2,"compress > %s",saved_rule_file);
- fp = popen(buf2, "w");
- fwrite(ta, sizeof(*ta), TSIZE, fp);
- err = pclose(fp);
- if (err) {
- sprintf(buf1,"pclose returned %d",err);
- show_msg(buf1);
- return;
- }
- show_rule(saved_rule_file);
- sprintf(buf1, "%s saved",saved_rule_file);
- show_msg(buf1);
- }
-
-
- edit_parm1()
- {
- int tmp_int;
-
- clear_msg();
- if (invalid_set_pressed())
- return;
- if (setting_sequence)
- add_sequence(edit_parm1);
- if (get_num("Parm1 value:", &tmp_int, 0, 255, parm1))
- return;
- parm1 = tmp_int;
- }
-
-
-
- edit_parm2()
- {
- int tmp_int;
-
- clear_msg();
- if (invalid_set_pressed())
- return;
- if (setting_sequence)
- add_sequence(edit_parm2);
- if (get_num("Parm2 value:", &tmp_int, 0, 255, parm2))
- return;
- parm2 = tmp_int;
- }
-
-
-
- load_rule() /* Load a rule (an LT or obj-code file) */
- {
- char objname[80], fname[128];
-
-
- clear_msg();
- if (invalid_set_pressed())
- return;
- if (setting_sequence)
- add_sequence(load_rule);
- get_msg("Load rule:", buf1, BUFLEN, saved_rule_file);
- if (buf1[0] == NULL)
- return;
- if (expand_fname(buf1, buf1))
- return;
- strcpy(saved_rule_file, buf1);
- if (!strcmp(&buf1[strlen(buf1)-2],".Z")) {
- tload_compressed(buf1);
- return;
- }
- strcpy(fname,buf1);
- if (auto_nhood_change)
- change_stuff_file(buf1);
- strcpy(buf1,fname);
- if (!(fp = fopen(buf1, "r"))) {
- if (function)
- sprintf(buf2, "%s/%s", Fcn_dir, buf1);
- else
- sprintf(buf2,"%s/%s",Table_dir,buf1);
- if (!(fp = fopen(buf2, "r"))) {
- /* try compressed version */
- tload_compressed(buf1);
- return;
- }
- }
- if (function) {
- sprintf(objname, "%s", buf1);
- if (stat(buf1,&statbuf)) {
- if (stat(buf2, &statbuf)) {
- show_msg("Could not open file");
- return;
- }
- sprintf(objname, "%s", buf2);
- }
- show_msg("Loading/linking file...");
- update_function = NULL;
- before_function = NULL;
- after_function = NULL;
- initialization_function = (void_func_ptr) dynamic_load(argv0, objname);
- initialization_function();
- }
- else {
- update_function = NULL;
- before_function = NULL;
- after_function = NULL;
- fread(ta, sizeof(*ta), TSIZE, fp);
- }
- fclose(fp);
- show_rule(buf1);
- strcat(buf1, " loaded");
- show_msg(buf1);
- }
-
-
- tload_compressed(name)
- char *name;
- { /* load a compressed t-table */
- int err;
-
- strcpy(buf1,name);
- if (buf1[0] == NULL)
- return;
- if (strcmp(&buf1[strlen(buf1)-2],".Z"))
- strcat(buf1,".Z");
- if (auto_nhood_change)
- change_stuff_file(name);
- if (!stat(buf1,&statbuf)) {
- if (function) {
- show_msg("Can't load compressed .o files yet");
- return;
- }
- sprintf(buf2,"uncompress -c %s",buf1);
- if (!(fp = popen(buf2, "r"))) {
- show_msg("Error trying to open pipe");
- return;
- }
- }
- else {
- if (function)
- sprintf(buf2, "%s/%s", Fcn_dir, buf1);
- else
- sprintf(buf2,"%s/%s",Table_dir,buf1);
- if (stat(buf2,&statbuf)) {
- show_msg("no such t-file");
- return;
- }
- if (function) {
- show_msg("Can't load compressed .o files yet");
- return;
- }
- sprintf(buf2,"uncompress -c %s/%s",Table_dir,buf1);
- if (!(fp = popen(buf2, "r"))) {
- show_msg("Error trying to open pipe");
- return;
- }
- }
- fread(ta, sizeof(*ta), TSIZE, fp);
- err = pclose(fp);
- if (err) {
- sprintf(buf1,"pclose returned %d",err);
- show_msg(err);
- return;
- }
- show_rule(buf1);
- strcat(buf1, " loaded");
- show_msg(buf1);
- }
-
-
- tclear_proc()
- { /* set all t-table entries to UNDEF */
- int i;
-
- if (invalid_set_pressed())
- return;
- if (function) {
- clear_msg();
- show_msg("no lookup table when");
- show_msg("using 256 states");
- }
- if (setting_sequence)
- add_sequence(tclear);
- for (i = 0; i < TSIZE; i++)
- ta[i] = UNDEF;
- clear_rule();
- }
-
- talter()
- { /* select and alter a t-table entry */
- State image;
- int aa;
- char nhood[BUFLEN];
-
- clear_msg();
- if (invalid_set_pressed())
- return;
- if (function) {
- clear_msg();
- show_msg("no lookup table when");
- show_msg("using 256 states");
- }
- if (setting_sequence)
- add_sequence(talter);
- get_msg("Neighborhood:", nhood, BUFLEN, saved_nhood);
- if (nhood[0] == 0)
- return;
- strcpy(saved_nhood, buf1);
- if (strlen(nhood) != N) {
- show_msg("Illegal neighhborhood");
- return;
- }
- alter_nhood(nhood);
-
- } /* talter */
-
-
-
- tgenerate()
- { /* generate Wolfram's basic rules */
- int rule, i;
-
- clear_msg();
- if (invalid_set_pressed())
- return;
- if (function) {
- clear_msg();
- show_msg("no lookup table when");
- show_msg("using 256 states");
- }
- if (setting_sequence)
- add_sequence(tgenerate);
- if (get_num("Rule number:", &rule, 0, 255, saved_rule_number))
- return;
- saved_rule_number = rule;
- for (i = 0; i < 8; i++) {
- ta[i] = rule & 1;
- rule >>= 1;
- }
- }
-
-
- lambda_proc()
- {
- if (function) {
- clear_msg();
- show_msg("Lambda invalid when using");
- show_msg("256 states");
- return;
- }
- if (set_pressed())
- tlambda_set();
- else
- tlambda_generate();
- }
-
-
- tlambda_set()
- {
- int i, percent;
-
- clear_msg();
- if (setting_sequence)
- add_sequence(tlambda_set);
- if (get_num("Enter percentage: ", &percent, 0, 100, saved_lambda_percent))
- return;
- saved_lambda_percent = percent;
- }
-
-
- tlambda_generate()
- {
- int i, j;
- char nhood_str[10];
-
- if (setting_sequence)
- add_sequence(tlambda_generate);
- if (saved_lambda_percent == INTUNDEF) {
- clear_msg();
- show_msg("Lambda value never set");
- return;
- }
- clear_msg();
- sprintf(buf1, "Generating tbl with lambda=%d",saved_lambda_percent);
- show_msg(buf1);
- tclear();
- ta[0] = 0;
-
- for (i=0; i < S; i++) { /* set transition for homogeneous nborhoods */
- for (j=0; j<N; j++)
- nhood_str[j] = '0'+i;
- nhood_str[N] = '\0';
- tstore(nhood_str, i);
- }
- for (i=0; i<TSIZE; i++) {
- if (ta[i] == UNDEF) {
- to_nhood(i, nhood_str);
- if ((random()%100) < saved_lambda_percent)
- tstore(nhood_str, (random()%(S-1))+1);
- else
- tstore(nhood_str, 0);
- }
- }
- clear_msg();
- sprintf(buf1, "Lambda = %1.2f", compute_lambda());
- }
-
-
- lambda_step_proc()
- {
- if (function) {
- clear_msg();
- show_msg("lambda-step invalid when");
- show_msg("using 256 states");
- return;
- }
- if (set_pressed())
- tlambda_step_set();
- else
- tlambda_step_generate();
- }
-
-
- tlambda_step_set()
- {
- int i, stepval;
-
- clear_msg();
- if (setting_sequence)
- add_sequence(tlambda_step_set);
- if (get_num("Enter step-value: ", &stepval, -TSIZE, TSIZE, saved_lambda_increment))
- return;
- saved_lambda_increment = stepval;
- saved_lambda_inc_set = 1;
- }
-
-
- tlambda_step_generate()
- {
- int i, j, k;
- char nhood_str[10];
-
- if (setting_sequence)
- add_sequence(tlambda_step_generate);
- if (!saved_lambda_inc_set) {
- clear_msg();
- show_msg("Lambda increment never set");
- return;
- }
- clear_msg();
- if (saved_lambda_increment == 0) {
- show_msg("Increment is 0 - no change");
- return;
- }
- if (saved_lambda_increment > 0)
- sprintf(buf1, "Adding %d transitions to tbl",saved_lambda_increment);
- else
- sprintf(buf1, "Clearing %d transitions in tbl", -1 * saved_lambda_increment);
- show_msg(buf1);
-
- if (saved_lambda_increment > 0) {
- for (i=0; i < saved_lambda_increment; i++) {
- j = random()%TSIZE;
- for (k=0; (k < TSIZE) && (ta[j] != 0); k++, j=(j+1)%TSIZE) ;
- if (k < TSIZE) {
- /* printf("setting tbl entry # %d (k=%d)\n",j,k); */
- to_nhood(j, nhood_str);
- tstore(nhood_str, (random()%(S-1))+1);
- }
- }
- }
- else {
- for (i=0; i < -1 * saved_lambda_increment; i++) {
- j = random()%TSIZE;
- for (k=0; (k < TSIZE) && (ta[j] == 0); k++, j=(j+1)%TSIZE) ;
- if (k < TSIZE) {
- /* printf("clearing tbl entry # %d (k=%d)\n",j,k); */
- to_nhood(j, nhood_str);
- tstore(nhood_str, 0);
- }
- }
- }
- sprintf(buf1, "Lambda = %1.2f", compute_lambda());
- show_msg(buf1);
- }
-
-
- rho_proc()
- {
- if (function) {
- clear_msg();
- show_msg("Rho invalid when using");
- show_msg("256 states");
- return;
- }
- if (set_pressed())
- trho_set();
- else
- trho_generate();
- }
-
-
- trho_set()
- {
- int done, sum, r, j, err, tmp_int;
- int i, percent[16];
-
- if (setting_sequence)
- add_sequence(trho_set);
- clear_msg();
- sum = 0;
- switch (S) {
- case 2:
- clear_msg();
- sprintf(buf1, "percentage of 1");
- if (get_num(buf1, &percent[1], 0, 100, 0))
- return;
- break;
- case 4:
- case 8:
- clear_msg();
- sprintf(buf1, "percentages of 1-%d", S-1);
- get_msg(buf1, buf2, BUFLEN, "");
- err = sscanf(buf2, "%d %d %d %d %d %d %d %d",&percent[1],
- &percent[2],&percent[3],&percent[4],&percent[5],
- &percent[6],&percent[7],&tmp_int);
- if (err != S-1) {
- sprintf(buf1, "wrong # of percentages entered");
- show_msg(buf1);
- return;
- }
- break;
- case 16:
- clear_msg();
- sprintf(buf1, "percentages of 1-7");
- get_msg(buf1, buf2, BUFLEN, "");
- err = sscanf(buf2, "%d %d %d %d %d %d %d %d",&percent[1],
- &percent[2],&percent[3],&percent[4],&percent[5],
- &percent[6],&percent[7],&tmp_int);
- if (err != 7) {
- sprintf(buf1, "wrong # of percentages entered");
- show_msg(buf1);
- return;
- }
- clear_msg();
- sprintf(buf1, "percentages of 8-15");
- get_msg(buf1, buf2, BUFLEN, "");
- err = sscanf(buf2, "%d %d %d %d %d %d %d %d %d",&percent[8],
- &percent[9],&percent[10],&percent[11],&percent[12],
- &percent[13],&percent[14],&percent[15],&tmp_int);
- if (err != 8) {
- sprintf(buf1, "wrong # of percentages entered");
- show_msg(buf1);
- return;
- }
- break;
- }
- for (i=1; i<S; i++)
- sum += percent[i];
- if (sum > 100) {
- show_msg("Sum was greater than 100%");
- return;
- }
- for (i=1; i < S; i++)
- saved_rho_percent[i] = percent[i];
- }
-
-
- trho_generate()
- {
- int done, sum, r, j;
- int i, percent[16], p[16];
- char nhood_str[10];
-
- clear_msg();
- if (setting_sequence)
- add_sequence(trho_generate);
- if (saved_rho_percent[0] == INTUNDEF) {
- show_msg("default never set, or cleared");
- show_msg("when configuration changed");
- return;
- }
- show_msg("Setting percentage rho");
- switch (S) {
- case 2:
- case 4:
- case 8:
- sprintf(buf1, "%d", saved_rho_percent[1]);
- for (i=2; i<S; i++) {
- sprintf(buf2, " %d", saved_rho_percent[i]);
- strcat(buf1, buf2);
- }
- show_msg(buf1);
- break;
- case 16:
- sprintf(buf1, "%d", saved_rho_percent[1]);
- for (i=2; i<= 8; i++) {
- sprintf(buf2, " %d", saved_rho_percent[i]);
- strcat(buf1, buf2);
- }
- show_msg(buf1);
- sprintf(buf1, "%d", saved_rho_percent[8]);
- for (i=9; i<16; i++) {
- sprintf(buf2, " %d", saved_rho_percent[i]);
- strcat(buf1, buf2);
- }
- show_msg(buf1);
- break;
- }
- show_msg("generating table...");
- p[0] = 0;
- for (i=1; i < S; i++)
- p[i] = p[i-1] + saved_rho_percent[i];
- tclear();
- for (i=0; i < S; i++) { /* set transition for homogeneous nborhoods */
- for (j=0; j<N; j++)
- nhood_str[j] = '0'+i;
- nhood_str[N] = '\0';
- tstore(nhood_str, i);
- }
- for (i=0; i < TSIZE; i++) {
- if (ta[i] == UNDEF) {
- to_nhood(i, nhood_str);
- done = 0;
- r = random()%100;
- for (j=1; j < S; j++) {
- if ((!done) && (r < p[j])) {
- done = 1;
- tstore(nhood_str, j);
- }
- }
- if (!done)
- tstore(nhood_str, 0);
- }
- }
- show_msg("done");
- }
-
-
- alter_nhood(nhood) /* alter a given t-table entry */
- char *nhood;
- {
- State image;
- int aa;
- char tstr[BUFLEN], saved_nhood[20];
-
- strcpy(buf2, nhood);
- strcpy(saved_nhood, nhood);
- aa = to_index(buf2); /* convert string to index */
-
- if (aa == TABLE_ERR)
- show_msg("Illegal neighborhood");
- else {
- sprintf(tstr, "%s => %c; new image?", buf2, to_char(ta[aa]));
- clear_msg();
- get_msg(tstr, buf1, BUFLEN, "");
- if (buf1[0] == NULL)
- show_msg("");
- else if (!is_state(buf1[0]))
- show_msg("Illegal image");
- else {
- image = to_state(buf1[0]);
- sprintf(tstr, "%s => %c ok? ", saved_nhood, buf1[0]);
- get_msg(tstr, buf1, BUFLEN, "");
- if (buf1[0] == 'y')
- tstore(saved_nhood, image);
- }
- } /* else */
-
- } /* alter_nhood */
-
-
- tstore(nhood, image) /* encode t-table index of ascii nhood */
- char nhood[];
- State image;
-
- {
- int aa, ab, ac, ad; /* vars for four nhood rotations */
-
- aa = to_index(nhood);
- if (!table_symmetry) {
- ta[aa] = image;
- return;
- }
- rotate(nhood);
- ab = to_index(nhood);
- rotate(nhood);
- ac = to_index(nhood);
- rotate(nhood);
- ad = to_index(nhood);
-
- /* now save image */
-
- ta[aa] = ta[ab] = ta[ac] = ta[ad] = image;
-
- } /* tstore */
-
-
-
- /********************* BUFFER ROUTINES *********************/
-
- bload()
- {
- clear_msg();
- if (invalid_set_pressed())
- return;
- if (setting_sequence)
- add_sequence(bload);
- bbufop(BUFOP_LOAD, "Load from");
- }
-
- bsave()
- {
- clear_msg();
- if (invalid_set_pressed())
- return;
- if (setting_sequence)
- add_sequence(bsave);
- bbufop(BUFOP_SAVE, "Save to");
- }
-
- bswap()
- {
- clear_msg();
- if (invalid_set_pressed())
- return;
- if (setting_sequence)
- add_sequence(bswap);
- bbufop(BUFOP_SWAP, "Swap to");
- }
-
- bxor()
- {
- clear_msg();
- if (invalid_set_pressed())
- return;
- if (setting_sequence)
- add_sequence(bxor);
- bbufop(BUFOP_XOR, "Xor with");
- }
-
- bor()
- {
- clear_msg();
- if (invalid_set_pressed())
- return;
- if (setting_sequence)
- add_sequence(bor);
- bbufop(BUFOP_OR, "Or with");
- }
-
- band()
- {
- clear_msg();
- if (invalid_set_pressed())
- return;
- if (setting_sequence)
- add_sequence(band);
- bbufop(BUFOP_AND, "And with");
- }
-
-
- bbufop(op, name) /* do bit-operation with buffer */
- int op;
- char *name;
- {
- int n, err;
- char str[BUFLEN];
- clear_msg();
- sprintf(str, "%s buffer #:", name);
- err = get_num(str, &n, 0, NBUFFERS - 1, saved_buffer);
- if (err)
- return;
- else {
- saved_buffer = n;
- switch (op) {
- case BUFOP_XOR:
- xor_with_buffer(n);
- break;
- case BUFOP_OR:
- or_with_buffer(n);
- break;
- case BUFOP_AND:
- and_with_buffer(n);
- break;
- case BUFOP_LOAD:
- load_from_buffer(n);
- break;
- case BUFOP_SAVE:
- copy_to_buffer(n);
- show_msg("Image copied");
- break;
- case BUFOP_SWAP:
- swap_to_buffer(n);
- break;
- } /* switch */
- display_image();
- } /* else */
- } /* bbufop */
-
-
-
- /*********************** PLANE ROUTINES ***********************/
-
- pclear()
- { /* clear given bitplanes */
- int mask;
-
- clear_msg();
- if (invalid_set_pressed())
- return;
- if (setting_sequence)
- add_sequence(pclear);
- if (get_num("Plane mask:", &mask, 1, AMASK, saved_plane_mask))
- return;
- saved_plane_mask = mask;
- clear_planes(mask);
- display_image();
- }
-
-
- pinvert()
- { /* invert given bitplanes */
- int mask;
-
- clear_msg();
- if (invalid_set_pressed())
- return;
- if (setting_sequence)
- add_sequence(pinvert);
- if (get_num("Plane mask:", &mask, 1, AMASK, saved_plane_mask))
- return;
- saved_plane_mask = mask;
- invert_planes(mask);
- display_image();
- }
-
- /******************** DRAWING ROUTINES ***********************/
-
- plot(x,y,val)
- int x,y,val;
- {
- if ((x < 0) || (x >= B) || (y < 0) || (y >= B))
- return;
- ca[y*B + x + ABASE] = val;
- }
-
-
- draw_horizontal_line(row, start_col, end_col, val)
- int row, start_col, end_col, val;
- {
- int index, x, tmp;
-
- if (start_col > end_col) {
- tmp = start_col;
- start_col = end_col;
- end_col = tmp;
- }
- index = row*B + start_col + ABASE;
- for (x=start_col; x <= end_col; x++)
- ca[index++] = val;
- display_image();
- }
-
-
- draw_vertical_line(col, start_row, end_row, val)
- int col, start_row, end_row, val;
- {
- int index, y, tmp;
-
- if (start_row > end_row) {
- tmp = start_row;
- start_row = end_row;
- end_row = tmp;
- }
- index = start_row*B + col + ABASE;
- for (y=start_row; y <= end_row; y++) {
- ca[index] = val;
- index += B;
- }
- display_image();
- }
-
-
- draw_arbitrary_line(start_x, start_y, end_x, end_y, val)
- int start_x, start_y, end_x, end_y, val;
- {
- int index;
- int dx, dy, count, error, x, y, tmp;
-
- dx = end_x - start_x;
- dy = end_y - start_y;
- error = 0;
-
- if (dy < 0) {
- tmp = start_x;
- start_x = end_x;
- end_x = tmp;
- tmp = start_y;
- start_y = end_y;
- end_y = tmp;
- dx = -dx;
- dy = -dy;
- }
- plot(start_x,start_y,val);
- x = start_x;
- y = start_y;
- if (dx >= 0) {
- if (dx == dy) {
- for (count = 1; count <= dx-1; count++)
- plot(x++, y++, val);
- }
- else if (dx >= dy) {
- for (count = 1; count <= dx-1; count++) {
- if (error < 0) {
- x++;
- plot(x,y,val);
- error = error+dy;
- }
- else {
- x++;
- y++;
- plot(x,y,val);
- error = error + dy - dx;
- }
- }
- }
- else {
- for (count = 1; count <= dy-1; count++) {
- if (error < 0) {
- x++;
- y++;
- plot(x,y,val);
- error = error + dy - dx;
- }
- else {
- y++;
- plot(x,y,val);
- error = error-dx;
- }
- }
- }
- }
- else {
- dx = -dx;
- /* if (dx == dy) {
- for (count = 1; count <= dx-1; count++)
- plot(x--, y++, val);
- }
- else */ if (dx >= dy) {
- for (count = 1; count <= dx-1; count++) {
- if (error < 0) {
- x--;
- plot(x,y,val);
- error = error+dy;
- }
- else {
- x--;
- y++;
- plot(x,y,val);
- error = error-dx+dy;
- }
- }
- }
- else {
- for (count=1; count <= dy-1; count++) {
- if (error < 0) {
- x--;
- y++;
- plot(x,y,val);
- error = error-dx+dy;
- }
- else {
- y++;
- plot(x,y,val);
- error = error-dx;
- }
- }
- }
- }
- plot(end_x,end_y,val);
- display_image();
- }
-
-
- draw_hollow_circ(center_x, center_y, x1, y1, val)
- int center_x, center_y, x1, y1, val;
- {
- double radius, dx, dy;
- double dtheta, ct, st, x, y, xtemp, xc, yc;
-
- xc = (double) center_x;
- yc = (double) center_y;
- dx = (double) abs(x1-center_x);
- dy = (double) abs(y1-center_y);
- radius = sqrt((dx*dx) + (dy*dy));
- if (radius == 0)
- return;
- dtheta = 1/radius;
- ct = cos(dtheta);
- st = sin(dtheta);
- x = 0.0;
- y = radius;
- while (y >= x) {
- plot((int)(xc+x),(int)(yc+y),val);
- plot((int)(xc-x),(int)(yc+y),val);
- plot((int)(xc+x),(int)(yc-y),val);
- plot((int)(xc-x),(int)(yc-y),val);
- plot((int)(xc+y),(int)(yc+x),val);
- plot((int)(xc-y),(int)(yc+x),val);
- plot((int)(xc+y),(int)(yc-x),val);
- plot((int)(xc-y),(int)(yc-x),val);
- xtemp = x;
- x = (x*ct - y*st);
- y = (y*ct + xtemp*st);
- }
- display_image();
- }
-
-
- draw_shaded_circ(center_x, center_y, x1, y1, xii, yii, val)
- int center_x, center_y, x1, y1, xii, yii, val;
- {
- double dx, dy, radius;
- double xc, yc, xi, yi, xl, xr, x, y, radical;
-
- xc = (double) center_x;
- yc = (double) center_y;
- dx = (double) abs(x1-center_x);
- dy = (double) abs(y1-center_y);
- radius = sqrt((dx*dx) + (dy*dy));
- xi = (double) xii;
- yi = (double) yii;
- if (radius == 0)
- return;
- y = yc+radius;
- plot((int)xc, (int)y, val);
- if (yi)
- y = y-yi;
- else
- y--;
- while (y > (yc-radius)) {
- radical = sqrt(radius*radius - (y-yc)*(y-yc));
- xl = xc - radical;
- xr = xc + radical;
- x = xl;
- if (xi && yi) {
- while (x < xr) {
- plot((int)x, (int)y, val);
- x = x + xi;
- }
- plot((int)xr, (int)y, val);
- y = y - yi;
- }
- else {
- plot((int)xl, (int)y, val);
- plot((int)xr, (int)y, val);
- y--;
- }
- }
- y = yc - radius;
- plot((int)xc, (int)y, val);
- display_image();
- }
-
- /********************* UTILITIES AND GENERAL ROUTINES********************/
-
-
-
- /*
- * See if the "set" button was just pressed... if so, return 1, else
- * return 0. In either case, unset the "set_just_pressed" variable
- */
- set_pressed()
- {
- if (set_just_pressed) {
- set_just_pressed = 0;
- return 1;
- }
- else
- return 0;
- }
-
-
- /*
- * If set was just pressed, then complain that set has no meaning for this
- * routine, and clear the flag and return 1. If set was not pressed, return 0.
- */
- invalid_set_pressed()
- {
- if (set_just_pressed) {
- clear_msg();
- show_msg("'Set' invalid for this function");
- set_just_pressed = 0;
- return 1;
- }
- else
- return 0;
- }
-
-
- /*
- * Find the full pathname of cellsim that is being executed,
- * so we can do dynamic linking if we need to.
- */
- void
- which(a0, result)
- char *a0, *result;
- {
- char *path, directory[256];
- int i, j;
-
- if ((!strncmp(a0, "./", 2)) || (!strncmp(a0, "../", 3)) || (a0[0] == '/')) {
- strcpy(result, a0);
- return;
- }
- if ((path = getenv("PATH")) == NULL)
- quit("Couldn't look up PATH from the environment!");
- i = 0;
- while (i < strlen(path)) {
- j = 0;
- while ((path[i] != ':') && (path[i] != '\0'))
- directory[j++] = path[i++];
- i++;
- directory[j++] = '/';
- directory[j++] = '\0';
- strcat(directory, a0);
- /* Now "directory" contains the next try */
- if (!stat(directory, &statbuf)) {
- strcpy(result, directory);
- return;
- }
- }
- }
-
-
- /*
- * Expand a "tilde" filename or filename with wildcards in it.
- */
- int
- expand_fname(src, dest)
- char *src, *dest;
- {
- FILE *fp;
- char command_str[256];
- int err, i;
-
- if (!strlen(src))
- return;
- sprintf(command_str, "/bin/sh -c \"/bin/csh -f -c '/bin/echo %s' 2>&1\"",src);
- if ((fp = popen(command_str, "r")) == NULL) {
- clear_msg();
- show_msg("error trying to expand filename");
- return 1;
- }
- fgets(dest, BUFLEN, fp);
- if ((dest[strlen(dest)-1] == '\n') || (dest[strlen(dest)-1] == '\r'))
- dest[strlen(dest)-1] = '\0';
- if ((!strncmp(dest,"Unknown user",12))||(!strncmp(dest,"No match.",9))) {
- clear_msg();
- show_msg(dest);
- pclose(fp);
- return 1;
- }
- for (i=0; i<strlen(dest); i++)
- if (dest[i] == ' ') { /* multiple matches */
- clear_msg();
- show_msg("Multiple filenames matched.");
- return 1;
- }
- if (strlen(dest) == 0) {
- clear_msg();
- show_msg("error trying to expand filename");
- return 1;
- }
- err = pclose(fp);
- if (err) {
- clear_msg();
- show_msg("Error trying to expand filename");
- return 1;
- }
- return 0;
- }
-
-
-
- /*
- * Two routines to print an error message and exit. (One that takes
- * one parameter, another that takes 2).
- */
- void
- quit(s)
- char *s;
- {
- fprintf(stderr, "%s\n", s);
- exit(1);
- }
-
-
- void
- quit2(s1,s2)
- char *s1, *s2;
- {
- fprintf(stderr, s1, s2);
- fprintf(stderr, "\n");
- exit(1);
- }
-
-
- int
- confirm_overwrite()
- {
- get_msg("Overwrite file?", buf1, 80, "");
- if (buf1[0] != 'y') {
- show_msg("Save cancelled.");
- return 0;
- }
- return 1;
- }
-
-
- /*
- * This is needed because tclear_proc adds itself to the current sequence
- * if one is being created. We need a tclear routine that won't do that.
- */
- tclear()
- { /* set all t-table entries to UNDEF */
- int i;
-
- if (invalid_set_pressed())
- return;
- for (i = 0; i < TSIZE; i++)
- ta[i] = UNDEF;
- clear_rule();
- }
-
-
- int
- is_state(c) /* is given character a valid state? */
- char c;
- {
- if (S >= 16)
- return ((c >= ASCZ && c < ASCZ + 10) || (c >= 'a' && c <= 'f')
- || (c >= 'A' && c <= 'F'));
- else
- return (c >= ASCZ && c < ASCZ + S);
- }
-
-
- show_next_state(x, y) /* at given point, show nhood and next state */
- unsigned short x, y;
- {
- int a, i;
- char state;
-
- /* initialize top and bottom buffers */
-
- for (i = 0; i < B; i++) {
- ca[i] = ca[BSQR + i];
- ca[BBUF + i] = ca[ABASE + i];
- }
-
- a = get_address(x, y);
-
- if (use_CM) {
- if (function) {
- clear_msg();
- show_msg("Probe not implement with");
- show_msg("256 states on CM yet");
- return;
- }
- i = CM_probe(x,y,a);
- to_nhood(a, buf2);
- state = to_char(i);
- sprintf(buf1, "%s -> %d", buf2, i);
- clear_msg();
- show_msg(buf1);
- return;
- }
- state = to_char(ta[a]); /* image state in t-table */
- to_nhood(a, buf2);
-
- sprintf(buf1, "%s => %c", buf2, state);
- clear_msg();
- show_msg(buf1);
-
- } /* show_next_state() */
-
-
- clear_sequence(n)
- short n;
- {
- sequence_length[n-1] = 0;
- }
-
-
- add_sequence(fptr)
- int_func_ptr fptr;
- {
- sequence_array[setting_sequence-1][sequence_length[setting_sequence-1]++] = fptr;
- }
-
-
-
- /*
- * Compare the current image with the previous image.
- * Returns 1 if they differ, 0 if the same.
- */
- compare_images()
- {
- unsigned char *ptr1, *ptr2;
- int i;
-
- ptr1 = ca+ICBASE;
- ptr2 = ia+ICBASE;
- i = 0;
- while (i < ICSIZE) {
- if (*ptr1 != *ptr2)
- i = ICSIZE+1;
- else
- i++;
- ptr1++;
- ptr2++;
- }
- if (i == ICSIZE+1) /* images are different */
- return 1;
- else
- return 0;
- }
-
-
- /*
- * See if the current array is empty. If so, return 1, else
- * return 0.
- */
- array_is_empty()
- {
- unsigned char *ptr;
- int i;
-
- ptr = ca + ICBASE;
- i = 0;
- while (i < ICSIZE) {
- if (*ptr)
- i = ICSIZE+1;
- else
- i++;
- ptr++;
- }
- if (i == ICSIZE+1) {
- /* fprintf(stderr,"array_is_empty() returning 0\n"); */
- return 0;
- }
- else {
- /* fprintf(stderr,"array_is_empty() returning 1\n"); */
- return 1;
- }
- }
-
-
- double
- compute_lambda()
- {
- int i, sum;
-
- sum = 0;
- for (i=0; i<TSIZE; i++)
- if (ta[i] && (ta[i] != UNDEF))
- sum++;
- return (((double)sum)/((double)TSIZE) * (double)100);
- }
-
-
- int
- valid_state(nborhood, nstates, radius)
- int nborhood, nstates, radius;
- {
- if ((nstates != 2) && (nstates != 4) && (nstates != 8) &&
- (nstates != 16) && (nstates != 256))
- return 0;
- if (nstates != 256) {
- if ((nborhood == NH_MOORE ||
- (nborhood == NH_LIN && radius == 3)) && nstates > 4)
- return 0;
- }
- if (radius > 3)
- return 0;
- return 1;
- }
-
-
- /* Do an emergency save of the LT (if there is currently one)
- * when a segmentation fault occurs
- */
- static void
- emergency_LT_save()
- {
- FILE *fp;
-
- unlink("/tmp/cellsim.LT");
- if ((fp=fopen("/tmp/cellsim.LT"))==NULL)
- quit("Couldn't perform emergency LT save");
- fwrite(ta, sizeof(*ta), TSIZE, fp);
- fclose(fp);
- default_segv_func();
- exit(1);
- }
-
-
- /*** DERIVE -- Derive t-functions by comparing two images *****/
-
- derive(x, y, nhood, iptr)
- int x, y, nhood;
- State *iptr;
-
- {
- unsigned int table_state, image_state;
- char str[BUFLEN];
- int aptr;
-
-
- image_state = *iptr;
- table_state = ta[nhood];
-
- to_nhood(nhood, str);
-
- if (table_state == UNDEF)
- tstore(str, image_state);
-
- else if (table_state != image_state) {
- mark_site(x, y); /* display cell marker */
-
- clear_msg();
- show_msg("conflict");
- sprintf(buf1, "current rule: %s => %c", str, to_char(table_state));
- show_msg(buf1);
- sprintf(buf1, "proposed: %s => %c", str, to_char(image_state));
- show_msg(buf1);
- get_msg("change? (y,n,q)", buf1, BUFLEN, "");
-
- switch (buf1[0]) {
-
- case 'y':
- tstore(str, image_state);
- display_site(x, y, image_state);
- break;
-
- case 'q':
- display_site(x, y, table_state);
- *iptr = table_state;
- return (0);
-
- default:
- display_site(x, y, table_state);
- *iptr = table_state;
- break;
-
- } /* switch */
-
- } /* else if */
- return (1);
-
- } /* derive() */
-
-
- undef(ptr) /* handle an undefined neighborhood */
- int ptr;
- {
- State image;
- int x, y, a, i, flag = TRUE;
- State save_state;
- char saved_nhood[BUFLEN];
-
- i = ptr - ABASE;
- x = i % B;
- y = i / B;
-
- a = get_address(x, y);
-
- to_nhood(a, buf2); /* get nhood in ascii c-clockwise format */
- strcpy(saved_nhood, buf2);
-
- mark_site(x, y);
-
- save_state = ca[ptr];
-
- clear_msg();
- sprintf(buf1, "Undefined nhood %s", buf2);
- show_msg(buf1);
- get_msg("Image ('q' to quit):", buf1, BUFLEN, "");
- if (buf1[0] != NULL && buf1[0] != 'q') {
- flag = FALSE;
- if (!is_state(buf1[0])) {
- show_msg("ILLEGAL IMAGE, try again:", buf1, BUFLEN);
- } else {
- image = to_state(buf1[0]);
- tstore(saved_nhood, image);
- }
-
- } /* if (buf1[0]...) */
- display_site(x, y, save_state);
-
- return (flag);
-
- } /* undef */
-
-
-
- random_image(side, percent) /* generate a random configuration */
- int side, percent;
- {
- int i, org, xcoord, ycoord, index, state;
- int grid_size, bucket_size, numcells;
- float density;
-
- org = (B - side) / 2;
- density = percent / 100.0;
-
- numcells = density * side * side;
- bucket_size = RSIZE / S;
- grid_size = RSIZE / side;
-
- clear_data();
- for (i = 0; i < numcells; ) {
- xcoord = (random() & RMASK) / grid_size;
- ycoord = (random() & RMASK) / grid_size;
- state = (random() & RMASK) / bucket_size;
-
- index = (ycoord + org) * B + xcoord + org + ABASE;
- if (ca[index] == 0) {
- ca[index] = state;
- i++;
- }
- }
-
- display_image();
-
- } /* random_image */
-
-
-
-
- set_image_dir()
- {
- clear_msg();
- if (invalid_set_pressed())
- return;
- if (setting_sequence)
- add_sequence(set_image_dir);
- get_msg("Enter new Image_dir:", buf1, BUFLEN, Image_dir);
- if (expand_fname(buf1, buf1))
- return;
- if (buf1[0] != '\0')
- sprintf(Image_dir, "%s", buf1);
- return;
- }
-
-
- set_fcn_dir()
- {
- clear_msg();
- if (invalid_set_pressed())
- return;
- if (setting_sequence)
- add_sequence(set_fcn_dir);
- get_msg("Enter new Fcn_dir:", buf1, BUFLEN, Fcn_dir);
- if (expand_fname(buf1, buf1))
- return;
- if (buf1[0] != '\0')
- sprintf(Fcn_dir, "%s", buf1);
- return;
- }
-
-
- set_table_dir()
- {
- clear_msg();
- if (invalid_set_pressed())
- return;
- if (setting_sequence)
- add_sequence(set_table_dir);
- get_msg("Enter new Table_dir:", buf1, BUFLEN, Table_dir);
- if (expand_fname(buf1, buf1))
- return;
- if (buf1[0] != '\0')
- sprintf(Table_dir, "%s", buf1);
- return;
- }
-
-
- set_cmap_dir()
- {
- clear_msg();
- if (invalid_set_pressed())
- return;
- if (setting_sequence)
- add_sequence(set_cmap_dir);
- get_msg("Enter new Cmap_dir:", buf1, BUFLEN, Cmap_dir);
- if (expand_fname(buf1, buf1))
- return;
- if (buf1[0] != '\0')
- sprintf(Cmap_dir, "%s", buf1);
- return;
- }
-
-
-
- /******************************** CHANGE ROUTINES ***********************/
- /* These are the routines used to change the neighborhood and number */
- /* of states, or the image size. */
-
-
-
- /* This routine is callable from the "rules" menu, and allows the
- * user to switch to a specified neighorhood and number of states
- */
- change_stuff_proc()
- {
- clear_msg();
- if (invalid_set_pressed())
- return;
- if (setting_sequence)
- add_sequence(change_stuff_proc);
- get_msg("Enter string:", buf1, BUFLEN, "");
- if (buf1[0] != '\0')
- change_stuff(buf1);
- }
-
-
-
- /*
- * This routine will be called by the various rule-loading routines
- * to automatically switch to the proper neighborhood and number of
- * states based on the file name.
- */
- change_stuff_file(name)
- char *name;
- {
- char fname[80];
- int i, j, radius;
- char *ptr, tmp_str[80];
-
- strcpy(fname, name);
- if (!strcmp(&fname[strlen(fname)-2], ".Z"))
- fname[strlen(fname)-2] = '\0';
- j = -1;
- if (!strcmp(&fname[strlen(fname)-2], ".o")) {
- for (i=1; i < strlen(fname); i++)
- if ((!strncmp(&fname[i], "256", 3)) && (fname[i-2] == '.'))
- j = i-1;
- switch (fname[j]) {
- case 'm':
- change_stuff("m256");
- break;
- case 'M':
- change_stuff("M256");
- break;
- case 'v':
- change_stuff("v256");
- break;
- case 'l':
- radius = 1;
- if (fname[j+4] == 'r')
- sprintf(tmp_str, "l256r%c", fname[j+5]);
- else
- sprintf(tmp_str, "l256");
- change_stuff(tmp_str);
- break;
- default:
- sprintf(tmp_str, "Illegal nborhood char '%c'", fname[j]);
- show_msg(tmp_str);
- return;
- break;
- }
- return;
- }
- /* If we reach here, then it was not a ".o" file */
- ptr = &fname[strlen(fname)-1];
- while ((*ptr != '.') && (ptr != fname))
- ptr--;
- if (ptr == fname)
- return;
- ptr++;
- change_stuff(ptr);
- }
-
-
- /*
- * This is the routine that gets called by the previous 2, to actually
- * perform the neighborhood change
- */
- change_stuff(str)
- char *str;
- {
- int nborhood, nstates, radius, i, j;
- char tmp_str[80], tmp2_str[80], save_str[80];
-
- strcpy(save_str, str);
- clear_msg();
- switch (str[0]) {
- case 'm':
- nborhood = NH_MOORE;
- break;
- case 'v':
- nborhood = NH_VONN;
- break;
- case 'M':
- nborhood = NH_MARG;
- break;
- case 'l':
- nborhood = NH_LIN;
- break;
- default:
- show_msg("Illegal nborhood");
- break;
- }
- i = 1;
- j = 0;
- while ((str[i] != '\0') && (str[i] != 'r'))
- tmp_str[j++] = str[i++];
- tmp_str[j] = '\0';
- sscanf(tmp_str, "%d", &nstates);
- radius = 1;
- if (str[i] == 'r')
- sscanf(&(str[i+1]), "%d", &radius);
- if (!valid_state(nborhood, nstates, radius)) {
- show_msg("Invalid neighborhood config");
- return;
- }
- if (use_CM) {
- if (!valid_CM_state(nborhood, nstates, radius)) {
- show_msg("Invalid nhood for CM");
- return;
- }
- }
- if (nborhood == NH_LIN) {
- if ((nborhood == NHOOD) && (nstates == S) && (radius == R))
- return;
- }
- else {
- if ((nborhood == NHOOD) && (nstates == S))
- return;
- }
- if (change_params(nborhood, nstates, radius)) {
- clear_msg();
- show_msg("Error in change_params()");
- return 1;
- }
- change_canvas_menus();
- and_states();
- and_color(AMASK);
- and_planemask(AMASK);
- clear_saved_nhood_defaults();
- if (ta) free(ta);
- if (function)
- ta = NULL;
- else
- if ((ta = (State *)malloc(TSIZE)) == NULL) {
- clear_msg();
- show_msg("Couldn't allocate memory for lookup-table");
- return 1;
- }
- tclear();
- free(statecount);
- statecount = (int *) malloc(S * sizeof(int));
- display_image();
- clear_msg();
- switch (nborhood) {
- case NH_MOORE:
- sprintf(tmp_str,"moore ");
- break;
- case NH_MARG:
- sprintf(tmp_str,"marg ");
- break;
- case NH_LIN:
- sprintf(tmp_str,"lin ");
- break;
- case NH_VONN:
- sprintf(tmp_str,"vonn ");
- break;
- }
- sprintf(tmp2_str,"%d", nstates);
- strcat(tmp_str, tmp2_str);
- if (nborhood == NH_LIN) {
- sprintf(tmp2_str," r %d",radius);
- strcat(tmp_str, tmp2_str);
- }
- show_msg(tmp_str);
- if (use_CM)
- CM_change_stuff(save_str);
- }
-
-
- /* This is a routine to change the image-size which is callable
- * from the "image" menu.
- */
- change_image_size_proc()
- {
- int newsize;
-
- clear_msg();
- if (invalid_set_pressed())
- return;
- if (setting_sequence)
- add_sequence(change_image_size_proc);
- get_msg("New size:", buf1, BUFLEN, "");
- if (buf1[0] != '\0') {
- sscanf(buf1,"%d",&newsize);
- change_image_size(newsize);
- }
- }
-
-
- /* This routine is called by the image-load routines, to change
- * the image-size if that is necessary to accomodate the new image,
- * based on the filename.
- */
- change_image_size_file(fname)
- char *fname;
- {
- char tmp_str[80], *ptr, *ptr2;
- int i, newsize;
-
- if (!strcmp(&fname[strlen(fname)-2], ".Z"))
- ptr = &fname[strlen(fname)-3];
- else ptr = &fname[strlen(fname)-1];
- ptr2 = ptr;
- while ((*ptr != '.') && (ptr != fname))
- ptr--;
- if (ptr == fname) return;
- ptr++;
- i = 0;
- while (ptr != ptr2)
- tmp_str[i++] = *ptr++;
- tmp_str[i++] = *ptr++;
- tmp_str[i] = '\0';
- if (tmp_str[i-1] == 'x')
- tmp_str[i-1] = '\0';
- sscanf(tmp_str,"%d",&newsize);
- change_image_size(newsize);
- }
-
-
- /*
- * This one does the actual work of changing the image size.
- */
- change_image_size(newsize)
- int newsize;
- {
- if (newsize == B)
- return;
- /* if ((newsize != 64) && (newsize != 128) && (newsize != 256) &&
- (newsize != 512)) {
- clear_msg();
- show_msg("Invalid image size");
- return;
- }
- */
- if (newsize < 4) {
- clear_msg();
- show_msg("Image size must be at least 4");
- return;
- }
- if (newsize > 512) {
- clear_msg();
- show_msg("Image size must be no greater");
- show_msg("than 512");
- return;
- }
- if (newsize%4) {
- clear_msg();
- show_msg("Image size must be multiple of 4");
- return;
- }
- if (use_CM) {
- if (!valid_CM_image(newsize)) {
- clear_msg();
- show_msg("Invalid size for CM.");
- show_msg("Must be 128, 256, or 512.");
- return;
- }
- }
- if (closeup)
- closeup_proc();
- B = newsize;
- BM1 = B - 1;
- BPL1 = B + 1;
- TBM1 = 2 * B - 1;
- BSQR = B * B;
- BBUF = BSQR + B;
- ASIZE = BBUF + B;
- ABASE = B;
- RCOUNT = B;
- if (NHOOD == NH_LIN) {
- ICBASE = BSQR;
- ICSIZE = B;
- change_image_size_l(); /* linear neighborhood uses its own private
- * array for some updates, so we have to tell
- * that array to change */
- }
- else {
- ICBASE = B;
- ICSIZE = BSQR;
- }
- if (use_CM)
- CM_change_image_size();
- change_scr();
- change_data();
- clear_saved_image_defaults();
- clear_data();
- display_image();
- sprintf(buf1,"Size is now %d",B);
- show_msg(buf1);
- }
-
-
- /*
- * This is almost the same as set_params; there a few differences, since
- * this one gets called only to switch neighborhood, where set_params
- * gets called to initialize things when cellsim is first started up.
- */
- change_params(nhood, nstates, radius) /* change the nborhood or # of states */
- int nhood, nstates;
- {
- /* if (SOCKET_INUSE) {
- clear_msg();
- show_msg("Can't change nhood using sockets");
- return 1;
- } */
- NHOOD = nhood;
- if (nstates == 256)
- function = 1;
- else
- function = 0;
- switch (nhood) {
- case NH_MOORE:
- change_states(nstates, 0);
- break;
- case NH_MARG:
- change_states(nstates, 0);
- break;
- case NH_VONN:
- change_states(nstates, 0);
- break;
- case NH_LIN:
- change_states(nstates, radius);
- break;
- default:
- clear_msg();
- show_msg("Illegal neighborhood");
- return 1;
- break;
- }
- if (NHOOD == NH_LIN) {
- ICBASE = BSQR;
- ICSIZE = B;
- DIM = 1;
- }
- else {
- ICBASE = B;
- ICSIZE = BSQR;
- DIM = 2;
- }
-
- L = (short) (log((double) S) / log((double) 2.0));
- AMASK = S-1;
- switch (NHOOD) {
- case NH_VONN:
- set_params_v();
- break;
- case NH_MOORE:
- set_params_m();
- break;
- case NH_LIN:
- set_params_l();
- break;
- case NH_MARG:
- set_params_marg();
- break;
- }
-
- if (!function)
- TSIZE = 1 << (L * N);
- else
- TSIZE = 0;
- return 0;
- }
-
-
- /*
- * Similar to set_states
- */
- change_states(nstates, radius)
- int nstates, radius;
- {
- S = nstates;
- R = radius;
- }
-
-
- /*
- * Unset any saved defaults which are no longer valid as a result of
- * the neighborhood being changed
- */
- clear_saved_nhood_defaults()
- {
- saved_max_val = INTUNDEF; /* for general random proc */
- saved_rho_percent[0] = INTUNDEF; /* rho array */
- }
-
-
- /*
- * Unset any saved defaults which are no longer valid as a result of
- * the image-size being changed
- */
- clear_saved_image_defaults()
- {
- saved_ox = INTUNDEF; /* size for general random proc */
- }
-
-
- /***************** Connection Machine (CM) Routines *****************/
- void
- CM_change_host()
- {
- clear_msg();
- if (invalid_set_pressed())
- return;
- if (setting_sequence)
- add_sequence(CM_change_host);
- get_msg("Hostname:", buf1, BUFLEN, CM_hostname);
- if (buf1[0] == NULL)
- return;
- strcpy(CM_hostname, buf1);
- }
-
-
- void
- CM_change_port()
- {
- int num;
-
- clear_msg();
- if (invalid_set_pressed())
- return;
- if (setting_sequence)
- add_sequence(CM_change_port);
- if (get_num("Port:", &num, 0, 50000, CM_port))
- return;
- CM_port = num;
- }
-
-
-
- int
- valid_CM_state(nborhood, nstates, radius)
- int nborhood, nstates, radius;
- {
- /* if (nborhood == NH_LIN)
- return 0; */
- if (nstates == 256)
- return 1;
- if ((nborhood == NH_MOORE) && (nstates > 2))
- return 0;
- if (((nborhood == NH_VONN) || (nborhood == NH_MARG) ||
- (nborhood == NH_LIN)) && (nstates > 8))
- return 0;
- return 1;
- }
-
-
- int
- valid_CM_image(size)
- int size;
- {
- if ((size==128) || (size==256) || (size==512))
- return 1;
- else
- return 0;
- }
-
-
-
- CM_run_forever_proc()
- {
- int go=TRUE;
-
- set_run_mode();
- if (use_CM && (!local_run) && (!SOCKET_INUSE)) {
- CM_auto_run();
- while (go) {
- go = !check_button();
- usleep(100000);
- }
- CM_stop_run();
- unset_run_mode();
- show_time(stime);
- }
- else {
- clear_msg();
- if (use_Sun_disp) {
- show_msg("You must disable local display to");
- show_msg("use 'run' on CM");
- }
- if (SOCKET_INUSE) {
- show_msg("Can't yet use 'run' on CM");
- show_msg("when using sockets");
- }
- unset_run_mode();
- return;
- }
- if (use_Sun_disp)
- CM_display_image();
- }
-
-
-
- /************************************* EOF **********************************/
-