summaryrefslogtreecommitdiffstats
path: root/src/main.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/main.c')
-rw-r--r--src/main.c321
1 files changed, 0 insertions, 321 deletions
diff --git a/src/main.c b/src/main.c
deleted file mode 100644
index 44a0955..0000000
--- a/src/main.c
+++ /dev/null
@@ -1,321 +0,0 @@
-#define _XOPEN_SOURCE 700
-
-#include <locale.h>
-#include <signal.h>
-#include <stdint.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <sys/ioctl.h>
-#include <termios.h>
-#include <time.h>
-#include <unistd.h>
-#include <wchar.h>
-
-#define UNICODE_MIN 0x0021
-#define UNICODE_MAX 0x007E
-
-#define RAIN_DENSITY 0.6
-
-#define COLOR_BG_RED 0
-#define COLOR_BG_GRN 0
-#define COLOR_BG_BLU 0
-#define COLOR_HD_RED 255
-#define COLOR_HD_GRN 255
-#define COLOR_HD_BLU 255
-#define COLOR_TL_RED 40
-#define COLOR_TL_GRN 254
-#define COLOR_TL_BLU 20
-
-#define ANSI_CUR_HIDE "\e[?25l"
-#define ANSI_CUR_SHOW "\e[?25h"
-#define ANSI_CUR_RESET "\x1b[H"
-#define ANSI_FONT_BOLD "\x1b[1m"
-#define ANSI_FONT_RESET "\x1b[0m"
-#define ANSI_SCRN_CLEAR "\x1b[2J"
-
-enum { red, green, blue };
-
-typedef union color_tag {
- uint32_t rgb;
- unsigned char color[4];
-} color;
-
-typedef struct matrix_tag {
- size_t rows;
- size_t cols;
- size_t *col;
- size_t *row;
- char *shade;
- wchar_t *code;
- color *rgb;
-} matrix;
-
-static size_t mat_idx(const matrix *mat, size_t row, size_t col) {
- return mat->cols * row + col;
-}
-
-static void mat_put_code(matrix *mat, size_t row, size_t col) {
- mat->code[mat_idx(mat, row, col)] =
- rand() % (UNICODE_MAX - UNICODE_MIN) + UNICODE_MIN;
-}
-
-static void shuffle(size_t *a, size_t n) {
- size_t i, j;
-
- for (i = n - 1; i > 0; i--) {
- j = rand() % (i + 1);
- a[j] = a[i] ^ a[j];
- a[i] = a[i] ^ a[j];
- a[j] = a[i] ^ a[j];
- }
-}
-
-static int mat_init(matrix *mat, const struct winsize *ws) {
- size_t i;
-
- mat->cols = ws->ws_col;
- mat->rows = ws->ws_row + 1;
-
- mat->code = realloc(mat->code, sizeof mat->code[0] * mat->rows * mat->cols);
- if (!mat->code)
- return 0;
-
- mat->rgb = realloc(mat->rgb, sizeof mat->rgb[0] * mat->rows * mat->cols);
- if (!mat->rgb)
- return 0;
-
- mat->shade = realloc(mat->shade, sizeof mat->shade[0] * mat->cols);
- if (!mat->shade)
- return 0;
-
- mat->col = realloc(mat->col, sizeof mat->col[0] * mat->cols);
- if (!mat->col)
- return 0;
-
- mat->row = realloc(mat->row, sizeof mat->row[0] * mat->cols);
- if (!mat->row)
- return 0;
-
- for (i = 0; i < mat->cols; i++) {
- mat->row[i] = 0;
- mat->col[i] = i;
- mat->shade[i] = 0;
- }
-
- shuffle(mat->col, mat->cols);
- return 1;
-}
-
-static void mat_reset_head(matrix *mat, size_t row, size_t col) {
- unsigned char *sc, *tc;
-
- sc = mat->rgb[mat_idx(mat, 0, col)].color;
- tc = mat->rgb[mat_idx(mat, row, col)].color;
-
- tc[red] = sc[red];
- tc[green] = sc[green];
- tc[blue] = sc[blue];
-}
-
-static void mat_set_tail(matrix *mat, size_t row, size_t col) {
- unsigned char *color;
-
- color = mat->rgb[mat_idx(mat, row, col)].color;
-
- color[red] = COLOR_TL_RED;
- color[green] = COLOR_TL_GRN;
- color[blue] = COLOR_TL_BLU;
-}
-
-static void mat_set_head(matrix *mat, size_t row, size_t col) {
- unsigned char *color;
-
- color = mat->rgb[mat_idx(mat, row, col)].color;
- color[red] = COLOR_HD_RED;
- color[green] = COLOR_HD_GRN;
-
- color[blue] = COLOR_HD_BLU;
-}
-
-static void mat_shade(matrix *mat, size_t row, size_t col) {
- unsigned char *color;
-
- color = mat->rgb[mat_idx(mat, row, col)].color;
-
- color[red] = color[red] - (color[red] - COLOR_BG_RED) / 2;
- color[green] = color[green] - (color[green] - COLOR_BG_GRN) / 2;
- color[blue] = color[blue] - (color[blue] - COLOR_BG_BLU) / 2;
-}
-
-static void mat_free(matrix *mat) {
- free(mat->code);
- free(mat->col);
- free(mat->row);
- free(mat->rgb);
- free(mat->shade);
-}
-
-static int term_init() {
- struct termios ta;
-
- if (tcgetattr(STDIN_FILENO, &ta) == 0) {
- ta.c_lflag &= ~ECHO;
-
- if (tcsetattr(STDIN_FILENO, TCSANOW, &ta) == 0) {
- wprintf(L"\x1b[48;2;%d;%d;%dm", COLOR_BG_RED, COLOR_BG_GRN, COLOR_BG_BLU);
-
- wprintf(L"%s", ANSI_FONT_BOLD);
- wprintf(L"%s", ANSI_CUR_HIDE);
- wprintf(L"%s", ANSI_CUR_RESET);
- wprintf(L"%s", ANSI_SCRN_CLEAR);
-
- setvbuf(stdout, 0, _IOFBF, 0);
- return 1;
- }
- }
- return 0;
-}
-
-static void term_reset() {
- struct termios ta;
-
- wprintf(L"%s", ANSI_FONT_RESET);
- wprintf(L"%s", ANSI_CUR_SHOW);
- wprintf(L"%s", ANSI_SCRN_CLEAR);
- wprintf(L"%s", ANSI_CUR_RESET);
-
- if (tcgetattr(STDIN_FILENO, &ta) == 0) {
- ta.c_lflag |= ECHO;
- if (tcsetattr(STDIN_FILENO, TCSANOW, &ta) != 0)
- perror("term_reset()");
- }
-
- setvbuf(stdout, 0, _IOLBF, 0);
-}
-
-static void term_size(const struct winsize *ws) {
- ioctl(STDOUT_FILENO, TIOCGWINSZ, ws);
-}
-
-static void term_print(const matrix *mat, size_t row, size_t col) {
- size_t idx;
-
- idx = mat_idx(mat, row, col);
-
- wprintf(L"\x1b[%d;%dH\x1b[38;2;%d;%d;%dm%lc", row, col,
- mat->rgb[idx].color[red], mat->rgb[idx].color[green],
- mat->rgb[idx].color[blue], mat->code[idx]);
-}
-
-static volatile int run;
-
-static void handle_signal(int sa) {
- switch (sa) {
- case SIGINT:
- case SIGQUIT:
- case SIGTERM:
- run = 0;
- break;
- }
-}
-
-int main(int argc, char *argv[]) {
- matrix mat;
-
- struct winsize ws;
- struct sigaction sa;
- size_t i, j, len, maxlen;
-
- setlocale(LC_CTYPE, "");
-
- sa.sa_handler = handle_signal;
- sigaction(SIGINT, &sa, 0);
- sigaction(SIGQUIT, &sa, 0);
- sigaction(SIGTERM, &sa, 0);
-
- srand(time(0));
-
- if (!term_init())
- return 1;
-
- term_size(&ws);
-
- mat = (matrix){0};
- if (!mat_init(&mat, &ws)) {
- term_reset();
- return 1;
- }
-
- run = 1, len = 1;
- maxlen = mat.cols * RAIN_DENSITY;
-
- while (run) {
- for (i = 0; run && i < len; i++) {
- if (mat.row[i] == mat.rows) {
- mat_reset_head(&mat, mat.row[i] - 1, mat.col[i]);
- term_print(&mat, mat.rows - 1, mat.col[i]);
- mat.row[i] = 0;
- }
-
- if (mat.shade[i] == 0) {
- if (mat.row[i] > 0) {
- mat_set_tail(&mat, mat.row[i] - 1, mat.col[i]);
- term_print(&mat, mat.row[i] - 1, mat.col[i]);
- }
-
- mat_set_head(&mat, mat.row[i], mat.col[i]);
- mat_put_code(&mat, mat.row[i], mat.col[i]);
- term_print(&mat, mat.row[i], mat.col[i]);
-
- if (mat.row[i] > 0 && rand() % 6 == 0) {
- j = rand() % mat.row[i];
- if (mat.code[mat_idx(&mat, j, mat.col[i])] != ' ') {
- mat_put_code(&mat, j, mat.col[i]);
- term_print(&mat, j, mat.col[i]);
- }
- }
-
- if (mat.row[i] == mat.rows - 1)
- mat.shade[i] = 1;
-
- mat.row[i]++;
- } else if (mat.shade[i] == 1 || mat.shade[i] == 2) {
- mat_shade(&mat, mat.row[i], mat.col[i]);
- term_print(&mat, mat.row[i], mat.col[i]);
-
- if (mat.row[i] == mat.rows - 1)
- mat.shade[i]++;
-
- mat.row[i]++;
- } else {
- mat.code[mat_idx(&mat, mat.row[i], mat.col[i])] = ' ';
- term_print(&mat, mat.row[i], mat.col[i]);
-
- if (mat.row[i] == mat.rows - 1) {
- mat.row[i] = 0;
- mat.shade[i] = 0;
-
- j = rand() % (mat.cols - maxlen) + maxlen;
- mat.col[i] = mat.col[i] ^ mat.col[j];
- mat.col[j] = mat.col[i] ^ mat.col[j];
- mat.col[i] = mat.col[i] ^ mat.col[j];
- } else
- mat.row[i]++;
- }
- }
-
- if (len < maxlen &&
- mat.row[len - 1] >= rand() % (int)(mat.rows * 0.25)) {
- mat.row[len] = 0;
- mat.shade[len++] = 0;
- }
-
- fflush(stdout);
- usleep(50000);
- }
-
- term_reset();
- mat_free(&mat);
-
- return 0;
-}