When old isn’t gold.

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.

A screenshot of Crystal Pixels

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?

Advertisements
This entry was posted in Projects, Thoughts and tagged , , , , , . Bookmark the permalink.

4 Responses to When old isn’t gold.

  1. Alex says:

    Maybe.

    Out of coincidence, this post of yours comes about three weeks after I have decided to come back to work at L.in.oleum’s third iteration. And, well, it looks like it’s growing its last flight feathers: run-time environment is conceptually ready, heap memory is working, there’s centralized deallocation and passing of blocks to callers (sort of semi-automatic garbage collection), there are if-then-else blocks now, a namespacing mechanism that allows local names in functions and subroutines, and facilities to create and map local variables in stack frames or in heap blocks, there’s organized persistent state information in libraries, defining contexts in which routines run, there’s interfaces and implementations, and precise calling conventions, and even more than before, everything was designed while targeting execution speed.

    The answer is a maybe-yes. I don’t have much time to waste left if I want to build some future for anynowhere, so it might be about time to come back. In my style, of course, but which seems to have evolved a great deal in the meantime (although it still scaredly floats away of multithreading and dislikes hardware-accelerated graphics). I’ve enjoyed your post speaking of global return values and no trace of an object model in Cryxtels. Of course there wasn’t: I wasn’t needing one, I just saw the code and enjoyed the warmth of the Turing tarpit. I’m not surprised you were astounded by my first couple years of C programming, using C about the same way I was using AmOS BASIC on the Amiga 500 I was coming from at that times. You must have been doing a great work with your port, and deserve congratulations for understanding the alien code of a weird guy keeping objects only in his mind and feeding that to a DOS compiler from over 20 years ago. :D

    • E_net4 says:

      All right, it seems I wasn’t far off. :P

      You know, I checked some logs in Frespych back from 2011, in New Year’s eve, talking about Linoleum and stuff like that… (http://anynowhere.com/bb/logs/2010/2010_01_01.html) and guess what… I laughed. And you will laugh as soon as you recall the conversation.

      I’m no longer as keen to program in Linoleum as I was a few years ago. And C++ took the spot of my favourite language. So you’ll have to impress me if I am to try that new version. :P
      In fact, I get both multi-threading and hardware-accelerated graphics with C++. As a matter of fact, the fact that Linoleum has none of these is a total loss from both ends: graphics processing can be performed in parallel, so multi-threading would have made software rendering faster. And even if it had multi-threading, it will never reach the power of a graphics cards. I’m sorry, but they won’t remain obsolete so soon. They are also being used for heavy computing and physics processing in games. Make it two great steps behind. :/

      And well, thanks for reading the post. Cryxtels came to mind while I was at the beach place without a persistent Internet access point. When I turned my computer on, most of what I did was doing C++ code, mostly solving ProjectEuler problems. Gladly, I had your source code with me, and it was then I wondered how hard it would be to make it work in a modern system. The code was a mess indeed, and the ported sources are still a mess, but maybe you’d like taking a small peek at them. I separated part of the variables and functions definitions to other source files, thus managing to reduce cryxtels.cpp by about a hundred lines. Some pieces are easily recognized as mine: a template function, SDL API function calls, and anything with the ‘auto’ keyword are some of the traces. :D

  2. Pingback: Doing things! Open-source! | E_net4's Blog

  3. Pingback: Mojang being bought by Microsoft | E_net4's Blog

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google+ photo

You are commenting using your Google+ account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s