before the storm
[carveJwlIkooP6JGAAIwe30JlM.git] / player.h
index 7f02ec0eee4e0f09e5b18bded7da3938bd266b61..6fb74dcf6427c5c6ce6a709399f77edb9a9dadec 100644 (file)
--- a/player.h
+++ b/player.h
@@ -1,3 +1,7 @@
+/*
+ * Copyright 2021-2022 (C) Mount0 Software, Harry Godden - All Rights Reserved
+ */
+
 #ifndef PLAYER_H
 #define PLAYER_H
 
@@ -46,6 +50,7 @@ static struct gplayer
 
    /* TODO: eugh */
    m3x3f gate_vr_frame, gate_vr_pstep_frame;
+   int on_board_frame, in_air_frame;
 
    v3f a, v_last, m, bob, vl;
 
@@ -92,6 +97,9 @@ static struct gplayer
          fsetup,
          walk_timer,
          fonboard;
+
+v3f last_step_pos;
+   int step_phase;
 }
 player = 
 {
@@ -105,6 +113,11 @@ player =
  * Player API
  */
 
+static float *player_get_pos(void)
+{
+   return player.rb.co;
+}
+
 
 /*
  * Free camera movement
@@ -519,6 +532,8 @@ static void player_walk_physics(void)
          }
       }
    }
+
+   player.in_air = len==0?1:0;
    
    v3_zero( player.rb.w );
    q_axis_angle( player.rb.q, (v3f){0.0f,1.0f,0.0f}, -player.angles[0] );
@@ -544,8 +559,8 @@ static void player_walk_physics(void)
       v3_muladds( player.rb.v, forward_dir, diff, player.rb.v );
 
       /* TODO move */
-      float walk_norm = (float)player.mdl.anim_walk->length / 30.0f,
-            run_norm  = (float)player.mdl.anim_run->length  / 30.0f;
+      float walk_norm = 30.0f/(float)player.mdl.anim_walk->length,
+            run_norm  = 30.0f/(float)player.mdl.anim_run->length ;
 
       player.walk_timer += ktimestep * vg_lerpf( walk_norm,run_norm,move_norm );
    }
@@ -723,7 +738,7 @@ static void player_physics(void)
          audio_lock();
          audio_player_set_flags( &audio_player_extra, AUDIO_FLAG_SPACIAL_3D );
          audio_player_set_position( &audio_player_extra, player.rb.co );
-         audio_player_set_vol( &audio_player_extra, 3.0f );
+         audio_player_set_vol( &audio_player_extra, 20.0f );
          audio_player_playclip( &audio_player_extra, &audio_jumps[rand()%4] );
          audio_unlock();
       }
@@ -806,7 +821,19 @@ static void player_do_motion(void)
          
          world_routes_activate_gate( i );
          player.rb_gate_frame = player.rb;
+         player.in_air_frame = player.in_air;
+         player.on_board_frame = player.on_board;
+
+         if( !player.on_board )
+         {
+            v3f fwd_dir = {cosf(player.angles[0]),
+                           0.0f,
+                           sinf(player.angles[0])};
+            m3x3_mulv( gate->transport, fwd_dir, fwd_dir );
 
+            player.angles[0] = atan2f( fwd_dir[2], fwd_dir[0] );
+         }
+         
          m3x3_copy( player.vr, player.gate_vr_frame );
          m3x3_copy( player.vr_pstep, player.gate_vr_pstep_frame );
 
@@ -829,13 +856,13 @@ static void player_animate_offboard(void)
    mdl_keyframe apose[32], bpose[32];
    struct skeleton *sk = &player.mdl.sk;
 
-   float walk_norm = 30.0f/(float)player.mdl.anim_walk->length,
-         run_norm  = 30.0f/(float)player.mdl.anim_run->length,
+   float walk_norm = (float)player.mdl.anim_walk->length/30.0f,
+         run_norm  = (float)player.mdl.anim_run->length/30.0f,
          t = player.walk_timer,
          l = vg_get_axis("grabr") * 0.5f + 0.5f;
 
    skeleton_sample_anim( sk, player.mdl.anim_walk, t*walk_norm, apose );
-   skeleton_sample_anim( sk, player.mdl.anim_run,  t*run_norm,  bpose );
+   skeleton_sample_anim( sk, player.mdl.anim_run,  t*run_norm, bpose );
 
    skeleton_lerp_pose( sk, apose, bpose, l, apose );
 
@@ -909,7 +936,6 @@ static void player_animate(void)
 
    offset[0] = vg_clampf( offset[0], -0.8f, 0.8f );
    offset[1] = vg_clampf( offset[1], -0.5f, 0.0f );
-   offset[1] = 0.0f;
 
    /* 
     * Animation blending
@@ -1009,7 +1035,7 @@ static void player_animate(void)
 
    skeleton_lerp_pose( sk, ground_pose, air_pose, player.ffly, apose );
 
-   float add_grab_mod = player.ffly * player.grab;
+   float add_grab_mod = 1.0f - player.ffly*player.grab;
 
    /* additive effects */
    apose[player.mdl.id_hip-1].co[0] += offset[0]*add_grab_mod;
