user layer refactor progress

This commit is contained in:
jacob 2025-08-01 00:50:41 -05:00
parent f1776dedaf
commit d93bed029e
13 changed files with 897 additions and 692 deletions

View File

@ -37,7 +37,7 @@ Global struct {
ClientStore *nil_client_store;
Client *nil_client;
Snapshot *nil_snapshot;
Ent *nil_ent;
Entity *nil_ent;
} G = ZI, DebugAlias(G, G_sim);
/* Accessed via `sim_client_store_nil()` */
@ -50,7 +50,7 @@ Readonly Client **_g_sim_client_nil = &G.nil_client;
Readonly Snapshot **_g_sim_snapshot_nil = &G.nil_snapshot;
/* Accessed via `sim_ent_nil()` */
Readonly Ent **_g_sim_ent_nil = &G.nil_ent;
Readonly Entity **_g_sim_ent_nil = &G.nil_ent;
SimStartupReceipt sim_startup(void)
{
@ -72,7 +72,7 @@ SimStartupReceipt sim_startup(void)
G.nil_snapshot->client = sim_client_nil();
/* Nil ent */
G.nil_ent = PushStruct(G.nil_arena, Ent);
G.nil_ent = PushStruct(G.nil_arena, Entity);
G.nil_ent->ss = sim_snapshot_nil();
G.nil_ent->valid = 0;
G.nil_ent->id = SIM_ENT_NIL_ID;
@ -325,20 +325,20 @@ Snapshot *sim_snapshot_alloc(Client *client, Snapshot *src, u64 tick)
ss->first_free_ent = src->first_free_ent;
ss->num_ents_allocated = src->num_ents_allocated;
ss->num_ents_reserved = src->num_ents_reserved;
ss->ents = PushStructsNoZero(ss->ents_arena, Ent, ss->num_ents_reserved);
ss->ents = PushStructsNoZero(ss->ents_arena, Entity, ss->num_ents_reserved);
if (ss->num_ents_reserved == 0) {
/* Copying from nil snapshot, need to create blank & root entity */
/* PushStruct blank ent at index 0 (because index 0 is never valid anyway since it maps to sim_ent_nil()) */
{
PushStruct(ss->ents_arena, Ent);
PushStruct(ss->ents_arena, Entity);
++ss->num_ents_allocated;
++ss->num_ents_reserved;
}
/* PushStruct root ent with constant id */
{
Ent *root = PushStructNoZero(ss->ents_arena, Ent);
Entity *root = PushStructNoZero(ss->ents_arena, Entity);
*root = *sim_ent_nil();
root->ss = ss;
root->valid = 1;
@ -351,8 +351,8 @@ Snapshot *sim_snapshot_alloc(Client *client, Snapshot *src, u64 tick)
}
} else {
for (u64 i = 0; i < ss->num_ents_reserved; ++i) {
Ent *dst_ent = &ss->ents[i];
Ent *src_ent = &src->ents[i];
Entity *dst_ent = &ss->ents[i];
Entity *src_ent = &src->ents[i];
*dst_ent = *src_ent;
dst_ent->ss = ss;
}
@ -593,10 +593,10 @@ void sim_snapshot_set_tile(Snapshot *ss, Vec2I32 world_tile_index, TileKind tile
{
Vec2I32 chunk_index = sim_tile_chunk_index_from_world_tile_index(world_tile_index);
EntId chunk_id = sim_ent_tile_chunk_id_from_tile_chunk_index(chunk_index);
Ent *chunk_ent = sim_ent_from_id(ss, chunk_id);
EntityId chunk_id = sim_ent_tile_chunk_id_from_tile_chunk_index(chunk_index);
Entity *chunk_ent = sim_ent_from_id(ss, chunk_id);
if (!chunk_ent->valid) {
Ent *root = sim_ent_from_id(ss, SIM_ENT_ROOT_ID);
Entity *root = sim_ent_from_id(ss, SIM_ENT_ROOT_ID);
chunk_ent = sim_ent_alloc_sync_src_with_id(root, chunk_id);
sim_ent_enable_prop(chunk_ent, SEPROP_TILE_CHUNK);
chunk_ent->tile_chunk_index = chunk_index;
@ -645,9 +645,9 @@ Snapshot *sim_snapshot_alloc_from_lerp(Client *client, Snapshot *ss0, Snapshot *
__profn("Lerp snapshot entities");
u64 num_entities = MinU64(ss0->num_ents_reserved, ss1->num_ents_reserved);
for (u64 i = 0; i < num_entities; ++i) {
Ent *e = &ss->ents[i];
Ent *e0 = &ss0->ents[i];
Ent *e1 = &ss1->ents[i];
Entity *e = &ss->ents[i];
Entity *e0 = &ss0->ents[i];
Entity *e1 = &ss1->ents[i];
sim_ent_lerp(e, e0, e1, blend);
}
}
@ -661,7 +661,7 @@ Snapshot *sim_snapshot_alloc_from_lerp(Client *client, Snapshot *ss0, Snapshot *
* ========================== */
/* Syncs entity data between snapshots */
void sim_snapshot_sync_ents(Snapshot *local_ss, Snapshot *remote_ss, EntId remote_player, u32 sync_flags)
void sim_snapshot_sync_ents(Snapshot *local_ss, Snapshot *remote_ss, EntityId remote_player, u32 sync_flags)
{
__prof;
@ -670,24 +670,24 @@ void sim_snapshot_sync_ents(Snapshot *local_ss, Snapshot *remote_ss, EntId remot
* - Determine new UUids for newly created ents
*/
Ent *local_root = sim_ent_from_id(local_ss, SIM_ENT_ROOT_ID);
Ent *remote_root = sim_ent_from_id(remote_ss, SIM_ENT_ROOT_ID);
Entity *local_root = sim_ent_from_id(local_ss, SIM_ENT_ROOT_ID);
Entity *remote_root = sim_ent_from_id(remote_ss, SIM_ENT_ROOT_ID);
/* Create new ents from remote */
for (Ent *remote_top = sim_ent_from_id(remote_ss, remote_root->first); remote_top->valid; remote_top = sim_ent_from_id(remote_ss, remote_top->next)) {
for (Entity *remote_top = sim_ent_from_id(remote_ss, remote_root->first); remote_top->valid; remote_top = sim_ent_from_id(remote_ss, remote_top->next)) {
sim_ent_sync_alloc_tree(local_root, remote_top, remote_player);
}
/* Sync ents with remote, skipping index 0 (nil) & index 1 (root) */
for (u64 i = 2; i < local_ss->num_ents_reserved; ++i) {
Ent *local_ent = &local_ss->ents[i];
Entity *local_ent = &local_ss->ents[i];
if (local_ent->valid && sim_ent_has_prop(local_ent, SEPROP_SYNC_DST)) {
b32 should_sync = sim_ent_id_eq(local_ent->owner, remote_player) || sim_ent_id_is_nil(remote_player);
if ((sync_flags & SIM_SYNC_FLAG_NOSYNC_PREDICTABLES) && sim_ent_id_eq(local_ent->predictor, local_ss->local_player)) {
should_sync = 0;
}
if (should_sync) {
Ent *remote_ent = sim_ent_from_id(remote_ss, local_ent->id);
Entity *remote_ent = sim_ent_from_id(remote_ss, local_ent->id);
if (remote_ent->valid) {
/* Copy all ent data from remote */
sim_ent_sync(local_ent, remote_ent);
@ -774,11 +774,11 @@ void sim_snapshot_encode(BB_Writer *bw, Client *receiver, Snapshot *ss0, Snapsho
BB_WriteDebugMarker(bw, StringFromStruct(&ss1->num_ents_reserved));
for (u64 i = 1; i < ss1->num_ents_reserved; ++i) {
Ent *e0 = sim_ent_nil();
Entity *e0 = sim_ent_nil();
if (i < ss0->num_ents_reserved) {
e0 = &ss0->ents[i];
}
Ent *e1 = &ss1->ents[i];
Entity *e1 = &ss1->ents[i];
sim_ent_encode(bw, e0, e1);
}
@ -801,7 +801,7 @@ void sim_snapshot_decode(BB_Reader *br, Snapshot *ss)
ss->continuity_gen = BB_ReadUV(br);
ss->phys_iteration = BB_ReadUV(br);
ss->local_player = (EntId) { .uid = BB_ReadUid(br) };
ss->local_player = (EntityId) { .uid = BB_ReadUid(br) };
/* Id bins */
/* TODO: Don't decode these, determine them implicitly from decoded ents */
@ -838,9 +838,9 @@ void sim_snapshot_decode(BB_Reader *br, Snapshot *ss)
ss->num_ents_reserved = BB_ReadUV(br);
i64 reserve_diff = (i64)ss->num_ents_reserved - (i64)old_num_ents_reserved;
if (reserve_diff > 0) {
PushStructsNoZero(ss->ents_arena, Ent, reserve_diff);
PushStructsNoZero(ss->ents_arena, Entity, reserve_diff);
for (u64 i = old_num_ents_reserved; i < ss->num_ents_reserved; ++i) {
Ent *e = &ss->ents[i];
Entity *e = &ss->ents[i];
*e = *sim_ent_nil();
e->ss = ss;
}
@ -854,7 +854,7 @@ void sim_snapshot_decode(BB_Reader *br, Snapshot *ss)
BB_ReadDebugMarker(br, Lit("SNAPSHOT ENTS"));
BB_ReadDebugMarker(br, StringFromStruct(&ss->num_ents_reserved));
for (u64 i = 1; i < ss->num_ents_reserved; ++i) {
Ent *e = &ss->ents[i];
Entity *e = &ss->ents[i];
e->ss = ss;
sim_ent_decode(br, e);
}
@ -901,7 +901,7 @@ void sim_snapshot_encode(BB_Writer *bw, Client *receiver, Snapshot *ss0, Snapsho
BB_AlignWriter(bw);
for (u64 i = 0; i < ss1->num_ents_reserved; ++i) {
Ent *e0 = sim_ent_nil();
Entity *e0 = sim_ent_nil();
if (i < ss0->num_ents_reserved) {
e0 = &ss0->ents[i];
}
@ -917,7 +917,7 @@ void sim_snapshot_encode(BB_Writer *bw, Client *receiver, Snapshot *ss0, Snapsho
}
if (e1->valid) {
Ent *e1 = &ss1->ents[i];
Entity *e1 = &ss1->ents[i];
sim_ent_encode(bw, e0, e1);
}
}
@ -947,7 +947,7 @@ void sim_snapshot_decode(BB_Reader *br, Snapshot *ss)
ss->continuity_gen = BB_ReadUV(br);
ss->phys_iteration = BB_ReadUV(br);
ss->local_player = (EntId) { .uid = BB_ReadUid(br) };
ss->local_player = (EntityId) { .uid = BB_ReadUid(br) };
#if 1
@ -959,9 +959,9 @@ void sim_snapshot_decode(BB_Reader *br, Snapshot *ss)
ss->num_ents_reserved = BB_ReadUV(br);
i64 reserve_diff = (i64)ss->num_ents_reserved - (i64)old_num_ents_reserved;
if (reserve_diff > 0) {
PushStructsNoZero(ss->ents_arena, Ent, reserve_diff);
PushStructsNoZero(ss->ents_arena, Entity, reserve_diff);
for (u64 i = old_num_ents_reserved; i < ss->num_ents_reserved; ++i) {
Ent *e = &ss->ents[i];
Entity *e = &ss->ents[i];
*e = *sim_ent_nil();
e->ss = ss;
}
@ -978,11 +978,11 @@ void sim_snapshot_decode(BB_Reader *br, Snapshot *ss)
b32 released = 0;
u32 alloc_parent_index = ZI;
EntId alloc_ent_id = ZI;
EntityId alloc_ent_id = ZI;
if (allocation_changed) {
released = BB_ReadBit(br);
if (released) {
Ent *e = sim_ent_from_index(ss, e);
Entity *e = sim_ent_from_index(ss, e);
Assert(e->valid); /* An entity that we don't have allocated should never have been marked for release */
if (e->valid) {
sim_ent_enable_prop(e, SEPROP_RELEASE);
@ -1019,11 +1019,11 @@ void sim_snapshot_decode(BB_Reader *br, Snapshot *ss)
for (struct sim_ent_decode_node *n = queue.first; n; n = n->next) {
if (n->is_new) {
u32 index = n->index;
Ent *parent = sim_ent_from_index(ss, n->alloc_parent_index);
Entity *parent = sim_ent_from_index(ss, n->alloc_parent_index);
Assert(!sim_ent_from_index(ss, index)->valid && !sim_ent_from_id(ss, alloc_ent_id)->valid); /* An entity that we have allocated already should never be marked for allocation */
Assert(parent->valid); /* Parent for new entity allocation should always be valid */
if (parent->valid && index < ss->num_ents_reserved) {
Ent *ent = &ss->ents[index];
Entity *ent = &ss->ents[index];
ent->valid = 1;
sim_ent_set_id(ent, n->alloc_ent_id);
sim_ent_link_parent(parent, ent);
@ -1038,7 +1038,7 @@ void sim_snapshot_decode(BB_Reader *br, Snapshot *ss)
for (struct sim_ent_decode_node *n = queue.first; n; n = n->next) {
BB_Reader ent_br = n->br;
u32 index = n->index;
Ent *e = sim_ent_from_index(ss, index);
Entity *e = sim_ent_from_index(ss, index);
if (e->valid) {
sim_ent_decode(&ent_br, e);
} else {
@ -1056,9 +1056,9 @@ void sim_snapshot_decode(BB_Reader *br, Snapshot *ss)
ss->num_ents_reserved = BB_ReadUV(br);
i64 reserve_diff = (i64)ss->num_ents_reserved - (i64)old_num_ents_reserved;
if (reserve_diff > 0) {
PushStructsNoZero(ss->ents_arena, Ent, reserve_diff);
PushStructsNoZero(ss->ents_arena, Entity, reserve_diff);
for (u64 i = old_num_ents_reserved; i < ss->num_ents_reserved; ++i) {
Ent *e = &ss->ents[i];
Entity *e = &ss->ents[i];
*e = *sim_ent_nil();
e->ss = ss;
}
@ -1077,7 +1077,7 @@ void sim_snapshot_decode(BB_Reader *br, Snapshot *ss)
}
for (u64 i = 0; i < ss->num_ents_reserved; ++i) {
Ent *e = &ss->ents[i];
Entity *e = &ss->ents[i];
e->ss = ss;
b32 valid_changed = BB_ReadBit(br);

View File

@ -11,7 +11,7 @@
#define SIM_LAYER_RELATIVE_DEFAULT (0)
#define SIM_LAYER_RELATIVE_WEAPON (1)
Struct(EntId) {
Struct(EntityId) {
Uid uid;
};
@ -88,7 +88,7 @@ Struct(Client) {
ClientHandle prev_in_bin;
/* The client's player entity id in the master sim (if relevant) */
EntId player_id;
EntityId player_id;
/* This is the highest confirmed tick of ours that we know this client has received */
u64 ack;
@ -202,7 +202,7 @@ Struct(Snapshot) {
u64 phys_iteration;
/* The id of the receiver's player in the snapshot */
EntId local_player;
EntityId local_player;
/* Id lookup */
struct EntBin *id_bins;
@ -210,7 +210,7 @@ Struct(Snapshot) {
/* Entities */
Arena *ents_arena;
struct Ent *ents;
struct Entity *ents;
u32 first_free_ent;
u32 num_ents_allocated;
u32 num_ents_reserved;
@ -244,7 +244,7 @@ void sim_snapshot_set_tile(Snapshot *ss, Vec2I32 world_tile_index, TileKind tile
Snapshot *sim_snapshot_alloc_from_lerp(Client *client, Snapshot *ss0, Snapshot *ss1, f64 blend);
/* Sync */
void sim_snapshot_sync_ents(Snapshot *local_ss, Snapshot *remote_ss, EntId remote_player, u32 sync_flags);
void sim_snapshot_sync_ents(Snapshot *local_ss, Snapshot *remote_ss, EntityId remote_player, u32 sync_flags);
/* Encode / decode */
void sim_snapshot_encode(BB_Writer *bw, Client *receiver, Snapshot *ss0, Snapshot *ss1);

View File

@ -3,12 +3,12 @@
#define SIM_ENT_COLLISION_DEBUG_BASIS_Uid (UID(0x302c01182013bb02, 0x570bd270399d11a5))
#define SIM_ENT_TILE_CHUNK_BASIS_Uid (UID(0x3ce42de071dd226b, 0x9b566f7df30c813a))
internal u32 index_from_ent(Snapshot *ss, Ent *ent)
internal u32 index_from_ent(Snapshot *ss, Entity *ent)
{
return ent - ss->ents;
}
internal Ent *ent_from_index(Snapshot *ss, u32 index)
internal Entity *ent_from_index(Snapshot *ss, u32 index)
{
if (index > 0 && index < ss->num_ents_reserved) {
return &ss->ents[index];
@ -18,22 +18,22 @@ internal Ent *ent_from_index(Snapshot *ss, u32 index)
}
/* ========================== *
* Ent allocation
* Entity allocation
* ========================== */
Ent *sim_ent_alloc_raw(Snapshot *ss, Ent *parent, EntId id)
Entity *sim_ent_alloc_raw(Snapshot *ss, Entity *parent, EntityId id)
{
Assert(parent->valid);
Assert(ss->valid);
Assert(ss == parent->ss);
Ent *ent;
Entity *ent;
if (ss->first_free_ent > 0 && ss->first_free_ent < ss->num_ents_reserved) {
/* Reuse from free list */
ent = &ss->ents[ss->first_free_ent];
ss->first_free_ent = ent->next_free;
} else {
/* Make new */
ent = PushStructNoZero(ss->ents_arena, Ent);
ent = PushStructNoZero(ss->ents_arena, Entity);
++ss->num_ents_reserved;
}
*ent = *sim_ent_nil();
@ -50,58 +50,58 @@ Ent *sim_ent_alloc_raw(Snapshot *ss, Ent *parent, EntId id)
}
/* Allocates a new entity that will not sync */
Ent *sim_ent_alloc_local(Ent *parent)
Entity *sim_ent_alloc_local(Entity *parent)
{
Snapshot *ss = parent->ss;
Ent *e = sim_ent_alloc_raw(ss, parent, sim_ent_random_id());
Entity *e = sim_ent_alloc_raw(ss, parent, sim_ent_random_id());
e->owner = ss->local_player;
return e;
}
Ent *sim_ent_alloc_local_with_id(Ent *parent, EntId id)
Entity *sim_ent_alloc_local_with_id(Entity *parent, EntityId id)
{
Snapshot *ss = parent->ss;
Ent *e = sim_ent_alloc_raw(ss, parent, id);
Entity *e = sim_ent_alloc_raw(ss, parent, id);
e->owner = ss->local_player;
return e;
}
/* Allocates a new entity to be synced to clients */
Ent *sim_ent_alloc_sync_src(Ent *parent)
Entity *sim_ent_alloc_sync_src(Entity *parent)
{
Snapshot *ss = parent->ss;
Ent *e = sim_ent_alloc_raw(ss, parent, sim_ent_random_id());
Entity *e = sim_ent_alloc_raw(ss, parent, sim_ent_random_id());
sim_ent_enable_prop(e, SEPROP_SYNC_SRC);
e->owner = ss->local_player;
return e;
}
Ent *sim_ent_alloc_sync_src_with_id(Ent *parent, EntId id)
Entity *sim_ent_alloc_sync_src_with_id(Entity *parent, EntityId id)
{
Snapshot *ss = parent->ss;
Ent *e = sim_ent_alloc_raw(ss, parent, id);
Entity *e = sim_ent_alloc_raw(ss, parent, id);
sim_ent_enable_prop(e, SEPROP_SYNC_SRC);
e->owner = ss->local_player;
return e;
}
/* Allocates a new entity that will sync with incoming net src ents containing id, and coming from the specified owner */
Ent *sim_ent_alloc_sync_dst(Ent *parent, EntId ent_id, EntId owner_id)
Entity *sim_ent_alloc_sync_dst(Entity *parent, EntityId ent_id, EntityId owner_id)
{
Snapshot *ss = parent->ss;
Ent *e = sim_ent_alloc_raw(ss, parent, ent_id);
Entity *e = sim_ent_alloc_raw(ss, parent, ent_id);
sim_ent_enable_prop(e, SEPROP_SYNC_DST);
e->owner = owner_id;
return e;
}
void sim_ent_release_raw(Ent *ent)
void sim_ent_release_raw(Entity *ent)
{
Snapshot *ss = ent->ss;
/* Release children */
Ent *child = sim_ent_from_id(ss, ent->first);
Entity *child = sim_ent_from_id(ss, ent->first);
while (child->valid) {
Ent *next = sim_ent_from_id(ss, child->next);
Entity *next = sim_ent_from_id(ss, child->next);
sim_ent_release_raw(child);
child = next;
}
@ -116,10 +116,10 @@ void sim_ent_release_raw(Ent *ent)
--ss->num_ents_allocated;
}
void sim_ent_release(Ent *ent)
void sim_ent_release(Entity *ent)
{
Snapshot *ss = ent->ss;
Ent *parent = sim_ent_from_id(ss, ent->parent);
Entity *parent = sim_ent_from_id(ss, ent->parent);
if (parent->valid) {
sim_ent_unlink_from_parent(ent);
}
@ -130,12 +130,12 @@ void sim_ent_release_all_with_prop(Snapshot *ss, EntProp prop)
{
TempArena scratch = BeginScratchNoConflict();
Ent **ents_to_release = PushDry(scratch.arena, Ent *);
Entity **ents_to_release = PushDry(scratch.arena, Entity *);
u64 ents_to_release_count = 0;
for (u64 ent_index = 0; ent_index < ss->num_ents_reserved; ++ent_index) {
Ent *ent = &ss->ents[ent_index];
Entity *ent = &ss->ents[ent_index];
if (ent->valid && sim_ent_has_prop(ent, prop)) {
*PushStructNoZero(scratch.arena, Ent *) = ent;
*PushStructNoZero(scratch.arena, Entity *) = ent;
++ents_to_release_count;
}
}
@ -144,7 +144,7 @@ void sim_ent_release_all_with_prop(Snapshot *ss, EntProp prop)
/* TODO: Breadth first iteration to only release parent entities (since
* child entities will be released along with parent anyway) */
for (u64 i = 0; i < ents_to_release_count; ++i) {
Ent *ent = ents_to_release[i];
Entity *ent = ents_to_release[i];
if (ent->valid && !ent->is_root && !sim_ent_has_prop(ent, SEPROP_CMD) && !sim_ent_has_prop(ent, SEPROP_PLAYER)) {
sim_ent_release(ent);
}
@ -157,7 +157,7 @@ void sim_ent_release_all_with_prop(Snapshot *ss, EntProp prop)
* Activate
* ========================== */
void sim_ent_activate(Ent *ent, u64 current_tick)
void sim_ent_activate(Entity *ent, u64 current_tick)
{
sim_ent_enable_prop(ent, SEPROP_ACTIVE);
ent->activation_tick = current_tick;
@ -165,19 +165,19 @@ void sim_ent_activate(Ent *ent, u64 current_tick)
}
/* ========================== *
* Ent id
* Entity id
* ========================== */
internal EntBin *bin_from_id(Snapshot *ss, EntId id)
internal EntBin *bin_from_id(Snapshot *ss, EntityId id)
{
return &ss->id_bins[id.uid.lo % ss->num_id_bins];
}
/* NOTE: This should only really happen during ent allocation (it doesn't make sense for an allocated ent's id to change) */
void sim_ent_set_id(Ent *ent, EntId id)
void sim_ent_set_id(Entity *ent, EntityId id)
{
Snapshot *ss = ent->ss;
EntId old_id = ent->id;
EntityId old_id = ent->id;
if (!sim_ent_id_eq(old_id, id)) {
/* Release old from lookup */
if (!sim_ent_id_is_nil(old_id)) {
@ -185,9 +185,9 @@ void sim_ent_set_id(Ent *ent, EntId id)
u32 prev_index = 0;
u32 next_index = 0;
u32 search_index = bin->first;
Ent *prev = sim_ent_nil();
Ent *next = sim_ent_nil();
Ent *search = ent_from_index(ss, search_index);
Entity *prev = sim_ent_nil();
Entity *next = sim_ent_nil();
Entity *search = ent_from_index(ss, search_index);
while (search->valid) {
next_index = search->next_in_id_bin;
next = ent_from_index(ss, next_index);
@ -220,7 +220,7 @@ void sim_ent_set_id(Ent *ent, EntId id)
if (!sim_ent_id_is_nil(id)) {
#if RtcIsEnabled
{
Ent *existing = sim_ent_from_id(ss, id);
Entity *existing = sim_ent_from_id(ss, id);
/* Collision should be extremely unlikely under normal circumstances, there's probably a logic error somewhere. */
Assert(!existing->valid);
}
@ -228,7 +228,7 @@ void sim_ent_set_id(Ent *ent, EntId id)
EntBin *bin = bin_from_id(ss, id);
u32 ent_index = index_from_ent(ss, ent);
Ent *last = ent_from_index(ss, bin->last);
Entity *last = ent_from_index(ss, bin->last);
if (last->valid) {
last->next_in_id_bin = ent_index;
ent->prev_in_id_bin = bin->last;
@ -244,12 +244,12 @@ void sim_ent_set_id(Ent *ent, EntId id)
}
Ent *sim_ent_from_id(Snapshot *ss, EntId id)
Entity *sim_ent_from_id(Snapshot *ss, EntityId id)
{
Ent *result = sim_ent_nil();
Entity *result = sim_ent_nil();
if (!sim_ent_id_is_nil(id) && ss->valid) {
EntBin *bin = bin_from_id(ss, id);
for (Ent *e = ent_from_index(ss, bin->first); e->valid; e = ent_from_index(ss, e->next_in_id_bin)) {
for (Entity *e = ent_from_index(ss, bin->first); e->valid; e = ent_from_index(ss, e->next_in_id_bin)) {
if (sim_ent_id_eq(e->id, id)) {
result = e;
break;
@ -259,17 +259,17 @@ Ent *sim_ent_from_id(Snapshot *ss, EntId id)
return result;
}
EntId sim_ent_random_id(void)
EntityId sim_ent_random_id(void)
{
EntId result = ZI;
EntityId result = ZI;
result.uid = UidFromTrueRand();
return result;
}
/* Returns the deterministic id of the contact constraint ent id that should be produced from e0 & e1 colliding */
EntId sim_ent_contact_constraint_id_from_contacting_ids(EntId player_id, EntId id0, EntId id1)
EntityId sim_ent_contact_constraint_id_from_contacting_ids(EntityId player_id, EntityId id0, EntityId id1)
{
EntId result = ZI;
EntityId result = ZI;
result.uid = SIM_ENT_CONTACT_BASIS_Uid;
result.uid = CombineUid(result.uid, player_id.uid);
result.uid = CombineUid(result.uid, id0.uid);
@ -278,9 +278,9 @@ EntId sim_ent_contact_constraint_id_from_contacting_ids(EntId player_id, EntId i
}
/* Returns the deterministic id of the debug contact constraint ent id that should be produced from e0 & e1 colliding */
EntId sim_ent_collision_debug_id_from_ids(EntId player_id, EntId id0, EntId id1)
EntityId sim_ent_collision_debug_id_from_ids(EntityId player_id, EntityId id0, EntityId id1)
{
EntId result = ZI;
EntityId result = ZI;
result.uid = SIM_ENT_COLLISION_DEBUG_BASIS_Uid;
result.uid = CombineUid(result.uid, player_id.uid);
result.uid = CombineUid(result.uid, id0.uid);
@ -289,24 +289,24 @@ EntId sim_ent_collision_debug_id_from_ids(EntId player_id, EntId id0, EntId id1)
}
/* Returns the deterministic id of the tile chunk that should be produced at chunk pos */
EntId sim_ent_tile_chunk_id_from_tile_chunk_index(Vec2I32 chunk_index)
EntityId sim_ent_tile_chunk_id_from_tile_chunk_index(Vec2I32 chunk_index)
{
EntId result = ZI;
EntityId result = ZI;
result.uid = SIM_ENT_TILE_CHUNK_BASIS_Uid;
result.uid = CombineUid(result.uid, UID(RandU64FromSeed(chunk_index.x), RandU64FromSeed(chunk_index.y)));
return result;
}
/* ========================== *
* Ent query
* Entity query
* ========================== */
Ent *sim_ent_find_first_match_one(Snapshot *ss, EntProp prop)
Entity *sim_ent_find_first_match_one(Snapshot *ss, EntProp prop)
{
u64 count = ss->num_ents_reserved;
Ent *entities = ss->ents;
Entity *entities = ss->ents;
for (u64 ent_index = 0; ent_index < count; ++ent_index) {
Ent *ent = &entities[ent_index];
Entity *ent = &entities[ent_index];
if (ent->valid && sim_ent_has_prop(ent, prop)) {
return ent;
}
@ -314,12 +314,12 @@ Ent *sim_ent_find_first_match_one(Snapshot *ss, EntProp prop)
return sim_ent_nil();
}
Ent *sim_ent_find_first_match_all(Snapshot *ss, EntPropArray props)
Entity *sim_ent_find_first_match_all(Snapshot *ss, EntPropArray props)
{
u64 count = ss->num_ents_reserved;
Ent *entities = ss->ents;
Entity *entities = ss->ents;
for (u64 ent_index = 0; ent_index < count; ++ent_index) {
Ent *ent = &entities[ent_index];
Entity *ent = &entities[ent_index];
if (ent->valid) {
b32 all = 1;
for (u64 i = 0; i < props.count; ++i) {
@ -337,22 +337,22 @@ Ent *sim_ent_find_first_match_all(Snapshot *ss, EntPropArray props)
}
/* ========================== *
* Ent tree
* Entity tree
* ========================== */
void sim_ent_link_parent(Ent *ent, Ent *parent)
void sim_ent_link_parent(Entity *ent, Entity *parent)
{
Snapshot *ss = ent->ss;
Ent *old_parent = sim_ent_from_id(ss, ent->parent);
Entity *old_parent = sim_ent_from_id(ss, ent->parent);
if (old_parent->valid) {
/* Unlink from current parent */
sim_ent_unlink_from_parent(ent);
}
EntId ent_id = ent->id;
EntId last_child_id = parent->last;
Ent *last_child = sim_ent_from_id(ss, last_child_id);
EntityId ent_id = ent->id;
EntityId last_child_id = parent->last;
Entity *last_child = sim_ent_from_id(ss, last_child_id);
if (last_child->valid) {
ent->prev = last_child_id;
last_child->next = ent_id;
@ -372,14 +372,14 @@ void sim_ent_link_parent(Ent *ent, Ent *parent)
}
/* NOTE: Entity will be dangling after calling this, should re-link to root ent. */
void sim_ent_unlink_from_parent(Ent *ent)
void sim_ent_unlink_from_parent(Entity *ent)
{
Snapshot *ss = ent->ss;
EntId parent_id = ent->parent;
Ent *parent = sim_ent_from_id(ss, parent_id);
Ent *prev = sim_ent_from_id(ss, ent->prev);
Ent *next = sim_ent_from_id(ss, ent->next);
EntityId parent_id = ent->parent;
Entity *parent = sim_ent_from_id(ss, parent_id);
Entity *prev = sim_ent_from_id(ss, ent->prev);
Entity *next = sim_ent_from_id(ss, ent->next);
/* Unlink from parent & siblings */
if (prev->valid) {
@ -397,12 +397,12 @@ void sim_ent_unlink_from_parent(Ent *ent)
}
/* ========================== *
* Ent xform
* Entity xform
* ========================== */
internal void sim_ent_mark_child_xforms_dirty(Snapshot *ss, Ent *ent)
internal void sim_ent_mark_child_xforms_dirty(Snapshot *ss, Entity *ent)
{
for (Ent *child = sim_ent_from_id(ss, ent->first); child->valid; child = sim_ent_from_id(ss, child->next)) {
for (Entity *child = sim_ent_from_id(ss, ent->first); child->valid; child = sim_ent_from_id(ss, child->next)) {
if (child->_is_xform_dirty) {
break;
} else {
@ -412,14 +412,14 @@ internal void sim_ent_mark_child_xforms_dirty(Snapshot *ss, Ent *ent)
}
}
internal Xform sim_ent_get_xform_internal(Snapshot *ss, Ent *ent)
internal Xform sim_ent_get_xform_internal(Snapshot *ss, Entity *ent)
{
Xform xf;
if (ent->_is_xform_dirty) {
if (ent->is_top) {
xf = ent->_local_xform;
} else {
Ent *parent = sim_ent_from_id(ss, ent->parent);
Entity *parent = sim_ent_from_id(ss, ent->parent);
xf = sim_ent_get_xform_internal(ss, parent);
xf = MulXform(xf, ent->_local_xform);
ent->_xform = xf;
@ -433,7 +433,7 @@ internal Xform sim_ent_get_xform_internal(Snapshot *ss, Ent *ent)
return xf;
}
Xform sim_ent_get_xform(Ent *ent)
Xform sim_ent_get_xform(Entity *ent)
{
Xform xf;
if (ent->_is_xform_dirty) {
@ -441,7 +441,7 @@ Xform sim_ent_get_xform(Ent *ent)
xf = ent->_local_xform;
} else {
Snapshot *ss = ent->ss;
Ent *parent = sim_ent_from_id(ss, ent->parent);
Entity *parent = sim_ent_from_id(ss, ent->parent);
xf = sim_ent_get_xform_internal(ss, parent);
xf = MulXform(xf, ent->_local_xform);
ent->_xform = xf;
@ -455,12 +455,12 @@ Xform sim_ent_get_xform(Ent *ent)
return xf;
}
Xform sim_ent_get_local_xform(Ent *ent)
Xform sim_ent_get_local_xform(Entity *ent)
{
return ent->_local_xform;
}
void sim_ent_set_xform(Ent *ent, Xform xf)
void sim_ent_set_xform(Entity *ent, Xform xf)
{
if (!EqXform(xf, ent->_xform)) {
Snapshot *ss = ent->ss;
@ -468,7 +468,7 @@ void sim_ent_set_xform(Ent *ent, Xform xf)
if (ent->is_top) {
ent->_local_xform = xf;
} else {
Ent *parent = sim_ent_from_id(ss, ent->parent);
Entity *parent = sim_ent_from_id(ss, ent->parent);
Xform parent_global = sim_ent_get_xform_internal(ss, parent);
ent->_local_xform = MulXform(InvertXform(parent_global), xf);
}
@ -478,7 +478,7 @@ void sim_ent_set_xform(Ent *ent, Xform xf)
}
}
void sim_ent_set_local_xform(Ent *ent, Xform xf)
void sim_ent_set_local_xform(Entity *ent, Xform xf)
{
if (!EqXform(xf, ent->_local_xform)) {
ent->_local_xform = xf;
@ -488,24 +488,24 @@ void sim_ent_set_local_xform(Ent *ent, Xform xf)
}
/* ========================== *
* Ent movement
* Entity movement
* ========================== */
void sim_ent_set_linear_velocity(Ent *ent, Vec2 velocity)
void sim_ent_set_linear_velocity(Entity *ent, Vec2 velocity)
{
if (sim_ent_has_prop(ent, SEPROP_KINEMATIC) || sim_ent_has_prop(ent, SEPROP_DYNAMIC)) {
ent->linear_velocity = ClampVec2Len(velocity, SIM_MAX_LINEAR_VELOCITY);
}
}
void sim_ent_set_angular_velocity(Ent *ent, f32 velocity)
void sim_ent_set_angular_velocity(Entity *ent, f32 velocity)
{
if (sim_ent_has_prop(ent, SEPROP_KINEMATIC) || sim_ent_has_prop(ent, SEPROP_DYNAMIC)) {
ent->angular_velocity = ClampF32(velocity, -SIM_MAX_ANGULAR_VELOCITY, SIM_MAX_ANGULAR_VELOCITY);
}
}
void sim_ent_apply_linear_impulse(Ent *ent, Vec2 impulse, Vec2 point)
void sim_ent_apply_linear_impulse(Entity *ent, Vec2 impulse, Vec2 point)
{
if (sim_ent_has_prop(ent, SEPROP_DYNAMIC)) {
Xform xf = sim_ent_get_xform(ent);
@ -520,7 +520,7 @@ void sim_ent_apply_linear_impulse(Ent *ent, Vec2 impulse, Vec2 point)
}
}
void sim_ent_apply_linear_impulse_to_center(Ent *ent, Vec2 impulse)
void sim_ent_apply_linear_impulse_to_center(Entity *ent, Vec2 impulse)
{
if (sim_ent_has_prop(ent, SEPROP_DYNAMIC)) {
Xform xf = sim_ent_get_xform(ent);
@ -531,14 +531,14 @@ void sim_ent_apply_linear_impulse_to_center(Ent *ent, Vec2 impulse)
}
}
void sim_ent_apply_force_to_center(Ent *ent, Vec2 force)
void sim_ent_apply_force_to_center(Entity *ent, Vec2 force)
{
if (sim_ent_has_prop(ent, SEPROP_DYNAMIC)) {
ent->force = AddVec2(ent->force, force);
}
}
void sim_ent_apply_angular_impulse(Ent *ent, f32 impulse)
void sim_ent_apply_angular_impulse(Entity *ent, f32 impulse)
{
if (sim_ent_has_prop(ent, SEPROP_DYNAMIC)) {
Xform xf = sim_ent_get_xform(ent);
@ -548,7 +548,7 @@ void sim_ent_apply_angular_impulse(Ent *ent, f32 impulse)
}
}
void sim_ent_apply_torque(Ent *ent, f32 torque)
void sim_ent_apply_torque(Entity *ent, f32 torque)
{
if (sim_ent_has_prop(ent, SEPROP_DYNAMIC)) {
ent->torque += torque;
@ -559,31 +559,31 @@ void sim_ent_apply_torque(Ent *ent, f32 torque)
* Tile
* ========================== */
Ent *sim_tile_chunk_from_chunk_index(Snapshot *ss, Vec2I32 chunk_index)
Entity *sim_tile_chunk_from_chunk_index(Snapshot *ss, Vec2I32 chunk_index)
{
EntId chunk_id = sim_ent_tile_chunk_id_from_tile_chunk_index(chunk_index);
Ent *chunk_ent = sim_ent_from_id(ss, chunk_id);
EntityId chunk_id = sim_ent_tile_chunk_id_from_tile_chunk_index(chunk_index);
Entity *chunk_ent = sim_ent_from_id(ss, chunk_id);
return chunk_ent;
}
Ent *sim_tile_chunk_from_world_tile_index(Snapshot *ss, Vec2I32 world_tile_index)
Entity *sim_tile_chunk_from_world_tile_index(Snapshot *ss, Vec2I32 world_tile_index)
{
Vec2I32 chunk_index = sim_tile_chunk_index_from_world_tile_index(world_tile_index);
Ent *chunk_ent = sim_tile_chunk_from_chunk_index(ss, chunk_index);
Entity *chunk_ent = sim_tile_chunk_from_chunk_index(ss, chunk_index);
return chunk_ent;
}
TileKind sim_get_chunk_tile(Ent *chunk_ent, Vec2I32 local_tile_index)
TileKind sim_get_chunk_tile(Entity *chunk_ent, Vec2I32 local_tile_index)
{
TileKind result = chunk_ent->tile_chunk_tiles[local_tile_index.x + (local_tile_index.y * SIM_TILES_PER_CHUNK_SQRT)];
return result;
}
/* ========================== *
* Ent lerp
* Entity lerp
* ========================== */
void sim_ent_lerp(Ent *e, Ent *e0, Ent *e1, f64 blend)
void sim_ent_lerp(Entity *e, Entity *e0, Entity *e1, f64 blend)
{
if (sim_ent_is_valid_and_active(e0) && sim_ent_is_valid_and_active(e1)
&& sim_ent_id_eq(e0->id, e1->id)
@ -620,32 +620,32 @@ void sim_ent_lerp(Ent *e, Ent *e0, Ent *e1, f64 blend)
}
/* ========================== *
* Ent sync
* Entity sync
* ========================== */
/* Walks a local & remote ent tree and allocates any missing net dst ents from remote src ents */
void sim_ent_sync_alloc_tree(Ent *local_parent, Ent *remote, EntId remote_player)
void sim_ent_sync_alloc_tree(Entity *local_parent, Entity *remote, EntityId remote_player)
{
__prof;
if (sim_ent_has_prop(remote, SEPROP_SYNC_SRC)) {
Snapshot *local_ss = local_parent->ss;
Snapshot *remote_ss = remote->ss;
EntId id = remote->id;
Ent *local_ent = sim_ent_from_id(local_ss, id);
EntityId id = remote->id;
Entity *local_ent = sim_ent_from_id(local_ss, id);
if (!local_ent->valid) {
local_ent = sim_ent_alloc_sync_dst(local_parent, id, remote_player);
}
for (Ent *remote_child = sim_ent_from_id(remote_ss, remote->first); remote_child->valid; remote_child = sim_ent_from_id(remote_ss, remote_child->next)) {
for (Entity *remote_child = sim_ent_from_id(remote_ss, remote->first); remote_child->valid; remote_child = sim_ent_from_id(remote_ss, remote_child->next)) {
sim_ent_sync_alloc_tree(local_ent, remote_child, remote_player);
}
}
}
/* Copies data between two synced entities */
void sim_ent_sync(Ent *local, Ent *remote)
void sim_ent_sync(Entity *local, Entity *remote)
{
Ent old = *local;
Entity old = *local;
CopyStruct(local, remote);
/* Why would 2 ents w/ different uids ever be synced? */
@ -684,10 +684,10 @@ void sim_ent_sync(Ent *local, Ent *remote)
#if 1
/* ========================== *
* Ent encode
* Entity encode
* ========================== */
void sim_ent_encode(BB_Writer *bw, Ent *e0, Ent *e1)
void sim_ent_encode(BB_Writer *bw, Entity *e0, Entity *e1)
{
Snapshot *ss = e1->ss;
/* FIXME: Things like xforms need to be retreived manually rather than memcopied. */
@ -711,10 +711,10 @@ void sim_ent_encode(BB_Writer *bw, Ent *e0, Ent *e1)
}
/* ========================== *
* Ent decode
* Entity decode
* ========================== */
void sim_ent_decode(BB_Reader *br, Ent *e)
void sim_ent_decode(BB_Reader *br, Entity *e)
{
Snapshot *old_ss = e->ss;
{
@ -736,10 +736,10 @@ void sim_ent_decode(BB_Reader *br, Ent *e)
#else
/* ========================== *
* Ent encode
* Entity encode
* ========================== */
void sim_ent_encode(BB_Writer *bw, Ent *e0, Ent *e1)
void sim_ent_encode(BB_Writer *bw, Entity *e0, Entity *e1)
{
Snapshot *ss = e1->ss;
@ -769,12 +769,12 @@ void sim_ent_encode(BB_Writer *bw, Ent *e0, Ent *e1)
}
/* ========================== *
* Ent decode
* Entity decode
* ========================== */
void sim_ent_decode(BB_Reader *br, Ent *e)
void sim_ent_decode(BB_Reader *br, Entity *e)
{
Ent decoded = *e;
Entity decoded = *e;
{
u64 pos = 0;
while (pos < sizeof(decoded)) {
@ -789,8 +789,8 @@ void sim_ent_decode(BB_Reader *br, Ent *e)
}
decoded.ss = e->ss;
EntId old_id = e->id;
EntId new_id = decoded.id;
EntityId old_id = e->id;
EntityId new_id = decoded.id;
CopyStruct(e, &decoded);
e->id = old_id;
if (!sim_ent_id_eq(old_id, new_id)) {

View File

@ -1,5 +1,5 @@
#define SIM_ENT_NIL_ID ((EntId) { UID(0, 0) })
#define SIM_ENT_ROOT_ID ((EntId) { UID(0xaaaaaaaaaaaaaaaa, 0xaaaaaaaaaaaaaaaa) })
#define SIM_ENT_NIL_ID ((EntityId) { UID(0, 0) })
#define SIM_ENT_ROOT_ID ((EntityId) { UID(0xaaaaaaaaaaaaaaaa, 0xaaaaaaaaaaaaaaaa) })
typedef i32 EntProp; enum {
SEPROP_ACTIVE,
@ -60,14 +60,14 @@ typedef i32 EntProp; enum {
SEPROP_COUNT
};
Struct(Ent) {
Struct(Entity) {
Snapshot *ss;
/* ====================================================================== */
/* Metadata */
b32 valid; /* Is this ent allocated in memory that can be written to (can always be read) */
EntId id;
EntityId id;
u64 props[(SEPROP_COUNT + 63) / 64];
u64 continuity_gen;
@ -78,14 +78,14 @@ Struct(Ent) {
b32 is_top;
/* The id of the top level parent of the ent tree (if ent is top then this point to itself) */
EntId top;
EntityId top;
/* Tree */
EntId parent;
EntId next;
EntId prev;
EntId first;
EntId last;
EntityId parent;
EntityId next;
EntityId prev;
EntityId first;
EntityId last;
/* Lists keyed by index in snapshot ent array */
u32 next_in_id_bin;
@ -99,10 +99,10 @@ Struct(Ent) {
/* SEPROP_SYNC_DST */
/* Id of the player that owns simulation for this entity */
EntId owner;
EntityId owner;
/* Id of the player that should predict simulation of this this entity locally */
EntId predictor;
EntityId predictor;
/* ====================================================================== */
/* Position */
@ -130,13 +130,13 @@ Struct(Ent) {
/* SEPROP_CMD */
CmdKind cmd_kind;
EntId cmd_player;
EntityId cmd_player;
/* FIXME: Lerp */
/* Control cmd */
ControlData cmd_control;
EntId cmd_control_hovered_ent;
EntityId cmd_control_hovered_ent;
/* Chat cmd */
//String cmd_chat_msg;
@ -146,7 +146,7 @@ Struct(Ent) {
/* SEPROP_CHAT */
EntId chat_player;
EntityId chat_player;
//String chat_msg;
@ -171,11 +171,11 @@ Struct(Ent) {
ControlData player_control;
Vec2 player_cursor_pos;
EntId player_hovered_ent;
EntId player_control_ent;
EntId player_camera_ent;
EntityId player_hovered_ent;
EntityId player_control_ent;
EntityId player_camera_ent;
EntId player_dbg_drag_joint_ent;
EntityId player_dbg_drag_joint_ent;
b32 player_dbg_drag_start;
b32 player_dbg_drag_stop;
@ -215,7 +215,7 @@ Struct(Ent) {
/* SEPROP_CONTROLLED */
EntId controlling_player;
EntityId controlling_player;
f32 control_force; /* How much force is applied to achieve desired control movement */
f32 control_force_max_speed; /* Maximum linear velocity achieved by force (m/s) */
@ -224,8 +224,8 @@ Struct(Ent) {
ControlData control;
EntId move_joint;
EntId aim_joint;
EntityId move_joint;
EntityId aim_joint;
/* ====================================================================== */
/* Physics */
@ -239,7 +239,7 @@ Struct(Ent) {
f32 mass_unscaled; /* Mass of ent in kg before any transformations */
f32 inertia_unscaled; /* Inertia of ent in kg*m^2 before any transformations */
EntId ground_friction_joint;
EntityId ground_friction_joint;
f32 linear_ground_friction;
f32 angular_ground_friction;
@ -282,22 +282,22 @@ Struct(Ent) {
/* ====================================================================== */
/* Equip */
EntId equipped;
EntityId equipped;
/* ====================================================================== */
/* Chucker */
/* SEPROP_WEAPON_CHUCKER */
EntId chucker_zone;
EntId chucker_joint;
EntityId chucker_zone;
EntityId chucker_joint;
/* ====================================================================== */
/* Chucker zone */
/* SEPROP_CHUCKER_ZONE */
EntId chucker_zone_ent;
EntityId chucker_zone_ent;
u64 chucker_zone_ent_tick;
/* ====================================================================== */
@ -319,14 +319,14 @@ Struct(Ent) {
i64 triggered_count;
/* Other triggers to activate when this entity has been triggered */
//EntId trigger_out_left;
//EntId trigger_out_right;
//EntityId trigger_out_left;
//EntityId trigger_out_right;
/* ====================================================================== */
/* Bullet */
EntId bullet_src;
EntId bullet_tracer;
EntityId bullet_src;
EntityId bullet_tracer;
Vec2 bullet_src_pos;
Vec2 bullet_src_dir;
f32 bullet_launch_velocity;
@ -380,7 +380,7 @@ Struct(Ent) {
/* Camera */
/* SEPROP_CAMERA */
EntId camera_follow;
EntityId camera_follow;
Xform camera_quad_xform;
f32 camera_lerp; /* Rate at which camera xform approaches target xform */
@ -392,7 +392,7 @@ Struct(Ent) {
};
Struct(EntArray) {
Ent *ents;
Entity *ents;
u64 count;
};
@ -410,9 +410,9 @@ Struct(EntBin) {
* Nil
* ========================== */
Inline Ent *sim_ent_nil(void)
Inline Entity *sim_ent_nil(void)
{
extern Readonly Ent **_g_sim_ent_nil;
extern Readonly Entity **_g_sim_ent_nil;
return *_g_sim_ent_nil;
}
@ -420,12 +420,12 @@ Inline Ent *sim_ent_nil(void)
* Id helpers
* ========================== */
Inline b32 sim_ent_id_eq(EntId a, EntId b)
Inline b32 sim_ent_id_eq(EntityId a, EntityId b)
{
return EqUid(a.uid, b.uid);
}
Inline b32 sim_ent_id_is_nil(EntId id)
Inline b32 sim_ent_id_is_nil(EntityId id)
{
return EqUid(id.uid, SIM_ENT_NIL_ID.uid);
}
@ -434,49 +434,49 @@ Inline b32 sim_ent_id_is_nil(EntId id)
* Property helpers
* ========================== */
Inline void sim_ent_enable_prop(Ent *ent, EntProp prop)
Inline void sim_ent_enable_prop(Entity *ent, EntProp prop)
{
u64 index = prop / 64;
u64 bit = prop % 64;
ent->props[index] |= ((u64)1 << bit);
}
Inline void sim_ent_disable_prop(Ent *ent, EntProp prop)
Inline void sim_ent_disable_prop(Entity *ent, EntProp prop)
{
u64 index = prop / 64;
u64 bit = prop % 64;
ent->props[index] &= ~((u64)1 << bit);
}
Inline b32 sim_ent_has_prop(Ent *ent, EntProp prop)
Inline b32 sim_ent_has_prop(Entity *ent, EntProp prop)
{
u64 index = prop / 64;
u64 bit = prop % 64;
return !!(ent->props[index] & ((u64)1 << bit));
}
Inline b32 sim_ent_is_valid_and_active(Ent *ent)
Inline b32 sim_ent_is_valid_and_active(Entity *ent)
{
return ent->valid && sim_ent_has_prop(ent, SEPROP_ACTIVE);
}
Inline b32 sim_ent_should_predict(Ent *ent)
Inline b32 sim_ent_should_predict(Entity *ent)
{
return sim_ent_id_eq(ent->predictor, ent->ss->local_player);
}
Inline b32 sim_ent_is_owner(Ent *ent)
Inline b32 sim_ent_is_owner(Entity *ent)
{
return sim_ent_id_eq(ent->owner, ent->ss->local_player);
}
Inline b32 sim_ent_should_simulate(Ent *ent)
Inline b32 sim_ent_should_simulate(Entity *ent)
{
b32 result = 0;
if (sim_ent_is_valid_and_active(ent)) {
result = 1;
if (sim_ent_has_prop(ent, SEPROP_SYNC_DST)) {
EntId local_player = ent->ss->local_player;
EntityId local_player = ent->ss->local_player;
result = sim_ent_id_eq(local_player, ent->owner) || sim_ent_id_eq(local_player, ent->predictor);
}
}
@ -484,67 +484,67 @@ Inline b32 sim_ent_should_simulate(Ent *ent)
}
/* ========================== *
* Ent functions
* Entity functions
* ========================== */
/* Alloc */
Ent *sim_ent_alloc_raw(Snapshot *ss, Ent *parent, EntId id);
Ent *sim_ent_alloc_local(Ent *parent);
Ent *sim_ent_alloc_local_with_id(Ent *parent, EntId id);
Ent *sim_ent_alloc_sync_src(Ent *parent);
Ent *sim_ent_alloc_sync_src_with_id(Ent *parent, EntId id);
Ent *sim_ent_alloc_sync_dst(Ent *parent, EntId ent_id, EntId owner_id);
Entity *sim_ent_alloc_raw(Snapshot *ss, Entity *parent, EntityId id);
Entity *sim_ent_alloc_local(Entity *parent);
Entity *sim_ent_alloc_local_with_id(Entity *parent, EntityId id);
Entity *sim_ent_alloc_sync_src(Entity *parent);
Entity *sim_ent_alloc_sync_src_with_id(Entity *parent, EntityId id);
Entity *sim_ent_alloc_sync_dst(Entity *parent, EntityId ent_id, EntityId owner_id);
void sim_ent_release_raw(Ent *ent);
void sim_ent_release(Ent *ent);
void sim_ent_release_raw(Entity *ent);
void sim_ent_release(Entity *ent);
void sim_ent_release_all_with_prop(Snapshot *ss, EntProp prop);
/* Activate */
void sim_ent_activate(Ent *ent, u64 current_tick);
void sim_ent_activate(Entity *ent, u64 current_tick);
/* Id */
void sim_ent_set_id(Ent *ent, EntId id);
Ent *sim_ent_from_id(Snapshot *ss, EntId id);
EntId sim_ent_random_id(void);
EntId sim_ent_contact_constraint_id_from_contacting_ids(EntId player_id, EntId id0, EntId id1);
EntId sim_ent_collision_debug_id_from_ids(EntId player_id, EntId id0, EntId id1);
EntId sim_ent_tile_chunk_id_from_tile_chunk_index(Vec2I32 chunk_start);
void sim_ent_set_id(Entity *ent, EntityId id);
Entity *sim_ent_from_id(Snapshot *ss, EntityId id);
EntityId sim_ent_random_id(void);
EntityId sim_ent_contact_constraint_id_from_contacting_ids(EntityId player_id, EntityId id0, EntityId id1);
EntityId sim_ent_collision_debug_id_from_ids(EntityId player_id, EntityId id0, EntityId id1);
EntityId sim_ent_tile_chunk_id_from_tile_chunk_index(Vec2I32 chunk_start);
/* Query */
Ent *sim_ent_find_first_match_one(Snapshot *ss, EntProp prop);
Ent *sim_ent_find_first_match_all(Snapshot *ss, EntPropArray props);
Entity *sim_ent_find_first_match_one(Snapshot *ss, EntProp prop);
Entity *sim_ent_find_first_match_all(Snapshot *ss, EntPropArray props);
/* Tree */
void sim_ent_link_parent(Ent *parent, Ent *child);
void sim_ent_unlink_from_parent(Ent *ent);
void sim_ent_link_parent(Entity *parent, Entity *child);
void sim_ent_unlink_from_parent(Entity *ent);
/* Xform */
Xform sim_ent_get_xform(Ent *ent);
Xform sim_ent_get_local_xform(Ent *ent);
void sim_ent_set_xform(Ent *ent, Xform xf);
void sim_ent_set_local_xform(Ent *ent, Xform xf);
Xform sim_ent_get_xform(Entity *ent);
Xform sim_ent_get_local_xform(Entity *ent);
void sim_ent_set_xform(Entity *ent, Xform xf);
void sim_ent_set_local_xform(Entity *ent, Xform xf);
/* Movement */
void sim_ent_set_linear_velocity(Ent *ent, Vec2 velocity);
void sim_ent_set_angular_velocity(Ent *ent, f32 velocity);
void sim_ent_apply_linear_impulse(Ent *ent, Vec2 impulse, Vec2 world_point);
void sim_ent_apply_linear_impulse_to_center(Ent *ent, Vec2 impulse);
void sim_ent_apply_force_to_center(Ent *ent, Vec2 force);
void sim_ent_apply_angular_impulse(Ent *ent, f32 impulse);
void sim_ent_apply_torque(Ent *ent, f32 torque);
void sim_ent_set_linear_velocity(Entity *ent, Vec2 velocity);
void sim_ent_set_angular_velocity(Entity *ent, f32 velocity);
void sim_ent_apply_linear_impulse(Entity *ent, Vec2 impulse, Vec2 world_point);
void sim_ent_apply_linear_impulse_to_center(Entity *ent, Vec2 impulse);
void sim_ent_apply_force_to_center(Entity *ent, Vec2 force);
void sim_ent_apply_angular_impulse(Entity *ent, f32 impulse);
void sim_ent_apply_torque(Entity *ent, f32 torque);
/* Tile */
Ent *sim_tile_chunk_from_chunk_index(Snapshot *ss, Vec2I32 chunk_index);
Ent *sim_tile_chunk_from_world_tile_index(Snapshot *ss, Vec2I32 world_tile_index);
TileKind sim_get_chunk_tile(Ent *chunk_ent, Vec2I32 local_tile_index);
Entity *sim_tile_chunk_from_chunk_index(Snapshot *ss, Vec2I32 chunk_index);
Entity *sim_tile_chunk_from_world_tile_index(Snapshot *ss, Vec2I32 world_tile_index);
TileKind sim_get_chunk_tile(Entity *chunk_ent, Vec2I32 local_tile_index);
/* Lerp */
void sim_ent_lerp(Ent *e, Ent *e0, Ent *e1, f64 blend);
void sim_ent_lerp(Entity *e, Entity *e0, Entity *e1, f64 blend);
/* Sync */
void sim_ent_sync_alloc_tree(Ent *local_parent, Ent *remote, EntId remote_player);
void sim_ent_sync(Ent *local, Ent *remote);
void sim_ent_sync_alloc_tree(Entity *local_parent, Entity *remote, EntityId remote_player);
void sim_ent_sync(Entity *local, Entity *remote);
/* Encode / decode */
void sim_ent_encode(BB_Writer *bw, Ent *e0, Ent *e1);
void sim_ent_decode(BB_Reader *br, Ent *e);
void sim_ent_encode(BB_Writer *bw, Entity *e0, Entity *e1);
void sim_ent_decode(BB_Reader *br, Entity *e);

View File

@ -5,7 +5,7 @@
* Contact
* ========================== */
internal b32 can_contact(Ent *e0, Ent *e1)
internal b32 can_contact(Entity *e0, Entity *e1)
{
b32 result = 0;
result = e0 != e1 &&
@ -20,14 +20,14 @@ void phys_create_and_update_contacts(PhysStepCtx *ctx, f32 elapsed_dt, u64 phys_
SimStepCtx *sim_step_ctx = ctx->sim_step_ctx;
Snapshot *ss = sim_step_ctx->world;
Space *space = sim_step_ctx->accel->space;
EntId local_player = ss->local_player;
EntityId local_player = ss->local_player;
phys_collision_callback_func *collision_callback = ctx->collision_callback;
Ent *root = sim_ent_from_id(ss, SIM_ENT_ROOT_ID);
Entity *root = sim_ent_from_id(ss, SIM_ENT_ROOT_ID);
u64 tick = ss->tick;
for (u64 check0_index = 0; check0_index < ss->num_ents_reserved; ++check0_index) {
Ent *check0 = &ss->ents[check0_index];
Entity *check0 = &ss->ents[check0_index];
if (!sim_ent_is_valid_and_active(check0)) continue;
if (!(sim_ent_has_prop(check0, SEPROP_SOLID) || sim_ent_has_prop(check0, SEPROP_SENSOR))) continue;
if (check0->local_collider.count <= 0) continue;
@ -39,15 +39,15 @@ void phys_create_and_update_contacts(PhysStepCtx *ctx, f32 elapsed_dt, u64 phys_
SpaceIter iter = space_iter_begin_aabb(space, aabb);
SpaceEntry *space_entry;
while ((space_entry = space_iter_next(&iter)) != 0) {
Ent *check1 = sim_ent_from_id(ss, space_entry->ent);
Entity *check1 = sim_ent_from_id(ss, space_entry->ent);
if (!sim_ent_is_valid_and_active(check1)) continue;
if (!(sim_ent_has_prop(check1, SEPROP_SOLID) || sim_ent_has_prop(check1, SEPROP_SENSOR))) continue;
if (check1->local_collider.count <= 0) continue;
if (!can_contact(check0, check1)) continue;
/* Deterministic order based on entity id */
Ent *e0;
Ent *e1;
Entity *e0;
Entity *e1;
Xform e0_xf;
Xform e1_xf;
CLD_Shape e0_collider;
@ -68,8 +68,8 @@ void phys_create_and_update_contacts(PhysStepCtx *ctx, f32 elapsed_dt, u64 phys_
e1_collider = check0_collider;
}
EntId constraint_id = sim_ent_contact_constraint_id_from_contacting_ids(local_player, e0->id, e1->id);
Ent *constraint_ent = sim_ent_from_id(ss, constraint_id);
EntityId constraint_id = sim_ent_contact_constraint_id_from_contacting_ids(local_player, e0->id, e1->id);
Entity *constraint_ent = sim_ent_from_id(ss, constraint_id);
if (constraint_ent->valid) {
if (constraint_ent->contact_constraint_data.last_phys_iteration >= phys_iteration) {
@ -228,8 +228,8 @@ void phys_create_and_update_contacts(PhysStepCtx *ctx, f32 elapsed_dt, u64 phys_
/* TODO: Remove this (debugging) */
#if COLLIDER_DEBUG && COLLIDER_DEBUG_DETAILED
{
EntId dbg_ent_id = sim_ent_collision_debug_id_from_ids(local_player, e0->id, e1->id);
Ent *dbg_ent = sim_ent_from_id(ss, dbg_ent_id);
EntityId dbg_ent_id = sim_ent_collision_debug_id_from_ids(local_player, e0->id, e1->id);
Entity *dbg_ent = sim_ent_from_id(ss, dbg_ent_id);
if (!dbg_ent->valid) {
/* FIXME: Entity never released */
dbg_ent = sim_ent_alloc_local_with_id(root, dbg_ent_id);
@ -271,15 +271,15 @@ void phys_prepare_contacts(PhysStepCtx *ctx, u64 phys_iteration)
Snapshot *ss = ctx->sim_step_ctx->world;
for (u64 sim_ent_index = 0; sim_ent_index < ss->num_ents_reserved; ++sim_ent_index) {
Ent *constraint_ent = &ss->ents[sim_ent_index];
Entity *constraint_ent = &ss->ents[sim_ent_index];
if (!sim_ent_should_simulate(constraint_ent)) continue;
if (!sim_ent_has_prop(constraint_ent, SEPROP_CONTACT_CONSTRAINT)) continue;
ContactConstraint *constraint = &constraint_ent->contact_constraint_data;
u32 num_points = constraint->num_points;
Ent *e0 = sim_ent_from_id(ss, constraint->e0);
Ent *e1 = sim_ent_from_id(ss, constraint->e1);
Entity *e0 = sim_ent_from_id(ss, constraint->e0);
Entity *e1 = sim_ent_from_id(ss, constraint->e1);
if (constraint->last_phys_iteration >= phys_iteration && num_points > 0 && sim_ent_is_valid_and_active(e0) && sim_ent_is_valid_and_active(e1)) {
Vec2 normal = constraint->normal;
Vec2 tangent = PerpVec2(normal);
@ -355,13 +355,13 @@ void phys_prepare_contacts(PhysStepCtx *ctx, u64 phys_iteration)
#if COLLIDER_DEBUG
/* Remove collision debug ents */
for (u64 sim_ent_index = 0; sim_ent_index < ss->num_ents_reserved; ++sim_ent_index) {
Ent *dbg_ent = &ss->ents[sim_ent_index];
Entity *dbg_ent = &ss->ents[sim_ent_index];
if (!sim_ent_should_simulate(dbg_ent)) continue;
if (!sim_ent_has_prop(dbg_ent, SEPROP_COLLISION_DEBUG)) continue;
CollisionDebugData *dbg = &dbg_ent->collision_debug_data;
Ent *e0 = sim_ent_from_id(ss, dbg->e0);
Ent *e1 = sim_ent_from_id(ss, dbg->e1);
Entity *e0 = sim_ent_from_id(ss, dbg->e0);
Entity *e1 = sim_ent_from_id(ss, dbg->e1);
if (!(sim_ent_should_simulate(e0) && sim_ent_should_simulate(e1)) ||
!(sim_ent_has_prop(e0, SEPROP_SOLID) || sim_ent_has_prop(e0, SEPROP_SENSOR)) ||
@ -380,15 +380,15 @@ void phys_warm_start_contacts(PhysStepCtx *ctx)
__prof;
Snapshot *ss = ctx->sim_step_ctx->world;
for (u64 sim_ent_index = 0; sim_ent_index < ss->num_ents_reserved; ++sim_ent_index) {
Ent *constraint_ent = &ss->ents[sim_ent_index];
Entity *constraint_ent = &ss->ents[sim_ent_index];
if (!sim_ent_should_simulate(constraint_ent)) continue;
if (!sim_ent_has_prop(constraint_ent, SEPROP_CONTACT_CONSTRAINT)) continue;
ContactConstraint *constraint = &constraint_ent->contact_constraint_data;
u32 num_points = constraint->num_points;
Ent *e0 = sim_ent_from_id(ss, constraint->e0);
Ent *e1 = sim_ent_from_id(ss, constraint->e1);
Entity *e0 = sim_ent_from_id(ss, constraint->e0);
Entity *e1 = sim_ent_from_id(ss, constraint->e1);
if (num_points > 0 && sim_ent_is_valid_and_active(e0) && sim_ent_is_valid_and_active(e1) && !constraint->skip_solve && !constraint->wrong_dir) {
f32 inv_m0 = constraint->inv_m0;
@ -432,14 +432,14 @@ void phys_solve_contacts(PhysStepCtx *ctx, f32 dt, b32 apply_bias)
__prof;
Snapshot *ss = ctx->sim_step_ctx->world;
for (u64 sim_ent_index = 0; sim_ent_index < ss->num_ents_reserved; ++sim_ent_index) {
Ent *constraint_ent = &ss->ents[sim_ent_index];
Entity *constraint_ent = &ss->ents[sim_ent_index];
if (!sim_ent_should_simulate(constraint_ent)) continue;
if (!sim_ent_has_prop(constraint_ent, SEPROP_CONTACT_CONSTRAINT)) continue;
ContactConstraint *constraint = &constraint_ent->contact_constraint_data;
Ent *e0 = sim_ent_from_id(ss, constraint->e0);
Ent *e1 = sim_ent_from_id(ss, constraint->e1);
Entity *e0 = sim_ent_from_id(ss, constraint->e0);
Entity *e1 = sim_ent_from_id(ss, constraint->e1);
Vec2 v0 = e0->linear_velocity;
Vec2 v1 = e1->linear_velocity;
@ -570,14 +570,14 @@ void phys_prepare_motor_joints(PhysStepCtx *ctx)
__prof;
Snapshot *ss = ctx->sim_step_ctx->world;
for (u64 sim_ent_index = 0; sim_ent_index < ss->num_ents_reserved; ++sim_ent_index) {
Ent *joint_ent = &ss->ents[sim_ent_index];
Entity *joint_ent = &ss->ents[sim_ent_index];
if (!sim_ent_should_simulate(joint_ent)) continue;
if (!sim_ent_has_prop(joint_ent, SEPROP_MOTOR_JOINT)) continue;
MotorJoint *joint = &joint_ent->motor_joint_data;
Ent *e0 = sim_ent_from_id(ss, joint->e0);
Ent *e1 = sim_ent_from_id(ss, joint->e1);
Entity *e0 = sim_ent_from_id(ss, joint->e0);
Entity *e1 = sim_ent_from_id(ss, joint->e1);
if (sim_ent_should_simulate(e0) && sim_ent_should_simulate(e1)) {
Xform e0_xf = sim_ent_get_xform(e0);
@ -634,14 +634,14 @@ void phys_warm_start_motor_joints(PhysStepCtx *ctx)
__prof;
Snapshot *ss = ctx->sim_step_ctx->world;
for (u64 sim_ent_index = 0; sim_ent_index < ss->num_ents_reserved; ++sim_ent_index) {
Ent *joint_ent = &ss->ents[sim_ent_index];
Entity *joint_ent = &ss->ents[sim_ent_index];
if (!sim_ent_should_simulate(joint_ent)) continue;
if (!sim_ent_has_prop(joint_ent, SEPROP_MOTOR_JOINT)) continue;
MotorJoint *joint = &joint_ent->motor_joint_data;
Ent *e0 = sim_ent_from_id(ss, joint->e0);
Ent *e1 = sim_ent_from_id(ss, joint->e1);
Entity *e0 = sim_ent_from_id(ss, joint->e0);
Entity *e1 = sim_ent_from_id(ss, joint->e1);
Xform e0_xf = sim_ent_get_xform(e0);
Xform e1_xf = sim_ent_get_xform(e1);
@ -666,14 +666,14 @@ void phys_solve_motor_joints(PhysStepCtx *ctx, f32 dt)
__prof;
Snapshot *ss = ctx->sim_step_ctx->world;
for (u64 sim_ent_index = 0; sim_ent_index < ss->num_ents_reserved; ++sim_ent_index) {
Ent *joint_ent = &ss->ents[sim_ent_index];
Entity *joint_ent = &ss->ents[sim_ent_index];
if (!sim_ent_should_simulate(joint_ent)) continue;
if (!sim_ent_has_prop(joint_ent, SEPROP_MOTOR_JOINT)) continue;
MotorJoint *joint = &joint_ent->motor_joint_data;
Ent *e0 = sim_ent_from_id(ss, joint->e0);
Ent *e1 = sim_ent_from_id(ss, joint->e1);
Entity *e0 = sim_ent_from_id(ss, joint->e0);
Entity *e1 = sim_ent_from_id(ss, joint->e1);
Xform e0_xf = sim_ent_get_xform(e0);
Xform e1_xf = sim_ent_get_xform(e1);
@ -772,12 +772,12 @@ void phys_prepare_mouse_joints(PhysStepCtx *ctx)
__prof;
Snapshot *ss = ctx->sim_step_ctx->world;
for (u64 sim_ent_index = 0; sim_ent_index < ss->num_ents_reserved; ++sim_ent_index) {
Ent *joint_ent = &ss->ents[sim_ent_index];
Entity *joint_ent = &ss->ents[sim_ent_index];
if (!sim_ent_should_simulate(joint_ent)) continue;
if (!sim_ent_has_prop(joint_ent, SEPROP_MOUSE_JOINT)) continue;
MouseJoint *joint = &joint_ent->mouse_joint_data;
Ent *ent = sim_ent_from_id(ss, joint->target);
Entity *ent = sim_ent_from_id(ss, joint->target);
if (sim_ent_should_simulate(ent)) {
Xform xf = sim_ent_get_xform(ent);
@ -819,12 +819,12 @@ void phys_warm_start_mouse_joints(PhysStepCtx *ctx)
__prof;
Snapshot *ss = ctx->sim_step_ctx->world;
for (u64 sim_ent_index = 0; sim_ent_index < ss->num_ents_reserved; ++sim_ent_index) {
Ent *joint_ent = &ss->ents[sim_ent_index];
Entity *joint_ent = &ss->ents[sim_ent_index];
if (!sim_ent_should_simulate(joint_ent)) continue;
if (!sim_ent_has_prop(joint_ent, SEPROP_MOUSE_JOINT)) continue;
MouseJoint *joint = &joint_ent->mouse_joint_data;
Ent *ent = sim_ent_from_id(ss, joint->target);
Entity *ent = sim_ent_from_id(ss, joint->target);
if (sim_ent_should_simulate(ent)) {
f32 inv_m = joint->inv_m;
f32 inv_i = joint->inv_i;
@ -841,12 +841,12 @@ void phys_solve_mouse_joints(PhysStepCtx *ctx, f32 dt)
__prof;
Snapshot *ss = ctx->sim_step_ctx->world;
for (u64 sim_ent_index = 0; sim_ent_index < ss->num_ents_reserved; ++sim_ent_index) {
Ent *joint_ent = &ss->ents[sim_ent_index];
Entity *joint_ent = &ss->ents[sim_ent_index];
if (!sim_ent_should_simulate(joint_ent)) continue;
if (!sim_ent_has_prop(joint_ent, SEPROP_MOUSE_JOINT)) continue;
MouseJoint *joint = &joint_ent->mouse_joint_data;
Ent *ent = sim_ent_from_id(ss, joint->target);
Entity *ent = sim_ent_from_id(ss, joint->target);
if (sim_ent_should_simulate(ent)) {
Vec2 v = ent->linear_velocity;
f32 w = ent->angular_velocity;
@ -937,15 +937,15 @@ void phys_prepare_weld_joints(PhysStepCtx *ctx)
__prof;
Snapshot *ss = ctx->sim_step_ctx->world;
for (u64 sim_ent_index = 0; sim_ent_index < ss->num_ents_reserved; ++sim_ent_index) {
Ent *joint_ent = &ss->ents[sim_ent_index];
Entity *joint_ent = &ss->ents[sim_ent_index];
if (!sim_ent_should_simulate(joint_ent)) continue;
if (!sim_ent_has_prop(joint_ent, SEPROP_WELD_JOINT)) continue;
/* TODO: Lookup and disable collision for any contacts between e0 & e1? */
WeldJoint *joint = &joint_ent->weld_joint_data;
Ent *e0 = sim_ent_from_id(ss, joint->e0);
Ent *e1 = sim_ent_from_id(ss, joint->e1);
Entity *e0 = sim_ent_from_id(ss, joint->e0);
Entity *e1 = sim_ent_from_id(ss, joint->e1);
if (sim_ent_should_simulate(e0) && sim_ent_should_simulate(e1)) {
Xform e0_xf = sim_ent_get_xform(e0);
Xform e1_xf = sim_ent_get_xform(e1);
@ -986,14 +986,14 @@ void phys_warm_start_weld_joints(PhysStepCtx *ctx)
__prof;
Snapshot *ss = ctx->sim_step_ctx->world;
for (u64 sim_ent_index = 0; sim_ent_index < ss->num_ents_reserved; ++sim_ent_index) {
Ent *joint_ent = &ss->ents[sim_ent_index];
Entity *joint_ent = &ss->ents[sim_ent_index];
if (!sim_ent_should_simulate(joint_ent)) continue;
if (!sim_ent_has_prop(joint_ent, SEPROP_WELD_JOINT)) continue;
WeldJoint *joint = &joint_ent->weld_joint_data;
#if 0
Ent *e0 = sim_ent_from_id(ss, joint->e0);
Entity *e0 = sim_ent_from_id(ss, joint->e0);
if (sim_ent_should_simulate(e0)) {
f32 inv_m = joint->inv_m0;
f32 inv_i = joint->inv_i0;
@ -1005,7 +1005,7 @@ void phys_warm_start_weld_joints(PhysStepCtx *ctx)
#endif
#if 1
Ent *e1 = sim_ent_from_id(ss, joint->e1);
Entity *e1 = sim_ent_from_id(ss, joint->e1);
if (sim_ent_should_simulate(e1)) {
f32 inv_m = joint->inv_m1;
f32 inv_i = joint->inv_i1;
@ -1023,13 +1023,13 @@ void phys_solve_weld_joints(PhysStepCtx *ctx, f32 dt)
__prof;
Snapshot *ss = ctx->sim_step_ctx->world;
for (u64 sim_ent_index = 0; sim_ent_index < ss->num_ents_reserved; ++sim_ent_index) {
Ent *joint_ent = &ss->ents[sim_ent_index];
Entity *joint_ent = &ss->ents[sim_ent_index];
if (!sim_ent_should_simulate(joint_ent)) continue;
if (!sim_ent_has_prop(joint_ent, SEPROP_WELD_JOINT)) continue;
WeldJoint *joint = &joint_ent->weld_joint_data;
Ent *e0 = sim_ent_from_id(ss, joint->e0);
Ent *e1 = sim_ent_from_id(ss, joint->e1);
Entity *e0 = sim_ent_from_id(ss, joint->e0);
Entity *e1 = sim_ent_from_id(ss, joint->e1);
if (sim_ent_should_simulate(e0) && sim_ent_should_simulate(e1)) {
Xform xf0 = sim_ent_get_xform(e0);
Xform xf1 = sim_ent_get_xform(e1);
@ -1086,7 +1086,7 @@ void phys_solve_weld_joints(PhysStepCtx *ctx, f32 dt)
* Integration
* ========================== */
internal Xform get_derived_xform(Ent *ent, f32 dt)
internal Xform get_derived_xform(Entity *ent, f32 dt)
{
Xform xf = sim_ent_get_xform(ent);
@ -1103,7 +1103,7 @@ void phys_integrate_forces(PhysStepCtx *ctx, f32 dt)
__prof;
Snapshot *ss = ctx->sim_step_ctx->world;
for (u64 sim_ent_index = 0; sim_ent_index < ss->num_ents_reserved; ++sim_ent_index) {
Ent *ent = &ss->ents[sim_ent_index];
Entity *ent = &ss->ents[sim_ent_index];
if (!sim_ent_should_simulate(ent)) continue;
b32 is_dynamic = sim_ent_has_prop(ent, SEPROP_DYNAMIC);
@ -1145,7 +1145,7 @@ void phys_integrate_velocities(PhysStepCtx *ctx, f32 dt)
__prof;
Snapshot *ss = ctx->sim_step_ctx->world;
for (u64 sim_ent_index = 0; sim_ent_index < ss->num_ents_reserved; ++sim_ent_index) {
Ent *ent = &ss->ents[sim_ent_index];
Entity *ent = &ss->ents[sim_ent_index];
if (!sim_ent_should_simulate(ent)) continue;
if (!sim_ent_has_prop(ent, SEPROP_DYNAMIC) && !sim_ent_has_prop(ent, SEPROP_KINEMATIC)) continue;
@ -1166,7 +1166,7 @@ f32 phys_determine_earliest_toi(PhysStepCtx *ctx, f32 step_dt, f32 tolerance, u3
f32 smallest_t = 1;
for (u64 e0_index = 0; e0_index < ss->num_ents_reserved; ++e0_index) {
Ent *e0 = &ss->ents[e0_index];
Entity *e0 = &ss->ents[e0_index];
if (!sim_ent_should_simulate(e0)) continue;
if (!(sim_ent_has_prop(e0, SEPROP_SOLID) || sim_ent_has_prop(e0, SEPROP_SENSOR))) continue;
if (!sim_ent_has_prop(e0, SEPROP_TOI)) continue;
@ -1184,7 +1184,7 @@ f32 phys_determine_earliest_toi(PhysStepCtx *ctx, f32 step_dt, f32 tolerance, u3
SpaceIter iter = space_iter_begin_aabb(space, combined_aabb);
SpaceEntry *entry;
while ((entry = space_iter_next(&iter)) != 0) {
Ent *e1 = sim_ent_from_id(ss, entry->ent);
Entity *e1 = sim_ent_from_id(ss, entry->ent);
if (!sim_ent_should_simulate(e1)) continue;
if (!(sim_ent_has_prop(e1, SEPROP_SOLID) || sim_ent_has_prop(e1, SEPROP_SENSOR))) continue;
if (e1->local_collider.count <= 0) continue;
@ -1215,7 +1215,7 @@ void phys_update_aabbs(PhysStepCtx *ctx)
Snapshot *ss = ctx->sim_step_ctx->world;
Space *space = ctx->sim_step_ctx->accel->space;
for (u64 sim_ent_index = 0; sim_ent_index < ss->num_ents_reserved; ++sim_ent_index) {
Ent *ent = &ss->ents[sim_ent_index];
Entity *ent = &ss->ents[sim_ent_index];
if (!sim_ent_is_valid_and_active(ent)) continue;
if (ent->local_collider.count > 0) {
Xform xf = sim_ent_get_xform(ent);

View File

@ -1,7 +1,7 @@
typedef struct CollisionData CollisionData;
struct CollisionData {
EntId e0;
EntId e1;
EntityId e0;
EntityId e1;
Vec2 point;
Vec2 normal; /* Normal of the collision from e0 to e1 */
Vec2 vrel; /* Relative velocity at point of collision */
@ -56,8 +56,8 @@ struct ContactConstraint {
u64 last_phys_iteration; /* To avoid checking collisions for the same constraint twice in one tick */
b32 skip_solve;
b32 wrong_dir;
EntId e0;
EntId e1;
EntityId e0;
EntityId e1;
f32 inv_m0;
f32 inv_m1;
f32 inv_i0;
@ -75,8 +75,8 @@ struct ContactConstraint {
typedef struct CollisionDebugData CollisionDebugData;
struct CollisionDebugData {
EntId e0;
EntId e1;
EntityId e0;
EntityId e1;
CLD_CollisionData collision_result;
ContactPoint points[2];
@ -100,8 +100,8 @@ void phys_solve_contacts(PhysStepCtx *ctx, f32 dt, b32 apply_bias);
typedef struct MotorJointDesc MotorJointDesc;
struct MotorJointDesc {
EntId e0;
EntId e1;
EntityId e0;
EntityId e1;
f32 correction_rate;
f32 max_force;
f32 max_torque;
@ -109,8 +109,8 @@ struct MotorJointDesc {
typedef struct MotorJoint MotorJoint;
struct MotorJoint {
EntId e0;
EntId e1;
EntityId e0;
EntityId e1;
f32 correction_rate;
f32 max_force;
f32 max_torque;
@ -142,7 +142,7 @@ void phys_solve_motor_joints(PhysStepCtx *ctx, f32 dt);
typedef struct MouseJointDesc MouseJointDesc;
struct MouseJointDesc {
EntId target;
EntityId target;
Vec2 point_local_start;
Vec2 point_end;
f32 linear_spring_hz;
@ -154,7 +154,7 @@ struct MouseJointDesc {
typedef struct MouseJoint MouseJoint;
struct MouseJoint {
EntId target;
EntityId target;
Vec2 point_local_start;
Vec2 point_end;
f32 linear_spring_hz;
@ -184,8 +184,8 @@ void phys_solve_mouse_joints(PhysStepCtx *ctx, f32 dt);
typedef struct WeldJointDesc WeldJointDesc;
struct WeldJointDesc {
EntId e0;
EntId e1;
EntityId e0;
EntityId e1;
/* The xform that transforms a point in e0's space into the desired e1 space
* (IE `xf` * VEC2(0, 0) should evaluate to the local point that e1's origin will lie) */
@ -199,8 +199,8 @@ struct WeldJointDesc {
typedef struct WeldJoint WeldJoint;
struct WeldJoint {
EntId e0;
EntId e1;
EntityId e0;
EntityId e1;
Xform xf0_to_xf1;
f32 linear_spring_hz;

View File

@ -267,7 +267,7 @@ SpaceEntry *space_entry_from_handle(Space *space, SpaceEntryHandle handle)
return entry;
}
SpaceEntry *space_entry_alloc(Space *space, EntId ent)
SpaceEntry *space_entry_alloc(Space *space, EntityId ent)
{
SpaceEntry *entry = 0;
SpaceEntryHandle handle = ZI;

View File

@ -14,7 +14,7 @@ struct SpaceEntry {
SpaceCellNode *last_node;
Aabb aabb;
EntId ent;
EntityId ent;
SpaceEntry *next_free;
};
@ -131,7 +131,7 @@ SpaceCell *space_get_cell(Space *space, Vec2I32 cell_pos);
* ========================== */
SpaceEntry *space_entry_from_handle(Space *space, SpaceEntryHandle handle);
SpaceEntry *space_entry_alloc(Space *space, EntId entity);
SpaceEntry *space_entry_alloc(Space *space, EntityId entity);
void space_entry_release(SpaceEntry *entry);
void space_entry_update_aabb(SpaceEntry *entry, Aabb new_aabb);

View File

@ -20,7 +20,7 @@ void sim_accel_reset(Snapshot *ss, SimAccel *accel)
/* Reset ent space handles */
for (u64 sim_ent_index = 0; sim_ent_index < ss->num_ents_reserved; ++sim_ent_index) {
Ent *ent = &ss->ents[sim_ent_index];
Entity *ent = &ss->ents[sim_ent_index];
if (ent->valid) {
ZeroStruct(&ent->space_handle);
}
@ -33,9 +33,9 @@ void sim_accel_reset(Snapshot *ss, SimAccel *accel)
/* TODO: Remove this */
internal Ent *test_spawn_smg(Ent *parent)
internal Entity *test_spawn_smg(Entity *parent)
{
Ent *e = sim_ent_alloc_sync_src(parent);
Entity *e = sim_ent_alloc_sync_src(parent);
e->sprite = S_TagFromPath(Lit("sprite/gun.ase"));
sim_ent_enable_prop(e, SEPROP_ATTACHED);
@ -49,9 +49,9 @@ internal Ent *test_spawn_smg(Ent *parent)
return e;
}
internal Ent *test_spawn_launcher(Ent *parent)
internal Entity *test_spawn_launcher(Entity *parent)
{
Ent *e = sim_ent_alloc_sync_src(parent);
Entity *e = sim_ent_alloc_sync_src(parent);
e->sprite = S_TagFromPath(Lit("sprite/gun.ase"));
sim_ent_enable_prop(e, SEPROP_ATTACHED);
@ -65,9 +65,9 @@ internal Ent *test_spawn_launcher(Ent *parent)
return e;
}
internal Ent *test_spawn_chucker(Ent *parent)
internal Entity *test_spawn_chucker(Entity *parent)
{
Ent *chucker = sim_ent_alloc_sync_src(parent);
Entity *chucker = sim_ent_alloc_sync_src(parent);
chucker->sprite = S_TagFromPath(Lit("sprite/gun.ase"));
sim_ent_enable_prop(chucker, SEPROP_ATTACHED);
@ -80,7 +80,7 @@ internal Ent *test_spawn_chucker(Ent *parent)
/* Chucker zone */
{
Ent *zone = sim_ent_alloc_sync_src(chucker);
Entity *zone = sim_ent_alloc_sync_src(chucker);
sim_ent_enable_prop(zone, SEPROP_CHUCKER_ZONE);
@ -100,13 +100,13 @@ internal Ent *test_spawn_chucker(Ent *parent)
return chucker;
}
internal Ent *test_spawn_employee(Ent *parent)
internal Entity *test_spawn_employee(Entity *parent)
{
/* Player */
Ent *employee = sim_ent_nil();
Entity *employee = sim_ent_nil();
{
Ent *e = sim_ent_alloc_sync_src(parent);
Entity *e = sim_ent_alloc_sync_src(parent);
Vec2 pos = VEC2(1, -1);
@ -174,7 +174,7 @@ internal Ent *test_spawn_employee(Ent *parent)
(UNUSED)test_spawn_launcher;
(UNUSED)test_spawn_chucker;
Ent *e = test_spawn_chucker(employee);
Entity *e = test_spawn_chucker(employee);
employee->equipped = e->id;
sim_ent_enable_prop(e, SEPROP_LIGHT_TEST);
@ -184,9 +184,9 @@ internal Ent *test_spawn_employee(Ent *parent)
return employee;
}
internal Ent *test_spawn_camera(Ent *parent, Ent *follow)
internal Entity *test_spawn_camera(Entity *parent, Entity *follow)
{
Ent *camera_ent = sim_ent_nil();
Entity *camera_ent = sim_ent_nil();
if (follow->valid) {
camera_ent = sim_ent_alloc_sync_src(parent);
sim_ent_set_xform(camera_ent, XformIdentity);
@ -203,9 +203,9 @@ internal Ent *test_spawn_camera(Ent *parent, Ent *follow)
return camera_ent;
}
internal Ent *test_spawn_explosion(Ent *parent, Vec2 pos, f32 strength, f32 radius)
internal Entity *test_spawn_explosion(Entity *parent, Vec2 pos, f32 strength, f32 radius)
{
Ent *ent = sim_ent_alloc_sync_src(parent);
Entity *ent = sim_ent_alloc_sync_src(parent);
sim_ent_set_xform(ent, XformFromPos(pos));
sim_ent_enable_prop(ent, SEPROP_EXPLOSION);
@ -219,7 +219,7 @@ internal Ent *test_spawn_explosion(Ent *parent, Vec2 pos, f32 strength, f32 radi
return ent;
}
internal void test_teleport(Ent *ent, Vec2 pos)
internal void test_teleport(Entity *ent, Vec2 pos)
{
//++ent->continuity_gen;
Xform xf = sim_ent_get_xform(ent);
@ -227,28 +227,28 @@ internal void test_teleport(Ent *ent, Vec2 pos)
sim_ent_set_xform(ent, xf);
}
internal void test_spawn_entities1(Ent *parent, Vec2 pos)
internal void test_spawn_entities1(Entity *parent, Vec2 pos)
{
(UNUSED)pos;
/* Enemy */
{
Ent *e = test_spawn_employee(parent);
Entity *e = test_spawn_employee(parent);
Xform xf = sim_ent_get_xform(e);
xf.og = pos;
sim_ent_set_xform(e, xf);
}
}
internal void test_spawn_entities2(Ent *parent, Vec2 pos)
internal void test_spawn_entities2(Entity *parent, Vec2 pos)
{
(UNUSED)pos;
/* Small Box */
#if 1
{
//Ent *e = sim_ent_alloc_local(parent);
Ent *e = sim_ent_alloc_sync_src(parent);
//Entity *e = sim_ent_alloc_local(parent);
Entity *e = sim_ent_alloc_sync_src(parent);
f32 rot = 0;
Vec2 size = VEC2(0.125, 0.125);
@ -290,7 +290,7 @@ internal void test_spawn_entities2(Ent *parent, Vec2 pos)
/* Tiny box */
#if 0
{
Ent *e = sim_ent_alloc_sync_src(parent);
Entity *e = sim_ent_alloc_sync_src(parent);
f32 r = Pi / 4;
Vec2 size = VEC2(0.5, 0.25);
@ -311,14 +311,14 @@ internal void test_spawn_entities2(Ent *parent, Vec2 pos)
#endif
}
internal void test_spawn_entities3(Ent *parent, Vec2 pos)
internal void test_spawn_entities3(Entity *parent, Vec2 pos)
{
(UNUSED)pos;
/* Heavy box */
{
//Ent *e = sim_ent_alloc_local(parent);
Ent *e = sim_ent_alloc_sync_src(parent);
//Entity *e = sim_ent_alloc_local(parent);
Entity *e = sim_ent_alloc_sync_src(parent);
f32 r = 0;
Vec2 size = VEC2(1, 1);
@ -336,12 +336,12 @@ internal void test_spawn_entities3(Ent *parent, Vec2 pos)
}
}
internal void test_spawn_entities4(Ent *parent, Vec2 pos)
internal void test_spawn_entities4(Entity *parent, Vec2 pos)
{
(UNUSED)pos;
/* Light box */
Ent *e = sim_ent_alloc_sync_src(parent);
Entity *e = sim_ent_alloc_sync_src(parent);
f32 r = 0;
Vec2 size = VEC2(2, 1);
@ -361,7 +361,7 @@ internal void test_spawn_entities4(Ent *parent, Vec2 pos)
internal void test_spawn_tile(Snapshot *world, Vec2 world_pos)
{
#if 0
Ent *e = sim_ent_alloc_sync_src(parent);
Entity *e = sim_ent_alloc_sync_src(parent);
i32 sign_x = (world_pos.x >= 0) - (world_pos.x < 0);
i32 sign_y = (world_pos.y >= 0) - (world_pos.y < 0);
@ -407,8 +407,8 @@ internal void test_spawn_tile(Snapshot *world, Vec2 world_pos)
internal MergesortCompareFuncDef(tile_chunk_sort_x, arg_a, arg_b, _)
{
Ent *a = *(Ent **)arg_a;
Ent *b = *(Ent **)arg_b;
Entity *a = *(Entity **)arg_a;
Entity *b = *(Entity **)arg_b;
i32 a_x = a->tile_chunk_index.x;
i32 b_x = b->tile_chunk_index.x;
@ -419,8 +419,8 @@ internal MergesortCompareFuncDef(tile_chunk_sort_x, arg_a, arg_b, _)
internal MergesortCompareFuncDef(tile_chunk_sort_y, arg_a, arg_b, _)
{
Ent *a = *(Ent **)arg_a;
Ent *b = *(Ent **)arg_b;
Entity *a = *(Entity **)arg_a;
Entity *b = *(Entity **)arg_b;
i32 a_y = a->tile_chunk_index.y;
i32 b_y = b->tile_chunk_index.y;
@ -433,29 +433,29 @@ internal void test_generate_walls(Snapshot *world)
{
__prof;
TempArena scratch = BeginScratchNoConflict();
Ent *root = sim_ent_from_id(world, SIM_ENT_ROOT_ID);
Entity *root = sim_ent_from_id(world, SIM_ENT_ROOT_ID);
/* Release existing walls and gather tile chunks.
* NOTE: We sort tile chunks before iterating so that chunk-edge tiles only
* need to check for adjacent walls to merge with in one direction */
Ent **x_sorted_tile_chunks = 0;
Ent **y_sorted_tile_chunks = 0;
Entity **x_sorted_tile_chunks = 0;
Entity **y_sorted_tile_chunks = 0;
u64 sorted_tile_chunks_count = 0;
{
x_sorted_tile_chunks = PushDry(scratch.arena, Ent *);
x_sorted_tile_chunks = PushDry(scratch.arena, Entity *);
for (u64 ent_index = 0; ent_index < world->num_ents_reserved; ++ent_index) {
Ent *ent = &world->ents[ent_index];
Entity *ent = &world->ents[ent_index];
if (!ent->valid) continue;
if (sim_ent_has_prop(ent, SEPROP_TILE_CHUNK)) {
/* Append chunk to array */
*PushStructNoZero(scratch.arena, Ent *) = ent;
*PushStructNoZero(scratch.arena, Entity *) = ent;
++sorted_tile_chunks_count;
} else if (sim_ent_has_prop(ent, SEPROP_WALL)) {
/* Release existing wall */
sim_ent_enable_prop(ent, SEPROP_RELEASE);
}
}
y_sorted_tile_chunks = PushStructsNoZero(scratch.arena, Ent *, sorted_tile_chunks_count);
y_sorted_tile_chunks = PushStructsNoZero(scratch.arena, Entity *, sorted_tile_chunks_count);
CopyBytes(y_sorted_tile_chunks, x_sorted_tile_chunks, sizeof(*x_sorted_tile_chunks) * sorted_tile_chunks_count);
/* NOTE: We sort x & y separately because it's possible that a wall
@ -480,10 +480,10 @@ internal void test_generate_walls(Snapshot *world)
/* Generate horizontal wall nodes */
for (u64 sorted_index = 0; sorted_index < sorted_tile_chunks_count; ++sorted_index) {
Ent *chunk = x_sorted_tile_chunks[sorted_index];
Entity *chunk = x_sorted_tile_chunks[sorted_index];
Vec2I32 chunk_index = chunk->tile_chunk_index;
Ent *top_chunk = sim_tile_chunk_from_chunk_index(world, VEC2I32(chunk_index.x, chunk_index.y - 1));
Ent *bottom_chunk = sim_tile_chunk_from_chunk_index(world, VEC2I32(chunk_index.x, chunk_index.y + 1));
Entity *top_chunk = sim_tile_chunk_from_chunk_index(world, VEC2I32(chunk_index.x, chunk_index.y - 1));
Entity *bottom_chunk = sim_tile_chunk_from_chunk_index(world, VEC2I32(chunk_index.x, chunk_index.y + 1));
/* If there's no chunk below this one, then do an extra iteration (since walls are created at the top of each tile) */
i32 y_iterations = SIM_TILES_PER_CHUNK_SQRT + !bottom_chunk->valid;
i32 x_iterations = SIM_TILES_PER_CHUNK_SQRT + 1;
@ -569,10 +569,10 @@ internal void test_generate_walls(Snapshot *world)
/* Generate vertical wall nodes */
for (u64 sorted_index = 0; sorted_index < sorted_tile_chunks_count; ++sorted_index) {
Ent *chunk = y_sorted_tile_chunks[sorted_index];
Entity *chunk = y_sorted_tile_chunks[sorted_index];
Vec2I32 chunk_index = chunk->tile_chunk_index;
Ent *left_chunk = sim_tile_chunk_from_chunk_index(world, VEC2I32(chunk_index.x - 1, chunk_index.y));
Ent *right_chunk = sim_tile_chunk_from_chunk_index(world, VEC2I32(chunk_index.x + 1, chunk_index.y));
Entity *left_chunk = sim_tile_chunk_from_chunk_index(world, VEC2I32(chunk_index.x - 1, chunk_index.y));
Entity *right_chunk = sim_tile_chunk_from_chunk_index(world, VEC2I32(chunk_index.x + 1, chunk_index.y));
/* If there's no chunk to the right of this one, then do an extra iteration (since walls are created on the left of each tile) */
i32 y_iterations = SIM_TILES_PER_CHUNK_SQRT + 1;
i32 x_iterations = SIM_TILES_PER_CHUNK_SQRT + !right_chunk->valid;
@ -659,7 +659,7 @@ internal void test_generate_walls(Snapshot *world)
/* Create wall entities */
for (struct wall_node *node = first_wall; node; node = node->next) {
Ent *wall_ent = sim_ent_alloc_sync_src(root);
Entity *wall_ent = sim_ent_alloc_sync_src(root);
sim_ent_enable_prop(wall_ent, SEPROP_WALL);
Vec2 start = sim_pos_from_world_tile_index(node->start);
@ -697,7 +697,7 @@ internal void test_clear_level(SimStepCtx *ctx)
{
Snapshot *world = ctx->world;
for (u64 j = 0; j < world->num_ents_reserved; ++j) {
Ent *ent = &world->ents[j];
Entity *ent = &world->ents[j];
if (ent->valid) {
sim_ent_enable_prop(ent, SEPROP_RELEASE);
}
@ -711,9 +711,9 @@ internal void test_clear_level(SimStepCtx *ctx)
internal PHYS_COLLISION_CALLBACK_FUNC_DEF(on_collision, data, step_ctx)
{
Snapshot *world = step_ctx->world;
Ent *e0 = sim_ent_from_id(world, data->e0);
Ent *e1 = sim_ent_from_id(world, data->e1);
Ent *root = sim_ent_from_id(world, SIM_ENT_ROOT_ID);
Entity *e0 = sim_ent_from_id(world, data->e0);
Entity *e1 = sim_ent_from_id(world, data->e1);
Entity *root = sim_ent_from_id(world, SIM_ENT_ROOT_ID);
b32 skip_solve = 0;
if (sim_ent_should_simulate(e0) && sim_ent_should_simulate(e1)) {
@ -722,16 +722,16 @@ internal PHYS_COLLISION_CALLBACK_FUNC_DEF(on_collision, data, step_ctx)
Vec2 normal = data->normal; /* Impact normal */
Vec2 vrel = data->vrel; /* Impact velocity */
Ent *bullet = e0;
Ent *target = e1;
Ent *src = sim_ent_from_id(world, bullet->bullet_src);
Entity *bullet = e0;
Entity *target = e1;
Entity *src = sim_ent_from_id(world, bullet->bullet_src);
/* Process collision if bullet already spent or * target share same top level parent */
if (!bullet->bullet_has_hit && !sim_ent_id_eq(src->top, target->top) && sim_ent_has_prop(target, SEPROP_SOLID)) {
Vec2 point = data->point;
/* Update tracer */
Ent *tracer = sim_ent_from_id(world, bullet->bullet_tracer);
Entity *tracer = sim_ent_from_id(world, bullet->bullet_tracer);
if (sim_ent_should_simulate(tracer)) {
Xform xf = sim_ent_get_xform(tracer);
xf.og = point;
@ -747,7 +747,7 @@ internal PHYS_COLLISION_CALLBACK_FUNC_DEF(on_collision, data, step_ctx)
/* TODO: Remove this */
{
Xform xf = XformFromTrs(TRS(.t = point, .r = RandF64FromState(&step_ctx->rand, 0, Tau)));
Ent *decal = sim_ent_alloc_sync_src(root);
Entity *decal = sim_ent_alloc_sync_src(root);
decal->sprite = S_TagFromPath(Lit("sprite/blood.ase"));
decal->sprite_tint = Rgba32F(1, 1, 1, 0.25f);
decal->layer = SIM_LAYER_FLOOR_DECALS;
@ -781,8 +781,8 @@ internal PHYS_COLLISION_CALLBACK_FUNC_DEF(on_collision, data, step_ctx)
/* Explosion blast collision */
if (sim_ent_has_prop(e0, SEPROP_EXPLOSION)) {
Ent *exp = e0;
Ent *victim = e1;
Entity *exp = e0;
Entity *victim = e1;
Xform xf = sim_ent_get_xform(exp);
@ -860,7 +860,7 @@ void sim_step(SimStepCtx *ctx)
S_Scope *sprite_frame_scope = S_BeginScope();
Ent *root = sim_ent_from_id(world, SIM_ENT_ROOT_ID);
Entity *root = sim_ent_from_id(world, SIM_ENT_ROOT_ID);
root->owner = world->client->player_id;
/* ========================== *
@ -872,7 +872,7 @@ void sim_step(SimStepCtx *ctx)
for (u64 client_index = 0; client_index < client_store->num_clients_reserved; ++client_index) {
Client *client = &client_store->clients[client_index];
if (client->valid && client != master_client && client != world_client && client != publish_client) {
Ent *player = sim_ent_from_id(world, client->player_id);
Entity *player = sim_ent_from_id(world, client->player_id);
/* Create player if necessary */
if (is_master && !player->valid) {
@ -912,7 +912,7 @@ void sim_step(SimStepCtx *ctx)
/* Mark all incoming ents as sync dsts */
for (u64 i = 0; i < world->num_ents_reserved; ++i) {
Ent *ent = &world->ents[i];
Entity *ent = &world->ents[i];
if (ent->valid && sim_ent_has_prop(ent, SEPROP_SYNC_SRC) && !sim_ent_id_eq(ent->owner, world_client->player_id)) {
sim_ent_disable_prop(ent, SEPROP_SYNC_SRC);
sim_ent_enable_prop(ent, SEPROP_SYNC_DST);
@ -921,7 +921,7 @@ void sim_step(SimStepCtx *ctx)
/* Mark incoming cmds with correct client */
for (u64 i = 0; i < world->num_ents_reserved; ++i) {
Ent *ent = &world->ents[i];
Entity *ent = &world->ents[i];
if (ent->valid && sim_ent_has_prop(ent, SEPROP_CMD) && sim_ent_has_prop(ent, SEPROP_SYNC_DST)) {
ent->cmd_player = ent->owner;
}
@ -930,7 +930,7 @@ void sim_step(SimStepCtx *ctx)
/* Mark any locally created CMDs as sync sources */
if (!is_master) {
for (u64 i = 0; i < world->num_ents_reserved; ++i) {
Ent *ent = &world->ents[i];
Entity *ent = &world->ents[i];
if (sim_ent_is_valid_and_active(ent) && sim_ent_has_prop(ent, SEPROP_CMD)) {
if (!sim_ent_id_is_nil(ent->cmd_player) && sim_ent_id_eq(ent->cmd_player, world->local_player)) {
sim_ent_enable_prop(ent, SEPROP_SYNC_SRC);
@ -952,7 +952,7 @@ void sim_step(SimStepCtx *ctx)
* ========================== */
for (u64 ent_index = 0; ent_index < world->num_ents_reserved; ++ent_index) {
Ent *ent = &world->ents[ent_index];
Entity *ent = &world->ents[ent_index];
if (!ent->valid) continue;
if (sim_ent_has_prop(ent, SEPROP_SYNC_DST) && !sim_ent_is_owner(ent) && !sim_ent_should_predict(ent)) continue;
@ -969,11 +969,11 @@ void sim_step(SimStepCtx *ctx)
* ========================== */
for (u64 ent_index = 0; ent_index < world->num_ents_reserved; ++ent_index) {
Ent *cmd_ent = &world->ents[ent_index];
Entity *cmd_ent = &world->ents[ent_index];
if (!is_master && !sim_ent_should_simulate(cmd_ent)) continue;
if (sim_ent_has_prop(cmd_ent, SEPROP_CMD)) {
Ent *player = sim_ent_from_id(world, cmd_ent->cmd_player);
Entity *player = sim_ent_from_id(world, cmd_ent->cmd_player);
if (sim_ent_should_simulate(player)) {
b32 persist_cmd = 0;
if (!is_master && !sim_ent_id_eq(player->id, world->local_player)) {
@ -1017,7 +1017,7 @@ void sim_step(SimStepCtx *ctx)
}
}
if (flags & SIM_CONTROL_FLAG_DELETE) {
Ent *ent = sim_ent_from_id(world, player->player_hovered_ent);
Entity *ent = sim_ent_from_id(world, player->player_hovered_ent);
if (ent->valid) {
sim_ent_enable_prop(ent, SEPROP_RELEASE);
}
@ -1088,7 +1088,7 @@ void sim_step(SimStepCtx *ctx)
struct sim_data_key msg_key = cmd_ent->cmd_chat_msg;
String msg = sim_data_from_key(sim_data_store, msg_key);
if (msg.len > 0) {
Ent *chat_ent = sim_ent_alloc_sync_src(root);
Entity *chat_ent = sim_ent_alloc_sync_src(root);
sim_ent_enable_prop(chat_ent, SEPROP_CHAT);
chat_ent->chat_player = player->id;
chat_ent->chat_msg = msg_key;
@ -1116,11 +1116,11 @@ void sim_step(SimStepCtx *ctx)
* ========================== */
for (u64 ent_index = 0; ent_index < world->num_ents_reserved; ++ent_index) {
Ent *ent = &world->ents[ent_index];
Entity *ent = &world->ents[ent_index];
if (!sim_ent_should_simulate(ent)) continue;
if (sim_ent_has_prop(ent, SEPROP_CONTROLLED)) {
Ent *player = sim_ent_from_id(world, ent->controlling_player);
Entity *player = sim_ent_from_id(world, ent->controlling_player);
if (player->valid) {
ent->control = player->player_control;
}
@ -1133,11 +1133,11 @@ void sim_step(SimStepCtx *ctx)
if (is_master) {
for (u64 i = 0; i < world->num_ents_reserved; ++i) {
Ent *ent = &world->ents[i];
Entity *ent = &world->ents[i];
if (!sim_ent_should_simulate(ent)) continue;
if (sim_ent_has_prop(ent, SEPROP_PLAYER)) {
/* FIXME: Ents never released when client disconnects */
Ent *control_ent = sim_ent_from_id(world, ent->player_control_ent);
Entity *control_ent = sim_ent_from_id(world, ent->player_control_ent);
if (!control_ent->valid) {
control_ent = test_spawn_employee(root);
control_ent->predictor = ent->id;
@ -1145,13 +1145,13 @@ void sim_step(SimStepCtx *ctx)
ent->player_control_ent = control_ent->id;
control_ent->controlling_player = ent->id;
}
Ent *camera_ent = sim_ent_from_id(world, ent->player_camera_ent);
Entity *camera_ent = sim_ent_from_id(world, ent->player_camera_ent);
if (!camera_ent->valid) {
camera_ent = test_spawn_camera(root, control_ent);
camera_ent->predictor = ent->id;
ent->player_camera_ent = camera_ent->id;
}
Ent *camera_follow = sim_ent_from_id(world, camera_ent->camera_follow);
Entity *camera_follow = sim_ent_from_id(world, camera_ent->camera_follow);
if (!camera_follow->valid) {
camera_ent->camera_follow = control_ent->id;
}
@ -1164,7 +1164,7 @@ void sim_step(SimStepCtx *ctx)
* ========================== */
for (u64 ent_index = 0; ent_index < world->num_ents_reserved; ++ent_index) {
Ent *ent = &world->ents[ent_index];
Entity *ent = &world->ents[ent_index];
if (!sim_ent_should_simulate(ent)) continue;
if (S_IsTagNil(ent->sprite)) continue;
@ -1266,11 +1266,11 @@ void sim_step(SimStepCtx *ctx)
* ========================== */
for (u64 ent_index = 0; ent_index < world->num_ents_reserved; ++ent_index) {
Ent *ent = &world->ents[ent_index];
Entity *ent = &world->ents[ent_index];
if (!sim_ent_should_simulate(ent)) continue;
if (!sim_ent_has_prop(ent, SEPROP_ATTACHED)) continue;
Ent *parent = sim_ent_from_id(world, ent->parent);
Entity *parent = sim_ent_from_id(world, ent->parent);
S_Tag parent_sprite = parent->sprite;
S_Sheet *parent_sheet = S_SheetFromTagAwait(sprite_frame_scope, parent_sprite);
@ -1291,20 +1291,20 @@ void sim_step(SimStepCtx *ctx)
* ========================== */
for (u64 ent_index = 0; ent_index < world->num_ents_reserved; ++ent_index) {
Ent *ent = &world->ents[ent_index];
Entity *ent = &world->ents[ent_index];
if (!sim_ent_should_simulate(ent)) continue;
if (sim_ent_has_prop(ent, SEPROP_CONTROLLED)) {
ControlData *control = &ent->control;
u32 flags = control->flags;
if (flags & SIM_CONTROL_FLAG_FIRE) {
Ent *equipped = sim_ent_from_id(world, ent->equipped);
Entity *equipped = sim_ent_from_id(world, ent->equipped);
if (equipped->valid) {
++equipped->num_primary_triggers;
}
}
if (flags & SIM_CONTROL_FLAG_FIRE_ALT) {
Ent *equipped = sim_ent_from_id(world, ent->equipped);
Entity *equipped = sim_ent_from_id(world, ent->equipped);
if (equipped->valid) {
++equipped->num_secondary_triggers;
}
@ -1320,7 +1320,7 @@ void sim_step(SimStepCtx *ctx)
* ========================== */
for (u64 ent_index = 0; ent_index < world->num_ents_reserved; ++ent_index) {
Ent *ent = &world->ents[ent_index];
Entity *ent = &world->ents[ent_index];
if (!sim_ent_should_simulate(ent)) continue;
b32 primary_triggered = ent->num_primary_triggers > 0;
@ -1357,7 +1357,7 @@ void sim_step(SimStepCtx *ctx)
Vec2 rel_dir = MulXformBasisV2(sprite_local_xform, out_slice.dir);
/* Spawn bullet */
Ent *bullet;
Entity *bullet;
{
bullet = sim_ent_alloc_sync_src(root);
@ -1382,7 +1382,7 @@ void sim_step(SimStepCtx *ctx)
/* Spawn tracer */
{
Ent *tracer = sim_ent_alloc_sync_src(root);
Entity *tracer = sim_ent_alloc_sync_src(root);
tracer->tracer_fade_duration = 0.025f;
tracer->layer = SIM_LAYER_TRACERS;
sim_ent_enable_prop(tracer, SEPROP_TRACER);
@ -1404,7 +1404,7 @@ void sim_step(SimStepCtx *ctx)
Vec2 rel_dir = MulXformBasisV2(sprite_local_xform, out_slice.dir);
/* Spawn bullet */
Ent *bullet;
Entity *bullet;
{
bullet = sim_ent_alloc_sync_src(root);
@ -1428,7 +1428,7 @@ void sim_step(SimStepCtx *ctx)
/* Spawn tracer */
{
Ent *tracer = sim_ent_alloc_sync_src(root);
Entity *tracer = sim_ent_alloc_sync_src(root);
tracer->tracer_fade_duration = 0.025f;
tracer->layer = SIM_LAYER_TRACERS;
sim_ent_enable_prop(tracer, SEPROP_TRACER);
@ -1443,12 +1443,12 @@ void sim_step(SimStepCtx *ctx)
if (primary_triggered) {
}
if (secondary_triggered) {
Ent *zone = sim_ent_from_id(world, ent->chucker_zone);
Ent *target = sim_ent_from_id(world, zone->chucker_zone_ent);
Ent *old_joint_ent = sim_ent_from_id(world, ent->chucker_joint);
Entity *zone = sim_ent_from_id(world, ent->chucker_zone);
Entity *target = sim_ent_from_id(world, zone->chucker_zone_ent);
Entity *old_joint_ent = sim_ent_from_id(world, ent->chucker_joint);
if (sim_ent_is_valid_and_active(target) && zone->chucker_zone_ent_tick == world->tick - 1) {
if (!sim_ent_id_eq(old_joint_ent->weld_joint_data.e1, target->id)) {
Ent *joint_ent = sim_ent_alloc_sync_src(root);
Entity *joint_ent = sim_ent_alloc_sync_src(root);
sim_ent_enable_prop(joint_ent, SEPROP_ACTIVE);
Xform xf0 = sim_ent_get_xform(ent);
@ -1481,11 +1481,11 @@ void sim_step(SimStepCtx *ctx)
* ========================== */
for (u64 ent_index = 0; ent_index < world->num_ents_reserved; ++ent_index) {
Ent *ent = &world->ents[ent_index];
Entity *ent = &world->ents[ent_index];
if (!sim_ent_should_simulate(ent)) continue;
if (sim_ent_has_prop(ent, SEPROP_CONTROLLED)) {
Ent *joint_ent = sim_ent_from_id(world, ent->move_joint);
Entity *joint_ent = sim_ent_from_id(world, ent->move_joint);
if (is_master && !sim_ent_is_valid_and_active(joint_ent)) {
joint_ent = sim_ent_alloc_sync_src(root);
joint_ent->predictor = ent->predictor;
@ -1518,7 +1518,7 @@ void sim_step(SimStepCtx *ctx)
#if SIM_PLAYER_AIM
for (u64 ent_index = 0; ent_index < world->num_ents_reserved; ++ent_index) {
Ent *ent = &world->ents[ent_index];
Entity *ent = &world->ents[ent_index];
if (!sim_ent_should_simulate(ent)) continue;
if (sim_ent_has_prop(ent, SEPROP_CONTROLLED)) {
@ -1526,7 +1526,7 @@ void sim_step(SimStepCtx *ctx)
Xform sprite_xf = MulXform(xf, ent->sprite_local_xform);
/* Retrieve / create aim joint */
Ent *joint_ent = sim_ent_from_id(world, ent->aim_joint);
Entity *joint_ent = sim_ent_from_id(world, ent->aim_joint);
if (is_master && !sim_ent_is_valid_and_active(joint_ent)) {
joint_ent = sim_ent_alloc_sync_src(root);
joint_ent->predictor = ent->predictor;
@ -1616,11 +1616,11 @@ void sim_step(SimStepCtx *ctx)
#if 1
for (u64 ent_index = 0; ent_index < world->num_ents_reserved; ++ent_index) {
Ent *ent = &world->ents[ent_index];
Entity *ent = &world->ents[ent_index];
if (!sim_ent_should_simulate(ent)) continue;
if (!sim_ent_has_prop(ent, SEPROP_DYNAMIC)) continue;
Ent *joint_ent = sim_ent_from_id(world, ent->ground_friction_joint);
Entity *joint_ent = sim_ent_from_id(world, ent->ground_friction_joint);
MotorJointDesc def = phys_motor_joint_def_init();
def.e0 = root->id;
@ -1647,7 +1647,7 @@ void sim_step(SimStepCtx *ctx)
if (is_master) {
for (u64 i = 0; i < world->num_ents_reserved; ++i) {
Ent *player = &world->ents[i];
Entity *player = &world->ents[i];
if (!sim_ent_should_simulate(player)) continue;
if (!sim_ent_has_prop(player, SEPROP_PLAYER)) continue;
@ -1655,8 +1655,8 @@ void sim_step(SimStepCtx *ctx)
b32 start_dragging = player->player_dbg_drag_start;
b32 stop_dragging = player->player_dbg_drag_stop;
Ent *joint_ent = sim_ent_from_id(world, player->player_dbg_drag_joint_ent);
Ent *target_ent = sim_ent_from_id(world, joint_ent->mouse_joint_data.target);
Entity *joint_ent = sim_ent_from_id(world, player->player_dbg_drag_joint_ent);
Entity *target_ent = sim_ent_from_id(world, joint_ent->mouse_joint_data.target);
if (stop_dragging) {
target_ent = sim_ent_nil();
@ -1712,7 +1712,7 @@ void sim_step(SimStepCtx *ctx)
* ========================== */
for (u64 ent_index = 0; ent_index < world->num_ents_reserved; ++ent_index) {
Ent *ent = &world->ents[ent_index];
Entity *ent = &world->ents[ent_index];
if (!sim_ent_should_simulate(ent)) continue;
if (!sim_ent_has_prop(ent, SEPROP_EXPLOSION)) continue;
@ -1725,7 +1725,7 @@ void sim_step(SimStepCtx *ctx)
* ========================== */
for (u64 ent_index = 0; ent_index < world->num_ents_reserved; ++ent_index) {
Ent *ent = &world->ents[ent_index];
Entity *ent = &world->ents[ent_index];
if (!sim_ent_should_simulate(ent)) continue;
if (!sim_ent_has_prop(ent, SEPROP_TRACER)) continue;
@ -1749,12 +1749,12 @@ void sim_step(SimStepCtx *ctx)
* ========================== */
for (u64 ent_index = 0; ent_index < world->num_ents_reserved; ++ent_index) {
Ent *ent = &world->ents[ent_index];
Entity *ent = &world->ents[ent_index];
if (!sim_ent_should_simulate(ent)) continue;
if (!sim_ent_has_prop(ent, SEPROP_BULLET)) continue;
if (ent->activation_tick == world->tick) {
Ent *src = sim_ent_from_id(world, ent->bullet_src);
Entity *src = sim_ent_from_id(world, ent->bullet_src);
Xform src_xf = sim_ent_get_xform(src);
/* Activate collision */
@ -1769,7 +1769,7 @@ void sim_step(SimStepCtx *ctx)
/* Add shooter velocity to bullet */
{
/* TODO: Add angular velocity as well? */
Ent *top = sim_ent_from_id(ss_blended, src->top);
Entity *top = sim_ent_from_id(ss_blended, src->top);
impulse = AddVec2(impulse, MulVec2(top->linear_velocity, dt));
}
#endif
@ -1781,7 +1781,7 @@ void sim_step(SimStepCtx *ctx)
sim_ent_set_linear_velocity(ent, vel);
/* Initialize tracer */
Ent *tracer = sim_ent_from_id(world, ent->bullet_tracer);
Entity *tracer = sim_ent_from_id(world, ent->bullet_tracer);
if (sim_ent_should_simulate(tracer)) {
sim_ent_set_xform(tracer, xf);
sim_ent_enable_prop(tracer, SEPROP_KINEMATIC);
@ -1794,7 +1794,7 @@ void sim_step(SimStepCtx *ctx)
/* Spawn quake */
{
Ent *quake = sim_ent_alloc_sync_src(root);
Entity *quake = sim_ent_alloc_sync_src(root);
sim_ent_set_xform(quake, XformFromPos(pos));
quake->quake_intensity = 0.2f;
quake->quake_fade = quake->quake_intensity / 0.1f;
@ -1808,7 +1808,7 @@ void sim_step(SimStepCtx *ctx)
* ========================== */
for (u64 ent_index = 0; ent_index < world->num_ents_reserved; ++ent_index) {
Ent *ent = &world->ents[ent_index];
Entity *ent = &world->ents[ent_index];
if (!sim_ent_should_simulate(ent)) continue;
if (!sim_ent_has_prop(ent, SEPROP_CAMERA)) continue;
@ -1816,7 +1816,7 @@ void sim_step(SimStepCtx *ctx)
/* Camera follow */
{
Ent *follow = sim_ent_from_id(world, ent->camera_follow);
Entity *follow = sim_ent_from_id(world, ent->camera_follow);
f32 aspect_ratio = 1.0;
{
@ -1849,7 +1849,7 @@ void sim_step(SimStepCtx *ctx)
/* TODO: Update based on distance to quake */
ent->shake = 0;
for (u64 quake_ent_index = 0; quake_ent_index < world->num_ents_reserved; ++quake_ent_index) {
Ent *quake = &world->ents[quake_ent_index];
Entity *quake = &world->ents[quake_ent_index];
if (!sim_ent_should_simulate(quake)) continue;
if (!sim_ent_has_prop(quake, SEPROP_QUAKE)) continue;
ent->shake += quake->quake_intensity;
@ -1864,7 +1864,7 @@ void sim_step(SimStepCtx *ctx)
* ========================== */
for (u64 ent_index = 0; ent_index < world->num_ents_reserved; ++ent_index) {
Ent *ent = &world->ents[ent_index];
Entity *ent = &world->ents[ent_index];
if (!sim_ent_should_simulate(ent)) continue;
if (!sim_ent_has_prop(ent, SEPROP_QUAKE)) continue;
@ -1881,20 +1881,20 @@ void sim_step(SimStepCtx *ctx)
{
TempArena temp = BeginTempArena(scratch.arena);
Ent **stack = PushStructNoZero(temp.arena, Ent *);
Entity **stack = PushStructNoZero(temp.arena, Entity *);
u64 stack_count = 1;
*stack = root;
while (stack_count > 0) {
Ent *parent;
PopStruct(temp.arena, Ent *, &parent);
Entity *parent;
PopStruct(temp.arena, Entity *, &parent);
--stack_count;
i32 parent_layer = parent->final_layer;
for (Ent *child = sim_ent_from_id(world, parent->first); child->valid; child = sim_ent_from_id(world, child->next)) {
for (Entity *child = sim_ent_from_id(world, parent->first); child->valid; child = sim_ent_from_id(world, child->next)) {
if (sim_ent_should_simulate(child)) {
child->final_layer = parent_layer + child->layer;
*PushStructNoZero(temp.arena, Ent *) = child;
*PushStructNoZero(temp.arena, Entity *) = child;
++stack_count;
}
}
@ -1922,7 +1922,7 @@ void sim_step(SimStepCtx *ctx)
/* Mark all synced ents as both sync dsts & sync srcs */
for (u64 ent_index = 2; ent_index < pub_world->num_ents_reserved; ++ent_index) {
Ent *ent = &pub_world->ents[ent_index];
Entity *ent = &pub_world->ents[ent_index];
if (ent->valid) {
sim_ent_enable_prop(ent, SEPROP_SYNC_DST);
sim_ent_enable_prop(ent, SEPROP_SYNC_SRC);

View File

@ -431,11 +431,11 @@ P_JobDef(S_LoadSpriteJob, job)
switch (ref.e->kind)
{
case CACHE_ENTRY_KIND_TEXTURE:
case S_CacheEntryKind_Texture:
{
S_LoadCacheEntryTexture(ref, cmd->tag);
} break;
case CACHE_ENTRY_KIND_SHEET:
case S_CacheEntryKind_Sheet:
{
S_LoadCacheEntrySheet(ref, cmd->tag);
} break;
@ -496,7 +496,7 @@ void S_LoadCacheEntryTexture(S_CacheEntryRef ref, S_Tag tag)
TempArena scratch = BeginScratchNoConflict();
S_CacheEntry *e = ref.e;
Atomic32FetchSet(&e->state, CACHE_ENTRY_STATE_WORKING);
Atomic32FetchSet(&e->state, S_CacheEntryState_Working);
String path = tag.path;
P_LogInfoF("Loading sprite texture [%F] \"%F\"", FmtHex(e->hash.v), FmtString(path));
@ -504,7 +504,7 @@ void S_LoadCacheEntryTexture(S_CacheEntryRef ref, S_Tag tag)
i64 start_ns = P_TimeNs();
Assert(StringEndsWith(path, Lit(".ase")));
Assert(e->kind == CACHE_ENTRY_KIND_TEXTURE);
Assert(e->kind == S_CacheEntryKind_Texture);
/* TODO: Replace arena allocs w/ buddy allocator */
/* TODO: Arena probably overkill. Just using it to store texture struct. */
@ -553,7 +553,7 @@ void S_LoadCacheEntryTexture(S_CacheEntryRef ref, S_Tag tag)
FmtUint(e->memory_usage));
}
Atomic32FetchSet(&e->state, CACHE_ENTRY_STATE_LOADED);
Atomic32FetchSet(&e->state, S_CacheEntryState_Loaded);
#if RESOURCE_RELOADING
S_CacheEntryBin *bin = &g->cache.bins[e->hash.v % S_CacheBinsCount];
@ -581,14 +581,14 @@ void S_LoadCacheEntrySheet(S_CacheEntryRef ref, S_Tag tag)
TempArena scratch = BeginScratchNoConflict();
S_CacheEntry *e = ref.e;
Atomic32FetchSet(&e->state, CACHE_ENTRY_STATE_WORKING);
Atomic32FetchSet(&e->state, S_CacheEntryState_Working);
String path = tag.path;
P_LogInfoF("Loading sprite sheet [%F] \"%F\"", FmtHex(e->hash.v), FmtString(path));
b32 success = 0;
i64 start_ns = P_TimeNs();
Assert(e->kind == CACHE_ENTRY_KIND_SHEET);
Assert(e->kind == S_CacheEntryKind_Sheet);
/* TODO: Replace arena allocs w/ buddy allocator */
e->arena = AllocArena(S_SheetArenaReserve);
@ -636,7 +636,7 @@ void S_LoadCacheEntrySheet(S_CacheEntryRef ref, S_Tag tag)
FmtUint(e->memory_usage));
}
Atomic32FetchSet(&e->state, CACHE_ENTRY_STATE_LOADED);
Atomic32FetchSet(&e->state, S_CacheEntryState_Loaded);
#if RESOURCE_RELOADING
S_CacheEntryBin *bin = &g->cache.bins[e->hash.v % S_CacheBinsCount];
@ -808,13 +808,13 @@ S_ScopeCacheEntryRef *S_EntryFromHashLocked(S_Scope *scope, S_Hash hash, P_Lock
* newest entry rather than the first one that exists since
* there may be more than one matching entry in the cache */
S_CacheEntry *match = 0;
S_CacheEntryState match_state = CACHE_ENTRY_STATE_NONE;
S_CacheEntryState match_state = S_CacheEntryState_None;
for (S_CacheEntry *entry = bin->first; entry; entry = entry->next_in_bin)
{
if (entry->hash.v == hash.v)
{
S_CacheEntryState entry_state = Atomic32Fetch(&entry->state);
if (!match || entry_state > match_state || (entry_state == CACHE_ENTRY_STATE_LOADED && match_state == CACHE_ENTRY_STATE_LOADED && entry->load_time_ns > match->load_time_ns))
if (!match || entry_state > match_state || (entry_state == S_CacheEntryState_Loaded && match_state == S_CacheEntryState_Loaded && entry->load_time_ns > match->load_time_ns))
{
match = entry;
match_state = entry_state;
@ -944,8 +944,8 @@ void *S_DataFromTag(S_Scope *scope, S_Tag tag, S_CacheEntryKind kind, b32 await)
void *result = 0;
switch (kind)
{
case CACHE_ENTRY_KIND_TEXTURE: { result = g->loading_texture; } break;
case CACHE_ENTRY_KIND_SHEET: { result = g->loading_sheet; } break;
case S_CacheEntryKind_Texture: { result = g->loading_texture; } break;
case S_CacheEntryKind_Sheet: { result = g->loading_sheet; } break;
default: { P_Panic(Lit("Unknown sprite cache entry kind")); } break;
}
@ -953,31 +953,31 @@ void *S_DataFromTag(S_Scope *scope, S_Tag tag, S_CacheEntryKind kind, b32 await)
S_CacheEntryRef ref = scope_ref->ref;
S_CacheEntryState state = Atomic32Fetch(&ref.e->state);
if (state == CACHE_ENTRY_STATE_LOADED)
if (state == S_CacheEntryState_Loaded)
{
switch (kind)
{
case CACHE_ENTRY_KIND_TEXTURE: { result = ref.e->texture; } break;
case CACHE_ENTRY_KIND_SHEET: { result = ref.e->sheet; } break;
case S_CacheEntryKind_Texture: { result = ref.e->texture; } break;
case S_CacheEntryKind_Sheet: { result = ref.e->sheet; } break;
default: { P_Panic(Lit("Unknown sprite cache entry kind")); } break;
}
}
else if (state == CACHE_ENTRY_STATE_NONE)
else if (state == S_CacheEntryState_None)
{
/* If entry is new, load texture */
if (Atomic32FetchTestSet(&ref.e->state, CACHE_ENTRY_STATE_NONE, CACHE_ENTRY_STATE_QUEUED) == CACHE_ENTRY_STATE_NONE)
if (Atomic32FetchTestSet(&ref.e->state, S_CacheEntryState_None, S_CacheEntryState_Queued) == S_CacheEntryState_None)
{
/* If caller is awaiting result then just load now on the calling thread. Otherwise spawn a work task. */
if (await)
{
switch (kind)
{
case CACHE_ENTRY_KIND_TEXTURE:
case S_CacheEntryKind_Texture:
{
S_LoadCacheEntryTexture(ref, tag);
result = ref.e->texture;
} break;
case CACHE_ENTRY_KIND_SHEET:
case S_CacheEntryKind_Sheet:
{
S_LoadCacheEntrySheet(ref, tag);
result = ref.e->sheet;
@ -994,9 +994,9 @@ void *S_DataFromTag(S_Scope *scope, S_Tag tag, S_CacheEntryKind kind, b32 await)
}
/* Spinlock until result is ready */
if (await && state != CACHE_ENTRY_STATE_LOADED)
if (await && state != S_CacheEntryState_Loaded)
{
while (Atomic32Fetch(&ref.e->state) != CACHE_ENTRY_STATE_LOADED)
while (Atomic32Fetch(&ref.e->state) != S_CacheEntryState_Loaded)
{
IxPause();
}
@ -1010,18 +1010,18 @@ void *S_DataFromTag(S_Scope *scope, S_Tag tag, S_CacheEntryKind kind, b32 await)
S_Texture *S_TextureFromTagAwait(S_Scope *scope, S_Tag tag)
{
return (S_Texture *)S_DataFromTag(scope, tag, CACHE_ENTRY_KIND_TEXTURE, 1);
return (S_Texture *)S_DataFromTag(scope, tag, S_CacheEntryKind_Texture, 1);
}
S_Texture *S_TextureFromTagAsync(S_Scope *scope, S_Tag tag)
{
return (S_Texture *)S_DataFromTag(scope, tag, CACHE_ENTRY_KIND_TEXTURE, 0);
return (S_Texture *)S_DataFromTag(scope, tag, S_CacheEntryKind_Texture, 0);
}
void S_PrefetchTextureFromTag(S_Scope *scope, S_Tag tag)
{
S_DataFromTag(scope, tag, CACHE_ENTRY_KIND_TEXTURE, 0);
S_DataFromTag(scope, tag, S_CacheEntryKind_Texture, 0);
}
////////////////////////////////
@ -1029,17 +1029,17 @@ void S_PrefetchTextureFromTag(S_Scope *scope, S_Tag tag)
S_Sheet *S_SheetFromTagAwait(S_Scope *scope, S_Tag tag)
{
return (S_Sheet *)S_DataFromTag(scope, tag, CACHE_ENTRY_KIND_SHEET, 1);
return (S_Sheet *)S_DataFromTag(scope, tag, S_CacheEntryKind_Sheet, 1);
}
S_Sheet *S_SheetFromTagAsync(S_Scope *scope, S_Tag tag)
{
return (S_Sheet *)S_DataFromTag(scope, tag, CACHE_ENTRY_KIND_SHEET, 0);
return (S_Sheet *)S_DataFromTag(scope, tag, S_CacheEntryKind_Sheet, 0);
}
void S_PrefetchSheetFromTag(S_Scope *scope, S_Tag tag)
{
S_DataFromTag(scope, tag, CACHE_ENTRY_KIND_SHEET, 0);
S_DataFromTag(scope, tag, S_CacheEntryKind_Sheet, 0);
}
////////////////////////////////
@ -1157,7 +1157,7 @@ W_CallbackFuncDef(S_WatchSpriteCallback, name)
}
S_Tag tag = S_TagFromPath(name);
for (S_CacheEntryKind kind = 0; kind < NUM_CACHE_ENTRY_KINDS; ++kind)
for (S_CacheEntryKind kind = 0; kind < S_CacheEntryKind_Count; ++kind)
{
S_ReloadSpriteFromTag(scope, tag, kind);
}
@ -1323,7 +1323,7 @@ P_JobDef(S_EvictorJob, _)
for (S_EvictorNode *en = first_evicted; en; en = en->next_evicted)
{
S_CacheEntry *n = en->cache_entry;
if (n->kind == CACHE_ENTRY_KIND_TEXTURE && n->texture->valid)
if (n->kind == S_CacheEntryKind_Texture && n->texture->valid)
{
GPU_ReleaseResourceFenced(n->texture->gp_texture);
}

View File

@ -95,18 +95,18 @@ Struct(S_Sheet)
typedef i32 S_CacheEntryKind; enum
{
CACHE_ENTRY_KIND_TEXTURE,
CACHE_ENTRY_KIND_SHEET,
S_CacheEntryKind_Texture,
S_CacheEntryKind_Sheet,
NUM_CACHE_ENTRY_KINDS
S_CacheEntryKind_Count
};
typedef i32 S_CacheEntryState; enum
{
CACHE_ENTRY_STATE_NONE,
CACHE_ENTRY_STATE_QUEUED,
CACHE_ENTRY_STATE_WORKING,
CACHE_ENTRY_STATE_LOADED
S_CacheEntryState_None,
S_CacheEntryState_Queued,
S_CacheEntryState_Working,
S_CacheEntryState_Loaded
};
Struct(S_Refcount)
@ -214,19 +214,11 @@ Struct(S_EvictorNode)
////////////////////////////////
//~ Cache constants
/* The evictor will begin evicting once cache usage is > threshold.
* It will entries until the budget has shrunk < target. */
#define S_CacheMemoryBudgetThreshold (Mebi(256))
#define S_CacheMemoryBudgetTarget (Mebi(128))
StaticAssert(S_CacheMemoryBudgetThreshold >= S_CacheMemoryBudgetTarget);
#define S_CacheBinsCount 1024
#define S_MaxScopeReferences 1024
/* Texture arena only used to store texture struct at the moment. Actual image data is allocated on GPU. */
#define S_TextureArenaReserve Mebi(1)
#define S_CacheBinsCount 1024
#define S_MaxScopeReferences 1024
#define S_SheetArenaReserve Mebi(64)
#define S_SheetSpanLookupTableBinRatio 2.0
#define S_SliceLookupTableBinRatio 2.0
@ -237,6 +229,12 @@ StaticAssert(S_CacheMemoryBudgetThreshold >= S_CacheMemoryBudgetTarget);
/* How many cycles a cache entry spends unused until it's considered evictable */
#define S_EvictorGracePeriodCycles (NsFromSeconds(10.000) / S_EvictorCycleIntervalNs)
/* The evictor will begin evicting once cache usage is > threshold.
* It will entries until the budget has shrunk < target. */
#define S_CacheMemoryBudgetThreshold (Mebi(256))
#define S_CacheMemoryBudgetTarget (Mebi(128))
StaticAssert(S_CacheMemoryBudgetThreshold >= S_CacheMemoryBudgetTarget);
////////////////////////////////
//~ Shared state

View File

@ -1,183 +1,7 @@
struct bind_state {
b32 is_held; /* Is this bind held down this frame */
u32 num_presses; /* How many times was this bind's pressed since last frame */
u32 num_repeats; /* How many times was this bind's key repeated since last frame */
u32 num_presses_and_repeats; /* Same as `num_presses` but includes key repeats as well */
u32 num_releases; /* How many times was this bind released since last frame */
};
struct second_stat {
u64 last_second_start;
u64 last_second_end;
u64 last_second;
};
struct console_log {
String msg;
i32 level;
i32 color_index;
P_DateTime datetime;
i64 time_ns;
Rect bounds;
struct console_log *prev;
struct console_log *next;
};
Global struct {
Atomic32 shutdown;
P_Counter shutdown_job_counters;
P_Window *window;
GPU_Swapchain *swapchain;
struct sim_ctx *local_sim_ctx;
Arena *arena;
String connect_address_str;
ClientStore *user_client_store;
Client *user_unblended_client; /* Contains snapshots received from local sim */
Client *user_blended_client; /* Contains single snapshot from result of blending local sim snapshots */
Snapshot *ss_blended; /* Points to blended snapshot contained in blended client */
/* Usage stats */
i64 last_second_reset_ns;
struct second_stat net_bytes_read;
struct second_stat net_bytes_sent;
/* Gpu resources */
GPU_RenderSig *render_sig;
struct bind_state bind_states[USER_BIND_KIND_COUNT];
/* Debug camera */
EntId debug_following;
b32 debug_camera;
b32 debug_camera_panning;
Vec2 debug_camera_pan_start;
b32 debug_draw;
/* Debug console */
P_Mutex console_logs_mutex;
Arena *console_logs_arena;
struct console_log *first_console_log;
struct console_log *last_console_log;
i32 console_log_color_indices[P_LogLevel_Count];
f32 console_logs_height;
b32 debug_console;
/* Window -> user */
P_Mutex sys_window_events_mutex;
Arena *sys_window_events_arena;
/* User -> local sim */
P_Mutex user_sim_cmd_mutex;
ControlData user_sim_cmd_control;
EntId user_hovered_ent;
u64 last_user_sim_cmd_gen;
u64 user_sim_cmd_gen;
Atomic32 user_paused;
Atomic32 user_paused_steps;
/* Local sim -> user */
P_Mutex local_to_user_client_mutex;
ClientStore *local_to_user_client_store;
Client *local_to_user_client;
i64 local_to_user_client_publish_dt_ns;
i64 local_to_user_client_publish_time_ns;
/* Rolling window of local sim -> user publish time deltas */
i64 last_local_to_user_snapshot_published_at_ns;
i64 average_local_to_user_snapshot_publish_dt_ns;
i64 local_sim_predicted_time_ns; /* Calculated from <last local sim to user pubilsh time> + <time since last local sim to user publish> */
i64 render_time_target_ns; /* Claculated from <local_sim_rpedicted_time_ns> - <render interp delay> */
i64 render_time_ns; /* Incremented at a constant rate based on average local to user publish delta, but snaps to render_time_target_ns if it gets too distant */
u64 local_sim_last_known_tick;
i64 local_sim_last_known_time_ns;
i64 real_dt_ns;
i64 real_time_ns;
/* Per-frame */
Vec2 screen_size;
Vec2 screen_cursor;
Xform ui_to_screen_xf;
Vec2 ui_size;
Vec2 ui_cursor;
Xform render_to_ui_xf;
Vec2 render_size;
Xform world_to_render_xf;
Xform world_to_ui_xf;
Vec2 world_cursor;
Vec2 focus_send;
} G = ZI, DebugAlias(G, G_user);
/* ========================== *
* Bind state
* ========================== */
/* TODO: Remove this */
Global Readonly enum user_bind_kind g_binds[P_Btn_Count] = {
[P_Btn_W] = USER_BIND_KIND_MOVE_UP,
[P_Btn_S] = USER_BIND_KIND_MOVE_DOWN,
[P_Btn_A] = USER_BIND_KIND_MOVE_LEFT,
[P_Btn_D] = USER_BIND_KIND_MOVE_RIGHT,
//[P_Btn_Alt] = USER_BIND_KIND_WALK,
[P_Btn_M1] = USER_BIND_KIND_FIRE,
[P_Btn_M2] = USER_BIND_KIND_FIRE_ALT,
/* Testing */
[P_Btn_Z] = USER_BIND_KIND_TILE_TEST,
[P_Btn_M5] = USER_BIND_KIND_DEBUG_DRAG,
[P_Btn_M4] = USER_BIND_KIND_DEBUG_DELETE,
[P_Btn_F] = USER_BIND_KIND_DEBUG_EXPLODE,
[P_Btn_T] = USER_BIND_KIND_DEBUG_TELEPORT,
[P_Btn_C] = USER_BIND_KIND_DEBUG_CLEAR,
[P_Btn_1] = USER_BIND_KIND_DEBUG_SPAWN1,
[P_Btn_2] = USER_BIND_KIND_DEBUG_SPAWN2,
[P_Btn_3] = USER_BIND_KIND_DEBUG_SPAWN3,
[P_Btn_4] = USER_BIND_KIND_DEBUG_SPAWN4,
[P_Btn_G] = USER_BIND_KIND_DEBUG_WALLS,
[P_Btn_N] = USER_BIND_KIND_DEBUG_STEP,
[P_Btn_Q] = USER_BIND_KIND_DEBUG_FOLLOW,
[P_Btn_F1] = USER_BIND_KIND_DEBUG_PAUSE,
[P_Btn_F2] = USER_BIND_KIND_DEBUG_CAMERA,
[P_Btn_F3] = USER_BIND_KIND_DEBUG_DRAW,
[P_Btn_F4] = USER_BIND_KIND_DEBUG_TOGGLE_TOPMOST,
[P_Btn_GraveAccent] = USER_BIND_KIND_DEBUG_CONSOLE,
[P_Btn_Alt] = USER_BIND_KIND_FULLSCREEN_MOD,
[P_Btn_Enter] = USER_BIND_KIND_FULLSCREEN,
[P_Btn_MWheelUp] = USER_BIND_KIND_ZOOM_IN,
[P_Btn_MWheelDown] = USER_BIND_KIND_ZOOM_OUT,
[P_Btn_M3] = USER_BIND_KIND_PAN,
#if RtcIsEnabled
/* Debug */
[P_Btn_ForwardSlash] = USER_BIND_KIND_RESET_DEBUG_STEPS,
[P_Btn_Comma] = USER_BIND_KIND_DECR_DEBUG_STEPS,
[P_Btn_Period] = USER_BIND_KIND_INCR_DEBUG_STEPS
#endif
};
/* ========================== *
* Startup
* ========================== */
internal P_ExitFuncDef(user_shutdown);
internal P_LogEventCallbackFuncDef(debug_console_log_callback, log);
internal P_JobDef(user_update_job, _);
internal P_JobDef(local_sim_job , _);
struct user_startup_receipt user_startup(F_StartupReceipt *font_sr,
S_StartupReceipt *sprite_sr,
D_StartupReceipt *draw_sr,
@ -273,7 +97,7 @@ internal void debug_draw_xform(Xform xf, u32 color_x, u32 color_y)
//D_DrawQuad(G.render_sig, quad, color);
}
internal void debug_draw_movement(Ent *ent)
internal void debug_draw_movement(Entity *ent)
{
f32 thickness = 2.f;
f32 arrow_len = 15.f;
@ -291,7 +115,7 @@ internal void debug_draw_movement(Ent *ent)
}
}
internal String get_ent_debug_text(Arena *arena, Ent *ent)
internal String get_ent_debug_text(Arena *arena, Entity *ent)
{
TempArena scratch = BeginScratch(arena);
Snapshot *ss = ent->ss;
@ -361,7 +185,7 @@ internal String get_ent_debug_text(Arena *arena, Ent *ent)
/* Children */
if (!sim_ent_id_is_nil(ent->first) || !sim_ent_id_is_nil(ent->last)) {
Ent *child = sim_ent_from_id(ss, ent->first);
Entity *child = sim_ent_from_id(ss, ent->first);
if (!sim_ent_id_eq(ent->first, ent->last) || !child->valid) {
result.len += StringFormat(arena, Lit("first child: [%F]\n"), FmtUid(ent->first.uid)).len;
result.len += StringFormat(arena, Lit("last child: [%F]\n"), FmtUid(ent->last.uid)).len;
@ -508,8 +332,8 @@ internal void draw_debug_console(i32 level, b32 minimized)
internal MergesortCompareFuncDef(ent_draw_order_cmp, arg_a, arg_b, _)
{
Ent *a = *(Ent **)arg_a;
Ent *b = *(Ent **)arg_b;
Entity *a = *(Entity **)arg_a;
Entity *b = *(Entity **)arg_b;
i32 result = 0;
@ -740,15 +564,15 @@ internal void user_update(P_Window *window)
* Find local entities
* ========================== */
Ent *local_player = sim_ent_from_id(G.ss_blended, G.ss_blended->local_player);
Ent *local_control = sim_ent_from_id(G.ss_blended, local_player->player_control_ent);
Ent *local_camera = sim_ent_from_id(G.ss_blended, local_player->player_camera_ent);
Entity *local_player = sim_ent_from_id(G.ss_blended, G.ss_blended->local_player);
Entity *local_control = sim_ent_from_id(G.ss_blended, local_player->player_control_ent);
Entity *local_camera = sim_ent_from_id(G.ss_blended, local_player->player_camera_ent);
/* ========================== *
* Find hovered entity
* ========================== */
Ent *hovered_ent = sim_ent_nil();
Entity *hovered_ent = sim_ent_nil();
{
Xform mouse_xf = XformFromPos(G.world_cursor);
CLD_Shape mouse_shape = ZI;
@ -756,7 +580,7 @@ internal void user_update(P_Window *window)
mouse_shape.count = 1;
mouse_shape.radius = 0.01f;
for (u64 ent_index = 0; ent_index < G.ss_blended->num_ents_reserved; ++ent_index) {
Ent *ent = &G.ss_blended->ents[ent_index];
Entity *ent = &G.ss_blended->ents[ent_index];
if (!sim_ent_is_valid_and_active(ent)) continue;
CLD_Shape ent_collider = ent->local_collider;
@ -811,11 +635,11 @@ internal void user_update(P_Window *window)
}
}
if (!sim_ent_id_is_nil(G.debug_following)) {
Ent *follow_ent = sim_ent_from_id(G.ss_blended, G.debug_following);
Ent *follow_camera = sim_ent_nil();
Entity *follow_ent = sim_ent_from_id(G.ss_blended, G.debug_following);
Entity *follow_camera = sim_ent_nil();
for (u64 i = 0; i < G.ss_blended->num_ents_reserved; ++i) {
Ent *ent = &G.ss_blended->ents[i];
Ent *ent_camera_follow = sim_ent_from_id(G.ss_blended, ent->camera_follow);
Entity *ent = &G.ss_blended->ents[i];
Entity *ent_camera_follow = sim_ent_from_id(G.ss_blended, ent->camera_follow);
if (ent_camera_follow->valid && ent_camera_follow == follow_ent) {
follow_camera = ent;
break;
@ -834,7 +658,7 @@ internal void user_update(P_Window *window)
* ========================== */
for (u64 ent_index = 0; ent_index < G.ss_blended->num_ents_reserved; ++ent_index) {
Ent *ent = &G.ss_blended->ents[ent_index];
Entity *ent = &G.ss_blended->ents[ent_index];
if (!sim_ent_is_valid_and_active(ent)) continue;
/* How much time between camera shakes */
@ -1039,7 +863,7 @@ internal void user_update(P_Window *window)
/* Alloc entries from new sim chunks */
for (u64 ent_index = 0; ent_index < G.ss_blended->num_ents_reserved; ++ent_index) {
Ent *chunk_ent = &G.ss_blended->ents[ent_index];
Entity *chunk_ent = &G.ss_blended->ents[ent_index];
if (sim_ent_is_valid_and_active(chunk_ent) && sim_ent_has_prop(chunk_ent, SEPROP_TILE_CHUNK)) {
struct user_tile_cache_entry *entry = user_tile_cache_entry_from_chunk_pos(chunk_ent->tile_chunk_pos);
if (!entry->valid) {
@ -1053,7 +877,7 @@ internal void user_update(P_Window *window)
for (u64 entry_index = 0; entry_index < G.tile_cache.num_reserved_entries; ++entry_index) {
struct tile_cache_entry *entry = &G.tile_cache.entries[entry_index];
if (entry->valid) {
Ent *chunk_ent = sim_ent_from_chunk_pos(entry->pos);
Entity *chunk_ent = sim_ent_from_chunk_pos(entry->pos);
if (!chunk_ent->valid) {
user_tile_cache_entry_release(entry);
}
@ -1068,7 +892,7 @@ internal void user_update(P_Window *window)
struct tile_cache_entry *entry = &G.tile_cache.entries[entry_index];
if (entry->valid) {
Vec2I32 chunk_pos = entry->pos;
Ent *chunk_ent = sim_ent_from_chunk_pos(chunk_pos);
Entity *chunk_ent = sim_ent_from_chunk_pos(chunk_pos);
if (entry->applied_dirty_gen != chunk_ent->dirty_gen) {
entry->applied_dirty_gen = chunk_ent->dirty_gen;
/* TODO: Autotiling */
@ -1092,7 +916,7 @@ internal void user_update(P_Window *window)
struct tile_cache_entry *entry = &G.tile_cache.entries[entry_index];
if (entry->valid) {
Vec2I32 chunk_pos = entry->pos;
Ent *chunk_ent = sim_ent_from_chunk_pos(chunk_pos);
Entity *chunk_ent = sim_ent_from_chunk_pos(chunk_pos);
if (entry->applied_dirty_gen != chunk_ent->dirty_gen) {
entry->applied_dirty_gen = chunk_ent->dirty_gen;
@ -1109,14 +933,14 @@ internal void user_update(P_Window *window)
Vec2I32 chunk_pos_bl = VEC2I32(chunk_pos.x - 1, chunk_pos.y + 1);
Vec2I32 chunk_pos_b = VEC2I32(chunk_pos.x, chunk_pos.y + 1);
Vec2I32 chunk_pos_br = VEC2I32(chunk_pos.x + 1, chunk_pos.y + 1);
Ent *chunk_ent_tl = sim_ent_from_chunk_pos(chunk_pos_tl);
Ent *chunk_ent_t = sim_ent_from_chunk_pos(chunk_pos_t);
Ent *chunk_ent_tr = sim_ent_from_chunk_pos(chunk_pos_tr);
Ent *chunk_ent_l = sim_ent_from_chunk_pos(chunk_pos_l);
Ent *chunk_ent_r = sim_ent_from_chunk_pos(chunk_pos_r);
Ent *chunk_ent_bl = sim_ent_from_chunk_pos(chunk_pos_bl);
Ent *chunk_ent_b = sim_ent_from_chunk_pos(chunk_pos_b);
Ent *chunk_ent_br = sim_ent_from_chunk_pos(chunk_pos_br);
Entity *chunk_ent_tl = sim_ent_from_chunk_pos(chunk_pos_tl);
Entity *chunk_ent_t = sim_ent_from_chunk_pos(chunk_pos_t);
Entity *chunk_ent_tr = sim_ent_from_chunk_pos(chunk_pos_tr);
Entity *chunk_ent_l = sim_ent_from_chunk_pos(chunk_pos_l);
Entity *chunk_ent_r = sim_ent_from_chunk_pos(chunk_pos_r);
Entity *chunk_ent_bl = sim_ent_from_chunk_pos(chunk_pos_bl);
Entity *chunk_ent_b = sim_ent_from_chunk_pos(chunk_pos_b);
Entity *chunk_ent_br = sim_ent_from_chunk_pos(chunk_pos_br);
String data = sim_ent_get_chunk_tile_data(chunk_ent);
@ -1131,16 +955,16 @@ internal void user_update(P_Window *window)
* Sort drawable entities
* ========================== */
Ent **sorted = PushDry(scratch.arena, Ent *);
Entity **sorted = PushDry(scratch.arena, Entity *);
u64 sorted_count = 0;
{
/* Copy valid entities */
{
__profn("Build ents list for sorting");
for (u64 ent_index = 0; ent_index < G.ss_blended->num_ents_reserved; ++ent_index) {
Ent *ent = &G.ss_blended->ents[ent_index];
Entity *ent = &G.ss_blended->ents[ent_index];
if (sim_ent_is_valid_and_active(ent)) {
*PushStructNoZero(scratch.arena, Ent *) = ent;
*PushStructNoZero(scratch.arena, Entity *) = ent;
++sorted_count;
}
}
@ -1159,13 +983,13 @@ internal void user_update(P_Window *window)
{
__profn("Draw entities");
for (u64 sorted_index = 0; sorted_index < sorted_count; ++sorted_index) {
Ent *ent = sorted[sorted_index];
Entity *ent = sorted[sorted_index];
if (!sim_ent_is_valid_and_active(ent)) continue;
//if (S_IsTagNil(ent->sprite)) continue;
S_Tag sprite = ent->sprite;
Ent *parent = sim_ent_from_id(G.ss_blended, ent->parent);
Entity *parent = sim_ent_from_id(G.ss_blended, ent->parent);
Xform xf = sim_ent_get_xform(ent);
Xform parent_xf = sim_ent_get_xform(parent);
@ -1337,7 +1161,7 @@ internal void user_update(P_Window *window)
/* Draw weld joint */
#if 0
if (sim_ent_has_prop(ent, SEPROP_WELD_JOINT)) {
Ent *e1 = sim_ent_from_id(G.ss_blended, ent->weld_joint_data.e1);
Entity *e1 = sim_ent_from_id(G.ss_blended, ent->weld_joint_data.e1);
Xform e1_xf = sim_ent_get_xform(e1);
u32 color = ColorYellow;
@ -1352,7 +1176,7 @@ internal void user_update(P_Window *window)
/* Draw mouse joint */
if (sim_ent_has_prop(ent, SEPROP_MOUSE_JOINT)) {
Ent *target = sim_ent_from_id(G.ss_blended, ent->mouse_joint_data.target);
Entity *target = sim_ent_from_id(G.ss_blended, ent->mouse_joint_data.target);
Xform target_xf = sim_ent_get_xform(target);
u32 color = ColorWhite;
Vec2 point_start = MulXformV2(target_xf, ent->mouse_joint_data.point_local_start);
@ -1402,8 +1226,8 @@ internal void user_update(P_Window *window)
/* Draw contact constraint */
if (sim_ent_has_prop(ent, SEPROP_CONTACT_CONSTRAINT)) {
ContactConstraint *data = &ent->contact_constraint_data;
Ent *e0 = sim_ent_from_id(G.ss_blended, data->e0);
Ent *e1 = sim_ent_from_id(G.ss_blended, data->e1);
Entity *e0 = sim_ent_from_id(G.ss_blended, data->e0);
Entity *e1 = sim_ent_from_id(G.ss_blended, data->e1);
(UNUSED)e0;
(UNUSED)e1;
@ -1472,8 +1296,8 @@ internal void user_update(P_Window *window)
if (sim_ent_has_prop(ent, SEPROP_COLLISION_DEBUG)) {
CollisionDebugData *data = &ent->collision_debug_data;
CLD_CollisionData collision_reuslt = data->collision_result;
Ent *e0 = sim_ent_from_id(G.ss_blended, data->e0);
Ent *e1 = sim_ent_from_id(G.ss_blended, data->e1);
Entity *e0 = sim_ent_from_id(G.ss_blended, data->e0);
Entity *e1 = sim_ent_from_id(G.ss_blended, data->e1);
CLD_Shape e0_collider = e0->local_collider;
CLD_Shape e1_collider = e1->local_collider;
(UNUSED)e0_collider;
@ -1896,7 +1720,7 @@ internal void user_update(P_Window *window)
* ========================== */
if (G.debug_draw && hovered_ent->valid) {
Ent *ent = hovered_ent;
Entity *ent = hovered_ent;
Vec2 pos = AddVec2(G.ui_cursor, VEC2(15, 15));
F_Font *font = F_LoadFontAsync(Lit("font/fixedsys.ttf"), 12.0f);
@ -2117,9 +1941,9 @@ internal void generate_user_input_cmds(Client *user_input_client, u64 tick)
{
Snapshot *prev_user_input_ss = sim_snapshot_from_tick(user_input_client, user_input_client->last_tick);
Snapshot *user_input_ss = sim_snapshot_alloc(user_input_client, prev_user_input_ss, tick);
Ent *user_input_root = sim_ent_from_id(user_input_ss, SIM_ENT_ROOT_ID);
Entity *user_input_root = sim_ent_from_id(user_input_ss, SIM_ENT_ROOT_ID);
/* Find / create local control cmd ent */
Ent *control_cmd = sim_ent_find_first_match_one(user_input_ss, SEPROP_CMD);
Entity *control_cmd = sim_ent_find_first_match_one(user_input_ss, SEPROP_CMD);
if (!control_cmd->valid) {
control_cmd = sim_ent_alloc_sync_src(user_input_root);
control_cmd->cmd_kind = SIM_CMD_KIND_CONTROL;
@ -2137,7 +1961,7 @@ internal void generate_user_input_cmds(Client *user_input_client, u64 tick)
#if 0
/* Create chat cmd */
if (G.user_sim_cmd_chat.len > 0) {
Ent *chat_cmd = sim_ent_alloc_sync_src(user_input_root);
Entity *chat_cmd = sim_ent_alloc_sync_src(user_input_root);
chat_cmd->cmd_kind = SIM_CMD_KIND_CHAT;
//chat_cmd->chat_msg = ZI
}
@ -2400,7 +2224,7 @@ internal P_JobDef(local_sim_job, _)
/* Assume all incoming ents want to be sync srcs */
for (u64 i = 0; i < ss->num_ents_reserved; ++i) {
Ent *ent = &ss->ents[i];
Entity *ent = &ss->ents[i];
if (ent->valid && sim_ent_has_prop(ent, SEPROP_SYNC_DST)) {
sim_ent_disable_prop(ent, SEPROP_SYNC_DST);
sim_ent_enable_prop(ent, SEPROP_SYNC_SRC);
@ -2602,7 +2426,7 @@ internal P_JobDef(local_sim_job, _)
}
if (master_ss->valid) {
Ent *master_player = sim_ent_find_first_match_one(master_ss, SEPROP_PLAYER_IS_MASTER);
Entity *master_player = sim_ent_find_first_match_one(master_ss, SEPROP_PLAYER_IS_MASTER);
/* Update ent id from master */
{

View File

@ -48,11 +48,394 @@ enum user_bind_kind {
};
struct user_startup_receipt { i32 _; };
struct bind_state
{
b32 is_held; /* Is this bind held down this frame */
u32 num_presses; /* How many times was this bind's pressed since last frame */
u32 num_repeats; /* How many times was this bind's key repeated since last frame */
u32 num_presses_and_repeats; /* Same as `num_presses` but includes key repeats as well */
u32 num_releases; /* How many times was this bind released since last frame */
};
struct second_stat
{
u64 last_second_start;
u64 last_second_end;
u64 last_second;
};
struct console_log
{
String msg;
i32 level;
i32 color_index;
P_DateTime datetime;
i64 time_ns;
Rect bounds;
struct console_log *prev;
struct console_log *next;
};
struct sim_ss_decode_node
{
Client *client;
u64 tick;
u64 base_tick;
String tmp_encoded;
struct sim_ss_decode_node *next;
};
struct sim_decode_queue
{
struct sim_ss_decode_node *first;
struct sim_ss_decode_node *last;
};
Global struct
{
Atomic32 shutdown;
P_Counter shutdown_job_counters;
P_Window *window;
GPU_Swapchain *swapchain;
struct sim_ctx *local_sim_ctx;
Arena *arena;
String connect_address_str;
ClientStore *user_client_store;
Client *user_unblended_client; /* Contains snapshots received from local sim */
Client *user_blended_client; /* Contains single snapshot from result of blending local sim snapshots */
Snapshot *ss_blended; /* Points to blended snapshot contained in blended client */
/* Usage stats */
i64 last_second_reset_ns;
struct second_stat net_bytes_read;
struct second_stat net_bytes_sent;
/* Gpu resources */
GPU_RenderSig *render_sig;
struct bind_state bind_states[USER_BIND_KIND_COUNT];
/* Debug camera */
EntityId debug_following;
b32 debug_camera;
b32 debug_camera_panning;
Vec2 debug_camera_pan_start;
b32 debug_draw;
/* Debug console */
P_Mutex console_logs_mutex;
Arena *console_logs_arena;
struct console_log *first_console_log;
struct console_log *last_console_log;
i32 console_log_color_indices[P_LogLevel_Count];
f32 console_logs_height;
b32 debug_console;
/* Window -> user */
P_Mutex sys_window_events_mutex;
Arena *sys_window_events_arena;
/* User -> local sim */
P_Mutex user_sim_cmd_mutex;
ControlData user_sim_cmd_control;
EntityId user_hovered_ent;
u64 last_user_sim_cmd_gen;
u64 user_sim_cmd_gen;
Atomic32 user_paused;
Atomic32 user_paused_steps;
/* Local sim -> user */
P_Mutex local_to_user_client_mutex;
ClientStore *local_to_user_client_store;
Client *local_to_user_client;
i64 local_to_user_client_publish_dt_ns;
i64 local_to_user_client_publish_time_ns;
/* Rolling window of local sim -> user publish time deltas */
i64 last_local_to_user_snapshot_published_at_ns;
i64 average_local_to_user_snapshot_publish_dt_ns;
i64 local_sim_predicted_time_ns; /* Calculated from <last local sim to user pubilsh time> + <time since last local sim to user publish> */
i64 render_time_target_ns; /* Claculated from <local_sim_rpedicted_time_ns> - <render interp delay> */
i64 render_time_ns; /* Incremented at a constant rate based on average local to user publish delta, but snaps to render_time_target_ns if it gets too distant */
u64 local_sim_last_known_tick;
i64 local_sim_last_known_time_ns;
i64 real_dt_ns;
i64 real_time_ns;
/* Per-frame */
Vec2 screen_size;
Vec2 screen_cursor;
Xform ui_to_screen_xf;
Vec2 ui_size;
Vec2 ui_cursor;
Xform render_to_ui_xf;
Vec2 render_size;
Xform world_to_render_xf;
Xform world_to_ui_xf;
Vec2 world_cursor;
Vec2 focus_send;
} G = ZI, DebugAlias(G, G_user);
/* ========================== *
* Bind state
* ========================== */
/* TODO: Remove this */
Global Readonly enum user_bind_kind g_binds[P_Btn_Count] = {
[P_Btn_W] = USER_BIND_KIND_MOVE_UP,
[P_Btn_S] = USER_BIND_KIND_MOVE_DOWN,
[P_Btn_A] = USER_BIND_KIND_MOVE_LEFT,
[P_Btn_D] = USER_BIND_KIND_MOVE_RIGHT,
//[P_Btn_Alt] = USER_BIND_KIND_WALK,
[P_Btn_M1] = USER_BIND_KIND_FIRE,
[P_Btn_M2] = USER_BIND_KIND_FIRE_ALT,
/* Testing */
[P_Btn_Z] = USER_BIND_KIND_TILE_TEST,
[P_Btn_M5] = USER_BIND_KIND_DEBUG_DRAG,
[P_Btn_M4] = USER_BIND_KIND_DEBUG_DELETE,
[P_Btn_F] = USER_BIND_KIND_DEBUG_EXPLODE,
[P_Btn_T] = USER_BIND_KIND_DEBUG_TELEPORT,
[P_Btn_C] = USER_BIND_KIND_DEBUG_CLEAR,
[P_Btn_1] = USER_BIND_KIND_DEBUG_SPAWN1,
[P_Btn_2] = USER_BIND_KIND_DEBUG_SPAWN2,
[P_Btn_3] = USER_BIND_KIND_DEBUG_SPAWN3,
[P_Btn_4] = USER_BIND_KIND_DEBUG_SPAWN4,
[P_Btn_G] = USER_BIND_KIND_DEBUG_WALLS,
[P_Btn_N] = USER_BIND_KIND_DEBUG_STEP,
[P_Btn_Q] = USER_BIND_KIND_DEBUG_FOLLOW,
[P_Btn_F1] = USER_BIND_KIND_DEBUG_PAUSE,
[P_Btn_F2] = USER_BIND_KIND_DEBUG_CAMERA,
[P_Btn_F3] = USER_BIND_KIND_DEBUG_DRAW,
[P_Btn_F4] = USER_BIND_KIND_DEBUG_TOGGLE_TOPMOST,
[P_Btn_GraveAccent] = USER_BIND_KIND_DEBUG_CONSOLE,
[P_Btn_Alt] = USER_BIND_KIND_FULLSCREEN_MOD,
[P_Btn_Enter] = USER_BIND_KIND_FULLSCREEN,
[P_Btn_MWheelUp] = USER_BIND_KIND_ZOOM_IN,
[P_Btn_MWheelDown] = USER_BIND_KIND_ZOOM_OUT,
[P_Btn_M3] = USER_BIND_KIND_PAN,
#if RtcIsEnabled
/* Debug */
[P_Btn_ForwardSlash] = USER_BIND_KIND_RESET_DEBUG_STEPS,
[P_Btn_Comma] = USER_BIND_KIND_DECR_DEBUG_STEPS,
[P_Btn_Period] = USER_BIND_KIND_INCR_DEBUG_STEPS
#endif
};
/* ========================== *
* Startup
* ========================== */
struct user_startup_receipt user_startup(F_StartupReceipt *font_sr,
S_StartupReceipt *sprite_sr,
S_StartupReceipt *sprite_sr,
D_StartupReceipt *draw_sr,
AC_StartupReceipt *asset_cache_sr,
SND_StartupReceipt *sound_sr,
MIX_StartupReceipt *mixer_sr,
SimStartupReceipt *sim_sr,
String connect_address_str);
String connect_address_str)
internal P_ExitFuncDef(user_shutdown)
/* ========================== *
* Debug draw
* ========================== */
/* TODO: remove this (testing) */
internal void debug_draw_xform(Xform xf, u32 color_x, u32 color_y)
internal void debug_draw_movement(Entity *ent)
internal String get_ent_debug_text(Arena *arena, Entity *ent)
/* ========================== *
* Debug console
* ========================== */
internal P_LogEventCallbackFuncDef(debug_console_log_callback, log)
internal void draw_debug_console(i32 level, b32 minimized)
/* ========================== *
* Sort entities
* ========================== */
internal MergesortCompareFuncDef(ent_draw_order_cmp, arg_a, arg_b, _)
/* ========================== *
* Update
* ========================== */
internal void user_update(P_Window *window)
internal P_JobDef(user_update_job, _)
/* ========================== *
* Local sim thread
* ========================== */
internal void generate_user_input_cmds(Client *user_input_client, u64 tick)
internal P_JobDef(local_sim_job, _)