/* orxonox - the future of 3D-vertical-scrollers Copyright (C) 2004 orx This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. ### File Specific: main-programmer: Patrick Boenzli co-programmer: Christian Meyer co-programmer: Benjamin Grauer: injected ResourceManager/GraphicsEngine/GUI */ #define DEBUG_SPECIAL_MODULE DEBUG_MODULE_ORXONOX #include "orxonox.h" #include "globals.h" #include "gui.h" #include "world.h" #include "ini_parser.h" #include "game_loader.h" //ENGINES #include "graphics_engine.h" #include "sound_engine.h" #include "resource_manager.h" #include "cd_engine.h" #include "text_engine.h" #include "event_handler.h" #include "garbage_collector.h" #include "factory.h" #include "fast_factory.h" #include "benchmark.h" #include "class_list.h" #include "shell_command_class.h" #include "shell_command.h" #include "shell_buffer.h" #include "load_param_description.h" #include "network_manager.h" #include int verbose = 4; using namespace std; SHELL_COMMAND(restart, Orxonox, restart); /** * create a new Orxonox In this funcitons only global values are set. The game will not be started here. */ Orxonox::Orxonox () { this->setClassID(CL_ORXONOX, "Orxonox"); this->setName("orxonox-main"); this->iniParser = NULL; this->argc = 0; this->argv = NULL; /* this way, there is no network enabled: */ this->clientName = NULL; this->port = -1; this->configFileName = NULL; } /** * remove Orxonox from memory */ Orxonox::~Orxonox () { // game-specific delete GameLoader::getInstance(); delete GarbageCollector::getInstance(); // class-less services/factories delete Factory::getFirst(); FastFactory::deleteAll(); ShellCommandClass::unregisterAllCommands(); LoadClassDescription::deleteAllDescriptions(); // engines delete CDEngine::getInstance(); delete SoundEngine::getInstance(); delete GraphicsEngine::getInstance(); // deleting the Graphics delete EventHandler::getInstance(); // handlers delete ResourceManager::getInstance(); // deletes the Resource Manager // output-buffer delete ShellBuffer::getInstance(); // orxonox class-stuff delete this->iniParser; delete[] this->configFileName; SDL_QuitSubSystem(SDL_INIT_TIMER); ClassList::debug(); PRINT(3) ( "===================================================\n" \ "Thanks for playing orxonox.\n" \ "visit: http://www.orxonox.net for new versions.\n" \ "===================================================\n" \ ORXONOX_LICENSE_SHORT ); Orxonox::singletonRef = NULL; } /** * this is a singleton class to prevent duplicates */ Orxonox* Orxonox::singletonRef = NULL; // DANGEROUS void Orxonox::restart() { // int argc = this->argc; // char** argv = this->argv; // // Orxonox *orx = Orxonox::getInstance(); // // delete orx; // // orx = Orxonox::getInstance(); // // if((*orx).init(argc, argv) == -1) // { // PRINTF(1)("! Orxonox initialization failed\n"); // return; // } // // printf("finished inizialisation\n"); // orx->start(); } /** * this finds the config file * @returns the new config-fileName * Since the config file varies from user to user and since one may want to specify different config files * for certain occasions or platforms this function finds the right config file for every occasion and stores * it's path and name into configfilename */ const char* Orxonox::getConfigFile () { if (ResourceManager::isFile("orxonox.conf")) { this->configFileName = new char[strlen("orxonox.conf")+1]; strcpy(this->configFileName, "orxonox.conf"); } else this->configFileName = ResourceManager::homeDirCheck(DEFAULT_CONFIG_FILE); this->iniParser = new IniParser(this->configFileName); PRINTF(3)("Parsed Config File: '%s'\n", this->configFileName); } /** * initialize Orxonox with command line */ int Orxonox::init (int argc, char** argv, const char* name, int port) { this->argc = argc; this->argv = argv; this->clientName = name; this->port = port; // initialize the Config-file this->getConfigFile(); // windows must not write into stdout.txt and stderr.txt #ifdef __WIN32__ freopen( "CON", "w", stdout ); freopen( "CON", "w", stderr ); #endif // initialize everything SDL_Init(SDL_INIT_TIMER); if( initResources () == -1) return -1; if( initVideo() == -1) return -1; if( initSound() == -1) return -1; if( initInput() == -1) return -1; if( initNetworking () == -1) return -1; if( initMisc () == -1) return -1; return 0; } /** * initializes SDL and OpenGL */ int Orxonox::initVideo() { PRINTF(3)("> Initializing video\n"); GraphicsEngine::getInstance(); GraphicsEngine::getInstance()->initFromIniFile(this->iniParser); char* iconName = ResourceManager::getFullName("pictures/fighter-top-32x32.bmp"); if (iconName != NULL) { GraphicsEngine::getInstance()->setWindowName(PACKAGE_NAME " " PACKAGE_VERSION, iconName); delete[] iconName; } return 0; } /** * initializes the sound engine */ int Orxonox::initSound() { PRINT(3)("> Initializing sound\n"); // SDL_InitSubSystem(SDL_INIT_AUDIO); SoundEngine::getInstance()->initAudio(); SoundEngine::getInstance()->loadSettings(this->iniParser); return 0; } /** * initializes input functions */ int Orxonox::initInput() { PRINT(3)("> Initializing input\n"); EventHandler::getInstance()->init(this->iniParser); EventHandler::getInstance()->subscribe(GraphicsEngine::getInstance(), ES_ALL, EV_VIDEO_RESIZE); return 0; } /** * initializes network system */ int Orxonox::initNetworking() { PRINT(3)("> Initializing networking\n"); NetworkManager::getInstance(); if( this->clientName != NULL) // we are a client NetworkManager::getInstance()->establishConnection(this->clientName, port); else if( this->port > 0) // we are a server NetworkManager::getInstance()->createServer(port); return 0; } /** * initializes and loads resource files */ int Orxonox::initResources() { PRINTF(3)("> Initializing resources\n"); PRINT(3)("initializing ResourceManager\n"); // init the resource manager const char* dataPath; if ((dataPath = this->iniParser->getVar(CONFIG_NAME_DATADIR, CONFIG_SECTION_DATA))!= NULL) { if (!ResourceManager::getInstance()->setDataDir(dataPath) && !ResourceManager::getInstance()->verifyDataDir(DEFAULT_DATA_DIR_CHECKFILE)) { PRINTF(1)("Data Could not be located in %s\n", dataPath); } } if (!ResourceManager::getInstance()->verifyDataDir(DEFAULT_DATA_DIR_CHECKFILE)) { PRINTF(1)("The DataDirectory %s could not be verified\n\nh" \ "!!! Please Change in File %s Section %s Entry %s to a suitable value !!!\n", ResourceManager::getInstance()->getDataDir(), this->configFileName, CONFIG_SECTION_DATA, CONFIG_NAME_DATADIR ); Gui* gui = new Gui(argc, argv); gui->startGui(); delete gui; exit(-1); } //! @todo this is a hack and should be loadable char* imageDir = ResourceManager::getInstance()->getFullName("maps"); ResourceManager::getInstance()->addImageDir(imageDir); delete[] imageDir; // start the collision detection engine CDEngine::getInstance(); return 0; } /** * initializes miscelaneous features * @return -1 on failure */ int Orxonox::initMisc() { ShellBuffer::getInstance(); return 0; } /** * starts the orxonox game or menu * here is the central orxonox state manager. There are currently two states * - menu * - game-play * both states manage their states themselfs again. */ void Orxonox::start() { this->gameLoader = GameLoader::getInstance(); this->gameLoader->loadCampaign("worlds/DefaultCampaign.oxc"); // this->gameLoader->loadDebugCampaign(DEBUG_CAMPAIGN_0); this->gameLoader->init(); this->gameLoader->start(); } /** * handles sprecial events from localinput * @param event: an event not handled by the CommandNode */ // void Orxonox::graphicsHandler(SDL_Event* event) // { // // Handle special events such as reshape, quit, focus changes // switch (event->type) // { // case SDL_VIDEORESIZE: // GraphicsEngine* tmpGEngine = GraphicsEngine::getInstance(); // tmpGEngine->resolutionChanged(event->resize); // break; // } // } bool showGui = false; /********************************** *** ORXONOX MAIN STARTING POINT *** **********************************/ /** * * main function * * here the journey begins */ int main(int argc, char** argv) { int i; for(i = 1; i < argc; ++i) { if( !strcmp( "--help", argv[i]) || !strcmp("-h", argv[i])) return showHelp(argc, argv); else if(!strcmp( "--gui", argv[i]) || !strcmp("-g", argv[i])) showGui = true; else if(!strcmp( "--client", argv[i]) || !strcmp("-c", argv[i])) return startNetworkOrxonox(argc, argv); else if(!strcmp( "--server", argv[i]) || !strcmp("-s", argv[i])) return startNetworkOrxonox(argc, argv); else if(!strcmp( "--license", argv[i]) || !strcmp("-s", argv[i])) return PRINT(0)(ORXONOX_LICENSE_SHORT); } return startOrxonox(argc, argv, NULL, -1); } int showHelp(int argc, char** argv) { PRINT(0)("Orxonox Version %s\n", PACKAGE_VERSION); PRINT(0)(" Starts Orxonox - The most furious 3D Action Game :)\n"); PRINT(0)("\n"); PRINT(0)("Common options:\n"); PRINT(0)(" -g, --gui starts the orxonox with the configuration GUI \n"); PRINT(0)(" -h, --help shows this help\n"); PRINT(0)("\n"); PRINT(0)("Network options:\n"); PRINT(0)(" -s, --server [port] starts Orxonox and listens on the [port] for players\n"); PRINT(0)(" -c, --client [hostname] [port] starts Orxonox as a Client\n"); PRINT(0)(" -c, --client [ip address] [port] starts Orxonox as a Client\n"); PRINT(0)("\n"); PRINT(0)("Other options:\n"); PRINT(0)(" --license prints the licence and exit\n\n"); PRINT(0)("\n"); // { // Gui* gui = new Gui(argc, argv); // gui->printHelp(); // delete gui; // } } /** * starts orxonox in network mode * @param argc parameters count given to orxonox * @param argv parameters given to orxonox */ int startNetworkOrxonox(int argc, char** argv) { int i; for(i = 0; i < argc; ++i ) { if( !strcmp( "--client", argv[i]) || !strcmp("-c", argv[i])) { if( argc <= (i+2)) { printf(" Wrong arguments try following notations:\n"); printf(" --client [server ip address] [port number]\n"); printf(" --client [dns name] [port number]\n"); return 0; } const char* name = argv[i+1]; int port = atoi(argv[i+2]); printf("Starting Orxonox as client: connecting to %s, on port %i\n", name, port); startOrxonox(argc, argv, name, port); } else if( !strcmp( "--server", argv[i]) || !strcmp("-s", argv[i])) { if( argc <= (i+1)) { printf(" Wrong arguments try following notations:\n"); printf(" --server [port number]\n"); return 0; } int port = atoi(argv[i+1]); printf("Starting Orxonox as server, listening on port %i\n", port); startOrxonox(argc, argv, NULL, port); } } } /** * starts orxonox * @param argc parameters count given to orxonox * @param argv parameters given to orxonox */ int startOrxonox(int argc, char** argv, const char* name, int port) { // checking for existence of the configuration-files, or if the lock file is still used if (showGui || (!ResourceManager::isFile("./orxonox.conf") && !ResourceManager::isFile(DEFAULT_CONFIG_FILE)) #if DEBUG < 3 // developers do not need to see the GUI, when orxonox fails || ResourceManager::isFile(DEFAULT_LOCK_FILE) #endif ) { if (ResourceManager::isFile(DEFAULT_LOCK_FILE)) ResourceManager::deleteFile(DEFAULT_LOCK_FILE); // starting the GUI Gui* gui = new Gui(argc, argv); gui->startGui(); if (! gui->startOrxonox) return 0; delete gui; } PRINT(0)(">>> Starting Orxonox <<<\n"); ResourceManager::touchFile(DEFAULT_LOCK_FILE); Orxonox *orx = Orxonox::getInstance(); if( orx->init(argc, argv, name, port) == -1) { PRINTF(1)("! Orxonox initialization failed\n"); return -1; } printf("finished inizialisation\n"); orx->start(); delete orx; ResourceManager::deleteFile("~/.orxonox/orxonox.lock"); }