/*
 Copyright (C) Andrew Wuensche
 
 This file is part of DDLab (Discrete Dynamics Lab) <www.ddlab.org>

 DDLab is free software: you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
 the Free Software Foundation, either version 3 of the License, or
 (at your option) any later version.
 
 This program is distributed in the hope that it will be useful,
 but WITHOUT ANY WARRANTY; without even the implied warranty of
 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 GNU General Public License for more details.
 
 You should have received a copy of the GNU General Public License
 along with DDLab.  If not, see <http://www.gnu.org/licenses/>.
 */

/***************** run forwards ***********************/
#include "edecfunc.h"
#include <fcntl.h>

#if __WATCOM__
#   include <io.h>
#   include <sys\stat.h>
#elif __UNIX__
#   include <sys/types.h>
#   include <sys/uio.h>
#endif

/*void reallocate_pixmap(int left, int top,
  int width, int height,Pixmap *the_pixmap)*/
/*void set_2d_3d_coords(int_stp *it)*/
/*unsigned int next_time_step(
                    char **thisrule,
                    char *state1a,
                    char *state2a,      
                    char this_partial_order,
                    char forwards_only,
                    unsigned int *pnhood, 
                    unsigned int n,
                    char this_rule_unmixed)*/
/*void forward_onthefly_bottom_prompts(void);*/
/*void run_forward(char **thisrule)*/

/****for Unix, allocate the offscreen pixmap referred to by pointer****/
#if __UNIX__
void reallocate_pixmap(int left, int top,
		int width, int height,Pixmap *the_pixmap){
	/*If the pixmap already exists, free it first*/
	if (*the_pixmap != 0) freeimage(the_pixmap);
	/*Now create one with the new size*/
	getimage(left, top, width, height, the_pixmap);
}
#endif

/*********** To represent 1d and 3d networks in 2d *****************/
void set_2d_3d_coords(int_stp *it){
 
   if (twod==0){
      if (oned){
	 /*if (i2d==0) set_i2dxj2d();*/
         set_i2dxj2d();
      }
      else if (threed){
	 i2d=i3d;
	 j2d=j3d*h3d;
      }
   }
   /*To represent 1d and 2d networks in 3d*/
   if (threed==0){
      unsigned int temp_3d;
      signed int z;

      for (z=(signed int)ceil(pow((double)lineL,1.0/3));z>=1;z--){
	    if (lineL%z==0) break;
      }
      i3d=z;
      temp_3d=lineL/i3d;
      for (z=(signed int)ceil(pow((double)temp_3d,.5));z>=1;z--){
	 if (temp_3d%z==0) break;
      }
      j3d=z;
      h3d=temp_3d/j3d;
      /*make  i>j>h*/
      while (i3d<j3d || j3d<h3d){
         if (j3d<h3d){
            temp_3d=h3d;
            h3d=j3d;
            j3d=temp_3d;
         }
         if (i3d<j3d){
            temp_3d=j3d;
            j3d=i3d;
            i3d=temp_3d;
         }
      }   
   }
   it->i2d_b=i2d;
   it->j2d_b=j2d;
   it->i3d_b=i3d;
   it->j3d_b=j3d;
   it->h3d_b=h3d;
}

/************** compute the next time-step, separated function May07 *********/
unsigned int next_time_step(
                    char **thisrule,
                    char *state1a,
                    char *state2a,                    
                    char this_partial_order,
                    char  *net_subset,
                    char forwards_only,
                    unsigned int *pnhood, 
                    unsigned int n,
                    char this_rule_unmixed){

  char inp[8],*temp_pn;
  unsigned int u;
  signed int  i,ii,jj,hh;
  char exLeftMax,exRightMax,ex2d3d; 
  
     u=0; /*find dec value of actual or pseudo-nhood*/             
             
     if ((temp_pn=(char*)calloc(nhoodm[n],sizeof(char)))
	                ==NULL) outof_memory("temp_pn");

     if (NULLboundaries==1){	      

	if (oned && nhoodm[n]>1){
               char countl=0, countr=0;

                /* left end
                   1   3    5      7
                   |  \|/ \\|// \\\|/// .... odd nhoods
                   0  1    2      3                   */
                if (nhoodm[n]%2==1) exLeftMax=nhoodm[n]/2;
 
                /* 2    4     6       8
                   |/  \|// \\|/// \\\|//// .... even nhoods
                  0    1     2       3        extra on right */
                else exLeftMax=nhoodm[n]/2 - 1;

                /*right end
                      3    5      7
                     \|/ \\|// \\\|/// .... odd nhoods
                       1    2      3                   */
                               
                /* 2    4     6       8
                   |/  \|// \\|/// \\\|//// .... even nhoods
                    1    2     3       4        extra on right */
                exRightMax=nhoodm[n]/2;

             /*will cope with k bigger that netsize*/
	     if (1){ //lineL<nhoodm[n]){
	       signed int  exL,exR,thisn;

	           thisn=(signed int)n;	
                   exL=exLeftMax-(L-thisn);//check if i is outside left edge
                   for (i=nhoodm[thisn]-1;i>=0;i--){
                       countl+=1;
                       if (countl <= exL) temp_pn[i]=1;
                       else break;                                              
		   }
                   if (diff_plot && thisn<=L/2){
		      countl=0; //check if i is outside centre left edge
                      exL=exLeftMax-(L/2-thisn);
                      for (i=nhoodm[thisn]-1;i>=0;i--){
                         countl+=1;
                         if (countl <= exL) temp_pn[i]=1;
                         else break;                                              
		      }
                   }
                   exR=exRightMax-thisn; //check if i is outside right edge
                   for (i=0;i<=nhoodm[thisn]-1;i++){
                       countr+=1;
                       if (countr <= exR) temp_pn[i]=1;
                       else break;
		   }
                   if (diff_plot && thisn>=lineL/2){
		      countr=0; //check if i is outside centre right edge
                      exR=exRightMax-(thisn-lineL/2); 
                      for (i=0;i<=nhoodm[thisn]-1;i++){
                         countr+=1;
                         if (countr <= exR) temp_pn[i]=1;
                         else break;
		      }
		   }
                   
                   /*fprintf(stderr,"\n n=%d:******************************",thisn);
                   for (i=nhoodm[n]-1;i>=0;i--){
                      fprintf(stderr,"%d",temp_pn[i]); 
		    }*/
                   //input_string(1,0);
             }
   
	     else{ //alternative methods superseded
                if (n > L-exLeftMax){ //left boundary                                      
                   for (i=nhoodm[n]-1;i>=1;i--){ //left <- right                        
		        //if (pnhood[i]<pnhood[0]) temp_pn[i]=1; //this also works
                        if (wiring[n][i] < exLeftMax) temp_pn[i]=1;
                   } 
                   /*for (ii=exLeftMax-1;ii>=0;ii--){ //this also works
                      if (n == L-ii){                  		                             
			 for (i=nhoodm[n]-1;i>=nhoodm[n]-1-(exLeftMax-1-ii); i--){
                            temp_pn[i]=1;
		         }
                      }
		   }*/
                }
                if (n < exRightMax){ //right boundary
                   for (i=nhoodm[n]-2;i>=0;i--){ //right -> left
		        //if (pnhood[i]>nhoodm[n]-1) temp_pn[i]=1; //this also works
                        if (wiring[n][i] > L-exRightMax) temp_pn[i]=1;
                   }                    
                   /*for (ii=exRightMax-1;ii>=0;ii--){ //this also works
                      if (n == ii){                         
		         for (i=exRightMax-1-ii;i>=0;i--){
			    temp_pn[i]=1;
                         }
		      }
		   }*/
                }
             }
        }
	else if (twod){ /*for 2d/3d basins/subtrees don't work for NUL boundary conditions*/
	       if (nhoodm[n]<=9){
		 ex2d3d=1;
		 if (hex2d==1 && nhoodm[n]==9) ex2d3d=2;
	       }
	       else if (nhoodm[n]<=13) ex2d3d=2;
               else ex2d3d=3;
               ii=n%i2d;
	       jj=n/i2d;


	       if (diff_plot){
                  if (ii >= i2d-1-ex2d3d){ //left boundary
                     for (i=nhoodm[n]-1;i>=1;i--){ //left <- right
                        if (wiring[n][i]%i2d < i2d/2+ex2d3d
                              && wiring[n][i]%i2d >= i2d/2) temp_pn[i]=1;
                     }
                  }
		  if (ii<=i2d/2-1 && ii >= i2d/2-1-ex2d3d){ //left boundary centre){
                     for (i=nhoodm[n]-1;i>=1;i--){ //left <- right
		        if (wiring[n][i]%i2d < ex2d3d) temp_pn[i]=1;
                     }
                  }
                  if (ii <= ex2d3d){ //right boundary
                     for (i=nhoodm[n]-1;i>=0;i--){ //left -> right
                        if (wiring[n][i]%i2d > i2d/2-1-ex2d3d
			  &&  wiring[n][i]%i2d <=i2d/2-1) temp_pn[i]=1;
                     } 
                  }
                  if (ii>=i2d/2 && ii<=i2d/2-1 + ex2d3d){ 
                     for (i=nhoodm[n]-1;i>=0;i--){ //left -> right
                        if (wiring[n][i]%i2d > i2d-1-ex2d3d) temp_pn[i]=1;
                     } 
                  }
	       }

               else{
                  if (ii >= i2d-1-ex2d3d){ //left boundary
                     for (i=nhoodm[n]-1;i>=1;i--){ //left <- right
                        if (wiring[n][i]%i2d < ex2d3d) temp_pn[i]=1;
                     }
                  }
	        
	          if (ii <= ex2d3d){ //right boundary
                     for (i=nhoodm[n]-1;i>=0;i--){ //left -> right
                        if (wiring[n][i]%i2d > i2d-1-ex2d3d) temp_pn[i]=1;
                     } 
                  }
               } 
               
               if (jj >= j2d-1-ex2d3d){ //top boundary
                   for (i=nhoodm[n]-1;i>=1;i--){ //bottom ^ top
		      if (wiring[n][i]/i2d < ex2d3d) temp_pn[i]=1; 
                   }
               }   
	       if (jj <= ex2d3d){ //bottom boundary
                   for (i=nhoodm[n]-1;i>=0;i--){ //top v bottom
                      if (wiring[n][i]/i2d > j2d-1-ex2d3d) temp_pn[i]=1; 
                   }
               }
          }
          else if (threed){
	       if (nhoodm[n]<=7) ex2d3d=2;
	       else ex2d3d=3;

               ii=n%i3d;
	       jj=n%(i3d*j3d)/i3d;
               hh=n/(i3d*j3d);
               //n=(i3d*j3d*hh) + (i3d*jj) + ii;

               if (ii >= i3d-1-ex2d3d){ //left boundary
                   for (i=nhoodm[n]-1;i>=0;i--){ //left <- right
                      if (wiring[n][i]%i3d < ex2d3d) temp_pn[i]=1;
                   }
                }
	        if (ii <= ex2d3d){ //right boundary
                   for (i=nhoodm[n]-1;i>=0;i--){ //left -> right
                       if (wiring[n][i]%i3d > i3d-1-ex2d3d) temp_pn[i]=1;
                   } 
                }
                
                if (jj >= j3d-1-ex2d3d){ //top boundary, highest jj
                   for (i=nhoodm[n]-1;i>=0;i--){
		      if (wiring[n][i]%(i3d*j3d)/i3d < ex2d3d) temp_pn[i]=1; 
                   }
                }   
	        if (jj <= ex2d3d){ //bottom boundary
                   for (i=nhoodm[n]-1;i>=0;i--){
                      if (wiring[n][i]%(i3d*j3d)/i3d > j3d-1-ex2d3d) temp_pn[i]=1; 
                   }
                }

                if (hh >= h3d-1-ex2d3d){ //front boundary, highest hh
                   for (i=nhoodm[n]-1;i>=0;i--){
		      if (wiring[n][i]/(i3d*j3d) < ex2d3d) temp_pn[i]=1; 
                   }
                }   
	        if (hh <= ex2d3d){ //back boundary
                   for (i=nhoodm[n]-1;i>=0;i--){ //bottom
                      if (wiring[n][i]/(i3d*j3d) > h3d-1-ex2d3d) temp_pn[i]=1; 
                   }
                }
	     }

             /*if (n > L-exLeftMax || n < exRightMax){
		  fprintf(stderr,"\nexL=%d exR=%d nhoodm[%d]=%d n=%d: ",
			  exLeftMax,exRightMax,n,nhoodm[n],n);
                   for (i=nhoodm[n]-1;i>=0;i--){
                      fprintf(stderr,"%d",temp_pn[i]); 
                   }
	      }*/                       
       }

       if (tot_only==0){
	      for (i=nhoodm[n]-1;i>=0;i--){
		 if (NULLboundaries==1 && temp_pn[i]==1) continue;
	         if (value_range==2) u+=get_bit(state1a,pnhood[i])*
                            (signed int)pow(2,(double)i);
                 else u+=get_value(state1a,pnhood[i])*
                            (signed int)pow(value_range,(double)i);
	      }

              /*if (n > L-exLeftMax || n < exRightMax){
		signed int temp_u;
		fprintf(stderr,"\nn=%d: ",n);
		 temp_u=u;
                 for (i=nhoodm[n]-1;i>=0;i--){
		   if (temp_u >= (signed int)pow(2,(double)i)){
                       fprintf(stderr,"1");
                       temp_u-=(signed int)pow(2,(double)i);                       
		    }
                    else fprintf(stderr,"0");
		 }
	       }*/
        }
        else if (totalistic==1){
	      for (i=nhoodm[n]-1;i>=0;i--){ 
		 if (NULLboundaries==1 && temp_pn[i]==1) continue;
                 u+=get_value(state1a,pnhood[i]);
              }
        }
        else if (totalistic==2){
              /*tree method*/
              for (ii=0;ii<=value_range-1;ii++) inp[ii]=0;
              /*printf("\n");*/
              for (i=nhoodm[n]-1;i>=0;i--){
		 if (NULLboundaries==1 && temp_pn[i]==1) continue;
		 if (reverse_value_order==0)
                      inp[(value_range-1)-get_value(state1a,pnhood[i])]+=1;
	      /*for Antonio's order*/
		 else inp[get_value(state1a,pnhood[i])]+=1;
              }
	      /*for (ii=0;ii<=value_range-1;ii++) printf("%d ",inp[ii]);*/
              u=(unsigned int)search_tree(inp,value_range,
                                            v_tree[nhoodm[n]],0); 
              /*printf("u=%d",u);*/
        }
	/*set cell next line according to random map*/
        if (exhaustive_testing!=2){ /*set later*/ 
	  /*if (exhaustive_testing==0){*/  /*exhaustive_testing==2 set in for*.c*/
	      /*set cell next line according to rule look-up table*/
	      if (outer_tot==0 && (rulemix==0 || this_rule_unmixed )){
                    /*wildcards in beehive rule*/
		    /*if (u==3 || u==4 || u==5 || u==6 ||
                        u==10 || u==11 || u==12 ||
                        u==16 || u==17 || u==21){
                        set_value(state2a,n,myrand()%value_range);
			fprintf(stderr,"%d ",u);
		    }*/
                    /*wildcards in spiral1 rule*/
		    /*if (u==3 || u==4 || u==5 || u==6 ||
                        u==10 || u==11 || u==12){
                        set_value(state2a,n,myrand()%value_range);
			fprintf(stderr,"%d ",u);
		    }*/
                    /*strong wildcards in spiral2 rule*/
		    /*if (u==3 || u==6 || u==7 || u==11 ||
                        u==12 || u==13 || u==14 || u==19 || u==20){
                        set_value(state2a,n,myrand()%value_range);
			//fprintf(stderr,"%d ",u);
		    }*/
                    /*weak+strong wildcards in spiral2 rule*/
		    /*if (u==3 || u==4 || u==5 || u==6 || u==7 || u==11 ||
                        u==12 || u==13 || u==14 || u==18 || u==19 || u==20 || 
                        u==25 || u==35){
                        set_value(state2a,n,myrand()%value_range);
			//fprintf(stderr,"%d ",u);
		    }
                    
                    else*/
		       if (value_range==2){ 
                          set_bit(state2a,n,get_bit(thisrule[0],u));
                       }
                    else set_value(state2a,n,get_value(thisrule[0],u));
	      }
              else if (outer_tot==1) /*outer totalistic*/
                 set_value(state2a,n,get_value(thisrule[get_value(state1a,n)],u));
	      else{ /*mixed rules*/
		    if (value_range==2){
                      set_bit(state2a,n,get_bit(thisrule[n],u));
                    }
                    else set_value(state2a,n,get_value(thisrule[n],u));
	      }
	      /* try to absorb gilders at border of 1d, 2d */
              if (forwards_only==1 && border>=1){
		 if (border<=0) border=1;
                 if (b_value<0 || b_value>value_range-1) b_value=0; 
                 if (oned){
                    if (lineL-n<=border || n+1<=border) 
                                             set_value(state2a,n,b_value);
                 }
                 else if (twod){               
                    if (n<i2d*border || n>lineL-i2d*border
		        || n%i2d >=i2d-border || (n+1)%i2d <= border)
                           set_value(state2a,n,b_value);
                 }
                 else if (threed){
		   if (n<i3d*j3d*border || n>=i3d*j3d*(h3d-border)
                        || n%i3d >=i3d-border || (n+1)%i3d <= border
		        || (n+1)%(i3d*j3d) <= i3d*border
                        || (n+1)%(i3d*j3d) >= (i3d*j3d)-i3d*border )
                                      set_value(state2a,n,b_value);
                 }
	      }  

              /*probabilistic networks, not for attractor basins*/
              if (forwards_only==1){		
		 /*just out_prob: obey the rule with "temp_out_prob" probability
                                  otherwise set at random*/
                 if (temp_out_prob<1.0 && temp_update_prob==1.0){
		    /*with prob=1-out_prob, set cell at random*/
		    if ( ((float)(myrand() % 10001))/10000>temp_out_prob){
		       if (value_range==2){
                           set_bit(state2a,n,(myrand()%100)/50);
                       }
                       else set_value(state2a,n,myrand()%value_range);
		    }
	         }
                 /*update_prob + out_prob if set*/
                 /*obey the rule with "temp_update_prob" probability
		                                otherwise leave as is*/ 
                 else if (temp_update_prob<1.0){
		    /*with prob=1-update_prob, set cell at random - as above*/
		    if ( ((float)(myrand() % 10001))/10000>temp_update_prob){

		       if (value_range==2){ 
                          set_bit(state2a,n,get_bit(state1a,n));
		       }
                       else set_value(state2a,n,get_value(state1a,n));

		       /*if cell WAS updated, apply noise with out_prob)*/
                       if (temp_out_prob<1.0){		          
		          if ( ((float)(myrand() % 100001))/100000>out_prob){
		              if (value_range==2){
                                  set_bit(state2a,n,(myrand()%100)/50);
                              }
                              else set_value(state2a,n,myrand()%value_range);
		          }
		       }
                    }
	         }
                 else if (this_partial_order==1){
		     if (get_bit(net_subset,n)==0){
                           set_value(state2a,n,get_value(state1a,n));
                     }
                 }
	      }             
	}

	
	/*exhaustive_testing==1 is for exhaustive and sequential
                            ==2 is for random map*/
	/*this screws up sequential updating and semms unnecessary, Dec2021*/   
	/*if (exhaustive_testing==1)
	    memmove(state2,exh_pairs+dec_equiv(state1,L)*bytesL,bytesL);*/
 
        free(temp_pn);
        return(u);
}

