Latest: adam_20nov2007.plan
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:
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:
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:
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
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,
layer->polygon.pol[ii].surf->color.tex->
param.imap.cindex );
char *texturePath =
clip->source.still.name;
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
Post a Comment
.plan Archive
.plan rss
adam_23feb2010.plan
adam_25sep2009.plan
adam_03may2009.plan
adam_07may2008.plan
adam_20nov2007.plan
adam_02nov2007.plan
adam_12oct2007.plan
adam_03oct2007.plan
adam_26sep2007.plan
adam_31jul2007.plan
adam_17jul2007.plan
adam_05jul2007.plan
adam_31may2007.plan
adam_16may2007.plan
adam_01may2007.plan
adam_28apr2007.plan
adam_11apr2007.plan
adam_08apr2007.plan
adam_03apr2007.plan
adam_31mar2007.plan
adam_29mar2007.plan
adam_29mar2007.plan
adam_26mar2007.plan
adam_04mar2007.plan
adam_27feb2007.plan
adam_08feb2007.plan
adam_02feb2007.plan
adam_01feb2007.plan
adam_28jan2007.plan
adam_27jan2007.plan
adam_26jan2007.plan
adam_22jan2007.plan
adam_18jan2007.plan
adam_06jan2007.plan
adam_28dec2006.plan
adam_22dec2006.plan
adam_17dec2006.plan
adam_14dec2006.plan
adam_28nov2006.plan
adam_26nov2006.plan
adam_24nov2006.plan
adam_11nov2006.plan
adam_02nov2006.plan
adam_31oct2006.plan
adam_25oct2006.plan
adam_19oct2006.plan
adam_16oct2006.plan
adam_09oct2006.plan
adam_28sep2006.plan
adam_24sep2006.plan
adam_21sep2006.plan
adam_23feb2010.plan
adam_25sep2009.plan
adam_03may2009.plan
adam_07may2008.plan
adam_20nov2007.plan
adam_02nov2007.plan
adam_12oct2007.plan
adam_03oct2007.plan
adam_26sep2007.plan
adam_31jul2007.plan
adam_17jul2007.plan
adam_05jul2007.plan
adam_31may2007.plan
adam_16may2007.plan
adam_01may2007.plan
adam_28apr2007.plan
adam_11apr2007.plan
adam_08apr2007.plan
adam_03apr2007.plan
adam_31mar2007.plan
adam_29mar2007.plan
adam_29mar2007.plan
adam_26mar2007.plan
adam_04mar2007.plan
adam_27feb2007.plan
adam_08feb2007.plan
adam_02feb2007.plan
adam_01feb2007.plan
adam_28jan2007.plan
adam_27jan2007.plan
adam_26jan2007.plan
adam_22jan2007.plan
adam_18jan2007.plan
adam_06jan2007.plan
adam_28dec2006.plan
adam_22dec2006.plan
adam_17dec2006.plan
adam_14dec2006.plan
adam_28nov2006.plan
adam_26nov2006.plan
adam_24nov2006.plan
adam_11nov2006.plan
adam_02nov2006.plan
adam_31oct2006.plan
adam_25oct2006.plan
adam_19oct2006.plan
adam_16oct2006.plan
adam_09oct2006.plan
adam_28sep2006.plan
adam_24sep2006.plan
adam_21sep2006.plan