/* 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: */ #include #include #include #include #include "environment.h" #include "world.h" #include "input_output.h" #include "data_tank.h" #include "stdincl.h" #include "player.h" #include "npc.h" #include "shoot_laser.h" #include "orxonox.h" using namespace std; Orxonox::Orxonox () { pause = false; } Orxonox::~Orxonox () {} /* this is a singleton class to prevent dublicates */ Orxonox* Orxonox::singleton_ref = 0; World* Orxonox::world = 0; InputOutput* Orxonox::io = 0; Player* Orxonox::localPlayer = 0; bool Orxonox::pause = false; bool Orxonox::inputEnabled = false; bool Orxonox::upWeGo = false; bool Orxonox::downWeGo = false; bool Orxonox::rightWeGo = false; bool Orxonox::leftWeGo = false; bool Orxonox::shoot1 = false; int Orxonox::fps = 0; int Orxonox::alpha = 0; int Orxonox::beta = 0; //int Orxonox::offsetX = 0; //int Orxonox::offsetY = 0; Orxonox* Orxonox::getInstance (void) { if (singleton_ref == NULL) singleton_ref = new Orxonox(); return singleton_ref; } int Orxonox::globalInit (int argc, char** argv) { if( SDL_Init (SDL_INIT_EVERYTHING) == -1) { printf ("Could not SDL_Init(): %s\n", SDL_GetError()); return -1; } // 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_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???) glEnable(GL_DEPTH_TEST); glShadeModel(GL_FLAT); // glutInit(&argc, argv); // glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH); // glutInitWindowSize(500, 500); // //glutFullScreen(); // glutInitWindowPosition(100, 100); // glutCreateWindow("OrxonoX"); // /* window event dispatchers */ // glutDisplayFunc(display); // glutReshapeFunc(reshape); // glutKeyboardFunc(keyboard); // glutKeyboardUpFunc(upKeyboard); // // glutTimerFunc(1000, timeSlice, 0); // cout << "measuring performance..."; } int Orxonox::menuInit (void) { glClearColor(0.0, 0.0, 0.0, 0.0); } int Orxonox::gameInit (void) { glClearColor(0.0, 0.0, 0.0, 0.0); /* world init, shouldnt be done here later */ world = new World; (*world).initEnvironement(); localPlayer = new Player; localPlayer->setPosition(0.0, -10.0, 3.0); localPlayer->setCollisionRadius(2.0); io = new InputOutput(world, localPlayer); (*world).addPlayer(localPlayer); Environment *env = new Environment; (*world).addEnv(env); NPC* npc = new NPC; npc->setPosition(3.0, 0.0, 3.0); npc->setCollisionRadius(1.0); world->addNPC(npc); NPC* npc2 = new NPC; npc2->setPosition(-2.0, 10.0, 3.0); npc2->setCollisionRadius(1.0); world->addNPC(npc2); glutSpecialFunc(specFunc); glutSpecialUpFunc(releaseKey); glutIdleFunc(continousRedraw); //cout << "Orxonox::gameInit" << endl; } /* this is the time triggered function. heart beat*/ void Orxonox::timeSlice(int value) { cout << "got " << fps << " fps" << endl; /* this is very very unsafe: io could be uninit */ io->setPlayerStep(19.2/fps); /* set player to propper speed */ localPlayer->shootLaser->setShootStep(20.0/fps); /* set shoot speed */ world->setWorldStep(7.0/fps); /* set the speed of the terrain moving away */ fps = 0; inputEnabled = true; glutTimerFunc(1000, timeSlice, 0); } void Orxonox::keyboard(unsigned char key, int x, int y) { switch(key) { /* perspectiv control */ case 'w': beta -= 1; break; case 's': beta += 1; break; case 'a': alpha -= 1; break; case 'd': alpha += 1; break; /* game controls */ case 'p': if (pause) { cout << "unset pause" << endl; glutIdleFunc(continousRedraw); pause = false; } else { cout << "set pause" << endl; glutIdleFunc(NULL); pause = true; } break; case 32: shoot1 = true; break; case 27: case 'q': quitGame(); break; } } void Orxonox::upKeyboard(unsigned char key, int x, int y) { switch(key) { case 32: shoot1 = false; break; } } void Orxonox::quitGame() { //cout << "finished garbage colletion, quitting..." << endl; exit(0); } void Orxonox::releaseKey(int key, int x, int y) { switch(key) { case GLUT_KEY_UP: upWeGo = false; break; case GLUT_KEY_DOWN: downWeGo = false; break; case GLUT_KEY_RIGHT: rightWeGo = false; break; case GLUT_KEY_LEFT: leftWeGo = false; break; } } /** \brief special keys function. called by glut Here are all special key function defined. */ void Orxonox::specFunc(int key, int x, int y) { switch(key) { /* spacecraft controls */ case GLUT_KEY_UP: upWeGo = true; break; case GLUT_KEY_DOWN: downWeGo = true; break; case GLUT_KEY_RIGHT: rightWeGo = true; break; case GLUT_KEY_LEFT: leftWeGo = true; break; } } void Orxonox::display() { glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glColor3f(0.0, 0.5, 0.6); glLoadIdentity(); gluLookAt(0.0, -14.0, 15.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0); (*world).drawWorld(); SDL_Flip( screen); } void Orxonox::continousRedraw() { /* increment the frames-per-second counter*/ fps++; /* check for collisions */ world->detectCollision(); /* check for input to pass it over */ if ( !pause && inputEnabled && (rightWeGo || leftWeGo || upWeGo || downWeGo || shoot1)) { if (upWeGo) (*io).goUp(); if (downWeGo) (*io).goDown(); if (rightWeGo) (*io).goRight(); if (leftWeGo) (*io).goLeft(); if (shoot1) (*io).shoot(); } /* request repaint */ glutPostRedisplay(); //cout << "Orxonox::continousRedraw" << endl; } void Orxonox::reshape (int w, int h) { glViewport(0, 0, (GLsizei) w, (GLsizei) h); glMatrixMode(GL_PROJECTION); glLoadIdentity(); glFrustum(-1.0, 1.0, -1.0, 1.0, 1.5, 200.0); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); //pb why a second time? } void Orxonox::testTheShit() { //Player* pl = new Player; //(*pl).setPosition(1, 1, 1); //(*world).addPlayer(pl); //NPC* nl = new NPC; //(*world).addNPC(nl); //(*world).addNPC(nl); //(*world).addNPC(nl); //(*world).addNPC(nl); //(*world).addNPC(nl); //(*world).addNPC(nl); //(*world).testThaTest(); } void Orxonox::mainLoop() { // This is where everything is run while( !bQuitOrxonox) { // Process input // Process time // Process collision // Draw display(); } } int main (int argc, char** argv) { Orxonox *orx = Orxonox::getInstance(); if( (*orx).globalInit(argc, argv) == -1) { printf("! Global initialization failed\n"); return -1; } //(*orx).menuInit(); pb: directly jump to the game, no menu if( (*orx).gameInit() == -1) { printf("! Game initialization failed\n"); return -1; } (*orx).mainLoop(); return 0; }