checkpoint diffs
authorhgn <hgodden00@gmail.com>
Sat, 25 Nov 2023 07:46:20 +0000 (07:46 +0000)
committerhgn <hgodden00@gmail.com>
Sat, 25 Nov 2023 07:46:20 +0000 (07:46 +0000)
entity.h
world_entity.c
world_routes.c
world_routes_ui.c

index 0e65c268a6c81f71ac05bb306f688532e2318ffe..13051d4f9b0eafd5fae78377ae4e2060f49ed1f3 100644 (file)
--- 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 {
index 3fd7ac63473459781b85ed7a348038247eb545a7..834ede636ab83ec8c6e4d235959e2b352c06f880 100644 (file)
@@ -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; j<route->checkpoints_count; j ++ )
+                  sections[j] = 0.0f;
+            }
+
+            for( u32 j=0; j<route->checkpoints_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; j<route->checkpoints_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 );
       }
index d81419f252852de5e4c575efc41a2656b4f2936e..e0b5fa3f0498c211a108155c01743f960850a1fa 100644 (file)
@@ -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; i<mdl_arrcount(&world->ent_checkpoint); i++ ){
+      ent_checkpoint *cp = mdl_arritm( &world->ent_checkpoint, i );
+      cp->best_time = 0.0;
+   }
+
    world_routes_clear( world );
 }
 
index 9ccad800ec2a7f3ceb5fe7804b110366607d0650..319870a9f85658971ceaf5456de942ac0ac9aafb 100644 (file)
@@ -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; i<route->checkpoints_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; i<valid_sections; i ++ ){
       struct time_block *block = &blocks[ i ];
-      ui_px w = block->length * 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;
    }