I was a bit under the weather over the last weekend, but that gave me plenty of time to work on this project. I’ve taken a roundabout way to get there, but I think I can say this is no longer the worst map editor ever.
I’ve been working on the map editing functionality, and a lot of that comes down to menus and selecting tiles and so on. I went into this without a really good idea of how I wanted the UI to look and went through creating a lot of pretty awkward screens until it started to come together.
What I really needed was to be able to select different terrain types and entities without leaving the main map screen. There was just enough space on the right-hand side of the screen for a list of terrain types, so that I could select one from the list and highlight it. This was a big step forward from my first iteration, which had dedicated key bindings for each terrain type – ‘m’ for mountain and so on. That was never going to scale well.
What really made the terrain editing come together was a “paint mode” toggle. With the toggle on, I can just move around on screen to paint the ground with the active terrain type. This is so much faster and easier, and it’s really a pleasure to use.
In order to really test out the system, I had to add a bunch more terrain types and entity types. I haven’t added graphics for all of them yet, but there’s enough there that it’s starting to look like a real game.
Of course, there’s more to creating the map than just plopping down terrain tiles, so there’s still a streamlined set of dedicated screens for controlling the details. There’s not much on the Entities screen yet because there’s not much to entities. Right now, each entity is just a location, a type, and a one-byte value. For creatures, the value could represent hit points. For a town, it’s the number of the map you move to when you enter the town, and so on.
I went through a number of approaches to the map screens before finally consolidating loading, saving, and editing map properties onto a single screen.
As I’ve been working on this, I’ve learned a lot more about how the games that inspired me were written, and how the design choices I’ve made compare to them. For instance, I’m using the C64’s character graphics mode with a custom character set for the main screen. That means I can redraw the map window (13 x 11 tiles ) by writing just 1144 bytes of character and color data. But it also means I’ve only got 256 unique character glyphs to work with.
By comparison, Ultima IV apparently uses the C64’s “high res” mode – a 320×200 bitmapped screen where each 8×8 pixel box uses a single foreground color. The map displays an 11 x 11 grid of 16 x 16 pixel tiles from a set of 256 tiles. That’s 8 KB just for the tile maps, and almost 8 KB for the bitmap itself. Oh, and there’s a custom character set in addition to the map tile data! That’s a huge amount of memory, and I don’t know how they squeezed it all in.
I’m not out of memory yet, but things are starting to get a bit snug inside the C64’s address space. My executable has inflated to a whopping 28 KB, and there’s only about 4 KB left of the space that I’ve set aside for CC65 programs to use. As for the 16 KB that I reserved for fixed-location data structures and buffers, I’ve got 9 KB left – but there’s lots of stuff I haven’t implemented yet.
The good news is that there’s a nice chunk of unused RAM at the top of memory, but there’s also a catch. The C64 famously has 64 KB of RAM, but it also has 20 KB of ROM, and the I/O devices also get mapped into locations in memory. In order to fit all that on a machine with a 64 KB address space, there’s a lot of bank switching going on. I can use the 12 KB that overlap the KERNAL ROM and I/O devices – I just can’t do anything that requires a KERNAL routine or uses the audio or video chips while the RAM is mapped into the address space. So it will be interesting to figure out what that RAM can be good for.
Really though, this thing is just about too big to be a single program. Sooner or later I’m going to have to split it up, and figure out how to load just the routines I need and swap between different modes. I’m not sure if I’ll have to do that before the end of the month, but I’m sure if I do I’ll find out the hard way.