diff --git a/.gitmodules b/.gitmodules index ec5d67c7..f0024e19 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,9 +1,6 @@ [submodule "lib/fmt"] path = 3rdparty/fmt url = https://github.com/fmtlib/fmt -[submodule "3rdparty/json"] - path = 3rdparty/json - url = https://github.com/ArthurSonzogni/nlohmann_json_cmake_fetchcontent [submodule "3rdparty/nanobench"] path = 3rdparty/nanobench url = https://github.com/martinus/nanobench diff --git a/3rdparty/CMakeLists.txt b/3rdparty/CMakeLists.txt index fb140abc..478ae635 100644 --- a/3rdparty/CMakeLists.txt +++ b/3rdparty/CMakeLists.txt @@ -1,6 +1,5 @@ add_subdirectory(fmt EXCLUDE_FROM_ALL) add_subdirectory(doctest EXCLUDE_FROM_ALL) -add_subdirectory(json EXCLUDE_FROM_ALL) add_subdirectory(nanobench EXCLUDE_FROM_ALL) set(BUILD_WITH_PEDANTIC_WARNINGS OFF CACHE BOOL "prevent pareto from adding /WX" FORCE) diff --git a/3rdparty/json b/3rdparty/json deleted file mode 160000 index 0db99d5e..00000000 --- a/3rdparty/json +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 0db99d5ed1ba0c4409509db3916e7bd8398ee920 diff --git a/common/CMakeLists.txt b/common/CMakeLists.txt index 13c6e9f6..0c7aa2bd 100644 --- a/common/CMakeLists.txt +++ b/common/CMakeLists.txt @@ -54,7 +54,9 @@ add_library(common STATIC ../include/common/mapfile.hh ) -target_link_libraries(common ${CMAKE_THREAD_LIBS_INIT} TBB::tbb TBB::tbbmalloc fmt::fmt nlohmann_json::nlohmann_json pareto) +find_package(jsoncpp CONFIG REQUIRED) + +target_link_libraries(common ${CMAKE_THREAD_LIBS_INIT} TBB::tbb TBB::tbbmalloc fmt::fmt JsonCpp::JsonCpp pareto) target_precompile_headers(common INTERFACE diff --git a/common/bspinfo.cc b/common/bspinfo.cc index 932441a7..a93e1a82 100644 --- a/common/bspinfo.cc +++ b/common/bspinfo.cc @@ -49,9 +49,9 @@ static std::string hex_string(const uint8_t *bytes, const size_t count) /** * returns a JSON array of models */ -static json serialize_bspxbrushlist(const std::vector &lump) +static Json::Value serialize_bspxbrushlist(const std::vector &lump) { - json j = json::array(); + Json::Value j = Json::Value(Json::arrayValue); imemstream p(lump.data(), lump.size(), std::ios_base::in | std::ios_base::binary); @@ -60,24 +60,24 @@ static json serialize_bspxbrushlist(const std::vector &lump) p >= structured; for (const bspxbrushes_permodel &src_model : structured.models) { - json &model = j.insert(j.end(), json::object()).value(); + auto &model = j.append(Json::Value(Json::objectValue)); model["ver"] = src_model.ver; model["modelnum"] = src_model.modelnum; model["numbrushes"] = src_model.brushes.size(); model["numfaces"] = src_model.numfaces; - json &brushes = (model.emplace("brushes", json::array())).first.value(); + auto &brushes = (model["brushes"] = Json::Value(Json::arrayValue)); for (const bspxbrushes_perbrush &src_brush : src_model.brushes) { - json &brush = brushes.insert(brushes.end(), json::object()).value(); - brush.push_back({"mins", src_brush.bounds.mins()}); - brush.push_back({"maxs", src_brush.bounds.maxs()}); - brush.push_back({"contents", src_brush.contents}); - json &faces = (brush.emplace("faces", json::array())).first.value(); + auto &brush = brushes.append(Json::Value(Json::objectValue)); + brush["mins"] = to_json(src_brush.bounds.mins()); + brush["maxs"] = to_json(src_brush.bounds.maxs()); + brush["contents"] = src_brush.contents; + auto &faces = (brush["faces"] = Json::Value(Json::arrayValue)); for (const bspxbrushes_perface &src_face : src_brush.faces) { - json &face = faces.insert(faces.end(), json::object()).value(); - face.push_back({"normal", src_face.normal}); - face.push_back({"dist", src_face.dist}); + auto &face = faces.append(Json::Value(Json::objectValue)); + face["normal"] = to_json(src_face.normal); + face["dist"] = src_face.dist; } } } @@ -85,9 +85,9 @@ static json serialize_bspxbrushlist(const std::vector &lump) return j; } -static json serialize_bspx_decoupled_lm(const std::vector &lump) +static Json::Value serialize_bspx_decoupled_lm(const std::vector &lump) { - json j = json::array(); + auto j = Json::Value(Json::arrayValue); imemstream p(lump.data(), lump.size(), std::ios_base::in | std::ios_base::binary); @@ -101,12 +101,14 @@ static json serialize_bspx_decoupled_lm(const std::vector &lump) break; } - json &model = j.insert(j.end(), json::object()).value(); + auto &model = j.append(Json::objectValue); model["lmwidth"] = src_face.lmwidth; model["lmheight"] = src_face.lmheight; model["offset"] = src_face.offset; - model["world_to_lm_space"] = - json::array({src_face.world_to_lm_space.row(0), src_face.world_to_lm_space.row(1)}); + model["world_to_lm_space"] = json_array({ + to_json(src_face.world_to_lm_space.row(0)), + to_json(src_face.world_to_lm_space.row(1)) + }); } return j; @@ -548,35 +550,36 @@ static void export_obj_and_lightmaps(const mbsp_t &bsp, const bspxentries_t &bsp void serialize_bsp(const bspdata_t &bspdata, const mbsp_t &bsp, const fs::path &name) { - json j = json::object(); + auto j = Json::Value(Json::objectValue); if (!bsp.dmodels.empty()) { - json &models = (j.emplace("models", json::array())).first.value(); + auto &models = (j["models"] = Json::Value(Json::arrayValue)); for (auto &src_model : bsp.dmodels) { - json &model = models.insert(models.end(), json::object()).value(); + auto &model = models.append(Json::Value(Json::objectValue)); - model.push_back({"mins", src_model.mins}); - model.push_back({"maxs", src_model.maxs}); - model.push_back({"origin", src_model.origin}); - model.push_back({"headnode", src_model.headnode}); - model.push_back({"visleafs", src_model.visleafs}); - model.push_back({"firstface", src_model.firstface}); - model.push_back({"numfaces", src_model.numfaces}); + model["mins"] = to_json(src_model.mins); + model["maxs"] = to_json(src_model.maxs); + model["origin"] = to_json(src_model.origin); + model["headnode"] = to_json(src_model.headnode); + model["visleafs"] = src_model.visleafs; + model["firstface"] = src_model.firstface; + model["numfaces"] = src_model.numfaces; } } if (bsp.dvis.bits.size()) { if (bsp.dvis.bit_offsets.size()) { - json &visdata = (j.emplace("visdata", json::object())).first.value(); + auto &visdata = j["visdata"]; + visdata = Json::Value(Json::objectValue); - json &pvs = (visdata.emplace("pvs", json::array())).first.value(); - json &phs = (visdata.emplace("pvs", json::array())).first.value(); + auto &pvs = (visdata["pvs"] = Json::Value(Json::arrayValue)); + auto &phs = (visdata["pvs"] = Json::Value(Json::arrayValue)); for (auto &offset : bsp.dvis.bit_offsets) { - pvs.push_back(offset[VIS_PVS]); - phs.push_back(offset[VIS_PHS]); + pvs.append(offset[VIS_PVS]); + phs.append(offset[VIS_PHS]); } visdata["bits"] = hex_string(bsp.dvis.bits.data(), bsp.dvis.bits.size()); @@ -594,207 +597,207 @@ void serialize_bsp(const bspdata_t &bspdata, const mbsp_t &bsp, const fs::path & } if (!bsp.dleafs.empty()) { - json &leafs = (j.emplace("leafs", json::array())).first.value(); + auto &leafs = (j["leafs"] = Json::Value(Json::arrayValue)); for (auto &src_leaf : bsp.dleafs) { - json &leaf = leafs.insert(leafs.end(), json::object()).value(); + auto &leaf = leafs.append(Json::Value(Json::objectValue)); - leaf.push_back({"contents", src_leaf.contents}); - leaf.push_back({"visofs", src_leaf.visofs}); - leaf.push_back({"mins", src_leaf.mins}); - leaf.push_back({"maxs", src_leaf.maxs}); - leaf.push_back({"firstmarksurface", src_leaf.firstmarksurface}); - leaf.push_back({"nummarksurfaces", src_leaf.nummarksurfaces}); - leaf.push_back({"ambient_level", src_leaf.ambient_level}); - leaf.push_back({"cluster", src_leaf.cluster}); - leaf.push_back({"area", src_leaf.area}); - leaf.push_back({"firstleafbrush", src_leaf.firstleafbrush}); - leaf.push_back({"numleafbrushes", src_leaf.numleafbrushes}); + leaf["contents"] = src_leaf.contents; + leaf["visofs"] = src_leaf.visofs; + leaf["mins"] = to_json(src_leaf.mins); + leaf["maxs"] = to_json(src_leaf.maxs); + leaf["firstmarksurface"] = src_leaf.firstmarksurface; + leaf["nummarksurfaces"] = src_leaf.nummarksurfaces; + leaf["ambient_level"] = to_json(src_leaf.ambient_level); + leaf["cluster"] = src_leaf.cluster; + leaf["area"] = src_leaf.area; + leaf["firstleafbrush"] = src_leaf.firstleafbrush; + leaf["numleafbrushes"] = src_leaf.numleafbrushes; } } if (!bsp.dplanes.empty()) { - json &planes = (j.emplace("planes", json::array())).first.value(); + auto &planes = (j["planes"] = Json::Value(Json::arrayValue)); for (auto &src_plane : bsp.dplanes) { - json &plane = planes.insert(planes.end(), json::object()).value(); + auto &plane = planes.append(Json::Value(Json::objectValue)); - plane.push_back({"normal", src_plane.normal}); - plane.push_back({"dist", src_plane.dist}); - plane.push_back({"type", src_plane.type}); + plane["normal"] = to_json(src_plane.normal); + plane["dist"] = src_plane.dist; + plane["type"] = src_plane.type; } } if (!bsp.dvertexes.empty()) { - json &vertexes = (j.emplace("vertexes", json::array())).first.value(); + auto &vertexes = (j["vertexes"] = Json::Value(Json::arrayValue)); for (auto &src_vertex : bsp.dvertexes) { - vertexes.insert(vertexes.end(), src_vertex); + vertexes.append(to_json(src_vertex)); } } if (!bsp.dnodes.empty()) { - json &nodes = (j.emplace("nodes", json::array())).first.value(); + auto &nodes = (j["nodes"] = Json::Value(Json::arrayValue)); for (auto &src_node : bsp.dnodes) { - json &node = nodes.insert(nodes.end(), json::object()).value(); + auto &node = nodes.append(Json::Value(Json::objectValue)); - node.push_back({"planenum", src_node.planenum}); - node.push_back({"children", src_node.children}); - node.push_back({"mins", src_node.mins}); - node.push_back({"maxs", src_node.maxs}); - node.push_back({"firstface", src_node.firstface}); - node.push_back({"numfaces", src_node.numfaces}); + node["planenum"] = src_node.planenum; + node["children"] = to_json(src_node.children); + node["mins"] = to_json(src_node.mins); + node["maxs"] = to_json(src_node.maxs); + node["firstface"] = src_node.firstface; + node["numfaces"] = src_node.numfaces; // human-readable plane auto &plane = bsp.dplanes.at(src_node.planenum); - node.push_back({"plane", json::array({plane.normal[0], plane.normal[1], plane.normal[2], plane.dist})}); + node["plane"] = json_array({plane.normal[0], plane.normal[1], plane.normal[2], plane.dist}); } } if (!bsp.texinfo.empty()) { - json &texinfos = (j.emplace("texinfo", json::array())).first.value(); + auto &texinfos = (j["texinfo"] = Json::Value(Json::arrayValue)); for (auto &src_texinfo : bsp.texinfo) { - json &texinfo = texinfos.insert(texinfos.end(), json::object()).value(); + auto &texinfo = texinfos.append(Json::Value(Json::objectValue)); - texinfo.push_back({"vecs", json::array({json::array({src_texinfo.vecs.at(0, 0), src_texinfo.vecs.at(0, 1), + texinfo["vecs"] = json_array({json_array({src_texinfo.vecs.at(0, 0), src_texinfo.vecs.at(0, 1), src_texinfo.vecs.at(0, 2), src_texinfo.vecs.at(0, 3)}), - json::array({src_texinfo.vecs.at(1, 0), src_texinfo.vecs.at(1, 1), - src_texinfo.vecs.at(1, 2), src_texinfo.vecs.at(1, 3)})})}); - texinfo.push_back({"flags", src_texinfo.flags.native}); - texinfo.push_back({"miptex", src_texinfo.miptex}); - texinfo.push_back({"value", src_texinfo.value}); - texinfo.push_back({"texture", std::string(src_texinfo.texture.data())}); - texinfo.push_back({"nexttexinfo", src_texinfo.nexttexinfo}); + json_array({src_texinfo.vecs.at(1, 0), src_texinfo.vecs.at(1, 1), + src_texinfo.vecs.at(1, 2), src_texinfo.vecs.at(1, 3)})}); + texinfo["flags"] = src_texinfo.flags.native; + texinfo["miptex"] = src_texinfo.miptex; + texinfo["value"] = src_texinfo.value; + texinfo["texture"] = std::string(src_texinfo.texture.data()); + texinfo["nexttexinfo"] = src_texinfo.nexttexinfo; } } if (!bsp.dfaces.empty()) { - json &faces = (j.emplace("faces", json::array())).first.value(); + auto &faces = (j["faces"] = Json::Value(Json::arrayValue)); for (auto &src_face : bsp.dfaces) { - json &face = faces.insert(faces.end(), json::object()).value(); + auto &face = faces.append(Json::Value(Json::objectValue)); - face.push_back({"planenum", src_face.planenum}); - face.push_back({"side", src_face.side}); - face.push_back({"firstedge", src_face.firstedge}); - face.push_back({"numedges", src_face.numedges}); - face.push_back({"texinfo", src_face.texinfo}); - face.push_back({"styles", src_face.styles}); - face.push_back({"lightofs", src_face.lightofs}); + face["planenum"] = src_face.planenum; + face["side"] = src_face.side; + face["firstedge"] = src_face.firstedge; + face["numedges"] = src_face.numedges; + face["texinfo"] = src_face.texinfo; + face["styles"] = to_json(src_face.styles); + face["lightofs"] = src_face.lightofs; // for readibility, also output the actual vertices - auto verts = json::array(); + auto verts = Json::Value(Json::arrayValue); for (int32_t k = 0; k < src_face.numedges; ++k) { auto se = bsp.dsurfedges[src_face.firstedge + k]; uint32_t v = (se < 0) ? bsp.dedges[-se][1] : bsp.dedges[se][0]; - verts.push_back(bsp.dvertexes[v]); + verts.append(to_json(bsp.dvertexes[v])); } - face.push_back({"vertices", verts}); + face["vertices"] = verts; #if 0 if (auto lm = get_lightmap_face(bsp, src_face, false)) { - face.push_back({"lightmap", serialize_image(lm)}); + face["lightmap", serialize_image(lm)}); } #endif } } if (!bsp.dclipnodes.empty()) { - json &clipnodes = (j.emplace("clipnodes", json::array())).first.value(); + auto &clipnodes = (j["clipnodes"] = Json::Value(Json::arrayValue)); for (auto &src_clipnodes : bsp.dclipnodes) { - json &clipnode = clipnodes.insert(clipnodes.end(), json::object()).value(); + auto &clipnode = clipnodes.append(Json::Value(Json::objectValue)); - clipnode.push_back({"planenum", src_clipnodes.planenum}); - clipnode.push_back({"children", src_clipnodes.children}); + clipnode["planenum"] = src_clipnodes.planenum; + clipnode["children"] = to_json(src_clipnodes.children); } } if (!bsp.dedges.empty()) { - json &edges = (j.emplace("edges", json::array())).first.value(); + auto &edges = (j["edges"] = Json::Value(Json::arrayValue)); for (auto &src_edge : bsp.dedges) { - edges.insert(edges.end(), src_edge); + edges.append(to_json(src_edge)); } } if (!bsp.dleaffaces.empty()) { - json &leaffaces = (j.emplace("leaffaces", json::array())).first.value(); + auto &leaffaces = (j["leaffaces"] = Json::Value(Json::arrayValue)); for (auto &src_leafface : bsp.dleaffaces) { - leaffaces.insert(leaffaces.end(), src_leafface); + leaffaces.append(src_leafface); } } if (!bsp.dsurfedges.empty()) { - json &surfedges = (j.emplace("surfedges", json::array())).first.value(); + auto &surfedges = (j["surfedges"] = Json::Value(Json::arrayValue)); for (auto &src_surfedges : bsp.dsurfedges) { - surfedges.insert(surfedges.end(), src_surfedges); + surfedges.append(src_surfedges); } } if (!bsp.dbrushsides.empty()) { - json &brushsides = (j.emplace("brushsides", json::array())).first.value(); + auto &brushsides = (j["brushsides"] = Json::Value(Json::arrayValue)); for (auto &src_brushside : bsp.dbrushsides) { - json &brushside = brushsides.insert(brushsides.end(), json::object()).value(); + auto &brushside = brushsides.append(Json::Value(Json::objectValue)); - brushside.push_back({"planenum", src_brushside.planenum}); - brushside.push_back({"texinfo", src_brushside.texinfo}); + brushside["planenum"] = src_brushside.planenum; + brushside["texinfo"] = src_brushside.texinfo; } } if (!bsp.dbrushes.empty()) { - json &brushes = (j.emplace("brushes", json::array())).first.value(); + auto &brushes = (j["brushes"] = Json::Value(Json::arrayValue)); for (auto &src_brush : bsp.dbrushes) { - json &brush = brushes.insert(brushes.end(), json::object()).value(); + auto &brush = brushes.append(Json::Value(Json::objectValue)); - brush.push_back({"firstside", src_brush.firstside}); - brush.push_back({"numsides", src_brush.numsides}); - brush.push_back({"contents", src_brush.contents}); + brush["firstside"] = src_brush.firstside; + brush["numsides"] = src_brush.numsides; + brush["contents"] = src_brush.contents; } } if (!bsp.dleafbrushes.empty()) { - json &leafbrushes = (j.emplace("leafbrushes", json::array())).first.value(); + auto &leafbrushes = (j["leafbrushes"] = Json::Value(Json::arrayValue)); for (auto &src_leafbrush : bsp.dleafbrushes) { - leafbrushes.push_back(src_leafbrush); + leafbrushes.append(src_leafbrush); } } if (bsp.dtex.textures.size()) { - json &textures = (j.emplace("textures", json::array())).first.value(); + auto &textures = (j["textures"] = Json::Value(Json::arrayValue)); for (auto &src_tex : bsp.dtex.textures) { if (src_tex.null_texture) { // use json null to indicate offset -1 - textures.insert(textures.end(), json(nullptr)); + textures.append(Json::Value(Json::nullValue)); continue; } - json &tex = textures.insert(textures.end(), json::object()).value(); + auto &tex = textures.append(Json::Value(Json::objectValue)); - tex.push_back({"name", src_tex.name}); - tex.push_back({"width", src_tex.width}); - tex.push_back({"height", src_tex.height}); + tex["name"] = src_tex.name; + tex["width"] = src_tex.width; + tex["height"] = src_tex.height; if (src_tex.data.size() > sizeof(dmiptex_t)) { - json &mips = tex["mips"] = json::array(); - mips.emplace_back( + auto &mips = tex["mips"] = Json::Value(Json::arrayValue); + mips.append( serialize_image(img::load_mip(src_tex.name, src_tex.data, false, bspdata.loadversion->game))); } } } if (!bspdata.bspx.entries.empty()) { - json &bspxentries = (j.emplace("bspxentries", json::array())).first.value(); + auto &bspxentries = (j["bspxentries"] = Json::Value(Json::arrayValue)); for (auto &lump : bspdata.bspx.entries) { - json &entry = bspxentries.insert(bspxentries.end(), json::object()).value(); + auto &entry = bspxentries.append(Json::Value(Json::objectValue)); entry["lumpname"] = lump.first; if (lump.first == "BRUSHLIST") { diff --git a/common/imglib.cc b/common/imglib.cc index 4b4079b0..3ae78579 100644 --- a/common/imglib.cc +++ b/common/imglib.cc @@ -372,7 +372,7 @@ std::optional load_wal_json_meta( const std::string_view &name, const fs::data &file, const gamedef_t *game) { try { - auto json = json::parse(file->begin(), file->end()); + auto json = parse_json(file->data(), file->data() + file->size()); texture_meta meta{}; @@ -386,71 +386,70 @@ std::optional load_wal_json_meta( meta = *wal_meta; } - if (json.contains("width") && json["width"].is_number_integer()) { - meta.width = json["width"].get(); + if (json.isMember("width") && json["width"].isInt()) { + meta.width = json["width"].as(); } - if (json.contains("height") && json["height"].is_number_integer()) { - meta.height = json["height"].get(); + if (json.isMember("height") && json["height"].isInt()) { + meta.height = json["height"].as(); } - if (json.contains("value") && json["value"].is_number_integer()) { - meta.value = json["value"].get(); + if (json.isMember("value") && json["value"].isInt()) { + meta.value = json["value"].as(); } - if (json.contains("contents")) { + if (json.isMember("contents")) { auto &contents = json["contents"]; - if (contents.is_number_integer()) { - meta.contents_native = contents.get(); - } else if (contents.is_string()) { - meta.contents_native = - game->contents_from_string(contents.get()); - } else if (contents.is_array()) { + if (contents.isInt()) { + meta.contents_native = contents.as(); + } else if (contents.isString()) { + meta.contents_native = game->contents_from_string(contents.as()); + } else if (contents.isArray()) { int native = 0; for (auto &content : contents) { - if (content.is_number_integer()) { - native |= content.get(); - } else if (content.is_string()) { - native |= game->contents_from_string(content.get()); + if (content.isInt()) { + native |= content.as(); + } else if (content.isString()) { + native |= game->contents_from_string(content.as()); } } meta.contents_native = native; } } - if (json.contains("flags")) { + if (json.isMember("flags")) { auto &flags = json["flags"]; - if (flags.is_number_integer()) { - meta.flags.native = flags.get(); - } else if (flags.is_string()) { - meta.flags.native = game->surfflags_from_string(flags.get()); - } else if (flags.is_array()) { + if (flags.isInt()) { + meta.flags.native = flags.as(); + } else if (flags.isString()) { + meta.flags.native = game->surfflags_from_string(flags.as()); + } else if (flags.isArray()) { for (auto &flag : flags) { - if (flag.is_number_integer()) { - meta.flags.native |= flag.get(); - } else if (flag.is_string()) { - meta.flags.native |= game->surfflags_from_string(flag.get()); + if (flag.isInt()) { + meta.flags.native |= flag.as(); + } else if (flag.isString()) { + meta.flags.native |= game->surfflags_from_string(flag.as()); } } } } - if (json.contains("animation") && json["animation"].is_string()) { - meta.animation = json["animation"].get(); + if (json.isMember("animation") && json["animation"].isString()) { + meta.animation = json["animation"].as(); } - if (json.contains("color")) { + if (json.isMember("color")) { auto &color = json["color"]; - qvec3b color_vec = {color.at(0).get(), color.at(1).get(), color.at(2).get()}; + qvec3b color_vec = {color[0].as(), color[1].as(), color[2].as()}; meta.color_override = {color_vec}; } return meta; - } catch (json::exception e) { + } catch (Json::Exception e) { logging::funcprint("{}, invalid JSON: {}\n", name, e.what()); return std::nullopt; } diff --git a/include/common/json.hh b/include/common/json.hh index d8d8ffa2..18091f75 100644 --- a/include/common/json.hh +++ b/include/common/json.hh @@ -21,25 +21,73 @@ // JSON & formatters for our types -#include +#include #include -using nlohmann::json; - template -void to_json(json &j, const qvec &p) +Json::Value to_json(const qvec &p) { - j = json::array(); + auto j = Json::Value(Json::arrayValue); for (auto &v : p) { - j.push_back(v); + j.append(v); } + + return j; +} + +template +Json::Value to_json(const std::vector &vec) +{ + auto j = Json::Value(Json::arrayValue); + + for (auto &v : vec) { + j.append(v); + } + + return j; +} + +template +Json::Value to_json(const std::array &arr) +{ + auto j = Json::Value(Json::arrayValue); + + for (auto &v : arr) { + j.append(v); + } + + return j; +} + +template +Json::Value json_array(std::initializer_list args) +{ + auto j = Json::Value(Json::arrayValue); + + for (auto &v : args) { + j.append(v); + } + + return j; } template -void from_json(const json &j, qvec &p) +qvec from_json(const Json::Value &j) { - for (size_t i = 0; i < N; i++) { - p[i] = j[i].get(); + qvec p; + for (unsigned int i = 0; i < N; i++) { + p[i] = j[i].as(); } -} \ No newline at end of file + return p; +} + +static Json::Value parse_json(const uint8_t *begin, const uint8_t *end) +{ + Json::Value result; + Json::CharReaderBuilder rbuilder; + auto reader = std::unique_ptr(rbuilder.newCharReader()); + reader->parse(reinterpret_cast(begin), + reinterpret_cast(end), &result, nullptr); + return result; +} diff --git a/light/CMakeLists.txt b/light/CMakeLists.txt index 197127f4..a5d4797b 100644 --- a/light/CMakeLists.txt +++ b/light/CMakeLists.txt @@ -42,7 +42,10 @@ if (embree_FOUND) endif(embree_FOUND) add_library(liblight STATIC ${LIGHT_SOURCES}) -target_link_libraries(liblight PRIVATE common ${CMAKE_THREAD_LIBS_INIT} fmt::fmt nlohmann_json::nlohmann_json) + +find_package(jsoncpp CONFIG REQUIRED) + +target_link_libraries(liblight PRIVATE common ${CMAKE_THREAD_LIBS_INIT} fmt::fmt JsonCpp::JsonCpp) add_executable(light main.cc) target_link_libraries(light PRIVATE common liblight) diff --git a/light/light.cc b/light/light.cc index a971fcf9..21556855 100644 --- a/light/light.cc +++ b/light/light.cc @@ -952,105 +952,104 @@ static void LoadExtendedTexinfoFlags(const fs::path &sourcefilename, const mbsp_ logging::print("Loading extended texinfo flags from {}...\n", filename); - json j; + Json::Value j; texinfofile >> j; - for (auto it = j.begin(); it != j.end(); ++it) { - size_t index = std::stoull(it.key()); - + for (auto &key : j.getMemberNames()) { + size_t index = std::stoull(key); if (index >= bsp->texinfo.size()) { logging::print("WARNING: Extended texinfo flags in {} does not match bsp, ignoring\n", filename); memset(extended_texinfo_flags.data(), 0, bsp->texinfo.size() * sizeof(surfflags_t)); return; } - auto &val = it.value(); + auto &val = j[key]; auto &flags = extended_texinfo_flags[index]; - if (val.contains("is_nodraw")) { - flags.is_nodraw = val.at("is_nodraw").get(); + if (val.isMember("is_nodraw")) { + flags.is_nodraw = val["is_nodraw"].as(); } - if (val.contains("is_hint")) { - flags.is_hint = val.at("is_hint").get(); + if (val.isMember("is_hint")) { + flags.is_hint = val["is_hint"].as(); } - if (val.contains("is_hintskip")) { - flags.is_hintskip = val.at("is_hintskip").get(); + if (val.isMember("is_hintskip")) { + flags.is_hintskip = val["is_hintskip"].as(); } - if (val.contains("no_dirt")) { - flags.no_dirt = val.at("no_dirt").get(); + if (val.isMember("no_dirt")) { + flags.no_dirt = val["no_dirt"].as(); } - if (val.contains("no_shadow")) { - flags.no_shadow = val.at("no_shadow").get(); + if (val.isMember("no_shadow")) { + flags.no_shadow = val["no_shadow"].as(); } - if (val.contains("no_bounce")) { - flags.no_bounce = val.at("no_bounce").get(); + if (val.isMember("no_bounce")) { + flags.no_bounce = val["no_bounce"].as(); } - if (val.contains("no_minlight")) { - flags.no_minlight = val.at("no_minlight").get(); + if (val.isMember("no_minlight")) { + flags.no_minlight = val["no_minlight"].as(); } - if (val.contains("no_expand")) { - flags.no_expand = val.at("no_expand").get(); + if (val.isMember("no_expand")) { + flags.no_expand = val["no_expand"].as(); } - if (val.contains("no_phong")) { - flags.no_expand = val.at("no_phong").get(); + if (val.isMember("no_phong")) { + flags.no_expand = val["no_phong"].as(); } - if (val.contains("light_ignore")) { - flags.light_ignore = val.at("light_ignore").get(); + if (val.isMember("light_ignore")) { + flags.light_ignore = val["light_ignore"].as(); } - if (val.contains("surflight_rescale")) { - flags.surflight_rescale = val.at("surflight_rescale").get(); + if (val.isMember("surflight_rescale")) { + flags.surflight_rescale = val["surflight_rescale"].as(); } - if (val.contains("surflight_style")) { - flags.surflight_style = val.at("surflight_style").get(); + if (val.isMember("surflight_style")) { + flags.surflight_style = val["surflight_style"].as(); } - if (val.contains("surflight_targetname")) { - flags.surflight_targetname = val.at("surflight_targetname").get(); + if (val.isMember("surflight_targetname")) { + flags.surflight_targetname = val["surflight_targetname"].as(); } - if (val.contains("surflight_color")) { - flags.surflight_color = val.at("surflight_color").get(); + if (val.isMember("surflight_color")) { + flags.surflight_color = from_json(val["surflight_color"]); } - if (val.contains("surflight_minlight_scale")) { - flags.surflight_minlight_scale = val.at("surflight_minlight_scale").get(); + if (val.isMember("surflight_minlight_scale")) { + flags.surflight_minlight_scale = val["surflight_minlight_scale"].as(); } - if (val.contains("phong_angle")) { - flags.phong_angle = val.at("phong_angle").get(); + if (val.isMember("phong_angle")) { + flags.phong_angle = val["phong_angle"].as(); } - if (val.contains("phong_angle_concave")) { - flags.phong_angle_concave = val.at("phong_angle_concave").get(); + if (val.isMember("phong_angle_concave")) { + flags.phong_angle_concave = val["phong_angle_concave"].as(); } - if (val.contains("phong_group")) { - flags.phong_group = val.at("phong_group").get(); + if (val.isMember("phong_group")) { + flags.phong_group = val["phong_group"].as(); } - if (val.contains("minlight")) { - flags.minlight = val.at("minlight").get(); + if (val.isMember("minlight")) { + flags.minlight = val["minlight"].as(); } - if (val.contains("maxlight")) { - flags.maxlight = val.at("maxlight").get(); + if (val.isMember("maxlight")) { + flags.maxlight = val["maxlight"].as(); } - if (val.contains("minlight_color")) { - flags.minlight_color = val.at("minlight_color").get(); + if (val.isMember("minlight_color")) { + flags.minlight_color = from_json(val["minlight_color"]); } - if (val.contains("light_alpha")) { - flags.light_alpha = val.at("light_alpha").get(); + if (val.isMember("light_alpha")) { + flags.light_alpha = val["light_alpha"].as(); } - if (val.contains("light_twosided")) { - flags.light_twosided = val.at("light_twosided").get(); + if (val.isMember("light_twosided")) { + flags.light_twosided = val["light_twosided"].as(); } - if (val.contains("lightcolorscale")) { - flags.lightcolorscale = val.at("lightcolorscale").get(); + if (val.isMember("lightcolorscale")) { + flags.lightcolorscale = val["lightcolorscale"].as(); } - if (val.contains("surflight_group")) { - flags.surflight_group = val.at("surflight_group").get(); + if (val.isMember("surflight_group")) { + flags.surflight_group = val["surflight_group"].as(); } - if (val.contains("world_units_per_luxel")) { - flags.world_units_per_luxel = val.at("world_units_per_luxel").get(); + if (val.isMember("world_units_per_luxel")) { + flags.world_units_per_luxel = val["world_units_per_luxel"].as(); } - if (val.contains("object_channel_mask")) { - flags.object_channel_mask = val.at("object_channel_mask").get(); + if (val.isMember("object_channel_mask")) { + flags.object_channel_mask = val["object_channel_mask"].as(); } - if (val.contains("surflight_minlight_scale")) { - flags.surflight_minlight_scale = val.at("surflight_minlight_scale").get(); + if (val.isMember("surflight_minlight_scale")) { + flags.surflight_minlight_scale = val["surflight_minlight_scale"].as(); } } } diff --git a/maputil/maputil.cc b/maputil/maputil.cc index fb5ed6cb..378a667f 100644 --- a/maputil/maputil.cc +++ b/maputil/maputil.cc @@ -120,20 +120,21 @@ size_t lua_count_array(lua_State *state) } // pushes value onto stack -static void json_to_lua(lua_State *state, const json &value) +static void json_to_lua(lua_State *state, const Json::Value &value) { switch (value.type()) { - case json::value_t::object: { + case Json::ValueType::objectValue: { lua_newtable(state); - for (auto it = value.begin(); it != value.end(); ++it) { - lua_pushstring(state, it.key().c_str()); - json_to_lua(state, it.value()); + for (auto &key : value.getMemberNames()) { + const Json::Value &val = value[key]; + lua_pushstring(state, key.c_str()); + json_to_lua(state, val); lua_settable(state, -3); } return; } - case json::value_t::array: { + case Json::ValueType::arrayValue: { lua_newtable(state); size_t i = 1; @@ -144,27 +145,27 @@ static void json_to_lua(lua_State *state, const json &value) } return; } - case json::value_t::string: { - lua_pushstring(state, value.get().c_str()); + case Json::ValueType::stringValue: { + lua_pushstring(state, value.asCString()); return; } - case json::value_t::number_unsigned: { - lua_pushnumber(state, value.get()); + case Json::ValueType::uintValue: { + lua_pushnumber(state, value.asUInt64()); return; } - case json::value_t::number_integer: { - lua_pushnumber(state, value.get()); + case Json::ValueType::intValue: { + lua_pushnumber(state, value.asInt64()); return; } - case json::value_t::number_float: { - lua_pushnumber(state, value.get()); + case Json::ValueType::realValue: { + lua_pushnumber(state, value.asDouble()); return; } - case json::value_t::boolean: { - lua_pushboolean(state, value.get()); + case Json::ValueType::booleanValue: { + lua_pushboolean(state, value.asBool()); return; } - case json::value_t::null: { + case Json::ValueType::nullValue: { lua_pushnil(state); return; } @@ -188,7 +189,7 @@ static int l_load_json(lua_State *state) try { - auto json = json::parse(result->begin(), result->end()); + auto json = parse_json(result->data(), result->data() + result->size()); json_to_lua(state, json); } diff --git a/qbsp/CMakeLists.txt b/qbsp/CMakeLists.txt index ee52b6eb..68023dd9 100644 --- a/qbsp/CMakeLists.txt +++ b/qbsp/CMakeLists.txt @@ -33,7 +33,10 @@ set(QBSP_SOURCES ${QBSP_INCLUDES}) add_library(libqbsp STATIC ${QBSP_SOURCES}) -target_link_libraries(libqbsp common ${CMAKE_THREAD_LIBS_INIT} TBB::tbb TBB::tbbmalloc fmt::fmt nlohmann_json::nlohmann_json pareto) + +find_package(jsoncpp CONFIG REQUIRED) + +target_link_libraries(libqbsp common ${CMAKE_THREAD_LIBS_INIT} TBB::tbb TBB::tbbmalloc fmt::fmt JsonCpp::JsonCpp pareto) add_executable(qbsp main.cc) target_link_libraries(qbsp libqbsp) diff --git a/qbsp/writebsp.cc b/qbsp/writebsp.cc index 845be046..5d4c17c9 100644 --- a/qbsp/writebsp.cc +++ b/qbsp/writebsp.cc @@ -32,7 +32,6 @@ #include #include -using nlohmann::json; /** * Returns the output plane number @@ -364,13 +363,13 @@ static void WriteExtendedTexinfoFlags() std::sort(texinfos_sorted.begin(), texinfos_sorted.end(), [](const maptexinfo_t &a, const maptexinfo_t &b) { return a.outputnum < b.outputnum; }); - json texinfofile = json::object(); + auto texinfofile = Json::Value(Json::objectValue); for (const auto &tx : texinfos_sorted) { if (!tx.outputnum.has_value() || !tx.flags.needs_write()) continue; - json t = json::object(); + auto t = Json::Value(Json::objectValue); if (tx.flags.is_nodraw) { t["is_nodraw"] = tx.flags.is_nodraw; @@ -409,7 +408,7 @@ static void WriteExtendedTexinfoFlags() t["surflight_targetname"] = tx.flags.surflight_targetname.value(); } if (tx.flags.surflight_color.has_value()) { - t["surflight_color"] = tx.flags.surflight_color.value(); + t["surflight_color"] = to_json(tx.flags.surflight_color.value()); } if (tx.flags.surflight_minlight_scale.has_value()) { t["surflight_minlight_scale"] = tx.flags.surflight_minlight_scale.value(); @@ -430,7 +429,7 @@ static void WriteExtendedTexinfoFlags() t["maxlight"] = tx.flags.maxlight; } if (!qv::emptyExact(tx.flags.minlight_color)) { - t["minlight_color"] = tx.flags.minlight_color; + t["minlight_color"] = to_json(tx.flags.minlight_color); } if (tx.flags.light_alpha) { t["light_alpha"] = *tx.flags.light_alpha;