diff --git a/binding-sandbox/sandbox-serial-util.cpp b/binding-sandbox/sandbox-serial-util.cpp index c90a9fab..c95e9d6e 100644 --- a/binding-sandbox/sandbox-serial-util.cpp +++ b/binding-sandbox/sandbox-serial-util.cpp @@ -107,15 +107,13 @@ template static typename std::enable_if> mkxp_sandbox::extra_objects; -std::unordered_map mkxp_sandbox::objects_deser; -std::unordered_map mkxp_sandbox::extra_objects_deser; +std::unordered_map mkxp_sandbox::swizzle_map; -sandbox_object_deser_info::sandbox_object_deser_info(void *ptr, wasm_size_t typenum) : ptr(ptr), typenum(typenum), ref_count(0), exists(true) {} +sandbox_swizzle_info::sandbox_swizzle_info(void *ptr, wasm_size_t typenum) : ptr(ptr), typenum(typenum), ref_count(0), exists(true) {} -sandbox_object_deser_info::sandbox_object_deser_info(struct sandbox_object_deser_info &&info) noexcept : ptr(std::exchange(info.ptr, nullptr)), typenum(info.typenum), ref_count(std::exchange(info.ref_count, 1)), exists(std::exchange(info.exists, true)) {} +sandbox_swizzle_info::sandbox_swizzle_info(struct sandbox_swizzle_info &&info) noexcept : ptr(std::exchange(info.ptr, nullptr)), typenum(info.typenum), ref_count(std::exchange(info.ref_count, 1)), exists(std::exchange(info.exists, true)) {} -struct sandbox_object_deser_info &sandbox_object_deser_info::operator=(struct sandbox_object_deser_info &&info) noexcept { +struct sandbox_swizzle_info &sandbox_swizzle_info::operator=(struct sandbox_swizzle_info &&info) noexcept { ptr = std::exchange(info.ptr, nullptr); typenum = info.typenum; ref_count = std::exchange(info.ref_count, 1); @@ -123,17 +121,17 @@ struct sandbox_object_deser_info &sandbox_object_deser_info::operator=(struct sa return *this; } -sandbox_object_deser_info::~sandbox_object_deser_info() { +sandbox_swizzle_info::~sandbox_swizzle_info() { if (!exists) { delete (std::vector *)ptr; } } -wasm_size_t sandbox_object_deser_info::get_ref_count() const noexcept { +wasm_size_t sandbox_swizzle_info::get_ref_count() const noexcept { return ref_count; } -bool sandbox_object_deser_info::set_ptr(void *ptr, wasm_size_t typenum) { +bool sandbox_swizzle_info::set_ptr(void *ptr, wasm_size_t typenum) { if (this->typenum != typenum) { // Don't allow pointers of mismatching type return false; @@ -153,15 +151,15 @@ bool sandbox_object_deser_info::set_ptr(void *ptr, wasm_size_t typenum) { return true; } -void *sandbox_object_deser_info::get_ptr() const { +void *sandbox_swizzle_info::get_ptr() const { return exists ? ptr : nullptr; } -wasm_size_t sandbox_object_deser_info::get_typenum() const { +wasm_size_t sandbox_swizzle_info::get_typenum() const { return typenum; } -bool sandbox_object_deser_info::get_exists() const { +bool sandbox_swizzle_info::get_exists() const { return exists; } diff --git a/binding-sandbox/sandbox-serial-util.h b/binding-sandbox/sandbox-serial-util.h index de2af258..7c09b341 100644 --- a/binding-sandbox/sandbox-serial-util.h +++ b/binding-sandbox/sandbox-serial-util.h @@ -22,7 +22,6 @@ #ifndef MKXPZ_SANDBOX_SERIAL_UTIL_H #define MKXPZ_SANDBOX_SERIAL_UTIL_H -#include #include #include #include @@ -76,14 +75,14 @@ namespace mkxp_sandbox { static constexpr wasm_size_t _get_typenum_counter_start = __COUNTER__; BOOST_PP_SEQ_FOR_EACH(_SANDBOX_DEF_GET_TYPENUM, _, SANDBOX_TYPENUM_TYPES); - struct sandbox_object_deser_info { - template sandbox_object_deser_info(T *&ref) : ptr(new std::vector({(void **)&ref})), typenum(mkxp_sandbox::get_typenum::value), ref_count(1), exists(false) {} - sandbox_object_deser_info(void *ptr, wasm_size_t typenum); - sandbox_object_deser_info(const struct sandbox_object_deser_info &) = delete; - sandbox_object_deser_info(struct sandbox_object_deser_info &&) noexcept; - struct sandbox_object_deser_info &operator=(const struct sandbox_object_deser_info &) = delete; - struct sandbox_object_deser_info &operator=(struct sandbox_object_deser_info &&) noexcept; - ~sandbox_object_deser_info(); + struct sandbox_swizzle_info { + template sandbox_swizzle_info(T *&ref) : ptr(new std::vector({(void **)&ref})), typenum(mkxp_sandbox::get_typenum::value), ref_count(1), exists(false) {} + sandbox_swizzle_info(void *ptr, wasm_size_t typenum); + sandbox_swizzle_info(const struct sandbox_swizzle_info &) = delete; + sandbox_swizzle_info(struct sandbox_swizzle_info &&) noexcept; + struct sandbox_swizzle_info &operator=(const struct sandbox_swizzle_info &) = delete; + struct sandbox_swizzle_info &operator=(struct sandbox_swizzle_info &&) noexcept; + ~sandbox_swizzle_info(); wasm_size_t get_ref_count() const noexcept; template bool add_ref(T *&ref) { if (typenum != mkxp_sandbox::get_typenum::value) { @@ -118,9 +117,7 @@ namespace mkxp_sandbox { bool exists; }; - extern std::vector> extra_objects; - extern std::unordered_map objects_deser; - extern std::unordered_map extra_objects_deser; + extern std::unordered_map swizzle_map; template using sandbox_serialize_member_declaration = decltype(std::declval()->sandbox_serialize(std::declval(), std::declval())); template using sandbox_deserialize_member_declaration = decltype(std::declval()->sandbox_deserialize(std::declval(), std::declval())); @@ -144,12 +141,7 @@ namespace mkxp_sandbox { template struct sandbox_ptr_map { private: - struct info { - mkxp_sandbox::wasm_objkey_t key; - bool is_extra; - }; - - static std::unordered_map map; + static std::unordered_map unswizzle_map; static bool is_serializing; static bool is_deserializing; @@ -166,14 +158,13 @@ namespace mkxp_sandbox { } is_serializing = true; - map.clear(); - extra_objects.clear(); + unswizzle_map.clear(); wasm_objkey_t key = 0; for (const auto &object : sb()->objects) { ++key; if (object.typenum == get_typenum::value) { - map.emplace((T *)object.inner.ptr, (struct info){key, false}); + unswizzle_map.emplace((T *)object.inner.ptr, key); } } } @@ -185,22 +176,9 @@ namespace mkxp_sandbox { std::abort(); } - if (ptr == nullptr) { - if (!mkxp_sandbox::sandbox_serialize((uint8_t)2, data, max_size)) return false; - } else { - const auto &it = map.find(ptr); - if (it != map.end()) { - if (!mkxp_sandbox::sandbox_serialize((uint8_t)(it->second.is_extra ? 1 : 0), data, max_size)) return false; - if (!mkxp_sandbox::sandbox_serialize(it->second.key, data, max_size)) return false; - } else { - if (!mkxp_sandbox::sandbox_serialize((uint8_t)1, data, max_size)) return false; - - constexpr wasm_size_t typenum = get_typenum::value; - extra_objects.emplace_back((const void *)ptr, typenum); - map.emplace(ptr, (struct info){(wasm_objkey_t)extra_objects.size(), true}); - - if (!mkxp_sandbox::sandbox_serialize((wasm_objkey_t)extra_objects.size(), data, max_size)) return false; - } + if (!mkxp_sandbox::sandbox_serialize(ptr != nullptr, data, max_size)) return false; + if (ptr != nullptr) { + if (!mkxp_sandbox::sandbox_serialize(unswizzle_map.at(ptr), data, max_size)) return false; } return true; @@ -212,8 +190,7 @@ namespace mkxp_sandbox { } is_serializing = false; - map.clear(); - extra_objects.clear(); + unswizzle_map.clear(); } static void sandbox_deserialize_begin() { @@ -228,8 +205,7 @@ namespace mkxp_sandbox { } is_deserializing = true; - objects_deser.clear(); - extra_objects_deser.clear(); + swizzle_map.clear(); } static bool sandbox_deserialize(T *&ref, const void *&data, wasm_size_t &max_size) { @@ -239,22 +215,19 @@ namespace mkxp_sandbox { std::abort(); } - uint8_t type; - if (!mkxp_sandbox::sandbox_deserialize(type, data, max_size)) return false; - if (type > 2) return false; + bool is_not_null; + if (!mkxp_sandbox::sandbox_deserialize(is_not_null, data, max_size)) return false; - if (type == 2) { + if (!is_not_null) { ref = nullptr; - // Don't allow null Color, Tone or Rect pointers (null Font pointers are allowed since they indicate `shState->defaultFont()`) - return !std::is_same::value && !std::is_same::value && !std::is_same::value; + return true; } wasm_objkey_t key; if (!mkxp_sandbox::sandbox_deserialize(key, data, max_size)) return false; - auto &deser_map = type != 0 ? extra_objects_deser : objects_deser; - const auto it = deser_map.find(key); - if (it == deser_map.end()) { - deser_map.emplace(key, sandbox_object_deser_info(ref)); + const auto it = swizzle_map.find(key); + if (it == swizzle_map.end()) { + swizzle_map.emplace(key, sandbox_swizzle_info(ref)); return true; } else { return it->second.add_ref(ref); @@ -267,21 +240,11 @@ namespace mkxp_sandbox { } is_deserializing = false; - objects_deser.clear(); - - // Delete extra objects with no references so we don't leak them - for (auto &pair : extra_objects_deser) { - struct sandbox_object_deser_info &info = pair.second; - if (info.get_ref_count() == 0 && info.get_ptr() != nullptr) { - typenum_table[info.get_typenum() - 1].destroy(info.get_ptr()); - } - } - - extra_objects_deser.clear(); + swizzle_map.clear(); } }; - template std::unordered_map::info> sandbox_ptr_map::map; + template std::unordered_map sandbox_ptr_map::unswizzle_map; template bool sandbox_ptr_map::is_serializing = false; template bool sandbox_ptr_map::is_deserializing = false; diff --git a/src/core.cpp b/src/core.cpp index 2ddfb3fb..335ee80b 100644 --- a/src/core.cpp +++ b/src/core.cpp @@ -1692,24 +1692,6 @@ extern "C" RETRO_API bool retro_serialize(void *data, size_t len) { num_free_objects = 0; } - // Write the number of extra objects that were found during serialization of the normal objects, then each such object - if (max_size < sizeof(wasm_size_t)) SER_OBJECTS_END_FAIL; - wasm_size_t *num_extra_objects_ptr = (wasm_size_t *)data; - ADVANCE(sizeof(wasm_size_t)); - for (size_t i = 0; i < extra_objects.size(); ++i) { // More items can be added to this vector during iteration - const void *ptr = std::get<0>(extra_objects[i]); - wasm_size_t typenum = std::get<1>(extra_objects[i]); - if (typenum != get_typenum::value && typenum != get_typenum::value && typenum != get_typenum::value) { - std::fprintf(stderr, "extra object other than Color, Tone or Rect found during save state serialization with typenum %llu (there's probably a bug in the sandbox bindings)\n", (unsigned long long)typenum); - std::fflush(stderr); - std::abort(); - } else { - if (!sandbox_serialize(typenum, data, max_size)) SER_OBJECTS_END_FAIL; - if (!typenum_table[typenum - 1].serialize(ptr, data, max_size)) SER_OBJECTS_END_FAIL; - } - } - *num_extra_objects_ptr = (wasm_size_t)extra_objects.size(); - SER_OBJECTS_END; std::memset(data, 0, max_size); return true; @@ -1888,8 +1870,8 @@ extern "C" RETRO_API bool retro_unserialize(const void *data, size_t len) { object.typenum = typenum; object.inner.ptr = typenum_table[typenum - 1].construct(); if (object.inner.ptr == nullptr) DESER_OBJECTS_END_FAIL; - typenum_table[typenum - 1].deserialize_begin(object.inner.ptr, true); currently_disposed = false; + typenum_table[typenum - 1].deserialize_begin(object.inner.ptr, true); } // Deserialize the object @@ -1899,10 +1881,10 @@ extern "C" RETRO_API bool retro_unserialize(const void *data, size_t len) { typenum_table[typenum - 1].dispose(object.inner.ptr); } - // Add it to the pointer map so that other objects that reference this one will be able to see it - auto it = objects_deser.find(object_key); - if (it == objects_deser.end()) { - objects_deser.emplace(object_key, sandbox_object_deser_info(object.inner.ptr, typenum)); + // Add it to the swizzle map so that other objects that reference this one will be able to see it + auto it = swizzle_map.find(object_key); + if (it == swizzle_map.end()) { + swizzle_map.emplace(object_key, sandbox_swizzle_info(object.inner.ptr, typenum)); } else { it->second.set_ptr(object.inner.ptr, typenum); } @@ -1910,46 +1892,8 @@ extern "C" RETRO_API bool retro_unserialize(const void *data, size_t len) { } } - // Read extra objects - wasm_objkey_t extra_object_key = 1; - wasm_size_t num_extra_objects; - if (!sandbox_deserialize(num_extra_objects, data, max_size)) DESER_OBJECTS_END_FAIL; - while (extra_object_key <= num_extra_objects) { - wasm_size_t typenum; - if (!sandbox_deserialize(typenum, data, max_size)) DESER_OBJECTS_END_FAIL; - if (typenum != get_typenum::value && typenum != get_typenum::value && typenum != get_typenum::value) DESER_OBJECTS_END_FAIL; - - // Create a new object - void *ptr = typenum_table[typenum - 1].construct(); - if (ptr == nullptr) DESER_OBJECTS_END_FAIL; - typenum_table[typenum - 1].deserialize_begin(ptr, true); - - // Deserialize into the newly created object - if (!typenum_table[typenum - 1].deserialize(ptr, data, max_size)) { - typenum_table[typenum - 1].destroy(ptr); - DESER_OBJECTS_END_FAIL; - } - - // Add it to the pointer map so that other objects that reference this one will be able to see it - auto it = extra_objects_deser.find(extra_object_key); - if (it == extra_objects_deser.end()) { - extra_objects_deser.emplace(extra_object_key, sandbox_object_deser_info(ptr, typenum)); - } else { - if (!it->second.set_ptr(ptr, typenum)) { - typenum_table[typenum - 1].destroy(ptr); - DESER_OBJECTS_END_FAIL; - } - } - ++extra_object_key; - } - // Make sure every pointer in the save state has been swizzled - for (const auto &pair : objects_deser) { - if (!pair.second.get_exists()) { - DESER_OBJECTS_END_FAIL; - } - } - for (const auto &pair : extra_objects_deser) { + for (const auto &pair : swizzle_map) { if (!pair.second.get_exists()) { DESER_OBJECTS_END_FAIL; } @@ -1960,11 +1904,6 @@ extern "C" RETRO_API bool retro_unserialize(const void *data, size_t len) { typenum_table[object.typenum - 1].deserialize_end(object.inner.ptr); } } - for (const auto &pair : extra_objects_deser) { - if (pair.second.get_typenum() > 0) { - typenum_table[pair.second.get_typenum() - 1].deserialize_end(pair.second.get_ptr()); - } - } DESER_OBJECTS_END; return true; } diff --git a/src/display/font.cpp b/src/display/font.cpp index 6404105d..655170f3 100644 --- a/src/display/font.cpp +++ b/src/display/font.cpp @@ -698,8 +698,9 @@ bool Font::sandbox_serialize(void *&data, mkxp_sandbox::wasm_size_t &max_size) c if (!mkxp_sandbox::sandbox_serialize(p->italic, data, max_size)) return false; if (!mkxp_sandbox::sandbox_serialize(p->outline, data, max_size)) return false; if (!mkxp_sandbox::sandbox_serialize(p->shadow, data, max_size)) return false; - if (!mkxp_sandbox::sandbox_serialize(p->color, data, max_size)) return false; - if (!mkxp_sandbox::sandbox_serialize(p->outColor, data, max_size)) return false; + + if (!mkxp_sandbox::sandbox_serialize(p->color == &p->colorTmp ? nullptr : p->color, data, max_size)) return false; + if (!mkxp_sandbox::sandbox_serialize(p->outColor == &p->outColorTmp ? nullptr : p->outColor, data, max_size)) return false; if (!mkxp_sandbox::sandbox_serialize((int32_t)p->size, data, max_size)) return false; if (!mkxp_sandbox::sandbox_serialize(p->name, data, max_size)) return false; @@ -713,8 +714,15 @@ bool Font::sandbox_deserialize(const void *&data, mkxp_sandbox::wasm_size_t &max if (!mkxp_sandbox::sandbox_deserialize(p->italic, data, max_size)) return false; if (!mkxp_sandbox::sandbox_deserialize(p->outline, data, max_size)) return false; if (!mkxp_sandbox::sandbox_deserialize(p->shadow, data, max_size)) return false; + if (!mkxp_sandbox::sandbox_deserialize(p->color, data, max_size)) return false; + if (p->color == nullptr) { + p->color = &p->colorTmp; + } if (!mkxp_sandbox::sandbox_deserialize(p->outColor, data, max_size)) return false; + if (p->outColor == nullptr) { + p->outColor = &p->outColorTmp; + } // Invalidate the inner font object if either the name or size of this font is different from before if (p->sdlFont != nullptr) { diff --git a/src/display/plane.cpp b/src/display/plane.cpp index 8a272a3e..b90eefba 100644 --- a/src/display/plane.cpp +++ b/src/display/plane.cpp @@ -360,10 +360,12 @@ bool Plane::sandbox_serialize(void *&data, mkxp_sandbox::wasm_size_t &max_size) if (!mkxp_sandbox::sandbox_serialize(p->zoomX, data, max_size)) return false; if (!mkxp_sandbox::sandbox_serialize(p->zoomY, data, max_size)) return false; if (!mkxp_sandbox::sandbox_serialize(p->sceneGeo, data, max_size)) return false; + if (!sandbox_serialize_viewport_element(data, max_size)) return false; + if (!mkxp_sandbox::sandbox_serialize(p->bitmap, 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->color == &p->tmp.color ? nullptr : p->color, data, max_size)) return false; + if (!mkxp_sandbox::sandbox_serialize(p->tone == &p->tmp.tone ? nullptr : p->tone, data, max_size)) return false; return true; } @@ -407,10 +409,18 @@ bool Plane::sandbox_deserialize(const void *&data, mkxp_sandbox::wasm_size_t &ma p->quadSourceDirty = true; } } + if (!sandbox_deserialize_viewport_element(data, max_size)) return false; + if (!mkxp_sandbox::sandbox_deserialize(p->bitmap, data, max_size)) return false; if (!mkxp_sandbox::sandbox_deserialize(p->color, data, max_size)) return false; + if (p->color == nullptr) { + p->color = &p->tmp.color; + } if (!mkxp_sandbox::sandbox_deserialize(p->tone, data, max_size)) return false; + if (p->tone == nullptr) { + p->tone = &p->tmp.tone; + } return true; } diff --git a/src/display/sprite.cpp b/src/display/sprite.cpp index fb60de65..21f66c01 100644 --- a/src/display/sprite.cpp +++ b/src/display/sprite.cpp @@ -890,9 +890,9 @@ bool Sprite::sandbox_serialize(void *&data, mkxp_sandbox::wasm_size_t &max_size) if (!mkxp_sandbox::sandbox_serialize(p->bitmap, data, max_size)) return false; if (!mkxp_sandbox::sandbox_serialize(p->pattern, data, max_size)) return false; - if (!mkxp_sandbox::sandbox_serialize(p->srcRect, 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->srcRect == &p->tmp.rect ? nullptr : p->srcRect, data, max_size)) return false; + if (!mkxp_sandbox::sandbox_serialize(p->color == &p->tmp.color ? nullptr : p->color, data, max_size)) return false; + if (!mkxp_sandbox::sandbox_serialize(p->tone == &p->tmp.tone ? nullptr : p->tone, data, max_size)) return false; return true; } @@ -977,8 +977,17 @@ bool Sprite::sandbox_deserialize(const void *&data, mkxp_sandbox::wasm_size_t &m if (!mkxp_sandbox::sandbox_deserialize(p->bitmap, data, max_size)) return false; if (!mkxp_sandbox::sandbox_deserialize(p->pattern, data, max_size)) return false; if (!mkxp_sandbox::sandbox_deserialize(p->srcRect, data, max_size)) return false; + if (p->srcRect == nullptr) { + p->srcRect = &p->tmp.rect; + } if (!mkxp_sandbox::sandbox_deserialize(p->color, data, max_size)) return false; + if (p->color == nullptr) { + p->color = &p->tmp.color; + } if (!mkxp_sandbox::sandbox_deserialize(p->tone, data, max_size)) return false; + if (p->tone == nullptr) { + p->tone = &p->tmp.tone; + } return true; } diff --git a/src/display/tilemap.cpp b/src/display/tilemap.cpp index 530a0462..610daa68 100644 --- a/src/display/tilemap.cpp +++ b/src/display/tilemap.cpp @@ -1514,8 +1514,8 @@ bool Tilemap::sandbox_serialize(void *&data, mkxp_sandbox::wasm_size_t &max_size if (!mkxp_sandbox::sandbox_serialize(p->mapData, data, max_size)) return false; if (!mkxp_sandbox::sandbox_serialize(p->priorities, data, max_size)) return false; if (!mkxp_sandbox::sandbox_serialize(p->flashMap.getData(), 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->color == &p->tmp.color ? nullptr : p->color, data, max_size)) return false; + if (!mkxp_sandbox::sandbox_serialize(p->tone == &p->tmp.tone ? nullptr : p->tone, data, max_size)) return false; if (!mkxp_sandbox::sandbox_serialize(atProxy, data, max_size)) return false; @@ -1577,7 +1577,13 @@ bool Tilemap::sandbox_deserialize(const void *&data, mkxp_sandbox::wasm_size_t & if (!mkxp_sandbox::sandbox_deserialize(p->priorities, data, max_size)) return false; if (!mkxp_sandbox::sandbox_deserialize(p->flashMap.getData(), data, max_size)) return false; if (!mkxp_sandbox::sandbox_deserialize(p->color, data, max_size)) return false; + if (p->color == nullptr) { + p->color = &p->tmp.color; + } if (!mkxp_sandbox::sandbox_deserialize(p->tone, data, max_size)) return false; + if (p->tone == nullptr) { + p->tone = &p->tmp.tone; + } if (!mkxp_sandbox::sandbox_deserialize(atProxy, data, max_size)) return false; diff --git a/src/display/viewport.cpp b/src/display/viewport.cpp index 2540e9d1..6afb046c 100644 --- a/src/display/viewport.cpp +++ b/src/display/viewport.cpp @@ -253,9 +253,9 @@ bool Viewport::sandbox_serialize(void *&data, mkxp_sandbox::wasm_size_t &max_siz 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; + if (!mkxp_sandbox::sandbox_serialize(p->rect == &p->tmp.rect ? nullptr : p->rect, data, max_size)) return false; + if (!mkxp_sandbox::sandbox_serialize(p->color == &p->tmp.color ? nullptr : p->color, data, max_size)) return false; + if (!mkxp_sandbox::sandbox_serialize(p->tone == &p->tmp.tone ? nullptr : p->tone, data, max_size)) return false; return true; } @@ -273,8 +273,17 @@ bool Viewport::sandbox_deserialize(const void *&data, mkxp_sandbox::wasm_size_t if (!sandbox_deserialize_scene_element(data, max_size)) return false; if (!mkxp_sandbox::sandbox_deserialize(p->rect, data, max_size)) return false; + if (p->rect == nullptr) { + p->rect = &p->tmp.rect; + } if (!mkxp_sandbox::sandbox_deserialize(p->color, data, max_size)) return false; + if (p->color == nullptr) { + p->color = &p->tmp.color; + } if (!mkxp_sandbox::sandbox_deserialize(p->tone, data, max_size)) return false; + if (p->tone == nullptr) { + p->tone = &p->tmp.tone; + } return true; } diff --git a/src/display/window.cpp b/src/display/window.cpp index 2692b17e..47efdfd6 100644 --- a/src/display/window.cpp +++ b/src/display/window.cpp @@ -967,14 +967,18 @@ 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->backOpacity, data, max_size)) return false; if (!mkxp_sandbox::sandbox_serialize(p->contentsOpacity, data, max_size)) return false; + if (!p->controlsElement.sandbox_serialize_viewport_element(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->pauseAniQuadIdx, data, max_size)) return false; + if (!sandbox_serialize_viewport_element(data, max_size)) return false; + if (!mkxp_sandbox::sandbox_serialize(p->windowskin, data, max_size)) return false; if (!mkxp_sandbox::sandbox_serialize(p->contents, data, max_size)) return false; - if (!mkxp_sandbox::sandbox_serialize(p->cursorRect, data, max_size)) return false; + if (!mkxp_sandbox::sandbox_serialize(p->cursorRect == &p->tmp.rect ? nullptr : p->cursorRect, data, max_size)) return false; return true; } @@ -1033,17 +1037,24 @@ bool Window::sandbox_deserialize(const void *&data, mkxp_sandbox::wasm_size_t &m p->contentsQuad.setColor(Vec4(1, 1, 1, p->contentsOpacity.norm)); } } + if (!p->controlsElement.sandbox_deserialize_viewport_element(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; p->pauseAniAlphaIdx = std::min(p->pauseAniAlphaIdx, (uint8_t)(pauseAniAlphaN - 1)); 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 (!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->cursorRect, data, max_size)) return false; + if (p->cursorRect == nullptr) { + p->cursorRect = &p->tmp.rect; + } return true; } diff --git a/src/display/windowvx.cpp b/src/display/windowvx.cpp index c1f01159..f9bddaf7 100644 --- a/src/display/windowvx.cpp +++ b/src/display/windowvx.cpp @@ -1191,11 +1191,13 @@ bool WindowVX::sandbox_serialize(void *&data, mkxp_sandbox::wasm_size_t &max_siz 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->sceneOffset, data, max_size)) return false; + if (!sandbox_serialize_viewport_element(data, max_size)) return false; + if (!mkxp_sandbox::sandbox_serialize(p->windowskin, data, max_size)) return false; if (!mkxp_sandbox::sandbox_serialize(p->contents, data, max_size)) return false; - if (!mkxp_sandbox::sandbox_serialize(p->cursorRect, data, max_size)) return false; - if (!mkxp_sandbox::sandbox_serialize(p->tone, data, max_size)) return false; + if (!mkxp_sandbox::sandbox_serialize(p->cursorRect == &p->tmp.rect ? nullptr : p->cursorRect, data, max_size)) return false; + if (!mkxp_sandbox::sandbox_serialize(p->tone == &p->tmp.tone ? nullptr : p->tone, data, max_size)) return false; return true; } @@ -1287,11 +1289,19 @@ bool WindowVX::sandbox_deserialize(const void *&data, mkxp_sandbox::wasm_size_t 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 (!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->contents, data, max_size)) return false; if (!mkxp_sandbox::sandbox_deserialize(p->cursorRect, data, max_size)) return false; + if (p->cursorRect == nullptr) { + p->cursorRect = &p->tmp.rect; + } if (!mkxp_sandbox::sandbox_deserialize(p->tone, data, max_size)) return false; + if (p->tone == nullptr) { + p->tone = &p->tmp.tone; + } return true; }