terom@21: terom@21: #include "Engine.hh" terom@21: terom@21: #include terom@21: #include terom@21: terom@21: #include terom@21: #include terom@21: terom@21: class ArgumentError : public std::exception { terom@24: private: terom@24: const char *message; terom@24: terom@24: public: terom@24: ArgumentError (const std::string &message) : message(message.c_str()) { } terom@21: terom@24: virtual const char* what() const throw() { terom@24: return message; terom@24: } terom@21: }; terom@21: terom@21: class Main : public CL_ClanApplication { terom@24: private: terom@24: // arguments terom@24: CL_CommandLine args; terom@25: terom@25: bool arg_graphics; terom@24: std::string arg_port; terom@25: bool arg_server; terom@24: std::string arg_connect; terom@21: terom@24: void parse_args (int argc, char **argv) { terom@24: // set up the options terom@24: args.add_option('p', "port", "PORT", "set network port used", true); terom@25: args.add_option('s', "server", "", "act as a network server", true); terom@25: args.add_option('c', "client", "SERVERHOST", "act as a network client", true); terom@25: args.add_option('g', "graphics", "", "run graphics/local input. Implied with --connect", true); terom@21: terom@24: // set defaults terom@25: arg_graphics = false; terom@24: arg_port = NETWORK_PORT_STR; terom@25: arg_server = false; terom@24: arg_connect = ""; terom@24: terom@24: try { terom@24: // parse args terom@24: args.parse_args(argc, argv); terom@25: terom@24: } catch (CL_Error &e) { terom@24: throw ArgumentError(e.message); terom@24: } terom@21: terom@24: while (args.next()) { terom@24: switch (args.get_key()) { terom@24: case 'p': terom@24: arg_port = args.get_argument(); terom@24: break; terom@21: terom@25: case 's': terom@25: arg_server = true; terom@24: break; terom@21: terom@24: case 'c': terom@24: arg_connect = args.get_argument(); terom@25: arg_graphics = true; terom@25: break; terom@25: terom@25: case 'g': terom@25: arg_graphics = true; terom@24: break; terom@24: terom@24: case CL_CommandLine::REST_ARG: terom@24: throw ArgumentError(args.get_argument()); terom@24: terom@24: default: terom@24: throw ArgumentError(std::string(1, (char) args.get_key())); terom@24: terom@24: } terom@24: } terom@24: terom@24: // check for valid combinations of arugments terom@25: if (!(arg_server xor !arg_connect.empty())) terom@25: throw ArgumentError("must supply *exactly* one of --server/--client"); terom@24: } terom@24: terom@24: public: terom@24: virtual int main (int argc, char **argv) { terom@25: // initialize the ClanLib components that we use terom@24: CL_SetupCore setup_core; terom@25: CL_SetupNetwork setup_network; terom@25: CL_SetupDisplay setup_disp; terom@25: CL_SetupGL setup_gl; terom@25: terom@24: try { terom@24: // parse arugments terom@24: parse_args(argc, argv); terom@25: terom@25: // our engine terom@25: Engine engine; terom@24: terom@25: // setup graphics terom@25: if (arg_graphics) terom@25: engine.setupGraphics(); terom@25: terom@25: // setup either network server or client terom@25: if (arg_server) { terom@25: engine.setupNetworkServer(arg_port); terom@24: terom@24: } else if (!arg_connect.empty()) { terom@25: engine.setupNetworkClient(arg_connect, arg_port); terom@24: terom@24: } else terom@24: assert(false); terom@25: terom@25: // run the main loop terom@25: engine.run(); terom@24: terom@24: // succesful return terom@24: return 0; terom@24: terom@24: } catch (ArgumentError &e) { terom@24: std::cerr << e.what() << std::endl; terom@24: args.print_help(); terom@24: terom@24: // XXX: handle --help terom@24: return 1; terom@24: terom@24: } catch (std::exception &e) { terom@24: std::cerr << e.what() << std::endl; terom@24: terom@24: return 1; terom@24: } terom@24: } terom@21: } app; terom@21: