Merge branch 'master' of github.com:isledecomp/isle-portable into psp

This commit is contained in:
Anders Jenbo 2025-07-02 08:54:43 +02:00
commit 8de4664e86
25 changed files with 221 additions and 104 deletions

55
.github/workflows/docker.yml vendored Normal file
View File

@ -0,0 +1,55 @@
name: Docker
on:
push:
branches: ['master']
env:
REGISTRY: ghcr.io
IMAGE_NAME: ${{ github.repository }}-emscripten
jobs:
publish-emscripten:
name: Publish web port
env:
IMAGE_NAME: ${{ github.repository }}-emscripten
runs-on: ubuntu-latest
permissions:
contents: read
packages: write
attestations: write
id-token: write
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Log in to the Container registry
uses: docker/login-action@65b78e6e13532edd9afa3aa52ac7964289d1a9c1
with:
registry: ${{ env.REGISTRY }}
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Extract metadata (tags, labels) for Docker
id: meta
uses: docker/metadata-action@9ec57ed1fcdbf14dcef7dfbe97b2010124a938b7
with:
images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}
- name: Build and push Docker image
id: push
uses: docker/build-push-action@f2a1d5e99d037542a71f64918e516c093c6f3fc4
with:
file: docker/emscripten/Dockerfile
context: .
push: true
tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }}
- name: Generate artifact attestation
uses: actions/attest-build-provenance@v2
with:
subject-name: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME}}
subject-digest: ${{ steps.push.outputs.digest }}
push-to-registry: true

View File

@ -4,7 +4,7 @@ project(isle LANGUAGES CXX C VERSION 0.1)
if (EMSCRIPTEN)
add_compile_options(-pthread)
add_link_options(-sALLOW_MEMORY_GROWTH=1 -sMAXIMUM_MEMORY=2gb -sUSE_PTHREADS=1 -sPROXY_TO_PTHREAD=1 -sPTHREAD_POOL_SIZE_STRICT=0 -sFORCE_FILESYSTEM=1 -sWASMFS=1 -sEXIT_RUNTIME=1)
add_link_options(-sALLOW_MEMORY_GROWTH=1 -sMAXIMUM_MEMORY=2gb -sUSE_PTHREADS=1 -sPROXY_TO_PTHREAD=1 -sOFFSCREENCANVAS_SUPPORT=1 -sPTHREAD_POOL_SIZE_STRICT=0 -sFORCE_FILESYSTEM=1 -sWASMFS=1 -sEXIT_RUNTIME=1)
set(SDL_PTHREADS ON CACHE BOOL "Enable SDL pthreads" FORCE)
endif()
@ -13,7 +13,7 @@ list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_LIST_DIR}/cmake")
include(CheckCXXSourceCompiles)
include(CMakeDependentOption)
include(CMakePushCheckState)
include(cmake/detectcpu.cmake)
include(CMake/detectcpu.cmake)
DetectTargetCPUArchitectures(ISLE_CPUS)

View File

