client -> server control snapshots
This commit is contained in:
parent
1c0009fb21
commit
746ef6913b
@ -442,7 +442,12 @@ D3D12_BARRIER_LAYOUT G_D12_BarrierLayoutFromLayout(G_Layout layout)
|
|||||||
[G_Layout_ComputeQueue_CopyRead] = D3D12_BARRIER_LAYOUT_COMPUTE_QUEUE_COPY_SOURCE,
|
[G_Layout_ComputeQueue_CopyRead] = D3D12_BARRIER_LAYOUT_COMPUTE_QUEUE_COPY_SOURCE,
|
||||||
[G_Layout_ComputeQueue_CopyWrite] = D3D12_BARRIER_LAYOUT_COMPUTE_QUEUE_COPY_DEST,
|
[G_Layout_ComputeQueue_CopyWrite] = D3D12_BARRIER_LAYOUT_COMPUTE_QUEUE_COPY_DEST,
|
||||||
};
|
};
|
||||||
return translate[layout];
|
D3D12_BARRIER_LAYOUT result = D3D12_BARRIER_LAYOUT_UNDEFINED;
|
||||||
|
if (layout >= 0 && layout < countof(translate))
|
||||||
|
{
|
||||||
|
result = translate[layout];
|
||||||
|
}
|
||||||
|
return result;
|
||||||
};
|
};
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
|
|||||||
@ -103,7 +103,6 @@ u32 NET_W32_ChecksumFromPacketString(String str)
|
|||||||
// Skip the first 4 bytes of packet since it contains the checksum itself
|
// Skip the first 4 bytes of packet since it contains the checksum itself
|
||||||
str.text += 4;
|
str.text += 4;
|
||||||
str.len -= 4;
|
str.len -= 4;
|
||||||
|
|
||||||
// https://en.wikipedia.org/wiki/Adler-32
|
// https://en.wikipedia.org/wiki/Adler-32
|
||||||
u32 a = 1;
|
u32 a = 1;
|
||||||
u32 b = 0;
|
u32 b = 0;
|
||||||
|
|||||||
58
src/pp/pp.c
58
src/pp/pp.c
@ -1464,54 +1464,80 @@ void P_StepFrame(P_Frame *frame)
|
|||||||
// }
|
// }
|
||||||
|
|
||||||
//////////////////////////////
|
//////////////////////////////
|
||||||
//- Integrate control forces
|
//- Update guy controls from player controls
|
||||||
|
|
||||||
for (P_Ent *ent = P_FirstEnt(frame); !P_IsEntNil(ent); ent = P_NextEnt(ent))
|
for (P_Ent *guy = P_FirstEnt(frame); !P_IsEntNil(guy); guy = P_NextEnt(guy))
|
||||||
{
|
{
|
||||||
// Xform xf = ent->xf;
|
if (guy->is_guy)
|
||||||
|
{
|
||||||
|
ZeroStruct(&guy->control);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (P_Ent *player = P_FirstEnt(frame); !P_IsEntNil(player); player = P_NextEnt(player))
|
||||||
|
{
|
||||||
|
if (player->is_player)
|
||||||
|
{
|
||||||
|
P_Ent *guy = P_EntFromKey(frame, player->guy);
|
||||||
|
if (!P_IsEntNil(guy))
|
||||||
|
{
|
||||||
|
guy->control = player->control;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//////////////////////////////
|
||||||
|
//- Integrate guy control forces
|
||||||
|
|
||||||
|
for (P_Ent *guy = P_FirstEnt(frame); !P_IsEntNil(guy); guy = P_NextEnt(guy))
|
||||||
|
{
|
||||||
|
if (guy->is_guy)
|
||||||
|
{
|
||||||
|
P_Control control = guy->control;
|
||||||
|
|
||||||
|
// Xform xf = guy->xf;
|
||||||
// Xform desired_xf = xf;
|
// Xform desired_xf = xf;
|
||||||
// if (!IsVec2Zero(ent->control.look))
|
// if (!IsVec2Zero(control.look))
|
||||||
// {
|
// {
|
||||||
// desired_xf = XformWithWorldRotation(xf, AngleFromVec2(ent->control.look));
|
// desired_xf = XformWithWorldRotation(xf, AngleFromVec2(control.look));
|
||||||
// }
|
// }
|
||||||
// f32 move_speed = TweakFloat("Guy move speed", 6.5, 0, 20);
|
// f32 move_speed = TweakFloat("Guy move speed", 6.5, 0, 20);
|
||||||
// desired_xf.og = AddVec2(xf.og, MulVec2(ent->control.move, move_speed * sim_dt));
|
// desired_xf.og = AddVec2(xf.og, MulVec2(control.move, move_speed * sim_dt));
|
||||||
|
|
||||||
// Vec2 pos_diff = SubVec2(desired_xf.og, xf.og);
|
// Vec2 pos_diff = SubVec2(desired_xf.og, xf.og);
|
||||||
// f32 angle_diff = UnwindAngleF32(RotationFromXform(desired_xf) - RotationFromXform(xf));
|
// f32 angle_diff = UnwindAngleF32(RotationFromXform(desired_xf) - RotationFromXform(xf));
|
||||||
|
|
||||||
// ent->solved_v = pos_diff;
|
// guy->solved_v = pos_diff;
|
||||||
// ent->solved_w = angle_diff;
|
// guy->solved_w = angle_diff;
|
||||||
|
|
||||||
{
|
{
|
||||||
// f32 damp_vel = damp_force * sim_dt;
|
// f32 damp_vel = damp_force * sim_dt;
|
||||||
|
|
||||||
if (Vec2Len(ent->solved_v) > 0.001)
|
if (Vec2Len(guy->solved_v) > 0.001)
|
||||||
{
|
{
|
||||||
f32 damp_force = TweakFloat("Guy damp force", 50, 0, 100);
|
f32 damp_force = TweakFloat("Guy damp force", 50, 0, 100);
|
||||||
Vec2 damp = MulVec2(NegVec2(ent->solved_v), damp_force * sim_dt);
|
Vec2 damp = MulVec2(NegVec2(guy->solved_v), damp_force * sim_dt);
|
||||||
ent->solved_v = AddVec2(ent->solved_v, damp);
|
guy->solved_v = AddVec2(guy->solved_v, damp);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
ent->solved_v = VEC2(0, 0);
|
guy->solved_v = VEC2(0, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
f32 move_force = TweakFloat("Guy move force", 400, 0, 400);
|
f32 move_force = TweakFloat("Guy move force", 400, 0, 400);
|
||||||
f32 max_speed = TweakFloat("Guy max speed", 10, 0, 20);
|
f32 max_speed = TweakFloat("Guy max speed", 10, 0, 20);
|
||||||
|
|
||||||
Vec2 new_velocity = ent->solved_v;
|
Vec2 new_velocity = guy->solved_v;
|
||||||
new_velocity = AddVec2(new_velocity, MulVec2(ent->control.move, move_force * sim_dt));
|
new_velocity = AddVec2(new_velocity, MulVec2(control.move, move_force * sim_dt));
|
||||||
|
|
||||||
// if (Vec2Len(new_velocity) > max_speed)
|
// if (Vec2Len(new_velocity) > max_speed)
|
||||||
// {
|
// {
|
||||||
// new_velocity = Vec2WithLen(new_velocity, max_speed);
|
// new_velocity = Vec2WithLen(new_velocity, max_speed);
|
||||||
// }
|
// }
|
||||||
|
|
||||||
ent->solved_v = new_velocity;
|
guy->solved_v = new_velocity;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
51
src/pp/pp.h
51
src/pp/pp.h
@ -74,6 +74,9 @@ Struct(P_DebugDrawNode)
|
|||||||
|
|
||||||
Struct(P_Control)
|
Struct(P_Control)
|
||||||
{
|
{
|
||||||
|
i64 tick;
|
||||||
|
i64 orig_tick; // Will differ from tick if this control was propagated from the control of another tick
|
||||||
|
|
||||||
Vec2 move;
|
Vec2 move;
|
||||||
Vec2 look;
|
Vec2 look;
|
||||||
f32 fire_held;
|
f32 fire_held;
|
||||||
@ -119,6 +122,8 @@ Struct(P_Ent)
|
|||||||
Vec2 hit_entry;
|
Vec2 hit_entry;
|
||||||
Vec2 hit_entry_normal;
|
Vec2 hit_entry_normal;
|
||||||
|
|
||||||
|
//- Player / Guy
|
||||||
|
|
||||||
P_Control control;
|
P_Control control;
|
||||||
|
|
||||||
//- Player
|
//- Player
|
||||||
@ -253,52 +258,6 @@ Struct(P_World)
|
|||||||
u8 *tiles;
|
u8 *tiles;
|
||||||
};
|
};
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////
|
|
||||||
//~ Sim snapshot types
|
|
||||||
|
|
||||||
Enum(P_SimDeltaKind)
|
|
||||||
{
|
|
||||||
P_SimDeltaKind_None,
|
|
||||||
P_SimDeltaKind_RawEnt,
|
|
||||||
};
|
|
||||||
|
|
||||||
Struct(P_SimDelta)
|
|
||||||
{
|
|
||||||
P_SimDeltaKind kind;
|
|
||||||
P_Ent ent;
|
|
||||||
};
|
|
||||||
|
|
||||||
Struct(P_SimDeltaNode)
|
|
||||||
{
|
|
||||||
P_SimDeltaNode *next;
|
|
||||||
P_SimDelta delta;
|
|
||||||
};
|
|
||||||
|
|
||||||
Struct(P_SimSnapshot)
|
|
||||||
{
|
|
||||||
u64 world_seed;
|
|
||||||
i64 src_tick;
|
|
||||||
i64 tick;
|
|
||||||
i64 time_ns;
|
|
||||||
|
|
||||||
i64 deltas_count;
|
|
||||||
P_SimDeltaNode *first_delta_node;
|
|
||||||
P_SimDeltaNode *last_delta_node;
|
|
||||||
};
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////
|
|
||||||
//~ Player snapshot types
|
|
||||||
|
|
||||||
Struct(P_PlayerSnapshot)
|
|
||||||
{
|
|
||||||
i64 tick;
|
|
||||||
|
|
||||||
Vec2 move;
|
|
||||||
Vec2 look;
|
|
||||||
b32 fire_held;
|
|
||||||
i32 fire_presses;
|
|
||||||
};
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
//~ Message types
|
//~ Message types
|
||||||
|
|
||||||
|
|||||||
@ -202,26 +202,35 @@ void S_TickForever(WaveLaneCtx *lane)
|
|||||||
if (S_IsClientNil(client))
|
if (S_IsClientNil(client))
|
||||||
{
|
{
|
||||||
String address_str = NET_StringFromKey(frame_arena, net_key);
|
String address_str = NET_StringFromKey(frame_arena, net_key);
|
||||||
u64 hash = NET_HashFromKey(net_key);
|
|
||||||
S_ClientBin *bin = &S.client_bins[hash % S.client_bins_count];
|
|
||||||
|
|
||||||
String orig_src_name = msg->data;
|
String orig_src_name = msg->data;
|
||||||
String src_name = TrimWhitespace(orig_src_name);
|
String src_name = TrimWhitespace(orig_src_name);
|
||||||
|
{
|
||||||
if (src_name.len < P_MinPlayerNameLen)
|
if (src_name.len < P_MinPlayerNameLen)
|
||||||
{
|
{
|
||||||
src_name = Lit("Player");
|
src_name = Lit("Player");
|
||||||
}
|
}
|
||||||
src_name.len = MinI64(src_name.len, P_MaxPlayerNameLen);
|
src_name.len = MinI64(src_name.len, P_MaxPlayerNameLen);
|
||||||
|
}
|
||||||
|
|
||||||
// FIXME: Freelist client
|
// FIXME: Freelist client
|
||||||
client = PushStruct(perm, S_Client);
|
client = PushStruct(perm, S_Client);
|
||||||
|
{
|
||||||
|
u64 hash = NET_HashFromKey(net_key);
|
||||||
|
S_ClientBin *bin = &S.client_bins[hash % S.client_bins_count];
|
||||||
|
|
||||||
client->hash = hash;
|
client->hash = hash;
|
||||||
client->net_key = net_key;
|
client->net_key = net_key;
|
||||||
client->name_len = MinI64(countof(client->name_text), src_name.len);
|
client->name_len = MinI64(countof(client->name_text), src_name.len);
|
||||||
CopyBytes(client->name_text, src_name.text, client->name_len);
|
CopyBytes(client->name_text, src_name.text, client->name_len);
|
||||||
|
|
||||||
|
client->max_controls = SIM_MAX_PING * SIM_TICKS_PER_SECOND;
|
||||||
|
client->controls = PushStructs(perm, P_Control, client->max_controls);
|
||||||
|
|
||||||
DllQueuePushNPZ(&S_NilClient, S.first_client, S.last_client, client, next, prev);
|
DllQueuePushNPZ(&S_NilClient, S.first_client, S.last_client, client, next, prev);
|
||||||
DllQueuePushNP(bin->first, bin->last, client, next_in_bin, prev_in_bin);
|
DllQueuePushNP(bin->first, bin->last, client, next_in_bin, prev_in_bin);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// Acknowledge player connection
|
// Acknowledge player connection
|
||||||
{
|
{
|
||||||
@ -258,15 +267,15 @@ void S_TickForever(WaveLaneCtx *lane)
|
|||||||
P_EntList new_players = Zi;
|
P_EntList new_players = Zi;
|
||||||
for (S_Client *client = S.first_client; !S_IsClientNil(client); client = client->next)
|
for (S_Client *client = S.first_client; !S_IsClientNil(client); client = client->next)
|
||||||
{
|
{
|
||||||
if (P_IsKeyNil(client->player_key))
|
if (P_IsKeyNil(client->player))
|
||||||
{
|
{
|
||||||
client->player_key = P_RandKey();
|
client->player = P_RandKey();
|
||||||
}
|
}
|
||||||
P_Ent *player = P_EntFromKey(world_frame, client->player_key);
|
P_Ent *player = P_EntFromKey(world_frame, client->player);
|
||||||
if (P_IsEntNil(player))
|
if (P_IsEntNil(player))
|
||||||
{
|
{
|
||||||
player = P_PushTempEnt(frame_arena, &new_players);
|
player = P_PushTempEnt(frame_arena, &new_players);
|
||||||
player->key = client->player_key;
|
player->key = client->player;
|
||||||
}
|
}
|
||||||
player->is_player = 1;
|
player->is_player = 1;
|
||||||
// Update name
|
// Update name
|
||||||
@ -307,6 +316,136 @@ void S_TickForever(WaveLaneCtx *lane)
|
|||||||
P_SpawnEntsFromList(world_frame, new_guys);
|
P_SpawnEntsFromList(world_frame, new_guys);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//////////////////////////////
|
||||||
|
//- Read client snapshots
|
||||||
|
|
||||||
|
for (P_MsgNode *msg_node = in_msgs.first; msg_node; msg_node = msg_node->next)
|
||||||
|
{
|
||||||
|
P_Msg *msg = &msg_node->msg;
|
||||||
|
if (msg->kind == P_MsgKind_Raw)
|
||||||
|
{
|
||||||
|
S_Client *client = S_ClientFromNetKey(msg->src);
|
||||||
|
if (!S_IsClientNil(client))
|
||||||
|
{
|
||||||
|
BB_Buff bb = BB_BuffFromString(msg->data);
|
||||||
|
BB_Reader bbr = BB_ReaderFromBuff(&bb);
|
||||||
|
|
||||||
|
//- Read header
|
||||||
|
BB_ReadBit(&bbr); // Raw
|
||||||
|
i64 remote_ack = BB_ReadIV(&bbr);
|
||||||
|
|
||||||
|
//- Read control
|
||||||
|
b32 done = 0;
|
||||||
|
while (!done)
|
||||||
|
{
|
||||||
|
// TODO: Delta compress
|
||||||
|
P_Control *raw_control = (P_Control *)BB_ReadBytesRaw(&bbr, sizeof(P_Control));
|
||||||
|
if (raw_control)
|
||||||
|
{
|
||||||
|
i64 control_tick = raw_control->tick;
|
||||||
|
P_Control *control = &client->controls[control_tick % client->max_controls];
|
||||||
|
{
|
||||||
|
*control = *raw_control;
|
||||||
|
}
|
||||||
|
|
||||||
|
//- Propagate control
|
||||||
|
//
|
||||||
|
// In case future snapshots aren't received, the last-received control should be used, so we copy this control forward here
|
||||||
|
//
|
||||||
|
// TODO: Not like this
|
||||||
|
i64 max_propagate_count = SIM_TICKS_PER_SECOND / 4;
|
||||||
|
{
|
||||||
|
// Propagate forwards
|
||||||
|
for (i64 prop_tick = control_tick; prop_tick < prop_tick + max_propagate_count; ++prop_tick)
|
||||||
|
{
|
||||||
|
P_Control *prop_control = &client->controls[prop_tick % client->max_controls];
|
||||||
|
if (prop_tick > prop_control->orig_tick)
|
||||||
|
{
|
||||||
|
*prop_control = *control;
|
||||||
|
prop_control->tick = prop_tick;
|
||||||
|
prop_control->orig_tick = control_tick;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Propagate backwards
|
||||||
|
for (i64 prop_tick = control_tick - 1; prop_tick > MaxI64(prop_tick - max_propagate_count, 0); --prop_tick)
|
||||||
|
{
|
||||||
|
P_Control *prop_control = &client->controls[prop_tick % client->max_controls];
|
||||||
|
if (prop_tick > prop_control->orig_tick)
|
||||||
|
{
|
||||||
|
*prop_control = *control;
|
||||||
|
prop_control->tick = prop_tick;
|
||||||
|
prop_control->orig_tick = control_tick;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//- Update ack
|
||||||
|
if (control->tick < world_frame->tick)
|
||||||
|
{
|
||||||
|
// If the control is outdated, go ahead and just ack it
|
||||||
|
if (control->tick > client->ack)
|
||||||
|
{
|
||||||
|
client->ack = control->tick;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Acknowledge the highest contiguously received control tick starting with the current frame
|
||||||
|
i64 max_ack_count = SIM_TICKS_PER_SECOND * SIM_MAX_PING;
|
||||||
|
i64 ack_tick = client->ack;
|
||||||
|
for (i64 check_ack_tick = world_frame->tick; check_ack_tick < world_frame->tick + max_ack_count; ++check_ack_tick)
|
||||||
|
{
|
||||||
|
P_Control *ack_control = &client->controls[check_ack_tick % client->max_controls];
|
||||||
|
if (ack_control->orig_tick == check_ack_tick)
|
||||||
|
{
|
||||||
|
ack_tick = check_ack_tick;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
client->ack = ack_tick;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
done = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//////////////////////////////
|
||||||
|
//- Apply client controls
|
||||||
|
|
||||||
|
for (S_Client *client = S.first_client; !S_IsClientNil(client); client = client->next)
|
||||||
|
{
|
||||||
|
P_Control *control = &client->controls[world_frame->tick % client->max_controls];
|
||||||
|
|
||||||
|
P_Ent *player = P_EntFromKey(world_frame, client->player);
|
||||||
|
if (!P_IsEntNil(player))
|
||||||
|
{
|
||||||
|
player->control = *control;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
//////////////////////////////
|
//////////////////////////////
|
||||||
//- Process connection messages
|
//- Process connection messages
|
||||||
|
|
||||||
@ -703,7 +842,7 @@ void S_TickForever(WaveLaneCtx *lane)
|
|||||||
BB_ResetWriter(&packer_bbw);
|
BB_ResetWriter(&packer_bbw);
|
||||||
u64 delta_start = BB_GetNumBytesWritten(&packer_bbw);
|
u64 delta_start = BB_GetNumBytesWritten(&packer_bbw);
|
||||||
{
|
{
|
||||||
// TODO: Compress
|
// TODO: Delta compress
|
||||||
should_transmit = 1;
|
should_transmit = 1;
|
||||||
BB_WriteBytes(&packer_bbw, StringFromStruct(ent));
|
BB_WriteBytes(&packer_bbw, StringFromStruct(ent));
|
||||||
}
|
}
|
||||||
@ -722,7 +861,7 @@ void S_TickForever(WaveLaneCtx *lane)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Collect deltas into snapshots
|
//- Collect & send snapshots
|
||||||
{
|
{
|
||||||
u64 max_snapshot_size = NET_PacketSize / 2;
|
u64 max_snapshot_size = NET_PacketSize / 2;
|
||||||
PackedDeltaNode *delta_node = first_delta_node;
|
PackedDeltaNode *delta_node = first_delta_node;
|
||||||
@ -745,7 +884,8 @@ void S_TickForever(WaveLaneCtx *lane)
|
|||||||
BB_WriteIV(&packer_bbw, world_frame->tick);
|
BB_WriteIV(&packer_bbw, world_frame->tick);
|
||||||
BB_WriteIV(&packer_bbw, world_frame->time_ns);
|
BB_WriteIV(&packer_bbw, world_frame->time_ns);
|
||||||
BB_WriteUBits(&packer_bbw, world->seed, 64);
|
BB_WriteUBits(&packer_bbw, world->seed, 64);
|
||||||
BB_WriteUBits(&packer_bbw, client->player_key.v, 64);
|
BB_WriteUBits(&packer_bbw, client->player.v, 64);
|
||||||
|
BB_WriteIV(&packer_bbw, client->ack);
|
||||||
}
|
}
|
||||||
|
|
||||||
//- Append packed delta
|
//- Append packed delta
|
||||||
|
|||||||
@ -12,11 +12,16 @@ Struct(S_Client)
|
|||||||
NET_Key net_key;
|
NET_Key net_key;
|
||||||
P_MsgList out_msgs;
|
P_MsgList out_msgs;
|
||||||
|
|
||||||
P_Key player_key;
|
P_Key player;
|
||||||
|
|
||||||
i32 name_len;
|
i32 name_len;
|
||||||
u8 name_text[P_MaxPlayerNameLen];
|
u8 name_text[P_MaxPlayerNameLen];
|
||||||
|
|
||||||
|
i64 max_controls;
|
||||||
|
P_Control *controls;
|
||||||
|
|
||||||
|
i64 ack;
|
||||||
|
|
||||||
u64 remote_tiles_hash;
|
u64 remote_tiles_hash;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@ -360,7 +360,15 @@ 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 *blend_world = P_AcquireWorld();
|
P_World *local_world = P_AcquireWorld();
|
||||||
|
|
||||||
|
i64 max_local_controls = SIM_MAX_PING * SIM_TICKS_PER_SECOND;
|
||||||
|
P_Control *local_controls = PushStructs(perm, P_Control, max_local_controls);
|
||||||
|
|
||||||
|
i64 known_sim_tick = 0;
|
||||||
|
i64 remote_ack_received_at_ns = 0;
|
||||||
|
i64 remote_ack = 0;
|
||||||
|
i64 prev_snapshot_sent_at_ns = 0;
|
||||||
|
|
||||||
Vec2I32 tiles_dims = VEC2I32(P_TilesPitch, P_TilesPitch);
|
Vec2I32 tiles_dims = VEC2I32(P_TilesPitch, P_TilesPitch);
|
||||||
Vec2I32 cells_dims = VEC2I32(V_CellsPerMeter * P_WorldPitch, V_CellsPerMeter * P_WorldPitch);
|
Vec2I32 cells_dims = VEC2I32(V_CellsPerMeter * P_WorldPitch, V_CellsPerMeter * P_WorldPitch);
|
||||||
@ -819,8 +827,8 @@ void V_TickForever(WaveLaneCtx *lane)
|
|||||||
Vec2 look_ratio = Zi;
|
Vec2 look_ratio = Zi;
|
||||||
look_ratio.y = 0.5;
|
look_ratio.y = 0.5;
|
||||||
look_ratio.x = look_ratio.y / (16.0 / 9.0);
|
look_ratio.x = look_ratio.y / (16.0 / 9.0);
|
||||||
P_Ent *player = P_EntFromKey(blend_world->last_frame, V.player_key);
|
P_Ent *player = P_EntFromKey(local_world->last_frame, V.player_key);
|
||||||
P_Ent *guy = P_EntFromKey(blend_world->last_frame, player->guy);
|
P_Ent *guy = P_EntFromKey(local_world->last_frame, player->guy);
|
||||||
Vec2 guy_center = P_WorldShapeFromEnt(guy).centroid;
|
Vec2 guy_center = P_WorldShapeFromEnt(guy).centroid;
|
||||||
Vec2 ui_center = MulVec2(frame->ui_dims, 0.5);
|
Vec2 ui_center = MulVec2(frame->ui_dims, 0.5);
|
||||||
Vec2 look = MulXformBasisV2(prev_frame->xf.ui_to_world, SubVec2(ui_frame->cursor_pos, ui_center));
|
Vec2 look = MulXformBasisV2(prev_frame->xf.ui_to_world, SubVec2(ui_frame->cursor_pos, ui_center));
|
||||||
@ -929,11 +937,6 @@ void V_TickForever(WaveLaneCtx *lane)
|
|||||||
frame->is_selecting = 1;
|
frame->is_selecting = 1;
|
||||||
// frame->equipped_tile = P_TileKind_Floor;
|
// frame->equipped_tile = P_TileKind_Floor;
|
||||||
}
|
}
|
||||||
else if (m2_held)
|
|
||||||
{
|
|
||||||
frame->is_selecting = 1;
|
|
||||||
// frame->equipped_tile = P_TileKind_Empty;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (frame->is_selecting && prev_frame->is_selecting)
|
if (frame->is_selecting && prev_frame->is_selecting)
|
||||||
{
|
{
|
||||||
@ -975,13 +978,13 @@ void V_TickForever(WaveLaneCtx *lane)
|
|||||||
//////////////////////////////
|
//////////////////////////////
|
||||||
//- Query entities
|
//- Query entities
|
||||||
|
|
||||||
P_Ent *local_player = P_EntFromKey(blend_world->last_frame, V.player_key);
|
P_Ent *local_player = P_EntFromKey(local_world->last_frame, V.player_key);
|
||||||
P_Ent *local_guy = P_EntFromKey(blend_world->last_frame, local_player->guy);
|
P_Ent *local_guy = P_EntFromKey(local_world->last_frame, local_player->guy);
|
||||||
P_Ent *hovered_ent = &P_NilEnt;
|
P_Ent *hovered_ent = &P_NilEnt;
|
||||||
{
|
{
|
||||||
// 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(blend_world->last_frame); !P_IsEntNil(ent); ent = P_NextEnt(ent))
|
for (P_Ent *ent = P_FirstEnt(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;
|
||||||
@ -2320,9 +2323,9 @@ void V_TickForever(WaveLaneCtx *lane)
|
|||||||
UI_BuildLabelF("Predicted world tick: %F", FmtSint(predict_world->last_frame->tick));
|
UI_BuildLabelF("Predicted world tick: %F", FmtSint(predict_world->last_frame->tick));
|
||||||
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_BuildSpacer(UI_PIX(padding, 1), Axis_Y);
|
UI_BuildSpacer(UI_PIX(padding, 1), Axis_Y);
|
||||||
UI_BuildLabelF("Blended world seed: 0x%F", FmtHex(blend_world->seed));
|
UI_BuildLabelF("Local world seed: 0x%F", FmtHex(local_world->seed));
|
||||||
UI_BuildLabelF("Blended world tick: %F", FmtSint(blend_world->last_frame->tick));
|
UI_BuildLabelF("Local world tick: %F", FmtSint(local_world->last_frame->tick));
|
||||||
UI_BuildLabelF("Blended world entities: %F", FmtSint(blend_world->last_frame->ents_count));
|
UI_BuildLabelF("Local world entities: %F", FmtSint(local_world->last_frame->ents_count));
|
||||||
}
|
}
|
||||||
UI_BuildSpacer(UI_PIX(padding, 1), Axis_Y);
|
UI_BuildSpacer(UI_PIX(padding, 1), Axis_Y);
|
||||||
{
|
{
|
||||||
@ -2703,21 +2706,19 @@ void V_TickForever(WaveLaneCtx *lane)
|
|||||||
frame->desired_sim_key = NET_KeyFromString(Lit("127.0.0.1"), Lit("22121"));
|
frame->desired_sim_key = NET_KeyFromString(Lit("127.0.0.1"), Lit("22121"));
|
||||||
if (!NET_MatchKey(frame->sim_key, frame->desired_sim_key))
|
if (!NET_MatchKey(frame->sim_key, frame->desired_sim_key))
|
||||||
{
|
{
|
||||||
i64 now_ns = TimeNs();
|
i64 retry_rate_ns = NsFromSeconds(0.100);
|
||||||
// i64 retry_rate_ns = NsFromSeconds(0.100);
|
// i64 retry_rate_ns = NsFromSeconds(0);
|
||||||
i64 retry_rate_ns = NsFromSeconds(0);
|
|
||||||
|
|
||||||
b32 should_try = 0;
|
b32 should_try = 0;
|
||||||
if (!NET_MatchKey(prev_frame->desired_sim_key, frame->desired_sim_key))
|
if (!NET_MatchKey(prev_frame->desired_sim_key, frame->desired_sim_key))
|
||||||
{
|
{
|
||||||
should_try = 1;
|
should_try = 1;
|
||||||
}
|
}
|
||||||
if (V.connect_try_ns == 0 || now_ns - V.connect_try_ns > retry_rate_ns)
|
if (V.connect_try_ns == 0 || frame->time_ns - V.connect_try_ns > retry_rate_ns)
|
||||||
{
|
{
|
||||||
should_try = 1;
|
should_try = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
// if (should_try && now_ns > NsFromSeconds(1.5))
|
|
||||||
if (should_try)
|
if (should_try)
|
||||||
{
|
{
|
||||||
P_MsgNode tmp_msg_node = Zi;
|
P_MsgNode tmp_msg_node = Zi;
|
||||||
@ -2733,7 +2734,7 @@ void V_TickForever(WaveLaneCtx *lane)
|
|||||||
String packed = P_PackMessages(&packer_bbw, tmp_msglist);
|
String packed = P_PackMessages(&packer_bbw, tmp_msglist);
|
||||||
|
|
||||||
NET_Send(net_pipe, frame->desired_sim_key, packed, NET_SendFlag_Raw);
|
NET_Send(net_pipe, frame->desired_sim_key, packed, NET_SendFlag_Raw);
|
||||||
V.connect_try_ns = now_ns;
|
V.connect_try_ns = frame->time_ns;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2793,9 +2794,6 @@ void V_TickForever(WaveLaneCtx *lane)
|
|||||||
for (P_MsgNode *msg_node = in_msgs.first; msg_node; msg_node = msg_node->next)
|
for (P_MsgNode *msg_node = in_msgs.first; msg_node; msg_node = msg_node->next)
|
||||||
{
|
{
|
||||||
P_Msg *msg = &msg_node->msg;
|
P_Msg *msg = &msg_node->msg;
|
||||||
|
|
||||||
|
|
||||||
//- Snapshot
|
|
||||||
if (msg->kind == P_MsgKind_Raw)
|
if (msg->kind == P_MsgKind_Raw)
|
||||||
{
|
{
|
||||||
BB_Buff bb = BB_BuffFromString(msg->data);
|
BB_Buff bb = BB_BuffFromString(msg->data);
|
||||||
@ -2808,6 +2806,14 @@ void V_TickForever(WaveLaneCtx *lane)
|
|||||||
i64 time_ns = BB_ReadIV(&bbr);
|
i64 time_ns = BB_ReadIV(&bbr);
|
||||||
u64 world_seed = BB_ReadUBits(&bbr, 64);
|
u64 world_seed = BB_ReadUBits(&bbr, 64);
|
||||||
P_Key player_key = { .v = BB_ReadUBits(&bbr, 64) };
|
P_Key player_key = { .v = BB_ReadUBits(&bbr, 64) };
|
||||||
|
i64 tmp_remote_ack = BB_ReadIV(&bbr);
|
||||||
|
|
||||||
|
if (dst_tick > known_sim_tick)
|
||||||
|
{
|
||||||
|
known_sim_tick = dst_tick;
|
||||||
|
remote_ack_received_at_ns = frame->time_ns;
|
||||||
|
remote_ack = tmp_remote_ack;
|
||||||
|
}
|
||||||
|
|
||||||
P_Frame *src_frame = P_FrameFromTick(sim_world, src_tick);
|
P_Frame *src_frame = P_FrameFromTick(sim_world, src_tick);
|
||||||
if (src_frame->tick == src_tick)
|
if (src_frame->tick == src_tick)
|
||||||
@ -2828,11 +2834,12 @@ void V_TickForever(WaveLaneCtx *lane)
|
|||||||
b32 done = 0;
|
b32 done = 0;
|
||||||
while (!done && BB_NumBitsRemaining(&bbr) > 0)
|
while (!done && BB_NumBitsRemaining(&bbr) > 0)
|
||||||
{
|
{
|
||||||
P_Ent *src_ent = (P_Ent *)BB_ReadBytesRaw(&bbr, sizeof(P_Ent));
|
// TODO: Delta compress
|
||||||
if (src_ent)
|
P_Ent *raw_ent = (P_Ent *)BB_ReadBytesRaw(&bbr, sizeof(P_Ent));
|
||||||
|
if (raw_ent)
|
||||||
{
|
{
|
||||||
P_EntListNode tmp_ent_node = Zi;
|
P_EntListNode tmp_ent_node = Zi;
|
||||||
CopyStruct(&tmp_ent_node.ent, src_ent);
|
CopyStruct(&tmp_ent_node.ent, raw_ent);
|
||||||
P_EntList ent_list = Zi;
|
P_EntList ent_list = Zi;
|
||||||
ent_list.first = &tmp_ent_node;
|
ent_list.first = &tmp_ent_node;
|
||||||
ent_list.last = &tmp_ent_node;
|
ent_list.last = &tmp_ent_node;
|
||||||
@ -2933,14 +2940,168 @@ void V_TickForever(WaveLaneCtx *lane)
|
|||||||
}
|
}
|
||||||
|
|
||||||
//////////////////////////////
|
//////////////////////////////
|
||||||
//- Push player snapshots
|
//- Determine local simulation bounds
|
||||||
|
|
||||||
// FIXME: Real ping
|
// FIXME: Real ping
|
||||||
// f64 ping = 0.250;
|
// f64 ping = 0.250;
|
||||||
f64 ping = 0;
|
f64 ping = 0;
|
||||||
i64 ping_ns = NsFromSeconds(ping);
|
i64 ping_ns = NsFromSeconds(ping);
|
||||||
|
|
||||||
frame->predict_to = sim_world->last_frame->tick + MaxF64(CeilF64(ping * SIM_TICKS_PER_SECOND), 1.0);
|
// frame->predict_to = sim_world->last_frame->tick + MaxF64(CeilF64(ping * SIM_TICKS_PER_SECOND), 1.0);
|
||||||
|
|
||||||
|
frame->predict_to = known_sim_tick + 10;
|
||||||
|
|
||||||
|
//////////////////////////////
|
||||||
|
//- Create player control
|
||||||
|
|
||||||
|
if (frame->predict_to > prev_frame->predict_to)
|
||||||
|
{
|
||||||
|
i64 control_tick = frame->predict_to;
|
||||||
|
|
||||||
|
P_Control control = Zi;
|
||||||
|
control.tick = control_tick;
|
||||||
|
control.orig_tick = control_tick;
|
||||||
|
control.move = frame->move;
|
||||||
|
control.look = frame->look;
|
||||||
|
control.fire_held = frame->fire_held;
|
||||||
|
control.fire_presses = frame->fire_presses;
|
||||||
|
|
||||||
|
//- Fill controls buffer backwards
|
||||||
|
i64 max_fill_count = SIM_TICKS_PER_SECOND / 4;
|
||||||
|
for (i64 dst_tick = control_tick; dst_tick > MaxI64(prev_frame->predict_to, (dst_tick - max_local_controls)); --dst_tick)
|
||||||
|
{
|
||||||
|
P_Control *dst_control = &local_controls[dst_tick % max_local_controls];
|
||||||
|
if (dst_tick > dst_control->orig_tick)
|
||||||
|
{
|
||||||
|
*dst_control = control;
|
||||||
|
dst_control->tick = dst_tick;
|
||||||
|
dst_control->orig_tick = control_tick;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//////////////////////////////
|
||||||
|
//- Send player snapshots
|
||||||
|
|
||||||
|
{
|
||||||
|
i64 snapshot_send_threshold_ns = NsFromSeconds(1.0) / SIM_TICKS_PER_SECOND;
|
||||||
|
if (prev_snapshot_sent_at_ns == 0 || (frame->time_ns - prev_snapshot_sent_at_ns) > snapshot_send_threshold_ns)
|
||||||
|
{
|
||||||
|
// FIXME: Base this on ping
|
||||||
|
i64 max_control_sends = SIM_TICKS_PER_SECOND;
|
||||||
|
|
||||||
|
//- Pack control deltas
|
||||||
|
Struct(PackedDeltaNode)
|
||||||
|
{
|
||||||
|
PackedDeltaNode *next;
|
||||||
|
String packed;
|
||||||
|
};
|
||||||
|
i64 total_delta_bytes = 0;
|
||||||
|
PackedDeltaNode *first_delta_node = 0;
|
||||||
|
PackedDeltaNode *last_delta_node = 0;
|
||||||
|
if (frame->predict_to >= known_sim_tick)
|
||||||
|
{
|
||||||
|
i64 last_send_tick = frame->predict_to;
|
||||||
|
i64 first_send_tick = MaxI64(known_sim_tick, remote_ack + 1);
|
||||||
|
first_send_tick = MaxI64(first_send_tick, last_send_tick - max_control_sends);
|
||||||
|
for (i64 send_tick = first_send_tick; send_tick <= last_send_tick; ++send_tick)
|
||||||
|
{
|
||||||
|
b32 should_transmit = 0;
|
||||||
|
BB_ResetWriter(&packer_bbw);
|
||||||
|
u64 delta_start = BB_GetNumBytesWritten(&packer_bbw);
|
||||||
|
{
|
||||||
|
// TODO: Delta compress
|
||||||
|
should_transmit = 1;
|
||||||
|
P_Control *control = &local_controls[send_tick % max_local_controls];
|
||||||
|
BB_WriteBytes(&packer_bbw, StringFromStruct(control));
|
||||||
|
}
|
||||||
|
u64 delta_end = BB_GetNumBytesWritten(&packer_bbw);
|
||||||
|
if (should_transmit)
|
||||||
|
{
|
||||||
|
String packed = Zi;
|
||||||
|
packed.text = BB_GetWrittenRaw(&packer_bbw) + delta_start;
|
||||||
|
packed.len = delta_end - delta_start;
|
||||||
|
{
|
||||||
|
PackedDeltaNode *delta_node = PushStruct(frame->arena, PackedDeltaNode);
|
||||||
|
delta_node->packed = PushString(frame->arena, packed);
|
||||||
|
SllQueuePush(first_delta_node, last_delta_node, delta_node);
|
||||||
|
total_delta_bytes += packed.len;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//- Collect & send snapshots
|
||||||
|
{
|
||||||
|
u64 max_snapshot_size = NET_PacketSize / 2;
|
||||||
|
PackedDeltaNode *delta_node = first_delta_node;
|
||||||
|
|
||||||
|
u64 snapshot_start = 0;
|
||||||
|
b32 new_snapshot = 1;
|
||||||
|
b32 done = 0;
|
||||||
|
while (!done)
|
||||||
|
{
|
||||||
|
PackedDeltaNode *next_delta_node = delta_node ? delta_node->next : 0;
|
||||||
|
{
|
||||||
|
//- Init snapshot
|
||||||
|
if (new_snapshot)
|
||||||
|
{
|
||||||
|
new_snapshot = 0;
|
||||||
|
BB_ResetWriter(&packer_bbw);
|
||||||
|
snapshot_start = BB_GetNumBytesWritten(&packer_bbw);
|
||||||
|
BB_WriteBit(&packer_bbw, 1); // Raw
|
||||||
|
BB_WriteIV(&packer_bbw, known_sim_tick);
|
||||||
|
}
|
||||||
|
|
||||||
|
//- Append packed delta
|
||||||
|
BB_WriteAlignToNextByte(&packer_bbw);
|
||||||
|
if (delta_node)
|
||||||
|
{
|
||||||
|
BB_WriteBytes(&packer_bbw, delta_node->packed);
|
||||||
|
}
|
||||||
|
|
||||||
|
//- Submit snapshot
|
||||||
|
{
|
||||||
|
if (!delta_node || !next_delta_node)
|
||||||
|
{
|
||||||
|
new_snapshot = 1;
|
||||||
|
done = 1;
|
||||||
|
}
|
||||||
|
u64 next_len = 0;
|
||||||
|
if (next_delta_node)
|
||||||
|
{
|
||||||
|
next_len = next_delta_node->packed.len;
|
||||||
|
}
|
||||||
|
u64 cur_snapshot_len = BB_GetNumBytesWritten(&packer_bbw);
|
||||||
|
if ((cur_snapshot_len - snapshot_start) + next_len >= max_snapshot_size)
|
||||||
|
{
|
||||||
|
new_snapshot = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (new_snapshot)
|
||||||
|
{
|
||||||
|
u64 snapshot_end = BB_GetNumBytesWritten(&packer_bbw);
|
||||||
|
String snapshot = Zi;
|
||||||
|
snapshot.text = BB_GetWrittenRaw(&packer_bbw) + snapshot_start;
|
||||||
|
snapshot.len = snapshot_end - snapshot_start;
|
||||||
|
|
||||||
|
// FIXME: Send raw snapshots
|
||||||
|
// NET_Send(net_pipe, frame->sim_key, snapshot, NET_SendFlag_Raw);
|
||||||
|
NET_Send(net_pipe, frame->sim_key, snapshot, NET_SendFlag_None);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
delta_node = next_delta_node;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
prev_snapshot_sent_at_ns = frame->time_ns;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// if (frame->predict_to != prev_frame->predict_to)
|
// if (frame->predict_to != prev_frame->predict_to)
|
||||||
// {
|
// {
|
||||||
// {
|
// {
|
||||||
@ -3031,21 +3192,21 @@ void V_TickForever(WaveLaneCtx *lane)
|
|||||||
|
|
||||||
|
|
||||||
//////////////////////////////
|
//////////////////////////////
|
||||||
//- Update blended world
|
//- Update local world
|
||||||
|
|
||||||
// TODO: Remove this
|
// TODO: Remove this
|
||||||
P_Frame *blend_frame = &P_NilFrame;
|
P_Frame *local_frame = &P_NilFrame;
|
||||||
{
|
{
|
||||||
if (blend_world->tiles_hash != predict_world->tiles_hash)
|
if (local_world->tiles_hash != predict_world->tiles_hash)
|
||||||
{
|
{
|
||||||
blend_world->tiles_hash = predict_world->tiles_hash;
|
local_world->tiles_hash = predict_world->tiles_hash;
|
||||||
CopyStructs(blend_world->tiles, predict_world->tiles, P_TilesCount);
|
CopyStructs(local_world->tiles, predict_world->tiles, P_TilesCount);
|
||||||
tiles_dirty = 1;
|
tiles_dirty = 1;
|
||||||
}
|
}
|
||||||
blend_world->seed = predict_world->seed;
|
local_world->seed = predict_world->seed;
|
||||||
|
|
||||||
P_ClearFrames(blend_world, I64Min, I64Max);
|
P_ClearFrames(local_world, I64Min, I64Max);
|
||||||
blend_frame = P_PushFrame(blend_world, predict_world->last_frame, predict_world->last_frame->tick);
|
local_frame = P_PushFrame(local_world, predict_world->last_frame, predict_world->last_frame->tick);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -3087,7 +3248,7 @@ void V_TickForever(WaveLaneCtx *lane)
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
for (P_Ent *bullet = P_FirstEnt(blend_frame); !P_IsEntNil(bullet); bullet = P_NextEnt(bullet))
|
for (P_Ent *bullet = P_FirstEnt(local_frame); !P_IsEntNil(bullet); bullet = P_NextEnt(bullet))
|
||||||
{
|
{
|
||||||
if (bullet->is_bullet)
|
if (bullet->is_bullet)
|
||||||
{
|
{
|
||||||
@ -3267,7 +3428,7 @@ void V_TickForever(WaveLaneCtx *lane)
|
|||||||
|
|
||||||
if (0)
|
if (0)
|
||||||
{
|
{
|
||||||
for (P_Ent *bullet = P_FirstEnt(blend_frame); !P_IsEntNil(bullet); bullet = P_NextEnt(bullet))
|
for (P_Ent *bullet = P_FirstEnt(local_frame); !P_IsEntNil(bullet); bullet = P_NextEnt(bullet))
|
||||||
{
|
{
|
||||||
if (bullet->is_bullet && bullet->has_hit)
|
if (bullet->is_bullet && bullet->has_hit)
|
||||||
{
|
{
|
||||||
@ -3344,7 +3505,7 @@ void V_TickForever(WaveLaneCtx *lane)
|
|||||||
|
|
||||||
|
|
||||||
// {
|
// {
|
||||||
// for (P_Ent *firer = P_FirstEnt(blend_frame); firer->valid; firer = P_NextEnt(firer))
|
// for (P_Ent *firer = P_FirstEnt(local_frame); firer->valid; firer = P_NextEnt(firer))
|
||||||
// {
|
// {
|
||||||
// if (firer->fire_held)
|
// if (firer->fire_held)
|
||||||
// {
|
// {
|
||||||
@ -3359,7 +3520,7 @@ void V_TickForever(WaveLaneCtx *lane)
|
|||||||
// P_RaycastResult victim_raycast = Zi;
|
// P_RaycastResult victim_raycast = Zi;
|
||||||
// {
|
// {
|
||||||
// f32 closest_len_sq = Inf;
|
// f32 closest_len_sq = Inf;
|
||||||
// for (P_Ent *victim = P_FirstEnt(blend_frame); victim->valid; victim = P_NextEnt(victim))
|
// for (P_Ent *victim = P_FirstEnt(local_frame); victim->valid; victim = P_NextEnt(victim))
|
||||||
// {
|
// {
|
||||||
// if (victim != firer)
|
// if (victim != firer)
|
||||||
// {
|
// {
|
||||||
@ -3430,7 +3591,7 @@ void V_TickForever(WaveLaneCtx *lane)
|
|||||||
|
|
||||||
|
|
||||||
// // for (P_QueryResult query = P_FirstRaycast(wrold, ray_start, ray_dir); query.
|
// // for (P_QueryResult query = P_FirstRaycast(wrold, ray_start, ray_dir); query.
|
||||||
// // P_RaycastWorldResult hits = P_RaycastWorld(blend_frame, ray_start, ray_dir)
|
// // P_RaycastWorldResult hits = P_RaycastWorld(local_frame, ray_start, ray_dir)
|
||||||
// // {
|
// // {
|
||||||
// // }
|
// // }
|
||||||
// }
|
// }
|
||||||
@ -3639,7 +3800,7 @@ void V_TickForever(WaveLaneCtx *lane)
|
|||||||
G_CopyCpuToTexture(
|
G_CopyCpuToTexture(
|
||||||
frame->cl,
|
frame->cl,
|
||||||
gpu_tiles, VEC3I32(0, 0, 0),
|
gpu_tiles, VEC3I32(0, 0, 0),
|
||||||
blend_world->tiles, VEC3I32(tiles_dims.x, tiles_dims.y, 1),
|
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))
|
||||||
);
|
);
|
||||||
G_DumbMemoryLayoutSync(frame->cl, gpu_tiles, G_Layout_DirectQueue_ShaderRead);
|
G_DumbMemoryLayoutSync(frame->cl, gpu_tiles, G_Layout_DirectQueue_ShaderRead);
|
||||||
|
|||||||
@ -63,7 +63,7 @@ ComputeShader(V_ClearParticlesCS, 64)
|
|||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
//~ Backdrop shader
|
//~ Backdrop shaders
|
||||||
|
|
||||||
ComputeShader2D(V_BackdropCS, 8, 8)
|
ComputeShader2D(V_BackdropCS, 8, 8)
|
||||||
{
|
{
|
||||||
@ -270,7 +270,7 @@ ComputeShader2D(V_BackdropCS, 8, 8)
|
|||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
//~ Quad shader
|
//~ Quad shaders
|
||||||
|
|
||||||
//////////////////////////////
|
//////////////////////////////
|
||||||
//- Vertex shader
|
//- Vertex shader
|
||||||
@ -461,7 +461,7 @@ ComputeShader(V_SimParticlesCS, 64)
|
|||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
//~ Shape shader
|
//~ Shape shaders
|
||||||
|
|
||||||
//////////////////////////////
|
//////////////////////////////
|
||||||
//- Vertex shader
|
//- Vertex shader
|
||||||
@ -493,7 +493,7 @@ PixelShader(V_DVertPS, V_DVertPSOutput, V_DVertPSInput input)
|
|||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
//~ Overlay shader
|
//~ Overlay shaders
|
||||||
|
|
||||||
//////////////////////////////
|
//////////////////////////////
|
||||||
//- Vertex shader
|
//- Vertex shader
|
||||||
|
|||||||
@ -53,10 +53,10 @@ Vec4 V_DryColor(Vec4 color, f32 dryness);
|
|||||||
ComputeShader2D(V_ClearCellsCS, 8, 8);
|
ComputeShader2D(V_ClearCellsCS, 8, 8);
|
||||||
ComputeShader(V_ClearParticlesCS, 64);
|
ComputeShader(V_ClearParticlesCS, 64);
|
||||||
|
|
||||||
//- Backdrop shader
|
//- Backdrop shaders
|
||||||
ComputeShader2D(V_BackdropCS, 8, 8);
|
ComputeShader2D(V_BackdropCS, 8, 8);
|
||||||
|
|
||||||
//- Quad shader
|
//- Quad shaders
|
||||||
VertexShader(V_DQuadVS, V_DQuadPSInput);
|
VertexShader(V_DQuadVS, V_DQuadPSInput);
|
||||||
PixelShader(V_DQuadPS, V_DQuadPSOutput, V_DQuadPSInput input);
|
PixelShader(V_DQuadPS, V_DQuadPSOutput, V_DQuadPSInput input);
|
||||||
|
|
||||||
@ -64,10 +64,10 @@ PixelShader(V_DQuadPS, V_DQuadPSOutput, V_DQuadPSInput input);
|
|||||||
ComputeShader(V_EmitParticlesCS, 64);
|
ComputeShader(V_EmitParticlesCS, 64);
|
||||||
ComputeShader(V_SimParticlesCS, 64);
|
ComputeShader(V_SimParticlesCS, 64);
|
||||||
|
|
||||||
//- Shape shader
|
//- Shape shaders
|
||||||
VertexShader(V_DVertVS, V_DVertPSInput);
|
VertexShader(V_DVertVS, V_DVertPSInput);
|
||||||
PixelShader(V_DVertPS, V_DVertPSOutput, V_DVertPSInput input);
|
PixelShader(V_DVertPS, V_DVertPSOutput, V_DVertPSInput input);
|
||||||
|
|
||||||
//- Overlay shader
|
//- Overlay shaders
|
||||||
VertexShader(V_OverlayVS, V_OverlayPSInput);
|
VertexShader(V_OverlayVS, V_OverlayPSInput);
|
||||||
PixelShader(V_OverlayPS, V_OverlayPSOutput, V_OverlayPSInput input);
|
PixelShader(V_OverlayPS, V_OverlayPSOutput, V_OverlayPSInput input);
|
||||||
|
|||||||
@ -1,5 +1,5 @@
|
|||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
//~ Rect shader
|
//~ Rect shaders
|
||||||
|
|
||||||
//////////////////////////////
|
//////////////////////////////
|
||||||
//- Vertex shader
|
//- Vertex shader
|
||||||
@ -115,7 +115,7 @@ PixelShader(UI_DRectPS, UI_DRectPSOutput, UI_DRectPSInput input)
|
|||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
//~ Blit shader
|
//~ Blit shaders
|
||||||
|
|
||||||
//////////////////////////////
|
//////////////////////////////
|
||||||
//- Vertex shader
|
//- Vertex shader
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user