mirror of
https://github.com/k4zmu2a/SpaceCadetPinball.git
synced 2023-12-30 21:52:56 +00:00
Fixed high score insertion for multiple players.
Refactored high_score. Issue #131.
This commit is contained in:
parent
0f88e43ba2
commit
cc06d35bc7
@ -3148,7 +3148,7 @@ void control::GameoverController(int code, TPinballComponent* caller)
|
|||||||
if (missionMsg & 0x200)
|
if (missionMsg & 0x200)
|
||||||
{
|
{
|
||||||
int highscoreId = missionMsg % 5;
|
int highscoreId = missionMsg % 5;
|
||||||
int highScore = pb::highscore_table[highscoreId].Score;
|
int highScore = high_score::highscore_table[highscoreId].Score;
|
||||||
auto nextHidhscoreId = highscoreId + 1;
|
auto nextHidhscoreId = highscoreId + 1;
|
||||||
if (highScore > 0)
|
if (highScore > 0)
|
||||||
{
|
{
|
||||||
|
@ -5,136 +5,114 @@
|
|||||||
#include "pinball.h"
|
#include "pinball.h"
|
||||||
#include "score.h"
|
#include "score.h"
|
||||||
|
|
||||||
int high_score::dlg_enter_name;
|
bool 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::ShowDialog = false;
|
bool high_score::ShowDialog = false;
|
||||||
|
high_score_entry high_score::DlgData;
|
||||||
|
std::vector<high_score_entry> high_score::ScoreQueue;
|
||||||
|
high_score_struct high_score::highscore_table[5];
|
||||||
|
|
||||||
|
int high_score::read()
|
||||||
int high_score::read(high_score_struct* table)
|
|
||||||
{
|
{
|
||||||
char Buffer[20];
|
char Buffer[20];
|
||||||
|
|
||||||
int checkSum = 0;
|
int checkSum = 0;
|
||||||
clear_table(table);
|
clear_table();
|
||||||
for (auto position = 0; position < 5; ++position)
|
for (auto position = 0; position < 5; ++position)
|
||||||
{
|
{
|
||||||
auto tablePtr = &table[position];
|
auto& tablePtr = highscore_table[position];
|
||||||
|
|
||||||
snprintf(Buffer, sizeof Buffer, "%d", position);
|
snprintf(Buffer, sizeof Buffer, "%d", position);
|
||||||
strcat(Buffer, ".Name");
|
strcat(Buffer, ".Name");
|
||||||
auto name = options::get_string(Buffer, "");
|
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);
|
snprintf(Buffer, sizeof Buffer, "%d", position);
|
||||||
strcat(Buffer, ".Score");
|
strcat(Buffer, ".Score");
|
||||||
tablePtr->Score = options::get_int(Buffer, tablePtr->Score);
|
tablePtr.Score = options::get_int(Buffer, tablePtr.Score);
|
||||||
|
|
||||||
for (int i = static_cast<int>(strlen(tablePtr->Name)); --i >= 0; checkSum += tablePtr->Name[i])
|
for (int i = static_cast<int>(strlen(tablePtr.Name)); --i >= 0; checkSum += tablePtr.Name[i])
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
checkSum += tablePtr->Score;
|
checkSum += tablePtr.Score;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto verification = options::get_int("Verification", 7);
|
auto verification = options::get_int("Verification", 7);
|
||||||
if (checkSum != verification)
|
if (checkSum != verification)
|
||||||
clear_table(table);
|
clear_table();
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int high_score::write(high_score_struct* table)
|
int high_score::write()
|
||||||
{
|
{
|
||||||
char Buffer[20];
|
char Buffer[20];
|
||||||
|
|
||||||
int checkSum = 0;
|
int checkSum = 0;
|
||||||
for (auto position = 0; position < 5; ++position)
|
for (auto position = 0; position < 5; ++position)
|
||||||
{
|
{
|
||||||
auto tablePtr = &table[position];
|
auto& tablePtr = highscore_table[position];
|
||||||
|
|
||||||
snprintf(Buffer, sizeof Buffer, "%d", position);
|
snprintf(Buffer, sizeof Buffer, "%d", position);
|
||||||
strcat(Buffer, ".Name");
|
strcat(Buffer, ".Name");
|
||||||
options::set_string(Buffer, tablePtr->Name);
|
options::set_string(Buffer, tablePtr.Name);
|
||||||
|
|
||||||
snprintf(Buffer, sizeof Buffer, "%d", position);
|
snprintf(Buffer, sizeof Buffer, "%d", position);
|
||||||
strcat(Buffer, ".Score");
|
strcat(Buffer, ".Score");
|
||||||
options::set_int(Buffer, tablePtr->Score);
|
options::set_int(Buffer, tablePtr.Score);
|
||||||
|
|
||||||
for (int i = static_cast<int>(strlen(tablePtr->Name)); --i >= 0; checkSum += tablePtr->Name[i])
|
for (int i = static_cast<int>(strlen(tablePtr.Name)); --i >= 0; checkSum += tablePtr.Name[i])
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
checkSum += tablePtr->Score;
|
checkSum += tablePtr.Score;
|
||||||
}
|
}
|
||||||
|
|
||||||
options::set_int("Verification", checkSum);
|
options::set_int("Verification", checkSum);
|
||||||
return 0;
|
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.Score = -999;
|
||||||
table->Name[0] = 0;
|
table.Name[0] = 0;
|
||||||
++table;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int high_score::get_score_position(high_score_struct* table, int score)
|
int high_score::get_score_position(int score)
|
||||||
{
|
{
|
||||||
if (score <= 0)
|
if (score <= 0)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
for (int position = 0; position < 5; position++)
|
for (int position = 0; position < 5; position++)
|
||||||
{
|
{
|
||||||
if (table[position].Score < score)
|
if (highscore_table[position].Score < score)
|
||||||
return position;
|
return position;
|
||||||
}
|
}
|
||||||
return -1;
|
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;
|
highscore_table[i] = highscore_table[i - 1];
|
||||||
int index = 5 - position;
|
|
||||||
do
|
|
||||||
{
|
|
||||||
--index;
|
|
||||||
memcpy(tablePtr, &tablePtr[-1], sizeof(high_score_struct));
|
|
||||||
--tablePtr;
|
|
||||||
}
|
|
||||||
while (index);
|
|
||||||
}
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
return position;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void high_score::show_high_score_dialog(high_score_struct* table)
|
data.Entry.Name[31] = 0;
|
||||||
|
highscore_table[data.Position] = data.Entry;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void high_score::show_high_score_dialog()
|
||||||
{
|
{
|
||||||
dlg_enter_name = 0;
|
|
||||||
dlg_score = 0;
|
|
||||||
dlg_hst = table;
|
|
||||||
ShowDialog = true;
|
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;
|
ScoreQueue.insert(ScoreQueue.begin(), score);
|
||||||
dlg_score = score;
|
|
||||||
dlg_hst = table;
|
|
||||||
dlg_enter_name = 1;
|
|
||||||
strncpy(default_name, defaultName, sizeof default_name - 1);
|
|
||||||
ShowDialog = true;
|
ShowDialog = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -143,13 +121,28 @@ void high_score::RenderHighScoreDialog()
|
|||||||
if (ShowDialog == true)
|
if (ShowDialog == true)
|
||||||
{
|
{
|
||||||
ShowDialog = false;
|
ShowDialog = false;
|
||||||
if (dlg_position == -1)
|
if (!ImGui::IsPopupOpen("High Scores"))
|
||||||
{
|
{
|
||||||
dlg_enter_name = 0;
|
dlg_enter_name = false;
|
||||||
return;
|
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;
|
bool unused_open = true;
|
||||||
if (ImGui::BeginPopupModal("High Scores", &unused_open, ImGuiWindowFlags_AlwaysAutoResize))
|
if (ImGui::BeginPopupModal("High Scores", &unused_open, ImGuiWindowFlags_AlwaysAutoResize))
|
||||||
@ -169,15 +162,15 @@ void high_score::RenderHighScoreDialog()
|
|||||||
snprintf(buf, sizeof buf, "%d", row + 1);
|
snprintf(buf, sizeof buf, "%d", row + 1);
|
||||||
ImGui::TextUnformatted(buf);
|
ImGui::TextUnformatted(buf);
|
||||||
|
|
||||||
auto currentRow = &dlg_hst[row + offset];
|
auto currentRow = &highscore_table[row + offset];
|
||||||
auto score = currentRow->Score;
|
auto score = currentRow->Score;
|
||||||
ImGui::TableNextColumn();
|
ImGui::TableNextColumn();
|
||||||
if (dlg_enter_name == 1 && dlg_position == row)
|
if (dlg_enter_name && DlgData.Position == row)
|
||||||
{
|
{
|
||||||
offset = -1;
|
offset = -1;
|
||||||
score = dlg_score;
|
score = DlgData.Entry.Score;
|
||||||
ImGui::PushItemWidth(200);
|
ImGui::PushItemWidth(200);
|
||||||
ImGui::InputText("", default_name, IM_ARRAYSIZE(default_name));
|
ImGui::InputText("", DlgData.Entry.Name, IM_ARRAYSIZE(DlgData.Entry.Name));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -195,8 +188,7 @@ void high_score::RenderHighScoreDialog()
|
|||||||
{
|
{
|
||||||
if (dlg_enter_name)
|
if (dlg_enter_name)
|
||||||
{
|
{
|
||||||
default_name[31] = 0;
|
place_new_score_into(DlgData);
|
||||||
place_new_score_into(dlg_hst, dlg_score, default_name, dlg_position);
|
|
||||||
}
|
}
|
||||||
ImGui::CloseCurrentPopup();
|
ImGui::CloseCurrentPopup();
|
||||||
}
|
}
|
||||||
@ -213,7 +205,7 @@ void high_score::RenderHighScoreDialog()
|
|||||||
ImGui::TextUnformatted(pinball::get_rc_string(40, 0));
|
ImGui::TextUnformatted(pinball::get_rc_string(40, 0));
|
||||||
if (ImGui::Button("OK", ImVec2(120, 0)))
|
if (ImGui::Button("OK", ImVec2(120, 0)))
|
||||||
{
|
{
|
||||||
clear_table(dlg_hst);
|
clear_table();
|
||||||
ImGui::CloseCurrentPopup();
|
ImGui::CloseCurrentPopup();
|
||||||
}
|
}
|
||||||
ImGui::SetItemDefaultFocus();
|
ImGui::SetItemDefaultFocus();
|
||||||
@ -226,5 +218,11 @@ void high_score::RenderHighScoreDialog()
|
|||||||
}
|
}
|
||||||
|
|
||||||
ImGui::EndPopup();
|
ImGui::EndPopup();
|
||||||
|
|
||||||
|
// Reenter dialog for the next score in the queue
|
||||||
|
if (!ImGui::IsPopupOpen("High Scores") && !ScoreQueue.empty())
|
||||||
|
{
|
||||||
|
ShowDialog = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -6,24 +6,31 @@ struct high_score_struct
|
|||||||
int Score;
|
int Score;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct high_score_entry
|
||||||
|
{
|
||||||
|
high_score_struct Entry;
|
||||||
|
int Position;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
class high_score
|
class high_score
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
static int read(high_score_struct* table);
|
static high_score_struct highscore_table[5];
|
||||||
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 void show_high_score_dialog(high_score_struct* table);
|
static int read();
|
||||||
static void show_and_set_high_score_dialog(high_score_struct* table, int score, int pos, LPCSTR defaultName);
|
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();
|
static void RenderHighScoreDialog();
|
||||||
private:
|
private:
|
||||||
static int dlg_enter_name;
|
static bool dlg_enter_name;
|
||||||
static int dlg_score;
|
static high_score_entry DlgData;
|
||||||
static int dlg_position;
|
|
||||||
static char default_name[32];
|
|
||||||
static high_score_struct* dlg_hst;
|
|
||||||
static bool ShowDialog;
|
static bool ShowDialog;
|
||||||
|
static std::vector<high_score_entry> ScoreQueue;
|
||||||
|
|
||||||
|
static void clear_table();
|
||||||
|
static void place_new_score_into(high_score_entry data);
|
||||||
};
|
};
|
||||||
|
@ -32,7 +32,6 @@ DatFile* pb::record_table = nullptr;
|
|||||||
int pb::time_ticks = 0;
|
int pb::time_ticks = 0;
|
||||||
GameModes pb::game_mode = GameModes::GameOver;
|
GameModes pb::game_mode = GameModes::GameOver;
|
||||||
float pb::time_now = 0, pb::time_next = 0, pb::ball_speed_limit, pb::time_ticks_remainder = 0;
|
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;
|
bool pb::FullTiltMode = false, pb::FullTiltDemoMode = false, pb::cheat_mode = false, pb::demo_mode = false;
|
||||||
std::string pb::DatFileName;
|
std::string pb::DatFileName;
|
||||||
|
|
||||||
@ -98,7 +97,7 @@ int pb::init()
|
|||||||
|
|
||||||
MainTable = new TPinballTable();
|
MainTable = new TPinballTable();
|
||||||
|
|
||||||
high_score::read(highscore_table);
|
high_score::read();
|
||||||
ball_speed_limit = MainTable->BallList.at(0)->Offset * 200.0f;
|
ball_speed_limit = MainTable->BallList.at(0)->Offset * 200.0f;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -108,7 +107,7 @@ int pb::uninit()
|
|||||||
score::unload_msg_font();
|
score::unload_msg_font();
|
||||||
loader::unload();
|
loader::unload();
|
||||||
delete record_table;
|
delete record_table;
|
||||||
high_score::write(highscore_table);
|
high_score::write();
|
||||||
delete MainTable;
|
delete MainTable;
|
||||||
MainTable = nullptr;
|
MainTable = nullptr;
|
||||||
timer::uninit();
|
timer::uninit();
|
||||||
@ -496,10 +495,12 @@ void pb::InputDown(GameInput input)
|
|||||||
ball->Acceleration.X = 0.0;
|
ball->Acceleration.X = 0.0;
|
||||||
break;
|
break;
|
||||||
case 'h':
|
case 'h':
|
||||||
char String1[200];
|
{
|
||||||
strncpy(String1, pinball::get_rc_string(26, 0), sizeof String1 - 1);
|
high_score_struct entry{ {0}, 1000000000 };
|
||||||
high_score::show_and_set_high_score_dialog(highscore_table, 1000000000, 1, String1);
|
strncpy(entry.Name, pinball::get_rc_string(26, 0), sizeof entry.Name - 1);
|
||||||
|
high_score::show_and_set_high_score_dialog({ entry, 1 });
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
case 'r':
|
case 'r':
|
||||||
control::cheat_bump_rank();
|
control::cheat_bump_rank();
|
||||||
break;
|
break;
|
||||||
@ -522,7 +523,6 @@ void pb::end_game()
|
|||||||
{
|
{
|
||||||
int scores[4]{};
|
int scores[4]{};
|
||||||
int scoreIndex[4]{};
|
int scoreIndex[4]{};
|
||||||
char String1[200];
|
|
||||||
|
|
||||||
mode_change(GameModes::GameOver);
|
mode_change(GameModes::GameOver);
|
||||||
int playerCount = MainTable->PlayerCount;
|
int playerCount = MainTable->PlayerCount;
|
||||||
@ -556,11 +556,12 @@ void pb::end_game()
|
|||||||
{
|
{
|
||||||
for (auto i = 0; i < playerCount; ++i)
|
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)
|
if (position >= 0)
|
||||||
{
|
{
|
||||||
strncpy(String1, pinball::get_rc_string(scoreIndex[i] + 26, 0), sizeof String1 - 1);
|
high_score_struct entry{ {0}, scores[i] };
|
||||||
high_score::show_and_set_high_score_dialog(highscore_table, scores[i], position, String1);
|
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()
|
void pb::high_scores()
|
||||||
{
|
{
|
||||||
high_score::show_high_score_dialog(highscore_table);
|
high_score::show_high_score_dialog();
|
||||||
}
|
}
|
||||||
|
|
||||||
void pb::tilt_no_more()
|
void pb::tilt_no_more()
|
||||||
@ -583,18 +584,13 @@ bool pb::chk_highscore()
|
|||||||
{
|
{
|
||||||
if (demo_mode)
|
if (demo_mode)
|
||||||
return false;
|
return false;
|
||||||
int playerIndex = MainTable->PlayerCount - 1;
|
for (auto i = 0; i < MainTable->PlayerCount; ++i)
|
||||||
if (playerIndex < 0)
|
|
||||||
return false;
|
|
||||||
for (int i = playerIndex;
|
|
||||||
high_score::get_score_position(highscore_table, MainTable->PlayerScores[i].ScoreStruct->Score) < 0;
|
|
||||||
--i)
|
|
||||||
{
|
{
|
||||||
if (--playerIndex < 0)
|
if (high_score::get_score_position(MainTable->PlayerScores[i].ScoreStruct->Score) >= 0)
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
float pb::collide(float timeNow, float timeDelta, TBall* ball)
|
float pb::collide(float timeNow, float timeDelta, TBall* ball)
|
||||||
{
|
{
|
||||||
|
@ -45,7 +45,6 @@ public:
|
|||||||
static bool cheat_mode;
|
static bool cheat_mode;
|
||||||
static DatFile* record_table;
|
static DatFile* record_table;
|
||||||
static TPinballTable* MainTable;
|
static TPinballTable* MainTable;
|
||||||
static high_score_struct highscore_table[5];
|
|
||||||
static bool FullTiltMode, FullTiltDemoMode;
|
static bool FullTiltMode, FullTiltDemoMode;
|
||||||
static std::string DatFileName;
|
static std::string DatFileName;
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user