summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--soh/soh/Enhancements/game-interactor/GameInteractor.h2
-rw-r--r--soh/soh/Enhancements/game-interactor/GameInteractor_Hooks.cpp6
-rw-r--r--soh/soh/Enhancements/game-interactor/GameInteractor_Hooks.h4
-rw-r--r--soh/soh/OTRGlobals.cpp40
-rw-r--r--soh/soh/OTRGlobals.h4
-rw-r--r--soh/soh/SohMenuBar.cpp3
-rw-r--r--soh/src/code/z_room.c5
-rw-r--r--soh/src/overlays/actors/ovl_Boss_Dodongo/z_boss_dodongo.c228
8 files changed, 261 insertions, 31 deletions
diff --git a/soh/soh/Enhancements/game-interactor/GameInteractor.h b/soh/soh/Enhancements/game-interactor/GameInteractor.h
index ae711c093..809ccda09 100644
--- a/soh/soh/Enhancements/game-interactor/GameInteractor.h
+++ b/soh/soh/Enhancements/game-interactor/GameInteractor.h
@@ -193,6 +193,8 @@ public:
DEFINE_HOOK(OnSetGameLanguage, void());
+ DEFINE_HOOK(OnAssetAltChange, void());
+
// Helpers
static bool IsSaveLoaded();
static bool IsGameplayPaused();
diff --git a/soh/soh/Enhancements/game-interactor/GameInteractor_Hooks.cpp b/soh/soh/Enhancements/game-interactor/GameInteractor_Hooks.cpp
index 13df133a0..4bd5354a6 100644
--- a/soh/soh/Enhancements/game-interactor/GameInteractor_Hooks.cpp
+++ b/soh/soh/Enhancements/game-interactor/GameInteractor_Hooks.cpp
@@ -181,3 +181,9 @@ void GameInteractor_ExecuteOnUpdateFileNameSelection(int16_t charCode) {
void GameInteractor_ExecuteOnSetGameLanguage() {
GameInteractor::Instance->ExecuteHooks<GameInteractor::OnSetGameLanguage>();
}
+
+// MARK: - System
+
+void GameInteractor_RegisterOnAssetAltChange(void (*fn)(void)) {
+ GameInteractor::Instance->RegisterGameHook<GameInteractor::OnAssetAltChange>(fn);
+}
diff --git a/soh/soh/Enhancements/game-interactor/GameInteractor_Hooks.h b/soh/soh/Enhancements/game-interactor/GameInteractor_Hooks.h
index 47114a300..7b7b226fa 100644
--- a/soh/soh/Enhancements/game-interactor/GameInteractor_Hooks.h
+++ b/soh/soh/Enhancements/game-interactor/GameInteractor_Hooks.h
@@ -56,6 +56,10 @@ void GameInteractor_ExecuteOnUpdateFileNameSelection(int16_t charCode);
// MARK: - Game
void GameInteractor_ExecuteOnSetGameLanguage();
+
+// MARK: - System
+void GameInteractor_RegisterOnAssetAltChange(void (*fn)(void));
+
#ifdef __cplusplus
}
#endif
diff --git a/soh/soh/OTRGlobals.cpp b/soh/soh/OTRGlobals.cpp
index ad57d1ca5..2eb72591d 100644
--- a/soh/soh/OTRGlobals.cpp
+++ b/soh/soh/OTRGlobals.cpp
@@ -1216,6 +1216,7 @@ extern "C" void Graph_StartFrame() {
case KbScancode::LUS_KB_TAB: {
// Toggle HD Assets
CVarSetInteger("gAltAssets", !CVarGetInteger("gAltAssets", 0));
+ GameInteractor::Instance->ExecuteHooks<GameInteractor::OnAssetAltChange>();
ShouldClearTextureCacheAtEndOfFrame = true;
break;
}
@@ -1415,6 +1416,14 @@ extern "C" void ResourceMgr_DirtyDirectory(const char* resName) {
LUS::Context::GetInstance()->GetResourceManager()->DirtyDirectory(resName);
}
+extern "C" void ResourceMgr_UnloadResource(const char* resName) {
+ std::string path = resName;
+ if (path.substr(0, 7) == "__OTR__") {
+ path = path.substr(7);
+ }
+ auto res = LUS::Context::GetInstance()->GetResourceManager()->UnloadResource(path);
+}
+
// OTRTODO: There is probably a more elegant way to go about this...
// Kenix: This is definitely leaking memory when it's called.
extern "C" char** ResourceMgr_ListFiles(const char* searchMask, int* resultSize) {
@@ -1441,6 +1450,27 @@ extern "C" uint8_t ResourceMgr_FileExists(const char* filePath) {
return ExtensionCache.contains(path);
}
+extern "C" uint8_t ResourceMgr_FileAltExists(const char* filePath) {
+ std::string path = filePath;
+ if (path.substr(0, 7) == "__OTR__") {
+ path = path.substr(7);
+ }
+
+ if (path.substr(0, 4) != "alt/") {
+ path = "alt/" + path;
+ }
+
+ return ExtensionCache.contains(path);
+}
+
+// Unloads a resource if an alternate version exists when alt assets are enabled
+// The resource is only removed from the internal cache to prevent it from used in the next resource lookup
+extern "C" void ResourceMgr_UnloadOriginalWhenAltExists(const char* resName) {
+ if (CVarGetInteger("gAltAssets", 0) && ResourceMgr_FileAltExists((char*) resName)) {
+ ResourceMgr_UnloadResource((char*) resName);
+ }
+}
+
extern "C" void ResourceMgr_LoadFile(const char* resName) {
LUS::Context::GetInstance()->GetResourceManager()->LoadResource(resName);
}
@@ -1480,6 +1510,11 @@ extern "C" char* ResourceMgr_LoadFileFromDisk(const char* filePath) {
return data;
}
+extern "C" uint8_t ResourceMgr_TexIsRaw(const char* texPath) {
+ auto res = std::static_pointer_cast<LUS::Texture>(GetResourceByNameHandlingMQ(texPath));
+ return res->Flags & TEX_FLAG_LOAD_AS_RAW;
+}
+
extern "C" uint8_t ResourceMgr_ResourceIsBackground(char* texPath) {
auto res = GetResourceByNameHandlingMQ(texPath);
return res->GetInitData()->Type == LUS::ResourceType::SOH_Background;
@@ -1565,6 +1600,11 @@ extern "C" void ResourceMgr_PushCurrentDirectory(char* path)
extern "C" Gfx* ResourceMgr_LoadGfxByName(const char* path)
{
+ // When an alt resource exists for the DL, we need to unload the original asset
+ // to clear the cache so the alt asset will be loaded instead
+ // OTRTODO: If Alt loading over original cache is fixed, this line can most likely be removed
+ ResourceMgr_UnloadOriginalWhenAltExists(path);
+
auto res = std::static_pointer_cast<LUS::DisplayList>(GetResourceByNameHandlingMQ(path));
return (Gfx*)&res->Instructions[0];
}
diff --git a/soh/soh/OTRGlobals.h b/soh/soh/OTRGlobals.h
index e00cfecd5..9b42e6895 100644
--- a/soh/soh/OTRGlobals.h
+++ b/soh/soh/OTRGlobals.h
@@ -86,11 +86,15 @@ uint32_t ResourceMgr_GetGameVersion(int index);
uint32_t ResourceMgr_GetGamePlatform(int index);
uint32_t ResourceMgr_GetGameRegion(int index);
void ResourceMgr_LoadDirectory(const char* resName);
+void ResourceMgr_UnloadResource(const char* resName);
char** ResourceMgr_ListFiles(const char* searchMask, int* resultSize);
uint8_t ResourceMgr_FileExists(const char* resName);
+uint8_t ResourceMgr_FileAltExists(const char* resName);
+void ResourceMgr_UnloadOriginalWhenAltExists(const char* resName);
char* GetResourceDataByNameHandlingMQ(const char* path);
void ResourceMgr_LoadFile(const char* resName);
char* ResourceMgr_LoadFileFromDisk(const char* filePath);
+uint8_t ResourceMgr_TexIsRaw(const char* texPath);
uint8_t ResourceMgr_ResourceIsBackground(char* texPath);
char* ResourceMgr_LoadJPEG(char* data, size_t dataSize);
uint16_t ResourceMgr_LoadTexWidthByName(char* texPath);
diff --git a/soh/soh/SohMenuBar.cpp b/soh/soh/SohMenuBar.cpp
index 8db6c7703..22746895f 100644
--- a/soh/soh/SohMenuBar.cpp
+++ b/soh/soh/SohMenuBar.cpp
@@ -907,6 +907,7 @@ void DrawEnhancementsMenu() {
if (ImGui::BeginMenu("Mods")) {
if (UIWidgets::PaddedEnhancementCheckbox("Use Alternate Assets", "gAltAssets", false, false)) {
ShouldClearTextureCacheAtEndOfFrame = true;
+ GameInteractor::Instance->ExecuteHooks<GameInteractor::OnAssetAltChange>();
}
UIWidgets::Tooltip("Toggle between standard assets and alternate assets. Usually mods will indicate if this setting has to be used or not.");
UIWidgets::PaddedEnhancementCheckbox("Disable Bomb Billboarding", "gDisableBombBillboarding", true, false);
@@ -1626,4 +1627,4 @@ void SohMenuBar::DrawElement() {
ImGui::EndMenuBar();
}
}
-} // namespace SohGui \ No newline at end of file
+} // namespace SohGui
diff --git a/soh/src/code/z_room.c b/soh/src/code/z_room.c
index ccbc93d0d..772978f09 100644
--- a/soh/src/code/z_room.c
+++ b/soh/src/code/z_room.c
@@ -277,6 +277,11 @@ void func_8009638C(Gfx** displayList, void* source, void* tlut, u16 width, u16 h
bg->b.imagePal = 0;
bg->b.imageFlip = CVarGetInteger("gMirroredWorld", 0) ? G_BG_FLAG_FLIPS : 0;
+ // When an alt resource exists for the background, we need to unload the original asset
+ // to clear the cache so the alt asset will be loaded instead
+ // OTRTODO: If Alt loading over original cache is fixed, this line can most likely be removed
+ ResourceMgr_UnloadOriginalWhenAltExists((char*) source);
+
if (ResourceMgr_ResourceIsBackground((char*) source)) {
char* blob = (char*) ResourceGetDataByName((char *) source);
swapAndConvertJPEG(blob);
diff --git a/soh/src/overlays/actors/ovl_Boss_Dodongo/z_boss_dodongo.c b/soh/src/overlays/actors/ovl_Boss_Dodongo/z_boss_dodongo.c
index e90e36e80..be9778c6c 100644
--- a/soh/src/overlays/actors/ovl_Boss_Dodongo/z_boss_dodongo.c
+++ b/soh/src/overlays/actors/ovl_Boss_Dodongo/z_boss_dodongo.c
@@ -5,6 +5,14 @@
#include "scenes/dungeons/ddan_boss/ddan_boss_room_1.h"
#include "soh/frame_interpolation.h"
#include "soh/Enhancements/boss-rush/BossRush.h"
+#include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h"
+
+#include <stdlib.h> // malloc
+#include <string.h> // memcpy
+
+// OTRTODO: Replace usage of this method when we can clear the cache
+// for a single texture without the need of a DL opcode in the render code
+void gfx_texture_cache_clear();
#define FLAGS (ACTOR_FLAG_TARGETABLE | ACTOR_FLAG_HOSTILE | ACTOR_FLAG_UPDATE_WHILE_CULLED | ACTOR_FLAG_DRAW_WHILE_CULLED)
@@ -59,6 +67,13 @@ static u8 sMaskTex8x8[8 * 8] = { { 0 } };
static u8 sMaskTex8x32[8 * 32] = { { 0 } };
static u8 sMaskTexLava[32 * 64] = { { 0 } };
+static u32* sLavaFloorModifiedTexRaw = NULL;
+static u32* sLavaWavyTexRaw = NULL;
+static u16 sLavaFloorModifiedTex[4096];
+static u16 sLavaWavyTex[2048];
+
+static u8 hasRegisteredBlendedHook = 0;
+
static InitChainEntry sInitChain[] = {
ICHAIN_U8(targetMode, 5, ICHAIN_CONTINUE),
ICHAIN_S8(naviEnemyId, 0x0C, ICHAIN_CONTINUE),
@@ -66,6 +81,70 @@ static InitChainEntry sInitChain[] = {
ICHAIN_F32(targetArrowOffset, 8200.0f, ICHAIN_STOP),
};
+void BossDodongo_RegisterBlendedLavaTextureUpdate() {
+ // Not in scene so there is nothing to do
+ if (gPlayState == NULL || gPlayState->sceneNum != SCENE_DODONGOS_CAVERN_BOSS) {
+ return;
+ }
+
+ // Free old textures
+ if (sLavaFloorModifiedTexRaw != NULL) {
+ free(sLavaFloorModifiedTexRaw);
+ sLavaFloorModifiedTexRaw = NULL;
+ }
+ if (sLavaWavyTexRaw != NULL) {
+ free(sLavaWavyTexRaw);
+ sLavaWavyTexRaw = NULL;
+ }
+
+ // Unload original textures to bypass cache result for lookups
+ ResourceMgr_UnloadOriginalWhenAltExists(sLavaFloorLavaTex);
+ ResourceMgr_UnloadOriginalWhenAltExists(sLavaFloorRockTex);
+ ResourceMgr_UnloadOriginalWhenAltExists(gDodongosCavernBossLavaFloorTex);
+
+ // When the texture is HD (raw) we need to work with u32 values for RGBA32
+ // Otherwise the original asset is u16 for RGBA16
+ if (ResourceMgr_TexIsRaw(sLavaFloorLavaTex)) {
+ u32* lavaTex = ResourceGetDataByName(sLavaFloorLavaTex);
+ size_t lavaSize = ResourceGetSizeByName(sLavaFloorLavaTex);
+ size_t floorSize = ResourceGetSizeByName(gDodongosCavernBossLavaFloorTex);
+
+ sLavaFloorModifiedTexRaw = malloc(lavaSize);
+ sLavaWavyTexRaw = malloc(floorSize);
+
+ memcpy(sLavaFloorModifiedTexRaw, lavaTex, lavaSize);
+
+ // When KD is dead, just immediately copy the rock texture
+ if (Flags_GetClear(gPlayState, gPlayState->roomCtx.curRoom.num)) {
+ u32* rockTex = ResourceGetDataByName(sLavaFloorRockTex);
+ size_t rockSize = ResourceGetSizeByName(sLavaFloorRockTex);
+ memcpy(sLavaFloorModifiedTexRaw, rockTex, rockSize);
+ }
+
+ memcpy(sLavaWavyTexRaw, sLavaFloorModifiedTexRaw, floorSize);
+
+ // Register the blended effect for the raw texture
+ Gfx_RegisterBlendedTexture(gDodongosCavernBossLavaFloorTex, sMaskTexLava, sLavaWavyTexRaw);
+ } else {
+ u16* lavaTex = ResourceGetDataByName(sLavaFloorLavaTex);
+ memcpy(sLavaFloorModifiedTex, lavaTex, sizeof(sLavaFloorModifiedTex));
+
+ // When KD is dead, just immediately copy the rock texture
+ if (Flags_GetClear(gPlayState, gPlayState->roomCtx.curRoom.num)) {
+ u16* rockTex = ResourceGetDataByName(sLavaFloorRockTex);
+ size_t rockSize = ResourceGetSizeByName(sLavaFloorRockTex);
+ memcpy(sLavaFloorModifiedTex, rockTex, rockSize);
+ }
+
+ // Register the blended effect for the non-raw texture
+ memcpy(sLavaWavyTex, sLavaFloorModifiedTex, sizeof(sLavaWavyTex));
+
+ Gfx_RegisterBlendedTexture(gDodongosCavernBossLavaFloorTex, sMaskTexLava, sLavaWavyTex);
+ }
+
+ gfx_texture_cache_clear();
+}
+
void func_808C12C4(u8* arg1, s16 arg2) {
if (arg2[arg1] != 0) {
sMaskTex8x16[arg2 / 2] = 1;
@@ -86,12 +165,51 @@ void func_808C12C4(u8* arg1, s16 arg2) {
}
}
-void func_808C1554(void* arg0, void* floorTex, s32 arg2, f32 arg3) {
- arg0 = GetResourceDataByNameHandlingMQ(arg0);
- floorTex = ResourceGetDataByName(floorTex);
+// Same as func_808C1554 but works with u32 values for RGBA32 raw textures
+void func_808C1554_Raw(void* arg0, void* floorTex, s32 arg2, f32 arg3) {
+ u16 width = ResourceGetTexWidthByName(arg0);
+ s32 size = ResourceGetTexHeightByName(arg0) * width;
+
+ u32* temp_s3 = sLavaWavyTexRaw;
+ u32* temp_s1 = sLavaFloorModifiedTexRaw;
+ s32 i;
+ s32 i2;
+ u32* sp54 = malloc(size * sizeof(u32)); // Match the size for lava floor tex
+ s32 temp;
+ s32 temp2;
+
+ // Multiplier is used to try to scale the wavy effect to match the scale of the HD texture
+ // Applying sqrt(multiplier) to arg3 is to control how many pixels move left/right for the selected row
+ // Applying to arg2 and M_PI help to space out the wave effect
+ // It's not perfect but close enough
+ u16 multiplier = width / 32;
+
+ for (i = 0; i < size; i += width) {
+ temp = sinf((((i / width) + (s32)(((arg2 * multiplier) * 50.0f) / 100.0f)) & (width - 1)) * (M_PI / (16 * multiplier))) * (arg3 * sqrt(multiplier));
+ for (i2 = 0; i2 < width; i2++) {
+ sp54[i + ((temp + i2) & (width - 1))] = temp_s1[i + i2];
+ }
+ }
+ for (i = 0; i < width; i++) {
+ temp = sinf(((i + (s32)(((arg2 * multiplier) * 80.0f) / 100.0f)) & (width - 1)) * (M_PI / (16 * multiplier))) * (arg3 * sqrt(multiplier));
+ temp *= width;
+ for (i2 = 0; i2 < size; i2 += width) {
+ temp2 = (temp + i2) & (size - 1);
+ temp_s3[i + temp2] = sp54[i + i2];
+ }
+ }
+
+ free(sp54);
+
+ // Need to clear the cache after updating sLavaWavyTexRaw
+ gfx_texture_cache_clear();
+}
- u16* temp_s3 = SEGMENTED_TO_VIRTUAL(arg0);
- u16* temp_s1 = SEGMENTED_TO_VIRTUAL(floorTex);
+// Modified to support CPU modified texture with the resource system
+// Used for the original non-raw asset working with u16 values
+void func_808C1554(void* arg0, void* floorTex, s32 arg2, f32 arg3) {
+ u16* temp_s3 = sLavaWavyTex;
+ u16* temp_s1 = sLavaFloorModifiedTex;
s16 i;
s16 i2;
u16 sp54[2048];
@@ -112,6 +230,9 @@ void func_808C1554(void* arg0, void* floorTex, s32 arg2, f32 arg3) {
temp_s3[i + temp2] = sp54[i + i2];
}
}
+
+ // Need to clear the cache after updating sLavaWavyTex
+ gfx_texture_cache_clear();
}
void func_808C17C8(PlayState* play, Vec3f* arg1, Vec3f* arg2, Vec3f* arg3, f32 arg4, s16 arg5) {
@@ -187,27 +308,21 @@ void BossDodongo_Init(Actor* thisx, PlayState* play) {
Collider_SetJntSph(play, &this->collider, &this->actor, &sJntSphInit, this->items);
if (Flags_GetClear(play, play->roomCtx.curRoom.num)) { // KD is dead
- u16* LavaFloorTex = ResourceGetDataByName(gDodongosCavernBossLavaFloorTex);
- u16* LavaFloorRockTex = ResourceGetDataByName(sLavaFloorRockTex);
- temp_s1_3 = SEGMENTED_TO_VIRTUAL(LavaFloorTex);
- temp_s2 = SEGMENTED_TO_VIRTUAL(LavaFloorRockTex);
+ // SOH [General]
+ // Applying the "cooled off" lava rock CPU modified texture for re-visiting the scene
+ // is now handled by BossDodongo_RegisterBlendedLavaTextureUpdate below
+
Actor_Kill(&this->actor);
Actor_SpawnAsChild(&play->actorCtx, &this->actor, play, ACTOR_DOOR_WARP1, -890.0f, -1523.76f,
-3304.0f, 0, 0, 0, WARP_DUNGEON_CHILD);
Actor_Spawn(&play->actorCtx, play, ACTOR_BG_BREAKWALL, -890.0f, -1523.76f, -3304.0f, 0, 0, 0, 0x6000, true);
Actor_Spawn(&play->actorCtx, play, ACTOR_ITEM_B_HEART, -690.0f, -1523.76f, -3304.0f, 0, 0, 0, 0, true);
-
- for (int i = 0; i < ARRAY_COUNT(sMaskTexLava); i++) {
- sMaskTexLava[i] = 1;
- }
- } else {
- for (int i = 0; i < ARRAY_COUNT(sMaskTexLava); i++) {
- sMaskTexLava[i] = 0;
- }
}
this->actor.flags &= ~ACTOR_FLAG_TARGETABLE;
+ // #region SOH [General]
+ // Init mask values for all blended textures
for (int i = 0; i < ARRAY_COUNT(sMaskTex8x16); i++) {
sMaskTex8x16[i] = 0;
}
@@ -223,6 +338,12 @@ void BossDodongo_Init(Actor* thisx, PlayState* play) {
for (int i = 0; i < ARRAY_COUNT(sMaskTex32x16); i++) {
sMaskTex32x16[i] = 0;
}
+ // Set all true for the lava as it will always replace the scene texture
+ for (int i = 0; i < ARRAY_COUNT(sMaskTexLava); i++) {
+ sMaskTexLava[i] = 1;
+ }
+
+ // Register all blended textures
Gfx_RegisterBlendedTexture(object_kingdodongo_Tex_015890, sMaskTex8x16, NULL);
Gfx_RegisterBlendedTexture(object_kingdodongo_Tex_017210, sMaskTex8x32, NULL);
Gfx_RegisterBlendedTexture(object_kingdodongo_Tex_015D90, sMaskTex16x16, NULL);
@@ -234,10 +355,14 @@ void BossDodongo_Init(Actor* thisx, PlayState* play) {
Gfx_RegisterBlendedTexture(object_kingdodongo_Tex_016990, sMaskTex32x16, NULL);
Gfx_RegisterBlendedTexture(object_kingdodongo_Tex_016E10, sMaskTex32x16, NULL);
- // OTRTODO: This is causing OOB memory reads with HD assets
- // commenting this out means the lava will stay lava even after beating king d
- //
- // Gfx_RegisterBlendedTexture(gDodongosCavernBossLavaFloorTex, sMaskTexLava, sLavaFloorRockTex);
+ BossDodongo_RegisterBlendedLavaTextureUpdate();
+
+ // Register alt listener to update the blended lava for the replacement texture based on alt path
+ if (!hasRegisteredBlendedHook) {
+ GameInteractor_RegisterOnAssetAltChange(BossDodongo_RegisterBlendedLavaTextureUpdate);
+ hasRegisteredBlendedHook = 1;
+ }
+ // #endregion
}
void BossDodongo_Destroy(Actor* thisx, PlayState* play) {
@@ -1014,21 +1139,64 @@ void BossDodongo_Update(Actor* thisx, PlayState* play2) {
}
}
- // TODO The lave floor bubbles with an effect that modifies the texture. This needs to be recreated shader-side.
- //func_808C1554(gDodongosCavernBossLavaFloorTex, sLavaFloorLavaTex, this->unk_19E, this->unk_224);
+ // The lava bubbles with a wavy effect as a CPU modified texture
+ // This has been done by maintaining copied/modified texture values in the actor code
+ // The "cooling off" effect for the lava is pre-applied to the lava texture before applying
+ // the wavy effect. Since this is two effects and closely related to the actor, I've opted
+ // to handle them here rather than as a shader effect.
+ //
+ // Apply the corresponding wavy effect based on the texture being raw or not
+ if (ResourceMgr_TexIsRaw(gDodongosCavernBossLavaFloorTex)) {
+ func_808C1554_Raw(gDodongosCavernBossLavaFloorTex, sLavaFloorLavaTex, this->unk_19E, this->unk_224);
+ } else {
+ func_808C1554(gDodongosCavernBossLavaFloorTex, sLavaFloorLavaTex, this->unk_19E, this->unk_224);
+ }
}
+ // Apply the "cooling off" effect for the lava
if (this->unk_1C6 != 0) {
- u16* ptr1 = ResourceGetDataByName(sLavaFloorLavaTex);
- u16* ptr2 = ResourceGetDataByName(sLavaFloorRockTex);
- s16 i2;
+ // Similar to above, the cooling off effect is a CPU modified texture effect
+ // Apply corresponding to the texture being raw or not
+ if (ResourceMgr_TexIsRaw(sLavaFloorRockTex)) {
+ u32* ptr1 = sLavaFloorModifiedTexRaw;
+ u32* ptr2 = ResourceGetDataByName(sLavaFloorRockTex);
+ u16 width = ResourceGetTexWidthByName(sLavaFloorRockTex);
+ u16 height = ResourceGetTexHeightByName(sLavaFloorRockTex);
+ s16 i2;
+
+ // Get the scale based on the original texture size
+ u16 widthScale = width / 32;
+ u16 heightScale = height / 64;
+ u32 size = width * height;
+
+ for (i2 = 0; i2 < 20; i2++) {
+ s16 new_var = this->unk_1C2 & 0x7FF;
+ // Compute the index to a scaled position (scaling pseudo x,y as a 1D value)
+ s32 indexStart = ((new_var % 32) * widthScale) + ((new_var / 32) * width * heightScale);
+
+ // From the starting index, apply extra pixels right/down based on the scale
+ for (size_t j = 0; j < heightScale; j++) {
+ for (size_t i3 = 0; i3 < widthScale; i3++) {
+ s32 scaledIndex = (indexStart + i3 + (j * width)) & (size - 1);
+ ptr1[scaledIndex] = ptr2[scaledIndex];
+ }
+ }
+
+ this->unk_1C2 += 37;
+ }
+ } else {
+ u16* ptr1 = sLavaFloorModifiedTex;
+ u16* ptr2 = ResourceGetDataByName(sLavaFloorRockTex);
+ s16 i2;
- for (i2 = 0; i2 < 20; i2++) {
- s16 new_var = this->unk_1C2 & 0x7FF;
+ for (i2 = 0; i2 < 20; i2++) {
+ s16 new_var = this->unk_1C2 & 0x7FF;
- sMaskTexLava[new_var] = 1;
- this->unk_1C2 += 37;
+ ptr1[new_var] = ptr2[new_var];
+ this->unk_1C2 += 37;
+ }
}
+
Math_SmoothStepToF(&this->unk_224, 0.0f, 1.0f, 0.01f, 0.0f);
}