So while I’m still trying to figure out various details of the engine, I decided to finally start writing some engine code myself instead of having a bundle of tools to do just one task.
The main annoyance is loading files in Rust. Since the game was designed for case-insensitive filesystems, the directories and files may have names in lowercase, uppercase or mixed. And since certain operating system chose the radically different approach to the Unicode encoding format for the filenames, Rust has OsString
in order to handle those external names properly. As the result in order to find the proper name corresponding to the file (e.g. “data/qgm/160.qgm” may be really names “DATA/Qgm/160.QGM”) I have to split path, convert it to an internal string in order to perform case-insensitive comparison and reconstruct the full path again. It’s not complicated but still annoying.
After dealing with this nuisance, I’ve moved to decoding graphic formats. For instance, I could finally dump all sprites and room backgrounds to inspect them better. And in order to do that I could simply create an archive object for loading data, image buffer object to paint room background and/or sprites to, and some objects to decode and paint the actual data.
Here is room 260, the bedroom in Gnome Ann’s Inn that serves as the starting point for the multiplayer games (except that it was cut and it takes some effort to see it):
If you’re familiar with the game you can see that it is not a simple mirror image of the usual single-player bedroom (the pictures are different as well as the chest placement). A subtler thing to notice is that on my picture the floorboards are curved while they look straight in the game—those would be too if I managed to implement the cylindrical mapping the game uses to project the background (I hope to get to it eventually). But since this is not that much fun by itself, here’s a GIF of the room with some of the sprites in place (beware of the size, it can hardly fit on a floppy). If some of them look wrong it’s because they were taken from the single-player bedroom and mirrored (funny enough, there’s a sprite for the second chest taken from there as well).
Speaking about the sprites, I’ve finally figured out why some of the sprites are rotated and some are not. As it turns out, there’s the following hierarchy: each room may have several views (e.g. slightly different views of the arena, front and back parts in the Hall of Kings or overall docks panorama with a specific Pholus shop close-up) and each of the view may have up to a hundred sprites associated with it. So e.g. multi-player bedroom has number 260, its only view has number 2600, and torches in it have sprites number 260000 and 260001 while chests have sprites number 260095 and 260096 correspondingly (with no other sprite numbers between them). Room 900 is a map that uses the standard BMP file for its background while points of interest on it are individual sprites (as well as the map you can see if you look at the inventory map).
So all of the room-associated sprites (except for map markers) are stored in rotated form while various GUI-related sprites (with the numbers in 1xxxxx range) are not.
And if you care about specific GUI sprite numbers, here’s a short list:
- 100000-100006: main window GUI elements
- 100010-100181 (but not 100100): character and monster portraits (with various expressions if they have spoken lines);
- 100100, 100200-101001, 101003: various GUI elements for dialogue windows
- 101002: small icons for all inventory items (as well as spells and paladin abilities);
- 101101-101607: animated items (spells, abilities) views for the inventory window;
- 120000-130001: custom GUI elements for the specific cases (e.g. bulletin board background and notes, power indicator for throwing, main menu background and so on);
- 140000-140048: GUI elements for the safe-cracking minigame (background, opening segments, dancing figures);
- 143000-144005: GUI elements for the cut minigame Wizard’s Whirl;
- 150000-155000: things that can be seen with the telescope in Erasmus’s castle;
- 156000-157002: pizza diagrams at the Scientific Isle;
- 160000: save/load game menu background;
- 161000: map (which looks the same as 900099 but the latter is stored in rotated form);
- 199909-199913: Wheel of Fortune minigame sprites (background and parrot, spinning wheels, arm and thrown knives are 3D models).
So the easy part is done, the next thing I’ll probably try is proper cylindrical projection for the room backgrounds and 3D object rendering. That should definitely take some time…
[…] I mentioned in my previous post, room backgrounds are supposed to be used as a texture on a virtual cylinder. After some […]