mirror of
https://github.com/isledecomp/isle-portable.git
synced 2026-05-02 02:23:56 +00:00
Introduces a third person camera system with orbit camera, input handling (mouse/keyboard/touch/gamepad), display actor cloning, and camera-relative movement. Includes shared character utilities (animator, cloner, customizer) and an IExtraAnimHandler interface for optional animation extensions. Also includes generic base game fixes and extension system improvements.
139 lines
3.9 KiB
C++
139 lines
3.9 KiB
C++
#include "filesystem.h"
|
|
|
|
#include "events.h"
|
|
#include "extensions/siloader.h"
|
|
#include "extensions/textureloader.h"
|
|
#include "legogamestate.h"
|
|
#include "misc.h"
|
|
#include "mxmain.h"
|
|
|
|
#include <SDL3/SDL_filesystem.h>
|
|
#include <SDL3/SDL_log.h>
|
|
#include <emscripten.h>
|
|
#include <emscripten/wasmfs.h>
|
|
|
|
static backend_t opfs = nullptr;
|
|
static backend_t fetchfs = nullptr;
|
|
|
|
extern const char* g_files[46];
|
|
extern const char* g_textures[120];
|
|
|
|
bool Emscripten_OPFSDisabled()
|
|
{
|
|
return MAIN_THREAD_EM_ASM_INT({return !!Module["disableOpfs"]});
|
|
}
|
|
|
|
bool Emscripten_SetupConfig(const char* p_iniConfig)
|
|
{
|
|
if (Emscripten_OPFSDisabled()) {
|
|
SDL_Log("OPFS is disabled; ignoring .ini path");
|
|
return false;
|
|
}
|
|
|
|
opfs = wasmfs_create_opfs_backend();
|
|
MxString iniConfig = p_iniConfig;
|
|
|
|
char* parse = iniConfig.GetData();
|
|
while ((parse = SDL_strchr(++parse, '/'))) {
|
|
*parse = '\0';
|
|
wasmfs_create_directory(iniConfig.GetData(), 0644, opfs);
|
|
*parse = '/';
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
void Emscripten_SetupFilesystem()
|
|
{
|
|
fetchfs = wasmfs_create_fetch_backend((MxString(Emscripten_streamHost) + "/LEGO").GetData(), 512 * 1024);
|
|
|
|
wasmfs_create_directory("/LEGO", 0644, fetchfs);
|
|
wasmfs_create_directory("/LEGO/Scripts", 0644, fetchfs);
|
|
wasmfs_create_directory("/LEGO/Scripts/Act2", 0644, fetchfs);
|
|
wasmfs_create_directory("/LEGO/Scripts/Act3", 0644, fetchfs);
|
|
wasmfs_create_directory("/LEGO/Scripts/Build", 0644, fetchfs);
|
|
wasmfs_create_directory("/LEGO/Scripts/Garage", 0644, fetchfs);
|
|
wasmfs_create_directory("/LEGO/Scripts/Hospital", 0644, fetchfs);
|
|
wasmfs_create_directory("/LEGO/Scripts/Infocntr", 0644, fetchfs);
|
|
wasmfs_create_directory("/LEGO/Scripts/Isle", 0644, fetchfs);
|
|
wasmfs_create_directory("/LEGO/Scripts/Police", 0644, fetchfs);
|
|
wasmfs_create_directory("/LEGO/Scripts/Race", 0644, fetchfs);
|
|
wasmfs_create_directory("/LEGO/data", 0644, fetchfs);
|
|
|
|
const auto registerFile = [](const char* p_path) {
|
|
MxString path = MxString(Emscripten_bundledPath) + MxString(p_path);
|
|
path.MapPathToFilesystem();
|
|
|
|
if (SDL_GetPathInfo(path.GetData(), NULL)) {
|
|
SDL_Log("File %s is bundled and won't be streamed", p_path);
|
|
}
|
|
else {
|
|
wasmfs_create_file(p_path, 0644, fetchfs);
|
|
MxOmni::GetCDFiles().emplace_back(p_path);
|
|
|
|
SDL_Log("File %s set up for streaming", p_path);
|
|
}
|
|
};
|
|
|
|
const auto preloadFile = [](const char* p_path) -> bool {
|
|
size_t length = 0;
|
|
void* data = SDL_LoadFile(p_path, &length);
|
|
if (data) {
|
|
SDL_free(data);
|
|
}
|
|
return length > 0;
|
|
};
|
|
|
|
for (const char* file : g_files) {
|
|
registerFile(file);
|
|
}
|
|
|
|
#ifdef EXTENSIONS
|
|
if (Extensions::TextureLoaderExt::enabled) {
|
|
MxString directory =
|
|
MxString("/LEGO") + Extensions::TextureLoaderExt::options["texture loader:texture path"].c_str();
|
|
Extensions::TextureLoaderExt::options["texture loader:texture path"] = directory.GetData();
|
|
wasmfs_create_directory(directory.GetData(), 0644, fetchfs);
|
|
|
|
MxU32 i = 0;
|
|
Emscripten_SendExtensionProgress("HD Textures", 0);
|
|
for (const char* file : g_textures) {
|
|
MxString path = directory + "/" + file + ".bmp";
|
|
registerFile(path.GetData());
|
|
|
|
if (!preloadFile(path.GetData())) {
|
|
Extensions::TextureLoaderExt::AddExcludedFile(file);
|
|
}
|
|
|
|
Emscripten_SendExtensionProgress("HD Textures", (++i * 100) / sizeOfArray(g_textures));
|
|
}
|
|
}
|
|
|
|
if (Extensions::SiLoaderExt::enabled) {
|
|
wasmfs_create_directory("/LEGO/extra", 0644, fetchfs);
|
|
|
|
for (const auto& file : Extensions::SiLoaderExt::GetFiles()) {
|
|
registerFile(file.c_str());
|
|
}
|
|
}
|
|
#endif
|
|
|
|
if (GameState()->GetSavePath() && *GameState()->GetSavePath() && !Emscripten_OPFSDisabled()) {
|
|
if (!opfs) {
|
|
opfs = wasmfs_create_opfs_backend();
|
|
}
|
|
|
|
MxString savePath = GameState()->GetSavePath();
|
|
if (savePath.GetData()[savePath.GetLength() - 1] != '/') {
|
|
savePath += "/";
|
|
}
|
|
|
|
char* parse = savePath.GetData();
|
|
while ((parse = SDL_strchr(++parse, '/'))) {
|
|
*parse = '\0';
|
|
wasmfs_create_directory(savePath.GetData(), 0644, opfs);
|
|
*parse = '/';
|
|
}
|
|
}
|
|
}
|