X-Git-Url: https://harrygodden.com/git/?a=blobdiff_plain;f=player.h;h=38e01ad2865bf73d72b12e64e43c433b007ef3e8;hb=f99902f513b0ad606437bf32de47405dd4ea5f98;hp=53016cd68884f2a6c32a085d745f844c8ab4c44b;hpb=72c40f1bc7a732f6a628dbf8a4135ac0bf3efa4e;p=carveJwlIkooP6JGAAIwe30JlM.git diff --git a/player.h b/player.h index 53016cd..38e01ad 100644 --- a/player.h +++ b/player.h @@ -7,8 +7,10 @@ #include "player_walk.h" #include "player_skate.h" #include "player_dead.h" +#include "player_drive.h" #define PLAYER_REWIND_FRAMES 60*4 +#define RESET_MAX_TIME 45.0 struct player_instance { @@ -26,8 +28,7 @@ struct player_instance */ camera cam; - enum camera_mode - { + enum camera_mode{ k_cam_firstperson = 1, k_cam_thirdperson = 0 } @@ -116,11 +117,11 @@ struct player_instance * ------------------------------------------------- */ - enum player_subsystem - { + enum player_subsystem{ k_player_subsystem_walk = 0, k_player_subsystem_skate = 1, - k_player_subsystem_dead = 2 + k_player_subsystem_dead = 2, + k_player_subsystem_drive = 3 } subsystem, subsystem_gate; @@ -128,6 +129,7 @@ struct player_instance struct player_skate _skate; struct player_walk _walk; struct player_dead _dead; + struct player_drive _drive; }; /* @@ -135,12 +137,22 @@ struct player_instance * --------------------------------------------------------- */ +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 + NULL, + player__drive_bind }; VG_STATIC @@ -148,7 +160,8 @@ void (*_player_reset[])( player_instance *player, ent_spawn *rp ) = { player__walk_reset, player__skate_reset, - NULL + NULL, + player__drive_reset }; VG_STATIC @@ -156,7 +169,8 @@ void (*_player_pre_update[])( player_instance *player ) = { player__walk_pre_update, player__skate_pre_update, - NULL + NULL, + player__drive_pre_update }; VG_STATIC @@ -165,6 +179,7 @@ void( *_player_update[])( player_instance *player ) = player__walk_update, player__skate_update, player__dead_update, + player__drive_update }; VG_STATIC @@ -172,7 +187,8 @@ void( *_player_post_update[])( player_instance *player ) = { player__walk_post_update, player__skate_post_update, - NULL + NULL, + player__drive_post_update }; VG_STATIC @@ -180,7 +196,8 @@ void( *_player_im_gui[])( player_instance *player ) = { player__walk_im_gui, player__skate_im_gui, - NULL + NULL, + player__drive_im_gui }; VG_STATIC @@ -188,7 +205,8 @@ void( *_player_animate[])( player_instance *player, player_animation *dest ) = { player__walk_animate, player__skate_animate, - player__dead_animate + player__dead_animate, + player__drive_animate }; VG_STATIC @@ -196,7 +214,8 @@ void( *_player_post_animate[])( player_instance *player ) = { player__walk_post_animate, player__skate_post_animate, - player__dead_post_animate + player__dead_post_animate, + player__drive_post_animate }; VG_STATIC @@ -204,9 +223,18 @@ void( *_player_restore[] )( player_instance *player ) = { player__walk_restore, player__skate_restore, + NULL, NULL }; +VG_STATIC void player_init(void) +{ + for( u32 i=0; i_ - * - * - * - */ - -/* - * ----------------------------------------------------------------------------- - * 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() */ -} - -#endif /* PLAYER_H */ -#endif