From b93c61c54e7ac56f6808b9a563d3e4221ca8482e Mon Sep 17 00:00:00 2001
From: hgn <hgodden00@gmail.com>
Date: Thu, 20 Oct 2022 23:40:17 +0100
Subject: [PATCH] the coolest fucking thing ive ever made

---
 player.h       |  6 +++++-
 world.h        | 13 +++++++++++--
 world_render.h |  2 +-
 world_routes.h | 41 ++++++++++++++++++++++++-----------------
 world_water.h  |  2 +-
 5 files changed, 42 insertions(+), 22 deletions(-)

diff --git a/player.h b/player.h
index fc435dc..442d03e 100644
--- a/player.h
+++ b/player.h
@@ -374,16 +374,20 @@ static void player_update_post(void)
       {
          player.rewinding = 0;
          player.rewind_length = 1;
+         world.sky_target_rate = 1.0;
       }
       else
       {
+         world.sky_target_rate = -100.0;
          assert( player.rewind_length > 0 );
 
          v2f override_angles;
          v3f override_pos;
 
          float budget         = vg.time_delta,
-               overall_length = player.rewind_length*0.25f;
+               overall_length = player.rewind_length;
+
+         world_routes_rollback_time( player.rewind_time / overall_length );
 
          for( int i=0; (i<10)&&(player.rewind_time>0.0f)&&(budget>0.0f); i ++ )
          {
diff --git a/world.h b/world.h
index 7f8432a..ba5d5e4 100644
--- a/world.h
+++ b/world.h
@@ -124,7 +124,7 @@ static struct gworld
       }
       *routes;
 
-      double last_interaction;
+      double time, rewind_from, rewind_to, last_use;
 
       u32 route_count,
           route_cap;
@@ -193,6 +193,8 @@ static struct gworld
 #if 0
    traffic_driver van_man[6];
 #endif
+
+   double sky_time, sky_rate, sky_target_rate;
    
    /* Physics */
    
@@ -225,7 +227,7 @@ static struct gworld
    v3f render_gate_pos;
    int active_route_board;
 }
