Fix some more bugs in libretro save state serialization/deserialization

This commit is contained in:
刘皓 2025-05-31 10:47:47 -04:00
parent 7f3e02ceec
commit 2ee1b61670
No known key found for this signature in database
GPG key ID: 7901753DB465B711
12 changed files with 79 additions and 128 deletions

View file

@ -22,6 +22,7 @@
#include "binding-sandbox.h" #include "binding-sandbox.h"
#include <zlib.h> #include <zlib.h>
#include "sharedstate.h" #include "sharedstate.h"
#include "core.h"
#include "audio-binding.h" #include "audio-binding.h"
#include "bitmap-binding.h" #include "bitmap-binding.h"
#include "etc-binding.h" #include "etc-binding.h"

View file

@ -20,6 +20,7 @@
*/ */
#include "binding-util.h" #include "binding-util.h"
#include "core.h"
#include "sharedstate.h" #include "sharedstate.h"
using namespace mkxp_sandbox; using namespace mkxp_sandbox;

View file

@ -20,6 +20,8 @@
*/ */
#include "input-binding.h" #include "input-binding.h"
#include "input.h"
#include "core.h"
#include "sharedstate.h" #include "sharedstate.h"
using namespace mkxp_sandbox; using namespace mkxp_sandbox;

View file

