// // Author: Michael Cameron // Email: chronokun@hotmail.com // #include #include #include #include #include #include #include "cxxopts.hpp" #include "oopless-parser.hpp" #include "brushdef.hpp" using namespace std; //ease of reading function pointer typedef void (*brushdef) (std::stringstream &, const std::vector &); #define ARG_INPUT_SHORTALIAS "i" #define ARG_OUTPUT_SHORTALIAS "o" #define ARG_BRUSHFORMAT "gtk" 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") (ARG_BRUSHFORMAT, "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 convert_worldspawn(const cxxopts::Options &o, vector > &q) { bool is_ok = false; brushdef fn = &brushdef_net; if (o.count(ARG_BRUSHFORMAT)) { fn = &brushdef_gtk; } try { 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 (is_ok) { cout << "Successfully converted map " << o[ARG_INPUT_SHORTALIAS].as() << " to " << o[ARG_OUTPUT_SHORTALIAS].as() << endl; } else { cout << "Failed to convert map." << endl; } return is_ok; } void print_entities(vector > &q) { vector entity; do { entity = q.front(); cout << "--------------------------" << endl; for (const string &s : entity) { cout << s << endl; } cout << "--------------------------" << endl; } while (!q.empty()); } void convert_entities(const cxxopts::Options &o, const vector > &q) { string entfile = o["e"].as(); if (entfile.empty()) { cout << "No entity data file given" "- skipping entity conversion" << endl; return; } EntityConverter e(entfile); e.extractMapInfo(q); ofstream fout(o[ARG_OUTPUT_SHORTALIAS].as(), ios::app); brushdef fn = &brushdef_net; vector entity; if (o.count(ARG_BRUSHFORMAT)) { fn = &brushdef_gtk; } for (const vector &entity : q) { try { write(entity, fout, fn, e); } catch (exception &e) { cerr << e.what() << endl; } } } int main(int argc, char** argv) { cxxopts::Options p = arguments(argc, argv); vector > entities; bool is_ok = convert_worldspawn(p, entities); // print_entities(entities); convert_entities(p, entities); return(0); }