summaryrefslogtreecommitdiffstats
path: root/_site
diff options
context:
space:
mode:
Diffstat (limited to '_site')
-rw-r--r--_site/feed.xml2
-rw-r--r--_site/posts.xml2
-rw-r--r--_site/projects/matrix-digital-rain/index.html89
3 files changed, 79 insertions, 14 deletions
diff --git a/_site/feed.xml b/_site/feed.xml
index 444d5a0..8cfe80e 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="/feed.xml" rel="self" type="application/atom+xml" /><link href="/" rel="alternate" type="text/html" /><updated>2025-12-12T19:52:43+08:00</updated><id>/feed.xml</id><title type="html">ASCIIMX | Blog</title><author><name>W. D. Sadeep Madurange</name></author><entry><title type="html">How I manage Suckless software installations</title><link href="/blog/suckless-software/" rel="alternate" type="text/html" title="How I manage Suckless software installations" /><published>2025-11-30T00:00:00+08:00</published><updated>2025-11-30T00:00:00+08:00</updated><id>/blog/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">Neo4J A* search</title><link href="/blog/neo4j-a-star-search/" rel="alternate" type="text/html" title="Neo4J A* search" /><published>2025-09-14T00:00:00+08:00</published><updated>2025-09-14T00:00:00+08:00</updated><id>/blog/neo4j-a-star-search</id><author><name>W. D. Sadeep Madurange</name></author><summary type="html"><![CDATA[Back in 2018, we used Neo4J graph database to track the movement of marine vessels. We were interested in the shortest path a ship could take through a network of about 13,000 route points. Algorithms based on graph theory, such as A* search, provide optimal solutions to such problems. In other words, the set of route points lends itself well to a model based on graphs.]]></summary></entry><entry><title type="html">MOSFETs as electronic switches</title><link href="/blog/mosfet-switches/" rel="alternate" type="text/html" title="MOSFETs as electronic switches" /><published>2025-06-22T00:00:00+08:00</published><updated>2025-06-22T00:00:00+08:00</updated><id>/blog/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="/blog/arduino-uno/" rel="alternate" type="text/html" title="How to configure ATmega328P microcontrollers to run at 3.3V and 5V" /><published>2025-04-10T00:00:00+08:00</published><updated>2025-04-10T00:00:00+08:00</updated><id>/blog/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">How to set up ATSAM3X8E microcontrollers for bare-metal programming in C</title><link href="/blog/arduino-due/" rel="alternate" type="text/html" title="How to set up ATSAM3X8E microcontrollers for bare-metal programming in C" /><published>2024-10-05T00:00:00+08:00</published><updated>2024-10-05T00:00:00+08:00</updated><id>/blog/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></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-13T14:22:49+08:00</updated><id>/feed.xml</id><title type="html">ASCIIMX | Blog</title><author><name>W. D. Sadeep Madurange</name></author><entry><title type="html">How I manage Suckless software installations</title><link href="/blog/suckless-software/" rel="alternate" type="text/html" title="How I manage Suckless software installations" /><published>2025-11-30T00:00:00+08:00</published><updated>2025-11-30T00:00:00+08:00</updated><id>/blog/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">Neo4J A* search</title><link href="/blog/neo4j-a-star-search/" rel="alternate" type="text/html" title="Neo4J A* search" /><published>2025-09-14T00:00:00+08:00</published><updated>2025-09-14T00:00:00+08:00</updated><id>/blog/neo4j-a-star-search</id><author><name>W. D. Sadeep Madurange</name></author><summary type="html"><![CDATA[Back in 2018, we used Neo4J graph database to track the movement of marine vessels. We were interested in the shortest path a ship could take through a network of about 13,000 route points. Algorithms based on graph theory, such as A* search, provide optimal solutions to such problems. In other words, the set of route points lends itself well to a model based on graphs.]]></summary></entry><entry><title type="html">MOSFETs as electronic switches</title><link href="/blog/mosfet-switches/" rel="alternate" type="text/html" title="MOSFETs as electronic switches" /><published>2025-06-22T00:00:00+08:00</published><updated>2025-06-22T00:00:00+08:00</updated><id>/blog/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="/blog/arduino-uno/" rel="alternate" type="text/html" title="How to configure ATmega328P microcontrollers to run at 3.3V and 5V" /><published>2025-04-10T00:00:00+08:00</published><updated>2025-04-10T00:00:00+08:00</updated><id>/blog/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">How to set up ATSAM3X8E microcontrollers for bare-metal programming in C</title><link href="/blog/arduino-due/" rel="alternate" type="text/html" title="How to set up ATSAM3X8E microcontrollers for bare-metal programming in C" /><published>2024-10-05T00:00:00+08:00</published><updated>2024-10-05T00:00:00+08:00</updated><id>/blog/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></feed> \ No newline at end of file
diff --git a/_site/posts.xml b/_site/posts.xml
index f9d56bb..844a600 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="/posts.xml" rel="self" type="application/atom+xml" /><link href="/" rel="alternate" type="text/html" /><updated>2025-12-12T19:52: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
+<?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-13T14:22:49+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/matrix-digital-rain/index.html b/_site/projects/matrix-digital-rain/index.html
index 666456b..2893c92 100644
--- a/_site/projects/matrix-digital-rain/index.html
+++ b/_site/projects/matrix-digital-rain/index.html
@@ -44,23 +44,88 @@
<h2 class="center" id="title">THE MATRIX DIGITAL RAIN</h2>
<h6 class="center">12 JANUARY 2024</h5>
<br>
- <div class="twocol justify"><p>The famous digital rain from The Matrix, implemented in C.</p>
+ <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>
<video style="max-width:100%;" controls="" poster="thumb.png">
<source src="matrix.mp4" type="video/mp4" />
</video>
-<p>This project is a fork of Domsson’s beautiful <a href="https://github.com/domsson/fakesteak" class="external" target="_blank" rel="noopener noreferrer">Fakesteak</a>.</p>
-
-<p>There are three color settings: head, tail, and background. They are configured
-by setting the 24-bit RGB channels 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. The ghosting effect of old monochrome screens is
-achieved by scaling the RGB channels. This results in a rain effect that
-closely resembles the original from the first Matrix movie.</p>
-
-<p>In addition, this implementation supports UTF-32 character sets. The
-<code class="language-plaintext highlighter-rouge">UNICODE_MIN</code> and <code class="language-plaintext highlighter-rouge">UNICODE_MAX</code> controls the Unicode block used. For
-instance, setting them to <code class="language-plaintext highlighter-rouge">0x30A1</code> and <code class="language-plaintext highlighter-rouge">0x30F6</code> rains Katakana:</p>
+<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 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.</p>
+
+<p>My version adds:</p>
+
+<ul>
+ <li>Unicode character support.</li>
+ <li>Fully customizable 24-bit RGB (truecolor) colors.</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 - 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:</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-&gt;rgb[idx].color[R],
+ mat-&gt;rgb[idx].color[G],
+ mat-&gt;rgb[idx].color[B],
+ mat-&gt;code[idx]);
+}
+</code></pre></div></div>
+
+<p>The ghosting effect, the signature feature of this implementation, works by
+scaling and mixing the RGB channels:</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)
+{
+ unsigned char *color;
+ color = mat-&gt;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;
+}
+</code></pre></div></div>
+
+<p>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.</p>
+
+<h2 id="customization">Customization</h2>
+
+<p>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.</p>
+
+<p>There are three color settings: head, tail, and background. You can configure
+them by setting the <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
+in main.c.</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>
<p><img style="width: 100%;" src="katakana.png" /></p>