I have spent the last few days completing Tomb Raider II (which I finally did), as well as writing some C++ over some extremely outdated code. Let’s talk about the latter.
One of my previous topics reminds of Crystal Pixels, the prototype game made by the creator of the old space travelling game Noctis and the Linoleum programming language. The game takes place in a deep void, with crystalline blue dots scattered around a bright star-like object. The player can visit these dots (called pixels) by travelling with a spaceship (called The Fly) and create new pixels and objects at the origin-centered star (called Sunny). These are only the basics for what can be considered “your own microcosm”, allowing you to make it the way you want it.
The source code was later published under the GPL (as well as Noctis’), and this time I had really considered the possibility of porting Cryxtels to modern systems. And well, after some days of tinkering and coding, I was successful. Crystal Pixels was first created in 1994, and continuously developed until 1997, by Alessandro Ghignola (who’s had several different nicknames ; let’s just call him Alex). It is an MS-DOS game. That brought up several difficulties playing the game under a modern system. DosBox works, but requires some extra power to play, and some people have had some other difficulties when playing it. Regardless of that, there were more difficulties porting the old code, so I might as well share them with you.
- First of all, it’s a DOS game. It no longer makes sense to have full access to the display buffer like programmers used to back then. Instead, a context must be created, and all rendering is performed in it. Using the SDL library, creating a window and getting access to input devices and a graphical surface was a piece of cake. What remained was to replace every single piece of drawing code to make it write on the surface instead of a special platform-specific adapter.
- It’s a blast from the past. 16 bits was the common integer size, and right now we usually have 32 bits. This caused a few issues when saving and loading game saves (called situations) and allocating memory. A few int‘s were converted to short int‘s to keep the original size.
- Due to the machine limits of that time, the code also relied on far pointers, a curious concept that is no longer as important and much less often studied. There were no difficulties here: first I cleaned up the far modifier ; then I replaced all calls to farmalloc() with the C++ new operator.
- Inline Assembly! The compiler used back then wasn’t very intelligent, and made C code very slow. As a consequence, Alex had decided to write some fast x86 Assembly code when accessing the display adapter and performing DOS API calls. Now that I think of it, part of this now false assumption could have lead into Alex creating Linoleum. Anyways, since this is no longer that much of a problem as it was 20 years ago and due to the fact that unsupported asm code actually became a problem in the present, I manually converted all the inline asm code to C++. Those with API calls were replaced with other similar API’s. Also tricky was to convert the several pieces of supposedly-fast drawing algorithms.
- Italian. Let’s not forget the origins/whereabouts of this man. Most code and comments were in Italian, which made the code even harder to interpret. Google translator actually helped a great deal here, allowing me to know what “attracco” was all about.
- Even when inline asm wasn’t used, there were a few outdated C library inclusions that had to be replaced. The most prevalent case is the <dos.h> header, but it wasn’t so hard to replace these calls.
- And finally, it wouldn’t have been so frustrating and complicated to do this port if the code was actually good and made with care. Much on the contrary, the code made use of the dirtiest hacks to get the job done! This includes:
- Global variables! Global variables everywhere!
- Labels! Labels and goto’s everywhere!
- Functions with return via global variables. Ugh.
- Fixed-size dynamically allocated memory buffers. I suppose this was excusable back then, but it consumes too much memory when not all of it is needed, while applying limits to the user when more is needed.
- No structs at all! Nothing was object-oriented. It was pretty hard to understand the semantic context of each groups of variables.
- There were functions all right… but I would dare you to see the main function. We’re speaking of over 1400 lines of code. Some of my attempts to shorten it only made the compiler rant about dependencies over variables declared in it. You know, this is why you’re constantly reminded of producing modular code. Otherwise, you’ll be taking the risk of affecting a leg by modifying a hand.
Ok, I just complained over a piece of code nearly as old as myself. But never mind that. Even so, the code turned into good results: a microcosm of cold blue lines and dots. And now, it can be played in a modern system. Great! But that only means I resurrected a void, a space of loneliness, chills and bad memories. And this was exactly what Alex hoped to avoid after the many years he lived in it.
For those of you wanting to try out the modern port of Crystal Pixels, right now you will find the Linux binaries here. A thorough exploration of this game may even give you a better clue of Alex’s feelings at that time.
Allow me now to speculate even further into his mind. Noctis was one step further into filling the void, creating a warmer and richer universe, with more emotions and colors. Planets with a huge generated surface feel much nicer than walking over transparent pixel grounds. A creature of a futuristic cat-like species explores the universe alone, finding nothing but some eventual fellow stardrifters, birds, and primitive versions of themselves in life planets. But he still felt lonely. That was when the Noctis starmap and guides entered with the ability of sharing discoveries with other people. All they had to do was to download the latest inbox and upload their discoveries to the outbox. The universe then became known and abstractly populated. The feeling that there were entries of other players’ discoveries had shortened the gap. This concept however, was not enough. Or at least it’s safe to assume it was, because the plans of a Noctis V, although well established, did not turn into a complete game.
Noctis V was postponed to the probable infinite. A curse had landed. But why, we ask? What’s wrong with Alex? It’s been so many years now, and it’s still not done. Well, a thorough reading of his thoughts may clarify that. He’s had enough of feeling lonely. He simply gave up a life of void, of lonely virtual space travelling. He looked into other projects. He energized a bike. He tried, and still is trying to fly. His other projects for the last 10 years had mostly involved the Linoleum language (through several iterations), the Postline web platform, and who knows what else. So it’s safe to say he isn’t completely idle. Yet the desire to work on Noctis V was suppressed, and we sure are capable of understanding why.
The concept of Keyway, an attempt to make a Cryxtels-like game with online play, hasn’t seen the light of day, but who knows, it may happen. And if it does, it will clear this long-lasting void. Real people will populate a free space with social interaction. Maybe then we will understand what led us into gathering around some sort of nowhere, waiting for a man to fulfil what was mostly for himself. Cryxtels gave him a space to live and hide in. Noctis gave him a distant neighbourhood. Is he ready for the final evolution of the concept?