-world;
+world ;
 
 /*
  * API
@@ -254,6 +256,9 @@ static int ray_world( v3f pos, v3f dir, ray_hit *hit );
 
 static void world_init(void)
 {
+   world.sky_rate = 1.0;
+   world.sky_target_rate = 1.0;
+
    shader_terrain_register();
    shader_sky_register();
    shader_planeinf_register();
@@ -304,6 +309,10 @@ static void world_free( void *_ )
 
 static void world_update( v3f pos )
 {
+   world.sky_time += world.sky_rate * vg.time_delta;
+   world.sky_rate = vg_lerp( world.sky_rate, world.sky_target_rate, 
+                                 vg.time_delta * 10.0 );
+
    world_routes_update();
 #if 0
    world_routes_debug();
diff --git a/world_render.h b/world_render.h
index 5da3556..32a15ba 100644
--- a/world_render.h
+++ b/world_render.h
@@ -183,7 +183,7 @@ static void render_sky(m4x3f camera)
    shader_sky_uMdl(identity_matrix);
    shader_sky_uPv(full);
    shader_sky_uTexGarbage(0);
-   shader_sky_uTime( vg.time );
+   shader_sky_uTime( world.sky_time );
 
    vg_tex2d_bind( &tex_terrain_noise, 0 );
 
diff --git a/world_routes.h b/world_routes.h
index 07e35c7..8d85989 100644
--- a/world_routes.h
+++ b/world_routes.h
@@ -19,11 +19,6 @@ enum route_special_type
    k_route_special_type_collector = 2
 };
 
-static void world_routes_interact(void)
-{
-   world.routes.last_interaction = vg.time;
-}
-
 static void debug_sbpath( struct route_node *rna, struct route_node *rnb,
                           u32 colour, float xoffset )
 {
@@ -308,6 +303,8 @@ static void world_routes_ui_updatetime( u32 route, float time )
  */
 static void world_routes_ui_notch( u32 route, float time )
 {
+   return; /* FIXME: Temporarily disabled */
+
    struct subworld_routes *r = &world.routes;
    struct route *pr = &r->routes[route];
 
@@ -410,7 +407,7 @@ static void world_routes_ui_draw( u32 route, v4f colour, float offset )
    shader_routeui_use();
    glBindVertexArray( pr->ui.vao );
 
-   float fade_amt = vg.time - pr->ui.fade_timer_start;
+   float fade_amt = r->time - pr->ui.fade_timer_start;
    fade_amt = vg_clampf( fade_amt / 1.0f, 0.0f, 1.0f );
    
    float fade_block_size = 0.0f,
@@ -431,7 +428,7 @@ static void world_routes_ui_draw( u32 route, v4f colour, float offset )
    fade_colour[3] *= 1.0f-fade_amt;
 
    /* 1 minute timer */
-   float timer_delta = (vg.time - world.routes.last_interaction) * (1.0/45.0),
+   float timer_delta = (r->time - r->last_use) * (1.0/45.0),
          timer_scale = 1.0f - vg_minf( timer_delta, 1.0f );
 
    /* 
@@ -589,7 +586,7 @@ static void world_routes_verify_run( u32 route )
 
    pr->ui.fade_start = pr->ui.segment_start;
    pr->ui.fade_count = 0;
-   pr->ui.fade_timer_start = vg.time;
+   pr->ui.fade_timer_start = r->time;
 
    int orig_seg_count = pr->ui.segment_count;
 
@@ -612,7 +609,7 @@ static void world_routes_verify_run( u32 route )
       pr->ui.fade_count ++;
    }
 
-   r->routes[route].latest_pass = vg.time;
+   r->routes[route].latest_pass = r->time;
 }
 
 /*
@@ -620,18 +617,18 @@ static void world_routes_verify_run( u32 route )
  */
 static void world_routes_activate_gate( u32 id )
 {
-   world_routes_interact();
-
    struct subworld_routes *r = &world.routes;
    struct route_gate *rg = &r->gates[id];
    struct route_node *pnode = &r->nodes[rg->node_id],
                      *pdest = &r->nodes[pnode->next[0]];
 
+   r->last_use = r->time;
+
    struct route_collector *rc = &r->collectors[ pdest->special_id ];
 
    r->active_gate = id;
    rg->timing.version = r->current_run_version;
-   rg->timing.time = vg.time;
+   rg->timing.time = r->time;
    for( u32 i=0; i<r->route_count; i++ )
    {
       struct route *route = &r->routes[i];
@@ -653,7 +650,7 @@ static void world_routes_activate_gate( u32 id )
       {
          route->ui.fade_start = route->ui.segment_start;
          route->ui.fade_count = route->ui.segment_count;
-         route->ui.fade_timer_start = vg.time;
+         route->ui.fade_timer_start = r->time;
          world_routes_ui_clear(i);
 
          vg_success( "CLEARING -> %u %u \n", route->ui.fade_start,
@@ -664,7 +661,7 @@ static void world_routes_activate_gate( u32 id )
    r->current_run_version ++;
 
    rc->timing.version = r->current_run_version;
-   rc->timing.time = vg.time;
+   rc->timing.time = r->time;
    r->current_run_version ++;
 }
 
@@ -674,15 +671,24 @@ static void world_routes_activate_gate( u32 id )
 static void world_routes_notify_reset(void)
 {
    struct subworld_routes *r = &world.routes;
-   world_routes_interact();
+   r->rewind_from = r->time;
+   r->rewind_to = r->last_use;
 
+#if 0
    for( int i=0; i<r->route_count; i++ )
    {
       struct route *route = &r->routes[i];
 
       if( route->active )
-         world_routes_ui_notch( i, vg.time - route->latest_pass );
+         world_routes_ui_notch( i, r->time - route->latest_pass );
    }
+#endif
+}
+
+static void world_routes_rollback_time( double t )
+{
+   struct subworld_routes *r = &world.routes;
+   r->time = vg_lerp( r->rewind_to, r->rewind_from, t );
 }
 
 static void world_routes_debug(void)
@@ -1125,6 +1131,7 @@ static void world_routes_free(void*_)
 static void world_routes_update(void)
 {
    struct subworld_routes *r = &world.routes;
+   r->time += vg.time_delta;
 
    for( int i=0; i<r->route_count; i++ )
    {
@@ -1134,7 +1141,7 @@ static void world_routes_update(void)
 
       if( route->active )
       {
-         world_routes_ui_updatetime( i, vg.time - route->latest_pass );
+         world_routes_ui_updatetime( i, r->time - route->latest_pass );
       }
    }
 }
diff --git a/world_water.h b/world_water.h
index a4f6967..5b82b12 100644
--- a/world_water.h
+++ b/world_water.h
@@ -163,7 +163,7 @@ static void render_water_surface( m4x4f pv, m4x3f camera )
 
    fb_bindtex( &wrender.fbdepth, 3 );
    shader_water_uTexBack( 3 );
-   shader_water_uTime( vg.time );
+   shader_water_uTime( world.routes.time );
    shader_water_uCamera( camera[3] );
    shader_water_uSurfaceY( wrender.height );
 
-- 
2.25.1