X-Git-Url: https://harrygodden.com/git/?a=blobdiff_plain;f=highscores.h;h=0c4ae54131fe58546f0a2798652a56d05af5d636;hb=6e6c7f31b8f17af3814727109e48fc6f85ef04b1;hp=28662bfa0a403c2b15f9fa1f56525ab828a71881;hpb=5e22cdfe9f6f83e807ce6456ab538d02104cd01d;p=carveJwlIkooP6JGAAIwe30JlM.git diff --git a/highscores.h b/highscores.h index 28662bf..0c4ae54 100644 --- a/highscores.h +++ b/highscores.h @@ -25,7 +25,7 @@ typedef struct highscore_playerinfo highscore_playerinfo; struct highscore_playerinfo { - char nickname[10]; + char nickname[16]; u64 playerid; union @@ -91,546 +91,22 @@ static struct highscore_system aainfo_playerinfo_playerid, aainfo_playerinfo; - void *data, *playerinfo_data; -} -highscore_system; - -static int highscore_cmp_points( void *a, void *b ) -{ - highscore_record *pa = a, *pb = b; - return (int)pa->points - (int)pb->points; -} - -static int highscore_cmp_datetime( void *a, void *b ) -{ - highscore_record *pa = a, *pb = b; - - if( pa->datetime == pb->datetime ) return 0; - return pa->datetime < pb->datetime? 1: -1; -} - -static int highscore_cmp_time( void *a, void *b ) -{ - highscore_record *pa = a, *pb = b; - return (int)pb->time - (int)pa->time; -} - -static int highscore_cmp_playerid( void *a, void *b ) -{ - highscore_record *pa = a, *pb = b; - if( pa->playerid == pb->playerid ) return 0; - return pa->playerid < pb->playerid? -1: 1; -} - -static int highscore_cmp_playerinfo_playerid( void *a, void *b ) -{ - highscore_playerinfo *pa = a, *pb = b; - if( pa->playerid == pb->playerid ) return 0; - return pa->playerid < pb->playerid? -1: 1; -} - -static void *highscore_malloc( u32 count, u32 size ) -{ - size_t requested_mem = size * count; - void *data = vg_alloc( requested_mem ); - - requested_mem /= 1024; - requested_mem /= 1024; - - if( !data ) - { - vg_error( "Could not allocated %dmb of memory\n", requested_mem ); - return NULL; - } - else - vg_success( "Allocated %dmb for %u records\n", requested_mem, count ); + void *data, + *playerinfo_data; - return data; + u32 pool_size, playerinfo_pool_size; } +highscore_system; -static void highscores_free(void) -{ - vg_free( highscore_system.data ); - vg_free( highscore_system.playerinfo_data ); -} - -static int highscores_init( u32 pool_size, u32 playerinfo_pool_size ) -{ - struct highscore_system *sys = &highscore_system; - - sys->data = highscore_malloc( pool_size, sizeof(highscore_record) ); - if( !sys->data ) return 0; - - sys->playerinfo_data = - highscore_malloc( playerinfo_pool_size, sizeof(highscore_playerinfo)); - if( !sys->playerinfo_data ) - { - vg_free( sys->data ); - return 0; - } - - /* This is ugly.. too bad! */ - sys->aainfo.base = highscore_system.data; - sys->aainfo.stride = sizeof(highscore_record); - sys->aainfo.offset = offsetof(highscore_record,pool); - sys->aainfo.p_cmp = NULL; - - sys->aainfo_datetime.base = highscore_system.data; - sys->aainfo_datetime.stride = sizeof(highscore_record); - sys->aainfo_datetime.offset = offsetof(highscore_record,aa.datetime); - sys->aainfo_datetime.p_cmp = highscore_cmp_datetime; - - sys->aainfo_points.base = highscore_system.data; - sys->aainfo_points.stride = sizeof(highscore_record); - sys->aainfo_points.offset = offsetof(highscore_record,aa.points); - sys->aainfo_points.p_cmp = highscore_cmp_points; - - sys->aainfo_time.base = highscore_system.data; - sys->aainfo_time.stride = sizeof(highscore_record); - sys->aainfo_time.offset = offsetof(highscore_record,aa.time); - sys->aainfo_time.p_cmp = highscore_cmp_time; - - sys->aainfo_playerid.base = highscore_system.data; - sys->aainfo_playerid.stride = sizeof(highscore_record); - sys->aainfo_playerid.offset = offsetof(highscore_record,aa.playerid); - sys->aainfo_playerid.p_cmp = highscore_cmp_playerid; - - sys->aainfo_playerinfo_playerid.base = highscore_system.playerinfo_data; - sys->aainfo_playerinfo_playerid.stride = sizeof(highscore_playerinfo); - sys->aainfo_playerinfo_playerid.offset = - offsetof(highscore_playerinfo,aa_playerid); - sys->aainfo_playerinfo_playerid.p_cmp = highscore_cmp_playerinfo_playerid; - - sys->aainfo_playerinfo.base = highscore_system.playerinfo_data; - sys->aainfo_playerinfo.stride = sizeof(highscore_playerinfo); - sys->aainfo_playerinfo.offset = offsetof(highscore_playerinfo,aapn); - sys->aainfo_playerinfo.p_cmp = NULL; - - FILE *fp = fopen( ".aadb", "rb" ); - if( fp ) - { - vg_info( "Loading existing database\n" ); - - u64 count = fread( &sys->dbheader, sizeof(highscore_database), 1, fp ); - - if( count != 1 ) - { - vg_error( "Unexpected EOF reading database header\n" ); - - highscores_free(); - return 0; - } - - count = fread( sys->data, sizeof(highscore_record), pool_size, fp ); - if( count != pool_size ) - { - vg_error( "Unexpected EOF reading database contents;" - " %lu records of %u were read\n", count, pool_size ); - - highscores_free(); - return 0; - } - - count = fread( sys->playerinfo_data, sizeof(highscore_playerinfo), - playerinfo_pool_size, fp ); - if( count != playerinfo_pool_size ) - { - vg_error( "Unexpected EOF reading playerinfo contents;" - " %lu records of %u were read\n", count, - playerinfo_pool_size ); - - highscores_free(); - return 0; - } - - fclose( fp ); - } - else - { - vg_low( "No existing database found (.aadb)\n" ); - vg_info( "Initializing database nodes\n" ); - memset( &sys->dbheader, 0, sizeof(highscore_database) ); - - sys->dbheader.pool_head = aatree_init_pool( &sys->aainfo, pool_size ); - sys->dbheader.entry_capacity = pool_size; - - for( int i=0; idbheader.tracks); i++ ) - { - highscore_track_table *table = &sys->dbheader.tracks[i]; - table->root_points = AATREE_PTR_NIL; - table->root_playerid = AATREE_PTR_NIL; - table->root_time = AATREE_PTR_NIL; - table->root_datetime = AATREE_PTR_NIL; - } - - /* Initialize secondary db */ - sys->dbheader.playerinfo_head = aatree_init_pool( - &sys->aainfo_playerinfo, - playerinfo_pool_size ); - sys->dbheader.playerinfo_capacity = playerinfo_pool_size; - sys->dbheader.playerinfo_root = AATREE_PTR_NIL; - } - - return 1; -} - -static int highscores_serialize_all(void) -{ - struct highscore_system *sys = &highscore_system; - vg_info( "Serializing database\n" ); - - FILE *fp = fopen( ".aadb", "wb" ); - - if( !fp ) - { - vg_error( "Could not open .aadb\n" ); - return 0; - } - - fwrite( &sys->dbheader, sizeof(highscore_database), 1, fp ); - fwrite( sys->data, sizeof(highscore_record), - sys->dbheader.entry_capacity, fp ); - fwrite( sys->playerinfo_data, sizeof(highscore_playerinfo), - sys->dbheader.playerinfo_capacity, fp ); - - fclose( fp ); - return 1; -} - -static highscore_record *highscore_find_user_record( u64 playerid, u32 trackid ) -{ - struct highscore_system *sys = &highscore_system; - - highscore_track_table *table = &sys->dbheader.tracks[trackid]; - highscore_record temp; - temp.playerid = playerid; - - aatree_ptr find = - aatree_find( &sys->aainfo_playerid, table->root_playerid, &temp ); - - if( find == AATREE_PTR_NIL ) - return NULL; - - return aatree_get_data( &sys->aainfo_playerid, find ); -} - -static aatree_ptr highscores_push_record( highscore_record *record ) -{ - struct highscore_system *sys = &highscore_system; - - vg_low( "Inserting record into database for track %hu\n",record->trackid ); - - if( record->trackid >= vg_list_size(sys->dbheader.tracks) ) - { - vg_error( "TrackID out of range (%hu>=%d)\n", record->trackid, - vg_list_size(sys->dbheader.tracks) ); - - return AATREE_PTR_NIL; - } - - /* Search for existing record on this track */ - highscore_track_table *table = &sys->dbheader.tracks[record->trackid]; - aatree_ptr existing = aatree_find( &sys->aainfo_playerid, - table->root_playerid, - record ); - - if( existing != AATREE_PTR_NIL ) - { - highscore_record *crecord = aatree_get_data( &sys->aainfo_playerid, - existing ); - - if( crecord->time < record->time || - (crecord->time == record->time && crecord->points > record->points)) - { - vg_low( "Not overwriting better score\n" ); - return existing; - } - - vg_low( "Freeing existing record for player %lu\n", record->playerid ); - table->root_playerid = aatree_del( &sys->aainfo_playerid, existing ); - table->root_datetime = aatree_del( &sys->aainfo_datetime, existing ); - table->root_points = aatree_del( &sys->aainfo_points, existing ); - table->root_time = aatree_del( &sys->aainfo_time, existing ); - - aatree_pool_free( &sys->aainfo, existing, &sys->dbheader.pool_head ); - } - - aatree_ptr index = - aatree_pool_alloc( &sys->aainfo, &sys->dbheader.pool_head ); - - if( index == AATREE_PTR_NIL ) - { - vg_error( "Database records are over capacity!\n" ); - return index; - } - - highscore_record *dst = aatree_get_data( &sys->aainfo, index ); - memset( dst, 0, sizeof(highscore_record) ); - - dst->trackid = record->trackid; - dst->datetime = record->datetime; - dst->playerid = record->playerid; - dst->points = record->points; - dst->time = record->time; - - table->root_time = - aatree_insert( &sys->aainfo_time, table->root_time, index ); - table->root_datetime = - aatree_insert( &sys->aainfo_datetime, table->root_datetime, index ); - table->root_playerid = - aatree_insert( &sys->aainfo_playerid, table->root_playerid, index ); - table->root_points = - aatree_insert( &sys->aainfo_points, table->root_points, index ); - - return index; -} - -static aatree_ptr highscore_set_user_nickname( u64 steamid, char nick[10] ) -{ - char name[11]; - for( int i=0; i<10; i++ ) - name[i] = nick[i]; - name[10] = '\0'; - - vg_low( "Updating %lu's nickname -> %s\n", steamid, name ); - - struct highscore_system *sys = &highscore_system; - - highscore_playerinfo temp; - temp.playerid = steamid; - - aatree_ptr record = aatree_find( &sys->aainfo_playerinfo_playerid, - sys->dbheader.playerinfo_root, - &temp ); - highscore_playerinfo *info; - - if( record != AATREE_PTR_NIL ) - { - info = aatree_get_data( &sys->aainfo_playerinfo, record ); - } - else - { - record = aatree_pool_alloc( &sys->aainfo_playerinfo, - &sys->dbheader.playerinfo_head ); - - if( record == AATREE_PTR_NIL ) - { - vg_error( "Player info database is over capacity!\n" ); - return AATREE_PTR_NIL; - } - - info = aatree_get_data( &sys->aainfo_playerinfo, record ); - memset( info, 0, sizeof(highscore_playerinfo) ); - - info->playerid = steamid; - sys->dbheader.playerinfo_root = aatree_insert( - &sys->aainfo_playerinfo_playerid, - sys->dbheader.playerinfo_root, - record ); - } - - for( int i=0; i<10; i++ ) - info->nickname[i] = nick[i]; - - return AATREE_PTR_NIL; -} - -/* Get the length of a string, bounded by '\0' or len, whichever is first */ -static int highscore_strlen( const char *str, int len ) -{ - int str_length; - for( str_length=0; str_length= width ) - return; - - buf[j] = str[i]; - } -} - -/* Print the string(max length:len) left aligned into buf */ -static void highscore_strl( char *buf, const char *str, int len ) -{ - for( int i=0; i=len ) - return; - - buf[ len-1 - (i ++) ] = '0' + (value % 10); - value /= 10; - } - - for( ;i=len ) - break; - - temp[ i ++ ] = '0' + (value % 10); - value /= 10; - } - - if( i>len ) - i = len; - - for( int j=0; jdbheader.tracks[ id ]; - aatree_ptr it = aatree_kth( &sys->aainfo_time, table->root_time, 0 ); - - highscore_strc ( buf+w*0, inf->name, w,w ); - highscore_clear( buf+w*1, '-', w ); - highscore_strl ( buf+w*2, " #| Player | Time ", 27 ); - - for( int i=0; iaainfo_time, it ); - highscore_playerinfo temp; - temp.playerid = record->playerid; - - aatree_ptr info_ptr = aatree_find( &sys->aainfo_playerinfo_playerid, - sys->dbheader.playerinfo_root, - &temp ); - - /* Player name */ - if( info_ptr == AATREE_PTR_NIL ) - highscore_strl( line+3, "unknown", 16 ); - else - { - highscore_playerinfo *inf = aatree_get_data( - &sys->aainfo_playerinfo_playerid, info_ptr ); - - highscore_strl( line+3, inf->nickname, 16 ); - } - - u16 centiseconds = record->time, - seconds = centiseconds / 100, - minutes = seconds / 60; - - centiseconds %= 100; - seconds %= 60; - minutes %= 60; - - if( minutes > 9 ) minutes = 9; - - /* Timer */ - highscore_intr( line+20, minutes, 1, '0' ); - line[21] = ':'; - highscore_intr( line+22, seconds, 2, '0' ); - line[24] = '.'; - highscore_intr( line+25, centiseconds, 2, '0' ); - -#if 0 - /* Score */ - highscore_intl( line+22, record->points, 5 ); -#endif - it = aatree_next( &sys->aainfo_time, it ); - } -} - -/* Print string out to file using newlines. Count is number of records - * ( this requires a buffer of (count+3)*27 size */ -static void highscores_board_printf( FILE *fp, const char *buf, u32 count ) -{ - int w=27; - - for( int i=0; i