From 0399d5a0a2e1818c3d4951f42abc1132f7e26421 Mon Sep 17 00:00:00 2001 From: hgn Date: Mon, 10 Jul 2023 16:19:17 +0100 Subject: [PATCH 1/1] cleanup frame saving --- player.h | 46 +++----------- player_render.c | 71 --------------------- player_replay.c | 166 +++++++++++++++++++++++++++++++++++++++--------- player_skate.h | 2 +- skaterift.c | 4 +- 5 files changed, 149 insertions(+), 140 deletions(-) diff --git a/player.h b/player.h index 6315e1a..2ae0485 100644 --- a/player.h +++ b/player.h @@ -111,8 +111,7 @@ static localplayer; */ VG_STATIC -void (*_player_system_register[])(void) = -{ +void (*_player_system_register[])(void) = { player__walk_register, player__skate_register, NULL, @@ -120,8 +119,7 @@ void (*_player_system_register[])(void) = }; VG_STATIC -void (*_player_bind[])( player_instance *player ) = -{ +void (*_player_bind[])( player_instance *player ) = { player__walk_bind, player__skate_bind, NULL, @@ -129,8 +127,7 @@ void (*_player_bind[])( player_instance *player ) = }; VG_STATIC -void (*_player_reset[])( player_instance *player, ent_spawn *rp ) = -{ +void (*_player_reset[])( player_instance *player, ent_spawn *rp ) = { player__walk_reset, player__skate_reset, NULL, @@ -138,8 +135,7 @@ void (*_player_reset[])( player_instance *player, ent_spawn *rp ) = }; VG_STATIC -void (*_player_pre_update[])( player_instance *player ) = -{ +void (*_player_pre_update[])( player_instance *player ) = { player__walk_pre_update, player__skate_pre_update, NULL, @@ -147,8 +143,7 @@ void (*_player_pre_update[])( player_instance *player ) = }; VG_STATIC -void( *_player_update[])( player_instance *player ) = -{ +void( *_player_update[])( player_instance *player ) = { player__walk_update, player__skate_update, player__dead_update, @@ -156,8 +151,7 @@ void( *_player_update[])( player_instance *player ) = }; VG_STATIC -void( *_player_post_update[])( player_instance *player ) = -{ +void( *_player_post_update[])( player_instance *player ) = { player__walk_post_update, player__skate_post_update, NULL, @@ -165,8 +159,7 @@ void( *_player_post_update[])( player_instance *player ) = }; VG_STATIC -void( *_player_im_gui[])( player_instance *player ) = -{ +void( *_player_im_gui[])( player_instance *player ) = { player__walk_im_gui, player__skate_im_gui, NULL, @@ -174,8 +167,7 @@ void( *_player_im_gui[])( player_instance *player ) = }; VG_STATIC -void( *_player_animate[])( player_instance *player, player_animation *dest ) = -{ +void( *_player_animate[])( player_instance *player, player_animation *dest ) = { player__walk_animate, player__skate_animate, player__dead_animate, @@ -183,33 +175,13 @@ void( *_player_animate[])( player_instance *player, player_animation *dest ) = }; VG_STATIC -void( *_player_post_animate[])( player_instance *player ) = -{ +void( *_player_post_animate[])( player_instance *player ) = { player__walk_post_animate, player__skate_post_animate, player__dead_post_animate, player__drive_post_animate }; -VG_STATIC -void( *_player_store_state[] )( player_instance *player ) = -{ - NULL, - NULL, - NULL, - NULL -}; - -VG_STATIC -void( *_player_load_state_lerp[] )( player_instance *player, - void *A, void *B, f32 t ) = -{ - NULL, - NULL, - NULL, - NULL -}; - PLAYER_API void player__debugtext( int size, const char *fmt, ... ); PLAYER_API void player__create( player_instance *inst ); PLAYER_API void player__use_avatar( player_instance *player, diff --git a/player_render.c b/player_render.c index aaefb07..b4897fc 100644 --- a/player_render.c +++ b/player_render.c @@ -179,7 +179,6 @@ VG_STATIC void player__animate( player_instance *player ){ VG_STATIC void player__animate_from_replay( player_instance *player, replay_buffer *replay ){ - /* TODO: frame blending */ /* TODO: holdout blending (from when the game has to slow down) */ player_animation res; @@ -212,76 +211,6 @@ VG_STATIC void player__animate_from_replay( player_instance *player, skeleton_apply_pose( sk, res.pose, k_anim_apply_absolute ); } -VG_STATIC -void player_record_replay_frame( player_instance *player, - 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; - - u32 gamestate_size = 0; - void *gamestate_src = NULL; - if( (statedelta > k_gamestate_rate) || force_gamestate ){ - if( player->subsystem == k_player_subsystem_walk ){ - gamestate_size = sizeof(struct player_walk_state); - gamestate_src = &player->_walk.state; - } - else if( player->subsystem == k_player_subsystem_skate ){ - gamestate_size = sizeof(struct player_skate_state); - gamestate_src = &player->_skate.state; - } - else if( player->subsystem == k_player_subsystem_dead ){ - gamestate_size = sizeof(struct player_ragdoll); - gamestate_src = &player->ragdoll; - } - } - assert( gamestate_size < 0xffff ); - - if( (delta > k_replay_rate) || gamestate_size ){ - replay_frame *frame = replay_newframe( replay, gamestate_size, 0 ); - 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 = &player->playeravatar->sk; - skeleton_decompose_mtx_absolute( sk, res->pose ); - - memcpy( &frame->board_pose, &player->board_pose, - sizeof(player->board_pose) ); - frame->time = vg.time; - v3_copy( player->cam.pos, frame->cam_pos ); - v3_copy( player->cam.angles, frame->cam_angles ); - frame->cam_fov = player->cam.fov; - - if( gamestate_size ){ - replay_gamestate *gs = replay_frame_gamestate( frame ); - gs->system = player->subsystem; - - /* permanent block */ - memcpy( &gs->rb, &player->rb, sizeof(rigidbody) ); - memcpy( &gs->cam_control, &player->cam_control, - sizeof(struct player_cam_controller) ); - v3_copy( player->angles, gs->angles ); - - /* subsytem/dynamic block */ - void *dst = replay_gamestate_subsystem_data( gs ); - memcpy( dst, gamestate_src, gamestate_size ); - } - } -} - VG_STATIC void player__pre_render( player_instance *player ){ /* shadowing/ao info */ struct player_avatar *av = player->playeravatar; diff --git a/player_replay.c b/player_replay.c index 1215f62..79db8da 100644 --- a/player_replay.c +++ b/player_replay.c @@ -222,6 +222,142 @@ VG_STATIC void replay_get_camera( replay_buffer *replay, camera *cam ){ } } +struct replay_rb{ + v3f co, v, w; + v4f q; +}; + +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; + + 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 ]; + } + + 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 ); + } + } + } + + 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 ); + + /* 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; + + for( u32 i=0; iobj.rb; + + 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 ); + + v3_copy( arr[i].co, part->prev_co ); + v4_copy( arr[i].q, part->prev_q ); + } + } + + localplayer.subsystem = gs->system; + + memcpy( &localplayer.rb, &gs->rb, sizeof(rigidbody) ); + v3_copy( gs->angles, localplayer.angles ); + + 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) ); +} + VG_STATIC void skaterift_replay_pre_update(void){ if( skaterift.activity != k_skaterift_replay ) return; @@ -251,35 +387,7 @@ VG_STATIC void skaterift_replay_pre_update(void){ replay_frame *prev = replay_find_recent_stateframe( &skaterift.replay ); if( prev ){ - /* TODO: Make gamestate_apply function / swap ... */ - 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, 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 ); - } - - localplayer.subsystem = gs->system; - - 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; - - memcpy( &localplayer.cam_control, &gs->cam_control, - sizeof(struct player_cam_controller) ); + skaterift_restore_frame( prev ); /* chop end off replay */ prev->r = NULL; diff --git a/player_skate.h b/player_skate.h index c3ec0e6..eca4582 100644 --- a/player_skate.h +++ b/player_skate.h @@ -261,9 +261,9 @@ VG_STATIC void player__skate_animate ( player_instance *player, VG_STATIC void player__skate_post_animate ( player_instance *player ); VG_STATIC void player__skate_reset ( player_instance *player, ent_spawn *rp ); -VG_STATIC void player__skate_restore( player_instance *player ); VG_STATIC void player__skate_clear_mechanics( player_instance *player ); VG_STATIC void player__skate_reset_animator( player_instance *player ); VG_STATIC void player__approximate_best_trajectory( player_instance *player ); + #endif /* PLAYER_SKATE_H */ diff --git a/skaterift.c b/skaterift.c index b06db68..20b686b 100644 --- a/skaterift.c +++ b/skaterift.c @@ -473,7 +473,7 @@ VG_STATIC void render_main_game(void){ player__animate_from_replay( &localplayer, &skaterift.replay ); } else - player_record_replay_frame( &localplayer, &skaterift.replay, 0 ); + skaterift_record_frame( &skaterift.replay, 0 ); player__pre_render( &localplayer ); skaterift_composite_maincamera(); @@ -491,7 +491,7 @@ VG_STATIC void render_main_game(void){ if( button_down( k_srbind_reset ) ){ if( skaterift.activity == k_skaterift_default ){ skaterift.activity = k_skaterift_replay; - player_record_replay_frame( &localplayer, &skaterift.replay, 1 ); + skaterift_record_frame( &skaterift.replay, 1 ); } } } -- 2.25.1