replay system reasonable
authorhgn <hgodden00@gmail.com>
Sun, 9 Jul 2023 01:50:46 +0000 (02:50 +0100)
committerhgn <hgodden00@gmail.com>
Sun, 9 Jul 2023 01:50:46 +0000 (02:50 +0100)
player.c
player_render.c
player_replay.c
player_replay.h
skaterift.c
skaterift.h

index 4746e4fb4c774e0777cc46cc7911dd98f20d2fee..d248aec116445aa558842503ecb521c4cc950680 100644 (file)
--- 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);
index 3fe93369c09226e7eb2fde5344af36b4edd4f977..b6cbf6311f387bae3f1aee10de0f9e8d92b4a28c 100644 (file)
@@ -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 = 
index 38c21921aa387af1f9dfe04cde497ad0b8abd38b..09cc136cbd477d6395aaea837b2486f815ae1da9 100644 (file)
@@ -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 */
index 20eafb4c08d8081ca0b4b68b1e21af819ee1875c..52a077291594ecd4fb1500c16b8fbcbe103af126 100644 (file)
@@ -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 */
index 8df2f8a098ef0a6f93f67cda440154cd10483696..64fb65a2055522ca7f3d2d37b6944c14f10a5d45 100644 (file)
@@ -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();
 }
index e78df2f40864ee4bb9be25b1a900e201c7973062..1e2fba31e67ac12bc4c6eb0d14761c826f3d372d 100644 (file)
@@ -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,