June 16, 2025
Deployment is done
Added a bunch of content to the site, not sure if this time should count towards SoM as I was mainly making markdown files, not actually coding things
Atom feeds and lists of projects and interesting things are done! Also <hr>s make the website look so much nicer
added some 88x31 buttons :)
Re-making my personal site using a custom html-only jekyll theme, inspired by @zrl's personal site. the lack of css is intentional.
Added the ability for player sprite animations to change depending on the state of the player, so jumping doesn't look stupid now ig. Also did some work on fixing collisions but im going to continue that tomorrow, spent a while thinking of the best way to do it and i think i came up with something half-decent perhaps
collisions are done!!!!!! here's a test scene (the artifacting is because phone camera)
oh my god ive been debugging this for the last 30 min and it's this max here that needs to be a min instead. collisions are close to done, it says 4h44min but it's probably a bit less in terms of normal human brain coding time, i code slowly when i'm low on sleep
Loading sounds from files works now! here's e1m1 because it seemed fitting
Static objects are a thing now, next I'll probably add level importing from LDTK, collisions and then start working on the demo! I'll probably delay font support until the third ship.
sprite animations!!!
i added the ability to flip sprites in the x-axis and also a 2d camera so that can be moved around, for example when the player moves to a different part of the level the camera moves too so that the player isn't offscreen. also spritesheet animation support is almost done, just need to write the tick function. got a lot done today.
writing this thing made me feel like an absolute genius, i think i'm starting to understand properly how rust works now. non-static lifetimes can die in hell, but other than that it's a decent language
Sprite loading works now!!! I encoded the png file from my pc using https://github.com/ArcaEge/embedded-encoder (that's my #siege project, so the time spent for that bit doesn't count here). I'm basically embedding the encoded spritesheet into the binary and it seems to work pretty well
screw memory usage and reliability, i gave up with static allocation and am now using dynamic allocation everywhere (fyi the size of my heap is only 64kb, this probably won't end well...)
why did i not write this in c???????? ughhhhhhhhhhh
i love rust lifetimes so much o_o
Audio in wasm works now, thanks a lot to whoever made the oscillator api
Sound support is done!! Well, not really, I still need to do the wasm bit but that's pretty simple and (hopefully) won't take too long. Also thanks @555 timer for permanently lending me these 15 passive buzzers
Busy trying to get sound working, here's a nice long comment I wrote :D
Implemented an actor-world system similar to greenfoot java, i.e. spent 6 hours building a fancy abstraction system to be able to draw this box:
Rectangles, yay!
Finally fixed that stupid bug causing the ssd1306 to get desynced. here's a cat because I don't have a better image to post.
Completely overhauled the input system to be a lot less stupid, this is across the last two devlogs. Also added a loading indicator to the canvas
yay, inputs work properly now on the pico!
Just did some soldering and stuff to repurpose this old controller I made a while ago, don't look at the solder joints on the back side :)
Got the demo working! Just need to compile it for the pico (I need to add the inputs to the pico HAL for that, maybe another hour or so of work, then I'm ready to deploy the demo somewhere and ship!)
Keyboard inputs in wasm work now!! That was quite annoying to do because it turns out that there's no API to get the current state of a key, you have to work it out yourself using event listeners. Time to make the demo! Then I'll do the first ship, and then add some quality-of-life features like builtin sprite rendering, but the core engine is basically done.
Display output in wasm is working! That went smoother than expected and I also made it a nice colour scheme. The canvas is pixel-perfect responsive (and all that logic is in rust because I'm not touching javascript with a metre stick if I can avoid it).
Lesson of the day: mixing async + non-async code = pure pain and suffering. I somehow made it work but it's pain. Also I still don't understand what the hell static lifetimes are but they seem to make the compiler happy. Anyway, delays in wasm work now and the code doesn't crash the main thread anymore. yay.
Next up is figuring out how to render to a canvas.
Refactored the project to be able to use wasm-pack and added a little webpack npm runner to run the devserver, printing stuff to the console works so we should be good. Just need to implement the HAL for wasm now, then I'll get inputs working, make a simple demo (maybe a dot moving around the screen controlled by wasd/arrows) and then ship the first version. I hope I can get that done by tonight.
Did some more work on individual pixel addressing and framebuffer stuff, here's a nice little pixel scanning across the screen row by row. Also ticks work now, I set the tick rate to ~60 ticks/sec. I need to work on the wasm side of things now, just need to create a HAL for web assembly.
Writing to the display now works! Here are some nice horizontal lines :D
Other stuff I've been up to:
- Added a 64KiB heap using embedded-alloc for dynamic memory allocation (don't need it now but will need it in the future)
- Implemented a generic framebuffer
- Found a bug/oversight in rp2040_hal (no good way to make two back-to-back i2c transactions without a stop/restart in between. logic analyser came in clutch for that one)
I added the function to initialise the display (the display's buffer is not cleared at startup so it makes this nice random pattern from the noise in the buffer, this isn't an issue as it goes away when you display the first frame). Next what I need to add is some function to put the pico's framebuffer data onto the display's framebuffer
I think I'm starting to figure out how Rust works but everything is taking 4x as long as it should because I'm still a clueless beginner to embedded Rust. I decided to say screw it, let's refactor the code because the old structure was stupid and hard to maintain, especially with 2 compile targets for pico and wasm. Speaking of wasm, I haven't done much in terms of that but I have started work on the ssd1306 driver code to drive the screen (I'm not using external crates for this because who likes to use libraries when you can do it yourself? It's pretty simple anyway because I'm just porting over the display driver code from my pico flappy bird project, which also used an ssd1306 but was written in C). Pictures are mandatory on devlogs, so here's a picture of the current setup I guess.
Clock and peripherals initialisations for the Pico are done, it took a while because this is one of my first projects using Rust and I was busy playing karate with the compiler
Did some boilerplate stuff, mostly just initialising the project structure and getting compilation to both RP2040 and WASM working.
A Rust-based monochrome pixel game engine that can be compiled to both web assembly (javascript canvas used for display) and also to the RP2040 microcontroller (which uses the monochrome SSD1306 display over I2C). I'm mainly making this so that I can bring hardware to Daydream (the final game apparently has to be uploadable to itch.io, hence the WASM support).
Didn't write too much code, just did a whole bunch of reading on the OSDev wiki and a bunch of experimentation (that's why hackatime recorded 2.5 hours). Managed to get a simple paged mode boot with vga text output but then decided to switch to Rust because a) I cba with C tooling, cargo is much better, b) I'd like to learn rust and c) rust cool and also memory safety I guess. Also updated README. Number 1 long term goal is to run Doom (doomgeneric makes that pretty simple by providing a hardware abstraction layer). But to do that, I first need other things (filesystem, proper colour and display output)
ALU is done. I added in extra flags because why not add flags? everyone likes flags. One for every pin of the accumulator and four general purpose flags too. Also logisim is glitchy now, the circuit decides whether it'll work or not depending on how and where you place it. yay.
It's done! I'm resetting the game by soft resetting the entire pi pico. Turns out that the Pico SDK didn't have a soft reset function (you can use watchdogs but that's janky and results in the pico locking up after reset occasionally for some reason? I think it might be an I2C-related thing as I wasn't resetting the display). So I had to write a value to the AIRCR register (standard register across many ARM cortex M-series chips I believe) in order to reset the RP2350. Anyway, the entire game is fully functional and done now :D
This was widely regarded as a great move by everyone.