From 02c9203df66d93f21c0e64f51193bcbeaabfc9bd Mon Sep 17 00:00:00 2001 From: hgn Date: Sat, 25 Nov 2023 07:46:20 +0000 Subject: [PATCH] checkpoint diffs --- entity.h | 3 +++ world_entity.c | 31 +++++++++++++++++++++++++++++++ world_routes.c | 18 ++++++++++++++++-- world_routes_ui.c | 34 +++++++++++++++++++++++++++++++--- 4 files changed, 81 insertions(+), 5 deletions(-) diff --git a/entity.h b/entity.h index 0e65c26..13051d4 100644 --- a/entity.h +++ b/entity.h @@ -168,6 +168,9 @@ struct ent_checkpoint{ u16 gate_index, path_start, path_count; + + /* EXTENSION */ + f32 best_time; }; enum ent_route_flag { diff --git a/world_entity.c b/world_entity.c index 3fd7ac6..834ede6 100644 --- a/world_entity.c +++ b/world_entity.c @@ -629,6 +629,25 @@ static void world_entity_start( world_instance *world, vg_msg *sav ){ route->flags |= vg_msg_getkvu32( &route_info, "flags", 0 ); route->best_laptime = vg_msg_getkvf64( &route_info, "best_laptime", 0.0 ); + + f32 sections[ route->checkpoints_count ]; + vg_msg_cmd cmd; + if( vg_msg_getkvcmd( &route_info, "sections", &cmd ) ){ + vg_msg_cast( cmd.value, cmd.code, sections, + k_vg_msg_f32 | + vg_msg_count_bits(route->checkpoints_count) ); + } + else{ + for( u32 j=0; jcheckpoints_count; j ++ ) + sections[j] = 0.0f; + } + + for( u32 j=0; jcheckpoints_count; j ++ ){ + ent_checkpoint *cp = mdl_arritm( &world->ent_checkpoint, + route->checkpoints_start + j ); + + cp->best_time = sections[j]; + } } } } @@ -653,6 +672,18 @@ static void world_entity_serialize( world_instance *world, vg_msg *sav ){ { vg_msg_wkvu32( sav, "flags", route->flags ); vg_msg_wkvf64( sav, "best_laptime", route->best_laptime ); + + f32 sections[ route->checkpoints_count ]; + + for( u32 j=0; jcheckpoints_count; j ++ ){ + ent_checkpoint *cp = mdl_arritm( &world->ent_checkpoint, + route->checkpoints_start + j ); + + sections[j] = cp->best_time; + } + + vg_msg_wkvnum( sav, "sections", k_vg_msg_f32, + route->checkpoints_count, sections ); } vg_msg_end_frame( sav ); } diff --git a/world_routes.c b/world_routes.c index d81419f..e0b5fa3 100644 --- a/world_routes.c +++ b/world_routes.c @@ -46,6 +46,8 @@ static void world_routes_time_lap( world_instance *world, ent_route *route ){ double start_time = 0.0; u32 last_version=0; + f64 last_time = 0.0; + ent_checkpoint *last_cp = NULL; u32 valid_sections=0; int clean = !localplayer.rewinded_since_last_gate; @@ -69,14 +71,16 @@ static void world_routes_time_lap( world_instance *world, ent_route *route ){ else valid_sections = 0; } - last_version = rg->timing_version; - vg_info( "%u %f [%s]\n", rg->timing_version, rg->timing_time, i? ((rg->flags & k_ent_gate_clean_pass)? "CLEAN": " "): " N/A "); if( !(rg->flags & k_ent_gate_clean_pass) ) clean = 0; + + last_version = rg->timing_version; + last_time = rg->timing_time; + last_cp = cp; } if( world_static.current_run_version == last_version+1 ){ @@ -85,6 +89,11 @@ static void world_routes_time_lap( world_instance *world, ent_route *route ){ if( route->checkpoints_count == 1 ){ route->timing_base = world_static.time; } + + f32 section = world_static.time - last_time; + if( (section < last_cp->best_time) || (last_cp->best_time == 0.0f) ){ + last_cp->best_time = section; + } } else valid_sections = 0; @@ -592,6 +601,11 @@ static void world_gen_routes_ent_init( world_instance *world ){ ent_gate *gate = mdl_arritm( &world->ent_gate, i ); } + for( u32 i=0; ient_checkpoint); i++ ){ + ent_checkpoint *cp = mdl_arritm( &world->ent_checkpoint, i ); + cp->best_time = 0.0; + } + world_routes_clear( world ); } diff --git a/world_routes_ui.c b/world_routes_ui.c index 9ccad80..319870a 100644 --- a/world_routes_ui.c +++ b/world_routes_ui.c @@ -18,14 +18,15 @@ static void ent_route_imgui( world_instance *world, ent_route *route, u32 last_version=0; f64 last_time = 0.0; + ent_checkpoint *last_cp = NULL; u32 valid_sections=0; struct time_block{ - f32 length; + f32 length, best; int clean; } - *blocks = alloca( sizeof(struct time_block) * route->checkpoints_count ); + blocks[ route->checkpoints_count ]; for( u32 i=0; icheckpoints_count; i++ ){ u32 cpid = i+route->active_checkpoint+1; @@ -40,17 +41,20 @@ static void ent_route_imgui( world_instance *world, ent_route *route, struct time_block *block = &blocks[ valid_sections ++ ]; block->clean = (rg->flags & k_ent_gate_clean_pass)? 1: 0; block->length = rg->timing_time - last_time; + block->best = last_cp? last_cp->best_time: 0.0f; } else valid_sections = 0; last_version = rg->timing_version; last_time = rg->timing_time; + last_cp = cp; } if( last_version+1 == world_static.current_run_version ){ struct time_block *block = &blocks[ valid_sections ++ ]; block->clean = localplayer.rewinded_since_last_gate? 0: 1; block->length = world_static.time - last_time; + block->best = last_cp->best_time; } else valid_sections = 0; @@ -62,13 +66,37 @@ static void ent_route_imgui( world_instance *world, ent_route *route, for( u32 i=0; ilength * 6.0f; + ui_px w = 20 + (block->length * 6.0f); ui_rect rect = { x, inout_cursor[1], w, h }; ui_fill( rect, colour ); if( block->clean ) ui_outline( rect, 1, 0xff00ffff, 0 ); + if( block->best != 0.0f ){ + char buf[32]; + vg_str str; + vg_strnull( &str, buf, 32 ); + + f32 diff = block->length - block->best, + as = fabsf(diff), + s = floorf( as ), + ds = floorf( vg_fractf( as ) * 10.0f ); + + if( (block->best != 0.0f) && (fabsf(diff) > 0.02f) ){ + if( diff > 0.0f ) + vg_strcatch( &str, '+' ); + else + vg_strcatch( &str, '-' ); + + vg_strcati32( &str, s ); + vg_strcatch( &str, '.' ); + vg_strcati32( &str, ds ); + + ui_text( rect, buf, 1, k_ui_align_middle_center, 0 ); + } + } + x += w + 4; } -- 2.25.1