I, uh… kind of forgot to write part 2 of the series. So here it is.
As I said in the beginning of the last article, I started off using the documentation on the Jongware website and the AoWRead documentation to figure out the Age of Wonders 1 version of the ILB file format. Sorting through these, as well as using a bit of intuition, I eventually managed to put together a basic C++ command line program that would take an ILB file and dump all the images, composited where applicable, into a folder for me. Here’s an example of one of the composited images:
The Triumph Studios logo from the title screen image library. The image is composed of a faded background glow and a solid logo (that isn’t actually solid!).
After building out a basic, static version of the title screen using HTML and CSS, I decided it was okay, but it wasn’t nearly as accurate as I wanted. One issue was simply that the ILB format allows for different effects to be applied to the image at render time, such as additive and multiplicative blending. My PNG exporter cheats when writing out the composited format, so it wasn’t ever going to be accurate simply because PNG doesn’t support the blending modes needed. I’m sure I could use CSS tricks and not pre-composite the images, but at that rate the converted images were going to end up a larger file size than the original ILB to begin with. Additionally, text was going to be a major pain because all the fonts were stored as bitmap graphics in ILB files as well.
This led me to the current solution: Instead of pre-converting and using HTML and CSS to render, I’d use what I learned about reading binary data from the IT player library, combined with what I learned about the file format from the C++ project, and dig in to learning HTML5’s Canvas system. One of the first things I did was look up if Canvas supported more interesting blend modes than bog standard alpha, just to be sure. It does, which greatly simplifies the rendering system.
Finally, I had image rendering. It was time to start doing stuff with that. The first thing was getting the scrolling background working. This was mildly complicated since I wanted to be able to handle arbitrary window sizes. Eventually I settled on a for loop, drawing images until the next one would be completely off screen. Interestingly, this ended up being one of two ways my reproduction ended up handling things better than the real thing, since Age of Wonders’ program didn’t account for large resolutions when drawing the title screen. It was fixed at only drawing two copies of the backdrop, so once the second copy was far enough to the left that it was no longer overdrawing (it’s only 1514px wide) you ended up with a smear of the last column as it scrolled until it hit X=0 where it switched to being the “first” copy, and the game started that whole routine over.
Instead, I cheated. Sort of. I wrote a function that would use the font’s image data to figure out the width of the string (which I’d use later anyway), then use that to build an image object to render the raw font to. From there, it was a basic matter of using blending modes to overwrite the non-transparent pixels, then drawing that on the final canvas. The width-finding function ended up being very useful for string positioning as well, making layout a breeze.
The fun came from drawing the credits. The fading text using a fancy font with a built in drop shadow, the logos, and the timing. All of it drove me nuts! The first thing I had to do was figure out where on the screen everything needed to be. I figured out the game was basing all of it’s key layout on a 640×480 box centered on the screen, which wasn’t an uncommon (although cramped) resolution at the time. I used CSS to set that as my minimum, then started figuring out offsets. A lot of this was simply using Visual Studio’s debugger to pause execution, using the mouse cursor to count pixels relative to some landmark, then putting that in my table of layout info. The various fades and whatnot actually made me add a render alpha parameter to the ILB drawing code. Amusingly enough, due to the way I draw the text, this ended up being the second way my reproduction handling things better. In the real Age of Wonders program, the blending code didn’t handle alpha AND additive/multiplicative blending (which was used by the main font for the text and it’s drop shadow, respectively) as well as it could have, resulting in some minor but obvious visual hiccoughs if you knew to look for them.
The orbs at the bottom were a walk in the park by comparison. Each has a slight glow behind it which is just one of the images from the ILB in additive blending mode. Then you have the orb image itself, where the only complicated thing was the mouse listening code to determine if the mouse was hovering and/or clicking in the orb’s bounding box to determine if it should draw the normal/hover/active image. In addition, it also draws the orb’s label if the mouse is within the orb’s bounding box. For kicks, I also added a way to have a callback fire when the orb has been “clicked” which I use for the exit orb to return you to the home page.
And there you have it. A reimplementation of the Age of Wonders title screen, with the added benefit of using the original game files. PlsNoSue, Triumph…