couple bugs
authorhgn <hgodden00@gmail.com>
Wed, 31 May 2023 19:34:27 +0000 (20:34 +0100)
committerhgn <hgodden00@gmail.com>
Wed, 31 May 2023 19:34:27 +0000 (20:34 +0100)
highscores.c [new file with mode: 0644]
highscores.h
input.h
maps_src/mp_mtzero/main.mdl
menu.h
network.h
server.c
skaterift.c
world_info.h
world_routes.c

diff --git a/highscores.c b/highscores.c
new file mode 100644 (file)
index 0000000..77ffc41
--- /dev/null
@@ -0,0 +1,540 @@
+#ifndef HIGHSCORES_C
+#define HIGHSCORES_C
+
+#include "highscores.h"
+
+VG_STATIC int highscore_cmp_points( void *a, void *b )
+{
+   highscore_record *pa = a, *pb = b;
+   return (int)pa->points - (int)pb->points;
+}
+
+VG_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;
+}
+
+VG_STATIC int highscore_cmp_time( void *a, void *b )
+{
+   highscore_record *pa = a, *pb = b;
+   return (int)pb->time - (int)pa->time;
+}
+
+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;
+}
+
+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;
+}
+
+VG_STATIC void highscores_create_db(void)
+{
+   struct highscore_system *sys = &highscore_system;
+
+   vg_info( "Initializing database nodes\n" );
+   memset( &sys->dbheader, 0, sizeof(highscore_database) );
+
+   sys->dbheader.pool_head = aatree_init_pool( &sys->aainfo, sys->pool_size );
+   sys->dbheader.entry_capacity = sys->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,
+         sys->playerinfo_pool_size );
+   sys->dbheader.playerinfo_capacity = sys->playerinfo_pool_size;
+   sys->dbheader.playerinfo_root = AATREE_PTR_NIL;
+}
+
+VG_STATIC int highscores_read(void)
+{
+   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;
+   }
+}
+
+VG_STATIC void highscores_init( u32 pool_size, u32 playerinfo_pool_size )
+{
+   struct highscore_system *sys = &highscore_system;
+
+   sys->data = vg_linear_alloc( vg_mem.rtmemory, 
+                                pool_size*sizeof(highscore_record) );
+
+   sys->playerinfo_data = 
+      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.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;
+
+   sys->playerinfo_pool_size = playerinfo_pool_size;
+   sys->pool_size = pool_size;
+}
+
+VG_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;
+}
+
+VG_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 );
+}
+
+VG_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;
+}
+
+VG_STATIC aatree_ptr highscore_set_user_nickname( u64 steamid, char nick[16] )
+{
+   char name[17];
+   for( int i=0; i<16; i++ )
+      name[i] = nick[i];
+   name[16] = '\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<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 */
+VG_STATIC int highscore_strlen( const char *str, int len )
+{
+   int str_length;
+   for( str_length=0; str_length<len; str_length++ )
+      if( !str[str_length] )
+         return str_length;
+
+   return str_length;
+}
+
+/* Print the string(max length:len) centered into buf (has width: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;
+
+   for( int i=0; i<str_length; i++ )
+   {
+      int j=i+offs;
+
+      if( j >= width )
+         return;
+
+      buf[j] = str[i];
+   }
+}
+
+/* Print the string(max length:len) left aligned into buf */
+VG_STATIC void highscore_strl( char *buf, const char *str, int len )
+{
+   for( int i=0; i<len; i++ )
+   {
+      if( !str[i] )
+         return;
+
+      buf[i] = str[i];
+   }
+}
+
+/* Print the string (max length:len) right aligned into buf (has width:width) */
+VG_STATIC void highscore_strr( char *buf, const char *str, int len, int width )
+{
+   int str_length = highscore_strlen( str, len );
+   
+   for( int i=0; i<len; i++ )
+   {
+      if( !str[i] )
+         return;
+
+      buf[width-str_length+i] = str[i];
+   }
+}
+
+/* Print integer (padded with: alt), right aligned into buf(width: len)
+ * returns number of digits (not including alt), that were written to buf */
+VG_STATIC int highscore_intr( char *buf, int value, int len, char alt )
+{
+   int i=0;
+   while(value){
+      if( i>=len ) 
+         return i;
+
+      buf[ len-1 - (i ++) ] = '0' + (value % 10);
+      value /= 10;
+   }
+
+   for( ;i<len; i ++ )
+      buf[ len-1 - i ] = alt;
+
+   return i;
+}
+
+/* Print integer into buffer with max length len 
+ * retuns the number of digits written to buf */
+VG_STATIC int highscore_intl( char *buf, int value, int len )
+{
+   char temp[32];
+
+   int i=0;
+   while(value){
+      if( i>=len ) 
+         break;
+
+      temp[ i ++ ] = '0' + (value % 10);
+      value /= 10;
+   }
+   
+   if( i>len )
+      i = len;
+
+   for( int j=0; j<i; j ++ )
+      buf[j] = temp[ i-1-j ];
+
+   return i;
+}
+
+/* Clear buffer with length using clr character */
+VG_STATIC void highscore_clear( char *buf, char clr, int length )
+{
+   for( int i=0; i<length; i++ )
+      buf[i] = clr;
+}
+
+/*
+       Megapark Green      
+--------------------------
+ #|   Player |  Time | Pts 
+ 1|aaaabbbbcc 5:23.32 30000
+ 2|       jef 0:20.34 10000
+ 3|aaabbbcccl 2:30.45 20000
+ 4|
+ 5|
+ 6|
+ 7|
+ 8|
+ 9|
+10|
+*/
+
+/* Generate a highscores board in text form, the width is always 27. Buffer 
+ * must be (count+3)*27 in size. */
+VG_STATIC void highscores_board_generate( char *buf, u32 id, u32 count )
+{
+   int w=27;
+   highscore_clear( buf, ' ', (count+3)*w );
+
+   struct track_info *inf = &track_infos[id];
+   struct highscore_system *sys = &highscore_system;
+
+   highscore_track_table *table = &sys->dbheader.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; i<count; i++ )
+   {
+      char *line = buf+w*(3+i);
+      highscore_intr( line, i+1, 2, ' ' );
+      line[2] = '|';
+
+      if( it == AATREE_PTR_NIL )
+         continue;
+
+      highscore_record *record = aatree_get_data( &sys->aainfo_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 );
+
+         /* 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,
+          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 */
+VG_STATIC void highscores_board_printf( FILE *fp, const char *buf, u32 count )
+{
+   int w=27;
+
+   for( int i=0; i<count+3; i++ )
+      fprintf( fp, "%.27s\n", &buf[i*w] );
+}
+
+#endif /* HIGHSCORES_C */
index b096714cb9e8c16af1e93e0cf47322846ae9b134..c94087fbff07bef56d2baee46f83320660e401f2 100644 (file)
@@ -98,537 +98,8 @@ VG_STATIC struct highscore_system
 }
 highscore_system;
 
-VG_STATIC int highscore_cmp_points( void *a, void *b )
-{
-   highscore_record *pa = a, *pb = b;
-   return (int)pa->points - (int)pb->points;
-}
-
-VG_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;
-}
-
-VG_STATIC int highscore_cmp_time( void *a, void *b )
-{
-   highscore_record *pa = a, *pb = b;
-   return (int)pb->time - (int)pa->time;
-}
-
-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;
-}
-
-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;
-}
-
-VG_STATIC void highscores_create_db(void)
-{
-   struct highscore_system *sys = &highscore_system;
-
-   vg_info( "Initializing database nodes\n" );
-   memset( &sys->dbheader, 0, sizeof(highscore_database) );
-
-   sys->dbheader.pool_head = aatree_init_pool( &sys->aainfo, sys->pool_size );
-   sys->dbheader.entry_capacity = sys->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,
-         sys->playerinfo_pool_size );
-   sys->dbheader.playerinfo_capacity = sys->playerinfo_pool_size;
-   sys->dbheader.playerinfo_root = AATREE_PTR_NIL;
-}
-
-VG_STATIC int highscores_read(void)
-{
-   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;
-   }
-}
-
-VG_STATIC void highscores_init( u32 pool_size, u32 playerinfo_pool_size )
-{
-   struct highscore_system *sys = &highscore_system;
-
-   sys->data = vg_linear_alloc( vg_mem.rtmemory, 
-                                pool_size*sizeof(highscore_record) );
-
-   sys->playerinfo_data = 
-      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.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;
-
-   sys->playerinfo_pool_size = playerinfo_pool_size;
-   sys->pool_size = pool_size;
-}
-
-VG_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;
-}
-
-VG_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 );
-}
-
-VG_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;
-}
-
-VG_STATIC aatree_ptr highscore_set_user_nickname( u64 steamid, char nick[16] )
-{
-   char name[17];
-   for( int i=0; i<16; i++ )
-      name[i] = nick[i];
-   name[16] = '\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<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 */
-VG_STATIC int highscore_strlen( const char *str, int len )
-{
-   int str_length;
-   for( str_length=0; str_length<len; str_length++ )
-      if( !str[str_length] )
-         return str_length;
-
-   return str_length;
-}
-
-/* Print the string(max length:len) centered into buf (has width: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;
-
-   for( int i=0; i<str_length; i++ )
-   {
-      int j=i+offs;
-
-      if( j >= width )
-         return;
-
-      buf[j] = str[i];
-   }
-}
-
-/* Print the string(max length:len) left aligned into buf */
-VG_STATIC void highscore_strl( char *buf, const char *str, int len )
-{
-   for( int i=0; i<len; i++ )
-   {
-      if( !str[i] )
-         return;
-
-      buf[i] = str[i];
-   }
-}
-
-/* Print the string (max length:len) right aligned into buf (has width:width) */
-VG_STATIC void highscore_strr( char *buf, const char *str, int len, int width )
-{
-   int str_length = highscore_strlen( str, len );
-   
-   for( int i=0; i<len; i++ )
-   {
-      if( !str[i] )
-         return;
-
-      buf[width-str_length+i] = str[i];
-   }
-}
-
-/* Print integer (padded with: alt), right aligned into buf(width: len)
- * returns number of digits (not including alt), that were written to buf */
-VG_STATIC int highscore_intr( char *buf, int value, int len, char alt )
-{
-   int i=0;
-   while(value){
-      if( i>=len ) 
-         return i;
-
-      buf[ len-1 - (i ++) ] = '0' + (value % 10);
-      value /= 10;
-   }
-
-   for( ;i<len; i ++ )
-      buf[ len-1 - i ] = alt;
-
-   return i;
-}
-
-/* Print integer into buffer with max length len 
- * retuns the number of digits written to buf */
-VG_STATIC int highscore_intl( char *buf, int value, int len )
-{
-   char temp[32];
-
-   int i=0;
-   while(value){
-      if( i>=len ) 
-         break;
-
-      temp[ i ++ ] = '0' + (value % 10);
-      value /= 10;
-   }
-   
-   if( i>len )
-      i = len;
-
-   for( int j=0; j<i; j ++ )
-      buf[j] = temp[ i-1-j ];
-
-   return i;
-}
-
-/* Clear buffer with length using clr character */
-VG_STATIC void highscore_clear( char *buf, char clr, int length )
-{
-   for( int i=0; i<length; i++ )
-      buf[i] = clr;
-}
-
-/*
-       Megapark Green      
---------------------------
- #|   Player |  Time | Pts 
- 1|aaaabbbbcc 5:23.32 30000
- 2|       jef 0:20.34 10000
- 3|aaabbbcccl 2:30.45 20000
- 4|
- 5|
- 6|
- 7|
- 8|
- 9|
-10|
-*/
-
-/* Generate a highscores board in text form, the width is always 27. Buffer 
- * must be (count+3)*27 in size. */
-VG_STATIC void highscores_board_generate( char *buf, u32 id, u32 count )
-{
-   int w=27;
-   highscore_clear( buf, ' ', (count+3)*w );
-
-   struct track_info *inf = &track_infos[id];
-   struct highscore_system *sys = &highscore_system;
-
-   highscore_track_table *table = &sys->dbheader.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; i<count; i++ )
-   {
-      char *line = buf+w*(3+i);
-      highscore_intr( line, i+1, 2, ' ' );
-      line[2] = '|';
-
-      if( it == AATREE_PTR_NIL )
-         continue;
-
-      highscore_record *record = aatree_get_data( &sys->aainfo_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 );
-
-         /* 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,
-          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 */
-VG_STATIC void highscores_board_printf( FILE *fp, const char *buf, u32 count )
-{
-   int w=27;
-
-   for( int i=0; i<count+3; i++ )
-      fprintf( fp, "%.27s\n", &buf[i*w] );
-}
+VG_STATIC int highscore_intr( char *buf, int value, int len, char alt );
+VG_STATIC int highscore_intl( char *buf, int value, int len );
+VG_STATIC void highscores_board_printf( FILE *fp, const char *buf, u32 count );
 
 #endif /* HIGHSCORES_H */
diff --git a/input.h b/input.h
index ff0aa6f2d5dd4ade58b7cd091a290705565a4de2..6548eef2c9d163d00a7c99a4b0ef60fcd3b8aef2 100644 (file)
--- a/input.h
+++ b/input.h
@@ -328,7 +328,8 @@ static void skaterift_preupdate_inputs(void)
       setbtn( k_srbind_mdown,  buttons[ SDL_CONTROLLER_BUTTON_DPAD_DOWN ] );
       setbtn( k_srbind_mback,  buttons[ SDL_CONTROLLER_BUTTON_B ] );
       setbtn( k_srbind_maccept,buttons[ SDL_CONTROLLER_BUTTON_A ] );
-      setbtn( k_srbind_mopen,  buttons[ SDL_CONTROLLER_BUTTON_GUIDE ] );
+      setbtn( k_srbind_mopen,  buttons[ SDL_CONTROLLER_BUTTON_START ] );
+      setbtn( k_srbind_mback,  buttons[ SDL_CONTROLLER_BUTTON_START ] );
 
       float *axis = controller->axises;
 
@@ -355,8 +356,8 @@ static void skaterift_preupdate_inputs(void)
 
       if( lh >  sensitivity ) setbtn( k_srbind_mright, 1 );
       if( lh < -sensitivity ) setbtn( k_srbind_mleft, 1 );
-      if( lv >  sensitivity ) setbtn( k_srbind_mup, 1 );
-      if( lv < -sensitivity ) setbtn( k_srbind_mdown, 1 );
+      if( lv >  sensitivity ) setbtn( k_srbind_mdown, 1 );
+      if( lv < -sensitivity ) setbtn( k_srbind_mup, 1 );
    }
 
    srinput.axis_states[ k_sraxis_grab ][0] = 
index eff63869b4708116e681485dd3015ef918e18473..ef57c3520c61a160277bb0bcff64b9b5e60ae18d 100644 (file)
Binary files a/maps_src/mp_mtzero/main.mdl and b/maps_src/mp_mtzero/main.mdl differ
diff --git a/menu.h b/menu.h
index 30c025d17f085c61ed3961a6ed28490dc7223d61..32291c1c6e2a10855779c1377366181336a2cf8a 100644 (file)
--- a/menu.h
+++ b/menu.h
@@ -22,8 +22,8 @@ struct {
        page_depth;
 
    enum menu_input_mode{
-      k_menu_input_mode_mouse,
-      k_menu_input_mode_keys
+      k_menu_input_mode_keys,
+      k_menu_input_mode_mouse
    }
    input_mode;
    f32 mouse_track, mouse_dist;  /* used for waking up mouse */
index 38fc9039eb3a39e97e129fd5c012d66b78bc967b..83564f019f8ecb7347353c840569526f756c8759 100644 (file)
--- a/network.h
+++ b/network.h
@@ -138,12 +138,16 @@ VG_STATIC void send_score_update(void)
    for( u32 i=0; i<vg_list_size(track_infos); i++ ){
       if( track_infos[i].push ){
          track_infos[i].push = 0;
+
+#if 0
          highscore_record *user_record = highscore_find_user_record( 0, i );
 
          if( !user_record ){
             vg_error( "No score set but tried to upload for track %u\n", i );
             continue;
          }
+#endif
+         highscore_record *user_record = &track_infos[i].record;
 
          setscore->records[count].trackid = i;
          setscore->records[count].playerid = 0;
index 3dd6021623bf573497ca190af257468aa9451453..3a0d666b4416380a0d236823b22b97e7a2a1c812 100644 (file)
--- a/server.c
+++ b/server.c
@@ -321,8 +321,7 @@ static void generate_boards(void)
 {
    FILE *fp = fopen( "www/html/srhighscores.txt", "w" );
 
-   for( int i=0; i<vg_list_size(track_infos); i++ )
-   {
+   for( int i=0; i<vg_list_size(track_infos); i++ ){
       struct netmsg_board *board = &scoreboard_client_data.boards[i];
 
       highscores_board_generate( board->data, i, 10 );
index 74e360b4d5e9ddbda702482f1a3faf76412f3b08..6cb3579e819c5b5261229e7c25decda86bad586d 100644 (file)
@@ -45,6 +45,7 @@
 #include "entity.c"
 #include "workshop.c"
 #include "addon.c"
+#include "highscores.c"
 
 static struct player_avatar localplayer_avatar;
 static struct player_model  localplayer_models[3];
index 0d2be39437818eab0ef615b2323cc16eee5f3be0..7135752e964af3ac02387bc193250733c2c39066 100644 (file)
@@ -8,43 +8,41 @@
 /* Purely an information header, shares common strings across client and 
  * server programs. */
 
-static struct track_info
+#include "highscores.h"
+
+struct track_info
 {
    const char *name, 
               *achievement_id;
+
+   highscore_record record;      /* session */
    int push;
 }
-track_infos[] = 
+static track_infos[] = 
 {
    {
       .name = "Megapark Green",
       .achievement_id = "ROUTE_MPG",
-      .push = 1
    },
    {
       .name = "Megapark Blue",
       .achievement_id = "ROUTE_MPB",
-      .push = 1
    },
    {
       .name = "Megapark Yellow",
       .achievement_id = "ROUTE_MPY",
-      .push = 1
    },
    {
       .name = "Megapark Red",
       .achievement_id = "ROUTE_MPR",
-      .push = 1
    },
    {
       .name = "Coastal Run",
       .achievement_id = "ROUTE_TC",
-      .push = 1
    },
    {
       .name = "Docks Jumps",
       .achievement_id = "ROUTE_TO",
-      .push = 1
    }
 };
 
index d366a123e09ee0f3f5e079504dacf1e66bdbb440..1ff33fe8501e9b90201613f1e0701fd63119257a 100644 (file)
@@ -31,17 +31,13 @@ void world_routes_local_set_record( world_instance *world, ent_route *route,
       if( time_centiseconds > (float)0xfffe )   /* skill issue */
          return;
 
-      highscore_record temp;
-      temp.trackid  = route->official_track_id;
-      temp.datetime = time(NULL);
-      temp.playerid = 0;
-      temp.points   = 0;
-      temp.time     = time_centiseconds;
-#if 0
-      highscores_push_record( &temp );
-#endif
-
       struct track_info *ti = &track_infos[ route->official_track_id ];
+      highscore_record *record = &ti->record;
+      record->trackid  = route->official_track_id;
+      record->datetime = time(NULL);
+      record->playerid = 0;
+      record->points   = 0;
+      record->time     = time_centiseconds;
       ti->push = 1;
       
       if( ti->achievement_id ){