From f0df3cd0ef1f339293f9d13fd1d2e0854b0e011d Mon Sep 17 00:00:00 2001 From: Korbo Date: Mon, 30 Jun 2025 14:20:53 -0500 Subject: [PATCH 1/8] Clear a few unknowns in act 3 (#1597) * Clear a few unknowns in act 3 * fix build error * fix other build error * requested changes --- LEGO1/lego/legoomni/include/act3.h | 14 ++-- LEGO1/lego/legoomni/src/actors/act3actors.cpp | 4 +- LEGO1/lego/legoomni/src/actors/act3ammo.cpp | 4 +- LEGO1/lego/legoomni/src/worlds/act3.cpp | 67 +++++++++---------- 4 files changed, 44 insertions(+), 45 deletions(-) diff --git a/LEGO1/lego/legoomni/include/act3.h b/LEGO1/lego/legoomni/include/act3.h index dc81160c..38e2876e 100644 --- a/LEGO1/lego/legoomni/include/act3.h +++ b/LEGO1/lego/legoomni/include/act3.h @@ -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 diff --git a/LEGO1/lego/legoomni/src/actors/act3actors.cpp b/LEGO1/lego/legoomni/src/actors/act3actors.cpp index 1bd13278..c9750667 100644 --- a/LEGO1/lego/legoomni/src/actors/act3actors.cpp +++ b/LEGO1/lego/legoomni/src/actors/act3actors.cpp @@ -579,7 +579,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; } @@ -595,7 +595,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); diff --git a/LEGO1/lego/legoomni/src/actors/act3ammo.cpp b/LEGO1/lego/legoomni/src/actors/act3ammo.cpp index 04e0e93c..d88a7bee 100644 --- a/LEGO1/lego/legoomni/src/actors/act3ammo.cpp +++ b/LEGO1/lego/legoomni/src/actors/act3ammo.cpp @@ -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 { diff --git a/LEGO1/lego/legoomni/src/worlds/act3.cpp b/LEGO1/lego/legoomni/src/worlds/act3.cpp index 64ed8d6c..10bf69cf 100644 --- a/LEGO1/lego/legoomni/src/worlds/act3.cpp +++ b/LEGO1/lego/legoomni/src/worlds/act3.cpp @@ -31,7 +31,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, @@ -51,7 +51,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, @@ -61,7 +61,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, @@ -73,7 +73,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, @@ -83,7 +83,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, @@ -94,7 +94,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, @@ -403,58 +403,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: @@ -575,13 +575,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); @@ -701,7 +700,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; } @@ -718,7 +717,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; } From f825b053ffa70e80d6cac7f8e8f2683c242a270f Mon Sep 17 00:00:00 2001 From: Fabian Neundorf Date: Tue, 1 Jul 2025 00:29:23 +0200 Subject: [PATCH 2/8] Clear unknown in `mxutilities.h` (#1598) Also change the parameter name to mask as it better represents the usage. --- LEGO1/lego/legoomni/src/common/legoutils.cpp | 4 ++-- LEGO1/lego/legoomni/src/common/mxcontrolpresenter.cpp | 2 +- LEGO1/lego/legoomni/src/entity/legoworld.cpp | 8 ++++---- LEGO1/lego/legoomni/src/worlds/infocenter.cpp | 4 ++-- LEGO1/omni/include/mxutilities.h | 2 +- LEGO1/omni/src/common/mxutilities.cpp | 8 ++++---- 6 files changed, 14 insertions(+), 14 deletions(-) diff --git a/LEGO1/lego/legoomni/src/common/legoutils.cpp b/LEGO1/lego/legoomni/src/common/legoutils.cpp index a4f8d022..a9ea98a7 100644 --- a/LEGO1/lego/legoomni/src/common/legoutils.cpp +++ b/LEGO1/lego/legoomni/src/common/legoutils.cpp @@ -507,7 +507,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(); @@ -536,7 +536,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(); diff --git a/LEGO1/lego/legoomni/src/common/mxcontrolpresenter.cpp b/LEGO1/lego/legoomni/src/common/mxcontrolpresenter.cpp index 0b397836..13ce2cee 100644 --- a/LEGO1/lego/legoomni/src/common/mxcontrolpresenter.cpp +++ b/LEGO1/lego/legoomni/src/common/mxcontrolpresenter.cpp @@ -44,7 +44,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; diff --git a/LEGO1/lego/legoomni/src/entity/legoworld.cpp b/LEGO1/lego/legoomni/src/entity/legoworld.cpp index c0819883..c12d32e4 100644 --- a/LEGO1/lego/legoomni/src/entity/legoworld.cpp +++ b/LEGO1/lego/legoomni/src/entity/legoworld.cpp @@ -120,12 +120,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(); } } @@ -141,7 +141,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(); } } @@ -157,7 +157,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(); } } diff --git a/LEGO1/lego/legoomni/src/worlds/infocenter.cpp b/LEGO1/lego/legoomni/src/worlds/infocenter.cpp index 90078e6d..55171729 100644 --- a/LEGO1/lego/legoomni/src/worlds/infocenter.cpp +++ b/LEGO1/lego/legoomni/src/worlds/infocenter.cpp @@ -1450,7 +1450,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(); } } @@ -1466,7 +1466,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(); } } diff --git a/LEGO1/omni/include/mxutilities.h b/LEGO1/omni/include/mxutilities.h index 51b897b7..8a897e39 100644 --- a/LEGO1/omni/include/mxutilities.h +++ b/LEGO1/omni/include/mxutilities.h @@ -75,7 +75,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 diff --git a/LEGO1/omni/src/common/mxutilities.cpp b/LEGO1/omni/src/common/mxutilities.cpp index 365d6b18..54714c4d 100644 --- a/LEGO1/omni/src/common/mxutilities.cpp +++ b/LEGO1/omni/src/common/mxutilities.cpp @@ -150,16 +150,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); @@ -169,7 +169,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); } } } From 7b06ee5ae610d94bbe51b32b9e5427394f65e22d Mon Sep 17 00:00:00 2001 From: Anders Jenbo Date: Wed, 2 Jul 2025 00:45:25 +0200 Subject: [PATCH 3/8] Add support for POT-only GPUs, fix VBO (#468) --- miniwin/src/d3drm/backends/opengl1/actual.cpp | 39 +++++---- miniwin/src/d3drm/backends/opengl1/actual.h | 6 +- .../src/d3drm/backends/opengl1/renderer.cpp | 86 +++++++++++++++---- .../src/d3drm/backends/opengles2/renderer.cpp | 1 + miniwin/src/internal/d3drmrenderer_opengl1.h | 1 + 5 files changed, 96 insertions(+), 37 deletions(-) diff --git a/miniwin/src/d3drm/backends/opengl1/actual.cpp b/miniwin/src/d3drm/backends/opengl1/actual.cpp index e1c56636..e809f7e5 100644 --- a/miniwin/src/d3drm/backends/opengl1/actual.cpp +++ b/miniwin/src/d3drm/backends/opengl1/actual.cpp @@ -42,12 +42,26 @@ void GL11_DestroyTexture(GLuint texId) glDeleteTextures(1, &texId); } -GLuint GL11_UploadTextureData(void* pixels, int width, int height) +GLuint GL11_UploadTextureData(void* pixels, int width, int height, bool isUi) { GLuint texId; glGenTextures(1, &texId); glBindTexture(GL_TEXTURE_2D, texId); + if (isUi) { + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + } + else { + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); + } + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, pixels); + return texId; } @@ -111,7 +125,6 @@ void GL11_BeginFrame(const Matrix4x4* projection) glDepthMask(GL_TRUE); glEnable(GL_LIGHTING); glEnable(GL_COLOR_MATERIAL); - glColorMaterial(GL_FRONT, GL_AMBIENT_AND_DIFFUSE); // Disable all lights and reset global ambient for (int i = 0; i < 8; ++i) { @@ -198,6 +211,7 @@ void GL11_SubmitDraw( glLoadMatrixf(&modelViewMatrix[0][0]); glEnable(GL_NORMALIZE); + glColorMaterial(GL_FRONT, GL_AMBIENT_AND_DIFFUSE); glColor4ub(appearance.color.r, appearance.color.g, appearance.color.b, appearance.color.a); if (appearance.shininess != 0.0f) { @@ -220,8 +234,6 @@ void GL11_SubmitDraw( // Bind texture if present if (appearance.textureId != NO_TEXTURE_ID) { - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glEnable(GL_TEXTURE_2D); glBindTexture(GL_TEXTURE_2D, texId); glEnableClientState(GL_TEXTURE_COORD_ARRAY); @@ -279,7 +291,7 @@ void GL11_Clear(float r, float g, float b) } void GL11_Draw2DImage( - GLuint texId, + GLTextureCacheEntry& cache, const SDL_Rect& srcRect, const SDL_Rect& dstRect, float left, @@ -305,24 +317,17 @@ void GL11_Draw2DImage( glColor4f(1.0f, 1.0f, 1.0f, 1.0f); glEnable(GL_TEXTURE_2D); - glBindTexture(GL_TEXTURE_2D, texId); + glBindTexture(GL_TEXTURE_2D, cache.glTextureId); glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); - GLint boundTexture = 0; glGetIntegerv(GL_TEXTURE_BINDING_2D, &boundTexture); - GLfloat texW, texH; - glGetTexLevelParameterfv(GL_TEXTURE_2D, 0, GL_TEXTURE_WIDTH, &texW); - glGetTexLevelParameterfv(GL_TEXTURE_2D, 0, GL_TEXTURE_HEIGHT, &texH); - - float u1 = srcRect.x / texW; - float v1 = srcRect.y / texH; - float u2 = (srcRect.x + srcRect.w) / texW; - float v2 = (srcRect.y + srcRect.h) / texH; + float u1 = srcRect.x / cache.width; + float v1 = srcRect.y / cache.height; + float u2 = (srcRect.x + srcRect.w) / cache.width; + float v2 = (srcRect.y + srcRect.h) / cache.height; float x1 = (float) dstRect.x; float y1 = (float) dstRect.y; diff --git a/miniwin/src/d3drm/backends/opengl1/actual.h b/miniwin/src/d3drm/backends/opengl1/actual.h index 8a4fb8e8..1d5e407d 100644 --- a/miniwin/src/d3drm/backends/opengl1/actual.h +++ b/miniwin/src/d3drm/backends/opengl1/actual.h @@ -39,6 +39,8 @@ struct GLTextureCacheEntry { IDirect3DRMTexture* texture; Uint32 version; GLuint glTextureId; + float width; + float height; }; struct GLMeshCacheEntry { @@ -62,7 +64,7 @@ struct GLMeshCacheEntry { void GL11_InitState(); void GL11_LoadExtensions(); void GL11_DestroyTexture(GLuint texId); -GLuint GL11_UploadTextureData(void* pixels, int width, int height); +GLuint GL11_UploadTextureData(void* pixels, int width, int height, bool isUI); void GL11_UploadMesh(GLMeshCacheEntry& cache, bool hasTexture); void GL11_DestroyMesh(GLMeshCacheEntry& cache); void GL11_BeginFrame(const Matrix4x4* projection); @@ -77,7 +79,7 @@ void GL11_SubmitDraw( void GL11_Resize(int width, int height); void GL11_Clear(float r, float g, float b); void GL11_Draw2DImage( - GLuint texId, + GLTextureCacheEntry& cache, const SDL_Rect& srcRect, const SDL_Rect& dstRect, float left, diff --git a/miniwin/src/d3drm/backends/opengl1/renderer.cpp b/miniwin/src/d3drm/backends/opengl1/renderer.cpp index fb7fccd4..2e18b38a 100644 --- a/miniwin/src/d3drm/backends/opengl1/renderer.cpp +++ b/miniwin/src/d3drm/backends/opengl1/renderer.cpp @@ -58,6 +58,8 @@ OpenGL1Renderer::OpenGL1Renderer(DWORD width, DWORD height, SDL_GLContext contex m_virtualHeight = height; m_renderedImage = SDL_CreateSurface(m_width, m_height, SDL_PIXELFORMAT_RGBA32); GL11_LoadExtensions(); + m_useVBOs = SDL_GL_ExtensionSupported("GL_ARB_vertex_buffer_object"); + m_useNPOT = SDL_GL_ExtensionSupported("GL_OES_texture_npot"); } OpenGL1Renderer::~OpenGL1Renderer() @@ -108,6 +110,58 @@ void OpenGL1Renderer::AddTextureDestroyCallback(Uint32 id, IDirect3DRMTexture* t ); } +static int NextPowerOfTwo(int v) +{ + int power = 1; + while (power < v) { + power <<= 1; + } + return power; +} + +static Uint32 UploadTextureData(SDL_Surface* src, bool useNPOT, bool isUi) +{ + SDL_Surface* working = src; + if (src->format != SDL_PIXELFORMAT_RGBA32) { + working = SDL_ConvertSurface(src, SDL_PIXELFORMAT_RGBA32); + if (!working) { + SDL_Log("SDL_ConvertSurface failed: %s", SDL_GetError()); + return NO_TEXTURE_ID; + } + } + + SDL_Surface* finalSurface = working; + + int newW = NextPowerOfTwo(working->w); + int newH = NextPowerOfTwo(working->h); + + if (!useNPOT && (newW != working->w || newH != working->h)) { + SDL_Surface* resized = SDL_CreateSurface(newW, newH, working->format); + if (!resized) { + SDL_Log("SDL_CreateSurface (resize) failed: %s", SDL_GetError()); + if (working != src) { + SDL_DestroySurface(working); + } + return NO_TEXTURE_ID; + } + + SDL_Rect srcRect = {0, 0, working->w, working->h}; + SDL_Rect dstRect = {0, 0, newW, newH}; + SDL_BlitSurfaceScaled(working, &srcRect, resized, &dstRect, SDL_SCALEMODE_NEAREST); + + if (working != src) { + SDL_DestroySurface(working); + } + finalSurface = resized; + } + + Uint32 texId = GL11_UploadTextureData(finalSurface->pixels, finalSurface->w, finalSurface->h, isUi); + if (finalSurface != src) { + SDL_DestroySurface(finalSurface); + } + return texId; +} + Uint32 OpenGL1Renderer::GetTextureId(IDirect3DRMTexture* iTexture, bool isUi) { auto texture = static_cast(iTexture); @@ -118,28 +172,16 @@ Uint32 OpenGL1Renderer::GetTextureId(IDirect3DRMTexture* iTexture, bool isUi) if (tex.texture == texture) { if (tex.version != texture->m_version) { GL11_DestroyTexture(tex.glTextureId); - - SDL_Surface* surf = SDL_ConvertSurface(surface->m_surface, SDL_PIXELFORMAT_RGBA32); - if (!surf) { - return NO_TEXTURE_ID; - } - tex.glTextureId = GL11_UploadTextureData(surf->pixels, surf->w, surf->h); - SDL_DestroySurface(surf); - + tex.glTextureId = UploadTextureData(surface->m_surface, m_useNPOT, isUi); tex.version = texture->m_version; + tex.width = surface->m_surface->w; + tex.height = surface->m_surface->h; } return i; } } - GLuint texId; - - SDL_Surface* surf = SDL_ConvertSurface(surface->m_surface, SDL_PIXELFORMAT_RGBA32); - if (!surf) { - return NO_TEXTURE_ID; - } - texId = GL11_UploadTextureData(surf->pixels, surf->w, surf->h); - SDL_DestroySurface(surf); + GLuint texId = UploadTextureData(surface->m_surface, m_useNPOT, isUi); for (Uint32 i = 0; i < m_textures.size(); ++i) { auto& tex = m_textures[i]; @@ -147,12 +189,20 @@ Uint32 OpenGL1Renderer::GetTextureId(IDirect3DRMTexture* iTexture, bool isUi) tex.texture = texture; tex.version = texture->m_version; tex.glTextureId = texId; + tex.width = surface->m_surface->w; + tex.height = surface->m_surface->h; AddTextureDestroyCallback(i, texture); return i; } } - m_textures.push_back({texture, texture->m_version, texId}); + m_textures.push_back( + {texture, + texture->m_version, + texId, + static_cast(surface->m_surface->w), + static_cast(surface->m_surface->h)} + ); AddTextureDestroyCallback((Uint32) (m_textures.size() - 1), texture); return (Uint32) (m_textures.size() - 1); } @@ -331,7 +381,7 @@ void OpenGL1Renderer::Draw2DImage(Uint32 textureId, const SDL_Rect& srcRect, con float top = -m_viewportTransform.offsetY / m_viewportTransform.scale; float bottom = (m_height - m_viewportTransform.offsetY) / m_viewportTransform.scale; - GL11_Draw2DImage(m_textures[textureId].glTextureId, srcRect, dstRect, left, right, bottom, top); + GL11_Draw2DImage(m_textures[textureId], srcRect, dstRect, left, right, bottom, top); } void OpenGL1Renderer::Download(SDL_Surface* target) diff --git a/miniwin/src/d3drm/backends/opengles2/renderer.cpp b/miniwin/src/d3drm/backends/opengles2/renderer.cpp index 6695da81..9cb8455c 100644 --- a/miniwin/src/d3drm/backends/opengles2/renderer.cpp +++ b/miniwin/src/d3drm/backends/opengles2/renderer.cpp @@ -47,6 +47,7 @@ Direct3DRMRenderer* OpenGLES2Renderer::Create(DWORD width, DWORD height) SDL_GLContext context = SDL_GL_CreateContext(DDWindow); if (!context) { + SDL_Log("SDL_GL_CreateContext: %s", SDL_GetError()); return nullptr; } diff --git a/miniwin/src/internal/d3drmrenderer_opengl1.h b/miniwin/src/internal/d3drmrenderer_opengl1.h index 58406709..dce25e6b 100644 --- a/miniwin/src/internal/d3drmrenderer_opengl1.h +++ b/miniwin/src/internal/d3drmrenderer_opengl1.h @@ -46,6 +46,7 @@ class OpenGL1Renderer : public Direct3DRMRenderer { D3DRMMATRIX4D m_projection; SDL_Surface* m_renderedImage; bool m_useVBOs; + bool m_useNPOT; bool m_dirty = false; std::vector m_lights; SDL_GLContext m_context; From 1f1787b5ac8b1a5940b0f42e4a89e738f707cbc7 Mon Sep 17 00:00:00 2001 From: Christian Semmler Date: Tue, 1 Jul 2025 15:46:57 -0700 Subject: [PATCH 4/8] Consolidate into a single CMake folder (#469) * Consolidate into a single CMake folder' * Remove extra path thing --- {cmake => CMake}/Findiniparser.cmake | 0 {cmake => CMake}/detectcpu.cmake | 0 CMakeLists.txt | 2 +- packaging/linux/flatpak/org.legoisland.Isle.json | 11 +---------- 4 files changed, 2 insertions(+), 11 deletions(-) rename {cmake => CMake}/Findiniparser.cmake (100%) rename {cmake => CMake}/detectcpu.cmake (100%) diff --git a/cmake/Findiniparser.cmake b/CMake/Findiniparser.cmake similarity index 100% rename from cmake/Findiniparser.cmake rename to CMake/Findiniparser.cmake diff --git a/cmake/detectcpu.cmake b/CMake/detectcpu.cmake similarity index 100% rename from cmake/detectcpu.cmake rename to CMake/detectcpu.cmake diff --git a/CMakeLists.txt b/CMakeLists.txt index e9812aea..f758bd95 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -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) diff --git a/packaging/linux/flatpak/org.legoisland.Isle.json b/packaging/linux/flatpak/org.legoisland.Isle.json index e8cd3f8e..178434fa 100644 --- a/packaging/linux/flatpak/org.legoisland.Isle.json +++ b/packaging/linux/flatpak/org.legoisland.Isle.json @@ -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 @@ } } ] -} +} \ No newline at end of file From de31c12a9ecc32384ef6549e0419971747489193 Mon Sep 17 00:00:00 2001 From: Christian Semmler Date: Tue, 1 Jul 2025 15:47:05 -0700 Subject: [PATCH 5/8] Add Docker image for Emscripten port (#466) * Add Docker web port image * Comment out master * Optimize * Slim down image * Revert "Comment out master" This reverts commit 115c9770e8e01c1a4bc2455eca944d4f7f4c1cf4. * Allow running from ISO --- .github/workflows/docker.yml | 55 ++++++++++++++++++++++++++++++++++++ docker/emscripten/Dockerfile | 37 ++++++++++++++++++++++++ docker/emscripten/nginx.conf | 27 ++++++++++++++++++ 3 files changed, 119 insertions(+) create mode 100644 .github/workflows/docker.yml create mode 100644 docker/emscripten/Dockerfile create mode 100644 docker/emscripten/nginx.conf diff --git a/.github/workflows/docker.yml b/.github/workflows/docker.yml new file mode 100644 index 00000000..ca316590 --- /dev/null +++ b/.github/workflows/docker.yml @@ -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 diff --git a/docker/emscripten/Dockerfile b/docker/emscripten/Dockerfile new file mode 100644 index 00000000..d15d2406 --- /dev/null +++ b/docker/emscripten/Dockerfile @@ -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 diff --git a/docker/emscripten/nginx.conf b/docker/emscripten/nginx.conf new file mode 100644 index 00000000..30d9e34d --- /dev/null +++ b/docker/emscripten/nginx.conf @@ -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; + } + } +} From cb7a35b7497f92e9bab6a82a9e00e62f531ad0bd Mon Sep 17 00:00:00 2001 From: Christian Semmler Date: Wed, 2 Jul 2025 01:04:02 +0200 Subject: [PATCH 6/8] Update README.md [skip ci] --- README.md | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/README.md b/README.md index 8f5c6756..fe4a285f 100644 --- a/README.md +++ b/README.md @@ -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. From 805c57b6aaf2e035388d55edbd22118cb9cea9e3 Mon Sep 17 00:00:00 2001 From: Fabian Neundorf Date: Wed, 2 Jul 2025 02:02:03 +0200 Subject: [PATCH 7/8] Clear unknowns in `ViewLOD` (#1599) --- .../legoomni/src/video/legopartpresenter.cpp | 2 +- LEGO1/lego/sources/roi/legolod.cpp | 10 +++++----- LEGO1/lego/sources/roi/legoroi.cpp | 4 ++-- LEGO1/viewmanager/viewlod.h | 16 ++++++++-------- LEGO1/viewmanager/viewmanager.cpp | 8 ++++---- 5 files changed, 20 insertions(+), 20 deletions(-) diff --git a/LEGO1/lego/legoomni/src/video/legopartpresenter.cpp b/LEGO1/lego/legoomni/src/video/legopartpresenter.cpp index f1d55a6d..88e31dd6 100644 --- a/LEGO1/lego/legoomni/src/video/legopartpresenter.cpp +++ b/LEGO1/lego/legoomni/src/video/legopartpresenter.cpp @@ -187,7 +187,7 @@ MxResult LegoPartPresenter::Read(MxDSChunk& p_chunk) } if (j == 0) { - if (surplusLODs != 0 && lod->GetUnknown0x08Test8()) { + if (surplusLODs != 0 && lod->IsExtraLOD()) { numLODs++; surplusLODs--; } diff --git a/LEGO1/lego/sources/roi/legolod.cpp b/LEGO1/lego/sources/roi/legolod.cpp index bf157b56..453a4dac 100644 --- a/LEGO1/lego/sources/roi/legolod.cpp +++ b/LEGO1/lego/sources/roi/legolod.cpp @@ -69,11 +69,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; } @@ -84,11 +84,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); @@ -315,7 +315,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; diff --git a/LEGO1/lego/sources/roi/legoroi.cpp b/LEGO1/lego/sources/roi/legoroi.cpp index 97baaadf..afd5f711 100644 --- a/LEGO1/lego/sources/roi/legoroi.cpp +++ b/LEGO1/lego/sources/roi/legoroi.cpp @@ -259,7 +259,7 @@ LegoResult LegoROI::Read( } if (j == 0) { - if (surplusLODs != 0 && lod->GetUnknown0x08Test8()) { + if (surplusLODs != 0 && lod->IsExtraLOD()) { numLODs++; } } @@ -276,7 +276,7 @@ LegoResult LegoROI::Read( } if (i == 0) { - if (surplusLODs != 0 && lod->GetUnknown0x08Test8()) { + if (surplusLODs != 0 && lod->IsExtraLOD()) { numLODs++; } } diff --git a/LEGO1/viewmanager/viewlod.h b/LEGO1/viewmanager/viewlod.h index 7bf68b52..b7104526 100644 --- a/LEGO1/viewmanager/viewlod.h +++ b/LEGO1/viewmanager/viewlod.h @@ -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 diff --git a/LEGO1/viewmanager/viewmanager.cpp b/LEGO1/viewmanager/viewmanager.cpp index 44635ffd..27919424 100644 --- a/LEGO1/viewmanager/viewmanager.cpp +++ b/LEGO1/viewmanager/viewmanager.cpp @@ -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((Tgl::MeshBuilder*) group); SetAppData(p_roi, reinterpret_cast(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 { From e7c7ecf510a06582316eaf698f63026b04a12eb0 Mon Sep 17 00:00:00 2001 From: Christian Semmler Date: Tue, 1 Jul 2025 23:15:15 -0700 Subject: [PATCH 8/8] Add experimental WebGL support to Emscripten (#440) Co-authored-by: Anders Jenbo --- CMakeLists.txt | 2 +- miniwin/CMakeLists.txt | 6 ++++-- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index f758bd95..3808cbe1 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -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() diff --git a/miniwin/CMakeLists.txt b/miniwin/CMakeLists.txt index 851403cc..c2aa0bd6 100644 --- a/miniwin/CMakeLists.txt +++ b/miniwin/CMakeLists.txt @@ -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()