Handle viewport changes when deserializing save states in libretro builds

This commit is contained in:
刘皓 2025-05-30 18:44:21 -04:00
parent 4202d94b79
commit 755565d3d6
No known key found for this signature in database
GPG key ID: 7901753DB465B711
10 changed files with 66 additions and 19 deletions

View file

@ -224,14 +224,14 @@ bool SceneElement::sandbox_deserialize_scene_element(const void *&data, mkxp_san
uint64_t value = creationStamp; uint64_t value = creationStamp;
if (!mkxp_sandbox::sandbox_deserialize(creationStamp, data, max_size)) return false; if (!mkxp_sandbox::sandbox_deserialize(creationStamp, data, max_size)) return false;
if (creationStamp != value) { if (creationStamp != value) {
deserModified = true; deserSceneElementModified = true;
} }
} }
{ {
int32_t value = (int32_t)z; int32_t value = (int32_t)z;
if (!mkxp_sandbox::sandbox_deserialize((int32_t &)z, data, max_size)) return false; if (!mkxp_sandbox::sandbox_deserialize((int32_t &)z, data, max_size)) return false;
if (z != value) { if (z != value) {
deserModified = true; deserSceneElementModified = true;
} }
} }
if (!mkxp_sandbox::sandbox_deserialize(visible, data, max_size)) return false; 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() void SceneElement::sandbox_deserialize_begin_scene_element()
{ {
deserModified = false; deserSceneElementModified = false;
} }
#endif // MKXPZ_REROO #endif // MKXPZ_REROO

View file

@ -114,7 +114,7 @@ public:
Scene *scene; Scene *scene;
#ifdef MKXPZ_RETRO #ifdef MKXPZ_RETRO
bool deserModified; bool deserSceneElementModified;
#endif // MKXPZ_RETRO #endif // MKXPZ_RETRO
protected: protected:

View file

@ -437,7 +437,7 @@ void Plane::sandbox_deserialize_end()
} }
if (isDisposed()) return; if (isDisposed()) return;
if (deserModified) { if (deserSceneElementModified) {
scene->reinsert(*this); scene->reinsert(*this);
} }
} }

View file

@ -1047,7 +1047,7 @@ void Sprite::sandbox_deserialize_end()
} }
if (isDisposed()) return; if (isDisposed()) return;
if (deserModified) { if (deserSceneElementModified) {
scene->reinsert(*this); scene->reinsert(*this);
} }
} }

View file

@ -1712,11 +1712,11 @@ void Tilemap::sandbox_deserialize_end()
} }
if (isDisposed()) return; if (isDisposed()) return;
if (p->elem.ground->deserModified) { if (p->elem.ground->deserSceneElementModified) {
p->elem.ground->scene->reinsert(*p->elem.ground); p->elem.ground->scene->reinsert(*p->elem.ground);
} }
for (size_t i = 0; i < zlayersMax; ++i) { 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]); p->elem.zlayers[i]->scene->reinsert(*p->elem.zlayers[i]);
} }
} }

View file

@ -792,10 +792,10 @@ void TilemapVX::sandbox_deserialize_end()
} }
if (isDisposed()) return; if (isDisposed()) return;
if (p->above.deserModified) { if (p->above.deserSceneElementModified) {
p->above.scene->reinsert(p->above); p->above.scene->reinsert(p->above);
} }
if (p->deserModified) { if (p->deserSceneElementModified) {
p->scene->reinsert(*p); p->scene->reinsert(*p);
} }
} }

View file

