summaryrefslogtreecommitdiffhomepage
path: root/serialize
diff options
context:
space:
mode:
Diffstat (limited to 'serialize')
-rw-r--r--serialize/anim.cpp5
-rw-r--r--serialize/atlas-type.hpp2
-rw-r--r--serialize/old-savegame.cpp27
-rw-r--r--serialize/savegame.cpp36
-rw-r--r--serialize/scenery.cpp6
5 files changed, 42 insertions, 34 deletions
diff --git a/serialize/anim.cpp b/serialize/anim.cpp
index cd1f5e5c..5e2ed388 100644
--- a/serialize/anim.cpp
+++ b/serialize/anim.cpp
@@ -133,10 +133,11 @@ namespace nlohmann {
void adl_serializer<floormat::anim_scale>::to_json(json& j, const anim_scale val)
{
+ if (val.type >= anim_scale_type::COUNT) [[unlikely]]
+ fm_throw("invalid anim_scale_type '{}"_cf, (unsigned)val.type);
switch (val.type)
{
- default:
- fm_throw("invalid anim_scale_type '{}"_cf, (unsigned)val.type);
+ case anim_scale_type::COUNT: std::unreachable();
case anim_scale_type::invalid:
fm_throw("anim_scale is invalid"_cf);
case anim_scale_type::fixed:
diff --git a/serialize/atlas-type.hpp b/serialize/atlas-type.hpp
index 1d3ea5aa..ef8bf440 100644
--- a/serialize/atlas-type.hpp
+++ b/serialize/atlas-type.hpp
@@ -3,6 +3,6 @@
namespace floormat::Serialize {
enum class atlas_type : uint8_t
{
- none, ground, wall, anim, vobj,
+ none, ground, wall, anim, vobj, COUNT,
};
} // namespace floormat::Serialize
diff --git a/serialize/old-savegame.cpp b/serialize/old-savegame.cpp
index 111d29f3..46b83590 100644
--- a/serialize/old-savegame.cpp
+++ b/serialize/old-savegame.cpp
@@ -309,11 +309,11 @@ void reader_state::read_chunks(reader_t& s)
tile_ref t = c[i];
using uchar = uint8_t;
const auto make_atlas = [&]<typename T>() -> image_proto_<T> {
- atlasid id;
+ atlasid atlas_id;
if (PROTO < 8) [[unlikely]]
- id = flags & meta_short_atlasid_ ? atlasid{s.read<uchar>()} : s.read<atlasid>();
+ atlas_id = flags & meta_short_atlasid_ ? atlasid{s.read<uchar>()} : s.read<atlasid>();
else
- id << s;
+ atlas_id << s;
uint8_t v;
if (PROTO >= 2) [[likely]]
v << s;
@@ -321,20 +321,24 @@ void reader_state::read_chunks(reader_t& s)
v = flags & meta_short_variant_
? s.read<uint8_t>()
: uint8_t(s.read<uint16_t>());
- auto name = lookup_atlas(id);
+ auto name = lookup_atlas(atlas_id);
if constexpr(std::is_same_v<ground_atlas, T>)
{
auto atlas = loader.ground_atlas(name, asset_policy);
fm_soft_assert(v < atlas->num_tiles());
return { atlas, v };
}
- else if (std::is_same_v<wall_atlas, T>)
+ else if constexpr(std::is_same_v<wall_atlas, T>)
{
auto atlas = loader.wall_atlas(name, asset_policy);
return { atlas, v };
}
else
+ {
+ static_assert(sizeof T{} != (size_t)-1);
+ static_assert(sizeof T{} == (size_t)-1);
std::unreachable();
+ }
};
SET_CHUNK_SIZE();
//t.passability() = pass_mode(flags & pass_mask);
@@ -364,7 +368,6 @@ void reader_state::read_chunks(reader_t& s)
oid << s;
fm_soft_assert((oid & lowbits<collision_data_BITS, object_id>) == oid);
type = object_type(s.read<std::underlying_type_t<object_type>>());
- fm_soft_assert(type < object_type::COUNT);
}
else
{
@@ -373,6 +376,9 @@ void reader_state::read_chunks(reader_t& s)
fm_soft_assert(oid != 0);
type = object_type(_id >> 61);
}
+ if (type >= object_type::COUNT || type == object_type::none) [[unlikely]]
+ fm_throw("invalid_object_type '{}'"_cf, (int)type);
+
const auto local = local_coords{s.read<uint8_t>()};
Vector2b offset;
@@ -388,6 +394,7 @@ void reader_state::read_chunks(reader_t& s)
s >> e.bbox_size[1];
};
SET_CHUNK_SIZE();
+
switch (type)
{
case object_type::critter: {
@@ -409,8 +416,8 @@ void reader_state::read_chunks(reader_t& s)
if (PROTO >= 9) [[likely]]
{
- uint32_t id; id << s;
- auto name = lookup_string(id);
+ uint32_t string_id; string_id << s;
+ auto name = lookup_string(string_id);
fm_soft_assert(name.size() < critter_name_max);
proto.name = name;
}
@@ -527,8 +534,8 @@ void reader_state::read_chunks(reader_t& s)
(void)L;
break;
}
- default:
- fm_throw("invalid_object_type '{}'"_cf, (int)type);
+ case object_type::none:
+ case object_type::COUNT: std::unreachable();
}
}
diff --git a/serialize/savegame.cpp b/serialize/savegame.cpp
index 912bb2c5..5a77db0f 100644
--- a/serialize/savegame.cpp
+++ b/serialize/savegame.cpp
@@ -150,9 +150,12 @@ struct visitor_
template<typename F>
void visit_object_internal(object& obj, F&& f, object_id id, object_type type, chunk_coords_ ch)
{
- non_const(obj.id) = id;
+ if (type >= object_type::COUNT || type == object_type::none) [[unlikely]]
+ fm_throw("invalid object type {}"_cf, (int)type);
switch (type)
{
+ case object_type::none:
+ case object_type::COUNT: std::unreachable();
case object_type::light:
static_cast<Derived&>(*this).visit(non_const(obj.atlas), atlas_type::vobj, f);
break;
@@ -160,19 +163,15 @@ struct visitor_
case object_type::critter:
static_cast<Derived&>(*this).visit(non_const(obj.atlas), atlas_type::anim, f);
break;
- case object_type::none:
- case object_type::COUNT:
- default:
- break;
+
}
- if (!obj.atlas)
- fm_throw("invalid object type {}"_cf, (int)type);
- //do_visit(*obj.c, f);
+ fm_debug_assert(obj.atlas);
{ auto pt = obj.coord.local();
do_visit(pt, f);
non_const(obj.coord) = {ch, pt};
}
+ non_const(obj.id) = id;
do_visit_nonconst(obj.offset, f);
do_visit_nonconst(obj.bbox_offset, f);
do_visit_nonconst(obj.bbox_size, f);
@@ -190,14 +189,10 @@ struct visitor_
switch (type)
{
+ default: break;
case object_type::critter: do_visit(static_cast<critter&>(obj), f); return;
case object_type::scenery: do_visit(static_cast<scenery&>(obj), f); return;
case object_type::light: do_visit(static_cast<light&>(obj), f); return;
- case object_type::COUNT:
- case object_type::none:
- break;
- default:
- fm_abort("invalid object type '%d'", (int)type);
}
}
@@ -455,16 +450,19 @@ struct writer final : visitor_<writer>
StringView name;
+ if (type >= atlas_type::COUNT || type == atlas_type::none) [[unlikely]]
+ fm_abort("invalid atlas type '%d'", (int)type);
switch (type)
{
- case atlas_type::ground: name = static_cast<const ground_atlas*>(atlas)->name(); break;
- case atlas_type::wall: name = static_cast<const wall_atlas*>(atlas)->name(); break;
+ case atlas_type::ground:
+ name = static_cast<const ground_atlas*>(atlas)->name(); break;
+ case atlas_type::wall:
+ name = static_cast<const wall_atlas*>(atlas)->name(); break;
case atlas_type::vobj:
case atlas_type::anim:
- name = static_cast<const anim_atlas*>(atlas)->name();
- break;
- default:
- fm_abort("invalid atlas type '%d'", (int)type);
+ name = static_cast<const anim_atlas*>(atlas)->name(); break;
+ case atlas_type::none:
+ case atlas_type::COUNT: std::unreachable();
}
do_visit(intern_string(name), f);
}
diff --git a/serialize/scenery.cpp b/serialize/scenery.cpp
index 080d0f71..5950ddf3 100644
--- a/serialize/scenery.cpp
+++ b/serialize/scenery.cpp
@@ -151,10 +151,12 @@ void adl_serializer<scenery_proto>::from_json(const json& j, scenery_proto& f)
fm_soft_assert(bbox_offset == Vector2i(Vector2b(bbox_offset)));
fm_soft_assert(bbox_size == Vector2ui(Vector2ub(bbox_size)));
+
+ fm_assert(type < scenery_type::COUNT);
switch (type)
{
- default:
- fm_throw("unhandled scenery type '{}'"_cf, (unsigned)type);
+ case scenery_type::none:
+ case scenery_type::COUNT: std::unreachable();
case scenery_type::generic: {
constexpr generic_scenery_proto G;
auto s = G;