@ -129,7 +129,7 @@ class Act3 : public LegoWorld {
void RemoveDonut(Act3Ammo& p_p);
MxResult ShootPizza(LegoPathController* p_controller, Vector3& p_location, Vector3& p_direction, Vector3& p_up);
MxResult ShootDonut(LegoPathController* p_controller, Vector3& p_location, Vector3& p_direction, Vector3& p_up);
void FUN_10072ad0(undefined4 p_param1);
void TriggerHitSound(undefined4 p_param1);
MxResult FUN_10073360(Act3Ammo& p_ammo, const Vector3& p_param2);
MxResult FUN_10073390(Act3Ammo& p_ammo, const Vector3& p_param2);
void SetBrickster(Act3Brickster* p_brickster);
@ -168,12 +168,12 @@ class Act3 : public LegoWorld {
Helicopter* m_copter; // 0x420c
Act3Shark* m_shark; // 0x4210
MxFloat m_time; // 0x4214
MxU8 m_unk0x4218; // 0x4218
MxU8 m_unk0x4219; // 0x4219
MxU8 m_unk0x421a; // 0x421a
MxU8 m_unk0x421b; // 0x421b
MxU8 m_unk0x421c; // 0x421c
MxU8 m_unk0x421d; // 0x421d
MxU8 m_pizzaHitSound; // 0x4218
MxU8 m_pizzaMissSound; // 0x4219
MxU8 m_copDonutSound; // 0x421a
MxU8 m_donutMissSound; // 0x421b
MxU8 m_islanderSound; // 0x421c
MxU8 m_bricksterDonutSound; // 0x421d
undefined m_unk0x421e; // 0x421e
Act3List m_unk0x4220; // 0x4220
MxPresenter* m_helicopterDots[15]; // 0x4230

View File

@ -580,7 +580,7 @@ void Act3Brickster::Animate(float p_time)
}
if (m_unk0x54 < p_time) {
((Act3*) m_world)->FUN_10072ad0(5);
((Act3*) m_world)->TriggerHitSound(5);
m_unk0x54 = p_time + 15000.0f;
}
@ -596,7 +596,7 @@ void Act3Brickster::Animate(float p_time)
assert(SoundManager()->GetCacheSoundManager());
if (m_unk0x58 >= 8) {
((Act3*) m_world)->FUN_10072ad0(6);
((Act3*) m_world)->TriggerHitSound(6);
}
else {
SoundManager()->GetCacheSoundManager()->Play("eatpz", NULL, FALSE);

View File

@ -378,11 +378,11 @@ void Act3Ammo::Animate(float p_time)
if (IsBit4()) {
if (IsPizza()) {
m_world->RemovePizza(*this);
m_world->FUN_10072ad0(2);
m_world->TriggerHitSound(2);
}
else {
m_world->RemoveDonut(*this);
m_world->FUN_10072ad0(4);
m_world->TriggerHitSound(4);
}
}
else {

View File

@ -511,7 +511,7 @@ MxBool RemoveFromCurrentWorld(const MxAtomId& p_atomId, MxS32 p_id)
}
else {
if (((MxPresenter*) object)->GetAction()) {
FUN_100b7220(((MxPresenter*) object)->GetAction(), MxDSAction::c_world, FALSE);
ApplyMask(((MxPresenter*) object)->GetAction(), MxDSAction::c_world, FALSE);
}
((MxPresenter*) object)->EndAction();
@ -540,7 +540,7 @@ MxBool RemoveFromWorld(MxAtomId& p_entityAtom, MxS32 p_entityId, MxAtomId& p_wor
}
else {
if (((MxPresenter*) object)->GetAction()) {
FUN_100b7220(((MxPresenter*) object)->GetAction(), MxDSAction::c_world, FALSE);
ApplyMask(((MxPresenter*) object)->GetAction(), MxDSAction::c_world, FALSE);
}
((MxPresenter*) object)->EndAction();

View File

@ -46,7 +46,7 @@ MxResult MxControlPresenter::StartAction(MxStreamController* p_controller, MxDSA
{
MxResult result = MxCompositePresenter::StartAction(p_controller, p_action);
FUN_100b7220(m_action, MxDSAction::c_world | MxDSAction::c_looping, TRUE);
ApplyMask(m_action, MxDSAction::c_world | MxDSAction::c_looping, TRUE);
ParseExtra();
MxS16 i = 0;

View File

@ -122,12 +122,12 @@ void LegoWorld::Destroy(MxBool p_fromDestructor)
animPresenter->DecrementUnknown0xd4();
if (animPresenter->GetUnknown0xd4() == 0) {
FUN_100b7220(action, MxDSAction::c_world, FALSE);
ApplyMask(action, MxDSAction::c_world, FALSE);
presenter->EndAction();
}
}
else {
FUN_100b7220(action, MxDSAction::c_world, FALSE);
ApplyMask(action, MxDSAction::c_world, FALSE);
presenter->EndAction();
}
}
@ -143,7 +143,7 @@ void LegoWorld::Destroy(MxBool p_fromDestructor)
MxDSAction* action = presenter->GetAction();
if (action) {
FUN_100b7220(action, MxDSAction::c_world, FALSE);
ApplyMask(action, MxDSAction::c_world, FALSE);
presenter->EndAction();
}
}
@ -159,7 +159,7 @@ void LegoWorld::Destroy(MxBool p_fromDestructor)
MxDSAction* action = presenter->GetAction();
if (action) {
FUN_100b7220(action, MxDSAction::c_world, FALSE);
ApplyMask(action, MxDSAction::c_world, FALSE);
presenter->EndAction();
}
}

View File

@ -189,7 +189,7 @@ MxResult LegoPartPresenter::Read(MxDSChunk& p_chunk)
}
if (j == 0) {
if (surplusLODs != 0 && lod->GetUnknown0x08Test8()) {
if (surplusLODs != 0 && lod->IsExtraLOD()) {
numLODs++;
surplusLODs--;
}

View File

@ -32,7 +32,7 @@ DECOMP_SIZE_ASSERT(Act3ListElement, 0x0c)
DECOMP_SIZE_ASSERT(Act3List, 0x10)
// GLOBAL: LEGO1 0x100d94f8
Act3Script::Script g_unk0x100d94f8[] = {
Act3Script::Script g_pizzaHitSounds[] = {
Act3Script::c_sns02xni_PlayWav,
Act3Script::c_sns03xni_PlayWav,
Act3Script::c_sns04xni_PlayWav,
@ -52,7 +52,7 @@ Act3Script::Script g_unk0x100d94f8[] = {
};
// GLOBAL: LEGO1 0x100d9538
Act3Script::Script g_unk0x100d9538[] = {
Act3Script::Script g_pizzaMissSounds[] = {
Act3Script::c_sns19xni_PlayWav,
Act3Script::c_sns20xni_PlayWav,
Act3Script::c_sns22xni_PlayWav,
@ -62,7 +62,7 @@ Act3Script::Script g_unk0x100d9538[] = {
};
// GLOBAL: LEGO1 0x100d9550
Act3Script::Script g_unk0x100d9550[] = {
Act3Script::Script g_copDonutSounds[] = {
Act3Script::c_sns25xni_PlayWav,
Act3Script::c_sns26xni_PlayWav,
Act3Script::c_sns27xni_PlayWav,
@ -74,7 +74,7 @@ Act3Script::Script g_unk0x100d9550[] = {
};
// GLOBAL: LEGO1 0x100d9570
Act3Script::Script g_unk0x100d9570[] = {
Act3Script::Script g_donutMissSounds[] = {
Act3Script::c_sns30xni_PlayWav,
Act3Script::c_sns31xni_PlayWav,
Act3Script::c_sns32xni_PlayWav,
@ -84,7 +84,7 @@ Act3Script::Script g_unk0x100d9570[] = {
};
// GLOBAL: LEGO1 0x100d9588
Act3Script::Script g_unk0x100d9588[] = {
Act3Script::Script g_islanderSounds[] = {
Act3Script::c_sns43xma_PlayWav, Act3Script::c_sns46xin_PlayWav, Act3Script::c_sns60xna_PlayWav,
Act3Script::c_sns52xro_PlayWav, Act3Script::c_sns58xna_PlayWav, Act3Script::c_sns68xbu_PlayWav,
Act3Script::c_sns59xna_PlayWav, Act3Script::c_sns51xin_PlayWav, Act3Script::c_sns61xva_PlayWav,
@ -95,7 +95,7 @@ Act3Script::Script g_unk0x100d9588[] = {
};
// GLOBAL: LEGO1 0x100d95d8
Act3Script::Script g_unk0x100d95d8[] = {
Act3Script::Script g_bricksterDonutSounds[] = {
Act3Script::c_tns080br_PlayWav,
Act3Script::c_tnsx07br_PlayWav,
Act3Script::c_snsxx2br_PlayWav,
@ -404,58 +404,58 @@ MxResult Act3::ShootDonut(LegoPathController* p_controller, Vector3& p_location,
// FUNCTION: LEGO1 0x10072ad0
// FUNCTION: BETA10 0x10015eec
void Act3::FUN_10072ad0(undefined4 p_param1)
void Act3::TriggerHitSound(undefined4 p_param1)
{
float time = Timer()->GetTime();
Act3Script::Script objectId;
switch (p_param1) {
case 1: {
if (m_unk0x4218 >= sizeOfArray(g_unk0x100d94f8)) {
m_unk0x4218 = 0;
if (m_pizzaHitSound >= sizeOfArray(g_pizzaHitSounds)) {
m_pizzaHitSound = 0;
}
objectId = g_unk0x100d94f8[m_unk0x4218++];
objectId = g_pizzaHitSounds[m_pizzaHitSound++];
break;
}
case 2: {
if (m_unk0x4219 >= sizeOfArray(g_unk0x100d9538) - 1) {
m_unk0x4219 = 0;
if (m_pizzaMissSound >= sizeOfArray(g_pizzaMissSounds) - 1) {
m_pizzaMissSound = 0;
}
objectId = g_unk0x100d9538[m_unk0x4219++];
objectId = g_pizzaMissSounds[m_pizzaMissSound++];
break;
}
case 3: {
if (m_unk0x421a >= sizeOfArray(g_unk0x100d9550)) {
m_unk0x421a = 0;
if (m_copDonutSound >= sizeOfArray(g_copDonutSounds)) {
m_copDonutSound = 0;
}
objectId = g_unk0x100d9550[m_unk0x421a++];
objectId = g_copDonutSounds[m_copDonutSound++];
break;
}
case 4: {
if (m_unk0x421b >= sizeOfArray(g_unk0x100d9570)) {
m_unk0x421b = 0;
if (m_donutMissSound >= sizeOfArray(g_donutMissSounds)) {
m_donutMissSound = 0;
}
objectId = g_unk0x100d9570[m_unk0x421b++];
objectId = g_donutMissSounds[m_donutMissSound++];
break;
}
case 5: {
if (m_unk0x421c >= sizeOfArray(g_unk0x100d9588)) {
m_unk0x421c = 0;
if (m_islanderSound >= sizeOfArray(g_islanderSounds)) {
m_islanderSound = 0;
}
objectId = g_unk0x100d9588[m_unk0x421c++];
objectId = g_islanderSounds[m_islanderSound++];
break;
}
case 6: {
if (m_unk0x421d >= sizeOfArray(g_unk0x100d95d8)) {
m_unk0x421d = 0;
if (m_bricksterDonutSound >= sizeOfArray(g_bricksterDonutSounds)) {
m_bricksterDonutSound = 0;
}
m_unk0x4220.Insert(g_unk0x100d95d8[m_unk0x421d++], 1);
m_unk0x4220.Insert(g_bricksterDonutSounds[m_bricksterDonutSound++], 1);
return;
}
default:
@ -576,13 +576,12 @@ MxLong Act3::Notify(MxParam& p_param)
m_cop2->VTable0xa8();
m_brickster->VTable0xa8();
m_unk0x4218 = 0;
m_unk0x4219 = 0;
m_unk0x421a = 0;
m_unk0x421b = 0;
m_unk0x421c = 0;
m_unk0x421d = 0;
m_pizzaHitSound = 0;
m_pizzaMissSound = 0;
m_copDonutSound = 0;
m_donutMissSound = 0;
m_islanderSound = 0;
m_bricksterDonutSound = 0;
MxS32 length;
LegoBuildingInfo* info = BuildingManager()->GetInfoArray(length);
@ -702,7 +701,7 @@ MxResult Act3::FUN_10073360(Act3Ammo& p_ammo, const Vector3& p_param2)
{
assert(m_brickster);
m_brickster->FUN_100417a0(p_ammo, p_param2);
FUN_10072ad0(1);
TriggerHitSound(1);
return SUCCESS;
}
@ -719,7 +718,7 @@ MxResult Act3::FUN_10073390(Act3Ammo& p_ammo, const Vector3& p_param2)
m_cop2->FUN_10040350(p_ammo, p_param2);
}
FUN_10072ad0(3);
TriggerHitSound(3);
g_unk0x100f7814++;
return SUCCESS;
}

View File

@ -1457,7 +1457,7 @@ void Infocenter::StartCredits()
MxDSAction* action = presenter->GetAction();
if (action) {
FUN_100b7220(action, MxDSAction::c_world, FALSE);
ApplyMask(action, MxDSAction::c_world, FALSE);
presenter->EndAction();
}
}
@ -1473,7 +1473,7 @@ void Infocenter::StartCredits()
MxDSAction* action = presenter->GetAction();
if (action) {
FUN_100b7220(action, MxDSAction::c_world, FALSE);
ApplyMask(action, MxDSAction::c_world, FALSE);
presenter->EndAction();
}
}

View File

@ -71,11 +71,11 @@ LegoResult LegoLOD::Read(Tgl::Renderer* p_renderer, LegoTextureContainer* p_text
LegoU32 i, indexBackwards, indexForwards, tempNumVertsAndNormals;
unsigned char paletteEntries[256];
if (p_storage->Read(&m_unk0x08, sizeof(undefined4)) != SUCCESS) {
if (p_storage->Read(&m_flags, sizeof(LegoU32)) != SUCCESS) {
goto done;
}
if (GetUnknown0x08Test4()) {
if (SkipReadingData()) {
return SUCCESS;
}
@ -86,11 +86,11 @@ LegoResult LegoLOD::Read(Tgl::Renderer* p_renderer, LegoTextureContainer* p_text
}
if (m_numMeshes == 0) {
ClearFlag(c_bit4);
ClearFlag(c_hasMesh);
return SUCCESS;
}
SetFlag(c_bit4);
SetFlag(c_hasMesh);
m_melems = new Mesh[m_numMeshes];
memset(m_melems, 0, sizeof(*m_melems) * m_numMeshes);
@ -317,7 +317,7 @@ LegoLOD* LegoLOD::Clone(Tgl::Renderer* p_renderer)
dupLod->m_melems[i].m_textured = m_melems[i].m_textured;
}
dupLod->m_unk0x08 = m_unk0x08;
dupLod->m_flags = m_flags;
dupLod->m_numMeshes = m_numMeshes;
dupLod->m_numVertices = m_numVertices;
dupLod->m_numPolys = m_numPolys;

View File

@ -260,7 +260,7 @@ LegoResult LegoROI::Read(
}
if (j == 0) {
if (surplusLODs != 0 && lod->GetUnknown0x08Test8()) {
if (surplusLODs != 0 && lod->IsExtraLOD()) {
numLODs++;
}
}
@ -277,7 +277,7 @@ LegoResult LegoROI::Read(
}
if (i == 0) {
if (surplusLODs != 0 && lod->GetUnknown0x08Test8()) {
if (surplusLODs != 0 && lod->IsExtraLOD()) {
numLODs++;
}
}

View File

@ -92,7 +92,7 @@ void MakeSourceName(char*, const char*);
void OmniError(const char* p_message, MxS32 p_status);
void SetOmniUserMessage(void (*p_omniUserMessage)(const char*, MxS32));
MxBool ContainsPresenter(MxCompositePresenterList& p_presenterList, MxPresenter* p_presenter);
void FUN_100b7220(MxDSAction* p_action, MxU32 p_newFlags, MxBool p_setFlags);
void ApplyMask(MxDSAction* p_action, MxU32 p_mask, MxBool p_setFlags);
MxBool KeyValueStringParse(char*, const char*, const char*);
// TEMPLATE: BETA10 0x1012dfd0

View File

@ -153,16 +153,16 @@ void SetOmniUserMessage(void (*p_omniUserMessage)(const char*, MxS32))
// FUNCTION: LEGO1 0x100b7220
// FUNCTION: BETA10 0x10136f37
void FUN_100b7220(MxDSAction* p_action, MxU32 p_newFlags, MxBool p_setFlags)
void ApplyMask(MxDSAction* p_action, MxU32 p_mask, MxBool p_setFlags)
{
MxU32 oldFlags = p_action->GetFlags();
MxU32 newFlags;
if (p_setFlags) {
newFlags = oldFlags | p_newFlags;
newFlags = oldFlags | p_mask;
}
else {
newFlags = oldFlags & ~p_newFlags;
newFlags = oldFlags & ~p_mask;
}
p_action->SetFlags(newFlags);
@ -172,7 +172,7 @@ void FUN_100b7220(MxDSAction* p_action, MxU32 p_newFlags, MxBool p_setFlags)
MxDSAction* action;
while (cursor.Next(action)) {
FUN_100b7220(action, p_newFlags, p_setFlags);
ApplyMask(action, p_mask, p_setFlags);
}
}
}

View File

@ -14,10 +14,10 @@
class ViewLOD : public LODObject {
public:
enum {
c_bit4 = 0x10
c_hasMesh = 0x10
};
ViewLOD(Tgl::Renderer* pRenderer) : m_meshBuilder(NULL), m_unk0x08(3) {}
ViewLOD(Tgl::Renderer* pRenderer) : m_meshBuilder(NULL), m_flags(3) {}
~ViewLOD() override;
// FUNCTION: LEGO1 0x100a6f30
@ -28,19 +28,19 @@ class ViewLOD : public LODObject {
Tgl::MeshBuilder* GetMeshBuilder() { return m_meshBuilder; }
const Tgl::MeshBuilder* GetMeshBuilder() const { return m_meshBuilder; }
undefined4 GetUnknown0x08() { return m_unk0x08; }
unsigned char GetUnknown0x08Test4() { return m_unk0x08 & 0xffffff04; }
unsigned char GetUnknown0x08Test8() { return m_unk0x08 & 0xffffff08; }
unsigned int GetFlags() { return m_flags; }
unsigned char SkipReadingData() { return m_flags & 0xffffff04; }
unsigned char IsExtraLOD() { return m_flags & 0xffffff08; }
void SetFlag(unsigned char p_flag) { m_unk0x08 |= p_flag; }
void ClearFlag(unsigned char p_flag) { m_unk0x08 &= ~p_flag; }
void SetFlag(unsigned char p_flag) { m_flags |= p_flag; }
void ClearFlag(unsigned char p_flag) { m_flags &= ~p_flag; }
// SYNTHETIC: LEGO1 0x100a6f60
// ViewLOD::`scalar deleting destructor'
protected:
Tgl::MeshBuilder* m_meshBuilder; // 0x04
undefined4 m_unk0x08; // 0x08
unsigned int m_flags; // 0x08
};
#endif // VIEWLOD_H

View File

@ -165,7 +165,7 @@ void ViewManager::UpdateROIDetailBasedOnLOD(ViewROI* p_roi, int p_lodLevel)
if (lodLevel < 0) {
lod = (ViewLOD*) p_roi->GetLOD(p_lodLevel);
if (lod->GetUnknown0x08() & ViewLOD::c_bit4) {
if (lod->GetFlags() & ViewLOD::c_hasMesh) {
scene->Add(group);
SetAppData(p_roi, reinterpret_cast<LPD3DRM_APPDATA>(p_roi));
}
@ -184,7 +184,7 @@ void ViewManager::UpdateROIDetailBasedOnLOD(ViewROI* p_roi, int p_lodLevel)
lod = (ViewLOD*) p_roi->GetLOD(p_lodLevel);
}
if (lod->GetUnknown0x08() & ViewLOD::c_bit4) {
if (lod->GetFlags() & ViewLOD::c_hasMesh) {
meshBuilder = lod->GetMeshBuilder();
if (meshBuilder != NULL) {
@ -389,7 +389,7 @@ inline int ViewManager::GetFirstLODIndex(ViewROI* p_roi)
const LODListBase* lods = p_roi->GetLODs();
if (lods != NULL && lods->Size() > 0) {
if (((ViewLOD*) p_roi->GetLOD(0))->GetUnknown0x08Test8()) {
if (((ViewLOD*) p_roi->GetLOD(0))->IsExtraLOD()) {
return 1;
}
else {
@ -404,7 +404,7 @@ inline int ViewManager::GetFirstLODIndex(ViewROI* p_roi)
const LODListBase* lods = ((ViewROI*) *it)->GetLODs();
if (lods != NULL && lods->Size() > 0) {
if (((ViewLOD*) ((ViewROI*) *it)->GetLOD(0))->GetUnknown0x08Test8()) {
if (((ViewLOD*) ((ViewROI*) *it)->GetLOD(0))->IsExtraLOD()) {
return 1;
}
else {

View File

@ -8,8 +8,6 @@ Please note: this project is dedicated to achieving platform independence withou
## Status
### Supported platforms
| Platform | Status |
| - | - |
| Windows | [![CI](https://github.com/isledecomp/isle-portable/actions/workflows/ci.yml/badge.svg)](https://github.com/isledecomp/isle-portable/actions/workflows/ci.yml) |
@ -20,7 +18,16 @@ Please note: this project is dedicated to achieving platform independence withou
We are actively working to support more platforms. If you have experience with a particular platform, we encourage you to contribute to `isle-portable`. You can find a [list of ongoing efforts](https://github.com/isledecomp/isle-portable/wiki/Work%E2%80%90in%E2%80%90progress-ports) in our Wiki.
### Library substitutions
## Usage
**An existing copy of LEGO Island is required to use this project.**
As it stands, builds provided in the [Releases tab](https://github.com/isledecomp/isle-portable/releases/tag/continuous) are mainly for developers; as such, they may not work properly for all end-users. Work is currently ongoing to create workable release builds ready for gameplay and general use by end-users. If you are technically inclined, you may find it easiest to compile the project yourself to get it running at this current point in time.
[Installation instructions](https://github.com/isledecomp/isle-portable/wiki/Installation) for some ports can be found in our Wiki.
## Library substitutions
To achieve our goal of platform independence, we need to replace any Windows-only libraries with platform-independent alternatives. This ensures that our codebase remains versatile and compatible across various systems. The following table serves as an overview of major libraries / subsystems and their chosen replacements. For any significant changes or additions, it's recommended to discuss them with the team on the Matrix chat first to ensure consistency and alignment with our project's objectives.
@ -43,12 +50,6 @@ To achieve our goal of platform independence, we need to replace any Windows-onl
This project uses the [CMake](https://cmake.org/) build system, which allows for a high degree of versatility regarding compilers and development environments. Please refer to the [GitHub action](/.github/workflows//ci.yml) for guidance.
## Usage
**An existing copy of LEGO Island is required to use this project.**
As it stands, the builds provided in the Releases tab are for developers; as such, they may not work properly for end-users. Work is currently ongoing to create workable release builds ready for gameplay and general use by end-users. If you are technically inclined, you may find it easiest to compile the project yourself to get it running at this current point in time.
## Contributing
If you're interested in helping or contributing to this project, check out the [CONTRIBUTING](/CONTRIBUTING.md) page.

View File

@ -0,0 +1,37 @@
FROM emscripten/emsdk:latest AS builder
ARG CMAKE_VERSION=3.29.3
WORKDIR /src
USER root
RUN apt-get update && apt-get install -y git wget && rm -rf /var/lib/apt/lists/*
RUN wget https://github.com/Kitware/CMake/releases/download/v${CMAKE_VERSION}/cmake-${CMAKE_VERSION}-Linux-x86_64.sh -O /tmp/cmake.sh && \
chmod +x /tmp/cmake.sh && \
/tmp/cmake.sh --skip-license --prefix=/usr/local && \
rm /tmp/cmake.sh
RUN chown -R emscripten:emscripten /src
USER emscripten
COPY ISLE/emscripten/libwasmfs_fetch.js.patch /tmp/
RUN cd /emsdk/upstream/emscripten && \
git apply --check /tmp/libwasmfs_fetch.js.patch && \
git apply /tmp/libwasmfs_fetch.js.patch
COPY --chown=emscripten:emscripten . .
RUN emcmake cmake -S . -B build -DISLE_BUILD_CONFIG=OFF -DISLE_DEBUG=OFF -DCMAKE_BUILD_TYPE=Release -DISLE_EMSCRIPTEN_HOST=/assets && \
emmake cmake --build build -j 32
RUN echo "Fetching isle.pizza frontend..."; \
git clone --depth 1 https://github.com/isledecomp/isle.pizza /tmp/isle.pizza;
FROM nginx:alpine
COPY docker/emscripten/nginx.conf /etc/nginx/nginx.conf
COPY --from=builder /tmp/isle.pizza /usr/share/nginx/html
COPY --from=builder /src/build/isle.* /usr/share/nginx/html
EXPOSE 6931

View File

@ -0,0 +1,27 @@
events {
worker_connections 1024;
}
http {
include /etc/nginx/mime.types;
server {
listen 6931;
server_name localhost;
add_header 'Cross-Origin-Embedder-Policy' 'require-corp';
add_header 'Cross-Origin-Opener-Policy' 'same-origin';
add_header 'Cross-Origin-Resource-Policy' 'cross-origin';
location / {
root /usr/share/nginx/html;
index index.html isle.html;
try_files $uri $uri/ =404;
}
location ~* ^/assets/(.*)$ {
alias /assets/;
try_files /$1 /DATA/disk/$1 =404;
}
}
}

View File

@ -45,11 +45,13 @@ else()
endif()
find_library(OPENGL_ES2_LIBRARY NAMES GLESv2)
if(OPENGL_ES2_LIBRARY)
if(EMSCRIPTEN OR OPENGL_ES2_LIBRARY)
message(STATUS "Found OpenGL: enabling OpenGL ES 2.x renderer")
target_sources(miniwin PRIVATE src/d3drm/backends/opengles2/renderer.cpp)
target_compile_definitions(miniwin PRIVATE USE_OPENGLES2)
target_link_libraries(miniwin PRIVATE OpenGL::GL)
if(OPENGL_ES2_LIBRARY)
target_link_libraries(miniwin PRIVATE OpenGL::GL)
endif()
else()
message(STATUS "🧩 OpenGL ES 2.x support not enabled")
endif()

View File

@ -134,7 +134,6 @@ static Uint32 UploadTextureData(SDL_Surface* src, bool useNPOT, bool isUi)
SDL_Surface* finalSurface = working;
// Resize to next power-of-two if needed and NPOT isn't supported
int newW = NextPowerOfTwo(working->w);
int newH = NextPowerOfTwo(working->h);
@ -199,7 +198,13 @@ Uint32 OpenGL1Renderer::GetTextureId(IDirect3DRMTexture* iTexture, bool isUi)
}
}
m_textures.push_back({texture, texture->m_version, texId, surface->m_surface->w, surface->m_surface->h});
m_textures.push_back(
{texture,
texture->m_version,
texId,
static_cast<float>(surface->m_surface->w),
static_cast<float>(surface->m_surface->h)}
);
AddTextureDestroyCallback((Uint32) (m_textures.size() - 1), texture);
return (Uint32) (m_textures.size() - 1);
}

View File

@ -1,12 +1,9 @@
{
"id": "org.legoisland.Isle",
"runtime": "org.kde.Platform",
"sdk": "org.kde.Sdk",
"runtime-version": "6.8",
"command": "isle",
"finish-args": [
"--share=ipc",
"--socket=wayland",
@ -19,7 +16,6 @@
"--filesystem=/mnt/:ro",
"--filesystem=home:ro"
],
"modules": [
{
"name": "isle",
@ -34,11 +30,6 @@
"path": "../../../3rdparty",
"dest": "3rdparty/"
},
{
"type": "dir",
"path": "../../../cmake",
"dest": "cmake/"
},
{
"type": "dir",
"path": "../../../CMake",
@ -86,4 +77,4 @@
}
}
]
}
}