Monthly Archives: November 2007


Spent a bit of time fixing up some code in Decrypt, killed some show stopper bugs dealing w\ the OS API for the applications which affected progressing through missions. Also upgraded PHPFreeChat to v1.0 final. PHPFreeChat is the software behind the chat application.

Gotten quite a lot done on the console project lately too.

See, in programing you quickly come to two assumptions which are fairly safe to make.

1) The programing language is right, your code is wrong.

2) The 3rd party library you are using is right, your code is wrong.

The first is pretty darn stead fast, and the second isn’t far behind (depending on how mature the library is of course).

So you’d think it’d be safe to assume the second when you are using a 20 year old, time tested library put out by the likes of a company such as NewTek (makers of LightWave).

But… you’d be wrong…

Lets examine this piece of code, it comes from lwio.c which wraps all of the I/O functionality that the rest of the files use. In there, there is a specific function which is used to read a NULL terminated string of bytes (not necessarily ASCII characters, but it doesn’t really make a difference). We know this is it’s purpose because we have read the documentation and looked at the data it is actually called on, it is always NULL terminated.

Now take a look at the function and tell me if you can spot a problem with it:

   for ( i = 1; ; i++ ) {
      c = fp->fgetc();
      if ( c <= 0 ) break;

Ok, the point of this piece of code is to count the size of bytes that the data is so we can allocate memory for it.

First, ew. Ugly code. But lets trace it, we keep reading and incrementing our count variable until... until what? Until it is less then or equal to 0...

HHhhhmmm... does that make any ef-ing sense if what it is we are looking for is NULL ( NULL == 0 btw )?

Assuming we just did not understand the actual point of the code we continued reading the spec, looking at the data it was reading in a Hex editor and running through everywhere the read function was called.

With out a doubt it was looking for a NULL terminated string of bytes, and that chunk of code was meant to count up to the NULL character.

So we quickly replaced the bugged line and came up with the more explicit:

   for ( i = 1; ; i++ ) {
      c = fp->fgetc();
      if ( c == '\0' ) break;

Now on a side note, the most astute of you may notice the file I/O using what appears to be an Object or Struct pointer. Well you are right, we ported the code to C++ and use our FileBuffer and FileIterator classes to emulate std:: file I/O operations. We looked a lot into how our getc() function might have been working differently then std::getc(). But I can assure you, that it works the same.

So back on topic here, it's not hard to see the case in which the original code would fail. Anytime the byte overflowed as an unsigned 8 bit int, it would be negative. The specific byte that was fucking us over was 0x80.

So, with that fixed, we finished porting lwobject and fixing bugs that cropped up in it. Then I went on to extract all the information we needed out of it and create our internal data structure for holding the data how we wanted to render it. Let me tell you, the UV coordinates were a bitch to find.

Just to get the texture file path, it took these two lines of code:

lwClip *clip = lwFindClip( obj->clip,
param.imap.cindex );

char *texturePath =

Anyway... With that all done I finished connecting all the dots between all of the supporting systems and the renderer and finally, finally, got Textured, 3D, rendering working.

So the current state of things is and solid complete base with 2D and 3D loading and rendering working.

Next, we start on integrating ODE! I don't want to jinx things, but it should, *fingers crossed* go a lot smoother then the other integrations have.

- Adam


So quite a bit of progress on the console development front.

As always while coding a big project like this, no matter what the actual task at hand is, I always clean up and refactor tons of of little semi or completely unrelated things along the way. So lots of little parts of the engine have been cleaned up, is the sort of central theme of what I’m trying to say I guess…

Annnyyy waaayyyy…

The engine now has a fully functional scene graph as well as a fully functional state manager / input handling system.

With all that in the bag, Rob and I working on integrated libPng and LibZ for use as your texture loader, and moved on to getting texture rendering working inside our engine (much more difficult then you’d have thought).

Moving forward we ported some file loading code for .lwo (LightWave Object) files. Let me tell you… not fun.

The code was ~20 years old. It was made when C compilers had almost no type checking apparently. So the first task was just getting it to compile in a modern C compiler. Then the porting could begin. To get it running on the console we had to use a custom File I/O class we have developed to assist with porting libraries. Bringing the old C code in C++ was even more fun.

Ever seen a function call like this?
lwListFree( (void*)texture, reinterpret_cast( lwFreePlugin ) );

I don’t know about you, but I’d never seen this arcane syntax before, but this what I had to come up with to get it to compile.

See, most modern code can be ported simply by dropping in our special header file. But some older code is more difficult. So we developed this class them emulated most of the C style file I/O. While we still have to go through and modify many many lines of code, our class is structured to work exactly like the old C style functions, so the structure and flow of the code need not change.

We have been developing good strategies and a good code base for porting libraries. So far we ahve ported libPNG, libZ (required by libPNG), lwobject (LightWave Object code), and partially ODE (Open Dynamics Engine).

While we did in fact get the lwobject code compiling and running, we still dont have the renderer coded to read and render the data from memory yet. Thats the next task. But with all the heavy lifting done by lwobject, it should be a sinch.

The real next task will be getting ODE running, verifying that it works, and plugging it together with everything else.

So starting to get close to some pretty exciting stuff!

– Adam