/* ------------------------------------------------------------ Kobo Deluxe - An enhanced SDL port of XKobo ------------------------------------------------------------ * Copyright (C) 1995, 1996 Akira Higuchi * Copyright (C) 2001, 2002 David Olofson * Copyright (C) 2002 Jeremy Sheeley * Copyright (C) 2007 David Olofson * * 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., * 675 Mass Ave, Cambridge, MA 02139, USA. */ #ifndef _KOBO_SCORE_H_ #define _KOBO_SCORE_H_ #include "config.h" #include "game.h" #include "pfile.h" #define MAX_PROFILES 100 #define MAX_HIGHSCORES 100 #define HISCORE_SAVE_MAX 100 #define PROFILE_VERSION 1 //DO NOT CHANGE! (Will break the file format.) #define SCORE_NAME_LEN 64 /*---------------------------------------------------------- s_*_t - Profile and score data wrappers ----------------------------------------------------------*/ // File format: // * The first 74 bytes are identical to those in old // XKobo score files, for compatibility reasons. // // * New sections are added in the form of RIFF style // chunks, starting at offset 74 in the file. (See // pfile.(h|cpp) for details.) // // * Chunks of unknown types are IGNORED, and are // therefore LOST if the file is overwritten by an // older version of Kobo Deluxe. // // * Extra data beyond the end of a chunk (ie data that // is added by a later version of Kobo Deluxe) is // IGNORED, and is therefore LOST if the file is // overwritten by an older version of Kobo Deluxe. // // * New versions may ADD data to chunks, but never // remove data from chunks. // // * New versions may add new chunk types. // // * New versions may remove old chunk types, although // this is STRONGLY DISCOURAGED, as it may render // old Kobo Deluxe versions seeing a vertually empty // profile file... // // * Strings are stored as fixed length, null padded // arrays of 64 bytes. All strings should have at // least one terminating null byte. // // * Signed and unsigned int are stored as little // endian 32 bit integers. // // Version 1 chunks: // // PROF: //Player profile header // Sint32 version; // Sint32 skill; // Sint32 handicap; // Sint32 color1; // Sint32 color2; // // HISC: //Hiscore entry // Uint32 start_date; // Uint32 end_date; // Sint32 skill; // Uint32 score; // Sint32 start_scene; // Sint32 end_scene; // Sint32 end_lives; // Sint32 end_health; // Uint32 playtime; // Sint32 saves; // Sint32 loads; // Sint32 gametype; // struct s_profile_t; // Stored as one "HISC" chunk for each entry. // No "real" maximum number of entries per profile, // but the current implementation uses an array of // HISCORE_SAVE_MAX entries. // FIXME: Should be dynamic, although there should // FIXME: probably be some sensible limit regardless. struct s_hiscore_t { // For all of the below, -1 (signed) or 0 (unsigned) means "unknown". unsigned int start_date; //Seconds since 2000...? unsigned int end_date; //Seconds since 2000...? int skill; //Skill setting used int gametype; //Single/cooperative/deathmatch/... unsigned int score; //Score achieved int start_scene; //Scene player started on int end_scene; //Scene player quit or died on int end_lives; //# of lives when player quit int end_health; //Health when player quit unsigned int playtime; //Effective play time, logic frames int saves; //# of times game was saved int loads; //# of times game was aborted + loaded // The fields below this line are not saved to file. s_profile_t *profile; //Profile this entry belongs to, //if any. (May be NULL!) char name[SCORE_NAME_LEN]; //(Kludge for highscore table.) s_hiscore_t(); void clear(); //Reset and clear all fields. void read(pfile_t &f); //Read this struct from pfile 'f'. void write(pfile_t &f); //Write this struct to pfile 'f'. }; // Stored as one "PROF" chunk. struct s_profile_t { //Old stuff (from XKobo) unsigned int best_score; //Best score int last_scene; //Last scene completed char name[SCORE_NAME_LEN]; //Player name //New stuff (for Kobo Deluxe 0.4) unsigned int version; //Profile file format version int skill; //Player skill setting int handicap; //Player handicap. 0 == none. int color1; //Primary color. (-1 == default) int color2; //Secondary color. (-1 == default) s_hiscore_t hiscoretab[HISCORE_SAVE_MAX]; // The fields below this line are not saved to file. unsigned int hiscores; //# of hiscores stored char *filename; s_profile_t(); ~s_profile_t(); void clear(); //Reset and clear all fields. int load(const char *fn); //Load from file 'fn'. int save(); //Save back to file. s_hiscore_t *best_hiscore(); }; /*---------------------------------------------------------- score_manager_t ----------------------------------------------------------*/ class score_manager_t { s_profile_t profiles[MAX_PROFILES]; unsigned int currentProfile; public: unsigned int highs; s_hiscore_t high_tbl[MAX_HIGHSCORES]; int numProfiles; score_manager_t(); ~score_manager_t(); int addPlayer(const char *name); void init(); s_profile_t *profile(int prof = -1) { if(prof < 0) return profiles + currentProfile; else return profiles + prof; } // NOTE: hiscore() with no argument (or -2) returns // the best known score of all found profiles; NOT // that of the current profile. int highscore(int prof = -2); int last_scene(int prof = -1) { if(prof < 0) return profiles[currentProfile].last_scene; else return profiles[prof].last_scene; } char *name(int prof = -1) { if(prof < 0) return profiles[currentProfile].name; else return profiles[prof].name; } void select_profile(int prof); int current_profile() { return currentProfile; } void record(s_hiscore_t *entry, int force = 0); void gather_high_scores(int placeholders = 0); void print_high_scores(); }; extern score_manager_t scorefile; #endif //_KOBO_SCORE_H_