// "Bleh" -- a "potato-friendly" cmatrix clone. // Compile this with gcc bleh.c -o bleh -static -O2. Or gcc bleh.c -o bleh -Bstatic if you are on MacOS. // Screenshot: https://i.imgur.com/dt6RmU7.png // Docker image (RISCV included): https://hub.docker.com/r/defnotgustavom/bleh #include <stdio.h> #include <stdlib.h> #include <time.h> #include <unistd.h> #include <termios.h> #include <fcntl.h> #include <sys/ioctl.h> #define DELAY 80000 #define RAND_RANGE 94 #define MIN_STREAM_LEN 5 typedef struct { short x; short y; short prev_y; unsigned char length; unsigned char active; } Stream; static inline void get_terminal_size(short* rows, short* cols) { struct winsize ws; ioctl(STDIN_FILENO, TIOCGWINSZ, &ws); *rows = ws.ws_row; *cols = ws.ws_col; } static inline int kbhit(void) { struct termios t = {0}; tcgetattr(STDIN_FILENO, &t); t.c_lflag &= ~(ICANON | ECHO); tcsetattr(STDIN_FILENO, TCSANOW, &t); int f = fcntl(STDIN_FILENO, F_GETFL, 0); fcntl(STDIN_FILENO, F_SETFL, f | O_NONBLOCK); int ch = getchar(); tcsetattr(STDIN_FILENO, TCSANOW, &t); fcntl(STDIN_FILENO, F_SETFL, f); if (ch != EOF) { ungetc(ch, stdin); return 1; } return 0; } int main() { short max_y, max_x; get_terminal_size(&max_y, &max_x); srand(time(NULL)); Stream* streams = calloc(max_x, sizeof(Stream)); if (!streams) return 1; for (short i = 0; i < max_x; i++) { streams[i].x = i; streams[i].y = rand() % max_y; streams[i].prev_y = streams[i].y; streams[i].length = (rand() % (max_y / 2)) + MIN_STREAM_LEN; streams[i].active = rand() & 1; } printf("\033[2J\033[?25l"); while (!kbhit()) { for (short i = 0; i < max_x; i++) { if (streams[i].active) { short y = streams[i].y; short prev_y = streams[i].prev_y; unsigned char len = streams[i].length; if (y != prev_y) { for (unsigned char j = 0; j < len; j++) { short prev_pos = prev_y - j; if (prev_pos >= 0 && prev_pos < max_y) { printf("\033[%d;%dH ", prev_pos + 1, i + 1); } } } if (y < max_y + len) { for (unsigned char j = 0; j < len; j++) { short pos = y - j; if (pos >= 0 && pos < max_y) { printf("\033[%d;%dH%s%c", pos + 1, i + 1, j == 0 ? "\033[97m" : "\033[32m", (rand() % RAND_RANGE) + 33); } } } streams[i].prev_y = y; if (++streams[i].y - len >= max_y) { streams[i].y = 0; streams[i].prev_y = 0; streams[i].length = (rand() % (max_y / 2)) + MIN_STREAM_LEN; streams[i].active = (rand() % 5) != 0; } } else if ((rand() % 50) == 0) { streams[i].active = 1; streams[i].y = 0; streams[i].prev_y = 0; streams[i].length = (rand() % (max_y / 2)) + MIN_STREAM_LEN; } } fflush(stdout); usleep(DELAY); } printf("\033[?25h\033[0m"); fflush(stdout); free(streams); return 0; }