X-Git-Url: https://harrygodden.com/git/?a=blobdiff_plain;f=player.h;h=18936a7ade2248844468cc7e182299c46ea14042;hb=6e6c7f31b8f17af3814727109e48fc6f85ef04b1;hp=cd7fd57a5996b28554968ed1c2b626fa043783c1;hpb=eb203257efcfe324217de9e733cc6c1371b99de6;p=carveJwlIkooP6JGAAIwe30JlM.git diff --git a/player.h b/player.h index cd7fd57..18936a7 100644 --- a/player.h +++ b/player.h @@ -1,133 +1,185 @@ #ifndef PLAYER_H #define PLAYER_H -#include "player_api.h" - +#include "skaterift.h" #include "player_common.h" +#include "network_compression.h" +#include "player_effects.h" + +enum player_subsystem{ + k_player_subsystem_walk = 0, + k_player_subsystem_skate = 1, + k_player_subsystem_dead = 2, + k_player_subsystem_drive = 3, + k_player_subsystem_basic_info = 4, + k_player_subsystem_max, + k_player_subsystem_invalid = 255 +}; + +struct player_cam_controller { + enum camera_mode{ + k_cam_firstperson = 1, + k_cam_thirdperson = 0 + } + camera_mode; + f32 camera_type_blend; + + v3f fpv_offset, /* expressed relative to rigidbody */ + tpv_offset, + tpv_offset_extra, + fpv_viewpoint, /* expressed relative to neck bone inverse final*/ + fpv_offset_smooth, + fpv_viewpoint_smooth, + tpv_offset_smooth, + tpv_lpf, + cam_velocity_smooth; +}; + +struct player_subsystem_interface{ + void(*system_register)(void); + void(*bind)(void); + void(*pre_update)(void); + void(*update)(void); + void(*post_update)(void); + void(*im_gui)(void); + void(*animate)(void); + void(*pose)( void *animator, player_pose *pose ); + void(*effects)( void *animator, m4x3f *final_mtx, struct player_board *board, + struct player_effects_data *effect_data ); + void(*post_animate)(void); + void(*network_animator_exchange)( bitpack_ctx *ctx, void *data ); + void(*sfx_oneshot)( u8 id, v3f pos, f32 volume ); + + void *animator_data; + u32 animator_size; + + const char *name; +}; + +#include "player_ragdoll.h" +#include "player_render.h" +#include "player_model.h" + +/* subsystem headers */ #include "player_walk.h" #include "player_skate.h" #include "player_dead.h" +#include "player_drive.h" +#include "player_basic_info.h" + +#include "player_replay.h" #define PLAYER_REWIND_FRAMES 60*4 +#define RESET_MAX_TIME 45.0 -struct player_instance -{ - /* transform definition */ - rigidbody rb, rb_gate_storage; - v3f angles, angles_storage; +static i32 k_cinema_fixed = 0; +static f32 k_cinema = 0.0f; +static i32 k_invert_y = 0; - v4f qbasis; - m3x3f basis, invbasis, basis_gate; - world_instance *viewable_world; +struct { + /* transform definition */ + rigidbody rb; + v3f angles; /* * Camera management * --------------------------- */ camera cam; - - enum camera_mode - { - k_cam_firstperson = 0, - k_cam_thirdperson = 1 - } - camera_mode; - float camera_type_blend; - - v3f fpv_offset, /* expressed relative to rigidbody */ - tpv_offset, - fpv_viewpoint, /* expressed relative to neck bone inverse final */ - fpv_offset_smooth, - fpv_viewpoint_smooth, - tpv_offset_smooth, - tpv_lpf, - cam_velocity_smooth; - - v3f cam_override_pos; - v2f cam_override_angles; - float cam_override_strength; + struct player_cam_controller cam_control; + f32 cam_trackshake; float cam_velocity_influence, cam_velocity_coefficient, cam_velocity_constant, cam_velocity_coefficient_smooth, cam_velocity_constant_smooth, - cam_velocity_influence_smooth, - cam_land_punch, - cam_land_punch_v; + cam_velocity_influence_smooth; + v3f cam_land_punch, cam_land_punch_v; ent_gate *gate_waiting; + int immobile; - /* - * Input - * -------------------------------- + int rewinded_since_last_gate; + + /* + * Network + * -------------------------------------------------- */ - struct input_binding *input_js1h, - *input_js1v, - *input_js2h, - *input_js2v, - *input_jump, - *input_push, - *input_trick0, - *input_trick1, - *input_trick2, - *input_walk, - *input_walkh, - *input_walkv, - *input_use, - *input_reset, - *input_grab, - *input_camera; + u16 boundary_hash; + struct net_sfx { + u8 system, priority, id; + f32 subframe, volume; + v3f location; + } + sfx_buffer[4]; + u32 sfx_buffer_count; /* * Animation * -------------------------------------------------- */ - struct player_avatar *playeravatar; - glmesh *playermesh; struct player_ragdoll ragdoll; - vg_tex2d *playertex; + struct player_model fallback_model; + struct player_board fallback_board; + + u16 board_view_slot, playermodel_view_slot; + player_pose pose; player_pose holdout_pose; float holdout_time; - /* - * Rewind - * ---------------------------------------------------- - */ - int rewinding, rewind_sound_wait; - - struct rewind_frame{ - v3f pos; - v3f ang; - } - *rewind_buffer; - u32 rewind_length; - float rewind_accum; - ent_gate *rewind_gate; - - float rewind_total_length, rewind_predicted_time, - dist_accum; - double rewind_start, rewind_time; + m4x3f *final_mtx; /* * Subsystems * ------------------------------------------------- */ - enum player_subsystem - { - k_player_subsystem_walk = 0, - k_player_subsystem_skate = 1, - k_player_subsystem_dead = 2 + enum player_subsystem subsystem; /* .. prev */ + + /* + * Rendering + */ + mdl_context skeleton_meta; + struct skeleton skeleton; + + u32 id_hip, + id_chest, + id_ik_hand_l, + id_ik_hand_r, + id_ik_elbow_l, + id_ik_elbow_r, + id_head, + id_ik_foot_l, + id_ik_foot_r, + id_ik_knee_l, + id_ik_knee_r, + id_wheel_l, + id_wheel_r, + id_board, + id_eyes; + + struct player_effects_data effect_data; +} +static localplayer = { + .rb = { + .co = { 0,0,0 }, + .w = { 0,0,0 }, + .v = { 0,0,0 }, + .q = { 0,0,0,1 }, + .to_world = M4X3_IDENTITY, + .to_local = M4X3_IDENTITY } - subsystem, - subsystem_gate; +}; - struct player_skate _skate; - struct player_walk _walk; - struct player_dead _dead; +struct player_subsystem_interface static *player_subsystems[] = { + [k_player_subsystem_walk] = &player_subsystem_walk, + [k_player_subsystem_dead] = &player_subsystem_dead, + [k_player_subsystem_drive] = &player_subsystem_drive, + [k_player_subsystem_skate] = &player_subsystem_skate, + [k_player_subsystem_basic_info]=&player_subsystem_basic_info }; /* @@ -135,934 +187,32 @@ struct player_instance * --------------------------------------------------------- */ -VG_STATIC -void (*_player_bind[])( player_instance *player ) = -{ - player__walk_bind, - player__skate_bind, - NULL -}; - -VG_STATIC -void (*_player_reset[])( player_instance *player, ent_spawn *rp ) = -{ - player__walk_reset, - player__skate_reset, - NULL -}; - -VG_STATIC -void (*_player_pre_update[])( player_instance *player ) = -{ - player__walk_pre_update, - player__skate_pre_update, - NULL -}; - -VG_STATIC -void( *_player_update[])( player_instance *player ) = -{ - player__walk_update, - player__skate_update, - player__dead_update, -}; - -VG_STATIC -void( *_player_post_update[])( player_instance *player ) = -{ - player__walk_post_update, - player__skate_post_update, - NULL -}; - -VG_STATIC -void( *_player_im_gui[])( player_instance *player ) = -{ - player__walk_im_gui, - player__skate_im_gui, - NULL -}; - -VG_STATIC -void( *_player_animate[])( player_instance *player, player_animation *dest ) = -{ - player__walk_animate, - player__skate_animate, - player__dead_animate -}; - -VG_STATIC -void( *_player_post_animate[])( player_instance *player ) = -{ - player__walk_post_animate, - player__skate_post_animate, - player__dead_post_animate -}; - -VG_STATIC -void( *_player_restore[] )( player_instance *player ) = -{ - player__walk_restore, - player__skate_restore, - NULL -}; - -/* implementation */ - -#include "player.c" -#include "player_common.c" -#include "player_walk.c" -#include "player_skate.c" -#include "player_dead.c" - -#endif /* PLAYER_H */ - - -#if 0 -/* - * Copyright (C) 2021-2023 Mt.ZERO Software, Harry Godden - All Rights Reserved - */ - -#define PLAYER_H -#ifndef PLAYER_H -#define PLAYER_H - -#define PLAYER_REWIND_FRAMES 60*4 - -#include "conf.h" -#include "audio.h" -#include "common.h" -#include "world.h" -#include "skeleton.h" -#include "bvh.h" - - -/* - * ----------------------------------------------------------------------------- - * Memory - * ----------------------------------------------------------------------------- - */ - -VG_STATIC struct gplayer -{ - rigidbody rb, rb_frame; - v3f co, angles; /* used as transfer between controllers */ - - enum player_controller - { - k_player_controller_walk, - k_player_controller_skate, - k_player_controller_ragdoll, - k_player_controller_mountain_skate, - k_player_controller_snowboard, - k_player_controller_drive - } - controller, - controller_frame; - - m4x3f visual_transform, - inv_visual_transform; - - int is_dead, death_tick_allowance, rewinding; - int rewind_sound_wait; - - - v3f handl_target, handr_target, - handl, handr; - - /* Input */ - struct input_binding *input_js1h, - *input_js1v, - *input_js2h, - *input_js2v, - *input_jump, - *input_push, - *input_walk, - *input_walkh, - *input_walkv, - *input_switch_mode, - *input_reset, - *input_grab; - - /* Camera */ - float air_time; - v3f camera_pos, smooth_localcam; - - struct rewind_frame - { - v3f pos; - v3f ang; - } - *rewind_buffer; - u32 rewind_incrementer, - rewind_length; - - float rewind_time, rewind_total_length, rewind_predicted_time; - double diag_rewind_start, diag_rewind_time; - float dist_accum; - - /* animation */ - double jump_time; - float fslide, - fdirz, fdirx, - fstand, - ffly, - fpush, - fairdir, - fsetup, - walk_timer, - fjump, - fonboard, - frun, - fgrind; - - v3f board_offset; - v4f board_rotation; - - float walk; - int step_phase; - enum mdl_surface_prop surface_prop; - - /* player model */ - struct player_model - { - glmesh player_meshes[3]; - - mdl_context meta; - struct skeleton sk; - struct skeleton_anim *anim_stand, - *anim_highg, - *anim_slide, - *anim_air, - *anim_push, *anim_push_reverse, - *anim_ollie, *anim_ollie_reverse, - *anim_grabs, *anim_stop, - *anim_walk, *anim_run, *anim_idle, - *anim_jump; - - u32 id_hip, - id_ik_hand_l, - id_ik_hand_r, - id_ik_elbow_l, - id_ik_elbow_r, - id_head, - id_ik_foot_l, - id_ik_foot_r, - id_board; - - v3f cam_pos; - - struct ragdoll_part - { - u32 bone_id; - //v3f offset; - - /* Collider transform relative to bone */ - m4x3f collider_mtx, - inv_collider_mtx; - - u32 use_limits; - v3f limits[2]; - - rigidbody rb; - u32 parent; - u32 colour; - } - ragdoll[32]; - u32 ragdoll_count; - - rb_constr_pos position_constraints[32]; - u32 position_constraints_count; - - rb_constr_swingtwist cone_constraints[32]; - u32 cone_constraints_count; - - int shoes[2]; - } - mdl; -} -player__OLD - -#if 0 -= -{ - .collide_front = { .type = k_rb_shape_sphere, .inf.sphere.radius = 0.3f }, - .collide_back = { .type = k_rb_shape_sphere, .inf.sphere.radius = 0.3f } -} -#endif - -; - -/* - * API - */ -VG_STATIC float *player_get_pos(void); -VG_STATIC void player_kill(void); -VG_STATIC float *player_cam_pos(void); -VG_STATIC void player_save_frame(void); -VG_STATIC void player_restore_frame(void); -VG_STATIC void player_save_rewind_frame(void); - -/* - * Submodules - */ -VG_STATIC void player_mouseview(void); - -#include "player_physics.h" -#include "player_physics_skate.h" -#include "player_physics_walk.h" -#include "player_ragdoll.h" -#include "player_model.h" -#include "player_animation.h" -#include "player_audio.h" - -/* - * player_physics__ - * - * - * - */ - -/* - * ----------------------------------------------------------------------------- - * Events - * ----------------------------------------------------------------------------- - */ -VG_STATIC int kill_player( int argc, char const *argv[] ); -VG_STATIC int reset_player( int argc, char const *argv[] ); -VG_STATIC void reset_player_poll( int argc, char const *argv[] ); - -VG_STATIC void player_init(void) /* 1 */ -{ - rb_init( &player.rb ); - - VG_VAR_F32( k_walkspeed ); - VG_VAR_F32( k_stopspeed ); - VG_VAR_F32( k_airspeed ); - VG_VAR_F32( k_walk_friction ); - VG_VAR_F32( k_walk_air_accel ); - VG_VAR_F32( k_walk_accel ); - - VG_VAR_I32( freecam ); - VG_VAR_I32( cl_thirdperson ); - VG_VAR_F32_PERSISTENT( fc_speed ); - - VG_VAR_F32( k_ragdoll_limit_scale ); - VG_VAR_I32( k_ragdoll_div ); - VG_VAR_I32( k_ragdoll_debug_collider ); - VG_VAR_I32( k_ragdoll_debug_constraints ); - - VG_VAR_F32( k_friction_lat ); - - VG_VAR_F32( k_cog_spring ); - VG_VAR_F32( k_cog_damp ); - - VG_VAR_F32( k_cog_mass_ratio ); - VG_VAR_F32( k_downforce ); - - VG_VAR_F32( k_spring_force ); - VG_VAR_F32( k_spring_dampener ); - VG_VAR_F32( k_spring_angular ); - - VG_VAR_F32( k_mmthrow_scale ); - VG_VAR_F32( k_mmcollect_lat ); - VG_VAR_F32( k_mmcollect_vert ); - VG_VAR_F32( k_mmdecay ); - - vg_function_push( (struct vg_cmd){ - .name = "reset", - .function = reset_player, - .poll_suggest = reset_player_poll - }); - - vg_function_push( (struct vg_cmd){ - .name = "kill", - .function = kill_player - }); - - /* HACK */ - rb_register_cvar(); - - player.rewind_length = 0; - player.rewind_buffer = - vg_linear_alloc( vg_mem.rtmemory, - sizeof(struct rewind_frame) * PLAYER_REWIND_FRAMES ); - - player_model_init(); -} - -VG_STATIC void player_save_rewind_frame(void) -{ - if( player.rewind_length < PLAYER_REWIND_FRAMES ) - { - struct rewind_frame *fr = - &player.rewind_buffer[ player.rewind_length ++ ]; - - v2_copy( player.angles, fr->ang ); - v3_copy( player.camera_pos, fr->pos ); - - player.rewind_incrementer = 0; - - if( player.rewind_length > 1 ) - { - player.rewind_total_length += - v3_dist( player.rewind_buffer[player.rewind_length-1].pos, - player.rewind_buffer[player.rewind_length-2].pos ); - } - } -} - - -/* disaster */ -VG_STATIC int menu_enabled(void); -#include "menu.h" - -VG_STATIC void player_do_motion(void); -/* - * Free camera movement - */ -VG_STATIC void player_mouseview(void) -{ - if( menu_enabled() ) - return; - - v2_muladds( player.angles, vg.mouse_delta, 0.0025f, player.angles ); - - if( vg_input.controller_should_use_trackpad_look ) - { - static v2f last_input; - static v2f vel; - static v2f vel_smooth; - - v2f input = { player.input_js2h->axis.value, - player.input_js2v->axis.value }; - - if( (v2_length2(last_input) > 0.001f) && (v2_length2(input) > 0.001f) ) - { - v2_sub( input, last_input, vel ); - v2_muls( vel, 1.0f/vg.time_delta, vel ); - } - else - { - v2_zero( vel ); - } - - v2_lerp( vel_smooth, vel, vg.time_delta*8.0f, vel_smooth ); - - v2_muladds( player.angles, vel_smooth, vg.time_delta, player.angles ); - v2_copy( input, last_input ); - } - else - { - player.angles[0] += player.input_js2h->axis.value * vg.time_delta * 4.0f; - player.angles[1] += player.input_js2v->axis.value * vg.time_delta * 4.0f; - } - - player.angles[1] = vg_clampf( player.angles[1], -VG_PIf*0.5f, VG_PIf*0.5f ); -} - -/* Deal with input etc */ -VG_STATIC void player_update_pre(void) -{ - - { - v3f ra, rb, rx; - v3_copy( main_camera.pos, ra ); - v3_muladds( ra, main_camera.transform[2], -10.0f, rb ); - - float t; - if( spherecast_world( ra, rb, 0.4f, &t, rx ) != -1 ) - { - m4x3f mtx; - m3x3_identity( mtx ); - v3_lerp( ra, rb, t, mtx[3] ); - - debug_sphere( mtx, 0.4f, 0xff00ff00 ); - - v3f x1; - v3_muladds( mtx[3], rx, 0.4f, x1 ); - vg_line( mtx[3], x1, 0xffffffff ); - } - } - -#if 0 - - vg_line_pt3( phys->cog, 0.10f, 0xffffffff ); - vg_line_pt3( phys->cog, 0.09f, 0xffffffff ); - vg_line_pt3( phys->cog, 0.08f, 0xffffffff ); - vg_line( phys->cog, phys->rb.co, 0xff000000 ); - - v3f spring_end; - v3f throw_end, p0, p1; - v3_muladds( phys->rb.co, phys->rb.up, 1.0f, spring_end ); - v3_muladds( spring_end, phys->throw_v, 1.0f, throw_end ); - v3_muladds( spring_end, player.debug_mmcollect_lat, 1.0f, p0 ); - v3_muladds( spring_end, player.debug_mmcollect_vert, 1.0f, p1 ); - vg_line( spring_end, throw_end, VG__RED ); - vg_line( spring_end, p0, VG__GREEN ); - vg_line( spring_end, p1, VG__BLUE ); -#endif - - if( player.rewinding ) - return; - - if( vg_input_button_down( player.input_reset ) && !menu_enabled() ) - { - double delta = world.time - world.last_use; - - if( (delta <= RESET_MAX_TIME) && (world.last_use != 0.0) ) - { - player.rewinding = 1; - player.rewind_sound_wait = 1; - player.rewind_time = (float)player.rewind_length - 0.0001f; - player_save_rewind_frame(); - audio_lock(); - audio_play_oneshot( &audio_rewind[0], 1.0f ); - audio_unlock(); - - /* based on analytical testing. DONT CHANGE! - * - * time taken: y = (x^(4/5)) * 74.5 - * inverse : x = (2/149)^(4/5) * y^(4/5) - */ - - float constant = powf( 2.0f/149.0f, 4.0f/5.0f ), - curve = powf( player.rewind_total_length, 4.0f/5.0f ); - - player.rewind_predicted_time = constant * curve; - player.diag_rewind_start = vg.time; - player.diag_rewind_time = player.rewind_time; - - player.is_dead = 0; - player.death_tick_allowance = 30; - player_restore_frame(); - - if( player.controller == k_player_controller_walk ) - { - player.angles[0] = atan2f( -player.rb.forward[2], - -player.rb.forward[0] ); - } - - player.mdl.shoes[0] = 1; - player.mdl.shoes[1] = 1; - - world_routes_notify_reset(); - - /* apply 1 frame of movement */ - player_do_motion(); - } - else - { - if( player.is_dead ) - { - reset_player( 0, NULL ); - } - else - { - /* cant do that */ - audio_lock(); - audio_play_oneshot( &audio_rewind[4], 1.0f ); - audio_unlock(); - } - } - } - - if( vg_input_button_down( player.input_switch_mode ) && !menu_enabled() ) - { - audio_lock(); - -#if 0 - if( phys->controller == k_player_controller_walk ) - { - phys->controller = k_player_controller_skate; - - v3_muladds( phys->rb.v, phys->rb.forward, 0.2f, phys->rb.v ); - audio_play_oneshot( &audio_lands[6], 1.0f ); - } - else if( phys->controller == k_player_controller_skate ) - { - phys->controller = k_player_controller_walk; - - audio_play_oneshot( &audio_lands[5], 1.0f ); - } -#endif - - audio_unlock(); - } - - if( player.controller == k_player_controller_walk ) - player_mouseview(); -} - -VG_STATIC void player_update_fixed(void) /* 2 */ -{ - if( player.rewinding ) - return; - - if( player.death_tick_allowance ) - player.death_tick_allowance --; - - if( player.is_dead ) - { - player_ragdoll_iter(); - } - else - { - player.rewind_incrementer ++; - - if( player.rewind_incrementer > (u32)(0.25/VG_TIMESTEP_FIXED) ) - { - player_save_rewind_frame(); - } - - player_do_motion(); - } -} - -VG_STATIC void player_update_post(void) -{ -#if 0 - for( int i=0; ilog_length - 1; j ++ ) - vg_line( p->log[j], p->log[j+1], p->colour ); - - vg_line_cross( p->log[p->log_length-1], p->colour, 0.25f ); - - v3f p1; - v3_add( p->log[p->log_length-1], p->n, p1 ); - vg_line( p->log[p->log_length-1], p1, 0xffffffff ); - } -#endif - -#if 0 - if( player.is_dead ) - { - player_debug_ragdoll(); - - if( !freecam ) - player_animate_death_cam(); - } - else - { - player_animate(); - - if( !freecam ) - { - if( cl_thirdperson ) - player_animate_camera_thirdperson(); - else - player_animate_camera(); - } - } - - if( freecam ) -#endif - player_freecam(); - - /* CAMERA POSITIONING: LAYER 0 */ - v2_copy( player.angles, main_camera.angles ); - v3_copy( player.camera_pos, main_camera.pos ); - -#if 0 - if( player.rewinding ) - { - if( player.rewind_time <= 0.0f ) - { - double taken = vg.time - player.diag_rewind_start; - vg_success( "Rewind took (rt, pl, tl): %f, %f, %f\n", - taken, player.diag_rewind_time, - player.rewind_total_length ); - - player.rewinding = 0; - player.rewind_length = 1; - player.rewind_total_length = 0.0f; - player.rewind_incrementer = 0; - world.sky_target_rate = 1.0; - } - else - { - world.sky_target_rate = -100.0; - assert( player.rewind_length > 0 ); - - v2f override_angles; - v3f override_pos; - - float budget = vg.time_delta, - overall_length = player.rewind_length; - - world_routes_rollback_time( player.rewind_time / overall_length ); - - for( int i=0; (i<10)&&(player.rewind_time>0.0f)&&(budget>0.0f); i ++ ) - { - /* Interpolate frames */ - int i0 = floorf( player.rewind_time ), - i1 = VG_MIN( i0+1, player.rewind_length-1 ); - - struct rewind_frame *fr = &player.rewind_buffer[i0], - *fr1 = &player.rewind_buffer[i1]; - - float dist = vg_maxf( v3_dist( fr->pos, fr1->pos ), 0.001f ), - subl = vg_fractf( player.rewind_time ) + 0.001f, - - sramp= 3.0f-(1.0f/(0.4f+0.4f*player.rewind_time)), - speed = sramp*28.0f + 0.5f*player.rewind_time, - mod = speed * (budget / dist), - - advl = vg_minf( mod, subl ), - advt = (advl / mod) * budget; - - player.dist_accum += speed * advt; - player.rewind_time -= advl; - budget -= advt; - } - - player.rewind_time = vg_maxf( 0.0f, player.rewind_time ); - - float current_time = vg.time - player.diag_rewind_start, - remaining = player.rewind_predicted_time - current_time; - - if( player.rewind_sound_wait ) - { - if( player.rewind_predicted_time >= 6.5f ) - { - if( remaining <= 6.5f ) - { - audio_lock(); - audio_play_oneshot( &audio_rewind[3], 1.0f ); - audio_unlock(); - player.rewind_sound_wait = 0; - } - } - else if( player.rewind_predicted_time >= 2.5f ) - { - if( remaining <= 2.5f ) - { - audio_lock(); - audio_play_oneshot( &audio_rewind[2], 1.0f ); - audio_unlock(); - player.rewind_sound_wait = 0; - } - } - else if( player.rewind_predicted_time >= 1.5f ) - { - if( remaining <= 1.5f ) - { - audio_lock(); - audio_play_oneshot( &audio_rewind[1], 1.0f ); - audio_unlock(); - player.rewind_sound_wait = 0; - } - } - } - - int i0 = floorf( player.rewind_time ), - i1 = VG_MIN( i0+1, player.rewind_length-1 ); - - struct rewind_frame *fr = &player.rewind_buffer[i0], - *fr1 = &player.rewind_buffer[i1]; - - float sub = vg_fractf(player.rewind_time); - - v3_lerp( fr->pos, fr1->pos, sub, override_pos ); - override_angles[0] = vg_alerpf( fr->ang[0], fr1->ang[0], sub ); - override_angles[1] = vg_lerpf ( fr->ang[1], fr1->ang[1], sub ); - - /* CAMERA POSITIONING: LAYER 1 */ - float blend = (4.0f-player.rewind_time) * 0.25f, - c = vg_clampf( blend, 0.0f, 1.0f ); - - main_camera.angles[0] = - vg_alerpf(override_angles[0], player.angles[0], c); - main_camera.angles[1] = - vg_lerpf (override_angles[1], player.angles[1], c); - v3_lerp( override_pos, player.camera_pos, c, main_camera.pos ); - } - } -#endif - - camera_update_transform( &main_camera ); - player_audio(); -} - -VG_STATIC void draw_player( camera *cam ) -{ - if( player.is_dead ) - player_model_copy_ragdoll(); - - shader_viewchar_use(); - vg_tex2d_bind( &tex_characters, 0 ); - shader_viewchar_uTexMain( 0 ); - shader_viewchar_uCamera( cam->transform[3] ); - shader_viewchar_uPv( cam->mtx.pv ); - shader_link_standard_ub( _shader_viewchar.id, 2 ); - glUniformMatrix4x3fv( _uniform_viewchar_uTransforms, - player.mdl.sk.bone_count, - 0, - (float *)player.mdl.sk.final_mtx ); - - mesh_bind( &player.mdl.player_meshes[cl_playermdl_id] ); - mesh_draw( &player.mdl.player_meshes[cl_playermdl_id] ); -} - -VG_STATIC void player_do_motion(void) -{ - if( world.water.enabled ) - { - if( (player.rb.co[1] < 0.0f) && !player.is_dead ) - { - 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, 20.0f ); - audio_player_playclip( &audio_player_extra, &audio_splash ); - audio_unlock(); - - player_kill(); - } - } - - v3f prevco; - v3_copy( player.rb.co, prevco ); - - if( player.controller == k_player_controller_skate ) - { -#if 0 - player_skate_update(); -#endif - } - else - player_walk_physics( &player_walky ); - - - /* Real angular velocity integration */ -#if 0 - v3_lerp( phys->rb.w, (v3f){0.0f,0.0f,0.0f}, 0.125f*0.5f, phys->rb.w ); - if( v3_length2( phys->rb.w ) > 0.0f ) - { - v4f rotation; - v3f axis; - v3_copy( phys->rb.w, axis ); - - float mag = v3_length( axis ); - v3_divs( axis, mag, axis ); - q_axis_angle( rotation, axis, mag*k_rb_delta ); - q_mul( rotation, phys->rb.q, phys->rb.q ); - } - - /* Faux angular velocity */ - v4f rotate; - - float lerpq = (player_skate.activity == k_skate_activity_air)? 0.04f: 0.3f; - phys->siY = vg_lerpf( phys->siY, phys->iY, lerpq ); - - q_axis_angle( rotate, phys->rb.up, phys->siY ); - q_mul( rotate, phys->rb.q, phys->rb.q ); - phys->iY = 0.0f; -#endif - - /* - * Gate intersection, by tracing a line over the gate planes - */ -#if 0 - for( int i=0; igate; - - if( gate_intersect( gate, phys->rb.co, prevco ) ) - { - m4x3_mulv( gate->transport, phys->rb.co, phys->rb.co ); - m4x3_mulv( gate->transport, phys->cog, phys->cog ); - m3x3_mulv( gate->transport, phys->cog_v, phys->cog_v ); - m3x3_mulv( gate->transport, phys->rb.v, phys->rb.v ); - m3x3_mulv( gate->transport, phys->vl, phys->vl ); - m3x3_mulv( gate->transport, phys->v_last, phys->v_last ); - m3x3_mulv( gate->transport, phys->m, phys->m ); - m3x3_mulv( gate->transport, phys->bob, phys->bob ); - - /* Pre-emptively edit the camera matrices so that the motion vectors - * are correct */ - m4x3f transport_i; - m4x4f transport_4; - m4x3_invert_affine( gate->transport, transport_i ); - m4x3_expand( transport_i, transport_4 ); - m4x4_mul( main_camera.mtx.pv, transport_4, main_camera.mtx.pv ); - m4x4_mul( main_camera.mtx.v, transport_4, main_camera.mtx.v ); - - v4f transport_rotation; - m3x3_q( gate->transport, transport_rotation ); - q_mul( transport_rotation, phys->rb.q, phys->rb.q ); - - world_routes_activate_gate( i ); - - if( phys->controller == k_player_controller_walk ) - { - 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] ); - } - - player.rewind_length = 0; - player.rewind_total_length = 0.0f; - player.rewind_incrementer = 10000; - player_save_frame(); - - audio_lock(); - audio_play_oneshot( &audio_gate_pass, 1.0f ); - audio_unlock(); - break; - } - } -#endif - - rb_update_transform( &player.rb ); -} - -/* - * ----------------------------------------------------------------------------- - * API implementation - * ----------------------------------------------------------------------------- - */ - -VG_STATIC float *player_get_pos(void) -{ - return player.rb.co; -} - -VG_STATIC void player_kill(void) -{ - if( player.death_tick_allowance == 0 ) - { - player.is_dead = 1; - player_ragdoll_copy_model( player.rb.v ); - } -} - -VG_STATIC float *player_cam_pos(void) -{ - return player.camera_pos; -} - - -VG_STATIC void player_save_frame(void) -{ - player.controller_frame = player.controller; - - /* TODO ->save() */ -} - -VG_STATIC void player_restore_frame(void) -{ - player.controller = player.controller_frame; - - /* TODO ->load() */ -} +static void player__debugtext( int size, const char *fmt, ... ); +static void player__use_mesh( glmesh *mesh ); +static void player__use_texture( vg_tex2d *tex ); +static void player__use_model( u16 reg_id ); + +static void player__bind(void); +static void player__pre_update(void); +static void player__update(void); +static void player__post_update(void); + +static void player__pass_gate( u32 id ); +static void player__im_gui(void); +static void player__setpos( v3f pos ); +static void player__spawn( ent_spawn *rp ); +static void player__clean_refs(void); +static void player__reset(void); +static void player__kill(void); +static void player__begin_holdout( v3f offset ); + +static int localplayer_cmd_respawn( int argc, const char *argv[] ); +static void player_apply_transport_to_cam( m4x3f transport ); + +static void player__clear_sfx_buffer(void); +static void player__networked_sfx( u8 system, u8 priority, u8 id, + v3f pos, f32 volume ); +static void net_sfx_exchange( bitpack_ctx *ctx, struct net_sfx *sfx ); +static void net_sfx_play( struct net_sfx *sfx ); #endif /* PLAYER_H */ -#endif