/*****show various onthefly prompts in the bottom title, June07*******/
void forward_onthefly_bottom_prompts(void){
       float temp_CWidth,temp_CHeight,tempchar;
           tempchar=is[0];
           temp_CWidth=CWidth;
           temp_CHeight=CHeight;
           set_medium_font();

           sprintf(textb[0],
		   "STP:tog/exp/contr-S/e/c, tog index-X, slower/max speed:</>");
           tempchar=is[0];
           draw_hint_box(0,0,textb[0],bottom_title_middx);
           is[0]=tempchar;

           restore_def_font();
           CWidth=temp_CWidth;
           CHeight=temp_CHeight;
}

/******* run CA forward, find attractor cycle, 13 May 93 **********/
void run_forward(char **thisrule){

# if __WATCOM__ /*not xwindows*/
     unsigned long imsize; /*for  block plot in stat graph*/
# endif
    
 /*declaring structure*/
 diff_var dp; /*for diff plot*/
 auto_ent ae; /*for auto -entropy*/
 ent_eeg  eg; /*entropy-dencity*/
 int_stp  it; /*extra variables to interrupt stp etc*/
 sk_att   sk; /* for sketeton and attractor hististograms*/

 // float **den_state; /*show density...x=t, y=t-1 is now in struct int_stp*/
 char  *net_subset, /*for partial order*/
       *temppoint,even_row=0; /*for hex layout with balls*/
 unsigned int n,poss,          
	  *pnhood, /*memory for pseudo-nhood*/
	  notocheck=0,
	  zu,zu1,u; 
 unsigned long zul;
 signed int  i,z,zz,xbox,tempx,tempy,step,
         X1,Y1,X2,Y2, /*for graph layout*/
         scroll_x,scroll_y;
 unsigned char
        /**stp_cell_color,*/ /*for graph layout*/
	nhdcolor, /*cell color according to n'hood*/        
	thiscolor,tempcolor,tempcolor1;
 char
   tempstp,
     tempchar,
     oldnhood, /*in case rule with diff nhood is loaded*/
     **rcheck,
     resetscreen=0,
     repeatfound=0,
     flipmem=0,
     forwards_only=0; /*=0 for attractors/subtrees, =1 for space-time patterns only*/

#   if __WATCOM__  /*for sound effects*/
	makesound=0;
#   endif
   
   iso_prototype_count=0;/*for 3x3 prototype blocks set wit "/" forward-slash, July2021*/
   /*to monitor pulsing in terminal*/
   it.etempent=it.old_etempent=0;
   it.emax_ent=.01;
   it.emin_ent=.99;
   it.e_up=it.e_down=0;
   
   for (z=0;z<=8;z++) it.req_iso_ptrns[z]=0;/*define nd show range of 3x3 iso-rule seeds,Sept2021*/ 
   it.req_iso_ptrns[4]=4; //default 4/9
   
   postScript_graph_state=0; /*during stp -- to save graph state to postScript*/
   
   index_of_flip=-1; /*to select a flip index*/
   it.a_sample_ht=150; /*for showing blocks of stp*/
   it.draw_3d_grid=1;  /*to toggle 3d grid in STP draw_axon_plane*/ 
                       /*also variable draw_3d_grid miscx.c and wiringx.c ??*/
   it.seedORblock=0, /*if set in stat_rule(.. ,
              when scanning  rule samples in time-step blocks
              and on-the-fly '4', 'v','5','6', Oct 2014*/
   
   it.partial_order= /*to update subsets of the network*/
   it.rect_h= /*height of hex rectangle*/
   it.keep_index= /*dont increase index, just change seed*/  
   it.time_step_density_plot= /*show density...x=t, y=t-1*/
   it.slice_3d=    /*to show 3d network in slices*/
        /*or, show 2d+time/scrolling  with balls instead of parallelograms*/
   it.invisible=   /*suppess 2d diagonal scrolling stp, to show graph only*/
   it.skip_timesteps=
   it.a_index_sample= /*for the automatic rule sample*/
   it.Hamming_plot=
   it.screenend=
   it.itt_step=
   it.frozen_islands=
   it.rule_unmixed=     /*to toggle mixed-single rule/s*/
   it.slant_even_k=
   it.mincount= /*April 2018*/
   it.maxcount= /*for amplitude/frquency of pulsing*/
   it.filter_toggle= /*in spite of filtering, to toggle filtering in on/off with '-', June2020*/
   ae.show_edata=
   eg.showlookupfreq=
   eg.lookup_entropy=
   it.cell_not_changed=
   eg.showeeg=
   eg.new_hist=
   eg.showlookupfuz=
   eg.barsep=
   sk.att_sample_no=
   sk.this_trans_length=0;

   eg.ent_den_plot_before[0]=0; /*to draw lines instead of just dots in  entropy-density plot*/
   eg.ent_den_plot_before[1]=0;
   eg.history_lines_in_plots=0; /*to toggle the lines, initially off*/
   

   it.pi_outline=1; /*for stp in 3d outline of balls, also 2 types of 2d scrolling added*/
   it.node_outline=1; /*for graph layout only */
   eg.hist_bar_factor=1; /*to amplify the bars: intut-entropy histogram*/
   if (direction=='f' && iso_tablemax==101 && twod && value_range==2)
                      eg.hist_bar_factor=0;//in this case start with log2 histogram

   it.stp_speed=0;      /*to slow down space-time patterns*/
   if (pre_speed>0) it.stp_speed=pre_speed; /*can be set finish_options(char alloptions)*/

   if (value_range==2) color_v[1]=white;/*default 1 (foreground) color
                       white (on black) can be toggled yellow
		       black (on white) - can be blue*/       
   color_v[0]=black; /*default zero (background) color is black (on black)
		       white (on white) - can be toggled shades of green*/
   if (p_order==1) it.partial_order=1;
   time_skip=1;
   if (stppause==-1){
      it.itt_step=1;
      stppause=0;
   }

   if (direction=='f' && limitcheck==0){
       forwards_only=1; /*space-time patterns only, NOT attractors/subtrees);*/
       forward_onthefly_bottom_prompts();
       /*for partial order updating*/
       if ((net_subset=(char *)calloc(bytesL,sizeof(char)))
				     ==NULL) outof_memory("net_subset");
       /*to show stp according to the graph layout and node size*/
       if ((stp_graph_layout=(signed int**)calloc(lineL+1,
             sizeof(signed int*)))==NULL) outof_memory("stp_graph_layout");
       for (zu=0;zu<=lineL;zu++){
          if ((stp_graph_layout[zu]=
                  (signed int *)calloc(2,sizeof(signed int)))
			      ==NULL) outof_memory("stp_graph_layout[]");
       }
       if ((stp_graph_node_size=(float *)calloc(lineL+1,sizeof(float)))
                               ==NULL) outof_memory("stp_graph_node_size");
       if ((stp_cell_color=
                   (unsigned char *)calloc(lineL,sizeof(unsigned char)))
			      ==NULL) outof_memory("stp_cell_color");
       /*graph layout box*/
        X1=vgax(140);
        X2=Maxx-vgax(5);
        Y1=CHeight*5; 
        Y2=vgay(430);       
   } 

   /*clear and restart backwards stp for each basin*/
   if (forwards_only==0 && stp){ 
      setviewport(0, 0, (lineL+1)*scale, Maxy, 1);
      clearviewport();
      setviewport(0, 0, Maxx, Maxy, 1);
      moveto(0,0);
   }


   if (d_mode==0){
      if (oned==1 || forwards_only==0) d_mode=1; /*avoid 2d/3d stp for basins*/
      else if (twod==2) d_mode=2;
      else if (twod==3) d_mode=3;
      else if (threed) d_mode=4;
   }
   
   if (forwards_only==1 && (twod==0 || threed==0)) 
                                  set_2d_3d_coords(&it);
   /*seq or rand updating*/
   it.temp_seq_update=seq_update;   

   if (forwards_only==0) diff_plot=0;

   /*set up diff statistical sample  */

   if (att_hist==2){
    startskel:
      sk.skel_val=1;
      setcolor(white);
      xbox=draw_prompt_box(3);
      outtext("frozen skeletons: 0s-0 1s-def both-b:");
      input_string(1,0);
      if (is[0]=='q') return;
      if (is[0]=='0') sk.skel_val=0;
      else if (is[0]=='b') sk.skel_val=2;

      moveto(xbox,gety+CHeight);
      /*no of steps that a gene must stay the same to be considered frozen*/
      sprintf(textb[0],
	 "no of steps frozen: gene (def %d):",frozen_gens);
      outtext(textb[0]);
      input_string(4,0);
      if (is[0]=='q') goto startskel;
      else if (is[0]!=13 && atoi(is)>0) frozen_gens=atoi(is);
      /*no of steps that the a frozen gene
	     must stay the same (within sk.percent_frozen_diff %)
	       to be considered a frozen pattern - i.e. a skeleton*/
      outtext(" skeleton (def 20):");
      input_string(4,0);
      if (is[0]=='q') goto startskel;
      if (is[0]!=13 && atoi(is)>0) dp.same_limit =atoi(is);
      else dp.same_limit =20;
      /*no of steps that the pattern of frozen genes
	     must stay the same to be considered frozen - i.e. a skeleton*/
      sk.percent_frozen_diff=100;
      moveto(xbox,gety+CHeight);
      outtext("% frozen (def-100):");
      input_string(10,0);
      if (is[0]=='q') goto startskel;
      if (is[0]!=13 && atof(is)>0 && atof(is)<100)
		       sk.percent_frozen_diff =atof(is);

      sk.percent_match=100;
      /* how close % a new frozen pattern needs to be to one of the
	 established skeleton types to be considered as that type,
	   otherwise it is made a new type*/
      outtext(" % same type (def-100):");
      input_string(10,0);
      if (is[0]=='q') goto startskel;
      if (is[0]!=13 && atof(is)>0 && atof(is)<100)
		       sk.percent_match =atof(is);
      erase_prompt_box(3);
      moveto(trboxw,Maxy/7);
      
      if (sk.skel_val==0) sprintf(textb[0],"%s","0s only");
      else if (sk.skel_val==1) sprintf(textb[0],"%s","1s only");
      else if (sk.skel_val==2) sprintf(textb[0],"%s","0s or 1s");
      outtext(textb[0]);
      sprintf(dp.textbuf," (%s) g/s/sp/tp %d %d %.1f %.1f",
	      textb[0],frozen_gens,dp.same_limit,
	       sk.percent_frozen_diff,sk.percent_match);
      /*re-set random seed -- in case seed was zero*/ 
      /*it.color1=random_seed(it.color1,100,0); has fixed density*/
      for (zu1=lineL-1;zu1!=Maxu;zu1--){ /*unbiased*/
         set_bit(state1,zu1,(myrand()%100)/50);
      }
   }

   if (diff_plot==3 || diff_plot==4){ /*3=actual 4=bins*/
      setup_diff_plot(&dp); /*for damage histogram*/
      if (is[0]=='q') return;
   }
   else if (att_hist==1 || att_hist==2){
      dp.att_types=0;
      dp.max_d_hist=10000;
      dp.min_d_hist=20;
      dp.d_histno=50;
      dp.d_bin_type='n';
      dp.pause_dam_hist=0;
      setup_diff_plot(&dp);
   }
   /*do this for "forwards only" and single basins, not for fields
   or subtrees*/
   if (exhaustive_testing==2 && !basinfield && direction=='f'){
     //fprintf(stderr,"ehx=%d",exhaustive_testing);
	is[0]=0;
	prestate_successor_pairs();
	if (is[0]=='q') return;
   }
   /*show index to interrupt keys*/
#  define showkey  interrupt_key_index(&eg,&it);

   tempstp=stp;
   wiring_madelocal=0;
   rnd_rewiring_each_timestep=0;
   it.track_pulsing=0;
   if (scale==0) scale=1;
   it.fscale=scale;

   it.hex_rad=(double)it.fscale * cos(PI/6)*2/3;
   it.show_2d_divs=it.show_dots=0;
   //it.divcolor=black;
   it.divcolor=lightgray; /*default start grid color is lightgray*/
   it.fsep=1;
   if (it.fscale>vgax(5)){ 
      it.fsep=2;
      it.show_2d_divs=1;
   }
   if (gens<1) gens=1;

   /* height of hex 2d rectangle*/
   for (z=1;z<=j2d;z++)
            it.rect_h+=(double)it.fscale * cos(PI/6); 

   /*memory for pseudo-nhood, allow for changing k in transform*/
   if ((pnhood=(unsigned int *)calloc(Maxnhood,sizeof(unsigned int)))
			      ==NULL) outof_memory("pnhood");
   if (forwards_only==0 || att_hist==1){
      if ((rcheck=(char**)calloc(1,sizeof(char*)))
			      ==NULL) outof_memory("rcheck");
      if ((rcheck[0]=(char *)calloc(bytesL,sizeof(char)))
			      ==NULL) outof_memory("rcheck[0]");
      memmove(rcheck[0],state1,bytesL); /*seed input for repeat check*/
      memmove(firstseed,state1,bytesL); /*keep track of seed to check density*/

      if ((att=(char**)calloc(1,sizeof(char*)))
			      ==NULL) outof_memory("att");
      if (att_hist==1){
	 /*array of one att state for each att type*/
	 if ((sk.att_type_state=(char**)calloc(1,sizeof(char*)))
			      ==NULL) outof_memory("sk.att_type_state");
	 if ((sk.att_type_state[0]=(char *)calloc(bytesL,sizeof(char)))
			      ==NULL) outof_memory("sk.att_type_state[0]");
         if (att_trans==1){
            /*array of transient states for current attractor*/
	    if ((sk.trans_states=(char**)calloc(1,sizeof(char*)))		
	         ==NULL) outof_memory("sk.trans_states");
	    if ((sk.trans_states[0]=(char *)calloc(bytesL,sizeof(char)))
	             ==NULL) outof_memory("sk.trans_states[0]");
            if ((sk.att_type_trans_length=(unsigned int*)
                           calloc(1,sizeof(unsigned int)))
			      ==NULL) outof_memory("sk->att_type_trans*");
         }

	 /*array of frequencies of each attractor type*/
	 if ((sk.att_type_no=(unsigned long *)calloc(1,
	     sizeof(unsigned long)))==NULL) outof_memory(" sk.att_type_no");

	 /*array of periods of each attractor type*/
	 if ((sk.att_type_period=
		    (unsigned int *)calloc(1,sizeof(unsigned int)))
			      ==NULL) outof_memory("sk.att_type_period");

         /*array of average transient lengths of each attractor type*/
         if ((sk.att_type_avtrans=
		    (float *)calloc(1,sizeof(float)))
			      ==NULL) outof_memory("sk.att_type_avtrans");
         /*to keep track of density of seed leading to all 0s and all 1s 
           point attractors, to check fittness of the density rule*/
         if (att_seed_dens==1){
            if ((sk.dens_seed=(unsigned int**)calloc(2,
              sizeof(unsigned int*)))==NULL) outof_memory("sk.dens_seed"); 
            for (z=0;z<=1;z++){
               sprintf(textb[0],"sk.dens_seed[%d]",z); 
               if ((sk.dens_seed[z]=(unsigned int*)calloc(3,
                sizeof(unsigned int)))==NULL) outof_memory("(textb[0]");
            }
         }          
      }
   }
   /*for frozen skeleton histogram*/
   if (forwards_only==1 && att_hist==2){

      if ((sk.frozen_buff=(char *)calloc(bytesL,sizeof(char)))
			      ==NULL) outof_memory("sk.frozen_buff");
      if ((sk.ref_buff=(char *)calloc(bytesL,sizeof(char)))
			      ==NULL) outof_memory("sk.ref_buff");

      if ((sk.att_type_state=(char**)calloc(1,sizeof(char*)))
			      ==NULL) outof_memory("sk.att_type_state");
      if ((sk.att_type_state[0]=(char *)calloc(bytesL,sizeof(char)))
			      ==NULL) outof_memory("sk.att_type_state[0]");
      if ((sk.att_type_no=(unsigned long *)calloc(1,sizeof(unsigned long)))
			      ==NULL) outof_memory("sk.att_type_no");
      
      /*array of average transient lengths of each attractor type*/
      if ((sk.att_type_avtrans=
		    (float *)calloc(1,sizeof(float)))
			      ==NULL) outof_memory("sk.att_type_avtrans");
      /*prop frozen 0s and 1s in each skeleton type*/
      /*array of average transient lengths of each attractor type*/
      if ((sk.type_fr0s=
		    (float *)calloc(1,sizeof(float)))
			      ==NULL) outof_memory("sk.type_fr0s");
      if ((sk.type_fr1s=
		    (float *)calloc(1,sizeof(float)))
			      ==NULL) outof_memory("sk.type_fr1s");    
   }


   /*set width if space-time pattern for attractor basins,
     reset for stp only*/
   if (d_mode==1) eg.stpwidth=lineL*it.fscale;
   else if (d_mode==2) eg.stpwidth=i2d*it.fscale;
   else if (d_mode==3) eg.stpwidth=i2d*it.fscale + j2d*it.fscale*sin(PI/4);
   else if (d_mode==4) eg.stpwidth=i3d*it.fscale + j3d*it.fscale*sin(PI/4);

   if (forwards_only==1){ /*forwards only*/
     float freq_step;

      /*memory for entropy data*/
      eg.sstep=30;
      eg.estep=430;
      ae.sample_size=5;
      ae.sample_sofar=0;
      ae.edataruleno=0;
      
#     if __WATCOM__ 
	 /*size of block for current statistics plot,
         statblock is global*/
	 imsize=imagesize(0,0,5,5);

	 if ((statblock = malloc(imsize)) == NULL){
	    draw_prompt_box(1);
	    sprintf(textb[0],"Out of memory! image, return-abort");
	    getch();
	    final_quit();
	 }
#     endif
      if ((freq_colors=
	  (unsigned char *)calloc(10,sizeof(unsigned char)))
			==NULL) outof_memory("freq_color");
      
      freq_colors[0]=black;
      freq_colors[1]=darkgray;
      freq_colors[2]=yellow;
      freq_colors[3]=lightblue;
      freq_colors[4]=brown;
      freq_colors[5]=cyan;
      freq_colors[6]=blue;
      freq_colors[7]=lightcyan;
      freq_colors[8]=magenta;
      freq_colors[9]=lightred;

      /* maximum froxen frequency bin boundarys=9*/
      num_bin_bound=9;
      if ((bin_bound=
	   (signed int *)calloc(num_bin_bound+1,sizeof(signed int)))
			==NULL) outof_memory("(bin_bound");

      if (frozen_gens-1 < num_bin_bound) num_bin_bound=frozen_gens-1;
      /*set the default bin boundaries*/
      freq_step=(float)frozen_gens/(num_bin_bound+1);
      for (z=1;z<=num_bin_bound;z++)
           bin_bound[z]=(signed int)freq_step*z;
         
      /*nominal size array*/
      if ((ae.edata=(float *)calloc(1,
	     sizeof(float)))==NULL) outof_memory("ae.edata");

      /*allocale mem prevoius states, at timestep t-1,t-2,...etc*/
      if ((it.last_state1=(char**)calloc(frozen_gens,sizeof(char*)))
				       ==NULL) outof_memory("it.last_state1");
      for (z=0;z<=frozen_gens-1;z++){
		 sprintf(textb[0],"it.last_state1[%d]",z);
		 if ((it.last_state1[z]=(char *)calloc(bytesL,sizeof(char)))
						==NULL) outof_memory(textb[0]);
      }
      /*position of flip in rule-table, up to 50*/
      if ((flippos=(signed int *)calloc(1,sizeof(signed int)))==NULL)
		outof_memory("flippos");
      //if (value_range>2){
       //value before flip (added Nov 2002), up to 50
      //now also applies for value_range=1 to allow zero flip June2021
         if ((flipvalue=(char *)calloc(1,sizeof(char)))==NULL)
		outof_memory("flipvalue");
      //}
      
      flipmem=1;
      it.diffgap=3; /*gap between sub-networks*/
      /*set width of pattern including gaps*/
      reset_stpwidth(&eg,&it);
          
      /*set width of graphs*/
      eg.eegwidth=eg.lookupfreqwidth=vgax(100);
     

      /*set up state-space matrix*/
      if (show_ss_matrixF==1) show_statespace_matrix(NULL);
      /*return map*/
      if (show_ss_matrixF=='r'){
         it.Hamming_plot=1;
         eg.ecolor=yellow;
         draw_Hamming_plot(1,eg.stpwidth);
         show_ss_matrixF=0;
      } 
      eg.showeeg=0;
      if (stpgraph==1) eg.showeeg=1; /*for density*/
      //if (eg.showeeg){
      if (stpgraph){
          if ((it.den_state=(float**)calloc(3, /*for density...x=t, y=t-1 (extended to t-2)*/
              sizeof(float*)))==NULL) outof_memory("it.den_state");
          for (z=0; z<=2; z++){ 
             if ((it.den_state[z]=(float*)calloc(value_range,
                sizeof(float)))==NULL) outof_memory("it.den_state");
          }
	  /*alloc mem to eg.eegcount
                  for each value
                  for each generation*/
         if ((eg.eegratiobefore=(double *)
                     calloc(value_range,sizeof(double)))
			         ==NULL)  outof_memory("eg.eegratiobefore");
         if ((eg.eegcount=(unsigned int **)
                     calloc(value_range,sizeof(unsigned int*)))
				   ==NULL)  outof_memory("eg.eegcount");
         for (zz=0;zz<=value_range-1;zz++){
	    if ((eg.eegcount[zz]=(unsigned int *)
                     calloc(gens,sizeof(unsigned int)))
				   ==NULL)  outof_memory("eg.eegcount[]");
         }
	 eg.tot_eegcount=0;
         for (zz=0;zz<=value_range-1;zz++)
	    eg.eegratiobefore[zz]=(double)eg.tot_eegcount/lineL;
      }
      eg.showlookupfreq=0;
      /* define size of rule table */
      if (nhood_mixed && single_entropy==1)
	       eg.ent_nhood=nhoodm[entropy_poss];
      else eg.ent_nhood=nhood;

      
      if (tot_only==0){
	if (set_iso_input_histogram==1) it.tablemax=iso_tablemax; /*isotropic rules*/
        else it.tablemax =(signed int)pow(value_range,(double)eg.ent_nhood)-1;
      }	
      else if (tot_only==1){
         if (totalistic==1) /*max index of tcode table*/
                it.tablemax=eg.ent_nhood*(value_range-1); 
         else if (totalistic==2) /*max index of kcode table*/
                it.tablemax=v_tablecodemax[eg.ent_nhood];
      }
      //if (stpgraph>1){
      if (stpgraph){
	 if (stpgraph==2) eg.showlookupfreq=1; /*for look-up frequency/entropy*/
	 else eg.showlookupfreq=2;
	 if ((eg.lookupcount=(unsigned int**)
                calloc(gens,sizeof(unsigned int*)))
			==NULL) outof_memory("eg.lookupcount");
	 /*alloc mem to eg.lookupcount for each nhood*/
	 for (z=0;z<=gens-1;z++){
	    sprintf(textb[0],"eg.lookupcount[%d]",z);
	    if ((eg.lookupcount[z]=(unsigned int *)calloc
		   (it.tablemax+1,sizeof(unsigned int)))
			    ==NULL) outof_memory(textb[0]);
	 }
	 /*alloc mem for size of old bar*/
	 if ((eg.oldbar=(signed int *)
                calloc(it.tablemax+1,sizeof(signed int)))
			     ==NULL) outof_memory("eg.oldbar");
         if (tempstp){
           signed int cols_available;
	    eg.startxbox=eg.stpwidth+(signed int)eg.lookupfreqwidth
	                               +vgax(10);
	    eg.xboxmax=eg.startxbox+(signed int)eg.lookupfreqwidth;
	    eg.startybox=vgay(57);/*top of lookup histogram*/
	    
	    eg.barno=it.tablemax+1;

            /*set the max length of histogram, before next row, also in forint*.c*/
            if (eg.barno>128) eg.barno=128;

	    eg.barw=(float)(Maxy-eg.startybox)/eg.barno;
	    if (eg.barw>vgay(5)) eg.barw=vgay(5);
	    eg.yboxmax=eg.startybox+(signed int)eg.barw*eg.barno;
	    eg.barsep=vgay(2);
            //input-histogram frame
	    draw_box(-1,eg.startxbox-3,eg.startybox-2,
	         eg.xboxmax+2,eg.yboxmax+1,1,0);           

            /*set up parameters for alternative newhist, which can divide long
	      lookup tables into groups, showing a bar for the max in each group*/
            cols_available=eg.yboxmax-1-(eg.startybox+1);
            eg.col_group_size=1;
            if (it.tablemax+1 > cols_available) eg.col_group_size=
                   (signed int) ceil( (float)(it.tablemax+1)/cols_available);
            cols_available=(it.tablemax+1)/eg.col_group_size; //adjust no of cols if required
            eg.lastgroup_size=(it.tablemax+1)%eg.col_group_size;
            if (eg.lastgroup_size>0) cols_available+=1;
            /*fprintf(stderr,
               "\ntablesize=%d cols_available=%d eg.col_group_size=%d eg.lastgroup_size=%d",
	       it->tablemax+1,eg.cols_available,eg.col_group_size,eg.lastgroup_size);*/
            if ((eg.hist_group=(signed int *)
                           calloc(eg.col_group_size+1,sizeof(signed int)))
				     ==NULL) outof_memory("eg.hist_group");
         }

         /*title box for single gene -- shown in on-the-fly key index*/
	 /*if (single_entropy==1){
	    draw_prompt_box(1);
	    if (oned==1) sprintf(textb[0],
	      "single entropy: pos=%d  gens=%d",
			       entropy_poss,gens);
	    else if (twod==2) sprintf(textb[0],
	      "single entropy: pos i,j=%d,%d gens=%d",
			entropy_poss%i2d,entropy_poss/i2d,gens);
            else if (threed==3) sprintf(textb[0],
	      "single entropy: pos i,j,h=%d,%d,%d gens=%d",
		     entropy_poss%i3d,
                           entropy_poss%(i3d*j3d)/i3d,
                                  entropy_poss/(i3d*j3d),gens);
	    outtext(textb[0]);
	  }*/

         /*limit the size of bars in lookup-histogram*/
	 /*if (eg.ent_nhood<8) eg.barlength=(signed int)eg.lookupfreqwidth;
	 else eg.barlength=(signed int)
	                 eg.lookupfreqwidth/((it.tablemax+1)/eg.barno);*/
         eg.barlength=(signed int)eg.lookupfreqwidth;
      }
   } /*if forward only*/

#  if __UNIX__
      /*allocate mem for pixmap*/
      if ((it.offscreen_pixmap =
          (Pixmap *)malloc(sizeof(Pixmap *))) == NULL)
		outof_memory("Pixmap pointer");

      *it.offscreen_pixmap = 0;
#  endif
      if (d_mode==1){   
	 pixmap_width=eg.stpwidth+1;
         /*allow for graph*/
         if (stp && forwards_only==1
	     && (eg.showlookupfreq || eg.showeeg==1)){ 
            pixmap_width+=(signed int)eg.eegwidth;           
         }
         /*restrict width to window*/
         if (pixmap_width>Maxx || pixmap_width<=0 ) pixmap_width=Maxx;
#        if __UNIX__ 	 
	    reallocate_pixmap(0,0,pixmap_width,Maxy,it.offscreen_pixmap);
#        endif
      }

      else if (d_mode==3){ /*2d axonometric*/ 
	  pixmap_width=eg.stpwidth; /*restrict pixmap just to stp*/
         /*restrict width to window*/
         if (pixmap_width>Maxx || pixmap_width<=0 ) pixmap_width=Maxx; 
#        if __UNIX__ 
            reallocate_pixmap(0,0,pixmap_width,
		              /*it->fscale*j2d+1*/ Maxy, it.offscreen_pixmap);
#        endif
      }
         
      else if (d_mode==2){
         pixmap_width=it.fscale*i2d+(((double)it.fscale)/2+1);
         /*allow for division*/
         if (diff_plot) pixmap_width+=(it.fscale*it.diffgap);
         /*restrict width to window*/
         if (pixmap_width>Maxx || pixmap_width<=0 ) pixmap_width=Maxx; 
#        if __UNIX__ 
            reallocate_pixmap(0,0,pixmap_width,
		              it.fscale*j2d+1, it.offscreen_pixmap);
#        endif
      }

      else if (d_mode==4){
         pixmap_width=i3d*it.fscale+j3d*it.fscale*sin(PI/4)+1;
         /*allow for division*/
         if (diff_plot) pixmap_width+=(it.fscale*it.diffgap);
         /*restrict width to window*/
         if (pixmap_width>Maxx || pixmap_width<=0 ) pixmap_width=Maxx; 
#        if __UNIX__ 
            reallocate_pixmap(0,0,pixmap_width,
	       j3d*it.fscale*sin(PI/4)+h3d*it.fscale+1,it.offscreen_pixmap);
#        endif
      }
      it.ittcount=attperiod=0;

      /*xtl=ytl=1;*/ /*displace top left corner from 0,0*/
   if (stp){
      it.color0=black;
      /*it.color1=yellow;*/
      it.color1=white;
      seed_was_set=1;    /*indicates a new seed set with key 4*/

      if (forwards_only==1){
	 /*show index to interrupt keys*/
	 showkey;
	 it.keyindex=1;
      }
      moveto(0,0);
   }
   if (forwards_only==1 && stpgraph && stp){
      /*draw frame to window*/
      draw_stpframe(eg.stpwidth,eg.eegwidth);
      /*draw frame to pixmap*/ 
#     if __UNIX__         
         *current_draw = *it.offscreen_pixmap; 
         draw_stpframe(eg.stpwidth,eg.eegwidth);
         *current_draw = W;        
#     endif
   }

   tempx=getx;		
   tempy=gety;
   /* create a nominal box for 3d */
   draw_box(16,0,0,1,1,0,-1);
   moveto(tempx,tempy);

   it.fsep=0; /*now we draw a black/white rectange for divisions, March 07, 
                so it.fsep is irrelevant*/

   /*d_mode (global variable) 1-1d, 2-2d, 3-2d+time, 4-3d*/
   if (d_mode==2 || d_mode==3){
      /*draw frame*/
      /*if plotting difference between 2 equalsize/shape  networks
      draw 2 frames seperated by a 3 cell gap*/
      it.axo_cell_h=sin(PI/4)*it.fscale;
      it.wx=it.fscale*i2d;
      it.aa=it.axo_cell_h*j2d;
      if (diff_plot && twod==2) draw_2d_frame(&eg,&it);
      
      if (d_mode==3){
	  /*if (it.fscale>vgax(5)) it.fsep=2;
	    else it.fsep=1;*/
	  it.strip=it.downy=0;
	  it.polyx=0;
	  it.polyy=it.aa;
	  moveto(it.polyx,it.polyy);
	  draw_axon_plane(it.fscale,gety,it.draw_3d_grid);
      }
   }
   else if (d_mode==4){
      /*draw frame*/
      /*if plotting difference between 2 equalsize/shape  networks
      draw 2 frames seperated by a 3 cell gap*/
      it.axo_cell_h=sin(PI/4)*it.fscale;
      it.wx=it.fscale*i3d;
      it.aa=it.axo_cell_h*j3d;     
      /*if (it.fscale>vgax(5)) it.fsep=2;
       else it.fsep=1;*/
      it.strip=0;
      it.downy=1;
      step=0;
      it.polyx=0;
      it.polyy=it.aa+it.fscale;
      moveto(it.polyx,it.aa);
      draw_axon_plane(it.fscale,gety,it.draw_3d_grid);
      freeimage(boximage[16]);
      draw_box(16,0,0,i3d*it.fscale+j3d*it.fscale*sin(PI/4),
		     j3d*it.fscale*sin(PI/4)+h3d*it.fscale,0,-1);
   }
   
   /*clear the difference plot buffer to retain damaged cells*/  
#  define clear_diff_plot {\
      for (zu=0;zu<=bytesL-1;zu++) tempState[zu]=0;\
   }
   if (diff_plot) clear_diff_plot; /*clear the difference plot buffer*/
   dp.same_count=0; /*steps that diff pattern doesnt change*/ 
   if (stpgraph) eg.twodgy=-1; /*reset input-entropy plot*/
   slant=-1; /* to unslant even k stp*/
   if (forwards_only) stagger_even_rows=0;
   it.slant_even_k=0;
   
   /*don't make slant it.slant_even_k the default*/
   /*if (forwards_only==1 && nhood%2==0 && 
          stp && oned && d_mode==1 && !nhood_mixed && nonlocal==0){
       it.slant_even_k=1;
   }*/
   /*to start with hex grid*/
   if (forwards_only==1 && twod==2 &&  
         d_mode==2 && nhood_mixed==0  && twod_local==1 
              && hex2d==1 ) stagger_even_rows=it.slant_even_k=1;

   if (forwards_only) show_multistate_color_key(1);
   nowscrolling=0;
   if (oned==1 && d_mode>1) scrolling=0;
   //if (d_mode==4) 
   it.slice_3d=1; /*show 3d as balls, 0=parallelogram*/
   
  
   while (1) {            
        if ((diff_plot==3 || diff_plot==4) && dp.d_ittcount==it.ittcount){
                       random_bitflip_state(it.color1);
	    if (oned && scrolling==0) moveto(0,0);
        }
	it.ittcount++;
        if (scrolling==1 && stp && d_mode==2){ /*scroll 2d*/
            if (nowscrolling==0) it.downy+=1;
            it.polyy=it.fscale*it.downy; /*position of top left corner for 
                                           axon_plane when scrolling*/
        }
        /*else if (d_mode==3){
            if (nowscrolling==0 && 
                    gety>=Maxy-it.fscale-
                         (signed int)(sin(PI/4)*it.fscale*j2d));
               it.downy+=1; 
	}*/

        /* to unslant even k stp*/  
        if (it.slant_even_k){
            slant++;
	   if (oned){
	      if (slant==lineL*2) slant=0;
              if (it.slant_even_k==1) 	     
	         moveto(((float)it.fscale/2) *slant,gety); /*slant right*/
              else if (it.slant_even_k==2) 	     
	         moveto(-((float)it.fscale/2) *slant,gety); /*slant left*/
           }          
        }


        if (it.skip_timesteps==1){
            if (it.ittcount%(time_skip+1)==0) stp=1;
            else stp=0;
        }

	eg.actgens=gens;
	if (it.ittcount<gens) eg.actgens=it.ittcount;

	/**** space-time patterns for random_graphs ???  ********/
	/*if (exhaustive_testing==2){
	  if (stp){
	      char tempscale,tempsep;

              tempscale=scale;
              tempsep=sep ;
              scale=it.fscale;
              sep=it.fsep;
	      print_current_state(state1,lightred);
	      end_page(it.fscale,0);
              scale=tempscale;
              sep=tempsep;
	   }
	   memmove(state2,exh_pairs+dec_equiv(state1,L)*bytesL,bytesL);
	   goto skip_for;
	}*/

	sk.frozen_1s=sk.frozen_0s=0;


        /*draw lines to scroll frame */
        if (nowscrolling==1 && (d_mode==1 || d_mode==3)  && stp
	     && (eg.showlookupfreq || eg.showeeg==1)){
	   tempcolor=getcolor();
#          if __UNIX__
	      *current_draw=*it.offscreen_pixmap;
#          endif
	      setcolor(red);
	      for (z=0;z<=4;z++){
		 if (stpgraph==2 && z>0 && z<4) continue;
		 if (it.fscale==1) putpixel(eg.stpwidth+
			       (eg.eegwidth/4)*z,gety,red);
		 else line(eg.stpwidth+(eg.eegwidth/4)*z,gety,
		   eg.stpwidth+(eg.eegwidth/4)*z,gety-it.fscale);
	      }
#          if __UNIX__
	      *current_draw=W;
#          endif
            setcolor(tempcolor);
	 }

        if (d_mode==4 && stp){ 
           moveto(it.polyx,it.aa);    
#          if __WATCOM__ /*not xwindows*/
               sprintf(textb[9],"%s","boximage[16]"); 
               putimage(0,0,boximage[16],COPY_PUT,textb[9]);            
#          elif __UNIX__ /*draw to pixmap*/                             
               /*show the pixmap on the screen*/
               sprintf(textb[9],"%s","offscreen_pixmap"); 
	       putimage(0,0,it.offscreen_pixmap,COPY_PUT,textb[9]);
               /*draw cage (clears previous pixmap)*/
               *current_draw = *it.offscreen_pixmap;
               sprintf(textb[9],"%s","boximage[16]");
               putimage(0,0,boximage[16],COPY_PUT,textb[9]);
               *current_draw = W;
	      
#          endif
	}
        if (forwards_only==1){
           if (it.partial_order==1 && forwards_only==1){

	      /*"partial order" updating (forward only):
              the lower and upper limit define a size window.
              At each time-step a rnd size is set between these limits, and applied rndly
              to positions in the network -- only these are updated. 
              Very similar (sort of opposite of) "update probability",
              but "partial order" guarantees a fixed range of the update subset, including
              just one value if lower limit = upper limit.*/
          
	     unsigned int try_no,temp_pos,net_limitsize,net_subsetsize;	  
              /*set size of subset to be updated synchronously*/
              for (zu=0; zu<=bytesL-1;zu++) net_subset[zu]=0;
              
              net_limitsize=porder_max-porder_min;
              /*at least 1 or porder_min, max lineL-1 or porder_max*/
              net_subsetsize=myrand()%(net_limitsize+1)+porder_min;
 
              /*fprintf(stderr,"\n %d-%d+1=%d sub=%d: ->",
		   porder_max,porder_min,net_limitsize,net_subsetsize);*/
	      try_no=0;
              while(1){	      
                 temp_pos=myrand()%lineL;
	         if (get_bit(net_subset,temp_pos)==0){ 
                    set_bit(net_subset,temp_pos,1);
                    try_no+=1;
                    /*fprintf(stderr," %d",temp_pos);*/
                    if (try_no==net_subsetsize) break;
                 }
                 else continue;
              }
           }
           if (it.temp_seq_update==4){
             unsigned int poss,try,tickoffbytes;
             char *seq_tickoff,dir;
          
              tickoffbytes=(unsigned int)ceil( (double)lineL/8);
              if ((seq_tickoff=(char *)calloc(tickoffbytes,sizeof(char)))
				     ==NULL) outof_memory("seq_tickoff");	
              /*fprintf(stderr,"\n");*/
	      for (poss=0;poss<=L;poss++){
                 try=myrand()%lineL;
	         dir=(myrand()%2)-1; /*choose -1 or 1 at random*/
	         if (dir==0) dir=1;
	     
	        try_again:	     
	         if (get_bit(seq_tickoff,try)==0){ /*if not used*/
		    seq_order[poss]=try;
		    set_bit1(seq_tickoff,try);
                    /*fprintf(stderr,"%d ",seq_order[poss]);*/
	         }
                 else {		 
		    try=try+dir; /*randomly inc or dec index by one*/
		    if (try==lineL) try=0;
		    else if (try==Maxu) try=L;
                    goto try_again;
	         }             
	      }     
           }
        }

	/*scan CA line from left to right -->*/       
	for (poss=L; poss!=Maxu; poss--){
	   if (it.temp_seq_update>0) n=seq_order[poss]; /*set updating order*/
           else n=poss;
           	  
           /* to unslant even k stp*/ 
           if (it.slant_even_k && oned){ //type casting to (signed int) essential
	      if (getx>=it.fscale*(signed int)lineL){  
                 if (slant%2==1) moveto((float)it.fscale/2,gety);
                 else moveto(0,gety);
	      }
              else if (getx<0)
                    moveto(getx+lineL*(float)it.fscale,gety);
           }   
      
  	   /*(on-the-fly) force local 1d wiring, conserve wiring mem*/         
           if (oned && (loc_twod_fonly || wiring_madelocal==1) ){  
	       if (L<nhoodm[n]/2){ /*i.e. for nhood=9 lineL=3 to work*/
                  signed int temp;
	          for (i=0;i<=nhoodm[n]-1;i++){
		       temp=lineL+n-(nhoodm[n]/2)+i;
		       if (temp<0) temp+=lineL;
		       pnhood[i]=abs(temp)%lineL;
	          }
	       }
	       else{
	          for (i=0;i<=nhoodm[n]-1;i++)
			pnhood[i]=(lineL+n-(nhoodm[n]/2)+i)%lineL;                  
	       }
	   }               
	   /*(on-the-fly) force local 2d wiring, conserve wiring mem*/
	    else if (twod && (loc_twod_fonly || wiring_madelocal==1)){   
                  wire_2d_local(n,pnhood);
            }
	   /*(on-the-fly) force local 3d wiring, conserve wiring mem*/
	    else if (threed && (loc_twod_fonly || wiring_madelocal==1)){
	          wire_3d_local(n,pnhood);
            }

	   /*nonlocal=1(rand wiring) or 0(local wiring), 
            get psuedo-nhood from wiringxx.c, 
            1d, if local: oneD_local_wire_cell, 
            2d, wireup_2d_nhood
            3d, wire_3d_local*/
	   else{
	       for (i=0;i<=nhoodm[n]-1;i++) pnhood[i]=wiring[n][i];
	   }
	   
	   /*show space-time pattern - print current cell, cell value*/
           /*set colors for cells, required for skeleton hist*/
	   if (stp || att_hist==2){              
	      /*color cell according to value, (or if frozen)*/
	      if (ncolor==0 || att_hist==2 ||  seed_was_set==1) {
		  /*check for frozen state in last x generations*/
		 if ((it.frozen_islands || att_hist==2) && forwards_only==1){
		    it.cell_not_changed=0;
		    if (it.ittcount>frozen_gens){
		       /*check cell not changed since last time-step*/
		       it.cell_not_changed=1;
                       if (get_value(state1,n)!=get_value(it.last_state1[0],n))
						    it.cell_not_changed=0;
		       /*same check if x previous generations frozen*/
		       if (it.cell_not_changed==1){
			 for (z=1;z<=frozen_gens-1;z++){
                             if (get_value(it.last_state1[z-1],n)!=
                                             get_value(it.last_state1[z],n)){
				   it.cell_not_changed=0;
				   break;
			     }
			  }
		       }                 
                       if (att_hist==2){                          
			   if (it.cell_not_changed==1){
                                 if (sk.skel_val==2) set_bit1(sk.frozen_buff,n);
			         if (get_bit(state1,n)==1){
                                     if (sk.skel_val==1) 
                                          set_bit1(sk.frozen_buff,n);
			         }  
                                 else{  
                                     if (sk.skel_val==0) 
                                          set_bit1(sk.frozen_buff,n);
			         }
                           }
                           else set_bit0(sk.frozen_buff,n);
		       }   
		       /*if cell frozen for x previous gens*/
                       /*frozen cells: 1=lightred ,0=red rest=background*/
		       if (att_hist==2 || it.frozen_islands==3){
			  if (it.cell_not_changed==1){
			     if (get_value(state1,n)==value_range-1) sk.frozen_1s++;
			     else  sk.frozen_0s++;
			  }
		       }
		       /*check time density of 1s for the last
			 frozen_gens generations*/
		       if (it.frozen_islands==4){
			  unsigned int freq;
                          char thiscolor_set=0;
                           
			   freq=0;
			   for (z=1;z<=frozen_gens-1;z++){
			      if (get_value(it.last_state1[z],n)==value_range-1) freq++;
			   }
			   if (get_value(state1,n)==value_range-1) freq++;

			   /*spot color according to freq*/                           
			   for (z=1;z<=num_bin_bound;z++){
                              if (freq<=bin_bound[z]){
				   if (z==1) thiscolor=freq_colors[0];
                                   else thiscolor=
                                      freq_colors[10*z/(num_bin_bound+1) -1];
                                   /*thiscolor=freq_colors[z-1];*/
                                   thiscolor_set=1;
                                   break;
                              }
                           }
                           if (thiscolor_set==0) thiscolor=freq_colors[9];
		       }

		       else if (it.frozen_islands==3){
                          if (it.cell_not_changed==1){
                              if (get_value(state1,n)==value_range-1) 
                                   thiscolor=lightred;
			      else thiscolor=green;
		          }
			  /*color changing cell as background*/
			  /*else thiscolor=black;*/
                          else thiscolor=color_v[0];                         
		       }
                       /*frozen cells lightred rest normal*/
		       else if (it.frozen_islands==2){ 
			 if (it.cell_not_changed==1)  thiscolor=magenta;   
                          else{ //if it.cell_not_changed==0, cell did change
			     //set nornal cell color
                             thiscolor=color_v[get_value(state1,n)];
			  }			  
                       }
                       //present non-zero normal, dynamic cell leave green tail on any stable background
                       else if (it.frozen_islands==1){ 
                          //if cell not changed for x (def 20) time-steps -- color=value
                          if (it.cell_not_changed==1)  thiscolor=color_v[get_value(state1,n)];                          
                          else{ //if cell has changed during last (def 20) time-steps,

                            if (get_value(state1,n)>=1) thiscolor=color_v[get_value(state1,n)];
                                   //otherwise leave a lightgreen/darkgreen trail (for white/black bground)
                                else thiscolor=darkgray;
			  }
		       }              
		       else thiscolor=color_v[get_value(state1,n)];
    	            }
                    else thiscolor=color_v[get_value(state1,n)];
		 }
		 /*normal color*/
		 /*else if (it.frozen_islands==0){ */
		 else{
                     /*set normal cell color*/
                     thiscolor=color_v[get_value(state1,n)];
		 }
		 if (forwards_only==1){
                    stp_cell_color[n]=thiscolor;/*for graph layout*/
                    //n=state-index, nhd[n]=decvalue of nhood
                    if (set_iso_input_histogram==1){
                       if (get_bit(color_filter,group_list_iso[nhd[n]])==1 
                             && it.filter_toggle==0) stp_cell_color[n]=color_v[0];
                    }
		    else{
                       if (get_bit(color_filter,nhd[n])==1
                             && it.filter_toggle==0) stp_cell_color[n]=color_v[0];                      
		    }                    
                 }
                                                          
		 if (d_mode<=2 &&  
                         !(d_mode==2 && scrolling==1)){ /*1d or 2d by value*/
		    /*1d or 2d - draw cells by value, or frozen*/
                     /*filter if set*/
		    if (set_iso_input_histogram==1){
                       if (get_bit(color_filter,group_list_iso[nhd[n]])==1
                              && it.filter_toggle==0) thiscolor=color_v[0];
                    }
                    else{ //thiscolor=black
                       if (get_bit(color_filter,nhd[n])==1
                              && it.filter_toggle==0) thiscolor=color_v[0];
		    }         
#                   if __UNIX__ /*draw to pixmap*/
                              *current_draw = *it.offscreen_pixmap;
#                   endif
                    
		    if (it.fscale==1) putpixel(getx,gety,thiscolor);
                    else{
                          setfillstyle(SOLID_FILL,thiscolor);
                          if (it.fscale==2) bar(getx,gety,getx+it.fscale,
                                                gety+it.fscale);
                          else if (it.fscale>=3){               
			     if (it.slant_even_k==1 && twod && d_mode==2){
				 draw_hexagonal_2d_cell(it.hex_rad,it.fscale,
				   it.show_2d_divs,it.show_dots,thiscolor,
                                      it.divcolor,getx,gety);
                                 /*old method with a circle*/
                                 /*pieslice(it.pi_outline,getx+it.fscale/2,gety+it.fscale/2,
				   0,360,it.fscale/2);*/
                             }
                             else{  
			       /*bar(getx,gety,getx+it.fscale-it.fsep,
				              gety+it.fscale-it.fsep);*/
			         bar(getx,gety,getx+it.fscale,
			                     gety+it.fscale);

                                 /*put a dot on zero cell*/
                                 /*if (it.show_dots==1 &&  cellscale>=4 &&*/
                                   if (it.show_dots==1 &&  it.fscale>=4 &&
				     /*(thiscolor==black || thiscolor==darkgray))*/
				     thiscolor==color_v[0])
	                             putpixel(getx+it.fscale/2,
                                         gety+it.fscale/2,green);
                         
                                 /* black rectangle for divisions, otherwise cell gap it.fsep*/ 
                                 if (it.fscale>3 && it.show_2d_divs==1){      
                                    setcolor(it.divcolor);
                                    rectangle(getx,gety,getx+it.fscale,gety+it.fscale);
                                 }
                             } 
                          }
		  }
#                 if __UNIX__  /*draw to window*/
                                       *current_draw = W;
#                 endif      
		  moverel(it.fscale,0);
		 }


                 /*2d scrolling - draw cells by value, or frozen*/ /*scroll 2d*/
		 else if (d_mode==2 && scrolling==1){
                    scroll_x=it.downy*it.fscale;
                    scroll_y=it.downy*it.fscale;
		    if (set_iso_input_histogram==1){
                        if (get_bit(color_filter,group_list_iso[nhd[n]])==1
                                && it.filter_toggle==0) thiscolor=black; //filter if set
                    }
                    else{
		        if (get_bit(color_filter,nhd[n])==1
                                && it.filter_toggle==0) thiscolor=black; /*filter if set*/
		    }
                    if (value_range>2){ /*dont show darkgray cells*/
                      if (color_v[get_value(state1,n)]==darkgray) thiscolor=black;
                    }
                    /*dont print black (background color),
                        or invisible (to show only graph option (i.e. 1d tube)*/
		    if (thiscolor!=black && it.invisible==0){
		       setcolor(thiscolor);
                    if (it.fscale==1) putpixel(scroll_x+getx,scroll_y+gety,thiscolor);
                    else if (/*it.fscale>3 &&*/ it.slice_3d==1){ /*show as balls*/
			     /*show 1s as normal, or runup to frozen*/
                             if (it.frozen_islands==0 || (it.cell_not_changed
                                           ==0 && it.frozen_islands!=3)){
			       if (bground=='w'){
				      setcolor(white); 
				      if (value_range==2) 
                                           setfillstyle(SOLID_FILL,blue);
                                      /*yellow balls, black outline*/
                                      else setfillstyle(SOLID_FILL,thiscolor);
				}
				else{
				   setcolor(yellow); 
				   if (value_range==2) 
                                       setfillstyle(SOLID_FILL,lightblue);
                                   /*lightblue balls, yellow outline*/
                                   else setfillstyle(SOLID_FILL,thiscolor);
				}
			     }
			     else{
				if (thiscolor==white) setcolor(yellow);
				else setcolor(white);
				setfillstyle(SOLID_FILL,thiscolor);
			     }
			     pieslice(it.pi_outline,
                                     scroll_x+getx+it.fscale/2,scroll_y+gety+it.fscale/2,
                                                                  0,360,it.fscale/2);
		             stp_cell_color[n]=fillcolor;/*for graph layout*/
		    }
                    else{ /*show as squares or hexagons*/
                          setfillstyle(SOLID_FILL,thiscolor);
                          if (it.fscale==2) bar(scroll_x+getx,scroll_y+gety,
                                 scroll_x+getx+it.fscale,scroll_y+gety+it.fscale);
                          else if (it.fscale>=3){                 
			     if (it.slant_even_k==1 && twod && d_mode==2){
				 draw_hexagonal_2d_cell(it.hex_rad,it.fscale,
				   it.show_2d_divs,it.show_dots,thiscolor,
                                         it.divcolor,scroll_x+getx,scroll_y+gety);
                             }
                             else{  
                                 bar(scroll_x+getx,scroll_y+gety,
                                    scroll_x+getx+it.fscale-it.fsep,
                                         scroll_y+gety+it.fscale-it.fsep);
                                 /*put a dot on zero cell*/
                                 /*if (it.show_dots==1 &&  cellscale>=4 &&*/
                                  if (it.show_dots==1 &&  it.fscale>=4 &&
				                         thiscolor==color_v[0])
	                             putpixel(scroll_x+getx+it.fscale/2,
                                         scroll_y+gety+it.fscale/2,green);
                                 /* black rectangle for divisions, otherwise cell gap it.fsep*/ 
                                 if (it.fscale>3 && it.show_2d_divs==1){      
                                    setcolor(it.divcolor);
                                    rectangle(scroll_x+getx,scroll_y+gety,
                                        scroll_x+getx+it.fscale,scroll_y+gety+it.fscale);
                                 }

                             }
		          }
		      } 
		    }
                    moverel(it.fscale,0);
                 }

		 /*2d+time or
                   3d - draw cells by value, or frozen*/
		 else if (d_mode==3 || d_mode==4){
                         
                 /* 23______45  2-d space-time patterns in 3-d axonometric
		     /     /
		    /     /
		   /     /
		  /_____/
		 01     67      */
		    step+=1;
		    if (set_iso_input_histogram==1){
		       if (get_bit(color_filter,group_list_iso[nhd[n]])==1
                            && it.filter_toggle==0) thiscolor=black; //filter if set
                    }
                    else{
		       if (get_bit(color_filter,nhd[n])==1
                            && it.filter_toggle==0) thiscolor=black; /*filter if set*/
		    }
                    if (value_range>2){ /*dont show darkgray cells*/
                      /*for singleton 3d*/
		      /*if (get_value(state1,n)==0 || 
                          (threed && color_v[get_value(state1,n)]==color_v[0])) 
			  thiscolor=black;*/
                      if (color_v[get_value(state1,n)]==darkgray)
                                        thiscolor=black;

                    }
		    if (thiscolor!=black){ /*not background color*/
		       setcolor(thiscolor);
		       /*1st vertex*/
		       poly[0] =it.polyx+(step-1)*it.fscale;
		       poly[1] =it.polyy-sin(PI/4)*it.strip*it.fscale;

		       if (it.fscale>1){
			   /*2nd*/
			   poly[2] =poly[0]+it.axo_cell_h;
			   poly[3] =poly[1]-it.axo_cell_h;
			   /*3rd*/
			   poly[4] = poly[2]+it.fscale;
			   poly[5] = poly[3];
			   /*4th*/
			   poly[6] = poly[0]+it.fscale;
			   poly[7] = poly[1];
			   setfillstyle(SOLID_FILL,thiscolor);
		       }
		       /* draw a filled polygon or circle*/
#                      if __WATCOM__ /*not xwindows*/
			  if (it.fscale==1)
					putpixel(poly[0],poly[1],thiscolor);
                          else if (/*it.fscale>3  &&*/ it.slice_3d==1){
			     /*show 1s as normal, or runup to frozen*/
                             if (it.frozen_islands==0 || (it.cell_not_changed
                                           ==0 && it.frozen_islands!=3)){
			       if (bground=='w'){
				      setcolor(white); 
				      if (value_range==2) 
                                           setfillstyle(SOLID_FILL,blue);
                                      /*yellow balls, black outline*/
                                      else setfillstyle(SOLID_FILL,thiscolor);
				}
				else{
				   setcolor(yellow); 
				   if (value_range==2) 
                                       setfillstyle(SOLID_FILL,lightblue);
                                   /*lightblue balls, yellow outline*/
                                   else setfillstyle(SOLID_FILL,thiscolor);
				}
			     }
			     else{
				if (thiscolor==white) setcolor(yellow);
				else setcolor(white);
				setfillstyle(SOLID_FILL,thiscolor);
			     }
			     pieslice(it.pi_outline,poly[2],poly[3],0,360,it.fscale/2);
		             stp_cell_color[n]=fillcolor;/*for graph layout*/
			  }
                             
			  else{
			     fillpoly(4, poly);/*draw the filled poly*/
			     /*then draw contrasting outline or part*/
			     /*if (it.frozen_islands==0 && it.fscale>=2){*/
			     if (it.fscale>=2){
				if (thiscolor==white) tempcolor=yellow;
				else tempcolor=white;
				setcolor(tempcolor);
				if (it.fscale==2)
					putpixel(poly[2],poly[3],tempcolor);
				else if (it.fscale>=3){
				   line(poly[0],poly[1],poly[2],poly[3]);
				   line(poly[2],poly[3],poly[4],poly[5]);
				}
			     }
			  }

#                      elif __UNIX__ /*draw to pixmap*/
			  if (d_mode==4)
				*current_draw = *it.offscreen_pixmap;
			  if (it.fscale==1)
					putpixel(poly[0],poly[1],thiscolor);
			  else if (/*it.fscale>3 &&*/ it.slice_3d==1){
			     /*show 1s as normal, or runup to frozen*/
			     if (it.frozen_islands==0 ||
			             (it.cell_not_changed==0 && 
                                                it.frozen_islands!=3)){
				if (bground=='w'){
				   setcolor(white); 
				   if (value_range==2) 
                                        setfillstyle(SOLID_FILL,blue);
                                   /*yellow balls, black outline*/
                                   else setfillstyle(SOLID_FILL,thiscolor);
				}
				else{
				   setcolor(yellow); 
				   if (value_range==2) 
                                       setfillstyle(SOLID_FILL,lightblue);
                                   /*lightblue balls, yellow outline*/
                                   else setfillstyle(SOLID_FILL,thiscolor);
				}
			     }
			     else{
				if (thiscolor==white) setcolor(yellow);
				else setcolor(white);
				setfillstyle(SOLID_FILL,thiscolor);
			     }
                             pieslice(it.pi_outline,poly[2],poly[3],0,360,it.fscale/2);
                             stp_cell_color[n]=fillcolor;/*for graph layout*/
			  }
			  else{
			     fillpoly(4, poly);/*draw the filled poly*/
			     /*if (it.frozen_islands==0 && it.fscale>=2){*/
			     /*then draw contrasting outline or part*/
			     if (it.fscale>=2){
				if (thiscolor==white) setcolor(yellow);
				else setcolor(white);
				if (it.fscale==2)
					putpixel(poly[2],poly[3],fillcolor);
				else if (it.fscale>=3){
				   line(poly[0],poly[1],poly[2],poly[3]);
				   line(poly[2],poly[3],poly[4],poly[5]);
				}
			     }
			  }
			  if (d_mode==4) *current_draw = W;
#                      endif
		    }      
		 }                  
	    }

	    /*print current cell, nhood value*/
	    if (ncolor==1 && seed_was_set==0 && forwards_only==1){
               if (set_iso_input_histogram==1){
		  
                  if (nhd[n]>0 && get_bit(color_filter,group_list_iso[nhd[n]])==1
                       && it.filter_toggle==0) nhdcolor=black;
                  else if (nhd[n]==0) nhdcolor=black; //override for zero on black bground
	          else nhdcolor=set_nhdcolor(nhoodm[n],group_list_iso[nhd[n]]);
               }
               else{
                  if (nhd[n]>0 && get_bit(color_filter,nhd[n])==1
                      && it.filter_toggle==0) nhdcolor=black;
                  else if (nhd[n]==0) nhdcolor=black; //override for zero on black bground	   
	          else nhdcolor=set_nhdcolor(nhoodm[n],nhd[n]);
               }

	       if (d_mode<=2 && 
                     !(d_mode==2 && scrolling==1)){ /*1d or 2d by nhood*/
#                 if __UNIX__   /*draw to pixmap*/
			    *current_draw = *it.offscreen_pixmap;
#                 endif
                  
		  if (it.fscale==1) putpixel(getx,gety,nhdcolor);
		  else{
                     setfillstyle(SOLID_FILL,nhdcolor);
                     if (it.fscale==2) bar(getx,gety,getx+it.fscale,
                                           gety+it.fscale);
                     else if (it.fscale>=3){
			 if (it.slant_even_k==1 && twod && d_mode==2){
                            draw_hexagonal_2d_cell(it.hex_rad,it.fscale,
			       it.show_2d_divs,it.show_dots,thiscolor,
                                it.divcolor,getx,gety);
			 }
                         else{
                             bar(getx,gety,getx+it.fscale-it.fsep,
                                               gety+it.fscale-it.fsep);
                             /* black rectangle for divisions, otherwise cell gap it.fsep*/ 
                             if (it.fscale>3 && it.show_2d_divs==1){      
                                    setcolor(it.divcolor);
                                    rectangle(getx,gety,getx+it.fscale,gety+it.fscale);
                             }
                         }
		     }
		  }
#                 if __UNIX__  /*draw to window*/
					     *current_draw = W;
#                 endif
		  moverel(it.fscale,0);
	       }
               /*2d scrolling - draw cells by nhood color */ /*scroll 2d*/
               else if (d_mode==2 && scrolling==1){ /*1d or 2d by nhood*/
                    scroll_x=it.downy*it.fscale;
                    scroll_y=it.downy*it.fscale;
                    /*dont print black (background color),
                        or invisible (to show only graph option (i.e. 1d tube)*/
		    if (nhdcolor != black && it.invisible==0){
                       if (it.fscale==1) putpixel(scroll_x+getx,scroll_y+gety,nhdcolor);
                       else if (/*it.fscale>3 &&*/ it.slice_3d==1){ /*show as balls*/
                          if (nhdcolor==white) setcolor(yellow);
			  else setcolor(white);
			  setfillstyle(SOLID_FILL,nhdcolor);
                          pieslice(it.pi_outline,scroll_x+getx+it.fscale/2,
                             scroll_y+gety+it.fscale/2,0,360,it.fscale/2);
		       }
		       else{
                          setfillstyle(SOLID_FILL,nhdcolor);
                          if (it.fscale==2) bar(scroll_x+getx,scroll_y+gety,
                                 scroll_x+getx+it.fscale,scroll_y+gety+it.fscale);
                          else if (it.fscale>=3){
                             if (it.slant_even_k==1 && twod && d_mode==2){
				 draw_hexagonal_2d_cell(it.hex_rad,it.fscale,
				   it.show_2d_divs,it.show_dots,nhdcolor,
                                         it.divcolor,scroll_x+getx,scroll_y+gety);
                             }
                           
                             else{ /*show as squares or hexagons*/ 
                                 bar(scroll_x+getx,scroll_y+gety,
                                    scroll_x+getx+it.fscale-it.fsep,
                                         scroll_y+gety+it.fscale-it.fsep);
                                 /*put a dot on zero cell*/
                                 /*if (it.show_dots==1 &&  cellscale>=4 &&*/
                                   if (it.show_dots==1 &&  it.fscale>=4 &&
				                         thiscolor==color_v[0])
	                             putpixel(scroll_x+getx+it.fscale/2,
                                         scroll_y+gety+it.fscale/2,green);
                                 /* black rectangle for divisions, otherwise cell gap it.fsep*/ 
                                 if (it.fscale>3 && it.show_2d_divs==1){      
                                    setcolor(it.divcolor);
                                    rectangle(scroll_x+getx,scroll_y+gety,
                                    scroll_x+getx+it.fscale,scroll_y+gety+it.fscale);
                                 }
                             }
                          }
		       }
		    }
		     moverel(it.fscale,0);
	       }

               /*2d+time or
                 3d axonometric - nhood color*/
	       else if (d_mode==3 || d_mode==4){
		/*  23______45  
		     /     /
		    /     /
		   /     /
		  /_____/
		01      57      */
		  step+=1;
                  if (get_value(state1,n)>0 && get_bit(color_filter,nhd[n])==0){

		       if (nhdcolor==0) nhdcolor=white;
		       setcolor(nhdcolor);

		       /*1st vertex*/
		       poly[0] =it.polyx+(step-1)*it.fscale;
		       poly[1] =it.polyy-sin(PI/4)*it.strip*it.fscale;

		       if (it.fscale>1){
			  /*2nd*/
			  poly[2] =poly[0]+it.axo_cell_h;
			  poly[3] =poly[1]-it.axo_cell_h;
			  /*3rd*/
			  poly[4] = poly[2]+it.fscale;
			  poly[5] = poly[3];
			  /*4th*/
			  poly[6] = poly[0]+it.fscale;
			  poly[7] = poly[1];
			  setfillstyle(SOLID_FILL,nhdcolor);
		       }
		       /* draw a filled polygon */
#                      if __WATCOM__ /*not xwindows*/
			  if (it.fscale==1)
				 putpixel(poly[0],poly[1],nhdcolor);
                          else if (/*it.fscale<=3 ||*/ it.slice_3d==0) 
			      fillpoly(4, poly);
			  else{
                             if (nhdcolor==white) setcolor(yellow);
			     else setcolor(white);
			     setfillstyle(SOLID_FILL,nhdcolor);
                             pieslice(it.pi_outline,poly[2],poly[3],0,360,it.fscale/2);
			  }
#                      elif __UNIX__ /*draw to pixmap*/
			  if (d_mode==4)
				*current_draw = *it.offscreen_pixmap;
			  if (it.fscale==1)
					putpixel(poly[0],poly[1],nhdcolor);
                          else if (/*it.fscale<=3 ||*/ it.slice_3d==0) 
			      fillpoly(4, poly);
                          /* cut above line for balls only 2d + time*/
			  else {
			     if (nhdcolor==white) setcolor(yellow);
			     else setcolor(white);
			     setfillstyle(SOLID_FILL,nhdcolor);
			     pieslice(it.pi_outline,poly[2],poly[3],0,360,it.fscale/2);
			  }
			  if (d_mode==4) *current_draw = W;
#                      endif
		  }
	       }
               if (forwards_only==1) 
                  stp_cell_color[n]=nhdcolor;/*for graph layout*/
	     }
	   }

           u=0; /*find dec value of actual or pseudo-nhood*/
           /*xxxxxxxxxxxx next time-step xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx*/
	   u=next_time_step(thisrule,
                            state1,
                            state2,
	                    it.partial_order,
                            net_subset,
                            forwards_only,
                            pnhood, 
                            n,
                            it.rule_unmixed);
           /*xxxxxxxxxxxx end next time-step xxxxxxxxxxxxxxxxxxxxxxxxxxxxx*/
	   nhd[n]=u;  /*keep track of nhood that was looked up*/
	   /*count nhood look up frequency*/
	   if (eg.showlookupfreq && (stp || ae.show_edata)){
	       if (set_iso_input_histogram==1){ /*/*input entropy according to iso-table*/
	          if (single_entropy==0) eg.lookupcount[0][group_list_iso[u]]+=1;
	          else{
		     if (n==entropy_poss) eg.lookupcount[0][group_list_iso[u]]+=1;
	          }
	       }
	       else{
		  if (single_entropy==0) eg.lookupcount[0][u]+=1;
	          else{
		     if (n==entropy_poss) eg.lookupcount[0][u]+=1;
	          }
               }		  
	   }
        
	   /*create it.diffgap cell gap*/
	   if (lineL>1 &&  ((lineL-n)%(lineL/2)==0) &&
		     diff_plot && stp && d_mode==1 && n<lineL && n>0){
	       setfillstyle(SOLID_FILL,black);
	       bar(getx,gety-it.fscale,getx+it.fscale*it.diffgap,gety);
	       moveto(getx+it.fscale*it.diffgap,gety);
	   }

           if (stp && (d_mode==2 || d_mode==3)){      
	      if ((lineL-poss)%i2d==0){
		 if (d_mode==2){
		    even_row=abs(even_row-1);
                    if (twod && it.slant_even_k==1 && it.fscale>=3){
                        if (even_row==1) moveto( (float)it.fscale/2,
                             gety+(double)it.fscale * cos(PI/6));
			 else moveto(0,gety+(double)it.fscale * cos(PI/6));
                    }
                    else moveto(0,gety+it.fscale);
		 }
		 else if (d_mode==3){
		    step=0;
		    it.strip+=1;
		    it.polyx=sin(PI/4)*it.strip*it.fscale;
		 }
	      }
	      else if (diff_plot && d_mode==2 && (lineL-poss)%(i2d/2)==0)
		  moveto(getx+it.fscale*it.diffgap,gety);
	   }
           
	   else if (stp && d_mode==4){
	      if (poss%i3d==0){
		 step=0;
		 it.strip+=1;
		 it.polyx=sin(PI/4)*it.strip*it.fscale;
	      }
	      if (poss>0 && poss%(i3d*j3d)==0){
		  /*if (it.slice_3d==1){ // ??? to show sucessive slices in 3d
#                    if __UNIX__
			//show the pixmap on the screen
                        sprintf(textb[9],"%s","offscreen_pixmap"); 
			putimage(0,0,it.offscreen_pixmap,COPY_PUT,textb[9]);
#                    endif
		  }*/
		  it.strip=0;
		  it.downy+=1;
		  it.polyx=0;
		  it.polyy=it.aa+it.downy*it.fscale;
	      }
	   }
	   /*for sequential updating only*/
	   if (it.temp_seq_update>0){ 
               if (value_range==2){
                   set_bit(state1,n,get_bit(state2,n));
               }
               else set_value(state1,n,get_value(state2,n));
           }
     } /*for (poss=L; poss!=Maxu; poss--){ **** next poss (cell)*******/

    /*random re-wiring, re-randomize wiring on each iteration, for check to oscillating networks*/    
    if (!loc_twod_fonly && wiring_madelocal==0 && nonlocal==1 
                                     && rnd_rewiring_each_timestep==1){ 
       unsigned int zr;
       signed int wire,thiswiring;
       signed int ii,jj,hh;
        //fprintf(stderr," %d",zonesize);
        for (zr=0;zr<=lineL-1;zr++){
	    for (wire=nhoodm[zr]-1;wire>=0;wire--){
              randomly_wire_cell(zr,lineL-1); //randomly rewire according to all prev settings              
	    }	    
	}
     }	    

     if (it.skip_timesteps==1){
            if (it.ittcount%(time_skip+1)==0) stp=1;
            else stp=0;
     }

     if (forwards_only==1 && graph_layout==1){
        if (it.skip_timesteps==1 &&  stp==0){
             goto skip_ts;
        }
        tempx=getx;
        tempy=gety;
        setviewport(0,0,Maxx,Maxy,0);
        if (threed && nowscrolling==0) draw_box(-1,X1+1,Y1+1,
	                 Maxx-vgax(130)-4-it.fscale,Y2-1,0,0);
        tempcolor=getcolor();
        for (zu=lineL-1;zu!=Maxu;zu--){
              if (threed && (get_value(state1,zu)==0 || /* skip */
                   color_v[get_value(state1,zu)]==color_v[0])); /*for singleton 3d ??*/
              else{  /*if stp is turned off, graph still runs*/
                 if (stp) setfillstyle(SOLID_FILL,stp_cell_color[zu]);
                 else setfillstyle(SOLID_FILL,color_v[get_value(state1,zu)]);
                 if (it.node_outline==0) 
                        setcolor(fillcolor); /*suppress node outline*/
                 else setcolor(darkgray);
                 if (stp_graph_node_size[1]<=1) putpixel(stp_graph_layout[zu+1][0],
                       stp_graph_layout[zu+1][1],fillcolor);
                 else pieslice(it.node_outline,stp_graph_layout[zu+1][0],
                       stp_graph_layout[zu+1][1],0,360,
                              (signed int)stp_graph_node_size[1]);
              }
	}       
        setcolor(tempcolor);
        moveto(tempx,tempy);       
        /*setviewport(0,0,Maxx,Maxy,0);*/ 
        skip_ts:;
     }

     /*show_edata, for showing/creating automatic (entropy) rule sample*/
     if (stp || ae.show_edata){
	   if (direction=='f'){
	      tempx=getx;
	      tempy=gety;
	      if (it.frozen_islands==3){
		 signed int tempxf,tempyf,tempcolorf;

		 tempxf=getx;
		 tempyf=gety;
		 tempcolorf=getcolor();

		 setcolor(lightred);
		 moveto(Maxx-vgax(200)+CWidth*9,CHeight*2.6);
		 setfillstyle(SOLID_FILL,black);
		      bar(getx,gety,Maxx-3,gety+CHeight);
		 if (value_range==2)
		    sprintf(textb[0],"1s=%.1f, 0s=%.1f, total=%.1f",
                       (float)(sk.frozen_1s*100)/lineL,
		          (float)(sk.frozen_0s*100)/lineL,                        
			    (float)((sk.frozen_0s+sk.frozen_1s)*100)/lineL);
                 else
		    sprintf(textb[0],"%ds=%.1f %d-0s=%.1f total=%.1f",
		       value_range-1,
                       (float)(sk.frozen_1s*100)/lineL,
                          value_range-2,
		          (float)(sk.frozen_0s*100)/lineL,                        
			    (float)((sk.frozen_0s+sk.frozen_1s)*100)/lineL);

		 outtext(textb[0]);
		 setcolor(tempcolorf);
		 moveto(tempxf,tempyf);
	      }
              if (!(d_mode==2 && scrolling==1)){
	         entropy_eeg_plot(&ae,&eg,&it,nhdcolor);
	         //if (show_ss_matrixF==1) show_statespace_matrix(state1);
	      }
	      moveto(tempx,tempy);
	   }
	   if (eg.showlookupfreq==2){ /*for the lookup-histogram+time*/
	     if (eg.thisxbox+eg.xboxmax+2-(eg.startxbox-3)>=Maxx
	       || eg.thisybox+eg.yboxmax+1-(eg.startybox-2)>=Maxy){
               is[0]='q'; //to pause with top-right interrupt on reaching screen edges
               it.screenend=2;
             }
	   }

	   /***************** draw pattern *****************/
           if (stp){
	    if (d_mode==1){
	       /*one-d, either start from the top or scroll*/
	       if (scrolling==0 ){
#                 if __UNIX__
		        /*show the pixmap on the screen*/
		        copy_part_image(it.offscreen_pixmap,&W,
                                        0,gety-it.fscale,
                                        0,gety-it.fscale,
                                        pixmap_width,it.fscale);
#                 endif
		  moveto(0,gety+it.fscale);
                  /*fprintf(stderr,"pixmap_width=%d\n",pixmap_width);
                  input_string(1,0);*/
		  if (Maxy-gety<it.fscale) it.screenend=1;
	       }
               else{ /*if scrolling 1d*/               
#                 if __UNIX__
		     *current_draw=*it.offscreen_pixmap;
		     end_page(it.fscale,0);
		     *current_draw=W;
#                 elif __WATCOM__
		     end_page(it.fscale,0);
#                 endif
	       }
	   }
           
	   /********* two-d, no scrolling********/
	   else if (scrolling==0 && d_mode==2){
#             if __UNIX__
		 /*show the pixmap on the screen*/
                 sprintf(textb[9],"%s","it.offscreen_pixmap"); 
                 putimage(0,0,it.offscreen_pixmap,COPY_PUT,textb[9]);
                 /*offset top left corner*/
	         /*putimage(1,1,it.offscreen_pixmap,COPY_PUT,textb[9]);*/ 
		 /*draw frame*/
		 /*first rectangle gets erased in xwindows??*/
		 /*if (it.ittcount==1) draw_2d_frame(&eg,&it);*/
                 draw_2d_frame(&eg,&it);
#             endif
	   }

	   /********* two-d and scrolling -- diagonal axo ********/
           else if (scrolling==1 && d_mode==2){
                   tempx=getx;
                   tempy=gety;
                   scroll_x=it.downy*it.fscale + i2d*it.fscale;
		   if (it.slant_even_k==1 && it.fscale>2) 
                            scroll_y=it.downy*it.fscale + it.rect_h;
                   else scroll_y=it.downy*it.fscale + j2d*it.fscale;
                   moveto(scroll_x,scroll_y);
                   end_page(it.fscale,it.keyindex);/*scroll 2d*/
                   moveto(tempx,tempy);
           }

           /***** frame for 2-d drawn as 3-d projection *****/
	   else if (d_mode==3){
	       it.strip=0;
	       if (nowscrolling==0  && 
                    gety<=Maxy-it.fscale) it.downy+=1;
	       it.polyx=0;
	       /*erase outline*/
               if (nowscrolling==0){
	          if (it.downy>2){
		     setcolor(black);
		     line(it.polyx,it.polyy,it.polyx+it.wx,it.polyy);
		     line(it.polyx+it.wx,it.polyy,
		       it.polyx+it.wx+it.aa,it.polyy-it.aa);
                  
		     if (it.fscale<2 && it.downy%2==0){
		        putpixel(it.polyx,it.polyy,white);
		        putpixel(it.polyx+it.wx,it.polyy,white);
		        putpixel(it.polyx+it.wx+it.aa,it.polyy-it.aa,white);
		     }
	          }
	          it.polyy=sin(PI/4)*(j2d-1+it.downy)*it.fscale;
	          moveto(it.polyx,it.polyy);
	          /*draw outline*/
	          setcolor(white);	       
                  line(it.polyx,it.polyy,it.polyx+it.wx,it.polyy); /*1-2*/
	          line(it.polyx+it.wx,it.polyy,
		    it.polyx+it.wx+it.aa,it.polyy-it.aa);       /*2-4*/
	       }
               if (scrolling==1) end_page(it.fscale,0);/*scroll 2d*/
               else{ 
	          if (Maxy-it.polyy<it.fscale){
			it.polyy=sin(PI/4)*(j2d-1)*it.fscale;
			it.downy=0;
			it.screenend=1;
	          }
               }
	   }
           /***** frame 3d move down to next slice  *****/
           else if (d_mode==4){
              it.strip=0;
              it.downy=1;
              step=0;  
	      it.polyx=0;
              it.aa=it.axo_cell_h*j3d;
              it.polyy=it.aa+it.fscale;                               
           }
           /********* for eeg, entropy plot in 2d and 3d ********/
	   if (d_mode>1){          
	      moveto(0,0);
              if (stpgraph){
		 eg.twodgy+=1;
		 if (eg.twodgy>Maxy){
		     draw_stpframe(eg.stpwidth,eg.lookupfreqwidth);
		     eg.twodgy=0;
		 }
	      }
	   }
	  } /*end:  if (stp)*/           
     } /*end: if (stp || ae.show_edata)*/

     //if (it.ittcount==1) input_string(1,0); //pause after upsate, for example with "/" or "\"

     if (stpgraph==1 && eg.showeeg==1 && it.time_step_density_plot){
      /* * * * * * show density return-map...x=t, y=t-1 * * *  * * * */
      signed short tempdx,tempdy; 
      char timestep,den_color,tempdcolor;
      float sum_density=0; //should add up to 1

       tempdx=getx;
       tempdy=gety;
       for (timestep=0; timestep<=2; timestep++){ 
          for (z=0; z<value_range; z++) it.den_state[timestep][z]=0;
       }
       for (timestep=0; timestep<=2; timestep++){ /*remember density of last 3 time-steps*/ 
          for (z=0; z<value_range; z++){
             for (zu=0; zu<=lineL-1; zu++){
	        if (get_value(it.last_state1[timestep],zu)==z) 
                              it.den_state[timestep][z] +=1;
             }
             //fprintf(stderr,"%f ",den_state[timestep][z]);
	  }
       }

       for (z=0; z<value_range; z++){
	   /*if (value_range==2 && z==0) continue;*/  //for binary dont't plot zero density
	   if (z==0) den_color=darkgray;
	   else den_color=color_v[z];
           moveto(eg.stpwidth+vgax(100)+2+vgax(10)+ (it.den_state[0][z]/lineL) *vgax(200),
			    Maxy-2-vgax(10)-(it.den_state[1][z]/lineL) *vgay(200));
	   /* putpixel(eg.stpwidth+vgax(100)+2+vgax(10)+ (it.den_state[0][z]/lineL) *vgax(200),
	      Maxy-2-vgax(10)-(it.den_state[1][z]/lineL) *vgay(200), den_color);*/
           
	   putpixel(getx,gety,den_color);
           if (eg.history_lines_in_plots==1){
             setcolor(den_color);
	     if (it.den_state[1][z]/lineL>0 && it.den_state[2][z]/lineL>0)
                 lineto(eg.stpwidth+vgax(100)+2+vgax(10)+ (it.den_state[1][z]/lineL) *vgax(200),
	              Maxy-2-vgax(10)-(it.den_state[2][z]/lineL) *vgay(200));
           }

           if (it.time_step_density_plot==2){
	      /* * * save density return-map values 0 to v-1 at the current timestep * * */
              sprintf(textb[0],"%f ",it.den_state[0][z]/lineL);              
              /*sum_density+=it.den_state[0][z]/lineL;
		print_out(textb[0]);*/                    
              save_data(textb[0]);    	 
           }
        }
        if (it.time_step_density_plot==2){
	  /*fprintf(stderr," =%f",sum_density);              
	    print_out("\n");*/
           save_data("\n");
        }
        moveto(tempdx,tempdy);
        setcolor(tempdcolor);
     }

#       if __WATCOM__ /*xwindows*/
	   if (makesound==1) {
		nosound();     /*turns speaker off*/
		if (L<8){
		   sound(dec_equiv_sound(state1, L,0));
		   delay(dec_equiv_sound(state1,L,0)/2);
		}
		else{
		   sound(dec_equiv_sound(state1, L,L-8));
		   delay(dec_equiv_sound(state1,8,0)/2);
		}
	   }
#       endif

	if (forwards_only==1){
	   if (!(d_mode==2 && scrolling==1)){

              /*state-space matrix*/
              if (show_ss_matrixF==1) show_statespace_matrix(state1);

              if (it.Hamming_plot==1 && it.ittcount>3){
	         double r_map_state1=0,r_map_state2=0; /*return map*/
                 unsigned int r_count=0;
                  for (zu=lineL-1;zu!=Maxu;zu--){ /*return map*/
                     /*for binary and multi-value*/   
                     r_map_state1+=((get_value(state1,zu)/(value_range-1))
                            * (1.0/(pow(2,r_count))));
                     r_map_state2+=((get_value(state2,zu)/(value_range-1))
                                  * (1.0/(pow(2,r_count))));

                     /*fprintf(stderr,
                           "zu=%d rcount=%d: 1/%lu=%g\n", 
                         zu,r_count,(unsigned long)pow(2,r_count),            
			 1.0/pow(2,r_count) );*/
                     r_count+=1;    
	          }

                  /*fprintf(stderr,"rmap= %g, %g\n", r_map_state1,r_map_state2);
		      fprintf(stderr,"-----------------------\n");*/
                  r_map_state1*=vgax(200)/2;
                  r_map_state2*=vgax(200)/2;
               
                  putpixel(eg.stpwidth+vgax(100)+2+vgax(10)+r_map_state1,
		      Maxy-2-vgax(10)-r_map_state2,eg.ecolor);
	      }
	   }
           
	   /*remember time steps t-2,t-3,...t-10*/
	   for (z=frozen_gens-1;z>=1;z--) 
                     memmove(it.last_state1[z],it.last_state1[z-1],bytesL);
	   /*remember time step t-1*/
	   memmove(it.last_state1[0],state1,bytesL);
	}
        /*updating random_graphs*/ 
        if (exhaustive_testing==2)
	         memmove(state2,exh_pairs+dec_equiv(state1,L)*bytesL,bytesL);
	/*dont do this for sequential updating*/
        /*copy state2 to state1*/
	if (it.temp_seq_update==0){
	   temppoint=state1; 
	   state1=state2;
	   state2=temppoint;
	} 

	seed_was_set=0;

        if (it.itt_step==1){ /*time-step pause*/
	  signed int maxpsteps;  
           tempx=getx;
	   tempy=gety;
           tempchar=is[0];
           setcolor(white);
           maxpsteps=frozen_gens-1;
           if (maxpsteps>it.ittcount) maxpsteps=it.ittcount;
           xbox=draw_prompt_box(3);
	   if (d_mode<3) sprintf(textb[0],             
	           "time-step %lu, next-ret, reset count-r, current: save-s PScript-P" ,
                                           it.ittcount);
	   else sprintf(textb[0],             
	      "time-step %lu, next-ret, reset count-r, current: save-s" ,
                                           it.ittcount);
           outtext(textb[0]);
           moveto(xbox,gety+CHeight);                                     
           sprintf(textb[0], 
              "stepback x time-steps (max=frozen-gens=%d)",maxpsteps);
           outtext(textb[0]);
           moveto(xbox,gety+CHeight);  
           sprintf(textb[0], 
              "on-the-fly/interrupt options -y/i, endpause -q:");
           outtext(textb[0]);
	   input_string(3,0);
           erase_prompt_box(3); 
           if (is[0]==13); /* next step */
           else if (is[0]=='q'){ 
              it.itt_step=0; /*continue run, stp steps*/
              forward_onthefly_bottom_prompts();
           }
           else if  (is[0]=='r') it.ittcount=0;          
           else if (is[0]=='s'){ /*save current time-step*/
               load_save_wrs('s',it.last_state1[0],'s');
               is[0]='s';
           }
           else if (is[0]=='P' && d_mode<3){
              if (forward_only==1){
		 if (d_mode==2) save_to_PostScript(it.last_state1[0],i2d,j2d,-2,
                            0,scale,it.show_2d_divs,it.divcolor,'d',stagger_even_rows,0);
                 else if (d_mode==1) save_to_PostScript(it.last_state1[0],lineL,Maxx/scale,-1,
                            0,scale,it.show_2d_divs,it.divcolor,'d',stagger_even_rows,0);
              }
              is[0]=0;
           }
           /*all the on-the-fly interupt options*/
           else if (is[0]=='y'){
              draw_box(-1,Maxx-vgax(130),2,Maxx-2,2+CHeight+vgay(6),1,0);
              sprintf(textb[0],"enter on-the-fly option:");
              outtext(textb[0]);
              input_string(1,0);
              if (is[0]!=13){ 
                 interrupt_stp(&dp,&ae,&eg,&it);
                 it.hex_rad=(double)it.fscale * cos(PI/6)*2/3;
              }
              is[0]=0;
              erase_box(Maxx-vgax(130),2,Maxx-2,2+CHeight+vgay(6));
           }
   
           /*all the on-the-fly interupt options*/
           else if (is[0]=='i'){
	      scale=it.fscale; 
              sep=it.fsep; /*to print 2d latex picture direct*/
	      if (tot_only==0){
		     if (set_iso_input_histogram==1)
		        resetscreen=interrupt_stp_box(2,iso_rule,it.ittcount,
                               it.last_state1[0],eg.stpwidth,&dp,&ae,&eg,&it);	
		     else resetscreen=interrupt_stp_box(2,thisrule[0],it.ittcount,
                               it.last_state1[0],eg.stpwidth,&dp,&ae,&eg,&it);
	      }  
              else {
		   if (totalistic==1)  resetscreen=
                      interrupt_stp_box(2,cacode[0],it.ittcount,
                                        it.last_state1[0],eg.stpwidth,&dp,&ae,&eg,&it);
                   else if (totalistic==2)  resetscreen=
                      interrupt_stp_box(2,v_code[0],it.ittcount,
                                        it.last_state1[0],eg.stpwidth,&dp,&ae,&eg,&it);
	      }  
	   }

           /*step backwards by x time_steps, max=frozen generations size*/  
	   else if (atoi(is)>=1 && atoi(is)<=maxpsteps){
	     signed int  step_back;
             unsigned long this_ittcount;
	        step_back=atoi(is);
	        memmove (state1,it.last_state1[step_back],bytesL);
                /*remember time steps t-2,t-3,...t-10*/
	        for (z=maxpsteps;z>=step_back+1;z--) 
                     memmove(it.last_state1[z],it.last_state1[z-step_back],bytesL);
	        /*remember time step t-1*/
	        memmove(it.last_state1[0],state1,bytesL);
                this_ittcount=it.ittcount;
	        this_ittcount-=(1+atoi(is));
                it.ittcount-=(1+atoi(is));
                //if (this_ittcount<=0) it.ittcount=0; /*ittcount is unsigned long*/
                if (this_ittcount>Maxlu-1000) it.ittcount=0;
           }
           else if (is[0]!=13) it.itt_step=0;
           is[0]=tempchar;
           moveto(tempx,tempy);
        }
        /* * * * * * * plot difference pattern * * * * * * */  
	if (diff_plot) plot_diff_pattern(&dp,&eg,&it);

        /* * * *  frozen skeleton histogram * * *  * * * */
        if (att_hist==2 && it.ittcount>frozen_gens){
	   if ( (sk.skel_val==2 && sk.frozen_0s+sk.frozen_1s)>0 /*something should be frozen*/
	         || (sk.skel_val==1 && sk.frozen_1s>0) 
		 || (sk.skel_val==0 && sk.frozen_0s>0) /*or*/
                 || memcmp(state1,all_0s,bytesL)==0   /*all 0s*/
                 || memcmp(state1,all_1s,bytesL)==0  )/*all 1s*/              
	      show_frozen_skel_hist(&sk,&dp,&it,eg.stpwidth); 
           
           /*else fprintf(stderr,"\n 1s=%.1f, 0s=%.1f, total=%.1f",
                       (float)(sk.frozen_1s*100)/lineL,
		          (float)(sk.frozen_0s*100)/lineL,                        
			  (float)((sk.frozen_0s+sk.frozen_1s)*100)/lineL);*/
               
        }
	/* * * * * * * check for repeat - divert to draw basin * *  * * * */
	//if (forwards_only==0 || att_hist==1){ this caused problems/segfault for subtrees!
        if ((limitcheck>0 && direction=='f') || att_hist==1){
	  notocheck=it.ittcount-1;
          repeatfound=0;
	  if (notocheck>limitcheck && att_hist!=1) notocheck=limitcheck;
	  for (zu=0;zu<=notocheck;zu++){
	     if (memcmp(rcheck[zu],state1,bytesL)==0){   /*if repeat found*/
	       repeatfound=1;
	       attperiod=it.ittcount-zu;
               /*for attractor basins:
                 prevent seg fault and warn if limitcheck is too small
		 to copy states to attractor --
                 should no longer apply*/
               if (limitcheck>0 && 
                      attperiod > limitcheck - (it.ittcount-attperiod)){
                   xbox=draw_prompt_box(2);
                   sprintf(textb[0],
                      "att period=%lu, run in=%lu",attperiod,it.ittcount);
                   sprintf(textb[1],
                      "history limit=%d (too small), should be >= %lu, cont-ret:",
                                  limitcheck,attperiod+(it.ittcount-attperiod));
                   outtext(textb[0]);
                   moveto(xbox, gety+CHeight);
                   outtext(textb[1]);
                   input_string(1,0);
                   is[0]='q';
                   break;
               }
	       if ((att=(char**) realloc(att,sizeof(char*)*(attperiod+1)))
					    ==NULL) outof_memory("att");
	       for (z=1;z<=attperiod;z++){
		  if ((att[z]=(char *)calloc(bytesL,sizeof(char)))
				     ==NULL) outof_memory("att[]");
	       }
	       if (stp) end_page(it.fscale,0);
	       /*transfer info from history array to attractor array*/
	       for (z=1;z<=attperiod;z++){
		  memmove(att[z],rcheck[zu-1+z],bytesL);
                  
		  if (stp && d_mode==1){
                    char cycle_color,cycle_value; 
		     /*inline code instead of function*/                     
                     /*print attractor cycle*/
                     for(zu1=L;zu1!=Maxu;zu1--){
		       
		        if (value_range==2){
			   cycle_value=get_bit(att[z],zu1);
                           if (cycle_value==0) cycle_color=darkgray;
                           else cycle_color=cyan;
                        }
                        else{                    
                          cycle_value=get_value(att[z],zu1);
                          if (cycle_value==0) cycle_color=darkgray;
		          else cycle_color=color_v[cycle_value];
			}
                        setfillstyle(SOLID_FILL,cycle_color);
                        bar(getx,gety,getx+it.fscale-it.fsep,gety+it.fscale-it.fsep);
                        /*put a dot on zero cell*/
                        if (cycle_value==0 && it.fscale>3) putpixel(getx-1+it.fscale/2,
			                      gety-1+it.fscale/2,green);
                        moverel(it.fscale,0);
                     }
                     end_page(it.fscale,0);
		  }
	       }

	       
               if (att_hist==1){
	        unsigned int zi;
                  /*Feb 2012: print history array - to see the transient*/
		  /*for (zu1=0;zu1<=notocheck;zu1++){
                      fprintf(stderr,"\n%d= ",zu1);
                      for (zi=lineL-1;zi!=Maxu;zi--){
                        fprintf(stderr,"%d",get_value(rcheck[zu1],zi));
                      }
		  }*/

                  if (att_trans==1){
                     /*free last array of transient states*/
                     for (zu1=0;zu1<=sk.this_trans_length;zu1++){  
                        free(sk.trans_states[zu1]);
                     }
                     free(sk.trans_states);

                     sk.this_trans_length=notocheck+1-attperiod; /*include attractor root state in trans list*/
		     /*fprintf(stderr,
              "\ndisclosure %d - attperiod %lu = %lu = this_trans_length %lu",
			notocheck+1,attperiod,
			notocheck+1-attperiod,sk.this_trans_length);*/
                  /*array for current transient states*/
	             if ((sk.trans_states=
                         (char**)calloc(sk.this_trans_length+1,sizeof(char*)))
			      ==NULL) outof_memory("sk.trans_states");
                     for (zu1=0;zu1<=sk.this_trans_length;zu1++){
                        if ((sk.trans_states[zu1]=
                             (char*)calloc(bytesL,sizeof(char)))
	                      ==NULL) outof_memory("sk.trans_states[zu1]");
                        memmove(sk.trans_states[zu1],rcheck[zu1],bytesL);
                    
                        /*fprintf(stderr,"\n%d: ",zu1);
		        for (zi=lineL-1;zi!=Maxu;zi--){
		           fprintf(stderr,"%d",get_value(rcheck[zu1],zi));
		        }
                        fprintf(stderr," -- ",zu1);
		        for (zi=lineL-1;zi!=Maxu;zi--){
		           fprintf(stderr,"%d",
                              get_value(sk.trans_states[zu1],zi));
                        }
                        input_string(1,0);*/
                     }                              
	          }
	       }
               /*free history array*/
	       for (zu1=0;zu1<=notocheck;zu1++) free(rcheck[zu1]);
	       free(rcheck);
               

	       /* * * * * * show attractor type histogram * * * * * */
               if (att_hist==1){
                  show_att_type_hist(&sk,&dp,&it,eg.stpwidth);                  
                  if (scrolling==1) nowscrolling=0;
                  if (stp && d_mode==1) it.screenend=1;

		  /*set random seed*/
		   /*set rnd block with pre-defined density, block can be whole network*/
		  
		  /*set_central_block(0,state1);*/ //central_block
		  /*random_seed(it.color1,100,0);*/  //has fixed density

                  for (zu1=lineL-1;zu1!=Maxu;zu1--){ //fully random
                         if (value_range==2){  
                             set_bit(state1,zu1,(myrand()%100)/50);
                         }
                         else set_value(state1,zu1,myrand()%(value_range));
		  }
		  
		  if ((rcheck=(char**)calloc(1,sizeof(char*)))
			      ==NULL) outof_memory("rcheck");
		  if ((rcheck[0]=(char *)calloc(bytesL,sizeof(char)))
			      ==NULL) outof_memory("rcheck[0]");
		  memmove(rcheck[0],state1,bytesL);/*seed input for repeat check*/
                  /*keep track of seed density to all_0/1s*/
                  if (att_seed_dens==1) memmove(firstseed,state1,bytesL);
		  /*free attractor array*/
		  for (z=1;z<=attperiod;z++) free(att[z]);
		  free(att);
		  /*allocate attractor array*/
		  if ((att=(char**)calloc(1,sizeof(char*)))
			      ==NULL) outof_memory("att");		  
		  it.ittcount=0;		  
		  break;

               }
	       /*draw basin of attraction*/
	       else{
		  free(pnhood);
                  
                  /*don't clear the run-in and attractor stp for single basin or subtree*/
		  /*if (stp && (basinfield || rangeL)){
		     setviewport(0, 0, (L+1)*it.fscale+2, Maxy, 1);
		     clearviewport();
		     setviewport(0, 0, Maxx, Maxy, 1);
		     moveto(0,0);
		     }*/

		  is[0]=0;
                  /*fprintf(stderr,
                         " \n >draw_basin() attperiod=%lu",attperiod);*/
		  draw_basin();
                  
		  attperiod=0;
		  if (stp) end_page(it.fscale,0);
		  goto exitFunc;
	       }
	    }
	  }
	  if (repeatfound==0){
	     if (it.ittcount<=limitcheck || att_hist==1){
		if((rcheck=(char**)
		   realloc(rcheck,sizeof(char*)*(it.ittcount+1)))
				 ==NULL) outof_memory("rcheck");
		sprintf(textb[0],"rcheck[%lu]",it.ittcount);
		if ((rcheck[it.ittcount]=(char *)
		    calloc(bytesL,sizeof(char)))
			    ==NULL) outof_memory(textb[0]);
		memmove(rcheck[it.ittcount],state1,bytesL);

                if (it.ittcount%10000==0){
                   tempx=getx;
	           tempy=gety;
	           draw_prompt_box(1);
	           sprintf (textb[0],
	             "looking for attractor cycle, %lu+ iterations"
                                                      ,it.ittcount);
	           outtext(textb[0]);
                   moveto(tempx,tempy);
                }
	     }
	  }
	}
	/* * end of check for repeat - divert to draw basin  * * * */
	if (direction=='b'){
	   /*start backward after stepforward iterations*/
	   if (stepforward==it.ittcount){    /*print final state*/
	      if (stp){
		 end_page(it.fscale,0);
		 print_current_state(state1,lightgreen);
		 end_page(it.fscale,0);
	      }
	      free(pnhood);
	      is[0]=0;
	      goto exitFunc;
	   }
	}
	/* * * * change space-time parameters on the fly * * * * * */
        if (stp || forwards_only==1){
           for (zul=0;zul<=it.stp_speed;zul++){ /*to slow down -- forwards_only*/
	      if (event_ready()){
	         if (is[0]=='q');
                 else{ 
                    interrupt_stp(&dp,&ae,&eg,&it);
                    it.hex_rad=(double)it.fscale * cos(PI/6)*2/3;
                 }
              }
           }
        }
        /*8 bit output to robot or device*/
        /*if (ex_device==1){ 
          unsigned char outchar=0;
          signed int spacing=4;
          signed int interval=3;
          signed int cellpos;
          
          cellpos=L;
          if (it.ittcount%interval==0){
             fprintf(stderr,"\n");
             for  (z=7; z>=0; z--){
                cellpos-=spacing;     
                if (cellpos<0) break;
	        fprintf(stderr, "%d",get_bit(state1,cellpos));
                outchar+=(unsigned char)get_bit(state1,cellpos)*pow(2,z);
             }
             fprintf(stderr," %d",outchar);
          }
	}*/

        /*to progressivly randomise % wiring at given intervals*/
        /*if (it.ittcount%30==0){               
              is[0]='m';
              interrupt_stp(&dp,&ae,&eg,&it);
              it.ittcount=0; 
        }*/
        
        /*showing a succession of rules for a given no of time-steps from new random seeds
          from the automatic sample -- with gaps in between,
          or just from new random seeds if keep_index==1 global variable*/                              
        if (it.a_index_sample==1){
           if (it.ittcount==it.a_sample_ht){	        	
	       if (scrolling==0){ 
		  if ( (d_mode==1 && gety+it.a_sample_ht*it.fscale+(CHeight/2)>Maxy)
		       || (d_mode==3 && (signed int)it.polyy 
                              + it.a_sample_ht*it.fscale + (CHeight/2) > Maxy) ){ 
                     it.screenend=1;                     
                     if (stppause==1){
		        if (d_mode==3) moveto(2,Maxy-CHeight*1.2);
                        setfillstyle(SOLID_FILL,black);
                        bar(2,gety,2+28*CWidth,gety+CHeight); /*blank out before printing*/
                        setcolor(white); 
                        //sprintf(textb[0]," s=%lu: endpause-* abandon-q cont-ret:",it.statrule_index);
                        sprintf(textb[0]," s=%lu: endpause-e abandon-q cont-ret:",it.statrule_index);
                        outtext(textb[0]);
                        input_string(1,0);
                        //bar(2,gety,2+28*CWidth,gety+CHeight); /*blank out after printing*/

                        if (is[0]=='e') stppause=0;
                     }
                     if (is[0]=='q') it.a_index_sample=0;
	          }                  
               }
               if (scrolling==0 && (d_mode==1 || d_mode==3)) moverel(0,it.fscale*3);
               /*statistical sample, increase or keep rule, and set rnd seed*/
               is[0]='w';
	       interrupt_stp(&dp,&ae,&eg,&it);
            }
	}
        
	if (is[0]=='q' && forwards_only==0){
	   /*interrupt while looking for attractor*/
	   tempcolor=getcolor();
           setcolor(white);
	   tempx=getx;
	   tempy=gety;
	   xbox=draw_prompt_box(2);
	   sprintf (textb[0],
	     "still looking for attractor cycle (%lu iterations) "
                                                      ,it.ittcount);
	   outtext(textb[0]);
	   //moveto(xbox,gety+CHeight);
	   outtext("exit-q, cont-ret:");
           setcolor(tempcolor);
	   input_string(1,0);
	   if (is[0]=='q'){
	      free(pnhood);
	      for (zu=0;zu<=notocheck;zu++)  free(rcheck[zu]);
	      free(rcheck);
	      free(att[0]);
	      free(att);
              if (basinfield && jump_graph) basintypeno-=1;
	      memory_box(1,NULL);
	      goto exitFunc;
	   }
	   moveto(tempx,tempy);
	}
         
	else if (is[0]=='q' || (stppause && it.screenend==1)
                  || (it.ittcount==ittpause && ittpause>0) ){
           
#          if __WATCOM__ /*xwindows*/
	      nosound();
#          endif
	   setcolor(white);
	   tempx=getx;
	   tempy=gety;
           if (tot_only==0){
	      if (!rulemix || it.rule_unmixed){ 
                 if (value_range==2) z_parameter_all(nhoodm[0],0,thisrule[0]);
                 else z_parameter_all_mvalue(nhoodm[0],0,thisrule[0]);
              }
           }
           /*redraw frame*/ 
	   if (d_mode==2){
	     if (nowscrolling==0 && scrolling==0) draw_2d_frame(&eg,&it);
           }
	   if (forwards_only==1){
	     char oldgraph_layout;
              scale=it.fscale;
              sep=it.fsep; /*to print 2d latex picture direct*/
              oldgraph_layout=graph_layout;
	      oldnhood=nhood;
	      /*pause with options window*/             
              if ((is[0]=='q' && stppause==0) ||  stppause==1){
		 if (tot_only==0){
		     if (set_iso_input_histogram==1)
		        resetscreen=interrupt_stp_box(2,iso_rule,it.ittcount,
                               it.last_state1[0],eg.stpwidth,&dp,&ae,&eg,&it);	
		     else resetscreen=interrupt_stp_box(2,thisrule[0],it.ittcount,
                               it.last_state1[0],eg.stpwidth,&dp,&ae,&eg,&it);
		 }    
                 else {
		   if (totalistic==1)  resetscreen=
                      interrupt_stp_box(2,cacode[0],it.ittcount,
                                  it.last_state1[0],eg.stpwidth,&dp,&ae,&eg,&it);
                   else if (totalistic==2)  resetscreen=
                      interrupt_stp_box(2,v_code[0],it.ittcount,
                                     it.last_state1[0],eg.stpwidth,&dp,&ae,&eg,&it);
		 }
                 if (postScript_graph_state){ /*save current state network graph to PostScript*/
                   signed int fid;
                   char *filename_graph_PS,file_ret,greypost=0;
		         greypost=postScript_graph_state-1;
                         /*filename for graph_postScript ascii file*/                  
                         file_ret=select_filename("SAVE","PostScript file","*.ps","my_sgPS");
	                 if (file_ret=='q') goto skipPost;
                         if ((filename_graph_PS=(char *)calloc(13,sizeof(char)))
				   ==NULL) outof_memory("filename_graph_PS");
	                 memmove(filename_graph_PS,filename,13);                  
                         /*delete previous*/
                         fid_PS=myopen(filename_graph_PS,1,0);
                         vret=write(fid_PS, "",0);
                         close(fid_PS);
                         /*start new*/
                         fid_PS=myopen(filename_graph_PS,1,1);
                         if (fid==-1){ 
                            file_error(filename_graph_PS);
                            goto skipPost;
                         }                          
                         prepare_basinPS(2,1); /*write/define postScipt for graph*/
                         tempcolor=getcolor();
                         for (zu=lineL-1;zu!=Maxu;zu--){
                            if (threed && (get_bit(state1,zu)==0 || /* skip */
                               color_v[get_value(state1,zu)]==color_v[0])); /*for singleton 3d*/
                            else{  /*if stp is turned off, graph still runs*/
                               if (stp) setfillstyle(SOLID_FILL,stp_cell_color[zu]);
                               else setfillstyle(SOLID_FILL,color_v[get_value(state1,zu)]);
                           }                           
                           color_ps(greypost,fillcolor);
                           if (stp_graph_node_size[1]<=1) 
                                smallspot_ps(stp_graph_layout[zu+1][0],stp_graph_layout[zu+1][1],1);
                           else{
                              /*filled circle*/
                              circle_fill_ps(stp_graph_layout[zu+1][0],stp_graph_layout[zu+1][1],
                                 (signed int)stp_graph_node_size[1]);
                              if (it.node_outline==1){/*outline*/
                                 color_ps(greypost,darkgray);
                                 circle_ps(stp_graph_layout[zu+1][0],stp_graph_layout[zu+1][1],
                                    (signed int)stp_graph_node_size[1]);
                              }
                           }
                        }   
                        setcolor(tempcolor);
		       skipPost:
                        close(fid);
                        free(filename_graph_PS);
                        postScript_graph_state=0;
                 }
                 
		 if (graph_layout!=oldgraph_layout){
		     if (graph_layout==1){
		       char ok;
                         ok=jump_graph_table(1,NULL,'n'); /*network graph*/
                         if (ok==0) graph_layout=0; /*graph was interrupted*/ 
                         else draw_box(-1,X1,Y1,X2,Y2,1,0);
                     }
                     else if (graph_layout==0) 
                                draw_box(-1,X1,Y1,X2,Y2,0,0); /*delete box*/
                     is[0]=0;
		 }

                 /*dont reset ittcount if making histograms*/
                 if (att_hist || diff_plot) resetscreen=0;

                 if (is[0]=='+'){ /*to pause at each timestep*/
                    it.itt_step=1;
                    is[0]=0;
                 }
                 forward_onthefly_bottom_prompts();                 
              }
              /*pause without options window*/  
              else if (stppause==2){
		 draw_bottom_title(0);        
		 if (draw_hint_box(1,1,"ops-Q cont-ret:",vgax(500))=='Q')
                    stppause=1;
                 forward_onthefly_bottom_prompts();
                 sprintf(textb[0],"scale=%d",it.fscale);
                        draw_hint_box(0,0,textb[0],vgax(500));
              }
              
              /*if rule revised, reset statespace_matrix (if showing)*/
              if (show_ss_matrixF==1 && resetscreen) 
				   show_statespace_matrix(NULL);
              /*if lookup hist being shown as graph,
                dont reset ittcount */
              if (resetscreen==2 && eg.showlookupfreq<2) it.ittcount=0;
              if (resetscreen==1){
                  it.ittcount=0;
                  if (scrolling==1){
                     moveto(0,0);
		     if (nowscrolling==1){
#                       if __WATCOM__
		           freeimage(stpimage);
#                       endif
                        nowscrolling=0;
                     }
                  }                                    
              }
	      if (it.keyindex==1) showkey;
	      if (eg.showlookupfreq){
		 if (is[0]=='4' || is[0]=='k'){
		    for (z=it.tablemax; z>=0; z--) eg.oldbar[z]=0;
		 }
	      }
	      /*if different nhood rule was loaded
		get rid of lookupfreq graph, swap to eeg*/
	      if (nhood!=oldnhood){
		 if (eg.showlookupfreq) {
		    eg.showeeg=1;
		    eg.showlookupfreq=0;
		    stpgraph=1;
		    eg.eegwidth=vgax(100);
		    if (d_mode==1){
		       erase_box(eg.startxbox-3,eg.startybox-2,
                                      eg.xboxmax+2,eg.yboxmax+1);
#                      if __UNIX__
                          *current_draw = *it.offscreen_pixmap; 
#                      endif
                          draw_stpframe(eg.stpwidth,eg.eegwidth);
#                      if __UNIX__
                          *current_draw = W;
#                      endif		
		    }
		    free(eg.oldbar);
		    for (z=0;z<=gens-1;z++) free(eg.lookupcount[z]);
		    free(eg.lookupcount);
                    /*alloc mem to eg.eegcount
                      for each value
                      for each generation*/
                    if ((eg.eegratiobefore=(double *)
                     calloc(value_range,sizeof(double)))
			         ==NULL)  outof_memory("eg.eegratiobefore");
                    if ((eg.eegcount=(unsigned int **)
                     calloc(value_range,sizeof(unsigned int*)))
				   ==NULL)  outof_memory("eg.eegcount");
                    for (zz=0;zz<=value_range-1;zz++){
	               if ((eg.eegcount[zz]=(unsigned int *)
                         calloc(gens,sizeof(unsigned int)))
				   ==NULL)  outof_memory("eg.eegcount[]");
                    }
		 }
	      }
	   }
          
	   if (resetscreen==1) it.screenend=1;
           if (was_changed==1){ /*if rule or wiring was changed*/
	      if (d_mode==3){
		 moveto(it.polyx,it.polyy-1);
                 draw_axon_plane(it.fscale,it.polyy-1,it.draw_3d_grid);
              }
	   }

	   moveto(tempx,tempy);
	   if (is[0]=='q'){
             if (d_mode==3){ /*change 2d+time back to d_mode=2, 
                                        otherwise crash*/
	         d_mode=2;
                 pixmap_width=it.fscale*i2d+1;	  
                 /*restrict width to window*/
                 if (pixmap_width>Maxx || pixmap_width<=0) pixmap_width=Maxx;
#                if __UNIX__ 
                    reallocate_pixmap(0,0,pixmap_width,
				 it.fscale*j2d+1, it.offscreen_pixmap);
#                endif     
                   
#                if __UNIX__
                    *current_draw = W;
                 draw_2d_frame(&eg,&it);
#                endif  
	      }
	      /*free mem previous states*/
              if (forwards_only==1){ /*forwards only*/
                 /*in case this takes time*/
		 inset_prompt_box(0,25,"freeing stuff forA - please wait",'m'); 
	         for (z=frozen_gens-1;z>=0;z--) free(it.last_state1[z]);
	         free(it.last_state1);
	         if (flipmem==1){
                    free(flippos);
	            //if (value_range>2)
		    //now also applies for value_range=1 to allow zero flip June2021
		    free(flipvalue);
                 }
                 if (stpgraph){//free entropy/density
		    free(eg.oldbar);
                    if (tempstp) free(eg.hist_group);
		    for (z=0;z<=gens-1;z++) free(eg.lookupcount[z]);
		    free(eg.lookupcount);

		    for (zz=0;zz<=value_range-1;zz++) free(eg.eegcount[zz]);                   
                    free(eg.eegcount);
                    free(eg.eegratiobefore);

                    for (z=0; z<=2; z++) free(it.den_state[z]);
		    free(it.den_state);
	         }
                 free(ae.edata);
#                if __WATCOM__ /*xwindows*/
		    free(statblock);
#                endif
              }
              if (forwards_only==0){
		 for (z=it.ittcount;z>=0;z--) free(rcheck[z]);
		 free(rcheck);
		 free(att);
	      }
	      free(pnhood);	      
	      if (exhaustive_testing==2 && direction=='f') free(exh_pairs);
	      goto exitFunc;
	   }
	}

        tempcolor1=fillcolor;
        setfillstyle(SOLID_FILL,black);
        /*--------Screen end------------*/
        if (it.screenend==2 && eg.showlookupfreq==2){ /*for the lookup-histogram+time*/
	   //input_string(1,0); not needed because is[0]='q'; line 2222
	   eg.thisxbox=eg.startxbox-1;
	   eg.thisybox=eg.startybox-1;
	   for (z=it.tablemax; z>=0; z--) eg.oldbar[z]=0;              
	   /*bar(0,0,eg.stpwidth,vgay(36));*/
           bar(eg.startxbox,vgay(36),Maxx,Maxy);
           if (it.keyindex==1) showkey;
           it.screenend=0;                   
	}
	else if (it.screenend==1){
	   tempcolor=fillcolor;
           setfillstyle(SOLID_FILL,black);
           if (d_mode==1){
	      if (diff_plot) bar(0, 0,eg.stpwidth+lineL*it.
					               fscale,Maxy);
	      else bar(0, 0,eg.stpwidth,Maxy);
	   }
	   else if (d_mode==2) bar(0, 0,eg.stpwidth,Maxy);
           else if (d_mode==3){
              bar(0, 0,(signed int)(it.polyx+it.fscale*i2d+it.axo_cell_h*j2d),Maxy);
	      it.strip=it.downy=0;
	      it.polyx=0;
	      it.polyy=it.axo_cell_h*j2d;
	   }	   	   
           setfillstyle(SOLID_FILL,tempcolor);

           if (stp){           
#             if __UNIX__ /*clear pixmap*/
	         *current_draw = *it.offscreen_pixmap;
	         setfillstyle(SOLID_FILL,black);
	         bar(0,0,pixmap_width-vgax(5),Maxy);
	         *current_draw = W;
                 sprintf(textb[9],"%s","it.offscreen_pixmap");
	         putimage(0,0,it.offscreen_pixmap,COPY_PUT,textb[9]);
#             endif
	      /*redraw frame to window*/
	      if (d_mode!=3){ /*not for 2d+time*/
	         if (eg.showeeg) draw_stpframe(eg.stpwidth,eg.eegwidth);
	         if (eg.showlookupfreq) draw_stpframe(eg.stpwidth,eg.lookupfreqwidth);
	      }
	      /*redraw frame to pixmap*/
#             if __UNIX__
	         *current_draw = *it.offscreen_pixmap;
	         if (eg.showeeg) draw_stpframe(eg.stpwidth,eg.eegwidth);
	         if (eg.showlookupfreq) draw_stpframe(eg.stpwidth,eg.lookupfreqwidth);
	         *current_draw = W;
#             endif
           }

	   if (tempstp && (eg.showlookupfreq || eg.lookup_entropy)){
	      eg.startxbox=eg.stpwidth+(signed int)eg.lookupfreqwidth+vgax(10);
	      eg.xboxmax=eg.startxbox+(signed int)eg.lookupfreqwidth;
	      if (!(eg.lookup_entropy && eg.barno>64)){
		 if (eg.showlookupfreq!=2)
		    draw_box(-1,eg.startxbox-3,eg.startybox-2,
			  eg.xboxmax+2,eg.yboxmax+1,1,0);
		 for (z=it.tablemax; z>=0; z--) eg.oldbar[z]=0;
	      }
	   }
	   
           moveto(0,0);

	   if (d_mode==3){
	       moveto(it.polyx,it.polyy);
	       draw_axon_plane(it.fscale,gety,it.draw_3d_grid);
	   }

	   it.screenend=0;
	}
        setfillstyle(SOLID_FILL,tempcolor);
	is[0]=0;
   } /******* while loop **********/

 exitFunc:
   if (forwards_only){
       show_multistate_color_key(0); /*delete and free color key*/
       setup_value_colors(0); /*restore default color scheme*/
   }
   /*memory for damage statistical sample*/
   if (diff_plot==3 || diff_plot==4) free(dp.damage_buf); /*statistical sample*/
   if (att_hist){ /*attractor (=1) or skeleton (=2) histogram*/
      /*array of states for each attractor type*/
      
      if (att_hist==1){
	if (dp.att_types>0){
            for (zu=0;zu<=dp.att_types;zu++){                     
               for (zu1=0;zu1<=sk.att_type_period[zu];zu1++)
                             free(m_att[zu][zu1]);         
            } 
            for (zu=0;zu<=dp.att_types;zu++) free(m_att[zu]);
            free(m_att);
            if (att_trans==1){
               for (zu=0;zu<=dp.att_types;zu++){
                 for (zu1=0;zu1<=sk.att_type_trans_length[zu];zu1++){
                     free(m_trans[zu][zu1]);
                 }
	       } 
               for (zu=0;zu<=dp.att_types;zu++){
                  free(m_trans[zu]);
                }
                free(m_trans);
                free(sk.att_type_trans_length);
	    }
	 }
       
         free(sk.att_type_period);
         if (att_seed_dens==1){
            for (z=0;z<=1;z++) free(sk.dens_seed[z]);
            free(sk.dens_seed);
         }         
      }
      
      if (att_trans==1){
         /*array of taransient states for current attractor type*/
         for (zu1=0;zu1<=sk.this_trans_length;zu1++){  
                 free(sk.trans_states[zu1]);
         }
         free(sk.trans_states);
      }
      
      for (zu1=0;zu1<=dp.att_types;zu1++)
	                      free(sk.att_type_state[zu1]);
       
      free(sk.att_type_state);      
      free(sk.att_type_no);      
      free(sk.att_type_avtrans);
      if (att_hist==2){
         free(sk.frozen_buff);
         free(sk.ref_buff);
         free(sk.type_fr0s);
	 free(sk.type_fr1s);
      }      
   }
   freeimage(boximage[16]);
#  if __UNIX__
      freeimage(it.offscreen_pixmap);
      free(it.offscreen_pixmap);
#  endif
   if (forwards_only==1){
      if (it.time_step_density_plot==2) close(fid_data);/*file for density data*/
      stp=tempstp;
      free(freq_colors);
      free(bin_bound);  
      if (twod){
         i2d=it.i2d_b;
         j2d=it.j2d_b;
      } 
      else if (threed){
         i3d=it.i3d_b;
         j3d=it.j3d_b;
         h3d=it.h3d_b;
      }
      /*in case this takes time*/
      xbox=inset_prompt_box(0,25,"freeing stuff forB - please wait",'m'); //!!
      erase_box(xbox,2,Maxx-2,2+CHeight+2); 
      
      for(zu=0;zu<=lineL;zu++) free(stp_graph_layout[zu]);      
      free(stp_graph_layout);
      free(stp_graph_node_size);
      free(stp_cell_color);
      free(net_subset);
   }
}
/*----------------------------------------------------------*/
