Back to index

supertuxkart  0.5+dfsg1
char_sel.cpp
Go to the documentation of this file.
00001 //  $Id: char_sel.cpp 2111 2008-05-31 07:04:30Z cosmosninja $
00002 //
00003 //  SuperTuxKart - a fun racing game with go-kart
00004 //  Copyright (C) 2006 SuperTuxKart-Team
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 "char_sel.hpp"
00024 #include "kart_properties_manager.hpp"
00025 #include "widget_manager.hpp"
00026 #include "race_manager.hpp"
00027 #include "user_config.hpp"
00028 #include "menu_manager.hpp"
00029 #include "kart_properties.hpp"
00030 #include "material_manager.hpp"
00031 #include "material.hpp"
00032 #include "unlock_manager.hpp"
00033 #include "translation.hpp"
00034 #if defined(WIN32) && !defined(__CYGWIN__)
00035 #  define snprintf _snprintf
00036 #endif
00037 
00038 enum WidgetTokens
00039 {
00040     WTOK_TITLE,
00041     WTOK_NAME,
00042 
00043     WTOK_QUIT,
00044     WTOK_RACER0
00045 };
00046 
00047 CharSel::CharSel(int whichPlayer)
00048         : m_kart(0), m_player_index(whichPlayer)
00049 {
00050     // For some strange reasons plib calls makeCurrent() in ssgContext
00051     // constructor, so we have to save the old one here and restore it
00052     ssgContext* oldContext = ssgGetCurrentContext();
00053     m_context = new ssgContext;
00054     oldContext->makeCurrent();
00055 
00056     // If m_player_index is 0 then this is a single player game or the first
00057     // player of a multiplayer game so we need to ensure that all karts are available.
00058     // If m_player_index is less than the number of elements in selected_karts then
00059     // the user is moving back through the menus and the last value in the vector
00060     // needs to be made available again.
00061     if (m_player_index == 0)
00062         kart_properties_manager->m_selected_karts.clear();
00063 
00064     if (m_player_index < (int)kart_properties_manager->m_selected_karts.size())
00065     kart_properties_manager->m_selected_karts.pop_back();
00066 
00067     char heading[MAX_MESSAGE_LENGTH];
00068     snprintf(heading, sizeof(heading), _("Player %d, choose a driver"),
00069              m_player_index + 1);
00070     widget_manager->addTitleWgt( WTOK_TITLE, 100, 10, heading );
00071     widget_manager->breakLine();
00072 
00073     widget_manager->addEmptyWgt( WidgetManager::WGT_NONE, 1, 2);
00074     widget_manager->breakLine();
00075 
00076     for (unsigned int i = 0; i < kart_properties_manager->getNumberOfKarts(); i++)
00077     {
00078         // Check if i has been previously selected
00079         if (kartAvailable(i))
00080         {
00081             const KartProperties* kp= kart_properties_manager->getKartById(i);
00082             if(unlock_manager->isLocked(kp->getIdent())) continue;
00083 
00084             widget_manager->addImgButtonWgt( WTOK_RACER0 + i, 8, 11,
00085                                              kp->getIconFile() );
00086         }
00087     }
00088 
00089     widget_manager->breakLine();
00090     widget_manager->addEmptyWgt( WidgetManager::WGT_NONE, 1, 2);
00091     widget_manager->breakLine();
00092 
00093     widget_manager->addTextWgt( WTOK_NAME, 30, 7, "");
00094 
00095     widget_manager->layout(WGT_AREA_TOP);
00096 
00097     m_current_kart = -1;
00098 
00099     const int LAST_KART = user_config->m_player[m_player_index].getLastKartId();
00100     if( LAST_KART != -1 && kartAvailable(LAST_KART))// is LAST_KART not in vector of selected karts
00101     {
00102         widget_manager->setSelectedWgt(WTOK_RACER0 + LAST_KART);
00103         switchCharacter(LAST_KART);
00104     }
00105     else
00106     {
00107         switchCharacter(0);
00108     }
00109 
00110 
00111     m_clock = 0;
00112     //test
00113 
00114 }
00115 
00116 //-----------------------------------------------------------------------------
00117 CharSel::~CharSel()
00118 {
00119     widget_manager->reset();
00120     ssgDeRefDelete(m_kart);
00121 
00122     delete m_context;
00123 }
00124 
00125 //-----------------------------------------------------------------------------
00126 void CharSel::switchCharacter(int n)
00127 {
00128     const KartProperties* kp= kart_properties_manager->getKartById(n);
00129     if (m_current_kart != n && kp != NULL)
00130     {
00131         widget_manager->setWgtText( WTOK_NAME, kp->getName().c_str());
00132 
00133         m_current_kart = n;
00134         ssgDeRefDelete(m_kart);
00135         m_kart = new ssgTransform;
00136         m_kart->ref();
00137         ssgEntity* kartentity = kp->getModel();
00138 
00139         m_kart->addKid(kartentity);
00140     }
00141 }
00142 
00143 //-----------------------------------------------------------------------------
00144 void CharSel::update(float dt)
00145 {
00146     m_clock += dt * 40.0f;
00147 
00148     if( widget_manager->selectionChanged() )
00149     {
00150         switchCharacter(widget_manager->getSelectedWgt() - WTOK_RACER0);
00151     }
00152 
00153     if (m_kart != NULL)
00154     {
00155         ssgContext* oldContext = ssgGetCurrentContext();
00156         m_context -> makeCurrent();
00157 
00158         glClear(GL_DEPTH_BUFFER_BIT);
00159 
00160         // Puts the character in the center. Scaling is done by
00161         // applying a big camera FOV.
00162         int w = user_config->m_width;
00163         int h = user_config->m_height;
00164         glViewport ( 0, 0, w, h);
00165 
00166         m_context -> setFOV ( 65.0f, 65.0f * h/w ) ;
00167         m_context -> setNearFar ( 0.05f, 1000.0f ) ;
00168 
00169         sgCoord cam_pos;
00170         sgSetCoord(&cam_pos, 0, 0, 0, 0, 0, 0);
00171         m_context -> setCamera ( &cam_pos ) ;
00172 
00173         glEnable (GL_DEPTH_TEST);
00174         sgCoord trans;
00175         sgSetCoord(&trans, 0, 3, -.4f, m_clock, 0, 0);
00176         m_kart->setTransform (&trans) ;
00177         //glShadeModel(GL_SMOOTH);
00178         ssgCullAndDraw ( m_kart ) ;
00179         glViewport ( 0, 0, user_config->m_width, user_config->m_height ) ;
00180 
00181         glDisable (GL_DEPTH_TEST);
00182         oldContext->makeCurrent();
00183     }
00184 
00185     widget_manager->update(dt);
00186 }
00187 
00188 //----------------------------------------------------------------------------
00189 void CharSel::select()
00190 {
00191     const int TOKEN = widget_manager->getSelectedWgt() - WTOK_RACER0;
00192     const KartProperties* KP = kart_properties_manager->getKartById(TOKEN);
00193     if (KP != NULL)
00194     {
00195         race_manager->setPlayerKart(m_player_index, KP->getIdent());
00196         user_config->m_player[m_player_index].setLastKartId(TOKEN);
00197         // Add selected kart (TOKEN) to selected karts vector so it cannot be
00198         // selected again
00199         kart_properties_manager->m_selected_karts.push_back(TOKEN);
00200     }
00201 
00202     if (race_manager->getNumPlayers() > 1)
00203     {
00204         if (menu_manager->isCurrentMenu(MENUID_CHARSEL_P1))
00205         {
00206             menu_manager->pushMenu(MENUID_CHARSEL_P2);
00207             return;
00208         }
00209     }
00210 
00211     if (race_manager->getNumPlayers() > 2)
00212     {
00213         if (menu_manager->isCurrentMenu(MENUID_CHARSEL_P2))
00214         {
00215             menu_manager->pushMenu(MENUID_CHARSEL_P3);
00216             return;
00217         }
00218     }
00219 
00220     if (race_manager->getNumPlayers() > 3)
00221     {
00222         if (menu_manager->isCurrentMenu(MENUID_CHARSEL_P3))
00223         {
00224             menu_manager->pushMenu(MENUID_CHARSEL_P4);
00225             return;
00226         }
00227     }
00228 
00229     if (race_manager->getRaceMode() == RaceManager::RM_GRAND_PRIX)
00230         menu_manager->pushMenu(MENUID_GRANDPRIXSELECT);
00231     else
00232         menu_manager->pushMenu(MENUID_TRACKSEL);
00233 }   // select
00234 
00235 //----------------------------------------------------------------------------
00236 // Function checks the vector of previously selected karts and returns true if
00237 // kart i is in the vector and false if it is not.
00238 
00239 bool CharSel::kartAvailable(int kart)
00240 {
00241        if (!kart_properties_manager->m_selected_karts.empty())
00242         {
00243             std::vector<int>::iterator it;
00244             for (it = kart_properties_manager->m_selected_karts.begin();
00245                 it < kart_properties_manager->m_selected_karts.end(); it++)
00246             {
00247                 if ( kart == *it)
00248                 return false;
00249             }
00250         }
00251     return true;
00252 }