From 8b783ef3705f88f0f67ef6cd8113f79ccb25ec20 Mon Sep 17 00:00:00 2001 From: hgn Date: Sun, 9 Jul 2023 02:50:46 +0100 Subject: [PATCH] replay system reasonable --- player.c | 4 +-- player_render.c | 13 +++---- player_replay.c | 90 ++++++++++++++++++++++++++++--------------------- player_replay.h | 16 +++------ skaterift.c | 18 +++++++++- skaterift.h | 10 +++++- 6 files changed, 91 insertions(+), 60 deletions(-) diff --git a/player.c b/player.c index 4746e4f..d248aec 100644 --- a/player.c +++ b/player.c @@ -222,7 +222,7 @@ PLAYER_API void player__im_gui( player_instance *player ){ g_player_debugger[0] = box[0]; g_player_debugger[1] = 0; g_player_debugger[2] = 300; - g_player_debugger[3] = 16; + g_player_debugger[3] = 32; player__debugtext( 2, "director" ); player__debugtext( 1, "activity: %s", @@ -240,7 +240,7 @@ PLAYER_API void player__im_gui( player_instance *player ){ if( _player_im_gui[ player->subsystem ] ) _player_im_gui[ player->subsystem ]( player ); - replay_debug_info( player ); + skaterift_replay_debug_info(); } VG_STATIC void global_skateshop_exit(void); diff --git a/player_render.c b/player_render.c index 3fe9336..b6cbf63 100644 --- a/player_render.c +++ b/player_render.c @@ -138,7 +138,7 @@ VG_STATIC void player_model_unload( struct player_model *board ){ dynamic_model_unload( &board->mdl ); } -VG_STATIC void player_animate( player_instance *player ){ +VG_STATIC void player__animate( player_instance *player ){ if( _player_animate[ player->subsystem ] ){ player_animation res; res.type = k_player_animation_type_fk; @@ -173,11 +173,15 @@ VG_STATIC void player_animate( player_instance *player ){ if( _player_post_animate[ player->subsystem ] ) _player_post_animate[ player->subsystem ]( player ); + + player__cam_iterate( player ); } -VG_STATIC void player_animate_from_replay( player_instance *player, - replay_buffer *replay ){ +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; replay_frame *frame = replay->cursor_frame; @@ -254,9 +258,6 @@ void player_record_replay_frame( player_instance *player, } VG_STATIC void player__pre_render( player_instance *player ){ - player_animate( player ); - player__cam_iterate( player ); - /* shadowing/ao info */ struct player_avatar *av = player->playeravatar; struct player_board *board = diff --git a/player_replay.c b/player_replay.c index 38c2192..09cc136 100644 --- a/player_replay.c +++ b/player_replay.c @@ -9,7 +9,6 @@ VG_STATIC void replay_clear( replay_buffer *replay ){ replay->cursor_frame = NULL; replay->statehead = NULL; replay->cursor = -99999.9; - replay->control = k_replay_control_none; } replay_gamestate *replay_frame_gamestate( replay_frame *frame, u16 index ){ @@ -155,74 +154,92 @@ VG_STATIC replay_frame *replay_find_recent_stateframe( replay_buffer *replay ){ return NULL; } -VG_STATIC void player_replay_control_update( player_instance *player ){ -#if 0 +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 ); + } + else { + v3_zero( cam->pos ); + v3_zero( cam->angles ); + cam->fov = 90.0f; + } +} + +VG_STATIC void skaterift_replay_pre_update(void){ + if( skaterift.activity != k_skaterift_replay ) return; + f64 speed = 1.0; - f64 target = player->replay.cursor; + f64 target = skaterift.replay.cursor; if( vg_getkey( SDLK_9 ) ){ target -= vg.time_frame_delta * speed; - player->replay.control = k_replay_control_scrub; - replay_seek( &player->replay, target ); + skaterift.replay_control = k_replay_control_scrub; + replay_seek( &skaterift.replay, target ); } if( vg_getkey( SDLK_0 ) ){ target += vg.time_frame_delta * speed; - player->replay.control = k_replay_control_scrub; - replay_seek( &player->replay, target ); + skaterift.replay_control = k_replay_control_scrub; + replay_seek( &skaterift.replay, target ); } if( vg_getkey( SDLK_7 ) ) - player->replay.control = k_replay_control_play; + skaterift.replay_control = k_replay_control_play; - if( player->replay.control == k_replay_control_play ){ + if( skaterift.replay_control == k_replay_control_play ){ target += vg.time_frame_delta; - replay_seek( &player->replay, target ); + replay_seek( &skaterift.replay, target ); } if( vg_getkey( SDLK_8 ) ){ - replay_frame *prev = replay_find_recent_stateframe( &player->replay ); + replay_frame *prev = replay_find_recent_stateframe( &skaterift.replay ); if( prev ){ /* TODO: Make gamestate_apply function / swap ... */ replay_gamestate *gs = replay_frame_gamestate( prev, 0 ); if( gs->system == k_player_subsystem_walk ){ - memcpy( &player->_walk.state, &gs->walk, + memcpy( &localplayer._walk.state, &gs->walk, sizeof(struct player_walk_state) ); } else if( gs->system == k_player_subsystem_skate ){ - memcpy( &player->_skate.state, &gs->skate, + memcpy( &localplayer._skate.state, &gs->skate, sizeof(struct player_skate_state) ); } - player->subsystem = gs->system; - - memcpy( &player->rb, &gs->rb, sizeof(rigidbody) ); - v3_copy( gs->angles, player->angles ); - v3_copy( prev->cam_pos, player->cam.pos ); - v3_copy( prev->cam_angles, player->cam_override_angles ); - player->cam.fov = prev->cam_fov; - memcpy( &player->cam_control, &gs->cam_control, + 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) ); /* chop end off replay */ prev->r = NULL; - player->replay.statehead = prev; - player->replay.head = prev; - player->replay.cursor_frame = prev; - player->replay.cursor = prev->time; - player->replay.control = k_replay_control_none; + skaterift.replay.statehead = prev; + skaterift.replay.head = prev; + skaterift.replay.cursor_frame = prev; + skaterift.replay.cursor = prev->time; + skaterift.replay_control = k_replay_control_scrub; + skaterift.activity = k_skaterift_default; vg.time = prev->time; return; } } -#endif } -VG_STATIC void replay_debug_info( player_instance *player ){ -#if 0 +VG_STATIC void skaterift_replay_debug_info(void){ player__debugtext( 2, "replay info" ); - replay_buffer *replay = &player->replay; + replay_buffer *replay = &skaterift.replay; u32 head = 0, tail = 0; @@ -247,14 +264,12 @@ VG_STATIC void replay_debug_info( player_instance *player ){ len = end - start; player__debugtext( 1, "cursor: %.2fs / %.2fs\n", cur, len ); -#endif } -VG_STATIC void replay_imgui( player_instance *player ){ -#if 0 - if( player->replay.control == k_replay_control_none ) return; +VG_STATIC void skaterift_replay_imgui(void){ + if( skaterift.activity != k_skaterift_replay ) return; - replay_buffer *replay = &player->replay; + replay_buffer *replay = &skaterift.replay; f64 start = replay->cursor, end = replay->cursor; if( replay->tail ) start = replay->tail->time; @@ -276,7 +291,7 @@ VG_STATIC void replay_imgui( player_instance *player ){ f64 l = (replay->cursor_frame->r->time-replay->cursor_frame->time)/len, s = (replay->cursor_frame->time - start) / len; ui_rect box = { s*(f64)vg.window_x, bar[1]-2, - VG_MAX(4,(ui_px)l), bar[3]+2 }; + VG_MAX(4,(ui_px)(l*vg.window_x)), bar[3]+2 }; ui_fill( box, ui_colour( k_ui_bg+4 ) ); } } @@ -309,7 +324,6 @@ VG_STATIC void replay_imgui( player_instance *player ){ 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 ); -#endif } #endif /* PLAYER_REPLAY_C */ diff --git a/player_replay.h b/player_replay.h index 20eafb4..52a0772 100644 --- a/player_replay.h +++ b/player_replay.h @@ -14,18 +14,9 @@ struct replay_buffer { void *data; u32 size; /* bytes */ - enum replay_control { - k_replay_control_none, - k_replay_control_scrub, - k_replay_control_play, - k_replay_control_resume - } - control; - replay_frame *head, *tail, *cursor_frame, *statehead; f64 cursor; - f32 track_velocity; }; struct replay_frame { @@ -58,15 +49,16 @@ struct replay_sfx { u32 none; }; -VG_STATIC void replay_debug_info( player_instance *player ); VG_STATIC replay_frame *replay_newframe( replay_buffer *replay, u16 gamestate_count, u16 sfx_count ); -VG_STATIC void replay_imgui( player_instance *player ); VG_STATIC void replay_seek( replay_buffer *replay, f64 t ); replay_gamestate *replay_frame_gamestate( replay_frame *frame, u16 index ); replay_sfx *replay_frame_sfx( replay_frame *frame, u16 index ); VG_STATIC replay_frame *replay_find_recent_stateframe( replay_buffer *replay ); -VG_STATIC void player_replay_control_update( player_instance *player ); + +VG_STATIC void skaterift_replay_pre_update(void); +VG_STATIC void skaterift_replay_imgui(void); +VG_STATIC void skaterift_replay_debug_info(void); #endif /* PLAYER_REPLAY_H */ diff --git a/skaterift.c b/skaterift.c index 8df2f8a..64fb65a 100644 --- a/skaterift.c +++ b/skaterift.c @@ -288,11 +288,13 @@ VG_STATIC void vg_pre_update(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 ); } } player__pre_update( &localplayer ); global_skateshop_preupdate(); + skaterift_replay_pre_update(); world_update( world_current_instance(), localplayer.rb.co ); audio_ambient_sprites_update( world_current_instance(), localplayer.rb.co ); @@ -446,6 +448,13 @@ VG_STATIC void skaterift_composite_maincamera(void){ camera_lerp( &localplayer.cam, &global_skateshop.cam, 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 ); + } + skaterift.cam.nearz = 0.1f; skaterift.cam.farz = 2100.0f; @@ -466,7 +475,14 @@ VG_STATIC void skaterift_composite_maincamera(void){ } VG_STATIC void render_main_game(void){ + player__animate( &localplayer ); + if( skaterift.activity == k_skaterift_replay ){ + player__animate_from_replay( &localplayer, &skaterift.replay ); + } + else + player_record_replay_frame( &localplayer, &skaterift.replay, 0 ); player__pre_render( &localplayer ); + skaterift_composite_maincamera(); render_scene(); @@ -517,7 +533,7 @@ VG_STATIC void vg_gui(void){ player__im_gui( &localplayer ); world_instance *world = world_current_instance(); - replay_imgui( &localplayer ); + skaterift_replay_imgui(); workshop_form_gui(); render_view_framebuffer_ui(); } diff --git a/skaterift.h b/skaterift.h index e78df2f..1e2fba3 100644 --- a/skaterift.h +++ b/skaterift.h @@ -26,8 +26,16 @@ struct{ op; f32 time_rate; - camera cam; + camera cam, replay_cam; + replay_buffer replay; + enum replay_control { + k_replay_control_scrub, + k_replay_control_play, + k_replay_control_resume + } + replay_control; + f32 track_velocity; enum skaterift_activity { k_skaterift_default = 0x00, -- 2.25.1