From da2fe19f44137feb8e06722bccc53110c80a3422 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=88=98=E7=9A=93?= Date: Fri, 30 May 2025 22:57:58 -0400 Subject: [PATCH] Fix bugs in viewport element/scene element deserialization in libretro builds --- src/display/gl/scene.cpp | 24 +++++++++++++++++++++--- src/display/gl/scene.h | 8 +++++--- src/display/plane.cpp | 17 ++++++----------- src/display/sprite.cpp | 5 ----- src/display/tilemap.cpp | 10 ---------- src/display/tilemapvx.cpp | 8 -------- src/display/viewport.cpp | 26 ++++++++++++-------------- src/display/window.cpp | 5 ----- src/display/windowvx.cpp | 5 ----- 9 files changed, 44 insertions(+), 64 deletions(-) diff --git a/src/display/gl/scene.cpp b/src/display/gl/scene.cpp index 22b444d7..872825fe 100644 --- a/src/display/gl/scene.cpp +++ b/src/display/gl/scene.cpp @@ -40,6 +40,9 @@ Scene::~Scene() for (iter = elements.begin(); iter != elements.end(); iter = iter->next) { iter->data->scene = 0; +#ifdef MKXPZ_RETRO + iter->data->deserSceneElementWasUnlinked = true; +#endif // MKXPZ_RETRO } } @@ -82,6 +85,9 @@ void Scene::insertAfter(SceneElement &element, SceneElement &after) void Scene::reinsert(SceneElement &element) { elements.remove(element.link); +#ifdef MKXPZ_RETRO + element.deserSceneElementWasUnlinked = true; +#endif // MKXPZ_RETRO insert(element); } @@ -206,6 +212,10 @@ void SceneElement::unlink() { if (scene) scene->elements.remove(link); + +#ifdef MKXPZ_RETRO + deserSceneElementWasUnlinked = true; +#endif // MKXPZ_RETRO } #ifdef MKXPZ_RETRO @@ -224,14 +234,14 @@ bool SceneElement::sandbox_deserialize_scene_element(const void *&data, mkxp_san uint64_t value = creationStamp; if (!mkxp_sandbox::sandbox_deserialize(creationStamp, data, max_size)) return false; if (creationStamp != value) { - deserSceneElementModified = true; + unlink(); } } { int32_t value = (int32_t)z; if (!mkxp_sandbox::sandbox_deserialize((int32_t &)z, data, max_size)) return false; if (z != value) { - deserSceneElementModified = true; + unlink(); } } if (!mkxp_sandbox::sandbox_deserialize(visible, data, max_size)) return false; @@ -241,6 +251,14 @@ bool SceneElement::sandbox_deserialize_scene_element(const void *&data, mkxp_san void SceneElement::sandbox_deserialize_begin_scene_element() { - deserSceneElementModified = false; + deserSceneElementWasUnlinked = false; +} + +void SceneElement::sandbox_deserialize_end_scene_element() +{ + if (deserSceneElementWasUnlinked && scene != nullptr) { + scene->insert(*this); + onGeometryChange(scene->getGeometry()); + } } #endif // MKXPZ_REROO diff --git a/src/display/gl/scene.h b/src/display/gl/scene.h index 00d83e9d..2adaafca 100644 --- a/src/display/gl/scene.h +++ b/src/display/gl/scene.h @@ -110,12 +110,10 @@ public: bool sandbox_serialize_scene_element(void *&data, mkxp_sandbox::wasm_size_t &max_size) const; bool sandbox_deserialize_scene_element(const void *&data, mkxp_sandbox::wasm_size_t &max_size); void sandbox_deserialize_begin_scene_element(); + void sandbox_deserialize_end_scene_element(); #endif // MKXPZ_REROO Scene *scene; -#ifdef MKXPZ_RETRO - bool deserSceneElementModified; -#endif // MKXPZ_RETRO protected: /* A bit about OpenGL state: @@ -153,6 +151,10 @@ protected: int z; bool visible; +#ifdef MKXPZ_RETRO + bool deserSceneElementWasUnlinked; +#endif // MKXPZ_RETRO + friend class Scene; friend class Viewport; friend struct TilemapPrivate; diff --git a/src/display/plane.cpp b/src/display/plane.cpp index f90257bf..9f3bdc7e 100644 --- a/src/display/plane.cpp +++ b/src/display/plane.cpp @@ -387,16 +387,16 @@ bool Plane::sandbox_deserialize(const void *&data, mkxp_sandbox::wasm_size_t &ma } } { - int32_t value = (int32_t)p->zoomX; - if (!mkxp_sandbox::sandbox_deserialize((int32_t &)p->zoomX, data, max_size)) return false; - if ((int32_t)p->zoomX != value) { + float value = p->zoomX; + if (!mkxp_sandbox::sandbox_deserialize(p->zoomX, data, max_size)) return false; + if (p->zoomX != value) { p->quadSourceDirty = true; } } { - int32_t value = (int32_t)p->zoomY; - if (!mkxp_sandbox::sandbox_deserialize((int32_t &)p->zoomY, data, max_size)) return false; - if ((int32_t)p->zoomY != value) { + float value = p->zoomY; + if (!mkxp_sandbox::sandbox_deserialize(p->zoomY, data, max_size)) return false; + if (p->zoomY != value) { p->quadSourceDirty = true; } } @@ -435,10 +435,5 @@ void Plane::sandbox_deserialize_end() p->bitmapDisposal(); } } - - if (isDisposed()) return; - if (deserSceneElementModified) { - scene->reinsert(*this); - } } #endif // MKXPZ_RETRO diff --git a/src/display/sprite.cpp b/src/display/sprite.cpp index f81025b9..e451e63a 100644 --- a/src/display/sprite.cpp +++ b/src/display/sprite.cpp @@ -1045,10 +1045,5 @@ void Sprite::sandbox_deserialize_end() if (p->deserBushDepthChanged) { p->recomputeBushDepth(); } - - if (isDisposed()) return; - if (deserSceneElementModified) { - scene->reinsert(*this); - } } #endif // MKXPZ_RETRO diff --git a/src/display/tilemap.cpp b/src/display/tilemap.cpp index 9e2e67ad..10bb3d9b 100644 --- a/src/display/tilemap.cpp +++ b/src/display/tilemap.cpp @@ -1710,15 +1710,5 @@ void Tilemap::sandbox_deserialize_end() if (p->flashMap.getData() != nullptr && (p->flashMap.getData()->deserModified || p->flashMap.getData()->id != p->deserSavedDataId)) { p->flashMap.setDirty(); } - - if (isDisposed()) return; - if (p->elem.ground->deserSceneElementModified) { - p->elem.ground->scene->reinsert(*p->elem.ground); - } - for (size_t i = 0; i < zlayersMax; ++i) { - if (p->elem.zlayers[i]->deserSceneElementModified) { - p->elem.zlayers[i]->scene->reinsert(*p->elem.zlayers[i]); - } - } } #endif // MKXPZ_RETRO diff --git a/src/display/tilemapvx.cpp b/src/display/tilemapvx.cpp index fa3d408c..dd565347 100644 --- a/src/display/tilemapvx.cpp +++ b/src/display/tilemapvx.cpp @@ -790,13 +790,5 @@ void TilemapVX::sandbox_deserialize_end() if (p->flashMap.getData() != nullptr && (p->flashMap.getData()->deserModified || p->flashMap.getData()->id != p->deserSavedDataId)) { p->flashMap.setDirty(); } - - if (isDisposed()) return; - if (p->above.deserSceneElementModified) { - p->above.scene->reinsert(p->above); - } - if (p->deserSceneElementModified) { - p->scene->reinsert(*p); - } } #endif // MKXPZ_RETRO diff --git a/src/display/viewport.cpp b/src/display/viewport.cpp index f6746727..5d91ca77 100644 --- a/src/display/viewport.cpp +++ b/src/display/viewport.cpp @@ -297,6 +297,8 @@ void Viewport::sandbox_deserialize_begin() void Viewport::sandbox_deserialize_end() { + sandbox_deserialize_end_scene_element(); + if (isDisposed()) return; if (p->rect != nullptr) { p->rectCon = p->rect->valueChanged.connect(&ViewportPrivate::onRectChange, p); @@ -309,11 +311,6 @@ void Viewport::sandbox_deserialize_end() if (p->deserScreenRectChanged) { p->recomputeOnScreen(); } - - if (isDisposed()) return; - if (deserSceneElementModified) { - scene->reinsert(*this); - } } #endif // MXKPZ_RETRO @@ -391,15 +388,16 @@ void ViewportElement::sandbox_deserialize_end_viewport_element() viewportElementDisposal(); } } - if (m_viewport->id != deserSavedViewportId) { - setScene(*m_viewport); - onViewportChange(); - onGeometryChange(scene->getGeometry()); - } - } else if (deserSavedViewportId != 0) { - setScene(*shState->screen()); - onViewportChange(); - onGeometryChange(scene->getGeometry()); } + + if ((m_viewport != nullptr && m_viewport->id != deserSavedViewportId) || (m_viewport == nullptr && deserSavedViewportId != 0)) { + if (!deserSceneElementWasUnlinked) { + unlink(); + } + scene = m_viewport == nullptr ? shState->screen() : m_viewport; + onViewportChange(); + } + + sandbox_deserialize_end_scene_element(); } #endif // MXKPZ_RETRO diff --git a/src/display/window.cpp b/src/display/window.cpp index 64930131..3f9cfc2b 100644 --- a/src/display/window.cpp +++ b/src/display/window.cpp @@ -1087,10 +1087,5 @@ void Window::sandbox_deserialize_end() p->markControlVertDirty(); } } - - if (isDisposed()) return; - if (deserSceneElementModified) { - scene->reinsert(*this); - } } #endif // MKXPZ_RETRO diff --git a/src/display/windowvx.cpp b/src/display/windowvx.cpp index 0e571df7..8f23ad5d 100644 --- a/src/display/windowvx.cpp +++ b/src/display/windowvx.cpp @@ -1353,10 +1353,5 @@ void WindowVX::sandbox_deserialize_end() p->invalidateBaseTex(); } } - - if (isDisposed()) return; - if (deserSceneElementModified) { - scene->reinsert(*this); - } } #endif // MKXPZ_RETRO