diff --git a/CMakeLists.txt b/CMakeLists.txt index 657100a2..73aafbc3 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -28,11 +28,11 @@ set(COMMON_INCLUDES ${CMAKE_SOURCE_DIR}/include/common/mathlib.hh ${CMAKE_SOURCE_DIR}/include/common/polylib.hh ${CMAKE_SOURCE_DIR}/include/common/threads.hh - ${CMAKE_SOURCE_DIR}/include/common/bsputils.hh) + ${CMAKE_SOURCE_DIR}/include/common/bsputils.hh + ${CMAKE_SOURCE_DIR}/include/common/parser.hh) set(QBSP_INCLUDES ${CMAKE_SOURCE_DIR}/include/qbsp/file.hh - ${CMAKE_SOURCE_DIR}/include/qbsp/parser.hh ${CMAKE_SOURCE_DIR}/include/qbsp/qbsp.hh ${CMAKE_SOURCE_DIR}/include/qbsp/wad.hh ${CMAKE_SOURCE_DIR}/include/qbsp/brush.hh @@ -59,6 +59,7 @@ set(QBSP_SOURCES ${CMAKE_SOURCE_DIR}/common/mesh.cc ${CMAKE_SOURCE_DIR}/common/mathlib.cc ${CMAKE_SOURCE_DIR}/common/bsputils.cc + ${CMAKE_SOURCE_DIR}/common/parser.cc ${CMAKE_SOURCE_DIR}/qbsp/brush.cc ${CMAKE_SOURCE_DIR}/qbsp/csg4.cc ${CMAKE_SOURCE_DIR}/qbsp/file.cc @@ -66,7 +67,6 @@ set(QBSP_SOURCES ${CMAKE_SOURCE_DIR}/qbsp/map.cc ${CMAKE_SOURCE_DIR}/qbsp/merge.cc ${CMAKE_SOURCE_DIR}/qbsp/outside.cc - ${CMAKE_SOURCE_DIR}/qbsp/parser.cc ${CMAKE_SOURCE_DIR}/qbsp/portals.cc ${CMAKE_SOURCE_DIR}/qbsp/qbsp.cc ${CMAKE_SOURCE_DIR}/qbsp/solidbsp.cc diff --git a/bspinfo/CMakeLists.txt b/bspinfo/CMakeLists.txt index e56c0406..fdc2d5a6 100644 --- a/bspinfo/CMakeLists.txt +++ b/bspinfo/CMakeLists.txt @@ -5,6 +5,7 @@ set(BSPINFO_SOURCES ${CMAKE_SOURCE_DIR}/common/bspfile.cc ${CMAKE_SOURCE_DIR}/common/log.cc ${CMAKE_SOURCE_DIR}/common/threads.cc + ${CMAKE_SOURCE_DIR}/common/parser.cc ${COMMON_INCLUDES}) add_executable(bspinfo ${BSPINFO_SOURCES}) diff --git a/bsputil/CMakeLists.txt b/bsputil/CMakeLists.txt index 42c0b40d..922ca25f 100644 --- a/bsputil/CMakeLists.txt +++ b/bsputil/CMakeLists.txt @@ -10,6 +10,7 @@ set(BSPUTIL_SOURCES ${CMAKE_SOURCE_DIR}/common/qvec.cc ${CMAKE_SOURCE_DIR}/common/log.cc ${CMAKE_SOURCE_DIR}/common/threads.cc + ${CMAKE_SOURCE_DIR}/common/parser.cc ${COMMON_INCLUDES}) add_executable(bsputil ${BSPUTIL_SOURCES}) diff --git a/common/cmdlib.cc b/common/cmdlib.cc index 678ae442..02ebba10 100644 --- a/common/cmdlib.cc +++ b/common/cmdlib.cc @@ -131,88 +131,6 @@ void SetQdirFromPath(const std::string &basedirname, std::filesystem::path path) } } -/* - * ============== - * COM_Parse - * Parse a token out of a string - * ============== - */ -const char *COM_Parse(const char *data) -{ - int c; - int len; - - len = 0; - com_token[0] = 0; - - if (!data) - return NULL; - - /* skip whitespace */ -skipwhite: - while ((c = *data) <= ' ') { - if (c == 0) { - com_eof = true; - return NULL; /* end of file; */ - } - data++; - } - - /* skip // (double forward slash) comments */ - if (c == '/' && data[1] == '/') { - while (*data && *data != '\n') - data++; - goto skipwhite; - } - - /* skip C-style comments */ - if (c == '/' && data[1] == '*') { - data += 2; - while (*data && !(*data == '*' && data[1] == '/')) - data++; - if (*data) - data += 2; - goto skipwhite; - } - - /* handle quoted strings specially */ - if (c == '\"') { - data++; - do { - c = *data; - if (c) - data++; - if (c == '\"') { - com_token[len] = 0; - return data; - } - com_token[len] = c; - len++; - } while (1); - } - - /* parse single characters */ - if (c == '{' || c == '}' || c == ')' || c == '(' || c == '\'' || c == ':') { - com_token[len] = c; - len++; - com_token[len] = 0; - return data + 1; - } - - /* parse a regular word */ - do { - com_token[len] = c; - data++; - len++; - c = *data; - if (c == '{' || c == '}' || c == ')' || c == '(' || c == '\'' || c == ':') - break; - } while (c > 32); - - com_token[len] = 0; - return data; -} - int Q_strncasecmp(const char *s1, const char *s2, int n) { int c1, c2; diff --git a/common/entdata.cc b/common/entdata.cc index 3d61c7f3..a51c798d 100644 --- a/common/entdata.cc +++ b/common/entdata.cc @@ -27,6 +27,7 @@ #include #include #include +#include #include @@ -116,16 +117,15 @@ keyvalues_t::iterator entdict_t::end() std::vector EntData_Parse(const char *entdata) { std::vector result; - const char *data = entdata; + parser_t parser(entdata); /* go through all the entities */ while (1) { /* parse the opening brace */ - data = COM_Parse(data); - if (!data) + if (!parser.parse_token()) break; - if (com_token[0] != '{') - FError("found {} when expecting {", com_token); + if (parser.token != "{") + FError("found {} when expecting {", parser.token); /* Allocate a new entity */ entdict_t entity; @@ -133,30 +133,26 @@ std::vector EntData_Parse(const char *entdata) /* go through all the keys in this entity */ while (1) { /* parse key */ - data = COM_Parse(data); - if (!data) + if (!parser.parse_token()) FError("EOF without closing brace"); - std::string keystr{com_token}; - - if (keystr == "}") + if (parser.token == "}") break; - if (keystr.length() > MAX_ENT_KEY - 1) - FError("Key length > {}: '{}'", MAX_ENT_KEY - 1, keystr); + if (parser.token.length() > MAX_ENT_KEY - 1) + FError("Key length > {}: '{}'", MAX_ENT_KEY - 1, parser.token); + + std::string keystr = parser.token; /* parse value */ - data = COM_Parse(data); - if (!data) + if (!parser.parse_token()) FError("EOF without closing brace"); - std::string valstring{com_token}; - - if (valstring[0] == '}') + if (parser.token == "}") FError("closing brace without data"); - if (valstring.length() > MAX_ENT_VALUE - 1) + if (parser.token.length() > MAX_ENT_VALUE - 1) FError("Value length > {}", MAX_ENT_VALUE - 1); - entity.set(keystr, valstring); + entity.set(keystr, parser.token); } result.push_back(entity); diff --git a/qbsp/parser.cc b/common/parser.cc similarity index 99% rename from qbsp/parser.cc rename to common/parser.cc index 1bc872b5..f0138bca 100644 --- a/qbsp/parser.cc +++ b/common/parser.cc @@ -20,7 +20,7 @@ */ #include -#include +#include bool parser_t::parse_token(parseflags flags) { diff --git a/include/common/cmdlib.hh b/include/common/cmdlib.hh index cffa9c82..7290fccc 100644 --- a/include/common/cmdlib.hh +++ b/include/common/cmdlib.hh @@ -156,11 +156,6 @@ int LittleLong(int l); float BigFloat(float l); float LittleFloat(float l); -const char *COM_Parse(const char *data); - -extern char com_token[1024]; -extern bool com_eof; - // temporary #ifdef _WIN32 #define copystring _strdup diff --git a/include/qbsp/parser.hh b/include/common/parser.hh similarity index 100% rename from include/qbsp/parser.hh rename to include/common/parser.hh diff --git a/include/common/qvec.hh b/include/common/qvec.hh index de855b50..5f329f8e 100644 --- a/include/common/qvec.hh +++ b/include/common/qvec.hh @@ -546,5 +546,54 @@ qmat4x4d inverse(const qmat4x4d &input); qmat2x2f inverse(const qmat2x2f &input); }; // namespace qv -// TODO: bounds type -using qboundsd = std::array; \ No newline at end of file +template +struct qbounds +{ + using vec = qvec<3, T>; + + vec mins, maxs; + + // default constructor is an "empty" bounds + constexpr qbounds() : + mins(VECT_MAX, VECT_MAX, VECT_MAX), + maxs(-VECT_MAX, -VECT_MAX, -VECT_MAX) + { + } + + // construct from mins/maxs + constexpr qbounds(const vec &mins, const vec &maxs) : + mins(mins), + maxs(maxs) + { + } + + // add point to bounds + constexpr qbounds &operator+=(const vec &v) + { + mins = qv::min(mins, v); + maxs = qv::max(maxs, v); + + return *this; + } + + // add bounds to bounds + constexpr qbounds &operator+=(const qbounds &v) + { + mins = qv::min(mins, v.mins); + maxs = qv::max(maxs, v.maxs); + + return *this; + } + + constexpr vec &operator[](const int32_t &index) + { + return (index == 0 ? mins : index == 1 ? maxs : throw std::exception()); + } + + constexpr const vec &operator[](const int32_t &index) const + { + return (index == 0 ? mins : index == 1 ? maxs : throw std::exception()); + } +}; + +using qboundsd = qbounds; \ No newline at end of file diff --git a/include/qbsp/map.hh b/include/qbsp/map.hh index d705caa6..74e33463 100644 --- a/include/qbsp/map.hh +++ b/include/qbsp/map.hh @@ -21,7 +21,7 @@ #pragma once -#include +#include #include "common/cmdlib.hh" #include diff --git a/light/CMakeLists.txt b/light/CMakeLists.txt index c0dd6f54..f42bfe60 100644 --- a/light/CMakeLists.txt +++ b/light/CMakeLists.txt @@ -30,6 +30,7 @@ set(LIGHT_SOURCES ${CMAKE_SOURCE_DIR}/common/log.cc ${CMAKE_SOURCE_DIR}/common/threads.cc ${CMAKE_SOURCE_DIR}/common/bsputils.cc + ${CMAKE_SOURCE_DIR}/common/parser.cc ${COMMON_INCLUDES} ${LIGHT_INCLUDES}) diff --git a/light/entities.cc b/light/entities.cc index 3f942258..03918826 100644 --- a/light/entities.cc +++ b/light/entities.cc @@ -21,6 +21,7 @@ #include #include #include +#include #include #include @@ -1466,22 +1467,22 @@ bool ParseLightsFile(const std::filesystem::path &fname) { std::getline(f, buf); - const char *t = COM_Parse(buf.c_str()); + parser_t parser(buf.c_str()); - if (!t) + if (!parser.parse_token()) continue; entdict_t d {}; - d.set("_surface", com_token); - t = COM_Parse(t); - float r = atof(com_token); - t = COM_Parse(t); - float g = atof(com_token); - t = COM_Parse(t); - float b = atof(com_token); + d.set("_surface", parser.token); + parser.parse_token(); + float r = std::stof(parser.token); + parser.parse_token(); + float g = std::stof(parser.token); + parser.parse_token(); + float b = std::stof(parser.token); d.set("_color", fmt::format("{} {} {}", r, g, b)); - t = COM_Parse(t); - d.set("light", com_token); + parser.parse_token(); + d.set("light", parser.token); // might be hdr rgbi values here radlights.push_back(d); diff --git a/qbsp/brush.cc b/qbsp/brush.cc index a8b8875e..674ca0df 100644 --- a/qbsp/brush.cc +++ b/qbsp/brush.cc @@ -980,7 +980,7 @@ brush_t *LoadBrush(const mapentity_t *src, const mapbrush_t *mapbrush, const con return NULL; } - if (hullnum) { + if (hullnum > 0) { auto &hulls = options.target_game->get_hull_sizes(); Q_assert(hullnum < hulls.size()); ExpandBrush(&hullbrush, *(hulls.begin() + hullnum), facelist); diff --git a/qbsp/map.cc b/qbsp/map.cc index 37b1fe07..5ef8b162 100644 --- a/qbsp/map.cc +++ b/qbsp/map.cc @@ -33,7 +33,7 @@ #include #include -#include +#include #include #include diff --git a/qbsp/qbsp.cc b/qbsp/qbsp.cc index 9dbb6651..575c6275 100644 --- a/qbsp/qbsp.cc +++ b/qbsp/qbsp.cc @@ -480,7 +480,10 @@ static void UpdateEntLump(void) UpdateBSPFileEntitiesLump(); if (!options.fAllverbose) + { options.fVerbose = false; + log_mask &= ~((1 << LOG_STAT) | (1 << LOG_PROGRESS)); + } } /* @@ -709,7 +712,10 @@ static void CreateSingleHull(const int hullnum) entity = &map.entities.at(i); ProcessEntity(entity, hullnum); if (!options.fAllverbose) + { options.fVerbose = false; // don't print rest of entities + log_mask &= ~((1 << LOG_STAT) | (1 << LOG_PROGRESS)); + } } } @@ -723,7 +729,10 @@ static void CreateHulls(void) { /* create the hulls sequentially */ if (!options.fNoverbose) - options.fVerbose = true; + { + options.fVerbose = true; + log_mask |= (1 << LOG_STAT) | (1 << LOG_PROGRESS); + } auto &hulls = options.target_game->get_hull_sizes(); @@ -802,7 +811,10 @@ static void ProcessFile(void) BeginBSPFile(); if (!options.fAllverbose) + { options.fVerbose = false; + log_mask &= ~((1 << LOG_STAT) | (1 << LOG_PROGRESS)); + } CreateHulls(); WriteEntitiesToString(); diff --git a/vis/CMakeLists.txt b/vis/CMakeLists.txt index 0c535523..e5a581bc 100644 --- a/vis/CMakeLists.txt +++ b/vis/CMakeLists.txt @@ -18,6 +18,7 @@ set(VIS_SOURCES ${CMAKE_SOURCE_DIR}/common/bspfile.cc ${CMAKE_SOURCE_DIR}/common/log.cc ${CMAKE_SOURCE_DIR}/common/threads.cc + ${CMAKE_SOURCE_DIR}/common/parser.cc ${COMMON_INCLUDES} ${VIS_INCLUDES})