#include "Entity.h" math::Vector4f vectorm3_from_json(const nlohmann::json& json) { ASSERT(json.size() == 3); math::Vector4f result; for (int i = 0; i < 3; i++) { result[i] = json[i].get() * METER_LENGTH; } result[3] = 1.f; return result; } math::Vector4f vectorm4_from_json(const nlohmann::json& json) { ASSERT(json.size() == 4); math::Vector4f result; for (int i = 0; i < 4; i++) { result[i] = json[i].get() * METER_LENGTH; } return result; } math::Vector4f movie_pos_from_json(const nlohmann::json& json) { ASSERT(json.size() == 4); math::Vector4f result; for (int i = 0; i < 3; i++) { result[i] = json[i].get() * METER_LENGTH; } result[3] = json[3].get() * DEGREES_LENGTH; return result; } math::Vector4f vector_from_json(const nlohmann::json& json) { ASSERT(json.size() == 4); math::Vector4f result; for (int i = 0; i < 4; i++) { result[i] = json[i].get(); } return result; } math::Vector4f vector_vol_from_json(const nlohmann::json& json) { ASSERT(json.size() == 4); math::Vector4f result; for (int i = 0; i < 3; i++) { result[i] = json[i].get(); } result[3] = json[3].get() * METER_LENGTH; return result; } u64 parse_enum(EnumType* e, goos::Object& rest) { if (e->is_bitfield()) { u64 value = 0; for_each_in_list(rest, [&](const goos::Object& o) { auto kv = e->entries().find(o.as_symbol().name_ptr); ASSERT_MSG(kv != e->entries().end(), fmt::format("The value {} was not found in enum.", o.print())); value |= ((u64)1 << (u64)kv->second); }); return value; } else { u64 value = 0; bool got = false; for_each_in_list(rest, [&](const goos::Object& o) { ASSERT_MSG(!got, "Invalid enum lookup."); auto kv = e->entries().find(o.as_symbol().name_ptr); ASSERT_MSG(kv != e->entries().end(), fmt::format("The value {} was not found in enum.", o.print())); value = kv->second; got = true; }); ASSERT_MSG(got, "Invalid enum lookup."); return value; } } u64 get_enum_val(const std::string& val, decompiler::DecompilerTypeSystem& dts) { auto& reader = pretty_print::get_pretty_printer_reader(); auto value = reader.read_from_string(val).as_pair()->cdr.as_pair()->car; auto type = value.as_pair()->car.as_symbol().name_ptr; auto rest = value.as_pair()->cdr; auto enum_def = dts.ts.try_enum_lookup(type); ASSERT_MSG(enum_def, fmt::format("Enum {} was not found.", type)); return parse_enum(enum_def, rest); } template std::vector enum_from_json(const nlohmann::json& json, decompiler::DecompilerTypeSystem& dts) { std::vector result; for (const auto& entry : json) { result.push_back(static_cast(get_enum_val(entry.get(), dts))); } return result; } static std::unordered_map(const std::string&, const nlohmann::json&, decompiler::DecompilerTypeSystem&)>> lump_map = { {"int32", [](const std::string& name, const nlohmann::json& json, decompiler::DecompilerTypeSystem& dts) { (void)dts; std::vector data; for (size_t i = 1; i < json.size(); i++) { data.push_back(json[i].get()); } return std::make_unique(name, data, -1000000000.0000); }}, {"uint32", [](const std::string& name, const nlohmann::json& json, decompiler::DecompilerTypeSystem& dts) { (void)dts; std::vector data; for (size_t i = 1; i < json.size(); i++) { data.push_back(json[i].get()); } return std::make_unique(name, data, -1000000000.0000); }}, {"enum-int32", [](const std::string& name, const nlohmann::json& json, decompiler::DecompilerTypeSystem& dts) { std::vector data; for (size_t i = 1; i < json.size(); i++) { data = enum_from_json(json[i], dts); } return std::make_unique(name, data, -1000000000.0000); }}, {"enum-uint32", [](const std::string& name, const nlohmann::json& json, decompiler::DecompilerTypeSystem& dts) { std::vector data; for (size_t i = 1; i < json.size(); i++) { data = enum_from_json(json[i], dts); } return std::make_unique(name, data, -1000000000.0000); }}, {"eco-info", [](const std::string& name, const nlohmann::json& json, decompiler::DecompilerTypeSystem& dts) { std::vector data; // pickup-type data.push_back(static_cast(get_enum_val(json[1].get(), dts))); // amount data.push_back(json[2].get()); return std::make_unique(name, data, -1000000000.0000); }}, {"water-height", [](const std::string& name, const nlohmann::json& json, decompiler::DecompilerTypeSystem& dts) { std::vector data; // water-height data.push_back(json[1].get() * METER_LENGTH); // wade-height data.push_back(json[2].get() * METER_LENGTH); // swim-height data.push_back(json[3].get() * METER_LENGTH); // water-flags data.push_back(static_cast(get_enum_val(json[4].get(), dts))); // bottom-height if (json.size() >= 6) { data.push_back(json[5].get() * METER_LENGTH); } return std::make_unique(name, data, -1000000000.0000); }}, {"vector", [](const std::string& name, const nlohmann::json& json, decompiler::DecompilerTypeSystem& dts) { (void)dts; std::vector data; for (size_t i = 1; i < json.size(); i++) { data.push_back(vector_from_json(json[i])); } return std::make_unique(name, data, -1000000000.0000); }}, {"vector4m", [](const std::string& name, const nlohmann::json& json, decompiler::DecompilerTypeSystem& dts) { (void)dts; std::vector data; for (size_t i = 1; i < json.size(); i++) { data.push_back(vectorm4_from_json(json[i])); } return std::make_unique(name, data, -1000000000.0000); }}, {"vector3m", [](const std::string& name, const nlohmann::json& json, decompiler::DecompilerTypeSystem& dts) { (void)dts; std::vector data; for (size_t i = 1; i < json.size(); i++) { data.push_back(vectorm3_from_json(json[i])); } return std::make_unique(name, data, -1000000000.0000); }}, {"movie-pos", [](const std::string& name, const nlohmann::json& json, decompiler::DecompilerTypeSystem& dts) { (void)dts; std::vector data; for (size_t i = 1; i < json.size(); i++) { data.push_back(movie_pos_from_json(json[i])); } return std::make_unique(name, data, -1000000000.0000); }}, {"vector-vol", [](const std::string& name, const nlohmann::json& json, decompiler::DecompilerTypeSystem& dts) { (void)dts; std::vector data; for (size_t i = 1; i < json.size(); i++) { data.push_back(vector_vol_from_json(json[i])); } return std::make_unique(name, data, -1000000000.0000); }}, {"float", [](const std::string& name, const nlohmann::json& json, decompiler::DecompilerTypeSystem& dts) { (void)dts; std::vector data; for (size_t i = 1; i < json.size(); i++) { data.push_back(json[i].get()); } return std::make_unique(name, data, -1000000000.0000); }}, {"meters", [](const std::string& name, const nlohmann::json& json, decompiler::DecompilerTypeSystem& dts) { (void)dts; std::vector data; for (size_t i = 1; i < json.size(); i++) { data.push_back(json[i].get() * METER_LENGTH); } return std::make_unique(name, data, -1000000000.0000); }}, {"degrees", [](const std::string& name, const nlohmann::json& json, decompiler::DecompilerTypeSystem& dts) { (void)dts; std::vector data; for (size_t i = 1; i < json.size(); i++) { data.push_back(json[i].get() * DEGREES_LENGTH); } return std::make_unique(name, data, -1000000000.0000); }}}; std::unique_ptr res_from_json_array(const std::string& name, const nlohmann::json& json_array, decompiler::DecompilerTypeSystem& dts) { ASSERT(!json_array.empty()); std::string array_type = json_array[0].get(); if (lump_map.find(array_type) != lump_map.end()) { return lump_map[array_type](name, json_array, dts); } else { ASSERT_MSG(false, fmt::format("unsupported array type: {}\n", array_type)); } }