main.cpp

Go to the documentation of this file.
00001 
00002 //
00003 // Das Tank - Copyright (C) 2006, 2007 Windsor Schmidt <windsor@windsorworld.net>
00004 //
00005 // This program is free software; you can redistribute it and/or modify it
00006 // under the terms of the GNU General Public License as published by the Free
00007 // Software Foundation; either version 2 of the License, or (at your option)
00008 // any later version.
00009 //
00010 // This program is distributed in the hope that it will be useful, but WITHOUT
00011 // ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
00012 // FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
00013 // more details.
00014 //
00015 // You should have received a copy of the GNU General Public License along with
00016 // this program; if not, write to the Free Software Foundation, Inc., 59 Temple
00017 // Place, Suite 330, Boston, MA 02111-1307 USA
00018 //
00020 
00021 
00022 #ifndef STDAFX
00023 #include "stdafx.h"
00024 #endif
00025 
00026 using namespace std;
00027 
00028 GameState * DasGame; // main game state pointer
00029 
00031 // globals for GUI and OpenGL
00033 SDL_Surface* screen;
00034 SDL_Event event;
00035 
00036 //gcn::SDLInput* input;                                 // Input driver
00037 gcn::OpenGLGraphics* graphics;                   // Graphics driver
00038 gcn::OpenGLSDLImageLoader* imageLoader;   // For loading images
00039 gcn::Gui* gui;                                                 // A Gui object - binds it all together
00040 gcn::ImageFont* font_small;                      // small font
00041 gcn::ImageFont* font_big;                        // big font
00042 
00043 // default widgets (make them global)
00044 gcn::Container* top;                             // A top level GUI container
00045 
00046 
00056 int main(int argc, char **argv) 
00057 {  
00058        int done;
00059 
00060        // try initializing the default device, at 44100hz stereo 16-bits
00061        if(ENABLE_SOUND)
00062        {
00063               // if not, then use 'NO SOUND' device.
00064               if(!BASS_Init(-1,44100,0,0,NULL)) BASS_Init(0,44100,0,0,NULL);
00065        }
00066        else BASS_Init(0,44100,0,0,NULL);
00067 
00068        // initialize SDL for video output
00069        if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_JOYSTICK) == -1) exit(1); // quit if this fails
00070 
00071        SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
00072 
00073        // create OpenGL screen surface
00074        screen = SDL_SetVideoMode(SCREEN_WIDTH, SCREEN_HEIGHT, 0, SDL_HWSURFACE |
00075               SDL_HWACCEL |
00076               SDL_OPENGL    |
00077               RUN_FULLSCREEN);
00078        if(screen == NULL) // quit if that fails
00079        {
00080               SDL_Quit();
00081               exit(1);
00082        }
00083 
00084        // SDL configuration
00085        SDL_WM_SetCaption("Das Tank", NULL);
00086        SDL_ShowCursor(SDL_DISABLE);
00087        SDL_EnableUNICODE(1);
00088 
00089 
00090        // guichan initialization
00091        imageLoader = new gcn::OpenGLSDLImageLoader();
00092        gcn::Image::setImageLoader(imageLoader);
00093 
00094        graphics = new gcn::OpenGLGraphics();
00095 
00096        // tell OpenGL graphics how big the screen is
00097        graphics->setTargetPlane(SCREEN_WIDTH, SCREEN_HEIGHT);
00098 
00099        // container for gui elements
00100        top = new gcn::Container();
00101 
00102        // set the dimension of the top container to match the screen
00103        top->setDimension(gcn::Rectangle(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT));
00104        gui = new gcn::Gui();
00105 
00106        // set gui to use the SDLGraphics object
00107        gui->setGraphics(graphics);
00108 
00109        // set the top container
00110        gui->setTop(top);
00111 
00112        // load the image fonts
00113        font_small = new gcn::ImageFont("tex/font_small.bmp"," !\"#$^&`()*+,-./0123456789:;<=>?abcdefghijklmnopqrstuvwxyz");
00114        font_big = new gcn::ImageFont("tex/font_big.bmp"," !#+,-.0123456789:?ABCDEFGHIJKLMNOPQRSTUVWXYZ");
00115 
00116        // The global font is static and must be set.
00117        gcn::Widget::setGlobalFont(font_small);
00118 
00119        initWidgets(); // initialize gui widgets
00120 
00121        InitGL(SCREEN_WIDTH, SCREEN_HEIGHT); // Initialize OpenGL graphics
00122 
00123        InitTextures(); // load textures from disk
00124 
00125        InitSound(); // load sounds from disk
00126 
00127        InitCollision(); // load collision interaction matrices from disk
00128 
00130        // master game loop
00132        int menuSelection = MENUID_NULL;
00133        bool firstLoop = true;
00134        DasGame = new GameState();                
00135 
00136        //SDL_EnableKeyRepeat(SDL_DEFAULT_REPEAT_DELAY, SDL_DEFAULT_REPEAT_INTERVAL);
00137 
00138        while(menuSelection != MENUID_QUIT)
00139        {
00140               if(firstLoop == true) // first time in menu since being in-game
00141               {
00142                      PlayMusic(MUSICID_MENU); // start or restart menu music
00143                      firstLoop = false;
00144               }
00145 
00146               menuSelection = MainMenu(graphics, font_small);
00147 
00148               switch(menuSelection)
00149               {
00150               case MENUID_START:
00151                      StopMusic(MUSICID_MENU);
00152 
00153                      DasGame->World = InitGame(DasGame->iCurrentLevel); // load current level in to new world
00154                      PlayGame(DasGame->World);
00155                      KillGame(DasGame->World); // delete all world data structures
00156 
00157                      // advance levels and loop back to first level if already at the last
00158                      if(DasGame->bAutoAdvanceLevel) DasGame->iCurrentLevel++;
00159                      if(DasGame->iCurrentLevel > DasGame->iMaxLevel) DasGame->iCurrentLevel = 1;
00160 
00161 
00162                      firstLoop = true; // flag that we're fresh out of a game
00163                      break;
00164               case MENUID_OPTIONS:
00165                      OptionsMenu(graphics, font_small, DasGame);
00166                      break;
00167               case MENUID_HIGHSCORES:
00168                      HighScoreMenu(graphics, font_small);
00169                      break;
00170               case MENUID_CREDITS:
00171                      Credits(graphics, font_small);
00172                      break;
00173               case MENUID_QUIT:
00174                      break;
00175               }
00176        }
00178        // end of master game loop
00180 
00181        SDL_Quit();                 // Kill SDL and OpenGL
00182        BASS_Free();         // Kill BASS
00183        return 0;                   // Go home
00184 }
00185 
00186 
00200 int PlayGame(CWorld * ThisWorld)
00201 {
00202        //PlayMusic(MUSICID_INGAME); // start music
00203        PlayLevelMusic(ThisWorld->musicFile);
00204 
00205        glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
00206 
00207        int timer = 0;
00208        int victor = 0;
00209 
00210        // FPS variables
00211        int fps = 0;
00212        int frameCounter = 0;
00213        Uint32 timeStamp = 0;
00214 
00215        Uint32 iStartingTimeStamp = SDL_GetTicks();
00216        Uint32 iStartingTimeElapsed = 0;
00217        
00218        Uint32 EffectsTimer = SDL_GetTicks();
00219        Uint32 PhysicsTimer = SDL_GetTicks();
00220        Uint32 StartingTimer = SDL_GetTicks();
00221 
00222        CEffect * StartFX = NULL;
00223        Vector vGuyPos, vOffset;
00224 
00225        SDL_Event event; // use to store incoming events
00226        static char string[256]; // use to format / store HUD messages before printing
00227 
00228        ThisWorld->bGameOver = false; // signal that the game is still in progress
00229 
00230        while (ThisWorld->bGameOver == false)
00231        {
00232               // update 'frames per second' variable
00233               ThisWorld->iCurrentTime = SDL_GetTicks();
00234 
00235               if(ThisWorld->iCurrentTime >= timeStamp + 1000)
00236               {
00237                      timeStamp = ThisWorld->iCurrentTime;
00238                      fps = frameCounter;
00239                      frameCounter = 0;
00240               }
00241               frameCounter++;
00242 
00243               //ThisWorld->Player[0]->iInput[INPUT_FIRE] = false; // limit one fire per key-down
00244               //ThisWorld->Player[1]->iInput[INPUT_FIRE] = false;
00245 
00246               // get input events and transform them in to player input
00247               while(SDL_PollEvent(&event))
00248               {
00249                      if(ThisWorld->bTakeInput)
00250                      {
00251                             switch(event.type)
00252                             {
00253                                    // handle joystick input from players
00254                             case SDL_JOYBUTTONDOWN:
00255                                    if(event.jbutton.which == DasGame->iGreenPlayerJoystick) // player 1
00256                                    {
00257                                           switch(event.jbutton.button)
00258                                           {
00259                                           case 0:
00260                                                  ThisWorld->Player[1]->iInput[INPUT_FIRE] = true;
00261                                                  break;
00262                                           }
00263                                    }
00264 
00265                                    if(event.jbutton.which == DasGame->iBrownPlayerJoystick) // player 2
00266                                    {
00267                                           switch(event.jbutton.button)
00268                                           {
00269                                           case 0:
00270                                                  ThisWorld->Player[0]->iInput[INPUT_FIRE] = true;
00271                                                  break;
00272                                           }
00273                                    }
00274                                    break;
00275 
00276                             case SDL_JOYBUTTONUP: // a little redundant?
00277                                    if(event.jbutton.which == DasGame->iGreenPlayerJoystick) // player 1
00278                                    {
00279                                           switch(event.jbutton.button)
00280                                           {
00281                                           case 0:
00282                                                  ThisWorld->Player[1]->iInput[INPUT_FIRE] = false;
00283                                                  break;
00284                                           }
00285                                    }
00286                                    if(event.jbutton.which == DasGame->iBrownPlayerJoystick) // player 2
00287                                    {
00288                                           switch(event.jbutton.button)
00289                                           {
00290                                           case 0:
00291                                                  ThisWorld->Player[0]->iInput[INPUT_FIRE] = false;
00292                                                  break;
00293                                           }
00294                                    }
00295                                    break;
00296 
00297                             case SDL_JOYHATMOTION:
00298                                    if(event.jhat.which == DasGame->iGreenPlayerJoystick) // player 1
00299                                    {
00300                                           if(event.jhat.value & SDL_HAT_UP) ThisWorld->Player[1]->iInput[INPUT_UP] = true;
00301                                           else ThisWorld->Player[1]->iInput[INPUT_UP] = false;
00302                                           if(event.jhat.value & SDL_HAT_DOWN) ThisWorld->Player[1]->iInput[INPUT_DOWN] = true;
00303                                           else ThisWorld->Player[1]->iInput[INPUT_DOWN] = false;
00304                                           if(event.jhat.value & SDL_HAT_LEFT) ThisWorld->Player[1]->iInput[INPUT_LEFT] = true;
00305                                           else ThisWorld->Player[1]->iInput[INPUT_LEFT] = false;
00306                                           if(event.jhat.value & SDL_HAT_RIGHT) ThisWorld->Player[1]->iInput[INPUT_RIGHT] = true;
00307                                           else ThisWorld->Player[1]->iInput[INPUT_RIGHT] = false;
00308                                    }
00309 
00310                                    if(event.jhat.which == DasGame->iBrownPlayerJoystick) // player 2
00311                                    {
00312                                           if(event.jhat.value & SDL_HAT_UP) ThisWorld->Player[0]->iInput[INPUT_UP] = true;
00313                                           else ThisWorld->Player[0]->iInput[INPUT_UP] = false;
00314                                           if(event.jhat.value & SDL_HAT_DOWN) ThisWorld->Player[0]->iInput[INPUT_DOWN] = true;
00315                                           else ThisWorld->Player[0]->iInput[INPUT_DOWN] = false;
00316                                           if(event.jhat.value & SDL_HAT_LEFT) ThisWorld->Player[0]->iInput[INPUT_LEFT] = true;
00317                                           else ThisWorld->Player[0]->iInput[INPUT_LEFT] = false;
00318                                           if(event.jhat.value & SDL_HAT_RIGHT) ThisWorld->Player[0]->iInput[INPUT_RIGHT] = true;
00319                                           else ThisWorld->Player[0]->iInput[INPUT_RIGHT] = false;
00320                                    }
00321                                    break;
00322 
00323                                    // handle keyboard input from players
00324                             case SDL_KEYUP:
00325                                    switch(event.key.keysym.sym)
00326                                    {
00327                                    case SDLK_KP4:
00328                                           ThisWorld->Player[0]->iInput[INPUT_LEFT] = false;
00329                                           break;
00330 
00331                                    case SDLK_KP6:
00332                                           ThisWorld->Player[0]->iInput[INPUT_RIGHT] = false;
00333                                           break;
00334 
00335                                    case SDLK_KP5:
00336                                           ThisWorld->Player[0]->iInput[INPUT_DOWN] = false;
00337                                           break;
00338 
00339                                    case SDLK_KP8:
00340                                           ThisWorld->Player[0]->iInput[INPUT_UP] = false;
00341                                           break;
00342 
00343                                    case SDLK_RETURN:
00344                                           ThisWorld->Player[0]->iInput[INPUT_FIRE] = false;
00345                                           break;
00346 
00347                                    case SDLK_a:
00348                                           ThisWorld->Player[1]->iInput[INPUT_LEFT] = false;
00349                                           break;
00350 
00351                                    case SDLK_d:
00352                                           ThisWorld->Player[1]->iInput[INPUT_RIGHT] = false;
00353                                           break;
00354 
00355                                    case SDLK_s:
00356                                           ThisWorld->Player[1]->iInput[INPUT_DOWN] = false;
00357                                           break;
00358 
00359                                    case SDLK_w:
00360                                           ThisWorld->Player[1]->iInput[INPUT_UP] = false;
00361                                           break;
00362 
00363                                    case SDLK_TAB:
00364                                           ThisWorld->Player[1]->iInput[INPUT_FIRE] = false;
00365                                           break;
00366                                    }
00367                                    break;
00368 
00369                             case SDL_KEYDOWN: 
00370                                    switch(event.key.keysym.sym)
00371                                    {
00372                                    case SDLK_ESCAPE: // user pressed escape, so exit
00373                                           ThisWorld->bGameOver = true;
00374                                           break;
00375 
00376                                    case SDLK_KP4:
00377                                           ThisWorld->Player[0]->iInput[INPUT_LEFT] = true;
00378                                           break;
00379 
00380                                    case SDLK_KP6:
00381                                           ThisWorld->Player[0]->iInput[INPUT_RIGHT] = true;
00382                                           break;
00383 
00384                                    case SDLK_KP5:
00385                                           ThisWorld->Player[0]->iInput[INPUT_DOWN] = true;
00386                                           break;
00387 
00388                                    case SDLK_KP8:
00389                                           ThisWorld->Player[0]->iInput[INPUT_UP] = true;
00390                                           break;
00391 
00392                                    case SDLK_RETURN:
00393                                           ThisWorld->Player[0]->iInput[INPUT_FIRE] = true;
00394                                           break;
00395 
00396                                    case SDLK_a:
00397                                           ThisWorld->Player[1]->iInput[INPUT_LEFT] = true;
00398                                           break;
00399 
00400                                    case SDLK_d:
00401                                           ThisWorld->Player[1]->iInput[INPUT_RIGHT] = true;
00402                                           break;
00403 
00404                                    case SDLK_s:
00405                                           ThisWorld->Player[1]->iInput[INPUT_DOWN] = true;
00406                                           break;
00407 
00408                                    case SDLK_w:
00409                                           ThisWorld->Player[1]->iInput[INPUT_UP] = true;
00410                                           break;
00411 
00412                                    case SDLK_TAB:
00413                                           ThisWorld->Player[1]->iInput[INPUT_FIRE] = true;
00414                                           break;
00415 
00416                                    case SDLK_PAGEUP:
00417                                           ThisWorld->iRenderStyle = RENDERSTYLE_PERSPECTIVE;
00418                                           break;
00419 
00420                                    case SDLK_PAGEDOWN:
00421                                           ThisWorld->iRenderStyle = RENDERSTYLE_FLAT;
00422                                           break;
00423                                    }
00424                                    break;
00425                             }
00426                      }
00427               }
00428 
00429               if((SDL_GetTicks() - PhysicsTimer) > 10)
00430               {
00431                      PhysicsUpdate(ThisWorld); // update the state of the world
00432                      PhysicsTimer = SDL_GetTicks();
00433               }
00434 
00435               ProcessTileCollisions(ThisWorld); // process effects of tiles that players are on
00436 
00437               DoCollisions(ThisWorld); // process collisions and their effects
00438 
00439               RemoveDeadObjects(ThisWorld); // clean up after the mess
00440 
00441               UpdateAnimation(ThisWorld); // step animation frames
00442 
00443               DrawGLScene(ThisWorld);     // draw the game world (tiles and objects)
00444 
00445               if((SDL_GetTicks() - EffectsTimer) > 20)
00446               {
00447                      ThisWorld->UpdateEffects(40); // step the effects
00448                      EffectsTimer = SDL_GetTicks();
00449               }
00450 
00451               if((SDL_GetTicks() - StartingTimer) > 10)
00452               {
00453                      iStartingTimeElapsed ++;
00454               }
00455 
00456               // if just beginning this round, let players get ready with a countdown
00457               graphics->setFont(font_big);
00458               
00459               switch(ThisWorld->iStartingState)
00460               {
00461               case STARTINGSTATE_IDLE:
00462                      if(iStartingTimeElapsed > 1000)
00463                      {
00464                             PlaySound(SOUNDID_READY);
00465                             InitStripeAlpha();
00466                             ThisWorld->iStartingState = STARTINGSTATE_READY;
00467 
00468                             // make sure the little guy starts off in the right place relative to her tank
00469                             vOffset.y = -0.6;
00470                             vOffset.z = 0;
00471                             VRotate2D(DegreesToRadians(ThisWorld->Player[1]->fAngle), vOffset);
00472                             vGuyPos = ThisWorld->Player[1]->Position + vOffset;
00473 
00474                             StartFX = new CEffect(EFFECTID_TILEANIM);
00475                             StartFX->TAnim = new TileAnim(vGuyPos,ThisWorld->Player[1]->fAngle,6000,ANIMID_GREEN_HOP_IN,80,1,true);
00476                             ThisWorld->Player[1]->ParentWorld->AddEffect(StartFX);
00477                      }
00478                      break;
00479 
00480               case STARTINGSTATE_READY:
00481 
00482                      DrawStripe(.15,-.15,1);
00483                      graphics->_beginDraw();
00484                      graphics->drawText("READY",SCREEN_WIDTH/2,SCREEN_HEIGHT/2 - (font_big->getHeight() / 2),
00485                             gcn::Graphics::CENTER);
00486                      graphics->_endDraw();
00487 
00488                      if(iStartingTimeElapsed > 2500)
00489                      {
00490                             PlaySound(SOUNDID_SET);
00491                             InitStripeAlpha();
00492                             ThisWorld->iStartingState = STARTINGSTATE_SET;
00493 
00494                             // make sure the little guy starts off in the right place relative to her tank
00495                             vOffset.x = 0;
00496                             vOffset.y = 0.6;
00497                             vOffset.z = 0;
00498                             VRotate2D(DegreesToRadians(ThisWorld->Player[0]->fAngle), vOffset);
00499                             vGuyPos = ThisWorld->Player[0]->Position + vOffset;
00500 
00501                             StartFX = new CEffect(EFFECTID_TILEANIM);
00502                             StartFX->TAnim = new TileAnim(vGuyPos, ThisWorld->Player[0]->fAngle,3000,ANIMID_BROWN_HOP_IN,80,1,true);
00503                             ThisWorld->Player[0]->ParentWorld->AddEffect(StartFX);
00504                      }
00505                      break;
00506 
00507               case STARTINGSTATE_SET:
00508 
00509                      DrawStripe(.15,-.15,1);
00510                      graphics->_beginDraw();
00511                      graphics->drawText("SET",SCREEN_WIDTH/2,SCREEN_HEIGHT/2 - (font_big->getHeight() / 2),
00512                             gcn::Graphics::CENTER);
00513                      graphics->_endDraw();
00514 
00515                      if(iStartingTimeElapsed > 4000)
00516                      {
00517                             PlaySound(SOUNDID_GO);
00518                             InitStripeAlpha();
00519                             ThisWorld->iStartingState = STARTINGSTATE_GO;
00520                             ThisWorld->bTakeInput = true;
00521                      }
00522                      break;
00523 
00524               case STARTINGSTATE_GO:
00525 
00526                      DrawStripe(.15,-.15,1);
00527                      graphics->_beginDraw();
00528                      graphics->drawText("GO!!!",SCREEN_WIDTH/2,SCREEN_HEIGHT/2 - (font_big->getHeight() / 2),
00529                             gcn::Graphics::CENTER);
00530                      graphics->_endDraw();
00531 
00532                      if(iStartingTimeElapsed > 5500)
00533                      {
00534                             ThisWorld->iStartingState = STARTINGSTATE_RUN;
00535                      }
00536                      break;
00537               }
00538 
00539               // somebody won this game
00540               if(ThisWorld->iStartingState == STARTINGSTATE_VICTORY)
00541               {
00542                      if(timer == 0)
00543                      {
00544                             PlaySound(SOUNDID_VICTORY);
00545                             InitStripeAlpha();
00546                      }
00547 
00548                      if(timer>=0 && timer<5000)
00549                      {
00550                             switch(victor)
00551                             {
00552                             case 0:
00553 
00554                                    if(ThisWorld->Player[0]->iHealth > 0 && ThisWorld->Player[1]->iHealth <= 0) victor = 1;
00555                                    if(ThisWorld->Player[0]->iHealth <= 0 && ThisWorld->Player[1]->iHealth > 0) victor = 2;
00556                                    if(ThisWorld->Player[0]->iHealth <= 0 && ThisWorld->Player[1]->iHealth <= 0) victor = 3;
00557                                    break;
00558 
00559                             case 1:
00560                                    DrawStripe(.15,-.15,1);
00561                                    graphics->_beginDraw();
00562                                    graphics->drawText("BROWN TANK WINS!",
00563                                           SCREEN_WIDTH/2,SCREEN_HEIGHT/2 - (font_big->getHeight() / 2),
00564                                           gcn::Graphics::CENTER);
00565                                    graphics->_endDraw();
00566                                    break;
00567 
00568                             case 2:
00569                                    DrawStripe(.15,-.15,1);
00570                                    graphics->_beginDraw();
00571                                    graphics->drawText("GREEN TANK WINS!",
00572                                           SCREEN_WIDTH/2,SCREEN_HEIGHT/2 - (font_big->getHeight() / 2),
00573                                           gcn::Graphics::CENTER);
00574                                    graphics->_endDraw();
00575                                    break;
00576 
00577                             case 3:
00578                                    DrawStripe(.15,-.15,1);
00579                                    graphics->_beginDraw();
00580                                    graphics->drawText("TIE GAME!",
00581                                           SCREEN_WIDTH/2,SCREEN_HEIGHT/2 - (font_big->getHeight() / 2),
00582                                           gcn::Graphics::CENTER);
00583                                    graphics->_endDraw();
00584                                    break;
00585                             }
00586                      }
00587 
00588                      timer++;
00589 
00590                      if (timer == 5000) ThisWorld->bGameOver = true;
00591               }
00592 
00593               // draw the on-screen stats
00594               graphics->setFont(font_small);
00595               graphics->_beginDraw();
00596 
00597               sprintf_s(string, "%d", fps);
00598               graphics->drawText(string, 25, SCREEN_HEIGHT - font_big->getHeight() - 5, gcn::Graphics::LEFT);
00599               graphics->setFont(font_big);
00600 
00601               if(ThisWorld->Player[1]->iAmmo == -1)
00602               {
00603                      sprintf_s(string, "?", ThisWorld->Player[1]->iAmmo);
00604                      graphics->drawText(string, 20, 120, gcn::Graphics::LEFT);
00605               }
00606               else
00607               {
00608                      sprintf_s(string, "%d", ThisWorld->Player[1]->iAmmo);
00609                      graphics->drawText(string, 20, 120, gcn::Graphics::LEFT);
00610 
00611               }
00612 
00613               if(ThisWorld->Player[0]->iAmmo == -1)
00614               {
00615                      sprintf_s(string, "?", ThisWorld->Player[0]->iAmmo);
00616                      graphics->drawText(string, SCREEN_WIDTH - 120, 120, gcn::Graphics::LEFT);
00617               }
00618               else
00619               {
00620                      sprintf_s(string, "%d", ThisWorld->Player[0]->iAmmo);
00621                      graphics->drawText(string, SCREEN_WIDTH - 120, 120, gcn::Graphics::LEFT);
00622 
00623               }
00624 
00625               graphics->_endDraw();
00626 
00627               //debugText(NULL); // display last debug text message
00628 
00629               // swap buffers to display, since we're double buffered.
00630               SDL_GL_SwapBuffers();
00631        }
00632 
00633        // control passes here when the game is over
00634 
00635        StopMusic(MUSICID_INGAME); // stop playing music before returning to main menu
00636 
00637        return 0;
00638 }
00639 
00640 
00652 CWorld * InitGame(int level)
00653 {
00654        CWorld * ThisWorld = new CWorld;
00655        ThisWorld->iStartingState = STARTINGSTATE_IDLE;
00656        ThisWorld->bTakeInput = false; // freeze players until round starts
00657 
00658 #ifdef DEBUG_IMPATIENT
00659        ThisWorld->iStartingState = STARTINGSTATE_RUN;
00660        ThisWorld->bTakeInput = true;
00661 #endif
00662 
00663        ThisWorld->fZoomBias = 0.5;
00664        char string[256];
00665 
00666        sprintf_s(string, "lvl\\%d.lvl", level); // get level filename from level #
00667        
00668        ThisWorld->LoadLevel(string); // load level from disk
00669 
00671        // create a tank and insert in world as a player
00673        CObject * BrownTank;
00674        BrownTank = new CObject(TYPEID_TANK, ThisWorld);
00675        BrownTank->iHealth -= DasGame->iBrownHandicap;
00676        BrownTank->iTint = TINTID_ARMYBROWN;
00677        BrownTank->iDamageSound = SOUNDID_HIT;
00678        BrownTank->Position.x = 22;
00679        BrownTank->Position.y = 16;
00680        BrownTank->iNormalAnim = ANIMID_TANKROLL;
00681        BrownTank->iNormalAnimSpeed = 100;
00682        BrownTank->iRemovalEffects = 2;
00683        BrownTank->iRemovalEffect[0] = EFFECTID_TILEANIM;
00684        BrownTank->iRemovalEffect[1] = EFFECTID_PSYSTEM;
00685        BrownTank->iRemovalAnim = ANIMID_BROWNTANKEXPLODE;
00686        BrownTank->iRemovalAnimSpeed = 200;
00687        BrownTank->iLingerTime = 9000;
00688        BrownTank->fAngle = 180;
00689        BrownTank->fSubAngle = 180;
00690 
00691        ThisWorld->Player[0] = BrownTank;
00692        ThisWorld->AddObject(BrownTank);
00693 
00695        // create a tank and insert in world as a player
00697        CObject * GreenTank;
00698        GreenTank = new CObject(TYPEID_TANK, ThisWorld);
00699        GreenTank->iHealth -= DasGame->iGreenHandicap;
00700        GreenTank->iTint = TINTID_ARMYGREEN;
00701        GreenTank->iDamageSound = SOUNDID_HIT;
00702        GreenTank->Position.x = 10;
00703        GreenTank->Position.y = 16;
00704        GreenTank->iNormalAnim = ANIMID_TANKROLL;
00705        GreenTank->iNormalAnimSpeed = 500;
00706        GreenTank->iRemovalEffects = 2;
00707        GreenTank->iRemovalEffect[0] = EFFECTID_TILEANIM;
00708        GreenTank->iRemovalEffect[1] = EFFECTID_PSYSTEM;
00709        GreenTank->iRemovalAnim = ANIMID_GREENTANKEXPLODE;
00710        GreenTank->iRemovalAnimSpeed = 500;
00711        GreenTank->iLingerTime = 9000;
00712 
00713        ThisWorld->Player[1] = GreenTank;
00714        ThisWorld->AddObject(GreenTank);
00715 
00716        return ThisWorld;
00717 }
00718 
00719 
00731 int KillGame(CWorld * ThisWorld)
00732 {
00733        delete ThisWorld;
00734 
00735        return 0;
00736 }
00737 
00738 
00744 void initWidgets()
00745 {
00746        top->setOpaque(false);
00747 }
00748 
00749 void debugText(const char * text)
00750 {
00751        static char string[256];
00752 
00753        if(text == NULL)
00754        {
00755               graphics->setFont(font_small);
00756               graphics->_beginDraw();
00757               graphics->drawText(string,SCREEN_WIDTH/2,SCREEN_HEIGHT/2,gcn::Graphics::CENTER);
00758               graphics->_endDraw();
00759        }
00760        else
00761        {
00762               strcpy_s(string, text);
00763        }
00764 }
00765 
00767 float DegreesToRadians(float deg)
00768 {
00769        return deg * PI / 180.0f;
00770 }
00771 
00773 float RadiansToDegrees(float rad)
00774 {      
00775        return rad * 180.0f / PI;
00776 }
00777 
00784 int ToggleFullScreen(GameState * State)
00785 {
00786        State->bFullScreen = !State->bFullScreen; // toggle the fullscreen state flag
00787 
00788        // initialize SDL for video output
00789        SDL_QuitSubSystem(SDL_INIT_VIDEO);
00790        
00791        if (SDL_InitSubSystem(SDL_INIT_VIDEO) == -1) return 1; // quit if this fails
00792 
00793        SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
00794 
00795        // create OpenGL screen surface
00796        if(State->bFullScreen)
00797        {
00798               screen = SDL_SetVideoMode(SCREEN_WIDTH,SCREEN_HEIGHT,0,
00799                      SDL_HWSURFACE|SDL_HWACCEL|SDL_OPENGL|SDL_FULLSCREEN);
00800        }
00801        else
00802        {
00803               screen = SDL_SetVideoMode(SCREEN_WIDTH,SCREEN_HEIGHT,0, SDL_HWSURFACE|SDL_HWACCEL|SDL_OPENGL);
00804        }
00805 
00806        if(screen == NULL) // quit if that fails
00807        {
00808               SDL_Quit();
00809               return 1;
00810        }
00811 
00812        // SDL configuration
00813        SDL_WM_SetCaption("Das Tank", NULL);
00814        SDL_ShowCursor(SDL_DISABLE);
00815 
00816        // guichan initialization
00817        imageLoader = new gcn::OpenGLSDLImageLoader();
00818        gcn::Image::setImageLoader(imageLoader);
00819 
00820        graphics = new gcn::OpenGLGraphics();
00821 
00822        // tell OpenGL graphics how big the screen is
00823        graphics->setTargetPlane(SCREEN_WIDTH, SCREEN_HEIGHT);
00824 
00825        // container for gui elements
00826        top = new gcn::Container();
00827 
00828        // set the dimension of the top container to match the screen
00829        top->setDimension(gcn::Rectangle(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT));
00830        gui = new gcn::Gui();
00831 
00832        // set gui to use the SDLGraphics object
00833        gui->setGraphics(graphics);
00834 
00835        // set the top container
00836        gui->setTop(top);
00837 
00838        // load the image fonts
00839        font_small = new gcn::ImageFont("tex/font_small.bmp"," !\"#$^&`()*+,-./0123456789:;<=>?abcdefghijklmnopqrstuvwxyz");
00840        font_big = new gcn::ImageFont("tex/font_big.bmp"," !#+,-.0123456789:?ABCDEFGHIJKLMNOPQRSTUVWXYZ");
00841 
00842        // The global font is static and must be set.
00843        gcn::Widget::setGlobalFont(font_small);
00844 
00845        initWidgets(); // initialize gui widgets
00846 
00847        InitGL(SCREEN_WIDTH, SCREEN_HEIGHT); // Initialize OpenGL graphics
00848        
00849        InitTextures(); // initialize textures
00850        
00851        return 0;
00852 }

 

Copyright Windsor Schmidt 2006 - All rights reserved.