now fall in immobile mode
[carveJwlIkooP6JGAAIwe30JlM.git] / player_replay.c
index 5313f936382550397c5d8d61ad10c876774fc020..5237e5f5b5d3451019c83061c3e82e9e976985a5 100644 (file)
@@ -13,43 +13,23 @@ VG_STATIC void replay_clear( replay_buffer *replay ){
    replay->cursor = -99999.9;
 }
 
-replay_gamestate *replay_frame_gamestate( replay_frame *frame ){
+VG_STATIC void *
+replay_frame_data( replay_frame *frame, enum replay_framedata type ){
    void *baseptr = frame;
-   return baseptr + vg_align8(sizeof(replay_frame));
+   return baseptr + frame->data_table[type][0];
 }
 
-void *replay_gamestate_subsystem_data( replay_gamestate *gs ){
-   void *baseptr = gs;
-   return baseptr + vg_align8(sizeof(replay_gamestate));
-}
+VG_STATIC u16
+replay_frame_calculate_data_offsets( u16 data_table[4][2] ){
+   u32 total = vg_align8( sizeof(replay_frame) );
+   for( u32 i=0; i<4; i++ ){
+      data_table[i][0] = total;
+      total += vg_align8(data_table[i][1]);
 
-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 );
+      if( total > 0xffff )
+         vg_fatal_error( "Exceeded frame storage capacity\n" );
    }
-   else
-      return 0;
-}
-
-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 = (gs + total_size);
-   return &array[index];
-}
-
-u32 _replay_frame_size( u32 subsystem_gamestate_size, u32 sfx_count ){
-   return vg_align8( sizeof( replay_frame ) ) + 
-          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->subsystem_gamestate_size, 
-                              frame->sfx_count );
+   return total;
 }
 
 VG_STATIC void replay_tailpop( replay_buffer *replay ){
@@ -67,15 +47,27 @@ VG_STATIC void replay_tailpop( replay_buffer *replay ){
 }
 
 VG_STATIC replay_frame *replay_newframe( replay_buffer *replay, 
-                                         u32 subsystem_gamestate_size, 
-                                         u32 sfx_count ){
+                                         u16 animator_size,
+                                         u16 gamestate_size,
+                                         u16 sfx_count ){
+   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_internal_gamestate ][1] = 0;
+   if( gamestate_size ){
+      data_table[ k_replay_framedata_internal_gamestate ][1] = 
+         sizeof( replay_gamestate );
+   }
+
+   u32 nextsize = replay_frame_calculate_data_offsets( data_table );
+
    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( subsystem_gamestate_size, sfx_count );
+      u32 headsize = replay->head->total_size,
+          nextpos  = ((void *)replay->head - replay->data) + headsize;
 
       if( nextsize > replay->size ){
          vg_error( "Keyframe too big\n" );
@@ -94,7 +86,6 @@ VG_STATIC replay_frame *replay_newframe( replay_buffer *replay,
       }
 
 check_again:;
-
       u32 tailpos = (void *)replay->tail - replay->data;
 
       if( tailpos >= nextpos ){
@@ -114,13 +105,17 @@ check_again:;
    else
       frame = replay->data;
 
-   frame->subsystem_gamestate_size = subsystem_gamestate_size;
-   frame->sfx_count = sfx_count;
+   for( u32 i=0; i<4; i++ ){
+      frame->data_table[i][0] = data_table[i][0];
+      frame->data_table[i][1] = data_table[i][1];
+   }
+
+   frame->total_size = nextsize;
    frame->l = replay->head;
    frame->r = NULL;
    replay->head = frame;
    if( !replay->tail ) replay->tail = frame;
-   if( subsystem_gamestate_size ) replay->statehead = frame;
+   if( gamestate_size ) replay->statehead = frame;
 
    return frame;
 }
@@ -174,7 +169,7 @@ VG_STATIC replay_frame *replay_find_recent_stateframe( replay_buffer *replay ){
    u32 i=4096;
    while( i --> 0 ){
       if( !frame ) return frame;
-      if( frame->subsystem_gamestate_size ) return frame;
+      if( frame->data_table[ k_replay_framedata_gamestate ][1] ) return frame;
       frame = frame->l;
    }
 
@@ -253,8 +248,7 @@ void skaterift_record_frame( replay_buffer *replay, int force_gamestate ){
 
    if( !save_frame ) return;
 
-   u32 gamestate_size = 0;
-
+   u16 gamestate_size = 0;
    if( save_state ){
       gamestate_size = (u32 []){ 
          [k_player_subsystem_walk ] = sizeof(struct player_walk_state),
@@ -264,12 +258,21 @@ void skaterift_record_frame( replay_buffer *replay, int force_gamestate ){
                                        sizeof(struct replay_rb)
       }[ localplayer.subsystem ];
    }
+
+   u16 animator_size = (u16 []){
+      [k_player_subsystem_walk ] = sizeof(struct player_walk_animator),
+      [k_player_subsystem_drive] = 0,
+      [k_player_subsystem_skate] = sizeof(struct player_skate_animator),
+      [k_player_subsystem_dead ] = sizeof(struct player_dead_animator)
+   }[ localplayer.subsystem ];
    
-   replay_frame *frame = replay_newframe( replay, gamestate_size, 0 );
+   replay_frame *frame = replay_newframe( replay,
+                                          animator_size, gamestate_size, 0 );
+   frame->system = localplayer.subsystem;
 
    if( save_state ){
-      replay_gamestate *gs = replay_frame_gamestate( frame );
-      gs->system = localplayer.subsystem;
+      replay_gamestate *gs = 
+         replay_frame_data( frame, k_replay_framedata_internal_gamestate );
 
       /* permanent block */
       memcpy( &gs->rb, &localplayer.rb, sizeof(rigidbody) );
@@ -277,7 +280,7 @@ void skaterift_record_frame( replay_buffer *replay, int force_gamestate ){
                sizeof(struct player_cam_controller) );
       v3_copy( localplayer.angles, gs->angles );
 
-      void *dst = replay_gamestate_subsystem_data( gs );
+      void *dst = replay_frame_data( frame, k_replay_framedata_gamestate );
 
       /* subsytem/dynamic block */
       if( localplayer.subsystem == k_player_subsystem_walk )
@@ -298,53 +301,44 @@ void skaterift_record_frame( replay_buffer *replay, int force_gamestate ){
 
    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;
-
-   memcpy( &frame->board_pose, &localplayer.board_pose, 
-            sizeof(localplayer.board_pose) );
    frame->time = vg.time;
-   v3_copy( localplayer.cam.pos, frame->cam_pos );
 
+   /* camera */
+   v3_copy( localplayer.cam.pos, frame->cam_pos );
    if( localplayer.gate_waiting ){
       m4x3_mulv( localplayer.gate_waiting->transport, 
                   frame->cam_pos, frame->cam_pos );
-
-      for( u32 i=1; i<sk->bone_count; i++ ){
-         struct skeleton_bone *sb = &sk->bones[i];
-         mdl_keyframe *kf = &res->pose[i-1];
-         m4x3f mtx;
-         m4x3_mul( localplayer.gate_waiting->transport, sk->final_mtx[i], mtx );
-         m4x3_decompose( mtx, kf->co, kf->q, kf->s );
-      }
    }
-   else
-      skeleton_decompose_mtx_absolute( sk, res->pose );
-
    v3_copy( localplayer.cam.angles, frame->cam_angles );
    frame->cam_fov = localplayer.cam.fov;
+
+   /* animator */
+   void *dst = replay_frame_data( frame, k_replay_framedata_animator );
+
+   if( localplayer.subsystem == k_player_subsystem_walk )
+      memcpy( dst, &localplayer._walk.animator, animator_size );
+   else if( localplayer.subsystem == k_player_subsystem_skate )
+      memcpy( dst, &localplayer._skate.animator, animator_size );
+   else if( localplayer.subsystem == k_player_subsystem_dead ){
+      memcpy( dst, &localplayer._dead.animator, animator_size );
+   }
 }
 
 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 );
+   replay_gamestate *gs = 
+      replay_frame_data( frame, k_replay_framedata_internal_gamestate );
+   void *src = replay_frame_data( frame, k_replay_framedata_gamestate );
+   u16 src_size = frame->data_table[ k_replay_framedata_gamestate ][1];
+   assert( src_size );
+
+   if(frame->system == k_player_subsystem_walk ){
+      memcpy( &localplayer._walk.state, src, src_size );
    }
-   else if( gs->system == k_player_subsystem_skate ){
-      memcpy( &localplayer._skate.state, src,
-              frame->subsystem_gamestate_size );
+   else if( frame->system == k_player_subsystem_skate ){
+      memcpy( &localplayer._skate.state, src, src_size );
    }
-   else if( gs->system == k_player_subsystem_dead ){
+   else if( frame->system == k_player_subsystem_dead ){
       player__dead_transition( &localplayer );
       struct replay_rb *arr = src;
 
@@ -362,7 +356,7 @@ void skaterift_restore_frame( replay_frame *frame ){
       }
    }
 
-   localplayer.subsystem = gs->system;
+   localplayer.subsystem = frame->system;
 
    memcpy( &localplayer.rb, &gs->rb, sizeof(rigidbody) );
    v3_copy( gs->angles, localplayer.angles );
@@ -540,10 +534,15 @@ VG_STATIC void skaterift_replay_debug_info(void){
    player__debugtext( 1, "head @%u | tail @%u\n", head, tail );
 
    if( replay->statehead ){
+      for( u32 i=0; i<4; i++ ){
+         player__debugtext( 1, "[%u]: [%hu, %hu]\n", i,
+              replay->statehead->data_table[i][0],
+              replay->statehead->data_table[i][1] );
+      }
       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 );
+      player__debugtext( 1, "gamestate_size: %hu\n", 
+           replay->statehead->data_table[k_replay_framedata_gamestate][1] );
    }
    else
       player__debugtext( 1, "gs @NULL\n" );