/* life.c - demonstrator for later Mips+LCD game of life * * 23.03.06 - MACRO-based version * 22.02.06 - new file */ //#include "ks0108.h" #include #include #include #include "libsys.h" #define NX 200 // 70 // 128 // 48 // 128 #define NY 150 // 31 // 64 // 27 // 64 #define SCREEN_X 800 #define SCREEN_Y 600 #define SCALE_X (4) #define SCALE_Y (4) #define OFFSET_X ((SCREEN_X-(SCALE_X*NX))/2) #define OFFSET_Y ((SCREEN_Y-(SCALE_Y*NY))/2) // OCCUPIED must be uneven, EMPTY even. #define OCCUPIED 0x77771111 #define EMPTY 0xeeee0000 #define MATRIX( row, col ) (*(matrix + (NX*col) + row )) #define FUTURE( row, col ) (*(future + (NX*col) + row )) UINT32 *g_gx_buff; int clock_lfsr32() { return rand(); } /* return a pseudo-random integer in the range 0..1023 */ int random1023() { int tmp; tmp = clock_lfsr32(); return tmp & 0x000003ff; } typedef struct _scolor_t { UINT8 r, g, b, a; } __attribute__ ((__packed__)) color_t; void DrawPixel(UINT32 x, UINT32 y, color_t *pColor) { int i, j; for (i=0; i < SCALE_Y; i++) for (j=0; j < SCALE_X; j++) g_gx_buff[(OFFSET_X+SCALE_X*x+j) + SCREEN_X*(OFFSET_Y+SCALE_Y*y+i)] = *((UINT32*)pColor); } /* MSB/LSB in y-Richtung vertauscht */ void displayBoard1( int* matrix ) { int x, y; int mask, accu; UINT32 color; for( x=0; x < NX; x++ ) { mask = 0x80; accu = 0x00; for( y=0; y < NY; y++ ) { color = (UINT32)-(MATRIX(x,y) & 0x1); DrawPixel(x, y, (color_t*)&color); // if (MATRIX( x, y ) != OCCUPIED) // { // accu |= mask; // } // mask = mask >> 1; // color = 0; // DrawPixel(x, (y>>3), (color_t*)&color); // if (mask == 0) // { // color = accu; // DrawPixel(x, (y>>3), (color_t*)&color); // mask = 0x80; // accu = 0x00; // } } // color = accu; // DrawPixel(x, (y>>3), (color_t*)&color); } // *(matrix-15) = 0xdead0000; // *(matrix-16) = *(matrix-16) + 1; } void initializeBoard( int* matrix ) { int x, y; for( x=0; x < NX; x++ ) { for( y=0; y < NY; y++ ) { int d = random1023(); if (d > 920) MATRIX( x, y ) = OCCUPIED; else MATRIX( x, y ) = EMPTY; } } } int countNeighbors( int* matrix, int i, int j ) { int im = i-1; int ip = i+1; int jm = j-1; int jp = j+1; int n = 0; // wrap-around if (ip >= NX) ip = 0; if (jp >= NY) jp = 0; if (im < 0) im = NX-1; if (jm < 0) jm = NY-1; // check eight neighbors n += MATRIX(im, jm ) & 0x1; // nw n += MATRIX(im, j ) & 0x1; // west n += MATRIX(im, jp ) & 0x1; // sw n += MATRIX(i, jm ) & 0x1; // north // n += MATRIX(i, j ) & 0x1; // center n += MATRIX(i, jp ) & 0x1; // south n += MATRIX(ip, jm ) & 0x1; // ne n += MATRIX(ip, j ) & 0x1; // east n += MATRIX(ip, jp ) & 0x1; // se return n; } /** * the actual game of life algorithm: cell is born when three neighbors, * survives when exactly two live neighbors, dies otherwise. */ void nextGeneration( int* matrix, int* future ) { int i, j; int lifes = 0; for( i=0; i < NX; i++ ) { for( j=0; j < NY; j++ ) { // count neighbors int n = countNeighbors( matrix, i, j ); //if ((n != 0) && (random1023() > 990)) { // some slight random offset // if (random1023() > 500) FUTURE(i,j) = OCCUPIED; // else FUTURE(i,j) = EMPTY; //} // else if (n == 3) FUTURE(i,j) = OCCUPIED; if (n == 3) FUTURE(i,j) = OCCUPIED; else if ((n == 2) && (MATRIX(i,j) == OCCUPIED)) FUTURE(i,j) = OCCUPIED; else FUTURE(i,j) = EMPTY; if (FUTURE(i,j) == OCCUPIED) lifes++; } } // generation ++; // avoid extinction :-) if (lifes < 10) { // printf( "CREATING A NEW POPULATION\n\n\n" ); initializeBoard( matrix ); } else { // swap buffers: C PROHIBITS ASSIGNING TO ARRAY TYPES for( i=0; i < NX; i++ ) { for( j=0; j < NY; j++ ) { MATRIX(i,j) = FUTURE(i,j); } } } } void gx_init(void) { volatile UINT32 *pVGA_ctrl = (UINT32*)sys_vga_ctrl; volatile UINT32 *pVGA_moffs = (UINT32*)sys_vga_moffs; sleep(500); g_gx_buff = (UINT32*)malloc(SCREEN_X*SCREEN_Y*sizeof(UINT32)); memset(g_gx_buff, 0, SCREEN_X*SCREEN_Y*sizeof(UINT32)); printf("g_gx_buff : %8.8X\n", (UINT32)g_gx_buff); *pVGA_ctrl |= sys_vga_bit_msten; *pVGA_moffs = (UINT32)g_gx_buff; } int main( int argc, char* argv[] ) { int* ptr, cnt = 0; int* matrix; int* future; volatile UINT32 *pBtn = (UINT32*)sys_gpio0; // lcdEnableDisplay( 1 ); // lcdSetColor( 1 ); // lcdSetPixel( 0, 0 ); // lcdSetPixel( 3, 5 ); // if we have stdlib: matrix = (void*) malloc( NX*NY*sizeof(int) ); future = (void*) malloc( NX*NY*sizeof(int) ); gx_init(); // matrix = (void *) 0x00004000; // future = (void *) 0x00014000; // init_lfsr32( 0xcafebabe ); // init_lfsr32( 0x13 ); srand(clock()); initializeBoard( matrix ); while( 1 ) { if (*pBtn) { srand(clock()); initializeBoard( matrix ); cnt = 0; } sputs("Generation #"); print_word(cnt++); sputs("\n"); displayBoard1( matrix ); nextGeneration( matrix, future ); } // return 0 }