From 0b35249b43422b4595cb05e3d433804721bf491f Mon Sep 17 00:00:00 2001 From: hikerstk Date: Thu, 29 Jul 2010 23:03:20 +0000 Subject: [PATCH] Improved new race result gui - it now consists of two parts: first the results of the just finished race, then an animated display of the GP standings (to test this please change the #undef USE_NEW_RACE_RESULT in race_result_gui.cpp). git-svn-id: svn+ssh://svn.code.sf.net/p/supertuxkart/code/main/trunk@5710 178a84e3-b1eb-0310-8ba1-8eac791a3b58 --- src/race/race_manager.cpp | 31 +++-- src/race/race_manager.hpp | 15 ++- src/states_screens/race_result_gui.cpp | 177 ++++++++++++++++--------- src/states_screens/race_result_gui.hpp | 27 ++-- 4 files changed, 165 insertions(+), 85 deletions(-) diff --git a/src/race/race_manager.cpp b/src/race/race_manager.cpp index 41fdf330b..2bba85483 100644 --- a/src/race/race_manager.cpp +++ b/src/race/race_manager.cpp @@ -99,7 +99,18 @@ void RaceManager::setLocalKartInfo(unsigned int player_id, const std::string& ka } // setLocalKartInfo //----------------------------------------------------------------------------- +/** Returns the kart with a given GP rank (or NULL if no such kart exists). + * \param n Rank (0<=ngetKart(i); + return NULL; +} // getKLartWithGPRank +//----------------------------------------------------------------------------- int RaceManager::getLocalPlayerGPRank(const int playerID) const { const int amount = m_kart_status.size(); @@ -199,8 +210,13 @@ void RaceManager::startNew() // First add the AI karts (randomly chosen) // ---------------------------------------- + int init_gp_rank = 0; for(unsigned int i=0; igetMinorMode()==RaceManager::MINOR_MODE_FOLLOW_LEADER) ? 1 : 0; + int start=(race_manager->getMinorMode()==RaceManager::MINOR_MODE_FOLLOW_LEADER); for (unsigned int kart_id = start; kart_id < NUM_KARTS; ++kart_id) { position[kart_id] = kart_id; @@ -394,7 +410,6 @@ void RaceManager::exitRace() // were finished, and not when a race is aborted. if (m_major_mode==MAJOR_MODE_GRAND_PRIX && m_track_number==(int)m_tracks.size()) { - computeGPRanks(); unlock_manager->grandPrixFinished(); StateManager::get()->resetAndGoToScreen( MainMenuScreen::getInstance() ); diff --git a/src/race/race_manager.hpp b/src/race/race_manager.hpp index 24e80d00a..e206a48d9 100644 --- a/src/race/race_manager.hpp +++ b/src/race/race_manager.hpp @@ -188,20 +188,23 @@ private: std::string m_player_name; // for networked karts int m_score; // score for this kart int m_last_score; // needed for restart race, and for race results GUI. - double m_overall_time; // sum of times of all races - double m_last_time; // needed for restart + float m_overall_time; // sum of times of all races + float m_last_time; // needed for restart int m_prev_finish_pos; // previous finished position KartType m_kart_type; // Kart type: AI, player, network player etc. int m_local_player_id; // player controling the kart, for AI: -1 int m_global_player_id; // global ID of player - int m_gp_rank; // In GPs, at the end, will hold the overall rank of this kart. + int m_gp_rank; // In GPs, at the end, will hold the overall + // rank of this kart (0<=m_gp_rank < num_karts-1) KartStatus(const std::string& ident, const int& prev_finish_pos, - int local_player_id, int global_player_id, KartType kt) : + int local_player_id, int global_player_id, + int init_gp_rank, KartType kt) : m_ident(ident), m_score(0), m_last_score(0), m_overall_time(0.0f), m_last_time(0.0f), m_prev_finish_pos(prev_finish_pos), m_kart_type(kt), m_local_player_id(local_player_id), + m_gp_rank(init_gp_rank), m_global_player_id(global_player_id) {} @@ -283,7 +286,7 @@ public: void computeGPRanks(); int getKartGPRank(const int kart_id) const { return m_kart_status[kart_id].m_gp_rank; } - + const Kart* getKartWithGPRank(unsigned int n); /** \return the GP rank of a local player, or -1 if the given player ID doesn't exist */ int getLocalPlayerGPRank(const int playerID) const; @@ -295,7 +298,7 @@ public: const { return m_kart_status[k].m_local_player_id; } int getKartGlobalPlayerId(int k) const { return m_kart_status[k].m_global_player_id; } - double getOverallTime(int kart) const { return m_kart_status[kart].m_overall_time;} + float getOverallTime(int kart) const { return m_kart_status[kart].m_overall_time;} KartType getKartType(int kart) const { return m_kart_status[kart].m_kart_type;} int getCoinTarget() const { return m_coin_target; } int getPositionScore(int p) const { return m_score_for_position[p-1]; } diff --git a/src/states_screens/race_result_gui.cpp b/src/states_screens/race_result_gui.cpp index 277f722eb..459948a39 100644 --- a/src/states_screens/race_result_gui.cpp +++ b/src/states_screens/race_result_gui.cpp @@ -29,7 +29,7 @@ */ RaceResultGUI::RaceResultGUI() { -#define USE_NEW_RACE_RESULT +#undef USE_NEW_RACE_RESULT #ifndef USE_NEW_RACE_RESULT // FIXME: for now disable the new race result display @@ -38,9 +38,9 @@ RaceResultGUI::RaceResultGUI() new RaceOverDialog(0.6f, 0.9f); return; #else - determineLayout(); + determineTableLayout(); m_timer = 0; - m_animation_state = RR_BEGIN_FIRST_TABLE; + m_animation_state = RR_INIT; #endif } // RaceResultGUI @@ -63,20 +63,21 @@ RaceResultGUI::~RaceResultGUI() */ void RaceResultGUI::nextPhase() { + // FIXME: make sure that computeGPRanks is called here!! new RaceOverDialog(0.6f, 0.9f); } // nextPhase //----------------------------------------------------------------------------- /** This determines the layout, i.e. the size of all columns, font size etc. */ -void RaceResultGUI::determineLayout() +void RaceResultGUI::determineTableLayout() { m_font = GUIEngine::getFont(); + assert(m_font); m_was_monospace = m_font->getMonospaceDigits(); m_font->setMonospaceDigits(true); - - assert(m_font); World *world = World::getWorld(); + std::vector order; world->raceResultOrder(&order); @@ -103,10 +104,6 @@ void RaceResultGUI::determineLayout() core::dimension2d rect = m_font->getDimension(kart->getName().c_str()); if(rect.Width > m_width_kart_name) m_width_kart_name = rect.Width; - m_new_points.push_back(race_manager->getPositionScore(i+1)); - int p = race_manager->getKartPrevScore(order[i]); - m_new_overall_points.push_back(p+m_new_points[i]); - m_current_displayed_points.push_back((float)p); } // for i < order.size() std::string max_time = StringUtils::timeToString(max_finish_time); @@ -119,7 +116,7 @@ void RaceResultGUI::determineLayout() unsigned int num_karts = m_finish_time_string.size(); // Top pixel where to display text - unsigned int top = (int)(0.15f*UserConfigParams::m_height); + m_top = (int)(0.15f*UserConfigParams::m_height); // Height of the result display unsigned int height = (int)(0.7f *UserConfigParams::m_height); @@ -133,7 +130,7 @@ void RaceResultGUI::determineLayout() m_time_single_scroll = 0.2f; // Time to rotate the entries to the proper GP position. - m_time_rotation = 2.0f; + m_time_rotation = 1.0f; // The time the first phase is being displayed: add the start time // of the last kart to the duration of the scroll plus some time @@ -162,10 +159,10 @@ void RaceResultGUI::determineLayout() // Determine width of new points column core::dimension2du r_new_p = m_font->getDimension(L"+99"); - m_width_new_points = r_new_p.Width; + m_width_new_points = r_new_p.Width; // Determine width of overall points column - core::dimension2du r_all_p = m_font->getDimension(L"9999"); + core::dimension2du r_all_p = m_font->getDimension(L"9999"); unsigned int width_all_points = r_all_p.Width; unsigned int table_width = m_width_icon + m_width_kart_name @@ -177,27 +174,7 @@ void RaceResultGUI::determineLayout() + 2 * m_width_column_space; m_leftmost_column = (UserConfigParams::m_width - table_width)/2; - if(race_manager->getMajorMode()==RaceManager::MAJOR_MODE_GRAND_PRIX) - race_manager->computeGPRanks(); - m_start_at.clear(); - for(unsigned int i=0; igetMajorMode()==RaceManager::MAJOR_MODE_GRAND_PRIX) - { - int gp_position = race_manager->getKartGPRank(order[i]); - if(gp_position<(int)i) - printf("X"); - m_radius.push_back( (gp_position-(int)i)*(int)m_distance_between_rows*0.5f); - m_centre_point.push_back(top+(gp_position+i)*m_distance_between_rows*0.5f); - } - } // i < num_karts - - -} // determineLayout +} // determineTableLayout //----------------------------------------------------------------------------- /** Render all global parts of the race gui, i.e. things that are only @@ -210,31 +187,57 @@ void RaceResultGUI::renderGlobal(float dt) World *world = World::getWorld(); assert(world->getPhase()==WorldStatus::RESULT_DISPLAY_PHASE); unsigned int num_karts = world->getNumKarts(); - - + + // First: Update the finite state machine, and set + // the current X and Y positions. + // =============================================== switch(m_animation_state) { - case RR_BEGIN_FIRST_TABLE: if(m_timer > m_time_overall_scroll) - { - m_animation_state = RR_INCREASE_POINTS; - m_timer = 0; - } - break; - case RR_INCREASE_POINTS: if(m_timer > 5) - { - m_animation_state = RR_RESORT_TABLE; - m_timer = 0; - } - break; - case RR_RESORT_TABLE: if(m_timer > m_time_rotation) - { - m_animation_state = RR_WAIT_TILL_END; - // Make the new row permanent. - for(unsigned int i=0; i m_time_overall_scroll) + { + if(race_manager->getMajorMode()!=RaceManager::MAJOR_MODE_GRAND_PRIX) + { + m_animation_state = RR_WAIT_TILL_END; + break; + } + + determineGPLayout(); + m_animation_state = RR_OLD_GP_RESULTS; + m_timer = 0; + } + break; + case RR_OLD_GP_RESULTS: + if(m_timer > m_time_overall_scroll) + { + m_animation_state = RR_INCREASE_POINTS; + m_timer = 0; + } + case RR_INCREASE_POINTS: + if(m_timer > 5) + { + m_animation_state = RR_RESORT_TABLE; + m_timer = 0; + } + break; + case RR_RESORT_TABLE: + if(m_timer > m_time_rotation) + { + m_animation_state = RR_WAIT_TILL_END; + // Make the new row permanent. + for(unsigned int i=0; i m_start_at[i]) { // if active m_x_pos[i] -= dt*v; @@ -272,6 +277,52 @@ void RaceResultGUI::renderGlobal(float dt) } } // renderGlobal +//----------------------------------------------------------------------------- +/** Determine the layout and fields for the GP table based on the previous + * GP results. + */ +void RaceResultGUI::determineGPLayout() +{ + unsigned int num_karts = m_kart_icons.size(); + m_current_displayed_points.resize(num_karts); + m_new_points.resize(num_karts); + std::vector old_rank(num_karts, 0); + for(unsigned int kart_id=0; kart_idgetKartGPRank(kart_id); + old_rank[kart_id] = rank; + const Kart *kart = World::getWorld()->getKart(kart_id); + m_kart_icons[rank] = + kart->getKartProperties()->getIconMaterial()->getTexture(); + m_kart_names[rank] = kart->getName(); + float time = race_manager->getOverallTime(kart_id); + m_finish_time_string[rank] + = StringUtils::timeToString(time).c_str(); + m_start_at[rank] = m_time_between_rows * rank; + m_x_pos[rank] = (float)UserConfigParams::m_width; + m_y_pos[rank] = (float)(m_top+rank*m_distance_between_rows); + int p = race_manager->getKartPrevScore(kart_id); + m_current_displayed_points[rank] = (float)p; + m_new_points[rank] = race_manager->getPositionScore(kart->getPosition()); + } + + // Now update the GP ranks, and determine the new position + // ------------------------------------------------------- + m_radius.resize(num_karts); + m_centre_point.resize(num_karts); + m_new_overall_points.resize(num_karts); + race_manager->computeGPRanks(); + for(unsigned int i=0; igetKartGPRank(i); + m_radius[j] = (j-gp_position)*(int)m_distance_between_rows*0.5f; + m_centre_point[j] = m_top+(gp_position+j)*m_distance_between_rows*0.5f; + int p = race_manager->getKartScore(i); + m_new_overall_points[j] = p; + } // i < num_karts +} // determineGPLayout + //----------------------------------------------------------------------------- /** Displays the race results for a single kart. * \param n Index of the kart to be displayed. @@ -312,9 +363,11 @@ void RaceResultGUI::displayOneEntry(unsigned int x, unsigned int y, m_font->draw(m_finish_time_string[n], dest_rect, color); m_font->setMonospaceDigits(mono); - // Only display points in GP mode. - // =============================== - if(race_manager->getMajorMode()!=RaceManager::MAJOR_MODE_GRAND_PRIX) + + // Only display points in GP mode and when the GP results are displayed. + // ===================================================================== + if(race_manager->getMajorMode()!=RaceManager::MAJOR_MODE_GRAND_PRIX || + m_animation_state == RR_RACE_RESULT) return; // Draw the new points diff --git a/src/states_screens/race_result_gui.hpp b/src/states_screens/race_result_gui.hpp index c65cb997d..72215f6bb 100644 --- a/src/states_screens/race_result_gui.hpp +++ b/src/states_screens/race_result_gui.hpp @@ -44,13 +44,18 @@ private: float m_timer; /** Finite state machine for the animations: - BEGIN_FIRST_TABLE: The rows scroll into place. - INCREASE_POINTS: The overall points are added up - RESORT_TABLE: Resort the table so that it is now sorted by - GP points. - WAIT_TILL_END Some delay to wait for end, after a period it - wii automatically end. */ - enum {RR_BEGIN_FIRST_TABLE, + INIT: Set up data structures. + RACE_RESULT: The rows scroll into place. + OLD_GP_TABLE: Scroll new table into place, sorted by previous + GP ranks + INCREASE_POINTS: The overall points are added up + RESORT_TABLE: Resort the table so that it is now sorted by + GP points. + WAIT_TILL_END Some delay to wait for end, after a period it + wii automatically end. */ + enum {RR_INIT, + RR_RACE_RESULT, + RR_OLD_GP_RESULTS, RR_INCREASE_POINTS, RR_RESORT_TABLE, RR_WAIT_TILL_END} @@ -63,7 +68,7 @@ private: std::vector m_x_pos; /** Currenct Y position. */ - std::vector m_y_pos; + std::vector m_y_pos; /** The center point when sorting the entries. */ std::vector m_centre_point; @@ -131,6 +136,9 @@ private: table is aligned. */ unsigned int m_leftmost_column; + /** Top-most pixel for first row. */ + unsigned int m_top; + /** Size of space between columns. */ unsigned int m_width_column_space; @@ -142,7 +150,8 @@ private: void displayOneEntry(unsigned int x, unsigned int y, unsigned int n, bool display_points); - void determineLayout(); + void determineTableLayout(); + void determineGPLayout(); public: