From cc06d35bc7cc775481c8985131871c3ce2e64989 Mon Sep 17 00:00:00 2001 From: Muzychenko Andrey <33288308+k4zmu2a@users.noreply.github.com> Date: Mon, 11 Apr 2022 10:28:20 +0300 Subject: [PATCH] Fixed high score insertion for multiple players. Refactored high_score. Issue #131. --- SpaceCadetPinball/control.cpp | 2 +- SpaceCadetPinball/high_score.cpp | 132 +++++++++++++++---------------- SpaceCadetPinball/high_score.h | 33 +++++--- SpaceCadetPinball/pb.cpp | 36 ++++----- SpaceCadetPinball/pb.h | 1 - 5 files changed, 102 insertions(+), 102 deletions(-) diff --git a/SpaceCadetPinball/control.cpp b/SpaceCadetPinball/control.cpp index 7af2705..8747dd9 100644 --- a/SpaceCadetPinball/control.cpp +++ b/SpaceCadetPinball/control.cpp @@ -3148,7 +3148,7 @@ void control::GameoverController(int code, TPinballComponent* caller) if (missionMsg & 0x200) { int highscoreId = missionMsg % 5; - int highScore = pb::highscore_table[highscoreId].Score; + int highScore = high_score::highscore_table[highscoreId].Score; auto nextHidhscoreId = highscoreId + 1; if (highScore > 0) { diff --git a/SpaceCadetPinball/high_score.cpp b/SpaceCadetPinball/high_score.cpp index 819eefc..5af1c26 100644 --- a/SpaceCadetPinball/high_score.cpp +++ b/SpaceCadetPinball/high_score.cpp @@ -5,136 +5,114 @@ #include "pinball.h" #include "score.h" -int high_score::dlg_enter_name; -int high_score::dlg_score; -int high_score::dlg_position; -char high_score::default_name[32]{}; -high_score_struct* high_score::dlg_hst; +bool high_score::dlg_enter_name; bool high_score::ShowDialog = false; +high_score_entry high_score::DlgData; +std::vector high_score::ScoreQueue; +high_score_struct high_score::highscore_table[5]; - -int high_score::read(high_score_struct* table) +int high_score::read() { char Buffer[20]; int checkSum = 0; - clear_table(table); + clear_table(); for (auto position = 0; position < 5; ++position) { - auto tablePtr = &table[position]; + auto& tablePtr = highscore_table[position]; snprintf(Buffer, sizeof Buffer, "%d", position); strcat(Buffer, ".Name"); auto name = options::get_string(Buffer, ""); - strncpy(tablePtr->Name, name.c_str(), sizeof tablePtr->Name); + strncpy(tablePtr.Name, name.c_str(), sizeof tablePtr.Name); snprintf(Buffer, sizeof Buffer, "%d", position); strcat(Buffer, ".Score"); - tablePtr->Score = options::get_int(Buffer, tablePtr->Score); + tablePtr.Score = options::get_int(Buffer, tablePtr.Score); - for (int i = static_cast(strlen(tablePtr->Name)); --i >= 0; checkSum += tablePtr->Name[i]) + for (int i = static_cast(strlen(tablePtr.Name)); --i >= 0; checkSum += tablePtr.Name[i]) { } - checkSum += tablePtr->Score; + checkSum += tablePtr.Score; } auto verification = options::get_int("Verification", 7); if (checkSum != verification) - clear_table(table); + clear_table(); return 0; } -int high_score::write(high_score_struct* table) +int high_score::write() { char Buffer[20]; int checkSum = 0; for (auto position = 0; position < 5; ++position) { - auto tablePtr = &table[position]; + auto& tablePtr = highscore_table[position]; snprintf(Buffer, sizeof Buffer, "%d", position); strcat(Buffer, ".Name"); - options::set_string(Buffer, tablePtr->Name); + options::set_string(Buffer, tablePtr.Name); snprintf(Buffer, sizeof Buffer, "%d", position); strcat(Buffer, ".Score"); - options::set_int(Buffer, tablePtr->Score); + options::set_int(Buffer, tablePtr.Score); - for (int i = static_cast(strlen(tablePtr->Name)); --i >= 0; checkSum += tablePtr->Name[i]) + for (int i = static_cast(strlen(tablePtr.Name)); --i >= 0; checkSum += tablePtr.Name[i]) { } - checkSum += tablePtr->Score; + checkSum += tablePtr.Score; } options::set_int("Verification", checkSum); return 0; } -void high_score::clear_table(high_score_struct* table) +void high_score::clear_table() { - for (int index = 5; index; --index) + for (auto& table : highscore_table) { - table->Score = -999; - table->Name[0] = 0; - ++table; + table.Score = -999; + table.Name[0] = 0; } } -int high_score::get_score_position(high_score_struct* table, int score) +int high_score::get_score_position(int score) { if (score <= 0) return -1; for (int position = 0; position < 5; position++) { - if (table[position].Score < score) + if (highscore_table[position].Score < score) return position; } return -1; } -int high_score::place_new_score_into(high_score_struct* table, int score, LPSTR scoreStr, int position) +void high_score::place_new_score_into(high_score_entry data) { - if (position >= 0) + if (data.Position >= 0 && data.Position < 5) { - if (position <= 4) + for (int i = 4; i > data.Position; i--) { - high_score_struct* tablePtr = table + 4; - int index = 5 - position; - do - { - --index; - memcpy(tablePtr, &tablePtr[-1], sizeof(high_score_struct)); - --tablePtr; - } - while (index); + highscore_table[i] = highscore_table[i - 1]; } - high_score_struct* posTable = &table[position]; - posTable->Score = score; - if (strlen(scoreStr) >= 31) - scoreStr[31] = 0; - strncpy(posTable->Name, scoreStr, sizeof posTable->Name); - posTable->Name[31] = 0; + + data.Entry.Name[31] = 0; + highscore_table[data.Position] = data.Entry; } - return position; } -void high_score::show_high_score_dialog(high_score_struct* table) +void high_score::show_high_score_dialog() { - dlg_enter_name = 0; - dlg_score = 0; - dlg_hst = table; ShowDialog = true; } -void high_score::show_and_set_high_score_dialog(high_score_struct* table, int score, int pos, LPCSTR defaultName) +void high_score::show_and_set_high_score_dialog(high_score_entry score) { - dlg_position = pos; - dlg_score = score; - dlg_hst = table; - dlg_enter_name = 1; - strncpy(default_name, defaultName, sizeof default_name - 1); + ScoreQueue.insert(ScoreQueue.begin(), score); ShowDialog = true; } @@ -143,12 +121,27 @@ void high_score::RenderHighScoreDialog() if (ShowDialog == true) { ShowDialog = false; - if (dlg_position == -1) + if (!ImGui::IsPopupOpen("High Scores")) { - dlg_enter_name = 0; - return; + dlg_enter_name = false; + while (!ScoreQueue.empty()) + { + DlgData = ScoreQueue.back(); + ScoreQueue.pop_back(); + if (DlgData.Position < 0 || DlgData.Position > 4) + { + DlgData.Position = get_score_position(DlgData.Entry.Score); + } + + if (DlgData.Position != -1) + { + dlg_enter_name = true; + break; + } + } + + ImGui::OpenPopup("High Scores"); } - ImGui::OpenPopup("High Scores"); } bool unused_open = true; @@ -169,15 +162,15 @@ void high_score::RenderHighScoreDialog() snprintf(buf, sizeof buf, "%d", row + 1); ImGui::TextUnformatted(buf); - auto currentRow = &dlg_hst[row + offset]; + auto currentRow = &highscore_table[row + offset]; auto score = currentRow->Score; ImGui::TableNextColumn(); - if (dlg_enter_name == 1 && dlg_position == row) + if (dlg_enter_name && DlgData.Position == row) { offset = -1; - score = dlg_score; + score = DlgData.Entry.Score; ImGui::PushItemWidth(200); - ImGui::InputText("", default_name, IM_ARRAYSIZE(default_name)); + ImGui::InputText("", DlgData.Entry.Name, IM_ARRAYSIZE(DlgData.Entry.Name)); } else { @@ -195,8 +188,7 @@ void high_score::RenderHighScoreDialog() { if (dlg_enter_name) { - default_name[31] = 0; - place_new_score_into(dlg_hst, dlg_score, default_name, dlg_position); + place_new_score_into(DlgData); } ImGui::CloseCurrentPopup(); } @@ -213,7 +205,7 @@ void high_score::RenderHighScoreDialog() ImGui::TextUnformatted(pinball::get_rc_string(40, 0)); if (ImGui::Button("OK", ImVec2(120, 0))) { - clear_table(dlg_hst); + clear_table(); ImGui::CloseCurrentPopup(); } ImGui::SetItemDefaultFocus(); @@ -226,5 +218,11 @@ void high_score::RenderHighScoreDialog() } ImGui::EndPopup(); + + // Reenter dialog for the next score in the queue + if (!ImGui::IsPopupOpen("High Scores") && !ScoreQueue.empty()) + { + ShowDialog = true; + } } } diff --git a/SpaceCadetPinball/high_score.h b/SpaceCadetPinball/high_score.h index ed94096..bd64330 100644 --- a/SpaceCadetPinball/high_score.h +++ b/SpaceCadetPinball/high_score.h @@ -6,24 +6,31 @@ struct high_score_struct int Score; }; +struct high_score_entry +{ + high_score_struct Entry; + int Position; +}; + class high_score { public: - static int read(high_score_struct* table); - static int write(high_score_struct* table); - static void clear_table(high_score_struct* table); - static int get_score_position(high_score_struct* table, int score); - static int place_new_score_into(high_score_struct* table, int score, LPSTR scoreStr, int position); + static high_score_struct highscore_table[5]; - static void show_high_score_dialog(high_score_struct* table); - static void show_and_set_high_score_dialog(high_score_struct* table, int score, int pos, LPCSTR defaultName); + static int read(); + static int write(); + static int get_score_position(int score); + + static void show_high_score_dialog(); + static void show_and_set_high_score_dialog(high_score_entry score); static void RenderHighScoreDialog(); -private : - static int dlg_enter_name; - static int dlg_score; - static int dlg_position; - static char default_name[32]; - static high_score_struct* dlg_hst; +private: + static bool dlg_enter_name; + static high_score_entry DlgData; static bool ShowDialog; + static std::vector ScoreQueue; + + static void clear_table(); + static void place_new_score_into(high_score_entry data); }; diff --git a/SpaceCadetPinball/pb.cpp b/SpaceCadetPinball/pb.cpp index ebb8904..a30c5a2 100644 --- a/SpaceCadetPinball/pb.cpp +++ b/SpaceCadetPinball/pb.cpp @@ -32,7 +32,6 @@ DatFile* pb::record_table = nullptr; int pb::time_ticks = 0; GameModes pb::game_mode = GameModes::GameOver; float pb::time_now = 0, pb::time_next = 0, pb::ball_speed_limit, pb::time_ticks_remainder = 0; -high_score_struct pb::highscore_table[5]; bool pb::FullTiltMode = false, pb::FullTiltDemoMode = false, pb::cheat_mode = false, pb::demo_mode = false; std::string pb::DatFileName; @@ -98,7 +97,7 @@ int pb::init() MainTable = new TPinballTable(); - high_score::read(highscore_table); + high_score::read(); ball_speed_limit = MainTable->BallList.at(0)->Offset * 200.0f; return 0; } @@ -108,7 +107,7 @@ int pb::uninit() score::unload_msg_font(); loader::unload(); delete record_table; - high_score::write(highscore_table); + high_score::write(); delete MainTable; MainTable = nullptr; timer::uninit(); @@ -496,10 +495,12 @@ void pb::InputDown(GameInput input) ball->Acceleration.X = 0.0; break; case 'h': - char String1[200]; - strncpy(String1, pinball::get_rc_string(26, 0), sizeof String1 - 1); - high_score::show_and_set_high_score_dialog(highscore_table, 1000000000, 1, String1); + { + high_score_struct entry{ {0}, 1000000000 }; + strncpy(entry.Name, pinball::get_rc_string(26, 0), sizeof entry.Name - 1); + high_score::show_and_set_high_score_dialog({ entry, 1 }); break; + } case 'r': control::cheat_bump_rank(); break; @@ -522,7 +523,6 @@ void pb::end_game() { int scores[4]{}; int scoreIndex[4]{}; - char String1[200]; mode_change(GameModes::GameOver); int playerCount = MainTable->PlayerCount; @@ -556,11 +556,12 @@ void pb::end_game() { for (auto i = 0; i < playerCount; ++i) { - int position = high_score::get_score_position(highscore_table, scores[i]); + int position = high_score::get_score_position(scores[i]); if (position >= 0) { - strncpy(String1, pinball::get_rc_string(scoreIndex[i] + 26, 0), sizeof String1 - 1); - high_score::show_and_set_high_score_dialog(highscore_table, scores[i], position, String1); + high_score_struct entry{ {0}, scores[i] }; + strncpy(entry.Name, pinball::get_rc_string(scoreIndex[i] + 26, 0), sizeof entry.Name - 1); + high_score::show_and_set_high_score_dialog({ entry, -1 }); } } } @@ -568,7 +569,7 @@ void pb::end_game() void pb::high_scores() { - high_score::show_high_score_dialog(highscore_table); + high_score::show_high_score_dialog(); } void pb::tilt_no_more() @@ -583,17 +584,12 @@ bool pb::chk_highscore() { if (demo_mode) return false; - int playerIndex = MainTable->PlayerCount - 1; - if (playerIndex < 0) - return false; - for (int i = playerIndex; - high_score::get_score_position(highscore_table, MainTable->PlayerScores[i].ScoreStruct->Score) < 0; - --i) + for (auto i = 0; i < MainTable->PlayerCount; ++i) { - if (--playerIndex < 0) - return false; + if (high_score::get_score_position(MainTable->PlayerScores[i].ScoreStruct->Score) >= 0) + return true; } - return true; + return false; } float pb::collide(float timeNow, float timeDelta, TBall* ball) diff --git a/SpaceCadetPinball/pb.h b/SpaceCadetPinball/pb.h index 6ab60cb..18984db 100644 --- a/SpaceCadetPinball/pb.h +++ b/SpaceCadetPinball/pb.h @@ -45,7 +45,6 @@ public: static bool cheat_mode; static DatFile* record_table; static TPinballTable* MainTable; - static high_score_struct highscore_table[5]; static bool FullTiltMode, FullTiltDemoMode; static std::string DatFileName;