X-Git-Url: https://harrygodden.com/git/?a=blobdiff_plain;f=player_replay.c;h=47da357c4ede76fbd3ae0454a69ec649bd5a14ba;hb=cba8a468e166156dd8cab3358da369b1df76eb8b;hp=1215f62d3f13d893114226b73fd422ebe842bcb7;hpb=6c84fa207dec2cf8e92b3882492bdd2f92ee7afe;p=carveJwlIkooP6JGAAIwe30JlM.git diff --git a/player_replay.c b/player_replay.c index 1215f62..47da357 100644 --- a/player_replay.c +++ b/player_replay.c @@ -222,75 +222,206 @@ VG_STATIC void replay_get_camera( replay_buffer *replay, camera *cam ){ } } -VG_STATIC void skaterift_replay_pre_update(void){ - if( skaterift.activity != k_skaterift_replay ) return; +struct replay_rb{ + v3f co, v, w; + v4f q; +}; - f64 speed = 1.0; - f64 target = skaterift.replay.cursor; +VG_STATIC +void skaterift_record_frame( replay_buffer *replay, int force_gamestate ){ + f64 delta = 9999999.9, + statedelta = 9999999.9; + + if( replay->head ) + delta = vg.time - replay->head->time; + + if( replay->statehead ) + statedelta = vg.time - replay->statehead->time; + + const f64 k_replay_rate = 1.0/30.0, + k_gamestate_rate = 0.5; - if( vg_getkey( SDLK_9 ) ){ - target -= vg.time_frame_delta * speed; - skaterift.replay_control = k_replay_control_scrub; - replay_seek( &skaterift.replay, target ); + int save_frame = 0, + save_state = 0; + + if( force_gamestate ) save_state = 1; + if( statedelta > k_gamestate_rate ) save_state = 1; + if( delta > k_replay_rate ) save_frame = 1; + if( save_state ) save_frame = 1; + + if( !save_frame ) return; + + u32 gamestate_size = 0; + + if( save_state ){ + gamestate_size = (u32 []){ + [k_player_subsystem_walk ] = sizeof(struct player_walk_state), + [k_player_subsystem_drive] = 0, + [k_player_subsystem_skate] = sizeof(struct player_skate_state), + [k_player_subsystem_dead ] = localplayer.ragdoll.part_count * + sizeof(struct replay_rb) + }[ localplayer.subsystem ]; } - if( vg_getkey( SDLK_0 ) ){ - target += vg.time_frame_delta * speed; - skaterift.replay_control = k_replay_control_scrub; - replay_seek( &skaterift.replay, target ); + + replay_frame *frame = replay_newframe( replay, gamestate_size, 0 ); + + if( save_state ){ + replay_gamestate *gs = replay_frame_gamestate( frame ); + gs->system = localplayer.subsystem; + + /* permanent block */ + memcpy( &gs->rb, &localplayer.rb, sizeof(rigidbody) ); + memcpy( &gs->cam_control, &localplayer.cam_control, + sizeof(struct player_cam_controller) ); + v3_copy( localplayer.angles, gs->angles ); + + void *dst = replay_gamestate_subsystem_data( gs ); + + /* subsytem/dynamic block */ + if( localplayer.subsystem == k_player_subsystem_walk ) + memcpy( dst, &localplayer._walk.state, gamestate_size ); + else if( localplayer.subsystem == k_player_subsystem_skate ) + memcpy( dst, &localplayer._skate.state, gamestate_size ); + else if( localplayer.subsystem == k_player_subsystem_dead ){ + struct replay_rb *arr = dst; + for( u32 i=0; ico, arr[i].co ); + v3_copy( rb->w, arr[i].w ); + v3_copy( rb->v, arr[i].v ); + v4_copy( rb->q, arr[i].q ); + } + } } - if( vg_getkey( SDLK_7 ) ) - skaterift.replay_control = k_replay_control_play; + replay->cursor = vg.time; + replay->cursor_frame = frame; + + player_animation *res = &frame->anim; + v3_zero( res->root_co ); + q_identity( res->root_q ); + 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 ); + v3_copy( localplayer.cam.angles, frame->cam_angles ); + frame->cam_fov = localplayer.cam.fov; +} + +VG_STATIC +void skaterift_restore_frame( replay_frame *frame ){ + replay_gamestate *gs = replay_frame_gamestate( frame ); + void *src = replay_gamestate_subsystem_data( gs ); - if( skaterift.replay_control == k_replay_control_play ){ - target += vg.time_frame_delta; - replay_seek( &skaterift.replay, target ); + /* TODO: Move this to subsystem bindings now that its variable */ + if( gs->system == k_player_subsystem_walk ){ + memcpy( &localplayer._walk.state, src, + frame->subsystem_gamestate_size ); } + else if( gs->system == k_player_subsystem_skate ){ + memcpy( &localplayer._skate.state, src, + frame->subsystem_gamestate_size ); + } + else if( gs->system == k_player_subsystem_dead ){ + player__dead_transition( &localplayer ); + struct replay_rb *arr = src; - if( vg_getkey( SDLK_8 ) ){ - replay_frame *prev = replay_find_recent_stateframe( &skaterift.replay ); + for( u32 i=0; iobj.rb; - if( prev ){ - /* TODO: Make gamestate_apply function / swap ... */ - replay_gamestate *gs = replay_frame_gamestate( prev ); - void *src = replay_gamestate_subsystem_data( gs ); + v3_copy( arr[i].co, rb->co ); + v3_copy( arr[i].w, rb->w ); + v3_copy( arr[i].v, rb->v ); + v4_copy( arr[i].q, rb->q ); - if( gs->system == k_player_subsystem_walk ){ - memcpy( &localplayer._walk.state, src, - prev->subsystem_gamestate_size ); - } - else if( gs->system == k_player_subsystem_skate ){ - memcpy( &localplayer._skate.state, src, - prev->subsystem_gamestate_size ); - } - else if( gs->system == k_player_subsystem_dead ){ - player__dead_transition( &localplayer ); - memcpy( &localplayer.ragdoll, src, - prev->subsystem_gamestate_size ); - } + v3_copy( arr[i].co, part->prev_co ); + v4_copy( arr[i].q, part->prev_q ); + } + } - localplayer.subsystem = gs->system; + localplayer.subsystem = gs->system; - memcpy( &localplayer.rb, &gs->rb, sizeof(rigidbody) ); - v3_copy( gs->angles, localplayer.angles ); + memcpy( &localplayer.rb, &gs->rb, sizeof(rigidbody) ); + v3_copy( gs->angles, localplayer.angles ); - v3_copy( prev->cam_pos, localplayer.cam.pos ); - v3_copy( prev->cam_angles, localplayer.cam.angles ); - localplayer.cam.fov = prev->cam_fov; + v3_copy( frame->cam_pos, localplayer.cam.pos ); + v3_copy( frame->cam_angles, localplayer.cam.angles ); + localplayer.cam.fov = frame->cam_fov; - memcpy( &localplayer.cam_control, &gs->cam_control, - sizeof(struct player_cam_controller) ); + memcpy( &localplayer.cam_control, &gs->cam_control, + sizeof(struct player_cam_controller) ); - /* chop end off replay */ - prev->r = NULL; - skaterift.replay.statehead = prev; - skaterift.replay.head = prev; - skaterift.replay.cursor_frame = prev; - skaterift.replay.cursor = prev->time; + /* chop end off replay */ + frame->r = NULL; + skaterift.replay.statehead = frame; + skaterift.replay.head = frame; + skaterift.replay.cursor_frame = frame; + skaterift.replay.cursor = frame->time; + skaterift.replay_control = k_replay_control_scrub; + skaterift.activity = k_skaterift_default; + vg.time = frame->time; +} + +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 ){ + skaterift_restore_frame( skaterift.resume_target ); + } + else { + vg_slewf( &skaterift.resume_transition, 1.0f, + vg.time_frame_delta * (1.0f/1.0f) ); + + if( skaterift.resume_transition >= 1.0f ) + skaterift_restore_frame( skaterift.resume_target ); + else { + target = vg_lerp( skaterift.resume_begin, + skaterift.resume_target->time, + vg_smoothstepf( skaterift.resume_transition ) ); + replay_seek( &skaterift.replay, target ); + } + } + } + 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; skaterift.replay_control = k_replay_control_scrub; - skaterift.activity = k_skaterift_default; - vg.time = prev->time; - return; + 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 += vg.time_frame_delta; + replay_seek( &skaterift.replay, target ); + } + + if( vg_getkey( SDLK_8 ) ){ + replay_frame *prev = replay_find_recent_stateframe(&skaterift.replay); + + if( prev ){ + skaterift.replay_control = k_replay_control_resume; + skaterift.resume_target = prev; + skaterift.resume_begin = skaterift.replay.cursor; + skaterift.resume_transition = 0.0f; + } } } }