diff --git a/ReflexToQ3/Makefile b/ReflexToQ3/Makefile index 33d992d..1b3bf85 100644 --- a/ReflexToQ3/Makefile +++ b/ReflexToQ3/Makefile @@ -5,19 +5,19 @@ CFLAGS=-std=c++11 -I"includes" -I"/usr/include/eigen3" all: v6 v8 -v6: planes.o brushdef.o mapparser.o - $(CC) $^ main.cpp $(CFLAGS) -o $(EXV6) 2>error6.log +v6: planes.o brushdef.o v6mapparser.o + $(CC) $^ main.cpp $(CFLAGS) -DV6 -o $(EXV6) 2>error6.log -v8: planes.o brushdef.o v8mapparser.o - $(CC) $^ main.cpp $(CFLAGS) -o $(EXV8) 2>error8.log - -mapparser.o: includes/mapparser.cpp - $(CC) -c $^ $(CFLAGS) +v8: planes.o brushdef.o v6mapparser.o v8mapparser.o + $(CC) $^ main.cpp $(CFLAGS) -DV8 -o $(EXV8) 2>error8.log v8mapparser.o: includes/v8mapparser.cpp $(CC) -c $^ $(CFLAGS) -brushdef.o: planes.o includes/brushdef.cpp +v6mapparser.o: includes/v6mapparser.cpp + $(CC) -c $^ $(CFLAGS) + +brushdef.o: includes/brushdef.cpp $(CC) -c $^ $(CFLAGS) planes.o: includes/planes.cpp diff --git a/ReflexToQ3/includes/mapparser.h b/ReflexToQ3/includes/mapparser.h deleted file mode 100644 index bd015c0..0000000 --- a/ReflexToQ3/includes/mapparser.h +++ /dev/null @@ -1,42 +0,0 @@ -// -// Author: Michael Cameron -// Email: chronokun@hotmail.com -// - -#ifndef __MAPPARSER_H__ -#define __MAPPARSER_H__ - -// Includes -#include "worldspawn.h" - -// enums -enum EParserState -{ - PARSERSTATE_UNKNOWN, - PARSERSTATE_ENTITY, - PARSERSTATE_WORLDSPAWN, - PARSERSTATE_BRUSH, - PARSERSTATE_VERTEX, - PARSERSTATE_FACE -}; - -class CMapParser -{ - // Variables -public: - TWorldSpawn m_WorldSpawn; - - // Functions -public: - const bool LoadMap(const char* _kpcFileName); - -protected: - EParserState ParseEntity(const std::string _Line); - EParserState ParseWorldSpawn(const std::string _Line); - EParserState ParseBrush(const std::string _Line); - EParserState ParseVertex(const std::string _Line); - EParserState ParseFace(const std::string _Line); - -}; - -#endif \ No newline at end of file diff --git a/ReflexToQ3/includes/mapparser.cpp b/ReflexToQ3/includes/v6mapparser.cpp similarity index 59% rename from ReflexToQ3/includes/mapparser.cpp rename to ReflexToQ3/includes/v6mapparser.cpp index 8b849be..fc8e490 100644 --- a/ReflexToQ3/includes/mapparser.cpp +++ b/ReflexToQ3/includes/v6mapparser.cpp @@ -1,251 +1,236 @@ -// -// Author: Michael Cameron -// Email: chronokun@hotmail.com -// - -// Libraries Include -#include "libraries.h" -// This Include -#include "mapparser.h" - -#ifndef _MSC_VER -/* - str*_s functions are microsoft only extensions of C string manip. - mingw is ok with strtok_r, but is not ok with strcpy_r - additionally, old versions of mingw may not be ok with strtok_r at all. -*/ -inline char *strtok_s(char* s, const char* delm, char** context) { - return strtok_r(s, delm, context); -} - -inline char *strcpy_s(char *dest, const char *src) { - return strcpy(dest, src); -} -#endif - -const bool CMapParser::LoadMap(const char* _kpcFileName) -{ - std::ifstream InFile; - EParserState eState = PARSERSTATE_UNKNOWN; - - InFile.open(_kpcFileName, std::ios::in); - if(InFile.is_open()) - { - std::string Line; - bool bAdvance = true; - bool bGoing = true; - while(bGoing) - { - if(bAdvance) - { - if(!std::getline(InFile, Line)) - { - bGoing = false; - } - } - bAdvance = true; - if(eState == PARSERSTATE_UNKNOWN) - { - if(strcmp(Line.c_str(), "entity") == 0) - { - eState = PARSERSTATE_ENTITY; - continue; - } - } - else if(eState == PARSERSTATE_ENTITY) - { - eState = this->ParseEntity(Line); - } - else if(eState == PARSERSTATE_WORLDSPAWN) - { - eState = this->ParseWorldSpawn(Line); - } - else if(eState == PARSERSTATE_BRUSH) - { - eState = this->ParseBrush(Line); - //bAdvance = false; - } - else if(eState == PARSERSTATE_VERTEX) - { - eState = this->ParseVertex(Line); - if(eState != PARSERSTATE_VERTEX) - { - bAdvance = false; - } - } - else if(eState == PARSERSTATE_FACE) - { - eState = this->ParseFace(Line); - if(eState != PARSERSTATE_FACE) - { - bAdvance = false; - } - } - } - InFile.close(); - } - else - { - return(false); - } - - return(true); -} - -EParserState CMapParser::ParseEntity(const std::string _Line) -{ - const size_t kszLineSize = 256; - char pcLine[kszLineSize]; - const char* kpcDelim = " "; - char* pcToken; - char* pcContext; - - strcpy_s(pcLine, _Line.c_str()); - pcToken = strtok_s(pcLine, kpcDelim, &pcContext); - - while(pcToken != nullptr) - { - if(strcmp(pcToken, "\ttype") == 0) - { - pcToken = strtok_s(nullptr, kpcDelim, &pcContext); - if(strcmp(pcToken, "WorldSpawn") == 0) - { - return(PARSERSTATE_WORLDSPAWN); - } - else - { - return(PARSERSTATE_UNKNOWN); - } - } - else - { - return(PARSERSTATE_ENTITY); - } - } - return(PARSERSTATE_UNKNOWN); -} - -EParserState CMapParser::ParseWorldSpawn(const std::string _Line) -{ - if(strcmp(_Line.c_str(), "brush") == 0) - { - this->m_WorldSpawn.m_Brushes.push_back(TBrush()); - return(PARSERSTATE_BRUSH); - } - return(PARSERSTATE_WORLDSPAWN); -} - -EParserState CMapParser::ParseBrush(const std::string _Line) -{ - if(strcmp(_Line.c_str(), "brush") == 0) - { - this->m_WorldSpawn.m_Brushes.push_back(TBrush()); - return(PARSERSTATE_BRUSH); - } - if(strcmp(_Line.c_str(), "\tvertices") == 0) - { - return(PARSERSTATE_VERTEX); - } - else if(strcmp(_Line.c_str(), "\tfaces") == 0) - { - return(PARSERSTATE_FACE); - } - return(PARSERSTATE_BRUSH); -} - -EParserState CMapParser::ParseVertex(const std::string _Line) -{ - const size_t kszLineSize = 2048; - char pcLine[kszLineSize]; - const char* kpcDelim = " \t"; - char* pcToken; - char* pcContext; - - strcpy_s(pcLine, _Line.c_str()); - pcToken = strtok_s(pcLine, kpcDelim, &pcContext); - - Eigen::Vector3f Vert; - int iTokenNum = 0; - while(pcToken != nullptr) - { - if(std::isdigit(pcToken[0], std::locale()) || pcToken[0] == '-') - { - double dValue = std::stod(pcToken); - if(iTokenNum == 0) - { - Vert[X] = (float)dValue; - } - else if(iTokenNum == 1) - { - Vert[Y] = (float)dValue; - } - else if(iTokenNum == 2) - { - Vert[Z] = (float)dValue; - } - iTokenNum++; - } - else - { - return(PARSERSTATE_BRUSH); - } - - pcToken = strtok_s(nullptr, kpcDelim, &pcContext); - } - - this->m_WorldSpawn.m_Brushes[this->m_WorldSpawn.m_Brushes.size()-1].m_Vertices.push_back(Vert); - return(PARSERSTATE_VERTEX); -} - -EParserState CMapParser::ParseFace(const std::string _Line) -{ - const size_t kszLineSize = 2048; - char pcLine[kszLineSize]; - const char* kpcDelim = " \t"; - char* pcToken; - char* pcContext; - - strcpy_s(pcLine, _Line.c_str()); - pcToken = strtok_s(pcLine, kpcDelim, &pcContext); - - int iTokenNum = 0; - - std::string material; - - std::vector Indices; - while(pcToken != nullptr) - { - if(iTokenNum < 5) - { - if(std::isdigit(pcToken[0], std::locale()) || pcToken[0] == '-') - { - double dValue = std::stod(pcToken); - } - else - { - return(PARSERSTATE_BRUSH); - } - } - else - { - if(std::isdigit(pcToken[0], std::locale()) || pcToken[0] == '-') - { - int iValue = std::stoi(pcToken); - Indices.push_back(iValue); - } - else - { - material = pcToken; - } - } - - iTokenNum++; - pcToken = strtok_s(nullptr, kpcDelim, &pcContext); - } - - TFace Face; - Face.m_Indices = Indices; - Face.m_Material = material; - this->m_WorldSpawn.m_Brushes[this->m_WorldSpawn.m_Brushes.size()-1].m_Faces.push_back(Face); - return(PARSERSTATE_FACE); -} +// +// Author: Michael Cameron +// Email: chronokun@hotmail.com +// + +#include "libraries.h" +#include "v6mapparser.hpp" +using namespace std; + +#ifndef _MSC_VER +/* + str*_s functions are microsoft only extensions of C string manip. + mingw is ok with strtok_r, but is not ok with strcpy_r + additionally, old versions of mingw may not be ok with strtok_r at all. +*/ +inline char *strtok_s(char* s, const char* delm, char** context) { + return strtok_r(s, delm, context); +} + +inline char *strcpy_s(char *dest, const char *src) { + return strcpy(dest, src); +} +#endif + +const bool V6MapParser::LoadMap(const char* _kpcFileName) +{ + std::ifstream InFile; + EParserState eState = PARSERSTATE_UNKNOWN; + + InFile.open(_kpcFileName, std::ios::in); + if(InFile.is_open()) + { + std::string Line; + bool bAdvance = true; + bool bGoing = true; + while(bGoing) + { + if(bAdvance) + { + if(!std::getline(InFile, Line)) + { + bGoing = false; + } + } + bAdvance = true; + if(eState == PARSERSTATE_UNKNOWN) + { + if(Line.find(KEYWORD_ENTITY) != string::npos) + { + eState = PARSERSTATE_ENTITY; + continue; + } else { + cout << "Warning: PARSERSTATE_UNKNOWN and no cases met." << endl; + } + } + else if(eState == PARSERSTATE_ENTITY) + { + eState = this->ParseEntity(Line); + } + else if(eState == PARSERSTATE_WORLDSPAWN) + { + eState = this->ParseWorldSpawn(Line); + } + else if(eState == PARSERSTATE_BRUSH) + { + eState = this->ParseBrush(Line); + //bAdvance = false; + } + else if(eState == PARSERSTATE_VERTEX) + { + eState = this->ParseVertex(Line); + if(eState != PARSERSTATE_VERTEX) + { + bAdvance = false; + } + } + else if(eState == PARSERSTATE_FACE) + { + eState = this->ParseFace(Line); + if(eState != PARSERSTATE_FACE) + { + bAdvance = false; + } + } + } + InFile.close(); + } + else + { + return(false); + } + + return(true); +} + +EParserState V6MapParser::ParseEntity(const std::string _Line) +{ + const size_t kszLineSize = 256; + char pcLine[kszLineSize]; + const char* kpcDelim = " "; + char* pcToken; + char* pcContext; + + strcpy_s(pcLine, _Line.c_str()); + pcToken = strtok_s(pcLine, kpcDelim, &pcContext); + + if (_Line.find(KEYWORD_BRUSH) != string::npos) { + m_WorldSpawn.m_Brushes.push_back(TBrush()); + return PARSERSTATE_BRUSH; + } + while(pcToken != nullptr) + { + if(strcmp(pcToken, "\ttype") == 0) + { + pcToken = strtok_s(nullptr, kpcDelim, &pcContext); + if(strcmp(pcToken, "WorldSpawn") == 0) + { + return(PARSERSTATE_WORLDSPAWN); + } + else + { + return(PARSERSTATE_UNKNOWN); + } + } + else + { + return(PARSERSTATE_ENTITY); + } + } + return(PARSERSTATE_UNKNOWN); +} + +EParserState V6MapParser::ParseWorldSpawn(const std::string _Line) +{ + if(_Line.find(KEYWORD_BRUSH) != string::npos) + { + m_WorldSpawn.m_Brushes.push_back(TBrush()); + return(PARSERSTATE_BRUSH); + } + return(PARSERSTATE_WORLDSPAWN); +} + +EParserState V6MapParser::ParseBrush(const std::string _Line) +{ + if(_Line.find(KEYWORD_BRUSH) != string::npos) + { + m_WorldSpawn.m_Brushes.push_back(TBrush()); + return(PARSERSTATE_BRUSH); + } + if(_Line.find(KEYWORD_VERTICES) != string::npos) + { + return(PARSERSTATE_VERTEX); + } + else if(_Line.find(KEYWORD_FACES) != string::npos) + { + return(PARSERSTATE_FACE); + } + return(PARSERSTATE_BRUSH); +} + +EParserState V6MapParser::ParseVertex(const std::string _Line) +{ + const size_t kszLineSize = 2048; + char pcLine[kszLineSize]; + const char* kpcDelim = " \t"; + char* pcToken; + char* pcContext; + + strcpy_s(pcLine, _Line.c_str()); + pcToken = strtok_s(pcLine, kpcDelim, &pcContext); + Eigen::Vector3f Vert; + int iTokenNum = 0; + while(pcToken != NULL) + { + if(std::isdigit(pcToken[0], std::locale()) || pcToken[0] == '-') + { + double dValue = std::stod(pcToken); + if(iTokenNum == 0) + { + Vert[X] = (float)dValue; + } + else if(iTokenNum == 1) + { + Vert[Y] = (float)dValue; + } + else if(iTokenNum == 2) + { + Vert[Z] = (float)dValue; + } + iTokenNum++; + } + else + { + return(PARSERSTATE_BRUSH); + } + + pcToken = strtok_s(NULL, kpcDelim, &pcContext); + } + m_WorldSpawn.m_Brushes[m_WorldSpawn.m_Brushes.size()-1].m_Vertices.push_back(Vert); + return(PARSERSTATE_VERTEX); +} + +EParserState V6MapParser::ParseFace(const std::string _Line) { + stringstream ss(_Line); + string material; + vector Indices; + TFace Face; + float *f = &Face.m_fXOffset; + string data; + unsigned int i = 0; + // For a primitive in Reflex, there is at least 9 and at most 10 fields. + while (ss >> data) { + if (i < 5) { + if (isdigit(data[0], std::locale()) || data[0] == '-') { + double dvalue = stod(data); + *f = (float)dvalue; + f++; + } else { + return PARSERSTATE_BRUSH; + } + } else if (i == 9) { + ; + } else { + if (isdigit(data[0], std::locale()) || data[0] == '-') { + Indices.push_back(stoi(data)); + } else { + material = data; + } + } + i++; + } + Face.m_Indices = Indices; + Face.m_Material = material; + m_WorldSpawn.m_Brushes[m_WorldSpawn.m_Brushes.size()-1].m_Faces.push_back(Face); + return(PARSERSTATE_FACE); +} diff --git a/ReflexToQ3/includes/v6mapparser.hpp b/ReflexToQ3/includes/v6mapparser.hpp new file mode 100644 index 0000000..5817b6c --- /dev/null +++ b/ReflexToQ3/includes/v6mapparser.hpp @@ -0,0 +1,42 @@ + +#ifndef __V6MAPPARSER_H__ +#define __V6MAPPARSER_H__ + +#include "worldspawn.h" + +#define KEYWORD_ENTITY "entity" +#define KEYWORD_BRUSH "brush" +#define KEYWORD_VERTICES "vertices" +#define KEYWORD_FACES "faces" + +// Map Parser States +enum EParserState +{ + PARSERSTATE_UNKNOWN, // 0 + PARSERSTATE_ENTITY, // 1 + PARSERSTATE_WORLDSPAWN, // 2 + PARSERSTATE_BRUSH, // 3 + PARSERSTATE_VERTEX, // 4 + PARSERSTATE_FACE, // 5 + PARSERSTATE_PREFAB // 6 - Only in V8 +}; + +class V6MapParser +{ + // Variables +public: + TWorldSpawn m_WorldSpawn; + + // Functions +public: + const bool LoadMap(const char* _kpcFileName); + +protected: + EParserState ParseEntity(const std::string _Line); + EParserState ParseWorldSpawn(const std::string _Line); + EParserState ParseBrush(const std::string _Line); + EParserState ParseVertex(const std::string _Line); + EParserState ParseFace(const std::string _Line); +}; + +#endif \ No newline at end of file diff --git a/ReflexToQ3/includes/v8mapparser.cpp b/ReflexToQ3/includes/v8mapparser.cpp index b622ae9..286be89 100644 --- a/ReflexToQ3/includes/v8mapparser.cpp +++ b/ReflexToQ3/includes/v8mapparser.cpp @@ -1,36 +1,9 @@ -// -// Author: Michael Cameron -// Email: chronokun@hotmail.com -// - -#include "libraries.h" -#include "v8mapparser.h" +#include "v8mapparser.hpp" +#include +#include +#include using namespace std; - -#ifndef _MSC_VER -/* - str*_s functions are microsoft only extensions of C string manip. - mingw is ok with strtok_r, but is not ok with strcpy_r - additionally, old versions of mingw may not be ok with strtok_r at all. -*/ -inline char *strtok_s(char* s, const char* delm, char** context) { - return strtok_r(s, delm, context); -} - -inline char *strcpy_s(char *dest, const char *src) { - return strcpy(dest, src); -} -#endif - -#define KEYWORD_GLOBAL "\tglobal" -#define KEYWORD_PREFAB "\tprefab" -#define KEYWORD_ENTITY "\tentity" -#define KEYWORD_BRUSH "\tbrush" -#define KEYWORD_VERTICES "\tvertices" -#define KEYWORD_FACES "\tfaces" - -const bool CMapParser::LoadMap(const char* _kpcFileName) -{ +const bool V8MapParser::LoadMap(const char* _kpcFileName) { std::ifstream InFile; EParserState eState = PARSERSTATE_UNKNOWN; @@ -107,7 +80,7 @@ const bool CMapParser::LoadMap(const char* _kpcFileName) return(true); } -EParserState CMapParser::ParsePrefab(const std::string _Line) { +EParserState V8MapParser::ParsePrefab(const std::string _Line) { // this is going with the idea that its possible to correctly parse the map file // if prefabs are simply broken and de-indented. @@ -118,145 +91,3 @@ EParserState CMapParser::ParsePrefab(const std::string _Line) { return PARSERSTATE_BRUSH; } } - -EParserState CMapParser::ParseEntity(const std::string _Line) -{ - const size_t kszLineSize = 256; - char pcLine[kszLineSize]; - const char* kpcDelim = " "; - char* pcToken; - char* pcContext; - - strcpy_s(pcLine, _Line.c_str()); - pcToken = strtok_s(pcLine, kpcDelim, &pcContext); - - if (_Line.find(KEYWORD_BRUSH) != string::npos) { - m_WorldSpawn.m_Brushes.push_back(TBrush()); - return PARSERSTATE_BRUSH; - } - while(pcToken != nullptr) - { - if(strcmp(pcToken, "\ttype") == 0) - { - pcToken = strtok_s(nullptr, kpcDelim, &pcContext); - if(strcmp(pcToken, "WorldSpawn") == 0) - { - return(PARSERSTATE_WORLDSPAWN); - } - else - { - return(PARSERSTATE_UNKNOWN); - } - } - else - { - return(PARSERSTATE_ENTITY); - } - } - return(PARSERSTATE_UNKNOWN); -} - -EParserState CMapParser::ParseWorldSpawn(const std::string _Line) -{ - if(_Line.find(KEYWORD_BRUSH) != string::npos) - { - m_WorldSpawn.m_Brushes.push_back(TBrush()); - return(PARSERSTATE_BRUSH); - } - return(PARSERSTATE_WORLDSPAWN); -} - -EParserState CMapParser::ParseBrush(const std::string _Line) -{ - if(_Line.find(KEYWORD_BRUSH) != string::npos) - { - m_WorldSpawn.m_Brushes.push_back(TBrush()); - return(PARSERSTATE_BRUSH); - } - if(_Line.find(KEYWORD_VERTICES) != string::npos) - { - return(PARSERSTATE_VERTEX); - } - else if(_Line.find(KEYWORD_FACES) != string::npos) - { - return(PARSERSTATE_FACE); - } - return(PARSERSTATE_BRUSH); -} - -EParserState CMapParser::ParseVertex(const std::string _Line) -{ - const size_t kszLineSize = 2048; - char pcLine[kszLineSize]; - const char* kpcDelim = " \t"; - char* pcToken; - char* pcContext; - - strcpy_s(pcLine, _Line.c_str()); - pcToken = strtok_s(pcLine, kpcDelim, &pcContext); - Eigen::Vector3f Vert; - int iTokenNum = 0; - while(pcToken != NULL) - { - if(std::isdigit(pcToken[0], std::locale()) || pcToken[0] == '-') - { - double dValue = std::stod(pcToken); - if(iTokenNum == 0) - { - Vert[X] = (float)dValue; - } - else if(iTokenNum == 1) - { - Vert[Y] = (float)dValue; - } - else if(iTokenNum == 2) - { - Vert[Z] = (float)dValue; - } - iTokenNum++; - } - else - { - return(PARSERSTATE_BRUSH); - } - - pcToken = strtok_s(NULL, kpcDelim, &pcContext); - } - m_WorldSpawn.m_Brushes[m_WorldSpawn.m_Brushes.size()-1].m_Vertices.push_back(Vert); - return(PARSERSTATE_VERTEX); -} - -EParserState CMapParser::ParseFace(const std::string _Line) { - stringstream ss(_Line); - string material; - vector Indices; - TFace Face; - float *f = &Face.m_fXOffset; - string data; - unsigned int i = 0; - // For a primitive in Reflex, there is at least 9 and at most 10 fields. - while (ss >> data) { - if (i < 5) { - if (isdigit(data[0], std::locale()) || data[0] == '-') { - double dvalue = stod(data); - *f = (float)dvalue; - f++; - } else { - return PARSERSTATE_BRUSH; - } - } else if (i == 9) { - ; - } else { - if (isdigit(data[0], std::locale()) || data[0] == '-') { - Indices.push_back(stoi(data)); - } else { - material = data; - } - } - i++; - } - Face.m_Indices = Indices; - Face.m_Material = material; - m_WorldSpawn.m_Brushes[m_WorldSpawn.m_Brushes.size()-1].m_Faces.push_back(Face); - return(PARSERSTATE_FACE); -} diff --git a/ReflexToQ3/includes/v8mapparser.hpp b/ReflexToQ3/includes/v8mapparser.hpp new file mode 100644 index 0000000..1620e77 --- /dev/null +++ b/ReflexToQ3/includes/v8mapparser.hpp @@ -0,0 +1,19 @@ +#ifndef __V8MAPPARSER_HPP__ +#define __V8MAPPARSER_HPP__ + +#include "v6mapparser.hpp" + +#define KEYWORD_GLOBAL "global" +#define KEYWORD_PREFAB "prefab" + +class V8MapParser : public V6MapParser { + public: + const bool LoadMap(const char *); + + protected: + EParserState ParsePrefab(const std::string); +}; + + + +#endif diff --git a/ReflexToQ3/main.cpp b/ReflexToQ3/main.cpp index b7c6fda..05d90ed 100644 --- a/ReflexToQ3/main.cpp +++ b/ReflexToQ3/main.cpp @@ -3,10 +3,19 @@ // Email: chronokun@hotmail.com // -// Libraries Include -#include "libraries.h" -// Local Includes -#include "mapparser.h" + +#include +#include +#include +#include +#include +#ifdef V8 + #include "v8mapparser.hpp" + typedef V8MapParser CMapParser; +#else + #include "v6mapparser.hpp" + typedef V6MapParser CMapParser; +#endif #include "brushdef.hpp" using namespace std;