I’ve always enjoyed short, snappy little projects that deliver a quick dose of dopamine, and I’m a big fan of CodePen as a way to exercise that ‘tinker and play’ attitude.
One of my earlier and more involved pens was the result of a thought: “What if 8-bit but open world?”. A great candidate seemed to be Jet Set Willy, and luckily there’s an absolutely excellent disassembly of the game available. It was fascinating to dive into the data and see how efficiently everything was packed in there while remaining pretty readable. Before the days of widespread fast and convenient compression, programmers just squeezed things down to the last bit.
I ended up writing various routines to process things in a way that looked true to the original, including figuring out how to parse the attributes (the way the Speccy encoded colour and more into 8×8 pixel blocks with a single byte) and generate all of the graphics, rooms and movement patterns.
It’s not complete unfortunately – the arrows and the rope swinging routine got the better of me at the time, but I still think it’s still a really cool little bit of nostalgia, and decently structured (for the time at least; this is pre-ES6 JavaScript).
Anyway, here it is in all its glory. Enjoy!
I quite like the big comment attempting to explain all the bitwise stuff:
// The attribute format is a single byte containing 2x 1-bit values for flash and bright, then 2x 3-bit values for paper and ink
// So the value 221 (binary 11011101) broken down becomes flash 1 (1), bright 1 (1), paper 011 (3) and ink 101 (5)
// To extract these, we perform up to two operations:
// 1. We perform a bitwise AND on the value with a bitmask of corresponding length for how many bits you want to extract - if
// we're looking for a boolean here (using a single bit in the mask), we can just coerce it with the !! operator as the outcome
// will be zero for false and non-zero for true
// 2. We perform a bitwise shift to the right so that the bits we're interested in are at far right side
//
// Examples:
// To get the bright value (1 - true) from 221 (11011101):
// 221 & 64 = 64 (binary: 11001101 AND 01000000 becomes 01000000)
// !!64 = true (binary: 01000000 is non-zero, so it becomes true)
//
// To get the paper value (3) from 221 (11011101):
// 221 & 56 = 24 (binary: 11011101 AND 00111000 becomes 00011000)
// 24 >> 3 = 3 (binary: 00011000 shifted right 3 times becomes 00000011)
//
// Quite a nice explanation of what you can do with bitwise operators can be found here:
// https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Operators/Bitwise_Operators
//
// P.S. I revised this whole intro in September 2020 as I realised I didn't understand bitwise operations as well as I should
// have. Littered throughout this code are examples of the old inefficient method of "shift then and", as opposed to the
// 'correct' way of doing things (especially for single bits). No doubt there's more on this for me to learn but it's good to
// be honest.
I’ll write up a few more of these for other pens I’ve done if there’s any interest. Let me know in the comments or via one of my socials if you’d like to know more about any of these, or indeed anything else I’ve done!