diff --git a/LEGO1/lego/legoomni/src/entity/legoworld.cpp b/LEGO1/lego/legoomni/src/entity/legoworld.cpp index 1ba828cb..fe4bbc63 100644 --- a/LEGO1/lego/legoomni/src/entity/legoworld.cpp +++ b/LEGO1/lego/legoomni/src/entity/legoworld.cpp @@ -1,6 +1,7 @@ #include "legoworld.h" #include "anim/legoanim.h" +#include "extensions/siloader.h" #include "legoanimationmanager.h" #include "legoanimpresenter.h" #include "legobuildingmanager.h" @@ -32,6 +33,8 @@ DECOMP_SIZE_ASSERT(LegoEntityListCursor, 0x10) DECOMP_SIZE_ASSERT(LegoCacheSoundList, 0x18) DECOMP_SIZE_ASSERT(LegoCacheSoundListCursor, 0x10) +using namespace Extensions; + // FUNCTION: LEGO1 0x1001ca40 LegoWorld::LegoWorld() : m_pathControllerList(TRUE) { @@ -636,6 +639,12 @@ MxCore* LegoWorld::Find(const char* p_class, const char* p_name) // FUNCTION: BETA10 0x100db3de MxCore* LegoWorld::Find(const MxAtomId& p_atom, MxS32 p_entityId) { + auto result = + Extension::Call(HandleFind, SiLoader::StreamObject{p_atom, p_entityId}, this).value_or(std::nullopt); + if (result) { + return result.value(); + } + LegoEntityListCursor entityCursor(m_entityList); LegoEntity* entity; diff --git a/assets/main.cpp b/assets/main.cpp index bbb033b6..ca80ca40 100644 --- a/assets/main.cpp +++ b/assets/main.cpp @@ -12,19 +12,17 @@ uint32_t bufferCount = 8; std::string out; std::ofstream depfile; +si::MemoryBuffer mxHd; void CreateWidescreen() { si::Interleaf si; - si.Read("widescreen/GaraDoor.si"); - - si::Object* garadoor = dynamic_cast(si.GetChildAt(0)); - const char append[] = "Replace:\\Lego\\Scripts\\Isle\\Isle;1160"; - garadoor->extra_.append(append, sizeof(append)); + mxHd.seek(0, si::MemoryBuffer::SeekStart); + si.Read(&mxHd); si::Object GaraDoor_Background_Wide; - const char extra[] = "World:current, RemoveWith:\\Lego\\Scripts\\Isle\\Isle;1161"; - GaraDoor_Background_Wide.id_ = 5001; + const char extra[] = + "World:current, StartWith:\\Lego\\Scripts\\Isle\\Isle;1160, RemoveWith:\\Lego\\Scripts\\Isle\\Isle;1161"; GaraDoor_Background_Wide.type_ = si::MxOb::Bitmap; GaraDoor_Background_Wide.flags_ = MxDSAction::c_enabled | MxDSAction::c_bit4; GaraDoor_Background_Wide.duration_ = -1; @@ -33,12 +31,11 @@ void CreateWidescreen() GaraDoor_Background_Wide.presenter_ = "MxStillPresenter"; GaraDoor_Background_Wide.name_ = "GaraDoor_Background_Wide"; GaraDoor_Background_Wide.filetype_ = si::MxOb::STL; - GaraDoor_Background_Wide.location_ = si::Vector3(-240.0, 0.0, -1.0); - GaraDoor_Background_Wide.direction_ = si::Vector3(0, 0, 0); - GaraDoor_Background_Wide.up_ = si::Vector3(0, 1.0, 0); + GaraDoor_Background_Wide.location_.x = -240.0; + GaraDoor_Background_Wide.location_.z = -1.0; GaraDoor_Background_Wide.up_.y = 1.0; GaraDoor_Background_Wide.ReplaceWithFile("widescreen/GaraDoor_Background_Wide.bmp"); - garadoor->AppendChild(&GaraDoor_Background_Wide); + si.AppendChild(&GaraDoor_Background_Wide); std::string file = out + "/widescreen.si"; depfile << file << ": " << (std::filesystem::current_path() / "widescreen/GaraDoor_Background_Wide.bmp").string() @@ -52,6 +49,12 @@ int main(int argc, char* argv[]) out = argv[1]; depfile = std::ofstream(argv[2]); + mxHd.WriteU32(si::RIFF::MxHd); + mxHd.WriteU32(3 * sizeof(uint32_t)); + mxHd.WriteU32(version); + mxHd.WriteU32(bufferSize); + mxHd.WriteU32(bufferCount); + CreateWidescreen(); return 0; } diff --git a/extensions/include/extensions/siloader.h b/extensions/include/extensions/siloader.h index e4ed4d1e..e8c3fa9d 100644 --- a/extensions/include/extensions/siloader.h +++ b/extensions/include/extensions/siloader.h @@ -16,6 +16,7 @@ class SiLoader { static void Initialize(); static bool Load(); + static std::optional HandleFind(StreamObject p_object, LegoWorld* world); static std::optional HandleStart(StreamObject p_object); static std::optional HandleRemove(StreamObject p_object, LegoWorld* world); @@ -29,19 +30,17 @@ class SiLoader { static std::vector> replace; static bool LoadFile(const char* p_file); - static void ParseDirectives( - const MxAtomId& p_atom, - si::Core* p_core, - const MxAtomId* p_parentReplacedAtom = nullptr - ); + static void ParseDirectives(const MxAtomId& p_atom, si::Core* p_core, MxAtomId p_parentReplacedAtom = MxAtomId()); }; #ifdef EXTENSIONS constexpr auto Load = &SiLoader::Load; +constexpr auto HandleFind = &SiLoader::HandleFind; constexpr auto HandleStart = &SiLoader::HandleStart; constexpr auto HandleRemove = &SiLoader::HandleRemove; #else constexpr decltype(&SiLoader::Load) Load = nullptr; +constexpr decltype(&SiLoader::HandleFind) HandleFind = nullptr; constexpr decltype(&SiLoader::HandleStart) HandleStart = nullptr; constexpr decltype(&SiLoader::HandleRemove) HandleRemove = nullptr; #endif diff --git a/extensions/src/siloader.cpp b/extensions/src/siloader.cpp index 121f742c..42b79548 100644 --- a/extensions/src/siloader.cpp +++ b/extensions/src/siloader.cpp @@ -36,6 +36,17 @@ bool SiLoader::Load() return true; } +std::optional SiLoader::HandleFind(StreamObject p_object, LegoWorld* world) +{ + for (const auto& key : replace) { + if (key.first == p_object) { + return world->Find(key.second.first, key.second.second); + } + } + + return std::nullopt; +} + std::optional SiLoader::HandleStart(StreamObject p_object) { for (const auto& key : startWith) { @@ -101,7 +112,7 @@ bool SiLoader::LoadFile(const char* p_file) return true; } -void SiLoader::ParseDirectives(const MxAtomId& p_atom, si::Core* p_core, const MxAtomId* p_parentReplacedAtom) +void SiLoader::ParseDirectives(const MxAtomId& p_atom, si::Core* p_core, MxAtomId p_parentReplacedAtom) { for (si::Core* child : p_core->GetChildren()) { if (si::Object* object = dynamic_cast(child)) { @@ -129,8 +140,11 @@ void SiLoader::ParseDirectives(const MxAtomId& p_atom, si::Core* p_core, const M } } - if (p_parentReplacedAtom) { - replace.emplace_back(StreamObject{*p_parentReplacedAtom, id}, StreamObject{p_atom, object->id_}); + if (p_parentReplacedAtom.GetInternal()) { + replace.emplace_back( + StreamObject{p_parentReplacedAtom, object->id_}, + StreamObject{p_atom, object->id_} + ); } else { if ((directive = SDL_strstr(extra.c_str(), "Replace:"))) { @@ -139,7 +153,7 @@ void SiLoader::ParseDirectives(const MxAtomId& p_atom, si::Core* p_core, const M StreamObject{MxAtomId{atom, e_lowerCase2}, id}, StreamObject{p_atom, object->id_} ); - p_parentReplacedAtom = &replace.back().first.first; + p_parentReplacedAtom = replace.back().first.first; } } }