mirror of
https://github.com/isledecomp/isle-portable.git
synced 2026-01-12 02:41:14 +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"]
|
||||
path = 3rdparty/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 PRIVATE SDL3::SDL3)
|
||||
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)
|
||||
|
||||
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_UBSAN "Enable Undefined Behavior Sanitizer" OFF)
|
||||
option(ISLE_WERROR "Treat warnings as errors" OFF)
|
||||
@ -490,9 +491,11 @@ if (NOT ISLE_MINIWIN)
|
||||
endif()
|
||||
|
||||
if (ISLE_EXTENSIONS)
|
||||
target_link_libraries(lego1 PRIVATE libweaver)
|
||||
target_compile_definitions(lego1 PUBLIC EXTENSIONS)
|
||||
target_sources(lego1 PRIVATE
|
||||
extensions/src/extensions.cpp
|
||||
extensions/src/siloader.cpp
|
||||
extensions/src/textureloader.cpp
|
||||
)
|
||||
endif()
|
||||
@ -644,6 +647,36 @@ if (ISLE_BUILD_CONFIG)
|
||||
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)
|
||||
set_property(TARGET ${isle_targets} APPEND PROPERTY LINK_LIBRARIES "miniwin")
|
||||
endif()
|
||||
|
||||
@ -2,6 +2,7 @@
|
||||
|
||||
#include "3dmanager/lego3dmanager.h"
|
||||
#include "anim/legoanim.h"
|
||||
#include "extensions/siloader.h"
|
||||
#include "isle.h"
|
||||
#include "isle_actions.h"
|
||||
#include "islepathactor.h"
|
||||
@ -37,6 +38,8 @@
|
||||
#include <string.h>
|
||||
#include <vec.h>
|
||||
|
||||
using namespace Extensions;
|
||||
|
||||
// FUNCTION: LEGO1 0x1003dd70
|
||||
// FUNCTION: BETA10 0x100d3410
|
||||
LegoROI* PickROI(MxLong p_x, MxLong p_y)
|
||||
@ -515,6 +518,8 @@ 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;
|
||||
@ -544,6 +549,8 @@ MxBool RemoveFromWorld(MxAtomId& p_entityAtom, MxS32 p_entityId, MxAtomId& p_wor
|
||||
}
|
||||
|
||||
((MxPresenter*) object)->EndAction();
|
||||
|
||||
Extension<SiLoader>::Call(RemoveWith, SiLoader::StreamObject{p_entityAtom, p_entityId}, world);
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
|
||||
@ -1,6 +1,7 @@
|
||||
#include "legomain.h"
|
||||
|
||||
#include "3dmanager/lego3dmanager.h"
|
||||
#include "extensions/siloader.h"
|
||||
#include "islepathactor.h"
|
||||
#include "legoanimationmanager.h"
|
||||
#include "legobuildingmanager.h"
|
||||
@ -40,6 +41,8 @@ DECOMP_SIZE_ASSERT(LegoOmni::WorldContainer, 0x1c)
|
||||
DECOMP_SIZE_ASSERT(LegoWorldList, 0x18)
|
||||
DECOMP_SIZE_ASSERT(LegoWorldListCursor, 0x10)
|
||||
|
||||
using namespace Extensions;
|
||||
|
||||
// GLOBAL: LEGO1 0x100f6718
|
||||
// GLOBAL: BETA10 0x101ee748
|
||||
// STRING: LEGO1 0x100f6710
|
||||
@ -670,6 +673,14 @@ 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;
|
||||
}
|
||||
|
||||
|
||||
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
|
||||
{
|
||||
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);
|
||||
|
||||
|
||||
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/siloader.h"
|
||||
#include "extensions/textureloader.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::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);
|
||||
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