diff --git a/ReflexToQ3/wip/oopless-parser.cpp b/ReflexToQ3/wip/oopless-parser.cpp new file mode 100644 index 0000000..8c395ad --- /dev/null +++ b/ReflexToQ3/wip/oopless-parser.cpp @@ -0,0 +1,164 @@ + + +#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 +#include +using namespace std; + + + +void write(const struct TBrush &object, const char * const fn) { + ; +} + + +void write(const vector &entity, const char * const fn) { + ; +} + +// 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 output; + string line; + unsigned int pos = f.tellg(); + while (getline(f, line)) { + if (line.find(KEYWORD_ENTITY) != string::npos || + line.find(KEYWORD_BRUSH) != string::npos || + line.find(KEYWORD_PREFAB) != string::npos) { + f.seekg(pos); + return output; + } else { + output.push_back(line); + } + } +} + +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) == '-') { + v[i] = stod(vdata); + } + i = (i + 1) % 3; + } + } + pos = f.tellg(); + } + return output; +} + +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 + // 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) { + f.seekg(pos); + return output; + } else { + struct TFace x; + float *f = &x.m_fXOffset;; + stringstream ss(line); + string fdata; + unsigned int i = 0; + while (ss >> fdata) { + if (i < 5) { + if (isdigit(FIRSTCH(fdata)) || FIRSTCH(fdata) == '-') { + double dvalue = stod(fdata); + *f = (float)dvalue; + f++; + } + } else if (i == 9) { + ; + } else { + if (isdigit(FIRSTCH(fdata)) || FIRSTCH(fdata) == '-') { + x.m_Indices.push_back(stoi(fdata)); + } else { + x.m_Material = fdata; + } + } + i++; + } // end, per field iteration + output.push_back(x); + } + 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); + 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) { + output.m_Faces = parse_face(f); + } + return output; +} + +void parse_prefab(ifstream & f, const char * const out) { + string l; + getline(f, l); + if (l.find(KEYWORD_BRUSH) != string::npos) { + write(parse_brush(f), out); + } else if (l.find(KEYWORD_ENTITY) != string::npos) { + write(get_entity(f), out); + } +} + +bool loadmap(const char* infile, const char * const outfile) { + ifstream fin; + fin.open(infile); + if (!fin.good()){ + return false; + } + // reflex maps start with a line saying which version it is, + string line; + while (getline(fin, line)) { + if (line.find(KEYWORD_PREFAB) != string::npos || + line.find(KEYWORD_GLOBAL) != string::npos) { + parse_prefab(fin, outfile); + } else if (line.find(KEYWORD_ENTITY) != string::npos) { + write(get_entity(fin), outfile); + } else if (line.find(KEYWORD_BRUSH) != string::npos) { + write(parse_brush(fin), outfile); + } + } + fin.close(); + return true; +} diff --git a/ReflexToQ3/wip/oopless-parser.hpp b/ReflexToQ3/wip/oopless-parser.hpp new file mode 100644 index 0000000..1e8721f --- /dev/null +++ b/ReflexToQ3/wip/oopless-parser.hpp @@ -0,0 +1,26 @@ + +#ifndef __OOPLESS_PARSER__ +#define __OOPLESS_PARSER__ + +#include "worldspawn.h" +#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); + +std::vector parse_vertices(std::ifstream &f); + +std::vector parse_face(std::ifstream & f); + +struct TBrush parse_brush(std::ifstream & f); + +void parse_prefab(std::ifstream & f, const char * const out); + +bool loadmap(const char* infile, const char * const outfile); + +#endif \ No newline at end of file diff --git a/ReflexToQ3/wip/test-oopless-parser.cpp b/ReflexToQ3/wip/test-oopless-parser.cpp new file mode 100644 index 0000000..994ad32 --- /dev/null +++ b/ReflexToQ3/wip/test-oopless-parser.cpp @@ -0,0 +1,74 @@ + +#include "oopless-parser.hpp" +#include +using namespace std; + +void print_TFace(const TFace x, int i) { + cout << "----------------------------" << endl; + cout << "TFace #" << i << endl; + cout << "\tOffset X: " << x.m_fXOffset << endl; + cout << "\tOffset Y: " << x.m_fYOffset << endl; + cout << "\tScale X: " << x.m_fXScale << endl; + cout << "\tScale Y: " << x.m_fYScale << endl; + cout << "\tRotation: " << x.m_fRotation << endl; + for (unsigned int i = 0; i < x.m_Indices.size(); ++i) { + cout << x.m_Indices[i] << ", "; + } + cout << "\n\tMaterial: " << x.m_Material << endl; + cout << "----------------------------" << endl; +} + +// jump to a line in fstream +// this is to set the stream position to test individual parsing functions. +void gotoline(ifstream &f, unsigned int n) { + string t; + for (unsigned int i = 0; i < n; ++i) { + getline(f, t); + } +} + +void test_parsevertices (const char * const fn, const int ln) { + ifstream fin; + fin.open(fn); + string line; + gotoline(fin, ln); + vector x = parse_vertices(fin); + cout << "size has a size of " << x.size() << endl; + // display data retrieved. + for (unsigned int i = 0; i < x.size(); ++i) { + for (unsigned int j = 0; j < 3; ++j) { + cout << x[i][j] << "\t"; + } + cout << endl; + } + getline(fin, line); + cout << "check stream state \n current line: " << endl; + cout << line << endl; + fin.close(); +} + +// test if faces are parsing correctly +void test_parseface(const char * const fn, const int ln) { + ifstream fin; + fin.open(fn); + string line; + gotoline(fin, ln); + vector x = parse_face(fin); + cout << "size has a size of " << x.size() << endl; + // display data retrieved. + for (unsigned int i = 0; i < x.size(); ++i) { + print_TFace(x[i], i); + } + // parse_face will rollback to a position if it comes across a keyword + // check the line that fin will retrieve. + getline(fin, line); + cout << "check stream state \n current line: " << endl; + cout << line << endl; + fin.close(); +} + +int main() { + //loadmap("empty.map", "empty-test.map"); + test_parsevertices("empty.map", 10); + test_parseface("empty.map", 19); +} diff --git a/ReflexToQ3/wip/worldspawn.h b/ReflexToQ3/wip/worldspawn.h new file mode 100644 index 0000000..2f0ed15 --- /dev/null +++ b/ReflexToQ3/wip/worldspawn.h @@ -0,0 +1,36 @@ +// +// Author: Michael Cameron +// Email: chronokun@hotmail.com +// + +#ifndef __WORLDSPAWN_H__ +#define __WORLDSPAWN_H__ + +#include +#include +#include + +struct TFace +{ + float m_fXOffset; + float m_fYOffset; + float m_fXScale; + float m_fYScale; + float m_fRotation; + std::vector m_Indices; + std::string m_Material; +}; + +struct TBrush +{ + std::vector m_Vertices; + std::vector m_Faces; + +}; + +struct TWorldSpawn +{ + std::vector m_Brushes; +}; + +#endif \ No newline at end of file