X-Git-Url: https://harrygodden.com/git/?a=blobdiff_plain;f=world_sfd.c;h=6473d63b3404b24f3699a789d9d9ffcd171afbf7;hb=494c85703c76c4123c49937a32584840b6be1470;hp=9fe2d68e76743060909b200e8ef97fc54152c0c3;hpb=342fcbf6fda017bdd38d56ce0fa7c9e59e589f3b;p=carveJwlIkooP6JGAAIwe30JlM.git diff --git a/world_sfd.c b/world_sfd.c index 9fe2d68..6473d63 100644 --- a/world_sfd.c +++ b/world_sfd.c @@ -4,9 +4,14 @@ #include "world_sfd.h" #include "shaders/scene_scoretext.h" #include "shaders/scene_vertex_blend.h" +#include "network.h" +#include "entity.h" +#include "network_common.h" +#include "world_routes.h" -static f32 sfd_encode_glyph( char c ) -{ +struct world_sfd world_sfd; + +static f32 sfd_encode_glyph( char c ){ int value = 0; if( c >= 'a' && c <= 'z' ) value = c-'a'+11; @@ -39,59 +44,221 @@ static f32 sfd_encode_glyph( char c ) return (float)value; } -VG_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 ); - world_sfd.buffer[idx] = sfd_encode_glyph( str[i] ); + 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, NULL ); + + 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 ); + } } -VG_STATIC void sfd_update(void) +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 ); +} + +void world_sfd_update( world_instance *world, v3f pos ) +{ + if( mdl_arrcount( &world->ent_route ) ){ + u32 closest = 0; + float min_dist = INFINITY; + + for( u32 i=0; ient_route ); i++ ){ + ent_route *route = mdl_arritm( &world->ent_route, i ); + float dist = v3_dist2( route->board_transform[3], pos ); + + if( dist < min_dist ){ + min_dist = dist; + closest = i; + } + } + + struct leaderboard_cache *board = &world->leaderboard_cache[ closest ]; + + /* 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 ); + + 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; } } -VG_STATIC void bind_terrain_noise(void); -VG_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); - - world_link_lighting_ub( world, _shader_scene_scoretext.id ); - world_bind_position_texture( world, _shader_scene_scoretext.id, - _uniform_scene_scoretext_g_world_depth, 2 ); - world_bind_light_array( world, _shader_scene_scoretext.id, - _uniform_scene_scoretext_uLightsArray, 3 ); - world_bind_light_index( world, _shader_scene_scoretext.id, - _uniform_scene_scoretext_uLightsIndex, 4 ); + WORLD_BIND_LIGHT_BUFFERS_UB0_TEX234( world, scene_scoretext ); bind_terrain_noise(); @@ -118,13 +285,8 @@ VG_STATIC void sfd_render( world_instance *world, camera *cam, m4x3f transform ) shader_scene_vertex_blend_use(); shader_scene_vertex_blend_uTexGarbage(0); shader_scene_vertex_blend_uTexGradients(1); - world_link_lighting_ub( world, _shader_scene_vertex_blend.id ); - world_bind_position_texture( world, _shader_scene_vertex_blend.id, - _uniform_scene_vertex_blend_g_world_depth, 2 ); - world_bind_light_array( world, _shader_scene_vertex_blend.id, - _uniform_scene_vertex_blend_uLightsArray, 3 ); - world_bind_light_index( world, _shader_scene_vertex_blend.id, - _uniform_scene_vertex_blend_uLightsIndex, 4 ); + WORLD_BIND_LIGHT_BUFFERS_UB0_TEX234( world, scene_vertex_blend ); + bind_terrain_noise(); glActiveTexture( GL_TEXTURE1 ); glBindTexture( GL_TEXTURE_2D, world_sfd.tex_scoretex ); @@ -138,28 +300,15 @@ VG_STATIC void sfd_render( world_instance *world, camera *cam, m4x3f transform ) mdl_draw_submesh( &world_sfd.sm_base ); } -VG_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; -} - -VG_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 );