162 lines
2.8 KiB
C
162 lines
2.8 KiB
C
|
#include <stdio.h>
|
||
|
#include <stdlib.h>
|
||
|
#include <unistd.h>
|
||
|
#include <string.h>
|
||
|
#include <signal.h>
|
||
|
#include <ncurses.h>
|
||
|
#include <sys/ioctl.h>
|
||
|
#include <errno.h>
|
||
|
|
||
|
#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);
|
||
|
}
|
||
|
}
|