/* 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 */ #include "orxonox.h" #include "world.h" #include "camera.h" #include "data_tank.h" #include "command_node.h" #include "game_loader.h" #include using namespace std; /** \brief create a new Orxonox */ Orxonox::Orxonox () { pause = false; } /** \brief remove Orxonox from memory */ Orxonox::~Orxonox () { Orxonox::singleton_ref = NULL; if( world != NULL) delete world; if( localinput != NULL) delete world; if( localcamera != NULL) delete localcamera; if( resources != NULL) delete resources; } /* this is a singleton class to prevent duplicates */ Orxonox* Orxonox::singleton_ref = 0; Orxonox* Orxonox::getInstance (void) { if (singleton_ref == NULL) singleton_ref = new Orxonox(); return singleton_ref; } /** \brief this finds the config file 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 */ void Orxonox::get_config_file (int argc, char** argv) { /* char* path; #ifdef __WIN32__ path = getenv(""); #else path = getenv("HOME"); #endif if( path != NULL) strcpy (configfilename, path); else strcpy (configfilename, "./"); strcat (configfilename, "/.orxonox.conf");*/ strcpy (configfilename, "orxonox.conf"); } /** \brief initialize Orxonox with command line */ int Orxonox::init (int argc, char** argv) { // parse command line // config file get_config_file (argc, argv); // initialize SDL printf("> Initializing SDL\n"); if( SDL_Init (SDL_INIT_VIDEO) == -1) { printf ("Could not SDL_Init(): %s\n", SDL_GetError()); return -1; } // initialize everything printf("> Initializing video\n"); if( init_video () == -1) return -1; printf("> Initializing sound\n"); if( init_sound () == -1) return -1; printf("> Initializing input\n"); if( init_input () == -1) return -1; printf("> Initializing networking\n"); if( init_networking () == -1) return -1; printf("> Initializing resources\n"); if( init_resources () == -1) return -1; //printf("> Initializing world\n"); //if( init_world () == -1) return -1; PB: world will be initialized when started return 0; } /** \brief initializes SDL and OpenGL */ int Orxonox::init_video () { // Set video mode // TO DO: parse arguments for settings SDL_GL_SetAttribute (SDL_GL_RED_SIZE, 5); SDL_GL_SetAttribute (SDL_GL_GREEN_SIZE, 5); SDL_GL_SetAttribute (SDL_GL_BLUE_SIZE, 5); SDL_GL_SetAttribute (SDL_GL_DEPTH_SIZE, 16); int bpp = 16; int width = 640; int height = 480; Uint32 flags = SDL_HWSURFACE | SDL_OPENGL | SDL_GL_DOUBLEBUFFER; if( (screen = SDL_SetVideoMode (width, height, bpp, flags)) == NULL) { printf ("Could not SDL_SetVideoMode(%d, %d, %d, %d): %s\n", width, height, bpp, flags, SDL_GetError()); SDL_Quit(); return -1; } // Set window labeling // TO DO: Add version information to caption SDL_WM_SetCaption( "Orxonox", "Orxonox"); // TO DO: Create a cool icon and use it here // SDL_WM_SetIcon(SDL_Surface *icon, Uint8 *mask); // OpenGL stuff // (Is this all we initialize globally???) glClearColor(0.0, 0.0, 0.0, 0.0); glEnable(GL_DEPTH_TEST); // LIGHTING GLfloat lmodelAmbient[] = {.1, .1, .1, 1.0}; GLfloat whiteLight[] = {1.0, 1.0, 1.0,1.0}; GLfloat lightPosition[] = {10.0, 10, 19.0, 0.0}; glLightfv(GL_LIGHT0, GL_DIFFUSE, whiteLight); glLightfv(GL_LIGHT0, GL_SPECULAR, whiteLight); glEnable(GL_LIGHTING); glEnable(GL_LIGHT0); glEnable(GL_DEPTH_TEST); glLightfv(GL_LIGHT0, GL_POSITION, lightPosition); glLightfv(GL_LIGHT0, GL_DIFFUSE, whiteLight); // glEnable(GL_COLOR); // glShadeModel(GL_SMOOTH); // create camera localcamera = new Camera(world); return 0; } /** \brief initializes the sound engine */ int Orxonox::init_sound () { printf("Not yet implemented\n"); return 0; } /** \brief initializes input functions */ int Orxonox::init_input () { // create localinput localinput = new CommandNode( configfilename); return 0; } /** \brief initializes network system */ int Orxonox::init_networking () { printf("Not yet implemented\n"); return 0; } /** \brief initializes and loads resource files */ int Orxonox::init_resources () { printf("Not yet implemented\n"); return 0; } /** \brief initializes the world */ int Orxonox::init_world () { //world = new World(); // TO DO: replace this with a menu/intro //world->load_debug_level(); return 0; } /** \brief 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->loadDebugCampaign(DEBUG_CAMPAIGN_0); this->gameLoader->init(); this->gameLoader->start(); } /** \brief exits Orxonox */ void Orxonox::quitGame() { bQuitOrxonox = true; } /** \brief this runs all of Orxonox */ void Orxonox::mainLoop() { lastframe = SDL_GetTicks(); bQuitOrxonox = false; // This is where everything is run printf("Orxonox|Entering main loop\n"); while( !bQuitOrxonox) { // Network synchronize(); // Process input handle_input(); // Process time time_slice(); // Process collision collision(); // Draw display(); } printf("Orxonox|Exiting the main loop\n"); } /** \brief handles sprecial events from localinput \param event: an event not handled by the CommandNode */ void Orxonox::event_handler (SDL_Event* event) { // Handle special events such as reshape, quit, focus changes } /** \brief synchronize local data with remote data */ void Orxonox::synchronize () { // Get remote input // Update synchronizables } /** \brief run all input processing */ void Orxonox::handle_input () { // localinput localinput->process(); // remoteinput } /** \brief advance the timeline */ void Orxonox::time_slice () { Uint32 curframe = SDL_GetTicks(); if( !pause) { Uint32 dt = curframe - lastframe; if(dt > 0) { float fps = 1000/dt; printf("fps = %f\n", fps); } world->time_slice (dt); world->update (); localcamera->time_slice (dt); } lastframe = curframe; } /** \brief compute collision detection */ void Orxonox::collision () { world->collide (); } /** \brief handle keyboard commands that are not meant for WorldEntities \param cmd: the command to handle \return true if the command was handled by the system or false if it may be passed to the WorldEntities */ bool Orxonox::system_command (Command* cmd) { if( !strcmp( cmd->cmd, "quit")) { if( !cmd->bUp) this->gameLoader->stop(); return true; } return false; } /** \brief render the current frame */ void Orxonox::display () { // clear buffer glClear( GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT); // set camera localcamera->apply (); // draw world world->draw (); // draw HUD // flip buffers SDL_GL_SwapBuffers(); } /** \brief retrieve a pointer to the local Camera \return a pointer to localcamera */ Camera* Orxonox::get_camera () { return localcamera; } /** \brief retrieve a pointer to the local CommandNode \return a pointer to localinput */ CommandNode* Orxonox::get_localinput () { return localinput; } /** \brief retrieve a pointer to the local World \return a pointer to world */ World* Orxonox::get_world () { return world; } int main (int argc, char** argv) { printf(">>> Starting Orxonox <<<\n"); Orxonox *orx = Orxonox::getInstance(); if( (*orx).init(argc, argv) == -1) { printf("! Orxonox initialization failed\n"); return -1; } //(*orx).mainLoop(); orx->start(); //delete orx; return 0; }