/* Demon.c Gary Teachout August 1989 lc -L Demon To compile and link with Lattice 5.0 */ #include #include #include #define DPEN 15 #define BPEN 14 #define SIZEX 160 #define SIZEY 94 #define CMAX 16 #define PLANES 4 #define COLORS 12 struct IntuitionBase *IntuitionBase ; struct GfxBase *GfxBase ; struct IntuiMessage *mes ; struct Screen *screen ; struct Window *window ; struct NewScreen ns = { 0 , 0 , 320 , 200 , PLANES , DPEN , BPEN , 0 , CUSTOMSCREEN , NULL , " DEMON" , NULL , NULL } ; struct NewWindow nw = { 0 , 0 , 320 , 200 , DPEN , BPEN , MENUPICK | MOUSEBUTTONS | RAWKEY , SMART_REFRESH | ACTIVATE | BACKDROP | BORDERLESS , NULL , NULL , NULL , NULL , NULL , 0 , 0 , 0 , 0 , CUSTOMSCREEN } ; struct TextAttr stext = { "topaz.font" , 8 , 0 , 0 } ; UBYTE *cells1 , *cells2 , *old , *new ; UBYTE ctab[ 16 ][ 3 ] = { { 9 , 1 , 0 } , { 12 , 5 , 0 } , { 15 , 0 , 0 } , { 10 , 0 , 8 } , { 8 , 0 , 15 } , { 0 , 0 , 15 } , { 0 , 8 , 5 } , { 0 , 15 , 0 } , { 8 , 8 , 8 } , { 15 , 15 , 0 } , { 15 , 5 , 0 } , { 6 , 2 , 0 } , { 0 , 0 , 0 } , { 0 , 0 , 0 } , { 0 , 0 , 0 } , { 14 , 14 , 14 } } ; char *AllocMem() ; struct Screen *OpenScreen() ; struct Window *OpenWindow() ; struct IntuiMessage *GetMsg() ; void cleanup( void ) ; void stepauto( void ) ; void display( void ) ; UBYTE random( void ) ; void scramble( void ) ; void main() { short i ; 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() ; for ( i = 0 ; i < 16 ; i ++ ) SetRGB4( &screen->ViewPort , i , ctab[ i ][ 0 ] , ctab[ i ][ 1 ] , ctab[ i ][ 2 ] ) ; 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 , "Cyclic Space Automaton" , 22 ) ; Move( window->RPort , 60 , 102 ) ; Text( window->RPort , "by Gary Teachout" , 17 ) ; Move( window->RPort , 60 , 130 ) ; Text( window->RPort , "Press any key to exit" , 21 ) ; cells1 = AllocMem( 2 * SIZEX * SIZEY , MEMF_FAST ) ; if ( ! cells1 ) cleanup() ; cells2 = cells1 + ( SIZEX * SIZEY ) ; ShowTitle( screen , TRUE ) ; old = cells1 ; new = cells2 ; scramble() ; display() ; old = cells2 ; new = cells1 ; for ( ; ; ) { stepauto() ; if ( mes = GetMsg( window->UserPort ) ) { ReplyMsg( mes ) ; break ; } display() ; if ( old == cells2 ) { old = cells1 ; new = cells2 ; } else { old = cells2 ; new = cells1 ; } if ( mes = GetMsg( window->UserPort ) ) { ReplyMsg( mes ) ; break ; } } 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 t , *oc , *n , *yp , *ym , *xp , *xm , *yy ; 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 ; t = ( *oc + 1 ) % COLORS ; if ( ( *yp == t ) || ( *ym == t ) || ( *( yy + SIZEX - 1 ) == t ) || ( *xp == t ) ) *( n ++ ) = t ; else *( n ++ ) = *oc ; yp ++ ; ym ++ ; xp ++ ; xm = yy ; oc ++ ; for ( x = 2 ; x < SIZEX ; x ++ ) { t = ( *oc + 1 ) % COLORS ; if ( ( *yp == t ) || ( *ym == t ) || ( *xm == t ) || ( *xp == t ) ) *( n ++ ) = t ; else *( n ++ ) = *oc ; yp ++ ; ym ++ ; xp ++ ; xm ++ ; oc ++ ; } xp = yy ; t = ( *oc + 1 ) % COLORS ; if ( ( *yp == t ) || ( *ym == t ) || ( *xm == t ) || ( *xp == t ) ) *( n ++ ) = t ; else *( n ++ ) = *oc ; yy += SIZEX ; oc ++ ; } } void display() { USHORT x , y , d , i , j , k , m , *wp[ PLANES ] , *wpc[ PLANES ] ; UBYTE cm , *c ; i = screen->BitMap.BytesPerRow >> 1 ; wp[ 0 ] = ( USHORT * ) screen->BitMap.Planes[ 0 ] + ( 12 * i ) ; wp[ 1 ] = ( USHORT * ) screen->BitMap.Planes[ 1 ] + ( 12 * i ) ; wp[ 2 ] = ( USHORT * ) screen->BitMap.Planes[ 2 ] + ( 12 * i ) ; wp[ 3 ] = ( USHORT * ) screen->BitMap.Planes[ 3 ] + ( 12 * i ) ; wpc[ 0 ] = ( USHORT * ) screen->BitMap.Planes[ 0 ] + ( 13 * i ) ; wpc[ 1 ] = ( USHORT * ) screen->BitMap.Planes[ 1 ] + ( 13 * i ) ; wpc[ 2 ] = ( USHORT * ) screen->BitMap.Planes[ 2 ] + ( 13 * i ) ; wpc[ 3 ] = ( USHORT * ) screen->BitMap.Planes[ 3 ] + ( 13 * i ) ; c = new ; for ( y = 0 ; y < SIZEY ; y ++ ) { for ( x = 0 ; x < SIZEX ; x += 8 ) { for ( cm = 1 , j = 0 ; j < PLANES ; j ++ , cm = cm << 1 ) { d = 0 ; for ( m = 0xc000 , k = 0 ; k < 8 ; m = m >> 2 , k ++ ) { if ( *( c + k ) & cm ) d |= m ; } *wp[ j ] = d ; wp[ j ] ++ ; *wpc[ j ] = d ; wpc[ j ] ++ ; } c += 8 ; } wp[ 0 ] += i ; wp[ 1 ] += i ; wp[ 2 ] += i ; wp[ 3 ] += i ; wpc[ 0 ] += i ; wpc[ 1 ] += i ; wpc[ 2 ] += i ; wpc[ 3 ] += i ; } } UBYTE random() { #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 ) ( ( COLORS * rr ) / RANDCOMP ) ; } void scramble() { short x , y ; for ( y = 0 ; y < SIZEY ; y ++ ) { for ( x = 0 ; x < SIZEX ; x ++ ) { *( new + x + ( y * SIZEX ) ) = random() ; } } }