nil entity
This commit is contained in:
parent
f260bf6579
commit
255626f934
@ -119,6 +119,7 @@ extern "C" {
|
|||||||
|
|
||||||
#define ASSERT(cond) ((cond) ? 1 : (__builtin_trap(), 0))
|
#define ASSERT(cond) ((cond) ? 1 : (__builtin_trap(), 0))
|
||||||
#define DEBUGBREAK __builtin_debugtrap()
|
#define DEBUGBREAK __builtin_debugtrap()
|
||||||
|
#define DEBUGBREAKABLE { volatile i32 __DEBUGBREAKABLE_VAR = 0; (UNUSED) __DEBUGBREAKABLE_VAR; }
|
||||||
|
|
||||||
/* Address sanitization */
|
/* Address sanitization */
|
||||||
#if 0
|
#if 0
|
||||||
@ -159,6 +160,9 @@ extern "C" {
|
|||||||
#define INTERNAL static
|
#define INTERNAL static
|
||||||
#define GLOBAL static
|
#define GLOBAL static
|
||||||
|
|
||||||
|
#pragma section(".roglob", read)
|
||||||
|
#define READONLY __declspec(allocate(".roglob"))
|
||||||
|
|
||||||
/* Markup */
|
/* Markup */
|
||||||
#define UNUSED void
|
#define UNUSED void
|
||||||
#define FALLTHROUGH __attribute((fallthrough))
|
#define FALLTHROUGH __attribute((fallthrough))
|
||||||
|
|||||||
5
src/entity.c
Normal file
5
src/entity.c
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
#include "entity.h"
|
||||||
|
|
||||||
|
READONLY struct entity _g_entity_nil = {
|
||||||
|
0
|
||||||
|
};
|
||||||
12
src/entity.h
12
src/entity.h
@ -30,7 +30,7 @@ enum entity_prop {
|
|||||||
};
|
};
|
||||||
|
|
||||||
struct entity {
|
struct entity {
|
||||||
b32 active;
|
b32 valid;
|
||||||
struct entity_handle handle;
|
struct entity_handle handle;
|
||||||
u64 continuity_gen;
|
u64 continuity_gen;
|
||||||
u64 props[(ENTITY_PROP_COUNT + 63) / 64];
|
u64 props[(ENTITY_PROP_COUNT + 63) / 64];
|
||||||
@ -94,17 +94,15 @@ struct entity {
|
|||||||
|
|
||||||
/* ====================================================================== */
|
/* ====================================================================== */
|
||||||
/* ENTITY_PROP_CAMERA */
|
/* ENTITY_PROP_CAMERA */
|
||||||
/* TODO */
|
|
||||||
|
|
||||||
|
struct entity_handle camera_follow;
|
||||||
};
|
};
|
||||||
|
|
||||||
/* ========================== *
|
extern READONLY struct entity _g_entity_nil;
|
||||||
* Handle
|
|
||||||
* ========================== */
|
|
||||||
|
|
||||||
INLINE b32 entity_is_valid(struct entity_handle eh)
|
INLINE READONLY struct entity *entity_nil(void)
|
||||||
{
|
{
|
||||||
return eh.gen != 0;
|
return &_g_entity_nil;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ========================== *
|
/* ========================== *
|
||||||
|
|||||||
56
src/game.c
56
src/game.c
@ -68,29 +68,34 @@ INTERNAL void entity_release(struct entity *entity)
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/* Returns a valid entity or nil entity. Always safe to read result, need to check to write. */
|
||||||
INTERNAL struct entity *entity_from_handle(struct entity_handle eh)
|
INTERNAL struct entity *entity_from_handle(struct entity_handle eh)
|
||||||
{
|
{
|
||||||
if (eh.idx < ARRAY_COUNT(L.tick.entities)) {
|
if (eh.idx < L.tick.entities_count) {
|
||||||
struct entity *entity = &L.tick.entities[eh.idx];
|
struct entity *entity = &L.tick.entities[eh.idx];
|
||||||
if (entity->handle.gen == eh.gen) {
|
if (entity->handle.gen == eh.gen) {
|
||||||
return entity;
|
return entity;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return NULL;
|
return entity_nil();
|
||||||
}
|
}
|
||||||
|
|
||||||
INTERNAL void entity_tree_attach(struct entity *parent, struct entity *child)
|
INTERNAL void entity_tree_attach(struct entity *parent, struct entity *child)
|
||||||
{
|
{
|
||||||
if (entity_is_valid(parent->last)) {
|
struct entity *first_child = entity_from_handle(parent->first);
|
||||||
struct entity *last_child = entity_from_handle(parent->last);
|
struct entity *last_child = entity_from_handle(parent->last);
|
||||||
last_child->next = child->handle;
|
|
||||||
child->prev = last_child->handle;
|
child->prev = last_child->handle;
|
||||||
|
child->parent = parent->handle;
|
||||||
|
|
||||||
|
if (last_child->valid) {
|
||||||
|
last_child->next = child->handle;
|
||||||
}
|
}
|
||||||
parent->last = child->handle;
|
parent->last = child->handle;
|
||||||
if (!entity_is_valid(parent->first)) {
|
|
||||||
|
if (!first_child->valid) {
|
||||||
parent->first = child->handle;
|
parent->first = child->handle;
|
||||||
}
|
}
|
||||||
child->parent = parent->handle;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ========================== *
|
/* ========================== *
|
||||||
@ -162,10 +167,11 @@ INTERNAL void game_update(void)
|
|||||||
static b32 run = 0;
|
static b32 run = 0;
|
||||||
if (!run) {
|
if (!run) {
|
||||||
run = 1;
|
run = 1;
|
||||||
|
(UNUSED)entity_tree_attach;
|
||||||
|
|
||||||
/* Player ent */
|
/* Player ent */
|
||||||
|
struct entity *player_ent;
|
||||||
{
|
{
|
||||||
(UNUSED)entity_tree_attach;
|
|
||||||
|
|
||||||
struct string sprite_name = STR("res/graphics/timmy.ase");
|
struct string sprite_name = STR("res/graphics/timmy.ase");
|
||||||
|
|
||||||
@ -177,23 +183,34 @@ INTERNAL void game_update(void)
|
|||||||
struct v2 pos = V2(0, 0);
|
struct v2 pos = V2(0, 0);
|
||||||
|
|
||||||
struct entity *e = entity_alloc();
|
struct entity *e = entity_alloc();
|
||||||
e->active = true;
|
e->valid = true;
|
||||||
//e->rel_trs = TRS(.t = pos, .r = 0, .s = V2(3, 1));
|
//e->rel_trs = TRS(.t = pos, .r = 0, .s = V2(3, 1));
|
||||||
e->rel_trs = TRS(.t = pos, .r = 0, .s = V2(1, 1));
|
e->rel_trs = TRS(.t = pos, .r = 0, .s = V2(1, 1));
|
||||||
|
|
||||||
e->sprite_name = sprite_name;
|
e->sprite_name = sprite_name;
|
||||||
e->sprite_trs = TRS(.s = sprite_size);
|
e->sprite_trs = TRS(.s = sprite_size);
|
||||||
e->sprite_pivot_norm = V2(0, 0.65);
|
e->sprite_pivot_norm = V2(0, 0.65);
|
||||||
|
//e->sprite_pivot_norm = V2(0.4, 0.65);
|
||||||
e->sprite_tint = COLOR_WHITE;
|
e->sprite_tint = COLOR_WHITE;
|
||||||
|
|
||||||
entity_enable_prop(e, ENTITY_PROP_PLAYER_CONTROLLED);
|
entity_enable_prop(e, ENTITY_PROP_PLAYER_CONTROLLED);
|
||||||
e->player_acceleration_magnitude = 5.0f;
|
e->player_acceleration_magnitude = 6.f;
|
||||||
e->drag = 2.0;
|
e->drag = 5;
|
||||||
|
|
||||||
|
player_ent = e;
|
||||||
|
|
||||||
//entity_enable_prop(e, ENTITY_PROP_TEST);
|
//entity_enable_prop(e, ENTITY_PROP_TEST);
|
||||||
//entity_enable_prop(e, ENTITY_PROP_TEST_FOLLOW_MOUSE);
|
//entity_enable_prop(e, ENTITY_PROP_TEST_FOLLOW_MOUSE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Camera ent */
|
||||||
|
{
|
||||||
|
struct entity *e = entity_alloc();
|
||||||
|
e->valid = true;
|
||||||
|
e->rel_trs = TRS();
|
||||||
|
|
||||||
|
e->camera_follow = player_ent->handle;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ========================== *
|
/* ========================== *
|
||||||
@ -233,7 +250,7 @@ INTERNAL void game_update(void)
|
|||||||
|
|
||||||
for (u64 entity_index = 0; entity_index < ARRAY_COUNT(L.tick.entities); ++entity_index) {
|
for (u64 entity_index = 0; entity_index < ARRAY_COUNT(L.tick.entities); ++entity_index) {
|
||||||
struct entity *ent = &L.tick.entities[entity_index];
|
struct entity *ent = &L.tick.entities[entity_index];
|
||||||
if (!ent->active) continue;
|
if (!ent->valid) continue;
|
||||||
|
|
||||||
/* ========================== *
|
/* ========================== *
|
||||||
* Initialize
|
* Initialize
|
||||||
@ -304,8 +321,8 @@ break_animation:
|
|||||||
|
|
||||||
for (u64 entity_index = 0; entity_index < ARRAY_COUNT(L.tick.entities); ++entity_index) {
|
for (u64 entity_index = 0; entity_index < ARRAY_COUNT(L.tick.entities); ++entity_index) {
|
||||||
struct entity *ent = &L.tick.entities[entity_index];
|
struct entity *ent = &L.tick.entities[entity_index];
|
||||||
if (!ent->active) continue;
|
if (!ent->valid) continue;
|
||||||
if (entity_is_valid(ent->parent)) continue; /* Only update parent entities */
|
if (ent->parent.gen) continue; /* Only update parent entities */
|
||||||
|
|
||||||
/* ========================== *
|
/* ========================== *
|
||||||
* Player movement
|
* Player movement
|
||||||
@ -349,6 +366,13 @@ break_animation:
|
|||||||
ent->test_start_rel_trs.t = L.tick.player_focus;
|
ent->test_start_rel_trs.t = L.tick.player_focus;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* ========================== *
|
||||||
|
* Update camera position
|
||||||
|
* ========================== */
|
||||||
|
if (ent->camera_follow.gen) {
|
||||||
|
//struct entity *
|
||||||
|
}
|
||||||
|
|
||||||
/* ========================== *
|
/* ========================== *
|
||||||
* Calculate xforms
|
* Calculate xforms
|
||||||
* ========================== */
|
* ========================== */
|
||||||
@ -357,7 +381,7 @@ break_animation:
|
|||||||
|
|
||||||
struct entity *child = entity_from_handle(ent->first);
|
struct entity *child = entity_from_handle(ent->first);
|
||||||
struct mat3x3 parent_xform = ent->world_xform;
|
struct mat3x3 parent_xform = ent->world_xform;
|
||||||
while (child) {
|
while (child->valid) {
|
||||||
child->world_xform = mat3x3_trs(parent_xform, child->rel_trs);
|
child->world_xform = mat3x3_trs(parent_xform, child->rel_trs);
|
||||||
|
|
||||||
/* Depth first iteration */
|
/* Depth first iteration */
|
||||||
@ -375,7 +399,7 @@ break_animation:
|
|||||||
parent_xform = grandparent->world_xform;
|
parent_xform = grandparent->world_xform;
|
||||||
child = entity_from_handle(parent->next);
|
child = entity_from_handle(parent->next);
|
||||||
} else {
|
} else {
|
||||||
child = NULL;
|
child = entity_nil();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -386,7 +410,7 @@ break_animation:
|
|||||||
|
|
||||||
for (u64 entity_index = 0; entity_index < ARRAY_COUNT(L.tick.entities); ++entity_index) {
|
for (u64 entity_index = 0; entity_index < ARRAY_COUNT(L.tick.entities); ++entity_index) {
|
||||||
struct entity *ent = &L.tick.entities[entity_index];
|
struct entity *ent = &L.tick.entities[entity_index];
|
||||||
if (!ent->active) continue;
|
if (!ent->valid) continue;
|
||||||
|
|
||||||
/* ========================== *
|
/* ========================== *
|
||||||
* Update sound emitter
|
* Update sound emitter
|
||||||
|
|||||||
@ -777,6 +777,7 @@ INTERNAL LRESULT CALLBACK win32_window_proc(HWND hwnd, UINT msg, WPARAM wparam,
|
|||||||
result = DefWindowProcA(hwnd, msg, wparam, lparam);
|
result = DefWindowProcA(hwnd, msg, wparam, lparam);
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
|
/* Keyboard buttons */
|
||||||
case WM_SYSKEYUP:
|
case WM_SYSKEYUP:
|
||||||
case WM_SYSKEYDOWN: {
|
case WM_SYSKEYDOWN: {
|
||||||
result = DefWindowProcA(hwnd, msg, wparam, lparam);
|
result = DefWindowProcA(hwnd, msg, wparam, lparam);
|
||||||
@ -787,10 +788,10 @@ INTERNAL LRESULT CALLBACK win32_window_proc(HWND hwnd, UINT msg, WPARAM wparam,
|
|||||||
b32 is_repeat = false;
|
b32 is_repeat = false;
|
||||||
|
|
||||||
enum sys_event_kind event_kind = SYS_EVENT_KIND_NONE;
|
enum sys_event_kind event_kind = SYS_EVENT_KIND_NONE;
|
||||||
if (msg == WM_KEYDOWN) {
|
if (msg == WM_KEYDOWN || msg == WM_SYSKEYDOWN) {
|
||||||
event_kind = SYS_EVENT_KIND_BUTTON_DOWN;
|
event_kind = SYS_EVENT_KIND_BUTTON_DOWN;
|
||||||
is_repeat = (lparam & 0x40000000) != 0;
|
is_repeat = (lparam & 0x40000000) != 0;
|
||||||
} else if (msg == WM_KEYUP) {
|
} else if (msg == WM_KEYUP || msg == WM_SYSKEYUP) {
|
||||||
event_kind = SYS_EVENT_KIND_BUTTON_UP;
|
event_kind = SYS_EVENT_KIND_BUTTON_UP;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -809,6 +810,7 @@ INTERNAL LRESULT CALLBACK win32_window_proc(HWND hwnd, UINT msg, WPARAM wparam,
|
|||||||
);
|
);
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
|
/* Text */
|
||||||
case WM_SYSCHAR:
|
case WM_SYSCHAR:
|
||||||
case WM_CHAR: {
|
case WM_CHAR: {
|
||||||
u32 character = (u32)wparam;
|
u32 character = (u32)wparam;
|
||||||
@ -871,6 +873,7 @@ INTERNAL LRESULT CALLBACK win32_window_proc(HWND hwnd, UINT msg, WPARAM wparam,
|
|||||||
}
|
}
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
|
/* Mouse wheel */
|
||||||
case WM_MOUSEWHEEL: {
|
case WM_MOUSEWHEEL: {
|
||||||
int delta = GET_WHEEL_DELTA_WPARAM(wparam);
|
int delta = GET_WHEEL_DELTA_WPARAM(wparam);
|
||||||
i32 dir = delta >= 0 ? 1 : -1;
|
i32 dir = delta >= 0 ? 1 : -1;
|
||||||
|
|||||||
@ -503,7 +503,7 @@ INTERNAL void user_update(void)
|
|||||||
/* Iterate entities */
|
/* Iterate entities */
|
||||||
for (u64 entity_index = 0; entity_index < tick->entities_count; ++entity_index) {
|
for (u64 entity_index = 0; entity_index < tick->entities_count; ++entity_index) {
|
||||||
struct entity *ent = &tick->entities[entity_index];
|
struct entity *ent = &tick->entities[entity_index];
|
||||||
if (!ent->active) continue;
|
if (!ent->valid) continue;
|
||||||
|
|
||||||
/* Draw sprite */
|
/* Draw sprite */
|
||||||
if (ent->sprite_name.len > 0) {
|
if (ent->sprite_name.len > 0) {
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user