diff --git a/src/display/gl/scene.cpp b/src/display/gl/scene.cpp index 483f2203..22b444d7 100644 --- a/src/display/gl/scene.cpp +++ b/src/display/gl/scene.cpp @@ -224,14 +224,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) { - deserModified = true; + deserSceneElementModified = true; } } { int32_t value = (int32_t)z; if (!mkxp_sandbox::sandbox_deserialize((int32_t &)z, data, max_size)) return false; if (z != value) { - deserModified = true; + deserSceneElementModified = true; } } if (!mkxp_sandbox::sandbox_deserialize(visible, data, max_size)) return false; @@ -241,6 +241,6 @@ bool SceneElement::sandbox_deserialize_scene_element(const void *&data, mkxp_san void SceneElement::sandbox_deserialize_begin_scene_element() { - deserModified = false; + deserSceneElementModified = false; } #endif // MKXPZ_REROO diff --git a/src/display/gl/scene.h b/src/display/gl/scene.h index 1ed3834d..00d83e9d 100644 --- a/src/display/gl/scene.h +++ b/src/display/gl/scene.h @@ -114,7 +114,7 @@ public: Scene *scene; #ifdef MKXPZ_RETRO - bool deserModified; + bool deserSceneElementModified; #endif // MKXPZ_RETRO protected: diff --git a/src/display/plane.cpp b/src/display/plane.cpp index 7a4e04f4..f90257bf 100644 --- a/src/display/plane.cpp +++ b/src/display/plane.cpp @@ -437,7 +437,7 @@ void Plane::sandbox_deserialize_end() } if (isDisposed()) return; - if (deserModified) { + if (deserSceneElementModified) { scene->reinsert(*this); } } diff --git a/src/display/sprite.cpp b/src/display/sprite.cpp index 4d5f21a9..f81025b9 100644 --- a/src/display/sprite.cpp +++ b/src/display/sprite.cpp @@ -1047,7 +1047,7 @@ void Sprite::sandbox_deserialize_end() } if (isDisposed()) return; - if (deserModified) { + if (deserSceneElementModified) { scene->reinsert(*this); } } diff --git a/src/display/tilemap.cpp b/src/display/tilemap.cpp index d59e1af3..9e2e67ad 100644 --- a/src/display/tilemap.cpp +++ b/src/display/tilemap.cpp @@ -1712,11 +1712,11 @@ void Tilemap::sandbox_deserialize_end() } if (isDisposed()) return; - if (p->elem.ground->deserModified) { + 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]->deserModified) { + if (p->elem.zlayers[i]->deserSceneElementModified) { p->elem.zlayers[i]->scene->reinsert(*p->elem.zlayers[i]); } } diff --git a/src/display/tilemapvx.cpp b/src/display/tilemapvx.cpp index dc73649f..fa3d408c 100644 --- a/src/display/tilemapvx.cpp +++ b/src/display/tilemapvx.cpp @@ -792,10 +792,10 @@ void TilemapVX::sandbox_deserialize_end() } if (isDisposed()) return; - if (p->above.deserModified) { + if (p->above.deserSceneElementModified) { p->above.scene->reinsert(p->above); } - if (p->deserModified) { + if (p->deserSceneElementModified) { p->scene->reinsert(*p); } } diff --git a/src/display/viewport.cpp b/src/display/viewport.cpp index aed1f15a..f6746727 100644 --- a/src/display/viewport.cpp +++ b/src/display/viewport.cpp @@ -37,6 +37,10 @@ #define GUARD_V(value, expression) do { expression; if (exception.is_error()) return value; } while (0) #define GUARD(expression) GUARD_V(, expression) +#ifdef MKXPZ_RETRO +static uint64_t next_id = 1; +#endif // MKXPZ_RETRO + struct ViewportPrivate { /* Needed for geometry changes */ @@ -46,6 +50,7 @@ struct ViewportPrivate sigslot::connection rectCon; #ifdef MKXPZ_RETRO Rect deserSavedRect; + bool deserScreenRectChanged; #endif // MKXPZ_RETRO Color *color; @@ -105,6 +110,9 @@ struct ViewportPrivate Viewport::Viewport(int x, int y, int width, int height) : SceneElement(*shState->screen()), +#ifdef MKXPZ_RETRO + id(next_id++), +#endif // MKXPZ_RETRO sceneLink(this) { initViewport(x, y, width, height); @@ -112,6 +120,9 @@ Viewport::Viewport(int x, int y, int width, int height) Viewport::Viewport(Rect *rect) : SceneElement(*shState->screen()), +#ifdef MKXPZ_RETRO + id(next_id++), +#endif // MKXPZ_RETRO sceneLink(this) { initViewport(rect->x, rect->y, rect->width, rect->height); @@ -119,6 +130,9 @@ Viewport::Viewport(Rect *rect) Viewport::Viewport() : SceneElement(*shState->screen()), +#ifdef MKXPZ_RETRO + id(next_id++), +#endif // MKXPZ_RETRO sceneLink(this) { const Graphics &graphics = shState->graphics(); @@ -236,8 +250,9 @@ void Viewport::releaseResources() bool Viewport::sandbox_serialize(void *&data, mkxp_sandbox::wasm_size_t &max_size) const { if (!mkxp_sandbox::sandbox_serialize(p->screenRect, data, max_size)) return false; - if (!mkxp_sandbox::sandbox_serialize(p->isOnScreen, data, max_size)) return false; + if (!sandbox_serialize_scene_element(data, max_size)) return false; + if (!mkxp_sandbox::sandbox_serialize(p->rect, data, max_size)) return false; if (!mkxp_sandbox::sandbox_serialize(p->color, data, max_size)) return false; if (!mkxp_sandbox::sandbox_serialize(p->tone, data, max_size)) return false; @@ -247,9 +262,16 @@ bool Viewport::sandbox_serialize(void *&data, mkxp_sandbox::wasm_size_t &max_siz bool Viewport::sandbox_deserialize(const void *&data, mkxp_sandbox::wasm_size_t &max_size) { - if (!mkxp_sandbox::sandbox_deserialize(p->screenRect, data, max_size)) return false; - if (!mkxp_sandbox::sandbox_deserialize(p->isOnScreen, data, max_size)) return false; + { + IntRect value = p->screenRect; + if (!mkxp_sandbox::sandbox_deserialize(p->screenRect, data, max_size)) return false; + if (p->screenRect != value) { + p->deserScreenRectChanged = true; + } + } + if (!sandbox_deserialize_scene_element(data, max_size)) return false; + if (!mkxp_sandbox::sandbox_deserialize(p->rect, data, max_size)) return false; if (!mkxp_sandbox::sandbox_deserialize(p->color, data, max_size)) return false; if (!mkxp_sandbox::sandbox_deserialize(p->tone, data, max_size)) return false; @@ -269,6 +291,8 @@ void Viewport::sandbox_deserialize_begin() } else { p->deserSavedRect.set(0, 0, 0, 0); } + + p->deserScreenRectChanged = false; } void Viewport::sandbox_deserialize_end() @@ -282,7 +306,12 @@ void Viewport::sandbox_deserialize_end() } if (isDisposed()) return; - if (deserModified) { + if (p->deserScreenRectChanged) { + p->recomputeOnScreen(); + } + + if (isDisposed()) return; + if (deserSceneElementModified) { scene->reinsert(*this); } } @@ -349,15 +378,28 @@ void ViewportElement::sandbox_deserialize_begin_viewport_element() sandbox_deserialize_begin_scene_element(); viewportDispCon.disconnect(); + + deserSavedViewportId = m_viewport == nullptr ? 0 : m_viewport->id; } void ViewportElement::sandbox_deserialize_end_viewport_element() { if (m_viewport != nullptr) { - viewportDispCon = m_viewport->wasDisposed.connect(&ViewportElement::viewportElementDisposal, this); - if (m_viewport->isDisposed()) { - viewportElementDisposal(); + if (rgssVer == 1) { + viewportDispCon = m_viewport->wasDisposed.connect(&ViewportElement::viewportElementDisposal, this); + if (m_viewport->isDisposed()) { + viewportElementDisposal(); + } } + if (m_viewport->id != deserSavedViewportId) { + setScene(*m_viewport); + onViewportChange(); + onGeometryChange(scene->getGeometry()); + } + } else if (deserSavedViewportId != 0) { + setScene(*shState->screen()); + onViewportChange(); + onGeometryChange(scene->getGeometry()); } } #endif // MXKPZ_RETRO diff --git a/src/display/viewport.h b/src/display/viewport.h index 7892938d..5fecf508 100644 --- a/src/display/viewport.h +++ b/src/display/viewport.h @@ -52,6 +52,8 @@ public: void initDynAttribs(); #ifdef MKXPZ_RETRO + const uint64_t id; // Globally unique nonzero ID for this viewport, for change detection during save state deserialization + bool sandbox_serialize(void *&data, mkxp_sandbox::wasm_size_t &max_size) const; bool sandbox_deserialize(const void *&data, mkxp_sandbox::wasm_size_t &max_size); void sandbox_deserialize_begin(); @@ -100,6 +102,9 @@ private: void (*m_dispose)(void *); Viewport *m_viewport; sigslot::connection viewportDispCon; +#ifdef MKXPZ_RETRO + uint64_t deserSavedViewportId; +#endif // MKXPZ_RETRO void viewportElementDisposal(); }; diff --git a/src/display/window.cpp b/src/display/window.cpp index 45eb50fd..64930131 100644 --- a/src/display/window.cpp +++ b/src/display/window.cpp @@ -1089,7 +1089,7 @@ void Window::sandbox_deserialize_end() } if (isDisposed()) return; - if (deserModified) { + if (deserSceneElementModified) { scene->reinsert(*this); } } diff --git a/src/display/windowvx.cpp b/src/display/windowvx.cpp index 1062fc3c..0e571df7 100644 --- a/src/display/windowvx.cpp +++ b/src/display/windowvx.cpp @@ -1355,7 +1355,7 @@ void WindowVX::sandbox_deserialize_end() } if (isDisposed()) return; - if (deserModified) { + if (deserSceneElementModified) { scene->reinsert(*this); } }