summaryrefslogtreecommitdiffstats
path: root/_site
diff options
context:
space:
mode:
authorSadeep Madurange <sadeep@asciimx.com>2025-12-12 23:16:51 +0800
committerSadeep Madurange <sadeep@asciimx.com>2025-12-12 23:16:51 +0800
commit5cab2b6a89097e0647295588e46901aaf049be65 (patch)
tree5f7f1f9aa692a8639a9ba6d3f5f1115bdb09fdb7 /_site
parent759669287a956f98664e2fb7a7688ef23c33a855 (diff)
downloadwww-5cab2b6a89097e0647295588e46901aaf049be65.tar.gz
Matrix post.term
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.html98
-rw-r--r--_site/robots.txt2
-rw-r--r--_site/sitemap.xml30
5 files changed, 104 insertions, 30 deletions
diff --git a/_site/feed.xml b/_site/feed.xml
index 444d5a0..ff9191d 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="http://localhost:4000/feed.xml" rel="self" type="application/atom+xml" /><link href="http://localhost:4000/" rel="alternate" type="text/html" /><updated>2025-12-12T23:16:15+08:00</updated><id>http://localhost:4000/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="http://localhost:4000/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>http://localhost:4000/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="http://localhost:4000/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>http://localhost:4000/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="http://localhost:4000/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>http://localhost:4000/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="http://localhost:4000/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>http://localhost:4000/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="http://localhost:4000/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>http://localhost:4000/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..803d3c7 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="http://localhost:4000/posts.xml" rel="self" type="application/atom+xml" /><link href="http://localhost:4000/" rel="alternate" type="text/html" /><updated>2025-12-12T23:16:15+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
diff --git a/_site/projects/matrix-digital-rain/index.html b/_site/projects/matrix-digital-rain/index.html
index 666456b..b69ac2d 100644
--- a/_site/projects/matrix-digital-rain/index.html
+++ b/_site/projects/matrix-digital-rain/index.html
@@ -44,23 +44,97 @@
<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, implemented in C, without 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>
+<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>. Use the following commands to compile
+and run the program:</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>While I loved Domsson’s take on the
+digital rain, what blew my mind was the minimalistic elegance of his code. As I
+carefully examined it, I thought about what it might take to recreate the
+original digital rain from the first Matrix movie with it. The challenge is
+adding these features without destroying fakesteak’s elegance.</p>
+
+<h2 id="how-does-it-work">How does it work?</h2>
+
+<p>The <code class="language-plaintext highlighter-rouge">matrix</code> struct makes use of three 2D arrays to encode the Matrix: the
+<code class="language-plaintext highlighter-rouge">code</code> array for 32-bit Unicode characters, the <code class="language-plaintext highlighter-rouge">rgb</code> array for 24-bit RGB
+values of the character (foreground color), and the <code class="language-plaintext highlighter-rouge">shade</code> array for the
+degree of transparency of the character to simulate the ghosting effect of old
+monochrome displays. The dimensions of these arrays depend on the size of the
+terminal screen. Each slot in the array corresponds to a cursor position on the
+screen.</p>
+
+<p>The ghosting effect, which is arguably the crowning feature of my version, is
+implemented by carefully 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 above algorithm achieves transparency by iteratively bringing the
+foreground color closer to the background color with each pass of the rain.
+This approach offers multiple advantages, such as simpler and more natural
+color configuration (background, foreground, and the color of the first drop)
+that lends itself well to Unix ricing, and of course, recreates The Matrix rain
+with high fidelity.</p>
+
+<p>Rather than heavy-weight graphics tool kits, we use ANSI escape codes to
+control the terminal screen. It’s the effective use of the ANSI escape codes
+that greatly contributes to the minimalism of the solution:</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>Finally, the glitch effect is controlled by the following code:</p>
+
+<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>if (mat.row[i] &gt; 0 &amp;&amp; rand() % 6 == 0) {
+ j = rand() % mat.row[i];
+ if (mat.code[mat_idx(&amp;mat, j, mat.col[i])] != ' ') {
+ mat_put_code(&amp;mat, j, mat.col[i]);
+ term_print(&amp;mat, j, mat.col[i]);
+ }
+}
+</code></pre></div></div>
+
+<p>The above code causes glitches in the Matrix with a probablity of 1/6.</p>
+
+<h2 id="customizing-the-rain">Customizing the rain</h2>
+
+<p>While you can customize almost any aspect of the rain including its speed,
+glitch frequency, and the density of the rain, the most useful settings for
+ricing are the color scheme and the character set used for the rain.</p>
+
+<p>There are three color settings: the head, the tail, and the background. They
+are configured 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. 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 instance, setting them to <code class="language-plaintext highlighter-rouge">0x30A1</code> and <code class="language-plaintext highlighter-rouge">0x30F6</code> rains
+Katakana code points:</p>
<p><img style="width: 100%;" src="katakana.png" /></p>
diff --git a/_site/robots.txt b/_site/robots.txt
index e087884..d297064 100644
--- a/_site/robots.txt
+++ b/_site/robots.txt
@@ -1 +1 @@
-Sitemap: /sitemap.xml
+Sitemap: http://localhost:4000/sitemap.xml
diff --git a/_site/sitemap.xml b/_site/sitemap.xml
index 1b23cd3..5130d9f 100644
--- a/_site/sitemap.xml
+++ b/_site/sitemap.xml
@@ -1,59 +1,59 @@
<?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>/blog/arduino-due/</loc>
+<loc>http://localhost:4000/blog/arduino-due/</loc>
<lastmod>2024-10-05T00:00:00+08:00</lastmod>
</url>
<url>
-<loc>/blog/arduino-uno/</loc>
+<loc>http://localhost:4000/blog/arduino-uno/</loc>
<lastmod>2025-04-10T00:00:00+08:00</lastmod>
</url>
<url>
-<loc>/blog/mosfet-switches/</loc>
+<loc>http://localhost:4000/blog/mosfet-switches/</loc>
<lastmod>2025-06-22T00:00:00+08:00</lastmod>
</url>
<url>
-<loc>/blog/neo4j-a-star-search/</loc>
+<loc>http://localhost:4000/blog/neo4j-a-star-search/</loc>
<lastmod>2025-09-14T00:00:00+08:00</lastmod>
</url>
<url>
-<loc>/blog/suckless-software/</loc>
+<loc>http://localhost:4000/blog/suckless-software/</loc>
<lastmod>2025-11-30T00:00:00+08:00</lastmod>
</url>
<url>
-<loc>/projects/e-reader/</loc>
+<loc>http://localhost:4000/projects/e-reader/</loc>
<lastmod>2023-10-24T00:00:00+08:00</lastmod>
</url>
<url>
-<loc>/projects/matrix-digital-rain/</loc>
+<loc>http://localhost:4000/projects/matrix-digital-rain/</loc>
<lastmod>2024-01-12T00:00:00+08:00</lastmod>
</url>
<url>
-<loc>/projects/etlas/</loc>
+<loc>http://localhost:4000/projects/etlas/</loc>
<lastmod>2024-09-05T00:00:00+08:00</lastmod>
</url>
<url>
-<loc>/projects/bumblebee/</loc>
+<loc>http://localhost:4000/projects/bumblebee/</loc>
<lastmod>2025-04-02T00:00:00+08:00</lastmod>
</url>
<url>
-<loc>/projects/my-first-pcb/</loc>
+<loc>http://localhost:4000/projects/my-first-pcb/</loc>
<lastmod>2025-07-14T00:00:00+08:00</lastmod>
</url>
<url>
-<loc>/projects/fpm-door-lock/</loc>
+<loc>http://localhost:4000/projects/fpm-door-lock/</loc>
<lastmod>2025-10-03T00:00:00+08:00</lastmod>
</url>
<url>
-<loc>/about/</loc>
+<loc>http://localhost:4000/about/</loc>
</url>
<url>
-<loc>/blog/</loc>
+<loc>http://localhost:4000/blog/</loc>
</url>
<url>
-<loc>/</loc>
+<loc>http://localhost:4000/</loc>
</url>
<url>
-<loc>/projects/</loc>
+<loc>http://localhost:4000/projects/</loc>
</url>
</urlset>