Replace SI objects

This commit is contained in:
Christian Semmler 2025-08-11 16:56:52 -07:00
parent 6a8aaaabe2
commit a69bb8da04
No known key found for this signature in database
GPG Key ID: 086DAA1360BEEE5C
7 changed files with 108 additions and 55 deletions

View File

@ -503,6 +503,12 @@ MxBool RemoveFromCurrentWorld(const MxAtomId& p_atomId, MxS32 p_id)
{
LegoWorld* world = CurrentWorld();
auto result =
Extension<SiLoader>::Call(HandleRemove, SiLoader::StreamObject{p_atomId, p_id}, world).value_or(std::nullopt);
if (result) {
return result.value();
}
if (world) {
MxCore* object = world->Find(p_atomId, p_id);
@ -518,8 +524,6 @@ MxBool RemoveFromCurrentWorld(const MxAtomId& p_atomId, MxS32 p_id)
}
((MxPresenter*) object)->EndAction();
Extension<SiLoader>::Call(RemoveWith, SiLoader::StreamObject{p_atomId, p_id}, world);
}
return TRUE;
@ -539,6 +543,12 @@ MxBool RemoveFromWorld(
{
LegoWorld* world = FindWorld(p_worldAtom, p_worldEntityId);
auto result = Extension<SiLoader>::Call(HandleRemove, SiLoader::StreamObject{p_entityAtom, p_entityId}, world)
.value_or(std::nullopt);
if (result) {
return result.value();
}
if (world) {
MxCore* object = world->Find(p_entityAtom, p_entityId);
@ -554,8 +564,6 @@ MxBool RemoveFromWorld(
}
((MxPresenter*) object)->EndAction();
Extension<SiLoader>::Call(RemoveWith, SiLoader::StreamObject{p_entityAtom, p_entityId}, world);
}
return TRUE;

View File

@ -663,6 +663,17 @@ void LegoOmni::CreateBackgroundAudio()
// FUNCTION: BETA10 0x1008f7e0
MxResult LegoOmni::Start(MxDSAction* p_dsAction)
{
{
auto result = Extension<SiLoader>::Call(
HandleStart,
SiLoader::StreamObject{p_dsAction->GetAtomId(), p_dsAction->GetObjectId()}
)
.value_or(std::nullopt);
if (result) {
return result.value();
}
}
MxResult result = MxOmni::Start(p_dsAction);
#ifdef BETA10
this->m_action = *p_dsAction;
@ -673,14 +684,6 @@ MxResult LegoOmni::Start(MxDSAction* p_dsAction)
this->m_action.SetObjectId(p_dsAction->GetObjectId());
this->m_action.SetUnknown24(p_dsAction->GetUnknown24());
#endif
if (result == SUCCESS) {
Extension<SiLoader>::Call(
StartWith,
SiLoader::StreamObject{p_dsAction->GetAtomId(), p_dsAction->GetObjectId()}
);
}
return result;
}

View File

@ -12,32 +12,37 @@ uint32_t bufferCount = 8;
std::string out;
std::ofstream depfile;
si::MemoryBuffer mxHd;
void CreateWidescreen()
{
si::Interleaf si;
std::string file = out + "/widescreen.si";
mxHd.seek(0, si::MemoryBuffer::SeekStart);
si.Read(&mxHd);
si.Read("widescreen/GaraDoor.si");
si::Object GaraDoor_Wide;
const char extra[] =
"World:current, StartWith:\\Lego\\Scripts\\Isle\\Isle;1160, RemoveWith:\\Lego\\Scripts\\Isle\\Isle;1161";
GaraDoor_Wide.type_ = si::MxOb::Bitmap;
GaraDoor_Wide.flags_ = MxDSAction::c_enabled | MxDSAction::c_bit4;
GaraDoor_Wide.duration_ = -1;
GaraDoor_Wide.loops_ = 1;
GaraDoor_Wide.extra_ = si::bytearray(extra, sizeof(extra));
GaraDoor_Wide.presenter_ = "MxStillPresenter";
GaraDoor_Wide.name_ = "GaraDoor_Wide";
GaraDoor_Wide.filetype_ = si::MxOb::STL;
GaraDoor_Wide.location_.x = -240.0;
GaraDoor_Wide.location_.z = -1.0;
GaraDoor_Wide.up_.y = 1.0;
GaraDoor_Wide.ReplaceWithFile("widescreen/garadoor.bmp");
si.AppendChild(&GaraDoor_Wide);
depfile << file << ": " << (std::filesystem::current_path() / "widescreen/garadoor.bmp").string() << std::endl;
si::Object* garadoor = dynamic_cast<si::Object*>(si.GetChildAt(0));
const char append[] = "Replace:\\Lego\\Scripts\\Isle\\Isle;1160";
garadoor->extra_.append(append, sizeof(append));
si::Object GaraDoor_Background_Wide;
const char extra[] = "World:current, RemoveWith:\\Lego\\Scripts\\Isle\\Isle;1161";
GaraDoor_Background_Wide.id_ = 5001;
GaraDoor_Background_Wide.type_ = si::MxOb::Bitmap;
GaraDoor_Background_Wide.flags_ = MxDSAction::c_enabled | MxDSAction::c_bit4;
GaraDoor_Background_Wide.duration_ = -1;
GaraDoor_Background_Wide.loops_ = 1;
GaraDoor_Background_Wide.extra_ = si::bytearray(extra, sizeof(extra));
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.up_.y = 1.0;
GaraDoor_Background_Wide.ReplaceWithFile("widescreen/GaraDoor_Background_Wide.bmp");
garadoor->AppendChild(&GaraDoor_Background_Wide);
std::string file = out + "/widescreen.si";
depfile << file << ": " << (std::filesystem::current_path() / "widescreen/GaraDoor_Background_Wide.bmp").string()
<< std::endl;
si.Write(file.c_str());
}
@ -47,12 +52,6 @@ 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;
}

BIN
assets/widescreen/GaraDoor.si Executable file

Binary file not shown.

View File

Before

Width:  |  Height:  |  Size: 526 KiB

After

Width:  |  Height:  |  Size: 526 KiB

View File

@ -4,6 +4,7 @@
#include "legoworld.h"
#include "mxatom.h"
#include <interleaf.h>
#include <map>
#include <vector>
@ -15,8 +16,8 @@ class SiLoader {
static void Initialize();
static bool Load();
static bool StartWith(StreamObject p_object);
static bool RemoveWith(StreamObject p_object, LegoWorld* world);
static std::optional<MxResult> HandleStart(StreamObject p_object);
static std::optional<MxBool> HandleRemove(StreamObject p_object, LegoWorld* world);
static std::map<std::string, std::string> options;
static std::vector<std::string> files;
@ -25,17 +26,23 @@ class SiLoader {
private:
static std::vector<std::pair<StreamObject, StreamObject>> startWith;
static std::vector<std::pair<StreamObject, StreamObject>> removeWith;
static std::vector<std::pair<StreamObject, StreamObject>> replace;
static bool LoadFile(const char* p_file);
static void ParseDirectives(
const MxAtomId& p_atom,
si::Core* p_core,
const MxAtomId* p_parentReplacedAtom = nullptr
);
};
#ifdef EXTENSIONS
constexpr auto Load = &SiLoader::Load;
constexpr auto StartWith = &SiLoader::StartWith;
constexpr auto RemoveWith = &SiLoader::RemoveWith;
constexpr auto HandleStart = &SiLoader::HandleStart;
constexpr auto HandleRemove = &SiLoader::HandleRemove;
#else
constexpr decltype(&SiLoader::Load) Load = nullptr;
constexpr decltype(&SiLoader::StartWith) StartWith = nullptr;
constexpr decltype(&SiLoader::RemoveWith) RemoveWith = nullptr;
constexpr decltype(&SiLoader::HandleStart) HandleStart = nullptr;
constexpr decltype(&SiLoader::HandleRemove) HandleRemove = nullptr;
#endif
}; // namespace Extensions

View File

@ -5,7 +5,6 @@
#include "mxstreamer.h"
#include <SDL3/SDL.h>
#include <interleaf.h>
using namespace Extensions;
@ -13,6 +12,7 @@ std::map<std::string, std::string> SiLoader::options;
std::vector<std::string> SiLoader::files;
std::vector<std::pair<SiLoader::StreamObject, SiLoader::StreamObject>> SiLoader::startWith;
std::vector<std::pair<SiLoader::StreamObject, SiLoader::StreamObject>> SiLoader::removeWith;
std::vector<std::pair<SiLoader::StreamObject, SiLoader::StreamObject>> SiLoader::replace;
bool SiLoader::enabled = false;
void SiLoader::Initialize()
@ -36,7 +36,7 @@ bool SiLoader::Load()
return true;
}
bool SiLoader::StartWith(StreamObject p_object)
std::optional<MxResult> SiLoader::HandleStart(StreamObject p_object)
{
for (const auto& key : startWith) {
if (key.first == p_object) {
@ -47,10 +47,19 @@ bool SiLoader::StartWith(StreamObject p_object)
}
}
return true;
for (const auto& key : replace) {
if (key.first == p_object) {
MxDSAction action;
action.SetAtomId(key.second.first);
action.SetObjectId(key.second.second);
return Start(&action);
}
}
return std::nullopt;
}
bool SiLoader::RemoveWith(StreamObject p_object, LegoWorld* world)
std::optional<MxBool> SiLoader::HandleRemove(StreamObject p_object, LegoWorld* world)
{
for (const auto& key : removeWith) {
if (key.first == p_object) {
@ -58,7 +67,13 @@ bool SiLoader::RemoveWith(StreamObject p_object, LegoWorld* world)
}
}
return true;
for (const auto& key : replace) {
if (key.first == p_object) {
return RemoveFromWorld(key.second.first, key.second.second, world->GetAtomId(), world->GetEntityId());
}
}
return std::nullopt;
}
bool SiLoader::LoadFile(const char* p_file)
@ -82,7 +97,13 @@ bool SiLoader::LoadFile(const char* p_file)
return false;
}
for (si::Core* child : si.GetChildren()) {
ParseDirectives(controller->GetAtom(), &si);
return true;
}
void SiLoader::ParseDirectives(const MxAtomId& p_atom, si::Core* p_core, const MxAtomId* p_parentReplacedAtom)
{
for (si::Core* child : p_core->GetChildren()) {
if (si::Object* object = dynamic_cast<si::Object*>(child)) {
if (object->type() != si::MxOb::Null) {
std::string extra(object->extra_.data(), object->extra_.size());
@ -94,7 +115,7 @@ bool SiLoader::LoadFile(const char* p_file)
if (SDL_sscanf(directive, "StartWith:%255[^;];%d", atom, &id) == 2) {
startWith.emplace_back(
StreamObject{MxAtomId{atom, e_lowerCase2}, id},
StreamObject{controller->GetAtom(), object->id_}
StreamObject{p_atom, object->id_}
);
}
}
@ -103,13 +124,28 @@ bool SiLoader::LoadFile(const char* p_file)
if (SDL_sscanf(directive, "RemoveWith:%255[^;];%d", atom, &id) == 2) {
removeWith.emplace_back(
StreamObject{MxAtomId{atom, e_lowerCase2}, id},
StreamObject{controller->GetAtom(), object->id_}
StreamObject{p_atom, object->id_}
);
}
}
if (p_parentReplacedAtom) {
replace.emplace_back(StreamObject{*p_parentReplacedAtom, id}, StreamObject{p_atom, object->id_});
}
else {
if ((directive = SDL_strstr(extra.c_str(), "Replace:"))) {
if (SDL_sscanf(directive, "Replace:%255[^;];%d", atom, &id) == 2) {
replace.emplace_back(
StreamObject{MxAtomId{atom, e_lowerCase2}, id},
StreamObject{p_atom, object->id_}
);
p_parentReplacedAtom = &replace.back().first.first;
}
}
}
}
}
}
return true;
ParseDirectives(p_atom, child, p_parentReplacedAtom);
}
}