From: hgn Date: Sat, 11 Dec 2021 00:38:34 +0000 (+0000) Subject: improved time management and pausing X-Git-Url: https://harrygodden.com/git/?p=fishladder.git;a=commitdiff_plain;h=315d9f4e88f3b0204b7161e25b01543849dbc8b7 improved time management and pausing --- diff --git a/fishladder.c b/fishladder.c index 3bb8aba..71b714b 100644 --- a/fishladder.c +++ b/fishladder.c @@ -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 // ========================================================================================================