reflex2q3/ReflexToQ3/main.cpp

129 lines
3.8 KiB
C++

//
// Author: Michael Cameron
// Email: chronokun@hotmail.com
//
#include <vector>
#include <string>
#include <sstream>
#include <fstream>
#include <iostream>
#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<TPlanePoints> &);
#define ARG_INPUT_SHORTALIAS "i"
#define ARG_OUTPUT_SHORTALIAS "o"
#define ARG_BRUSHFORMAT "gtk"
cxxopts::Options arguments(int ac, char ** av) {
vector<string> 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<string>(), "FILE")
("o,output",
"required, output map file, for idTech 3 or similar map editors",
cxxopts::value<string>(), "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<string>(), "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<vector<string> > &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<string>().c_str(), // in file
o[ARG_OUTPUT_SHORTALIAS].as<string>().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<string>()
<< " to "
<< o[ARG_OUTPUT_SHORTALIAS].as<string>()
<< endl;
} else {
cout << "Failed to convert map." << endl;
}
return is_ok;
}
void print_entities(vector<vector<string> > &q) {
vector<string> 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<vector<string> > &q) {
string entfile = o["e"].as<string>();
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<string>(), ios::app);
brushdef fn = &brushdef_net;
vector<string> entity;
if (o.count(ARG_BRUSHFORMAT)) {
fn = &brushdef_gtk;
}
for (const vector<string> &entity : q) {
write(entity, fout, fn, e);
}
}
int main(int argc, char** argv)
{
cxxopts::Options p = arguments(argc, argv);
vector<vector<string> > entities;
bool is_ok = convert_worldspawn(p, entities);
// print_entities(entities);
convert_entities(p, entities);
return(0);
}