Difference between revisions of "Mobile textures (SA/VC)"

From GTAMods Wiki
Jump to navigation Jump to search
(Started mobile textures article)
 
(No difference)

Revision as of 16:10, 5 February 2021

There are multiple texture formats used in the mobile version of GTA:SA, with different formats being used for different platforms in order to take advantage of the strengths of the different graphics/processing chips in devices on each platform.

A single texture database is made up of several files:

  • name.txt
  • name.x.toc
  • name.x.dat
  • name.x.tmb

Textures are grouped into separate databases based on which archive file they are in on non-mobile versions, and the 4 files listed above are named accordingly: name is gta3 for textures from gta3.img, gta_int for textures from gta_int.img, and so on.

In these file names, x refers to the file extension of the texture format used. For example iOS devices use the PVRTC format, which means that x is pvr.

.txt

The .txt file contains a list of all the textures in the database, along with various texture properties for each. It also contains information about the database itself.

Properties in the .txt file are set with propertyname=value where value may be an integer or string value. There are two properties – png and img – that are used with hexadecimal numbers (e.g. png=72b88910), but these properties are never read by the game. It is possible that they are some sort of checksum or identifier for texture PNGs/other images.

The affiliate property is set inside quotes – "affiliate=something".

The category line defines default values for texture properties as well as information about the database itself. It must set the cat property in order to be correctly identified as a category line. In GTA:SA, this line is the first in the file, but this is not a requirement.

Texture lines begin with the quoted texture name, such as "ahoodfence2".

See the table below for a list of properties.

Property name Type Meaning
format
Integer Specifies the format of the texture.
mipmode Boolean
hassibling Boolean
hasbias Boolean
camnorm Boolean Unknown. Used for "thin" textures (e.g. leaves, wires).
forcez Boolean Unknown. Used for some glass textures.
decalz Boolean
noalphatest Boolean Unknown. Used for some shadow textures.
hasdetail Integer
isdetail Integer
detailtile Integer The number of times to tile the detail texture (unconfirmed).
alphamode Integer 1, 2 or 3
streammode Boolean
width Integer The width of the texture, measured in pixels.
height Integer The height of the texture, measured in pixels.
affiliate String A texture that this texture "points to". If a texture is defined as an affiliate, it simply redirects to whichever texture it points to. Affiliate textures do not have any texture data and typically do not define any other properties.

.toc

Overview

The .toc file is a table of offsets for the .dat file (which contains all of the texture data). This file is not required by the game; a new offset table can be created by reading the .dat file. The purpose of the offset table is to accelerate texture loading. A game running without prebuilt offset tables will likely suffer from small stutters, generally lower FPS, and textures loading later than they should (leaving some objects untextured until the texture loads).

The offset table file stores the size of the .dat file it is for in order to allow the game to ensure that the two files are compatible. If the size given in the .toc file does not match the actual .dat size, the table will be discarded and the offsets will be read directly from the data file instead.

The game is capable of generating offset table files for future use, but this code never runs in production builds.

Format

Offset files have a very basic format: one 32-bit unsigned integer (uint32) for the size of the data file, and then the rest of the file is consecutive uint32 offsets in the order of the entries in the .txt file.

To read an offset file, code similar to the following pseudo-C++ may be used:

FILE *offsetFile = std::fopen(pathToOffsetFile, "rb");

if (!offsetFile) {
    // Error: unable to open the file.
    // ...
}

uint32 statedSize;
std::fread(&statedSize, 1, 4, offsetFile);

uint32 dataFileSize = /* the size of the data file */;
if (statedSize != dataFileSize) {
    // Error: offset and data files do not match.
    // ...
}

uint32 *offsetArray = new uint32[database.entryCount];

std::fread(offsetArray, 4, database.entryCount, offsetFile);
std::fclose(offsetFile);

// offsetArray now contains the offsets from the file.

In both error cases in the above code, the game will resort to reading the offsets from the data file.