Texture formats 8, 9 and 10 are DXT1, DXT3 and DXT5. The hardware's format is a little different from the standard (as you'd find in a .DDS file, for example).
(See http://oss.sgi.com/projects/ogl-sample/ ... n_s3tc.txt or http://en.wikipedia.org/wiki/S3_Texture_Compression for a description of the DXTn texture formats to make sense of the below.)
For DXT1, each 4x4 texel block has 2 16-bit 565 colours, and 16 2-bit per-texel fields (8 bytes/block). The PSP hardware expects the per-texel bits to come first, followed by the two colours. It also expects the colours to be in (PSP-standard) BGR 565, rather than the standard RGB 565.
For DXT3 and DXT5, each 4x4 block has 8 bytes of alpha data followed by 8 bytes of pixel data. The PSP reverses this, so it wants the pixel data followed by alpha data. Also, the pixel data is normally encoded in the same way as the DXT1 blocks, which is almost true for the PSP. The encoding is the same as for DXT1 textures, except the colours are in RGB 565 format (!?).
Sample code:
Code: Select all
static inline unsigned short swizzle_565(unsigned short in)
{
unsigned short r = (in & 0xf800) >> 11;
unsigned short g = (in & 0x07e0);
unsigned short b = (in & 0x001f) << 11;
return b | g | r;
}
void convert_dxt1(void *to, const void *from, unsigned size)
{
const unsigned short *src = from;
unsigned short *dest = to;
for(; size >= 8; size -= 8) {
dest[0] = src[2];
dest[1] = src[3];
dest[2] = swizzle_565(src[0]);
dest[3] = swizzle_565(src[1]);
dest += 4;
src += 4;
}
}
void convert_dxt35(void *to, const void *from, unsigned size)
{
const unsigned short *src = from;
unsigned short *dest = to;
for(; size >= 16; size -= 16) {
/* copy alpha */
memcpy(&dest[4], &src[0], 8);
dest[0] = src[6];
dest[1] = src[7];
dest[2] = src[4];
dest[3] = src[5];
dest += 8;
src += 8;
}
}