Files
vhdl/lib/CPUs/MIPS/bsp/examples/life.c
T
jens 79de05d54c Initial version
Committed on the Free edition of March Hare Software CVSNT Server.
Upgrade to CVS Suite for more features and support:
http://march-hare.com/cvsnt/


git-svn-id: http://moon:8086/svn/vhdl/trunk@448 cc03376c-175c-47c8-b038-4cd826a8556b
2009-04-15 14:11:45 +00:00

250 lines
5.2 KiB
C

/* 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 <stdio.h>
#include <stdlib.h>
#include <string.h>
#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_mctrl = (UINT32*)sys_vga_mctrl;
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_mctrl = 1;
*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
}