Nugget
Bare-metal libraries and examples for the original PlayStation
Loading...
Searching...
No Matches
Classes | Public Types | Public Member Functions | List of all members
psyqo::TIM Struct Reference

A reader for Sony's TIM texture container. More...

#include <psyqo/tim.hh>

Classes

struct  Section
 One CLUT or pixel section. More...
 

Public Types

enum class  Type : uint8_t {
  Tex4Bits = 0 , Tex8Bits = 1 , Tex16Bits = 2 , Tex24Bits = 3 ,
  Mixed = 4
}
 The pixel format of the data, as declared by the file. More...
 
enum class  Error : uint8_t {
  None = 0 , TooSmall , BadMagic , Compressed ,
  BadType , Truncated , BadSectionSize
}
 Why a TIM was rejected. More...
 

Public Member Functions

bool parse (const uint8_t *data, uint32_t size)
 Parses a TIM out of a buffer, without copying or taking ownership.
 
void upload (GPU &gpu) const
 Uploads the texture, and its palette if it has one, to the VRAM coordinates the file itself asks for.
 
void upload (GPU &gpu, Vertex texturePosition, Vertex clutPosition) const
 Uploads to caller-chosen VRAM coordinates, ignoring the ones in the file.
 
PrimPieces::TPageAttr tpage (Vertex texturePosition) const
 Builds the texture page attribute describing where the pixels landed, with the colour mode taken from the file's type.
 
PrimPieces::ClutIndex clutIndex (Vertex clutPosition) const
 Builds the CLUT index for a palette uploaded at the given VRAM position. Meaningless when the file has no CLUT.
 
bool hasCLUT () const
 
Type type () const
 
Error error () const
 
const Section & pixels () const
 
const Section & clut () const
 
unsigned width () const
 The width of the image in texels rather than in VRAM units.
 
unsigned height () const
 

Detailed Description

A reader for Sony's TIM texture container.

TIM is the devkit's texture format, and is what most PS1 games ship. It is a thin wrapper: a short file header, then one optional CLUT section and one pixel section, each carrying a destination in VRAM and its dimensions, followed by data that is already in the layout the GPU wants. There is no compression and no decoding, so loading one is a validation pass and two transfers.

The dimensions in a TIM section are in 16-bit VRAM units rather than in texels, which happens to be exactly what GPU::uploadToVRAM wants, so the section headers drop almost directly into a Rect.

Validation is mostly a build-time concern. A TIM you produced yourself either loads or visibly does not, and paying for those checks in every shipped binary buys nothing, so define DEBUG_TIM to get them. The one exception is always compiled in: a section whose declared size disagrees with its dimensions is rejected unconditionally, because that is the only failure that is not visible. It catches a bad width, the width is what the transfer length comes from, and the result is a write past the end of the buffer rather than a wrong picture.

Member Enumeration Documentation

◆ Error

enum class psyqo::TIM::Error : uint8_t
strong

Why a TIM was rejected.

Explicit rather than a bool because the failures mean genuinely different things: a compressed TIM is a valid file this parser refuses, while a truncated one is a broken asset.

The enum keeps its shape in every configuration on purpose. All but BadSectionSize require DEBUG_TIM to be produced, but a type whose definition changes between builds is how a header and a library end up disagreeing, so the values stay put and simply go unused.

Enumerator
None 
TooSmall 

The buffer cannot hold even a file header.

BadMagic 

The file does not start with 0x10, 0x00.

Compressed 

The reserved field is set, which marks a compressed TIM.

BadType 

The type field is outside the range the format defines.

Truncated 

A section claims to extend past the end of the buffer.

BadSectionSize 

A section's declared size disagrees with its dimensions.

◆ Type

enum class psyqo::TIM::Type : uint8_t
strong

The pixel format of the data, as declared by the file.

This is only a hint about how to view the pixels. The data is copied into VRAM the same way regardless, so treat this as the source for a texture page's colour mode rather than as something to branch on. Mixed means the file holds several formats at once.

Enumerator
Tex4Bits 
Tex8Bits 
Tex16Bits 
Tex24Bits 
Mixed 

Member Function Documentation

◆ clut()

const Section & psyqo::TIM::clut ( ) const
inline

◆ clutIndex()

psyqo::PrimPieces::ClutIndex psyqo::TIM::clutIndex ( Vertex  clutPosition) const

Builds the CLUT index for a palette uploaded at the given VRAM position. Meaningless when the file has no CLUT.

◆ error()

Error psyqo::TIM::error ( ) const
inline

◆ hasCLUT()

bool psyqo::TIM::hasCLUT ( ) const
inline

◆ height()

unsigned psyqo::TIM::height ( ) const
inline

◆ parse()

bool psyqo::TIM::parse ( const uint8_t *  data,
uint32_t  size 
)

Parses a TIM out of a buffer, without copying or taking ownership.

The buffer has to outlive this object. Nothing is transferred to VRAM here, so a caller can inspect the sections and decide where they should land before committing to anything.

Parameters
dataStart of the file.
sizeBytes available. Checked against the section extents only when DEBUG_TIM is defined.
Returns
Whether the file was accepted. On failure error() says why.

◆ pixels()

const Section & psyqo::TIM::pixels ( ) const
inline

◆ tpage()

psyqo::PrimPieces::TPageAttr psyqo::TIM::tpage ( Vertex  texturePosition) const

Builds the texture page attribute describing where the pixels landed, with the colour mode taken from the file's type.

Parameters
texturePositionThe same position passed to upload, or pixels().rect.pos when the file's own coordinates were used.

◆ type()

Type psyqo::TIM::type ( ) const
inline

◆ upload() [1/2]

void psyqo::TIM::upload ( GPU &  gpu) const

Uploads the texture, and its palette if it has one, to the VRAM coordinates the file itself asks for.

Convenient for assets authored alongside the code that loads them, and the wrong choice as soon as anything decides placement at runtime, since the file wins. Prefer the overload taking explicit positions when the application owns the VRAM layout.

This is a blocking transfer with the same rules as GPU::uploadToVRAM: no other GPU transfer may be in flight. Called while a frame is running, use GPU::waitChainIdle first.

◆ upload() [2/2]

void psyqo::TIM::upload ( GPU &  gpu,
Vertex  texturePosition,
Vertex  clutPosition 
) const

Uploads to caller-chosen VRAM coordinates, ignoring the ones in the file.

Parameters
texturePositionWhere the pixels go. Has to sit on a texture page boundary to be addressable: a multiple of 64 in x, of 256 in y.
clutPositionWhere the palette goes, ignored when the file has no CLUT. CLUTs are addressed in 16 pixel steps, so x should be a multiple of 16.

Same blocking rules as the other overload.

◆ width()

unsigned psyqo::TIM::width ( ) const

The width of the image in texels rather than in VRAM units.

The two differ everywhere except 16bpp, and confusing them is the classic way to end up with a sheared texture.


The documentation for this struct was generated from the following files: