diff options
Diffstat (limited to '_log/_site/matrix-digital-rain.html')
| -rw-r--r-- | _log/_site/matrix-digital-rain.html | 103 |
1 files changed, 0 insertions, 103 deletions
diff --git a/_log/_site/matrix-digital-rain.html b/_log/_site/matrix-digital-rain.html deleted file mode 100644 index 85bac5d..0000000 --- a/_log/_site/matrix-digital-rain.html +++ /dev/null @@ -1,103 +0,0 @@ -<p>The Matrix digital rain implemented in raw C using ANSI escape sequences with -zero dependencies—not even ncurses.</p> - -<video style="max-width:100%;" controls="" poster="poster.png"> - <source src="matrix.mp4" type="video/mp4" /> -</video> - -<p>This project began over three years ago as a fork of Domsson’s unique rendition -of the Matrix rain: <a href="https://github.com/domsson/fakesteak" class="external" target="_blank" rel="noopener noreferrer">Fakesteak</a>. I -aimed to modify the algorithm to produce a rain that resembled the original -with high visual fidelity.</p> - -<h2 id="unicode-support">Unicode support</h2> - -<p>Unicode support in the 2022 version lacked flexibility. The charset used in the -rain had to be a single contiguous block defined by <code class="language-plaintext highlighter-rouge">UNICODE_MIN</code> and -<code class="language-plaintext highlighter-rouge">UNICODE_MAX</code> settings:</p> - -<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>#define UNICODE_MIN 0x0021 -#define UNICODE_MAX 0x007E - -static inline void insert_code(matrix *mat, - size_t row, size_t col) -{ - mat->code[index(mat, row, col)] = rand() - % (UNICODE_MAX - UNICODE_MIN) - + UNICODE_MIN; -} -</code></pre></div></div> - -<p>There was no way, for instance, to use both ASCII and Katakana at the same -time. The user had to pick one. In the new version, the user can use any number -of Unicode blocks using <code class="language-plaintext highlighter-rouge">glyphs</code> array. In fact, the default rain now includes -both ASCII and half-width Katakana characters:</p> - -<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>#define UNICODE(min, max) (((uint64_t)max << 32) | min) - -static uint64_t glyphs[] = { - UNICODE(0x0021, 0x007E), /* ASCII */ - UNICODE(0xFF65, 0xFF9F), /* Half-width Katakana */ -}; - -static uint8_t glyphlen = (sizeof glyphs) / (sizeof glyphs[0]); - -static inline void insert_code(matrix *mat, - size_t row, size_t col) -{ - uint64_t block; - uint32_t unicode_min, unicode_max; - - block = glyphs[(rand() % glyphlen)]; - unicode_min = (uint32_t)block; - unicode_max = (uint32_t)(block >> 32); - - mat->code[index(mat, row, col)] = rand() - % (unicode_max - unicode_min) - + unicode_min; -} -</code></pre></div></div> - -<p>Entries in the <code class="language-plaintext highlighter-rouge">glyphs</code> array are Unicode blocks bit-packed in an 8-byte -container: the four low bytes forms the first codepoint and the four high bytes -the last.</p> - -<h2 id="phosphor-decay">Phosphor decay</h2> - -<p>The dim afterglow of monochrome CRT displays is achieved by carefully scaling -the RGB channels individually and mixing them:</p> - -<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>#define DECAY_MPLIER 2 - -static inline void blend(matrix *mat, - size_t row, size_t col) -{ - unsigned char *color; - - color = mat->rgb[index(mat, row, col)].color; - color[R] = color[R] - (color[R] - RGB_BG_RED) / DECAY_MPLIER; - color[G] = color[G] - (color[G] - RGB_BG_GRN) / DECAY_MPLIER; - color[B] = color[B] - (color[B] - RGB_BG_BLU) / DECAY_MPLIER; -} -</code></pre></div></div> - -<p>The blending function emulates the phosphor decay by gradually transitioning -each raindrop’s color towards the background color. The multiplier is the -number of passes over the rain track needed before the afterglow disappears.</p> - -<p>Nonetheless, the rain resembles the original with high visual fidelity. It’s -highly customizable and gentle on the CPU. On my 14” ThinkPad T490, which has a -resolution of 1920x1080 and 4GHz CPU, it uses 2-3% of the CPU with occasional -jumps of up to about 8%. Not too bad for a weekend project. The program has -been tested 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.</p> - -<p>Lastly, to compile and run:</p> - -<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>$ cc -O3 main.c -o matrix -$ ./matrix -</code></pre></div></div> - -<p>“All I see is blonde, brunette, red head.”</p> - -<p>Files: <a href="source.tar.gz">source.tar.gz</a></p> |
