Mr Speaker

mrspeaker's head in a monitor You find yourself at the entrance to the Hompage of Mr Speaker. In a darkened corner sits a trunk containing HTML5 games and some JavaScript tidbits. Next to it you spy a ■■■■■■■ account. Exits are North, East, and .

Your Last Ever Computer

I gaze across the calm morning ocean as I sip my coffee. The computer takes a while to boot, and watching the ocean is more relaxing than the torrent of kernel messages that (hopefully) say things are loading nominally.

I wonder if there will be any deliveries today. It's been a while, and recent weather has not been good.

A login prompt appears. I mindlessly enter my password. I should really just get rid of the prompt but it's a comforting tidbit of nostalgia. Makes me feel like work is about to happen. Hmm, what to work on though? I'm not sure yet. Something fun.

Read on for more »

Basic-er BASIC


Today I wrote an "eBASIC" code snippet that contained a macro. The macro expansion included another macro that when expanded generated 6502 assembler code - which itself happened to contain a KickAssembler macro: that in turn generated its own 6502 assembler. The result of the entire macro formed part of a BASIC program that POKEd the assembled bytes into memory and called the machine code via SYS. The final BASIC program was then compiled back to machine language as a .prg file and run in a JavaScript Commodore 64 emulator. The output of the running emulator was used as an input texture to a WebGL shader, and rendered as the screen of a 3D model of a C64 computer monitor, updating 60 times a second.

This is the story of the funnest thing I've worked on, ever.

It started as a simple text-munging script to "save some time" while writing Commodore 64 BASIC. It ballooned into eBASIC: a cornucopia of scope-creepy feature additions. File includes, macros, inline 6502 assembly compilation... I estimate I'll have to write at least fifty BASIC programs to break-even, in regards to the amount of time spent on my eBASIC-to-BASIC tool.

eBASIC -> BASIC tranformation Read on for more »

NBA Jam, um, tank-mode?

Eight minutes ago I had a flashback. The following is my stream-of-consciousness account of those eight minutes. I refuse to google it to see if it's true, or if I imagined the whole thing.

big-head Pippen in Battlezone

The year was… 1992? 1993? I was playing the hit arcade game NBA Jam. A lot. I remember playing NBA Jam a lot. At the time the NBA was huge where I lived. I spent uncountable weekends delivering newspapers so I could blow it all on a pair of Jordan 5s, and let me tell you - I loved those shoes.

Anyway, one day I was at the local bowling-alley arcade with a friend. We'd heard a rumour that you could use whipper-snipper (weed eater/weedwacker in other countries) wire - bend it into a square shape that had edges the same radius as a coin - and push it into the coin slot of arcade machines to get free credits.

After an hour or so we concluded that it wasn't true at all. We reverted to real money.

