+/*
+ * Copyright (C) 2021-2022 Mt.ZERO Software, Harry Godden - All Rights Reserved
+ */
+
#ifndef HIGHSCORES_H
#define HIGHSCORES_H
struct highscore_playerinfo
{
- char nickname[10];
+ char nickname[16];
u64 playerid;
union
#pragma pack(pop)
-static struct highscore_system
+VG_STATIC struct highscore_system
{
highscore_database dbheader;
aatree aainfo,
aainfo_playerinfo_playerid,
aainfo_playerinfo;
- void *data, *playerinfo_data;
+ void *data,
+ *playerinfo_data;
+
+ u32 pool_size, playerinfo_pool_size;
}
highscore_system;
-static int highscore_cmp_points( void *a, void *b )
+VG_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 )
+VG_STATIC int highscore_cmp_datetime( void *a, void *b )
{
highscore_record *pa = a, *pb = b;
return pa->datetime < pb->datetime? 1: -1;
}
-static int highscore_cmp_time( void *a, void *b )
+VG_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 )
+VG_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 )
+VG_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 )
+VG_STATIC void highscores_create_db(void)
{
- size_t requested_mem = size * count;
- void *data = vg_alloc( requested_mem );
+ struct highscore_system *sys = &highscore_system;
+
+ vg_info( "Initializing database nodes\n" );
+ memset( &sys->dbheader, 0, sizeof(highscore_database) );
- requested_mem /= 1024;
- requested_mem /= 1024;
+ sys->dbheader.pool_head = aatree_init_pool( &sys->aainfo, sys->pool_size );
+ sys->dbheader.entry_capacity = sys->pool_size;
- if( !data )
+ for( int i=0; i<vg_list_size(sys->dbheader.tracks); i++ )
{
- vg_error( "Could not allocated %dmb of memory\n", requested_mem );
- return NULL;
+ 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;
}
- else
- vg_success( "Allocated %dmb for %u records\n", requested_mem, count );
- return data;
+ /* Initialize secondary db */
+ sys->dbheader.playerinfo_head = aatree_init_pool(
+ &sys->aainfo_playerinfo,
+ sys->playerinfo_pool_size );
+ sys->dbheader.playerinfo_capacity = sys->playerinfo_pool_size;
+ sys->dbheader.playerinfo_root = AATREE_PTR_NIL;
}
-static void highscores_free(void)
+VG_STATIC int highscores_read(void)
{
- vg_free( highscore_system.data );
- vg_free( highscore_system.playerinfo_data );
+ struct highscore_system *sys = &highscore_system;
+
+ 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" );
+ return 0;
+ }
+
+ count = fread( sys->data, sizeof(highscore_record),
+ sys->pool_size, fp );
+
+ if( count != sys->pool_size )
+ {
+ vg_error( "Unexpected EOF reading database contents;"
+ " %lu records of %u were read\n", count, sys->pool_size );
+ return 0;
+ }
+
+ count = fread( sys->playerinfo_data, sizeof(highscore_playerinfo),
+ sys->playerinfo_pool_size, fp );
+
+ if( count != sys->playerinfo_pool_size )
+ {
+ vg_error( "Unexpected EOF reading playerinfo contents;"
+ " %lu records of %u were read\n", count,
+ sys->playerinfo_pool_size );
+ return 0;
+ }
+
+ fclose( fp );
+ return 1;
+ }
+ else
+ {
+ vg_low( "No existing database found (.aadb)\n" );
+ return 0;
+ }
}
-static int highscores_init( u32 pool_size, u32 playerinfo_pool_size )
+VG_STATIC void 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->data = vg_linear_alloc( vg_mem.rtmemory,
+ pool_size*sizeof(highscore_record) );
sys->playerinfo_data =
- highscore_malloc( playerinfo_pool_size, sizeof(highscore_playerinfo));
- if( !sys->playerinfo_data )
- {
- vg_free( sys->data );
- return 0;
- }
+ vg_linear_alloc( vg_mem.rtmemory,
+ playerinfo_pool_size * sizeof(highscore_playerinfo) );
+
+ memset( sys->data, 0, pool_size*sizeof(highscore_record) );
+ memset( sys->playerinfo_data, 0,
+ playerinfo_pool_size*sizeof(highscore_playerinfo) );
+
/* This is ugly.. too bad! */
sys->aainfo.base = highscore_system.data;
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; 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;
+ sys->playerinfo_pool_size = playerinfo_pool_size;
+ sys->pool_size = pool_size;
}
-static int highscores_serialize_all(void)
+VG_STATIC int highscores_serialize_all(void)
{
struct highscore_system *sys = &highscore_system;
vg_info( "Serializing database\n" );
return 1;
}
-static highscore_record *highscore_find_user_record( u64 playerid, u32 trackid )
+VG_STATIC highscore_record *highscore_find_user_record( u64 playerid, u32 trackid )
{
struct highscore_system *sys = &highscore_system;
return aatree_get_data( &sys->aainfo_playerid, find );
}
-static aatree_ptr highscores_push_record( highscore_record *record )
+VG_STATIC aatree_ptr highscores_push_record( highscore_record *record )
{
struct highscore_system *sys = &highscore_system;
return index;
}
-static aatree_ptr highscore_set_user_nickname( u64 steamid, char nick[10] )
+VG_STATIC aatree_ptr highscore_set_user_nickname( u64 steamid, char nick[16] )
{
- char name[11];
- for( int i=0; i<10; i++ )
+ char name[17];
+ for( int i=0; i<16; i++ )
name[i] = nick[i];
- name[10] = '\0';
+ name[16] = '\0';
vg_low( "Updating %lu's nickname -> %s\n", steamid, name );
info->playerid = steamid;
sys->dbheader.playerinfo_root = aatree_insert(
&sys->aainfo_playerinfo_playerid,
- sys->dbheader.playerinfo_root,
- record );
+ sys->dbheader.playerinfo_root, record );
}
- for( int i=0; i<10; i++ )
+ for( int i=0; i<16; 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 )
+VG_STATIC int highscore_strlen( const char *str, int len )
{
int str_length;
for( str_length=0; str_length<len; str_length++ )
}
/* Print the string(max length:len) centered into buf (has width:width) */
-static void highscore_strc( char *buf, const char *str, int len, int width )
+VG_STATIC void highscore_strc( char *buf, const char *str, int len, int width )
{
int str_length = highscore_strlen( str, len ),
offs = (width-str_length)/2;
}
/* Print the string(max length:len) left aligned into buf */
-static void highscore_strl( char *buf, const char *str, int len )
+VG_STATIC void highscore_strl( char *buf, const char *str, int len )
{
for( int i=0; i<len; i++ )
{
}
/* Print the string (max length:len) right aligned into buf (has width:width) */
-static void highscore_strr( char *buf, const char *str, int len, int width )
+VG_STATIC void highscore_strr( char *buf, const char *str, int len, int width )
{
int str_length = highscore_strlen( str, len );
}
/* Print integer (padded with: alt), right aligned into buf(width: len) */
-static void highscore_intr( char *buf, int value, int len, char alt )
+VG_STATIC void highscore_intr( char *buf, int value, int len, char alt )
{
int i=0;
- while(value)
- {
+ while(value){
if( i>=len )
return;
}
/* Print integer into buffer with max length len */
-static void highscore_intl( char *buf, int value, int len )
+VG_STATIC void highscore_intl( char *buf, int value, int len )
{
char temp[32];
}
/* Clear buffer with length using clr character */
-static void highscore_clear( char *buf, char clr, int length )
+VG_STATIC void highscore_clear( char *buf, char clr, int length )
{
for( int i=0; i<length; i++ )
buf[i] = clr;
/* Generate a highscores board in text form, the width is always 27. Buffer
* must be (count+3)*27 in size. */
-static void highscores_board_generate( char *buf, u32 id, u32 count )
+VG_STATIC void highscores_board_generate( char *buf, u32 id, u32 count )
{
int w=27;
highscore_clear( buf, ' ', (count+3)*w );
highscore_strc ( buf+w*0, inf->name, w,w );
highscore_clear( buf+w*1, '-', w );
- highscore_strl ( buf+w*2, " #| Player | Time | Pts", 27 );
+ highscore_strl ( buf+w*2, " #| Player | Time ", 27 );
for( int i=0; i<count; i++ )
{
/* Player name */
if( info_ptr == AATREE_PTR_NIL )
- highscore_strl( line+3, "unknown", 10 );
+ 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, 10 );
+ highscore_strl( line+3, inf->nickname, 16 );
+
+ /* yep, this is fucking awesome! */
+ if( inf->playerid == 0x8297744501001001 ||
+ inf->playerid == 0x1ec4620101001001 ||
+ inf->playerid == 0x0110000145749782 ||
+ inf->playerid == 0x011000010162c41e )
+ {
+ i --;
+ /* FIXME: Clear line, or yknow, do it properly */
+ }
}
u16 centiseconds = record->time,
if( minutes > 9 ) minutes = 9;
/* Timer */
- highscore_intr( line+14, minutes, 1, '0' );
- line[15] = ':';
- highscore_intr( line+16, seconds, 2, '0' );
- line[18] = '.';
- highscore_intr( line+19, centiseconds, 2, '0' );
+ 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 )
+VG_STATIC void highscores_board_printf( FILE *fp, const char *buf, u32 count )
{
int w=27;