#include #include #include #include #include #include #include #include #define ARRAY_SIZE(x) (sizeof(x) / sizeof(x[0])) typedef struct { struct winsize ws; /* m middle */ size_t mx; size_t my; } SCREEN_SIZE; SCREEN_SIZE ss; typedef struct { char *str; int color; int x; int y; } ENTITY; ENTITY names[10]; enum { COL_RED = 1, COL_GREEN, COL_BLUE, COL_YELLOW, COL_CYAN, COL_MAGENTA, COL_COUNT }; char *persons[] = { "PseudoCube", "wonderfox", "DwarfX", "prahou", "8nl", "blit", "kir4ik52", "cybertailor", "ej", "Sarotar", "continue", "mittorn", "edges", "mirsusarch", "Worst", "Timukra", "mnnwwn", "dlmk", "vlnst" }; void color_print(const int y, const int x, const char *str, const int color) { attron(COLOR_PAIR(color)); mvprintw(y, x, "%s", str); attroff(COLOR_PAIR(color)); } void draw_tree(void) { mvprintw(ss.ws.ws_row - 1, ss.mx - 2, "|___|"); for (unsigned int i = ss.ws.ws_row - 2; i > 0; i--) for (unsigned int j = 0; j < i * 2; j++) color_print(i, (int)(ss.mx - i + j), "#", COL_GREEN); } void init_names(int i, int y) { names[i].y = y; names[i].x = ss.mx + (-6 + rand() % 12); names[i].str = persons[rand() % (sizeof(persons) / sizeof(char *))]; int color = rand() % COL_COUNT; while (color == COL_GREEN) color = rand() % COL_COUNT; names[i].color = color; } void update_names(void) { for (size_t i = 0; i < ARRAY_SIZE(names); i++) { names[i].x += -3 + rand() % 6; names[i].y++; if (names[i].y >= ss.ws.ws_row) init_names(i, 0); } } void sig_handler(int sig) { (void)sig; endwin(); exit(0); } int main(void) { srand(getpid()); /* Fill SCREEN_SIZE structure */ if (ioctl(STDOUT_FILENO, TIOCGWINSZ, &ss.ws) < 0) { fprintf(stderr, "ioctl failed: %s\n", strerror(errno)); return 1; } ss.mx = ss.ws.ws_col / 2; ss.my = ss.ws.ws_row / 2; /* Init ncurses */ initscr(); noecho(); cbreak(); curs_set(0); /* Colors */ start_color(); init_pair(1, COLOR_RED, COLOR_BLACK); init_pair(2, COLOR_GREEN, COLOR_BLACK); init_pair(3, COLOR_BLUE, COLOR_BLACK); init_pair(4, COLOR_YELLOW, COLOR_BLACK); init_pair(5, COLOR_CYAN, COLOR_BLACK); init_pair(6, COLOR_MAGENTA, COLOR_BLACK); if (!has_colors()) { endwin(); fputs("colors not supported by your terminal", stderr); return 1; } /* Update siganls */ signal(SIGINT, sig_handler); signal(SIGKILL, sig_handler); /* Update names */ for (size_t i = 0; i < ARRAY_SIZE(names); i++) init_names(i, i); /* Main */ while (1) { clear(); char *msg = "HAPPY NEW YEAR!"; mvprintw(0, ss.mx - strlen(msg) / 2, "%s", msg); draw_tree(); update_names(); for (size_t i = 0; i < ARRAY_SIZE(names); i++) color_print(names[i].y, names[i].x, names[i].str, names[i].color); refresh(); usleep(700000); } }