Reverse Engineering the textures

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).

Article content
The code section in charge of rendering the new viewport texture.
Article content
The new texture viewport

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.

Article content
Texture Offset is the only thing working so far

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.

Article content
Vehicles.textures file containing all the ATV textures

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.

Article content
'TEXS' magic string (pink rect). Textures amount in addr 0xC (yellow rects)
Article content
Amount of textures 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.

Article content

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.

Article content


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.

Article content
Blender showing thumbnails of the textures.

Up next, I decode the UV's of the 3d models so we can actually use these textures on the models.



To view or add a comment, sign in

More articles by Pablo Narvaja

Others also viewed

Explore content categories