- /* New board transformation */
- v4f board_rotation; v3f board_location;
-
- v4f rz, rx;
- q_axis_angle( rz, (v3f){ 0.0f, 0.0f, 1.0f }, player.board_xy[0] );
- q_axis_angle( rx, (v3f){ 1.0f, 0.0f, 0.0f }, player.board_xy[1] );
- q_mul( rx, rz, board_rotation );
-
- v3f *mboard = player.mdl.matrices[k_chpart_board];// player.mboard;
- q_m3x3( board_rotation, mboard );
- m3x3_mulv( mboard, (v3f){ 0.0f, -0.5f, 0.0f }, board_location );
- v3_add( (v3f){0.0f,0.5f,0.0f}, board_location, board_location );
- v3_copy( board_location, mboard[3] );
-
-
- float wheel_r = offset[0]*-0.4f;
- v4f qwheel;
- q_axis_angle( qwheel, (v3f){0.0f,1.0f,0.0f}, wheel_r );
-
- q_m3x3( qwheel, player.mdl.matrices[k_chpart_wb] );
-
- m3x3_transpose( player.mdl.matrices[k_chpart_wb],
- player.mdl.matrices[k_chpart_wf] );
- v3_copy( player.mdl.offsets[k_chpart_wb],
- player.mdl.matrices[k_chpart_wb][3] );
- v3_copy( player.mdl.offsets[k_chpart_wf],
- player.mdl.matrices[k_chpart_wf][3] );
-
- m4x3_mul( mboard, player.mdl.matrices[k_chpart_wb],
- player.mdl.matrices[k_chpart_wb] );
- m4x3_mul( mboard, player.mdl.matrices[k_chpart_wf],
- player.mdl.matrices[k_chpart_wf] );
-
- m4x3_mulv( mboard, player.mdl.ik_leg_l.end, player.mdl.ik_leg_l.end );
- m4x3_mulv( mboard, player.mdl.ik_leg_r.end, player.mdl.ik_leg_r.end );
-
-
- v3_copy( player.mdl.ik_arm_l.end, player.handl_target );
- v3_copy( player.mdl.ik_arm_r.end, player.handr_target );
-
- if( 1||player.in_air )
- {
- float tuck = player.board_xy[1],
- tuck_amt = fabsf( tuck ) * (1.0f-fabsf(player.board_xy[0]));
-
- float crouch = player.grab*0.3f;
- v3_muladds( player.mdl.ik_body.base, (v3f){0.0f,-1.0f,0.0f},
- crouch, player.mdl.ik_body.base );
- v3_muladds( player.mdl.ik_body.end, (v3f){0.0f,-1.0f,0.0f},
- crouch*1.2f, player.mdl.ik_body.end );
-
- if( tuck < 0.0f )
- {
- //foot_l *= 1.0f-tuck_amt*1.5f;
-
- if( player.grab > 0.1f )
- {
- m4x3_mulv( mboard, (v3f){0.1f,0.14f,0.6f},
- player.handl_target );
- }
- }
- else
- {
- //foot_r *= 1.0f-tuck_amt*1.4f;
-
- if( player.grab > 0.1f )
- {
- m4x3_mulv( mboard, (v3f){0.1f,0.14f,-0.6f},
- player.handr_target );
- }
- }
- }
-
- v3_lerp( player.handl, player.handl_target, 0.1f, player.handl );
- v3_lerp( player.handr, player.handr_target, 0.1f, player.handr );
-
- v3_copy( player.handl, player.mdl.ik_arm_l.end );
- v3_copy( player.handr, player.mdl.ik_arm_r.end );
-
- /* Head rotation */
-
- static float rhead = 0.0f;
- rhead = vg_lerpf( rhead,
- vg_clampf(atan2f( localv[2], -localv[0] ),-1.0f,1.0f), 0.04f );
- player.mdl.rhead = rhead;
-}
-
-static void player_update(void)
-{
- if( vg_get_axis("grabl")>0.0f)
- reset_player(0,NULL);
-
- if( freecam )
- {
- player_freecam();
- }
- else
- {
- if( player.is_dead )
- {
- character_ragdoll_iter( &player.mdl );
- character_debug_ragdoll( &player.mdl );
- }
- else
- {
- if( player.on_board )
- {
- player_do_motion();
- player_animate();
- }
- else
- {
- player_walkgrid();
- }
- }
- }
-
- /* Update camera matrices */
- m4x3_identity( player.camera );
- m4x3_rotate_y( player.camera, -player.angles[0] );
- m4x3_rotate_x( player.camera, -0.33f -player.angles[1] );
- v3_copy( player.camera_pos, player.camera[3] );
- m4x3_invert_affine( player.camera, player.camera_inverse );
-}
-
-static void draw_player(void)
-{
- /* Draw */
- m4x3_copy( player.to_world, player.mdl.mroot );
-
- if( player.is_dead )
- character_mimic_ragdoll( &player.mdl );
- else
- character_eval( &player.mdl );
-
- character_draw( &player.mdl, (player.is_dead|player.in_air)? 0.0f: 1.0f );
-}
+ enum player_subsystem{
+ k_player_subsystem_walk = 0,
+ k_player_subsystem_skate = 1,
+ k_player_subsystem_dead = 2,
+ k_player_subsystem_drive = 3
+ }
+ subsystem,
+ subsystem_gate;
+
+ struct player_skate _skate;
+ struct player_walk _walk;
+ struct player_dead _dead;
+ struct player_drive _drive;
+}
+static localplayer;
+
+/*
+ * Gameloop tables
+ * ---------------------------------------------------------
+ */
+
+VG_STATIC
+void (*_player_system_register[])(void) =
+{
+ player__walk_register,
+ player__skate_register,
+ NULL,
+ NULL
+};
+
+VG_STATIC
+void (*_player_bind[])( player_instance *player ) =
+{
+ player__walk_bind,
+ player__skate_bind,
+ NULL,
+ player__drive_bind
+};
+
+VG_STATIC
+void (*_player_reset[])( player_instance *player, ent_spawn *rp ) =
+{
+ player__walk_reset,
+ player__skate_reset,
+ NULL,
+ player__drive_reset
+};
+
+VG_STATIC
+void (*_player_pre_update[])( player_instance *player ) =
+{
+ player__walk_pre_update,
+ player__skate_pre_update,
+ NULL,
+ player__drive_pre_update
+};
+
+VG_STATIC
+void( *_player_update[])( player_instance *player ) =
+{
+ player__walk_update,
+ player__skate_update,
+ player__dead_update,
+ player__drive_update
+};
+
+VG_STATIC
+void( *_player_post_update[])( player_instance *player ) =
+{
+ player__walk_post_update,
+ player__skate_post_update,
+ NULL,
+ player__drive_post_update
+};
+
+VG_STATIC
+void( *_player_im_gui[])( player_instance *player ) =
+{
+ player__walk_im_gui,
+ player__skate_im_gui,
+ NULL,
+ player__drive_im_gui
+};
+
+VG_STATIC
+void( *_player_animate[])( player_instance *player, player_animation *dest ) =
+{
+ player__walk_animate,
+ player__skate_animate,
+ player__dead_animate,
+ player__drive_animate
+};
+
+VG_STATIC
+void( *_player_post_animate[])( player_instance *player ) =
+{
+ player__walk_post_animate,
+ player__skate_post_animate,
+ player__dead_post_animate,
+ player__drive_post_animate
+};
+
+VG_STATIC
+void( *_player_restore[] )( player_instance *player ) =
+{
+ player__walk_restore,
+ player__skate_restore,
+ NULL,
+ NULL
+};
+
+PLAYER_API void player__debugtext( int size, const char *fmt, ... );
+PLAYER_API void player__create( player_instance *inst );
+PLAYER_API void player__use_avatar( player_instance *player,
+ struct player_avatar *av );
+PLAYER_API void player__use_mesh( player_instance *player, glmesh *mesh );
+PLAYER_API void player__use_texture( player_instance *player, vg_tex2d *tex );
+PLAYER_API void player__bind( player_instance *player );
+PLAYER_API void player__pre_update( player_instance *player );
+PLAYER_API void player__update( player_instance *player );
+PLAYER_API void player__post_update( player_instance *player );
+
+PLAYER_API void player__pass_gate( player_instance *player, ent_gate *gate );
+PLAYER_API void player__im_gui( player_instance *player );
+PLAYER_API void player__spawn( player_instance *player, ent_spawn *rp );
+PLAYER_API void player__kill( player_instance *player );
+
+VG_STATIC int localplayer_cmd_respawn( int argc, const char *argv[] );
+VG_STATIC void player_apply_transport_to_cam( m4x3f transport );