2025/xmas.c

190 lines
3.4 KiB
C
Raw Normal View History

2024-12-27 12:09:04 +00:00
#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;
2024-12-27 15:05:29 +00:00
static SCREEN_SIZE ss;
2024-12-27 12:09:04 +00:00
typedef struct {
char *str;
int color;
int x;
int y;
} ENTITY;
2024-12-27 15:05:29 +00:00
static ENTITY names[10];
static ENTITY stars[25];
2024-12-27 12:09:04 +00:00
enum {
COL_RED = 1,
COL_GREEN,
COL_BLUE,
COL_YELLOW,
COL_CYAN,
COL_MAGENTA,
2024-12-27 15:05:29 +00:00
COL_WHITE,
2024-12-27 12:09:04 +00:00
COL_COUNT
};
char *persons[] = {
"PseudoCube",
"wonderfox",
"DwarfX",
"prahou",
"8nl",
"blit",
"kir4ik52",
"cybertailor",
"ej",
"Sarotar",
"continue",
"mittorn",
"edges",
"mirsusarch",
"Worst",
"Timukra",
"mnnwwn",
"dlmk",
2024-12-27 15:05:29 +00:00
"vlnst",
"KindFoxie",
"leca",
"kurator88",
"SiberiaBread"
2024-12-27 12:09:04 +00:00
};
2024-12-27 15:05:29 +00:00
void add_entity(ENTITY *ent, int y, int x, char *str, int color) {
ent->y = y;
ent->x = x;
ent->color = color;
ent->str = str;
2024-12-27 12:09:04 +00:00
}
void init_names(int i, int y) {
int color = rand() % COL_COUNT;
while (color == COL_GREEN)
color = rand() % COL_COUNT;
2024-12-27 15:05:29 +00:00
add_entity(&names[i], y, ss.mx + (-6 + rand() % 12), persons[rand() % ARRAY_SIZE(persons)], color);
2024-12-27 12:09:04 +00:00
}
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)
2024-12-27 15:05:29 +00:00
init_names(i, 1);
}
}
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 - 3, "|_____|");
for (size_t i = ss.ws.ws_row - 2; i > 0; i--) {
for (size_t j = 0; j < i; j++) {
color_print(i, (int)(ss.mx + j), "-", COL_GREEN);
color_print(i, (int)(ss.mx - j), "-", COL_GREEN);
}
if (i == 1)
color_print(i, ss.mx, "@", COL_YELLOW);
2024-12-27 12:09:04 +00:00
}
}
void sig_handler(int sig) {
(void)sig;
endwin();
exit(0);
}
int main(void) {
srand(getpid());
2024-12-27 15:05:29 +00:00
/* Fill SCREEN_SIZE struct */
2024-12-27 12:09:04 +00:00
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);
2024-12-27 15:05:29 +00:00
init_pair(7, COLOR_WHITE, COLOR_BLACK);
2024-12-27 12:09:04 +00:00
if (!has_colors()) {
endwin();
2024-12-27 15:05:29 +00:00
fputs("colors are not supported by the terminal", stderr);
2024-12-27 12:09:04 +00:00
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);
2024-12-27 15:05:29 +00:00
/* Add stars */
for (size_t i = 0; i < ARRAY_SIZE(stars); i++)
add_entity(&stars[i], rand() % ss.my, rand() % ss.ws.ws_col, ".", COLOR_WHITE);
2024-12-27 12:09:04 +00:00
/* Main */
while (1) {
clear();
2024-12-27 15:05:29 +00:00
/* Stars */
for (size_t i = 0; i < ARRAY_SIZE(stars); i++)
color_print(stars[i].y, stars[i].x, stars[i].str, stars[i].color);
/* Title */
2024-12-27 12:09:04 +00:00
char *msg = "HAPPY NEW YEAR!";
mvprintw(0, ss.mx - strlen(msg) / 2, "%s", msg);
2024-12-27 15:05:29 +00:00
/* Tree */
2024-12-27 12:09:04 +00:00
draw_tree();
2024-12-27 15:05:29 +00:00
/* Names */
2024-12-27 12:09:04 +00:00
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();
2024-12-27 15:05:29 +00:00
usleep(600000);
2024-12-27 12:09:04 +00:00
}
}