/src/

ass="hl opt">; } // Passed to menus to allow disconnecting and exiting MainGameCallback *g_gamecallback = NULL; // Instance of the time getter static TimeGetter *g_timegetter = NULL; u32 getTimeMs() { if (g_timegetter == NULL) return 0; return g_timegetter->getTime(PRECISION_MILLI); } u32 getTime(TimePrecision prec) { if (g_timegetter == NULL) return 0; return g_timegetter->getTime(prec); } ClientLauncher::~ClientLauncher() { if (receiver) delete receiver; if (input) delete input; if (g_fontengine) delete g_fontengine; if (device) device->drop(); } bool ClientLauncher::run(GameParams &game_params, const Settings &cmd_args) { init_args(game_params, cmd_args); // List video modes if requested if (list_video_modes) return print_video_modes(); if (!init_engine()) { errorstream << "Could not initialize game engine." << std::endl; return false; } // Create time getter g_timegetter = new IrrlichtTimeGetter(device); // Speed tests (done after irrlicht is loaded to get timer) if (cmd_args.getFlag("speedtests")) { dstream << "Running speed tests" << std::endl; speed_tests(); return true; } video::IVideoDriver *video_driver = device->getVideoDriver(); if (video_driver == NULL) { errorstream << "Could not initialize video driver." << std::endl; return false; } porting::setXorgClassHint(video_driver->getExposedVideoData(), PROJECT_NAME_C); /* This changes the minimum allowed number of vertices in a VBO. Default is 500. */ //driver->setMinHardwareBufferVertexCount(50); // Create game callback for menus g_gamecallback = new MainGameCallback(device); device->setResizable(true); if (random_input) input = new RandomInputHandler(); else input = new RealInputHandler(device, receiver); smgr = device->getSceneManager(); smgr->getParameters()->setAttribute(scene::ALLOW_ZWRITE_ON_TRANSPARENT, true); guienv = device->getGUIEnvironment(); skin = guienv->getSkin(); skin->setColor(gui::EGDC_BUTTON_TEXT, video::SColor(255, 255, 255, 255)); skin->setColor(gui::EGDC_3D_LIGHT, video::SColor(0, 0, 0, 0)); skin->setColor(gui::EGDC_3D_HIGH_LIGHT, video::SColor(255, 30, 30, 30)); skin->setColor(gui::EGDC_3D_SHADOW, video::SColor(255, 0, 0, 0)); skin->setColor(gui::EGDC_HIGH_LIGHT, video::SColor(255, 70, 120, 50)); skin->setColor(gui::EGDC_HIGH_LIGHT_TEXT, video::SColor(255, 255, 255, 255)); g_fontengine = new FontEngine(g_settings, guienv); FATAL_ERROR_IF(g_fontengine == NULL, "Font engine creation failed."); #if (IRRLICHT_VERSION_MAJOR >= 1 && IRRLICHT_VERSION_MINOR >= 8) || IRRLICHT_VERSION_MAJOR >= 2 // Irrlicht 1.8 input colours skin->setColor(gui::EGDC_EDITABLE, video::SColor(255, 128, 128, 128)); skin->setColor(gui::EGDC_FOCUSED_EDITABLE, video::SColor(255, 96, 134, 49)); #endif // Create the menu clouds if (!g_menucloudsmgr) g_menucloudsmgr = smgr->createNewSceneManager(); if (!g_menuclouds) g_menuclouds = new Clouds(g_menucloudsmgr->getRootSceneNode(), g_menucloudsmgr, -1, rand(), 100); g_menuclouds->update(v2f(0, 0), video::SColor(255, 200, 200, 255)); scene::ICameraSceneNode* camera; camera = g_menucloudsmgr->addCameraSceneNode(0, v3f(0, 0, 0), v3f(0, 60, 100)); camera->setFarValue(10000); /* GUI stuff */ ChatBackend chat_backend; // If an error occurs, this is set to something by menu(). // It is then displayed before the menu shows on the next call to menu() std::string error_message; bool reconnect_requested = false; bool first_loop = true; /* Menu-game loop */ bool retval = true; bool *kill = porting::signal_handler_killstatus(); while (device->run() && !*kill && !g_gamecallback->shutdown_requested) { // Set the window caption const wchar_t *text = wgettext("Main Menu"); device->setWindowCaption((utf8_to_wide(PROJECT_NAME_C) + L" [" + text + L"]").c_str()); delete[] text; try { // This is used for catching disconnects guienv->clear(); /* We need some kind of a root node to be able to add custom gui elements directly on the screen. Otherwise they won't be automatically drawn. */ guiroot = guienv->addStaticText(L"", core::rect<s32>(0, 0, 10000, 10000)); bool game_has_run = launch_game(error_message, reconnect_requested, game_params, cmd_args); // If skip_main_menu, we only want to startup once if (skip_main_menu && !first_loop) break; first_loop = false; if (!game_has_run) { if (skip_main_menu) break; else continue; } // Break out of menu-game loop to shut down cleanly if (!device->run() || *kill) { if (g_settings_path != "") g_settings->updateConfigFile(g_settings_path.c_str()); break; } if (current_playername.length() > PLAYERNAME_SIZE-1) { error_message = gettext("Player name too long."); playername = current_playername.substr(0, PLAYERNAME_SIZE-1); g_settings->set("name", playername); continue; } device->getVideoDriver()->setTextureCreationFlag( video::ETCF_CREATE_MIP_MAPS, g_settings->getBool("mip_map")); #ifdef HAVE_TOUCHSCREENGUI receiver->m_touchscreengui = new TouchScreenGUI(device, receiver); g_touchscreengui = receiver->m_touchscreengui; #endif the_game( kill, random_input, input, device, worldspec.path, current_playername, current_password, current_address, current_port, error_message, chat_backend, &reconnect_requested, gamespec, simple_singleplayer_mode ); smgr->clear(); #ifdef HAVE_TOUCHSCREENGUI delete g_touchscreengui; g_touchscreengui = NULL; receiver->m_touchscreengui = NULL; #endif } //try catch (con::PeerNotFoundException &e) { error_message = gettext("Connection error (timed out?)"); errorstream << error_message << std::endl; } #ifdef NDEBUG catch (std::exception &e) { std::string error_message = "Some exception: \""; error_message += e.what(); error_message += "\""; errorstream << error_message << std::endl; } #endif // If no main menu, show error and exit if (skip_main_menu) { if (!error_message.empty()) { verbosestream << "error_message = " << error_message << std::endl; retval = false; } break; } } // Menu-game loop g_menuclouds->drop(); g_menucloudsmgr->drop(); return retval; } void ClientLauncher::init_args(GameParams &game_params, const Settings &cmd_args) { skip_main_menu = cmd_args.getFlag("go"); // FIXME: This is confusing (but correct) /* If world_path is set then override it unless skipping the main menu using * the --go command line param. Else, give preference to the address * supplied on the command line */ address = g_settings->get("address"); if (game_params.world_path != "" && !skip_main_menu) address = ""; else if (cmd_args.exists("address")) address = cmd_args.get("address"); playername = g_settings->get("name"); if (cmd_args.exists("name")) playername = cmd_args.get("name"); list_video_modes = cmd_args.getFlag("videomodes"); use_freetype = g_settings->getBool("freetype"); random_input = g_settings->getBool("random_input") || cmd_args.getFlag("random-input"); } bool ClientLauncher::init_engine() { receiver = new MyEventReceiver(); create_engine_device(); return device != NULL; } bool ClientLauncher::launch_game(std::string &error_message, bool reconnect_requested, GameParams &game_params, const Settings &cmd_args) { // Initialize menu data MainMenuData menudata; menudata.address = address; menudata.name = playername; menudata.port = itos(game_params.socket_port);