home *** CD-ROM | disk | FTP | other *** search
- /*
- Life.c Gary Teachout August 1989
-
- lc -L Life To compile and link with Lattice 5.0
- */
-
- #include <exec/types.h>
- #include <exec/memory.h>
- #include <intuition/intuition.h>
-
- #define FPEN 1
- #define DPEN 1
- #define BPEN 0
- #define SIZEX 160
- #define SIZEY 94
- #define PLANES 1
-
- struct menubox
- {
- struct MenuItem item ;
- struct IntuiText text ;
- } ;
-
- struct IntuitionBase *IntuitionBase ;
- struct GfxBase *GfxBase ;
-
- struct IntuiMessage *mes ;
- struct Screen *screen ;
- struct Window *window ;
-
- ULONG class ;
- USHORT code ;
-
- struct NewScreen ns =
- {
- 0 , 0 , 320 , 200 , PLANES , DPEN , BPEN , 0 ,
- CUSTOMSCREEN , NULL , NULL , NULL , NULL
- } ;
-
- UBYTE *title[ 2 ] =
- {
- " Life" ,
- " Edit Seed"
- } ;
-
- struct NewWindow
- nw =
- {
- 0 , 0 , 320 , 200 , DPEN , BPEN ,
- MENUPICK | MENUVERIFY | MOUSEBUTTONS ,
- SMART_REFRESH | ACTIVATE | BACKDROP | BORDERLESS ,
- NULL , NULL , NULL ,
- NULL , NULL , 0 , 0 , 0 , 0 , CUSTOMSCREEN
- } ;
-
- USHORT chip pointer[ 20 ] =
- {
- 0x0000 , 0x0000 ,
- 0x8000 , 0x0000 ,
- 0xc000 , 0x0000 ,
- 0xa000 , 0x0000 ,
- 0x9000 , 0x0000 ,
- 0x8800 , 0x0000 ,
- 0x8400 , 0x0000 ,
- 0x8000 , 0x0000 ,
- 0x0000 , 0x0000 ,
- 0x0000 , 0x0000
- } ;
-
- struct Menu
- menulist[ 2 ] =
- {
- { NULL , 1 , 0 , 90 , 8 , MENUENABLED , " Control" , NULL } ,
- { NULL , 1 , 0 , 90 , 8 , MENUENABLED , " Edit" , NULL }
- } ;
-
- struct menubox
- controlmenu[ 5 ] =
- {
- {
- { NULL , 0 , 0 , 140 , 11 ,
- ITEMTEXT | ITEMENABLED | HIGHCOMP | COMMSEQ ,
- 0 , NULL , NULL , 'S' , NULL , NULL } ,
- { FPEN , BPEN , JAM1 , 10 , 2 , NULL , "Stop" , NULL }
- } ,
- {
- { NULL , 0 , 11 , 140 , 11 ,
- ITEMTEXT | ITEMENABLED | HIGHCOMP | COMMSEQ ,
- 0 , NULL , NULL , 'G' , NULL , NULL } ,
- { FPEN , BPEN , JAM1 , 10 , 2 , NULL , "Go" , NULL }
- } ,
- {
- { NULL , 0 , 22 , 140 , 11 ,
- ITEMTEXT | ITEMENABLED | HIGHCOMP | COMMSEQ ,
- 0 , NULL , NULL , 'C' , NULL , NULL } ,
- { FPEN , BPEN , JAM1 , 10 , 2 , NULL , "Custom Seed" , NULL }
- } ,
- {
- { NULL , 0 , 33 , 140 , 11 ,
- ITEMTEXT | ITEMENABLED | HIGHCOMP ,
- 0 , NULL , NULL , 0 , NULL , NULL } ,
- { FPEN , BPEN , JAM1 , 10 , 2 , NULL , "Random Seed" , NULL }
- } ,
- {
- { NULL , 0 , 50 , 140 , 11 ,
- ITEMTEXT | ITEMENABLED | HIGHCOMP | COMMSEQ ,
- 0 , NULL , NULL , 'Q' , NULL , NULL } ,
- { FPEN , BPEN , JAM1 , 10 , 2 , NULL , "Quit" , NULL }
- }
- } ,
- seedsub[ 3 ] =
- {
- {
- { NULL , 130 , 0 , 120 , 11 ,
- ITEMTEXT | ITEMENABLED | HIGHCOMP | COMMSEQ ,
- 0 , NULL , NULL , '1' , NULL , NULL } ,
- { FPEN , BPEN , JAM1 , 10 , 2 , NULL , "Small" , NULL }
- } ,
- {
- { NULL , 130 , 11 , 120 , 11 ,
- ITEMTEXT | ITEMENABLED | HIGHCOMP | COMMSEQ,
- 0 , NULL , NULL , '2' , NULL , NULL } ,
- { FPEN , BPEN , JAM1 , 10 , 2 , NULL , "Medium" , NULL }
- } ,
- {
- { NULL , 130 , 22 , 120 , 11 ,
- ITEMTEXT | ITEMENABLED | HIGHCOMP | COMMSEQ ,
- 0 , NULL , NULL , '3' , NULL , NULL } ,
- { FPEN , BPEN , JAM1 , 10 , 2 , NULL , "Large" , NULL }
- }
- } ,
- editmenu[ 4 ] =
- {
- {
- { NULL , 0 , 0 , 170 , 11 ,
- ITEMTEXT | ITEMENABLED | HIGHCOMP | COMMSEQ | CHECKIT ,
- 0x02 , NULL , NULL , 'A' , NULL , NULL } ,
- { FPEN , BPEN , JAM1 , 25 , 2 , NULL , "Alive (White)" , NULL }
- } ,
- {
- { NULL , 0 , 11 , 170 , 11 ,
- ITEMTEXT | ITEMENABLED | HIGHCOMP | COMMSEQ | CHECKIT ,
- 0x01 , NULL , NULL , 'D' , NULL , NULL } ,
- { FPEN , BPEN , JAM1 , 25 , 2 , NULL , "Dead (Black)" , NULL }
- } ,
- {
- { NULL , 0 , 22 , 170 , 11 ,
- ITEMTEXT | ITEMENABLED | HIGHCOMP | COMMSEQ ,
- 0 , NULL , NULL , 'B' , NULL , NULL } ,
- { FPEN , BPEN , JAM1 , 25 , 2 , NULL , "Blank Field" , NULL }
- } ,
- {
- { NULL , 0 , 33 , 170 , 11 ,
- ITEMTEXT | ITEMENABLED | HIGHCOMP | COMMSEQ ,
- 0 , NULL , NULL , 'C' , NULL , NULL } ,
- { FPEN , BPEN , JAM1 , 25 , 2 , NULL , "Continue" , NULL }
- }
- } ;
-
- struct TextAttr stext = { "topaz.font" , 8 , 0 , 0 } ;
-
- UBYTE *cells1 , *cells2 , *old , *new ;
-
- short stopflag = 0 , reseed = 0 ;
-
- char *AllocMem() ;
- struct Screen *OpenScreen() ;
- struct Window *OpenWindow() ;
- struct IntuiMessage *GetMsg() ;
-
- void cleanup( void ) ;
- void stepauto( void ) ;
- void display( void ) ;
- UBYTE random( UBYTE ) ;
- void scramble( short ) ;
- short stringreq( UBYTE * , short ) ;
- void handlemsg( void ) ;
- void handlemenu( void ) ;
- void randrule( void ) ;
- void stoploop( void ) ;
- void editmode( void ) ;
-
- void main()
- {
- IntuitionBase = ( struct IntuitionBase * )
- OpenLibrary( "intuition.library" , 33 ) ;
- if ( ! IntuitionBase )
- cleanup() ;
-
- GfxBase = ( struct GfxBase * )
- OpenLibrary( "graphics.library" , 33 ) ;
- if ( ! GfxBase )
- cleanup() ;
-
- ns.Font = &stext ;
- screen = OpenScreen( &ns ) ;
- if ( ! screen )
- cleanup() ;
-
- SetRGB4( &screen->ViewPort , 0 , 0 , 0 , 0 ) ;
- SetRGB4( &screen->ViewPort , 1 , 15 , 15 , 15 ) ;
-
- nw.Screen = screen ;
- window = OpenWindow( &nw ) ;
- if ( ! window )
- cleanup() ;
-
- SetBPen( window->RPort , 0 ) ;
- SetAPen( window->RPort , 15 ) ;
- Move( window->RPort , 60 , 90 ) ;
- Text( window->RPort , "The Game of Life" , 16 ) ;
- Move( window->RPort , 60 , 102 ) ;
- Text( window->RPort , "by Gary Teachout" , 17 ) ;
-
- cells1 = AllocMem( 2 * SIZEX * SIZEY , MEMF_FAST | MEMF_CLEAR ) ;
- if ( ! cells1 )
- cleanup() ;
- cells2 = cells1 + ( SIZEX * SIZEY ) ;
-
- menulist[ 0 ].FirstItem = &controlmenu[ 0 ].item ;
-
- controlmenu[ 0 ].item.ItemFill = ( APTR ) &controlmenu[ 0 ].text ;
- controlmenu[ 0 ].item.NextItem = &controlmenu[ 1 ].item ;
- controlmenu[ 1 ].item.ItemFill = ( APTR ) &controlmenu[ 1 ].text ;
- controlmenu[ 1 ].item.NextItem = &controlmenu[ 2 ].item ;
- controlmenu[ 2 ].item.ItemFill = ( APTR ) &controlmenu[ 2 ].text ;
- controlmenu[ 2 ].item.NextItem = &controlmenu[ 3 ].item ;
- controlmenu[ 3 ].item.ItemFill = ( APTR ) &controlmenu[ 3 ].text ;
- controlmenu[ 3 ].item.NextItem = &controlmenu[ 4 ].item ;
- controlmenu[ 4 ].item.ItemFill = ( APTR ) &controlmenu[ 4 ].text ;
-
- controlmenu[ 3 ].item.SubItem = &seedsub[ 0 ].item ;
- seedsub[ 0 ].item.ItemFill = ( APTR ) &seedsub[ 0 ].text ;
- seedsub[ 0 ].item.NextItem = &seedsub[ 1 ].item ;
- seedsub[ 1 ].item.ItemFill = ( APTR ) &seedsub[ 1 ].text ;
- seedsub[ 1 ].item.NextItem = &seedsub[ 2 ].item ;
- seedsub[ 2 ].item.ItemFill = ( APTR ) &seedsub[ 2 ].text ;
-
- menulist[ 1 ].FirstItem = &editmenu[ 0 ].item ;
-
- editmenu[ 0 ].item.ItemFill = ( APTR ) &editmenu[ 0 ].text ;
- editmenu[ 0 ].item.NextItem = &editmenu[ 1 ].item ;
- editmenu[ 1 ].item.ItemFill = ( APTR ) &editmenu[ 1 ].text ;
- editmenu[ 1 ].item.NextItem = &editmenu[ 2 ].item ;
- editmenu[ 2 ].item.ItemFill = ( APTR ) &editmenu[ 2 ].text ;
- editmenu[ 2 ].item.NextItem = &editmenu[ 3 ].item ;
- editmenu[ 3 ].item.ItemFill = ( APTR ) &editmenu[ 3 ].text ;
-
- SetMenuStrip( window , &menulist[ 0 ] ) ;
- SetWindowTitles( window , NULL , title[ 0 ] ) ;
- ShowTitle( screen , TRUE ) ;
-
- Delay( 100 ) ;
-
- old = cells1 ;
- new = cells2 ;
-
- scramble( 25 ) ;
- display() ;
-
- old = cells2 ;
- new = cells1 ;
-
- for ( ; ; )
- {
- stepauto() ;
-
- display() ;
-
- if ( old == cells2 )
- {
- old = cells1 ;
- new = cells2 ;
- }
- else
- {
- old = cells2 ;
- new = cells1 ;
- }
-
- }
-
- cleanup() ;
- }
-
-
- void cleanup()
- {
- if ( cells1 )
- FreeMem( cells1 , 2 * SIZEX * SIZEY ) ;
-
- if ( window )
- CloseWindow( window ) ;
-
- if ( screen )
- CloseScreen( screen ) ;
-
- if ( GfxBase )
- CloseLibrary( GfxBase ) ;
-
- if ( IntuitionBase )
- CloseLibrary( IntuitionBase ) ;
-
- exit() ;
- }
-
-
- void stepauto()
- {
- short x , y ;
- UBYTE *oc , *n , *yp , *ym , *xp , *xm , *yy ,
- *mm , *pm , *mp , *pp , t ;
-
- oc = old ;
- n = new ;
- yy = old ;
-
- for ( y = 0 ; y < SIZEY ; y ++ )
- {
- yp = old + ( ( ( y + 1 ) % SIZEY ) * SIZEX ) ;
- ym = old + ( ( ( y + SIZEY - 1 ) % SIZEY ) * SIZEX ) ;
- xp = yy + 1 ;
- xm = yy + SIZEX - 1 ;
-
- mm = ym + SIZEX - 1 ;
- mp = yp + SIZEX - 1 ;
- pm = ym + 1 ;
- pp = yp + 1 ;
-
- t = *yp + *ym + *( xp ++ ) + *xm
- + *mm + *( pm ++ ) + *mp + *( pp ++ ) ;
-
- if ( *( oc ++ ) )
- *( n ++ ) = ( ( t == 2 ) || ( t == 3 ) ) ? 1 : 0 ;
- else
- *( n ++ ) = ( t == 3 ) ? 1 : 0 ;
-
- mm = ym ;
- mp = yp ;
- yp ++ ;
- ym ++ ;
- xm = yy ;
-
- for ( x = 2 ; x < SIZEX ; x ++ )
- {
- t = *( yp ++ ) + *( ym ++ ) + *( xp ++ ) + *( xm ++ )
- + *( mm ++ ) + *( pm ++ ) + *( mp ++ ) + *( pp ++ ) ;
-
- if ( *( oc ++ ) )
- *( n ++ ) = ( ( t == 2 ) || ( t == 3 ) ) ? 1 : 0 ;
- else
- *( n ++ ) = ( t == 3 ) ? 1 : 0 ;
- }
-
- xp = yy ;
- pm -= SIZEX ;
- pp -= SIZEX ;
-
- t = *yp + *ym + *xp + *xm + *mm + *pm + *mp + *pp ;
-
- if ( *( oc ++ ) )
- *( n ++ ) = ( ( t == 2 ) || ( t == 3 ) ) ? 1 : 0 ;
- else
- *( n ++ ) = ( t == 3 ) ? 1 : 0 ;
-
- yy += SIZEX ;
- }
- }
-
-
- void display()
- {
- USHORT x , y , d , i , k , m , *wp , *wpc ;
- UBYTE *c ;
-
- do
- {
- reseed = 0 ;
-
- i = screen->BitMap.BytesPerRow >> 1 ;
- wp = ( USHORT * ) screen->BitMap.Planes[ 0 ] + ( 12 * i ) ;
- wpc = ( USHORT * ) screen->BitMap.Planes[ 0 ] + ( 13 * i ) ;
- c = new ;
-
- for ( y = 0 ; y < SIZEY ; y ++ )
- {
- for ( x = 0 ; x < SIZEX ; x += 8 )
- {
- d = 0 ;
- for ( m = 0xc000 , k = 0 ; k < 8 ; m = m >> 2 , k ++ )
- {
- if ( *( c + k ) & 1 )
- d |= m ;
- }
- *wp = d ;
- wp ++ ;
- *wpc = d ;
- wpc ++ ;
- c += 8 ;
- }
- wp += i ;
- wpc += i ;
-
- handlemsg() ;
- if ( reseed )
- break ;
- }
- } while ( reseed ) ;
- }
-
-
- UBYTE random( a )
- UBYTE a ;
- {
- #define RANDSHIFT 8
- #define RANDTAB 23
- #define RANDCOMP 8388608
- static UBYTE fp = 1 ;
- static long v[ RANDTAB ] , rr ;
- short vi ;
-
- if ( fp )
- {
- CurrentTime( &v[ 0 ] , &v[ 1 ] ) ;
- srand( v[ 1 ] ) ;
- for ( vi = 0 ; vi < RANDTAB ; vi ++ )
- v[ vi ] = rand() >> RANDSHIFT ;
- rr = rand() >> RANDSHIFT ;
- fp = 0 ;
- }
-
- vi = RANDTAB * rr / RANDCOMP ;
- rr = v[ vi ] ;
- v[ vi ] = rand() >> RANDSHIFT ;
-
- return ( UBYTE ) ( ( a * rr ) / RANDCOMP ) ;
- }
-
-
- void scramble( s )
- short s ;
- {
- short x , y ;
-
- for ( x = 0 ; x < ( SIZEX * SIZEY ) ; x ++ )
- *( new + x ) = 0 ;
-
- for ( y = ( SIZEY - s ) >> 1 ; y < ( ( SIZEY + s ) >> 1 ) ; y ++ )
- {
- for ( x = ( SIZEX - s ) >> 1 ; x < ( ( SIZEX + s ) >> 1 ) ; x ++ )
- {
- *( new + x + ( y * SIZEX ) ) = random( 2 ) ;
- }
- }
- }
-
-
- void handlemsg()
- {
- while ( mes = GetMsg( window->UserPort ) )
- {
- class = mes->Class ;
- code = mes->Code ;
- ReplyMsg( mes ) ;
- switch ( class )
- {
- case MENUVERIFY :
- Wait( 1 << window->UserPort->mp_SigBit ) ;
- while ( class != MENUPICK )
- {
- if ( mes = GetMsg( window->UserPort ) )
- {
- class = mes->Class ;
- code = mes->Code ;
- ReplyMsg( mes ) ;
- }
- }
- case MENUPICK :
- handlemenu() ;
- break ;
- }
- }
- }
-
-
- void handlemenu()
- {
- if ( ! MENUNUM( code ) )
- {
- switch ( ITEMNUM( code ) )
- {
- case 0 :
- stoploop() ;
- break ;
- case 1 :
- stopflag = 0 ;
- break ;
- case 2 :
- editmode() ;
- break ;
- case 3 :
- switch ( SUBNUM( code ) )
- {
- case 0 :
- scramble( 5 ) ;
- break ;
- case 1 :
- scramble( 25 ) ;
- break ;
- case 2 :
- scramble( 80 ) ;
- break ;
- }
- reseed = 1 ;
- break ;
- case 4 : /* quit */
- cleanup() ;
- break ;
- }
- }
- }
-
-
- void stoploop()
- {
- if ( ! stopflag )
- {
- stopflag = 1 ;
- while ( stopflag )
- {
- Wait( 1 << window->UserPort->mp_SigBit ) ;
- handlemsg() ;
- }
- }
- }
-
-
- void editmode()
- {
- UBYTE live = 1 ;
- short x , y , ox , oy , mx , my ;
-
- SetWindowTitles( window , NULL , title[ 1 ] ) ;
- ClearMenuStrip( window ) ;
- display() ;
- editmenu[ 0 ].item.Flags = editmenu[ 0 ].item.Flags | CHECKED ;
- editmenu[ 1 ].item.Flags = editmenu[ 1 ].item.Flags & ( ~ CHECKED ) ;
- SetMenuStrip( window , &menulist[ 1 ] ) ;
-
- SetPointer( window , pointer , 7 , 7 , -1 , 0 ) ;
-
- stopflag = 0 ;
- reseed = 0 ;
- while( ! reseed )
- {
- Wait( 1 << window->UserPort->mp_SigBit ) ;
- while ( mes = GetMsg( window->UserPort ) )
- {
- class = mes->Class ;
- code = mes->Code ;
- ReplyMsg( mes ) ;
- switch ( class )
- {
- case MENUVERIFY :
- Wait( 1 << window->UserPort->mp_SigBit ) ;
- while ( class != MENUPICK )
- {
- if ( mes = GetMsg( window->UserPort ) )
- {
- class = mes->Class ;
- code = mes->Code ;
- ReplyMsg( mes ) ;
- }
- }
- case MENUPICK :
- switch ( ITEMNUM( code ) )
- {
- case 0 :
- live = 1 ;
- break ;
- case 1 :
- live = 0 ;
- break ;
- case 2 :
- for ( y = 0 ; y < ( SIZEY * SIZEX ) ; y ++ )
- *( new + y ) = 0 ;
- SetRast( window->RPort , 0 ) ;
- break ;
- case 3 :
- reseed = 1 ;
- break ;
- }
- break ;
- case MOUSEBUTTONS :
- if ( code == SELECTDOWN )
- {
- ox = oy = -1 ;
- while ( code != SELECTUP )
- {
- mx = window->MouseX & 0xfffe ;
- my = window->MouseY & 0xfffe ;
- x = mx >> 1 ;
- y = ( my >> 1 ) - 6 ;
- if ( ( ( x != ox ) || ( y != oy ) ) && ( y >= 0 ) )
- {
- *( new + x + ( y * SIZEX ) ) = live ;
- if ( live )
- SetAPen( window->RPort , 1 ) ;
- else
- SetAPen( window->RPort , 0 ) ;
- WritePixel( window->RPort , mx , my ) ;
- WritePixel( window->RPort , mx + 1 , my ) ;
- WritePixel( window->RPort , mx , my + 1 ) ;
- WritePixel( window->RPort , mx + 1 , my + 1 ) ;
- ox = x ;
- oy = y ;
- }
- while ( mes = GetMsg( window->UserPort ) )
- {
- if ( mes->Class == MOUSEBUTTONS )
- code = mes->Code ;
- ReplyMsg( mes ) ;
- }
- }
- }
- break ;
- }
- }
- }
-
- ClearPointer( window ) ;
-
- ClearMenuStrip( window ) ;
- SetMenuStrip( window , &menulist[ 0 ] ) ;
- SetWindowTitles( window , NULL , title[ 0 ] ) ;
- }
-
-
-
-