diff --git a/ReflexToQ3/includes/oopless-parser.cpp b/ReflexToQ3/includes/oopless-parser.cpp index 023b02b..2377b38 100644 --- a/ReflexToQ3/includes/oopless-parser.cpp +++ b/ReflexToQ3/includes/oopless-parser.cpp @@ -1,9 +1,3 @@ -#define KEYWORD_ENTITY "entity" -#define KEYWORD_BRUSH "brush" -#define KEYWORD_VERTICES "vertices" -#define KEYWORD_FACES "faces" -#define KEYWORD_GLOBAL "global" -#define KEYWORD_PREFAB "prefab" #include "oopless-parser.hpp" #include "brushdef.hpp" @@ -17,8 +11,8 @@ bool is_ebrush(std::vector input) { #define KEYWORD_ENTBRUSH1 "type Teleporter" #define KEYWORD_ENTBRUSH2 "type JumpPad" for (const string &str : input) { - if (str.compare(KEYWORD_ENTBRUSH1) == 0 || - str.compare(KEYWORD_ENTBRUSH2) == 0) { + if (str.find(KEYWORD_ENTBRUSH1) != string::npos || + str.find(KEYWORD_ENTBRUSH2) != string::npos) { return true; } } @@ -70,123 +64,13 @@ vector get_entity(ifstream &f) { } } -vector parse_vertices(ifstream &f) { -#define FIRSTCH(x) x[0] - vector output; - string line; - unsigned int pos = f.tellg(); - while(getline(f, line)) { - if (line.find(KEYWORD_FACES) != string::npos || - line.find(KEYWORD_BRUSH) != string::npos || - line.find(KEYWORD_ENTITY) != string::npos || - line.find(KEYWORD_PREFAB) != string::npos) { - f.seekg(pos); - return output; - } else { - Eigen::Vector3f v; - stringstream ss(line); - string vdata; - unsigned int i = 0; - while (ss >> vdata) { - if (isdigit(FIRSTCH(vdata)) || FIRSTCH(vdata) == '-') { - double dvalue = stod(vdata); - v[i] = (float)dvalue; - } - // note: this prevents the index growing out of vector capacity - // alternatively can throw an exception when that happens instead - // to make it clear that an illegal line has been hit. - i = (i + 1) % 3; - } - output.push_back(v); - } - pos = f.tellg(); - } - return output; -} - -vector parse_face(ifstream &f) { -#define FIRSTCH(x) x[0] -#define SECONDCH(x) x[1] - // it is possible for the next line to be unrelated to faces - // so it is needed to reset the stream prior to reading - // the new label, e.g '\tbrush'. - vector output; - string line; - unsigned int pos = f.tellg(); - while(getline(f, line)) { - if (line.find(KEYWORD_VERTICES) != string::npos || - line.find(KEYWORD_BRUSH) != string::npos || - line.find(KEYWORD_ENTITY) != string::npos || - line.find(KEYWORD_PREFAB) != string::npos || - line.find(KEYWORD_GLOBAL) != string::npos) { - f.seekg(pos); - return output; - } else { - struct TFace x; - float *f = &x.m_fXOffset;; - stringstream ss(line); - string fdata; - bool hex = false; - unsigned int i = 0; - while (ss >> fdata) { - if (i < 5) { - if (isdigit(FIRSTCH(fdata)) || FIRSTCH(fdata) == '-') { - double dvalue = stod(fdata); - *f = (float)dvalue; - f++; - } - // note: if there is a non-digit in the first 5 fields - // then it qualifies as an illegal line. - } else if (4 < i && i < 8) { - x.m_Indices.push_back(stoi(fdata)); - } else if (8 <= i) { - if (!hex && fdata.length() > 1) { - if (SECONDCH(fdata) == 'x') { - // this is the unidentified hex digit. - // out of range for stoi - x.hex = strtoul(fdata.c_str(), NULL, 16); - hex = true; - } - } else if (!hex) { - x.m_Indices.push_back(stoi(fdata)); - } else if (hex) { - x.m_Material = fdata; - } else { - ; - } - } - i++; - } // end, per field iteration - output.push_back(x); - } // end else case, if line did not contain other keywords - pos = f.tellg(); - } // end, per line iteration - // the odd case when the map file ends with a face indent. - return output; -} - -struct TBrush parse_brush(ifstream &f) { - struct TBrush output; - string l; - getline(f, l); - // wip: note must return the entire brush, adjust control flow - if (l.find(KEYWORD_VERTICES) != string::npos) { - output.m_Vertices = parse_vertices(f); - } - getline(f, l); - if (l.find(KEYWORD_FACES) != string::npos) { - output.m_Faces = parse_face(f); - } - return output; -} - void parse_prefab(ifstream &f, ofstream &out, void (*b) (stringstream &, const vector &)) { string l; getline(f, l); if (l.find(KEYWORD_BRUSH) != string::npos) { - write(parse_brush(f), out, b); + write(parse_brush(f), out, b); } else if (l.find(KEYWORD_ENTITY) != string::npos) { write(get_entity(f), out); } @@ -218,7 +102,7 @@ bool convertmap(const char * const infile, } else if (line.find(KEYWORD_ENTITY) != string::npos) { write(get_entity(fin), fout); } else if (line.find(KEYWORD_BRUSH) != string::npos) { - write(parse_brush(fin), fout, brushdef); + write(parse_brush(fin), fout, brushdef); } } fout << "}" << endl; diff --git a/ReflexToQ3/includes/oopless-parser.hpp b/ReflexToQ3/includes/oopless-parser.hpp index dfae25b..ab1f6e3 100644 --- a/ReflexToQ3/includes/oopless-parser.hpp +++ b/ReflexToQ3/includes/oopless-parser.hpp @@ -8,7 +8,7 @@ #include #include - +bool is_ebrush(std::vector); bool write(const struct TBrush &, std::ofstream &, @@ -18,12 +18,6 @@ void write(const std::vector &, std::ofstream &); std::vector get_entity(std::ifstream &); -std::vector parse_vertices(std::ifstream &); - -std::vector parse_face(std::ifstream &); - -struct TBrush parse_brush(std::ifstream &); - void parse_prefab(std::ifstream &, std::ofstream &, void (*f) (std::stringstream &, const std::vector &)); @@ -32,4 +26,126 @@ bool convertmap(const char * const, const char * const, void (*f) (std::stringstream &, const std::vector &)); +#define KEYWORD_ENTITY "entity" +#define KEYWORD_BRUSH "brush" +#define KEYWORD_VERTICES "vertices" +#define KEYWORD_FACES "faces" +#define KEYWORD_GLOBAL "global" +#define KEYWORD_PREFAB "prefab" + +template +std::vector parse_vertices(T &f) { +using namespace std; +#define FIRSTCH(x) x[0] + vector output; + string line; + unsigned int pos = f.tellg(); + while(getline(f, line)) { + if (line.find(KEYWORD_FACES) != string::npos || + line.find(KEYWORD_BRUSH) != string::npos || + line.find(KEYWORD_ENTITY) != string::npos || + line.find(KEYWORD_PREFAB) != string::npos) { + f.seekg(pos); + return output; + } else { + Eigen::Vector3f v; + stringstream ss(line); + string vdata; + unsigned int i = 0; + while (ss >> vdata) { + if (isdigit(FIRSTCH(vdata)) || FIRSTCH(vdata) == '-') { + double dvalue = stod(vdata); + v[i] = (float)dvalue; + } + // note: this prevents the index growing out of vector capacity + // alternatively can throw an exception when that happens instead + // to make it clear that an illegal line has been hit. + i = (i + 1) % 3; + } + output.push_back(v); + } + pos = f.tellg(); + } + return output; +} + +template +std::vector parse_face(T &f) { +using namespace std; +#define FIRSTCH(x) x[0] +#define SECONDCH(x) x[1] + // it is possible for the next line to be unrelated to faces + // so it is needed to reset the stream prior to reading + // the new label, e.g '\tbrush'. + vector output; + string line; + unsigned int pos = f.tellg(); + while(getline(f, line)) { + if (line.find(KEYWORD_VERTICES) != string::npos || + line.find(KEYWORD_BRUSH) != string::npos || + line.find(KEYWORD_ENTITY) != string::npos || + line.find(KEYWORD_PREFAB) != string::npos || + line.find(KEYWORD_GLOBAL) != string::npos) { + f.seekg(pos); + return output; + } else { + struct TFace x; + float *f = &x.m_fXOffset;; + stringstream ss(line); + string fdata; + bool hex = false; + unsigned int i = 0; + while (ss >> fdata) { + if (i < 5) { + if (isdigit(FIRSTCH(fdata)) || FIRSTCH(fdata) == '-') { + double dvalue = stod(fdata); + *f = (float)dvalue; + f++; + } + // note: if there is a non-digit in the first 5 fields + // then it qualifies as an illegal line. + } else if (4 < i && i < 8) { + x.m_Indices.push_back(stoi(fdata)); + } else if (8 <= i) { + if (!hex && fdata.length() > 1) { + if (SECONDCH(fdata) == 'x') { + // this is the unidentified hex digit. + // out of range for stoi + x.hex = strtoul(fdata.c_str(), NULL, 16); + hex = true; + } + } else if (!hex) { + x.m_Indices.push_back(stoi(fdata)); + } else if (hex) { + x.m_Material = fdata; + } else { + ; + } + } + i++; + } // end, per field iteration + output.push_back(x); + } // end else case, if line did not contain other keywords + pos = f.tellg(); + } // end, per line iteration + // the odd case when the map file ends with a face indent. + return output; +} + +template +struct TBrush parse_brush(T &f) { +using namespace std; + struct TBrush output; + string l; + getline(f, l); + if (l.find(KEYWORD_VERTICES) != string::npos) { + output.m_Vertices = parse_vertices(f); + } + getline(f, l); + if (l.find(KEYWORD_FACES) != string::npos) { + output.m_Faces = parse_face(f); + } + return output; +} + #endif \ No newline at end of file