diff --git a/data/dynos.cpp.h b/data/dynos.cpp.h index a4da960df..259edaf36 100644 --- a/data/dynos.cpp.h +++ b/data/dynos.cpp.h @@ -1091,6 +1091,7 @@ bool DynOS_Bin_IsCompressed(const SysPath &aFilename); bool DynOS_Bin_Compress(const SysPath &aFilename); BinFile *DynOS_Bin_Decompress(const SysPath &aFilename); +void DynOS_Find_Pending_Scroll_Target(Vtx *data, Vtx *newData); void DynOS_Add_Scroll_Target(u32 index, const char *name, u32 offset, u32 size); #endif diff --git a/data/dynos_mgr_models.cpp b/data/dynos_mgr_models.cpp index 9d8cfeed3..58779547e 100644 --- a/data/dynos_mgr_models.cpp +++ b/data/dynos_mgr_models.cpp @@ -266,6 +266,7 @@ Gfx *DynOS_Model_Duplicate_DisplayList(Gfx* aGfx) { u32 size = C0(cmd, 12, 8) * sizeof(Vtx); Vtx *vtxDuplicate = (Vtx *) malloc(size); memcpy(vtxDuplicate, (Vtx *) cmd->words.w1, size); + DynOS_Find_Pending_Scroll_Target((Vtx *) cmd->words.w1, vtxDuplicate); cmd->words.w1 = (uintptr_t) vtxDuplicate; sCurrModelDuplicates->push_back(vtxDuplicate); } diff --git a/data/dynos_misc.cpp b/data/dynos_misc.cpp index 63723718e..c46b8c748 100644 --- a/data/dynos_misc.cpp +++ b/data/dynos_misc.cpp @@ -1,21 +1,9 @@ #include "dynos.cpp.h" +#ifdef max +#undef max +#endif +#include extern "C" { -#include "object_fields.h" -#include "engine/level_script.h" -#include "game/object_helpers.h" -#include "game/segment2.h" -#include "game/level_geo.h" -#include "game/level_update.h" -#include "game/moving_texture.h" -#include "game/paintings.h" -#include "game/geo_misc.h" -#include "game/mario_misc.h" -#include "game/mario_actions_cutscene.h" -#include "game/screen_transition.h" -#include "game/object_list_processor.h" -#include "game/behavior_actions.h" -#include "game/rendering_graph_node.h" -#include "game/skybox.h" #include "game/scroll_targets.h" } @@ -117,16 +105,37 @@ s32 DynOS_String_Width(const u8 *aStr64) { // Scroll Targets // +struct PendingScrollTarget { + u32 mIndex; + u32 mOffset; + u32 mSize; + Vtx *mData; +}; + +static std::vector sPendingScrollTargets; + +// Finds a pending scroll target and registers it with the new vtx buffer +void DynOS_Find_Pending_Scroll_Target(Vtx *data, Vtx *newData) { + for (auto it = sPendingScrollTargets.begin(); it != sPendingScrollTargets.end(); ++it) { + if (it->mData == data) { + add_vtx_scroll_target(it->mIndex, &newData[it->mOffset], it->mSize, it->mOffset > 0); + sPendingScrollTargets.erase(it); + break; + } + } +} + void DynOS_Add_Scroll_Target(u32 index, const char* name, u32 offset, u32 size) { for (auto& lvlPair : DynOS_Lvl_GetArray()) { for (auto& node : lvlPair.second->mVertices) { if (node->mName.Find(name) >= 0) { - add_vtx_scroll_target( - index, - offset > 0 ? &node->mData[offset] : node->mData, - (size > 0 && size < node->mSize) ? size : node->mSize, - offset > 0 - ); + struct PendingScrollTarget scroll = { + .mIndex = index, + .mOffset = offset, + .mSize = (size > 0 && size < node->mSize) ? size : node->mSize, + .mData = node->mData, + }; + sPendingScrollTargets.push_back(scroll); } } }