Buuut, also, someone else had also told us about a new cheat code for NBA Jam! Of course everyone knew the "Big Head" cheats (a cousin's friend's cousin's friend told me about that one), but apparently there was another better one. A very elaborate one. One that would trigger a whole new game!

Read on for more »

Why WebGL colors don’t look like Blender colors

The following is an account of my embarrassing ignorance on color spaces, gamma correction, and pretty-much everything to do with how a computer outputs things to a monitor.

Recently I've been kicking around an idea for probably the greatest retro-video-game game of all time. I'm 40% sure it will be amazing and spawn a whole new genre of games. I'm also 60% sure it will be not as fun as I imagine, so I thought I'd better test it out first.

As part of prototyping I made some placeholder models in Blender. I added textures to a couple of the models, but - in the interests of saving time - assigned simple solid colors for the rest.

Blender model of my bedroom in the 80s

Next I exported the file as an .obj file and wrote a parser to read the vertex data and materials. These could then be displayed in the browser using WebGL2, as seen in the screen shot below.

Everything (except for the crazy PETSCII background and the C64 computer display) is rendered using a single vertex shader and a single fragment shader.

WebGL rendering of my bedroom in the 80s

With the scene-renderer working ~fine~ (well, considering the limited amount of work I put into the shaders) it was time to move on to the game logic... but something was bugging me.

Read on for more »

USB Mini Shawarma

Years ago I had a genius idea of making a USB-powered mini shawarma machine that you could have on your desk, and shave off bits of meat during the day. Sometimes I still lay awake at night, wondering if that would have worked.

And… goodbye JavaScript!

When I de-bloated my piece of the web, I noted that the largest asset I was serving on my blog was a local version of jQuery - coming in at some 70+ kilobytes - that "I still need to insert into the head of my page for historical reasons: 15 years ago I in-lined lots of my wacky JavaScript experiments".

But things change: we are now in the middle of a bloat-a-demic. Web sites are tracking and expanding far beyond sustainable levels... and emergency measures must be taken.

So I have done the unthinkable. I have pulled the plug on JavaScript on my blog. All of it. Now the total number of network requests (not counting any images inside of posts) comes in at six (6):

  • / : 35k
  • style.css : 7.7k
  • mrman-up.jpg : 43k
  • mrspeaker.png : 17k
  • mrman.jpg : 43k
  • favicon.ico : 1.5k

And `mrman.jpg` and `mrman-up.jpg` are the same image, flipped vertically - so I should certainly lose one of them. 1.5k for a favicon seems a bit hefty - I should check that. And I did some more tweaking of my old php software and made the html output prettier and leaner, but I'm sure there's more to improve in there too.

Naturally, "no scripts" means my wacky JavaScript experiments have been killed dead… and that simply can not stand. I'll commence the long process of de-jquery-fying them and making them run stand-alone (mostly they were just using JQuery for the `$(document).ready` anyways).

But it feels pretty good to go cruft-free. Having dropped the kilobytes (down originally from around 5Mb (!) to around 200k for a full page of posts) I feel like a whole new webmaster. A giant weight has been lifted.

Until the next big web trend comes along, of course.

Monads for Babies

Monads for Babies is the first in a series that teaches computer science to toddlers. It's only available in digital form at the moment (png format, embedded below), so I suggest `right-click -> print` so you can read it to the lil' tigers at bed time:

Support my Patreon if you'd like to see more.

A most useful function

Hot on the heels of my web colors rant, comes this amazing piece of Emacs Lisp I now have in my init file:

(defun web-color ()
  (let ((cols '("AliceBlue" "AntiqueWhite" "Aqua" "Aquamarine"
     "Azure" "Beige" "Bisque" "Black" "BlanchedAlmond" "Blue"
     "BlueViolet" "Brown" "BurlyWood" "CadetBlue" "Chartreuse"
     "Chocolate" "Coral" "CornflowerBlue" "Cornsilk" "Crimson" "Cyan"
     "DarkBlue" "DarkCyan" "DarkGoldenRod" "DarkGray" "DarkGreen"
     "DarkKhaki" "DarkMagenta" "DarkOliveGreen" "Darkorange" "DarkOrchid"
     "DarkRed" "DarkSalmon" "DarkSeaGreen" "DarkSlateBlue" "DarkSlateGray"
     "DarkTurquoise" "DarkViolet" "DeepPink" "DeepSkyBlue" "DimGray"
     "DodgerBlue" "FireBrick" "FloralWhite" "ForestGreen" "Fuchsia"
     "Gainsboro" "GhostWhite" "Gold" "GoldenRod" "Gray" "Green"
     "GreenYellow" "HoneyDew" "HotPink" "IndianRed" "Indigo" "Ivory"
     "Khaki" "Lavender" "LavenderBlush" "LawnGreen" "LemonChiffon"
     "LightBlue" "LightCoral" "LightCyan" "LightGoldenRodYellow"
     "LightGray" "LightGreen" "LightPink" "LightSalmon" "LightSeaGreen"
     "LightSkyBlue" "LightSlateGray" "LightSteelBlue" "LightYellow" "Lime"
     "LimeGreen" "Linen" "Magenta" "Maroon" "MediumAquaMarine" "MediumBlue"
     "MediumOrchid" "MediumPurple" "MediumSeaGreen" "MediumSlateBlue"
     "MediumSpringGreen" "MediumTurquoise" "MediumVioletRed" "MidnightBlue"
     "MintCream" "MistyRose" "Moccasin" "NavajoWhite" "Navy" "OldLace"
     "Olive" "OliveDrab" "Orange" "OrangeRed" "Orchid" "PaleGoldenRod"
     "PaleGreen" "PaleTurquoise" "PaleVioletRed" "PapayaWhip" "PeachPuff"
     "Peru" "Pink" "Plum" "PowderBlue" "Purple" "Red" "RosyBrown" "RoyalBlue"
     "SaddleBrown" "Salmon" "SandyBrown" "SeaGreen" "SeaShell" "Sienna"
     "Silver" "SkyBlue" "SlateBlue" "SlateGray" "Snow" "SpringGreen"
     "SteelBlue" "Tan" "Teal" "Thistle" "Tomato" "Turquoise" "Violet"
     "Wheat" "White" "WhiteSmoke" "Yellow" "YellowGreen")))
    (insert (nth (random (length cols)) cols))))

Calling it with `M-x w-c` (from anywhere you care to type things) injects a random entry - so you get a wonderful rainbow of weird names, instead of forgetting them all every time and just choosing "lemonchiffon".

Debugging has never looked so good.