/* $Id$ */ /* * Copyright (c) 2010 Dimitri Sokolyuk * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ #include #include #include #include #include #include #include #include #include struct particle { int x; int y; int dy; int c; TAILQ_ENTRY(particle) link; } *pp, *pnext; TAILQ_HEAD(, particle) head; extern int LINES; extern int COLS; static int d_flag = 0; char flake[] = ".*#"; void resize(int signo) { struct winsize ws; if (ioctl(STDOUT_FILENO, TIOCGWINSZ, &ws) != -1) resizeterm(ws.ws_row, ws.ws_col); } void die(int signo) { d_flag = 1; } int main() { initscr(); curs_set(0); TAILQ_INIT(&head); srandom(time(NULL)); signal(SIGWINCH, resize); signal(SIGINT, die); signal(SIGTERM, die); signal(SIGHUP, die); while (!d_flag) { erase(); for (pp = TAILQ_FIRST(&head); pp; pp = pnext) { pnext = TAILQ_NEXT(pp, link); if (pp->y >= LINES || pp->x < 0 || pp->x >= COLS) { TAILQ_REMOVE(&head, pp, link); free(pp); } else { mvaddch(pp->y, pp->x, pp->c); pp->y += 1 + pp->dy; pp->x += 1 - random() % 3; } } pp = calloc(1, sizeof(struct particle)); pp->dy = random() % 3; pp->y = 0; pp->x = random() % COLS; pp->c = flake[random() % (nitems(flake) - 1)]; TAILQ_INSERT_HEAD(&head, pp, link); refresh(); usleep(50000); } curs_set(1); endwin(); return 0; }