Day 3: not much progress. I’ve added a little code to render a basic
game map, but most of my time has been taken up by
a bug in the Rust
ncurses bindings, which prevented
special “ACS” characters from displaying.
I spent three hours last night tracking down the bug, on the hunch
that Rust wasn’t correctly finding the array where the codes for the
special characters were kept (
acs_map). Long story short, after
looking through the disassembly of the game1, I found that the
function that accesses
acs_map was essentially a no-op:
After figuring that out, the question was how to get Rust to properly
read the array.
acs_map is a static global array (not a pointer to
one), and was currently declared as
[chtype; 0] (0 length because we
don’t know the length).
*const chtype caused
[chtype; 128] worked, and looking at the generated
assembly, I saw that Rust was
memcpying the array. I think this is
because arrays implement
Copy. The accessor function basically
looked like this:
so Rust would copy the array…except it was told the array was 0-size,
so it did nothing, expecting that you wouldn’t be so naïve as to try
and dereference it, which of course we were. The solution was to cast
the base of the array to a pointer before accessing it, preventing
Rust from trying to
memcpy. Adding the length “fixed” it because
then Rust copied over the data we were trying to access first.
I’ve filed a pull request to fix the bug. Next up: actually rendering the programs you control. I’ll be talking a little more about game mechanics soon.
I’m terrible at reading AMD64 assembly, as we’re taught MIPS at school, never mind the fact that the Rust-generated assembly is a lot messier than C’s. ↩