summaryrefslogtreecommitdiffstats
path: root/_log/matrix-digital-rain.md
diff options
context:
space:
mode:
authorSadeep Madurange <sadeep@asciimx.com>2025-12-21 01:10:18 +0800
committerSadeep Madurange <sadeep@asciimx.com>2025-12-21 01:21:00 +0800
commitaad38bc831c8bba90688df2cc28c46a46cac1112 (patch)
tree7ccd19e374254b52502a9cf1d9a0e5f8347a4cf6 /_log/matrix-digital-rain.md
parente15f1076b59e997108914f6a5b9b28652d323268 (diff)
downloadwww-aad38bc831c8bba90688df2cc28c46a46cac1112.tar.gz
Matrix post as a journal entry.
Diffstat (limited to '_log/matrix-digital-rain.md')
-rw-r--r--_log/matrix-digital-rain.md101
1 files changed, 35 insertions, 66 deletions
diff --git a/_log/matrix-digital-rain.md b/_log/matrix-digital-rain.md
index d8e2543..0a3d30d 100644
--- a/_log/matrix-digital-rain.md
+++ b/_log/matrix-digital-rain.md
@@ -1,65 +1,34 @@
---
-title: The Matrix digital rain
+title: Recreating the Matrix rain with ANSI escape sequences
date: 2022-08-22
layout: post
project: true
thumbnail: thumb_sm.png
---
-"All I see is blonde, brunette, red head." The iconic digital rain from The
-Matrix in C, with zero dependencies—not even ncurses.
-
-<video style="max-width:100%;" controls="" poster="poster.png">
- <source src="matrix.mp4" type="video/mp4">
-</video>
-
-## Overview
-
-This is my fork of Domsson's beautiful <a
+Over the weekend, I came across Domsson's <a
href="https://github.com/domsson/fakesteak" class="external" target="_blank"
-rel="noopener noreferrer">Fakesteak</a>. While going through his code, I
-wondered what it would take to faithfully recreate the original Matrix from the
-first movie without sacrificing its minimalism.
-
-My implementation supports:
-
- - Unicode characters.
- - 24-bit RGB colors (truecolor).
- - 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
-```
+rel="noopener noreferrer">Fakesteak</a>: a beautifully lean rendition of the
+Matrix rain in raw C using ANSI escape sequences—zero dependencies, not even
+ncurses.
-## How does it work?
+The project's README noted that it didn't support Japanese characters and that
+it used 8-bit color mode. The latter meant that the ghosting effect has to rely
+on different foreground colors rather than shades of the same color.
-The program tracks the state of the terminal, such as code points, background
-and foreground colors, and cursor position, using multiple internal data
-buffers. On each frame, it updates these buffers and repaints the screen using
-ANSI escape codes:
+As a tip of the hat to Domsson's impressive work, I decided to add Unicode and
+24-bit truecolor support to it, aiming to faithfully recreate the original
+Matrix from the first movie during Neo and Cypher's conversation:
-```
-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]);
-}
-```
+<video style="max-width:100%;" controls="" poster="poster.png">
+ <source src="matrix.mp4" type="video/mp4">
+</video>
-The ghosting effect is achieved by carefully scaling the RGB
-channels before mixing them:
+Adding Unicode support via `wchar_t` and `wprintf()` was easy enough.
+Implementing the ghosting effect with truecolor support, however, turned out
+harder than expected. To achieve the ghosting effect, I treated phosphor decay
+as a multiplier, allowing me to emulate a dim afterglow by gradually
+transitioning each raindrop's RGB values towards the background color:
```
static void mat_shade(matrix *mat, size_t row, size_t col)
@@ -72,25 +41,25 @@ static void mat_shade(matrix *mat, size_t row, size_t col)
}
```
-The ghosting function emulates the dim after glow 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 and high-fidelity recreation of the Matrix aesthetic.
-
-## Customization
+Looking back at the implementation, there are still a few improvements to be
+made. Instead of using a dedicated buffer, I should have bit-packed the
+phosphor decay into the RGB data buffer to save memory. I'm not entirely
+satisfied with the Unicode support as it's restricted to contiguous code
+points. The glitch effect, which I implemented with characters unexpectedly
+changing, really should flash white as well.
-While you can alter almost every aspect, including speed, glitch frequency, and
-rain density, the most common customizations are the color scheme and character
-set.
+Nonetheless, the rain closely resembles the original, is highly customizable,
+and is gentle on the CPU. Not too bad for a weekend project. I tested the
+program with xterm and urxvt terminal emulators on OpenBSD and Arch Linux
+systems. Someone has managed to get it moving on a Raspberry Pi as well.
-There are three color settings: head, tail, and background. You can configure
-them using `COLOR_*_RED`, `COLOR_*_GRN`, and `COLOR_*_BLU` definitions found in
-main.c.
+Lastly, to compile and run:
-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:
+```
+$ cc -O3 main.c -o matrix
+$ ./matrix
+```
-<img style="width: 100%;" src="katakana.png" />
+"All I see is blonde, brunette, red head."
Files: [source.tar.gz](source.tar.gz)