Reverse Engineering the textures
In this article I will show how I decoded the binary files containing the textures of the 3d models from the game PURE(2009).
What you may want to know before continuing
What is texture?
A texture is an image that is wrapped around a 3d model like a big coloured sticker. It is used to add detail to a model because making that detail from a pure vertex mesh would require a lot of computing power and memory for single asset in a video-game.
The common way to store textures for video-games
The most common way to store these images is using the compressed format DDS (Direct-Draw Surface), a format storage created by Microsoft for direct3d. Compression is very important when storing assets because in the past CDs and later DVDs had a maximum of 700MB and 4.7GB of storage respectively. Today it is still important because it makes downloading faster, storage cheaper, and if the user has an internet data limit, they are more likely to download a small game than a large one.
The format is made up of a header where all the information about the texture is located, e.g.: texture size, compression algorithm, etc. And the image data.
Adding a feature to my tool to help me decode the format
To make my life easier, I started adding a new viewport to visualize what the texture looked like. Doing it with IMGUI was very easy, just copy and paste, and thanks to my clear design of the rendering API in my tool I was able to get it working very quickly (2 days or 8 hours approx).
In the "Binary parser" area, I added the "Textures" collapsing header with all the options needed to read any texture. It doesn't work, stay with me here, It is there as a template for the next features I'll add, but right now only the texture offset (yellow rectangle) is used and the rest (pink rectangle) is discarded. The reason for this is the speed of development. I didn't need the other features to work for decoding this texture file, I just needed the address where the texture starts and the DDS reader would take the length of the texture from the texture header.
The DDS reader is just a function in the code that reads the format, it is not another program or module in the tool. I made a whole function to take control of reading the texture because, as I'll expand on later, all the textures were in this format and decoding them without reading the header would be mentally overhead and slower.
Once the DDS reader grabbed the image data from the texture file, I fed that data to the GPU through OpenGL API, without decompressing it on the CPU. Most, if not all, GPU drivers have the ability to decode the S3 Texture Compression codec using only the GPU and thus speeding up the process.
The texture format
In PURE the textures are not saved in the same .model file. Instead they are all packed in the .textures files.
Recommended by LinkedIn
If we take a look at this file, we'll see that it starts with the magic string 'SXET' , which says 'texs' backwards, short for textures. Then there are 8 bytes with what appear to be random numbers, and at the address 0xC there is a number that is exactly the same as the number of textures I found in the file.
If we take a quick look at the file we'll find the code 'dds' many times, this gave me the tip that the game used dds to store the textures, and I used it to find out that the file stores the amount in the header.
I searched the file format on the web and found that there are many versions called DXT and the version number, e.g.: DXT4. This version is the most common in the files, but some use DXT5 and others use DXT1.
At the end of the .textures file we find readable characters, these are the file names followed by 8 bytes.
Personally, I don't care much about decoding each image with its name, because my intention is not to replicate the file format but only to extract its content. What I tried was to find each 'DDS' and read to the next 'DDS', this has a problem and that is that it pollutes the last image with the meta-data at the end of the file, since the game only has 5 texture packs this gives me a total of 5 images to clean manually, so that's what I did.
Conclusion
I am getting close to having the ATV's look complete with only the UV's missing which makes this adventure far more interesting to invest time in. Looking at the result, I found 371 textures in total, in 5 different file containers.
I used blender to have a landscape of all of them.
Up next, I decode the UV's of the 3d models so we can actually use these textures on the models.