From 78cc452a8343821ba47c0905d755657847dafd25 Mon Sep 17 00:00:00 2001 From: hgn Date: Tue, 19 Dec 2023 18:03:20 +0000 Subject: [PATCH] add one shots to replay buffer --- network.c | 2 +- player.c | 53 ++++++++++++++++++++++++++++---------------- player.h | 9 +++++--- player_render.c | 12 ++++++++++ player_render.h | 1 + player_replay.c | 59 +++++++++++++++++++++++++++++++++++++++---------- player_replay.h | 2 +- player_skate.c | 10 +-------- 8 files changed, 103 insertions(+), 45 deletions(-) diff --git a/network.c b/network.c index eaad202..3bb59b3 100644 --- a/network.c +++ b/network.c @@ -557,7 +557,7 @@ static void network_update(void){ if( frame_delta > NETWORK_FRAMERATE ){ network_client.last_frame = vg.time_real; remote_player_send_playerframe(); - player__clear_sfx_buffer(); + localplayer.sfx_buffer_count = 0; } remote_player_debug_update(); diff --git a/player.c b/player.c index c019f69..c115162 100644 --- a/player.c +++ b/player.c @@ -323,36 +323,51 @@ static void net_sfx_play( struct net_sfx *sfx ){ } }; -static void player__networked_sfx( u8 system, u8 priority, u8 id, - v3f pos, f32 volume ){ - struct net_sfx null, *sfx = &null; - - if( localplayer.sfx_buffer_count < vg_list_size(localplayer.sfx_buffer) ) - sfx = &localplayer.sfx_buffer[ localplayer.sfx_buffer_count ++ ]; +static struct net_sfx *find_lower_priority_sfx( struct net_sfx *buffer, u32 len, + u32 *count, u8 priority ){ + struct net_sfx *p_sfx = NULL; + if( *count < len ){ + p_sfx = &buffer[ *count ]; + *count = *count+1; + } else { - for( u32 i=0; ipriority < priority ){ - sfx = a; + p_sfx = a; break; } } } - sfx->id = id; - sfx->priority = priority; - sfx->volume = volume; - v3_copy( pos, sfx->location ); - sfx->system = system; + return p_sfx; +} +static void player__networked_sfx( u8 system, u8 priority, u8 id, + v3f pos, f32 volume ){ + struct net_sfx sfx, + *p_net = find_lower_priority_sfx( + localplayer.sfx_buffer, 4, + &localplayer.sfx_buffer_count, priority ), + *p_replay = find_lower_priority_sfx( + localplayer.local_sfx_buffer, 2, + &localplayer.local_sfx_buffer_count, priority ); + + sfx.id = id; + sfx.priority = priority; + sfx.volume = volume; + v3_copy( pos, sfx.location ); + sfx.system = system; + + /* we only care about subframe in networked sfx. local replays run at a + * high enough framerate. */ f32 t = (vg.time_real - network_client.last_frame) / NETWORK_FRAMERATE; - sfx->subframe = vg_clampf( t, 0.0f, 1.0f ); + sfx.subframe = vg_clampf( t, 0.0f, 1.0f ); - net_sfx_play( sfx ); -} + if( p_net ) *p_net = sfx; + if( p_replay ) *p_replay = sfx; -static void player__clear_sfx_buffer(void){ - localplayer.sfx_buffer_count = 0; + net_sfx_play( &sfx ); } /* implementation */ diff --git a/player.h b/player.h index e1b44fe..f837cb9 100644 --- a/player.h +++ b/player.h @@ -117,8 +117,10 @@ struct { f32 subframe, volume; v3f location; } - sfx_buffer[4]; - u32 sfx_buffer_count; + sfx_buffer[4], /* large timeframe 1/10s; for networking */ + local_sfx_buffer[2]; /* per framerate 1/30s; for replay */ + u32 sfx_buffer_count, + local_sfx_buffer_count; /* * Animation @@ -142,7 +144,8 @@ struct { * ------------------------------------------------- */ - enum player_subsystem subsystem; /* .. prev */ + enum player_subsystem subsystem, + observing_system; /* * Rendering diff --git a/player_render.c b/player_render.c index 6174155..1ade3d7 100644 --- a/player_render.c +++ b/player_render.c @@ -275,6 +275,7 @@ static void player__animate(void){ if( sys->post_animate ) sys->post_animate(); + player__observe_system( localplayer.subsystem ); if( sys->sfx_comp ) sys->sfx_comp( sys->animator_data ); @@ -310,6 +311,16 @@ static void lerp_player_pose( player_pose *pose0, player_pose *pose1, f32 t, } } +static void player__observe_system( enum player_subsystem id ){ + if( id != localplayer.observing_system ){ + struct player_subsystem_interface *sysm1 = + player_subsystems[ localplayer.observing_system ]; + + if( sysm1->sfx_kill ) sysm1->sfx_kill(); + localplayer.observing_system = id; + } +} + static void player__animate_from_replay( replay_buffer *replay ){ replay_frame *frame = replay->cursor_frame, *next = NULL; @@ -338,6 +349,7 @@ static void player__animate_from_replay( replay_buffer *replay ){ sys0->pose( a0, &localplayer.pose ); } + player__observe_system( frame->system ); if( sys0->sfx_comp ) sys0->sfx_comp( a0 ); } diff --git a/player_render.h b/player_render.h index 02a1c6b..ee98488 100644 --- a/player_render.h +++ b/player_render.h @@ -73,5 +73,6 @@ static void lerp_player_pose( player_pose *pose0, player_pose *pose1, f32 t, player_pose *posed ); static void player_mirror_pose( mdl_keyframe pose[32], mdl_keyframe mirrored[32] ); +static void player__observe_system( enum player_subsystem id ); #endif /* PLAYER_RENDER_H */ diff --git a/player_replay.c b/player_replay.c index 9fbbfcc..6fea7d9 100644 --- a/player_replay.c +++ b/player_replay.c @@ -54,7 +54,7 @@ static replay_frame *replay_newframe( replay_buffer *replay, u16 data_table[4][2]; data_table[ k_replay_framedata_animator ][1] = animator_size; data_table[ k_replay_framedata_gamestate ][1] = gamestate_size; - data_table[ k_replay_framedata_sfx ][1] = 0; + data_table[ k_replay_framedata_sfx ][1] = sfx_count*sizeof(struct net_sfx); data_table[ k_replay_framedata_internal_gamestate ][1] = 0; if( gamestate_size ){ data_table[ k_replay_framedata_internal_gamestate ][1] = @@ -114,8 +114,19 @@ check_again:; return frame; } -static void replay_seek( replay_buffer *replay, f64 t ){ - if( !replay->head ) return; +static void replay_emit_frame_sounds( replay_frame *frame ){ + void *baseptr = frame; + u16 *inf = frame->data_table[k_replay_framedata_sfx]; + struct net_sfx *buffer = baseptr + inf[0]; + u32 count = inf[1] / sizeof(struct net_sfx); + + for( u32 i=0; ihead ) return 0; assert( replay->tail ); if( t < replay->tail->time ) t = replay->tail->time; @@ -132,13 +143,18 @@ static void replay_seek( replay_buffer *replay, f64 t ){ } f64 dir = t - replay->cursor; - if( dir == 0.0 ) return; + if( dir == 0.0 ) return 0; dir = vg_signf( dir ); + u32 i=4096; while( i --> 0 ){ - if( dir < 0.0 ) - if( t > replay->cursor_frame->time ) break; + if( dir < 0.0 ){ + if( t > replay->cursor_frame->time ) { + replay->cursor = t; + return 1; + } + } replay_frame *next; if( dir > 0.0 ) next = replay->cursor_frame->r; @@ -146,16 +162,23 @@ static void replay_seek( replay_buffer *replay, f64 t ){ if( !next ) break; - if( dir > 0.0 ) - if( t < next->time ) break; + if( dir > 0.0 ){ + if( t < next->time ){ + replay->cursor = t; + return 1; + } + } + + replay_emit_frame_sounds( next ); replay->cursor_frame = next; replay->cursor = next->time; - if( !i ) return; + if( !i ) return 1; } replay->cursor = t; + return 0; } static replay_frame *replay_find_recent_stateframe( replay_buffer *replay ){ @@ -261,7 +284,8 @@ static void skaterift_record_frame( replay_buffer *replay, }[ localplayer.subsystem ]; replay_frame *frame = replay_newframe( replay, - animator_size, gamestate_size, 0 ); + animator_size, gamestate_size, + localplayer.local_sfx_buffer_count ); frame->system = localplayer.subsystem; if( save_state ){ @@ -323,6 +347,13 @@ static void skaterift_record_frame( replay_buffer *replay, else if( localplayer.subsystem == k_player_subsystem_dead ){ memcpy( dst, &player_dead.animator, animator_size ); } + + /* sound effects */ + memcpy( replay_frame_data( frame, k_replay_framedata_sfx ), + localplayer.local_sfx_buffer, + sizeof(struct net_sfx)*localplayer.local_sfx_buffer_count ); + + localplayer.local_sfx_buffer_count = 0; } static @@ -413,7 +444,10 @@ static void skaterift_replay_pre_update(void){ f64 target = vg_lerp( skaterift.resume_begin, skaterift.resume_target->time, vg_smoothstepf( skaterift.resume_transition ) ); - replay_seek( &skaterift.replay, target ); + if( replay_seek( &skaterift.replay, target ) ) + skaterift.track_velocity = 1.0f; + else + skaterift.track_velocity = 0.0f; } } } @@ -446,7 +480,8 @@ static void skaterift_replay_pre_update(void){ f64 target = skaterift.replay.cursor; target += skaterift.track_velocity * vg.time_frame_delta; - replay_seek( &skaterift.replay, target ); + if( !replay_seek( &skaterift.replay, target ) ) + skaterift.track_velocity = 0.0f; } if( button_down( k_srbind_mback ) ){ diff --git a/player_replay.h b/player_replay.h index 0aa370e..38599d4 100644 --- a/player_replay.h +++ b/player_replay.h @@ -52,7 +52,7 @@ static replay_frame *replay_newframe( replay_buffer *replay, u16 animator_size, u16 gamestate_size, u16 sfx_count ); -static void replay_seek( replay_buffer *replay, f64 t ); +static int replay_seek( replay_buffer *replay, f64 t ); static replay_frame *replay_find_recent_stateframe( replay_buffer *replay ); static void replay_get_camera( replay_buffer *replay, camera *cam ); diff --git a/player_skate.c b/player_skate.c index 4fa21ed..779ba75 100644 --- a/player_skate.c +++ b/player_skate.c @@ -758,7 +758,6 @@ static void skate_apply_trick_model(void){ if( (v3_length2(state->trick_vel) >= 0.0001f ) && state->trick_time > 0.2f) { - player__skate_kill_audio(); player__dead_transition( k_player_die_type_feet ); } @@ -1220,7 +1219,6 @@ static void player__skate_pre_update(void){ localplayer.rb.co ); player__begin_holdout( offset ); - player__skate_kill_audio(); player__walk_transition( state->activity <= k_skate_activity_air_to_grind? 0: 1, state->trick_euler[0] ); return; @@ -1278,10 +1276,7 @@ static void player__skate_comp_audio( void *_animator ){ f32 gate = skaterift.time_rate; if( skaterift.activity == k_skaterift_replay ){ - if( skaterift.replay_control == k_replay_control_play ) - gate = 1.0f; - else - gate = vg_minf( 1.0f, fabsf(skaterift.track_velocity) ); + gate = vg_minf( 1.0f, fabsf(skaterift.track_velocity) ); } f32 @@ -2192,7 +2187,6 @@ static void player__skate_update(void){ player__networked_sfx( k_player_subsystem_walk, 32, k_player_walk_soundeffect_splash, localplayer.rb.co, 1.0f ); - player__skate_kill_audio(); player__dead_transition( k_player_die_type_generic ); return; } @@ -2468,7 +2462,6 @@ begin_collision:; v3_lerp( start_co, localplayer.rb.co, t, localplayer.rb.co ); rb_update_transform( &localplayer.rb ); - player__skate_kill_audio(); player__dead_transition( k_player_die_type_head ); return; } @@ -2638,7 +2631,6 @@ begin_collision:; if( nforce > 17.6f ){ v3_muladds( localplayer.rb.v, normal_total, -1.0f, localplayer.rb.v ); player__dead_transition( k_player_die_type_feet ); - player__skate_kill_audio(); return; } -- 2.25.1