@ -37,6 +37,10 @@
#define GUARD_V(value, expression) do { expression; if (exception.is_error()) return value; } while (0) #define GUARD_V(value, expression) do { expression; if (exception.is_error()) return value; } while (0)
#define GUARD(expression) GUARD_V(, expression) #define GUARD(expression) GUARD_V(, expression)
#ifdef MKXPZ_RETRO
static uint64_t next_id = 1;
#endif // MKXPZ_RETRO
struct ViewportPrivate struct ViewportPrivate
{ {
/* Needed for geometry changes */ /* Needed for geometry changes */
@ -46,6 +50,7 @@ struct ViewportPrivate
sigslot::connection rectCon; sigslot::connection rectCon;
#ifdef MKXPZ_RETRO #ifdef MKXPZ_RETRO
Rect deserSavedRect; Rect deserSavedRect;
bool deserScreenRectChanged;
#endif // MKXPZ_RETRO #endif // MKXPZ_RETRO
Color *color; Color *color;
@ -105,6 +110,9 @@ struct ViewportPrivate
Viewport::Viewport(int x, int y, int width, int height) Viewport::Viewport(int x, int y, int width, int height)
: SceneElement(*shState->screen()), : SceneElement(*shState->screen()),
#ifdef MKXPZ_RETRO
id(next_id++),
#endif // MKXPZ_RETRO
sceneLink(this) sceneLink(this)
{ {
initViewport(x, y, width, height); initViewport(x, y, width, height);
@ -112,6 +120,9 @@ Viewport::Viewport(int x, int y, int width, int height)
Viewport::Viewport(Rect *rect) Viewport::Viewport(Rect *rect)
: SceneElement(*shState->screen()), : SceneElement(*shState->screen()),
#ifdef MKXPZ_RETRO
id(next_id++),
#endif // MKXPZ_RETRO
sceneLink(this) sceneLink(this)
{ {
initViewport(rect->x, rect->y, rect->width, rect->height); initViewport(rect->x, rect->y, rect->width, rect->height);
@ -119,6 +130,9 @@ Viewport::Viewport(Rect *rect)
Viewport::Viewport() Viewport::Viewport()
: SceneElement(*shState->screen()), : SceneElement(*shState->screen()),
#ifdef MKXPZ_RETRO
id(next_id++),
#endif // MKXPZ_RETRO
sceneLink(this) sceneLink(this)
{ {
const Graphics &graphics = shState->graphics(); 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 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->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 (!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->rect, data, max_size)) return false;
if (!mkxp_sandbox::sandbox_serialize(p->color, 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; 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) 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 (!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->rect, data, max_size)) return false;
if (!mkxp_sandbox::sandbox_deserialize(p->color, 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; if (!mkxp_sandbox::sandbox_deserialize(p->tone, data, max_size)) return false;
@ -269,6 +291,8 @@ void Viewport::sandbox_deserialize_begin()
} else { } else {
p->deserSavedRect.set(0, 0, 0, 0); p->deserSavedRect.set(0, 0, 0, 0);
} }
p->deserScreenRectChanged = false;
} }
void Viewport::sandbox_deserialize_end() void Viewport::sandbox_deserialize_end()
@ -282,7 +306,12 @@ void Viewport::sandbox_deserialize_end()
} }
if (isDisposed()) return; if (isDisposed()) return;
if (deserModified) { if (p->deserScreenRectChanged) {
p->recomputeOnScreen();
}
if (isDisposed()) return;
if (deserSceneElementModified) {
scene->reinsert(*this); scene->reinsert(*this);
} }
} }
@ -349,15 +378,28 @@ void ViewportElement::sandbox_deserialize_begin_viewport_element()
sandbox_deserialize_begin_scene_element(); sandbox_deserialize_begin_scene_element();
viewportDispCon.disconnect(); viewportDispCon.disconnect();
deserSavedViewportId = m_viewport == nullptr ? 0 : m_viewport->id;
} }
void ViewportElement::sandbox_deserialize_end_viewport_element() void ViewportElement::sandbox_deserialize_end_viewport_element()
{ {
if (m_viewport != nullptr) { if (m_viewport != nullptr) {
viewportDispCon = m_viewport->wasDisposed.connect(&ViewportElement::viewportElementDisposal, this); if (rgssVer == 1) {
if (m_viewport->isDisposed()) { viewportDispCon = m_viewport->wasDisposed.connect(&ViewportElement::viewportElementDisposal, this);
viewportElementDisposal(); 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 #endif // MXKPZ_RETRO

View file

@ -52,6 +52,8 @@ public:
void initDynAttribs(); void initDynAttribs();
#ifdef MKXPZ_RETRO #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_serialize(void *&data, mkxp_sandbox::wasm_size_t &max_size) const;
bool sandbox_deserialize(const void *&data, mkxp_sandbox::wasm_size_t &max_size); bool sandbox_deserialize(const void *&data, mkxp_sandbox::wasm_size_t &max_size);
void sandbox_deserialize_begin(); void sandbox_deserialize_begin();
@ -100,6 +102,9 @@ private:
void (*m_dispose)(void *); void (*m_dispose)(void *);
Viewport *m_viewport; Viewport *m_viewport;
sigslot::connection viewportDispCon; sigslot::connection viewportDispCon;
#ifdef MKXPZ_RETRO
uint64_t deserSavedViewportId;
#endif // MKXPZ_RETRO
void viewportElementDisposal(); void viewportElementDisposal();
}; };

View file

@ -1089,7 +1089,7 @@ void Window::sandbox_deserialize_end()
} }
if (isDisposed()) return; if (isDisposed()) return;
if (deserModified) { if (deserSceneElementModified) {
scene->reinsert(*this); scene->reinsert(*this);
} }
} }

View file

@ -1355,7 +1355,7 @@ void WindowVX::sandbox_deserialize_end()
} }
if (isDisposed()) return; if (isDisposed()) return;
if (deserModified) { if (deserSceneElementModified) {
scene->reinsert(*this); scene->reinsert(*this);
} }
} }