diff --git a/src/ase.c b/src/ase.c index d37fb08c..ca7eab56 100644 --- a/src/ase.c +++ b/src/ase.c @@ -954,8 +954,8 @@ struct ase_decode_sheet_result ase_decode_sheet(struct arena *arena, struct buff slice->start = start; slice->x1 = x; slice->y1 = y; - slice->x2 = max_u32((x + width) - 1, 0); - slice->y2 = max_u32((y + height) - 1, 0); + slice->x2 = x + width; + slice->y2 = y + height; } ++num_slice_keys; diff --git a/src/game.c b/src/game.c index 9e378a4d..e9cbde77 100644 --- a/src/game.c +++ b/src/game.c @@ -175,7 +175,6 @@ INTERNAL void game_update(void) e->sprite = sprite_tag_from_path(STR("res/graphics/tim.ase")); e->sprite_span_name = STR("idle.unarmed"); //e->sprite_span_name = STR("idle.two_handed"); - e->sprite_quad_xform = XFORM_TRS(.s = size); entity_enable_prop(e, ENTITY_PROP_PLAYER_CONTROLLED); e->player_max_speed = 4.f; @@ -187,7 +186,6 @@ INTERNAL void game_update(void) player_ent = e; //entity_enable_prop(e, ENTITY_PROP_TEST); - //entity_enable_prop(e, ENTITY_PROP_TEST_FOLLOW_MOUSE); } /* Camera ent */ @@ -300,6 +298,18 @@ INTERNAL void game_update(void) ent->animation_frame = span_frame_offset; } + /* ========================== * + * Calculate sprite xform + * ========================== */ + + if (!sprite_tag_is_nil(ent->sprite)) { + struct sprite_sheet *sheet = sprite_sheet_from_tag_await(sprite_frame_scope, ent->sprite); + struct v2 sprite_size = v2_div(sheet->frame_size, (f32)PIXELS_PER_UNIT); + struct sprite_sheet_slice slice = sprite_sheet_get_slice(sheet, STR("pivot"), ent->animation_frame); + struct v2 pivot_pos = v2_mul_v2(slice.center_norm, sprite_size); + ent->sprite_quad_xform = xform_with_scale(XFORM_POS(v2_neg(pivot_pos)), sprite_size); + } + /* ========================== * * Test * ========================== */ @@ -324,29 +334,12 @@ INTERNAL void game_update(void) ent->rel_xform = xform_with_scale(ent->rel_xform, s); } - /* ========================== * - * Calculate sprite xform - * ========================== */ - - if (ent->sprite.hash != 0) { - struct sprite_sheet *sheet = sprite_sheet_from_tag_await(sprite_frame_scope, ent->sprite); - struct v2 sprite_size = v2_div(sheet->frame_size, (f32)PIXELS_PER_UNIT); - - struct sprite_sheet_slice slice = sprite_sheet_get_slice(sheet, STR("pivot"), ent->animation_frame); - struct v2 pivot_pos = v2_mul_v2(slice.center_norm, sprite_size); - - /* Apply Pivot */ - struct xform sprite_xf = XFORM_POS(v2_neg(pivot_pos)); - sprite_xf = xform_scale(sprite_xf, sprite_size); - - ent->sprite_quad_xform = sprite_xf; - } - /* ========================== * * Calculate player aim angle * ========================== */ if (entity_has_prop(ent, ENTITY_PROP_PLAYER_CONTROLLED)) { +#if 1 /* Update focus */ ent->focus = G.world.player_aim; @@ -355,6 +348,16 @@ INTERNAL void game_update(void) struct v2 look_pos = v2_add(ent_pos, ent->focus); f32 r = v2_angle_to_point(ent_pos, look_pos) + PI / 2; ent->rel_xform = xform_with_rotation(ent->rel_xform, r); +#else + /* Update focus */ + ent->focus = G.world.player_aim; + + /* Update view angle */ + struct v2 ent_pos = ent->rel_xform.og; + struct v2 look_pos = v2_add(ent_pos, ent->focus); + f32 r = v2_angle_to_point(ent_pos, look_pos) + PI / 2; + ent->rel_xform = xform_with_rotation(ent->rel_xform, r); +#endif } } diff --git a/src/sprite.c b/src/sprite.c index f8814193..5713e944 100644 --- a/src/sprite.c +++ b/src/sprite.c @@ -650,7 +650,7 @@ INTERNAL void cache_node_load_sheet(struct cache_node *n, struct sprite_tag tag) logf_info("Loading sprite sheet \"%F\"", FMT_STR(path)); sys_timestamp_t start_ts = sys_timestamp(); - ASSERT(string_ends_with(path, STR(".ase"))); + //ASSERT(string_ends_with(path, STR(".ase"))); ASSERT(n->kind == CACHE_NODE_KIND_SHEET); n->arena = arena_alloc(SHEET_ARENA_RESERVE); @@ -671,7 +671,7 @@ INTERNAL void cache_node_load_sheet(struct cache_node *n, struct sprite_tag tag) n->sheet->loaded = true; n->sheet->valid = true; } else { - logf_error("Sprite \"%F\" not found", path); + logf_error("Sprite \"%F\" not found", FMT_STR(path)); } } #if RESOURCE_RELOADING @@ -899,7 +899,6 @@ INTERNAL void *data_from_tag_internal(struct sprite_scope *scope, struct sprite_ sys_mutex_unlock(&lock); } - } } diff --git a/src/user.c b/src/user.c index 7a52f721..02fa3a87 100644 --- a/src/user.c +++ b/src/user.c @@ -457,6 +457,7 @@ INTERNAL void user_update(void) e->sprite_quad_xform = xform_lerp(e0->sprite_quad_xform, e1->sprite_quad_xform, tick_blend); e->animation_time_in_frame = math_lerp64(e0->animation_time_in_frame, e1->animation_time_in_frame, (f64)tick_blend); + e->animation_frame = (u32)math_round_to_int(math_lerp(e0->animation_frame, e1->animation_frame, tick_blend)); e->camera_quad_xform = xform_lerp(e0->camera_quad_xform, e1->camera_quad_xform, tick_blend); e->camera_rel_xform_target = xform_lerp(e0->camera_rel_xform_target, e1->camera_rel_xform_target, tick_blend); @@ -765,29 +766,10 @@ INTERNAL void user_update(void) struct sprite_texture *texture = sprite_texture_from_tag_async(sprite_frame_scope, sprite); (UNUSED)texture; + /* TODO: Fade in placeholder if texture isn't loaded */ if (sheet->loaded) { - struct sprite_sheet_frame frame; - { - struct sprite_sheet_span span = sprite_sheet_get_span(sheet, ent->sprite_span_name); - u32 frame_index = span.start + ent->animation_frame; - frame = sprite_sheet_get_frame(sheet, frame_index); - if (entity_has_prop(ent, ENTITY_PROP_ANIMATING)) { - f64 time_in_frame = ent->animation_time_in_frame; - while (time_in_frame > frame.duration) { - time_in_frame -= frame.duration; - ++frame_index; - if (frame_index > span.end) { - /* Loop animation */ - frame_index = span.start; - } - frame = sprite_sheet_get_frame(sheet, frame_index); - } - } - } - + struct sprite_sheet_frame frame = sprite_sheet_get_frame(sheet, ent->animation_frame); struct quad quad = quad_mul_xform(QUAD_UNIT_SQUARE_CENTERED, xform_mul(ent->world_xform, ent->sprite_quad_xform)); - - /* TODO: Fade in placeholder if texture isn't loaded */ struct draw_sprite_params params = DRAW_SPRITE_PARAMS(.sprite = sprite, .tint = ent->sprite_tint, .clip = frame.clip); draw_sprite_quad(G.world_canvas, params, quad); } @@ -840,9 +822,8 @@ INTERNAL void user_update(void) debug_draw_xform(ent->world_xform); } -#if 0 /* Draw slices */ - { + if (!sprite_tag_is_nil(ent->sprite)) { struct sprite_tag sprite = ent->sprite; struct sprite_sheet *sheet = sprite_sheet_from_tag_async(sprite_frame_scope, sprite); @@ -850,12 +831,14 @@ INTERNAL void user_update(void) struct sprite_sheet_slice_group *group = &sheet->slice_groups[i]; for (u32 j = 0; j < group->per_frame_count; ++j) { - group->frame_slices[(j * group->per_frame_count) + k]; + struct sprite_sheet_slice slice = group->frame_slices[(ent->animation_frame * group->per_frame_count) + j]; + struct quad quad = quad_from_rect(slice.rect_norm); + quad = quad_mul_xform(quad, xform_mul(ent->world_xform, ent->sprite_quad_xform)); + draw_solid_quad_line(G.viewport_canvas, quad_mul_xform(quad, G.world_view), 3, COLOR_RED); } } - } -#endif + /* Draw hierarchy */ struct entity *parent = entity_from_handle(&G.world.entity_store, ent->parent); if (parent->valid) {