6 #include "player_model.h"
11 VG_STATIC
int localplayer_cmd_respawn( int argc
, const char *argv
[] )
13 ent_spawn
*rp
= NULL
, *r
;
14 world_instance
*world
= localplayer
.viewable_world
;
17 rp
= world_find_spawn_by_name( world
, argv
[0] );
20 rp
= world_find_closest_spawn( world
, localplayer
.rb
.co
);
26 player__spawn( &localplayer
, rp
);
30 VG_STATIC
void player_init(void)
32 for( u32 i
=0; i
<vg_list_size(_player_system_register
); i
++ ){
33 if( _player_system_register
[i
] )
34 _player_system_register
[i
]();
37 vg_console_reg_cmd( "respawn", localplayer_cmd_respawn
, NULL
);
38 VG_VAR_F32( k_cam_damp
);
39 VG_VAR_F32( k_cam_spring
);
40 VG_VAR_F32( k_cam_punch
);
41 VG_VAR_F32( k_cam_shake_strength
);
42 VG_VAR_F32( k_cam_shake_trackspeed
);
43 VG_VAR_I32( k_player_debug_info
);
45 vg_console_reg_var( "cinema", &k_cinema
, k_var_dtype_f32
, 0 );
46 vg_console_reg_var( "cinema_fixed", &k_cinema_fixed
, k_var_dtype_i32
, 0 );
47 vg_console_reg_var( "invert_y", &k_invert_y
,
48 k_var_dtype_i32
, VG_VAR_PERSISTENT
);
52 void player__debugtext( int size
, const char *fmt
, ... )
57 va_start( args
, fmt
);
58 vsnprintf( buffer
, 1024, fmt
, args
);
61 ui_text( g_player_debugger
, buffer
, size
, k_ui_align_left
, 0 );
62 g_player_debugger
[1] += size
*16;
69 void player__create( player_instance
*inst
)
71 static int only_once
= 0;
72 assert( only_once
== 0 );
75 v3_zero( inst
->rb
.co
);
76 v3_zero( inst
->rb
.w
);
77 v3_zero( inst
->rb
.v
);
78 q_identity( inst
->rb
.q
);
79 m4x3_identity( inst
->rb
.to_world
);
80 m4x3_identity( inst
->rb
.to_local
);
82 inst
->rewind_length
= 0;
84 vg_linear_alloc( vg_mem
.rtmemory
,
85 sizeof(struct rewind_frame
) * PLAYER_REWIND_FRAMES
);
93 void player__use_avatar( player_instance
*player
, struct player_avatar
*av
)
95 player
->playeravatar
= av
;
96 player_setup_ragdoll_from_avatar( &player
->ragdoll
, av
);
100 void player__use_model( player_instance
*player
, u16 reg_id
){
101 addon_cache_unwatch( k_addon_type_player
, player
->playermodel_view_slot
);
102 player
->playermodel_view_slot
=
103 addon_cache_create_viewer( k_addon_type_player
, reg_id
);
107 void player__bind( player_instance
*player
)
109 for( u32 i
=0; i
<vg_list_size(_player_bind
); i
++ ){
110 if( _player_bind
[i
] )
111 _player_bind
[i
]( player
);
117 * ----------------------------------------------------------------------------
120 VG_STATIC
void player_save_rewind_frame( player_instance
*player
)
122 if( player
->rewind_length
< PLAYER_REWIND_FRAMES
){
123 struct rewind_frame
*fr
=
124 &player
->rewind_buffer
[ player
->rewind_length
++ ];
126 v2_copy( player
->cam
.angles
, fr
->ang
);
127 v3_copy( player
->cam
.pos
, fr
->pos
);
129 if( player
->rewind_length
>= 2 ){
130 player
->rewind_total_length
+=
131 v3_dist( player
->rewind_buffer
[player
->rewind_length
-1].pos
,
132 player
->rewind_buffer
[player
->rewind_length
-2].pos
);
138 void player__pre_update( player_instance
*player
)
140 if( player
->rewinding
){
144 if( button_down( k_srbind_reset
) && !player
->immobile
){
145 f64 delta
= world_static
.time
- world_static
.last_use
;
147 if( (delta
<= RESET_MAX_TIME
) && (world_static
.last_use
!= 0.0) ){
148 player
->rewinding
= 1;
149 player
->rewind_sound_wait
= 1;
150 player
->rewind_time
= (double)player
->rewind_length
- 0.0001;
151 player_save_rewind_frame( player
);
154 audio_oneshot( &audio_rewind
[0], 1.0f
, 0.0f
);
157 /* based on testing. DONT CHANGE!
159 * time taken: y = (x^(4/5)) * 74.5
160 * inverse : x = (2/149)^(4/5) * y^(4/5)
163 float constant
= powf( 2.0f
/149.0f
, 4.0f
/5.0f
),
164 curve
= powf( player
->rewind_total_length
, 4.0f
/5.0f
);
166 player
->rewind_predicted_time
= constant
* curve
;
167 player
->rewind_start
= vg
.time
;
168 player
->subsystem
= player
->subsystem_gate
;
169 player
->rb
= player
->rb_gate_storage
;
170 v3_copy( player
->angles_storage
, player
->angles
);
172 if( _player_restore
[ player
->subsystem
] )
173 _player_restore
[ player
->subsystem
]( player
);
176 if( player
->subsystem
== k_player_subsystem_dead
){
177 localplayer_cmd_respawn( 0, NULL
);
182 audio_oneshot( &audio_rewind
[4], 1.0f
, 0.0f
);
188 if( button_down( k_srbind_camera
) && !player
->immobile
){
189 if( player
->camera_mode
== k_cam_firstperson
)
190 player
->camera_mode
= k_cam_thirdperson
;
192 player
->camera_mode
= k_cam_firstperson
;
195 if( _player_pre_update
[ player
->subsystem
] )
196 _player_pre_update
[ player
->subsystem
]( player
);
200 void player__update( player_instance
*player
)
202 if( player
->rewinding
)
205 if( _player_update
[ player
->subsystem
] )
206 _player_update
[ player
->subsystem
]( player
);
210 void player__post_update( player_instance
*player
)
212 if( player
->rewinding
)
215 if( _player_post_update
[ player
->subsystem
] )
216 _player_post_update
[ player
->subsystem
]( player
);
218 if((player
->subsystem
!= k_player_subsystem_dead
) && !player
->gate_waiting
){
219 player
->rewind_accum
+= vg
.time_frame_delta
;
221 if( player
->rewind_accum
> 0.25f
){
222 player
->rewind_accum
-= 0.25f
;
223 player_save_rewind_frame( player
);
229 * Applies gate transport to a player_interface
232 void player__pass_gate( player_instance
*player
, ent_gate
*gate
)
234 world_routes_fracture( world_current_instance(), gate
,
235 player
->rb
.co
, player
->rb
.v
);
237 player
->gate_waiting
= gate
;
238 world_routes_activate_entry_gate( world_current_instance(), gate
);
240 m4x3_mulv( gate
->transport
, player
->tpv_lpf
, player
->tpv_lpf
);
241 m3x3_mulv( gate
->transport
, player
->cam_velocity_smooth
,
242 player
->cam_velocity_smooth
);
244 m3x3_copy( player
->basis
, player
->basis_gate
);
247 m3x3_q( gate
->transport
, q
);
248 q_mul( q
, player
->qbasis
, player
->qbasis
);
249 q_normalize( player
->qbasis
);
250 q_m3x3( player
->qbasis
, player
->basis
);
251 m3x3_transpose( player
->basis
, player
->invbasis
);
253 player
->subsystem_gate
= player
->subsystem
;
254 player
->rb_gate_storage
= player
->rb
;
255 v3_copy( player
->angles
, player
->angles_storage
);
256 player
->rewind_length
= 0;
257 player
->rewind_total_length
= 0.0f
;
258 player
->rewind_gate
= gate
;
259 player
->rewind_accum
= 0.0f
;
261 m4x3_mulv( gate
->transport
, player
->cam
.pos
, player
->cam
.pos
);
262 player_save_rewind_frame( player
);
264 if( gate
->type
== k_gate_type_nonlocel
)
265 world_static
.active_world
= gate
->target
;
267 world_volumes
.inside
= 0;
270 audio_oneshot( &audio_gate_pass
, 1.0f
, 0.0f
);
274 VG_STATIC
void player_apply_transport_to_cam( m4x3f transport
)
276 /* FIXME: Applies to main_camera directly! */
278 /* Pre-emptively edit the camera matrices so that the motion vectors
282 m4x3_invert_affine( transport
, transport_i
);
283 m4x3_expand( transport_i
, transport_4
);
284 m4x4_mul( main_camera
.mtx
.pv
, transport_4
, main_camera
.mtx
.pv
);
285 m4x4_mul( main_camera
.mtx
.v
, transport_4
, main_camera
.mtx
.v
);
287 /* we want the regular transform here no the inversion */
288 m4x3_expand( transport
, transport_4
);
289 m4x4_mul( gate_camera
.mtx
.pv
, transport_4
, gate_camera
.mtx
.pv
);
290 m4x4_mul( gate_camera
.mtx
.v
, transport_4
, gate_camera
.mtx
.v
);
293 __attribute__ ((deprecated
))
294 VG_STATIC
void gate_rotate_angles( ent_gate
*gate
, v3f angles
, v3f d
)
296 v3_copy( angles
, d
);
299 v3f fwd_dir
= { cosf(angles
[0]),
302 m3x3_mulv( gate
->transport
, fwd_dir
, fwd_dir
);
304 v3_copy( angles
, d
);
305 d
[0] = atan2f( fwd_dir
[2], fwd_dir
[0] );
308 PLAYER_API
void player__im_gui( player_instance
*player
){
309 if( !k_player_debug_info
) return;
318 ui_fill( box
, (ui_colour(k_ui_bg
)&0x00ffffff)|0x50000000 );
320 g_player_debugger
[0] = box
[0];
321 g_player_debugger
[1] = 0;
322 g_player_debugger
[2] = 300;
323 g_player_debugger
[3] = 16;
325 player__debugtext( 1, "angles: " PRINTF_v3f( player
->cam
.angles
) );
326 player__debugtext( 1, "basis: " PRINTF_v4f( player
->qbasis
) );
328 if( _player_im_gui
[ player
->subsystem
] )
329 _player_im_gui
[ player
->subsystem
]( player
);
332 VG_STATIC
void global_skateshop_exit(void);
334 PLAYER_API
void player__setpos( player_instance
*player
, v3f pos
){
335 v3_copy( pos
, player
->rb
.co
);
336 v3_zero( player
->rb
.v
);
337 rb_update_transform( &player
->rb
);
340 PLAYER_API
void player__spawn( player_instance
*player
, ent_spawn
*rp
){
341 player__setpos( player
, rp
->transform
.co
);
342 v3_zero( player
->rb
.w
);
343 q_identity( player
->rb
.q
);
344 rb_update_transform( &player
->rb
);
346 q_identity( player
->qbasis
);
347 m3x3_identity( player
->basis
);
348 m3x3_identity( player
->invbasis
);
350 player
->subsystem
= k_player_subsystem_walk
;
351 player
->immobile
= 0;
352 player
->gate_waiting
= NULL
;
353 player
->rewind_length
= 0;
354 player
->rewind_accum
= 0.0f
;
355 player
->rewind_gate
= NULL
;
356 player
->rewinding
= 0;
357 world_static
.last_use
= 0.0;
359 global_skateshop_exit();
361 if( _player_reset
[ player
->subsystem
] )
362 _player_reset
[ player
->subsystem
]( player
, rp
);
366 PLAYER_API
void player__kill( player_instance
*player
){
371 #include "player_common.c"
372 #include "player_walk.c"
373 #include "player_skate.c"
374 #include "player_dead.c"
375 #include "player_drive.c"
376 #include "player_render.c"
377 #include "player_ragdoll.c"
379 #endif /* PLAYER_C */