diff --git a/ReflexToQ3/includes/oopless-parser.cpp b/ReflexToQ3/includes/oopless-parser.cpp index 13eb689..bf9700f 100644 --- a/ReflexToQ3/includes/oopless-parser.cpp +++ b/ReflexToQ3/includes/oopless-parser.cpp @@ -103,32 +103,26 @@ vector get_entity(ifstream &f) { void parse_prefab(ifstream &f, ofstream &out, void (*b) (stringstream &, const vector &), - EntityConverter &e) { + queue > &entities) { string l; getline(f, l); if (l.find(KEYWORD_BRUSH) != string::npos) { write(parse_brush(f), out, b); } else if (l.find(KEYWORD_ENTITY) != string::npos) { - write(get_entity(f), out, b, e); + entities.push(get_entity(f)); } } bool convertmap(const char * const infile, const char * const outfile, void (*brushdef) (stringstream &, const vector &), - const char * const entfile) { + queue > &entities) { ifstream fin; fin.open(infile); if (!fin.good()){ cerr << "error: failed to open input file" << endl; return false; } - EntityConverter ec; - if (entfile != NULL) { - string ef(entfile); - string in(infile); - ec = EntityConverter(ef, in); - } ofstream fout; fout.open(outfile); if (!fout.good()) { @@ -141,9 +135,9 @@ bool convertmap(const char * const infile, while (getline(fin, line)) { if (line.find(KEYWORD_PREFAB) != string::npos || line.find(KEYWORD_GLOBAL) != string::npos) { - parse_prefab(fin, fout, brushdef, ec); + parse_prefab(fin, fout, brushdef, entities); } else if (line.find(KEYWORD_ENTITY) != string::npos) { - write(get_entity(fin), fout, brushdef, ec); + entities.push(get_entity(fin)); } else if (line.find(KEYWORD_BRUSH) != string::npos) { write(parse_brush(fin), fout, brushdef); } diff --git a/ReflexToQ3/includes/oopless-parser.hpp b/ReflexToQ3/includes/oopless-parser.hpp index 3508f98..4dcba89 100644 --- a/ReflexToQ3/includes/oopless-parser.hpp +++ b/ReflexToQ3/includes/oopless-parser.hpp @@ -7,6 +7,7 @@ #include #include #include +#include #include "EntityConverter.hpp" bool is_ebrush(std::vector); @@ -25,12 +26,12 @@ std::vector get_entity(std::ifstream &); void parse_prefab(std::ifstream &, std::ofstream &, void (*f) (std::stringstream &, const std::vector &), - EntityConverter &); + std::queue > &); bool convertmap(const char * const, const char * const, void (*f) (std::stringstream &, const std::vector &), - const char * const); + std::queue > &); #define KEYWORD_ENTITY "entity" #define KEYWORD_BRUSH "brush" diff --git a/ReflexToQ3/main.cpp b/ReflexToQ3/main.cpp index 2cd121a..acb2693 100644 --- a/ReflexToQ3/main.cpp +++ b/ReflexToQ3/main.cpp @@ -2,52 +2,105 @@ // Author: Michael Cameron // Email: chronokun@hotmail.com // - - #include #include #include #include #include +#include + #include "oopless-parser.hpp" #include "brushdef.hpp" +#define ARG_INPUT_SHORTALIAS "i" +#define ARG_OUTPUT_SHORTALIAS "o" using namespace std; -int main(const int _kiArgC, const char** _kppcArgv) -{ -#define ARG_POS_BRUSHDEF 5 -#define ARG_POS_ENTITYCONV 4 - // Minimum: program, input file, output file - if(_kiArgC < 3) - { - return(3); - } - // placeholder argument parsing until something more robust is decided upon -/* // optional arg #1: brush definition - gtkradiant or netradiant style - void (*brushdef) (std::stringstream &, const std::vector &); - brushdef = ((string(_kppcArgv[ARG_POS_BRUSHDEF - 1])).compare("-gtk") == 0) ? - &brushdef_gtk: &brushdef_net; - */ - // optional arg #2: entity mapping file - enables entity conversion - const char * const entitymap = (_kiArgC >= ARG_POS_ENTITYCONV) ? - _kppcArgv[ARG_POS_ENTITYCONV - 1]: NULL; +cxxopts::Options arguments(int ac, char ** av) { + vector parg = {"input", "output"}; + cxxopts::Options o("reflex2q3", + "A tool to convert Reflex maps to idTech 3 maps."); + o.add_options() + ("h,help", "displays help") + ("i,input", + "required, input map file, from Reflex", + cxxopts::value(), "FILE") + ("o,output", + "required, output map file, for idTech 3 or similar map editors", + cxxopts::value(), "FILE") + ("gtk", + "optional, output in GTK Radiant's brush definition format") + ("e,ent", + "optional, convert game entities given a table of equivalents", + cxxopts::value(), "FILE") + ; + o.parse_positional(parg); + o.parse(ac, av); + if (o.count("help")) { + cout << o.help() << endl; + } + if (o.count(ARG_INPUT_SHORTALIAS) < 1 || + o.count(ARG_OUTPUT_SHORTALIAS) < 1) { + cerr << "error: no input or output file given" << endl; + exit(EXIT_FAILURE); + } + return o; +} - bool status; +bool convert_worldspawn(const cxxopts::Options &o, + queue > &q) { +//ease of reading +typedef void (*brushdef) (std::stringstream &, + const std::vector &); + bool is_ok = false; + brushdef fn = &brushdef_net; + if (o.count("gtk")) { + fn = &brushdef_gtk; + } try { - status = convertmap(_kppcArgv[1], _kppcArgv[2], &brushdef_net, entitymap); + is_ok = convertmap( + o[ARG_INPUT_SHORTALIAS].as().c_str(), // in file + o[ARG_OUTPUT_SHORTALIAS].as().c_str(), // out file + fn, // brush definition + q); // queue of entities } catch (exception &e) { cout << e.what() << endl; + cout << "exception encountered while converting map geometry" + " - unrecoverable failure" << endl; } - if (status) { + if (is_ok) { cout << "Successfully converted map " - << _kppcArgv[1] + << o[ARG_INPUT_SHORTALIAS].as() << " to " - << _kppcArgv[2] + << o[ARG_OUTPUT_SHORTALIAS].as() << endl; } else { cout << "Failed to convert map." << endl; } + return is_ok; +} + +// wip: current a print out of all entities +bool convert_entities(const cxxopts::Options &o, queue > &q) { + vector entity; + do { + entity = q.front(); + for (const string &s : entity) { + cout << s << endl; + } + q.pop(); + } while (!q.empty()); + return true; +} + +int main(int argc, char** argv) +{ + string entityfile; + cxxopts::Options p = arguments(argc, argv); + + queue > entities; + bool is_ok = convert_worldspawn(p, entities); + convert_entities(p, entities); return(0); }