home *** CD-ROM | disk | FTP | other *** search
/ The Fred Fish Collection 1.5 / ffcollection-1-5-1992-11.iso / ff_disks / 200-299 / ff249.lzh / Automata / Crud.c < prev    next >
C/C++ Source or Header  |  1989-09-14  |  23KB  |  854 lines

  1. /*
  2.       crud.c        Gary Teachout      August  1989
  3.  
  4.       lc -L Crud    To compile and link with Lattice 5.0
  5. */
  6.  
  7.  #include <exec/types.h>
  8.  #include <exec/memory.h>
  9.  #include <intuition/intuition.h>
  10.  
  11.  #define FPEN        7
  12.  #define DPEN        7
  13.  #define BPEN        0
  14.  #define SIZEX       160
  15.  #define SIZEY       94
  16.  #define CMAX        8
  17.  #define PLANES      3
  18.  #define COLORS      4
  19.  
  20.  #define RULESIZE    ( 7 * 9 ) + 1
  21.  #define SEEDMAX     50
  22.  #define SEEDOFF     ( 60 * SIZEX ) + 70
  23.  
  24.  struct menubox
  25.  {
  26.    struct MenuItem      item  ;
  27.    struct IntuiText     text  ;
  28.  }  ;
  29.  
  30.  struct IntuitionBase      *IntuitionBase  ;
  31.  struct GfxBase            *GfxBase  ;
  32.  
  33.  struct IntuiMessage       *mes  ;
  34.  struct Screen             *screen  ;
  35.  struct Window             *window  ;
  36.  
  37.  ULONG   class  ;
  38.  USHORT  code  ;
  39.  
  40.  struct  NewScreen   ns =
  41.  {
  42.    0 , 0 , 320 , 200 , PLANES , DPEN , BPEN , 0 ,
  43.    CUSTOMSCREEN , NULL , "  Creeping Crud" , NULL , NULL
  44.  }  ;
  45.  
  46.  struct  NewWindow
  47.    nw =
  48.    {
  49.       0 , 0 , 320 , 200 , DPEN , BPEN ,
  50.       MENUPICK | MENUVERIFY ,
  51.       SMART_REFRESH | ACTIVATE | BACKDROP | BORDERLESS ,
  52.       NULL , NULL , NULL , 
  53.       NULL , NULL , 0 , 0 , 0 , 0 , CUSTOMSCREEN
  54.    } ,
  55.    rnw =                /* for string request window */
  56.    {
  57.       0 , 30 , 320 , 38 , DPEN , 3 ,
  58.       GADGETUP ,
  59.       SMART_REFRESH | ACTIVATE | WINDOWDRAG ,
  60.       NULL , NULL , NULL , 
  61.       NULL , NULL , 0 , 0 , 0 , 0 , CUSTOMSCREEN
  62.    }  ;
  63.  
  64. /* string request gadgets and stuff */
  65.  struct Gadget    rgadget[ 3 ] =
  66.  {
  67.    {  NULL , 4 , 13 , 312 , 8 ,
  68.       GADGHCOMP , TOGGLESELECT | RELVERIFY | STRINGCENTER , STRGADGET , 
  69.       NULL , NULL , NULL , 0 , NULL , 1 , NULL } ,
  70.    {  NULL , 8 , 25 , 100 , 10 ,
  71.       GADGHCOMP , RELVERIFY , BOOLGADGET , 
  72.       NULL , NULL , NULL , 0 , NULL , 2 , NULL } ,
  73.    {  NULL , 212 , 25 , 100 , 10 ,
  74.       GADGHCOMP , RELVERIFY , BOOLGADGET , 
  75.       NULL , NULL , NULL , 0 , NULL , 3 , NULL }
  76.  }  ;
  77.  
  78.  struct StringInfo   reqinfo  ;
  79.  
  80.  UBYTE   buff[ RULESIZE + 1 ] ,
  81.          ubuff[ RULESIZE + 1 ]  ;
  82.  
  83.  struct Border    borders[ 3 ] =
  84.  {
  85.    {  -2 , -2 , 4 , 0 , JAM1 , 5 } ,
  86.    {  -1 , -1 , 2 , 0 , JAM1 , 5 } ,
  87.    {  -1 , -1 , 1 , 0 , JAM1 , 5 } ,
  88.  }  ;
  89.  
  90.  short   xyborders[ 2 ][ 10 ] =
  91.  {
  92.    {  0 , 0 , 315 , 0 , 315 , 11 , 0 , 11 , 0 , 0  } ,
  93.    {  0 , 0 , 101 , 0 , 101 , 11 , 0 , 11 , 0 , 0  }
  94.  } ;
  95.  
  96.  struct IntuiText    gtext[ 2 ] =
  97.  {
  98.    {  FPEN , BPEN , JAM1 , 42 , 2 , NULL , "OK" , NULL  } ,
  99.    {  FPEN , BPEN , JAM1 , 26 , 2 , NULL , "CANCEL" , NULL  }
  100.  }  ;
  101.  
  102. /* display window menus */
  103.  struct Menu      menulist[ 1 ] =
  104.  {
  105.    {  NULL , 1   , 0 , 90 , 8  , MENUENABLED , " Control" , NULL }
  106.  }  ;
  107.  
  108.  struct menubox 
  109.    controlmenu[ 6 ] =
  110.    {
  111.       {
  112.          {  NULL , 0 , 0  , 140 , 11 , 
  113.             ITEMTEXT | ITEMENABLED | HIGHCOMP | COMMSEQ ,
  114.             0 , NULL , NULL , 'S' , NULL , NULL } ,
  115.          {  FPEN , BPEN , JAM1 , 10 , 2 , NULL , "Stop" , NULL } 
  116.       } ,
  117.       {
  118.          {  NULL , 0 , 11 , 140 , 11 , 
  119.             ITEMTEXT | ITEMENABLED | HIGHCOMP | COMMSEQ ,
  120.             0 , NULL , NULL , 'C' , NULL , NULL } ,
  121.          {  FPEN , BPEN , JAM1 , 10 , 2 , NULL , "Continue" , NULL } 
  122.       } ,
  123.       {
  124.          {  NULL , 0 , 22 , 140 , 11 , 
  125.             ITEMTEXT | ITEMENABLED | HIGHCOMP ,
  126.             0 , NULL , NULL , 0 , NULL , NULL } ,
  127.          {  FPEN , BPEN , JAM1 , 10 , 2 , NULL , "New Rule" , NULL } 
  128.       } ,
  129.       {
  130.          {  NULL , 0 , 33 , 140 , 11 , 
  131.             ITEMTEXT | ITEMENABLED | HIGHCOMP ,
  132.             0 , NULL , NULL , 0 , NULL , NULL } ,
  133.          {  FPEN , BPEN , JAM1 , 10 , 2 , NULL , "New Seed" , NULL } 
  134.       } ,
  135.       {
  136.          {  NULL , 0 , 44 , 140 , 11 , 
  137.             ITEMTEXT | ITEMENABLED | HIGHCOMP ,
  138.             0 , NULL , NULL , 0 , NULL , NULL } ,
  139.          {  FPEN , BPEN , JAM1 , 10 , 2 , NULL , "Neighborhood" , NULL } 
  140.       } ,
  141.       {
  142.          {  NULL , 0 , 66 , 140 , 11 , 
  143.             ITEMTEXT | ITEMENABLED | HIGHCOMP | COMMSEQ ,
  144.             0 , NULL , NULL , 'Q' , NULL , NULL } ,
  145.          {  FPEN , BPEN , JAM1 , 10 , 2 , NULL , "Quit" , NULL } 
  146.       } 
  147.    } ,
  148.    seedsub[ 5 ] =
  149.    {
  150.       {
  151.          {  NULL , 130 , 0  , 120 , 11 , 
  152.             ITEMTEXT | ITEMENABLED | HIGHCOMP | COMMSEQ ,
  153.             0 , NULL , NULL , '1' , NULL , NULL } ,
  154.          {  FPEN , BPEN , JAM1 , 10 , 2 , NULL , "Small" , NULL } 
  155.       } ,
  156.       {
  157.          {  NULL , 130 , 11 , 120 , 11 , 
  158.             ITEMTEXT | ITEMENABLED | HIGHCOMP | COMMSEQ,
  159.             0 , NULL , NULL , '2' , NULL , NULL } ,
  160.          {  FPEN , BPEN , JAM1 , 10 , 2 , NULL , "Medium" , NULL } 
  161.       } ,
  162.       {
  163.          {  NULL , 130 , 22 , 120 , 11 , 
  164.             ITEMTEXT | ITEMENABLED | HIGHCOMP | COMMSEQ ,
  165.             0 , NULL , NULL , '3' , NULL , NULL } ,
  166.          {  FPEN , BPEN , JAM1 , 10 , 2 , NULL , "Large" , NULL } 
  167.       } ,
  168.       {
  169.          {  NULL , 130 , 33 , 120 , 11 , 
  170.             ITEMTEXT | ITEMENABLED | HIGHCOMP ,
  171.             0 , NULL , NULL , 0 , NULL , NULL } ,
  172.          {  FPEN , BPEN , JAM1 , 10 , 2 , NULL , "Horizontal" , NULL } 
  173.       } ,
  174.       {
  175.          {  NULL , 130 , 44 , 120 , 11 , 
  176.             ITEMTEXT | ITEMENABLED | HIGHCOMP ,
  177.             0 , NULL , NULL , 0 , NULL , NULL } ,
  178.          {  FPEN , BPEN , JAM1 , 10 , 2 , NULL , "Diagonal" , NULL } 
  179.       }
  180.    } ,
  181.    neighborsub[ 2 ] =
  182.    {
  183.       {
  184.          {  NULL , 130 , 0  , 140 , 11 , 
  185.             ITEMTEXT | ITEMENABLED | HIGHCOMP | CHECKIT ,
  186.             0x02 , NULL , NULL , 0 , NULL , NULL } ,
  187.          {  FPEN , BPEN , JAM1 , 25 , 2 , NULL , "Von Neumann" , NULL } 
  188.       } ,
  189.       {
  190.          {  NULL , 130 , 11 , 140 , 11 , 
  191.             ITEMTEXT | ITEMENABLED | HIGHCOMP | CHECKIT | CHECKED ,
  192.             0x01 , NULL , NULL , 0 , NULL , NULL } ,
  193.          {  FPEN , BPEN , JAM1 , 25 , 2 , NULL , "Moore" , NULL } 
  194.       }
  195.    } ,
  196.    rulesub[ 2 ] =
  197.    {
  198.       {
  199.          {  NULL , 130 , 0  , 110 , 11 , 
  200.             ITEMTEXT | ITEMENABLED | HIGHCOMP | COMMSEQ ,
  201.             0 , NULL , NULL , 'R' , NULL , NULL } ,
  202.          {  FPEN , BPEN , JAM1 , 10 , 2 , NULL , "Random" , NULL } 
  203.       } ,
  204.       {
  205.          {  NULL , 130 , 11 , 110 , 11 , 
  206.             ITEMTEXT | ITEMENABLED | HIGHCOMP ,
  207.             0 , NULL , NULL , 0 , NULL , NULL } ,
  208.          {  FPEN , BPEN , JAM1 , 10 , 2 , NULL , "Custom" , NULL } 
  209.       }
  210.    }  ;
  211.  
  212.  struct TextAttr  stext = { "topaz.font" , 8 , 0 , 0 }  ;
  213.  
  214.  UBYTE   *cells1 , *cells2 , *old , *new  ;
  215.  
  216.  UBYTE   ctab[ CMAX ][ 3 ] =     /* screen colors */
  217.  {
  218.    { 0 , 0 , 0 } ,
  219.    { 15 , 0 , 0 } ,
  220.    { 0 , 15 , 0 } ,
  221.    { 0 , 0 , 15 } ,
  222.  
  223.    { 14 , 14 , 0 } ,
  224.    { 14 , 0 , 14 } ,
  225.    { 0 , 14 , 14 } ,
  226.    { 14 , 14 , 14 } 
  227.  }  ;
  228.  
  229.  UBYTE   rule[ RULESIZE ] = 
  230.    {  0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 1 , 1 , 1 , 2 , 2 , 2 ,
  231.       3 , 3 , 3 , 4 , 4 , 4 , 4  }  ;
  232.  
  233.  UBYTE   oldseed[ SEEDMAX + 1 ] = { 1 , 255 }  ;
  234.  
  235.  UBYTE   colors = 4  ;
  236.  
  237.  short   stopflag = 0 , neighborhood = 1 , reseed = 0  ;
  238.  
  239.  char                   *AllocMem()  ;
  240.  struct Screen          *OpenScreen()  ;
  241.  struct Window          *OpenWindow()  ;
  242.  struct IntuiMessage    *GetMsg()  ;
  243.  
  244.  void    cleanup( void )  ;
  245.  void    stepauto( void )  ;
  246.  void    display( void )  ;
  247.  UBYTE   random( UBYTE )  ;
  248.  void    scramble( short )  ;
  249.  short   stringreq( UBYTE * , short )  ;
  250.  void    handlemsg( void )  ;
  251.  void    handlemenu( void )  ;
  252.  void    randrule( void )  ;
  253.  void    stoploop( void )  ;
  254.  
  255.  
  256.  void main()
  257.  {
  258.    short    i  ;
  259.  
  260.    IntuitionBase = ( struct IntuitionBase * )
  261.                    OpenLibrary( "intuition.library" , 33 )  ;
  262.    if ( ! IntuitionBase )
  263.       cleanup()  ;
  264.  
  265.    GfxBase = ( struct GfxBase * )
  266.              OpenLibrary( "graphics.library" , 33 )  ;
  267.    if ( ! GfxBase )
  268.       cleanup()  ;
  269.  
  270.    ns.Font = &stext  ;
  271.    screen = OpenScreen( &ns )  ;
  272.    if ( ! screen )
  273.       cleanup()  ;
  274.  
  275.    for ( i = 0 ; i < CMAX ; i ++ )
  276.       SetRGB4( &screen->ViewPort , i , ctab[ i ][ 0 ] ,
  277.                                        ctab[ i ][ 1 ] ,
  278.                                        ctab[ i ][ 2 ] )  ;
  279.  
  280.    rgadget[ 0 ].NextGadget = &rgadget[ 1 ]  ;
  281.    rgadget[ 1 ].NextGadget = &rgadget[ 2 ]  ;
  282.    rgadget[ 0 ].SpecialInfo = ( APTR ) &reqinfo  ;
  283.    reqinfo.Buffer = buff  ;
  284.    reqinfo.UndoBuffer = ubuff  ;
  285.    rgadget[ 0 ].GadgetRender = ( APTR ) &borders[ 0 ]  ;
  286.    rgadget[ 1 ].GadgetRender = ( APTR ) &borders[ 1 ]  ;
  287.    rgadget[ 2 ].GadgetRender = ( APTR ) &borders[ 2 ]  ;
  288.    borders[ 0 ].XY = &xyborders[ 0 ][ 0 ]  ;
  289.    borders[ 1 ].XY = &xyborders[ 1 ][ 0 ]  ;
  290.    borders[ 2 ].XY = &xyborders[ 1 ][ 0 ]  ;
  291.    rgadget[ 1 ].GadgetText = >ext[ 0 ]  ;
  292.    rgadget[ 2 ].GadgetText = >ext[ 1 ]  ;
  293.    rnw.FirstGadget = &rgadget[ 0 ]  ;
  294.  
  295.  
  296.    nw.Screen = screen  ;
  297.    window = OpenWindow( &nw )  ;
  298.    if ( ! window )
  299.       cleanup()  ;
  300.  
  301.    SetBPen( window->RPort , 0 )  ;
  302.    SetAPen( window->RPort , 15 )  ;
  303.    Move( window->RPort , 60 , 90 )  ;          
  304.    Text( window->RPort , "A Cellular Automation" , 21 )  ;
  305.    Move( window->RPort , 60 , 102 )  ;
  306.    Text( window->RPort , "by  Gary Teachout" , 17 )  ;
  307.  
  308.    cells1 = AllocMem( 2 * SIZEX * SIZEY , MEMF_FAST | MEMF_CLEAR )  ;
  309.    if ( ! cells1 )
  310.       cleanup()  ;
  311.    cells2 = cells1 + ( SIZEX * SIZEY )  ;
  312.  
  313.    menulist[ 0 ].FirstItem = &controlmenu[ 0 ].item  ;
  314.  
  315.    controlmenu[ 0 ].item.ItemFill = ( APTR ) &controlmenu[ 0 ].text  ;
  316.    controlmenu[ 0 ].item.NextItem = &controlmenu[ 1 ].item  ;
  317.    controlmenu[ 1 ].item.ItemFill = ( APTR ) &controlmenu[ 1 ].text  ;
  318.    controlmenu[ 1 ].item.NextItem = &controlmenu[ 2 ].item  ;
  319.    controlmenu[ 2 ].item.ItemFill = ( APTR ) &controlmenu[ 2 ].text  ;
  320.    controlmenu[ 2 ].item.NextItem = &controlmenu[ 3 ].item  ;
  321.    controlmenu[ 3 ].item.ItemFill = ( APTR ) &controlmenu[ 3 ].text  ;
  322.    controlmenu[ 3 ].item.NextItem = &controlmenu[ 4 ].item  ;
  323.    controlmenu[ 4 ].item.ItemFill = ( APTR ) &controlmenu[ 4 ].text  ;
  324.    controlmenu[ 4 ].item.NextItem = &controlmenu[ 5 ].item  ;
  325.    controlmenu[ 5 ].item.ItemFill = ( APTR ) &controlmenu[ 5 ].text  ;
  326.  
  327.    controlmenu[ 4 ].item.SubItem = &neighborsub[ 0 ].item  ;
  328.       neighborsub[ 0 ].item.ItemFill = ( APTR ) &neighborsub[ 0 ].text  ;
  329.       neighborsub[ 0 ].item.NextItem = &neighborsub[ 1 ].item  ;
  330.       neighborsub[ 1 ].item.ItemFill = ( APTR ) &neighborsub[ 1 ].text  ;
  331.  
  332.    controlmenu[ 2 ].item.SubItem = &rulesub[ 0 ].item  ;
  333.       rulesub[ 0 ].item.ItemFill = ( APTR ) &rulesub[ 0 ].text  ;
  334.       rulesub[ 0 ].item.NextItem = &rulesub[ 1 ].item  ;
  335.       rulesub[ 1 ].item.ItemFill = ( APTR ) &rulesub[ 1 ].text  ;
  336.  
  337.    controlmenu[ 3 ].item.SubItem = &seedsub[ 0 ].item  ;
  338.       seedsub[ 0 ].item.ItemFill = ( APTR ) &seedsub[ 0 ].text  ;
  339.       seedsub[ 0 ].item.NextItem = &seedsub[ 1 ].item  ;
  340.       seedsub[ 1 ].item.ItemFill = ( APTR ) &seedsub[ 1 ].text  ;
  341.       seedsub[ 1 ].item.NextItem = &seedsub[ 2 ].item  ;
  342.       seedsub[ 2 ].item.ItemFill = ( APTR ) &seedsub[ 2 ].text  ;
  343.       seedsub[ 2 ].item.NextItem = &seedsub[ 3 ].item  ;
  344.       seedsub[ 3 ].item.ItemFill = ( APTR ) &seedsub[ 3 ].text  ;
  345.       seedsub[ 3 ].item.NextItem = &seedsub[ 4 ].item  ;
  346.       seedsub[ 4 ].item.ItemFill = ( APTR ) &seedsub[ 4 ].text  ;
  347.  
  348.    SetMenuStrip( window , menulist ) ;
  349.  
  350.    ShowTitle( screen , TRUE )  ;
  351.  
  352.    old = cells1  ;
  353.    new = cells2  ;
  354.  
  355.    scramble( 25 )  ;
  356.    display()  ;
  357.  
  358.    old = cells2  ;
  359.    new = cells1  ;
  360.  
  361.    for ( ; ; )
  362.    {
  363.       stepauto()  ;
  364.  
  365.       display()  ;
  366.  
  367.       if ( old == cells2 )
  368.       {
  369.          old = cells1  ;
  370.          new = cells2  ;
  371.       }
  372.       else
  373.       {
  374.          old = cells2  ;
  375.          new = cells1  ;
  376.       }
  377.  
  378.    }
  379.  
  380.    cleanup()  ;
  381.  }
  382.  
  383.  
  384.  void cleanup()  
  385.  {
  386.    if ( cells1 )
  387.       FreeMem( cells1 , 2 * SIZEX * SIZEY )  ;
  388.  
  389.    if ( window )
  390.       CloseWindow( window )  ;
  391.  
  392.    if ( screen )
  393.       CloseScreen( screen )  ;
  394.  
  395.    if ( GfxBase )
  396.       CloseLibrary( GfxBase )  ;
  397.  
  398.    if ( IntuitionBase )
  399.       CloseLibrary( IntuitionBase )  ;
  400.  
  401.    exit()  ;
  402.  }
  403.  
  404.  
  405.  void stepauto()
  406.  {
  407.    short    x , y  ;
  408.    UBYTE    *oc , *n , *yp , *ym , *xp , *xm , *yy ,
  409.                        *mm , *pm , *mp , *pp  ;
  410.  
  411.  
  412.    oc = old  ;
  413.    n = new  ;
  414.    yy = old  ;
  415.  
  416.    if ( neighborhood )
  417.    {
  418.       for ( y = 0 ; y < SIZEY ; y ++ )
  419.       {
  420.          yp = old + ( ( ( y + 1 ) % SIZEY ) * SIZEX )  ;
  421.          ym = old + ( ( ( y + SIZEY - 1 ) % SIZEY ) * SIZEX )  ;
  422.          xp = yy + 1  ;
  423.          xm = yy + SIZEX - 1  ;
  424.  
  425.          mm = ym + SIZEX - 1  ;
  426.          mp = yp + SIZEX - 1  ;
  427.          pm = ym + 1  ;
  428.          pp = yp + 1  ;
  429.  
  430.          *( n ++ ) = rule[    *( oc ++ )
  431.                            +  *yp
  432.                            +  *ym
  433.                            +  *( xp ++ )
  434.                            +  *xm
  435.                            +  *mm 
  436.                            +  *( pm ++ )
  437.                            +  *mp
  438.                            +  *( pp ++ )  ]  ;
  439.  
  440.          mm = ym  ;
  441.          mp = yp  ;
  442.  
  443.          yp ++  ;
  444.          ym ++  ;
  445.          xm = yy  ;
  446.  
  447.          for ( x = 2 ; x < SIZEX ; x ++ )
  448.          {
  449.             *( n ++ ) = rule[    *( oc ++ )
  450.                               +  *( yp ++ )
  451.                               +  *( ym ++ )
  452.                               +  *( xp ++ )
  453.                               +  *( xm ++ )
  454.                               +  *( mm ++ ) 
  455.                               +  *( pm ++ )
  456.                               +  *( mp ++ )
  457.                               +  *( pp ++ )  ]  ;
  458.          }
  459.  
  460.          xp = yy  ;
  461.  
  462.          pm -= SIZEX  ;
  463.          pp -= SIZEX  ;
  464.  
  465.          *( n ++ ) = rule[    *( oc ++ ) + *yp + *ym + *xp + *xm
  466.                            +  *mm + *pm + *mp + *pp  ]  ;
  467.  
  468.          yy += SIZEX  ;
  469.  
  470.          handlemsg()  ;
  471.          if ( reseed )
  472.          {
  473.             reseed = 0  ;
  474.             break  ;
  475.          }
  476.       }
  477.    }
  478.    else
  479.    {
  480.       for ( y = 0 ; y < SIZEY ; y ++ )
  481.       {
  482.          yp = old + ( ( ( y + 1 ) % SIZEY ) * SIZEX )  ;
  483.          ym = old + ( ( ( y + SIZEY - 1 ) % SIZEY ) * SIZEX )  ;
  484.          xp = yy + 1  ;
  485.          xm = yy + SIZEX - 1  ;
  486.  
  487.          *( n ++ ) = rule[    *( oc ++ )
  488.                            +  *( yp ++ )
  489.                            +  *( ym ++ )
  490.                            +  *( xp ++ )
  491.                            +  *xm  ]  ;
  492.  
  493.          xm = yy  ;
  494.  
  495.          for ( x = 2 ; x < SIZEX ; x ++ )
  496.          {
  497.             *( n ++ ) = rule[    *( oc ++ )
  498.                               +  *( yp ++ )
  499.                               +  *( ym ++ )
  500.                               +  *( xp ++ )
  501.                               +  *( xm ++ )  ]  ;
  502.          }
  503.  
  504.          xp = yy  ;
  505.  
  506.          *( n ++ ) = rule[ *( oc ++ ) + *yp + *ym + *xp + *xm ]  ;
  507.  
  508.          yy += SIZEX  ;
  509.  
  510.          handlemsg()  ;
  511.          if ( reseed )
  512.          {
  513.             reseed = 0  ;
  514.             break  ;
  515.          }
  516.       }
  517.    }
  518.  }
  519.  
  520.  
  521.  void display()
  522.  {
  523.    USHORT   x , y , d , i , j , k , m , *wp[ PLANES ] , *wpc[ PLANES ]  ;
  524.    UBYTE    cm , *c ;
  525.  
  526.    do
  527.    {
  528.       reseed = 0  ;
  529.  
  530.       i = screen->BitMap.BytesPerRow >> 1  ;
  531.       wp[ 0 ] = ( USHORT * ) screen->BitMap.Planes[ 0 ] + ( 12 * i ) ;
  532.       wp[ 1 ] = ( USHORT * ) screen->BitMap.Planes[ 1 ] + ( 12 * i ) ;
  533.       wp[ 2 ] = ( USHORT * ) screen->BitMap.Planes[ 2 ] + ( 12 * i ) ;
  534.       wpc[ 0 ] = ( USHORT * ) screen->BitMap.Planes[ 0 ] + ( 13 * i ) ;
  535.       wpc[ 1 ] = ( USHORT * ) screen->BitMap.Planes[ 1 ] + ( 13 * i ) ;
  536.       wpc[ 2 ] = ( USHORT * ) screen->BitMap.Planes[ 2 ] + ( 13 * i ) ;
  537.       c = new  ;
  538.  
  539.       for ( y = 0 ; y < SIZEY ; y ++ )
  540.       {
  541.          for ( x = 0 ; x < SIZEX ; x += 8 )
  542.          {
  543.             for ( cm = 1 , j = 0 ; j < PLANES ; j ++ , cm = cm << 1 )
  544.             {
  545.                d = 0  ;
  546.                for ( m = 0xc000 , k = 0 ; k < 8 ; m = m >> 2 , k ++ )
  547.                {
  548.                   if ( *( c + k ) & cm )
  549.                      d |= m  ;
  550.                }
  551.                *wp[ j ] = d  ;
  552.                wp[ j ] ++  ;
  553.                *wpc[ j ] = d  ;
  554.                wpc[ j ] ++  ;
  555.             }
  556.             c += 8  ;
  557.          }
  558.          wp[ 0 ] += i  ;
  559.          wp[ 1 ] += i  ;
  560.          wp[ 2 ] += i  ;
  561.          wpc[ 0 ] += i  ;
  562.          wpc[ 1 ] += i  ;
  563.          wpc[ 2 ] += i  ;
  564.  
  565.          handlemsg()  ;
  566.          if ( reseed )
  567.             break  ;
  568.       }
  569.    } while ( reseed )  ;
  570.  }
  571.  
  572.  
  573.  UBYTE random( a )
  574.    UBYTE    a  ;
  575.  {
  576.    #define RANDSHIFT      8
  577.    #define RANDTAB        23
  578.    #define RANDCOMP       8388608
  579.    static UBYTE   fp = 1  ;
  580.    static long    v[ RANDTAB ] , rr ;
  581.    short          vi  ;
  582.  
  583.    if ( fp )
  584.    {
  585.       CurrentTime( &v[ 0 ] , &v[ 1 ] )  ;
  586.       srand( v[ 1 ] )  ;
  587.       for ( vi = 0 ; vi < RANDTAB ; vi ++ )
  588.          v[ vi ] = rand() >> RANDSHIFT  ;
  589.       rr = rand() >> RANDSHIFT  ;
  590.       fp = 0  ;
  591.    }
  592.  
  593.    vi = RANDTAB * rr / RANDCOMP  ;
  594.    rr = v[ vi ]  ;
  595.    v[ vi ] = rand() >> RANDSHIFT  ;
  596.  
  597.    return ( UBYTE ) ( ( a * rr ) / RANDCOMP )  ;
  598.  }
  599.  
  600.  
  601.  void scramble( s )
  602.    short    s  ;
  603.  {
  604.    short    x , y  ;
  605.  
  606.    for ( x = 0 ; x < ( SIZEX * SIZEY ) ; x ++ )
  607.       *( new + x ) = 0  ;
  608.  
  609.    for ( y = ( SIZEY - s ) >> 1 ; y < ( ( SIZEY + s ) >> 1 ) ; y ++ )
  610.    {
  611.       for ( x = ( SIZEX - s ) >> 1 ; x < ( ( SIZEX + s ) >> 1 ) ; x ++ )
  612.       {
  613.          *( new + x + ( y * SIZEX ) ) = random( colors )  ;
  614.       }
  615.    }
  616.  }
  617.  
  618.  
  619.  short stringreq( t , l )
  620.    UBYTE    *t  ;
  621.    short    l  ;
  622.  {
  623.    struct Window  *rw  ;
  624.    struct Gadget  *g  ;
  625.    long           sig  ;
  626.  
  627.    rnw.Title = t  ;
  628.    rnw.Screen = screen  ;
  629.    reqinfo.BufferPos = 0  ;
  630.    reqinfo.DispPos = 0  ;
  631.    reqinfo.MaxChars = l  ;
  632.  
  633.    rw = OpenWindow( &rnw )  ; /* a window but it looks like a requester */
  634.    if ( rw )
  635.    {
  636.       sig =       ( 1 << window->UserPort->mp_SigBit )
  637.                |  ( 1 << rw->UserPort->mp_SigBit )   ;
  638.  
  639.       while ( class != GADGETUP )
  640.       {
  641.          Wait( sig )  ;
  642.          while ( mes = GetMsg( window->UserPort ) )
  643.          {
  644.             if ( ( mes->Class == MENUVERIFY ) && ( mes->Code == MENUHOT ) )
  645.                mes->Code = MENUCANCEL  ;
  646.             ReplyMsg( mes )  ;
  647.          }
  648.          while ( mes = GetMsg( rw->UserPort ) )
  649.          {
  650.             class = mes->Class  ;
  651.             g = ( struct Gadget * ) mes->IAddress  ;
  652.             ReplyMsg( mes )  ;
  653.          }
  654.       }
  655.  
  656.       CloseWindow( rw )  ;
  657.  
  658.       if ( g->GadgetID == 3 )
  659.          return 0  ;
  660.       else
  661.          return 1  ;
  662.    }
  663.    else
  664.    {
  665.       DisplayBeep( screen )  ;
  666.       return 0  ;
  667.    }
  668.  }
  669.  
  670.  
  671.  void handlemsg()
  672.  {
  673.    while ( mes = GetMsg( window->UserPort ) )
  674.    {
  675.       class = mes->Class  ;
  676.       code = mes->Code  ;
  677.       ReplyMsg( mes )  ;
  678.       switch ( class )
  679.       {
  680.       case MENUVERIFY :
  681.          Wait( 1 << window->UserPort->mp_SigBit )  ;
  682.          while ( class != MENUPICK )
  683.          {
  684.             if ( mes = GetMsg( window->UserPort ) )
  685.             {
  686.                class = mes->Class  ;
  687.                code = mes->Code  ;
  688.                ReplyMsg( mes )  ;
  689.             }
  690.          }
  691.       case MENUPICK :
  692.          handlemenu()  ;
  693.          break  ;
  694.       }
  695.    }
  696.  }
  697.  
  698.  
  699.  void handlemenu()
  700.  {
  701.    short    i , j  ;
  702.  
  703.    if ( ! MENUNUM( code ) )
  704.    {
  705.       switch ( ITEMNUM( code ) )
  706.       {
  707.       case 0 :
  708.          stoploop()  ;
  709.          break  ;
  710.       case 1 :
  711.          stopflag = 0  ;
  712.          break  ;
  713.       case 2 :
  714.          switch ( SUBNUM( code ) )
  715.          {
  716.          case 0 :
  717.             randrule()  ;
  718.             break  ;
  719.          case 1 :
  720.             for ( i = RULESIZE - 1 ; ( i >= 0 ) && ( ! rule[ i ] ) ; i -- )
  721.                ; 
  722.             for ( j = 0 ; i >= 0 ; i -- , j ++ )
  723.                buff[ j ] = rule[ i ] + 48  ;
  724.             buff[ j ] = 0  ;
  725.             if ( stringreq( "  Enter New Rule  " , RULESIZE + 1 ) )
  726.             {
  727.                for ( i = 0 ; ( i < RULESIZE + 1 ) && ( buff[ i ] ) ; i ++ )
  728.                   ;
  729.                for ( j = 0 , i -- ; i >= 0 ; i -- , j ++ )
  730.                   rule[ j ] = ( buff[ i ] - 48 ) & 7  ;
  731.                for ( ; j < RULESIZE ; j ++ )
  732.                   rule[ j ] = 0  ;
  733.                for ( colors = 0 , i = 0 ; i < RULESIZE ; i ++ )
  734.                   if ( rule[ i ] >= colors )
  735.                      colors = rule[ i ] + 1  ;
  736.             }
  737.             break  ;
  738.          }
  739.          break  ;
  740.       case 3 :
  741.          switch ( SUBNUM( code ) )
  742.          {
  743.          case 0 :
  744.             scramble( 5 )  ;
  745.             reseed = 1  ;
  746.             break  ;
  747.          case 1 :
  748.             scramble( 25 )  ;
  749.             reseed = 1  ;
  750.             break  ;
  751.          case 2 :
  752.             scramble( 80 )  ;
  753.             reseed = 1  ;
  754.             break  ;
  755.          case 3 :
  756.          case 4 :
  757.             for ( i = 0 ; ( i < SEEDMAX + 1 ) && ( oldseed[ i ] != 255 ) ; i ++ )
  758.                buff[ i ] = oldseed[ i ] + 48  ;
  759.             buff[ i ] = 0  ;
  760.             if ( stringreq( "  Enter New Seed  " , SEEDMAX + 1 ) )
  761.             {
  762.                for ( i = 0 ; i < ( SIZEX * SIZEY ) ; i ++ )
  763.                   *( new + i ) = 0  ;
  764.                for ( i = 0 ; ( i < SEEDMAX + 1 ) && buff[ i ] ; i ++ )
  765.                   oldseed[ i ] = ( buff[ i ] - 48 ) & 7  ;
  766.                oldseed[ i ] = 255  ;
  767.                reseed = 1  ;
  768.             }
  769.             else
  770.                break  ;
  771.  
  772.             switch ( SUBNUM( code ) )
  773.             {
  774.             case 3 :
  775.                for (    i = 0 ;
  776.                         ( i < SEEDMAX ) && ( oldseed[ i ] != 255 ) ;
  777.                         i ++ )
  778.                   *( new + i + SEEDOFF ) = oldseed[ i ]  ;
  779.                break  ;
  780.             case 4 :
  781.                for (    i = 0 ;
  782.                         ( i < SEEDMAX ) && ( oldseed[ i ] != 255 ) ;
  783.                         i ++ )
  784.                   *( new + i + SEEDOFF - ( i * SIZEX ) ) = oldseed[ i ]  ;
  785.                break  ;
  786.             }
  787.             break  ;
  788.          }
  789.          break  ;
  790.       case 4 :
  791.          neighborhood = SUBNUM( code )  ;
  792.          break  ;
  793.       case 5 : /* quit */
  794.          cleanup()  ;
  795.          break  ;
  796.       }
  797.    }
  798.  }
  799.  
  800.  
  801.  void randrule()
  802.  {
  803.    short    i , s  ;
  804.    UBYTE    c  ;
  805.  
  806.  
  807.    if ( random( 2 ) )
  808.       c = 2 + random( 6 )  ;          /* 2 - 7  colors */
  809.    else
  810.       c = 3 + random( 3 )  ;          /* 3 - 5  colors */
  811.    do
  812.    {
  813.       s = 2 + random( ( UBYTE ) (   ( c - 1 ) 
  814.                                  *  ( ( neighborhood + 1 ) * 4 + 1 ) ) )  ;
  815.       for ( i = 0 ; i < s ; i ++ )
  816.          rule[ i ] = random( c )  ;
  817.       for ( ; i < RULESIZE ; i ++ )
  818.          rule[ i ] = 0  ;
  819.       if ( random( 4 ) )
  820.       {
  821.          rule[ 0 ] = 0  ;
  822.          if ( random( 4 ) )
  823.          {
  824.             rule[ 1 ] = 0  ;
  825.             if ( random( 4 ) )
  826.             {
  827.                rule[ 2 ] = 0  ;
  828.                if ( random( 4 ) )
  829.                   rule[ 3 ] = 0  ;
  830.             }
  831.          }
  832.       }
  833.       for ( colors = 0 , i = 0 ; i < RULESIZE ; i ++ )
  834.          if ( rule[ i ] >= colors )
  835.             colors = rule[ i ] + 1  ;
  836.    } while ( colors <= 1 )  ;
  837.  }
  838.  
  839.  
  840.  void stoploop()
  841.  {
  842.    if ( ! stopflag )
  843.    {
  844.       stopflag = 1  ;
  845.       while ( stopflag )
  846.       {
  847.          Wait( 1 << window->UserPort->mp_SigBit )  ;
  848.          handlemsg()  ;
  849.       }
  850.    }
  851.  }
  852.  
  853.  
  854.