camera entity

This commit is contained in:
jacob 2024-03-05 22:51:10 -06:00
parent 255626f934
commit a4dc273480
8 changed files with 105 additions and 68 deletions

View File

@ -193,7 +193,7 @@ if (UNOPTIMIZED)
set(COMPILER_FLAGS "${COMPILER_FLAGS} -O0 -DUNOPTIMIZED=1") set(COMPILER_FLAGS "${COMPILER_FLAGS} -O0 -DUNOPTIMIZED=1")
set(LINKER_FLAGS "${LINKER_FLAGS} -O0") set(LINKER_FLAGS "${LINKER_FLAGS} -O0")
else() else()
set(COMPILER_FLAGS "${COMPILER_FLAGS} -O3 -flto") set(COMPILER_FLAGS "${COMPILER_FLAGS} -O3 -flto -fwhole-program")
set(LINKER_FLAGS "${LINKER_FLAGS} -O3 -flto -fwhole-program") set(LINKER_FLAGS "${LINKER_FLAGS} -O3 -flto -fwhole-program")
endif() endif()

View File

@ -1,5 +1,43 @@
#include "entity.h" #include "entity.h"
READONLY struct entity _g_entity_nil = { READONLY struct entity _g_entity_nil = { 0 };
0
}; /* ========================== *
* Prop
* ========================== */
void entity_enable_prop(struct entity *entity, enum entity_prop prop)
{
u64 index = prop / 64;
u64 bit = prop % 64;
entity->props[index] |= ((u64)1 << bit);
}
void entity_disable_prop(struct entity *entity, enum entity_prop prop)
{
u64 index = prop / 64;
u64 bit = prop % 64;
entity->props[index] &= ~((u64)1 << bit);
}
b32 entity_has_prop(struct entity *entity, enum entity_prop prop)
{
u64 index = prop / 64;
u64 bit = prop % 64;
return !!(entity->props[index] & ((u64)1 << bit));
}
/* ========================== *
* Animation
* ========================== */
/* TODO: Move this to game */
void entity_start_animation(struct entity *entity, struct string animation_name, u64 flags)
{
entity_enable_prop(entity, ENTITY_PROP_SPRITE_ANIMATED);
entity->animation_name = animation_name;
entity->animation_flags = flags;
entity->animation_time_in_frame = 0;
++entity->animation_start_gen;
}

View File

@ -93,11 +93,16 @@ struct entity {
struct mixer_track_handle sound_handle; struct mixer_track_handle sound_handle;
/* ====================================================================== */ /* ====================================================================== */
/* ENTITY_PROP_CAMERA */
/* ENTITY_PROP_CAMERA */
b32 camera_active;
struct entity_handle camera_follow; struct entity_handle camera_follow;
f32 camera_rot;
f32 camera_zoom;
}; };
/* Nil entity */
extern READONLY struct entity _g_entity_nil; extern READONLY struct entity _g_entity_nil;
INLINE READONLY struct entity *entity_nil(void) INLINE READONLY struct entity *entity_nil(void)
@ -105,46 +110,17 @@ INLINE READONLY struct entity *entity_nil(void)
return &_g_entity_nil; return &_g_entity_nil;
} }
/* ========================== * /* Prop */
* Prop
* ========================== */
INLINE void entity_enable_prop(struct entity *entity, enum entity_prop prop) { void entity_enable_prop(struct entity *entity, enum entity_prop prop);
u64 index = prop / 64; void entity_disable_prop(struct entity *entity, enum entity_prop prop);
u64 bit = prop % 64; b32 entity_has_prop(struct entity *entity, enum entity_prop prop);
entity->props[index] |= ((u64)1 << bit);
}
INLINE void entity_disable_prop(struct entity *entity, enum entity_prop prop) /* Animation */
{
u64 index = prop / 64;
u64 bit = prop % 64;
entity->props[index] &= ~((u64)1 << bit);
}
INLINE b32 entity_has_prop(struct entity *entity, enum entity_prop prop)
{
u64 index = prop / 64;
u64 bit = prop % 64;
return !!(entity->props[index] & ((u64)1 << bit));
}
/* ========================== *
* Animation
* ========================== */
/* TODO: Move this kind of stuff to game_thread? */
#define ANIMATION_FLAG_NONE 0x0 #define ANIMATION_FLAG_NONE 0x0
#define ANIMATION_FLAG_LOOPING 0x1 #define ANIMATION_FLAG_LOOPING 0x1
INLINE void entity_start_animation(struct entity *entity, struct string animation_name, u64 flags) void entity_start_animation(struct entity *entity, struct string animation_name, u64 flags);
{
entity_enable_prop(entity, ENTITY_PROP_SPRITE_ANIMATED);
entity->animation_name = animation_name;
entity->animation_flags = flags;
entity->animation_time_in_frame = 0;
++entity->animation_start_gen;
}
#endif #endif

View File

