#include "manage_hiscore_table.h" #include // for SDL_GetError #include // for SDL_RWread, SDL_RWwrite, SDL_RWFromFile #include // for free, malloc #include // for sort #include // for basic_ostream, char_traits, operator<< #include "utils.h" // for HiScoreEntry // Constructor ManageHiScoreTable::ManageHiScoreTable(std::vector *table) : table_(table) {} // Resetea la tabla a los valores por defecto void ManageHiScoreTable::clear() { // Limpia la tabla table_->clear(); // Añade 10 entradas predefinidas table_->push_back({"Bry", 1000000}); table_->push_back({"Usufondo", 500000}); table_->push_back({"G.Lucas", 100000}); table_->push_back({"P.Delgat", 50000}); table_->push_back({"P.Arrabalera", 10000}); table_->push_back({"Pelechano", 5000}); table_->push_back({"Sahuquillo", 1000}); table_->push_back({"Bacteriol", 500}); table_->push_back({"Pepe", 200}); table_->push_back({"Rosita", 100}); } // Añade un elemento a la tabla void ManageHiScoreTable::add(HiScoreEntry entry) { // Añade la entrada a la tabla table_->push_back(entry); // Ordena la tabla sort(); // Deja solo las 10 primeras entradas if (static_cast(table_->size()) > 10) { table_->resize(10); } } // Ordena la tabla void ManageHiScoreTable::sort() { struct { bool operator()(const HiScoreEntry &a, const HiScoreEntry &b) const { return a.score > b.score; } } custom_less; std::sort(table_->begin(), table_->end(), custom_less); } // Carga la tabla con los datos de un fichero bool ManageHiScoreTable::loadFromFile(const std::string &file_path) { clear(); auto success = true; auto file = SDL_RWFromFile(file_path.c_str(), "r+b"); if (file) { #ifdef VERBOSE const std::string file_name = file_path.substr(file_path.find_last_of("\\/") + 1); std::cout << "Reading file: " << file_name.c_str() << std::endl; #endif for (int i = 0; i < (int)table_->size(); ++i) { int nameSize = 0; if (SDL_RWread(file, &table_->at(i).score, sizeof(int), 1) == 0) { success = false; break; } if (SDL_RWread(file, &nameSize, sizeof(int), 1) == 0) { success = false; break; } char *name = static_cast(malloc(nameSize + 1)); if (SDL_RWread(file, name, sizeof(char) * nameSize, 1) == 0) { success = false; free(name); break; } else { name[nameSize] = 0; table_->at(i).name = name; free(name); } } SDL_RWclose(file); } if (!success) { clear(); } return success; } // Guarda la tabla en un fichero bool ManageHiScoreTable::saveToFile(const std::string &file_path) { #ifdef VERBOSE const std::string file_name = file_path.substr(file_path.find_last_of("\\/") + 1); #endif auto success = true; auto file = SDL_RWFromFile(file_path.c_str(), "w+b"); if (file) { // Guarda los datos for (int i = 0; i < (int)table_->size(); ++i) { SDL_RWwrite(file, &table_->at(i).score, sizeof(int), 1); const int nameSize = (int)table_->at(i).name.size(); SDL_RWwrite(file, &nameSize, sizeof(int), 1); SDL_RWwrite(file, table_->at(i).name.c_str(), nameSize, 1); } #ifdef VERBOSE std::cout << "Writing file: " << file_name.c_str() << std::endl; #endif // Cierra el fichero SDL_RWclose(file); } else { #ifdef VERBOSE std::cout << "Error: Unable to save " << file_name.c_str() << " file! " << SDL_GetError() << std::endl; #endif } return success; }