THE MATRIX DIGITAL RAIN

12 JANUARY 2024

“All I see is blonde, brunette, red head.” The iconic digital rain from The Matrix in C, with zero dependencies - not even ncurses.

Overview

This is my fork of Domsson’s beautiful Fakesteak. While studying the code, I wondered what it would take to faithfully recreate the original Matrix from the first movie without sacrificing the program’s minimalism and elegance.

My version adds:

  • Unicode character support.
  • Fully customizable 24-bit RGB (truecolor) colors.
  • Glitches in the matrix.
  • Ghosting effect of old monochrome CRT displays.
  • Closely resembles the Matrix seen in the background during Neo and Cypher’s conversation.

With no dependencies, compilation is trivial:

$ cc -O3 main.c -o matrix
$ ./matrix

How does it work?

The program tracks the state of the terminal - characters, background and foreground colors, shading levels, cursor position - using multiple internal data buffers. On each frame, it updates these buffers and repaints the screen using ANSI escape codes:

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[R],
        mat->rgb[idx].color[G],
        mat->rgb[idx].color[B],
        mat->code[idx]);
}

The ghosting effect, the signature feature of this implementation, works by scaling and mixing the RGB channels:

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[R] = color[R] - (color[R] - COLOR_BG_RED) / 2;
    color[G] = color[G] - (color[G] - COLOR_BG_GRN) / 2;
    color[B] = color[B] - (color[B] - COLOR_BG_BLU) / 2;
}

The ghosting function emulates the screen decay by gradually transitioning each raindrop’s color towards the background color. This approach provides two key benefits: straightforward color configuration that integrates naturally with Unix ricing (desktop customization) and high-fidelity recreation of the Matrix aesthetic.

Customization

While you can adjust almost every aspect, including its speed, glitch frequency, and rain density, the most useful settings for customization are the color scheme and character set.

There are three color settings: head, tail, and background. You can configure them by setting the COLOR_*_RED, COLOR_*_GRN, and COLOR_*_BLU definitions in main.c.

The UNICODE_MIN and UNICODE_MAX values control the Unicode block used. For example, setting them to 0x30A1 and 0x30F6 rains Katakana (if a font that supports Katakana is present on the system):

Files: source.tar.gz