hopefully version stuff is now run properly on every make...
#include "Application.hh"
#include <stdexcept>
#include <cstdio>
#include <cassert>
enum ArgumentCodes {
ARG_HELP = 'h',
ARG_PORT = 'p',
ARG_SERVER = 's',
ARG_CLIENT = 'c',
ARG_GRAPHICS = 'g',
ARG_FULLSCREEN = 'F',
ARG_RESOLUTION = 'R',
ARG_LIST_MODES = 0xff01,
ARG_VERSION = 0xff02,
};
/**
* Set the arg_* members
*/
bool Main::parse_args (int argc, char **argv) {
// set up the options
args.add_option(ARG_HELP, "help", "",
"display argument help and exit");
args.add_option(ARG_PORT, "port", "PORT",
"set network port used");
args.add_option(ARG_SERVER, "server", "",
"act as a network server");
args.add_option(ARG_CLIENT, "client", "SERVERHOST",
"act as a network client");
args.add_option(ARG_GRAPHICS, "graphics", "",
"run graphics/local input. Implied with --connect");
args.add_option(ARG_FULLSCREEN, "fullscreen", "",
"run graphics in fullscreen mode");
args.add_option(ARG_RESOLUTION, "resolution", "WIDTHxHEIGHT",
"set graphics resolution");
args.add_option(ARG_LIST_MODES, "list-modes", "",
"output a list of available display modes and exit");
args.add_option(ARG_VERSION, "version", "",
"output application version and exit");
// set defaults
arg_graphics = false;
arg_port = NETWORK_PORT_STR;
arg_server = false;
arg_connect = "";
arg_fullscreen = GRAPHICS_FULLSCREEN;
arg_resolution = PixelCoordinate(GRAPHICS_RESOLUTION_WIDTH, GRAPHICS_RESOLUTION_HEIGHT);
// extra state
bool resolution_default = true;
try {
// parse args
args.parse_args(argc, argv);
} catch (CL_Error &e) {
throw ArgumentError(e.message);
}
while (args.next()) {
switch (args.get_key()) {
case ARG_HELP:
args.print_help();
return false;
case ARG_PORT:
arg_port = args.get_argument();
break;
case ARG_SERVER:
arg_server = true;
break;
case ARG_CLIENT:
arg_connect = args.get_argument();
break;
case ARG_GRAPHICS:
arg_graphics = true;
break;
case ARG_FULLSCREEN:
arg_fullscreen = true;
// choose best resolution unless explicitly set
if (resolution_default) {
const CL_DisplayMode best_mode = Graphics::getBestMode();
const CL_Size best_resolution = best_mode.get_resolution();
arg_resolution = PixelCoordinate(best_resolution.width, best_resolution.height);
}
break;
case ARG_RESOLUTION:
parse_arg_resolution(args.get_argument());
resolution_default = false;
break;
case ARG_LIST_MODES:
dump_display_modes();
return false;
case ARG_VERSION:
dump_version();
return false;
case CL_CommandLine::REST_ARG:
throw ArgumentError(args.get_argument());
default:
throw ArgumentError(std::string(1, (char) args.get_key()));
}
}
// check for invalid combinations of arugments
if (arg_server and !arg_connect.empty())
throw ArgumentError("cannot be both server and client");
// enable graphics by default unless server
if (!arg_server)
arg_graphics = true;
// continue
return true;
}
void Main::parse_arg_resolution (const std::string &val) {
unsigned int w, h;
// sccanf as unsigned
if (sscanf(val.c_str(), "%ux%u", &w, &h) != 2)
throw ArgumentError("invalid format for --resolution");
// store as PixelCoordinate
arg_resolution = PixelCoordinate(w, h);
}
void Main::dump_display_modes (void) {
const std::vector<CL_DisplayMode> &modes = Graphics::getDisplayModes();
std::cout << "Available display modes:" << std::endl;
for (std::vector<CL_DisplayMode>::const_iterator it = modes.begin(); it != modes.end(); it++)
std::cout << "\t" << it->get_resolution().width << "x" << it->get_resolution().height << std::endl;
}
void Main::dump_version (void) {
std::cout << PROJECT_LONG_NAME << " version " << PROJECT_VERSION << " built " << PROJECT_BUILD_TIMESTAMP << std::endl;
}
/**
* IT BEGAN IN AFRIKA
*/
int Main::main (int argc, char **argv) {
// initialize the ClanLib components that we use
CL_SetupCore setup_core;
CL_SetupNetwork setup_network;
CL_SetupDisplay setup_disp;
CL_SetupGL setup_gl;
try {
// parse arugments, exit if false
if (parse_args(argc, argv) == false)
return 0;
// our engine
Engine engine;
// setup graphics
if (arg_graphics)
engine.setupGraphics(arg_resolution, arg_fullscreen);
// setup either network server, client or singleplayer
if (arg_server) {
engine.setupNetworkServer(arg_port);
} else if (!arg_connect.empty()) {
engine.setupNetworkClient(arg_connect, arg_port);
} else {
engine.setupSinglePlayer();
}
// run the main loop
engine.run();
// succesful return
return 0;
} catch (ArgumentError &e) {
std::cerr << e.what() << std::endl;
args.print_help();
// XXX: handle --help
return 1;
} catch (CL_Error &e) {
std::cerr << "main: CL_Error:" << e.message << std::endl;
return 1;
} catch (std::exception &e) {
std::cerr << "FATAL [uncaught_exception] " << e.what() << std::endl;
return 1;
}
}