@ -10,7 +10,7 @@
#include "math.h" #include "math.h"
#include "scratch.h" #include "scratch.h"
#define GAME_FPS 30 #define GAME_FPS 50
GLOBAL struct { GLOBAL struct {
b32 shutdown; b32 shutdown;
@ -151,13 +151,6 @@ INTERNAL void game_update(void)
struct temp_arena scratch = scratch_begin_no_conflict(); struct temp_arena scratch = scratch_begin_no_conflict();
#if 0
/* TODO: remove this (testing variable frame latency) */
u32 rand = sys_rand_u32();
u32 sleep_ms = rand % 500;
sys_sleep((f64)sleep_ms / 1000);
#endif
++L.tick.id; ++L.tick.id;
L.tick.dt = max_f64(0.0, (1.0 / GAME_FPS) * L.timescale); L.tick.dt = max_f64(0.0, (1.0 / GAME_FPS) * L.timescale);
L.tick.time += L.tick.dt; L.tick.time += L.tick.dt;
@ -173,7 +166,7 @@ INTERNAL void game_update(void)
struct entity *player_ent; struct entity *player_ent;
{ {
struct string sprite_name = STR("res/graphics/timmy.ase"); struct string sprite_name = STR("res/graphics/tim.ase");
struct sheet *sheet = sheet_load(sprite_name); struct sheet *sheet = sheet_load(sprite_name);
f32 meters_width = sheet->image_size.x / PIXELS_PER_UNIT; f32 meters_width = sheet->image_size.x / PIXELS_PER_UNIT;
@ -194,7 +187,7 @@ INTERNAL void game_update(void)
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 = 6.f; e->player_acceleration_magnitude = 4.f;
e->drag = 5; e->drag = 5;
player_ent = e; player_ent = e;
@ -209,7 +202,11 @@ INTERNAL void game_update(void)
e->valid = true; e->valid = true;
e->rel_trs = TRS(); e->rel_trs = TRS();
entity_enable_prop(e, ENTITY_PROP_CAMERA);
e->camera_active = true;
e->camera_follow = player_ent->handle; e->camera_follow = player_ent->handle;
e->camera_zoom = 1;
} }
} }
@ -366,13 +363,6 @@ 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
* ========================== */ * ========================== */
@ -413,7 +403,20 @@ break_animation:
if (!ent->valid) continue; if (!ent->valid) continue;
/* ========================== * /* ========================== *
* Update sound emitter * Update camera position
* ========================== */
if (entity_has_prop(ent, ENTITY_PROP_CAMERA)) {
struct entity *follow = entity_from_handle(ent->camera_follow);
struct v2 pos = follow->rel_trs.t;
ent->rel_trs.t = pos;
ent->world_xform = mat3x3_from_trs(ent->rel_trs);
}
/* ========================== *
* Update sound emitters
* ========================== */ * ========================== */
if (entity_has_prop(ent, ENTITY_PROP_TEST_SOUND_EMITTER)) { if (entity_has_prop(ent, ENTITY_PROP_TEST_SOUND_EMITTER)) {

10
src/tick.c Normal file
View File

@ -0,0 +1,10 @@
#include "tick.h"
void tick_cpy(struct tick *dst, struct tick *src)
{
__prof;
/* Copy non-entity fields */
MEMCPY(dst, src, FIELD_OFFSETOF(struct tick, entities));
/* Copy entities */
MEMCPY(&dst->entities, &src->entities, sizeof(struct entity) * src->entities_count);
}

View File

@ -17,13 +17,6 @@ struct tick {
struct entity entities[MAX_ENTITIES]; struct entity entities[MAX_ENTITIES];
}; };
INLINE void tick_cpy(struct tick *dst, struct tick *src) void tick_cpy(struct tick *dst, struct tick *src);
{
__prof;
/* Copy non-entity fields */
MEMCPY(dst, src, FIELD_OFFSETOF(struct tick, entities));
/* Copy entities */
MEMCPY(&dst->entities, &src->entities, sizeof(struct entity) * src->entities_count);
}
#endif #endif

View File

@ -444,9 +444,13 @@ INTERNAL void user_update(void)
struct entity *e1 = &t1->entities[i]; struct entity *e1 = &t1->entities[i];
if (e0->handle.gen == e1->handle.gen && e0->continuity_gen == e1->continuity_gen) { if (e0->handle.gen == e1->handle.gen && e0->continuity_gen == e1->continuity_gen) {
e->rel_trs = trs_lerp(e0->rel_trs, e1->rel_trs, tick_blend); e->rel_trs = trs_lerp(e0->rel_trs, e1->rel_trs, tick_blend);
e->world_xform = mat3x3_lerp(e0->world_xform, e1->world_xform, tick_blend);
e->sprite_trs = trs_lerp(e0->sprite_trs, e1->sprite_trs, tick_blend); e->sprite_trs = trs_lerp(e0->sprite_trs, e1->sprite_trs, tick_blend);
e->sprite_pivot_norm = v2_lerp(e0->sprite_pivot_norm, e1->sprite_pivot_norm, tick_blend); e->sprite_pivot_norm = v2_lerp(e0->sprite_pivot_norm, e1->sprite_pivot_norm, tick_blend);
e->world_xform = mat3x3_lerp(e0->world_xform, e1->world_xform, tick_blend);
e->camera_rot = math_lerp_angle(e0->camera_rot, e1->camera_rot, tick_blend);
e->camera_zoom = math_lerp_f32(e0->camera_rot, e1->camera_rot, tick_blend);
} }
} }
@ -505,6 +509,19 @@ INTERNAL void user_update(void)
struct entity *ent = &tick->entities[entity_index]; struct entity *ent = &tick->entities[entity_index];
if (!ent->valid) continue; if (!ent->valid) continue;
/* Update view */
if (entity_has_prop(ent, ENTITY_PROP_CAMERA)) {
if (ent->camera_active) {
struct v2 center = mat3x3_get_pos(ent->world_xform);
f32 rot = ent->camera_rot;
f32 zoom = ent->camera_zoom;
zoom = zoom > 0 ? zoom : 1.0;
L.world_view.center = center;
L.world_view.rot = rot;
L.world_view.zoom = 1;
}
}
/* Draw sprite */ /* Draw sprite */
if (ent->sprite_name.len > 0) { if (ent->sprite_name.len > 0) {
struct string tex_name = ent->sprite_name; struct string tex_name = ent->sprite_name;