From 4b0f2ea43929cbce781a4a8f84acb6aa041234ed Mon Sep 17 00:00:00 2001 From: fgsfds Date: Sun, 20 Aug 2023 17:26:11 +0200 Subject: [PATCH] port: unswizzle pre-swizzled textures --- port/src/preprocess.c | 10 ++++- src/game/texdecompress.c | 71 +++++++++++++++++++++++++++++++- src/include/game/texdecompress.h | 4 ++ 3 files changed, 82 insertions(+), 3 deletions(-) diff --git a/port/src/preprocess.c b/port/src/preprocess.c index ce5d76d41..1349254f2 100644 --- a/port/src/preprocess.c +++ b/port/src/preprocess.c @@ -8,9 +8,10 @@ #include "platform.h" #include "data.h" #include "bss.h" +#include "game/setuputils.h" +#include "game/texdecompress.h" #include "preprocess.h" #include "romdata.h" -#include "game/setuputils.h" static inline f32 swapF32(f32 x) { *(u32 *)&x = PD_BE32(*(u32 *)&x); return x; } static inline u32 swapU32(u32 x) { return PD_BE32(x); } @@ -1050,6 +1051,13 @@ void preprocessModel(u8 *base, u32 ofs) struct textureconfig *texconfigs = PD_PTR_BASEOFS(mdl->texconfigs, base, ofs); for (s16 i = 0; i < mdl->numtexconfigs; ++i) { PD_SWAP_VAL(texconfigs[i].texturenum); + if ((texconfigs[i].texturenum & 0xf000000) == 0x5000000) { + // embedded texture; we need to unswizzle this + u8 *texdata = PD_PTR_BASEOFS(texconfigs[i].texturenum, base, ofs); + // figure out the format and unswizzle + const s32 format = texConfigToFormat(&texconfigs[i]); + texSwapAltRowBytesInternal(texdata, texconfigs[i].width, texconfigs[i].height, format); + } } } diff --git a/src/game/texdecompress.c b/src/game/texdecompress.c index 8e70e5ec8..70a04f684 100644 --- a/src/game/texdecompress.c +++ b/src/game/texdecompress.c @@ -1907,9 +1907,77 @@ s32 texInflateLookupFromBuffer(u8 *src, s32 width, s32 height, u8 *dst, u8 *look * For textures with 32-bit colour values (in GBI format), swap every pair * within each word. For all other textures, swap every byte within each pair. */ +#ifdef PLATFORM_N64 +void texSwapAltRowBytes(u8 *dst, s32 width, s32 height, s32 format) +#else +s32 texConfigToFormat(const struct textureconfig *tex) +{ + switch (tex->format) { + case G_IM_FMT_I: + switch (tex->depth) { + case G_IM_SIZ_4b: + return TEXFORMAT_I4; + case G_IM_SIZ_8b: + return TEXFORMAT_I8; + default: + break; + } + break; + case G_IM_FMT_IA: + switch (tex->depth) { + case G_IM_SIZ_4b: + return TEXFORMAT_IA4; + case G_IM_SIZ_8b: + return TEXFORMAT_IA8; + case G_IM_SIZ_16b: + return TEXFORMAT_IA16; + default: + break; + } + break; + case G_IM_FMT_CI: + switch (tex->depth) { + case G_IM_SIZ_4b: + return TEXFORMAT_IA16_CI4; + case G_IM_SIZ_8b: + return TEXFORMAT_IA16_CI8; + default: + break; + } + break; + case G_IM_FMT_RGBA: + switch (tex->depth) { + case G_IM_SIZ_4b: + return TEXFORMAT_RGBA16_CI4; + case G_IM_SIZ_8b: + return TEXFORMAT_RGBA16_CI8; + case G_IM_SIZ_16b: + return TEXFORMAT_RGBA16; + case G_IM_SIZ_32b: + return TEXFORMAT_RGBA32; + default: + break; + } + break; + default: + break; + } + + return TEXFORMAT_I8; +} + void texSwapAltRowBytes(u8 *dst, s32 width, s32 height, s32 format) { -#ifdef PLATFORM_N64 // the N64 GPU wants interleaved data, we don't + /** + * The N64 GPU wants swizzled textures, we don't. + * Thus this function is stubbed out, but its functionality is still made + * available for unswizzling the embedded textures in preprocess.c. + */ +} + +void texSwapAltRowBytesInternal(u8 *dst, s32 width, s32 height, s32 format) +#endif +{ s32 x; s32 y; s32 alignedwidth; @@ -1967,7 +2035,6 @@ void texSwapAltRowBytes(u8 *dst, s32 width, s32 height, s32 format) row += alignedwidth * 2; } } -#endif } /** diff --git a/src/include/game/texdecompress.h b/src/include/game/texdecompress.h index 5c2c70d5d..d82a670e3 100644 --- a/src/include/game/texdecompress.h +++ b/src/include/game/texdecompress.h @@ -35,5 +35,9 @@ void texLoadFromDisplayList(Gfx *gdl, struct texpool *pool, s32 arg2); void texLoad(texnum_t *updateword, struct texpool *pool, bool arg2); void texLoadFromConfigs(struct textureconfig *configs, s32 numconfigs, struct texpool *pool, s32 arg3); void texLoadFromTextureNum(u32 arg0, struct texpool *pool); +#ifndef PLATFORM_N64 +void texSwapAltRowBytesInternal(u8 *dst, s32 width, s32 height, s32 format); +s32 texConfigToFormat(const struct textureconfig *tex); +#endif #endif