/* $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; LIST_ENTRY(particle) link; } *pp, *pnext; LIST_HEAD(, particle) head; extern int LINES; extern int COLS; static int d_flag = 0; static int ocurs; static char flake[] = ".*#"; #ifndef nitems #define nitems(s) (sizeof(s) / sizeof((s)[0])) #endif 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() { signal(SIGWINCH, resize); signal(SIGINT, die); signal(SIGTERM, die); signal(SIGHUP, die); initscr(); noecho(); nonl(); leaveok(stdscr, TRUE); scrollok(stdscr, FALSE); ocurs = curs_set(0); LIST_INIT(&head); srandom(time(NULL)); while (!d_flag) { erase(); LIST_FOREACH_SAFE(pp, &head, link, pnext) { if (pp->y >= LINES || pp->x < 0 || pp->x >= COLS) { LIST_REMOVE(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)]; LIST_INSERT_HEAD(&head, pp, link); refresh(); usleep(50000); } curs_set(ocurs); endwin(); return 0; }