Back to index

supertuxkart  0.5+dfsg1
leader_result.cpp
Go to the documentation of this file.
00001 // $Id: grand_prix_ending.cpp 1681 2008-04-09 13:52:48Z hikerstk $
00002 //
00003 //  SuperTuxKart - a fun racing game with go-kart
00004 //  Copyright (C) 2008 Joerg Henrichs
00005 //
00006 //  This program is free software; you can redistribute it and/or
00007 //  modify it under the terms of the GNU General Public License
00008 //  as published by the Free Software Foundation; either version 2
00009 //  of the License, or (at your option) any later version.
00010 //
00011 //  This program is distributed in the hope that it will be useful,
00012 //  but WITHOUT ANY WARRANTY; without even the implied warranty of
00013 //  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00014 //  GNU General Public License for more details.
00015 //
00016 //  You should have received a copy of the GNU General Public License
00017 //  along with this program; if not, write to the Free Software
00018 //  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
00019 
00020 #include <sstream>
00021 #include <string>
00022 
00023 #include <SDL/SDL.h>
00024 
00025 #include "leader_result.hpp"
00026 #include "loader.hpp"
00027 #include "sound_manager.hpp"
00028 #include "kart_properties_manager.hpp"
00029 #include "unlock_manager.hpp"
00030 #include "widget_manager.hpp"
00031 #include "race_manager.hpp"
00032 #include "game_manager.hpp"
00033 #include "user_config.hpp"
00034 #include "menu_manager.hpp"
00035 #include "kart_properties.hpp"
00036 #include "translation.hpp"
00037 #include "kart.hpp"
00038 #include "world.hpp"
00039 #include "scene.hpp"
00040 #if defined(WIN32) && !defined(__CYGWIN__)
00041 #  define snprintf _snprintf
00042 #endif
00043 
00044 enum WidgetTokens
00045 {
00046     WTOK_TITLE,
00047     WTOK_QUIT,
00048 
00049     WTOK_FIRSTKART
00050 };
00051 
00052 
00053 LeaderResult::LeaderResult()
00054         : m_kart(0)
00055 {
00056     // for some strange reasons plib calls makeCurrent() in ssgContext
00057     // constructor, so we have to save the old one here and restore it
00058     ssgContext* oldContext = ssgGetCurrentContext();
00059     m_context = new ssgContext;
00060     oldContext->makeCurrent();
00061 
00062     const unsigned int MAX_STR_LEN = 60;
00063     const unsigned int NUM_KARTS = race_manager->getNumKarts();
00064 
00065     int *scores   = new int[NUM_KARTS];
00066     int *position = new int[NUM_KARTS];
00067     double *race_time = new double[NUM_KARTS];
00068 
00069     // Ignore kart 0, since it was the leader
00070     for( unsigned int kart_id = 1; kart_id < NUM_KARTS; ++kart_id )
00071     {
00072         position[kart_id]  = kart_id;
00073         scores[kart_id]    = race_manager->getKartScore(kart_id);
00074         race_time[kart_id] = race_manager->getOverallTime(kart_id);
00075     }
00076 
00077     //Bubblesort
00078     bool sorted;
00079     do
00080     {
00081         sorted = true;
00082         for( unsigned int i = 1; i < NUM_KARTS - 1; ++i )
00083         {
00084             if( scores[i] < scores[i+1] || (scores[i] == scores[i+1] 
00085               && race_time[i] > race_time[i+1]))
00086             {
00087                 int tmp_score[2];
00088                 double tmp_time;
00089 
00090                 tmp_score[0]   = position[i];
00091                 tmp_score[1]   = scores[i];
00092                 tmp_time       = race_time[i];
00093 
00094                 position[i]    = position[i+1];
00095                 scores[i]      = scores[i+1];
00096                 race_time[i]   = race_time[i+1];
00097 
00098                 position[i+1]  = tmp_score[0];
00099                 scores[i+1]    = tmp_score[1];
00100                 race_time[i+1] = tmp_time;
00101 
00102                 sorted = false;
00103             }
00104         }
00105     } while(!sorted);
00106     
00107     static char output[MAX_MESSAGE_LENGTH];
00108     snprintf(output, sizeof(output),
00109         _("The winner is %s!"),race_manager->getKartName(position[1]).c_str());
00110     widget_manager->addWgt( WTOK_TITLE, 60, 10);
00111     widget_manager->showWgtRect(WTOK_TITLE);
00112     widget_manager->showWgtText(WTOK_TITLE);
00113     widget_manager->setWgtText(WTOK_TITLE, output);
00114     widget_manager->setWgtTextSize(WTOK_TITLE, WGT_FNT_LRG);
00115     widget_manager->breakLine();
00116 
00117     m_score = new char[MAX_STR_LEN*NUM_KARTS];
00118 
00119     for(unsigned int i=1; i < NUM_KARTS; ++i)
00120     {
00121         // char sTime[20];
00122         // For now: don't display the time, since it's not correctly
00123         // set in follow-the-leader
00124         //TimeToString(race_time[i], sTime);
00125         sprintf((char*)(m_score + MAX_STR_LEN * i), "%d. %s %d",
00126             i , race_manager->getKartName(position[i]).c_str(), scores[i]);
00127 
00128         widget_manager->addWgt(WTOK_FIRSTKART + i, 40, 5);
00129         widget_manager->showWgtRect(WTOK_FIRSTKART + i);
00130         widget_manager->showWgtText(WTOK_FIRSTKART + i);
00131         widget_manager->setWgtText(WTOK_FIRSTKART + i,
00132             (char*)(m_score + MAX_STR_LEN * i));
00133         widget_manager->setWgtTextSize(WTOK_FIRSTKART + i, WGT_FNT_SML);
00134     widget_manager->breakLine();
00135     }
00136     const std::string KART_NAME = race_manager->getKartName(position[1]);
00137     const KartProperties* WINNING_KART = kart_properties_manager->getKart(KART_NAME);
00138     delete []scores;
00139     delete []position;
00140     delete []race_time;
00141 
00142     widget_manager->addWgt(WTOK_QUIT, 50, 7);
00143     widget_manager->activateWgt(WTOK_QUIT);
00144     widget_manager->showWgtRect(WTOK_QUIT);
00145     widget_manager->showWgtText(WTOK_QUIT);
00146     if(unlock_manager->getUnlockedFeatures().size()>0)
00147     {
00148         widget_manager->setWgtText(WTOK_QUIT, _("Continue"));
00149     }
00150     else
00151     {
00152         widget_manager->setWgtText(WTOK_QUIT, _("Back to the main menu"));
00153     }
00154 
00155     widget_manager->layout(WGT_AREA_TOP);
00156 
00157     m_kart = new ssgTransform;
00158     m_kart->ref();
00159     ssgEntity* kartentity = WINNING_KART->getModel();
00160     m_kart->addKid(kartentity);
00161 
00162     sound_manager->playSfx(SOUND_WINNER);
00163 
00164     m_clock = 0;
00165 
00166     //FIXME: this is taken from RaceMode::exit_race,
00167     //this should be organized better.
00168     scene->clear();
00169     delete world;
00170     world = 0;
00171     race_manager->m_active_race = false;
00172 
00173 }
00174 
00175 //-----------------------------------------------------------------------------
00176 LeaderResult::~LeaderResult()
00177 {
00178     widget_manager->reset();
00179     ssgDeRefDelete(m_kart);
00180 
00181     delete m_context;
00182     delete[] m_score;
00183 
00184     //The next line prevents textures like the background of the main menu from
00185     //going white after finishing the grandprix
00186     // FIXME: I think this is not necessary anymore after the
00187     //        texture bug fix (r733) - but I can't currently test this.
00188     loader->shared_textures.removeAll();
00189 }
00190 
00191 //-----------------------------------------------------------------------------
00192 
00193 void LeaderResult::update(float dt)
00194 {
00195     m_clock += dt * 40.0f;
00196 
00197     glClearColor (0.1f, 0.1f, 0.1f, 1.0f);
00198     glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
00199 
00200     ssgContext* oldContext = ssgGetCurrentContext();
00201     m_context -> makeCurrent();
00202 
00203     // FIXME: A bit hackish...
00204     glViewport ( 0, 0, 800, 320);
00205 
00206     m_context -> setFOV ( 45.0f, 45.0f * 320.0f/800.0f ) ;
00207     m_context -> setNearFar ( 0.05f, 1000.0f ) ;
00208 
00209     sgCoord cam_pos;
00210     sgSetCoord(&cam_pos, 0, 0, 0, 0, 0, 0);
00211     m_context -> setCamera ( &cam_pos ) ;
00212 
00213     glEnable (GL_DEPTH_TEST);
00214     sgCoord trans;
00215     sgSetCoord(&trans, 0, 3, -.4f, m_clock, 0, 0);
00216     m_kart->setTransform (&trans) ;
00217     //glShadeModel(GL_SMOOTH);
00218     ssgCullAndDraw ( m_kart ) ;
00219     glViewport ( 0, 0, user_config->m_width, user_config->m_height ) ;
00220 
00221     glDisable (GL_DEPTH_TEST);
00222     oldContext->makeCurrent();
00223     BaseGUI::update(dt);
00224 }
00225 
00226 //-----------------------------------------------------------------------------
00227 void LeaderResult::select()
00228 {
00229     // If a new feature was unlocked, display the new feature first
00230     // before returning to the main menu
00231     if(unlock_manager->getUnlockedFeatures().size()>0)
00232     {
00233         // This removes this menu from the stack, and adds the main menu. 
00234         // Then we push the new feature menu on top, so that it will be
00235         // displayed next, and on return the main menu is shown.
00236         menu_manager->switchToMainMenu();
00237         menu_manager->pushMenu(MENUID_UNLOCKED_FEATURE);
00238         return;
00239     }
00240 
00241     menu_manager->switchToMainMenu();
00242 }
00243 //-----------------------------------------------------------------------------
00244 void LeaderResult::handle(GameAction ga, int value)
00245 {
00246   // Attempts to close the menu are silently discarded
00247   // since they do not make sense at this point.
00248   if (ga == GA_LEAVE)
00249    return;
00250   else
00251     BaseGUI::handle(ga, value);
00252 }