Changed map parser so V8 inherits from v6

This commit is contained in:
2017-04-12 00:18:29 -07:00
parent add1138a78
commit 8689f24329
7 changed files with 324 additions and 480 deletions

View File

@ -5,19 +5,19 @@ CFLAGS=-std=c++11 -I"includes" -I"/usr/include/eigen3"
all: v6 v8 all: v6 v8
v6: planes.o brushdef.o mapparser.o v6: planes.o brushdef.o v6mapparser.o
$(CC) $^ main.cpp $(CFLAGS) -o $(EXV6) 2>error6.log $(CC) $^ main.cpp $(CFLAGS) -DV6 -o $(EXV6) 2>error6.log
v8: planes.o brushdef.o v8mapparser.o v8: planes.o brushdef.o v6mapparser.o v8mapparser.o
$(CC) $^ main.cpp $(CFLAGS) -o $(EXV8) 2>error8.log $(CC) $^ main.cpp $(CFLAGS) -DV8 -o $(EXV8) 2>error8.log
mapparser.o: includes/mapparser.cpp
$(CC) -c $^ $(CFLAGS)
v8mapparser.o: includes/v8mapparser.cpp v8mapparser.o: includes/v8mapparser.cpp
$(CC) -c $^ $(CFLAGS) $(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) $(CC) -c $^ $(CFLAGS)
planes.o: includes/planes.cpp planes.o: includes/planes.cpp

View File

@ -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

View File

