+ srinput.state = k_input_state_resume;
+ gui_helper_clear();
+ }
+
+ if( skaterift.freecam ){
+ camera *cam = &skaterift.replay_freecam;
+ v3f angles;
+ v3_copy( cam->angles, angles );
+ player_look( angles, 1.0f );
+
+ f32 decay = vg_maxf(0.0f,1.0f-vg.time_frame_delta*10.0f);
+
+ v3f d;
+ v3_sub( angles, cam->angles, d );
+ v3_muladds( skaterift.freecam_w, d, 20.0f, skaterift.freecam_w );
+ v3_muls( skaterift.freecam_w, decay, skaterift.freecam_w );
+ v3_muladds( cam->angles, skaterift.freecam_w, vg.time_frame_delta,
+ cam->angles );
+ cam->angles[1] = vg_clampf( cam->angles[1], -VG_PIf*0.5f,VG_PIf*0.5f);
+
+ camera_update_transform( cam );
+
+ v3f lookdir = { 0.0f, 0.0f, -1.0f },
+ sidedir = { 1.0f, 0.0f, 0.0f };
+
+ m3x3_mulv( cam->transform, lookdir, lookdir );
+ m3x3_mulv( cam->transform, sidedir, sidedir );
+
+ v2f input;
+ joystick_state( k_srjoystick_steer, input );
+ v2_muls( input, vg.time_frame_delta*6.0f*20.0f, input );
+
+ v3_muladds( skaterift.freecam_v, lookdir, -input[1],
+ skaterift.freecam_v );
+ v3_muladds( skaterift.freecam_v, sidedir, input[0],
+ skaterift.freecam_v );
+
+ v3_muls( skaterift.freecam_v, decay, skaterift.freecam_v );
+ v3_muladds( cam->pos,
+ skaterift.freecam_v, vg.time_frame_delta, cam->pos );
+ }
+ else {
+ if( button_down( k_srbind_replay_resume ) ){
+ skaterift_replay_resume();
+ }
+ }
+ }
+}
+
+static void skaterift_replay_update_helpers(void){
+ skaterift.helper_resume->greyed = skaterift.freecam;
+
+ vg_str freecam_text;
+ vg_strnull( &freecam_text, skaterift.helper_freecam->text,
+ GUI_HELPER_TEXT_LENGTH );
+ vg_strcat( &freecam_text, skaterift.freecam? "exit freecam": "freecam" );
+}
+
+static void skaterift_replay_post_render(void){
+ if( world_static.active_instance != k_world_purpose_client )
+ return;
+
+ /* capture the current resume frame at the very last point */
+ if( button_down( k_srbind_reset ) ){
+ if( skaterift.activity == k_skaterift_default ){
+ skaterift.activity = k_skaterift_replay;
+ skaterift_record_frame( &skaterift.replay, 1 );
+ if( skaterift.replay.head ){
+ skaterift.replay.cursor = skaterift.replay.head->time;
+ skaterift.replay.cursor_frame = skaterift.replay.head;
+ }
+ skaterift.replay_control = k_replay_control_scrub;
+
+ gui_helper_clear();
+ vg_str text;
+
+ if( gui_new_helper( input_axis_list[k_sraxis_replay_h], &text ) )
+ vg_strcat( &text, "scrub" );
+
+ if( (skaterift.helper_resume = gui_new_helper(
+ input_button_list[k_srbind_replay_resume], &text )) )
+ vg_strcat( &text, "resume" );
+
+ if( gui_new_helper( input_button_list[k_srbind_replay_play], &text ))
+ vg_strcat( &text, "playback" );
+
+ skaterift.helper_freecam = gui_new_helper(
+ input_button_list[k_srbind_replay_freecam], &text );
+
+ skaterift_replay_update_helpers();