fp: Add mob spawner and profiling metrics
This commit is contained in:
parent
f431be1b29
commit
38410073cf
2
External/tely
vendored
2
External/tely
vendored
@ -1 +1 @@
|
|||||||
Subproject commit 2e846b010ab9c32e3792375aa5db23796201b3ee
|
Subproject commit 5a56d52e71c4b66a9c6fa795a5a851f0dd4206cb
|
204
feely_pona.cpp
204
feely_pona.cpp
@ -478,8 +478,8 @@ void TELY_DLL_Init(void *user_data)
|
|||||||
|
|
||||||
// NOTE: Hero
|
// NOTE: Hero
|
||||||
{
|
{
|
||||||
FP_GameEntity *entity = FP_Game_MakeEntityPointerF(game, "Hero");
|
FP_GameEntity *entity = FP_Game_MakeEntityPointerF(game, "Terry");
|
||||||
entity->local_pos = Dqn_V2_InitNx2(100.f, 100.f);
|
entity->local_pos = Dqn_V2_InitNx2(1334, 396);
|
||||||
entity->size_scale = Dqn_V2_InitNx1(4);
|
entity->size_scale = Dqn_V2_InitNx1(4);
|
||||||
entity->sprite_sheet = &game->hero_sprite_sheet;
|
entity->sprite_sheet = &game->hero_sprite_sheet;
|
||||||
entity->sprite_anims = game->hero_sprite_anims;
|
entity->sprite_anims = game->hero_sprite_anims;
|
||||||
@ -488,27 +488,15 @@ void TELY_DLL_Init(void *user_data)
|
|||||||
entity->flags |= FP_GameEntityFlag_MoveByKeyboard;
|
entity->flags |= FP_GameEntityFlag_MoveByKeyboard;
|
||||||
entity->flags |= FP_GameEntityFlag_MoveByMouse;
|
entity->flags |= FP_GameEntityFlag_MoveByMouse;
|
||||||
entity->flags |= FP_GameEntityFlag_NonTraversable;
|
entity->flags |= FP_GameEntityFlag_NonTraversable;
|
||||||
|
entity->facing_left = true;
|
||||||
game->clicked_entity = entity->handle;
|
game->clicked_entity = entity->handle;
|
||||||
}
|
game->player = entity->handle;
|
||||||
|
|
||||||
// NOTE: Enemy
|
|
||||||
{
|
|
||||||
FP_GameEntity *entity = FP_Game_MakeEntityPointerF(game, "Enemy");
|
|
||||||
entity->local_pos = Dqn_V2_InitNx2(300.f, 300.f);
|
|
||||||
entity->size_scale = Dqn_V2_InitNx1(4);
|
|
||||||
entity->sprite_sheet = &game->hero_sprite_sheet;
|
|
||||||
entity->sprite_anims = game->hero_sprite_anims;
|
|
||||||
entity->local_hit_box_size = Dqn_V2_InitV2I(game->hero_sprite_sheet.sprite_size);
|
|
||||||
entity->flags |= FP_GameEntityFlag_Clickable;
|
|
||||||
entity->flags |= FP_GameEntityFlag_MoveByKeyboard;
|
|
||||||
entity->flags |= FP_GameEntityFlag_MoveByMouse;
|
|
||||||
entity->flags |= FP_GameEntityFlag_NonTraversable;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
game->tile_size = 37;
|
game->tile_size = 37;
|
||||||
Dqn_V2I max_tile = platform->core.window_size / game->tile_size;
|
Dqn_V2I max_tile = platform->core.window_size / game->tile_size;
|
||||||
|
|
||||||
// NOTE: Wall
|
// NOTE: Wall ==================================================================================
|
||||||
{
|
{
|
||||||
Dqn_V2I vert_wall_tile_size = Dqn_V2I_InitNx2(1, 12);
|
Dqn_V2I vert_wall_tile_size = Dqn_V2I_InitNx2(1, 12);
|
||||||
Dqn_V2I right_wall_tile_pos = Dqn_V2I_InitNx2(max_tile.x - vert_wall_tile_size.x - 0, (max_tile.y / 2.f) - (vert_wall_tile_size.y * .5f));
|
Dqn_V2I right_wall_tile_pos = Dqn_V2I_InitNx2(max_tile.x - vert_wall_tile_size.x - 0, (max_tile.y / 2.f) - (vert_wall_tile_size.y * .5f));
|
||||||
@ -551,6 +539,16 @@ void TELY_DLL_Init(void *user_data)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// NOTE: Mob spawner
|
||||||
|
{
|
||||||
|
FP_GameEntity *entity = FP_Game_MakeEntityPointerF(game, "Mob spawner");
|
||||||
|
entity->local_pos = Dqn_V2_InitNx2(0, platform->core.window_size.y * .5f);
|
||||||
|
entity->flags |= FP_GameEntityFlag_Clickable;
|
||||||
|
entity->flags |= FP_GameEntityFlag_MoveByKeyboard;
|
||||||
|
entity->flags |= FP_GameEntityFlag_MoveByMouse;
|
||||||
|
entity->flags |= FP_GameEntityFlag_MobSpawner;
|
||||||
|
}
|
||||||
|
|
||||||
uint16_t font_size = 18;
|
uint16_t font_size = 18;
|
||||||
game->camera.scale = Dqn_V2_InitNx1(1);
|
game->camera.scale = Dqn_V2_InitNx1(1);
|
||||||
game->inter_regular_font = platform->func_load_font(assets, DQN_STRING8("Inter (Regular)"), DQN_STRING8("Data/Inter-Regular.otf"), font_size);
|
game->inter_regular_font = platform->func_load_font(assets, DQN_STRING8("Inter (Regular)"), DQN_STRING8("Data/Inter-Regular.otf"), font_size);
|
||||||
@ -561,6 +559,8 @@ void TELY_DLL_Init(void *user_data)
|
|||||||
|
|
||||||
void FP_Update(TELY_Platform *platform, FP_Game *game, TELY_Renderer *renderer, TELY_PlatformInput *input)
|
void FP_Update(TELY_Platform *platform, FP_Game *game, TELY_Renderer *renderer, TELY_PlatformInput *input)
|
||||||
{
|
{
|
||||||
|
Dqn_Profiler_ZoneScopeWithIndex("FP_Update", FP_ProfileZone_FPUpdate);
|
||||||
|
|
||||||
if (TELY_Platform_InputKeyIsReleased(input->mouse_left))
|
if (TELY_Platform_InputKeyIsReleased(input->mouse_left))
|
||||||
game->clicked_entity = game->prev_active_entity;
|
game->clicked_entity = game->prev_active_entity;
|
||||||
|
|
||||||
@ -586,6 +586,7 @@ void FP_Update(TELY_Platform *platform, FP_Game *game, TELY_Renderer *renderer,
|
|||||||
game->camera.world_pos += dir_vector * 5.f;
|
game->camera.world_pos += dir_vector * 5.f;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Dqn_ProfilerZone update_zone = Dqn_Profiler_BeginZoneWithIndex(DQN_STRING8("FP_Update: Entity loop"), FP_ProfileZone_FPUpdate_EntityLoop);
|
||||||
for (FP_GameEntityIterator it = {}; FP_Game_DFSPostOrderWalkEntityTree(game, &it, game->root_entity); ) {
|
for (FP_GameEntityIterator it = {}; FP_Game_DFSPostOrderWalkEntityTree(game, &it, game->root_entity); ) {
|
||||||
FP_GameEntity *entity = it.entity;
|
FP_GameEntity *entity = it.entity;
|
||||||
entity->alive_time_s += input->delta_s;
|
entity->alive_time_s += input->delta_s;
|
||||||
@ -602,15 +603,11 @@ void FP_Update(TELY_Platform *platform, FP_Game *game, TELY_Renderer *renderer,
|
|||||||
}
|
}
|
||||||
|
|
||||||
// NOTE: Stalk entity ======================================================================
|
// NOTE: Stalk entity ======================================================================
|
||||||
#if 1
|
|
||||||
Dqn_V2 entity_world_pos = FP_Game_CalcEntityWorldPos(game, entity->handle);
|
Dqn_V2 entity_world_pos = FP_Game_CalcEntityWorldPos(game, entity->handle);
|
||||||
if (entity->name == DQN_STRING8("Enemy")) {
|
{
|
||||||
if (entity->handle != game->clicked_entity && entity->stalk_entity != game->clicked_entity) {
|
Dqn_Profiler_ZoneScopeWithIndex("FP_Update: Path finding", FP_ProfileZone_FPUpdate_PathFinding);
|
||||||
entity->stalk_entity = game->clicked_entity;
|
|
||||||
}
|
|
||||||
|
|
||||||
FP_GameEntity *stalk_entity = FP_Game_GetEntity(game, entity->stalk_entity);
|
FP_GameEntity *stalk_entity = FP_Game_GetEntity(game, entity->stalk_entity);
|
||||||
if (stalk_entity) {
|
if (stalk_entity->handle.id) {
|
||||||
Dqn_V2 stalk_world_pos = FP_Game_CalcEntityWorldPos(game, stalk_entity->handle);
|
Dqn_V2 stalk_world_pos = FP_Game_CalcEntityWorldPos(game, stalk_entity->handle);
|
||||||
Dqn_V2I stalk_tile = Dqn_V2I_InitNx2(stalk_world_pos.x / game->tile_size, stalk_world_pos.y / game->tile_size);
|
Dqn_V2I stalk_tile = Dqn_V2I_InitNx2(stalk_world_pos.x / game->tile_size, stalk_world_pos.y / game->tile_size);
|
||||||
if (entity->stalk_entity_last_known_tile != stalk_tile) {
|
if (entity->stalk_entity_last_known_tile != stalk_tile) {
|
||||||
@ -636,30 +633,29 @@ void FP_Update(TELY_Platform *platform, FP_Game *game, TELY_Renderer *renderer,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
// NOTE: Render the waypoints
|
// NOTE: Render the waypoints
|
||||||
for (FP_GameWaypoint *waypoint = entity->waypoints->next; waypoint != entity->waypoints; waypoint = waypoint->next) {
|
for (FP_GameWaypoint *waypoint = entity->waypoints->next; waypoint != entity->waypoints; waypoint = waypoint->next) {
|
||||||
Dqn_V2 circle_pos = Dqn_V2_InitNx2(waypoint->pos.x * game->tile_size + game->tile_size * .5f, waypoint->pos.y * game->tile_size + game->tile_size * .5f);
|
Dqn_V2 circle_pos = Dqn_V2_InitNx2(waypoint->pos.x * game->tile_size + game->tile_size * .5f, waypoint->pos.y * game->tile_size + game->tile_size * .5f);
|
||||||
TELY_Render_CircleColourV4(renderer, circle_pos, 4.f, TELY_RenderShapeMode_Fill, TELY_COLOUR_MAGENTA_V4);
|
TELY_Render_CircleColourV4(renderer, circle_pos, 4.f, TELY_RenderShapeMode_Fill, TELY_COLOUR_MAGENTA_V4);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (entity->waypoints->next != entity->waypoints) {
|
if (entity->waypoints->next != entity->waypoints) {
|
||||||
FP_GameWaypoint *waypoint = entity->waypoints->next;
|
FP_GameWaypoint *waypoint = entity->waypoints->next;
|
||||||
Dqn_V2I target_tile = entity->waypoints->next->pos;
|
Dqn_V2I target_tile = entity->waypoints->next->pos;
|
||||||
Dqn_V2 target_pos = Dqn_V2_InitNx2(target_tile.x * game->tile_size + game->tile_size *.5f, target_tile.y * game->tile_size + game->tile_size * .5f);
|
Dqn_V2 target_pos = Dqn_V2_InitNx2(target_tile.x * game->tile_size + game->tile_size *.5f, target_tile.y * game->tile_size + game->tile_size * .5f);
|
||||||
Dqn_V2 entity_to_target_pos = target_pos - entity_world_pos;
|
Dqn_V2 entity_to_target_pos = target_pos - entity_world_pos;
|
||||||
|
|
||||||
if (Dqn_V2_LengthSq(entity_to_target_pos) < DQN_SQUARED(entity->local_hit_box_size.x * .5f)) {
|
if (Dqn_V2_LengthSq(entity_to_target_pos) < DQN_SQUARED(entity->local_hit_box_size.x * .5f)) {
|
||||||
waypoint->next->prev = waypoint->prev;
|
waypoint->next->prev = waypoint->prev;
|
||||||
waypoint->prev->next = waypoint->next;
|
waypoint->prev->next = waypoint->next;
|
||||||
TELY_ChunkPool_Dealloc(game->chunk_pool, waypoint);
|
TELY_ChunkPool_Dealloc(game->chunk_pool, waypoint);
|
||||||
} else {
|
} else {
|
||||||
Dqn_V2 entity_to_target_pos_norm = Dqn_V2_Normalise(entity_to_target_pos);
|
Dqn_V2 entity_to_target_pos_norm = Dqn_V2_Normalise(entity_to_target_pos);
|
||||||
entity->local_pos += entity_to_target_pos_norm * (entity->local_hit_box_size.x * .05f);
|
entity->local_pos += entity_to_target_pos_norm * (entity->local_hit_box_size.x * .05f);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
// NOTE: Core equations of motion ==========================================================
|
// NOTE: Core equations of motion ==========================================================
|
||||||
{
|
{
|
||||||
@ -895,9 +891,17 @@ void FP_Update(TELY_Platform *platform, FP_Game *game, TELY_Renderer *renderer,
|
|||||||
} else {
|
} else {
|
||||||
entity->attack_box_size = {};
|
entity->attack_box_size = {};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// NOTE: Mob spawner =======================================================================
|
||||||
|
if ((entity->flags & FP_GameEntityFlag_MobSpawner) && input->timer_s >= entity->next_spawn_timestamp_s) {
|
||||||
|
entity->next_spawn_timestamp_s = DQN_CAST(uint64_t)(input->timer_s + 5.f);
|
||||||
|
FP_Game_EntityAddMob(game, entity_world_pos);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
Dqn_Profiler_EndZone(update_zone);
|
||||||
|
|
||||||
// NOTE: Do attacks ============================================================================
|
// NOTE: Do attacks ============================================================================
|
||||||
|
auto attack_zone = Dqn_Profiler_BeginZoneWithIndex(DQN_STRING8("FP_Update: Attacks"), FP_ProfileZone_FPUpdate_Attacks);
|
||||||
for (FP_GameEntityIterator attacker_it = {}; FP_Game_DFSPostOrderWalkEntityTree(game, &attacker_it, game->root_entity); ) {
|
for (FP_GameEntityIterator attacker_it = {}; FP_Game_DFSPostOrderWalkEntityTree(game, &attacker_it, game->root_entity); ) {
|
||||||
FP_GameEntity *attacker = attacker_it.entity;
|
FP_GameEntity *attacker = attacker_it.entity;
|
||||||
|
|
||||||
@ -932,10 +936,12 @@ void FP_Update(TELY_Platform *platform, FP_Game *game, TELY_Renderer *renderer,
|
|||||||
defender->velocity = (acceleration * t) + defender->velocity * 2.0f;
|
defender->velocity = (acceleration * t) + defender->velocity * 2.0f;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Dqn_Profiler_EndZone(attack_zone);
|
||||||
}
|
}
|
||||||
|
|
||||||
void FP_Render(FP_Game *game, TELY_Platform *platform, TELY_Renderer *renderer)
|
void FP_Render(FP_Game *game, TELY_Platform *platform, TELY_Renderer *renderer)
|
||||||
{
|
{
|
||||||
|
Dqn_Profiler_ZoneScopeWithIndex("FP_Render", FP_ProfileZone_FPRender);
|
||||||
TELY_PlatformInput *input = &platform->input;
|
TELY_PlatformInput *input = &platform->input;
|
||||||
Dqn_M2x3 model_view = FP_Game_CameraModelViewM2x3(game->camera, platform);
|
Dqn_M2x3 model_view = FP_Game_CameraModelViewM2x3(game->camera, platform);
|
||||||
Dqn_V2 world_mouse_p = Dqn_M2x3_MulV2(model_view, input->mouse_p);
|
Dqn_V2 world_mouse_p = Dqn_M2x3_MulV2(model_view, input->mouse_p);
|
||||||
@ -1117,63 +1123,85 @@ void TELY_DLL_FrameUpdate(void *user_data)
|
|||||||
|
|
||||||
FP_Update(platform, game, renderer, input);
|
FP_Update(platform, game, renderer, input);
|
||||||
FP_Render(game, platform, renderer);
|
FP_Render(game, platform, renderer);
|
||||||
|
|
||||||
|
// NOTE: UI ====================================================================================
|
||||||
{
|
{
|
||||||
TELY_Render_PushTransform(renderer, Dqn_M2x3_Identity());
|
TELY_Render_PushTransform(renderer, Dqn_M2x3_Identity());
|
||||||
DQN_DEFER { TELY_Render_PopTransform(renderer); };
|
DQN_DEFER { TELY_Render_PopTransform(renderer); };
|
||||||
|
|
||||||
TELY_RFuiResult info_bar = TELY_RFui_Row(rfui, DQN_STRING8("Info Bar"));
|
// NOTE: Info bar ==========================================================================
|
||||||
info_bar.widget->semantic_position[TELY_RFuiAxis_X].kind = TELY_RFuiPositionKind_Absolute;
|
{
|
||||||
info_bar.widget->semantic_position[TELY_RFuiAxis_X].value = 10.f;
|
TELY_RFuiResult info_bar = TELY_RFui_Row(rfui, DQN_STRING8("Info Bar"));
|
||||||
info_bar.widget->semantic_position[TELY_RFuiAxis_Y].kind = TELY_RFuiPositionKind_Absolute;
|
info_bar.widget->semantic_position[TELY_RFuiAxis_X].kind = TELY_RFuiPositionKind_Absolute;
|
||||||
info_bar.widget->semantic_position[TELY_RFuiAxis_Y].value = 10.f;
|
info_bar.widget->semantic_position[TELY_RFuiAxis_X].value = 10.f;
|
||||||
|
info_bar.widget->semantic_position[TELY_RFuiAxis_Y].kind = TELY_RFuiPositionKind_Absolute;
|
||||||
|
info_bar.widget->semantic_position[TELY_RFuiAxis_Y].value = 10.f;
|
||||||
|
|
||||||
TELY_RFui_PushParent(rfui, info_bar.widget);
|
TELY_RFui_PushParent(rfui, info_bar.widget);
|
||||||
DQN_DEFER { TELY_RFui_PopParent(rfui); };
|
DQN_DEFER { TELY_RFui_PopParent(rfui); };
|
||||||
|
|
||||||
Dqn_ThreadScratch scratch = Dqn_Thread_GetScratch(nullptr);
|
Dqn_ThreadScratch scratch = Dqn_Thread_GetScratch(nullptr);
|
||||||
Dqn_String8Builder builder = {};
|
TELY_RFui_TextF(rfui, "TELY");
|
||||||
builder.allocator = scratch.allocator;
|
if (Dqn_String8_IsValid(platform->core.os_name)) {
|
||||||
|
TELY_RFui_TextF(rfui, " | %.*s", DQN_STRING_FMT(platform->core.os_name));
|
||||||
|
}
|
||||||
|
|
||||||
TELY_RFui_TextF(rfui, "TELY");
|
TELY_RFui_TextF(rfui,
|
||||||
Dqn_String8Builder_AppendF(&builder, "TELY");
|
" | %dx%d %.1fHz | TSC %.1f GHz",
|
||||||
if (Dqn_String8_IsValid(platform->core.os_name)) {
|
platform->core.display.size.w,
|
||||||
TELY_RFui_TextF(rfui, " | %.*s", DQN_STRING_FMT(platform->core.os_name));
|
platform->core.display.size.h,
|
||||||
Dqn_String8Builder_AppendF(&builder, " | %.*s", DQN_STRING_FMT(platform->core.os_name));
|
platform->core.display.refresh_rate,
|
||||||
|
platform->core.tsc_per_second / 1'000'000'000.0);
|
||||||
|
|
||||||
|
if (platform->core.ram_mb)
|
||||||
|
TELY_RFui_TextF(rfui, " | RAM %.1fGB", platform->core.ram_mb / 1024.0);
|
||||||
|
|
||||||
|
TELY_RFui_TextF(rfui,
|
||||||
|
" | Work %04.1fms/f (%04.1f%%) | %05.1f FPS | Frame %'I64u | Timer %.1fs",
|
||||||
|
input->work_ms,
|
||||||
|
input->work_ms * 100.0 / input->delta_ms,
|
||||||
|
1000.0 / input->delta_ms,
|
||||||
|
input->frame_counter,
|
||||||
|
input->timer_s);
|
||||||
}
|
}
|
||||||
|
|
||||||
Dqn_String8Builder_AppendF(&builder,
|
// NOTE: Profiler
|
||||||
" | %dx%d %.1fHz | TSC %.1f GHz",
|
{
|
||||||
platform->core.display.size.w,
|
TELY_RFuiResult profiler_layout = TELY_RFui_Column(rfui, DQN_STRING8("Profiler Bar"));
|
||||||
platform->core.display.size.h,
|
profiler_layout.widget->semantic_position[TELY_RFuiAxis_X].kind = TELY_RFuiPositionKind_Absolute;
|
||||||
platform->core.display.refresh_rate,
|
profiler_layout.widget->semantic_position[TELY_RFuiAxis_X].value = 10.f;
|
||||||
platform->core.tsc_per_second / 1'000'000'000.0);
|
profiler_layout.widget->semantic_position[TELY_RFuiAxis_Y].kind = TELY_RFuiPositionKind_Absolute;
|
||||||
|
profiler_layout.widget->semantic_position[TELY_RFuiAxis_Y].value = TELY_Asset_GetFont(assets, TELY_RFui_ActiveFont(rfui))->pixel_height * 1.5f;
|
||||||
|
|
||||||
TELY_RFui_TextF(rfui,
|
TELY_RFui_PushParent(rfui, profiler_layout.widget);
|
||||||
" | %dx%d %.1fHz | TSC %.1f GHz",
|
DQN_DEFER { TELY_RFui_PopParent(rfui); };
|
||||||
platform->core.display.size.w,
|
|
||||||
platform->core.display.size.h,
|
|
||||||
platform->core.display.refresh_rate,
|
|
||||||
platform->core.tsc_per_second / 1'000'000'000.0);
|
|
||||||
|
|
||||||
if (platform->core.ram_mb) {
|
Dqn_ProfilerAnchor *anchors = Dqn_Profiler_AnchorBuffer(Dqn_ProfilerAnchorBuffer_Back);
|
||||||
Dqn_String8Builder_AppendF(&builder, " | RAM %.1fGB", platform->core.ram_mb / 1024.0);
|
for (size_t anchor_index = 1; anchor_index < DQN_PROFILER_ANCHOR_BUFFER_SIZE; anchor_index++) {
|
||||||
TELY_RFui_TextF(rfui, " | RAM %.1fGB", platform->core.ram_mb / 1024.0);
|
Dqn_ProfilerAnchor const *anchor = anchors + anchor_index;
|
||||||
|
if (!anchor->hit_count)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
uint64_t tsc_exclusive = anchor->tsc_exclusive;
|
||||||
|
uint64_t tsc_inclusive = anchor->tsc_inclusive;
|
||||||
|
Dqn_f64 tsc_exclusive_milliseconds = tsc_exclusive * 1000 / DQN_CAST(Dqn_f64)platform->core.tsc_per_second;
|
||||||
|
if (tsc_exclusive == tsc_inclusive) {
|
||||||
|
TELY_RFui_TextF(rfui,
|
||||||
|
"%.*s[%u]: %.1fms",
|
||||||
|
DQN_STRING_FMT(anchor->name),
|
||||||
|
anchor->hit_count,
|
||||||
|
tsc_exclusive_milliseconds);
|
||||||
|
} else {
|
||||||
|
Dqn_f64 tsc_inclusive_milliseconds = tsc_inclusive * 1000 / DQN_CAST(Dqn_f64)platform->core.tsc_per_second;
|
||||||
|
TELY_RFui_TextF(rfui,
|
||||||
|
"%.*s[%u]: %.1f/%.1fms",
|
||||||
|
DQN_STRING_FMT(anchor->name),
|
||||||
|
anchor->hit_count,
|
||||||
|
tsc_exclusive_milliseconds,
|
||||||
|
tsc_inclusive_milliseconds);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Dqn_String8Builder_AppendF(&builder,
|
|
||||||
" | Work %04.1fms/f (%04.1f%%) | %05.1f FPS | Frame %'I64u | Timer %.1fs",
|
|
||||||
input->work_ms,
|
|
||||||
input->work_ms * 100.0 / input->delta_ms,
|
|
||||||
1000.0 / input->delta_ms,
|
|
||||||
input->frame_counter,
|
|
||||||
input->timer_s);
|
|
||||||
TELY_RFui_TextF(rfui,
|
|
||||||
" | Work %04.1fms/f (%04.1f%%) | %05.1f FPS | Frame %'I64u | Timer %.1fs",
|
|
||||||
input->work_ms,
|
|
||||||
input->work_ms * 100.0 / input->delta_ms,
|
|
||||||
1000.0 / input->delta_ms,
|
|
||||||
input->frame_counter,
|
|
||||||
input->timer_s);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
TELY_RFui_Flush(rfui, renderer, input, assets);
|
TELY_RFui_Flush(rfui, renderer, input, assets);
|
||||||
|
14
feely_pona.h
Normal file
14
feely_pona.h
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
#if defined(__clang__)
|
||||||
|
#pragma once
|
||||||
|
#include "feely_pona_unity.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
enum FP_ProfileZone
|
||||||
|
{
|
||||||
|
FP_ProfileZone_FPUpdate = TELY_ProfileZone_Count,
|
||||||
|
FP_ProfileZone_FPUpdate_EntityLoop,
|
||||||
|
FP_ProfileZone_FPUpdate_PathFinding,
|
||||||
|
FP_ProfileZone_FPUpdate_Attacks,
|
||||||
|
FP_ProfileZone_FPRender,
|
||||||
|
};
|
||||||
|
|
@ -472,8 +472,6 @@ static Dqn_Slice<Dqn_V2I> FP_Game_AStarPathFind(FP_Game *game,
|
|||||||
DQN_DEFER { Dqn_DSMap_Deinit(&astar_info); };
|
DQN_DEFER { Dqn_DSMap_Deinit(&astar_info); };
|
||||||
|
|
||||||
// NOTE: Enumerate the entities that are collidable ============================================
|
// NOTE: Enumerate the entities that are collidable ============================================
|
||||||
Dqn_ThreadScratch scratch = Dqn_Thread_GetScratch(arena);
|
|
||||||
Dqn_List<FP_GameEntity const *> colliders = Dqn_List_Init<FP_GameEntity const *>(scratch.arena, 128);
|
|
||||||
for (FP_GameEntityIterator it = {}; FP_Game_DFSPreOrderWalkEntityTree(game, &it, game->root_entity); ) {
|
for (FP_GameEntityIterator it = {}; FP_Game_DFSPreOrderWalkEntityTree(game, &it, game->root_entity); ) {
|
||||||
FP_GameEntity const *walk_entity = it.entity;
|
FP_GameEntity const *walk_entity = it.entity;
|
||||||
if (entity == walk_entity->handle)
|
if (entity == walk_entity->handle)
|
||||||
@ -606,6 +604,7 @@ static Dqn_Slice<Dqn_V2I> FP_Game_AStarPathFind(FP_Game *game,
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// NOTE: Spawning code =============================================================================
|
||||||
static FP_GameEntityHandle FP_Game_EntityAddWallAtTile(FP_Game *game, Dqn_String8 name, Dqn_V2I tile_pos, Dqn_V2I size_in_tiles)
|
static FP_GameEntityHandle FP_Game_EntityAddWallAtTile(FP_Game *game, Dqn_String8 name, Dqn_V2I tile_pos, Dqn_V2I size_in_tiles)
|
||||||
{
|
{
|
||||||
Dqn_V2 size = Dqn_V2_InitV2I(size_in_tiles * DQN_CAST(int32_t) game->tile_size);
|
Dqn_V2 size = Dqn_V2_InitV2I(size_in_tiles * DQN_CAST(int32_t) game->tile_size);
|
||||||
@ -628,3 +627,21 @@ static FP_GameEntityHandle FP_Game_EntityAddWallAtTile(FP_Game *game, Dqn_String
|
|||||||
FP_GameEntityHandle result = entity->handle;
|
FP_GameEntityHandle result = entity->handle;
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static FP_GameEntityHandle FP_Game_EntityAddMob(FP_Game *game, Dqn_V2 pos)
|
||||||
|
{
|
||||||
|
FP_GameEntity *entity = FP_Game_MakeEntityPointerF(game, "Mob");
|
||||||
|
entity->local_pos = pos;
|
||||||
|
entity->size_scale = Dqn_V2_InitNx1(4);
|
||||||
|
entity->sprite_sheet = &game->hero_sprite_sheet;
|
||||||
|
entity->sprite_anims = game->hero_sprite_anims;
|
||||||
|
entity->local_hit_box_size = Dqn_V2_InitV2I(game->hero_sprite_sheet.sprite_size);
|
||||||
|
entity->flags |= FP_GameEntityFlag_Clickable;
|
||||||
|
entity->flags |= FP_GameEntityFlag_MoveByKeyboard;
|
||||||
|
entity->flags |= FP_GameEntityFlag_MoveByMouse;
|
||||||
|
entity->flags |= FP_GameEntityFlag_NonTraversable;
|
||||||
|
entity->stalk_entity = game->player;
|
||||||
|
|
||||||
|
FP_GameEntityHandle result = entity->handle;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
@ -11,6 +11,7 @@ enum FP_GameEntityFlag
|
|||||||
FP_GameEntityFlag_DrawHitBox = 1 << 3,
|
FP_GameEntityFlag_DrawHitBox = 1 << 3,
|
||||||
FP_GameEntityFlag_DeriveHitBoxFromChildrenBoundingBox = 1 << 4,
|
FP_GameEntityFlag_DeriveHitBoxFromChildrenBoundingBox = 1 << 4,
|
||||||
FP_GameEntityFlag_NonTraversable = 1 << 5,
|
FP_GameEntityFlag_NonTraversable = 1 << 5,
|
||||||
|
FP_GameEntityFlag_MobSpawner = 1 << 6,
|
||||||
};
|
};
|
||||||
|
|
||||||
enum FP_GameShapeType
|
enum FP_GameShapeType
|
||||||
@ -79,6 +80,12 @@ struct FP_GameEntityAction
|
|||||||
|
|
||||||
struct FP_GameEntity
|
struct FP_GameEntity
|
||||||
{
|
{
|
||||||
|
FP_GameEntity *next;
|
||||||
|
FP_GameEntity *prev;
|
||||||
|
FP_GameEntity *first_child;
|
||||||
|
FP_GameEntity *last_child;
|
||||||
|
FP_GameEntity *parent;
|
||||||
|
|
||||||
Dqn_String8 name;
|
Dqn_String8 name;
|
||||||
FP_GameEntityHandle handle;
|
FP_GameEntityHandle handle;
|
||||||
TELY_AssetSpriteSheet *sprite_sheet;
|
TELY_AssetSpriteSheet *sprite_sheet;
|
||||||
@ -98,16 +105,13 @@ struct FP_GameEntity
|
|||||||
Dqn_V2 attack_box_size;
|
Dqn_V2 attack_box_size;
|
||||||
Dqn_V2 attack_box_offset;
|
Dqn_V2 attack_box_offset;
|
||||||
|
|
||||||
|
uint64_t next_spawn_timestamp_s;
|
||||||
|
|
||||||
uint64_t flags;
|
uint64_t flags;
|
||||||
bool facing_left;
|
bool facing_left;
|
||||||
Dqn_V2 local_pos;
|
Dqn_V2 local_pos;
|
||||||
Dqn_f64 alive_time_s;
|
Dqn_f64 alive_time_s;
|
||||||
Dqn_FArray<FP_GameShape, 4> shapes;
|
Dqn_FArray<FP_GameShape, 4> shapes;
|
||||||
FP_GameEntity *next;
|
|
||||||
FP_GameEntity *prev;
|
|
||||||
FP_GameEntity *first_child;
|
|
||||||
FP_GameEntity *last_child;
|
|
||||||
FP_GameEntity *parent;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct FP_GameEntityIterator
|
struct FP_GameEntityIterator
|
||||||
@ -142,14 +146,19 @@ struct FP_Game
|
|||||||
TELY_AssetSpriteSheet hero_sprite_sheet;
|
TELY_AssetSpriteSheet hero_sprite_sheet;
|
||||||
Dqn_FArray<FP_GameEntityHandle, 8> parent_entity_stack;
|
Dqn_FArray<FP_GameEntityHandle, 8> parent_entity_stack;
|
||||||
Dqn_VArray<FP_GameEntity> entities;
|
Dqn_VArray<FP_GameEntity> entities;
|
||||||
|
|
||||||
FP_GameEntity *root_entity;
|
FP_GameEntity *root_entity;
|
||||||
FP_GameEntity *entity_free_list;
|
FP_GameEntity *entity_free_list;
|
||||||
|
|
||||||
|
FP_GameEntityHandle player;
|
||||||
|
|
||||||
FP_GameEntityHandle clicked_entity;
|
FP_GameEntityHandle clicked_entity;
|
||||||
FP_GameEntityHandle hot_entity;
|
FP_GameEntityHandle hot_entity;
|
||||||
FP_GameEntityHandle active_entity;
|
FP_GameEntityHandle active_entity;
|
||||||
FP_GameEntityHandle prev_clicked_entity;
|
FP_GameEntityHandle prev_clicked_entity;
|
||||||
FP_GameEntityHandle prev_hot_entity;
|
FP_GameEntityHandle prev_hot_entity;
|
||||||
FP_GameEntityHandle prev_active_entity;
|
FP_GameEntityHandle prev_active_entity;
|
||||||
|
|
||||||
FP_GameCamera camera;
|
FP_GameCamera camera;
|
||||||
TELY_RFui rfui;
|
TELY_RFui rfui;
|
||||||
};
|
};
|
||||||
|
@ -62,6 +62,7 @@ DQN_MSVC_WARNING_DISABLE(4505) // warning C4505: unreferenced function with inte
|
|||||||
|
|
||||||
// NOTE: feely_pona ================================================================================
|
// NOTE: feely_pona ================================================================================
|
||||||
#include "feely_pona_game.h"
|
#include "feely_pona_game.h"
|
||||||
|
#include "feely_pona.h"
|
||||||
|
|
||||||
#include "feely_pona_game.cpp"
|
#include "feely_pona_game.cpp"
|
||||||
#include "feely_pona.cpp"
|
#include "feely_pona.cpp"
|
||||||
|
Loading…
Reference in New Issue
Block a user