add one shots to replay buffer
authorhgn <hgodden00@gmail.com>
Tue, 19 Dec 2023 18:03:20 +0000 (18:03 +0000)
committerhgn <hgodden00@gmail.com>
Tue, 19 Dec 2023 18:03:20 +0000 (18:03 +0000)
network.c
player.c
player.h
player_render.c
player_render.h
player_replay.c
player_replay.h
player_skate.c

index eaad202773f4d6a16ea7b841fd821bddbbdab63c..3bb59b3e6c08e708b34958372587e41756e6332c 100644 (file)
--- 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();
index c019f698484881551872ff89a171ecedfb1314de..c115162099fb6d4b075ebcccb8f420b90eda5632 100644 (file)
--- 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; i<vg_list_size(localplayer.sfx_buffer); i++ ){
-         struct net_sfx *a = &localplayer.sfx_buffer[i];
+      for( u32 i=0; i<len; i++ ){
+         struct net_sfx *a = &buffer[i];
          if( a->priority < 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 */
index e1b44fe1104a3fc87cb6da6ebc372a7f74833be3..f837cb955cb96b87a033e9879eed80a87d327a8a 100644 (file)
--- 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
index 6174155351ef8486297f2e158bf31e29adbdd3e4..1ade3d7d86c1856cfe556c4f2600d42b15675739 100644 (file)
@@ -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 );
    }
index 02a1c6b7b56aacc80d9843f62e67e881c3604fe8..ee98488db270dd1524daa58c435376788ab64017 100644 (file)
@@ -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 */
index 9fbbfcc6e7dd07c5ae9b2433071dd8b3154e061a..6fea7d91338c5805fe7dae536877fe6c3ab47845 100644 (file)
@@ -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; i<count; i ++ ){
+      net_sfx_play( buffer + i );
+   }
+}
+
+static int replay_seek( replay_buffer *replay, f64 t ){
+   if( !replay->head ) 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 ) ){
index 0aa370e63d1407a9d71c3d2830b61f280b95e353..38599d448a320e48989e2a0634865f5a884a96bf 100644 (file)
@@ -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 );
index 4fa21edccde8d7f5ae6f17f324726d781ce8a1e0..779ba7596f5f5126ae102443bdd416d02b4c406c 100644 (file)
@@ -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;
       }