world blend wip
This commit is contained in:
parent
5ca777f646
commit
55311f7b98
@ -38,7 +38,7 @@ i64 SaturateI64(i64 v) { return v < 0 ? 0 : v > 1 ? 1 : v; }
|
|||||||
f64 SaturateF64(f64 v) { return v < 0 ? 0 : v > 1 ? 1 : v; }
|
f64 SaturateF64(f64 v) { return v < 0 ? 0 : v > 1 ? 1 : v; }
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
//~ Float ops
|
//~ Numeric ops
|
||||||
|
|
||||||
//- Sign
|
//- Sign
|
||||||
|
|
||||||
|
|||||||
@ -234,7 +234,7 @@ i64 SaturateI64(i64 v);
|
|||||||
f64 SaturateF64(f64 v);
|
f64 SaturateF64(f64 v);
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
//~ Float ops
|
//~ Numeric ops
|
||||||
|
|
||||||
//- Round
|
//- Round
|
||||||
#define RoundF32 roundf
|
#define RoundF32 roundf
|
||||||
@ -257,6 +257,8 @@ f64 SaturateF64(f64 v);
|
|||||||
#define ModF64 fmod
|
#define ModF64 fmod
|
||||||
|
|
||||||
//- Abs
|
//- Abs
|
||||||
|
#define AbsI32 abs
|
||||||
|
#define AbsI64 llabs
|
||||||
#define AbsF32 fabsf
|
#define AbsF32 fabsf
|
||||||
#define AbsF64 fabs
|
#define AbsF64 fabs
|
||||||
|
|
||||||
|
|||||||
@ -89,39 +89,39 @@ u32 countof(T arr[N])
|
|||||||
#define ClampF64 (f64)clamp
|
#define ClampF64 (f64)clamp
|
||||||
|
|
||||||
//- Round
|
//- Round
|
||||||
#define RoundF32 (f32)round
|
#define RoundF32(a) round((f32)(a))
|
||||||
#define RoundF64 (f64)round
|
#define RoundF64(a) round((f64)(a))
|
||||||
|
|
||||||
//- Floor
|
//- Floor
|
||||||
#define FloorF32 (f32)floor
|
#define FloorF32(a) floor((f32)(a))
|
||||||
#define FloorF64 (f64)floor
|
#define FloorF64(a) floor((f64)(a))
|
||||||
|
|
||||||
//- Ceil
|
//- Ceil
|
||||||
#define CeilF32 (f32)ceil
|
#define CeilF32(a) ceil((f32)(a))
|
||||||
#define CeilF64 (f64)ceil
|
#define CeilF64(a) ceil((f64)(a))
|
||||||
|
|
||||||
//- Trunc
|
//- Trunc
|
||||||
#define TruncF32 (f32)trunc
|
#define TruncF32(a) trunc((f32)(a))
|
||||||
#define TruncF64 (f64)trunc
|
#define TruncF64(a) trunc((f64)(a))
|
||||||
|
|
||||||
//- Mod
|
//- Mod
|
||||||
#define ModF32 (f32)fmod
|
#define ModF32(a, b) fmod((f32)(a), (f32)(b))
|
||||||
#define ModF64 (f64)fmod
|
#define ModF64(a, b) fmod((f64)(a), (f64)(b))
|
||||||
|
|
||||||
//- Abs
|
//- Abs
|
||||||
#define AbsF32 (f32)abs
|
#define AbsF32(a) abs((f32)(a))
|
||||||
#define AbsF64 (f64)abs
|
#define AbsF64(a) abs((f64)(a))
|
||||||
|
|
||||||
//- Sign
|
//- Sign
|
||||||
#define SignF32 (f32)sign
|
#define SignF32(a) sign((f32)(a))
|
||||||
#define SignF64 (f64)sign
|
#define SignF64(a) sign((f64)(a))
|
||||||
|
|
||||||
//- Smoothstep
|
//- Smoothstep
|
||||||
#define SmoothstepF32 (f32)smoothstep
|
#define SmoothstepF32(a, b, t) smoothstep((f32)(a), (f32)(b), (f32)(t))
|
||||||
#define SmoothstepF64 (f64)smoothstep
|
#define SmoothstepF64(a, b, t) smoothstep((f64)(a), (f64)(b), (f64)(t))
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
//~ Float ops
|
//~ Numeric ops
|
||||||
|
|
||||||
//- Normalize
|
//- Normalize
|
||||||
|
|
||||||
|
|||||||
10
src/config.h
10
src/config.h
@ -1,20 +1,14 @@
|
|||||||
// Project-wide configurable constants
|
// Project-wide configurable constants
|
||||||
|
|
||||||
// How many ticks back in time should the user thread blend between?
|
|
||||||
// <Delay> = <USER_INTERP_RATIO> * <Tick interval>
|
|
||||||
// E.g: At 1.5, the user thread will render 75ms back in time if the sim runs at 50tps
|
|
||||||
#define USER_INTERP_RATIO 1.2
|
|
||||||
#define USER_INTERP_ENABLED 1
|
|
||||||
|
|
||||||
#define SIM_MAX_PING 5.0
|
#define SIM_MAX_PING 5.0
|
||||||
|
|
||||||
#define SIM_PHYSICS_SUBSTEPS 4
|
#define SIM_PHYSICS_SUBSTEPS 4
|
||||||
|
|
||||||
#define SIM_TICKS_PER_SECOND 64
|
#define SIM_TICKS_PER_SECOND 32
|
||||||
#define SIM_TICK_INTERVAL_NS (NsFromSeconds(1) / SIM_TICKS_PER_SECOND)
|
#define SIM_TICK_INTERVAL_NS (NsFromSeconds(1) / SIM_TICKS_PER_SECOND)
|
||||||
// Like USER_INTERP_RATIO, but applies to snapshots received by the local sim from the
|
// Like USER_INTERP_RATIO, but applies to snapshots received by the local sim from the
|
||||||
// master sim (how far back in time should the client render the server's state)
|
// master sim (how far back in time should the client render the server's state)
|
||||||
#define SIM_CLIENT_INTERP_RATIO 2.0
|
// #define SIM_CLIENT_INTERP_RATIO 2.0
|
||||||
|
|
||||||
|
|
||||||
#define GPU_NAMES IsRtcEnabled
|
#define GPU_NAMES IsRtcEnabled
|
||||||
|
|||||||
@ -363,7 +363,6 @@ void V_TickForever(WaveLaneCtx *lane)
|
|||||||
|
|
||||||
P_World *sim_world = P_AcquireWorld();
|
P_World *sim_world = P_AcquireWorld();
|
||||||
P_World *predict_world = P_AcquireWorld();
|
P_World *predict_world = P_AcquireWorld();
|
||||||
P_World *local_world = P_AcquireWorld();
|
|
||||||
|
|
||||||
i64 local_controls_cap = NextPow2U64(SIM_MAX_PING * SIM_TICKS_PER_SECOND);
|
i64 local_controls_cap = NextPow2U64(SIM_MAX_PING * SIM_TICKS_PER_SECOND);
|
||||||
P_Control *local_controls = PushStructs(perm, P_Control, local_controls_cap);
|
P_Control *local_controls = PushStructs(perm, P_Control, local_controls_cap);
|
||||||
@ -524,6 +523,7 @@ void V_TickForever(WaveLaneCtx *lane)
|
|||||||
frame->quads_arena = AcquireArena(Gibi(64));
|
frame->quads_arena = AcquireArena(Gibi(64));
|
||||||
frame->dverts_arena = AcquireArena(Gibi(64));
|
frame->dverts_arena = AcquireArena(Gibi(64));
|
||||||
frame->dvert_idxs_arena = AcquireArena(Gibi(64));
|
frame->dvert_idxs_arena = AcquireArena(Gibi(64));
|
||||||
|
frame->local_world = P_AcquireWorld();
|
||||||
}
|
}
|
||||||
|
|
||||||
//////////////////////////////
|
//////////////////////////////
|
||||||
@ -577,11 +577,13 @@ void V_TickForever(WaveLaneCtx *lane)
|
|||||||
Arena *old_quads_arena = frame->quads_arena;
|
Arena *old_quads_arena = frame->quads_arena;
|
||||||
Arena *old_dverts_arena = frame->dverts_arena;
|
Arena *old_dverts_arena = frame->dverts_arena;
|
||||||
Arena *old_dvert_idxs_arena = frame->dvert_idxs_arena;
|
Arena *old_dvert_idxs_arena = frame->dvert_idxs_arena;
|
||||||
|
P_World *old_local_world = frame->local_world;
|
||||||
ZeroStruct(frame);
|
ZeroStruct(frame);
|
||||||
frame->arena = old_arena;
|
frame->arena = old_arena;
|
||||||
frame->quads_arena = old_quads_arena;
|
frame->quads_arena = old_quads_arena;
|
||||||
frame->dverts_arena = old_dverts_arena;
|
frame->dverts_arena = old_dverts_arena;
|
||||||
frame->dvert_idxs_arena = old_dvert_idxs_arena;
|
frame->dvert_idxs_arena = old_dvert_idxs_arena;
|
||||||
|
frame->local_world = old_local_world;
|
||||||
}
|
}
|
||||||
frame->cl = G_PrepareCommandList(G_QueueKind_Direct);
|
frame->cl = G_PrepareCommandList(G_QueueKind_Direct);
|
||||||
ResetArena(frame->arena);
|
ResetArena(frame->arena);
|
||||||
@ -1006,8 +1008,8 @@ void V_TickForever(WaveLaneCtx *lane)
|
|||||||
Vec2 look_pos = frame->look;
|
Vec2 look_pos = frame->look;
|
||||||
look_pos = RotateVec2(look_pos, InvertRot(rot));
|
look_pos = RotateVec2(look_pos, InvertRot(rot));
|
||||||
|
|
||||||
P_Ent *player = P_EntFromKey(local_world->last_frame, V.player_key);
|
P_Ent *player = P_EntFromKey(frame->local_world->last_frame, V.player_key);
|
||||||
P_Ent *guy = P_EntFromKey(local_world->last_frame, player->guy);
|
P_Ent *guy = P_EntFromKey(frame->local_world->last_frame, player->guy);
|
||||||
Vec2 guy_center = P_WorldShapeFromEnt(guy).centroid;
|
Vec2 guy_center = P_WorldShapeFromEnt(guy).centroid;
|
||||||
Vec2 screen_center = MulVec2(frame->screen_dims, 0.5);
|
Vec2 screen_center = MulVec2(frame->screen_dims, 0.5);
|
||||||
target_camera_pos = guy_center;
|
target_camera_pos = guy_center;
|
||||||
@ -1363,12 +1365,13 @@ void V_TickForever(WaveLaneCtx *lane)
|
|||||||
// If the server reports it has too many of our commands buffered up, we
|
// If the server reports it has too many of our commands buffered up, we
|
||||||
// slow the rate of prediction.
|
// slow the rate of prediction.
|
||||||
|
|
||||||
|
f64 dilation_factor = 0;
|
||||||
{
|
{
|
||||||
// How many buffered commands of ours we'd like the server to have
|
// How many buffered commands of ours we'd like the server to have
|
||||||
i64 target_buffered_controls_count = 1;
|
i64 target_buffered_controls_count = 1;
|
||||||
f64 rtt_bias_factor = 10.0;
|
f64 rtt_bias_factor = 10.0;
|
||||||
|
|
||||||
f64 dilation_factor = SmoothstepF64(
|
dilation_factor = SmoothstepF64(
|
||||||
-(SIM_TICKS_PER_SECOND * smoothed_rtt * rtt_bias_factor),
|
-(SIM_TICKS_PER_SECOND * smoothed_rtt * rtt_bias_factor),
|
||||||
(SIM_TICKS_PER_SECOND * smoothed_rtt * rtt_bias_factor),
|
(SIM_TICKS_PER_SECOND * smoothed_rtt * rtt_bias_factor),
|
||||||
target_buffered_controls_count - remote_buffered_controls_count
|
target_buffered_controls_count - remote_buffered_controls_count
|
||||||
@ -1630,7 +1633,7 @@ void V_TickForever(WaveLaneCtx *lane)
|
|||||||
}
|
}
|
||||||
predict_world->seed = sim_world->seed;
|
predict_world->seed = sim_world->seed;
|
||||||
|
|
||||||
P_ClearFrames(predict_world, I64Min, first_predict_tick - 1);
|
P_ClearFrames(predict_world, I64Min, MinI64(first_predict_tick - 1, prev_frame->blend_from_tick - 1));
|
||||||
predict_frame = P_PushFrame(predict_world, P_FrameFromTick(sim_world, first_predict_tick), first_predict_tick);
|
predict_frame = P_PushFrame(predict_world, P_FrameFromTick(sim_world, first_predict_tick), first_predict_tick);
|
||||||
|
|
||||||
for (i64 predict_tick = first_predict_tick + 1; predict_tick <= last_predict_tick; ++predict_tick)
|
for (i64 predict_tick = first_predict_tick + 1; predict_tick <= last_predict_tick; ++predict_tick)
|
||||||
@ -1833,21 +1836,92 @@ void V_TickForever(WaveLaneCtx *lane)
|
|||||||
//////////////////////////////
|
//////////////////////////////
|
||||||
//- Update local world
|
//- Update local world
|
||||||
|
|
||||||
// TODO: Remove this
|
P_Frame *prev_local_frame = prev_frame->local_world->last_frame;
|
||||||
P_Frame *local_frame = &P_NilFrame;
|
P_Frame *local_frame = &P_NilFrame;
|
||||||
{
|
{
|
||||||
if (local_world->tiles_hash != predict_world->tiles_hash)
|
if (frame->local_world->tiles_hash != predict_world->tiles_hash)
|
||||||
{
|
{
|
||||||
local_world->tiles_hash = predict_world->tiles_hash;
|
frame->local_world->tiles_hash = predict_world->tiles_hash;
|
||||||
CopyStructs(local_world->tiles, predict_world->tiles, P_TilesCount);
|
CopyStructs(frame->local_world->tiles, predict_world->tiles, P_TilesCount);
|
||||||
frame->tiles_dirty = 1;
|
frame->tiles_dirty = 1;
|
||||||
}
|
}
|
||||||
local_world->seed = predict_world->seed;
|
frame->local_world->seed = predict_world->seed;
|
||||||
|
P_ClearFrames(frame->local_world, I64Min, I64Max);
|
||||||
|
|
||||||
P_ClearFrames(local_world, I64Min, local_world->last_frame->tick - 1);
|
i64 target_blend_dt_ns = frame->dt_ns + frame->dt_ns * dilation_factor;
|
||||||
local_frame = P_PushFrame(local_world, predict_world->last_frame, predict_world->last_frame->tick);
|
i64 blend_dt_ns = frame->dt_ns;
|
||||||
|
|
||||||
// LogDebugF("First frame: %F, Last frame: %F", FmtSint(local_world->first_frame->tick), FmtSint(local_world->last_frame->tick));
|
V.target_blend_time_ns += target_blend_dt_ns;
|
||||||
|
V.blend_time_ns += blend_dt_ns;
|
||||||
|
|
||||||
|
// How many ticks back in time should the user thread blend between?
|
||||||
|
// <Delay> = <USER_INTERP_RATIO> * <Tick interval>
|
||||||
|
// E.g: At 1.5, the world will render 75ms back in time if the sim runs at 50tps
|
||||||
|
f32 interp_ratio = TweakFloat("Interpolation ratio", 1.2, 0, 5);
|
||||||
|
if (predict_to != prev_frame_predict_to)
|
||||||
|
{
|
||||||
|
i64 delay_ns = SIM_TICK_INTERVAL_NS * interp_ratio;
|
||||||
|
V.target_blend_time_ns = predict_world->last_frame->time_ns - delay_ns;
|
||||||
|
}
|
||||||
|
|
||||||
|
f64 blend_to_target_lerp_rate = 0.05;
|
||||||
|
V.blend_time_ns = LerpI64(V.blend_time_ns, V.target_blend_time_ns, blend_to_target_lerp_rate);
|
||||||
|
if (AbsI64(V.blend_time_ns - V.target_blend_time_ns) > (SIM_TICK_INTERVAL_NS * interp_ratio * 2))
|
||||||
|
{
|
||||||
|
LogDebugF("Blend reset");
|
||||||
|
V.blend_time_ns = V.target_blend_time_ns;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (TweakBool("Interpolation enabled", 1))
|
||||||
|
{
|
||||||
|
P_Frame *left_frame = &P_NilFrame;
|
||||||
|
P_Frame *right_frame = &P_NilFrame;
|
||||||
|
for (P_Frame *tmp = predict_world->last_frame; !P_IsFrameNil(tmp); tmp = tmp->prev)
|
||||||
|
{
|
||||||
|
if (tmp->time_ns >= V.blend_time_ns && tmp->prev->time_ns <= V.blend_time_ns)
|
||||||
|
{
|
||||||
|
right_frame = tmp;
|
||||||
|
left_frame = tmp->prev;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (P_IsFrameNil(left_frame) || P_IsFrameNil(right_frame))
|
||||||
|
{
|
||||||
|
right_frame = predict_world->last_frame;
|
||||||
|
left_frame = right_frame->prev;
|
||||||
|
}
|
||||||
|
|
||||||
|
frame->blend_from_tick = left_frame->tick;
|
||||||
|
frame->blend_to_tick = right_frame->tick;
|
||||||
|
|
||||||
|
local_frame = P_PushFrame(frame->local_world, left_frame, left_frame->tick);
|
||||||
|
{
|
||||||
|
f64 blend_t = (f64)(V.blend_time_ns - left_frame->time_ns) / (f64)(right_frame->time_ns - left_frame->time_ns);
|
||||||
|
|
||||||
|
for (P_Ent *ent = P_FirstEnt(local_frame); !P_IsEntNil(ent); ent = P_NextEnt(ent))
|
||||||
|
{
|
||||||
|
P_Ent *left = ent;
|
||||||
|
P_Ent *right = P_EntFromKey(right_frame, ent->key);
|
||||||
|
|
||||||
|
ent->exists = LerpF32(left->exists, right->exists, blend_t);
|
||||||
|
if (!P_IsEntNil(right))
|
||||||
|
{
|
||||||
|
ent->health = LerpF32(left->health, right->health, blend_t);
|
||||||
|
ent->xf.t = LerpVec2(left->xf.t, right->xf.t, blend_t);
|
||||||
|
ent->xf.r = SlerpVec2(left->xf.r, right->xf.r, blend_t);
|
||||||
|
ent->walk_time_accum_ns = LerpI64(left->walk_time_accum_ns, right->walk_time_accum_ns, blend_t);
|
||||||
|
ent->v = LerpVec2(left->v, right->v, blend_t);
|
||||||
|
ent->w = LerpF32(left->w, right->w, blend_t);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
local_frame = P_PushFrame(frame->local_world, predict_world->last_frame, predict_world->last_frame->tick);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
P_DebugDrawFrame(local_frame);
|
P_DebugDrawFrame(local_frame);
|
||||||
@ -1858,6 +1932,34 @@ void V_TickForever(WaveLaneCtx *lane)
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// // TODO: Remove this
|
||||||
|
// P_Frame *local_frame = &P_NilFrame;
|
||||||
|
// {
|
||||||
|
// if (frame->local_world->tiles_hash != predict_world->tiles_hash)
|
||||||
|
// {
|
||||||
|
// frame->local_world->tiles_hash = predict_world->tiles_hash;
|
||||||
|
// CopyStructs(frame->local_world->tiles, predict_world->tiles, P_TilesCount);
|
||||||
|
// frame->tiles_dirty = 1;
|
||||||
|
// }
|
||||||
|
// frame->local_world->seed = predict_world->seed;
|
||||||
|
|
||||||
|
// P_ClearFrames(frame->local_world, I64Min, frame->local_world->last_frame->tick - 1);
|
||||||
|
// local_frame = P_PushFrame(frame->local_world, predict_world->last_frame, predict_world->last_frame->tick);
|
||||||
|
|
||||||
|
// // LogDebugF("First frame: %F, Last frame: %F", FmtSint(frame->local_world->first_frame->tick), FmtSint(frame->local_world->last_frame->tick));
|
||||||
|
|
||||||
|
|
||||||
|
// P_DebugDrawFrame(local_frame);
|
||||||
|
// }
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// {
|
// {
|
||||||
// i64 delay_ns = NsFromSeconds(100);
|
// i64 delay_ns = NsFromSeconds(100);
|
||||||
|
|
||||||
@ -1883,8 +1985,8 @@ void V_TickForever(WaveLaneCtx *lane)
|
|||||||
//////////////////////////////
|
//////////////////////////////
|
||||||
//- Query local player
|
//- Query local player
|
||||||
|
|
||||||
P_Ent *local_player = P_EntFromKey(local_world->last_frame, V.player_key);
|
P_Ent *local_player = P_EntFromKey(frame->local_world->last_frame, V.player_key);
|
||||||
P_Ent *local_guy = P_EntFromKey(local_world->last_frame, local_player->guy);
|
P_Ent *local_guy = P_EntFromKey(frame->local_world->last_frame, local_player->guy);
|
||||||
|
|
||||||
//////////////////////////////
|
//////////////////////////////
|
||||||
//- Compute crosshair position
|
//- Compute crosshair position
|
||||||
@ -2082,7 +2184,7 @@ void V_TickForever(WaveLaneCtx *lane)
|
|||||||
{
|
{
|
||||||
// TODO: Real world query
|
// TODO: Real world query
|
||||||
P_Shape cursor_shape = P_ShapeFromDesc(.count = 1, .points = { frame->world_cursor });
|
P_Shape cursor_shape = P_ShapeFromDesc(.count = 1, .points = { frame->world_cursor });
|
||||||
for (P_Ent *ent = P_FirstEnt(local_world->last_frame); !P_IsEntNil(ent); ent = P_NextEnt(ent))
|
for (P_Ent *ent = P_FirstEnt(frame->local_world->last_frame); !P_IsEntNil(ent); ent = P_NextEnt(ent))
|
||||||
{
|
{
|
||||||
P_Shape ent_shape = P_WorldShapeFromEnt(ent);
|
P_Shape ent_shape = P_WorldShapeFromEnt(ent);
|
||||||
b32 is_hovered = P_CollisionResultFromShapes(ent_shape, cursor_shape).collision_points_count > 0;
|
b32 is_hovered = P_CollisionResultFromShapes(ent_shape, cursor_shape).collision_points_count > 0;
|
||||||
@ -2300,7 +2402,7 @@ void V_TickForever(WaveLaneCtx *lane)
|
|||||||
if (bullet->is_bullet)
|
if (bullet->is_bullet)
|
||||||
{
|
{
|
||||||
// FIXME: Use 'last visible' pos
|
// FIXME: Use 'last visible' pos
|
||||||
P_Ent *old_bullet = P_EntFromKey(local_world->last_frame->prev, bullet->key);
|
P_Ent *old_bullet = P_EntFromKey(prev_local_frame, bullet->key);
|
||||||
Vec2 start = old_bullet->xf.t;
|
Vec2 start = old_bullet->xf.t;
|
||||||
Vec2 end = bullet->xf.t;
|
Vec2 end = bullet->xf.t;
|
||||||
if (P_IsEntNil(old_bullet))
|
if (P_IsEntNil(old_bullet))
|
||||||
@ -2374,7 +2476,7 @@ void V_TickForever(WaveLaneCtx *lane)
|
|||||||
if (bullet->is_bullet && bullet->has_hit)
|
if (bullet->is_bullet && bullet->has_hit)
|
||||||
{
|
{
|
||||||
// FIXME: Use actual velocity
|
// FIXME: Use actual velocity
|
||||||
P_Ent *old_bullet = P_EntFromKey(local_frame->prev, bullet->key);
|
P_Ent *old_bullet = P_EntFromKey(prev_local_frame, bullet->key);
|
||||||
Vec2 start = old_bullet->xf.t;
|
Vec2 start = old_bullet->xf.t;
|
||||||
Vec2 end = bullet->xf.t;
|
Vec2 end = bullet->xf.t;
|
||||||
if (P_IsEntNil(old_bullet))
|
if (P_IsEntNil(old_bullet))
|
||||||
@ -4166,10 +4268,10 @@ void V_TickForever(WaveLaneCtx *lane)
|
|||||||
UI_BuildLabelF("Predicted world entities: %F", FmtSint(predict_world->last_frame->ents_count));
|
UI_BuildLabelF("Predicted world entities: %F", FmtSint(predict_world->last_frame->ents_count));
|
||||||
UI_BuildLabelF("Predicted world constraints: %F", FmtSint(predict_world->last_frame->constraints_count));
|
UI_BuildLabelF("Predicted world constraints: %F", FmtSint(predict_world->last_frame->constraints_count));
|
||||||
UI_BuildSpacer(UI_PIX(padding, 1), Axis_Y);
|
UI_BuildSpacer(UI_PIX(padding, 1), Axis_Y);
|
||||||
UI_BuildLabelF("Local world seed: 0x%F", FmtHex(local_world->seed));
|
UI_BuildLabelF("Local world seed: 0x%F", FmtHex(frame->local_world->seed));
|
||||||
UI_BuildLabelF("Local world tick: %F", FmtSint(local_world->last_frame->tick));
|
UI_BuildLabelF("Local world tick: %F", FmtSint(frame->local_world->last_frame->tick));
|
||||||
UI_BuildLabelF("Local world entities: %F", FmtSint(local_world->last_frame->ents_count));
|
UI_BuildLabelF("Local world entities: %F", FmtSint(frame->local_world->last_frame->ents_count));
|
||||||
UI_BuildLabelF("Local world constraints: %F", FmtSint(local_world->last_frame->constraints_count));
|
UI_BuildLabelF("Local world constraints: %F", FmtSint(frame->local_world->last_frame->constraints_count));
|
||||||
}
|
}
|
||||||
UI_BuildSpacer(UI_PIX(padding, 1), Axis_Y);
|
UI_BuildSpacer(UI_PIX(padding, 1), Axis_Y);
|
||||||
{
|
{
|
||||||
@ -4795,7 +4897,7 @@ void V_TickForever(WaveLaneCtx *lane)
|
|||||||
G_CopyCpuToTexture(
|
G_CopyCpuToTexture(
|
||||||
frame->cl,
|
frame->cl,
|
||||||
gpu_tiles_res, VEC3I32(0, 0, 0),
|
gpu_tiles_res, VEC3I32(0, 0, 0),
|
||||||
local_world->tiles, VEC3I32(tiles_dims.x, tiles_dims.y, 1),
|
frame->local_world->tiles, VEC3I32(tiles_dims.x, tiles_dims.y, 1),
|
||||||
RNG3I32(VEC3I32(0, 0, 0), VEC3I32(tiles_dims.x, tiles_dims.y, 1))
|
RNG3I32(VEC3I32(0, 0, 0), VEC3I32(tiles_dims.x, tiles_dims.y, 1))
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@ -5175,6 +5277,7 @@ void V_TickForever(WaveLaneCtx *lane)
|
|||||||
G_CommitCommandList(frame->cl);
|
G_CommitCommandList(frame->cl);
|
||||||
|
|
||||||
i32 vsync = !!TweakBool("Vsync", 1);
|
i32 vsync = !!TweakBool("Vsync", 1);
|
||||||
|
vsync = 1;
|
||||||
UI_EndFrame(ui_frame, vsync);
|
UI_EndFrame(ui_frame, vsync);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -228,12 +228,16 @@ Struct(V_Frame)
|
|||||||
|
|
||||||
Embed(V_SharedFrame, shared_frame);
|
Embed(V_SharedFrame, shared_frame);
|
||||||
|
|
||||||
|
P_World *local_world;
|
||||||
RandState rand;
|
RandState rand;
|
||||||
|
|
||||||
NET_Key sim_key;
|
NET_Key sim_key;
|
||||||
NET_Key desired_sim_key;
|
NET_Key desired_sim_key;
|
||||||
f64 predict_tick_accum;
|
f64 predict_tick_accum;
|
||||||
|
|
||||||
|
i64 blend_from_tick;
|
||||||
|
i64 blend_to_tick;
|
||||||
|
|
||||||
Button held_buttons[Button_COUNT];
|
Button held_buttons[Button_COUNT];
|
||||||
V_Palette palette;
|
V_Palette palette;
|
||||||
|
|
||||||
@ -260,6 +264,9 @@ Struct(V_Ctx)
|
|||||||
|
|
||||||
i64 connect_try_ns;
|
i64 connect_try_ns;
|
||||||
|
|
||||||
|
i64 target_blend_time_ns;
|
||||||
|
i64 blend_time_ns;
|
||||||
|
|
||||||
// Notifications
|
// Notifications
|
||||||
V_Notif *first_notif;
|
V_Notif *first_notif;
|
||||||
V_Notif *last_notif;
|
V_Notif *last_notif;
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user