diff --git a/data/dynos.c.h b/data/dynos.c.h index 911d17a5..44a11fa7 100644 --- a/data/dynos.c.h +++ b/data/dynos.c.h @@ -12,7 +12,7 @@ void *dynos_swap_cmd(void *cmd); void *dynos_update_cmd (void *cmd); void dynos_update_gfx (); void dynos_update_opt (void *pad); -s32 dynos_gfx_import_texture (void **output, void *ptr, s32 tile, void *grapi, void **hashmap, void *pool, s32 *poolpos, s32 poolsize); +s32 dynos_tex_import (void **output, void *ptr, s32 tile, void *grapi, void **hashmap, void *pool, s32 *poolpos, s32 poolsize); void dynos_gfx_swap_animations(void *ptr); // -- warps -- // diff --git a/data/dynos.cpp.h b/data/dynos.cpp.h index e00a8a28..e0d1dd15 100644 --- a/data/dynos.cpp.h +++ b/data/dynos.cpp.h @@ -672,8 +672,6 @@ void DynOS_Opt_DrawPrompt(DynosOption *aCurrentMenu, DynosOption *aOptionsMenu, // Gfx // -u8 *DynOS_Gfx_TextureConvertToRGBA32(const u8 *aData, u64 aLength, s32 aFormat, s32 aSize, const u8 *aPalette); -bool DynOS_Gfx_ImportTexture(void **aOutput, void *aPtr, s32 aTile, void *aGfxRApi, void **aHashMap, void *aPool, u32 *aPoolPos, u32 aPoolSize); Array &DynOS_Gfx_GetActorList(); Array &DynOS_Gfx_GetPacks(); Array &DynOS_Gfx_GetPacksEnabled(); @@ -759,13 +757,21 @@ const void *DynOS_Actor_GetLayoutFromName(const char *aActorName); s32 DynOS_Actor_GetIndex(const void *aGeoLayout); bool DynOS_Actor_IsCustom(s32 aIndex); +// +// Tex Manager +// + +void DynOS_Tex_Valid(GfxData* aGfxData); +void DynOS_Tex_Invalid(GfxData* aGfxData); +u8 *DynOS_Tex_ConvertToRGBA32(const u8 *aData, u64 aLength, s32 aFormat, s32 aSize, const u8 *aPalette); +bool DynOS_Tex_Import(void **aOutput, void *aPtr, s32 aTile, void *aGfxRApi, void **aHashMap, void *aPool, u32 *aPoolPos, u32 aPoolSize); + // // Lvl Manager // Array> &DynOS_Lvl_GetArray(); void DynOS_Lvl_Activate(s32 modIndex, const SysPath &aFilePath, const char *aLevelName); -DataNode* DynOS_Lvl_GetTexture(void *aPtr); GfxData* DynOS_Lvl_GetActiveGfx(void); const char* DynOS_Lvl_GetToken(u32 index); DataNode* DynOS_Lvl_GetMovtexQuadCollection(s32 index); diff --git a/data/dynos_bin_tex.cpp b/data/dynos_bin_tex.cpp index ab8cea71..51c860e8 100644 --- a/data/dynos_bin_tex.cpp +++ b/data/dynos_bin_tex.cpp @@ -37,7 +37,7 @@ void DynOS_Tex_ConvertTextureDataToPng(GfxData *aGfxData, TexData* aTexture) { // Convert to RGBA32 const u8 *_Palette = (aGfxData->mGfxContext.mCurrentPalette ? aGfxData->mGfxContext.mCurrentPalette->mData->mRawData.begin() : NULL); - u8 *_Buffer = DynOS_Gfx_TextureConvertToRGBA32(aTexture->mRawData.begin(), aTexture->mRawData.Count(), aTexture->mRawFormat, aTexture->mRawSize, _Palette); + u8 *_Buffer = DynOS_Tex_ConvertToRGBA32(aTexture->mRawData.begin(), aTexture->mRawData.Count(), aTexture->mRawFormat, aTexture->mRawSize, _Palette); if (_Buffer == NULL) { PrintError(" ERROR: Unknown texture format"); return; diff --git a/data/dynos_c.cpp b/data/dynos_c.cpp index 49388610..600f0774 100644 --- a/data/dynos_c.cpp +++ b/data/dynos_c.cpp @@ -20,8 +20,8 @@ void dynos_update_opt(void *pad) { return DynOS_UpdateOpt(pad); } -s32 dynos_gfx_import_texture(void **output, void *ptr, s32 tile, void *grapi, void **hashmap, void *pool, s32 *poolpos, s32 poolsize) { - return DynOS_Gfx_ImportTexture(output, ptr, tile, grapi, hashmap, pool, (u32 *) poolpos, (u32) poolsize); +s32 dynos_tex_import(void **output, void *ptr, s32 tile, void *grapi, void **hashmap, void *pool, s32 *poolpos, s32 poolsize) { + return DynOS_Tex_Import(output, ptr, tile, grapi, hashmap, pool, (u32 *) poolpos, (u32) poolsize); } void dynos_gfx_swap_animations(void *ptr) { diff --git a/data/dynos_gfx_update.cpp b/data/dynos_gfx_update.cpp index 866f80db..224bbda8 100644 --- a/data/dynos_gfx_update.cpp +++ b/data/dynos_gfx_update.cpp @@ -147,6 +147,7 @@ void DynOS_Gfx_Update() { _ActorGfx->mGfxData = _GfxData; _ActorGfx->mGraphNode = (GraphNode *) DynOS_Geo_GetGraphNode((*(_GfxData->mGeoLayouts.end() - 1))->mData, true); _ActorGfx->mGraphNode->georef = DynOS_Actor_GetLayoutFromIndex(_ActorIndex); + DynOS_Tex_Valid(_GfxData); break; } } @@ -154,6 +155,7 @@ void DynOS_Gfx_Update() { // If disabled and this pack is the one selected // replace the actor's model by the default one else if (!_Enabled[i] && _ActorGfx->mPackIndex == i) { + DynOS_Tex_Invalid(_ActorGfx->mGfxData); _ActorGfx->mPackIndex = -1; _ActorGfx->mGfxData = NULL; _ActorGfx->mGraphNode = (GraphNode *) DynOS_Geo_GetGraphNode(DynOS_Actor_GetLayoutFromIndex(_ActorIndex), true); diff --git a/data/dynos_mgr_actor.cpp b/data/dynos_mgr_actor.cpp index f6ee4a36..008df908 100644 --- a/data/dynos_mgr_actor.cpp +++ b/data/dynos_mgr_actor.cpp @@ -49,6 +49,7 @@ void DynOS_Actor_AddCustom(const SysPath &aFilename, const char *aActorName) { pActorGfxList[index].mPackIndex = 99; pActorGfxList[index].mGfxData = _GfxData; pActorGfxList[index].mGraphNode = (GraphNode *) DynOS_Geo_GetGraphNode(geoLayout, false); + DynOS_Tex_Valid(_GfxData); } s32 DynOS_Actor_GetCount() { diff --git a/data/dynos_mgr_lvl.cpp b/data/dynos_mgr_lvl.cpp index d15dfe6f..d4ecf3a6 100644 --- a/data/dynos_mgr_lvl.cpp +++ b/data/dynos_mgr_lvl.cpp @@ -55,20 +55,7 @@ void DynOS_Lvl_Activate(s32 modIndex, const SysPath &aFilename, const char *aLev DynOS_Level_Override((void*)originalScript, newScriptNode->mData); sDynosOverrideLevelScripts.Add({ originalScript, newScriptNode->mData, _Node}); -} - -DataNode *DynOS_Lvl_GetTexture(void *aPtr) { - for (s32 i = 0; i < sDynosCustomLevelScripts.Count(); ++i) { - auto &mTextures = sDynosCustomLevelScripts[i].second->mTextures; - for (s32 j = 0; j < mTextures.Count(); j++) { - auto &texture = mTextures[j]; - if (texture == aPtr) { - return texture; - } - - } - } - return NULL; + DynOS_Tex_Valid(_Node); } GfxData* DynOS_Lvl_GetActiveGfx(void) { diff --git a/data/dynos_gfx_texture.cpp b/data/dynos_mgr_tex.cpp similarity index 83% rename from data/dynos_gfx_texture.cpp rename to data/dynos_mgr_tex.cpp index e533c14f..8476235a 100644 --- a/data/dynos_gfx_texture.cpp +++ b/data/dynos_mgr_tex.cpp @@ -1,8 +1,11 @@ +#include #include "dynos.cpp.h" extern "C" { #include "pc/gfx/gfx_rendering_api.h" } +static std::set *> sDynosValidTextures; + // // Conversion // @@ -162,7 +165,7 @@ static u8 *I8_RGBA32(const u8 *aData, u64 aLength) { return _Buffer; } -u8 *DynOS_Gfx_TextureConvertToRGBA32(const u8 *aData, u64 aLength, s32 aFormat, s32 aSize, const u8 *aPalette) { +u8 *DynOS_Tex_ConvertToRGBA32(const u8 *aData, u64 aLength, s32 aFormat, s32 aSize, const u8 *aPalette) { switch ((aFormat << 8) | aSize ) { case ((G_IM_FMT_RGBA << 8) | G_IM_SIZ_16b): return RGBA16_RGBA32(aData, aLength); case ((G_IM_FMT_RGBA << 8) | G_IM_SIZ_32b): return RGBA32_RGBA32(aData, aLength); @@ -182,7 +185,7 @@ u8 *DynOS_Gfx_TextureConvertToRGBA32(const u8 *aData, u64 aLength, s32 aFormat, // typedef struct GfxRenderingAPI GRAPI; -static void DynOS_Gfx_UploadTexture(DataNode *aNode, GRAPI *aGfxRApi, s32 aTile, s32 aTexId) { +static void DynOS_Tex_Upload(DataNode *aNode, GRAPI *aGfxRApi, s32 aTile, s32 aTexId) { aGfxRApi->select_texture(aTile, aTexId); aGfxRApi->upload_texture(aNode->mData->mRawData.begin(), aNode->mData->mRawWidth, aNode->mData->mRawHeight); aNode->mData->mUploaded = true; @@ -201,7 +204,7 @@ struct THN { bool mLInf; }; -static bool DynOS_Gfx_CacheTexture(THN **aOutput, DataNode *aNode, s32 aTile, GRAPI *aGfxRApi, THN **aHashMap, THN *aPool, u32 *aPoolPos, u32 aPoolSize) { +static bool DynOS_Tex_Cache(THN **aOutput, DataNode *aNode, s32 aTile, GRAPI *aGfxRApi, THN **aHashMap, THN *aPool, u32 *aPoolPos, u32 aPoolSize) { // Find texture in cache uintptr_t _Hash = ((uintptr_t) aNode) & ((aPoolSize * 2) - 1); @@ -210,7 +213,7 @@ static bool DynOS_Gfx_CacheTexture(THN **aOutput, DataNode *aNode, s32 if ((*_Node)->mAddr == (const void *) aNode) { aGfxRApi->select_texture(aTile, (*_Node)->mTexId); if (!aNode->mData->mUploaded) { - DynOS_Gfx_UploadTexture(aNode, aGfxRApi, aTile, (*_Node)->mTexId); + DynOS_Tex_Upload(aNode, aGfxRApi, aTile, (*_Node)->mTexId); } (*aOutput) = (*_Node); return true; @@ -242,37 +245,46 @@ static bool DynOS_Gfx_CacheTexture(THN **aOutput, DataNode *aNode, s32 return false; } +// +// Make textures valid/invalid +// + +void DynOS_Tex_Valid(GfxData* aGfxData) { + for (auto &_Texture : aGfxData->mTextures) { + sDynosValidTextures.insert(_Texture); + } +} + +void DynOS_Tex_Invalid(GfxData* aGfxData) { + for (auto &_Texture : aGfxData->mTextures) { + sDynosValidTextures.erase(_Texture); + } +} + // // Import // -static DataNode *DynOS_Gfx_RetrieveNode(void *aPtr) { - Array &pActorGfxList = DynOS_Gfx_GetActorList(); - for (auto& _ActorGfx : pActorGfxList) { - if (_ActorGfx.mGfxData) { - for (auto &_Node : _ActorGfx.mGfxData->mTextures) { - if ((void*) _Node == aPtr) { - return _Node; - } - } - } +static DataNode *DynOS_Tex_RetrieveNode(void *aPtr) { + if (sDynosValidTextures.find((DataNode*)aPtr) != sDynosValidTextures.end()) { + return (DataNode*)aPtr; } - return DynOS_Lvl_GetTexture(aPtr); + return NULL; } -static bool DynOS_Gfx_ImportTexture_Typed(THN **aOutput, void *aPtr, s32 aTile, GRAPI *aGfxRApi, THN **aHashMap, THN *aPool, u32 *aPoolPos, u32 aPoolSize) { - DataNode *_Node = DynOS_Gfx_RetrieveNode(aPtr); +static bool DynOS_Tex_Import_Typed(THN **aOutput, void *aPtr, s32 aTile, GRAPI *aGfxRApi, THN **aHashMap, THN *aPool, u32 *aPoolPos, u32 aPoolSize) { + DataNode *_Node = DynOS_Tex_RetrieveNode(aPtr); if (_Node) { - if (!DynOS_Gfx_CacheTexture(aOutput, _Node, aTile, aGfxRApi, aHashMap, aPool, aPoolPos, aPoolSize)) { - DynOS_Gfx_UploadTexture(_Node, aGfxRApi, aTile, (*aOutput)->mTexId); + if (!DynOS_Tex_Cache(aOutput, _Node, aTile, aGfxRApi, aHashMap, aPool, aPoolPos, aPoolSize)) { + DynOS_Tex_Upload(_Node, aGfxRApi, aTile, (*aOutput)->mTexId); } return true; } return false; } -bool DynOS_Gfx_ImportTexture(void **aOutput, void *aPtr, s32 aTile, void *aGfxRApi, void **aHashMap, void *aPool, u32 *aPoolPos, u32 aPoolSize) { - return DynOS_Gfx_ImportTexture_Typed( +bool DynOS_Tex_Import(void **aOutput, void *aPtr, s32 aTile, void *aGfxRApi, void **aHashMap, void *aPool, u32 *aPoolPos, u32 aPoolSize) { + return DynOS_Tex_Import_Typed( (THN **) aOutput, (void *) aPtr, (s32) aTile, diff --git a/src/pc/gfx/gfx_pc.c b/src/pc/gfx/gfx_pc.c index aecd4039..905d6e24 100644 --- a/src/pc/gfx/gfx_pc.c +++ b/src/pc/gfx/gfx_pc.c @@ -602,8 +602,8 @@ static bool preload_texture(UNUSED void *user, const char *path) { #endif // EXTERNAL_DATA static void import_texture(int tile) { - extern s32 dynos_gfx_import_texture(void **output, void *ptr, s32 tile, void *grapi, void **hashmap, void *pool, s32 *poolpos, s32 poolsize); - if (dynos_gfx_import_texture((void **) &rendering_state.textures[tile], (void *) rdp.loaded_texture[tile].addr, tile, gfx_rapi, (void **) gfx_texture_cache.hashmap, (void *) gfx_texture_cache.pool, (int *) &gfx_texture_cache.pool_pos, MAX_CACHED_TEXTURES)) { return; } + extern s32 dynos_tex_import(void **output, void *ptr, s32 tile, void *grapi, void **hashmap, void *pool, s32 *poolpos, s32 poolsize); + if (dynos_tex_import((void **) &rendering_state.textures[tile], (void *) rdp.loaded_texture[tile].addr, tile, gfx_rapi, (void **) gfx_texture_cache.hashmap, (void *) gfx_texture_cache.pool, (int *) &gfx_texture_cache.pool_pos, MAX_CACHED_TEXTURES)) { return; } uint8_t fmt = rdp.texture_tile.fmt; uint8_t siz = rdp.texture_tile.siz;