📄 life.c
字号:
/* * Copyright (c) 2000 Blue Mug, Inc. All Rights Reserved. */#include <target/herrno.h>#include <target/scan.h>#include <ep7211/ioregs.h>#include "life.h"unsigned rand_seed;unsigned rand(void){ rand_seed = 1664525L * rand_seed + 1013904223L; return rand_seed;}void srand(unsigned seed){ rand_seed = seed;}static int count_neighbors(int row, int col);static void draw_cell(int row, int col);static void lcd_init(void);static void game_of_life(word_t seed, word_t density);static void game_init(word_t density);static void generation(void);static void redraw_all(void);#define SCREENWIDTH 640#define SCREENHEIGHT 240#define COLORDEPTH 4#define PIXELS_PER_BYTE 2#define PIXELS_PER_WORD 8#define VIDEO_MEM_BASE (0xC0000000)#define VIDEO_MEM_SIZE (SCREENWIDTH*SCREENHEIGHT/PIXELS_PER_BYTE)/* these can't go lower than 8 and remain square, since 1 32-bit word * == 8 pixels, and we currently draw at word granularity. */#define CELLWIDTH 8#define CELLHEIGHT 8#define NUMROWS (SCREENHEIGHT/CELLHEIGHT)#define NUMCOLS (SCREENWIDTH/CELLWIDTH)/* cells of the game */static unsigned char cell [NUMROWS][NUMCOLS];static unsigned char future [NUMROWS][NUMCOLS];#define WORDS_PER_ROW (SCREENWIDTH/PIXELS_PER_WORD)#define WORDS_PER_COL (CELLWIDTH/PIXELS_PER_WORD)static void draw_cell(int row, int col){ unsigned *dst = (unsigned*) VIDEO_MEM_BASE; unsigned value = cell[row][col] ? ~0U : 0U; int i; dst += (row * WORDS_PER_ROW * CELLHEIGHT) + (col * WORDS_PER_COL); for (i=0; i<CELLHEIGHT; ++i) { dst[0] = dst[1] = value; dst += WORDS_PER_ROW;; }}static int count_neighbors(int row, int col){ const int above = (row + NUMROWS - 1) % NUMROWS; const int below = (row + 1) % NUMROWS; const int left = (col + NUMCOLS - 1) % NUMCOLS; const int right = (col + 1) % NUMCOLS; return (cell[above][left] + cell[above][col] + cell[above][right] + cell[row][left] + cell[row][right] + cell[below][left] + cell[below][col] + cell[below][right]);}static void game_init(word_t density){ int row, col; density %= 100; density *= 1000; for (row=0; row<NUMROWS; ++row) for (col=0; col<NUMCOLS; ++col) cell[row][col] = ((rand() % 100000) <= density);}static void lcd_clear(void){ char *p = (char*) VIDEO_MEM_BASE; int i = VIDEO_MEM_SIZE; while (i--) *p++ = 0;}#define SYSCON1_LCD_ENABLE (0x00001000)#define PD1_LCD_DC_DC_EN (1<<1)#define PD2_LCDEN (1<<2)#define PD3_LCDBL (1<<3)#define LCD_GSMD (1<<31)#define LCD_GSEN (1<<30)static void lcd_init(void){ volatile int i; word_t video_bufsize, video_linelength, lcdcon; /* configure LCD control registers */ IO_PALLSW = 0x76543210; IO_PALMSW = 0xFEDCBA98; video_bufsize = (SCREENWIDTH*SCREENHEIGHT*COLORDEPTH) / 128 - 1; video_linelength = SCREENWIDTH / 16 - 1; lcdcon = LCD_GSMD | LCD_GSEN | (0x18 << 25) | /* AC prescale */ (3 << 19) | /* pixel prescale */ (video_linelength << 13) | video_bufsize; IO_LCDCON = lcdcon; /* clear screen buffer */ lcd_clear(); /* activate LCD and display backlight */ IO_SYSCON1 |= SYSCON1_LCD_ENABLE; /* activate LCD controller */ IO_PDDR |= PD2_LCDEN; /* turn LCD on */ for (i=0; i<(65536*4); ++i); /* delay (demonstrated in lib7211) */ IO_PDDR |= PD1_LCD_DC_DC_EN; /* power up DC-DC converter */ IO_PDDR |= PD3_LCDBL; /* enable display backlight */}static void generation(void){ int row, col; /* compute next generation */ for (row=0; row<NUMROWS; ++row) { for (col=0; col<NUMCOLS; ++col) { switch (count_neighbors(row, col)) { case 2: future[row][col] = cell[row][col]; break; case 3: future[row][col] = 1; break; default: future[row][col] = 0; } } } /* copy next generation over current */ for (row=0; row<NUMROWS; ++row) for (col=0; col<NUMCOLS; ++col) if (cell[row][col] != future[row][col]) { cell[row][col] = future[row][col]; draw_cell(row, col); }}static void redraw_all(void){ int row, col; for (row=0; row<NUMROWS; ++row) for (col=0; col<NUMCOLS; ++col) draw_cell(row, col);}static void game_of_life(word_t seed, word_t density){ lcd_init(); srand(seed); game_init(density); redraw_all(); while (1) { int i; for (i=0; i<1000; ++i) generation(); game_init(density); redraw_all(); }}static int game_of_life_cmdfunc(int argc, char *argv[]){ word_t seed = 0, density = 30; if ((argc < 1) || (argc > 3)) return -H_EUSAGE; if (argc > 1) if (scan(*++argv, &seed)) return -H_EUSAGE; if (argc > 2) if (scan(*++argv, &density)) return -H_EUSAGE; game_of_life(seed, density); return 0;}const command_t game_of_life_command = { "life", "<seed> <density>", "John Conway's game of Life", &game_of_life_cmdfunc };
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -