# HG changeset patch # User Tero Marttila # Date 1231870623 -7200 # Node ID e74c1820fbd2ec22e77316fa1af85efcab191d40 # Parent ecb243eebc2585e2137c9f856ebcac2c105135a3 implement --help, --fullscreen, --resolution and --list-modes diff -r ecb243eebc25 -r e74c1820fbd2 src/Application.cc --- a/src/Application.cc Tue Jan 13 16:11:37 2009 +0000 +++ b/src/Application.cc Tue Jan 13 20:17:03 2009 +0200 @@ -2,24 +2,58 @@ #include "Application.hh" #include +#include #include +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, +}; + /** * Set the arg_* members */ -void Main::parse_args (int argc, char **argv) { +bool Main::parse_args (int argc, char **argv) { // set up the options - args.add_option('p', "port", "PORT", "set network port used", true); - args.add_option('s', "server", "", "act as a network server", true); - args.add_option('c', "client", "SERVERHOST", "act as a network client", true); - args.add_option('g', "graphics", "", "run graphics/local input. Implied with --connect", true); + 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"); // 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 graphics_default = true; @@ -34,22 +68,38 @@ while (args.next()) { switch (args.get_key()) { - case 'p': + case ARG_HELP: + args.print_help(); + return false; + + case ARG_PORT: arg_port = args.get_argument(); break; - case 's': + case ARG_SERVER: arg_server = true; break; - case 'c': + case ARG_CLIENT: arg_connect = args.get_argument(); break; - case 'g': + case ARG_GRAPHICS: arg_graphics = true; break; + case ARG_FULLSCREEN: + arg_fullscreen = true; + break; + + case ARG_RESOLUTION: + parse_arg_resolution(args.get_argument()); + break; + + case ARG_LIST_MODES: + dump_display_modes(); + return false; + case CL_CommandLine::REST_ARG: throw ArgumentError(args.get_argument()); @@ -66,6 +116,29 @@ // enable graphics by default unless server if (!arg_server && graphics_default) 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 &modes = Graphics::getDisplayModes(); + + std::cout << "Available display modes:" << std::endl; + + for (std::vector::const_iterator it = modes.begin(); it != modes.end(); it++) + std::cout << "\t" << it->get_resolution().width << "x" << it->get_resolution().height << std::endl; } /** @@ -79,15 +152,16 @@ CL_SetupGL setup_gl; try { - // parse arugments - parse_args(argc, argv); + // parse arugments, exit if false + if (parse_args(argc, argv) == false) + return 0; // our engine Engine engine; // setup graphics if (arg_graphics) - engine.setupGraphics(); + engine.setupGraphics(arg_resolution, arg_fullscreen); // setup either network server, client or singleplayer if (arg_server) { diff -r ecb243eebc25 -r e74c1820fbd2 src/Application.hh --- a/src/Application.hh Tue Jan 13 16:11:37 2009 +0000 +++ b/src/Application.hh Tue Jan 13 20:17:03 2009 +0200 @@ -39,11 +39,33 @@ * --connect */ std::string arg_connect; + + /** + * --fullscreen + */ + bool arg_fullscreen; + + /** + * --resolution + */ + PixelCoordinate arg_resolution; + + /** + * Set the arg_* members + * + * @return true if execution should proceed, false if execution should stop + */ + bool parse_args (int argc, char **argv); + + /** + * Parse and set --resolution/arg_resolution WIDTHxHEIGHT + */ + void parse_arg_resolution (const std::string &val); /** - * Set the arg_* members + * Print out a list of display modes */ - void parse_args (int argc, char **argv); + void dump_display_modes (void); public: /** diff -r ecb243eebc25 -r e74c1820fbd2 src/Config.hh --- a/src/Config.hh Tue Jan 13 16:11:37 2009 +0000 +++ b/src/Config.hh Tue Jan 13 20:17:03 2009 +0200 @@ -117,6 +117,7 @@ const uint32_t GRAPHICS_RESOLUTION_WIDTH = 800; const uint32_t GRAPHICS_RESOLUTION_HEIGHT = 600; const uint16_t GRAPHICS_UPDATE_INTERVAL_MS = 20; +const bool GRAPHICS_FULLSCREEN = false; // Filesystem paths diff -r ecb243eebc25 -r e74c1820fbd2 src/Engine.cc --- a/src/Engine.cc Tue Jan 13 16:11:37 2009 +0000 +++ b/src/Engine.cc Tue Jan 13 20:17:03 2009 +0200 @@ -12,9 +12,9 @@ } -void Engine::setupGraphics (void) { +void Engine::setupGraphics (PixelCoordinate resolution, bool fullscreen) { // create the graphics - graphics = new Graphics(*this, game_state); + graphics = new Graphics(*this, game_state, resolution, fullscreen); } void Engine::setupNetworkServer (const std::string &listen_port) { diff -r ecb243eebc25 -r e74c1820fbd2 src/Engine.hh --- a/src/Engine.hh Tue Jan 13 16:11:37 2009 +0000 +++ b/src/Engine.hh Tue Jan 13 20:17:03 2009 +0200 @@ -37,7 +37,7 @@ Engine (const std::string resource_xml_path = RESOURCE_XML_PATH); // setup graphics - void setupGraphics (void); + void setupGraphics (PixelCoordinate resolution, bool fullscreen); // set up network server/client // setting up both of these will lead to odd behaviour :) diff -r ecb243eebc25 -r e74c1820fbd2 src/Graphics.cc --- a/src/Graphics.cc Tue Jan 13 16:11:37 2009 +0000 +++ b/src/Graphics.cc Tue Jan 13 20:17:03 2009 +0200 @@ -4,11 +4,11 @@ #include #include -Graphics::Graphics (Engine &engine, GameState &state) : - CL_DisplayWindow(GRAPHICS_WINDOW_TITLE, GRAPHICS_RESOLUTION_WIDTH, GRAPHICS_RESOLUTION_HEIGHT), +Graphics::Graphics (Engine &engine, GameState &state, PixelCoordinate resolution, bool fullscreen) : + CL_DisplayWindow(GRAPHICS_WINDOW_TITLE, resolution.x, resolution.y, fullscreen), engine(engine), state(state), - resolution(GRAPHICS_RESOLUTION_WIDTH, GRAPHICS_RESOLUTION_HEIGHT), + resolution(resolution), update_timer(GRAPHICS_UPDATE_INTERVAL_MS), input(get_ic()->get_keyboard()), simple_font("Font2", engine.getResourceManager()) @@ -21,13 +21,33 @@ update_timer.start(); } +const std::vector & Graphics::getDisplayModes (void) { + return CL_DisplayMode::get_display_modes(); +} + void Graphics::check_input (void) { LocalPlayer *player; PlayerInput input_mask; TimeMS input_dt; // update gui flags - this->flags = input.readGuiInput(); + handle_input(input.readGuiInput()); + + // stop here if we don't have a local player + if ((player = state.getLocalPlayer()) == NULL) + return; + + // build input_mask + input.readPlayerInput(input_mask, input_dt); + + // apply input if there was any + if (input_mask) + player->handleInput(input_mask, input_dt); +} + +void Graphics::handle_input (GuiInput flags) { + // update flags + this->flags = flags; // quit? if (flags & GUI_INPUT_QUIT) { @@ -35,21 +55,18 @@ return; } - - // stop here if we don't have a local player - if ((player = state.getLocalPlayer()) == NULL) - return; + + // dump player debug info on stderr + if ((flags & GUI_INPUT_DEBUG_PLAYER) && state.getLocalPlayer()) + state.getLocalPlayer()->printDebugInfo(); - // dump debug info on stderr - if (flags & GUI_INPUT_DEBUG_PLAYER) - player->printDebugInfo(); - - // build input_mask - input.readPlayerInput(input_mask, input_dt); - - // apply input if there was any - if (input_mask) - player->handleInput(input_mask, input_dt); + // toggle fullscreen? + if (flags & GUI_INPUT_TOGGLE_FULLSCREEN) { + if (is_fullscreen()) + set_windowed(); + else + set_fullscreen(); + } } static PixelDimension value_between (PixelDimension low, PixelDimension value, PixelDimension high) { @@ -114,10 +131,10 @@ } void Graphics::draw_player_info(CL_GraphicContext *gc, Player *p) { - int box_top = GRAPHICS_RESOLUTION_HEIGHT - 100; + int box_top = resolution.y - 100; int box_left = 0; - int box_right = GRAPHICS_RESOLUTION_WIDTH; - int box_bottom = GRAPHICS_RESOLUTION_HEIGHT; + int box_right = resolution.x; + int box_bottom = resolution.y; int bar_length = 3; // *100 // draw status info at bottom of display diff -r ecb243eebc25 -r e74c1820fbd2 src/Graphics.hh --- a/src/Graphics.hh Tue Jan 13 16:11:37 2009 +0000 +++ b/src/Graphics.hh Tue Jan 13 20:17:03 2009 +0200 @@ -37,12 +37,24 @@ CL_Font simple_font; public: - Graphics (Engine &engine, GameState &state); + Graphics (Engine &engine, GameState &state, PixelCoordinate resolution, bool fullscreen); CL_Font& getSimpleFont (void) { return simple_font; } + + static const std::vector & getDisplayModes (void); private: + /** + * Reads current input events from Input and applies them, using LocalPlayer::handleInput and + * Graphics::handle_input. + */ void check_input (void); + + /** + * Handles GuiInput flags read from Input. + */ + void handle_input (GuiInput flags); + void do_redraw (void); void on_update (TimeMS tick_length); diff -r ecb243eebc25 -r e74c1820fbd2 src/Input.cc --- a/src/Input.cc Tue Jan 13 16:11:37 2009 +0000 +++ b/src/Input.cc Tue Jan 13 20:17:03 2009 +0200 @@ -22,10 +22,11 @@ }; InputKeymapEntry INPUT_GUI_KEYMAP[] = { - { GUI_INPUT_QUIT, 0, { CL_KEY_ESCAPE, 0 } }, - { GUI_INPUT_DISPLAY_WEAPON, 0, { CL_KEY_ENTER, 0 } }, - { GUI_INPUT_DEBUG_PLAYER, 0, { CL_KEY_I, 0 } }, - { GUI_INPUT_NONE, 0, { 0, 0, } } + { GUI_INPUT_QUIT, 0, { CL_KEY_ESCAPE, 0 } }, + { GUI_INPUT_DISPLAY_WEAPON, 0, { CL_KEY_ENTER, 0 } }, + { GUI_INPUT_DEBUG_PLAYER, 0, { CL_KEY_I, 0 } }, + { GUI_INPUT_TOGGLE_FULLSCREEN, INPUT_FLAG_NOREPEAT,{ CL_KEY_LCONTROL, CL_KEY_F } }, + { GUI_INPUT_NONE, 0, { 0, 0, } } }; /* diff -r ecb243eebc25 -r e74c1820fbd2 src/Input.hh --- a/src/Input.hh Tue Jan 13 16:11:37 2009 +0000 +++ b/src/Input.hh Tue Jan 13 20:17:03 2009 +0200 @@ -68,6 +68,8 @@ GUI_INPUT_QUIT = 0x0001, GUI_INPUT_DISPLAY_WEAPON = 0x0002, GUI_INPUT_DEBUG_PLAYER = 0x0004, + + GUI_INPUT_TOGGLE_FULLSCREEN = 0x0008, }; /**