mirror of
https://github.com/isledecomp/isle-portable.git
synced 2026-01-18 13:21:16 +00:00
SiLoader draft
This commit is contained in:
parent
f2b6188d89
commit
602c3eafc8
3
.gitmodules
vendored
3
.gitmodules
vendored
@ -7,3 +7,6 @@
|
|||||||
[submodule "imgui"]
|
[submodule "imgui"]
|
||||||
path = 3rdparty/imgui
|
path = 3rdparty/imgui
|
||||||
url = https://github.com/ocornut/imgui
|
url = https://github.com/ocornut/imgui
|
||||||
|
[submodule "3rdparty/libweaver"]
|
||||||
|
path = 3rdparty/libweaver
|
||||||
|
url = https://github.com/isledecomp/SIEdit
|
||||||
|
|||||||
20
3rdparty/CMakeLists.txt
vendored
20
3rdparty/CMakeLists.txt
vendored
@ -72,3 +72,23 @@ target_include_directories(imgui PUBLIC ${imgui_SOURCE_DIR})
|
|||||||
target_link_libraries(imgui PUBLIC SDL3::Headers)
|
target_link_libraries(imgui PUBLIC SDL3::Headers)
|
||||||
target_link_libraries(imgui PRIVATE SDL3::SDL3)
|
target_link_libraries(imgui PRIVATE SDL3::SDL3)
|
||||||
set_property(TARGET imgui PROPERTY CXX_CLANG_TIDY "")
|
set_property(TARGET imgui PROPERTY CXX_CLANG_TIDY "")
|
||||||
|
|
||||||
|
if(DOWNLOAD_DEPENDENCIES)
|
||||||
|
include(FetchContent)
|
||||||
|
FetchContent_Populate(
|
||||||
|
libweaver
|
||||||
|
URL https://github.com/isledecomp/SIEdit/archive/6da93b2072c41c41d526b8b9df7d4292be1f0f55.tar.gz
|
||||||
|
URL_MD5 ae59007fcb9efadc06c67621e1e107cb
|
||||||
|
)
|
||||||
|
else()
|
||||||
|
set(libsmacker_SOURCE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/libweaver")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
add_library(libweaver STATIC
|
||||||
|
${libweaver_SOURCE_DIR}/lib/core.cpp
|
||||||
|
${libweaver_SOURCE_DIR}/lib/file.cpp
|
||||||
|
${libweaver_SOURCE_DIR}/lib/interleaf.cpp
|
||||||
|
${libweaver_SOURCE_DIR}/lib/object.cpp
|
||||||
|
${libweaver_SOURCE_DIR}/lib/sitypes.cpp
|
||||||
|
)
|
||||||
|
target_include_directories(libweaver PUBLIC ${libweaver_SOURCE_DIR}/lib)
|
||||||
|
|||||||
1
3rdparty/libweaver
vendored
Submodule
1
3rdparty/libweaver
vendored
Submodule
@ -0,0 +1 @@
|
|||||||
|
Subproject commit 6da93b2072c41c41d526b8b9df7d4292be1f0f55
|
||||||
@ -42,6 +42,7 @@ find_program(SDL_SHADERCROSS_BIN NAMES "shadercross")
|
|||||||
find_package(Python3 3.12 COMPONENTS Interpreter)
|
find_package(Python3 3.12 COMPONENTS Interpreter)
|
||||||
|
|
||||||
option(ISLE_BUILD_APP "Build isle application" ON)
|
option(ISLE_BUILD_APP "Build isle application" ON)
|
||||||
|
option(ISLE_BUILD_ASSETS "Build assets from the /assets directory" OFF)
|
||||||
option(ISLE_ASAN "Enable Address Sanitizer" OFF)
|
option(ISLE_ASAN "Enable Address Sanitizer" OFF)
|
||||||
option(ISLE_UBSAN "Enable Undefined Behavior Sanitizer" OFF)
|
option(ISLE_UBSAN "Enable Undefined Behavior Sanitizer" OFF)
|
||||||
option(ISLE_WERROR "Treat warnings as errors" OFF)
|
option(ISLE_WERROR "Treat warnings as errors" OFF)
|
||||||
@ -490,9 +491,11 @@ if (NOT ISLE_MINIWIN)
|
|||||||
endif()
|
endif()
|
||||||
|
|
||||||
if (ISLE_EXTENSIONS)
|
if (ISLE_EXTENSIONS)
|
||||||
|
target_link_libraries(lego1 PRIVATE libweaver)
|
||||||
target_compile_definitions(lego1 PUBLIC EXTENSIONS)
|
target_compile_definitions(lego1 PUBLIC EXTENSIONS)
|
||||||
target_sources(lego1 PRIVATE
|
target_sources(lego1 PRIVATE
|
||||||
extensions/src/extensions.cpp
|
extensions/src/extensions.cpp
|
||||||
|
extensions/src/siloader.cpp
|
||||||
extensions/src/textureloader.cpp
|
extensions/src/textureloader.cpp
|
||||||
)
|
)
|
||||||
endif()
|
endif()
|
||||||
@ -644,6 +647,36 @@ if (ISLE_BUILD_CONFIG)
|
|||||||
endif()
|
endif()
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
if(ISLE_BUILD_ASSETS)
|
||||||
|
message(STATUS "Asset building is enabled")
|
||||||
|
set(GENERATED_ASSETS_DIR "${CMAKE_BINARY_DIR}/assets")
|
||||||
|
|
||||||
|
add_executable(asset_generator EXCLUDE_FROM_ALL
|
||||||
|
assets/main.cpp
|
||||||
|
)
|
||||||
|
target_link_libraries(asset_generator PRIVATE libweaver)
|
||||||
|
target_include_directories(asset_generator PRIVATE "${CMAKE_SOURCE_DIR}/util" "${CMAKE_SOURCE_DIR}/LEGO1/omni/include" "${CMAKE_SOURCE_DIR}/LEGO1" "${CMAKE_SOURCE_DIR}/LEGO1/lego/sources")
|
||||||
|
|
||||||
|
add_custom_command(
|
||||||
|
OUTPUT ${GENERATED_ASSETS_DIR}/.stamp
|
||||||
|
COMMAND ${CMAKE_COMMAND} -E make_directory ${GENERATED_ASSETS_DIR}
|
||||||
|
COMMAND $<TARGET_FILE:asset_generator> ${GENERATED_ASSETS_DIR}
|
||||||
|
COMMAND ${CMAKE_COMMAND} -E touch ${GENERATED_ASSETS_DIR}/.stamp
|
||||||
|
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}/assets
|
||||||
|
DEPENDS asset_generator
|
||||||
|
COMMENT "Generating assets into ${GENERATED_ASSETS_DIR}/"
|
||||||
|
VERBATIM
|
||||||
|
)
|
||||||
|
|
||||||
|
add_custom_target(build_assets ALL
|
||||||
|
DEPENDS ${GENERATED_ASSETS_DIR}/.stamp
|
||||||
|
)
|
||||||
|
|
||||||
|
install(DIRECTORY ${GENERATED_ASSETS_DIR}/
|
||||||
|
DESTINATION assets
|
||||||
|
)
|
||||||
|
endif()
|
||||||
|
|
||||||
if (ISLE_MINIWIN)
|
if (ISLE_MINIWIN)
|
||||||
set_property(TARGET ${isle_targets} APPEND PROPERTY LINK_LIBRARIES "miniwin")
|
set_property(TARGET ${isle_targets} APPEND PROPERTY LINK_LIBRARIES "miniwin")
|
||||||
endif()
|
endif()
|
||||||
|
|||||||
@ -2,6 +2,7 @@
|
|||||||
|
|
||||||
#include "3dmanager/lego3dmanager.h"
|
#include "3dmanager/lego3dmanager.h"
|
||||||
#include "anim/legoanim.h"
|
#include "anim/legoanim.h"
|
||||||
|
#include "extensions/siloader.h"
|
||||||
#include "isle.h"
|
#include "isle.h"
|
||||||
#include "isle_actions.h"
|
#include "isle_actions.h"
|
||||||
#include "islepathactor.h"
|
#include "islepathactor.h"
|
||||||
@ -37,6 +38,8 @@
|
|||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <vec.h>
|
#include <vec.h>
|
||||||
|
|
||||||
|
using namespace Extensions;
|
||||||
|
|
||||||
// FUNCTION: LEGO1 0x1003dd70
|
// FUNCTION: LEGO1 0x1003dd70
|
||||||
// FUNCTION: BETA10 0x100d3410
|
// FUNCTION: BETA10 0x100d3410
|
||||||
LegoROI* PickROI(MxLong p_x, MxLong p_y)
|
LegoROI* PickROI(MxLong p_x, MxLong p_y)
|
||||||
@ -515,6 +518,8 @@ MxBool RemoveFromCurrentWorld(const MxAtomId& p_atomId, MxS32 p_id)
|
|||||||
}
|
}
|
||||||
|
|
||||||
((MxPresenter*) object)->EndAction();
|
((MxPresenter*) object)->EndAction();
|
||||||
|
|
||||||
|
Extension<SiLoader>::Call(RemoveWith, SiLoader::StreamObject{p_atomId, p_id}, world);
|
||||||
}
|
}
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
@ -544,6 +549,8 @@ MxBool RemoveFromWorld(MxAtomId& p_entityAtom, MxS32 p_entityId, MxAtomId& p_wor
|
|||||||
}
|
}
|
||||||
|
|
||||||
((MxPresenter*) object)->EndAction();
|
((MxPresenter*) object)->EndAction();
|
||||||
|
|
||||||
|
Extension<SiLoader>::Call(RemoveWith, SiLoader::StreamObject{p_entityAtom, p_entityId}, world);
|
||||||
}
|
}
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
|
|||||||
@ -1,6 +1,7 @@
|
|||||||
#include "legomain.h"
|
#include "legomain.h"
|
||||||
|
|
||||||
#include "3dmanager/lego3dmanager.h"
|
#include "3dmanager/lego3dmanager.h"
|
||||||
|
#include "extensions/siloader.h"
|
||||||
#include "islepathactor.h"
|
#include "islepathactor.h"
|
||||||
#include "legoanimationmanager.h"
|
#include "legoanimationmanager.h"
|
||||||
#include "legobuildingmanager.h"
|
#include "legobuildingmanager.h"
|
||||||
@ -40,6 +41,8 @@ DECOMP_SIZE_ASSERT(LegoOmni::WorldContainer, 0x1c)
|
|||||||
DECOMP_SIZE_ASSERT(LegoWorldList, 0x18)
|
DECOMP_SIZE_ASSERT(LegoWorldList, 0x18)
|
||||||
DECOMP_SIZE_ASSERT(LegoWorldListCursor, 0x10)
|
DECOMP_SIZE_ASSERT(LegoWorldListCursor, 0x10)
|
||||||
|
|
||||||
|
using namespace Extensions;
|
||||||
|
|
||||||
// GLOBAL: LEGO1 0x100f6718
|
// GLOBAL: LEGO1 0x100f6718
|
||||||
// GLOBAL: BETA10 0x101ee748
|
// GLOBAL: BETA10 0x101ee748
|
||||||
// STRING: LEGO1 0x100f6710
|
// STRING: LEGO1 0x100f6710
|
||||||
@ -670,6 +673,14 @@ MxResult LegoOmni::Start(MxDSAction* p_dsAction)
|
|||||||
this->m_action.SetObjectId(p_dsAction->GetObjectId());
|
this->m_action.SetObjectId(p_dsAction->GetObjectId());
|
||||||
this->m_action.SetUnknown24(p_dsAction->GetUnknown24());
|
this->m_action.SetUnknown24(p_dsAction->GetUnknown24());
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
if (result == SUCCESS) {
|
||||||
|
Extension<SiLoader>::Call(
|
||||||
|
StartWith,
|
||||||
|
SiLoader::StreamObject{p_dsAction->GetAtomId(), p_dsAction->GetObjectId()}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
53
assets/main.cpp
Normal file
53
assets/main.cpp
Normal file
@ -0,0 +1,53 @@
|
|||||||
|
|
||||||
|
#include "mxdsaction.h"
|
||||||
|
|
||||||
|
#include <file.h>
|
||||||
|
#include <interleaf.h>
|
||||||
|
#include <object.h>
|
||||||
|
|
||||||
|
si::Interleaf::Version version = si::Interleaf::Version2_2;
|
||||||
|
uint32_t bufferSize = 65535;
|
||||||
|
uint32_t bufferCount = 8;
|
||||||
|
|
||||||
|
std::string out;
|
||||||
|
si::MemoryBuffer mxHd;
|
||||||
|
|
||||||
|
void CreateWidescreen()
|
||||||
|
{
|
||||||
|
si::Interleaf si;
|
||||||
|
mxHd.seek(0, si::MemoryBuffer::SeekStart);
|
||||||
|
si.Read(&mxHd);
|
||||||
|
|
||||||
|
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);
|
||||||
|
|
||||||
|
si.Write((out + "/widescreen.si").c_str());
|
||||||
|
}
|
||||||
|
|
||||||
|
int main(int argc, char* argv[])
|
||||||
|
{
|
||||||
|
out = argv[1];
|
||||||
|
|
||||||
|
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.bmp
Executable file
BIN
assets/widescreen/garadoor.bmp
Executable file
Binary file not shown.
|
After Width: | Height: | Size: 526 KiB |
@ -9,7 +9,7 @@
|
|||||||
|
|
||||||
namespace Extensions
|
namespace Extensions
|
||||||
{
|
{
|
||||||
constexpr const char* availableExtensions[] = {"extensions:texture loader"};
|
constexpr const char* availableExtensions[] = {"extensions:texture loader", "extensions:si loader"};
|
||||||
|
|
||||||
LEGO1_EXPORT void Enable(const char* p_key, std::map<std::string, std::string> p_options);
|
LEGO1_EXPORT void Enable(const char* p_key, std::map<std::string, std::string> p_options);
|
||||||
|
|
||||||
|
|||||||
38
extensions/include/extensions/siloader.h
Normal file
38
extensions/include/extensions/siloader.h
Normal file
@ -0,0 +1,38 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "extensions/extensions.h"
|
||||||
|
#include "legoworld.h"
|
||||||
|
#include "mxatom.h"
|
||||||
|
|
||||||
|
#include <map>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
namespace Extensions
|
||||||
|
{
|
||||||
|
class SiLoader {
|
||||||
|
public:
|
||||||
|
typedef std::pair<MxAtomId, MxU32> StreamObject;
|
||||||
|
|
||||||
|
static void Initialize();
|
||||||
|
static bool StartWith(StreamObject p_object);
|
||||||
|
static bool RemoveWith(StreamObject p_object, LegoWorld* world);
|
||||||
|
|
||||||
|
static std::map<std::string, std::string> options;
|
||||||
|
static bool enabled;
|
||||||
|
|
||||||
|
private:
|
||||||
|
static std::vector<std::string> files;
|
||||||
|
static std::vector<std::pair<StreamObject, StreamObject>> startWith;
|
||||||
|
static std::vector<std::pair<StreamObject, StreamObject>> removeWith;
|
||||||
|
|
||||||
|
static bool LoadFile(const char* p_file);
|
||||||
|
};
|
||||||
|
|
||||||
|
#ifdef EXTENSIONS
|
||||||
|
constexpr auto StartWith = &SiLoader::StartWith;
|
||||||
|
constexpr auto RemoveWith = &SiLoader::RemoveWith;
|
||||||
|
#else
|
||||||
|
constexpr decltype(&SiLoader::StartWith) StartWith = nullptr;
|
||||||
|
constexpr decltype(&SiLoader::RemoveWith) RemoveWith = nullptr;
|
||||||
|
#endif
|
||||||
|
}; // namespace Extensions
|
||||||
@ -1,5 +1,6 @@
|
|||||||
#include "extensions/extensions.h"
|
#include "extensions/extensions.h"
|
||||||
|
|
||||||
|
#include "extensions/siloader.h"
|
||||||
#include "extensions/textureloader.h"
|
#include "extensions/textureloader.h"
|
||||||
|
|
||||||
#include <SDL3/SDL_log.h>
|
#include <SDL3/SDL_log.h>
|
||||||
@ -13,6 +14,11 @@ void Extensions::Enable(const char* p_key, std::map<std::string, std::string> p_
|
|||||||
TextureLoader::enabled = true;
|
TextureLoader::enabled = true;
|
||||||
TextureLoader::Initialize();
|
TextureLoader::Initialize();
|
||||||
}
|
}
|
||||||
|
else if (!SDL_strcasecmp(p_key, "extensions:si loader")) {
|
||||||
|
SiLoader::options = std::move(p_options);
|
||||||
|
SiLoader::enabled = true;
|
||||||
|
SiLoader::Initialize();
|
||||||
|
}
|
||||||
|
|
||||||
SDL_Log("Enabled extension: %s", p_key);
|
SDL_Log("Enabled extension: %s", p_key);
|
||||||
break;
|
break;
|
||||||
|
|||||||
99
extensions/src/siloader.cpp
Normal file
99
extensions/src/siloader.cpp
Normal file
@ -0,0 +1,99 @@
|
|||||||
|
#include "extensions/siloader.h"
|
||||||
|
|
||||||
|
#include "mxdsaction.h"
|
||||||
|
#include "mxmisc.h"
|
||||||
|
#include "mxstreamer.h"
|
||||||
|
|
||||||
|
#include <SDL3/SDL.h>
|
||||||
|
#include <interleaf.h>
|
||||||
|
|
||||||
|
using namespace Extensions;
|
||||||
|
|
||||||
|
std::map<std::string, std::string> SiLoader::options;
|
||||||
|
std::vector<std::pair<SiLoader::StreamObject, SiLoader::StreamObject>> SiLoader::startWith;
|
||||||
|
std::vector<std::pair<SiLoader::StreamObject, SiLoader::StreamObject>> SiLoader::removeWith;
|
||||||
|
bool SiLoader::enabled = false;
|
||||||
|
|
||||||
|
void SiLoader::Initialize()
|
||||||
|
{
|
||||||
|
char* files = SDL_strdup(options["si loader:files"].c_str());
|
||||||
|
char* saveptr;
|
||||||
|
|
||||||
|
for (char* file = SDL_strtok_r(files, ",\n", &saveptr); file; file = SDL_strtok_r(NULL, ",\n", &saveptr)) {
|
||||||
|
LoadFile(file);
|
||||||
|
}
|
||||||
|
|
||||||
|
SDL_free(files);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool SiLoader::StartWith(StreamObject p_object)
|
||||||
|
{
|
||||||
|
for (const auto& key : startWith) {
|
||||||
|
if (key.first == p_object) {
|
||||||
|
MxDSAction action;
|
||||||
|
action.SetAtomId(key.second.first);
|
||||||
|
action.SetObjectId(key.second.second);
|
||||||
|
Start(&action);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool SiLoader::RemoveWith(StreamObject p_object, LegoWorld* world)
|
||||||
|
{
|
||||||
|
for (auto& key : startWith) {
|
||||||
|
if (key.first == p_object) {
|
||||||
|
RemoveFromWorld(key.second.first, key.second.second, world->GetAtomId(), world->GetEntityId());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool SiLoader::LoadFile(const char* p_file)
|
||||||
|
{
|
||||||
|
si::Interleaf si;
|
||||||
|
MxStreamController* controller;
|
||||||
|
|
||||||
|
if (si.Read(p_file) != si::Interleaf::ERROR_SUCCESS) {
|
||||||
|
SDL_Log("Could not parse SI file %s", p_file);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((controller = Streamer()->Open(p_file, MxStreamer::e_diskStream)) != SUCCESS) {
|
||||||
|
SDL_Log("Could not load SI file %s", p_file);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (si::Core* child : si.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());
|
||||||
|
const char* directive;
|
||||||
|
char atom[256];
|
||||||
|
uint32_t id;
|
||||||
|
|
||||||
|
if ((directive = SDL_strstr(extra.c_str(), "StartWith:"))) {
|
||||||
|
if (SDL_sscanf(extra.c_str(), "StartWith:%255[^;];%d", atom, &id) == 2) {
|
||||||
|
startWith.emplace_back(
|
||||||
|
StreamObject{MxAtomId{atom, e_lowerCase2}, id},
|
||||||
|
StreamObject{controller->GetAtom(), object->id_}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((directive = SDL_strstr(extra.c_str(), "RemoveWith:"))) {
|
||||||
|
if (SDL_sscanf(extra.c_str(), "RemoveWith:%255[^;];%d", atom, &id) == 2) {
|
||||||
|
removeWith.emplace_back(
|
||||||
|
StreamObject{MxAtomId{atom, e_lowerCase2}, id},
|
||||||
|
StreamObject{controller->GetAtom(), object->id_}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
Loading…
Reference in New Issue
Block a user