waeeij
authorhgn <hgodden00@gmail.com>
Wed, 1 Feb 2023 10:05:47 +0000 (10:05 +0000)
committerhgn <hgodden00@gmail.com>
Wed, 1 Feb 2023 10:05:47 +0000 (10:05 +0000)
player_device_common.h
player_device_dead.h
player_device_skate.h
player_device_walk.h
player_interface.h
skaterift.c

index 6e468eb9e8124746cb093febf1cc9a1ac3b08cdf..07a3d87194a9c82fc87792d93b8ae05a190787cf 100644 (file)
 #include "common.h"
 #include "player_interface.h"
 
-struct mixedcam_state
+struct device_transition_skateboard
 {
-   v3f vl, vt, pos, post, dir;
-   struct teleport_gate *gate;
+   v3f dir;
 };
 
-/* 
- * this is a little yucky but needs to be done so we can use this 'prediction' 
- * in the pose function. its unfortunate. too bad
- */
-VG_STATIC void followcam_nextpos( player_interface *player,
-                                  struct mixedcam_state *mc,
-                                  v3f next_pos, v3f d )
+struct device_transition_walk
 {
-}
-
-
-VG_STATIC int followcam_will_hit_gate( player_interface *player,
-                                       struct mixedcam_state *mc )
-{
-   if( mc->gate )
-   {
-      v3f next_pos, d, _;
-      followcam_nextpos( player, mc, next_pos, d );
-
-      return gate_intersect_plane( mc->gate, next_pos, mc->pos, _ );
-   }
-
-   return 0;
-}
-
-VG_STATIC void mixedcam_transport( struct mixedcam_state *mc, 
-                                   teleport_gate *gate )
-{
-   m3x3_mulv( gate->transport, mc->vl, mc->vl );
-   mc->gate = gate;
-
-#if 0
-   if( !cl_thirdperson )
-      player_apply_transport_to_cam( gate->transport );
-#endif
-}
-
-VG_STATIC void mixedcam_reset( player_interface *player, 
-                               struct mixedcam_state *mc )
-{
-   mc->gate = NULL;
-}
-
-
-VG_STATIC void mixedcam_set_targets( struct mixedcam_state *mc, v3f v, v3f co )
-{
-   v3_copy( v, mc->vt );
-   v3_copy( co, mc->post );
-}
-
-
-VG_STATIC void mixedcam_iterate_firstperson_frame( player_interface *player,
-                                                   struct mixedcam_state *mc )
-{
-   v3_lerp( mc->vl, mc->vt, 4.0f*vg.time_delta, mc->vl );
-}
-
-VG_STATIC void mixedcam_iterate_thirdperson_frame( player_interface *player,
-                                                   struct mixedcam_state *mc )
-{
-   v3f prev_pos, origin, target, dir;
-
-   v3_copy( mc->pos, prev_pos );
-
-   if( mc->gate )
-   {
-      m4x3f inverse;
-      m4x3_invert_affine( mc->gate->transport, inverse );
-      m4x3_mulv( inverse, mc->post, origin );
-   }
-   else
-   {
-      v3_copy( mc->post, origin );
-   }
-
-   /* TODO: Remove? */
-   v3_add( origin, (v3f){0.0f,1.35f,0.0f}, origin );
-   v3_sub( origin, mc->pos, dir );
-   
-   if( v3_length2( dir ) < 0.1f*0.1f )
-      v3_copy( (v3f){ 0.0f, 0.0f, 1.0f }, dir );   /* FIXME */
-   else
-      v3_normalize( dir );
-
-   v3_muladds( origin, dir, -2.0f, target );
-   v3_lerp( mc->pos, target, vg.frame_delta * 12.0f, mc->pos );
-   v3_copy( dir, mc->dir );
-
-   if( mc->gate )
-   {
-      v2f _;
-      if( gate_intersect_plane( mc->gate, mc->pos, prev_pos, _ ) )
-      {
-         m4x3_mulv( mc->gate->transport, mc->pos, mc->pos );
-         m3x3_mulv( mc->gate->transport, mc->dir, mc->dir );
-         //player_apply_transport_to_cam( mc->gate->transport );
-
-         mc->gate = NULL;
-      }
-   }
-}
-
-VG_STATIC void mixedcam_iterate_frame( player_interface *player,
-                                       struct mixedcam_state *mc )
-{
-   if( cl_thirdperson )
-      mixedcam_iterate_thirdperson_frame( player, mc );
-   else
-      mixedcam_iterate_firstperson_frame( player, mc );
-}
-
-VG_STATIC void mixedcam_get_camera( struct mixedcam_state *mc )
-{
-   
-}
+   v3f angles;
+};
 
 #endif /* PLAYER_DEVICE_COMMON_H */
index 9a0ed20940049aab2a269bd81eb53877455322d6..56055714d63bf6b24fab80af58f1e60646ee48ef 100644 (file)
@@ -5,97 +5,60 @@
 #include "skeleton.h"
 #include "player_model.h"
 
+VG_STATIC
 struct player_device_dead
 {
-};
-
-VG_STATIC void player_dead_pre_update( player_interface *player,
-                                       player_attachment *at )
-{
-}
-
-VG_STATIC void player_dead_update( player_interface *player,
-                                   player_attachment *at )
-{
-   player_ragdoll_iter( &player->ragdoll );
-}
-
-VG_STATIC void player_dead_post_update( player_interface *player,
-                                        player_attachment *at )
-{
-}
-
-VG_STATIC void player_dead_ui( player_interface *player,
-                               player_attachment *at )
-{
+   int _;
 }
+localplayer_device_dead;
 
