diff options
| author | Sadeep Madurange <sadeep@asciimx.com> | 2025-12-21 01:10:18 +0800 |
|---|---|---|
| committer | Sadeep Madurange <sadeep@asciimx.com> | 2025-12-21 01:21:00 +0800 |
| commit | aad38bc831c8bba90688df2cc28c46a46cac1112 (patch) | |
| tree | 7ccd19e374254b52502a9cf1d9a0e5f8347a4cf6 | |
| parent | e15f1076b59e997108914f6a5b9b28652d323268 (diff) | |
| download | www-aad38bc831c8bba90688df2cc28c46a46cac1112.tar.gz | |
Matrix post as a journal entry.
| -rw-r--r-- | _log/matrix-digital-rain.md | 101 | ||||
| -rw-r--r-- | _site/feed.xml | 2 | ||||
| -rw-r--r-- | _site/index.html | 2 | ||||
| -rw-r--r-- | _site/log/index.html | 2 | ||||
| -rw-r--r-- | _site/log/matrix-digital-rain/index.html | 100 | ||||
| -rw-r--r-- | _site/posts.xml | 2 | ||||
| -rw-r--r-- | _site/projects/index.html | 4 | ||||
| -rw-r--r-- | _site/robots.txt | 2 | ||||
| -rw-r--r-- | _site/sitemap.xml | 28 |
9 files changed, 90 insertions, 153 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) diff --git a/_site/feed.xml b/_site/feed.xml index dd2f441..9a57c65 100644 --- a/_site/feed.xml +++ b/_site/feed.xml @@ -1 +1 @@ -<?xml version="1.0" encoding="utf-8"?><feed xmlns="http://www.w3.org/2005/Atom" ><generator uri="https://jekyllrb.com/" version="4.4.1">Jekyll</generator><link href="http://localhost:4000/feed.xml" rel="self" type="application/atom+xml" /><link href="http://localhost:4000/" rel="alternate" type="text/html" /><updated>2025-12-20T21:35:40+08:00</updated><id>http://localhost:4000/feed.xml</id><title type="html">ASCIIMX | Log</title><author><name>W. D. Sadeep Madurange</name></author><entry><title type="html">How to manage Suckless software installations</title><link href="http://localhost:4000/log/suckless-software/" rel="alternate" type="text/html" title="How to manage Suckless software installations" /><published>2025-11-30T00:00:00+08:00</published><updated>2025-11-30T00:00:00+08:00</updated><id>http://localhost:4000/log/suckless-software</id><author><name>W. D. Sadeep Madurange</name></author><summary type="html"><![CDATA[Since suckless software requires users to modify the source code and recompile to customize, I need a way to maintain patches over the long term while retaining the ability to upgrade the software as new versions are released.]]></summary></entry><entry><title type="html">Fingerprint door lock</title><link href="http://localhost:4000/log/fpm-door-lock/" rel="alternate" type="text/html" title="Fingerprint door lock" /><published>2025-08-18T00:00:00+08:00</published><updated>2025-08-18T00:00:00+08:00</updated><id>http://localhost:4000/log/fpm-door-lock</id><author><name>W. D. Sadeep Madurange</name></author><summary type="html"><![CDATA[This project features a fingerprint door lock powered by an ATmega328P microcontroller.]]></summary></entry><entry><title type="html">On the use of MOSFETs as electronic switches</title><link href="http://localhost:4000/log/mosfet-switches/" rel="alternate" type="text/html" title="On the use of MOSFETs as electronic switches" /><published>2025-06-22T00:00:00+08:00</published><updated>2025-06-22T00:00:00+08:00</updated><id>http://localhost:4000/log/mosfet-switches</id><author><name>W. D. Sadeep Madurange</name></author><summary type="html"><![CDATA[Recently, I needed a low-power circuit for one of my battery-operated projects. Much of the system’s power savings depended on its ability to electronically switch off components, such as servos, that draw high levels of quiescent currents. My search for a solution led me to MOSFETs, transistors capable of controlling circuits operating at voltages far above their own.]]></summary></entry><entry><title type="html">How to configure ATmega328P microcontrollers to run at 3.3V and 5V</title><link href="http://localhost:4000/log/arduino-uno/" rel="alternate" type="text/html" title="How to configure ATmega328P microcontrollers to run at 3.3V and 5V" /><published>2025-06-10T00:00:00+08:00</published><updated>2025-06-10T00:00:00+08:00</updated><id>http://localhost:4000/log/arduino-uno</id><author><name>W. D. Sadeep Madurange</name></author><summary type="html"><![CDATA[This is a quick reference for wiring up ATmega328P ICs to run at 5V and 3.3V. While the 5V configuration is common, the 3.3V configuration can be useful in low-power applications and when interfacing with parts that themselves run at 3.3V. In this guide, the 5V setup is configured with a 16MHz crystal oscillator, while the 3.3V configuration makes use of an 8MHz crystal oscillator.]]></summary></entry><entry><title type="html">My first PCB</title><link href="http://localhost:4000/log/my-first-pcb/" rel="alternate" type="text/html" title="My first PCB" /><published>2025-04-26T00:00:00+08:00</published><updated>2025-04-26T00:00:00+08:00</updated><id>http://localhost:4000/log/my-first-pcb</id><author><name>W. D. Sadeep Madurange</name></author><summary type="html"><![CDATA[In 2023, I started tinkering with DIY electronics as a hobby. Until now, I’ve been using development boards like the Arduino Uno and ESP-32-WROOM so that I can focus on the software. Recently, I decided to step outside of my comfort zone and design a PCB from scratch for a door lock I’m working on.]]></summary></entry><entry><title type="html">Bumblebee: browser automation</title><link href="http://localhost:4000/log/bumblebee/" rel="alternate" type="text/html" title="Bumblebee: browser automation" /><published>2025-04-02T00:00:00+08:00</published><updated>2025-04-02T00:00:00+08:00</updated><id>http://localhost:4000/log/bumblebee</id><author><name>W. D. Sadeep Madurange</name></author><summary type="html"><![CDATA[Bumblebee is a tool I built for one of my employers to automate the generation of web scraping scripts.]]></summary></entry><entry><title type="html">How to set up ATSAM3X8E microcontrollers for bare-metal programming in C</title><link href="http://localhost:4000/log/arduino-due/" rel="alternate" type="text/html" title="How to set up ATSAM3X8E microcontrollers for bare-metal programming in C" /><published>2024-09-16T00:00:00+08:00</published><updated>2024-09-16T00:00:00+08:00</updated><id>http://localhost:4000/log/arduino-due</id><author><name>W. D. Sadeep Madurange</name></author><summary type="html"><![CDATA[This article is a step-by-step guide for programming bare-metal ATSAM3X8E chips found on Arduino Due boards. It also includes notes on the chip’s memory layout relevant for writing linker scripts. The steps described in this article were tested on an OpenBSD workstation.]]></summary></entry><entry><title type="html">Etlas: e-paper dashboard</title><link href="http://localhost:4000/log/etlas/" rel="alternate" type="text/html" title="Etlas: e-paper dashboard" /><published>2024-09-05T00:00:00+08:00</published><updated>2024-09-05T00:00:00+08:00</updated><id>http://localhost:4000/log/etlas</id><author><name>W. D. Sadeep Madurange</name></author><summary type="html"><![CDATA[Etlas is a news, stock market, and weather tracker powered by an ESP32 NodeMCU D1, featuring a 7.5-inch Waveshare e-paper display and a DHT22 sensor module.]]></summary></entry><entry><title type="html">Experimental e-reader</title><link href="http://localhost:4000/log/e-reader/" rel="alternate" type="text/html" title="Experimental e-reader" /><published>2023-10-24T00:00:00+08:00</published><updated>2023-10-24T00:00:00+08:00</updated><id>http://localhost:4000/log/e-reader</id><author><name>W. D. Sadeep Madurange</name></author><summary type="html"><![CDATA[This project features an experimental e-reader powered by an ESP-WROOM-32 development board and a 7.5-inch Waveshare e-paper display built with the intention of learning about e-paper displays.]]></summary></entry><entry><title type="html">The Matrix digital rain</title><link href="http://localhost:4000/log/matrix-digital-rain/" rel="alternate" type="text/html" title="The Matrix digital rain" /><published>2022-08-22T00:00:00+08:00</published><updated>2022-08-22T00:00:00+08:00</updated><id>http://localhost:4000/log/matrix-digital-rain</id><author><name>W. D. Sadeep Madurange</name></author><summary type="html"><![CDATA[“All I see is blonde, brunette, red head.” The iconic digital rain from The Matrix in C, with zero dependencies—not even ncurses.]]></summary></entry></feed>
\ No newline at end of file +<?xml version="1.0" encoding="utf-8"?><feed xmlns="http://www.w3.org/2005/Atom" ><generator uri="https://jekyllrb.com/" version="4.4.1">Jekyll</generator><link href="/feed.xml" rel="self" type="application/atom+xml" /><link href="/" rel="alternate" type="text/html" /><updated>2025-12-21T01:20:43+08:00</updated><id>/feed.xml</id><title type="html">ASCIIMX | Log</title><author><name>W. D. Sadeep Madurange</name></author><entry><title type="html">How to manage Suckless software installations</title><link href="/log/suckless-software/" rel="alternate" type="text/html" title="How to manage Suckless software installations" /><published>2025-11-30T00:00:00+08:00</published><updated>2025-11-30T00:00:00+08:00</updated><id>/log/suckless-software</id><author><name>W. D. Sadeep Madurange</name></author><summary type="html"><![CDATA[Since suckless software requires users to modify the source code and recompile to customize, I need a way to maintain patches over the long term while retaining the ability to upgrade the software as new versions are released.]]></summary></entry><entry><title type="html">Fingerprint door lock</title><link href="/log/fpm-door-lock/" rel="alternate" type="text/html" title="Fingerprint door lock" /><published>2025-08-18T00:00:00+08:00</published><updated>2025-08-18T00:00:00+08:00</updated><id>/log/fpm-door-lock</id><author><name>W. D. Sadeep Madurange</name></author><summary type="html"><![CDATA[This project features a fingerprint door lock powered by an ATmega328P microcontroller.]]></summary></entry><entry><title type="html">On the use of MOSFETs as electronic switches</title><link href="/log/mosfet-switches/" rel="alternate" type="text/html" title="On the use of MOSFETs as electronic switches" /><published>2025-06-22T00:00:00+08:00</published><updated>2025-06-22T00:00:00+08:00</updated><id>/log/mosfet-switches</id><author><name>W. D. Sadeep Madurange</name></author><summary type="html"><![CDATA[Recently, I needed a low-power circuit for one of my battery-operated projects. Much of the system’s power savings depended on its ability to electronically switch off components, such as servos, that draw high levels of quiescent currents. My search for a solution led me to MOSFETs, transistors capable of controlling circuits operating at voltages far above their own.]]></summary></entry><entry><title type="html">How to configure ATmega328P microcontrollers to run at 3.3V and 5V</title><link href="/log/arduino-uno/" rel="alternate" type="text/html" title="How to configure ATmega328P microcontrollers to run at 3.3V and 5V" /><published>2025-06-10T00:00:00+08:00</published><updated>2025-06-10T00:00:00+08:00</updated><id>/log/arduino-uno</id><author><name>W. D. Sadeep Madurange</name></author><summary type="html"><![CDATA[This is a quick reference for wiring up ATmega328P ICs to run at 5V and 3.3V. While the 5V configuration is common, the 3.3V configuration can be useful in low-power applications and when interfacing with parts that themselves run at 3.3V. In this guide, the 5V setup is configured with a 16MHz crystal oscillator, while the 3.3V configuration makes use of an 8MHz crystal oscillator.]]></summary></entry><entry><title type="html">My first PCB</title><link href="/log/my-first-pcb/" rel="alternate" type="text/html" title="My first PCB" /><published>2025-04-26T00:00:00+08:00</published><updated>2025-04-26T00:00:00+08:00</updated><id>/log/my-first-pcb</id><author><name>W. D. Sadeep Madurange</name></author><summary type="html"><![CDATA[In 2023, I started tinkering with DIY electronics as a hobby. Until now, I’ve been using development boards like the Arduino Uno and ESP-32-WROOM so that I can focus on the software. Recently, I decided to step outside of my comfort zone and design a PCB from scratch for a door lock I’m working on.]]></summary></entry><entry><title type="html">Bumblebee: browser automation</title><link href="/log/bumblebee/" rel="alternate" type="text/html" title="Bumblebee: browser automation" /><published>2025-04-02T00:00:00+08:00</published><updated>2025-04-02T00:00:00+08:00</updated><id>/log/bumblebee</id><author><name>W. D. Sadeep Madurange</name></author><summary type="html"><![CDATA[Bumblebee is a tool I built for one of my employers to automate the generation of web scraping scripts.]]></summary></entry><entry><title type="html">How to set up ATSAM3X8E microcontrollers for bare-metal programming in C</title><link href="/log/arduino-due/" rel="alternate" type="text/html" title="How to set up ATSAM3X8E microcontrollers for bare-metal programming in C" /><published>2024-09-16T00:00:00+08:00</published><updated>2024-09-16T00:00:00+08:00</updated><id>/log/arduino-due</id><author><name>W. D. Sadeep Madurange</name></author><summary type="html"><![CDATA[This article is a step-by-step guide for programming bare-metal ATSAM3X8E chips found on Arduino Due boards. It also includes notes on the chip’s memory layout relevant for writing linker scripts. The steps described in this article were tested on an OpenBSD workstation.]]></summary></entry><entry><title type="html">Etlas: e-paper dashboard</title><link href="/log/etlas/" rel="alternate" type="text/html" title="Etlas: e-paper dashboard" /><published>2024-09-05T00:00:00+08:00</published><updated>2024-09-05T00:00:00+08:00</updated><id>/log/etlas</id><author><name>W. D. Sadeep Madurange</name></author><summary type="html"><![CDATA[Etlas is a news, stock market, and weather tracker powered by an ESP32 NodeMCU D1, featuring a 7.5-inch Waveshare e-paper display and a DHT22 sensor module.]]></summary></entry><entry><title type="html">Experimental e-reader</title><link href="/log/e-reader/" rel="alternate" type="text/html" title="Experimental e-reader" /><published>2023-10-24T00:00:00+08:00</published><updated>2023-10-24T00:00:00+08:00</updated><id>/log/e-reader</id><author><name>W. D. Sadeep Madurange</name></author><summary type="html"><![CDATA[This project features an experimental e-reader powered by an ESP-WROOM-32 development board and a 7.5-inch Waveshare e-paper display built with the intention of learning about e-paper displays.]]></summary></entry><entry><title type="html">Recreating the Matrix rain with ANSI escape sequences</title><link href="/log/matrix-digital-rain/" rel="alternate" type="text/html" title="Recreating the Matrix rain with ANSI escape sequences" /><published>2022-08-22T00:00:00+08:00</published><updated>2022-08-22T00:00:00+08:00</updated><id>/log/matrix-digital-rain</id><author><name>W. D. Sadeep Madurange</name></author><summary type="html"><![CDATA[Over the weekend, I came across Domsson’s Fakesteak: a beautifully lean rendition of the Matrix rain in raw C using ANSI escape sequences—zero dependencies, not even ncurses.]]></summary></entry></feed>
\ No newline at end of file diff --git a/_site/index.html b/_site/index.html index f279bc5..8b74fe9 100644 --- a/_site/index.html +++ b/_site/index.html @@ -173,7 +173,7 @@ <tr> <td class="posts-td posts-td-link"> - <a href="/log/matrix-digital-rain/" class="link-decor-none">The Matrix digital rain</a> + <a href="/log/matrix-digital-rain/" class="link-decor-none">Recreating the Matrix rain with ANSI escape sequences</a> </td> <td class="posts-td posts-td-time"> <span class="post-meta"> diff --git a/_site/log/index.html b/_site/log/index.html index 181a379..57887a7 100644 --- a/_site/log/index.html +++ b/_site/log/index.html @@ -163,7 +163,7 @@ <tr> <td class="posts-td posts-td-link"> - <a href="/log/matrix-digital-rain/" class="link-decor-none">The Matrix digital rain</a> + <a href="/log/matrix-digital-rain/" class="link-decor-none">Recreating the Matrix rain with ANSI escape sequences</a> </td> <td class="posts-td posts-td-time"> <span class="post-meta"> diff --git a/_site/log/matrix-digital-rain/index.html b/_site/log/matrix-digital-rain/index.html index 26244b3..ac4a536 100644 --- a/_site/log/matrix-digital-rain/index.html +++ b/_site/log/matrix-digital-rain/index.html @@ -2,12 +2,12 @@ <html> <head> <meta charset="utf-8"> - <title>The Matrix digital rain</title> + <title>Recreating the Matrix rain with ANSI escape sequences</title> <head> <meta charset="utf-8"> <meta name="viewport" content="width=device-width, initial-scale=1"> - <title>The Matrix digital rain</title> + <title>Recreating the Matrix rain with ANSI escape sequences</title> <link rel="stylesheet" href="/assets/css/main.css"> <link rel="stylesheet" href="/assets/css/skeleton.css"> </head> @@ -41,61 +41,30 @@ <main> <div class="container"> <div class="container-2"> - <h2 class="center" id="title">THE MATRIX DIGITAL RAIN</h2> + <h2 class="center" id="title">RECREATING THE MATRIX RAIN WITH ANSI ESCAPE SEQUENCES</h2> <h6 class="center">22 AUGUST 2022</h5> <br> - <div class="twocol justify"><p>“All I see is blonde, brunette, red head.” The iconic digital rain from The -Matrix in C, with zero dependencies—not even ncurses.</p> + <div class="twocol justify"><p>Over the weekend, I came across Domsson’s <a href="https://github.com/domsson/fakesteak" class="external" target="_blank" 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.</p> + +<p>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.</p> + +<p>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:</p> <video style="max-width:100%;" controls="" poster="poster.png"> <source src="matrix.mp4" type="video/mp4" /> </video> -<h2 id="overview">Overview</h2> - -<p>This is my fork of Domsson’s beautiful <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.</p> - -<p>My implementation supports:</p> - -<ul> - <li>Unicode characters.</li> - <li>24-bit RGB colors (truecolor).</li> - <li>Glitches in the matrix.</li> - <li>Ghosting effect of old monochrome CRT displays.</li> - <li>Closely resembles the Matrix seen in the background during Neo and Cypher’s -conversation.</li> -</ul> - -<p>With no dependencies, compilation is trivial:</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> - -<h2 id="how-does-it-work">How does it work?</h2> - -<p>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:</p> - -<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>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]); -} -</code></pre></div></div> - -<p>The ghosting effect is achieved by carefully scaling the RGB -channels before mixing them:</p> +<p>Adding Unicode support via <code class="language-plaintext highlighter-rouge">wchar_t</code> and <code class="language-plaintext highlighter-rouge">wprintf()</code> 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:</p> <div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>static void mat_shade(matrix *mat, size_t row, size_t col) { @@ -107,26 +76,25 @@ channels before mixing them:</p> } </code></pre></div></div> -<p>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.</p> - -<h2 id="customization">Customization</h2> +<p>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.</p> -<p>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.</p> +<p>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.</p> -<p>There are three color settings: head, tail, and background. You can configure -them using <code class="language-plaintext highlighter-rouge">COLOR_*_RED</code>, <code class="language-plaintext highlighter-rouge">COLOR_*_GRN</code>, and <code class="language-plaintext highlighter-rouge">COLOR_*_BLU</code> definitions found in -main.c.</p> +<p>Lastly, to compile and run:</p> -<p>The <code class="language-plaintext highlighter-rouge">UNICODE_MIN</code> and <code class="language-plaintext highlighter-rouge">UNICODE_MAX</code> values control the Unicode block used. For -example, setting them to <code class="language-plaintext highlighter-rouge">0x30A1</code> and <code class="language-plaintext highlighter-rouge">0x30F6</code> rains Katakana, if a font that -supports Katakana is present on the system:</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><img style="width: 100%;" src="katakana.png" /></p> +<p>“All I see is blonde, brunette, red head.”</p> <p>Files: <a href="source.tar.gz">source.tar.gz</a></p> </div> diff --git a/_site/posts.xml b/_site/posts.xml index 7b61271..a20233d 100644 --- a/_site/posts.xml +++ b/_site/posts.xml @@ -1 +1 @@ -<?xml version="1.0" encoding="utf-8"?><feed xmlns="http://www.w3.org/2005/Atom" ><generator uri="https://jekyllrb.com/" version="4.4.1">Jekyll</generator><link href="http://localhost:4000/posts.xml" rel="self" type="application/atom+xml" /><link href="http://localhost:4000/" rel="alternate" type="text/html" /><updated>2025-12-20T21:35:40+08:00</updated><id>http://localhost:4000/posts.xml</id><title type="html">ASCIIMX</title><author><name>W. D. Sadeep Madurange</name></author></feed>
\ No newline at end of file +<?xml version="1.0" encoding="utf-8"?><feed xmlns="http://www.w3.org/2005/Atom" ><generator uri="https://jekyllrb.com/" version="4.4.1">Jekyll</generator><link href="/posts.xml" rel="self" type="application/atom+xml" /><link href="/" rel="alternate" type="text/html" /><updated>2025-12-21T01:20:43+08:00</updated><id>/posts.xml</id><title type="html">ASCIIMX</title><author><name>W. D. Sadeep Madurange</name></author></feed>
\ No newline at end of file diff --git a/_site/projects/index.html b/_site/projects/index.html index 6cd47f3..2ef4c48 100644 --- a/_site/projects/index.html +++ b/_site/projects/index.html @@ -93,8 +93,8 @@ <td class="project-item"> <a href="../log/matrix-digital-rain" class="link-decor-none"> - <img src="../log/matrix-digital-rain/thumb_sm.png" alt="The Matrix digital rain"> - <h5>The Matrix digital rain</h5> + <img src="../log/matrix-digital-rain/thumb_sm.png" alt="Recreating the Matrix rain with ANSI escape sequences"> + <h5>Recreating the Matrix rain with ANSI escape sequences</h5> </a> </td> diff --git a/_site/robots.txt b/_site/robots.txt index d297064..e087884 100644 --- a/_site/robots.txt +++ b/_site/robots.txt @@ -1 +1 @@ -Sitemap: http://localhost:4000/sitemap.xml +Sitemap: /sitemap.xml diff --git a/_site/sitemap.xml b/_site/sitemap.xml index 442c589..e2c5b7e 100644 --- a/_site/sitemap.xml +++ b/_site/sitemap.xml @@ -1,55 +1,55 @@ <?xml version="1.0" encoding="UTF-8"?> <urlset xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.sitemaps.org/schemas/sitemap/0.9 http://www.sitemaps.org/schemas/sitemap/0.9/sitemap.xsd" xmlns="http://www.sitemaps.org/schemas/sitemap/0.9"> <url> -<loc>http://localhost:4000/log/matrix-digital-rain/</loc> +<loc>/log/matrix-digital-rain/</loc> <lastmod>2022-08-22T00:00:00+08:00</lastmod> </url> <url> -<loc>http://localhost:4000/log/e-reader/</loc> +<loc>/log/e-reader/</loc> <lastmod>2023-10-24T00:00:00+08:00</lastmod> </url> <url> -<loc>http://localhost:4000/log/etlas/</loc> +<loc>/log/etlas/</loc> <lastmod>2024-09-05T00:00:00+08:00</lastmod> </url> <url> -<loc>http://localhost:4000/log/arduino-due/</loc> +<loc>/log/arduino-due/</loc> <lastmod>2024-09-16T00:00:00+08:00</lastmod> </url> <url> -<loc>http://localhost:4000/log/bumblebee/</loc> +<loc>/log/bumblebee/</loc> <lastmod>2025-04-02T00:00:00+08:00</lastmod> </url> <url> -<loc>http://localhost:4000/log/my-first-pcb/</loc> +<loc>/log/my-first-pcb/</loc> <lastmod>2025-04-26T00:00:00+08:00</lastmod> </url> <url> -<loc>http://localhost:4000/log/arduino-uno/</loc> +<loc>/log/arduino-uno/</loc> <lastmod>2025-06-10T00:00:00+08:00</lastmod> </url> <url> -<loc>http://localhost:4000/log/mosfet-switches/</loc> +<loc>/log/mosfet-switches/</loc> <lastmod>2025-06-22T00:00:00+08:00</lastmod> </url> <url> -<loc>http://localhost:4000/log/fpm-door-lock/</loc> +<loc>/log/fpm-door-lock/</loc> <lastmod>2025-08-18T00:00:00+08:00</lastmod> </url> <url> -<loc>http://localhost:4000/log/suckless-software/</loc> +<loc>/log/suckless-software/</loc> <lastmod>2025-11-30T00:00:00+08:00</lastmod> </url> <url> -<loc>http://localhost:4000/about/</loc> +<loc>/about/</loc> </url> <url> -<loc>http://localhost:4000/</loc> +<loc>/</loc> </url> <url> -<loc>http://localhost:4000/log/</loc> +<loc>/log/</loc> </url> <url> -<loc>http://localhost:4000/projects/</loc> +<loc>/projects/</loc> </url> </urlset> |
