improved time management and pausing
authorhgn <hgodden00@gmail.com>
Sat, 11 Dec 2021 00:38:34 +0000 (00:38 +0000)
committerhgn <hgodden00@gmail.com>
Sat, 11 Dec 2021 00:38:34 +0000 (00:38 +0000)
fishladder.c

index 3bb8abafc35f73c92b6cd40fb0e166c1d65c7fcf..71b714b53a731aa025dab5586f55f728ed89aed4 100644 (file)
@@ -63,7 +63,7 @@ enum e_world_button
 {
        k_world_button_none = -1,
        k_world_button_sim = 0,
-       k_world_button_ff = 1,
+       k_world_button_pause = 1,
        k_world_button_wire_mode = 2
 };
 
@@ -169,16 +169,18 @@ struct world
        *data;
 #pragma pack(pop)
        
-       int frame;
        
        int initialzed;
        
-       int sim_frame;
-       float sim_start;
        int sim_run, max_runs;
-       
-       float sim_speed;
-       float frame_lerp;
+
+       int sim_frame, sim_target;
+       float sim_internal_time,                // current tick-time 
+               sim_internal_ref,                               // Reference point of internal time
+               sim_delta_ref,                          // Reference point of vg_time when we started at current sim_speed
+               sim_delta_speed,                                // Rate to apply time delta
+               frame_lerp,                                             // Fractional part of sim_internal_time
+               pause_offset_target;                    // 
        
        struct cell_terminal
        {
@@ -1049,6 +1051,7 @@ static int is_simulation_running(void)
 static void simulation_stop(void)
 {
        world.buttons[ k_world_button_sim ].pressed = 0;
+       world.buttons[ k_world_button_pause ].pressed = 0;
        
        world.num_fishes = 0;
        world.sim_frame = 0;
@@ -1290,7 +1293,18 @@ void vg_update(void)
        // ========================================================================================================
        if( is_simulation_running() )
        {       
-               while( world.sim_frame < (int)((vg_time-world.sim_start)*world.sim_speed) )
+               if( !world.buttons[ k_world_button_pause ].pressed )
+               {
+                       world.sim_internal_time = world.sim_internal_ref + (vg_time-world.sim_delta_ref) * world.sim_delta_speed;
+               }
+               else
+               {
+                       world.sim_internal_time = vg_lerpf( world.sim_internal_time, world.sim_internal_ref + world.pause_offset_target, vg_time_delta*15.0f );
+               }
+               
+               world.sim_target = (int)floorf(world.sim_internal_time);
+               
+               while( world.sim_frame < world.sim_target )
                {
                        sfx_set_playrnd( &audio_random, &audio_system_balls_switching, 0, 9 );
 
@@ -1613,9 +1627,20 @@ void vg_update(void)
                                                vg_success( "Run passed, starting next\n" );
                                                world.sim_run ++;
                                                world.sim_frame = 0;
-                                               world.sim_start = vg_time;
+                                               world.sim_target = 0;
                                                world.num_fishes = 0;
                                                
+                                               // Reset timing reference points
+                                               world.sim_delta_ref = vg_time;
+                                               world.sim_internal_ref = 0.0f;
+                                               
+                                               if( world.buttons[ k_world_button_pause ].pressed )
+                                                       world.pause_offset_target = 0.5f;
+                                               else
+                                                       world.pause_offset_target = 0.0f;
+                                               
+                                               world.sim_internal_time = 0.0f;
+                                               
                                                for( int i = 0; i < world.w*world.h; i ++ )
                                                        world.data[ i ].state &= ~FLAG_FLIP_FLOP;
                                                
@@ -1658,9 +1683,7 @@ void vg_update(void)
                // Position update
                // =====================================================================================================
                
-               float scaled_time = 0.0f;
-               scaled_time = (vg_time-world.sim_start)*world.sim_speed;
-               world.frame_lerp = scaled_time - (float)world.sim_frame;
+               world.frame_lerp = world.sim_internal_time - floorf( world.sim_internal_time );
                
                for( int i = 0; i < world.num_fishes; i ++ )
                {
@@ -1812,6 +1835,29 @@ static void draw_numbers( v3f coord, int number )
        }
 }*/
 
+static void simulation_start(void)
+{
+       vg_success( "Starting simulation!\n" );
+                               
+       sfx_set_playrnd( &audio_rolls, &audio_system_balls_rolling, 0, 1 );
+       
+       world.num_fishes = 0;
+       world.sim_frame = 0;
+       world.sim_run = 0;
+       
+       world.sim_delta_speed = 2.5f;
+       world.sim_delta_ref = vg_time;
+       world.sim_internal_ref = 0.0f;
+       world.pause_offset_target = 0.0f;
+       
+       world.sim_target = 0;
+       
+       for( int i = 0; i < world.w*world.h; i ++ )
+               world.data[ i ].state &= ~FLAG_FLIP_FLOP;
+       
+       io_reset();
+}
+
 static void wbutton_run( enum e_world_button btn_name )
 {
        struct cell_button *btn = &world.buttons[btn_name];
@@ -1822,41 +1868,68 @@ static void wbutton_run( enum e_world_button btn_name )
        if( vg_get_button_up( "primary" ) && is_hovering )
        {
                // Click event
-               btn->pressed ^= 0x1;
-               
                if( btn_name == k_world_button_sim )
                {
-                       if( btn->pressed )
+                       if( world.buttons[ k_world_button_pause ].pressed )
                        {
-                               vg_success( "Starting simulation!\n" );
-                       
-                               sfx_set_playrnd( &audio_rolls, &audio_system_balls_rolling, 0, 1 );
-                               
-                               world.num_fishes = 0;
-                               world.sim_frame = 0;
-                               world.sim_start = vg_time;
-                               world.sim_run = 0;
-                               world.sim_speed = 2.5f;
-                               
-                               for( int i = 0; i < world.w*world.h; i ++ )
-                                       world.data[ i ].state &= ~FLAG_FLIP_FLOP;
+                               if( !btn->pressed )
+                               {
+                                       btn->pressed = 1;
+                                       simulation_start();
+                               }
                                
-                               io_reset();
+                               world.pause_offset_target += 1.0f;
                        }
                        else
                        {
-                               simulation_stop();
+                               btn->pressed ^= 0x1;
+                               
+                               if( btn->pressed )
+                                       simulation_start();
+                               else
+                                       simulation_stop();
+                       }
+               }
+               else if( btn_name == k_world_button_pause )
+               {
+                       btn->pressed ^= 0x1;
+               
+                       world.sim_internal_ref = world.sim_internal_time;
+                       world.sim_delta_ref = vg_time;
+                       
+                       if( btn->pressed )
+                       {
+                               float time_frac = world.sim_internal_time-floorf(world.sim_internal_time);
+                               world.pause_offset_target = 0.5f - time_frac;
                        }
+                       else
+                               world.pause_offset_target = 0.0f;
                }
        }
        
        // Drawing
-       if( btn->pressed ) btn->light_target = is_hovering? 0.9f: 0.8f;
-       else btn->light_target = is_hovering? 0.2f: 0.0f;
+       if( btn->pressed ) 
+       {
+               if( is_hovering )
+               {
+                       btn->light_target = 0.9f;
+               }
+               else
+               {
+                       if( btn_name == k_world_button_sim && world.buttons[ k_world_button_pause ].pressed )
+                               btn->light_target = fabsf(sinf( vg_time * 2.0f )) * 0.3f + 0.3f;
+                       else
+                               btn->light_target = 0.8f;
+               }
+       }
+       else 
+       {
+               btn->light_target = is_hovering? 0.2f: 0.0f;
+       }
 
        if( vg_get_button( "primary" ) && is_hovering )
                btn->light_target = 1.0f;
-
+       
        btn->light = vg_lerpf( btn->light, btn->light_target, vg_time_delta*26.0f );
        
        glUniform4f( SHADER_UNIFORM( shader_buttons, "uOffset" ), 
@@ -2047,7 +2120,7 @@ void vg_render(void)
        glUniform1i( SHADER_UNIFORM( shader_buttons, "uTexMain" ), 0 );
        
        wbutton_run( k_world_button_sim );
-       wbutton_run( k_world_button_ff );
+       wbutton_run( k_world_button_pause );
        
        // WIRES
        // ========================================================================================================