Bun Runner Devlog -- 2025-02-09
This week was all about improving asset loading and drawing some warmup graphics.
Before this week, the background graphics – the foreground columns and the
background art – were imported directly into the output binary with INCBIN, just for
simplicity in those early days when I was still flailing about with
Amiga development. I decided to load those in dynamically as XPK compressed
assets, much like how I load sprites.
I wanted to add unit tests for this, but ran into an issue with the
XPK library and
Vamos. Vamos fails to load the XPK library with the error
libmgr:WARNING: xpkmaster.library: init resident failed!. This means that
if I want to write tests against XPK, I need to run them on a “real” Amiga.
This was easy to set up in the test suite:
if (strcmp(argv[1], "xpk") == 0) {
printf("Running XPK tests, these only work on a real Amiga!\n");
XPKLoaderSuite(suite);
LevelDataReaderSuite(suite);
}
It did mean that, if (when!) I wrote code that would crash the Amiga, the dev cycle was a lot slower. But at least I have tests around the loader code now.
The next part is warmup graphics. I want the rabbit to, at the start of the game, stretch a bit before starting to run. That would take about three or four seconds to go through the poses, and it’ll be cute. After the rabbit crashes and the level restarts, I want to pick only one pose, then the crouching pose, then get the game started, so you don’t have to sit through the whole warmup after each death. Here’s the sprites for the poses I have so far:
Up to this point, this game has had no need for randomization, and I actually don’t want it for the level designs. I want them repeatable, to better facilltate muscle memory and speedruns. However, I do want to randomize the poses, so I needed something to help me generate randomness.
Last summer I went through a big FPGA practice experience, pushing my little
Go Board as far as I could, then eventually
getting a ULX3S to
go further. I decided to put that aside to work on this game, but I did learn
how FPGAs do randomization, and got reacquainted with it reading the
Wikipedia arcicle on Xorshift. I implemented a very simple Xorshift in
assembler that overwrites the seed value for later use, much like how you
would want to use amiga.lib/FastRand
but without needing to link in that library. Here’s the code. It’s super easy:
MOVE.L #1000,RandomSeed
MOVE.L #RandomSeed,A0
BSR randomizeLong ;=> RandomSeed contains new "random" value
RTS
RandomSeed DS.L 1
; Implement Xorshift LFSR
; https://en.wikipedia.org/wiki/Xorshift
; @inreg A0 uint32_t Memory location to randomize, using itself as the seed
randomizeLong:
MOVE.L (A0),D0
MOVE.L D0,D1
; 32 bit xorshift
; x ^= x << 13;
LSL.L #8,D0
LSL.L #5,D0
EOR.L D0,D1
MOVE.L D1,D0
; x ^= x >> 17;
LSR.L #8,D0
LSR.L #8,D0
LSR.L #1,D0
EOR.L D0,D1
MOVE.L D1,D0
; x ^= x << 5;
LSL.L #5,D0
EOR.L D0,D1
; write it back
MOVE.L D1,(A0)
RTS