-VG_STATIC void player_dead_bind( player_interface *player,
-                                 player_attachment *at )
+VG_STATIC int player_dead_event( player_device *dev, player_interface *player,
+                                 enum player_device_event_type ev, void *data )
 {
-   copy_avatar_pose_to_ragdoll( player->playeravatar, &player->ragdoll, 
-                                player->rb.v );
-}
-
-/* FIXME: This should be an optional function */
-VG_STATIC void player_dead_animate( player_interface *player,
-                                    player_attachment *at )
-{
-   v3_zero( at->pose_root_co );
-   q_identity( at->pose_root_q );
-   
-   for( int i=0; i<vg_list_size( at->pose ); i ++ )
+   if( ev == k_player_device_event_update )
    {
-      v3_zero( at->pose[i].co );
-      v3_fill( at->pose[i].s, 1.0f );
-      q_identity( at->pose[i].q );
+      player_ragdoll_iter( &player->ragdoll );
    }
-}
-
-VG_STATIC void player_dead_post_animate( player_interface *player,
-                                         player_attachment *at )
-{
-   struct player_avatar *av = player->playeravatar;
-
-   v3_zero( at->cam_1st.pos );
-   v3_zero( at->cam_1st.angles );
-   at->cam_1st.fov = 90.0f;
-   
-   /* FIXME: This overwrites pose blending, however, do we need to blend with 
-    * this device, anyway? */
-   copy_ragdoll_pose_to_avatar( &player->ragdoll, player->playeravatar );
-
-#if 0
-   v3f vp = {-0.1f,1.8f,0.0f},
-       vd = {-1.0f,0.0f,0.0f};
-
-   m4x3_mulv( av->sk.final_mtx[ av->id_head-1 ], vp, cam->pos );
-   m3x3_mulv( av->sk.final_mtx[ av->id_head-1 ], vd, vd );
-
-   v3_zero( cam->angles );
-   cam->fov = 119.0f;
-
-   skate_camera_vector_look( cam, vd, 1.0f, 0.0f );
-#endif
-}
+   else if( ev == k_player_device_event_custom_transition )
+   {
+      copy_avatar_pose_to_ragdoll( player->playeravatar, &player->ragdoll, 
+                                   player->rb.v );
+   }
+   else if( ev == k_player_device_event_animate )
+   {
+      v3_zero( dev->pose_root_co );
+      q_identity( dev->pose_root_q );
+      
+      for( int i=0; i<vg_list_size( dev->pose ); i ++ )
+      {
+         v3_zero( dev->pose[i].co );
+         v3_fill( dev->pose[i].s, 1.0f );
+         q_identity( dev->pose[i].q );
+      }
+   }
+   else if( ev == k_player_device_event_post_animate )
+   {
+      struct player_avatar *av = player->playeravatar;
+
+      v3_zero( dev->cam_1st.pos );
+      v3_zero( dev->cam_1st.angles );
+      dev->cam_1st.fov = 90.0f;
+      
+      /* FIXME: This overwrites pose blending, however, do we need to blend with 
+       * this device, anyway? */
+      copy_ragdoll_pose_to_avatar( &player->ragdoll, player->playeravatar );
+   }
+   else
+      return 0;
 
-VG_STATIC void player_dead_transport( player_interface *player,
-                                      player_attachment *at,
-                                      teleport_gate *gate )
-{
+   return 1;
 }
 
 VG_STATIC player_device player_device_dead =
 {
-   .pre_update    = player_dead_pre_update,
-   .update        = player_dead_update,
-   .post_update   = player_dead_post_update,
-   .animate       = player_dead_animate,
-   .post_animate  = player_dead_post_animate,
-   .debug_ui      = player_dead_ui,
-   .bind          = player_dead_bind,
-#if 0
-   .pose          = player_dead_pose,
-#endif
+   .name          = "ragdoll/dead",
+   .event         = player_dead_event,
+   .storage       = &localplayer_device_dead
 };
+
 #endif /* PLAYER_DEVICE_DEAD_H */
index 13f6398a0b549d37f338b2b25ffd0bacb7062320..5ae2a9bb0f30d95faa662d2c593c3f304fb0b224 100644 (file)
@@ -6,6 +6,7 @@
 #include "player_model.h"
 #include "player_device_common.h"
 
+VG_STATIC
 struct player_device_skate
 {
    struct
@@ -97,12 +98,14 @@ struct player_device_skate
    v2f wobble;
 
    float debug_normal_pressure;
-};
+   u32 device_id_walk;
+}
+localplayer_device_skate;
 
