- 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 = malloc( 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 );
-
- return data;
-}
-
-static void highscores_free(void)
-{
- free( highscore_system.data );
- 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 )
- {
- 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_log( "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; i<vg_list_size(sys->dbheader.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;
- }