#include "HighScoreManager.hxx" #include #include #include #include #include namespace fs = std::filesystem; HighScoreManager::HighScoreManager() { data_dir_ = SDL_GetPrefPath("draconic-bytes", "snake"); fs::create_directories(data_dir_); load(); } void HighScoreManager::load() { auto const filename = fs::path{data_dir_}/"highscore.dat"; std::ifstream input{filename, std::ios::binary}; if (!input) { SDL_LogWarn(SDL_LOG_CATEGORY_APPLICATION, "Missing high score file: %s", filename.c_str()); return; } std::size_t count; input.read(std::bit_cast(&count), sizeof(std::size_t)); high_score_.scores_.resize(count); for (std::size_t n = 0; n(&len), sizeof(std::size_t)); high_score_.scores_[n].player_name_.resize(len); input.read(high_score_.scores_[n].player_name_.data(), static_cast(len)); input.read(std::bit_cast(&(high_score_.scores_[n].points_)), sizeof(unsigned)); } std::ranges::stable_sort(high_score_.scores_, std::greater<>{}, &Score::points_); if (high_score_.scores_.empty()) { SDL_Log("No existing high scores."); } else { SDL_Log("Loaded high scores:"); for (auto const& score: high_score_.scores_) { SDL_Log(" - %s: %u", score.player_name_.c_str(), score.points_); } } } void HighScoreManager::save() const { auto const filename = fs::path{data_dir_}/"highscore.dat"; std::ofstream output{filename, std::ios::binary}; if (!output) { SDL_LogError(SDL_LOG_CATEGORY_ERROR, "Failed saving high scores to file %s", filename.c_str()); return; } auto const count = high_score_.scores_.size(); output.write(std::bit_cast(&count), sizeof(std::size_t)); for (auto const& score: high_score_.scores_) { auto const len = score.player_name_.length(); output.write(std::bit_cast(&len), sizeof(std::size_t)); output.write(score.player_name_.data(), static_cast(score.player_name_.length())); output.write(std::bit_cast(&score.points_), sizeof(unsigned)); } if (high_score_.scores_.empty()) { SDL_Log("No high scores saved."); } else { SDL_Log("Saved high scores:"); for (auto const& score: high_score_.scores_) { SDL_Log(" - %s: %u", score.player_name_.c_str(), score.points_); } } } void HighScoreManager::set_new_score(unsigned int score) { if (high_score_.scores_.size(){}, &Score::points_); if (high_score_.scores_.size()>MAX_SCORES) { high_score_.scores_.resize(MAX_SCORES); } save(); } } HighScoreManager& HighScoreManager::instance() { static HighScoreManager manager; return manager; } std::vector const& HighScoreManager::get_scores() const { return high_score_.scores_; }