You do not need an alternate keyboard layout like Colemak or Dvorak to type fast. Nor do you need to learn to use the QWERTY “home row keys.” All it takes is a misspent youth and muscle memory.
My typing teacher in high school wasn’t my biggest fan. I won the class typing competitions without using the “proper” techniques she taught. I could tell it pained her to give me the prizes.
Back around the time the first iPhone was released (feeling old! 😬) I was taking a course where we built a CPU-based ray tracer in C.
If you’re not familiar with the ray tracing technique, check it out here.
What I mostly remember from the course was math, pointers, and segfaults. Oh the segfaults. By the end of the course, however, I had a decent grasp on C and that’s been a valuable skill so many times in my career and hobbies.
How the original project functioned
You wrote an input file that describes various shapes, light sources, and attributes of the environment.
You fed the file into the C program.
You waited a bit (remember, we’re doing everything on the CPU in ~2007).
You got a fancy PPM file. (PPM was a great image format due to its simplicity – we were dealing with enough!)
Wasm motivation
Recently I decided that I wanted to learn more about the inner workings of WebAssembly (Wasm) and figured this would be a great candidate project. It’s fully contained without any external dependencies, *I wrote all the code so it shouldn’t be too mysterious, and if I got it to work there would be a visual payoff.
*Feel free to judge some of the rough spots in the code – it was a long time ago!
Process
The first thing I made sure of was that I could compile the project locally the non-Wasm way. There were no hiccups there – it worked on the first try using the Makefile. ✅
I then started reading this tutorial on converting a C project to Wasm. After installing emscripten on macOS (I used Homebrew) I decided to add a new C source file to the project and added a function that looked something like:
#include "emscripten.h"
EMSCRIPTEN_KEEPALIVE
int version() {
return 42;
}
If I could get this to work I could at least get information from C -> JS for starters. All that it took to make this work was:
Substituting gcc with emcc in the Makefile
Making sure I added the EXPORTED_RUNTIME_METHODS='["cwrap"]' compiler flag
Calling Module.cwrap from JS to use the function
That was pretty much it. I’m not going to go super in-depth with this blog post because I think most of it can be figured out from the source.
Next challenges
I had a bit more to go but was surprised at how easy it was to send a value from C to JS. The next items to figure out were:
The ray tracer expected an input file and an output file, how would this work with a browser?
We can pass integers easily, but what about the big array of pixel data when we ultimately generate an image?
Where would our C calls to fprintf and its siblings go when trying to debug to stdout and stderr?
What about main – does it run?
I’ll go ahead and spoil these really quickly in their respective order:
fmemopen saved the day by taking the input string (which is a char *) and providing a FILE type in return which is an in-memory buffer stream. In other words, no massive overhauling needed although we aren’t using “real” files anymore. In addition a slight refactoring was done to the project to return an array of pixels rather than write out an image file.
They automagically show up in the browser console! This is a really nice feature, and stderr calls are even properly displayed as errors.
Yes! In my case I got rid of it because it was prompting for the CLI input, but it was interesting to see that it automatically ran. There may be a compiler setting to disable this.
A summary of what it took to convert the ray tracer to Wasm
I really hate to brag, but I wanted to share this life achievement. The Pinball Arcade Trial running on Windows 98 informed me that I got the highest score possible for the trial version.
Some front yard shots from the geomagnetic storm on May 10th, 2024. I never thought we’d see one of these in South Carolina!
The sky wasn’t as vibrant to the naked eye due to all the ambient light in my neighborhood, but the iPhone 15 Pro’s sensor picked it up great with a three second exposure.
Hot swappable switches – in case I get bored with Gateron Browns.
Made out of aluminum – a sturdy 5 lbs!
Knobs are cool.
South-facing RGB LEDs.
Has a handy switch to toggle between Mac and PC modes.
After an hour or so of using it, so far so good! It’s exactly what I hoped it’d be, and a leap in modernization and build quality from the New Model M that I’ve been running. I’ll still use Buckling Springs on my retro machines, of course, but it’s so nice to have LEDs, a knob for volume, dedicated function keys for brightness and Spaces, and the flexibility to do whatever I want with custom firmware. 😎
Muir BeachMuir WoodsRichmond Marina BayTilden Park Merry Go RoundCable CarLiving Roof at CASClaude the albino alligatorOsher RainforestFish in CAS AquariumJellyfish in CAS AquariumIndian Rock
I didn’t get out much in Munich as it was an intense week of work, but one morning I did take a walk in the park that borders the Eisbach river. It was cold, rainy, and quite enjoyable.
I’m starting to dust off some seasonal projects and realized I hadn’t made this simple tool public which others may find handy. With projects like the NeoPixel Tree it can be much quicker to code visual sequences locally instead of waiting for new firmware to upload to the MCU every time you want to tweak something.