X-Git-Url: https://harrygodden.com/git/?a=blobdiff_plain;f=world_sfd.c;h=ef4fc3bc7726fe4f29a21efb17601856912c05ad;hb=b440efbe5785d114d08bb3f5ec0e09cad943006d;hp=9310aee6a52e21f54040b1f46a8f559e81010570;hpb=7e1fe6c7931ba4492aa10ac5eebc316b74fb5dac;p=carveJwlIkooP6JGAAIwe30JlM.git diff --git a/world_sfd.c b/world_sfd.c index 9310aee..ef4fc3b 100644 --- a/world_sfd.c +++ b/world_sfd.c @@ -6,6 +6,10 @@ #include "shaders/scene_vertex_blend.h" #include "network.h" #include "entity.h" +#include "network_common.h" +#include "world_routes.h" + +struct world_sfd world_sfd; static f32 sfd_encode_glyph( char c ){ int value = 0; @@ -40,26 +44,154 @@ static f32 sfd_encode_glyph( char c ){ return (float)value; } -static void sfd_encode( u32 row, const char *str ){ - int end=0; +static void sfd_clear( u32 row ){ u32 row_h = world_sfd.h -1 -row; - for( int i=0; i= world_sfd.w) || (u < 0) ) + continue; + + if( !str[i] ) + return; + + world_sfd.buffer[idx] = sfd_encode_glyph( str[i] ); + } +} + +void world_sfd_compile_scores( struct leaderboard_cache *board, + const char *title ) +{ + for( u32 i=0; i<13; i++ ) + sfd_clear(i); + + sfd_encode( (v2i){0,0}, title, k_world_sfd_left ); + + if( !board ){ + sfd_encode( (v2i){-1,4}, "Error out of range", k_world_sfd_center ); + return; + } + + if( !network_connected() ){ + sfd_encode( (v2i){-1,0}, "Offline", k_world_sfd_right ); + return; + } + + if( board->status == k_request_status_not_found ){ + sfd_encode( (v2i){-1,4}, "No records", k_world_sfd_center ); + return; + } + + if( board->status != k_request_status_ok ){ + char buf[32]; + vg_str s; + vg_strnull( &s, buf, 32 ); + vg_strcat( &s, "Error: " ); + vg_strcati32( &s, board->status ); + sfd_encode( (v2i){-1,4}, buf, k_world_sfd_center ); + return; + } + + vg_msg body; + vg_msg_init( &body, board->data, board->data_len ); + + const char *alias = "rows"; + + if( world_sfd.view_weekly ){ + alias = "rows_weekly"; + sfd_encode( (v2i){-1,0}, "Weekly", k_world_sfd_right ); + } + else { + sfd_encode( (v2i){-1,0}, "All-Time", k_world_sfd_right ); + } + + u32 l = 1; + if( vg_msg_seekframe( &body, alias ) ){ + while( vg_msg_seekframe( &body, NULL ) ){ + /* name */ + const char *username = vg_msg_getkvstr( &body, "username" ); + + char buf[100]; + vg_str str; + vg_strnull( &str, buf, 100 ); + vg_strcati32( &str, l ); + vg_strcat( &str, " " ); + + if( username ) + vg_strcat( &str, username ); + else + vg_strcat( &str, "??????" ); + + sfd_encode( (v2i){0,l}, str.buffer, k_world_sfd_left ); + + /* time */ + vg_strnull( &str, buf, 100 ); + + u32 centiseconds; + vg_msg_getkvintg( &body, "time", k_vg_msg_i32, ¢iseconds ); + + i32 seconds = centiseconds / 100, + minutes = seconds / 60; + + centiseconds %= 100; + seconds %= 60; + minutes %= 60; + if( minutes > 9 ) vg_strcat( &str, "?" ); + else vg_strcati32( &str, minutes ); + vg_strcat( &str, ":" ); + vg_strcati32r( &str, seconds, 2, '0' ); + vg_strcat( &str, "." ); + vg_strcati32r( &str, centiseconds, 2, '0' ); + sfd_encode( (v2i){-1,l}, str.buffer, k_world_sfd_right ); + l ++; + + vg_msg_skip_frame( &body ); } } + else { + sfd_encode( (v2i){-1,4}, "No records", k_world_sfd_center ); + } +} + +void world_sfd_compile_active_scores(void) +{ + world_instance *world = world_current_instance(); + + struct leaderboard_cache *board = NULL; + const char *name = "Out of range"; + + if( world_sfd.active_route_board < mdl_arrcount( &world->ent_route ) ){ + board = &world->leaderboard_cache[ world_sfd.active_route_board ]; + ent_route *route = mdl_arritm( &world->ent_route, + world_sfd.active_route_board ); + name = mdl_pstr( &world->meta, route->pstr_name ); + } + + world_sfd_compile_scores( board, name ); } -static void world_sfd_update( world_instance *world, v3f pos ){ +void world_sfd_update( world_instance *world, v3f pos ) +{ if( mdl_arrcount( &world->ent_route ) ){ u32 closest = 0; float min_dist = INFINITY; @@ -74,43 +206,55 @@ static void world_sfd_update( world_instance *world, v3f pos ){ } } - if( (world_sfd.active_route_board != closest) || network_scores_updated ){ - network_scores_updated = 0; - world_sfd.active_route_board = closest; - ent_route *route = mdl_arritm( &world->ent_route, closest ); + struct leaderboard_cache *board = &world->leaderboard_cache[ closest ]; - addon_reg *world_reg = - world_static.instance_addons[ world_static.active_instance ]; + /* request new board if cache expires */ + if( network_connected() ){ + f64 delta = vg.time_real - board->cache_time; + if( (delta > 45.0) || (board->cache_time == 0.0) ){ + board->cache_time = vg.time_real; + ent_route *route = mdl_arritm( &world->ent_route, closest ); + addon_reg *world_reg = + world_static.instance_addons[ world - world_static.instances ]; - char mod_uid[ ADDON_UID_MAX ]; - addon_alias_uid( &world_reg->alias, mod_uid ); + char mod_uid[ ADDON_UID_MAX ]; + addon_alias_uid( &world_reg->alias, mod_uid ); - network_request_scoreboard( - mod_uid, - mdl_pstr( &world->meta, route->pstr_name ), - 0 ); + network_request_scoreboard( + mod_uid, + mdl_pstr( &world->meta, route->pstr_name ), + NETWORK_LEADERBOARD_ALLTIME_AND_CURRENT_WEEK, closest ); + } } + + /* compile board text if we changed. */ + if( world_sfd.active_route_board != closest ){ + world_sfd_compile_active_scores(); + } + + world_sfd.active_route_board = closest; } for( int i=0; i rate ){ *cur += rate; - if( *cur > 60.0f ) - *cur -= 60.0f; + if( *cur > 49.0f ) + *cur -= 49.0f; } else *cur = *target; } } -static void bind_terrain_noise(void); -static void sfd_render( world_instance *world, camera *cam, m4x3f transform ){ +void bind_terrain_noise(void); +void sfd_render( world_instance *world, vg_camera *cam, m4x3f transform ) +{ mesh_bind( &world_sfd.mesh_display ); shader_scene_scoretext_use(); shader_scene_scoretext_uTexMain(1); @@ -156,26 +300,15 @@ static void sfd_render( world_instance *world, camera *cam, m4x3f transform ){ mdl_draw_submesh( &world_sfd.sm_base ); } -static int world_sfd_test( int argc, const char *argv[] ){ - if( argc == 2 ){ - int row = vg_min( vg_max(atoi(argv[0]),0), world_sfd.h); - sfd_encode( row, argv[1] ); - } - - return 0; -} - -static void world_sfd_init(void){ +void world_sfd_init(void) +{ vg_info( "world_sfd_init\n" ); - shader_scene_scoretext_register(); - vg_console_reg_cmd( "sfd", world_sfd_test, NULL ); - vg_linear_clear( vg_mem.scratch ); mdl_context mscoreboard; mdl_open( &mscoreboard, "models/rs_scoretext.mdl", vg_mem.scratch ); mdl_load_metadata_block( &mscoreboard, vg_mem.scratch ); - mdl_async_load_glmesh( &mscoreboard, &world_sfd.mesh_base ); + mdl_async_load_glmesh( &mscoreboard, &world_sfd.mesh_base, NULL ); mdl_load_mesh_block( &mscoreboard, vg_mem.scratch );