// $Id: highscoresdisplay.cc,v 1.7 2006/08/23 22:43:17 matthew Exp $ // Fish Supper // Copyright (C) 2006 Matthew Clarke // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License // as published by the Free Software Foundation; either version 2 // of the License, or (at your option) any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA // 02111-1307, USA. #include "highscoresdisplay.h" #include "fontrepository.h" extern char * fs_dir; extern FS::FontRepository * font_rep; // ******************* // *** CONSTRUCTOR *** // ******************* FS::HighScoresDisplay::HighScoresDisplay() : my_font(font_rep->get_SFont(FontRepository::LARGE_FONT)), my_font_faint(font_rep->get_SFont(FontRepository::LARGE_FONT_FAINT)) { read_high_scores(); background = SDL_DisplayFormat(IMG_Load( PKG_DATA_DIR "/images/highscores/cats_whiskers.png" )); font_height = my_font.getHeight(); } // FS::HighScoresDisplay::HighScoresDisplay() // ****************** // *** DESTRUCTOR *** // ****************** FS::HighScoresDisplay::~HighScoresDisplay() { SDL_FreeSurface(background); } // FS::HighScoresDisplay::~HighScoresDisplay() // ************************ // *** MEMBER FUNCTIONS *** // ************************ // ************************************************** void FS::HighScoresDisplay::print_table() { std::list::iterator my_iter; my_iter = my_entries.begin(); do { std::cout << my_iter->name << " ... " << my_iter->score << "\n"; ++my_iter; } while (my_iter != my_entries.end()); } // FS::HighScoresDisplay::print_table() // ************************************************** bool FS::HighScoresDisplay::check_candidate(int sc) { std::list::iterator my_iter; my_iter = my_entries.begin(); // this doesn't like method to be const do { if (sc > my_iter->score) { return true; } // if ++my_iter; } while (my_iter != my_entries.end()); return false; } // FS::HighScoresDisplay::check_candidate() // ************************************************** void FS::HighScoresDisplay::add_entry(const char * nm, int sc) { HighScoreEntry hse; strncpy(hse.name, nm, NAME_MAX_LEN); hse.name[NAME_MAX_LEN] = '\0'; hse.score = sc; std::list::iterator my_iter; my_iter = my_entries.begin(); // FIXME - we're assuming function is being used correctly // (i.e. after a call to check_candidate() has returned true). do { if (sc > my_iter->score) { break; } // if ++my_iter; } while (my_iter != my_entries.end()); new_entry = my_entries.insert(my_iter, hse); my_entries.pop_back(); } // FS::HighScoresDisplay::add_entry() // ************************************************** void FS::HighScoresDisplay::read_high_scores() { // load table and populate my_entries list std::string my_file = fs_dir; my_file += "/table.txt"; std::ifstream fin( my_file.c_str() ); if ( !fin.is_open() ) { std::cerr << "Can't open " << my_file << " for reading. Using defaults.\n"; populate_default_table(); return; } // if std::string my_line; std::string temp_name; int temp_score; int split_index; HighScoreEntry temp_entry; my_entries.clear(); // ?! for (int i = 0; i < NUM_ENTRIES; ++i) { getline(fin, my_line); split_index = my_line.find('='); temp_name = my_line.substr(0, split_index); temp_score = atoi( (my_line.substr(split_index + 1)).c_str() ); strncpy(temp_entry.name, temp_name.c_str(), NAME_MAX_LEN); temp_entry.name[NAME_MAX_LEN] = '\0'; temp_entry.score = temp_score; my_entries.push_back(temp_entry); } // for fin.close(); } // FS::HighScoresDisplay::read_high_scores() // ************************************************** void FS::HighScoresDisplay::write_high_scores() { std::string my_file = fs_dir; my_file += "/table.txt"; std::ofstream fout( my_file.c_str() ); if ( !fout.is_open() ) { std::cerr << "Can't open " << my_file << " for writing. " << "Unable to save high scores.\n"; return; } // if std::list::iterator my_iter; my_iter = my_entries.begin(); do { fout << my_iter->name << "=" << my_iter->score << std::endl; ++my_iter; } while (my_iter != my_entries.end()); fout.close(); } // FS::HighScoresDisplay::write_high_scores() // ************************************************** void FS::HighScoresDisplay::show_high_scores(SDL_Surface * screen) { SDL_BlitSurface(background, NULL, screen, NULL); std::list::iterator my_iter; my_iter = my_entries.begin(); int y = TOP_Y; char score_text[7]; do { my_font.write(screen, my_iter->name, NAME_X, y); sprintf(score_text, "%06d", my_iter->score); my_font.write(screen, score_text, SCORE_X, y); ++my_iter; y += Y_GAP; } while (my_iter != my_entries.end()); SDL_UpdateRect(screen, 0, 0, 0, 0); } // FS::HighScoresDisplay::show_high_scores() // ************************************************** void FS::HighScoresDisplay::init_input(int score, SDL_Surface * screen) { add_entry("anon", score); new_entry_name.clear(); SDL_BlitSurface(background, NULL, screen, NULL); std::list::iterator my_iter; my_iter = my_entries.begin(); int y = TOP_Y; char score_text[7]; do { sprintf(score_text, "%06d", my_iter->score); if (my_iter == new_entry) { new_entry_y = y; my_font.write(screen, score_text, SCORE_X, y); } else { my_font_faint.write(screen, my_iter->name, NAME_X, y); my_font_faint.write(screen, score_text, SCORE_X, y); } // if ... else ++my_iter; y += Y_GAP; } while (my_iter != my_entries.end()); // only erase_rect.w ever changes... dest_rect.x = NAME_X; dest_rect.y = new_entry_y; erase_rect.x = NAME_X; erase_rect.y = new_entry_y; erase_rect.h = font_height; SDL_UpdateRect(screen, 0, 0, 0, 0); } // FS::HighScoresDisplay::init_input() // ************************************************** bool FS::HighScoresDisplay::input(SDL_keysym * keys_down, int n, SDL_Surface * screen) { int i = 0; bool must_redraw = false; bool must_erase = false; SDLKey my_key; while (i < n) { my_key = keys_down[i].sym; if ( (my_key >= SDLK_a) && (my_key <= SDLK_z) ) { // a letter was typed... is there still room? if ( new_entry_name.length() < ((unsigned int) NAME_MAX_LEN) ) { if ( keys_down[i].mod & KMOD_SHIFT ) { new_entry_name += toupper((char) my_key); } else { new_entry_name += ((char) my_key); } // if ... else must_redraw = true; } else { // beep! } // if ... else } else if ( my_key == SDLK_BACKSPACE ) { if ( new_entry_name.length() > 0 ) { erase_rect.w = my_font.getTextWidth(new_entry_name.c_str()); new_entry_name.erase(--new_entry_name.end()); must_erase = true; must_redraw = true; } else { // beep! } // if ... else } else if ( my_key == SDLK_RETURN ) { // if string is empty, we'll stick with default name (= "anon") // otherwise copy new name if ( !new_entry_name.empty() ) { // there will always be enough room because of NAME_MAX_LEN limit strcpy(new_entry->name, new_entry_name.c_str()); } // if return true; } // if ... else ++i; } // while if (must_erase) { // FIXME: should erase max width SDL_BlitSurface(background, &erase_rect, screen, &dest_rect); my_font.write(screen, new_entry_name.c_str(), NAME_X, new_entry_y); SDL_UpdateRect(screen, NAME_X, new_entry_y, erase_rect.w, erase_rect.h); } else if (must_redraw) { my_font.write(screen, new_entry_name.c_str(), NAME_X, new_entry_y); SDL_UpdateRect(screen, NAME_X, new_entry_y, my_font.getTextWidth(new_entry_name.c_str()), font_height); } // if ... else return false; } // FS::HighScoresDisplay::input() // ************************************************** void FS::HighScoresDisplay::populate_default_table() { HighScoreEntry temp_entry; char * names[] = { "Bertie", "Agatha", "Oofy", "Madelaine", "Spode" }; int scores[] = { 4000, 3000, 2000, 1000, 500 }; my_entries.clear(); // ?! for (int i = 0; i < NUM_ENTRIES; ++i) { strncpy(temp_entry.name, names[i], NAME_MAX_LEN); temp_entry.name[NAME_MAX_LEN] = '\0'; temp_entry.score = scores[i]; my_entries.push_back(temp_entry); } // for } // FS::HighScoresDisplay::populate_default_table() // ************************************************** // **************************************************