@ -21,10 +21,8 @@
#include "sandbox-serial-util.h" #include "sandbox-serial-util.h"
#include "etc-internal.h" #include "etc-internal.h"
#include "quad.h"
#include "scene.h" #include "scene.h"
#include "transform.h" #include "transform.h"
#include "vertex.h"
using namespace mkxp_sandbox; using namespace mkxp_sandbox;
@ -356,6 +354,8 @@ template <> bool mkxp_sandbox::sandbox_serialize(const NormValue &value, void *&
template <> bool mkxp_sandbox::sandbox_deserialize(NormValue &value, const void *&data, wasm_size_t &max_size) { template <> bool mkxp_sandbox::sandbox_deserialize(NormValue &value, const void *&data, wasm_size_t &max_size) {
if (!sandbox_deserialize((int32_t &)value.unNorm, data, max_size)) return false; if (!sandbox_deserialize((int32_t &)value.unNorm, data, max_size)) return false;
value.unNorm = clamp(value.unNorm, 0, 255);
value.norm = value.unNorm / 255.0f;
return true; return true;
} }
@ -427,84 +427,6 @@ template <> bool mkxp_sandbox::sandbox_deserialize(Scene::Geometry &value, const
return true; return true;
} }
template <> bool mkxp_sandbox::sandbox_serialize(const SVertex &value, void *&data, wasm_size_t &max_size) {
if (!sandbox_serialize(value.pos, data, max_size)) return false;
if (!sandbox_serialize(value.texPos, data, max_size)) return false;
return true;
}
template <> bool mkxp_sandbox::sandbox_deserialize(SVertex &value, const void *&data, wasm_size_t &max_size) {
if (!sandbox_deserialize(value.pos, data, max_size)) return false;
if (!sandbox_deserialize(value.texPos, data, max_size)) return false;
return true;
}
template <> bool mkxp_sandbox::sandbox_serialize(const CVertex &value, void *&data, wasm_size_t &max_size) {
if (!sandbox_serialize(value.pos, data, max_size)) return false;
if (!sandbox_serialize(value.color, data, max_size)) return false;
return true;
}
template <> bool mkxp_sandbox::sandbox_deserialize(CVertex &value, const void *&data, wasm_size_t &max_size) {
if (!sandbox_deserialize(value.pos, data, max_size)) return false;
if (!sandbox_deserialize(value.color, data, max_size)) return false;
return true;
}
template <> bool mkxp_sandbox::sandbox_serialize(const Vertex &value, void *&data, wasm_size_t &max_size) {
if (!sandbox_serialize(value.pos, data, max_size)) return false;
if (!sandbox_serialize(value.texPos, data, max_size)) return false;
if (!sandbox_serialize(value.color, data, max_size)) return false;
return true;
}
template <> bool mkxp_sandbox::sandbox_deserialize(Vertex &value, const void *&data, wasm_size_t &max_size) {
if (!sandbox_deserialize(value.pos, data, max_size)) return false;
if (!sandbox_deserialize(value.texPos, data, max_size)) return false;
if (!sandbox_deserialize(value.color, data, max_size)) return false;
return true;
}
template <> bool mkxp_sandbox::sandbox_serialize(const Quad &value, void *&data, wasm_size_t &max_size) {
if (!sandbox_serialize(value.vert[0], data, max_size)) return false;
if (!sandbox_serialize(value.vert[1], data, max_size)) return false;
if (!sandbox_serialize(value.vert[2], data, max_size)) return false;
if (!sandbox_serialize(value.vert[3], data, max_size)) return false;
return true;
}
template <> bool mkxp_sandbox::sandbox_deserialize(Quad &value, const void *&data, wasm_size_t &max_size) {
{
Vertex old_vert = value.vert[0];
if (!sandbox_deserialize(value.vert[0], data, max_size)) return false;
if (value.vert[0].pos != old_vert.pos || value.vert[0].texPos != old_vert.texPos || value.vert[0].color != old_vert.color) {
value.vboDirty = true;
}
}
{
Vertex old_vert = value.vert[1];
if (!sandbox_deserialize(value.vert[1], data, max_size)) return false;
if (value.vert[1].pos != old_vert.pos || value.vert[1].texPos != old_vert.texPos || value.vert[1].color != old_vert.color) {
value.vboDirty = true;
}
}
{
Vertex old_vert = value.vert[2];
if (!sandbox_deserialize(value.vert[2], data, max_size)) return false;
if (value.vert[2].pos != old_vert.pos || value.vert[2].texPos != old_vert.texPos || value.vert[2].color != old_vert.color) {
value.vboDirty = true;
}
}
{
Vertex old_vert = value.vert[3];
if (!sandbox_deserialize(value.vert[3], data, max_size)) return false;
if (value.vert[3].pos != old_vert.pos || value.vert[3].texPos != old_vert.texPos || value.vert[3].color != old_vert.color) {
value.vboDirty = true;
}
}
return true;
}
template <> bool mkxp_sandbox::sandbox_serialize(const Transform &value, void *&data, wasm_size_t &max_size) { template <> bool mkxp_sandbox::sandbox_serialize(const Transform &value, void *&data, wasm_size_t &max_size) {
if (!sandbox_serialize(value.getPosition(), data, max_size)) return false; if (!sandbox_serialize(value.getPosition(), data, max_size)) return false;
if (!sandbox_serialize(value.getOrigin(), data, max_size)) return false; if (!sandbox_serialize(value.getOrigin(), data, max_size)) return false;

View file

@ -31,11 +31,12 @@
#include <boost/preprocessor/seq/size.hpp> #include <boost/preprocessor/seq/size.hpp>
#include <boost/type_traits/is_detected.hpp> #include <boost/type_traits/is_detected.hpp>
#include "sandbox.h"
#include "bitmap.h" #include "bitmap.h"
#include "etc.h" #include "etc.h"
#include "font.h" #include "font.h"
#include "plane.h" #include "plane.h"
#include "quadarray.h"
#include "sprite.h" #include "sprite.h"
#include "table.h" #include "table.h"
#include "tilemap.h" #include "tilemap.h"
@ -127,7 +128,6 @@ namespace mkxp_sandbox {
template <typename T> typename std::enable_if<std::is_enum<T>::value, bool>::type sandbox_serialize(T value, void *&data, wasm_size_t &max_size); template <typename T> typename std::enable_if<std::is_enum<T>::value, bool>::type sandbox_serialize(T value, void *&data, wasm_size_t &max_size);
template <typename T> typename std::enable_if<!std::is_same<T, bool>::value && !std::is_enum<T>::value && std::is_arithmetic<T>::value, bool>::type sandbox_serialize(T value, void *&data, wasm_size_t &max_size); template <typename T> typename std::enable_if<!std::is_same<T, bool>::value && !std::is_enum<T>::value && std::is_arithmetic<T>::value, bool>::type sandbox_serialize(T value, void *&data, wasm_size_t &max_size);
template <typename T> bool sandbox_serialize(const std::vector<T> &value, void *&data, wasm_size_t &max_size); template <typename T> bool sandbox_serialize(const std::vector<T> &value, void *&data, wasm_size_t &max_size);
template <typename T> bool sandbox_serialize(const QuadArray<T> &value, void *&data, wasm_size_t &max_size);
template <typename T> typename std::enable_if<std::is_same<T, char>::value, bool>::type sandbox_serialize(const T *value, void *&data, wasm_size_t &max_size); template <typename T> typename std::enable_if<std::is_same<T, char>::value, bool>::type sandbox_serialize(const T *value, void *&data, wasm_size_t &max_size);
template <typename T> typename std::enable_if<std::is_class<T>::value, bool>::type sandbox_serialize(const T *value, void *&data, wasm_size_t &max_size); template <typename T> typename std::enable_if<std::is_class<T>::value, bool>::type sandbox_serialize(const T *value, void *&data, wasm_size_t &max_size);
template <typename T> typename std::enable_if<std::is_class<T>::value && boost::is_detected<sandbox_serialize_member_declaration, T>::value, bool>::type sandbox_serialize(const T &value, void *&data, wasm_size_t &max_size); template <typename T> typename std::enable_if<std::is_class<T>::value && boost::is_detected<sandbox_serialize_member_declaration, T>::value, bool>::type sandbox_serialize(const T &value, void *&data, wasm_size_t &max_size);
@ -137,7 +137,6 @@ namespace mkxp_sandbox {
template <typename T> typename std::enable_if<!std::is_const<T>::value && std::is_enum<T>::value, bool>::type sandbox_deserialize(T &value, const void *&data, wasm_size_t &max_size); template <typename T> typename std::enable_if<!std::is_const<T>::value && std::is_enum<T>::value, bool>::type sandbox_deserialize(T &value, const void *&data, wasm_size_t &max_size);
template <typename T> typename std::enable_if<!std::is_const<T>::value && !std::is_same<T, bool>::value && !std::is_enum<T>::value && std::is_arithmetic<T>::value, bool>::type sandbox_deserialize(T &value, const void *&data, wasm_size_t &max_size); template <typename T> typename std::enable_if<!std::is_const<T>::value && !std::is_same<T, bool>::value && !std::is_enum<T>::value && std::is_arithmetic<T>::value, bool>::type sandbox_deserialize(T &value, const void *&data, wasm_size_t &max_size);
template <typename T> typename std::enable_if<!std::is_const<T>::value, bool>::type sandbox_deserialize(std::vector<T> &value, const void *&data, wasm_size_t &max_size); template <typename T> typename std::enable_if<!std::is_const<T>::value, bool>::type sandbox_deserialize(std::vector<T> &value, const void *&data, wasm_size_t &max_size);
template <typename T> typename std::enable_if<!std::is_const<T>::value, bool>::type sandbox_deserialize(QuadArray<T> &value, const void *&data, wasm_size_t &max_size);
template <typename T> typename std::enable_if<!std::is_const<T>::value && std::is_class<T>::value, bool>::type sandbox_deserialize(T *&value, const void *&data, wasm_size_t &max_size); template <typename T> typename std::enable_if<!std::is_const<T>::value && std::is_class<T>::value, bool>::type sandbox_deserialize(T *&value, const void *&data, wasm_size_t &max_size);
template <typename T> typename std::enable_if<!std::is_const<T>::value && std::is_class<T>::value && boost::is_detected<sandbox_deserialize_member_declaration, T>::value, bool>::type sandbox_deserialize(T &value, const void *&data, wasm_size_t &max_size); template <typename T> typename std::enable_if<!std::is_const<T>::value && std::is_class<T>::value && boost::is_detected<sandbox_deserialize_member_declaration, T>::value, bool>::type sandbox_deserialize(T &value, const void *&data, wasm_size_t &max_size);
template <typename T> typename std::enable_if<!std::is_const<T>::value && std::is_class<T>::value && !boost::is_detected<sandbox_deserialize_member_declaration, T>::value, bool>::type sandbox_deserialize(T &value, const void *&data, wasm_size_t &max_size); template <typename T> typename std::enable_if<!std::is_const<T>::value && std::is_class<T>::value && !boost::is_detected<sandbox_deserialize_member_declaration, T>::value, bool>::type sandbox_deserialize(T &value, const void *&data, wasm_size_t &max_size);
@ -313,16 +312,6 @@ namespace mkxp_sandbox {
return true; return true;
} }
template <typename T> bool sandbox_serialize(const QuadArray<T> &value, void *&data, wasm_size_t &max_size) {
return sandbox_serialize(value.vertices, data, max_size);
}
template <typename T> typename std::enable_if<!std::is_const<T>::value, bool>::type sandbox_deserialize(QuadArray<T> &value, const void *&data, wasm_size_t &max_size) {
if (!sandbox_deserialize(value.vertices, data, max_size)) return false;
value.quadCount = value.vertices.size() / 4;
return true;
}
template <typename T> typename std::enable_if<std::is_enum<T>::value, bool>::type sandbox_serialize(T value, void *&data, wasm_size_t &max_size) { template <typename T> typename std::enable_if<std::is_enum<T>::value, bool>::type sandbox_serialize(T value, void *&data, wasm_size_t &max_size) {
return sandbox_serialize((int32_t)value, data, max_size); return sandbox_serialize((int32_t)value, data, max_size);
} }

View file

@ -3454,6 +3454,7 @@ bool Bitmap::sandbox_deserialize(const void *&data, mkxp_sandbox::wasm_size_t &m
if (!mkxp_sandbox::sandbox_deserialize((int32_t &)p->gl.width, data, max_size)) return false; if (!mkxp_sandbox::sandbox_deserialize((int32_t &)p->gl.width, data, max_size)) return false;
if (p->gl.width != old_width) { if (p->gl.width != old_width) {
deserModified = true; deserModified = true;
deserSizeChanged = true;
} }
} }
{ {
@ -3461,6 +3462,7 @@ bool Bitmap::sandbox_deserialize(const void *&data, mkxp_sandbox::wasm_size_t &m
if (!mkxp_sandbox::sandbox_deserialize((int32_t &)p->gl.height, data, max_size)) return false; if (!mkxp_sandbox::sandbox_deserialize((int32_t &)p->gl.height, data, max_size)) return false;
if (p->gl.height != old_height) { if (p->gl.height != old_height) {
deserModified = true; deserModified = true;
deserSizeChanged = true;
} }
} }
{ {
@ -3503,6 +3505,8 @@ void Bitmap::sandbox_deserialize_begin(bool is_new)
loresDispCon.disconnect(); loresDispCon.disconnect();
deserModified = is_new; deserModified = is_new;
deserSizeChanged = is_new;
} }
void Bitmap::sandbox_deserialize_end() void Bitmap::sandbox_deserialize_end()

View file

@ -194,6 +194,7 @@ public:
#ifdef MKXPZ_RETRO #ifdef MKXPZ_RETRO
const uint64_t id; // Globally unique nonzero ID for this bitmap, for change detection during save state deserialization const uint64_t id; // Globally unique nonzero ID for this bitmap, for change detection during save state deserialization
bool deserModified; bool deserModified;
bool deserSizeChanged;
#endif // MKXPZ_RETRO #endif // MKXPZ_RETRO
static int maxSize(); static int maxSize();

View file

@ -62,7 +62,6 @@ struct SpritePrivate
Rect *srcRect; Rect *srcRect;
sigslot::connection srcRectCon; sigslot::connection srcRectCon;
#ifdef MKXPZ_RETRO #ifdef MKXPZ_RETRO
uint64_t deserSavedBitmapId;
Rect deserSavedSrcRect; Rect deserSavedSrcRect;
bool deserMirrorChanged; bool deserMirrorChanged;
bool deserYChanged; bool deserYChanged;
@ -992,8 +991,6 @@ void Sprite::sandbox_deserialize_begin()
p->bitmapDispCon.disconnect(); p->bitmapDispCon.disconnect();
p->deserSavedBitmapId = p->bitmap == nullptr ? 0 : p->bitmap->id;
p->srcRectCon.disconnect(); p->srcRectCon.disconnect();
if (p->srcRect != nullptr) { if (p->srcRect != nullptr) {
p->deserSavedSrcRect = *p->srcRect; p->deserSavedSrcRect = *p->srcRect;
@ -1018,11 +1015,6 @@ void Sprite::sandbox_deserialize_end()
} }
} }
if (isDisposed()) return;
if (p->bitmap != nullptr && (p->bitmap->deserModified || p->bitmap->id != p->deserSavedBitmapId)) {
p->wave.dirty = true;
}
if (isDisposed()) return; if (isDisposed()) return;
if (p->srcRect != nullptr) { if (p->srcRect != nullptr) {
p->srcRectCon = p->srcRect->valueChanged.connect(&SpritePrivate::onSrcRectChange, p); p->srcRectCon = p->srcRect->valueChanged.connect(&SpritePrivate::onSrcRectChange, p);

View file

@ -1552,6 +1552,7 @@ bool Tilemap::sandbox_deserialize(const void *&data, mkxp_sandbox::wasm_size_t &
if (!mkxp_sandbox::sandbox_deserialize(p->tiles.aniIdx, data, max_size)) return false; if (!mkxp_sandbox::sandbox_deserialize(p->tiles.aniIdx, data, max_size)) return false;
if (!mkxp_sandbox::sandbox_deserialize(p->flashAlphaIdx, data, max_size)) return false; if (!mkxp_sandbox::sandbox_deserialize(p->flashAlphaIdx, data, max_size)) return false;
p->flashAlphaIdx %= flashAlphaN;
if (!p->elem.ground->sandbox_deserialize_viewport_element(data, max_size)) return false; if (!p->elem.ground->sandbox_deserialize_viewport_element(data, max_size)) return false;
@ -1645,10 +1646,12 @@ void Tilemap::sandbox_deserialize_end()
} }
if (isDisposed()) return; if (isDisposed()) return;
if (p->tileset != nullptr && !p->tileset->isDisposed()) { if (p->tileset != nullptr) {
p->tilesetCon = p->tileset->modified.connect(&TilemapPrivate::invalidateAtlasSize, p); p->tilesetCon = p->tileset->modified.connect(&TilemapPrivate::invalidateAtlasSize, p);
if (p->tileset->deserModified || p->tileset->id != p->deserSavedTilesetId) { if (p->tileset->deserModified || p->tileset->id != p->deserSavedTilesetId) {
p->invalidateAtlasSize(); p->invalidateAtlasSize();
Exception e;
p->updateAtlasInfo(e);
} }
} }
@ -1658,7 +1661,10 @@ void Tilemap::sandbox_deserialize_end()
p->autotilesCon[i] = p->autotiles[i]->modified.connect(&TilemapPrivate::invalidateAtlasContents, p); p->autotilesCon[i] = p->autotiles[i]->modified.connect(&TilemapPrivate::invalidateAtlasContents, p);
if (p->autotiles[i]->deserModified || p->autotiles[i]->id != p->deserSavedAutotileIds[i]) { if (p->autotiles[i]->deserModified || p->autotiles[i]->id != p->deserSavedAutotileIds[i]) {
p->invalidateAtlasContents(); p->invalidateAtlasContents();
p->updateAutotileInfo();
} }
} else if (p->deserSavedAutotileIds[i] != 0) {
p->invalidateAtlasContents();
} }
} }

