From 9eb48c8ff86c42fd2a9ee84370484a562279f158 Mon Sep 17 00:00:00 2001 From: <> Date: Fri, 5 May 2017 17:11:22 -0700 Subject: [PATCH] new parser fully converts geometry (tested with empty.map) --- ReflexToQ3/wip/oopless-parser.cpp | 75 +++++++++++++++++++------- ReflexToQ3/wip/oopless-parser.hpp | 27 ++++++---- ReflexToQ3/wip/test-oopless-parser.cpp | 3 ++ 3 files changed, 78 insertions(+), 27 deletions(-) diff --git a/ReflexToQ3/wip/oopless-parser.cpp b/ReflexToQ3/wip/oopless-parser.cpp index 8c395ad..ccbb07f 100644 --- a/ReflexToQ3/wip/oopless-parser.cpp +++ b/ReflexToQ3/wip/oopless-parser.cpp @@ -8,24 +8,38 @@ #define KEYWORD_PREFAB "prefab" #include "oopless-parser.hpp" +#include "brushdef.hpp" #include #include using namespace std; - -void write(const struct TBrush &object, const char * const fn) { - ; +// place holding functions to test proper control flow. +bool write(const struct TBrush &geometry, + ofstream &fout, + void (*b) (stringstream &, const vector &)) { + bool ok = true; + if (geometry.m_Vertices.size() < 1) { + cerr << "error: geometry has no vertices" << endl; + ok = false; + } + if (geometry.m_Faces.size() < 1) { + cerr << "error: geometry has no faces"<< endl; + ok = false; + } + if (ok) { + fout << GetBrushString(geometry, b); + } + return ok; } - -void write(const vector &entity, const char * const fn) { +void write(const vector &entity, ofstream &fo) { ; } // entities will vary widely depending on their type and available flags. // for now, acquire entity data, and handle their conversion in the write methods. -vector get_entity(ifstream & f) { +vector get_entity(ifstream &f) { vector output; string line; unsigned int pos = f.tellg(); @@ -38,6 +52,7 @@ vector get_entity(ifstream & f) { } else { output.push_back(line); } + pos = f.tellg(); } } @@ -60,17 +75,22 @@ vector parse_vertices(ifstream &f) { unsigned int i = 0; while (ss >> vdata) { if (isdigit(FIRSTCH(vdata)) || FIRSTCH(vdata) == '-') { - v[i] = stod(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) { +vector parse_face(ifstream &f) { #define FIRSTCH(x) x[0] // it is possible for the next line to be unrelated to faces // so it is needed to reset the stream prior to reading @@ -98,6 +118,8 @@ vector parse_face(ifstream & f) { *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 (i == 9) { ; } else { @@ -117,48 +139,65 @@ vector parse_face(ifstream & f) { return output; } -struct TBrush parse_brush(ifstream & f) { +struct TBrush parse_brush(ifstream &f) { struct TBrush output; string l; getline(f, l); - cout << l << endl; // wip: note must return the entire brush, adjust control flow if (l.find(KEYWORD_VERTICES) != string::npos) { output.m_Vertices = parse_vertices(f); - } else if (l.find(KEYWORD_FACES) != string::npos) { + } + getline(f, l); + if (l.find(KEYWORD_FACES) != string::npos) { output.m_Faces = parse_face(f); } return output; } -void parse_prefab(ifstream & f, const char * const out) { +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); + write(parse_brush(f), out, b); } else if (l.find(KEYWORD_ENTITY) != string::npos) { write(get_entity(f), out); } } -bool loadmap(const char* infile, const char * const outfile) { +// note: can't use a single function pointer for variadic overloaded write function? +bool convertmap(const char * const infile, + const char * const outfile, + void (*brushdef) (stringstream &, const vector &)) { ifstream fin; fin.open(infile); if (!fin.good()){ + cerr << "error: failed to open input file" << endl; return false; } - // reflex maps start with a line saying which version it is, + ofstream fout; + fout.open(outfile); + if (!fout.good()) { + cerr << "error: failed to open output file" << endl; + return false; + } + fout << "{\n" + << "\"classname\" \"worldspawn\"" << endl; string line; while (getline(fin, line)) { + cout << line << endl; if (line.find(KEYWORD_PREFAB) != string::npos || line.find(KEYWORD_GLOBAL) != string::npos) { - parse_prefab(fin, outfile); + parse_prefab(fin, fout, brushdef); } else if (line.find(KEYWORD_ENTITY) != string::npos) { - write(get_entity(fin), outfile); + write(get_entity(fin), fout); } else if (line.find(KEYWORD_BRUSH) != string::npos) { - write(parse_brush(fin), outfile); + write(parse_brush(fin), fout, brushdef); } } + fout << "}" << endl; fin.close(); + fout.close(); return true; } diff --git a/ReflexToQ3/wip/oopless-parser.hpp b/ReflexToQ3/wip/oopless-parser.hpp index 1e8721f..dfae25b 100644 --- a/ReflexToQ3/wip/oopless-parser.hpp +++ b/ReflexToQ3/wip/oopless-parser.hpp @@ -2,25 +2,34 @@ #ifndef __OOPLESS_PARSER__ #define __OOPLESS_PARSER__ +#include "planes.h" #include "worldspawn.h" +#include #include #include -#include -void write(const TBrush &object, const char * const fn); -void write(const std::vector &object, const char * const fn); -std::vector get_entity(std::ifstream &f); +bool write(const struct TBrush &, + std::ofstream &, + void (*f) (std::stringstream &, const std::vector &)); -std::vector parse_vertices(std::ifstream &f); +void write(const std::vector &, std::ofstream &); -std::vector parse_face(std::ifstream & f); +std::vector get_entity(std::ifstream &); -struct TBrush parse_brush(std::ifstream & f); +std::vector parse_vertices(std::ifstream &); -void parse_prefab(std::ifstream & f, const char * const out); +std::vector parse_face(std::ifstream &); -bool loadmap(const char* infile, const char * const outfile); +struct TBrush parse_brush(std::ifstream &); + +void parse_prefab(std::ifstream &, + std::ofstream &, + void (*f) (std::stringstream &, const std::vector &)); + +bool convertmap(const char * const, + const char * const, + void (*f) (std::stringstream &, const std::vector &)); #endif \ No newline at end of file diff --git a/ReflexToQ3/wip/test-oopless-parser.cpp b/ReflexToQ3/wip/test-oopless-parser.cpp index 994ad32..9d32893 100644 --- a/ReflexToQ3/wip/test-oopless-parser.cpp +++ b/ReflexToQ3/wip/test-oopless-parser.cpp @@ -1,5 +1,6 @@ #include "oopless-parser.hpp" +#include "brushdef.hpp" #include using namespace std; @@ -71,4 +72,6 @@ int main() { //loadmap("empty.map", "empty-test.map"); test_parsevertices("empty.map", 10); test_parseface("empty.map", 19); + test_parseface("pocket-infinity.map", 16); + convertmap("empty.map", "test-empty.map", &brushdef_net); }