diff --git a/android/AndroidManifest.xml b/android/AndroidManifest.xml
index 3a3af85ee..7308272e6 100644
--- a/android/AndroidManifest.xml
+++ b/android/AndroidManifest.xml
@@ -39,8 +39,6 @@
-
-
diff --git a/android/make.sh b/android/make.sh
index 338a7476b..10ba5437f 100755
--- a/android/make.sh
+++ b/android/make.sh
@@ -237,7 +237,7 @@ if [ -f "$DIRNAME/obj/project_version" ]; then
PROJECT_VERSION_PREV=$(cat "$DIRNAME/obj/project_version")
if [ -z "$PROJECT_VERSION" ]; then
- PROJECT_VERSION="$PROJECT_VERSION_PREV"
+ export PROJECT_VERSION="$PROJECT_VERSION_PREV"
elif [ "$PROJECT_VERSION" != "$PROJECT_VERSION_PREV" ]; then
echo "Different project version has been set. Forcing recompilation..."
touch -c "$DIRNAME/Android.mk"
@@ -246,7 +246,7 @@ fi
if [ -z "$PROJECT_VERSION" ]; then
if [ $IS_DEBUG_BUILD -ne 0 ]; then
- PROJECT_VERSION="git"
+ export PROJECT_VERSION="git"
else
echo "Error: Variable PROJECT_VERSION is not set. It must have unique" \
"value for release build."
diff --git a/src/achievements/achievement.cpp b/src/achievements/achievement.cpp
index d6dbb3589..7aa60397b 100644
--- a/src/achievements/achievement.cpp
+++ b/src/achievements/achievement.cpp
@@ -68,8 +68,8 @@ void Achievement::load(const XMLNode *node)
*/
void Achievement::save(UTFWriter &out)
{
- out << L" \n";
diff --git a/src/achievements/achievements_status.cpp b/src/achievements/achievements_status.cpp
index bccf443d2..2b51abe7e 100644
--- a/src/achievements/achievements_status.cpp
+++ b/src/achievements/achievements_status.cpp
@@ -94,14 +94,14 @@ void AchievementsStatus::add(Achievement *achievement)
*/
void AchievementsStatus::save(UTFWriter &out)
{
- out << L" \n";
+ out << " \n";
std::map::const_iterator i;
for(i = m_achievements.begin(); i != m_achievements.end(); i++)
{
if (i->second != NULL)
i->second->save(out);
}
- out << L" \n";
+ out << " \n";
} // save
// ----------------------------------------------------------------------------
diff --git a/src/challenges/challenge_status.cpp b/src/challenges/challenge_status.cpp
index 1c0c36863..1397422ea 100644
--- a/src/challenges/challenge_status.cpp
+++ b/src/challenges/challenge_status.cpp
@@ -104,15 +104,15 @@ bool ChallengeStatus::isGrandPrix()
void ChallengeStatus::save(UTFWriter& writer)
{
- writer << L" <" << m_data->getChallengeId();
+ writer << " <" << m_data->getChallengeId();
if (isSolved(RaceManager::DIFFICULTY_BEST))
- writer << L" solved=\"best\"/>\n";
+ writer << " solved=\"best\"/>\n";
else if (isSolved(RaceManager::DIFFICULTY_HARD))
- writer << L" solved=\"hard\"/>\n";
+ writer << " solved=\"hard\"/>\n";
else if (isSolved(RaceManager::DIFFICULTY_MEDIUM))
- writer << L" solved=\"medium\"/>\n";
+ writer << " solved=\"medium\"/>\n";
else if (isSolved(RaceManager::DIFFICULTY_EASY))
- writer << L" solved=\"easy\"/>\n";
+ writer << " solved=\"easy\"/>\n";
else
- writer << L" solved=\"none\"/>\n";
+ writer << " solved=\"none\"/>\n";
} // save
diff --git a/src/challenges/story_mode_status.cpp b/src/challenges/story_mode_status.cpp
index 8fb8d820a..266f6548d 100644
--- a/src/challenges/story_mode_status.cpp
+++ b/src/challenges/story_mode_status.cpp
@@ -355,7 +355,7 @@ void StoryModeStatus::grandPrixFinished()
*/
void StoryModeStatus::save(UTFWriter &out)
{
- out << L" \n";
+ out << " \n";
std::map::const_iterator i;
for(i = m_challenges_state.begin();
i != m_challenges_state.end(); i++)
@@ -363,5 +363,5 @@ void StoryModeStatus::save(UTFWriter &out)
if (i->second != NULL)
i->second->save(out);
}
- out << L" \n";
+ out << " \n";
} // save
diff --git a/src/config/player_manager.cpp b/src/config/player_manager.cpp
index 416600b46..f52e470e4 100644
--- a/src/config/player_manager.cpp
+++ b/src/config/player_manager.cpp
@@ -261,14 +261,14 @@ void PlayerManager::save()
std::string filename = file_manager->getUserConfigFile("players.xml");
try
{
- UTFWriter players_file(filename.c_str());
+ UTFWriter players_file(filename.c_str(), false);
- players_file << L"\n";
- players_file << L"\n";
+ players_file << "\n";
+ players_file << "\n";
if(m_current_player)
{
- players_file << L" getName(true/*ignoreRTL*/)) << L"\"/>\n";
}
@@ -278,7 +278,7 @@ void PlayerManager::save()
if(!player->isGuestAccount())
player->save(players_file);
}
- players_file << L"\n";
+ players_file << "\n";
players_file.close();
}
catch (std::runtime_error& e)
diff --git a/src/config/player_profile.cpp b/src/config/player_profile.cpp
index a7b10f42a..913c70aa5 100644
--- a/src/config/player_profile.cpp
+++ b/src/config/player_profile.cpp
@@ -87,7 +87,7 @@ PlayerProfile::PlayerProfile(const XMLNode* node)
node->get("saved-session", &m_saved_session );
node->get("saved-user", &m_saved_user_id );
node->get("saved-token", &m_saved_token );
- node->get("last-online-name", &m_last_online_name );
+ node->getAndDecode("last-online-name", &m_last_online_name );
node->get("last-was-online", &m_last_was_online );
node->get("remember-password", &m_remember_password);
node->get("icon-filename", &m_icon_filename );
@@ -200,21 +200,21 @@ const std::string PlayerProfile::getIconFilename() const
*/
void PlayerProfile::save(UTFWriter &out)
{
- out << L" \n";
+ out << " saved-user=\"" << m_saved_user_id
+ << "\" saved-token=\"" << m_saved_token << "\"\n";
+ out << " last-online-name=\"" << StringUtils::xmlEncode(m_last_online_name)
+ << "\" last-was-online=\"" << m_last_was_online << "\"\n";
+ out << " remember-password=\"" << m_remember_password << "\"\n";
+ out << " default-kart-color=\"" << m_default_kart_color << "\">\n";
{
if(m_story_mode_status)
m_story_mode_status->save(out);
@@ -222,7 +222,7 @@ void PlayerProfile::save(UTFWriter &out)
if(m_achievements_status)
m_achievements_status->save(out);
}
- out << L" \n";
+ out << " \n";
} // save
//------------------------------------------------------------------------------
diff --git a/src/io/assets_android.cpp b/src/io/assets_android.cpp
index 8d7a80853..17877f10c 100644
--- a/src/io/assets_android.cpp
+++ b/src/io/assets_android.cpp
@@ -59,18 +59,18 @@ void AssetsAndroid::init()
if (getenv("SUPERTUXKART_DATADIR"))
paths.push_back(getenv("SUPERTUXKART_DATADIR"));
- if (getenv("EXTERNAL_STORAGE"))
- paths.push_back(getenv("EXTERNAL_STORAGE"));
-
- if (getenv("SECONDARY_STORAGE"))
- paths.push_back(getenv("SECONDARY_STORAGE"));
-
if (global_android_app->activity->externalDataPath)
paths.push_back(global_android_app->activity->externalDataPath);
if (global_android_app->activity->internalDataPath)
paths.push_back(global_android_app->activity->internalDataPath);
+ if (getenv("EXTERNAL_STORAGE"))
+ paths.push_back(getenv("EXTERNAL_STORAGE"));
+
+ if (getenv("SECONDARY_STORAGE"))
+ paths.push_back(getenv("SECONDARY_STORAGE"));
+
paths.push_back("/sdcard/");
paths.push_back("/storage/sdcard0/");
paths.push_back("/storage/sdcard1/");
diff --git a/src/io/utf_writer.cpp b/src/io/utf_writer.cpp
index 4232f20ab..9e12f3770 100644
--- a/src/io/utf_writer.cpp
+++ b/src/io/utf_writer.cpp
@@ -25,27 +25,40 @@ using namespace irr;
// ----------------------------------------------------------------------------
-UTFWriter::UTFWriter(const char* dest)
+UTFWriter::UTFWriter(const char* dest, bool wide)
: m_base(dest, std::ios::out | std::ios::binary)
{
+ m_wide = wide;
+
if (!m_base.is_open())
{
throw std::runtime_error("Failed to open file for writing : " +
std::string(dest));
}
- // FIXME: make sure to properly handle endianness
- // UTF-16 BOM is 0xFEFF; UTF-32 BOM is 0x0000FEFF. So this works in either case
- wchar_t BOM = 0xFEFF;
+ if (wide)
+ {
+ // FIXME: make sure to properly handle endianness
+ // UTF-16 BOM is 0xFEFF; UTF-32 BOM is 0x0000FEFF. So this works in either case
+ wchar_t BOM = 0xFEFF;
- m_base.write((char *) &BOM, sizeof(wchar_t));
+ m_base.write((char *) &BOM, sizeof(wchar_t));
+ }
} // UTFWriter
// ----------------------------------------------------------------------------
UTFWriter& UTFWriter::operator<< (const irr::core::stringw& txt)
{
- m_base.write((char *) txt.c_str(), txt.size() * sizeof(wchar_t));
+ if (m_wide)
+ {
+ m_base.write((char *) txt.c_str(), txt.size() * sizeof(wchar_t));
+ }
+ else
+ {
+ std::string utf8 = StringUtils::wideToUtf8(txt);
+ operator<<(utf8);
+ }
return *this;
} // operator<< (stringw)
@@ -53,7 +66,15 @@ UTFWriter& UTFWriter::operator<< (const irr::core::stringw& txt)
UTFWriter& UTFWriter::operator<< (const wchar_t*txt)
{
- m_base.write((char *) txt, wcslen(txt) * sizeof(wchar_t));
+ if (m_wide)
+ {
+ m_base.write((char *) txt, wcslen(txt) * sizeof(wchar_t));
+ }
+ else
+ {
+ std::string utf8 = StringUtils::wideToUtf8(txt);
+ operator<<(utf8);
+ }
return *this;
} // operator<< (wchar_t)
diff --git a/src/io/utf_writer.hpp b/src/io/utf_writer.hpp
index 02f8ebcd7..9ac71f7a5 100644
--- a/src/io/utf_writer.hpp
+++ b/src/io/utf_writer.hpp
@@ -34,9 +34,12 @@
class UTFWriter
{
std::ofstream m_base;
+
+ /** If true, use utf-16/32 (obsolete) */
+ bool m_wide;
public:
- UTFWriter(const char* dest);
+ UTFWriter(const char* dest, bool wide);
void close();
UTFWriter& operator<< (const irr::core::stringw& txt);
@@ -44,12 +47,24 @@ public:
// ------------------------------------------------------------------------
UTFWriter& operator<< (const char *txt)
{
- return operator<<(irr::core::stringw(txt));
+ if (m_wide)
+ {
+ return operator<<(irr::core::stringw(txt));
+ }
+ else
+ {
+ m_base.write((char *)txt, strlen(txt));
+ return *this;
+ }
+
} // operator<<(char*)
// ------------------------------------------------------------------------
UTFWriter& operator<< (const std::string &txt)
{
- return operator<< (irr::core::stringw(txt.c_str()));
+ if (m_wide)
+ return operator<<(irr::core::stringw(txt.c_str()));
+ else
+ return operator<<(txt.c_str());
} // operator<<(std::string)
// ------------------------------------------------------------------------
UTFWriter& operator<< (const bool &b)
diff --git a/src/modes/standard_race.cpp b/src/modes/standard_race.cpp
index 0fa6f72d3..e701c6e6b 100644
--- a/src/modes/standard_race.cpp
+++ b/src/modes/standard_race.cpp
@@ -98,36 +98,56 @@ void StandardRace::endRaceEarly()
std::vector active_players;
// Required for debugging purposes
beginSetKartPositions();
+ float worse_finish_time = 0.0f;
+
for (unsigned int i = 1; i <= kart_amount; i++)
{
int kartid = m_position_index[i-1];
AbstractKart* kart = m_karts[kartid];
+
if (kart->hasFinishedRace())
{
+ if (kart->getFinishTime() > worse_finish_time)
+ worse_finish_time = kart->getFinishTime();
+
// Have to do this to keep endSetKartPosition happy
setKartPosition(kartid, kart->getPosition());
- continue;
}
- if (kart->getController()->isPlayerController())
- {
- // Keep active players apart for now
- active_players.push_back(kartid);
- }
else
{
+ float estimated_finish_time = estimateFinishTimeForKart(kart);
+ if (estimated_finish_time > worse_finish_time)
+ worse_finish_time = estimated_finish_time;
+
+ // Keep active players apart for now
+ if (kart->getController()->isPlayerController())
+ {
+ active_players.push_back(kartid);
+ }
// AI karts finish
- setKartPosition(kartid, i - (unsigned int) active_players.size());
- kart->finishedRace(estimateFinishTimeForKart(kart));
+ else
+ {
+ setKartPosition(kartid, i - (unsigned int) active_players.size());
+ kart->finishedRace(estimated_finish_time);
+ }
}
} // i <= kart_amount
+
// Now make the active players finish
for (unsigned int i = 0; i < active_players.size(); i++)
{
int kartid = active_players[i];
int position = getNumKarts() - (int) active_players.size() + 1 + i;
setKartPosition(kartid, position);
- m_karts[kartid]->eliminate();
+ float punished_time = estimateFinishTimeForKart(m_karts[kartid])
+ + worse_finish_time - WorldStatus::getTime();
+ m_karts[kartid]->finishedRace(punished_time);
+
+ // In networked races, endRaceEarly will be called if a player
+ // takes too much time to finish, so don't mark him as eliminated
+ if (!isNetworkWorld())
+ m_karts[kartid]->eliminate();
} // Finish the active players
endSetKartPositions();
setPhase(RESULT_DISPLAY_PHASE);
diff --git a/src/race/grand_prix_data.cpp b/src/race/grand_prix_data.cpp
index 1a662f091..90ca62cb3 100644
--- a/src/race/grand_prix_data.cpp
+++ b/src/race/grand_prix_data.cpp
@@ -270,7 +270,7 @@ void GrandPrixData::reload()
throw std::runtime_error("Wrong root node name");
}
- if (!root->get("name", &m_name))
+ if (!root->getAndDecode("name", &m_name))
{
Log::error("GrandPrixData",
"Error while trying to read grandprix file '%s': "
@@ -361,20 +361,20 @@ bool GrandPrixData::writeToFile()
{
try
{
- UTFWriter file(m_filename.c_str());
+ UTFWriter file(m_filename.c_str(), false);
if (file.is_open())
{
- file << L"\n\n\n";
+ file << "\n\n\n";
for (unsigned int i = 0; i < m_tracks.size(); i++)
{
file <<
- L"\t\n";
+ "\t\n";
}
- file << L"\n\n";
+ file << "\n\n";
file.close();
diff --git a/src/race/highscore_manager.cpp b/src/race/highscore_manager.cpp
index 92eff9094..e0fc094f4 100644
--- a/src/race/highscore_manager.cpp
+++ b/src/race/highscore_manager.cpp
@@ -150,15 +150,15 @@ void HighscoreManager::saveHighscores()
try
{
- UTFWriter highscore_file(m_filename.c_str());
- highscore_file << L"\n";
- highscore_file << L"\n";
+ UTFWriter highscore_file(m_filename.c_str(), false);
+ highscore_file << "\n";
+ highscore_file << "\n";
for(unsigned int i=0; iwriteEntry(highscore_file);
}
- highscore_file << L"\n";
+ highscore_file << "\n";
highscore_file.close();
}
catch(std::exception &e)
diff --git a/src/race/highscores.cpp b/src/race/highscores.cpp
index bc5a4f2c5..54daf277e 100644
--- a/src/race/highscores.cpp
+++ b/src/race/highscores.cpp
@@ -83,7 +83,7 @@ void Highscores::readEntry(const XMLNode &node)
{
const XMLNode *entry = node.getNode(i);
entry->get("time", &m_time[i] );
- entry->get("name", &m_name[i] );
+ entry->getAndDecode("name", &m_name[i] );
entry->get("kartname", &m_kart_name[i] );
// a non-empty entry needs a non-empty kart name.
@@ -113,25 +113,25 @@ void Highscores::writeEntry(UTFWriter &writer)
one_is_set |= m_time[i]>=0;
if(!one_is_set) return;
- writer << L" \n";
+ writer << " \n";
for(int i=0; i 0.0f)
{
assert(m_kart_name[i].size() > 0);
- writer << L" \n";
+ writer << " \n";
}
} // for i
- writer << L" \n";
+ writer << " \n";
} // writeEntry
// -----------------------------------------------------------------------------