From: hgn Date: Tue, 11 Jul 2023 01:50:20 +0000 (+0100) Subject: rewind full X-Git-Url: https://harrygodden.com/git/?a=commitdiff_plain;h=bf8478e3656ae729248a594a57d111f08bed41e0;p=carveJwlIkooP6JGAAIwe30JlM.git rewind full --- diff --git a/input.h b/input.h index fe387cc..cd5f826 100644 --- a/input.h +++ b/input.h @@ -25,6 +25,9 @@ enum sr_bind{ k_srbind_mback, k_srbind_maccept, k_srbind_mopen, + k_srbind_replay_play, + k_srbind_replay_freecam, + k_srbind_replay_resume, k_srbind_max, }; @@ -39,6 +42,8 @@ enum sr_axis{ k_sraxis_grab = 0, k_sraxis_mbrowse_h, k_sraxis_mbrowse_v, + k_sraxis_replay_h, + k_sraxis_max }; @@ -67,8 +72,7 @@ static const char *controller_glyphs[ SDL_CONTROLLER_BUTTON_MAX ][2] = [ SDL_CONTROLLER_BUTTON_GUIDE ] = { "\x91", "\x91" }, }; -static const char *controller_glyph( u32 sdl_index ) -{ +static const char *controller_glyph( u32 sdl_index ){ if( vg_input.display_input_type == SDL_CONTROLLER_TYPE_PS3 || vg_input.display_input_type == SDL_CONTROLLER_TYPE_PS4 || vg_input.display_input_type == SDL_CONTROLLER_TYPE_PS5 ) @@ -109,7 +113,10 @@ static const char *button_display_string( enum sr_bind button ) [k_srbind_mdown] = controller_glyph( SDL_CONTROLLER_BUTTON_DPAD_DOWN ), [k_srbind_mback] = controller_glyph( SDL_CONTROLLER_BUTTON_B ), [k_srbind_maccept]= controller_glyph( SDL_CONTROLLER_BUTTON_A ), - [k_srbind_mopen] = controller_glyph( SDL_CONTROLLER_BUTTON_GUIDE ) + [k_srbind_mopen] = controller_glyph( SDL_CONTROLLER_BUTTON_GUIDE ), +[k_srbind_replay_play]= controller_glyph( SDL_CONTROLLER_BUTTON_A ), +[k_srbind_replay_freecam]=controller_glyph(SDL_CONTROLLER_BUTTON_Y ), +[k_srbind_replay_resume]=controller_glyph( SDL_CONTROLLER_BUTTON_LEFTSHOULDER ) }; const char *keyboard_table[ k_srbind_max ] = { @@ -128,6 +135,9 @@ static const char *button_display_string( enum sr_bind button ) [k_srbind_mback] = "\xa3", [k_srbind_maccept]= "\xa2", [k_srbind_mopen] = "\xa3" , +[k_srbind_replay_play]= "\xa1", +[k_srbind_replay_freecam] = KEYBOARD_GLYPH( "F" ), +[k_srbind_replay_resume]=KEYBOARD_GLYPH( "R" ) }; if( vg_input.display_input_method == k_input_method_controller ) @@ -141,13 +151,15 @@ static const char *axis_display_string( enum sr_axis axis ) const char *controller_table[ k_sraxis_max ] = { [k_sraxis_grab] = "\x90", [k_sraxis_mbrowse_h] = "\x88", - [k_sraxis_mbrowse_v] = "\x89" + [k_sraxis_mbrowse_v] = "\x89", + [k_sraxis_replay_h] = "\x88" }; const char *keyboard_table[ k_sraxis_max ] = { [k_sraxis_grab] = "\x9e", [k_sraxis_mbrowse_h] = KEYBOARD_GLYPH("\x93")KEYBOARD_GLYPH("\x95"), - [k_sraxis_mbrowse_v] = KEYBOARD_GLYPH("\x96")KEYBOARD_GLYPH("\x94") + [k_sraxis_mbrowse_v] = KEYBOARD_GLYPH("\x96")KEYBOARD_GLYPH("\x94"), + [k_sraxis_replay_h] = KEYBOARD_GLYPH("\x93")KEYBOARD_GLYPH("\x95"), }; if( vg_input.display_input_method == k_input_method_controller ) @@ -231,8 +243,7 @@ static void joystick_state( enum sr_joystick joystick, v2f state ) v2_copy( srinput.joystick_states[ joystick ][0], state ); } -static float axis_state( enum sr_axis axis ) -{ +static float axis_state( enum sr_axis axis ){ if( vg_ui.wants_mouse ) return 0.0f; else return srinput.axis_states[axis][0]; } @@ -282,6 +293,9 @@ static void skaterift_preupdate_inputs(void) setbtn( k_srbind_maccept, vg_getkey(SDLK_e) ); setbtn( k_srbind_maccept, vg_getkey(SDLK_RETURN)); setbtn( k_srbind_maccept, vg_getkey(SDLK_RETURN2)); + setbtn( k_srbind_replay_play, vg_getkey(SDLK_SPACE) ); + setbtn( k_srbind_replay_freecam, vg_getkey(SDLK_f) ); + setbtn( k_srbind_replay_resume, vg_getkey(SDLK_r) ); /* axis * --------------------------------------------*/ @@ -300,10 +314,15 @@ static void skaterift_preupdate_inputs(void) srinput.axis_states[ k_sraxis_mbrowse_v ][0] -= 1.0f; if( vg_getkey( SDLK_UP ) ) srinput.axis_states[ k_sraxis_mbrowse_v ][0] += 1.0f; - if( vg_getkey( SDLK_LEFT ) ) + + if( vg_getkey( SDLK_LEFT ) ){ srinput.axis_states[ k_sraxis_mbrowse_h ][0] -= 1.0f; - if( vg_getkey( SDLK_RIGHT ) ) + srinput.axis_states[ k_sraxis_replay_h ][0] -= 1.0f; + } + if( vg_getkey( SDLK_RIGHT ) ){ srinput.axis_states[ k_sraxis_mbrowse_h ][0] += 1.0f; + srinput.axis_states[ k_sraxis_replay_h ][0] += 1.0f; + } if( vg_input.active_controller_index >= 0 ){ struct vg_controller *controller = @@ -326,15 +345,19 @@ static void skaterift_preupdate_inputs(void) setbtn( k_srbind_maccept,buttons[ SDL_CONTROLLER_BUTTON_A ] ); setbtn( k_srbind_mopen, buttons[ SDL_CONTROLLER_BUTTON_START ] ); setbtn( k_srbind_mback, buttons[ SDL_CONTROLLER_BUTTON_START ] ); + setbtn( k_srbind_replay_resume, + buttons[ SDL_CONTROLLER_BUTTON_LEFTSHOULDER ] ); + setbtn( k_srbind_replay_play, buttons[ SDL_CONTROLLER_BUTTON_A ] ); + setbtn( k_srbind_replay_freecam, buttons[ SDL_CONTROLLER_BUTTON_Y ] ); float *axis = controller->axises; - float *steer = srinput.joystick_states[ k_srjoystick_steer ][0], *look = srinput.joystick_states[ k_srjoystick_look ][0], *grab = srinput.joystick_states[ k_srjoystick_grab ][0], *axisgrab = &srinput.axis_states[ k_sraxis_grab ][0], *axisbrowseh = &srinput.axis_states[ k_sraxis_mbrowse_h ][0], - *axisbrowsev = &srinput.axis_states[ k_sraxis_mbrowse_v ][0]; + *axisbrowsev = &srinput.axis_states[ k_sraxis_mbrowse_v ][0], + *axisreplayh = &srinput.axis_states[ k_sraxis_replay_h ][0]; steer[0] += axis[ SDL_CONTROLLER_AXIS_LEFTX ]; steer[1] += axis[ SDL_CONTROLLER_AXIS_LEFTY ]; @@ -345,6 +368,7 @@ static void skaterift_preupdate_inputs(void) axisgrab[0] += vg_maxf( 0.0f, axis[ SDL_CONTROLLER_AXIS_TRIGGERRIGHT ] ); axisbrowseh[0] += axis[ SDL_CONTROLLER_AXIS_LEFTX ]; axisbrowsev[0] += axis[ SDL_CONTROLLER_AXIS_LEFTY ]; + axisreplayh[0] += axis[ SDL_CONTROLLER_AXIS_LEFTX ]; float lh = axis[ SDL_CONTROLLER_AXIS_LEFTX ], lv = axis[ SDL_CONTROLLER_AXIS_LEFTY ], diff --git a/player.c b/player.c index d248aec..b0888ea 100644 --- a/player.c +++ b/player.c @@ -7,6 +7,7 @@ #include "input.h" #include "world.h" #include "audio.h" +#include "player_replay.h" VG_STATIC int localplayer_cmd_respawn( int argc, const char *argv[] ) { @@ -171,6 +172,8 @@ void player__pass_gate( player_instance *player, ent_gate *gate ) audio_lock(); audio_oneshot( &audio_gate_pass, 1.0f, 0.0f ); audio_unlock(); + + replay_clear( &skaterift.replay ); } VG_STATIC void player_apply_transport_to_cam( m4x3f transport ) @@ -252,6 +255,7 @@ PLAYER_API void player__setpos( player_instance *player, v3f pos ){ } PLAYER_API void player__spawn( player_instance *player, ent_spawn *rp ){ + replay_clear( &skaterift.replay ); player__setpos( player, rp->transform.co ); v3_zero( player->rb.w ); q_identity( player->rb.q ); diff --git a/player_replay.c b/player_replay.c index 47da357..ed0c644 100644 --- a/player_replay.c +++ b/player_replay.c @@ -2,6 +2,7 @@ #define PLAYER_REPLAY_C #include "player_replay.h" +#include "input.h" VG_STATIC void replay_clear( replay_buffer *replay ){ replay->head = NULL; @@ -303,12 +304,27 @@ void skaterift_record_frame( replay_buffer *replay, int force_gamestate ){ res->type = k_player_animation_type_absolute; struct skeleton *sk = &localplayer.playeravatar->sk; - skeleton_decompose_mtx_absolute( sk, res->pose ); memcpy( &frame->board_pose, &localplayer.board_pose, sizeof(localplayer.board_pose) ); frame->time = vg.time; v3_copy( localplayer.cam.pos, frame->cam_pos ); + + if( localplayer.gate_waiting ){ + m4x3_mulv( localplayer.gate_waiting->transport, + frame->cam_pos, frame->cam_pos ); + + for( u32 i=1; ibone_count; i++ ){ + struct skeleton_bone *sb = &sk->bones[i]; + mdl_keyframe *kf = &res->pose[i-1]; + m4x3f mtx; + m4x3_mul( localplayer.gate_waiting->transport, sk->final_mtx[i], mtx ); + m4x3_decompose( mtx, kf->co, kf->q, kf->s ); + } + } + else + skeleton_decompose_mtx_absolute( sk, res->pose ); + v3_copy( localplayer.cam.angles, frame->cam_angles ); frame->cam_fov = localplayer.cam.fov; } @@ -371,9 +387,6 @@ void skaterift_restore_frame( replay_frame *frame ){ VG_STATIC void skaterift_replay_pre_update(void){ if( skaterift.activity != k_skaterift_replay ) return; - f64 speed = vg.time_frame_delta * 1.0; - f64 target = skaterift.replay.cursor; - if( skaterift.replay_control == k_replay_control_resume ){ if( skaterift.replay.cursor_frame == skaterift.resume_target || skaterift.replay.cursor_frame == NULL ){ @@ -386,7 +399,7 @@ VG_STATIC void skaterift_replay_pre_update(void){ if( skaterift.resume_transition >= 1.0f ) skaterift_restore_frame( skaterift.resume_target ); else { - target = vg_lerp( skaterift.resume_begin, + f64 target = vg_lerp( skaterift.resume_begin, skaterift.resume_target->time, vg_smoothstepf( skaterift.resume_transition ) ); replay_seek( &skaterift.replay, target ); @@ -394,26 +407,28 @@ VG_STATIC void skaterift_replay_pre_update(void){ } } else { - if( vg_getkey( SDLK_9 ) ){ - target -= speed; - skaterift.replay_control = k_replay_control_scrub; - replay_seek( &skaterift.replay, target ); - } - if( vg_getkey( SDLK_0 ) ){ - target += speed; + if( button_down( k_srbind_replay_play ) ) + skaterift.replay_control = k_replay_control_play; + + f32 target_speed = axis_state( k_sraxis_replay_h ) * 5.0; + + if( fabsf(target_speed) > 0.01f ) skaterift.replay_control = k_replay_control_scrub; - replay_seek( &skaterift.replay, target ); - } - if( vg_getkey( SDLK_7 ) ) - skaterift.replay_control = k_replay_control_play; + if( skaterift.replay_control == k_replay_control_play ) + target_speed = 1.0; + + vg_slewf( &skaterift.track_velocity, target_speed, + 10.0f*vg.time_frame_delta ); + + if( fabsf( skaterift.track_velocity ) > 0.0001f ){ + f64 target = skaterift.replay.cursor; + target += skaterift.track_velocity * vg.time_frame_delta; - if( skaterift.replay_control == k_replay_control_play ){ - target += vg.time_frame_delta; replay_seek( &skaterift.replay, target ); } - if( vg_getkey( SDLK_8 ) ){ + if( button_down( k_srbind_replay_resume ) ){ replay_frame *prev = replay_find_recent_stateframe(&skaterift.replay); if( prev ){ @@ -423,6 +438,13 @@ VG_STATIC void skaterift_replay_pre_update(void){ skaterift.resume_transition = 0.0f; } } + else if( button_down( k_srbind_mback ) ){ + if( skaterift.replay.statehead ) + skaterift_restore_frame( skaterift.replay.statehead ); + else + skaterift.activity = k_skaterift_default; + srinput.enabled = 0; + } } } @@ -472,7 +494,7 @@ VG_STATIC void skaterift_replay_imgui(void){ char buffer[ 128 ]; /* mainbar */ - ui_px height = 20, + ui_px height = 32, cwidth = 2; ui_rect bar = { 0, vg.window_y - height, vg.window_x, height }; ui_fill( bar, ui_colour( k_ui_bg ) ); @@ -516,6 +538,12 @@ VG_STATIC void skaterift_replay_imgui(void){ snprintf( buffer, 128, "-%.2fs\n", len ); ui_text( bar, buffer, 1, k_ui_align_middle_left, 0 ); ui_text( bar, "0s", 1, k_ui_align_middle_right, 0 ); + + ui_rect info = { 0, vg.window_y-bar[3]-64, 128, 64 }; + if( vg_input.display_input_method == k_input_method_controller ) + ui_text( info, "scrub: <- LS ->\nresume:LB\nplay: A", 1,0,0 ); + else + ui_text( info, "scrub: <- ->\nresume:R\nplay: space", 1,0,0 ); } #endif /* PLAYER_REPLAY_C */ diff --git a/player_replay.h b/player_replay.h index 91b9f72..9a3f2ab 100644 --- a/player_replay.h +++ b/player_replay.h @@ -64,6 +64,7 @@ VG_STATIC replay_frame *replay_find_recent_stateframe( replay_buffer *replay ); VG_STATIC void replay_get_camera( replay_buffer *replay, camera *cam ); VG_STATIC void replay_get_frame_camera( replay_frame *frame, camera *cam ); VG_STATIC f32 replay_subframe_time( replay_buffer *replay ); +VG_STATIC void replay_clear( replay_buffer *replay ); VG_STATIC void skaterift_replay_pre_update(void); VG_STATIC void skaterift_replay_imgui(void); diff --git a/shaders/blitblur.fs b/shaders/blitblur.fs index 65f4ea2..1d3bdfa 100644 --- a/shaders/blitblur.fs +++ b/shaders/blitblur.fs @@ -3,28 +3,43 @@ uniform sampler2D uTexMain; uniform sampler2D uTexMotion; uniform float uBlurStrength; uniform vec2 uOverrideDir; +uniform float uTime; +uniform float uGlitchStrength; in vec2 aUv; -vec2 rand_hash22( vec2 p ) -{ +vec2 rand_hash22( vec2 p ){ vec3 p3 = fract(vec3(p.xyx) * 213.8976123); p3 += dot(p3, p3.yzx+19.19); return fract(vec2((p3.x + p3.y)*p3.z, (p3.x+p3.z)*p3.y)); } -void main() -{ - vec2 vcenter = (aUv-vec2(0.5))*vec2(2.0); - vec2 vrand = rand_hash22( aUv ) * 2.0 - vec2(1.0); +const int NOISE_LOOP = 3; +vec3 digital_noise( uvec3 iuv ){ + iuv *=uvec3(8,2524,7552); + for( int i=0; i 0.0 ){ + uvec3 p = uvec3( gl_FragCoord.xy, uint(uTime*30.0) ); + vec2 g = digital_noise(p).xy; + vuv = aUv + g.xy*uGlitchStrength - uGlitchStrength*0.5; + } + + vec2 vrand = rand_hash22( vuv ) * 2.0 - vec2(1.0); vec2 vrand1 = rand_hash22( vrand ) * 2.0 - vec2(1.0); - vec2 vdir = texture( uTexMotion, aUv ).xy * uBlurStrength + uOverrideDir; + vec2 vdir = texture( uTexMotion, vuv ).xy * uBlurStrength + uOverrideDir; - vec4 vcolour0 = texture( uTexMain, aUv + vdir*vrand.x ); - vec4 vcolour1 = texture( uTexMain, aUv + vdir*vrand.y ); - vec4 vcolour2 = texture( uTexMain, aUv + vdir*vrand1.x ); - vec4 vcolour3 = texture( uTexMain, aUv + vdir*vrand1.y ); + vec4 vcolour0 = texture( uTexMain, vuv + vdir*vrand.x ); + vec4 vcolour1 = texture( uTexMain, vuv + vdir*vrand.y ); + vec4 vcolour2 = texture( uTexMain, vuv + vdir*vrand1.x ); + vec4 vcolour3 = texture( uTexMain, vuv + vdir*vrand1.y ); FragColor = ( vcolour0 + vcolour1 + vcolour2 + vcolour3 ) * 0.25; } diff --git a/shaders/blitblur.h b/shaders/blitblur.h index ac5f784..5de8e0a 100644 --- a/shaders/blitblur.h +++ b/shaders/blitblur.h @@ -29,28 +29,43 @@ static struct vg_shader _shader_blitblur = { "uniform sampler2D uTexMotion;\n" "uniform float uBlurStrength;\n" "uniform vec2 uOverrideDir;\n" +"uniform float uTime;\n" +"uniform float uGlitchStrength;\n" "\n" "in vec2 aUv;\n" "\n" -"vec2 rand_hash22( vec2 p )\n" -"{\n" +"vec2 rand_hash22( vec2 p ){\n" " vec3 p3 = fract(vec3(p.xyx) * 213.8976123);\n" " p3 += dot(p3, p3.yzx+19.19);\n" " return fract(vec2((p3.x + p3.y)*p3.z, (p3.x+p3.z)*p3.y));\n" "}\n" "\n" -"void main()\n" -"{\n" -" vec2 vcenter = (aUv-vec2(0.5))*vec2(2.0);\n" -" vec2 vrand = rand_hash22( aUv ) * 2.0 - vec2(1.0);\n" +"const int NOISE_LOOP = 3;\n" +"vec3 digital_noise( uvec3 iuv ){\n" +" iuv *=uvec3(8,2524,7552);\n" +" for( int i=0; i 0.0 ){\n" +" uvec3 p = uvec3( gl_FragCoord.xy, uint(uTime*30.0) );\n" +" vec2 g = digital_noise(p).xy;\n" +" vuv = aUv + g.xy*uGlitchStrength - uGlitchStrength*0.5;\n" +" }\n" +"\n" +" vec2 vrand = rand_hash22( vuv ) * 2.0 - vec2(1.0);\n" " vec2 vrand1 = rand_hash22( vrand ) * 2.0 - vec2(1.0);\n" " \n" -" vec2 vdir = texture( uTexMotion, aUv ).xy * uBlurStrength + uOverrideDir;\n" +" vec2 vdir = texture( uTexMotion, vuv ).xy * uBlurStrength + uOverrideDir;\n" "\n" -" vec4 vcolour0 = texture( uTexMain, aUv + vdir*vrand.x );\n" -" vec4 vcolour1 = texture( uTexMain, aUv + vdir*vrand.y );\n" -" vec4 vcolour2 = texture( uTexMain, aUv + vdir*vrand1.x );\n" -" vec4 vcolour3 = texture( uTexMain, aUv + vdir*vrand1.y );\n" +" vec4 vcolour0 = texture( uTexMain, vuv + vdir*vrand.x );\n" +" vec4 vcolour1 = texture( uTexMain, vuv + vdir*vrand.y );\n" +" vec4 vcolour2 = texture( uTexMain, vuv + vdir*vrand1.x );\n" +" vec4 vcolour3 = texture( uTexMain, vuv + vdir*vrand1.y );\n" "\n" " FragColor = ( vcolour0 + vcolour1 + vcolour2 + vcolour3 ) * 0.25;\n" "}\n" @@ -62,6 +77,8 @@ static GLuint _uniform_blitblur_uTexMain; static GLuint _uniform_blitblur_uTexMotion; static GLuint _uniform_blitblur_uBlurStrength; static GLuint _uniform_blitblur_uOverrideDir; +static GLuint _uniform_blitblur_uTime; +static GLuint _uniform_blitblur_uGlitchStrength; static void shader_blitblur_uInverseRatio(v2f v){ glUniform2fv(_uniform_blitblur_uInverseRatio,1,v); } @@ -77,6 +94,12 @@ static void shader_blitblur_uBlurStrength(float f){ static void shader_blitblur_uOverrideDir(v2f v){ glUniform2fv(_uniform_blitblur_uOverrideDir,1,v); } +static void shader_blitblur_uTime(float f){ + glUniform1f(_uniform_blitblur_uTime,f); +} +static void shader_blitblur_uGlitchStrength(float f){ + glUniform1f(_uniform_blitblur_uGlitchStrength,f); +} static void shader_blitblur_register(void){ vg_shader_register( &_shader_blitblur ); } @@ -87,5 +110,7 @@ static void shader_blitblur_link(void){ _uniform_blitblur_uTexMotion = glGetUniformLocation( _shader_blitblur.id, "uTexMotion" ); _uniform_blitblur_uBlurStrength = glGetUniformLocation( _shader_blitblur.id, "uBlurStrength" ); _uniform_blitblur_uOverrideDir = glGetUniformLocation( _shader_blitblur.id, "uOverrideDir" ); + _uniform_blitblur_uTime = glGetUniformLocation( _shader_blitblur.id, "uTime" ); + _uniform_blitblur_uGlitchStrength = glGetUniformLocation( _shader_blitblur.id, "uGlitchStrength" ); } #endif /* SHADER_blitblur_H */ diff --git a/skaterift.c b/skaterift.c index 20b686b..a6d8d8d 100644 --- a/skaterift.c +++ b/skaterift.c @@ -14,7 +14,7 @@ #if 1 #define SR_NETWORKED -#define VG_DEVWINDOW +//#define VG_DEVWINDOW /* * system headers @@ -169,7 +169,7 @@ VG_STATIC void vg_load(void){ vg_loader_step( load_playermodels, NULL ); /* player setup */ - u32 bytes = (1024*1024*1)/2; + u32 bytes = 1024*1024*10; skaterift.replay.data = vg_linear_alloc( vg_mem.rtmemory, bytes ); skaterift.replay.size = bytes; replay_clear( &skaterift.replay ); @@ -282,7 +282,7 @@ VG_STATIC void vg_pre_update(void){ if( skaterift.activity & (k_skaterift_replay|k_skaterift_menu) ) target = 0; - vg_slewf( &skaterift.time_rate, target, vg.time_frame_delta * 6.0f ); + vg_slewf( &skaterift.time_rate, target, vg.time_frame_delta * (1.0f/0.3f) ); vg.time_rate = vg_smoothstepf( skaterift.time_rate ); player__pre_update( &localplayer ); @@ -358,6 +358,20 @@ VG_STATIC void present_view_with_post_processing(void){ (vg.time_frame_delta*60.0) ); shader_blitblur_uInverseRatio( inverse ); + static f64 effect_time = 133.0; + effect_time += vg.time_frame_delta; + shader_blitblur_uTime( effect_time ); + + f32 glitch_strength = 0.0f; + if( skaterift.activity == k_skaterift_replay ){ + glitch_strength = 0.005f; + if( skaterift.replay_control == k_replay_control_play ) + glitch_strength = 0.005f; + else + glitch_strength += 0.005f*skaterift.track_velocity; + } + shader_blitblur_uGlitchStrength( glitch_strength ); + v2f override; if( skaterift.activity == k_skaterift_menu ) v2_muls( (v2f){ 0.04f, 0.001f }, 1.0f-skaterift.time_rate, override ); @@ -442,10 +456,7 @@ VG_STATIC void skaterift_composite_maincamera(void){ vg_smoothstepf(global_skateshop.factive), &skaterift.cam ); if( skaterift.activity == k_skaterift_replay ){ - camera temp; - replay_get_camera( &skaterift.replay, &temp ); - camera_lerp( &skaterift.cam, &temp, 1.0f-skaterift.time_rate, - &skaterift.cam ); + replay_get_camera( &skaterift.replay, &skaterift.cam ); } skaterift.cam.nearz = 0.1f;