X-Git-Url: https://harrygodden.com/git/?a=blobdiff_plain;f=player_replay.c;h=1215f62d3f13d893114226b73fd422ebe842bcb7;hb=6c84fa207dec2cf8e92b3882492bdd2f92ee7afe;hp=09cc136cbd477d6395aaea837b2486f815ae1da9;hpb=8b783ef3705f88f0f67ef6cd8113f79ccb25ec20;p=carveJwlIkooP6JGAAIwe30JlM.git diff --git a/player_replay.c b/player_replay.c index 09cc136..1215f62 100644 --- a/player_replay.c +++ b/player_replay.c @@ -11,48 +11,85 @@ VG_STATIC void replay_clear( replay_buffer *replay ){ replay->cursor = -99999.9; } -replay_gamestate *replay_frame_gamestate( replay_frame *frame, u16 index ){ +replay_gamestate *replay_frame_gamestate( replay_frame *frame ){ void *baseptr = frame; - - replay_gamestate *array = (baseptr + vg_align8( sizeof(replay_frame))); - return &array[ index ]; + return baseptr + vg_align8(sizeof(replay_frame)); +} + +void *replay_gamestate_subsystem_data( replay_gamestate *gs ){ + void *baseptr = gs; + return baseptr + vg_align8(sizeof(replay_gamestate)); +} + +u32 replay_frame_gamestate_total_size( u32 subsystem_gamestate_size ){ + if( subsystem_gamestate_size ){ + return vg_align8( sizeof(replay_gamestate) ) + + vg_align8( subsystem_gamestate_size ); + } + else + return 0; } -replay_sfx *replay_frame_sfx( replay_frame *frame, u16 index ){ - void *gsarr = replay_frame_gamestate( frame, 0 ); - u32 gssize = frame->gamestate_count * sizeof(replay_gamestate); +replay_sfx *replay_frame_sfx( replay_frame *frame, u32 index ){ + void *gs = replay_frame_gamestate( frame ); + u32 total_size = + replay_frame_gamestate_total_size( frame->subsystem_gamestate_size ); - replay_sfx *array = (gsarr + vg_align8(gssize)); + replay_sfx *array = (gs + total_size); return &array[index]; } -u32 _replay_frame_size( u16 gamestate_count, u16 sfx_count ){ +u32 _replay_frame_size( u32 subsystem_gamestate_size, u32 sfx_count ){ return vg_align8( sizeof( replay_frame ) ) + - vg_align8( gamestate_count * sizeof(replay_gamestate) ) + + replay_frame_gamestate_total_size( subsystem_gamestate_size ) + vg_align8( sfx_count * sizeof(replay_sfx) ); } u32 replay_frame_size( replay_frame *frame ){ - return _replay_frame_size( frame->gamestate_count, frame->sfx_count ); + return _replay_frame_size( frame->subsystem_gamestate_size, + frame->sfx_count ); +} + +VG_STATIC void replay_tailpop( replay_buffer *replay ){ + if( replay->cursor_frame == replay->tail ) + replay->cursor_frame = NULL; + if( replay->statehead == replay->tail ) + replay->statehead = NULL; + + replay->tail = replay->tail->r; + + if( replay->tail ) + replay->tail->l = NULL; + else + replay->head = NULL; } VG_STATIC replay_frame *replay_newframe( replay_buffer *replay, - u16 gamestate_count, u16 sfx_count ){ + u32 subsystem_gamestate_size, + u32 sfx_count ){ replay_frame *frame = NULL; if( replay->head ){ assert( replay->head ); u32 headsize = replay_frame_size( replay->head ), nextpos = ((void *)replay->head - replay->data) + headsize, - nextsize = _replay_frame_size( gamestate_count, sfx_count ); + nextsize = _replay_frame_size( subsystem_gamestate_size, sfx_count ); if( nextsize > replay->size ){ vg_error( "Keyframe too big\n" ); return NULL; } - if( nextpos + nextsize > replay->size ) + if( nextpos + nextsize > replay->size ){ nextpos = 0; + + /* maintain contiguity */ + while( replay->tail ){ + if( (void *)replay->tail - replay->data ) + replay_tailpop( replay ); + else break; + } + } check_again:; @@ -60,21 +97,10 @@ check_again:; if( tailpos >= nextpos ){ if( nextpos + nextsize > tailpos ){ - /* remove links */ - if( replay->cursor_frame == replay->tail ) - replay->cursor_frame = NULL; - if( replay->statehead == replay->tail ) - replay->statehead = NULL; - - /* pop node */ - replay->tail = replay->tail->r; + replay_tailpop( replay ); - if( replay->tail ) { - replay->tail->l = NULL; + if( replay->tail ) goto check_again; - } - else - replay->head = NULL; } } @@ -86,13 +112,13 @@ check_again:; else frame = replay->data; - frame->gamestate_count = gamestate_count; + frame->subsystem_gamestate_size = subsystem_gamestate_size; frame->sfx_count = sfx_count; frame->l = replay->head; frame->r = NULL; replay->head = frame; if( !replay->tail ) replay->tail = frame; - if( gamestate_count ) replay->statehead = frame; + if( subsystem_gamestate_size ) replay->statehead = frame; return frame; } @@ -143,25 +169,51 @@ VG_STATIC void replay_seek( replay_buffer *replay, f64 t ){ VG_STATIC replay_frame *replay_find_recent_stateframe( replay_buffer *replay ){ replay_frame *frame = replay->cursor_frame; - u32 i=4096; while( i --> 0 ){ if( !frame ) return frame; - if( frame->gamestate_count ) return frame; + if( frame->subsystem_gamestate_size ) return frame; frame = frame->l; } return NULL; } +VG_STATIC f32 replay_subframe_time( replay_buffer *replay ){ + replay_frame *frame = replay->cursor_frame; + if( !frame ) return 0.0f; + replay_frame *next = frame->r; + if( next ){ + f64 l = next->time - frame->time, + t = (replay->cursor - frame->time) / l; + return vg_clampf( t, 0.0f, 1.0f ); + } + else + return 0.0f; +} + +VG_STATIC void replay_get_frame_camera( replay_frame *frame, camera *cam ){ + cam->fov = frame->cam_fov; + v3_copy( frame->cam_pos, cam->pos ); + v3_copy( frame->cam_angles, cam->angles ); +} + VG_STATIC void replay_get_camera( replay_buffer *replay, camera *cam ){ cam->nearz = 0.1f; cam->farz = 100.0f; if( replay->cursor_frame ){ - /* TODO: frame lerp */ - cam->fov = replay->cursor_frame->cam_fov; - v3_copy( replay->cursor_frame->cam_pos, cam->pos ); - v3_copy( replay->cursor_frame->cam_angles, cam->angles ); + replay_frame *next = replay->cursor_frame->r; + + if( next ){ + camera temp; + + replay_get_frame_camera( replay->cursor_frame, cam ); + replay_get_frame_camera( next, &temp ); + camera_lerp( cam, &temp, replay_subframe_time( replay ), cam ); + } + else { + replay_get_frame_camera( replay->cursor_frame, cam ); + } } else { v3_zero( cam->pos ); @@ -200,16 +252,23 @@ VG_STATIC void skaterift_replay_pre_update(void){ if( prev ){ /* TODO: Make gamestate_apply function / swap ... */ - replay_gamestate *gs = replay_frame_gamestate( prev, 0 ); + replay_gamestate *gs = replay_frame_gamestate( prev ); + void *src = replay_gamestate_subsystem_data( gs ); if( gs->system == k_player_subsystem_walk ){ - memcpy( &localplayer._walk.state, &gs->walk, - sizeof(struct player_walk_state) ); + memcpy( &localplayer._walk.state, src, + prev->subsystem_gamestate_size ); } else if( gs->system == k_player_subsystem_skate ){ - memcpy( &localplayer._skate.state, &gs->skate, - sizeof(struct player_skate_state) ); + 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 ); } + localplayer.subsystem = gs->system; memcpy( &localplayer.rb, &gs->rb, sizeof(rigidbody) ); @@ -251,6 +310,8 @@ VG_STATIC void skaterift_replay_debug_info(void){ if( replay->statehead ){ u32 state = (void *)replay->statehead - replay->data; player__debugtext( 1, "gs @%u\n", state ); + player__debugtext( 1, "gamestate_size: %u\n", + replay->statehead->subsystem_gamestate_size ); } else player__debugtext( 1, "gs @NULL\n" );