JD2022-TU1/main/extern/TexPostCookWii/Tiling.cpp

375 lines
10 KiB
C++

#include <algorithm>
typedef unsigned char u8;
typedef unsigned short u16;
typedef unsigned long u32;
extern bool gb_Endiannes;
/*
=======================================================================================================================
=======================================================================================================================
*/
void GDK_images_FixEndian(u8 *src, u32 numBytes)
{
#define TPL_BIG_END
#ifdef TPL_BIG_END
u8 tmp[8]; // large enough to hold a double
u32 max, i;
//TCAssertMsg( (numBytes <= 8), "TCFixEndian: numBytes > 8\n" );
if( (numBytes == 0) || (numBytes == 1) )
{
return;
}
max = numBytes - 1;
for(i=0; i< numBytes; i++)
{
tmp[(max - i)] = src[i];
}
for(i=0; i< numBytes; i++)
{
src[i] = tmp[i];
}
#endif
}
/*
=======================================================================================================================
=======================================================================================================================
*/
void GDK_images_FixCMPWord(u16 *data)
{
u16 tmp;
tmp = *data;
// reverse tuple order within bytes
*data = ( (tmp & 0x3 ) << 6 ) |
( (tmp & 0xC ) << 2 ) |
( (tmp & 0x30) >> 2 ) |
( (tmp & 0xC0) >> 6 ) |
( (tmp & 0x300 ) << 6 ) |
( (tmp & 0xC00 ) << 2 ) |
( (tmp & 0x3000) >> 2 ) |
( (tmp & 0xC000) >> 6 ) ;
}
/*
=======================================================================================================================
=======================================================================================================================
*/
void GDK_images_PackCMPTile
(
void * _pv_SrcImg,
u32 _u32_Width,
u32 _u32_Height,
u32 tileX,
u32 tileY,
u16 * dstPtr
)
{
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
u32 x, y;
u16 * srcPtr;
u16 tmp;
u32 srcTileOffset;
u32 subTileRows, subRowShorts; // number of s3 4x4 tiles
u32 srcPadWidth, srcPadHeight;
u16 * buffPtr;
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
// set the padded size of the s3 source image out to a 4-texel boundary
srcPadWidth = ( (_u32_Width + 3) >> 2 );
srcPadHeight = ( (_u32_Height + 3) >> 2 );
// number of bytes in a single row of 4x4 texel source tiles
srcTileOffset = srcPadWidth * 8;
// number of 4x4 (source) tile rows to copy ( will be 1 or 2 )
subTileRows = 2;
if( (srcPadHeight - tileY) < 2 )
subTileRows = 1;
// number of 4x4 tile cols to copy translated into number of short values
// ( will be 4 or 8 )
subRowShorts = 8;
if( (srcPadWidth - tileX) < 2 )
subRowShorts = 4;
for( y=0; y < subTileRows; y++ )
{
srcPtr = (u16*)( (u8*)(_pv_SrcImg) + ((tileY + y) * srcTileOffset) + (tileX*8) );
buffPtr = ( dstPtr + (y * 8) ); // 16 bytes per subRow = 8 shorts
// process one or both 4x4 row tiles at once- 4 short each
for( x=0; x < subRowShorts; x++ )
{
switch( x )
{
// color table entries - switch bytes within a 16-bit world only
case 0:
case 1:
case 4:
case 5:
tmp = *srcPtr++;
GDK_images_FixEndian((u8*)(&tmp), 2);
*buffPtr++ = tmp;
break;
// 2-bit color tuples;
// reverse tuple order within bytes of a word
case 2:
case 3:
case 6:
case 7:
tmp = *srcPtr++;
GDK_images_FixCMPWord(&tmp);
*buffPtr++ = tmp;
break;
} // end switch
} // end for( subRowShorts )
} // end for( subTileRows )
}
/*
=======================================================================================================================
After DXT1 compression, Wii textures must be tiled => CMPR format
=======================================================================================================================
*/
void GDK_images_TileDXTForWii
(
void * _pv_DestImg,
void * _pv_SrcImg,
u32 _u32_Width,
u32 _u32_Height
)
{
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
u32 tileRow, tileCol;
u32 srcTileRows, srcTileCols;
u16 * dstPtr;
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
// each source tile is 4x4 texels, 8B
srcTileRows = ((_u32_Height + 3) >> 2);
srcTileCols = ((_u32_Width + 3) >> 2);
dstPtr = (u16*) _pv_DestImg;
// each dst tile is 2x2 source tiles, so move by 2 each iteration
for (tileRow = 0; tileRow < srcTileRows; tileRow += 2)
{
for (tileCol = 0; tileCol < srcTileCols; tileCol += 2)
{
GDK_images_PackCMPTile(_pv_SrcImg, _u32_Width, _u32_Height, tileCol, tileRow, dstPtr );
dstPtr += 16; // 32B per dst tile, short ptr
}
}
}
/*
=======================================================================================================================
Tile a raw image I8 format for WII
=======================================================================================================================
*/
void GDK_images_TileRawBufferForWiiI8
(
void * _pv_DestImg,
void * _pv_SrcImg,
u32 _u32_Width,
u32 _u32_Height
)
{
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
u32 row, col;
u8 * dstPtr;
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
dstPtr = (u8*)_pv_DestImg;
// one tile is 32B 4 rows x 8 columns
for (row = 0; row < _u32_Height; row += 4)
{
for (col = 0; col < _u32_Width; col += 8)
{
u8* src1 = (u8*)_pv_SrcImg + ((row + 0) * _u32_Width + col);
u8* src2 = (u8*)_pv_SrcImg + ((row + 1) * _u32_Width + col);
u8* src3 = (u8*)_pv_SrcImg + ((row + 2) * _u32_Width + col);
u8* src4 = (u8*)_pv_SrcImg + ((row + 3) * _u32_Width + col);
for(u32 i = 0; i < 8; ++i, ++dstPtr, ++src1) *dstPtr = *src1;
for(u32 i = 0; i < 8; ++i, ++dstPtr, ++src2) *dstPtr = *src2;
for(u32 i = 0; i < 8; ++i, ++dstPtr, ++src3) *dstPtr = *src3;
for(u32 i = 0; i < 8; ++i, ++dstPtr, ++src4) *dstPtr = *src4;
}
}
}
/*
=======================================================================================================================
Tile a raw image I8A8 format for WII
=======================================================================================================================
*/
void GDK_images_TileRawBufferForWiiI8A8
(
void * _pv_DestImg,
void * _pv_SrcImg,
u32 _u32_Width,
u32 _u32_Height
)
{
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
u32 row, col;
u16 * dstPtr;
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
dstPtr = (u16*)_pv_DestImg;
// one tile is 32B 4 rows x 4 columns
for (row = 0; row < _u32_Height; row += 4)
{
for (col = 0; col < _u32_Width; col += 4)
{
u16* src1 = (u16*)_pv_SrcImg + ((row + 0) * _u32_Width + col);
u16* src2 = (u16*)_pv_SrcImg + ((row + 1) * _u32_Width + col);
u16* src3 = (u16*)_pv_SrcImg + ((row + 2) * _u32_Width + col);
u16* src4 = (u16*)_pv_SrcImg + ((row + 3) * _u32_Width + col);
for(u32 i = 0; i < 4; ++i, ++dstPtr, ++src1) *dstPtr = *src1;
for(u32 i = 0; i < 4; ++i, ++dstPtr, ++src2) *dstPtr = *src2;
for(u32 i = 0; i < 4; ++i, ++dstPtr, ++src3) *dstPtr = *src3;
for(u32 i = 0; i < 4; ++i, ++dstPtr, ++src4) *dstPtr = *src4;
}
}
}
void GDK_images_TileForWii
(
void * _pv_DestImg,
const void * _pv_SrcImg,
u32 _u32_Width,
u32 _u32_Height,
u32 _u32_BPP
)
{
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
const u32 tileSize = 32;
u32 nbXTiles, nbYTiles, nbTexelsPerTileX = 0, nbTexelsPerTileY = 0;
u8 u8_BytesPerColor = 0;
u8 * currARTilePtr = 0;
u8 * currGBTilePtr = 0;
u8 * currTilePtr = 0;
u32 Ix, Iy; // Image x and y;
u32 tileY, tileX;
u8 * srcImage = 0;
u32 tx, ty; // Tile x and y
u32 u32_Color = 0;
u16 u16_Color = 0;
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
// Set tiles and color size according to BPP (if palette, color size is not used)
switch (_u32_BPP)
{
case 32:
nbTexelsPerTileX = 4;
nbTexelsPerTileY = 4;
u8_BytesPerColor = 4;
break;
case 16:
nbTexelsPerTileX = 4;
nbTexelsPerTileY = 4;
u8_BytesPerColor = 2;
break;
case 8:
nbTexelsPerTileX = 8;
nbTexelsPerTileY = 4;
break;
default:
return;
}
// Destination pointers for mipmap 0
currARTilePtr = (u8 *) _pv_DestImg;
currGBTilePtr = (u8 *) _pv_DestImg + tileSize;
currTilePtr = (u8 *) _pv_DestImg;
// Set source pointers
srcImage = (u8 *) _pv_SrcImg;
u32 un = 1;
nbXTiles = std::max(un, _u32_Width / nbTexelsPerTileX);
nbYTiles = std::max(un, _u32_Height / nbTexelsPerTileY);
// For each tile
for (tileY = 0; tileY < nbYTiles; tileY++)
{
for (tileX = 0; tileX < nbXTiles; tileX++)
{
// Fill the tiles texel by texel
for (ty = 0 ; ty < nbTexelsPerTileY ; ty++)
{
for (tx = 0 ; tx < nbTexelsPerTileX ; tx++)
{
Ix = (tileX * nbTexelsPerTileX + tx);
Iy = (tileY * nbTexelsPerTileY + ty);
if (Ix < _u32_Width && Iy < _u32_Height)
{
// Fill dest buffer according to BPP
switch (_u32_BPP)
{
case 32:
u32_Color = *(u32 *)(srcImage + u8_BytesPerColor * (Iy * _u32_Width + Ix));
*currARTilePtr = (u8)((u32_Color & 0xFF000000) >> 24);
*(currARTilePtr + 1) = (u8)((u32_Color & 0x00FF0000) >> 16);
//*(currARTilePtr + 1) = (_u32_Flags & K3D_C_texture_NoInvertRB) ? (u8)((u32_Color & 0x0000FF00) >> 8) : (u8)((u32_Color & 0xFF000000) >> 24);
*currGBTilePtr = (u8)((u32_Color & 0x0000FF00) >> 8);
*(currGBTilePtr + 1) = (u8)((u32_Color & 0x000000FF) >> 0);
//*(currGBTilePtr + 1) = (_u32_Flags & K3D_C_texture_NoInvertRB) ? (u8)((u32_Color & 0xFF000000) >> 24) : (u8)((u32_Color & 0x0000FF00) >> 8);
break;
case 16:
u16_Color = *(u16 *)(srcImage + u8_BytesPerColor * (Iy * _u32_Width + Ix));
*currTilePtr = (u8)(u16_Color >> 8);
*++currTilePtr = (u8)(u16_Color);
break;
case 8:
*currTilePtr = *(srcImage + _u32_Width * Iy + Ix);
break;
default:
*currARTilePtr = 0xFF;
*(currARTilePtr + 1) = 0xFF;
*currGBTilePtr = 0x00;
*(currGBTilePtr + 1) = 0x00;
break;
}
}
currARTilePtr += 2;
currGBTilePtr += 2;
currTilePtr++;
}
}
currARTilePtr += tileSize;
currGBTilePtr += tileSize;
}
}
}