stk-code_catmod/src/gui/leader_result.cpp
cosmosninja eb482c7d4b Updated the GPL version to GPLv3.
git-svn-id: svn+ssh://svn.code.sf.net/p/supertuxkart/code/trunk/supertuxkart@2128 178a84e3-b1eb-0310-8ba1-8eac791a3b58
2008-06-13 00:53:52 +00:00

253 lines
7.8 KiB
C++

// $Id: grand_prix_ending.cpp 1681 2008-04-09 13:52:48Z hikerstk $
//
// SuperTuxKart - a fun racing game with go-kart
// Copyright (C) 2008 Joerg Henrichs
//
// 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 3
// of the License, 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.
#include <sstream>
#include <string>
#include <SDL/SDL.h>
#include "leader_result.hpp"
#include "loader.hpp"
#include "sound_manager.hpp"
#include "kart_properties_manager.hpp"
#include "unlock_manager.hpp"
#include "widget_manager.hpp"
#include "race_manager.hpp"
#include "game_manager.hpp"
#include "user_config.hpp"
#include "menu_manager.hpp"
#include "kart_properties.hpp"
#include "translation.hpp"
#include "kart.hpp"
#include "world.hpp"
#include "scene.hpp"
#if defined(WIN32) && !defined(__CYGWIN__)
# define snprintf _snprintf
#endif
enum WidgetTokens
{
WTOK_TITLE,
WTOK_QUIT,
WTOK_FIRSTKART
};
LeaderResult::LeaderResult()
: m_kart(0)
{
// for some strange reasons plib calls makeCurrent() in ssgContext
// constructor, so we have to save the old one here and restore it
ssgContext* oldContext = ssgGetCurrentContext();
m_context = new ssgContext;
oldContext->makeCurrent();
const unsigned int MAX_STR_LEN = 60;
const unsigned int NUM_KARTS = race_manager->getNumKarts();
int *scores = new int[NUM_KARTS];
int *position = new int[NUM_KARTS];
double *race_time = new double[NUM_KARTS];
// Ignore kart 0, since it was the leader
for( unsigned int kart_id = 1; kart_id < NUM_KARTS; ++kart_id )
{
position[kart_id] = kart_id;
scores[kart_id] = race_manager->getKartScore(kart_id);
race_time[kart_id] = race_manager->getOverallTime(kart_id);
}
//Bubblesort
bool sorted;
do
{
sorted = true;
for( unsigned int i = 1; i < NUM_KARTS - 1; ++i )
{
if( scores[i] < scores[i+1] || (scores[i] == scores[i+1]
&& race_time[i] > race_time[i+1]))
{
int tmp_score[2];
double tmp_time;
tmp_score[0] = position[i];
tmp_score[1] = scores[i];
tmp_time = race_time[i];
position[i] = position[i+1];
scores[i] = scores[i+1];
race_time[i] = race_time[i+1];
position[i+1] = tmp_score[0];
scores[i+1] = tmp_score[1];
race_time[i+1] = tmp_time;
sorted = false;
}
}
} while(!sorted);
static char output[MAX_MESSAGE_LENGTH];
snprintf(output, sizeof(output),
_("The winner is %s!"),race_manager->getKartName(position[1]).c_str());
widget_manager->addWgt( WTOK_TITLE, 60, 10);
widget_manager->showWgtRect(WTOK_TITLE);
widget_manager->showWgtText(WTOK_TITLE);
widget_manager->setWgtText(WTOK_TITLE, output);
widget_manager->setWgtTextSize(WTOK_TITLE, WGT_FNT_LRG);
widget_manager->breakLine();
m_score = new char[MAX_STR_LEN*NUM_KARTS];
for(unsigned int i=1; i < NUM_KARTS; ++i)
{
// char sTime[20];
// For now: don't display the time, since it's not correctly
// set in follow-the-leader
//TimeToString(race_time[i], sTime);
sprintf((char*)(m_score + MAX_STR_LEN * i), "%d. %s %d",
i , race_manager->getKartName(position[i]).c_str(), scores[i]);
widget_manager->addWgt(WTOK_FIRSTKART + i, 40, 5);
widget_manager->showWgtRect(WTOK_FIRSTKART + i);
widget_manager->showWgtText(WTOK_FIRSTKART + i);
widget_manager->setWgtText(WTOK_FIRSTKART + i,
(char*)(m_score + MAX_STR_LEN * i));
widget_manager->setWgtTextSize(WTOK_FIRSTKART + i, WGT_FNT_SML);
widget_manager->breakLine();
}
const std::string KART_NAME = race_manager->getKartName(position[1]);
const KartProperties* WINNING_KART = kart_properties_manager->getKart(KART_NAME);
delete []scores;
delete []position;
delete []race_time;
widget_manager->addWgt(WTOK_QUIT, 50, 7);
widget_manager->activateWgt(WTOK_QUIT);
widget_manager->showWgtRect(WTOK_QUIT);
widget_manager->showWgtText(WTOK_QUIT);
if(unlock_manager->getUnlockedFeatures().size()>0)
{
widget_manager->setWgtText(WTOK_QUIT, _("Continue"));
}
else
{
widget_manager->setWgtText(WTOK_QUIT, _("Back to the main menu"));
}
widget_manager->layout(WGT_AREA_TOP);
m_kart = new ssgTransform;
m_kart->ref();
ssgEntity* kartentity = WINNING_KART->getModel();
m_kart->addKid(kartentity);
sound_manager->playSfx(SOUND_WINNER);
m_clock = 0;
//FIXME: this is taken from RaceMode::exit_race,
//this should be organized better.
scene->clear();
delete world;
world = 0;
race_manager->m_active_race = false;
}
//-----------------------------------------------------------------------------
LeaderResult::~LeaderResult()
{
widget_manager->reset();
ssgDeRefDelete(m_kart);
delete m_context;
delete[] m_score;
//The next line prevents textures like the background of the main menu from
//going white after finishing the grandprix
// FIXME: I think this is not necessary anymore after the
// texture bug fix (r733) - but I can't currently test this.
loader->shared_textures.removeAll();
}
//-----------------------------------------------------------------------------
void LeaderResult::update(float dt)
{
m_clock += dt * 40.0f;
glClearColor (0.1f, 0.1f, 0.1f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
ssgContext* oldContext = ssgGetCurrentContext();
m_context -> makeCurrent();
// FIXME: A bit hackish...
glViewport ( 0, 0, 800, 320);
m_context -> setFOV ( 45.0f, 45.0f * 320.0f/800.0f ) ;
m_context -> setNearFar ( 0.05f, 1000.0f ) ;
sgCoord cam_pos;
sgSetCoord(&cam_pos, 0, 0, 0, 0, 0, 0);
m_context -> setCamera ( &cam_pos ) ;
glEnable (GL_DEPTH_TEST);
sgCoord trans;
sgSetCoord(&trans, 0, 3, -.4f, m_clock, 0, 0);
m_kart->setTransform (&trans) ;
//glShadeModel(GL_SMOOTH);
ssgCullAndDraw ( m_kart ) ;
glViewport ( 0, 0, user_config->m_width, user_config->m_height ) ;
glDisable (GL_DEPTH_TEST);
oldContext->makeCurrent();
BaseGUI::update(dt);
}
//-----------------------------------------------------------------------------
void LeaderResult::select()
{
// If a new feature was unlocked, display the new feature first
// before returning to the main menu
if(unlock_manager->getUnlockedFeatures().size()>0)
{
// This removes this menu from the stack, and adds the main menu.
// Then we push the new feature menu on top, so that it will be
// displayed next, and on return the main menu is shown.
menu_manager->switchToMainMenu();
menu_manager->pushMenu(MENUID_UNLOCKED_FEATURE);
return;
}
menu_manager->switchToMainMenu();
}
//-----------------------------------------------------------------------------
void LeaderResult::handle(GameAction ga, int value)
{
// Attempts to close the menu are silently discarded
// since they do not make sense at this point.
if (ga == GA_LEAVE)
return;
else
BaseGUI::handle(ga, value);
}