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(LINKER_FLAGS "${LINKER_FLAGS} -O0")
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")
endif()

View File

@ -1,5 +1,43 @@
#include "entity.h"
READONLY struct entity _g_entity_nil = {
0
};
READONLY struct entity _g_entity_nil = { 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;
/* ====================================================================== */
/* ENTITY_PROP_CAMERA */
/* ENTITY_PROP_CAMERA */
b32 camera_active;
struct entity_handle camera_follow;
f32 camera_rot;
f32 camera_zoom;
};
/* Nil entity */
extern READONLY struct entity _g_entity_nil;
INLINE READONLY struct entity *entity_nil(void)
@ -105,46 +110,17 @@ INLINE READONLY struct entity *entity_nil(void)
return &_g_entity_nil;
}
/* ========================== *
* Prop
* ========================== */
/* Prop */
INLINE 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_enable_prop(struct entity *entity, enum entity_prop prop);
void entity_disable_prop(struct entity *entity, enum entity_prop prop);
b32 entity_has_prop(struct entity *entity, enum entity_prop prop);
INLINE 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);
}
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? */
/* Animation */
#define ANIMATION_FLAG_NONE 0x0
#define ANIMATION_FLAG_LOOPING 0x1
INLINE 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;
}
void entity_start_animation(struct entity *entity, struct string animation_name, u64 flags);
#endif

View File

@ -10,7 +10,7 @@
#include "math.h"
#include "scratch.h"
#define GAME_FPS 30
#define GAME_FPS 50
GLOBAL struct {
b32 shutdown;
@ -151,13 +151,6 @@ INTERNAL void game_update(void)
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.dt = max_f64(0.0, (1.0 / GAME_FPS) * L.timescale);
L.tick.time += L.tick.dt;
@ -173,7 +166,7 @@ INTERNAL void game_update(void)
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);
f32 meters_width = sheet->image_size.x / PIXELS_PER_UNIT;
@ -194,7 +187,7 @@ INTERNAL void game_update(void)
e->sprite_tint = COLOR_WHITE;
entity_enable_prop(e, ENTITY_PROP_PLAYER_CONTROLLED);
e->player_acceleration_magnitude = 6.f;
e->player_acceleration_magnitude = 4.f;
e->drag = 5;
player_ent = e;
@ -209,7 +202,11 @@ INTERNAL void game_update(void)
e->valid = true;
e->rel_trs = TRS();
entity_enable_prop(e, ENTITY_PROP_CAMERA);
e->camera_active = true;
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;
}
/* ========================== *
* Update camera position
* ========================== */
if (ent->camera_follow.gen) {
//struct entity *
}
/* ========================== *
* Calculate xforms
* ========================== */
@ -413,7 +403,20 @@ break_animation:
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)) {

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];
};
INLINE 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);
}
void tick_cpy(struct tick *dst, struct tick *src);
#endif

View File

@ -444,9 +444,13 @@ INTERNAL void user_update(void)
struct entity *e1 = &t1->entities[i];
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->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_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];
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 */
if (ent->sprite_name.len > 0) {
struct string tex_name = ent->sprite_name;