From 681a5c0d7a135ba78655d9cb6d1476a50a4e4709 Mon Sep 17 00:00:00 2001 From: hgn Date: Thu, 18 Aug 2022 15:22:27 +0100 Subject: [PATCH] route verify --- world_routes.h | 158 ++++++++++++++++++++++++++++++++++++------------- 1 file changed, 117 insertions(+), 41 deletions(-) diff --git a/world_routes.h b/world_routes.h index a4624dc..91fde29 100644 --- a/world_routes.h +++ b/world_routes.h @@ -8,6 +8,12 @@ #include "shaders/vblend.h" #include "shaders/route.h" +enum route_special_type +{ + k_route_special_type_gate = 1, + k_route_special_type_collector = 2 +}; + struct subworld_routes { struct route_node @@ -15,7 +21,7 @@ struct subworld_routes v3f co, right, up, h; u32 next[2]; - u32 is_gate, gate_id, current_refs, ref_count; + u32 special_type, special_id, current_refs, ref_count; u32 route_ids[4]; /* Gates can be linked into up to four routes */ } *nodes; @@ -44,14 +50,20 @@ struct subworld_routes teleport_gate gate; u32 node_id; - - double time_passed; /* When did we last pass this gate? */ - u32 passed_version; /* Incremented on every reset */ + u32 passed_version; /* Incremented on every teleport */ } *gates; + struct route_collector + { + double time_passed; /* When did we last pass this? */ + } + *collectors; + u32 gate_count, - gate_cap; + gate_cap, + collector_count, + collector_cap; u32 active_gate, current_run_version; @@ -147,7 +159,6 @@ static u32 world_routes_get_path( u32 starter, u32 stack[64] ) static void world_routes_verify_run( u32 route, double new_pass_time ) { struct subworld_routes *r = subworld_routes(); - if( r->current_run_version == 0 ) return; u32 stack[64]; u32 si = world_routes_get_path( r->routes[route].start, stack ); @@ -155,10 +166,11 @@ static void world_routes_verify_run( u32 route, double new_pass_time ) /* * we only care about gates that ref gates, so shuffle down the array */ + u32 gates[64]; u32 sj = 0; for( u32 i=0; inodes[stack[i]].is_gate && r->nodes[stack[(i+1)%si]].is_gate ) - stack[sj ++] = r->nodes[stack[i]].gate_id; + if( r->nodes[stack[i]].special_type == k_route_special_type_gate ) + gates[sj ++] = r->nodes[stack[i]].special_id; /* * run versions & times must always ASCEND apart from exactly once, where @@ -167,49 +179,98 @@ static void world_routes_verify_run( u32 route, double new_pass_time ) vg_info("Verifying run (%u)\n", route); - u32 descend_allowance = 1; + u32 offset = 0xffffffff; + + vg_info( " ver: %u\n", r->current_run_version ); + + for( u32 i=0; igates[gates[i]]; + u32 na = r->nodes[r->nodes[pa->node_id].next[0]].special_id; + struct route_collector *pca = &r->collectors[ na ]; + + if( pa->passed_version != r->current_run_version ) + { + vg_info( " [%u]: %u (%f)\n", gates[i], pa->passed_version, + pca->time_passed ); + } + else + { + vg_info( " [%u]: %u (%f & %f)\n", gates[i], pa->passed_version, + pca->time_passed, + new_pass_time ); + offset = i; + } + } + + if( offset == 0xffffffff ) + { + /* If we don't find the emitter we passed through, we've only just + * started this route, so no blocks need to be emmited */ + return; + } + double lap_time = 0.0; + int verify_count = 0; for( u32 i=0; igates[stack[i]], - *pb = &r->gates[stack[(i+1) % sj]]; + u32 j = i+offset; + struct route_gate *pa = &r->gates[gates[j%sj]], + *pb = &r->gates[gates[(j+1) % sj]]; + + u32 na = r->nodes[r->nodes[pa->node_id].next[0]].special_id, + nb = r->nodes[r->nodes[pb->node_id].next[0]].special_id; + + struct route_collector *pca = &r->collectors[ na ], + *pcb = &r->collectors[ nb ]; - vg_info( " pa: %u, pb: %u\n", pa->passed_version, pb->passed_version ); - - int version_inorder = 0; double diff = 0.0; - if( pb->passed_version == pa->passed_version+1 ) + /* Verifying the path: either of this conditions must be true */ + int verified = 0; + if( pa->passed_version == r->current_run_version ) { - version_inorder = 1; - diff = pb->time_passed - pa->time_passed; + /* The version should drop back down to pa+1-sj */ } - else if( pb->passed_version == pa->passed_version+1-sj && - pa->passed_version+1 == r->current_run_version ) + else { - version_inorder = 1; - diff = new_pass_time - pa->time_passed; + /* The version should be pa+1 */ } + + verify_count += verified; - if( !version_inorder ) - return; - + if( pb->passed_version == r->current_run_version ) + { + /* we need to use new val */ + diff = new_pass_time - pca->time_passed; + vg_info( " LOOP %f\n", diff ); + } + else + { + diff = pcb->time_passed - pca->time_passed; + vg_info( " %f\n", diff ); + } + lap_time += diff; } - /* We've now verified the run was completed correctly */ - vg_success( "Lap time set. route %u: %lf\n", route, lap_time ); + /* Verify count is how many blocks we want to emit */ } static void world_routes_activate_gate( u32 id ) { struct subworld_routes *r = subworld_routes(); - struct route_gate *ig = &r->gates[id]; - struct route_node *pnode = &r->nodes[ig->node_id], + struct route_gate *rg = &r->gates[id]; + struct route_node *pnode = &r->nodes[rg->node_id], *pdest = &r->nodes[pnode->next[0]]; + struct route_collector *rc = &r->collectors[ pdest->special_id ]; + r->active_gate = id; + rg->passed_version = r->current_run_version; + + vg_info( "collector updated: %u\n", pdest->special_id ); for( u32 i=0; iroute_count; i++ ) { @@ -227,8 +288,7 @@ static void world_routes_activate_gate( u32 id ) } } - ig->time_passed = vg_time; - ig->passed_version = r->current_run_version; + rc->time_passed = vg_time; r->current_run_version ++; } @@ -239,7 +299,7 @@ static void world_routes_debug(void) for( int i=0; inode_count; i++ ) { struct route_node *rn = &r->nodes[i]; - vg_line_pt3( rn->co, 1.0f, rn->is_gate? 0xffffff00: 0xff00b2ff ); + vg_line_pt3( rn->co, 1.0f, rn->special_type? 0xffffff00: 0xff00b2ff ); } for( int i=0; iroute_count; i++ ) @@ -317,7 +377,7 @@ static void world_routes_gen_meshes(void) *rnk = &r->nodes[ stack[sk] ], *rnl; - if( rnj->is_gate && rnk->is_gate ) + if( rnj->special_type && rnk->special_type ) { last_valid = 0; continue; @@ -326,7 +386,7 @@ static void world_routes_gen_meshes(void) float base_x0 = (float)rnj->ref_count*-0.5f + (float)rnj->current_refs, base_x1 = (float)rnk->ref_count*-0.5f + (float)rnk->current_refs; - if( rnk->is_gate ) + if( rnk->special_type ) { rnl = &r->nodes[ rnk->next[0] ]; base_x1 = (float)rnl->ref_count*-0.5f + (float)rnl->current_refs; @@ -501,20 +561,17 @@ static void world_routes_loadfrom( mdl_header *mdl ) v3_copy( transform[3], rn->co ); rn->ref_count = 0; rn->current_refs = 0; + rn->special_type = 0; + rn->special_id = 0; if( pnode->classtype == k_classtype_gate ) { - r->gates = buffer_reserve( r->gates, r->gate_count, &r->gate_cap, - 1, sizeof( struct route_gate ) ); - struct classtype_gate *inf = mdl_get_entdata( mdl, pnode ); /* H is later scaled based on link distance */ v3_normalize( rn->h ); rn->next[0] = inf->target; rn->next[1] = 0; - rn->gate_id = r->gate_count; - rn->is_gate = 1; /* TODO */ if( inf->target ) @@ -523,10 +580,13 @@ static void world_routes_loadfrom( mdl_header *mdl ) if( pother->classtype == k_classtype_gate ) { + r->gates = buffer_reserve( r->gates, r->gate_count, + &r->gate_cap, + 1, sizeof( struct route_gate ) ); + struct route_gate *rg = &r->gates[r->gate_count]; rg->node_id = r->node_count; - rg->passed_version = 0; - rg->time_passed = 0.0; + rg->passed_version = 0xffffffff; v3_copy( pnode->co, rg->gate.co[0] ); v3_copy( pother->co, rg->gate.co[1] ); @@ -535,17 +595,33 @@ static void world_routes_loadfrom( mdl_header *mdl ) v2_copy( inf->dims, rg->gate.dims ); gate_transform_update( &rg->gate ); + rn->special_type = k_route_special_type_gate; + rn->special_id = r->gate_count; r->gate_count ++; } } + + if( rn->special_type == 0 ) + { + r->collectors = buffer_reserve( + r->collectors, r->collector_count, &r->collector_cap, + 1, sizeof( struct route_collector )); + + struct route_collector *rc = &r->collectors[r->collector_count]; + rc->time_passed = 0.0; + + rn->special_type = k_route_special_type_collector; + rn->special_id = r->collector_count; + + r->collector_count ++; + } } else { struct classtype_route_node *inf = mdl_get_entdata( mdl, pnode ); rn->next[0] = inf->target; rn->next[1] = inf->target1; - rn->is_gate = 0; } r->node_count ++; -- 2.25.1