-VG_STATIC void player_skate_bind( player_interface *player,
-                                  player_attachment *at )
+VG_STATIC void player_skate_bind( player_device *dev,
+                                  player_interface *player )
 {
-   struct player_device_skate *s = at->storage;
+   struct player_device_skate *s = dev->storage;
    struct player_avatar *av = player->playeravatar;
    struct skeleton *sk = &av->sk;
 
@@ -116,11 +119,8 @@ VG_STATIC void player_skate_bind( player_interface *player,
    s->anim_ollie           = skeleton_get_anim( sk, "ollie" );
    s->anim_ollie_reverse   = skeleton_get_anim( sk, "ollie_reverse" );
    s->anim_grabs           = skeleton_get_anim( sk, "grabs" );
-}
 
-VG_STATIC void player_skate_pre_update( player_interface *player,
-                                        player_attachment *at )
-{
+   s->device_id_walk = player_get_device( player, "walk" );
 }
 
 /* 
@@ -210,8 +210,9 @@ VG_STATIC struct grind_edge *skate_collect_grind_edge( v3f p0, v3f p1,
    return closest_edge;
 }
 
-VG_STATIC int skate_grind_collide( player_interface *player, 
-                                   player_attachment *at, rb_ct *contact )
+VG_STATIC int skate_grind_collide( player_device *dev,
+                                   player_interface *player, 
+                                   rb_ct *contact )
 {
    v3f p0, p1, c0, c1;
    v3_muladds( player->rb.co, player->rb.to_world[2],  0.5f, p0 );
@@ -1101,10 +1102,10 @@ VG_STATIC void skate_integrate( player_interface *player,
    rb_update_transform( &player->rb );
 }
 
-VG_STATIC void player_skate_update( player_interface *player,
-                                    player_attachment *at )
+VG_STATIC void player_skate_update( player_device *dev,
+                                    player_interface *player )
 {
-   struct player_device_skate *s = at->storage;
+   struct player_device_skate *s = dev->storage;
    v3_copy( player->rb.co, s->state.prev_pos );
    s->state.activity_prev = s->state.activity;
 
@@ -1160,7 +1161,7 @@ VG_STATIC void player_skate_update( player_interface *player,
    interface_manifold = manifold;
    grind_manifold = manifold + interface_len;
 
-   int grind_len = skate_grind_collide( player, at, grind_manifold );
+   int grind_len = skate_grind_collide( dev, player, grind_manifold );
 
    for( int i=0; i<interface_len+grind_len; i ++ )
    {
@@ -1216,15 +1217,9 @@ VG_STATIC void player_skate_update( player_interface *player,
    }
 }
 
-VG_STATIC void player_skate_post_update( player_interface *player,
-                                         player_attachment *at )
+VG_STATIC void player_skate_ui( player_device *dev, player_interface *player )
 {
-}
-
-VG_STATIC void player_skate_ui( player_interface *player,
-                                player_attachment *at )
-{
-   struct player_device_skate *s = at->storage;
+   struct player_device_skate *s = dev->storage;
 
    /* FIXME: Compression */
    player_debugtext( 1, "V:  %5.2f %5.2f %5.2f",player->rb.v[0],
@@ -1247,10 +1242,10 @@ VG_STATIC void player_skate_ui( player_interface *player,
                         k_steer_ground, k_steer_air );
 }
 
-VG_STATIC void player_skate_animate( player_interface *player,
-                                     player_attachment *at )
+VG_STATIC void player_skate_animate( player_device *dev, 
+                                     player_interface *player )
 {
-   struct player_device_skate *s = at->storage;
+   struct player_device_skate *s = dev->storage;
    struct player_avatar *av = player->playeravatar;
    struct skeleton *sk = &av->sk;
 
@@ -1413,7 +1408,7 @@ VG_STATIC void player_skate_animate( player_interface *player,
       skeleton_lerp_pose( sk, apose, bpose, s->state.grabbing, air_pose );
    }
 
-   skeleton_lerp_pose( sk, ground_pose, air_pose, s->blend_fly, at->pose );
+   skeleton_lerp_pose( sk, ground_pose, air_pose, s->blend_fly, dev->pose );
 
    float add_grab_mod = 1.0f - s->blend_fly;
 
@@ -1427,13 +1422,13 @@ VG_STATIC void player_skate_animate( player_interface *player,
 
       for( int i=0; i<vg_list_size(apply_to); i ++ )
       {
-         at->pose[apply_to[i]-1].co[0] += offset[0]*add_grab_mod;
-         at->pose[apply_to[i]-1].co[2] += offset[2]*add_grab_mod;
+         dev->pose[apply_to[i]-1].co[0] += offset[0]*add_grab_mod;
+         dev->pose[apply_to[i]-1].co[2] += offset[2]*add_grab_mod;
       }
 
-      mdl_keyframe *kf_board  = &at->pose[av->id_board-1],
-                   *kf_foot_l = &at->pose[av->id_ik_foot_l-1],
-                   *kf_foot_r = &at->pose[av->id_ik_foot_r-1];
+      mdl_keyframe *kf_board  = &dev->pose[av->id_board-1],
+                   *kf_foot_l = &dev->pose[av->id_ik_foot_l-1],
+                   *kf_foot_r = &dev->pose[av->id_ik_foot_r-1];
 
       v3f bo;
       v3_muls( s->board_offset, add_grab_mod, bo );
@@ -1459,10 +1454,10 @@ VG_STATIC void player_skate_animate( player_interface *player,
    }
 
    /* transform */
-   rb_extrapolate( &player->rb, at->pose_root_co, at->pose_root_q );
+   rb_extrapolate( &player->rb, dev->pose_root_co, dev->pose_root_q );
 
-   v3_muladds( at->pose_root_co, player->rb.to_world[1], -0.28f, 
-               at->pose_root_co );
+   v3_muladds( dev->pose_root_co, player->rb.to_world[1], -0.28f, 
+               dev->pose_root_co );
 
    v4f qresy, qresx, qresidual;
    m3x3f mtx_residual;
@@ -1472,8 +1467,8 @@ VG_STATIC void player_skate_animate( player_interface *player,
 
    q_mul( qresy, qresx, qresidual );
    q_normalize( qresidual );
-   q_mul( at->pose_root_q, qresidual, at->pose_root_q );
-   q_normalize( at->pose_root_q );
+   q_mul( dev->pose_root_q, qresidual, dev->pose_root_q );
+   q_normalize( dev->pose_root_q );
 
 #if 0
    if( cl_thirdperson )
@@ -1504,18 +1499,18 @@ VG_STATIC void skate_camera_vector_look( camera *cam, v3f v, float C, float k )
    cam->angles[1] = pitch;
 }
 
-VG_STATIC void skate_camera_firstperson( player_interface *player,
-                                         player_attachment *at )
+VG_STATIC void skate_camera_firstperson( player_device *dev,
+                                         player_interface *player )
 {
-   struct player_device_skate *s = at->storage;
+   struct player_device_skate *s = dev->storage;
    struct player_avatar *av = player->playeravatar;
 
    /* FIXME: viewpoint entity */
    v3f vp = {-0.1f,1.8f,0.0f};
-   m4x3_mulv( av->sk.final_mtx[ av->id_head-1 ], vp, at->cam_1st.pos );
+   m4x3_mulv( av->sk.final_mtx[ av->id_head-1 ], vp, dev->cam_1st.pos );
 
-   v3_zero( at->cam_1st.angles );
-   at->cam_1st.fov = 119.0f;
+   v3_zero( dev->cam_1st.angles );
+   dev->cam_1st.fov = 119.0f;
 
    v3f flat_dir,
        vel_dir,
@@ -1540,13 +1535,13 @@ VG_STATIC void skate_camera_firstperson( player_interface *player,
    v3_lerp( flat_dir, vel_dir, vg_clampf( tti / 2.0f, 0.4f, 1.0f ), look_dir );
    v3_lerp( s->state.vl, look_dir, 4.0f*vg.time_delta, s->state.vl );
 
-   skate_camera_vector_look( &at->cam_1st, s->state.vl, 1.0f, 0.25f );
+   skate_camera_vector_look( &dev->cam_1st, s->state.vl, 1.0f, 0.25f );
 }
 
-VG_STATIC void skate_camera_thirdperson( player_interface *player,
-                                         player_attachment *at )
+VG_STATIC void skate_camera_thirdperson( player_device *dev,
+                                         player_interface *player )
 {
-   struct player_device_skate *s = at->storage;
+   struct player_device_skate *s = dev->storage;
    struct player_avatar *av = player->playeravatar;
 
    v3f origin, dir, target;
@@ -1562,23 +1557,23 @@ VG_STATIC void skate_camera_thirdperson( player_interface *player,
    v3_muladds( origin, dir, -2.0f, target );
    v3_lerp( s->state.posl, target, vg.frame_delta * 12.0f, s->state.posl );
 
-   v3_copy( s->state.posl, at->cam_3rd.pos );
-   skate_camera_vector_look( &at->cam_3rd, dir, 1.0f, 0.0f );
-   at->cam_3rd.fov = 100.0f;
+   v3_copy( s->state.posl, dev->cam_3rd.pos );
+   skate_camera_vector_look( &dev->cam_3rd, dir, 1.0f, 0.0f );
+   dev->cam_3rd.fov = 100.0f;
 }
 
-VG_STATIC void player_skate_post_animate( player_interface *player,
-                                          player_attachment *at )
+VG_STATIC void player_skate_post_animate( player_device *dev,
+                                          player_interface *player )
 {
-   struct player_device_skate *s = at->storage;
+   struct player_device_skate *s = dev->storage;
    struct player_avatar *av = player->playeravatar;
 
-   v3_zero( at->cam_1st.pos );
-   v3_zero( at->cam_1st.angles );
-   at->cam_1st.fov = 90.0f;
+   v3_zero( dev->cam_1st.pos );
+   v3_zero( dev->cam_1st.angles );
+   dev->cam_1st.fov = 90.0f;
 
-   skate_camera_thirdperson( player, at );
-   skate_camera_firstperson( player, at );
+   skate_camera_thirdperson( dev, player );
+   skate_camera_firstperson( dev, player );
 
    /* FIXME: Organize this. Its int wrong fucking place */
    v3f vp0 = {0.0f,0.1f, 0.6f},
@@ -1588,17 +1583,11 @@ VG_STATIC void player_skate_post_animate( player_interface *player,
    m4x3_mulv( av->sk.final_mtx[ av->id_board ], vp1, TEMP_BOARD_1 );
 }
 
-VG_STATIC void player_skate_transport( player_interface *player,
-                                       player_attachment *at,
-                                       teleport_gate *gate )
-{
-}
-
-VG_STATIC void player_skate_reset( player_interface *player,
-                                   player_attachment *at,
+VG_STATIC void player_skate_reset( player_device *dev,
+                                   player_interface *player,
                                    struct respawn_point *rp )
 {
-   struct player_device_skate *s = at->storage;
+   struct player_device_skate *s = dev->storage;
    v3_muladds( player->rb.co, player->rb.to_world[1], 1.0f, s->state.cog );
 
 #if 0
@@ -1606,16 +1595,68 @@ VG_STATIC void player_skate_reset( player_interface *player,
 #endif
 }
 
+VG_STATIC int player_skate_event( player_device *dev, player_interface *player,
+                                  enum player_device_event_type ev, 
+                                  void *data )
+{
+   struct player_device_skate *s = dev->storage;
+
+   if( ev == k_player_device_event_bind )
+      player_skate_bind( dev, player );
+   else if( ev == k_player_device_event_respawn )
+      player_skate_reset( dev, player, data );
+   else if( ev == k_player_device_event_pre_update )
+   {
+      if( vg_input_button_down( player->input_use ) )
+      {
+         struct device_transition_walk inf;
+         v3_copy( player->cam.angles, inf.angles );
+         inf.angles[2] = 0.0f;
+
+         player_transition_to_device( player, s->device_id_walk, &inf );
+         return 1;
+      }
+   }
+   else if( ev == k_player_device_event_custom_transition )
+   {
+      /* transition coming in from walking */
+      struct device_transition_skateboard *inf = data;
+
+      q_axis_angle( player->rb.q, (v3f){0.0f,1.0f,0.0f}, 
+                    atan2f( inf->dir[0], inf->dir[2] ) );
+      v3_copy( player->cam.pos, s->state.posl );
+
+      rb_update_transform( &player->rb );
+      v3_muladds( player->rb.co, player->rb.to_world[1], 1.0f, s->state.cog );
+      v3_copy( player->rb.v, s->state.cog_v );
+   }
+   else if( ev == k_player_device_event_update )
+   {
+      player_skate_update( dev, player );
+   }
+   else if( ev == k_player_device_event_animate )
+   {
+      player_skate_animate( dev, player );
+   }
+   else if( ev == k_player_device_event_post_animate )
+   {
+      player_skate_post_animate( dev, player );
+   }
+   else if( ev == k_player_device_event_debug_ui )
+   {
+      player_skate_ui( dev, player );
+   }
+   else
+      return 0;
+
+   return 1;
+}
+
 VG_STATIC player_device player_device_skate =
 {
-   .pre_update    = player_skate_pre_update,
-   .update        = player_skate_update,
-   .post_update   = player_skate_post_update,
-   .animate       = player_skate_animate,
-   .post_animate  = player_skate_post_animate,
-   .debug_ui      = player_skate_ui,
-   .bind          = player_skate_bind,
-   .reset         = player_skate_reset
+   .name          = "skateboard",
+   .event         = player_skate_event,
+   .storage       = &localplayer_device_skate
 };
 
 #endif /* PLAYER_DEVICE_SKATE_H */
index 3b30d061fa040d808fe4bea56ae1e78d415ef079..c1fbd4fd5ee48bd1235f1c271e42688582508f4f 100644 (file)
@@ -2,9 +2,11 @@
 #define PLAYER_DEVICE_WALK_H
 
 #include "player_interface.h"
+#include "player_device_common.h"
 #include "skeleton.h"
 #include "player_model.h"
 
+VG_STATIC
 struct player_device_walk
 {
    rb_capsule collider;
@@ -26,7 +28,6 @@ struct player_device_walk
    state_gate_storage;
 
    enum mdl_surface_prop surface;
-
    struct skeleton_anim *anim_walk, *anim_run, *anim_idle, *anim_jump;
 
    float blend_fly,
@@ -35,14 +36,41 @@ struct player_device_walk
 
          move_speed,
          walk_timer;
-};
 
-VG_STATIC void player_walk_pre_update( player_interface *player,
-                                       player_attachment *at )
+   u32 device_id_skate;
+}
+localplayer_device_walk;
+
+VG_STATIC void player_walk_pre_update( player_device *dev, 
+                                       player_interface *player )
 {
-   struct player_device_walk *w = at->storage;
+   struct player_device_walk *w = dev->storage;
    player_look( player, w->state.angles );
 
+   if( vg_input_button_down( player->input_use ) )
+   {
+      struct device_transition_skateboard inf;
+
+      v3f xy_speed;
+      v3_copy( player->rb.v, xy_speed );
+      xy_speed[1] = 0.0f;
+
+      if( v3_length2( xy_speed ) > 0.1f * 0.1f )
+      {
+         v3_copy( player->rb.v, inf.dir );
+      }
+      else
+      {
+         inf.dir[0] = -sinf( -w->state.angles[0] );
+         inf.dir[1] =  0.0f;
+         inf.dir[2] = -cosf( -w->state.angles[0] );
+         v3_muls( inf.dir, 1.6f, player->rb.v );
+      }
+
+      player_transition_to_device( player, w->device_id_skate, &inf );
+      return;
+   }
+
 #if 0
    v3f walk = {  player->input_walkh->axis.value,
                  0.0f, 
@@ -96,10 +124,10 @@ VG_STATIC void player_friction( v3f v )
    v3_muls( v, newspeed, v );
 }
 
-VG_STATIC void player_walk_update( player_interface *player,
-                                   player_attachment *at )
+VG_STATIC void player_walk_update( player_device *dev, 
+                                   player_interface *player )
 {
-   struct player_device_walk *w = at->storage;
+   struct player_device_walk *w = dev->storage;
    v3_copy( player->rb.co, w->state.prev_pos );
 
    w->collider.height = 2.0f;
@@ -323,7 +351,7 @@ VG_STATIC void player_walk_update( player_interface *player,
    teleport_gate *gate;
    if( (gate = world_intersect_gates( player->rb.co, w->state.prev_pos )) )
    {
-      struct player_device_walk *w = at->storage;
+      struct player_device_walk *w = dev->storage;
 
       m4x3_mulv( gate->transport, player->rb.co, player->rb.co );
       m3x3_mulv( gate->transport, player->rb.v,  player->rb.v );
@@ -341,10 +369,10 @@ VG_STATIC void player_walk_update( player_interface *player,
    }
 }
 
-VG_STATIC void player_walk_post_update( player_interface *player,
-                                        player_attachment *at )
+VG_STATIC void player_walk_post_update( player_device *dev,
+                                        player_interface *player )
 {
-   struct player_device_walk *w = at->storage;
+   struct player_device_walk *w = dev->storage;
 
    m4x3f mtx;
    m3x3_identity( mtx );
@@ -360,10 +388,10 @@ VG_STATIC void player_walk_post_update( player_interface *player,
 
 }
 
-VG_STATIC void player_walk_animate( player_interface *player,
-                                    player_attachment *at )
+VG_STATIC void player_walk_animate( player_device *dev, 
+                                    player_interface *player )
 {
-   struct player_device_walk *w = at->storage;
+   struct player_device_walk *w = dev->storage;
    struct skeleton *sk = &player->playeravatar->sk;
 
    {
@@ -416,21 +444,21 @@ VG_STATIC void player_walk_animate( player_interface *player,
 
    /* air */
    skeleton_sample_anim( sk, w->anim_jump, vg.time*0.6f, bpose );
-   skeleton_lerp_pose( sk, apose, bpose, w->blend_fly, at->pose );
+   skeleton_lerp_pose( sk, apose, bpose, w->blend_fly, dev->pose );
 
    /* Create transform */
-   rb_extrapolate( &player->rb, at->pose_root_co, at->pose_root_q );
-   q_axis_angle( at->pose_root_q, (v3f){0.0f,1.0f,0.0f}, 
+   rb_extrapolate( &player->rb, dev->pose_root_co, dev->pose_root_q );
+   q_axis_angle( dev->pose_root_q, (v3f){0.0f,1.0f,0.0f}, 
                  -w->state.angles[0]-VG_PIf*0.5f );
 }
 
-VG_STATIC void player_walk_post_animate( player_interface *player,
-                                         player_attachment *at )
+VG_STATIC void player_walk_post_animate( player_device *dev,
+                                         player_interface *player )
 {
    /* 
     * Camera 
     */
-   struct player_device_walk *w = at->storage;
+   struct player_device_walk *w = dev->storage;
    struct player_avatar *av = player->playeravatar;
 
    /* 3RD */
@@ -441,28 +469,34 @@ VG_STATIC void player_walk_post_animate( player_interface *player,
 
    v3_add( player->rb.co, (v3f){0.0f,2.0f,0.0f}, origin );
 
-   v3_muladds( origin, angles[2], 2.0f, at->cam_3rd.pos );
-   v3_muladds( at->cam_3rd.pos, angles[0], 0.5f, at->cam_3rd.pos );
+   v3_muladds( origin, angles[2], 2.0f, dev->cam_3rd.pos );
+   v3_muladds( dev->cam_3rd.pos, angles[0], 0.5f, dev->cam_3rd.pos );
 
    float t;
    v3f n;
-   if( spherecast_world( origin, at->cam_3rd.pos, 0.1f, &t, n ) != -1 )
-      v3_lerp( origin, at->cam_3rd.pos, t, at->cam_3rd.pos );
-   v3_copy( w->state.angles, at->cam_3rd.angles );
-   at->cam_3rd.fov = 90.0f;
+   if( spherecast_world( origin, dev->cam_3rd.pos, 0.1f, &t, n ) != -1 )
+      v3_lerp( origin, dev->cam_3rd.pos, t, dev->cam_3rd.pos );
+   v3_copy( w->state.angles, dev->cam_3rd.angles );
+   dev->cam_3rd.fov = 90.0f;
 
 
    /* 1ST */
    /* FIXME: viewpoint entity */
    v3f vp = {-0.1f,1.8f,0.0f};
-   m4x3_mulv( av->sk.final_mtx[ av->id_head-1 ], vp, at->cam_1st.pos );
-   v3_copy( w->state.angles, at->cam_1st.angles );
-   at->cam_1st.fov = 90.0f;
+   m4x3_mulv( av->sk.final_mtx[ av->id_head-1 ], vp, dev->cam_1st.pos );
+   v3_copy( w->state.angles, dev->cam_1st.angles );
+   dev->cam_1st.fov = 90.0f;
+
+   /* FIXME: Organize this. Its int wrong fucking place */
+   v3f vp0 = {0.0f,0.1f, 0.6f},
+       vp1 = {0.0f,0.1f,-0.6f};
+
+   m4x3_mulv( av->sk.final_mtx[ av->id_board ], vp0, TEMP_BOARD_0 );
+   m4x3_mulv( av->sk.final_mtx[ av->id_board ], vp1, TEMP_BOARD_1 );
 }
 
 
-VG_STATIC void player_walk_ui( player_interface *player,
-                               player_attachment *at )
+VG_STATIC void player_walk_ui( player_device *dev, player_interface *player )
 {
    player_debugtext( 1, "V:  %5.2f %5.2f %5.2f",player->rb.v[0],
                                                 player->rb.v[1],
@@ -472,10 +506,9 @@ VG_STATIC void player_walk_ui( player_interface *player,
                                                 player->rb.co[2] );
 }
 
-VG_STATIC void player_walk_bind( player_interface *player,
-                                 player_attachment *at )
+VG_STATIC void player_walk_bind( player_device *dev, player_interface *player )
 {
-   struct player_device_walk *w = at->storage;
+   struct player_device_walk *w = dev->storage;
    struct player_avatar *av = player->playeravatar;
    struct skeleton *sk = &av->sk;
 
@@ -483,17 +516,59 @@ VG_STATIC void player_walk_bind( player_interface *player,
    w->anim_walk = skeleton_get_anim( sk, "walk" );
    w->anim_run  = skeleton_get_anim( sk, "run" );
    w->anim_jump = skeleton_get_anim( sk, "jump" );
+
+   w->device_id_skate = player_get_device( player, "skateboard" );
+}
+
+VG_STATIC int player_walk_event( player_device *dev, player_interface *player,
+                                 enum player_device_event_type ev, void *data )
+{
+   struct player_device_walk *w = dev->storage;
+
+   if( ev == k_player_device_event_bind )
+   {
+      player_walk_bind( dev, player );
+   }
+   else if( ev == k_player_device_event_custom_transition )
+   {
+      struct device_transition_walk *inf = data;
+      v3_copy( inf->angles, w->state.angles );
+   }
+   else if( ev == k_player_device_event_pre_update )
+   {
+      player_walk_pre_update( dev, player );
+   }
+   else if( ev == k_player_device_event_update )
+   {
+      player_walk_update( dev, player );
+   }
+   else if( ev == k_player_device_event_post_update )
+   {
+      player_walk_post_update( dev, player );
+   }
+   else if( ev == k_player_device_event_animate )
+   {
+      player_walk_animate( dev, player );
+   }
+   else if( ev == k_player_device_event_post_animate )
+   {
+      player_walk_post_animate( dev, player );
+   }
+   else if( ev == k_player_device_event_debug_ui )
+   {
+      player_walk_ui( dev, player );
+   }
+   else
+      return 0;
+
+   return 1;
 }
 
 VG_STATIC player_device player_device_walk =
 {
-   .pre_update    = player_walk_pre_update,
-   .update        = player_walk_update,
-   .post_update   = player_walk_post_update,
-   .debug_ui      = player_walk_ui,
-   .bind          = player_walk_bind,
-   .animate       = player_walk_animate,
-   .post_animate  = player_walk_post_animate
+   .name          = "walk",
+   .event         = player_walk_event,
+   .storage       = &localplayer_device_walk
 };
 
 #endif /* PLAYER_DEVICE_WALK_H */
index 93c699e1ebc82827ab30b7bf4b7b618a89bd4629..38b98b776ca4647fd72b4eaa624a412f258f37f8 100644 (file)
@@ -10,7 +10,7 @@
 
 typedef struct player_device     player_device;
 typedef struct player_interface  player_interface;
-typedef struct player_attachment player_attachment;
+typedef struct player_device_transition player_device_transition;
 typedef mdl_keyframe player_pose[32];
 
 #define PLAYER_DEVICE_API VG_STATIC
@@ -19,21 +19,15 @@ struct player_interface
 {
    rigidbody rb;
    camera cam;
-   
-   struct player_attachment
-   {
-      player_device *device;
-      void          *storage;
-
-      /* animation driven */
-      player_pose    pose;
-      v3f            pose_root_co;
-      v4f            pose_root_q;
-      camera         cam_1st, cam_3rd;
-   }
-   dev,
-   dev_previous;
 
+   player_device *devices[ 8 ];
+   u32 active_device, 
+       device_count;
+
+   /*
+    * Camera management
+    * ---------------------------
+    */
    enum camera_mode
    {
       k_camera_mode_firstperson,
@@ -44,9 +38,10 @@ struct player_interface
 
    teleport_gate *gate_waiting;
 
-   int   device_blend;
-   float device_blend_time;
-
+   /*
+    * Input 
+    * --------------------------------
+    */
    struct input_binding *input_js1h,
                         *input_js1v,
                         *input_js2h,
@@ -61,20 +56,29 @@ struct player_interface
                         *input_grab,
                         *input_camera;
 
-#if 0
-   v3f prev_position;
-#endif
+   /*
+    * Animation
+    * --------------------------------------------------
+    */
 
    struct player_avatar  *playeravatar;
    glmesh                *playermesh;
    struct player_ragdoll  ragdoll;
+};
 
-
-   /* FIXME: eventually store animation state here when we have more than 1
-    *        player. since currently its written into the avatar
-    *
-    * struct avatar_anim_state anim_state;
-    */
+enum player_device_event_type
+{
+   k_player_device_event_bind,
+   k_player_device_event_respawn,
+   k_player_device_event_custom_transition,
+
+   k_player_device_event_pre_update,
+   k_player_device_event_update,
+   k_player_device_event_post_update,
+   k_player_device_event_animate,
+   k_player_device_event_post_animate,
+   k_player_device_event_debug_ui,
+   k_player_device_event_restore_state,
 };
 
 /* FIXME: yo */
@@ -82,72 +86,17 @@ vg_tex2d tex_characters = { .path = "textures/ch_gradient.qoi" };
 
 struct player_device
 {
-   void (* bind )      ( player_interface *player, player_attachment *at );
+   const char *name;
+   int (* event )  ( player_device *dev, player_interface *player,
+                     enum player_device_event_type ev, void *data );
 
-   /*
-    * Regular updates
-    */
-   void (* pre_update) ( player_interface *player, player_attachment *at );
-   void (* update)     ( player_interface *player, player_attachment *at );
-   void (* post_update)( player_interface *player, player_attachment *at );
-
-#if 0
-   /* 
-    * Get current pose, and root transform
-    */
-   void (* pose)       ( player_interface *player, player_attachment *at, 
-                            player_pose pose, v3f root_co, v4f root_q );
-#endif
-
-   /*
-    * Use this to fill out animation state
-    */
-   void (* animate) ( player_interface *player, player_attachment *at );
-
-   /* Get current camera, required fields to be filled are:
-    *    fov
-    *    pos
-    *    angles
-    *
-    * They may be blended with other systems
-    */
-   void (* post_animate) ( player_interface *player, player_attachment *at );
-
-   /*
-     This is called when a player is forced back to a spawnpoint.
-    */
-   void (* reset )     ( player_interface *player, player_attachment *at,
-                           struct respawn_point *spawn );
-
-   /*
-    * make calls into player_debugtext( .. ) in this function
-    */
-   void (* debug_ui)   ( player_interface *player, player_attachment *at );
-
-#if 0
-   /*
-    * Called when going through a gate, it should modify any direction and 
-    * position sensitive things, as well as store context here. it may be
-    * restored later.
-    */
-   void (* gate_transport)( player_interface *player, player_attachment *at,
-                            teleport_gate *gate );
-#endif
-
-   /*
-    * Load the state previously saved when gate_transport was called
-    */
-   void (* load_state) ( player_interface *player, player_attachment *at );
-
-
-
-
-#if 0
-   void (* store_state)( player_interface *player, player_attachment *at );
-   void (* attatch )   ( player_interface *player, player_attachment *at, 
-                            void *storage );
-#endif
+   void          *storage;
 
+   /* animation driven */
+   player_pose    pose;
+   v3f            pose_root_co;
+   v4f            pose_root_q;
+   camera         cam_1st, cam_3rd;
 };
 
 VG_STATIC void player_interface_create_player( player_interface *inst )
@@ -220,6 +169,20 @@ VG_STATIC void player_interface_create_player( player_interface *inst )
    m4x3_identity( inst->rb.to_local );
 }
 
+PLAYER_DEVICE_API u32 player_get_device( player_interface *player,
+                                         const char *name )
+{
+   for( u32 i=0; i<player->device_count; i++ )
+   {
+      player_device *dev = player->devices[i];
+      if( !strcmp( name, dev->name ) )
+         return i;
+   }
+
+   vg_fatal_exit_loop( "Invalid device name\n" );
+   return -1;
+}
+
 VG_STATIC void player_use_avatar( player_interface *player,
                                   struct player_avatar *av )
 {
@@ -234,19 +197,42 @@ VG_STATIC void player_use_mesh( player_interface *player, glmesh *mesh )
 
 /* FIXME: Seperate concepts for binding and equip.
  */
-VG_STATIC void player_use_device( player_interface *player, player_device *dev,
-                                  void *storage )
+VG_STATIC void player_add_device( player_interface *player, player_device *dev )
+{
+   if( player->device_count == vg_list_size( player->devices ) )
+      vg_fatal_exit_loop( "Too many devices added\n" );
+
+   player->devices[ player->device_count ++ ] = dev;
+
+   assert( dev->event );
+   assert( dev->storage );
+
+   vg_success( "Added player device '%s'\n", dev->name );
+}
+
+VG_STATIC void player_bind( player_interface *player )
+{
+   for( int i=0; i<player->device_count; i++ )
+   {
+      player_device *dev = player->devices[i];
+      dev->event( dev, player, k_player_device_event_bind, NULL );
+   }
+}
+
+PLAYER_DEVICE_API void player_transition_to_device( player_interface *player,
+                                                    u32 id, void *data )
 {
-   player->dev.device = dev;
-   player->dev.storage = storage;
+   assert( id < player->device_count );
 
-   player->dev.device->bind( player, &player->dev );
+   player->active_device = id;
+   player_device *dev = player->devices[ player->active_device ];
+
+   dev->event( dev, player, k_player_device_event_custom_transition, data );
+   //dev->event( dev, player, k_player_device_event_pre_update, NULL );
 }
 
 VG_STATIC void player_pre_update( player_interface *player )
 {
-   assert( player->dev.device );
-
    if( vg_input_button_down( player->input_camera ) )
    {
       if( player->camera_mode == k_camera_mode_firstperson )
@@ -255,20 +241,23 @@ VG_STATIC void player_pre_update( player_interface *player )
          player->camera_mode = k_camera_mode_firstperson;
    }
 
+#if 0
+   if( vg_input_button_down( player->input_use ) )
+      player->active_device ^= 0x1;
+#endif
+
 #if 0
    v3_copy( player->rb.co, player->prev_position );
 #endif
 
-   if( player->dev.device->pre_update )
-      player->dev.device->pre_update( player, &player->dev );
+   player_device *dev = player->devices[ player->active_device ];
+   dev->event( dev, player, k_player_device_event_pre_update, NULL );
 }
 
 VG_STATIC void player_update( player_interface *player )
 {
-   assert( player->dev.device );
-
-   if( player->dev.device->update )
-      player->dev.device->update( player, &player->dev );
+   player_device *dev = player->devices[ player->active_device ];
+   dev->event( dev, player, k_player_device_event_update, NULL );
 }
 
 VG_STATIC void player_apply_transport_to_cam( m4x3f transport )
@@ -296,27 +285,26 @@ void player_pass_gate( player_interface *player, teleport_gate *gate )
 
 VG_STATIC void player_post_update( player_interface *player )
 {
-   assert( player->dev.device );
-
-   if( player->dev.device->post_update )
-      player->dev.device->post_update( player, &player->dev );
+   player_device *dev = player->devices[ player->active_device ];
+   dev->event( dev, player, k_player_device_event_post_update, NULL );
 }
 
 VG_STATIC void player_pre_render( player_interface *player )
 {
-   player->dev.device->animate( player, &player->dev );
+   player_device *dev = player->devices[ player->active_device ];
+   dev->event( dev, player, k_player_device_event_animate, NULL );
 
    /* TODO: eventually, blending code goes here */
 
    m4x3f transform;
-   q_m3x3( player->dev.pose_root_q, transform );
-   v3_copy( player->dev.pose_root_co, transform[3] );
+   q_m3x3( dev->pose_root_q, transform );
+   v3_copy( dev->pose_root_co, transform[3] );
 
    struct skeleton *sk = &player->playeravatar->sk;
 
-   skeleton_apply_pose( sk, player->dev.pose, k_anim_apply_defer_ik );
+   skeleton_apply_pose( sk, dev->pose, k_anim_apply_defer_ik );
    skeleton_apply_ik_pass( sk );
-   skeleton_apply_pose( sk, player->dev.pose, k_anim_apply_deffered_only );
+   skeleton_apply_pose( sk, dev->pose, k_anim_apply_deffered_only );
    skeleton_apply_inverses( sk );
    skeleton_apply_transform( sk, transform );
    skeleton_debug( sk );
@@ -337,7 +325,7 @@ VG_STATIC void player_pre_render( player_interface *player )
    }
 #endif
 
-   player->dev.device->post_animate( player, &player->dev );
+   dev->event( dev, player, k_player_device_event_post_animate, NULL );
 
    /* TODO: eventually, blending code goes here */
 
@@ -350,7 +338,8 @@ VG_STATIC void player_pre_render( player_interface *player )
                                          5.0f * vg.frame_delta );
 
    float t = player->camera_type_blend;
-   camera_lerp( &player->dev.cam_1st, &player->dev.cam_3rd, t, &player->cam );
+   camera_lerp( &dev->cam_1st, &dev->cam_3rd, t, &player->cam );
+   player->cam.fov = vg_lerpf( 118.0f, 90.0f, t );
 
    if( player->gate_waiting )
    {
@@ -424,27 +413,26 @@ VG_STATIC void player_debugtext( int size, const char *fmt, ... )
 VG_STATIC void player_ui( player_interface *player )
 {
    /* TODO: if debugger enabled */
+   player_device *dev = player->devices[ player->active_device ];
 
-   if( player->dev.device->debug_ui )
-   {
-      vg_uictx.cursor[0] = vg.window_x - 200;
-      vg_uictx.cursor[1] = 0;
-      vg_uictx.cursor[2] = 200;
-      vg_uictx.cursor[3] = 200;
+   vg_uictx.cursor[0] = vg.window_x - 200;
+   vg_uictx.cursor[1] = 0;
+   vg_uictx.cursor[2] = 200;
+   vg_uictx.cursor[3] = 200;
 
-      struct ui_vert *b = ui_fill_rect( vg_uictx.cursor, 0x70000000 );
+   struct ui_vert *b = ui_fill_rect( vg_uictx.cursor, 0x70000000 );
 
-      vg_uictx.cursor[0] = vg.window_x;
-      player->dev.device->debug_ui( player, &player->dev );
+   vg_uictx.cursor[0] = vg.window_x;
+   dev->event( dev, player, k_player_device_event_debug_ui, NULL );
 
-      b[2].co[1] = vg_uictx.cursor[1];
-      b[3].co[1] = vg_uictx.cursor[1];
-   }
+   b[2].co[1] = vg_uictx.cursor[1];
+   b[3].co[1] = vg_uictx.cursor[1];
 }
 
 VG_STATIC void player_spawn( player_interface *player, 
                              struct respawn_point *rp )
 {
+   player_device *dev = player->devices[ player->active_device ];
    v3_copy( rp->co, player->rb.co );
 #if 0
    v3_copy( rp->co, player->prev_position );
@@ -454,8 +442,7 @@ VG_STATIC void player_spawn( player_interface *player,
    q_identity( player->rb.q );
    rb_update_transform( &player->rb );
 
-   if( player->dev.device->reset )
-      player->dev.device->reset( player, &player->dev, rp );
+   dev->event( dev, player, k_player_device_event_respawn, rp );
 }
 
 
index 0d3ff70599a60ec40e2b2e653363c5b66e810d8b..b3d51c364653e637fba9df4ec5f44f6db53f2d34 100644 (file)
@@ -30,9 +30,6 @@
 
 /* temp */
 VG_STATIC player_interface localplayer;
-VG_STATIC struct player_device_walk localplayer_walk;
-VG_STATIC struct player_device_skate localplayer_skate;
-VG_STATIC struct player_device_dead localplayer_dead;
 VG_STATIC struct player_avatar localplayer_avatar;
 VG_STATIC glmesh localplayer_meshes[3];
 
@@ -70,7 +67,9 @@ VG_STATIC void vg_launch_opt(void)
 
 VG_STATIC int __kill( int argc, const char *argv[] )
 {
+#if 0
    player_use_device( &localplayer, &player_device_dead, &localplayer_dead );
+#endif
    return 0;
 }
 
@@ -250,8 +249,11 @@ VG_STATIC void vg_load(void)
    player_avatar_load( &localplayer_avatar, "models/ch_new.mdl" );
    player_use_avatar( &localplayer, &localplayer_avatar );
    player_use_mesh( &localplayer, &localplayer_meshes[0] );
-   player_use_device( &localplayer, &player_device_walk, &localplayer_walk );
-   player_use_device( &localplayer, &player_device_skate, &localplayer_skate );
+
+   player_add_device( &localplayer, &player_device_walk );
+   player_add_device( &localplayer, &player_device_skate );
+   player_add_device( &localplayer, &player_device_dead );
+   player_bind( &localplayer );
 
    /* --------------------- */