@ -1,251 +1,236 @@
// //
// Author: Michael Cameron // Author: Michael Cameron
// Email: chronokun@hotmail.com // Email: chronokun@hotmail.com
// //
// Libraries Include #include "libraries.h"
#include "libraries.h" #include "v6mapparser.hpp"
// This Include using namespace std;
#include "mapparser.h"
#ifndef _MSC_VER
#ifndef _MSC_VER /*
/* str*_s functions are microsoft only extensions of C string manip.
str*_s functions are microsoft only extensions of C string manip. mingw is ok with strtok_r, but is not ok with strcpy_r
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.
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) {
inline char *strtok_s(char* s, const char* delm, char** context) { return strtok_r(s, delm, context);
return strtok_r(s, delm, context); }
}
inline char *strcpy_s(char *dest, const char *src) {
inline char *strcpy_s(char *dest, const char *src) { return strcpy(dest, src);
return strcpy(dest, src); }
} #endif
#endif
const bool V6MapParser::LoadMap(const char* _kpcFileName)
const bool CMapParser::LoadMap(const char* _kpcFileName) {
{ std::ifstream InFile;
std::ifstream InFile; EParserState eState = PARSERSTATE_UNKNOWN;
EParserState eState = PARSERSTATE_UNKNOWN;
InFile.open(_kpcFileName, std::ios::in);
InFile.open(_kpcFileName, std::ios::in); if(InFile.is_open())
if(InFile.is_open()) {
{ std::string Line;
std::string Line; bool bAdvance = true;
bool bAdvance = true; bool bGoing = true;
bool bGoing = true; while(bGoing)
while(bGoing) {
{ if(bAdvance)
if(bAdvance) {
{ if(!std::getline(InFile, Line))
if(!std::getline(InFile, Line)) {
{ bGoing = false;
bGoing = false; }
} }
} bAdvance = true;
bAdvance = true; if(eState == PARSERSTATE_UNKNOWN)
if(eState == PARSERSTATE_UNKNOWN) {
{ if(Line.find(KEYWORD_ENTITY) != string::npos)
if(strcmp(Line.c_str(), "entity") == 0) {
{ eState = PARSERSTATE_ENTITY;
eState = PARSERSTATE_ENTITY; continue;
continue; } else {
} cout << "Warning: PARSERSTATE_UNKNOWN and no cases met." << endl;
} }
else if(eState == PARSERSTATE_ENTITY) }
{ else if(eState == PARSERSTATE_ENTITY)
eState = this->ParseEntity(Line); {
} eState = this->ParseEntity(Line);
else if(eState == PARSERSTATE_WORLDSPAWN) }
{ else if(eState == PARSERSTATE_WORLDSPAWN)
eState = this->ParseWorldSpawn(Line); {
} eState = this->ParseWorldSpawn(Line);
else if(eState == PARSERSTATE_BRUSH) }
{ else if(eState == PARSERSTATE_BRUSH)
eState = this->ParseBrush(Line); {
//bAdvance = false; eState = this->ParseBrush(Line);
} //bAdvance = false;
else if(eState == PARSERSTATE_VERTEX) }
{ else if(eState == PARSERSTATE_VERTEX)
eState = this->ParseVertex(Line); {
if(eState != PARSERSTATE_VERTEX) eState = this->ParseVertex(Line);
{ if(eState != PARSERSTATE_VERTEX)
bAdvance = false; {
} bAdvance = false;
} }
else if(eState == PARSERSTATE_FACE) }
{ else if(eState == PARSERSTATE_FACE)
eState = this->ParseFace(Line); {
if(eState != PARSERSTATE_FACE) eState = this->ParseFace(Line);
{ if(eState != PARSERSTATE_FACE)
bAdvance = false; {
} bAdvance = false;
} }
} }
InFile.close(); }
} InFile.close();
else }
{ else
return(false); {
} return(false);
}
return(true);
} return(true);
}
EParserState CMapParser::ParseEntity(const std::string _Line)
{ EParserState V6MapParser::ParseEntity(const std::string _Line)
const size_t kszLineSize = 256; {
char pcLine[kszLineSize]; const size_t kszLineSize = 256;
const char* kpcDelim = " "; char pcLine[kszLineSize];
char* pcToken; const char* kpcDelim = " ";
char* pcContext; char* pcToken;
char* pcContext;
strcpy_s(pcLine, _Line.c_str());
pcToken = strtok_s(pcLine, kpcDelim, &pcContext); strcpy_s(pcLine, _Line.c_str());
pcToken = strtok_s(pcLine, kpcDelim, &pcContext);
while(pcToken != nullptr)
{ if (_Line.find(KEYWORD_BRUSH) != string::npos) {
if(strcmp(pcToken, "\ttype") == 0) m_WorldSpawn.m_Brushes.push_back(TBrush());
{ return PARSERSTATE_BRUSH;
pcToken = strtok_s(nullptr, kpcDelim, &pcContext); }
if(strcmp(pcToken, "WorldSpawn") == 0) while(pcToken != nullptr)
{ {
return(PARSERSTATE_WORLDSPAWN); if(strcmp(pcToken, "\ttype") == 0)
} {
else pcToken = strtok_s(nullptr, kpcDelim, &pcContext);
{ if(strcmp(pcToken, "WorldSpawn") == 0)
return(PARSERSTATE_UNKNOWN); {
} return(PARSERSTATE_WORLDSPAWN);
} }
else else
{ {
return(PARSERSTATE_ENTITY); return(PARSERSTATE_UNKNOWN);
} }
} }
return(PARSERSTATE_UNKNOWN); else
} {
return(PARSERSTATE_ENTITY);
EParserState CMapParser::ParseWorldSpawn(const std::string _Line) }
{ }
if(strcmp(_Line.c_str(), "brush") == 0) return(PARSERSTATE_UNKNOWN);
{ }
this->m_WorldSpawn.m_Brushes.push_back(TBrush());
return(PARSERSTATE_BRUSH); EParserState V6MapParser::ParseWorldSpawn(const std::string _Line)
} {
return(PARSERSTATE_WORLDSPAWN); if(_Line.find(KEYWORD_BRUSH) != string::npos)
} {
m_WorldSpawn.m_Brushes.push_back(TBrush());
EParserState CMapParser::ParseBrush(const std::string _Line) return(PARSERSTATE_BRUSH);
{ }
if(strcmp(_Line.c_str(), "brush") == 0) return(PARSERSTATE_WORLDSPAWN);
{ }
this->m_WorldSpawn.m_Brushes.push_back(TBrush());
return(PARSERSTATE_BRUSH); EParserState V6MapParser::ParseBrush(const std::string _Line)
} {
if(strcmp(_Line.c_str(), "\tvertices") == 0) if(_Line.find(KEYWORD_BRUSH) != string::npos)
{ {
return(PARSERSTATE_VERTEX); m_WorldSpawn.m_Brushes.push_back(TBrush());
} return(PARSERSTATE_BRUSH);
else if(strcmp(_Line.c_str(), "\tfaces") == 0) }
{ if(_Line.find(KEYWORD_VERTICES) != string::npos)
return(PARSERSTATE_FACE); {
} return(PARSERSTATE_VERTEX);
return(PARSERSTATE_BRUSH); }
} else if(_Line.find(KEYWORD_FACES) != string::npos)
{
EParserState CMapParser::ParseVertex(const std::string _Line) return(PARSERSTATE_FACE);
{ }
const size_t kszLineSize = 2048; return(PARSERSTATE_BRUSH);
char pcLine[kszLineSize]; }
const char* kpcDelim = " \t";
char* pcToken; EParserState V6MapParser::ParseVertex(const std::string _Line)
char* pcContext; {
const size_t kszLineSize = 2048;
strcpy_s(pcLine, _Line.c_str()); char pcLine[kszLineSize];
pcToken = strtok_s(pcLine, kpcDelim, &pcContext); const char* kpcDelim = " \t";
char* pcToken;
Eigen::Vector3f Vert; char* pcContext;
int iTokenNum = 0;
while(pcToken != nullptr) strcpy_s(pcLine, _Line.c_str());
{ pcToken = strtok_s(pcLine, kpcDelim, &pcContext);
if(std::isdigit(pcToken[0], std::locale()) || pcToken[0] == '-') Eigen::Vector3f Vert;
{ int iTokenNum = 0;
double dValue = std::stod(pcToken); while(pcToken != NULL)
if(iTokenNum == 0) {
{ if(std::isdigit(pcToken[0], std::locale()) || pcToken[0] == '-')
Vert[X] = (float)dValue; {
} double dValue = std::stod(pcToken);
else if(iTokenNum == 1) if(iTokenNum == 0)
{ {
Vert[Y] = (float)dValue; Vert[X] = (float)dValue;
} }
else if(iTokenNum == 2) else if(iTokenNum == 1)
{ {
Vert[Z] = (float)dValue; Vert[Y] = (float)dValue;
} }
iTokenNum++; else if(iTokenNum == 2)
} {
else Vert[Z] = (float)dValue;
{ }
return(PARSERSTATE_BRUSH); iTokenNum++;
} }
else
pcToken = strtok_s(nullptr, kpcDelim, &pcContext); {
} return(PARSERSTATE_BRUSH);
}
this->m_WorldSpawn.m_Brushes[this->m_WorldSpawn.m_Brushes.size()-1].m_Vertices.push_back(Vert);
return(PARSERSTATE_VERTEX); pcToken = strtok_s(NULL, kpcDelim, &pcContext);
} }
m_WorldSpawn.m_Brushes[m_WorldSpawn.m_Brushes.size()-1].m_Vertices.push_back(Vert);
EParserState CMapParser::ParseFace(const std::string _Line) return(PARSERSTATE_VERTEX);
{ }
const size_t kszLineSize = 2048;
char pcLine[kszLineSize]; EParserState V6MapParser::ParseFace(const std::string _Line) {
const char* kpcDelim = " \t"; stringstream ss(_Line);
char* pcToken; string material;
char* pcContext; vector<int> Indices;
TFace Face;
strcpy_s(pcLine, _Line.c_str()); float *f = &Face.m_fXOffset;
pcToken = strtok_s(pcLine, kpcDelim, &pcContext); string data;
unsigned int i = 0;
int iTokenNum = 0; // For a primitive in Reflex, there is at least 9 and at most 10 fields.
while (ss >> data) {
std::string material; if (i < 5) {
if (isdigit(data[0], std::locale()) || data[0] == '-') {
std::vector<int> Indices; double dvalue = stod(data);
while(pcToken != nullptr) *f = (float)dvalue;
{ f++;
if(iTokenNum < 5) } else {
{ return PARSERSTATE_BRUSH;
if(std::isdigit(pcToken[0], std::locale()) || pcToken[0] == '-') }
{ } else if (i == 9) {
double dValue = std::stod(pcToken); ;
} } else {
else if (isdigit(data[0], std::locale()) || data[0] == '-') {
{ Indices.push_back(stoi(data));
return(PARSERSTATE_BRUSH); } else {
} material = data;
} }
else }
{ i++;
if(std::isdigit(pcToken[0], std::locale()) || pcToken[0] == '-') }
{ Face.m_Indices = Indices;
int iValue = std::stoi(pcToken); Face.m_Material = material;
Indices.push_back(iValue); m_WorldSpawn.m_Brushes[m_WorldSpawn.m_Brushes.size()-1].m_Faces.push_back(Face);
} return(PARSERSTATE_FACE);
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);
}

View File

@ -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

View File

@ -1,36 +1,9 @@
// #include "v8mapparser.hpp"
// Author: Michael Cameron #include <string>
// Email: chronokun@hotmail.com #include <iostream>
// #include <fstream>
#include "libraries.h"
#include "v8mapparser.h"
using namespace std; using namespace std;
const bool V8MapParser::LoadMap(const char* _kpcFileName) {
#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)
{
std::ifstream InFile; std::ifstream InFile;
EParserState eState = PARSERSTATE_UNKNOWN; EParserState eState = PARSERSTATE_UNKNOWN;
@ -107,7 +80,7 @@ const bool CMapParser::LoadMap(const char* _kpcFileName)
return(true); 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 // this is going with the idea that its possible to correctly parse the map file
// if prefabs are simply broken and de-indented. // if prefabs are simply broken and de-indented.
@ -118,145 +91,3 @@ EParserState CMapParser::ParsePrefab(const std::string _Line) {
return PARSERSTATE_BRUSH; 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<int> 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);
}

View File

@ -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

View File

@ -3,10 +3,19 @@
// Email: chronokun@hotmail.com // Email: chronokun@hotmail.com
// //
// Libraries Include
#include "libraries.h" #include <vector>
// Local Includes #include <string>
#include "mapparser.h" #include <sstream>
#include <fstream>
#include <iostream>
#ifdef V8
#include "v8mapparser.hpp"
typedef V8MapParser CMapParser;
#else
#include "v6mapparser.hpp"
typedef V6MapParser CMapParser;
#endif
#include "brushdef.hpp" #include "brushdef.hpp"
using namespace std; using namespace std;