summaryrefslogtreecommitdiffstats
path: root/_projects
diff options
context:
space:
mode:
Diffstat (limited to '_projects')
-rw-r--r--_projects/bumblebee.md8
-rw-r--r--_projects/matrix-digital-rain.md88
2 files changed, 81 insertions, 15 deletions
diff --git a/_projects/bumblebee.md b/_projects/bumblebee.md
index b322969..80acfe3 100644
--- a/_projects/bumblebee.md
+++ b/_projects/bumblebee.md
@@ -38,10 +38,10 @@ target="_blank" rel="noopener noreferrer">Scintilla.NET</a> editor), debounce
events, and block hidden elements and scripts.
Before settling on a desktop application, we contemplated designing Bumblebee
-as a browser extension. We decided against that because we didn't want the
-browser vendors to dictate Bumblebee's capabilities. Besides, the company's
-security policy, which prohibited browser extensions, would have complicated
-the deployment of an extension-based solution. The initial prototype used a C#
+as a browser extension. We chose the desktop app because extensions don't offer
+the deep, event-based control we needed. Besides, the company's security
+policy, which prohibited browser extensions, would have complicated the
+deployment of an extension-based solution. The initial prototype used a C#
wrapper of the Chromium project instead of WebView. WebView's more intuitive
API and its seamless integration with Windows Forms led us to choose it over
the Chromium wrapper.
diff --git a/_projects/matrix-digital-rain.md b/_projects/matrix-digital-rain.md
index f9a1a22..1b48d82 100644
--- a/_projects/matrix-digital-rain.md
+++ b/_projects/matrix-digital-rain.md
@@ -5,25 +5,91 @@ thumbnail: thumb.png
layout: post
---
-The famous digital rain from The Matrix, implemented in C.
+"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="thumb.png">
<source src="matrix.mp4" type="video/mp4">
</video>
-This project is a fork of Domsson's beautiful <a
+## Overview
+
+This is my fork of Domsson's beautiful <a
href="https://github.com/domsson/fakesteak" class="external" target="_blank"
-rel="noopener noreferrer">Fakesteak</a>.
+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.
+
+My version adds:
+
+ - Unicode character support.
+ - Fully customizable 24-bit RGB (truecolor) colors.
+ - 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
+```
+
+## How does it work?
+
+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:
+
+```
+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]);
+}
+```
+
+The ghosting effect, the signature feature of this implementation, works by
+scaling and mixing the RGB channels:
+
+```
+static void mat_shade(matrix *mat, size_t row, size_t col)
+{
+ unsigned char *color;
+ color = mat->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;
+}
+```
+
+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.
+
+## Customization
+
+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.
-There are three color settings: head, tail, and background. They are configured
-by setting the 24-bit RGB channels using `COLOR_*_RED`, `COLOR_*_GRN`, and
-`COLOR_*_BLU` 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.
+There are three color settings: head, tail, and background. You can configure
+them by setting the `COLOR_*_RED`, `COLOR_*_GRN`, and `COLOR_*_BLU` definitions
+in main.c.
-In addition, this implementation supports UTF-32 character sets. The
-`UNICODE_MIN` and `UNICODE_MAX` controls the Unicode block used. For
-instance, setting them to `0x30A1` and `0x30F6` rains Katakana:
+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):
<img style="width: 100%;" src="katakana.png" />