#include #include #include #include #include /* Fixed integer size type definitions. */ typedef __INT8_TYPE__ i8; typedef __INT16_TYPE__ i16; typedef __INT32_TYPE__ i32; typedef __INT64_TYPE__ i64; typedef __UINT8_TYPE__ u8; typedef __UINT16_TYPE__ u16; typedef __UINT32_TYPE__ u32; typedef __UINT64_TYPE__ u64; /* Variable integer sizes. */ typedef signed long long llong; typedef unsigned char uchar; typedef unsigned short ushort; typedef unsigned int uint; typedef unsigned long ulong; typedef unsigned long long ullong; static const char *formats[3] = { "\033[1K" // Erase from start of the line to the cursor "\033[%d;%dH" // Set cursor to row and column (origin 1,1) "\033[9%dm%s", // Set colour and print text. "\033[%d;%dH" // Set cursor to row and column (origin 1,1) "\033[9%dm%s", // Set colour and print text. "\033[%d;%dH" // Set cursor to row and column (origin 1,1) "\033[1K" // Erase from start of the line to the cursor "\033[9%dm%s", // Set colour and print text. }; static const char *owo = "owo\0"; static const char *uwu = "uwu\0"; static const char *ovo = "ovo\0"; static void cursor_pos(int *row, int *col) { /* Disable echo and canonical mode, * So LF isn't needed to continue execution, and so the value isn't printed. */ tcflag_t flag; struct termios term; tcgetattr(STDIN_FILENO, &term); flag = term.c_lflag; term.c_lflag &= ~(ICANON | ECHO); // Disable echo and canonical mode tcsetattr(STDIN_FILENO, TCSANOW, &term); /* Acquire the cursor position(s). */ fprintf(stderr, "\033[6n"); getchar(); // ESC getchar(); // [ char c; *row = 0; *col = 0; while ((c = getchar()) != ';') *row = (*row * 10) + (c - '0'); while ((c = getchar()) != 'R') *col = (*col * 10) + (c - '0'); /* Restore the previous flags. */ term.c_lflag = flag; tcsetattr(STDIN_FILENO, TCSANOW, &term); } /* * INFO: Beware the fmt parameter, since it may break. */ static void dvd(const char *fmt, const char *txt) { u8 colour = 0; int x, dx = -1; int y, dy = 1; _Bool tmpx, tmpy; cursor_pos(&y, &x); fprintf(stderr, "\033[?25l"); // Hide cursor ushort w, h; { struct winsize ws; ioctl(STDERR_FILENO, TIOCGWINSZ, &ws); w = ws.ws_col - 2; h = ws.ws_row; } while (1) { /* test for collisions. */ tmpx = (1 < x) & (x < w); tmpy = (1 < y) & (y < h); /* flip direction if that axis has collided. */ dx = tmpx ? dx : -dx; dy = tmpy ? dy : -dy; colour = (colour + !(tmpx & tmpy)) & 7; // increment colour on collisions /* Write the message */ fprintf(stderr, fmt, y, x, colour, txt); /* Increment the co-ordinate, and ensure it remains within bounds. */ x += dx; y += dy; usleep(50 * 1000); } } int main(int argc, char **argv) { /* Perform slightly different actions, depending on arg0. */ if (!argc) return 1; if (!strncmp(*argv, owo, 4)) dvd(formats[0], owo); if (!strncmp(*argv, uwu, 4)) dvd(formats[1], uwu); if (!strncmp(*argv, ovo, 4)) dvd(formats[2], ovo); return 1; }