@@ -1038,9 +1064,13 @@ static void player_animate(void)
 static void player_camera_update(void)
 {
    /* Update camera matrices */
-   m4x3_identity( player.camera );
-   m4x3_rotate_y( player.camera, -player.angles[0] );
-   m4x3_rotate_x( player.camera, -player.angles[1] );
+   v4f qyaw, qpitch, qcam;
+   q_axis_angle( qyaw, (v3f){ 0.0f, 1.0f, 0.0f }, -player.angles[0] ); 
+   q_axis_angle( qpitch, (v3f){ 1.0f, 0.0f, 0.0f }, -player.angles[1] ); 
+
+   q_mul( qyaw, qpitch, qcam );
+   q_m3x3( qcam, player.camera );
+
    v3_copy( player.camera_pos, player.camera[3] );
    m4x3_invert_affine( player.camera, player.camera_inverse );
 }
@@ -1170,7 +1200,8 @@ static void player_audio(void)
    audio_lock();
    
    double revert_delta = vg_time - last_revert;
-   if( (!_air && l2) && (fabsf(player.slip) > 0.5f) && (revert_delta > 0.7) )
+   if( player.on_board && (!_air && l2) && (fabsf(player.slip) > 0.5f) && 
+         (revert_delta > 0.7) )
    {
       audio_player_set_position( &audio_player_extra, player.rb.co );
       audio_player_set_flags( &audio_player_extra, AUDIO_FLAG_SPACIAL_3D );
@@ -1208,12 +1239,66 @@ static void player_audio(void)
 
    /* Tunnel / occlusion */
    audio_sample_occlusion( player.camera[3] );
+
+   int sprite_avail = -1;
+   for( int i=0; i<vg_list_size(ambient_sprites); i++ )
+   {
+      if( !audio_player_is_playing( &ambient_sprites[i] ) )
+      {
+         sprite_avail = i;
+         break;
+      }
+   }
+   
+   if( sprite_avail != -1 )
+   {
+      v3f waterpos;
+      enum audio_sprite_type sprite_type = 
+         audio_sample_sprite_random( player.rb.co, waterpos );
+
+      if( sprite_type != k_audio_sprite_type_none )
+      {
+         audio_player *avail = &ambient_sprites[ sprite_avail ];
+
+         audio_player_set_vol( avail, 20.0f );
+         audio_player_set_flags( avail, AUDIO_FLAG_SPACIAL_3D );
+         audio_player_set_position( avail, waterpos );
+
+         if( sprite_type == k_audio_sprite_type_grass )
+         {
+            audio_player_playclip( avail, &audio_grass[rand()%4] );
+         }
+         else if( sprite_type == k_audio_sprite_type_water )
+         {
+            audio_player_playclip( avail, &audio_water[rand()%6] );
+         }
+      }
+   }
    
    if( freecam || player.is_dead || !player.on_board )
    {
       audio_player_set_vol( &audio_player0, 0.0f );
       audio_player_set_vol( &audio_player1, 0.0f );
       audio_player_set_vol( &audio_player2, 0.0f );
+
+      int walk_phase = 0;
+      if( vg_fractf(player.walk_timer) > 0.5f )
+         walk_phase = 1;
+      else
+         walk_phase = 0;
+
+      if( (player.step_phase != walk_phase) && !player.in_air )
+      {
+         v3_copy( player.rb.co, player.last_step_pos );
+
+         audio_player_set_flags( &audio_player_extra, AUDIO_FLAG_SPACIAL_3D );
+         audio_player_set_position( &audio_player_extra, player.rb.co );
+         audio_player_set_vol( &audio_player_extra, 6.0f );
+         audio_player_playclip( &audio_player_extra, 
+                                          &audio_footsteps[rand()%4] );
+      }
+
+      player.step_phase = walk_phase;
    }
    else
    {
@@ -1313,6 +1398,8 @@ static int reset_player( int argc, char const *argv[] )
    m3x3_identity( player.gate_vr_pstep_frame );
 
    player.rb_gate_frame = player.rb;
+   player.on_board_frame = player.on_board;
+   player.in_air_frame = player.in_air;
    return 1;
 }
 
@@ -1325,10 +1412,20 @@ static void player_update(void)
    if( vg_get_axis("grabl")>0.0f)
    {
       player.rb = player.rb_gate_frame;
+      player.on_board = player.on_board_frame;
+      player.in_air = player.in_air_frame;
       m3x3_copy( player.gate_vr_frame, player.vr );
       m3x3_copy( player.gate_vr_pstep_frame, player.vr_pstep );
       player.is_dead = 0;
       player.in_air = 1;
+
+
+      if( !player.on_board )
+      {
+         player.angles[0] = atan2f( -player.rb.forward[2], 
+                                    -player.rb.forward[0] );
+      }
+
       m3x3_identity( player.vr );
 
       player.mdl.shoes[0] = 1;