View file

@ -680,7 +680,9 @@ bool TilemapVX::sandbox_deserialize(const void *&data, mkxp_sandbox::wasm_size_t
} }
} }
if (!mkxp_sandbox::sandbox_deserialize(p->frameIdx, data, max_size)) return false; if (!mkxp_sandbox::sandbox_deserialize(p->frameIdx, data, max_size)) return false;
p->frameIdx %= 30*3*4;
if (!mkxp_sandbox::sandbox_deserialize(p->flashAlphaIdx, data, max_size)) return false; if (!mkxp_sandbox::sandbox_deserialize(p->flashAlphaIdx, data, max_size)) return false;
p->flashAlphaIdx %= flashAlphaN;
if (!p->above.sandbox_deserialize_viewport_element(data, max_size)) return false; if (!p->above.sandbox_deserialize_viewport_element(data, max_size)) return false;
if (!p->sandbox_deserialize_viewport_element(data, max_size)) return false; if (!p->sandbox_deserialize_viewport_element(data, max_size)) return false;

View file

@ -189,6 +189,7 @@ struct WindowPrivate
sigslot::connection cursorRectCon; sigslot::connection cursorRectCon;
#ifdef MKXPZ_RETRO #ifdef MKXPZ_RETRO
uint64_t deserSavedContentsId;
Rect deserSavedCursorRect; Rect deserSavedCursorRect;
#endif // MKXPZ_RETRO #endif // MKXPZ_RETRO
@ -966,12 +967,7 @@ bool Window::sandbox_serialize(void *&data, mkxp_sandbox::wasm_size_t &max_size)
if (!mkxp_sandbox::sandbox_serialize(p->opacity, data, max_size)) return false; if (!mkxp_sandbox::sandbox_serialize(p->opacity, data, max_size)) return false;
if (!mkxp_sandbox::sandbox_serialize(p->backOpacity, data, max_size)) return false; if (!mkxp_sandbox::sandbox_serialize(p->backOpacity, data, max_size)) return false;
if (!mkxp_sandbox::sandbox_serialize(p->contentsOpacity, data, max_size)) return false; if (!mkxp_sandbox::sandbox_serialize(p->contentsOpacity, data, max_size)) return false;
if (!mkxp_sandbox::sandbox_serialize(p->baseQuadArray, data, max_size)) return false;
if (!mkxp_sandbox::sandbox_serialize(p->useBaseTex, data, max_size)) return false;
if (!mkxp_sandbox::sandbox_serialize(p->baseTexQuad, data, max_size)) return false;
if (!p->controlsElement.sandbox_serialize_viewport_element(data, max_size)) return false; if (!p->controlsElement.sandbox_serialize_viewport_element(data, max_size)) return false;
if (!mkxp_sandbox::sandbox_serialize(p->controlsQuadArray, data, max_size)) return false;
if (!mkxp_sandbox::sandbox_serialize(p->contentsQuad, data, max_size)) return false;
if (!mkxp_sandbox::sandbox_serialize(p->cursorAniAlphaIdx, data, max_size)) return false; if (!mkxp_sandbox::sandbox_serialize(p->cursorAniAlphaIdx, data, max_size)) return false;
if (!mkxp_sandbox::sandbox_serialize(p->pauseAniAlphaIdx, data, max_size)) return false; if (!mkxp_sandbox::sandbox_serialize(p->pauseAniAlphaIdx, data, max_size)) return false;
if (!mkxp_sandbox::sandbox_serialize(p->pauseAniQuadIdx, data, max_size)) return false; if (!mkxp_sandbox::sandbox_serialize(p->pauseAniQuadIdx, data, max_size)) return false;
@ -993,7 +989,13 @@ bool Window::sandbox_deserialize(const void *&data, mkxp_sandbox::wasm_size_t &m
} }
} }
if (!mkxp_sandbox::sandbox_deserialize(p->active, data, max_size)) return false; if (!mkxp_sandbox::sandbox_deserialize(p->active, data, max_size)) return false;
{
bool value = p->pause;
if (!mkxp_sandbox::sandbox_deserialize(p->pause, data, max_size)) return false; if (!mkxp_sandbox::sandbox_deserialize(p->pause, data, max_size)) return false;
if (p->pause != value) {
p->controlsVertDirty = true;
}
}
if (!mkxp_sandbox::sandbox_deserialize(p->sceneOffset, data, max_size)) return false; if (!mkxp_sandbox::sandbox_deserialize(p->sceneOffset, data, max_size)) return false;
if (!mkxp_sandbox::sandbox_deserialize(p->position, data, max_size)) return false; if (!mkxp_sandbox::sandbox_deserialize(p->position, data, max_size)) return false;
{ {
@ -1024,16 +1026,20 @@ bool Window::sandbox_deserialize(const void *&data, mkxp_sandbox::wasm_size_t &m
p->opacityDirty = true; p->opacityDirty = true;
} }
} }
{
NormValue value = p->contentsOpacity;
if (!mkxp_sandbox::sandbox_deserialize(p->contentsOpacity, data, max_size)) return false; if (!mkxp_sandbox::sandbox_deserialize(p->contentsOpacity, data, max_size)) return false;
if (!mkxp_sandbox::sandbox_deserialize(p->baseQuadArray, data, max_size)) return false; if (value != p->contentsOpacity) {
if (!mkxp_sandbox::sandbox_deserialize(p->useBaseTex, data, max_size)) return false; p->contentsQuad.setColor(Vec4(1, 1, 1, p->contentsOpacity.norm));
if (!mkxp_sandbox::sandbox_deserialize(p->baseTexQuad, data, max_size)) return false; }
}
if (!p->controlsElement.sandbox_deserialize_viewport_element(data, max_size)) return false; if (!p->controlsElement.sandbox_deserialize_viewport_element(data, max_size)) return false;
if (!mkxp_sandbox::sandbox_deserialize(p->controlsQuadArray, data, max_size)) return false;
if (!mkxp_sandbox::sandbox_deserialize(p->contentsQuad, data, max_size)) return false;
if (!mkxp_sandbox::sandbox_deserialize(p->cursorAniAlphaIdx, data, max_size)) return false; if (!mkxp_sandbox::sandbox_deserialize(p->cursorAniAlphaIdx, data, max_size)) return false;
p->cursorAniAlphaIdx %= cursorAniAlphaN;
if (!mkxp_sandbox::sandbox_deserialize(p->pauseAniAlphaIdx, data, max_size)) return false; if (!mkxp_sandbox::sandbox_deserialize(p->pauseAniAlphaIdx, data, max_size)) return false;
p->pauseAniAlphaIdx = std::min(p->pauseAniAlphaIdx, (uint8_t)(pauseAniAlphaN - 1));
if (!mkxp_sandbox::sandbox_deserialize(p->pauseAniQuadIdx, data, max_size)) return false; if (!mkxp_sandbox::sandbox_deserialize(p->pauseAniQuadIdx, data, max_size)) return false;
p->pauseAniQuadIdx %= pauseAniQuadN;
if (!sandbox_deserialize_viewport_element(data, max_size)) return false; if (!sandbox_deserialize_viewport_element(data, max_size)) return false;
if (!mkxp_sandbox::sandbox_deserialize(p->windowskin, data, max_size)) return false; if (!mkxp_sandbox::sandbox_deserialize(p->windowskin, data, max_size)) return false;
if (!mkxp_sandbox::sandbox_deserialize(p->contents, data, max_size)) return false; if (!mkxp_sandbox::sandbox_deserialize(p->contents, data, max_size)) return false;
@ -1052,6 +1058,8 @@ void Window::sandbox_deserialize_begin()
p->contentsDispCon.disconnect(); p->contentsDispCon.disconnect();
p->deserSavedContentsId = p->contents == nullptr ? 0 : p->contents->id;
p->cursorRectCon.disconnect(); p->cursorRectCon.disconnect();
if (p->cursorRect != nullptr) { if (p->cursorRect != nullptr) {
p->deserSavedCursorRect = *p->cursorRect; p->deserSavedCursorRect = *p->cursorRect;
@ -1080,6 +1088,11 @@ void Window::sandbox_deserialize_end()
} }
} }
if (isDisposed()) return;
if (p->contents != nullptr && (p->contents->deserSizeChanged || p->contents->id != p->deserSavedContentsId)) {
p->contentsQuad.setTexPosRect(p->contents->rect(), p->contents->rect());
}
if (isDisposed()) return; if (isDisposed()) return;
if (p->cursorRect != nullptr) { if (p->cursorRect != nullptr) {
p->cursorRectCon = p->cursorRect->valueChanged.connect(&WindowPrivate::markControlVertDirty, p); p->cursorRectCon = p->cursorRect->valueChanged.connect(&WindowPrivate::markControlVertDirty, p);

View file

@ -1187,11 +1187,6 @@ bool WindowVX::sandbox_serialize(void *&data, mkxp_sandbox::wasm_size_t &max_siz
if (!mkxp_sandbox::sandbox_serialize(p->backOpacity, data, max_size)) return false; if (!mkxp_sandbox::sandbox_serialize(p->backOpacity, data, max_size)) return false;
if (!mkxp_sandbox::sandbox_serialize(p->contentsOpacity, data, max_size)) return false; if (!mkxp_sandbox::sandbox_serialize(p->contentsOpacity, data, max_size)) return false;
if (!mkxp_sandbox::sandbox_serialize(p->openness, data, max_size)) return false; if (!mkxp_sandbox::sandbox_serialize(p->openness, data, max_size)) return false;
if (!mkxp_sandbox::sandbox_serialize(p->ctrlVert, data, max_size)) return false;
if (!mkxp_sandbox::sandbox_serialize(p->contentsQuad, data, max_size)) return false;
if (!mkxp_sandbox::sandbox_serialize(p->padRect, data, max_size)) return false;
if (!mkxp_sandbox::sandbox_serialize(p->clipRect, data, max_size)) return false;
if (!mkxp_sandbox::sandbox_serialize(p->cursorVert, data, max_size)) return false;
if (!mkxp_sandbox::sandbox_serialize(p->pauseAlphaIdx, data, max_size)) return false; if (!mkxp_sandbox::sandbox_serialize(p->pauseAlphaIdx, data, max_size)) return false;
if (!mkxp_sandbox::sandbox_serialize(p->pauseQuadIdx, data, max_size)) return false; if (!mkxp_sandbox::sandbox_serialize(p->pauseQuadIdx, data, max_size)) return false;
if (!mkxp_sandbox::sandbox_serialize(p->cursorAlphaIdx, data, max_size)) return false; if (!mkxp_sandbox::sandbox_serialize(p->cursorAlphaIdx, data, max_size)) return false;
@ -1236,7 +1231,13 @@ bool WindowVX::sandbox_deserialize(const void *&data, mkxp_sandbox::wasm_size_t
p->width = p->geo.w; p->width = p->geo.w;
p->height = p->geo.h; p->height = p->geo.h;
} }
{
Vec2i value = p->contentsOff;
if (!mkxp_sandbox::sandbox_deserialize(p->contentsOff, data, max_size)) return false; if (!mkxp_sandbox::sandbox_deserialize(p->contentsOff, data, max_size)) return false;
if (p->contentsOff != value) {
p->ctrlVertDirty = true;
}
}
{ {
int32_t value = (int32_t)p->padding; int32_t value = (int32_t)p->padding;
if (!mkxp_sandbox::sandbox_deserialize((int32_t &)p->padding, data, max_size)) return false; if (!mkxp_sandbox::sandbox_deserialize((int32_t &)p->padding, data, max_size)) return false;
@ -1251,7 +1252,13 @@ bool WindowVX::sandbox_deserialize(const void *&data, mkxp_sandbox::wasm_size_t
p->clipRectDirty = true; p->clipRectDirty = true;
} }
} }
{
NormValue value = p->opacity;
if (!mkxp_sandbox::sandbox_deserialize(p->opacity, data, max_size)) return false; if (!mkxp_sandbox::sandbox_deserialize(p->opacity, data, max_size)) return false;
if (p->opacity != value) {
p->base.quad.setColor(Vec4(1, 1, 1, p->opacity.norm));
}
}
{ {
NormValue value = p->backOpacity; NormValue value = p->backOpacity;
if (!mkxp_sandbox::sandbox_deserialize(p->backOpacity, data, max_size)) return false; if (!mkxp_sandbox::sandbox_deserialize(p->backOpacity, data, max_size)) return false;
@ -1259,16 +1266,26 @@ bool WindowVX::sandbox_deserialize(const void *&data, mkxp_sandbox::wasm_size_t
p->base.texDirty = true; p->base.texDirty = true;
} }
} }
{
NormValue value = p->contentsOpacity;
if (!mkxp_sandbox::sandbox_deserialize(p->contentsOpacity, data, max_size)) return false; if (!mkxp_sandbox::sandbox_deserialize(p->contentsOpacity, data, max_size)) return false;
if (p->contentsOpacity != value) {
p->contentsQuad.setColor(Vec4(1, 1, 1, p->contentsOpacity.norm));
}
}
{
NormValue value = p->openness;
if (!mkxp_sandbox::sandbox_deserialize(p->openness, data, max_size)) return false; if (!mkxp_sandbox::sandbox_deserialize(p->openness, data, max_size)) return false;
if (!mkxp_sandbox::sandbox_deserialize(p->ctrlVert, data, max_size)) return false; if (p->openness != value) {
if (!mkxp_sandbox::sandbox_deserialize(p->contentsQuad, data, max_size)) return false; p->updateBaseQuad();
if (!mkxp_sandbox::sandbox_deserialize(p->padRect, data, max_size)) return false; }
if (!mkxp_sandbox::sandbox_deserialize(p->clipRect, data, max_size)) return false; }
if (!mkxp_sandbox::sandbox_deserialize(p->cursorVert, data, max_size)) return false;
if (!mkxp_sandbox::sandbox_deserialize(p->pauseAlphaIdx, data, max_size)) return false; if (!mkxp_sandbox::sandbox_deserialize(p->pauseAlphaIdx, data, max_size)) return false;
p->pauseAlphaIdx = std::min(p->pauseAlphaIdx, (uint8_t)(pauseAlphaN - 1));
if (!mkxp_sandbox::sandbox_deserialize(p->pauseQuadIdx, data, max_size)) return false; if (!mkxp_sandbox::sandbox_deserialize(p->pauseQuadIdx, data, max_size)) return false;
p->pauseQuadIdx %= pauseQuadN;
if (!mkxp_sandbox::sandbox_deserialize(p->cursorAlphaIdx, data, max_size)) return false; if (!mkxp_sandbox::sandbox_deserialize(p->cursorAlphaIdx, data, max_size)) return false;
p->cursorAlphaIdx %= cursorAlphaN;
if (!mkxp_sandbox::sandbox_deserialize(p->sceneOffset, data, max_size)) return false; if (!mkxp_sandbox::sandbox_deserialize(p->sceneOffset, data, max_size)) return false;
if (!sandbox_deserialize_viewport_element(data, max_size)) return false; if (!sandbox_deserialize_viewport_element(data, max_size)) return false;
if (!mkxp_sandbox::sandbox_deserialize(p->windowskin, data, max_size)) return false; if (!mkxp_sandbox::sandbox_deserialize(p->windowskin, data, max_size)) return false;
@ -1335,6 +1352,7 @@ void WindowVX::sandbox_deserialize_end()
if (isDisposed()) return; if (isDisposed()) return;
if (p->contents != nullptr && (p->contents->deserModified || p->contents->id != p->deserSavedContentsId)) { if (p->contents != nullptr && (p->contents->deserModified || p->contents->id != p->deserSavedContentsId)) {
p->contentsQuad.setTexPosRect(p->contents->rect(), p->contents->rect());
p->ctrlVertDirty = true; p->ctrlVertDirty = true;
} }