entity & sprite translation
This commit is contained in:
parent
7b2437889e
commit
fb2e026665
@ -126,7 +126,7 @@ add_executable(powerplay_exe ${sources})
|
||||
set_target_properties(
|
||||
powerplay_exe PROPERTIES
|
||||
C_STANDARD 99
|
||||
OUTPUT_NAME "${PROJECT_NAME}.exe"
|
||||
OUTPUT_NAME "PowerPlay.exe"
|
||||
)
|
||||
|
||||
# Add precompiled header
|
||||
|
||||
BIN
res/graphics/timmy.ase
(Stored with Git LFS)
BIN
res/graphics/timmy.ase
(Stored with Git LFS)
Binary file not shown.
37
src/common.h
37
src/common.h
@ -380,16 +380,31 @@ struct v2 {
|
||||
f32 x, y;
|
||||
};
|
||||
|
||||
struct v2_array {
|
||||
struct v2 *points;
|
||||
u64 count;
|
||||
};
|
||||
|
||||
#define V3(x, y, z) ((struct v3) { (x), (y), (z) })
|
||||
struct v3 {
|
||||
f32 x, y, z;
|
||||
};
|
||||
|
||||
struct v3_array {
|
||||
struct v3 *points;
|
||||
u64 count;
|
||||
};
|
||||
|
||||
#define V4(x, y, z, w) ((struct v4) { (x), (y), (z), (w) })
|
||||
struct v4 {
|
||||
f32 x, y, z, w;
|
||||
};
|
||||
|
||||
struct v4_array {
|
||||
struct v4 *points;
|
||||
u64 count;
|
||||
};
|
||||
|
||||
struct mat3x3 {
|
||||
union {
|
||||
f32 e[3][3];
|
||||
@ -409,17 +424,27 @@ struct rect {
|
||||
f32 x, y, width, height;
|
||||
};
|
||||
|
||||
|
||||
/* Values expected to be normalized 0.0 -> 1.0 */
|
||||
#define CLIP_ALL ((struct clip_rect) { { 0.0f, 0.0f }, { 1.0f, 1.0f } })
|
||||
struct clip_rect {
|
||||
struct v2 p1, p2;
|
||||
};
|
||||
|
||||
#define QUAD_UNIT_SQUARE (struct quad) { V2(0, 0), V2(0, 1), V2(1, 1), V2(1, 0) }
|
||||
#define QUAD_UNIT_SQUARE_CENTERED (struct quad) { V2(-0.5f, -0.5f), V2(0.5f, -0.5f), V2(0.5f, 0.5f), V2(-0.5f, 0.5f) }
|
||||
|
||||
struct quad {
|
||||
struct v2 p1, p2, p3, p4;
|
||||
};
|
||||
|
||||
/* (T)ranslation, (R)otation, (S)cale */
|
||||
#define TRS(...) ((struct trs) { .t = V2(0,0), .s = V2(1, 1), .r = 0, __VA_ARGS__ })
|
||||
struct trs {
|
||||
struct v2 t;
|
||||
struct v2 s;
|
||||
f32 r;
|
||||
};
|
||||
|
||||
/* ========================== *
|
||||
* Common utilities
|
||||
* ========================== */
|
||||
@ -465,13 +490,13 @@ INLINE u64 cstr_len(char *cstr)
|
||||
/* Clang/GCC cleanup macros */
|
||||
#if COMPILER_CLANG || COMPILER_GCC
|
||||
# if !TRACY_NO_CALLSTACK
|
||||
# define __prof static const struct ___tracy_source_location_data CAT(__tracy_source_location,__LINE__) = { NULL, __func__, __FILE__, (uint32_t)__LINE__, 0 }; TracyCZoneCtx ctx = __attribute((cleanup(__prof_zone_cleanup_func))) ___tracy_emit_zone_begin_callstack( &CAT(__tracy_source_location,__LINE__), TRACY_CALLSTACK, true );
|
||||
# define __proscope(name) static const struct ___tracy_source_location_data CAT(__tracy_source_location,__LINE__) = { NULL, name, __FILE__, (uint32_t)__LINE__, 0 }; TracyCZoneCtx ctx = __attribute((cleanup(__prof_zone_cleanup_func))) ___tracy_emit_zone_begin_callstack( &CAT(__tracy_source_location,__LINE__), TRACY_CALLSTACK, true );
|
||||
# define __prof static const struct ___tracy_source_location_data CAT(__tracy_source_location,__LINE__) = { NULL, __func__, __FILE__, (uint32_t)__LINE__, 0 }; TracyCZoneCtx __tracy_ctx = __attribute((cleanup(__prof_zone_cleanup_func))) ___tracy_emit_zone_begin_callstack( &CAT(__tracy_source_location,__LINE__), TRACY_CALLSTACK, true );
|
||||
# define __proscope(name) static const struct ___tracy_source_location_data CAT(__tracy_source_location,__LINE__) = { NULL, name, __FILE__, (uint32_t)__LINE__, 0 }; TracyCZoneCtx __tracy_ctx = __attribute((cleanup(__prof_zone_cleanup_func))) ___tracy_emit_zone_begin_callstack( &CAT(__tracy_source_location,__LINE__), TRACY_CALLSTACK, true );
|
||||
# endif
|
||||
# define __prof static const struct ___tracy_source_location_data CAT(__tracy_source_location,__LINE__) = { NULL, __func__, __FILE__, (uint32_t)__LINE__, 0 }; __attribute((cleanup(__prof_zone_cleanup_func))) TracyCZoneCtx ctx = ___tracy_emit_zone_begin( &CAT(__tracy_source_location,__LINE__), true );
|
||||
# define __profscope(name) static const struct ___tracy_source_location_data CAT(__tracy_source_location,__LINE__) = { NULL, #name, __FILE__, (uint32_t)__LINE__, 0 }; __attribute((cleanup(__prof_zone_cleanup_func))) TracyCZoneCtx ctx = ___tracy_emit_zone_begin( &CAT(__tracy_source_location,__LINE__), true );
|
||||
# define __prof static const struct ___tracy_source_location_data CAT(__tracy_source_location,__LINE__) = { NULL, __func__, __FILE__, (uint32_t)__LINE__, 0 }; __attribute((cleanup(__prof_zone_cleanup_func))) TracyCZoneCtx __tracy_ctx = ___tracy_emit_zone_begin( &CAT(__tracy_source_location,__LINE__), true );
|
||||
# define __profscope(name) static const struct ___tracy_source_location_data CAT(__tracy_source_location,__LINE__) = { NULL, #name, __FILE__, (uint32_t)__LINE__, 0 }; __attribute((cleanup(__prof_zone_cleanup_func))) TracyCZoneCtx __tracy_ctx = ___tracy_emit_zone_begin( &CAT(__tracy_source_location,__LINE__), true );
|
||||
#endif
|
||||
INLINE void __prof_zone_cleanup_func(TracyCZoneCtx *ctx) { TracyCZoneEnd(*ctx); }
|
||||
INLINE void __prof_zone_cleanup_func(TracyCZoneCtx *__tracy_ctx) { TracyCZoneEnd(*__tracy_ctx); }
|
||||
|
||||
#define __profalloc(ptr, size) TracyCAlloc(ptr, size)
|
||||
#define __proffree(ptr) TracyCFree(ptr)
|
||||
|
||||
106
src/draw.c
106
src/draw.c
@ -90,9 +90,69 @@ void draw_texture_rect(struct renderer_canvas *canvas, struct draw_texture_param
|
||||
}
|
||||
|
||||
/* ========================== *
|
||||
* Shapes
|
||||
* Solid fill shapes
|
||||
* ========================== */
|
||||
|
||||
void draw_solid_poly(struct renderer_canvas *canvas, struct v2_array array, u32 color)
|
||||
{
|
||||
if (array.count < 3) {
|
||||
return;
|
||||
}
|
||||
|
||||
renderer_canvas_ensure_texture_cmd(canvas, (struct texture_shader_parameters) { .texture = L.solid_white });
|
||||
|
||||
u32 num_tris = array.count - 2;
|
||||
u32 num_indices = num_tris * 3;
|
||||
|
||||
struct texture_shader_vertex *vertices = NULL;
|
||||
vidx *indices = NULL;
|
||||
size_t idx_offset = renderer_canvas_push_vertices(canvas, (u8 **)&vertices, &indices, array.count, num_indices);
|
||||
|
||||
/* Fill vertices */
|
||||
for (u32 i = 0; i < array.count; ++i) {
|
||||
vertices[i] = (struct texture_shader_vertex) {
|
||||
.pos = array.points[i],
|
||||
.color = color
|
||||
};
|
||||
}
|
||||
|
||||
/* Fill indices */
|
||||
for (u32 i = 0; i < num_tris; ++i) {
|
||||
u32 tri_offset = i * 3;
|
||||
indices[tri_offset + 0] = idx_offset + 0;
|
||||
indices[tri_offset + 1] = idx_offset + (i + 1);
|
||||
indices[tri_offset + 2] = idx_offset + (i + 2);
|
||||
}
|
||||
}
|
||||
|
||||
void draw_solid_circle(struct renderer_canvas *canvas, struct v2 pos, f32 radius, u32 color, u32 detail)
|
||||
{
|
||||
struct temp_arena scratch = scratch_begin_no_conflict();
|
||||
|
||||
struct v2 *points = arena_push_array(scratch.arena, struct v2, detail);
|
||||
for(u32 i = 0; i < detail; ++i) {
|
||||
struct v2 p = V2(
|
||||
radius * math_cos(i * (PI * 2.f) / detail),
|
||||
radius * math_sin(i * (PI * 2.f) / detail)
|
||||
);
|
||||
points[i] = v2_add(pos, p);
|
||||
}
|
||||
|
||||
struct v2_array a = {
|
||||
.points = points,
|
||||
.count = detail
|
||||
};
|
||||
draw_solid_poly(canvas, a, color);
|
||||
|
||||
scratch_end(scratch);
|
||||
}
|
||||
|
||||
void draw_solid_quad(struct renderer_canvas *canvas, struct quad quad, u32 color)
|
||||
{
|
||||
renderer_canvas_ensure_texture_cmd(canvas, (struct texture_shader_parameters) { .texture = L.solid_white });
|
||||
draw_texture_quad_internal(canvas, CLIP_ALL, color, quad);
|
||||
}
|
||||
|
||||
void draw_solid_rect(struct renderer_canvas *canvas, struct rect rect, u32 color)
|
||||
{
|
||||
renderer_canvas_ensure_texture_cmd(canvas, (struct texture_shader_parameters) { .texture = L.solid_white });
|
||||
@ -100,6 +160,17 @@ void draw_solid_rect(struct renderer_canvas *canvas, struct rect rect, u32 color
|
||||
draw_texture_quad_internal(canvas, CLIP_ALL, color, quad);
|
||||
}
|
||||
|
||||
/* ========================== *
|
||||
* Solid line shapes
|
||||
* ========================== */
|
||||
|
||||
void draw_solid_ray(struct renderer_canvas *canvas, struct v2 pos, struct v2 rel, f32 thickness, u32 color)
|
||||
{
|
||||
renderer_canvas_ensure_texture_cmd(canvas, (struct texture_shader_parameters) { .texture = L.solid_white });
|
||||
struct quad quad = quad_from_ray(pos, rel, thickness);
|
||||
draw_texture_quad_internal(canvas, CLIP_ALL, color, quad);
|
||||
}
|
||||
|
||||
void draw_solid_line(struct renderer_canvas *canvas, struct v2 start, struct v2 end, f32 thickness, u32 color)
|
||||
{
|
||||
renderer_canvas_ensure_texture_cmd(canvas, (struct texture_shader_parameters) { .texture = L.solid_white });
|
||||
@ -107,11 +178,38 @@ void draw_solid_line(struct renderer_canvas *canvas, struct v2 start, struct v2
|
||||
draw_texture_quad_internal(canvas, CLIP_ALL, color, quad);
|
||||
}
|
||||
|
||||
void draw_solid_ray(struct renderer_canvas *canvas, struct v2 pos, struct v2 rel, f32 thickness, u32 color)
|
||||
void draw_solid_poly_line(struct renderer_canvas *canvas, struct v2_array array, b32 loop, f32 thickness, u32 color)
|
||||
{
|
||||
if (array.count < 2) {
|
||||
return;
|
||||
}
|
||||
|
||||
renderer_canvas_ensure_texture_cmd(canvas, (struct texture_shader_parameters) { .texture = L.solid_white });
|
||||
struct quad quad = quad_from_ray(pos, rel, thickness);
|
||||
draw_texture_quad_internal(canvas, CLIP_ALL, color, quad);
|
||||
for (u64 i = 1; i < array.count; ++i) {
|
||||
struct v2 p1 = array.points[i - 1];
|
||||
struct v2 p2 = array.points[i];
|
||||
struct quad q = quad_from_line(p1, p2, thickness);
|
||||
draw_texture_quad_internal(canvas, CLIP_ALL, color, q);
|
||||
}
|
||||
if (loop && array.count > 2) {
|
||||
struct v2 p1 = array.points[array.count - 1];
|
||||
struct v2 p2 = array.points[0];
|
||||
struct quad q = quad_from_line(p1, p2, thickness);
|
||||
draw_texture_quad_internal(canvas, CLIP_ALL, color, q);
|
||||
}
|
||||
}
|
||||
|
||||
void draw_solid_quad_line(struct renderer_canvas *canvas, struct quad quad, f32 thickness, u32 color)
|
||||
{
|
||||
struct v2 points[] = { quad.p1, quad.p2, quad.p3, quad.p4 };
|
||||
struct v2_array a = { .points = points, .count = ARRAY_COUNT(points) };
|
||||
draw_solid_poly_line(canvas, a, true, thickness, color);
|
||||
}
|
||||
|
||||
void draw_solid_rect_line(struct renderer_canvas *canvas, struct rect rect, f32 thickness, u32 color)
|
||||
{
|
||||
struct quad q = quad_from_rect(rect);
|
||||
draw_solid_quad_line(canvas, q, thickness, color);
|
||||
}
|
||||
|
||||
/* ========================== *
|
||||
|
||||
@ -20,9 +20,16 @@ void draw_startup(void);
|
||||
void draw_texture_quad(struct renderer_canvas *canvas, struct draw_texture_params params, struct quad quad);
|
||||
void draw_texture_rect(struct renderer_canvas *canvas, struct draw_texture_params params, struct rect rect);
|
||||
|
||||
void draw_solid_poly(struct renderer_canvas *canvas, struct v2_array array, u32 color);
|
||||
void draw_solid_circle(struct renderer_canvas *canvas, struct v2 pos, f32 radius, u32 color, u32 detail);
|
||||
void draw_solid_quad(struct renderer_canvas *canvas, struct quad quad, u32 color);
|
||||
void draw_solid_rect(struct renderer_canvas *canvas, struct rect rect, u32 color);
|
||||
void draw_solid_line(struct renderer_canvas *canvas, struct v2 start, struct v2 end, f32 thickness, u32 color);
|
||||
|
||||
void draw_solid_ray(struct renderer_canvas *canvas, struct v2 start, struct v2 ray, f32 thickness, u32 color);
|
||||
void draw_solid_line(struct renderer_canvas *canvas, struct v2 start, struct v2 end, f32 thickness, u32 color);
|
||||
void draw_solid_poly_line(struct renderer_canvas *canvas, struct v2_array array, b32 loop, f32 thickness, u32 color);
|
||||
void draw_solid_quad_line(struct renderer_canvas *canvas, struct quad quad, f32 thickness, u32 color);
|
||||
void draw_solid_rect_line(struct renderer_canvas *canvas, struct rect rect, f32 thickness, u32 color);
|
||||
|
||||
void draw_text(struct renderer_canvas *canvas, struct font *font, struct v2 pos, struct string str);
|
||||
void draw_text_ex(struct renderer_canvas *canvas, struct font *font, struct v2 pos, f32 scale, struct string str);
|
||||
|
||||
67
src/entity.h
67
src/entity.h
@ -8,14 +8,23 @@
|
||||
* Entity
|
||||
* ========================== */
|
||||
|
||||
struct entity_handle {
|
||||
u64 idx;
|
||||
u64 gen;
|
||||
};
|
||||
|
||||
enum entity_prop {
|
||||
ENTITY_PROP_NONE,
|
||||
|
||||
ENTITY_PROP_SPRITE_ANIMATED,
|
||||
ENTITY_PROP_PLAYER_CONTROLLED,
|
||||
ENTITY_PROP_CAMERA,
|
||||
|
||||
/* Test props */
|
||||
|
||||
ENTITY_PROP_TEST,
|
||||
ENTITY_PROP_TEST_FOLLOW_MOUSE,
|
||||
ENTITY_PROP_TEST_SOUND_EMITTER,
|
||||
ENTITY_PROP_TEXTURED,
|
||||
ENTITY_PROP_ANIMATED,
|
||||
ENTITY_PROP_PLAYER_CONTROLLED,
|
||||
|
||||
ENTITY_PROP_COUNT
|
||||
};
|
||||
@ -24,36 +33,52 @@ struct entity {
|
||||
b32 active;
|
||||
u64 gen;
|
||||
u64 continuity_gen;
|
||||
|
||||
u64 props[(ENTITY_PROP_COUNT + 63) / 64];
|
||||
struct entity *next_free;
|
||||
|
||||
struct v2 pos;
|
||||
/* TODO: Entity tree */
|
||||
|
||||
/* ENTITY_PROP_TEST */
|
||||
struct v2 start_pos;
|
||||
/* ====================================================================== */
|
||||
/* Translation, rotation, scale in relation to parent entity */
|
||||
|
||||
/* ENTITY_PROP_TEST_SOUND_EMITTER */
|
||||
struct string sound_name;
|
||||
struct mixer_desc sound_desc;
|
||||
struct mixer_track_handle sound_handle;
|
||||
struct trs rel_trs;
|
||||
|
||||
/* ENTITY_PROP_TEXTURED */
|
||||
struct string texture_name;
|
||||
struct v2 draw_size;
|
||||
/* ====================================================================== */
|
||||
/* Sprite */
|
||||
|
||||
/* ENTITY_PROP_ANIMATED */
|
||||
/* Use entity_start_animation */
|
||||
struct string sprite_name;
|
||||
struct trs sprite_trs;
|
||||
struct v2 sprite_pivot; /* Normalized. <0, 0> is center, <1, 1> is bottom right corner, etc. */
|
||||
|
||||
/* ====================================================================== */
|
||||
/* Animation */
|
||||
|
||||
/* ENTITY_PROP_SPRITE_ANIMATED */
|
||||
struct string animation_name;
|
||||
u64 animation_flags;
|
||||
f64 animation_time_in_frame;
|
||||
u64 animation_start_gen;
|
||||
u64 animation_gen;
|
||||
struct sheet_frame frame;
|
||||
};
|
||||
struct sheet_frame animation_frame;
|
||||
|
||||
/* ====================================================================== */
|
||||
/* ENTITY_PROP_TEST */
|
||||
|
||||
b32 test_initialized;
|
||||
struct trs test_trs;
|
||||
|
||||
/* ====================================================================== */
|
||||
/* ENTITY_PROP_TEST_SOUND_EMITTER */
|
||||
|
||||
struct string sound_name;
|
||||
struct mixer_desc sound_desc;
|
||||
struct mixer_track_handle sound_handle;
|
||||
|
||||
/* ====================================================================== */
|
||||
/* ENTITY_PROP_CAMERA */
|
||||
/* TODO */
|
||||
|
||||
struct entity_handle {
|
||||
u64 idx;
|
||||
u64 gen;
|
||||
};
|
||||
|
||||
/* ========================== *
|
||||
@ -91,7 +116,7 @@ INLINE b32 entity_has_prop(struct entity *entity, enum entity_prop prop)
|
||||
|
||||
INLINE void entity_start_animation(struct entity *entity, struct string animation_name, u64 flags)
|
||||
{
|
||||
entity_enable_prop(entity, ENTITY_PROP_ANIMATED);
|
||||
entity_enable_prop(entity, ENTITY_PROP_SPRITE_ANIMATED);
|
||||
entity->animation_name = animation_name;
|
||||
entity->animation_flags = flags;
|
||||
entity->animation_time_in_frame = 0;
|
||||
|
||||
85
src/game.c
85
src/game.c
@ -141,17 +141,27 @@ INTERNAL void game_update(void)
|
||||
|
||||
/* Player ent */
|
||||
{
|
||||
struct entity *e = entity_alloc();
|
||||
e->active = true;
|
||||
e->pos = V2(0, 0.25);
|
||||
entity_enable_prop(e, ENTITY_PROP_TEXTURED);
|
||||
struct string sprite_name = STR("res/graphics/timmy.ase");
|
||||
|
||||
e->texture_name = STR("res/graphics/timmy.ase");
|
||||
|
||||
struct sheet *sheet = sheet_load(e->texture_name);
|
||||
struct sheet *sheet = sheet_load(sprite_name);
|
||||
f32 meters_width = sheet->image_size.x / PIXELS_PER_UNIT;
|
||||
f32 meters_height = sheet->image_size.y / PIXELS_PER_UNIT;
|
||||
e->draw_size = V2(meters_width, meters_height);
|
||||
|
||||
struct v2 pos = V2(0, 0);
|
||||
//f32 rot = PI / 2;
|
||||
f32 rot = 0;
|
||||
struct v2 size = V2(meters_width, meters_height);
|
||||
|
||||
struct entity *e = entity_alloc();
|
||||
e->active = true;
|
||||
e->rel_trs = TRS(.t = pos, .r = rot, .s = V2(2, 2));
|
||||
|
||||
e->sprite_name = sprite_name;
|
||||
e->sprite_trs = TRS(.t = V2(1, 0), .r = 0, .s = size);
|
||||
e->sprite_pivot = V2(0, -0.5);
|
||||
|
||||
entity_enable_prop(e, ENTITY_PROP_TEST);
|
||||
entity_enable_prop(e, ENTITY_PROP_TEST_FOLLOW_MOUSE);
|
||||
}
|
||||
}
|
||||
|
||||
@ -172,31 +182,44 @@ INTERNAL void game_update(void)
|
||||
};
|
||||
}
|
||||
|
||||
/* ---------------------------------------------------------------------- */
|
||||
/* ---------------------------------------------------------------------- */
|
||||
|
||||
/* ========================== *
|
||||
* Update entities
|
||||
* ========================== */
|
||||
|
||||
for (u64 i = 0; i < ARRAY_COUNT(L.tick.entities); ++i) {
|
||||
struct entity *ent = &L.tick.entities[i];
|
||||
for (u64 entity_index = 0; entity_index < ARRAY_COUNT(L.tick.entities); ++entity_index) {
|
||||
struct entity *ent = &L.tick.entities[entity_index];
|
||||
if (!ent->active) continue;
|
||||
|
||||
/* ========================== *
|
||||
* Animation
|
||||
* Initialize
|
||||
* ========================== */
|
||||
|
||||
if (entity_has_prop(ent, ENTITY_PROP_ANIMATED)) {
|
||||
struct sheet *sheet = sheet_load(ent->texture_name);
|
||||
/* ENTITY_PROP_TEST */
|
||||
if (entity_has_prop(ent, ENTITY_PROP_TEST) && !ent->test_initialized) {
|
||||
ent->test_initialized = true;
|
||||
ent->test_trs = ent->rel_trs;
|
||||
}
|
||||
|
||||
/* ========================== *
|
||||
* Update animation
|
||||
* ========================== */
|
||||
|
||||
if (entity_has_prop(ent, ENTITY_PROP_SPRITE_ANIMATED)) {
|
||||
struct sheet *sheet = sheet_load(ent->sprite_name);
|
||||
struct sheet_tag tag = sheet_get_tag(sheet, ent->animation_name);
|
||||
|
||||
if (ent->animation_start_gen == ent->animation_gen) {
|
||||
ent->animation_time_in_frame += L.dt;
|
||||
} else {
|
||||
ent->frame = sheet_get_frame(sheet, tag.start);
|
||||
ent->animation_frame = sheet_get_frame(sheet, tag.start);
|
||||
ent->animation_start_gen = ent->animation_gen;
|
||||
}
|
||||
|
||||
while (ent->frame.duration != 0 && ent->animation_time_in_frame > ent->frame.duration) {
|
||||
u64 new_frame_index = ent->frame.index + 1;
|
||||
while (ent->animation_frame.duration != 0 && ent->animation_time_in_frame > ent->animation_frame.duration) {
|
||||
u64 new_frame_index = ent->animation_frame.index + 1;
|
||||
if (new_frame_index > tag.end) {
|
||||
if (ent->animation_flags & ANIMATION_FLAG_LOOPING) {
|
||||
/* Restart animation */
|
||||
@ -207,28 +230,33 @@ INTERNAL void game_update(void)
|
||||
goto break_animation;
|
||||
}
|
||||
}
|
||||
ent->frame = sheet_get_frame(sheet, new_frame_index);
|
||||
ent->animation_time_in_frame -= ent->frame.duration;
|
||||
ent->animation_frame = sheet_get_frame(sheet, new_frame_index);
|
||||
ent->animation_time_in_frame -= ent->animation_frame.duration;
|
||||
}
|
||||
}
|
||||
break_animation:
|
||||
|
||||
/* ========================== *
|
||||
* Update entity positions
|
||||
* Update position
|
||||
* ========================== */
|
||||
|
||||
/* ENTITY_PROP_TEST_FOLLOW_MOUSE */
|
||||
if (entity_has_prop(ent, ENTITY_PROP_TEST_FOLLOW_MOUSE)) {
|
||||
//ent->pos = v2_sub(L.tick.focus, v2_mul(ent->draw_size, 0.5f));
|
||||
ent->pos = L.tick.player_focus;
|
||||
ent->start_pos = ent->pos;
|
||||
ent->rel_trs.t = L.tick.player_focus;
|
||||
ent->test_trs.t = L.tick.player_focus;
|
||||
}
|
||||
|
||||
/* Update pos */
|
||||
/* ENTITY_PROP_TEST */
|
||||
if (entity_has_prop(ent, ENTITY_PROP_TEST)) {
|
||||
f32 t = ((f32)L.time);
|
||||
f32 x = (math_cos(t * 2.f) / 10.f);
|
||||
f32 y = (math_sin(t * 2.f) / 10.f);
|
||||
ent->pos = v2_add(ent->start_pos, V2(x, y));
|
||||
f32 r = t * 0.5f;
|
||||
|
||||
ent->sprite_trs.r = ent->test_trs.r + (r * 3.0f);
|
||||
|
||||
ent->rel_trs.r = ent->test_trs.r + (r * 0.25f);
|
||||
|
||||
//f32 s = 1 + (math_abs_f32(math_sin(t * 5)) * 0.5f);
|
||||
//ent->rel_trs.s = v2_mul(ent->test_trs.s, s);
|
||||
}
|
||||
|
||||
/* ========================== *
|
||||
@ -238,7 +266,7 @@ break_animation:
|
||||
if (entity_has_prop(ent, ENTITY_PROP_TEST_SOUND_EMITTER)) {
|
||||
struct mixer_desc desc = ent->sound_desc;
|
||||
desc.speed = L.timescale;
|
||||
desc.pos = ent->pos;
|
||||
desc.pos = ent->rel_trs.t;
|
||||
struct sound *sound = sound_load_async(ent->sound_name, 0);
|
||||
b32 played = ent->sound_handle.gen != 0;
|
||||
if (sound) {
|
||||
@ -251,6 +279,9 @@ break_animation:
|
||||
}
|
||||
}
|
||||
|
||||
/* ---------------------------------------------------------------------- */
|
||||
/* ---------------------------------------------------------------------- */
|
||||
|
||||
/* Publish tick */
|
||||
publish_game_tick();
|
||||
__profframe("Game");
|
||||
|
||||
154
src/math.h
154
src/math.h
@ -238,6 +238,11 @@ INLINE struct v2 v2_mul_v2(struct v2 a, struct v2 b)
|
||||
return V2(a.x * b.x, a.y * b.y);
|
||||
}
|
||||
|
||||
INLINE struct v2 v2_neg(struct v2 a)
|
||||
{
|
||||
return V2(-a.x, -a.y);
|
||||
}
|
||||
|
||||
INLINE struct v2 v2_add(struct v2 a, struct v2 b)
|
||||
{
|
||||
return V2(a.x + b.x, a.y + b.y);
|
||||
@ -306,6 +311,42 @@ INLINE struct v2 v2_lerp(struct v2 val0, struct v2 val1, f32 t)
|
||||
* Mat3x3
|
||||
* ========================== */
|
||||
|
||||
INLINE struct mat3x3 mat3x3_ident(void)
|
||||
{
|
||||
return (struct mat3x3) {
|
||||
.e = {
|
||||
{ 1, 0, 0 },
|
||||
{ 0, 1, 0 },
|
||||
{ 0, 0, 1 }
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
INLINE struct mat3x3 mat3x3_mul(struct mat3x3 a, struct mat3x3 b)
|
||||
{
|
||||
f32 a00 = a.e[0][0], a01 = a.e[0][1], a02 = a.e[0][2],
|
||||
a10 = a.e[1][0], a11 = a.e[1][1], a12 = a.e[1][2],
|
||||
a20 = a.e[2][0], a21 = a.e[2][1], a22 = a.e[2][2],
|
||||
b00 = b.e[0][0], b01 = b.e[0][1], b02 = b.e[0][2],
|
||||
b10 = b.e[1][0], b11 = b.e[1][1], b12 = b.e[1][2],
|
||||
b20 = b.e[2][0], b21 = b.e[2][1], b22 = b.e[2][2];
|
||||
|
||||
struct mat3x3 res;
|
||||
|
||||
res.e[0][0] = a00 * b00 + a10 * b01 + a20 * b02;
|
||||
res.e[0][1] = a01 * b00 + a11 * b01 + a21 * b02;
|
||||
res.e[0][2] = a02 * b00 + a12 * b01 + a22 * b02;
|
||||
res.e[1][0] = a00 * b10 + a10 * b11 + a20 * b12;
|
||||
res.e[1][1] = a01 * b10 + a11 * b11 + a21 * b12;
|
||||
res.e[1][2] = a02 * b10 + a12 * b11 + a22 * b12;
|
||||
res.e[2][0] = a00 * b20 + a10 * b21 + a20 * b22;
|
||||
res.e[2][1] = a01 * b20 + a11 * b21 + a21 * b22;
|
||||
res.e[2][2] = a02 * b20 + a12 * b21 + a22 * b22;
|
||||
|
||||
return res;
|
||||
|
||||
}
|
||||
|
||||
INLINE struct mat3x3 mat3x3_from_translate(struct v2 v)
|
||||
{
|
||||
return (struct mat3x3) {
|
||||
@ -347,14 +388,6 @@ INLINE struct mat3x3 mat3x3_rotate(struct mat3x3 m, f32 angle)
|
||||
return res;
|
||||
}
|
||||
|
||||
INLINE struct mat3x3 mat3x3_rotate_pivot(struct mat3x3 m, f32 angle, struct v2 pivot)
|
||||
{
|
||||
m = mat3x3_translate(m, V2(pivot.x, pivot.y)); /* Start pivot */
|
||||
m = mat3x3_rotate(m, angle);
|
||||
m = mat3x3_translate(m, V2(-pivot.x, -pivot.y)); /* End pivot */
|
||||
return m;
|
||||
}
|
||||
|
||||
INLINE struct mat3x3 mat3x3_scale(struct mat3x3 m, struct v3 v)
|
||||
{
|
||||
m.e[0][0] *= v.x;
|
||||
@ -369,46 +402,37 @@ INLINE struct mat3x3 mat3x3_scale(struct mat3x3 m, struct v3 v)
|
||||
return m;
|
||||
}
|
||||
|
||||
INLINE struct mat3x3 mat3x3_scale_pivot(struct mat3x3 m, struct v3 v, struct v2 pivot)
|
||||
INLINE struct mat3x3 mat3x3_from_trs(struct trs trs)
|
||||
{
|
||||
m = mat3x3_translate(m, V2(pivot.x, pivot.y)); /* Start pivot */
|
||||
m = mat3x3_scale(m, v);
|
||||
m = mat3x3_translate(m, V2(-pivot.x, -pivot.y)); /* End pivot */
|
||||
struct mat3x3 m = mat3x3_from_translate(trs.t);
|
||||
m = mat3x3_rotate(m, trs.r);
|
||||
m = mat3x3_scale(m, V3(trs.s.x, trs.s.y, 1));
|
||||
return m;
|
||||
}
|
||||
|
||||
INLINE struct mat3x3 mat3x3_from_trs(struct v2 pos, f32 rot, struct v2 scale)
|
||||
INLINE struct mat3x3 mat3x3_trs(struct mat3x3 m, struct trs trs)
|
||||
{
|
||||
struct mat3x3 m = mat3x3_from_translate(pos);
|
||||
m = mat3x3_rotate(m, rot);
|
||||
m = mat3x3_scale(m, V3(scale.x, scale.y, 1));
|
||||
m = mat3x3_translate(m, trs.t);
|
||||
m = mat3x3_rotate(m, trs.r);
|
||||
m = mat3x3_scale(m, V3(trs.s.x, trs.s.y, 1));
|
||||
return m;
|
||||
}
|
||||
|
||||
INLINE struct mat3x3 mat3x3_from_trs_pivot(struct v2 pos, f32 rot, struct v2 scale, struct v2 pivot)
|
||||
INLINE struct mat3x3 mat3x3_trs_pivot_r(struct mat3x3 m, struct trs trs, struct v2 pivot)
|
||||
{
|
||||
struct mat3x3 m = mat3x3_from_translate(pos);
|
||||
m = mat3x3_translate(m, V2(pivot.x, pivot.y)); /* Start pivot */
|
||||
m = mat3x3_rotate(m, rot);
|
||||
m = mat3x3_scale(m, V3(scale.x, scale.y, 1));
|
||||
m = mat3x3_translate(m, V2(-pivot.x, -pivot.y)); /* End pivot */
|
||||
m = mat3x3_translate(m, trs.t);
|
||||
m = mat3x3_rotate(m, trs.r);
|
||||
m = mat3x3_translate(m, v2_neg(pivot));
|
||||
m = mat3x3_scale(m, V3(trs.s.x, trs.s.y, 1));
|
||||
return m;
|
||||
}
|
||||
|
||||
INLINE struct mat3x3 mat3x3_trs(struct mat3x3 m, struct v2 pos, f32 rot, struct v2 scale)
|
||||
INLINE struct mat3x3 mat3x3_trs_pivot_rs(struct mat3x3 m, struct trs trs, struct v2 pivot)
|
||||
{
|
||||
m = mat3x3_translate(m, pos);
|
||||
m = mat3x3_rotate(m, rot);
|
||||
m = mat3x3_scale(m, V3(scale.x, scale.y, 1));
|
||||
return m;
|
||||
}
|
||||
|
||||
INLINE struct mat3x3 mat3x3_trs_pivot(struct mat3x3 m, struct v2 pos, f32 rot, struct v2 scale , struct v2 pivot)
|
||||
{
|
||||
m = mat3x3_translate(m, V2(pos.x + pivot.x, pos.y + pivot.y)); /* Start pivot */
|
||||
m = mat3x3_rotate(m, rot);
|
||||
m = mat3x3_scale(m, V3(scale.x, scale.y, 1));
|
||||
m = mat3x3_translate(m, V2(-pivot.x, -pivot.y)); /* End pivot */
|
||||
m = mat3x3_translate(m, trs.t);
|
||||
m = mat3x3_rotate(m, trs.r);
|
||||
m = mat3x3_scale(m, V3(trs.s.x, trs.s.y, 1));
|
||||
m = mat3x3_translate(m, v2_neg(pivot));
|
||||
return m;
|
||||
}
|
||||
|
||||
@ -421,6 +445,15 @@ INLINE struct v3 mat3x3_mul_v3(struct mat3x3 m, struct v3 v)
|
||||
return res;
|
||||
}
|
||||
|
||||
/* Equivalent to multiplying by V3(v.x, v.y, 1.0) */
|
||||
INLINE struct v2 mat3x3_mul_v2(struct mat3x3 m, struct v2 v)
|
||||
{
|
||||
struct v2 res;
|
||||
res.x = m.e[0][0] * v.x + m.e[1][0] * v.y + m.e[2][0];
|
||||
res.y = m.e[0][1] * v.x + m.e[1][1] * v.y + m.e[2][1];
|
||||
return res;
|
||||
}
|
||||
|
||||
INLINE struct mat3x3 mat3x3_inverse(struct mat3x3 m)
|
||||
{
|
||||
f32 a = m.e[0][0], b = m.e[0][1], c = m.e[0][2],
|
||||
@ -444,26 +477,31 @@ INLINE struct mat3x3 mat3x3_inverse(struct mat3x3 m)
|
||||
return res;
|
||||
}
|
||||
|
||||
INLINE struct v2 mat3x3_right(struct mat3x3 m)
|
||||
INLINE struct v2 mat3x3_get_right(struct mat3x3 m)
|
||||
{
|
||||
return V2(m.e[0][0], m.e[0][1]);
|
||||
}
|
||||
|
||||
INLINE struct v2 mat3x3_left(struct mat3x3 m)
|
||||
INLINE struct v2 mat3x3_get_left(struct mat3x3 m)
|
||||
{
|
||||
return V2(-m.e[0][0], -m.e[0][1]);
|
||||
}
|
||||
|
||||
INLINE struct v2 mat3x3_up(struct mat3x3 m)
|
||||
INLINE struct v2 mat3x3_get_up(struct mat3x3 m)
|
||||
{
|
||||
return V2(-m.e[1][0], -m.e[1][1]);
|
||||
}
|
||||
|
||||
INLINE struct v2 mat3x3_down(struct mat3x3 m)
|
||||
INLINE struct v2 mat3x3_get_down(struct mat3x3 m)
|
||||
{
|
||||
return V2(m.e[1][0], m.e[1][1]);
|
||||
}
|
||||
|
||||
INLINE struct v2 mat3x3_get_pos(struct mat3x3 m)
|
||||
{
|
||||
return V2(m.e[2][0], m.e[2][1]);
|
||||
}
|
||||
|
||||
/* ========================== *
|
||||
* Mat4x4
|
||||
* ========================== */
|
||||
@ -522,6 +560,19 @@ INLINE struct mat4x4 mat4x4_mul(struct mat4x4 m1, struct mat4x4 m2)
|
||||
return res;
|
||||
}
|
||||
|
||||
/* ========================== *
|
||||
* Trs
|
||||
* ========================== */
|
||||
|
||||
INLINE struct trs trs_lerp(struct trs a, struct trs b, f32 t)
|
||||
{
|
||||
struct trs res;
|
||||
res.t = v2_lerp(a.t, b.t, t);
|
||||
res.r = math_lerp_f32(a.r, b.r, t);
|
||||
res.s = v2_lerp(a.s, b.s, t);
|
||||
return res;
|
||||
}
|
||||
|
||||
/* ========================== *
|
||||
* Quad
|
||||
* ========================== */
|
||||
@ -555,10 +606,33 @@ INLINE struct quad quad_from_line(struct v2 start, struct v2 end, f32 thickness)
|
||||
};
|
||||
}
|
||||
|
||||
INLINE struct quad quad_from_ray(struct v2 pos, struct v2 rel, f32 thickness)
|
||||
INLINE struct quad quad_from_ray(struct v2 pos, struct v2 rel, f32 thickness)
|
||||
{
|
||||
struct v2 end = v2_add(pos, rel);
|
||||
return quad_from_line(pos, end, thickness);
|
||||
}
|
||||
|
||||
INLINE struct quad quad_scale(struct quad q, f32 s)
|
||||
{
|
||||
q.p1 = v2_mul(q.p1, s);
|
||||
q.p2 = v2_mul(q.p2, s);
|
||||
q.p3 = v2_mul(q.p3, s);
|
||||
q.p4 = v2_mul(q.p4, s);
|
||||
return q;
|
||||
}
|
||||
|
||||
INLINE struct quad quad_mul_mat3x3(struct quad quad, struct mat3x3 m)
|
||||
{
|
||||
struct v3 p1_v3 = mat3x3_mul_v3(m, V3(quad.p1.x, quad.p1.y, 1));
|
||||
struct v3 p2_v3 = mat3x3_mul_v3(m, V3(quad.p2.x, quad.p2.y, 1));
|
||||
struct v3 p3_v3 = mat3x3_mul_v3(m, V3(quad.p3.x, quad.p3.y, 1));
|
||||
struct v3 p4_v3 = mat3x3_mul_v3(m, V3(quad.p4.x, quad.p4.y, 1));
|
||||
return (struct quad) {
|
||||
V2(p1_v3.x, p1_v3.y),
|
||||
V2(p2_v3.x, p2_v3.y),
|
||||
V2(p3_v3.x, p3_v3.y),
|
||||
V2(p4_v3.x, p4_v3.y)
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@ -632,7 +632,7 @@ struct renderer_canvas *renderer_canvas_alloc(void)
|
||||
MEMZERO_STRUCT(canvas);
|
||||
canvas->cpu_cmd_store.arena = arena_alloc(GIGABYTE(8));
|
||||
canvas->gpu_cmd_store.arena = arena_alloc(GIGABYTE(8));
|
||||
canvas->view = mat3x3_from_trs(V2(0, 0), 0, V2(1, 1));
|
||||
canvas->view = mat3x3_from_trs(TRS());
|
||||
canvas->valid = true;
|
||||
|
||||
/* Initialize buffers, skipping index 0 (SHADER_NONE) */
|
||||
|
||||
@ -35,6 +35,7 @@ void resource_startup(void)
|
||||
|
||||
b32 resource_exists(struct string path)
|
||||
{
|
||||
__prof;
|
||||
#if RESOURCES_EMBEDDED
|
||||
struct tar_entry *entry = tar_get(&L.archive, path);
|
||||
return entry && !entry->is_dir;
|
||||
@ -45,6 +46,7 @@ b32 resource_exists(struct string path)
|
||||
|
||||
struct resource resource_open(struct string path)
|
||||
{
|
||||
__prof;
|
||||
#if RESOURCES_EMBEDDED
|
||||
struct tar_entry *entry = tar_get(&L.archive, path);
|
||||
return (struct resource) {
|
||||
|
||||
@ -439,6 +439,8 @@ wchar_t *string_to_wstr(struct arena *arena, struct string str)
|
||||
*/
|
||||
struct string string_formatv(struct arena *arena, struct string fmt, va_list args)
|
||||
{
|
||||
__prof;
|
||||
|
||||
u64 final_len = 0;
|
||||
u8 *final_text = arena_dry_push(arena, u8);
|
||||
|
||||
|
||||
@ -216,6 +216,7 @@ struct string sys_get_write_path(struct arena *arena)
|
||||
|
||||
b32 sys_is_file(struct string path)
|
||||
{
|
||||
__prof;
|
||||
struct temp_arena scratch = scratch_begin_no_conflict();
|
||||
const char *path_cstr = string_to_cstr(scratch.arena, path);
|
||||
DWORD attributes = GetFileAttributes(path_cstr);
|
||||
|
||||
174
src/user.c
174
src/user.c
@ -182,7 +182,16 @@ INTERNAL void push_game_cmds(struct game_cmd_list *list)
|
||||
INTERNAL struct mat3x3 view_get_xform(struct view view)
|
||||
{
|
||||
f32 scale = view.zoom * view.px_per_unit;
|
||||
struct mat3x3 res = mat3x3_from_trs_pivot(v2_sub(L.screen_center, view.center), view.rot, V2(scale, scale), view.center);
|
||||
struct trs trs = TRS(
|
||||
.t = v2_sub(L.screen_center, view.center),
|
||||
.r = view.rot,
|
||||
.s = V2(scale, scale)
|
||||
);
|
||||
|
||||
struct v2 pivot = view.center;
|
||||
struct mat3x3 res = mat3x3_from_translate(pivot);
|
||||
res = mat3x3_trs_pivot_rs(res, trs, pivot);
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
@ -198,6 +207,24 @@ INTERNAL struct v2 view_mouse_pos(struct view view)
|
||||
return view_inverse_point(view, L.screen_mouse);
|
||||
}
|
||||
|
||||
/* TODO: remove this (testing) */
|
||||
INTERNAL void debug_draw_xform(struct mat3x3 mtx)
|
||||
{
|
||||
f32 thickness = 2.f / PIXELS_PER_UNIT / L.world_view.zoom;
|
||||
u32 color = RGBA_F(0, 1, 1, 0.3);
|
||||
u32 color_x = RGBA_F(1, 0, 0, 0.3);
|
||||
u32 color_y = RGBA_F(0, 1, 0, 0.3);
|
||||
|
||||
struct v2 pos = mat3x3_get_pos(mtx);
|
||||
struct v2 x_ray = mat3x3_get_right(mtx);
|
||||
struct v2 y_ray = mat3x3_get_down(mtx);
|
||||
struct quad quad = quad_mul_mat3x3(quad_scale(QUAD_UNIT_SQUARE, 0.075), mtx);
|
||||
|
||||
draw_solid_ray(L.world_canvas, pos, x_ray, thickness, color_x);
|
||||
draw_solid_ray(L.world_canvas, pos, y_ray, thickness, color_y);
|
||||
draw_solid_quad(L.world_canvas, quad, color);
|
||||
}
|
||||
|
||||
/* ========================== *
|
||||
* Update
|
||||
* ========================== */
|
||||
@ -228,9 +255,13 @@ INTERNAL void user_update(void)
|
||||
L.screen_mouse = sys_window_get_mouse_pos(L.window);
|
||||
struct sys_event_array events = pull_sys_events(scratch.arena);
|
||||
|
||||
/* ========================== *
|
||||
* Read sys events
|
||||
* ========================== */
|
||||
|
||||
i32 zooms_to_apply = 0;
|
||||
for (u64 i = 0; i < events.count; ++i) {
|
||||
struct sys_event *event = &events.events[i];
|
||||
for (u64 entity_index = 0; entity_index < events.count; ++entity_index) {
|
||||
struct sys_event *event = &events.events[entity_index];
|
||||
|
||||
/* Send event to console. Skip if consumed. */
|
||||
if (console_process_event(*event)) {
|
||||
@ -337,7 +368,9 @@ INTERNAL void user_update(void)
|
||||
struct entity *e0 = &t0->entities[i];
|
||||
struct entity *e1 = &t1->entities[i];
|
||||
if (e0->gen == e1->gen && e0->continuity_gen == e1->continuity_gen) {
|
||||
e->pos = v2_lerp(e0->pos, e1->pos, blend);
|
||||
e->rel_trs = trs_lerp(e0->rel_trs, e1->rel_trs, blend);
|
||||
e->sprite_trs = trs_lerp(e0->sprite_trs, e1->sprite_trs, blend);
|
||||
e->sprite_pivot = v2_lerp(e0->sprite_pivot, e1->sprite_pivot, blend);
|
||||
}
|
||||
}
|
||||
#else
|
||||
@ -384,55 +417,118 @@ INTERNAL void user_update(void)
|
||||
}
|
||||
}
|
||||
|
||||
/* ---------------------------------------------------------------------- */
|
||||
/* ---------------------------------------------------------------------- */
|
||||
|
||||
/* ========================== *
|
||||
* Iterate entities
|
||||
* ========================== */
|
||||
|
||||
{
|
||||
__profscope(iterate_ents);
|
||||
/* Iterate entities */
|
||||
for (u64 i = 0; i < tick->entities_count; ++i) {
|
||||
struct entity *ent = &tick->entities[i];
|
||||
if (!ent->active) continue;
|
||||
/* Iterate entities */
|
||||
for (u64 entity_index = 0; entity_index < tick->entities_count; ++entity_index) {
|
||||
struct entity *ent = &tick->entities[entity_index];
|
||||
if (!ent->active) continue;
|
||||
|
||||
/* Debug draw transform */
|
||||
{
|
||||
struct mat3x3 mtx = mat3x3_from_trs(ent->rel_trs);
|
||||
debug_draw_xform(mtx);
|
||||
}
|
||||
|
||||
/* Draw sprite */
|
||||
if (ent->sprite_name.len > 0) {
|
||||
struct string tex_name = ent->sprite_name;
|
||||
|
||||
/* Draw texture */
|
||||
if (entity_has_prop(ent, ENTITY_PROP_TEXTURED)) {
|
||||
if (ent->texture_name.len > 0) {
|
||||
struct string tex_name = ent->texture_name;
|
||||
struct v2 pos = ent->pos;
|
||||
struct v2 size = ent->draw_size;
|
||||
struct quad quad = QUAD_UNIT_SQUARE_CENTERED;
|
||||
|
||||
/* Draw texture */
|
||||
struct texture *texture = texture_load_async(tex_name);
|
||||
if (texture) {
|
||||
struct rect rect = { pos.x, pos.y, size.x, size.y };
|
||||
struct draw_texture_params params;
|
||||
if (entity_has_prop(ent, ENTITY_PROP_ANIMATED)) {
|
||||
struct sheet_frame frame = ent->frame;
|
||||
params = DRAW_TEXTURE_PARAMS(.texture = texture, .clip = frame.clip);
|
||||
} else {
|
||||
params = DRAW_TEXTURE_PARAMS(.texture = texture);
|
||||
}
|
||||
draw_texture_rect(L.world_canvas, params, rect);
|
||||
}
|
||||
/* TODO: Do this calculation in game loop */
|
||||
struct mat3x3 mtx;
|
||||
{
|
||||
/* Entity trs */
|
||||
mtx = mat3x3_from_trs(ent->rel_trs);
|
||||
|
||||
/* Draw name */
|
||||
if (entity_has_prop(ent, ENTITY_PROP_TEST)) {
|
||||
struct font *disp_font = font_load_async(STR("res/fonts/fixedsys.ttf"), 12.0f);
|
||||
if (disp_font) {
|
||||
struct string disp_name = {
|
||||
.len = tex_name.len - 13,
|
||||
.text = tex_name.text + 13
|
||||
};
|
||||
draw_text_ex(L.world_canvas, disp_font, V2(pos.x, pos.y - (disp_font->point_size / PIXELS_PER_UNIT) * 2), 1.0f / PIXELS_PER_UNIT, disp_name);
|
||||
}
|
||||
}
|
||||
/* Sprite trs & pivot */
|
||||
struct v2 pivot = v2_mul_v2(ent->sprite_pivot, v2_mul(ent->sprite_trs.s, 0.5f));
|
||||
mtx = mat3x3_trs_pivot_r(mtx, ent->sprite_trs, pivot);
|
||||
|
||||
quad = quad_mul_mat3x3(quad, mtx);
|
||||
}
|
||||
|
||||
struct texture *texture = texture_load_async(tex_name);
|
||||
if (texture) {
|
||||
|
||||
struct draw_texture_params params;
|
||||
if (entity_has_prop(ent, ENTITY_PROP_SPRITE_ANIMATED)) {
|
||||
struct sheet_frame frame = ent->animation_frame;
|
||||
params = DRAW_TEXTURE_PARAMS(.texture = texture, .clip = frame.clip);
|
||||
} else {
|
||||
params = DRAW_TEXTURE_PARAMS(.texture = texture);
|
||||
}
|
||||
draw_texture_quad(L.world_canvas, params, quad);
|
||||
}
|
||||
|
||||
/* Debug draw sprite quad */
|
||||
{
|
||||
f32 thickness = 2.f;
|
||||
u32 color = RGBA_F(1, 1, 0, 0.25);
|
||||
draw_solid_quad_line(L.world_canvas, quad, (thickness / PIXELS_PER_UNIT / L.world_view.zoom), color);
|
||||
}
|
||||
|
||||
/* Debug draw sprite transform */
|
||||
{
|
||||
debug_draw_xform(mtx);
|
||||
}
|
||||
|
||||
/* Debug draw sprite pivot */
|
||||
{
|
||||
u32 color = RGBA_F(1, 0, 0, 1);
|
||||
|
||||
struct mat3x3 mtx_pre_pivot = mat3x3_from_trs(ent->rel_trs);
|
||||
mtx_pre_pivot = mat3x3_trs(mtx_pre_pivot, ent->sprite_trs);
|
||||
|
||||
struct v2 p = mat3x3_get_pos(mtx_pre_pivot);
|
||||
draw_solid_circle(L.world_canvas, p, 0.05, color, 20);
|
||||
|
||||
draw_solid_circle(L.world_canvas, mat3x3_get_pos(mtx_pre_pivot), 0.05, color, 20);
|
||||
}
|
||||
|
||||
/* Debug draw sprite name */
|
||||
if (entity_has_prop(ent, ENTITY_PROP_TEST)) {
|
||||
struct font *disp_font = font_load_async(STR("res/fonts/fixedsys.ttf"), 12.0f);
|
||||
|
||||
f32 offset = 0.3;
|
||||
|
||||
struct v2 dir = v2_mul(mat3x3_get_up(mtx), 0.5f);
|
||||
dir = v2_add(dir, v2_mul(v2_norm(dir), offset));
|
||||
|
||||
struct v2 pos = v2_add(mat3x3_get_pos(mtx), dir);
|
||||
|
||||
|
||||
if (disp_font) {
|
||||
struct string disp_name = { .len = tex_name.len - 13, .text = tex_name.text + 13 };
|
||||
|
||||
struct string fmt = STR(
|
||||
"sprite name: %F,\n"
|
||||
"rel rot: %F,\n"
|
||||
"sprite rot: %F\n"
|
||||
);
|
||||
struct string text = string_format(scratch.arena, fmt,
|
||||
FMT_STR(disp_name),
|
||||
FMT_FLOAT((f64)ent->rel_trs.r),
|
||||
FMT_FLOAT((f64)ent->sprite_trs.r)
|
||||
);
|
||||
|
||||
|
||||
draw_text_ex(L.world_canvas, disp_font, pos, 1.0f / PIXELS_PER_UNIT, text);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* ---------------------------------------------------------------------- */
|
||||
/* ---------------------------------------------------------------------- */
|
||||
|
||||
/* Update listener using world view */
|
||||
mixer_set_listener(L.world_view.center, V2(-math_sin(L.world_view.rot), -math_cos(L.world_view.rot)));
|
||||
|
||||
|
||||
Loading…
Reference in New Issue
Block a user